Repository: laravel/vapor-core Branch: 2.0 Commit: e03d8fc00766 Files: 130 Total size: 473.9 KB Directory structure: gitextract__wb9ole1/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── SECURITY.md │ ├── SUPPORT.md │ └── workflows/ │ ├── static-analysis.yml │ ├── tests.yml │ └── update-changelog.yml ├── .gitignore ├── .styleci.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── config/ │ └── vapor.php ├── phpstan.neon.dist ├── phpunit.xml.dist ├── src/ │ ├── Arr.php │ ├── ConfiguresAssets.php │ ├── ConfiguresDynamoDb.php │ ├── ConfiguresQueue.php │ ├── ConfiguresRedis.php │ ├── ConfiguresSqs.php │ ├── Console/ │ │ └── Commands/ │ │ ├── OctaneStatusCommand.php │ │ ├── VaporHealthCheckCommand.php │ │ ├── VaporQueueListFailedCommand.php │ │ ├── VaporScheduleCommand.php │ │ ├── VaporWorkCommand.php │ │ └── WritesQueueEventMessages.php │ ├── Contracts/ │ │ ├── LambdaEventHandler.php │ │ ├── LambdaResponse.php │ │ └── SignedStorageUrlController.php │ ├── DefinesRoutes.php │ ├── Events/ │ │ └── LambdaEvent.php │ ├── HasAwsContext.php │ ├── Http/ │ │ ├── Controllers/ │ │ │ └── SignedStorageUrlController.php │ │ └── Middleware/ │ │ └── ServeStaticAssets.php │ ├── Logging/ │ │ └── JsonFormatter.php │ ├── Queue/ │ │ ├── JobAttempts.php │ │ ├── VaporConnector.php │ │ ├── VaporJob.php │ │ ├── VaporQueue.php │ │ └── VaporWorker.php │ ├── Runtime/ │ │ ├── ArrayLambdaResponse.php │ │ ├── CliHandlerFactory.php │ │ ├── Environment.php │ │ ├── Fpm/ │ │ │ ├── ActsAsFastCgiDataProvider.php │ │ │ ├── Fpm.php │ │ │ ├── FpmApplication.php │ │ │ ├── FpmHttpHandlerFactory.php │ │ │ ├── FpmRequest.php │ │ │ ├── FpmResponse.php │ │ │ └── FpmResponseHeaders.php │ │ ├── Handlers/ │ │ │ ├── CliHandler.php │ │ │ ├── FpmHandler.php │ │ │ ├── LoadBalancedFpmHandler.php │ │ │ ├── LoadBalancedOctaneHandler.php │ │ │ ├── OctaneHandler.php │ │ │ ├── PayloadFormatVersion2FpmHandler.php │ │ │ ├── PayloadFormatVersion2OctaneHandler.php │ │ │ ├── QueueHandler.php │ │ │ ├── UnknownEventHandler.php │ │ │ ├── WarmerHandler.php │ │ │ └── WarmerPingHandler.php │ │ ├── Http/ │ │ │ └── Middleware/ │ │ │ ├── EnsureBinaryEncoding.php │ │ │ ├── EnsureOnNakedDomain.php │ │ │ ├── EnsureVanityUrlIsNotIndexed.php │ │ │ └── RedirectStaticAssets.php │ │ ├── HttpKernel.php │ │ ├── LambdaContainer.php │ │ ├── LambdaInvocation.php │ │ ├── LambdaResponse.php │ │ ├── LambdaRuntime.php │ │ ├── LoadBalancedLambdaResponse.php │ │ ├── Logger.php │ │ ├── NotifiesLambda.php │ │ ├── Octane/ │ │ │ ├── Octane.php │ │ │ ├── OctaneHttpHandlerFactory.php │ │ │ └── OctaneRequestContextFactory.php │ │ ├── PayloadFormatVersion2LambdaResponse.php │ │ ├── Request.php │ │ ├── Response.php │ │ ├── Secrets.php │ │ └── StorageDirectories.php │ ├── Vapor.php │ ├── VaporJobTimedOutException.php │ ├── VaporServiceProvider.php │ └── debug.php ├── stubs/ │ ├── 503.html │ ├── cliRuntime.php │ ├── fpmRuntime.php │ ├── httpHandler.php │ ├── httpRuntime.php │ ├── octaneRuntime.php │ ├── php-fpm.conf │ ├── rds-combined-ca-bundle.pem │ ├── runtime-with-vendor-download.php │ └── runtime.php └── tests/ ├── Feature/ │ ├── ApiGatewayOctaneHandlerTest.php │ ├── Commands/ │ │ └── OctaneStatusCommandTest.php │ ├── EnsureOnNakedDomainTest.php │ ├── LambdaProxyOctaneHandlerTest.php │ ├── LoadBalancedOctaneHandlerTest.php │ ├── OctaneManageDatabaseSessionsTest.php │ ├── OctaneTest.php │ ├── RedirectStaticAssetsTest.php │ ├── SignedStorageUrlEndpointTest.php │ ├── VaporJobTest.php │ └── VaporQueueTest.php ├── Fixtures/ │ ├── 503.json │ ├── asset.js │ ├── customLambdaEventFromSQS.json │ ├── customNonSQSLambdaEvent.json │ └── jobLambdaEventFromSQS.json ├── TestCase.php └── Unit/ ├── FakeJob.php ├── FpmRequestTest.php ├── HttpKernelTest.php ├── LambdaEventTest.php ├── LoadBalancedLambdaResponseTest.php ├── Logging/ │ └── JsonFormatterTest.php ├── OctaneHttpHandlerFactoryTest.php ├── QueueHandlerTest.php ├── Runtime/ │ └── CliHandlerFactoryTest.php ├── VaporConnectorTest.php ├── VaporScheduleCommandTest.php ├── VaporTest.php └── VaporWorkCommandTest.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true indent_style = space indent_size = 4 trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false [*.{yml,yaml}] indent_size = 2 ================================================ FILE: .gitattributes ================================================ # Path-based git attributes # https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html # Ignore all test and documentation with "export-ignore". /.env.example export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.github export-ignore /phpunit.xml.dist export-ignore /.scrutinizer.yml export-ignore /tests export-ignore /.editorconfig export-ignore phpstan.neon.dist export-ignore ================================================ FILE: .github/CODE_OF_CONDUCT.md ================================================ # Code of Conduct The Laravel Code of Conduct can be found in the [Laravel documentation](https://laravel.com/docs/contributions#code-of-conduct). ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contribution Guide The Laravel contributing guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ================================================ FILE: .github/SECURITY.md ================================================ # Security Policy **PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, [SEE BELOW](#reporting-a-vulnerability).** ## Supported Versions Only the latest major version receives security fixes. ## Reporting a Vulnerability If you discover a security vulnerability within Laravel, please send an email to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed. ### Public PGP Key ``` -----BEGIN PGP PUBLIC KEY BLOCK----- Version: OpenPGP v2.0.8 Comment: Report Security Vulnerabilities to taylor@laravel.com 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 WBGOG/qJGDlNiqBYYt2xNqzHCJoC =zXOv -----END PGP PUBLIC KEY BLOCK----- ``` ================================================ FILE: .github/SUPPORT.md ================================================ # Support Questions The Laravel support guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions#support-questions). ================================================ FILE: .github/workflows/static-analysis.yml ================================================ name: static analysis on: push: branches: - master - '*.x' pull_request: permissions: contents: read jobs: tests: uses: laravel/.github/.github/workflows/static-analysis.yml@main ================================================ FILE: .github/workflows/tests.yml ================================================ name: tests on: push: pull_request: schedule: - cron: '0 0 * * *' jobs: tests: runs-on: ubuntu-22.04 strategy: fail-fast: true matrix: php: [8.1, 8.2, 8.3] laravel: [10, 11, '12', '13'] exclude: - php: 8.1 laravel: 11 - laravel: '12' php: 8.1 - laravel: '13' php: 8.1 - laravel: '13' php: 8.2 name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} tools: composer:v2 coverage: none - name: Setup Problem Matches run: | echo "::add-matcher::${{ runner.tool_cache }}/php.json" echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - name: Install PHP dependencies run: | composer require "illuminate/contracts=^${{ matrix.laravel }}" --no-update composer update --prefer-dist --no-interaction --no-progress - name: Install Octane run: | composer require laravel/octane --with-all-dependencies --dev if: | matrix.php >= 8.0 && (matrix.laravel == '8' || matrix.laravel == '9' || matrix.laravel == '10' || matrix.laravel == '11') - name: Execute unit tests run: vendor/bin/phpunit ================================================ FILE: .github/workflows/update-changelog.yml ================================================ name: update changelog on: release: types: [released] jobs: update: permissions: contents: write uses: laravel/.github/.github/workflows/update-changelog.yml@main ================================================ FILE: .gitignore ================================================ .env .phpunit.result.cache phpunit.xml build composer.lock docs vendor coverage ================================================ FILE: .styleci.yml ================================================ preset: laravel disabled: - single_class_element_per_statement ================================================ FILE: CHANGELOG.md ================================================ # Release Notes ## [Unreleased](https://github.com/laravel/vapor-core/compare/v2.43.3...2.0) ## [v2.43.3](https://github.com/laravel/vapor-core/compare/v2.43.2...v2.43.3) - 2026-03-09 * [2.0] Catch PDOException when MySQL server has gone away during SET SESSION wait_timeout reset by [@rizalpahlevii](https://github.com/rizalpahlevii) in https://github.com/laravel/vapor-core/pull/200 ## [v2.43.2](https://github.com/laravel/vapor-core/compare/v2.43.1...v2.43.2) - 2026-02-21 * Laravel 13.x Compatibility by [@laravel-shift](https://github.com/laravel-shift) in https://github.com/laravel/vapor-core/pull/199 ## [v2.43.1](https://github.com/laravel/vapor-core/compare/v2.43.0...v2.43.1) - 2026-01-20 * fix: `curl_close()` is deprecated by [@mortenhauberg](https://github.com/mortenhauberg) in https://github.com/laravel/vapor-core/pull/198 ## [v2.43.0](https://github.com/laravel/vapor-core/compare/v2.42.0...v2.43.0) - 2026-01-08 * Add dynamic cli handler factory. by [@Sfonxs](https://github.com/Sfonxs) in https://github.com/laravel/vapor-core/pull/197 ## [v2.42.0](https://github.com/laravel/vapor-core/compare/v2.41.0...v2.42.0) - 2025-12-19 * Expose AWS Lambda execution context for Vapor logging by [@sahil7194](https://github.com/sahil7194) in https://github.com/laravel/vapor-core/pull/196 ## [v2.41.0](https://github.com/laravel/vapor-core/compare/v2.40.0...v2.41.0) - 2025-09-10 * fix: Allow custom Lambda events from SQS by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/vapor-core/pull/194 ## [v2.40.0](https://github.com/laravel/vapor-core/compare/v2.39.0...v2.40.0) - 2025-08-04 ## [v2.39.0](https://github.com/laravel/vapor-core/compare/v2.38.2...v2.39.0) - 2025-07-10 * Add API Gateway request timestamp to server variables by [@mortenhauberg](https://github.com/mortenhauberg) in https://github.com/laravel/vapor-core/pull/192 ## [v2.38.2](https://github.com/laravel/vapor-core/compare/v2.38.1...v2.38.2) - 2025-07-04 ## [v2.38.1](https://github.com/laravel/vapor-core/compare/v2.38.0...v2.38.1) - 2025-06-27 ## [v2.38.0](https://github.com/laravel/vapor-core/compare/v2.37.9...v2.38.0) - 2025-06-02 * Fix missing write permission for changelog updater by [@olivernybroe](https://github.com/olivernybroe) in https://github.com/laravel/vapor-core/pull/189 * [2.x] Fixes support for S3-Compatible Storage like Herd minio by [@pintend](https://github.com/pintend) in https://github.com/laravel/vapor-core/pull/190 ## [v2.37.9](https://github.com/laravel/vapor-core/compare/v2.37.8...v2.37.9) - 2025-01-07 * Fix parsing multidimensional array from multipart by [@Vinimaks](https://github.com/Vinimaks) in https://github.com/laravel/vapor-core/pull/186 ## [v2.37.8](https://github.com/laravel/vapor-core/compare/v2.37.2...v2.37.8) - 2024-12-06 * Fix Octane cookies for v2 by [@Vinimaks](https://github.com/Vinimaks) in https://github.com/laravel/vapor-core/pull/185 ## [v2.37.2](https://github.com/laravel/vapor-core/compare/v2.37.1...v2.37.2) - 2024-11-06 * Add missing files in .github by [@Jubeki](https://github.com/Jubeki) in https://github.com/laravel/vapor-core/pull/178 * [2.x] Reset scoped instances before running a new vapor job by [@themsaid](https://github.com/themsaid) in https://github.com/laravel/vapor-core/pull/183 * Fix tests by [@themsaid](https://github.com/themsaid) in https://github.com/laravel/vapor-core/pull/184 ## [v2.37.1](https://github.com/laravel/vapor-core/compare/v2.33.2...v2.37.1) - 2024-03-26 * Use VAPOR_ENV for non-standard environment option by [@joelvh](https://github.com/joelvh) in https://github.com/laravel/vapor-core/pull/176 ## [v2.33.2](https://github.com/laravel/cashier/compare/v2.33.1...v2.33.2) - 2023-10-03 * [2.x] Adds helpers to determine when an app is running on Vapor by @joedixon in https://github.com/laravel/vapor-core/pull/164 ================================================ FILE: LICENSE.md ================================================ The MIT License (MIT) Copyright (c) Taylor Otwell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Laravel Vapor Core / Runtime

Build Status Total Downloads Latest Stable Version License

[Laravel Vapor](https://vapor.laravel.com) is an auto-scaling, serverless deployment platform for Laravel, powered by AWS Lambda. Manage your Laravel infrastructure on Vapor and fall in love with the scalability and simplicity of serverless. Vapor abstracts the complexity of managing Laravel applications on AWS Lambda, as well as interfacing those applications with SQS queues, databases, Redis clusters, networks, CloudFront CDN, and more. This repository contains the core service providers and runtime client used to make Laravel applications run smoothly in a serverless environment. To learn more about Vapor and how to use this repository, please consult the [official documentation](https://docs.vapor.build). ================================================ FILE: composer.json ================================================ { "name": "laravel/vapor-core", "description": "The kernel and invocation handlers for Laravel Vapor", "keywords": [ "laravel", "vapor" ], "homepage": "https://github.com/laravel/vapor-core", "license": "MIT", "authors": [ { "name": "Taylor Otwell", "email": "taylor@laravel.com" } ], "require": { "php": "^7.2|^8.0", "aws/aws-sdk-php": "^3.80", "guzzlehttp/promises": "^1.4|^2.0", "guzzlehttp/guzzle": "^6.3|^7.0", "hollodotme/fast-cgi-client": "^3.0", "illuminate/container": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", "illuminate/queue": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", "monolog/monolog": "^1.12|^2.0|^3.2", "nyholm/psr7": "^1.0", "riverline/multipart-parser": "^2.0.9", "symfony/process": "^4.3|^5.0|^6.0|^7.0", "symfony/psr-http-message-bridge": "^1.0|^2.0|^6.4|^7.0" }, "require-dev": { "laravel/octane": "*", "mockery/mockery": "^1.2", "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", "phpstan/phpstan": "^1.10|^2.1", "phpunit/phpunit": "^8.0|^9.0|^10.4|^11.5.3|^12.5.12" }, "autoload": { "psr-4": { "Laravel\\Vapor\\": "src" }, "files": [ "src/debug.php" ] }, "autoload-dev": { "psr-4": { "Laravel\\Vapor\\Tests\\": "tests" } }, "scripts": { "test": "vendor/bin/phpunit" }, "extra": { "branch-alias": { "dev-master": "2.0-dev" }, "laravel": { "providers": [ "Laravel\\Vapor\\VaporServiceProvider" ], "aliases": { "Vapor": "Laravel\\Vapor\\Vapor" } } }, "config": { "sort-packages": true }, "minimum-stability": "dev", "prefer-stable": true } ================================================ FILE: config/vapor.php ================================================ true, /* |-------------------------------------------------------------------------- | Redirect robots.txt |-------------------------------------------------------------------------- | | When this option is enabled, Vapor will redirect requests for your | application's "robots.txt" file to the location of the S3 asset | bucket or CloudFront's asset URL instead of serving directly. | */ 'redirect_robots_txt' => true, /* |-------------------------------------------------------------------------- | Servable Assets |-------------------------------------------------------------------------- | | Here you can configure list of public assets that should be servable | from your application's domain instead of only being servable via | the public S3 "asset" bucket or the AWS CloudFront CDN network. | */ 'serve_assets' => [ // ], ]; ================================================ FILE: phpstan.neon.dist ================================================ parameters: paths: - config - src level: 0 ignoreErrors: - "#Unsafe usage of new static\\(\\)#" - "#\\(void\\) is used.#" ================================================ FILE: phpunit.xml.dist ================================================ ./tests/Unit ./tests/Feature ================================================ FILE: src/Arr.php ================================================ * @author Matthieu Napoli */ class Arr { /** * Set a multi-part body array value in the given array. * * @param array $array * @param string $name * @param mixed $value * @return array */ public static function setMultipartArrayValue(array $array, string $name, $value) { $segments = explode('[', $name); $pointer = &$array; foreach ($segments as $key => $segment) { // If this is our first time through the loop we will just grab the initial // key's part of the array. After this we will start digging deeper into // the array as needed until we get to the correct depth in the array. if ($key === 0) { $pointer = &$pointer[$segment]; continue; } // If this segment is malformed, we will just use the key as-is since there // is nothing we can do with it from here. We will return the array back // to the caller with the value set. We cannot continue looping on it. if (static::malformedMultipartSegment($segment)) { $array[$name] = $value; return $array; } $segment = substr($segment, 0, -1); // If the segment is empty after trimming off the closing bracket, it means // we are at the end of the segment and are ready to set the value so we // can grab a pointer to the array location and set it after the loop. if ($segment === '') { $pointer = &$pointer[]; } else { $pointer = &$pointer[$segment]; } } $pointer = $value; return $array; } /** * Determine if the given multi-part value segment is malformed. * * This can occur when there are two [[ or no closing bracket. * * @param string $segment * @return bool */ protected static function malformedMultipartSegment($segment) { return $segment === '' || substr($segment, -1) !== ']'; } } ================================================ FILE: src/ConfiguresAssets.php ================================================ 'dynamodb', 'key' => $_ENV['AWS_ACCESS_KEY_ID'] ?? null, 'secret' => $_ENV['AWS_SECRET_ACCESS_KEY'] ?? null, 'region' => $_ENV['AWS_DEFAULT_REGION'] ?? 'us-east-1', 'table' => $_ENV['DYNAMODB_CACHE_TABLE'] ?? 'cache', 'endpoint' => $_ENV['DYNAMODB_ENDPOINT'] ?? null, ], Config::get('cache.stores.dynamodb') ?? [])); } } ================================================ FILE: src/ConfiguresQueue.php ================================================ app->bound('queue.vaporWorker')) { return; } $this->app->singleton('queue.vaporWorker', function () { $isDownForMaintenance = function () { return $this->app->isDownForMaintenance(); }; return new VaporWorker( $this->app['queue'], $this->app['events'], $this->app[ExceptionHandler::class], $isDownForMaintenance ); }); $this->app->singleton(JobAttempts::class, function () { return new JobAttempts( isset($_ENV['VAPOR_CACHE_JOB_ATTEMPTS']) && $_ENV['VAPOR_CACHE_JOB_ATTEMPTS'] === 'true' ? $this->app['cache']->driver() : new Repository(new NullStore()) ); }); } } ================================================ FILE: src/ConfiguresRedis.php ================================================ $_ENV['REDIS_CLIENT'] ?? 'phpredis', 'options' => array_merge( Config::get('database.redis.options', []), array_filter([ 'cluster' => $_ENV['REDIS_CLUSTER'] ?? 'redis', 'scheme' => $_ENV['REDIS_SCHEME'] ?? null, 'context' => array_filter(['cafile' => $_ENV['REDIS_SSL_CA'] ?? null]), ]) ), 'clusters' => array_merge(Config::get('database.redis.clusters', []), [ 'default' => [ [ 'host' => $_ENV['REDIS_HOST'] ?? '127.0.0.1', 'password' => null, 'port' => 6379, 'database' => 0, ], ], 'cache' => [ [ 'host' => $_ENV['REDIS_HOST'] ?? '127.0.0.1', 'password' => null, 'port' => 6379, 'database' => 0, ], ], ]), ])); } } ================================================ FILE: src/ConfiguresSqs.php ================================================ 'sqs', 'key' => $_ENV['AWS_ACCESS_KEY_ID'] ?? null, 'secret' => $_ENV['AWS_SECRET_ACCESS_KEY'] ?? null, 'prefix' => $_ENV['SQS_PREFIX'] ?? null, 'queue' => $_ENV['SQS_QUEUE'] ?? 'default', 'region' => $_ENV['AWS_DEFAULT_REGION'] ?? 'us-east-1', ], Config::get('queue.connections.sqs') ?? [])); } } ================================================ FILE: src/Console/Commands/OctaneStatusCommand.php ================================================ isEnvironmentRunningOnOctane() ? $this->info('Octane server is running.') : $this->info('Octane server is not running.'); } /** * Determine if the environment is running on Octane. * * @return bool */ protected function isEnvironmentRunningOnOctane() { return isset($_ENV['OCTANE_DATABASE_SESSION_TTL']); } } ================================================ FILE: src/Console/Commands/VaporHealthCheckCommand.php ================================================ ensureBaseConfigurationFilesWereHarmonized(); $this->ensureCacheIsWorking(); return $this->info('Health check complete!'); } /** * Ensure the configuration files were harmonized. * * @return void */ protected function ensureBaseConfigurationFilesWereHarmonized() { if (! file_exists($filename = __DIR__.'/../../../../framework/config/cache.php')) { return; } $configuration = file_get_contents($filename); if (! Str::contains($configuration, "'key' => env('NULL_AWS_ACCESS_KEY_ID')")) { throw new Exception( 'Laravel 11 or later requires the latest version of Vapor CLI.' ); } } /** * Ensure cache calls are working as expected. * * @return void */ protected function ensureCacheIsWorking() { Cache::get('vapor-health-check'); } } ================================================ FILE: src/Console/Commands/VaporQueueListFailedCommand.php ================================================ options()) ->filter(function ($value, $option) { return ! is_null($value) && in_array($option, ['id', 'queue', 'query', 'start']); }); $failer = $this->laravel['queue.failer']; $start = $this->option('start'); if (is_callable([$failer, 'getTable']) && $start) { $failed = $failer->getTable() ->where('failed_at', '>=', Carbon::createFromTimestamp($start)->toDateTimeString()) ->get(); $options = $options->reject(function ($value, $name) { return $name === 'start'; }); } else { $failed = $failer->all(); } $failedJobs = collect($failed)->filter(function ($job) use ($options) { return $options->every(function ($value, $option) use ($job) { return $this->filter($job, $option, $value); }); }); $total = count($failedJobs); $page = $this->option('page'); $limit = $this->option('limit'); if ($limit) { $failedJobs = $failedJobs->forPage($page, $limit); } $failedJobs = $failedJobs->map(function ($failed) { return array_merge((array) $failed, [ 'payload' => $failed->payload, 'exception' => Str::limit($failed->exception, 1000), 'name' => $this->extractJobName($failed->payload), 'queue' => Str::afterLast($failed->queue, '/'), 'message' => $this->extractMessage($failed->exception), 'connection' => $failed->connection, ]); })->values()->toArray(); $failedJobs = [ 'failed_jobs' => $failedJobs, 'total' => $total, 'from' => $limit ? ($page - 1) * $limit + 1 : 1, 'to' => $limit ? min($page * $limit, $total) : $total, 'has_next_page' => $limit && $total > $limit * $page, 'has_previous_page' => $limit && $page > 1 && $total > $limit * ($page - 1), ]; $this->output->writeln( json_encode($failedJobs) ); } /** * Extract the failed job name from payload. * * @param string $payload * @return string|null */ private function extractJobName($payload) { $payload = json_decode($payload, true); if ($payload && (! isset($payload['data']['command']))) { return $payload['job'] ?? null; } elseif ($payload && isset($payload['data']['command'])) { return $this->matchJobName($payload); } } /** * Extract the failed job message from exception. * * @param string $exception * @return string */ private function extractMessage($exception) { if (Str::startsWith($exception, ManuallyFailedException::class)) { $message = 'Manually failed'; } else { [$_, $message] = explode(':', $exception); [$message] = explode(' in /', $message); [$message] = explode(' in closure', $message); } if (! empty($message)) { return trim($message); } return ''; } /** * Match the job name from the payload. * * @param array $payload * @return string|null */ protected function matchJobName($payload) { preg_match('/"([^"]+)"/', $payload['data']['command'], $matches); return $matches[1] ?? $payload['job'] ?? null; } /** * Determine whether the given job matches the given filter. * * @param stdClass $job * @param string $option * @param string $value * @return bool */ protected function filter($job, $option, $value) { if ($option === 'id') { return $job->id === $value; } if ($option === 'queue') { return Str::afterLast($job->queue, '/') === $value; } if ($option === 'query') { return Str::contains(json_encode($job), $value); } if ($option === 'start') { return Carbon::parse($job->failed_at)->timestamp >= $value; } return false; } } ================================================ FILE: src/Console/Commands/VaporScheduleCommand.php ================================================ ensureValidCacheDriver()) { $this->call('schedule:run'); return 0; } $key = (string) Str::uuid(); $lockObtained = false; while (true) { if (! $lockObtained) { $lockObtained = $this->obtainLock($cache, $key); } if ($lockObtained && now()->second === 0) { $this->releaseLock($cache); $this->call('schedule:run'); return 0; } if (! $lockObtained && now()->second === 0) { return 1; } usleep(10000); } } /** * Ensure the cache driver is valid. */ protected function ensureValidCacheDriver(): ?Repository { $manager = $this->laravel['cache']; if (in_array($manager->getDefaultDriver(), ['memcached', 'redis', 'dynamodb', 'database'])) { return $manager->driver(); } return null; } /** * Obtain the lock for the schedule. */ protected function obtainLock(Repository $cache, string $key): bool { return $key === $cache->remember('vapor:schedule:lock', 60, function () use ($key) { return $key; }); } /** * Release the lock for the schedule. */ protected function releaseLock(Repository $cache): void { $cache->forget('vapor:schedule:lock'); } } ================================================ FILE: src/Console/Commands/VaporWorkCommand.php ================================================ worker = $worker; } /** * Execute the console command. * * @param \Laravel\Vapor\Events\LambdaEvent $event * @return void */ public function handle(LambdaEvent $event) { if ($this->downForMaintenance()) { return; } if (! static::$listeningForEvents) { $this->listenForEvents(); static::$listeningForEvents = true; } $this->worker->setCache($this->laravel['cache']->driver()); return $this->worker->runVaporJob( $this->marshalJob($this->message($event)), 'sqs', $this->gatherWorkerOptions() ); } /** * Marshal the job with the given message ID. * * @param array $message * @return \Laravel\Vapor\Queue\VaporJob */ protected function marshalJob(array $message) { $normalizedMessage = $this->normalizeMessage($message); $queue = $this->worker->getManager()->connection('sqs'); return new VaporJob( $this->laravel, $queue->getSqs(), $normalizedMessage, 'sqs', $this->queueUrl($message) ); } /** * Normalize the casing of the message array. * * @param array $message * @return array */ protected function normalizeMessage(array $message) { return [ 'MessageId' => $message['messageId'], 'ReceiptHandle' => $message['receiptHandle'], 'Body' => $message['body'], 'Attributes' => $message['attributes'], 'MessageAttributes' => $message['messageAttributes'], ]; } /** * Get the message payload. * * @param \Laravel\Vapor\Events\LambdaEvent $event * @return array */ protected function message($event) { return $event['Records'][0]; } /** * Get the queue URL from the given message. * * @param array $message * @return string */ protected function queueUrl(array $message) { $eventSourceArn = explode(':', $message['eventSourceARN']); return sprintf( 'https://sqs.%s.amazonaws.com/%s/%s', $message['awsRegion'], $accountId = $eventSourceArn[4], $queue = $eventSourceArn[5] ); } /** * Gather all of the queue worker options as a single object. * * @return \Illuminate\Queue\WorkerOptions */ protected function gatherWorkerOptions() { $options = [ $this->option('delay'), $memory = 512, $this->option('timeout'), $sleep = 0, $this->option('tries'), $this->option('force'), $stopWhenEmpty = false, ]; if (property_exists(WorkerOptions::class, 'name')) { $options = array_merge(['default'], $options); } return new WorkerOptions(...$options); } /** * Store a failed job event. * * @param \Illuminate\Queue\Events\JobFailed $event * @return void */ protected function logFailedJob(JobFailed $event) { $this->laravel['queue.failer']->log( $event->connectionName, $event->job->getQueue(), $event->job->getRawBody(), $event->exception ); } /** * Determine if the worker should run in maintenance mode. * * @return bool */ protected function downForMaintenance() { if (! $this->option('force')) { return $this->laravel->isDownForMaintenance(); } return false; } /** * Reset static variables. * * @return void */ public static function flushState() { static::$listeningForEvents = false; } } ================================================ FILE: src/Console/Commands/WritesQueueEventMessages.php ================================================ laravel['events']->listen(JobProcessing::class, function ($event) { $this->writeOutput($event->job, 'starting'); }); $this->laravel['events']->listen(JobProcessed::class, function ($event) { $this->writeOutput($event->job, 'success'); }); $this->laravel['events']->listen(JobFailed::class, function ($event) { $this->writeOutput($event->job, 'failed'); $this->logFailedJob($event); }); } /** * Write the status output for the queue worker. * * @param \Illuminate\Contracts\Queue\Job $job * @param string $status * @return void */ protected function writeOutput(Job $job, $status) { switch ($status) { case 'starting': return $this->writeStatus($job, 'Processing', 'comment'); case 'success': return $this->writeStatus($job, 'Processed', 'info'); case 'failed': return $this->writeStatus($job, 'Failed', 'error'); } } /** * Format the status output for the queue worker. * * @param \Illuminate\Contracts\Queue\Job $job * @param string $status * @param string $type * @return void */ protected function writeStatus(Job $job, $status, $type) { $this->output->writeln(sprintf( "<{$type}>%s %s", str_pad("{$status}:", 11), $job->resolveName() )); } } ================================================ FILE: src/Contracts/LambdaEventHandler.php ================================================ app->routesAreCached()) { return; } if (config('vapor.signed_storage.enabled', true)) { Route::post( config('vapor.signed_storage.url', '/vapor/signed-storage-url'), Contracts\SignedStorageUrlController::class.'@store' )->middleware(config('vapor.middleware', 'web')); } } } ================================================ FILE: src/Events/LambdaEvent.php ================================================ event = $event; } /** * Determine if an item exists at an offset. * * @param string $key * @return bool */ #[\ReturnTypeWillChange] public function offsetExists($key) { return Arr::exists($this->event, $key); } /** * Get an item at a given offset. * * @param string $key * @return array|string|int */ #[\ReturnTypeWillChange] public function offsetGet($key) { return Arr::get($this->event, $key); } /** * Set the item at a given offset. * * @param string $key * @param array|string|int $value * @return void */ #[\ReturnTypeWillChange] public function offsetSet($key, $value) { Arr::set($this->event, $key, $value); } /** * Unset the item at a given offset. * * @param string $key * @return void */ #[\ReturnTypeWillChange] public function offsetUnset($key) { Arr::forget($this->event, $key); } /** * Get the instance as an array. * * @return array */ public function toArray() { return $this->event; } } ================================================ FILE: src/HasAwsContext.php ================================================ self::requestId(), 'function_name' => self::functionName(), 'function_version' => self::functionVersion(), 'log_group_name' => self::logGroupName(), 'log_stream_name' => self::logStreamName(), ]; } } ================================================ FILE: src/Http/Controllers/SignedStorageUrlController.php ================================================ ensureEnvironmentVariablesAreAvailable($request); Gate::authorize('uploadFiles', [ $request->user(), $bucket = $request->input('bucket') ?: $_ENV['AWS_BUCKET'], ]); $client = $this->storageClient(); $uuid = (string) Str::uuid(); $expiresAfter = config('vapor.signed_storage_url_expires_after', 5); $signedRequest = $client->createPresignedRequest( $this->createCommand($request, $client, $bucket, $key = $this->getKey($uuid)), sprintf('+%s minutes', $expiresAfter) ); $uri = $signedRequest->getUri(); return response()->json([ 'uuid' => $uuid, 'bucket' => $bucket, 'key' => $key, 'url' => $uri->getScheme().'://'.$uri->getAuthority().$uri->getPath().'?'.$uri->getQuery(), 'headers' => $this->headers($request, $signedRequest), ], 201); } /** * Create a command for the PUT operation. * * @param \Illuminate\Http\Request $request * @param \Aws\S3\S3Client $client * @param string $bucket * @param string $key * @return \Aws\Command */ protected function createCommand(Request $request, S3Client $client, $bucket, $key) { return $client->getCommand('putObject', array_filter([ 'Bucket' => $bucket, 'Key' => $key, 'ACL' => $request->input('visibility') ?: $this->defaultVisibility(), 'ContentType' => $request->input('content_type') ?: 'application/octet-stream', 'CacheControl' => $request->input('cache_control') ?: null, 'Expires' => $request->input('expires') ?: null, ])); } /** * Get the headers that should be used when making the signed request. * * @param \Illuminate\Http\Request $request * @param \GuzzleHttp\Psr7\Request * @return array */ protected function headers(Request $request, $signedRequest) { return array_merge( $signedRequest->getHeaders(), [ 'Content-Type' => $request->input('content_type') ?: 'application/octet-stream', ] ); } /** * Ensure the required environment variables are available. * * @param \Illuminate\Http\Request $request * @return void */ protected function ensureEnvironmentVariablesAreAvailable(Request $request) { $missing = array_diff_key(array_flip(array_filter([ $request->input('bucket') ? null : 'AWS_BUCKET', 'AWS_DEFAULT_REGION', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', ])), $_ENV); if (empty($missing)) { return; } throw new InvalidArgumentException( 'Unable to issue signed URL. Missing environment variables: '.implode(', ', array_keys($missing)) ); } /** * Get the S3 storage client instance. * * @return \Aws\S3\S3Client */ protected function storageClient() { $config = [ 'region' => config('filesystems.disks.s3.region', $_ENV['AWS_DEFAULT_REGION']), 'version' => 'latest', 'signature_version' => 'v4', 'use_path_style_endpoint' => config('filesystems.disks.s3.use_path_style_endpoint', false), ]; if (! isset($_ENV['AWS_LAMBDA_FUNCTION_VERSION'])) { $config['credentials'] = array_filter([ 'key' => $_ENV['AWS_ACCESS_KEY_ID'] ?? null, 'secret' => $_ENV['AWS_SECRET_ACCESS_KEY'] ?? null, 'token' => $_ENV['AWS_SESSION_TOKEN'] ?? null, ]); if (array_key_exists('AWS_URL', $_ENV) && ! is_null($_ENV['AWS_URL'])) { $config['url'] = $_ENV['AWS_URL']; $config['endpoint'] = $_ENV['AWS_URL']; } if (array_key_exists('AWS_ENDPOINT', $_ENV) && ! is_null($_ENV['AWS_ENDPOINT'])) { $config['endpoint'] = $_ENV['AWS_ENDPOINT']; } } return new S3Client($config); } /** * Get key for the given UUID. * * @param string $uuid * @return string */ protected function getKey(string $uuid) { return 'tmp/'.$uuid; } /** * Get the default visibility for uploads. * * @return string */ protected function defaultVisibility() { return 'private'; } } ================================================ FILE: src/Http/Middleware/ServeStaticAssets.php ================================================ getStatusCode() === 404) { $requestUri = $request->getRequestUri(); if (! in_array(ltrim($requestUri, '/'), config('vapor.serve_assets', []))) { return $response; } $asset = null; try { $asset = (new Client)->get(asset($requestUri)); } catch (ClientException $e) { report($e); } if ($asset && $asset->getStatusCode() === 200) { $headers = collect($asset->getHeaders()) ->only(['Content-Length', 'Content-Type']) ->all(); return response($asset->getBody())->withHeaders($headers); } } return $response; } } ================================================ FILE: src/Logging/JsonFormatter.php ================================================ ($_ENV['AWS_REQUEST_ID'] ?? null)]; if ($record instanceof LogRecord) { $record = new LogRecord( $record->datetime, $record->channel, $record->level, $record->message, array_merge($record->context, $context), $record->extra, $record->formatted ); } else { $record['context'] = array_merge( $record['context'] ?? [], $context ); } return parent::format($record); } } ================================================ FILE: src/Queue/JobAttempts.php ================================================ cache = $cache; } /** * Determine if the job have been attempted before. * * @param \Illuminate\Contracts\Queue\Job|string $job * @return bool */ protected function has($job) { return ! is_null($this->cache->get($this->key($job))); } /** * Get the number of times the job has been attempted. * * @param \Illuminate\Contracts\Queue\Job|string $job * @return int */ public function get($job) { return (int) $this->cache->get($this->key($job), 0); } /** * Increment the number of times the job has been attempted. * * @param \Illuminate\Contracts\Queue\Job $job * @return void */ public function increment($job) { if ($this->has($job)) { $this->cache->increment($this->key($job)); return; } $this->cache->put($this->key($job), 1, static::TTL); } /** * Transfer the job attempts from one job to another. * * @param \Illuminate\Contracts\Queue\Job|string $from * @param \Illuminate\Contracts\Queue\Job|string $to * @return void */ public function transfer($from, $to) { $this->cache->put($this->key($to), $this->get($from), static::TTL); $this->cache->forget($this->key($from)); } /** * Forget the number of times the job has been attempted. * * @param \Illuminate\Contracts\Queue\Job|string $job * @return null */ public function forget($job) { $this->cache->forget($this->key($job)); } /** * Gets the cache key for the given job. * * @param \Illuminate\Contracts\Queue\Job|string $job * @return string */ protected function key($job) { $jobId = $job instanceof Job ? $job->getJobId() : $job; return 'laravel_vapor_job_attempts:'.$jobId; } } ================================================ FILE: src/Queue/VaporConnector.php ================================================ getDefaultConfiguration($config); if ($config['key'] && $config['secret']) { $config['credentials'] = Arr::only($config, ['key', 'secret', 'token']); } return new VaporQueue( new SqsClient($config), $config['queue'], $config['prefix'] ?? '', $config['suffix'] ?? '', $config['after_commit'] ?? null ); } /** * Get the default configuration for SQS. * * @param array $config * @return array */ protected function getDefaultConfiguration(array $config) { return array_merge([ 'version' => 'latest', 'http' => [ 'timeout' => 60, 'connect_timeout' => 60, ], ], $config); } } ================================================ FILE: src/Queue/VaporJob.php ================================================ payload()['attempts'] ?? 0) + 1, $this->container->make(JobAttempts::class)->get($this) ); } /** * Delete the job from the queue. * * @return void */ public function delete() { parent::delete(); $this->container ->make(JobAttempts::class) ->forget($this); } /** * Release the job back into the queue. * * @param int $delay * @return void */ public function release($delay = 0) { $this->released = true; $payload = $this->payload(); $payload['attempts'] = $this->attempts(); $this->sqs->deleteMessage([ 'QueueUrl' => $this->queue, 'ReceiptHandle' => $this->job['ReceiptHandle'], ]); $jobId = $this->sqs->sendMessage([ 'QueueUrl' => $this->queue, 'MessageBody' => json_encode($payload), 'DelaySeconds' => $this->secondsUntil($delay), ])->get('MessageId'); $this->container ->make(JobAttempts::class) ->transfer($this, $jobId); } } ================================================ FILE: src/Queue/VaporQueue.php ================================================ sqs->receiveMessage([ 'QueueUrl' => $queue = $this->getQueue($queue), 'AttributeNames' => ['ApproximateReceiveCount'], ]); if (! is_null($response['Messages']) && count($response['Messages']) > 0) { return tap(new VaporJob( $this->container, $this->sqs, $response['Messages'][0], $this->connectionName, $queue ), function ($job) { $this->container ->make(JobAttempts::class) ->increment($job); }); } } /** * Create a payload string from the given job and data. * * @param string $job * @param string $queue * @param mixed $data * @return array */ protected function createPayloadArray($job, $queue, $data = '') { return array_merge(parent::createPayloadArray($job, $queue, $data), [ 'attempts' => 0, ]); } } ================================================ FILE: src/Queue/VaporWorker.php ================================================ forgetScopedInstances(); pcntl_async_signals(true); pcntl_signal(SIGALRM, function () use ($job) { throw new VaporJobTimedOutException($job->resolveName()); }); pcntl_alarm( max($this->timeoutForJob($job, $options), 0) ); app(JobAttempts::class)->increment($job); $this->runJob($job, $connectionName, $options); pcntl_alarm(0); } } ================================================ FILE: src/Runtime/ArrayLambdaResponse.php ================================================ response = $response; } /** * Convert the response to API Gateway's supported format. * * @return array */ public function toApiGatewayFormat() { return $this->response; } } ================================================ FILE: src/Runtime/CliHandlerFactory.php ================================================ job ?? null; return $messageId && $job ? new QueueHandler : new CliHandler; } /** * Set a custom handler factory callback. * * @param callable $callback * @return void */ public static function createHandlerUsing(callable $callback) { static::$customHandlerFactory = $callback; } /** * Reset the handler factory to its default behavior. * * @return void */ public static function createHandlersNormally() { static::$customHandlerFactory = null; } } ================================================ FILE: src/Runtime/Environment.php ================================================ app = $app; $this->environment = $_ENV['VAPOR_ENV'] ?? $_ENV['APP_ENV'] ?? 'production'; $this->environmentFile = '.env.'.$this->environment; $this->encryptedFile = '.env.'.$this->environment.'.encrypted'; } /** * Decrypt the environment file and load it into the runtime. * * @return void */ public static function decrypt($app) { (new static($app))->decryptEnvironment(); } /** * Decrypt the environment file and load it into the runtime. * * @return void */ public function decryptEnvironment() { try { if (! $this->canBeDecrypted()) { return; } $this->copyEncryptedFile(); $this->decryptFile(); $this->loadEnvironment(); } catch (Throwable $e) { function_exists('__vapor_debug') && __vapor_debug($e->getMessage()); } } /** * Determine if it is possible to decrypt the environment file. * * @return bool */ public function canBeDecrypted() { if (! isset($_ENV['LARAVEL_ENV_ENCRYPTION_KEY'])) { return false; } if (version_compare($this->app->version(), '9.37.0', '<')) { function_exists('__vapor_debug') && __vapor_debug('Decrypt command not available.'); return false; } if (! file_exists($this->app->basePath($this->encryptedFile))) { function_exists('__vapor_debug') && __vapor_debug('Encrypted environment file not found.'); return false; } return true; } /** * Copy the encrypted environment file to the writable path. * * @return void */ public function copyEncryptedFile() { copy( $this->app->basePath($this->encryptedFile), $this->writePath.DIRECTORY_SEPARATOR.$this->encryptedFile ); } /** * Decrypt the environment file. * * @return void */ public function decryptFile() { function_exists('__vapor_debug') && __vapor_debug('Decrypting environment variables.'); $this->console()->call('env:decrypt', ['--env' => $this->environment, '--path' => $this->writePath]); } /** * Load the decrypted environment file. * * @return void */ public function loadEnvironment() { function_exists('__vapor_debug') && __vapor_debug('Loading decrypted environment variables.'); Dotenv::createMutable($this->writePath, $this->environmentFile)->load(); } /** * Get the console kernel implementation. * * @return \Illuminate\Contracts\Console\Kernel */ public function console() { if (! $this->console) { $this->console = $this->app->make(Kernel::class); } return $this->console; } } ================================================ FILE: src/Runtime/Fpm/ActsAsFastCgiDataProvider.php ================================================ serverVariables['REQUEST_METHOD']; } /** * {@inheritdoc} */ public function getScriptFilename(): string { return $this->serverVariables['SCRIPT_FILENAME']; } /** * {@inheritdoc} */ public function getServerSoftware(): string { return 'vapor'; } /** * {@inheritdoc} */ public function getRemoteAddress(): string { return $this->serverVariables['REMOTE_ADDR']; } /** * {@inheritdoc} */ public function getRemotePort(): int { return $this->serverVariables['SERVER_PORT']; } /** * {@inheritdoc} */ public function getServerAddress(): string { return $this->serverVariables['SERVER_ADDR']; } /** * {@inheritdoc} */ public function getServerPort(): int { return $this->serverVariables['SERVER_PORT']; } /** * {@inheritdoc} */ public function getServerName(): string { return $this->serverVariables['SERVER_NAME']; } /** * {@inheritdoc} */ public function getServerProtocol(): string { return $this->serverVariables['SERVER_PROTOCOL']; } /** * {@inheritdoc} */ public function getContentType(): string { return $this->serverVariables['CONTENT_TYPE']; } /** * {@inheritdoc} */ public function getContentLength(): int { $contentLength = $this->serverVariables['CONTENT_LENGTH'] ?: 0; return is_numeric($contentLength) ? (int) $contentLength : 0; } /** * {@inheritdoc} */ public function getContent(): string { return $this->body; } /** * {@inheritdoc} */ public function getCustomVars(): array { return $this->serverVariables; } /** * {@inheritdoc} */ public function getParams(): array { return $this->serverVariables; } /** * {@inheritdoc} */ public function getRequestUri(): string { return $this->serverVariables['PATH_INFO']; } /** * {@inheritdoc} */ public function getResponseCallbacks(): array { return []; } /** * {@inheritdoc} */ public function getFailureCallbacks(): array { return []; } /** * {@inheritdoc} */ public function getPassThroughCallbacks(): array { return []; } } ================================================ FILE: src/Runtime/Fpm/Fpm.php ================================================ client = $client; $this->handler = $handler; $this->serverVariables = $serverVariables; $this->socketConnection = $socketConnection; } /** * Boot FPM with the given handler. * * @param string $handler * @return static */ public static function boot($handler, array $serverVariables = []) { if (file_exists(static::SOCKET)) { @unlink(static::SOCKET); } $socketConnection = new UnixDomainSocket(self::SOCKET, 1000, 900000); return static::$instance = tap(new static(new Client, $socketConnection, $handler, $serverVariables), function ($fpm) { $fpm->start(); }); } /** * Resolve the static FPM instance. * * @return static */ public static function resolve() { return static::$instance; } /** * Start the PHP-FPM process. */ public function start() { if ($this->isReady()) { $this->killExistingFpm(); } function_exists('__vapor_debug') && __vapor_debug('Ensuring ready to start FPM'); $this->ensureReadyToStart(); $this->fpm = new Process([ 'php-fpm', '--nodaemonize', '--force-stderr', '--fpm-config', self::CONFIG, ]); function_exists('__vapor_debug') && __vapor_debug('Starting FPM Process...'); $this->fpm->disableOutput() ->setTimeout(null) ->start(function ($type, $output) { fwrite(STDERR, $output.PHP_EOL); }); $this->ensureFpmHasStarted(); } /** * Ensure that the proper configuration is in place to start FPM. * * @return void */ protected function ensureReadyToStart() { if (! is_dir(dirname(self::SOCKET))) { mkdir(dirname(self::SOCKET)); } if (! file_exists(self::CONFIG)) { file_put_contents( self::CONFIG, file_get_contents(__DIR__.'/../../../stubs/php-fpm.conf') ); } } /** * Proxy the request to PHP-FPM and return its response. * * @param \Laravel\Vapor\Runtime\Fpm\FpmRequest $request * @return \Laravel\Vapor\Runtime\Fpm\FpmResponse */ public function handle($request) { return (new FpmApplication($this->client, $this->socketConnection)) ->handle($request); } /** * Wait until the FPM process is ready to receive requests. * * @return void */ protected function ensureFpmHasStarted() { $elapsed = 0; while (! $this->isReady()) { usleep(5000); $elapsed += 5000; if ($elapsed > ($fiveSeconds = 5000000)) { throw new Exception('Timed out waiting for FPM to start: '.self::SOCKET); } if (! $this->fpm->isRunning()) { throw new Exception('PHP-FPM was unable to start.'); } } } /** * Determine is the FPM process is ready to receive requests. * * @return bool */ protected function isReady() { clearstatcache(false, self::SOCKET); return file_exists(self::SOCKET); } /** * Ensure that the FPM process is still running. * * @return void * * @throws \Exception */ public function ensureRunning() { try { if (! $this->fpm || ! $this->fpm->isRunning()) { throw new Exception('PHP-FPM has stopped unexpectedly.'); } } catch (Throwable $e) { function_exists('__vapor_debug') && __vapor_debug($e->getMessage()); exit(1); } } /** * Stop the FPM process. * * @return void */ public function stop() { if ($this->fpm && $this->fpm->isRunning()) { $this->fpm->stop(); } } /** * Kill any existing FPM processes on the system. * * @return void */ protected function killExistingFpm() { function_exists('__vapor_debug') && __vapor_debug('Killing existing FPM'); if (! file_exists(static::PID_FILE)) { return unlink(static::SOCKET); } $pid = (int) file_get_contents(static::PID_FILE); if (posix_getpgid($pid) === false) { return $this->removeFpmProcessFiles(); } $result = posix_kill($pid, SIGTERM); if ($result === false) { return $this->removeFpmProcessFiles(); } $this->waitUntilStopped($pid); $this->removeFpmProcessFiles(); } /** * Remove FPM's process related files. * * @return void */ protected function removeFpmProcessFiles() { unlink(static::SOCKET); unlink(static::PID_FILE); } /** * Wait until the given process is stopped. * * @param int $pid * @return void */ protected function waitUntilStopped($pid) { $elapsed = 0; while (posix_getpgid($pid) !== false) { usleep(5000); $elapsed += 5000; if ($elapsed > 1000000) { throw new Exception('Process did not stop within the given threshold.'); } } } /** * Get the underlying process. * * @return \Symfony\Component\Process\Process */ public function process() { return $this->fpm; } /** * Get the handler. * * @return string */ public function handler() { return $this->handler; } /** * Get the server variables. * * @return array */ public function serverVariables() { return $this->serverVariables; } /** * Handle the destruction of the class. * * @return void */ public function __destruct() { $this->stop(); } } ================================================ FILE: src/Runtime/Fpm/FpmApplication.php ================================================ client = $client; $this->socketConnection = $socketConnection; } /** * Handle the given FPM request. * * @param \Laravel\Vapor\Runtime\Fpm\FpmRequest $request * @return \Laravel\Vapor\Runtime\Fpm\FpmResponse */ public function handle(FpmRequest $request) { return new FpmResponse( $this->client->sendRequest($this->socketConnection, $request) ); } } ================================================ FILE: src/Runtime/Fpm/FpmHttpHandlerFactory.php ================================================ getOutput()); parent::__construct( $response->getBody(), $headers, $this->prepareStatus($headers) ); } /** * Prepare the status code of the response. * * @return int */ protected function prepareStatus(array $headers) { $headers = array_change_key_case($headers, CASE_LOWER); return isset($headers['status'][0]) ? (int) explode(' ', $headers['status'][0])[0] : 200; } } ================================================ FILE: src/Runtime/Fpm/FpmResponseHeaders.php ================================================ &1', $_ENV['LAMBDA_TASK_ROOT'], trim($event['cli'] ?? 'vapor:handle '.base64_encode(json_encode($event))) ) )->setTimeout(null); $process->run(function ($type, $line) use (&$output) { if (! Str::containsAll($line, ['{"message":', '"level":'])) { $output .= $line; } else { echo $line.PHP_EOL; } }); echo $output = json_encode([ 'output' => $output, 'context' => [ 'command' => $command, 'aws_request_id' => $_ENV['AWS_REQUEST_ID'] ?? null, ], ]); return new ArrayLambdaResponse(tap([ 'requestId' => $_ENV['AWS_REQUEST_ID'] ?? null, 'logGroup' => $_ENV['AWS_LAMBDA_LOG_GROUP_NAME'] ?? null, 'logStream' => $_ENV['AWS_LAMBDA_LOG_STREAM_NAME'] ?? null, 'statusCode' => $process->getExitCode(), 'output' => base64_encode($output), ], function ($response) use ($event) { $this->ping($event['callback'] ?? null, $response); })); } /** * Ping the given callback URL. * * @param string $callback * @param array $response * @return void */ protected function ping($callback, $response) { if (! isset($callback)) { return; } try { (new Client)->post($callback, ['json' => $response]); } catch (Throwable $e) { // } } } ================================================ FILE: src/Runtime/Handlers/FpmHandler.php ================================================ response( Fpm::resolve()->handle($this->request($event)) ); } /** * Create a new fpm request from the incoming event. * * @param array $event * @return \Laravel\Vapor\Runtime\Fpm\FpmRequest */ public function request($event) { return FpmRequest::fromLambdaEvent( $event, $this->serverVariables(), Fpm::resolve()->handler() ); } /** * Covert a response to Lambda-ready response. * * @param \Laravel\Vapor\Runtime\Response $response * @return \Laravel\Vapor\Runtime\LambdaResponse */ public function response($response) { return new LambdaResponse( $response->status, $response->headers, $response->body ); } /** * Get the server variables. * * @return array */ public function serverVariables() { return array_merge(Fpm::resolve()->serverVariables(), array_filter([ 'AWS_REQUEST_ID' => $_ENV['AWS_REQUEST_ID'] ?? null, ])); } } ================================================ FILE: src/Runtime/Handlers/LoadBalancedFpmHandler.php ================================================ status, $response->headers, $response->body ); } } ================================================ FILE: src/Runtime/Handlers/LoadBalancedOctaneHandler.php ================================================ status, $response->headers, $response->body ); } } ================================================ FILE: src/Runtime/Handlers/OctaneHandler.php ================================================ request($event); return $this->response( Octane::handle($request) ); } /** * Create a new Octane request from the incoming event. * * @param array $event * @return \Laravel\Octane\RequestContext */ protected function request($event) { return OctaneRequestContextFactory::fromEvent($event, $this->serverVariables()); } /** * Covert a response to Lambda-ready response. * * @param \Laravel\Vapor\Runtime\Response $response * @return \Laravel\Vapor\Runtime\LambdaResponse */ protected function response($response) { return new LambdaResponse( $response->status, $response->headers, $response->body ); } /** * Get the server variables. * * @return array */ public function serverVariables() { return [ 'AWS_REQUEST_ID' => $_ENV['AWS_REQUEST_ID'] ?? null, ]; } } ================================================ FILE: src/Runtime/Handlers/PayloadFormatVersion2FpmHandler.php ================================================ status, $response->headers, $response->body ); } } ================================================ FILE: src/Runtime/Handlers/PayloadFormatVersion2OctaneHandler.php ================================================ status, $response->headers, $response->body ); } } ================================================ FILE: src/Runtime/Handlers/QueueHandler.php ================================================ useStoragePath(StorageDirectories::PATH); $consoleKernel = static::$app->make(Kernel::class); static::$app->bind(LambdaEvent::class, function () use ($event) { return new LambdaEvent($event); }); $consoleInput = new StringInput( 'vapor:work '.$commandOptions.' --no-interaction' ); $status = $consoleKernel->handle( $consoleInput, $output = new BufferedOutput ); $consoleKernel->terminate($consoleInput, $status); return new ArrayLambdaResponse([ 'requestId' => $_ENV['AWS_REQUEST_ID'] ?? null, 'logGroup' => $_ENV['AWS_LAMBDA_LOG_GROUP_NAME'] ?? null, 'logStream' => $_ENV['AWS_LAMBDA_LOG_STREAM_NAME'] ?? null, 'statusCode' => $status, 'output' => base64_encode($output->fetch()), ]); } finally { unset(static::$app[LambdaEvent::class]); $this->terminate(); } } /** * Terminate any relevant application services. * * @return void */ protected function terminate() { if (static::$app->resolved('db') && ($_ENV['VAPOR_QUEUE_DATABASE_SESSION_PERSIST'] ?? false) !== 'true') { collect(static::$app->make('db')->getConnections())->each->disconnect(); } } } ================================================ FILE: src/Runtime/Handlers/UnknownEventHandler.php ================================================ $event, ]); return new ArrayLambdaResponse([ 'output' => 'Unknown event type.', ]); } } ================================================ FILE: src/Runtime/Handlers/WarmerHandler.php ================================================ buildPromises($this->lambdaClient(), $event) )->wait(); } catch (Throwable $e) { Logger::error($e->getMessage(), ['exception' => $e]); } return new ArrayLambdaResponse([ 'output' => 'Warmer event handled.', ]); } /** * Build the array of warmer invocation promises. * * @return array */ protected function buildPromises(LambdaClient $lambda, array $event) { return collect(range(1, $event['concurrency'] - 1)) ->mapWithKeys(function ($i) use ($lambda, $event) { return ['warmer-'.$i => $lambda->invokeAsync([ 'FunctionName' => $event['functionName'], 'Qualifier' => $event['functionAlias'], 'LogType' => 'None', 'Payload' => json_encode(['vaporWarmerPing' => true]), ])]; })->all(); } /** * Get the Lambda client instance. * * @return \Aws\Lambda\LambdaClient */ protected function lambdaClient() { return new LambdaClient([ 'region' => $_ENV['AWS_DEFAULT_REGION'], 'version' => 'latest', 'http' => [ 'timeout' => 5, 'connect_timeout' => 5, ], ]); } } ================================================ FILE: src/Runtime/Handlers/WarmerPingHandler.php ================================================ 'Warmer ping handled.', ]); } } ================================================ FILE: src/Runtime/Http/Middleware/EnsureBinaryEncoding.php ================================================ headers->set('X-Vapor-Base64-Encode', 'True'); } return $response; } /** * Determine if base64 encoding is required for the response. * * @param \Illuminate\Http\Response $response * @return bool */ public static function isBase64EncodingRequired(Response $response): bool { $contentType = strtolower($response->headers->get('Content-Type', 'text/html')); if (Str::startsWith($contentType, 'text/') || Str::contains($contentType, ['xml', 'json'])) { return false; } return true; } } ================================================ FILE: src/Runtime/Http/Middleware/EnsureOnNakedDomain.php ================================================ getHttpHost() === $_ENV['APP_VANITY_URL']) { return $next($request); } if (config('vapor.redirect_to_root') === true && strpos($request->getHost(), 'www.') === 0) { return new RedirectResponse(Str::replaceFirst( 'www.', '', $request->fullUrl() ), 301); } if (config('vapor.redirect_to_root') === false) { $url = parse_url(config('app.url')); $nakedHost = preg_replace('#^www\.(.+\.)#i', '$1', $url[ 'host' ]); if ($request->getHost() === $nakedHost) { return new RedirectResponse(str_replace( $request->getScheme().'://', $request->getScheme().'://www.', $request->fullUrl() ), 301); } } return $next($request); } } ================================================ FILE: src/Runtime/Http/Middleware/EnsureVanityUrlIsNotIndexed.php ================================================ getHttpHost() === $_ENV['APP_VANITY_URL']) { $response->headers->set('X-Robots-Tag', 'noindex, nofollow', true); } return $response; } } ================================================ FILE: src/Runtime/Http/Middleware/RedirectStaticAssets.php ================================================ path() === 'favicon.ico') { return new RedirectResponse($_ENV['ASSET_URL'].'/favicon.ico', 302, [ 'Cache-Control' => 'public, max-age=3600', ]); } if (config('vapor.redirect_robots_txt') && $request->path() === 'robots.txt') { return new RedirectResponse($_ENV['ASSET_URL'].'/robots.txt', 302, [ 'Cache-Control' => 'public, max-age=3600', ]); } return $next($request); } } ================================================ FILE: src/Runtime/HttpKernel.php ================================================ app = $app; } /** * Handle the incoming HTTP request. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function handle(Request $request) { $this->app->useStoragePath(StorageDirectories::PATH); if (static::shouldSendMaintenanceModeResponse($request)) { if ( isset($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']) && $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] == $request->path() ) { $response = static::bypassResponse($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']); $this->app->terminate(); } elseif ( isset($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']) && static::hasValidBypassCookie($request, $_ENV['VAPOR_MAINTENANCE_MODE_SECRET']) ) { $response = $this->sendRequest($request); } else { if ($request->wantsJson() && file_exists($_ENV['LAMBDA_TASK_ROOT'].'/503.json')) { $response = JsonResponse::fromJsonString( file_get_contents($_ENV['LAMBDA_TASK_ROOT'].'/503.json'), 503 ); } else { $response = new Response( file_get_contents($_ENV['LAMBDA_TASK_ROOT'].'/503.html'), 503 ); } $this->app->terminate(); } } else { $response = $this->sendRequest($request); } return $response; } /** * Determine if a maintenance mode response should be sent. * * @param \Illuminate\Http\Request $request * @return bool */ public static function shouldSendMaintenanceModeResponse(Request $request) { return isset($_ENV['VAPOR_MAINTENANCE_MODE']) && $_ENV['VAPOR_MAINTENANCE_MODE'] === 'true' && 'https://'.$request->getHttpHost() !== $_ENV['APP_VANITY_URL']; } /** * Determine if the incoming request has a maintenance mode bypass cookie. * * @param \Illuminate\Http\Request $request * @param string $secret * @return bool */ public static function hasValidBypassCookie($request, $secret) { return $request->cookie('laravel_maintenance') && MaintenanceModeBypassCookie::isValid( $request->cookie('laravel_maintenance'), $secret ); } /** * Redirect the user back to the root of the application with a maintenance mode bypass cookie. * * @param string $secret * @return \Illuminate\Http\RedirectResponse */ public static function bypassResponse(string $secret) { $response = new RedirectResponse('/'); $expiresAt = Carbon::now()->addHours(12); $path = isset($_ENV['VAPOR_MAINTENANCE_MODE_COOKIE_PATH']) ? $_ENV['VAPOR_MAINTENANCE_MODE_COOKIE_PATH'] : '/'; $domain = isset($_ENV['VAPOR_MAINTENANCE_MODE_COOKIE_DOMAIN']) ? $_ENV['VAPOR_MAINTENANCE_MODE_COOKIE_DOMAIN'] : null; $cookie = new Cookie('laravel_maintenance', base64_encode(json_encode([ 'expires_at' => $expiresAt->getTimestamp(), 'mac' => hash_hmac('sha256', $expiresAt->getTimestamp(), $secret), ])), $expiresAt, $path, $domain); $response->headers->setCookie($cookie); return $response; } /** * Resolve the HTTP kernel for the request. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Contracts\Http\Kernel */ protected function resolveKernel(Request $request) { return tap($this->app->make(HttpKernelContract::class), function ($kernel) use ($request) { $this->app->instance('request', $request); Facade::clearResolvedInstance('request'); $kernel->bootstrap(); }); } /** * Send the request to the kernel. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ protected function sendRequest(Request $request) { $kernel = $this->resolveKernel($request); $response = (new Pipeline)->send($request) ->through([ new EnsureOnNakedDomain, new RedirectStaticAssets, new EnsureVanityUrlIsNotIndexed, new EnsureBinaryEncoding(), ])->then(function ($request) use ($kernel) { return $kernel->handle($request); }); $kernel->terminate($request, $response); return $response; } } ================================================ FILE: src/Runtime/LambdaContainer.php ================================================ = $invocationLimit) { if (interface_exists(\Laravel\Octane\Contracts\Client::class)) { Octane::terminate(); } function_exists('__vapor_debug') && __vapor_debug('Killing container. Container has processed '.$invocationLimit.' invocations. ('.$_ENV['AWS_REQUEST_ID'].')'); exit(0); } } } ================================================ FILE: src/Runtime/LambdaInvocation.php ================================================ body = $body; $this->status = $status; $this->headers = $headers; } /** * Convert the response to API Gateway's supported format. * * @return array */ public function toApiGatewayFormat() { $requiresEncoding = isset($this->headers['x-vapor-base64-encode'][0]); return [ 'isBase64Encoded' => $requiresEncoding, 'statusCode' => $this->status, 'headers' => empty($this->headers) ? new stdClass : $this->prepareHeaders($this->headers), 'body' => $requiresEncoding ? base64_encode($this->body) : $this->body, ]; } /** * Prepare the given response headers for API Gateway. * * @param array $responseHeaders * @return array */ protected function prepareHeaders(array $responseHeaders) { $headers = []; foreach ($responseHeaders as $name => $values) { $name = $this->normalizeHeaderName($name); if ($name == 'Set-Cookie') { $headers = array_merge($headers, $this->buildCookieHeaders($values)); continue; } foreach ($values as $value) { $headers[$name] = $value; } } if (! isset($headers['Content-Type'])) { $headers['Content-Type'] = 'text/html'; } return $headers; } /** * Build the Set-Cookie header names using binary casing. * * @param array $values * @return array */ protected function buildCookieHeaders(array $values) { $headers = []; foreach ($values as $index => $value) { $headers[$this->cookiePermutation($index)] = $value; } return $headers; } /** * Calculate the permutation of Set-Cookie for the current index. * * @param int $index * @return string */ protected function cookiePermutation($index) { // Hard-coded to support up to 18 cookies for now... switch ($index) { case 0: return 'set-cookie'; case 1: return 'Set-cookie'; case 2: return 'sEt-cookie'; case 3: return 'seT-cookie'; case 4: return 'set-Cookie'; case 5: return 'set-cOokie'; case 6: return 'set-coOkie'; case 7: return 'set-cooKie'; case 8: return 'set-cookIe'; case 9: return 'set-cookiE'; case 10: return 'SEt-cookie'; case 11: return 'SET-cookie'; case 12: return 'SEt-Cookie'; case 13: return 'SEt-cOokie'; case 14: return 'SEt-coOkie'; case 15: return 'SEt-cooKie'; case 16: return 'SEt-cookIe'; case 17: return 'SEt-cookiE'; default: return 'Set-Cookie'; } } /** * Normalize the given header name into studly-case. * * @param string $name * @return string */ protected function normalizeHeaderName($name) { return str_replace(' ', '-', ucwords(str_replace('-', ' ', $name))); } } ================================================ FILE: src/Runtime/LambdaRuntime.php ================================================ apiUrl = $apiUrl; } /** * Create new Lambda runtime from the API environment variable. * * @return static */ public static function fromEnvironmentVariable() { return new static(getenv('AWS_LAMBDA_RUNTIME_API')); } /** * Handle the next Lambda invocation. * * @return void */ public function nextInvocation(callable $callback) { [$invocationId, $event] = LambdaInvocation::next($this->apiUrl); $_ENV['AWS_REQUEST_ID'] = $invocationId; try { $this->notifyLambdaOfResponse($invocationId, $callback($invocationId, $event)); } catch (Throwable $error) { $this->handleException($invocationId, $error); exit(1); } } /** * Inform Lambda of an invocation failure. * * @return void */ public function handleException(string $invocationId, Throwable $error) { $errorMessage = $error instanceof Exception ? 'Uncaught '.get_class($error).': '.$error->getMessage() : $error->getMessage(); function_exists('__vapor_debug') && __vapor_debug(sprintf( "Fatal error: %s in %s:%d\nStack trace:\n%s", $errorMessage, $error->getFile(), $error->getLine(), $error->getTraceAsString() )); $this->notifyLambdaOfError($invocationId, [ 'errorMessage' => $error->getMessage(), 'errorType' => get_class($error), 'stackTrace' => explode(PHP_EOL, $error->getTraceAsString()), ]); } } ================================================ FILE: src/Runtime/LoadBalancedLambdaResponse.php ================================================ headers['x-vapor-base64-encode'][0]); return [ 'isBase64Encoded' => $requiresEncoding, 'statusCode' => $this->status, 'statusDescription' => $this->status.' '.$this->statusText($this->status), 'multiValueHeaders' => empty($this->headers) ? [] : $this->prepareHeaders($this->headers), 'body' => $requiresEncoding ? base64_encode($this->body) : $this->body, ]; } /** * Get the status text for the given status code. * * @param int $status * @return string */ public function statusText($status) { $statusTexts = SymfonyResponse::$statusTexts; $statusTexts[419] = 'Authentication Timeout'; return $statusTexts[$status]; } /** * Prepare the given response headers. * * @param array $responseHeaders * @return array */ protected function prepareHeaders(array $responseHeaders) { $headers = []; foreach ($responseHeaders as $name => $values) { $headers[static::normalizeHeaderName($name)] = static::normalizeHeaderValues($values); } if (! isset($headers['Content-Type']) || empty($headers['Content-Type'])) { $headers['Content-Type'] = ['text/html']; } return $headers; } /** * Normalize the given header values into strings. * * @param array $values * @return array */ protected function normalizeHeaderValues($values) { return array_map(function ($value) { return (string) $value; }, $values); } } ================================================ FILE: src/Runtime/Logger.php ================================================ info($message, $context); } /** * Write error information to the log. * * @param string $message * @param array $context * @return void */ public static function error($message, array $context = []) { static::ensureLoggerIsAvailable(); static::$logger->error($message, $context); } /** * Ensure the logger has been instantiated. * * @return void */ protected static function ensureLoggerIsAvailable() { if (isset(static::$logger)) { return; } static::$logger = new MonologLogger('vapor', [ (new StreamHandler('php://stderr'))->setFormatter(new JsonFormatter), ]); } } ================================================ FILE: src/Runtime/NotifiesLambda.php ================================================ lambdaRequest( "http://{$this->apiUrl}/2018-06-01/runtime/invocation/{$invocationId}/response", $data ); } /** * Send the error response data to Lambda. * * @param string $invocationId * @param mixed $data * @return void */ protected function notifyLambdaOfError($invocationId, $data) { return $this->lambdaRequest( "http://{$this->apiUrl}/2018-06-01/runtime/invocation/{$invocationId}/error", $data ); } /** * Send the given data to the given URL as JSON. * * @param string $url * @param mixed $data * @return void */ protected function lambdaRequest($url, $data) { $json = json_encode($data); if ($json === false) { throw new Exception('Error encoding runtime JSON response: '.json_last_error_msg()); } $handler = curl_init($url); curl_setopt($handler, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($handler, CURLOPT_RETURNTRANSFER, true); curl_setopt($handler, CURLOPT_POSTFIELDS, $json); curl_setopt($handler, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Content-Length: '.strlen($json), ]); curl_exec($handler); if (curl_error($handler)) { $errorMessage = curl_error($handler); throw new Exception('Error calling the runtime API: '.$errorMessage); } curl_setopt($handler, CURLOPT_HEADERFUNCTION, null); curl_setopt($handler, CURLOPT_READFUNCTION, null); curl_setopt($handler, CURLOPT_WRITEFUNCTION, null); curl_setopt($handler, CURLOPT_PROGRESSFUNCTION, null); curl_reset($handler); if (PHP_VERSION_ID >= 80000) { unset($handler); } else { curl_close($handler); } } } ================================================ FILE: src/Runtime/Octane/Octane.php ================================================ boot()->onRequestHandled(static::manageDatabaseSessions($databaseSessionPersist, $databaseSessionTtl)); if ($databaseSessionPersist && $databaseSessionTtl > 0) { static::worker()->application()->make('db')->beforeExecuting(function ($query, $bindings, $connection) { if ($connection instanceof MySqlConnection && ! in_array($connection->getName(), static::$databaseSessions)) { static::$databaseSessions[] = $connection->getName(); $connection->unprepared(sprintf( 'SET SESSION wait_timeout=%s', static::DB_SESSION_DEFAULT_TTL )); } }); } } /** * Manage the database sessions. * * @param bool $databaseSessionPersist * @param int $databaseSessionTtl * @return callable */ protected static function manageDatabaseSessions($databaseSessionPersist, $databaseSessionTtl) { return function ($request, $response, $sandbox) use ($databaseSessionPersist, $databaseSessionTtl) { if (! $sandbox->resolved('db') || ($databaseSessionPersist && $databaseSessionTtl == 0)) { return; } $connections = collect($sandbox->make('db')->getConnections()); if (! $databaseSessionPersist) { return $connections->each->disconnect(); } $connections->filter(function ($connection) { $hasSession = in_array($connection->getName(), static::$databaseSessions); if (! $hasSession) { try { $connection->disconnect(); } catch (Throwable $e) { // Likely already disconnected... } } return $hasSession; })->map->getRawPdo()->filter(function ($pdo) { return $pdo instanceof PDO; })->each(function ($pdo) use ($databaseSessionTtl) { try { $pdo->exec(sprintf( 'SET SESSION wait_timeout=%s', $databaseSessionTtl )); } catch (Throwable $e) { // Connection already gone away, safe to ignore... } }); }; } /** * Handle the given Octane request. * * @param \Laravel\Octane\RequestContext $request * @return \Laravel\Vapor\Runtime\Response */ public static function handle($request) { [$request, $context] = (new self)->marshalRequest($request); static::$databaseSessions = []; self::worker()->application()->useStoragePath(StorageDirectories::PATH); if (HttpKernel::shouldSendMaintenanceModeResponse($request)) { if (isset($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']) && $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] == $request->path()) { $response = HttpKernel::bypassResponse($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']); } elseif (isset($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']) && static::hasValidBypassCookie($request, $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'])) { $response = static::sendRequest($request, $context); } elseif ($request->wantsJson() && file_exists($_ENV['LAMBDA_TASK_ROOT'].'/503.json')) { $response = JsonResponse::fromJsonString( file_get_contents($_ENV['LAMBDA_TASK_ROOT'].'/503.json'), 503 ); } else { $response = new \Illuminate\Http\Response( file_get_contents($_ENV['LAMBDA_TASK_ROOT'].'/503.html'), 503 ); } } else { $response = static::sendRequest($request, $context); } $content = $response instanceof BinaryFileResponse ? $response->getFile()->getContent() : $response->getContent(); if ($response instanceof StreamedResponse) { $content = static::captureContent($response); } return tap(new Response( $content, $response->headers->all(), $response->getStatusCode() ), static function () { static::$response = null; }); } /** * Send the request to the worker. * * @param \Illuminate\Http\Request $request * @param \Laravel\Octane\RequestContext $context * @return \Laravel\Octane\OctaneResponse */ protected static function sendRequest($request, $context) { return (new Pipeline)->send($request) ->through([ new EnsureOnNakedDomain, new RedirectStaticAssets, new EnsureVanityUrlIsNotIndexed, new EnsureBinaryEncoding(), ])->then(function ($request) use ($context) { static::$worker->handle($request, $context); return static::$response->response; }); } /** * Determine if the incoming request has a maintenance mode bypass cookie. * * @param \Illuminate\Http\Request $request * @param string $secret * @return bool */ public static function hasValidBypassCookie($request, $secret) { return HttpKernel::hasValidBypassCookie($request, $secret); } /** * Terminates an Octane worker instance, if any. * * @return void */ public static function terminate() { if (static::$worker) { static::$worker->terminate(); static::$worker = null; self::ensureServerSoftware(null); } } /** * Marshal the given Octane request context into an Laravel foundation request. */ public function marshalRequest(RequestContext $context): array { return [ static::toHttpFoundationRequest($context->psr7Request), $context, ]; } /** * Stores the response in the instance. */ public function respond(RequestContext $context, OctaneResponse $response): void { static::$response = $response; } /** * Send an error message to the server. */ public function error(Throwable $e, Application $app, Request $request, RequestContext $context): void { try { static::$response = new OctaneResponse( $app[ExceptionHandler::class]->render($request, $e) ); } catch (Throwable $throwable) { function_exists('__vapor_debug') && __vapor_debug($throwable->getMessage()); function_exists('__vapor_debug') && __vapor_debug($e->getMessage()); static::$response = new OctaneResponse( new \Illuminate\Http\Response('', 500) ); } } /** * Ensures the given software name is set globally. * * @param string|null $software * @return void */ protected static function ensureServerSoftware($software) { $_ENV['SERVER_SOFTWARE'] = $software; $_SERVER['SERVER_SOFTWARE'] = $software; } /** * Get the Octane worker, if any. * * @return \Laravel\Octane\Worker|null */ public static function worker() { return static::$worker; } /** * Capture the content from a streamed response. */ protected static function captureContent(StreamedResponse $response): string { ob_start(); $response->sendContent(); $content = ob_get_contents(); ob_end_clean(); return $content; } } ================================================ FILE: src/Runtime/Octane/OctaneHttpHandlerFactory.php ================================================ serverVariables['REQUEST_METHOD']; $contentType = array_change_key_case($request->headers)['content-type'] ?? null; $serverRequest = new ServerRequest( $request->serverVariables['REQUEST_METHOD'], static::parseUri($request->serverVariables['REQUEST_URI']), $request->headers, $request->body, $request->serverVariables['SERVER_PROTOCOL'], $request->serverVariables ); $serverRequest = $serverRequest->withCookieParams(static::cookies($event, $request->headers)); $serverRequest = $serverRequest->withUploadedFiles(static::uploadedFiles( $method, $contentType, $request->body )); $serverRequest = $serverRequest->withParsedBody(static::parsedBody( $method, $contentType, $request->body )); parse_str($request->serverVariables['QUERY_STRING'], $queryParams); $serverRequest = $serverRequest->withQueryParams($queryParams); return new RequestContext([ 'psr7Request' => $serverRequest, ]); } /** * Get the cookies from the given headers. * * @param array $event * @param array $headers * @return array */ protected static function cookies($event, $headers) { if (isset($event['version']) && $event['version'] === '2.0') { $cookies = $event['cookies'] ?? []; } else { $headers = array_change_key_case($headers); $cookies = isset($headers['cookie']) ? explode('; ', $headers['cookie']) : []; } if (empty($cookies)) { return []; } return Collection::make($cookies)->mapWithKeys(function ($cookie) { $cookie = explode('=', trim($cookie), 2); $key = $cookie[0]; if (! isset($cookie[1])) { return [$key => null]; } return [$key => urldecode($cookie[1])]; })->filter()->all(); } /** * Create a new file instance from the given HTTP request document part. * * @param \Riverline\MultipartParser\Part $part * @return \Psr\Http\Message\UploadedFileInterface */ protected static function createFile($part) { file_put_contents( $path = tempnam(sys_get_temp_dir(), 'vapor_upload_'), $part->getBody() ); return new UploadedFile( $path, filesize($path), UPLOAD_ERR_OK, $part->getFileName(), $part->getMimeType() ); } /** * Parse the files for the given HTTP request body. * * @param string $contentType * @param string $body * @return array */ protected static function parseFiles($contentType, $body) { $document = new Part("Content-Type: $contentType\r\n\r\n".$body); if (! $document->isMultiPart()) { return []; } return Collection::make($document->getParts()) ->filter ->isFile() ->reduce(function ($files, $part) { return Str::contains($name = $part->getName(), '[') ? Arr::setMultiPartArrayValue($files, $name, static::createFile($part)) : SupportArr::set($files, $name, static::createFile($part)); }, []); } /** * Get the uploaded files for the incoming event. * * @param string $method * @param string $contentType * @param string $body * @return array */ protected static function uploadedFiles($method, $contentType, $body) { if (! in_array($method, ['POST', 'PUT']) || is_null($contentType) || static::isUrlEncodedForm($contentType)) { return []; } return static::parseFiles($contentType, $body); } /** * Get the parsed body for the event. * * @param string $method * @param string $contentType * @param string $body * @return array|null */ protected static function parsedBody($method, $contentType, $body) { if (! in_array($method, ['POST', 'PUT']) || is_null($contentType)) { return; } if (static::isUrlEncodedForm($contentType)) { parse_str($body, $parsedBody); return $parsedBody; } return static::parseBody($contentType, $body); } /** * Parse the incoming event's request body. * * @param string $contentType * @param string $body * @return array */ protected static function parseBody($contentType, $body) { $document = new Part("Content-Type: $contentType\r\n\r\n".$body); if (! $document->isMultiPart()) { return; } return Collection::make($document->getParts()) ->reject ->isFile() ->reduce(function ($parsedBody, $part) { return Str::contains($name = $part->getName(), '[') ? Arr::setMultiPartArrayValue($parsedBody, $name, $part->getBody()) : SupportArr::set($parsedBody, $name, $part->getBody()); }, []); } /** * Parse the incoming event's request uri. * * @param string $uri * @return string */ protected static function parseUri($uri) { if (parse_url($uri) === false) { return '/'; } return $uri; } /** * Determine if the given content type represents a URL encoded form. * * @param string $contentType * @return bool */ protected static function isUrlEncodedForm($contentType) { return Str::contains(strtolower($contentType), 'application/x-www-form-urlencoded'); } } ================================================ FILE: src/Runtime/PayloadFormatVersion2LambdaResponse.php ================================================ headers['x-vapor-base64-encode'][0]); return [ 'isBase64Encoded' => $requiresEncoding, 'statusCode' => $this->status, 'cookies' => isset($this->headers['set-cookie']) ? $this->headers['set-cookie'] : [], 'headers' => empty($this->headers) ? new stdClass : $this->prepareHeaders($this->headers), 'body' => $requiresEncoding ? base64_encode($this->body) : $this->body, ]; } /** * Prepare the given response headers for API Gateway. * * @param array $responseHeaders * @return array */ protected function prepareHeaders(array $responseHeaders) { $headers = []; foreach ($responseHeaders as $name => $values) { $name = $this->normalizeHeaderName($name); if ($name == 'Set-Cookie') { continue; } foreach ($values as $value) { $headers[$name] = $value; } } if (! isset($headers['Content-Type'])) { $headers['Content-Type'] = 'text/html'; } return $headers; } } ================================================ FILE: src/Runtime/Request.php ================================================ body = $body; $this->serverVariables = $serverVariables; $this->headers = $headers; } /** * Create a new request from the given Lambda event. * * @param array $event * @param array $serverVariables * @param string|null $handler * @return static */ public static function fromLambdaEvent(array $event, array $serverVariables = [], $handler = null) { [$uri, $queryString] = static::getUriAndQueryString($event); $headers = static::getHeaders($event); $requestBody = static::getRequestBody($event); $serverVariables = array_merge($serverVariables, [ 'GATEWAY_INTERFACE' => 'FastCGI/1.0', 'PATH_INFO' => $event['path'] ?? $event['requestContext']['http']['path'] ?? '/', 'QUERY_STRING' => $queryString, 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_PORT' => $headers['x-forwarded-port'] ?? 80, 'REQUEST_METHOD' => $event['httpMethod'] ?? $event['requestContext']['http']['method'], 'REQUEST_URI' => $uri, 'REQUEST_TIME' => time(), 'REQUEST_TIME_FLOAT' => microtime(true), 'SERVER_ADDR' => '127.0.0.1', 'SERVER_NAME' => $headers['host'] ?? 'localhost', 'SERVER_PORT' => $headers['x-forwarded-port'] ?? 80, 'SERVER_PROTOCOL' => $event['requestContext']['protocol'] ?? $event['requestContext']['http']['protocol'] ?? 'HTTP/1.1', 'SERVER_SOFTWARE' => 'vapor', ]); if ($handler) { $serverVariables['SCRIPT_FILENAME'] = $handler; } if ($timestamp = self::extractRequestTimestamp($event)) { $serverVariables['AWS_API_GATEWAY_REQUEST_TIME'] = $timestamp; } [$headers, $serverVariables] = static::ensureContentTypeIsSet( $event, $headers, $serverVariables ); [$headers, $serverVariables] = static::ensureContentLengthIsSet( $event, $headers, $serverVariables, $requestBody ); $headers = static::ensureSourceIpAddressIsSet( $event, $headers ); foreach ($headers as $header => $value) { $serverVariables['HTTP_'.strtoupper(str_replace('-', '_', $header))] = $value; } return new static($serverVariables, $requestBody, $headers); } /** * Get the URI and query string for the given event. * * @param array $event * @return array */ protected static function getUriAndQueryString(array $event) { $uri = $event['requestContext']['http']['path'] ?? $event['path'] ?? '/'; $queryString = self::getQueryString($event); parse_str($queryString, $queryParameters); return [ empty($queryString) ? $uri : $uri.'?'.$queryString, http_build_query($queryParameters), ]; } /** * Get the query string from the event. * * @param array $event * @return string */ protected static function getQueryString(array $event) { if (isset($event['version']) && $event['version'] === '2.0') { return http_build_query( collect($event['queryStringParameters'] ?? []) ->mapWithKeys(function ($value, $key) { $values = explode(',', $value); return count($values) === 1 ? [$key => $values[0]] : [(substr($key, -2) == '[]' ? substr($key, 0, -2) : $key) => $values]; })->all() ); } if (! isset($event['multiValueQueryStringParameters'])) { return http_build_query( $event['queryStringParameters'] ?? [] ); } return http_build_query( collect($event['multiValueQueryStringParameters'] ?? []) ->mapWithKeys(function ($values, $key) use ($event) { $key = ! isset($event['requestContext']['elb']) ? $key : urldecode($key); return count($values) === 1 ? [$key => $values[0]] : [(substr($key, -2) == '[]' ? substr($key, 0, -2) : $key) => $values]; })->map(function ($values) use ($event) { if (! isset($event['requestContext']['elb'])) { return $values; } return ! is_array($values) ? urldecode($values) : array_map(function ($value) { return urldecode($value); }, $values); })->all() ); } /** * Get the request headers from the event. * * @param array $event * @return array */ protected static function getHeaders(array $event) { if (! isset($event['multiValueHeaders'])) { return array_change_key_case( $event['headers'] ?? [], CASE_LOWER ); } return array_change_key_case( collect($event['multiValueHeaders'] ?? []) ->mapWithKeys(function ($headers, $name) { return [$name => Arr::last($headers)]; })->all(), CASE_LOWER ); } /** * Get the request body from the event. * * @param array $event * @return string */ protected static function getRequestBody(array $event) { $body = $event['body'] ?? ''; return isset($event['isBase64Encoded']) && $event['isBase64Encoded'] ? base64_decode($body) : $body; } /** * Ensure the request headers / server variables contain a content type. * * @param array $event * @param array $headers * @param array $serverVariables * @return array */ protected static function ensureContentTypeIsSet(array $event, array $headers, array $serverVariables) { if ((! isset($headers['content-type']) && isset($event['httpMethod']) && (strtoupper($event['httpMethod']) === 'POST')) || (! isset($headers['content-type']) && isset($event['requestContext']['http']['method']) && (strtoupper($event['requestContext']['http']['method']) === 'POST'))) { $headers['content-type'] = 'application/x-www-form-urlencoded'; } if (isset($headers['content-type'])) { $serverVariables['CONTENT_TYPE'] = $headers['content-type']; } return [$headers, $serverVariables]; } /** * Ensure the request headers / server variables contain a content length. * * @param array $event * @param array $headers * @param array $serverVariables * @param string $requestBody * @return array */ protected static function ensureContentLengthIsSet(array $event, array $headers, array $serverVariables, $requestBody) { if ((! isset($headers['content-length']) && isset($event['httpMethod']) && ! in_array(strtoupper($event['httpMethod']), ['TRACE'])) || (! isset($headers['content-length']) && isset($event['requestContext']['http']['method']) && ! in_array(strtoupper($event['requestContext']['http']['method']), ['TRACE']))) { $headers['content-length'] = strlen($requestBody); } if (isset($headers['content-length'])) { $serverVariables['CONTENT_LENGTH'] = $headers['content-length']; } return [$headers, $serverVariables]; } /** * Ensure the request headers contain a source IP address. * * @param array $event * @param array $headers * @return array */ protected static function ensureSourceIpAddressIsSet(array $event, array $headers) { if (isset($event['requestContext']['identity']['sourceIp'])) { $headers['x-vapor-source-ip'] = $event['requestContext']['identity']['sourceIp']; } if (isset($event['requestContext']['http']['sourceIp'])) { $headers['x-vapor-source-ip'] = $event['requestContext']['http']['sourceIp']; } return $headers; } /** * Extracts the time (millisecond epoch) when the request was received by the API Gateway. * * @param array $event * @return int|null */ protected static function extractRequestTimestamp(array $event) { if (! isset($event['requestContext'])) { return null; } return $event['requestContext']['requestTimeEpoch'] // REST API (V1) ?? $event['requestContext']['timeEpoch'] // HTTP API (V2) ?? null; } } ================================================ FILE: src/Runtime/Response.php ================================================ body = $body; $this->status = $status; $this->headers = $this->prepareHeaders($headers); } /** * Prepare the given response headers. * * @param array $headers * @return array */ protected function prepareHeaders(array $headers) { $headers = array_change_key_case($headers, CASE_LOWER); unset($headers['status']); return $headers; } } ================================================ FILE: src/Runtime/Secrets.php ================================================ $value) { $_ENV[$key] = $value; $_SERVER[$key] = $value; } }); } /** * Get all of the secret parameters (AWS SSM) at the given path. * * @param string $path * @return array */ public static function all($path, array $parameters = []) { if (empty($parameters)) { return []; } $ssm = SsmClient::factory([ 'region' => $_ENV['AWS_DEFAULT_REGION'], 'version' => 'latest', ]); return collect($parameters)->chunk(10)->reduce(function ($carry, $parameters) use ($ssm, $path) { $ssmResponse = $ssm->getParameters([ 'Names' => collect($parameters)->map(function ($version, $parameter) use ($path) { return $path.'/'.$parameter.':'.$version; })->values()->all(), 'WithDecryption' => true, ]); return array_merge($carry, static::parseSecrets( $ssmResponse['Parameters'] ?? [] )); }, []); } /** * Parse the secret names and values into an array. * * @return array */ protected static function parseSecrets(array $secrets) { return collect($secrets)->mapWithKeys(function ($secret) { $segments = explode('/', $secret['Name']); return [$segments[count($segments) - 1] => $secret['Value']]; })->all(); } } ================================================ FILE: src/Runtime/StorageDirectories.php ================================================ ensureRoutesAreDefined(); $this->registerOctaneCommands(); if (($_ENV['VAPOR_SERVERLESS_DB'] ?? null) === 'true') { Schema::defaultStringLength(191); } if ($this->app->resolved('queue')) { call_user_func($this->queueExtender()); } else { $this->app->afterResolving( 'queue', $this->queueExtender() ); } } /** * Get the queue extension callback. * * @return \Closure */ protected function queueExtender() { return function () { Queue::extend('sqs', function () { return new VaporConnector; }); }; } /** * Register the service provider. * * @return void */ public function register() { $this->app->singleton( Contracts\SignedStorageUrlController::class, SignedStorageUrlController::class ); $this->configure(); $this->offerPublishing(); $this->ensureAssetPathsAreConfigured(); $this->ensureRedisIsConfigured(); $this->ensureDynamoDbIsConfigured(); $this->ensureQueueIsConfigured(); $this->ensureSqsIsConfigured(); $this->ensureMixIsConfigured(); $this->configureTrustedProxy(); $this->registerMiddleware(); $this->registerCommands(); } /** * Setup the configuration for Horizon. * * @return void */ protected function configure() { $this->mergeConfigFrom( __DIR__.'/../config/vapor.php', 'vapor' ); } /** * Setup the resource publishing groups for Horizon. * * @return void */ protected function offerPublishing() { if ($this->app->runningInConsole()) { $this->publishes([ __DIR__.'/../config/vapor.php' => config_path('vapor.php'), ], 'vapor-config'); } } /** * Ensure Laravel Mix is properly configured. * * @return void */ protected function ensureMixIsConfigured() { if (isset($_ENV['MIX_URL'])) { Config::set('app.mix_url', $_ENV['MIX_URL']); } } /** * Configure trusted proxy. * * @return void */ private function configureTrustedProxy() { Config::set('trustedproxy.proxies', Config::get('trustedproxy.proxies') ?? ['0.0.0.0/0', '2000:0:0:0:0:0:0:0/3']); } /** * Register the Vapor HTTP middleware. * * @return void */ protected function registerMiddleware() { $this->app[HttpKernel::class]->pushMiddleware(ServeStaticAssets::class); } /** * Register the Vapor console commands. * * @return void * * @throws \InvalidArgumentException */ protected function registerCommands() { if (! $this->app->runningInConsole()) { return; } $this->app[ConsoleKernel::class]->command('vapor:handle {payload}', function () { throw new InvalidArgumentException( 'Unknown event type. Please create a vapor:handle command to handle custom events.' ); }); $this->app->singleton('command.vapor.work', function ($app) { return new VaporWorkCommand($app['queue.vaporWorker']); }); $this->app->singleton('command.vapor.queue-failed', function () { return new VaporQueueListFailedCommand; }); $this->app->singleton('command.vapor.health-check', function () { return new VaporHealthCheckCommand; }); $this->app->singleton('command.vapor.schedule', function () { return new VaporScheduleCommand; }); $this->commands(['command.vapor.work', 'command.vapor.queue-failed', 'command.vapor.health-check', 'command.vapor.schedule']); } /** * Register the Vapor "Octane" console commands. * * @return void * * @throws \InvalidArgumentException */ protected function registerOctaneCommands() { // Ensure we are running on Vapor... if (! isset($_ENV['VAPOR_SSM_PATH'])) { return; } if ($this->app->runningInConsole()) { $this->commands(OctaneStatusCommand::class); } } } ================================================ FILE: src/debug.php ================================================ Service Unavailable
503
Service Unavailable
================================================ FILE: stubs/cliRuntime.php ================================================ useStoragePath(StorageDirectories::PATH); if (isset($_ENV['VAPOR_MAINTENANCE_MODE']) && $_ENV['VAPOR_MAINTENANCE_MODE'] === 'true') { file_put_contents($app->storagePath().'/framework/down', '[]'); } function_exists('__vapor_debug') && __vapor_debug('Caching Laravel configuration'); try { $app->make(ConsoleKernelContract::class)->call('config:cache'); } catch (Throwable $e) { function_exists('__vapor_debug') && __vapor_debug('Failing caching Laravel configuration: '.$e->getMessage()); } /* |-------------------------------------------------------------------------- | Listen For Lambda Invocations |-------------------------------------------------------------------------- | | When receiving Lambda requests to the CLI environment, we simply send | them to the appropriate handlers based on if they are CLI commands | or queued jobs. Then we'll return a response back to the Lambda. | */ $invocations = 0; $lambdaRuntime = LambdaRuntime::fromEnvironmentVariable(); while (true) { $lambdaRuntime->nextInvocation(function ($invocationId, $event) { return CliHandlerFactory::make($event) ->handle($event) ->toApiGatewayFormat(); }); LambdaContainer::terminateIfInvocationLimitHasBeenReached( ++$invocations, (int) ($_ENV['VAPOR_MAX_REQUESTS'] ?? 250) ); } ================================================ FILE: stubs/fpmRuntime.php ================================================ useStoragePath(StorageDirectories::PATH); function_exists('__vapor_debug') && __vapor_debug('Caching Laravel configuration'); $app->make(ConsoleKernelContract::class)->call('config:cache'); /* |-------------------------------------------------------------------------- | Start PHP-FPM |-------------------------------------------------------------------------- | | We need to boot the PHP-FPM process with the appropriate handler so it | is ready to accept requests. This will initialize this process then | wait for this socket to become ready before continuing execution. | */ function_exists('__vapor_debug') && __vapor_debug('Preparing to boot FPM'); $fpm = Fpm::boot( __DIR__.'/httpHandler.php' ); /* |-------------------------------------------------------------------------- | Listen For Lambda Invocations |-------------------------------------------------------------------------- | | When using FPM, we will listen for Lambda invocations and proxy them | through the FPM process. We'll then return formatted FPM response | back to the user. We'll monitor FPM to make sure it is running. | */ $invocations = 0; $lambdaRuntime = LambdaRuntime::fromEnvironmentVariable(); while (true) { $lambdaRuntime->nextInvocation(function ($invocationId, $event) { try { return FpmHttpHandlerFactory::make($event) ->handle($event) ->toApiGatewayFormat(); } catch (WriteFailedException $e) { if (Str::contains($e->getMessage(), 'Failed to write request to socket [broken pipe]')) { function_exists('__vapor_debug') && __vapor_debug($e->getMessage()); return (new LambdaResponse(502, [], '')) ->toApiGatewayFormat(); } throw $e; } }); $fpm->ensureRunning(); LambdaContainer::terminateIfInvocationLimitHasBeenReached( ++$invocations, (int) ($_ENV['VAPOR_MAX_REQUESTS'] ?? 250) ); } ================================================ FILE: stubs/httpHandler.php ================================================ */ define('LARAVEL_START', microtime(true)); /* |-------------------------------------------------------------------------- | Register The Auto Loader |-------------------------------------------------------------------------- | | Composer provides a convenient, automatically generated class loader for | our application. We just need to utilize it! We'll simply require it | into the script here so that we don't have to worry about manual | loading any of our classes later on. It feels great to relax. | */ require __DIR__.'/vendor/autoload.php'; /* |-------------------------------------------------------------------------- | Turn On The Lights |-------------------------------------------------------------------------- | | We need to illuminate PHP development, so let us turn on the lights. | This bootstraps the framework and gets it ready for use, then it | will load up this application so that we can run it and send | the responses back to the browser and delight our users. | */ $app = require_once __DIR__.'/bootstrap/app.php'; /* |-------------------------------------------------------------------------- | Run The Application |-------------------------------------------------------------------------- | | Once we have the application, we can handle the incoming request | through the kernel, and send the associated response back to | the client's browser allowing them to enjoy the creative | and wonderful application we have prepared for them. | */ $handler = new HttpKernel($app); $response = $handler->handle(Request::capture()); $response->send(); ================================================ FILE: stubs/httpRuntime.php ================================================ useStoragePath(StorageDirectories::PATH); function_exists('__vapor_debug') && __vapor_debug('Caching Laravel configuration'); $app->make(ConsoleKernelContract::class)->call('config:cache'); /* |-------------------------------------------------------------------------- | Start Octane Worker |-------------------------------------------------------------------------- | | We need to boot the application request Octane worker so it's ready to | serve incoming requests. This will initialize this worker then wait | for Lambda invocations to be received for this Vapor application. | */ function_exists('__vapor_debug') && __vapor_debug('Preparing to boot Octane'); Octane::boot( __DIR__, getenv('OCTANE_DATABASE_SESSION_PERSIST') === 'true', getenv('OCTANE_DATABASE_SESSION_TTL') ?: 0 ); /* |-------------------------------------------------------------------------- | Listen For Lambda Invocations |-------------------------------------------------------------------------- | | When using FPM, we will listen for Lambda invocations and proxy them | through the FPM process. We'll then return formatted FPM response | back to the user. We'll monitor FPM to make sure it is running. | */ $invocations = 0; $lambdaRuntime = LambdaRuntime::fromEnvironmentVariable(); while (true) { $lambdaRuntime->nextInvocation(function ($invocationId, $event) { return OctaneHttpHandlerFactory::make($event) ->handle($event) ->toApiGatewayFormat(); }); LambdaContainer::terminateIfInvocationLimitHasBeenReached( ++$invocations, (int) ($_ENV['VAPOR_MAX_REQUESTS'] ?? 250) ); } ================================================ FILE: stubs/php-fpm.conf ================================================ error_log = /dev/null pid = /tmp/.vapor/php-fpm.pid log_limit= 10000 [default] pm = static pm.max_children = 2 pm.max_requests = 250 listen = /tmp/.vapor/php-fpm.sock clear_env = no catch_workers_output = yes decorate_workers_output = no ================================================ FILE: stubs/rds-combined-ca-bundle.pem ================================================ -----BEGIN CERTIFICATE----- MIIEEjCCAvqgAwIBAgIJAM2ZN/+nPi27MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBhZi1zb3V0aC0xIFJvb3QgQ0Ew HhcNMTkxMDI4MTgwNTU4WhcNMjQxMDI2MTgwNTU4WjCBlTELMAkGA1UEBhMCVVMx EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx JjAkBgNVBAMMHUFtYXpvbiBSRFMgYWYtc291dGgtMSBSb290IENBMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwR2351uPMZaJk2gMGT+1sk8HE9MQh2rc /sCnbxGn2p1c7Oi9aBbd/GiFijeJb2BXvHU+TOq3d3Jjqepq8tapXVt4ojbTJNyC J5E7r7KjTktKdLxtBE1MK25aY+IRJjtdU6vG3KiPKUT1naO3xs3yt0F76WVuFivd 9OHv2a+KHvPkRUWIxpmAHuMY9SIIMmEZtVE7YZGx5ah0iO4JzItHcbVR0y0PBH55 arpFBddpIVHCacp1FUPxSEWkOpI7q0AaU4xfX0fe1BV5HZYRKpBOIp1TtZWvJD+X jGUtL1BEsT5vN5g9MkqdtYrC+3SNpAk4VtpvJrdjraI/hhvfeXNnAwIDAQABo2Mw YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUEEi/ WWMcBJsoGXg+EZwkQ0MscZQwHwYDVR0jBBgwFoAUEEi/WWMcBJsoGXg+EZwkQ0Ms cZQwDQYJKoZIhvcNAQELBQADggEBAGDZ5js5Pc/gC58LJrwMPXFhJDBS8QuDm23C FFUdlqucskwOS3907ErK1ZkmVJCIqFLArHqskFXMAkRZ2PNR7RjWLqBs+0znG5yH hRKb4DXzhUFQ18UBRcvT6V6zN97HTRsEEaNhM/7k8YLe7P8vfNZ28VIoJIGGgv9D wQBBvkxQ71oOmAG0AwaGD0ORGUfbYry9Dz4a4IcUsZyRWRMADixgrFv6VuETp26s /+z+iqNaGWlELBKh3iQCT6Y/1UnkPLO42bxrCSyOvshdkYN58Q2gMTE1SVTqyo8G Lw8lLAz9bnvUSgHzB3jRrSx6ggF/WRMRYlR++y6LXP4SAsSAaC0= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEEjCCAvqgAwIBAgIJAJYM4LxvTZA6MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBldS1zb3V0aC0xIFJvb3QgQ0Ew HhcNMTkxMDMwMjAyMDM2WhcNMjQxMDI4MjAyMDM2WjCBlTELMAkGA1UEBhMCVVMx EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx JjAkBgNVBAMMHUFtYXpvbiBSRFMgZXUtc291dGgtMSBSb290IENBMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqM921jXCXeqpRNCS9CBPOe5N7gMaEt+D s5uR3riZbqzRlHGiF1jZihkXfHAIQewDwy+Yz+Oec1aEZCQMhUHxZJPusuX0cJfj b+UluFqHIijL2TfXJ3D0PVLLoNTQJZ8+GAPECyojAaNuoHbdVqxhOcznMsXIXVFq yVLKDGvyKkJjai/iSPDrQMXufg3kWt0ISjNLvsG5IFXgP4gttsM8i0yvRd4QcHoo DjvH7V3cS+CQqW5SnDrGnHToB0RLskE1ET+oNOfeN9PWOxQprMOX/zmJhnJQlTqD QP7jcf7SddxrKFjuziFiouskJJyNDsMjt1Lf60+oHZhed2ogTeifGwIDAQABo2Mw YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUFBAF cgJe/BBuZiGeZ8STfpkgRYQwHwYDVR0jBBgwFoAUFBAFcgJe/BBuZiGeZ8STfpkg RYQwDQYJKoZIhvcNAQELBQADggEBAKAYUtlvDuX2UpZW9i1QgsjFuy/ErbW0dLHU e/IcFtju2z6RLZ+uF+5A8Kme7IKG1hgt8s+w9TRVQS/7ukQzoK3TaN6XKXRosjtc o9Rm4gYWM8bmglzY1TPNaiI4HC7546hSwJhubjN0bXCuj/0sHD6w2DkiGuwKNAef yTu5vZhPkeNyXLykxkzz7bNp2/PtMBnzIp+WpS7uUDmWyScGPohKMq5PqvL59z+L ZI3CYeMZrJ5VpXUg3fNNIz/83N3G0sk7wr0ohs/kHTP7xPOYB0zD7Ku4HA0Q9Swf WX0qr6UQgTPMjfYDLffI7aEId0gxKw1eGYc6Cq5JAZ3ipi/cBFc= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEEjCCAvqgAwIBAgIJANew34ehz5l8MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h em9uIFJEUzEmMCQGA1UEAwwdQW1hem9uIFJEUyBtZS1zb3V0aC0xIFJvb3QgQ0Ew HhcNMTkwNTEwMjE0ODI3WhcNMjQwNTA4MjE0ODI3WjCBlTELMAkGA1UEBhMCVVMx EDAOBgNVBAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoM GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx JjAkBgNVBAMMHUFtYXpvbiBSRFMgbWUtc291dGgtMSBSb290IENBMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp7BYV88MukcY+rq0r79+C8UzkT30fEfT aPXbx1d6M7uheGN4FMaoYmL+JE1NZPaMRIPTHhFtLSdPccInvenRDIatcXX+jgOk UA6lnHQ98pwN0pfDUyz/Vph4jBR9LcVkBbe0zdoKKp+HGbMPRU0N2yNrog9gM5O8 gkU/3O2csJ/OFQNnj4c2NQloGMUpEmedwJMOyQQfcUyt9CvZDfIPNnheUS29jGSw ERpJe/AENu8Pxyc72jaXQuD+FEi2Ck6lBkSlWYQFhTottAeGvVFNCzKszCntrtqd rdYUwurYsLTXDHv9nW2hfDUQa0mhXf9gNDOBIVAZugR9NqNRNyYLHQIDAQABo2Mw YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU54cf DjgwBx4ycBH8+/r8WXdaiqYwHwYDVR0jBBgwFoAU54cfDjgwBx4ycBH8+/r8WXda iqYwDQYJKoZIhvcNAQELBQADggEBAIIMTSPx/dR7jlcxggr+O6OyY49Rlap2laKA eC/XI4ySP3vQkIFlP822U9Kh8a9s46eR0uiwV4AGLabcu0iKYfXjPkIprVCqeXV7 ny9oDtrbflyj7NcGdZLvuzSwgl9SYTJp7PVCZtZutsPYlbJrBPHwFABvAkMvRtDB hitIg4AESDGPoCl94sYHpfDfjpUDMSrAMDUyO6DyBdZH5ryRMAs3lGtsmkkNUrso aTW6R05681Z0mvkRdb+cdXtKOSuDZPoe2wJJIaz3IlNQNSrB5TImMYgmt6iAsFhv 3vfTSTKrZDNTJn4ybG6pq1zWExoXsktZPylJly6R3RBwV6nwqBM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBjCCAu6gAwIBAgIJAMc0ZzaSUK51MA0GCSqGSIb3DQEBCwUAMIGPMQswCQYD VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h em9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkw ODIyMTcwODUwWhcNMjQwODIyMTcwODUwWjCBjzELMAkGA1UEBhMCVVMxEDAOBgNV BAcMB1NlYXR0bGUxEzARBgNVBAgMCldhc2hpbmd0b24xIjAgBgNVBAoMGUFtYXpv biBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxIDAeBgNV BAMMF0FtYXpvbiBSRFMgUm9vdCAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEArXnF/E6/Qh+ku3hQTSKPMhQQlCpoWvnIthzX6MK3p5a0eXKZ oWIjYcNNG6UwJjp4fUXl6glp53Jobn+tWNX88dNH2n8DVbppSwScVE2LpuL+94vY 0EYE/XxN7svKea8YvlrqkUBKyxLxTjh+U/KrGOaHxz9v0l6ZNlDbuaZw3qIWdD/I 6aNbGeRUVtpM6P+bWIoxVl/caQylQS6CEYUk+CpVyJSkopwJlzXT07tMoDL5WgX9 O08KVgDNz9qP/IGtAcRduRcNioH3E9v981QO1zt/Gpb2f8NqAjUUCUZzOnij6mx9 McZ+9cWX88CRzR0vQODWuZscgI08NvM69Fn2SQIDAQABo2MwYTAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUc19g2LzLA5j0Kxc0LjZa pmD/vB8wHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJKoZIhvcN AQELBQADggEBAHAG7WTmyjzPRIM85rVj+fWHsLIvqpw6DObIjMWokpliCeMINZFV ynfgBKsf1ExwbvJNzYFXW6dihnguDG9VMPpi2up/ctQTN8tm9nDKOy08uNZoofMc NUZxKCEkVKZv+IL4oHoeayt8egtv3ujJM6V14AstMQ6SwvwvA93EP/Ug2e4WAXHu cbI1NAbUgVDqp+DRdfvZkgYKryjTWd/0+1fS8X1bBZVWzl7eirNVnHbSH2ZDpNuY 0SBd8dj5F6ld3t58ydZbrTHze7JJOd8ijySAp4/kiu9UfZWuTPABzDa/DSdz9Dk/ zPW4CXXvhLmE02TA9/HeCw3KEHIwicNuEfw= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEEDCCAvigAwIBAgIJAKFMXyltvuRdMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h em9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJEUyBCZXRhIFJvb3QgMjAxOSBDQTAe Fw0xOTA4MTkxNzM4MjZaFw0yNDA4MTkxNzM4MjZaMIGUMQswCQYDVQQGEwJVUzEQ MA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UECgwZ QW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEl MCMGA1UEAwwcQW1hem9uIFJEUyBCZXRhIFJvb3QgMjAxOSBDQTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAMkZdnIH9ndatGAcFo+DppGJ1HUt4x+zeO+0 ZZ29m0sfGetVulmTlv2d5b66e+QXZFWpcPQMouSxxYTW08TbrQiZngKr40JNXftA atvzBqIImD4II0ZX5UEVj2h98qe/ypW5xaDN7fEa5e8FkYB1TEemPaWIbNXqchcL tV7IJPr3Cd7Z5gZJlmujIVDPpMuSiNaal9/6nT9oqN+JSM1fx5SzrU5ssg1Vp1vv 5Xab64uOg7wCJRB9R2GC9XD04odX6VcxUAGrZo6LR64ZSifupo3l+R5sVOc5i8NH skdboTzU9H7+oSdqoAyhIU717PcqeDum23DYlPE2nGBWckE+eT8CAwEAAaNjMGEw DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFK2hDBWl sbHzt/EHd0QYOooqcFPhMB8GA1UdIwQYMBaAFK2hDBWlsbHzt/EHd0QYOooqcFPh MA0GCSqGSIb3DQEBCwUAA4IBAQAO/718k8EnOqJDx6wweUscGTGL/QdKXUzTVRAx JUsjNUv49mH2HQVEW7oxszfH6cPCaupNAddMhQc4C/af6GHX8HnqfPDk27/yBQI+ yBBvIanGgxv9c9wBbmcIaCEWJcsLp3HzXSYHmjiqkViXwCpYfkoV3Ns2m8bp+KCO y9XmcCKRaXkt237qmoxoh2sGmBHk2UlQtOsMC0aUQ4d7teAJG0q6pbyZEiPyKZY1 XR/UVxMJL0Q4iVpcRS1kaNCMfqS2smbLJeNdsan8pkw1dvPhcaVTb7CvjhJtjztF YfDzAI5794qMlWxwilKMmUvDlPPOTen8NNHkLwWvyFCH7Doh -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEFjCCAv6gAwIBAgIJAMzYZJ+R9NBVMA0GCSqGSIb3DQEBCwUAMIGXMQswCQYD VQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi MCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1h em9uIFJEUzEoMCYGA1UEAwwfQW1hem9uIFJEUyBQcmV2aWV3IFJvb3QgMjAxOSBD QTAeFw0xOTA4MjEyMjI5NDlaFw0yNDA4MjEyMjI5NDlaMIGXMQswCQYDVQQGEwJV UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE UzEoMCYGA1UEAwwfQW1hem9uIFJEUyBQcmV2aWV3IFJvb3QgMjAxOSBDQTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7kkS6vjgKKQTPynC2NjdN5aPPV O71G0JJS/2ARVBVJd93JLiGovVJilfWYfwZCs4gTRSSjrUD4D4HyqCd6A+eEEtJq M0DEC7i0dC+9WNTsPszuB206Jy2IUmxZMIKJAA1NHSbIMjB+b6/JhbSUi7nKdbR/ brj83bF+RoSA+ogrgX7mQbxhmFcoZN9OGaJgYKsKWUt5Wqv627KkGodUK8mDepgD S3ZfoRQRx3iceETpcmHJvaIge6+vyDX3d9Z22jmvQ4AKv3py2CmU2UwuhOltFDwB 0ddtb39vgwrJxaGfiMRHpEP1DfNLWHAnA69/pgZPwIggidS+iBPUhgucMp8CAwEA AaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FGnTGpQuQ2H/DZlXMQijZEhjs7TdMB8GA1UdIwQYMBaAFGnTGpQuQ2H/DZlXMQij ZEhjs7TdMA0GCSqGSIb3DQEBCwUAA4IBAQC3xz1vQvcXAfpcZlngiRWeqU8zQAMQ LZPCFNv7PVk4pmqX+ZiIRo4f9Zy7TrOVcboCnqmP/b/mNq0gVF4O+88jwXJZD+f8 /RnABMZcnGU+vK0YmxsAtYU6TIb1uhRFmbF8K80HHbj9vSjBGIQdPCbvmR2zY6VJ BYM+w9U9hp6H4DVMLKXPc1bFlKA5OBTgUtgkDibWJKFOEPW3UOYwp9uq6pFoN0AO xMTldqWFsOF3bJIlvOY0c/1EFZXu3Ns6/oCP//Ap9vumldYMUZWmbK+gK33FPOXV 8BQ6jNC29icv7lLDpRPwjibJBXX+peDR5UK4FdYcswWEB1Tix5X8dYu6 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSYwJAYDVQQDDB1BbWF6b24gUkRTIGFmLXNvdXRoLTEgUm9vdCBDQTAeFw0xOTEw MjgxODA2NTNaFw0yNDEwMjgxODA2NTNaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE AwwYQW1hem9uIFJEUyBhZi1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAvtV1OqmFa8zCVQSKOvPUJERLVFtd4rZmDpImc5rIoeBk7w/P 9lcKUJjO8R/w1a2lJXx3oQ81tiY0Piw6TpT62YWVRMWrOw8+Vxq1dNaDSFp9I8d0 UHillSSbOk6FOrPDp+R6AwbGFqUDebbN5LFFoDKbhNmH1BVS0a6YNKpGigLRqhka cClPslWtPqtjbaP3Jbxl26zWzLo7OtZl98dR225pq8aApNBwmtgA7Gh60HK/cX0t 32W94n8D+GKSg6R4MKredVFqRTi9hCCNUu0sxYPoELuM+mHiqB5NPjtm92EzCWs+ +vgWhMc6GxG+82QSWx1Vj8sgLqtE/vLrWddf5QIDAQABo2YwZDAOBgNVHQ8BAf8E BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuLB4gYVJrSKJj/Gz pqc6yeA+RcAwHwYDVR0jBBgwFoAUEEi/WWMcBJsoGXg+EZwkQ0MscZQwDQYJKoZI hvcNAQELBQADggEBABauYOZxUhe9/RhzGJ8MsWCz8eKcyDVd4FCnY6Qh+9wcmYNT LtnD88LACtJKb/b81qYzcB0Em6+zVJ3Z9jznfr6buItE6es9wAoja22Xgv44BTHL rimbgMwpTt3uEMXDffaS0Ww6YWb3pSE0XYI2ISMWz+xRERRf+QqktSaL39zuiaW5 tfZMre+YhohRa/F0ZQl3RCd6yFcLx4UoSPqQsUl97WhYzwAxZZfwvLJXOc4ATt3u VlCUylNDkaZztDJc/yN5XQoK9W5nOt2cLu513MGYKbuarQr8f+gYU8S+qOyuSRSP NRITzwCRVnsJE+2JmcRInn/NcanB7uOGqTvJ9+c= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSYwJAYDVQQDDB1BbWF6b24gUkRTIGV1LXNvdXRoLTEgUm9vdCBDQTAeFw0xOTEw MzAyMDIxMzBaFw0yNDEwMzAyMDIxMzBaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE AwwYQW1hem9uIFJEUyBldS1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAtEyjYcajx6xImJn8Vz1zjdmL4ANPgQXwF7+tF7xccmNAZETb bzb3I9i5fZlmrRaVznX+9biXVaGxYzIUIR3huQ3Q283KsDYnVuGa3mk690vhvJbB QIPgKa5mVwJppnuJm78KqaSpi0vxyCPe3h8h6LLFawVyWrYNZ4okli1/U582eef8 RzJp/Ear3KgHOLIiCdPDF0rjOdCG1MOlDLixVnPn9IYOciqO+VivXBg+jtfc5J+L AaPm0/Yx4uELt1tkbWkm4BvTU/gBOODnYziITZM0l6Fgwvbwgq5duAtKW+h031lC 37rEvrclqcp4wrsUYcLAWX79ZyKIlRxcAdvEhQIDAQABo2YwZDAOBgNVHQ8BAf8E BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU7zPyc0azQxnBCe7D b9KAadH1QSEwHwYDVR0jBBgwFoAUFBAFcgJe/BBuZiGeZ8STfpkgRYQwDQYJKoZI hvcNAQELBQADggEBAFGaNiYxg7yC/xauXPlaqLCtwbm2dKyK9nIFbF/7be8mk7Q3 MOA0of1vGHPLVQLr6bJJpD9MAbUcm4cPAwWaxwcNpxOjYOFDaq10PCK4eRAxZWwF NJRIRmGsl8NEsMNTMCy8X+Kyw5EzH4vWFl5Uf2bGKOeFg0zt43jWQVOX6C+aL3Cd pRS5MhmYpxMG8irrNOxf4NVFE2zpJOCm3bn0STLhkDcV/ww4zMzObTJhiIb5wSWn EXKKWhUXuRt7A2y1KJtXpTbSRHQxE++69Go1tWhXtRiULCJtf7wF2Ksm0RR/AdXT 1uR1vKyH5KBJPX3ppYkQDukoHTFR0CpB+G84NLo= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSYwJAYDVQQDDB1BbWF6b24gUkRTIG1lLXNvdXRoLTEgUm9vdCBDQTAeFw0xOTA1 MTAyMTU4NDNaFw0yNTA2MDExMjAwMDBaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UE CAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9u IFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UE AwwYQW1hem9uIFJEUyBtZS1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAudOYPZH+ihJAo6hNYMB5izPVBe3TYhnZm8+X3IoaaYiKtsp1 JJhkTT0CEejYIQ58Fh4QrMUyWvU8qsdK3diNyQRoYLbctsBPgxBR1u07eUJDv38/ C1JlqgHmMnMi4y68Iy7ymv50QgAMuaBqgEBRI1R6Lfbyrb2YvH5txjJyTVMwuCfd YPAtZVouRz0JxmnfsHyxjE+So56uOKTDuw++Ho4HhZ7Qveej7XB8b+PIPuroknd3 FQB5RVbXRvt5ZcVD4F2fbEdBniF7FAF4dEiofVCQGQ2nynT7dZdEIPfPdH3n7ZmE lAOmwHQ6G83OsiHRBLnbp+QZRgOsjkHJxT20bQIDAQABo2YwZDAOBgNVHQ8BAf8E BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUOEVDM7VomRH4HVdA QvIMNq2tXOcwHwYDVR0jBBgwFoAU54cfDjgwBx4ycBH8+/r8WXdaiqYwDQYJKoZI hvcNAQELBQADggEBAHhvMssj+Th8IpNePU6RH0BiL6o9c437R3Q4IEJeFdYL+nZz PW/rELDPvLRUNMfKM+KzduLZ+l29HahxefejYPXtvXBlq/E/9czFDD4fWXg+zVou uDXhyrV4kNmP4S0eqsAP/jQHPOZAMFA4yVwO9hlqmePhyDnszCh9c1PfJSBh49+b 4w7i/L3VBOMt8j3EKYvqz0gVfpeqhJwL4Hey8UbVfJRFJMJzfNHpePqtDRAY7yjV PYquRaV2ab/E+/7VFkWMM4tazYz/qsYA2jSH+4xDHvYk8LnsbcrF9iuidQmEc5sb FgcWaSKG4DJjcI5k7AJLWcXyTDt21Ci43LE+I9Q= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECDCCAvCgAwIBAgICVIYwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MDQxNzEz MDRaFw0yNDA4MjIxNzA4NTBaMIGVMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEmMCQGA1UEAwwdQW1h em9uIFJEUyBhcC1zb3V0aC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDUYOz1hGL42yUCrcsMSOoU8AeD/3KgZ4q7gP+vAz1WnY9K/kim eWN/2Qqzlo3+mxSFQFyD4MyV3+CnCPnBl9Sh1G/F6kThNiJ7dEWSWBQGAB6HMDbC BaAsmUc1UIz8sLTL3fO+S9wYhA63Wun0Fbm/Rn2yk/4WnJAaMZcEtYf6e0KNa0LM p/kN/70/8cD3iz3dDR8zOZFpHoCtf0ek80QqTich0A9n3JLxR6g6tpwoYviVg89e qCjQ4axxOkWWeusLeTJCcY6CkVyFvDAKvcUl1ytM5AiaUkXblE7zDFXRM4qMMRdt lPm8d3pFxh0fRYk8bIKnpmtOpz3RIctDrZZxAgMBAAGjZjBkMA4GA1UdDwEB/wQE AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBT99wKJftD3jb4sHoHG i3uGlH6W6TAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG 9w0BAQsFAAOCAQEAZ17hhr3dII3hUfuHQ1hPWGrpJOX/G9dLzkprEIcCidkmRYl+ hu1Pe3caRMh/17+qsoEErmnVq5jNY9X1GZL04IZH8YbHc7iRHw3HcWAdhN8633+K jYEB2LbJ3vluCGnCejq9djDb6alOugdLMJzxOkHDhMZ6/gYbECOot+ph1tQuZXzD tZ7prRsrcuPBChHlPjmGy8M9z8u+kF196iNSUGC4lM8vLkHM7ycc1/ZOwRq9aaTe iOghbQQyAEe03MWCyDGtSmDfr0qEk+CHN+6hPiaL8qKt4s+V9P7DeK4iW08ny8Ox AVS7u0OK/5+jKMAMrKwpYrBydOjTUTHScocyNw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBzCCAu+gAwIBAgICQ2QwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MDUxODQ2 MjlaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h em9uIFJEUyBzYS1lYXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAMMvR+ReRnOzqJzoaPipNTt1Z2VA968jlN1+SYKUrYM3No+Vpz0H M6Tn0oYB66ByVsXiGc28ulsqX1HbHsxqDPwvQTKvO7SrmDokoAkjJgLocOLUAeld 5AwvUjxGRP6yY90NV7X786MpnYb2Il9DIIaV9HjCmPt+rjy2CZjS0UjPjCKNfB8J bFjgW6GGscjeyGb/zFwcom5p4j0rLydbNaOr9wOyQrtt3ZQWLYGY9Zees/b8pmcc Jt+7jstZ2UMV32OO/kIsJ4rMUn2r/uxccPwAc1IDeRSSxOrnFKhW3Cu69iB3bHp7 JbawY12g7zshE4I14sHjv3QoXASoXjx4xgMCAwEAAaNmMGQwDgYDVR0PAQH/BAQD AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFI1Fc/Ql2jx+oJPgBVYq ccgP0pQ8MB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 DQEBCwUAA4IBAQB4VVVabVp70myuYuZ3vltQIWqSUMhkaTzehMgGcHjMf9iLoZ/I 93KiFUSGnek5cRePyS9wcpp0fcBT3FvkjpUdCjVtdttJgZFhBxgTd8y26ImdDDMR 4+BUuhI5msvjL08f+Vkkpu1GQcGmyFVPFOy/UY8iefu+QyUuiBUnUuEDd49Hw0Fn /kIPII6Vj82a2mWV/Q8e+rgN8dIRksRjKI03DEoP8lhPlsOkhdwU6Uz9Vu6NOB2Q Ls1kbcxAc7cFSyRVJEhh12Sz9d0q/CQSTFsVJKOjSNQBQfVnLz1GwO/IieUEAr4C jkTntH0r1LX5b/GwN4R887LvjAEdTbg1his7 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECDCCAvCgAwIBAgIDAIkHMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJV UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE UzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkwOTA2MTc0 MDIxWhcNMjQwODIyMTcwODUwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldh c2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoMGUFtYXpvbiBXZWIg U2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxJTAjBgNVBAMMHEFt YXpvbiBSRFMgdXMtd2VzdC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDD2yzbbAl77OofTghDMEf624OvU0eS9O+lsdO0QlbfUfWa1Kd6 0WkgjkLZGfSRxEHMCnrv4UPBSK/Qwn6FTjkDLgemhqBtAnplN4VsoDL+BkRX4Wwq /dSQJE2b+0hm9w9UMVGFDEq1TMotGGTD2B71eh9HEKzKhGzqiNeGsiX4VV+LJzdH uM23eGisNqmd4iJV0zcAZ+Gbh2zK6fqTOCvXtm7Idccv8vZZnyk1FiWl3NR4WAgK AkvWTIoFU3Mt7dIXKKClVmvssG8WHCkd3Xcb4FHy/G756UZcq67gMMTX/9fOFM/v l5C0+CHl33Yig1vIDZd+fXV1KZD84dEJfEvHAgMBAAGjZjBkMA4GA1UdDwEB/wQE AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBR+ap20kO/6A7pPxo3+ T3CfqZpQWjAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG 9w0BAQsFAAOCAQEAHCJky2tPjPttlDM/RIqExupBkNrnSYnOK4kr9xJ3sl8UF2DA PAnYsjXp3rfcjN/k/FVOhxwzi3cXJF/2Tjj39Bm/OEfYTOJDNYtBwB0VVH4ffa/6 tZl87jaIkrxJcreeeHqYMnIxeN0b/kliyA+a5L2Yb0VPjt9INq34QDc1v74FNZ17 4z8nr1nzg4xsOWu0Dbjo966lm4nOYIGBRGOKEkHZRZ4mEiMgr3YLkv8gSmeitx57 Z6dVemNtUic/LVo5Iqw4n3TBS0iF2C1Q1xT/s3h+0SXZlfOWttzSluDvoMv5PvCd pFjNn+aXLAALoihL1MJSsxydtsLjOBro5eK0Vw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEDDCCAvSgAwIBAgICOFAwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTAxNzQ2 MjFaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h em9uIFJEUyBhcC1ub3J0aGVhc3QtMiAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAzU72e6XbaJbi4HjJoRNjKxzUEuChKQIt7k3CWzNnmjc5 8I1MjCpa2W1iw1BYVysXSNSsLOtUsfvBZxi/1uyMn5ZCaf9aeoA9UsSkFSZBjOCN DpKPCmfV1zcEOvJz26+1m8WDg+8Oa60QV0ou2AU1tYcw98fOQjcAES0JXXB80P2s 3UfkNcnDz+l4k7j4SllhFPhH6BQ4lD2NiFAP4HwoG6FeJUn45EPjzrydxjq6v5Fc cQ8rGuHADVXotDbEhaYhNjIrsPL+puhjWfhJjheEw8c4whRZNp6gJ/b6WEes/ZhZ h32DwsDsZw0BfRDUMgUn8TdecNexHUw8vQWeC181hwIDAQABo2YwZDAOBgNVHQ8B Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUwW9bWgkWkr0U lrOsq2kvIdrECDgwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ KoZIhvcNAQELBQADggEBAEugF0Gj7HVhX0ehPZoGRYRt3PBuI2YjfrrJRTZ9X5wc 9T8oHmw07mHmNy1qqWvooNJg09bDGfB0k5goC2emDiIiGfc/kvMLI7u+eQOoMKj6 mkfCncyRN3ty08Po45vTLBFZGUvtQmjM6yKewc4sXiASSBmQUpsMbiHRCL72M5qV obcJOjGcIdDTmV1BHdWT+XcjynsGjUqOvQWWhhLPrn4jWe6Xuxll75qlrpn3IrIx CRBv/5r7qbcQJPOgwQsyK4kv9Ly8g7YT1/vYBlR3cRsYQjccw5ceWUj2DrMVWhJ4 prf+E3Aa4vYmLLOUUvKnDQ1k3RGNu56V0tonsQbfsaM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECjCCAvKgAwIBAgICEzUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTAyMDUy MjVaFw0yNDA4MjIxNzA4NTBaMIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEoMCYGA1UEAwwfQW1h em9uIFJEUyBjYS1jZW50cmFsLTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAOxHqdcPSA2uBjsCP4DLSlqSoPuQ/X1kkJLusVRKiQE2zayB viuCBt4VB9Qsh2rW3iYGM+usDjltGnI1iUWA5KHcvHszSMkWAOYWLiMNKTlg6LCp XnE89tvj5dIH6U8WlDvXLdjB/h30gW9JEX7S8supsBSci2GxEzb5mRdKaDuuF/0O qvz4YE04pua3iZ9QwmMFuTAOYzD1M72aOpj+7Ac+YLMM61qOtU+AU6MndnQkKoQi qmUN2A9IFaqHFzRlSdXwKCKUA4otzmz+/N3vFwjb5F4DSsbsrMfjeHMo6o/nb6Nh YDb0VJxxPee6TxSuN7CQJ2FxMlFUezcoXqwqXD0CAwEAAaNmMGQwDgYDVR0PAQH/ BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFDGGpon9WfIpsggE CxHq8hZ7E2ESMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqG SIb3DQEBCwUAA4IBAQAvpeQYEGZvoTVLgV9rd2+StPYykMsmFjWQcyn3dBTZRXC2 lKq7QhQczMAOhEaaN29ZprjQzsA2X/UauKzLR2Uyqc2qOeO9/YOl0H3qauo8C/W9 r8xqPbOCDLEXlOQ19fidXyyEPHEq5WFp8j+fTh+s8WOx2M7IuC0ANEetIZURYhSp xl9XOPRCJxOhj7JdelhpweX0BJDNHeUFi0ClnFOws8oKQ7sQEv66d5ddxqqZ3NVv RbCvCtEutQMOUMIuaygDlMn1anSM8N7Wndx8G6+Uy67AnhjGx7jw/0YPPxopEj6x JXP8j0sJbcT9K/9/fPVLNT25RvQ/93T2+IQL4Ca2 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBzCCAu+gAwIBAgICYpgwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTExNzMx NDhaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h em9uIFJEUyBldS13ZXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAMk3YdSZ64iAYp6MyyKtYJtNzv7zFSnnNf6vv0FB4VnfITTMmOyZ LXqKAT2ahZ00hXi34ewqJElgU6eUZT/QlzdIu359TEZyLVPwURflL6SWgdG01Q5X O++7fSGcBRyIeuQWs9FJNIIqK8daF6qw0Rl5TXfu7P9dBc3zkgDXZm2DHmxGDD69 7liQUiXzoE1q2Z9cA8+jirDioJxN9av8hQt12pskLQumhlArsMIhjhHRgF03HOh5 tvi+RCfihVOxELyIRTRpTNiIwAqfZxxTWFTgfn+gijTmd0/1DseAe82aYic8JbuS EMbrDduAWsqrnJ4GPzxHKLXX0JasCUcWyMECAwEAAaNmMGQwDgYDVR0PAQH/BAQD AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFPLtsq1NrwJXO13C9eHt sLY11AGwMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 DQEBCwUAA4IBAQAnWBKj5xV1A1mYd0kIgDdkjCwQkiKF5bjIbGkT3YEFFbXoJlSP 0lZZ/hDaOHI8wbLT44SzOvPEEmWF9EE7SJzkvSdQrUAWR9FwDLaU427ALI3ngNHy lGJ2hse1fvSRNbmg8Sc9GBv8oqNIBPVuw+AJzHTacZ1OkyLZrz1c1QvwvwN2a+Jd vH0V0YIhv66llKcYDMUQJAQi4+8nbRxXWv6Gq3pvrFoorzsnkr42V3JpbhnYiK+9 nRKd4uWl62KRZjGkfMbmsqZpj2fdSWMY1UGyN1k+kDmCSWYdrTRDP0xjtIocwg+A J116n4hV/5mbA0BaPiS2krtv17YAeHABZcvz -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECjCCAvKgAwIBAgICV2YwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTExOTM2 MjBaFw0yNDA4MjIxNzA4NTBaMIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEoMCYGA1UEAwwfQW1h em9uIFJEUyBldS1jZW50cmFsLTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAMEx54X2pHVv86APA0RWqxxRNmdkhAyp2R1cFWumKQRofoFv n+SPXdkpIINpMuEIGJANozdiEz7SPsrAf8WHyD93j/ZxrdQftRcIGH41xasetKGl I67uans8d+pgJgBKGb/Z+B5m+UsIuEVekpvgpwKtmmaLFC/NCGuSsJoFsRqoa6Gh m34W6yJoY87UatddCqLY4IIXaBFsgK9Q/wYzYLbnWM6ZZvhJ52VMtdhcdzeTHNW0 5LGuXJOF7Ahb4JkEhoo6TS2c0NxB4l4MBfBPgti+O7WjR3FfZHpt18A6Zkq6A2u6 D/oTSL6c9/3sAaFTFgMyL3wHb2YlW0BPiljZIqECAwEAAaNmMGQwDgYDVR0PAQH/ BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFOcAToAc6skWffJa TnreaswAfrbcMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqG SIb3DQEBCwUAA4IBAQA1d0Whc1QtspK496mFWfFEQNegLh0a9GWYlJm+Htcj5Nxt DAIGXb+8xrtOZFHmYP7VLCT5Zd2C+XytqseK/+s07iAr0/EPF+O2qcyQWMN5KhgE cXw2SwuP9FPV3i+YAm11PBVeenrmzuk9NrdHQ7TxU4v7VGhcsd2C++0EisrmquWH mgIfmVDGxphwoES52cY6t3fbnXmTkvENvR+h3rj+fUiSz0aSo+XZUGHPgvuEKM/W CBD9Smc9CBoBgvy7BgHRgRUmwtABZHFUIEjHI5rIr7ZvYn+6A0O6sogRfvVYtWFc qpyrW1YX8mD0VlJ8fGKM3G+aCOsiiPKDV/Uafrm+ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECDCCAvCgAwIBAgICGAcwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTIxODE5 NDRaFw0yNDA4MjIxNzA4NTBaMIGVMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEmMCQGA1UEAwwdQW1h em9uIFJEUyBldS1ub3J0aC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQCiIYnhe4UNBbdBb/nQxl5giM0XoVHWNrYV5nB0YukA98+TPn9v Aoj1RGYmtryjhrf01Kuv8SWO+Eom95L3zquoTFcE2gmxCfk7bp6qJJ3eHOJB+QUO XsNRh76fwDzEF1yTeZWH49oeL2xO13EAx4PbZuZpZBttBM5zAxgZkqu4uWQczFEs JXfla7z2fvWmGcTagX10O5C18XaFroV0ubvSyIi75ue9ykg/nlFAeB7O0Wxae88e uhiBEFAuLYdqWnsg3459NfV8Yi1GnaitTym6VI3tHKIFiUvkSiy0DAlAGV2iiyJE q+DsVEO4/hSINJEtII4TMtysOsYPpINqeEzRAgMBAAGjZjBkMA4GA1UdDwEB/wQE AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRR0UpnbQyjnHChgmOc hnlc0PogzTAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG 9w0BAQsFAAOCAQEAKJD4xVzSf4zSGTBJrmamo86jl1NHQxXUApAZuBZEc8tqC6TI T5CeoSr9CMuVC8grYyBjXblC4OsM5NMvmsrXl/u5C9dEwtBFjo8mm53rOOIm1fxl I1oYB/9mtO9ANWjkykuLzWeBlqDT/i7ckaKwalhLODsRDO73vRhYNjsIUGloNsKe pxw3dzHwAZx4upSdEVG4RGCZ1D0LJ4Gw40OfD69hfkDfRVVxKGrbEzqxXRvovmDc tKLdYZO/6REoca36v4BlgIs1CbUXJGLSXUwtg7YXGLSVBJ/U0+22iGJmBSNcoyUN cjPFD9JQEhDDIYYKSGzIYpvslvGc4T5ISXFiuQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBzCCAu+gAwIBAgICZIEwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTIyMTMy MzJaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h em9uIFJEUyBldS13ZXN0LTIgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBALGiwqjiF7xIjT0Sx7zB3764K2T2a1DHnAxEOr+/EIftWKxWzT3u PFwS2eEZcnKqSdRQ+vRzonLBeNLO4z8aLjQnNbkizZMBuXGm4BqRm1Kgq3nlLDQn 7YqdijOq54SpShvR/8zsO4sgMDMmHIYAJJOJqBdaus2smRt0NobIKc0liy7759KB 6kmQ47Gg+kfIwxrQA5zlvPLeQImxSoPi9LdbRoKvu7Iot7SOa+jGhVBh3VdqndJX 7tm/saj4NE375csmMETFLAOXjat7zViMRwVorX4V6AzEg1vkzxXpA9N7qywWIT5Y fYaq5M8i6vvLg0CzrH9fHORtnkdjdu1y+0MCAwEAAaNmMGQwDgYDVR0PAQH/BAQD AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFOhOx1yt3Z7mvGB9jBv 2ymdZwiOMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 DQEBCwUAA4IBAQBehqY36UGDvPVU9+vtaYGr38dBbp+LzkjZzHwKT1XJSSUc2wqM hnCIQKilonrTIvP1vmkQi8qHPvDRtBZKqvz/AErW/ZwQdZzqYNFd+BmOXaeZWV0Q oHtDzXmcwtP8aUQpxN0e1xkWb1E80qoy+0uuRqb/50b/R4Q5qqSfJhkn6z8nwB10 7RjLtJPrK8igxdpr3tGUzfAOyiPrIDncY7UJaL84GFp7WWAkH0WG3H8Y8DRcRXOU mqDxDLUP3rNuow3jnGxiUY+gGX5OqaZg4f4P6QzOSmeQYs6nLpH0PiN00+oS1BbD bpWdZEttILPI+vAYkU4QuBKKDjJL6HbSd+cn -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECDCCAvCgAwIBAgIDAIVCMA0GCSqGSIb3DQEBCwUAMIGPMQswCQYDVQQGEwJV UzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEiMCAGA1UE CgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJE UzEgMB4GA1UEAwwXQW1hem9uIFJEUyBSb290IDIwMTkgQ0EwHhcNMTkwOTEzMTcw NjQxWhcNMjQwODIyMTcwODUwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldh c2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoMGUFtYXpvbiBXZWIg U2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxJTAjBgNVBAMMHEFt YXpvbiBSRFMgdXMtZWFzdC0yIDIwMTkgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDE+T2xYjUbxOp+pv+gRA3FO24+1zCWgXTDF1DHrh1lsPg5k7ht 2KPYzNc+Vg4E+jgPiW0BQnA6jStX5EqVh8BU60zELlxMNvpg4KumniMCZ3krtMUC au1NF9rM7HBh+O+DYMBLK5eSIVt6lZosOb7bCi3V6wMLA8YqWSWqabkxwN4w0vXI 8lu5uXXFRemHnlNf+yA/4YtN4uaAyd0ami9+klwdkZfkrDOaiy59haOeBGL8EB/c dbJJlguHH5CpCscs3RKtOOjEonXnKXldxarFdkMzi+aIIjQ8GyUOSAXHtQHb3gZ4 nS6Ey0CMlwkB8vUObZU9fnjKJcL5QCQqOfwvAgMBAAGjZjBkMA4GA1UdDwEB/wQE AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQUPuRHohPxx4VjykmH 6usGrLL1ETAfBgNVHSMEGDAWgBRzX2DYvMsDmPQrFzQuNlqmYP+8HzANBgkqhkiG 9w0BAQsFAAOCAQEAUdR9Vb3y33Yj6X6KGtuthZ08SwjImVQPtknzpajNE5jOJAh8 quvQnU9nlnMO85fVDU1Dz3lLHGJ/YG1pt1Cqq2QQ200JcWCvBRgdvH6MjHoDQpqZ HvQ3vLgOGqCLNQKFuet9BdpsHzsctKvCVaeBqbGpeCtt3Hh/26tgx0rorPLw90A2 V8QSkZJjlcKkLa58N5CMM8Xz8KLWg3MZeT4DmlUXVCukqK2RGuP2L+aME8dOxqNv OnOz1zrL5mR2iJoDpk8+VE/eBDmJX40IJk6jBjWoxAO/RXq+vBozuF5YHN1ujE92 tO8HItgTp37XT8bJBAiAnt5mxw+NLSqtxk2QdQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEDDCCAvSgAwIBAgICY4kwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTMyMDEx NDJaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h em9uIFJEUyBhcC1zb3V0aGVhc3QtMSAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAr5u9OuLL/OF/fBNUX2kINJLzFl4DnmrhnLuSeSnBPgbb qddjf5EFFJBfv7IYiIWEFPDbDG5hoBwgMup5bZDbas+ZTJTotnnxVJTQ6wlhTmns eHECcg2pqGIKGrxZfbQhlj08/4nNAPvyYCTS0bEcmQ1emuDPyvJBYDDLDU6AbCB5 6Z7YKFQPTiCBblvvNzchjLWF9IpkqiTsPHiEt21sAdABxj9ityStV3ja/W9BfgxH wzABSTAQT6FbDwmQMo7dcFOPRX+hewQSic2Rn1XYjmNYzgEHisdUsH7eeXREAcTw 61TRvaLH8AiOWBnTEJXPAe6wYfrcSd1pD0MXpoB62wIDAQABo2YwZDAOBgNVHQ8B Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUytwMiomQOgX5 Ichd+2lDWRUhkikwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ KoZIhvcNAQELBQADggEBACf6lRDpfCD7BFRqiWM45hqIzffIaysmVfr+Jr+fBTjP uYe/ba1omSrNGG23bOcT9LJ8hkQJ9d+FxUwYyICQNWOy6ejicm4z0C3VhphbTPqj yjpt9nG56IAcV8BcRJh4o/2IfLNzC/dVuYJV8wj7XzwlvjysenwdrJCoLadkTr1h eIdG6Le07sB9IxrGJL9e04afk37h7c8ESGSE4E+oS4JQEi3ATq8ne1B9DQ9SasXi IRmhNAaISDzOPdyLXi9N9V9Lwe/DHcja7hgLGYx3UqfjhLhOKwp8HtoZORixAmOI HfILgNmwyugAbuZoCazSKKBhQ0wgO0WZ66ZKTMG8Oho= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBzCCAu+gAwIBAgICUYkwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTYxODIx MTVaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h em9uIFJEUyB1cy13ZXN0LTIgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBANCEZBZyu6yJQFZBJmSUZfSZd3Ui2gitczMKC4FLr0QzkbxY+cLa uVONIOrPt4Rwi+3h/UdnUg917xao3S53XDf1TDMFEYp4U8EFPXqCn/GXBIWlU86P PvBN+gzw3nS+aco7WXb+woTouvFVkk8FGU7J532llW8o/9ydQyDIMtdIkKTuMfho OiNHSaNc+QXQ32TgvM9A/6q7ksUoNXGCP8hDOkSZ/YOLiI5TcdLh/aWj00ziL5bj pvytiMZkilnc9dLY9QhRNr0vGqL0xjmWdoEXz9/OwjmCihHqJq+20MJPsvFm7D6a 2NKybR9U+ddrjb8/iyLOjURUZnj5O+2+OPcCAwEAAaNmMGQwDgYDVR0PAQH/BAQD AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEBxMBdv81xuzqcK5TVu pHj+Aor8MB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 DQEBCwUAA4IBAQBZkfiVqGoJjBI37aTlLOSjLcjI75L5wBrwO39q+B4cwcmpj58P 3sivv+jhYfAGEbQnGRzjuFoyPzWnZ1DesRExX+wrmHsLLQbF2kVjLZhEJMHF9eB7 GZlTPdTzHErcnuXkwA/OqyXMpj9aghcQFuhCNguEfnROY9sAoK2PTfnTz9NJHL+Q UpDLEJEUfc0GZMVWYhahc0x38ZnSY2SKacIPECQrTI0KpqZv/P+ijCEcMD9xmYEb jL4en+XKS1uJpw5fIU5Sj0MxhdGstH6S84iAE5J3GM3XHklGSFwwqPYvuTXvANH6 uboynxRgSae59jIlAK6Jrr6GWMwQRbgcaAlW -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEDDCCAvSgAwIBAgICEkYwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTYxOTUz NDdaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h em9uIFJEUyBhcC1zb3V0aGVhc3QtMiAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAufodI2Flker8q7PXZG0P0vmFSlhQDw907A6eJuF/WeMo GHnll3b4S6nC3oRS3nGeRMHbyU2KKXDwXNb3Mheu+ox+n5eb/BJ17eoj9HbQR1cd gEkIciiAltf8gpMMQH4anP7TD+HNFlZnP7ii3geEJB2GGXSxgSWvUzH4etL67Zmn TpGDWQMB0T8lK2ziLCMF4XAC/8xDELN/buHCNuhDpxpPebhct0T+f6Arzsiswt2j 7OeNeLLZwIZvVwAKF7zUFjC6m7/VmTQC8nidVY559D6l0UhhU0Co/txgq3HVsMOH PbxmQUwJEKAzQXoIi+4uZzHFZrvov/nDTNJUhC6DqwIDAQABo2YwZDAOBgNVHQ8B Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUwaZpaCme+EiV M5gcjeHZSTgOn4owHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ KoZIhvcNAQELBQADggEBAAR6a2meCZuXO2TF9bGqKGtZmaah4pH2ETcEVUjkvXVz sl+ZKbYjrun+VkcMGGKLUjS812e7eDF726ptoku9/PZZIxlJB0isC/0OyixI8N4M NsEyvp52XN9QundTjkl362bomPnHAApeU0mRbMDRR2JdT70u6yAzGLGsUwMkoNnw 1VR4XKhXHYGWo7KMvFrZ1KcjWhubxLHxZWXRulPVtGmyWg/MvE6KF+2XMLhojhUL +9jB3Fpn53s6KMx5tVq1x8PukHmowcZuAF8k+W4gk8Y68wIwynrdZrKRyRv6CVtR FZ8DeJgoNZT3y/GT254VqMxxfuy2Ccb/RInd16tEvVk= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEDDCCAvSgAwIBAgICOYIwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTcyMDA1 MjlaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h em9uIFJEUyBhcC1ub3J0aGVhc3QtMyAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEA4dMak8W+XW8y/2F6nRiytFiA4XLwePadqWebGtlIgyCS kbug8Jv5w7nlMkuxOxoUeD4WhI6A9EkAn3r0REM/2f0aYnd2KPxeqS2MrtdxxHw1 xoOxk2x0piNSlOz6yog1idsKR5Wurf94fvM9FdTrMYPPrDabbGqiBMsZZmoHLvA3 Z+57HEV2tU0Ei3vWeGIqnNjIekS+E06KhASxrkNU5vi611UsnYZlSi0VtJsH4UGV LhnHl53aZL0YFO5mn/fzuNG/51qgk/6EFMMhaWInXX49Dia9FnnuWXwVwi6uX1Wn 7kjoHi5VtmC8ZlGEHroxX2DxEr6bhJTEpcLMnoQMqwIDAQABo2YwZDAOBgNVHQ8B Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUsUI5Cb3SWB8+ gv1YLN/ABPMdxSAwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ KoZIhvcNAQELBQADggEBAJAF3E9PM1uzVL8YNdzb6fwJrxxqI2shvaMVmC1mXS+w G0zh4v2hBZOf91l1EO0rwFD7+fxoI6hzQfMxIczh875T6vUXePKVOCOKI5wCrDad zQbVqbFbdhsBjF4aUilOdtw2qjjs9JwPuB0VXN4/jY7m21oKEOcnpe36+7OiSPjN xngYewCXKrSRqoj3mw+0w/+exYj3Wsush7uFssX18av78G+ehKPIVDXptOCP/N7W 8iKVNeQ2QGTnu2fzWsGUSvMGyM7yqT+h1ILaT//yQS8er511aHMLc142bD4D9VSy DgactwPDTShK/PXqhvNey9v/sKXm4XatZvwcc8KYlW4= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEDDCCAvSgAwIBAgICcEUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTgxNjU2 MjBaFw0yNDA4MjIxNzA4NTBaMIGZMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEqMCgGA1UEAwwhQW1h em9uIFJEUyBhcC1ub3J0aGVhc3QtMSAyMDE5IENBMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAndtkldmHtk4TVQAyqhAvtEHSMb6pLhyKrIFved1WO3S7 +I+bWwv9b2W/ljJxLq9kdT43bhvzonNtI4a1LAohS6bqyirmk8sFfsWT3akb+4Sx 1sjc8Ovc9eqIWJCrUiSvv7+cS7ZTA9AgM1PxvHcsqrcUXiK3Jd/Dax9jdZE1e15s BEhb2OEPE+tClFZ+soj8h8Pl2Clo5OAppEzYI4LmFKtp1X/BOf62k4jviXuCSst3 UnRJzE/CXtjmN6oZySVWSe0rQYuyqRl6//9nK40cfGKyxVnimB8XrrcxUN743Vud QQVU0Esm8OVTX013mXWQXJHP2c0aKkog8LOga0vobQIDAQABo2YwZDAOBgNVHQ8B Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQULmoOS1mFSjj+ snUPx4DgS3SkLFYwHwYDVR0jBBgwFoAUc19g2LzLA5j0Kxc0LjZapmD/vB8wDQYJ KoZIhvcNAQELBQADggEBAAkVL2P1M2/G9GM3DANVAqYOwmX0Xk58YBHQu6iiQg4j b4Ky/qsZIsgT7YBsZA4AOcPKQFgGTWhe9pvhmXqoN3RYltN8Vn7TbUm/ZVDoMsrM gwv0+TKxW1/u7s8cXYfHPiTzVSJuOogHx99kBW6b2f99GbP7O1Sv3sLq4j6lVvBX Fiacf5LAWC925nvlTzLlBgIc3O9xDtFeAGtZcEtxZJ4fnGXiqEnN4539+nqzIyYq nvlgCzyvcfRAxwltrJHuuRu6Maw5AGcd2Y0saMhqOVq9KYKFKuD/927BTrbd2JVf 2sGWyuPZPCk3gq+5pCjbD0c6DkhcMGI6WwxvM5V/zSM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBzCCAu+gAwIBAgICJDQwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTgxNzAz MTVaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h em9uIFJEUyBldS13ZXN0LTMgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAL9bL7KE0n02DLVtlZ2PL+g/BuHpMYFq2JnE2RgompGurDIZdjmh 1pxfL3nT+QIVMubuAOy8InRfkRxfpxyjKYdfLJTPJG+jDVL+wDcPpACFVqoV7Prg pVYEV0lc5aoYw4bSeYFhdzgim6F8iyjoPnObjll9mo4XsHzSoqJLCd0QC+VG9Fw2 q+GDRZrLRmVM2oNGDRbGpGIFg77aRxRapFZa8SnUgs2AqzuzKiprVH5i0S0M6dWr i+kk5epmTtkiDHceX+dP/0R1NcnkCPoQ9TglyXyPdUdTPPRfKCq12dftqll+u4mV ARdN6WFjovxax8EAP2OAUTi1afY+1JFMj+sCAwEAAaNmMGQwDgYDVR0PAQH/BAQD AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLfhrbrO5exkCVgxW0x3 Y2mAi8lNMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 DQEBCwUAA4IBAQAigQ5VBNGyw+OZFXwxeJEAUYaXVoP/qrhTOJ6mCE2DXUVEoJeV SxScy/TlFA9tJXqmit8JH8VQ/xDL4ubBfeMFAIAo4WzNWDVoeVMqphVEcDWBHsI1 AETWzfsapRS9yQekOMmxg63d/nV8xewIl8aNVTHdHYXMqhhik47VrmaVEok1UQb3 O971RadLXIEbVd9tjY5bMEHm89JsZDnDEw1hQXBb67Elu64OOxoKaHBgUH8AZn/2 zFsL1ynNUjOhCSAA15pgd1vjwc0YsBbAEBPcHBWYBEyME6NLNarjOzBl4FMtATSF wWCKRGkvqN8oxYhwR2jf2rR5Mu4DWkK5Q8Ep -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBzCCAu+gAwIBAgICJVUwDQYJKoZIhvcNAQELBQAwgY8xCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSAwHgYDVQQDDBdBbWF6b24gUkRTIFJvb3QgMjAxOSBDQTAeFw0xOTA5MTkxODE2 NTNaFw0yNDA4MjIxNzA4NTBaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2Fz aGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBT ZXJ2aWNlcywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1h em9uIFJEUyB1cy1lYXN0LTEgMjAxOSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAM3i/k2u6cqbMdcISGRvh+m+L0yaSIoOXjtpNEoIftAipTUYoMhL InXGlQBVA4shkekxp1N7HXe1Y/iMaPEyb3n+16pf3vdjKl7kaSkIhjdUz3oVUEYt i8Z/XeJJ9H2aEGuiZh3kHixQcZczn8cg3dA9aeeyLSEnTkl/npzLf//669Ammyhs XcAo58yvT0D4E0D/EEHf2N7HRX7j/TlyWvw/39SW0usiCrHPKDLxByLojxLdHzso QIp/S04m+eWn6rmD+uUiRteN1hI5ncQiA3wo4G37mHnUEKo6TtTUh+sd/ku6a8HK glMBcgqudDI90s1OpuIAWmuWpY//8xEG2YECAwEAAaNmMGQwDgYDVR0PAQH/BAQD AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFPqhoWZcrVY9mU7tuemR RBnQIj1jMB8GA1UdIwQYMBaAFHNfYNi8ywOY9CsXNC42WqZg/7wfMA0GCSqGSIb3 DQEBCwUAA4IBAQB6zOLZ+YINEs72heHIWlPZ8c6WY8MDU+Be5w1M+BK2kpcVhCUK PJO4nMXpgamEX8DIiaO7emsunwJzMSvavSPRnxXXTKIc0i/g1EbiDjnYX9d85DkC E1LaAUCmCZBVi9fIe0H2r9whIh4uLWZA41oMnJx/MOmo3XyMfQoWcqaSFlMqfZM4 0rNoB/tdHLNuV4eIdaw2mlHxdWDtF4oH+HFm+2cVBUVC1jXKrFv/euRVtsTT+A6i h2XBHKxQ1Y4HgAn0jACP2QSPEmuoQEIa57bEKEcZsBR8SDY6ZdTd2HLRIApcCOSF MRM8CKLeF658I0XgF8D5EsYoKPsA+74Z+jDH -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEETCCAvmgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSUwIwYDVQQDDBxBbWF6b24gUkRTIEJldGEgUm9vdCAyMDE5IENBMB4XDTE5MDgy MDE3MTAwN1oXDTI0MDgxOTE3MzgyNlowgZkxCzAJBgNVBAYTAlVTMRMwEQYDVQQI DApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6b24g V2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMSowKAYDVQQD DCFBbWF6b24gUkRTIEJldGEgdXMtZWFzdC0xIDIwMTkgQ0EwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQDTNCOlotQcLP8TP82U2+nk0bExVuuMVOgFeVMx vbUHZQeIj9ikjk+jm6eTDnnkhoZcmJiJgRy+5Jt69QcRbb3y3SAU7VoHgtraVbxF QDh7JEHI9tqEEVOA5OvRrDRcyeEYBoTDgh76ROco2lR+/9uCvGtHVrMCtG7BP7ZB sSVNAr1IIRZZqKLv2skKT/7mzZR2ivcw9UeBBTUf8xsfiYVBvMGoEsXEycjYdf6w WV+7XS7teNOc9UgsFNN+9AhIBc1jvee5E//72/4F8pAttAg/+mmPUyIKtekNJ4gj OAR2VAzGx1ybzWPwIgOudZFHXFduxvq4f1hIRPH0KbQ/gkRrAgMBAAGjZjBkMA4G A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTkvpCD 6C43rar9TtJoXr7q8dkrrjAfBgNVHSMEGDAWgBStoQwVpbGx87fxB3dEGDqKKnBT 4TANBgkqhkiG9w0BAQsFAAOCAQEAJd9fOSkwB3uVdsS+puj6gCER8jqmhd3g/J5V Zjk9cKS8H0e8pq/tMxeJ8kpurPAzUk5RkCspGt2l0BSwmf3ahr8aJRviMX6AuW3/ g8aKplTvq/WMNGKLXONa3Sq8591J+ce8gtOX/1rDKmFI4wQ/gUzOSYiT991m7QKS Fr6HMgFuz7RNJbb3Fy5cnurh8eYWA7mMv7laiLwTNsaro5qsqErD5uXuot6o9beT a+GiKinEur35tNxAr47ax4IRubuIzyfCrezjfKc5raVV2NURJDyKP0m0CCaffAxE qn2dNfYc3v1D8ypg3XjHlOzRo32RB04o8ALHMD9LSwsYDLpMag== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEFzCCAv+gAwIBAgICFSUwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK DBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRT MSgwJgYDVQQDDB9BbWF6b24gUkRTIFByZXZpZXcgUm9vdCAyMDE5IENBMB4XDTE5 MDgyMTIyMzk0N1oXDTI0MDgyMTIyMjk0OVowgZwxCzAJBgNVBAYTAlVTMRMwEQYD VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMSIwIAYDVQQKDBlBbWF6 b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMS0wKwYD VQQDDCRBbWF6b24gUkRTIFByZXZpZXcgdXMtZWFzdC0yIDIwMTkgQ0EwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0dB/U7qRnSf05wOi7m10Pa2uPMTJv r6U/3Y17a5prq5Zr4++CnSUYarG51YuIf355dKs+7Lpzs782PIwCmLpzAHKWzix6 pOaTQ+WZ0+vUMTxyqgqWbsBgSCyP7pVBiyqnmLC/L4az9XnscrbAX4pNaoJxsuQe mzBo6yofjQaAzCX69DuqxFkVTRQnVy7LCFkVaZtjNAftnAHJjVgQw7lIhdGZp9q9 IafRt2gteihYfpn+EAQ/t/E4MnhrYs4CPLfS7BaYXBycEKC5Muj1l4GijNNQ0Efo xG8LSZz7SNgUvfVwiNTaqfLP3AtEAWiqxyMyh3VO+1HpCjT7uNBFtmF3AgMBAAGj ZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW BBQtinkdrj+0B2+qdXngV2tgHnPIujAfBgNVHSMEGDAWgBRp0xqULkNh/w2ZVzEI o2RIY7O03TANBgkqhkiG9w0BAQsFAAOCAQEAtJdqbCxDeMc8VN1/RzCabw9BIL/z 73Auh8eFTww/sup26yn8NWUkfbckeDYr1BrXa+rPyLfHpg06kwR8rBKyrs5mHwJx bvOzXD/5WTdgreB+2Fb7mXNvWhenYuji1MF+q1R2DXV3I05zWHteKX6Dajmx+Uuq Yq78oaCBSV48hMxWlp8fm40ANCL1+gzQ122xweMFN09FmNYFhwuW+Ao+Vv90ZfQG PYwTvN4n/gegw2TYcifGZC2PNX74q3DH03DXe5fvNgRW5plgz/7f+9mS+YHd5qa9 tYTPUvoRbi169ou6jicsMKUKPORHWhiTpSCWR1FMMIbsAcsyrvtIsuaGCQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQdOCSuA9psBpQd8EI368/0DANBgkqhkiG9w0BAQsFADCB lzELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdB bWF6b24gUkRTIHNhLWVhc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTE5MTgwNjI2WhgPMjA2MTA1MTkxOTA2MjZaMIGXMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpv biBSRFMgc2EtZWFzdC0xIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UEBwwHU2Vh dHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN6ftL6w8v3dB2yW LjCxSP1D7ZsOTeLZOSCz1Zv0Gkd0XLhil5MdHOHBvwH/DrXqFU2oGzCRuAy+aZis DardJU6ChyIQIciXCO37f0K23edhtpXuruTLLwUwzeEPdcnLPCX+sWEn9Y5FPnVm pCd6J8edH2IfSGoa9LdErkpuESXdidLym/w0tWG/O2By4TabkNSmpdrCL00cqI+c prA8Bx1jX8/9sY0gpAovtuFaRN+Ivg3PAnWuhqiSYyQ5nC2qDparOWuDiOhpY56E EgmTvjwqMMjNtExfYx6Rv2Ndu50TriiNKEZBzEtkekwXInTupmYTvc7U83P/959V UiQ+WSMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU4uYHdH0+ bUeh81Eq2l5/RJbW+vswDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IB AQBhxcExJ+w74bvDknrPZDRgTeMLYgbVJjx2ExH7/Ac5FZZWcpUpFwWMIJJxtewI AnhryzM3tQYYd4CG9O+Iu0+h/VVfW7e4O3joWVkxNMb820kQSEwvZfA78aItGwOY WSaFNVRyloVicZRNJSyb1UL9EiJ9ldhxm4LTT0ax+4ontI7zTx6n6h8Sr6r/UOvX d9T5aUUENWeo6M9jGupHNn3BobtL7BZm2oS8wX8IVYj4tl0q5T89zDi2x0MxbsIV 5ZjwqBQ5JWKv7ASGPb+z286RjPA9R2knF4lJVZrYuNV90rHvI/ECyt/JrDqeljGL BLl1W/UsvZo6ldLIpoMbbrb5 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBDCCAuygAwIBAgIQUfVbqapkLYpUqcLajpTJWzANBgkqhkiG9w0BAQsFADCB mjELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTMwMQYDVQQDDCpB bWF6b24gUkRTIG1lLWNlbnRyYWwtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNV BAcMB1NlYXR0bGUwIBcNMjIwNTA2MjMyMDA5WhgPMjA2MjA1MDcwMDIwMDlaMIGa MQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5j LjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMzAxBgNVBAMMKkFt YXpvbiBSRFMgbWUtY2VudHJhbC0xIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UE BwwHU2VhdHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJIeovu3 ewI9FVitXMQzvkh34aQ6WyI4NO3YepfJaePiv3cnyFGYHN2S1cR3UQcLWgypP5va j6bfroqwGbCbZZcb+6cyOB4ceKO9Ws1UkcaGHnNDcy5gXR7aCW2OGTUfinUuhd2d 5bOGgV7JsPbpw0bwJ156+MwfOK40OLCWVbzy8B1kITs4RUPNa/ZJnvIbiMu9rdj4 8y7GSFJLnKCjlOFUkNI5LcaYvI1+ybuNgphT3nuu5ZirvTswGakGUT/Q0J3dxP0J pDfg5Sj/2G4gXiaM0LppVOoU5yEwVewhQ250l0eQAqSrwPqAkdTg9ng360zqCFPE JPPcgI1tdGUgneECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU /2AJVxWdZxc8eJgdpbwpW7b0f7IwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB CwUAA4IBAQBYm63jTu2qYKJ94gKnqc+oUgqmb1mTXmgmp/lXDbxonjszJDOXFbri 3CCO7xB2sg9bd5YWY8sGKHaWmENj3FZpCmoefbUx++8D7Mny95Cz8R32rNcwsPTl ebpd9A/Oaw5ug6M0x/cNr0qzF8Wk9Dx+nFEimp8RYQdKvLDfNFZHjPa1itnTiD8M TorAqj+VwnUGHOYBsT/0NY12tnwXdD+ATWfpEHdOXV+kTMqFFwDyhfgRVNpTc+os ygr8SwhnSCpJPB/EYl2S7r+tgAbJOkuwUvGT4pTqrzDQEhwE7swgepnHC87zhf6l qN6mVpSnQKQLm6Ob5TeCEFgcyElsF5bH -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjSgAwIBAgIRAOxu0I1QuMAhIeszB3fJIlkwCgYIKoZIzj0EAwMwgZYx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1h em9uIFJEUyB1cy13ZXN0LTIgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTI0MjIwNjU5WhgPMjEyMTA1MjQyMzA2NTlaMIGWMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExLzAtBgNVBAMMJkFtYXpvbiBS RFMgdXMtd2VzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdTZWF0dGxl MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEz4bylRcGqqDWdP7gQIIoTHdBK6FNtKH1 4SkEIXRXkYDmRvL9Bci1MuGrwuvrka5TDj4b7e+csY0llEzHpKfq6nJPFljoYYP9 uqHFkv77nOpJJ633KOr8IxmeHW5RXgrZo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBQQikVz8wmjd9eDFRXzBIU8OseiGzAOBgNVHQ8BAf8EBAMCAYYwCgYI KoZIzj0EAwMDaAAwZQIwf06Mcrpw1O0EBLBBrp84m37NYtOkE/0Z0O+C7D41wnXi EQdn6PXUVgdD23Gj82SrAjEAklhKs+liO1PtN15yeZR1Io98nFve+lLptaLakZcH +hfFuUtCqMbaI8CdvJlKnPqT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGCTCCA/GgAwIBAgIRALyWMTyCebLZOGcZZQmkmfcwDQYJKoZIhvcNAQEMBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1ub3J0aGVhc3QtMyBSb290IENBIFJTQTQwOTYgRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTI0MjAyODAzWhgPMjEyMTA1MjQyMTI4MDNa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtbm9ydGhlYXN0LTMgUm9vdCBDQSBSU0E0MDk2IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA wGFiyDyCrGqgdn4fXG12cxKAAfVvhMea1mw5h9CVRoavkPqhzQpAitSOuMB9DeiP wQyqcsiGl/cTEau4L+AUBG8b9v26RlY48exUYBXj8CieYntOT9iNw5WtdYJa3kF/ JxgI+HDMzE9cmHDs5DOO3S0uwZVyra/xE1ymfSlpOeUIOTpHRJv97CBUEpaZMUW5 Sr6GruuOwFVpO5FX3A/jQlcS+UN4GjSRgDUJuqg6RRQldEZGCVCCmodbByvI2fGm reGpsPJD54KkmAX08nOR8e5hkGoHxq0m2DLD4SrOFmt65vG47qnuwplWJjtk9B3Z 9wDoopwZLBOtlkPIkUllWm1P8EuHC1IKOA+wSP6XdT7cy8S77wgyHzR0ynxv7q/l vlZtH30wnNqFI0y9FeogD0TGMCHcnGqfBSicJXPy9T4fU6f0r1HwqKwPp2GArwe7 dnqLTj2D7M9MyVtFjEs6gfGWXmu1y5uDrf+CszurE8Cycoma+OfjjuVQgWOCy7Nd jJswPxAroTzVfpgoxXza4ShUY10woZu0/J+HmNmqK7lh4NS75q1tz75in8uTZDkV be7GK+SEusTrRgcf3tlgPjSTWG3veNzFDF2Vn1GLJXmuZfhdlVQDBNXW4MNREExS dG57kJjICpT+r8X+si+5j51gRzkSnMYs7VHulpxfcwECAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQU4JWOpDBmUBuWKvGPZelw87ezhL8wDgYDVR0P AQH/BAQDAgGGMA0GCSqGSIb3DQEBDAUAA4ICAQBRNLMql7itvXSEFQRAnyOjivHz l5IlWVQjAbOUr6ogZcwvK6YpxNAFW5zQr8F+fdkiypLz1kk5irx9TIpff0BWC9hQ /odMPO8Gxn8+COlSvc+dLsF2Dax3Hvz0zLeKMo+cYisJOzpdR/eKd0/AmFdkvQoM AOK9n0yYvVJU2IrSgeJBiiCarpKSeAktEVQ4rvyacQGr+QAPkkjRwm+5LHZKK43W nNnggRli9N/27qYtc5bgr3AaQEhEXMI4RxPRXCLsod0ehMGWyRRK728a+6PMMJAJ WHOU0x7LCEMPP/bvpLj3BdvSGqNor4ZtyXEbwREry1uzsgODeRRns5acPwTM6ff+ CmxO2NZ0OktIUSYRmf6H/ZFlZrIhV8uWaIwEJDz71qvj7buhQ+RFDZ9CNL64C0X6 mf0zJGEpddjANHaaVky+F4gYMtEy2K2Lcm4JGTdyIzUoIe+atzCnRp0QeIcuWtF+ s8AjDYCVFNypcMmqbRmNpITSnOoCHSRuVkY3gutVoYyMLbp8Jm9SJnCIlEWTA6Rm wADOMGZJVn5/XRTRuetVOB3KlQDjs9OO01XN5NzGSZO2KT9ngAUfh9Eqhf1iRWSP nZlRbQ2NRCuY/oJ5N59mLGxnNJSE7giEKEBRhTQ/XEPIUYAUPD5fca0arKRJwbol l9Se1Hsq0ZU5f+OZKQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 5zT5+Bs= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 Hing -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIRANxgyBbnxgTEOpDul2ZnC0UwDQYJKoZIhvcNAQELBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtMyBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNjEwMTgxOTA3WhgPMjA2MTA2MTAxOTE5MDda MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtc291dGhlYXN0LTMgUm9vdCBDQSBSU0EyMDQ4IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA xnwSDAChrMkfk5TA4Dk8hKzStDlSlONzmd3fTG0Wqr5+x3EmFT6Ksiu/WIwEl9J2 K98UI7vYyuZfCxUKb1iMPeBdVGqk0zb92GpURd+Iz/+K1ps9ZLeGBkzR8mBmAi1S OfpwKiTBzIv6E8twhEn4IUpHsdcuX/2Y78uESpJyM8O5CpkG0JaV9FNEbDkJeBUQ Ao2qqNcH4R0Qcr5pyeqA9Zto1RswgL06BQMI9dTpfwSP5VvkvcNUaLl7Zv5WzLQE JzORWePvdPzzvWEkY/3FPjxBypuYwssKaERW0fkPDmPtykktP9W/oJolKUFI6pXp y+Y6p6/AVdnQD2zZjW5FhQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBT+jEKs96LC+/X4BZkUYUkzPfXdqTAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI hvcNAQELBQADggEBAIGQqgqcQ6XSGkmNebzR6DhadTbfDmbYeN5N0Vuzv+Tdmufb tMGjdjnYMg4B+IVnTKQb+Ox3pL9gbX6KglGK8HupobmIRtwKVth+gYYz3m0SL/Nk haWPYzOm0x3tJm8jSdufJcEob4/ATce9JwseLl76pSWdl5A4lLjnhPPKudUDfH+1 BLNUi3lxpp6GkC8aWUPtupnhZuXddolTLOuA3GwTZySI44NfaFRm+o83N1jp+EwD 6e94M4cTRzjUv6J3MZmSbdtQP/Tk1uz2K4bQZGP0PZC3bVpqiesdE/xr+wbu8uHr cM1JXH0AmXf1yIkTgyWzmvt0k1/vgcw5ixAqvvE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEATCCAumgAwIBAgIRAMhw98EQU18mIji+unM2YH8wDQYJKoZIhvcNAQELBQAw gZgxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTExMC8GA1UEAwwo QW1hem9uIFJEUyBhcC1zb3V0aC0yIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UE BwwHU2VhdHRsZTAgFw0yMjA2MDYyMTQyMjJaGA8yMDYyMDYwNjIyNDIyMlowgZgx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTExMC8GA1UEAwwoQW1h em9uIFJEUyBhcC1zb3V0aC0yIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UEBwwH U2VhdHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIeeRoLfTm+7 vqm7ZlFSx+1/CGYHyYrOOryM4/Z3dqYVHFMgWTR7V3ziO8RZ6yUanrRcWVX3PZbF AfX0KFE8OgLsXEZIX8odSrq86+/Th5eZOchB2fDBsUB7GuN2rvFBbM8lTI9ivVOU lbuTnYyb55nOXN7TpmH2bK+z5c1y9RVC5iQsNAl6IJNvSN8VCqXh31eK5MlKB4DT +Y3OivCrSGsjM+UR59uZmwuFB1h+icE+U0p9Ct3Mjq3MzSX5tQb6ElTNGlfmyGpW Kh7GQ5XU1KaKNZXoJ37H53woNSlq56bpVrKI4uv7ATpdpFubOnSLtpsKlpLdR3sy Ws245200pC8CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUp0ki 6+eWvsnBjQhMxwMW5pwn7DgwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUA A4IBAQB2V8lv0aqbYQpj/bmVv/83QfE4vOxKCJAHv7DQ35cJsTyBdF+8pBczzi3t 3VNL5IUgW6WkyuUOWnE0eqAFOUVj0yTS1jSAtfl3vOOzGJZmWBbqm9BKEdu1D8O6 sB8bnomwiab2tNDHPmUslpdDqdabbkWwNWzLJ97oGFZ7KNODMEPXWKWNxg33iHfS /nlmnrTVI3XgaNK9qLZiUrxu9Yz5gxi/1K+sG9/Dajd32ZxjRwDipOLiZbiXQrsd qzIMY4GcWf3g1gHL5mCTfk7dG22h/rhPyGV0svaDnsb+hOt6sv1McMN6Y3Ou0mtM /UaAXojREmJmTSCNvs2aBny3/2sy -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjSgAwIBAgIRAMnRxsKLYscJV8Qv5pWbL7swCgYIKoZIzj0EAwMwgZYx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1h em9uIFJEUyBzYS1lYXN0LTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTE5MTgxNjAxWhgPMjEyMTA1MTkxOTE2MDFaMIGWMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExLzAtBgNVBAMMJkFtYXpvbiBS RFMgc2EtZWFzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdTZWF0dGxl MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEjFOCZgTNVKxLKhUxffiDEvTLFhrmIqdO dKqVdgDoELEzIHWDdC+19aDPitbCYtBVHl65ITu/9pn6mMUl5hhUNtfZuc6A+Iw1 sBe0v0qI3y9Q9HdQYrGgeHDh8M5P7E2ho0IwQDAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBS5L7/8M0TzoBZk39Ps7BkfTB4yJTAOBgNVHQ8BAf8EBAMCAYYwCgYI KoZIzj0EAwMDaAAwZQIwI43O0NtWKTgnVv9z0LO5UMZYgSve7GvGTwqktZYCMObE rUI4QerXM9D6JwLy09mqAjEAypfkdLyVWtaElVDUyHFkihAS1I1oUxaaDrynLNQK Ou/Ay+ns+J+GyvyDUjBpVVW1 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF/jCCA+agAwIBAgIQR71Z8lTO5Sj+as2jB7IWXzANBgkqhkiG9w0BAQwFADCB lzELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdB bWF6b24gUkRTIHVzLXdlc3QtMiBSb290IENBIFJTQTQwOTYgRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTI0MjIwMzIwWhgPMjEyMTA1MjQyMzAzMjBaMIGXMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpv biBSRFMgdXMtd2VzdC0yIFJvb3QgQ0EgUlNBNDA5NiBHMTEQMA4GA1UEBwwHU2Vh dHRsZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM977bHIs1WJijrS XQMfUOhmlJjr2v0K0UjPl52sE1TJ76H8umo1yR4T7Whkd9IwBHNGKXCJtJmMr9zp fB38eLTu+5ydUAXdFuZpRMKBWwPVe37AdJRKqn5beS8HQjd3JXAgGKUNNuE92iqF qi2fIqFMpnJXWo0FIW6s2Dl2zkORd7tH0DygcRi7lgVxCsw1BJQhFJon3y+IV8/F bnbUXSNSDUnDW2EhvWSD8L+t4eiXYsozhDAzhBvojpxhPH9OB7vqFYw5qxFx+G0t lSLX5iWi1jzzc3XyGnB6WInZDVbvnvJ4BGZ+dTRpOCvsoMIn9bz4EQTvu243c7aU HbS/kvnCASNt+zk7C6lbmaq0AGNztwNj85Opn2enFciWZVnnJ/4OeefUWQxD0EPp SjEd9Cn2IHzkBZrHCg+lWZJQBKbUVS0lLIMSsLQQ6WvR38jY7D2nxM1A93xWxwpt ZtQnYRCVXH6zt2OwDAFePInWwxUjR5t/wu3XxPgpSfrmTi3WYtr1wFypAJ811e/P yBtswWUQ6BNJQvy+KnOEeGfOwmtdDFYR+GOCfvCihzrKJrxOtHIieehR5Iw3cbXG sm4pDzfMUVvDDz6C2M6PRlJhhClbatHCjik9hxFYEsAlqtVVK9pxaz9i8hOqSFQq kJSQsgWw+oM/B2CyjcSqkSQEu8RLAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8w HQYDVR0OBBYEFPmrdxpRRgu3IcaB5BTqlprcKdTsMA4GA1UdDwEB/wQEAwIBhjAN BgkqhkiG9w0BAQwFAAOCAgEAVdlxWjPvVKky3kn8ZizeM4D+EsLw9dWLau2UD/ls zwDCFoT6euagVeCknrn+YEl7g20CRYT9iaonGoMUPuMR/cdtPL1W/Rf40PSrGf9q QuxavWiHLEXOQTCtCaVZMokkvjuuLNDXyZnstgECuiZECTwhexUF4oiuhyGk9o01 QMaiz4HX4lgk0ozALUvEzaNd9gWEwD2qe+rq9cQMTVq3IArUkvTIftZUaVUMzr0O ed1+zAsNa9nJhURJ/6anJPJjbQgb5qA1asFcp9UaMT1ku36U3gnR1T/BdgG2jX3X Um0UcaGNVPrH1ukInWW743pxWQb7/2sumEEMVh+jWbB18SAyLI4WIh4lkurdifzS IuTFp8TEx+MouISFhz/vJDWZ84tqoLVjkEcP6oDypq9lFoEzHDJv3V1CYcIgOusT k1jm9P7BXdTG7TYzUaTb9USb6bkqkD9EwJAOSs7DI94aE6rsSws2yAHavjAMfuMZ sDAZvkqS2Qg2Z2+CI6wUZn7mzkJXbZoqRjDvChDXEB1mIhzVXhiNW/CR5WKVDvlj 9v1sdGByh2pbxcLQtVaq/5coM4ANgphoNz3pOYUPWHS+JUrIivBZ+JobjXcxr3SN 9iDzcu5/FVVNbq7+KN/nvPMngT+gduEN5m+EBjm8GukJymFG0m6BENRA0QSDqZ7k zDY= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIRAK5EYG3iHserxMqgg+0EFjgwDQYJKoZIhvcNAQELBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1ub3J0aGVhc3QtMyBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTI0MjAyMzE2WhgPMjA2MTA1MjQyMTIzMTZa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtbm9ydGhlYXN0LTMgUm9vdCBDQSBSU0EyMDQ4IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA s1L6TtB84LGraLHVC+rGPhLBW2P0oN/91Rq3AnYwqDOuTom7agANwEjvLq7dSRG/ sIfZsSV/ABTgArZ5sCmLjHFZAo8Kd45yA9byx20RcYtAG8IZl+q1Cri+s0XefzyO U6mlfXZkVe6lzjlfXBkrlE/+5ifVbJK4dqOS1t9cWIpgKqv5fbE6Qbq4LVT+5/WM Vd2BOljuBMGMzdZubqFKFq4mzTuIYfnBm7SmHlZfTdfBYPP1ScNuhpjuzw4n3NCR EdU6dQv04Q6th4r7eiOCwbWI9LkmVbvBe3ylhH63lApC7MiiPYLlB13xBubVHVhV q1NHoNTi+zA3MN9HWicRxQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBSuxoqm0/wjNiZLvqv+JlQwsDvTPDAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI hvcNAQELBQADggEBAFfTK/j5kv90uIbM8VaFdVbr/6weKTwehafT0pAk1bfLVX+7 uf8oHgYiyKTTl0DFQicXejghXTeyzwoEkWSR8c6XkhD5vYG3oESqmt/RGvvoxz11 rHHy7yHYu7RIUc3VQG60c4qxXv/1mWySGwVwJrnuyNT9KZXPevu3jVaWOVHEILaK HvzQ2YEcWBPmde/zEseO2QeeGF8FL45Q1d66wqIP4nNUd2pCjeTS5SpB0MMx7yi9 ki1OH1pv8tOuIdimtZ7wkdB8+JSZoaJ81b8sRrydRwJyvB88rftuI3YB4WwGuONT ZezUPsmaoK69B0RChB0ofDpAaviF9V3xOWvVZfo= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 1axqeKpI0F5SBUPsaVNYY2uNFg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECDCCAvCgAwIBAgIQCREfzzVyDTMcNME+gWnTCTANBgkqhkiG9w0BAQsFADCB nDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTUwMwYDVQQDDCxB bWF6b24gUkRTIGFwLXNvdXRoZWFzdC0yIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4G A1UEBwwHU2VhdHRsZTAgFw0yMTA1MjQyMDQyMzNaGA8yMDYxMDUyNDIxNDIzM1ow gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtMiBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDL 1MT6br3L/4Pq87DPXtcjlXN3cnbNk2YqRAZHJayStTz8VtsFcGPJOpk14geRVeVk e9uKFHRbcyr/RM4owrJTj5X4qcEuATYZbo6ou/rW2kYzuWFZpFp7lqm0vasV4Z9F fChlhwkNks0UbM3G+psCSMNSoF19ERunj7w2c4E62LwujkeYLvKGNepjnaH10TJL 2krpERd+ZQ4jIpObtRcMH++bTrvklc+ei8W9lqrVOJL+89v2piN3Ecdd389uphst qQdb1BBVXbhUrtuGHgVf7zKqN1SkCoktoWxVuOprVWhSvr7akaWeq0UmlvbEsujU vADqxGMcJFyCzxx3CkJjAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O BBYEFFk8UJmlhoxFT3PP12PvhvazHjT4MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG 9w0BAQsFAAOCAQEAfFtr2lGoWVXmWAsIo2NYre7kzL8Xb9Tx7desKxCCz5HOOvIr 8JMB1YK6A7IOvQsLJQ/f1UnKRh3X3mJZjKIywfrMSh0FiDf+rjcEzXxw2dGtUem4 A+WMvIA3jwxnJ90OQj5rQ8bg3iPtE6eojzo9vWQGw/Vu48Dtw1DJo9210Lq/6hze hPhNkFh8fMXNT7Q1Wz/TJqJElyAQGNOXhyGpHKeb0jHMMhsy5UNoW5hLeMS5ffao TBFWEJ1gVfxIU9QRxSh+62m46JIg+dwDlWv8Aww14KgepspRbMqDuaM2cinoejv6 t3dyOyHHrsOyv3ffZUKtQhQbQr+sUcL89lARsg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/zCCAuegAwIBAgIRAIJLTMpzGNxqHZ4t+c1MlCIwDQYJKoZIhvcNAQELBQAw gZcxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwn QW1hem9uIFJEUyBhcC1lYXN0LTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyNTIxMzAzM1oYDzIwNjEwNTI1MjIzMDMzWjCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGFwLWVhc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcMB1Nl YXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtdHut0ZhJ9Nn2 MpVafFcwHdoEzx06okmmhjJsNy4l9QYVeh0UUoek0SufRNMRF4d5ibzpgZol0Y92 /qKWNe0jNxhEj6sXyHsHPeYtNBPuDMzThfbvsLK8z7pBP7vVyGPGuppqW/6m4ZBB lcc9fsf7xpZ689iSgoyjiT6J5wlVgmCx8hFYc/uvcRtfd8jAHvheug7QJ3zZmIye V4htOW+fRVWnBjf40Q+7uTv790UAqs0Zboj4Yil+hER0ibG62y1g71XcCyvcVpto 2/XW7Y9NCgMNqQ7fGN3wR1gjtSYPd7DO32LTzYhutyvfbpAZjsAHnoObmoljcgXI QjfBcCFpAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJI3aWLg CS5xqU5WYVaeT5s8lpO0MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC AQEAUwATpJOcGVOs3hZAgJwznWOoTzOVJKfrqBum7lvkVH1vBwxBl9CahaKj3ZOt YYp2qJzhDUWludL164DL4ZjS6eRedLRviyy5cRy0581l1MxPWTThs27z+lCC14RL PJZNVYYdl7Jy9Q5NsQ0RBINUKYlRY6OqGDySWyuMPgno2GPbE8aynMdKP+f6G/uE YHOf08gFDqTsbyfa70ztgVEJaRooVf5JJq4UQtpDvVswW2reT96qi6tXPKHN5qp3 3wI0I1Mp4ePmiBKku2dwYzPfrJK/pQlvu0Gu5lKOQ65QdotwLAAoaFqrf9za1yYs INUkHLWIxDds+4OHNYcerGp5Dw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGCTCCA/GgAwIBAgIRAIO6ldra1KZvNWJ0TA1ihXEwDQYJKoZIhvcNAQEMBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtMSBSb290IENBIFJTQTQwOTYgRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTIxMjE0NTA1WhgPMjEyMTA1MjEyMjQ1MDVa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtc291dGhlYXN0LTEgUm9vdCBDQSBSU0E0MDk2IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA sDN52Si9pFSyZ1ruh3xAN0nVqEs960o2IK5CPu/ZfshFmzAwnx/MM8EHt/jMeZtj SM58LADAsNDL01ELpFZATjgZQ6xNAyXRXE7RiTRUvNkK7O3o2qAGbLnJq/UqF7Sw LRnB8V6hYOv+2EjVnohtGCn9SUFGZtYDjWXsLd4ML4Zpxv0a5LK7oEC7AHzbUR7R jsjkrXqSv7GE7bvhSOhMkmgxgj1F3J0b0jdQdtyyj109aO0ATUmIvf+Bzadg5AI2 A9UA+TUcGeebhpHu8AP1Hf56XIlzPpaQv3ZJ4vzoLaVNUC7XKzAl1dlvCl7Klg/C 84qmbD/tjZ6GHtzpLKgg7kQEV7mRoXq8X4wDX2AFPPQl2fv+Kbe+JODqm5ZjGegm uskABBi8IFv1hYx9jEulZPxC6uD/09W2+niFm3pirnlWS83BwVDTUBzF+CooUIMT jhWkIIZGDDgMJTzouBHfoSJtS1KpUZi99m2WyVs21MNKHeWAbs+zmI6TO5iiMC+T uB8spaOiHFO1573Fmeer4sy3YA6qVoqVl6jjTQqOdy3frAMbCkwH22/crV8YA+08 hLeHXrMK+6XUvU+EtHAM3VzcrLbuYJUI2XJbzTj5g0Eb8I8JWsHvWHR5K7Z7gceR 78AzxQmoGEfV6KABNWKsgoCQnfb1BidDJIe3BsI0A6UCAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQUABp0MlB14MSHgAcuNSOhs3MOlUcwDgYDVR0P AQH/BAQDAgGGMA0GCSqGSIb3DQEBDAUAA4ICAQCv4CIOBSQi/QR9NxdRgVAG/pAh tFJhV7OWb/wqwsNKFDtg6tTxwaahdCfWpGWId15OUe7G9LoPiKiwM9C92n0ZeHRz 4ewbrQVo7Eu1JI1wf0rnZJISL72hVYKmlvaWaacHhWxvsbKLrB7vt6Cknxa+S993 Kf8i2Psw8j5886gaxhiUtzMTBwoDWak8ZaK7m3Y6C6hXQk08+3pnIornVSFJ9dlS PAqt5UPwWmrEfF+0uIDORlT+cvrAwgSp7nUF1q8iasledycZ/BxFgQqzNwnkBDwQ Z/aM52ArGsTzfMhkZRz9HIEhz1/0mJw8gZtDVQroD8778h8zsx2SrIz7eWQ6uWsD QEeSWXpcheiUtEfzkDImjr2DLbwbA23c9LoexUD10nwohhoiQQg77LmvBVxeu7WU E63JqaYUlOLOzEmNJp85zekIgR8UTkO7Gc+5BD7P4noYscI7pPOL5rP7YLg15ZFi ega+G53NTckRXz4metsd8XFWloDjZJJq4FfD60VuxgXzoMNT9wpFTNSH42PR2s9L I1vcl3w8yNccs9se2utM2nLsItZ3J0m/+QSRiw9hbrTYTcM9sXki0DtH2kyIOwYf lOrGJDiYOIrXSQK36H0gQ+8omlrUTvUj4msvkXuQjlfgx6sgp2duOAfnGxE7uHnc UhnJzzoe6M+LfGHkVQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICuDCCAj2gAwIBAgIQSAG6j2WHtWUUuLGJTPb1nTAKBggqhkjOPQQDAzCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLW5vcnRoZWFzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyMDE2MzgyNloYDzIxMjEwNTIwMTczODI2WjCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLW5vcnRoZWFzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE2eqwU4FOzW8RV1W381Bd olhDOrqoMqzWli21oDUt7y8OnXM/lmAuOS6sr8Nt61BLVbONdbr+jgCYw75KabrK ZGg3siqvMOgabIKkKuXO14wtrGyGDt7dnKXg5ERGYOZlo0IwQDAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBS1Acp2WYxOcblv5ikZ3ZIbRCCW+zAOBgNVHQ8BAf8E BAMCAYYwCgYIKoZIzj0EAwMDaQAwZgIxAJL84J08PBprxmsAKPTotBuVI3MyW1r8 xQ0i8lgCQUf8GcmYjQ0jI4oZyv+TuYJAcwIxAP9Xpzq0Docxb+4N1qVhpiOfWt1O FnemFiy9m1l+wv6p3riQMPV7mBVpklmijkIv3Q== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIRALZLcqCVIJ25maDPE3sbPCIwDQYJKoZIhvcNAQELBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTIxMjEzOTM5WhgPMjA2MTA1MjEyMjM5Mzla MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtc291dGhlYXN0LTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ypKc+6FfGx6Gl6fQ78WYS29QoKgQiur58oxR3zltWeg5fqh9Z85K5S3UbRSTqWWu Xcfnkz0/FS07qHX+nWAGU27JiQb4YYqhjZNOAq8q0+ptFHJ6V7lyOqXBq5xOzO8f +0DlbJSsy7GEtJp7d7QCM3M5KVY9dENVZUKeJwa8PC5StvwPx4jcLeZRJC2rAVDG SW7NAInbATvr9ssSh03JqjXb+HDyywiqoQ7EVLtmtXWimX+0b3/2vhqcH5jgcKC9 IGFydrjPbv4kwMrKnm6XlPZ9L0/3FMzanXPGd64LQVy51SI4d5Xymn0Mw2kMX8s6 Nf05OsWcDzJ1n6/Q1qHSxQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBRmaIc8eNwGP7i6P7AJrNQuK6OpFzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI hvcNAQELBQADggEBAIBeHfGwz3S2zwIUIpqEEI5/sMySDeS+3nJR+woWAHeO0C8i BJdDh+kzzkP0JkWpr/4NWz84/IdYo1lqASd1Kopz9aT1+iROXaWr43CtbzjXb7/X Zv7eZZFC8/lS5SROq42pPWl4ekbR0w8XGQElmHYcWS41LBfKeHCUwv83ATF0XQ6I 4t+9YSqZHzj4vvedrvcRInzmwWJaal9s7Z6GuwTGmnMsN3LkhZ+/GD6oW3pU/Pyh EtWqffjsLhfcdCs3gG8x9BbkcJPH5aPAVkPn4wc8wuXg6xxb9YGsQuY930GWTYRf schbgjsuqznW4HHakq4WNhs1UdTSTKkRdZz7FUQ= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIRAM2zAbhyckaqRim63b+Tib8wDQYJKoZIhvcNAQELBQAw gZ8xCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE4MDYGA1UEAwwv QW1hem9uIFJEUyBQcmV2aWV3IHVzLWVhc3QtMiBSb290IENBIFJTQTIwNDggRzEx EDAOBgNVBAcMB1NlYXR0bGUwIBcNMjEwNTE4MjA0OTQ1WhgPMjA2MTA1MTgyMTQ5 NDVaMIGfMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExODA2BgNV BAMML0FtYXpvbiBSRFMgUHJldmlldyB1cy1lYXN0LTIgUm9vdCBDQSBSU0EyMDQ4 IEcxMRAwDgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEA1ybjQMH1MkbvfKsWJaCTXeCSN1SG5UYid+Twe+TjuSqaXWonyp4WRR5z tlkqq+L2MWUeQQAX3S17ivo/t84mpZ3Rla0cx39SJtP3BiA2BwfUKRjhPwOjmk7j 3zrcJjV5k1vSeLNOfFFSlwyDiVyLAE61lO6onBx+cRjelu0egMGq6WyFVidTdCmT Q9Zw3W6LTrnPvPmEyjHy2yCHzH3E50KSd/5k4MliV4QTujnxYexI2eR8F8YQC4m3 DYjXt/MicbqA366SOoJA50JbgpuVv62+LSBu56FpzY12wubmDZsdn4lsfYKiWxUy uc83a2fRXsJZ1d3whxrl20VFtLFHFQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/ MB0GA1UdDgQWBBRC0ytKmDYbfz0Bz0Psd4lRQV3aNTAOBgNVHQ8BAf8EBAMCAYYw DQYJKoZIhvcNAQELBQADggEBAGv8qZu4uaeoF6zsbumauz6ea6tdcWt+hGFuwGrb tRbI85ucAmVSX06x59DJClsb4MPhL1XmqO3RxVMIVVfRwRHWOsZQPnXm8OYQ2sny rYuFln1COOz1U/KflZjgJmxbn8x4lYiTPZRLarG0V/OsCmnLkQLPtEl/spMu8Un7 r3K8SkbWN80gg17Q8EV5mnFwycUx9xsTAaFItuG0en9bGsMgMmy+ZsDmTRbL+lcX Fq8r4LT4QjrFz0shrzCwuuM4GmcYtBSxlacl+HxYEtAs5k10tmzRf6OYlY33tGf6 1tkYvKryxDPF/EDgGp/LiBwx6ixYMBfISoYASt4V/ylAlHA= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtTCCAjqgAwIBAgIRAK9BSZU6nIe6jqfODmuVctYwCgYIKoZIzj0EAwMwgZkx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEyMDAGA1UEAwwpQW1h em9uIFJEUyBjYS1jZW50cmFsLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTIxMjIxMzA5WhgPMjEyMTA1MjEyMzEzMDlaMIGZMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMjAwBgNVBAMMKUFtYXpv biBSRFMgY2EtY2VudHJhbC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEUkEERcgxneT5H+P+fERcbGmf bVx+M7rNWtgWUr6w+OBENebQA9ozTkeSg4c4M+qdYSObFqjxITdYxT1z/nHz1gyx OKAhLjWu+nkbRefqy3RwXaWT680uUaAP6ccnkZOMo0IwQDAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBSN6fxlg0s5Wny08uRBYZcQ3TUoyzAOBgNVHQ8BAf8EBAMC AYYwCgYIKoZIzj0EAwMDaQAwZgIxAORaz+MBVoFBTmZ93j2G2vYTwA6T5hWzBWrx CrI54pKn5g6At56DBrkjrwZF5T1enAIxAJe/LZ9xpDkAdxDgGJFN8gZYLRWc0NRy Rb4hihy5vj9L+w9uKc9VfEBIFuhT7Z3ljg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIQB/57HSuaqUkLaasdjxUdPjANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChB bWF6b24gUkRTIGFwLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUxOTE3NDAzNFoYDzIwNjEwNTE5MTg0MDM0WjCBmDEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChBbWF6 b24gUkRTIGFwLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtbkaoVsUS76o TgLFmcnaB8cswBk1M3Bf4IVRcwWT3a1HeJSnaJUqWHCJ+u3ip/zGVOYl0gN1MgBb MuQRIJiB95zGVcIa6HZtx00VezDTr3jgGWRHmRjNVCCHGmxOZWvJjsIE1xavT/1j QYV/ph4EZEIZ/qPq7e3rHohJaHDe23Z7QM9kbyqp2hANG2JtU/iUhCxqgqUHNozV Zd0l5K6KnltZQoBhhekKgyiHqdTrH8fWajYl5seD71bs0Axowb+Oh0rwmrws3Db2 Dh+oc2PwREnjHeca9/1C6J2vhY+V0LGaJmnnIuOANrslx2+bgMlyhf9j0Bv8AwSi dSWsobOhNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQb7vJT VciLN72yJGhaRKLn6Krn2TAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD ggEBAAxEj8N9GslReAQnNOBpGl8SLgCMTejQ6AW/bapQvzxrZrfVOZOYwp/5oV0f 9S1jcGysDM+DrmfUJNzWxq2Y586R94WtpH4UpJDGqZp+FuOVJL313te4609kopzO lDdmd+8z61+0Au93wB1rMiEfnIMkOEyt7D2eTFJfJRKNmnPrd8RjimRDlFgcLWJA 3E8wca67Lz/G0eAeLhRHIXv429y8RRXDtKNNz0wA2RwURWIxyPjn1fHjA9SPDkeW E1Bq7gZj+tBnrqz+ra3yjZ2blss6Ds3/uRY6NYqseFTZWmQWT7FolZEnT9vMUitW I0VynUbShVpGf6946e0vgaaKw20= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQGyUVTaVjYJvWhroVEiHPpDANBgkqhkiG9w0BAQsFADCB lzELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdB bWF6b24gUkRTIHVzLXdlc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTE5MTkwNDA2WhgPMjA2MTA1MTkyMDA0MDZaMIGXMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpv biBSRFMgdXMtd2VzdC0xIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UEBwwHU2Vh dHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANhyXpJ0t4nigRDZ EwNtFOem1rM1k8k5XmziHKDvDk831p7QsX9ZOxl/BT59Pu/P+6W6SvasIyKls1sW FJIjFF+6xRQcpoE5L5evMgN/JXahpKGeQJPOX9UEXVW5B8yi+/dyUitFT7YK5LZA MqWBN/LtHVPa8UmE88RCDLiKkqiv229tmwZtWT7nlMTTCqiAHMFcryZHx0pf9VPh x/iPV8p2gBJnuPwcz7z1kRKNmJ8/cWaY+9w4q7AYlAMaq/rzEqDaN2XXevdpsYAK TMMj2kji4x1oZO50+VPNfBl5ZgJc92qz1ocF95SAwMfOUsP8AIRZkf0CILJYlgzk /6u6qZECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm5jfcS9o +LwL517HpB6hG+PmpBswDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IB AQAcQ6lsqxi63MtpGk9XK8mCxGRLCad51+MF6gcNz6i6PAqhPOoKCoFqdj4cEQTF F8dCfa3pvfJhxV6RIh+t5FCk/y6bWT8Ls/fYKVo6FhHj57bcemWsw/Z0XnROdVfK Yqbc7zvjCPmwPHEqYBhjU34NcY4UF9yPmlLOL8uO1JKXa3CAR0htIoW4Pbmo6sA4 6P0co/clW+3zzsQ92yUCjYmRNeSbdXbPfz3K/RtFfZ8jMtriRGuO7KNxp8MqrUho HK8O0mlSUxGXBZMNicfo7qY8FD21GIPH9w5fp5oiAl7lqFzt3E3sCLD3IiVJmxbf fUwpGd1XZBBSdIxysRLM6j48 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrTCCAjOgAwIBAgIQU+PAILXGkpoTcpF200VD/jAKBggqhkjOPQQDAzCBljEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMS8wLQYDVQQDDCZBbWF6 b24gUkRTIGFwLWVhc3QtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2Vh dHRsZTAgFw0yMTA1MjUyMTQ1MTFaGA8yMTIxMDUyNTIyNDUxMVowgZYxCzAJBgNV BAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYD VQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1hem9uIFJE UyBhcC1lYXN0LTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1NlYXR0bGUw djAQBgcqhkjOPQIBBgUrgQQAIgNiAAT3tFKE8Kw1sGQAvNLlLhd8OcGhlc7MiW/s NXm3pOiCT4vZpawKvHBzD76Kcv+ZZzHRxQEmG1/muDzZGlKR32h8AAj+NNO2Wy3d CKTtYMiVF6Z2zjtuSkZQdjuQbe4eQ7qjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFAiSQOp16Vv0Ohpvqcbd2j5RmhYNMA4GA1UdDwEB/wQEAwIBhjAKBggq hkjOPQQDAwNoADBlAjBVsi+5Ape0kOhMt/WFkANkslD4qXA5uqhrfAtH29Xzz2NV tR7akiA771OaIGB/6xsCMQCZt2egCtbX7J0WkuZ2KivTh66jecJr5DHvAP4X2xtS F/5pS+AUhcKTEGjI9jDH3ew= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICuDCCAj2gAwIBAgIQT5mGlavQzFHsB7hV6Mmy6TAKBggqhkjOPQQDAzCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLXNvdXRoZWFzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyNDIwNTAxNVoYDzIxMjEwNTI0MjE1MDE1WjCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLXNvdXRoZWFzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEcm4BBBjYK7clwm0HJRWS flt3iYwoJbIXiXn9c1y3E+Vb7bmuyKhS4eO8mwO4GefUcXObRfoHY2TZLhMJLVBQ 7MN2xDc0RtZNj07BbGD3VAIFRTDX0mH9UNYd0JQM3t/Oo0IwQDAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBRrd5ITedfAwrGo4FA9UaDaGFK3rjAOBgNVHQ8BAf8E BAMCAYYwCgYIKoZIzj0EAwMDaQAwZgIxAPBNqmVv1IIA3EZyQ6XuVf4gj79/DMO8 bkicNS1EcBpUqbSuU4Zwt2BYc8c/t7KVOQIxAOHoWkoKZPiKyCxfMtJpCZySUG+n sXgB/LOyWE5BJcXUfm+T1ckeNoWeUUMOLmnJjg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIRAJcDeinvdNrDQBeJ8+t38WQwDQYJKoZIhvcNAQELBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtNCBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjIwNTI1MTY0OTE2WhgPMjA2MjA1MjUxNzQ5MTZa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtc291dGhlYXN0LTQgUm9vdCBDQSBSU0EyMDQ4IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA k8DBNkr9tMoIM0NHoFiO7cQfSX0cOMhEuk/CHt0fFx95IBytx7GHCnNzpM27O5z6 x6iRhfNnx+B6CrGyCzOjxvPizneY+h+9zfvNz9jj7L1I2uYMuiNyOKR6FkHR46CT 1CiArfVLLPaTqgD/rQjS0GL2sLHS/0dmYipzynnZcs613XT0rAWdYDYgxDq7r/Yi Xge5AkWQFkMUq3nOYDLCyGGfQqWKkwv6lZUHLCDKf+Y0Uvsrj8YGCI1O8mF0qPCQ lmlfaDvbuBu1AV+aabmkvyFj3b8KRIlNLEtQ4N8KGYR2Jdb82S4YUGIOAt4wuuFt 1B7AUDLk3V/u+HTWiwfoLQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBSNpcjz6ArWBtAA+Gz6kyyZxrrgdDAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI hvcNAQELBQADggEBAGJEd7UgOzHYIcQRSF7nSYyjLROyalaIV9AX4WXW/Cqlul1c MblP5etDZm7A/thliZIWAuyqv2bNicmS3xKvNy6/QYi1YgxZyy/qwJ3NdFl067W0 t8nGo29B+EVK94IPjzFHWShuoktIgp+dmpijB7wkTIk8SmIoe9yuY4+hzgqk+bo4 ms2SOXSN1DoQ75Xv+YmztbnZM8MuWhL1T7hA4AMorzTQLJ9Pof8SpSdMHeDsHp0R 01jogNFkwy25nw7cL62nufSuH2fPYGWXyNDg+y42wKsKWYXLRgUQuDVEJ2OmTFMB T0Vf7VuNijfIA9hkN2d3K53m/9z5WjGPSdOjGhg= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQRiwspKyrO0xoxDgSkqLZczANBgkqhkiG9w0BAQsFADCB lzELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdB bWF6b24gUkRTIHVzLXdlc3QtMiBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTI0MjE1OTAwWhgPMjA2MTA1MjQyMjU5MDBaMIGXMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpv biBSRFMgdXMtd2VzdC0yIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UEBwwHU2Vh dHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL53Jk3GsKiu+4bx jDfsevWbwPCNJ3H08Zp7GWhvI3Tgi39opfHYv2ku2BKFjK8N2L6RvNPSR8yplv5j Y0tK0U+XVNl8o0ibhqRDhbTuh6KL8CFINWYzAajuxFS+CF0U6c1Q3tXLBdALxA7l FlXJ71QrP06W31kRe7kvgrvO7qWU3/OzUf9qYw4LSiR1/VkvvRCTqcVNw09clw/M Jbw6FSgweN65M9j7zPbjGAXSHkXyxH1Erin2fa+B9PE4ZDgX9cp2C1DHewYJQL/g SepwwcudVNRN1ibKH7kpMrgPnaNIVNx5sXVsTjk6q2ZqYw3SVHegltJpLy/cZReP mlivF2kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUmTcQd6o1 CuS65MjBrMwQ9JJjmBwwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IB AQAKSDSIzl956wVddPThf2VAzI8syw9ngSwsEHZvxVGHBvu5gg618rDyguVCYX9L 4Kw/xJrk6S3qxOS2ZDyBcOpsrBskgahDFIunzoRP3a18ARQVq55LVgfwSDQiunch Bd05cnFGLoiLkR5rrkgYaP2ftn3gRBRaf0y0S3JXZ2XB3sMZxGxavYq9mfiEcwB0 LMTMQ1NYzahIeG6Jm3LqRqR8HkzP/Ztq4dT2AtSLvFebbNMiWqeqT7OcYp94HTYT zqrtaVdUg9bwyAUCDgy0GV9RHDIdNAOInU/4LEETovrtuBU7Z1q4tcHXvN6Hd1H8 gMb0mCG5I393qW5hFsA/diFb -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIRAPQAvihfjBg/JDbj6U64K98wDQYJKoZIhvcNAQELBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1ub3J0aGVhc3QtMiBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTIwMTYyODQxWhgPMjA2MTA1MjAxNzI4NDFa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtbm9ydGhlYXN0LTIgUm9vdCBDQSBSU0EyMDQ4IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA vJ9lgyksCxkBlY40qOzI1TCj/Q0FVGuPL/Z1Mw2YN0l+41BDv0FHApjTUkIKOeIP nwDwpXTa3NjYbk3cOZ/fpH2rYJ++Fte6PNDGPgKppVCUh6x3jiVZ1L7wOgnTdK1Q Trw8440IDS5eLykRHvz8OmwvYDl0iIrt832V0QyOlHTGt6ZJ/aTQKl12Fy3QBLv7 stClPzvHTrgWqVU6uidSYoDtzHbU7Vda7YH0wD9IUoMBf7Tu0rqcE4uH47s2XYkc SdLEoOg/Ngs7Y9B1y1GCyj3Ux7hnyvCoRTw014QyNB7dTatFMDvYlrRDGG14KeiU UL7Vo/+EejWI31eXNLw84wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBQkgTWFsNg6wA3HbbihDQ4vpt1E2zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI hvcNAQELBQADggEBAGz1Asiw7hn5WYUj8RpOCzpE0h/oBZcnxP8wulzZ5Xd0YxWO 0jYUcUk3tTQy1QvoY+Q5aCjg6vFv+oFBAxkib/SmZzp4xLisZIGlzpJQuAgRkwWA 6BVMgRS+AaOMQ6wKPgz1x4v6T0cIELZEPq3piGxvvqkcLZKdCaeC3wCS6sxuafzZ 4qA3zMwWuLOzRftgX2hQto7d/2YkRXga7jSvQl3id/EI+xrYoH6zIWgjdU1AUaNq NGT7DIo47vVMfnd9HFZNhREsd4GJE83I+JhTqIxiKPNxrKgESzyADmNPt0gXDnHo tbV1pMZz5HpJtjnP/qVZhEK5oB0tqlKPv9yx074= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICuTCCAj6gAwIBAgIRAKp1Rn3aL/g/6oiHVIXtCq8wCgYIKoZIzj0EAwMwgZsx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE0MDIGA1UEAwwrQW1h em9uIFJEUyBhcC1ub3J0aGVhc3QtMyBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UE BwwHU2VhdHRsZTAgFw0yMTA1MjQyMDMyMTdaGA8yMTIxMDUyNDIxMzIxN1owgZsx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE0MDIGA1UEAwwrQW1h em9uIFJEUyBhcC1ub3J0aGVhc3QtMyBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UE BwwHU2VhdHRsZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGTYWPILeBJXfcL3Dz4z EWMUq78xB1HpjBwHoTURYfcMd5r96BTVG6yaUBWnAVCMeeD6yTG9a1eVGNhG14Hk ZAEjgLiNB7RRbEG5JZ/XV7W/vODh09WCst2y9SLKsdgeAaNCMEAwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUoE0qZHmDCDB+Bnm8GUa/evpfPwgwDgYDVR0PAQH/ BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCnil5MMwhY3qoXv0xvcKZGxGPaBV15 0CCssCKn0oVtdJQfJQ3Jrf3RSaEyijXIJsoCMQC35iJi4cWoNX3N/qfgnHohW52O B5dg0DYMqy5cNZ40+UcAanRMyqNQ6P7fy3umGco= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtzCCAj2gAwIBAgIQPXnDTPegvJrI98qz8WxrMjAKBggqhkjOPQQDAzCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIEJldGEgdXMtZWFzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUxODIxNDAxMloYDzIxMjEwNTE4MjI0MDEyWjCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIEJldGEgdXMtZWFzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEI0sR7gwutK5AB46hM761 gcLTGBIYlURSEoM1jcBwy56CL+3CJKZwLLyJ7qoOKfWbu5GsVLUTWS8MV6Nw33cx 2KQD2svb694wi+Px2f4n9+XHkEFQw8BbiodDD7RZA70fo0IwQDAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBTQSioOvnVLEMXwNSDg+zgln/vAkjAOBgNVHQ8BAf8E BAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIxAMwu1hqm5Bc98uE/E0B5iMYbBQ4kpMxO tP8FTfz5UR37HUn26nXE0puj6S/Ffj4oJgIwXI7s2c26tFQeqzq6u3lrNJHp5jC9 Uxlo/hEJOLoDj5jnpxo8dMAtCNoQPaHdfL0P -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjWgAwIBAgIQGKVv+5VuzEZEBzJ+bVfx2zAKBggqhkjOPQQDAzCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGFwLXNvdXRoLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTE5MTc1MDU5WhgPMjEyMTA1MTkxODUwNTlaMIGXMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpvbiBS RFMgYXAtc291dGgtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2VhdHRs ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMqdLJ0tZF/DGFZTKZDrGRJZID8ivC2I JRCYTWweZKCKSCAzoiuGGHzJhr5RlLHQf/QgmFcgXsdmO2n3CggzhA4tOD9Ip7Lk P05eHd2UPInyPCHRgmGjGb0Z+RdQ6zkitKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUC1yhRgVqU5bR8cGzOUCIxRpl4EYwDgYDVR0PAQH/BAQDAgGGMAoG CCqGSM49BAMDA2cAMGQCMG0c/zLGECRPzGKJvYCkpFTCUvdP4J74YP0v/dPvKojL t/BrR1Tg4xlfhaib7hPc7wIwFvgqHes20CubQnZmswbTKLUrgSUW4/lcKFpouFd2 t2/ewfi/0VhkeUW+IiHhOMdU -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGCTCCA/GgAwIBAgIRAOXxJuyXVkbfhZCkS/dOpfEwDQYJKoZIhvcNAQEMBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1ub3J0aGVhc3QtMSBSb290IENBIFJTQTQwOTYgRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTI1MjE1OTEwWhgPMjEyMTA1MjUyMjU5MTBa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtbm9ydGhlYXN0LTEgUm9vdCBDQSBSU0E0MDk2IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA xiP4RDYm4tIS12hGgn1csfO8onQDmK5SZDswUpl0HIKXOUVVWkHNlINkVxbdqpqH FhbyZmNN6F/EWopotMDKe1B+NLrjNQf4zefv2vyKvPHJXhxoKmfyuTd5Wk8k1F7I lNwLQzznB+ElhrLIDJl9Ro8t31YBBNFRGAGEnxyACFGcdkjlsa52UwfYrwreEg2l gW5AzqHgjFfj9QRLydeU/n4bHm0F1adMsV7P3rVwilcUlqsENDwXnWyPEyv3sw6F wNemLEs1129mB77fwvySb+lLNGsnzr8w4wdioZ74co+T9z2ca+eUiP+EQccVw1Is D4Fh57IjPa6Wuc4mwiUYKkKY63+38aCfEWb0Qoi+zW+mE9nek6MOQ914cN12u5LX dBoYopphRO5YmubSN4xcBy405nIdSdbrAVWwxXnVVyjqjknmNeqQsPZaxAhdoKhV AqxNr8AUAdOAO6Sz3MslmcLlDXFihrEEOeUbpg/m1mSUUHGbu966ajTG1FuEHHwS 7WB52yxoJo/tHvt9nAWnh3uH5BHmS8zn6s6CGweWKbX5yICnZ1QFR1e4pogxX39v XD6YcNOO+Vn+HY4nXmjgSYVC7l+eeP8eduMg1xJujzjrbmrXU+d+cBObgdTOAlpa JFHaGwYw1osAwPCo9cZ2f04yitBfj9aPFia8ASKldakCAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQUqKS+ltlior0SyZKYAkJ/efv55towDgYDVR0P AQH/BAQDAgGGMA0GCSqGSIb3DQEBDAUAA4ICAQAdElvp8bW4B+Cv+1WSN87dg6TN wGyIjJ14/QYURgyrZiYpUmZpj+/pJmprSWXu4KNyqHftmaidu7cdjL5nCAvAfnY5 /6eDDbX4j8Gt9fb/6H9y0O0dn3mUPSEKG0crR+JRFAtPhn/2FNvst2P82yguWLv0 pHjHVUVcq+HqDMtUIJsTPYjSh9Iy77Q6TOZKln9dyDOWJpCSkiUWQtMAKbCSlvzd zTs/ahqpT+zLfGR1SR+T3snZHgQnbnemmz/XtlKl52NxccARwfcEEKaCRQyGq/pR 0PVZasyJS9JY4JfQs4YOdeOt4UMZ8BmW1+BQWGSkkb0QIRl8CszoKofucAlqdPcO IT/ZaMVhI580LFGWiQIizWFskX6lqbCyHqJB3LDl8gJISB5vNTHOHpvpMOMs5PYt cRl5Mrksx5MKMqG7y5R734nMlZxQIHjL5FOoOxTBp9KeWIL/Ib89T2QDaLw1SQ+w ihqWBJ4ZdrIMWYpP3WqM+MXWk7WAem+xsFJdR+MDgOOuobVQTy5dGBlPks/6gpjm rO9TjfQ36ppJ3b7LdKUPeRfnYmlR5RU4oyYJ//uLbClI443RZAgxaCXX/nyc12lr eVLUMNF2abLX4/VF63m2/Z9ACgMRfqGshPssn1NN33OonrotQoj4S3N9ZrjvzKt8 iHcaqd60QKpfiH2A3A== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICuDCCAj2gAwIBAgIQPaVGRuu86nh/ylZVCLB0MzAKBggqhkjOPQQDAzCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLW5vcnRoZWFzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyNTIyMDMxNloYDzIxMjEwNTI1MjMwMzE2WjCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLW5vcnRoZWFzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEexNURoB9KE93MEtEAlJG obz4LS/pD2hc8Gczix1WhVvpJ8bN5zCDXaKdnDMCebetyRQsmQ2LYlfmCwpZwSDu 0zowB11Pt3I5Avu2EEcuKTlKIDMBeZ1WWuOd3Tf7MEAMo0IwQDAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBSaYbZPBvFLikSAjpa8mRJvyArMxzAOBgNVHQ8BAf8E BAMCAYYwCgYIKoZIzj0EAwMDaQAwZgIxAOEJkuh3Zjb7Ih/zuNRd1RBqmIYcnyw0 nwUZczKXry+9XebYj3VQxSRNadrarPWVqgIxAMg1dyGoDAYjY/L/9YElyMnvHltO PwpJShmqHvCLc/mXMgjjYb/akK7yGthvW6j/uQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGCDCCA/CgAwIBAgIQChu3v5W1Doil3v6pgRIcVzANBgkqhkiG9w0BAQwFADCB nDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTUwMwYDVQQDDCxB bWF6b24gUkRTIEJldGEgdXMtZWFzdC0xIFJvb3QgQ0EgUlNBNDA5NiBHMTEQMA4G A1UEBwwHU2VhdHRsZTAgFw0yMTA1MTgyMTM0MTVaGA8yMTIxMDUxODIyMzQxNVow gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBCZXRhIHVzLWVhc3QtMSBSb290IENBIFJTQTQwOTYgRzExEDAO BgNVBAcMB1NlYXR0bGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC1 FUGQ5tf3OwpDR6hGBxhUcrkwKZhaXP+1St1lSOQvjG8wXT3RkKzRGMvb7Ee0kzqI mzKKe4ASIhtV3UUWdlNmP0EA3XKnif6N79MismTeGkDj75Yzp5A6tSvqByCgxIjK JqpJrch3Dszoyn8+XhwDxMZtkUa5nQVdJgPzJ6ltsQ8E4SWLyLtTu0S63jJDkqYY S7cQblk7y7fel+Vn+LS5dGTdRRhMvSzEnb6mkVBaVzRyVX90FNUED06e8q+gU8Ob htvQlf9/kRzHwRAdls2YBhH40ZeyhpUC7vdtPwlmIyvW5CZ/QiG0yglixnL6xahL pbmTuTSA/Oqz4UGQZv2WzHe1lD2gRHhtFX2poQZeNQX8wO9IcUhrH5XurW/G9Xwl Sat9CMPERQn4KC3HSkat4ir2xaEUrjfg6c4XsGyh2Pk/LZ0gLKum0dyWYpWP4JmM RQNjrInXPbMhzQObozCyFT7jYegS/3cppdyy+K1K7434wzQGLU1gYXDKFnXwkX8R bRKgx2pHNbH5lUddjnNt75+e8m83ygSq/ZNBUz2Ur6W2s0pl6aBjwaDES4VfWYlI jokcmrGvJNDfQWygb1k00eF2bzNeNCHwgWsuo3HSxVgc/WGsbcGrTlDKfz+g3ich bXUeUidPhRiv5UQIVCLIHpHuin3bj9lQO/0t6p+tAQIDAQABo0IwQDAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBSFmMBgm5IsRv3hLrvDPIhcPweXYTAOBgNVHQ8B Af8EBAMCAYYwDQYJKoZIhvcNAQEMBQADggIBAAa2EuozymOsQDJlEi7TqnyA2OhT GXPfYqCyMJVkfrqNgcnsNpCAiNEiZbb+8sIPXnT8Ay8hrwJYEObJ5b7MHXpLuyft z0Pu1oFLKnQxKjNxrIsCvaB4CRRdYjm1q7EqGhMGv76se9stOxkOqO9it31w/LoU ENDk7GLsSqsV1OzYLhaH8t+MaNP6rZTSNuPrHwbV3CtBFl2TAZ7iKgKOhdFz1Hh9 Pez0lG+oKi4mHZ7ajov6PD0W7njn5KqzCAkJR6OYmlNVPjir+c/vUtEs0j+owsMl g7KE5g4ZpTRShyh5BjCFRK2tv0tkqafzNtxrKC5XNpEkqqVTCnLcKG+OplIEadtr C7UWf4HyhCiR+xIyxFyR05p3uY/QQU/5uza7GlK0J+U1sBUytx7BZ+Fo8KQfPPqV CqDCaYUksoJcnJE/KeoksyqNQys7sDGJhkd0NeUGDrFLKHSLhIwAMbEWnqGxvhli E7sP2E5rI/I9Y9zTbLIiI8pfeZlFF8DBdoP/Hzg8pqsiE/yiXSFTKByDwKzGwNqz F0VoFdIZcIbLdDbzlQitgGpJtvEL7HseB0WH7B2PMMD8KPJlYvPveO3/6OLzCsav +CAkvk47NQViKMsUTKOA0JDCW+u981YRozxa3K081snhSiSe83zIPBz1ikldXxO9 6YYLNPRrj3mi9T/f -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjSgAwIBAgIRAMkvdFnVDb0mWWFiXqnKH68wCgYIKoZIzj0EAwMwgZYx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1h em9uIFJEUyB1cy13ZXN0LTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTE5MTkxMzI0WhgPMjEyMTA1MTkyMDEzMjRaMIGWMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExLzAtBgNVBAMMJkFtYXpvbiBS RFMgdXMtd2VzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdTZWF0dGxl MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEy86DB+9th/0A5VcWqMSWDxIUblWTt/R0 ao6Z2l3vf2YDF2wt1A2NIOGpfQ5+WAOJO/IQmnV9LhYo+kacB8sOnXdQa6biZZkR IyouUfikVQAKWEJnh1Cuo5YMM4E2sUt5o0IwQDAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBQ8u3OnecANmG8OoT7KLWDuFzZwBTAOBgNVHQ8BAf8EBAMCAYYwCgYI KoZIzj0EAwMDaAAwZQIwQ817qkb7mWJFnieRAN+m9W3E0FLVKaV3zC5aYJUk2fcZ TaUx3oLp3jPLGvY5+wgeAjEA6wAicAki4ZiDfxvAIuYiIe1OS/7H5RA++R8BH6qG iRzUBM/FItFpnkus7u/eTkvo -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrzCCAjWgAwIBAgIQS/+Ryfgb/IOVEa1pWoe8oTAKBggqhkjOPQQDAzCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGFwLXNvdXRoLTIgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjIwNjA2MjE1NDQyWhgPMjEyMjA2MDYyMjU0NDJaMIGXMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpvbiBS RFMgYXAtc291dGgtMiBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2VhdHRs ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDsX6fhdUWBQpYTdseBD/P3s96Dtw2Iw OrXKNToCnmX5nMkUGdRn9qKNiz1pw3EPzaPxShbYwQ7LYP09ENK/JN4QQjxMihxC jLFxS85nhBQQQGRCWikDAe38mD8fSvREQKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUIh1xZiseQYFjPYKJmGbruAgRH+AwDgYDVR0PAQH/BAQDAgGGMAoG CCqGSM49BAMDA2gAMGUCMFudS4zLy+UUGrtgNLtRMcu/DZ9BUzV4NdHxo0bkG44O thnjl4+wTKI6VbyAbj2rkgIxAOHps8NMITU5DpyiMnKTxV8ubb/WGHrLl0BjB8Lw ETVJk5DNuZvsIIcm7ykk6iL4Tw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGBDCCA+ygAwIBAgIQDcEmNIAVrDpUw5cH5ynutDANBgkqhkiG9w0BAQwFADCB mjELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTMwMQYDVQQDDCpB bWF6b24gUkRTIG1lLWNlbnRyYWwtMSBSb290IENBIFJTQTQwOTYgRzExEDAOBgNV BAcMB1NlYXR0bGUwIBcNMjIwNTA3MDA0MDIzWhgPMjEyMjA1MDcwMTQwMjNaMIGa MQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5j LjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMzAxBgNVBAMMKkFt YXpvbiBSRFMgbWUtY2VudHJhbC0xIFJvb3QgQ0EgUlNBNDA5NiBHMTEQMA4GA1UE BwwHU2VhdHRsZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKvADk8t Fl9bFlU5sajLPPDSOUpPAkKs6iPlz+27o1GJC88THcOvf3x0nVAcu9WYe9Qaas+4 j4a0vv51agqyODRD/SNi2HnqW7DbtLPAm6KBHe4twl28ItB/JD5g7u1oPAHFoXMS cH1CZEAs5RtlZGzJhcBXLFsHNv/7+SCLyZ7+2XFh9OrtgU4wMzkHoRNndhfwV5bu 17bPTwuH+VxH37zXf1mQ/KjhuJos0C9dL0FpjYBAuyZTAWhZKs8dpSe4DI544z4w gkwUB4bC2nA1TBzsywEAHyNuZ/xRjNpWvx0ToWAA2iFJqC3VO3iKcnBplMvaUuMt jwzVSNBnKcoabXCZL2XDLt4YTZR8FSwz05IvsmwcPB7uNTBXq3T9sjejW8QQK3vT tzyfLq4jKmQE7PoS6cqYm+hEPm2hDaC/WP9bp3FdEJxZlPH26fq1b7BWYWhQ9pBA Nv9zTnzdR1xohTyOJBUFQ81ybEzabqXqVXUIANqIOaNcTB09/sLJ7+zuMhp3mwBu LtjfJv8PLuT1r63bU3seROhKA98b5KfzjvbvPSg3vws78JQyoYGbqNyDfyjVjg3U v//AdVuPie6PNtdrW3upZY4Qti5IjP9e3kimaJ+KAtTgMRG56W0WxD3SP7+YGGbG KhntDOkKsN39hLpn9UOafTIqFu7kIaueEy/NAgMBAAGjQjBAMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFHAems86dTwdZbLe8AaPy3kfIUVoMA4GA1UdDwEB/wQE AwIBhjANBgkqhkiG9w0BAQwFAAOCAgEAOBHpp0ICx81kmeoBcZTrMdJs2gnhcd85 FoSCjXx9H5XE5rmN/lQcxxOgj8hr3uPuLdLHu+i6THAyzjrl2NA1FWiqpfeECGmy 0jm7iZsYORgGQYp/VKnDrwnKNSqlZvOuRr0kfUexwFlr34Y4VmupvEOK/RdGsd3S +3hiemcHse9ST/sJLHx962AWMkN86UHPscJEe4+eT3f2Wyzg6La8ARwdWZSNS+WH ZfybrncMmuiXuUdHv9XspPsqhKgtHhcYeXOGUtrwQPLe3+VJZ0LVxhlTWr9951GZ GfmWwTV/9VsyKVaCFIXeQ6L+gjcKyEzYF8wpMtQlSc7FFqwgC4bKxvMBSaRy88Nr lV2+tJD/fr8zGUeBK44Emon0HKDBWGX+/Hq1ZIv0Da0S+j6LbA4fusWxtGfuGha+ luhHgVInCpALIOamiBEdGhILkoTtx7JrYppt3/Raqg9gUNCOOYlCvGhqX7DXeEfL DGabooiY2FNWot6h04JE9nqGj5QqT8D6t/TL1nzxhRPzbcSDIHUd/b5R+a0bAA+7 YTU6JqzEVCWKEIEynYmqikgLMGB/OzWsgyEL6822QW6hJAQ78XpbNeCzrICF4+GC 7KShLnwuWoWpAb26268lvOEvCTFM47VC6jNQl97md+2SA9Ma81C9wflid2M83Wle cuLMVcQZceE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIQAhAteLRCvizAElaWORFU2zANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChB bWF6b24gUkRTIG1lLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyMDE3MDkxNloYDzIwNjEwNTIwMTgwOTE2WjCBmDEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChBbWF6 b24gUkRTIG1lLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+qg7JAcOVKjh N83SACnBFZPyB63EusfDr/0V9ZdL8lKcmZX9sv/CqoBo3N0EvBqHQqUUX6JvFb7F XrMUZ740kr28gSRALfXTFgNODjXeDsCtEkKRTkac/UM8xXHn+hR7UFRPHS3e0GzI iLiwQWDkr0Op74W8aM0CfaVKvh2bp4BI1jJbdDnQ9OKXpOxNHGUf0ZGb7TkNPkgI b2CBAc8J5o3H9lfw4uiyvl6Fz5JoP+A+zPELAioYBXDrbE7wJeqQDJrETWqR9VEK BXURCkVnHeaJy123MpAX2ozf4pqk0V0LOEOZRS29I+USF5DcWr7QIXR/w2I8ws1Q 7ys+qbE+kQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQFJ16n 1EcCMOIhoZs/F9sR+Jy++zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD ggEBAOc5nXbT3XTDEZsxX2iD15YrQvmL5m13B3ImZWpx/pqmObsgx3/dg75rF2nQ qS+Vl+f/HLh516pj2BPP/yWCq12TRYigGav8UH0qdT3CAClYy2o+zAzUJHm84oiB ud+6pFVGkbqpsY+QMpJUbZWu52KViBpJMYsUEy+9cnPSFRVuRAHjYynSiLk2ZEjb Wkdc4x0nOZR5tP0FgrX0Ve2KcjFwVQJVZLgOUqmFYQ/G0TIIGTNh9tcmR7yp+xJR A2tbPV2Z6m9Yxx4E8lLEPNuoeouJ/GR4CkMEmF8cLwM310t174o3lKKUXJ4Vs2HO Wj2uN6R9oI+jGLMSswTzCNV1vgc= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICuDCCAj6gAwIBAgIRAOocLeZWjYkG/EbHmscuy8gwCgYIKoZIzj0EAwMwgZsx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE0MDIGA1UEAwwrQW1h em9uIFJEUyBhcC1zb3V0aGVhc3QtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UE BwwHU2VhdHRsZTAgFw0yMTA1MjEyMTUwMDFaGA8yMTIxMDUyMTIyNTAwMVowgZsx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE0MDIGA1UEAwwrQW1h em9uIFJEUyBhcC1zb3V0aGVhc3QtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UE BwwHU2VhdHRsZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABCEr3jq1KtRncnZfK5cq btY0nW6ZG3FMbh7XwBIR6Ca0f8llGZ4vJEC1pXgiM/4Dh045B9ZIzNrR54rYOIfa 2NcYZ7mk06DjIQML64hbAxbQzOAuNzLPx268MrlL2uW2XaNCMEAwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUln75pChychwN4RfHl+tOinMrfVowDgYDVR0PAQH/ BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMGiyPINRU1mwZ4Crw01vpuPvxZxb2IOr yX3RNlOIu4We1H+5dQk5tIvH8KGYFbWEpAIxAO9NZ6/j9osMhLgZ0yj0WVjb+uZx YlZR9fyFisY/jNfX7QhSk+nrc3SFLRUNtpXrng== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBTCCAu2gAwIBAgIRAKiaRZatN8eiz9p0s0lu0rQwDQYJKoZIhvcNAQELBQAw gZoxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEzMDEGA1UEAwwq QW1hem9uIFJEUyBjYS1jZW50cmFsLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYD VQQHDAdTZWF0dGxlMCAXDTIxMDUyMTIyMDIzNVoYDzIwNjEwNTIxMjMwMjM1WjCB mjELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTMwMQYDVQQDDCpB bWF6b24gUkRTIGNhLWNlbnRyYWwtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNV BAcMB1NlYXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCygVMf qB865IR9qYRBRFHn4eAqGJOCFx+UbraQZmjr/mnRqSkY+nhbM7Pn/DWOrRnxoh+w q5F9ZxdZ5D5T1v6kljVwxyfFgHItyyyIL0YS7e2h7cRRscCM+75kMedAP7icb4YN LfWBqfKHbHIOqvvQK8T6+Emu/QlG2B5LvuErrop9K0KinhITekpVIO4HCN61cuOe CADBKF/5uUJHwS9pWw3uUbpGUwsLBuhJzCY/OpJlDqC8Y9aToi2Ivl5u3/Q/sKjr 6AZb9lx4q3J2z7tJDrm5MHYwV74elGSXoeoG8nODUqjgklIWAPrt6lQ3WJpO2kug 8RhCdSbWkcXHfX95AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FOIxhqTPkKVqKBZvMWtKewKWDvDBMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0B AQsFAAOCAQEAqoItII89lOl4TKvg0I1EinxafZLXIheLcdGCxpjRxlZ9QMQUN3yb y/8uFKBL0otbQgJEoGhxm4h0tp54g28M6TN1U0332dwkjYxUNwvzrMaV5Na55I2Z 1hq4GB3NMXW+PvdtsgVOZbEN+zOyOZ5MvJHEQVkT3YRnf6avsdntltcRzHJ16pJc Y8rR7yWwPXh1lPaPkxddrCtwayyGxNbNmRybjR48uHRhwu7v2WuAMdChL8H8bp89 TQLMrMHgSbZfee9hKhO4Zebelf1/cslRSrhkG0ESq6G5MUINj6lMg2g6F0F7Xz2v ncD/vuRN5P+vT8th/oZ0Q2Gc68Pun0cn/g== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/zCCAuegAwIBAgIRAJYlnmkGRj4ju/2jBQsnXJYwDQYJKoZIhvcNAQELBQAw gZcxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwn QW1hem9uIFJEUyB1cy1lYXN0LTIgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyMTIzMDQ0NFoYDzIwNjEwNTIyMDAwNDQ0WjCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIHVzLWVhc3QtMiBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcMB1Nl YXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC74V3eigv+pCj5 nqDBqplY0Jp16pTeNB06IKbzb4MOTvNde6QjsZxrE1xUmprT8LxQqN9tI3aDYEYk b9v4F99WtQVgCv3Y34tYKX9NwWQgwS1vQwnIR8zOFBYqsAsHEkeJuSqAB12AYUSd Zv2RVFjiFmYJho2X30IrSLQfS/IE3KV7fCyMMm154+/K1Z2IJlcissydEAwgsUHw edrE6CxJVkkJ3EvIgG4ugK/suxd8eEMztaQYJwSdN8TdfT59LFuSPl7zmF3fIBdJ //WexcQmGabaJ7Xnx+6o2HTfkP8Zzzzaq8fvjAcvA7gyFH5EP26G2ZqMG+0y4pTx SPVTrQEXAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIWWuNEF sUMOC82XlfJeqazzrkPDMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC AQEAgClmxcJaQTGpEZmjElL8G2Zc8lGc+ylGjiNlSIw8X25/bcLRptbDA90nuP+q zXAMhEf0ccbdpwxG/P5a8JipmHgqQLHfpkvaXx+0CuP++3k+chAJ3Gk5XtY587jX +MJfrPgjFt7vmMaKmynndf+NaIJAYczjhJj6xjPWmGrjM3MlTa9XesmelMwP3jep bApIWAvCYVjGndbK9byyMq1nyj0TUzB8oJZQooaR3MMjHTmADuVBylWzkRMxbKPl 4Nlsk4Ef1JvIWBCzsMt+X17nuKfEatRfp3c9tbpGlAE/DSP0W2/Lnayxr4RpE9ds ICF35uSis/7ZlsftODUe8wtpkQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 Pqj2 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 KDPtFEk= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtzCCAj2gAwIBAgIQVZ5Y/KqjR4XLou8MCD5pOjAKBggqhkjOPQQDAzCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLXNvdXRoZWFzdC00IFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIyMDUyNTE2NTgzM1oYDzIxMjIwNTI1MTc1ODMzWjCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLXNvdXRoZWFzdC00IFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEbo473OmpD5vkckdJajXg brhmNFyoSa0WCY1njuZC2zMFp3zP6rX4I1r3imrYnJd9pFH/aSiV/r6L5ACE5RPx 4qdg5SQ7JJUaZc3DWsTOiOed7BCZSzM+KTYK/2QzDMApo0IwQDAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBTmogc06+1knsej1ltKUOdWFvwgsjAOBgNVHQ8BAf8E BAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIxAIs7TlLMbGTWNXpGiKf9DxaM07d/iDHe F/Vv/wyWSTGdobxBL6iArQNVXz0Gr4dvPAIwd0rsoa6R0x5mtvhdRPtM37FYrbHJ pbV+OMusQqcSLseunLBoCHenvJW0QOCQ8EDY -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGBTCCA+2gAwIBAgIRAO9dVdiLTEGO8kjUFExJmgowDQYJKoZIhvcNAQEMBQAw gZoxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEzMDEGA1UEAwwq QW1hem9uIFJEUyBpbC1jZW50cmFsLTEgUm9vdCBDQSBSU0E0MDk2IEcxMRAwDgYD VQQHDAdTZWF0dGxlMCAXDTIyMTIwMjIwMjYwOFoYDzIxMjIxMjAyMjEyNjA4WjCB mjELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTMwMQYDVQQDDCpB bWF6b24gUkRTIGlsLWNlbnRyYWwtMSBSb290IENBIFJTQTQwOTYgRzExEDAOBgNV BAcMB1NlYXR0bGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDkVHmJ bUc8CNDGBcgPmXHSHj5dS1PDnnpk3doCu6pahyYXW8tqAOmOqsDuNz48exY7YVy4 u9I9OPBeTYB9ZUKwxq+1ZNLsr1cwVz5DdOyDREVFOjlU4rvw0eTgzhP5yw/d+Ai/ +WmPebZG0irwPKN2f60W/KJ45UNtR+30MT8ugfnPuSHWjjV+dqCOCp/mj8nOCckn k8GoREwjuTFJMKInpQUC0BaVVX6LiIdgtoLY4wdx00EqNBuROoRTAvrked0jvm7J UI39CSYxhNZJ9F6LdESZXjI4u2apfNQeSoy6WptxFHr+kh2yss1B2KT6lbwGjwWm l9HODk9kbBNSy2NeewAms36q+p8wSLPavL28IRfK0UaBAiN1hr2a/2RDGCwOJmw6 5erRC5IIX5kCStyXPEGhVPp18EvMuBd37eLIxjZBBO8AIDf4Ue8QmxSeZH0cT204 3/Bd6XR6+Up9iMTxkHr1URcL1AR8Zd62lg/lbEfxePNMK9mQGxKP8eTMG5AjtW9G TatEoRclgE0wZQalXHmKpBNshyYdGqQZhzL1MxCxWzfHNgZkTKIsdzxrjnP7RiBR jdRH0YhXn6Y906QfLwMCaufwfQ5J8+nj/tu7nG138kSxsu6VUkhnQJhUcUsxuHD/ NnBx0KGVEldtZiZf7ccgtRVp1lA0OrVtq3ZLMQIDAQABo0IwQDAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBQ2WC3p8rWeE2N0S4Om01KsNLpk/jAOBgNVHQ8BAf8E BAMCAYYwDQYJKoZIhvcNAQEMBQADggIBAFFEVDt45Obr6Ax9E4RMgsKjj4QjMFB9 wHev1jL7hezl/ULrHuWxjIusaIZEIcKfn+v2aWtqOq13P3ht7jV5KsV29CmFuCdQ q3PWiAXVs+hnMskTOmGMDnptqd6/UuSIha8mlOKKAvnmRQJvfX9hIfb/b/mVyKWD uvTTmcy3cOTJY5ZIWGyzuvmcqA0YNcb7rkJt/iaLq4RX3/ofq4y4w36hefbcvj++ pXHOmXk3dAej3y6SMBOUcGMyCJcCluRPNYKDTLn+fitcPxPC3JG7fI5bxQ0D6Hpa qbyGBQu96sfahQyMc+//H8EYlo4b0vPeS5RFFXJS/VBf0AyNT4vVc7H17Q6KjeNp wEARqsIa7UalHx9MnxrQ/LSTTxiC8qmDkIFuQtw8iQMN0SoL5S0eCZNRD31awgaY y1PvY8JMN549ugIUjOXnown/OxharLW1evWUraU5rArq3JfeFpPXl4K/u10T5SCL iJRoxFilGPMFE3hvnmbi5rEy8wRUn7TpLb4I4s/CB/lT2qZTPqvQHwxKCnMm9BKF NHb4rLL5dCvUi5NJ6fQ/exOoGdOVSfT7jqFeq2TtNunERSz9vpriweliB6iIe1Al Thj8aEs1GqA764rLVGA+vUe18NhjJm9EemrdIzjSQFy/NdbN/DMaHqEzJogWloAI izQWYnCS19TJ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICvTCCAkOgAwIBAgIQCIY7E/bFvFN2lK9Kckb0dTAKBggqhkjOPQQDAzCBnjEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTcwNQYDVQQDDC5BbWF6 b24gUkRTIFByZXZpZXcgdXMtZWFzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYD VQQHDAdTZWF0dGxlMCAXDTIxMDUxODIxMDUxMFoYDzIxMjEwNTE4MjIwNTEwWjCB njELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTcwNQYDVQQDDC5B bWF6b24gUkRTIFByZXZpZXcgdXMtZWFzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAw DgYDVQQHDAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEMI0hzf1JCEOI Eue4+DmcNnSs2i2UaJxHMrNGGfU7b42a7vwP53F7045ffHPBGP4jb9q02/bStZzd VHqfcgqkSRI7beBKjD2mfz82hF/wJSITTgCLs+NRpS6zKMFOFHUNo0IwQDAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBS8uF/6hk5mPLH4qaWv9NVZaMmyTjAOBgNV HQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIxAO7Pu9wzLyM0X7Q08uLIL+vL qaxe3UFuzFTWjM16MLJHbzLf1i9IDFKz+Q4hXCSiJwIwClMBsqT49BPUxVsJnjGr EbyEk6aOOVfY1p2yQL649zh3M4h8okLnwf+bYIb1YpeU -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIQY+JhwFEQTe36qyRlUlF8ozANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChB bWF6b24gUkRTIGFmLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUxOTE5MjQxNloYDzIwNjEwNTE5MjAyNDE2WjCBmDEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChBbWF6 b24gUkRTIGFmLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnIye77j6ev40 8wRPyN2OdKFSUfI9jB20Or2RLO+RDoL43+USXdrze0Wv4HMRLqaen9BcmCfaKMp0 E4SFo47bXK/O17r6G8eyq1sqnHE+v288mWtYH9lAlSamNFRF6YwA7zncmE/iKL8J 0vePHMHP/B6svw8LULZCk+nZk3tgxQn2+r0B4FOz+RmpkoVddfqqUPMbKUxhM2wf fO7F6bJaUXDNMBPhCn/3ayKCjYr49ErmnpYV2ZVs1i34S+LFq39J7kyv6zAgbHv9 +/MtRMoRB1CjpqW0jIOZkHBdYcd1o9p1zFn591Do1wPkmMsWdjIYj+6e7UXcHvOB 2+ScIRAcnwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQGtq2W YSyMMxpdQ3IZvcGE+nyZqTAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD ggEBAEgoP3ixJsKSD5FN8dQ01RNHERl/IFbA7TRXfwC+L1yFocKnQh4Mp/msPRSV +OeHIvemPW/wtZDJzLTOFJ6eTolGekHK1GRTQ6ZqsWiU2fmiOP8ks4oSpI+tQ9Lw VrfZqTiEcS5wEIqyfUAZZfKDo7W1xp+dQWzfczSBuZJZwI5iaha7+ILM0r8Ckden TVTapc5pLSoO15v0ziRuQ2bT3V3nwu/U0MRK44z+VWOJdSiKxdnOYDs8hFNnKhfe klbTZF7kW7WbiNYB43OaAQBJ6BALZsIskEaqfeZT8FD71uN928TcEQyBDXdZpRN+ iGQZDGhht0r0URGMDSs9waJtTfA= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF/jCCA+agAwIBAgIQXY/dmS+72lZPranO2JM9jjANBgkqhkiG9w0BAQwFADCB lzELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdB bWF6b24gUkRTIGFwLWVhc3QtMSBSb290IENBIFJTQTQwOTYgRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTI1MjEzNDUxWhgPMjEyMTA1MjUyMjM0NTFaMIGXMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpv biBSRFMgYXAtZWFzdC0xIFJvb3QgQ0EgUlNBNDA5NiBHMTEQMA4GA1UEBwwHU2Vh dHRsZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMyW9kBJjD/hx8e8 b5E1sF42bp8TXsz1htSYE3Tl3T1Aq379DfEhB+xa/ASDZxt7/vwa81BkNo4M6HYq okYIXeE7cu5SnSgjWXqcERhgPevtAwgmhdE3yREe8oz2DyOi2qKKZqah+1gpPaIQ fK0uAqoeQlyHosye3KZZKkDHBatjBsQ5kf8lhuf7wVulEZVRHY2bP2X7N98PfbpL QdH7mWXzDtJJ0LiwFwds47BrkgK1pkHx2p1mTo+HMkfX0P6Fq1atkVC2RHHtbB/X iYyH7paaHBzviFrhr679zNqwXIOKlbf74w3mS11P76rFn9rS1BAH2Qm6eY5S/Fxe HEKXm4kjPN63Zy0p3yE5EjPt54yPkvumOnT+RqDGJ2HCI9k8Ehcbve0ogfdRKNqQ VHWYTy8V33ndQRHZlx/CuU1yN61TH4WSoMly1+q1ihTX9sApmlQ14B2pJi/9DnKW cwECrPy1jAowC2UJ45RtC8UC05CbP9yrIy/7Noj8gQDiDOepm+6w1g6aNlWoiuQS kyI6nzz1983GcnOHya73ga7otXo0Qfg9jPghlYiMomrgshlSLDHZG0Ib/3hb8cnR 1OcN9FpzNmVK2Ll1SmTMLrIhuCkyNYX9O/bOknbcf706XeESxGduSkHEjIw/k1+2 Atteoq5dT6cwjnJ9hyhiueVlVkiDAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8w HQYDVR0OBBYEFLUI+DD7RJs+0nRnjcwIVWzzYSsFMA4GA1UdDwEB/wQEAwIBhjAN BgkqhkiG9w0BAQwFAAOCAgEAb1mcCHv4qMQetLGTBH9IxsB2YUUhr5dda0D2BcHr UtDbfd0VQs4tux6h/6iKwHPx0Ew8fuuYj99WknG0ffgJfNc5/fMspxR/pc1jpdyU 5zMQ+B9wi0lOZPO9uH7/pr+d2odcNEy8zAwqdv/ihsTwLmGP54is9fVbsgzNW1cm HKAVL2t/Ope+3QnRiRilKCN1lzhav4HHdLlN401TcWRWKbEuxF/FgxSO2Hmx86pj e726lweCTMmnq/cTsPOVY0WMjs0or3eHDVlyLgVeV5ldyN+ptg3Oit60T05SRa58 AJPTaVKIcGQ/gKkKZConpu7GDofT67P/ox0YNY57LRbhsx9r5UY4ROgz7WMQ1yoS Y+19xizm+mBm2PyjMUbfwZUyCxsdKMwVdOq5/UmTmdms+TR8+m1uBHPOTQ2vKR0s Pd/THSzPuu+d3dbzRyDSLQbHFFneG760CUlD/ZmzFlQjJ89/HmAmz8IyENq+Sjhx Jgzy+FjVZb8aRUoYLlnffpUpej1n87Ynlr1GrvC4GsRpNpOHlwuf6WD4W0qUTsC/ C9JO+fBzUj/aWlJzNcLEW6pte1SB+EdkR2sZvWH+F88TxemeDrV0jKJw5R89CDf8 ZQNfkxJYjhns+YeV0moYjqQdc7tq4i04uggEQEtVzEhRLU5PE83nlh/K2NZZm8Kj dIA= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/zCCAuegAwIBAgIRAPVSMfFitmM5PhmbaOFoGfUwDQYJKoZIhvcNAQELBQAw gZcxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwn QW1hem9uIFJEUyB1cy1lYXN0LTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyNTIyMzQ1N1oYDzIwNjEwNTI1MjMzNDU3WjCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIHVzLWVhc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcMB1Nl YXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDu9H7TBeGoDzMr dxN6H8COntJX4IR6dbyhnj5qMD4xl/IWvp50lt0VpmMd+z2PNZzx8RazeGC5IniV 5nrLg0AKWRQ2A/lGGXbUrGXCSe09brMQCxWBSIYe1WZZ1iU1IJ/6Bp4D2YEHpXrW bPkOq5x3YPcsoitgm1Xh8ygz6vb7PsvJvPbvRMnkDg5IqEThapPjmKb8ZJWyEFEE QRrkCIRueB1EqQtJw0fvP4PKDlCJAKBEs/y049FoOqYpT3pRy0WKqPhWve+hScMd 6obq8kxTFy1IHACjHc51nrGII5Bt76/MpTWhnJIJrCnq1/Uc3Qs8IVeb+sLaFC8K DI69Sw6bAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE7PCopt lyOgtXX0Y1lObBUxuKaCMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC AQEAFj+bX8gLmMNefr5jRJfHjrL3iuZCjf7YEZgn89pS4z8408mjj9z6Q5D1H7yS jNETVV8QaJip1qyhh5gRzRaArgGAYvi2/r0zPsy+Tgf7v1KGL5Lh8NT8iCEGGXwF g3Ir+Nl3e+9XUp0eyyzBIjHtjLBm6yy8rGk9p6OtFDQnKF5OxwbAgip42CD75r/q p421maEDDvvRFR4D+99JZxgAYDBGqRRceUoe16qDzbMvlz0A9paCZFclxeftAxv6 QlR5rItMz/XdzpBJUpYhdzM0gCzAzdQuVO5tjJxmXhkSMcDP+8Q+Uv6FA9k2VpUV E/O5jgpqUJJ2Hc/5rs9VkAPXeA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrzCCAjWgAwIBAgIQW0yuFCle3uj4vWiGU0SaGzAKBggqhkjOPQQDAzCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGFmLXNvdXRoLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTE5MTkzNTE2WhgPMjEyMTA1MTkyMDM1MTZaMIGXMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpvbiBS RFMgYWYtc291dGgtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2VhdHRs ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDPiKNZSaXs3Un/J/v+LTsFDANHpi7en oL2qh0u0DoqNzEBTbBjvO23bLN3k599zh6CY3HKW0r2k1yaIdbWqt4upMCRCcUFi I4iedAmubgzh56wJdoMZztjXZRwDthTkJKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUWbYkcrvVSnAWPR5PJhIzppcAnZIwDgYDVR0PAQH/BAQDAgGGMAoG CCqGSM49BAMDA2gAMGUCMCESGqpat93CjrSEjE7z+Hbvz0psZTHwqaxuiH64GKUm mYynIiwpKHyBrzjKBmeDoQIxANGrjIo6/b8Jl6sdIZQI18V0pAyLfLiZjlHVOnhM MOTVgr82ZuPoEHTX78MxeMnYlw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIRAIbsx8XOl0sgTNiCN4O+18QwDQYJKoZIhvcNAQELBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1ub3J0aGVhc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTI1MjE1NDU4WhgPMjA2MTA1MjUyMjU0NTha MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtbm9ydGhlYXN0LTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA tROxwXWCgn5R9gI/2Ivjzaxc0g95ysBjoJsnhPdJEHQb7w3y2kWrVWU3Y9fOitgb CEsnEC3PrhRnzNVW0fPsK6kbvOeCmjvY30rdbxbc8h+bjXfGmIOgAkmoULEr6Hc7 G1Q/+tvv4lEwIs7bEaf+abSZxRJbZ0MBxhbHn7UHHDiMZYvzK+SV1MGCxx7JVhrm xWu3GC1zZCsGDhB9YqY9eR6PmjbqA5wy8vqbC57dZZa1QVtWIQn3JaRXn+faIzHx nLMN5CEWihsdmHBXhnRboXprE/OS4MFv1UrQF/XM/h5RBeCywpHePpC+Oe1T3LNC iP8KzRFrjC1MX/WXJnmOVQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBS33XbXAUMs1znyZo4B0+B3D68WFTAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI hvcNAQELBQADggEBADuadd2EmlpueY2VlrIIPC30QkoA1EOSoCmZgN6124apkoY1 HiV4r+QNPljN4WP8gmcARnNkS7ZeR4fvWi8xPh5AxQCpiaBMw4gcbTMCuKDV68Pw P2dZCTMspvR3CDfM35oXCufdtFnxyU6PAyINUqF/wyTHguO3owRFPz64+sk3r2pT WHmJjG9E7V+KOh0s6REgD17Gqn6C5ijLchSrPUHB0wOIkeLJZndHxN/76h7+zhMt fFeNxPWHY2MfpcaLjz4UREzZPSB2U9k+y3pW1omCIcl6MQU9itGx/LpQE+H3ZeX2 M2bdYd5L+ow+bdbGtsVKOuN+R9Dm17YpswF+vyQ= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 Em4Hy3A= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBDCCAuygAwIBAgIQFn6AJ+uxaPDpNVx7174CpjANBgkqhkiG9w0BAQsFADCB mjELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTMwMQYDVQQDDCpB bWF6b24gUkRTIGlsLWNlbnRyYWwtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNV BAcMB1NlYXR0bGUwIBcNMjIxMjAyMjAxNDA4WhgPMjA2MjEyMDIyMTE0MDhaMIGa MQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5j LjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMzAxBgNVBAMMKkFt YXpvbiBSRFMgaWwtY2VudHJhbC0xIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UE BwwHU2VhdHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2xGTSJ fXorki/dkkTqdLyv4U1neeFYEyUCPN/HJ7ZloNwhj8RBrHYhZ4qtvUAvN+rs8fUm L0wmaL69ye61S+CSfDzNwBDGwOzUm/cc1NEJOHCm8XA0unBNBvpJTjsFk2LQ+rz8 oU0lVV4mjnfGektrTDeADonO1adJvUTYmF6v1wMnykSkp8AnW9EG/6nwcAJuAJ7d BfaLThm6lfxPdsBNG81DLKi2me2TLQ4yl+vgRKJi2fJWwA77NaDqQuD5upRIcQwt 5noJt2kFFmeiro98ZMMRaDTHAHhJfWkwkw5f2QNIww7T4r85IwbQCgJVRo4m4ZTC W/1eiEccU2407mECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU DNhVvGHzKXv0Yh6asK0apP9jJlUwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB CwUAA4IBAQCoEVTUY/rF9Zrlpb1Y1hptEguw0i2pCLakcmv3YNj6thsubbGeGx8Z RjUA/gPKirpoae2HU1y64WEu7akwr6pdTRtXXjbe9NReT6OW/0xAwceSXCOiStqS cMsWWTGg6BA3uHqad5clqITjDZr1baQ8X8en4SXRBxXyhJXbOkB60HOQeFR9CNeh pJdrWLeNYXwU0Z59juqdVMGwvDAYdugWUhW2rhafVUXszfRA5c8Izc+E31kq90aY LmxFXUHUfG0eQOmxmg+Z/nG7yLUdHIFA3id8MRh22hye3KvRdQ7ZVGFni0hG2vQQ Q01AvD/rhzyjg0czzJKLK9U/RttwdMaV -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 jGKc3k6UNxpg -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 0Ws= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtDCCAjqgAwIBAgIRAMyaTlVLN0ndGp4ffwKAfoMwCgYIKoZIzj0EAwMwgZkx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEyMDAGA1UEAwwpQW1h em9uIFJEUyBtZS1jZW50cmFsLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjIwNTA3MDA0NDM3WhgPMjEyMjA1MDcwMTQ0MzdaMIGZMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMjAwBgNVBAMMKUFtYXpv biBSRFMgbWUtY2VudHJhbC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE19nCV1nsI6CohSor13+B25cr zg+IHdi9Y3L7ziQnHWI6yjBazvnKD+oC71aRRlR8b5YXsYGUQxWzPLHN7EGPcSGv bzA9SLG1KQYCJaQ0m9Eg/iGrwKWOgylbhVw0bCxoo0IwQDAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBS4KsknsJXM9+QPEkBdZxUPaLr11zAOBgNVHQ8BAf8EBAMC AYYwCgYIKoZIzj0EAwMDaAAwZQIxAJaRgrYIEfXQMZQQDxMTYS0azpyWSseQooXo L3nYq4OHGBgYyQ9gVjvRYWU85PXbfgIwdi82DtANQFkCu+j+BU0JBY/uRKPEeYzo JG92igKIcXPqCoxIJ7lJbbzmuf73gQu5 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 Tspdjbg= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIRAJZFh4s9aZGzKaTMLrSb4acwDQYJKoZIhvcNAQELBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBCZXRhIHVzLWVhc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTE4MjEyODQxWhgPMjA2MTA1MTgyMjI4NDFa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgQmV0YSB1cy1lYXN0LTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA 17i2yoU6diep+WrqxIn2CrDEO2NdJVwWTSckx4WMZlLpkQDoymSmkNHjq9ADIApD A31Cx+843apL7wub8QkFZD0Tk7/ThdHWJOzcAM3ov98QBPQfOC1W5zYIIRP2F+vQ TRETHQnLcW3rLv0NMk5oQvIKpJoC9ett6aeVrzu+4cU4DZVWYlJUoC/ljWzCluau 8blfW0Vwin6OB7s0HCG5/wijQWJBU5SrP/KAIPeQi1GqG5efbqAXDr/ple0Ipwyo Xjjl73LenGUgqpANlC9EAT4i7FkJcllLPeK3NcOHjuUG0AccLv1lGsHAxZLgjk/x z9ZcnVV9UFWZiyJTKxeKPwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBRWyMuZUo4gxCR3Luf9/bd2AqZ7CjAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI hvcNAQELBQADggEBAIqN2DlIKlvDFPO0QUZQVFbsi/tLdYM98/vvzBpttlTGVMyD gJuQeHVz+MnhGIwoCGOlGU3OOUoIlLAut0+WG74qYczn43oA2gbMd7HoD7oL/IGg njorBwJVcuuLv2G//SqM3nxGcLRtkRnQ+lvqPxMz9+0fKFUn6QcIDuF0QSfthLs2 WSiGEPKO9c9RSXdRQ4pXA7c3hXng8P4A2ZmdciPne5Nu4I4qLDGZYRrRLRkNTrOi TyS6r2HNGUfgF7eOSeKt3NWL+mNChcYj71/Vycf5edeczpUgfnWy9WbPrK1svKyl aAs2xg+X6O8qB+Mnj2dNBzm+lZIS3sIlm+nO9sg= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjSgAwIBAgIRAPAlEk8VJPmEzVRRaWvTh2AwCgYIKoZIzj0EAwMwgZYx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1h em9uIFJEUyB1cy1lYXN0LTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTI1MjI0MTU1WhgPMjEyMTA1MjUyMzQxNTVaMIGWMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExLzAtBgNVBAMMJkFtYXpvbiBS RFMgdXMtZWFzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdTZWF0dGxl MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEx5xjrup8II4HOJw15NTnS3H5yMrQGlbj EDA5MMGnE9DmHp5dACIxmPXPMe/99nO7wNdl7G71OYPCgEvWm0FhdvVUeTb3LVnV BnaXt32Ek7/oxGk1T+Df03C+W0vmuJ+wo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBTGXmqBWN/1tkSea4pNw0oHrjk2UDAOBgNVHQ8BAf8EBAMCAYYwCgYI KoZIzj0EAwMDaAAwZQIxAIqqZWCSrIkZ7zsv/FygtAusW6yvlL935YAWYPVXU30m jkMFLM+/RJ9GMvnO8jHfCgIwB+whlkcItzE9CRQ6CsMo/d5cEHDUu/QW6jSIh9BR OGh9pTYPVkUbBiKPA7lVVhre -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 nWS0 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtDCCAjmgAwIBAgIQKKqVZvk6NsLET+uYv5myCzAKBggqhkjOPQQDAzCBmTEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTIwMAYDVQQDDClBbWF6 b24gUkRTIGlsLWNlbnRyYWwtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwH U2VhdHRsZTAgFw0yMjEyMDIyMDMyMjBaGA8yMTIyMTIwMjIxMzIyMFowgZkxCzAJ BgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMw EQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEyMDAGA1UEAwwpQW1hem9u IFJEUyBpbC1jZW50cmFsLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASYwfvj8BmvLAP6UkNQ4X4dXBB/ webBO7swW+8HnFN2DAu+Cn/lpcDpu+dys1JmkVX435lrCH3oZjol0kCDIM1lF4Cv +78yoY1Jr/YMat22E4iz4AZd9q0NToS7+ZA0r2yjQjBAMA8GA1UdEwEB/wQFMAMB Af8wHQYDVR0OBBYEFO/8Py16qPr7J2GWpvxlTMB+op7XMA4GA1UdDwEB/wQEAwIB hjAKBggqhkjOPQQDAwNpADBmAjEAwk+rg788+u8JL6sdix7l57WTo8E/M+o3TO5x uRuPdShrBFm4ArGR2PPs4zCQuKgqAjEAi0TA3PVqAxKpoz+Ps8/054p9WTgDfBFZ i/lm2yTaPs0xjY6FNWoy7fsVw5oEKxOn -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGCTCCA/GgAwIBAgIRAOY7gfcBZgR2tqfBzMbFQCUwDQYJKoZIhvcNAQEMBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1zb3V0aGVhc3QtNCBSb290IENBIFJTQTQwOTYgRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjIwNTI1MTY1NDU5WhgPMjEyMjA1MjUxNzU0NTla MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtc291dGhlYXN0LTQgUm9vdCBDQSBSU0E0MDk2IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA lfxER43FuLRdL08bddF0YhbCP+XXKj1A/TFMXmd2My8XDei8rPXFYyyjMig9+xZw uAsIxLwz8uiA26CKA8bCZKg5VG2kTeOJAfvBJaLv1CZefs3Z4Uf1Sjvm6MF2yqEj GoORfyfL9HiZFTDuF/hcjWoKYCfMuG6M/wO8IbdICrX3n+BiYQJu/pFO660Mg3h/ 8YBBWYDbHoCiH/vkqqJugQ5BM3OI5nsElW51P1icEEqti4AZ7JmtSv9t7fIFBVyR oaEyOgpp0sm193F/cDJQdssvjoOnaubsSYm1ep3awZAUyGN/X8MBrPY95d0hLhfH Ehc5Icyg+hsosBljlAyksmt4hFQ9iBnWIz/ZTfGMck+6p3HVL9RDgvluez+rWv59 8q7omUGsiPApy5PDdwI/Wt/KtC34/2sjslIJfvgifdAtkRPkhff1WEwER00ADrN9 eGGInaCpJfb1Rq8cV2n00jxg7DcEd65VR3dmIRb0bL+jWK62ni/WdEyomAOMfmGj aWf78S/4rasHllWJ+QwnaUYY3u6N8Cgio0/ep4i34FxMXqMV3V0/qXdfhyabi/LM wCxNo1Dwt+s6OtPJbwO92JL+829QAxydfmaMTeHBsgMPkG7RwAekeuatKGHNsc2Z x2Q4C2wVvOGAhcHwxfM8JfZs3nDSZJndtVVnFlUY0UECAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQUpnG7mWazy6k97/tb5iduRB3RXgQwDgYDVR0P AQH/BAQDAgGGMA0GCSqGSIb3DQEBDAUAA4ICAQCDLqq1Wwa9Tkuv7vxBnIeVvvFF ecTn+P+wJxl9Qa2ortzqTHZsBDyJO62d04AgBwiDXkJ9a+bthgG0H1J7Xee8xqv1 xyX2yKj24ygHjspLotKP4eDMdDi5TYq+gdkbPmm9Q69B1+W6e049JVGXvWG8/7kU igxeuCYwtCCdUPRLf6D8y+1XMGgVv3/DSOHWvTg3MJ1wJ3n3+eve3rjGdRYWZeJu k21HLSZYzVrCtUsh2YAeLnUbSxVuT2Xr4JehYe9zW5HEQ8Je/OUfnCy9vzoN/ITw osAH+EBJQey7RxEDqMwCaRefH0yeHFcnOll0OXg/urnQmwbEYzQ1uutJaBPsjU0J Qf06sMxI7GiB5nPE+CnI2sM6A9AW9kvwexGXpNJiLxF8dvPQthpOKGcYu6BFvRmt 6ctfXd9b7JJoVqMWuf5cCY6ihpk1e9JTlAqu4Eb/7JNyGiGCR40iSLvV28un9wiE plrdYxwcNYq851BEu3r3AyYWw/UW1AKJ5tM+/Gtok+AphMC9ywT66o/Kfu44mOWm L3nSLSWEcgfUVgrikpnyGbUnGtgCmHiMlUtNVexcE7OtCIZoVAlCGKNu7tyuJf10 Qlk8oIIzfSIlcbHpOYoN79FkLoDNc2er4Gd+7w1oPQmdAB0jBJnA6t0OUBPKdDdE Ufff2jrbfbzECn1ELg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 fejbXelUSJSzDIdY -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGCTCCA/GgAwIBAgIRAN7Y9G9i4I+ZaslPobE7VL4wDQYJKoZIhvcNAQEMBQAw gZwxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTE1MDMGA1UEAwws QW1hem9uIFJEUyBhcC1ub3J0aGVhc3QtMiBSb290IENBIFJTQTQwOTYgRzExEDAO BgNVBAcMB1NlYXR0bGUwIBcNMjEwNTIwMTYzMzIzWhgPMjEyMTA1MjAxNzMzMjNa MIGcMQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywg SW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExNTAzBgNVBAMM LEFtYXpvbiBSRFMgYXAtbm9ydGhlYXN0LTIgUm9vdCBDQSBSU0E0MDk2IEcxMRAw DgYDVQQHDAdTZWF0dGxlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA 4BEPCiIfiK66Q/qa8k+eqf1Q3qsa6Xuu/fPkpuStXVBShhtXd3eqrM0iT4Xxs420 Va0vSB3oZ7l86P9zYfa60n6PzRxdYFckYX330aI7L/oFIdaodB/C9szvROI0oLG+ 6RwmIF2zcprH0cTby8MiM7G3v9ykpq27g4WhDC1if2j8giOQL3oHpUaByekZNIHF dIllsI3RkXmR3xmmxoOxJM1B9MZi7e1CvuVtTGOnSGpNCQiqofehTGwxCN2wFSK8 xysaWlw48G0VzZs7cbxoXMH9QbMpb4tpk0d+T8JfAPu6uWO9UwCLWWydf0CkmA/+ D50/xd1t33X9P4FEaPSg5lYbHXzSLWn7oLbrN2UqMLaQrkoEBg/VGvzmfN0mbflw +T87bJ/VEOVNlG+gepyCTf89qIQVWOjuYMox4sK0PjzZGsYEuYiq1+OUT3vk/e5K ag1fCcq2Isy4/iwB2xcXrsQ6ljwdk1fc+EmOnjGKrhuOHJY3S+RFv4ToQBsVyYhC XGaC3EkqIX0xaCpDimxYhFjWhpDXAjG/zJ+hRLDAMCMhl/LPGRk/D1kzSbPmdjpl lEMK5695PeBvEBTQdBQdOiYgOU3vWU6tzwwHfiM2/wgvess/q0FDAHfJhppbgbb9 3vgsIUcsvoC5o29JvMsUxsDRvsAfEmMSDGkJoA/X6GECAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQUgEWm1mZCbGD6ytbwk2UU1aLaOUUwDgYDVR0P AQH/BAQDAgGGMA0GCSqGSIb3DQEBDAUAA4ICAQBb4+ABTGBGwxK1U/q4g8JDqTQM 1Wh8Oz8yAk4XtPJMAmCctxbd81cRnSnePWw/hxViLVtkZ/GsemvXfqAQyOn1coN7 QeYSw+ZOlu0j2jEJVynmgsR7nIRqE7QkCyZAU+d2FTJUfmee+IiBiGyFGgxz9n7A JhBZ/eahBbiuoOik/APW2JWLh0xp0W0GznfJ8lAlaQTyDa8iDXmVtbJg9P9qzkvl FgPXQttzEOyooF8Pb2LCZO4kUz+1sbU7tHdr2YE+SXxt6D3SBv+Yf0FlvyWLiqVk GDEOlPPTDSjAWgKnqST8UJ0RDcZK/v1ixs7ayqQJU0GUQm1I7LGTErWXHMnCuHKe UKYuiSZwmTcJ06NgdhcCnGZgPq13ryMDqxPeltQc3n5eO7f1cL9ERYLDLOzm6A9P oQ3MfcVOsbHgGHZWaPSeNrQRN9xefqBXH0ZPasgcH9WJdsLlEjVUXoultaHOKx3b UCCb+d3EfqF6pRT488ippOL6bk7zNubwhRa/+y4wjZtwe3kAX78ACJVcjPobH9jZ ErySads5zdQeaoee5wRKdp3TOfvuCe4bwLRdhOLCHWzEcXzY3g/6+ppLvNom8o+h Bh5X26G6KSfr9tqhQ3O9IcbARjnuPbvtJnoPY0gz3EHHGPhy0RNW8i2gl3nUp0ah PtjwbKW0hYAhIttT0Q== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtzCCAj2gAwIBAgIQQRBQTs6Y3H1DDbpHGta3lzAKBggqhkjOPQQDAzCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLXNvdXRoZWFzdC0zIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDYxMTAwMTI0M1oYDzIxMjEwNjExMDExMjQzWjCBmzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTQwMgYDVQQDDCtBbWF6 b24gUkRTIGFwLXNvdXRoZWFzdC0zIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQH DAdTZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEs0942Xj4m/gKA+WA6F5h AHYuek9eGpzTRoLJddM4rEV1T3eSueytMVKOSlS3Ub9IhyQrH2D8EHsLYk9ktnGR pATk0kCYTqFbB7onNo070lmMJmGT/Q7NgwC8cySChFxbo0IwQDAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBQ20iKBKiNkcbIZRu0y1uoF1yJTEzAOBgNVHQ8BAf8E BAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwYv0wTSrpQTaPaarfLN8Xcqrqu3hzl07n FrESIoRw6Cx77ZscFi2/MV6AFyjCV/TlAjEAhpwJ3tpzPXpThRML8DMJYZ3YgMh3 CMuLqhPpla3cL0PhybrD27hJWl29C4el6aMO -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrDCCAjOgAwIBAgIQGcztRyV40pyMKbNeSN+vXTAKBggqhkjOPQQDAzCBljEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMS8wLQYDVQQDDCZBbWF6 b24gUkRTIHVzLWVhc3QtMiBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2Vh dHRsZTAgFw0yMTA1MjEyMzE1NTZaGA8yMTIxMDUyMjAwMTU1NlowgZYxCzAJBgNV BAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYD VQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1hem9uIFJE UyB1cy1lYXN0LTIgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1NlYXR0bGUw djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQfDcv+GGRESD9wT+I5YIPRsD3L+/jsiIis Tr7t9RSbFl+gYpO7ZbDXvNbV5UGOC5lMJo/SnqFRTC6vL06NF7qOHfig3XO8QnQz 6T5uhhrhnX2RSY3/10d2kTyHq3ZZg3+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFLDyD3PRyNXpvKHPYYxjHXWOgfPnMA4GA1UdDwEB/wQEAwIBhjAKBggq hkjOPQQDAwNnADBkAjB20HQp6YL7CqYD82KaLGzgw305aUKw2aMrdkBR29J183jY 6Ocj9+Wcif9xnRMS+7oCMAvrt03rbh4SU9BohpRUcQ2Pjkh7RoY0jDR4Xq4qzjNr 5UFr3BXpFvACxXF51BksGQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjWgAwIBAgIQeKbS5zvtqDvRtwr5H48cAjAKBggqhkjOPQQDAzCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIG1lLXNvdXRoLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTIwMTcxOTU1WhgPMjEyMTA1MjAxODE5NTVaMIGXMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpvbiBS RFMgbWUtc291dGgtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2VhdHRs ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABEKjgUaAPmUlRMEQdBC7BScAGosJ1zRV LDd38qTBjzgmwBfQJ5ZfGIvyEK5unB09MB4e/3qqK5I/L6Qn5Px/n5g4dq0c7MQZ u7G9GBYm90U3WRJBf7lQrPStXaRnS4A/O6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUNKcAbGEIn03/vkwd8g6jNyiRdD4wDgYDVR0PAQH/BAQDAgGGMAoG CCqGSM49BAMDA2cAMGQCMHIeTrjenCSYuGC6txuBt/0ZwnM/ciO9kHGWVCoK8QLs jGghb5/YSFGZbmQ6qpGlSAIwVOQgdFfTpEfe5i+Vs9frLJ4QKAfc27cTNYzRIM0I E+AJgK4C4+DiyyMzOpiCfmvq -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 WT1QcNdw7ntUJP/w -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrzCCAjWgAwIBAgIQARky6+5PNFRkFVOp3Ob1CTAKBggqhkjOPQQDAzCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGV1LXNvdXRoLTIgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjIwNTIzMTg0MTI4WhgPMjEyMjA1MjMxOTQxMjdaMIGXMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpvbiBS RFMgZXUtc291dGgtMiBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2VhdHRs ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABNVGL5oF7cfIBxKyWd2PVK/S5yQfaJY3 QFHWvEdt6951n9JhiiPrHzfVHsxZp1CBjILRMzjgRbYWmc8qRoLkgGE7htGdwudJ Fa/WuKzO574Prv4iZXUnVGTboC7JdvKbh6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUgDeIIEKynwUbNXApdIPnmRWieZwwDgYDVR0PAQH/BAQDAgGGMAoG CCqGSM49BAMDA2gAMGUCMEOOJfucrST+FxuqJkMZyCM3gWGZaB+/w6+XUAJC6hFM uSTY0F44/bERkA4XhH+YGAIxAIpJQBakCA1/mXjsTnQ+0El9ty+LODp8ibkn031c 8DKDS7pR9UK7ZYdR6zFg3ZCjQw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjOgAwIBAgIQJvkWUcYLbnxtuwnyjMmntDAKBggqhkjOPQQDAzCBljEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMS8wLQYDVQQDDCZBbWF6 b24gUkRTIGV1LXdlc3QtMyBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2Vh dHRsZTAgFw0yMTA1MjUyMjI2MTJaGA8yMTIxMDUyNTIzMjYxMlowgZYxCzAJBgNV BAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMwEQYD VQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1hem9uIFJE UyBldS13ZXN0LTMgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1NlYXR0bGUw djAQBgcqhkjOPQIBBgUrgQQAIgNiAARENn8uHCyjn1dFax4OeXxvbV861qsXFD9G DshumTmFzWWHN/69WN/AOsxy9XN5S7Cgad4gQgeYYYgZ5taw+tFo/jQvCLY//uR5 uihcLuLJ78opvRPvD9kbWZ6oXfBtFkWjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFKiK3LpoF+gDnqPldGSwChBPCYciMA4GA1UdDwEB/wQEAwIBhjAKBggq hkjOPQQDAwNpADBmAjEA+7qfvRlnvF1Aosyp9HzxxCbN7VKu+QXXPhLEBWa5oeWW UOcifunf/IVLC4/FGCsLAjEAte1AYp+iJyOHDB8UYkhBE/1sxnFaTiEPbvQBU0wZ SuwWVLhu2wWDuSW+K7tTuL8p -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/zCCAuegAwIBAgIRAKeDpqX5WFCGNo94M4v69sUwDQYJKoZIhvcNAQELBQAw gZcxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwn QW1hem9uIFJEUyBldS13ZXN0LTMgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyNTIyMTgzM1oYDzIwNjEwNTI1MjMxODMzWjCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGV1LXdlc3QtMyBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcMB1Nl YXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcKOTEMTfzvs4H WtJR8gI7GXN6xesulWtZPv21oT+fLGwJ+9Bv8ADCGDDrDxfeH/HxJmzG9hgVAzVn 4g97Bn7q07tGZM5pVi96/aNp11velZT7spOJKfJDZTlGns6DPdHmx48whpdO+dOb 6+eR0VwCIv+Vl1fWXgoACXYCoKjhxJs+R+fwY//0JJ1YG8yjZ+ghLCJmvlkOJmE1 TCPUyIENaEONd6T+FHGLVYRRxC2cPO65Jc4yQjsXvvQypoGgx7FwD5voNJnFMdyY 754JGPOOe/SZdepN7Tz7UEq8kn7NQSbhmCsgA/Hkjkchz96qN/YJ+H/okiQUTNB0 eG9ogiVFAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFjayw9Y MjbxfF14XAhMM2VPl0PfMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC AQEAAtmx6d9+9CWlMoU0JCirtp4dSS41bBfb9Oor6GQ8WIr2LdfZLL6uES/ubJPE 1Sh5Vu/Zon5/MbqLMVrfniv3UpQIof37jKXsjZJFE1JVD/qQfRzG8AlBkYgHNEiS VtD4lFxERmaCkY1tjKB4Dbd5hfhdrDy29618ZjbSP7NwAfnwb96jobCmMKgxVGiH UqsLSiEBZ33b2hI7PJ6iTJnYBWGuiDnsWzKRmheA4nxwbmcQSfjbrNwa93w3caL2 v/4u54Kcasvcu3yFsUwJygt8z43jsGAemNZsS7GWESxVVlW93MJRn6M+MMakkl9L tWaXdHZ+KUV7LhfYLb0ajvb40w== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBDCCAuygAwIBAgIQJ5oxPEjefCsaESSwrxk68DANBgkqhkiG9w0BAQsFADCB mjELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTMwMQYDVQQDDCpB bWF6b24gUkRTIGV1LWNlbnRyYWwtMiBSb290IENBIFJTQTIwNDggRzExEDAOBgNV BAcMB1NlYXR0bGUwIBcNMjIwNjA2MjExNzA1WhgPMjA2MjA2MDYyMjE3MDVaMIGa MQswCQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5j LjETMBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMzAxBgNVBAMMKkFt YXpvbiBSRFMgZXUtY2VudHJhbC0yIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UE BwwHU2VhdHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTQt5eX g+VP3BjO9VBkWJhE0GfLrU/QIk32I6WvrnejayTrlup9H1z4QWlXF7GNJrqScRMY KhJHlcP05aPsx1lYco6pdFOf42ybXyWHHJdShj4A5glU81GTT+VrXGzHSarLmtua eozkQgPpDsSlPt0RefyTyel7r3Cq+5K/4vyjCTcIqbfgaGwTU36ffjM1LaPCuE4O nINMeD6YuImt2hU/mFl20FZ+IZQUIFZZU7pxGLqTRz/PWcH8tDDxnkYg7tNuXOeN JbTpXrw7St50/E9ZQ0llGS+MxJD8jGRAa/oL4G/cwnV8P2OEPVVkgN9xDDQeieo0 3xkzolkDkmeKOnUCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU bwu8635iQGQMRanekesORM8Hkm4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB CwUAA4IBAQAgN6LE9mUgjsj6xGCX1afYE69fnmCjjb0rC6eEe1mb/QZNcyw4XBIW 6+zTXo4mjZ4ffoxb//R0/+vdTE7IvaLgfAZgFsLKJCtYDDstXZj8ujQnGR9Pig3R W+LpNacvOOSJSawNQq0Xrlcu55AU4buyD5VjcICnfF1dqBMnGTnh27m/scd/ZMx/ kapHZ/fMoK2mAgSX/NvUKF3UkhT85vSSM2BTtET33DzCPDQTZQYxFBa4rFRmFi4c BLlmIReiCGyh3eJhuUUuYAbK6wLaRyPsyEcIOLMQmZe1+gAFm1+1/q5Ke9ugBmjf PbTWjsi/lfZ5CdVAhc5lmZj/l5aKqwaS -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjSgAwIBAgIRAKKPTYKln9L4NTx9dpZGUjowCgYIKoZIzj0EAwMwgZYx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1h em9uIFJEUyBldS13ZXN0LTIgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTIxMjI1NTIxWhgPMjEyMTA1MjEyMzU1MjFaMIGWMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExLzAtBgNVBAMMJkFtYXpvbiBS RFMgZXUtd2VzdC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdTZWF0dGxl MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE/owTReDvaRqdmbtTzXbyRmEpKCETNj6O hZMKH0F8oU9Tmn8RU7kQQj6xUKEyjLPrFBN7c+26TvrVO1KmJAvbc8bVliiJZMbc C0yV5PtJTalvlMZA1NnciZuhxaxrzlK1o0IwQDAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBT4i5HaoHtrs7Mi8auLhMbKM1XevDAOBgNVHQ8BAf8EBAMCAYYwCgYI KoZIzj0EAwMDaAAwZQIxAK9A+8/lFdX4XJKgfP+ZLy5ySXC2E0Spoy12Gv2GdUEZ p1G7c1KbWVlyb1d6subzkQIwKyH0Naf/3usWfftkmq8SzagicKz5cGcEUaULq4tO GzA/AMpr63IDBAqkZbMDTCmH -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrzCCAjWgAwIBAgIQTgIvwTDuNWQo0Oe1sOPQEzAKBggqhkjOPQQDAzCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGV1LW5vcnRoLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTI0MjEwNjM4WhgPMjEyMTA1MjQyMjA2MzhaMIGXMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpvbiBS RFMgZXUtbm9ydGgtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2VhdHRs ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJuzXLU8q6WwSKXBvx8BbdIi3mPhb7Xo rNJBfuMW1XRj5BcKH1ZoGaDGw+BIIwyBJg8qNmCK8kqIb4cH8/Hbo3Y+xBJyoXq/ cuk8aPrxiNoRsKWwiDHCsVxaK9L7GhHHAqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUYgcsdU4fm5xtuqLNppkfTHM2QMYwDgYDVR0PAQH/BAQDAgGGMAoG CCqGSM49BAMDA2gAMGUCMQDz/Rm89+QJOWJecYAmYcBWCcETASyoK1kbr4vw7Hsg 7Ew3LpLeq4IRmTyuiTMl0gMCMAa0QSjfAnxBKGhAnYxcNJSntUyyMpaXzur43ec0 3D8npJghwC4DuICtKEkQiI5cSg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 u3UBpZI= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtDCCAjmgAwIBAgIQenQbcP/Zbj9JxvZ+jXbRnTAKBggqhkjOPQQDAzCBmTEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTIwMAYDVQQDDClBbWF6 b24gUkRTIGV1LWNlbnRyYWwtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwH U2VhdHRsZTAgFw0yMTA1MjEyMjMzMjRaGA8yMTIxMDUyMTIzMzMyNFowgZkxCzAJ BgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRMw EQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEyMDAGA1UEAwwpQW1hem9u IFJEUyBldS1jZW50cmFsLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATlBHiEM9LoEb1Hdnd5j2VpCDOU 5nGuFoBD8ROUCkFLFh5mHrHfPXwBc63heW9WrP3qnDEm+UZEUvW7ROvtWCTPZdLz Z4XaqgAlSqeE2VfUyZOZzBSgUUJk7OlznXfkCMOjQjBAMA8GA1UdEwEB/wQFMAMB Af8wHQYDVR0OBBYEFDT/ThjQZl42Nv/4Z/7JYaPNMly2MA4GA1UdDwEB/wQEAwIB hjAKBggqhkjOPQQDAwNpADBmAjEAnZWmSgpEbmq+oiCa13l5aGmxSlfp9h12Orvw Dq/W5cENJz891QD0ufOsic5oGq1JAjEAp5kSJj0MxJBTHQze1Aa9gG4sjHBxXn98 4MP1VGsQuhfndNHQb4V0Au7OWnOeiobq -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/zCCAuegAwIBAgIRAMgnyikWz46xY6yRgiYwZ3swDQYJKoZIhvcNAQELBQAw gZcxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwn QW1hem9uIFJEUyBldS13ZXN0LTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyMDE2NDkxMloYDzIwNjEwNTIwMTc0OTEyWjCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGV1LXdlc3QtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcMB1Nl YXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi8JYOc9cYSgZH gYPxLk6Xcc7HqzamvsnjYU98Dcb98y6iDqS46Ra2Ne02MITtU5MDL+qjxb8WGDZV RUA9ZS69tkTO3gldW8QdiSh3J6hVNJQW81F0M7ZWgV0gB3n76WCmfT4IWos0AXHM 5v7M/M4tqVmCPViQnZb2kdVlM3/Xc9GInfSMCgNfwHPTXl+PXX+xCdNBePaP/A5C 5S0oK3HiXaKGQAy3K7VnaQaYdiv32XUatlM4K2WS4AMKt+2cw3hTCjlmqKRHvYFQ veWCXAuc+U5PQDJ9SuxB1buFJZhT4VP3JagOuZbh5NWpIbOTxlAJOb5pGEDuJTKi 1gQQQVEFAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNXm+N87 OFxK9Af/bjSxDCiulGUzMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC AQEAkqIbkgZ45spvrgRQ6n9VKzDLvNg+WciLtmVrqyohwwJbj4pYvWwnKQCkVc7c hUOSBmlSBa5REAPbH5o8bdt00FPRrD6BdXLXhaECKgjsHe1WW08nsequRKD8xVmc 8bEX6sw/utBeBV3mB+3Zv7ejYAbDFM4vnRsWtO+XqgReOgrl+cwdA6SNQT9oW3e5 rSQ+VaXgJtl9NhkiIysq9BeYigxqS/A13pHQp0COMwS8nz+kBPHhJTsajHCDc8F4 HfLi6cgs9G0gaRhT8FCH66OdGSqn196sE7Y3bPFFFs/3U+vxvmQgoZC6jegQXAg5 Prxd+VNXtNI/azitTysQPumH7A== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEBTCCAu2gAwIBAgIRAO8bekN7rUReuNPG8pSTKtEwDQYJKoZIhvcNAQELBQAw gZoxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEzMDEGA1UEAwwq QW1hem9uIFJEUyBldS1jZW50cmFsLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYD VQQHDAdTZWF0dGxlMCAXDTIxMDUyMTIyMjM0N1oYDzIwNjEwNTIxMjMyMzQ3WjCB mjELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTMwMQYDVQQDDCpB bWF6b24gUkRTIGV1LWNlbnRyYWwtMSBSb290IENBIFJTQTIwNDggRzExEDAOBgNV BAcMB1NlYXR0bGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCTTYds Tray+Q9VA5j5jTh5TunHKFQzn68ZbOzdqaoi/Rq4ohfC0xdLrxCpfqn2TGDHN6Zi 2qGK1tWJZEd1H0trhzd9d1CtGK+3cjabUmz/TjSW/qBar7e9MA67/iJ74Gc+Ww43 A0xPNIWcL4aLrHaLm7sHgAO2UCKsrBUpxErOAACERScVYwPAfu79xeFcX7DmcX+e lIqY16pQAvK2RIzrekSYfLFxwFq2hnlgKHaVgZ3keKP+nmXcXmRSHQYUUr72oYNZ HcNYl2+gxCc9ccPEHM7xncVEKmb5cWEWvVoaysgQ+osi5f5aQdzgC2X2g2daKbyA XL/z5FM9GHpS5BJjAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FBDAiJ7Py9/A9etNa/ebOnx5l5MGMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0B AQsFAAOCAQEALMh/+81fFPdJV/RrJUeoUvFCGMp8iaANu97NpeJyKitNOv7RoeVP WjivS0KcCqZaDBs+p6IZ0sLI5ZH098LDzzytcfZg0PsGqUAb8a0MiU/LfgDCI9Ee jsOiwaFB8k0tfUJK32NPcIoQYApTMT2e26lPzYORSkfuntme2PTHUnuC7ikiQrZk P+SZjWgRuMcp09JfRXyAYWIuix4Gy0eZ4rpRuaTK6mjAb1/LYoNK/iZ/gTeIqrNt l70OWRsWW8jEmSyNTIubGK/gGGyfuZGSyqoRX6OKHESkP6SSulbIZHyJ5VZkgtXo 2XvyRyJ7w5pFyoofrL3Wv0UF8yt/GDszmg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF/zCCA+egAwIBAgIRAMDk/F+rrhdn42SfE+ghPC8wDQYJKoZIhvcNAQEMBQAw gZcxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwn QW1hem9uIFJEUyBldS13ZXN0LTIgUm9vdCBDQSBSU0E0MDk2IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyMTIyNTEyMloYDzIxMjEwNTIxMjM1MTIyWjCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGV1LXdlc3QtMiBSb290IENBIFJTQTQwOTYgRzExEDAOBgNVBAcMB1Nl YXR0bGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2twMALVg9vRVu VNqsr6N8thmp3Dy8jEGTsm3GCQ+C5P2YcGlD/T/5icfWW84uF7Sx3ezcGlvsqFMf Ukj9sQyqtz7qfFFugyy7pa/eH9f48kWFHLbQYm9GEgbYBIrWMp1cy3vyxuMCwQN4 DCncqU+yNpy0CprQJEha3PzY+3yJOjDQtc3zr99lyECCFJTDUucxHzyQvX89eL74 uh8la0lKH3v9wPpnEoftbrwmm5jHNFdzj7uXUHUJ41N7af7z7QUfghIRhlBDiKtx 5lYZemPCXajTc3ryDKUZC/b+B6ViXZmAeMdmQoPE0jwyEp/uaUcdp+FlUQwCfsBk ayPFEApTWgPiku2isjdeTVmEgL8bJTDUZ6FYFR7ZHcYAsDzcwHgIu3GGEMVRS3Uf ILmioiyly9vcK4Sa01ondARmsi/I0s7pWpKflaekyv5boJKD/xqwz9lGejmJHelf 8Od2TyqJScMpB7Q8c2ROxBwqwB72jMCEvYigB+Wnbb8RipliqNflIGx938FRCzKL UQUBmNAznR/yRRL0wHf9UAE/8v9a09uZABeiznzOFAl/frHpgdAbC00LkFlnwwgX g8YfEFlkp4fLx5B7LtoO6uVNFVimLxtwirpyKoj3G4M/kvSTux8bTw0heBCmWmKR 57MS6k7ODzbv+Kpeht2hqVZCNFMxoQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/ MB0GA1UdDgQWBBRuMnDhJjoj7DcKALj+HbxEqj3r6jAOBgNVHQ8BAf8EBAMCAYYw DQYJKoZIhvcNAQEMBQADggIBALSnXfx72C3ldhBP5kY4Mo2DDaGQ8FGpTOOiD95d 0rf7I9LrsBGVqu/Nir+kqqP80PB70+Jy9fHFFigXwcPBX3MpKGxK8Cel7kVf8t1B 4YD6A6bqlzP+OUL0uGWfZpdpDxwMDI2Flt4NEldHgXWPjvN1VblEKs0+kPnKowyg jhRMgBbD/y+8yg0fIcjXUDTAw/+INcp21gWaMukKQr/8HswqC1yoqW9in2ijQkpK 2RB9vcQ0/gXR0oJUbZQx0jn0OH8Agt7yfMAnJAdnHO4M3gjvlJLzIC5/4aGrRXZl JoZKfJ2fZRnrFMi0nhAYDeInoS+Rwx+QzaBk6fX5VPyCj8foZ0nmqvuYoydzD8W5 mMlycgxFqS+DUmO+liWllQC4/MnVBlHGB1Cu3wTj5kgOvNs/k+FW3GXGzD3+rpv0 QTLuwSbMr+MbEThxrSZRSXTCQzKfehyC+WZejgLb+8ylLJUA10e62o7H9PvCrwj+ ZDVmN7qj6amzvndCP98sZfX7CFZPLfcBd4wVIjHsFjSNEwWHOiFyLPPG7cdolGKA lOFvonvo4A1uRc13/zFeP0Xi5n5OZ2go8aOOeGYdI2vB2sgH9R2IASH/jHmr0gvY 0dfBCcfXNgrS0toq0LX/y+5KkKOxh52vEYsJLdhqrveuZhQnsFEm/mFwjRXkyO7c 2jpC -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 FEv9Bg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICsDCCAjagAwIBAgIRAMgApnfGYPpK/fD0dbN2U4YwCgYIKoZIzj0EAwMwgZcx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwnQW1h em9uIFJEUyBldS1zb3V0aC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMCAXDTIxMDUxOTE4MzgxMVoYDzIxMjEwNTE5MTkzODExWjCBlzELMAkG A1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzAR BgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6b24g UkRTIGV1LXNvdXRoLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1NlYXR0 bGUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQfEWl6d4qSuIoECdZPp+39LaKsfsX7 THs3/RrtT0+h/jl3bjZ7Qc68k16x+HGcHbaayHfqD0LPdzH/kKtNSfQKqemdxDQh Z4pwkixJu8T1VpXZ5zzCvBXCl75UqgEFS92jQjBAMA8GA1UdEwEB/wQFMAMBAf8w HQYDVR0OBBYEFFPrSNtWS5JU+Tvi6ABV231XbjbEMA4GA1UdDwEB/wQEAwIBhjAK BggqhkjOPQQDAwNoADBlAjEA+a7hF1IrNkBd2N/l7IQYAQw8chnRZDzh4wiGsZsC 6A83maaKFWUKIb3qZYXFSi02AjAbp3wxH3myAmF8WekDHhKcC2zDvyOiKLkg9Y6v ZVmyMR043dscQbcsVoacOYv198c= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtDCCAjqgAwIBAgIRAPhVkIsQ51JFhD2kjFK5uAkwCgYIKoZIzj0EAwMwgZkx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEyMDAGA1UEAwwpQW1h em9uIFJEUyBldS1jZW50cmFsLTIgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjIwNjA2MjEyOTE3WhgPMjEyMjA2MDYyMjI5MTdaMIGZMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMjAwBgNVBAMMKUFtYXpv biBSRFMgZXUtY2VudHJhbC0yIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEA5xnIEBtG5b2nmbj49UEwQza yX0844fXjccYzZ8xCDUe9dS2XOUi0aZlGblgSe/3lwjg8fMcKXLObGGQfgIx1+5h AIBjORis/dlyN5q/yH4U5sjS8tcR0GDGVHrsRUZCo0IwQDAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBRK+lSGutXf4DkTjR3WNfv4+KeNFTAOBgNVHQ8BAf8EBAMC AYYwCgYIKoZIzj0EAwMDaAAwZQIxAJ4NxQ1Gerqr70ZrnUqc62Vl8NNqTzInamCG Kce3FTsMWbS9qkgrjZkO9QqOcGIw/gIwSLrwUT+PKr9+H9eHyGvpq9/3AIYSnFkb Cf3dyWPiLKoAtLFwjzB/CkJlsAS1c8dS -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF/jCCA+agAwIBAgIQGZH12Q7x41qIh9vDu9ikTjANBgkqhkiG9w0BAQwFADCB lzELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdB bWF6b24gUkRTIGV1LXdlc3QtMyBSb290IENBIFJTQTQwOTYgRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTI1MjIyMjMzWhgPMjEyMTA1MjUyMzIyMzNaMIGXMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpv biBSRFMgZXUtd2VzdC0zIFJvb3QgQ0EgUlNBNDA5NiBHMTEQMA4GA1UEBwwHU2Vh dHRsZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMqE47sHXWzdpuqj JHb+6jM9tDbQLDFnYjDWpq4VpLPZhb7xPNh9gnYYTPKG4avG421EblAHqzy9D2pN 1z90yKbIfUb/Sy2MhQbmZomsObhONEra06fJ0Dydyjswf1iYRp2kwpx5AgkVoNo7 3dlws73zFjD7ImKvUx2C7B75bhnw2pJWkFnGcswl8fZt9B5Yt95sFOKEz2MSJE91 kZlHtya19OUxZ/cSGci4MlOySzqzbGwUqGxEIDlY8I39VMwXaYQ8uXUN4G780VcL u46FeyRGxZGz2n3hMc805WAA1V5uir87vuirTvoSVREET97HVRGVVNJJ/FM6GXr1 VKtptybbo81nefYJg9KBysxAa2Ao2x2ry/2ZxwhS6VZ6v1+90bpZA1BIYFEDXXn/ dW07HSCFnYSlgPtSc+Muh15mdr94LspYeDqNIierK9i4tB6ep7llJAnq0BU91fM2 JPeqyoTtc3m06QhLf68ccSxO4l8Hmq9kLSHO7UXgtdjfRVaffngopTNk8qK7bIb7 LrgkqhiQw/PRCZjUdyXL153/fUcsj9nFNe25gM4vcFYwH6c5trd2tUl31NTi1MfG Mgp3d2dqxQBIYANkEjtBDMy3SqQLIo9EymqmVP8xx2A/gCBgaxvMAsI6FSWRoC7+ hqJ8XH4mFnXSHKtYMe6WPY+/XZgtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8w HQYDVR0OBBYEFIkXqTnllT/VJnI2NqipA4XV8rh1MA4GA1UdDwEB/wQEAwIBhjAN BgkqhkiG9w0BAQwFAAOCAgEAKjSle8eenGeHgT8pltWCw/HzWyQruVKhfYIBfKJd MhV4EnH5BK7LxBIvpXGsFUrb0ThzSw0fn0zoA9jBs3i/Sj6KyeZ9qUF6b8ycDXd+ wHonmJiQ7nk7UuMefaYAfs06vosgl1rI7eBHC0itexIQmKh0aX+821l4GEgEoSMf loMFTLXv2w36fPHHCsZ67ODldgcZbKNnpCTX0YrCwEYO3Pz/L398btiRcWGrewrK jdxAAyietra8DRno1Zl87685tfqc6HsL9v8rVw58clAo9XAQvT+fmSOFw/PogRZ7 OMHUat3gu/uQ1M5S64nkLLFsKu7jzudBuoNmcJysPlzIbqJ7vYc82OUGe9ucF3wi 3tbKQ983hdJiTExVRBLX/fYjPsGbG3JtPTv89eg2tjWHlPhCDMMxyRKl6isu2RTq 6VT489Z2zQrC33MYF8ZqO1NKjtyMAMIZwxVu4cGLkVsqFmEV2ScDHa5RadDyD3Ok m+mqybhvEVm5tPgY6p0ILPMN3yvJsMSPSvuBXhO/X5ppNnpw9gnxpwbjQKNhkFaG M5pkADZ14uRguOLM4VthSwUSEAr5VQYCFZhEwK+UOyJAGiB/nJz6IxL5XBNUXmRM Hl8Xvz4riq48LMQbjcVQj0XvH941yPh+P8xOi00SGaQRaWp55Vyr4YKGbV0mEDz1 r1o= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF/zCCA+egAwIBAgIRAKwYju1QWxUZpn6D1gOtwgQwDQYJKoZIhvcNAQEMBQAw gZcxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEwMC4GA1UEAwwn QW1hem9uIFJEUyBldS13ZXN0LTEgUm9vdCBDQSBSU0E0MDk2IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyMDE2NTM1NFoYDzIxMjEwNTIwMTc1MzU0WjCBlzEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6 b24gUkRTIGV1LXdlc3QtMSBSb290IENBIFJTQTQwOTYgRzExEDAOBgNVBAcMB1Nl YXR0bGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCKdBP1U4lqWWkc Cb25/BKRTsvNVnISiKocva8GAzJyKfcGRa85gmgu41U+Hz6+39K+XkRfM0YS4BvQ F1XxWT0bNyypuvwCvmYShSTjN1TY0ltncDddahTajE/4MdSOZb/c98u0yt03cH+G hVwRyT50h0v/UEol50VfwcVAEZEgcQQYhf1IFUFlIvKpmDOqLuFakOnc7c9akK+i ivST+JO1tgowbnNkn2iLlSSgUWgb1gjaOsNfysagv1RXdlyPw3EyfwkFifAQvF2P Q0ayYZfYS640cccv7efM1MSVyFHR9PrrDsF/zr2S2sGPbeHr7R/HwLl+S5J/l9N9 y0rk6IHAWV4dEkOvgpnuJKURwA48iu1Hhi9e4moNS6eqoK2KmY3VFpuiyWcA73nH GSmyaH+YuMrF7Fnuu7GEHZL/o6+F5cL3mj2SJJhL7sz0ryf5Cs5R4yN9BIEj/f49 wh84pM6nexoI0Q4wiSFCxWiBpjSmOK6h7z6+2utaB5p20XDZHhxAlmlx4vMuWtjh XckgRFxc+ZpVMU3cAHUpVEoO49e/+qKEpPzp8Xg4cToKw2+AfTk3cmyyXQfGwXMQ ZUHNZ3w9ILMWihGCM2aGUsLcGDRennvNmnmin/SENsOQ8Ku0/a3teEzwV9cmmdYz 5iYs1YtgPvKFobY6+T2RXXh+A5kprwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/ MB0GA1UdDgQWBBSyUrsQVnKmA8z6/2Ech0rCvqpNmTAOBgNVHQ8BAf8EBAMCAYYw DQYJKoZIhvcNAQEMBQADggIBAFlj3IFmgiFz5lvTzFTRizhVofhTJsGr14Yfkuc7 UrXPuXOwJomd4uot2d/VIeGJpfnuS84qGdmQyGewGTJ9inatHsGZgHl9NHNWRwKZ lTKTbBiq7aqgtUSFa06v202wpzU+1kadxJJePrbABxiXVfOmIW/a1a4hPNcT3syH FIEg1+CGsp71UNjBuwg3JTKWna0sLSKcxLOSOvX1fzxK5djzVpEsvQMB4PSAzXca vENgg2ErTwgTA+4s6rRtiBF9pAusN1QVuBahYP3ftrY6f3ycS4K65GnqscyfvKt5 YgjtEKO3ZeeX8NpubMbzC+0Z6tVKfPFk/9TXuJtwvVeqow0YMrLLyRiYvK7EzJ97 rrkxoKnHYQSZ+rH2tZ5SE392/rfk1PJL0cdHnkpDkUDO+8cKsFjjYKAQSNC52sKX 74AVh6wMwxYwVZZJf2/2XxkjMWWhKNejsZhUkTISSmiLs+qPe3L67IM7GyKm9/m6 R3r8x6NGjhTsKH64iYJg7AeKeax4b2e4hBb6GXFftyOs7unpEOIVkJJgM6gh3mwn R7v4gwFbLKADKt1vHuerSZMiTuNTGhSfCeDM53XI/mjZl2HeuCKP1mCDLlaO+gZR Q/G+E0sBKgEX4xTkAc3kgkuQGfExdGtnN2U2ehF80lBHB8+2y2E+xWWXih/ZyIcW wOx+ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 89cEIGdbjsA= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIQYjbPSg4+RNRD3zNxO1fuKDANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChB bWF6b24gUkRTIGV1LW5vcnRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUyNDIwNTkyMVoYDzIwNjEwNTI0MjE1OTIxWjCBmDEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChBbWF6 b24gUkRTIGV1LW5vcnRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA179eQHxcV0YL XMkqEmhSBazHhnRVd8yICbMq82PitE3BZcnv1Z5Zs/oOgNmMkOKae4tCXO/41JCX wAgbs/eWWi+nnCfpQ/FqbLPg0h3dqzAgeszQyNl9IzTzX4Nd7JFRBVJXPIIKzlRf +GmFsAhi3rYgDgO27pz3ciahVSN+CuACIRYnA0K0s9lhYdddmrW/SYeWyoB7jPa2 LmWpAs7bDOgS4LlP2H3eFepBPgNufRytSQUVA8f58lsE5w25vNiUSnrdlvDrIU5n Qwzc7NIZCx4qJpRbSKWrUtbyJriWfAkGU7i0IoainHLn0eHp9bWkwb9D+C/tMk1X ERZw2PDGkwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSFmR7s dAblusFN+xhf1ae0KUqhWTAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD ggEBAHsXOpjPMyH9lDhPM61zYdja1ebcMVgfUvsDvt+w0xKMKPhBzYDMs/cFOi1N Q8LV79VNNfI2NuvFmGygcvTIR+4h0pqqZ+wjWl3Kk5jVxCrbHg3RBX02QLumKd/i kwGcEtTUvTssn3SM8bgM0/1BDXgImZPC567ciLvWDo0s/Fe9dJJC3E0G7d/4s09n OMdextcxFuWBZrBm/KK3QF0ByA8MG3//VXaGO9OIeeOJCpWn1G1PjT1UklYhkg61 EbsTiZVA2DLd1BGzfU4o4M5mo68l0msse/ndR1nEY6IywwpgIFue7+rEleDh6b9d PYkG1rHVw2I0XDG4o17aOn5E94I= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIQC6W4HFghUkkgyQw14a6JljANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChB bWF6b24gUkRTIGV1LXNvdXRoLTIgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIyMDUyMzE4MTYzMloYDzIwNjIwNTIzMTkxNjMyWjCBmDEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChBbWF6 b24gUkRTIGV1LXNvdXRoLTIgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiM/t4FV2R9Nx UQG203UY83jInTa/6TMq0SPyg617FqYZxvz2kkx09x3dmxepUg9ttGMlPgjsRZM5 LCFEi1FWk+hxHzt7vAdhHES5tdjwds3aIkgNEillmRDVrUsbrDwufLaa+MMDO2E1 wQ/JYFXw16WBCCi2g1EtyQ2Xp+tZDX5IWOTnvhZpW8vVDptZ2AcJ5rMhfOYO3OsK 5EF0GGA5ldzuezP+BkrBYGJ4wVKGxeaq9+5AT8iVZrypjwRkD7Y5CurywK3+aBwm s9Q5Nd8t45JCOUzYp92rFKsCriD86n/JnEvgDfdP6Hvtm0/DkwXK40Wz2q0Zrd0k mjP054NRPwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRR7yqd SfKcX2Q8GzhcVucReIpewTAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD ggEBAEszBRDwXcZyNm07VcFwI1Im94oKwKccuKYeJEsizTBsVon8VpEiMwDs+yGu 3p8kBhvkLwWybkD/vv6McH7T5b9jDX2DoOudqYnnaYeypsPH/00Vh3LvKagqzQza orWLx+0tLo8xW4BtU+Wrn3JId8LvAhxyYXTn9bm+EwPcStp8xGLwu53OPD1RXYuy uu+3ps/2piP7GVfou7H6PRaqbFHNfiGg6Y+WA0HGHiJzn8uLmrRJ5YRdIOOG9/xi qTmAZloUNM7VNuurcMM2hWF494tQpsQ6ysg2qPjbBqzlGoOt3GfBTOZmqmwmqtam K7juWM/mdMQAJ3SMlE5wI8nVdx4= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICrjCCAjSgAwIBAgIRAL9SdzVPcpq7GOpvdGoM80IwCgYIKoZIzj0EAwMwgZYx CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTEvMC0GA1UEAwwmQW1h em9uIFJEUyBldS13ZXN0LTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl YXR0bGUwIBcNMjEwNTIwMTY1ODA3WhgPMjEyMTA1MjAxNzU4MDdaMIGWMQswCQYD VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExLzAtBgNVBAMMJkFtYXpvbiBS RFMgZXUtd2VzdC0xIFJvb3QgQ0EgRUNDMzg0IEcxMRAwDgYDVQQHDAdTZWF0dGxl MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEJWDgXebvwjR+Ce+hxKOLbnsfN5W5dOlP Zn8kwWnD+SLkU81Eac/BDJsXGrMk6jFD1vg16PEkoSevsuYWlC8xR6FmT6F6pmeh fsMGOyJpfK4fyoEPhKeQoT23lFIc5Orjo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBSVNAN1CHAz0eZ77qz2adeqjm31TzAOBgNVHQ8BAf8EBAMCAYYwCgYI KoZIzj0EAwMDaAAwZQIxAMlQeHbcjor49jqmcJ9gRLWdEWpXG8thIf6zfYQ/OEAg d7GDh4fR/OUk0VfjsBUN/gIwZB0bGdXvK38s6AAE/9IT051cz/wMe9GIrX1MnL1T 1F5OqnXJdiwfZRRTHsRQ/L00 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 1YfpdH2jp30= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQTDc+UgTRtYO7ZGTQ8UWKDDANBgkqhkiG9w0BAQsFADCB lzELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdB bWF6b24gUkRTIGV1LXdlc3QtMiBSb290IENBIFJTQTIwNDggRzExEDAOBgNVBAcM B1NlYXR0bGUwIBcNMjEwNTIxMjI0NjI0WhgPMjA2MTA1MjEyMzQ2MjRaMIGXMQsw CQYDVQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjET MBEGA1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpv biBSRFMgZXUtd2VzdC0yIFJvb3QgQ0EgUlNBMjA0OCBHMTEQMA4GA1UEBwwHU2Vh dHRsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM1oGtthQ1YiVIC2 i4u4swMAGxAjc/BZp0yq0eP5ZQFaxnxs7zFAPabEWsrjeDzrRhdVO0h7zskrertP gblGhfD20JfjvCHdP1RUhy/nzG+T+hn6Takan/GIgs8grlBMRHMgBYHW7tklhjaH 3F7LujhceAHhhgp6IOrpb6YTaTTaJbF3GTmkqxSJ3l1LtEoWz8Al/nL/Ftzxrtez Vs6ebpvd7sw37sxmXBWX2OlvUrPCTmladw9OrllGXtCFw4YyLe3zozBlZ3cHzQ0q lINhpRcajTMfZrsiGCkQtoJT+AqVJPS2sHjqsEH8yiySW9Jbq4zyMbM1yqQ2vnnx MJgoYMcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUaQG88UnV JPTI+Pcti1P+q3H7pGYwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IB AQBAkgr75V0sEJimC6QRiTVWEuj2Khy7unjSfudbM6zumhXEU2/sUaVLiYy6cA/x 3v0laDle6T07x9g64j5YastE/4jbzrGgIINFlY0JnaYmR3KZEjgi1s1fkRRf3llL PJm9u4Q1mbwAMQK/ZjLuuRcL3uRIHJek18nRqT5h43GB26qXyvJqeYYpYfIjL9+/ YiZAbSRRZG+Li23cmPWrbA1CJY121SB+WybCbysbOXzhD3Sl2KSZRwSw4p2HrFtV 1Prk0dOBtZxCG9luf87ultuDZpfS0w6oNBAMXocgswk24ylcADkkFxBWW+7BETn1 EpK+t1Lm37mU4sxtuha00XAi -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIQcY44/8NUvBwr6LlHfRy7KjANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChB bWF6b24gUkRTIGV1LXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH DAdTZWF0dGxlMCAXDTIxMDUxOTE4MjcxOFoYDzIwNjEwNTE5MTkyNzE4WjCBmDEL MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChBbWF6 b24gUkRTIGV1LXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQHDAdT ZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0UaBeC+Usalu EtXnV7+PnH+gi7/71tI/jkKVGKuhD2JDVvqLVoqbMHRh3+wGMvqKCjbHPcC2XMWv 566fpAj4UZ9CLB5fVzss+QVNTl+FH2XhEzigopp+872ajsNzcZxrMkifxGb4i0U+ t0Zi+UrbL5tsfP2JonKR1crOrbS6/DlzHBjIiJazGOQcMsJjNuTOItLbMohLpraA /nApa3kOvI7Ufool1/34MG0+wL3UUA4YkZ6oBJVxjZvvs6tI7Lzz/SnhK2widGdc snbLqBpHNIZQSorVoiwcFaRBGYX/uzYkiw44Yfa4cK2V/B5zgu1Fbr0gbI2am4eh yVYyg4jPawIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS9gM1m IIjyh9O5H/7Vj0R/akI7UzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD ggEBAF0Sm9HC2AUyedBVnwgkVXMibnYChOzz7T+0Y+fOLXYAEXex2s8oqGeZdGYX JHkjBn7JXu7LM+TpTbPbFFDoc1sgMguD/ls+8XsqAl1CssW+amryIL+jfcfbgQ+P ICwEUD9hGdjBgJ5WcuS+qqxHsEIlFNci3HxcxfBa9VsWs5TjI7Vsl4meL5lf7ZyL wDV7dHRuU+cImqG1MIvPRIlvPnT7EghrCYi2VCPhP2pM/UvShuwVnkz4MJ29ebIk WR9kpblFxFdE92D5UUvMCjC2kmtgzNiErvTcwIvOO9YCbBHzRB1fFiWrXUHhJWq9 IkaxR5icb/IpAV0A1lYZEWMVsfQ= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 rM2p0kk= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM 9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L 93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU 5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy rqXRfboQnoZsG4q5WTP468SQvvG5 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg 1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K 8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r 2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR 8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz 7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 +XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI 0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY +gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl 7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE 76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H 9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT 4PsJYGw= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM YyRIHN8wfdVoOw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi 9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB /zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW 1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk 6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn 0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN sSi6 -----END CERTIFICATE----- ================================================ FILE: stubs/runtime-with-vendor-download.php ================================================ markTestSkipped('Requires Laravel Octane.'); } parent::setUp(); $_ENV['APP_VANITY_URL'] = 'https://127.0.0.1'; $_ENV['LAMBDA_TASK_ROOT'] = __DIR__.'/../Fixtures'; Octane::boot(app()->basePath()); Octane::worker()->application()->register(OctaneServiceProvider::class); } protected function tearDown(): void { Mockery::close(); unset($_ENV['APP_VANITY_URL']); unset($_ENV['LAMBDA_TASK_ROOT']); unset($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']); Octane::terminate(); parent::tearDown(); } public function test_response_body() { $handler = new OctaneHandler(); Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', ]); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_invalid_uri() { $handler = new OctaneHandler(); Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/////foo', ]); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_response_file() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return response()->file(__DIR__.'/../Fixtures/asset.js', [ 'Content-Type' => 'text/javascript; charset=UTF-8', ]); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); static::assertEquals('text/javascript; charset=UTF-8', $response->toApiGatewayFormat()['headers']['Content-Type']); static::assertEquals("console.log();\n", $response->toApiGatewayFormat()['body']); } public function test_response_download() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return response()->download(__DIR__.'/../Fixtures/asset.js'); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); static::assertEquals('attachment; filename=asset.js', $response->toApiGatewayFormat()['headers']['Content-Disposition']); static::assertEquals("console.log();\n", $response->toApiGatewayFormat()['body']); } public function test_response_fires_events() { Event::fake([RequestReceived::class, RequestTerminated::class]); $handler = new OctaneHandler(); Route::get('/', function () { return response('Hello World')->withHeaders([ 'Foo' => 'Bar', ]); }); $handler->handle([ 'httpMethod' => 'GET', ]); Event::assertDispatched(RequestReceived::class); Event::assertDispatched(RequestTerminated::class); } public function test_response_headers() { $handler = new OctaneHandler(); Route::get('/', function () { return response('Hello World')->withHeaders([ 'Foo' => 'Bar', ]); }); $response = $handler->handle([ 'httpMethod' => 'GET', ]); static::assertArrayHasKey('Foo', $response->toApiGatewayFormat()['headers']); static::assertEquals('Bar', $response->toApiGatewayFormat()['headers']['Foo']); } public function test_response_status() { $handler = new OctaneHandler(); Route::get('/', function () { throw new RuntimeException('Something wrong happened.'); }); $response = $handler->handle([ 'httpMethod' => 'GET', ]); static::assertEquals(500, $response->toApiGatewayFormat()['statusCode']); } public function test_each_request_have_its_own_app() { $handler = new OctaneHandler(); Route::get('/bind', function () { app()->bind('counter', function () { return 1; }); return app('counter'); }); Route::get('/bound', function () { return app()->bound('counter') ? 'bound' : 'not bound'; }); $bindResponse = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/bind', ]); $boundResponse = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/bound', ]); static::assertEquals('1', $bindResponse->toApiGatewayFormat()['body']); static::assertEquals('not bound', $boundResponse->toApiGatewayFormat()['body']); } public function test_response_cookies() { $handler = new OctaneHandler(); Route::get('/', function () { return response('Hello World')->cookie('cookie-key', 'cookie-value', 10); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); $setCookie = $response->toApiGatewayFormat()['headers']['set-cookie']; static::assertStringStartsWith('cookie-key=cookie-value;', $setCookie); } public function test_robots_header_is_set() { $handler = new OctaneHandler(); $_ENV['APP_VANITY_URL'] = 'https://127.0.0.1'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); $robotsTag = $response->toApiGatewayFormat()['headers']['X-Robots-Tag']; static::assertEquals('noindex, nofollow', $robotsTag); } public function test_maintenance_mode() { $handler = new OctaneHandler(); $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'Accept' => 'application/json', ], ]); static::assertEquals('application/json', $response->toApiGatewayFormat()['headers']['Content-Type']); static::assertEquals(['message' => 'We are currently down for maintenance.'], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_body() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return $request->all(); }); $response = $handler->handle([ 'httpMethod' => 'POST', 'path' => '/', 'headers' => [ 'Content-Type' => 'application/json', ], 'body' => <<<'EOF' {"_method":"PUT","name":"nuno","email":"nuno@laravel.com"} EOF ]); static::assertEquals([ '_method' => 'PUT', 'name' => 'nuno', 'email' => 'nuno@laravel.com', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_form_url_encoded_without_inline_input_method() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return $request->all(); }); $response = $handler->handle([ 'httpMethod' => 'PUT', 'path' => '/', 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8', ], 'body' => <<<'EOF' name=nuno&email=nuno@laravel.com EOF ]); static::assertEquals([ 'name' => 'nuno', 'email' => 'nuno@laravel.com', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_cookies() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->cookies->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals( ['XSRF-TOKEN' => 'token_value'], json_decode($response->toApiGatewayFormat()['body'], true) ); } public function test_request_ignores_invalid_cookies() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->cookies->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'cookie' => 'cookieKey1; cookieKey2=cookieValue2', ], ]); static::assertEquals( ['cookieKey2' => 'cookieValue2'], json_decode($response->toApiGatewayFormat()['body'], true) ); } public function test_request_file_uploads() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return array_merge($request->all(), [ 'filename' => $request->file('file')->getClientOriginalName(), 'file' => $request->file('file')->getContent(), ]); }); $response = $handler->handle([ 'httpMethod' => 'POST', 'path' => '/', 'headers' => [ 'Content-Type' => 'multipart/form-data; boundary=---------------------------317050813134112680482597024243', ], 'body' => <<<'EOF' -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="_method" PUT -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="name" nuno -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="email" nuno@laravel.com -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="file"; filename="my_uploaded.txt" Content-Type: text/plain foo -----------------------------317050813134112680482597024243-- EOF ]); static::assertEquals([ '_method' => 'PUT', 'name' => 'nuno', 'email' => 'nuno@laravel.com', 'filename' => 'my_uploaded.txt', 'file' => 'foo', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_file_uploads_without_inline_input_method() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return array_merge($request->all(), [ 'filename' => $request->file('file')->getClientOriginalName(), 'file' => $request->file('file')->getContent(), ]); }); $response = $handler->handle([ 'httpMethod' => 'PUT', 'path' => '/', 'headers' => [ 'Content-Type' => 'multipart/form-data; boundary=---------------------------317050813134112680482597024243', ], 'body' => <<<'EOF' -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="name" nuno -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="email" nuno@laravel.com -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="file"; filename="my_uploaded.txt" Content-Type: text/plain foo -----------------------------317050813134112680482597024243-- EOF ]); static::assertEquals([ 'name' => 'nuno', 'email' => 'nuno@laravel.com', 'filename' => 'my_uploaded.txt', 'file' => 'foo', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_query_string() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->getQueryString(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'multiValueQueryStringParameters' => [ 'param1' => ['value1'], 'param2' => ['value1', 'value2'], ], 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals('param1=value1¶m2[0]=value1¶m2[1]=value2', urldecode($response->toApiGatewayFormat()['body'])); } public function test_request_query_params() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->query(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'multiValueQueryStringParameters' => [ 'param1' => ['value1'], 'param2' => ['value1', 'value2'], ], 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals([ 'param1' => 'value1', 'param2' => ['value1', 'value2'], ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_headers() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->headers->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'X-Xsrf-Token' => 'my-token', ], ]); $body = $response->toApiGatewayFormat()['body']; static::assertEquals(['my-token'], json_decode($body, true)['x-xsrf-token']); } public function test_request_multi_headers() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->headers->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'multiValueHeaders' => [ 'X-Xsrf-Token' => ['my-token'], 'X-Multi-Header' => ['value1', 'value2'], ], ]); $body = $response->toApiGatewayFormat()['body']; static::assertEquals(['my-token'], json_decode($body, true)['x-xsrf-token']); static::assertEquals(['value2'], json_decode($body, true)['x-multi-header']); } public function test_maintenance_mode_with_valid_bypass_cookie() { $octane = new class() extends Octane { public static function hasValidBypassCookie($request, $secret) { return true; } }; $handler = new class() extends OctaneHandler { public function request($event) { return parent::request($event); } public function response($response) { return parent::response($response); } }; $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] = 'my-secret'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->response($octane::handle($handler->request([ 'httpMethod' => 'GET', 'path' => '/', ]))); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_maintenance_mode_with_invalid_bypass_cookie() { $handler = new OctaneHandler(); $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] = 'my-secret'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'Accept' => 'application/json', ], ]); static::assertEquals('application/json', $response->toApiGatewayFormat()['headers']['Content-Type']); static::assertEquals(['message' => 'We are currently down for maintenance.'], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_streamed_responses() { $handler = new OctaneHandler(); Route::get('/', function () { return new StreamedResponse(function () { echo 'Hello World'; }, 200, ['mime-type' => 'image/png']); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [], ]); static::assertEquals('image/png', $response->toApiGatewayFormat()['headers']['Mime-Type']); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } } ================================================ FILE: tests/Feature/Commands/OctaneStatusCommandTest.php ================================================ artisan('octane:status') ->assertSuccessful() ->expectsOutput('Octane server is not running.'); } public function test_when_octane_is_running() { $_ENV['OCTANE_DATABASE_SESSION_TTL'] = 'false'; $this->artisan('octane:status') ->assertSuccessful() ->expectsOutput('Octane server is running.'); } protected function tearDown(): void { unset($_ENV['OCTANE_DATABASE_SESSION_TTL']); unset($_ENV['VAPOR_SSM_PATH']); parent::tearDown(); } } ================================================ FILE: tests/Feature/EnsureOnNakedDomainTest.php ================================================ middleware(EnsureOnNakedDomain::class); } protected function getPackageProviders($app): array { return [ VaporServiceProvider::class, ]; } #[DataProvider('useCases')] public function test_redirects($useCase) { config()->set('vapor.redirect_to_root', $useCase['redirect_to_root']); config()->set('app.url', $useCase['app_url']); $response = $this->get($useCase['request_url']); $response->assertStatus($useCase['response_status']); if ($useCase['response_status'] == 301) { $response->assertRedirect($useCase['redirected_to']); } } public static function useCases() { return [ [[ 'app_url' => 'https://domain.com', 'request_url' => 'https://domain.com', 'redirect_to_root' => true, 'response_status' => 200, ]], [[ 'app_url' => 'https://domain.net.io', 'request_url' => 'https://domain.net.io', 'redirect_to_root' => true, 'response_status' => 200, ]], [[ 'app_url' => 'https://domain.com', 'request_url' => 'https://www.domain.com', 'redirect_to_root' => true, 'response_status' => 301, 'redirected_to' => 'https://domain.com', ]], [[ 'app_url' => 'https://domain.net.io', 'request_url' => 'https://www.domain.net.io', 'redirect_to_root' => true, 'response_status' => 301, 'redirected_to' => 'https://domain.net.io', ]], [[ 'app_url' => 'https://domain.com', 'request_url' => 'https://sub.domain.com', 'redirect_to_root' => true, 'response_status' => 200, ]], [[ 'app_url' => 'https://domain.net.io', 'request_url' => 'https://sub.domain.net.io', 'redirect_to_root' => true, 'response_status' => 200, ]], // redirect_to_root => false [[ 'app_url' => 'https://domain.com', 'request_url' => 'https://www.domain.com', 'redirect_to_root' => false, 'response_status' => 200, ]], [[ 'app_url' => 'https://domain.net.io', 'request_url' => 'https://www.domain.net.io', 'redirect_to_root' => false, 'response_status' => 200, ]], [[ 'app_url' => 'https://domain.com', 'request_url' => 'https://domain.com', 'redirect_to_root' => false, 'response_status' => 301, 'redirected_to' => 'https://www.domain.com', ]], [[ 'app_url' => 'https://domain.net.io', 'request_url' => 'https://domain.net.io', 'redirect_to_root' => false, 'response_status' => 301, 'redirected_to' => 'https://www.domain.net.io', ]], [[ 'app_url' => 'https://domain.com', 'request_url' => 'https://sub.domain.com', 'redirect_to_root' => false, 'response_status' => 200, ]], [[ 'app_url' => 'https://domain.net.io', 'request_url' => 'https://sub.domain.net.io', 'redirect_to_root' => false, 'response_status' => 200, ]], ]; } } ================================================ FILE: tests/Feature/LambdaProxyOctaneHandlerTest.php ================================================ markTestSkipped('Requires Laravel Octane.'); } parent::setUp(); $_ENV['APP_VANITY_URL'] = 'https://127.0.0.1'; $_ENV['LAMBDA_TASK_ROOT'] = __DIR__.'/../Fixtures'; Octane::boot(app()->basePath()); Octane::worker()->application()->register(OctaneServiceProvider::class); } protected function tearDown(): void { Mockery::close(); unset($_ENV['APP_VANITY_URL']); unset($_ENV['LAMBDA_TASK_ROOT']); unset($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']); Octane::terminate(); parent::tearDown(); } public function test_response_body() { $handler = new OctaneHandler(); Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', ], ], ]); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_invalid_uri() { $handler = new OctaneHandler(); Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/////foo', ], ], ]); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_response_file() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return response()->file(__DIR__.'/../Fixtures/asset.js', [ 'Content-Type' => 'text/javascript; charset=UTF-8', ]); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], ]); static::assertEquals('text/javascript; charset=UTF-8', $response->toApiGatewayFormat()['headers']['Content-Type']); static::assertEquals("console.log();\n", $response->toApiGatewayFormat()['body']); } public function test_response_download() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return response()->download(__DIR__.'/../Fixtures/asset.js'); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', ], ], ]); static::assertEquals('attachment; filename=asset.js', $response->toApiGatewayFormat()['headers']['Content-Disposition']); static::assertEquals("console.log();\n", $response->toApiGatewayFormat()['body']); } public function test_response_fires_events() { Event::fake([RequestReceived::class, RequestTerminated::class]); $handler = new OctaneHandler(); Route::get('/', function () { return response('Hello World')->withHeaders([ 'Foo' => 'Bar', ]); }); $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', ], ], ]); Event::assertDispatched(RequestReceived::class); Event::assertDispatched(RequestTerminated::class); } public function test_response_headers() { $handler = new OctaneHandler(); Route::get('/', function () { return response('Hello World')->withHeaders([ 'Foo' => 'Bar', ]); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', ], ], ]); static::assertArrayHasKey('Foo', $response->toApiGatewayFormat()['headers']); static::assertEquals('Bar', $response->toApiGatewayFormat()['headers']['Foo']); } public function test_response_status() { $handler = new OctaneHandler(); Route::get('/', function () { throw new RuntimeException('Something wrong happened.'); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', ], ], ]); static::assertEquals(500, $response->toApiGatewayFormat()['statusCode']); } public function test_each_request_have_its_own_app() { $handler = new OctaneHandler(); Route::get('/bind', function () { app()->bind('counter', function () { return 1; }); return app('counter'); }); Route::get('/bound', function () { return app()->bound('counter') ? 'bound' : 'not bound'; }); $bindResponse = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/bind', ], ], ]); $boundResponse = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/bound', ], ], ]); static::assertEquals('1', $bindResponse->toApiGatewayFormat()['body']); static::assertEquals('not bound', $boundResponse->toApiGatewayFormat()['body']); } public function test_response_cookies() { $handler = new OctaneHandler(); Route::get('/', function () { return response('Hello World')->cookie('cookie-key', 'cookie-value', 10); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], ]); $setCookie = $response->toApiGatewayFormat()['headers']['set-cookie']; static::assertStringStartsWith('cookie-key=cookie-value;', $setCookie); } public function test_robots_header_is_set() { $handler = new OctaneHandler(); $_ENV['APP_VANITY_URL'] = 'https://127.0.0.1'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], ]); $robotsTag = $response->toApiGatewayFormat()['headers']['X-Robots-Tag']; static::assertEquals('noindex, nofollow', $robotsTag); } public function test_maintenance_mode() { $handler = new OctaneHandler(); $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'headers' => [ 'Accept' => 'application/json', ], ]); static::assertEquals('application/json', $response->toApiGatewayFormat()['headers']['Content-Type']); static::assertEquals(['message' => 'We are currently down for maintenance.'], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_body() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return $request->all(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'POST', 'path' => '/', ], ], 'headers' => [ 'Content-Type' => 'application/json', ], 'body' => <<<'EOF' {"_method":"PUT","name":"nuno","email":"nuno@laravel.com"} EOF ]); static::assertEquals([ '_method' => 'PUT', 'name' => 'nuno', 'email' => 'nuno@laravel.com', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_form_url_encoded_without_inline_input_method() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return $request->all(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'PUT', 'path' => '/', ], ], 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8', ], 'body' => <<<'EOF' name=nuno&email=nuno@laravel.com EOF ]); static::assertEquals([ 'name' => 'nuno', 'email' => 'nuno@laravel.com', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_cookies() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->cookies->all(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'cookies' => [ 'XSRF-TOKEN=token_value', ], ]); static::assertEquals( ['XSRF-TOKEN' => 'token_value'], json_decode($response->toApiGatewayFormat()['body'], true) ); } public function test_request_ignores_invalid_cookies() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->cookies->all(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'cookies' => [ 'cookieKey1', 'cookieKey2=cookieValue2', ], ]); static::assertEquals( ['cookieKey2' => 'cookieValue2'], json_decode($response->toApiGatewayFormat()['body'], true) ); } public function test_request_file_uploads() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return array_merge($request->all(), [ 'filename' => $request->file('file')->getClientOriginalName(), 'file' => $request->file('file')->getContent(), ]); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'POST', 'path' => '/', ], ], 'headers' => [ 'Content-Type' => 'multipart/form-data; boundary=---------------------------317050813134112680482597024243', ], 'body' => <<<'EOF' -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="_method" PUT -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="name" nuno -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="email" nuno@laravel.com -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="file"; filename="my_uploaded.txt" Content-Type: text/plain foo -----------------------------317050813134112680482597024243-- EOF ]); static::assertEquals([ '_method' => 'PUT', 'name' => 'nuno', 'email' => 'nuno@laravel.com', 'filename' => 'my_uploaded.txt', 'file' => 'foo', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_file_uploads_without_inline_input_method() { $handler = new OctaneHandler(); Route::put('/', function (Request $request) { return array_merge($request->all(), [ 'filename' => $request->file('file')->getClientOriginalName(), 'file' => $request->file('file')->getContent(), ]); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'PUT', 'path' => '/', ], ], 'headers' => [ 'Content-Type' => 'multipart/form-data; boundary=---------------------------317050813134112680482597024243', ], 'body' => <<<'EOF' -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="name" nuno -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="email" nuno@laravel.com -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="file"; filename="my_uploaded.txt" Content-Type: text/plain foo -----------------------------317050813134112680482597024243-- EOF ]); static::assertEquals([ 'name' => 'nuno', 'email' => 'nuno@laravel.com', 'filename' => 'my_uploaded.txt', 'file' => 'foo', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_query_string() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->getQueryString(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'queryStringParameters' => [ 'param1' => 'value1', 'param2' => 'value1,value2', ], 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals('param1=value1¶m2[0]=value1¶m2[1]=value2', urldecode($response->toApiGatewayFormat()['body'])); } public function test_request_query_params() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->query(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'queryStringParameters' => [ 'param1' => 'value1', 'param2' => 'value1,value2', ], 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals([ 'param1' => 'value1', 'param2' => ['value1', 'value2'], ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_headers() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->headers->all(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'path' => '/', 'headers' => [ 'X-Xsrf-Token' => 'my-token', ], ]); $body = $response->toApiGatewayFormat()['body']; static::assertEquals(['my-token'], json_decode($body, true)['x-xsrf-token']); } public function test_request_multi_headers() { $handler = new OctaneHandler(); Route::get('/', function (Request $request) { return $request->headers->all(); }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'headers' => [ 'X-Xsrf-Token' => 'my-token', 'X-Multi-Header' => 'value1,value2', ], ]); $body = $response->toApiGatewayFormat()['body']; static::assertEquals(['my-token'], json_decode($body, true)['x-xsrf-token']); static::assertEquals(['value1,value2'], json_decode($body, true)['x-multi-header']); } public function test_maintenance_mode_with_valid_bypass_cookie() { $octane = new class() extends Octane { public static function hasValidBypassCookie($request, $secret) { return true; } }; $handler = new class() extends OctaneHandler { public function request($event) { return parent::request($event); } public function response($response) { return parent::response($response); } }; $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] = 'my-secret'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->response($octane::handle($handler->request([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], ]))); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_maintenance_mode_with_invalid_bypass_cookie() { $handler = new OctaneHandler(); $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] = 'my-secret'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'path' => '/', ], ], 'headers' => [ 'Accept' => 'application/json', ], ]); static::assertEquals('application/json', $response->toApiGatewayFormat()['headers']['Content-Type']); static::assertEquals(['message' => 'We are currently down for maintenance.'], json_decode($response->toApiGatewayFormat()['body'], true)); } } ================================================ FILE: tests/Feature/LoadBalancedOctaneHandlerTest.php ================================================ markTestSkipped('Requires Laravel Octane.'); } parent::setUp(); $_ENV['APP_VANITY_URL'] = 'https://127.0.0.1'; $_ENV['LAMBDA_TASK_ROOT'] = __DIR__.'/../Fixtures'; Octane::boot(app()->basePath()); Octane::worker()->application()->register(OctaneServiceProvider::class); } protected function tearDown(): void { Mockery::close(); unset($_ENV['APP_VANITY_URL']); unset($_ENV['LAMBDA_TASK_ROOT']); unset($_ENV['VAPOR_MAINTENANCE_MODE_SECRET']); Octane::terminate(); parent::tearDown(); } public function test_response_body() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', ]); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_invalid_uri() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/////foo', ]); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_response_fires_events() { Event::fake([RequestReceived::class, RequestTerminated::class]); $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { return response('Hello World')->withHeaders([ 'Foo' => 'Bar', ]); }); $handler->handle([ 'httpMethod' => 'GET', ]); Event::assertDispatched(RequestReceived::class); Event::assertDispatched(RequestTerminated::class); } public function test_response_file() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return response()->file(__DIR__.'/../Fixtures/asset.js', [ 'Content-Type' => 'text/javascript; charset=UTF-8', ]); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); static::assertEquals(['text/javascript; charset=UTF-8'], $response->toApiGatewayFormat()['multiValueHeaders']['Content-Type']); static::assertEquals("console.log();\n", $response->toApiGatewayFormat()['body']); } public function test_response_download() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return response()->download(__DIR__.'/../Fixtures/asset.js'); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); static::assertEquals(['attachment; filename=asset.js'], $response->toApiGatewayFormat()['multiValueHeaders']['Content-Disposition']); static::assertEquals("console.log();\n", $response->toApiGatewayFormat()['body']); } public function test_response_headers() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { return response('Hello World')->withHeaders([ 'Foo' => 'Bar', ]); }); $response = $handler->handle([ 'httpMethod' => 'GET', ]); static::assertArrayHasKey('Foo', $response->toApiGatewayFormat()['multiValueHeaders']); static::assertEquals(['Bar'], $response->toApiGatewayFormat()['multiValueHeaders']['Foo']); } public function test_response_status() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { throw new RuntimeException('Something wrong happened.'); }); $response = $handler->handle([ 'httpMethod' => 'GET', ]); static::assertEquals(500, $response->toApiGatewayFormat()['statusCode']); } public function test_each_response_have_its_own_app() { $handler = new LoadBalancedOctaneHandler(); Route::get('/bind', function () { app()->bind('counter', function () { return 1; }); return app('counter'); }); Route::get('/bound', function () { return app()->bound('counter') ? 'bound' : 'not bound'; }); $bindResponse = $handler->handle([ 'httpMethod' => 'GET', 'path' => 'bind', ]); $boundResponse = $handler->handle([ 'httpMethod' => 'GET', 'path' => 'bound', ]); static::assertEquals('1', $bindResponse->toApiGatewayFormat()['body']); static::assertEquals('not bound', $boundResponse->toApiGatewayFormat()['body']); } public function test_response_cookies() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { return response('Hello World')->cookie('cookie-key', 'cookie-value', 10); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); $setCookie = $response->toApiGatewayFormat()['multiValueHeaders']['Set-Cookie']; static::assertStringStartsWith('cookie-key=cookie-value;', $setCookie[0]); } public function test_robots_header_is_set() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', ]); $robotsTag = $response->toApiGatewayFormat()['multiValueHeaders']['X-Robots-Tag']; static::assertEquals(['noindex, nofollow'], $robotsTag); } public function test_maintenance_mode() { $handler = new LoadBalancedOctaneHandler(); $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'Accept' => 'application/json', ], ]); static::assertEquals(['application/json'], $response->toApiGatewayFormat()['multiValueHeaders']['Content-Type']); static::assertEquals(['message' => 'We are currently down for maintenance.'], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_body() { $handler = new LoadBalancedOctaneHandler(); Route::put('/', function (Request $request) { return $request->all(); }); $response = $handler->handle([ 'httpMethod' => 'POST', 'path' => '/', 'headers' => [ 'Content-Type' => 'application/json', ], 'body' => <<<'EOF' {"_method":"PUT","name":"nuno","email":"nuno@laravel.com"} EOF ]); static::assertEquals([ '_method' => 'PUT', 'name' => 'nuno', 'email' => 'nuno@laravel.com', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_form_url_encoded_without_inline_input_method() { $handler = new LoadBalancedOctaneHandler(); Route::put('/', function (Request $request) { return $request->all(); }); $response = $handler->handle([ 'httpMethod' => 'PUT', 'path' => '/', 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8', ], 'body' => <<<'EOF' name=nuno&email=nuno@laravel.com EOF ]); static::assertEquals([ 'name' => 'nuno', 'email' => 'nuno@laravel.com', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_file_uploads() { $handler = new LoadBalancedOctaneHandler(); Route::put('/', function (Request $request) { return array_merge($request->all(), [ 'filename' => $request->file('file')->getClientOriginalName(), 'file' => $request->file('file')->getContent(), ]); }); $response = $handler->handle([ 'httpMethod' => 'POST', 'path' => '/', 'headers' => [ 'Content-Type' => 'multipart/form-data; boundary=---------------------------317050813134112680482597024243', ], 'body' => <<<'EOF' -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="_method" PUT -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="name" nuno -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="email" nuno@laravel.com -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="file"; filename="my_uploaded.txt" Content-Type: text/plain foo -----------------------------317050813134112680482597024243-- EOF ]); static::assertEquals([ '_method' => 'PUT', 'name' => 'nuno', 'email' => 'nuno@laravel.com', 'filename' => 'my_uploaded.txt', 'file' => 'foo', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_file_uploads_without_inline_input_method() { $handler = new LoadBalancedOctaneHandler(); Route::put('/', function (Request $request) { return array_merge($request->all(), [ 'filename' => $request->file('file')->getClientOriginalName(), 'file' => $request->file('file')->getContent(), ]); }); $response = $handler->handle([ 'httpMethod' => 'PUT', 'path' => '/', 'headers' => [ 'Content-Type' => 'multipart/form-data; boundary=---------------------------317050813134112680482597024243', ], 'body' => <<<'EOF' -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="name" nuno -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="email" nuno@laravel.com -----------------------------317050813134112680482597024243 Content-Disposition: form-data; name="file"; filename="my_uploaded.txt" Content-Type: text/plain foo -----------------------------317050813134112680482597024243-- EOF ]); static::assertEquals([ 'name' => 'nuno', 'email' => 'nuno@laravel.com', 'filename' => 'my_uploaded.txt', 'file' => 'foo', ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_cookies() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return $request->cookies->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals( ['XSRF-TOKEN' => 'token_value'], json_decode($response->toApiGatewayFormat()['body'], true) ); } public function test_request_ignores_invalid_cookies() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return $request->cookies->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'cookie' => 'cookieKey1; cookieKey2=cookieValue2', ], ]); static::assertEquals( ['cookieKey2' => 'cookieValue2'], json_decode($response->toApiGatewayFormat()['body'], true) ); } public function test_request_query_string() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return $request->getQueryString(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'multiValueQueryStringParameters' => [ 'param1' => ['value1'], 'param2' => ['value1', 'value2'], ], 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals('param1=value1¶m2[0]=value1¶m2[1]=value2', urldecode($response->toApiGatewayFormat()['body'])); } public function test_request_query_params() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return $request->query(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'multiValueQueryStringParameters' => [ 'param1' => ['value1'], 'param2' => ['value1', 'value2'], ], 'headers' => [ 'cookie' => 'XSRF-TOKEN=token_value', ], ]); static::assertEquals([ 'param1' => 'value1', 'param2' => ['value1', 'value2'], ], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_request_headers() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return $request->headers->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'X-Xsrf-Token' => 'my-token', ], ]); $body = $response->toApiGatewayFormat()['body']; static::assertEquals(['my-token'], json_decode($body, true)['x-xsrf-token']); } public function test_request_multi_headers() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function (Request $request) { return $request->headers->all(); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'multiValueHeaders' => [ 'X-Xsrf-Token' => ['my-token'], 'X-Multi-Header' => ['value1', 'value2'], ], ]); $body = $response->toApiGatewayFormat()['body']; static::assertEquals(['my-token'], json_decode($body, true)['x-xsrf-token']); static::assertEquals(['value2'], json_decode($body, true)['x-multi-header']); } public function test_maintenance_mode_with_valid_bypass_cookie() { $octane = new class() extends Octane { public static function hasValidBypassCookie($request, $secret) { return true; } }; $handler = new class() extends LoadBalancedOctaneHandler { public function request($event) { return parent::request($event); } public function response($response) { return parent::response($response); } }; $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] = 'my-secret'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->response($octane::handle($handler->request([ 'httpMethod' => 'GET', 'path' => '/', ]))); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } public function test_maintenance_mode_with_invalid_bypass_cookie() { $handler = new LoadBalancedOctaneHandler(); $_ENV['VAPOR_MAINTENANCE_MODE'] = 'true'; $_ENV['APP_VANITY_URL'] = 'production.com'; $_ENV['VAPOR_MAINTENANCE_MODE_SECRET'] = 'my-secret'; Route::get('/', function () { return 'Hello World'; }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'Accept' => 'application/json', ], ]); static::assertEquals(['application/json'], $response->toApiGatewayFormat()['multiValueHeaders']['Content-Type']); static::assertEquals(['message' => 'We are currently down for maintenance.'], json_decode($response->toApiGatewayFormat()['body'], true)); } public function test_streamed_responses() { $handler = new LoadBalancedOctaneHandler(); Route::get('/', function () { return new StreamedResponse(function () { echo 'Hello World'; }, 200, ['mime-type' => 'image/png']); }); $response = $handler->handle([ 'httpMethod' => 'GET', 'path' => '/', 'headers' => [ 'Accept' => 'application/json', ], ]); static::assertEquals(['image/png'], $response->toApiGatewayFormat()['multiValueHeaders']['Mime-Type']); static::assertEquals('Hello World', $response->toApiGatewayFormat()['body']); } } ================================================ FILE: tests/Feature/OctaneManageDatabaseSessionsTest.php ================================================ shouldReceive('exec') ->andThrow(new PDOException( 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' )); try { collect([$stalePdo]) ->filter(fn ($pdo) => $pdo instanceof PDO) ->each(function ($pdo) { try { $pdo->exec(sprintf('SET SESSION wait_timeout=%s', 10)); } catch (\Throwable $e) { // Connection already gone away, safe to ignore... } }); } catch (\Throwable $e) { $this->fail('Expected no exception, but caught: '.$e->getMessage()); } $this->assertTrue(true); } public function test_it_proves_bug_exists_without_fix() { $stalePdo = Mockery::mock(PDO::class); $stalePdo->shouldReceive('exec') ->andThrow(new PDOException( 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' )); $this->expectException(PDOException::class); // This is the ORIGINAL broken code - proves the bug collect([$stalePdo]) ->filter(fn ($pdo) => $pdo instanceof PDO) ->each->exec(sprintf('SET SESSION wait_timeout=%s', 10)); } public function test_it_still_sets_wait_timeout_on_live_connections() { $livePdo = Mockery::mock(PDO::class); $livePdo->shouldReceive('exec') ->once() ->with('SET SESSION wait_timeout=10') ->andReturn(true); collect([$livePdo]) ->filter(fn ($pdo) => $pdo instanceof PDO) ->each(function ($pdo) { try { $pdo->exec(sprintf('SET SESSION wait_timeout=%s', 10)); } catch (\Throwable $e) { // } }); $this->addToAssertionCount( Mockery::getContainer()->mockery_getExpectationCount() ); } public function test_it_handles_mixed_live_and_stale_connections() { // Simulates Aurora writer alive + reader dead $livePdo = Mockery::mock(PDO::class); $livePdo->shouldReceive('exec')->once()->andReturn(true); $stalePdo = Mockery::mock(PDO::class); $stalePdo->shouldReceive('exec') ->andThrow(new PDOException( 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' )); try { collect([$livePdo, $stalePdo]) ->filter(fn ($pdo) => $pdo instanceof PDO) ->each(function ($pdo) { try { $pdo->exec(sprintf('SET SESSION wait_timeout=%s', 10)); } catch (\Throwable $e) { // } }); } catch (\Throwable $e) { $this->fail('Expected no exception, but caught: '.$e->getMessage()); } $this->assertTrue(true); } } ================================================ FILE: tests/Feature/OctaneTest.php ================================================ markTestSkipped('Requires Laravel Octane.'); } parent::setUp(); Octane::boot(app()->basePath()); Octane::worker()->application()->register(OctaneServiceProvider::class); } protected function tearDown(): void { Mockery::close(); Octane::terminate(); parent::tearDown(); } public function test_on_error() { Event::fake([WorkerErrorOccurred::class]); $worker = Octane::worker(); $reflection = new \ReflectionClass($worker); $method = tap($reflection->getMethod('handleWorkerError'))->setAccessible(true); $exception = new Exception('Something wrong happened'); $exceptionHandler = Mockery::mock(ExceptionHandler::class); $exceptionHandler->shouldReceive('report')->with($exception); $app = Mockery::mock($worker->application()); $app->shouldReceive('make')->with(ExceptionHandler::class)->andReturn($exceptionHandler); $method->invoke( $worker, $exception, $app, new Request(), new RequestContext(), false ); Event::assertDispatched(WorkerErrorOccurred::class); } public function test_server_software() { self::assertSame('vapor', $_ENV['SERVER_SOFTWARE']); self::assertSame('vapor', $_SERVER['SERVER_SOFTWARE']); } } ================================================ FILE: tests/Feature/RedirectStaticAssetsTest.php ================================================ middleware(RedirectStaticAssets::class); } protected function getPackageProviders($app): array { return [ VaporServiceProvider::class, ]; } public function test_redirects_to_favicon_ico() { $response = $this->get('/favicon.ico'); $response->assertStatus(302)->assertRedirect('https://asset-url.com/favicon.ico'); config()->set('vapor.redirect_favicon', false); $response = $this->get('/favicon.ico'); $response->assertStatus(200)->assertSee('My own favicon.'); } } ================================================ FILE: tests/Feature/SignedStorageUrlEndpointTest.php ================================================ $_ENV['AWS_BUCKET'] = 'storage', 'filesystems.disks.s3.key' => $_ENV['AWS_ACCESS_KEY_ID'] = 'sail', 'filesystems.disks.s3.region' => $_ENV['AWS_DEFAULT_REGION'] = 'us-east-1', 'filesystems.disks.s3.secret' => $_ENV['AWS_SECRET_ACCESS_KEY'] = 'password', 'filesystems.disks.s3.url' => $_ENV['AWS_URL'] = 'http://minio:9000', 'filesystems.disks.s3.use_path_style_endpoint' => true, ]); Gate::define('uploadFiles', static function ($user = null, $bucket = null): bool { return true; }); $response = $this->json('POST', '/vapor/signed-storage-url') ->assertStatus(201); $components = (object) [ 'actual' => parse_url($response->json('url')), 'expected' => parse_url($_ENV['AWS_URL'].'/'.$_ENV['AWS_BUCKET']), ]; $this->assertEquals($components->expected['scheme'], $components->actual['scheme']); $this->assertEquals($components->expected['host'], $components->actual['host']); $this->assertEquals($components->expected['port'], $components->actual['port']); $this->assertStringStartsWith($components->expected['path'], $components->actual['path']); } public function test_signed_url_expires_after(): void { Config::set([ 'filesystems.disks.s3.bucket' => $_ENV['AWS_BUCKET'] = 'storage', 'filesystems.disks.s3.key' => $_ENV['AWS_ACCESS_KEY_ID'] = 'sail', 'filesystems.disks.s3.region' => $_ENV['AWS_DEFAULT_REGION'] = 'us-east-1', 'filesystems.disks.s3.secret' => $_ENV['AWS_SECRET_ACCESS_KEY'] = 'password', 'filesystems.disks.s3.url' => $_ENV['AWS_URL'] = 'http://minio:9000', 'filesystems.disks.s3.use_path_style_endpoint' => true, ]); Gate::define('uploadFiles', static function ($user = null, $bucket = null): bool { return true; }); $response = $this->json('POST', '/vapor/signed-storage-url'); parse_str($response->json()['url'], $queryParams); $this->assertEquals(300, $queryParams['X-Amz-Expires']); config()->set('vapor.signed_storage_url_expires_after', 6); $response = $this->json('POST', '/vapor/signed-storage-url'); parse_str($response->json()['url'], $queryParams); $this->assertEquals(360, $queryParams['X-Amz-Expires']); } } ================================================ FILE: tests/Feature/VaporJobTest.php ================================================ app->singleton('cache.store', ArrayStore::class); } protected function getPackageProviders($app): array { return [ VaporServiceProvider::class, ]; } public function test_job_release_attempts_without_cache() { unset($_ENV['VAPOR_CACHE_JOB_ATTEMPTS']); $sqs = Mockery::mock(SqsClient::class); $sqs->shouldReceive('deleteMessage')->once()->with([ 'QueueUrl' => 'test-vapor-queue-url', 'ReceiptHandle' => 'test-receipt-handle', ]); $sqs->shouldReceive('sendMessage')->once()->with([ 'QueueUrl' => 'test-vapor-queue-url', 'MessageBody' => json_encode(['attempts' => 2]), 'DelaySeconds' => 0, ])->andReturn(new Result([ 'MessageId' => 'my-released-job-id', ])); $job = new VaporJob($this->app, $sqs, [ 'ReceiptHandle' => 'test-receipt-handle', 'Body' => json_encode(['attempts' => 1]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); $job->release(); $this->assertSame(0, resolve(JobAttempts::class)->get('my-job-id')); $this->assertSame(0, resolve(JobAttempts::class)->get('my-released-job-id')); } public function test_job_release_attempts_with_cache() { $_ENV['VAPOR_CACHE_JOB_ATTEMPTS'] = 'true'; $sqs = Mockery::mock(SqsClient::class); $sqs->shouldReceive('deleteMessage')->once()->with([ 'QueueUrl' => 'test-vapor-queue-url', 'ReceiptHandle' => 'test-receipt-handle', ]); $sqs->shouldReceive('sendMessage')->once()->with([ 'QueueUrl' => 'test-vapor-queue-url', 'MessageBody' => json_encode(['attempts' => 2]), 'DelaySeconds' => 0, ])->andReturn(new Result([ 'MessageId' => 'my-released-job-id', ])); $job = new VaporJob($this->app, $sqs, [ 'ReceiptHandle' => 'test-receipt-handle', 'Body' => json_encode(['attempts' => 1]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); // Equivalent to ['attempts' => 1] resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $job->release(); $this->assertSame(0, resolve(JobAttempts::class)->get('my-job-id')); $this->assertSame(2, resolve(JobAttempts::class)->get('my-released-job-id')); } public function test_job_attempts_without_cache() { unset($_ENV['VAPOR_CACHE_JOB_ATTEMPTS']); $sqs = Mockery::mock(SqsClient::class); $job = new VaporJob($this->app, $sqs, [ 'Body' => json_encode(['attempts' => 1]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $this->assertSame(2, $job->attempts()); $this->assertSame(0, resolve(JobAttempts::class)->get($job)); } public function test_job_attempts_with_cache() { $_ENV['VAPOR_CACHE_JOB_ATTEMPTS'] = 'true'; $sqs = Mockery::mock(SqsClient::class); $job = new VaporJob($this->app, $sqs, [ 'Body' => json_encode(['attempts' => 1]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $this->assertSame(4, $job->attempts()); $this->assertSame(4, resolve(JobAttempts::class)->get($job)); } public function test_job_attempts_priority() { $_ENV['VAPOR_CACHE_JOB_ATTEMPTS'] = 'true'; $sqs = Mockery::mock(SqsClient::class); $job = new VaporJob($this->app, $sqs, [ 'Body' => json_encode(['attempts' => 2]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $this->assertSame(3, $job->attempts()); $job = new VaporJob($this->app, $sqs, [ 'Body' => json_encode(['attempts' => 0]), 'MessageId' => 'my-other-job-id', ], 'sqs', 'test-vapor-queue-url'); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $this->assertSame(2, $job->attempts()); } public function test_job_attempts_when_its_missing_from_payload() { unset($_ENV['VAPOR_CACHE_JOB_ATTEMPTS']); $sqs = Mockery::mock(SqsClient::class); $job = new VaporJob($this->app, $sqs, [ 'Body' => json_encode([]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); $this->assertSame(1, $job->attempts()); } public function test_job_attempts_on_delete() { $_ENV['VAPOR_CACHE_JOB_ATTEMPTS'] = 'true'; $sqs = Mockery::mock(SqsClient::class); $sqs->shouldReceive('deleteMessage')->once()->with([ 'QueueUrl' => 'test-vapor-queue-url', 'ReceiptHandle' => 'my-job-receipt', ]); $job = new VaporJob($this->app, $sqs, [ 'Body' => json_encode(['attempts' => 0]), 'MessageId' => 'my-job-id', 'ReceiptHandle' => 'my-job-receipt', ], 'sqs', 'test-vapor-queue-url'); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $this->assertSame(3, $job->attempts()); $job->delete(); $this->assertSame(0, resolve(JobAttempts::class)->get($job)); } public function test_job_fire_without_cache() { unset($_ENV['VAPOR_CACHE_JOB_ATTEMPTS']); $sqs = Mockery::mock(SqsClient::class); $sqs->shouldReceive('deleteMessage')->once()->with([ 'QueueUrl' => 'test-vapor-queue-url', 'ReceiptHandle' => 'my-job-receipt', ]); $job = new FakeJob; $job = new VaporJob($this->app, $sqs, [ 'ReceiptHandle' => 'my-job-receipt', 'Body' => json_encode([ 'displayName' => FakeJob::class, 'job' => 'Illuminate\Queue\CallQueuedHandler@call', 'maxTries' => null, 'timeout' => null, 'timeoutAt' => null, 'data' => [ 'commandName' => FakeJob::class, 'command' => serialize($job), ], 'attempts' => 3, ]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $job->fire(); $this->assertSame(0, resolve(JobAttempts::class)->get($job)); } public function test_job_fire_with_cache() { $_ENV['VAPOR_CACHE_JOB_ATTEMPTS'] = 'true'; $sqs = Mockery::mock(SqsClient::class); $sqs->shouldReceive('deleteMessage')->once()->with([ 'QueueUrl' => 'test-vapor-queue-url', 'ReceiptHandle' => 'my-job-receipt', ]); $job = new FakeJob; $job = new VaporJob($this->app, $sqs, [ 'ReceiptHandle' => 'my-job-receipt', 'Body' => json_encode([ 'displayName' => FakeJob::class, 'job' => 'Illuminate\Queue\CallQueuedHandler@call', 'maxTries' => null, 'timeout' => null, 'timeoutAt' => null, 'data' => [ 'commandName' => FakeJob::class, 'command' => serialize($job), ], 'attempts' => 3, ]), 'MessageId' => 'my-job-id', ], 'sqs', 'test-vapor-queue-url'); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); resolve(JobAttempts::class)->increment($job); $job->fire(); $this->assertSame(0, resolve(JobAttempts::class)->get($job)); } } ================================================ FILE: tests/Feature/VaporQueueTest.php ================================================ app->singleton('cache.store', ArrayStore::class); } protected function getPackageProviders($app): array { return [ VaporServiceProvider::class, ]; } public function test_proper_payload_array_is_created() { $sqs = Mockery::mock(SqsClient::class); $job = new FakeJob; $sqs->shouldReceive('sendMessage')->once()->with(Mockery::on(function ($argument) use ($job) { $messageBody = json_decode($argument['MessageBody'], true); $this->assertSame('/test-vapor-queue-url', $argument['QueueUrl']); $subset = [ 'displayName' => FakeJob::class, 'job' => 'Illuminate\Queue\CallQueuedHandler@call', 'maxTries' => null, 'timeout' => null, 'attempts' => 0, ]; foreach ($subset as $key => $value) { $this->assertArrayHasKey($key, $messageBody); $this->assertSame($value, $messageBody[$key]); } $this->assertArrayHasKey('data', $messageBody); $this->assertSame(FakeJob::class, $messageBody['data']['commandName']); $this->assertSame(serialize($job), $messageBody['data']['command']); return true; }))->andReturnSelf(); $sqs->shouldReceive('get')->andReturn('attribute-value'); $queue = new VaporQueue($sqs, 'test-vapor-queue-url'); $queue->setContainer($this->app); $this->assertSame('attribute-value', $queue->push($job)); } public function test_queue_pop() { $_ENV['VAPOR_CACHE_JOB_ATTEMPTS'] = 'true'; $sqs = Mockery::mock(SqsClient::class); $job = new FakeJob; $sqs->shouldReceive('receiveMessage')->once()->andReturn([ 'Messages' => [ ['MessageId' => 'my-job-id'], ], ]); $queue = new VaporQueue($sqs, 'test-vapor-queue-url'); $queue->setContainer($this->app); $job = $queue->pop(); $this->assertSame(1, resolve(JobAttempts::class)->get('my-job-id')); } } ================================================ FILE: tests/Fixtures/503.json ================================================ { "message": "We are currently down for maintenance." } ================================================ FILE: tests/Fixtures/asset.js ================================================ console.log(); ================================================ FILE: tests/Fixtures/customLambdaEventFromSQS.json ================================================ { "Records": [ { "messageId": "ddccab4e-f6fe-4a9a-aa18-b67ca8724d01", "receiptHandle": "AQEBq42fiVBuPsL7mSHaAX7JqRNPgx\/5a1o\/ku1DFfrowMGI32C+1IHyaF9uHXjjJiLWE7JL8aUu0tb5yZoXbY+gEP\/tyfONuOEqxqiU6UnWT8aBMtqRnuz+F4Y2BN\/0lYxEJg4Pz849zxHtjvtkDw7zoB6SMCxAgE26UbSvIxAzNBLlU6sEQX24eKVBngEktA+i3TY9sCSuFy3lQte7yO+9ccmwbndxJ\/HV9An9KOE3FtBVIoUCx6Oum4dm5MQoMcoqBUvYDbQLM8dLfAVFT72aOu3J+WbBbOfi7bMbvkPodvfQUcum9nWnpXbci0F91R4GDnyDJfzw5oCGKazeLbjUzr8zWSy8qX\/bu3b99dE3nORQyI87OK7x8b3t+iFWzWPmCZwXh\/MvWLn9CUntj0qMPw==", "body": "{\"test\": \"123\"}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1757361341318", "SenderId":"AROATHDQZYADPZZTHGFLF:vapor-laravel-staging", "ApproximateFirstReceiveTimestamp": "1757361341319" }, "messageAttributes": [], "md5OfBody": "9e536d7703a805854db06bdf6169656c", "eventSource": "aws:sqs", "eventSourceARN":"arn:aws:sqs:eu-west-3:221427384326:laravel-staging", "awsRegion": "us-east-1" } ] } ================================================ FILE: tests/Fixtures/customNonSQSLambdaEvent.json ================================================ { "Records": [ { "receiptHandle": "AQEBq42fiVBuPsL7mSHaAX7JqRNPgx\/5a1o\/ku1DFfrowMGI32C+1IHyaF9uHXjjJiLWE7JL8aUu0tb5yZoXbY+gEP\/tyfONuOEqxqiU6UnWT8aBMtqRnuz+F4Y2BN\/0lYxEJg4Pz849zxHtjvtkDw7zoB6SMCxAgE26UbSvIxAzNBLlU6sEQX24eKVBngEktA+i3TY9sCSuFy3lQte7yO+9ccmwbndxJ\/HV9An9KOE3FtBVIoUCx6Oum4dm5MQoMcoqBUvYDbQLM8dLfAVFT72aOu3J+WbBbOfi7bMbvkPodvfQUcum9nWnpXbci0F91R4GDnyDJfzw5oCGKazeLbjUzr8zWSy8qX\/bu3b99dE3nORQyI87OK7x8b3t+iFWzWPmCZwXh\/MvWLn9CUntj0qMPw==", "body": "{\"test\": \"123\"}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1757361341318", "SenderId":"AROATHDQZYADPZZTHGFLF:vapor-laravel-staging", "ApproximateFirstReceiveTimestamp": "1757361341319" }, "messageAttributes": [], "md5OfBody": "9e536d7703a805854db06bdf6169656c", "eventSource": "aws:s3", "eventSourceARN":"arn:aws:s3:eu-west-3:221427384326:laravel-staging", "awsRegion": "us-east-1" } ] } ================================================ FILE: tests/Fixtures/jobLambdaEventFromSQS.json ================================================ { "Records":[ { "messageId":"58600123-d011-4d76-af5d-960159ca44aa", "receiptHandle":"AQEBberAbZm/iuRDZevRaZ1cd1arwj3mHxvAZo/972KO8UH+HiNMTOMl66TPi/pZUbNYu+owiBzhyVGafAJuGDz9+LoyzEt6JqxMrzOKV7C3IO6wRZsUKRBKrlfr42KKP/+KS8zQUJE3QIgWiAwEfEwTnbSLhsxfqGxTFWzLh5+Or7u8U10p3K8tdDozssv2Hr39RhkiOKbuE2CS1U6f1oUvHowIr6o5vqNy9xxEiYr/XDXqbsReBE5zw531guvXxJagJjjKhxaNJoIozuYotF/+TeAz8/0Y0kuQTHZY0/tgS79MWGIPEL6izkF5uDm2lKo5PP4SKqfNMvNHS/i5u35mqzOQfHhJytLMWoRmCwUShI4KSaVNkkX+4ZyBpflOpLQl6u/DJ5TbfgkzWOJqhV+DQQ==", "body":"{\"uuid\":\"0a0bcc75-f78b-4f15-b834-78e71c56afa3\",\"displayName\":\"Closure (web.php:19)\",\"job\":\"Illuminate\\\\Queue\\\\CallQueuedHandler@call\",\"maxTries\":null,\"maxExceptions\":null,\"failOnTimeout\":false,\"backoff\":null,\"timeout\":null,\"retryUntil\":null,\"data\":{\"commandName\":\"Illuminate\\\\Queue\\\\CallQueuedClosure\",\"command\":\"O:34:\\\"Illuminate\\\\Queue\\\\CallQueuedClosure\\\":14:{s:7:\\\"closure\\\";O:47:\\\"Laravel\\\\SerializableClosure\\\\SerializableClosure\\\":1:{s:12:\\\"serializable\\\";O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Signed\\\":2:{s:12:\\\"serializable\\\";s:432:\\\"O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Native\\\":5:{s:3:\\\"use\\\";a:1:{s:10:\\\"collection\\\";O:29:\\\"Illuminate\\\\Support\\\\Collection\\\":2:{s:8:\\\"\\u0000*\\u0000items\\\";a:1:{i:0;s:4:\\\"nuno\\\";}s:28:\\\"\\u0000*\\u0000escapeWhenCastingToString\\\";b:0;}}s:8:\\\"function\\\";s:79:\\\"function () use ($collection) {\\n \\\\info($collection->implode(','));\\n }\\\";s:5:\\\"scope\\\";s:37:\\\"Illuminate\\\\Routing\\\\RouteFileRegistrar\\\";s:4:\\\"this\\\";N;s:4:\\\"self\\\";s:32:\\\"00000000000001a10000000000000000\\\";}\\\";s:4:\\\"hash\\\";s:44:\\\"bl2j1wIRyXIqlgbMDpY7+kCIUvwcJwhHde9gTY7Ma4E=\\\";}}s:16:\\\"failureCallbacks\\\";a:0:{}s:23:\\\"deleteWhenMissingModels\\\";b:1;s:7:\\\"batchId\\\";N;s:3:\\\"job\\\";N;s:10:\\\"connection\\\";N;s:5:\\\"queue\\\";N;s:15:\\\"chainConnection\\\";N;s:10:\\\"chainQueue\\\";N;s:19:\\\"chainCatchCallbacks\\\";N;s:5:\\\"delay\\\";N;s:11:\\\"afterCommit\\\";N;s:10:\\\"middleware\\\";a:0:{}s:7:\\\"chained\\\";a:0:{}}\"},\"attempts\":0}", "attributes":{ "ApproximateReceiveCount":"1", "SentTimestamp":"1639158884706", "SenderId":"AROATHDQZYADPZZTHGFLF:vapor-laravel-staging", "ApproximateFirstReceiveTimestamp":"1639158884710" }, "messageAttributes":[ ], "md5OfBody":"28381da423cdb6fb5ba21f2eccb4fea1", "eventSource":"aws:sqs", "eventSourceARN":"arn:aws:sqs:eu-west-3:221427384326:laravel-staging", "awsRegion":"eu-west-3" } ] } ================================================ FILE: tests/TestCase.php ================================================ 'GET', 'multiValueQueryStringParameters' => [ 'Host' => [$host = '2000-01-01%2000%3A00%3A00'], ], 'requestContext' => [ 'elb' => true, ], ]); $this->assertSame(http_build_query(['Host' => urldecode($host)]), $request->serverVariables['QUERY_STRING']); } public function test_api_gateway_headers_are_handled() { $trace = ['Root=1-7696740c-c075312a25f21abe1ca19805;foobar']; $for = ['172.105.167.153', '70.132.20.166']; $port = ['443']; $proto = ['https']; $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', 'multiValueHeaders' => [ 'X-Amzn-Trace-Id' => $trace, 'X-Forwarded-For' => $for, 'X-Forwarded-Port' => $port, 'X-Forwarded-Proto' => $proto, ], 'queryStringParameters' => null, 'multiValueQueryStringParameters' => null, ]); $this->assertSame('Root=1-7696740c-c075312a25f21abe1ca19805;foobar', $request->serverVariables['HTTP_X_AMZN_TRACE_ID']); $this->assertSame('70.132.20.166', $request->serverVariables['HTTP_X_FORWARDED_FOR']); $this->assertSame('443', $request->serverVariables['HTTP_X_FORWARDED_PORT']); $this->assertSame('https', $request->serverVariables['HTTP_X_FORWARDED_PROTO']); } public function test_api_gateway_v2_headers_are_handled() { $trace = 'Root=1-7696740c-c075312a25f21abe1ca19805;foobar'; $for = '172.105.167.153,70.132.20.166'; $port = '443'; $proto = 'https'; $request = FpmRequest::fromLambdaEvent([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'protocol' => 'HTTP/1.1', ], ], 'headers' => [ 'x-amzn-trace-id' => $trace, 'x-forwarded-for' => $for, 'x-forwarded-port' => $port, 'x-forwarded-proto' => $proto, ], 'queryStringParameters' => null, ]); $this->assertSame('Root=1-7696740c-c075312a25f21abe1ca19805;foobar', $request->serverVariables['HTTP_X_AMZN_TRACE_ID']); $this->assertSame('172.105.167.153,70.132.20.166', $request->serverVariables['HTTP_X_FORWARDED_FOR']); $this->assertSame('443', $request->serverVariables['HTTP_X_FORWARDED_PORT']); $this->assertSame('https', $request->serverVariables['HTTP_X_FORWARDED_PROTO']); } public function test_api_gateway_v2_query_parameters_are_handled() { $request = FpmRequest::fromLambdaEvent([ 'version' => '2.0', 'requestContext' => [ 'http' => [ 'method' => 'GET', 'protocol' => 'HTTP/1.1', ], ], 'queryStringParameters' => [ 'key1' => 'value1', 'key2' => 'value2,value3', ], ]); $this->assertSame( http_build_query([ 'key1' => 'value1', 'key2' => ['value2', 'value3'], ]), $request->serverVariables['QUERY_STRING'] ); } public function test_load_balancer_headers_are_over_spoofed_headers() { $request = FpmRequest::fromLambdaEvent([ 'requestContext' => [ 'elb' => [ 'targetGroupArn' => 'arn:aws:elasticloadbalancing:us-west-2:308264878215:targetgroup/vapor-staging/2aa8690968087e6e', ], ], 'httpMethod' => 'GET', 'multiValueQueryStringParameters' => [], 'multiValueHeaders' => [ 'x-amzn-trace-id' => [ 'foobar', $trace = 'Root=1-7696740c-c075312a25f21abe1ca19805;foobar', ], 'x-forwarded-for' => [ '8.8.8.8', $for = '8.8.8.8, 172.105.167.153', ], 'x-forwarded-port' => [ '69', $port = '443', ], 'x-forwarded-proto' => [ 'http', $proto = 'https', ], ], ]); $this->assertSame($trace, $request->serverVariables['HTTP_X_AMZN_TRACE_ID']); $this->assertSame($for, $request->serverVariables['HTTP_X_FORWARDED_FOR']); $this->assertSame($port, $request->serverVariables['HTTP_X_FORWARDED_PORT']); $this->assertSame($proto, $request->serverVariables['HTTP_X_FORWARDED_PROTO']); } public function test_request_content_length_is_numeric() { $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', 'headers' => [ // .. ], ]); $this->assertSame(0, $request->getContentLength()); $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', 'headers' => [ 'content-length' => 1, ], ]); $this->assertSame(1, $request->getContentLength()); $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', 'headers' => [ 'content-length' => '1', ], ]); $this->assertSame(1, $request->getContentLength()); $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', 'headers' => [ 'content-length' => 'foo', ], ]); $this->assertSame(0, $request->getContentLength()); } public function test_api_gateway_v1_request_time_is_set() { $epoch = Carbon::now()->getPreciseTimestamp(3); $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', 'requestContext' => [ 'requestTimeEpoch' => $epoch, ], ]); $this->assertSame($epoch, $request->serverVariables['AWS_API_GATEWAY_REQUEST_TIME']); } public function test_api_gateway_v2_request_time_is_set() { $epoch = Carbon::now()->getPreciseTimestamp(3); $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', 'requestContext' => [ 'timeEpoch' => $epoch, ], ]); $this->assertSame($epoch, $request->serverVariables['AWS_API_GATEWAY_REQUEST_TIME']); } public function test_elb_request_time_is_not_set() { $request = FpmRequest::fromLambdaEvent([ 'httpMethod' => 'GET', ]); $this->assertArrayNotHasKey('AWS_API_GATEWAY_REQUEST_TIME', $request->serverVariables); } } ================================================ FILE: tests/Unit/HttpKernelTest.php ================================================ assertTrue(HttpKernel::shouldSendMaintenanceModeResponse(Request::create('/', 'GET'))); $this->assertFalse(HttpKernel::shouldSendMaintenanceModeResponse(Request::create('http://something.com', 'GET'))); unset($_ENV['APP_VANITY_URL']); unset($_ENV['VAPOR_MAINTENANCE_MODE']); $this->assertFalse(HttpKernel::shouldSendMaintenanceModeResponse(Request::create('/', 'GET'))); $this->assertFalse(HttpKernel::shouldSendMaintenanceModeResponse(Request::create('http://something.com', 'GET'))); } public function test_should_send_isbase64encode_on_binary_response() { $response = new Response('ok', 200); $this->assertFalse(EnsureBinaryEncoding::isBase64EncodingRequired($response)); $response = new Response('{}', 200, [ 'Content-Type' => 'application/json', ]); $this->assertFalse(EnsureBinaryEncoding::isBase64EncodingRequired($response)); $response = new Response('{}', 200, [ 'Content-Type' => 'application/vnd.api+json; charset=UTF-8', ]); $this->assertFalse(EnsureBinaryEncoding::isBase64EncodingRequired($response)); $response = new Response('*', 200, [ 'Content-Type' => 'application/octet-stream', ]); $this->assertTrue(EnsureBinaryEncoding::isBase64EncodingRequired($response)); $response = new Response('*', 200, [ 'Content-Type' => 'image/png', ]); $this->assertTrue(EnsureBinaryEncoding::isBase64EncodingRequired($response)); } } ================================================ FILE: tests/Unit/LambdaEventTest.php ================================================ getEvent(); $this->assertIsArray($event->toArray()); } public function test_array_access() { $event = $this->getEvent(); $this->assertIsArray($event['Records']); $this->assertSame('58600123-d011-4d76-af5d-960159ca44aa', $event['Records.0.messageId']); $this->assertSame('1', $event['Records.0.attributes.ApproximateReceiveCount']); unset($event['Records']); $this->assertFalse(isset($event['Records'])); $event['Records'] = [['messageId' => 'foo']]; $this->assertTrue(isset($event['Records'])); $this->assertSame('foo', $event['Records.0.messageId']); } public function getEvent() { return new LambdaEvent(json_decode( file_get_contents(__DIR__.'/../Fixtures/jobLambdaEventFromSQS.json'), true )); } } ================================================ FILE: tests/Unit/LoadBalancedLambdaResponseTest.php ================================================ [1]], 'body'); $elbResponse = $response->toApiGatewayFormat(); self::assertSame(['Foo-Bar' => ['1'], 'Content-Type' => ['text/html']], $elbResponse['multiValueHeaders']); } } ================================================ FILE: tests/Unit/Logging/JsonFormatterTest.php ================================================ 'context-value'], ['extra-test' => 'extra-value'] ); } else { $record = [ 'datetime' => new \DateTimeImmutable(), 'channel' => 'channel-test', 'level' => 200, 'level_name' => 'INFO', 'message' => 'message-test', 'context' => ['context-test' => 'context-value'], 'extra' => ['extra-test' => 'extra-value'], ]; } $_ENV['AWS_REQUEST_ID'] = '123456789'; $record = $formatter->format($record); $this->assertJson($record); $record = json_decode($record, true); if (class_exists(LogRecord::class)) { $this->assertSame([ 'message' => 'message-test', 'context' => [ 'context-test' => 'context-value', 'aws_request_id' => '123456789', ], 'level' => 200, 'level_name' => 'INFO', 'channel' => 'channel-test', 'datetime' => $record['datetime'], 'extra' => [ 'extra-test' => 'extra-value', ], ], $record); } else { $this->assertSame([ 'datetime' => $record['datetime'], 'channel' => 'channel-test', 'level' => 200, 'level_name' => 'INFO', 'message' => 'message-test', 'context' => [ 'context-test' => 'context-value', 'aws_request_id' => '123456789', ], 'extra' => [ 'extra-test' => 'extra-value', ], ], $record); } } public function test_includes_aws_request_id() { $formatter = new JsonFormatter(); $_ENV['AWS_REQUEST_ID'] = '123456789'; if (class_exists(LogRecord::class)) { $record = new LogRecord( new \DateTimeImmutable(), 'channel-test', Level::Info, 'message-test', ['foo' => 'bar'] ); } else { $record = [ 'datetime' => new \DateTimeImmutable(), 'channel' => 'channel-test', 'level' => 200, 'level_name' => 'INFO', 'message' => 'message-test', 'context' => ['foo' => 'bar'], 'extra' => [], ]; } $record = $formatter->format($record); $this->assertJson($record); $record = json_decode($record, true); $this->assertSame(['foo' => 'bar', 'aws_request_id' => '123456789'], $record['context']); } public function test_aws_request_id_may_be_null() { $formatter = new JsonFormatter(); if (class_exists(LogRecord::class)) { $record = new LogRecord( new \DateTimeImmutable(), 'channel-test', Level::Info, 'message-test' ); } else { $record = [ 'datetime' => new \DateTimeImmutable(), 'channel' => 'channel-test', 'level' => 200, 'level_name' => 'INFO', 'message' => 'message-test', 'context' => [], 'extra' => [], ]; } $record = $formatter->format($record); $this->assertJson($record); $record = json_decode($record, true); $this->assertSame(['aws_request_id' => null], $record['context']); } } ================================================ FILE: tests/Unit/OctaneHttpHandlerFactoryTest.php ================================================ markTestSkipped('Requires Laravel Octane.'); } parent::setUp(); } protected function tearDown(): void { parent::tearDown(); Mockery::close(); } public function test_resolves_warmer() { $handler = OctaneHttpHandlerFactory::make([ 'vaporWarmer' => true, ]); static::assertInstanceOf(WarmerHandler::class, $handler); } public function test_resolves_warmer_ping() { $handler = OctaneHttpHandlerFactory::make([ 'vaporWarmerPing' => true, ]); static::assertInstanceOf(WarmerPingHandler::class, $handler); } public function test_resolves_octane() { $handler = OctaneHttpHandlerFactory::make([ 'httpMethod' => true, ]); static::assertInstanceOf(OctaneHandler::class, $handler); } public function test_resolves_unknown() { $handler = OctaneHttpHandlerFactory::make([ // .. ]); static::assertInstanceOf(UnknownEventHandler::class, $handler); } } ================================================ FILE: tests/Unit/QueueHandlerTest.php ================================================ assertFalse(FakeJob::$handled); $job = new FakeJob; $event = $this->getEvent(); $event['Records'][0]['body'] = json_encode([ 'displayName' => FakeJob::class, 'job' => 'Illuminate\Queue\CallQueuedHandler@call', 'maxTries' => null, 'timeout' => null, 'timeoutAt' => null, 'data' => [ 'commandName' => FakeJob::class, 'command' => serialize($job), ], 'attempts' => 0, ]); QueueHandler::$app = $this->app; $queueHandler = new QueueHandler(); $this->assertFalse(QueueHandler::$app->bound(LambdaEvent::class)); $queueHandler->handle($event); $this->assertFalse(QueueHandler::$app->bound(LambdaEvent::class)); $this->assertTrue(FakeJob::$handled); } protected function getPackageProviders($app) { return [ \Laravel\Vapor\VaporServiceProvider::class, ]; } protected function getEnvironmentSetUp($app) { $app['config']->set('queue.connections.vapor', [ 'driver' => 'sqs', 'key' => env('SQS_KEY', 'your-public-key'), 'secret' => env('SQS_SECRET', 'your-secret-key'), 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 'queue' => env('SQS_QUEUE', 'your-queue-name'), 'region' => env('SQS_REGION', 'us-east-1'), 'delay' => env('SQS_DELAY', 0), 'tries' => env('SQS_TRIES', 0), 'force' => env('SQS_FORCE', false), ]); } protected function getEvent() { return json_decode( file_get_contents(__DIR__.'/../Fixtures/jobLambdaEventFromSQS.json'), true ); } } ================================================ FILE: tests/Unit/Runtime/CliHandlerFactoryTest.php ================================================ assertInstanceOf(CliHandler::class, CliHandlerFactory::make($this->getSQSCustomEvent())); } public function test_custom_non_sqs_lambda_events_use_cli_handler() { $this->assertInstanceOf(CliHandler::class, CliHandlerFactory::make($this->getCustomNonSQSLambdaEvent())); } public function test_laravel_jobs_use_queue_handler() { $this->assertInstanceOf(QueueHandler::class, CliHandlerFactory::make($this->getSQSJobEvent())); } public function test_custom_handler_factory_is_used_when_set() { CliHandlerFactory::createHandlerUsing(function ($event) { return new CliHandler; }); $this->assertInstanceOf(CliHandler::class, CliHandlerFactory::make($this->getSQSJobEvent())); } public function test_custom_handler_factory_receives_event() { $receivedEvent = null; CliHandlerFactory::createHandlerUsing(function ($event) use (&$receivedEvent) { $receivedEvent = $event; return new CliHandler; }); $expectedEvent = $this->getSQSJobEvent(); CliHandlerFactory::make($expectedEvent); $this->assertSame($expectedEvent, $receivedEvent); } public function test_default_behavior_is_restored_after_reset() { CliHandlerFactory::createHandlerUsing(function ($event) { return new CliHandler; }); CliHandlerFactory::createHandlersNormally(); $this->assertInstanceOf(QueueHandler::class, CliHandlerFactory::make($this->getSQSJobEvent())); } protected function getCustomNonSQSLambdaEvent() { return json_decode( file_get_contents(__DIR__.'/../../Fixtures/customNonSQSLambdaEvent.json'), true ); } protected function getSQSJobEvent() { return json_decode( file_get_contents(__DIR__.'/../../Fixtures/jobLambdaEventFromSQS.json'), true ); } protected function getSQSCustomEvent() { return json_decode( file_get_contents(__DIR__.'/../../Fixtures/customLambdaEventFromSQS.json'), true ); } } ================================================ FILE: tests/Unit/VaporConnectorTest.php ================================================ connect([ 'driver' => 'sqs', 'key' => 'test-key', 'secret' => 'test-secret', 'prefix' => 'https://sqs.us-east-1.amazonaws.com/111111111', 'queue' => 'test-queue', 'region' => 'us-east-1', ]); $this->assertInstanceOf(VaporQueue::class, $queue); } } ================================================ FILE: tests/Unit/VaporScheduleCommandTest.php ================================================ once()->andReturn('array'); $fake->shouldNotReceive('remember'); if (version_compare($this->app->version(), 10, 'eq')) { $fake->shouldReceive('forget')->once()->with('illuminate:schedule:interrupt')->andReturn(true); } if (version_compare($this->app->version(), 11, '>=')) { Cache::shouldReceive('driver')->twice()->andReturn($fake); } elseif (! Str::startsWith($this->app->version(), '9')) { Cache::shouldReceive('driver')->once()->andReturn($fake); } $fake->shouldNotReceive('forget')->with('vapor:schedule:lock'); if (version_compare($this->app->version(), '13.0.0', '>=')) { $fake->shouldReceive('get')->with('illuminate:schedule:paused', false)->andReturn(false); } $this->artisan('vapor:schedule') ->assertExitCode(0); } public function test_scheduler_is_called_at_the_top_of_the_minute() { Cache::shouldReceive('getDefaultDriver')->once()->andReturn('dynamodb'); Cache::shouldReceive('driver')->andReturn($fake = Mockery::mock(Repository::class)); $fake->shouldReceive('remember')->once()->with('vapor:schedule:lock', 60, Mockery::any())->andReturn('test-schedule-lock-key'); if (version_compare($this->app->version(), 10, 'eq')) { $fake->shouldReceive('forget')->once()->with('illuminate:schedule:interrupt')->andReturn(true); } $fake->shouldReceive('forget')->once()->with('vapor:schedule:lock')->andReturn(true); if (version_compare($this->app->version(), '13.0.0', '>=')) { $fake->shouldReceive('get')->with('illuminate:schedule:paused', false)->andReturn(false); } $this->artisan('vapor:schedule') ->assertExitCode(0); } public function test_scheduler_is_not_invoked_if_lock_cannot_be_obtained() { Cache::shouldReceive('getDefaultDriver')->once()->andReturn('dynamodb'); Cache::shouldReceive('driver')->andReturn($fake = Mockery::mock(Repository::class)); $fake->shouldReceive('remember')->once()->with('vapor:schedule:lock', 60, Mockery::any())->andReturn('test-locked-schedule-lock-key'); $fake->shouldNotReceive('forget')->with('illuminate:schedule:interrupt')->andReturn(true); $fake->shouldNotReceive('forget')->with('vapor:schedule:lock'); $this->artisan('vapor:schedule') ->assertExitCode(1); } } ================================================ FILE: tests/Unit/VaporTest.php ================================================ assertTrue(Vapor::active()); } public function test_vapor_inactive() { $this->assertTrue(Vapor::inactive()); } public function test_vapor_when_active() { $_ENV['VAPOR_SSM_PATH'] = '/my-project-production'; $this->assertSame('active', Vapor::whenActive('active', 'inactive')); } public function test_vapor_when_active_with_callback() { $_ENV['VAPOR_SSM_PATH'] = '/my-project-production'; $this->assertSame('active', Vapor::whenActive(function () { return 'active'; }, 'inactive')); } public function test_vapor_when_inactive() { $this->assertSame('inactive', Vapor::whenInactive('inactive', 'active')); } public function test_vapor_when_inactive_with_callback() { $this->assertSame('inactive', Vapor::whenInactive(function () { return 'inactive'; }, 'active')); } } ================================================ FILE: tests/Unit/VaporWorkCommandTest.php ================================================ assertFalse(FakeJob::$handled); $job = new FakeJob; $event = $this->getEvent(); $event['Records.0.body'] = json_encode([ 'displayName' => FakeJob::class, 'job' => 'Illuminate\Queue\CallQueuedHandler@call', 'maxTries' => null, 'timeout' => null, 'timeoutAt' => null, 'data' => [ 'commandName' => FakeJob::class, 'command' => serialize($job), ], 'attempts' => 0, ]); $this->instance(LambdaEvent::class, $event); $this->artisan('vapor:work'); $this->assertTrue(FakeJob::$handled); } protected function getPackageProviders($app) { return [ \Laravel\Vapor\VaporServiceProvider::class, ]; } protected function getEnvironmentSetUp($app) { $app['config']->set('queue.connections.vapor', [ 'driver' => 'sqs', 'key' => env('SQS_KEY', 'your-public-key'), 'secret' => env('SQS_SECRET', 'your-secret-key'), 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 'queue' => env('SQS_QUEUE', 'your-queue-name'), 'region' => env('SQS_REGION', 'us-east-1'), 'delay' => env('SQS_DELAY', 0), 'tries' => env('SQS_TRIES', 0), 'force' => env('SQS_FORCE', false), ]); } protected function getEvent() { return new LambdaEvent(json_decode( file_get_contents(__DIR__.'/../Fixtures/jobLambdaEventFromSQS.json'), true )); } }