TrackManiaControl/plugins/MCTeam/Dedimania/DedimaniaWebHandler.php

581 lines
57 KiB
PHP

<?php
namespace MCTeam\Dedimania;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Files\AsyncHttpRequest;
use ManiaControl\Logger;
use ManiaControl\ManiaControl;
use ManiaControl\Players\Player;
/**
* ManiaControl Dedimania Webhandler Class for Dedimania Plugin
*
* @author ManiaControl Team <mail@maniacontrol.com>
* @copyright 2014-2017 ManiaControl Team
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class DedimaniaWebHandler implements TimerListener {
const XMLRPC_MULTICALL = 'system.multicall';
const DEDIMANIA_URL = 'http://dedimania.net:8082/Dedimania';
const DEDIMANIA_OPEN_SESSION = 'dedimania.OpenSession';
const DEDIMANIA_CHECK_SESSION = 'dedimania.CheckSession';
const DEDIMANIA_GET_RECORDS = 'dedimania.GetChallengeRecords';
const DEDIMANIA_PLAYERCONNECT = 'dedimania.PlayerConnect';
const DEDIMANIA_PLAYERDISCONNECT = 'dedimania.PlayerDisconnect';
const DEDIMANIA_UPDATE_SERVER_PLAYERS = 'dedimania.UpdateServerPlayers';
const DEDIMANIA_SET_CHALLENGE_TIMES = 'dedimania.SetChallengeTimes';
const DEDIMANIA_WARNINGSANDTTR2 = 'dedimania.WarningsAndTTR2';
/** @var ManiaControl $maniaControl */
private $maniaControl;
/** @var \MCTeam\Dedimania\DedimaniaData $dedimaniaData */
private $dedimaniaData;
private $requests = array();
private $requestIndex = 0;
private $maniaLinkNeedsUpdate = false;
public function __construct($maniaControl) {
$this->maniaControl = $maniaControl;
}
/**
* Opens the Dedimania Session
*
* @param bool $updateRecords
*/
public function openDedimaniaSession($updateRecords = false) {
//TODO updateRecords
$content = $this->encodeRequest(self::DEDIMANIA_OPEN_SESSION, array($this->dedimaniaData->toArray()));
Logger::logInfo("Try to connect on Dedimania");
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, self::DEDIMANIA_URL);
$asyncHttpRequest->setCallable(function ($data, $error) use ($updateRecords) {
if (!$data || $error) {
Logger::logError("Dedimania Error while opening session: '{$error}' Line 42");
}
$data = $this->decode($data);
if (!is_array($data) || empty($data)) {
return;
}
$methodResponse = $data[0];
if (xmlrpc_is_fault($methodResponse)) {
$this->handleXmlRpcFault($methodResponse, self::DEDIMANIA_OPEN_SESSION);
return;
}
$responseData = $methodResponse[0];
$this->dedimaniaData->sessionId = $responseData['SessionId'];
if ($this->dedimaniaData->sessionId) {
Logger::logInfo("Dedimania connection successfully established.");
if ($updateRecords) {
$this->fetchDedimaniaRecords();
}
} else {
Logger::logError("Error while opening Dedimania Connection");
}
});
$asyncHttpRequest->setContent($content);
$asyncHttpRequest->setCompression(true);
$asyncHttpRequest->setTimeout(500);
$asyncHttpRequest->postData();
}
/**
* Fetch Dedimania Records
*
* @param bool $reset
* @return bool
*/
public function fetchDedimaniaRecords($reset = true) {
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
return false;
}
// Reset records
if ($reset) {
$this->dedimaniaData->unsetRecords();
}
$serverInfo = $this->getServerInfo();
$playerInfo = $this->getPlayerList();
$mapInfo = $this->getMapInfo();
$gameMode = $this->getGameModeString();
if (!$serverInfo || !$playerInfo || !$mapInfo || !$gameMode) {
$data = array($this->dedimaniaData->sessionId, $mapInfo, $gameMode, $serverInfo, $playerInfo);
if ($serverInfo) { // No Players
Logger::logError("Dedimania Records could not be fetched, debuginfo:" . json_encode($data));
}
if (!$gameMode) {
$this->maniaControl->getChat()->sendError("Dedimania Error: Gamemode not found, try to restart map!");
}
return false;
}
$data = array($this->dedimaniaData->sessionId, $mapInfo, $gameMode, $serverInfo, $playerInfo);
Logger::logInfo("Try to fetch Dedimania Records");
$this->addRequest(self::DEDIMANIA_GET_RECORDS, $data);
return true;
}
/**
* Checks If a Dedimania Session exists, if not create a new oen
*/
public function checkDedimaniaSession() { //TODO complete check and refactor
if (!$this->dedimaniaData->sessionIdSet()) {
return;
}
$this->addRequest(self::DEDIMANIA_CHECK_SESSION, array($this->dedimaniaData->sessionId));
}
/**
* Handle EndMap Callback
*/
public function submitChallengeTimes() {
if (!$this->dedimaniaData->sessionIdSet()) {
return;
}
if (!$this->getDedimaniaData()->recordsExisting()) {
return;
}
//Finish Counts as CP somehow
if ($this->maniaControl->getMapManager()->getCurrentMap()->nbCheckpoints < 2) {
return;
}
// Send dedimania records
$gameMode = $this->getGameModeString();
$times = array();
$replays = array();
foreach ($this->dedimaniaData->records as $record) {
if ($record->rank > $this->dedimaniaData->serverMaxRank) {
break;
}
if (!$record->newRecord) {
continue;
}
if ($record->vReplay == '' || !$record->vReplay) {
Logger::logInfo("Dedimania Ignore time for " . $record->login . " no validation replay found");
continue;
}
//TODO check number of checkpoints
array_push($times, array('Login' => $record->login, 'Best' => $record->best, 'Checks' => $record->checkpoints));
if (!isset($replays['VReplay'])) {
$replays['VReplay'] = $record->vReplay;
}
if (!isset($replays['VReplayChecks'])) {
$replays['VReplayChecks'] = '';
// TODO: VReplayChecks
}
if (!isset($replays['Top1GReplay'])) {
$replays['Top1GReplay'] = $record->top1GReplay;
}
}
xmlrpc_set_type($replays['VReplay'], 'base64');
xmlrpc_set_type($replays['Top1GReplay'], 'base64');
$data = array($this->dedimaniaData->sessionId, $this->getMapInfo(), $gameMode, $times, $replays);
Logger::logInfo("Dedimania Submitting Map Times at End-Map Start");
$this->addRequest(self::DEDIMANIA_SET_CHALLENGE_TIMES, $data);
}
/**
* Handle PlayerConnect callback
*
* @param Player $player
*/
public function handlePlayerConnect(Player $player) {
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
return;
}
// Send Dedimania request
$data = array($this->dedimaniaData->sessionId, $player->login, $player->rawNickname, $player->path, $player->isSpectator);
$this->addRequest(self::DEDIMANIA_PLAYERCONNECT, $data);
}
/**
* Handle Player Disconnect Callback
*
* @param Player $player
*/
public function handlePlayerDisconnect(Player $player) { //TODO move into webhandler
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
return;
}
$this->dedimaniaData->removePlayer($player->login);
// Send Dedimania request
$data = array($this->dedimaniaData->sessionId, $player->login, '');
$this->addRequest(self::DEDIMANIA_PLAYERDISCONNECT, $data);
}
/**
* Update the PlayerList every 3 Minutes
*/
public function updatePlayerList() {
$serverInfo = $this->getServerInfo();
$playerList = $this->getPlayerList();
$votesInfo = $this->getVotesInfo();
if (!$serverInfo || !$votesInfo || !$playerList || !isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
return;
}
// Send Dedimania request
$data = array($this->dedimaniaData->sessionId, $serverInfo, $votesInfo, $playerList);
$this->addRequest(self::DEDIMANIA_UPDATE_SERVER_PLAYERS, $data);
}
/** Adds a Request to the Dedimania Queue */
private function addRequest($method, $params) {
$this->requests[$this->requestIndex] = array('methodName' => $method, 'params' => $params);
$this->requestIndex++;
}
/**
* Process Dedimania Calls
*/
public function callDedimania() {
if (empty($this->requests)) {
return;
}
//var_dump($this->dedimaniaData->sessionId);
$this->addRequest(self::DEDIMANIA_WARNINGSANDTTR2, array());
$content = xmlrpc_encode_request(self::XMLRPC_MULTICALL, array($this->requests), array('encoding' => 'UTF-8', 'escaping' => 'cdata, non-ascii, non-print, markup',
'verbosity' => 'no_white_space'));
/* $content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>system.multicall</methodName>
<params>
<param><value><array><data><value><struct><member><name>methodName</name><value>
<string>dedimania.SetChallengeTimes</string></value></member>
<member><name>params</name><value><array><data><value><string>".$this->dedimaniaData->sessionId."</string></value>
<value><struct><member><name>UId</name><value><string>ymBMv4ra0y81UM58_E4qfUpfSOd</string></value></member>
<member><name>Name</name><value><string>Sparkster's Canyon B12</string></value></member><member>
<name>Environment</name><value><string>Canyon</string></value></member><member><name>Author</name>
<value><string>sparkster</string></value></member><member><name>NbCheckpoints</name><value><int>3</int></value></member>
<member><name>NbLaps</name><value><int>0</int></value></member></struct></value><value><string>TA</string></value><value><array>
<data><value><struct><member><name>Login</name><value><string>kremsy</string></value></member><member><name>Best</name><value>
<int>271954</int></value></member><member><name>Checks</name><value><string>9092,17778,271954</string></value></member></struct></value></data></array></value><value><struct><member><name>VReplay</name><value><base64>R0JYBgBCVUNSADAJAwcDAAADAAAAADAJA5IAAAABMAkD2QEAgAIwCQOAAAAACAAAAAMAAAAA&#10;AABAGwAAAHltQk12NHJhMHk4MVVNNThfRTRxZlVwZlNPZAwAAAAAAABACQAAAHNwYXJrc3R&#10;lclImBAAvAAAA77u/JHokcyRpJDA5Zs+BJDAwMMK7JGFhYW9tYm8gJGZmZkx1ayQwOWbDqS&#10;DupaQGAAAAa3JlbXN5AQAAAEAIAAAAVE1DYW55b27VAQAAPGhlYWRlciB0eXBlPSJyZXBsY&#10;XkiIGV4ZXZlcj0iMy4zLjAiIGV4ZWJ1aWxkPSIyMDE3LTA1LTE2XzE5XzAwIiB0aXRsZT0i&#10;VE1DYW55b24iPjxtYXAgdWlkPSJ5bUJNdjRyYTB5ODFVTTU4X0U0cWZVcGZTT2QiIG5hbWU&#10;9IlNwYXJrc3RlciZhcG9zO3MgQ2FueW9uIEIxMiIgYXV0aG9yPSJzcGFya3N0ZXIiIGF1dG&#10;hvcnpvbmU9IldvcmxkfEV1cm9wZXxHZXJtYW55fFJoZWlubGFuZC1QZmFsenxLYWlzZXJzb&#10;GF1dGVybiIvPjxkZXNjIGVudmlyPSJDYW55b24iIG1vb2Q9IiIgbWFwdHlwZT0iVHJhY2tt&#10;YW5pYVxSYWNlIiBtYXBzdHlsZT0iIiBkaXNwbGF5Y29zdD0iMCIgbW9kPSIiIC8+PHBsYXl&#10;lcm1vZGVsIGlkPSJDYW55b25DYXIiLz48dGltZXMgYmVzdD0iMjcxOTU0IiByZXNwYXducz&#10;0iOSIgc3R1bnRzY29yZT0iNTIiIHZhbGlkYWJsZT0iMSIvPjxjaGVja3BvaW50cyBjdXI9I&#10;jMiIG9uZWxhcD0iMyIvPjwvaGVhZGVyPgEAAAAAAAAADQAAAHBhcmFnb25jYW55b24wAAAA&#10;JHckQURGUCQ5Q0ZhJDdCRnIkN0JGYSQ1QUZnJDJBRm8kMDlGbiRmZmYgQ2FueW9uKwAAAO+&#10;7v1dvcmxkfEV1cm9wZXxGcmFuY2V8w45sZS1kZS1GcmFuY2V8UGFyaXMAAAAAAgAAAAAAAA&#10;BpdQAAqmoAAAAIAjAJA/NZAABHQlgGAEJVQ1IAMAQDAAAAABxwAA0AAAAhawEA0lkAAAYNM&#10;AQDZAMH/ykAAAkRMAQDAWQEAOOwAQOMAAUAAAAB3sr6AowCAwUDAbAFA2gBKgwADwSwBQOd&#10;5gAAt8wAAOPEAADsurQDAAMIsAUDYOoAACUAAAAKsAUDUElLUxypAwAuvAD8BAENsAUDeRE&#10;O3AUABRsAAAAPAAAAVHJhY2ttYW5pYVxSYWNldAh4FGgTBAgAAAAYMASYC2wBbANtFBnMAg&#10;EpAAAAfAF8Aj8PAB8wBG0FQHwOAAp5bUJNdjRyYTB5ODFVTTU4X0U0cWZVcGZTT2QMoAkAA&#10;UAJAAAAc3BhcmtzdGVyFgAAAFPwAQ8ncyBDYW55b24gQjEyAAAAQAZ0AwJ1bnNldPAHDnwd&#10;AABwTmFkZW8gAAAAKAAAAHwAYAtpBcR3AwAAQHAFD1dhdGVyQ2xpZmYxMgEBAg5FEJgxDUA&#10;LAAAAVW5hc3NpZ25lZDFgImwnCgUAAEABAQIVhRACAAZsAcw83QIWeAcxXgAXBTS9ABg1HQ&#10;EZNb0AGjW+ABvFNH0BHC48AnQldB+YHgIAAgIOAC3gAAUHAABAAAICFTVdABs1XQAcM10AA&#10;zV9AQM1fgEDAjR9AQQ1HwEEAhQz3QEENX0BBTUdAQU1HQEFNR8BBgITM90BBjUdAQY1HQEH&#10;NR0BBzUdAQc1HQEINR0BCDUdAQg1HQEJNR0BCTUdAQk1HwEVAhYzfwQVAhc1XQAYNV0AGTV&#10;dABo1XAA0/ggVAjR+ChYCNH4BFgI0fQEWNX0KFjd9AR0znwIWAh41XQAfLlwAYIsBABYCIC&#10;6AD510FzW9Bhc1vQYXNb0GFzUdBBc1HQQXNR0EFzUeBBcCNB0EFzUeBBcCNB8EFwIgLmAUn&#10;SAYNR0EGDUdBBg1HQQYNTYsAAsfBBgCIC5gF50gGTUdBCgMAAb9Dhk1/g4ZAjRgAQE9BRk1&#10;NgwAA10JGjU9BWwAABgbNb0AHDVdAB01XQAIfi8AAI06CGwuJy8AGAAQJy0AGSktABonLQA&#10;JKe2sAAAcbDTNBwl8MicsACjvAAYCDScdAQZs5c8EBgIPKV0AECktABEpLQASJy0ABykdAa&#10;wAAh4BBwIoKBAAAx0BCCldAGwAAQkpXQBsAAoVKS0AFimNABYpXQAXzAABGCldAGwAARkpX&#10;QBsAAEaKV0AbAABGyldAGwAARwpXQBsAAEdKV0AbAABHildAGwAAFMfKV0AH7wCbMQFAyAC&#10;EUUQAADOARKFKJ0ICS5MGd1KCjVdAAs1XQAMNV0ADTVcADRtKQhsQCzwLN0REDMfAQkCBDV&#10;cADReAwkCNF4DCQI0XgMJAjRdAwlsWDGdAgl8WTNdAA81nGgCDgo1XwMKAgUzHwEKAgY1XQ&#10;AHZChkCgPdBBU1PQKsAAGdBRU1KAwAARY1PQKsAAJ+BBYCNCgQAAACfQQWNd0HFjU9CxZ8m&#10;zGdCBc1XQM+DAABGDVdAz4MAAEZNV0DNAwAAd0NGTUrDAABBBk13Y0AGpZxvQBkQ20AHIRE&#10;Ab0AHTWsAAEeNb0AbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&#10;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL&#10;gfMFwAzfEQLqwuIhBGCAQAAABEaXJ0AA4XL/0cCCINRg81XQAQNV0AETBcAHwPAQEUAgwu7&#10;DjdAg0uXALcAi/QSHwCAQMLAgYyHAEBAwsCBzJQSgEDCwIILqw23QgJLhwBfSEK3CEjKE4C&#10;OAEMDwcudQIJIrpNDA8vVAHdAgkuvAAjVSEKdGUlFSsKZGQnLQAMJ7UqCmRhJ10ADilcACj&#10;VKwp0OyeMACi1KgokBCbNDRMp7QAUKS0AFSktABYpLQAXKSwAKGUvCil1LgoipDQlVycLAg&#10;onhycLAgsuFAXVKwwuHATdAg01vQAONV0AEzX1BhQ1XQAVNR0BFjW9ABc1nQIYNb0AGTW8A&#10;DNIVAEDCwIbLhwB3UQKLhwB3QILNbwALzwF3QUNNbwAL3wE3QUVNbwAL8hY3AUvfATdAhg1&#10;/AIvfATdBRouvACViw0wtBDdBRsuvADdRwUylA8BARQCBS68AN0IBjW9AxwyXAABAA0PHTI&#10;eAQAONV8ADw8dMx0BEDW9ABE1vQASNFwAAgMTDx1JMmVcCyL0NSxUJ3wjAgALAhJAMr0ADD&#10;W/AAwCEjK8AwEBDA8TM90BDTUfAQ0CEi7cDY2RETW9ABEwvACfFxICEi48BZ8CEwISNdwHL&#10;7wDfD4BAw8PCS4cAdwCM98NAw8PM58LAw8PLxwQ3AgznwsDDw8vnAt/FwEQAi8cAd0CGTXc&#10;BDQlSxFssizcB50sEiJURTNcADRlWRM1vQATNX0BFDW9ABQwvAB/IwAPDy/kXZ4CEA8zHBY&#10;CARACFwkt3Ap8IwECEQIXLnwEngISAi+8Bp0CEzS/AAEUAi98E5wFARQCF8Ax3AECABACGo&#10;kyXgARAi+cF38aAhEPL5wXnpsRFy/EX38OABICL5wInQgSNR0BEjUdARM1PwITDxsuPAV/C&#10;wMTDy/cE34RARR8+yz8CNwCL1wDnwgPDxsunBGdHQ8wnAJ+BQIQNV0DEDC8AHwOAQMLAg8u&#10;/A7dAhAuvAZ/CwEMDyPEdCrIc3wCAQAMDw8uHAR8CAECDAIQLjwRnhcNFy+0SJ8IDQ8PLpw&#10;UnwgNAhAunAKdCA41HgEODy9cA50FDzW9AA8w3AGdBRA1vQAQNX0BETW9ABEwfAGfGhECEC&#10;7cDX8gAw8PM3wiAQMPDwwuPAh+CAEQIqwoMFwJAgAQAgvJLXwNfAsBAhAPDC48BZ2bESL8L&#10;DEfARECCy5cBp4IEQ8vvCSdCBI1HwESAgsuPAidCBIwHAGfAhMPDDN9HBM1fQETMHwBnREU&#10;NL4AARQijDAsvAN+DgMPItwxJBwuAgEQAgkFJnVVESKUPiVdMBIpLQATrAGPMRQCBie9ABS&#10;8Ao0QFSKkQM0HFSJ0QCctAAgnXTAVvAWOTw8XLwRQbxMADw8vhEudBRA1vQAQMGw1nxQQAg&#10;gubAWdCBE1HQERNBwBAQIRAgguDAudCBI1HwESDwcu7Al8EQECEgIIMmwIAQMTDwYy7AkBA&#10;xMPBzPNERMwPAJ8CwEBFAIHLpwCfAIBAhQCCDWtEwUufAF8LwECDQ8FLvwCnQIONV4ADw8z&#10;ziwCEDVdABE1XQASNX8BEw8FLhwHnxoKAgIuvAOfUAoCAy6kWJ8FFQICLlwDnQUVNb8AFgI&#10;CLlwGnQUWNb8AFwICLnwHnQUXNb0AGDX9Ahg1vQAZNX0BGTC8ACIEQgUTAAAAUm9hZCIMlA&#10;ABU3RhcnRNaXJyb3IBHwURAAASACLokgEAkAAubAAiiJAiFI0CU3Bhd24iVJEBAZAALiIIl&#10;iaMlI8C3sr6KlwcbAwiGJMOQXJlbmFXYWxsUmlkZUxvb3CQDQMAHQMSAAAs5BEFCwAAQAId&#10;Aw8zXQAcNV0AGzReAAAcNH4BABo1XQAbNF4AAhowfAFkG3QnK2QDB0Nvcm5lcgAZCBAu+AI&#10;EDAAAQAMZCC+4A3gIARUAAAArGAEJU3RyYWlnaHQDGQgRLiEBDSJFSB4wXABiDAEeNOIBAh&#10;404QEZLuABA0JvcmRlcrcYAR4HLxUDDnIzHgcvFAN+AgMZNF4AABkwHAF1HhTwDwRCaVNsb&#10;3Bl8h4BEWxPMFMIAwYHLzAEKxwBKngJA0VuZAMGEi+9ABB2MAYSL/wC3AIvvAN8CyK0oJQz&#10;CVNpbXBsZUJhc2UDCDApAhFpCwk1XQAKMFwAaAsn/AgHQ2hlY2twb2ludHoLAQx6BRIAIrh&#10;UZG9sAHRvIrhQKKQAmG0gBggOImCfjBgFVHVyYm8yAQtgDCyIBZWQGyKMf8XyHCktAB2sAW&#10;SkAQAaAhUupBh/AgMaAjO2NQMaNJY0Axo0lDoBAxoCGS6EFN0LGi4kF90CGzW8ADRPVxoCH&#10;TW9AB4uJBfdCx813QEgM9Y2GwIzVlAAHDQDpQAdAi+UTI0xGiJMYs0xGyktABwpLQAdrAF8&#10;FAECGgICLpQrfAIBAxoCAzW9AwQ1vQMFNb0DBjUcATNGIQMaNS9cGgIJNRwBL7RE3BcvtCz&#10;cAi/ULd0CDTJ0MAECGwINMt8BAhwCM09gAh0CL/RYnTIeIvyKJFQsAQIeAg0yDAgCAx4CDo&#10;AtxDFsEwECHwIOM78AHwIPM78AIAIPMlYjAB9sECz8DnwLAQMgAhMutCZ8AgEAHgIUM88OH&#10;gIVM88IHwIULhwBfpsBDTDcEH/RAwYNL6gVvQIONV0AES9cAGiwAQEIEhMuvBsiPCABAQgM&#10;FDVdAA4uXADcCC+8ANwCL1wh3AIvHAGNPRYplWQXKS0AGKwBbCsBAxYCDC7sBo0HGDUVSxg&#10;irJIs7AbcBTSdqBg01DYBAhcCDC5MB9wINM2HGDVNdBY0fAEBABYCCy4cDZ0LFzS+AAEXMB&#10;Q5fiMAFnwdvmUDFiIETM2aFnwjvAICARcCFkAlHo8CFymNABesBGzlIrggI55sMTIiwCoBS&#10;GlnaG7lMQHdCxQiaSIXrA1uAQMXIhyYLJwFfgIAFjdcAC9MjH4FARYwXAN9AgIxvAN+AgMX&#10;fiwAAJ5lBgwvXAmdAgU1XQAGMJwL3AUvPAt+YgMDMBwBnm4DEi/cAdwCLxwBfAsBAAUNFS4&#10;cDZ0CBjRcAAECBg0NLr0AEyL9Iwc3XAAvfAF+FwEIMHwBfxQBCRMvvAC9AhQ1XQAVL1wAvX&#10;oiL1wAvQghL1wAfgUDBjC8AH8UAwYcL7wAfgIBCH4dAACuChMNIkgmrQEUKS0AFYwBfwsBC&#10;CKMAa0EIYwBfgIDBrwCbwoDBhycAm1eECt0NiRPMAIQFy98G2wFLIsnMQMIMMkCFmk0CHgL&#10;LFgMeAci4MkiaH4GSGlsbDIBDRcWLt0ZFyLfMQ0XFy4MHdwCL4Ru3AIvLCfcAi9EWtwCLyw&#10;nfAIBAA0XHDI8AgECDhcWLpwafwUDDhcvxF7cAi/wydwCL/DJ3AIznwIDDhcvpFrdBRwyPA&#10;IBAQ0XBjL/AgENFy/Ef38IAQ0XL8R/3AIv7CTcAi/sJNwCLwRVfwIADRcvRFF8AgECDhcGM&#10;v8CAw4XL7yDfwUDDhcvtErcAi9EbNwCM58CAw4XM54CAw4wnAJwVSIw1XDABkNhdmVFbnRy&#10;eWRXkMMGOExvdzIAEA4PLnBHI3NKDQ8TIlBSI2JODRcjsILMASOwgnrVAg4iMFrJ1A4iQHG&#10;q1AAOIrJwAACdCA4pHQEOKR4BDhcoHQEPIrBe3QgPKR0BDyIwct8IDw8TInCDjRAPKR0BDy&#10;kdARAi8GDdCBApHQEQKT0CECk9AhApHQEQvQgPa3cQBhF5kxh65BAOI9CGaSkcyIwwKgUxM&#10;mzsfB4uLQUZbQgOInCIMBwRIjBIaDMHTWFpbgAQEBIDACyNABoim48QEBE1XQAQM14ADgwv&#10;vACdMBEp3QMRKd0DEbwebgQAESIQcLwtAQASDxZ8LXwCAgMTDxYJJcghAQEUAhMi6LB8PwE&#10;BFAIUbATNARV8AiPZIxUiyC3dMBUkODzcAow+jQEWKY0AFimNABYiy8EAABWOHxcVIqgjbC&#10;84GAsCMTJMb3doES7oBXgGIrhI6Cwj5EQIR1RDdXJ2ZTIDFQQv+CxgBmA/4AYJSnVtcFNtY&#10;WxsAhYFLxlEHWEUFmhkLNAGgVQScCosXADAKS/8On4CAhJwMyy8ANwIL/zangUTDy/sMnwC&#10;AgMTDxRFLSw1cBoiWEYORGVjb1RyZWVzQmlnMVgxARJsQCzJAR5sVTEAa30CAIxlLLwAaQs&#10;OzGIiUFQERmluaXNoA5EfEiKhuQAiNEZsACJERiKERgFHb2FsZGsgAzhUhECUUzDUAXQ0Yh&#10;pIRIzwJBBOZNwudTEgdzQNFxwu9C/cAi9UMHwCZLsyvABl00AtdAV8BWSvLlwAaSMYIsSaA&#10;mVjb0hEIzDljq4xMqwVIpxtLq0CIYqPAggiOCx8B/Q2CVJlZmZpbmVyeVgxAoSoLD0EInQ2&#10;MVhzaAgi0FK8JCoIAgREZWFkZW5kIuafQBGrtgEUAi+cl5l0FSLURCzBARt9FBQwXABgDvh&#10;0aJorvA0lrlwVBC+wLcBdI2DJzAEjiJ1iWgASIhh0qhQCEimVGBK0u2wEAQMTDw10kM0BDi&#10;ktAA/0lgECEwIQfAKJGhOsB9WWD3wCbAECAhQCEMAm2W4UrASeBRUCKJmfFWS5J2QTI5iff&#10;VQCI3ClZlsAQCLwNWSIKEQMrh8DEiJJlRAiVPAgEFwMZ3ABEhecIobUEgRoYGEOQCLIYKw8&#10;KGQfsEwDAxMPD0ARLPEGJnRFAhMPEwAUMFwAfbzAMbwAIrCTAUATAADPBxuAEizsAHYnAAQ&#10;waNaeAgUCM8OYAAYCL/gqfAUBAQcCGy5gDHwCAQABAh0yOEgBAAICHTILTgAIAi8ghJ4ICQ&#10;I0LfQKNb4ABwIvOC1/CAMIAi/4Kn4CAQk0aFEBAgkCAzJcAwEBCAIDLrgrnwgIAgQ1XAMvk&#10;HF+BQIINRNzCQIFLjATfgUBCSLQeTAeBwEJNLiuAQIJAggu/AJkbgEBAQ8BLhgs3AIvsG/d&#10;AgMuiBrcAi+IVdwCNPN0Ag8BLhwBlocCFy94zHwIAQIDDwEusHKdAgQwHAGdAgU1XwAGDwE&#10;uvAZ/BQMGDzO8AwEDBg8DMtwBAQMGDwQ1XAAz8HcBAQIXAjOeBQIXM3wBAQACFwQynAIBAg&#10;MXAi7cAZ4mAx8vkHd8GgEBAxcELnAbfwICBBcvvAOdCAQ0HwEABBcvmNadCAU0XwMDBRczn&#10;ggDBTBcAyMpQAMweEQiDz8BBwwvGEfcAi8kGp1iFCLIYyeFFx0poYUeKS0AH2wBfgUAFSKo&#10;7cbUCwIvjAZvBAMLAi8sA9wCLwwIfgIBFDQfAQEUAi+sB9wFL+wMcPF0/yXUIWDSDU1lZEJ&#10;hcnJhZ2VMZWZ0ARMiZLosABBwBgEaAAAAM9EAUiOVdRNg4CzUACKERgEDEwkRLpRLvQIKNV&#10;0ACzVdAAw1XAA11VwTNdZcEw8vHAF0GyJMJiNwbyYBdFQieH0ktkgDE3DqLG0DKSIaSBMDL&#10;ywBJCRKMARe3AIv5FxsDwoGAAAAUG9kaXVtAgkPL/ShIs8/AQUPL7AZfwICBg8vsBl8AgEB&#10;AQ8eLpAP3QIfLnAUfAIBAAEPIC4QEXwCAQICDx4zUxACER8uVDV/BQACDy98+XwCAQIDDx4&#10;uzEuRggM1HgEDDy+8/nwIAQAEDyAuHAGdAgU1vQAGNL8AAwYPEAhgAXwIAQIHDx0zfQEHNH&#10;wBAQIIDx0y3gQDCDC8A3wLAQMIDx8uPAXdAiAuvAZyoAEJMHwB3AIvXAbcAi98B38CAAkPL&#10;3wBYIQBAAoCHC7wJH4FAgo0drsACjB8B34IAwswMCR8CAEBBhEeLnwEfAIBAAYRHzK+AwIH&#10;NLwAAQMHER8zHQELMDwCfgsDDDCcBdwCLxwEfwIBChcvvAx/AgAKFzPeAQILNLfAAgsXM74&#10;DAws0HAECAAwPHQIt5Dh/DgMMDzMffQENAi+cAnwvAQENAh8u3Ap/AgANAi9cD38CAg4CL/&#10;wII0kzDhAOoQMOcNksBBSfCA8CHi4wKp0IDzUeAQ8CL/wOnQgQNT0CEDUdARAQCWATnQgRN&#10;T0CETUdARE1XQMSNT0CEjUdARI1XgMTAi/cE50jEzUdARMQCUAJnRoUEA5hChQ1HQEUMHwE&#10;IhRBfUEALSA3fAJ8Si5AOHwCfHounBd8AnyGIqEjIyLHPwECGC4AMJ8CCQIHMlwAAQMLAgo&#10;u4Ch8BQEDCwILLpA53QINMh4BAg8wxCF8BQEADwISLmAzdewXJ9RFKDk8RCTCQwAOMD08Ky&#10;I8PAERDxMALUw7fAIiOE0BgBEAAM4BHIAtSAXeAg5ANO0ADSLsUs0EBi7sAHrBAhMwLDF/A&#10;gMTDy/go9wCLxwp3QIELtgUfgIBDCJuNgAAzQECInxWzQEDIuBSbAEDAAwPBEkQrAQBAg0P&#10;AewEAQANDwQiZERuBAIOIuw0rgQADiLcMq4BAg8ijDSuAQAPKb0AECm9ABApvQARKX8BEQ8&#10;E7g0CEim9ABK8CHijAQENEQIy+xgADREvzDx8BQECDhECLtgdfwIADhEv3Cx/AgIPES8MM3&#10;4CAA81vQAQNX4BEBEvXAZ+CAIRNX0BETW+ABIRL/wwfggDEjC8AyPiURMPL2w2fAJ8Si7oD&#10;XwCfEEyXABsQDIpDRInKA0jlVVEtGgBAQwPAy6hDixghAQMDwKAEAAAbAFkWDKMAAEDEw8D&#10;LmASfgUAEDAkAyK0SSLIti68AHB8IlhfLsxLI4SDAQMPDwwuwQAtIg9YDw8HLuQTYAkotBA&#10;qgFSICSKYty7VDi5/HBQCCy5sA3wCAQIUAhcyXAAiCM9kgc0EHi5MAWCtAQMaAiAueAJwnA&#10;EBFAIbMrAUAQEUAhxkk80EHS7IA50CDTDQGGgeIiClbCcFQ2FjdHVzTWUiQDIBMVgxADGsL&#10;yJpWQEx7C54CGQnIyQ1A0JyaWRnZWgmCE5vUGlsbGFyAgYbLwmAMH2sBzBcAHQ/AQENFxou&#10;XAp8AgEDDhcZLmQD3AIvbE/dAhd41XgT7FcjyGMokwMRFxwupQExe0MSFxwu7AZ9AgEx2NR&#10;0C+woAkJ1c2hlKA0FASOgdCz9JDJiHw0XL4ybfAIBAw8XFC44AmDGAQEMDxYumAjdAhouoA&#10;7dAhQumAhjLgEGGy/siZ0CBzBcAHgacCYipEAi6Foj9F50OgUxAQ0YDQCAACKKrUAHIshZA&#10;ZAFAwJsAACDAAAAITQDyuqqln8LVKW6P6ZjSLEPa24yplLYM3kKwWNPcRv93Hk/AAAAU2tp&#10;bnNcQW55XEFkdmVydGlzZW1lbnRcQnJpbGxpYW5jZSAnbicgTWV0YWxzXEVtZXJhbGRfVGl&#10;0bGUuanBnOQAAAGh0dHA6Ly9kbC5kcm9wYm94LmNvbS9zL3lhZXl6dDRjZnI1MWFpby8v8A&#10;AjXL54Fj4MABJAUzcWBDIBEiEGkLQgIuF2AGQgbAC0IAAQ9RH4GNU3Kz6517kqaUP2mWmc+&#10;VkyMdjBhenMx0tdW8BFACAXFAQCTWlzY18kaG1sIXgpNiwEDTVlem96N3cwbXM4dDV1cS/s&#10;IS0IASAQRAQi1EQvXQgyJFljASIgf9wiImCMIMtcBCLoZYygJjRJClNjcmVlbjJ4MQMZBhH&#10;sZiIouvQibFAAEAOsmvq7MnKz3zvH/9+l+QIH6AV7H3/AE+sRHcFQp+/szzMSuVprNcQMCn&#10;VkZGllYWRcQnVkZHkXyFtkQwE6AAAANmQIDWFzZnE5MHVneDV3M3Ziby8w9AAgDFEINSJaT&#10;B0EJ4gDIkCV6BwirHcAEiE0A066RCY4+uvmQMCFVJtwIuiCk8bJfHXYg8ujm+hSlgYNRjqQ&#10;AztYEAVTZXJpZXNfR2gtfR5AOdwDDDNpdHRrMXp2amV4YXp1aidEDC4MASAM9APwhCe0ByY&#10;4xgJBAwkJEvg+EvRgLUwEAA5FcJWwWZpSC7araSAf1DnJjhAttQu1qk0uIoVb58NCYCAZkB&#10;AIV2Fybl9EYW5nZXJoIjqQEAxvdGh4NDMwc3Z1bHFjeW0nSAQtCAEgDEUEN39BCQkQ7R8Nf&#10;Fxwo2wAoKQguO0DNmwfAwYPEgCAAojkIkSELdwHABBKKvAex853mjshr/bVrH4kfTuvHxc+&#10;e0t9QKaPaLy7JUEAIBdwGARBcnJvd18xbT47ORgMDGJ1YWtlbWo4ZG8ycWdxZCfMByn4ACA&#10;MvAcq2Nojml8GES80jdwCL+CM3AIv/NDcAi/oXCIENAEBGw8WMiY4AhwixJIswCV+BQIdIv&#10;SSMV0AHjW9AB80XgAAHxAN/gkCICJElDB/AQMgDxAIvASeER8PL9CnnwIgDxguXAMjwlwfF&#10;xAIfAjcAhAI5GF+CAAfMBj/fwIDIA8QDT8MIA8aMqY8AyAQDX4CARs0HgQBGzBcA54UHBcv&#10;gL5+EQEbND4CARs0PgIBGzRfAwEbDy/A0n4LABsQCVwWfwIBHBcvnAXcAi8wq9wCM34EARw&#10;wMKt+BQAcMNCtvQIPEAjcGp0jHTR8BAECHRcYLiRHfwgDHRc0HgcdFzOeAgMdNJ8CAx0XLy&#10;BpfgsAHTCcAp4CHg8zHwcDHg8QCBwUnRoeNd4KHhc03goeDxAIRG5+DgMeNH4HAx40o2QAG&#10;w8vkK5+CAAcEA2eAAAdEAk8A50FHjVdAB80HgEDIDDcAdwgL2DJngIfFy9cAH4OAyAS/AAz&#10;PBEvcLDdBQo1/A4QDN4FARwiJFAwfAEBARwPAjIeAQEcNNaCARwidE4zHAEz1oICHSKEUCy&#10;8AJwgAR0XAgAtQGTcAi8UgtwCL/SA3AIvtIfcAhAMLgQCHiKkUTE9Ah41PgIeFzQ9Ah4wNI&#10;OeDh4XND0CHhANbgMCHzReBgMfNF8GAx8PM6ZRAx80XgYDHxANDwABGw8vkL1+SgEbEAmsB&#10;dwCL5C93AIQCFw93AIv8LrcAjN/CgIcDzO8BgEBHBcHLnwcnwgcFwgugHvcAjO8DAEAHBcK&#10;LlwVnTUcND4OAh0wsMGeBR0fEAhUWNwCEAhUWH8RAB0XL5wOvAU13QEeNd0BHjXeAR4fNN4&#10;BHhcz/AUBAx8PBi7ASX8UAh8XEAhsDH4CAx80nwUDHxcz3AcBAx8XCjK+BgIgNL4JAyAwvA&#10;ki7FIioOkunAKfAh0CDS6gSyL8VCJw6S78VJ8CHwIOLhwBnwIgAg8irKciTlYDH2wBLEwQn&#10;wIeAg4uTAGfAhoCDS5wTiKsWm3QgC0kaJwCAhwXCsATLHwBfAJtx4AyXQAfMLwAIpNPAB4P&#10;L/DknwIdFwoy9Gps3CJ4r48EHA8MLswCnwIeFwoujAN+AgIeNABSAQIfDxYyAFIiHC4uHAF&#10;sHCLcJTJMBCKcIy78F58FGw8WMkwEIrwtLtwHbDEigP0uXAMiJlgBDTB8DX8CAw4XEAj0b9&#10;wCL3SjfAIi0NEyBFoBAQ0XCSaYtiq8rxd8BgJhcnQBFTDYkCLlQB4pxLwDU3dpdGNoI6hVJ&#10;gxBAjF4MQEUMCCSI8dFGQMRJpQ5InC4LZQ5ABAuo8xsVTGnpC54bbp7ptBquMNb+OD3xWkm&#10;HFIRhEerwFEAIBeUOQJMb2dvXxRIpQlfR3JhbmRfRHJpZnQi1TlLOdQ5DG12NThhaG9xaTR&#10;ldXViMCfUOTk4ASAYFDpkKyqYUhAB8AclmVIXdDET6IAr9LUicE4orAAi2EIgA2zCdA0i8E&#10;8nUFQVFBIFT2ZmaWNlAhhsDSzED2QGIshkLsQABldpbmRvd3MCHDDJBzwi5WAbMFwAaAlwS&#10;CyWnlRvaAsCQWlyX20UXRoUMNx8ZAdwEDXkAAEBFAISLlQOIgzSAwEVCBICACw8A38CABUI&#10;L6zR3QIQLrwAaA8ieGEi5GkiTGYBUGluZSQkygEDERcULu1lPyJNRRE00mQCDzBcAHQLEgS&#10;vLXQBIgSAI+pyLUQk73IDDhcvvRxAIk1vDTBcENwCL7wffAIikN8upATcAi98L9wCL7w03A&#10;IvXDR+AgENMBw13AIvPDYiZncDDjD8an8CAQ0XL7wW3JovMId8AiIgoC5cA58CBw8dLhwdf&#10;AIiAJwyfBQiAJwuTAdsNHhWN4wGI7BpMsieIymNAxKMlyScrQEAAwIdImyCIsiMAQMEAhwp&#10;LgAdiSYtgwQiSqMAACO1JQQi+KEknoIBBSLon68BAgUPI0yvjQQFrAR0GgECBA8eInQgItX&#10;FA8wHdBdsrnQXKELONADZBkFsdZgJLJgMeQYfJRh9KdgLKGAKJKTGIoCnLt0FQ31SBTCgqJ&#10;0CAWQXLKgBfAIioKIyHAEBAwgPIDJcACJAqC5cAHxMIiCnMl4AAAcwHAF8BSJAqDO9AAU1v&#10;QAEMFwAZC8BAAYPIDKeCQADNFwAdDkuPCIjHyEGER4yzCUi4KEurCR8BSJAny6dIiN/LxQC&#10;Dy48AtwCL1wN3AIQCOS3fAIFAhECEEAQAACMAQEMAhBALSSRfwIADAIv9RUjIm96EQISLiw&#10;NI85ZEwcnNCAjMNAirF1sACS8XSC8zFkkvWEIJ8xdZMstNCQAEBQi1XSZKxcGEgCXidMjpm&#10;i20bTzHjHcm5GJluWSg19MTAAgFzQkBk9ic3RhY2xlXxJxNl8iLL0iISRGOSAkDHdrNGZiY&#10;29kbmpocnJxeCcgJDQkASAYDCTVIhAmjCgilIItVAQAEL5mABjx2Mf/+BQCjgKkY39JM11Z&#10;nmz94YOq8WYcYyMiTQAgJVQEI7DAeSJHOVgEDG04aG5ycGI5azJoaDhvbjVYBCcoASAYXAS&#10;WZQYPJ7QMIsQuLVwEILy0DNwfJ1wIIvSUIMv8A3DwImDqK6h+FPw+Jtc1AQMVL5nQRGHAAx&#10;AJuBTcAi/40NwCL8SNmy8DEw74ciLgMC34BQAOKHsOFhRkMlxp9mzYJxApzg+DGWJpHg0Ki&#10;ugsI37jE1cgH4FwM2hxOoBwDGU0eGp2dTQ0am9mZTBiNycoDiSAcJgHIB37DQMTDfwfIgQy&#10;LfwDAA72tVF2k9Xa+g8nfF9ws7sW0zmvRsrWs4ItBHfvoKEZmiAf/QM1PvwDDHdocXpjdjl&#10;kNzZybms5eS38A5gHIB/9AxQmcHwimDot/AMADo30r3DH6NOzwnV3lz2KcR37GX8yrbjBSX&#10;V1+lzf7MgUIB/9Azc+/AMMYWMzNnRrcno5eDVwMmlmLfwDmAcgDPwDzV4V7D4iKNotzAMgv&#10;MwHaI58PIiOLKgRBVRvd2VyAgYNL8F8RSINMQcwXAAimDMBAQECCiK4tM4BC8UWPw4BAgwm&#10;+jMBARLYPiXp4gIU2DUl6DQjcP2NAQQpXQAFrAEikCl8CyKwUM8BDMARJLAqbAoiSKUliOU&#10;jXIcSuisCBRQ4J38RAwICL5Bb3AIvsF/cAi8gU3wlIvSYIxSuIsg+AgEDDgmJLYVoRoKyDg&#10;ouCMx8AgEAAw4LLrwAcA0BAgMCDC68AJ0CBGAnLAQ1nQIFNb0ABjS/AAEHAhAIvKJ+CAEHY&#10;DYwfwEBBwIQCPwefgUCBxAJjDp8AgEAAgIWLvQvfgIDAhANp4UDAgIvpIHcBRAIfCncAi/s&#10;rXwCAQADAhYuyM99LAEiCEU0XAYv3AF8BQEAAw4ZLuRlfwsCAwIQDI5SAAQQDkaIBAIvpHt&#10;+CAAFMJwCfgICBTV/AQYCFi48CHwUAQIGDhcu5GJ/AgMGDjNcAwEDBg4ZM70JBhAJBIl/EQ&#10;EHAi/EONwCEAj8LdwCEAj8LdwCL8SCfwICBwIvaLB+AgEBFDR6bAEBAwICCXCFImdnAAEPE&#10;Aj8KmwEAQEBAgcyXwMBAQIzx20AAg8QCCSffwgCAgIQCBwsfgIAAhAN9HQBAAMXBS78BZ0U&#10;AxAJNHd+CAIDEA12dgADNJ4CAwQ1fQEENf4CBAIQCLwxfg4ABBAJ1Hkk/Egw5HedFwU1/wI&#10;FAgcu5H2dCwU1/QIGMARtfgUCBjWeBQYCL8R2ngUHAi9EdXwCAgMHAggCMVwPAQIEDhcuPA&#10;ieYgQOEAjknNwCL1wMfwIBBQ4vZJTcAi+cC3wCAQAFDhkuPAh8AgECBg4JIrzSbAEBAwYOC&#10;iIc080BCyLsT24BAgRsBCzsFX4CAwR8BTNdAAsujBJ+BQEFNQ0aBTUPGgUOCy7MApL6BQ4v&#10;cDGdAgY1XQAHNFwAAQAHDQ8ukP1+CAAGNV4ABQ4vkDK8BTVdAAcwXAAjV54IHAwu3AHdAhY&#10;uXQApIuZeCB0vvADcAi+8ACTNQgknbD4S/AEtoCgADlAbvOAe+gaw91ZML+N2/CVgFLjSOC&#10;3oXP52M5PDkUTlIBnUrCR0MwFTcGxpIyxrOtSsDGZ1c2IzNWN4bzNocWE4OS2ALCcIASAMk&#10;CwqFKVvcAABAhAIDGNsiAIBAQ8QSS1sDt4CEUUtXACfCAICDy7sHn8FAgIPEA1XnAIXES70&#10;Vp8IAwIPLqwcnggDDxAIzMqNoAMwHAF8BQEAAw8SM50CBBAJNKF+BQIENL8DAwQPL7wDfAU&#10;BAwQPEi78DnwXAQIEAhMyjhUBBRJIJywcEH4FAQUSiCkzXAAv3AHdBRIufAR8AgECBQITLs&#10;wmfhQAAXwUJAxjAgEBAhPJKBEvFHyYjwQCDxJsAZ0IAhSwPSPhLgIUkDyeAgMCEzBEnQIDv&#10;AIl4S4UIlTYJLAuEuITAAAiJG0EAQ0XGwAQYhLpKUAeoBqfAggPBy50W58CBw8FLvwCnwID&#10;FxEuXAAi4C4iVDAiXGQGVGVycmFpbkhEYziAEKIrwQFHYIMDBA8RQBHCL1wAYEQzXAACAg8&#10;SABIwvABiPkATMHwBYCwy3AECAQEPEYAx3AFiYoAQMHwBYW4AMXwBAgIDDxBAMbwAItAtAU&#10;ARogEqQA9+HQEBEgBlM18AFkAQM10AGjUeARyAMXwBElcsgBCCL9wBElUsgDF8ASLgbDIcA&#10;QIDBAIdwDEcASJxbcAy3wEFAhsznAIT9S5iLzwCErYsQBEwnAISGM4yfgEDCxLYszF/BAwP&#10;GDKeCAEMIpiqMB4HAwsSNEkwHgEDCxL0STNdABYy3AQCAwsCGAAzHAQCDhkAEEIvPAsBAQU&#10;OGC7ADXxBIpIxQBEwvAAikTHALYAOfAUikDEyvAAiMSUAMRwBIrAmMrwAIhA2AQAQQACMCg&#10;IEDhhAESwwEHwCImA3MkwBAgMEDhnAMYwDIjElgDEcASLxJUAxvAACAQMOCgAxvAAi4D4yz&#10;AIiAEAzPwIGDgsyPAIiYCgz3wEFDgoyLAYBAAUOCzV9AQoyLAYiMSiAMl8DBwIKMmwIIqE/&#10;QDEMDiLBQMAxXAAiIC8yvAAioDMyvAAioTZAMcwOIuE1ADF8ASIgODLMDiJQODL8AgEABA8&#10;GMuwVAgEBDwXAMQwUIiE4ADGMFQUAAw8GwBDAAGxMAQAFDwYy/A4CAwYPBcAx7gADBiJY+D&#10;FdDwYiCPozXgACQDG8GAMCBRcCwBIwvBgSNDEyvBgStzKAEIIwXA8SNTQSMFwAErQyM38ZA&#10;xcCMqwEEvQ0MhwZAQIEDwEzvwAFDwEyvwABAQ8zvAMStThAMb4DAQE0PAUStDgyvBsBAQIX&#10;AzI8BSLwQDI8BRJHCMAQQi/8FxKkBTIsCQECEBECMjwIEiQHM7wDAQ0RAgAxXCESVAo03wE&#10;PBQAxrAoSSLYyXgMCDiLgIzBcCRLotTN9BxE0LgwBDHwIMLwJEtjyMhwBAQEMDwkyPAIBAB&#10;ERAzI8CBJFCIAyfSISfEQx/AUBEhECADE+CAIRfE0yvAB8FywcBCIAKAEAEg8ELiwVnQIRN&#10;V0ADTRcABJEETMdAQ8wvACchhIQbDEcBxJkDzLcEBKEEDJ8BAMBCQIFQBEwfCIBAQgCBDJs&#10;FBI1TwAyjxUKAgIyvAABAgsCAjK8ABJw/DVdIQgyzBcBAwsCCS5cJCNSLwYHLzjd3QIQLiA&#10;+I4I+Bg0vvAC9Ag42vAA1XQAOLxwBIuAvIoRjItShEAXAACXCpQ0YJ/RnIvB1LVA/EMTYAC&#10;rcL3wiIqCYI+RnAVR1YmUlhpcZCS8JBUkiSTQZEpBiLMw5aAgiRIsnCAEmlHoBQQAZCRAIL&#10;EJ0BSLM6WwNJBCoEvZlAxowvQFLfQ0aMLwBfgIBGzdcAC/cAirFAUcVQHUBVXADHDAFAUxl&#10;DhwwJAJkCCIWglRvdRZWqCQIQWlyQURvd24CHRAvFQpNIiKUHRAvKQJKIs1sHRAJiKR0hiL&#10;wyDIUHCKyyYARMBQfInDTMgQjIpDUMjQaInDTM7wAARsPBsAxdBYBARsPCDK0GwEBGw8KMv&#10;QXAQEbDwszdxMfDwwzVxggDwkyPgIDIDR8ASLQ2TJ8ASKyxoARMPQaIpDRMtwBIlDVMvwCI&#10;hDTMr4DAx8iZCkw/AUiMMgydBwi0tMAESQEKSJg2jLMAgEBHA8FMgwCAQEbDwk07gYXBzIc&#10;AQECHhcHMg8FARwXM+wGAQIfFwc0rAQEFwiAEcAAMiLIcjGQzhJ3GQIdHy/QwZxWBBQCFYA&#10;RoAHNAQ0yNC8BABACEjMHGhACEC6FPyIdXGkBJDAEAyAIfVIlHDBmIkC8Jw8AJjAEG4FoKC&#10;luACkwHPRnI0yVJ6QAoAECMrDl7SrNBTTcBBIYgHUDNtwBABowAAAAX13rQ8hS2MLhfIRE7&#10;vw3v9Ttqr/6CMQ9AADIQgAAIEEK16M8AACAv68AAAA4zAftCT3cARLIBSJ8SxLo1W0MPilc&#10;AHwBIqy/fQBA3AJ41+wIbAf8A20EQs0EgxoQbmECABNhjAAfxGkAVy8AAAAkcyQwMEZTJDI&#10;yRHAkNDRCYSQ2NjlyJDg4OGskOTk2cyRCQjR0JEREMmUkRkYwcjMAAABXb3JsZHxFdXJvcG&#10;V8R2VybWFueXxSaGVpbmxhbmQtUGZhbHp8S2Fpc2Vyc2xhdXRlchMB2UPaEduQrRHTfABsF&#10;wHQEQMCbAAYAaFtQHgYA1ZvaWRUbyKYsWitZAJsASPdvzginH15JAJsUwHeyvoAfAdsAKkd&#10;QHwCaCgga4wAbBZkH2wTE6AefBVsAMwWdBxoOCP8gJocMTJsBm0YAzWcA3wC/BxsATJcAXw&#10;CILeMAHwjbCpsHDLsA2wtbARsKGwBNowA/CM6jAB8CGwNNowAbBBsBGwNbAEyrAF8AuwNbA&#10;EgABiMAHwsbDE2DAVsaWwEZIYiKI4nIQ0ENSANfALgM2wBMmAGfAJwCmAPbAEyjABwQ3wIE&#10;gghbAEqjABh1wEisCfMAGwJcEU+nAB8CSADnAB8CWwTLjwBbBH8DnwDzQBAbK9gJCqMAiqs&#10;AHwObAU2PAFwL2wEbAZsATIcAXwCbAhsAGwBNowAfAh8IyBDjADMERK580A2PAJsBM0AQGw&#10;TkLI+sAAjDDUxNBpwGnAIYApsATIcAXAsbARwKWwBNowAbAhsACIQbTaMAHwIbAQ2HAFsEG&#10;wEbA1sATIcAXwCbAhsADpcA3wDbAAgA4wAbAo2rAF8ESBzAAggA1wDOowAfBp8IzbsA2CJb&#10;ARsMWwBMnwEfAJsCGwANtwHbAR8CGwEbAEyHAF8QWwEbA1sASqMAGwv8IRsAyAHnAB8DWwA&#10;LlwCLjwBbAQgJxATbBN8CXwUKgwDfBpsGGwtbAR8AWwBOowAfAg2jAD0yJB/eMhkrHAYItR&#10;6MlABfAJgDz6MAHwIYA98BTIcAWASfAg+AANsCGwAOgAKfANsADqMAGwNbAR8DjI8AmAtbA&#10;R8EWwBNowAbAhsAC4wCHwGYDNsB3wIbARsATIcAWwQbARsBmwBNowAbAhsADpcA3wDbAA6j&#10;ABsDWwENqwBbDR8NT5MB3wIPowAfAhsDWwKNlwDfAggZ+wDYIn8EWwBMswCfAJsGmwANtwH&#10;bAR8CGwEbAEyHAF8QWwEbB9sASqMAC4wESAHnAB8DWwALlwCLjwBbARsAD7cAXw3bAcunAB&#10;sFiAvfAtsHGwSPlwKbA82PAl8AnwIbBZsASpMBXwGbBZ8AvwabAEyjABsEHwIbAZsATaMAH&#10;wVbAA6vA18A2wAOowAbA1sBDasAXwvbBZ8EWwBMjwCfAJ8CGwfbAE2jAB8CDqMAGwQfAhsD&#10;WwBMhwBfAJ8FWwAOlwDfANsADqMAGwNbARsCjKsAWw0bBZ8EWwBNowAfAh8GjqMAHwIOowA&#10;bBB8CGwNbAEyrAF8AnwVbABsATaMAHwIbA06jAD8ETaMAGyHfAh8EWwBMqwBfAJsEWwALtw&#10;PfAZsXmwEfAhsBGwBMhwBbEZsBGwGbAEqjAB8GHwIfAJsAHwWIAOcAHwJbAdsBj48ATKcAG&#10;wM/A5sF2wANowDbAx8DWwEbAEqvAH8CHwsbAR8AWwBOowAfAg2jABsTGwgPvwbbA0+jAB8C&#10;GwNbAo6PAI+zAJsCGwAOqwNfANsAD6MAGwWNuwDfAL8GmwBOswCICMcAXwVIEfsA3wafA02&#10;XANsNHw1fBpsATLsA3wCfAg+jAB8CGwNfAUyHAFsEHwIPuwDbAR8CHwFMhwBfH1sDXwRbAE&#10;2jAB8CD6MAHwMfBE6HAFsBGwANpwObAdsDWwEbAEyPAJ8d2wWbA1sATaMAHwIPtwQIEuMAG&#10;wWOjwCbDR8EXwabAEyXAN8AmwEfCNsATKMAGxGbA18CGwBNowAfAh8ETqMAHwIOowAbBB8C&#10;GwNbAEyrAF8AnwVbAA+bBEg+4wAfCx8I3wpMpwFfDh8NWwxbAE2jAB8CDpMB2wHfAg6jABs&#10;EHwIbA1sATKsAXwCbAQ6zAJsfGwNfAhsATIcAXwCzAgTQG4qjABsFCIMIGwEbIFsCXyUbAE&#10;+nABsCi6cAHwQ/AnsF2wLKiwBfAtsBHwHbAAuLBMgf3wA7Bx8M3wlfAFsASqMA2wCbBx8As&#10;wBO4RYbCV8HnwFNhwBICeMAGwubBI6rAFsBGwAIAAcvBF8JyBHTAcgA2wIfBEgA9wHPswCb&#10;F5sCTb8CHx9fBFsDWwBKjwLMrwRfAQuHBEynABsAi6cAGwHfGx8DGwOfBJsASrMAXwZbARs&#10;A2wAIA+8EewMfB1sH3wJbAEqjAEqjAB8ED6MAHwIbBEuHAF8BiAnrAJ8EHwSLowBbAJsDHw&#10;CbBBsACAAIJwPIAAUDAUMAgAAAAEAAEADAABAAAAAgAAKAwAAQAHeyvoA0BEDAmwABAAAAA&#10;EAAEB8AgIJAAAAA6wAM4wAAQQAAEBsBAECAAAAbAEyHAF9AgWsCCAgjABsDXwRbAoqrQEBz&#10;BaAGgEAAAAFPUwDfAV8GyoMAWwY/B58CHwBPowAfQQGOawBfAM+rAFsIyAjjABsDSAnzAJs&#10;CT5cAyAAAB2MAGxefEcufA18YGxwbANsADYdDwLcjnwFbAEyHA98AnwMICOMAHyOfBFsCiq&#10;sAWwLIAO8AnwcbBEgAACJfA5sXWwAILMMGGx2fHEqHA98cnx4fALsfWwBMowAbIDseWwBKo&#10;wAImwifAh8AmwAbAl8DWwBPpwAfC0unAD8EnwCbA4yjAB8C2wObANsADbMFHwZfBFsCmwBK&#10;jwCbAJsCHwCfAx8GGwBIACojAB8Qj5MB2wEbAAgA8wPIABAbAh8dDq8BvyBfHZsASqcDnwG&#10;bHl8AmwAbAkgB5wAbAdsBio8AWwH/Alsg2xENowAIlw2fA1skmwBMhwBfAJ8CCAjjABsDXw&#10;RbAoyrAF8FGwEbA1sATaMAPwRIAAcjAB8LGwxNgwFbIZ8LHxJbAEyLAZ8AmwIbAA6HBJ8CG&#10;wEfAUyHAFsEHwRIABE3Ad8OWwxbC42LAZ8NSADbBE+jABsOjqMAHyAbA1sEmwBKjwCfAZ8m&#10;HwCbBVsCTJ8CDKcADp8A3wJbA5sBGwBKswBfBBsDnwNbAR8AWwBKowA/A18AnwH/BJsATqc&#10;AHwJfBcgn5wAfB0+7AR8A2wANmwrbCd8A2wAOowAbCZsBHwFKmwFfDJ8NHyJbAR8AWwBNow&#10;AbAhsACAfjBLsDTY8AnwCfAxsADpcA3wDbAAujAAgAARsCWwwbCdsLTa8B2xUbG06TAh8CD&#10;6MAHwIbA02HAFseXwIfE9sASo8Auw5fAJsFfwEbAE+nABsDi6cAGwMbF58CWwJbARsASosA&#10;ewEbAdsBHwBbAEqjAD8EnwCfAdsHHwEbAE6nAB8CWwHIJ+cAHwdMhwDbCB8K3wibCtsAC58&#10;DiAPjABsJnwIbAoqbAX8CHxKbAR8AWwBNowAbAhsACCT/BJsGyCfzAhsNDLMCGwC7EZsHCA&#10;DbAlsCWw5IGNMCGwWfBE6jAZsBGwV/ARsASqcCuwgKpwAOnwDfARsCWwEbAEqLAF8EPwpbA&#10;R8AS68AWwC7ARsCGwAIAOcDjocAWwNfBggZ4wAbBo+PAJsBGwAIAPsAzqMAGwffAg27AN8k&#10;mwEfC5sATK8BnwCbAhsACB/jBJ8GC78CDbsA3wCbB8+LAYgS4wAbCw+PAJsBGwAIIfcB3yA&#10;bChsM2wBKowJbB18NXwC/DF8BGwBPpwAbCAunABsB/wJbA5sBGwLKiwB7ARsB2wEfAFsATa&#10;MAGwIbAAgH7wFfMc+TCp8ESAjjABsDWwWbHc2XANsDSAj7AN8DGwAIB98BPwRNswCfAJ8DG&#10;wAIIscEnwabBY2jAl8Gnw1ICPcB2wNPhwBbA18EXwOID9sCHwRbA067ANsBHxQNjwCfAJsC&#10;GwAIBvcB3yA7A1sASrsAyDLHBLsIHwqKgwEbDBsp3wCbC1sADq8BXwDbAA6jABsDWwEbAoy&#10;rAF8QmwEbA9sATaMAGwIbAA6jBF8A2wAOowAbA1sBDasAXwUbAR8EWwBMjwCfAJsCGwAIPf&#10;sA2wjbAAgZ3wEbDp8ESBj3Adsj3wRbExsASqMCS4cEmy1fAQu3AIynABsAi6cAGwHbHp8DG&#10;wObCBsASrMAewEbAdsBHwBbAE2jABsCGwAIGecDWwRbAAgZ6wJbBFsACBnfARsOnwRfJY2T&#10;AdsBCAj3Ad8DGwAIGfsA2wRbAAgZ2wIfCx8ETZ8DWw0bARsMWwBMrwGfAJsCGwAIBtcA3yA&#10;/ItsATKsAXwCfBFsi2wBIBuMAGwNOhwBbCJsBGwfbAEyrAF8AvwRbAE2jAB8CGwNNowAbCh&#10;8CGwNbAEyHAF8AmwsbAA6nAV8A2wAOowAbA1sBGwKMqwBfBRsFnwRbAE2jAB8CDpcA2wHIA&#10;OMAGwNOhwBfBR8CHwRbAEyPAJ8AmwabAAg9+wDbCNsACBnfAQgY9wHInw6IkwifCJsADasG&#10;HxLfBV8BWwBNgwKfFQgj4wAfB4gI2wNfAhsADp8CXwDINt8BCDb7ANsPyCLbAh8FSAjXAxs&#10;gmwJLtwQbEEgB+wRbAggIywCfBBsAD4cBiAAAACqjAB8hmx5IABo7BEuHAZsumzAfALcNCJ&#10;c9TNM9ewEfAQgACT8FnwpNhwvbCwiTDo+jAB8BCD3LAYgAGzsESKsKT4sC2yRPowAIPu8C2&#10;wjbAA+PBAgAEQsBiAAbOwRIANMDCAAAK2MACAAAAAAo+wRIpxrPiwwbJw+fDwgACSMACJcJ&#10;D6cBWwEbAA+3DEgu4wAOtw6IAAkHAogAwwFfIYyrAoivDsijFN8T2wALox9IF98AGydfBMi&#10;vIpsGHwRbAEybFB8AmwhII+MAHwabC98FzJcA3xnfBpsIWwBNowAbAhsACDTrBF8I2wfNnw&#10;EbCt8LCCPbAh8GiAjzAJsH3wjfCAq/AhsC3xrbANsACAv/A9sVnwLfA5sEHwNbAEqDAIqjA&#10;AgJ7wDICccAWwifBMuzAJsqfwabAM2bAMunAA2XAIgF5wAfA7MFDNcamwTfANsAC5sB3wa7&#10;Bh8EmwEfAUybAZ8amwEbAZsATaMAGwIbAAg9wwS7Cg2nAV8AnwnbAAuvAYujAhsPzI8DS6c&#10;AGwOIFOcAHwTfBhsGjK8CHwCbBMyjAB8FWxTbANsAC4sBCAffAB8WHwL7BB8AWwBNpwCbBB&#10;sAC4cAnwG/Ah8A2wAIFuMADLsB2wULmwDLpwAfBZsAC7sAiAXnAA2XAdsESALvAQ+HAFskW&#10;wEfApsATL8BnwCbBtsACAASFwSfDE+zAl8NnxLIE+cAHySMtwBbBbsU2wTfEUubAIgH9wRP&#10;vwALgwCfAEuDAJsAvwUbBRsAC7cDiBvjAB8LewWfBl8K2wUbAEqzA4unABsG2wALnwDIBec&#10;AHwOfAku3AFsEfwTfANsAC7MASqMAD4cAWyOfExsBmwBKowDbAJsDXwCfAxsGWwBOowAfAQ&#10;gk+wSOlwDfCM67ANsNHwsfCVsATJ8BHwCbCNsAGwBOowAbA0+jAB8CDrcB3wDbAAgA4wAOq&#10;wBfBo+PAL8Iy4cAT4MESAffAB8LXxTfA5sEHwBbAE2bAUgAywDIEuMAHwzMmwFbAL8GnwZN&#10;mwDLpwANuwCIBecAHwObAdsEDZMBWwYbAA6nAl8EmwELhwBPvwHfDl8IGxzbBF8AWwBMiwC&#10;fAJsDHwVbAE6jAB8BCBLjBI6PAJ8GjLMAiAHbARsKnwrbCNsATLcA3wCbAR8HmwBOowAPhw&#10;BbAhsADq8B3wDbAA6jAA2PAI+3AMg/3wAfDdsZnw8bEt8AWwBOswHfE8gi4wAfBoyzAIgH2&#10;wIbCVsJ3x1bAx8AWwBMuwEfAJsWHwQbAEgP4wAfBEyrAEgJ8wDfD9sDGwebAEyPAN8AmwEf&#10;BBsATqMAD4cAewnOhwBIAOMADY8AiAfXAQgN/wABkQwBANQSUtTGGCkAQAAABB/ACAAEXwl&#10;aAFtKkjOBBI8ZAIAAwAABgAAACMEAAAIAABAAAcPAQAQAm0CQGwUAf/////dAgI1XQADNV0&#10;ABDVdAAU1XQAGM10ACDU+AggPND4CCA82HQEHM30BCTV/AQkPHDO9AAo1vQALNV0AFDVdAB&#10;U1XQAWNV0AFzVdABg1XQAZNV0AGjVdABs3XAA0ngUbDzTeBxsPNN4HGw803wcbDx4znwUbD&#10;x81XQAgM10AHDUdARw1HgEcDzQdAR01HQEdNR0BHTUdAR41HQEeNR0BHjUfAR8PDTO/Ax8P&#10;FTVcADTfCh8PHTW8ADT9BR81nQIfNZ0CIDX9CCA1nQ4gNf0IIDX9CCA1/QggNX8EIA8OM78&#10;DIA8UNVwAND0FIDUdECA1PQUgNd0HIDU9BSAwPAUBAAAAQHy2AARSb2FkUmFjZUNsaXBMZW&#10;Z0AAwZFQAgLG0WTm+2EwURLlwAbAgBEQAAACoMAQFSaWdocQgNMrEADNMFQ2F2gA4BABMCD&#10;i6dAFCSDQIUM18ADgoPNV0AEzNeABAONB4BEA4v3AFwGQkNAAAAQXJlbmFGcmWAFAECAwwP&#10;fddRErvPAgwO7wEAAwxsBXoBQBMu0AAGQm90dG9tAwMLJ7gAAQIDDBVsBdkIFO8BAAMMdgc&#10;AUnoLAwsnXwACAw0n7wADAg2IDW8HAAMNaCjcBSgJAiPoEA5XYWxsUmlkZUxvb3BTdGFydO&#10;AZmzICAw2UGWkdIj/IAJVBA7APBFMAAEACAw2RGFRiNAMNgBdwEgECAw0W4hoDAqwEfwIAA&#10;w2AGrAboCC9CA6QG70IDoAa3AKcCNwCjAdlFSEupAIBU3RyYXRM7BtjFQIDEjhoAy7AAJMh&#10;AAMSnSpViRsSiRtWiRsSiButAROYE60EE4QM3AKMBNwCmBa9AhScBXkWID7YAgNUb3ADAxU&#10;pDQIUnQtXjUEViCTMCowN3AKYIr0OFJwO3AKcF30OHy7cAQNCb3JkZXIqswQAAxU4mAIsuA&#10;CLJQIDFYkTWJkjFZkRWZkmFYgQdj0CBCimDAAEqFOFPwQpGQwEtEB+BQAEKekLBCnpCwQo6&#10;gsABCm4C8wKbgcCBCjGCQAEKZQJKX4BAgUpPQIFvBF4I2yeK4gPAlRvcAEFrA5+FQEFKb0C&#10;BSm9AgW9FVoSMdsFKM4BAQUp7ALcCG4UAAWsF38FAgUOmDx9CwLMEW4EAgUpHAPMCn8FAAU&#10;OmDl9BQDMEG0XF+g7LIwGfl8DBLBqeQoA2A1oBifwDKgGLiQMqZUAKd0CAswPcAcifC+MJb&#10;AH6EiPQgMEDolRXHxAzBdtBh4sjAICQmFycmks9wkDBA+QW3QFJ7AKpAwttADBDQ+ADWcbA&#10;wUHfTcAbwEABgeQUnMkAwYGJ18AAwUHbNKupAYGjAF/BQIGB4BXbAEBAwUHEmiWzAeMAZqO&#10;BgiMCpqRBggnvgACBikxCQawSWI1AQYp4QgGKeEIBinhCAYp4QgGKeEIBingCNwIbhMABin&#10;hCAYp4AjdDlt9gwWgudwFmClhMQDcFJ2GBqwEjYUGKbgWzRBdvAiMHG0HAtwUbgoCBilgCt&#10;wFfh0ABilgCiuMA7wUfQgAzRlenQsOnCm8EawBvREOnQ5frASMAbwOvAt9CALcDq0HD5wIr&#10;QcPnAW9AhApXQAQKV0AEYwiaEwvbBw0DgwDBiopARGJTmB5Ewa4CmgJL0gXe+xFbmTgY2Nx&#10;AAYSJ+gBJ/ANKlgeKbwAn1sCBhKQDWAMKIAPBnJpZGdlQmFzZe4LAwWtsGNuEgUVmF3MAYh&#10;czAGIWcwBmCFvAQIGG4wSbwEDBRuMkW8BAAYbnMBvAQIGG4y5bwEDBRucj28BAAYbmBO5Mx&#10;ycCG8BAwUcnAhvAQAGHJwIbwECBhycCG8BAwUcnAhvAQAGHJwIqWsdnAipbh2MB9wCjAfcA&#10;p0FYn6LBiKdBWF+zwYinAXcApwF3AKcBW8WAwUljBPMASgNAgeohn4RAQioiYmAB7iHzAGc&#10;KW4EAgcoyhABCCnKEAcGnCysBClpEAeog34IAgcpORAHKTkQB7iBzASMFrwIqIluAQAHqIC&#10;sBKwK3AKcIGp3AQi4e2plAAcoDgICB6iMeoQBCLh+bQQC3A5+CAIHKXgP3AXMDYwlaFEn7A&#10;oOVHVyYm8yU2xvcGVVcERvd27kUiL+IgcPgC1yCgAHrICwE7TRYg8AB6Abbn0BCKyAboMBC&#10;KyAbgcCB7x+sBYpYBnRE2RyXgcPkBO8CKjIvAi8w3EWHPDPNcMNAQgXgWdlcvgIF4A9zAGA&#10;OmJGAgcosgwAByiCDAEIKOIMAgcosgwAB6BkbgcBCKBnrBoosgwABymBDAcoggwAB7BinAX&#10;ATG0BANBTb64DCAicFGI0AwgpPRsIKNIHAAiwRG4EAQgp4QkIKeEJCCjiCQEIKe0ZCLwzvA&#10;4o4QkBzAp+AgIIKcEICKBMrA28C28oAwcXkFPMAYBbj7QIHAts7ZGpCLwprAopfQQIKH4EA&#10;Qmgi30LAMwu3AWQfW4BAAgo3gQBCbCM3AWMRJ7ECBx5qQDcDowHM48IVG9w6FpjuAIIHYxa&#10;bQUdLjwJKawAk7cACB2RG2Z2lAgdgQ5ndpQIHYARchUCCaSHbgEACbSOgTsJKWEHCaA7cA5&#10;gBwhTY3JlZW5TdXBwbygNNwLBBmhhDAkkpCJgBmTcK8AANIUbAcwPegcCCSRwI20BANkKaX&#10;BizBW9AgmQ62gMZN87iAFygQkKkWtqcnUJCpBWrAq8HG8KAgkJlNLMBJBufiICCSkxCwmwW&#10;X4CAQokzD1yOwEJKWELCaBPbgQACaBbbwEBCgyAT9wFjAF+AgIJKZELCbBcfgIBCiR8O7wF&#10;vA52zwIJtKt20gAJrATcAnkzANwCjBl+CAIJKYEMCaBkfgIBCiQ8PNwLjAe8CKCkvAgkDDz&#10;cAoBV3AKcF2bdAAkksDpn3QIJEpwsY1sBCRGMNMwEnCncAowT3AWcDnNxAgkTkHRiZAAJJH&#10;A73AKcDtwCnA69AhQpvAAkcDvcAim9ABQpvAAk4Dq8CCSUOSKDOgEJFpBqkaQKrATMAZwXz&#10;AGMFswBKkwBKa0BFZwCzAopXQMhKZ0CISOEIL0gIJwOrRYhKR0BIZwIzAScCKwlJKQhvCkk&#10;pCHcAowH3AKMB7wUKKchAQolnAh+PgIKKc0PCinNDwqsYX5BAwqsfp0FCym9AAu8BW4EAAu&#10;sBGPgAQsJjGqdBQwpvQAMKL4AAQy8BWx2cJEj9DYGQ2hlY2twb2luJzdIAgwIiUVrZokMCJ&#10;hJaQYa/J0wyAAimTwMKQECDSkBAg2gEGITAQ4k9DVinAENKLIDAQ0oYAJ4DeSuCUV4Y2x1Z&#10;GVyAw0CECIdaW1xkA8oLAABAw0CEilcAIwBZBVgkpIbQmkjaCIuyBOFuRAkmCZ8BSc4IzW8&#10;ALW5ECQcKGIZAw+hGW5muxEFmSVveiURBX0XAJ4CEgQoXgASBJwCbwcBEwSENXRgAQITAhF&#10;gGHAQaEgEQ2xpZmYxMiLLVE1lZCbWVQMSqB50BHw2MJQAghQDErQheVkAwAuxDAOADprQEw&#10;OQEprQEwOQEnlcA38FAAAArAe8BawHsBWsB6AarAegGqwHvAWsB7wFrQcFnA68AqwBvAK0P&#10;bwCrAG8CKwBvgIPD2Aja3kDExCcFMwBjAq+CA8TKYwAnBpnRAIUAowHbAEBABQCDWwEbAEB&#10;AhQCFe8BABQCjAedCBmkQZ0OGbA8nREZrBYiYksCGaA+ImJLARqkWqwHpF2sB7wCbQQA3AV&#10;uBwEaKI4AARooPQ0m/GkmPCr4VAFDb3JuKFREA1RvcAAZCYQgYUApIAXUACXtRhmoEoknGa&#10;B0ehYBGql8cnbxGQmJJ3OMAagVf1QDGQOUr28BABoDhKh3jgIaAideAAIaqD9uBAMZuEnMB&#10;IAW3AKcC20BANwFbwQAGgInXwACGgOUpm8EAxkDhL3MBIwBdt8DGahOdt8DGahRfhoCGrAj&#10;bgEAGqwZfggAGynNAhspzQIbrBZ/CwIbAiedAgApXgAAGyltAhusE38FABsCnBFuDQIbKd0&#10;BGyndARwp3QEcKd0BHCndARwp3AEpXgAAHCndARwp3QEcKd0BHCndARwp3QEdvA5uHwEerD&#10;duFgIdKQ0CHawQzASMH8wEjAF9AgAsjACMNG4EAB0pbQIdrBN+BQEeKb0GHbwUbjQBHrw1b&#10;jcBHim9Bh0p/QIdvBdqZgIeqGxqZgMdvFZ+AgMdrFJ9AgDMBG5YAx2oaW5YAR6sCm5YAR6s&#10;B240AR6sXnl5AcwHanUDHSj+CwIerBBuBwIerA1gbSLoLgNQeWxvbnOIyQ0ECAIMABAgAHQ&#10;AAEAECBwMIsiCrAECAwwEAADeAhMMIuiIvAIkNDONAQN0kM8HAxINJ+8AAwMNJ78AAwsNIo&#10;iEvgUPDSLog60BESOQIo0BBCkeAQQNKB0BBCkeAQQLKO0ABSm9AAUpvQAFKb0ABSm9AAYpv&#10;QAGKb0ABim9AAYpvQAHKb0ABym9AAcpvQAHKL0AACkPBQAIDScPBQAIAyfcBAEACAsMJ+0D&#10;CSl9AQkp3QQJKX0BCSndBAkp3QQJKN0EACncBCL4Yf0vACnfBAAECyifBQUCDievBwUODvw&#10;FAQQFAw4nvwYFCw4nnAIliFyNNAYp7QAGKe0ABintAAYp7AAlRFSNBwcp7QAHKe0AByntAA&#10;cp7AAl9ERuBwAIKKwEIsQ/7hYACCiuBAAIKI4DAAMorwEAAxEnjgMAAyisAQEAAwsO71IAA&#10;w8nvgMABCnuAAQMKO0ABCnsACVoZ4wTKT4FAAUpvAApPQUAJWhlnAUpDwUABhUofwEGAw7v&#10;bQAGEyg8AincBCJESSfsAyndBAAp3gQACCn9AggpPQIIKfwCJaREnREJKb0ACSmtBAkpvQA&#10;JKa0ECSitBAR45f+GGgMP7RMEaNL9AhspXABoxv0CHCldAB0iVCPNiB0pXQAGInAo3wIGDB&#10;AnfwEGAxAnrgoGC5i7bhkEBym+AAcHKL8ABwMQbD1on3z7qJ8IUmVmZmluZXJ5BAm5BnV6n&#10;wkJmAasAbgGrgEHEGhiaAhsaagIBkhpZ2h3YXkAFr0XdiKaLBYEnCCsAajVbRMAKS0DACkt&#10;AwApLQMAKS0DACktAwApLQMAzBluCgQIIogt3yMIBxEnfgQIAyNImo0ECSmNAAkpjQAJKY0&#10;ACimNAAopjQAKKY0ACymNAAspjQALKY0ADSmNAA0pjQANKY0AEimOABIEKM0CErj3nSYVoD&#10;KsAbw4rAGgMm4BBBa8CKwBvAisAbwIjR8ZrAStAQgorQEZKTwCJTQrbgQAGrwOrQEDgEGMA&#10;SIoJd5WABspXAAiqCP9AhwoXgAEHSneAR0DKN0BHildAB4pPQIeKTwCyPl+DgQGItQz3zsG&#10;DBInfwcGAxIp/AsjGCOdBQcpvgAHByi/AAcDEnxfbQQAKc0IACnNCAApzQgAKc0IACnNCAA&#10;pzQgAKc0IACnNCAApzQgAKc0IACnNCAApzQgAKc0IACnNCAApzQgAKc0IACnNCADMRn4aBB&#10;sp7gMbAyjsAyLYKc40BBwoXQAAKYwGIlgo7SsAKc0FACnNBQApzwUABgsnzQUAKc0FACnNB&#10;QDMLnKHAAmsE60BCYwTrAG8Mq4BBxJgjG5YABa8Ba0BBJwFrAEkhDufHQMCFCcfHwMRFPwX&#10;AQQDAxQnbwgDCxT8PgEEAw8UfAuNBwQp7gAEDCjtAAQp7AAlaIKdBQUpvQAFKb0ABSm8ACU&#10;4gJ0FBim+AAYVKH8BBgMU79wEBhMoPQIHKb4ABw0ovQAHKX4BBwsovQAIKb0ACCk9AggpvA&#10;AlpF+dEQkpvQAJKa0ECSm9AAkprQQJKK4EABoiND2scAEAGgMT/CwjuDTeSgAbKVwAIjgz/&#10;QIcKVwAIvgw/QIdKVwAKS0GACktBgApLQYAKS0GACkvBgAFDietBAApLgYABSitBAAliIJ9&#10;IAApXgYABintAAYoHgQABinsACUkeowHKY4GAAcp7AApjQYAKY4GAAckMFhuBwQIInRCrCg&#10;BBAgMFewoAQQIAxUnrgoICyMQUX4FAAMovwAAAxInvgAAAyi8AAEAAwsV7FsBAAMPFe9bAA&#10;MRKB0BBCkeAQQNKB0BBCkeAQQLKO0ABSm9AAUpvQAFKb0ABSm9AAYpvQAGKb0ABim9AAYpv&#10;QAHKb0ABym9AAcpvQAHKLwAAQQIAhYnjw8IDRYp3QQWKd0EFiftAwkpfQEJKd0ECSl9AQkp&#10;3QQJKd0ECSncBCnfAQAIHCfcAQEACAMW/3cACBMnDgIACCRUcG03Aik+OAIDKN00Aik+OAI&#10;DKN00AikdNwIpHTcCKR03AikdNwYpvQAGKb0ABim9AAYpvQACKR03AikdNwIpHTcCKR03Bi&#10;m9AAYpvQAGKb0ABiq8ACkeNwYJKL0DBikeNwYJvB0i8CgirEkk8CgiJFQiAKoBBgwXDSLsT&#10;gR3AABABgwYI+Q7bAEDAg4XDQEQJPU9AilGMwIDKFUvAilFMwIl3KWUMClVMgIpVTICKVUy&#10;AilVMgIpVjICBil8ASllNwIlnI+cCylWMgIHKbwAKVQyJiCAfQUGKb0ABim9AAYpvQAGJeC&#10;AnAUpVjIGCSh9AQYpVTIGJVhsfAUj4E7VqwIpJTIGKYUyBipcACmFMgYphTIGKYUyBimFMg&#10;YphTIGKYUyAilWLwIGJKQqnREGJKQqbQEGKSUvBiklLwYpJS8CKecpAhoIJ+YpAhooHQECJ&#10;WxWbAojcE/9HRspvQAbKb0AGySwSJwFKaYqAhwpvQAcKb0AHCm9AB0oJiwCHSm9AB0pvAAl&#10;IEt9CwYpvQAGKb0ABim9AAYpvgACBigmLAIGKKYwAgYoJSwCKaUqAimlKgIppSoCKaUqAim&#10;lKgIppSoGKY0ABimNAAYpjQACKaUqAimlKgIppSoGKY0ABimNAAYpjQACKTUrAik1KwIpNi&#10;sCDintAw4p7QMOKe0DECmNABApjQAQKI0ABimPAAYQBieUMQEGEAMR5sIGECScX200AikXL&#10;QISBSe+AAISKLwAJNBmpvUCEyRUNY0HEyRUNX2SBiI/ZRAgAKwBrASsASiOAAIVvBd+AgIV&#10;JAQ0jAEBFwIRAc4HAhgpLQAZKS0AGyntABso7QAGKV0ABildAAIlJC+cCyW0NW0BBiW0Naw&#10;BKZ0CHiieAgYfKK4BBh8pjQAfrASMHylGMAIGKFY1AgYk9C5tBAYpFjAGByiNAAYlFDBtBA&#10;IiUGDudhoII1QvvAIoHQECJTxlnAIpRjMCGym9ABspvQAbJFBXnAUppjMCHCm9ABwpvQAcK&#10;bwAItBb/REdKb0AHSm8ACWAWn0LBim9AAYpvQAGKb0ABim9AAIp5SwCKeUsAiKgYfwOKeUs&#10;BildAAYqXAApRS0GKUUtBilFLQYpRS0CKWY0AgModTACKWU0AiXMwZwaKQUuBikGLgYEKFU&#10;sBikFLgIpFi0CBil8ASkVLQIljKt9CwIp5iwCBym9AAcofgECByRckn0FBim9AAYpvQAGKb&#10;0ABiq8ACl2MwYJKH0BBil2MwYJKH0BAil0LSJowyZVKQIpdi0CAygVKgYpFS0GKRUtBikVL&#10;QYpFS0CKVUsAilVLAIpVSwCKVUsAilVLAIpViwCByjVKgIpVSwGKb0ABim9AAYpvQAGKrwA&#10;KVYsBgko1S0GKVYsBgm8HY6FDBcjLHWtARgj1DCPAQ0XFSI8JgEAAAAAIuDqIjQnBQgAAAB&#10;EaXJ0Ijh7IuyFElTiAXgAAEAyLAAiMNH8AiIAZgEZAAAAI2VwAByknAJXYXRlciohAXkpIA&#10;EqLAAqIAEiHEIipO0BEAAAADbgASpdAE8pTAHwEHASKowANiwAIoDSbAVwHHwOIvg1IixUN&#10;rwAKlwAMuwAIrhxKlwAKrwANiwAfA0BCgAAACIYLTaMADZMAewHbBcgD+wAIthYbA4gE8wC&#10;7Ad8DwFJMAQDfCYi5O8uDAAiSDdg930ASyUU8Xw6YE4qDQBNzAMBLAAAAGwJbAMiWIh8Imw&#10;BNh0AT90GTBxIpGoFAEB0AAHwDQkAbwAAAAAu7AAiRPMBAAAQCWwAbBN4BWwA/AR9A1DcCt&#10;BZEviyGpionABtBVHdA0lwAa0AQGBnBlRNQ2FueW9uMXBoACBhdGU9MjAxNy0wNS0xNl8xO&#10;V8wMCBTdm49NzQ3MzUgR2FtZVZlcnNpb249My4zLjBSMCQo9mAJrwoAAFPADWwCcCh9AlTM&#10;AiJIx+AYcFhsA+0AVcwEfQFWzAF8BewIAAL/////AAAAAAAAAADgkwQAAd7K+hEAAAcwCQN&#10;QSUtTBAAAAP////8UMAkDCgAAAAEAAAABAAAAACAJAwbwAwMBAAAAIAAAAA8AAAB4nGNgYG&#10;BgZMANAAA8AAIH8AMDUElLUwQAAAAAAAAAACAJA1BJS1OYAAAAAgAAAAMAAAAAAABACQAAA&#10;ENhbnlvbkNhcgAAAEAIAAAAVmVoaWNsZXMAAABABQAAAE5hZGVvAACAPwAAAAAAAAAAAAAA&#10;AAAAAAAvAAAA77u/JHokcyRpJDA5Zs+BJDAwMMK7JGFhYW9tYm8gJGZmZkx1ayQwOWbDqSD&#10;upaQTAAAATWVkaWFcRmxhZ3NcQVVULmRkcwAAAAAFIAkDUElLUwQAAABSJgQACCAJA1BJS1&#10;MEAAAACQAAAAogCQNQSUtTBAAAADQAAAALIAkDUElLUxwAAAADAAAAhCMAAAAAAAByRQAAA&#10;AAAAFImBAAAAAAADCAJAwAAAAAOIAkDAAAAAA8gCQMGAAAAa3JlbXN5ECAJA/////8TIAkD&#10;UElLUwgAAAAAAAAAAAAAABQgCQNQSUtTBAAAAAgAAAAaIAkDUElLUwQAAAADAAAAGyAJA1B&#10;JS1MeAAAAAgAAAAMANAAJAFImBACEIwAA7iEAAODgAwD/////HCAJA8GI9Mtsc3SkQJRk7s&#10;tCB1+/DIB4haPR0PkR7EavEz7iHSAJA1BJS1MIAAAAAwAAAAAAAAAiIAkDUElLUwgAAAAEA&#10;AAAAAAAACMgCQNQSUtTLwAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAADmyJJaAAAA&#10;AAEAAAAAAAAAAAAAJCAJA1BJS1MIAAAAAAAAAAAAAAAlIAkDUElLU/YWAAAAAAAAUiYEAAA&#10;AAAAIAAAAAAAAQA8AAABfRmFrZUZpbmlzaExpbmUAAABACgAAAEFjY2VsZXJhdGUAAABABQ&#10;AAAEJyYWtlAAAAQAkAAABTdGVlckxlZnQAAABACgAAAFN0ZWVyUmlnaHQAAABABwAAAFJlc&#10;3Bhd24AAABAEgAAAF9GYWtlSXNSYWNlUnVubmluZwAAAEAUAAAAX0Zha2VEb250SW52ZXJz&#10;ZUF4aXNvAgAAAAAAAEJ7AQAHgAAAAGp7AQABgAAAAKCGAQAGgAAAALKrAQAEgAAAABasAQA&#10;EAAAAAPKxAQADgAAAAEyyAQADAAAAAC7QAQAEgAAAAIjQAQAEAAAAABjSAQAEgAAAAIbSAQ&#10;AEAAAAADDTAQAEgAAAAJ7TAQAEAAAAAEjUAQAEgAAAAKLUAQAEAAAAALbZAQAEgAAAAHjbA&#10;QAEAAAAAErcAQAEgAAAAGLdAQAEAAAAALLdAQADgAAAAHreAQABAAAAAPbfAQABgAAAADzg&#10;AQADAAAAAP7hAQADgAAAAIDiAQADAAAAAODmAQAEgAAAACbnAQAEAAAAAEzpAQADgAAAAJL&#10;pAQADAAAAAHbsAQADgAAAALzsAQADAAAAAHjvAQAEgAAAAILvAQABAAAAAAbzAQABgAAAAE&#10;LzAQAEAAAAAEb0AQAEgAAAAIL0AQABAAAAAAz3AQAEAAAAAD73AQADgAAAAGj6AQADAAAAA&#10;LL7AQADgAAAAKb9AQADAAAAAIz+AQACgAAAAA7/AQAEgAAAALj/AQAEAAAAAHoBAgACAAAA&#10;ACQCAgADgAAAAKADAgADAAAAAOAEAgADgAAAAGIFAgADAAAAAB4IAgAEgAAAACYKAgAEAAA&#10;AAEwRAgAEgAAAAAoSAgAEAAAAAPQTAgAEgAAAAJAYAgAEAAAAAJUZAgAFgAAAANkZAgAFAA&#10;AAAKwaAgABgAAAAG4mAgAEgAAAAPomAgAEAAAAAPgoAgAEgAAAAHApAgAEAAAAAEIqAgAEg&#10;AAAAMQqAgAEAAAAAEYrAgAEgAAAAJYrAgAEAAAAAHIxAgAEgAAAABwyAgAEAAAAALIyAgAE&#10;gAAAAD4zAgAEAAAAAI4zAgAEgAAAALo0AgAEAAAAAB41AgADgAAAAPg3AgADAAAAACA4AgA&#10;EgAAAAOg4AgAEAAAAAIpBAgABAAAAANBBAgABgAAAAHpCAgABAAAAALREAgADgAAAAPpEAg&#10;ADAAAAAEpFAgABgAAAAHZGAgABAAAAACBHAgAEgAAAAIhIAgAEAAAAALBIAgAEgAAAAOZJA&#10;gACgAAAAERQAgAEAAAAALZRAgADgAAAAN5RAgACAAAAAHJUAgADAAAAANBVAgAEgAAAAPha&#10;AgACgAAAAIRgAgACAAAAAJhgAgAEAAAAAGJhAgAFgAAAAKNhAgAFAAAAAGRiAgABgAAAAGp&#10;wAgAEgAAAAB5xAgAEAAAAALhyAgAEgAAAAPhzAgAEEiiCCvh4AgAEgAAAALZ5AgASy20AQn&#10;rFAs5gAW4EtHvGArh8zAQCEn0CAAN0BgFWfwIAEn6DAMRgAWYCFIDGAiaCzQSAYAGdCIXeC&#10;BiG3Qh8YAF2BnaHxgLQh9YG3ojeCLSKxgIsi8YCmpDcCAHCkAIAE0KFYJjaB4iY0AVhAQJk&#10;CwJmnAIAAnYPcJzaB8yfzgSKoMYCpKTGAqilxgJWp8QCAgSzAgABfgiks8oDWL7VD9BgAWY&#10;L9sDGAmTB2RDwYAF2BnzCxgImw80EqGABdgZCxckM7GABZgJGxs0E3GABZgIIyMUC+GABZg&#10;J6ycUComABZgLyyd4I3s7GFFbPxgKU0sYCxtLWBvLT3hG61M4EQNbOBIbWzgQ+2M4EatnNB&#10;OxgAW4NoNrGAizb1gaw3tYGCt/WBo7n0DICf+gCAAVxIOVgAXoHyOnSKVz21QbyYAFqA2r3&#10;xQLOYAFmApD5xQL0YAFmAjD/xwIyAgOvVeYCA79QbAQDvVDQYAFyDmYFxwKoCQOmXJgK1gb&#10;UCtYGnAvOBGIOzQS8YAFuDWYPxgJMENYGxBDWBmQR1gbgEsYCCBPGAhYU1QZcYAF+CHQVxA&#10;JgAYxVAYwWAwCGU8oexgsuH94IUCDfCL4gA7JWCCLKA0gjygMkJMUC7GABawxeJgOqVOAmz&#10;w06JwO+Yj4ozg22Ms4NwDLHC6YzA7Uz5mABfgigNN4IDEHdCI5gAWoD9kLGAlBD3gg6RcUC&#10;nmABbgSmR8YCDknOBIBKxgKiS8YCOEzSF0RP2hmeT84EPlDOBGpRxgKCUsYC/lPGAoBUxgL&#10;WWMYCYlnGAqJaxgIkW8YCllzGAhhd5QJh2iIEYskDwmABchdYY8IldmPKA3Bk1AZgAYKInG&#10;XSFyxn0heGZ9IFmmfaB9Bo1AZgAZYGSGnOBFJpzgTybukwb9IFVHHGC45zyjDyc8oMfHbJA&#10;/5gAWoVPHrFAshgAWYCSnvGAkJ+1gYAf8UCvmABbgR+g8YCAITOBICGwRO8YAFuBJaJxQLc&#10;YAFmAqaNxQLiYAFmAlahxQLEYAFmAvyqxgKIq9oZHK7NDZRgAW4EJLDsBGABZgKCsc0E5mA&#10;BZgKgts4EmsHeCMLBzgTQws4WHsXOBCLGzgQwx84EUsjOBELJxgJ8y8YCYszGAjjOxgLizt&#10;4IXtreCGjazgRC3dJETN3SBeXdx2Um3gMT154ADt/aNBzq3QiyYAF2GMDrxgIu7MYLDu7FA&#10;nJgAW4EcPDFAqxgAWYC7PHGAkby1gbk9MYCevXGAmD2xQLEYAF2BiL4xQLCYAFmAjr51Rju&#10;YAFmAsD6xgLi+9oZVP3FAvRgAW8EGgUEtaiSYAFnArIIBK+mxggExokJBLeWzgoEr68eCwS&#10;tlG5gAWquoAvWBu4SzARgAZZgjhPLDPYUBKK1+hXCCtYW3ggMGNkHtmABexAsGwSmm5ob2Q&#10;f0ZAJqAxIc3AhgASMCI6of0gV+I84W0iTKDJAlygzMJcMTsCYEtZ/5YAFiCqwn2gdaM9kQ0&#10;mABagNiNcUC5GABZgLyNsYCYDfCCqo4xgIsOcUC4GABeiJYOsYCLjzVGJxgAX4Iqj3WBiI+&#10;zQT+YAF2Bp4/xgJcQNYGHkLKHuZC1gaGQ84EikTGAoRFxgLURdYGPEfVBqBgAWYLOknGAl5&#10;N1QbCYAF+EdpOxgJIT94IClHFAtJgAW4EhlLGArJTzgQMVM0NmGABbgQ4VcowsFXSBbpV7T&#10;Fc1gaaXNIyDF7aB1BgwhOgYM4xAmPeCH5kzgSIZMoDDmbKAyJm1gYgaMoDcGjSDuxpzg0Ua&#10;tIFcmveCIZr0gWUbMoDxmzeCNduz0MZbwS+fSJw0gW2fMYLOH3GC4J+xQL6YAFuH6R/xgIS&#10;gM4EjoHFAvxgAW4EDIbFAt5gAWYCQofGAkaI1QbSYAF+NVSJxgKQidIXiorKFQyLxgJWjMY&#10;CUI3eCA6O1Qb0YAF+CKiPxgJIkNUGymABdg+elNYGDJXOBBqWzQSIYAFuBEqYwiVymMkD4G&#10;ABagNSmtI7fpvOOr6cxgLwnMYLNp3FC8JgAX4RMJ7GAjqe1gYMn9IFNJ/aB4yhzgTcoc4ED&#10;qLOBCKizQTgYAF6EAij0gWEpM4EJKXGAkylxjiSpdIXUKbaGXimyiekp8IKqKjODUyq0QXY&#10;YAFqDPaq3gi6vsoMRr/KDDTCxgLmxMYC4MXaByrHyQyEYAFuHwrJxQKWYAFmAoDLxgIMzN0&#10;I1GABcg7Yzd4Ils7OFqDO0gVvz81VrmABcgWK0MYUPN3dCLRgAWoD9N7GAnbfxhQM4MUCrG&#10;ABbgRC4cUCsGABZgKA6cYCKurWBqLq3hFq69oQ1u3OBDDuxhT879IFqPDFFONgAWIKoPHGF&#10;Ej+1QbyYAFqA37/xQL2YAFnAswBBafRRAIFvs7AA8YCTATHAlQLBb3X9GABdgYWDccCTA4F&#10;us1qDtcGkg4Fp9pkDwWyy5YP3QjIYAFuMe4RxgL4Ed4I1BLWBowUwgqgFMIKgBbeCGga1ga&#10;aGtYG0CDSBRYh0gVsJd4IgCXSBbIl8gUlBabsSCbSBXom2AdgAZnotmgDYRz8aANqFVYn1w&#10;bMKQW68f4p2gcIKtoHOirGFDwt1g9QLdYPgi3WD6ot3ggAN9YGBDjeCHY50gUmPsoMlD7CC&#10;mBA2QfOYAFiEwRC1QauYAFmAlRHxQLCYAFmApJKxgIeS8YLok7GAvJOxhS6T94RyFDSDopS&#10;0gWYU9IFQlTaELpUygPIVcoDQFbGAipYxRS2YAF2DzZbxQKuYAFmAipd1QaEYAFmAsJgxgI&#10;cYd4IrmXWBiZm3iN4bs0EqmABdgYccMUCYmABZgLyccYCGnLeCMp2xgJgd8YCLHnFAqRgAX&#10;YG4H7GAkR/zgTIh9YPGIjWDxaKxQJwYAF2BnSL1Qa6YAFmAkCNzQSQYAFmAvaQzgRgmsYLJ&#10;J/GApChxgLgocow+KLaB46jzjF0pM4xTqfELwLyrAUAAHxQAAoRAAAATWFuaWFQbGFuZXQu&#10;My4zLjAmvdB+DwAAhHAFLAAAADxpZD4QATDHCzwvaWQ+PGxhcHM+MTwvnAAIPGN0PjEzPC9&#10;jdD54FWwAASYgCQMSscsQcAEtDQAnKWwAI+xKKXwAEmjN+AEHFTAJA/////8YMK0JjKIDQA&#10;gSnMwETUNhbnlvbmgCCQ0AAABwYXJhZ29uY5ACAAMwAAAAJHckQURGUCQ5Q0ZhJDdCRnJwA&#10;AADYSQ1QUZnJDJBRm8kMDlGbiRmZmYgoAkAEisAAADvu79Xb3JsZHxFdXJvcGV8RnJhbmNl&#10;fMOObGUtZGUtRrgBAlBhcmlzfQ4a3RIUcAEpDABsFnkBG9wDfBV8AW0AHM0CEnABElDQbBk&#10;HaW1lQXR0YWNrHdQDKsUAHswCZCmUicQHeQAfzAN8BSKUQmUPIM0CDBKg0nAEzQAh3AJsBc&#10;oCACIxTQAjzAJ8B3wEbAp/ACQwCRMY1HwBbQAlKpwADAAAAAAAgL8AAAAAAd7K+hEAAA==&#10;</base64></value></member><member><name>VReplayChecks</name><value><string/></value></member><member>
<name>Top1GReplay</name><value><base64></base64></value></member>
</struct></value></data></array></value></member></struct></value><value><struct><member><name>methodName</name><value><string>dedimania.WarningsAndTTR2</string></value></member><member><name>params</name><value><array><data/></array></value></member></struct></value></data></array></value></param></params></methodCall>";
*/ //TODO remove debug code later
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, self::DEDIMANIA_URL);
$asyncHttpRequest->setCallable(function ($answerData, $error) {
if ($error) {
Logger::logError("Dedimania Error while Request: " . $error);
$this->checkDedimaniaSession();
return;
}
//var_dump($error);
//var_dump($answerData);
$data = $this->decode($answerData);
if (!$data) {
//TODO just Temporary
var_dump("Dedimania Debug:");
var_dump($answerData);
}
if (!is_array($data) || empty($data) || !isset($data[0]) || !isset($data[0][0])) {
return;
}
//Get the Errors and Warnings to get the Method Order
$errorsAndWarnings = $data[count($data) - 1][0];
$methods = $errorsAndWarnings['methods'];
foreach ($data as $key => $methodResponse) {
$methodName = $methods[$key]['methodName'];
if (xmlrpc_is_fault($methodResponse)) {
$this->handleXmlRpcFault($methodResponse, $methodName);
}
$responseParameters = $methodResponse[0];
switch ($methodName) {
case self::DEDIMANIA_UPDATE_SERVER_PLAYERS:
Logger::logInfo("Dedimania Playerlist Updated");
break;
case self::DEDIMANIA_GET_RECORDS:
if (!isset($responseParameters['Players']) || !isset($responseParameters['Records'])) {
$this->maniaControl->getErrorHandler()->triggerDebugNotice('Invalid Dedimania response! ' . json_encode($responseParameters));
return;
}
$this->dedimaniaData->serverMaxRank = $responseParameters['ServerMaxRank'];
foreach ($responseParameters['Players'] as $player) {
$dediPlayer = new DedimaniaPlayer($player);
$this->dedimaniaData->addPlayer($dediPlayer);
}
foreach ($responseParameters['Records'] as $recordKey => $record) {
$this->dedimaniaData->records[$recordKey] = new RecordData($record);
}
Logger::logInfo(count($this->dedimaniaData->records) . " Dedimania Records Fetched succesfully!");
$this->maniaLinkNeedsUpdate = true;
$this->maniaControl->getCallbackManager()->triggerCallback(DedimaniaPlugin::CB_DEDIMANIA_UPDATED, $this->dedimaniaData->records); //TODO
//3 Minutes
$this->maniaControl->getTimerManager()->registerOneTimeListening($this, function () {
$this->updatePlayerList();
}, 1000 * 60 * 3);
break;
case self::DEDIMANIA_CHECK_SESSION:
//TODO Check and reopen if needed
break;
case self::DEDIMANIA_SET_CHALLENGE_TIMES:
//TODO Proper Checks
Logger::logInfo("Dedimania Times succesfully submitted");
break;
case self::DEDIMANIA_PLAYERCONNECT:
$dediPlayer = new DedimaniaPlayer($responseParameters);
$this->dedimaniaData->addPlayer($dediPlayer);
// Fetch records if he is the first who joined the server
if ($this->maniaControl->getPlayerManager()->getPlayerCount(false) === 1) {
$this->fetchDedimaniaRecords(true);
}
Logger::logInfo("Dedimania Player added " . $dediPlayer->login);
$this->maniaLinkNeedsUpdate = true; //TODO handle update for only one player instead of everyone as soon splitted
break;
case self::DEDIMANIA_PLAYERDISCONNECT:
Logger::logInfo("Debug: Dedimania Player removed");
break;
case self::DEDIMANIA_WARNINGSANDTTR2:
foreach ($responseParameters['methods'] as $method) {
if ($method['errors']) {
Logger::log('Dedimania Warning or Error: ' . $method['methodName'] . ': ' . json_encode($method['errors']));
}
}
}
}
//exit();
});
$asyncHttpRequest->setContent($content);
//$asyncHttpRequest->setCompression(true);
//FIXME setChallengeTime Compressed gives Dedimania Error 400
$asyncHttpRequest->setTimeout(500);
$asyncHttpRequest->postData();
$this->requests = array();
}
/**
* Encode the given xml rpc method and params
*
* @param string $method
* @param array $params
* @return string
*/
private function encodeRequest($method, $params) {
$paramArray = array(array('methodName' => $method, 'params' => $params), array('methodName' => self::DEDIMANIA_WARNINGSANDTTR2, 'params' => array()));
return xmlrpc_encode_request(self::XMLRPC_MULTICALL, array($paramArray), array('encoding' => 'UTF-8', 'escaping' => 'markup'));
}
/**
* Decodes xml rpc response
*
* @param string $response
* @return mixed
*/
private function decode($response) {
return xmlrpc_decode($response, 'utf-8');
}
/**
* Build Votes Info Array for Callbacks
*/
private function getVotesInfo() {
$map = $this->maniaControl->getMapManager()->getCurrentMap();
if (!$map) {
return null;
}
$gameMode = $this->getGameModeString();
if (!$gameMode) {
return null;
}
return array('UId' => $map->uid, 'GameMode' => $gameMode);
}
/**
* Build server info Structure for callbacks
*/
private function getServerInfo() {
$server = $this->maniaControl->getClient()->getServerOptions();
if (!$server) {
return null;
}
if ($this->maniaControl->getPlayerManager()->getPlayerCount(false) <= 0) {
return null;
}
$playerCount = $this->maniaControl->getPlayerManager()->getPlayerCount();
$spectatorCount = $this->maniaControl->getPlayerManager()->getSpectatorCount();
return array('SrvName' => $server->name, 'Comment' => $server->comment, 'Private' => (strlen($server->password) > 0), 'NumPlayers' => $playerCount, 'MaxPlayers' => $server->currentMaxPlayers,
'NumSpecs' => $spectatorCount, 'MaxSpecs' => $server->currentMaxSpectators);
}
/**
* Build simple player list for callbacks
*/
private function getPlayerList() {
$players = $this->maniaControl->getPlayerManager()->getPlayers();
if (empty($players)) {
return null;
}
$playerInfo = array();
foreach ($players as $player) {
array_push($playerInfo, array('Login' => $player->login, 'IsSpec' => $player->isSpectator));
}
return $playerInfo;
}
/**
* Build Map Info Array for Dedimania Requests
*
* @return array
*/
private function getMapInfo() {
$map = $this->maniaControl->getMapManager()->getCurrentMap();
if (!$map) {
return null;
}
$mapInfo = array();
$mapInfo['UId'] = $map->uid;
$mapInfo['Name'] = $map->rawName;
$mapInfo['Environment'] = $map->environment;
$mapInfo['Author'] = $map->authorLogin;
$mapInfo['NbCheckpoints'] = $map->nbCheckpoints;
$mapInfo['NbLaps'] = $map->nbLaps;
return $mapInfo;
}
/**
* Get Dedimania String Representation of the current Game Mode
*
* @return String
*/
private function getGameModeString() {
$gameMode = $this->maniaControl->getServer()->getGameMode();
if ($gameMode === null) {
Logger::logError("Couldn't retrieve game mode.");
return null;
}
switch ($gameMode) {
case 0: {
$scriptNameResponse = $this->maniaControl->getClient()->getScriptName();
$scriptName = str_replace('.Script.txt', '', $scriptNameResponse['CurrentValue']);
switch ($scriptName) {
case 'Rounds':
case 'Cup':
case 'Team':
return 'Rounds';
case 'TimeAttack':
case 'Laps':
case 'TeamAttack':
case 'TimeAttackPlus':
return 'TA';
}
break;
}
case 1:
case 3:
case 5: {
return 'Rounds';
}
case 2:
case 4: {
return 'TA';
}
}
return null;
}
/**
* Handle xml rpc fault
*
* @param array $fault
* @param string $method
*/
private function handleXmlRpcFault(array $fault, $method) {
trigger_error("XmlRpc Fault on '{$method}': '{$fault['faultString']} ({$fault['faultCode']})!");
}
/**
* @return \MCTeam\Dedimania\DedimaniaData
*/
public function getDedimaniaData() {
return $this->dedimaniaData;
}
/**
* @param \MCTeam\Dedimania\DedimaniaData $dedimaniaData
*/
public function setDedimaniaData($dedimaniaData) {
$this->dedimaniaData = $dedimaniaData;
}
/**
* @return bool
*/
public function doesManiaLinkNeedUpdate() {
return $this->maniaLinkNeedsUpdate;
}
/**
* Call if ManiaLink got Updated
*/
public function maniaLinkUpdated() {
$this->maniaLinkNeedsUpdate = false;
}
/**
* Call if You want a ManiaLink Update
*/
public function maniaLinkUpdateNeeded() {
$this->maniaLinkNeedsUpdate = true;
}
}