<?php
/**
* input.php
*/
$input = [
// count, profession, grade, [chief]
'Purchasing' => [
[9, Employee::MANAGER, 1],
[3, Employee::MANAGER, 2],
[2, Employee::MANAGER, 3],
[2, Employee::MARKETER, 1],
[1, Employee::MANAGER, 2, true]
],
'Sales' => [
[12, Employee::MANAGER, 1],
[6, Employee::MARKETER, 1],
[3, Employee::ANALYST, 1],
[2, Employee::ANALYST, 2],
[1, Employee::MARKETER, 2, true]
],
'Advertising' => [
[15, Employee::MARKETER, 1],
[10, Employee::MARKETER, 2],
[8, Employee::MANAGER, 1],
[2, Employee::ENGINEER, 1],
[1, Employee::MARKETER, 3, true]
],
'Logistics' => [
[13, Employee::MANAGER, 1],
[5, Employee::MANAGER, 2],
[5, Employee::ENGINEER, 1],
[1, Employee::MANAGER, 1, true]
]
];
/**
* classes.php
*/
class Company {
protected array $departments; protected int $numOfDepts;
public function __construct
(array $departments) { $this->departments = $departments;
$this->numOfDepts = count($departments); }
public function getDepartments
(): array { return $this->departments;
}
public function getTotalStaff(): int {
$staff = 0;
foreach ($this->departments as $dept) {
$staff += $dept->getStaffNumber();
}
return $staff;
}
public function getTotalLaborCost() {
$cost = 0;
foreach ($this->departments as $dept) {
$cost += $dept->getLaborCost();
}
return $cost;
}
public function getTotalCoffeeDrunk() {
$amount = 0;
foreach ($this->departments as $dept) {
$amount += $dept->getCoffeeDrunk();
}
return $amount;
}
public function getTotalPagesProduced(): int {
$pages = 0;
foreach ($this->departments as $dept) {
$pages += $dept->getPagesProduced();
}
return $pages;
}
public function getTotalCostPerPage() {
$cost = 0;
foreach ($this->departments as $dept) {
$cost += $dept->getCostPerPage();
}
return $cost;
}
public function getAverageStaff() {
$staff = 0;
foreach ($this->departments as $dept) {
$staff += $dept->getStaffNumber();
}
return $staff / $this->numOfDepts;
}
public function getAverageLaborCost() {
$cost = 0;
foreach ($this->departments as $dept) {
$cost += $dept->getLaborCost();
}
return $cost / $this->numOfDepts;
}
public function getAverageCoffeeDrunk() {
$amount = 0;
foreach ($this->departments as $dept) {
$amount += $dept->getCoffeeDrunk();
}
return $amount / $this->numOfDepts;
}
public function getAveragePagesProduced() {
$pages = 0;
foreach ($this->departments as $dept) {
$pages += $dept->getPagesProduced();
}
return $pages / $this->numOfDepts;
}
public function getAverageCostPerPage() {
$cost = 0;
foreach ($this->departments as $dept) {
$cost += $dept->getCostPerPage();
}
return $cost / $this->numOfDepts;
}
}
class Department {
protected string $name;
public function __construct
(string
$name, array $employees) { $this->name = $name;
$this->staff = [];
foreach ($employees as $empGroup) {
$empQuantity = $empGroup[0];
$empType = $empGroup[1];
$empGrade = $empGroup[2]; // 1
$empChief = isset($empGroup[3]) ?
true : false; for ($c = 0; $c < $empQuantity; $c++) {
$this->staff[] = new $empType($empGrade, $empChief);
}
}
}
public function getDeptName(): string {
return $this->name;
}
public function getStaffNumber(): int {
$staffNumber = count($this->staff); return $staffNumber;
}
public function getLaborCost(): int {
$aggregateCost = 0;
foreach ($this->staff as $employee) {
$aggregateCost += $employee->getActualPay();
}
return $aggregateCost;
}
public function getCoffeeDrunk(): int {
$totalCoffeeDrunk = 0;
foreach ($this->staff as $employee) {
$totalCoffeeDrunk += $employee->getActualCoffeeConsumption();
}
return $totalCoffeeDrunk;
}
public function getPagesProduced() {
$totalPagesProduced = 0;
foreach ($this->staff as $employee) {
$totalPagesProduced += $employee->getActualPaperworkProduced();
}
return $totalPagesProduced;
}
public function getCostPerPage() {
$pages = $this->getPagesProduced();
$laborCost = $this->getLaborCost();
return round($laborCost / $pages, 2); }
}
abstract class Employee {
const MANAGER = "Manager";
const MARKETER = "Marketer";
const ENGINEER = "Engineer";
const ANALYST = "Analyst";
protected int $grade;
protected $baseRate;
protected bool $chief;
protected $baseCoffeeConsumption;
protected int $basePaperworkProduced;
public function __construct(int $grade, bool $chief = false) {
$this->grade = $grade;
$this->chief = $chief;
}
public function getActualPay() {
$rate = $this->baseRate;
if ($this->grade == 2) {
$rate *= 1.25;
} elseif ($this->grade == 3) {
$rate = $rate * 1.5;
}
return $this->chief ? $rate * 2 : $rate;
}
public function getActualCoffeeConsumption() {
return $this->chief ? $this->baseCoffeeConsumption * 2 : $this->baseCoffeeConsumption;
}
public function getActualPaperworkProduced(): int {
return $this->chief ? 0 : $this->basePaperworkProduced;
}
}
class Manager extends Employee {
protected $baseRate = 500;
protected $baseCoffeeConsumption = 20;
protected int $basePaperworkProduced = 200;
}
class Marketer extends Employee {
protected $baseRate = 400;
protected $baseCoffeeConsumption = 15;
protected int $basePaperworkProduced = 150;
}
class Engineer extends Employee {
protected $baseRate = 200;
protected $baseCoffeeConsumption = 5;
protected int $basePaperworkProduced = 50;
}
class Analyst extends Employee {
protected $baseRate = 800;
protected $baseCoffeeConsumption = 50;
protected int $basePaperworkProduced = 5;
}
/**
* padstring.php
*/
function padString($string, $length, $side = "right", $pad = " ") {
if (strlen($string) == $length) { return $string;
} else {
$charsNeeded = $length - strlen($string); $side == "right" ? ($string = $string . $padding) : ($string = $padding . $string);
return $string;
}
}
/**
* main.php
*/
include('classes.php');
include('input.php');
include('padstring.php');
$departments = [];
foreach ($input as $department => $employees) {
$departments[] = new Department($department, $employees);
}
return $departments;
}
function printReport
(array $departments) { $company = new Company($departments);
$firstCol = 20;
$regCol = 15;
echo padString('DEPARTMENT', $firstCol) . padString('STAFF', $regCol, 'left') . padString('LABOR COST', $regCol, 'left') . padString('COFFEE DRUNK', $regCol, 'left') . padString('PAGES', $regCol, 'left') . padString('COST PER PAGE', $regCol, 'left') . "\n";
echo padString('=', $firstCol, 'right', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . "\n";
foreach ($company->getDepartments() as $department) {
echo padString($department->getDeptName(), $firstCol) . padString($department->getStaffNumber(), $regCol, 'left') . padString($department->getLaborCost(), $regCol, 'left') . padString($department->getCoffeeDrunk(), $regCol, 'left') . padString($department->getPagesProduced(), $regCol, 'left') . padString($department->getCostPerPage(), $regCol, 'left') . "\n";
}
echo padString('=', $firstCol, 'right', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . padString('=', $regCol, 'left', '=') . "\n";
echo padString('TOTAL', $firstCol) . padString($company->getTotalStaff(), $regCol, 'left') . padString($company->getTotalLaborCost(), $regCol, 'left') . padString($company->getTotalCoffeeDrunk(), $regCol, 'left') . padString($company->getTotalPagesProduced(), $regCol, 'left') . padString($company->getTotalCostPerPage(), $regCol, 'left') . "\n";
echo padString('AVERAGE', $firstCol) . padString($company->getAverageStaff(), $regCol, 'left') . padString($company->getAverageLaborCost(), $regCol, 'left') . padString($company->getAverageCoffeeDrunk(), $regCol, 'left') . padString($company->getAveragePagesProduced(), $regCol, 'left') . padString($company->getAverageCostPerPage(), $regCol, 'left') . "\n";
}
$departments = getDepartments($input);
printReport($departments);
PD9waHAKIAogLyoqCiAqIGlucHV0LnBocAogKi8KCiRpbnB1dCA9IFsKCS8vIGNvdW50LCBwcm9mZXNzaW9uLCBncmFkZSwgW2NoaWVmXQoJCgknUHVyY2hhc2luZycgPT4gWwoJCVs5LCBFbXBsb3llZTo6TUFOQUdFUiwgMV0sCgkJWzMsIEVtcGxveWVlOjpNQU5BR0VSLCAyXSwKCQlbMiwgRW1wbG95ZWU6Ok1BTkFHRVIsIDNdLAoJCVsyLCBFbXBsb3llZTo6TUFSS0VURVIsIDFdLAoJCVsxLCBFbXBsb3llZTo6TUFOQUdFUiwgMiwgdHJ1ZV0KCV0sCgoJJ1NhbGVzJyA9PiBbCgkJWzEyLCBFbXBsb3llZTo6TUFOQUdFUiwgMV0sCgkJWzYsIEVtcGxveWVlOjpNQVJLRVRFUiwgMV0sCgkJWzMsIEVtcGxveWVlOjpBTkFMWVNULCAxXSwKCQlbMiwgRW1wbG95ZWU6OkFOQUxZU1QsIDJdLAoJCVsxLCBFbXBsb3llZTo6TUFSS0VURVIsIDIsIHRydWVdCgldLAoKCgknQWR2ZXJ0aXNpbmcnID0+IFsKCQlbMTUsIEVtcGxveWVlOjpNQVJLRVRFUiwgMV0sCgkJWzEwLCBFbXBsb3llZTo6TUFSS0VURVIsIDJdLAoJCVs4LCBFbXBsb3llZTo6TUFOQUdFUiwgMV0sCgkJWzIsIEVtcGxveWVlOjpFTkdJTkVFUiwgMV0sCgkJWzEsIEVtcGxveWVlOjpNQVJLRVRFUiwgMywgdHJ1ZV0KCV0sCgoKCSdMb2dpc3RpY3MnID0+IFsKCQlbMTMsIEVtcGxveWVlOjpNQU5BR0VSLCAxXSwKCQlbNSwgRW1wbG95ZWU6Ok1BTkFHRVIsIDJdLAoJCVs1LCBFbXBsb3llZTo6RU5HSU5FRVIsIDFdLAoJCVsxLCBFbXBsb3llZTo6TUFOQUdFUiwgMSwgdHJ1ZV0KCV0KCl07CgogLyoqCiAqIGNsYXNzZXMucGhwCiAqLwogCiBjbGFzcyBDb21wYW55IHsKCXByb3RlY3RlZCBhcnJheSAkZGVwYXJ0bWVudHM7Cglwcm90ZWN0ZWQgaW50ICRudW1PZkRlcHRzOwoKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkZGVwYXJ0bWVudHMpIHsKCQkkdGhpcy0+ZGVwYXJ0bWVudHMgPSAkZGVwYXJ0bWVudHM7CgkJJHRoaXMtPm51bU9mRGVwdHMgPSBjb3VudCgkZGVwYXJ0bWVudHMpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXREZXBhcnRtZW50cygpOiBhcnJheSB7CgkJcmV0dXJuICR0aGlzLT5kZXBhcnRtZW50czsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0VG90YWxTdGFmZigpOiBpbnQgewoJCSRzdGFmZiA9IDA7CgkJZm9yZWFjaCAoJHRoaXMtPmRlcGFydG1lbnRzIGFzICRkZXB0KSB7CgkJCSRzdGFmZiArPSAkZGVwdC0+Z2V0U3RhZmZOdW1iZXIoKTsKCQl9CgkJcmV0dXJuICRzdGFmZjsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0VG90YWxMYWJvckNvc3QoKSB7CgkJJGNvc3QgPSAwOwoJCWZvcmVhY2ggKCR0aGlzLT5kZXBhcnRtZW50cyBhcyAkZGVwdCkgewoJCQkkY29zdCArPSAkZGVwdC0+Z2V0TGFib3JDb3N0KCk7CgkJfQoJCXJldHVybiAkY29zdDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0VG90YWxDb2ZmZWVEcnVuaygpIHsKCQkkYW1vdW50ID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+ZGVwYXJ0bWVudHMgYXMgJGRlcHQpIHsKCQkJJGFtb3VudCArPSAkZGVwdC0+Z2V0Q29mZmVlRHJ1bmsoKTsKCQl9CgkJcmV0dXJuICRhbW91bnQ7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldFRvdGFsUGFnZXNQcm9kdWNlZCgpOiBpbnQgewoJCSRwYWdlcyA9IDA7CgkJZm9yZWFjaCAoJHRoaXMtPmRlcGFydG1lbnRzIGFzICRkZXB0KSB7CgkJCSRwYWdlcyArPSAkZGVwdC0+Z2V0UGFnZXNQcm9kdWNlZCgpOwoJCX0KCQlyZXR1cm4gJHBhZ2VzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRUb3RhbENvc3RQZXJQYWdlKCkgewoJCSRjb3N0ID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+ZGVwYXJ0bWVudHMgYXMgJGRlcHQpIHsKCQkJJGNvc3QgKz0gJGRlcHQtPmdldENvc3RQZXJQYWdlKCk7CgkJfQoJCXJldHVybiAkY29zdDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QXZlcmFnZVN0YWZmKCkgewoJCSRzdGFmZiA9IDA7CgkJZm9yZWFjaCAoJHRoaXMtPmRlcGFydG1lbnRzIGFzICRkZXB0KSB7CgkJCSRzdGFmZiArPSAkZGVwdC0+Z2V0U3RhZmZOdW1iZXIoKTsKCQl9CgkJcmV0dXJuICRzdGFmZiAvICR0aGlzLT5udW1PZkRlcHRzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRBdmVyYWdlTGFib3JDb3N0KCkgewoJCSRjb3N0ID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+ZGVwYXJ0bWVudHMgYXMgJGRlcHQpIHsKCQkJJGNvc3QgKz0gJGRlcHQtPmdldExhYm9yQ29zdCgpOwoJCX0KCQlyZXR1cm4gJGNvc3QgLyAkdGhpcy0+bnVtT2ZEZXB0czsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QXZlcmFnZUNvZmZlZURydW5rKCkgewoJCSRhbW91bnQgPSAwOwoJCWZvcmVhY2ggKCR0aGlzLT5kZXBhcnRtZW50cyBhcyAkZGVwdCkgewoJCQkkYW1vdW50ICs9ICRkZXB0LT5nZXRDb2ZmZWVEcnVuaygpOwoJCX0KCQlyZXR1cm4gJGFtb3VudCAvICR0aGlzLT5udW1PZkRlcHRzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRBdmVyYWdlUGFnZXNQcm9kdWNlZCgpIHsKCQkkcGFnZXMgPSAwOwoJCWZvcmVhY2ggKCR0aGlzLT5kZXBhcnRtZW50cyBhcyAkZGVwdCkgewoJCQkkcGFnZXMgKz0gJGRlcHQtPmdldFBhZ2VzUHJvZHVjZWQoKTsKCQl9CgkJcmV0dXJuICRwYWdlcyAvICR0aGlzLT5udW1PZkRlcHRzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRBdmVyYWdlQ29zdFBlclBhZ2UoKSB7CgkJJGNvc3QgPSAwOwoJCWZvcmVhY2ggKCR0aGlzLT5kZXBhcnRtZW50cyBhcyAkZGVwdCkgewoJCQkkY29zdCArPSAkZGVwdC0+Z2V0Q29zdFBlclBhZ2UoKTsKCQl9CgkJcmV0dXJuICRjb3N0IC8gJHRoaXMtPm51bU9mRGVwdHM7Cgl9Cn0KCmNsYXNzIERlcGFydG1lbnQgewoJcHJvdGVjdGVkIHN0cmluZyAkbmFtZTsKCXByb3RlY3RlZCBhcnJheSAkc3RhZmY7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KHN0cmluZyAkbmFtZSwgYXJyYXkgJGVtcGxveWVlcykgewoJCSR0aGlzLT5uYW1lID0gJG5hbWU7CgkJJHRoaXMtPnN0YWZmID0gW107CgkJZm9yZWFjaCAoJGVtcGxveWVlcyBhcyAkZW1wR3JvdXApIHsKCQkJJGVtcFF1YW50aXR5ID0gJGVtcEdyb3VwWzBdOwoJCQkkZW1wVHlwZSA9ICRlbXBHcm91cFsxXTsKCQkJJGVtcEdyYWRlID0gJGVtcEdyb3VwWzJdOyAvLyAxCgkJCSRlbXBDaGllZiA9IGlzc2V0KCRlbXBHcm91cFszXSkgPyB0cnVlIDogZmFsc2U7CgkJCWZvciAoJGMgPSAwOyAkYyA8ICRlbXBRdWFudGl0eTsgJGMrKykgewoJCQkJJHRoaXMtPnN0YWZmW10gPSBuZXcgJGVtcFR5cGUoJGVtcEdyYWRlLCAkZW1wQ2hpZWYpOwoJCQl9CgkJfQoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXREZXB0TmFtZSgpOiBzdHJpbmcgewoJCXJldHVybiAkdGhpcy0+bmFtZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhZmZOdW1iZXIoKTogaW50IHsKCQkkc3RhZmZOdW1iZXIgPSBjb3VudCgkdGhpcy0+c3RhZmYpOwoJCXJldHVybiAkc3RhZmZOdW1iZXI7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldExhYm9yQ29zdCgpOiBpbnQgewoJCSRhZ2dyZWdhdGVDb3N0ID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+c3RhZmYgYXMgJGVtcGxveWVlKSB7CgkJCSRhZ2dyZWdhdGVDb3N0ICs9ICRlbXBsb3llZS0+Z2V0QWN0dWFsUGF5KCk7CgkJfQoJCXJldHVybiAkYWdncmVnYXRlQ29zdDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0Q29mZmVlRHJ1bmsoKTogaW50IHsKCQkkdG90YWxDb2ZmZWVEcnVuayA9IDA7CgkJZm9yZWFjaCAoJHRoaXMtPnN0YWZmIGFzICRlbXBsb3llZSkgewoJCQkkdG90YWxDb2ZmZWVEcnVuayArPSAkZW1wbG95ZWUtPmdldEFjdHVhbENvZmZlZUNvbnN1bXB0aW9uKCk7CgkJfQoJCXJldHVybiAkdG90YWxDb2ZmZWVEcnVuazsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0UGFnZXNQcm9kdWNlZCgpIHsKCQkkdG90YWxQYWdlc1Byb2R1Y2VkID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+c3RhZmYgYXMgJGVtcGxveWVlKSB7CgkJCSR0b3RhbFBhZ2VzUHJvZHVjZWQgKz0gJGVtcGxveWVlLT5nZXRBY3R1YWxQYXBlcndvcmtQcm9kdWNlZCgpOwoJCX0KCQlyZXR1cm4gJHRvdGFsUGFnZXNQcm9kdWNlZDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0Q29zdFBlclBhZ2UoKSB7CgkJJHBhZ2VzID0gJHRoaXMtPmdldFBhZ2VzUHJvZHVjZWQoKTsKCQkkbGFib3JDb3N0ID0gJHRoaXMtPmdldExhYm9yQ29zdCgpOwoJCXJldHVybiByb3VuZCgkbGFib3JDb3N0IC8gJHBhZ2VzLCAyKTsKCX0KfQoKYWJzdHJhY3QgY2xhc3MgRW1wbG95ZWUgewoJY29uc3QgTUFOQUdFUiA9ICJNYW5hZ2VyIjsKCWNvbnN0IE1BUktFVEVSID0gIk1hcmtldGVyIjsKCWNvbnN0IEVOR0lORUVSID0gIkVuZ2luZWVyIjsKCWNvbnN0IEFOQUxZU1QgPSAiQW5hbHlzdCI7CgoJcHJvdGVjdGVkIGludCAkZ3JhZGU7Cglwcm90ZWN0ZWQgJGJhc2VSYXRlOwoJcHJvdGVjdGVkIGJvb2wgJGNoaWVmOwoJcHJvdGVjdGVkICRiYXNlQ29mZmVlQ29uc3VtcHRpb247Cglwcm90ZWN0ZWQgaW50ICRiYXNlUGFwZXJ3b3JrUHJvZHVjZWQ7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KGludCAkZ3JhZGUsIGJvb2wgJGNoaWVmID0gZmFsc2UpIHsKCQkkdGhpcy0+Z3JhZGUgPSAkZ3JhZGU7CgkJJHRoaXMtPmNoaWVmID0gJGNoaWVmOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRBY3R1YWxQYXkoKSB7CgkJJHJhdGUgPSAkdGhpcy0+YmFzZVJhdGU7CgkJaWYgKCR0aGlzLT5ncmFkZSA9PSAyKSB7CgkJCSRyYXRlICo9IDEuMjU7CgkJfSBlbHNlaWYgKCR0aGlzLT5ncmFkZSA9PSAzKSB7CgkJCSRyYXRlID0gJHJhdGUgKiAxLjU7CgkJfQoKCQlyZXR1cm4gJHRoaXMtPmNoaWVmID8gJHJhdGUgKiAyIDogJHJhdGU7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEFjdHVhbENvZmZlZUNvbnN1bXB0aW9uKCkgewoJCXJldHVybiAkdGhpcy0+Y2hpZWYgPyAkdGhpcy0+YmFzZUNvZmZlZUNvbnN1bXB0aW9uICogMiA6ICR0aGlzLT5iYXNlQ29mZmVlQ29uc3VtcHRpb247Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEFjdHVhbFBhcGVyd29ya1Byb2R1Y2VkKCk6IGludCB7CgkJcmV0dXJuICR0aGlzLT5jaGllZiA/IDAgOiAkdGhpcy0+YmFzZVBhcGVyd29ya1Byb2R1Y2VkOwkKCX0KfQoKY2xhc3MgTWFuYWdlciBleHRlbmRzIEVtcGxveWVlIHsKCXByb3RlY3RlZCAkYmFzZVJhdGUgPSA1MDA7Cglwcm90ZWN0ZWQgJGJhc2VDb2ZmZWVDb25zdW1wdGlvbiA9IDIwOwoJcHJvdGVjdGVkIGludCAkYmFzZVBhcGVyd29ya1Byb2R1Y2VkID0gMjAwOwp9CgpjbGFzcyBNYXJrZXRlciBleHRlbmRzIEVtcGxveWVlIHsKCXByb3RlY3RlZCAkYmFzZVJhdGUgPSA0MDA7Cglwcm90ZWN0ZWQgJGJhc2VDb2ZmZWVDb25zdW1wdGlvbiA9IDE1OwoJcHJvdGVjdGVkIGludCAkYmFzZVBhcGVyd29ya1Byb2R1Y2VkID0gMTUwOwp9CgpjbGFzcyBFbmdpbmVlciBleHRlbmRzIEVtcGxveWVlIHsKCXByb3RlY3RlZCAkYmFzZVJhdGUgPSAyMDA7Cglwcm90ZWN0ZWQgJGJhc2VDb2ZmZWVDb25zdW1wdGlvbiA9IDU7Cglwcm90ZWN0ZWQgaW50ICRiYXNlUGFwZXJ3b3JrUHJvZHVjZWQgPSA1MDsKfQoKY2xhc3MgQW5hbHlzdCBleHRlbmRzIEVtcGxveWVlIHsKCXByb3RlY3RlZCAkYmFzZVJhdGUgPSA4MDA7Cglwcm90ZWN0ZWQgJGJhc2VDb2ZmZWVDb25zdW1wdGlvbiA9IDUwOwoJcHJvdGVjdGVkIGludCAkYmFzZVBhcGVyd29ya1Byb2R1Y2VkID0gNTsKfQogCiAgLyoqCiAqIHBhZHN0cmluZy5waHAKICovCiAKIGZ1bmN0aW9uIHBhZFN0cmluZygkc3RyaW5nLCAkbGVuZ3RoLCAkc2lkZSA9ICJyaWdodCIsICRwYWQgPSAiICIpIHsKCWlmIChzdHJsZW4oJHN0cmluZykgPT0gJGxlbmd0aCkgewoJCXJldHVybiAkc3RyaW5nOwoJfSBlbHNlIHsKCQkkY2hhcnNOZWVkZWQgPSAkbGVuZ3RoIC0gc3RybGVuKCRzdHJpbmcpOwoJCSRwYWRkaW5nID0gc3RyX3JlcGVhdCgkcGFkLCAkY2hhcnNOZWVkZWQpOwoJCSRzaWRlID09ICJyaWdodCIgPyAoJHN0cmluZyA9ICRzdHJpbmcgLiAkcGFkZGluZykgOiAoJHN0cmluZyA9ICRwYWRkaW5nIC4gJHN0cmluZyk7CgkJcmV0dXJuICRzdHJpbmc7Cgl9Cn0KCiAvKioKICogbWFpbi5waHAKICovCiAKaW5jbHVkZSgnY2xhc3Nlcy5waHAnKTsKaW5jbHVkZSgnaW5wdXQucGhwJyk7CmluY2x1ZGUoJ3BhZHN0cmluZy5waHAnKTsKCmZ1bmN0aW9uIGdldERlcGFydG1lbnRzKGFycmF5ICRpbnB1dCk6IGFycmF5IHsKCSRkZXBhcnRtZW50cyA9IFtdOwoKCWZvcmVhY2ggKCRpbnB1dCBhcyAkZGVwYXJ0bWVudCA9PiAkZW1wbG95ZWVzKSB7CgkJJGRlcGFydG1lbnRzW10gPSBuZXcgRGVwYXJ0bWVudCgkZGVwYXJ0bWVudCwgJGVtcGxveWVlcyk7Cgl9CgoJcmV0dXJuICRkZXBhcnRtZW50czsKfQoKZnVuY3Rpb24gcHJpbnRSZXBvcnQoYXJyYXkgJGRlcGFydG1lbnRzKSB7CgkkY29tcGFueSA9IG5ldyBDb21wYW55KCRkZXBhcnRtZW50cyk7CgkkZmlyc3RDb2wgPSAyMDsKCSRyZWdDb2wgPSAxNTsKCgllY2hvIHBhZFN0cmluZygnREVQQVJUTUVOVCcsICRmaXJzdENvbCkgLiBwYWRTdHJpbmcoJ1NUQUZGJywgJHJlZ0NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygnTEFCT1IgQ09TVCcsICRyZWdDb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJ0NPRkZFRSBEUlVOSycsICRyZWdDb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJ1BBR0VTJywgJHJlZ0NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygnQ09TVCBQRVIgUEFHRScsICRyZWdDb2wsICdsZWZ0JykgLiAiXG4iOwoJZWNobyBwYWRTdHJpbmcoJz0nLCAkZmlyc3RDb2wsICdyaWdodCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnQ29sLCAnbGVmdCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnQ29sLCAnbGVmdCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnQ29sLCAnbGVmdCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnQ29sLCAnbGVmdCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnQ29sLCAnbGVmdCcsICc9JykgLiAiXG4iOwoKCWZvcmVhY2ggKCRjb21wYW55LT5nZXREZXBhcnRtZW50cygpIGFzICRkZXBhcnRtZW50KSB7CgkJZWNobyBwYWRTdHJpbmcoJGRlcGFydG1lbnQtPmdldERlcHROYW1lKCksICRmaXJzdENvbCkgLiBwYWRTdHJpbmcoJGRlcGFydG1lbnQtPmdldFN0YWZmTnVtYmVyKCksICRyZWdDb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJGRlcGFydG1lbnQtPmdldExhYm9yQ29zdCgpLCAkcmVnQ29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCRkZXBhcnRtZW50LT5nZXRDb2ZmZWVEcnVuaygpLCAkcmVnQ29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCRkZXBhcnRtZW50LT5nZXRQYWdlc1Byb2R1Y2VkKCksICRyZWdDb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJGRlcGFydG1lbnQtPmdldENvc3RQZXJQYWdlKCksICRyZWdDb2wsICdsZWZ0JykgLiAiXG4iOwoJfQoKCWVjaG8gcGFkU3RyaW5nKCc9JywgJGZpcnN0Q29sLCAncmlnaHQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ0NvbCwgJ2xlZnQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ0NvbCwgJ2xlZnQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ0NvbCwgJ2xlZnQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ0NvbCwgJ2xlZnQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ0NvbCwgJ2xlZnQnLCAnPScpIC4gIlxuIjsKCgllY2hvIHBhZFN0cmluZygnVE9UQUwnLCAkZmlyc3RDb2wpIC4gcGFkU3RyaW5nKCRjb21wYW55LT5nZXRUb3RhbFN0YWZmKCksICRyZWdDb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJGNvbXBhbnktPmdldFRvdGFsTGFib3JDb3N0KCksICRyZWdDb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJGNvbXBhbnktPmdldFRvdGFsQ29mZmVlRHJ1bmsoKSwgJHJlZ0NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkY29tcGFueS0+Z2V0VG90YWxQYWdlc1Byb2R1Y2VkKCksICRyZWdDb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJGNvbXBhbnktPmdldFRvdGFsQ29zdFBlclBhZ2UoKSwgJHJlZ0NvbCwgJ2xlZnQnKSAuICJcbiI7CgoJZWNobyBwYWRTdHJpbmcoJ0FWRVJBR0UnLCAkZmlyc3RDb2wpIC4gcGFkU3RyaW5nKCRjb21wYW55LT5nZXRBdmVyYWdlU3RhZmYoKSwgJHJlZ0NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkY29tcGFueS0+Z2V0QXZlcmFnZUxhYm9yQ29zdCgpLCAkcmVnQ29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCRjb21wYW55LT5nZXRBdmVyYWdlQ29mZmVlRHJ1bmsoKSwgJHJlZ0NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkY29tcGFueS0+Z2V0QXZlcmFnZVBhZ2VzUHJvZHVjZWQoKSwgJHJlZ0NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkY29tcGFueS0+Z2V0QXZlcmFnZUNvc3RQZXJQYWdlKCksICRyZWdDb2wsICdsZWZ0JykgLiAiXG4iOwoKfQoKJGRlcGFydG1lbnRzID0gZ2V0RGVwYXJ0bWVudHMoJGlucHV0KTsKCnByaW50UmVwb3J0KCRkZXBhcnRtZW50cyk7