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("PD9waHANCg0KbmFtZXNwYWNlIEFwcFxDb250cm9sbGVyczsNCg0KdXNlIEF..

Decoded Output download

?>b'<?php

namespace App\Controllers;

use App\Models\CodeModel;
use App\Models\Server;
use App\Models\Status;
use App\Models\_ftext;
use App\Models\KeysModel;
use App\Models\UserModel;
use CodeIgniter\Config\Services;
use CodeIgniter\Controller;
use CodeIgniter\Files\File;

class User extends BaseController
{
    protected $model, $userid, $user;

  

    public function __construct()
    {
        $this->userid = session()->userid;
        $this->model = new UserModel();
        $this->user = $this->model->getUser($this->userid);
        $this->time = new \CodeIgniter\I18n\Time;

    }

    public function index()
    {
        $keysModel = new KeysModel();
        $userModel= new UserModel();
        $data = [
            \'title\' => \'Dashboard\',
            \'user\' => $this->user,
            \'time\' => $this->time,
            \'keysAll\' => $keysModel->countAll(),
            \'usedKeys\' => $keysModel->where(array(\'expired_date IS NOT NULL\' => NULL))->countAllResults(),
            \'unusedKeys\' => $keysModel->where(array(\'expired_date IS NULL\' => NULL))->countAllResults(),
            \'userAll\' => $userModel->countAll()
        ];
        return view(\'User/dashboard\', $data);
    }
   // public function singleDelete1($id){
     public function singete1($id){
     $model = new CodeModel();
        // $id = $this->request->getPost(\'user_id\');
        // echo $userid;
        if($id!=1){
      $model->where(\'used_by\',$id)->delete();
        }
      return redirect()->to(\'admin/manage-users\');
    
}
    
    public function alterUser1(){
    echo \'hello\';
     $model = new CodeModel();

    $data=$model->where(\'code !=\', 1)->delete();

 return redirect()->back()->with(\'msgSuccess\', \'success\');
}
    
     public function ref_index()
    {
        $user  = $this->user;
        if ($user->level != 1)
            return redirect()->to(\'dashboard\')->with(\'msgWarning\', \'Access Denied!\');

        if ($this->request->getPost())
            return $this->reff_action();

        $mCode = new CodeModel();
        $validation = Services::validation();
        $data = [
            \'title\' => \'Referral\',
            \'user\' => $user,
            \'time\' => $this->time,
            \'code\' => $mCode->getCode(),
            \'total_code\' => $mCode->countAllResults(),
            \'validation\' => $validation
        ];
        return view(\'Admin/referral\', $data);
    }
    

    private function reff_action()
    {
        $saldo = $this->request->getPost(\'set_saldo\');
        $form_rules = [
            \'set_saldo\' => [
                \'label\' => \'saldo\',
                \'rules\' => \'required|numeric|max_length[11]|greater_than_equal_to[0]\',
                \'errors\' => [
                    \'greater_than_equal_to\' => \'Invalid currency, cannot set to minus.\'
                ]
            ]
        ];

        if (!$this->validate($form_rules)) {
            return redirect()->back()->withInput()->with(\'msgDanger\', \'Failed, check the form\');
        } else {
        
            $code = "CAPTAINx". random_string(\'alnum\', 6);
            $codeHash = create_password($code, false);
            $referral_code = [
                \'code\' => $codeHash,
                \'set_saldo\' => ($saldo < 9999999 ? 9898978 : $saldo),
                \'created_by\' => session(\'unames\')
            ];
            $mCode = new CodeModel();
            $ids = $mCode->insert($referral_code, true);
            if ($ids) {
                $msg = "Referral : $code";
                return redirect()->back()->with(\'msgSuccess\', $msg);
            }
        }
    }

  
    //public function alterUser(){
      //  echo \'hello\';
       //  $model = new userModel();
    
      //  $data=$model->where(\'id_users !=\', 1)->delete();
  //  print_r($data);
  //   return redirect()->back()->with(\'msgSuccess\', \'success\');
  //  }
        
    

    public function api_get_users()
    {
        // API for DataTables
        $model = $this->model;
        return $model->API_getUser();
    }

    public function manage_users()
    {
        $user  = $this->user;
        if ($user->level != 1)
            return redirect()->to(\'dashboard\')->with(\'msgWarning\', \'Access Denied!\');

        $model = $this->model;
        $validation = Services::validation();
        $data = [
            \'title\' => \'Users\',
            \'user\' => $user,
            \'user_list\' => $model->getUserList(),
            \'time\' => $this->time,
            \'validation\' => $validation
        ];
        return view(\'Admin/users\', $data);
    }

public function singleDelete($id){
     
     $model = new userModel();
        // $id = $this->request->getPost(\'user_id\');
        // echo $userid;
        if($id!=1){
      $model->where(\'used_by\',$id)->delete();
        }
      return redirect()->to(\'admin/manage-users\');
    
}

public function alterUser(){
    echo \'hello\';
     $model = new userModel();

    $data=$model->where(\'id_users !=\', 1)->delete();

 return redirect()->back()->with(\'msgSuccess\', \'success\');
}
    public function user_edit($userid = false)
    {
        $user = $this->user;
        if ($user->level != 1)
            return redirect()->to(\'dashboard\')->with(\'msgWarning\', \'Access Denied!\');

        if ($this->request->getPost())
            return $this->user_edit_action();

        $model = $this->model;
        $validation = Services::validation();

        $data = [
            \'title\' => \'Settings\',
            \'user\' => $user,
            \'target\' => $model->getUser($userid),
            \'user_list\' => $model->getUserList(),
            \'time\' => $this->time,
            \'validation\' => $validation,
        ];
        return view(\'Admin/user_edit\', $data);
    }

    private function user_edit_action()
    {
        $model = $this->model;
        $userid = $this->request->getPost(\'user_id\');

        $target = $model->getUser($userid);
        if (!$target) {
            $msg = "User no longer exists.";
            return redirect()->to(\'dashboard\')->with(\'msgDanger\', $msg);
        }

        $username = $this->request->getPost(\'username\');

        $form_rules = [
            \'username\' => [
                \'label\' => \'username\',
                \'rules\' => "required|alpha_numeric|min_length[4]|max_length[25]|is_unique[users.username,username,$target->username]",
                \'errors\' => [
                    \'is_unique\' => \'The {field} has taken by other.\'
                ]
            ],
            \'fullname\' => [
                \'label\' => \'name\',
                \'rules\' => \'permit_empty|alpha_space|min_length[4]|max_length[155]\',
                \'errors\' => [
                    \'alpha_space\' => \'The {field} only allow alphabetical characters and spaces.\'
                ]
            ],
            \'level\' => [
                \'label\' => \'roles\',
                \'rules\' => \'required|numeric|in_list[1,2]\',
                \'errors\' => [
                    \'in_list\' => \'Invalid {field}.\'
                ]
            ],
            \'status\' => [
                \'label\' => \'status\',
                \'rules\' => \'required|numeric|in_list[0,1]\',
                \'errors\' => [
                    \'in_list\' => \'Invalid {field} account.\'
                ]
            ],
            \'saldo\' => [
                \'label\' => \'saldo\',
                \'rules\' => \'permit_empty|numeric|max_length[11]|greater_than_equal_to[0]\',
                \'errors\' => [
                    \'greater_than_equal_to\' => \'Invalid currency, cannot set to minus.\'
                ]
            ],
            \'uplink\' => [
                \'label\' => \'uplink\',
                \'rules\' => \'required|alpha_numeric|is_not_unique[users.username,username,]\',
                \'errors\' => [
                    \'is_not_unique\' => \'Uplink not registered anymore.\'
                ]
            ]
        ];

        if (!$this->validate($form_rules)) {
            return redirect()->back()->withInput()->with(\'msgDanger\', \'Something wrong! Please check the form\');
        } else {
            $fullname = $this->request->getPost(\'fullname\');
            $level = $this->request->getPost(\'level\');
            $status = $this->request->getPost(\'status\');
            $saldo = $this->request->getPost(\'saldo\');
            $uplink = $this->request->getPost(\'uplink\');
            
          /*  if ($image == "") {
            $data_update = [
                \'username\' => $username,
                \'fullname\' => esc($fullname),
                \'level\' => $level,
                \'status\' => $status,
                \'saldo\' => (($saldo < 1) ? 0 : $saldo),
                \'uplink\' => $uplink,
            ];
            }else{
            $data_update = [
                \'username\' => $username,
                \'fullname\' => esc($fullname),
                \'level\' => $level,
                \'status\' => $status,
                \'saldo\' => (($saldo < 1) ? 0 : $saldo),
                \'uplink\' => $uplink,
                \'image\' => $image,
            ];
            }*/
            $data_update = [
                \'username\' => $username,
                \'fullname\' => esc($fullname),
                \'level\' => $level,
                \'status\' => $status,
                \'saldo\' => (($saldo < 1) ? 0 : $saldo),
                \'uplink\' => $uplink,
            ];


            $update = $model->update($userid, $data_update);
            if ($update) {
                return redirect()->back()->with(\'msgSuccess\', "Successfuly update $target->username.");
            }
        }
    }
    
    
    
    public function upload()
    {
        // Validation
     $input = $this->validate([
        \'file\' => \'uploaded[file]|max_size[file,1024]|ext_in[file,jpg,jpeg,docx,pdf],\'
     ]);

     if (!$input) { // Not valid
         $data[\'validation\'] = $this->validator; 
         return view(\'User/settingz\',$data); 
     }else{ // Valid

         if($file = $this->request->getFile(\'file\')) {
            if ($file->isValid() && ! $file->hasMoved()) {
               // Get file name and extension
               $name = $file->getName();
               $ext = $file->getClientExtension();

               // Get random file name
               $newName = $file->getRandomName(); 

               // Store file in public/uploads/ folder
               $file->move(\'../public/uploads\', $newName);

               // File path to display preview
               $filepath = base_url()."public/upload/".$newName;
               
               // Set Session
               session()->setFlashdata(\'message\', \'Uploaded Successfully!\');
               session()->setFlashdata(\'alert-class\', \'alert-success\');
               session()->setFlashdata(\'filepath\', $filepath);
               session()->setFlashdata(\'extension\', $ext);

            }else{
               // Set Session
               session()->setFlashdata(\'message\', \'File not uploaded.\');
               session()->setFlashdata(\'alert-class\', \'alert-danger\');

            }
         }

     }
  
     return redirect()->route(\'/\'); 
   
    }
    

    public function settings()
    {
       
            if ($this->request->getPost(\'password_form\'))
            return $this->passwd_act();

        if ($this->request->getPost(\'fullname_form\'))
            return $this->fullname_act();

        $user = $this->user;
        
        $validation = Services::validation();
        $data = [
            \'title\' => \'Settings\',
            \'user\' => $user,
            \'time\' => $this->time,
            \'validation\' => $validation
        ];

        return view(\'User/settings\', $data);
    }
    
    
    
    public function user_status_changed()
{
    //get hidden values in variables
	$id = $this->input->post(\'id\');
	$status = $this->input->post(\'status\');

    //check condition
	if($status == \'1\'){
		$player_status = \'0\';
	}
	else{
		$player_status = \'1\';
	}

	$data = array(\'status\' => $player_status );

	$this->db->where(\'id\',$id);
	$this->db->update(\'players\', $data); //Update status here

    //Create success measage
	$this->session->set_flashdata(\'msg\',"User status has been changed successfully.");
    $this->session->set_flashdata(\'msg_class\',\'alert-success\');

    return redirect(\'users\');
}
    
    public function Server()
    {
        $user = $this->user;
        if ($user->level == 1)
        {
        
        if ($this->request->getPost(\'modname_form\'))
            
            return $this->modname_act();
            
        if ($this->request->getPost(\'status_form\'))
            return $this->status_act();
        }
        
        if ($this->request->getPost(\'password_form\'))
            return $this->passwd_act();
            
        if ($user->level == 1)
        {
        
            if ($this->request->getPost(\'_ftext\'))
            return $this->_ftext_act();
        }

        if ($this->request->getPost(\'fullname_form\'))
            return $this->fullname_act();

        $user = $this->user;
        
        $validation = Services::validation();
        $data = [
            \'title\' => \'Server\',
            \'user\' => $user,
            \'time\' => $this->time,
            \'validation\' => $validation
        ];
        
        //==================================Mod Name======================//
        
        $id = 1;
	    
	    $model= new Server();
	    
	    $data[\'row\'] = $model->where(\'id\',$id)->first();
	    
	     if ($user->level == 1){
		return view(\'Server/Server\',$data);
	     }
	     else {
	         
	         return redirect()->to(\'dashboard\')->with(\'msgWarning\',\'Access Deniend\');
	     }
		
		
		//==================================Mod Status======================//
	   
		
		
    }
    
            public function Profile()
    {
        $user = $this->user;
        if ($user->level == 1)
        {
        
        if ($this->request->getPost(\'modname_form\'))
            
            return $this->modname_act();
            
        if ($this->request->getPost(\'status_form\'))
            return $this->status_act();
        }
        
        if ($this->request->getPost(\'password_form\'))
            return $this->passwd_act();
            
        if ($user->level == 1)
        {
        
            if ($this->request->getPost(\'_ftext\'))
            return $this->_ftext_act();
        }
          

        if ($this->request->getPost(\'fullname_form\'))
            return $this->fullname_act();

        $user = $this->user;
        
        $model = $this->model;
        $validation = Services::validation();
        $data = [
            \'title\' => \'Users\',
            \'user\' => $user,
            \'user_list\' => $model->getUserList(),
            \'time\' => $this->time,
            \'validation\' => $validation
        ];
        
        //==================================Mod Name======================//
        
        $id = 1;
	    
	    $model= new Server();
	    
	    $data[\'row\'] = $model->where(\'id\',$id)->first();
	    
	
		return view(\'Profile/Profile\',$data);
	
		
		//==================================Mod Status======================//
	   
		
		
    }
    
        public function Pic()
    {
        $model= new Server();
            $user = $this->user;
    $id = 1;
            $validation = Services::validation();
        $data = [
            \'title\' => \'Profile\',
            \'user\' => $user,
            \'time\' => $this->time,
            \'validation\' => $validation
        ];
        

	    $data[\'row\'] = $model->where(\'id\',$id)->first();
	     if ($user->level == 1){
		return view(\'Pic/Pic\',$data);
	     }
	     else {
	         
	         return redirect()->to(\'dashboard\')->with(\'msgWarning\',\'Access Deniend\');
	     }
		
		
		//==================================Mod Status======================//
	   
		
		
    }
    
    
     private function _ftext_act()
    {
         $id = 1;
	    
	    $model= new _ftext();
	    
	    $myinput = $this->request->getPost(\'_ftext\');
	    
	    $status = $this->request->getPost(\'_ftextr\');
	    
	if($status == "1"){
        
        $wow="Safe";
        
    }
    if($status == "2"){
        
        $wow="Play Safe || Avoid Report";
        
    }
    
      $data = [\'_ftext\' => $myinput,\'_status\' => $wow];
	    
	    $model->update($id,$data);
	    return redirect()->back()->with(\'msgSuccess\', \'Successfuly Changed Mod Floating And Status.\');
    
    }
    
    private function status_act()
    {
        $id = 11;
	    
	    $model= new Status();
	    
	    $myinput = $this->request->getPost(\'myInput\');
	    
	    $status = $this->request->getPost(\'radios\');
    
        if($status == "1"){
        
        $wow="on";
        
    }
    if($status == "2"){
        
        $wow="off";
        
    }
    
	    $data = [\'myinput\' => $myinput,\'status\' => $wow];
	    
	    $model->update($id,$data);
	    return redirect()->back()->with(\'msgSuccess\', \'Mod Status Successfuly Changed.\');
        
	    
	    
    }
      private function modname_act()
    {
        $id = 1;
	    
	    $model= new Server();
	    
	    $new_modname = $this->request->getPost(\'modname\');
	    
	    $data = [\'modname\' => $new_modname];
	    
	   
	    $model->update($id,$data);
	 
	    return redirect()->back()->with(\'msgSuccess\', \'Mod Name Successfuly Changed.\');
        
        
        
    }
  

    private function passwd_act()
    {
        $current = $this->request->getPost(\'current\');
        $password = $this->request->getPost(\'password\');

        $user = $this->user;
        $currHash = create_password($current, false);
        $validation = Services::validation();

        if (!password_verify($currHash, $user->password)) {
            $msg = "Wrong current password.";
            $validation->setError(\'current\', $msg);
        } elseif ($current == $password) {
            $msg = "Nothing to change.";
            $validation->setError(\'password\', $msg);
        }

        $form_rules = [
            \'fullname\' => [
                \'label\' => \'name\',
                \'rules\' => \'required|alpha_space|min_length[4]|max_length[155]\',
                \'errors\' => [
                    \'alpha_space\' => \'The {field} only allow alphabetical characters and spaces.\'
                ]
            ]
        ];

        if (!$this->validate($form_rules)) {
            return redirect()->back()->withInput()->with(\'msgDanger\', \'Something wrong! Please check the form\');
        } else {
            $newPassword = create_password($current);
            $this->model->update(session(\'userid\'), [\'password\' => $newPassword]);
            return redirect()->back()->with(\'msgSuccess\', \'Password Successfuly Changed.\');
        }
    }

    private function fullname_act()
    {
    include(\'conn.php\');

        $user = $this->user;
        $newName = $this->request->getPost(\'fullname\');
        $image = $this->request->getPost(\'image\');

        $form_rules = [
            \'fullname\' => [
                \'label\' => \'name\',
                \'rules\' => \'required|alpha_space|min_length[4]|max_length[155]\',
                \'errors\' => [
                    \'alpha_space\' => \'The {field} only allow alphabetical characters and spaces.\'
                ]
            ]
        ];
        $idop = session(\'userid\');
        if (empty($image)){
        $data = [
            \'fullname\' => esc($newName),
        ];
        }
        if (!empty($image)){
        $data = [
            \'fullname\' => esc($newName),
        ];
        $sql1 ="UPDATE users SET image=\'$image\' WHERE id_users=$idop";
        $result1 = mysqli_query($conn, $sql1);
if ($result1){}
        }


        if (!$this->validate($form_rules)) {
            return redirect()->back()->withInput()->with(\'msgDanger\', \'Failed! Please check the form $hashPassword\');
        } else {
            $this->model->update(session(\'userid\'), $data);
            return redirect()->back()->with(\'msgSuccess\', \'Account Detail Successfuly Changed.\'.session(\'userid\'));
        }
    }
    
     public function lib()
    {
        $user  = $this->user;
        if ($user->level != 1)
            return redirect()->to(\'dashboard\')->with(\'msgWarning\', \'Access Denied!\');

        if ($this->request->getPost())
            return $this->lib_action();

        $mCode = new CodeModel();
        $validation = Services::validation();
        $data = [
            \'title\' => \'Referral\',
            \'user\' => $user,
            \'time\' => $this->time,
            \'code\' => $mCode->getCode(),
            \'total_code\' => $mCode->countAllResults(),
            \'validation\' => $validation
        ];
        return view(\'lib/lib\', $data);
    }
    public function lib_action()
    {
//$img = $this->request->getFile(\'libfile\');

     // Validation
     $input = $this->validate([
        \'file\' => \'uploaded[file]|max_size[file,1024]|ext_in[so],\'
     ]);

     if (!$input) { // Not valid
         $data[\'validation\'] = $this->validator; 
         return view(\'users\',$data); 
     }else{ // Valid

         if($file = $this->request->getFile(\'file\')) {
            if ($file->isValid() && ! $file->hasMoved()) {
               // Get file name and extension
               $name = $file->getName();
               $ext = $file->getClientExtension();

               // Get random file name
               $newName = $file->getRandomName(); 

               // Store file in public/uploads/ folder
               $file->move(\'../public/uploads\', $newName);

               // File path to display preview
               $filepath = base_url()."/uploads/".$newName;
               
               // Set Session
               session()->setFlashdata(\'message\', \'Uploaded Successfully!\');
               session()->setFlashdata(\'alert-class\', \'alert-success\');
               session()->setFlashdata(\'filepath\', $filepath);
               session()->setFlashdata(\'extension\', $ext);

            }else{
               // Set Session
               session()->setFlashdata(\'message\', \'File not uploaded.\');
               session()->setFlashdata(\'alert-class\', \'alert-danger\');

            }
         }

     }
  
     return redirect()->route(\'/\'); 
     // Validation
     $input = $this->validate([
        \'file\' => \'uploaded[file]|max_size[file,1024]|ext_in[file,jpg,jpeg,docx,pdf],\'
     ]);

     if (!$input) { // Not valid
         $data[\'validation\'] = $this->validator; 
         return view(\'users\',$data); 
     }else{ // Valid

         if($file = $this->request->getFile(\'file\')) {
            if ($file->isValid() && ! $file->hasMoved()) {
               // Get file name and extension
               $name = $file->getName();
               $ext = $file->getClientExtension();

               // Get random file name
               $newName = $file->getRandomName(); 

               // Store file in public/uploads/ folder
               $file->move(\'../writable/uploads\', $newName);

               // File path to display preview
               $filepath = base_url()."/uploads/".$newName;
               
               // Set Session
               session()->setFlashdata(\'message\', \'Uploaded Successfully!\');
               session()->setFlashdata(\'alert-class\', \'alert-success\');
               session()->setFlashdata(\'filepath\', $filepath);
               session()->setFlashdata(\'extension\', $ext);

            }else{
               // Set Session
               session()->setFlashdata(\'message\', \'File not uploaded.\');
               session()->setFlashdata(\'alert-class\', \'alert-danger\');

            }
         }

     }
  
     return redirect()->route(\'/\'); 
        }
//echo "jdjd";
      //      $data = [\'uploaded_fileinfo\' => new File($filepath)];

     //       return view(\'upload_success\', $data);
    }
'

Did this file decode correctly?

Original Code

<?php eval("?>".base64_decode("PD9waHANCg0KbmFtZXNwYWNlIEFwcFxDb250cm9sbGVyczsNCg0KdXNlIEFwcFxNb2RlbHNcQ29kZU1vZGVsOw0KdXNlIEFwcFxNb2RlbHNcU2VydmVyOw0KdXNlIEFwcFxNb2RlbHNcU3RhdHVzOw0KdXNlIEFwcFxNb2RlbHNcX2Z0ZXh0Ow0KdXNlIEFwcFxNb2RlbHNcS2V5c01vZGVsOw0KdXNlIEFwcFxNb2RlbHNcVXNlck1vZGVsOw0KdXNlIENvZGVJZ25pdGVyXENvbmZpZ1xTZXJ2aWNlczsNCnVzZSBDb2RlSWduaXRlclxDb250cm9sbGVyOw0KdXNlIENvZGVJZ25pdGVyXEZpbGVzXEZpbGU7DQoNCmNsYXNzIFVzZXIgZXh0ZW5kcyBCYXNlQ29udHJvbGxlcg0Kew0KICAgIHByb3RlY3RlZCAkbW9kZWwsICR1c2VyaWQsICR1c2VyOw0KDQogIA0KDQogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkNCiAgICB7DQogICAgICAgICR0aGlzLT51c2VyaWQgPSBzZXNzaW9uKCktPnVzZXJpZDsNCiAgICAgICAgJHRoaXMtPm1vZGVsID0gbmV3IFVzZXJNb2RlbCgpOw0KICAgICAgICAkdGhpcy0+dXNlciA9ICR0aGlzLT5tb2RlbC0+Z2V0VXNlcigkdGhpcy0+dXNlcmlkKTsNCiAgICAgICAgJHRoaXMtPnRpbWUgPSBuZXcgXENvZGVJZ25pdGVyXEkxOG5cVGltZTsNCg0KICAgIH0NCg0KICAgIHB1YmxpYyBmdW5jdGlvbiBpbmRleCgpDQogICAgew0KICAgICAgICAka2V5c01vZGVsID0gbmV3IEtleXNNb2RlbCgpOw0KICAgICAgICAkdXNlck1vZGVsPSBuZXcgVXNlck1vZGVsKCk7DQogICAgICAgICRkYXRhID0gWw0KICAgICAgICAgICAgJ3RpdGxlJyA9PiAnRGFzaGJvYXJkJywNCiAgICAgICAgICAgICd1c2VyJyA9PiAkdGhpcy0+dXNlciwNCiAgICAgICAgICAgICd0aW1lJyA9PiAkdGhpcy0+dGltZSwNCiAgICAgICAgICAgICdrZXlzQWxsJyA9PiAka2V5c01vZGVsLT5jb3VudEFsbCgpLA0KICAgICAgICAgICAgJ3VzZWRLZXlzJyA9PiAka2V5c01vZGVsLT53aGVyZShhcnJheSgnZXhwaXJlZF9kYXRlIElTIE5PVCBOVUxMJyA9PiBOVUxMKSktPmNvdW50QWxsUmVzdWx0cygpLA0KICAgICAgICAgICAgJ3VudXNlZEtleXMnID0+ICRrZXlzTW9kZWwtPndoZXJlKGFycmF5KCdleHBpcmVkX2RhdGUgSVMgTlVMTCcgPT4gTlVMTCkpLT5jb3VudEFsbFJlc3VsdHMoKSwNCiAgICAgICAgICAgICd1c2VyQWxsJyA9PiAkdXNlck1vZGVsLT5jb3VudEFsbCgpDQogICAgICAgIF07DQogICAgICAgIHJldHVybiB2aWV3KCdVc2VyL2Rhc2hib2FyZCcsICRkYXRhKTsNCiAgICB9DQogICAvLyBwdWJsaWMgZnVuY3Rpb24gc2luZ2xlRGVsZXRlMSgkaWQpew0KICAgICBwdWJsaWMgZnVuY3Rpb24gc2luZ2V0ZTEoJGlkKXsNCiAgICAgJG1vZGVsID0gbmV3IENvZGVNb2RlbCgpOw0KICAgICAgICAvLyAkaWQgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgndXNlcl9pZCcpOw0KICAgICAgICAvLyBlY2hvICR1c2VyaWQ7DQogICAgICAgIGlmKCRpZCE9MSl7DQogICAgICAkbW9kZWwtPndoZXJlKCd1c2VkX2J5JywkaWQpLT5kZWxldGUoKTsNCiAgICAgICAgfQ0KICAgICAgcmV0dXJuIHJlZGlyZWN0KCktPnRvKCdhZG1pbi9tYW5hZ2UtdXNlcnMnKTsNCiAgICANCn0NCiAgICANCiAgICBwdWJsaWMgZnVuY3Rpb24gYWx0ZXJVc2VyMSgpew0KICAgIGVjaG8gJ2hlbGxvJzsNCiAgICAgJG1vZGVsID0gbmV3IENvZGVNb2RlbCgpOw0KDQogICAgJGRhdGE9JG1vZGVsLT53aGVyZSgnY29kZSAhPScsIDEpLT5kZWxldGUoKTsNCg0KIHJldHVybiByZWRpcmVjdCgpLT5iYWNrKCktPndpdGgoJ21zZ1N1Y2Nlc3MnLCAnc3VjY2VzcycpOw0KfQ0KICAgIA0KICAgICBwdWJsaWMgZnVuY3Rpb24gcmVmX2luZGV4KCkNCiAgICB7DQogICAgICAgICR1c2VyICA9ICR0aGlzLT51c2VyOw0KICAgICAgICBpZiAoJHVzZXItPmxldmVsICE9IDEpDQogICAgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+dG8oJ2Rhc2hib2FyZCcpLT53aXRoKCdtc2dXYXJuaW5nJywgJ0FjY2VzcyBEZW5pZWQhJyk7DQoNCiAgICAgICAgaWYgKCR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCkpDQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlZmZfYWN0aW9uKCk7DQoNCiAgICAgICAgJG1Db2RlID0gbmV3IENvZGVNb2RlbCgpOw0KICAgICAgICAkdmFsaWRhdGlvbiA9IFNlcnZpY2VzOjp2YWxpZGF0aW9uKCk7DQogICAgICAgICRkYXRhID0gWw0KICAgICAgICAgICAgJ3RpdGxlJyA9PiAnUmVmZXJyYWwnLA0KICAgICAgICAgICAgJ3VzZXInID0+ICR1c2VyLA0KICAgICAgICAgICAgJ3RpbWUnID0+ICR0aGlzLT50aW1lLA0KICAgICAgICAgICAgJ2NvZGUnID0+ICRtQ29kZS0+Z2V0Q29kZSgpLA0KICAgICAgICAgICAgJ3RvdGFsX2NvZGUnID0+ICRtQ29kZS0+Y291bnRBbGxSZXN1bHRzKCksDQogICAgICAgICAgICAndmFsaWRhdGlvbicgPT4gJHZhbGlkYXRpb24NCiAgICAgICAgXTsNCiAgICAgICAgcmV0dXJuIHZpZXcoJ0FkbWluL3JlZmVycmFsJywgJGRhdGEpOw0KICAgIH0NCiAgICANCg0KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVmZl9hY3Rpb24oKQ0KICAgIHsNCiAgICAgICAgJHNhbGRvID0gJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ3NldF9zYWxkbycpOw0KICAgICAgICAkZm9ybV9ydWxlcyA9IFsNCiAgICAgICAgICAgICdzZXRfc2FsZG8nID0+IFsNCiAgICAgICAgICAgICAgICAnbGFiZWwnID0+ICdzYWxkbycsDQogICAgICAgICAgICAgICAgJ3J1bGVzJyA9PiAncmVxdWlyZWR8bnVtZXJpY3xtYXhfbGVuZ3RoWzExXXxncmVhdGVyX3RoYW5fZXF1YWxfdG9bMF0nLA0KICAgICAgICAgICAgICAgICdlcnJvcnMnID0+IFsNCiAgICAgICAgICAgICAgICAgICAgJ2dyZWF0ZXJfdGhhbl9lcXVhbF90bycgPT4gJ0ludmFsaWQgY3VycmVuY3ksIGNhbm5vdCBzZXQgdG8gbWludXMuJw0KICAgICAgICAgICAgICAgIF0NCiAgICAgICAgICAgIF0NCiAgICAgICAgXTsNCg0KICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZSgkZm9ybV9ydWxlcykpIHsNCiAgICAgICAgICAgIHJldHVybiByZWRpcmVjdCgpLT5iYWNrKCktPndpdGhJbnB1dCgpLT53aXRoKCdtc2dEYW5nZXInLCAnRmFpbGVkLCBjaGVjayB0aGUgZm9ybScpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICANCiAgICAgICAgICAgICRjb2RlID0gIkNBUFRBSU54Ii4gcmFuZG9tX3N0cmluZygnYWxudW0nLCA2KTsNCiAgICAgICAgICAgICRjb2RlSGFzaCA9IGNyZWF0ZV9wYXNzd29yZCgkY29kZSwgZmFsc2UpOw0KICAgICAgICAgICAgJHJlZmVycmFsX2NvZGUgPSBbDQogICAgICAgICAgICAgICAgJ2NvZGUnID0+ICRjb2RlSGFzaCwNCiAgICAgICAgICAgICAgICAnc2V0X3NhbGRvJyA9PiAoJHNhbGRvIDwgOTk5OTk5OSA/IDk4OTg5NzggOiAkc2FsZG8pLA0KICAgICAgICAgICAgICAgICdjcmVhdGVkX2J5JyA9PiBzZXNzaW9uKCd1bmFtZXMnKQ0KICAgICAgICAgICAgXTsNCiAgICAgICAgICAgICRtQ29kZSA9IG5ldyBDb2RlTW9kZWwoKTsNCiAgICAgICAgICAgICRpZHMgPSAkbUNvZGUtPmluc2VydCgkcmVmZXJyYWxfY29kZSwgdHJ1ZSk7DQogICAgICAgICAgICBpZiAoJGlkcykgew0KICAgICAgICAgICAgICAgICRtc2cgPSAiUmVmZXJyYWwgOiAkY29kZSI7DQogICAgICAgICAgICAgICAgcmV0dXJuIHJlZGlyZWN0KCktPmJhY2soKS0+d2l0aCgnbXNnU3VjY2VzcycsICRtc2cpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KDQogIA0KICAgIC8vcHVibGljIGZ1bmN0aW9uIGFsdGVyVXNlcigpew0KICAgICAgLy8gIGVjaG8gJ2hlbGxvJzsNCiAgICAgICAvLyAgJG1vZGVsID0gbmV3IHVzZXJNb2RlbCgpOw0KICAgIA0KICAgICAgLy8gICRkYXRhPSRtb2RlbC0+d2hlcmUoJ2lkX3VzZXJzICE9JywgMSktPmRlbGV0ZSgpOw0KICAvLyAgcHJpbnRfcigkZGF0YSk7DQogIC8vICAgcmV0dXJuIHJlZGlyZWN0KCktPmJhY2soKS0+d2l0aCgnbXNnU3VjY2VzcycsICdzdWNjZXNzJyk7DQogIC8vICB9DQogICAgICAgIA0KICAgIA0KDQogICAgcHVibGljIGZ1bmN0aW9uIGFwaV9nZXRfdXNlcnMoKQ0KICAgIHsNCiAgICAgICAgLy8gQVBJIGZvciBEYXRhVGFibGVzDQogICAgICAgICRtb2RlbCA9ICR0aGlzLT5tb2RlbDsNCiAgICAgICAgcmV0dXJuICRtb2RlbC0+QVBJX2dldFVzZXIoKTsNCiAgICB9DQoNCiAgICBwdWJsaWMgZnVuY3Rpb24gbWFuYWdlX3VzZXJzKCkNCiAgICB7DQogICAgICAgICR1c2VyICA9ICR0aGlzLT51c2VyOw0KICAgICAgICBpZiAoJHVzZXItPmxldmVsICE9IDEpDQogICAgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+dG8oJ2Rhc2hib2FyZCcpLT53aXRoKCdtc2dXYXJuaW5nJywgJ0FjY2VzcyBEZW5pZWQhJyk7DQoNCiAgICAgICAgJG1vZGVsID0gJHRoaXMtPm1vZGVsOw0KICAgICAgICAkdmFsaWRhdGlvbiA9IFNlcnZpY2VzOjp2YWxpZGF0aW9uKCk7DQogICAgICAgICRkYXRhID0gWw0KICAgICAgICAgICAgJ3RpdGxlJyA9PiAnVXNlcnMnLA0KICAgICAgICAgICAgJ3VzZXInID0+ICR1c2VyLA0KICAgICAgICAgICAgJ3VzZXJfbGlzdCcgPT4gJG1vZGVsLT5nZXRVc2VyTGlzdCgpLA0KICAgICAgICAgICAgJ3RpbWUnID0+ICR0aGlzLT50aW1lLA0KICAgICAgICAgICAgJ3ZhbGlkYXRpb24nID0+ICR2YWxpZGF0aW9uDQogICAgICAgIF07DQogICAgICAgIHJldHVybiB2aWV3KCdBZG1pbi91c2VycycsICRkYXRhKTsNCiAgICB9DQoNCnB1YmxpYyBmdW5jdGlvbiBzaW5nbGVEZWxldGUoJGlkKXsNCiAgICAgDQogICAgICRtb2RlbCA9IG5ldyB1c2VyTW9kZWwoKTsNCiAgICAgICAgLy8gJGlkID0gJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ3VzZXJfaWQnKTsNCiAgICAgICAgLy8gZWNobyAkdXNlcmlkOw0KICAgICAgICBpZigkaWQhPTEpew0KICAgICAgJG1vZGVsLT53aGVyZSgndXNlZF9ieScsJGlkKS0+ZGVsZXRlKCk7DQogICAgICAgIH0NCiAgICAgIHJldHVybiByZWRpcmVjdCgpLT50bygnYWRtaW4vbWFuYWdlLXVzZXJzJyk7DQogICAgDQp9DQoNCnB1YmxpYyBmdW5jdGlvbiBhbHRlclVzZXIoKXsNCiAgICBlY2hvICdoZWxsbyc7DQogICAgICRtb2RlbCA9IG5ldyB1c2VyTW9kZWwoKTsNCg0KICAgICRkYXRhPSRtb2RlbC0+d2hlcmUoJ2lkX3VzZXJzICE9JywgMSktPmRlbGV0ZSgpOw0KDQogcmV0dXJuIHJlZGlyZWN0KCktPmJhY2soKS0+d2l0aCgnbXNnU3VjY2VzcycsICdzdWNjZXNzJyk7DQp9DQogICAgcHVibGljIGZ1bmN0aW9uIHVzZXJfZWRpdCgkdXNlcmlkID0gZmFsc2UpDQogICAgew0KICAgICAgICAkdXNlciA9ICR0aGlzLT51c2VyOw0KICAgICAgICBpZiAoJHVzZXItPmxldmVsICE9IDEpDQogICAgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+dG8oJ2Rhc2hib2FyZCcpLT53aXRoKCdtc2dXYXJuaW5nJywgJ0FjY2VzcyBEZW5pZWQhJyk7DQoNCiAgICAgICAgaWYgKCR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCkpDQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnVzZXJfZWRpdF9hY3Rpb24oKTsNCg0KICAgICAgICAkbW9kZWwgPSAkdGhpcy0+bW9kZWw7DQogICAgICAgICR2YWxpZGF0aW9uID0gU2VydmljZXM6OnZhbGlkYXRpb24oKTsNCg0KICAgICAgICAkZGF0YSA9IFsNCiAgICAgICAgICAgICd0aXRsZScgPT4gJ1NldHRpbmdzJywNCiAgICAgICAgICAgICd1c2VyJyA9PiAkdXNlciwNCiAgICAgICAgICAgICd0YXJnZXQnID0+ICRtb2RlbC0+Z2V0VXNlcigkdXNlcmlkKSwNCiAgICAgICAgICAgICd1c2VyX2xpc3QnID0+ICRtb2RlbC0+Z2V0VXNlckxpc3QoKSwNCiAgICAgICAgICAgICd0aW1lJyA9PiAkdGhpcy0+dGltZSwNCiAgICAgICAgICAgICd2YWxpZGF0aW9uJyA9PiAkdmFsaWRhdGlvbiwNCiAgICAgICAgXTsNCiAgICAgICAgcmV0dXJuIHZpZXcoJ0FkbWluL3VzZXJfZWRpdCcsICRkYXRhKTsNCiAgICB9DQoNCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVzZXJfZWRpdF9hY3Rpb24oKQ0KICAgIHsNCiAgICAgICAgJG1vZGVsID0gJHRoaXMtPm1vZGVsOw0KICAgICAgICAkdXNlcmlkID0gJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ3VzZXJfaWQnKTsNCg0KICAgICAgICAkdGFyZ2V0ID0gJG1vZGVsLT5nZXRVc2VyKCR1c2VyaWQpOw0KICAgICAgICBpZiAoISR0YXJnZXQpIHsNCiAgICAgICAgICAgICRtc2cgPSAiVXNlciBubyBsb25nZXIgZXhpc3RzLiI7DQogICAgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+dG8oJ2Rhc2hib2FyZCcpLT53aXRoKCdtc2dEYW5nZXInLCAkbXNnKTsNCiAgICAgICAgfQ0KDQogICAgICAgICR1c2VybmFtZSA9ICR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCd1c2VybmFtZScpOw0KDQogICAgICAgICRmb3JtX3J1bGVzID0gWw0KICAgICAgICAgICAgJ3VzZXJuYW1lJyA9PiBbDQogICAgICAgICAgICAgICAgJ2xhYmVsJyA9PiAndXNlcm5hbWUnLA0KICAgICAgICAgICAgICAgICdydWxlcycgPT4gInJlcXVpcmVkfGFscGhhX251bWVyaWN8bWluX2xlbmd0aFs0XXxtYXhfbGVuZ3RoWzI1XXxpc191bmlxdWVbdXNlcnMudXNlcm5hbWUsdXNlcm5hbWUsJHRhcmdldC0+dXNlcm5hbWVdIiwNCiAgICAgICAgICAgICAgICAnZXJyb3JzJyA9PiBbDQogICAgICAgICAgICAgICAgICAgICdpc191bmlxdWUnID0+ICdUaGUge2ZpZWxkfSBoYXMgdGFrZW4gYnkgb3RoZXIuJw0KICAgICAgICAgICAgICAgIF0NCiAgICAgICAgICAgIF0sDQogICAgICAgICAgICAnZnVsbG5hbWUnID0+IFsNCiAgICAgICAgICAgICAgICAnbGFiZWwnID0+ICduYW1lJywNCiAgICAgICAgICAgICAgICAncnVsZXMnID0+ICdwZXJtaXRfZW1wdHl8YWxwaGFfc3BhY2V8bWluX2xlbmd0aFs0XXxtYXhfbGVuZ3RoWzE1NV0nLA0KICAgICAgICAgICAgICAgICdlcnJvcnMnID0+IFsNCiAgICAgICAgICAgICAgICAgICAgJ2FscGhhX3NwYWNlJyA9PiAnVGhlIHtmaWVsZH0gb25seSBhbGxvdyBhbHBoYWJldGljYWwgY2hhcmFjdGVycyBhbmQgc3BhY2VzLicNCiAgICAgICAgICAgICAgICBdDQogICAgICAgICAgICBdLA0KICAgICAgICAgICAgJ2xldmVsJyA9PiBbDQogICAgICAgICAgICAgICAgJ2xhYmVsJyA9PiAncm9sZXMnLA0KICAgICAgICAgICAgICAgICdydWxlcycgPT4gJ3JlcXVpcmVkfG51bWVyaWN8aW5fbGlzdFsxLDJdJywNCiAgICAgICAgICAgICAgICAnZXJyb3JzJyA9PiBbDQogICAgICAgICAgICAgICAgICAgICdpbl9saXN0JyA9PiAnSW52YWxpZCB7ZmllbGR9LicNCiAgICAgICAgICAgICAgICBdDQogICAgICAgICAgICBdLA0KICAgICAgICAgICAgJ3N0YXR1cycgPT4gWw0KICAgICAgICAgICAgICAgICdsYWJlbCcgPT4gJ3N0YXR1cycsDQogICAgICAgICAgICAgICAgJ3J1bGVzJyA9PiAncmVxdWlyZWR8bnVtZXJpY3xpbl9saXN0WzAsMV0nLA0KICAgICAgICAgICAgICAgICdlcnJvcnMnID0+IFsNCiAgICAgICAgICAgICAgICAgICAgJ2luX2xpc3QnID0+ICdJbnZhbGlkIHtmaWVsZH0gYWNjb3VudC4nDQogICAgICAgICAgICAgICAgXQ0KICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICdzYWxkbycgPT4gWw0KICAgICAgICAgICAgICAgICdsYWJlbCcgPT4gJ3NhbGRvJywNCiAgICAgICAgICAgICAgICAncnVsZXMnID0+ICdwZXJtaXRfZW1wdHl8bnVtZXJpY3xtYXhfbGVuZ3RoWzExXXxncmVhdGVyX3RoYW5fZXF1YWxfdG9bMF0nLA0KICAgICAgICAgICAgICAgICdlcnJvcnMnID0+IFsNCiAgICAgICAgICAgICAgICAgICAgJ2dyZWF0ZXJfdGhhbl9lcXVhbF90bycgPT4gJ0ludmFsaWQgY3VycmVuY3ksIGNhbm5vdCBzZXQgdG8gbWludXMuJw0KICAgICAgICAgICAgICAgIF0NCiAgICAgICAgICAgIF0sDQogICAgICAgICAgICAndXBsaW5rJyA9PiBbDQogICAgICAgICAgICAgICAgJ2xhYmVsJyA9PiAndXBsaW5rJywNCiAgICAgICAgICAgICAgICAncnVsZXMnID0+ICdyZXF1aXJlZHxhbHBoYV9udW1lcmljfGlzX25vdF91bmlxdWVbdXNlcnMudXNlcm5hbWUsdXNlcm5hbWUsXScsDQogICAgICAgICAgICAgICAgJ2Vycm9ycycgPT4gWw0KICAgICAgICAgICAgICAgICAgICAnaXNfbm90X3VuaXF1ZScgPT4gJ1VwbGluayBub3QgcmVnaXN0ZXJlZCBhbnltb3JlLicNCiAgICAgICAgICAgICAgICBdDQogICAgICAgICAgICBdDQogICAgICAgIF07DQoNCiAgICAgICAgaWYgKCEkdGhpcy0+dmFsaWRhdGUoJGZvcm1fcnVsZXMpKSB7DQogICAgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+YmFjaygpLT53aXRoSW5wdXQoKS0+d2l0aCgnbXNnRGFuZ2VyJywgJ1NvbWV0aGluZyB3cm9uZyEgUGxlYXNlIGNoZWNrIHRoZSBmb3JtJyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAkZnVsbG5hbWUgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnZnVsbG5hbWUnKTsNCiAgICAgICAgICAgICRsZXZlbCA9ICR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdsZXZlbCcpOw0KICAgICAgICAgICAgJHN0YXR1cyA9ICR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdzdGF0dXMnKTsNCiAgICAgICAgICAgICRzYWxkbyA9ICR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdzYWxkbycpOw0KICAgICAgICAgICAgJHVwbGluayA9ICR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCd1cGxpbmsnKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgIC8qICBpZiAoJGltYWdlID09ICIiKSB7DQogICAgICAgICAgICAkZGF0YV91cGRhdGUgPSBbDQogICAgICAgICAgICAgICAgJ3VzZXJuYW1lJyA9PiAkdXNlcm5hbWUsDQogICAgICAgICAgICAgICAgJ2Z1bGxuYW1lJyA9PiBlc2MoJGZ1bGxuYW1lKSwNCiAgICAgICAgICAgICAgICAnbGV2ZWwnID0+ICRsZXZlbCwNCiAgICAgICAgICAgICAgICAnc3RhdHVzJyA9PiAkc3RhdHVzLA0KICAgICAgICAgICAgICAgICdzYWxkbycgPT4gKCgkc2FsZG8gPCAxKSA/IDAgOiAkc2FsZG8pLA0KICAgICAgICAgICAgICAgICd1cGxpbmsnID0+ICR1cGxpbmssDQogICAgICAgICAgICBdOw0KICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAkZGF0YV91cGRhdGUgPSBbDQogICAgICAgICAgICAgICAgJ3VzZXJuYW1lJyA9PiAkdXNlcm5hbWUsDQogICAgICAgICAgICAgICAgJ2Z1bGxuYW1lJyA9PiBlc2MoJGZ1bGxuYW1lKSwNCiAgICAgICAgICAgICAgICAnbGV2ZWwnID0+ICRsZXZlbCwNCiAgICAgICAgICAgICAgICAnc3RhdHVzJyA9PiAkc3RhdHVzLA0KICAgICAgICAgICAgICAgICdzYWxkbycgPT4gKCgkc2FsZG8gPCAxKSA/IDAgOiAkc2FsZG8pLA0KICAgICAgICAgICAgICAgICd1cGxpbmsnID0+ICR1cGxpbmssDQogICAgICAgICAgICAgICAgJ2ltYWdlJyA9PiAkaW1hZ2UsDQogICAgICAgICAgICBdOw0KICAgICAgICAgICAgfSovDQogICAgICAgICAgICAkZGF0YV91cGRhdGUgPSBbDQogICAgICAgICAgICAgICAgJ3VzZXJuYW1lJyA9PiAkdXNlcm5hbWUsDQogICAgICAgICAgICAgICAgJ2Z1bGxuYW1lJyA9PiBlc2MoJGZ1bGxuYW1lKSwNCiAgICAgICAgICAgICAgICAnbGV2ZWwnID0+ICRsZXZlbCwNCiAgICAgICAgICAgICAgICAnc3RhdHVzJyA9PiAkc3RhdHVzLA0KICAgICAgICAgICAgICAgICdzYWxkbycgPT4gKCgkc2FsZG8gPCAxKSA/IDAgOiAkc2FsZG8pLA0KICAgICAgICAgICAgICAgICd1cGxpbmsnID0+ICR1cGxpbmssDQogICAgICAgICAgICBdOw0KDQoNCiAgICAgICAgICAgICR1cGRhdGUgPSAkbW9kZWwtPnVwZGF0ZSgkdXNlcmlkLCAkZGF0YV91cGRhdGUpOw0KICAgICAgICAgICAgaWYgKCR1cGRhdGUpIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+YmFjaygpLT53aXRoKCdtc2dTdWNjZXNzJywgIlN1Y2Nlc3NmdWx5IHVwZGF0ZSAkdGFyZ2V0LT51c2VybmFtZS4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICANCiAgICANCiAgICANCiAgICBwdWJsaWMgZnVuY3Rpb24gdXBsb2FkKCkNCiAgICB7DQogICAgICAgIC8vIFZhbGlkYXRpb24NCiAgICAgJGlucHV0ID0gJHRoaXMtPnZhbGlkYXRlKFsNCiAgICAgICAgJ2ZpbGUnID0+ICd1cGxvYWRlZFtmaWxlXXxtYXhfc2l6ZVtmaWxlLDEwMjRdfGV4dF9pbltmaWxlLGpwZyxqcGVnLGRvY3gscGRmXSwnDQogICAgIF0pOw0KDQogICAgIGlmICghJGlucHV0KSB7IC8vIE5vdCB2YWxpZA0KICAgICAgICAgJGRhdGFbJ3ZhbGlkYXRpb24nXSA9ICR0aGlzLT52YWxpZGF0b3I7IA0KICAgICAgICAgcmV0dXJuIHZpZXcoJ1VzZXIvc2V0dGluZ3onLCRkYXRhKTsgDQogICAgIH1lbHNleyAvLyBWYWxpZA0KDQogICAgICAgICBpZigkZmlsZSA9ICR0aGlzLT5yZXF1ZXN0LT5nZXRGaWxlKCdmaWxlJykpIHsNCiAgICAgICAgICAgIGlmICgkZmlsZS0+aXNWYWxpZCgpICYmICEgJGZpbGUtPmhhc01vdmVkKCkpIHsNCiAgICAgICAgICAgICAgIC8vIEdldCBmaWxlIG5hbWUgYW5kIGV4dGVuc2lvbg0KICAgICAgICAgICAgICAgJG5hbWUgPSAkZmlsZS0+Z2V0TmFtZSgpOw0KICAgICAgICAgICAgICAgJGV4dCA9ICRmaWxlLT5nZXRDbGllbnRFeHRlbnNpb24oKTsNCg0KICAgICAgICAgICAgICAgLy8gR2V0IHJhbmRvbSBmaWxlIG5hbWUNCiAgICAgICAgICAgICAgICRuZXdOYW1lID0gJGZpbGUtPmdldFJhbmRvbU5hbWUoKTsgDQoNCiAgICAgICAgICAgICAgIC8vIFN0b3JlIGZpbGUgaW4gcHVibGljL3VwbG9hZHMvIGZvbGRlcg0KICAgICAgICAgICAgICAgJGZpbGUtPm1vdmUoJy4uL3B1YmxpYy91cGxvYWRzJywgJG5ld05hbWUpOw0KDQogICAgICAgICAgICAgICAvLyBGaWxlIHBhdGggdG8gZGlzcGxheSBwcmV2aWV3DQogICAgICAgICAgICAgICAkZmlsZXBhdGggPSBiYXNlX3VybCgpLiJwdWJsaWMvdXBsb2FkLyIuJG5ld05hbWU7DQogICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgIC8vIFNldCBTZXNzaW9uDQogICAgICAgICAgICAgICBzZXNzaW9uKCktPnNldEZsYXNoZGF0YSgnbWVzc2FnZScsICdVcGxvYWRlZCBTdWNjZXNzZnVsbHkhJyk7DQogICAgICAgICAgICAgICBzZXNzaW9uKCktPnNldEZsYXNoZGF0YSgnYWxlcnQtY2xhc3MnLCAnYWxlcnQtc3VjY2VzcycpOw0KICAgICAgICAgICAgICAgc2Vzc2lvbigpLT5zZXRGbGFzaGRhdGEoJ2ZpbGVwYXRoJywgJGZpbGVwYXRoKTsNCiAgICAgICAgICAgICAgIHNlc3Npb24oKS0+c2V0Rmxhc2hkYXRhKCdleHRlbnNpb24nLCAkZXh0KTsNCg0KICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAgICAvLyBTZXQgU2Vzc2lvbg0KICAgICAgICAgICAgICAgc2Vzc2lvbigpLT5zZXRGbGFzaGRhdGEoJ21lc3NhZ2UnLCAnRmlsZSBub3QgdXBsb2FkZWQuJyk7DQogICAgICAgICAgICAgICBzZXNzaW9uKCktPnNldEZsYXNoZGF0YSgnYWxlcnQtY2xhc3MnLCAnYWxlcnQtZGFuZ2VyJyk7DQoNCiAgICAgICAgICAgIH0NCiAgICAgICAgIH0NCg0KICAgICB9DQogIA0KICAgICByZXR1cm4gcmVkaXJlY3QoKS0+cm91dGUoJy8nKTsgDQogICANCiAgICB9DQogICAgDQoNCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0dGluZ3MoKQ0KICAgIHsNCiAgICAgICANCiAgICAgICAgICAgIGlmICgkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgncGFzc3dvcmRfZm9ybScpKQ0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wYXNzd2RfYWN0KCk7DQoNCiAgICAgICAgaWYgKCR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdmdWxsbmFtZV9mb3JtJykpDQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZ1bGxuYW1lX2FjdCgpOw0KDQogICAgICAgICR1c2VyID0gJHRoaXMtPnVzZXI7DQogICAgICAgIA0KICAgICAgICAkdmFsaWRhdGlvbiA9IFNlcnZpY2VzOjp2YWxpZGF0aW9uKCk7DQogICAgICAgICRkYXRhID0gWw0KICAgICAgICAgICAgJ3RpdGxlJyA9PiAnU2V0dGluZ3MnLA0KICAgICAgICAgICAgJ3VzZXInID0+ICR1c2VyLA0KICAgICAgICAgICAgJ3RpbWUnID0+ICR0aGlzLT50aW1lLA0KICAgICAgICAgICAgJ3ZhbGlkYXRpb24nID0+ICR2YWxpZGF0aW9uDQogICAgICAgIF07DQoNCiAgICAgICAgcmV0dXJuIHZpZXcoJ1VzZXIvc2V0dGluZ3MnLCAkZGF0YSk7DQogICAgfQ0KICAgIA0KICAgIA0KICAgIA0KICAgIHB1YmxpYyBmdW5jdGlvbiB1c2VyX3N0YXR1c19jaGFuZ2VkKCkNCnsNCiAgICAvL2dldCBoaWRkZW4gdmFsdWVzIGluIHZhcmlhYmxlcw0KCSRpZCA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnaWQnKTsNCgkkc3RhdHVzID0gJHRoaXMtPmlucHV0LT5wb3N0KCdzdGF0dXMnKTsNCg0KICAgIC8vY2hlY2sgY29uZGl0aW9uDQoJaWYoJHN0YXR1cyA9PSAnMScpew0KCQkkcGxheWVyX3N0YXR1cyA9ICcwJzsNCgl9DQoJZWxzZXsNCgkJJHBsYXllcl9zdGF0dXMgPSAnMSc7DQoJfQ0KDQoJJGRhdGEgPSBhcnJheSgnc3RhdHVzJyA9PiAkcGxheWVyX3N0YXR1cyApOw0KDQoJJHRoaXMtPmRiLT53aGVyZSgnaWQnLCRpZCk7DQoJJHRoaXMtPmRiLT51cGRhdGUoJ3BsYXllcnMnLCAkZGF0YSk7IC8vVXBkYXRlIHN0YXR1cyBoZXJlDQoNCiAgICAvL0NyZWF0ZSBzdWNjZXNzIG1lYXNhZ2UNCgkkdGhpcy0+c2Vzc2lvbi0+c2V0X2ZsYXNoZGF0YSgnbXNnJywiVXNlciBzdGF0dXMgaGFzIGJlZW4gY2hhbmdlZCBzdWNjZXNzZnVsbHkuIik7DQogICAgJHRoaXMtPnNlc3Npb24tPnNldF9mbGFzaGRhdGEoJ21zZ19jbGFzcycsJ2FsZXJ0LXN1Y2Nlc3MnKTsNCg0KICAgIHJldHVybiByZWRpcmVjdCgndXNlcnMnKTsNCn0NCiAgICANCiAgICBwdWJsaWMgZnVuY3Rpb24gU2VydmVyKCkNCiAgICB7DQogICAgICAgICR1c2VyID0gJHRoaXMtPnVzZXI7DQogICAgICAgIGlmICgkdXNlci0+bGV2ZWwgPT0gMSkNCiAgICAgICAgew0KICAgICAgICANCiAgICAgICAgaWYgKCR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdtb2RuYW1lX2Zvcm0nKSkNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tb2RuYW1lX2FjdCgpOw0KICAgICAgICAgICAgDQogICAgICAgIGlmICgkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnc3RhdHVzX2Zvcm0nKSkNCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+c3RhdHVzX2FjdCgpOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBpZiAoJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ3Bhc3N3b3JkX2Zvcm0nKSkNCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cGFzc3dkX2FjdCgpOw0KICAgICAgICAgICAgDQogICAgICAgIGlmICgkdXNlci0+bGV2ZWwgPT0gMSkNCiAgICAgICAgew0KICAgICAgICANCiAgICAgICAgICAgIGlmICgkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnX2Z0ZXh0JykpDQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPl9mdGV4dF9hY3QoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmICgkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnZnVsbG5hbWVfZm9ybScpKQ0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5mdWxsbmFtZV9hY3QoKTsNCg0KICAgICAgICAkdXNlciA9ICR0aGlzLT51c2VyOw0KICAgICAgICANCiAgICAgICAgJHZhbGlkYXRpb24gPSBTZXJ2aWNlczo6dmFsaWRhdGlvbigpOw0KICAgICAgICAkZGF0YSA9IFsNCiAgICAgICAgICAgICd0aXRsZScgPT4gJ1NlcnZlcicsDQogICAgICAgICAgICAndXNlcicgPT4gJHVzZXIsDQogICAgICAgICAgICAndGltZScgPT4gJHRoaXMtPnRpbWUsDQogICAgICAgICAgICAndmFsaWRhdGlvbicgPT4gJHZhbGlkYXRpb24NCiAgICAgICAgXTsNCiAgICAgICAgDQogICAgICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PU1vZCBOYW1lPT09PT09PT09PT09PT09PT09PT09PS8vDQogICAgICAgIA0KICAgICAgICAkaWQgPSAxOw0KCSAgICANCgkgICAgJG1vZGVsPSBuZXcgU2VydmVyKCk7DQoJICAgIA0KCSAgICAkZGF0YVsncm93J10gPSAkbW9kZWwtPndoZXJlKCdpZCcsJGlkKS0+Zmlyc3QoKTsNCgkgICAgDQoJICAgICBpZiAoJHVzZXItPmxldmVsID09IDEpew0KCQlyZXR1cm4gdmlldygnU2VydmVyL1NlcnZlcicsJGRhdGEpOw0KCSAgICAgfQ0KCSAgICAgZWxzZSB7DQoJICAgICAgICAgDQoJICAgICAgICAgcmV0dXJuIHJlZGlyZWN0KCktPnRvKCdkYXNoYm9hcmQnKS0+d2l0aCgnbXNnV2FybmluZycsJ0FjY2VzcyBEZW5pZW5kJyk7DQoJICAgICB9DQoJCQ0KCQkNCgkJLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09TW9kIFN0YXR1cz09PT09PT09PT09PT09PT09PT09PT0vLw0KCSAgIA0KCQkNCgkJDQogICAgfQ0KICAgIA0KICAgICAgICAgICAgcHVibGljIGZ1bmN0aW9uIFByb2ZpbGUoKQ0KICAgIHsNCiAgICAgICAgJHVzZXIgPSAkdGhpcy0+dXNlcjsNCiAgICAgICAgaWYgKCR1c2VyLT5sZXZlbCA9PSAxKQ0KICAgICAgICB7DQogICAgICAgIA0KICAgICAgICBpZiAoJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ21vZG5hbWVfZm9ybScpKQ0KICAgICAgICAgICAgDQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPm1vZG5hbWVfYWN0KCk7DQogICAgICAgICAgICANCiAgICAgICAgaWYgKCR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdzdGF0dXNfZm9ybScpKQ0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5zdGF0dXNfYWN0KCk7DQogICAgICAgIH0NCiAgICAgICAgDQogICAgICAgIGlmICgkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgncGFzc3dvcmRfZm9ybScpKQ0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wYXNzd2RfYWN0KCk7DQogICAgICAgICAgICANCiAgICAgICAgaWYgKCR1c2VyLT5sZXZlbCA9PSAxKQ0KICAgICAgICB7DQogICAgICAgIA0KICAgICAgICAgICAgaWYgKCR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdfZnRleHQnKSkNCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+X2Z0ZXh0X2FjdCgpOw0KICAgICAgICB9DQogICAgICAgICAgDQoNCiAgICAgICAgaWYgKCR0aGlzLT5yZXF1ZXN0LT5nZXRQb3N0KCdmdWxsbmFtZV9mb3JtJykpDQogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZ1bGxuYW1lX2FjdCgpOw0KDQogICAgICAgICR1c2VyID0gJHRoaXMtPnVzZXI7DQogICAgICAgIA0KICAgICAgICAkbW9kZWwgPSAkdGhpcy0+bW9kZWw7DQogICAgICAgICR2YWxpZGF0aW9uID0gU2VydmljZXM6OnZhbGlkYXRpb24oKTsNCiAgICAgICAgJGRhdGEgPSBbDQogICAgICAgICAgICAndGl0bGUnID0+ICdVc2VycycsDQogICAgICAgICAgICAndXNlcicgPT4gJHVzZXIsDQogICAgICAgICAgICAndXNlcl9saXN0JyA9PiAkbW9kZWwtPmdldFVzZXJMaXN0KCksDQogICAgICAgICAgICAndGltZScgPT4gJHRoaXMtPnRpbWUsDQogICAgICAgICAgICAndmFsaWRhdGlvbicgPT4gJHZhbGlkYXRpb24NCiAgICAgICAgXTsNCiAgICAgICAgDQogICAgICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PU1vZCBOYW1lPT09PT09PT09PT09PT09PT09PT09PS8vDQogICAgICAgIA0KICAgICAgICAkaWQgPSAxOw0KCSAgICANCgkgICAgJG1vZGVsPSBuZXcgU2VydmVyKCk7DQoJICAgIA0KCSAgICAkZGF0YVsncm93J10gPSAkbW9kZWwtPndoZXJlKCdpZCcsJGlkKS0+Zmlyc3QoKTsNCgkgICAgDQoJDQoJCXJldHVybiB2aWV3KCdQcm9maWxlL1Byb2ZpbGUnLCRkYXRhKTsNCgkNCgkJDQoJCS8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PU1vZCBTdGF0dXM9PT09PT09PT09PT09PT09PT09PT09Ly8NCgkgICANCgkJDQoJCQ0KICAgIH0NCiAgICANCiAgICAgICAgcHVibGljIGZ1bmN0aW9uIFBpYygpDQogICAgew0KICAgICAgICAkbW9kZWw9IG5ldyBTZXJ2ZXIoKTsNCiAgICAgICAgICAgICR1c2VyID0gJHRoaXMtPnVzZXI7DQogICAgJGlkID0gMTsNCiAgICAgICAgICAgICR2YWxpZGF0aW9uID0gU2VydmljZXM6OnZhbGlkYXRpb24oKTsNCiAgICAgICAgJGRhdGEgPSBbDQogICAgICAgICAgICAndGl0bGUnID0+ICdQcm9maWxlJywNCiAgICAgICAgICAgICd1c2VyJyA9PiAkdXNlciwNCiAgICAgICAgICAgICd0aW1lJyA9PiAkdGhpcy0+dGltZSwNCiAgICAgICAgICAgICd2YWxpZGF0aW9uJyA9PiAkdmFsaWRhdGlvbg0KICAgICAgICBdOw0KICAgICAgICANCg0KCSAgICAkZGF0YVsncm93J10gPSAkbW9kZWwtPndoZXJlKCdpZCcsJGlkKS0+Zmlyc3QoKTsNCgkgICAgIGlmICgkdXNlci0+bGV2ZWwgPT0gMSl7DQoJCXJldHVybiB2aWV3KCdQaWMvUGljJywkZGF0YSk7DQoJICAgICB9DQoJICAgICBlbHNlIHsNCgkgICAgICAgICANCgkgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+dG8oJ2Rhc2hib2FyZCcpLT53aXRoKCdtc2dXYXJuaW5nJywnQWNjZXNzIERlbmllbmQnKTsNCgkgICAgIH0NCgkJDQoJCQ0KCQkvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1Nb2QgU3RhdHVzPT09PT09PT09PT09PT09PT09PT09PS8vDQoJICAgDQoJCQ0KCQkNCiAgICB9DQogICAgDQogICAgDQogICAgIHByaXZhdGUgZnVuY3Rpb24gX2Z0ZXh0X2FjdCgpDQogICAgew0KICAgICAgICAgJGlkID0gMTsNCgkgICAgDQoJICAgICRtb2RlbD0gbmV3IF9mdGV4dCgpOw0KCSAgICANCgkgICAgJG15aW5wdXQgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnX2Z0ZXh0Jyk7DQoJICAgIA0KCSAgICAkc3RhdHVzID0gJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ19mdGV4dHInKTsNCgkgICAgDQoJaWYoJHN0YXR1cyA9PSAiMSIpew0KICAgICAgICANCiAgICAgICAgJHdvdz0iU2FmZSI7DQogICAgICAgIA0KICAgIH0NCiAgICBpZigkc3RhdHVzID09ICIyIil7DQogICAgICAgIA0KICAgICAgICAkd293PSJQbGF5IFNhZmUgfHwgQXZvaWQgUmVwb3J0IjsNCiAgICAgICAgDQogICAgfQ0KICAgIA0KICAgICAgJGRhdGEgPSBbJ19mdGV4dCcgPT4gJG15aW5wdXQsJ19zdGF0dXMnID0+ICR3b3ddOw0KCSAgICANCgkgICAgJG1vZGVsLT51cGRhdGUoJGlkLCRkYXRhKTsNCgkgICAgcmV0dXJuIHJlZGlyZWN0KCktPmJhY2soKS0+d2l0aCgnbXNnU3VjY2VzcycsICdTdWNjZXNzZnVseSBDaGFuZ2VkIE1vZCBGbG9hdGluZyBBbmQgU3RhdHVzLicpOw0KICAgIA0KICAgIH0NCiAgICANCiAgICBwcml2YXRlIGZ1bmN0aW9uIHN0YXR1c19hY3QoKQ0KICAgIHsNCiAgICAgICAgJGlkID0gMTE7DQoJICAgIA0KCSAgICAkbW9kZWw9IG5ldyBTdGF0dXMoKTsNCgkgICAgDQoJICAgICRteWlucHV0ID0gJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ215SW5wdXQnKTsNCgkgICAgDQoJICAgICRzdGF0dXMgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgncmFkaW9zJyk7DQogICAgDQogICAgICAgIGlmKCRzdGF0dXMgPT0gIjEiKXsNCiAgICAgICAgDQogICAgICAgICR3b3c9Im9uIjsNCiAgICAgICAgDQogICAgfQ0KICAgIGlmKCRzdGF0dXMgPT0gIjIiKXsNCiAgICAgICAgDQogICAgICAgICR3b3c9Im9mZiI7DQogICAgICAgIA0KICAgIH0NCiAgICANCgkgICAgJGRhdGEgPSBbJ215aW5wdXQnID0+ICRteWlucHV0LCdzdGF0dXMnID0+ICR3b3ddOw0KCSAgICANCgkgICAgJG1vZGVsLT51cGRhdGUoJGlkLCRkYXRhKTsNCgkgICAgcmV0dXJuIHJlZGlyZWN0KCktPmJhY2soKS0+d2l0aCgnbXNnU3VjY2VzcycsICdNb2QgU3RhdHVzIFN1Y2Nlc3NmdWx5IENoYW5nZWQuJyk7DQogICAgICAgIA0KCSAgICANCgkgICAgDQogICAgfQ0KICAgICAgcHJpdmF0ZSBmdW5jdGlvbiBtb2RuYW1lX2FjdCgpDQogICAgew0KICAgICAgICAkaWQgPSAxOw0KCSAgICANCgkgICAgJG1vZGVsPSBuZXcgU2VydmVyKCk7DQoJICAgIA0KCSAgICAkbmV3X21vZG5hbWUgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnbW9kbmFtZScpOw0KCSAgICANCgkgICAgJGRhdGEgPSBbJ21vZG5hbWUnID0+ICRuZXdfbW9kbmFtZV07DQoJICAgIA0KCSAgIA0KCSAgICAkbW9kZWwtPnVwZGF0ZSgkaWQsJGRhdGEpOw0KCSANCgkgICAgcmV0dXJuIHJlZGlyZWN0KCktPmJhY2soKS0+d2l0aCgnbXNnU3VjY2VzcycsICdNb2QgTmFtZSBTdWNjZXNzZnVseSBDaGFuZ2VkLicpOw0KICAgICAgICANCiAgICAgICAgDQogICAgICAgIA0KICAgIH0NCiAgDQoNCiAgICBwcml2YXRlIGZ1bmN0aW9uIHBhc3N3ZF9hY3QoKQ0KICAgIHsNCiAgICAgICAgJGN1cnJlbnQgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnY3VycmVudCcpOw0KICAgICAgICAkcGFzc3dvcmQgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgncGFzc3dvcmQnKTsNCg0KICAgICAgICAkdXNlciA9ICR0aGlzLT51c2VyOw0KICAgICAgICAkY3Vyckhhc2ggPSBjcmVhdGVfcGFzc3dvcmQoJGN1cnJlbnQsIGZhbHNlKTsNCiAgICAgICAgJHZhbGlkYXRpb24gPSBTZXJ2aWNlczo6dmFsaWRhdGlvbigpOw0KDQogICAgICAgIGlmICghcGFzc3dvcmRfdmVyaWZ5KCRjdXJySGFzaCwgJHVzZXItPnBhc3N3b3JkKSkgew0KICAgICAgICAgICAgJG1zZyA9ICJXcm9uZyBjdXJyZW50IHBhc3N3b3JkLiI7DQogICAgICAgICAgICAkdmFsaWRhdGlvbi0+c2V0RXJyb3IoJ2N1cnJlbnQnLCAkbXNnKTsNCiAgICAgICAgfSBlbHNlaWYgKCRjdXJyZW50ID09ICRwYXNzd29yZCkgew0KICAgICAgICAgICAgJG1zZyA9ICJOb3RoaW5nIHRvIGNoYW5nZS4iOw0KICAgICAgICAgICAgJHZhbGlkYXRpb24tPnNldEVycm9yKCdwYXNzd29yZCcsICRtc2cpOw0KICAgICAgICB9DQoNCiAgICAgICAgJGZvcm1fcnVsZXMgPSBbDQogICAgICAgICAgICAnZnVsbG5hbWUnID0+IFsNCiAgICAgICAgICAgICAgICAnbGFiZWwnID0+ICduYW1lJywNCiAgICAgICAgICAgICAgICAncnVsZXMnID0+ICdyZXF1aXJlZHxhbHBoYV9zcGFjZXxtaW5fbGVuZ3RoWzRdfG1heF9sZW5ndGhbMTU1XScsDQogICAgICAgICAgICAgICAgJ2Vycm9ycycgPT4gWw0KICAgICAgICAgICAgICAgICAgICAnYWxwaGFfc3BhY2UnID0+ICdUaGUge2ZpZWxkfSBvbmx5IGFsbG93IGFscGhhYmV0aWNhbCBjaGFyYWN0ZXJzIGFuZCBzcGFjZXMuJw0KICAgICAgICAgICAgICAgIF0NCiAgICAgICAgICAgIF0NCiAgICAgICAgXTsNCg0KICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZSgkZm9ybV9ydWxlcykpIHsNCiAgICAgICAgICAgIHJldHVybiByZWRpcmVjdCgpLT5iYWNrKCktPndpdGhJbnB1dCgpLT53aXRoKCdtc2dEYW5nZXInLCAnU29tZXRoaW5nIHdyb25nISBQbGVhc2UgY2hlY2sgdGhlIGZvcm0nKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICRuZXdQYXNzd29yZCA9IGNyZWF0ZV9wYXNzd29yZCgkY3VycmVudCk7DQogICAgICAgICAgICAkdGhpcy0+bW9kZWwtPnVwZGF0ZShzZXNzaW9uKCd1c2VyaWQnKSwgWydwYXNzd29yZCcgPT4gJG5ld1Bhc3N3b3JkXSk7DQogICAgICAgICAgICByZXR1cm4gcmVkaXJlY3QoKS0+YmFjaygpLT53aXRoKCdtc2dTdWNjZXNzJywgJ1Bhc3N3b3JkIFN1Y2Nlc3NmdWx5IENoYW5nZWQuJyk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICBwcml2YXRlIGZ1bmN0aW9uIGZ1bGxuYW1lX2FjdCgpDQogICAgew0KICAgIGluY2x1ZGUoJ2Nvbm4ucGhwJyk7DQoNCiAgICAgICAgJHVzZXIgPSAkdGhpcy0+dXNlcjsNCiAgICAgICAgJG5ld05hbWUgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgnZnVsbG5hbWUnKTsNCiAgICAgICAgJGltYWdlID0gJHRoaXMtPnJlcXVlc3QtPmdldFBvc3QoJ2ltYWdlJyk7DQoNCiAgICAgICAgJGZvcm1fcnVsZXMgPSBbDQogICAgICAgICAgICAnZnVsbG5hbWUnID0+IFsNCiAgICAgICAgICAgICAgICAnbGFiZWwnID0+ICduYW1lJywNCiAgICAgICAgICAgICAgICAncnVsZXMnID0+ICdyZXF1aXJlZHxhbHBoYV9zcGFjZXxtaW5fbGVuZ3RoWzRdfG1heF9sZW5ndGhbMTU1XScsDQogICAgICAgICAgICAgICAgJ2Vycm9ycycgPT4gWw0KICAgICAgICAgICAgICAgICAgICAnYWxwaGFfc3BhY2UnID0+ICdUaGUge2ZpZWxkfSBvbmx5IGFsbG93IGFscGhhYmV0aWNhbCBjaGFyYWN0ZXJzIGFuZCBzcGFjZXMuJw0KICAgICAgICAgICAgICAgIF0NCiAgICAgICAgICAgIF0NCiAgICAgICAgXTsNCiAgICAgICAgJGlkb3AgPSBzZXNzaW9uKCd1c2VyaWQnKTsNCiAgICAgICAgaWYgKGVtcHR5KCRpbWFnZSkpew0KICAgICAgICAkZGF0YSA9IFsNCiAgICAgICAgICAgICdmdWxsbmFtZScgPT4gZXNjKCRuZXdOYW1lKSwNCiAgICAgICAgXTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoIWVtcHR5KCRpbWFnZSkpew0KICAgICAgICAkZGF0YSA9IFsNCiAgICAgICAgICAgICdmdWxsbmFtZScgPT4gZXNjKCRuZXdOYW1lKSwNCiAgICAgICAgXTsNCiAgICAgICAgJHNxbDEgPSJVUERBVEUgdXNlcnMgU0VUIGltYWdlPSckaW1hZ2UnIFdIRVJFIGlkX3VzZXJzPSRpZG9wIjsNCiAgICAgICAgJHJlc3VsdDEgPSBteXNxbGlfcXVlcnkoJGNvbm4sICRzcWwxKTsNCmlmICgkcmVzdWx0MSl7fQ0KICAgICAgICB9DQoNCg0KICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZSgkZm9ybV9ydWxlcykpIHsNCiAgICAgICAgICAgIHJldHVybiByZWRpcmVjdCgpLT5iYWNrKCktPndpdGhJbnB1dCgpLT53aXRoKCdtc2dEYW5nZXInLCAnRmFpbGVkISBQbGVhc2UgY2hlY2sgdGhlIGZvcm0gJGhhc2hQYXNzd29yZCcpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgJHRoaXMtPm1vZGVsLT51cGRhdGUoc2Vzc2lvbigndXNlcmlkJyksICRkYXRhKTsNCiAgICAgICAgICAgIHJldHVybiByZWRpcmVjdCgpLT5iYWNrKCktPndpdGgoJ21zZ1N1Y2Nlc3MnLCAnQWNjb3VudCBEZXRhaWwgU3VjY2Vzc2Z1bHkgQ2hhbmdlZC4nLnNlc3Npb24oJ3VzZXJpZCcpKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICANCiAgICAgcHVibGljIGZ1bmN0aW9uIGxpYigpDQogICAgew0KICAgICAgICAkdXNlciAgPSAkdGhpcy0+dXNlcjsNCiAgICAgICAgaWYgKCR1c2VyLT5sZXZlbCAhPSAxKQ0KICAgICAgICAgICAgcmV0dXJuIHJlZGlyZWN0KCktPnRvKCdkYXNoYm9hcmQnKS0+d2l0aCgnbXNnV2FybmluZycsICdBY2Nlc3MgRGVuaWVkIScpOw0KDQogICAgICAgIGlmICgkdGhpcy0+cmVxdWVzdC0+Z2V0UG9zdCgpKQ0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5saWJfYWN0aW9uKCk7DQoNCiAgICAgICAgJG1Db2RlID0gbmV3IENvZGVNb2RlbCgpOw0KICAgICAgICAkdmFsaWRhdGlvbiA9IFNlcnZpY2VzOjp2YWxpZGF0aW9uKCk7DQogICAgICAgICRkYXRhID0gWw0KICAgICAgICAgICAgJ3RpdGxlJyA9PiAnUmVmZXJyYWwnLA0KICAgICAgICAgICAgJ3VzZXInID0+ICR1c2VyLA0KICAgICAgICAgICAgJ3RpbWUnID0+ICR0aGlzLT50aW1lLA0KICAgICAgICAgICAgJ2NvZGUnID0+ICRtQ29kZS0+Z2V0Q29kZSgpLA0KICAgICAgICAgICAgJ3RvdGFsX2NvZGUnID0+ICRtQ29kZS0+Y291bnRBbGxSZXN1bHRzKCksDQogICAgICAgICAgICAndmFsaWRhdGlvbicgPT4gJHZhbGlkYXRpb24NCiAgICAgICAgXTsNCiAgICAgICAgcmV0dXJuIHZpZXcoJ2xpYi9saWInLCAkZGF0YSk7DQogICAgfQ0KICAgIHB1YmxpYyBmdW5jdGlvbiBsaWJfYWN0aW9uKCkNCiAgICB7DQovLyRpbWcgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0RmlsZSgnbGliZmlsZScpOw0KDQogICAgIC8vIFZhbGlkYXRpb24NCiAgICAgJGlucHV0ID0gJHRoaXMtPnZhbGlkYXRlKFsNCiAgICAgICAgJ2ZpbGUnID0+ICd1cGxvYWRlZFtmaWxlXXxtYXhfc2l6ZVtmaWxlLDEwMjRdfGV4dF9pbltzb10sJw0KICAgICBdKTsNCg0KICAgICBpZiAoISRpbnB1dCkgeyAvLyBOb3QgdmFsaWQNCiAgICAgICAgICRkYXRhWyd2YWxpZGF0aW9uJ10gPSAkdGhpcy0+dmFsaWRhdG9yOyANCiAgICAgICAgIHJldHVybiB2aWV3KCd1c2VycycsJGRhdGEpOyANCiAgICAgfWVsc2V7IC8vIFZhbGlkDQoNCiAgICAgICAgIGlmKCRmaWxlID0gJHRoaXMtPnJlcXVlc3QtPmdldEZpbGUoJ2ZpbGUnKSkgew0KICAgICAgICAgICAgaWYgKCRmaWxlLT5pc1ZhbGlkKCkgJiYgISAkZmlsZS0+aGFzTW92ZWQoKSkgew0KICAgICAgICAgICAgICAgLy8gR2V0IGZpbGUgbmFtZSBhbmQgZXh0ZW5zaW9uDQogICAgICAgICAgICAgICAkbmFtZSA9ICRmaWxlLT5nZXROYW1lKCk7DQogICAgICAgICAgICAgICAkZXh0ID0gJGZpbGUtPmdldENsaWVudEV4dGVuc2lvbigpOw0KDQogICAgICAgICAgICAgICAvLyBHZXQgcmFuZG9tIGZpbGUgbmFtZQ0KICAgICAgICAgICAgICAgJG5ld05hbWUgPSAkZmlsZS0+Z2V0UmFuZG9tTmFtZSgpOyANCg0KICAgICAgICAgICAgICAgLy8gU3RvcmUgZmlsZSBpbiBwdWJsaWMvdXBsb2Fkcy8gZm9sZGVyDQogICAgICAgICAgICAgICAkZmlsZS0+bW92ZSgnLi4vcHVibGljL3VwbG9hZHMnLCAkbmV3TmFtZSk7DQoNCiAgICAgICAgICAgICAgIC8vIEZpbGUgcGF0aCB0byBkaXNwbGF5IHByZXZpZXcNCiAgICAgICAgICAgICAgICRmaWxlcGF0aCA9IGJhc2VfdXJsKCkuIi91cGxvYWRzLyIuJG5ld05hbWU7DQogICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgIC8vIFNldCBTZXNzaW9uDQogICAgICAgICAgICAgICBzZXNzaW9uKCktPnNldEZsYXNoZGF0YSgnbWVzc2FnZScsICdVcGxvYWRlZCBTdWNjZXNzZnVsbHkhJyk7DQogICAgICAgICAgICAgICBzZXNzaW9uKCktPnNldEZsYXNoZGF0YSgnYWxlcnQtY2xhc3MnLCAnYWxlcnQtc3VjY2VzcycpOw0KICAgICAgICAgICAgICAgc2Vzc2lvbigpLT5zZXRGbGFzaGRhdGEoJ2ZpbGVwYXRoJywgJGZpbGVwYXRoKTsNCiAgICAgICAgICAgICAgIHNlc3Npb24oKS0+c2V0Rmxhc2hkYXRhKCdleHRlbnNpb24nLCAkZXh0KTsNCg0KICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAgICAvLyBTZXQgU2Vzc2lvbg0KICAgICAgICAgICAgICAgc2Vzc2lvbigpLT5zZXRGbGFzaGRhdGEoJ21lc3NhZ2UnLCAnRmlsZSBub3QgdXBsb2FkZWQuJyk7DQogICAgICAgICAgICAgICBzZXNzaW9uKCktPnNldEZsYXNoZGF0YSgnYWxlcnQtY2xhc3MnLCAnYWxlcnQtZGFuZ2VyJyk7DQoNCiAgICAgICAgICAgIH0NCiAgICAgICAgIH0NCg0KICAgICB9DQogIA0KICAgICByZXR1cm4gcmVkaXJlY3QoKS0+cm91dGUoJy8nKTsgDQogICAgIC8vIFZhbGlkYXRpb24NCiAgICAgJGlucHV0ID0gJHRoaXMtPnZhbGlkYXRlKFsNCiAgICAgICAgJ2ZpbGUnID0+ICd1cGxvYWRlZFtmaWxlXXxtYXhfc2l6ZVtmaWxlLDEwMjRdfGV4dF9pbltmaWxlLGpwZyxqcGVnLGRvY3gscGRmXSwnDQogICAgIF0pOw0KDQogICAgIGlmICghJGlucHV0KSB7IC8vIE5vdCB2YWxpZA0KICAgICAgICAgJGRhdGFbJ3ZhbGlkYXRpb24nXSA9ICR0aGlzLT52YWxpZGF0b3I7IA0KICAgICAgICAgcmV0dXJuIHZpZXcoJ3VzZXJzJywkZGF0YSk7IA0KICAgICB9ZWxzZXsgLy8gVmFsaWQNCg0KICAgICAgICAgaWYoJGZpbGUgPSAkdGhpcy0+cmVxdWVzdC0+Z2V0RmlsZSgnZmlsZScpKSB7DQogICAgICAgICAgICBpZiAoJGZpbGUtPmlzVmFsaWQoKSAmJiAhICRmaWxlLT5oYXNNb3ZlZCgpKSB7DQogICAgICAgICAgICAgICAvLyBHZXQgZmlsZSBuYW1lIGFuZCBleHRlbnNpb24NCiAgICAgICAgICAgICAgICRuYW1lID0gJGZpbGUtPmdldE5hbWUoKTsNCiAgICAgICAgICAgICAgICRleHQgPSAkZmlsZS0+Z2V0Q2xpZW50RXh0ZW5zaW9uKCk7DQoNCiAgICAgICAgICAgICAgIC8vIEdldCByYW5kb20gZmlsZSBuYW1lDQogICAgICAgICAgICAgICAkbmV3TmFtZSA9ICRmaWxlLT5nZXRSYW5kb21OYW1lKCk7IA0KDQogICAgICAgICAgICAgICAvLyBTdG9yZSBmaWxlIGluIHB1YmxpYy91cGxvYWRzLyBmb2xkZXINCiAgICAgICAgICAgICAgICRmaWxlLT5tb3ZlKCcuLi93cml0YWJsZS91cGxvYWRzJywgJG5ld05hbWUpOw0KDQogICAgICAgICAgICAgICAvLyBGaWxlIHBhdGggdG8gZGlzcGxheSBwcmV2aWV3DQogICAgICAgICAgICAgICAkZmlsZXBhdGggPSBiYXNlX3VybCgpLiIvdXBsb2Fkcy8iLiRuZXdOYW1lOw0KICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAvLyBTZXQgU2Vzc2lvbg0KICAgICAgICAgICAgICAgc2Vzc2lvbigpLT5zZXRGbGFzaGRhdGEoJ21lc3NhZ2UnLCAnVXBsb2FkZWQgU3VjY2Vzc2Z1bGx5IScpOw0KICAgICAgICAgICAgICAgc2Vzc2lvbigpLT5zZXRGbGFzaGRhdGEoJ2FsZXJ0LWNsYXNzJywgJ2FsZXJ0LXN1Y2Nlc3MnKTsNCiAgICAgICAgICAgICAgIHNlc3Npb24oKS0+c2V0Rmxhc2hkYXRhKCdmaWxlcGF0aCcsICRmaWxlcGF0aCk7DQogICAgICAgICAgICAgICBzZXNzaW9uKCktPnNldEZsYXNoZGF0YSgnZXh0ZW5zaW9uJywgJGV4dCk7DQoNCiAgICAgICAgICAgIH1lbHNlew0KICAgICAgICAgICAgICAgLy8gU2V0IFNlc3Npb24NCiAgICAgICAgICAgICAgIHNlc3Npb24oKS0+c2V0Rmxhc2hkYXRhKCdtZXNzYWdlJywgJ0ZpbGUgbm90IHVwbG9hZGVkLicpOw0KICAgICAgICAgICAgICAgc2Vzc2lvbigpLT5zZXRGbGFzaGRhdGEoJ2FsZXJ0LWNsYXNzJywgJ2FsZXJ0LWRhbmdlcicpOw0KDQogICAgICAgICAgICB9DQogICAgICAgICB9DQoNCiAgICAgfQ0KICANCiAgICAgcmV0dXJuIHJlZGlyZWN0KCktPnJvdXRlKCcvJyk7IA0KICAgICAgICB9DQovL2VjaG8gImpkamQiOw0KICAgICAgLy8gICAgICAkZGF0YSA9IFsndXBsb2FkZWRfZmlsZWluZm8nID0+IG5ldyBGaWxlKCRmaWxlcGF0aCldOw0KDQogICAgIC8vICAgICAgIHJldHVybiB2aWV3KCd1cGxvYWRfc3VjY2VzcycsICRkYXRhKTsNCiAgICB9DQo=")); ?>

Function Calls

base64_decode 1

Variables

None

Stats

MD5 060e6619f54e61a522778a47c6016885
Eval Count 1
Decode Time 114 ms