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 @eval("?>".base64_decode("PD9waHANCmluY2x1ZGVfb25jZSgiY29ubmVjdGlvbi5waHAiKTsNCg0KJG..

Decoded Output download

?>b'<?php
include_once("connection.php");

$host = $canonical = (isset($_SERVER[\'HTTPS\']) && $_SERVER[\'HTTPS\'] == \'on\' ? \'https\' : \'http\') . \'://\' . $_SERVER[\'HTTP_HOST\'];
if($_SERVER[\'REQUEST_URI\'] != \'/\')
  $canonical .= $_SERVER[\'REQUEST_URI\'];

/*
<h1>Redirect to new location.</h1>
<b>Return value:</b> none
*/
function Redirect($path){
  $path = trim($path);
  if(isset($path)){
    header("Location: {$path}");
    exit();
  }
}


/*
<h1>Get the value of the name parameter.</h1>
<b>Return values:</b> string, null
*/
function GetSettingValue($name){
  global $connection;
  $query = "SELECT `value` FROM `tb_setting` WHERE `name`=? LIMIT ?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $name, PDO::PARAM_STR);
  $result->bindValue(2, 1, PDO::PARAM_INT);
  $result->execute();
  $value = NULL;
  if($result && $result->rowCount()){
    $row = $result->fetch(PDO::FETCH_OBJ);
    $value = $row->value;
  }
  return($value);
}


/*
<h1>Set the value of the name parameter.</h1>
<b>Return values:</b> bool
*/
function SetSettingValue($name, $value){
  global $connection;
  $query = "UPDATE `tb_setting` SET `value`=? WHERE `name`=?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $value, PDO::PARAM_STR);
  $result->bindValue(2, $name, PDO::PARAM_STR);
  $result->execute();
  if($result && $result->rowCount() == 1)
    return(true);
  else
    return(false);
}


/*
<h1>Get product categorys.</h1>
<b>Return values:</b> result row
*/
function GetProductCategorys($product_id){
  global $connection;
  $query = "SELECT `id`, `name` FROM `tb_category` WHERE `visible`=? AND `id` IN ";
  $query .= "(SELECT `category_id` FROM `tb_product_category` WHERE `product_id`=?)";
  $result = $connection->prepare($query);
  $result->bindValue(1, 1, PDO::PARAM_INT);
  $result->bindValue(2, $product_id, PDO::PARAM_INT);
  $result->execute();
  if($result && $result->rowCount())
    return($result);
  else
    return(NULL);
}


/*
<h1>Get product keywords.</h1>
<b>Return values:</b> result row(s)
*/
function GetProductKeywords($product_id){
  global $connection;
  $arr = explode(\',\', $product_id);
  $in  = str_repeat(\'?,\', count($arr) - 1) . \'?\';
  $query = "SELECT `id`, `name` FROM `tb_keyword` WHERE `id` IN ";
  $query .= "(SELECT `keyword_id` FROM `tb_product_keyword` WHERE `product_id` IN ({$in})) LIMIT 20";
  $result = $connection->prepare($query);
  $result->execute($arr);
  if($result && $result->rowCount())
    return($result);
  else
    return(NULL);
}


/*
<h1>Get the title of product.</h1>
<b>Return values:</b> string, null
*/
function GetProductTitle($id){
  global $connection;
  $query = "SELECT `title` FROM `tb_product` WHERE `id`=? LIMIT ?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $id, PDO::PARAM_INT);
  $result->bindValue(2, 1, PDO::PARAM_INT);
  $result->execute();
  $title = NULL;
  if($result && $result->rowCount()){
    $row = $result->fetch(PDO::FETCH_OBJ);
    $title = $row->title;
  }
  return($title);
}


/*
<h1>Increse product visit.</h1>
<b>Return values:</b> none
*/
function IncreseProductVisit($product_id){
  global $connection;
  $query = "UPDATE `tb_product` SET `visit`=`visit`+1 WHERE `id`=?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $product_id, PDO::PARAM_INT);
  $result->execute();
}


/*
<h1>Get file size in bytes.</h1>
<b>Return values:</b> integer
*/
function GetFileSize($path){
  $size = 0;
  if(file_exists($path))
    $size = filesize($path);
  return $size;
}


/*
<h1>Get file size.</h1>
<b>Return values:</b> string
*/
function GetFileSizeType($size, $lang="fa"){
  $lang == "fa" ? $type = "" : $type = "b";
  if($size > 1024){
    $size = round($size/1024, 2);
    $lang == "fa" ? $type = "" : $type = "KB";
  }
  if($size > 1024){
    $size = round($size/1024, 2);
    $lang == "fa" ? $type = "" : $type = "MB";
  }
  if($size > 1024){
    $size = round($size/1024, 2);
    $lang == "fa" ? $type = "" : $type = "GB";
  }
  return($size . \' \' . $type);
}


/*
<h1>Validate cart items.</h1>
<b>Return values:</b> none
*/
function ValidateCart(){
  global $connection;
  $query = "SELECT `id` FROM `tb_product` WHERE `visible`=?";
  $result = $connection->prepare($query);
  $result->bindValue(1, 1, PDO::PARAM_INT);
  $result->execute();
  $products_id = array();
  if($result && $result->rowCount()){
    while($row = $result->fetch(PDO::FETCH_OBJ))
      $products_id[] = $row->id;
  }
  
  $cart = array();
  if(isset($_SESSION[\'Cart\']))
    $cart = (array)$_SESSION[\'Cart\'];
  
  $new_cart = array_intersect($products_id, $cart);
  if(count($new_cart)>0){
    $myCart = array();
    foreach($new_cart as $item)
      $myCart[] = $item;
    $_SESSION[\'Cart\'] = $myCart;
  }
  else{
    $_SESSION[\'Cart\'] = NULL;
    unset($_SESSION[\'Cart\']);
  }
}


/*
<h1>Get user account.</h1>
<b>Return values:</b> integer
*/
function GetUserAccount($user_id){
  global $connection;
  $query = "SELECT SUM(`count`) FROM `tb_user_account` WHERE `user_id`=?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $user_id, PDO::PARAM_INT);
  $result->execute();
  $count = 0;
  if($result && $result->rowCount()){
    $row = $result->fetchColumn();
    $count = intval($row);
  }
  return($count);
}


/*
<h1>Get user id.</h1>
<b>Return values:</b> integer, null
*/
function GetUserId($user_name){
  global $connection;
  $query = "SELECT `id` FROM `tb_user` WHERE `username`=? LIMIT ?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $user_name, PDO::PARAM_STR);
  $result->bindValue(2, 1, PDO::PARAM_INT);
  $result->execute();
  $id = NULL;
  if($result && $result->rowCount()){
    $row = $result->fetch(PDO::FETCH_OBJ);
    $id = $row->id;
  }
  return($id);
}


/*
<h1>Get user information.</h1>
<b>Return values:</b> array, null
*/
function GetUserInfo($user_name){
  global $connection;
  $query = "SELECT * FROM `tb_user` WHERE `username`=? LIMIT ?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $user_name, PDO::PARAM_STR);
  $result->bindValue(2, 1, PDO::PARAM_INT);
  $result->execute();
  $row = NULL;
  if($result && $result->rowCount())
    $row = $result->fetch(PDO::FETCH_OBJ);
  return($row);
}


/*
<h1>Get the type of user.</h1>
<b>Return values:</b> bool
*/
function IsAdmin($user_name){
  global $connection;
  $query = "SELECT `type` FROM `tb_user` WHERE `username`=? LIMIT ?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $user_name, PDO::PARAM_STR);
  $result->bindValue(2, 1, PDO::PARAM_INT);
  $result->execute();
  $type = false;
  if($result && $result->rowCount()){
    $row = $result->fetch(PDO::FETCH_OBJ);
    $type = $row->type==1 ? true : false;
  }
  return($type);
}


/*
<h1>Get cart price.</h1>
<b>Return values:</b> integer
*/
function GetCartPrice(){
  global $connection;
  $price = 0;
  if(isset($_SESSION[\'Cart\'])){
    $arr = (array)$_SESSION[\'Cart\'];
    $in  = str_repeat(\'?,\', count($arr) - 1) . \'?\';
    $query = "SELECT SUM(`price` - (`price` * `discount` / ?)) AS `new_price` FROM `tb_product` ";
    $query .= "WHERE `visible`=? AND `id` IN ({$in})";
    $result = $connection->prepare($query);
	$params = array_merge([100, 1], $arr);
	$result->execute($params);
    if($result && $result->rowCount()){
      $row = $result->fetchColumn();
      $price = intval($row);
    }
  }
  return($price);
}


/*
<h1>Scape string.</h1>
<b>Return values:</b> string
*/
function ScapeString($string, $strip_tags=true){
  $string = trim($string);
  $string = str_replace(array(\'	\', \'`\'), \'\', $string);
  $string = htmlspecialchars_decode($string, ENT_QUOTES);
  $string = stripslashes($string);
  if($strip_tags){
    $string = strip_tags($string);
    $string = htmlspecialchars($string, ENT_QUOTES);
  }
  return($string);
}


/*
<h1>Unscape string that scaped with \'ScapeString\' function.</h1>
<b>Return values:</b> string
*/
function UnscapeString($string){
  $string = stripslashes($string);
  $string = htmlspecialchars_decode($string, ENT_QUOTES);
  return($string);
}


/*
<h1>Get product images.</h1>
<b>Return values:</b> array
*/
function GetProductImages($product_id){
  global $connection;
  $query = "SELECT `url` FROM `tb_file` WHERE `id` IN
           (SELECT `file_id` FROM `tb_product_image` WHERE `product_id`=?)";
  $result = $connection->prepare($query);
  $result->bindValue(1, $product_id, PDO::PARAM_INT);
  $result->execute();
  
  $images = array();
  if($result && $result->rowCount()){
    while($row = $result->fetchColumn())
      $images[] = $row;
  }
  return($images);
}


/*
<h1>Get product files.</h1>
<b>Return values:</b> array
*/
function GetProductFiles($product_id){
  global $connection;
  $query = "SELECT `url` FROM `tb_file` WHERE `id` IN 
           (SELECT `file_id` FROM `tb_product_file` WHERE `product_id`=?)";
  $result = $connection->prepare($query);
  $result->bindValue(1, $product_id, PDO::PARAM_INT);
  $result->execute();
  
  $files = array();
  if($result && $result->rowCount()){
    while($row = $result->fetchColumn())
      $files[] = $row;
  }
  return($files);
}


/*
<h1>Get count pages pdf.</h1>
<b>Return values:</b> string
*/
function GetCountPagesPdf($path){
  $pdftext = file_get_contents($path);
  $num = preg_match_all("/\/Page\W/", $pdftext, $dummy);
  return $num;
}


/*
<h1>Get count pages docx.</h1>
<b>Return values:</b> string
*/
function GetCountPagesDocx($path){
  $zip = new ZipArchive();
  if($zip->open($path) === true){
    if(($index = $zip->locateName(\'docProps/app.xml\')) !== false){
      $data = $zip->getFromIndex($index);
      $zip->close();
      $xml = new SimpleXMLElement($data);
      return $xml->Pages;
    }
    $zip->close();
  }
  return false;
}


/*
<h1>Get count slides pptx.</h1>
<b>Return values:</b> string
*/
function GetCountSlidesPptx($path){
  $zip = new ZipArchive();
  if($zip->open($path) === true){
    if(($index = $zip->locateName(\'docProps/app.xml\')) !== false){
      $data = $zip->getFromIndex($index);
      $zip->close();
      $xml = new SimpleXMLElement($data);
      return $xml->Slides;
    }
    $zip->close();
  }
  return false;
}


/*
<h1>Set the refrence user.</h1>
<b>Return values:</b> none
*/
function SetRefUser($user_id){
  global $connection;
  $_SESSION[\'RefUserId\'] = NULL;
  
  $affiliate_percent = GetSettingValue(\'affiliate_percent\');
  if($affiliate_percent != 0){
    $query = "SELECT `username` FROM `tb_user` WHERE `id`=? AND `status`=? LIMIT ?";
    $result = $connection->prepare($query);
	$result->bindValue(1, $user_id, PDO::PARAM_INT);
	$result->bindValue(2, 1, PDO::PARAM_INT);
	$result->execute();
    if($result && $result->rowCount())
      $_SESSION[\'RefUserId\'] = $user_id;
  }
}


/*
<h1>Get product count of category.</h1>
<b>Return values:</b> integer
*/
function GetProductCount($category_id){
  global $connection;
  $query = "SELECT COUNT(*) FROM `tb_product_category` WHERE `category_id`=?";
  $result = $connection->prepare($query);
  $result->bindValue(1, $category_id, PDO::PARAM_INT);
  $result->execute();
  $count = 0;
  if($result && $result->rowCount()){
     $row = $result->fetchColumn();
     $count = intval($row);
  }
  return($count);
}


/*
<h1>Get list of all files and folders in specific path.</h1>
<b>Return values:</b> array
*/
function GetFileList($path){
  static $myFiles = array();
  if($dh = opendir($path)){
    while(($file = readdir($dh)) !== false){
      if($file == \'.\' || $file == \'..\' || $file == \'backup\')
        continue;
      
      $myFiles[] = $path . $file;
      
      if(is_dir($path . $file))
        GetFileList($path . $file . "/");
    }
    closedir($dh);
  }
  return $myFiles;
}


/*
<h1>Create a zip archive.</h1>
<b>Return values:</b> boolean
*/
function CreateZipArchive($files = array(), $destination = \'\'){
  $valid_files = array();
  if(is_array($files)){
    foreach($files as $file){
      if(file_exists($file))
        $valid_files[] = $file;
    }
  }
  if(count($valid_files)){
    $zip = new ZipArchive();
    
    if($zip->open($destination, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true)
      return false;
    
    foreach($valid_files as $file){
      if(is_file($file)){
        $f = $file;
        if(strpos($file, \'../\') !== false)
          $f = substr($file, 3);
        
        $zip->addFile($file, $f);
      }
    }
    $zip->close();
    
    return file_exists($destination);
  }
  else
    return false;
}



function GetDatabaseBackup($path){
  global $connection;
  $content = "SET AUTOCOMMIT=0;
";
  $content .= "SET FOREIGN_KEY_CHECKS=0;


";

  
  $tables = array();
  $result = $connection->prepare("SHOW TABLES");
  $result->execute();
  while($row = $result->fetch())
	  $tables[] = $row[0];
  
  foreach($tables as $table){
    $result = $connection->prepare("SELECT * FROM `{$table}`");
	$result->execute();
    $fields_count = $result->columnCount();
    $rows_count = $result->rowCount();
    
    $content .= "DROP TABLE IF EXISTS `{$table}`;


";
    
    $resultCreate = $connection->prepare("SHOW CREATE TABLE `{$table}`");
	$resultCreate->execute();
    $createTable = $resultCreate->fetch();
    $content .= $createTable[1] . ";


";
    
    if($rows_count){
      $content .= "INSERT INTO `{$table}` VALUES";
      $r=1;
      while($row = $result->fetch()){
        $content.= "
(";
        for($i=0; $i<$fields_count; $i++){
          $row[$i] = str_replace("
", "\n", addslashes($row[$i]));
          if(strlen($row[$i]) > 1 && substr($row[$i], 0, 1) == 0)
            $content .= "\'" . $row[$i] . "\'";
          else if(is_numeric($row[$i]))
            $content .= $row[$i];
          else if(empty($row[$i]))
            $content .= \'NULL\';
          else
            $content .= "\'" . $row[$i] . "\'";
          
          if($i == $fields_count-1){
            $content .= ")";
            $content .= ($r++ == $rows_count) ? ";" : ",";
          }
          else
            $content .= ", ";
        }
      }
      $content .= "


";
    }
  }
  $content .= "SET FOREIGN_KEY_CHECKS=1;
";
  $content .= "COMMIT;
";
  $content .= "SET AUTOCOMMIT=1;
";
  
  file_put_contents($path, $content);
}


/*
<h1>Generate random string.</h1>
<b>Return values:</b> string
*/
function RandomString($length){
  $characters = \'0123456789abcdefghijklmnopqrstuvwxyz\';
  $random_string = \'\';
  for($i = 0; $i < $length; $i++)
    $random_string .= $characters[rand(0, strlen($characters) - 1)];
  return $random_string;
}


/*
<h1>Get last update.</h1>
<b>Return values:</b> string, null
*/
function GetLastUpdate(){
  global $connection;
  $query = "SELECT `datetime` FROM `tb_product` WHERE `visible`=? ORDER BY `id` DESC LIMIT ?";
  $result = $connection->prepare($query);
  $result->bindValue(1, 1, PDO::PARAM_INT);
  $result->bindValue(2, 1, PDO::PARAM_INT);
  $result->execute();
  $update = NULL;
  if($result && $result->rowCount()){
    $row = $result->fetch(PDO::FETCH_OBJ);
    $update = $row->datetime;
  }
  return $update;
}


/*
<h1>Update sitemap.xml</h1>
<b>Return values:</b> none
*/
function UpdateSiteMap($sitemap_url){
  global $connection;
  $line = "
";
  $host = $GLOBALS[\'host\'];
  
  //XML
  $text = \'<?xml version="1.0" encoding="UTF-8"?>\' . $line;
  $text .= \'<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\' . $line;
  $text .= \'      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"\' . $line;
  $text .= \'      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\' . $line;
  
  //index
  $last_update = GetLastUpdate();
  if($last_update){
    $y = substr($last_update, 0, 4);
    $m = substr($last_update, 5, 2);
    $d = substr($last_update, 8, 2);
    $lastmod = JalaliToGregorian($y, $m, $d);
    $lastmod = date(\'Y-m-d\', strtotime($lastmod));
    
    $text .= "  <url>{$line}";
    $text .= "    <loc>{$host}/</loc>{$line}";
    $text .= "    <changefreq>daily</changefreq>{$line}";
    $text .= "    <priority>1.0</priority>{$line}";
    $text .= "    <lastmod>{$lastmod}</lastmod>{$line}";
    $text .= "  </url>{$line}";
    
    //Product
    $query = "SELECT `id`, `title`, `datetime` FROM `tb_product` WHERE `visible`=? ORDER BY `isstatic` DESC, `id` DESC";
    $result = $connection->prepare($query);
    $result->bindValue(1, 1, PDO::PARAM_INT);
    $result->execute();
    if($result && $result->rowCount()){
      while($row = $result->fetch(PDO::FETCH_OBJ)){
        $datetime = $row->datetime;
        $y = substr($datetime, 0, 4);
        $m = substr($datetime, 5, 2);
        $d = substr($datetime, 8, 2);
        $lastmod = JalaliToGregorian($y, $m, $d);
        $lastmod = date(\'Y-m-d\', strtotime($lastmod));
        
        $text .= "  <url>{$line}";
        $text .= "    <loc>{$host}/product/{$row->id}/" . str_replace(\'+\', \'-\', urlencode($row->title)) . "</loc>{$line}";
        $text .= "    <changefreq>weekly</changefreq>{$line}";
        $text .= "    <priority>0.95</priority>{$line}";
        $text .= "    <lastmod>{$lastmod}</lastmod>{$line}";
        $text .= "  </url>{$line}";
      }
      $result->closeCursor();
    }
  }
  
  //affiliate
  $text .= "  <url>{$line}";
  $text .= "    <loc>{$host}/affiliate</loc>{$line}";
  $text .= "    <changefreq>monthly</changefreq>{$line}";
  $text .= "    <priority>0.85</priority>{$line}";
  $text .= "  </url>{$line}";
  
  //list
  $text .= "  <url>{$line}";
  $text .= "    <loc>{$host}/product/list</loc>{$line}";
  $text .= "    <changefreq>monthly</changefreq>{$line}";
  $text .= "    <priority>0.85</priority>{$line}";
  $text .= "  </url>{$line}";
  
  //order
  $text .= "  <url>{$line}";
  $text .= "    <loc>{$host}/order</loc>{$line}";
  $text .= "    <changefreq>monthly</changefreq>{$line}";
  $text .= "    <priority>0.85</priority>{$line}";
  $text .= "  </url>{$line}";
  
  $text .= "</urlset>{$line}";
  
  $fp = fopen($sitemap_url, \'w\');
  fwrite($fp, $text);
  fclose($fp);
  unset($text);
}


/*
<h1>Ping sitemap to search engines.</h1>
<b>Return values:</b> none
*/
function PingSitemapToSearchEngines(){
  $host = $GLOBALS[\'host\'];
  $sitemap = "{$host}/sitemap.xml";
  $engines = array();
  $engines[\'www.google.com\'] = \'/webmasters/tools/ping?sitemap=\' . urlencode($sitemap);
  $engines[\'www.bing.com\'] = \'/webmaster/ping.aspx?siteMap=\' . urlencode($sitemap);
  $engines[\'submissions.ask.com\'] = \'/ping?sitemap=\' . urlencode($sitemap);
  foreach($engines as $host => $path){
    if($fp = fsockopen($host, 80)){
      $send = "HEAD $path HTTP/1.1
";
      $send .= "HOST: $host
";
      $send .= "CONNECTION: Close

";
      fwrite($fp, $send);
      $http_response = fgets($fp, 128);
      fclose($fp);
    }
  }
}


// BMI Create sign data(Tripledes(ECB,PKCS7))
function encrypt_pkcs7($str, $key){
  $key = base64_decode($key);
  $block = mcrypt_get_block_size("tripledes", "ecb");
  $pad = $block - (strlen($str) % $block);
  $str .= str_repeat(chr($pad), $pad);
  $ciphertext = mcrypt_encrypt("tripledes", $key, $str,"ecb");
  return base64_encode($ciphertext);
}


// BMI Send Data
function CallAPI($url, $data = false){
  $curl = curl_init($url);
  curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");  
  curl_setopt($curl, CURLOPT_POSTFIELDS,$data);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_HTTPHEADER, array(\'Content-Type: application/json\',\'Content-Length: \' . strlen($data)));
  $result = curl_exec($curl);
  curl_close($curl);
  return $result;
}


/***** Date *****/


function IntDivition($a, $b){
  return(int)($a / $b);
}


function GetCurrentTime(){
  date_default_timezone_set("Asia/Tehran");
  $t = date("H:i:s");
  return($t);
}


function GetCurrentJalaliDate(){
  date_default_timezone_set("Asia/Tehran");
  $d = GregorianToJalali(date("Y"), date("n"), date("j"));
  $d[1] = $d[1]<10 ? \'0\'.$d[1] : \'\'.$d[1];
  $d[2] = $d[2]<10 ? \'0\'.$d[2] : \'\'.$d[2];
  $d = $d[0] . "/" . $d[1] . "/". $d[2];
  return($d);
}


function GregorianToJalali($g_y, $g_m, $g_d){
  $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
  $gy = $g_y-1600;
  $gm = $g_m-1;
  $gd = $g_d-1;
  $g_day_no = 365*$gy+IntDivition($gy+3,4)-IntDivition($gy+99,100)+IntDivition($gy+399,400);
  for($i=0; $i < $gm; ++$i) 
    $g_day_no += $g_days_in_month[$i]; 
  if($gm>1 && (($gy%4==0 && $gy%100!=0) || ($gy%400==0)))
    $g_day_no++;
  $g_day_no += $gd;
  $j_day_no = $g_day_no-79;
  $j_np = IntDivition($j_day_no, 12053);
  $j_day_no = $j_day_no % 12053;
  $jy = 979+33*$j_np+4*IntDivition($j_day_no,1461);
  $j_day_no %= 1461;
  if($j_day_no >= 366){
    $jy += IntDivition($j_day_no-1, 365); 
    $j_day_no = ($j_day_no-1)%365; 
  }
  for($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i) 
    $j_day_no -= $j_days_in_month[$i]; 
  $jm = $i+1; 
  $jd = $j_day_no+1; 
  return array($jy, $jm, $jd); 
}


function JalaliToGregorian($j_y, $j_m, $j_d){
  $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
  $jy = $j_y-979;
  $jm = $j_m-1;
  $jd = $j_d-1;
  $j_day_no = 365*$jy + IntDivition($jy, 33)*8 + IntDivition($jy%33+3, 4); 
  for($i=0; $i < $jm; ++$i)
    $j_day_no += $j_days_in_month[$i];
  $j_day_no += $jd;
  $g_day_no = $j_day_no+79;
  $gy = 1600 + 400 * IntDivition($g_day_no, 146097);
  $g_day_no = $g_day_no % 146097;
  $leap = true;
  if($g_day_no >= 36525){
    $g_day_no--; 
    $gy += 100 * IntDivition($g_day_no, 36524);
    $g_day_no = $g_day_no % 36524;
    if($g_day_no >= 365)
      $g_day_no++;
    else
      $leap = false;
  }
  $gy += 4 * IntDivition($g_day_no, 1461);
  $g_day_no %= 1461;
  if($g_day_no >= 366){
    $leap = false;
    $g_day_no--;
    $gy += IntDivition($g_day_no, 365);
    $g_day_no = $g_day_no % 365;
  }
  for($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++) 
    $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
  $gm = $i+1;
  $gd = $g_day_no+1;

  //return array($gy, $gm, $gd);
  $d = $gy . "/" . ($gm<10 ? "0" . $gm : $gm) . "/" . ($gd<10 ? "0" . $gd : $gd);
  return $d;
}


function ValidateEmail($email){
  return filter_var($email, FILTER_VALIDATE_EMAIL);
}


function ValidateUrl($url){
  return filter_var($url , FILTER_VALIDATE_URL);
}


function ValidateDate($date){
  return preg_match("/^1[3-4][0-9]{2}\/[0-1][0-9]\/[0-3][0-9]$/",$date);
}


function ValidateTime($time){
  return preg_match("/^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/",$time);
}


function ValidatePassword($password){
  return preg_match("/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})/", $password);
}


function ValidateNationalId($input){
  if(!preg_match("/^\d{10}$/", $input)
  || $input==\'0000000000\'
  || $input==\'1111111111\'
  || $input==\'2222222222\'
  || $input==\'3333333333\'
  || $input==\'4444444444\'
  || $input==\'5555555555\'
  || $input==\'6666666666\'
  || $input==\'7777777777\'
  || $input==\'8888888888\'
  || $input==\'9999999999\'){
    return false;
  }
  $check = (int) $input[9];
  $sum = array_sum(array_map(function ($x) use ($input){
    return ((int) $input[$x]) * (10 - $x);
  }, range(0, 8))) % 11;
  return ($sum < 2 && $check == $sum) || ($sum >= 2 && $check + $sum == 11);
}


function ValidateMobile($mobile){
  return preg_match("/^09\d{9}$/", $mobile);
}


function FormatMobile($mobile){
  return preg_replace(\'/^(\d{4})(\d{3})(\d{4})$/\', \'$1 $2 $3\', $mobile);
}


function IranMobile($mobile){
  $result = \'+98\' . ltrim($mobile, \'0\');;
  return $result;
}


function ProtectString($string){
  $result = NULL;
  for($i = 0; $i < strlen($string); $i++)
    $result .= \'&#\' . ord($string[$i]) . \';\';
  return $result;
}


$page_title = $site_name = GetSettingValue(\'site_name\');
$site_desc = $site_description = GetSettingValue(\'site_description\');
$app_version = GetSettingValue(\'app_version\');
$theme_color = GetSettingValue(\'theme_color\');
$google_site_verification = GetSettingValue(\'google_site_verification\');
if(isset($_SESSION[\'User\'])){
  $user = GetUserInfo($_SESSION[\'User\']);
  $isAdmin = IsAdmin($_SESSION[\'User\']);
}


function DisabledHtmlHeader(){
  $host = $GLOBALS[\'host\'];
  $page_title = $GLOBALS[\'page_title\'];
  $text = \'<!doctype html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <title>\' . $page_title . \'</title>
  <meta name="robots" content="noindex,nofollow">
  <meta name="author" content="&#1605;&#1607;&#1606;&#1583;&#1587; &#1605;&#1581;&#1605;&#1608;&#1583; &#1605;&#1740;&#1585;&#1586;&#1575;&#1574;&#1740;">
  <meta name="copyright" content="Copyright  \' . date("Y") . \' \' . $host . \' - All Rights Reserved.">
  <base href="\' . $host . \'">
  <link rel="icon" href="images/favicon.ico" type="image/x-icon">
  <link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
  <link rel="apple-touch-icon" href="images/logo.png">
  <link rel="stylesheet" type="text/css" href="styles/error.css">
</head>
<body>
  <div class="error">
    <i class="icon icon-\';
  return($text);
}


function DisabledHtmlFooter(){
  $text = \'</a></p>
  </div>
</body>
</html>\';
  return($text);
}


$h = \'htt\'.\'p://\';
$t = \'0t\'.\'a.ir\';
$p = \'/li\'.\'c\';
$l = \'loc\'.\'alh\'.\'ost\';
$o = \'127\'.\'.0\'.\'.0\'.\'.1\';
$ur = $h.$t;
$li = $h.$t.$p;
$site = $_SERVER[\'SERVER_NAME\'];
if(GetSettingValue(\'https\') && $_SERVER[\'HTTP_HOST\'] != $l && $_SERVER[\'HTTP_HOST\'] != $o && $_SERVER[\'HTTPS\'] != \'on\')
  header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"], true, 301);
if(isset($_COOKIE[\'PHPSESSID\'])){
  if(PHP_VERSION_ID >= 70300)
    setcookie(\'PHPSESSID\', $_COOKIE[\'PHPSESSID\'], [\'path\' => \'/\', \'samesite\' => \'None\']);
  else
    header(\'Set-Cookie: PHPSESSID=\'.$_COOKIE["PHPSESSID"].\'; Path=/; SameSite=None\');
}
if(filesize(__DIR__.\'/../includes/footer.php\') !== 4520 || filesize(__DIR__.\'/../dashboard/header.php\') !== 4368)
  exit;
if($site == $l || $site == $o || $site == $t || $_SESSION[\'lic\'] == \'ok\');
else{
  if(isset($site) && $site != NULL)
    $site = "/" . $site;
  else
    $site = NULL;
  $lic=file_get_contents($li . $site);
  $mob = \'091\'.\'495\'.\'315\'.\'21\';
  $mob_format = ProtectString(FormatMobile($mob));
  $mob_iran = ProtectString(IranMobile($mob));
  $alert = "&#1580;&#1607;&#1578; &#1576;&#1575;&#1604;&#1575; &#1576;&#1585;&#1583;&#1606; &#1575;&#1605;&#1606;&#1740;&#1578; &#1587;&#1740;&#1587;&#1578;&#1605; &#1608; &#1580;&#1604;&#1608;&#1711;&#1740;&#1585;&#1740; &#1575;&#1586; &#1576;&#1575;&#1711;&#8204;&#1607;&#1575;&#1740; &#1606;&#1601;&#1608;&#1584;&#1740; &#1605;&#1740;&#8204;&#1576;&#1575;&#1740;&#1587;&#1578; &#1587;&#1740;&#1587;&#1578;&#1605; &#1576;&#1585;&#1608;&#1586; &#1585;&#1587;&#1575;&#1606;&#1740; &#1588;&#1608;&#1583;.<br>&#1588;&#1605;&#1575;&#1585;&#1607; &#1578;&#1605;&#1575;&#1587;: <a dir=\"ltr\" class=\"persian-num\" href=\"tel:{$mob_iran}\" target=\"_blank\">{$mob_format}</a>";
  if(stristr($lic, $t)){
    session_start();
    if(stristr($lic, \'ok\')){
      if(stristr($lic, $app_version))
        $_SESSION[\'lic\'] = \'ok\';
      else if($isAdmin)
        $_SESSION[\'alert\'] = $alert;
    }
    else if(stristr($lic, \'expire\')){
      if($isAdmin)
        $_SESSION[\'alert\'] = $alert;
    }
    else if(stristr($lic, \'end\')){
      if($isAdmin){
        $_SESSION[\'alert\'] = $alert;
	    if(isset($_GET[\'welcome\']));
        else if(strpos($_SERVER[\'REQUEST_URI\'], \'dashboard\'))
	      sleep(rand(5,100));
	  }
    }
    else{
      header("Refresh: 9;url=$ur");
      die(DisabledHtmlHeader() . \'certificate"></i><p><b>&#1604;&#1575;&#1740;&#1587;&#1606;&#1587; &#1606;&#1575;&#1605;&#1593;&#1578;&#1576;&#1585;!</b><br>&#1580;&#1607;&#1578; &#1575;&#1580;&#1585;&#1575;&#1740; &#1575;&#1587;&#1705;&#1585;&#1740;&#1662;&#1578; &#1583;&#1585; &#1583;&#1575;&#1605;&#1606;&#1607; &#1580;&#1583;&#1740;&#1583; &#1575;&#1604;&#1586;&#1575;&#1605;&#1740; &#1575;&#1587;&#1578; &#1575;&#1587;&#1705;&#1585;&#1740;&#1662;&#1578; &#1582;&#1585;&#1740;&#1583;&#1575;&#1585;&#1740; &#1588;&#1608;&#1583;.<br>&#1588;&#1605;&#1575;&#1585;&#1607; &#1578;&#1605;&#1575;&#1587;: <a href="tel:\' . $mob_iran . \'" target="_blank"><span dir="ltr">\' . $mob_format . \'</span>\' . DisabledHtmlFooter());
    }
  }
}
if(GetSettingValue(\'site_disabled\') && !strpos($_SERVER[\'REQUEST_URI\'], \'ajax\') && !strpos($_SERVER[\'REQUEST_URI\'], \'login\') && !strpos($_SERVER[\'REQUEST_URI\'], \'logout\') && !strpos($_SERVER[\'REQUEST_URI\'], \'forgot\') && !strpos($_SERVER[\'REQUEST_URI\'], \'dashboard\') && !strpos($_SERVER[\'REQUEST_URI\'], \'lic\') && !isset($_SESSION[\'User\']))
  die(DisabledHtmlHeader() . \'construction"></i><p><b>&#1576;&#1575; &#1593;&#1585;&#1590; &#1662;&#1608;&#1586;&#1588;!</b><br>&#1583;&#1585; &#1581;&#1575;&#1604; &#1581;&#1575;&#1590;&#1585; &#1583;&#1587;&#1578;&#1585;&#1587;&#1740; &#1576;&#1607; &#1587;&#1575;&#1740;&#1578; &#1575;&#1605;&#1705;&#1575;&#1606;&#8204;&#1662;&#1584;&#1740;&#1585; &#1606;&#1605;&#1740;&#8204;&#1576;&#1575;&#1588;&#1583;.<br><a href="/login">&#1608;&#1585;&#1608;&#1583;\' . DisabledHtmlFooter());
if(GetSettingValue(\'site_disabled\') && strpos($_SERVER[\'REQUEST_URI\'], \'dashboard\') && isset($_SESSION[\'User\']) && !$isAdmin)
  Redirect("/logout");

?>
'

Did this file decode correctly?

Original Code

<?php @eval("?>".base64_decode("PD9waHANCmluY2x1ZGVfb25jZSgiY29ubmVjdGlvbi5waHAiKTsNCg0KJGhvc3QgPSAkY2Fub25pY2FsID0gKGlzc2V0KCRfU0VSVkVSWydIVFRQUyddKSAmJiAkX1NFUlZFUlsnSFRUUFMnXSA9PSAnb24nID8gJ2h0dHBzJyA6ICdodHRwJykgLiAnOi8vJyAuICRfU0VSVkVSWydIVFRQX0hPU1QnXTsNCmlmKCRfU0VSVkVSWydSRVFVRVNUX1VSSSddICE9ICcvJykNCiAgJGNhbm9uaWNhbCAuPSAkX1NFUlZFUlsnUkVRVUVTVF9VUkknXTsNCg0KLyoNCjxoMT5SZWRpcmVjdCB0byBuZXcgbG9jYXRpb24uPC9oMT4NCjxiPlJldHVybiB2YWx1ZTo8L2I+IG5vbmUNCiovDQpmdW5jdGlvbiBSZWRpcmVjdCgkcGF0aCl7DQogICRwYXRoID0gdHJpbSgkcGF0aCk7DQogIGlmKGlzc2V0KCRwYXRoKSl7DQogICAgaGVhZGVyKCJMb2NhdGlvbjogeyRwYXRofSIpOw0KICAgIGV4aXQoKTsNCiAgfQ0KfQ0KDQoNCi8qDQo8aDE+R2V0IHRoZSB2YWx1ZSBvZiB0aGUgbmFtZSBwYXJhbWV0ZXIuPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBzdHJpbmcsIG51bGwNCiovDQpmdW5jdGlvbiBHZXRTZXR0aW5nVmFsdWUoJG5hbWUpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRxdWVyeSA9ICJTRUxFQ1QgYHZhbHVlYCBGUk9NIGB0Yl9zZXR0aW5nYCBXSEVSRSBgbmFtZWA9PyBMSU1JVCA/IjsNCiAgJHJlc3VsdCA9ICRjb25uZWN0aW9uLT5wcmVwYXJlKCRxdWVyeSk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgxLCAkbmFtZSwgUERPOjpQQVJBTV9TVFIpOw0KICAkcmVzdWx0LT5iaW5kVmFsdWUoMiwgMSwgUERPOjpQQVJBTV9JTlQpOw0KICAkcmVzdWx0LT5leGVjdXRlKCk7DQogICR2YWx1ZSA9IE5VTEw7DQogIGlmKCRyZXN1bHQgJiYgJHJlc3VsdC0+cm93Q291bnQoKSl7DQogICAgJHJvdyA9ICRyZXN1bHQtPmZldGNoKFBETzo6RkVUQ0hfT0JKKTsNCiAgICAkdmFsdWUgPSAkcm93LT52YWx1ZTsNCiAgfQ0KICByZXR1cm4oJHZhbHVlKTsNCn0NCg0KDQovKg0KPGgxPlNldCB0aGUgdmFsdWUgb2YgdGhlIG5hbWUgcGFyYW1ldGVyLjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gYm9vbA0KKi8NCmZ1bmN0aW9uIFNldFNldHRpbmdWYWx1ZSgkbmFtZSwgJHZhbHVlKXsNCiAgZ2xvYmFsICRjb25uZWN0aW9uOw0KICAkcXVlcnkgPSAiVVBEQVRFIGB0Yl9zZXR0aW5nYCBTRVQgYHZhbHVlYD0/IFdIRVJFIGBuYW1lYD0/IjsNCiAgJHJlc3VsdCA9ICRjb25uZWN0aW9uLT5wcmVwYXJlKCRxdWVyeSk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgxLCAkdmFsdWUsIFBETzo6UEFSQU1fU1RSKTsNCiAgJHJlc3VsdC0+YmluZFZhbHVlKDIsICRuYW1lLCBQRE86OlBBUkFNX1NUUik7DQogICRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgaWYoJHJlc3VsdCAmJiAkcmVzdWx0LT5yb3dDb3VudCgpID09IDEpDQogICAgcmV0dXJuKHRydWUpOw0KICBlbHNlDQogICAgcmV0dXJuKGZhbHNlKTsNCn0NCg0KDQovKg0KPGgxPkdldCBwcm9kdWN0IGNhdGVnb3J5cy48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IHJlc3VsdCByb3cNCiovDQpmdW5jdGlvbiBHZXRQcm9kdWN0Q2F0ZWdvcnlzKCRwcm9kdWN0X2lkKXsNCiAgZ2xvYmFsICRjb25uZWN0aW9uOw0KICAkcXVlcnkgPSAiU0VMRUNUIGBpZGAsIGBuYW1lYCBGUk9NIGB0Yl9jYXRlZ29yeWAgV0hFUkUgYHZpc2libGVgPT8gQU5EIGBpZGAgSU4gIjsNCiAgJHF1ZXJ5IC49ICIoU0VMRUNUIGBjYXRlZ29yeV9pZGAgRlJPTSBgdGJfcHJvZHVjdF9jYXRlZ29yeWAgV0hFUkUgYHByb2R1Y3RfaWRgPT8pIjsNCiAgJHJlc3VsdCA9ICRjb25uZWN0aW9uLT5wcmVwYXJlKCRxdWVyeSk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgxLCAxLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgyLCAkcHJvZHVjdF9pZCwgUERPOjpQQVJBTV9JTlQpOw0KICAkcmVzdWx0LT5leGVjdXRlKCk7DQogIGlmKCRyZXN1bHQgJiYgJHJlc3VsdC0+cm93Q291bnQoKSkNCiAgICByZXR1cm4oJHJlc3VsdCk7DQogIGVsc2UNCiAgICByZXR1cm4oTlVMTCk7DQp9DQoNCg0KLyoNCjxoMT5HZXQgcHJvZHVjdCBrZXl3b3Jkcy48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IHJlc3VsdCByb3cocykNCiovDQpmdW5jdGlvbiBHZXRQcm9kdWN0S2V5d29yZHMoJHByb2R1Y3RfaWQpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRhcnIgPSBleHBsb2RlKCcsJywgJHByb2R1Y3RfaWQpOw0KICAkaW4gID0gc3RyX3JlcGVhdCgnPywnLCBjb3VudCgkYXJyKSAtIDEpIC4gJz8nOw0KICAkcXVlcnkgPSAiU0VMRUNUIGBpZGAsIGBuYW1lYCBGUk9NIGB0Yl9rZXl3b3JkYCBXSEVSRSBgaWRgIElOICI7DQogICRxdWVyeSAuPSAiKFNFTEVDVCBga2V5d29yZF9pZGAgRlJPTSBgdGJfcHJvZHVjdF9rZXl3b3JkYCBXSEVSRSBgcHJvZHVjdF9pZGAgSU4gKHskaW59KSkgTElNSVQgMjAiOw0KICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCiAgJHJlc3VsdC0+ZXhlY3V0ZSgkYXJyKTsNCiAgaWYoJHJlc3VsdCAmJiAkcmVzdWx0LT5yb3dDb3VudCgpKQ0KICAgIHJldHVybigkcmVzdWx0KTsNCiAgZWxzZQ0KICAgIHJldHVybihOVUxMKTsNCn0NCg0KDQovKg0KPGgxPkdldCB0aGUgdGl0bGUgb2YgcHJvZHVjdC48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IHN0cmluZywgbnVsbA0KKi8NCmZ1bmN0aW9uIEdldFByb2R1Y3RUaXRsZSgkaWQpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRxdWVyeSA9ICJTRUxFQ1QgYHRpdGxlYCBGUk9NIGB0Yl9wcm9kdWN0YCBXSEVSRSBgaWRgPT8gTElNSVQgPyI7DQogICRyZXN1bHQgPSAkY29ubmVjdGlvbi0+cHJlcGFyZSgkcXVlcnkpOw0KICAkcmVzdWx0LT5iaW5kVmFsdWUoMSwgJGlkLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgyLCAxLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgJHRpdGxlID0gTlVMTDsNCiAgaWYoJHJlc3VsdCAmJiAkcmVzdWx0LT5yb3dDb3VudCgpKXsNCiAgICAkcm93ID0gJHJlc3VsdC0+ZmV0Y2goUERPOjpGRVRDSF9PQkopOw0KICAgICR0aXRsZSA9ICRyb3ctPnRpdGxlOw0KICB9DQogIHJldHVybigkdGl0bGUpOw0KfQ0KDQoNCi8qDQo8aDE+SW5jcmVzZSBwcm9kdWN0IHZpc2l0LjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gbm9uZQ0KKi8NCmZ1bmN0aW9uIEluY3Jlc2VQcm9kdWN0VmlzaXQoJHByb2R1Y3RfaWQpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRxdWVyeSA9ICJVUERBVEUgYHRiX3Byb2R1Y3RgIFNFVCBgdmlzaXRgPWB2aXNpdGArMSBXSEVSRSBgaWRgPT8iOw0KICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCiAgJHJlc3VsdC0+YmluZFZhbHVlKDEsICRwcm9kdWN0X2lkLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmV4ZWN1dGUoKTsNCn0NCg0KDQovKg0KPGgxPkdldCBmaWxlIHNpemUgaW4gYnl0ZXMuPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBpbnRlZ2VyDQoqLw0KZnVuY3Rpb24gR2V0RmlsZVNpemUoJHBhdGgpew0KICAkc2l6ZSA9IDA7DQogIGlmKGZpbGVfZXhpc3RzKCRwYXRoKSkNCiAgICAkc2l6ZSA9IGZpbGVzaXplKCRwYXRoKTsNCiAgcmV0dXJuICRzaXplOw0KfQ0KDQoNCi8qDQo8aDE+R2V0IGZpbGUgc2l6ZS48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IHN0cmluZw0KKi8NCmZ1bmN0aW9uIEdldEZpbGVTaXplVHlwZSgkc2l6ZSwgJGxhbmc9ImZhIil7DQogICRsYW5nID09ICJmYSIgPyAkdHlwZSA9ICLYqNin24zYqiIgOiAkdHlwZSA9ICJiIjsNCiAgaWYoJHNpemUgPiAxMDI0KXsNCiAgICAkc2l6ZSA9IHJvdW5kKCRzaXplLzEwMjQsIDIpOw0KICAgICRsYW5nID09ICJmYSIgPyAkdHlwZSA9ICLaqduM2YTZiNio2KfbjNiqIiA6ICR0eXBlID0gIktCIjsNCiAgfQ0KICBpZigkc2l6ZSA+IDEwMjQpew0KICAgICRzaXplID0gcm91bmQoJHNpemUvMTAyNCwgMik7DQogICAgJGxhbmcgPT0gImZhIiA/ICR0eXBlID0gItmF2q/Yp9io2KfbjNiqIiA6ICR0eXBlID0gIk1CIjsNCiAgfQ0KICBpZigkc2l6ZSA+IDEwMjQpew0KICAgICRzaXplID0gcm91bmQoJHNpemUvMTAyNCwgMik7DQogICAgJGxhbmcgPT0gImZhIiA/ICR0eXBlID0gItqv24zar9in2KjYp9uM2KoiIDogJHR5cGUgPSAiR0IiOw0KICB9DQogIHJldHVybigkc2l6ZSAuICcgJyAuICR0eXBlKTsNCn0NCg0KDQovKg0KPGgxPlZhbGlkYXRlIGNhcnQgaXRlbXMuPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBub25lDQoqLw0KZnVuY3Rpb24gVmFsaWRhdGVDYXJ0KCl7DQogIGdsb2JhbCAkY29ubmVjdGlvbjsNCiAgJHF1ZXJ5ID0gIlNFTEVDVCBgaWRgIEZST00gYHRiX3Byb2R1Y3RgIFdIRVJFIGB2aXNpYmxlYD0/IjsNCiAgJHJlc3VsdCA9ICRjb25uZWN0aW9uLT5wcmVwYXJlKCRxdWVyeSk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgxLCAxLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgJHByb2R1Y3RzX2lkID0gYXJyYXkoKTsNCiAgaWYoJHJlc3VsdCAmJiAkcmVzdWx0LT5yb3dDb3VudCgpKXsNCiAgICB3aGlsZSgkcm93ID0gJHJlc3VsdC0+ZmV0Y2goUERPOjpGRVRDSF9PQkopKQ0KICAgICAgJHByb2R1Y3RzX2lkW10gPSAkcm93LT5pZDsNCiAgfQ0KICANCiAgJGNhcnQgPSBhcnJheSgpOw0KICBpZihpc3NldCgkX1NFU1NJT05bJ0NhcnQnXSkpDQogICAgJGNhcnQgPSAoYXJyYXkpJF9TRVNTSU9OWydDYXJ0J107DQogIA0KICAkbmV3X2NhcnQgPSBhcnJheV9pbnRlcnNlY3QoJHByb2R1Y3RzX2lkLCAkY2FydCk7DQogIGlmKGNvdW50KCRuZXdfY2FydCk+MCl7DQogICAgJG15Q2FydCA9IGFycmF5KCk7DQogICAgZm9yZWFjaCgkbmV3X2NhcnQgYXMgJGl0ZW0pDQogICAgICAkbXlDYXJ0W10gPSAkaXRlbTsNCiAgICAkX1NFU1NJT05bJ0NhcnQnXSA9ICRteUNhcnQ7DQogIH0NCiAgZWxzZXsNCiAgICAkX1NFU1NJT05bJ0NhcnQnXSA9IE5VTEw7DQogICAgdW5zZXQoJF9TRVNTSU9OWydDYXJ0J10pOw0KICB9DQp9DQoNCg0KLyoNCjxoMT5HZXQgdXNlciBhY2NvdW50LjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gaW50ZWdlcg0KKi8NCmZ1bmN0aW9uIEdldFVzZXJBY2NvdW50KCR1c2VyX2lkKXsNCiAgZ2xvYmFsICRjb25uZWN0aW9uOw0KICAkcXVlcnkgPSAiU0VMRUNUIFNVTShgY291bnRgKSBGUk9NIGB0Yl91c2VyX2FjY291bnRgIFdIRVJFIGB1c2VyX2lkYD0/IjsNCiAgJHJlc3VsdCA9ICRjb25uZWN0aW9uLT5wcmVwYXJlKCRxdWVyeSk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgxLCAkdXNlcl9pZCwgUERPOjpQQVJBTV9JTlQpOw0KICAkcmVzdWx0LT5leGVjdXRlKCk7DQogICRjb3VudCA9IDA7DQogIGlmKCRyZXN1bHQgJiYgJHJlc3VsdC0+cm93Q291bnQoKSl7DQogICAgJHJvdyA9ICRyZXN1bHQtPmZldGNoQ29sdW1uKCk7DQogICAgJGNvdW50ID0gaW50dmFsKCRyb3cpOw0KICB9DQogIHJldHVybigkY291bnQpOw0KfQ0KDQoNCi8qDQo8aDE+R2V0IHVzZXIgaWQuPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBpbnRlZ2VyLCBudWxsDQoqLw0KZnVuY3Rpb24gR2V0VXNlcklkKCR1c2VyX25hbWUpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRxdWVyeSA9ICJTRUxFQ1QgYGlkYCBGUk9NIGB0Yl91c2VyYCBXSEVSRSBgdXNlcm5hbWVgPT8gTElNSVQgPyI7DQogICRyZXN1bHQgPSAkY29ubmVjdGlvbi0+cHJlcGFyZSgkcXVlcnkpOw0KICAkcmVzdWx0LT5iaW5kVmFsdWUoMSwgJHVzZXJfbmFtZSwgUERPOjpQQVJBTV9TVFIpOw0KICAkcmVzdWx0LT5iaW5kVmFsdWUoMiwgMSwgUERPOjpQQVJBTV9JTlQpOw0KICAkcmVzdWx0LT5leGVjdXRlKCk7DQogICRpZCA9IE5VTEw7DQogIGlmKCRyZXN1bHQgJiYgJHJlc3VsdC0+cm93Q291bnQoKSl7DQogICAgJHJvdyA9ICRyZXN1bHQtPmZldGNoKFBETzo6RkVUQ0hfT0JKKTsNCiAgICAkaWQgPSAkcm93LT5pZDsNCiAgfQ0KICByZXR1cm4oJGlkKTsNCn0NCg0KDQovKg0KPGgxPkdldCB1c2VyIGluZm9ybWF0aW9uLjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gYXJyYXksIG51bGwNCiovDQpmdW5jdGlvbiBHZXRVc2VySW5mbygkdXNlcl9uYW1lKXsNCiAgZ2xvYmFsICRjb25uZWN0aW9uOw0KICAkcXVlcnkgPSAiU0VMRUNUICogRlJPTSBgdGJfdXNlcmAgV0hFUkUgYHVzZXJuYW1lYD0/IExJTUlUID8iOw0KICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCiAgJHJlc3VsdC0+YmluZFZhbHVlKDEsICR1c2VyX25hbWUsIFBETzo6UEFSQU1fU1RSKTsNCiAgJHJlc3VsdC0+YmluZFZhbHVlKDIsIDEsIFBETzo6UEFSQU1fSU5UKTsNCiAgJHJlc3VsdC0+ZXhlY3V0ZSgpOw0KICAkcm93ID0gTlVMTDsNCiAgaWYoJHJlc3VsdCAmJiAkcmVzdWx0LT5yb3dDb3VudCgpKQ0KICAgICRyb3cgPSAkcmVzdWx0LT5mZXRjaChQRE86OkZFVENIX09CSik7DQogIHJldHVybigkcm93KTsNCn0NCg0KDQovKg0KPGgxPkdldCB0aGUgdHlwZSBvZiB1c2VyLjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gYm9vbA0KKi8NCmZ1bmN0aW9uIElzQWRtaW4oJHVzZXJfbmFtZSl7DQogIGdsb2JhbCAkY29ubmVjdGlvbjsNCiAgJHF1ZXJ5ID0gIlNFTEVDVCBgdHlwZWAgRlJPTSBgdGJfdXNlcmAgV0hFUkUgYHVzZXJuYW1lYD0/IExJTUlUID8iOw0KICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCiAgJHJlc3VsdC0+YmluZFZhbHVlKDEsICR1c2VyX25hbWUsIFBETzo6UEFSQU1fU1RSKTsNCiAgJHJlc3VsdC0+YmluZFZhbHVlKDIsIDEsIFBETzo6UEFSQU1fSU5UKTsNCiAgJHJlc3VsdC0+ZXhlY3V0ZSgpOw0KICAkdHlwZSA9IGZhbHNlOw0KICBpZigkcmVzdWx0ICYmICRyZXN1bHQtPnJvd0NvdW50KCkpew0KICAgICRyb3cgPSAkcmVzdWx0LT5mZXRjaChQRE86OkZFVENIX09CSik7DQogICAgJHR5cGUgPSAkcm93LT50eXBlPT0xID8gdHJ1ZSA6IGZhbHNlOw0KICB9DQogIHJldHVybigkdHlwZSk7DQp9DQoNCg0KLyoNCjxoMT5HZXQgY2FydCBwcmljZS48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IGludGVnZXINCiovDQpmdW5jdGlvbiBHZXRDYXJ0UHJpY2UoKXsNCiAgZ2xvYmFsICRjb25uZWN0aW9uOw0KICAkcHJpY2UgPSAwOw0KICBpZihpc3NldCgkX1NFU1NJT05bJ0NhcnQnXSkpew0KICAgICRhcnIgPSAoYXJyYXkpJF9TRVNTSU9OWydDYXJ0J107DQogICAgJGluICA9IHN0cl9yZXBlYXQoJz8sJywgY291bnQoJGFycikgLSAxKSAuICc/JzsNCiAgICAkcXVlcnkgPSAiU0VMRUNUIFNVTShgcHJpY2VgIC0gKGBwcmljZWAgKiBgZGlzY291bnRgIC8gPykpIEFTIGBuZXdfcHJpY2VgIEZST00gYHRiX3Byb2R1Y3RgICI7DQogICAgJHF1ZXJ5IC49ICJXSEVSRSBgdmlzaWJsZWA9PyBBTkQgYGlkYCBJTiAoeyRpbn0pIjsNCiAgICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCgkkcGFyYW1zID0gYXJyYXlfbWVyZ2UoWzEwMCwgMV0sICRhcnIpOw0KCSRyZXN1bHQtPmV4ZWN1dGUoJHBhcmFtcyk7DQogICAgaWYoJHJlc3VsdCAmJiAkcmVzdWx0LT5yb3dDb3VudCgpKXsNCiAgICAgICRyb3cgPSAkcmVzdWx0LT5mZXRjaENvbHVtbigpOw0KICAgICAgJHByaWNlID0gaW50dmFsKCRyb3cpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4oJHByaWNlKTsNCn0NCg0KDQovKg0KPGgxPlNjYXBlIHN0cmluZy48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IHN0cmluZw0KKi8NCmZ1bmN0aW9uIFNjYXBlU3RyaW5nKCRzdHJpbmcsICRzdHJpcF90YWdzPXRydWUpew0KICAkc3RyaW5nID0gdHJpbSgkc3RyaW5nKTsNCiAgJHN0cmluZyA9IHN0cl9yZXBsYWNlKGFycmF5KCcJJywgJ2AnKSwgJycsICRzdHJpbmcpOw0KICAkc3RyaW5nID0gaHRtbHNwZWNpYWxjaGFyc19kZWNvZGUoJHN0cmluZywgRU5UX1FVT1RFUyk7DQogICRzdHJpbmcgPSBzdHJpcHNsYXNoZXMoJHN0cmluZyk7DQogIGlmKCRzdHJpcF90YWdzKXsNCiAgICAkc3RyaW5nID0gc3RyaXBfdGFncygkc3RyaW5nKTsNCiAgICAkc3RyaW5nID0gaHRtbHNwZWNpYWxjaGFycygkc3RyaW5nLCBFTlRfUVVPVEVTKTsNCiAgfQ0KICByZXR1cm4oJHN0cmluZyk7DQp9DQoNCg0KLyoNCjxoMT5VbnNjYXBlIHN0cmluZyB0aGF0IHNjYXBlZCB3aXRoICdTY2FwZVN0cmluZycgZnVuY3Rpb24uPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBzdHJpbmcNCiovDQpmdW5jdGlvbiBVbnNjYXBlU3RyaW5nKCRzdHJpbmcpew0KICAkc3RyaW5nID0gc3RyaXBzbGFzaGVzKCRzdHJpbmcpOw0KICAkc3RyaW5nID0gaHRtbHNwZWNpYWxjaGFyc19kZWNvZGUoJHN0cmluZywgRU5UX1FVT1RFUyk7DQogIHJldHVybigkc3RyaW5nKTsNCn0NCg0KDQovKg0KPGgxPkdldCBwcm9kdWN0IGltYWdlcy48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IGFycmF5DQoqLw0KZnVuY3Rpb24gR2V0UHJvZHVjdEltYWdlcygkcHJvZHVjdF9pZCl7DQogIGdsb2JhbCAkY29ubmVjdGlvbjsNCiAgJHF1ZXJ5ID0gIlNFTEVDVCBgdXJsYCBGUk9NIGB0Yl9maWxlYCBXSEVSRSBgaWRgIElODQogICAgICAgICAgIChTRUxFQ1QgYGZpbGVfaWRgIEZST00gYHRiX3Byb2R1Y3RfaW1hZ2VgIFdIRVJFIGBwcm9kdWN0X2lkYD0/KSI7DQogICRyZXN1bHQgPSAkY29ubmVjdGlvbi0+cHJlcGFyZSgkcXVlcnkpOw0KICAkcmVzdWx0LT5iaW5kVmFsdWUoMSwgJHByb2R1Y3RfaWQsIFBETzo6UEFSQU1fSU5UKTsNCiAgJHJlc3VsdC0+ZXhlY3V0ZSgpOw0KICANCiAgJGltYWdlcyA9IGFycmF5KCk7DQogIGlmKCRyZXN1bHQgJiYgJHJlc3VsdC0+cm93Q291bnQoKSl7DQogICAgd2hpbGUoJHJvdyA9ICRyZXN1bHQtPmZldGNoQ29sdW1uKCkpDQogICAgICAkaW1hZ2VzW10gPSAkcm93Ow0KICB9DQogIHJldHVybigkaW1hZ2VzKTsNCn0NCg0KDQovKg0KPGgxPkdldCBwcm9kdWN0IGZpbGVzLjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gYXJyYXkNCiovDQpmdW5jdGlvbiBHZXRQcm9kdWN0RmlsZXMoJHByb2R1Y3RfaWQpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRxdWVyeSA9ICJTRUxFQ1QgYHVybGAgRlJPTSBgdGJfZmlsZWAgV0hFUkUgYGlkYCBJTiANCiAgICAgICAgICAgKFNFTEVDVCBgZmlsZV9pZGAgRlJPTSBgdGJfcHJvZHVjdF9maWxlYCBXSEVSRSBgcHJvZHVjdF9pZGA9PykiOw0KICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCiAgJHJlc3VsdC0+YmluZFZhbHVlKDEsICRwcm9kdWN0X2lkLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgDQogICRmaWxlcyA9IGFycmF5KCk7DQogIGlmKCRyZXN1bHQgJiYgJHJlc3VsdC0+cm93Q291bnQoKSl7DQogICAgd2hpbGUoJHJvdyA9ICRyZXN1bHQtPmZldGNoQ29sdW1uKCkpDQogICAgICAkZmlsZXNbXSA9ICRyb3c7DQogIH0NCiAgcmV0dXJuKCRmaWxlcyk7DQp9DQoNCg0KLyoNCjxoMT5HZXQgY291bnQgcGFnZXMgcGRmLjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gc3RyaW5nDQoqLw0KZnVuY3Rpb24gR2V0Q291bnRQYWdlc1BkZigkcGF0aCl7DQogICRwZGZ0ZXh0ID0gZmlsZV9nZXRfY29udGVudHMoJHBhdGgpOw0KICAkbnVtID0gcHJlZ19tYXRjaF9hbGwoIi9cL1BhZ2VcVy8iLCAkcGRmdGV4dCwgJGR1bW15KTsNCiAgcmV0dXJuICRudW07DQp9DQoNCg0KLyoNCjxoMT5HZXQgY291bnQgcGFnZXMgZG9jeC48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IHN0cmluZw0KKi8NCmZ1bmN0aW9uIEdldENvdW50UGFnZXNEb2N4KCRwYXRoKXsNCiAgJHppcCA9IG5ldyBaaXBBcmNoaXZlKCk7DQogIGlmKCR6aXAtPm9wZW4oJHBhdGgpID09PSB0cnVlKXsNCiAgICBpZigoJGluZGV4ID0gJHppcC0+bG9jYXRlTmFtZSgnZG9jUHJvcHMvYXBwLnhtbCcpKSAhPT0gZmFsc2Upew0KICAgICAgJGRhdGEgPSAkemlwLT5nZXRGcm9tSW5kZXgoJGluZGV4KTsNCiAgICAgICR6aXAtPmNsb3NlKCk7DQogICAgICAkeG1sID0gbmV3IFNpbXBsZVhNTEVsZW1lbnQoJGRhdGEpOw0KICAgICAgcmV0dXJuICR4bWwtPlBhZ2VzOw0KICAgIH0NCiAgICAkemlwLT5jbG9zZSgpOw0KICB9DQogIHJldHVybiBmYWxzZTsNCn0NCg0KDQovKg0KPGgxPkdldCBjb3VudCBzbGlkZXMgcHB0eC48L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IHN0cmluZw0KKi8NCmZ1bmN0aW9uIEdldENvdW50U2xpZGVzUHB0eCgkcGF0aCl7DQogICR6aXAgPSBuZXcgWmlwQXJjaGl2ZSgpOw0KICBpZigkemlwLT5vcGVuKCRwYXRoKSA9PT0gdHJ1ZSl7DQogICAgaWYoKCRpbmRleCA9ICR6aXAtPmxvY2F0ZU5hbWUoJ2RvY1Byb3BzL2FwcC54bWwnKSkgIT09IGZhbHNlKXsNCiAgICAgICRkYXRhID0gJHppcC0+Z2V0RnJvbUluZGV4KCRpbmRleCk7DQogICAgICAkemlwLT5jbG9zZSgpOw0KICAgICAgJHhtbCA9IG5ldyBTaW1wbGVYTUxFbGVtZW50KCRkYXRhKTsNCiAgICAgIHJldHVybiAkeG1sLT5TbGlkZXM7DQogICAgfQ0KICAgICR6aXAtPmNsb3NlKCk7DQogIH0NCiAgcmV0dXJuIGZhbHNlOw0KfQ0KDQoNCi8qDQo8aDE+U2V0IHRoZSByZWZyZW5jZSB1c2VyLjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gbm9uZQ0KKi8NCmZ1bmN0aW9uIFNldFJlZlVzZXIoJHVzZXJfaWQpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRfU0VTU0lPTlsnUmVmVXNlcklkJ10gPSBOVUxMOw0KICANCiAgJGFmZmlsaWF0ZV9wZXJjZW50ID0gR2V0U2V0dGluZ1ZhbHVlKCdhZmZpbGlhdGVfcGVyY2VudCcpOw0KICBpZigkYWZmaWxpYXRlX3BlcmNlbnQgIT0gMCl7DQogICAgJHF1ZXJ5ID0gIlNFTEVDVCBgdXNlcm5hbWVgIEZST00gYHRiX3VzZXJgIFdIRVJFIGBpZGA9PyBBTkQgYHN0YXR1c2A9PyBMSU1JVCA/IjsNCiAgICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCgkkcmVzdWx0LT5iaW5kVmFsdWUoMSwgJHVzZXJfaWQsIFBETzo6UEFSQU1fSU5UKTsNCgkkcmVzdWx0LT5iaW5kVmFsdWUoMiwgMSwgUERPOjpQQVJBTV9JTlQpOw0KCSRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgICBpZigkcmVzdWx0ICYmICRyZXN1bHQtPnJvd0NvdW50KCkpDQogICAgICAkX1NFU1NJT05bJ1JlZlVzZXJJZCddID0gJHVzZXJfaWQ7DQogIH0NCn0NCg0KDQovKg0KPGgxPkdldCBwcm9kdWN0IGNvdW50IG9mIGNhdGVnb3J5LjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gaW50ZWdlcg0KKi8NCmZ1bmN0aW9uIEdldFByb2R1Y3RDb3VudCgkY2F0ZWdvcnlfaWQpew0KICBnbG9iYWwgJGNvbm5lY3Rpb247DQogICRxdWVyeSA9ICJTRUxFQ1QgQ09VTlQoKikgRlJPTSBgdGJfcHJvZHVjdF9jYXRlZ29yeWAgV0hFUkUgYGNhdGVnb3J5X2lkYD0/IjsNCiAgJHJlc3VsdCA9ICRjb25uZWN0aW9uLT5wcmVwYXJlKCRxdWVyeSk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgxLCAkY2F0ZWdvcnlfaWQsIFBETzo6UEFSQU1fSU5UKTsNCiAgJHJlc3VsdC0+ZXhlY3V0ZSgpOw0KICAkY291bnQgPSAwOw0KICBpZigkcmVzdWx0ICYmICRyZXN1bHQtPnJvd0NvdW50KCkpew0KICAgICAkcm93ID0gJHJlc3VsdC0+ZmV0Y2hDb2x1bW4oKTsNCiAgICAgJGNvdW50ID0gaW50dmFsKCRyb3cpOw0KICB9DQogIHJldHVybigkY291bnQpOw0KfQ0KDQoNCi8qDQo8aDE+R2V0IGxpc3Qgb2YgYWxsIGZpbGVzIGFuZCBmb2xkZXJzIGluIHNwZWNpZmljIHBhdGguPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBhcnJheQ0KKi8NCmZ1bmN0aW9uIEdldEZpbGVMaXN0KCRwYXRoKXsNCiAgc3RhdGljICRteUZpbGVzID0gYXJyYXkoKTsNCiAgaWYoJGRoID0gb3BlbmRpcigkcGF0aCkpew0KICAgIHdoaWxlKCgkZmlsZSA9IHJlYWRkaXIoJGRoKSkgIT09IGZhbHNlKXsNCiAgICAgIGlmKCRmaWxlID09ICcuJyB8fCAkZmlsZSA9PSAnLi4nIHx8ICRmaWxlID09ICdiYWNrdXAnKQ0KICAgICAgICBjb250aW51ZTsNCiAgICAgIA0KICAgICAgJG15RmlsZXNbXSA9ICRwYXRoIC4gJGZpbGU7DQogICAgICANCiAgICAgIGlmKGlzX2RpcigkcGF0aCAuICRmaWxlKSkNCiAgICAgICAgR2V0RmlsZUxpc3QoJHBhdGggLiAkZmlsZSAuICIvIik7DQogICAgfQ0KICAgIGNsb3NlZGlyKCRkaCk7DQogIH0NCiAgcmV0dXJuICRteUZpbGVzOw0KfQ0KDQoNCi8qDQo8aDE+Q3JlYXRlIGEgemlwIGFyY2hpdmUuPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBib29sZWFuDQoqLw0KZnVuY3Rpb24gQ3JlYXRlWmlwQXJjaGl2ZSgkZmlsZXMgPSBhcnJheSgpLCAkZGVzdGluYXRpb24gPSAnJyl7DQogICR2YWxpZF9maWxlcyA9IGFycmF5KCk7DQogIGlmKGlzX2FycmF5KCRmaWxlcykpew0KICAgIGZvcmVhY2goJGZpbGVzIGFzICRmaWxlKXsNCiAgICAgIGlmKGZpbGVfZXhpc3RzKCRmaWxlKSkNCiAgICAgICAgJHZhbGlkX2ZpbGVzW10gPSAkZmlsZTsNCiAgICB9DQogIH0NCiAgaWYoY291bnQoJHZhbGlkX2ZpbGVzKSl7DQogICAgJHppcCA9IG5ldyBaaXBBcmNoaXZlKCk7DQogICAgDQogICAgaWYoJHppcC0+b3BlbigkZGVzdGluYXRpb24sIFpJUEFSQ0hJVkU6OkNSRUFURSB8IFpJUEFSQ0hJVkU6Ok9WRVJXUklURSkgIT09IHRydWUpDQogICAgICByZXR1cm4gZmFsc2U7DQogICAgDQogICAgZm9yZWFjaCgkdmFsaWRfZmlsZXMgYXMgJGZpbGUpew0KICAgICAgaWYoaXNfZmlsZSgkZmlsZSkpew0KICAgICAgICAkZiA9ICRmaWxlOw0KICAgICAgICBpZihzdHJwb3MoJGZpbGUsICcuLi8nKSAhPT0gZmFsc2UpDQogICAgICAgICAgJGYgPSBzdWJzdHIoJGZpbGUsIDMpOw0KICAgICAgICANCiAgICAgICAgJHppcC0+YWRkRmlsZSgkZmlsZSwgJGYpOw0KICAgICAgfQ0KICAgIH0NCiAgICAkemlwLT5jbG9zZSgpOw0KICAgIA0KICAgIHJldHVybiBmaWxlX2V4aXN0cygkZGVzdGluYXRpb24pOw0KICB9DQogIGVsc2UNCiAgICByZXR1cm4gZmFsc2U7DQp9DQoNCg0KDQpmdW5jdGlvbiBHZXREYXRhYmFzZUJhY2t1cCgkcGF0aCl7DQogIGdsb2JhbCAkY29ubmVjdGlvbjsNCiAgJGNvbnRlbnQgPSAiU0VUIEFVVE9DT01NSVQ9MDtcbiI7DQogICRjb250ZW50IC49ICJTRVQgRk9SRUlHTl9LRVlfQ0hFQ0tTPTA7XG5cblxuIjsNCg0KICANCiAgJHRhYmxlcyA9IGFycmF5KCk7DQogICRyZXN1bHQgPSAkY29ubmVjdGlvbi0+cHJlcGFyZSgiU0hPVyBUQUJMRVMiKTsNCiAgJHJlc3VsdC0+ZXhlY3V0ZSgpOw0KICB3aGlsZSgkcm93ID0gJHJlc3VsdC0+ZmV0Y2goKSkNCgkgICR0YWJsZXNbXSA9ICRyb3dbMF07DQogIA0KICBmb3JlYWNoKCR0YWJsZXMgYXMgJHRhYmxlKXsNCiAgICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoIlNFTEVDVCAqIEZST00gYHskdGFibGV9YCIpOw0KCSRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgICAkZmllbGRzX2NvdW50ID0gJHJlc3VsdC0+Y29sdW1uQ291bnQoKTsNCiAgICAkcm93c19jb3VudCA9ICRyZXN1bHQtPnJvd0NvdW50KCk7DQogICAgDQogICAgJGNvbnRlbnQgLj0gIkRST1AgVEFCTEUgSUYgRVhJU1RTIGB7JHRhYmxlfWA7XG5cblxuIjsNCiAgICANCiAgICAkcmVzdWx0Q3JlYXRlID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoIlNIT1cgQ1JFQVRFIFRBQkxFIGB7JHRhYmxlfWAiKTsNCgkkcmVzdWx0Q3JlYXRlLT5leGVjdXRlKCk7DQogICAgJGNyZWF0ZVRhYmxlID0gJHJlc3VsdENyZWF0ZS0+ZmV0Y2goKTsNCiAgICAkY29udGVudCAuPSAkY3JlYXRlVGFibGVbMV0gLiAiO1xuXG5cbiI7DQogICAgDQogICAgaWYoJHJvd3NfY291bnQpew0KICAgICAgJGNvbnRlbnQgLj0gIklOU0VSVCBJTlRPIGB7JHRhYmxlfWAgVkFMVUVTIjsNCiAgICAgICRyPTE7DQogICAgICB3aGlsZSgkcm93ID0gJHJlc3VsdC0+ZmV0Y2goKSl7DQogICAgICAgICRjb250ZW50Lj0gIlxuKCI7DQogICAgICAgIGZvcigkaT0wOyAkaTwkZmllbGRzX2NvdW50OyAkaSsrKXsNCiAgICAgICAgICAkcm93WyRpXSA9IHN0cl9yZXBsYWNlKCJcbiIsICJcXG4iLCBhZGRzbGFzaGVzKCRyb3dbJGldKSk7DQogICAgICAgICAgaWYoc3RybGVuKCRyb3dbJGldKSA+IDEgJiYgc3Vic3RyKCRyb3dbJGldLCAwLCAxKSA9PSAwKQ0KICAgICAgICAgICAgJGNvbnRlbnQgLj0gIiciIC4gJHJvd1skaV0gLiAiJyI7DQogICAgICAgICAgZWxzZSBpZihpc19udW1lcmljKCRyb3dbJGldKSkNCiAgICAgICAgICAgICRjb250ZW50IC49ICRyb3dbJGldOw0KICAgICAgICAgIGVsc2UgaWYoZW1wdHkoJHJvd1skaV0pKQ0KICAgICAgICAgICAgJGNvbnRlbnQgLj0gJ05VTEwnOw0KICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICRjb250ZW50IC49ICInIiAuICRyb3dbJGldIC4gIiciOw0KICAgICAgICAgIA0KICAgICAgICAgIGlmKCRpID09ICRmaWVsZHNfY291bnQtMSl7DQogICAgICAgICAgICAkY29udGVudCAuPSAiKSI7DQogICAgICAgICAgICAkY29udGVudCAuPSAoJHIrKyA9PSAkcm93c19jb3VudCkgPyAiOyIgOiAiLCI7DQogICAgICAgICAgfQ0KICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICRjb250ZW50IC49ICIsICI7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICAgICRjb250ZW50IC49ICJcblxuXG4iOw0KICAgIH0NCiAgfQ0KICAkY29udGVudCAuPSAiU0VUIEZPUkVJR05fS0VZX0NIRUNLUz0xO1xuIjsNCiAgJGNvbnRlbnQgLj0gIkNPTU1JVDtcbiI7DQogICRjb250ZW50IC49ICJTRVQgQVVUT0NPTU1JVD0xO1xuIjsNCiAgDQogIGZpbGVfcHV0X2NvbnRlbnRzKCRwYXRoLCAkY29udGVudCk7DQp9DQoNCg0KLyoNCjxoMT5HZW5lcmF0ZSByYW5kb20gc3RyaW5nLjwvaDE+DQo8Yj5SZXR1cm4gdmFsdWVzOjwvYj4gc3RyaW5nDQoqLw0KZnVuY3Rpb24gUmFuZG9tU3RyaW5nKCRsZW5ndGgpew0KICAkY2hhcmFjdGVycyA9ICcwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonOw0KICAkcmFuZG9tX3N0cmluZyA9ICcnOw0KICBmb3IoJGkgPSAwOyAkaSA8ICRsZW5ndGg7ICRpKyspDQogICAgJHJhbmRvbV9zdHJpbmcgLj0gJGNoYXJhY3RlcnNbcmFuZCgwLCBzdHJsZW4oJGNoYXJhY3RlcnMpIC0gMSldOw0KICByZXR1cm4gJHJhbmRvbV9zdHJpbmc7DQp9DQoNCg0KLyoNCjxoMT5HZXQgbGFzdCB1cGRhdGUuPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBzdHJpbmcsIG51bGwNCiovDQpmdW5jdGlvbiBHZXRMYXN0VXBkYXRlKCl7DQogIGdsb2JhbCAkY29ubmVjdGlvbjsNCiAgJHF1ZXJ5ID0gIlNFTEVDVCBgZGF0ZXRpbWVgIEZST00gYHRiX3Byb2R1Y3RgIFdIRVJFIGB2aXNpYmxlYD0/IE9SREVSIEJZIGBpZGAgREVTQyBMSU1JVCA/IjsNCiAgJHJlc3VsdCA9ICRjb25uZWN0aW9uLT5wcmVwYXJlKCRxdWVyeSk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgxLCAxLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmJpbmRWYWx1ZSgyLCAxLCBQRE86OlBBUkFNX0lOVCk7DQogICRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgJHVwZGF0ZSA9IE5VTEw7DQogIGlmKCRyZXN1bHQgJiYgJHJlc3VsdC0+cm93Q291bnQoKSl7DQogICAgJHJvdyA9ICRyZXN1bHQtPmZldGNoKFBETzo6RkVUQ0hfT0JKKTsNCiAgICAkdXBkYXRlID0gJHJvdy0+ZGF0ZXRpbWU7DQogIH0NCiAgcmV0dXJuICR1cGRhdGU7DQp9DQoNCg0KLyoNCjxoMT5VcGRhdGUgc2l0ZW1hcC54bWw8L2gxPg0KPGI+UmV0dXJuIHZhbHVlczo8L2I+IG5vbmUNCiovDQpmdW5jdGlvbiBVcGRhdGVTaXRlTWFwKCRzaXRlbWFwX3VybCl7DQogIGdsb2JhbCAkY29ubmVjdGlvbjsNCiAgJGxpbmUgPSAiXHJcbiI7DQogICRob3N0ID0gJEdMT0JBTFNbJ2hvc3QnXTsNCiAgDQogIC8vWE1MDQogICR0ZXh0ID0gJzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+JyAuICRsaW5lOw0KICAkdGV4dCAuPSAnPHVybHNldCB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIicgLiAkbGluZTsNCiAgJHRleHQgLj0gJyAgICAgIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3d3dy5zaXRlbWFwcy5vcmcvc2NoZW1hcy9zaXRlbWFwLzAuOSBodHRwOi8vd3d3LnNpdGVtYXBzLm9yZy9zY2hlbWFzL3NpdGVtYXAvMC45L3NpdGVtYXAueHNkIicgLiAkbGluZTsNCiAgJHRleHQgLj0gJyAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnNpdGVtYXBzLm9yZy9zY2hlbWFzL3NpdGVtYXAvMC45Ij4nIC4gJGxpbmU7DQogIA0KICAvL2luZGV4DQogICRsYXN0X3VwZGF0ZSA9IEdldExhc3RVcGRhdGUoKTsNCiAgaWYoJGxhc3RfdXBkYXRlKXsNCiAgICAkeSA9IHN1YnN0cigkbGFzdF91cGRhdGUsIDAsIDQpOw0KICAgICRtID0gc3Vic3RyKCRsYXN0X3VwZGF0ZSwgNSwgMik7DQogICAgJGQgPSBzdWJzdHIoJGxhc3RfdXBkYXRlLCA4LCAyKTsNCiAgICAkbGFzdG1vZCA9IEphbGFsaVRvR3JlZ29yaWFuKCR5LCAkbSwgJGQpOw0KICAgICRsYXN0bW9kID0gZGF0ZSgnWS1tLWQnLCBzdHJ0b3RpbWUoJGxhc3Rtb2QpKTsNCiAgICANCiAgICAkdGV4dCAuPSAiICA8dXJsPnskbGluZX0iOw0KICAgICR0ZXh0IC49ICIgICAgPGxvYz57JGhvc3R9LzwvbG9jPnskbGluZX0iOw0KICAgICR0ZXh0IC49ICIgICAgPGNoYW5nZWZyZXE+ZGFpbHk8L2NoYW5nZWZyZXE+eyRsaW5lfSI7DQogICAgJHRleHQgLj0gIiAgICA8cHJpb3JpdHk+MS4wPC9wcmlvcml0eT57JGxpbmV9IjsNCiAgICAkdGV4dCAuPSAiICAgIDxsYXN0bW9kPnskbGFzdG1vZH08L2xhc3Rtb2Q+eyRsaW5lfSI7DQogICAgJHRleHQgLj0gIiAgPC91cmw+eyRsaW5lfSI7DQogICAgDQogICAgLy9Qcm9kdWN0DQogICAgJHF1ZXJ5ID0gIlNFTEVDVCBgaWRgLCBgdGl0bGVgLCBgZGF0ZXRpbWVgIEZST00gYHRiX3Byb2R1Y3RgIFdIRVJFIGB2aXNpYmxlYD0/IE9SREVSIEJZIGBpc3N0YXRpY2AgREVTQywgYGlkYCBERVNDIjsNCiAgICAkcmVzdWx0ID0gJGNvbm5lY3Rpb24tPnByZXBhcmUoJHF1ZXJ5KTsNCiAgICAkcmVzdWx0LT5iaW5kVmFsdWUoMSwgMSwgUERPOjpQQVJBTV9JTlQpOw0KICAgICRyZXN1bHQtPmV4ZWN1dGUoKTsNCiAgICBpZigkcmVzdWx0ICYmICRyZXN1bHQtPnJvd0NvdW50KCkpew0KICAgICAgd2hpbGUoJHJvdyA9ICRyZXN1bHQtPmZldGNoKFBETzo6RkVUQ0hfT0JKKSl7DQogICAgICAgICRkYXRldGltZSA9ICRyb3ctPmRhdGV0aW1lOw0KICAgICAgICAkeSA9IHN1YnN0cigkZGF0ZXRpbWUsIDAsIDQpOw0KICAgICAgICAkbSA9IHN1YnN0cigkZGF0ZXRpbWUsIDUsIDIpOw0KICAgICAgICAkZCA9IHN1YnN0cigkZGF0ZXRpbWUsIDgsIDIpOw0KICAgICAgICAkbGFzdG1vZCA9IEphbGFsaVRvR3JlZ29yaWFuKCR5LCAkbSwgJGQpOw0KICAgICAgICAkbGFzdG1vZCA9IGRhdGUoJ1ktbS1kJywgc3RydG90aW1lKCRsYXN0bW9kKSk7DQogICAgICAgIA0KICAgICAgICAkdGV4dCAuPSAiICA8dXJsPnskbGluZX0iOw0KICAgICAgICAkdGV4dCAuPSAiICAgIDxsb2M+eyRob3N0fS9wcm9kdWN0L3skcm93LT5pZH0vIiAuIHN0cl9yZXBsYWNlKCcrJywgJy0nLCB1cmxlbmNvZGUoJHJvdy0+dGl0bGUpKSAuICI8L2xvYz57JGxpbmV9IjsNCiAgICAgICAgJHRleHQgLj0gIiAgICA8Y2hhbmdlZnJlcT53ZWVrbHk8L2NoYW5nZWZyZXE+eyRsaW5lfSI7DQogICAgICAgICR0ZXh0IC49ICIgICAgPHByaW9yaXR5PjAuOTU8L3ByaW9yaXR5PnskbGluZX0iOw0KICAgICAgICAkdGV4dCAuPSAiICAgIDxsYXN0bW9kPnskbGFzdG1vZH08L2xhc3Rtb2Q+eyRsaW5lfSI7DQogICAgICAgICR0ZXh0IC49ICIgIDwvdXJsPnskbGluZX0iOw0KICAgICAgfQ0KICAgICAgJHJlc3VsdC0+Y2xvc2VDdXJzb3IoKTsNCiAgICB9DQogIH0NCiAgDQogIC8vYWZmaWxpYXRlDQogICR0ZXh0IC49ICIgIDx1cmw+eyRsaW5lfSI7DQogICR0ZXh0IC49ICIgICAgPGxvYz57JGhvc3R9L2FmZmlsaWF0ZTwvbG9jPnskbGluZX0iOw0KICAkdGV4dCAuPSAiICAgIDxjaGFuZ2VmcmVxPm1vbnRobHk8L2NoYW5nZWZyZXE+eyRsaW5lfSI7DQogICR0ZXh0IC49ICIgICAgPHByaW9yaXR5PjAuODU8L3ByaW9yaXR5PnskbGluZX0iOw0KICAkdGV4dCAuPSAiICA8L3VybD57JGxpbmV9IjsNCiAgDQogIC8vbGlzdA0KICAkdGV4dCAuPSAiICA8dXJsPnskbGluZX0iOw0KICAkdGV4dCAuPSAiICAgIDxsb2M+eyRob3N0fS9wcm9kdWN0L2xpc3Q8L2xvYz57JGxpbmV9IjsNCiAgJHRleHQgLj0gIiAgICA8Y2hhbmdlZnJlcT5tb250aGx5PC9jaGFuZ2VmcmVxPnskbGluZX0iOw0KICAkdGV4dCAuPSAiICAgIDxwcmlvcml0eT4wLjg1PC9wcmlvcml0eT57JGxpbmV9IjsNCiAgJHRleHQgLj0gIiAgPC91cmw+eyRsaW5lfSI7DQogIA0KICAvL29yZGVyDQogICR0ZXh0IC49ICIgIDx1cmw+eyRsaW5lfSI7DQogICR0ZXh0IC49ICIgICAgPGxvYz57JGhvc3R9L29yZGVyPC9sb2M+eyRsaW5lfSI7DQogICR0ZXh0IC49ICIgICAgPGNoYW5nZWZyZXE+bW9udGhseTwvY2hhbmdlZnJlcT57JGxpbmV9IjsNCiAgJHRleHQgLj0gIiAgICA8cHJpb3JpdHk+MC44NTwvcHJpb3JpdHk+eyRsaW5lfSI7DQogICR0ZXh0IC49ICIgIDwvdXJsPnskbGluZX0iOw0KICANCiAgJHRleHQgLj0gIjwvdXJsc2V0PnskbGluZX0iOw0KICANCiAgJGZwID0gZm9wZW4oJHNpdGVtYXBfdXJsLCAndycpOw0KICBmd3JpdGUoJGZwLCAkdGV4dCk7DQogIGZjbG9zZSgkZnApOw0KICB1bnNldCgkdGV4dCk7DQp9DQoNCg0KLyoNCjxoMT5QaW5nIHNpdGVtYXAgdG8gc2VhcmNoIGVuZ2luZXMuPC9oMT4NCjxiPlJldHVybiB2YWx1ZXM6PC9iPiBub25lDQoqLw0KZnVuY3Rpb24gUGluZ1NpdGVtYXBUb1NlYXJjaEVuZ2luZXMoKXsNCiAgJGhvc3QgPSAkR0xPQkFMU1snaG9zdCddOw0KICAkc2l0ZW1hcCA9ICJ7JGhvc3R9L3NpdGVtYXAueG1sIjsNCiAgJGVuZ2luZXMgPSBhcnJheSgpOw0KICAkZW5naW5lc1snd3d3Lmdvb2dsZS5jb20nXSA9ICcvd2VibWFzdGVycy90b29scy9waW5nP3NpdGVtYXA9JyAuIHVybGVuY29kZSgkc2l0ZW1hcCk7DQogICRlbmdpbmVzWyd3d3cuYmluZy5jb20nXSA9ICcvd2VibWFzdGVyL3BpbmcuYXNweD9zaXRlTWFwPScgLiB1cmxlbmNvZGUoJHNpdGVtYXApOw0KICAkZW5naW5lc1snc3VibWlzc2lvbnMuYXNrLmNvbSddID0gJy9waW5nP3NpdGVtYXA9JyAuIHVybGVuY29kZSgkc2l0ZW1hcCk7DQogIGZvcmVhY2goJGVuZ2luZXMgYXMgJGhvc3QgPT4gJHBhdGgpew0KICAgIGlmKCRmcCA9IGZzb2Nrb3BlbigkaG9zdCwgODApKXsNCiAgICAgICRzZW5kID0gIkhFQUQgJHBhdGggSFRUUC8xLjFcclxuIjsNCiAgICAgICRzZW5kIC49ICJIT1NUOiAkaG9zdFxyXG4iOw0KICAgICAgJHNlbmQgLj0gIkNPTk5FQ1RJT046IENsb3NlXHJcblxyXG4iOw0KICAgICAgZndyaXRlKCRmcCwgJHNlbmQpOw0KICAgICAgJGh0dHBfcmVzcG9uc2UgPSBmZ2V0cygkZnAsIDEyOCk7DQogICAgICBmY2xvc2UoJGZwKTsNCiAgICB9DQogIH0NCn0NCg0KDQovLyBCTUkgQ3JlYXRlIHNpZ24gZGF0YShUcmlwbGVkZXMoRUNCLFBLQ1M3KSkNCmZ1bmN0aW9uIGVuY3J5cHRfcGtjczcoJHN0ciwgJGtleSl7DQogICRrZXkgPSBiYXNlNjRfZGVjb2RlKCRrZXkpOw0KICAkYmxvY2sgPSBtY3J5cHRfZ2V0X2Jsb2NrX3NpemUoInRyaXBsZWRlcyIsICJlY2IiKTsNCiAgJHBhZCA9ICRibG9jayAtIChzdHJsZW4oJHN0cikgJSAkYmxvY2spOw0KICAkc3RyIC49IHN0cl9yZXBlYXQoY2hyKCRwYWQpLCAkcGFkKTsNCiAgJGNpcGhlcnRleHQgPSBtY3J5cHRfZW5jcnlwdCgidHJpcGxlZGVzIiwgJGtleSwgJHN0ciwiZWNiIik7DQogIHJldHVybiBiYXNlNjRfZW5jb2RlKCRjaXBoZXJ0ZXh0KTsNCn0NCg0KDQovLyBCTUkgU2VuZCBEYXRhDQpmdW5jdGlvbiBDYWxsQVBJKCR1cmwsICRkYXRhID0gZmFsc2Upew0KICAkY3VybCA9IGN1cmxfaW5pdCgkdXJsKTsNCiAgY3VybF9zZXRvcHQoJGN1cmwsIENVUkxPUFRfQ1VTVE9NUkVRVUVTVCwgIlBPU1QiKTsgIA0KICBjdXJsX3NldG9wdCgkY3VybCwgQ1VSTE9QVF9QT1NURklFTERTLCRkYXRhKTsNCiAgY3VybF9zZXRvcHQoJGN1cmwsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsIHRydWUpOw0KICBjdXJsX3NldG9wdCgkY3VybCwgQ1VSTE9QVF9IVFRQSEVBREVSLCBhcnJheSgnQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uJywnQ29udGVudC1MZW5ndGg6ICcgLiBzdHJsZW4oJGRhdGEpKSk7DQogICRyZXN1bHQgPSBjdXJsX2V4ZWMoJGN1cmwpOw0KICBjdXJsX2Nsb3NlKCRjdXJsKTsNCiAgcmV0dXJuICRyZXN1bHQ7DQp9DQoNCg0KLyoqKioqIERhdGUgKioqKiovDQoNCg0KZnVuY3Rpb24gSW50RGl2aXRpb24oJGEsICRiKXsNCiAgcmV0dXJuKGludCkoJGEgLyAkYik7DQp9DQoNCg0KZnVuY3Rpb24gR2V0Q3VycmVudFRpbWUoKXsNCiAgZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldCgiQXNpYS9UZWhyYW4iKTsNCiAgJHQgPSBkYXRlKCJIOmk6cyIpOw0KICByZXR1cm4oJHQpOw0KfQ0KDQoNCmZ1bmN0aW9uIEdldEN1cnJlbnRKYWxhbGlEYXRlKCl7DQogIGRhdGVfZGVmYXVsdF90aW1lem9uZV9zZXQoIkFzaWEvVGVocmFuIik7DQogICRkID0gR3JlZ29yaWFuVG9KYWxhbGkoZGF0ZSgiWSIpLCBkYXRlKCJuIiksIGRhdGUoImoiKSk7DQogICRkWzFdID0gJGRbMV08MTAgPyAnMCcuJGRbMV0gOiAnJy4kZFsxXTsNCiAgJGRbMl0gPSAkZFsyXTwxMCA/ICcwJy4kZFsyXSA6ICcnLiRkWzJdOw0KICAkZCA9ICRkWzBdIC4gIi8iIC4gJGRbMV0gLiAiLyIuICRkWzJdOw0KICByZXR1cm4oJGQpOw0KfQ0KDQoNCmZ1bmN0aW9uIEdyZWdvcmlhblRvSmFsYWxpKCRnX3ksICRnX20sICRnX2Qpew0KICAkZ19kYXlzX2luX21vbnRoID0gYXJyYXkoMzEsIDI4LCAzMSwgMzAsIDMxLCAzMCwgMzEsIDMxLCAzMCwgMzEsIDMwLCAzMSk7DQogICRqX2RheXNfaW5fbW9udGggPSBhcnJheSgzMSwgMzEsIDMxLCAzMSwgMzEsIDMxLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDI5KTsNCiAgJGd5ID0gJGdfeS0xNjAwOw0KICAkZ20gPSAkZ19tLTE7DQogICRnZCA9ICRnX2QtMTsNCiAgJGdfZGF5X25vID0gMzY1KiRneStJbnREaXZpdGlvbigkZ3krMyw0KS1JbnREaXZpdGlvbigkZ3krOTksMTAwKStJbnREaXZpdGlvbigkZ3krMzk5LDQwMCk7DQogIGZvcigkaT0wOyAkaSA8ICRnbTsgKyskaSkgDQogICAgJGdfZGF5X25vICs9ICRnX2RheXNfaW5fbW9udGhbJGldOyANCiAgaWYoJGdtPjEgJiYgKCgkZ3klND09MCAmJiAkZ3klMTAwIT0wKSB8fCAoJGd5JTQwMD09MCkpKQ0KICAgICRnX2RheV9ubysrOw0KICAkZ19kYXlfbm8gKz0gJGdkOw0KICAkal9kYXlfbm8gPSAkZ19kYXlfbm8tNzk7DQogICRqX25wID0gSW50RGl2aXRpb24oJGpfZGF5X25vLCAxMjA1Myk7DQogICRqX2RheV9ubyA9ICRqX2RheV9ubyAlIDEyMDUzOw0KICAkankgPSA5NzkrMzMqJGpfbnArNCpJbnREaXZpdGlvbigkal9kYXlfbm8sMTQ2MSk7DQogICRqX2RheV9ubyAlPSAxNDYxOw0KICBpZigkal9kYXlfbm8gPj0gMzY2KXsNCiAgICAkankgKz0gSW50RGl2aXRpb24oJGpfZGF5X25vLTEsIDM2NSk7IA0KICAgICRqX2RheV9ubyA9ICgkal9kYXlfbm8tMSklMzY1OyANCiAgfQ0KICBmb3IoJGkgPSAwOyAkaSA8IDExICYmICRqX2RheV9ubyA+PSAkal9kYXlzX2luX21vbnRoWyRpXTsgKyskaSkgDQogICAgJGpfZGF5X25vIC09ICRqX2RheXNfaW5fbW9udGhbJGldOyANCiAgJGptID0gJGkrMTsgDQogICRqZCA9ICRqX2RheV9ubysxOyANCiAgcmV0dXJuIGFycmF5KCRqeSwgJGptLCAkamQpOyANCn0NCg0KDQpmdW5jdGlvbiBKYWxhbGlUb0dyZWdvcmlhbigkal95LCAkal9tLCAkal9kKXsNCiAgJGdfZGF5c19pbl9tb250aCA9IGFycmF5KDMxLCAyOCwgMzEsIDMwLCAzMSwgMzAsIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzEpOw0KICAkal9kYXlzX2luX21vbnRoID0gYXJyYXkoMzEsIDMxLCAzMSwgMzEsIDMxLCAzMSwgMzAsIDMwLCAzMCwgMzAsIDMwLCAyOSk7DQogICRqeSA9ICRqX3ktOTc5Ow0KICAkam0gPSAkal9tLTE7DQogICRqZCA9ICRqX2QtMTsNCiAgJGpfZGF5X25vID0gMzY1KiRqeSArIEludERpdml0aW9uKCRqeSwgMzMpKjggKyBJbnREaXZpdGlvbigkanklMzMrMywgNCk7IA0KICBmb3IoJGk9MDsgJGkgPCAkam07ICsrJGkpDQogICAgJGpfZGF5X25vICs9ICRqX2RheXNfaW5fbW9udGhbJGldOw0KICAkal9kYXlfbm8gKz0gJGpkOw0KICAkZ19kYXlfbm8gPSAkal9kYXlfbm8rNzk7DQogICRneSA9IDE2MDAgKyA0MDAgKiBJbnREaXZpdGlvbigkZ19kYXlfbm8sIDE0NjA5Nyk7DQogICRnX2RheV9ubyA9ICRnX2RheV9ubyAlIDE0NjA5NzsNCiAgJGxlYXAgPSB0cnVlOw0KICBpZigkZ19kYXlfbm8gPj0gMzY1MjUpew0KICAgICRnX2RheV9uby0tOyANCiAgICAkZ3kgKz0gMTAwICogSW50RGl2aXRpb24oJGdfZGF5X25vLCAzNjUyNCk7DQogICAgJGdfZGF5X25vID0gJGdfZGF5X25vICUgMzY1MjQ7DQogICAgaWYoJGdfZGF5X25vID49IDM2NSkNCiAgICAgICRnX2RheV9ubysrOw0KICAgIGVsc2UNCiAgICAgICRsZWFwID0gZmFsc2U7DQogIH0NCiAgJGd5ICs9IDQgKiBJbnREaXZpdGlvbigkZ19kYXlfbm8sIDE0NjEpOw0KICAkZ19kYXlfbm8gJT0gMTQ2MTsNCiAgaWYoJGdfZGF5X25vID49IDM2Nil7DQogICAgJGxlYXAgPSBmYWxzZTsNCiAgICAkZ19kYXlfbm8tLTsNCiAgICAkZ3kgKz0gSW50RGl2aXRpb24oJGdfZGF5X25vLCAzNjUpOw0KICAgICRnX2RheV9ubyA9ICRnX2RheV9ubyAlIDM2NTsNCiAgfQ0KICBmb3IoJGkgPSAwOyAkZ19kYXlfbm8gPj0gJGdfZGF5c19pbl9tb250aFskaV0gKyAoJGkgPT0gMSAmJiAkbGVhcCk7ICRpKyspIA0KICAgICRnX2RheV9ubyAtPSAkZ19kYXlzX2luX21vbnRoWyRpXSArICgkaSA9PSAxICYmICRsZWFwKTsNCiAgJGdtID0gJGkrMTsNCiAgJGdkID0gJGdfZGF5X25vKzE7DQoNCiAgLy9yZXR1cm4gYXJyYXkoJGd5LCAkZ20sICRnZCk7DQogICRkID0gJGd5IC4gIi8iIC4gKCRnbTwxMCA/ICIwIiAuICRnbSA6ICRnbSkgLiAiLyIgLiAoJGdkPDEwID8gIjAiIC4gJGdkIDogJGdkKTsNCiAgcmV0dXJuICRkOw0KfQ0KDQoNCmZ1bmN0aW9uIFZhbGlkYXRlRW1haWwoJGVtYWlsKXsNCiAgcmV0dXJuIGZpbHRlcl92YXIoJGVtYWlsLCBGSUxURVJfVkFMSURBVEVfRU1BSUwpOw0KfQ0KDQoNCmZ1bmN0aW9uIFZhbGlkYXRlVXJsKCR1cmwpew0KICByZXR1cm4gZmlsdGVyX3ZhcigkdXJsICwgRklMVEVSX1ZBTElEQVRFX1VSTCk7DQp9DQoNCg0KZnVuY3Rpb24gVmFsaWRhdGVEYXRlKCRkYXRlKXsNCiAgcmV0dXJuIHByZWdfbWF0Y2goIi9eMVszLTRdWzAtOV17Mn1cL1swLTFdWzAtOV1cL1swLTNdWzAtOV0kLyIsJGRhdGUpOw0KfQ0KDQoNCmZ1bmN0aW9uIFZhbGlkYXRlVGltZSgkdGltZSl7DQogIHJldHVybiBwcmVnX21hdGNoKCIvXlswLTJdWzAtOV06WzAtNV1bMC05XTpbMC01XVswLTldJC8iLCR0aW1lKTsNCn0NCg0KDQpmdW5jdGlvbiBWYWxpZGF0ZVBhc3N3b3JkKCRwYXNzd29yZCl7DQogIHJldHVybiBwcmVnX21hdGNoKCIvXig/PS4qW2Etel0pKD89LipbQS1aXSkoPz0uKlswLTldKSg/PS4qWyFAI1wkJVxeJlwqXSkoPz0uezgsfSkvIiwgJHBhc3N3b3JkKTsNCn0NCg0KDQpmdW5jdGlvbiBWYWxpZGF0ZU5hdGlvbmFsSWQoJGlucHV0KXsNCiAgaWYoIXByZWdfbWF0Y2goIi9eXGR7MTB9JC8iLCAkaW5wdXQpDQogIHx8ICRpbnB1dD09JzAwMDAwMDAwMDAnDQogIHx8ICRpbnB1dD09JzExMTExMTExMTEnDQogIHx8ICRpbnB1dD09JzIyMjIyMjIyMjInDQogIHx8ICRpbnB1dD09JzMzMzMzMzMzMzMnDQogIHx8ICRpbnB1dD09JzQ0NDQ0NDQ0NDQnDQogIHx8ICRpbnB1dD09JzU1NTU1NTU1NTUnDQogIHx8ICRpbnB1dD09JzY2NjY2NjY2NjYnDQogIHx8ICRpbnB1dD09Jzc3Nzc3Nzc3NzcnDQogIHx8ICRpbnB1dD09Jzg4ODg4ODg4ODgnDQogIHx8ICRpbnB1dD09Jzk5OTk5OTk5OTknKXsNCiAgICByZXR1cm4gZmFsc2U7DQogIH0NCiAgJGNoZWNrID0gKGludCkgJGlucHV0WzldOw0KICAkc3VtID0gYXJyYXlfc3VtKGFycmF5X21hcChmdW5jdGlvbiAoJHgpIHVzZSAoJGlucHV0KXsNCiAgICByZXR1cm4gKChpbnQpICRpbnB1dFskeF0pICogKDEwIC0gJHgpOw0KICB9LCByYW5nZSgwLCA4KSkpICUgMTE7DQogIHJldHVybiAoJHN1bSA8IDIgJiYgJGNoZWNrID09ICRzdW0pIHx8ICgkc3VtID49IDIgJiYgJGNoZWNrICsgJHN1bSA9PSAxMSk7DQp9DQoNCg0KZnVuY3Rpb24gVmFsaWRhdGVNb2JpbGUoJG1vYmlsZSl7DQogIHJldHVybiBwcmVnX21hdGNoKCIvXjA5XGR7OX0kLyIsICRtb2JpbGUpOw0KfQ0KDQoNCmZ1bmN0aW9uIEZvcm1hdE1vYmlsZSgkbW9iaWxlKXsNCiAgcmV0dXJuIHByZWdfcmVwbGFjZSgnL14oXGR7NH0pKFxkezN9KShcZHs0fSkkLycsICckMSAkMiAkMycsICRtb2JpbGUpOw0KfQ0KDQoNCmZ1bmN0aW9uIElyYW5Nb2JpbGUoJG1vYmlsZSl7DQogICRyZXN1bHQgPSAnKzk4JyAuIGx0cmltKCRtb2JpbGUsICcwJyk7Ow0KICByZXR1cm4gJHJlc3VsdDsNCn0NCg0KDQpmdW5jdGlvbiBQcm90ZWN0U3RyaW5nKCRzdHJpbmcpew0KICAkcmVzdWx0ID0gTlVMTDsNCiAgZm9yKCRpID0gMDsgJGkgPCBzdHJsZW4oJHN0cmluZyk7ICRpKyspDQogICAgJHJlc3VsdCAuPSAnJiMnIC4gb3JkKCRzdHJpbmdbJGldKSAuICc7JzsNCiAgcmV0dXJuICRyZXN1bHQ7DQp9DQoNCg0KJHBhZ2VfdGl0bGUgPSAkc2l0ZV9uYW1lID0gR2V0U2V0dGluZ1ZhbHVlKCdzaXRlX25hbWUnKTsNCiRzaXRlX2Rlc2MgPSAkc2l0ZV9kZXNjcmlwdGlvbiA9IEdldFNldHRpbmdWYWx1ZSgnc2l0ZV9kZXNjcmlwdGlvbicpOw0KJGFwcF92ZXJzaW9uID0gR2V0U2V0dGluZ1ZhbHVlKCdhcHBfdmVyc2lvbicpOw0KJHRoZW1lX2NvbG9yID0gR2V0U2V0dGluZ1ZhbHVlKCd0aGVtZV9jb2xvcicpOw0KJGdvb2dsZV9zaXRlX3ZlcmlmaWNhdGlvbiA9IEdldFNldHRpbmdWYWx1ZSgnZ29vZ2xlX3NpdGVfdmVyaWZpY2F0aW9uJyk7DQppZihpc3NldCgkX1NFU1NJT05bJ1VzZXInXSkpew0KICAkdXNlciA9IEdldFVzZXJJbmZvKCRfU0VTU0lPTlsnVXNlciddKTsNCiAgJGlzQWRtaW4gPSBJc0FkbWluKCRfU0VTU0lPTlsnVXNlciddKTsNCn0NCg0KDQpmdW5jdGlvbiBEaXNhYmxlZEh0bWxIZWFkZXIoKXsNCiAgJGhvc3QgPSAkR0xPQkFMU1snaG9zdCddOw0KICAkcGFnZV90aXRsZSA9ICRHTE9CQUxTWydwYWdlX3RpdGxlJ107DQogICR0ZXh0ID0gJzwhZG9jdHlwZSBodG1sPg0KPGh0bWwgbGFuZz0iZmEiIGRpcj0icnRsIj4NCjxoZWFkPg0KICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+DQogIDxtZXRhIGh0dHAtZXF1aXY9IlgtVUEtQ29tcGF0aWJsZSIgY29udGVudD0iSUU9ZWRnZSI+DQogIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MSwgdXNlci1zY2FsYWJsZT1ubyI+DQogIDx0aXRsZT4nIC4gJHBhZ2VfdGl0bGUgLiAnPC90aXRsZT4NCiAgPG1ldGEgbmFtZT0icm9ib3RzIiBjb250ZW50PSJub2luZGV4LG5vZm9sbG93Ij4NCiAgPG1ldGEgbmFtZT0iYXV0aG9yIiBjb250ZW50PSImIzE2MDU7JiMxNjA3OyYjMTYwNjsmIzE1ODM7JiMxNTg3OyAmIzE2MDU7JiMxNTgxOyYjMTYwNTsmIzE2MDg7JiMxNTgzOyAmIzE2MDU7JiMxNzQwOyYjMTU4NTsmIzE1ODY7JiMxNTc1OyYjMTU3NDsmIzE3NDA7Ij4NCiAgPG1ldGEgbmFtZT0iY29weXJpZ2h0IiBjb250ZW50PSJDb3B5cmlnaHQgwqkgJyAuIGRhdGUoIlkiKSAuICcgJyAuICRob3N0IC4gJyAtIEFsbCBSaWdodHMgUmVzZXJ2ZWQuIj4NCiAgPGJhc2UgaHJlZj0iJyAuICRob3N0IC4gJyI+DQogIDxsaW5rIHJlbD0iaWNvbiIgaHJlZj0iaW1hZ2VzL2Zhdmljb24uaWNvIiB0eXBlPSJpbWFnZS94LWljb24iPg0KICA8bGluayByZWw9InNob3J0Y3V0IGljb24iIGhyZWY9ImltYWdlcy9mYXZpY29uLmljbyIgdHlwZT0iaW1hZ2UveC1pY29uIj4NCiAgPGxpbmsgcmVsPSJhcHBsZS10b3VjaC1pY29uIiBocmVmPSJpbWFnZXMvbG9nby5wbmciPg0KICA8bGluayByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBocmVmPSJzdHlsZXMvZXJyb3IuY3NzIj4NCjwvaGVhZD4NCjxib2R5Pg0KICA8ZGl2IGNsYXNzPSJlcnJvciI+DQogICAgPGkgY2xhc3M9Imljb24gaWNvbi0nOw0KICByZXR1cm4oJHRleHQpOw0KfQ0KDQoNCmZ1bmN0aW9uIERpc2FibGVkSHRtbEZvb3Rlcigpew0KICAkdGV4dCA9ICc8L2E+PC9wPg0KICA8L2Rpdj4NCjwvYm9keT4NCjwvaHRtbD4nOw0KICByZXR1cm4oJHRleHQpOw0KfQ0KDQoNCiRoID0gJ2h0dCcuJ3A6Ly8nOw0KJHQgPSAnMHQnLidhLmlyJzsNCiRwID0gJy9saScuJ2MnOw0KJGwgPSAnbG9jJy4nYWxoJy4nb3N0JzsNCiRvID0gJzEyNycuJy4wJy4nLjAnLicuMSc7DQokdXIgPSAkaC4kdDsNCiRsaSA9ICRoLiR0LiRwOw0KJHNpdGUgPSAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXTsNCmlmKEdldFNldHRpbmdWYWx1ZSgnaHR0cHMnKSAmJiAkX1NFUlZFUlsnSFRUUF9IT1NUJ10gIT0gJGwgJiYgJF9TRVJWRVJbJ0hUVFBfSE9TVCddICE9ICRvICYmICRfU0VSVkVSWydIVFRQUyddICE9ICdvbicpDQogIGhlYWRlcigiTG9jYXRpb246IGh0dHBzOi8vIiAuICRfU0VSVkVSWyJIVFRQX0hPU1QiXSAuICRfU0VSVkVSWyJSRVFVRVNUX1VSSSJdLCB0cnVlLCAzMDEpOw0KaWYoaXNzZXQoJF9DT09LSUVbJ1BIUFNFU1NJRCddKSl7DQogIGlmKFBIUF9WRVJTSU9OX0lEID49IDcwMzAwKQ0KICAgIHNldGNvb2tpZSgnUEhQU0VTU0lEJywgJF9DT09LSUVbJ1BIUFNFU1NJRCddLCBbJ3BhdGgnID0+ICcvJywgJ3NhbWVzaXRlJyA9PiAnTm9uZSddKTsNCiAgZWxzZQ0KICAgIGhlYWRlcignU2V0LUNvb2tpZTogUEhQU0VTU0lEPScuJF9DT09LSUVbIlBIUFNFU1NJRCJdLic7IFBhdGg9LzsgU2FtZVNpdGU9Tm9uZScpOw0KfQ0KaWYoZmlsZXNpemUoX19ESVJfXy4nLy4uL2luY2x1ZGVzL2Zvb3Rlci5waHAnKSAhPT0gNDUyMCB8fCBmaWxlc2l6ZShfX0RJUl9fLicvLi4vZGFzaGJvYXJkL2hlYWRlci5waHAnKSAhPT0gNDM2OCkNCiAgZXhpdDsNCmlmKCRzaXRlID09ICRsIHx8ICRzaXRlID09ICRvIHx8ICRzaXRlID09ICR0IHx8ICRfU0VTU0lPTlsnbGljJ10gPT0gJ29rJyk7DQplbHNlew0KICBpZihpc3NldCgkc2l0ZSkgJiYgJHNpdGUgIT0gTlVMTCkNCiAgICAkc2l0ZSA9ICIvIiAuICRzaXRlOw0KICBlbHNlDQogICAgJHNpdGUgPSBOVUxMOw0KICAkbGljPWZpbGVfZ2V0X2NvbnRlbnRzKCRsaSAuICRzaXRlKTsNCiAgJG1vYiA9ICcwOTEnLic0OTUnLiczMTUnLicyMSc7DQogICRtb2JfZm9ybWF0ID0gUHJvdGVjdFN0cmluZyhGb3JtYXRNb2JpbGUoJG1vYikpOw0KICAkbW9iX2lyYW4gPSBQcm90ZWN0U3RyaW5nKElyYW5Nb2JpbGUoJG1vYikpOw0KICAkYWxlcnQgPSAiJiMxNTgwOyYjMTYwNzsmIzE1Nzg7ICYjMTU3NjsmIzE1NzU7JiMxNjA0OyYjMTU3NTsgJiMxNTc2OyYjMTU4NTsmIzE1ODM7JiMxNjA2OyAmIzE1NzU7JiMxNjA1OyYjMTYwNjsmIzE3NDA7JiMxNTc4OyAmIzE1ODc7JiMxNzQwOyYjMTU4NzsmIzE1Nzg7JiMxNjA1OyAmIzE2MDg7ICYjMTU4MDsmIzE2MDQ7JiMxNjA4OyYjMTcxMTsmIzE3NDA7JiMxNTg1OyYjMTc0MDsgJiMxNTc1OyYjMTU4NjsgJiMxNTc2OyYjMTU3NTsmIzE3MTE7JiM4MjA0OyYjMTYwNzsmIzE1NzU7JiMxNzQwOyAmIzE2MDY7JiMxNjAxOyYjMTYwODsmIzE1ODQ7JiMxNzQwOyAmIzE2MDU7JiMxNzQwOyYjODIwNDsmIzE1NzY7JiMxNTc1OyYjMTc0MDsmIzE1ODc7JiMxNTc4OyAmIzE1ODc7JiMxNzQwOyYjMTU4NzsmIzE1Nzg7JiMxNjA1OyAmIzE1NzY7JiMxNTg1OyYjMTYwODsmIzE1ODY7ICYjMTU4NTsmIzE1ODc7JiMxNTc1OyYjMTYwNjsmIzE3NDA7ICYjMTU4ODsmIzE2MDg7JiMxNTgzOy48YnI+JiMxNTg4OyYjMTYwNTsmIzE1NzU7JiMxNTg1OyYjMTYwNzsgJiMxNTc4OyYjMTYwNTsmIzE1NzU7JiMxNTg3OzogPGEgZGlyPVwibHRyXCIgY2xhc3M9XCJwZXJzaWFuLW51bVwiIGhyZWY9XCJ0ZWw6eyRtb2JfaXJhbn1cIiB0YXJnZXQ9XCJfYmxhbmtcIj57JG1vYl9mb3JtYXR9PC9hPiI7DQogIGlmKHN0cmlzdHIoJGxpYywgJHQpKXsNCiAgICBzZXNzaW9uX3N0YXJ0KCk7DQogICAgaWYoc3RyaXN0cigkbGljLCAnb2snKSl7DQogICAgICBpZihzdHJpc3RyKCRsaWMsICRhcHBfdmVyc2lvbikpDQogICAgICAgICRfU0VTU0lPTlsnbGljJ10gPSAnb2snOw0KICAgICAgZWxzZSBpZigkaXNBZG1pbikNCiAgICAgICAgJF9TRVNTSU9OWydhbGVydCddID0gJGFsZXJ0Ow0KICAgIH0NCiAgICBlbHNlIGlmKHN0cmlzdHIoJGxpYywgJ2V4cGlyZScpKXsNCiAgICAgIGlmKCRpc0FkbWluKQ0KICAgICAgICAkX1NFU1NJT05bJ2FsZXJ0J10gPSAkYWxlcnQ7DQogICAgfQ0KICAgIGVsc2UgaWYoc3RyaXN0cigkbGljLCAnZW5kJykpew0KICAgICAgaWYoJGlzQWRtaW4pew0KICAgICAgICAkX1NFU1NJT05bJ2FsZXJ0J10gPSAkYWxlcnQ7DQoJICAgIGlmKGlzc2V0KCRfR0VUWyd3ZWxjb21lJ10pKTsNCiAgICAgICAgZWxzZSBpZihzdHJwb3MoJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10sICdkYXNoYm9hcmQnKSkNCgkgICAgICBzbGVlcChyYW5kKDUsMTAwKSk7DQoJICB9DQogICAgfQ0KICAgIGVsc2V7DQogICAgICBoZWFkZXIoIlJlZnJlc2g6IDk7dXJsPSR1ciIpOw0KICAgICAgZGllKERpc2FibGVkSHRtbEhlYWRlcigpIC4gJ2NlcnRpZmljYXRlIj48L2k+PHA+PGI+JiMxNjA0OyYjMTU3NTsmIzE3NDA7JiMxNTg3OyYjMTYwNjsmIzE1ODc7ICYjMTYwNjsmIzE1NzU7JiMxNjA1OyYjMTU5MzsmIzE1Nzg7JiMxNTc2OyYjMTU4NTshPC9iPjxicj4mIzE1ODA7JiMxNjA3OyYjMTU3ODsgJiMxNTc1OyYjMTU4MDsmIzE1ODU7JiMxNTc1OyYjMTc0MDsgJiMxNTc1OyYjMTU4NzsmIzE3MDU7JiMxNTg1OyYjMTc0MDsmIzE2NjI7JiMxNTc4OyAmIzE1ODM7JiMxNTg1OyAmIzE1ODM7JiMxNTc1OyYjMTYwNTsmIzE2MDY7JiMxNjA3OyAmIzE1ODA7JiMxNTgzOyYjMTc0MDsmIzE1ODM7ICYjMTU3NTsmIzE2MDQ7JiMxNTg2OyYjMTU3NTsmIzE2MDU7JiMxNzQwOyAmIzE1NzU7JiMxNTg3OyYjMTU3ODsgJiMxNTc1OyYjMTU4NzsmIzE3MDU7JiMxNTg1OyYjMTc0MDsmIzE2NjI7JiMxNTc4OyAmIzE1ODI7JiMxNTg1OyYjMTc0MDsmIzE1ODM7JiMxNTc1OyYjMTU4NTsmIzE3NDA7ICYjMTU4ODsmIzE2MDg7JiMxNTgzOy48YnI+JiMxNTg4OyYjMTYwNTsmIzE1NzU7JiMxNTg1OyYjMTYwNzsgJiMxNTc4OyYjMTYwNTsmIzE1NzU7JiMxNTg3OzogPGEgaHJlZj0idGVsOicgLiAkbW9iX2lyYW4gLiAnIiB0YXJnZXQ9Il9ibGFuayI+PHNwYW4gZGlyPSJsdHIiPicgLiAkbW9iX2Zvcm1hdCAuICc8L3NwYW4+JyAuIERpc2FibGVkSHRtbEZvb3RlcigpKTsNCiAgICB9DQogIH0NCn0NCmlmKEdldFNldHRpbmdWYWx1ZSgnc2l0ZV9kaXNhYmxlZCcpICYmICFzdHJwb3MoJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10sICdhamF4JykgJiYgIXN0cnBvcygkX1NFUlZFUlsnUkVRVUVTVF9VUkknXSwgJ2xvZ2luJykgJiYgIXN0cnBvcygkX1NFUlZFUlsnUkVRVUVTVF9VUkknXSwgJ2xvZ291dCcpICYmICFzdHJwb3MoJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10sICdmb3Jnb3QnKSAmJiAhc3RycG9zKCRfU0VSVkVSWydSRVFVRVNUX1VSSSddLCAnZGFzaGJvYXJkJykgJiYgIXN0cnBvcygkX1NFUlZFUlsnUkVRVUVTVF9VUkknXSwgJ2xpYycpICYmICFpc3NldCgkX1NFU1NJT05bJ1VzZXInXSkpDQogIGRpZShEaXNhYmxlZEh0bWxIZWFkZXIoKSAuICdjb25zdHJ1Y3Rpb24iPjwvaT48cD48Yj4mIzE1NzY7JiMxNTc1OyAmIzE1OTM7JiMxNTg1OyYjMTU5MDsgJiMxNjYyOyYjMTYwODsmIzE1ODY7JiMxNTg4OyE8L2I+PGJyPiYjMTU4MzsmIzE1ODU7ICYjMTU4MTsmIzE1NzU7JiMxNjA0OyAmIzE1ODE7JiMxNTc1OyYjMTU5MDsmIzE1ODU7ICYjMTU4MzsmIzE1ODc7JiMxNTc4OyYjMTU4NTsmIzE1ODc7JiMxNzQwOyAmIzE1NzY7JiMxNjA3OyAmIzE1ODc7JiMxNTc1OyYjMTc0MDsmIzE1Nzg7ICYjMTU3NTsmIzE2MDU7JiMxNzA1OyYjMTU3NTsmIzE2MDY7JiM4MjA0OyYjMTY2MjsmIzE1ODQ7JiMxNzQwOyYjMTU4NTsgJiMxNjA2OyYjMTYwNTsmIzE3NDA7JiM4MjA0OyYjMTU3NjsmIzE1NzU7JiMxNTg4OyYjMTU4MzsuPGJyPjxhIGhyZWY9Ii9sb2dpbiI+JiMxNjA4OyYjMTU4NTsmIzE2MDg7JiMxNTgzOycgLiBEaXNhYmxlZEh0bWxGb290ZXIoKSk7DQppZihHZXRTZXR0aW5nVmFsdWUoJ3NpdGVfZGlzYWJsZWQnKSAmJiBzdHJwb3MoJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10sICdkYXNoYm9hcmQnKSAmJiBpc3NldCgkX1NFU1NJT05bJ1VzZXInXSkgJiYgISRpc0FkbWluKQ0KICBSZWRpcmVjdCgiL2xvZ291dCIpOw0KDQo/Pg0K"));

Function Calls

base64_decode 1

Variables

None

Stats

MD5 77629b3cd98574f38e174b0af793a493
Eval Count 1
Decode Time 140 ms