DIR : /home/kozerus/public_html/tl.php

/home/kozerus/public_html

<?php
# tl.php 20221213_0900	tlgif
# tl.php 20221213_0700	html_bluehost html_parallels
# tl.php 20221212_0030	save=savfil
# tl.php 20221212_0000	timeaddition
# tl.php 20221211_2040
# tl.php 20221211_1222



#	exit();
#	phpinfo();
	$progid="tl";
	$dttm=date("Ymd_His");
	$timezone_identifier="US/Central";
	date_default_timezone_set( $timezone_identifier );
#	$db3="files.db3";
#	$db3="/fb/usps/usps.db3";
#	$db3="usps.db3";
	$db3_default="tl/db3/tl.db3";
	$tbl_default="fb";
#	$db3=$db3_default;
#	$tbl=$tbl_default;
	$tlid_default="tlid";
	$limit=100;
	$sql="";

#	$sql = "";
#	$sql .= "select ";
#	$sql .= " startdate, enddate, headline, text, ";
#	$sql .= " media, credit, caption ";
#	$sql .= " from $db3 ";
#	$sql .= " limit $limit ";
	$nl="\n";

#	$tbl="mp4";
#	$tbl="files";
#	$tbl="jpg";
#	$tbl="tl";
#	$tbl="usps";

	$url=""; $request_uri=""; $query_string="";
	if( isset($_SERVER['REQUEST_URI'])) { $url=$_SERVER['REQUEST_URI']; }
	$php_self=$_SERVER['PHP_SELF'];
	if( isset($_SERVER['REQUEST_URI'])) { $request_uri=$_SERVER['REQUEST_URI']; }
	if( isset($_SERVER['QUERY_STRING'])){ $query_string=$_SERVER['QUERY_STRING']; }
	$parts=parse_url($url);
	$params = [];
	$get_tlid = "get_tlid";
	parse_str($query_string, $params);
	$tlid=$tlid_default;
	$tlid="";
	$pf="";
	$p="";
	$f="";
	$d1="";
	$d2="";
	$limit="";
	$limit_default=100;
	$rowid="0";
	$fmt="";
	$save=""; $savefile="";
	$help="";


	if( isset($params['db3'] )) { $db3=$params['db3']; } else { $db3=$db3_default; }
	if( isset($params['tbl'] )) { $tbl=$params['tbl']; } else { $tbl=$tbl_default; }
	if( isset($params['tlid'] )) { $tlid=$params['tlid']; }
	if( isset($params['pf'] )) { $pf=$params['pf']; }
	if( isset($params['p'] )) { $p=$params['p']; }
	if( isset($params['f'] )) { $f=$params['f']; }
	if( isset($params['d1'] )) { $d1=$params['d1']; }
	if( isset($params['d2'] )) { $d2=$params['d2']; }
	if( isset($params['limit'] )) { $limit=$params['limit']; }
	if( isset($params['rowid'] )) { $rowid=$params['rowid']; }
	if( isset($params['fmt'] )) { $fmt=$params['fmt']; }
	if( isset($params['save'] )) { 
		$save=$params['save']; 
		if( $save == "" ) { $savefile="tl_$dttm.json"; }
		else {		$savefile = $save; }
		}
	if( isset($_GET['tlid'])) { $get_tlid=$_GET['tlid']; }

#	$sql .= sprintf( "select * from %s order by dttm desc limit %s", $db3tbl, $limit );
#	$sql .= sprintf( "select * from %s where tlid = '$tlid' order by dttm desc limit %s", $db3tbl, $limit );

#	printf( "<h2>BUGS_80 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h2>\n" );
#	exit();

	$sql = ""; $perc='%';
	$sql .= sprintf( "select * from %s ",$tbl );
#	if( $tlid != "" ) { $sql .= sprintf( " where tlid='%s'", $tlid ); }
	if( $tlid != "" ) { $sql .= sprintf( " where tlid like '%s'", $tlid ); }
	else { $sql .= sprintf( " where tlid != '' " ); }
	if( $pf != "" ) { $sql .= sprintf( " and pathfile like '%s%s%s'", $perc,$pf,$perc ); }
	if( $p != "" ) { $sql .= sprintf( " and path like '%s%s%s'", $perc,$p,$perc ); }
	if( $f != "" ) { $sql .= sprintf( " and base like '%s%s%s'", $perc,$f,$perc ); }
	if( $d1 != "" ) { $sql .= sprintf( " and startdate >= '%s'", $d1 ); }
	if( $d2 != "" ) { $sql .= sprintf( " and enddate <= '%s'", $d2 ); }
	if( $rowid > 0 ) { $sql .= sprintf( " and rowid == %s", $rowid ); }
	else { $sql .= sprintf( " and rowid>%s ",$rowid ); }
	$sql .= sprintf( " and status is NULL" );
	$sql .= sprintf( " order by startdate,starttime desc " );
	if( $tlid == '' ) { 
		$sql .= sprintf( " limit %s",$limit_default ); 
		}
	else {
		if( $limit > 0 ) { $sql .= sprintf( " limit %s",$limit ); }
		}
	$sql .= ";\n";

	if( isset($params['help'] )) {
		$html_help = html_help($db3,$tbl,$tlid,$pf,$p,$f,$d1,$d2,$limit,$fmt);
		echo "$html_help";
		exit();
		}



#	echo "BUGS_51 tlid=$tlid<br>\n";
	if( $savefile != "" ) { 
		if(file_exists($savefile)) {
			printf( "<h1>ERR_109 EXISTS savefile=$savefile</h1>\n" );
			exit();
			}
		printf( "<h1>MSG_110 savefile=$savefile</h1>\n" );
		$json = db3_json($db3, $tbl, $tlid, $sql );
		$myfile = fopen($savefile,"w") or die( "ERR_111 savefile=$savefile" ) ;
		fwrite($myfile,$json);
		fclose($myfile);
		}

#	printf( "<h1>BUGS_110 db3=$db3 tbl=$tbl tlid=$tlid fmt=$fmt sql=$sql </h1>\n" );
	if(preg_match("/json/", $fmt)) {
		$json = db3_json($db3, $tbl, $tlid, $sql );
		header('Content-Type: application/json; charset=utf-8');
		echo $json;
		exit();
		}

#	printf( "<h1>BUGS_125 db3=$db3 tbl=$tbl tlid=$tlid fmt=$fmt sql=$sql</h1>\n" );

	if(( $fmt == "" ) || ( $fmt == "html" )) {
		$html = html($db3,$tbl,$tlid,$sql);
		echo "$html";
		exit();
		}

	if( $tlid == "" ) {
		$html .= html_menus($db3,$tbl,$tlid,$sql);
		echo "$html";
		exit();
		}
	echo "BUGS_100 UNSUPPORTED fmt=$fmt<br>\n";
	exit();

#	$json = ajaks_0($db3, $sql );
#	$json = ajaks_tl($db3, $sql );
#	printf( $json );
	exit();


function html_menus($db3,$tbl) {
	$dttm=date("Ymd_His");
	$sql = "select tlid, count(*) cnt from $tbl group by tlid";
#	printf( "BUGS_150 db3=$db3 tbl=$tbl sql=$sql<br>\n" );

	$html = "";
	$html .= "<hr color=black>\n";
	$html .= "<hr color=white>\n";
	$html .= "<div id=div_menus>\n";
	$html .= "	<h2>menus</h2>\n";
	$html .= "	<h2>db3=$db3 tbl=$tbl</h3>\n";
	$html .= "<hr color=black>\n";
	$html .= "<hr color=white>\n";

	$html .= html_menu_tlid($db3,$tbl);
	$html .= "<hr color=black>\n";
	$html .= "<hr color=white>\n";

	$html .= html_menu_tbl($db3);
	$html .= "<hr color=white>\n";
	$html .= "<hr color=black>\n";

	$html .= html_menu_db3();
	$html .= "<hr color=white>\n";
	$html .= "<hr color=black>\n";

	$html .= html_menu_json();
	$html .= "<hr color=white>\n";
	$html .= "<hr color=black>\n";

	$html .= "	</div id=div_menus_end>\n";
	$html .= "<hr color=white>\n";
	$html .= "<hr color=black>\n";
	$html .= html_coffee('RoyalOne');
	$html .= " &nbsp &nbsp &nbsp ";
	$html .= html_bluehost('/track/konet');
	$html .= " &nbsp &nbsp &nbsp ";
	$html .= html_parallels('?partner=konet');
	$html .= "	</div>\n";
#	$html .= "	</body>\n";
#	$html .= "	</html>\n";
	return($html);
	}

function html_menu_db3() {
	$html = "";
	$j=0;
	$html .= "<img src=/imgs/btn/koeye.png id=img_menu_db3 ";
	$html .= " onclick=\"toggle('div_menu_db3');return false;\" height=20>menu_db3";
	$html .= "<div id=div_menu_db3>\n";
	$html .= "	<h1>menu_db3</h1>\n";
	$html .= "	<table id=table_db3>\n";
	$html .= "	<tr><td width=50>num</td><td width=400>link</td></tr>\n";

	$syscmd='find tl  -name "*.db3"';
	$j=0; $html_menu_db3=""; $tbl="";
#	$db3s=system($syscmd);
	$db3list=shell_exec($syscmd);
	$db3s = preg_split("/\n/", $db3list, -1, PREG_SPLIT_NO_EMPTY);
	foreach ( $db3s as $db3 ) {
		$j=$j+1;
		$url = "$j <a href=/tl.php?db3=$db3>$db3</a><br>";
		$html .= "<tr><td>$j</td><td>$url</td></tr>\n";
		}
	$html .= "	</table id=table_db3_end>\n";
	$html .= "	</div id=div_menu_db3_end>\n";
	return($html);
	}


function html_menu_tlid($db3, $tbl) {
	if( $db3 == "" ) { return(""); }
	$sql="select tlid,count(*) cnt from $tbl group by tlid";
	$db = new SQLite3($db3);
        $result = $db->query($sql);	//->fetchArray(SQLITE3_ASSOC);

	$html = "";
	$j=0;
	$tlid="";
	$cnt="";
	$nl="\n";

	$html .= "<img src=/imgs/btn/koeye.png id=img_menu_tlid ";
	$html .= " onclick=\"toggle('div_menu_tlid');return false;\" height=20>menu_tlid";
	$html .= "<div id=div_menu_tlid>\n";
	$html .= "	<h1>menu_tlid</h1>\n";
	$html .= "	<table id=table_tlid>\n";
	$html .= "	<tr><td width=50>num</td><td width=400>link</td><td width=50>cnt</td></tr>\n";

	while($row = $result->fetchArray(SQLITE3_ASSOC)){
		$tlid=""; $cnt="";
		if(isset($row['tlid'])) { $tlid=$row['tlid']; }
		if(isset($row['cnt'])) { $cnt=$row['cnt']; }
		if( $tlid == "." ) { continue; }
		$j=$j+1;
		$url="<a href=/tl.php?db3=$db3&tbl=$tbl&tlid=$tlid >$tlid</a>\n";
		$html .= "<tr><td>$j</td><td>$url</td><td>$cnt</td></tr>\n";
		}
	$html .= "	</table id=table_tlid>\n";
	$html .= "	</div id=div_menu_tlid_end>\n";
	return($html);
	}

function html_menu_tbl($db3) {

	$sql="select * from sqlite_master where sql like '%tlid%'";
	$sql="select * from sqlite_master";
	if( $db3 == "" ) { return(""); }
#	printf( "<h1>BUGS_230 db3=$db3 sql=$sql</h1>\n" );

	$db = new SQLite3($db3);
        $result = $db->query($sql);	//->fetchArray(SQLITE3_ASSOC);

	$html = "";
	$j=0;
	$tbl="";
	$nl="\n";

	$html .= "<img src=/imgs/btn/koeye.png id=img_menu_tbl ";
	$html .= " onclick=\"toggle('div_menu_tbl');return false;\" height=20>menu_tbl";
	$html .= "<div id=div_menu_tbl>\n";
	$html .= "	<h1>menu_tbl</h1>\n";
	$html .= "	<h2>$db3=$db3 sql=$sql</h2>\n";
	$html .= "	<table id=table_tbl>\n";
	$html .= "	<tr><td width=50>num</td><td width=400>link</td></tr>\n";

	while($row = $result->fetchArray(SQLITE3_ASSOC)){
		if(isset($row['tbl_name'])) { $tbl=$row['tbl_name']; } else { $tbl="-"; }
		if(isset($row['sql'])) { $sql=$row['sql']; } else { $sql="-"; }
		$j=$j+1;
#		if(! preg_match("/*tlid*/", $sql)) { continue; }
		$url="<a href=/tl.php?db3=$db3&tbl=$tbl >$tbl</a>\n";
		$html .= "<tr><td>$j</td><td>$url</td></tr>\n";
		}
	$html .= "	</table id=table_tbl>\n";
	$html .= "	</div id=div_menu_tbl_end>\n";
	return($html);
	}

function html_menu_json() {
	$j=0;
	$html = "";
	$html .= "<img src=/imgs/btn/koeye.png id=img_menu_json ";
	$html .= " onclick=\"toggle('div_menu_json');return false;\" height=20>menu_json";
	$html .= "<div id=div_menu_json>\n";
	$html .= "	<h1>menu_json</h1>\n";
	$html .= "	<table id=table_json>\n";
	$html .= "	<tr><td width=50>num</td><td width=400>link</td></tr>\n";

	$syscmd='find tl  -name "*.json"';
#	printf( "<h1>BUGS_210 syscmd=$syscmd</h1>\n" );
#	$jsons_list=system($syscmd);
	$jsonlist=shell_exec($syscmd);
	$jsons = preg_split("/\n/", $jsonlist, -1, PREG_SPLIT_NO_EMPTY);
	foreach ( $jsons as $json ) {
		$j=$j+1;
#		printf( "<h1>BUGS_270 j=$j json=$json</h1>\n" );
#		$url="<a href=/tl.html?tlid=$json target=_blank>$json</a>";
		$url="<a href=/tl.php?tlid=$json target=_blank>$json</a>";
		$html .= "<tr><td>$j</td><td>$url</td></tr>\n";
		}
	$html .= "	</table id=table_json_end>\n";
	$html .= "	</div id=div_json_end>\n";
	return($html);
	}


function html_help($db3,$tbl,$tlid,$pf,$p,$f,$d1,$d2,$limit,$fmt) {
	$dttm=date("Ymd_His");
	$html = "";
	$html .= "<html>\n";
	$html .= "<head>\n";
	$html .= "	<title>tl.php help $dttm</title>\n";
	$html .= html_scripts_konet();
	$html .= "	</head>\n";
	$html .= "<body bgcolor=linen>\n";
	$html .= "	<hr color=black>\n";
	$html .= "	<hr color=white>\n";
	$html .= "	<div id=div_help>\n";
	$html .= "		<h1>help</h1>\n";
	$html .= "		db3=$db3<br>\n";
	$html .= "		tbl=$tbl<br>\n";
	$html .= "		tlid=$tlid<br>\n";
	$html .= "		pf=$pf<br>\n";
	$html .= "		p=$p<br>\n";
	$html .= "		f=$f<br>\n";
	$html .= "		d1=$d1<br>\n";
	$html .= "		d2=$d2<br>\n";
	$html .= "		limit=$limit<br>\n";
	$html .= "		rowid=$db3<br>\n";
	$html .= "		fmt=$fmt|html|json<br>\n";
	$html .= "		save=savefile.json|tl_20221212_0231.json\n";
	$html .= "		</div>\n";
	$html .= "	<hr color=white>\n";
	$html .= "	<hr color=black>\n";

	$html .= html_coffee('RoyalOnd');
	$html .= " &nbsp &nbsp &nbsp ";
	$html .= html_bluehost('/track/konet');
	$html .= " &nbsp &nbsp &nbsp ";
	$html .= html_parallels('partner=konet');
	$html .= "	</body>\n";
	$html .= "	</html>\n";
	return($html);
	}


function html($db3,$tbl,$tlid,$sql) {
	$dttm=date("Ymd_His");
#	printf( "<h1>BUGS_350 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#	exit;

	$html = "";
	$html .= "<html>\n";
	$html .= "<head>\n";
	$html .= "	<title>tl.php html $dttm</title>\n";
#	$html .= "	<script src=\"/js/jquery-1.8.3.js\" ></script>\n";
#	$html .= "	<script src=\"/js/jquery-ui-1.9.2.custom.js\" ></script>\n";
	$html .= "	<script src=\"/tl/lib/js/storyjs-embed.js\" ></script>\n";
	$html .= "	<script src=\"/tl/lib/js/jquery-min.js\" ></script>\n";
	$html .= html_scripts_konet('');
	$html .= "	<script id=\"script_tl\" >\n";

#	$html .= "		tl_source='$json';\n";
#	$html .= "		tl_source='tl.json',\n";
#	$html .= 'tl_source=\'{ "timeline": {';
#	$html .= '"headline":"jtfdc_20210917_1627_mail_speedy_notime2talk.mp4",';
#	$html .= '"type":"default",';
#	$html .= '"text":"<a href=\'/fb/usps/mp4/jtfdc_20210917_1627_mail_speedy_notime2talk.mp4\' target=_blank><img src=\'/imgs/btn/btn_mp4.png\' height=200></a>",';
#	$html .= '"startDate":"1900,1,1",';
#	$html .= '"endDate":"1900,1,1",';
#	$html .= '"date": [ ';
#	$html .= '{';
#	$html .= '"startDate":"1900,1,1",';
#	$html .= '"endDate":"1900,1,1",';
#	$html .= '	"headline":"jtfdc_20210917_1627_mail_speedy_notime2talk.mp4",';
#	$html .= '"text":"<a href=\'/fb/usps/mp4/jtfdc_20210917_1627_mail_speedy_notime2talk.mp4\' target=_blank><img src=\'/imgs/btn/btn_mp4.png\' height=200></a>",';
#	$html .= '"asset": {';
#	$html .= '		"media":"/fb/usps/mp4/jtfdc_20210917_1627_mail_speedy_notime2talk.mp4",';
#	$html .= '		"credit":" credit 4",';
#	$html .= '		"caption":"caption"';
#	$html .= '		} } ] } }';
#	$html .= '\';';



	$html .= "		\$(document).ready(function () {\n";
	$html .= "			createStoryJS({\n";
	$html .= "				type:		'timeline',\n";
	$html .= "				width:		'1400',\n";
	$html .= "				height:		'800',\n";
	if(preg_match("/.json/", $tlid)) {
		$html .= "				source:		'$tlid',\n";
		}
	else {
#		printf( "<h1>BUGS_400 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#		exit();
		$json=db3_json($db3,$tbl,$tlid, $sql);
#		printf( "<h1>BUGS_410 json=$json</h1>\n" );
#		printf( "<h1>BUGS_411 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#		exit();
		$html .= "				source:		$json,\n";
		}
	$html .= "				embed_id:	'my-timeline',\n";
	$html .= "				debug:		true\n";
	$html .= "			});\n";
	$html .= "		});\n";
	$html .= "		</script>\n";
	$html .= "	</head>\n";

	$html .= "<body bgcolor=linen>\n";
	$html .= "<a href=/tl.php><img src=/imgs/btn/ko.png height=20></a>\n";
	$html .= "<br>\n";

	$html .= "<hr color=black>\n";
	$html .= "<hr color=white>\n";
	$html .= "<div id=div_tl>\n";
	$html .= "	<h1>ko_timeline: db3=$db3 tbl=$tbl tlid=$tlid</h1>\n";
	$html .= "	<h2>$dttm</h2>\n";
	$html .= "	<h3>$sql</h3>\n";
	$html .= "<hr color=black>\n";
	$html .= "<hr color=white>\n";
	$html .= "	<div id=\"my-timeline\"></div>\n";
	$html .= "	</div>\n";
	$html .= "<hr color=white>\n";
	$html .= "<hr color=black>\n";
	$html .= html_coffee('RoyalOnd');
	$html .= " &nbsp &nbsp &nbsp ";
	$html .= html_bluehost('/track/konet');
	$html .= " &nbsp &nbsp &nbsp ";
	$html .= html_parallels('?partner=konet');
	$html .= "<hr color=black>\n";
	$html .= "<hr color=white>\n";
	$html .= html_menus($db3,$tbl,$tlid,$sql);
	$html .= "<hr color=white>\n";
	$html .= "<hr color=black>\n";
	$html .= "	</body>\n";
	$html .= "	</html>\n";
	return($html);
	}


function ajaks_0($db3, $sql ) {
        $db = new SQLite3($db3);
	$data= array();
        $row = array();
	if( $sql == "" ) {
		$sql = 'select f_name as file from mp4 where file like "%byrd%"';
		}

        $result = $db->query($sql);
	while ($res= $result->fetchArray(1)) {
		array_push($data, $res);
		}
	return( json_encode($data));
	exit();
	}
function ajaks_1($db3, $sql) {
	}


function db3_json($db3, $tbl, $tlid, $sql ) {
#	printf( "<h1>BUGS_460 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#	exit();
	if ( $db3 == "" ) { return(""); }
	if ( $tbl == "" ) { return(""); }
	if( $sql == "" ) { 
		if( $tlid == "" ) {
			$sql= "select * from $tbl where tlid like '$tlid'";
			}
		else {
			$sql= "select * from $tbl";
			}
		}

#	$sql = 'select pathfile as file from avg where pathfile like "%byrd%"';
#	if( $sql == "" ) {
#		$sql = 'select startdate,enddate,headline,text,media,credit,caption from files ';
#		echo "BUGS_105 default_sql: sql=$sql";
#		}
#	printf( "<h1>BUGS_430 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql<br>\n" );
#
        $db = new SQLite3($db3);
        $result = $db->query($sql);	//->fetchArray(SQLITE3_ASSOC);

#	$timeline = array();
#	$row = array();
#	$asset = array();
        $i = 0;
	$firsttime="yes";
	$nl="\n";
	$tl_json_body = "";
	$j=0;
	while($row = $result->fetchArray(SQLITE3_ASSOC)){
		$j=$j+1;
		if(!isset($row['startdate'])) continue;
#		print_r($row);
#		printf( "<h1>BUGS_500 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#		exit();

		if(!isset($row['headline'])) { $headline=""; }
		if(!isset($row['text'])) { $text=""; }
		if(!isset($row['startdate'])) { $startdate=""; }
		if(!isset($row['enddate'])) { $enddate=""; }
		if(!isset($row['media'])) { $media=""; }
		else { $media=$row['media']; }
		if(!isset($row['credit'])) { $credit=""; }
		if(!isset($row['caption'])) { $caption=""; }
#		if( isset($row['startdate'])) {
		if( $media != "" ) {
#			printf( "<h1>BUGS_510 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#			printf( "<h1>BUGS_511 media=$media</h1>\n" );
			$headline=$row['headline'];
			$text=$row['text'];
			$startdate=$row['startdate'];
			$enddate=$row['enddate'];
			$media=$row['media'];
			$credit=$row['credit'];
			$caption=$row['caption'];
			$tlid=$row['tlid'];
			$tn=$row['tn'];

#			print( "<h1>BUGS_530 tlid=$tlid media=$media text=$text tn=$tn</h1>\n" );

#			$text="";
#			$tn=$media;
#			if(( $text == "" ) || ( $text == "text" )) {
			if( $text == "" ) {
				if( $tn != "" ) {
					$text="<a href='$media' target=_blank><img src='$tn' height=200></a>";
					}
				else {
					$text="<a href='$media' target=_blank><img src='$media' height=200></a>";
					}
				}
#			echo "BUGS_540 MEDIA<br> tlid=$tlid media=$media caption=$caption<br><hr> ";
			if(str_contains($media,"pdf")) {
				$tn="/imgs/btn/btn_pdf.png";
				if(( $text == "" ) || ( $text == "text" )) {
					$text="<a href='/pdf/web/viewer.html?file=$media' target=_blank><img src='$tn' height=200></a>";
					}
		
#				echo "BUGS_535 PDF text=$text";
				}
			if(str_contains($media,"mp3")) {
				$tn="/imgs/btn/btn_mp3.png";
				$text="<a href='$media' target=_blank><img src='$tn' height=200></a>";
#				echo "<h1>BUGS_540 MP3 text=$text<\h1>";
				}
			if(str_contains($media,"mp4")) {
				$tn="/imgs/btn/btn_mp4.png";
				$text="<a href='$media' target=_blank><img src='$tn' height=200></a>";
#				echo "<h1>BUGS_545 MP4 text=$text</h1>";
				}

# sqlite3 SELECT GROUP_CONCAT(tlid,"|") FROM tbl

			if( $firsttime == "yes" ) {
				$headline="ko_timeline</h2>";
#				$tlgif=tlgif('','');
				$tlgiftn=tlgif('','tn');
				$tlgif=str_replace("tn/tn_","",$tlgiftn);
#				printf( "<h1>BUGS_580 tlgif=$tlgif tlgiftn=$tlgiftn</h1>\n");
				$text="<a href=$tlgif target=_blank><img src=$tlgiftn width=800></a>";
				$text .= "<h1>tlid=$tlid</h1>";
				$text .= "<h2>tbl=$tbl db3=$db3</h2>";
				$startdate="2013,01,01"; $starttime="00:00:01";
				$enddate=date('now'); $enddate="23:59:59";
				$tl_json_head = '';
				$tl_json_head .= sprintf('{ "timeline": {%s',$nl);
				$tl_json_head .= sprintf('"headline":"%s",%s',$headline, $nl);
				$tl_json_head .= sprintf('"type":"default",%s',$nl);
				$tl_json_head .= sprintf('"text":"%s",%s',$text, $nl);
				$tl_json_head .= sprintf('"startDate":"%s",%s',$startdate, $nl);
				$tl_json_head .= sprintf('"endDate":"%s",%s',$enddate, $nl);
			        $tl_json_head .= sprintf('"date": [ %s', $nl);
				$firsttime="no";
#				echo "<h1>BUGS_560 HEAD</h1>";
				}
			else {
#				echo "<h1>BUGS_175 BODYLOOP</h1>";
#				$tl_json_body = "";
				$tl_json_body .= sprintf('	{%s',$nl);
				$tl_json_body .= sprintf('	"startDate":"%s",%s', $startdate,$nl);
				$tl_json_body .= sprintf('	"endDate":"%s",%s', $enddate,$nl);
				$tl_json_body .= sprintf('	"headline":"%s",%s', $headline,$nl);
				$tl_json_body .= sprintf('	"text":"%s",%s', $text,$nl);
				$tl_json_body .= sprintf('	"asset": {%s',$nl );
				$tl_json_body .= sprintf('		"media":"%s",%s', $media,$nl);
				$tl_json_body .= sprintf('		"credit":"%s",%s', $credit,$nl);
				$tl_json_body .= sprintf('		"caption":"%s"%s', $caption,$nl);
				$tl_json_body .= sprintf("		} },%s",$nl);
#				print( "<h1>BUGS_570 tlid=$tlid media=$media text=$text tn=$tn</h1>\n" );
#				exit();
				}
#			print( "<h1>BUGS_590 tlid=$tlid startdate=$startdate text=$text</hr>\n" );
#			exit();
			$i++;
			}
		}

#	printf( "<h1>BUGS_580 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#	exit();


	$tl_json_tail = "";
	if(!isset($startdate)) { $startdate=""; }
	if(!isset($enddate)) { $enddate=""; }
	if(!isset($headline)) { $headline=""; }
	if(!isset($text)) { $text=""; }
	if(!isset($media)) { $media=""; }
	if(!isset($caption)) { $caption=""; }
	if(!isset($credit)) { $credit=""; }
	if(!isset($tl_json_head)) { $tl_json_head=""; }

	$tl_json_tail .= sprintf('	{%s',$nl);
	$tl_json_tail .= sprintf('	"startDate":"%s",%s', $startdate,$nl);
	$tl_json_tail .= sprintf('	"endDate":"%s",%s', $enddate,$nl);
	$tl_json_tail .= sprintf('	"headline":"%s",%s', $headline,$nl);
	$tl_json_tail .= sprintf('	"text":"%s",%s', $text,$nl);
	$tl_json_tail .= sprintf('	"asset": {%s',$nl );
	$tl_json_tail .= sprintf('		"media":"%s",%s', $media,$nl);
	$tl_json_tail .= sprintf('		"credit":"%s",%s', $credit,$nl);
	$tl_json_tail .= sprintf('		"caption":"%s"%s', $caption,$nl);
	$tl_json_tail .= sprintf("		} } ] } }%s",$nl);

#	printf( "<h1>BUGS_600 db3=$db3 tbl=$tbl tlid=$tlid sql=$sql</h1>\n" );
#	exit();

#	print_r($row);
	if( $i  == 0 ) {
		$tl_json_head = '';
		$tl_json_head .= sprintf('{ "timeline": {%s',$nl);
		$tl_json_head .= sprintf('"headline": "NOTFOUND %s",%s',$headline, $nl);
		$tl_json_head .= sprintf('"type":"default",%s',$nl);
		$tl_json_head .= sprintf('"text":"%s",%s',$text, $nl);
		$tl_json_head .= sprintf('"startDate":"%s",%s',$startdate, $nl);
		$tl_json_head .= sprintf('"endDate":"%s",%s',$enddate, $nl);
	        $tl_json_head .= sprintf('"date": [ %s', $nl);
		$firsttime="no";
#		echo "BUGS_170 HEAD";
		}


	$json = "";
	$json .= $tl_json_head;
	$json .= $tl_json_body;
	$json .= $tl_json_tail;
	return( $json );
	}


function ajaks2($db3, $sql) {
// Open a new sqlite3 DB
//	$db3="avg.db3";
	$db = new SQLite3($db3);

	$firsttime="yes";
	$nl="\n";

	if ( $sql == "" ) { 
		$sql = 'select * from mp4 where file like "%/kt/%"'; 
		}
	$results= $db->query($sql);
	$data= array();
	while ($res= $results->fetchArray(1)) {
		array_push($data, $res);
		}
#	echo json_encode($data);
	return( json_encode($data));
	}

#  [
#  {"id":1,"algorithm":"GA"},
#  {"id":2,"algorithm":"PSO"},
#  {"id":3,"algorithm":"IWO"},
#  {"id":4,"algorithm":"OIWO"}
# ]

#	$a = 'How are you?';
#	$search = 'are y';
#	if(preg_match("/{$search}/i", $a)) {
#		echo 'true';
#		}


