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

Signing you up...

Thank you for signing up!

PHP Decode

eval(base64_decode('DQovKioNCiAqIENyZWF0ZWQgYnkgSW50ZWxsaUogSURFQS4NCiAqIFVzZXI6IG11bHRhem..

Decoded Output download


/**
 * Created by IntelliJ IDEA.
 * User: multazam
 * Date: 07/07/20
 * Time: 14:10
 */

class Cbtbanksoal extends CI_Controller {

	public function __construct(){
		parent::__construct();
		if (!$this->ion_auth->logged_in()){
			redirect('auth');
		}else if ( !$this->ion_auth->is_admin() && !$this->ion_auth->in_group('guru')){
			show_error('Hanya Administrator dan guru yang diberi hak untuk mengakses halaman ini, <a href="'.base_url('dashboard').'">Kembali ke menu awal</a>', 403, 'Akses Terlarang');
		}
		$this->load->library('upload');
		//$this->load->library('MY_Upload', 'my_upload');
		$this->load->library(['datatables', 'form_validation']);// Load Library Ignited-Datatables
		$this->form_validation->set_error_delimiters('','');

		$this->load->helper('my');// Load Library Ignited-Datatables
		$this->load->model('Master_model', 'master');
		$this->load->model('Dashboard_model', 'dashboard');
		$this->load->model('Cbt_model', 'cbt');
		$this->load->model('Log_model', 'logging');
		$this->load->model('Kelas_model', 'kelas');
		$this->load->model('Dropdown_model', 'dropdown');
	}

	public function output_json($data, $encode = true)
	{
		if($encode) $data = json_encode($data);
		$this->output->set_content_type('application/json')->set_output($data);
	}

	public function index() {
		$user = $this->ion_auth->user()->row();
		$setting = $this->dashboard->getSetting();
		$data = [
			'user' => $user,
			'judul'	=> 'Bank Soal',
			'subjudul'=> 'Soal',
			'setting'		=> $setting
		];

		$tp = $this->master->getTahunActive();
		$smt = $this->master->getSemesterActive();

		$data['tp'] = $this->dashboard->getTahun();
		$data['tp_active'] = $tp;
		$data['smt'] = $this->dashboard->getSemester();
		$data['smt_active'] = $smt;
        $data['levels'] = $this->dropdown->getAllLevel($setting->jenjang);
        $data['mapels'] = $this->dropdown->getAllMapel();

        $type = $this->input->get('type');
		if($this->ion_auth->is_admin()){
            $data['profile'] = $this->dashboard->getProfileAdmin($user->id);
			$data['gurus'] = $this->dropdown->getAllGuru();
            $data['kelas'] = $this->cbt->getKelas($tp->id_tp, $smt->id_smt);

            $data['filters'] = ['0'=>'Semua', '1'=>'Guru', '2'=>'Mapel', '3'=>'Level'];
            $data['id_filter'] = $type == null ? '' : $type;
            if ($type == '1') {
                $id_guru = $this->input->get('id');
                $data['id_guru'] = $id_guru;
                $data['banks'] = $this->cbt->getDataBank($id_guru);

                $data['id_mapel'] = '';
                $data['id_level'] = '';
            } elseif ($type == '2') {
                $id_mapel = $this->input->get('id');
                $data['id_mapel'] = $id_mapel;
                $data['banks'] = $this->cbt->getDataBank(null, $id_mapel);

                $data['id_guru'] = '';
                $data['id_level'] = '';
            } elseif ($type == '3') {
                $id_level = $this->input->get('id');
                $data['id_level'] = $id_level;
                $data['banks'] = $this->cbt->getDataBank(null, null, $id_level);

                $data['id_guru'] = '';
                $data['id_mapel'] = '';
            } else {
                $data['banks'] = $this->cbt->getDataBank();
                $data['id_guru'] = null;
                $data['id_mapel'] = null;
                $data['id_level'] = null;
            }

			$this->load->view('_templates/dashboard/_header', $data);
			$this->load->view('cbt/banksoal/data');
			$this->load->view('_templates/dashboard/_footer');
		}else{
			$guru = $this->dashboard->getDataGuruByUserId($user->id, $tp->id_tp, $smt->id_smt);
			$nguru[$guru->id_guru] = $guru->nama_guru;
			$data['guru'] = $guru;
            $data['gurus'] = $nguru;
            $data['kelas'] = $this->cbt->getKelas($tp->id_tp, $smt->id_smt);

            $data['filters'] = ['0'=>'Semua', '2'=>'Mapel', '3'=>'Level'];
            $data['id_filter'] = $type == null ? '' : $type;
            if ($type == '2') {
                $id_mapel = $this->input->get('id');
                $data['id_mapel'] = $id_mapel;
                $data['banks'] = $this->cbt->getDataBank($guru->id_guru, $id_mapel);

                $data['id_guru'] = '';
                $data['id_level'] = '';
            } elseif ($type == '3') {
                $id_level = $this->input->get('id');
                $data['id_level'] = $id_level;
                $data['banks'] = $this->cbt->getDataBank($guru->id_guru, null, $id_level);

                $data['id_guru'] = '';
                $data['id_mapel'] = '';
            } else {
                $data['id_guru'] = $guru->id_guru;
                $data['banks'] = $this->cbt->getDataBank($guru->id_guru);
                $data['id_mapel'] = '';
                $data['id_level'] = '';
            }

			$this->load->view('members/guru/templates/header', $data);
            $this->load->view('cbt/banksoal/data');
			$this->load->view('members/guru/templates/footer');
		}
	}

	public function data($guru=null) {
		$this->output_json($this->cbt->getDataBank($guru), false);
	}

    public function dataTable($guru=null) {
        $this->output_json($this->cbt->getDataTableBank($guru), false);
    }

    public function getMapelGuru() {
        $id_guru = $this->input->get('id_guru', true);

        $tp = $this->master->getTahunActive();
        $smt = $this->master->getSemesterActive();
        $mapel_guru = $this->kelas->getGuruMapelKelas($id_guru, $tp->id_tp, $smt->id_smt);
        $mapel = json_decode(json_encode(unserialize($mapel_guru->mapel_kelas)));

        $arrMapel = [];
        if ($mapel!=null){
            foreach ($mapel as $m) {
                $arrMapel[$m->id_mapel] = $m->nama_mapel;
            }
        }

        $this->output_json($arrMapel);
    }

	public function getKelasLevel() {
		$level = $this->input->get('level', true);
		$id_guru = $this->input->get('id_guru', true);
		$id_mapel = $this->input->get('mapel', true);

        $tp = $this->master->getTahunActive();
        $smt = $this->master->getSemesterActive();
		$mapel_guru = $this->kelas->getGuruMapelKelas($id_guru, $tp->id_tp, $smt->id_smt);
        $arrKelas = [];
        $arrMapel = [];
        $mapel = json_decode(json_encode(unserialize($mapel_guru->mapel_kelas)));

        foreach ($mapel as $m) {
            $arrMapel[$m->id_mapel] = $m->nama_mapel;
            if ($id_mapel===$m->id_mapel){
                foreach ($m->kelas_mapel as $kls) {
                    array_push($arrKelas, $kls->kelas);
                }
            }
        }

		$this->output_json(['mapel'=> $arrMapel, 'kelas'=>$this->cbt->getKelasByLevel($level, $arrKelas)]);
	}

	public function addBank() {
		$user = $this->ion_auth->user()->row();
        $setting = $this->dashboard->getSetting();
		$data = [
			'user'      => $user,
			'judul'	    => 'Bank Soal',
			'subjudul'  => 'Buat Bank Soal',
		];

		$tp = $this->master->getTahunActive();
		$smt = $this->master->getSemesterActive();

		$data['tp'] = $this->dashboard->getTahun();
		$data['tp_active'] = $tp;
		$data['smt'] = $this->dashboard->getSemester();
		$data['smt_active'] = $smt;

		$data['setting'] = $this->dashboard->getSetting();
		$data['bank'] = json_decode(json_encode($this->cbt->dummy($setting->jenjang)));
		$data['jenis'] = $this->cbt->getAllJenisUjian();
		$data['jurusan'] = $this->cbt->getAllJurusan();
		$data['level'] = $this->dropdown->getAllLevel($setting->jenjang);

		if($this->ion_auth->is_admin()){
            $data['profile'] = $this->dashboard->getProfileAdmin($user->id);
			$data['kelas'] = $this->dropdown->getAllKelas($tp->id_tp, $smt->id_smt);
			$data['id_guru'] = '';
			$data['gurus'] = $this->dropdown->getAllGuru();
			$data['mapel'] = $this->dropdown->getAllMapel();

			$this->load->view('_templates/dashboard/_header', $data);
			$this->load->view('cbt/banksoal/add');
			$this->load->view('_templates/dashboard/_footer');
		}else{
			$guru = $this->dashboard->getDataGuruByUserId($user->id, $tp->id_tp, $smt->id_smt);
			$nguru[$guru->id_guru] = $guru->nama_guru;
            $data['gurus'] = $nguru;
			$data['guru'] = $guru;
			$data['id_guru'] = $guru->id_guru;

			$mapel_guru = $this->kelas->getGuruMapelKelas($guru->id_guru, $tp->id_tp, $smt->id_smt);
			$mapel = json_decode(json_encode(unserialize($mapel_guru->mapel_kelas)));

			$arrMapel = [];
			$arrKelas = [];
			foreach ($mapel as $m) {
				$arrMapel[$m->id_mapel] = $m->nama_mapel;
				foreach ($m->kelas_mapel as $kls) {
					$arrKelas[$m->id_mapel][] = [
						'id_kelas'	=>	$kls->kelas,
						'nama_kelas'=>$this->dropdown->getNamaKelasById($tp->id_tp, $smt->id_smt, $kls->kelas)];
				}
			}

			$arrId = [];
			if (count($mapel) > 0) {
                foreach ($mapel[0]->kelas_mapel as $id_mapel) {
                    array_push($arrId, $id_mapel->kelas);
                }
            }

			$data['mapel_guru'] = $mapel_guru;
			$data['mapel'] = $arrMapel;
			$data['arrkelas'] = $arrKelas;
			$data['kelas'] = count($arrId) > 0 ? $this->dropdown->getAllKelasByArrayId($tp->id_tp, $smt->id_smt, $arrId) : [];

			$this->load->view('members/guru/templates/header', $data);
            $this->load->view('cbt/banksoal/add');
			$this->load->view('members/guru/templates/footer');
		}
	}

	public function editBank() {
		$id_bank = $this->input->get('id_bank', true);
		$id_guru = $this->input->get('id_guru', true);
        $setting = $this->dashboard->getSetting();

		$user = $this->ion_auth->user()->row();
		$data = [
			'user'      => $user,
			'judul'	    => 'Edit Bank Soal',
			'subjudul'  => 'Edit Bank Soal'
		];

		$tp = $this->master->getTahunActive();
		$smt = $this->master->getSemesterActive();

		$data['tp'] = $this->dashboard->getTahun();
		$data['tp_active'] = $tp;
		$data['smt'] = $this->dashboard->getSemester();
		$data['smt_active'] = $smt;
		$data['bulan'] = $this->dropdown->getBulan();

		$data['setting'] = $this->dashboard->getSetting();
		$data['jenis'] = $this->cbt->getAllJenisUjian();
		$data['jurusan'] = $this->cbt->getAllJurusan();
		$data['level'] = $this->dropdown->getAllLevel($setting->jenjang);
		$data['kelas'] = $this->dropdown->getAllKelas($tp->id_tp, $smt->id_smt);

		$data['bank'] = $this->cbt->getDataBankById($id_bank);

		if($this->ion_auth->is_admin()){
            $data['profile'] = $this->dashboard->getProfileAdmin($user->id);
			$data['id_guru'] = $id_guru;
			$data['gurus'] = $this->dropdown->getAllGuru();

			$arrMapel = [];
			$mapel_guru = $this->kelas->getGuruMapelKelas($id_guru, $tp->id_tp, $smt->id_smt);
			$mapel = $mapel_guru->mapel_kelas != null ? json_decode(json_encode(unserialize($mapel_guru->mapel_kelas))) : [];
			foreach ($mapel as $m) {
				$arrMapel[$m->id_mapel] = $m->nama_mapel;
			}
			$data['mapel'] = $arrMapel;
			$data['mapel_guru'] = $mapel_guru;
			$this->load->view('_templates/dashboard/_header', $data);
			$this->load->view('cbt/banksoal/add');
			$this->load->view('_templates/dashboard/_footer');
		}else{
			$guru = $this->dashboard->getDataGuruByUserId($user->id, $tp->id_tp, $smt->id_smt);
			$nguru[$guru->id_guru] = $guru->nama_guru;
			$mapel_guru = $this->kelas->getGuruMapelKelas($guru->id_guru, $tp->id_tp, $smt->id_smt);
			$mapel = json_decode(json_encode(unserialize($mapel_guru->mapel_kelas)));

			$arrMapel = [];
			foreach ($mapel as $m) {
				$arrMapel[$m->id_mapel] = $m->nama_mapel;
			}

            $data['gurus'] = $nguru;
			$data['mapel_guru'] = $mapel_guru;
			$data['guru'] = $guru;
			$data['id_guru'] = $guru->id_guru;
			$data['mapel'] = $arrMapel;

			$this->load->view('members/guru/templates/header', $data);
            $this->load->view('cbt/banksoal/add');
			//$this->load->view('members/guru/cbt/banksoal/add');
			$this->load->view('members/guru/templates/footer');
		}
	}

	public function saveBank() {
		if ($this->input->post()) {
            $tp = $this->master->getTahunActive();
            $smt = $this->master->getSemesterActive();

			$this->cbt->saveBankSoal($tp->id_tp, $smt->id_smt);
			$status = TRUE;
		} else {
			$status = FALSE;
		}
		$data['status'] = $status;

		$id = $this->input->post('id_bank', true);
		if (!$id) {
			$this->logging->saveLog(3, 'menambah bank soal');
		} else {
			$this->logging->saveLog(4, 'mengedit bank soal');
		}

		$this->output_json($data);
	}

	public function deleteBank() {
		$id = $this->input->get('id_bank', true);
		if ($this->cbt->cekJadwalBankSoal($id)>0) {
			$this->output_json(['status' => false, 'message' => 'Ada jadwal ujian yang menggunakan bank soal ini']);
		} else {
			if ($this->master->delete('cbt_soal', $id, 'bank_id')) {
                //if ($this->master->delete('cbt_soal_siswa', $id, 'id_bank')) {}
				if ($this->master->delete('cbt_bank_soal', $id, 'id_bank')) {
                    $this->logging->saveLog(5, 'menghapus bank soal');
                    $this->output_json(['status' => true, 'message' => 'berhasil' ]);
				}
			}
		}
	}

    public function detail($id) {
        $user = $this->ion_auth->user()->row();
        $data = [
            'user'      => $user,
            'judul'	    => 'Detail Soal',
            'subjudul'  => 'Detail Soal'
        ];
        $data['setting'] = $this->dashboard->getSetting();

        $tp = $this->master->getTahunActive();
        $smt = $this->master->getSemesterActive();

        $data['tp'] = $this->dashboard->getTahun();
        $data['tp_active'] = $tp;
        $data['smt'] = $this->dashboard->getSemester();
        $data['smt_active'] = $smt;
        $data['bank'] = $this->cbt->getDataBankById($id);
        $data['soals'] = $this->cbt->getAllSoalByBank($id);
        $data['kelas'] = $this->cbt->getKelas($tp->id_tp, $smt->id_smt);
        if($this->ion_auth->is_admin()){
            $data['profile'] = $this->dashboard->getProfileAdmin($user->id);

            $this->load->view('_templates/dashboard/_header', $data);
            $this->load->view('cbt/banksoal/detail');
            $this->load->view('_templates/dashboard/_footer');
        }else{
            $data['guru'] = $this->dashboard->getDataGuruByUserId($user->id, $tp->id_tp, $smt->id_smt);

            $this->load->view('members/guru/templates/header', $data);
            $this->load->view('cbt/banksoal/detail');
            $this->load->view('members/guru/templates/footer');
        }
    }

    public function saveSelected() {
        $bank_id = $this->input->post('id_bank', true);
        $jenis = $this->input->post('jenis', true);
        $soal = count($this->input->post('soal', true));
        $unchek = json_decode($this->input->post('uncheck', true));
        $arrId = [];
        for ($i = 0; $i <= $soal; $i++) {
            $id = $this->input->post('soal['.$i.']', true);
            if ($id!=null) array_push($arrId, $id);
        }

        $updated = 0;
        foreach ($arrId as $id) {
            $this->db->set('tampilkan', 1);
            $this->db->where('id_soal', $id);
            $this->db->update('cbt_soal');
            $updated ++;
        }

        foreach ($unchek as $id) {
            $this->db->set('tampilkan', 0);
            $this->db->where('id_soal', $id);
            $this->db->update('cbt_soal');
        }

        sleep(1);
        $bank = $this->cbt->getDataBankById($bank_id);
        $soals = $this->cbt->getAllSoalByBank($bank_id);

        $total_soal_tampil = isset(array_count_values(array_column($soals, 'tampilkan'))['1']) ? array_count_values(array_column($soals, 'tampilkan'))['1'] : 0;
        $total_soal_seharusnya_tampil = $bank->tampil_pg + $bank->tampil_kompleks + $bank->tampil_jodohkan + $bank->tampil_isian + $bank->tampil_esai;
        $tampil_kurang = $total_soal_tampil < $total_soal_seharusnya_tampil;
        $status_soal = $tampil_kurang ? '0' : '1';

        $this->db->set('status_soal', $status_soal);
        $this->db->where('id_bank', $bank_id);
        $this->db->update('cbt_bank_soal');

        $data['check'] = $updated;
        $this->output_json($data);
    }

    public function copyBankSoal($id_bank) {
        $tp = $this->dashboard->getTahunActive();
        $smt = $this->dashboard->getSemesterActive();
        $bank = $this->cbt->getDataBankById($id_bank);
        $soals = $this->cbt->getAllSoalByBank($id_bank);

        $data = [
            'id_tp'             => $tp->id_tp,
            'id_smt'            =>$smt->id_smt,
            'bank_jenis_id'     => $bank->bank_jenis_id,
            'bank_kode'         =>$bank->bank_kode,
            'bank_level'        => $bank->bank_level,
            'bank_kelas'        => $bank->bank_kelas,
            'bank_mapel_id'     => $bank->bank_mapel_id,
            'bank_jurusan_id'   => $bank->bank_jurusan_id,
            'bank_guru_id'      => $bank->bank_guru_id,
            'bank_nama'         => $bank->bank_nama,
            'kkm'               => $bank->kkm,
            'deskripsi'         => $bank->deskripsi,
            'jml_soal'          => $bank->jml_soal,
            'tampil_pg'         => $bank->tampil_pg,
            'bobot_pg'          => $bank->bobot_pg,
            'jml_kompleks'      => $bank->jml_kompleks,
            'tampil_kompleks'   => $bank->tampil_kompleks,
            'bobot_kompleks'    => $bank->bobot_kompleks,
            'jml_jodohkan'      => $bank->jml_jodohkan,
            'tampil_jodohkan'   => $bank->tampil_jodohkan,
            'bobot_jodohkan'    => $bank->bobot_jodohkan,
            'jml_isian'         => $bank->jml_isian,
            'tampil_isian'      => $bank->tampil_isian,
            'bobot_isian'       => $bank->bobot_isian,
            'jml_esai'          => $bank->jml_esai,
            'tampil_esai'       => $bank->tampil_esai,
            'bobot_esai'        => $bank->bobot_esai,
            'opsi'              => $bank->opsi,
            'date'              => date('Y-m-d H:i:s'),
            'status'            => $bank->status,
            'soal_agama'        => $bank->soal_agama
        ];

        $result = $this->master->create('cbt_bank_soal', $data);
        $id = $this->db->insert_id();
        foreach ($soals as $soal) {
            unset($soal->id_soal);
            $soal->bank_id = $id;
            $soal->created_on = time();
            $soal->updated_on = time();
        }
        $this->db->insert_batch('cbt_soal', $soals);

        //$result['status'] = 'Materi berhasil dibuat';
        $this->logging->saveLog(3, 'membuat bank soal');

        $this->output_json($result);
    }

	public function buatsoal($id_bank) {
		//$id = $this->input->post('id_bank', true);
		$user = $this->ion_auth->user()->row();
		$data = [
			'user'      => $user,
			'judul'	    => 'Buat Soal',
			'subjudul'  => 'Buat Soal'
		];

		$tp = $this->master->getTahunActive();
		$smt = $this->master->getSemesterActive();

		$data['tp'] = $this->dashboard->getTahun();
		$data['tp_active'] = $tp;
		$data['smt'] = $this->dashboard->getSemester();
		$data['smt_active'] = $smt;

		$setting = $this->dashboard->getSetting();
        $data['setting'] = $setting;

        $tab = $this->input->get('tab', true);
        $jenis = $tab == null ? "1" : $tab;
        $data['tab_active'] = $jenis;
        $bank = $this->cbt->getDataBankById($id_bank);

        $data['soal'] = null;//$this->cbt->getSoalByIdBank($id_bank, $jenis);
		$data['soal_ada'] = $this->cbt->cekSoalAda($id_bank, $jenis);
        $data['soal_belum_komplit'] = $this->cbt->cekSoalBelumKomplit($id_bank, $jenis, $setting->jenjang);

        //$total_pg = $bank->jml_soal;
        //$jml_soal_pg = $this->cbt->getTotalSoal($id_bank, 1);
        if ($jenis == "1") $data['jml_pg'] = $this->cbt->getNomorSoalTerbesar($id_bank, 1);
        elseif ($jenis == "2") $data['jml_pg2'] = $this->cbt->getNomorSoalTerbesar($id_bank, 2);
        elseif ($jenis == "3") $data['jml_jodohkan'] = $this->cbt->getNomorSoalTerbesar($id_bank, 3);
        elseif ($jenis == "4") $data['jml_isian'] = $this->cbt->getNomorSoalTerbesar($id_bank, 4);
        elseif ($jenis == "5") $data['jml_essai'] = $this->cbt->getNomorSoalTerbesar($id_bank, 5);
        //$data['jml_total'] = $this->cbt->getTotalSoal($id_bank);
        $data['bank'] = $bank;

        $data['soals'] = $this->cbt->getAllSoalByBank($id_bank, $jenis);
		$data['jurusan'] = $this->cbt->getAllJurusan();
		$data['level'] = $this->dropdown->getAllLevel($setting->jenjang);
		$data['kelas'] = $this->dropdown->getAllKelas($tp->id_tp, $smt->id_smt);

		if($this->ion_auth->is_admin()){
            $data['profile'] = $this->dashboard->getProfileAdmin($user->id);

			$this->load->view('_templates/dashboard/_header', $data);
			$this->load->view('cbt/banksoal/soal');
			$this->load->view('_templates/dashboard/_footer');
		} else {
            $data['guru'] = $this->dashboard->getDataGuruByUserId($user->id, $tp->id_tp, $smt->id_smt);

			$this->load->view('members/guru/templates/header', $data);
            $this->load->view('cbt/banksoal/soal');
			$this->load->view('members/guru/templates/footer');
		}
	}

    public function getSoalByNomor() {
        $bank_id = $this->input->get('bank_id', true);
        $nomor = $this->input->get('nomor', true);
        $jenis = $this->input->get('jenis', true);
        $soal = $this->cbt->getSoalByNomor($bank_id, $nomor, $jenis);
        $data = $soal;
        if ($data != null) {
            $data->file = unserialize($soal->file);
            if ($jenis == '2') {
                $t = @unserialize($soal->opsi_a);
                if ($t !== false) $data->opsi_a = $t;
                else ($data->opsi_a = false);

                $j = @unserialize($soal->jawaban);
                if ($j !== false) $data->jawaban = $j;
                else ($data->jawaban = false);
            } elseif ($jenis == '3') {
                $j = @unserialize($soal->jawaban);
                if ($j !== false) $data->jawaban = $j;
                else ($data->jawaban = false);
            }
        }
        $this->output_json($data);
    }

    public function tambahSoal(){
        $bank = $this->input->post('bank', true);
        $nomor = $this->input->post('nomor', true);
        $jenis = $this->input->post('jenis', true);

        $data = [
            'bank_id'		=> $bank,
            'nomor_soal'	=> $nomor,
            'jenis'			=> $jenis,
            'tampilkan'		=> 0,
            'created_on'	=> time(),
            'updated_on'	=> time()
        ];

        $insert = $this->db->insert('cbt_soal', $data);
        $this->output_json($insert);
    }

	public function importsoal($id) {
		$user = $this->ion_auth->user()->row();
        $setting = $this->dashboard->getSetting();
		$data = [
			'user'      => $user,
			'judul'	    => 'Import Bank Soal',
			'subjudul'  => 'Import Bank Soal'
		];

		$tp = $this->master->getTahunActive();
		$smt = $this->master->getSemesterActive();

		$data['tp'] = $this->dashboard->getTahun();
		$data['tp_active'] = $tp;
		$data['smt'] = $this->dashboard->getSemester();
		$data['smt_active'] = $smt;

		$data['setting'] = $setting;
		$data['bank'] = $this->cbt->getDataBankById($id);
		$data['jenis'] = $this->cbt->getAllJenisUjian();
		$data['jurusan'] = $this->cbt->getAllJurusan();
		$data['level'] = $this->dropdown->getAllLevel($setting->jenjang);
		$data['kelas'] = $this->dropdown->getAllKelas($tp->id_tp, $smt->id_smt);

		if($this->ion_auth->is_admin()){
            $data['profile'] = $this->dashboard->getProfileAdmin($user->id);

			$this->load->view('_templates/dashboard/_header', $data);
			$this->load->view('cbt/banksoal/import');
			$this->load->view('_templates/dashboard/_footer');
		}else{
            $data['guru'] = $this->dashboard->getDataGuruByUserId($user->id, $tp->id_tp, $smt->id_smt);

			$this->load->view('members/guru/templates/header', $data);
            $this->load->view('cbt/banksoal/import');
			$this->load->view('members/guru/templates/footer');
		}
	}

	public function previewExcel() {
		$config['upload_path']		= './uploads/import/';
		$config['allowed_types']	= 'xls|xlsx|csv';
		$config['max_size']			= 2048;
		$config['encrypt_name']		= true;

		$this->load->library('upload', $config);

		if (!$this->upload->do_upload('upload_file')) {
			$error = $this->upload->display_errors();
			echo $error;
			die;
		} else {
			$file = $this->upload->data('full_path');
			$ext = $this->upload->data('file_ext');

			switch ($ext) {
				case '.xlsx':
					$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
					break;
				case '.xls':
					$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
					break;
				case '.csv':
					$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
					break;
				default:
					echo "unknown file ext";
					die;
			}

			$spreadsheet = $reader->load($file);
			$sheetData = $spreadsheet->getActiveSheet()->toArray();
			$data = [];
			for ($i = 1; $i < count($sheetData); $i++) {
				if ($sheetData[$i][0] != null) {
					$data[] = [
						'nama' => $sheetData[$i][1],
						'nip' => $sheetData[$i][2],
						'kode' => $sheetData[$i][3],
						'username' => $sheetData[$i][4],
						'password' => $sheetData[$i][5],
					];
					//$jurusan[] = $sheetData[$i][0];
				}
			}

			unlink($file);
			echo json_encode($data);
		}
	}

	public function previewWord($id_bank) {
		$config['upload_path']		= './uploads/import';
		$config['allowed_types']	= 'docx';
		$config['max_size']			= 2048;
		$config['encrypt_name']		= true;

		//$this->load->library('upload', $config);
		$this->upload->initialize($config);

		if (!$this->upload->do_upload('upload_file')) {
			$error = $this->upload->display_errors();
			echo $error;
			die;
		} else {
			$file = $this->upload->data('full_path');
			$phpWord = \PhpOffice\PhpWord\IOFactory::load($file);
			$htmlWriter = new \PhpOffice\PhpWord\Writer\HTML($phpWord);
			try {
				$htmlWriter->save('./uploads/temp/doc.html');
				//$htmlWriter->save("php://output");
			} catch (\PhpOffice\PhpWord\Exception\Exception $e) {
			}

			unlink($file);
			$text = file_get_contents('./uploads/temp/doc.html');

			$dom = new DOMDocument();
            $dom->preserveWhiteSpace = false;
            $dom->formatOutput = true;
			$dom->loadHTML($text);

			$images = $dom->getElementsByTagName('img');
			$numimg = 1;
			foreach ($images as $image) {
				$base64_image_string = $image->getAttribute('src');
				//echo $image->getAttribute('src') . "
";

				//usage:  if( substr( $img_src, 0, 5 ) === "data:" ) {  $filename=save_base64_image($base64_image_string, $output_file_without_extentnion, getcwd() . "/application/assets/pins/$user_id/"); }
				//data is like:    data:image/png;base64,asdfasdfasdf
				$splited = explode(',', substr( $base64_image_string , 5 ) , 2);
				$mime=$splited[0];
				$data=$splited[1];

				$mime_split_without_base64=explode(';', $mime,2);
				$mime_split=explode('/', $mime_split_without_base64[0],2);
				if(count($mime_split)==2)
				{
					$extension=$mime_split[1];
					if($extension=='jpeg')$extension='jpg';
					$output_file = 'img_'.$id_bank.$numimg.'.'.$extension;
				}
				file_put_contents( './uploads/bank_soal/' . $output_file, base64_decode($data) );
				$image->setAttribute('src', 'uploads/bank_soal/' . $output_file);
				$numimg ++;
				//return $output_file_with_extension;
			}

			$newhtml = $dom->saveHTML();
			/*
			$dom->loadHTML($newhtml);
			$data = [];
			$tables = $dom->getElementsByTagName('table');
            $arrJenis = ['1', '2', '3', '4', '5'];
            $UPPERCASE_LETTERS = range(chr(65),chr(90));
            $LOWERCASE_LETTERS = range(chr(97),chr(122));
            $NUMBERS_ZERO_THROUGH_NINE = range(chr(48),chr(57));


            for ($t=0;$t<$tables->count(); $t++) {
                $rows = $tables->item(0)->getElementsByTagName('tr');
                $nop = 1;
                for ($i = 1; $i < $rows->count(); $i++) {
                    $cols = $rows[$i]->getElementsByTagName('td');

                    $nomor = trim($cols->item(0)->nodeValue);
                    $nomor_kosong = (int)$nomor === 0;

                    $gambar = $cols->item(1)->getElementsByTagName('img');
                    $soal_gambar = $gambar->count() > 0;
                    $sSoal = trim($cols->item(1)->nodeValue);
                    $soal_kosong = !$soal_gambar && strlen($sSoal) < 3;

                    $jenis = trim($cols->item(2)->nodeValue);
                    $jenis_kosong = !in_array($jenis, $arrJenis);

                    $opsi = trim($cols->item(3)->nodeValue);
                    $opsi_kosong = !in_array($opsi, $UPPERCASE_LETTERS);

                    $jgambar = $cols->item(4)->getElementsByTagName('img');
                    $jwb_gambar = $gambar->count() > 0;
                    $jwbn = trim($cols->item(4)->nodeValue);
                    $jwbn_kosong = !$jwb_gambar && $jwbn === "";

                    $kunci = strtolower(trim($cols->item(5)->nodeValue));
                    $kunci_kosong = $kunci !== 'v';

                    $data[] = [
                        'nomor_soal' => $nop,
                        'soal'       => trim($this->innerXML($cols->item(1))),
                        'jenis'		 => trim($cols->item(2)->nodeValue),
                        'opsi'       => trim($cols->item(3)->nodeValue),
                        'jawaban'  => trim($cols->item(4)->nodeValue),//$dom->saveXML($cols->item(4), LIBXML_NOEMPTYTAG),
                        'kunci'    => $kunci,

                        'utf8_jenis' => mb_convert_encoding(trim($cols->item(2)->nodeValue), 'UTF-8', 'UTF-8'),
                        'soal_gambar' => $soal_gambar,
                        'soal_kosong' => $soal_kosong,
                        'opsi_kosong' => $opsi_kosong,
                        'kunci_kosong' => $kunci_kosong,
                        'jwbn_kosong' => $jwbn_kosong,
                    ];
                    $nop ++;
                }
            }
            /*
            $rows = $tables->item(0)->getElementsByTagName('tr');

            $nop = 1;
            for ($i = 1; $i < $rows->count(); $i++) {
                $cols = $rows[$i]->getElementsByTagName('td');
                $data[] = [
                    'jenis'		=> '1',
                    'nomor_soal'=> $nop,
                    'soal'       => trim($this->innerXML($cols->item(1))),
                    'jawaban_a'  => trim($this->innerXML($cols->item(2))),
                    'jawaban_b'  => trim($this->innerXML($cols->item(3))),
                    'jawaban_c'  => trim($this->innerXML($cols->item(4))),
                    'jawaban_d'  => trim($this->innerXML($cols->item(5))),
                    'jawaban_e'  => trim($this->innerXML($cols->item(6))),
                    'jawaban'  	 => trim($cols->item(7)->nodeValue)
                ];
                $nop ++;
            }

            if ($tables->item(1) !=null) {
                $rowsEssai = $tables->item(1)->getElementsByTagName('tr');
                $noe = 1;
                for ($j = 1; $j < $rowsEssai->count(); $j++) {
                    $cols = $rowsEssai[$j]->getElementsByTagName('td');
                    $data[] = [
                        'jenis'		=> '2',
                        'nomor_soal'=> $noe,
                        'soal'       => $this->innerXML($cols->item(1)),
                        'jawaban_a'  => '',
                        'jawaban_b'  => '',
                        'jawaban_c'  => '',
                        'jawaban_d'  => '',
                        'jawaban_e'  => '',
                        'jawaban'  => $this->innerXML($cols->item(2))
                    ];
                    $noe ++;
                }
            }
            //echo json_encode(array('pg' => $data));
            */
            $dataInsert = json_decode(json_encode($newhtml));
            //$json = json_decode(json_encode($data));
            $result['pg'] = $dataInsert;
            //$result['json'] = $json;
            $result['type'] = 'html';
		}

		/*
		// INSERT
        $bank = $this->cbt->getDataBankById($id_bank);
        $soal_ada = $this->cbt->cekSoalAda($id_bank);
        if (count($soal_ada) > 0) {
            $this->db->where('bank_id', $id_bank);
            $this->db->delete('cbt_soal');
        }

        $data = [];
        foreach ($dataInsert as $pg) {
            if ($pg->jenis == 1) {
                $tampilkan = $pg->nomor_soal > $bank->jml_soal ? 0 : 1;
            } else {
                $tampilkan = $pg->nomor_soal > $bank->jml_esai ? 0 : 1;
            }

            $data[] = [
                'bank_id'		=> $id_bank,
                'nomor_soal'	=> $pg->nomor_soal,
                'jenis'			=> $pg->jenis,
                'soal'			=> $pg->soal,
                'opsi_a'		=> $pg->jawaban_a,
                'opsi_b'		=> $pg->jawaban_b,
                'opsi_c'		=> $pg->jawaban_c,
                'opsi_d'		=> $pg->jawaban_d,
                'opsi_e'		=> $pg->jawaban_e,
                'jawaban'		=> $pg->jawaban,
                'tampilkan'		=> $tampilkan,
                'created_on'	=> time(),
                'updated_on'	=> time()
            ];
        }

        $save = $this->master->create('cbt_soal', $data, true);
        $this->logging->saveLog(3, 'mengimport bank soal');
        $result['data'] = $save;
		*/

        $this->output_json($result);
    }

    /**
     * @throws Exception
     */
    public function import(){
		$bank_id = $this->input->post('bank_id', true);
        $bank = $this->cbt->getDataBankById($bank_id);

        $input = $this->input->post('ganda');
        $str = preg_replace("",'',$input);
        $obj = json_decode($str);

        $json = json_decode( preg_replace('/[--]/', '', $input), true );
        $result['error'] = json_last_error_msg();

        $soal = json_decode(json_encode($json));
        $result['soal'] = $obj;
        /*
        $this->db->where('bank_id', $bank_id);
		if ($this->db->delete('cbt_soal', $bank_id)) {
			$data = [];
			foreach ($soal as $pg) {
			    if ($pg->jenis == 1) {
                    $tampilkan = $pg->nomor_soal > $bank->jml_soal ? 0 : 1;
                } else {
                    $tampilkan = $pg->nomor_soal > $bank->jml_esai ? 0 : 1;
                }

				$data[] = [
					'bank_id'		=> $bank_id,
					'nomor_soal'	=> $pg->nomor_soal,
					'jenis'			=> $pg->jenis,
					'soal'			=> $pg->soal,
					'opsi_a'		=> $pg->jawaban_a,
					'opsi_b'		=> $pg->jawaban_b,
					'opsi_c'		=> $pg->jawaban_c,
					'opsi_d'		=> $pg->jawaban_d,
					'opsi_e'		=> $pg->jawaban_e,
					'jawaban'		=> $pg->jawaban,
                    'tampilkan'		=> $tampilkan,
					'created_on'	=> time(),
					'updated_on'	=> time()
				];
			}

			$save = $this->master->create('cbt_soal', $data, true);
			$this->logging->saveLog(3, 'mengimport bank soal');
			$result['data'] = $save;
			//$this->output_json($save);
			//$this->output->set_content_type('application/json')->set_output($save);
		} else {
            $result['data'] = '0';
		}*/

        $this->output_json($result);
	}

	public function export($bank_id) {
        $bank = $this->cbt->getDataBankById($bank_id);

        $soal[] = json_decode(json_encode(['soal'=>'','opsi_a'=>'','opsi_b'=>'','opsi_c'=>'','opsi_d'=>'','opsi_e'=>'','jawaban'=>'']));
        $list = $this->cbt->getAllSoalByBank($bank_id, '1');
        $soals = array_merge($soal, $list);

        $ess[] = json_decode(json_encode(['soal'=>'','jawaban'=>'']));
        $listEss = $this->cbt->getAllSoalByBank($bank_id, '2');
        $essai = array_merge($ess, $listEss);

        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $section = $phpWord->addSection();
        $header = array('size' => 10, 'bold' => true);
        $arrHeader = ['', 'NO', 'SOAL', 'JAWABAN A', 'JAWABAN B', 'JAWABAN C', 'JAWABAN D', 'JAWABAN E', 'JAWABAN BENAR',];

        $cols = 8;
        $section->addText('I. PILIHAN GANDA', $header);

        $tableStyle = array('borderSize' => 6, 'borderColor' => '000000');
        $phpWord->addTableStyle('tab style', $tableStyle);
        $table = $section->addTable('tab style');

        for ($r = 1; $r <= count($soals); $r++) {
            $soal = $soals[$r-(1)];
            $arrVal = ['', '',
                isset($soal) ? $soal->soal : '',
                isset($soal) ? $soal->opsi_a : '',
                isset($soal) ? $soal->opsi_b : '',
                isset($soal) ? $soal->opsi_c : '',
                isset($soal) ? $soal->opsi_d : '',
                isset($soal) ? $soal->opsi_e : '',
                isset($soal) ? $soal->jawaban : '',
            ];

            $table->addRow();
            for ($c = 1; $c <= $cols; $c++) {
                $width = 4000;
                $align = array(
                    'align' => 'left',
                    'space' => array('before' => 50, 'after' => 50),
                    'indentation' => array('left' => 100, 'right' => 100));
                if ($c == 1) {
                    $align = array(
                        'align' => 'center',
                        'space' => array('before' => 50, 'after' => 50),
                        'indentation' => array('left' => 100, 'right' => 100));
                    $width = 500;
                } elseif ($c==2) {
                    $width = 8000;
                }

                $fontStyle = array('size' => 10, 'bold' => false);
                $no = $r-1;

                if ($r==1){
                    $no = "NO";
                    $align = array(
                        'align' => 'center',
                        'space' => array('before' => 50, 'after' => 50),
                        'indentation' => array('left' => 50, 'right' => 50));
                    $fontStyle = array('size' => 10, 'bold' => true);
                }

                if ($r == 1) {
                    if ($c == 1 ) {
                        $table->addCell($width)->addText($no, $fontStyle, $align);
                    } else {
                        $table->addCell($width)->addText($arrHeader[$c], $fontStyle, $align);
                    }
                } else {
                    if ($c == 1 ) {
                        $table->addCell($width)->addText($no, $fontStyle, $align);
                    } else {
                        $tagRemoved = strip_tags($arrVal[$c]);
                        $html = htmlspecialchars($tagRemoved);
                        $table->addCell($width)->addText($this->cleanString($html), $fontStyle, $align);
                        //$table->addCell($width)->addText(htmlspecialchars(strip_tags($arrVal[$c])), $fontStyle, $align);
                    }
                }
            }
        }

        $section->addPageBreak();
        $section->addText('II. ESSAI', $header);
        $arrHeader = ['', 'NO', 'SOAL', 'JAWABAN',];
        $cols = 3;
        $phpWord->addTableStyle('tab style', $tableStyle);
        $table = $section->addTable('tab style');

        for ($r = 1; $r <= count($essai); $r++) {
            $soal = $essai[$r-(1)];
            $arrVal = ['', '',
                isset($soal) ? $soal->soal : '',
                isset($soal) ? $soal->jawaban : '',
            ];

            $table->addRow();
            for ($c = 1; $c <= $cols; $c++) {
                $width = 4000;
                $align = array(
                    'align' => 'left',
                    'space' => array('before' => 50, 'after' => 50),
                    'indentation' => array('left' => 100, 'right' => 100));
                if ($c == 1) {
                    $align = array(
                        'align' => 'center',
                        'space' => array('before' => 50, 'after' => 50),
                        'indentation' => array('left' => 100, 'right' => 100));
                    $width = 500;
                } elseif ($c==2) {
                    $width = 8000;
                }

                $fontStyle = array('size' => 10, 'bold' => false);
                $no = $r-1;

                if ($r==1){
                    $no = "NO";
                    $align = array(
                        'align' => 'center',
                        'space' => array('before' => 50, 'after' => 50),
                        'indentation' => array('left' => 50, 'right' => 50));
                    $fontStyle = array('size' => 10, 'bold' => true);
                }

                if ($r == 1) {
                    if ($c == 1 ) {
                        $table->addCell($width)->addText($no, $fontStyle, $align);
                    } else {
                        $table->addCell($width)->addText($arrHeader[$c], $fontStyle, $align);
                    }
                } else {
                    if ($c == 1 ) {
                        $table->addCell($width)->addText($no, $fontStyle, $align);
                    } else {
                        $tagRemoved = strip_tags($arrVal[$c]);
                        $html = htmlspecialchars($tagRemoved);
                        $table->addCell($width)->addText($this->cleanString($html), $fontStyle, $align);
                    }
                }
            }
        }

        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        header("Content-Disposition: attachment; filename=Soal ".$bank->nama_mapel.".docx");
        $objWriter->save('php://output');
    }

    public function getSoalSiswa($id_bank) {
        $soals = $this->cbt->getAllSoalByBank($id_bank);
        foreach ($soals as $soal) {
            $soal->file = unserialize($soal->file);
            if ($soal->jenis == '2') {
                $soal->jawaban = unserialize($soal->jawaban);
                $soal->opsi_a = unserialize($soal->opsi_a);
            } elseif ($soal->jenis == '3') {
                $soal->jawaban = unserialize($soal->jawaban);
            }
        }
        $data['soal'] = $soals;
        $this->output_json($data);
    }

	function innerXML($node) {
		$doc  = $node->ownerDocument;
		$frag = $doc->createDocumentFragment();
		foreach ($node->childNodes as $child) {
			$frag->appendChild($child->cloneNode(TRUE));
		}
		return $doc->saveXML($frag);
	}

	public function file_config() {
		$allowed_type 	= [
			"image/jpeg", "image/jpg", "image/png", "image/gif",
			"audio/mpeg", "audio/mpg", "audio/mpeg3", "audio/mp3", "audio/x-wav", "audio/wave", "audio/wav",
			"video/mp4", "application/octet-stream"
		];
		$config['upload_path']      = FCPATH.'uploads/bank_soal/';
		$config['allowed_types']    = 'jpeg|jpg|png|gif|mpeg|mpg|mpeg3|mp3|wav|wave|mp4';
		$config['encrypt_name']     = TRUE;

		return $this->load->library('upload', $config);
	}

	public function validasi($jenis) {
		$this->form_validation->set_rules('soal', 'Soal', 'required');
		if ($jenis==1) {
            $this->form_validation->set_rules('jawaban_pg', 'Kunci Jawaban', 'required');
        } elseif ($jenis==2) {
            $this->form_validation->set_rules('jawaban2_a', 'Kunci Jawaban', 'required');
            $this->form_validation->set_rules('jawaban_benar_pg2[]', 'Kunci Jawaban', 'required');
        } elseif ($jenis==3) {
            $this->form_validation->set_rules('jawaban_jodohkan', 'Kunci Jawaban', 'required');
        } elseif ($jenis==4) {
            $this->form_validation->set_rules('jawaban_isian', 'Kunci Jawaban', 'required');
		} else {
			$this->form_validation->set_rules('jawaban_essai', 'Kunci Jawaban', 'required');
		}
	}

	public function saveSoal() {
		$method = $this->input->post('method', true);
		$jenis = $this->input->post('jenis', true);

		$this->validasi($jenis);
		$this->file_config();

        $data = [
            'bank_id'       => $this->input->post('bank_id', true),
            'jenis'         => $jenis,
            'nomor_soal'    => $this->input->post('nomor_soal', true),
            'soal'          => $this->input->post('soal', false)
        ];

        if ($jenis==1) {
            $abjad = ['a', 'b', 'c', 'd', 'e'];
            foreach ($abjad as $abj) {
                $data['opsi_'.$abj] = $this->input->post('jawaban_'.$abj, false);
            }
            $data['jawaban'] = $this->input->post('jawaban_pg', true);
        } elseif ($jenis == 2) {
            $opsis = [];
            for ($i=97; $i<117; $i++) {
                $op = $this->input->post('jawaban2_'. chr($i), false);
                if ($op != null) {
                    //array_push($opsis, $op);
                    $opsis[chr($i)] = $op;
                }
            }
            $data['opsi_a'] = serialize($opsis);

            $jawabans = [];
            $jwb_pg2 = count($this->input->post('jawaban_benar_pg2', true));
            for ($i = 0; $i <= $jwb_pg2; $i++) {
                $jwb = $this->input->post('jawaban_benar_pg2['.$i.']', true);
                //if ($id!=null) array_push($arrId, $id);
                array_push($jawabans, $jwb);
            }
            $data['jawaban'] = serialize($jawabans);
        } elseif ($jenis == 3) {
            $jwb_jodohkan = [
                'model' => $this->input->post('model', true),
                'type' => $this->input->post('type', true),
                'jawaban' => json_decode($this->input->post('jawaban_jodohkan', true))
            ];
            $data['jawaban'] = serialize($jwb_jodohkan);
        } elseif ($jenis == 4) {
            $data['jawaban'] = $this->input->post('jawaban_isian', true);
		} else {
            $data['jawaban'] = $this->input->post('jawaban_essai', true);
		}

		if ($this->form_validation->run() === FALSE){
			$result['status'] = 'error';
		} else {
			if($method==='add'){
				$data['created_on'] = time();
				$data['updated_on'] = time();
				$this->master->create('cbt_soal', $data);
				$result['status'] = 'Soal berhasil dibuat';
				$this->logging->saveLog(3, 'membuat soal');
			} else if ($method==='edit'){
				$id_soal = $this->input->post('soal_id', true);
				$data['updated_on'] = time();
				$this->master->update('cbt_soal', $data, 'id_soal', $id_soal);
				$result['status'] = 'Soal berhasil diupdate';
				$this->logging->saveLog(4, 'mengedit soal');
			} else {
				$result['status'] = '400 Method not found';
			}
		}
		$this->output_json($result);
	}

    public function hapusSoal() {
        $id_soal = $this->input->post('soal_id', true);
        if ($this->db->delete('cbt_soal', 'id_soal='.$id_soal)){
            $result['status'] = 'Soal berhasil dihapus';
        } else {
            $result['status'] = '400 Method not found';
        }
        $this->output_json($result);
    }

    function uploadFile(){
        $id_soal = $this->input->get('id_soal', true);
        $soal = $this->cbt->getSoalById($id_soal);
        $files = $soal == null || $soal->file == null ? [] : unserialize($soal->file);

        if(isset($_FILES["file_uploads"]["name"])){
            $nama_file_asal = $_FILES["file_uploads"]["name"];
            $kode_file = $id_soal.'_'.time();

            $config['upload_path'] = './uploads/bank_soal/';
            $config['allowed_types'] = 'mpeg|mpg|mpeg3|mp3|wav|wave|mp4|avi';
            $config['file_name'] = $kode_file;

            //$config['encrypt_name'] = TRUE;
            //$config['max_size'] = '0';
            //$config['overwrite'] = FALSE;
            $this->upload->initialize($config);
            if(!$this->upload->do_upload('file_uploads')){
                $data['status'] = false;
                $src = '';
                $filename = '';
                $data['src'] = $this->upload->display_errors();
            }else{
                $file = $this->upload->data();
                /*
                $config['image_library']='gd2';
                $config['source_image']='./uploads/bank_soal/'.$file['file_name'];
                $config['create_thumb']= FALSE;
                $config['maintain_ratio']= TRUE;
                $config['quality']= '60%';
                $config['width']= 800;
                $config['height']= 800;
                $config['new_image']= './uploads/bank_soal/'.$file['file_name'];
                $this->load->library('image_lib', $config);
                $this->image_lib->resize();
                */

                //echo base_url().'uploads/bank_soal/'.$file['file_name'];
                $ext = pathinfo($file['file_name'], PATHINFO_EXTENSION);
                $src = 'uploads/bank_soal/'.$kode_file.'.'.$ext;
                $data['src'] = $src;
                //$filename = pathinfo($file['file_name'], PATHINFO_FILENAME);
                //$data['filename'] = $filename;
                $data['filename'] = $nama_file_asal;
                $data['status'] = true;

                $type = $_FILES['file_uploads']['type'];
                $data['type'] = $type;
                $data['size'] = $_FILES['file_uploads']['size'];
                $data['soal'] = $soal;

                $files[] = [
                    'file_name' => $nama_file_asal,
                    'alias' => $kode_file,
                    'src' => $src,
                    'type' => $type
                ];
                //array_push($files, ['files'=>$addFiles]);

                $this->db->set('file', serialize($files));
                $this->db->where('id_soal', $id_soal);
                $this->db->update('cbt_soal');
            }
        }

        $data['files'] = $files;
        $this->output_json($data);
    }
	//Upload image summernote
	function upload_image(){
		//$data['tag_id'] = $this->input->post('tag_id', true);
        $status = false;
        if(isset($_FILES["file"]["name"])){
			$config['upload_path'] = './uploads/bank_soal/';
			$config['allowed_types'] = 'jpg|jpeg|png|gif|mp3|ogg|wav|mp4|mpeg|webm';
            $config['file_name'] = 'file_'.date('YmdHis');
			$this->upload->initialize($config);
			if(!$this->upload->do_upload('file')){
				$this->upload->display_errors();
				$status = false;
			}else{
				$uploaded = $this->upload->data();
				//Compress Image
				//$config['image_library']='gd2';
				//$config['source_image']='./uploads/bank_soal/'.$data['file_name'];
				//$config['create_thumb']= FALSE;
				//$config['maintain_ratio']= TRUE;
				//$config['quality']= '60%';
				//$config['width']= 800;
				//$config['height']= 800;
				//$config['new_image']= './uploads/bank_soal/'.$data['file_name'];
				//$this->load->library('image_lib', $config);
				//$this->image_lib->resize();

				$data['filename'] =  'uploads/bank_soal/'.$uploaded['file_name'];
				$status = true;
			}
		}
		$data['status'] = $status;
		$this->output_json($data);
	}

	//Delete image summernote
    function deleteFile() {
        $src = $this->input->post('src');
        $file_name = str_replace(base_url(), '', $src);
        if (unlink($file_name)) {
            echo 'File Delete Successfully';
        }
    }

    function cleanString($text) {
        // 1) convert   => a o
        $text = preg_replace("/[]/u","a",$text);
        $text = preg_replace("/[]/u","A",$text);
        $text = preg_replace("/[]/u","I",$text);
        $text = preg_replace("/[]/u","i",$text);
        $text = preg_replace("/[]/u","e",$text);
        $text = preg_replace("/[]/u","E",$text);
        $text = preg_replace("/[]/u","o",$text);
        $text = preg_replace("/[]/u","O",$text);
        $text = preg_replace("/[]/u","u",$text);
        $text = preg_replace("/[]/u","U",$text);
        $text = preg_replace("/[]/u","'",$text);
        $text = preg_replace("/[]/u",'"',$text);
        $text = str_replace("","-",$text);
        $text = str_replace(" "," ",$text);
        $text = str_replace("","c",$text);
        $text = str_replace("","C",$text);
        $text = str_replace("","n",$text);
        $text = str_replace("","N",$text);

        //2) Translation CP1252. &ndash; => -
        $trans = get_html_translation_table(HTML_ENTITIES);
        $trans[chr(130)] = '&sbquo;';    // Single Low-9 Quotation Mark
        $trans[chr(131)] = '&fnof;';    // Latin Small Letter F With Hook
        $trans[chr(132)] = '&bdquo;';    // Double Low-9 Quotation Mark
        $trans[chr(133)] = '&hellip;';    // Horizontal Ellipsis
        $trans[chr(134)] = '&dagger;';    // Dagger
        $trans[chr(135)] = '&Dagger;';    // Double Dagger
        $trans[chr(136)] = '&circ;';    // Modifier Letter Circumflex Accent
        $trans[chr(137)] = '&permil;';    // Per Mille Sign
        $trans[chr(138)] = '&Scaron;';    // Latin Capital Letter S With Caron
        $trans[chr(139)] = '&lsaquo;';    // Single Left-Pointing Angle Quotation Mark
        $trans[chr(140)] = '&OElig;';    // Latin Capital Ligature OE
        $trans[chr(145)] = '&lsquo;';    // Left Single Quotation Mark
        $trans[chr(146)] = '&rsquo;';    // Right Single Quotation Mark
        $trans[chr(147)] = '&ldquo;';    // Left Double Quotation Mark
        $trans[chr(148)] = '&rdquo;';    // Right Double Quotation Mark
        $trans[chr(149)] = '&bull;';    // Bullet
        $trans[chr(150)] = '&ndash;';    // En Dash
        $trans[chr(151)] = '&mdash;';    // Em Dash
        $trans[chr(152)] = '&tilde;';    // Small Tilde
        $trans[chr(153)] = '&trade;';    // Trade Mark Sign
        $trans[chr(154)] = '&scaron;';    // Latin Small Letter S With Caron
        $trans[chr(155)] = '&rsaquo;';    // Single Right-Pointing Angle Quotation Mark
        $trans[chr(156)] = '&oelig;';    // Latin Small Ligature OE
        $trans[chr(159)] = '&Yuml;';    // Latin Capital Letter Y With Diaeresis
        $trans['euro'] = '&euro;';    // euro currency symbol
        ksort($trans);

        foreach ($trans as $k => $v) {
            $text = str_replace($v, $k, $text);
        }

        // 3) remove <p>, <br/> ...
        $text = strip_tags($text);

        // 4) &amp; => & &quot; => '
        $text = html_entity_decode($text);

        // 5) remove Windows-1252 symbols like "TradeMark", "Euro"...
        $text = preg_replace('/[^( -)]*/','', $text);

        $targets=array('
','
','
','	');
        $results=array(" "," "," ","");
        $text = str_replace($targets,$results,$text);

        //XML compatible
        /*
        $text = str_replace("&", "and", $text);
        $text = str_replace("<", ".", $text);
        $text = str_replace(">", ".", $text);
        $text = str_replace("\", "-", $text);
        $text = str_replace("/", "-", $text);
        */

        return ($text);
    }

    function cleanHTML($html) {
        $doc = new DOMDocument();
        /* Load the HTML */
        $doc->loadHTML($html,
            LIBXML_HTML_NOIMPLIED | # Make sure no extra BODY
            LIBXML_HTML_NODEFDTD |  # or DOCTYPE is created
            LIBXML_NOERROR |        # Suppress any errors
            LIBXML_NOWARNING        # or warnings about prefixes.
        );
        /* Immediately save the HTML and return it. */
        return $doc->saveHTML();
    }

    function addNamespaces($xml) {
        $root = '<w:wordDocument
        xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
        xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
        xmlns:o="urn:schemas-microsoft-com:office:office">';
        $root .= $xml;
        $root .= '</w:wordDocument>';
        return $root;
    }

    function doImport() {
        $bank_id = $this->input->post('id_bank', true);
        $string = $this->input->post('data', false);

        $json = json_decode($string);
        /*
        switch (json_last_error()) {
            case JSON_ERROR_NONE:
                echo ' - No errors';
                break;
            case JSON_ERROR_DEPTH:
                echo ' - Maximum stack depth exceeded';
                break;
            case JSON_ERROR_STATE_MISMATCH:
                echo ' - Underflow or the modes mismatch';
                break;
            case JSON_ERROR_CTRL_CHAR:
                echo ' - Unexpected control character found';
                break;
            case JSON_ERROR_SYNTAX:
                echo ' - Syntax error, malformed JSON';
                break;
            case JSON_ERROR_UTF8:
                echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
                break;
            default:
                echo ' - Unknown error';
                break;
        }
        */
        $datas = [];
        $jml = [];
        foreach ($json as $jenis=>$values) {
            $data_soal = [];
            foreach ($values as $val) {
                if (isset($val->NO)) {
                    $no = $val->NO;
                    if (isset($val->SOAL) && $val->SOAL != "") $data_soal[$no]['soal'] = $val->SOAL;

                    if ($jenis == "1") {
                        if (isset($val->OPSI)) {
                            $data_soal[$no]['opsi'][strtoupper($val->OPSI)] = $val->JAWABAN;
                            if (isset($val->KUNCI) && strtolower($val->KUNCI) == "v") {
                                $data_soal[$no]['kunci'][strtolower($val->KUNCI)] = strtoupper($val->OPSI);
                            }
                        }
                    } elseif ($jenis == "2") {
                        if (isset($val->OPSI)) {
                            $data_soal[$no]['opsi'][strtoupper($val->OPSI)] = $val->JAWABAN;
                            if (isset($val->KUNCI) && strtolower($val->KUNCI) == "v") {
                                $data_soal[$no]['kunci'][strtoupper($val->OPSI)] = strtolower($val->KUNCI);
                            }
                        }
                    } elseif ($jenis == "3") {
                        if (isset($val->KD_BARIS)) {
                            $data_soal[$no]['baris'][strtoupper($val->KD_BARIS)] = $val->BARIS;

                            if (isset($val->KUNCI)) {
                                $data_soal[$no]['kunci'][strtoupper($val->KD_KUNCI)] = strtoupper($val->KUNCI);
                            }
                        }

                        if (isset($val->KD_KOLOM)) {
                            $data_soal[$no]['kolom'][strtoupper($val->KD_KOLOM)] = $val->KOLOM;
                        }
                    } else {
                        if (isset($val->KUNCI)) $data_soal[$no]['kunci'] = $val->KUNCI;
                    }
                }
            }

            $datas[$jenis] = $data_soal;
        }

        $data_insert = [];
        foreach ($datas as $jenis=>$keys) {
            foreach ($keys as $no=>$v) {
                $isi_soal = isset($v['soal']) ? $v['soal'] : "";
                if ($isi_soal != "") {
                    $insert = [
                        'jenis' => $jenis,
                        'nomor_soal' => $no,
                        'soal' => $isi_soal,
                        'file' => serialize([]) ,
                    ];

                    if ($jenis == "1") {
                        $insert['opsi_a'] = isset($v['opsi']) && isset($v['opsi']['A']) ? $v['opsi']['A'] : '';
                        $insert['opsi_b'] = isset($v['opsi']) && isset($v['opsi']['B']) ? $v['opsi']['B'] : '';
                        $insert['opsi_c'] = isset($v['opsi']) && isset($v['opsi']['C']) ? $v['opsi']['C'] : '';
                        $insert['opsi_d'] = isset($v['opsi']) && isset($v['opsi']['D']) ? $v['opsi']['D'] : '';
                        $insert['opsi_e'] = isset($v['opsi']) && isset($v['opsi']['E']) ? $v['opsi']['E'] : '';
                        $insert['jawaban'] = isset($v['kunci']) && isset($v['kunci']['v']) ? $v['kunci']['v'] : '';
                    } elseif ($jenis == "2") {
                        $opsis = [];
                        $kuncis = [];
                        if (isset($v['opsi'])) {
                            foreach ($v['opsi'] as $opsi=>$jawaban) {
                                $opsis[strtolower($opsi)] = $jawaban;
                            }
                        }

                        if (isset($v['kunci'])) {
                            foreach ($v['kunci'] as $kunci=>$jawaban) {
                                if ($jawaban == "v") $kuncis[] = strtolower($kunci);
                            }
                        }
                        $insert['opsi_a'] = serialize($opsis);
                        $insert['jawaban'] = serialize($kuncis);

                    } elseif ($jenis == "3") {
                        $baris = [];
                        $kolom = [];

                        $header = [];
                        array_push($header, '#');

                        $arrKol = [];
                        foreach ($v['kolom'] as $kd_kol=>$kol) {
                            $kolom[$kd_kol] = $kol;
                            if ($kol != "") array_push($header, $kol);

                            foreach ($v['kunci'] as $kd_bar=>$kd_kol) {
                                if ($kd_kol != "") $arrKol[$kd_bar] = explode(',', $kd_kol);
                            }
                        }

                        array_push($baris, $header);
                        $jwbnBaris = [];
                        foreach ($v['baris'] as $kd_bar=>$bar) {
                            $jwbn = [];
                            if ($kd_bar != "") array_push($jwbn, $bar);

                            foreach ($kolom as $kk=>$val) {
                                if ($kd_bar != "" && $val != "") {
                                    $match = in_array($kk, $arrKol[$kd_bar]);
                                    array_push($jwbn, $match ? '1' : '0');
                                }
                            }
                            if (count($jwbn) > 0) array_push($baris, $jwbn);

                            if ($kd_bar != "") {
                                array_shift($jwbn);
                                $jwbnBaris[$kd_bar] = $jwbn;
                            }
                        }
                        $types = [];
                        foreach ($jwbnBaris as $brs=>$jml) {
                            $jmlType = array_count_values($jml);
                            if ($jmlType[1] > 1) array_push($types, 'checkbox');
                        }
                        $type = count($types) > 0 ? '1' : '2';

                        $jml_baris = count($baris);
                        $jml_kolom = count($baris[0]);

                        $jwb_jodohkan = [
                            'model' => $jml_baris == $jml_kolom ? '1' : '2',
                            'type' => $type,
                            'jawaban' => $baris
                        ];
                        $insert['jawaban'] = serialize($jwb_jodohkan);
                    } elseif ($jenis == "4") {
                        if (isset($v['kunci'])) $insert['jawaban'] = strip_tags($v['kunci']);
                    } else {
                        if (isset($v['kunci'])) $insert['jawaban'] = $v['kunci'];
                    }

                    $data_insert[] = $insert;
                }
            }
        }

        $inserted = [];
        foreach ($data_insert as $dins) {
            $inserted[] = [
                'bank_id' => $bank_id,
                'jenis' => $dins['jenis'],
                'nomor_soal' => $dins['nomor_soal'],
                'soal' => $dins['soal'],
                'deskripsi'=> '',
                'kesulitan'=> '8',
                'timer' => '0',
                'timer_menit' => '0',
                'file' => $dins['file'] ,
                'tampilkan' => '0',
                'created_on' => time(),
                'updated_on' => time(),
                'opsi_a' => isset($dins['opsi_a']) ? $dins['opsi_a'] : '',
                'opsi_b' => isset($dins['opsi_b']) ? $dins['opsi_b'] : '',
                'opsi_c' => isset($dins['opsi_c']) ? $dins['opsi_c'] : '',
                'opsi_d' => isset($dins['opsi_d']) ? $dins['opsi_d'] : '',
                'opsi_e' => isset($dins['opsi_e']) ? $dins['opsi_e'] : '',
                'jawaban' => $dins['jawaban']
            ];
        }

        $data['data_insert'] = $inserted;
        $data['total'] = count($inserted);
        if (count($inserted) > 0) {
            $this->db->where('bank_id', $bank_id);
            if ($this->db->delete('cbt_soal')) {
                $data['insert'] = $this->db->insert_batch('cbt_soal', $inserted);
            }
        } else {
            $data['insert'] = 0;
        }
        $this->output_json($data);
    }
}

Did this file decode correctly?

Original Code

eval(base64_decode('DQovKioNCiAqIENyZWF0ZWQgYnkgSW50ZWxsaUogSURFQS4NCiAqIFVzZXI6IG11bHRhemFtDQogKiBEYXRlOiAwNy8wNy8yMA0KICogVGltZTogMTQ6MTANCiAqLw0KDQpjbGFzcyBDYnRiYW5rc29hbCBleHRlbmRzIENJX0NvbnRyb2xsZXIgew0KDQoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCl7DQoJCXBhcmVudDo6X19jb25zdHJ1Y3QoKTsNCgkJaWYgKCEkdGhpcy0+aW9uX2F1dGgtPmxvZ2dlZF9pbigpKXsNCgkJCXJlZGlyZWN0KCdhdXRoJyk7DQoJCX1lbHNlIGlmICggISR0aGlzLT5pb25fYXV0aC0+aXNfYWRtaW4oKSAmJiAhJHRoaXMtPmlvbl9hdXRoLT5pbl9ncm91cCgnZ3VydScpKXsNCgkJCXNob3dfZXJyb3IoJ0hhbnlhIEFkbWluaXN0cmF0b3IgZGFuIGd1cnUgeWFuZyBkaWJlcmkgaGFrIHVudHVrIG1lbmdha3NlcyBoYWxhbWFuIGluaSwgPGEgaHJlZj0iJy5iYXNlX3VybCgnZGFzaGJvYXJkJykuJyI+S2VtYmFsaSBrZSBtZW51IGF3YWw8L2E+JywgNDAzLCAnQWtzZXMgVGVybGFyYW5nJyk7DQoJCX0NCgkJJHRoaXMtPmxvYWQtPmxpYnJhcnkoJ3VwbG9hZCcpOw0KCQkvLyR0aGlzLT5sb2FkLT5saWJyYXJ5KCdNWV9VcGxvYWQnLCAnbXlfdXBsb2FkJyk7DQoJCSR0aGlzLT5sb2FkLT5saWJyYXJ5KFsnZGF0YXRhYmxlcycsICdmb3JtX3ZhbGlkYXRpb24nXSk7Ly8gTG9hZCBMaWJyYXJ5IElnbml0ZWQtRGF0YXRhYmxlcw0KCQkkdGhpcy0+Zm9ybV92YWxpZGF0aW9uLT5zZXRfZXJyb3JfZGVsaW1pdGVycygnJywnJyk7DQoNCgkJJHRoaXMtPmxvYWQtPmhlbHBlcignbXknKTsvLyBMb2FkIExpYnJhcnkgSWduaXRlZC1EYXRhdGFibGVzDQoJCSR0aGlzLT5sb2FkLT5tb2RlbCgnTWFzdGVyX21vZGVsJywgJ21hc3RlcicpOw0KCQkkdGhpcy0+bG9hZC0+bW9kZWwoJ0Rhc2hib2FyZF9tb2RlbCcsICdkYXNoYm9hcmQnKTsNCgkJJHRoaXMtPmxvYWQtPm1vZGVsKCdDYnRfbW9kZWwnLCAnY2J0Jyk7DQoJCSR0aGlzLT5sb2FkLT5tb2RlbCgnTG9nX21vZGVsJywgJ2xvZ2dpbmcnKTsNCgkJJHRoaXMtPmxvYWQtPm1vZGVsKCdLZWxhc19tb2RlbCcsICdrZWxhcycpOw0KCQkkdGhpcy0+bG9hZC0+bW9kZWwoJ0Ryb3Bkb3duX21vZGVsJywgJ2Ryb3Bkb3duJyk7DQoJfQ0KDQoJcHVibGljIGZ1bmN0aW9uIG91dHB1dF9qc29uKCRkYXRhLCAkZW5jb2RlID0gdHJ1ZSkNCgl7DQoJCWlmKCRlbmNvZGUpICRkYXRhID0ganNvbl9lbmNvZGUoJGRhdGEpOw0KCQkkdGhpcy0+b3V0cHV0LT5zZXRfY29udGVudF90eXBlKCdhcHBsaWNhdGlvbi9qc29uJyktPnNldF9vdXRwdXQoJGRhdGEpOw0KCX0NCg0KCXB1YmxpYyBmdW5jdGlvbiBpbmRleCgpIHsNCgkJJHVzZXIgPSAkdGhpcy0+aW9uX2F1dGgtPnVzZXIoKS0+cm93KCk7DQoJCSRzZXR0aW5nID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0U2V0dGluZygpOw0KCQkkZGF0YSA9IFsNCgkJCSd1c2VyJyA9PiAkdXNlciwNCgkJCSdqdWR1bCcJPT4gJ0JhbmsgU29hbCcsDQoJCQknc3VianVkdWwnPT4gJ1NvYWwnLA0KCQkJJ3NldHRpbmcnCQk9PiAkc2V0dGluZw0KCQldOw0KDQoJCSR0cCA9ICR0aGlzLT5tYXN0ZXItPmdldFRhaHVuQWN0aXZlKCk7DQoJCSRzbXQgPSAkdGhpcy0+bWFzdGVyLT5nZXRTZW1lc3RlckFjdGl2ZSgpOw0KDQoJCSRkYXRhWyd0cCddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0VGFodW4oKTsNCgkJJGRhdGFbJ3RwX2FjdGl2ZSddID0gJHRwOw0KCQkkZGF0YVsnc210J10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRTZW1lc3RlcigpOw0KCQkkZGF0YVsnc210X2FjdGl2ZSddID0gJHNtdDsNCiAgICAgICAgJGRhdGFbJ2xldmVscyddID0gJHRoaXMtPmRyb3Bkb3duLT5nZXRBbGxMZXZlbCgkc2V0dGluZy0+amVuamFuZyk7DQogICAgICAgICRkYXRhWydtYXBlbHMnXSA9ICR0aGlzLT5kcm9wZG93bi0+Z2V0QWxsTWFwZWwoKTsNCg0KICAgICAgICAkdHlwZSA9ICR0aGlzLT5pbnB1dC0+Z2V0KCd0eXBlJyk7DQoJCWlmKCR0aGlzLT5pb25fYXV0aC0+aXNfYWRtaW4oKSl7DQogICAgICAgICAgICAkZGF0YVsncHJvZmlsZSddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0UHJvZmlsZUFkbWluKCR1c2VyLT5pZCk7DQoJCQkkZGF0YVsnZ3VydXMnXSA9ICR0aGlzLT5kcm9wZG93bi0+Z2V0QWxsR3VydSgpOw0KICAgICAgICAgICAgJGRhdGFbJ2tlbGFzJ10gPSAkdGhpcy0+Y2J0LT5nZXRLZWxhcygkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KDQogICAgICAgICAgICAkZGF0YVsnZmlsdGVycyddID0gWycwJz0+J1NlbXVhJywgJzEnPT4nR3VydScsICcyJz0+J01hcGVsJywgJzMnPT4nTGV2ZWwnXTsNCiAgICAgICAgICAgICRkYXRhWydpZF9maWx0ZXInXSA9ICR0eXBlID09IG51bGwgPyAnJyA6ICR0eXBlOw0KICAgICAgICAgICAgaWYgKCR0eXBlID09ICcxJykgew0KICAgICAgICAgICAgICAgICRpZF9ndXJ1ID0gJHRoaXMtPmlucHV0LT5nZXQoJ2lkJyk7DQogICAgICAgICAgICAgICAgJGRhdGFbJ2lkX2d1cnUnXSA9ICRpZF9ndXJ1Ow0KICAgICAgICAgICAgICAgICRkYXRhWydiYW5rcyddID0gJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmsoJGlkX2d1cnUpOw0KDQogICAgICAgICAgICAgICAgJGRhdGFbJ2lkX21hcGVsJ10gPSAnJzsNCiAgICAgICAgICAgICAgICAkZGF0YVsnaWRfbGV2ZWwnXSA9ICcnOw0KICAgICAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09ICcyJykgew0KICAgICAgICAgICAgICAgICRpZF9tYXBlbCA9ICR0aGlzLT5pbnB1dC0+Z2V0KCdpZCcpOw0KICAgICAgICAgICAgICAgICRkYXRhWydpZF9tYXBlbCddID0gJGlkX21hcGVsOw0KICAgICAgICAgICAgICAgICRkYXRhWydiYW5rcyddID0gJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmsobnVsbCwgJGlkX21hcGVsKTsNCg0KICAgICAgICAgICAgICAgICRkYXRhWydpZF9ndXJ1J10gPSAnJzsNCiAgICAgICAgICAgICAgICAkZGF0YVsnaWRfbGV2ZWwnXSA9ICcnOw0KICAgICAgICAgICAgfSBlbHNlaWYgKCR0eXBlID09ICczJykgew0KICAgICAgICAgICAgICAgICRpZF9sZXZlbCA9ICR0aGlzLT5pbnB1dC0+Z2V0KCdpZCcpOw0KICAgICAgICAgICAgICAgICRkYXRhWydpZF9sZXZlbCddID0gJGlkX2xldmVsOw0KICAgICAgICAgICAgICAgICRkYXRhWydiYW5rcyddID0gJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmsobnVsbCwgbnVsbCwgJGlkX2xldmVsKTsNCg0KICAgICAgICAgICAgICAgICRkYXRhWydpZF9ndXJ1J10gPSAnJzsNCiAgICAgICAgICAgICAgICAkZGF0YVsnaWRfbWFwZWwnXSA9ICcnOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAkZGF0YVsnYmFua3MnXSA9ICR0aGlzLT5jYnQtPmdldERhdGFCYW5rKCk7DQogICAgICAgICAgICAgICAgJGRhdGFbJ2lkX2d1cnUnXSA9IG51bGw7DQogICAgICAgICAgICAgICAgJGRhdGFbJ2lkX21hcGVsJ10gPSBudWxsOw0KICAgICAgICAgICAgICAgICRkYXRhWydpZF9sZXZlbCddID0gbnVsbDsNCiAgICAgICAgICAgIH0NCg0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ190ZW1wbGF0ZXMvZGFzaGJvYXJkL19oZWFkZXInLCAkZGF0YSk7DQoJCQkkdGhpcy0+bG9hZC0+dmlldygnY2J0L2Jhbmtzb2FsL2RhdGEnKTsNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdfdGVtcGxhdGVzL2Rhc2hib2FyZC9fZm9vdGVyJyk7DQoJCX1lbHNlew0KCQkJJGd1cnUgPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXREYXRhR3VydUJ5VXNlcklkKCR1c2VyLT5pZCwgJHRwLT5pZF90cCwgJHNtdC0+aWRfc210KTsNCgkJCSRuZ3VydVskZ3VydS0+aWRfZ3VydV0gPSAkZ3VydS0+bmFtYV9ndXJ1Ow0KCQkJJGRhdGFbJ2d1cnUnXSA9ICRndXJ1Ow0KICAgICAgICAgICAgJGRhdGFbJ2d1cnVzJ10gPSAkbmd1cnU7DQogICAgICAgICAgICAkZGF0YVsna2VsYXMnXSA9ICR0aGlzLT5jYnQtPmdldEtlbGFzKCR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoNCiAgICAgICAgICAgICRkYXRhWydmaWx0ZXJzJ10gPSBbJzAnPT4nU2VtdWEnLCAnMic9PidNYXBlbCcsICczJz0+J0xldmVsJ107DQogICAgICAgICAgICAkZGF0YVsnaWRfZmlsdGVyJ10gPSAkdHlwZSA9PSBudWxsID8gJycgOiAkdHlwZTsNCiAgICAgICAgICAgIGlmICgkdHlwZSA9PSAnMicpIHsNCiAgICAgICAgICAgICAgICAkaWRfbWFwZWwgPSAkdGhpcy0+aW5wdXQtPmdldCgnaWQnKTsNCiAgICAgICAgICAgICAgICAkZGF0YVsnaWRfbWFwZWwnXSA9ICRpZF9tYXBlbDsNCiAgICAgICAgICAgICAgICAkZGF0YVsnYmFua3MnXSA9ICR0aGlzLT5jYnQtPmdldERhdGFCYW5rKCRndXJ1LT5pZF9ndXJ1LCAkaWRfbWFwZWwpOw0KDQogICAgICAgICAgICAgICAgJGRhdGFbJ2lkX2d1cnUnXSA9ICcnOw0KICAgICAgICAgICAgICAgICRkYXRhWydpZF9sZXZlbCddID0gJyc7DQogICAgICAgICAgICB9IGVsc2VpZiAoJHR5cGUgPT0gJzMnKSB7DQogICAgICAgICAgICAgICAgJGlkX2xldmVsID0gJHRoaXMtPmlucHV0LT5nZXQoJ2lkJyk7DQogICAgICAgICAgICAgICAgJGRhdGFbJ2lkX2xldmVsJ10gPSAkaWRfbGV2ZWw7DQogICAgICAgICAgICAgICAgJGRhdGFbJ2JhbmtzJ10gPSAkdGhpcy0+Y2J0LT5nZXREYXRhQmFuaygkZ3VydS0+aWRfZ3VydSwgbnVsbCwgJGlkX2xldmVsKTsNCg0KICAgICAgICAgICAgICAgICRkYXRhWydpZF9ndXJ1J10gPSAnJzsNCiAgICAgICAgICAgICAgICAkZGF0YVsnaWRfbWFwZWwnXSA9ICcnOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAkZGF0YVsnaWRfZ3VydSddID0gJGd1cnUtPmlkX2d1cnU7DQogICAgICAgICAgICAgICAgJGRhdGFbJ2JhbmtzJ10gPSAkdGhpcy0+Y2J0LT5nZXREYXRhQmFuaygkZ3VydS0+aWRfZ3VydSk7DQogICAgICAgICAgICAgICAgJGRhdGFbJ2lkX21hcGVsJ10gPSAnJzsNCiAgICAgICAgICAgICAgICAkZGF0YVsnaWRfbGV2ZWwnXSA9ICcnOw0KICAgICAgICAgICAgfQ0KDQoJCQkkdGhpcy0+bG9hZC0+dmlldygnbWVtYmVycy9ndXJ1L3RlbXBsYXRlcy9oZWFkZXInLCAkZGF0YSk7DQogICAgICAgICAgICAkdGhpcy0+bG9hZC0+dmlldygnY2J0L2Jhbmtzb2FsL2RhdGEnKTsNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdtZW1iZXJzL2d1cnUvdGVtcGxhdGVzL2Zvb3RlcicpOw0KCQl9DQoJfQ0KDQoJcHVibGljIGZ1bmN0aW9uIGRhdGEoJGd1cnU9bnVsbCkgew0KCQkkdGhpcy0+b3V0cHV0X2pzb24oJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmsoJGd1cnUpLCBmYWxzZSk7DQoJfQ0KDQogICAgcHVibGljIGZ1bmN0aW9uIGRhdGFUYWJsZSgkZ3VydT1udWxsKSB7DQogICAgICAgICR0aGlzLT5vdXRwdXRfanNvbigkdGhpcy0+Y2J0LT5nZXREYXRhVGFibGVCYW5rKCRndXJ1KSwgZmFsc2UpOw0KICAgIH0NCg0KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRNYXBlbEd1cnUoKSB7DQogICAgICAgICRpZF9ndXJ1ID0gJHRoaXMtPmlucHV0LT5nZXQoJ2lkX2d1cnUnLCB0cnVlKTsNCg0KICAgICAgICAkdHAgPSAkdGhpcy0+bWFzdGVyLT5nZXRUYWh1bkFjdGl2ZSgpOw0KICAgICAgICAkc210ID0gJHRoaXMtPm1hc3Rlci0+Z2V0U2VtZXN0ZXJBY3RpdmUoKTsNCiAgICAgICAgJG1hcGVsX2d1cnUgPSAkdGhpcy0+a2VsYXMtPmdldEd1cnVNYXBlbEtlbGFzKCRpZF9ndXJ1LCAkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KICAgICAgICAkbWFwZWwgPSBqc29uX2RlY29kZShqc29uX2VuY29kZSh1bnNlcmlhbGl6ZSgkbWFwZWxfZ3VydS0+bWFwZWxfa2VsYXMpKSk7DQoNCiAgICAgICAgJGFyck1hcGVsID0gW107DQogICAgICAgIGlmICgkbWFwZWwhPW51bGwpew0KICAgICAgICAgICAgZm9yZWFjaCAoJG1hcGVsIGFzICRtKSB7DQogICAgICAgICAgICAgICAgJGFyck1hcGVsWyRtLT5pZF9tYXBlbF0gPSAkbS0+bmFtYV9tYXBlbDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgICR0aGlzLT5vdXRwdXRfanNvbigkYXJyTWFwZWwpOw0KICAgIH0NCg0KCXB1YmxpYyBmdW5jdGlvbiBnZXRLZWxhc0xldmVsKCkgew0KCQkkbGV2ZWwgPSAkdGhpcy0+aW5wdXQtPmdldCgnbGV2ZWwnLCB0cnVlKTsNCgkJJGlkX2d1cnUgPSAkdGhpcy0+aW5wdXQtPmdldCgnaWRfZ3VydScsIHRydWUpOw0KCQkkaWRfbWFwZWwgPSAkdGhpcy0+aW5wdXQtPmdldCgnbWFwZWwnLCB0cnVlKTsNCg0KICAgICAgICAkdHAgPSAkdGhpcy0+bWFzdGVyLT5nZXRUYWh1bkFjdGl2ZSgpOw0KICAgICAgICAkc210ID0gJHRoaXMtPm1hc3Rlci0+Z2V0U2VtZXN0ZXJBY3RpdmUoKTsNCgkJJG1hcGVsX2d1cnUgPSAkdGhpcy0+a2VsYXMtPmdldEd1cnVNYXBlbEtlbGFzKCRpZF9ndXJ1LCAkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KICAgICAgICAkYXJyS2VsYXMgPSBbXTsNCiAgICAgICAgJGFyck1hcGVsID0gW107DQogICAgICAgICRtYXBlbCA9IGpzb25fZGVjb2RlKGpzb25fZW5jb2RlKHVuc2VyaWFsaXplKCRtYXBlbF9ndXJ1LT5tYXBlbF9rZWxhcykpKTsNCg0KICAgICAgICBmb3JlYWNoICgkbWFwZWwgYXMgJG0pIHsNCiAgICAgICAgICAgICRhcnJNYXBlbFskbS0+aWRfbWFwZWxdID0gJG0tPm5hbWFfbWFwZWw7DQogICAgICAgICAgICBpZiAoJGlkX21hcGVsPT09JG0tPmlkX21hcGVsKXsNCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbS0+a2VsYXNfbWFwZWwgYXMgJGtscykgew0KICAgICAgICAgICAgICAgICAgICBhcnJheV9wdXNoKCRhcnJLZWxhcywgJGtscy0+a2VsYXMpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoJCSR0aGlzLT5vdXRwdXRfanNvbihbJ21hcGVsJz0+ICRhcnJNYXBlbCwgJ2tlbGFzJz0+JHRoaXMtPmNidC0+Z2V0S2VsYXNCeUxldmVsKCRsZXZlbCwgJGFycktlbGFzKV0pOw0KCX0NCg0KCXB1YmxpYyBmdW5jdGlvbiBhZGRCYW5rKCkgew0KCQkkdXNlciA9ICR0aGlzLT5pb25fYXV0aC0+dXNlcigpLT5yb3coKTsNCiAgICAgICAgJHNldHRpbmcgPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRTZXR0aW5nKCk7DQoJCSRkYXRhID0gWw0KCQkJJ3VzZXInICAgICAgPT4gJHVzZXIsDQoJCQknanVkdWwnCSAgICA9PiAnQmFuayBTb2FsJywNCgkJCSdzdWJqdWR1bCcgID0+ICdCdWF0IEJhbmsgU29hbCcsDQoJCV07DQoNCgkJJHRwID0gJHRoaXMtPm1hc3Rlci0+Z2V0VGFodW5BY3RpdmUoKTsNCgkJJHNtdCA9ICR0aGlzLT5tYXN0ZXItPmdldFNlbWVzdGVyQWN0aXZlKCk7DQoNCgkJJGRhdGFbJ3RwJ10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRUYWh1bigpOw0KCQkkZGF0YVsndHBfYWN0aXZlJ10gPSAkdHA7DQoJCSRkYXRhWydzbXQnXSA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFNlbWVzdGVyKCk7DQoJCSRkYXRhWydzbXRfYWN0aXZlJ10gPSAkc210Ow0KDQoJCSRkYXRhWydzZXR0aW5nJ10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRTZXR0aW5nKCk7DQoJCSRkYXRhWydiYW5rJ10gPSBqc29uX2RlY29kZShqc29uX2VuY29kZSgkdGhpcy0+Y2J0LT5kdW1teSgkc2V0dGluZy0+amVuamFuZykpKTsNCgkJJGRhdGFbJ2plbmlzJ10gPSAkdGhpcy0+Y2J0LT5nZXRBbGxKZW5pc1VqaWFuKCk7DQoJCSRkYXRhWydqdXJ1c2FuJ10gPSAkdGhpcy0+Y2J0LT5nZXRBbGxKdXJ1c2FuKCk7DQoJCSRkYXRhWydsZXZlbCddID0gJHRoaXMtPmRyb3Bkb3duLT5nZXRBbGxMZXZlbCgkc2V0dGluZy0+amVuamFuZyk7DQoNCgkJaWYoJHRoaXMtPmlvbl9hdXRoLT5pc19hZG1pbigpKXsNCiAgICAgICAgICAgICRkYXRhWydwcm9maWxlJ10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRQcm9maWxlQWRtaW4oJHVzZXItPmlkKTsNCgkJCSRkYXRhWydrZWxhcyddID0gJHRoaXMtPmRyb3Bkb3duLT5nZXRBbGxLZWxhcygkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KCQkJJGRhdGFbJ2lkX2d1cnUnXSA9ICcnOw0KCQkJJGRhdGFbJ2d1cnVzJ10gPSAkdGhpcy0+ZHJvcGRvd24tPmdldEFsbEd1cnUoKTsNCgkJCSRkYXRhWydtYXBlbCddID0gJHRoaXMtPmRyb3Bkb3duLT5nZXRBbGxNYXBlbCgpOw0KDQoJCQkkdGhpcy0+bG9hZC0+dmlldygnX3RlbXBsYXRlcy9kYXNoYm9hcmQvX2hlYWRlcicsICRkYXRhKTsNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdjYnQvYmFua3NvYWwvYWRkJyk7DQoJCQkkdGhpcy0+bG9hZC0+dmlldygnX3RlbXBsYXRlcy9kYXNoYm9hcmQvX2Zvb3RlcicpOw0KCQl9ZWxzZXsNCgkJCSRndXJ1ID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0RGF0YUd1cnVCeVVzZXJJZCgkdXNlci0+aWQsICR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoJCQkkbmd1cnVbJGd1cnUtPmlkX2d1cnVdID0gJGd1cnUtPm5hbWFfZ3VydTsNCiAgICAgICAgICAgICRkYXRhWydndXJ1cyddID0gJG5ndXJ1Ow0KCQkJJGRhdGFbJ2d1cnUnXSA9ICRndXJ1Ow0KCQkJJGRhdGFbJ2lkX2d1cnUnXSA9ICRndXJ1LT5pZF9ndXJ1Ow0KDQoJCQkkbWFwZWxfZ3VydSA9ICR0aGlzLT5rZWxhcy0+Z2V0R3VydU1hcGVsS2VsYXMoJGd1cnUtPmlkX2d1cnUsICR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoJCQkkbWFwZWwgPSBqc29uX2RlY29kZShqc29uX2VuY29kZSh1bnNlcmlhbGl6ZSgkbWFwZWxfZ3VydS0+bWFwZWxfa2VsYXMpKSk7DQoNCgkJCSRhcnJNYXBlbCA9IFtdOw0KCQkJJGFycktlbGFzID0gW107DQoJCQlmb3JlYWNoICgkbWFwZWwgYXMgJG0pIHsNCgkJCQkkYXJyTWFwZWxbJG0tPmlkX21hcGVsXSA9ICRtLT5uYW1hX21hcGVsOw0KCQkJCWZvcmVhY2ggKCRtLT5rZWxhc19tYXBlbCBhcyAka2xzKSB7DQoJCQkJCSRhcnJLZWxhc1skbS0+aWRfbWFwZWxdW10gPSBbDQoJCQkJCQknaWRfa2VsYXMnCT0+CSRrbHMtPmtlbGFzLA0KCQkJCQkJJ25hbWFfa2VsYXMnPT4kdGhpcy0+ZHJvcGRvd24tPmdldE5hbWFLZWxhc0J5SWQoJHRwLT5pZF90cCwgJHNtdC0+aWRfc210LCAka2xzLT5rZWxhcyldOw0KCQkJCX0NCgkJCX0NCg0KCQkJJGFycklkID0gW107DQoJCQlpZiAoY291bnQoJG1hcGVsKSA+IDApIHsNCiAgICAgICAgICAgICAgICBmb3JlYWNoICgkbWFwZWxbMF0tPmtlbGFzX21hcGVsIGFzICRpZF9tYXBlbCkgew0KICAgICAgICAgICAgICAgICAgICBhcnJheV9wdXNoKCRhcnJJZCwgJGlkX21hcGVsLT5rZWxhcyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQoJCQkkZGF0YVsnbWFwZWxfZ3VydSddID0gJG1hcGVsX2d1cnU7DQoJCQkkZGF0YVsnbWFwZWwnXSA9ICRhcnJNYXBlbDsNCgkJCSRkYXRhWydhcnJrZWxhcyddID0gJGFycktlbGFzOw0KCQkJJGRhdGFbJ2tlbGFzJ10gPSBjb3VudCgkYXJySWQpID4gMCA/ICR0aGlzLT5kcm9wZG93bi0+Z2V0QWxsS2VsYXNCeUFycmF5SWQoJHRwLT5pZF90cCwgJHNtdC0+aWRfc210LCAkYXJySWQpIDogW107DQoNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdtZW1iZXJzL2d1cnUvdGVtcGxhdGVzL2hlYWRlcicsICRkYXRhKTsNCiAgICAgICAgICAgICR0aGlzLT5sb2FkLT52aWV3KCdjYnQvYmFua3NvYWwvYWRkJyk7DQoJCQkkdGhpcy0+bG9hZC0+dmlldygnbWVtYmVycy9ndXJ1L3RlbXBsYXRlcy9mb290ZXInKTsNCgkJfQ0KCX0NCg0KCXB1YmxpYyBmdW5jdGlvbiBlZGl0QmFuaygpIHsNCgkJJGlkX2JhbmsgPSAkdGhpcy0+aW5wdXQtPmdldCgnaWRfYmFuaycsIHRydWUpOw0KCQkkaWRfZ3VydSA9ICR0aGlzLT5pbnB1dC0+Z2V0KCdpZF9ndXJ1JywgdHJ1ZSk7DQogICAgICAgICRzZXR0aW5nID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0U2V0dGluZygpOw0KDQoJCSR1c2VyID0gJHRoaXMtPmlvbl9hdXRoLT51c2VyKCktPnJvdygpOw0KCQkkZGF0YSA9IFsNCgkJCSd1c2VyJyAgICAgID0+ICR1c2VyLA0KCQkJJ2p1ZHVsJwkgICAgPT4gJ0VkaXQgQmFuayBTb2FsJywNCgkJCSdzdWJqdWR1bCcgID0+ICdFZGl0IEJhbmsgU29hbCcNCgkJXTsNCg0KCQkkdHAgPSAkdGhpcy0+bWFzdGVyLT5nZXRUYWh1bkFjdGl2ZSgpOw0KCQkkc210ID0gJHRoaXMtPm1hc3Rlci0+Z2V0U2VtZXN0ZXJBY3RpdmUoKTsNCg0KCQkkZGF0YVsndHAnXSA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFRhaHVuKCk7DQoJCSRkYXRhWyd0cF9hY3RpdmUnXSA9ICR0cDsNCgkJJGRhdGFbJ3NtdCddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0U2VtZXN0ZXIoKTsNCgkJJGRhdGFbJ3NtdF9hY3RpdmUnXSA9ICRzbXQ7DQoJCSRkYXRhWydidWxhbiddID0gJHRoaXMtPmRyb3Bkb3duLT5nZXRCdWxhbigpOw0KDQoJCSRkYXRhWydzZXR0aW5nJ10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRTZXR0aW5nKCk7DQoJCSRkYXRhWydqZW5pcyddID0gJHRoaXMtPmNidC0+Z2V0QWxsSmVuaXNVamlhbigpOw0KCQkkZGF0YVsnanVydXNhbiddID0gJHRoaXMtPmNidC0+Z2V0QWxsSnVydXNhbigpOw0KCQkkZGF0YVsnbGV2ZWwnXSA9ICR0aGlzLT5kcm9wZG93bi0+Z2V0QWxsTGV2ZWwoJHNldHRpbmctPmplbmphbmcpOw0KCQkkZGF0YVsna2VsYXMnXSA9ICR0aGlzLT5kcm9wZG93bi0+Z2V0QWxsS2VsYXMoJHRwLT5pZF90cCwgJHNtdC0+aWRfc210KTsNCg0KCQkkZGF0YVsnYmFuayddID0gJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmtCeUlkKCRpZF9iYW5rKTsNCg0KCQlpZigkdGhpcy0+aW9uX2F1dGgtPmlzX2FkbWluKCkpew0KICAgICAgICAgICAgJGRhdGFbJ3Byb2ZpbGUnXSA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFByb2ZpbGVBZG1pbigkdXNlci0+aWQpOw0KCQkJJGRhdGFbJ2lkX2d1cnUnXSA9ICRpZF9ndXJ1Ow0KCQkJJGRhdGFbJ2d1cnVzJ10gPSAkdGhpcy0+ZHJvcGRvd24tPmdldEFsbEd1cnUoKTsNCg0KCQkJJGFyck1hcGVsID0gW107DQoJCQkkbWFwZWxfZ3VydSA9ICR0aGlzLT5rZWxhcy0+Z2V0R3VydU1hcGVsS2VsYXMoJGlkX2d1cnUsICR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoJCQkkbWFwZWwgPSAkbWFwZWxfZ3VydS0+bWFwZWxfa2VsYXMgIT0gbnVsbCA/IGpzb25fZGVjb2RlKGpzb25fZW5jb2RlKHVuc2VyaWFsaXplKCRtYXBlbF9ndXJ1LT5tYXBlbF9rZWxhcykpKSA6IFtdOw0KCQkJZm9yZWFjaCAoJG1hcGVsIGFzICRtKSB7DQoJCQkJJGFyck1hcGVsWyRtLT5pZF9tYXBlbF0gPSAkbS0+bmFtYV9tYXBlbDsNCgkJCX0NCgkJCSRkYXRhWydtYXBlbCddID0gJGFyck1hcGVsOw0KCQkJJGRhdGFbJ21hcGVsX2d1cnUnXSA9ICRtYXBlbF9ndXJ1Ow0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ190ZW1wbGF0ZXMvZGFzaGJvYXJkL19oZWFkZXInLCAkZGF0YSk7DQoJCQkkdGhpcy0+bG9hZC0+dmlldygnY2J0L2Jhbmtzb2FsL2FkZCcpOw0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ190ZW1wbGF0ZXMvZGFzaGJvYXJkL19mb290ZXInKTsNCgkJfWVsc2V7DQoJCQkkZ3VydSA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldERhdGFHdXJ1QnlVc2VySWQoJHVzZXItPmlkLCAkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KCQkJJG5ndXJ1WyRndXJ1LT5pZF9ndXJ1XSA9ICRndXJ1LT5uYW1hX2d1cnU7DQoJCQkkbWFwZWxfZ3VydSA9ICR0aGlzLT5rZWxhcy0+Z2V0R3VydU1hcGVsS2VsYXMoJGd1cnUtPmlkX2d1cnUsICR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoJCQkkbWFwZWwgPSBqc29uX2RlY29kZShqc29uX2VuY29kZSh1bnNlcmlhbGl6ZSgkbWFwZWxfZ3VydS0+bWFwZWxfa2VsYXMpKSk7DQoNCgkJCSRhcnJNYXBlbCA9IFtdOw0KCQkJZm9yZWFjaCAoJG1hcGVsIGFzICRtKSB7DQoJCQkJJGFyck1hcGVsWyRtLT5pZF9tYXBlbF0gPSAkbS0+bmFtYV9tYXBlbDsNCgkJCX0NCg0KICAgICAgICAgICAgJGRhdGFbJ2d1cnVzJ10gPSAkbmd1cnU7DQoJCQkkZGF0YVsnbWFwZWxfZ3VydSddID0gJG1hcGVsX2d1cnU7DQoJCQkkZGF0YVsnZ3VydSddID0gJGd1cnU7DQoJCQkkZGF0YVsnaWRfZ3VydSddID0gJGd1cnUtPmlkX2d1cnU7DQoJCQkkZGF0YVsnbWFwZWwnXSA9ICRhcnJNYXBlbDsNCg0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ21lbWJlcnMvZ3VydS90ZW1wbGF0ZXMvaGVhZGVyJywgJGRhdGEpOw0KICAgICAgICAgICAgJHRoaXMtPmxvYWQtPnZpZXcoJ2NidC9iYW5rc29hbC9hZGQnKTsNCgkJCS8vJHRoaXMtPmxvYWQtPnZpZXcoJ21lbWJlcnMvZ3VydS9jYnQvYmFua3NvYWwvYWRkJyk7DQoJCQkkdGhpcy0+bG9hZC0+dmlldygnbWVtYmVycy9ndXJ1L3RlbXBsYXRlcy9mb290ZXInKTsNCgkJfQ0KCX0NCg0KCXB1YmxpYyBmdW5jdGlvbiBzYXZlQmFuaygpIHsNCgkJaWYgKCR0aGlzLT5pbnB1dC0+cG9zdCgpKSB7DQogICAgICAgICAgICAkdHAgPSAkdGhpcy0+bWFzdGVyLT5nZXRUYWh1bkFjdGl2ZSgpOw0KICAgICAgICAgICAgJHNtdCA9ICR0aGlzLT5tYXN0ZXItPmdldFNlbWVzdGVyQWN0aXZlKCk7DQoNCgkJCSR0aGlzLT5jYnQtPnNhdmVCYW5rU29hbCgkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KCQkJJHN0YXR1cyA9IFRSVUU7DQoJCX0gZWxzZSB7DQoJCQkkc3RhdHVzID0gRkFMU0U7DQoJCX0NCgkJJGRhdGFbJ3N0YXR1cyddID0gJHN0YXR1czsNCg0KCQkkaWQgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ2lkX2JhbmsnLCB0cnVlKTsNCgkJaWYgKCEkaWQpIHsNCgkJCSR0aGlzLT5sb2dnaW5nLT5zYXZlTG9nKDMsICdtZW5hbWJhaCBiYW5rIHNvYWwnKTsNCgkJfSBlbHNlIHsNCgkJCSR0aGlzLT5sb2dnaW5nLT5zYXZlTG9nKDQsICdtZW5nZWRpdCBiYW5rIHNvYWwnKTsNCgkJfQ0KDQoJCSR0aGlzLT5vdXRwdXRfanNvbigkZGF0YSk7DQoJfQ0KDQoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZUJhbmsoKSB7DQoJCSRpZCA9ICR0aGlzLT5pbnB1dC0+Z2V0KCdpZF9iYW5rJywgdHJ1ZSk7DQoJCWlmICgkdGhpcy0+Y2J0LT5jZWtKYWR3YWxCYW5rU29hbCgkaWQpPjApIHsNCgkJCSR0aGlzLT5vdXRwdXRfanNvbihbJ3N0YXR1cycgPT4gZmFsc2UsICdtZXNzYWdlJyA9PiAnQWRhIGphZHdhbCB1amlhbiB5YW5nIG1lbmdndW5ha2FuIGJhbmsgc29hbCBpbmknXSk7DQoJCX0gZWxzZSB7DQoJCQlpZiAoJHRoaXMtPm1hc3Rlci0+ZGVsZXRlKCdjYnRfc29hbCcsICRpZCwgJ2JhbmtfaWQnKSkgew0KICAgICAgICAgICAgICAgIC8vaWYgKCR0aGlzLT5tYXN0ZXItPmRlbGV0ZSgnY2J0X3NvYWxfc2lzd2EnLCAkaWQsICdpZF9iYW5rJykpIHt9DQoJCQkJaWYgKCR0aGlzLT5tYXN0ZXItPmRlbGV0ZSgnY2J0X2Jhbmtfc29hbCcsICRpZCwgJ2lkX2JhbmsnKSkgew0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bG9nZ2luZy0+c2F2ZUxvZyg1LCAnbWVuZ2hhcHVzIGJhbmsgc29hbCcpOw0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+b3V0cHV0X2pzb24oWydzdGF0dXMnID0+IHRydWUsICdtZXNzYWdlJyA9PiAnYmVyaGFzaWwnIF0pOw0KCQkJCX0NCgkJCX0NCgkJfQ0KCX0NCg0KICAgIHB1YmxpYyBmdW5jdGlvbiBkZXRhaWwoJGlkKSB7DQogICAgICAgICR1c2VyID0gJHRoaXMtPmlvbl9hdXRoLT51c2VyKCktPnJvdygpOw0KICAgICAgICAkZGF0YSA9IFsNCiAgICAgICAgICAgICd1c2VyJyAgICAgID0+ICR1c2VyLA0KICAgICAgICAgICAgJ2p1ZHVsJwkgICAgPT4gJ0RldGFpbCBTb2FsJywNCiAgICAgICAgICAgICdzdWJqdWR1bCcgID0+ICdEZXRhaWwgU29hbCcNCiAgICAgICAgXTsNCiAgICAgICAgJGRhdGFbJ3NldHRpbmcnXSA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFNldHRpbmcoKTsNCg0KICAgICAgICAkdHAgPSAkdGhpcy0+bWFzdGVyLT5nZXRUYWh1bkFjdGl2ZSgpOw0KICAgICAgICAkc210ID0gJHRoaXMtPm1hc3Rlci0+Z2V0U2VtZXN0ZXJBY3RpdmUoKTsNCg0KICAgICAgICAkZGF0YVsndHAnXSA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFRhaHVuKCk7DQogICAgICAgICRkYXRhWyd0cF9hY3RpdmUnXSA9ICR0cDsNCiAgICAgICAgJGRhdGFbJ3NtdCddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0U2VtZXN0ZXIoKTsNCiAgICAgICAgJGRhdGFbJ3NtdF9hY3RpdmUnXSA9ICRzbXQ7DQogICAgICAgICRkYXRhWydiYW5rJ10gPSAkdGhpcy0+Y2J0LT5nZXREYXRhQmFua0J5SWQoJGlkKTsNCiAgICAgICAgJGRhdGFbJ3NvYWxzJ10gPSAkdGhpcy0+Y2J0LT5nZXRBbGxTb2FsQnlCYW5rKCRpZCk7DQogICAgICAgICRkYXRhWydrZWxhcyddID0gJHRoaXMtPmNidC0+Z2V0S2VsYXMoJHRwLT5pZF90cCwgJHNtdC0+aWRfc210KTsNCiAgICAgICAgaWYoJHRoaXMtPmlvbl9hdXRoLT5pc19hZG1pbigpKXsNCiAgICAgICAgICAgICRkYXRhWydwcm9maWxlJ10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRQcm9maWxlQWRtaW4oJHVzZXItPmlkKTsNCg0KICAgICAgICAgICAgJHRoaXMtPmxvYWQtPnZpZXcoJ190ZW1wbGF0ZXMvZGFzaGJvYXJkL19oZWFkZXInLCAkZGF0YSk7DQogICAgICAgICAgICAkdGhpcy0+bG9hZC0+dmlldygnY2J0L2Jhbmtzb2FsL2RldGFpbCcpOw0KICAgICAgICAgICAgJHRoaXMtPmxvYWQtPnZpZXcoJ190ZW1wbGF0ZXMvZGFzaGJvYXJkL19mb290ZXInKTsNCiAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAkZGF0YVsnZ3VydSddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0RGF0YUd1cnVCeVVzZXJJZCgkdXNlci0+aWQsICR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoNCiAgICAgICAgICAgICR0aGlzLT5sb2FkLT52aWV3KCdtZW1iZXJzL2d1cnUvdGVtcGxhdGVzL2hlYWRlcicsICRkYXRhKTsNCiAgICAgICAgICAgICR0aGlzLT5sb2FkLT52aWV3KCdjYnQvYmFua3NvYWwvZGV0YWlsJyk7DQogICAgICAgICAgICAkdGhpcy0+bG9hZC0+dmlldygnbWVtYmVycy9ndXJ1L3RlbXBsYXRlcy9mb290ZXInKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIHB1YmxpYyBmdW5jdGlvbiBzYXZlU2VsZWN0ZWQoKSB7DQogICAgICAgICRiYW5rX2lkID0gJHRoaXMtPmlucHV0LT5wb3N0KCdpZF9iYW5rJywgdHJ1ZSk7DQogICAgICAgICRqZW5pcyA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnamVuaXMnLCB0cnVlKTsNCiAgICAgICAgJHNvYWwgPSBjb3VudCgkdGhpcy0+aW5wdXQtPnBvc3QoJ3NvYWwnLCB0cnVlKSk7DQogICAgICAgICR1bmNoZWsgPSBqc29uX2RlY29kZSgkdGhpcy0+aW5wdXQtPnBvc3QoJ3VuY2hlY2snLCB0cnVlKSk7DQogICAgICAgICRhcnJJZCA9IFtdOw0KICAgICAgICBmb3IgKCRpID0gMDsgJGkgPD0gJHNvYWw7ICRpKyspIHsNCiAgICAgICAgICAgICRpZCA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnc29hbFsnLiRpLiddJywgdHJ1ZSk7DQogICAgICAgICAgICBpZiAoJGlkIT1udWxsKSBhcnJheV9wdXNoKCRhcnJJZCwgJGlkKTsNCiAgICAgICAgfQ0KDQogICAgICAgICR1cGRhdGVkID0gMDsNCiAgICAgICAgZm9yZWFjaCAoJGFycklkIGFzICRpZCkgew0KICAgICAgICAgICAgJHRoaXMtPmRiLT5zZXQoJ3RhbXBpbGthbicsIDEpOw0KICAgICAgICAgICAgJHRoaXMtPmRiLT53aGVyZSgnaWRfc29hbCcsICRpZCk7DQogICAgICAgICAgICAkdGhpcy0+ZGItPnVwZGF0ZSgnY2J0X3NvYWwnKTsNCiAgICAgICAgICAgICR1cGRhdGVkICsrOw0KICAgICAgICB9DQoNCiAgICAgICAgZm9yZWFjaCAoJHVuY2hlayBhcyAkaWQpIHsNCiAgICAgICAgICAgICR0aGlzLT5kYi0+c2V0KCd0YW1waWxrYW4nLCAwKTsNCiAgICAgICAgICAgICR0aGlzLT5kYi0+d2hlcmUoJ2lkX3NvYWwnLCAkaWQpOw0KICAgICAgICAgICAgJHRoaXMtPmRiLT51cGRhdGUoJ2NidF9zb2FsJyk7DQogICAgICAgIH0NCg0KICAgICAgICBzbGVlcCgxKTsNCiAgICAgICAgJGJhbmsgPSAkdGhpcy0+Y2J0LT5nZXREYXRhQmFua0J5SWQoJGJhbmtfaWQpOw0KICAgICAgICAkc29hbHMgPSAkdGhpcy0+Y2J0LT5nZXRBbGxTb2FsQnlCYW5rKCRiYW5rX2lkKTsNCg0KICAgICAgICAkdG90YWxfc29hbF90YW1waWwgPSBpc3NldChhcnJheV9jb3VudF92YWx1ZXMoYXJyYXlfY29sdW1uKCRzb2FscywgJ3RhbXBpbGthbicpKVsnMSddKSA/IGFycmF5X2NvdW50X3ZhbHVlcyhhcnJheV9jb2x1bW4oJHNvYWxzLCAndGFtcGlsa2FuJykpWycxJ10gOiAwOw0KICAgICAgICAkdG90YWxfc29hbF9zZWhhcnVzbnlhX3RhbXBpbCA9ICRiYW5rLT50YW1waWxfcGcgKyAkYmFuay0+dGFtcGlsX2tvbXBsZWtzICsgJGJhbmstPnRhbXBpbF9qb2RvaGthbiArICRiYW5rLT50YW1waWxfaXNpYW4gKyAkYmFuay0+dGFtcGlsX2VzYWk7DQogICAgICAgICR0YW1waWxfa3VyYW5nID0gJHRvdGFsX3NvYWxfdGFtcGlsIDwgJHRvdGFsX3NvYWxfc2VoYXJ1c255YV90YW1waWw7DQogICAgICAgICRzdGF0dXNfc29hbCA9ICR0YW1waWxfa3VyYW5nID8gJzAnIDogJzEnOw0KDQogICAgICAgICR0aGlzLT5kYi0+c2V0KCdzdGF0dXNfc29hbCcsICRzdGF0dXNfc29hbCk7DQogICAgICAgICR0aGlzLT5kYi0+d2hlcmUoJ2lkX2JhbmsnLCAkYmFua19pZCk7DQogICAgICAgICR0aGlzLT5kYi0+dXBkYXRlKCdjYnRfYmFua19zb2FsJyk7DQoNCiAgICAgICAgJGRhdGFbJ2NoZWNrJ10gPSAkdXBkYXRlZDsNCiAgICAgICAgJHRoaXMtPm91dHB1dF9qc29uKCRkYXRhKTsNCiAgICB9DQoNCiAgICBwdWJsaWMgZnVuY3Rpb24gY29weUJhbmtTb2FsKCRpZF9iYW5rKSB7DQogICAgICAgICR0cCA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFRhaHVuQWN0aXZlKCk7DQogICAgICAgICRzbXQgPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRTZW1lc3RlckFjdGl2ZSgpOw0KICAgICAgICAkYmFuayA9ICR0aGlzLT5jYnQtPmdldERhdGFCYW5rQnlJZCgkaWRfYmFuayk7DQogICAgICAgICRzb2FscyA9ICR0aGlzLT5jYnQtPmdldEFsbFNvYWxCeUJhbmsoJGlkX2JhbmspOw0KDQogICAgICAgICRkYXRhID0gWw0KICAgICAgICAgICAgJ2lkX3RwJyAgICAgICAgICAgICA9PiAkdHAtPmlkX3RwLA0KICAgICAgICAgICAgJ2lkX3NtdCcgICAgICAgICAgICA9PiRzbXQtPmlkX3NtdCwNCiAgICAgICAgICAgICdiYW5rX2plbmlzX2lkJyAgICAgPT4gJGJhbmstPmJhbmtfamVuaXNfaWQsDQogICAgICAgICAgICAnYmFua19rb2RlJyAgICAgICAgID0+JGJhbmstPmJhbmtfa29kZSwNCiAgICAgICAgICAgICdiYW5rX2xldmVsJyAgICAgICAgPT4gJGJhbmstPmJhbmtfbGV2ZWwsDQogICAgICAgICAgICAnYmFua19rZWxhcycgICAgICAgID0+ICRiYW5rLT5iYW5rX2tlbGFzLA0KICAgICAgICAgICAgJ2JhbmtfbWFwZWxfaWQnICAgICA9PiAkYmFuay0+YmFua19tYXBlbF9pZCwNCiAgICAgICAgICAgICdiYW5rX2p1cnVzYW5faWQnICAgPT4gJGJhbmstPmJhbmtfanVydXNhbl9pZCwNCiAgICAgICAgICAgICdiYW5rX2d1cnVfaWQnICAgICAgPT4gJGJhbmstPmJhbmtfZ3VydV9pZCwNCiAgICAgICAgICAgICdiYW5rX25hbWEnICAgICAgICAgPT4gJGJhbmstPmJhbmtfbmFtYSwNCiAgICAgICAgICAgICdra20nICAgICAgICAgICAgICAgPT4gJGJhbmstPmtrbSwNCiAgICAgICAgICAgICdkZXNrcmlwc2knICAgICAgICAgPT4gJGJhbmstPmRlc2tyaXBzaSwNCiAgICAgICAgICAgICdqbWxfc29hbCcgICAgICAgICAgPT4gJGJhbmstPmptbF9zb2FsLA0KICAgICAgICAgICAgJ3RhbXBpbF9wZycgICAgICAgICA9PiAkYmFuay0+dGFtcGlsX3BnLA0KICAgICAgICAgICAgJ2JvYm90X3BnJyAgICAgICAgICA9PiAkYmFuay0+Ym9ib3RfcGcsDQogICAgICAgICAgICAnam1sX2tvbXBsZWtzJyAgICAgID0+ICRiYW5rLT5qbWxfa29tcGxla3MsDQogICAgICAgICAgICAndGFtcGlsX2tvbXBsZWtzJyAgID0+ICRiYW5rLT50YW1waWxfa29tcGxla3MsDQogICAgICAgICAgICAnYm9ib3Rfa29tcGxla3MnICAgID0+ICRiYW5rLT5ib2JvdF9rb21wbGVrcywNCiAgICAgICAgICAgICdqbWxfam9kb2hrYW4nICAgICAgPT4gJGJhbmstPmptbF9qb2RvaGthbiwNCiAgICAgICAgICAgICd0YW1waWxfam9kb2hrYW4nICAgPT4gJGJhbmstPnRhbXBpbF9qb2RvaGthbiwNCiAgICAgICAgICAgICdib2JvdF9qb2RvaGthbicgICAgPT4gJGJhbmstPmJvYm90X2pvZG9oa2FuLA0KICAgICAgICAgICAgJ2ptbF9pc2lhbicgICAgICAgICA9PiAkYmFuay0+am1sX2lzaWFuLA0KICAgICAgICAgICAgJ3RhbXBpbF9pc2lhbicgICAgICA9PiAkYmFuay0+dGFtcGlsX2lzaWFuLA0KICAgICAgICAgICAgJ2JvYm90X2lzaWFuJyAgICAgICA9PiAkYmFuay0+Ym9ib3RfaXNpYW4sDQogICAgICAgICAgICAnam1sX2VzYWknICAgICAgICAgID0+ICRiYW5rLT5qbWxfZXNhaSwNCiAgICAgICAgICAgICd0YW1waWxfZXNhaScgICAgICAgPT4gJGJhbmstPnRhbXBpbF9lc2FpLA0KICAgICAgICAgICAgJ2JvYm90X2VzYWknICAgICAgICA9PiAkYmFuay0+Ym9ib3RfZXNhaSwNCiAgICAgICAgICAgICdvcHNpJyAgICAgICAgICAgICAgPT4gJGJhbmstPm9wc2ksDQogICAgICAgICAgICAnZGF0ZScgICAgICAgICAgICAgID0+IGRhdGUoJ1ktbS1kIEg6aTpzJyksDQogICAgICAgICAgICAnc3RhdHVzJyAgICAgICAgICAgID0+ICRiYW5rLT5zdGF0dXMsDQogICAgICAgICAgICAnc29hbF9hZ2FtYScgICAgICAgID0+ICRiYW5rLT5zb2FsX2FnYW1hDQogICAgICAgIF07DQoNCiAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5tYXN0ZXItPmNyZWF0ZSgnY2J0X2Jhbmtfc29hbCcsICRkYXRhKTsNCiAgICAgICAgJGlkID0gJHRoaXMtPmRiLT5pbnNlcnRfaWQoKTsNCiAgICAgICAgZm9yZWFjaCAoJHNvYWxzIGFzICRzb2FsKSB7DQogICAgICAgICAgICB1bnNldCgkc29hbC0+aWRfc29hbCk7DQogICAgICAgICAgICAkc29hbC0+YmFua19pZCA9ICRpZDsNCiAgICAgICAgICAgICRzb2FsLT5jcmVhdGVkX29uID0gdGltZSgpOw0KICAgICAgICAgICAgJHNvYWwtPnVwZGF0ZWRfb24gPSB0aW1lKCk7DQogICAgICAgIH0NCiAgICAgICAgJHRoaXMtPmRiLT5pbnNlcnRfYmF0Y2goJ2NidF9zb2FsJywgJHNvYWxzKTsNCg0KICAgICAgICAvLyRyZXN1bHRbJ3N0YXR1cyddID0gJ01hdGVyaSBiZXJoYXNpbCBkaWJ1YXQnOw0KICAgICAgICAkdGhpcy0+bG9nZ2luZy0+c2F2ZUxvZygzLCAnbWVtYnVhdCBiYW5rIHNvYWwnKTsNCg0KICAgICAgICAkdGhpcy0+b3V0cHV0X2pzb24oJHJlc3VsdCk7DQogICAgfQ0KDQoJcHVibGljIGZ1bmN0aW9uIGJ1YXRzb2FsKCRpZF9iYW5rKSB7DQoJCS8vJGlkID0gJHRoaXMtPmlucHV0LT5wb3N0KCdpZF9iYW5rJywgdHJ1ZSk7DQoJCSR1c2VyID0gJHRoaXMtPmlvbl9hdXRoLT51c2VyKCktPnJvdygpOw0KCQkkZGF0YSA9IFsNCgkJCSd1c2VyJyAgICAgID0+ICR1c2VyLA0KCQkJJ2p1ZHVsJwkgICAgPT4gJ0J1YXQgU29hbCcsDQoJCQknc3VianVkdWwnICA9PiAnQnVhdCBTb2FsJw0KCQldOw0KDQoJCSR0cCA9ICR0aGlzLT5tYXN0ZXItPmdldFRhaHVuQWN0aXZlKCk7DQoJCSRzbXQgPSAkdGhpcy0+bWFzdGVyLT5nZXRTZW1lc3RlckFjdGl2ZSgpOw0KDQoJCSRkYXRhWyd0cCddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0VGFodW4oKTsNCgkJJGRhdGFbJ3RwX2FjdGl2ZSddID0gJHRwOw0KCQkkZGF0YVsnc210J10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRTZW1lc3RlcigpOw0KCQkkZGF0YVsnc210X2FjdGl2ZSddID0gJHNtdDsNCg0KCQkkc2V0dGluZyA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFNldHRpbmcoKTsNCiAgICAgICAgJGRhdGFbJ3NldHRpbmcnXSA9ICRzZXR0aW5nOw0KDQogICAgICAgICR0YWIgPSAkdGhpcy0+aW5wdXQtPmdldCgndGFiJywgdHJ1ZSk7DQogICAgICAgICRqZW5pcyA9ICR0YWIgPT0gbnVsbCA/ICIxIiA6ICR0YWI7DQogICAgICAgICRkYXRhWyd0YWJfYWN0aXZlJ10gPSAkamVuaXM7DQogICAgICAgICRiYW5rID0gJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmtCeUlkKCRpZF9iYW5rKTsNCg0KICAgICAgICAkZGF0YVsnc29hbCddID0gbnVsbDsvLyR0aGlzLT5jYnQtPmdldFNvYWxCeUlkQmFuaygkaWRfYmFuaywgJGplbmlzKTsNCgkJJGRhdGFbJ3NvYWxfYWRhJ10gPSAkdGhpcy0+Y2J0LT5jZWtTb2FsQWRhKCRpZF9iYW5rLCAkamVuaXMpOw0KICAgICAgICAkZGF0YVsnc29hbF9iZWx1bV9rb21wbGl0J10gPSAkdGhpcy0+Y2J0LT5jZWtTb2FsQmVsdW1Lb21wbGl0KCRpZF9iYW5rLCAkamVuaXMsICRzZXR0aW5nLT5qZW5qYW5nKTsNCg0KICAgICAgICAvLyR0b3RhbF9wZyA9ICRiYW5rLT5qbWxfc29hbDsNCiAgICAgICAgLy8kam1sX3NvYWxfcGcgPSAkdGhpcy0+Y2J0LT5nZXRUb3RhbFNvYWwoJGlkX2JhbmssIDEpOw0KICAgICAgICBpZiAoJGplbmlzID09ICIxIikgJGRhdGFbJ2ptbF9wZyddID0gJHRoaXMtPmNidC0+Z2V0Tm9tb3JTb2FsVGVyYmVzYXIoJGlkX2JhbmssIDEpOw0KICAgICAgICBlbHNlaWYgKCRqZW5pcyA9PSAiMiIpICRkYXRhWydqbWxfcGcyJ10gPSAkdGhpcy0+Y2J0LT5nZXROb21vclNvYWxUZXJiZXNhcigkaWRfYmFuaywgMik7DQogICAgICAgIGVsc2VpZiAoJGplbmlzID09ICIzIikgJGRhdGFbJ2ptbF9qb2RvaGthbiddID0gJHRoaXMtPmNidC0+Z2V0Tm9tb3JTb2FsVGVyYmVzYXIoJGlkX2JhbmssIDMpOw0KICAgICAgICBlbHNlaWYgKCRqZW5pcyA9PSAiNCIpICRkYXRhWydqbWxfaXNpYW4nXSA9ICR0aGlzLT5jYnQtPmdldE5vbW9yU29hbFRlcmJlc2FyKCRpZF9iYW5rLCA0KTsNCiAgICAgICAgZWxzZWlmICgkamVuaXMgPT0gIjUiKSAkZGF0YVsnam1sX2Vzc2FpJ10gPSAkdGhpcy0+Y2J0LT5nZXROb21vclNvYWxUZXJiZXNhcigkaWRfYmFuaywgNSk7DQogICAgICAgIC8vJGRhdGFbJ2ptbF90b3RhbCddID0gJHRoaXMtPmNidC0+Z2V0VG90YWxTb2FsKCRpZF9iYW5rKTsNCiAgICAgICAgJGRhdGFbJ2JhbmsnXSA9ICRiYW5rOw0KDQogICAgICAgICRkYXRhWydzb2FscyddID0gJHRoaXMtPmNidC0+Z2V0QWxsU29hbEJ5QmFuaygkaWRfYmFuaywgJGplbmlzKTsNCgkJJGRhdGFbJ2p1cnVzYW4nXSA9ICR0aGlzLT5jYnQtPmdldEFsbEp1cnVzYW4oKTsNCgkJJGRhdGFbJ2xldmVsJ10gPSAkdGhpcy0+ZHJvcGRvd24tPmdldEFsbExldmVsKCRzZXR0aW5nLT5qZW5qYW5nKTsNCgkJJGRhdGFbJ2tlbGFzJ10gPSAkdGhpcy0+ZHJvcGRvd24tPmdldEFsbEtlbGFzKCR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoNCgkJaWYoJHRoaXMtPmlvbl9hdXRoLT5pc19hZG1pbigpKXsNCiAgICAgICAgICAgICRkYXRhWydwcm9maWxlJ10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRQcm9maWxlQWRtaW4oJHVzZXItPmlkKTsNCg0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ190ZW1wbGF0ZXMvZGFzaGJvYXJkL19oZWFkZXInLCAkZGF0YSk7DQoJCQkkdGhpcy0+bG9hZC0+dmlldygnY2J0L2Jhbmtzb2FsL3NvYWwnKTsNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdfdGVtcGxhdGVzL2Rhc2hib2FyZC9fZm9vdGVyJyk7DQoJCX0gZWxzZSB7DQogICAgICAgICAgICAkZGF0YVsnZ3VydSddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0RGF0YUd1cnVCeVVzZXJJZCgkdXNlci0+aWQsICR0cC0+aWRfdHAsICRzbXQtPmlkX3NtdCk7DQoNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdtZW1iZXJzL2d1cnUvdGVtcGxhdGVzL2hlYWRlcicsICRkYXRhKTsNCiAgICAgICAgICAgICR0aGlzLT5sb2FkLT52aWV3KCdjYnQvYmFua3NvYWwvc29hbCcpOw0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ21lbWJlcnMvZ3VydS90ZW1wbGF0ZXMvZm9vdGVyJyk7DQoJCX0NCgl9DQoNCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U29hbEJ5Tm9tb3IoKSB7DQogICAgICAgICRiYW5rX2lkID0gJHRoaXMtPmlucHV0LT5nZXQoJ2JhbmtfaWQnLCB0cnVlKTsNCiAgICAgICAgJG5vbW9yID0gJHRoaXMtPmlucHV0LT5nZXQoJ25vbW9yJywgdHJ1ZSk7DQogICAgICAgICRqZW5pcyA9ICR0aGlzLT5pbnB1dC0+Z2V0KCdqZW5pcycsIHRydWUpOw0KICAgICAgICAkc29hbCA9ICR0aGlzLT5jYnQtPmdldFNvYWxCeU5vbW9yKCRiYW5rX2lkLCAkbm9tb3IsICRqZW5pcyk7DQogICAgICAgICRkYXRhID0gJHNvYWw7DQogICAgICAgIGlmICgkZGF0YSAhPSBudWxsKSB7DQogICAgICAgICAgICAkZGF0YS0+ZmlsZSA9IHVuc2VyaWFsaXplKCRzb2FsLT5maWxlKTsNCiAgICAgICAgICAgIGlmICgkamVuaXMgPT0gJzInKSB7DQogICAgICAgICAgICAgICAgJHQgPSBAdW5zZXJpYWxpemUoJHNvYWwtPm9wc2lfYSk7DQogICAgICAgICAgICAgICAgaWYgKCR0ICE9PSBmYWxzZSkgJGRhdGEtPm9wc2lfYSA9ICR0Ow0KICAgICAgICAgICAgICAgIGVsc2UgKCRkYXRhLT5vcHNpX2EgPSBmYWxzZSk7DQoNCiAgICAgICAgICAgICAgICAkaiA9IEB1bnNlcmlhbGl6ZSgkc29hbC0+amF3YWJhbik7DQogICAgICAgICAgICAgICAgaWYgKCRqICE9PSBmYWxzZSkgJGRhdGEtPmphd2FiYW4gPSAkajsNCiAgICAgICAgICAgICAgICBlbHNlICgkZGF0YS0+amF3YWJhbiA9IGZhbHNlKTsNCiAgICAgICAgICAgIH0gZWxzZWlmICgkamVuaXMgPT0gJzMnKSB7DQogICAgICAgICAgICAgICAgJGogPSBAdW5zZXJpYWxpemUoJHNvYWwtPmphd2FiYW4pOw0KICAgICAgICAgICAgICAgIGlmICgkaiAhPT0gZmFsc2UpICRkYXRhLT5qYXdhYmFuID0gJGo7DQogICAgICAgICAgICAgICAgZWxzZSAoJGRhdGEtPmphd2FiYW4gPSBmYWxzZSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgJHRoaXMtPm91dHB1dF9qc29uKCRkYXRhKTsNCiAgICB9DQoNCiAgICBwdWJsaWMgZnVuY3Rpb24gdGFtYmFoU29hbCgpew0KICAgICAgICAkYmFuayA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnYmFuaycsIHRydWUpOw0KICAgICAgICAkbm9tb3IgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ25vbW9yJywgdHJ1ZSk7DQogICAgICAgICRqZW5pcyA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnamVuaXMnLCB0cnVlKTsNCg0KICAgICAgICAkZGF0YSA9IFsNCiAgICAgICAgICAgICdiYW5rX2lkJwkJPT4gJGJhbmssDQogICAgICAgICAgICAnbm9tb3Jfc29hbCcJPT4gJG5vbW9yLA0KICAgICAgICAgICAgJ2plbmlzJwkJCT0+ICRqZW5pcywNCiAgICAgICAgICAgICd0YW1waWxrYW4nCQk9PiAwLA0KICAgICAgICAgICAgJ2NyZWF0ZWRfb24nCT0+IHRpbWUoKSwNCiAgICAgICAgICAgICd1cGRhdGVkX29uJwk9PiB0aW1lKCkNCiAgICAgICAgXTsNCg0KICAgICAgICAkaW5zZXJ0ID0gJHRoaXMtPmRiLT5pbnNlcnQoJ2NidF9zb2FsJywgJGRhdGEpOw0KICAgICAgICAkdGhpcy0+b3V0cHV0X2pzb24oJGluc2VydCk7DQogICAgfQ0KDQoJcHVibGljIGZ1bmN0aW9uIGltcG9ydHNvYWwoJGlkKSB7DQoJCSR1c2VyID0gJHRoaXMtPmlvbl9hdXRoLT51c2VyKCktPnJvdygpOw0KICAgICAgICAkc2V0dGluZyA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldFNldHRpbmcoKTsNCgkJJGRhdGEgPSBbDQoJCQkndXNlcicgICAgICA9PiAkdXNlciwNCgkJCSdqdWR1bCcJICAgID0+ICdJbXBvcnQgQmFuayBTb2FsJywNCgkJCSdzdWJqdWR1bCcgID0+ICdJbXBvcnQgQmFuayBTb2FsJw0KCQldOw0KDQoJCSR0cCA9ICR0aGlzLT5tYXN0ZXItPmdldFRhaHVuQWN0aXZlKCk7DQoJCSRzbXQgPSAkdGhpcy0+bWFzdGVyLT5nZXRTZW1lc3RlckFjdGl2ZSgpOw0KDQoJCSRkYXRhWyd0cCddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0VGFodW4oKTsNCgkJJGRhdGFbJ3RwX2FjdGl2ZSddID0gJHRwOw0KCQkkZGF0YVsnc210J10gPSAkdGhpcy0+ZGFzaGJvYXJkLT5nZXRTZW1lc3RlcigpOw0KCQkkZGF0YVsnc210X2FjdGl2ZSddID0gJHNtdDsNCg0KCQkkZGF0YVsnc2V0dGluZyddID0gJHNldHRpbmc7DQoJCSRkYXRhWydiYW5rJ10gPSAkdGhpcy0+Y2J0LT5nZXREYXRhQmFua0J5SWQoJGlkKTsNCgkJJGRhdGFbJ2plbmlzJ10gPSAkdGhpcy0+Y2J0LT5nZXRBbGxKZW5pc1VqaWFuKCk7DQoJCSRkYXRhWydqdXJ1c2FuJ10gPSAkdGhpcy0+Y2J0LT5nZXRBbGxKdXJ1c2FuKCk7DQoJCSRkYXRhWydsZXZlbCddID0gJHRoaXMtPmRyb3Bkb3duLT5nZXRBbGxMZXZlbCgkc2V0dGluZy0+amVuamFuZyk7DQoJCSRkYXRhWydrZWxhcyddID0gJHRoaXMtPmRyb3Bkb3duLT5nZXRBbGxLZWxhcygkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KDQoJCWlmKCR0aGlzLT5pb25fYXV0aC0+aXNfYWRtaW4oKSl7DQogICAgICAgICAgICAkZGF0YVsncHJvZmlsZSddID0gJHRoaXMtPmRhc2hib2FyZC0+Z2V0UHJvZmlsZUFkbWluKCR1c2VyLT5pZCk7DQoNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdfdGVtcGxhdGVzL2Rhc2hib2FyZC9faGVhZGVyJywgJGRhdGEpOw0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ2NidC9iYW5rc29hbC9pbXBvcnQnKTsNCgkJCSR0aGlzLT5sb2FkLT52aWV3KCdfdGVtcGxhdGVzL2Rhc2hib2FyZC9fZm9vdGVyJyk7DQoJCX1lbHNlew0KICAgICAgICAgICAgJGRhdGFbJ2d1cnUnXSA9ICR0aGlzLT5kYXNoYm9hcmQtPmdldERhdGFHdXJ1QnlVc2VySWQoJHVzZXItPmlkLCAkdHAtPmlkX3RwLCAkc210LT5pZF9zbXQpOw0KDQoJCQkkdGhpcy0+bG9hZC0+dmlldygnbWVtYmVycy9ndXJ1L3RlbXBsYXRlcy9oZWFkZXInLCAkZGF0YSk7DQogICAgICAgICAgICAkdGhpcy0+bG9hZC0+dmlldygnY2J0L2Jhbmtzb2FsL2ltcG9ydCcpOw0KCQkJJHRoaXMtPmxvYWQtPnZpZXcoJ21lbWJlcnMvZ3VydS90ZW1wbGF0ZXMvZm9vdGVyJyk7DQoJCX0NCgl9DQoNCglwdWJsaWMgZnVuY3Rpb24gcHJldmlld0V4Y2VsKCkgew0KCQkkY29uZmlnWyd1cGxvYWRfcGF0aCddCQk9ICcuL3VwbG9hZHMvaW1wb3J0Lyc7DQoJCSRjb25maWdbJ2FsbG93ZWRfdHlwZXMnXQk9ICd4bHN8eGxzeHxjc3YnOw0KCQkkY29uZmlnWydtYXhfc2l6ZSddCQkJPSAyMDQ4Ow0KCQkkY29uZmlnWydlbmNyeXB0X25hbWUnXQkJPSB0cnVlOw0KDQoJCSR0aGlzLT5sb2FkLT5saWJyYXJ5KCd1cGxvYWQnLCAkY29uZmlnKTsNCg0KCQlpZiAoISR0aGlzLT51cGxvYWQtPmRvX3VwbG9hZCgndXBsb2FkX2ZpbGUnKSkgew0KCQkJJGVycm9yID0gJHRoaXMtPnVwbG9hZC0+ZGlzcGxheV9lcnJvcnMoKTsNCgkJCWVjaG8gJGVycm9yOw0KCQkJZGllOw0KCQl9IGVsc2Ugew0KCQkJJGZpbGUgPSAkdGhpcy0+dXBsb2FkLT5kYXRhKCdmdWxsX3BhdGgnKTsNCgkJCSRleHQgPSAkdGhpcy0+dXBsb2FkLT5kYXRhKCdmaWxlX2V4dCcpOw0KDQoJCQlzd2l0Y2ggKCRleHQpIHsNCgkJCQljYXNlICcueGxzeCc6DQoJCQkJCSRyZWFkZXIgPSBuZXcgXFBocE9mZmljZVxQaHBTcHJlYWRzaGVldFxSZWFkZXJcWGxzeCgpOw0KCQkJCQlicmVhazsNCgkJCQljYXNlICcueGxzJzoNCgkJCQkJJHJlYWRlciA9IG5ldyBcUGhwT2ZmaWNlXFBocFNwcmVhZHNoZWV0XFJlYWRlclxYbHMoKTsNCgkJCQkJYnJlYWs7DQoJCQkJY2FzZSAnLmNzdic6DQoJCQkJCSRyZWFkZXIgPSBuZXcgXFBocE9mZmljZVxQaHBTcHJlYWRzaGVldFxSZWFkZXJcQ3N2KCk7DQoJCQkJCWJyZWFrOw0KCQkJCWRlZmF1bHQ6DQoJCQkJCWVjaG8gInVua25vd24gZmlsZSBleHQiOw0KCQkJCQlkaWU7DQoJCQl9DQoNCgkJCSRzcHJlYWRzaGVldCA9ICRyZWFkZXItPmxvYWQoJGZpbGUpOw0KCQkJJHNoZWV0RGF0YSA9ICRzcHJlYWRzaGVldC0+Z2V0QWN0aXZlU2hlZXQoKS0+dG9BcnJheSgpOw0KCQkJJGRhdGEgPSBbXTsNCgkJCWZvciAoJGkgPSAxOyAkaSA8IGNvdW50KCRzaGVldERhdGEpOyAkaSsrKSB7DQoJCQkJaWYgKCRzaGVldERhdGFbJGldWzBdICE9IG51bGwpIHsNCgkJCQkJJGRhdGFbXSA9IFsNCgkJCQkJCSduYW1hJyA9PiAkc2hlZXREYXRhWyRpXVsxXSwNCgkJCQkJCSduaXAnID0+ICRzaGVldERhdGFbJGldWzJdLA0KCQkJCQkJJ2tvZGUnID0+ICRzaGVldERhdGFbJGldWzNdLA0KCQkJCQkJJ3VzZXJuYW1lJyA9PiAkc2hlZXREYXRhWyRpXVs0XSwNCgkJCQkJCSdwYXNzd29yZCcgPT4gJHNoZWV0RGF0YVskaV1bNV0sDQoJCQkJCV07DQoJCQkJCS8vJGp1cnVzYW5bXSA9ICRzaGVldERhdGFbJGldWzBdOw0KCQkJCX0NCgkJCX0NCg0KCQkJdW5saW5rKCRmaWxlKTsNCgkJCWVjaG8ganNvbl9lbmNvZGUoJGRhdGEpOw0KCQl9DQoJfQ0KDQoJcHVibGljIGZ1bmN0aW9uIHByZXZpZXdXb3JkKCRpZF9iYW5rKSB7DQoJCSRjb25maWdbJ3VwbG9hZF9wYXRoJ10JCT0gJy4vdXBsb2Fkcy9pbXBvcnQnOw0KCQkkY29uZmlnWydhbGxvd2VkX3R5cGVzJ10JPSAnZG9jeCc7DQoJCSRjb25maWdbJ21heF9zaXplJ10JCQk9IDIwNDg7DQoJCSRjb25maWdbJ2VuY3J5cHRfbmFtZSddCQk9IHRydWU7DQoNCgkJLy8kdGhpcy0+bG9hZC0+bGlicmFyeSgndXBsb2FkJywgJGNvbmZpZyk7DQoJCSR0aGlzLT51cGxvYWQtPmluaXRpYWxpemUoJGNvbmZpZyk7DQoNCgkJaWYgKCEkdGhpcy0+dXBsb2FkLT5kb191cGxvYWQoJ3VwbG9hZF9maWxlJykpIHsNCgkJCSRlcnJvciA9ICR0aGlzLT51cGxvYWQtPmRpc3BsYXlfZXJyb3JzKCk7DQoJCQllY2hvICRlcnJvcjsNCgkJCWRpZTsNCgkJfSBlbHNlIHsNCgkJCSRmaWxlID0gJHRoaXMtPnVwbG9hZC0+ZGF0YSgnZnVsbF9wYXRoJyk7DQoJCQkkcGhwV29yZCA9IFxQaHBPZmZpY2VcUGhwV29yZFxJT0ZhY3Rvcnk6OmxvYWQoJGZpbGUpOw0KCQkJJGh0bWxXcml0ZXIgPSBuZXcgXFBocE9mZmljZVxQaHBXb3JkXFdyaXRlclxIVE1MKCRwaHBXb3JkKTsNCgkJCXRyeSB7DQoJCQkJJGh0bWxXcml0ZXItPnNhdmUoJy4vdXBsb2Fkcy90ZW1wL2RvYy5odG1sJyk7DQoJCQkJLy8kaHRtbFdyaXRlci0+c2F2ZSgicGhwOi8vb3V0cHV0Iik7DQoJCQl9IGNhdGNoIChcUGhwT2ZmaWNlXFBocFdvcmRcRXhjZXB0aW9uXEV4Y2VwdGlvbiAkZSkgew0KCQkJfQ0KDQoJCQl1bmxpbmsoJGZpbGUpOw0KCQkJJHRleHQgPSBmaWxlX2dldF9jb250ZW50cygnLi91cGxvYWRzL3RlbXAvZG9jLmh0bWwnKTsNCg0KCQkJJGRvbSA9IG5ldyBET01Eb2N1bWVudCgpOw0KICAgICAgICAgICAgJGRvbS0+cHJlc2VydmVXaGl0ZVNwYWNlID0gZmFsc2U7DQogICAgICAgICAgICAkZG9tLT5mb3JtYXRPdXRwdXQgPSB0cnVlOw0KCQkJJGRvbS0+bG9hZEhUTUwoJHRleHQpOw0KDQoJCQkkaW1hZ2VzID0gJGRvbS0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ2ltZycpOw0KCQkJJG51bWltZyA9IDE7DQoJCQlmb3JlYWNoICgkaW1hZ2VzIGFzICRpbWFnZSkgew0KCQkJCSRiYXNlNjRfaW1hZ2Vfc3RyaW5nID0gJGltYWdlLT5nZXRBdHRyaWJ1dGUoJ3NyYycpOw0KCQkJCS8vZWNobyAkaW1hZ2UtPmdldEF0dHJpYnV0ZSgnc3JjJykgLiAiXG4iOw0KDQoJCQkJLy91c2FnZTogIGlmKCBzdWJzdHIoICRpbWdfc3JjLCAwLCA1ICkgPT09ICJkYXRhOiIgKSB7ICAkZmlsZW5hbWU9c2F2ZV9iYXNlNjRfaW1hZ2UoJGJhc2U2NF9pbWFnZV9zdHJpbmcsICRvdXRwdXRfZmlsZV93aXRob3V0X2V4dGVudG5pb24sIGdldGN3ZCgpIC4gIi9hcHBsaWNhdGlvbi9hc3NldHMvcGlucy8kdXNlcl9pZC8iKTsgfQ0KCQkJCS8vZGF0YSBpcyBsaWtlOiAgICBkYXRhOmltYWdlL3BuZztiYXNlNjQsYXNkZmFzZGZhc2RmDQoJCQkJJHNwbGl0ZWQgPSBleHBsb2RlKCcsJywgc3Vic3RyKCAkYmFzZTY0X2ltYWdlX3N0cmluZyAsIDUgKSAsIDIpOw0KCQkJCSRtaW1lPSRzcGxpdGVkWzBdOw0KCQkJCSRkYXRhPSRzcGxpdGVkWzFdOw0KDQoJCQkJJG1pbWVfc3BsaXRfd2l0aG91dF9iYXNlNjQ9ZXhwbG9kZSgnOycsICRtaW1lLDIpOw0KCQkJCSRtaW1lX3NwbGl0PWV4cGxvZGUoJy8nLCAkbWltZV9zcGxpdF93aXRob3V0X2Jhc2U2NFswXSwyKTsNCgkJCQlpZihjb3VudCgkbWltZV9zcGxpdCk9PTIpDQoJCQkJew0KCQkJCQkkZXh0ZW5zaW9uPSRtaW1lX3NwbGl0WzFdOw0KCQkJCQlpZigkZXh0ZW5zaW9uPT0nanBlZycpJGV4dGVuc2lvbj0nanBnJzsNCgkJCQkJJG91dHB1dF9maWxlID0gJ2ltZ18nLiRpZF9iYW5rLiRudW1pbWcuJy4nLiRleHRlbnNpb247DQoJCQkJfQ0KCQkJCWZpbGVfcHV0X2NvbnRlbnRzKCAnLi91cGxvYWRzL2Jhbmtfc29hbC8nIC4gJG91dHB1dF9maWxlLCBiYXNlNjRfZGVjb2RlKCRkYXRhKSApOw0KCQkJCSRpbWFnZS0+c2V0QXR0cmlidXRlKCdzcmMnLCAndXBsb2Fkcy9iYW5rX3NvYWwvJyAuICRvdXRwdXRfZmlsZSk7DQoJCQkJJG51bWltZyArKzsNCgkJCQkvL3JldHVybiAkb3V0cHV0X2ZpbGVfd2l0aF9leHRlbnNpb247DQoJCQl9DQoNCgkJCSRuZXdodG1sID0gJGRvbS0+c2F2ZUhUTUwoKTsNCgkJCS8qDQoJCQkkZG9tLT5sb2FkSFRNTCgkbmV3aHRtbCk7DQoJCQkkZGF0YSA9IFtdOw0KCQkJJHRhYmxlcyA9ICRkb20tPmdldEVsZW1lbnRzQnlUYWdOYW1lKCd0YWJsZScpOw0KICAgICAgICAgICAgJGFyckplbmlzID0gWycxJywgJzInLCAnMycsICc0JywgJzUnXTsNCiAgICAgICAgICAgICRVUFBFUkNBU0VfTEVUVEVSUyA9IHJhbmdlKGNocig2NSksY2hyKDkwKSk7DQogICAgICAgICAgICAkTE9XRVJDQVNFX0xFVFRFUlMgPSByYW5nZShjaHIoOTcpLGNocigxMjIpKTsNCiAgICAgICAgICAgICROVU1CRVJTX1pFUk9fVEhST1VHSF9OSU5FID0gcmFuZ2UoY2hyKDQ4KSxjaHIoNTcpKTsNCg0KDQogICAgICAgICAgICBmb3IgKCR0PTA7JHQ8JHRhYmxlcy0+Y291bnQoKTsgJHQrKykgew0KICAgICAgICAgICAgICAgICRyb3dzID0gJHRhYmxlcy0+aXRlbSgwKS0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RyJyk7DQogICAgICAgICAgICAgICAgJG5vcCA9IDE7DQogICAgICAgICAgICAgICAgZm9yICgkaSA9IDE7ICRpIDwgJHJvd3MtPmNvdW50KCk7ICRpKyspIHsNCiAgICAgICAgICAgICAgICAgICAgJGNvbHMgPSAkcm93c1skaV0tPmdldEVsZW1lbnRzQnlUYWdOYW1lKCd0ZCcpOw0KDQogICAgICAgICAgICAgICAgICAgICRub21vciA9IHRyaW0oJGNvbHMtPml0ZW0oMCktPm5vZGVWYWx1ZSk7DQogICAgICAgICAgICAgICAgICAgICRub21vcl9rb3NvbmcgPSAoaW50KSRub21vciA9PT0gMDsNCg0KICAgICAgICAgICAgICAgICAgICAkZ2FtYmFyID0gJGNvbHMtPml0ZW0oMSktPmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpbWcnKTsNCiAgICAgICAgICAgICAgICAgICAgJHNvYWxfZ2FtYmFyID0gJGdhbWJhci0+Y291bnQoKSA+IDA7DQogICAgICAgICAgICAgICAgICAgICRzU29hbCA9IHRyaW0oJGNvbHMtPml0ZW0oMSktPm5vZGVWYWx1ZSk7DQogICAgICAgICAgICAgICAgICAgICRzb2FsX2tvc29uZyA9ICEkc29hbF9nYW1iYXIgJiYgc3RybGVuKCRzU29hbCkgPCAzOw0KDQogICAgICAgICAgICAgICAgICAgICRqZW5pcyA9IHRyaW0oJGNvbHMtPml0ZW0oMiktPm5vZGVWYWx1ZSk7DQogICAgICAgICAgICAgICAgICAgICRqZW5pc19rb3NvbmcgPSAhaW5fYXJyYXkoJGplbmlzLCAkYXJySmVuaXMpOw0KDQogICAgICAgICAgICAgICAgICAgICRvcHNpID0gdHJpbSgkY29scy0+aXRlbSgzKS0+bm9kZVZhbHVlKTsNCiAgICAgICAgICAgICAgICAgICAgJG9wc2lfa29zb25nID0gIWluX2FycmF5KCRvcHNpLCAkVVBQRVJDQVNFX0xFVFRFUlMpOw0KDQogICAgICAgICAgICAgICAgICAgICRqZ2FtYmFyID0gJGNvbHMtPml0ZW0oNCktPmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpbWcnKTsNCiAgICAgICAgICAgICAgICAgICAgJGp3Yl9nYW1iYXIgPSAkZ2FtYmFyLT5jb3VudCgpID4gMDsNCiAgICAgICAgICAgICAgICAgICAgJGp3Ym4gPSB0cmltKCRjb2xzLT5pdGVtKDQpLT5ub2RlVmFsdWUpOw0KICAgICAgICAgICAgICAgICAgICAkandibl9rb3NvbmcgPSAhJGp3Yl9nYW1iYXIgJiYgJGp3Ym4gPT09ICLCoCI7DQoNCiAgICAgICAgICAgICAgICAgICAgJGt1bmNpID0gc3RydG9sb3dlcih0cmltKCRjb2xzLT5pdGVtKDUpLT5ub2RlVmFsdWUpKTsNCiAgICAgICAgICAgICAgICAgICAgJGt1bmNpX2tvc29uZyA9ICRrdW5jaSAhPT0gJ3YnOw0KDQogICAgICAgICAgICAgICAgICAgICRkYXRhW10gPSBbDQogICAgICAgICAgICAgICAgICAgICAgICAnbm9tb3Jfc29hbCcgPT4gJG5vcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICdzb2FsJyAgICAgICA9PiB0cmltKCR0aGlzLT5pbm5lclhNTCgkY29scy0+aXRlbSgxKSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgJ2plbmlzJwkJID0+IHRyaW0oJGNvbHMtPml0ZW0oMiktPm5vZGVWYWx1ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAnb3BzaScgICAgICAgPT4gdHJpbSgkY29scy0+aXRlbSgzKS0+bm9kZVZhbHVlKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuJyAgPT4gdHJpbSgkY29scy0+aXRlbSg0KS0+bm9kZVZhbHVlKSwvLyRkb20tPnNhdmVYTUwoJGNvbHMtPml0ZW0oNCksIExJQlhNTF9OT0VNUFRZVEFHKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICdrdW5jaScgICAgPT4gJGt1bmNpLA0KDQogICAgICAgICAgICAgICAgICAgICAgICAndXRmOF9qZW5pcycgPT4gbWJfY29udmVydF9lbmNvZGluZyh0cmltKCRjb2xzLT5pdGVtKDIpLT5ub2RlVmFsdWUpLCAnVVRGLTgnLCAnVVRGLTgnKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICdzb2FsX2dhbWJhcicgPT4gJHNvYWxfZ2FtYmFyLA0KICAgICAgICAgICAgICAgICAgICAgICAgJ3NvYWxfa29zb25nJyA9PiAkc29hbF9rb3NvbmcsDQogICAgICAgICAgICAgICAgICAgICAgICAnb3BzaV9rb3NvbmcnID0+ICRvcHNpX2tvc29uZywNCiAgICAgICAgICAgICAgICAgICAgICAgICdrdW5jaV9rb3NvbmcnID0+ICRrdW5jaV9rb3NvbmcsDQogICAgICAgICAgICAgICAgICAgICAgICAnandibl9rb3NvbmcnID0+ICRqd2JuX2tvc29uZywNCiAgICAgICAgICAgICAgICAgICAgXTsNCiAgICAgICAgICAgICAgICAgICAgJG5vcCArKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICAvKg0KICAgICAgICAgICAgJHJvd3MgPSAkdGFibGVzLT5pdGVtKDApLT5nZXRFbGVtZW50c0J5VGFnTmFtZSgndHInKTsNCg0KICAgICAgICAgICAgJG5vcCA9IDE7DQogICAgICAgICAgICBmb3IgKCRpID0gMTsgJGkgPCAkcm93cy0+Y291bnQoKTsgJGkrKykgew0KICAgICAgICAgICAgICAgICRjb2xzID0gJHJvd3NbJGldLT5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGQnKTsNCiAgICAgICAgICAgICAgICAkZGF0YVtdID0gWw0KICAgICAgICAgICAgICAgICAgICAnamVuaXMnCQk9PiAnMScsDQogICAgICAgICAgICAgICAgICAgICdub21vcl9zb2FsJz0+ICRub3AsDQogICAgICAgICAgICAgICAgICAgICdzb2FsJyAgICAgICA9PiB0cmltKCR0aGlzLT5pbm5lclhNTCgkY29scy0+aXRlbSgxKSkpLA0KICAgICAgICAgICAgICAgICAgICAnamF3YWJhbl9hJyAgPT4gdHJpbSgkdGhpcy0+aW5uZXJYTUwoJGNvbHMtPml0ZW0oMikpKSwNCiAgICAgICAgICAgICAgICAgICAgJ2phd2FiYW5fYicgID0+IHRyaW0oJHRoaXMtPmlubmVyWE1MKCRjb2xzLT5pdGVtKDMpKSksDQogICAgICAgICAgICAgICAgICAgICdqYXdhYmFuX2MnICA9PiB0cmltKCR0aGlzLT5pbm5lclhNTCgkY29scy0+aXRlbSg0KSkpLA0KICAgICAgICAgICAgICAgICAgICAnamF3YWJhbl9kJyAgPT4gdHJpbSgkdGhpcy0+aW5uZXJYTUwoJGNvbHMtPml0ZW0oNSkpKSwNCiAgICAgICAgICAgICAgICAgICAgJ2phd2FiYW5fZScgID0+IHRyaW0oJHRoaXMtPmlubmVyWE1MKCRjb2xzLT5pdGVtKDYpKSksDQogICAgICAgICAgICAgICAgICAgICdqYXdhYmFuJyAgCSA9PiB0cmltKCRjb2xzLT5pdGVtKDcpLT5ub2RlVmFsdWUpDQogICAgICAgICAgICAgICAgXTsNCiAgICAgICAgICAgICAgICAkbm9wICsrOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoJHRhYmxlcy0+aXRlbSgxKSAhPW51bGwpIHsNCiAgICAgICAgICAgICAgICAkcm93c0Vzc2FpID0gJHRhYmxlcy0+aXRlbSgxKS0+Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RyJyk7DQogICAgICAgICAgICAgICAgJG5vZSA9IDE7DQogICAgICAgICAgICAgICAgZm9yICgkaiA9IDE7ICRqIDwgJHJvd3NFc3NhaS0+Y291bnQoKTsgJGorKykgew0KICAgICAgICAgICAgICAgICAgICAkY29scyA9ICRyb3dzRXNzYWlbJGpdLT5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGQnKTsNCiAgICAgICAgICAgICAgICAgICAgJGRhdGFbXSA9IFsNCiAgICAgICAgICAgICAgICAgICAgICAgICdqZW5pcycJCT0+ICcyJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdub21vcl9zb2FsJz0+ICRub2UsDQogICAgICAgICAgICAgICAgICAgICAgICAnc29hbCcgICAgICAgPT4gJHRoaXMtPmlubmVyWE1MKCRjb2xzLT5pdGVtKDEpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuX2EnICA9PiAnJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuX2InICA9PiAnJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuX2MnICA9PiAnJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuX2QnICA9PiAnJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuX2UnICA9PiAnJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuJyAgPT4gJHRoaXMtPmlubmVyWE1MKCRjb2xzLT5pdGVtKDIpKQ0KICAgICAgICAgICAgICAgICAgICBdOw0KICAgICAgICAgICAgICAgICAgICAkbm9lICsrOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8vZWNobyBqc29uX2VuY29kZShhcnJheSgncGcnID0+ICRkYXRhKSk7DQogICAgICAgICAgICAqLw0KICAgICAgICAgICAgJGRhdGFJbnNlcnQgPSBqc29uX2RlY29kZShqc29uX2VuY29kZSgkbmV3aHRtbCkpOw0KICAgICAgICAgICAgLy8kanNvbiA9IGpzb25fZGVjb2RlKGpzb25fZW5jb2RlKCRkYXRhKSk7DQogICAgICAgICAgICAkcmVzdWx0WydwZyddID0gJGRhdGFJbnNlcnQ7DQogICAgICAgICAgICAvLyRyZXN1bHRbJ2pzb24nXSA9ICRqc29uOw0KICAgICAgICAgICAgJHJlc3VsdFsndHlwZSddID0gJ2h0bWwnOw0KCQl9DQoNCgkJLyoNCgkJLy8gSU5TRVJUDQogICAgICAgICRiYW5rID0gJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmtCeUlkKCRpZF9iYW5rKTsNCiAgICAgICAgJHNvYWxfYWRhID0gJHRoaXMtPmNidC0+Y2VrU29hbEFkYSgkaWRfYmFuayk7DQogICAgICAgIGlmIChjb3VudCgkc29hbF9hZGEpID4gMCkgew0KICAgICAgICAgICAgJHRoaXMtPmRiLT53aGVyZSgnYmFua19pZCcsICRpZF9iYW5rKTsNCiAgICAgICAgICAgICR0aGlzLT5kYi0+ZGVsZXRlKCdjYnRfc29hbCcpOw0KICAgICAgICB9DQoNCiAgICAgICAgJGRhdGEgPSBbXTsNCiAgICAgICAgZm9yZWFjaCAoJGRhdGFJbnNlcnQgYXMgJHBnKSB7DQogICAgICAgICAgICBpZiAoJHBnLT5qZW5pcyA9PSAxKSB7DQogICAgICAgICAgICAgICAgJHRhbXBpbGthbiA9ICRwZy0+bm9tb3Jfc29hbCA+ICRiYW5rLT5qbWxfc29hbCA/IDAgOiAxOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAkdGFtcGlsa2FuID0gJHBnLT5ub21vcl9zb2FsID4gJGJhbmstPmptbF9lc2FpID8gMCA6IDE7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICRkYXRhW10gPSBbDQogICAgICAgICAgICAgICAgJ2JhbmtfaWQnCQk9PiAkaWRfYmFuaywNCiAgICAgICAgICAgICAgICAnbm9tb3Jfc29hbCcJPT4gJHBnLT5ub21vcl9zb2FsLA0KICAgICAgICAgICAgICAgICdqZW5pcycJCQk9PiAkcGctPmplbmlzLA0KICAgICAgICAgICAgICAgICdzb2FsJwkJCT0+ICRwZy0+c29hbCwNCiAgICAgICAgICAgICAgICAnb3BzaV9hJwkJPT4gJHBnLT5qYXdhYmFuX2EsDQogICAgICAgICAgICAgICAgJ29wc2lfYicJCT0+ICRwZy0+amF3YWJhbl9iLA0KICAgICAgICAgICAgICAgICdvcHNpX2MnCQk9PiAkcGctPmphd2FiYW5fYywNCiAgICAgICAgICAgICAgICAnb3BzaV9kJwkJPT4gJHBnLT5qYXdhYmFuX2QsDQogICAgICAgICAgICAgICAgJ29wc2lfZScJCT0+ICRwZy0+amF3YWJhbl9lLA0KICAgICAgICAgICAgICAgICdqYXdhYmFuJwkJPT4gJHBnLT5qYXdhYmFuLA0KICAgICAgICAgICAgICAgICd0YW1waWxrYW4nCQk9PiAkdGFtcGlsa2FuLA0KICAgICAgICAgICAgICAgICdjcmVhdGVkX29uJwk9PiB0aW1lKCksDQogICAgICAgICAgICAgICAgJ3VwZGF0ZWRfb24nCT0+IHRpbWUoKQ0KICAgICAgICAgICAgXTsNCiAgICAgICAgfQ0KDQogICAgICAgICRzYXZlID0gJHRoaXMtPm1hc3Rlci0+Y3JlYXRlKCdjYnRfc29hbCcsICRkYXRhLCB0cnVlKTsNCiAgICAgICAgJHRoaXMtPmxvZ2dpbmctPnNhdmVMb2coMywgJ21lbmdpbXBvcnQgYmFuayBzb2FsJyk7DQogICAgICAgICRyZXN1bHRbJ2RhdGEnXSA9ICRzYXZlOw0KCQkqLw0KDQogICAgICAgICR0aGlzLT5vdXRwdXRfanNvbigkcmVzdWx0KTsNCiAgICB9DQoNCiAgICAvKioNCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbg0KICAgICAqLw0KICAgIHB1YmxpYyBmdW5jdGlvbiBpbXBvcnQoKXsNCgkJJGJhbmtfaWQgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ2JhbmtfaWQnLCB0cnVlKTsNCiAgICAgICAgJGJhbmsgPSAkdGhpcy0+Y2J0LT5nZXREYXRhQmFua0J5SWQoJGJhbmtfaWQpOw0KDQogICAgICAgICRpbnB1dCA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnZ2FuZGEnKTsNCiAgICAgICAgJHN0ciA9IHByZWdfcmVwbGFjZSgiXHhFRlx4QkJceEJGIiwnJywkaW5wdXQpOw0KICAgICAgICAkb2JqID0ganNvbl9kZWNvZGUoJHN0cik7DQoNCiAgICAgICAgJGpzb24gPSBqc29uX2RlY29kZSggcHJlZ19yZXBsYWNlKCcvW1x4MDAtXHgxRlx4ODAtXHhGRl0vJywgJycsICRpbnB1dCksIHRydWUgKTsNCiAgICAgICAgJHJlc3VsdFsnZXJyb3InXSA9IGpzb25fbGFzdF9lcnJvcl9tc2coKTsNCg0KICAgICAgICAkc29hbCA9IGpzb25fZGVjb2RlKGpzb25fZW5jb2RlKCRqc29uKSk7DQogICAgICAgICRyZXN1bHRbJ3NvYWwnXSA9ICRvYmo7DQogICAgICAgIC8qDQogICAgICAgICR0aGlzLT5kYi0+d2hlcmUoJ2JhbmtfaWQnLCAkYmFua19pZCk7DQoJCWlmICgkdGhpcy0+ZGItPmRlbGV0ZSgnY2J0X3NvYWwnLCAkYmFua19pZCkpIHsNCgkJCSRkYXRhID0gW107DQoJCQlmb3JlYWNoICgkc29hbCBhcyAkcGcpIHsNCgkJCSAgICBpZiAoJHBnLT5qZW5pcyA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICR0YW1waWxrYW4gPSAkcGctPm5vbW9yX3NvYWwgPiAkYmFuay0+am1sX3NvYWwgPyAwIDogMTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAkdGFtcGlsa2FuID0gJHBnLT5ub21vcl9zb2FsID4gJGJhbmstPmptbF9lc2FpID8gMCA6IDE7DQogICAgICAgICAgICAgICAgfQ0KDQoJCQkJJGRhdGFbXSA9IFsNCgkJCQkJJ2JhbmtfaWQnCQk9PiAkYmFua19pZCwNCgkJCQkJJ25vbW9yX3NvYWwnCT0+ICRwZy0+bm9tb3Jfc29hbCwNCgkJCQkJJ2plbmlzJwkJCT0+ICRwZy0+amVuaXMsDQoJCQkJCSdzb2FsJwkJCT0+ICRwZy0+c29hbCwNCgkJCQkJJ29wc2lfYScJCT0+ICRwZy0+amF3YWJhbl9hLA0KCQkJCQknb3BzaV9iJwkJPT4gJHBnLT5qYXdhYmFuX2IsDQoJCQkJCSdvcHNpX2MnCQk9PiAkcGctPmphd2FiYW5fYywNCgkJCQkJJ29wc2lfZCcJCT0+ICRwZy0+amF3YWJhbl9kLA0KCQkJCQknb3BzaV9lJwkJPT4gJHBnLT5qYXdhYmFuX2UsDQoJCQkJCSdqYXdhYmFuJwkJPT4gJHBnLT5qYXdhYmFuLA0KICAgICAgICAgICAgICAgICAgICAndGFtcGlsa2FuJwkJPT4gJHRhbXBpbGthbiwNCgkJCQkJJ2NyZWF0ZWRfb24nCT0+IHRpbWUoKSwNCgkJCQkJJ3VwZGF0ZWRfb24nCT0+IHRpbWUoKQ0KCQkJCV07DQoJCQl9DQoNCgkJCSRzYXZlID0gJHRoaXMtPm1hc3Rlci0+Y3JlYXRlKCdjYnRfc29hbCcsICRkYXRhLCB0cnVlKTsNCgkJCSR0aGlzLT5sb2dnaW5nLT5zYXZlTG9nKDMsICdtZW5naW1wb3J0IGJhbmsgc29hbCcpOw0KCQkJJHJlc3VsdFsnZGF0YSddID0gJHNhdmU7DQoJCQkvLyR0aGlzLT5vdXRwdXRfanNvbigkc2F2ZSk7DQoJCQkvLyR0aGlzLT5vdXRwdXQtPnNldF9jb250ZW50X3R5cGUoJ2FwcGxpY2F0aW9uL2pzb24nKS0+c2V0X291dHB1dCgkc2F2ZSk7DQoJCX0gZWxzZSB7DQogICAgICAgICAgICAkcmVzdWx0WydkYXRhJ10gPSAnMCc7DQoJCX0qLw0KDQogICAgICAgICR0aGlzLT5vdXRwdXRfanNvbigkcmVzdWx0KTsNCgl9DQoNCglwdWJsaWMgZnVuY3Rpb24gZXhwb3J0KCRiYW5rX2lkKSB7DQogICAgICAgICRiYW5rID0gJHRoaXMtPmNidC0+Z2V0RGF0YUJhbmtCeUlkKCRiYW5rX2lkKTsNCg0KICAgICAgICAkc29hbFtdID0ganNvbl9kZWNvZGUoanNvbl9lbmNvZGUoWydzb2FsJz0+JycsJ29wc2lfYSc9PicnLCdvcHNpX2InPT4nJywnb3BzaV9jJz0+JycsJ29wc2lfZCc9PicnLCdvcHNpX2UnPT4nJywnamF3YWJhbic9PicnXSkpOw0KICAgICAgICAkbGlzdCA9ICR0aGlzLT5jYnQtPmdldEFsbFNvYWxCeUJhbmsoJGJhbmtfaWQsICcxJyk7DQogICAgICAgICRzb2FscyA9IGFycmF5X21lcmdlKCRzb2FsLCAkbGlzdCk7DQoNCiAgICAgICAgJGVzc1tdID0ganNvbl9kZWNvZGUoanNvbl9lbmNvZGUoWydzb2FsJz0+JycsJ2phd2FiYW4nPT4nJ10pKTsNCiAgICAgICAgJGxpc3RFc3MgPSAkdGhpcy0+Y2J0LT5nZXRBbGxTb2FsQnlCYW5rKCRiYW5rX2lkLCAnMicpOw0KICAgICAgICAkZXNzYWkgPSBhcnJheV9tZXJnZSgkZXNzLCAkbGlzdEVzcyk7DQoNCiAgICAgICAgJHBocFdvcmQgPSBuZXcgXFBocE9mZmljZVxQaHBXb3JkXFBocFdvcmQoKTsNCiAgICAgICAgJHNlY3Rpb24gPSAkcGhwV29yZC0+YWRkU2VjdGlvbigpOw0KICAgICAgICAkaGVhZGVyID0gYXJyYXkoJ3NpemUnID0+IDEwLCAnYm9sZCcgPT4gdHJ1ZSk7DQogICAgICAgICRhcnJIZWFkZXIgPSBbJycsICdOTycsICdTT0FMJywgJ0pBV0FCQU4gQScsICdKQVdBQkFOIEInLCAnSkFXQUJBTiBDJywgJ0pBV0FCQU4gRCcsICdKQVdBQkFOIEUnLCAnSkFXQUJBTiBCRU5BUicsXTsNCg0KICAgICAgICAkY29scyA9IDg7DQogICAgICAgICRzZWN0aW9uLT5hZGRUZXh0KCdJLiBQSUxJSEFOIEdBTkRBJywgJGhlYWRlcik7DQoNCiAgICAgICAgJHRhYmxlU3R5bGUgPSBhcnJheSgnYm9yZGVyU2l6ZScgPT4gNiwgJ2JvcmRlckNvbG9yJyA9PiAnMDAwMDAwJyk7DQogICAgICAgICRwaHBXb3JkLT5hZGRUYWJsZVN0eWxlKCd0YWIgc3R5bGUnLCAkdGFibGVTdHlsZSk7DQogICAgICAgICR0YWJsZSA9ICRzZWN0aW9uLT5hZGRUYWJsZSgndGFiIHN0eWxlJyk7DQoNCiAgICAgICAgZm9yICgkciA9IDE7ICRyIDw9IGNvdW50KCRzb2Fscyk7ICRyKyspIHsNCiAgICAgICAgICAgICRzb2FsID0gJHNvYWxzWyRyLSgxKV07DQogICAgICAgICAgICAkYXJyVmFsID0gWycnLCAnJywNCiAgICAgICAgICAgICAgICBpc3NldCgkc29hbCkgPyAkc29hbC0+c29hbCA6ICcnLA0KICAgICAgICAgICAgICAgIGlzc2V0KCRzb2FsKSA/ICRzb2FsLT5vcHNpX2EgOiAnJywNCiAgICAgICAgICAgICAgICBpc3NldCgkc29hbCkgPyAkc29hbC0+b3BzaV9iIDogJycsDQogICAgICAgICAgICAgICAgaXNzZXQoJHNvYWwpID8gJHNvYWwtPm9wc2lfYyA6ICcnLA0KICAgICAgICAgICAgICAgIGlzc2V0KCRzb2FsKSA/ICRzb2FsLT5vcHNpX2QgOiAnJywNCiAgICAgICAgICAgICAgICBpc3NldCgkc29hbCkgPyAkc29hbC0+b3BzaV9lIDogJycsDQogICAgICAgICAgICAgICAgaXNzZXQoJHNvYWwpID8gJHNvYWwtPmphd2FiYW4gOiAnJywNCiAgICAgICAgICAgIF07DQoNCiAgICAgICAgICAgICR0YWJsZS0+YWRkUm93KCk7DQogICAgICAgICAgICBmb3IgKCRjID0gMTsgJGMgPD0gJGNvbHM7ICRjKyspIHsNCiAgICAgICAgICAgICAgICAkd2lkdGggPSA0MDAwOw0KICAgICAgICAgICAgICAgICRhbGlnbiA9IGFycmF5KA0KICAgICAgICAgICAgICAgICAgICAnYWxpZ24nID0+ICdsZWZ0JywNCiAgICAgICAgICAgICAgICAgICAgJ3NwYWNlJyA9PiBhcnJheSgnYmVmb3JlJyA9PiA1MCwgJ2FmdGVyJyA9PiA1MCksDQogICAgICAgICAgICAgICAgICAgICdpbmRlbnRhdGlvbicgPT4gYXJyYXkoJ2xlZnQnID0+IDEwMCwgJ3JpZ2h0JyA9PiAxMDApKTsNCiAgICAgICAgICAgICAgICBpZiAoJGMgPT0gMSkgew0KICAgICAgICAgICAgICAgICAgICAkYWxpZ24gPSBhcnJheSgNCiAgICAgICAgICAgICAgICAgICAgICAgICdhbGlnbicgPT4gJ2NlbnRlcicsDQogICAgICAgICAgICAgICAgICAgICAgICAnc3BhY2UnID0+IGFycmF5KCdiZWZvcmUnID0+IDUwLCAnYWZ0ZXInID0+IDUwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICdpbmRlbnRhdGlvbicgPT4gYXJyYXkoJ2xlZnQnID0+IDEwMCwgJ3JpZ2h0JyA9PiAxMDApKTsNCiAgICAgICAgICAgICAgICAgICAgJHdpZHRoID0gNTAwOw0KICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkYz09Mikgew0KICAgICAgICAgICAgICAgICAgICAkd2lkdGggPSA4MDAwOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgICRmb250U3R5bGUgPSBhcnJheSgnc2l6ZScgPT4gMTAsICdib2xkJyA9PiBmYWxzZSk7DQogICAgICAgICAgICAgICAgJG5vID0gJHItMTsNCg0KICAgICAgICAgICAgICAgIGlmICgkcj09MSl7DQogICAgICAgICAgICAgICAgICAgICRubyA9ICJOTyI7DQogICAgICAgICAgICAgICAgICAgICRhbGlnbiA9IGFycmF5KA0KICAgICAgICAgICAgICAgICAgICAgICAgJ2FsaWduJyA9PiAnY2VudGVyJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdzcGFjZScgPT4gYXJyYXkoJ2JlZm9yZScgPT4gNTAsICdhZnRlcicgPT4gNTApLA0KICAgICAgICAgICAgICAgICAgICAgICAgJ2luZGVudGF0aW9uJyA9PiBhcnJheSgnbGVmdCcgPT4gNTAsICdyaWdodCcgPT4gNTApKTsNCiAgICAgICAgICAgICAgICAgICAgJGZvbnRTdHlsZSA9IGFycmF5KCdzaXplJyA9PiAxMCwgJ2JvbGQnID0+IHRydWUpOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIGlmICgkciA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICgkYyA9PSAxICkgew0KICAgICAgICAgICAgICAgICAgICAgICAgJHRhYmxlLT5hZGRDZWxsKCR3aWR0aCktPmFkZFRleHQoJG5vLCAkZm9udFN0eWxlLCAkYWxpZ24pOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgJHRhYmxlLT5hZGRDZWxsKCR3aWR0aCktPmFkZFRleHQoJGFyckhlYWRlclskY10sICRmb250U3R5bGUsICRhbGlnbik7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBpZiAoJGMgPT0gMSApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICR0YWJsZS0+YWRkQ2VsbCgkd2lkdGgpLT5hZGRUZXh0KCRubywgJGZvbnRTdHlsZSwgJGFsaWduKTsNCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICR0YWdSZW1vdmVkID0gc3RyaXBfdGFncygkYXJyVmFsWyRjXSk7DQogICAgICAgICAgICAgICAgICAgICAgICAkaHRtbCA9IGh0bWxzcGVjaWFsY2hhcnMoJHRhZ1JlbW92ZWQpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJHRhYmxlLT5hZGRDZWxsKCR3aWR0aCktPmFkZFRleHQoJHRoaXMtPmNsZWFuU3RyaW5nKCRodG1sKSwgJGZvbnRTdHlsZSwgJGFsaWduKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vJHRhYmxlLT5hZGRDZWxsKCR3aWR0aCktPmFkZFRleHQoaHRtbHNwZWNpYWxjaGFycyhzdHJpcF90YWdzKCRhcnJWYWxbJGNdKSksICRmb250U3R5bGUsICRhbGlnbik7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAkc2VjdGlvbi0+YWRkUGFnZUJyZWFrKCk7DQogICAgICAgICRzZWN0aW9uLT5hZGRUZXh0KCdJSS4gRVNTQUknLCAkaGVhZGVyKTsNCiAgICAgICAgJGFyckhlYWRlciA9IFsnJywgJ05PJywgJ1NPQUwnLCAnSkFXQUJBTicsXTsNCiAgICAgICAgJGNvbHMgPSAzOw0KICAgICAgICAkcGhwV29yZC0+YWRkVGFibGVTdHlsZSgndGFiIHN0eWxlJywgJHRhYmxlU3R5bGUpOw0KICAgICAgICAkdGFibGUgPSAkc2VjdGlvbi0+YWRkVGFibGUoJ3RhYiBzdHlsZScpOw0KDQogICAgICAgIGZvciAoJHIgPSAxOyAkciA8PSBjb3VudCgkZXNzYWkpOyAkcisrKSB7DQogICAgICAgICAgICAkc29hbCA9ICRlc3NhaVskci0oMSldOw0KICAgICAgICAgICAgJGFyclZhbCA9IFsnJywgJycsDQogICAgICAgICAgICAgICAgaXNzZXQoJHNvYWwpID8gJHNvYWwtPnNvYWwgOiAnJywNCiAgICAgICAgICAgICAgICBpc3NldCgkc29hbCkgPyAkc29hbC0+amF3YWJhbiA6ICcnLA0KICAgICAgICAgICAgXTsNCg0KICAgICAgICAgICAgJHRhYmxlLT5hZGRSb3coKTsNCiAgICAgICAgICAgIGZvciAoJGMgPSAxOyAkYyA8PSAkY29sczsgJGMrKykgew0KICAgICAgICAgICAgICAgICR3aWR0aCA9IDQwMDA7DQogICAgICAgICAgICAgICAgJGFsaWduID0gYXJyYXkoDQogICAgICAgICAgICAgICAgICAgICdhbGlnbicgPT4gJ2xlZnQnLA0KICAgICAgICAgICAgICAgICAgICAnc3BhY2UnID0+IGFycmF5KCdiZWZvcmUnID0+IDUwLCAnYWZ0ZXInID0+IDUwKSwNCiAgICAgICAgICAgICAgICAgICAgJ2luZGVudGF0aW9uJyA9PiBhcnJheSgnbGVmdCcgPT4gMTAwLCAncmlnaHQnID0+IDEwMCkpOw0KICAgICAgICAgICAgICAgIGlmICgkYyA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICRhbGlnbiA9IGFycmF5KA0KICAgICAgICAgICAgICAgICAgICAgICAgJ2FsaWduJyA9PiAnY2VudGVyJywNCiAgICAgICAgICAgICAgICAgICAgICAgICdzcGFjZScgPT4gYXJyYXkoJ2JlZm9yZScgPT4gNTAsICdhZnRlcicgPT4gNTApLA0KICAgICAgICAgICAgICAgICAgICAgICAgJ2luZGVudGF0aW9uJyA9PiBhcnJheSgnbGVmdCcgPT4gMTAwLCAncmlnaHQnID0+IDEwMCkpOw0KICAgICAgICAgICAgICAgICAgICAkd2lkdGggPSA1MDA7DQogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRjPT0yKSB7DQogICAgICAgICAgICAgICAgICAgICR3aWR0aCA9IDgwMDA7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgJGZvbnRTdHlsZSA9IGFycmF5KCdzaXplJyA9PiAxMCwgJ2JvbGQnID0+IGZhbHNlKTsNCiAgICAgICAgICAgICAgICAkbm8gPSAkci0xOw0KDQogICAgICAgICAgICAgICAgaWYgKCRyPT0xKXsNCiAgICAgICAgICAgICAgICAgICAgJG5vID0gIk5PIjsNCiAgICAgICAgICAgICAgICAgICAgJGFsaWduID0gYXJyYXkoDQogICAgICAgICAgICAgICAgICAgICAgICAnYWxpZ24nID0+ICdjZW50ZXInLA0KICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYWNlJyA9PiBhcnJheSgnYmVmb3JlJyA9PiA1MCwgJ2FmdGVyJyA9PiA1MCksDQogICAgICAgICAgICAgICAgICAgICAgICAnaW5kZW50YXRpb24nID0+IGFycmF5KCdsZWZ0JyA9PiA1MCwgJ3JpZ2h0JyA9PiA1MCkpOw0KICAgICAgICAgICAgICAgICAgICAkZm9udFN0eWxlID0gYXJyYXkoJ3NpemUnID0+IDEwLCAnYm9sZCcgPT4gdHJ1ZSk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgaWYgKCRyID09IDEpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKCRjID09IDEgKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkdGFibGUtPmFkZENlbGwoJHdpZHRoKS0+YWRkVGV4dCgkbm8sICRmb250U3R5bGUsICRhbGlnbik7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkdGFibGUtPmFkZENlbGwoJHdpZHRoKS0+YWRkVGV4dCgkYXJySGVhZGVyWyRjXSwgJGZvbnRTdHlsZSwgJGFsaWduKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmICgkYyA9PSAxICkgew0KICAgICAgICAgICAgICAgICAgICAgICAgJHRhYmxlLT5hZGRDZWxsKCR3aWR0aCktPmFkZFRleHQoJG5vLCAkZm9udFN0eWxlLCAkYWxpZ24pOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgJHRhZ1JlbW92ZWQgPSBzdHJpcF90YWdzKCRhcnJWYWxbJGNdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRodG1sID0gaHRtbHNwZWNpYWxjaGFycygkdGFnUmVtb3ZlZCk7DQogICAgICAgICAgICAgICAgICAgICAgICAkdGFibGUtPmFkZENlbGwoJHdpZHRoKS0+YWRkVGV4dCgkdGhpcy0+Y2xlYW5TdHJpbmcoJGh0bWwpLCAkZm9udFN0eWxlLCAkYWxpZ24pOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgJG9ialdyaXRlciA9IFxQaHBPZmZpY2VcUGhwV29yZFxJT0ZhY3Rvcnk6OmNyZWF0ZVdyaXRlcigkcGhwV29yZCwgJ1dvcmQyMDA3Jyk7DQogICAgICAgIGhlYWRlcigiQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9U29hbCAiLiRiYW5rLT5uYW1hX21hcGVsLiIuZG9jeCIpOw0KICAgICAgICAkb2JqV3JpdGVyLT5zYXZlKCdwaHA6Ly9vdXRwdXQnKTsNCiAgICB9DQoNCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U29hbFNpc3dhKCRpZF9iYW5rKSB7DQogICAgICAgICRzb2FscyA9ICR0aGlzLT5jYnQtPmdldEFsbFNvYWxCeUJhbmsoJGlkX2JhbmspOw0KICAgICAgICBmb3JlYWNoICgkc29hbHMgYXMgJHNvYWwpIHsNCiAgICAgICAgICAgICRzb2FsLT5maWxlID0gdW5zZXJpYWxpemUoJHNvYWwtPmZpbGUpOw0KICAgICAgICAgICAgaWYgKCRzb2FsLT5qZW5pcyA9PSAnMicpIHsNCiAgICAgICAgICAgICAgICAkc29hbC0+amF3YWJhbiA9IHVuc2VyaWFsaXplKCRzb2FsLT5qYXdhYmFuKTsNCiAgICAgICAgICAgICAgICAkc29hbC0+b3BzaV9hID0gdW5zZXJpYWxpemUoJHNvYWwtPm9wc2lfYSk7DQogICAgICAgICAgICB9IGVsc2VpZiAoJHNvYWwtPmplbmlzID09ICczJykgew0KICAgICAgICAgICAgICAgICRzb2FsLT5qYXdhYmFuID0gdW5zZXJpYWxpemUoJHNvYWwtPmphd2FiYW4pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICRkYXRhWydzb2FsJ10gPSAkc29hbHM7DQogICAgICAgICR0aGlzLT5vdXRwdXRfanNvbigkZGF0YSk7DQogICAgfQ0KDQoJZnVuY3Rpb24gaW5uZXJYTUwoJG5vZGUpIHsNCgkJJGRvYyAgPSAkbm9kZS0+b3duZXJEb2N1bWVudDsNCgkJJGZyYWcgPSAkZG9jLT5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7DQoJCWZvcmVhY2ggKCRub2RlLT5jaGlsZE5vZGVzIGFzICRjaGlsZCkgew0KCQkJJGZyYWctPmFwcGVuZENoaWxkKCRjaGlsZC0+Y2xvbmVOb2RlKFRSVUUpKTsNCgkJfQ0KCQlyZXR1cm4gJGRvYy0+c2F2ZVhNTCgkZnJhZyk7DQoJfQ0KDQoJcHVibGljIGZ1bmN0aW9uIGZpbGVfY29uZmlnKCkgew0KCQkkYWxsb3dlZF90eXBlIAk9IFsNCgkJCSJpbWFnZS9qcGVnIiwgImltYWdlL2pwZyIsICJpbWFnZS9wbmciLCAiaW1hZ2UvZ2lmIiwNCgkJCSJhdWRpby9tcGVnIiwgImF1ZGlvL21wZyIsICJhdWRpby9tcGVnMyIsICJhdWRpby9tcDMiLCAiYXVkaW8veC13YXYiLCAiYXVkaW8vd2F2ZSIsICJhdWRpby93YXYiLA0KCQkJInZpZGVvL21wNCIsICJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iDQoJCV07DQoJCSRjb25maWdbJ3VwbG9hZF9wYXRoJ10gICAgICA9IEZDUEFUSC4ndXBsb2Fkcy9iYW5rX3NvYWwvJzsNCgkJJGNvbmZpZ1snYWxsb3dlZF90eXBlcyddICAgID0gJ2pwZWd8anBnfHBuZ3xnaWZ8bXBlZ3xtcGd8bXBlZzN8bXAzfHdhdnx3YXZlfG1wNCc7DQoJCSRjb25maWdbJ2VuY3J5cHRfbmFtZSddICAgICA9IFRSVUU7DQoNCgkJcmV0dXJuICR0aGlzLT5sb2FkLT5saWJyYXJ5KCd1cGxvYWQnLCAkY29uZmlnKTsNCgl9DQoNCglwdWJsaWMgZnVuY3Rpb24gdmFsaWRhc2koJGplbmlzKSB7DQoJCSR0aGlzLT5mb3JtX3ZhbGlkYXRpb24tPnNldF9ydWxlcygnc29hbCcsICdTb2FsJywgJ3JlcXVpcmVkJyk7DQoJCWlmICgkamVuaXM9PTEpIHsNCiAgICAgICAgICAgICR0aGlzLT5mb3JtX3ZhbGlkYXRpb24tPnNldF9ydWxlcygnamF3YWJhbl9wZycsICdLdW5jaSBKYXdhYmFuJywgJ3JlcXVpcmVkJyk7DQogICAgICAgIH0gZWxzZWlmICgkamVuaXM9PTIpIHsNCiAgICAgICAgICAgICR0aGlzLT5mb3JtX3ZhbGlkYXRpb24tPnNldF9ydWxlcygnamF3YWJhbjJfYScsICdLdW5jaSBKYXdhYmFuJywgJ3JlcXVpcmVkJyk7DQogICAgICAgICAgICAkdGhpcy0+Zm9ybV92YWxpZGF0aW9uLT5zZXRfcnVsZXMoJ2phd2FiYW5fYmVuYXJfcGcyW10nLCAnS3VuY2kgSmF3YWJhbicsICdyZXF1aXJlZCcpOw0KICAgICAgICB9IGVsc2VpZiAoJGplbmlzPT0zKSB7DQogICAgICAgICAgICAkdGhpcy0+Zm9ybV92YWxpZGF0aW9uLT5zZXRfcnVsZXMoJ2phd2FiYW5fam9kb2hrYW4nLCAnS3VuY2kgSmF3YWJhbicsICdyZXF1aXJlZCcpOw0KICAgICAgICB9IGVsc2VpZiAoJGplbmlzPT00KSB7DQogICAgICAgICAgICAkdGhpcy0+Zm9ybV92YWxpZGF0aW9uLT5zZXRfcnVsZXMoJ2phd2FiYW5faXNpYW4nLCAnS3VuY2kgSmF3YWJhbicsICdyZXF1aXJlZCcpOw0KCQl9IGVsc2Ugew0KCQkJJHRoaXMtPmZvcm1fdmFsaWRhdGlvbi0+c2V0X3J1bGVzKCdqYXdhYmFuX2Vzc2FpJywgJ0t1bmNpIEphd2FiYW4nLCAncmVxdWlyZWQnKTsNCgkJfQ0KCX0NCg0KCXB1YmxpYyBmdW5jdGlvbiBzYXZlU29hbCgpIHsNCgkJJG1ldGhvZCA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnbWV0aG9kJywgdHJ1ZSk7DQoJCSRqZW5pcyA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnamVuaXMnLCB0cnVlKTsNCg0KCQkkdGhpcy0+dmFsaWRhc2koJGplbmlzKTsNCgkJJHRoaXMtPmZpbGVfY29uZmlnKCk7DQoNCiAgICAgICAgJGRhdGEgPSBbDQogICAgICAgICAgICAnYmFua19pZCcgICAgICAgPT4gJHRoaXMtPmlucHV0LT5wb3N0KCdiYW5rX2lkJywgdHJ1ZSksDQogICAgICAgICAgICAnamVuaXMnICAgICAgICAgPT4gJGplbmlzLA0KICAgICAgICAgICAgJ25vbW9yX3NvYWwnICAgID0+ICR0aGlzLT5pbnB1dC0+cG9zdCgnbm9tb3Jfc29hbCcsIHRydWUpLA0KICAgICAgICAgICAgJ3NvYWwnICAgICAgICAgID0+ICR0aGlzLT5pbnB1dC0+cG9zdCgnc29hbCcsIGZhbHNlKQ0KICAgICAgICBdOw0KDQogICAgICAgIGlmICgkamVuaXM9PTEpIHsNCiAgICAgICAgICAgICRhYmphZCA9IFsnYScsICdiJywgJ2MnLCAnZCcsICdlJ107DQogICAgICAgICAgICBmb3JlYWNoICgkYWJqYWQgYXMgJGFiaikgew0KICAgICAgICAgICAgICAgICRkYXRhWydvcHNpXycuJGFial0gPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ2phd2FiYW5fJy4kYWJqLCBmYWxzZSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAkZGF0YVsnamF3YWJhbiddID0gJHRoaXMtPmlucHV0LT5wb3N0KCdqYXdhYmFuX3BnJywgdHJ1ZSk7DQogICAgICAgIH0gZWxzZWlmICgkamVuaXMgPT0gMikgew0KICAgICAgICAgICAgJG9wc2lzID0gW107DQogICAgICAgICAgICBmb3IgKCRpPTk3OyAkaTwxMTc7ICRpKyspIHsNCiAgICAgICAgICAgICAgICAkb3AgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ2phd2FiYW4yXycuIGNocigkaSksIGZhbHNlKTsNCiAgICAgICAgICAgICAgICBpZiAoJG9wICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgLy9hcnJheV9wdXNoKCRvcHNpcywgJG9wKTsNCiAgICAgICAgICAgICAgICAgICAgJG9wc2lzW2NocigkaSldID0gJG9wOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgICRkYXRhWydvcHNpX2EnXSA9IHNlcmlhbGl6ZSgkb3BzaXMpOw0KDQogICAgICAgICAgICAkamF3YWJhbnMgPSBbXTsNCiAgICAgICAgICAgICRqd2JfcGcyID0gY291bnQoJHRoaXMtPmlucHV0LT5wb3N0KCdqYXdhYmFuX2JlbmFyX3BnMicsIHRydWUpKTsNCiAgICAgICAgICAgIGZvciAoJGkgPSAwOyAkaSA8PSAkandiX3BnMjsgJGkrKykgew0KICAgICAgICAgICAgICAgICRqd2IgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ2phd2FiYW5fYmVuYXJfcGcyWycuJGkuJ10nLCB0cnVlKTsNCiAgICAgICAgICAgICAgICAvL2lmICgkaWQhPW51bGwpIGFycmF5X3B1c2goJGFycklkLCAkaWQpOw0KICAgICAgICAgICAgICAgIGFycmF5X3B1c2goJGphd2FiYW5zLCAkandiKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgICRkYXRhWydqYXdhYmFuJ10gPSBzZXJpYWxpemUoJGphd2FiYW5zKTsNCiAgICAgICAgfSBlbHNlaWYgKCRqZW5pcyA9PSAzKSB7DQogICAgICAgICAgICAkandiX2pvZG9oa2FuID0gWw0KICAgICAgICAgICAgICAgICdtb2RlbCcgPT4gJHRoaXMtPmlucHV0LT5wb3N0KCdtb2RlbCcsIHRydWUpLA0KICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkdGhpcy0+aW5wdXQtPnBvc3QoJ3R5cGUnLCB0cnVlKSwNCiAgICAgICAgICAgICAgICAnamF3YWJhbicgPT4ganNvbl9kZWNvZGUoJHRoaXMtPmlucHV0LT5wb3N0KCdqYXdhYmFuX2pvZG9oa2FuJywgdHJ1ZSkpDQogICAgICAgICAgICBdOw0KICAgICAgICAgICAgJGRhdGFbJ2phd2FiYW4nXSA9IHNlcmlhbGl6ZSgkandiX2pvZG9oa2FuKTsNCiAgICAgICAgfSBlbHNlaWYgKCRqZW5pcyA9PSA0KSB7DQogICAgICAgICAgICAkZGF0YVsnamF3YWJhbiddID0gJHRoaXMtPmlucHV0LT5wb3N0KCdqYXdhYmFuX2lzaWFuJywgdHJ1ZSk7DQoJCX0gZWxzZSB7DQogICAgICAgICAgICAkZGF0YVsnamF3YWJhbiddID0gJHRoaXMtPmlucHV0LT5wb3N0KCdqYXdhYmFuX2Vzc2FpJywgdHJ1ZSk7DQoJCX0NCg0KCQlpZiAoJHRoaXMtPmZvcm1fdmFsaWRhdGlvbi0+cnVuKCkgPT09IEZBTFNFKXsNCgkJCSRyZXN1bHRbJ3N0YXR1cyddID0gJ2Vycm9yJzsNCgkJfSBlbHNlIHsNCgkJCWlmKCRtZXRob2Q9PT0nYWRkJyl7DQoJCQkJJGRhdGFbJ2NyZWF0ZWRfb24nXSA9IHRpbWUoKTsNCgkJCQkkZGF0YVsndXBkYXRlZF9vbiddID0gdGltZSgpOw0KCQkJCSR0aGlzLT5tYXN0ZXItPmNyZWF0ZSgnY2J0X3NvYWwnLCAkZGF0YSk7DQoJCQkJJHJlc3VsdFsnc3RhdHVzJ10gPSAnU29hbCBiZXJoYXNpbCBkaWJ1YXQnOw0KCQkJCSR0aGlzLT5sb2dnaW5nLT5zYXZlTG9nKDMsICdtZW1idWF0IHNvYWwnKTsNCgkJCX0gZWxzZSBpZiAoJG1ldGhvZD09PSdlZGl0Jyl7DQoJCQkJJGlkX3NvYWwgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ3NvYWxfaWQnLCB0cnVlKTsNCgkJCQkkZGF0YVsndXBkYXRlZF9vbiddID0gdGltZSgpOw0KCQkJCSR0aGlzLT5tYXN0ZXItPnVwZGF0ZSgnY2J0X3NvYWwnLCAkZGF0YSwgJ2lkX3NvYWwnLCAkaWRfc29hbCk7DQoJCQkJJHJlc3VsdFsnc3RhdHVzJ10gPSAnU29hbCBiZXJoYXNpbCBkaXVwZGF0ZSc7DQoJCQkJJHRoaXMtPmxvZ2dpbmctPnNhdmVMb2coNCwgJ21lbmdlZGl0IHNvYWwnKTsNCgkJCX0gZWxzZSB7DQoJCQkJJHJlc3VsdFsnc3RhdHVzJ10gPSAnNDAwIE1ldGhvZCBub3QgZm91bmQnOw0KCQkJfQ0KCQl9DQoJCSR0aGlzLT5vdXRwdXRfanNvbigkcmVzdWx0KTsNCgl9DQoNCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFwdXNTb2FsKCkgew0KICAgICAgICAkaWRfc29hbCA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnc29hbF9pZCcsIHRydWUpOw0KICAgICAgICBpZiAoJHRoaXMtPmRiLT5kZWxldGUoJ2NidF9zb2FsJywgJ2lkX3NvYWw9Jy4kaWRfc29hbCkpew0KICAgICAgICAgICAgJHJlc3VsdFsnc3RhdHVzJ10gPSAnU29hbCBiZXJoYXNpbCBkaWhhcHVzJzsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICRyZXN1bHRbJ3N0YXR1cyddID0gJzQwMCBNZXRob2Qgbm90IGZvdW5kJzsNCiAgICAgICAgfQ0KICAgICAgICAkdGhpcy0+b3V0cHV0X2pzb24oJHJlc3VsdCk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gdXBsb2FkRmlsZSgpew0KICAgICAgICAkaWRfc29hbCA9ICR0aGlzLT5pbnB1dC0+Z2V0KCdpZF9zb2FsJywgdHJ1ZSk7DQogICAgICAgICRzb2FsID0gJHRoaXMtPmNidC0+Z2V0U29hbEJ5SWQoJGlkX3NvYWwpOw0KICAgICAgICAkZmlsZXMgPSAkc29hbCA9PSBudWxsIHx8ICRzb2FsLT5maWxlID09IG51bGwgPyBbXSA6IHVuc2VyaWFsaXplKCRzb2FsLT5maWxlKTsNCg0KICAgICAgICBpZihpc3NldCgkX0ZJTEVTWyJmaWxlX3VwbG9hZHMiXVsibmFtZSJdKSl7DQogICAgICAgICAgICAkbmFtYV9maWxlX2FzYWwgPSAkX0ZJTEVTWyJmaWxlX3VwbG9hZHMiXVsibmFtZSJdOw0KICAgICAgICAgICAgJGtvZGVfZmlsZSA9ICRpZF9zb2FsLidfJy50aW1lKCk7DQoNCiAgICAgICAgICAgICRjb25maWdbJ3VwbG9hZF9wYXRoJ10gPSAnLi91cGxvYWRzL2Jhbmtfc29hbC8nOw0KICAgICAgICAgICAgJGNvbmZpZ1snYWxsb3dlZF90eXBlcyddID0gJ21wZWd8bXBnfG1wZWczfG1wM3x3YXZ8d2F2ZXxtcDR8YXZpJzsNCiAgICAgICAgICAgICRjb25maWdbJ2ZpbGVfbmFtZSddID0gJGtvZGVfZmlsZTsNCg0KICAgICAgICAgICAgLy8kY29uZmlnWydlbmNyeXB0X25hbWUnXSA9IFRSVUU7DQogICAgICAgICAgICAvLyRjb25maWdbJ21heF9zaXplJ10gPSAnMCc7DQogICAgICAgICAgICAvLyRjb25maWdbJ292ZXJ3cml0ZSddID0gRkFMU0U7DQogICAgICAgICAgICAkdGhpcy0+dXBsb2FkLT5pbml0aWFsaXplKCRjb25maWcpOw0KICAgICAgICAgICAgaWYoISR0aGlzLT51cGxvYWQtPmRvX3VwbG9hZCgnZmlsZV91cGxvYWRzJykpew0KICAgICAgICAgICAgICAgICRkYXRhWydzdGF0dXMnXSA9IGZhbHNlOw0KICAgICAgICAgICAgICAgICRzcmMgPSAnJzsNCiAgICAgICAgICAgICAgICAkZmlsZW5hbWUgPSAnJzsNCiAgICAgICAgICAgICAgICAkZGF0YVsnc3JjJ10gPSAkdGhpcy0+dXBsb2FkLT5kaXNwbGF5X2Vycm9ycygpOw0KICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAgICAgJGZpbGUgPSAkdGhpcy0+dXBsb2FkLT5kYXRhKCk7DQogICAgICAgICAgICAgICAgLyoNCiAgICAgICAgICAgICAgICAkY29uZmlnWydpbWFnZV9saWJyYXJ5J109J2dkMic7DQogICAgICAgICAgICAgICAgJGNvbmZpZ1snc291cmNlX2ltYWdlJ109Jy4vdXBsb2Fkcy9iYW5rX3NvYWwvJy4kZmlsZVsnZmlsZV9uYW1lJ107DQogICAgICAgICAgICAgICAgJGNvbmZpZ1snY3JlYXRlX3RodW1iJ109IEZBTFNFOw0KICAgICAgICAgICAgICAgICRjb25maWdbJ21haW50YWluX3JhdGlvJ109IFRSVUU7DQogICAgICAgICAgICAgICAgJGNvbmZpZ1sncXVhbGl0eSddPSAnNjAlJzsNCiAgICAgICAgICAgICAgICAkY29uZmlnWyd3aWR0aCddPSA4MDA7DQogICAgICAgICAgICAgICAgJGNvbmZpZ1snaGVpZ2h0J109IDgwMDsNCiAgICAgICAgICAgICAgICAkY29uZmlnWyduZXdfaW1hZ2UnXT0gJy4vdXBsb2Fkcy9iYW5rX3NvYWwvJy4kZmlsZVsnZmlsZV9uYW1lJ107DQogICAgICAgICAgICAgICAgJHRoaXMtPmxvYWQtPmxpYnJhcnkoJ2ltYWdlX2xpYicsICRjb25maWcpOw0KICAgICAgICAgICAgICAgICR0aGlzLT5pbWFnZV9saWItPnJlc2l6ZSgpOw0KICAgICAgICAgICAgICAgICovDQoNCiAgICAgICAgICAgICAgICAvL2VjaG8gYmFzZV91cmwoKS4ndXBsb2Fkcy9iYW5rX3NvYWwvJy4kZmlsZVsnZmlsZV9uYW1lJ107DQogICAgICAgICAgICAgICAgJGV4dCA9IHBhdGhpbmZvKCRmaWxlWydmaWxlX25hbWUnXSwgUEFUSElORk9fRVhURU5TSU9OKTsNCiAgICAgICAgICAgICAgICAkc3JjID0gJ3VwbG9hZHMvYmFua19zb2FsLycuJGtvZGVfZmlsZS4nLicuJGV4dDsNCiAgICAgICAgICAgICAgICAkZGF0YVsnc3JjJ10gPSAkc3JjOw0KICAgICAgICAgICAgICAgIC8vJGZpbGVuYW1lID0gcGF0aGluZm8oJGZpbGVbJ2ZpbGVfbmFtZSddLCBQQVRISU5GT19GSUxFTkFNRSk7DQogICAgICAgICAgICAgICAgLy8kZGF0YVsnZmlsZW5hbWUnXSA9ICRmaWxlbmFtZTsNCiAgICAgICAgICAgICAgICAkZGF0YVsnZmlsZW5hbWUnXSA9ICRuYW1hX2ZpbGVfYXNhbDsNCiAgICAgICAgICAgICAgICAkZGF0YVsnc3RhdHVzJ10gPSB0cnVlOw0KDQogICAgICAgICAgICAgICAgJHR5cGUgPSAkX0ZJTEVTWydmaWxlX3VwbG9hZHMnXVsndHlwZSddOw0KICAgICAgICAgICAgICAgICRkYXRhWyd0eXBlJ10gPSAkdHlwZTsNCiAgICAgICAgICAgICAgICAkZGF0YVsnc2l6ZSddID0gJF9GSUxFU1snZmlsZV91cGxvYWRzJ11bJ3NpemUnXTsNCiAgICAgICAgICAgICAgICAkZGF0YVsnc29hbCddID0gJHNvYWw7DQoNCiAgICAgICAgICAgICAgICAkZmlsZXNbXSA9IFsNCiAgICAgICAgICAgICAgICAgICAgJ2ZpbGVfbmFtZScgPT4gJG5hbWFfZmlsZV9hc2FsLA0KICAgICAgICAgICAgICAgICAgICAnYWxpYXMnID0+ICRrb2RlX2ZpbGUsDQogICAgICAgICAgICAgICAgICAgICdzcmMnID0+ICRzcmMsDQogICAgICAgICAgICAgICAgICAgICd0eXBlJyA9PiAkdHlwZQ0KICAgICAgICAgICAgICAgIF07DQogICAgICAgICAgICAgICAgLy9hcnJheV9wdXNoKCRmaWxlcywgWydmaWxlcyc9PiRhZGRGaWxlc10pOw0KDQogICAgICAgICAgICAgICAgJHRoaXMtPmRiLT5zZXQoJ2ZpbGUnLCBzZXJpYWxpemUoJGZpbGVzKSk7DQogICAgICAgICAgICAgICAgJHRoaXMtPmRiLT53aGVyZSgnaWRfc29hbCcsICRpZF9zb2FsKTsNCiAgICAgICAgICAgICAgICAkdGhpcy0+ZGItPnVwZGF0ZSgnY2J0X3NvYWwnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgICRkYXRhWydmaWxlcyddID0gJGZpbGVzOw0KICAgICAgICAkdGhpcy0+b3V0cHV0X2pzb24oJGRhdGEpOw0KICAgIH0NCgkvL1VwbG9hZCBpbWFnZSBzdW1tZXJub3RlDQoJZnVuY3Rpb24gdXBsb2FkX2ltYWdlKCl7DQoJCS8vJGRhdGFbJ3RhZ19pZCddID0gJHRoaXMtPmlucHV0LT5wb3N0KCd0YWdfaWQnLCB0cnVlKTsNCiAgICAgICAgJHN0YXR1cyA9IGZhbHNlOw0KICAgICAgICBpZihpc3NldCgkX0ZJTEVTWyJmaWxlIl1bIm5hbWUiXSkpew0KCQkJJGNvbmZpZ1sndXBsb2FkX3BhdGgnXSA9ICcuL3VwbG9hZHMvYmFua19zb2FsLyc7DQoJCQkkY29uZmlnWydhbGxvd2VkX3R5cGVzJ10gPSAnanBnfGpwZWd8cG5nfGdpZnxtcDN8b2dnfHdhdnxtcDR8bXBlZ3x3ZWJtJzsNCiAgICAgICAgICAgICRjb25maWdbJ2ZpbGVfbmFtZSddID0gJ2ZpbGVfJy5kYXRlKCdZbWRIaXMnKTsNCgkJCSR0aGlzLT51cGxvYWQtPmluaXRpYWxpemUoJGNvbmZpZyk7DQoJCQlpZighJHRoaXMtPnVwbG9hZC0+ZG9fdXBsb2FkKCdmaWxlJykpew0KCQkJCSR0aGlzLT51cGxvYWQtPmRpc3BsYXlfZXJyb3JzKCk7DQoJCQkJJHN0YXR1cyA9IGZhbHNlOw0KCQkJfWVsc2V7DQoJCQkJJHVwbG9hZGVkID0gJHRoaXMtPnVwbG9hZC0+ZGF0YSgpOw0KCQkJCS8vQ29tcHJlc3MgSW1hZ2UNCgkJCQkvLyRjb25maWdbJ2ltYWdlX2xpYnJhcnknXT0nZ2QyJzsNCgkJCQkvLyRjb25maWdbJ3NvdXJjZV9pbWFnZSddPScuL3VwbG9hZHMvYmFua19zb2FsLycuJGRhdGFbJ2ZpbGVfbmFtZSddOw0KCQkJCS8vJGNvbmZpZ1snY3JlYXRlX3RodW1iJ109IEZBTFNFOw0KCQkJCS8vJGNvbmZpZ1snbWFpbnRhaW5fcmF0aW8nXT0gVFJVRTsNCgkJCQkvLyRjb25maWdbJ3F1YWxpdHknXT0gJzYwJSc7DQoJCQkJLy8kY29uZmlnWyd3aWR0aCddPSA4MDA7DQoJCQkJLy8kY29uZmlnWydoZWlnaHQnXT0gODAwOw0KCQkJCS8vJGNvbmZpZ1snbmV3X2ltYWdlJ109ICcuL3VwbG9hZHMvYmFua19zb2FsLycuJGRhdGFbJ2ZpbGVfbmFtZSddOw0KCQkJCS8vJHRoaXMtPmxvYWQtPmxpYnJhcnkoJ2ltYWdlX2xpYicsICRjb25maWcpOw0KCQkJCS8vJHRoaXMtPmltYWdlX2xpYi0+cmVzaXplKCk7DQoNCgkJCQkkZGF0YVsnZmlsZW5hbWUnXSA9ICAndXBsb2Fkcy9iYW5rX3NvYWwvJy4kdXBsb2FkZWRbJ2ZpbGVfbmFtZSddOw0KCQkJCSRzdGF0dXMgPSB0cnVlOw0KCQkJfQ0KCQl9DQoJCSRkYXRhWydzdGF0dXMnXSA9ICRzdGF0dXM7DQoJCSR0aGlzLT5vdXRwdXRfanNvbigkZGF0YSk7DQoJfQ0KDQoJLy9EZWxldGUgaW1hZ2Ugc3VtbWVybm90ZQ0KICAgIGZ1bmN0aW9uIGRlbGV0ZUZpbGUoKSB7DQogICAgICAgICRzcmMgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ3NyYycpOw0KICAgICAgICAkZmlsZV9uYW1lID0gc3RyX3JlcGxhY2UoYmFzZV91cmwoKSwgJycsICRzcmMpOw0KICAgICAgICBpZiAodW5saW5rKCRmaWxlX25hbWUpKSB7DQogICAgICAgICAgICBlY2hvICdGaWxlIERlbGV0ZSBTdWNjZXNzZnVsbHknOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgZnVuY3Rpb24gY2xlYW5TdHJpbmcoJHRleHQpIHsNCiAgICAgICAgLy8gMSkgY29udmVydCDDoSDDtCA9PiBhIG8NCiAgICAgICAgJHRleHQgPSBwcmVnX3JlcGxhY2UoIi9bw6HDoMOiw6PCqsOkXS91IiwiYSIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHByZWdfcmVwbGFjZSgiL1vDgcOAw4LDg8OEXS91IiwiQSIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHByZWdfcmVwbGFjZSgiL1vDjcOMw47Dj10vdSIsIkkiLCR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBwcmVnX3JlcGxhY2UoIi9bw63DrMOuw69dL3UiLCJpIiwkdGV4dCk7DQogICAgICAgICR0ZXh0ID0gcHJlZ19yZXBsYWNlKCIvW8Opw6jDqsOrXS91IiwiZSIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHByZWdfcmVwbGFjZSgiL1vDicOIw4rDi10vdSIsIkUiLCR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBwcmVnX3JlcGxhY2UoIi9bw7PDssO0w7XCusO2XS91IiwibyIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHByZWdfcmVwbGFjZSgiL1vDk8OSw5TDlcOWXS91IiwiTyIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHByZWdfcmVwbGFjZSgiL1vDusO5w7vDvF0vdSIsInUiLCR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBwcmVnX3JlcGxhY2UoIi9bw5rDmcObw5xdL3UiLCJVIiwkdGV4dCk7DQogICAgICAgICR0ZXh0ID0gcHJlZ19yZXBsYWNlKCIvW+KAmeKAmOKAueKAuuKAml0vdSIsIiciLCR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBwcmVnX3JlcGxhY2UoIi9b4oCc4oCdwqvCu+KAnl0vdSIsJyInLCR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBzdHJfcmVwbGFjZSgi4oCTIiwiLSIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCIgIiwiICIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCLDpyIsImMiLCR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBzdHJfcmVwbGFjZSgiw4ciLCJDIiwkdGV4dCk7DQogICAgICAgICR0ZXh0ID0gc3RyX3JlcGxhY2UoIsOxIiwibiIsJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCLDkSIsIk4iLCR0ZXh0KTsNCg0KICAgICAgICAvLzIpIFRyYW5zbGF0aW9uIENQMTI1Mi4gJm5kYXNoOyA9PiAtDQogICAgICAgICR0cmFucyA9IGdldF9odG1sX3RyYW5zbGF0aW9uX3RhYmxlKEhUTUxfRU5USVRJRVMpOw0KICAgICAgICAkdHJhbnNbY2hyKDEzMCldID0gJyZzYnF1bzsnOyAgICAvLyBTaW5nbGUgTG93LTkgUXVvdGF0aW9uIE1hcmsNCiAgICAgICAgJHRyYW5zW2NocigxMzEpXSA9ICcmZm5vZjsnOyAgICAvLyBMYXRpbiBTbWFsbCBMZXR0ZXIgRiBXaXRoIEhvb2sNCiAgICAgICAgJHRyYW5zW2NocigxMzIpXSA9ICcmYmRxdW87JzsgICAgLy8gRG91YmxlIExvdy05IFF1b3RhdGlvbiBNYXJrDQogICAgICAgICR0cmFuc1tjaHIoMTMzKV0gPSAnJmhlbGxpcDsnOyAgICAvLyBIb3Jpem9udGFsIEVsbGlwc2lzDQogICAgICAgICR0cmFuc1tjaHIoMTM0KV0gPSAnJmRhZ2dlcjsnOyAgICAvLyBEYWdnZXINCiAgICAgICAgJHRyYW5zW2NocigxMzUpXSA9ICcmRGFnZ2VyOyc7ICAgIC8vIERvdWJsZSBEYWdnZXINCiAgICAgICAgJHRyYW5zW2NocigxMzYpXSA9ICcmY2lyYzsnOyAgICAvLyBNb2RpZmllciBMZXR0ZXIgQ2lyY3VtZmxleCBBY2NlbnQNCiAgICAgICAgJHRyYW5zW2NocigxMzcpXSA9ICcmcGVybWlsOyc7ICAgIC8vIFBlciBNaWxsZSBTaWduDQogICAgICAgICR0cmFuc1tjaHIoMTM4KV0gPSAnJlNjYXJvbjsnOyAgICAvLyBMYXRpbiBDYXBpdGFsIExldHRlciBTIFdpdGggQ2Fyb24NCiAgICAgICAgJHRyYW5zW2NocigxMzkpXSA9ICcmbHNhcXVvOyc7ICAgIC8vIFNpbmdsZSBMZWZ0LVBvaW50aW5nIEFuZ2xlIFF1b3RhdGlvbiBNYXJrDQogICAgICAgICR0cmFuc1tjaHIoMTQwKV0gPSAnJk9FbGlnOyc7ICAgIC8vIExhdGluIENhcGl0YWwgTGlnYXR1cmUgT0UNCiAgICAgICAgJHRyYW5zW2NocigxNDUpXSA9ICcmbHNxdW87JzsgICAgLy8gTGVmdCBTaW5nbGUgUXVvdGF0aW9uIE1hcmsNCiAgICAgICAgJHRyYW5zW2NocigxNDYpXSA9ICcmcnNxdW87JzsgICAgLy8gUmlnaHQgU2luZ2xlIFF1b3RhdGlvbiBNYXJrDQogICAgICAgICR0cmFuc1tjaHIoMTQ3KV0gPSAnJmxkcXVvOyc7ICAgIC8vIExlZnQgRG91YmxlIFF1b3RhdGlvbiBNYXJrDQogICAgICAgICR0cmFuc1tjaHIoMTQ4KV0gPSAnJnJkcXVvOyc7ICAgIC8vIFJpZ2h0IERvdWJsZSBRdW90YXRpb24gTWFyaw0KICAgICAgICAkdHJhbnNbY2hyKDE0OSldID0gJyZidWxsOyc7ICAgIC8vIEJ1bGxldA0KICAgICAgICAkdHJhbnNbY2hyKDE1MCldID0gJyZuZGFzaDsnOyAgICAvLyBFbiBEYXNoDQogICAgICAgICR0cmFuc1tjaHIoMTUxKV0gPSAnJm1kYXNoOyc7ICAgIC8vIEVtIERhc2gNCiAgICAgICAgJHRyYW5zW2NocigxNTIpXSA9ICcmdGlsZGU7JzsgICAgLy8gU21hbGwgVGlsZGUNCiAgICAgICAgJHRyYW5zW2NocigxNTMpXSA9ICcmdHJhZGU7JzsgICAgLy8gVHJhZGUgTWFyayBTaWduDQogICAgICAgICR0cmFuc1tjaHIoMTU0KV0gPSAnJnNjYXJvbjsnOyAgICAvLyBMYXRpbiBTbWFsbCBMZXR0ZXIgUyBXaXRoIENhcm9uDQogICAgICAgICR0cmFuc1tjaHIoMTU1KV0gPSAnJnJzYXF1bzsnOyAgICAvLyBTaW5nbGUgUmlnaHQtUG9pbnRpbmcgQW5nbGUgUXVvdGF0aW9uIE1hcmsNCiAgICAgICAgJHRyYW5zW2NocigxNTYpXSA9ICcmb2VsaWc7JzsgICAgLy8gTGF0aW4gU21hbGwgTGlnYXR1cmUgT0UNCiAgICAgICAgJHRyYW5zW2NocigxNTkpXSA9ICcmWXVtbDsnOyAgICAvLyBMYXRpbiBDYXBpdGFsIExldHRlciBZIFdpdGggRGlhZXJlc2lzDQogICAgICAgICR0cmFuc1snZXVybyddID0gJyZldXJvOyc7ICAgIC8vIGV1cm8gY3VycmVuY3kgc3ltYm9sDQogICAgICAgIGtzb3J0KCR0cmFucyk7DQoNCiAgICAgICAgZm9yZWFjaCAoJHRyYW5zIGFzICRrID0+ICR2KSB7DQogICAgICAgICAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCR2LCAkaywgJHRleHQpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gMykgcmVtb3ZlIDxwPiwgPGJyLz4gLi4uDQogICAgICAgICR0ZXh0ID0gc3RyaXBfdGFncygkdGV4dCk7DQoNCiAgICAgICAgLy8gNCkgJmFtcDsgPT4gJiAmcXVvdDsgPT4gJw0KICAgICAgICAkdGV4dCA9IGh0bWxfZW50aXR5X2RlY29kZSgkdGV4dCk7DQoNCiAgICAgICAgLy8gNSkgcmVtb3ZlIFdpbmRvd3MtMTI1MiBzeW1ib2xzIGxpa2UgIlRyYWRlTWFyayIsICJFdXJvIi4uLg0KICAgICAgICAkdGV4dCA9IHByZWdfcmVwbGFjZSgnL1teKFx4MjAtXHg3RildKi8nLCcnLCAkdGV4dCk7DQoNCiAgICAgICAgJHRhcmdldHM9YXJyYXkoJ1xyXG4nLCdcbicsJ1xyJywnXHQnKTsNCiAgICAgICAgJHJlc3VsdHM9YXJyYXkoIiAiLCIgIiwiICIsIiIpOw0KICAgICAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCR0YXJnZXRzLCRyZXN1bHRzLCR0ZXh0KTsNCg0KICAgICAgICAvL1hNTCBjb21wYXRpYmxlDQogICAgICAgIC8qDQogICAgICAgICR0ZXh0ID0gc3RyX3JlcGxhY2UoIiYiLCAiYW5kIiwgJHRleHQpOw0KICAgICAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCI8IiwgIi4iLCAkdGV4dCk7DQogICAgICAgICR0ZXh0ID0gc3RyX3JlcGxhY2UoIj4iLCAiLiIsICR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBzdHJfcmVwbGFjZSgiXFwiLCAiLSIsICR0ZXh0KTsNCiAgICAgICAgJHRleHQgPSBzdHJfcmVwbGFjZSgiLyIsICItIiwgJHRleHQpOw0KICAgICAgICAqLw0KDQogICAgICAgIHJldHVybiAoJHRleHQpOw0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIGNsZWFuSFRNTCgkaHRtbCkgew0KICAgICAgICAkZG9jID0gbmV3IERPTURvY3VtZW50KCk7DQogICAgICAgIC8qIExvYWQgdGhlIEhUTUwgKi8NCiAgICAgICAgJGRvYy0+bG9hZEhUTUwoJGh0bWwsDQogICAgICAgICAgICBMSUJYTUxfSFRNTF9OT0lNUExJRUQgfCAjIE1ha2Ugc3VyZSBubyBleHRyYSBCT0RZDQogICAgICAgICAgICBMSUJYTUxfSFRNTF9OT0RFRkRURCB8ICAjIG9yIERPQ1RZUEUgaXMgY3JlYXRlZA0KICAgICAgICAgICAgTElCWE1MX05PRVJST1IgfCAgICAgICAgIyBTdXBwcmVzcyBhbnkgZXJyb3JzDQogICAgICAgICAgICBMSUJYTUxfTk9XQVJOSU5HICAgICAgICAjIG9yIHdhcm5pbmdzIGFib3V0IHByZWZpeGVzLg0KICAgICAgICApOw0KICAgICAgICAvKiBJbW1lZGlhdGVseSBzYXZlIHRoZSBIVE1MIGFuZCByZXR1cm4gaXQuICovDQogICAgICAgIHJldHVybiAkZG9jLT5zYXZlSFRNTCgpOw0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIGFkZE5hbWVzcGFjZXMoJHhtbCkgew0KICAgICAgICAkcm9vdCA9ICc8dzp3b3JkRG9jdW1lbnQNCiAgICAgICAgeG1sbnM6dz0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2Uvd29yZC8yMDAzL3dvcmRtbCINCiAgICAgICAgeG1sbnM6d3g9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vb2ZmaWNlL3dvcmQvMjAwMy9hdXhIaW50Ig0KICAgICAgICB4bWxuczpvPSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOm9mZmljZTpvZmZpY2UiPic7DQogICAgICAgICRyb290IC49ICR4bWw7DQogICAgICAgICRyb290IC49ICc8L3c6d29yZERvY3VtZW50Pic7DQogICAgICAgIHJldHVybiAkcm9vdDsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBkb0ltcG9ydCgpIHsNCiAgICAgICAgJGJhbmtfaWQgPSAkdGhpcy0+aW5wdXQtPnBvc3QoJ2lkX2JhbmsnLCB0cnVlKTsNCiAgICAgICAgJHN0cmluZyA9ICR0aGlzLT5pbnB1dC0+cG9zdCgnZGF0YScsIGZhbHNlKTsNCg0KICAgICAgICAkanNvbiA9IGpzb25fZGVjb2RlKCRzdHJpbmcpOw0KICAgICAgICAvKg0KICAgICAgICBzd2l0Y2ggKGpzb25fbGFzdF9lcnJvcigpKSB7DQogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfTk9ORToNCiAgICAgICAgICAgICAgICBlY2hvICcgLSBObyBlcnJvcnMnOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgY2FzZSBKU09OX0VSUk9SX0RFUFRIOg0KICAgICAgICAgICAgICAgIGVjaG8gJyAtIE1heGltdW0gc3RhY2sgZGVwdGggZXhjZWVkZWQnOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgY2FzZSBKU09OX0VSUk9SX1NUQVRFX01JU01BVENIOg0KICAgICAgICAgICAgICAgIGVjaG8gJyAtIFVuZGVyZmxvdyBvciB0aGUgbW9kZXMgbWlzbWF0Y2gnOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgY2FzZSBKU09OX0VSUk9SX0NUUkxfQ0hBUjoNCiAgICAgICAgICAgICAgICBlY2hvICcgLSBVbmV4cGVjdGVkIGNvbnRyb2wgY2hhcmFjdGVyIGZvdW5kJzsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgSlNPTl9FUlJPUl9TWU5UQVg6DQogICAgICAgICAgICAgICAgZWNobyAnIC0gU3ludGF4IGVycm9yLCBtYWxmb3JtZWQgSlNPTic7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBjYXNlIEpTT05fRVJST1JfVVRGODoNCiAgICAgICAgICAgICAgICBlY2hvICcgLSBNYWxmb3JtZWQgVVRGLTggY2hhcmFjdGVycywgcG9zc2libHkgaW5jb3JyZWN0bHkgZW5jb2RlZCc7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgICAgIGVjaG8gJyAtIFVua25vd24gZXJyb3InOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQogICAgICAgICovDQogICAgICAgICRkYXRhcyA9IFtdOw0KICAgICAgICAkam1sID0gW107DQogICAgICAgIGZvcmVhY2ggKCRqc29uIGFzICRqZW5pcz0+JHZhbHVlcykgew0KICAgICAgICAgICAgJGRhdGFfc29hbCA9IFtdOw0KICAgICAgICAgICAgZm9yZWFjaCAoJHZhbHVlcyBhcyAkdmFsKSB7DQogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR2YWwtPk5PKSkgew0KICAgICAgICAgICAgICAgICAgICAkbm8gPSAkdmFsLT5OTzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR2YWwtPlNPQUwpICYmICR2YWwtPlNPQUwgIT0gIiIpICRkYXRhX3NvYWxbJG5vXVsnc29hbCddID0gJHZhbC0+U09BTDsNCg0KICAgICAgICAgICAgICAgICAgICBpZiAoJGplbmlzID09ICIxIikgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR2YWwtPk9QU0kpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGFfc29hbFskbm9dWydvcHNpJ11bc3RydG91cHBlcigkdmFsLT5PUFNJKV0gPSAkdmFsLT5KQVdBQkFOOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdmFsLT5LVU5DSSkgJiYgc3RydG9sb3dlcigkdmFsLT5LVU5DSSkgPT0gInYiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkYXRhX3NvYWxbJG5vXVsna3VuY2knXVtzdHJ0b2xvd2VyKCR2YWwtPktVTkNJKV0gPSBzdHJ0b3VwcGVyKCR2YWwtPk9QU0kpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRqZW5pcyA9PSAiMiIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdmFsLT5PUFNJKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkYXRhX3NvYWxbJG5vXVsnb3BzaSddW3N0cnRvdXBwZXIoJHZhbC0+T1BTSSldID0gJHZhbC0+SkFXQUJBTjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHZhbC0+S1VOQ0kpICYmIHN0cnRvbG93ZXIoJHZhbC0+S1VOQ0kpID09ICJ2Iikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGF0YV9zb2FsWyRub11bJ2t1bmNpJ11bc3RydG91cHBlcigkdmFsLT5PUFNJKV0gPSBzdHJ0b2xvd2VyKCR2YWwtPktVTkNJKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkamVuaXMgPT0gIjMiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHZhbC0+S0RfQkFSSVMpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGFfc29hbFskbm9dWydiYXJpcyddW3N0cnRvdXBwZXIoJHZhbC0+S0RfQkFSSVMpXSA9ICR2YWwtPkJBUklTOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR2YWwtPktVTkNJKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGF0YV9zb2FsWyRub11bJ2t1bmNpJ11bc3RydG91cHBlcigkdmFsLT5LRF9LVU5DSSldID0gc3RydG91cHBlcigkdmFsLT5LVU5DSSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHZhbC0+S0RfS09MT00pKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGFfc29hbFskbm9dWydrb2xvbSddW3N0cnRvdXBwZXIoJHZhbC0+S0RfS09MT00pXSA9ICR2YWwtPktPTE9NOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzc2V0KCR2YWwtPktVTkNJKSkgJGRhdGFfc29hbFskbm9dWydrdW5jaSddID0gJHZhbC0+S1VOQ0k7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICRkYXRhc1skamVuaXNdID0gJGRhdGFfc29hbDsNCiAgICAgICAgfQ0KDQogICAgICAgICRkYXRhX2luc2VydCA9IFtdOw0KICAgICAgICBmb3JlYWNoICgkZGF0YXMgYXMgJGplbmlzPT4ka2V5cykgew0KICAgICAgICAgICAgZm9yZWFjaCAoJGtleXMgYXMgJG5vPT4kdikgew0KICAgICAgICAgICAgICAgICRpc2lfc29hbCA9IGlzc2V0KCR2Wydzb2FsJ10pID8gJHZbJ3NvYWwnXSA6ICIiOw0KICAgICAgICAgICAgICAgIGlmICgkaXNpX3NvYWwgIT0gIiIpIHsNCiAgICAgICAgICAgICAgICAgICAgJGluc2VydCA9IFsNCiAgICAgICAgICAgICAgICAgICAgICAgICdqZW5pcycgPT4gJGplbmlzLA0KICAgICAgICAgICAgICAgICAgICAgICAgJ25vbW9yX3NvYWwnID0+ICRubywNCiAgICAgICAgICAgICAgICAgICAgICAgICdzb2FsJyA9PiAkaXNpX3NvYWwsDQogICAgICAgICAgICAgICAgICAgICAgICAnZmlsZScgPT4gc2VyaWFsaXplKFtdKSAsDQogICAgICAgICAgICAgICAgICAgIF07DQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKCRqZW5pcyA9PSAiMSIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICRpbnNlcnRbJ29wc2lfYSddID0gaXNzZXQoJHZbJ29wc2knXSkgJiYgaXNzZXQoJHZbJ29wc2knXVsnQSddKSA/ICR2WydvcHNpJ11bJ0EnXSA6ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGluc2VydFsnb3BzaV9iJ10gPSBpc3NldCgkdlsnb3BzaSddKSAmJiBpc3NldCgkdlsnb3BzaSddWydCJ10pID8gJHZbJ29wc2knXVsnQiddIDogJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAkaW5zZXJ0WydvcHNpX2MnXSA9IGlzc2V0KCR2WydvcHNpJ10pICYmIGlzc2V0KCR2WydvcHNpJ11bJ0MnXSkgPyAkdlsnb3BzaSddWydDJ10gOiAnJzsNCiAgICAgICAgICAgICAgICAgICAgICAgICRpbnNlcnRbJ29wc2lfZCddID0gaXNzZXQoJHZbJ29wc2knXSkgJiYgaXNzZXQoJHZbJ29wc2knXVsnRCddKSA/ICR2WydvcHNpJ11bJ0QnXSA6ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGluc2VydFsnb3BzaV9lJ10gPSBpc3NldCgkdlsnb3BzaSddKSAmJiBpc3NldCgkdlsnb3BzaSddWydFJ10pID8gJHZbJ29wc2knXVsnRSddIDogJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAkaW5zZXJ0WydqYXdhYmFuJ10gPSBpc3NldCgkdlsna3VuY2knXSkgJiYgaXNzZXQoJHZbJ2t1bmNpJ11bJ3YnXSkgPyAkdlsna3VuY2knXVsndiddIDogJyc7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkamVuaXMgPT0gIjIiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkb3BzaXMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRrdW5jaXMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdlsnb3BzaSddKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2WydvcHNpJ10gYXMgJG9wc2k9PiRqYXdhYmFuKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRvcHNpc1tzdHJ0b2xvd2VyKCRvcHNpKV0gPSAkamF3YWJhbjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdlsna3VuY2knXSkpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICgkdlsna3VuY2knXSBhcyAka3VuY2k9PiRqYXdhYmFuKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkamF3YWJhbiA9PSAidiIpICRrdW5jaXNbXSA9IHN0cnRvbG93ZXIoJGt1bmNpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAkaW5zZXJ0WydvcHNpX2EnXSA9IHNlcmlhbGl6ZSgkb3BzaXMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGluc2VydFsnamF3YWJhbiddID0gc2VyaWFsaXplKCRrdW5jaXMpOw0KDQogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkamVuaXMgPT0gIjMiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAkYmFyaXMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRrb2xvbSA9IFtdOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAkaGVhZGVyID0gW107DQogICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9wdXNoKCRoZWFkZXIsICcjJyk7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICRhcnJLb2wgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2Wydrb2xvbSddIGFzICRrZF9rb2w9PiRrb2wpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAka29sb21bJGtkX2tvbF0gPSAka29sOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgka29sICE9ICIiKSBhcnJheV9wdXNoKCRoZWFkZXIsICRrb2wpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoJHZbJ2t1bmNpJ10gYXMgJGtkX2Jhcj0+JGtkX2tvbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGtkX2tvbCAhPSAiIikgJGFycktvbFska2RfYmFyXSA9IGV4cGxvZGUoJywnLCAka2Rfa29sKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3B1c2goJGJhcmlzLCAkaGVhZGVyKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICRqd2JuQmFyaXMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCR2WydiYXJpcyddIGFzICRrZF9iYXI9PiRiYXIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkandibiA9IFtdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgka2RfYmFyICE9ICIiKSBhcnJheV9wdXNoKCRqd2JuLCAkYmFyKTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRrb2xvbSBhcyAka2s9PiR2YWwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRrZF9iYXIgIT0gIiIgJiYgJHZhbCAhPSAiIikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1hdGNoID0gaW5fYXJyYXkoJGtrLCAkYXJyS29sWyRrZF9iYXJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3B1c2goJGp3Ym4sICRtYXRjaCA/ICcxJyA6ICcwJyk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50KCRqd2JuKSA+IDApIGFycmF5X3B1c2goJGJhcmlzLCAkandibik7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJGtkX2JhciAhPSAiIikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9zaGlmdCgkandibik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRqd2JuQmFyaXNbJGtkX2Jhcl0gPSAkandibjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAkdHlwZXMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRqd2JuQmFyaXMgYXMgJGJycz0+JGptbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRqbWxUeXBlID0gYXJyYXlfY291bnRfdmFsdWVzKCRqbWwpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkam1sVHlwZVsxXSA+IDEpIGFycmF5X3B1c2goJHR5cGVzLCAnY2hlY2tib3gnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICR0eXBlID0gY291bnQoJHR5cGVzKSA+IDAgPyAnMScgOiAnMic7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICRqbWxfYmFyaXMgPSBjb3VudCgkYmFyaXMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgJGptbF9rb2xvbSA9IGNvdW50KCRiYXJpc1swXSk7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICRqd2Jfam9kb2hrYW4gPSBbDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21vZGVsJyA9PiAkam1sX2JhcmlzID09ICRqbWxfa29sb20gPyAnMScgOiAnMicsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3R5cGUnID0+ICR0eXBlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICdqYXdhYmFuJyA9PiAkYmFyaXMNCiAgICAgICAgICAgICAgICAgICAgICAgIF07DQogICAgICAgICAgICAgICAgICAgICAgICAkaW5zZXJ0WydqYXdhYmFuJ10gPSBzZXJpYWxpemUoJGp3Yl9qb2RvaGthbik7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZWlmICgkamVuaXMgPT0gIjQiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHZbJ2t1bmNpJ10pKSAkaW5zZXJ0WydqYXdhYmFuJ10gPSBzdHJpcF90YWdzKCR2WydrdW5jaSddKTsNCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3NldCgkdlsna3VuY2knXSkpICRpbnNlcnRbJ2phd2FiYW4nXSA9ICR2WydrdW5jaSddOw0KICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgJGRhdGFfaW5zZXJ0W10gPSAkaW5zZXJ0Ow0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgICRpbnNlcnRlZCA9IFtdOw0KICAgICAgICBmb3JlYWNoICgkZGF0YV9pbnNlcnQgYXMgJGRpbnMpIHsNCiAgICAgICAgICAgICRpbnNlcnRlZFtdID0gWw0KICAgICAgICAgICAgICAgICdiYW5rX2lkJyA9PiAkYmFua19pZCwNCiAgICAgICAgICAgICAgICAnamVuaXMnID0+ICRkaW5zWydqZW5pcyddLA0KICAgICAgICAgICAgICAgICdub21vcl9zb2FsJyA9PiAkZGluc1snbm9tb3Jfc29hbCddLA0KICAgICAgICAgICAgICAgICdzb2FsJyA9PiAkZGluc1snc29hbCddLA0KICAgICAgICAgICAgICAgICdkZXNrcmlwc2knPT4gJycsDQogICAgICAgICAgICAgICAgJ2tlc3VsaXRhbic9PiAnOCcsDQogICAgICAgICAgICAgICAgJ3RpbWVyJyA9PiAnMCcsDQogICAgICAgICAgICAgICAgJ3RpbWVyX21lbml0JyA9PiAnMCcsDQogICAgICAgICAgICAgICAgJ2ZpbGUnID0+ICRkaW5zWydmaWxlJ10gLA0KICAgICAgICAgICAgICAgICd0YW1waWxrYW4nID0+ICcwJywNCiAgICAgICAgICAgICAgICAnY3JlYXRlZF9vbicgPT4gdGltZSgpLA0KICAgICAgICAgICAgICAgICd1cGRhdGVkX29uJyA9PiB0aW1lKCksDQogICAgICAgICAgICAgICAgJ29wc2lfYScgPT4gaXNzZXQoJGRpbnNbJ29wc2lfYSddKSA/ICRkaW5zWydvcHNpX2EnXSA6ICcnLA0KICAgICAgICAgICAgICAgICdvcHNpX2InID0+IGlzc2V0KCRkaW5zWydvcHNpX2InXSkgPyAkZGluc1snb3BzaV9iJ10gOiAnJywNCiAgICAgICAgICAgICAgICAnb3BzaV9jJyA9PiBpc3NldCgkZGluc1snb3BzaV9jJ10pID8gJGRpbnNbJ29wc2lfYyddIDogJycsDQogICAgICAgICAgICAgICAgJ29wc2lfZCcgPT4gaXNzZXQoJGRpbnNbJ29wc2lfZCddKSA/ICRkaW5zWydvcHNpX2QnXSA6ICcnLA0KICAgICAgICAgICAgICAgICdvcHNpX2UnID0+IGlzc2V0KCRkaW5zWydvcHNpX2UnXSkgPyAkZGluc1snb3BzaV9lJ10gOiAnJywNCiAgICAgICAgICAgICAgICAnamF3YWJhbicgPT4gJGRpbnNbJ2phd2FiYW4nXQ0KICAgICAgICAgICAgXTsNCiAgICAgICAgfQ0KDQogICAgICAgICRkYXRhWydkYXRhX2luc2VydCddID0gJGluc2VydGVkOw0KICAgICAgICAkZGF0YVsndG90YWwnXSA9IGNvdW50KCRpbnNlcnRlZCk7DQogICAgICAgIGlmIChjb3VudCgkaW5zZXJ0ZWQpID4gMCkgew0KICAgICAgICAgICAgJHRoaXMtPmRiLT53aGVyZSgnYmFua19pZCcsICRiYW5rX2lkKTsNCiAgICAgICAgICAgIGlmICgkdGhpcy0+ZGItPmRlbGV0ZSgnY2J0X3NvYWwnKSkgew0KICAgICAgICAgICAgICAgICRkYXRhWydpbnNlcnQnXSA9ICR0aGlzLT5kYi0+aW5zZXJ0X2JhdGNoKCdjYnRfc29hbCcsICRpbnNlcnRlZCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAkZGF0YVsnaW5zZXJ0J10gPSAwOw0KICAgICAgICB9DQogICAgICAgICR0aGlzLT5vdXRwdXRfanNvbigkZGF0YSk7DQogICAgfQ0KfQ=='))

Function Calls

base64_decode 1

Variables

None

Stats

MD5 4a7f479cb06c4a64e21b8fff7bcb89d8
Eval Count 1
Decode Time 308 ms