<?php 
/********** Generating sorted structure (array / SplMaxHeap): *************/ 
 
function  generateSorted( $start  =  300000 ,  $elementsNum  =  10000 ,  $dev  =  30 ,  $heap  =  false ) { 
	$sorted  =  $heap  ? 
new  SplMaxHeap
( )  :  array ( ) ;  	for ( $i  =  1 ;  $i  <=  $elementsNum ;  $i ++ ) { 
		$start  -=  $rand ; 
		if ( ! $heap ) { 
			$sorted [ ]  =  $start ; 
		} else { 
			$sorted -> insert ( $start ) ;  
		} 
	} 
	return  $sorted ; 
} 
 
/********************** Four insert functions: **************************/ 
 
// for loop, and array copying 
function  insert1( & $arr ,  $elem ) { 
		$arr [ ]  =  $elem ; 
		return  true ; 
	} 
	$lastIndex  =  $c  -  1 ; 
	$inserted  =  false ; 
	for ( $i  =  0 ;  $i  <  $c ;  $i ++ ) { 
		if ( ! $inserted  &&  $arr [ $i ]  <=  $elem ) { 
			$tmp [ ]  =  $elem ; 
			$inserted  =  true ; 
		} 
		$tmp [ ]  =  $arr [ $i ] ; 
		if ( $lastIndex  ==  $i  &&  ! $inserted )  $tmp [ ]  =  $elem ; 
	} 
	$arr  =  $tmp ; 
	return  true ; 
} 
 
// new element inserted at the end of array  
// and moved up until correct place 
function  insert2( & $arr ,  $elem ) { 
	for ( $i  =  $c ;  $i  >  0 ;  $i -- ) { 
		if ( $arr [ $i  -  1 ]  >=  $arr [ $i ] )  break ; 
		$tmp  =  $arr [ $i  -  1 ] ; 
		$arr [ $i  -  1 ]  =  $arr [ $i ] ; 
		$arr [ $i ]  =  $tmp ; 
	} 
	return  true ; 
} 
 
// binary search for correct place + array_splice() to insert element 
function  insert3( & $arr ,  $elem ) { 
	$startIndex  =  0 ; 
	$stopIndex  =  count ( $arr )  -  1 ;  	$middle  =  0 ; 
	while ( $startIndex  <  $stopIndex ) { 
		$middle  =  ceil ( ( $stopIndex  +  $startIndex )  /  2 ) ;  		if ( $elem  >  $arr [ $middle ] ) { 
			$stopIndex  =  $middle  -  1 ; 
		} else  if ( $elem  <=  $arr [ $middle ] ) { 
			$startIndex  =  $middle ; 
		} 
	} 
	$offset  =  $elem  >=  $arr [ $startIndex ]  ? $startIndex  :  $startIndex  +  1 ;  
} 
 
// for loop to find correct place + array_splice() to insert 
function  insert4( & $arr ,  $elem ) { 
	$inserted  =  false ; 
	for ( $i  =  0 ;  $i  <  $c ;  $i ++ ) { 
		if ( $elem  >=  $arr [ $i ] ) { 
			$inserted  =  true ; 
			break ; 
		} 
	} 
	if ( ! $inserted )  $arr [ ]  =  $elem ; 
	return  true ; 
} 
 
/*********************** Speed tests: *************************/ 
 
// check if array is sorted descending 
function  checkIfArrayCorrect( $arr ,  $expectedCount  =  null ) { 
	if ( isset ( $expectedCount )  &&  $c  !=  $expectedCount )  return  false ;  	$correct  =  true ; 
	for ( $i  =  0 ;  $i  <  $c  -  1 ;  $i ++ ) { 
		if ( ! isset ( $arr [ $i  +  1 ] )  ||  $arr [ $i ]  <  $arr [ $i  +  1 ] ) {  			$correct  =  false ; 
			break ; 
		} 
	} 
	return  $correct ; 
} 
// claculates microtimetime diff 
function  timeDiff( $startTime ) { 
	return  $diff ; 
} 
// prints formatted execution time info 
function  showTime( $func ,  $time ) { 
	printf ( "Execution time of %s (): %f  s\n " ,  $func ,  $time ) ;  } 