function tl_json_text($db3, $sql ) {
	$dttm=date('Ymd_His');
	$yyyy=date("Y"); $m=date("m"); $d=date("d");
	$nl="\n";

	$tl_headline=sprintf("jtfdcr: Defford Court Report %s-%s dttm=%s", $yyyy,$m, $dttm, $nl );
	$tl_text=sprintf("jtfdc_timeline: timejak dttm=%s",$dttm );
	$tl_startdate=sprintf("%s,%s,%s",$yyyy,$m,$d);;
	$tl_enddate=sprintf("%s",date('Y,m,d'));

	$tl_json_head = <<<TL_JSON_HEAD
{ "timeline": {
        "headline":"$tl_headline",
        "type":"default",
	"text":"$tl_text",
	"startDate":"$tl_startdate",
	"endDate":"$tl_enddate",
        "date": [ 
TL_JSON_HEAD;

	$tl_json_head = '';
	$tl_json_head .= sprintf('{ "timeline": {%s',$nl);
	$tl_json_head .= sprintf('"headline":"%s",%s',$tl_headline, $nl);
	$tl_json_head .= sprintf('"type":"default",%s',$nl);
	$tl_json_head .= sprintf('"text":"%s",%s',$tl_text, $nl);
	$tl_json_head .= sprintf('"startDate":"%s",%s',$tl_startdate, $nl);
	$tl_json_head .= sprintf('"endDate":"%s",%s',$tl_enddate, $nl);
        $tl_json_head .= sprintf('"date": [ %s', $nl);



	$dttm=date("Ymd_His");
	$startdate=date("Y,m,d");
	$enddate=date("Y,m,d");
	$headline = sprintf( "headline_%s", $dttm );
	$text = sprintf( "text_%s", $dttm );
	$media = sprintf( "%s", "/index0.mp4" );

	$credit = sprintf( "credit_%s", $dttm );
	$caption = sprintf( "caption_%s", $dttm );


$tl_json_body = <<<TL_JSON_BODY
		{
               	"startDate":"$startdate",
               	"endDate":"$enddate",
		"headline":"$headline",
		"text":"$text",
		"asset": {
			"media":"$media",
			"credit":"$credit",
			"caption":"$caption"
			} },
TL_JSON_BODY;

	$tl_json_body = "";
	$tl_json_body .= sprintf('	{%s',$nl);
	$tl_json_body .= sprintf('	"startDate":"%s",%s', $startdate,$nl);
	$tl_json_body .= sprintf('	"endDate":"%s",%s', $enddate,$nl);
	$tl_json_body .= sprintf('	"headline":"%s",%s', $headline,$nl);
	$tl_json_body .= sprintf('	"text":"%s",%s', $text,$nl);
	$tl_json_body .= sprintf('	"asset": {%s',$nl );
	$tl_json_body .= sprintf('		"media":"%s",%s', $media,$nl);
	$tl_json_body .= sprintf('		"credit":"%s",%s', $credit,$nl);
	$tl_json_body .= sprintf('		"caption":"%s"%s', $caption,$nl);
	$tl_json_body .= sprintf("		} },%s",$nl);


	$dttm=date("Ymd_His");
	$startdate="2019,8,6";
	$enddate=date("Y,m,d");
	$headline=sprintf("headline_tail_%s",$dttm );
	$text=sprintf("text_tail_%s",$dttm );
	$media=sprintf("%s","index0.mp4" );
	$credit=sprintf("credit_tail_%s",$dttm );
	$caption=sprintf("caption_tail_%s",$dttm );

$tl_json_tail = <<<TL_JSON_TAIL
 		{
                 "startDate":"$startdate",
                 "endDate":"$enddate",
                 "headline":"$headline",
                 "text":"$text",
                 "asset": {
 			"media":"$media",
 			"credit":"$credit",
 			"caption":"$caption"
 			} } ] } }
TL_JSON_TAIL;
 
	$tl_json_tail = "";
	$tl_json_tail .= sprintf('	{%s',$nl);
	$tl_json_tail .= sprintf('	"startDate":"%s",%s', $startdate,$nl);
	$tl_json_tail .= sprintf('	"endDate":"%s",%s', $enddate,$nl);
	$tl_json_tail .= sprintf('	"headline":"%s",%s', $headline,$nl);
	$tl_json_tail .= sprintf('	"text":"%s",%s', $text,$nl);
	$tl_json_tail .= sprintf('	"asset": {%s',$nl );
	$tl_json_tail .= sprintf('		"media":"%s",%s', $media,$nl);
	$tl_json_tail .= sprintf('		"credit":"%s",%s', $credit,$nl);
	$tl_json_tail .= sprintf('		"caption":"%s"%s', $caption,$nl);
	$tl_json_tail .= sprintf("		} } ] } }%s",$nl);

	$json = "";
	$json .= $tl_json_head;
	$json .= $tl_json_body;
	$json .= $tl_json_tail;
	echo( $json );

#	echo json_encode($json);
	return($json);
	}
function tlgif($gifnum,$tn) {
$tlgif_list=<<<TLGIF_LIST
/imgs/gif/time/giph_time_ticktocky.gif
/imgs/gif/time/giphy_recordtime.gif
/imgs/gif/time/giphy_time1.gif
/imgs/gif/time/giphy_time_1213.gif
/imgs/gif/time/giphy_time_clockrays.gif
/imgs/gif/time/giphy_time_clocks.gif
/imgs/gif/time/giphy_time_cubist.gif
/imgs/gif/time/giphy_time_cycle.gif
/imgs/gif/time/giphy_time_flywheel.gif
/imgs/gif/time/giphy_time_gears.gif
/imgs/gif/time/giphy_time_goo.gif
/imgs/gif/time/giphy_time_hotsand.gif
/imgs/gif/time/giphy_time_numbers.gif
/imgs/gif/time/giphy_time_running.gif
/imgs/gif/time/giphy_time_silouette.gif
/imgs/gif/time/giphy_time_spinn.gif
/imgs/gif/time/giphy_time_spiral.gif
/imgs/gif/time/giphy_time_spiral_up.gif
/imgs/gif/time/giphy_time_strobe.gif
/imgs/gif/time/giphy_time_swingers.gif
/imgs/gif/time/giphy_time_toons.gif
/imgs/gif/time/giphy_time_up.gif
/imgs/gif/time/giphy_timebench.gif
/imgs/gif/time/giphy_timeferro.gif
/imgs/gif/time/giphy_timegirls.gif
/imgs/gif/time/giphy_timeguy.gif
/imgs/gif/time/giphy_timegym.gif
/imgs/gif/time/giphy_timeinky.gif
/imgs/gif/time/giphy_timerunning.gif
/imgs/gif/time/giphy_timespiral_gold.gif
TLGIF_LIST;

$tlgiftn_list=<<<TLGIFTN_LIST
/imgs/gif/time/tn/tn_giph_time_ticktocky.gif
/imgs/gif/time/tn/tn_giph_time_ticktocky.gif
/imgs/gif/time/tn/tn_giphy_recordtime.gif
/imgs/gif/time/tn/tn_giphy_time1.gif
/imgs/gif/time/tn/tn_giphy_time_1213.gif
/imgs/gif/time/tn/tn_giphy_time_clockrays.gif
/imgs/gif/time/tn/tn_giphy_time_clocks.gif
/imgs/gif/time/tn/tn_giphy_time_cubist.gif
/imgs/gif/time/tn/tn_giphy_time_cycle.gif
/imgs/gif/time/tn/tn_giphy_time_flywheel.gif
/imgs/gif/time/tn/tn_giphy_time_gears.gif
/imgs/gif/time/tn/tn_giphy_time_goo.gif
/imgs/gif/time/tn/tn_giphy_time_hotsand.gif
/imgs/gif/time/tn/tn_giphy_time_numbers.gif
/imgs/gif/time/tn/tn_giphy_time_running.gif
/imgs/gif/time/tn/tn_giphy_time_schedule.gif
/imgs/gif/time/tn/tn_giphy_time_silouette.gif
/imgs/gif/time/tn/tn_giphy_time_spinn.gif
/imgs/gif/time/tn/tn_giphy_time_spiral.gif
/imgs/gif/time/tn/tn_giphy_time_spiral_up.gif
/imgs/gif/time/tn/tn_giphy_time_strobe.gif
/imgs/gif/time/tn/tn_giphy_time_swingers.gif
/imgs/gif/time/tn/tn_giphy_time_toons.gif
/imgs/gif/time/tn/tn_giphy_time_up.gif
/imgs/gif/time/tn/tn_giphy_timebench.gif
/imgs/gif/time/tn/tn_giphy_timeferro.gif
/imgs/gif/time/tn/tn_giphy_timegirls.gif
/imgs/gif/time/tn/tn_giphy_timeguy.gif
/imgs/gif/time/tn/tn_giphy_timegym.gif
/imgs/gif/time/tn/tn_giphy_timeinky.gif
/imgs/gif/time/tn/tn_giphy_timerunning.gif
/imgs/gif/time/tn/tn_giphy_timespiral_gold.gif
/imgs/gif/time/tn/tn_giphy_timespiral_gold.gif
TLGIFTN_LIST;
	if( $tn == "" ) { 
//		$tlgifs=explode("\n",$tlgif_list);
		$tlgifs=explode("\n",$tlgiftn_list);
		$min=1; $max=count($tlgifs)-1;
		if( $gifnum == "" ) { $gifnum=rand($max,$min); }
		if( $gifnum > $max ) { $gifnum=rand($max,$min); }
		$gif=$tlgifs[$gifnum]; 
		} 
	else { 
		$tlgiftns=explode("\n",$tlgiftn_list);
		$min=1; $max=count($tlgiftns)-1;
		if( $gifnum == "" ) { $gifnum=rand($max,$min); }
		if( $gifnum > $max ) { $gifnum=ran($max,$min); }
		$gif=$tlgiftns[$gifnum]; 
		}
	return($gif);
	}

function html_bluehost($bluehost_id) {
#	$hostname=$gethostbyaddr("10.5.50.111");
	$hostname=gethostname();
#	$hostname="ka1";
	$html = "";
	$html .= "<a href=https://bluehost.com/$bluehost_id/$hostname target=_blank>";
	$html .= "<img src=/imgs/btn/logo_bluehost.png height=20>";
#	$html .= "<img src=/imgs/kogrids/kob_grid.png height=20>";
	$html .= "</a>\n";
	return($html);
	}

function html_coffee($coffee_id) {
	$html = "";
	$html .= "<a href=https://buymeacoffee.com/$coffee_id target=_blank>";
	$html .= "<img src=/imgs/btn/logo_buymeacoffee.png height=20>";
	$html .= "</a>\n";
	return($html);
	}

function html_parallels($parallels_id) {
	$html = "";
	$html .= "<a href=https://parallels.com/$parallels_id target=_blank>";
	$html .= "<img src=/imgs/btn/logo_parallels.png height=20>";
	$html .= "</a>\n";
	return($html);
	}

function html_scripts_konet0($args) {
#	$html = "";
#	$html .= "<script id=script_toggle>\n";
#	$html .= "	function toggle(divid) {\n";
#	$html .= "		}\n";
#	$html .= "	</script>\n";

$html = <<<HTML_SCRIPTS
	<script id=script_toggle>
		function toggle(divid) {
                         var imgid=divid.replace("div_","img_" );
                         if(! document.getElementById(divid)) { return; }
                         var imgid=divid.replace("div_","img_" );
                         style_display=document.getElementById(divid).style.display;
                         if( style_display == "none" ) {
                                 img="<img src=/imgs/btn/koeyew.png id="+imgid+" height=50 onclick=\"toggle('"+divid+"'); return false;\" >";
                                 document.getElementById(divid).style.display="inline";
                                 document.getElementById(imgid).innerHTML=img;
                                 document.getElementById(imgid).src="/imgs/btn/koeyew.png";
                                 }
                         else {
                                 img="<img src=/imgs/btn/koeyeb.png id="+imgid+" height=50 onclick=\"toggle('"+divid+"'); return false;\" >";
                                 document.getElementById(divid).style.display="none";
                                 document.getElementById(imgid).innerHTML=img;
                                 document.getElementById(imgid).src="/imgs/btn/koeyeb.png";
                                 }
			}
		</script>
 
 	<script id="script_random_int" >
 		function random_int(max,min) {
 			min = Math.ceil(min);
 			max = Math.floor(max);
 			return Math.floor(Math.random() * (max - min + 1)) + min;
 			}
		</script>
 

	<script id=script_odd_or_even >
                 function odd_or_even(x) {return ( x & 1 ) ? "odd" : "even";}
		</script>

HTML_SCRIPTS;
	$perc="";
	$html .= " <script id=script_isodd >\n";
	$html .= "	function isodd(num) { return num $perc 2; }\n";
	$html .= "	</script>\n";
	return($html);
	}

function html_scripts_konet($args) {
$html_scripts_konet=<<<HTML_SCRIPTS_KONET
 	<script id=script_toggle>
                function toggle(divid) {
                         var imgid=divid.replace("div_","img_" );
                         if(! document.getElementById(divid)) { return; }
                         var imgid=divid.replace("div_","img_" );
                         style_display=document.getElementById(divid).style.display;
                         if( style_display == "none" ) {
                                 img="<img src=/imgs/btn/koeyew.png id="+imgid+" height=50 onclick=\"toggle('"+divid+"'); return false;\" >";
                                 document.getElementById(divid).style.display="inline";
                                 document.getElementById(imgid).innerHTML=img;
                                 document.getElementById(imgid).src="/imgs/btn/koeyew.png";
                                 }
                         else {
                                 img="<img src=/imgs/btn/koeyeb.png id="+imgid+" height=50 onclick=\"toggle('"+divid+"'); return false;\" >";
                                 document.getElementById(divid).style.display="none";
                                 document.getElementById(imgid).innerHTML=img;
                                 document.getElementById(imgid).src="/imgs/btn/koeyeb.png";
                                 }
                         }
                 </script>
 
 	<script id="script_random_int" >
 		function random_int(max,min) {
 			min = Math.ceil(min);
 			max = Math.floor(max);
 			return Math.floor(Math.random() * (max - min + 1)) + min;
 			}
 		</script>
 
         <script id=script_isodd >
                 function isOdd(num) { return num  2;}
                 function oddOrEven(x) {return ( x & 1 ) ? "odd" : "even";}
                 </script>
HTML_SCRIPTS_KONET;
 	return($html_scripts_konet);
 	}

function time2sec($time) {
	list($h, $m, $s) = explode (":", $time);
	$seconds = 0;
	$seconds += (intval($h) * 3600);
	$seconds += (intval($m) * 60);
	$seconds += (intval($s));
	return $seconds;
	}

function sec2time($sec) {
	return sprintf('%02d:%02d:%02d', floor($sec / 3600), floor($sec / 60 % 60), floor($sec % 60));
	}

function dateadd($date0,$interval) {
	$date=date_create($date0);
	date_add($date,date_interval_create_from_date_string($interval));
	return date_format($date,"Y-m-d");
	}

#	$newdate = date('Y-m-d', strtotime($date0. ' + 10 days'));
#	$time1 = time_to_sec("00:02:00");
#	$time2 =  time_to_sec("00:15:00");
#	$time3 = time_to_sec("00:08:00");
#	$total = $time1 + $time2 + $time3;
#	var_dump(sec_to_time($total));

#	$date0="2022-12-11";
#	$interval="40 days";
#	$interval="1 days";
#	$newdate=dateadd($date0,$interval);
#	printf( "<h1>BUGS_10 newdate=$newdate date0=$date0 interval=$interval</h1>\n" );
#	$time0 = "23:59:59";
#	$time1 = "23:59:59";
#	printf( "<h1>BUGS_11 time0=$time0 time1=$time1</h1>\n");
#	$secs0 = time2sec($time0);
#	$secs1 = time2sec($time1);
#	$secs = $secs0 + $secs1;
#	printf( "<h1>BUGS_12 secs=$secs secs0=$secs0 secs1=$secs1</h1>\n");
#	$time = sec2time($secs);
#	printf( "<h1>BUGS_13 time=$time</h1>\n" );

function sql3_upd($db3,$sql) {
	$db=new SQLite3($db3) or die( "<h1>ERR_890 db3=$db3</h1>\n" );
	$db->exec($sql);
	}

