<?php 
 
 
abstract  class  Question
{ 
	protected  $text ; 
	protected  $points ; 
	protected  $correctAnswer ; 
	protected  $hint ; 
 
	abstract  function  getAsString( ) :  string; 
	abstract  function  checkAnswer
( $answer ) :  array ;   
	// Возвращает вопрос 
	public  function  getQuestionText( ) :  string
	{ 
		$text  =  $this -> text ; 
		return  $text ; 
	} 
 
	// Возвращает количество баллов за правильный ответ 
	public  function  getPoints( ) :  int
	{ 
		$points  =  $this -> points ; 
		return  $points ; 
	} 
 
	// Возвращает подсказку 
	public  function  getQuestionHint( ) :  string
	{ 
		$hint  =  $this -> hint ; 
		return  $hint ; 
	} 
} 
 
class  MultipleChoiceQuestion extends  Question
{ 
    protected  $answers ; 
    protected  $almostCorrectAnswer ; 
 
	public  function  __construct
( string 
$text ,  float 
$points ,  array $answers ,  string 
$correctAnswer ,  string 
$hint )  	{ 
		$this -> text  =  $text ; 
		$this -> points  =  $points ; 
		$this -> answers  =  $answers ; 
		$this -> correctAnswer  =  $correctAnswer ; 
		$this -> hint  =  $hint ; 
	} 
 
	// Функция добавляющая почти корректный ответ 
	public  function  addAlmostCorrectAnswer( $almostCorrectAnswer ) 
	{ 
		$this -> almostCorrectAnswer  =  $almostCorrectAnswer ; 
	} 
 
	// Функция отдающая строку со списком вопросов 
	public  function  getAsString( ) :  string
	{ 
		$string  =  "{$this->text} \n Варианты ответов:\n " ; 
 
		foreach  ( $this -> answers  as  $letter  =>  $answer )  { 
			$string  =  $string . "{$letter} . {$answer} \n " ; 
		} 
 
		return  $string ; 
	} 
 
	/* Функция получает на вход ответ.  
	Проверяет его, учитывая почти правильный вариант ответа.  
	Возвращает в массиве результаты проверки */ 
 
	public  function  checkAnswer
( $answer ) :  array  	{ 
		$isCorrect  =  0 ; 
		$isAlmostCorrect  =  0 ; 
 
		if  ( $answer  ==  $this -> correctAnswer )  { 
			$isCorrect  =  1 ; 
		}  elseif  ( $answer  ==  $this -> almostCorrectAnswer )  { 
			$isAlmostCorrect  =  1 ; 
		} 
 
		return  array ( $isCorrect ,  $isAlmostCorrect ) ;  	} 
 
} 
 
class  NumericalQuestion extends  Question
{ 
	protected  $deviation ; 
 
	function  __construct( string $text ,  string $hint ,  float $points ,  float $correctAnswer ,  float $deviation  =  0 ) 
	{ 
		$this -> text  =  $text ; 
		$this -> points  =  $points ; 
		$this -> correctAnswer  =  $correctAnswer ; 
		$this -> deviation  =  $deviation ; 
		$this -> hint  =  $hint ; 
	} 
 
	// Функция возвращает строку со списком вопросов 
	public  function  getAsString( ) :  string
	{ 
		return  "{$this->text} \n " ; 
	} 
 
	/* Функция получает ответ. Проверяет его с учетом возможного отклонения. 
	Возвращает в массиве результат проверки. */ 
 
	public  function  checkAnswer
( $answer ) :  array  	{ 
		$isCorrect  =  0 ; 
 
		if  ( $answer  ==  $this -> correctAnswer  or 
$this -> deviation  >  abs ( $this -> correctAnswer  -  $answer ) )  {  			$isCorrect  =  1 ; 
		} 
 
        return  array ( $isCorrect ,  $isAlmostCorrect  =  0 ) ;  	} 
 
} 
 