// generated elements num 
$elementsNum  =  10000 ; 
// generate starting point 
$start  =  300000 ; 
// generated elements random range  1 - $dev 
$dev  =  50 ; 
 
 
echo  "Generating array with descending order, $elementsNum  elements, begining from $start \n " ; 
$arr  =  generateSorted( $start ,  $elementsNum ,  $dev ) ; 
showTime( 'generateSorted' ,  timeDiff( $startTime ) ) ; 
 
$step  =  2 ; 
echo  "Generating second array using range range(), $elementsNum  elements, begining from $start , step $step \n " ; 
$arr2  =  range ( $start ,  $start  -  $elementsNum  *  $step ,  $step ) ; showTime( 'range' ,  timeDiff( $startTime ) ) ; 
 
echo  "Generating SplMaxHeap, $elementsNum  elements, begining from $start \n " ; 
$heap  =  generateSorted( $start ,  $elementsNum ,  $dev ,  true ) ; 
showTime( 'SplMaxHeap' ,  timeDiff( $startTime ) ) ; 
 
echo  "Checking if array is correct\n " ; 
$sorted  =  checkIfArrayCorrect( $arr ,  $elementsNum ) ; 
showTime( 'checkIfArrayCorrect' ,  timeDiff( $startTime ) ) ; 
 
if ( ! $sorted )  die ( "Array is not in descending order!\n " ) ; echo  "Array OK\n " ; 
 
 
// number of elements to insert from every range 
$randElementNum  =  20 ; 
 
// some ranges of elements to insert near begining, middle and end of generated array 
// start value => end value 
	300000  =>  280000 , 
	160000  =>  140000 , 
	30000  =>  0 , 
) ; 
foreach ( $ranges  as  $from  =>  $to ) { 
	echo  "Generating $randElementNum  random elements from range [$from  - $to ] to insert\n " ; 
	while ( count ( $values )  <  $randElementNum ) {  	} 
} 
// some elements to insert on begining and end of array 
 
echo  "Generated elements: \n " ; 
for ( $i  =  0 ;  $i  <  count ( $toInsert ) ;  $i ++ ) { 	if ( $i  >  0  &&  $i  %  5  ==  0 )  echo  "\n " ; 
	printf ( "%8d , " ,  $toInsert [ $i ] ) ;  	if ( $i  ==  count ( $toInsert )  -  1 )  echo  "\n " ;  } 
// functions to test 
$toTest  =  array ( 'insert1'  =>  null ,  'insert2'  =>  null ,  'insert3'  =>  null ,  'insert4'  =>  null ) ; foreach ( $toTest  as  $func  =>  & $time ) { 
	echo  "\n \n ================== Testing speed of $func () ======================\n \n " ; 
	$tmpArr  =  $arr ; 
	for ( $i  =  0 ;  $i  <  count ( $toInsert ) ;  $i ++ ) {  		$func ( $tmpArr ,  $toInsert [ $i ] ) ; 
	} 
	$time  =  timeDiff( $startTime ) ; 
	showTime( $func ,  $time ) ; 
	echo  "Checking if after using $func () array is still correct: \n " ; 
	if ( ! checkIfArrayCorrect
( $tmpArr ,  count ( $arr )  +  count ( $toInsert ) ) ) {  		echo  "Array INCORRECT!\n \n " ; 
	} else { 
		echo  "Array OK!\n \n " ; 
	} 
	//echo "Few elements from begining of array:\n"; 
	//print_r(array_slice($tmpArr, 0, 5)); 
 
	//echo "Few elements from end of array:\n"; 
	//print_r(array_slice($tmpArr, -5)); 
 
	//echo "\n================== Finished testing $func() ======================\n\n"; 
} 
 