function wz($args) {
$wz=<<<WZ
	<script id="wz_library" src='data:/text/plain;base64,DQoNCi8vSW50ZWdyYXRlZCB0byBXYWx0ZXIgWm9ybiBodG1sIGxpYnJhcnkNCg0KLy8gZnVuY3Rpb24gZXhlY3V0ZVRlc3Q6IGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9uIGxheWVyT2JqZWN0Lmh0bQ0KZnVuY3Rpb24gZXhlY3V0ZVRlc3QoKXsNCg0KdHJhbnNmb3JtTGF5ZXIgKGRvY3VtZW50LmZvcm1zWzBdLngudmFsdWUsZG9jdW1lbnQuZm9ybXNbMF0ueS52YWx1ZSxkb2N1bWVudC5mb3Jtc1swXS53LnZhbHVlLGRvY3VtZW50LmZvcm1zWzBdLmgudmFsdWUsIkJsb3F1ZSIsMTAwLDEwKTsNCg0KDQp9DQoNCi8vIFVzZXMgV1ogZGh0bWwgbGlicmFyeSB0byBtYWtlIHRpbWVkIHRyYW5zZm9ybWF0aW9ucyBvZiBkaHRtbCwNCi8vIHNvIG1pbmltaXppbmcsIG1heGltaXppbmcgbGF5ZXJzIGNhbiBiZSByYXRoZXIgInNtb290IiBmb3IgdXNlciwNCi8vIHNpbXVsYXRpbmcgd2luZG93cyBvcy4NCg0KLy9GdW5jdGlvbiB0cmFuc2Zvcm1MYXllcg0KLy94LHkgPSBQb3NpdGlvbi4gVG9wIGxlZnQgY29ybmVyIGNvb3JkaW5hdGVzDQovL3csaCA9IFNpemUuIHdpZHRoIGFuZCBoZWlnaHQgb2YgPGRpdj48L2Rpdj4gbGF5ZXINCi8vaWQgPSBpZCBvZiB0aGUgRGl2IChpLmUuOiBpZD0ibXlMYXllciIsIHRoZW4sIHVzZSAibXlMYXllciIsIFdJVEggcXVvdGVzISkNCi8vZHVyYXRpb24gPSBEdXJhdGlvbiwgaW4gbWlsaXNlY29uZHMNCi8vc3RlcHMgPSBUcmFuc2l0aW9uIGludGVydmFscw0KDQpmdW5jdGlvbiB0cmFuc2Zvcm1MYXllciAoeCx5LHcsaCxpZCxkdXJhdGlvbixzdGVwcykgew0KICANCiAgLy9kdXJhdGlvbiBpcyBpbiBzZWNvbmRzDQogIHN0ZXBEdXJhdGlvbiA9IE1hdGgucm91bmQoZHVyYXRpb24vc3RlcHMpIDsgLy8gVmFsdWUgaXMgaW4gbWlsaXNlY29uZHMuDQoNCiAgb2JqID0gZGQuZWxlbWVudHNbaWRdOw0KICANCg0KICAvLyBHZXQgb3JpZ2luYWwgdmFsdWVzOiB4LHkgPSB0b3AgbGVmdCBjb3JuZXI7ICB3LGggPSB3aWR0aCBoZWlnaHQgICANCiAgDQogIHgxID0gb2JqLng7ICANCiAgeTEgPSBvYmoueTsgIA0KICB3MSA9IG9iai53OyAgDQogIGgxID0gb2JqLmg7ICANCg0KDQogIC8vIElmIHZhbHVlcyBub3Qgc2V0LCBvciB6ZXJvLCB3ZSBkbyBub3QgbW9kaWZ5IHRoZW0sIGFuZCB0YWtlIG9yaWdpbmFsIGFzIGZpbmFsIGFzIHdlbGwNCiAgeCA9ICh4KT94OngxOw0KICB5ID0gKHkpP3k6eTE7DQogIHcgPSAodyk/dzp3MTsNCiAgaCA9IChoKT9oOmgxOw0KDQogIC8vIGhvdyBtdWNoIGRvIHdlIG5lZWQgdG8gbW9kaWZ5IG91ciB2YWx1ZXMgZm9yIGVhY2ggc3RlcD8NCiAgLy8gVGhlIFdaIGxpYnJhcnkgbW92ZUJ5IGFuZCByZXNpemVCeSB0YWtlcyB0aGUgZGlmZiB3aXRoIGludmVydGVkIHNpZ24gYXMgZnJvbSBvcmlnaW5hbCBjZSBzY3JpcHQ6DQogIGRpZlggPSAoeCAtIHgxKS9zdGVwczsgIA0KICBkaWZZID0gKHkgLSB5MSkvc3RlcHM7ICANCiAgZGlmVyA9ICh3IC0gdzEpL3N0ZXBzOyAgDQogIGRpZkggPSAoaCAtIGgxKS9zdGVwczsgIA0KICANCiAgDQogIA0KICBpZih0b3AuZGVidWc9PXRydWUpICB3aW5kb3cuYWxlcnQoJ3gxOicreDErJywgeTE6Jyt5MSsnLCB3MTonK3cxKycsIGgxOicraDErJyw8YnI+eDonK3grJywgeTonK3krJywgdzonK3crJywgaDonK2grJywgPGJyPmRpZlg6JytkaWZYKycsIGRpZlk6JytkaWZZKycsIGRpZlc6JytkaWZXKycsIGRpZkg6JytkaWZIKycsPGJyPmR1cmF0aW9uOicrZHVyYXRpb24rJywgPGJyPnN0ZXBzOicrc3RlcHMrJyw8YnI+c3RlcER1cmF0aW9uOicrc3RlcER1cmF0aW9uKycnKTsNCiANCiAgb2JqLm1vdmVCeShkaWZYLGRpZlkpOw0KICBvYmoucmVzaXplQnkoZGlmVyxkaWZIKTsNCg0KICAvL1dlIHRha2Ugb3V0IHRoZSBhbW91bnQgb2YgdGltZSB1c2VkLCBhbmQgYSBzdGVwIGFscmVhZHkgYmVpbmcgZXhlY3V0ZWQNCiAgZHVyYXRpb24gPSAoZHVyYXRpb24gLSBzdGVwRHVyYXRpb24pOw0KICBzdGVwcyAtLTsNCg0KCS8vSWYgdGhlcmUgaXMgYW55IHN0ZXAgbGVmdCwgd2UgZXhlY3V0ZSBhZ2Fpbg0KCWlmKHN0ZXBzPj0wKXsNCgkgc2V0VGltZW91dCgndHJhbnNmb3JtTGF5ZXIoJyt4KycsJyt5KycsJyt3KycsJytoKycsIicraWQrJyIsJytkdXJhdGlvbisnLCcrc3RlcHMrJyknLHN0ZXBEdXJhdGlvbik7DQoJIH0NCiAgLy9JZiBSZXR1cm4uLi4gd2UgY291bGQgc2V0IHNvbWUgYXBpIGhlcmUgYXMgdG8gY2FsbCBhIGZ1bmN0aW9uIHRvIGJlIGV2YWx1YXRlZCBieSB0aGUgamF2YXNjcmlwdCxpZiBzZXQsIG9uIHJldHVybg0KICAvL2ZvciBleGFtcGxlIHRvIGNhbGwgdGhlIGZ1bmN0aW9uIHRoYXQgaGFzIHRvIHBvcHVsYXRlIHRoZSBkaXYgd2l0aCBjb250ZW50DQogIC8vYnV0IFdaIGhhcyBhbHJlYWR5IHRob3VnaHQgb24gaXQgOi0pDQogIHJldHVybjsNCg0KfQ0KDQo='></script>


	<script id="wz_dragdrop" src='data:/text/plain;base64,LyogVGhpcyBub3RpY2UgbXVzdCBiZSB1bnRvdWNoZWQgYXQgYWxsIHRpbWVzLCBhbmQgbXVzdCBub3QgYmUgcmVtb3ZlZC4KCnd6X2RyYWdkcm9wLmpzCXYuIDQuOTEKVGhlIGxhdGVzdCB2ZXJzaW9uIGlzIGF2YWlsYWJsZSBhdApodHRwOi8vd3d3LndhbHRlcnpvcm4uY29tCm9yIGh0dHA6Ly93d3cuZGV2aXJhLmNvbQpvciBodHRwOi8vd3d3LndhbHRlcnpvcm4uZGUKCkNvcHlyaWdodCAoYykgV2FsdGVyIFpvcm4uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCkNyZWF0ZWQgMjYuIDguIDIwMDIgYnkgV2FsdGVyIFpvcm4gKFdlYjogaHR0cDovL3d3dy53YWx0ZXJ6b3JuLmNvbSApCkxhc3QgbW9kaWZpZWQ6IDEwLjEwLjIwMDgKClRoaXMgREhUTUwgJiBEcmFnJkRyb3AgTGlicmFyeSBhZGRzIERyYWcmRHJvcCBmdW5jdGlvbmFsaXR5IHRvOgotIGltYWdlcywgZXZlbiB0aG9zZSBub3QgcG9zaXRpb25lZCB2aWEgbGF5ZXJzLAogIG5vciB2aWEgc3R5bGVzaGVldHMgb3IgYW55IG90aGVyIGtpbmQgb2YgImhhcmQtY29kaW5nIjsKLSByZWxhdGl2ZWx5IGFuZCBhYnNvbHV0ZWx5IHBvc2l0aW9uZWQgbGF5ZXJzIChESVYgZWxlbWVudHMpLgpNb3Jlb3ZlciwgaXQgcHJvdmlkZXMgZXh0ZW5kZWQgREhUTUwgY2FwYWJpbGl0aWVzLgoKTElDRU5TRTogTEdQTAoKVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgptb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCkxpY2Vuc2UgKExHUEwpIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgpUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgoKRm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLApzZWUgaHR0cDovL3d3dy5nbnUub3JnL2NvcHlsZWZ0L2xlc3Nlci5odG1sCiovCgoKLy8gUEFUSCBUTyBUSEUgVFJBTlNQQVJFTlQgMSoxIFBYIElNQUdFIChyZXF1aXJlZCBieSBOUyA0IGFzIHNwYWNlcikKdmFyIHNwYWNlciA9ICd0cmFuc3BhcmVudHBpeGVsLmdpZic7CgoKCgovL3dpbmRvdy5vbmVycm9yID0gbmV3IEZ1bmN0aW9uKCdyZXR1cm4gdHJ1ZTsnKTsKCgovLyBPcHRpb25hbCBjb21tYW5kcyBwYXNzZWQgdG8gU0VUX0RIVE1MKCkgb24gdGhlIGh0bWwtcGFnZSAoZzogbWF5IGJlIGFwcGxpZWQgZ2xvYmFsbHksIGk6IGluZGl2aWR1YWxseSkKdmFyIENMT05FCQkJPSAnQzEwbkUnOyAgIC8vIGkgIGltZwkgIGNsb25lIGltYWdlCnZhciBDT1BZCQkJPSAnQzBwWSc7CS8vIGkgIGltZwkgIGNyZWF0ZSBjb3BpZXMKdmFyIERFVEFDSF9DSElMRFJFTiA9ICdkMzdhQ0gnOyAgLy8gaSAgbHlyCSAgZGV0YWNoIGltYWdlcwp2YXIgSE9SSVpPTlRBTAkJPSAnSDByMVonOyAgIC8vIGkgIGltZyxseXIgIGhvcml6b250YWxseSBkcmFnZ2FibGUgb25seQp2YXIgTUFYSEVJR0hUCQk9ICdtN3g4SSc7ICAgLy8gaSAgaW1nLGx5ciAgbWF4aW11bSBoZWlnaHQgbGltaXQsICIKdmFyIE1BWE9GRkJPVFRPTQk9ICdtN3hkMHdOJzsgLy8gaSAgaW1nLGx5ciAgZG93bndhcmQgb2Zmc2V0IGxpbWl0CnZhciBNQVhPRkZMRUZUCQk9ICdtN3gyM0Z0JzsgLy8gaSAgaW1nLGx5ciAgbGVmdHdhcmQgb2Zmc2V0IGxpbWl0CnZhciBNQVhPRkZSSUdIVAkJPSAnbTd4MEZmOCc7IC8vIGkgIGltZyxseXIgIHJpZ2h0d2FyZCBvZmZzZXQgbGltaXQKdmFyIE1BWE9GRlRPUAkJPSAnbTd4dTknOyAgIC8vIGkgIGltZyxseXIgIHVwd2FyZCBvZmZzZXQgbGltaXQKdmFyIE1BWFdJRFRICQk9ICdtN3hXMSc7ICAgLy8gaSAgaW1nLGx5ciAgbWF4aW11bSB3aWR0aCBsaW1pdCwgdXNlIHdpdGggcmVzaXphYmxlIG9yIHNjYWxhYmxlCnZhciBNSU5XSURUSAkJPSAnbTFudzEnOyAgIC8vIGkgIGltZyxseXIgIG1pbmltdW0gd2lkdGggbGltaXQsICIKdmFyIE1JTkhFSUdIVAkJPSAnbTFuOEknOyAgIC8vIGkgIGltZyxseXIgIG1pbmltdW0gaGVpZ2h0IGxpbWl0LCAiCnZhciBOT19BTFQJCQk9ICdubzgxVCc7ICAgLy8gZ2kgaW1nCSAgZGlzYWJsZSBhbHQgYW5kIHRpdGxlIGF0dHJpYnV0ZXMKdmFyIE5PX0RSQUcJCQk9ICdOMGQ0QWcnOyAgLy8gaSAgaW1nLGx5ciAgZGlzYWJsZSBkcmFnZ2FiaWxpdHkKdmFyIFJFU0VUX1oJCQk9ICdyMzVFN3onOyAgLy8gZ2kgaW1nLGx5ciAgcmVzZXQgei1pbmRleCB3aGVuIGRyb3BwZWQKdmFyIFJFU0laQUJMRQkJPSAncjVJWmJsJzsgIC8vIGdpIGltZyxseXIgIHJlc2l6YWJsZSBpZiA8Y3RybD4gb3IgPHNoaWZ0PiBwcmVzc2VkCnZhciBTQ0FMQUJMRQkJPSAnU0NMYmwnOyAgIC8vIGdpIGltZyxseXIgIHNjYWxhYmxlCQkgICAiCnZhciBTQ1JPTEwJCQk9ICdzQzhsTCc7ICAgLy8gZ2kgaW1nLGx5ciAgZW5hYmxlIGF1dG8gc2Nyb2xsIGZ1bmN0aW9uYWxpdHkKdmFyIFRSQU5TUEFSRU5UCQk9ICdkSUFwSEFuJzsgLy8gZ2kgaW1nLGx5ciAgdHJhbnNsdWNlbnQgd2hpbGUgZHJhZ2dlZAp2YXIgVkVSVElDQUwJCT0gJ1YzUnQxQyc7ICAvLyBpICBpbWcsbHlyICB2ZXJ0aWNhbGx5IGRyYWdnYWJsZSBvbmx5CnZhciBkZF9jdXJzb3JzID0gbmV3IEFycmF5KAoJJ2M6ZGVmYXVsdCcsCgknYzpjcm9zc2hhaXInLAoJJ2M6ZS1yZXNpemUnLAoJJ2M6aGFuZCcsCgknYzpoZWxwJywKCSdjOm1vdmUnLAoJJ2M6bi1yZXNpemUnLAoJJ2M6bmUtcmVzaXplJywKCSdjOm53LXJlc2l6ZScsCgknYzpzLXJlc2l6ZScsCgknYzpzZS1yZXNpemUnLAoJJ2M6c3ctcmVzaXplJywKCSdjOnRleHQnLAoJJ2M6dy1yZXNpemUnLAoJJ2M6d2FpdCcKKTsKZm9yKHZhciBkZF9pID0gZGRfY3Vyc29ycy5sZW5ndGg7IGRkX2k7KQp7LS1kZF9pOwoJZXZhbCgndmFyIENVUlNPUl8nICsgKGRkX2N1cnNvcnNbZGRfaV0uc3Vic3RyaW5nKDIpLnRvVXBwZXJDYXNlKCkucmVwbGFjZSgnLScsICdfJykpICsgJyA9ICInICsgZGRfY3Vyc29yc1tkZF9pXSArICciOycpOwp9CnZhciBkZF91ID0gInVuZGVmaW5lZCI7CmZ1bmN0aW9uIFdaREQoKQp7Cgl0aGlzLmVsZW1lbnRzID0gbmV3IEFycmF5KDApOwoJdGhpcy5vYmogPSBudWxsOwoJdGhpcy5uID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpOwoJdGhpcy5kYiA9IChkb2N1bWVudC5jb21wYXRNb2RlICYmIGRvY3VtZW50LmNvbXBhdE1vZGUudG9Mb3dlckNhc2UoKSAhPSAiYmFja2NvbXBhdCIpPwoJCWRvY3VtZW50LmRvY3VtZW50RWxlbWVudAoJCTogKGRvY3VtZW50LmJvZHkgfHwgbnVsbCk7Cgl0aGlzLm9wID0gISEod2luZG93Lm9wZXJhICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKTsKCWlmKHRoaXMub3ApIGRvY3VtZW50Lm9ubW91c2Vkb3duID0gbmV3IEZ1bmN0aW9uKCdlJywKCQknaWYoKChlID0gZSB8fCB3aW5kb3cuZXZlbnQpLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQpLnRhZ05hbWUgPT0gIklNQUdFIikgcmV0dXJuIGZhbHNlOycpOwoJdGhpcy5pZSA9ICEhKHRoaXMubi5pbmRleE9mKCJtc2llIikgPj0gMCAmJiBkb2N1bWVudC5hbGwgJiYgdGhpcy5kYiAmJiAhdGhpcy5vcCk7Cgl0aGlzLmllbWFjID0gISEodGhpcy5pZSAmJiB0aGlzLm4uaW5kZXhPZigibWFjIikgPj0gMCk7Cgl0aGlzLmllNCA9ICEhKHRoaXMuaWUgJiYgIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKTsKCXRoaXMubjQgPSAhIShkb2N1bWVudC5sYXllcnMgJiYgdHlwZW9mIGRvY3VtZW50LmNsYXNzZXMgIT0gZGRfdSk7Cgl0aGlzLm42ID0gISEodHlwZW9mIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlICE9IGRkX3UgJiYgdHlwZW9mIGRvY3VtZW50LmNyZWF0ZVJhbmdlICE9IGRkX3UpOwoJdGhpcy53M2MgPSAhISghdGhpcy5vcCAmJiAhdGhpcy5pZSAmJiAhdGhpcy5uNiAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCk7Cgl0aGlzLmNlID0gISEoZG9jdW1lbnQuY2FwdHVyZUV2ZW50cyAmJiBkb2N1bWVudC5yZWxlYXNlRXZlbnRzICYmICF0aGlzLm42KTsKCXRoaXMucHggPSB0aGlzLm40PyAnJyA6ICdweCc7Cgl0aGlzLnRXYWl0ID0gdGhpcy53M2M/IDQwIDogMTA7Cgl0aGlzLm5vUmVjYWxjID0gZmFsc2U7Cn0KdmFyIGRkID0gbmV3IFdaREQoKTsKCmRkLkludCA9IGZ1bmN0aW9uKGRfeCwgZF95KQp7CglyZXR1cm4gaXNOYU4oZF95ID0gcGFyc2VJbnQoZF94KSk/IDAgOiBkX3k7Cn07CmRkLmdldFduZFcgPSBmdW5jdGlvbigpCnsKCXJldHVybiBkZC5JbnQoCgkJKGRkLmRiICYmICFkZC5vcCAmJiAhZGQudzNjICYmIGRkLmRiLmNsaWVudFdpZHRoKT8gZGQuZGIuY2xpZW50V2lkdGgKCQk6ICh3aW5kb3cuaW5uZXJXaWR0aCB8fCAwKQoJKTsKfTsKZGQuZ2V0V25kSCA9IGZ1bmN0aW9uKCkKewoJcmV0dXJuIGRkLkludCgKCQkoZGQuZGIgJiYgIWRkLm9wICYmICFkZC53M2MgJiYgZGQuZGIuY2xpZW50SGVpZ2h0KT8gZGQuZGIuY2xpZW50SGVpZ2h0CgkJOiAod2luZG93LmlubmVySGVpZ2h0IHx8IDApCgkpOwp9OwpkZC5nZXRTY3JvbGxYID0gZnVuY3Rpb24oKQp7CglyZXR1cm4gZGQuSW50KHdpbmRvdy5wYWdlWE9mZnNldCB8fCAoZGQuZGI/IGRkLmRiLnNjcm9sbExlZnQgOiAwKSk7Cn07CmRkLmdldFNjcm9sbFkgPSBmdW5jdGlvbigpCnsKCXJldHVybiBkZC5JbnQod2luZG93LnBhZ2VZT2Zmc2V0IHx8IChkZC5kYj8gZGQuZGIuc2Nyb2xsVG9wIDogMCkpOwp9OwpkZC5nZXRQYWdlWFkgPSBmdW5jdGlvbihkX28pCnsKCWlmKGRkLm40ICYmIGRfbykKCXsKCQlkZC54ID0gZF9vLnBhZ2VYIHx8IDA7CgkJZGQueSA9IGRfby5wYWdlWSB8fCAwOwoJfQoJZWxzZQoJewoJCWRkLnggPSBkZC55ID0gMDsgLy9nbG9iYWwgaGVscGVyIHZhcnMKCQl3aGlsZShkX28pCgkJewoJCQlkZC54ICs9IGRkLkludChkX28ub2Zmc2V0TGVmdCk7CgkJCWRkLnkgKz0gZGQuSW50KGRfby5vZmZzZXRUb3ApOwoJCQlkX28gPSBkX28ub2Zmc2V0UGFyZW50IHx8IG51bGw7CgkJfQoJfQp9OwpkZC5nZXRDc3NYWSA9IGZ1bmN0aW9uKGRfbykKewoJaWYoZF9vLmRpdikKCXsKCQlpZihkZC5uNCkKCQl7CgkJCWRfby5jc3N4ID0gZF9vLmRpdi54OwoJCQlkX28uY3NzeSA9IGRfby5kaXYueTsKCQl9CgkJZWxzZSBpZihkZC5pZTQpCgkJewoJCQlkX28uY3NzeCA9IGRfby5jc3MucGl4ZWxMZWZ0OwoJCQlkX28uY3NzeSA9IGRfby5jc3MucGl4ZWxUb3A7CgkJfQoJCWVsc2UKCQl7CgkJCWRfby5jc3MubGVmdCA9IGRfby5jc3MudG9wID0gMCArIGRkLnB4OwoJCQlkZC5nZXRQYWdlWFkoZF9vLmRpdik7CgkJCWRfby5jc3N4ID0gZF9vLnggLSBkZC54OwoJCQlkX28uY3NzeSA9IGRfby55IC0gZGQueTsKCQkJZF9vLmNzcy5sZWZ0ID0gZF9vLmNzc3ggKyBkZC5weDsKCQkJZF9vLmNzcy50b3AgPSBkX28uY3NzeSArIGRkLnB4OwoJCX0KCX0KCWVsc2UKCXsKCQlkX28uY3NzeCA9IDA7CgkJZF9vLmNzc3kgPSAwOwoJfQp9OwpkZC5nZXRJbWdXID0gZnVuY3Rpb24oZF9vKQp7CglyZXR1cm4gZF9vPyBkZC5JbnQoZF9vLndpZHRoKSA6IDA7Cn07CmRkLmdldEltZ0ggPSBmdW5jdGlvbihkX28pCnsKCXJldHVybiBkX28/IGRkLkludChkX28uaGVpZ2h0KSA6IDA7Cn07CmRkLmdldERpdlcgPSBmdW5jdGlvbihkX28pCnsKCXJldHVybiBkZC5JbnQoCgkJZGQubjQ/IChkX28uZGl2PyBkX28uZGl2LmNsaXAud2lkdGggOiAwKQoJCTogZF9vLmRpdj8gKGRfby5kaXYub2Zmc2V0V2lkdGggfHwgZF9vLmNzcy5waXhlbFdpZHRoIHx8IGRfby5jc3Mud2lkdGggfHwgMCkKCQk6IDAKCSk7Cn07CmRkLmdldERpdkggPSBmdW5jdGlvbihkX28pCnsKCXJldHVybiBkZC5JbnQoCgkJZGQubjQ/IChkX28uZGl2PyBkX28uZGl2LmNsaXAuaGVpZ2h0IDogMCkKCQk6IGRfby5kaXY/IChkX28uZGl2Lm9mZnNldEhlaWdodCB8fCBkX28uY3NzLnBpeGVsSGVpZ2h0IHx8IGRfby5jc3MuaGVpZ2h0IHx8IDApCgkJOiAwCgkpOwp9OwpkZC5nZXRXSCA9IGZ1bmN0aW9uKGRfbykKewoJZF9vLncgPSBkZC5nZXREaXZXKGRfbyk7CglkX28uaCA9IGRkLmdldERpdkgoZF9vKTsKCWlmKGRfby5jc3MpCgl7CgkJZF9vLmNzcy53aWR0aCA9IGRfby53ICsgZGQucHg7CgkJZF9vLmNzcy5oZWlnaHQgPSBkX28uaCArIGRkLnB4OwoJCWRfby5kdyA9IGRkLmdldERpdlcoZF9vKS1kX28udzsKCQlkX28uZGggPSBkZC5nZXREaXZIKGRfbyktZF9vLmg7CgkJZF9vLmNzcy53aWR0aCA9IChkX28udy1kX28uZHcpICsgZGQucHg7CgkJZF9vLmNzcy5oZWlnaHQgPSAoZF9vLmgtZF9vLmRoKSArIGRkLnB4OwoJfQoJZWxzZSBkX28uZHcgPSBkX28uZGggPSAwOwp9OwpkZC5nZXRDc3NQcm9wID0gZnVuY3Rpb24oZF9vLCBkX3BuNiwgZF9wc3R5bGUsIGRfcG40KQp7CglpZihkX28gJiYgZGQubjYpIHJldHVybiAnJyt3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkX28sIG51bGwpLmdldFByb3BlcnR5VmFsdWUoZF9wbjYpOwoJaWYoZF9vICYmIGRfby5jdXJyZW50U3R5bGUpIHJldHVybiAnJytldmFsKCdkX28uY3VycmVudFN0eWxlLicrZF9wc3R5bGUpOwoJaWYoZF9vICYmIGRfby5zdHlsZSkgcmV0dXJuICcnK2V2YWwoJ2Rfby5zdHlsZS4nK2RfcHN0eWxlKTsKCWlmKGRfbyAmJiBkZC5uNCkgcmV0dXJuICcnK2V2YWwoJ2Rfby4nK2RfcG40KTsKCXJldHVybiAnJzsKfTsKZGQuZ2V0RGl2ID0gZnVuY3Rpb24oZF94LCBkX2QpCnsKCWRfZCA9IGRfZCB8fCBkb2N1bWVudDsKCWlmKGRkLm40KQoJewoJCWlmKGRfZC5sYXllcnNbZF94XSkgcmV0dXJuIGRfZC5sYXllcnNbZF94XTsKCQlmb3IodmFyIGRfaSA9IGRfZC5sYXllcnMubGVuZ3RoOyBkX2k7KQoJCXsKCQkJdmFyIGRfeSA9IGRkLmdldERpdihkX3gsIGRfZC5sYXllcnNbLS1kX2ldLmRvY3VtZW50KTsKCQkJaWYoZF95KSByZXR1cm4gZF95OwoJCX0KCX0KCWlmKGRkLmllKSByZXR1cm4gZF9kLmFsbFtkX3hdIHx8IG51bGw7CglpZihkX2QuZ2V0RWxlbWVudEJ5SWQpIHJldHVybiBkX2QuZ2V0RWxlbWVudEJ5SWQoZF94KSB8fCBudWxsOwoJcmV0dXJuIG51bGw7Cn07CmRkLmdldEltZyA9IGZ1bmN0aW9uKGRfbywgZF9ubSwgZF94eSwgZF93KQp7CglkX3cgPSBkX3cgfHwgd2luZG93OwoJdmFyIGRfaW1nOwoJaWYoZG9jdW1lbnQuaW1hZ2VzICYmIChkX2ltZyA9IGRfdy5kb2N1bWVudC5pbWFnZXNbZF9ubV0pKQoJewoJCWlmKGRfeHkpCgkJewoJCQlpZihkZC5uNCkKCQkJewoJCQkJZGQuZ2V0UGFnZVhZKGRfdyk7CgkJCQlkX28uZGVmeCA9IGRfaW1nLnggKyBkZC54OwoJCQkJZF9vLmRlZnkgPSBkX2ltZy55ICsgZGQueTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWRkLmdldFBhZ2VYWShkX2ltZyk7CgkJCQlkX28uZGVmeCA9IGRkLng7CgkJCQlkX28uZGVmeSA9IGRkLnk7CgkJCX0KCQl9CgkJcmV0dXJuIGRfaW1nOwoJfQoJaWYoZGQubjQpIGZvcih2YXIgZF9pID0gZF93LmRvY3VtZW50LmxheWVycy5sZW5ndGg7IGRfaTspCgl7CgkJdmFyIGRfeSA9IGRkLmdldEltZyhkX28sIGRfbm0sIGRfeHksIGRfdy5kb2N1bWVudC5sYXllcnNbLS1kX2ldKTsKCQlpZihkX3kpIHJldHVybiBkX3k7Cgl9CglyZXR1cm4gbnVsbDsKfTsKZGQuZ2V0UGFyZW50ID0gZnVuY3Rpb24oZF9vLCBkX3ApCnsKCWlmKGRkLm40KQoJewoJCWZvcih2YXIgZF9pID0gZGQuZWxlbWVudHMubGVuZ3RoOyBkX2k7KQoJCXsKCQkJaWYoISgoZF9wID0gZGQuZWxlbWVudHNbLS1kX2ldKS5pc19pbWFnZSkgJiYgZF9wLmRpdiAmJiAoZF9wLmRpdi5kb2N1bWVudC5sYXllcnNbZF9vLm5hbWVdIHx8IGRfby5vaW1nICYmIGRfcC5kaXYuZG9jdW1lbnQuaW1hZ2VzW2Rfby5vaW1nLm5hbWVdKSkKCQkJCWRfcC5hZGRDaGlsZChkX28sIGRfcC5kZXRhY2gsIDEpOwoJCX0KCX0KCWVsc2UKCXsKCQlkX3AgPSBkX28uaXNfaW1hZ2U/IGRkLmdldEltZyhkX28sIGRfby5vaW1nLm5hbWUpIDogKGRfby5kaXYgfHwgbnVsbCk7CgkJd2hpbGUoZF9wICYmICEhKGRfcCA9IGRfcC5vZmZzZXRQYXJlbnQgfHwgZF9wLnBhcmVudE5vZGUgfHwgbnVsbCkpCgkJewoJCQlpZihkX3AuZGRPYmopCgkJCXsKCQkJCWRfcC5kZE9iai5hZGRDaGlsZChkX28sIGRfcC5kZE9iai5kZXRhY2gsIDEpOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9Cn07CmRkLmdldENtZCA9IGZ1bmN0aW9uKGRfbywgZF9jbWQsIGRfY21kU3RyKQp7Cgl2YXIgZF9pID0gZF9vLmlkLmluZGV4T2YoZF9jbWQpLCBkX2osCglkX3kgPSAoZF9pID49IDApKjE7CglpZihkX3kpCgl7CgkJZF9qID0gZF9pK2RfY21kLmxlbmd0aDsKCQlpZihkX2NtZFN0cikgZF9vLmNtZCArPSBkX28uaWQuc3Vic3RyaW5nKGRfaSwgZF9qKTsKCQlkX28uaWQgPSBkX28uaWQuc3Vic3RyaW5nKDAsIGRfaSkgKyBkX28uaWQuc3Vic3RyaW5nKGRfaik7Cgl9CglyZXR1cm4gZF95Owp9OwpkZC5nZXRDbWRWYWwgPSBmdW5jdGlvbihkX28sIGRfY21kLCBkX2NtZFN0ciwgaW50MCkKewoJdmFyIGRfaSA9IGRfby5pZC5pbmRleE9mKGRfY21kKSwgZF9qLAoJZF95ID0gKGRfby5pZC5pbmRleE9mKGRfY21kKSA+PSAwKT8gZGQuSW50KGRfby5pZC5zdWJzdHJpbmcoZF9vLmlkLmluZGV4T2YoZF9jbWQpK2RfY21kLmxlbmd0aCkpIDogaW50MD8gLTEgOiAwOwoJaWYoIWludDAgJiYgZF95IHx8IGludDAgJiYgZF95ID49IDApCgl7CgkJZF9qID0gZF9pK2RfY21kLmxlbmd0aCsoIiIrZF95KS5sZW5ndGg7CgkJaWYoZF9jbWRTdHIpIGRfby5jbWQgKz0gZF9vLmlkLnN1YnN0cmluZyhkX2ksIGRfaik7CgkJZF9vLmlkID0gZF9vLmlkLnN1YnN0cmluZygwLCBkX2kpICsgZF9vLmlkLnN1YnN0cmluZyhkX2opOwoJfQoJcmV0dXJuIGRfeTsKfTsKZGQuYWRkRWx0ID0gZnVuY3Rpb24oZF9vLCBkX3ApCnsKCWRkLmVsZW1lbnRzW2Rfby5uYW1lXSA9IGRkLmVsZW1lbnRzW2Rfby5pbmRleCA9IGRkLmVsZW1lbnRzLmxlbmd0aF0gPSBkX287CglpZihkX3ApIGRfcC5jb3BpZXNbZF9vLm5hbWVdID0gZF9wLmNvcGllc1tkX3AuY29waWVzLmxlbmd0aF0gPSBkX287Cn07CmRkLm1rV3pEb20gPSBmdW5jdGlvbigpCnsKCXZhciBkX28sIGRfbCA9IGRkLmVsZW1lbnRzLmxlbmd0aCwgZF9pOwoJZm9yKGRfaSA9IGRfbDsgZF9pOykgZGQuZ2V0UGFyZW50KGRkLmVsZW1lbnRzWy0tZF9pXSk7Cglmb3IoZF9pID0gZF9sOyBkX2k7KQoJewoJCWlmKChkX28gPSBkZC5lbGVtZW50c1stLWRfaV0pLmNoaWxkcmVuICYmICFkX28ucGFyZW50KQoJCXsKCQkJZm9yKHZhciBkX2ogPSBkX28uY2hpbGRyZW4ubGVuZ3RoOyBkX2o7KQoJCQl7LS1kX2o7CgkJCQlkX28uY2hpbGRyZW5bZF9qXS5zZXRaKGRfby56K2Rfby5jaGlsZHJlbltkX2pdLnosIDEpOwoJCQl9CgkJfQoJfQp9OwpkZC5hZGRQcm9wcyA9IGZ1bmN0aW9uKGRfbykKewoJaWYoZF9vLmlzX2ltYWdlKQoJewoJCWRfby5kaXYgPSBkZC5nZXREaXYoZF9vLmlkKTsKCQlkX28uY3NzID0gKGRfby5kaXYgJiYgdHlwZW9mIGRfby5kaXYuc3R5bGUgIT0gZGRfdSk/IGRfby5kaXYuc3R5bGUgOiBudWxsOwoJCWRfby5uaW1nID0gKGRkLm40ICYmIGRfby5kaXYpPyBkX28uZGl2LmRvY3VtZW50LmltYWdlc1swXSA6IChkb2N1bWVudC5pbWFnZXNbZF9vLmlkKyJOSTFtNkciXSB8fCBudWxsKTsKCQlpZighZF9vLm5vYWx0ICYmICFkZC5ub2FsdCAmJiBkX28ubmltZyAmJiBkX28ub2ltZykKCQl7CgkJCWRfby5uaW1nLmFsdCA9IGRfby5vaW1nLmFsdCB8fCAnJzsKCQkJZF9vLm5pbWcudGl0bGUgPSBkX28ub2ltZy50aXRsZTsKCQkJZF9vLm5pbWcub25tb3VzZW92ZXIgPSBkX28ub2ltZy5vbm1vdXNlb3ZlcjsKCQkJZF9vLm5pbWcub25tb3VzZW91dCA9IGRfby5vaW1nLm9ubW91c2VvdXQ7CgkJfQoJCWRfby5iZ0NvbG9yID0gJyc7Cgl9CgllbHNlCgl7CgkJZF9vLmJnQ29sb3IgPSBkZC5nZXRDc3NQcm9wKGRfby5kaXYsICdiYWNrZ3JvdW5kLWNvbG9yJywnYmFja2dyb3VuZENvbG9yJywnYmdDb2xvcicpLnRvTG93ZXJDYXNlKCk7CgkJaWYoZGQubjYgJiYgZF9vLmRpdikKCQl7CgkJCXZhciBkX2MgPSBkX28uYmdDb2xvci50b0xvd2VyQ2FzZSgpOwoJCQlpZihkX2MuaW5kZXhPZigncmdiJykgPj0gMCkKCQkJewoJCQkJZF9jID0gZF9jLnN1YnN0cmluZyg0LCBkX2MubGVuZ3RoLTEpLnNwbGl0KCcsJyk7CgkJCQlkX28uYmdDb2xvciA9ICcjJzsKCQkJCWZvcih2YXIgZF9sID0gZF9jLmxlbmd0aCwgZF9pID0gMDsgZF9pIDwgZF9sOyBkX2krKykgZF9vLmJnQ29sb3IgKz0gcGFyc2VJbnQoZF9jW2RfaV0pLnRvU3RyaW5nKDB4MTApOwoJCQl9CgkJCWVsc2UgZF9vLmJnQ29sb3IgPSBkX2M7CgkJfQoJfQoJaWYoZGQuc2NhbGFibGUpIGRfby5zY2FsYWJsZSA9IGRfby5yZXNpemFibGVeMTsKCWVsc2UgaWYoZGQucmVzaXphYmxlKSBkX28ucmVzaXphYmxlID0gZF9vLnNjYWxhYmxlXjE7CglkX28uc2V0WihkX28uZGVmeik7CglkX28uY3Vyc29yID0gZF9vLmN1cnNvciB8fCBkZC5jdXJzb3IgfHwgJ2F1dG8nOwoJZF9vLl9zZXRDcnMoZF9vLm5vZHJhZz8gJ2F1dG8nIDogZF9vLmN1cnNvcik7CglkX28uZGlhcGhhbiA9IGRfby5kaWFwaGFuIHx8IGRkLmRpYXBoYW4gfHwgMDsKCWRfby5vcGFjaXR5ID0gMS4wOwoJZF9vLnZpc2libGUgPSB0cnVlOwp9OwpkZC5pbml0eiA9IGZ1bmN0aW9uKCkKewoJaWYoIShkZCAmJiAoZGQubjQgfHwgZGQubjYgfHwgZGQuaWUgfHwgZGQub3AgfHwgZGQudzNjKSkpIHJldHVybjsKCWVsc2UgaWYoZGQubjYgfHwgZGQuaWUgfHwgZGQub3AgfHwgZGQudzNjKSBkZC5yZWNhbGMoMSk7Cgl2YXIgZF9kcmFnID0gKGRvY3VtZW50Lm9ubW91c2Vtb3ZlID09IERSQUcpLAoJZF9yZXNpemUgPSAoZG9jdW1lbnQub25tb3VzZW1vdmUgPT0gUkVTSVpFKTsKCWlmKGRkLmxvYWRGdW5jKSBkZC5sb2FkRnVuYygpOwoJaWYoZF9kcmFnKSBkZC5zZXRNb3ZIZGwoRFJBRyk7CgllbHNlIGlmKGRfcmVzaXplKSBkZC5zZXRNb3ZIZGwoUkVTSVpFKTsKCWlmKGRfZHJhZyB8fCBkX3Jlc2l6ZSkgZGQuc2V0VXBIZGwoRFJPUCk7CglkZC5zZXREd25IZGwoUElDSyk7Cn07CmRkLmZpbmx6ID0gZnVuY3Rpb24oKQp7CglpZihkZC5pZSAmJiBkZC5lbGVtZW50cykKCXsKCQlkZC5ub1JlY2FsYyA9IHRydWU7CgkJZm9yKHZhciBkX2kgPSBkZC5lbGVtZW50cy5sZW5ndGg7IGRfaTspCgkJCWRkLmVsZW1lbnRzWy0tZF9pXS5kZWwoKTsKCQlkZC5ub1JlY2FsYyA9IGZhbHNlOwoJfQoJaWYoZGQudWxvYWRGdW5jKSBkZC51bG9hZEZ1bmMoKTsKfTsKZGQuc2V0Q2UgPSBmdW5jdGlvbihkX2UsIGRfZm5jKQp7CglkX2ZuYz8gZG9jdW1lbnQuY2FwdHVyZUV2ZW50cyhkX2UpIDogZG9jdW1lbnQucmVsZWFzZUV2ZW50cyhkX2UpOwp9OwpkZC5zZXREd25IZGwgPSBmdW5jdGlvbihkX3gpCnsKCWlmKGRvY3VtZW50Lm9ubW91c2Vkb3duICE9IGRfeCkKCXsKCQlkZC5kb3duRnVuYyA9IGRvY3VtZW50Lm9ubW91c2Vkb3duOwoJCWRvY3VtZW50Lm9ubW91c2Vkb3duID0gZF94OwoJCWlmKGRkLmNlKSBkZC5zZXRDZShFdmVudC5NT1VTRURPV04sIGRfeCk7Cgl9Cn07CmRkLnNldE1vdkhkbCA9IGZ1bmN0aW9uKGRfeCkKewoJaWYoZG9jdW1lbnQub25tb3VzZW1vdmUgIT0gZF94KQoJewoJCWRkLm1vdmVGdW5jID0gZG9jdW1lbnQub25tb3VzZW1vdmU7CgkJZG9jdW1lbnQub25tb3VzZW1vdmUgPSBkX3g7CgkJaWYoZGQuY2UpIGRkLnNldENlKEV2ZW50Lk1PVVNFTU9WRSwgZF94KTsKCX0KfTsKZGQuc2V0VXBIZGwgPSBmdW5jdGlvbihkX3gpCnsKCWlmKGRvY3VtZW50Lm9ubW91c2V1cCAhPSBkX3gpCgl7CgkJZGQudXBGdW5jID0gZG9jdW1lbnQub25tb3VzZXVwOwoJCWRvY3VtZW50Lm9ubW91c2V1cCA9IGRfeDsKCQlpZihkZC5jZSkgZGQuc2V0Q2UoRXZlbnQuTU9VU0VVUCwgZF94KTsKCX0KfTsKZGQuZXZ0ID0gZnVuY3Rpb24oZF9lKQp7Cgl0aGlzLmJ1dCA9ICh0aGlzLmUgPSBkX2UgfHwgd2luZG93LmV2ZW50KS53aGljaCB8fCB0aGlzLmUuYnV0dG9uIHx8IDA7Cgl0aGlzLmJ1dHRvbiA9ICh0aGlzLmUudHlwZSA9PSAnbW91c2Vkb3duJyk/IHRoaXMuYnV0CgkJOiAoZGQuZSAmJiBkZC5lLmJ1dHRvbik/IGRkLmUuYnV0dG9uCgkJOiAwOwoJdGhpcy5zcmMgPSB0aGlzLmUudGFyZ2V0IHx8IHRoaXMuZS5zcmNFbGVtZW50IHx8IG51bGw7Cgl0aGlzLnNyYy50YWcgPSAoIiIgKyAodGhpcy5zcmMudGFnTmFtZSB8fCB0aGlzLnNyYykpLnRvTG93ZXJDYXNlKCk7Cgl0aGlzLnggPSBkZC5JbnQodGhpcy5lLnBhZ2VYIHx8IHRoaXMuZS5jbGllbnRYIHx8IDApOwoJdGhpcy55ID0gZGQuSW50KHRoaXMuZS5wYWdlWSB8fCB0aGlzLmUuY2xpZW50WSB8fCAwKTsKCWlmKGRkLmllKQoJewoJCXRoaXMueCArPSBkZC5nZXRTY3JvbGxYKCkgLSAoZGQuaWUgJiYgIWRkLmllbWFjKSoxOwoJCXRoaXMueSArPSBkZC5nZXRTY3JvbGxZKCkgLSAoZGQuaWUgJiYgIWRkLmllbWFjKSoxOwoJfQoJdGhpcy5tb2RpZktleSA9IHRoaXMuZS5tb2RpZmllcnM/IHRoaXMuZS5tb2RpZmllcnMmRXZlbnQuU0hJRlRfTUFTSyA6ICh0aGlzLmUuc2hpZnRLZXkgfHwgZmFsc2UpOwp9OwpkZC5nZXRFdmVudFRhcmdldCA9IGZ1bmN0aW9uKGRfZSwgZF9zLCBkX24pCnsKCWRfZSA9IGRfZSB8fCB3aW5kb3cuZXZlbnQ7CglpZihkX2UgJiYgKGRfcyA9IGRfZS50YXJnZXQgfHwgZF9lLnNyY0VsZW1lbnQgfHwgbnVsbCkgIT0gbnVsbCkKCXsKCQlpZihudWxsICE9IChkX24gPSBkX3MuaWQgfHwgZF9zLm5hbWUgfHwgbnVsbCkpCgkJewoJCQlpZihkX24uaW5kZXhPZigiZElpMTV2TkkxbTZHIikgPT0gZF9uLmxlbmd0aC0xMikKCQkJCXJldHVybiBkZC5lbGVtZW50c1tkX24uc3Vic3RyaW5nKDAsIGRfbi5sZW5ndGgtMTIpXSB8fCBudWxsOwoJCQlpZihkX24uaW5kZXhPZigiZElpMTV2IikgPT0gZF9uLmxlbmd0aC02KQoJCQkJcmV0dXJuIGRkLmVsZW1lbnRzW2Rfbi5zdWJzdHJpbmcoMCwgZF9uLmxlbmd0aC02KV0gfHwgbnVsbDsKCQkJcmV0dXJuIGRkLmVsZW1lbnRzW2Rfbl0gfHwgbnVsbDsKCQl9Cgl9CglyZXR1cm4gbnVsbDsKfTsKZGQucmVjYWxjID0gZnVuY3Rpb24oZF94KQp7CglpZihkZC5ub1JlY2FsYykgcmV0dXJuOwoJZm9yKHZhciBkX28sIGRfaSA9IGRkLmVsZW1lbnRzLmxlbmd0aDsgZF9pOykKCXsKCQlpZighKGRfbyA9IGRkLmVsZW1lbnRzWy0tZF9pXSkuaXNfaW1hZ2UgJiYgZF9vLmRpdikKCQl7CgkJCWRkLmdldFdIKGRfbyk7CgkJCWlmKGRfby5kaXYucG9zX3JlbCkKCQkJewoJCQkJZGQuZ2V0UGFnZVhZKGRfby5kaXYpOwoJCQkJdmFyIGRfZHggPSBkZC54IC0gZF9vLngsIGRfZHkgPSBkZC55IC0gZF9vLnk7CgkJCQlkX28uZGVmeCArPSBkX2R4OwoJCQkJZF9vLnggKz0gZF9keDsKCQkJCWRfby5kZWZ5ICs9IGRfZHk7CgkJCQlkX28ueSArPSBkX2R5OwoJCQkJZm9yKHZhciBkX3AsIGRfaiA9IGRfby5jaGlsZHJlbi5sZW5ndGg7IGRfajspCgkJCQl7CgkJCQkJaWYoIShkX3AgPSBkX28uY2hpbGRyZW5bLS1kX2pdKS5kZXRhY2hlZCAmJiAoZF9vICE9IGRfcC5kZWZwYXJlbnQgfHwgIShkX3AuaXNfaW1hZ2UgJiYgZGQuZ2V0SW1nKGRfcCwgZF9wLm9pbWcubmFtZSwgMSkpKSkKCQkJCQl7CgkJCQkJCWRfcC5kZWZ4ICs9IGRfZHg7CgkJCQkJCWRfcC5kZWZ5ICs9IGRfZHk7CgkJCQkJCWRfcC5tb3ZlQnkoZF9keCwgZF9keSk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCWVsc2UgaWYoZF9vLmlzX2ltYWdlICYmICFkZC5uNCkKCQl7CgkJCWlmKGRkLm42ICYmIGRfeCAmJiAhZF9vLmRlZncpIGRfby5yZXNpemVUbyhkX28uZGVmdyA9IGRkLmdldEltZ1coZF9vLm9pbWcpLCBkX28uZGVmaCA9IGRkLmdldEltZ0goZF9vLm9pbWcpKTsKCQkJdmFyIGRfZGVmeCA9IGRfby5kZWZ4LCBkX2RlZnkgPSBkX28uZGVmeTsKCQkJaWYoIShkX28ucGFyZW50ICYmIGRfby5wYXJlbnQgIT0gZF9vLmRlZnBhcmVudCkgJiYgKGRfeCB8fCAhZF9vLmRldGFjaGVkIHx8IGRfby5ob3Jpem9udGFsIHx8IGRfby52ZXJ0aWNhbCkgJiYgZGQuZ2V0SW1nKGRfbywgZF9vLm9pbWcubmFtZSwgMSkpCgkJCQlkX28ubW92ZUJ5KGRfby5kZWZ4LWRfZGVmeCwgZF9vLmRlZnktZF9kZWZ5KTsKCQl9Cgl9Cn07CmZ1bmN0aW9uIFdJTlNaKGRfeCkKewoJaWYoZF94KQoJewoJCWlmKGRkLm40KQoJCXsKCQkJZGQuaVcgPSBpbm5lcldpZHRoOwoJCQlkZC5pSCA9IGlubmVySGVpZ2h0OwoJCX0KCQl3aW5kb3cub25yZXNpemUgPSBuZXcgRnVuY3Rpb24oJ1dJTlNaKCk7Jyk7Cgl9CgllbHNlIGlmKGRkLm40ICYmIChpbm5lcldpZHRoICE9IGRkLmlXIHx8IGlubmVySGVpZ2h0ICE9IGRkLmlIKSkgbG9jYXRpb24ucmVsb2FkKCk7CgllbHNlIGlmKCFkZC5uNCkgc2V0VGltZW91dCgnZGQucmVjYWxjKCknLCAweGEpOwp9CldJTlNaKDEpOwoKZnVuY3Rpb24gRERPYmooZF9vLCBkX2kpCnsKCXRoaXMuaWQgPSBkX287Cgl0aGlzLmNtZCA9ICcnOwoJdGhpcy5jcHlfbiA9IGRkLmdldENtZFZhbCh0aGlzLCBDT1BZKTsKCXRoaXMubWF4b2ZmYiA9IGRkLmdldENtZFZhbCh0aGlzLCBNQVhPRkZCT1RUT00sIDAsIDEpOwoJdGhpcy5tYXhvZmZsID0gZGQuZ2V0Q21kVmFsKHRoaXMsIE1BWE9GRkxFRlQsIDAsIDEpOwoJdGhpcy5tYXhvZmZyID0gZGQuZ2V0Q21kVmFsKHRoaXMsIE1BWE9GRlJJR0hULCAwLCAxKTsKCXRoaXMubWF4b2ZmdCA9IGRkLmdldENtZFZhbCh0aGlzLCBNQVhPRkZUT1AsIDAsIDEpOwoJdmFyIGRfaiA9IGRkX2N1cnNvcnMubGVuZ3RoOyB3aGlsZShkX2otLSkKCQlpZihkZC5nZXRDbWQodGhpcywgZGRfY3Vyc29yc1tkX2pdLCAxKSkgdGhpcy5jdXJzb3IgPSBkZF9jdXJzb3JzW2Rfal0uc3Vic3RyaW5nKDIpOwoJdGhpcy5jbG9uZSA9IGRkLmdldENtZCh0aGlzLCBDTE9ORSwgMSk7Cgl0aGlzLmRldGFjaCA9IGRkLmdldENtZCh0aGlzLCBERVRBQ0hfQ0hJTERSRU4pOwoJdGhpcy5zY2FsYWJsZSA9IGRkLmdldENtZCh0aGlzLCBTQ0FMQUJMRSwgMSk7Cgl0aGlzLmhvcml6b250YWwgPSBkZC5nZXRDbWQodGhpcywgSE9SSVpPTlRBTCk7Cgl0aGlzLm5vYWx0ID0gZGQuZ2V0Q21kKHRoaXMsIE5PX0FMVCwgMSk7Cgl0aGlzLm5vZHJhZyA9IGRkLmdldENtZCh0aGlzLCBOT19EUkFHKTsKCXRoaXMuc2Nyb2xsID0gZGQuZ2V0Q21kKHRoaXMsIFNDUk9MTCwgMSk7Cgl0aGlzLnJlc2l6YWJsZSA9IGRkLmdldENtZCh0aGlzLCBSRVNJWkFCTEUsIDEpOwoJdGhpcy5yZV96ID0gZGQuZ2V0Q21kKHRoaXMsIFJFU0VUX1osIDEpOwoJdGhpcy5kaWFwaGFuID0gZGQuZ2V0Q21kKHRoaXMsIFRSQU5TUEFSRU5ULCAxKTsKCXRoaXMudmVydGljYWwgPSBkZC5nZXRDbWQodGhpcywgVkVSVElDQUwpOwoJdGhpcy5tYXh3ID0gZGQuZ2V0Q21kVmFsKHRoaXMsIE1BWFdJRFRILCAxLCAxKTsKCXRoaXMubWludyA9IE1hdGguYWJzKGRkLmdldENtZFZhbCh0aGlzLCBNSU5XSURUSCwgMSwgMSkpOwoJdGhpcy5tYXhoID0gZGQuZ2V0Q21kVmFsKHRoaXMsIE1BWEhFSUdIVCwgMSwgMSk7Cgl0aGlzLm1pbmggPSBNYXRoLmFicyhkZC5nZXRDbWRWYWwodGhpcywgTUlOSEVJR0hULCAxLCAxKSk7Cgl0aGlzLnBpY2tGdW5jID0gdGhpcy5kcmFnRnVuYyA9IHRoaXMucmVzaXplRnVuYyA9IHRoaXMuZHJvcEZ1bmMgPSBudWxsOwoKCXRoaXMubmFtZSA9IHRoaXMuaWQgKyAoZF9pIHx8ICcnKTsKCXRoaXMub2ltZyA9IGRkLmdldEltZyh0aGlzLCB0aGlzLmlkLCAxKTsKCXRoaXMuaXNfaW1hZ2UgPSAhIXRoaXMub2ltZzsKCXRoaXMuY29waWVzID0gbmV3IEFycmF5KCk7Cgl0aGlzLmNoaWxkcmVuID0gbmV3IEFycmF5KCk7Cgl0aGlzLnBhcmVudCA9IHRoaXMub3JpZ2luYWwgPSBudWxsOwoJaWYodGhpcy5vaW1nKQoJewoJCXRoaXMuaWQgPSB0aGlzLm5hbWUgKyAiZElpMTV2IjsKCQl0aGlzLncgPSBkZC5nZXRJbWdXKHRoaXMub2ltZyk7CgkJdGhpcy5oID0gZGQuZ2V0SW1nSCh0aGlzLm9pbWcpOwoJCXRoaXMuZHcgPSB0aGlzLmRoID0gMDsKCQl0aGlzLmRlZnogPSBkZC5JbnQoZGQuZ2V0Q3NzUHJvcCh0aGlzLm9pbWcsICd6LWluZGV4JywnekluZGV4JywnekluZGV4JykpIHx8IDE7CgkJdGhpcy5kZWZzcmMgPSB0aGlzLnNyYyA9IHRoaXMub2ltZy5zcmM7CgkJdGhpcy5odG0gPSAnPGltZyBuYW1lPSInICsgdGhpcy5pZCArICdOSTFtNkciJysKCQkJJyBzcmM9IicgKyB0aGlzLm9pbWcuc3JjICsgJyIgJysKCQkJJ3dpZHRoPSInICsgdGhpcy53ICsgJyIgaGVpZ2h0PSInICsgdGhpcy5oICsgJyI+JzsKCQl0aGlzLnRfaHRtID0gJzxkaXYgaWQ9IicgKyB0aGlzLmlkICsKCQkJJyIgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlOycrCgkJCSdsZWZ0OicgKyAodGhpcy5jc3N4ID0gdGhpcy54ID0gdGhpcy5kZWZ4KSArICdweDsnKwoJCQkndG9wOicgKyAodGhpcy5jc3N5ID0gdGhpcy55ID0gdGhpcy5kZWZ5KSArICdweDsnKwoJCQknd2lkdGg6JyArIHRoaXMudyArICdweDsnKwoJCQknaGVpZ2h0OicgKyB0aGlzLmggKyAncHg7Ij4nKwoJCQl0aGlzLmh0bSArICc8L2Rpdj4nOwoJfQoJZWxzZQoJewoJCWlmKCEhKHRoaXMuZGl2ID0gZGQuZ2V0RGl2KHRoaXMuaWQpKSAmJiB0eXBlb2YgdGhpcy5kaXYuc3R5bGUgIT0gZGRfdSkgdGhpcy5jc3MgPSB0aGlzLmRpdi5zdHlsZTsKCQlkZC5nZXRXSCh0aGlzKTsKCQlpZih0aGlzLmRpdikKCQl7CgkJCXRoaXMuZGl2LmRkT2JqID0gdGhpczsKCQkJdGhpcy5kaXYucG9zX3JlbCA9IGRkLmdldENzc1Byb3AodGhpcy5kaXYsICdwb3NpdGlvbicsJ3Bvc2l0aW9uJywncG9zaXRpb24nKSA9PSAicmVsYXRpdmUiOwoJCX0KCQlkZC5nZXRQYWdlWFkodGhpcy5kaXYpOwoJCXRoaXMuZGVmeCA9IHRoaXMueCA9IGRkLng7CgkJdGhpcy5kZWZ5ID0gdGhpcy55ID0gZGQueTsKCQlkZC5nZXRDc3NYWSh0aGlzKTsKCQl0aGlzLmRlZnogPSBkZC5JbnQoZGQuZ2V0Q3NzUHJvcCh0aGlzLmRpdiwgJ3otaW5kZXgnLCd6SW5kZXgnLCd6SW5kZXgnKSk7Cgl9Cgl0aGlzLmRlZncgPSB0aGlzLncgfHwgMDsKCXRoaXMuZGVmaCA9IHRoaXMuaCB8fCAwOwp9CkRET2JqLnByb3RvdHlwZS5zZXRQaWNrRnVuYyA9IGZ1bmN0aW9uKGRfeCkKewoJdGhpcy5waWNrRnVuYyA9IGRfeDsKfTsKRERPYmoucHJvdG90eXBlLnNldERyYWdGdW5jID0gZnVuY3Rpb24oZF94KQp7Cgl0aGlzLmRyYWdGdW5jID0gZF94Owp9OwpERE9iai5wcm90b3R5cGUuc2V0UmVzaXplRnVuYyA9IGZ1bmN0aW9uKGRfeCkKewoJdGhpcy5yZXNpemVGdW5jID0gZF94Owp9OwpERE9iai5wcm90b3R5cGUuc2V0RHJvcEZ1bmMgPSBmdW5jdGlvbihkX3gpCnsKCXRoaXMuZHJvcEZ1bmMgPSBkX3g7Cn07CkRET2JqLnByb3RvdHlwZS5tb3ZlQnkgPSBmdW5jdGlvbihkX3gsIGRfeSwgZF9rZHMsIGRfbykKewoJaWYoIXRoaXMuZGl2KSByZXR1cm47Cgl0aGlzLnggKz0gKGRfeCA9IGRkLkludChkX3gpKTsKCXRoaXMueSArPSAoZF95ID0gZGQuSW50KGRfeSkpOwoJaWYoIWRfa2RzIHx8IHRoaXMuaXNfaW1hZ2UgfHwgdGhpcy5wYXJlbnQgIT0gdGhpcy5kZWZwYXJlbnQpCgl7CgkJKGRfbyA9IHRoaXMuY3NzIHx8IHRoaXMuZGl2KS5sZWZ0ID0gKHRoaXMuY3NzeCArPSBkX3gpICsgZGQucHg7CgkJZF9vLnRvcCA9ICh0aGlzLmNzc3kgKz0gZF95KSArIGRkLnB4OwoJfQoJZm9yKHZhciBkX2kgPSB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgZF9pOykKCXsKCQlpZighKGRfbyA9IHRoaXMuY2hpbGRyZW5bLS1kX2ldKS5kZXRhY2hlZCkgZF9vLm1vdmVCeShkX3gsIGRfeSwgMSk7CgkJZF9vLmRlZnggKz0gZF94OwoJCWRfby5kZWZ5ICs9IGRfeTsKCX0KfTsKCkRET2JqLnByb3RvdHlwZS5tb3ZlVG8gPSBmdW5jdGlvbihkX3gsIGRfeSkKewoJdGhpcy5tb3ZlQnkoZGQuSW50KGRfeCktdGhpcy54LCBkZC5JbnQoZF95KS10aGlzLnkpOwp9OwpERE9iai5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uKGRfbSwgZF9vLCBkX3ApCnsKCWlmKHRoaXMuZGl2ICYmIHRoaXMudmlzaWJsZSkKCXsKCQlkX3AgPSB0aGlzLmNzcyB8fCB0aGlzLmRpdjsKCQlpZihkX20gJiYgIWRkLm40KQoJCXsKCQkJdGhpcy5kaXNwbGF5ID0gZGQuZ2V0Q3NzUHJvcCh0aGlzLmRpdiwgImRpc3BsYXkiLCAiZGlzcGxheSIsICJkaXNwbGF5Iik7CgkJCWlmKHRoaXMub2ltZykKCQkJewoJCQkJdGhpcy5vaW1nLmRpc3BsYXkgPSBkZC5nZXRDc3NQcm9wKHRoaXMub2ltZywgImRpc3BsYXkiLCAiZGlzcGxheSIsICJkaXNwbGF5Iik7CgkJCQl0aGlzLm9pbWcuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKCQkJfQoJCQlkX3AuZGlzcGxheSA9ICJub25lIjsKCQkJZGQucmVjYWxjKCk7CgkJfQoJCWVsc2UgZF9wLnZpc2liaWxpdHkgPSAiaGlkZGVuIjsKCX0KCXRoaXMudmlzaWJsZSA9IGZhbHNlOwoJZm9yKHZhciBkX2kgPSB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgZF9pOykKCQlpZighKGRfbyA9IHRoaXMuY2hpbGRyZW5bLS1kX2ldKS5kZXRhY2hlZCkgZF9vLmhpZGUoZF9tKTsKfTsKRERPYmoucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbihkX28sIGRfcCkKewoJaWYodGhpcy5kaXYpCgl7CgkJZF9wID0gdGhpcy5jc3MgfHwgdGhpcy5kaXY7CgkJaWYoZF9wLmRpc3BsYXkgJiYgZF9wLmRpc3BsYXkgPT0gIm5vbmUiKQoJCXsKCQkJZF9wLmRpc3BsYXkgPSB0aGlzLmRpc3BsYXkgfHwgImJsb2NrIjsKCQkJaWYodGhpcy5vaW1nKSB0aGlzLm9pbWcuc3R5bGUuZGlzcGxheSA9IHRoaXMub2ltZy5kaXNwbGF5IHx8ICJpbmxpbmUiOwoJCQlkZC5yZWNhbGMoKTsKCQl9CgkJZWxzZSBkX3AudmlzaWJpbGl0eSA9ICJ2aXNpYmxlIjsKCX0KCXRoaXMudmlzaWJsZSA9IHRydWU7Cglmb3IodmFyIGRfaSA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBkX2k7KQoJCWlmKCEoZF9vID0gdGhpcy5jaGlsZHJlblstLWRfaV0pLmRldGFjaGVkKSBkX28uc2hvdygpOwp9OwpERE9iai5wcm90b3R5cGUucmVzaXplVG8gPSBmdW5jdGlvbihkX3csIGRfaCwgZF9vKQp7CglpZighdGhpcy5kaXYpIHJldHVybjsKCWRfdyA9ICh0aGlzLncgPSBkZC5JbnQoZF93KSktdGhpcy5kdzsKCWRfaCA9ICh0aGlzLmggPSBkZC5JbnQoZF9oKSktdGhpcy5kaDsKCWlmKGRkLm40KQoJewoJCXRoaXMuZGl2LnJlc2l6ZVRvKGRfdywgZF9oKTsKCQlpZih0aGlzLmlzX2ltYWdlKQoJCXsKCQkJdGhpcy53cml0ZSgnPGltZyBzcmM9IicgKyB0aGlzLnNyYyArICciIHdpZHRoPSInICsgZF93ICsgJyIgaGVpZ2h0PSInICsgZF9oICsgJyI+Jyk7CgkJCSh0aGlzLm5pbWcgPSB0aGlzLmRpdi5kb2N1bWVudC5pbWFnZXNbMF0pLnNyYyA9IHRoaXMuc3JjOwoJCX0KCX0KCWVsc2UgaWYodHlwZW9mIHRoaXMuY3NzLnBpeGVsV2lkdGggIT0gZGRfdSkKCXsKCQl0aGlzLmNzcy5waXhlbFdpZHRoID0gZF93OwoJCXRoaXMuY3NzLnBpeGVsSGVpZ2h0ID0gZF9oOwoJCWlmKHRoaXMuaXNfaW1hZ2UpCgkJewoJCQkoZF9vID0gdGhpcy5uaW1nLnN0eWxlKS5waXhlbFdpZHRoID0gZF93OwoJCQlkX28ucGl4ZWxIZWlnaHQgPSBkX2g7CgkJfQoJfQoJZWxzZQoJewoJCXRoaXMuY3NzLndpZHRoID0gZF93ICsgZGQucHg7CgkJdGhpcy5jc3MuaGVpZ2h0ID0gZF9oICsgZGQucHg7CgkJaWYodGhpcy5pc19pbWFnZSkKCQl7CgkJCShkX28gPSB0aGlzLm5pbWcpLndpZHRoID0gZF93OwoJCQlkX28uaGVpZ2h0ID0gZF9oOwoJCQlpZighZF9vLmNvbXBsZXRlKSBkX28uc3JjID0gdGhpcy5zcmM7CgkJfQoJfQp9OwpERE9iai5wcm90b3R5cGUucmVzaXplQnkgPSBmdW5jdGlvbihkX2R3LCBkX2RoKQp7Cgl0aGlzLnJlc2l6ZVRvKHRoaXMudytkZC5JbnQoZF9kdyksIHRoaXMuaCtkZC5JbnQoZF9kaCkpOwp9OwpERE9iai5wcm90b3R5cGUuc3dhcEltYWdlID0gZnVuY3Rpb24oZF94LCBkX2NwKQp7CglpZighdGhpcy5uaW1nKSByZXR1cm47Cgl0aGlzLm5pbWcuc3JjID0gZF94OwoJdGhpcy5zcmMgPSB0aGlzLm5pbWcuc3JjOwoJaWYoZF9jcCkKCXsKCQlmb3IodmFyIGRfaSA9IHRoaXMuY29waWVzLmxlbmd0aDsgZF9pOykKCQl7LS1kX2k7CgkJCXRoaXMuY29waWVzW2RfaV0uc3JjID0gdGhpcy5jb3BpZXNbZF9pXS5uaW1nLnNyYyA9IHRoaXMubmltZy5zcmM7CgkJfQoJfQp9OwpERE9iai5wcm90b3R5cGUuc2V0QmdDb2xvciA9IGZ1bmN0aW9uKGRfeCkKewoJaWYoZGQubjQgJiYgdGhpcy5kaXYpIHRoaXMuZGl2LmJnQ29sb3IgPSBkX3g7CgllbHNlIGlmKHRoaXMuY3NzKSB0aGlzLmNzcy5iYWNrZ3JvdW5kID0gZF94OwoJdGhpcy5iZ0NvbG9yID0gZF94Owp9OwpERE9iai5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihkX3gsIGRfbykKewoJdGhpcy50ZXh0ID0gZF94OwoJaWYoIXRoaXMuZGl2KSByZXR1cm47CglpZihkZC5uNCkKCXsKCQkoZF9vID0gdGhpcy5kaXYuZG9jdW1lbnQpLm9wZW4oKTsKCQlkX28ud3JpdGUoZF94KTsKCQlkX28uY2xvc2UoKTsKCQlkZC5nZXRXSCh0aGlzKTsKCX0KCWVsc2UKCXsKCQl0aGlzLmNzcy5oZWlnaHQgPSAnYXV0byc7CgkJdGhpcy5kaXYuaW5uZXJIVE1MID0gZF94OwoJCWlmKCFkZC5pZTQpIGRkLnJlY2FsYygpOwoJCWlmKGRkLmllNCB8fCBkZC5uNikgc2V0VGltZW91dCgnZGQucmVjYWxjKCk7JywgMCk7IC8vIG42LjA6IHJlY2FsYyB0d2ljZQoJfQp9OwpERE9iai5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKGRfbiwgZF9wLCBkX2IpCnsKCWlmKCF0aGlzLm9pbWcpIHJldHVybjsKCWRfYiA9IChkZC5pZSAmJiBkb2N1bWVudC5hbGwudGFncygnYm9keScpKT8gZG9jdW1lbnQuYWxsLnRhZ3MoJ2JvZHknKVswXSA6IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lPyAoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2JvZHknKVswXSB8fCBkZC5kYikgOiBkZC5kYjsKCWZvcihkX24gPSBkX24gfHwgMTsgZF9uID4gMDsgLS1kX24pCgl7CgkJdmFyIGRfbCA9IHRoaXMuY29waWVzLmxlbmd0aCwKCQlkX28gPSBuZXcgRERPYmoodGhpcy5uYW1lK3RoaXMuY21kLCBkX2wrMSk7CgkJaWYoZGQubjQpCgkJewoJCQlkX28uaWQgPSAoZF9wID0gbmV3IExheWVyKGRfby53KSkubmFtZTsKCQkJZF9wLmNsaXAuaGVpZ2h0ID0gZF9vLmg7CgkJCWRfcC52aXNpYmlsaXR5ID0gJ3Nob3cnOwoJCQkoZF9wID0gZF9wLmRvY3VtZW50KS5vcGVuKCk7CgkJCWRfcC53cml0ZShkX28uaHRtKTsKCQkJZF9wLmNsb3NlKCk7CgkJfQoJCWVsc2UgaWYoZF9iICYmIGRfYi5pbnNlcnRBZGphY2VudEhUTUwpIGRfYi5pbnNlcnRBZGphY2VudEhUTUwoIkFmdGVyQmVnaW4iLCBkX28udF9odG0pOwoJCWVsc2UgaWYoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCAmJiBkX2IgJiYgZF9iLmFwcGVuZENoaWxkKQoJCXsKCQkJZF9iLmFwcGVuZENoaWxkKGRfcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRJaTE1diIpKTsKCQkJZF9wLmlubmVySFRNTCA9IGRfby5odG07CgkJCWRfcC5pZCA9IGRfby5pZDsKCQkJZF9wLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJzsKCQkJZF9wLnN0eWxlLndpZHRoID0gZF9vLncgKyAncHgnOwoJCQlkX3Auc3R5bGUuaGVpZ2h0ID0gZF9vLmggKyAncHgnOwoJCX0KCQllbHNlIGlmKGRfYiAmJiBkX2IuaW5uZXJIVE1MKSBkX2IuaW5uZXJIVE1MICs9IGRfby50X2h0bTsKCQlkX28uZGVmeiA9IHRoaXMuZGVmeisxK2RfbDsKCQlkZC5hZGRQcm9wcyhkX28pOwoJCWRfby5vcmlnaW5hbCA9IHRoaXM7CgkJZGQuYWRkRWx0KGRfbywgdGhpcyk7CgkJaWYodGhpcy5wYXJlbnQpCgkJewoJCQl0aGlzLnBhcmVudC5hZGRDaGlsZChkX28sIHRoaXMuZGV0YWNoZWQpOwoJCQlkX28uZGVmcGFyZW50ID0gdGhpcy5kZWZwYXJlbnQ7CgkJfQoJCWRfby5tb3ZlVG8oZF9vLmRlZnggPSB0aGlzLmRlZngsIGRfby5kZWZ5ID0gdGhpcy5kZWZ5KTsKCQlpZihkZC5uNCkgZF9vLmRlZnNyYyA9IGRfby5zcmMgPSB0aGlzLmRlZnNyYzsKCQlkX28uc3dhcEltYWdlKHRoaXMuc3JjKTsKCX0KfTsKRERPYmoucHJvdG90eXBlLmFkZENoaWxkID0gZnVuY3Rpb24oZF9rZCwgZGV0YWNoLCBkZWZwKQp7CglpZih0eXBlb2YgZF9rZCAhPSAib2JqZWN0IikgZF9rZCA9IGRkLmVsZW1lbnRzW2Rfa2RdOwoJaWYoZF9rZC5wYXJlbnQgJiYgZF9rZC5wYXJlbnQgPT0gdGhpcyB8fCBkX2tkID09IHRoaXMgfHwgIWRfa2QuaXNfaW1hZ2UgJiYgZF9rZC5kZWZwYXJlbnQgJiYgIWRlZnApIHJldHVybjsKCgl0aGlzLmNoaWxkcmVuW3RoaXMuY2hpbGRyZW4ubGVuZ3RoXSA9IHRoaXMuY2hpbGRyZW5bZF9rZC5uYW1lXSA9IGRfa2Q7CglkX2tkLmRldGFjaGVkID0gZGV0YWNoIHx8IDA7CglpZihkZWZwKSBkX2tkLmRlZnBhcmVudCA9IHRoaXM7CgllbHNlIGlmKHRoaXMgPT0gZF9rZC5kZWZwYXJlbnQgJiYgZF9rZC5pc19pbWFnZSkgZGQuZ2V0SW1nKHRoaXMsIGRfa2Qub2ltZy5uYW1lLCAxKTsKCWlmKCFkX2tkLmRlZnBhcmVudCB8fCB0aGlzICE9IGRfa2QuZGVmcGFyZW50KQoJewoJCWRfa2QuZGVmeCA9IGRfa2QueDsKCQlkX2tkLmRlZnkgPSBkX2tkLnk7Cgl9CglpZighZGV0YWNoKQoJewoJCWRfa2QuZGVmeiA9IGRfa2QuZGVmeit0aGlzLmRlZnotKGRfa2QucGFyZW50PyBkX2tkLnBhcmVudC5kZWZ6IDogMCkrKCFkX2tkLmlzX2ltYWdlKjEpOwoJCWRfa2Quc2V0WihkX2tkLnordGhpcy56LShkX2tkLnBhcmVudD8gZF9rZC5wYXJlbnQueiA6IDApKyghZF9rZC5pc19pbWFnZSoxKSwgMSk7Cgl9CglpZihkX2tkLnBhcmVudCkgZF9rZC5wYXJlbnQucmVtb3ZlQ2hpbGQoZF9rZCwgMSk7CglkX2tkLnBhcmVudCA9IHRoaXM7Cn07CkRET2JqLnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uKGRfa2QsIGRfbmV3cCkKewoJaWYodHlwZW9mIGRfa2QgIT0gIm9iamVjdCIpIGRfa2QgPSB0aGlzLmNoaWxkcmVuW2Rfa2RdOwoJdmFyIGRfb2MgPSB0aGlzLmNoaWxkcmVuLCBkX25jID0gbmV3IEFycmF5KCk7Cglmb3IodmFyIGRfaSA9IDA7IGRfaSA8IGRfb2MubGVuZ3RoOyBkX2krKykKCQlpZihkX29jW2RfaV0gIT0gZF9rZCkgZF9uY1tkX25jLmxlbmd0aF0gPSBkX29jW2RfaV07Cgl0aGlzLmNoaWxkcmVuID0gZF9uYzsKCWRfa2QucGFyZW50ID0gbnVsbDsKCWlmKCFkX25ld3ApCgl7CgkJZF9rZC5kZXRhY2hlZCA9IGRfa2QuZGVmcCA9IDA7CgkJaWYoZF9rZC5pc19pbWFnZSkgZGQuZ2V0SW1nKGRfa2QsIGRfa2Qub2ltZy5uYW1lLCAxKTsKCX0KfTsKRERPYmoucHJvdG90eXBlLmF0dGFjaENoaWxkID0gZnVuY3Rpb24oZF9rZCkKewoJKGRfa2QgPSAodHlwZW9mIGRfa2QgIT0gIm9iamVjdCIpPyB0aGlzLmNoaWxkcmVuW2Rfa2RdOiBkX2tkKS5kZXRhY2hlZCA9IDA7CglkX2tkLnNldFooZF9rZC5kZWZ6ICsgdGhpcy56LXRoaXMuZGVmeiwgMSk7Cn07CkRET2JqLnByb3RvdHlwZS5kZXRhY2hDaGlsZCA9IGZ1bmN0aW9uKGRfa2QpCnsKCShkX2tkID0gKHR5cGVvZiBkX2tkICE9ICJvYmplY3QiKT8gdGhpcy5jaGlsZHJlbltkX2tkXTogZF9rZCkuZGV0YWNoZWQgPSAxOwp9OwpERE9iai5wcm90b3R5cGUuc2V0WiA9IGZ1bmN0aW9uKGRfeCwgZF9rZHMsIGRfbykKewoJaWYoZF9rZHMpCgl7CgkJZm9yKHZhciBkX2R6ID0gZF94LXRoaXMueiwgZF9pID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGRfaTspCgkJCWlmKCEoZF9vID0gdGhpcy5jaGlsZHJlblstLWRfaV0pLmRldGFjaGVkKSBkX28uc2V0WihkX28ueitkX2R6LCAxKTsKCX0KCWRkLnogPSBNYXRoLm1heChkZC56LCB0aGlzLnogPSB0aGlzLmRpdj8gKCh0aGlzLmNzcyB8fCB0aGlzLmRpdikuekluZGV4ID0gZF94KSA6IDApOwp9OwpERE9iai5wcm90b3R5cGUubWF4aW1pemVaID0gZnVuY3Rpb24oKQp7Cgl0aGlzLnNldFooZGQueisxLCAxKTsKfTsKRERPYmoucHJvdG90eXBlLl9yZXNldFogPSBmdW5jdGlvbihkX28pCnsKCWlmKHRoaXMucmVfeiB8fCBkZC5yZV96KQoJewoJCXRoaXMuc2V0Wih0aGlzLmRlZnopOwoJCWZvcih2YXIgZF9pID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGRfaTspCgkJCWlmKCEoZF9vID0gdGhpcy5jaGlsZHJlblstLWRfaV0pLmRldGFjaGVkKSBkX28uc2V0WihkX28uZGVmeik7Cgl9Cn07CkRET2JqLnByb3RvdHlwZS5zZXRPcGFjaXR5ID0gZnVuY3Rpb24oZF94KQp7Cgl0aGlzLm9wYWNpdHkgPSBkX3g7Cgl0aGlzLl9zZXRPcGFSZWwoMS4wLCAxKTsKfTsKRERPYmoucHJvdG90eXBlLl9zZXRPcGFSZWwgPSBmdW5jdGlvbihkX3gsIGRfa2QsIGRfeSwgZF9vKQp7CglpZih0aGlzLmNzcyAmJiAodGhpcy5kaWFwaGFuIHx8IGRfa2QpKQoJewoJCWRfeSA9IHRoaXMub3BhY2l0eSpkX3g7CgkJaWYodHlwZW9mIHRoaXMuY3NzLk1vek9wYWNpdHkgIT0gZGRfdSkgdGhpcy5jc3MuTW96T3BhY2l0eSA9IGRfeTsKCQllbHNlIGlmICh0eXBlb2YgdGhpcy5jc3Mub3BhY2l0eSAhPSBkZF91KSB0aGlzLmNzcy5vcGFjaXR5ID0gZF95OwoJCWVsc2UgaWYodHlwZW9mIHRoaXMuY3NzLmZpbHRlciAhPSBkZF91KQoJCQl0aGlzLmNzcy5maWx0ZXIgPSAiQWxwaGEob3BhY2l0eT0iK3BhcnNlSW50KDEwMCpkX3kpKyIpIjsKCQlmb3IodmFyIGRfaSA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBkX2k7KQoJCQlpZighKGRfbyA9IHRoaXMuY2hpbGRyZW5bLS1kX2ldKS5kZXRhY2hlZCkgZF9vLl9zZXRPcGFSZWwoZF94LCAxKTsKCX0KfTsKRERPYmoucHJvdG90eXBlLnNldEN1cnNvciA9IGZ1bmN0aW9uKGRfeCkKewoJdGhpcy5fc2V0Q3JzKHRoaXMuY3Vyc29yID0gKGRfeC5pbmRleE9mKCdjOicpKzEpPyBkX3guc3Vic3RyaW5nKDIpIDogZF94KTsKfTsKRERPYmoucHJvdG90eXBlLl9zZXRDcnMgPSBmdW5jdGlvbihkX3gpCnsKCWlmKHRoaXMuY3NzKSB0aGlzLmNzcy5jdXJzb3IgPSAoKCFkZC5pZSB8fCBkZC5pZW1hYykgJiYgZF94ID09ICdoYW5kJyk/ICdwb2ludGVyJyA6IGRfeDsKfTsKRERPYmoucHJvdG90eXBlLnNldERyYWdnYWJsZSA9IGZ1bmN0aW9uKGRfeCkKewoJdGhpcy5ub2RyYWcgPSAhZF94KjE7Cgl0aGlzLl9zZXRDcnMoZF94PyB0aGlzLmN1cnNvciA6ICdhdXRvJyk7Cn07CkRET2JqLnByb3RvdHlwZS5zZXRSZXNpemFibGUgPSBmdW5jdGlvbihkX3gpCnsKCXRoaXMucmVzaXphYmxlID0gZF94KjE7CglpZihkX3gpIHRoaXMuc2NhbGFibGUgPSAwOwp9OwpERE9iai5wcm90b3R5cGUuc2V0U2NhbGFibGUgPSBmdW5jdGlvbihkX3gpCnsKCXRoaXMuc2NhbGFibGUgPSBkX3gqMTsKCWlmKGRfeCkgdGhpcy5yZXNpemFibGUgPSAwOwp9OwpERE9iai5wcm90b3R5cGUuc2V0SG9yaXpvbnRhbCA9IGZ1bmN0aW9uKGRfeCkKewoJdGhpcy5ob3Jpem9udGFsID0gZF94KjE7Cn07CkRET2JqLnByb3RvdHlwZS5zZXRWZXJ0aWNhbCA9IGZ1bmN0aW9uKGRfeCkKewoJdGhpcy52ZXJ0aWNhbCA9IGRfeCoxOwp9OwpERE9iai5wcm90b3R5cGUuZ2V0RWx0QmVsb3cgPSBmdW5jdGlvbihkX3JldCwgZF94LCBkX3kpCnsKCXZhciBkX28sIGRfY21wID0gLTEsIGRfaSA9IGRkLmVsZW1lbnRzLmxlbmd0aDsgd2hpbGUoZF9pLS0pCgl7CgkJZF9vID0gZGQuZWxlbWVudHNbZF9pXTsKCQlkX3ggPSBkX28ueC10aGlzLncvMjsKCQlkX3kgPSBkX28ueS10aGlzLmgvMjsKCQlpZihkX28udmlzaWJsZSAmJiBkX28ueiA8IHRoaXMueiAmJiB0aGlzLnggPj0gZF94ICYmIHRoaXMueCA8PSBkX3grZF9vLncgJiYgdGhpcy55ID49IGRfeSAmJiB0aGlzLnkgPD0gZF95K2Rfby5oKQoJCXsKCQkJaWYoZF9vLnogPiBkX2NtcCkKCQkJewoJCQkJZF9jbXAgPSBkX28uejsKCQkJCWRfcmV0ID0gZF9vOwoJCQl9CgkJfQoJfQoJcmV0dXJuIGRfcmV0Owp9OwpERE9iai5wcm90b3R5cGUuZGVsID0gZnVuY3Rpb24oZF9vcywgZF9vKQp7Cgl2YXIgZF9pLCBkX2w7CglpZih0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudC5yZW1vdmVDaGlsZCkgdGhpcy5wYXJlbnQucmVtb3ZlQ2hpbGQodGhpcyk7CglpZih0aGlzLm9yaWdpbmFsKQoJewoJCXRoaXMuaGlkZSgpOwoJCWlmKHRoaXMub3JpZ2luYWwuY29waWVzKQoJCXsKCQkJZF9vcyA9IG5ldyBBcnJheSgpOwoJCQlmb3IoZF9sID0gdGhpcy5vcmlnaW5hbC5jb3BpZXMubGVuZ3RoLCBkX2kgPSAwOyBkX2kgPCBkX2w7IGRfaSsrKQoJCQkJaWYoKGRfbyA9IHRoaXMub3JpZ2luYWwuY29waWVzW2RfaV0pICE9IHRoaXMpIGRfb3NbZF9vLm5hbWVdID0gZF9vc1tkX29zLmxlbmd0aF0gPSBkX287CgkJCXRoaXMub3JpZ2luYWwuY29waWVzID0gZF9vczsKCQl9Cgl9CgllbHNlIGlmKHRoaXMuaXNfaW1hZ2UpCgl7CgkJdGhpcy5oaWRlKCk7CgkJaWYodGhpcy5vaW1nKQoJCXsKCQkgIGlmKGRkLm40KSB0aGlzLm9pbWcuc3JjID0gdGhpcy5kZWZzcmM7CgkJICBlbHNlIHRoaXMub2ltZy5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnOwoJCX0KCX0KCWVsc2UgaWYodGhpcy5tb3ZlVG8pCgl7CgkJaWYodGhpcy5jc3MpIHRoaXMuY3NzLmN1cnNvciA9ICdkZWZhdWx0JzsKCQl0aGlzLm1vdmVUbyh0aGlzLmRlZngsIHRoaXMuZGVmeSk7CgkJdGhpcy5yZXNpemVUbyh0aGlzLmRlZncsIHRoaXMuZGVmaCk7Cgl9CglkX29zID0gbmV3IEFycmF5KCk7Cglmb3IoZF9sID0gZGQuZWxlbWVudHMubGVuZ3RoLCBkX2kgPSAwOyBkX2kgPCBkX2w7IGRfaSsrKQoJewoJCWlmKChkX28gPSBkZC5lbGVtZW50c1tkX2ldKSAhPSB0aGlzKSBkX29zW2Rfby5uYW1lXSA9IGRfb3NbZF9vLmluZGV4ID0gZF9vcy5sZW5ndGhdID0gZF9vOwoJCWVsc2UgZF9vLl9mcmVlKCk7Cgl9CglkZC5lbGVtZW50cyA9IGRfb3M7CglpZighZGQubjQpIGRkLnJlY2FsYygpOwp9OwpERE9iai5wcm90b3R5cGUuX2ZyZWUgPSBmdW5jdGlvbigpCnsKCWZvcih2YXIgZF9pIGluIHRoaXMpCgkJdGhpc1tkX2ldID0gbnVsbDsKCWRkLmVsZW1lbnRzW3RoaXMubmFtZV0gPSBudWxsOwp9OwpkZC5uNFJlY3RWaXMgPSBmdW5jdGlvbih2aXMpCnsKCWZvcih2YXIgZF9pID0gNDsgZF9pOykKCXstLWRfaTsKCQlkZC5yZWN0SVtkX2ldLnZpc2liaWxpdHkgPSBkZC5yZWN0QVtkX2ldLnZpc2liaWxpdHkgPSB2aXM/ICdzaG93JyA6ICdoaWRlJzsKCQlpZih2aXMpIGRkLnJlY3RJW2RfaV0uekluZGV4ID0gZGQucmVjdEFbZF9pXS56SW5kZXggPSBkZC56KzI7Cgl9Cn07CmRkLm40UmVjdFBvcyA9IGZ1bmN0aW9uKGRfbywgZF94LCBkX3ksIGRfdywgZF9oKQp7CglkX28ueCA9IGRfeDsKCWRfby55ID0gZF95OwoJZF9vLmNsaXAud2lkdGggPSBkX3c7CglkX28uY2xpcC5oZWlnaHQgPSBkX2g7Cn07Ci8vIE5ONDogRHJhdyBpbWcgc2l6aW5nIHJlY3QKZGQubjRSZWN0ID0gZnVuY3Rpb24oZF93LCBkX2gpCnsKCXZhciBkX2k7CglpZighZGQucmVjdEkpCgl7CgkJZGQucmVjdEkgPSBuZXcgQXJyYXkoKTsKCQlkZC5yZWN0QSA9IG5ldyBBcnJheSgpOwoJfQoJaWYoIWRkLnJlY3RJWzBdKQoJewoJCWZvcihkX2kgPSA0OyBkX2k7KQoJCXsKCQkJKGRkLnJlY3RJWy0tZF9pXSA9IG5ldyBMYXllcigxKSkuYmdDb2xvciA9ICcjMDAwMDAwJzsKCQkJKGRkLnJlY3RBW2RfaV0gPSBuZXcgTGF5ZXIoMSkpLmJnQ29sb3IgPSAnI2ZmZmZmZic7CgkJfQoJfQoJaWYoIWRkLnJlY3RJWzBdLnZpc2liaWxpdHkgfHwgZGQucmVjdElbMF0udmlzaWJpbGl0eSA9PSAnaGlkZScpIGRkLm40UmVjdFZpcygxKTsKCWRkLm9iai53ID0gZF93OwoJZGQub2JqLmggPSBkX2g7Cglmb3IoZF9pID0gNDsgZF9pOykKCXstLWRfaTsKCQlkZC5uNFJlY3RQb3MoZGQucmVjdElbZF9pXSwgZGQub2JqLnggKyAoIShkX2ktMSk/IChkZC5vYmoudy0xKSA6IDApLCBkZC5vYmoueSArICghKGRfaS0yKT8gKGRkLm9iai5oLTEpIDogMCksIGRfaSYxIHx8IGRkLm9iai53LCAhKGRfaSYxKSB8fCBkZC5vYmouaCk7CgkJZGQubjRSZWN0UG9zKGRkLnJlY3RBW2RfaV0sICEoZF9pLTEpPyBkZC5yZWN0SVsxXS54KzEgOiAoZGQub2JqLngtMSksICEoZF9pLTIpPyBkZC5yZWN0SVsyXS55KzEgOiAoZGQub2JqLnktMSksIGRfaSYxIHx8IGRkLm9iai53KzIsICEoZF9pJjEpIHx8IGRkLm9iai5oKzIpOwoJfQp9OwpkZC5yZXN6VG8gPSBmdW5jdGlvbihkX3csIGRfaCkKewoJaWYoZGQubjQgJiYgZGQub2JqLmlzX2ltYWdlKSBkZC5uNFJlY3QoZF93LCBkX2gpOwoJZWxzZSBkZC5vYmoucmVzaXplVG8oZF93LCBkX2gpOwp9OwpkZC5lbWJlZFZpcyA9IGZ1bmN0aW9uKGRfdmlzKQp7Cgl2YXIgZF9vID0gbmV3IEFycmF5KCdpZnJhbWUnLCAnYXBwbGV0JywgJ2VtYmVkJywgJ29iamVjdCcpOwoJZm9yKHZhciBkX2kgPSBkX28ubGVuZ3RoOyBkX2k7KQoJey0tZF9pOwoJCXZhciBkX3AgPSBkZC5pZT8gZG9jdW1lbnQuYWxsLnRhZ3MoZF9vW2RfaV0pIDogZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWU/IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKGRfb1tkX2ldKSA6IG51bGw7CgkJaWYoZF9wKQoJCXsKCQkJZm9yKHZhciBkX2ogPSBkX3AubGVuZ3RoOyBkX2o7KQoJCQl7CgkJCQl2YXIgZF9xID0gZF9wWy0tZF9qXTsKCQkJCXdoaWxlKGRfcS5vZmZzZXRQYXJlbnQgfHwgZF9xLnBhcmVudE5vZGUpCgkJCQl7CgkJCQkJaWYoKGRfcSA9IGRfcS5wYXJlbnROb2RlIHx8IGRfcS5vZmZzZXRQYXJlbnQgfHwgbnVsbCkgPT0gZGQub2JqLmRpdikKCQkJCQl7CgkJCQkJCWRfcFtkX2pdLnN0eWxlLnZpc2liaWxpdHkgPSBkX3ZpczsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJfQp9OwoKZGQubWF4T2ZmWCA9IGZ1bmN0aW9uKGRfeCwgZF95KQp7CglyZXR1cm4oCgkJKGRkLm9iai5tYXhvZmZsKzEgJiYgKGRfeSA9IGRkLm9iai5kZWZ4LWRkLm9iai5tYXhvZmZsKS1kX3ggPiAwCgkJfHwgZGQub2JqLm1heG9mZnIrMSAmJiAoZF95ID0gZGQub2JqLmRlZngrZGQub2JqLm1heG9mZnIpLWRfeCA8IDApPyBkX3kKCQk6IGRfeAoJKTsKfTsKZGQubWF4T2ZmWSA9IGZ1bmN0aW9uKGRfeCwgZF95KQp7CglyZXR1cm4oCgkJKGRkLm9iai5tYXhvZmZ0KzEgJiYgKGRfeSA9IGRkLm9iai5kZWZ5LWRkLm9iai5tYXhvZmZ0KS1kX3ggPiAwCgkJfHwgZGQub2JqLm1heG9mZmIrMSAmJiAoZF95ID0gZGQub2JqLmRlZnkrZGQub2JqLm1heG9mZmIpLWRfeCA8IDApPyBkX3kKCQk6IGRfeAoJKTsKfTsKZGQuaW5XbmRXID0gZnVuY3Rpb24oZF94LCBkX3kpCnsKCXZhciBkX3d4ID0gZGQuZ2V0U2Nyb2xsWCgpLAoJZF93dyA9IGRkLmdldFduZFcoKTsKCXJldHVybigKCQkoKGRfeSA9IGRfd3grMiktZF94ID4gMCkgfHwgKChkX3kgPSBkX3d4K2Rfd3crZGQub2JqLnctMiktZF94IDwgMCk/IGRfeQoJCTogZF94CgkpOwp9OwpkZC5pblduZEggPSBmdW5jdGlvbihkX3gsIGRfeSkKewoJdmFyIGRfd3kgPSBkZC5nZXRTY3JvbGxZKCksCglkX3doID0gZGQuZ2V0V25kSCgpOwoJcmV0dXJuKAoJCSgoZF95ID0gZF93eSsyKS1kX3ggPiAwKSB8fCAoKGRfeSA9IGRfd3krZF93aCtkZC5vYmouaC0yKS1kX3ggPCAwKT8gZF95CgkJOiBkX3gKCSk7Cn07Ci8vIFRoZXNlIHR3byBmdW5jcyBsaW1pdCB0aGUgc2l6ZSBvZiBlbGVtZW50IHdoZW4gbW91c2VyZXNpemVkLgovLyBJbXBsZW1lbnRlZCAyMi41LjIwMDMgYnkgR3JlZ29yIEx0b2xmLCBtb2RpZmllZCBieSBXYWx0ZXIgWm9ybgpkZC5saW1XID0gZnVuY3Rpb24oZF93KQp7CglyZXR1cm4oCgkJKGRkLm9iai5taW53LWRfdyA+IDApPyBkZC5vYmoubWludwoJCTogKGRkLm9iai5tYXh3ID4gMCAmJiBkZC5vYmoubWF4dy1kX3cgPCAwKT8gZGQub2JqLm1heHcKCQk6IGRfdwoJKTsKfTsKZGQubGltSCA9IGZ1bmN0aW9uKGRfaCkKewoJcmV0dXJuKAoJCShkZC5vYmoubWluaC1kX2ggPiAwKT8gZGQub2JqLm1pbmgKCQk6IChkZC5vYmoubWF4aCA+IDAgJiYgZGQub2JqLm1heGgtZF9oIDwgMCk/IGRkLm9iai5tYXhoCgkJOiBkX2gKCSk7Cn07Ci8vIE9wdGlvbmFsIGF1dG9zY3JvbGwtcGFnZSBmdW5jdGlvbmFsaXR5LiBDb3VydGVzeSBDZWRyaWMgU2F2YXJlc2UuCi8vIE1vZGlmaWVkIGJ5IFdhbHRlciBab3JuLgpmdW5jdGlvbiBERFNjcm9sbCgpCnsKCWlmKCFkZC5vYmogfHwgIWRkLm9iai5zY3JvbGwgJiYgIWRkLnNjcm9sbCB8fCBkZC5pZTQgfHwgZGQud2hyYXRpbykKCXsKCQlkZC5zY3J4ID0gZGQuc2NyeSA9IDA7CgkJcmV0dXJuOwoJfQoJdmFyIGRfYm5kID0gMHgxYywKCWRfd3ggPSBkZC5nZXRTY3JvbGxYKCksIGRfd3kgPSBkZC5nZXRTY3JvbGxZKCk7CglpZihkZC5tc21vdmVkKQoJewoJCXZhciBkX3d3ID0gZGQuZ2V0V25kVygpLCBkX3doID0gZGQuZ2V0V25kSCgpLCBkX3k7CgkJZGQuc2NyeCA9ICgoZF95ID0gZGQuZS54LWRfd3ctZF93eCtkX2JuZCkgPiAwKT8gKGRfeT4+PTIpKmRfeQoJCQk6ICgoZF95ID0gZF93eCtkX2JuZC1kZC5lLngpID4gMCk/IC0oZF95Pj49MikqZF95CgkJCTogMDsKCQlkZC5zY3J5ID0gKChkX3kgPSBkZC5lLnktZF93aC1kX3d5K2RfYm5kKSA+IDApPyAoZF95Pj49MikqZF95CgkJCTogKChkX3kgPSBkX3d5K2RfYm5kLWRkLmUueSkgPiAwKT8gLShkX3k+Pj0yKSpkX3kKCQkJOiAwOwoJfQoJaWYoZGQuc2NyeCB8fCBkZC5zY3J5KQoJewoJCXdpbmRvdy5zY3JvbGxUbygKCQkJZF93eCArIChkZC5zY3J4ID0gZGQub2JqLmlzX3Jlc2l6ZWQ/IGRkLmxpbVcoZGQub2JqLncrZGQuc2NyeCktZGQub2JqLncgOiBkZC5vYmoudmVydGljYWw/IDAgOiAoZGQubWF4T2ZmWChkZC5vYmoueCtkZC5zY3J4KS1kZC5vYmoueCkpLAoJCQlkX3d5ICsgKGRkLnNjcnkgPSBkZC5vYmouaXNfcmVzaXplZD8gZGQubGltSChkZC5vYmouaCtkZC5zY3J5KS1kZC5vYmouaCA6IGRkLm9iai5ob3Jpem9udGFsPyAwIDogKGRkLm1heE9mZlkoZGQub2JqLnkrZGQuc2NyeSktZGQub2JqLnkpKQoJCSk7CgkJZGQub2JqLmlzX2RyYWdnZWQ/IGRkLm9iai5tb3ZlVG8oZGQub2JqLngrZGQuZ2V0U2Nyb2xsWCgpLWRfd3gsIGRkLm9iai55K2RkLmdldFNjcm9sbFkoKS1kX3d5KQoJCQk6IGRkLnJlc3pUbyhkZC5vYmoudytkZC5nZXRTY3JvbGxYKCktZF93eCwgZGQub2JqLmgrZGQuZ2V0U2Nyb2xsWSgpLWRfd3kpOwoJfQoJZGQubXNtb3ZlZCA9IDA7Cgl3aW5kb3cuc2V0VGltZW91dCgnRERTY3JvbGwoKScsIDB4MzMpOwp9CmZ1bmN0aW9uIFBJQ0soZF9ldikKewoJZGQuZSA9IG5ldyBkZC5ldnQoZF9ldik7CglpZihkZC5lLnggPj0gZGQuZ2V0V25kVygpK2RkLmdldFNjcm9sbFgoKSB8fCBkZC5lLnkgPj0gZGQuZ2V0V25kSCgpK2RkLmdldFNjcm9sbFkoKSkgcmV0dXJuIHRydWU7IC8vIG9uIHNjcm9sbGJhcgoJZm9yKHZhciBkX28sIGRfdCwgZF9jbXAgPSAtMSwgZF9pID0gZGQuZWxlbWVudHMubGVuZ3RoOyBkX2k7KQoJewoJCWRfbyA9IGRkLmVsZW1lbnRzWy0tZF9pXTsKCQlpZihkZC5uNCAmJiBkZC5lLmJ1dCA+IDEgJiYgZGQuZS5zcmMgPT0gZF9vLm9pbWcgJiYgIWRfby5jbG9uZSkgcmV0dXJuIGZhbHNlOwoJCWlmKGRfby52aXNpYmxlICYmIGRkLmUuYnV0IDw9IDEgJiYgZGQuZS54ID49IGRfby54ICYmIGRkLmUueCA8PSBkX28ueCtkX28udyAmJiBkZC5lLnkgPj0gZF9vLnkgJiYgZGQuZS55IDw9IGRfby55K2Rfby5oKQoJCXsKCQkJaWYoZF9vLnogPiBkX2NtcCAmJiAoZF90ID0gZGQuZS5zcmMudGFnKS5pbmRleE9mKCdpbnB1JykgPCAwICYmIGRfdC5pbmRleE9mKCd0ZXh0YScpIDwgMCAmJiBkX3QuaW5kZXhPZignc2VsZScpIDwgMCAmJiBkX3QuaW5kZXhPZignb3B0aScpIDwgMCAmJiBkX3QuaW5kZXhPZignc2Nyb2wnKSA8IDApCgkJCXsKCQkJCWRfY21wID0gZF9vLno7CgkJCQlkZC5vYmogPSBkX287CgkJCX0KCQl9Cgl9CglpZihkZC5vYmopCgl7CgkJaWYoZGQub2JqLm5vZHJhZykgZGQub2JqID0gbnVsbDsKCQllbHNlCgkJewoJCQlkZC5lLmUuY2FuY2VsQnViYmxlID0gdHJ1ZTsKCQkJdmFyIGRfcnN6ID0gZGQuZS5tb2RpZktleSAmJiAoZGQub2JqLnJlc2l6YWJsZSB8fCBkZC5vYmouc2NhbGFibGUpOwoJCQlpZihkZC5vcCkKCQkJewoJCQkJKGRfbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdPcEJsVXInKSkuc3R5bGUucGl4ZWxMZWZ0ID0gZGQuZS54OwoJCQkJZF9vLnN0eWxlLnBpeGVsVG9wID0gZGQuZS55OwoJCQkJKGRfbyA9IGRfby5jaGlsZHJlblswXS5jaGlsZHJlblswXSkuZm9jdXMoKTsKCQkJCWRfby5ibHVyKCk7CgkJCX0KCQkJZWxzZSBpZihkZC5pZSAmJiAhZGQuaWU0KQoJCQl7CgkJCQlpZihkb2N1bWVudC5zZWxlY3Rpb24gJiYgZG9jdW1lbnQuc2VsZWN0aW9uLmVtcHR5KSBkb2N1bWVudC5zZWxlY3Rpb24uZW1wdHkoKTsKCQkJCWRkLmRiLm9uc2VsZWN0c3RhcnQgPSBmdW5jdGlvbigpCgkJCQl7CgkJCQkJZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTsKCQkJCX07CgkJCX0KCQkJaWYoZF9yc3opCgkJCXsKCQkJCWRkLm9iai5fc2V0Q3JzKCdzZS1yZXNpemUnKTsKCQkJCWRkLm9iai5pc19yZXNpemVkID0gMTsKCQkJCWRkLndocmF0aW8gPSBkZC5vYmouc2NhbGFibGU/IGRkLm9iai5kZWZ3L2RkLm9iai5kZWZoIDogMDsKCQkJCWlmKGRkLmllKQoJCQkJewoJCQkJCWlmKGRkLmllNCkKCQkJCQl7CgkJCQkJCXdpbmRvdy5kZF94ID0gZGQuZ2V0U2Nyb2xsWCgpOwoJCQkJCQl3aW5kb3cuZGRfeSA9IGRkLmdldFNjcm9sbFkoKTsKCQkJCQl9CgkJCQkJc2V0VGltZW91dCgKCQkJCQkJJ2lmKGRkLm9iaiAmJiBkb2N1bWVudC5zZWxlY3Rpb24gJiYgZG9jdW1lbnQuc2VsZWN0aW9uLmVtcHR5KScrCgkJCQkJCSd7JysKCQkJCQkJCSdkb2N1bWVudC5zZWxlY3Rpb24uZW1wdHkoKTsnKwoJCQkJCQkJJ2lmKGRkLmllNCkgd2luZG93LnNjcm9sbFRvKHdpbmRvdy5kZF94LCB3aW5kb3cuZGRfeSk7JysKCQkJCQkJJ30nCgkJCQkJLDApOwoJCQkJfQoJCQkJZGQuc2V0TW92SGRsKFJFU0laRSk7CgkJCQlkZC5yZXN6VG8oZGQub2JqLncsIGRkLm9iai5oKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWRkLm9iai5pc19kcmFnZ2VkID0gMTsKCQkJCWRkLnNldE1vdkhkbChEUkFHKTsKCQkJfQoJCQlkZC5zZXRVcEhkbChEUk9QKTsKCQkJZGQuZW1iZWRWaXMoJ2hpZGRlbicpOwoJCQlkZC5vYmouX3NldE9wYVJlbCgwLjcpOwoJCQlkZC5vYmoubWF4aW1pemVaKCk7CgkJCWRkLm9meCA9IGRkLm9iai54K2RkLm9iai53LWRkLmUueDsKCQkJZGQub2Z5ID0gZGQub2JqLnkrZGQub2JqLmgtZGQuZS55OwoJCQlpZih3aW5kb3cubXlfUGlja0Z1bmMpIG15X1BpY2tGdW5jKCk7CgkJCWlmKGRkLm9iai5waWNrRnVuYykgZGQub2JqLnBpY2tGdW5jKCk7CgkJCUREU2Nyb2xsKCk7CgkJCXJldHVybiAhKAoJCQkJZGQub2JqLmlzX3Jlc2l6ZWQKCQkJCXx8IGRkLm40ICYmIGRkLm9iai5pc19pbWFnZQoJCQkJfHwgZGQubjYgfHwgZGQudzNjCgkJCSk7CgkJfQoJfQoJaWYoZGQuZG93bkZ1bmMpIHJldHVybiBkZC5kb3duRnVuYyhkX2V2KTsKCXJldHVybiB0cnVlOwp9CmZ1bmN0aW9uIERSQUcoZF9ldikKewoJaWYoIWRkLm9iaiB8fCAhZGQub2JqLnZpc2libGUpIHJldHVybiB0cnVlOwoJaWYoZGQuaWU0IHx8IGRkLnczYyB8fCBkZC5uNiB8fCBkZC5vYmouY2hpbGRyZW4ubGVuZ3RoID4gMHhmKQoJewoJCWlmKGRkLndhaXQpIHJldHVybiBmYWxzZTsKCQlkZC53YWl0ID0gMTsKCQlzZXRUaW1lb3V0KCdkZC53YWl0ID0gMDsnLCBkZC50V2FpdCk7Cgl9CglkZC5lID0gbmV3IGRkLmV2dChkX2V2KTsKCWlmKGRkLmllICYmICFkZC5lLmJ1dCkKCXsKCQlEUk9QKGRfZXYpOwoJCXJldHVybiB0cnVlOwoJfQoJZGQubXNtb3ZlZCA9IDE7CglkZC5vYmoubW92ZVRvKAoJCWRkLm9iai52ZXJ0aWNhbD8gZGQub2JqLnggOiBkZC5tYXhPZmZYKGRkLmluV25kVyhkZC5vZngrZGQuZS54KS1kZC5vYmoudyksCgkJZGQub2JqLmhvcml6b250YWw/IGRkLm9iai55IDogZGQubWF4T2ZmWShkZC5pblduZEgoZGQub2Z5K2RkLmUueSktZGQub2JqLmgpCgkpOwoKCWlmKHdpbmRvdy5teV9EcmFnRnVuYykgbXlfRHJhZ0Z1bmMoKTsKCWlmKGRkLm9iai5kcmFnRnVuYykgZGQub2JqLmRyYWdGdW5jKCk7CglpZihkZC5tb3ZlRnVuYykgcmV0dXJuIGRkLm1vdmVGdW5jKGRfZXYpOwoJcmV0dXJuIGZhbHNlOwp9CmZ1bmN0aW9uIFJFU0laRShkX2V2KQp7CglpZighZGQub2JqIHx8ICFkZC5vYmoudmlzaWJsZSkgcmV0dXJuIHRydWU7CglpZihkZC53YWl0KSByZXR1cm4gZmFsc2U7CglkZC53YWl0ID0gMTsKCXNldFRpbWVvdXQoJ2RkLndhaXQgPSAwOycsIGRkLnRXYWl0KTsKCWRkLmUgPSBuZXcgZGQuZXZ0KGRfZXYpOwoJaWYoZGQuaWUgJiYgIWRkLmUuYnV0KQoJewoJCURST1AoZF9ldik7CgkJcmV0dXJuIHRydWU7Cgl9CglkZC5tc21vdmVkID0gMTsKCXZhciBkX3cgPSBkZC5saW1XKGRkLmluV25kVyhkZC5vZngrZGQuZS54KS1kZC5vYmoueCksIGRfaDsKCWlmKCFkZC53aHJhdGlvKSBkX2ggPSBkZC5saW1IKGRkLmluV25kSChkZC5vZnkrZGQuZS55KS1kZC5vYmoueSk7CgllbHNlCgl7CgkJZF9oID0gZGQubGltSChkZC5pblduZEgoTWF0aC5yb3VuZChkX3cvZGQud2hyYXRpbykrZGQub2JqLnkpLWRkLm9iai55KTsKCQlkX3cgPSBNYXRoLnJvdW5kKGRfaCpkZC53aHJhdGlvKTsKCX0KCWRkLnJlc3pUbyhkX3csIGRfaCk7CglpZih3aW5kb3cubXlfUmVzaXplRnVuYykgbXlfUmVzaXplRnVuYygpOwoJaWYoZGQub2JqLnJlc2l6ZUZ1bmMpIGRkLm9iai5yZXNpemVGdW5jKCk7CglpZihkZC5tb3ZlRnVuYykgcmV0dXJuIGRkLm1vdmVGdW5jKGRfZXYpOwoJcmV0dXJuIGZhbHNlOwp9CmZ1bmN0aW9uIERST1AoZF9ldikKewoJaWYoZGQub2JqKQoJewoJCWlmKGRkLm9iai5pc19kcmFnZ2VkKQoJCXsKCQkJaWYoIWRkLm9iai5pc19pbWFnZSkgZGQuZ2V0V0goZGQub2JqKTsKCQl9CgkJZWxzZSBpZihkZC5uNCkKCQl7CgkJCWlmKGRkLm9iai5pc19pbWFnZSkKCQkJewoJCQkJZGQubjRSZWN0VmlzKDApOwoJCQkJZGQub2JqLnJlc2l6ZVRvKGRkLm9iai53LCBkZC5vYmouaCk7CgkJCX0KCQl9CgkJaWYoIWRkLm40IHx8ICFkZC5vYmouaXNfaW1hZ2UpIGRkLnJlY2FsYygpOwoJCWRkLnNldE1vdkhkbChkZC5tb3ZlRnVuYyk7CgkJZGQuc2V0VXBIZGwoZGQudXBGdW5jKTsKCQlpZihkZC5kYikgZGQuZGIub25zZWxlY3RzdGFydCA9IG51bGw7CgkJZGQub2JqLl9zZXRPcGFSZWwoMS4wKTsKCQlkZC5vYmouX3NldENycyhkZC5vYmouY3Vyc29yKTsKCQlkZC5lbWJlZFZpcygndmlzaWJsZScpOwoJCWRkLm9iai5fcmVzZXRaKCk7CgkJZGQuZSA9IG5ldyBkZC5ldnQoZF9ldik7CgkJaWYod2luZG93Lm15X0Ryb3BGdW5jKSBteV9Ecm9wRnVuYygpOwoJCWlmKGRkLm9iai5kcm9wRnVuYykgZGQub2JqLmRyb3BGdW5jKCk7CgkJZGQubXNtb3ZlZCA9IGRkLm9iai5pc19kcmFnZ2VkID0gZGQub2JqLmlzX3Jlc2l6ZWQgPSBkZC53aHJhdGlvID0gMDsKCQlkZC5vYmogPSBudWxsOwoJfQoJZGQuc2V0RHduSGRsKFBJQ0spOwp9CmZ1bmN0aW9uIFNFVF9ESFRNTCgpCnsKCXZhciBkX2EgPSBhcmd1bWVudHMsIGRfYWksIGRfaHRtID0gJycsIGRfbywgZF9pID0gZF9hLmxlbmd0aDsKCXdoaWxlKGRfaSkKCXsKCQlpZighKGRfYWkgPSBkX2FbLS1kX2ldKS5pbmRleE9mKCdjOicpKSBkZC5jdXJzb3IgPSBkX2FpLnN1YnN0cmluZygyKTsKCQllbHNlIGlmKGRfYWkgPT0gTk9fQUxUKSBkZC5ub2FsdCA9IDE7CgkJZWxzZSBpZihkX2FpID09IFNDUk9MTCkgZGQuc2Nyb2xsID0gMTsKCQllbHNlIGlmKGRfYWkgPT0gUkVTRVRfWikgZGQucmVfeiA9IDE7CgkJZWxzZSBpZihkX2FpID09IFJFU0laQUJMRSkgZGQucmVzaXphYmxlID0gMTsKCQllbHNlIGlmKGRfYWkgPT0gU0NBTEFCTEUpIGRkLnNjYWxhYmxlID0gMTsKCQllbHNlIGlmKGRfYWkgPT0gVFJBTlNQQVJFTlQpIGRkLmRpYXBoYW4gPSAxOwoJCWVsc2UKCQl7CgkJCWRfbyA9IG5ldyBERE9iaihkX2FpKTsKCQkJZGQuYWRkRWx0KGRfbyk7CgkJCWRfaHRtICs9IGRfby50X2h0bSB8fCAnJzsKCQkJaWYoZF9vLm9pbWcgJiYgZF9vLmNweV9uKQoJCQl7CgkJCQlmb3IodmFyIGRfbCA9IGRfby5jcHlfbiwgZF9qID0gMDsgZF9qIDwgZF9sOykKCQkJCXsKCQkJCQl2YXIgZF9wID0gbmV3IERET2JqKGRfby5uYW1lK2Rfby5jbWQsICsrZF9qKTsKCQkJCQlkZC5hZGRFbHQoZF9wLCBkX28pOwoJCQkJCWRfcC5kZWZ6ID0gZF9vLmRlZnorZF9qOwoJCQkJCWRfcC5vcmlnaW5hbCA9IGRfbzsKCQkJCQlkX2h0bSArPSBkX3AudF9odG07CgkJCQl9CgkJCX0KCQl9Cgl9CglpZiAoZGQubjQgfHwgZGQubjYgfHwgZGQuaWUgfHwgZGQub3AgfHwgZGQudzNjKSBkb2N1bWVudC53cml0ZSgKCQkoZGQubjQ/ICc8ZGl2IHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTsiPjxcL2Rpdj5cbicKCQk6IChkZC5vcCAmJiAhZGQub3A2KT8gJzxkaXYgaWQ9Ik9wQmxVciIgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlO3Zpc2liaWxpdHk6aGlkZGVuO3dpZHRoOjBweDtoZWlnaHQ6MHB4OyI+PGZvcm0+PGlucHV0IHR5cGU9InRleHQiIHN0eWxlPSJ3aWR0aDowcHg7aGVpZ2h0OjBweDsiPjxcL2Zvcm0+PFwvZGl2PicKCQk6ICcnKSArIGRfaHRtCgkpOwoJZGQueiA9IDB4MzM7Cglmb3IoZF9pID0gZGQuZWxlbWVudHMubGVuZ3RoOyBkX2k7KQoJewoJCWRkLmFkZFByb3BzKGRfbyA9IGRkLmVsZW1lbnRzWy0tZF9pXSk7CgkJaWYoZF9vLmlzX2ltYWdlICYmICFkX28ub3JpZ2luYWwgJiYgIWRfby5jbG9uZSkKCQkJZGQubjQ/IGRfby5vaW1nLnNyYyA9IHNwYWNlciA6IGRfby5vaW1nLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJzsKCX0KCWRkLm1rV3pEb20oKTsKCWlmKHdpbmRvdy5vbmxvYWQpIGRkLmxvYWRGdW5jID0gd2luZG93Lm9ubG9hZDsKCWlmKHdpbmRvdy5vbnVubG9hZCkgZGQudWxvYWRGdW5jID0gd2luZG93Lm9udW5sb2FkOwoJd2luZG93Lm9ubG9hZCA9IGRkLmluaXR6OwoJd2luZG93Lm9udW5sb2FkID0gZGQuZmlubHo7CglkZC5zZXREd25IZGwoUElDSyk7Cn0KZnVuY3Rpb24gQUREX0RIVE1MKCkgLy8gbGF5ZXJzIG9ubHkhCnsKCXZhciBkX2EgPSBhcmd1bWVudHMsIGRfbywgZF9pID0gZF9hLmxlbmd0aDsgd2hpbGUoZF9pKQoJewoJCWRfbyA9IG5ldyBERE9iaihkX2FbLS1kX2ldKTsKCQlkZC5hZGRFbHQoZF9vKTsKCQlkZC5hZGRQcm9wcyhkX28pOwoJfQoJZGQubWtXekRvbSgpOwp9CgoKCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLy8gSWYgbm90IG5lZWRlZCwgYWxsIGNvZGUgYmVsb3cgdGhpcyBsaW5lIG1heSBiZSByZW1vdmVkCgoKLy8gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKZGQuZCA9IGRvY3VtZW50OwkJCS8vIDwgdi4gMi43Mgp2YXIgUkVTRVRfWklOREVYID0gUkVTRVRfWjsgLy8gPCAzLjQ0CnZhciBLRVlET1dOX1JFU0laRSA9IFJFU0laQUJMRTsgLy8gPCA0LjQzCnZhciBDVVJTT1JfUE9JTlRFUiA9IENVUlNPUl9IQU5EOyAvLyA8IDQuNDQKdmFyIE5PX1NDUk9MTCA9ICcnOwkJIC8vIDwgdi4gNC40OQoKCgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIEZVTkNUSU9OUyBGT1IgRVhURU5ERUQgU0NSSVBUSU5HCi8vIFVzZSB0aGVzZSBmb3IgeW91ciBvd24gZXh0ZW5zaW9ucywKLy8gb3IgdG8gY2FsbCBmdW5jdGlvbnMgZGVmaW5lZCBlbHNld2hlcmUKCgoKLyogbXlfUGlja0Z1bmMgSVMgQVVUT01BVElDQUxMWSBDQUxMRUQgV0hFTiBBTiBJVEVNIFNUQVJUUyBUTyBCRSBEUkFHR0VELgpUaGUgZm9sbG93aW5nIG9iamVjdHMvcHJvcGVydGllcyBhcmUgYWNjZXNzaWJsZSBmcm9tIGhlcmU6CgotIGRkLmU6IGN1cnJlbnQgbW91c2UgZXZlbnQKLSBkZC5lLnByb3BlcnR5OiBhY2Nlc3MgdG8gYSBwcm9wZXJ0eSBvZiB0aGUgY3VycmVudCBtb3VzZSBldmVudC4KICBNb3N0bHkgcmVxdWVzdGVkIHByb3BlcnRpZXM6CiAgLSBkZC5lLng6IGRvY3VtZW50LXJlbGF0ZWQgeCBjby1vcmRpbmF0ZQogIC0gZGQuZS55OiBkb2N1bWVudC1yZWxhdGVkIHkgY28tb3JkCiAgLSBkZC5lLnNyYzogdGFyZ2V0IG9mIG1vdXNlIGV2ZW50IChub3QgaWRlbnRpY2FsIHdpdGggdGhlIGRyYWcgZHJvcCBvYmplY3QgaXRzZWxmKS4KICAtIGRkLmUuYnV0dG9uOiBjdXJyZW50bHkgcHJlc3NlZCBtb3VzZSBidXR0b24uIExlZnQgYnV0dG9uOiBkZC5lLmJ1dHRvbiA8PSAxCgotIGRkLm9iajogcmVmZXJlbmNlIHRvIGN1cnJlbnRseSBkcmFnZ2VkIGl0ZW0uCi0gZGQub2JqLnByb3BlcnR5OiBhY2Nlc3MgdG8gYW55IHByb3BlcnR5IG9mIHRoYXQgaXRlbS4KLSBkZC5vYmoubWV0aG9kKCk6IGZvciBleGFtcGxlIGRkLm9iai5yZXNpemVUbygpIG9yIGRkLm9iai5zd2FwSW1hZ2UoKSAuCiAgTW9zdGx5IHJlcXVlc3RlZCBwcm9wZXJ0aWVzOgoJLSBkZC5vYmoubmFtZTogaW1hZ2UgbmFtZSBvciBsYXllciBJRCBwYXNzZWQgdG8gU0VUX0RIVE1MKCk7CgktIGRkLm9iai54IGFuZCBkZC5vYmoueTogY28tb3JkaW5hdGVzOwoJLSBkZC5vYmoudyBhbmQgZGQub2JqLmg6IHNpemU7CgktIGRkLm9iai5pc19kcmFnZ2VkOiAxIHdoaWxlIGl0ZW0gaXMgZHJhZ2dlZCwgZWxzZSAwOwoJLSBkZC5vYmouaXNfcmVzaXplZDogMSB3aGlsZSBpdGVtIGlzIHJlc2l6ZWQsIGkuZS4gaWYgPGN0cmw+IG9yIDxzaGlmdD4gaXMgcHJlc3NlZCwgZWxzZSAwCgpGb3IgbW9yZSBwcm9wZXJ0aWVzIGFuZCBkZXRhaWxzLCB2aXNpdCB0aGUgQVBJIGRvY3VtZW50YXRpb24KYXQgaHR0cDovL3d3dy53YWx0ZXJ6b3JuLmNvbS9kcmFnZHJvcC9hcGlfZS5odG0gKGVuZ2xpc2gpIG9yCmh0dHA6Ly93d3cud2FsdGVyem9ybi5kZS9kcmFnZHJvcC9hcGkuaHRtIChnZXJtYW4pCSovCmZ1bmN0aW9uIG15X1BpY2tGdW5jKCkKewp9CgoKCgovKiBteV9EcmFnRnVuYyBJUyBDQUxMRUQgV0hJTEUgQU4gSVRFTSBJUyBEUkFHR0VEClNlZSB0aGUgZGVzY3JpcHRpb24gb2YgbXlfUGlja0Z1bmMgYWJvdmUgZm9yIHdoYXQncyBhY2Nlc3NpYmxlIGZyb20gaGVyZS4gKi8KZnVuY3Rpb24gbXlfRHJhZ0Z1bmMoKQp7CgkvL3dpbmRvdy5zdGF0dXMgPSAnZGQuZWxlbWVudHMuJyArIGRkLm9iai5uYW1lICsgJy54ICA9ICcgKyBkZC5vYmoueCArICcJIGRkLmVsZW1lbnRzLicgKyBkZC5vYmoubmFtZSArICcueSA9ICcgKyBkZC5vYmoueTsKfQoKCgoKLyogbXlfUmVzaXplRnVuYyBJUyBDQUxMRUQgV0hJTEUgQU4gSVRFTSBJUyBSRVNJWkVEClNlZSB0aGUgZGVzY3JpcHRpb24gb2YgbXlfUGlja0Z1bmMgYWJvdmUgZm9yIHdoYXQncyBhY2Nlc3NpYmxlIGZyb20gaGVyZS4gKi8KZnVuY3Rpb24gbXlfUmVzaXplRnVuYygpCnsKCS8vd2luZG93LnN0YXR1cyA9ICdkZC5lbGVtZW50cy4nICsgZGQub2JqLm5hbWUgKyAnLncgID0gJyArIGRkLm9iai53ICsgJwkgZGQuZWxlbWVudHMuJyArIGRkLm9iai5uYW1lICsgJy5oID0gJyArIGRkLm9iai5oOwp9CgoKCgovKiBUSElTIE9ORSBJUyBDQUxMRUQgT05DRSBBTiBJVEVNIElTIERST1BQRUQKU2VlIHRoZSBkZXNjcmlwdGlvbiBvZiBteV9QaWNrRnVuYyBmb3Igd2hhdCdzIGFjY2Vzc2libGUgZnJvbSBoZXJlLgpIZXJlIG1heSBiZSBpbnZlc3RpZ2F0ZWQsIGZvciBleGFtcGxlLCB3aGF0J3MgdGhlIG5hbWUgKGRkLm9iai5uYW1lKQpvZiB0aGUgZHJvcHBlZCBpdGVtLCBhbmQgd2hlcmUgKGRkLm9iai54LCBkZC5vYmoueSkgaXQgaGFzIGJlZW4gZHJvcHBlZC4uLiAqLwpmdW5jdGlvbiBteV9Ecm9wRnVuYygpCnsKfQo='></script>


	<script id="wz_graphics" src='data:/text/plain;base64,LyogVGhpcyBub3RpY2UgbXVzdCBiZSB1bnRvdWNoZWQgYXQgYWxsIHRpbWVzLg0KDQp3el9qc2dyYXBoaWNzLmpzICAgIHYuIDMuMDUNClRoZSBsYXRlc3QgdmVyc2lvbiBpcyBhdmFpbGFibGUgYXQNCmh0dHA6Ly93d3cud2FsdGVyem9ybi5jb20NCm9yIGh0dHA6Ly93d3cuZGV2aXJhLmNvbQ0Kb3IgaHR0cDovL3d3dy53YWx0ZXJ6b3JuLmRlDQoNCkNvcHlyaWdodCAoYykgMjAwMi0yMDA5IFdhbHRlciBab3JuLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KQ3JlYXRlZCAzLiAxMS4gMjAwMiBieSBXYWx0ZXIgWm9ybiAoV2ViOiBodHRwOi8vd3d3LndhbHRlcnpvcm4uY29tICkNCkxhc3QgbW9kaWZpZWQ6IDIuIDIuIDIwMDkNCg0KUGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9ucyBmb3IgSW50ZXJuZXQgRXhwbG9yZXINCmJ5IFRob21hcyBGcmFuayBhbmQgSm9obiBIb2xkc3dvcnRoLg0KZmlsbFBvbHlnb24gbWV0aG9kIGltcGxlbWVudGVkIGJ5IE1hdHRoaWV1IEhhbGxlci4NCg0KSGlnaCBQZXJmb3JtYW5jZSBKYXZhU2NyaXB0IEdyYXBoaWNzIExpYnJhcnkuDQpQcm92aWRlcyBtZXRob2RzDQotIHRvIGRyYXcgbGluZXMsIHJlY3RhbmdsZXMsIGVsbGlwc2VzLCBwb2x5Z29ucw0KCXdpdGggc3BlY2lmaWFibGUgbGluZSB0aGlja25lc3MsDQotIHRvIGZpbGwgcmVjdGFuZ2xlcywgcG9seWdvbnMsIGVsbGlwc2VzIGFuZCBhcmNzDQotIHRvIGRyYXcgdGV4dC4NCk5PVEU6IE9wZXJhdGlvbnMsIGZ1bmN0aW9ucyBhbmQgYnJhbmNoaW5nIGhhdmUgcmF0aGVyIGJlZW4gb3B0aW1pemVkDQp0byBlZmZpY2llbmN5IGFuZCBzcGVlZCB0aGFuIHRvIHNob3J0bmVzcyBvZiBzb3VyY2UgY29kZS4NCg0KTElDRU5TRTogTEdQTA0KDQpUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQptb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQpMaWNlbnNlIChMR1BMKSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQp2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCg0KVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQpidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCkxlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQoNCllvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCkxpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCkZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EsDQpvciBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2NvcHlsZWZ0L2xlc3Nlci5odG1sDQoqLw0KDQoNCnZhciBqZ19vaywgamdfaWUsIGpnX2Zhc3QsIGpnX2RvbSwgamdfbW96Ow0KDQoNCmZ1bmN0aW9uIF9jaGtESFRNKHduZCwgeCwgaSkNCi8vIFVuZGVyIFhVTCwgb3duZXIgb2YgJ2RvY3VtZW50JyBtdXN0IGJlIHNwZWNpZmllZCBleHBsaWNpdGx5DQp7DQoJeCA9IHduZC5kb2N1bWVudC5ib2R5IHx8IG51bGw7DQoJamdfaWUgPSB4ICYmIHR5cGVvZiB4Lmluc2VydEFkamFjZW50SFRNTCAhPSAidW5kZWZpbmVkIiAmJiB3bmQuZG9jdW1lbnQuY3JlYXRlRWxlbWVudDsNCglqZ19kb20gPSAoeCAmJiAhamdfaWUgJiYNCgkJdHlwZW9mIHguYXBwZW5kQ2hpbGQgIT0gInVuZGVmaW5lZCIgJiYNCgkJdHlwZW9mIHduZC5kb2N1bWVudC5jcmVhdGVSYW5nZSAhPSAidW5kZWZpbmVkIiAmJg0KCQl0eXBlb2YgKGkgPSB3bmQuZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKSkuc2V0U3RhcnRCZWZvcmUgIT0gInVuZGVmaW5lZCIgJiYNCgkJdHlwZW9mIGkuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50ICE9ICJ1bmRlZmluZWQiKTsNCglqZ19mYXN0ID0gamdfaWUgJiYgd25kLmRvY3VtZW50LmFsbCAmJiAhd25kLm9wZXJhOw0KCWpnX21veiA9IGpnX2RvbSAmJiB0eXBlb2YgeC5zdHlsZS5Nb3pPcGFjaXR5ICE9ICJ1bmRlZmluZWQiOw0KCWpnX29rID0gISEoamdfaWUgfHwgamdfZG9tKTsNCn0NCg0KZnVuY3Rpb24gX3BudENudkRvbSgpDQp7DQoJdmFyIHggPSB0aGlzLnduZC5kb2N1bWVudC5jcmVhdGVSYW5nZSgpOw0KCXguc2V0U3RhcnRCZWZvcmUodGhpcy5jbnYpOw0KCXggPSB4LmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChqZ19mYXN0PyB0aGlzLl9odG1ScGMoKSA6IHRoaXMuaHRtKTsNCglpZih0aGlzLmNudikgdGhpcy5jbnYuYXBwZW5kQ2hpbGQoeCk7DQoJdGhpcy5odG0gPSAiIjsNCn0NCg0KZnVuY3Rpb24gX3BudENudkllKCkNCnsNCglpZih0aGlzLmNudikgdGhpcy5jbnYuaW5zZXJ0QWRqYWNlbnRIVE1MKCJCZWZvcmVFbmQiLCBqZ19mYXN0PyB0aGlzLl9odG1ScGMoKSA6IHRoaXMuaHRtKTsNCgl0aGlzLmh0bSA9ICIiOw0KfQ0KDQpmdW5jdGlvbiBfcG50RG9jKCkNCnsNCgl0aGlzLnduZC5kb2N1bWVudC53cml0ZShqZ19mYXN0PyB0aGlzLl9odG1ScGMoKSA6IHRoaXMuaHRtKTsNCgl0aGlzLmh0bSA9ICcnOw0KfQ0KDQpmdW5jdGlvbiBfcG50TigpDQp7DQoJOw0KfQ0KDQpmdW5jdGlvbiBfbWtEaXYoeCwgeSwgdywgaCkNCnsNCgl0aGlzLmh0bSArPSAnPGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7JysNCgkJJ2xlZnQ6JyArIHggKyAncHg7JysNCgkJJ3RvcDonICsgeSArICdweDsnKw0KCQknd2lkdGg6JyArIHcgKyAncHg7JysNCgkJJ2hlaWdodDonICsgaCArICdweDsnKw0KCQknY2xpcDpyZWN0KDAsJyt3KydweCwnK2grJ3B4LDApOycrDQoJCSdiYWNrZ3JvdW5kLWNvbG9yOicgKyB0aGlzLmNvbG9yICsNCgkJKCFqZ19tb3o/ICc7b3ZlcmZsb3c6aGlkZGVuJyA6ICcnKSsNCgkJJzsiPjxcL2Rpdj4nOw0KfQ0KDQpmdW5jdGlvbiBfbWtEaXZJZSh4LCB5LCB3LCBoKQ0Kew0KCXRoaXMuaHRtICs9ICclJScrdGhpcy5jb2xvcisnOycreCsnOycreSsnOycrdysnOycraCsnOyc7DQp9DQoNCmZ1bmN0aW9uIF9ta0RpdlBydCh4LCB5LCB3LCBoKQ0Kew0KCXRoaXMuaHRtICs9ICc8ZGl2IHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTsnKw0KCQknYm9yZGVyLWxlZnQ6JyArIHcgKyAncHggc29saWQgJyArIHRoaXMuY29sb3IgKyAnOycrDQoJCSdsZWZ0OicgKyB4ICsgJ3B4OycrDQoJCSd0b3A6JyArIHkgKyAncHg7JysNCgkJJ3dpZHRoOjBweDsnKw0KCQknaGVpZ2h0OicgKyBoICsgJ3B4OycrDQoJCSdjbGlwOnJlY3QoMCwnK3crJ3B4LCcraCsncHgsMCk7JysNCgkJJ2JhY2tncm91bmQtY29sb3I6JyArIHRoaXMuY29sb3IgKw0KCQkoIWpnX21vej8gJztvdmVyZmxvdzpoaWRkZW4nIDogJycpKw0KCQknOyI+PFwvZGl2Pic7DQp9DQoNCnZhciBfcmVnZXggPSAgLyUlKFteO10rKTsoW147XSspOyhbXjtdKyk7KFteO10rKTsoW147XSspOy9nOw0KZnVuY3Rpb24gX2h0bVJwYygpDQp7DQoJcmV0dXJuIHRoaXMuaHRtLnJlcGxhY2UoDQoJCV9yZWdleCwNCgkJJzxkaXYgc3R5bGU9Im92ZXJmbG93OmhpZGRlbjtwb3NpdGlvbjphYnNvbHV0ZTtiYWNrZ3JvdW5kLWNvbG9yOicrDQoJCSckMTtsZWZ0OiQycHg7dG9wOiQzcHg7d2lkdGg6JDRweDtoZWlnaHQ6JDVweCI+PC9kaXY+XG4nKTsNCn0NCg0KZnVuY3Rpb24gX2h0bVBydFJwYygpDQp7DQoJcmV0dXJuIHRoaXMuaHRtLnJlcGxhY2UoDQoJCV9yZWdleCwNCgkJJzxkaXYgc3R5bGU9Im92ZXJmbG93OmhpZGRlbjtwb3NpdGlvbjphYnNvbHV0ZTtiYWNrZ3JvdW5kLWNvbG9yOicrDQoJCSckMTtsZWZ0OiQycHg7dG9wOiQzcHg7d2lkdGg6JDRweDtoZWlnaHQ6JDVweDtib3JkZXItbGVmdDokNHB4IHNvbGlkICQxIj48L2Rpdj5cbicpOw0KfQ0KDQpmdW5jdGlvbiBfbWtMaW4oeDEsIHkxLCB4MiwgeTIpDQp7DQoJaWYoeDEgPiB4MikNCgl7DQoJCXZhciBfeDIgPSB4MjsNCgkJdmFyIF95MiA9IHkyOw0KCQl4MiA9IHgxOw0KCQl5MiA9IHkxOw0KCQl4MSA9IF94MjsNCgkJeTEgPSBfeTI7DQoJfQ0KCXZhciBkeCA9IHgyLXgxLCBkeSA9IE1hdGguYWJzKHkyLXkxKSwNCgl4ID0geDEsIHkgPSB5MSwNCgl5SW5jciA9ICh5MSA+IHkyKT8gLTEgOiAxOw0KDQoJaWYoZHggPj0gZHkpDQoJew0KCQl2YXIgcHIgPSBkeTw8MSwNCgkJcHJ1ID0gcHIgLSAoZHg8PDEpLA0KCQlwID0gcHItZHgsDQoJCW94ID0geDsNCgkJd2hpbGUoZHggPiAwKQ0KCQl7LS1keDsNCgkJCSsreDsNCgkJCWlmKHAgPiAwKQ0KCQkJew0KCQkJCXRoaXMuX21rRGl2KG94LCB5LCB4LW94LCAxKTsNCgkJCQl5ICs9IHlJbmNyOw0KCQkJCXAgKz0gcHJ1Ow0KCQkJCW94ID0geDsNCgkJCX0NCgkJCWVsc2UgcCArPSBwcjsNCgkJfQ0KCQl0aGlzLl9ta0RpdihveCwgeSwgeDItb3grMSwgMSk7DQoJfQ0KDQoJZWxzZQ0KCXsNCgkJdmFyIHByID0gZHg8PDEsDQoJCXBydSA9IHByIC0gKGR5PDwxKSwNCgkJcCA9IHByLWR5LA0KCQlveSA9IHk7DQoJCWlmKHkyIDw9IHkxKQ0KCQl7DQoJCQl3aGlsZShkeSA+IDApDQoJCQl7LS1keTsNCgkJCQlpZihwID4gMCkNCgkJCQl7DQoJCQkJCXRoaXMuX21rRGl2KHgrKywgeSwgMSwgb3kteSsxKTsNCgkJCQkJeSArPSB5SW5jcjsNCgkJCQkJcCArPSBwcnU7DQoJCQkJCW95ID0geTsNCgkJCQl9DQoJCQkJZWxzZQ0KCQkJCXsNCgkJCQkJeSArPSB5SW5jcjsNCgkJCQkJcCArPSBwcjsNCgkJCQl9DQoJCQl9DQoJCQl0aGlzLl9ta0Rpdih4MiwgeTIsIDEsIG95LXkyKzEpOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJd2hpbGUoZHkgPiAwKQ0KCQkJey0tZHk7DQoJCQkJeSArPSB5SW5jcjsNCgkJCQlpZihwID4gMCkNCgkJCQl7DQoJCQkJCXRoaXMuX21rRGl2KHgrKywgb3ksIDEsIHktb3kpOw0KCQkJCQlwICs9IHBydTsNCgkJCQkJb3kgPSB5Ow0KCQkJCX0NCgkJCQllbHNlIHAgKz0gcHI7DQoJCQl9DQoJCQl0aGlzLl9ta0Rpdih4Miwgb3ksIDEsIHkyLW95KzEpOw0KCQl9DQoJfQ0KfQ0KDQpmdW5jdGlvbiBfbWtMaW4yRCh4MSwgeTEsIHgyLCB5MikNCnsNCglpZih4MSA+IHgyKQ0KCXsNCgkJdmFyIF94MiA9IHgyOw0KCQl2YXIgX3kyID0geTI7DQoJCXgyID0geDE7DQoJCXkyID0geTE7DQoJCXgxID0gX3gyOw0KCQl5MSA9IF95MjsNCgl9DQoJdmFyIGR4ID0geDIteDEsIGR5ID0gTWF0aC5hYnMoeTIteTEpLA0KCXggPSB4MSwgeSA9IHkxLA0KCXlJbmNyID0gKHkxID4geTIpPyAtMSA6IDE7DQoNCgl2YXIgcyA9IHRoaXMuc3Ryb2tlOw0KCWlmKGR4ID49IGR5KQ0KCXsNCgkJaWYoZHggPiAwICYmIHMtMyA+IDApDQoJCXsNCgkJCXZhciBfcyA9IChzKmR4Kk1hdGguc3FydCgxK2R5KmR5LyhkeCpkeCkpLWR4LShzPj4xKSpkeSkgLyBkeDsNCgkJCV9zID0gKCEocy00KT8gTWF0aC5jZWlsKF9zKSA6IE1hdGgucm91bmQoX3MpKSArIDE7DQoJCX0NCgkJZWxzZSB2YXIgX3MgPSBzOw0KCQl2YXIgYWQgPSBNYXRoLmNlaWwocy8yKTsNCg0KCQl2YXIgcHIgPSBkeTw8MSwNCgkJcHJ1ID0gcHIgLSAoZHg8PDEpLA0KCQlwID0gcHItZHgsDQoJCW94ID0geDsNCgkJd2hpbGUoZHggPiAwKQ0KCQl7LS1keDsNCgkJCSsreDsNCgkJCWlmKHAgPiAwKQ0KCQkJew0KCQkJCXRoaXMuX21rRGl2KG94LCB5LCB4LW94K2FkLCBfcyk7DQoJCQkJeSArPSB5SW5jcjsNCgkJCQlwICs9IHBydTsNCgkJCQlveCA9IHg7DQoJCQl9DQoJCQllbHNlIHAgKz0gcHI7DQoJCX0NCgkJdGhpcy5fbWtEaXYob3gsIHksIHgyLW94K2FkKzEsIF9zKTsNCgl9DQoNCgllbHNlDQoJew0KCQlpZihzLTMgPiAwKQ0KCQl7DQoJCQl2YXIgX3MgPSAocypkeSpNYXRoLnNxcnQoMStkeCpkeC8oZHkqZHkpKS0ocz4+MSkqZHgtZHkpIC8gZHk7DQoJCQlfcyA9ICghKHMtNCk/IE1hdGguY2VpbChfcykgOiBNYXRoLnJvdW5kKF9zKSkgKyAxOw0KCQl9DQoJCWVsc2UgdmFyIF9zID0gczsNCgkJdmFyIGFkID0gTWF0aC5yb3VuZChzLzIpOw0KDQoJCXZhciBwciA9IGR4PDwxLA0KCQlwcnUgPSBwciAtIChkeTw8MSksDQoJCXAgPSBwci1keSwNCgkJb3kgPSB5Ow0KCQlpZih5MiA8PSB5MSkNCgkJew0KCQkJKythZDsNCgkJCXdoaWxlKGR5ID4gMCkNCgkJCXstLWR5Ow0KCQkJCWlmKHAgPiAwKQ0KCQkJCXsNCgkJCQkJdGhpcy5fbWtEaXYoeCsrLCB5LCBfcywgb3kteSthZCk7DQoJCQkJCXkgKz0geUluY3I7DQoJCQkJCXAgKz0gcHJ1Ow0KCQkJCQlveSA9IHk7DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCXkgKz0geUluY3I7DQoJCQkJCXAgKz0gcHI7DQoJCQkJfQ0KCQkJfQ0KCQkJdGhpcy5fbWtEaXYoeDIsIHkyLCBfcywgb3kteTIrYWQpOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJd2hpbGUoZHkgPiAwKQ0KCQkJey0tZHk7DQoJCQkJeSArPSB5SW5jcjsNCgkJCQlpZihwID4gMCkNCgkJCQl7DQoJCQkJCXRoaXMuX21rRGl2KHgrKywgb3ksIF9zLCB5LW95K2FkKTsNCgkJCQkJcCArPSBwcnU7DQoJCQkJCW95ID0geTsNCgkJCQl9DQoJCQkJZWxzZSBwICs9IHByOw0KCQkJfQ0KCQkJdGhpcy5fbWtEaXYoeDIsIG95LCBfcywgeTItb3krYWQrMSk7DQoJCX0NCgl9DQp9DQoNCmZ1bmN0aW9uIF9ta0xpbkRvdHQoeDEsIHkxLCB4MiwgeTIpDQp7DQoJaWYoeDEgPiB4MikNCgl7DQoJCXZhciBfeDIgPSB4MjsNCgkJdmFyIF95MiA9IHkyOw0KCQl4MiA9IHgxOw0KCQl5MiA9IHkxOw0KCQl4MSA9IF94MjsNCgkJeTEgPSBfeTI7DQoJfQ0KCXZhciBkeCA9IHgyLXgxLCBkeSA9IE1hdGguYWJzKHkyLXkxKSwNCgl4ID0geDEsIHkgPSB5MSwNCgl5SW5jciA9ICh5MSA+IHkyKT8gLTEgOiAxLA0KCWRydyA9IHRydWU7DQoJaWYoZHggPj0gZHkpDQoJew0KCQl2YXIgcHIgPSBkeTw8MSwNCgkJcHJ1ID0gcHIgLSAoZHg8PDEpLA0KCQlwID0gcHItZHg7DQoJCXdoaWxlKGR4ID4gMCkNCgkJey0tZHg7DQoJCQlpZihkcncpIHRoaXMuX21rRGl2KHgsIHksIDEsIDEpOw0KCQkJZHJ3ID0gIWRydzsNCgkJCWlmKHAgPiAwKQ0KCQkJew0KCQkJCXkgKz0geUluY3I7DQoJCQkJcCArPSBwcnU7DQoJCQl9DQoJCQllbHNlIHAgKz0gcHI7DQoJCQkrK3g7DQoJCX0NCgl9DQoJZWxzZQ0KCXsNCgkJdmFyIHByID0gZHg8PDEsDQoJCXBydSA9IHByIC0gKGR5PDwxKSwNCgkJcCA9IHByLWR5Ow0KCQl3aGlsZShkeSA+IDApDQoJCXstLWR5Ow0KCQkJaWYoZHJ3KSB0aGlzLl9ta0Rpdih4LCB5LCAxLCAxKTsNCgkJCWRydyA9ICFkcnc7DQoJCQl5ICs9IHlJbmNyOw0KCQkJaWYocCA+IDApDQoJCQl7DQoJCQkJKyt4Ow0KCQkJCXAgKz0gcHJ1Ow0KCQkJfQ0KCQkJZWxzZSBwICs9IHByOw0KCQl9DQoJfQ0KCWlmKGRydykgdGhpcy5fbWtEaXYoeCwgeSwgMSwgMSk7DQp9DQoNCmZ1bmN0aW9uIF9ta092KGxlZnQsIHRvcCwgd2lkdGgsIGhlaWdodCkNCnsNCgl2YXIgYSA9ICgrK3dpZHRoKT4+MSwgYiA9ICgrK2hlaWdodCk+PjEsDQoJd29kID0gd2lkdGgmMSwgaG9kID0gaGVpZ2h0JjEsDQoJY3ggPSBsZWZ0K2EsIGN5ID0gdG9wK2IsDQoJeCA9IDAsIHkgPSBiLA0KCW94ID0gMCwgb3kgPSBiLA0KCWFhMiA9IChhKmEpPDwxLCBhYTQgPSBhYTI8PDEsIGJiMiA9IChiKmIpPDwxLCBiYjQgPSBiYjI8PDEsDQoJc3QgPSAoYWEyPj4xKSooMS0oYjw8MSkpICsgYmIyLA0KCXR0ID0gKGJiMj4+MSkgLSBhYTIqKChiPDwxKS0xKSwNCgl3LCBoOw0KCXdoaWxlKHkgPiAwKQ0KCXsNCgkJaWYoc3QgPCAwKQ0KCQl7DQoJCQlzdCArPSBiYjIqKCh4PDwxKSszKTsNCgkJCXR0ICs9IGJiNCooKyt4KTsNCgkJfQ0KCQllbHNlIGlmKHR0IDwgMCkNCgkJew0KCQkJc3QgKz0gYmIyKigoeDw8MSkrMykgLSBhYTQqKHktMSk7DQoJCQl0dCArPSBiYjQqKCsreCkgLSBhYTIqKCgoeS0tKTw8MSktMyk7DQoJCQl3ID0geC1veDsNCgkJCWggPSBveS15Ow0KCQkJaWYoKHcmMikgJiYgKGgmMikpDQoJCQl7DQoJCQkJdGhpcy5fbWtPdlFkcyhjeCwgY3ksIHgtMiwgeSsyLCAxLCAxLCB3b2QsIGhvZCk7DQoJCQkJdGhpcy5fbWtPdlFkcyhjeCwgY3ksIHgtMSwgeSsxLCAxLCAxLCB3b2QsIGhvZCk7DQoJCQl9DQoJCQllbHNlIHRoaXMuX21rT3ZRZHMoY3gsIGN5LCB4LTEsIG95LCB3LCBoLCB3b2QsIGhvZCk7DQoJCQlveCA9IHg7DQoJCQlveSA9IHk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQl0dCAtPSBhYTIqKCh5PDwxKS0zKTsNCgkJCXN0IC09IGFhNCooLS15KTsNCgkJfQ0KCX0NCgl3ID0gYS1veCsxOw0KCWggPSAob3k8PDEpK2hvZDsNCgl5ID0gY3ktb3k7DQoJdGhpcy5fbWtEaXYoY3gtYSwgeSwgdywgaCk7DQoJdGhpcy5fbWtEaXYoY3grb3grd29kLTEsIHksIHcsIGgpOw0KfQ0KDQpmdW5jdGlvbiBfbWtPdjJEKGxlZnQsIHRvcCwgd2lkdGgsIGhlaWdodCkNCnsNCgl2YXIgcyA9IHRoaXMuc3Ryb2tlOw0KCXdpZHRoICs9IHMrMTsNCgloZWlnaHQgKz0gcysxOw0KCXZhciBhID0gd2lkdGg+PjEsIGIgPSBoZWlnaHQ+PjEsDQoJd29kID0gd2lkdGgmMSwgaG9kID0gaGVpZ2h0JjEsDQoJY3ggPSBsZWZ0K2EsIGN5ID0gdG9wK2IsDQoJeCA9IDAsIHkgPSBiLA0KCWFhMiA9IChhKmEpPDwxLCBhYTQgPSBhYTI8PDEsIGJiMiA9IChiKmIpPDwxLCBiYjQgPSBiYjI8PDEsDQoJc3QgPSAoYWEyPj4xKSooMS0oYjw8MSkpICsgYmIyLA0KCXR0ID0gKGJiMj4+MSkgLSBhYTIqKChiPDwxKS0xKTsNCg0KCWlmKHMtNCA8IDAgJiYgKCEocy0yKSB8fCB3aWR0aC01MSA+IDAgJiYgaGVpZ2h0LTUxID4gMCkpDQoJew0KCQl2YXIgb3ggPSAwLCBveSA9IGIsDQoJCXcsIGgsDQoJCXB4dzsNCgkJd2hpbGUoeSA+IDApDQoJCXsNCgkJCWlmKHN0IDwgMCkNCgkJCXsNCgkJCQlzdCArPSBiYjIqKCh4PDwxKSszKTsNCgkJCQl0dCArPSBiYjQqKCsreCk7DQoJCQl9DQoJCQllbHNlIGlmKHR0IDwgMCkNCgkJCXsNCgkJCQlzdCArPSBiYjIqKCh4PDwxKSszKSAtIGFhNCooeS0xKTsNCgkJCQl0dCArPSBiYjQqKCsreCkgLSBhYTIqKCgoeS0tKTw8MSktMyk7DQoJCQkJdyA9IHgtb3g7DQoJCQkJaCA9IG95LXk7DQoNCgkJCQlpZih3LTEpDQoJCQkJew0KCQkJCQlweHcgPSB3KzErKHMmMSk7DQoJCQkJCWggPSBzOw0KCQkJCX0NCgkJCQllbHNlIGlmKGgtMSkNCgkJCQl7DQoJCQkJCXB4dyA9IHM7DQoJCQkJCWggKz0gMSsocyYxKTsNCgkJCQl9DQoJCQkJZWxzZSBweHcgPSBoID0gczsNCgkJCQl0aGlzLl9ta092UWRzKGN4LCBjeSwgeC0xLCBveSwgcHh3LCBoLCB3b2QsIGhvZCk7DQoJCQkJb3ggPSB4Ow0KCQkJCW95ID0geTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQl0dCAtPSBhYTIqKCh5PDwxKS0zKTsNCgkJCQlzdCAtPSBhYTQqKC0teSk7DQoJCQl9DQoJCX0NCgkJdGhpcy5fbWtEaXYoY3gtYSwgY3ktb3ksIHMsIChveTw8MSkraG9kKTsNCgkJdGhpcy5fbWtEaXYoY3grYSt3b2QtcywgY3ktb3ksIHMsIChveTw8MSkraG9kKTsNCgl9DQoNCgllbHNlDQoJew0KCQl2YXIgX2EgPSAod2lkdGgtKHM8PDEpKT4+MSwNCgkJX2IgPSAoaGVpZ2h0LShzPDwxKSk+PjEsDQoJCV94ID0gMCwgX3kgPSBfYiwNCgkJX2FhMiA9IChfYSpfYSk8PDEsIF9hYTQgPSBfYWEyPDwxLCBfYmIyID0gKF9iKl9iKTw8MSwgX2JiNCA9IF9iYjI8PDEsDQoJCV9zdCA9IChfYWEyPj4xKSooMS0oX2I8PDEpKSArIF9iYjIsDQoJCV90dCA9IChfYmIyPj4xKSAtIF9hYTIqKChfYjw8MSktMSksDQoNCgkJcHhsID0gbmV3IEFycmF5KCksDQoJCXB4dCA9IG5ldyBBcnJheSgpLA0KCQlfcHhiID0gbmV3IEFycmF5KCk7DQoJCXB4bFswXSA9IDA7DQoJCXB4dFswXSA9IGI7DQoJCV9weGJbMF0gPSBfYi0xOw0KCQl3aGlsZSh5ID4gMCkNCgkJew0KCQkJaWYoc3QgPCAwKQ0KCQkJew0KCQkJCXB4bFtweGwubGVuZ3RoXSA9IHg7DQoJCQkJcHh0W3B4dC5sZW5ndGhdID0geTsNCgkJCQlzdCArPSBiYjIqKCh4PDwxKSszKTsNCgkJCQl0dCArPSBiYjQqKCsreCk7DQoJCQl9DQoJCQllbHNlIGlmKHR0IDwgMCkNCgkJCXsNCgkJCQlweGxbcHhsLmxlbmd0aF0gPSB4Ow0KCQkJCXN0ICs9IGJiMiooKHg8PDEpKzMpIC0gYWE0Kih5LTEpOw0KCQkJCXR0ICs9IGJiNCooKyt4KSAtIGFhMiooKCh5LS0pPDwxKS0zKTsNCgkJCQlweHRbcHh0Lmxlbmd0aF0gPSB5Ow0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCXR0IC09IGFhMiooKHk8PDEpLTMpOw0KCQkJCXN0IC09IGFhNCooLS15KTsNCgkJCX0NCg0KCQkJaWYoX3kgPiAwKQ0KCQkJew0KCQkJCWlmKF9zdCA8IDApDQoJCQkJew0KCQkJCQlfc3QgKz0gX2JiMiooKF94PDwxKSszKTsNCgkJCQkJX3R0ICs9IF9iYjQqKCsrX3gpOw0KCQkJCQlfcHhiW19weGIubGVuZ3RoXSA9IF95LTE7DQoJCQkJfQ0KCQkJCWVsc2UgaWYoX3R0IDwgMCkNCgkJCQl7DQoJCQkJCV9zdCArPSBfYmIyKigoX3g8PDEpKzMpIC0gX2FhNCooX3ktMSk7DQoJCQkJCV90dCArPSBfYmI0KigrK194KSAtIF9hYTIqKCgoX3ktLSk8PDEpLTMpOw0KCQkJCQlfcHhiW19weGIubGVuZ3RoXSA9IF95LTE7DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCV90dCAtPSBfYWEyKigoX3k8PDEpLTMpOw0KCQkJCQlfc3QgLT0gX2FhNCooLS1feSk7DQoJCQkJCV9weGJbX3B4Yi5sZW5ndGgtMV0tLTsNCgkJCQl9DQoJCQl9DQoJCX0NCg0KCQl2YXIgb3ggPSAtd29kLCBveSA9IGIsDQoJCV9veSA9IF9weGJbMF0sDQoJCWwgPSBweGwubGVuZ3RoLA0KCQl3LCBoOw0KCQlmb3IodmFyIGkgPSAwOyBpIDwgbDsgaSsrKQ0KCQl7DQoJCQlpZih0eXBlb2YgX3B4YltpXSAhPSAidW5kZWZpbmVkIikNCgkJCXsNCgkJCQlpZihfcHhiW2ldIDwgX295IHx8IHB4dFtpXSA8IG95KQ0KCQkJCXsNCgkJCQkJeCA9IHB4bFtpXTsNCgkJCQkJdGhpcy5fbWtPdlFkcyhjeCwgY3ksIHgsIG95LCB4LW94LCBveS1fb3ksIHdvZCwgaG9kKTsNCgkJCQkJb3ggPSB4Ow0KCQkJCQlveSA9IHB4dFtpXTsNCgkJCQkJX295ID0gX3B4YltpXTsNCgkJCQl9DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJeCA9IHB4bFtpXTsNCgkJCQl0aGlzLl9ta0RpdihjeC14LCBjeS1veSwgMSwgKG95PDwxKStob2QpOw0KCQkJCXRoaXMuX21rRGl2KGN4K294K3dvZCwgY3ktb3ksIDEsIChveTw8MSkraG9kKTsNCgkJCQlveCA9IHg7DQoJCQkJb3kgPSBweHRbaV07DQoJCQl9DQoJCX0NCgkJdGhpcy5fbWtEaXYoY3gtYSwgY3ktb3ksIDEsIChveTw8MSkraG9kKTsNCgkJdGhpcy5fbWtEaXYoY3grb3grd29kLCBjeS1veSwgMSwgKG95PDwxKStob2QpOw0KCX0NCn0NCg0KZnVuY3Rpb24gX21rT3ZEb3R0KGxlZnQsIHRvcCwgd2lkdGgsIGhlaWdodCkNCnsNCgl2YXIgYSA9ICgrK3dpZHRoKT4+MSwgYiA9ICgrK2hlaWdodCk+PjEsDQoJd29kID0gd2lkdGgmMSwgaG9kID0gaGVpZ2h0JjEsIGhvZHUgPSBob2ReMSwNCgljeCA9IGxlZnQrYSwgY3kgPSB0b3ArYiwNCgl4ID0gMCwgeSA9IGIsDQoJYWEyID0gKGEqYSk8PDEsIGFhNCA9IGFhMjw8MSwgYmIyID0gKGIqYik8PDEsIGJiNCA9IGJiMjw8MSwNCglzdCA9IChhYTI+PjEpKigxLShiPDwxKSkgKyBiYjIsDQoJdHQgPSAoYmIyPj4xKSAtIGFhMiooKGI8PDEpLTEpLA0KCWRydyA9IHRydWU7DQoJd2hpbGUoeSA+IDApDQoJew0KCQlpZihzdCA8IDApDQoJCXsNCgkJCXN0ICs9IGJiMiooKHg8PDEpKzMpOw0KCQkJdHQgKz0gYmI0KigrK3gpOw0KCQl9DQoJCWVsc2UgaWYodHQgPCAwKQ0KCQl7DQoJCQlzdCArPSBiYjIqKCh4PDwxKSszKSAtIGFhNCooeS0xKTsNCgkJCXR0ICs9IGJiNCooKyt4KSAtIGFhMiooKCh5LS0pPDwxKS0zKTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXR0IC09IGFhMiooKHk8PDEpLTMpOw0KCQkJc3QgLT0gYWE0KigtLXkpOw0KCQl9DQoJCWlmKGRydyAmJiB5ID49IGhvZHUpIHRoaXMuX21rT3ZRZHMoY3gsIGN5LCB4LCB5LCAxLCAxLCB3b2QsIGhvZCk7DQoJCWRydyA9ICFkcnc7DQoJfQ0KfQ0KDQpmdW5jdGlvbiBfbWtSZWN0KHgsIHksIHcsIGgpDQp7DQoJdmFyIHMgPSB0aGlzLnN0cm9rZTsNCgl0aGlzLl9ta0Rpdih4LCB5LCB3LCBzKTsNCgl0aGlzLl9ta0Rpdih4K3csIHksIHMsIGgpOw0KCXRoaXMuX21rRGl2KHgsIHkraCwgdytzLCBzKTsNCgl0aGlzLl9ta0Rpdih4LCB5K3MsIHMsIGgtcyk7DQp9DQoNCmZ1bmN0aW9uIF9ta1JlY3REb3R0KHgsIHksIHcsIGgpDQp7DQoJdGhpcy5kcmF3TGluZSh4LCB5LCB4K3csIHkpOw0KCXRoaXMuZHJhd0xpbmUoeCt3LCB5LCB4K3csIHkraCk7DQoJdGhpcy5kcmF3TGluZSh4LCB5K2gsIHgrdywgeStoKTsNCgl0aGlzLmRyYXdMaW5lKHgsIHksIHgsIHkraCk7DQp9DQoNCmZ1bmN0aW9uIGpzZ0ZvbnQoKQ0Kew0KCXRoaXMuUExBSU4gPSAnZm9udC13ZWlnaHQ6bm9ybWFsOyc7DQoJdGhpcy5CT0xEID0gJ2ZvbnQtd2VpZ2h0OmJvbGQ7JzsNCgl0aGlzLklUQUxJQyA9ICdmb250LXN0eWxlOml0YWxpYzsnOw0KCXRoaXMuSVRBTElDX0JPTEQgPSB0aGlzLklUQUxJQyArIHRoaXMuQk9MRDsNCgl0aGlzLkJPTERfSVRBTElDID0gdGhpcy5JVEFMSUNfQk9MRDsNCn0NCnZhciBGb250ID0gbmV3IGpzZ0ZvbnQoKTsNCg0KZnVuY3Rpb24ganNnU3Ryb2tlKCkNCnsNCgl0aGlzLkRPVFRFRCA9IC0xOw0KfQ0KdmFyIFN0cm9rZSA9IG5ldyBqc2dTdHJva2UoKTsNCg0KZnVuY3Rpb24ganNHcmFwaGljcyhjbnYsIHduZCkNCnsNCgl0aGlzLnNldENvbG9yID0gZnVuY3Rpb24oeCkNCgl7DQoJCXRoaXMuY29sb3IgPSB4LnRvTG93ZXJDYXNlKCk7DQoJfTsNCg0KCXRoaXMuc2V0U3Ryb2tlID0gZnVuY3Rpb24oeCkNCgl7DQoJCXRoaXMuc3Ryb2tlID0geDsNCgkJaWYoISh4KzEpKQ0KCQl7DQoJCQl0aGlzLmRyYXdMaW5lID0gX21rTGluRG90dDsNCgkJCXRoaXMuX21rT3YgPSBfbWtPdkRvdHQ7DQoJCQl0aGlzLmRyYXdSZWN0ID0gX21rUmVjdERvdHQ7DQoJCX0NCgkJZWxzZSBpZih4LTEgPiAwKQ0KCQl7DQoJCQl0aGlzLmRyYXdMaW5lID0gX21rTGluMkQ7DQoJCQl0aGlzLl9ta092ID0gX21rT3YyRDsNCgkJCXRoaXMuZHJhd1JlY3QgPSBfbWtSZWN0Ow0KCQl9DQoJCWVsc2UNCgkJew0KCQkJdGhpcy5kcmF3TGluZSA9IF9ta0xpbjsNCgkJCXRoaXMuX21rT3YgPSBfbWtPdjsNCgkJCXRoaXMuZHJhd1JlY3QgPSBfbWtSZWN0Ow0KCQl9DQoJfTsNCg0KCXRoaXMuc2V0UHJpbnRhYmxlID0gZnVuY3Rpb24oYXJnKQ0KCXsNCgkJdGhpcy5wcmludGFibGUgPSBhcmc7DQoJCWlmKGpnX2Zhc3QpDQoJCXsNCgkJCXRoaXMuX21rRGl2ID0gX21rRGl2SWU7DQoJCQl0aGlzLl9odG1ScGMgPSBhcmc/IF9odG1QcnRScGMgOiBfaHRtUnBjOw0KCQl9DQoJCWVsc2UgdGhpcy5fbWtEaXYgPSBhcmc/IF9ta0RpdlBydCA6IF9ta0RpdjsNCgl9Ow0KDQoJdGhpcy5zZXRGb250ID0gZnVuY3Rpb24oZmFtLCBzeiwgc3R5KQ0KCXsNCgkJdGhpcy5mdEZhbSA9IGZhbTsNCgkJdGhpcy5mdFN6ID0gc3o7DQoJCXRoaXMuZnRTdHkgPSBzdHkgfHwgRm9udC5QTEFJTjsNCgl9Ow0KDQoJdGhpcy5kcmF3UG9seWxpbmUgPSB0aGlzLmRyYXdQb2x5TGluZSA9IGZ1bmN0aW9uKHgsIHkpDQoJew0KCQlmb3IgKHZhciBpPXgubGVuZ3RoIC0gMTsgaTspDQoJCXstLWk7DQoJCQl0aGlzLmRyYXdMaW5lKHhbaV0sIHlbaV0sIHhbaSsxXSwgeVtpKzFdKTsNCgkJfQ0KCX07DQoNCgl0aGlzLmZpbGxSZWN0ID0gZnVuY3Rpb24oeCwgeSwgdywgaCkNCgl7DQoJCXRoaXMuX21rRGl2KHgsIHksIHcsIGgpOw0KCX07DQoNCgl0aGlzLmRyYXdQb2x5Z29uID0gZnVuY3Rpb24oeCwgeSkNCgl7DQoJCXRoaXMuZHJhd1BvbHlsaW5lKHgsIHkpOw0KCQl0aGlzLmRyYXdMaW5lKHhbeC5sZW5ndGgtMV0sIHlbeC5sZW5ndGgtMV0sIHhbMF0sIHlbMF0pOw0KCX07DQoNCgl0aGlzLmRyYXdFbGxpcHNlID0gdGhpcy5kcmF3T3ZhbCA9IGZ1bmN0aW9uKHgsIHksIHcsIGgpDQoJew0KCQl0aGlzLl9ta092KHgsIHksIHcsIGgpOw0KCX07DQoNCgl0aGlzLmZpbGxFbGxpcHNlID0gdGhpcy5maWxsT3ZhbCA9IGZ1bmN0aW9uKGxlZnQsIHRvcCwgdywgaCkNCgl7DQoJCXZhciBhID0gdz4+MSwgYiA9IGg+PjEsDQoJCXdvZCA9IHcmMSwgaG9kID0gaCYxLA0KCQljeCA9IGxlZnQrYSwgY3kgPSB0b3ArYiwNCgkJeCA9IDAsIHkgPSBiLCBveSA9IGIsDQoJCWFhMiA9IChhKmEpPDwxLCBhYTQgPSBhYTI8PDEsIGJiMiA9IChiKmIpPDwxLCBiYjQgPSBiYjI8PDEsDQoJCXN0ID0gKGFhMj4+MSkqKDEtKGI8PDEpKSArIGJiMiwNCgkJdHQgPSAoYmIyPj4xKSAtIGFhMiooKGI8PDEpLTEpLA0KCQl4bCwgZHcsIGRoOw0KCQlpZih3KSB3aGlsZSh5ID4gMCkNCgkJew0KCQkJaWYoc3QgPCAwKQ0KCQkJew0KCQkJCXN0ICs9IGJiMiooKHg8PDEpKzMpOw0KCQkJCXR0ICs9IGJiNCooKyt4KTsNCgkJCX0NCgkJCWVsc2UgaWYodHQgPCAwKQ0KCQkJew0KCQkJCXN0ICs9IGJiMiooKHg8PDEpKzMpIC0gYWE0Kih5LTEpOw0KCQkJCXhsID0gY3gteDsNCgkJCQlkdyA9ICh4PDwxKSt3b2Q7DQoJCQkJdHQgKz0gYmI0KigrK3gpIC0gYWEyKigoKHktLSk8PDEpLTMpOw0KCQkJCWRoID0gb3kteTsNCgkJCQl0aGlzLl9ta0Rpdih4bCwgY3ktb3ksIGR3LCBkaCk7DQoJCQkJdGhpcy5fbWtEaXYoeGwsIGN5K3kraG9kLCBkdywgZGgpOw0KCQkJCW95ID0geTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQl0dCAtPSBhYTIqKCh5PDwxKS0zKTsNCgkJCQlzdCAtPSBhYTQqKC0teSk7DQoJCQl9DQoJCX0NCgkJdGhpcy5fbWtEaXYoY3gtYSwgY3ktb3ksIHcsIChveTw8MSkraG9kKTsNCgl9Ow0KDQoJdGhpcy5maWxsQXJjID0gZnVuY3Rpb24oaUwsIGlULCBpVywgaUgsIGZBbmdBLCBmQW5nWikNCgl7DQoJCXZhciBhID0gaVc+PjEsIGIgPSBpSD4+MSwNCgkJaU9kZHMgPSAoaVcmMSkgfCAoKGlIJjEpIDw8IDE2KSwNCgkJY3ggPSBpTCthLCBjeSA9IGlUK2IsDQoJCXggPSAwLCB5ID0gYiwgb3ggPSB4LCBveSA9IHksDQoJCWFhMiA9IChhKmEpPDwxLCBhYTQgPSBhYTI8PDEsIGJiMiA9IChiKmIpPDwxLCBiYjQgPSBiYjI8PDEsDQoJCXN0ID0gKGFhMj4+MSkqKDEtKGI8PDEpKSArIGJiMiwNCgkJdHQgPSAoYmIyPj4xKSAtIGFhMiooKGI8PDEpLTEpLA0KCQkvLyBWYXJzIGZvciByYWRpYWwgYm91bmRhcnkgbGluZXMNCgkJeEVuZEEsIHlFbmRBLCB4RW5kWiwgeUVuZFosDQoJCWlTZWN0cyA9ICgxIDw8IChNYXRoLmZsb29yKChmQW5nQSAlPSAzNjAuMCkvMTgwLjApIDw8IDMpKQ0KCQkJCXwgKDIgPDwgKE1hdGguZmxvb3IoKGZBbmdaICU9IDM2MC4wKS8xODAuMCkgPDwgMykpDQoJCQkJfCAoKGZBbmdBID49IGZBbmdaKSA8PCAxNiksDQoJCWFCbmRBID0gbmV3IEFycmF5KGIrMSksIGFCbmRaID0gbmV3IEFycmF5KGIrMSk7DQoJCQ0KCQkvLyBTZXQgdXAgcmFkaWFsIGJvdW5kYXJ5IGxpbmVzDQoJCWZBbmdBICo9IE1hdGguUEkvMTgwLjA7DQoJCWZBbmdaICo9IE1hdGguUEkvMTgwLjA7DQoJCXhFbmRBID0gY3grTWF0aC5yb3VuZChhKk1hdGguY29zKGZBbmdBKSk7DQoJCXlFbmRBID0gY3krTWF0aC5yb3VuZCgtYipNYXRoLnNpbihmQW5nQSkpOw0KCQlfbWtMaW5WaXJ0KGFCbmRBLCBjeCwgY3ksIHhFbmRBLCB5RW5kQSk7DQoJCXhFbmRaID0gY3grTWF0aC5yb3VuZChhKk1hdGguY29zKGZBbmdaKSk7DQoJCXlFbmRaID0gY3krTWF0aC5yb3VuZCgtYipNYXRoLnNpbihmQW5nWikpOw0KCQlfbWtMaW5WaXJ0KGFCbmRaLCBjeCwgY3ksIHhFbmRaLCB5RW5kWik7DQoNCgkJd2hpbGUoeSA+IDApDQoJCXsNCgkJCWlmKHN0IDwgMCkgLy8gQWR2YW5jZSB4DQoJCQl7DQoJCQkJc3QgKz0gYmIyKigoeDw8MSkrMyk7DQoJCQkJdHQgKz0gYmI0KigrK3gpOw0KCQkJfQ0KCQkJZWxzZSBpZih0dCA8IDApIC8vIEFkdmFuY2UgeCBhbmQgeQ0KCQkJew0KCQkJCXN0ICs9IGJiMiooKHg8PDEpKzMpIC0gYWE0Kih5LTEpOw0KCQkJCW94ID0geDsNCgkJCQl0dCArPSBiYjQqKCsreCkgLSBhYTIqKCgoeS0tKTw8MSktMyk7DQoJCQkJdGhpcy5fbWtBcmNEaXYob3gsIHksIG95LCBjeCwgY3ksIGlPZGRzLCBhQm5kQSwgYUJuZFosIGlTZWN0cyk7DQoJCQkJb3kgPSB5Ow0KCQkJfQ0KCQkJZWxzZSAvLyBBZHZhbmNlIHkNCgkJCXsNCgkJCQl0dCAtPSBhYTIqKCh5PDwxKS0zKTsNCgkJCQlzdCAtPSBhYTQqKC0teSk7DQoJCQkJaWYoeSAmJiAoYUJuZEFbeV0gIT0gYUJuZEFbeS0xXSB8fCBhQm5kWlt5XSAhPSBhQm5kWlt5LTFdKSkNCgkJCQl7DQoJCQkJCXRoaXMuX21rQXJjRGl2KHgsIHksIG95LCBjeCwgY3ksIGlPZGRzLCBhQm5kQSwgYUJuZFosIGlTZWN0cyk7DQoJCQkJCW94ID0geDsNCgkJCQkJb3kgPSB5Ow0KCQkJCX0NCgkJCX0NCgkJfQ0KCQl0aGlzLl9ta0FyY0Rpdih4LCAwLCBveSwgY3gsIGN5LCBpT2RkcywgYUJuZEEsIGFCbmRaLCBpU2VjdHMpOw0KCQlpZihpT2RkcyA+PiAxNikgLy8gT2RkIGhlaWdodA0KCQl7DQoJCQlpZihpU2VjdHMgPj4gMTYpIC8vIFN0YXJ0LWFuZ2xlID4gZW5kLWFuZ2xlDQoJCQl7DQoJCQkJdmFyIHhsID0gKHlFbmRBIDw9IGN5IHx8IHlFbmRaID4gY3kpPyAoY3ggLSB4KSA6IGN4Ow0KCQkJCXRoaXMuX21rRGl2KHhsLCBjeSwgeCArIGN4IC0geGwgKyAoaU9kZHMgJiAweGZmZmYpLCAxKTsNCgkJCX0NCgkJCWVsc2UgaWYoKGlTZWN0cyAmIDB4MDEpICYmIHlFbmRaID4gY3kpDQoJCQkJdGhpcy5fbWtEaXYoY3ggLSB4LCBjeSwgeCwgMSk7DQoJCX0NCgl9Ow0KDQovKiBmaWxsUG9seWdvbiBtZXRob2QsIGltcGxlbWVudGVkIGJ5IE1hdHRoaWV1IEhhbGxlci4NClRoaXMgamF2YXNjcmlwdCBmdW5jdGlvbiBpcyBhbiBhZGFwdGF0aW9uIG9mIHRoZSBnZEltYWdlRmlsbGVkUG9seWdvbiBmb3IgV2FsdGVyIFpvcm4gbGliLg0KQyBzb3VyY2Ugb2YgR0QgMS44LjQgZm91bmQgYXQgaHR0cDovL3d3dy5ib3V0ZWxsLmNvbS9nZC8NCg0KVEhBTktTIHRvIEtpcnN0ZW4gU2NodWx6IGZvciB0aGUgcG9seWdvbiBmaXhlcyENCg0KVGhlIGludGVyc2VjdGlvbiBmaW5kaW5nIHRlY2huaXF1ZSBvZiB0aGlzIGNvZGUgY291bGQgYmUgaW1wcm92ZWQNCmJ5IHJlbWVtYmVyaW5nIHRoZSBwcmV2aW91cyBpbnRlcnRlcnNlY3Rpb24sIGFuZCBieSB1c2luZyB0aGUgc2xvcGUuDQpUaGF0IGNvdWxkIGhlbHAgdG8gYWRqdXN0IGludGVyc2VjdGlvbnMgdG8gcHJvZHVjZSBhIG5pY2UNCmludGVyaW9yX2V4dHJlbWEuICovDQoJdGhpcy5maWxsUG9seWdvbiA9IGZ1bmN0aW9uKGFycmF5X3gsIGFycmF5X3kpDQoJew0KCQl2YXIgaTsNCgkJdmFyIHk7DQoJCXZhciBtaW55LCBtYXh5Ow0KCQl2YXIgeDEsIHkxOw0KCQl2YXIgeDIsIHkyOw0KCQl2YXIgaW5kMSwgaW5kMjsNCgkJdmFyIGludHM7DQoNCgkJdmFyIG4gPSBhcnJheV94Lmxlbmd0aDsNCgkJaWYoIW4pIHJldHVybjsNCg0KCQltaW55ID0gYXJyYXlfeVswXTsNCgkJbWF4eSA9IGFycmF5X3lbMF07DQoJCWZvcihpID0gMTsgaSA8IG47IGkrKykNCgkJew0KCQkJaWYoYXJyYXlfeVtpXSA8IG1pbnkpDQoJCQkJbWlueSA9IGFycmF5X3lbaV07DQoNCgkJCWlmKGFycmF5X3lbaV0gPiBtYXh5KQ0KCQkJCW1heHkgPSBhcnJheV95W2ldOw0KCQl9DQoJCWZvcih5ID0gbWlueTsgeSA8PSBtYXh5OyB5KyspDQoJCXsNCgkJCXZhciBwb2x5SW50cyA9IG5ldyBBcnJheSgpOw0KCQkJaW50cyA9IDA7DQoJCQlmb3IoaSA9IDA7IGkgPCBuOyBpKyspDQoJCQl7DQoJCQkJaWYoIWkpDQoJCQkJew0KCQkJCQlpbmQxID0gbi0xOw0KCQkJCQlpbmQyID0gMDsNCgkJCQl9DQoJCQkJZWxzZQ0KCQkJCXsNCgkJCQkJaW5kMSA9IGktMTsNCgkJCQkJaW5kMiA9IGk7DQoJCQkJfQ0KCQkJCXkxID0gYXJyYXlfeVtpbmQxXTsNCgkJCQl5MiA9IGFycmF5X3lbaW5kMl07DQoJCQkJaWYoeTEgPCB5MikNCgkJCQl7DQoJCQkJCXgxID0gYXJyYXlfeFtpbmQxXTsNCgkJCQkJeDIgPSBhcnJheV94W2luZDJdOw0KCQkJCX0NCgkJCQllbHNlIGlmKHkxID4geTIpDQoJCQkJew0KCQkJCQl5MiA9IGFycmF5X3lbaW5kMV07DQoJCQkJCXkxID0gYXJyYXlfeVtpbmQyXTsNCgkJCQkJeDIgPSBhcnJheV94W2luZDFdOw0KCQkJCQl4MSA9IGFycmF5X3hbaW5kMl07DQoJCQkJfQ0KCQkJCWVsc2UgY29udGludWU7DQoNCgkJCQkgLy8gIE1vZGlmaWVkIDExLiAyLiAyMDA0IFdhbHRlciBab3JuDQoJCQkJaWYoKHkgPj0geTEpICYmICh5IDwgeTIpKQ0KCQkJCQlwb2x5SW50c1tpbnRzKytdID0gTWF0aC5yb3VuZCgoeS15MSkgKiAoeDIteDEpIC8gKHkyLXkxKSArIHgxKTsNCg0KCQkJCWVsc2UgaWYoKHkgPT0gbWF4eSkgJiYgKHkgPiB5MSkgJiYgKHkgPD0geTIpKQ0KCQkJCQlwb2x5SW50c1tpbnRzKytdID0gTWF0aC5yb3VuZCgoeS15MSkgKiAoeDIteDEpIC8gKHkyLXkxKSArIHgxKTsNCgkJCX0NCgkJCXBvbHlJbnRzLnNvcnQoX0NvbXBJbnQpOw0KCQkJZm9yKGkgPSAwOyBpIDwgaW50czsgaSs9MikNCgkJCQl0aGlzLl9ta0Rpdihwb2x5SW50c1tpXSwgeSwgcG9seUludHNbaSsxXS1wb2x5SW50c1tpXSsxLCAxKTsNCgkJfQ0KCX07DQoNCgl0aGlzLmRyYXdTdHJpbmcgPSBmdW5jdGlvbih0eHQsIHgsIHkpDQoJew0KCQl0aGlzLmh0bSArPSAnPGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7d2hpdGUtc3BhY2U6bm93cmFwOycrDQoJCQknbGVmdDonICsgeCArICdweDsnKw0KCQkJJ3RvcDonICsgeSArICdweDsnKw0KCQkJJ2ZvbnQtZmFtaWx5OicgKyAgdGhpcy5mdEZhbSArICc7JysNCgkJCSdmb250LXNpemU6JyArIHRoaXMuZnRTeiArICc7JysNCgkJCSdjb2xvcjonICsgdGhpcy5jb2xvciArICc7JyArIHRoaXMuZnRTdHkgKyAnIj4nKw0KCQkJdHh0ICsNCgkJCSc8XC9kaXY+JzsNCgl9Ow0KDQovKiBkcmF3U3RyaW5nUmVjdCgpIGFkZGVkIGJ5IFJpY2sgQmxvbW1lcnMuDQpBbGxvd3MgdG8gc3BlY2lmeSB0aGUgc2l6ZSBvZiB0aGUgdGV4dCByZWN0YW5nbGUgYW5kIHRvIGFsaWduIHRoZQ0KdGV4dCBib3RoIGhvcml6b250YWxseSAoZS5nLiByaWdodCkgYW5kIHZlcnRpY2FsbHkgd2l0aGluIHRoYXQgcmVjdGFuZ2xlICovDQoJdGhpcy5kcmF3U3RyaW5nUmVjdCA9IGZ1bmN0aW9uKHR4dCwgeCwgeSwgd2lkdGgsIGhhbGlnbikNCgl7DQoJCXRoaXMuaHRtICs9ICc8ZGl2IHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTtvdmVyZmxvdzpoaWRkZW47JysNCgkJCSdsZWZ0OicgKyB4ICsgJ3B4OycrDQoJCQkndG9wOicgKyB5ICsgJ3B4OycrDQoJCQknd2lkdGg6Jyt3aWR0aCArJ3B4OycrDQoJCQkndGV4dC1hbGlnbjonK2hhbGlnbisnOycrDQoJCQknZm9udC1mYW1pbHk6JyArICB0aGlzLmZ0RmFtICsgJzsnKw0KCQkJJ2ZvbnQtc2l6ZTonICsgdGhpcy5mdFN6ICsgJzsnKw0KCQkJJ2NvbG9yOicgKyB0aGlzLmNvbG9yICsgJzsnICsgdGhpcy5mdFN0eSArICciPicrDQoJCQl0eHQgKw0KCQkJJzxcL2Rpdj4nOw0KCX07DQoNCgl0aGlzLmRyYXdJbWFnZSA9IGZ1bmN0aW9uKGltZ1NyYywgeCwgeSwgdywgaCwgYSkNCgl7DQoJCXRoaXMuaHRtICs9ICc8ZGl2IHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTsnKw0KCQkJJ2xlZnQ6JyArIHggKyAncHg7JysNCgkJCSd0b3A6JyArIHkgKyAncHg7JysNCgkJCS8vIHcgKHdpZHRoKSBhbmQgaCAoaGVpZ2h0KSBhcmd1bWVudHMgYXJlIG5vdyBvcHRpb25hbC4NCgkJCS8vIEFkZGVkIGJ5IE1haG11dCBLZXlndWJhdGxpLCAxNC4xLjIwMDgNCgkJCSh3PyAoJ3dpZHRoOicgKyAgdyArICdweDsnKSA6ICcnKSArDQoJCQkoaD8gKCdoZWlnaHQ6JyArIGggKyAncHg7Jyk6JycpKyciPicrDQoJCQknPGltZyBzcmM9IicgKyBpbWdTcmMgKyciJysgKHcgPyAoJyB3aWR0aD0iJyArIHcgKyAnIicpOicnKSsgKGggPyAoJyBoZWlnaHQ9IicgKyBoICsgJyInKTonJykgKyAoYT8gKCcgJythKSA6ICcnKSArICc+JysNCgkJCSc8XC9kaXY+JzsNCgl9Ow0KDQoJdGhpcy5jbGVhciA9IGZ1bmN0aW9uKCkNCgl7DQoJCXRoaXMuaHRtID0gIiI7DQoJCWlmKHRoaXMuY252KSB0aGlzLmNudi5pbm5lckhUTUwgPSAiIjsNCgl9Ow0KDQoJdGhpcy5fbWtPdlFkcyA9IGZ1bmN0aW9uKGN4LCBjeSwgeCwgeSwgdywgaCwgd29kLCBob2QpDQoJew0KCQl2YXIgeGwgPSBjeCAtIHgsIHhyID0gY3ggKyB4ICsgd29kIC0gdywgeXQgPSBjeSAtIHksIHliID0gY3kgKyB5ICsgaG9kIC0gaDsNCgkJaWYoeHIgPiB4bCt3KQ0KCQl7DQoJCQl0aGlzLl9ta0Rpdih4ciwgeXQsIHcsIGgpOw0KCQkJdGhpcy5fbWtEaXYoeHIsIHliLCB3LCBoKTsNCgkJfQ0KCQllbHNlDQoJCQl3ID0geHIgLSB4bCArIHc7DQoJCXRoaXMuX21rRGl2KHhsLCB5dCwgdywgaCk7DQoJCXRoaXMuX21rRGl2KHhsLCB5YiwgdywgaCk7DQoJfTsNCgkNCgl0aGlzLl9ta0FyY0RpdiA9IGZ1bmN0aW9uKHgsIHksIG95LCBjeCwgY3ksIGlPZGRzLCBhQm5kQSwgYUJuZFosIGlTZWN0cykNCgl7DQoJCXZhciB4ckRlZiA9IGN4ICsgeCArIChpT2RkcyAmIDB4ZmZmZiksIHkyLCBoID0gb3kgLSB5LCB4bCwgeHIsIHc7DQoNCgkJaWYoIWgpIGggPSAxOw0KCQl4ID0gY3ggLSB4Ow0KDQoJCWlmKGlTZWN0cyAmIDB4ZmYwMDAwKSAvLyBTdGFydC1hbmdsZSA+IGVuZC1hbmdsZQ0KCQl7DQoJCQl5MiA9IGN5IC0geSAtIGg7DQoJCQlpZihpU2VjdHMgJiAweDAwZmYpDQoJCQl7DQoJCQkJaWYoaVNlY3RzICYgMHgwMikNCgkJCQl7DQoJCQkJCXhsID0gTWF0aC5tYXgoeCwgYUJuZFpbeV0pOw0KCQkJCQl3ID0geHJEZWYgLSB4bDsNCgkJCQkJaWYodyA+IDApIHRoaXMuX21rRGl2KHhsLCB5MiwgdywgaCk7DQoJCQkJfQ0KCQkJCWlmKGlTZWN0cyAmIDB4MDEpDQoJCQkJew0KCQkJCQl4ciA9IE1hdGgubWluKHhyRGVmLCBhQm5kQVt5XSk7DQoJCQkJCXcgPSB4ciAtIHg7DQoJCQkJCWlmKHcgPiAwKSB0aGlzLl9ta0Rpdih4LCB5MiwgdywgaCk7DQoJCQkJfQ0KCQkJfQ0KCQkJZWxzZQ0KCQkJCXRoaXMuX21rRGl2KHgsIHkyLCB4ckRlZiAtIHgsIGgpOw0KCQkJeTIgPSBjeSArIHkgKyAoaU9kZHMgPj4gMTYpOw0KCQkJaWYoaVNlY3RzICYgMHhmZjAwKQ0KCQkJew0KCQkJCWlmKGlTZWN0cyAmIDB4MDEwMCkNCgkJCQl7DQoJCQkJCXhsID0gTWF0aC5tYXgoeCwgYUJuZEFbeV0pOw0KCQkJCQl3ID0geHJEZWYgLSB4bDsNCgkJCQkJaWYodyA+IDApIHRoaXMuX21rRGl2KHhsLCB5MiwgdywgaCk7DQoJCQkJfQ0KCQkJCWlmKGlTZWN0cyAmIDB4MDIwMCkNCgkJCQl7DQoJCQkJCXhyID0gTWF0aC5taW4oeHJEZWYsIGFCbmRaW3ldKTsNCgkJCQkJdyA9IHhyIC0geDsNCgkJCQkJaWYodyA+IDApIHRoaXMuX21rRGl2KHgsIHkyLCB3LCBoKTsNCgkJCQl9DQoJCQl9DQoJCQllbHNlDQoJCQkJdGhpcy5fbWtEaXYoeCwgeTIsIHhyRGVmIC0geCwgaCk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlpZihpU2VjdHMgJiAweDAwZmYpDQoJCQl7DQoJCQkJaWYoaVNlY3RzICYgMHgwMikNCgkJCQkJeGwgPSBNYXRoLm1heCh4LCBhQm5kWlt5XSk7DQoJCQkJZWxzZQ0KCQkJCQl4bCA9IHg7DQoJCQkJaWYoaVNlY3RzICYgMHgwMSkNCgkJCQkJeHIgPSBNYXRoLm1pbih4ckRlZiwgYUJuZEFbeV0pOw0KCQkJCWVsc2UNCgkJCQkJeHIgPSB4ckRlZjsNCgkJCQl5MiA9IGN5IC0geSAtIGg7DQoJCQkJdyA9IHhyIC0geGw7DQoJCQkJaWYodyA+IDApIHRoaXMuX21rRGl2KHhsLCB5MiwgdywgaCk7DQoJCQl9DQoJCQlpZihpU2VjdHMgJiAweGZmMDApDQoJCQl7DQoJCQkJaWYoaVNlY3RzICYgMHgwMTAwKQ0KCQkJCQl4bCA9IE1hdGgubWF4KHgsIGFCbmRBW3ldKTsNCgkJCQllbHNlDQoJCQkJCXhsID0geDsNCgkJCQlpZihpU2VjdHMgJiAweDAyMDApDQoJCQkJCXhyID0gTWF0aC5taW4oeHJEZWYsIGFCbmRaW3ldKTsNCgkJCQllbHNlDQoJCQkJCXhyID0geHJEZWY7DQoJCQkJeTIgPSBjeSArIHkgKyAoaU9kZHMgPj4gMTYpOw0KCQkJCXcgPSB4ciAtIHhsOw0KCQkJCWlmKHcgPiAwKSB0aGlzLl9ta0Rpdih4bCwgeTIsIHcsIGgpOw0KCQkJfQ0KCQl9DQoJfTsNCg0KCXRoaXMuc2V0U3Ryb2tlKDEpOw0KCXRoaXMuc2V0Rm9udCgidmVyZGFuYSxnZW5ldmEsaGVsdmV0aWNhLHNhbnMtc2VyaWYiLCAiMTJweCIsIEZvbnQuUExBSU4pOw0KCXRoaXMuY29sb3IgPSAiIzAwMDAwMCI7DQoJdGhpcy5odG0gPSAiIjsNCgl0aGlzLnduZCA9IHduZCB8fCB3aW5kb3c7DQoNCglpZighamdfb2spIF9jaGtESFRNKHRoaXMud25kKTsNCglpZihqZ19vaykNCgl7DQoJCWlmKGNudikNCgkJew0KCQkJaWYodHlwZW9mKGNudikgPT0gInN0cmluZyIpDQoJCQkJdGhpcy5jb250ID0gZG9jdW1lbnQuYWxsPyAodGhpcy53bmQuZG9jdW1lbnQuYWxsW2Nudl0gfHwgbnVsbCkNCgkJCQkJOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZD8gKHRoaXMud25kLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNudikgfHwgbnVsbCkNCgkJCQkJOiBudWxsOw0KCQkJZWxzZSBpZihjbnYgPT0gd2luZG93LmRvY3VtZW50KQ0KCQkJCXRoaXMuY29udCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IilbMF07DQoJCQkvLyBJZiBjbnYgaXMgYSBkaXJlY3QgcmVmZXJlbmNlIHRvIGEgY2FudmFzIERPTSBub2RlDQoJCQkvLyAob3B0aW9uIHN1Z2dlc3RlZCBieSBBbmRyZWFzIEx1bGVpY2gpDQoJCQllbHNlIHRoaXMuY29udCA9IGNudjsNCgkJCS8vIENyZWF0ZSBuZXcgY2FudmFzIGluc2lkZSBjb250YWluZXIgRElWLiBUaHVzIHRoZSBkcmF3aW5nIGFuZCBjbGVhcmluZw0KCQkJLy8gbWV0aG9kcyB3b24ndCBpbnRlcmZlcmUgd2l0aCB0aGUgY29udGFpbmVyJ3MgaW5uZXIgaHRtbC4NCgkJCS8vIFNvbHV0aW9uIHN1Z2dlc3RlZCBieSBWbGFkaW1pci4NCgkJCXRoaXMuY252ID0gdGhpcy53bmQuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7DQoJCQl0aGlzLmNudi5zdHlsZS5mb250U2l6ZT0wOw0KCQkJdGhpcy5jb250LmFwcGVuZENoaWxkKHRoaXMuY252KTsNCgkJCXRoaXMucGFpbnQgPSBqZ19kb20/IF9wbnRDbnZEb20gOiBfcG50Q252SWU7DQoJCX0NCgkJZWxzZQ0KCQkJdGhpcy5wYWludCA9IF9wbnREb2M7DQoJfQ0KCWVsc2UNCgkJdGhpcy5wYWludCA9IF9wbnROOw0KDQoJdGhpcy5zZXRQcmludGFibGUoZmFsc2UpOw0KfQ0KDQpmdW5jdGlvbiBfbWtMaW5WaXJ0KGFMaW4sIHgxLCB5MSwgeDIsIHkyKQ0Kew0KCXZhciBkeCA9IE1hdGguYWJzKHgyLXgxKSwgZHkgPSBNYXRoLmFicyh5Mi15MSksDQoJeCA9IHgxLCB5ID0geTEsDQoJeEluY3IgPSAoeDEgPiB4Mik/IC0xIDogMSwNCgl5SW5jciA9ICh5MSA+IHkyKT8gLTEgOiAxLA0KCXAsDQoJaSA9IDA7DQoJaWYoZHggPj0gZHkpDQoJew0KCQl2YXIgcHIgPSBkeTw8MSwNCgkJcHJ1ID0gcHIgLSAoZHg8PDEpOw0KCQlwID0gcHItZHg7DQoJCXdoaWxlKGR4ID4gMCkNCgkJey0tZHg7DQoJCQlpZihwID4gMCkgICAgLy8gIEluY3JlbWVudCB5DQoJCQl7DQoJCQkJYUxpbltpKytdID0geDsNCgkJCQl5ICs9IHlJbmNyOw0KCQkJCXAgKz0gcHJ1Ow0KCQkJfQ0KCQkJZWxzZSBwICs9IHByOw0KCQkJeCArPSB4SW5jcjsNCgkJfQ0KCX0NCgllbHNlDQoJew0KCQl2YXIgcHIgPSBkeDw8MSwNCgkJcHJ1ID0gcHIgLSAoZHk8PDEpOw0KCQlwID0gcHItZHk7DQoJCXdoaWxlKGR5ID4gMCkNCgkJey0tZHk7DQoJCQl5ICs9IHlJbmNyOw0KCQkJYUxpbltpKytdID0geDsNCgkJCWlmKHAgPiAwKSAgICAvLyAgSW5jcmVtZW50IHgNCgkJCXsNCgkJCQl4ICs9IHhJbmNyOw0KCQkJCXAgKz0gcHJ1Ow0KCQkJfQ0KCQkJZWxzZSBwICs9IHByOw0KCQl9DQoJfQ0KCWZvcih2YXIgbGVuID0gYUxpbi5sZW5ndGgsIGkgPSBsZW4taTsgaTspDQoJCWFMaW5bbGVuLShpLS0pXSA9IHg7DQp9Ow0KDQpmdW5jdGlvbiBfQ29tcEludCh4LCB5KQ0Kew0KCXJldHVybih4IC0geSk7DQp9DQoNCg=='></script>
WZ;
	return($wz);
	}
//


koh5_pano



Your browser does not support the HTML5 canvas element.


Drag mouse to navigate.

Navigation





17.Aug.2010, Martin Wengenmayer