// Функция создающая массив с вопросами 
function  createQuestions( )  { 
 
	$questions  =  [ ] ; 
 
	$text  =  'Какая планета располагается четвертой по счету от Солнца?' ; 
	$answers  =  array ( 'a'  =>  'Венера' ,  'b'  =>  'Марс' ,  'c'  =>  'Юпитер' ,  'd'  =>  'Меркурий' ) ;  	$hint  =  'Одноименное название носит шоколадный батончик.' ; 
	$q  =  new  MultipleChoiceQuestion( $text ,  10 ,  $answers ,  'b' ,  $hint ) ; 
 
	$questions [ ]  =  $q ; 
 
	$text  =  'Какой город является столицей Великобритании?' ; 
	$answers  =  array ( 'a'  =>  'Париж' ,  'b'  =>  'Москва' ,  'c'  =>  'Нью-Йорк' ,  'd'  =>  'Лондон' ) ;  	$hint  =  '%Городнейм% из кэпитал оф грейт британ.' ; 
	$q  =  new  MultipleChoiceQuestion( $text ,  5 ,  $answers ,  'd' ,  $hint ) ; 
 
	$questions [ ]  =  $q ; 
 
	$text  =  'Кто придумал теорию относительности?' ; 
	$answers  =  array ( 'a'  =>  'Джон Леннон' ,  'b'  =>  'Джим Моррисон' ,  'c'  =>  'Альберт Эйнштейн' ,  'd'  =>  'Исаак Ньютон' ) ;  	$hint  =  'Этим парнем был...' ; 
	$q  =  new  MultipleChoiceQuestion( $text ,  30 ,  $answers ,  'c' ,  $hint ) ; 
	$q -> addAlmostCorrectAnswer ( 'b' ) ; 
 
	$questions [ ]  =  $q ; 
 
	$hint  =  'Попробуй еще раз, дружок-пирожок!' ; 
	$q  =  new  NumericalQuestion( 'Чему равна скорость света в км/с?' ,  $hint ,  15 ,  299792 ,  210 ) ; 
 
	$questions [ ]  =  $q ; 
 
	$hint  =  'Между 2 и 4, подумой.' ; 
	$q  =  new  NumericalQuestion( 'Чему равно число Пи?' ,  $hint ,  30 ,  3.14 ,  0.01 ) ; 
 
	$questions [ ]  =  $q ; 
 
	$hint  =  'Сычёв, ты отчислен!' ; 
	$q  =  new  NumericalQuestion( 'В каком году закончилась вторая мировая война?' ,  $hint ,  10 ,  1945 ) ; 
 
	$questions [ ]  =  $q ; 
 
	return  $questions ; 
} 
 
// Функция выводящая список вопросов с вариантами ответов 
function  printQuestions( $questions )  { 
 
	$number  =  1 ; 
 
	foreach  ( $questions  as  $question )  { 
		echo  "\n {$number} . " ; 
		echo  $question -> getAsString ( ) ; 
 
		$number  ++; 
	} 
 
} 
 
/* Функция получает массивы вопросов и ответов. Проверяет ответы,  
считает число баллов и печатает вопросы на которые был дан неправильный ответ. */ 
 
function  checkAnswers( $questions ,  $answers ) 
{ 
        die ( "Число ответов и вопросов не совпадает\n " ) ;      } 
 
    $pointsTotal  =  0 ; 
    $pointsMax  =  0 ; 
    $correctAnswers  =  0 ; 
 
    $totalQuestions  =  count ( $questions ) ;   
    for  ( $i  =  0 ;  $i  <  count ( $questions ) ;  $i ++ )  {   
        $question  =  $questions [ $i ] ; 
        $answer  =  $answers [ $i ] ; 
 
        list ( $isCorrect ,  $isAlmostCorrect )  =  $question -> checkAnswer ( $answer ) ;          $points  =  $question -> getPoints ( ) ; 
 
        $pointsMax  +=  $points ; 
 
        if  ( $isCorrect )  { 
 
            $correctAnswers  ++; 
            $pointsTotal  +=  $points ; 
 
        }  elseif  ( $isAlmostCorrect )  { 
 
        	$correctAnswers  ++; 
            $pointsTotal  +=  $points  /  2 ; 
 
        }  else  { 
 
            $number  =  $i  +  1 ; 
            echo  "\n Неправильный ответ на вопрос №{$number}  ({$question->getQuestionText ()})\n " ; 
			echo  "\n Подсказка: {$question->getQuestionHint ()}\n " ; 
 
        } 
 
    } 
 
    echo  "\n Правильных ответов: {$correctAnswers}  из {$totalQuestions} , баллов набрано: $pointsTotal  из $pointsMax \n " ; 
} 
 
