<?php //департаменты и сотрудники
$departmentNames = array("закупок","продаж","рекламы","логистики");
$listOfWorkersDep["закупок"] = array("ме1"=>9,"ме2"=>3,"ме3"=>2, "ма1"=>2,"ма2"=>0,"ма3"=>0,
"ин1"=>0,"ин2"=>0,"ин3"=>0,
"аа1"=>0,"ан2"=>0,"ан3"=>0);
$listOfWorkersDep["продаж"] = array("ме1"=>12,"ме2"=>0,"ме3"=>0, "мар1"=>6,"ма2"=>0,"ма3"=>0,
"ин1"=>0,"ин2"=>0,"ин3"=>0,
"ан1"=>3,"ан2"=>2,"ан3"=>0);
$listOfWorkersDep["рекламы"] = array("ме1"=>8,"ме2"=>0,"ме3"=>0, "ма1"=>15,"ма2"=>10,"ма3"=>0,
"ин1"=>2,"ин2"=>0,"ин3"=>0,
"ан1"=>0,"ан2"=>0,"ан3"=>0);
$listOfWorkersDep["логистики"] = array("ме1"=>13,"мен2"=>5,"ме3"=>0, "мар1"=>0,"ма2"=>0,"ма3"=>0,
"ин1"=>5,"ин2"=>0,"ин3"=>0,
"ан1"=>0,"ан2"=>0,"ан3"=>0);
class Department
{
protected $name;
protected $listOfWorkers = array(); protected $numberOfWorkers = 0;
public function __construct( $name )
{
$this->name = $name;
}
public function addWorker( Worker $newWorker )
{
$this->listOfWorkers[] = $newWorker;
$this->numberOfWorkers++;
}
public function getName()
{
return $this->name;
}
public function summonWorkers( $quantity, $type, $rank, $leadership )
{
for( $i=0;$i<$quantity;$i++ )
{
switch($type)
{
case 1:
$this->listOfWorkers[] = new Manager( $this, $rank, $leadership );
case 2:
$this->listOfWorkers[] = new Marketer( $this, $rank, $leadership );
case 3:
$this->listOfWorkers[] = new Engineer( $this, $rank, $leadership );
case 4:
$this->listOfWorkers[] = new Analyst( $this, $rank, $leadership );
}
}
}
public function getWorkersInfos()
{
foreach( $this->listOfWorkers as $number=>$worker )
{
$worker->getInfos();
}
}
public function getTotalWorkers()
{
return $this->numberOfWorkers;
}
public function getTotalSalary()
{
$totalSalary = 0;
foreach( $this->listOfWorkers as $number=>$worker )
{
$totalSalary += $worker->getSalary();
}
return $totalSalary;
}
public function getTotalCoffeeConsumption()
{
$totalCoffee = 0;
foreach( $this->listOfWorkers as $number=>$worker )
{
$totalCoffee += $worker->getCoffeeConsumption();
}
return $totalCoffee;
}
public function getTotalProduction()
{
$totalProduction = 0;
foreach( $this->listOfWorkers as $number=>$worker )
{
$totalProduction += $worker->getProduction();
}
return $totalProduction;
}
public function getDepartmentInfos()
{
return array($this->name, $this->getTotalWorkers(),
$this->getTotalSalary(),
$this->getTotalCoffeeConsumption(),
$this->getTotalProduction(),
round($this->getTotalSalary()/$this->getTotalProduction(),2)); }
}
abstract class Worker
{
protected $department;
protected $rank;
protected $isChief;
protected $baseSalary;
protected $coffeeConsumptionRate;
protected $productionPerMount;
protected $productionType;
public function __construct( Department $department, $rank, $chief )
{
$this->department = $department->getName();
$this->rank = $rank;
$this->isChief = $chief;
$department->addWorker($this);
}
public function getCoffeeConsumption()
{
if ( $this->isChief )
{
$coffee = $this->coffeeConsumptionRate*2;
}
else
{
$coffee = $this->coffeeConsumptionRate;
}
return $coffee;
}
public function getSalary()
{
switch( $this->rank )
{
case 1:
$salary = $this->baseSalary;
break;
case 2:
$salary = $this->baseSalary*1.25;
break;
case 3:
$salary = $this->baseSalary*1.5;
break;
}
if( $this->isChief )
{
$salary*= 1.5;
}
return $salary;
}
public function getProduction()
{
return $this->productionPerMount;
}
public function getInfos()
{
echo $this->rank;
echo "-го уровня ";
if ($this->isChief)
{
echo "и начальник ";
}
echo "департамента ";
echo $this->department;
echo ", зарплата ";
echo $this->getSalary();
echo " тугриков в месяц, выпивает ";
echo $this->getCoffeeConsumption();
echo " литров кофе в месяц\n";
}
}
class Manager extends Worker
{
protected $coffeeConsumptionRate = 20;
protected $baseSalary = 500;
protected $productionPerMount = 200;
protected $productionType = "страница отчёта";
public function getInfos()
{
echo "Это менеджер ";
parent::getInfos();
}
}
class Marketer extends Worker
{
protected $coffeeConsumptionRate = 15;
protected $baseSalary = 400;
protected $productionPerMount = 150;
protected $productionType = "страница отчёта";
public function getInfos()
{
echo "Это маркетолог ";
parent::getInfos();
}
}
class Engineer extends Worker
{
protected $coffeeConsumptionRate = 5;
protected $baseSalary = 200;
protected $productionPerMount = 50;
protected $productionType = "страница чертёжа";
public function getInfos()
{
echo "Это инженер ";
parent::getInfos();
}
}
class Analyst extends Worker
{
protected $coffeeConsumptionRate = 50;
protected $baseSalary = 800;
protected $productionPerMount = 5;
protected $productionType = "стратегическое исследование";
public function getInfos()
{
echo "Это аналитик ";
parent::getInfos();
}
}
function padLeft( $string,$columns )
{
}
function printInfos( $arrayOfSomething,$columns )
{
foreach( $arrayOfSomething as $number=>$data )
{
echo padLeft( $data,$columns );
}
echo "\n";
}
$departmentList = array(); foreach( $departmentNames as $i=>$name )
{
$departmentList[$name] = new Department($name);
}
foreach( $departmentNames as $i=>$name ) //вносим работников в департаменты
{
$workers = $listOfWorkersDep[$name];
foreach( $workers as $key=>$num)
{
if ( $num > 0 )
{
switch($key)
{
case "ме1":
for ( $i=0;$i<$num;$i++ )
{
new Manager( $departmentList[$name], 1, false );
}
break;
case "ме2":
for ( $i=0;$i<$num;$i++ )
{
new Manager( $departmentList[$name], 2, false );
}
break;
case "ме3":
for ( $i=0;$i<$num;$i++ )
{
new Manager( $departmentList[$name], 3, false );
}
break;
case "ма1":
for ( $i=0;$i<$num;$i++ )
{
new Marketer( $departmentList[$name], 1, false );
}
break;
case "ма2":
for ( $i=0;$i<$num;$i++ )
{
new Marketer( $departmentList[$name], 2, false );
}
break;
case "ма3":
for ( $i=0;$i<$num;$i++ )
{
new Marketer( $departmentList[$name], 3, false );
}
break;
case "ин1":
for ( $i=0;$i<$num;$i++ )
{
new Engineer( $departmentList[$name], 1, false );
}
break;
case "ин2":
for ( $i=0;$i<$num;$i++ )
{
new Engineer( $departmentList[$name], 2, false );
}
break;
case "ин3":
for ( $i=0;$i<$num;$i++ )
{
new Engineer( $departmentList[$name], 3, false );
}
break;
case "ан1":
for ( $i=0;$i<$num;$i++ )
{
new Analyst( $departmentList[$name], 1, false );
}
break;
case "ан2":
for ( $i=0;$i<$num;$i++ )
{
new Analyst( $departmentList[$name], 2, false );
}
break;
case "ан3":
for ( $i=0;$i<$num;$i++ )
{
new Analyst( $departmentList[$name], 3, false );
}
break;
}
}
}
}
//добавляем начальников департаментов
new Manager( $departmentList["закупок"], 2, true );
new Marketer( $departmentList["продаж"], 2, true );
new Marketer( $departmentList["рекламы"], 3, true );
new Manager( $departmentList["логистики"], 1, true );
printInfos
(array("Департамент","Работников","Зарплата","Расход кофе","Результат(стр)","Расход на стр"),15);
foreach( $departmentNames as $i=>$name )
{
$arrayOfInfos[$i]=$departmentList[$name]->getDepartmentInfos();
printInfos($arrayOfInfos[$i],15);
}
$totalInfos = array("итого",0,0,0,0,0);
foreach( $arrayOfInfos as $key=>$data )
{
for( $i=1;$i<6;$i++ )
{
$totalInfos[$i] += $data[$i];
}
}
$totalInfos[5] = round($totalInfos[2]/$totalInfos[4],2);
printInfos($totalInfos,15);
PD9waHAgLy/QtNC10L/QsNGA0YLQsNC80LXQvdGC0Ysg0Lgg0YHQvtGC0YDRg9C00L3QuNC60LgKIAoKZXJyb3JfcmVwb3J0aW5nKC0xKTsKbWJfaW50ZXJuYWxfZW5jb2RpbmcoJ3V0Zi04Jyk7CgkKCiRkZXBhcnRtZW50TmFtZXMgPSBhcnJheSgi0LfQsNC60YPQv9C+0LoiLCLQv9GA0L7QtNCw0LYiLCLRgNC10LrQu9Cw0LzRiyIsItC70L7Qs9C40YHRgtC40LrQuCIpOwoKJGxpc3RPZldvcmtlcnNEZXBbItC30LDQutGD0L/QvtC6Il0gPSBhcnJheSgi0LzQtTEiPT45LCLQvNC1MiI9PjMsItC80LUzIj0+MiwKCQkJCQkJCQki0LzQsDEiPT4yLCLQvNCwMiI9PjAsItC80LAzIj0+MCwKCQkJCQkJCQki0LjQvTEiPT4wLCLQuNC9MiI9PjAsItC40L0zIj0+MCwKCQkJCQkJCQki0LDQsDEiPT4wLCLQsNC9MiI9PjAsItCw0L0zIj0+MCk7CiRsaXN0T2ZXb3JrZXJzRGVwWyLQv9GA0L7QtNCw0LYiXSA9IGFycmF5KCLQvNC1MSI9PjEyLCLQvNC1MiI9PjAsItC80LUzIj0+MCwKCQkJCQkJCQki0LzQsNGAMSI9PjYsItC80LAyIj0+MCwi0LzQsDMiPT4wLAoJCQkJCQkJCSLQuNC9MSI9PjAsItC40L0yIj0+MCwi0LjQvTMiPT4wLAoJCQkJCQkJCSLQsNC9MSI9PjMsItCw0L0yIj0+Miwi0LDQvTMiPT4wKTsKJGxpc3RPZldvcmtlcnNEZXBbItGA0LXQutC70LDQvNGLIl0gPSBhcnJheSgi0LzQtTEiPT44LCLQvNC1MiI9PjAsItC80LUzIj0+MCwKCQkJCQkJCQki0LzQsDEiPT4xNSwi0LzQsDIiPT4xMCwi0LzQsDMiPT4wLAoJCQkJCQkJCSLQuNC9MSI9PjIsItC40L0yIj0+MCwi0LjQvTMiPT4wLAoJCQkJCQkJCSLQsNC9MSI9PjAsItCw0L0yIj0+MCwi0LDQvTMiPT4wKTsKJGxpc3RPZldvcmtlcnNEZXBbItC70L7Qs9C40YHRgtC40LrQuCJdID0gYXJyYXkoItC80LUxIj0+MTMsItC80LXQvTIiPT41LCLQvNC1MyI9PjAsCgkJCQkJCQkJItC80LDRgDEiPT4wLCLQvNCwMiI9PjAsItC80LAzIj0+MCwKCQkJCQkJCQki0LjQvTEiPT41LCLQuNC9MiI9PjAsItC40L0zIj0+MCwKCQkJCQkJCQki0LDQvTEiPT4wLCLQsNC9MiI9PjAsItCw0L0zIj0+MCk7CgoKCmNsYXNzIERlcGFydG1lbnQgCnsKCXByb3RlY3RlZCAkbmFtZTsKCXByb3RlY3RlZCAkbGlzdE9mV29ya2VycyA9IGFycmF5KCk7Cglwcm90ZWN0ZWQgJG51bWJlck9mV29ya2VycyA9IDA7CgkKCQoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCAkbmFtZSApCgl7CgkJJHRoaXMtPm5hbWUgPSAkbmFtZTsKCX0KCQoJcHVibGljIGZ1bmN0aW9uIGFkZFdvcmtlciggV29ya2VyICRuZXdXb3JrZXIgKQoJewoJCSR0aGlzLT5saXN0T2ZXb3JrZXJzW10gPSAkbmV3V29ya2VyOwoJCSR0aGlzLT5udW1iZXJPZldvcmtlcnMrKzsKCX0KCQoJcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKQoJewoJCXJldHVybiAkdGhpcy0+bmFtZTsKCX0KCQoJcHVibGljIGZ1bmN0aW9uIHN1bW1vbldvcmtlcnMoICRxdWFudGl0eSwgJHR5cGUsICRyYW5rLCAkbGVhZGVyc2hpcCApCgl7CgkJJGxpc3QgPSBhcnJheSgpOwoJCWZvciggJGk9MDskaTwkcXVhbnRpdHk7JGkrKyApCgkJewoJCQlzd2l0Y2goJHR5cGUpCgkJCXsKCQkJCWNhc2UgMTogCgkJCQkJJHRoaXMtPmxpc3RPZldvcmtlcnNbXSA9IG5ldyBNYW5hZ2VyKCAkdGhpcywgJHJhbmssICRsZWFkZXJzaGlwICk7CgkJCQljYXNlIDI6IAoJCQkJCSR0aGlzLT5saXN0T2ZXb3JrZXJzW10gPSBuZXcgTWFya2V0ZXIoICR0aGlzLCAkcmFuaywgJGxlYWRlcnNoaXAgKTsKCQkJCWNhc2UgMzoKCQkJCQkkdGhpcy0+bGlzdE9mV29ya2Vyc1tdID0gbmV3IEVuZ2luZWVyKCAkdGhpcywgJHJhbmssICRsZWFkZXJzaGlwICk7CgkJCQljYXNlIDQ6CgkJCQkJJHRoaXMtPmxpc3RPZldvcmtlcnNbXSA9IG5ldyBBbmFseXN0KCAkdGhpcywgJHJhbmssICRsZWFkZXJzaGlwICk7CgkJCX0KCQl9Cgl9CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRXb3JrZXJzSW5mb3MoKQoJewoJCWZvcmVhY2goICR0aGlzLT5saXN0T2ZXb3JrZXJzIGFzICRudW1iZXI9PiR3b3JrZXIgKQoJCXsKCQkJJHdvcmtlci0+Z2V0SW5mb3MoKTsKCQl9Cgl9CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRUb3RhbFdvcmtlcnMoKQoJewoJCXJldHVybiAkdGhpcy0+bnVtYmVyT2ZXb3JrZXJzOwoJfQoJCglwdWJsaWMgZnVuY3Rpb24gZ2V0VG90YWxTYWxhcnkoKQoJewoJCSR0b3RhbFNhbGFyeSA9IDA7CgkJZm9yZWFjaCggJHRoaXMtPmxpc3RPZldvcmtlcnMgYXMgJG51bWJlcj0+JHdvcmtlciApCgkJewoJCQkkdG90YWxTYWxhcnkgKz0gJHdvcmtlci0+Z2V0U2FsYXJ5KCk7CgkJfQoJCXJldHVybiAkdG90YWxTYWxhcnk7Cgl9CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRUb3RhbENvZmZlZUNvbnN1bXB0aW9uKCkKCXsKCQkkdG90YWxDb2ZmZWUgPSAwOwoJCWZvcmVhY2goICR0aGlzLT5saXN0T2ZXb3JrZXJzIGFzICRudW1iZXI9PiR3b3JrZXIgKQoJCXsKCQkJJHRvdGFsQ29mZmVlICs9ICR3b3JrZXItPmdldENvZmZlZUNvbnN1bXB0aW9uKCk7CgkJfQoJCXJldHVybiAkdG90YWxDb2ZmZWU7Cgl9CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRUb3RhbFByb2R1Y3Rpb24oKQoJewoJCSR0b3RhbFByb2R1Y3Rpb24gPSAwOwoJCWZvcmVhY2goICR0aGlzLT5saXN0T2ZXb3JrZXJzIGFzICRudW1iZXI9PiR3b3JrZXIgKQoJCXsKCQkJJHRvdGFsUHJvZHVjdGlvbiArPSAkd29ya2VyLT5nZXRQcm9kdWN0aW9uKCk7CgkJfQoJCXJldHVybiAkdG90YWxQcm9kdWN0aW9uOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXREZXBhcnRtZW50SW5mb3MoKQoJewoJCXJldHVybiBhcnJheSgkdGhpcy0+bmFtZSwKCQkJCQkkdGhpcy0+Z2V0VG90YWxXb3JrZXJzKCksCgkJCQkJJHRoaXMtPmdldFRvdGFsU2FsYXJ5KCksCgkJCQkJJHRoaXMtPmdldFRvdGFsQ29mZmVlQ29uc3VtcHRpb24oKSwKCQkJCQkkdGhpcy0+Z2V0VG90YWxQcm9kdWN0aW9uKCksCgkJCQkJcm91bmQoJHRoaXMtPmdldFRvdGFsU2FsYXJ5KCkvJHRoaXMtPmdldFRvdGFsUHJvZHVjdGlvbigpLDIpKTsKCX0KfQoKYWJzdHJhY3QgY2xhc3MgCVdvcmtlcgp7Cglwcm90ZWN0ZWQgJGRlcGFydG1lbnQ7CQoJcHJvdGVjdGVkICRyYW5rOwoJcHJvdGVjdGVkICRpc0NoaWVmOwoJcHJvdGVjdGVkICRiYXNlU2FsYXJ5OwoJcHJvdGVjdGVkICRjb2ZmZWVDb25zdW1wdGlvblJhdGU7Cglwcm90ZWN0ZWQgJHByb2R1Y3Rpb25QZXJNb3VudDsKCXByb3RlY3RlZCAkcHJvZHVjdGlvblR5cGU7CgkKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCggRGVwYXJ0bWVudCAkZGVwYXJ0bWVudCwgJHJhbmssICRjaGllZiApCgl7CgkJJHRoaXMtPmRlcGFydG1lbnQgPSAkZGVwYXJ0bWVudC0+Z2V0TmFtZSgpOwoJCSR0aGlzLT5yYW5rID0gJHJhbms7CgkJJHRoaXMtPmlzQ2hpZWYgPSAkY2hpZWY7CgkJJGRlcGFydG1lbnQtPmFkZFdvcmtlcigkdGhpcyk7Cgl9CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRDb2ZmZWVDb25zdW1wdGlvbigpCgl7CgkJaWYgKCAkdGhpcy0+aXNDaGllZiApCgkJewoJCQkkY29mZmVlID0gJHRoaXMtPmNvZmZlZUNvbnN1bXB0aW9uUmF0ZSoyOwoJCX0KCQllbHNlCgkJewoJCQkkY29mZmVlID0gJHRoaXMtPmNvZmZlZUNvbnN1bXB0aW9uUmF0ZTsKCQl9CgkJcmV0dXJuICRjb2ZmZWU7Cgl9CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRTYWxhcnkoKQoJewoJCXN3aXRjaCggJHRoaXMtPnJhbmsgKQoJCXsKCQkJY2FzZSAxOgoJCQkJJHNhbGFyeSA9ICR0aGlzLT5iYXNlU2FsYXJ5OwoJCQkJYnJlYWs7CgkJCWNhc2UgMjoKCQkJCSRzYWxhcnkgPSAkdGhpcy0+YmFzZVNhbGFyeSoxLjI1OwoJCQkJYnJlYWs7CgkJCWNhc2UgMzogCgkJCQkkc2FsYXJ5ID0gJHRoaXMtPmJhc2VTYWxhcnkqMS41OwoJCQkJYnJlYWs7CgkJfQoJCQoJCWlmKCAkdGhpcy0+aXNDaGllZiApCgkJewoJCQkkc2FsYXJ5Kj0gMS41OwoJCX0KCQkKCQlyZXR1cm4gJHNhbGFyeTsKCX0KCQoJcHVibGljIGZ1bmN0aW9uIGdldFByb2R1Y3Rpb24oKQoJewoJCXJldHVybiAkdGhpcy0+cHJvZHVjdGlvblBlck1vdW50OwoJfQoJCglwdWJsaWMgZnVuY3Rpb24gZ2V0SW5mb3MoKQoJewoJCWVjaG8gJHRoaXMtPnJhbms7CgkJZWNobyAiLdCz0L4g0YPRgNC+0LLQvdGPICI7IAoJCWlmICgkdGhpcy0+aXNDaGllZikKCQl7CgkJCWVjaG8gItC4INC90LDRh9Cw0LvRjNC90LjQuiAiOwoJCX0KCQllY2hvICLQtNC10L/QsNGA0YLQsNC80LXQvdGC0LAgIjsKCQllY2hvICR0aGlzLT5kZXBhcnRtZW50OwoJCWVjaG8gIiwg0LfQsNGA0L/Qu9Cw0YLQsCAiOwoJCWVjaG8gJHRoaXMtPmdldFNhbGFyeSgpOwoJCWVjaG8gIiDRgtGD0LPRgNC40LrQvtCyINCyINC80LXRgdGP0YYsINCy0YvQv9C40LLQsNC10YIgIjsKCQllY2hvICR0aGlzLT5nZXRDb2ZmZWVDb25zdW1wdGlvbigpOwoJCWVjaG8gIiDQu9C40YLRgNC+0LIg0LrQvtGE0LUg0LIg0LzQtdGB0Y/RhlxuIjsKCX0KfQoKY2xhc3MgTWFuYWdlciBleHRlbmRzIFdvcmtlcgp7Cglwcm90ZWN0ZWQgJGNvZmZlZUNvbnN1bXB0aW9uUmF0ZSA9IDIwOwoJcHJvdGVjdGVkICRiYXNlU2FsYXJ5ID0gNTAwOwoJcHJvdGVjdGVkICRwcm9kdWN0aW9uUGVyTW91bnQgPSAyMDA7Cglwcm90ZWN0ZWQgJHByb2R1Y3Rpb25UeXBlID0gItGB0YLRgNCw0L3QuNGG0LAg0L7RgtGH0ZHRgtCwIjsKCglwdWJsaWMgZnVuY3Rpb24gZ2V0SW5mb3MoKQoJewoJCWVjaG8gItCt0YLQviDQvNC10L3QtdC00LbQtdGAICI7CgkJcGFyZW50OjpnZXRJbmZvcygpOwoJfQp9CgpjbGFzcyBNYXJrZXRlciBleHRlbmRzIFdvcmtlcgp7Cglwcm90ZWN0ZWQgJGNvZmZlZUNvbnN1bXB0aW9uUmF0ZSA9IDE1OwoJcHJvdGVjdGVkICRiYXNlU2FsYXJ5ID0gNDAwOwoJcHJvdGVjdGVkICRwcm9kdWN0aW9uUGVyTW91bnQgPSAxNTA7Cglwcm90ZWN0ZWQgJHByb2R1Y3Rpb25UeXBlID0gItGB0YLRgNCw0L3QuNGG0LAg0L7RgtGH0ZHRgtCwIjsKCQoJcHVibGljIGZ1bmN0aW9uIGdldEluZm9zKCkKCXsKCQllY2hvICLQrdGC0L4g0LzQsNGA0LrQtdGC0L7Qu9C+0LMgIjsKCQlwYXJlbnQ6OmdldEluZm9zKCk7Cgl9Cn0KCmNsYXNzIEVuZ2luZWVyIGV4dGVuZHMgV29ya2VyCnsKCXByb3RlY3RlZCAkY29mZmVlQ29uc3VtcHRpb25SYXRlID0gNTsKCXByb3RlY3RlZCAkYmFzZVNhbGFyeSA9IDIwMDsKCXByb3RlY3RlZCAkcHJvZHVjdGlvblBlck1vdW50ID0gNTA7Cglwcm90ZWN0ZWQgJHByb2R1Y3Rpb25UeXBlID0gItGB0YLRgNCw0L3QuNGG0LAg0YfQtdGA0YLRkdC20LAiOwoJCglwdWJsaWMgZnVuY3Rpb24gZ2V0SW5mb3MoKQoJewoJCWVjaG8gItCt0YLQviDQuNC90LbQtdC90LXRgCAiOwoJCXBhcmVudDo6Z2V0SW5mb3MoKTsKCX0KfQoKY2xhc3MgQW5hbHlzdCBleHRlbmRzIFdvcmtlcgp7Cglwcm90ZWN0ZWQgJGNvZmZlZUNvbnN1bXB0aW9uUmF0ZSA9IDUwOwoJcHJvdGVjdGVkICRiYXNlU2FsYXJ5ID0gODAwOwoJcHJvdGVjdGVkICRwcm9kdWN0aW9uUGVyTW91bnQgPSA1OwoJcHJvdGVjdGVkICRwcm9kdWN0aW9uVHlwZSA9ICLRgdGC0YDQsNGC0LXQs9C40YfQtdGB0LrQvtC1INC40YHRgdC70LXQtNC+0LLQsNC90LjQtSI7CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRJbmZvcygpCgl7CgkJZWNobyAi0K3RgtC+INCw0L3QsNC70LjRgtC40LogIjsKCQlwYXJlbnQ6OmdldEluZm9zKCk7Cgl9Cn0KCgpmdW5jdGlvbiBwYWRMZWZ0KCAkc3RyaW5nLCRjb2x1bW5zICkKewoJcmV0dXJuIHN0cl9yZXBlYXQoIiAiLCRjb2x1bW5zLW1iX3N0cmxlbigkc3RyaW5nKSkuJHN0cmluZzsKfQoKZnVuY3Rpb24gcHJpbnRJbmZvcyggJGFycmF5T2ZTb21ldGhpbmcsJGNvbHVtbnMgKQp7Cglmb3JlYWNoKCAkYXJyYXlPZlNvbWV0aGluZyBhcyAkbnVtYmVyPT4kZGF0YSApCgl7CgkJZWNobyBwYWRMZWZ0KCAkZGF0YSwkY29sdW1ucyApOwoJfQoJZWNobyAiXG4iOwp9CgoKCgokZGVwYXJ0bWVudExpc3QgPSBhcnJheSgpOwpmb3JlYWNoKCAkZGVwYXJ0bWVudE5hbWVzIGFzICRpPT4kbmFtZSApCnsKCSRkZXBhcnRtZW50TGlzdFskbmFtZV0gPSBuZXcgRGVwYXJ0bWVudCgkbmFtZSk7Cn0KCmZvcmVhY2goICRkZXBhcnRtZW50TmFtZXMgYXMgJGk9PiRuYW1lICkJCQkJCQkJCQkJLy/QstC90L7RgdC40Lwg0YDQsNCx0L7RgtC90LjQutC+0LIg0LIg0LTQtdC/0LDRgNGC0LDQvNC10L3RgtGLCnsKCSR3b3JrZXJzID0gJGxpc3RPZldvcmtlcnNEZXBbJG5hbWVdOwoJZm9yZWFjaCggJHdvcmtlcnMgYXMgJGtleT0+JG51bSkKCXsKCQlpZiAoICRudW0gPiAwICkKCQl7CgkJCXN3aXRjaCgka2V5KQoJCQl7CgkJCQljYXNlICLQvNC1MSI6CgkJCQkJZm9yICggJGk9MDskaTwkbnVtOyRpKysgKQoJCQkJCXsKCQkJCQkJbmV3IE1hbmFnZXIoICRkZXBhcnRtZW50TGlzdFskbmFtZV0sIDEsIGZhbHNlICk7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSAi0LzQtTIiOgoJCQkJCWZvciAoICRpPTA7JGk8JG51bTskaSsrICkKCQkJCQl7CgkJCQkJCW5ldyBNYW5hZ2VyKCAkZGVwYXJ0bWVudExpc3RbJG5hbWVdLCAyLCBmYWxzZSApOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgItC80LUzIjoKCQkJCQlmb3IgKCAkaT0wOyRpPCRudW07JGkrKyApCgkJCQkJewoJCQkJCQluZXcgTWFuYWdlciggJGRlcGFydG1lbnRMaXN0WyRuYW1lXSwgMywgZmFsc2UgKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlICLQvNCwMSI6CgkJCQkJZm9yICggJGk9MDskaTwkbnVtOyRpKysgKQoJCQkJCXsKCQkJCQkJbmV3IE1hcmtldGVyKCAkZGVwYXJ0bWVudExpc3RbJG5hbWVdLCAxLCBmYWxzZSApOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgItC80LAyIjoKCQkJCQlmb3IgKCAkaT0wOyRpPCRudW07JGkrKyApCgkJCQkJewoJCQkJCQluZXcgTWFya2V0ZXIoICRkZXBhcnRtZW50TGlzdFskbmFtZV0sIDIsIGZhbHNlICk7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSAi0LzQsDMiOgoJCQkJCWZvciAoICRpPTA7JGk8JG51bTskaSsrICkKCQkJCQl7CgkJCQkJCW5ldyBNYXJrZXRlciggJGRlcGFydG1lbnRMaXN0WyRuYW1lXSwgMywgZmFsc2UgKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlICLQuNC9MSI6CgkJCQkJZm9yICggJGk9MDskaTwkbnVtOyRpKysgKQoJCQkJCXsKCQkJCQkJbmV3IEVuZ2luZWVyKCAkZGVwYXJ0bWVudExpc3RbJG5hbWVdLCAxLCBmYWxzZSApOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgItC40L0yIjoKCQkJCQlmb3IgKCAkaT0wOyRpPCRudW07JGkrKyApCgkJCQkJewoJCQkJCQluZXcgRW5naW5lZXIoICRkZXBhcnRtZW50TGlzdFskbmFtZV0sIDIsIGZhbHNlICk7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSAi0LjQvTMiOgoJCQkJCWZvciAoICRpPTA7JGk8JG51bTskaSsrICkKCQkJCQl7CgkJCQkJCW5ldyBFbmdpbmVlciggJGRlcGFydG1lbnRMaXN0WyRuYW1lXSwgMywgZmFsc2UgKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlICLQsNC9MSI6CgkJCQkJZm9yICggJGk9MDskaTwkbnVtOyRpKysgKQoJCQkJCXsKCQkJCQkJbmV3IEFuYWx5c3QoICRkZXBhcnRtZW50TGlzdFskbmFtZV0sIDEsIGZhbHNlICk7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSAi0LDQvTIiOgoJCQkJCWZvciAoICRpPTA7JGk8JG51bTskaSsrICkKCQkJCQl7CgkJCQkJCW5ldyBBbmFseXN0KCAkZGVwYXJ0bWVudExpc3RbJG5hbWVdLCAyLCBmYWxzZSApOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgItCw0L0zIjoKCQkJCQlmb3IgKCAkaT0wOyRpPCRudW07JGkrKyApCgkJCQkJewoJCQkJCQluZXcgQW5hbHlzdCggJGRlcGFydG1lbnRMaXN0WyRuYW1lXSwgMywgZmFsc2UgKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9Cn0KCi8v0LTQvtCx0LDQstC70Y/QtdC8INC90LDRh9Cw0LvRjNC90LjQutC+0LIg0LTQtdC/0LDRgNGC0LDQvNC10L3RgtC+0LIKbmV3IE1hbmFnZXIoICRkZXBhcnRtZW50TGlzdFsi0LfQsNC60YPQv9C+0LoiXSwgMiwgdHJ1ZSApOwpuZXcgTWFya2V0ZXIoICRkZXBhcnRtZW50TGlzdFsi0L/RgNC+0LTQsNC2Il0sIDIsIHRydWUgKTsKbmV3IE1hcmtldGVyKCAkZGVwYXJ0bWVudExpc3RbItGA0LXQutC70LDQvNGLIl0sIDMsIHRydWUgKTsKbmV3IE1hbmFnZXIoICRkZXBhcnRtZW50TGlzdFsi0LvQvtCz0LjRgdGC0LjQutC4Il0sIDEsIHRydWUgKTsKCgoKcHJpbnRJbmZvcyhhcnJheSgi0JTQtdC/0LDRgNGC0LDQvNC10L3RgiIsItCg0LDQsdC+0YLQvdC40LrQvtCyIiwi0JfQsNGA0L/Qu9Cw0YLQsCIsItCg0LDRgdGF0L7QtCDQutC+0YTQtSIsItCg0LXQt9GD0LvRjNGC0LDRgijRgdGC0YApIiwi0KDQsNGB0YXQvtC0INC90LAg0YHRgtGAIiksMTUpOwoKZm9yZWFjaCggJGRlcGFydG1lbnROYW1lcyBhcyAkaT0+JG5hbWUgKQp7CgkkYXJyYXlPZkluZm9zWyRpXT0kZGVwYXJ0bWVudExpc3RbJG5hbWVdLT5nZXREZXBhcnRtZW50SW5mb3MoKTsKCXByaW50SW5mb3MoJGFycmF5T2ZJbmZvc1skaV0sMTUpOwp9CgokdG90YWxJbmZvcyA9IGFycmF5KCLQuNGC0L7Qs9C+IiwwLDAsMCwwLDApOwoKZm9yZWFjaCggJGFycmF5T2ZJbmZvcyBhcyAka2V5PT4kZGF0YSApCnsKCWZvciggJGk9MTskaTw2OyRpKysgKQoJewoJCSR0b3RhbEluZm9zWyRpXSArPSAkZGF0YVskaV07Cgl9Cn0KCiR0b3RhbEluZm9zWzVdID0gcm91bmQoJHRvdGFsSW5mb3NbMl0vJHRvdGFsSW5mb3NbNF0sMik7CgpwcmludEluZm9zKCR0b3RhbEluZm9zLDE1KTsKCgoKCgo=