ProfileTest   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 235
Duplicated Lines 6.81 %

Coupling/Cohesion

Components 1
Dependencies 33

Importance

Changes 0
Metric Value
dl 16
loc 235
c 0
b 0
f 0
wmc 14
lcom 1
cbo 33
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A test_idp_stores() 0 11 1
A test_metadata_profile() 0 20 1
A test_send_authn_request_profile() 0 26 1
A test_receive_response_profile() 0 26 1
A test_attribute_value_provider_throws_exception() 0 7 1
A test_session_info_provider_throws_exception() 0 7 1
A test_name_id_provider_throws_exception() 0 7 1
A test_session() 0 5 1
A test_idp_entity_descriptor() 8 8 1
A test_sp_entity_descriptor() 8 8 1
B getBuildContainer() 0 87 3
A getSamlResponseCode() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace LightSaml\Tests\Functional\Bridge\Pimple;
4
5
use LightSaml\Bridge\Pimple\Container\BuildContainer;
6
use LightSaml\Bridge\Pimple\Container\PartyContainer;
7
use LightSaml\Bridge\Pimple\Container\StoreContainer;
8
use LightSaml\Bridge\Pimple\Container\SystemContainer;
9
use LightSaml\ClaimTypes;
10
use LightSaml\Helper;
11
use LightSaml\Model\Protocol\Response;
12
use LightSaml\Provider\TimeProvider\TimeProviderInterface;
13
use LightSaml\SamlConstants;
14
use LightSaml\State\Request\RequestState;
15
use LightSaml\Store\Request\RequestStateArrayStore;
16
use LightSaml\Tests\BaseTestCase;
17
use LightSaml\Tests\Fixtures\Meta\TimeProviderMock;
18
use Pimple\Container;
19
use Symfony\Component\DomCrawler\Crawler;
20
use Symfony\Component\HttpFoundation\Request;
21
22
class ProfileTest extends BaseTestCase
23
{
24
    const OWN_ENTITY_ID = 'https://localhost/lightSAML/lightSAML';
25
26
    public function test_idp_stores()
27
    {
28
        $buildContainer = $this->getBuildContainer();
29
        $allIdpEntityDescriptors = $buildContainer->getPartyContainer()->getIdpEntityDescriptorStore()->all();
30
31
        $this->assertCount(4, $allIdpEntityDescriptors);
0 ignored issues
show
Documentation introduced by
$allIdpEntityDescriptors is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
32
        $this->assertEquals('https://idp.testshib.org/idp/shibboleth', $allIdpEntityDescriptors[0]->getEntityID());
33
        $this->assertEquals('https://sp.testshib.org/shibboleth-sp', $allIdpEntityDescriptors[1]->getEntityID());
34
        $this->assertEquals('https://localhost/lightSAML/lightSAML-IDP', $allIdpEntityDescriptors[2]->getEntityID());
35
        $this->assertEquals('https://openidp.feide.no', $allIdpEntityDescriptors[3]->getEntityID());
36
    }
37
38
    public function test_metadata_profile()
39
    {
40
        $buildContainer = $this->getBuildContainer();
41
42
        $builder = new \LightSaml\Builder\Profile\Metadata\MetadataProfileBuilder($buildContainer);
43
44
        $context = $builder->buildContext();
45
        $action = $builder->buildAction();
46
47
        $action->execute($context);
48
49
        $this->assertNotNull($context->getHttpResponseContext()->getResponse());
50
        $xml = $context->getHttpResponseContext()->getResponse()->getContent();
51
52
        $root = new \SimpleXMLElement($xml);
53
54
        $this->assertEquals('EntityDescriptor', $root->getName());
55
        $this->assertEquals('SPSSODescriptor', $root->SPSSODescriptor->getName());
56
        $this->assertEquals('https://localhost/lightsaml/lightSAML/web/sp/acs.php', $root->SPSSODescriptor->AssertionConsumerService['Location']);
57
    }
58
59
    public function test_send_authn_request_profile()
60
    {
61
        $buildContainer = $this->getBuildContainer();
62
63
        $idpEntityId = 'https://localhost/lightSAML/lightSAML-IDP';
64
65
        $builder = new \LightSaml\Builder\Profile\WebBrowserSso\Sp\SsoSpSendAuthnRequestProfileBuilder($buildContainer, $idpEntityId);
66
        $context = $builder->buildContext();
67
        $action = $builder->buildAction();
68
69
        $action->execute($context);
70
71
        $html = $context->getHttpResponseContext()->getResponse()->getContent();
72
73
        $crawler = new Crawler($html);
74
75
        $code = $crawler->filter('body form input[name="SAMLRequest"]')->first()->attr('value');
76
        $xml = base64_decode($code);
77
78
        $root = new \SimpleXMLElement($xml);
79
        $root->registerXPathNamespace('saml', SamlConstants::NS_ASSERTION);
80
        $this->assertEquals('AuthnRequest', $root->getName());
81
        $this->assertEquals(self::OWN_ENTITY_ID, (string) $root->children('saml', true)->Issuer);
82
        $this->assertEquals('https://localhost/lightsaml/lightSAML-IDP/web/idp/login.php', $root['Destination']);
83
        $this->assertEquals('Signature', $root->children('ds', true)->Signature->getName());
84
    }
85
86
    public function test_receive_response_profile()
87
    {
88
        $buildContainer = $this->getBuildContainer(
89
            '_1db06e4f91d3997b7ed3285a59f77028071db2dc5f',
90
            new TimeProviderMock(
91
                new \DateTime('@'.Helper::parseSAMLTime('2015-11-22T15:37:14Z'), new \DateTimeZone('UTC'))
92
            )
93
        );
94
95
        $builder = new \LightSaml\Builder\Profile\WebBrowserSso\Sp\SsoSpReceiveResponseProfileBuilder($buildContainer);
96
97
        $context = $builder->buildContext();
98
        $action = $builder->buildAction();
99
100
        $request = Request::create('https://localhost/lightsaml/lightSAML/web/sp/acs.php', 'POST', ['SAMLResponse' => $this->getSamlResponseCode()]);
101
        $context->getHttpRequestContext()->setRequest($request);
102
103
        $action->execute($context);
104
105
        /** @var Response $response */
106
        $response = $context->getInboundMessage();
107
        $this->assertInstanceOf(Response::class, $response);
108
        $this->assertCount(1, $response->getAllAssertions());
0 ignored issues
show
Documentation introduced by
$response->getAllAssertions() is of type array<integer,object<Lig...l\Assertion\Assertion>>, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
109
        $this->assertEquals('[email protected]', $response->getFirstAssertion()->getFirstAttributeStatement()
110
            ->getFirstAttributeByName(ClaimTypes::EMAIL_ADDRESS)->getFirstAttributeValue());
111
    }
112
113
    public function test_attribute_value_provider_throws_exception()
114
    {
115
        $this->expectExceptionMessage("Attribute value provider not set");
116
        $this->expectException(\LightSaml\Error\LightSamlBuildException::class);
117
        $buildContainer = $this->getBuildContainer();
118
        $buildContainer->getProviderContainer()->getAttributeValueProvider();
119
    }
120
121
    public function test_session_info_provider_throws_exception()
122
    {
123
        $this->expectExceptionMessage("Session info provider not set");
124
        $this->expectException(\LightSaml\Error\LightSamlBuildException::class);
125
        $buildContainer = $this->getBuildContainer();
126
        $buildContainer->getProviderContainer()->getSessionInfoProvider();
127
    }
128
129
    public function test_name_id_provider_throws_exception()
130
    {
131
        $this->expectExceptionMessage("Name ID provider not set");
132
        $this->expectException(\LightSaml\Error\LightSamlBuildException::class);
133
        $buildContainer = $this->getBuildContainer();
134
        $buildContainer->getProviderContainer()->getNameIdProvider();
135
    }
136
137
    public function test_session()
138
    {
139
        $buildContainer = $this->getBuildContainer();
140
        $this->assertInstanceOf(\Symfony\Component\HttpFoundation\Session\Session::class, $buildContainer->getSystemContainer()->getSession());
141
    }
142
143 View Code Duplication
    public function test_idp_entity_descriptor()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
    {
145
        $pimple = new Container();
146
        $pimple->register(new \LightSaml\Bridge\Pimple\Container\Factory\PartyContainerProvider());
147
        $buildContainer = new BuildContainer($pimple);
148
149
        $this->assertInstanceOf(\LightSaml\Store\EntityDescriptor\EntityDescriptorStoreInterface::class, $buildContainer->getPartyContainer()->getIdpEntityDescriptorStore());
150
    }
151
152 View Code Duplication
    public function test_sp_entity_descriptor()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
    {
154
        $pimple = new Container();
155
        $pimple->register(new \LightSaml\Bridge\Pimple\Container\Factory\PartyContainerProvider());
156
        $buildContainer = new BuildContainer($pimple);
157
158
        $this->assertInstanceOf(\LightSaml\Store\EntityDescriptor\EntityDescriptorStoreInterface::class, $buildContainer->getPartyContainer()->getSpEntityDescriptorStore());
159
    }
160
161
    private function getBuildContainer($inResponseTo = null, TimeProviderInterface $timeProvider = null)
162
    {
163
        $buildContainer = new BuildContainer($pimple = new Container());
164
165
        // OWN
166
        $ownCredential = new \LightSaml\Credential\X509Credential(
167
            \LightSaml\Credential\X509Certificate::fromFile(__DIR__.'/../../../../../../web/sp/saml.crt'),
168
            \LightSaml\Credential\KeyHelper::createPrivateKey(__DIR__.'/../../../../../../web/sp/saml.key', null, true)
169
        );
170
        $ownCredential->setEntityId(self::OWN_ENTITY_ID);
171
172
        $ownEntityDescriptor = new \LightSaml\Builder\EntityDescriptor\SimpleEntityDescriptorBuilder(
173
            self::OWN_ENTITY_ID,
174
            'https://localhost/lightsaml/lightSAML/web/sp/acs.php',
175
            null,
176
            $ownCredential->getCertificate()
177
        );
178
179
        $buildContainer->getPimple()->register(new \LightSaml\Bridge\Pimple\Container\Factory\OwnContainerProvider(
180
            $ownEntityDescriptor,
181
            [$ownCredential]
182
        ));
183
184
        // SYSTEM
185
        $buildContainer->getPimple()->register(new \LightSaml\Bridge\Pimple\Container\Factory\SystemContainerProvider(true));
186
        if ($timeProvider) {
187
            $pimple[SystemContainer::TIME_PROVIDER] = function () use ($timeProvider) {
188
                return $timeProvider;
189
            };
190
        }
191
192
        // PARTY
193
        $buildContainer->getPimple()->register(new \LightSaml\Bridge\Pimple\Container\Factory\PartyContainerProvider());
194
        $pimple[PartyContainer::IDP_ENTITY_DESCRIPTOR] = function () {
195
            $idpProvider = new \LightSaml\Store\EntityDescriptor\FixedEntityDescriptorStore();
196
            $idpProvider->add(
197
                \LightSaml\Model\Metadata\EntitiesDescriptor::load(__DIR__.'/../../../../../../web/sp/testshib-providers.xml')
198
            );
199
            $idpProvider->add(
200
                \LightSaml\Model\Metadata\EntityDescriptor::load(__DIR__.'/../../../../../../web/sp/localhost-lightsaml-lightsaml-idp.xml')
201
            );
202
            $idpProvider->add(
203
                \LightSaml\Model\Metadata\EntityDescriptor::load(__DIR__.'/../../../../../../web/sp/openidp.feide.no.xml')
204
            );
205
206
            return $idpProvider;
207
        };
208
209
        // STORE
210
        $buildContainer->getPimple()->register(
211
            new \LightSaml\Bridge\Pimple\Container\Factory\StoreContainerProvider(
212
                $buildContainer->getSystemContainer()
213
            )
214
        );
215
        if ($inResponseTo) {
216
            $pimple[StoreContainer::REQUEST_STATE_STORE] = function () use ($inResponseTo) {
217
                $store = new RequestStateArrayStore();
218
                $store->set(new RequestState($inResponseTo));
219
220
                return $store;
221
            };
222
        }
223
224
        // PROVIDER
225
        $buildContainer->getPimple()->register(
226
            new \LightSaml\Bridge\Pimple\Container\Factory\ProviderContainerProvider()
227
        );
228
229
        // CREDENTIAL
230
        $buildContainer->getPimple()->register(
231
            new \LightSaml\Bridge\Pimple\Container\Factory\CredentialContainerProvider(
232
                $buildContainer->getPartyContainer(),
233
                $buildContainer->getOwnContainer()
234
            )
235
        );
236
237
        // SERVICE
238
        $buildContainer->getPimple()->register(
239
            new \LightSaml\Bridge\Pimple\Container\Factory\ServiceContainerProvider(
240
                $buildContainer->getCredentialContainer(),
241
                $buildContainer->getStoreContainer(),
242
                $buildContainer->getSystemContainer()
243
            )
244
        );
245
246
        return $buildContainer;
247
    }
248
249
    /**
250
     * @return string
251
     */
252
    private function getSamlResponseCode()
253
    {
254
        return 'PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzYW1scDpSZXNwb25zZSB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJRD0iX2I4YzNlZjQ0ZmZjZDNjMjc1OWYyYWU0ZTdjZGVjN2YwZGVhNGU0MGRkOCIgSW5SZXNwb25zZVRvPSJfMWRiMDZlNGY5MWQzOTk3YjdlZDMyODVhNTlmNzcwMjgwNzFkYjJkYzVmIiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAxNS0xMS0yMlQxNTozODoxNFoiIERlc3RpbmF0aW9uPSJodHRwczovL2xvY2FsaG9zdC9saWdodHNhbWwvbGlnaHRTQU1ML3dlYi9zcC9hY3MucGhwIj48c2FtbDpJc3N1ZXIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDplbnRpdHkiPmh0dHBzOi8vbG9jYWxob3N0L2xpZ2h0U0FNTC9saWdodFNBTUwtSURQPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSIvPgogIDxkczpSZWZlcmVuY2UgVVJJPSIjX2I4YzNlZjQ0ZmZjZDNjMjc1OWYyYWU0ZTdjZGVjN2YwZGVhNGU0MGRkOCI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvZHM6VHJhbnNmb3Jtcz48ZHM6RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3NoYTEiLz48ZHM6RGlnZXN0VmFsdWU+djZyaEovaUMyY3p4VXdoVHAxeStFOUZiYjlrPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5oTU43VzkrU08wOU1XOVEvWkx1aHlFNTJpZ3NxclRmallxZmJPRGJBbUtVQXFzT2llU2t6NU84cXhjdGR0K2FQTlNmTmdmeW96MCtuT2xvOXNtellISlRnZm1tV1ZGQUtkQjh3TU5XeU9NN3RZbWVqdU1DYm9pWmJORjJjUWNBc1lTazJ4R1JEVW53OWlRNGNIdTQ1S1ZWR01FdnlLblArQXBGWXgvSmdDUDU4MVQ0dU44c21reFp6bG1Wa1N1NSthdG11eEFXQlVWcytqMkk5US9tU09VUllyZWh5MUxqbWQ5bTBqVG00bGpMS3RZNW9FS3Z5TmpVeEthNlJFcThYbVhuSUtiTjJkazN2eThMcWE1SS9DTWNrQU52YmVDemdxNXdacGFiTlY2bStuSVptZnNvME9jdFdsa3dGOFFUSE9yQXRSMUpzamhmT2hBRzRVN2JvWXc9PTwvZHM6U2lnbmF0dXJlVmFsdWU+CjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUR5akNDQXJLZ0F3SUJBZ0lKQUpOT0Z1UWQ3MjdjTUEwR0NTcUdTSWIzRFFFQkJRVUFNRXd4Q3pBSkJnTlZCQVlUQWxKVE1SRXdEd1lEVlFRSUV3aENaV3huY21Ga1pURVNNQkFHQTFVRUNoTUpUR2xuYUhSVFFVMU1NUll3RkFZRFZRUURFdzFzYVdkb2RITmhiV3d1WTI5dE1CNFhEVEUxTURreE16RTVNREUwTUZvWERUSTFNRGt4TURFNU1ERTBNRm93VERFTE1Ba0dBMVVFQmhNQ1VsTXhFVEFQQmdOVkJBZ1RDRUpsYkdkeVlXUmxNUkl3RUFZRFZRUUtFd2xNYVdkb2RGTkJUVXd4RmpBVUJnTlZCQU1URFd4cFoyaDBjMkZ0YkM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDN3BVS09QTXlFMm9TY0hMUEdKRlRlcEs5ajFIMDNlL3MvV25PTnc4WndZQmFCSVlJUXVYNnVFOGpGUGREMHVRU2FZcE93NWg1VGdxNnhCVjdtMmtQTzUzaHM4Z0VHV1JiQ2RDdHhpOUVNSndJT1lyK2lzRzBOK0R2VjlLeWJKZjZ0cWNNNTBQaUZqVk50Zng4SXViTXBBS0NicXVhcWRMYUhIMHJnUDFoYmduR201WVpreUVLNHM4eHVMVURTNnFMN043YS9lejJaazQ1dTNMM3FGY3VuY1BJNUJUbkpnNmZxbHlwRGhDRE9CSTVMancxMEhtZ1pIUElYek9oRVBWVityWDJpSGhGNFY5dnpFb2VJVUFCWVhRVk5SUk5IcFBkVnNLNmlUVGt5dmJyR0ovdHYzb0ZaaE5PU0wwS3V5K1E5bmxFOWZFRnF5VXlkSjY3dnNYcVpBZ01CQUFHamdhNHdnYXN3SFFZRFZSME9CQllFRkhQVDZFeTFxZ3hNek1JdDJkM09XdXd6ZlBTVU1Id0dBMVVkSXdSMU1IT0FGSFBUNkV5MXFneE16TUl0MmQzT1d1d3pmUFNVb1ZDa1RqQk1NUXN3Q1FZRFZRUUdFd0pTVXpFUk1BOEdBMVVFQ0JNSVFtVnNaM0poWkdVeEVqQVFCZ05WQkFvVENVeHBaMmgwVTBGTlRERVdNQlFHQTFVRUF4TU5iR2xuYUhSellXMXNMbU52YllJSkFKTk9GdVFkNzI3Y01Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUhrSHR3SkJvZU9odnIwNk0wTWlrS2M5OXplNlRxQUd2ZitRa2dGb1Yxc1dHQWgzTktjQVIrWFNsZksrc1FXckhHa2lpYTVoV0tnQVBNTVVia0xQOURGV2tqYksyNDFpc0NaWkQvTHZBMWFuYlYrN1BpZG4rc3daNWRSN3luWDJ2ajBrRlliK1ZzR1BrYXZOY2o4Uk4vRGR1aE4vVG1pNXNRQWxXaGF3MDZVQWVFcVh0RmVMYlRnTGZmQmFqN1BtUjBJWWp2VFpBMFgyRmRSdTBHWFJ4bjd6Z2hqcHZTcTludVdhM3BHYmZkVnRMNkdJa3dZVVBjRHpqcjRPZUdYTm1JWmUvd01Dbno2VkdaWStMVWd6aS80REFDNlYzT2pNdWhkcVMvMitvMStDWEN3TjA4Q0lIUVY2K0FVQmVuRVZhd01zaWFkTEJneDNrRmU1aVhyWVJNQT08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSIvPgogIDxkczpSZWZlcmVuY2UgVVJJPSIjX2I4YzNlZjQ0ZmZjZDNjMjc1OWYyYWU0ZTdjZGVjN2YwZGVhNGU0MGRkOCI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvZHM6VHJhbnNmb3Jtcz48ZHM6RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3NoYTEiLz48ZHM6RGlnZXN0VmFsdWU+QVREc2tQVGZuRmtFSTNXenJNQ3JDelNCNktvPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5nZTNYeG1ZMWw3M2FuUWs1L2Fzd0JCVENkVkpGa0U1TlBOOVlCbmVvK2lkREhKb2IvMitPcnZyS1B5QlQwZHBSSnBTellVYUYyRllOaU1RMG5jNkpQdDVyMk52c2Q4aVB0VzZXRjRhYWVYZDRmTlFQZXRNL3AzS2l0ejl3b0NzakdJNUNQNy85eUkrVTlUbEo0QWlLdTNMTEdHbjQxbnZxVG9sUVRRa0RDajJvQjZmTVp6TFBOYlFEVFV2SFI0REdMdGt4aU0wSk1IRUdyYVE4NGhzeENuaTBYQ1BNd0w1dnVmOFMrMng2ODc0VDBpbFllZnU4ZnFRanFOK0t1NklyZFBycE9QRG1SUDhGemlyRWFkMXJNZFpSK2dpM3VmVmpxZFZhTWhMLzFPSkhqZnRUQzRORzI2MElib1V6QVowa1BHM2V1T0tIWjUydHdhT1BVdEFqU1E9PTwvZHM6U2lnbmF0dXJlVmFsdWU+CjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUR5akNDQXJLZ0F3SUJBZ0lKQUpOT0Z1UWQ3MjdjTUEwR0NTcUdTSWIzRFFFQkJRVUFNRXd4Q3pBSkJnTlZCQVlUQWxKVE1SRXdEd1lEVlFRSUV3aENaV3huY21Ga1pURVNNQkFHQTFVRUNoTUpUR2xuYUhSVFFVMU1NUll3RkFZRFZRUURFdzFzYVdkb2RITmhiV3d1WTI5dE1CNFhEVEUxTURreE16RTVNREUwTUZvWERUSTFNRGt4TURFNU1ERTBNRm93VERFTE1Ba0dBMVVFQmhNQ1VsTXhFVEFQQmdOVkJBZ1RDRUpsYkdkeVlXUmxNUkl3RUFZRFZRUUtFd2xNYVdkb2RGTkJUVXd4RmpBVUJnTlZCQU1URFd4cFoyaDBjMkZ0YkM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDN3BVS09QTXlFMm9TY0hMUEdKRlRlcEs5ajFIMDNlL3MvV25PTnc4WndZQmFCSVlJUXVYNnVFOGpGUGREMHVRU2FZcE93NWg1VGdxNnhCVjdtMmtQTzUzaHM4Z0VHV1JiQ2RDdHhpOUVNSndJT1lyK2lzRzBOK0R2VjlLeWJKZjZ0cWNNNTBQaUZqVk50Zng4SXViTXBBS0NicXVhcWRMYUhIMHJnUDFoYmduR201WVpreUVLNHM4eHVMVURTNnFMN043YS9lejJaazQ1dTNMM3FGY3VuY1BJNUJUbkpnNmZxbHlwRGhDRE9CSTVMancxMEhtZ1pIUElYek9oRVBWVityWDJpSGhGNFY5dnpFb2VJVUFCWVhRVk5SUk5IcFBkVnNLNmlUVGt5dmJyR0ovdHYzb0ZaaE5PU0wwS3V5K1E5bmxFOWZFRnF5VXlkSjY3dnNYcVpBZ01CQUFHamdhNHdnYXN3SFFZRFZSME9CQllFRkhQVDZFeTFxZ3hNek1JdDJkM09XdXd6ZlBTVU1Id0dBMVVkSXdSMU1IT0FGSFBUNkV5MXFneE16TUl0MmQzT1d1d3pmUFNVb1ZDa1RqQk1NUXN3Q1FZRFZRUUdFd0pTVXpFUk1BOEdBMVVFQ0JNSVFtVnNaM0poWkdVeEVqQVFCZ05WQkFvVENVeHBaMmgwVTBGTlRERVdNQlFHQTFVRUF4TU5iR2xuYUhSellXMXNMbU52YllJSkFKTk9GdVFkNzI3Y01Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUhrSHR3SkJvZU9odnIwNk0wTWlrS2M5OXplNlRxQUd2ZitRa2dGb1Yxc1dHQWgzTktjQVIrWFNsZksrc1FXckhHa2lpYTVoV0tnQVBNTVVia0xQOURGV2tqYksyNDFpc0NaWkQvTHZBMWFuYlYrN1BpZG4rc3daNWRSN3luWDJ2ajBrRlliK1ZzR1BrYXZOY2o4Uk4vRGR1aE4vVG1pNXNRQWxXaGF3MDZVQWVFcVh0RmVMYlRnTGZmQmFqN1BtUjBJWWp2VFpBMFgyRmRSdTBHWFJ4bjd6Z2hqcHZTcTludVdhM3BHYmZkVnRMNkdJa3dZVVBjRHpqcjRPZUdYTm1JWmUvd01Dbno2VkdaWStMVWd6aS80REFDNlYzT2pNdWhkcVMvMitvMStDWEN3TjA4Q0lIUVY2K0FVQmVuRVZhd01zaWFkTEJneDNrRmU1aVhyWVJNQT08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48c2FtbHA6U3RhdHVzPjxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz48L3NhbWxwOlN0YXR1cz48c2FtbDpFbmNyeXB0ZWRBc3NlcnRpb24geG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+PHhlbmM6RW5jcnlwdGVkRGF0YSB4bWxuczp4ZW5jPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyMiIHhtbG5zOmRzaWc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiIFR5cGU9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI0VsZW1lbnQiPjx4ZW5jOkVuY3J5cHRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNhZXMxMjgtY2JjIi8+PGRzaWc6S2V5SW5mbyB4bWxuczpkc2lnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48eGVuYzpFbmNyeXB0ZWRLZXk+PHhlbmM6RW5jcnlwdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSIvPjx4ZW5jOkNpcGhlckRhdGE+PHhlbmM6Q2lwaGVyVmFsdWU+TFRHVUdjMzkzSHVaeDM0eVBjRjJjRGZnS0o3bDNOdnYxKzh2QWIvSTUxdXZmSWlyeHVqeGNBcUZ3YVl5WXlMekVzbnlCVUJhdUZiYzZhR2hUQlhuaWlieWpiR0NzWGtTdHc2NUJlb0o5alpPZDNyRVJvZ0dEaHBDVktHZTF3UVZLMVIvRTdZTzZDVWt2WHdqWmhxalBwSEIwcGVlUHJDUVZtOUprV0xBOFNBR0pSRzJwVUNJRUNVWE1LUGxqZ1FFKzNQRkQ0dGlBN0tvZ3hTQTVrcldjbmVjOTA1ZWl5eUJlN202UXh3OEZYSXVZSU50U2VQOUU2dXdCd2xFdUdUOVRjSXJhV0dCYXNmRnlRNXkya0huanJYdHljT2RnaXZOUFoyQ1Y1bUNLRGFxUjloT094dXpPUnVpM3d2cDBoV1E1aHAwQ1Y2Z3hVM3ZRdXM0aXdJQytBPT08L3hlbmM6Q2lwaGVyVmFsdWU+PC94ZW5jOkNpcGhlckRhdGE+PC94ZW5jOkVuY3J5cHRlZEtleT48L2RzaWc6S2V5SW5mbz4KICAgPHhlbmM6Q2lwaGVyRGF0YT4KICAgICAgPHhlbmM6Q2lwaGVyVmFsdWU+Nk5ZaXU1aGN6NTBlblBYdUllRCt0MUlMcTFtQm1QZ0Y1ZTJuWW9hR0wrZ0EvcHgwZkNzOWRJci8wejJkY3pZZ1YrUThFK2FydFptUGJtai8zalFjZkswNHlaZFYvL0YrdEdOaFFYM3VKbmFxSVQ5WGE5dENic29MaWQydE1ucTJkZ3psb1N1VWR4K05MY0p5VnJWYUs4ek15N21PVVdtRndQV2U1b0Y1ZEl2N1ZXeEY4aitrVHAzRHNnVmZlS2ZWaG1wUEFFMGJPanhXWUoxVEhZUEttQjRIS3duOW9COERXM1FnQjV1R2hBUzFlMXFFM0pXdFY0c3Y2b1N2Nk9ocE9oaXREN1BTRzNlTStBSVlYa2tEaXBXU01PZGhJT0lSYlg0aHNZKzczemIzclJXZjFYUlFWVlRnZmVReW9lMG5GdzlQZXpsOGpmUnpSSTlTa0toQVVvKzhwbUtKVUIxZTNNOUZlK1g5K3U5Yjc3QmdUTkFIWlhhS1pKNnRmTmxsVG5sbFBvU2ZDalRDZ3BNOXNEUXE3ZlZNd1ltSHdYWklGTmIxazErWU81bFpOZkRvckpkd0FtRHBrVVRwNm9LKzFJOEw3SzZqdVVPRHB6UlRwUkx3RjY0VjlVUW95TnBVRkZnL0FQeTR1MkFGTTNEcEpoaFR3M0RpTWh5c3BkOXFiN1d4dlZnM3F0a1h3cFA2bWlYd3Q1ei83NVBtUitHWnVVcS9TcEhmNXJDTE5SN2RicHU3UHhyTzliV0s5Q1VTZEswWXA4QTI5dnYzaTJBWk9WM2JoMFJMVlhiV0RPL2gvaWx5MnFpWlNJdlA5cjNZamEwTjdmeUZKbExOWVo4RWkvSkpyUldONkc3Q1hUOVMvRjIvN1RDU24vVXZwK0tYcjF1WXhtQmtXU0JkWmFuaFdPdzdLTC9jUnpLZk83YlMrMkN0UjRHYWVNbkJWK3NqRnliUStzUE9iTExoS3AwUEdTMW9CeG91bnpmQ3V6YTlDQnVRelVqQ1VGT25aampraVZaZVloeFJCa05PZ0lWSTkxQ2l2cmxkc2NQZEQ4UWVlSU8xcldyRHVIZzhwRXBoN00zQXh6RmFBSHRlb2ZlQnl6UVkxNjloQTZCTlhma1hGakdyZXZZNDdIc05YSERMRUEvcWxXTFczc3RZcWtvU3NuWFRjYXI2bmlvRkI1T3pHY1N3bXBWcTBBY0k0VTgzQzJ5RG9VSWxocmRRU2x5NWpKSzliZkYxZmxmMFNwaVk0RDdQYXR6QmFaQVB2eGZESElmWVBBSWNUMXNFNWsyNERrU25DSXZjK3RxRkd2SmFTb080UTdXZkh4ZEMrUlJYaWlQaVpMcHdXdlpxdFNhZEFIYXljd08ybDlJRnd2dTB4WFlNdmZXL1REVWQvTlFsMjJpOFdmTkhBOFVrQUgvR2lvZTA4ZXJCZlN4THdqNlFGTmxhZ2NCL25CV0JMN2RFM1JpbXVqOHdtU0JwN3FGNXdJQnYwNEZGblc1WTVSTmxEV2hUa280ZVpZNkV5NHVXYjNsWnN5di9MWWUwT1JPa0tkNE1LckoxaDJaMU9CaTloUldDMFhzdmpFRmFKUVRmYlQyOHJnUStFVWJxOE04U21XR2RXRnIrbVVIQTVGVjl0NlYzNVpGVGdpdFV3TjFpSnBMeUhpS29wZWpjSEU3Q3cvaEI4OGJTN1h2V0xSSEV2NFdVOE9uQ3FWQ20wdzFVTFptQWNpdWJrNjhuOU55VVNpTWdzbnhjT0owOG1rNEpqMFZJUmlpMUc5NzVub0x5UjZRT3Y4dWlEMlFCYjNZRnZKTzJYSk1JSExBZG05b1JQVEVuYlVxb0RXQXcxcGEvTjEza3JsdENRMFcxT21YcmFjcStSNnMzaG9GU3ZEaU0wZ1FpQ284U2RGZE9RUkJNRVlXMk8rdlhwYWt1dmhEMUVNcnBjWjdHUFlBZ3pjdHhER0M3WEhFVmRxNzBsYW84a2lZMHRoWWJEbVhuaEtpNlFqRDNIZlU0NHhkaXZ6S256VHJJMWZRTUJFQmVBV2dDVCtWbFg1NlRyTEg0WFFTSmEvMnBYbXpaVHI3ZFpwQ2dTQ3pwL1pBNXlLYXovTHVwR2I4TFFWTDJMbnJYb3kzU0RSb012d1owMFM2eFJ6ZnY3QVR1TmMvZW1aem8zYXJ1bXlwNGxYU0hiTGFxdGgvdGsvRWpMZ1NUUStpY1ExeGpPU01mWWZpc21maEhaZXhVN1JhbFhjanlRb1dON1liNlFrV1U3WXpna1BrSWJnMFc1SXpGOURaSkZEVE9LNVAwMkJtbVJnTll0SHVucWRRckV5Mi95djNwVlE4VVBqYjB4SWxlcE5DWVpLSlB1NmJqa0N0OXhZU0pLUnpzV1hqZm5TMGJ1ZDlkOHRTdWZOeCtqZzRTVXErYkJTc2pxWUwwQm93MWZDTjVSM3ZnMHdqU3RteVNTYUdNdW1GVzM1UkVxd2xoQzBoZS9BTVVWZTVOMEFkYmlnclE4QzJTaG9xdW5vOUdkVlo0aDdoUWJKbHo3b3JBaEJVV0VhUmRKQ1FOYmZwN2gzOThJaGhCVkFvVEhlZkFGdmVBRS9YSlhvWkxuejUyUmFHZDk3QTRBaVdNQnlYNDFYUkQ1L1M0cTVZVmVUNjRYUUZrNEk5dWNCZ09HaCsybXkrdWhLL1VEMjBvcm9JaThHVzFNenF0aENNbjBTRURVMVJFMFN5Q3NnK3NKMWZVMWFsLzZEZGFEamZGZ3Z6SWZoNmZqT2FSb2NSaEFrS2dxSnF4YnFnTm5tNlhEWDNLbXorWU5TSWtoVVd2T20xYTV1cnRLelh0dkIzOW5DN1A5VDZVTkpobEZ4ZUxBZlZSa1NlTHdjRnk3Z04yUW4rbXNieGhPSXVGdmNLbHNEY210dTNFY3c1RS9UMWVjMU54MFlzT051Sm0vUUNXWGJNc2tTK0h6QkI2bURuemdIWkRwTkFFMGdaTllnZWVDNTNWSjVyNzNydzkybTVqMEZkVEZCd0p5TzFpRWhmZTNvWWhrR1Q1UzBDRXI5aG1mSWxMMDlXS2E1T2w2Qkx5VE9JUitibnJ3alZXMzZsdFk0QjdDK0QxVGdpbFY4MmJacXR1OFhtcDNva2ZlV3lMR0dTcktpQytBekE0NEhBVVN1TVBKbjZmbHgwTTFOODBaZDFqN3R2aXMxaGNLUGQwbXhuSXJqU1dqd2hoMGpjaVdkZk9zdFBPMTA2UGt0dkdjU0ZLajhzaTJLOVVFcHpCU3VTRTEvODNQNkF5RjJ0T0N1YTBBNlVheWZaR2szTVgzdlRHVmoxNXdoZEc2RlpGY21KTnZVc2l5ZjNaZmhnV0VjQ0FLQ2U5OEYyb2tGYjZrSlRUVk1wSUxPdkUxK3dWKzdZTWRSdi9iL3lzTXZMYVQ1MkdMMmd2citUdy9xL2ZNeGpSRUpadGJzUjJrY1dkMWNVUW1lUE5rNFBlVVRRem9DNGxHaVVFTWEwb1RnZE5hVVZmNkwyUGxUbWNLVW5tOFVERno2K3ZGZ3V5N1M2S0lBSlBBTnA5ekRBOXlHWFBac3lyZ1hQdTdaaWttSmxaMnk3OFFRQkdFdFc2c2pITHNZZHNoRU9wRDc5ZHJWajhvMGhzVGFkdzJHZzE3akMyRFRrZCtRZHQxMkZMZW1VVStWRWxBUUhqWGtmRzc0d2xnbVBqOW0xZWIyS0U1bHAzbDVqd3NrdGNzSjJjMm5zZ3lVaFZ0ZjFCd2svV2RXb3lrWFg2Ty84a29COHpJU0dPdzJMZ1l0cm9UUTJvcHI4YXFmTFZUdXZBbjRwR3JNRmlRUUlmNW50YUcxOFc5bTVIclpFVFBKZXkzWW1GUStJcUJhRjkxOVhlanZLZDYyc2EvZHphakFaQ0pTRmxpaCtOYXZ3WHJFaUJxZU03Z05zVU9mMWZTYUwwUFdDRHVrSUt3RXVDaWdXQWo5NytXUWVNc3hFYkJGRk1oTVNRZjB4ekRHcnE4dDA3Y3FhVlJVQ3lnUXpybml0SHhIYmM2RTBTeE1Dais3MjlCZVJ4aVJLSkxKajBXYlo5dGZUdkJ1Q2ZxbVRoaG9xOFRWelJVMko4OUFuZVNuenJpa044c1psaytHQnJ4ajF2cGViRUJ3Y3diMUNIM0pzZmFNblp4eGFROXppMlYvSDdRVC9NODZ6aUdpamxUS0VMWHZ6MytJY0VDVjE5YlYyMjhsRmRabXppTnBxSytneFZzUjE4VC9GaHZRUFRqQWpteVpDaHhjK0JhcEhoSmd3VTh2ZTl5QURIS0FXeUlsVFVqWDUvcWhqaGhia1ozS1hRa0NrMXBudTFCZ1RyWWZOZFpUYW1nclEyMU5jRVF3L2xBZ1M2ZndTTVdJZ3B1djd4Q3RscTFlVS9RSElST3JQcEI2aGpieUMwbnJWci9neW15b0ZzQVlkeHZTWmhXWGxJbWU3SXBXdWNUaGwzOTNNek5LRXdKTjQzWHNxUGM1QVFkN1NUSCtWVm15VUFYd3Rab3VQa2JqMlVYbGNiVThwU3ZhWFBaVUhIaUIwUTEzNU1RMjA3Rnh6UjhSNlZJY1lSMFQvd25sNGFMTlR5SS9ERVl0ZFhwcHJhcytJWmdFMmM2TE1VTjZOd0tLcWVBUWh6L0hvL1hTL2dZd3VDREcrWWpmYThVRCtJeTd6ai9EUDZJWkphK3RrbFVMZTYxTnlWQzFFOERzNUNBVXROZFp3ZnpncUhyT1lqUk9KVFhOTjNSS2U0YmtYQXdLNDcybzJENy95TFBycFVuVUpiYkJ2dThDMDd1KzI4cmhSSHdaUWUyYytOKzBEc3BoSkJwSnZvNmZFSTRaUnk3QVphZWtGZWdlVThCWmZEL1Vzb29PcERvS29KdjBNZDl4TEJjUE1ITTQ1UWhHMHhob0VZb1JFR2dNMFVwWWlpYkp5OHpwU3ZZM0xKbzFiQjN0bTRORnNDTEZzYXFwQnlnKzYyandTNXVBL29RNktJUzVPWFZwQ3c4Q3FTL01nN2xlQ3ZHTWlaQnhLUjFnZTFseURxUGQ2dE1Sd2dwTmpSZ0gzZEEwSTQrY3RDWk9xY2N4NE1XeVhGcy9aYU12ZkVMK1FJUWJkYTRQNEphVEtla1gyN1dSVGFXdnl1V2lxVFYxeUFxaVEvMGduVjIzVDhNY1VGQ003UWxRZUh5cWtIY29EUFA4VUVEYUNmTEdKdXJSRlVvL2YzNlEwVWI4Q1Fyc2xCd2k5cTRTSjFZR3JvcDBpWGlPTFBQM0RSNHF4VklKZTYxTElIS3pjb016c0duQ29nMXlvSW1UM2ZEZEhrZkdxaHh0Y0xaZGRuczRRcmJnSm5oOXUxUlIzU2hUUG4zRHVYNDNXOWNlVDlVY0ltVlpKZExVRHorRHUxZkt0WTlzNk1wZ1ZmM2xrWWowaTg5c0xiYkxTRlhKb0NNUDV3YUJoT2lzV0ZYWUNCc1dRUXd6Nm9ndXRHdlVCRlFWVzd2KzJjT0ZMWGRDWFlxc21uc2JXbEs1RUprU3NKbm5lNUFZRjhNTGt4VkdHWUlIZU1UY05tZHdseFB6K09yTzdzdXk5TXFTRzR6UmxvWUxLMHRjNXlrTjMxeS9lazNsdVhTY1JYZzQ1YVdMd0NYSDJOYTFxSFpRT0RublVPTFJyb3AyQW1qVG9iVlVMR25Ibm52bHZiZXVyY0ZIY2U3R2laTlozSHNDZG1qY0Zob21QWEVwNW5ab3dkYnJ3dVdXRUJqMmVvMFZOWUZZeVVyOUp3ZFFUZ0tUWThVSU5MTWpkWGNxUXV4Yjh3c25XSEdod0w1dzN2WFBDTkJQSXJUcVZMbklXeUlLZHNIbVYvZnlPc0NxNWE5U2NWMXYrVEtJOTNmamltRU43V0NUVE5XUUdhUlkvcHFTK01MZElIb0xpZjJJUkZqOWcwQWhHS0E5NFNzNXgwbDg0ekhUZlc0bDJsNjBiSWtJZmJWOHBTdTRZQlZlZEZicmRsS0MzWllFV2haZGZhYUp2QTNlYjBQSVpCK1hWUjhaa0NqS3JRTWpmMmZQV29obEo1WVF3MDhRQVJYN0h0VWlZaVJNMzRLTFB3SEpqOFc3U1M0SkpTSGo0V05DY3dYYU9YQStYT0c0LzhFMmhNbDVRMXIvRVVsNGFMTk5CSC8zUlpzNklBT0xJOEhlbkpMSFo0Q1A2VE9vbThYNmFXZGVFa3YvTEk1d3V1OTJ3cjZzdnN5S1ZVTHg2U2MxY0FsbXpQaTVlYkdyR2FFQkxYYmptak9QbzRhbUN4SGdCRzF5aTZXV2w3eHNnU3A1RGptZi9sWEFDQmdCbTJidUxHVDVUWkh3ZDl6eDRTaG10MTlRV0MwZGVhemQxWGlKSkU0dlZ4dFY3VEZIekpkSFlvMnM4YXpDR3lDMnBsN05yYXlmZVAxbDRoSlBiRDNSODlab0k2ZXIxT2p4amNoTzVmcEt5djYrakdhWkdSSXJ2aVpsTktVQmxLaHRNanpxSUZYME1LeDhkY0tGdUpKU2VGOHdFR3NZSlkyNm1YY1VIL0RRLytqZEwwbGJ1WFd1VzN0c21zYWRNZXVjTEpocHg2clRDeUJhT0lhMjdpQjBvVEMvdmNoWXBzK05iUGhrNEsxU3ZVVWR0TXEzeXUyUkRtM0JNeGVndnBUcExiaWl3VEgvcnJuamNFR0ZyaFRqVVJyMUNhaVVsdDNsZnR3N0RoVjJxT1VhUUtzb1pYSEVzMStPajNwODJNWmg3V0Zhd1RyMGJTTFVnMmp4dXhxOTRNUzVrNlpXRzhuNXF0eW1DRWhHNUtJOGxxZ1g3Qk5xRjM2aEJsZkNsUkZrcmlHdFN2T01oMVJJTXRIK0VFei9RdHo0aVp3R05GaHlQN21HdTRsTE94Njg0K3RxeXVEbUwzaE9WTUFwb08zU25jbS84RUIwZ1RTR0xSSEx5amozMnAzM3J0K2NaY0tZVCtKVVdDL0wrUHd4UkdWc3FXRm5LbzM3RURyWXNkWE13V2swZ0YvRmZ6WDhqbXZ5SkZWR29GQXA4eXNmTjBlVm1nVjc0eXZVMGFwbjJGUGlvWjNoZnk4eHhVZmRPNkp2S3lRejk2bWNzSHRtYUpvRTRETEJQNktXNnF2ald1Ky9NOS9HUmk2OFdnNGxyTmFtSEIvOUU0MHhLKzJHS1ZiblV6Yll5OW00bGVCYjNrYjhqNFpqSWFQTHZzK0lzQ1VCRGlHazV3d255TFhFeENpZWZCc0hPbktNQ2w3QzVyRzc1Y3FpWkYxVmFhOHc0Q1F0ZytNandvVGR4Q25FODE4Q0dnMjQ2cDJocjYzUHgrVUVHclVKNE9oZ1V5MDdBZWhidlVCUGpvVWxJd3dpUGQ2VjAxTnBXMTFHekkvQ1AvamVZRVhnSVJ6V0hhb09mL08xK3gxLzFoTVI0R0FibCtlRlcvNjQxaTIvZkFFNGJTRVBwbk9wa1BORkRqbUx4MDF6YVhIMUJIQUVVUWlPa3VMTUpuNDNPQ3ZrbGJXeVhHUlNhMkZjMjhMTlVWM1QwMDVCUUcvNFhWR0E9PTwveGVuYzpDaXBoZXJWYWx1ZT4KICAgPC94ZW5jOkNpcGhlckRhdGE+CjwveGVuYzpFbmNyeXB0ZWREYXRhPjwvc2FtbDpFbmNyeXB0ZWRBc3NlcnRpb24+PC9zYW1scDpSZXNwb25zZT4K';
255
    }
256
}
257