$questions  =  createQuestions( ) ; 
printQuestions( $questions ) ; 
checkAnswers
( $questions ,  array ( 'b' ,  'd' ,  'b' ,  299792 ,  3.14444 ,  1944 ) ) ; PD9waHAKCmVycm9yX3JlcG9ydGluZyhFX0FMTCk7CgphYnN0cmFjdCBjbGFzcyBRdWVzdGlvbgp7Cglwcm90ZWN0ZWQgJHRleHQ7Cglwcm90ZWN0ZWQgJHBvaW50czsKCXByb3RlY3RlZCAkY29ycmVjdEFuc3dlcjsKCXByb3RlY3RlZCAkaGludDsKCglhYnN0cmFjdCBmdW5jdGlvbiBnZXRBc1N0cmluZygpOiBzdHJpbmc7CglhYnN0cmFjdCBmdW5jdGlvbiBjaGVja0Fuc3dlcigkYW5zd2VyKTogYXJyYXk7CgoJLy8g0JLQvtC30LLRgNCw0YnQsNC10YIg0LLQvtC/0YDQvtGBCglwdWJsaWMgZnVuY3Rpb24gZ2V0UXVlc3Rpb25UZXh0KCk6IHN0cmluZwoJewoJCSR0ZXh0ID0gJHRoaXMtPnRleHQ7CgkJcmV0dXJuICR0ZXh0OwoJfQoKCS8vINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINC60L7Qu9C40YfQtdGB0YLQstC+INCx0LDQu9C70L7QsiDQt9CwINC/0YDQsNCy0LjQu9GM0L3Ri9C5INC+0YLQstC10YIKCXB1YmxpYyBmdW5jdGlvbiBnZXRQb2ludHMoKTogaW50Cgl7CgkJJHBvaW50cyA9ICR0aGlzLT5wb2ludHM7CgkJcmV0dXJuICRwb2ludHM7Cgl9CgoJLy8g0JLQvtC30LLRgNCw0YnQsNC10YIg0L/QvtC00YHQutCw0LfQutGDCglwdWJsaWMgZnVuY3Rpb24gZ2V0UXVlc3Rpb25IaW50KCk6IHN0cmluZwoJewoJCSRoaW50ID0gJHRoaXMtPmhpbnQ7CgkJcmV0dXJuICRoaW50OwoJfQp9CgpjbGFzcyBNdWx0aXBsZUNob2ljZVF1ZXN0aW9uIGV4dGVuZHMgUXVlc3Rpb24KewogICAgcHJvdGVjdGVkICRhbnN3ZXJzOwogICAgcHJvdGVjdGVkICRhbG1vc3RDb3JyZWN0QW5zd2VyOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChzdHJpbmcgJHRleHQsIGZsb2F0ICRwb2ludHMsIGFycmF5ICRhbnN3ZXJzLCBzdHJpbmcgJGNvcnJlY3RBbnN3ZXIsIHN0cmluZyAkaGludCkKCXsKCQkkdGhpcy0+dGV4dCA9ICR0ZXh0OwoJCSR0aGlzLT5wb2ludHMgPSAkcG9pbnRzOwoJCSR0aGlzLT5hbnN3ZXJzID0gJGFuc3dlcnM7CgkJJHRoaXMtPmNvcnJlY3RBbnN3ZXIgPSAkY29ycmVjdEFuc3dlcjsKCQkkdGhpcy0+aGludCA9ICRoaW50OwoJfQoKCS8vINCk0YPQvdC60YbQuNGPINC00L7QsdCw0LLQu9GP0Y7RidCw0Y8g0L/QvtGH0YLQuCDQutC+0YDRgNC10LrRgtC90YvQuSDQvtGC0LLQtdGCCglwdWJsaWMgZnVuY3Rpb24gYWRkQWxtb3N0Q29ycmVjdEFuc3dlcigkYWxtb3N0Q29ycmVjdEFuc3dlcikKCXsKCQkkdGhpcy0+YWxtb3N0Q29ycmVjdEFuc3dlciA9ICRhbG1vc3RDb3JyZWN0QW5zd2VyOwoJfQoKCS8vINCk0YPQvdC60YbQuNGPINC+0YLQtNCw0Y7RidCw0Y8g0YHRgtGA0L7QutGDINGB0L4g0YHQv9C40YHQutC+0Lwg0LLQvtC/0YDQvtGB0L7QsgoJcHVibGljIGZ1bmN0aW9uIGdldEFzU3RyaW5nKCk6IHN0cmluZwoJewoJCSRzdHJpbmcgPSAieyR0aGlzLT50ZXh0fVxu0JLQsNGA0LjQsNC90YLRiyDQvtGC0LLQtdGC0L7QsjpcbiI7CgoJCWZvcmVhY2ggKCR0aGlzLT5hbnN3ZXJzIGFzICRsZXR0ZXIgPT4gJGFuc3dlcikgewoJCQkkc3RyaW5nID0gJHN0cmluZy4ieyRsZXR0ZXJ9LiB7JGFuc3dlcn1cbiI7CgkJfQoKCQlyZXR1cm4gJHN0cmluZzsKCX0KCgkvKiDQpNGD0L3QutGG0LjRjyDQv9C+0LvRg9GH0LDQtdGCINC90LAg0LLRhdC+0LQg0L7RgtCy0LXRgi4gCgnQn9GA0L7QstC10YDRj9C10YIg0LXQs9C+LCDRg9GH0LjRgtGL0LLQsNGPINC/0L7Rh9GC0Lgg0L/RgNCw0LLQuNC70YzQvdGL0Lkg0LLQsNGA0LjQsNC90YIg0L7RgtCy0LXRgtCwLiAKCdCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINCyINC80LDRgdGB0LjQstC1INGA0LXQt9GD0LvRjNGC0LDRgtGLINC/0YDQvtCy0LXRgNC60LggKi8KCglwdWJsaWMgZnVuY3Rpb24gY2hlY2tBbnN3ZXIoJGFuc3dlcik6IGFycmF5Cgl7CgkJJGlzQ29ycmVjdCA9IDA7CgkJJGlzQWxtb3N0Q29ycmVjdCA9IDA7CgoJCWlmICgkYW5zd2VyID09ICR0aGlzLT5jb3JyZWN0QW5zd2VyKSB7CgkJCSRpc0NvcnJlY3QgPSAxOwoJCX0gZWxzZWlmICgkYW5zd2VyID09ICR0aGlzLT5hbG1vc3RDb3JyZWN0QW5zd2VyKSB7CgkJCSRpc0FsbW9zdENvcnJlY3QgPSAxOwoJCX0KCgkJcmV0dXJuIGFycmF5KCRpc0NvcnJlY3QsICRpc0FsbW9zdENvcnJlY3QpOwoJfQoKfQoKY2xhc3MgTnVtZXJpY2FsUXVlc3Rpb24gZXh0ZW5kcyBRdWVzdGlvbgp7Cglwcm90ZWN0ZWQgJGRldmlhdGlvbjsKCglmdW5jdGlvbiBfX2NvbnN0cnVjdChzdHJpbmcgJHRleHQsIHN0cmluZyAkaGludCwgZmxvYXQgJHBvaW50cywgZmxvYXQgJGNvcnJlY3RBbnN3ZXIsIGZsb2F0ICRkZXZpYXRpb24gPSAwKQoJewoJCSR0aGlzLT50ZXh0ID0gJHRleHQ7CgkJJHRoaXMtPnBvaW50cyA9ICRwb2ludHM7CgkJJHRoaXMtPmNvcnJlY3RBbnN3ZXIgPSAkY29ycmVjdEFuc3dlcjsKCQkkdGhpcy0+ZGV2aWF0aW9uID0gJGRldmlhdGlvbjsKCQkkdGhpcy0+aGludCA9ICRoaW50OwoJfQoKCS8vINCk0YPQvdC60YbQuNGPINCy0L7Qt9Cy0YDQsNGJ0LDQtdGCINGB0YLRgNC+0LrRgyDRgdC+INGB0L/QuNGB0LrQvtC8INCy0L7Qv9GA0L7RgdC+0LIKCXB1YmxpYyBmdW5jdGlvbiBnZXRBc1N0cmluZygpOiBzdHJpbmcKCXsKCQlyZXR1cm4gInskdGhpcy0+dGV4dH1cbiI7Cgl9CgoJLyog0KTRg9C90LrRhtC40Y8g0L/QvtC70YPRh9Cw0LXRgiDQvtGC0LLQtdGCLiDQn9GA0L7QstC10YDRj9C10YIg0LXQs9C+INGBINGD0YfQtdGC0L7QvCDQstC+0LfQvNC+0LbQvdC+0LPQviDQvtGC0LrQu9C+0L3QtdC90LjRjy4KCdCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINCyINC80LDRgdGB0LjQstC1INGA0LXQt9GD0LvRjNGC0LDRgiDQv9GA0L7QstC10YDQutC4LiAqLwoKCXB1YmxpYyBmdW5jdGlvbiBjaGVja0Fuc3dlcigkYW5zd2VyKTogYXJyYXkKCXsKCQkkaXNDb3JyZWN0ID0gMDsKCgkJaWYgKCRhbnN3ZXIgPT0gJHRoaXMtPmNvcnJlY3RBbnN3ZXIgb3IgJHRoaXMtPmRldmlhdGlvbiA+IGFicygkdGhpcy0+Y29ycmVjdEFuc3dlciAtICRhbnN3ZXIpKSB7CgkJCSRpc0NvcnJlY3QgPSAxOwoJCX0KCiAgICAgICAgcmV0dXJuIGFycmF5KCRpc0NvcnJlY3QsICRpc0FsbW9zdENvcnJlY3QgPSAwKTsKCX0KCn0KCi8vINCk0YPQvdC60YbQuNGPINGB0L7Qt9C00LDRjtGJ0LDRjyDQvNCw0YHRgdC40LIg0YEg0LLQvtC/0YDQvtGB0LDQvNC4CmZ1bmN0aW9uIGNyZWF0ZVF1ZXN0aW9ucygpIHsKCgkkcXVlc3Rpb25zID0gW107CgoJJHRleHQgPSAn0JrQsNC60LDRjyDQv9C70LDQvdC10YLQsCDRgNCw0YHQv9C+0LvQsNCz0LDQtdGC0YHRjyDRh9C10YLQstC10YDRgtC+0Lkg0L/QviDRgdGH0LXRgtGDINC+0YIg0KHQvtC70L3RhtCwPyc7CgkkYW5zd2VycyA9IGFycmF5KCdhJyA9PiAn0JLQtdC90LXRgNCwJywgJ2InID0+ICfQnNCw0YDRgScsICdjJyA9PiAn0K7Qv9C40YLQtdGAJywgJ2QnID0+ICfQnNC10YDQutGD0YDQuNC5Jyk7CgkkaGludCA9ICfQntC00L3QvtC40LzQtdC90L3QvtC1INC90LDQt9Cy0LDQvdC40LUg0L3QvtGB0LjRgiDRiNC+0LrQvtC70LDQtNC90YvQuSDQsdCw0YLQvtC90YfQuNC6Lic7CgkkcSA9IG5ldyBNdWx0aXBsZUNob2ljZVF1ZXN0aW9uKCR0ZXh0LCAxMCwgJGFuc3dlcnMsICdiJywgJGhpbnQpOwoKCSRxdWVzdGlvbnNbXSA9ICRxOwoKCSR0ZXh0ID0gJ9Ca0LDQutC+0Lkg0LPQvtGA0L7QtCDRj9Cy0LvRj9C10YLRgdGPINGB0YLQvtC70LjRhtC10Lkg0JLQtdC70LjQutC+0LHRgNC40YLQsNC90LjQuD8nOwoJJGFuc3dlcnMgPSBhcnJheSgnYScgPT4gJ9Cf0LDRgNC40LYnLCAnYicgPT4gJ9Cc0L7RgdC60LLQsCcsICdjJyA9PiAn0J3RjNGOLdCZ0L7RgNC6JywgJ2QnID0+ICfQm9C+0L3QtNC+0L0nKTsKCSRoaW50ID0gJyXQk9C+0YDQvtC00L3QtdC50LwlINC40Lcg0LrRjdC/0LjRgtCw0Lsg0L7RhCDQs9GA0LXQudGCINCx0YDQuNGC0LDQvS4nOwoJJHEgPSBuZXcgTXVsdGlwbGVDaG9pY2VRdWVzdGlvbigkdGV4dCwgNSwgJGFuc3dlcnMsICdkJywgJGhpbnQpOwoKCSRxdWVzdGlvbnNbXSA9ICRxOwoKCSR0ZXh0ID0gJ9Ca0YLQviDQv9GA0LjQtNGD0LzQsNC7INGC0LXQvtGA0LjRjiDQvtGC0L3QvtGB0LjRgtC10LvRjNC90L7RgdGC0Lg/JzsKCSRhbnN3ZXJzID0gYXJyYXkoJ2EnID0+ICfQlNC20L7QvSDQm9C10L3QvdC+0L0nLCAnYicgPT4gJ9CU0LbQuNC8INCc0L7RgNGA0LjRgdC+0L0nLCAnYycgPT4gJ9CQ0LvRjNCx0LXRgNGCINCt0LnQvdGI0YLQtdC50L0nLCAnZCcgPT4gJ9CY0YHQsNCw0Log0J3RjNGO0YLQvtC9Jyk7CgkkaGludCA9ICfQrdGC0LjQvCDQv9Cw0YDQvdC10Lwg0LHRi9C7Li4uJzsKCSRxID0gbmV3IE11bHRpcGxlQ2hvaWNlUXVlc3Rpb24oJHRleHQsIDMwLCAkYW5zd2VycywgJ2MnLCAkaGludCk7CgkkcS0+YWRkQWxtb3N0Q29ycmVjdEFuc3dlcignYicpOwoKCSRxdWVzdGlvbnNbXSA9ICRxOwoKCSRoaW50ID0gJ9Cf0L7Qv9GA0L7QsdGD0Lkg0LXRidC1INGA0LDQtywg0LTRgNGD0LbQvtC6LdC/0LjRgNC+0LbQvtC6ISc7CgkkcSA9IG5ldyBOdW1lcmljYWxRdWVzdGlvbign0KfQtdC80YMg0YDQsNCy0L3QsCDRgdC60L7RgNC+0YHRgtGMINGB0LLQtdGC0LAg0LIg0LrQvC/RgT8nLCAkaGludCwgMTUsIDI5OTc5MiwgMjEwKTsKCgkkcXVlc3Rpb25zW10gPSAkcTsKCgkkaGludCA9ICfQnNC10LbQtNGDIDIg0LggNCwg0L/QvtC00YPQvNC+0LkuJzsKCSRxID0gbmV3IE51bWVyaWNhbFF1ZXN0aW9uKCfQp9C10LzRgyDRgNCw0LLQvdC+INGH0LjRgdC70L4g0J/QuD8nLCAkaGludCwgMzAsIDMuMTQsIDAuMDEpOwoKCSRxdWVzdGlvbnNbXSA9ICRxOwoKCSRoaW50ID0gJ9Ch0YvRh9GR0LIsINGC0Ysg0L7RgtGH0LjRgdC70LXQvSEnOwoJJHEgPSBuZXcgTnVtZXJpY2FsUXVlc3Rpb24oJ9CSINC60LDQutC+0Lwg0LPQvtC00YMg0LfQsNC60L7QvdGH0LjQu9Cw0YHRjCDQstGC0L7RgNCw0Y8g0LzQuNGA0L7QstCw0Y8g0LLQvtC50L3QsD8nLCAkaGludCwgMTAsIDE5NDUpOwoKCSRxdWVzdGlvbnNbXSA9ICRxOwoKCXJldHVybiAkcXVlc3Rpb25zOwp9CgovLyDQpNGD0L3QutGG0LjRjyDQstGL0LLQvtC00Y/RidCw0Y8g0YHQv9C40YHQvtC6INCy0L7Qv9GA0L7RgdC+0LIg0YEg0LLQsNGA0LjQsNC90YLQsNC80Lgg0L7RgtCy0LXRgtC+0LIKZnVuY3Rpb24gcHJpbnRRdWVzdGlvbnMoJHF1ZXN0aW9ucykgewoKCSRudW1iZXIgPSAxOwoKCWZvcmVhY2ggKCRxdWVzdGlvbnMgYXMgJHF1ZXN0aW9uKSB7CgkJZWNobyAiXG57JG51bWJlcn0uICI7CgkJZWNobyAkcXVlc3Rpb24tPmdldEFzU3RyaW5nKCk7CgoJCSRudW1iZXIgKys7Cgl9Cgp9CgovKiDQpNGD0L3QutGG0LjRjyDQv9C+0LvRg9GH0LDQtdGCINC80LDRgdGB0LjQstGLINCy0L7Qv9GA0L7RgdC+0LIg0Lgg0L7RgtCy0LXRgtC+0LIuINCf0YDQvtCy0LXRgNGP0LXRgiDQvtGC0LLQtdGC0YssIArRgdGH0LjRgtCw0LXRgiDRh9C40YHQu9C+INCx0LDQu9C70L7QsiDQuCDQv9C10YfQsNGC0LDQtdGCINCy0L7Qv9GA0L7RgdGLINC90LAg0LrQvtGC0L7RgNGL0LUg0LHRi9C7INC00LDQvSDQvdC10L/RgNCw0LLQuNC70YzQvdGL0Lkg0L7RgtCy0LXRgi4gKi8KCmZ1bmN0aW9uIGNoZWNrQW5zd2VycygkcXVlc3Rpb25zLCAkYW5zd2VycykKewogICAgaWYgKGNvdW50KCRxdWVzdGlvbnMpICE9IGNvdW50KCRhbnN3ZXJzKSkgewogICAgICAgIGRpZSgi0KfQuNGB0LvQviDQvtGC0LLQtdGC0L7QsiDQuCDQstC+0L/RgNC+0YHQvtCyINC90LUg0YHQvtCy0L/QsNC00LDQtdGCXG4iKTsKICAgIH0KCiAgICAkcG9pbnRzVG90YWwgPSAwOwogICAgJHBvaW50c01heCA9IDA7CiAgICAkY29ycmVjdEFuc3dlcnMgPSAwOwoKICAgICR0b3RhbFF1ZXN0aW9ucyA9IGNvdW50KCRxdWVzdGlvbnMpOwoKICAgIGZvciAoJGkgPSAwOyAkaSA8IGNvdW50KCRxdWVzdGlvbnMpOyAkaSsrKSB7CgogICAgICAgICRxdWVzdGlvbiA9ICRxdWVzdGlvbnNbJGldOwogICAgICAgICRhbnN3ZXIgPSAkYW5zd2Vyc1skaV07CgogICAgICAgIGxpc3QoJGlzQ29ycmVjdCwgJGlzQWxtb3N0Q29ycmVjdCkgPSAkcXVlc3Rpb24tPmNoZWNrQW5zd2VyKCRhbnN3ZXIpOwogICAgICAgICRwb2ludHMgPSAkcXVlc3Rpb24tPmdldFBvaW50cygpOwoKICAgICAgICAkcG9pbnRzTWF4ICs9ICRwb2ludHM7CgogICAgICAgIGlmICgkaXNDb3JyZWN0KSB7CgogICAgICAgICAgICAkY29ycmVjdEFuc3dlcnMgKys7CiAgICAgICAgICAgICRwb2ludHNUb3RhbCArPSAkcG9pbnRzOwoKICAgICAgICB9IGVsc2VpZiAoJGlzQWxtb3N0Q29ycmVjdCkgewoKICAgICAgICAJJGNvcnJlY3RBbnN3ZXJzICsrOwogICAgICAgICAgICAkcG9pbnRzVG90YWwgKz0gJHBvaW50cyAvIDI7CgogICAgICAgIH0gZWxzZSB7CgogICAgICAgICAgICAkbnVtYmVyID0gJGkgKyAxOwogICAgICAgICAgICBlY2hvICJcbtCd0LXQv9GA0LDQstC40LvRjNC90YvQuSDQvtGC0LLQtdGCINC90LAg0LLQvtC/0YDQvtGBIOKElnskbnVtYmVyfSAoeyRxdWVzdGlvbi0+Z2V0UXVlc3Rpb25UZXh0KCl9KVxuIjsKCQkJZWNobyAiXG7Qn9C+0LTRgdC60LDQt9C60LA6IHskcXVlc3Rpb24tPmdldFF1ZXN0aW9uSGludCgpfVxuIjsKCiAgICAgICAgfQoKICAgIH0KCiAgICBlY2hvICJcbtCf0YDQsNCy0LjQu9GM0L3Ri9GFINC+0YLQstC10YLQvtCyOiB7JGNvcnJlY3RBbnN3ZXJzfSDQuNC3IHskdG90YWxRdWVzdGlvbnN9LCDQsdCw0LvQu9C+0LIg0L3QsNCx0YDQsNC90L46ICRwb2ludHNUb3RhbCDQuNC3ICRwb2ludHNNYXhcbiI7Cn0KCiRxdWVzdGlvbnMgPSBjcmVhdGVRdWVzdGlvbnMoKTsKcHJpbnRRdWVzdGlvbnMoJHF1ZXN0aW9ucyk7CmNoZWNrQW5zd2VycygkcXVlc3Rpb25zLCBhcnJheSgnYicsICdkJywgJ2InLCAyOTk3OTIsIDMuMTQ0NDQsIDE5NDQpKTs=