echo  "\n \n ================== Testing speed of SplMaxHeap::insert() ======================\n \n " ; 
for ( $i  =  0 ;  $i  <  count ( $toInsert ) ;  $i ++ ) { 	$heap -> insert ( $toInsert [ $i ] ) ; 
} 
$time  =  timeDiff( $startTime ) ; 
showTime( 'SplMaxHeap::insert' ,  $time ) ; 
$toTest [ 'SplMaxHeap::insert' ]  =  $time ; 
echo  "\n \n ================== Functions time summary  ======================\n \n " ; 
foreach ( $toTest  as  $func  =>  $time ) { 
	printf ( "%18s () => %.10f \n " ,  $func ,  $time ) ;  } 
PD9waHAKLyoqKioqKioqKiogR2VuZXJhdGluZyBzb3J0ZWQgc3RydWN0dXJlIChhcnJheSAvIFNwbE1heEhlYXApOiAqKioqKioqKioqKioqLwoKZnVuY3Rpb24gZ2VuZXJhdGVTb3J0ZWQoJHN0YXJ0ID0gMzAwMDAwLCAkZWxlbWVudHNOdW0gPSAxMDAwMCwgJGRldiA9IDMwLCAkaGVhcCA9IGZhbHNlKXsKCSRzb3J0ZWQgPSAkaGVhcCA/IG5ldyBTcGxNYXhIZWFwKCkgOiBhcnJheSgpOwoJZm9yKCRpID0gMTsgJGkgPD0gJGVsZW1lbnRzTnVtOyAkaSsrKXsKCQkkcmFuZCA9IG10X3JhbmQoMSwgJGRldik7CgkJJHN0YXJ0IC09ICRyYW5kOwoJCWlmKCEkaGVhcCl7CgkJCSRzb3J0ZWRbXSA9ICRzdGFydDsKCQl9ZWxzZXsKCQkJJHNvcnRlZC0+aW5zZXJ0KCRzdGFydCk7IAoJCX0KCX0KCXJldHVybiAkc29ydGVkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKiBGb3VyIGluc2VydCBmdW5jdGlvbnM6ICoqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLy8gZm9yIGxvb3AsIGFuZCBhcnJheSBjb3B5aW5nCmZ1bmN0aW9uIGluc2VydDEoJiRhcnIsICRlbGVtKXsKCWlmKGVtcHR5KCRhcnIpKXsKCQkkYXJyW10gPSAkZWxlbTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCSRjID0gY291bnQoJGFycik7CgkkbGFzdEluZGV4ID0gJGMgLSAxOwoJJHRtcCA9IGFycmF5KCk7CgkkaW5zZXJ0ZWQgPSBmYWxzZTsKCWZvcigkaSA9IDA7ICRpIDwgJGM7ICRpKyspewoJCWlmKCEkaW5zZXJ0ZWQgJiYgJGFyclskaV0gPD0gJGVsZW0pewoJCQkkdG1wW10gPSAkZWxlbTsKCQkJJGluc2VydGVkID0gdHJ1ZTsKCQl9CgkJJHRtcFtdID0gJGFyclskaV07CgkJaWYoJGxhc3RJbmRleCA9PSAkaSAmJiAhJGluc2VydGVkKSAkdG1wW10gPSAkZWxlbTsKCX0KCSRhcnIgPSAkdG1wOwoJcmV0dXJuIHRydWU7Cn0KCi8vIG5ldyBlbGVtZW50IGluc2VydGVkIGF0IHRoZSBlbmQgb2YgYXJyYXkgCi8vIGFuZCBtb3ZlZCB1cCB1bnRpbCBjb3JyZWN0IHBsYWNlCmZ1bmN0aW9uIGluc2VydDIoJiRhcnIsICRlbGVtKXsKCSRjID0gY291bnQoJGFycik7CglhcnJheV9wdXNoKCRhcnIsICRlbGVtKTsKCWZvcigkaSA9ICRjOyAkaSA+IDA7ICRpLS0pewoJCWlmKCRhcnJbJGkgLSAxXSA+PSAkYXJyWyRpXSkgYnJlYWs7CgkJJHRtcCA9ICRhcnJbJGkgLSAxXTsKCQkkYXJyWyRpIC0gMV0gPSAkYXJyWyRpXTsKCQkkYXJyWyRpXSA9ICR0bXA7Cgl9CglyZXR1cm4gdHJ1ZTsKfQoKLy8gYmluYXJ5IHNlYXJjaCBmb3IgY29ycmVjdCBwbGFjZSArIGFycmF5X3NwbGljZSgpIHRvIGluc2VydCBlbGVtZW50CmZ1bmN0aW9uIGluc2VydDMoJiRhcnIsICRlbGVtKXsKCSRzdGFydEluZGV4ID0gMDsKCSRzdG9wSW5kZXggPSBjb3VudCgkYXJyKSAtIDE7CgkkbWlkZGxlID0gMDsKCXdoaWxlKCRzdGFydEluZGV4IDwgJHN0b3BJbmRleCl7CgkJJG1pZGRsZSA9IGNlaWwoKCRzdG9wSW5kZXggKyAkc3RhcnRJbmRleCkgLyAyKTsKCQlpZigkZWxlbSA+ICRhcnJbJG1pZGRsZV0pewoJCQkkc3RvcEluZGV4ID0gJG1pZGRsZSAtIDE7CgkJfWVsc2UgaWYoJGVsZW0gPD0gJGFyclskbWlkZGxlXSl7CgkJCSRzdGFydEluZGV4ID0gJG1pZGRsZTsKCQl9Cgl9Cgkkb2Zmc2V0ID0gJGVsZW0gPj0gJGFyclskc3RhcnRJbmRleF0gPyAkc3RhcnRJbmRleCA6ICRzdGFydEluZGV4ICsgMTsgCglhcnJheV9zcGxpY2UoJGFyciwgJG9mZnNldCwgMCwgYXJyYXkoJGVsZW0pKTsKfQoKLy8gZm9yIGxvb3AgdG8gZmluZCBjb3JyZWN0IHBsYWNlICsgYXJyYXlfc3BsaWNlKCkgdG8gaW5zZXJ0CmZ1bmN0aW9uIGluc2VydDQoJiRhcnIsICRlbGVtKXsKCSRjID0gY291bnQoJGFycik7CgkkaW5zZXJ0ZWQgPSBmYWxzZTsKCWZvcigkaSA9IDA7ICRpIDwgJGM7ICRpKyspewoJCWlmKCRlbGVtID49ICRhcnJbJGldKXsKCQkJYXJyYXlfc3BsaWNlKCRhcnIsICRpLCAwLCBhcnJheSgkZWxlbSkpOwoJCQkkaW5zZXJ0ZWQgPSB0cnVlOwoJCQlicmVhazsKCQl9Cgl9CglpZighJGluc2VydGVkKSAkYXJyW10gPSAkZWxlbTsKCXJldHVybiB0cnVlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKiogU3BlZWQgdGVzdHM6ICoqKioqKioqKioqKioqKioqKioqKioqKiovCgovLyBjaGVjayBpZiBhcnJheSBpcyBzb3J0ZWQgZGVzY2VuZGluZwpmdW5jdGlvbiBjaGVja0lmQXJyYXlDb3JyZWN0KCRhcnIsICRleHBlY3RlZENvdW50ID0gbnVsbCl7CgkkYyA9IGNvdW50KCRhcnIpOwoJaWYoaXNzZXQoJGV4cGVjdGVkQ291bnQpICYmICRjICE9ICRleHBlY3RlZENvdW50KSByZXR1cm4gZmFsc2U7CgkkY29ycmVjdCA9IHRydWU7Cglmb3IoJGkgPSAwOyAkaSA8ICRjIC0gMTsgJGkrKyl7CgkJaWYoIWlzc2V0KCRhcnJbJGkgKyAxXSkgfHwgJGFyclskaV0gPCAkYXJyWyRpICsgMV0pewoJCQkkY29ycmVjdCA9IGZhbHNlOwoJCQlicmVhazsKCQl9Cgl9CglyZXR1cm4gJGNvcnJlY3Q7Cn0KLy8gY2xhY3VsYXRlcyBtaWNyb3RpbWV0aW1lIGRpZmYKZnVuY3Rpb24gdGltZURpZmYoJHN0YXJ0VGltZSl7CgkkZGlmZiA9IG1pY3JvdGltZSh0cnVlKSAtICRzdGFydFRpbWU7CglyZXR1cm4gJGRpZmY7Cn0KLy8gcHJpbnRzIGZvcm1hdHRlZCBleGVjdXRpb24gdGltZSBpbmZvCmZ1bmN0aW9uIHNob3dUaW1lKCRmdW5jLCAkdGltZSl7CglwcmludGYoIkV4ZWN1dGlvbiB0aW1lIG9mICVzKCk6ICVmIHNcbiIsICRmdW5jLCAkdGltZSk7Cn0KLy8gZ2VuZXJhdGVkIGVsZW1lbnRzIG51bQokZWxlbWVudHNOdW0gPSAxMDAwMDsKLy8gZ2VuZXJhdGUgc3RhcnRpbmcgcG9pbnQKJHN0YXJ0ID0gMzAwMDAwOwovLyBnZW5lcmF0ZWQgZWxlbWVudHMgcmFuZG9tIHJhbmdlICAxIC0gJGRldgokZGV2ID0gNTA7CgoKZWNobyAiR2VuZXJhdGluZyBhcnJheSB3aXRoIGRlc2NlbmRpbmcgb3JkZXIsICRlbGVtZW50c051bSBlbGVtZW50cywgYmVnaW5pbmcgZnJvbSAkc3RhcnRcbiI7CiRzdGFydFRpbWUgPSBtaWNyb3RpbWUodHJ1ZSk7CiRhcnIgPSBnZW5lcmF0ZVNvcnRlZCgkc3RhcnQsICRlbGVtZW50c051bSwgJGRldik7CnNob3dUaW1lKCdnZW5lcmF0ZVNvcnRlZCcsIHRpbWVEaWZmKCRzdGFydFRpbWUpKTsKCiRzdGVwID0gMjsKZWNobyAiR2VuZXJhdGluZyBzZWNvbmQgYXJyYXkgdXNpbmcgcmFuZ2UgcmFuZ2UoKSwgJGVsZW1lbnRzTnVtIGVsZW1lbnRzLCBiZWdpbmluZyBmcm9tICRzdGFydCwgc3RlcCAkc3RlcFxuIjsKJHN0YXJ0VGltZSA9IG1pY3JvdGltZSh0cnVlKTsKJGFycjIgPSByYW5nZSgkc3RhcnQsICRzdGFydCAtICRlbGVtZW50c051bSAqICRzdGVwLCAkc3RlcCk7CnNob3dUaW1lKCdyYW5nZScsIHRpbWVEaWZmKCRzdGFydFRpbWUpKTsKCmVjaG8gIkdlbmVyYXRpbmcgU3BsTWF4SGVhcCwgJGVsZW1lbnRzTnVtIGVsZW1lbnRzLCBiZWdpbmluZyBmcm9tICRzdGFydFxuIjsKJHN0YXJ0VGltZSA9IG1pY3JvdGltZSh0cnVlKTsKJGhlYXAgPSBnZW5lcmF0ZVNvcnRlZCgkc3RhcnQsICRlbGVtZW50c051bSwgJGRldiwgdHJ1ZSk7CnNob3dUaW1lKCdTcGxNYXhIZWFwJywgdGltZURpZmYoJHN0YXJ0VGltZSkpOwoKZWNobyAiQ2hlY2tpbmcgaWYgYXJyYXkgaXMgY29ycmVjdFxuIjsKJHN0YXJ0VGltZSA9IG1pY3JvdGltZSh0cnVlKTsKJHNvcnRlZCA9IGNoZWNrSWZBcnJheUNvcnJlY3QoJGFyciwgJGVsZW1lbnRzTnVtKTsKc2hvd1RpbWUoJ2NoZWNrSWZBcnJheUNvcnJlY3QnLCB0aW1lRGlmZigkc3RhcnRUaW1lKSk7CgppZighJHNvcnRlZCkgZGllKCJBcnJheSBpcyBub3QgaW4gZGVzY2VuZGluZyBvcmRlciFcbiIpOwplY2hvICJBcnJheSBPS1xuIjsKCiR0b0luc2VydCA9IGFycmF5KCk7CgovLyBudW1iZXIgb2YgZWxlbWVudHMgdG8gaW5zZXJ0IGZyb20gZXZlcnkgcmFuZ2UKJHJhbmRFbGVtZW50TnVtID0gMjA7CgovLyBzb21lIHJhbmdlcyBvZiBlbGVtZW50cyB0byBpbnNlcnQgbmVhciBiZWdpbmluZywgbWlkZGxlIGFuZCBlbmQgb2YgZ2VuZXJhdGVkIGFycmF5Ci8vIHN0YXJ0IHZhbHVlID0+IGVuZCB2YWx1ZQokcmFuZ2VzID0gYXJyYXkoCgkzMDAwMDAgPT4gMjgwMDAwLAoJMTYwMDAwID0+IDE0MDAwMCwKCTMwMDAwID0+IDAsCik7CmZvcmVhY2goJHJhbmdlcyBhcyAkZnJvbSA9PiAkdG8pewoJJHZhbHVlcyA9IGFycmF5KCk7CgllY2hvICJHZW5lcmF0aW5nICRyYW5kRWxlbWVudE51bSByYW5kb20gZWxlbWVudHMgZnJvbSByYW5nZSBbJGZyb20gLSAkdG9dIHRvIGluc2VydFxuIjsKCXdoaWxlKGNvdW50KCR2YWx1ZXMpIDwgJHJhbmRFbGVtZW50TnVtKXsKCQkkdmFsdWVzW210X3JhbmQoJGZyb20sICR0byldID0gMTsKCX0KCSR0b0luc2VydCA9IGFycmF5X21lcmdlKCR0b0luc2VydCwgYXJyYXlfa2V5cygkdmFsdWVzKSk7Cn0KLy8gc29tZSBlbGVtZW50cyB0byBpbnNlcnQgb24gYmVnaW5pbmcgYW5kIGVuZCBvZiBhcnJheQphcnJheV9wdXNoKCR0b0luc2VydCwgMzEwMDAwKTsKYXJyYXlfcHVzaCgkdG9JbnNlcnQsIC0xMDAwKTsKCmVjaG8gIkdlbmVyYXRlZCBlbGVtZW50czogXG4iOwpmb3IoJGkgPSAwOyAkaSA8IGNvdW50KCR0b0luc2VydCk7ICRpKyspewoJaWYoJGkgPiAwICYmICRpICUgNSA9PSAwKSBlY2hvICJcbiI7CglwcmludGYoIiU4ZCwgIiwgJHRvSW5zZXJ0WyRpXSk7CglpZigkaSA9PSBjb3VudCgkdG9JbnNlcnQpIC0gMSkgZWNobyAiXG4iOwp9Ci8vIGZ1bmN0aW9ucyB0byB0ZXN0CiR0b1Rlc3QgPSBhcnJheSgnaW5zZXJ0MScgPT4gbnVsbCwgJ2luc2VydDInID0+IG51bGwsICdpbnNlcnQzJyA9PiBudWxsLCAnaW5zZXJ0NCcgPT4gbnVsbCk7CmZvcmVhY2goJHRvVGVzdCBhcyAkZnVuYyA9PiAmJHRpbWUpewoJZWNobyAiXG5cbj09PT09PT09PT09PT09PT09PSBUZXN0aW5nIHNwZWVkIG9mICRmdW5jKCkgPT09PT09PT09PT09PT09PT09PT09PVxuXG4iOwoJJHRtcEFyciA9ICRhcnI7Cgkkc3RhcnRUaW1lID0gbWljcm90aW1lKHRydWUpOwoJZm9yKCRpID0gMDsgJGkgPCBjb3VudCgkdG9JbnNlcnQpOyAkaSsrKXsKCQkkZnVuYygkdG1wQXJyLCAkdG9JbnNlcnRbJGldKTsKCX0KCSR0aW1lID0gdGltZURpZmYoJHN0YXJ0VGltZSk7CglzaG93VGltZSgkZnVuYywgJHRpbWUpOwoJZWNobyAiQ2hlY2tpbmcgaWYgYWZ0ZXIgdXNpbmcgJGZ1bmMoKSBhcnJheSBpcyBzdGlsbCBjb3JyZWN0OiBcbiI7CglpZighY2hlY2tJZkFycmF5Q29ycmVjdCgkdG1wQXJyLCBjb3VudCgkYXJyKSArIGNvdW50KCR0b0luc2VydCkpKXsKCQllY2hvICJBcnJheSBJTkNPUlJFQ1QhXG5cbiI7Cgl9ZWxzZXsKCQllY2hvICJBcnJheSBPSyFcblxuIjsKCX0KCS8vZWNobyAiRmV3IGVsZW1lbnRzIGZyb20gYmVnaW5pbmcgb2YgYXJyYXk6XG4iOwoJLy9wcmludF9yKGFycmF5X3NsaWNlKCR0bXBBcnIsIDAsIDUpKTsKCQoJLy9lY2hvICJGZXcgZWxlbWVudHMgZnJvbSBlbmQgb2YgYXJyYXk6XG4iOwoJLy9wcmludF9yKGFycmF5X3NsaWNlKCR0bXBBcnIsIC01KSk7CgoJLy9lY2hvICJcbj09PT09PT09PT09PT09PT09PSBGaW5pc2hlZCB0ZXN0aW5nICRmdW5jKCkgPT09PT09PT09PT09PT09PT09PT09PVxuXG4iOwp9CgplY2hvICJcblxuPT09PT09PT09PT09PT09PT09IFRlc3Rpbmcgc3BlZWQgb2YgU3BsTWF4SGVhcDo6aW5zZXJ0KCkgPT09PT09PT09PT09PT09PT09PT09PVxuXG4iOwokc3RhcnRUaW1lID0gbWljcm90aW1lKHRydWUpOwpmb3IoJGkgPSAwOyAkaSA8IGNvdW50KCR0b0luc2VydCk7ICRpKyspewoJJGhlYXAtPmluc2VydCgkdG9JbnNlcnRbJGldKTsKfQokdGltZSA9IHRpbWVEaWZmKCRzdGFydFRpbWUpOwpzaG93VGltZSgnU3BsTWF4SGVhcDo6aW5zZXJ0JywgJHRpbWUpOwokdG9UZXN0WydTcGxNYXhIZWFwOjppbnNlcnQnXSA9ICR0aW1lOwplY2hvICJcblxuPT09PT09PT09PT09PT09PT09IEZ1bmN0aW9ucyB0aW1lIHN1bW1hcnkgID09PT09PT09PT09PT09PT09PT09PT1cblxuIjsKZm9yZWFjaCgkdG9UZXN0IGFzICRmdW5jID0+ICR0aW1lKXsKCXByaW50ZigiJTE4cygpID0+ICUuMTBmXG4iLCAkZnVuYywgJHRpbWUpOwp9