From 0b2c508761dcf23746112f6221622a4e9ecc5ae4 Mon Sep 17 00:00:00 2001 From: spbsoluble <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 13 Aug 2026 18:53:26 -0700 Subject: [PATCH 1/8] feat: Initial release --- .github/workflows/codemap-check.yml | 48 + .github/workflows/integration-tests.yml | 39 + .../keyfactor-bootstrap-workflow.yml | 19 + .github/workflows/unit-tests.yml | 42 + .gitignore | 19 +- CHANGELOG.md | 3 + DEVELOPMENT.md | 456 ++++ README.md | 535 ++++- TestConsole/Helpers/CSRGenerator.cs | 7 +- TestConsole/Program.cs | 127 +- TestConsole/README.md | 40 + TestConsole/TestConsole.csproj | 4 +- TestConsole/lib/MarkmonitorDigiCACert.pem | 28 + docs/Gemfile | 7 + docs/_config.yml | 36 + docs/_includes/head_custom.html | 44 + docs/_includes/header_custom.html | 22 + docs/_includes/mermaid_config.js | 10 + docs/_sass/color_schemes/keyfactor-dark.scss | 20 + docs/_sass/color_schemes/keyfactor.scss | 14 + docs/_sass/custom/custom.scss | 40 + docs/architecture.md | 170 ++ .../css/just-the-docs-keyfactor-dark.scss | 3 + docs/assets/css/just-the-docs-keyfactor.scss | 3 + .../images/gateway_ca_configuration.png | Bin 0 -> 244663 bytes .../gateway_registration_local_file.png | Bin 0 -> 266981 bytes .../images/gateway_registration_store.png | Bin 0 -> 257629 bytes docs/assets/images/gateway_template.png | Bin 0 -> 239498 bytes docs/assets/images/logo.svg | 33 + .../images/template_enrollment_params.png | Bin 0 -> 218432 bytes docs/changelog.md | 15 + docs/configuration.md | 106 + docs/index.md | 61 + docs/installation.md | 80 + docs/overview.md | 97 + docsource/CODEMAP.md | 185 ++ docsource/configuration.md | 390 ++++ docsource/images/gateway_ca_configuration.png | Bin 0 -> 244663 bytes .../gateway_registration_local_file.png | Bin 0 -> 266981 bytes .../images/gateway_registration_store.png | Bin 0 -> 257629 bytes docsource/images/gateway_template.png | Bin 0 -> 239498 bytes .../images/template_enrollment_params.png | Bin 0 -> 218432 bytes docsource/overview.md | 158 ++ integration-manifest.json | 152 +- justfile | 128 ++ markmonitor-cagateway.sln | 38 - .../Client/MarkMonitorClient.cs | 849 ------- markmonitor-cagateway/Constants.cs | 6 - .../MarkMonitorCAConnector.cs | 287 --- .../MarkMonitorCAPluginConfig.cs | 213 -- markmonitor-cagateway/MarkMonitorConfig.cs | 26 - .../Models/EnrollCertificateRequest.cs | 18 - markmonitor-cagateway/Models/IssuerDn.cs | 18 - markmonitor-cagateway/Models/SubjectDn.cs | 18 - .../markmonitor-cagateway.csproj | 33 - markmonitor-cagateway/packages.config | 14 - .../MarkMonitorClientAuthenticateLiveTests.cs | 26 + .../MarkMonitorClientEnrollLiveTests.cs | 90 + ...torClientListCertificateOrdersLiveTests.cs | 34 + .../MarkMonitorClientListOrgsLiveTests.cs | 42 + .../LiveApiCredentials.cs | 21 + .../OrderCleanup.cs | 37 + ...rkmonitor-caplugin.IntegrationTests.csproj | 33 + .../MarkMonitorClientAdditionalEmailsTests.cs | 36 + .../MarkMonitorClientAuthLifecycleTests.cs | 130 ++ .../MarkMonitorClientAuthenticateTests.cs | 147 ++ .../Client/MarkMonitorClientCancelTests.cs | 118 + .../MarkMonitorClientCleanSubjectTests.cs | 57 + .../Client/MarkMonitorClientDisposeTests.cs | 18 + ...MarkMonitorClientEnrollIdempotencyTests.cs | 411 ++++ .../MarkMonitorClientEnrollLoggingTests.cs | 147 ++ .../Client/MarkMonitorClientEnrollTests.cs | 155 ++ ...MonitorClientErrorMessageRedactionTests.cs | 54 + .../MarkMonitorClientErrorPropagationTests.cs | 109 + .../MarkMonitorClientFetchOrderAuthTests.cs | 82 + .../MarkMonitorClientGetSingleOrderTests.cs | 112 + .../Client/MarkMonitorClientInventoryTests.cs | 112 + ...MarkMonitorClientOrderIdValidationTests.cs | 88 + .../MarkMonitorClientOrgResolutionTests.cs | 153 ++ .../MarkMonitorClientPickupPollingTests.cs | 245 ++ .../MarkMonitorClientQueryEncodingTests.cs | 51 + .../Client/MarkMonitorClientRetryTests.cs | 211 ++ .../Client/MarkMonitorClientRevokeTests.cs | 137 ++ .../Client/MarkMonitorClientSanTests.cs | 161 ++ .../MarkMonitorClientStatusMappingTests.cs | 52 + .../MarkMonitorClientSyncResilienceTests.cs | 289 +++ .../MarkMonitorCAPluginClientCachingTests.cs | 34 + .../MarkMonitorCAPluginEnrollTests.cs | 77 + ...MarkMonitorCAPluginGetSingleRecordTests.cs | 27 + .../MarkMonitorCAPluginPingTests.cs | 79 + .../MarkMonitorCAPluginRenewOrReissueTests.cs | 322 +++ .../MarkMonitorCAPluginRevokeTests.cs | 94 + ...itorCAPluginValidateConnectionInfoTests.cs | 183 ++ ...MonitorCAPluginValidateProductInfoTests.cs | 57 + .../MarkMonitorConfigTests.cs | 86 + .../Models/TokenResponseTests.cs | 23 + .../TestHelpers/CapturingLoggerFactory.cs | 62 + .../FakeAnyCAPluginConfigProvider.cs | 26 + .../TestHelpers/FakeCertificateDataReader.cs | 35 + .../TestHelpers/FakeHttpMessageHandler.cs | 111 + .../LogHandlerFactoryCollection.cs | 14 + .../TestHelpers/ManualTimeProvider.cs | 9 + .../TestHelpers/SampleConfig.cs | 21 + .../TestHelpers/SampleCsr.cs | 23 + .../TestHelpers/SampleCsr2.cs | 24 + .../TestHelpers/SampleCsrWithSans.cs | 42 + .../TestHelpers/SampleEccCsrs.cs | 32 + .../TestHelpers/SampleOrders.cs | 65 + .../TestHelpers/SampleOrgs.cs | 46 + .../markmonitor-caplugin.Tests.csproj | 28 + markmonitor-caplugin.sln | 86 + .../Client/MarkMonitorClient.cs | 2025 +++++++++++++++++ markmonitor-caplugin/LogSanitizer.cs | 13 + .../MarkMonitorCAConnector.cs | 663 ++++++ .../MarkMonitorCAPluginConfig.cs | 278 +++ markmonitor-caplugin/MarkMonitorConfig.cs | 137 ++ .../Models/Enums.cs | 13 + .../Models/MarkMonitorCommon.cs | 0 .../Models/MarkMonitorGetContactResponse.cs | 0 .../MarkMonitorGetOrganizationResponse.cs | 0 .../MarkMonitorListCertificatesResponse.cs | 0 .../Models/MarkMonitorListContactsResponse.cs | 0 .../Models/MarkMonitorListGroupsResponse.cs | 57 + .../Models/MarkMonitorListOrgsResponse.cs | 0 .../Models/MarkMonitorOrder.cs | 6 + .../Models/MarkMonitorOrderRequest.cs | 0 .../Models/MarkMonitorReissueRequest.cs | 0 .../Models/TokenRequest.cs | 0 .../Models/TokenResponse.cs | 2 +- .../Properties/AssemblyInfo.cs | 7 +- .../app.config | 0 .../manifest.json | 2 +- .../markmonitor-caplugin.csproj | 54 + 133 files changed, 11181 insertions(+), 1701 deletions(-) create mode 100644 .github/workflows/codemap-check.yml create mode 100644 .github/workflows/integration-tests.yml create mode 100644 .github/workflows/keyfactor-bootstrap-workflow.yml create mode 100644 .github/workflows/unit-tests.yml create mode 100644 DEVELOPMENT.md create mode 100644 TestConsole/README.md create mode 100644 TestConsole/lib/MarkmonitorDigiCACert.pem create mode 100644 docs/Gemfile create mode 100644 docs/_config.yml create mode 100644 docs/_includes/head_custom.html create mode 100644 docs/_includes/header_custom.html create mode 100644 docs/_includes/mermaid_config.js create mode 100644 docs/_sass/color_schemes/keyfactor-dark.scss create mode 100644 docs/_sass/color_schemes/keyfactor.scss create mode 100644 docs/_sass/custom/custom.scss create mode 100644 docs/architecture.md create mode 100644 docs/assets/css/just-the-docs-keyfactor-dark.scss create mode 100644 docs/assets/css/just-the-docs-keyfactor.scss create mode 100644 docs/assets/images/gateway_ca_configuration.png create mode 100644 docs/assets/images/gateway_registration_local_file.png create mode 100644 docs/assets/images/gateway_registration_store.png create mode 100644 docs/assets/images/gateway_template.png create mode 100644 docs/assets/images/logo.svg create mode 100644 docs/assets/images/template_enrollment_params.png create mode 100644 docs/changelog.md create mode 100644 docs/configuration.md create mode 100644 docs/index.md create mode 100644 docs/installation.md create mode 100644 docs/overview.md create mode 100644 docsource/CODEMAP.md create mode 100644 docsource/configuration.md create mode 100644 docsource/images/gateway_ca_configuration.png create mode 100644 docsource/images/gateway_registration_local_file.png create mode 100644 docsource/images/gateway_registration_store.png create mode 100644 docsource/images/gateway_template.png create mode 100644 docsource/images/template_enrollment_params.png create mode 100644 docsource/overview.md create mode 100644 justfile delete mode 100644 markmonitor-cagateway.sln delete mode 100644 markmonitor-cagateway/Client/MarkMonitorClient.cs delete mode 100644 markmonitor-cagateway/Constants.cs delete mode 100644 markmonitor-cagateway/MarkMonitorCAConnector.cs delete mode 100644 markmonitor-cagateway/MarkMonitorCAPluginConfig.cs delete mode 100644 markmonitor-cagateway/MarkMonitorConfig.cs delete mode 100644 markmonitor-cagateway/Models/EnrollCertificateRequest.cs delete mode 100644 markmonitor-cagateway/Models/IssuerDn.cs delete mode 100644 markmonitor-cagateway/Models/SubjectDn.cs delete mode 100644 markmonitor-cagateway/markmonitor-cagateway.csproj delete mode 100644 markmonitor-cagateway/packages.config create mode 100644 markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs create mode 100644 markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs create mode 100644 markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs create mode 100644 markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs create mode 100644 markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs create mode 100644 markmonitor-caplugin.IntegrationTests/OrderCleanup.cs create mode 100644 markmonitor-caplugin.IntegrationTests/markmonitor-caplugin.IntegrationTests.csproj create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs create mode 100644 markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs create mode 100644 markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs create mode 100644 markmonitor-caplugin.Tests/Models/TokenResponseTests.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs create mode 100644 markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs create mode 100644 markmonitor-caplugin.Tests/markmonitor-caplugin.Tests.csproj create mode 100644 markmonitor-caplugin.sln create mode 100644 markmonitor-caplugin/Client/MarkMonitorClient.cs create mode 100644 markmonitor-caplugin/LogSanitizer.cs create mode 100644 markmonitor-caplugin/MarkMonitorCAConnector.cs create mode 100644 markmonitor-caplugin/MarkMonitorCAPluginConfig.cs create mode 100644 markmonitor-caplugin/MarkMonitorConfig.cs rename {markmonitor-cagateway => markmonitor-caplugin}/Models/Enums.cs (93%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorCommon.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorGetContactResponse.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorGetOrganizationResponse.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorListCertificatesResponse.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorListContactsResponse.cs (100%) create mode 100644 markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorListOrgsResponse.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorOrder.cs (95%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorOrderRequest.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/MarkMonitorReissueRequest.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/TokenRequest.cs (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/Models/TokenResponse.cs (73%) rename {markmonitor-cagateway => markmonitor-caplugin}/Properties/AssemblyInfo.cs (86%) rename {markmonitor-cagateway => markmonitor-caplugin}/app.config (100%) rename {markmonitor-cagateway => markmonitor-caplugin}/manifest.json (88%) create mode 100644 markmonitor-caplugin/markmonitor-caplugin.csproj diff --git a/.github/workflows/codemap-check.yml b/.github/workflows/codemap-check.yml new file mode 100644 index 0000000..9318c30 --- /dev/null +++ b/.github/workflows/codemap-check.yml @@ -0,0 +1,48 @@ +name: CODEMAP freshness + +# Guards the honor-system rule in docsource/CODEMAP.md: a PR that changes plugin +# source must also update the codemap, so agents/humans can trust it as the +# orientation map. The generated root README.md is handled separately by the +# Keyfactor bootstrap workflow (it auto-commits a regenerated README), so this +# check deliberately covers only the hand-maintained CODEMAP. +# +# Escape hatch: add the "skip-codemap" label to a PR when a source change +# genuinely does not affect the codemap (e.g. a comment-only or whitespace edit). + +on: + pull_request: + paths: + - 'markmonitor-caplugin/**' + +jobs: + codemap: + runs-on: ubuntu-latest + if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-codemap') }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Require CODEMAP update when plugin source changes + env: + BASE: ${{ github.event.pull_request.base.sha }} + HEAD: ${{ github.event.pull_request.head.sha }} + run: | + set -euo pipefail + changed="$(git diff --name-only "$BASE" "$HEAD")" + + # Production plugin source only: exclude build output and the test project. + src="$(printf '%s\n' "$changed" \ + | grep -E '^markmonitor-caplugin/.*\.cs$' \ + | grep -vE '/(bin|obj)/' || true)" + + codemap="$(printf '%s\n' "$changed" | grep -E '^docsource/CODEMAP\.md$' || true)" + + if [ -n "$src" ] && [ -z "$codemap" ]; then + echo "::error::Plugin source changed but docsource/CODEMAP.md was not updated. Update the codemap to match, or add the 'skip-codemap' label if this change genuinely does not affect it." + echo "Changed plugin source files:" + printf ' %s\n' $src + exit 1 + fi + + echo "CODEMAP freshness check passed." diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 0000000..019d5c2 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,39 @@ +name: Integration Tests + +# Manual-only: hits the real MarkMonitor sandbox API and creates/cancels real orders. Never runs on +# push or pull_request. The "markmonitor-integration" environment additionally gates every run +# behind a required reviewer approval, on top of this workflow_dispatch trigger. + +on: + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + environment: markmonitor-integration + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + 10.0.x + + - name: Add Keyfactor GitHub Packages NuGet source + run: | + dotnet nuget add source "https://nuget.pkg.github.com/Keyfactor/index.json" \ + --name keyfactor-github \ + --username keyfactor \ + --password "${{ secrets.V2BUILDTOKEN }}" \ + --store-password-in-clear-text + + - name: Run live integration tests + env: + MARKMONITOR_BASE_URL: ${{ secrets.MARKMONITOR_BASE_URL }} + MARKMONITOR_API_TOKEN: ${{ secrets.MARKMONITOR_API_TOKEN }} + MARKMONITOR_USERNAME: ${{ secrets.MARKMONITOR_USERNAME }} + MARKMONITOR_PASSWORD: ${{ secrets.MARKMONITOR_PASSWORD }} + run: dotnet test markmonitor-caplugin.IntegrationTests/markmonitor-caplugin.IntegrationTests.csproj --configuration Release --verbosity normal diff --git a/.github/workflows/keyfactor-bootstrap-workflow.yml b/.github/workflows/keyfactor-bootstrap-workflow.yml new file mode 100644 index 0000000..bd05b07 --- /dev/null +++ b/.github/workflows/keyfactor-bootstrap-workflow.yml @@ -0,0 +1,19 @@ +name: Keyfactor Bootstrap Workflow + +on: + workflow_dispatch: + pull_request: + types: [opened, closed, synchronize, edited, reopened] + push: + create: + branches: + - 'release-*.*' + +jobs: + call-starter-workflow: + uses: keyfactor/actions/.github/workflows/starter.yml@v5 + secrets: + token: ${{ secrets.V2BUILDTOKEN}} + gpg_key: ${{ secrets.KF_GPG_PRIVATE_KEY }} + gpg_pass: ${{ secrets.KF_GPG_PASSPHRASE }} + scan_token: ${{ secrets.SAST_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..be350ea --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,42 @@ +name: Unit Tests + +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: + - main + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + 10.0.x + + # markmonitor-caplugin.Tests references markmonitor-caplugin, which restores several + # Keyfactor.* packages from Keyfactor's GitHub Packages feed - not just nuget.org. + # + # Deliberately not locked down with a checked-in nuget.config + packageSourceMapping: the + # keyfactor-bootstrap-workflow's shared dotnet-build-and-release action adds its own NuGet + # source (named "github", credentialed with this same token) via the same mechanism, and a + # repo-wide nuget.config restricting Keyfactor.* to a source name/mapping this workflow alone + # controls would leave that other, already-green workflow's differently-named source + # unable to resolve any Keyfactor.* package. + - name: Add Keyfactor GitHub Packages NuGet source + run: | + dotnet nuget add source "https://nuget.pkg.github.com/Keyfactor/index.json" \ + --name keyfactor-github \ + --username keyfactor \ + --password "${{ secrets.V2BUILDTOKEN }}" \ + --store-password-in-clear-text + + - name: Run unit tests + run: dotnet test markmonitor-caplugin.Tests/markmonitor-caplugin.Tests.csproj --configuration Release --verbosity normal diff --git a/.gitignore b/.gitignore index 6b4a476..d78b105 100644 --- a/.gitignore +++ b/.gitignore @@ -364,4 +364,21 @@ FodyWeavers.xsd *.env *.env.local -*.idea/ \ No newline at end of file +*.idea/ + +# Local scratch/sandbox artifacts - contain sandbox credentials or org/contact data +# and are not meant to be committed. +.DS_Store +/order_from_*.json +TestConsole/Scripts/ +TestConsole/lib/list_real.json +TestConsole/lib/request.json +# Claude Code local settings (never commit) +.claude/ + +# Jekyll local preview build output/vendored gems (see `just docs-preview`) +docs/_site/ +docs/.jekyll-cache/ +docs/.bundle/ +docs/vendor/ +docs/Gemfile.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29..3b529de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# Features + +- initial release diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..0eed198 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,456 @@ +# Developer Guide + +This document covers local development, testing, live API smoke-testing, and the internal design of +the MarkMonitor AnyCA Gateway REST plugin. For production deployment and CA connector configuration +for end users, see [README.md](README.md). + +## Prerequisites + +- .NET SDK 8.0 **and** 10.0 (the plugin dual-targets `net8.0` and `net10.0`). +- A MarkMonitor API key and service account for live smoke-testing (see + [Live smoke-testing](#live-smoke-testing-testconsole)). Not required to build or run the unit + tests. + +## Solution Layout + +The solution (`markmonitor-caplugin.sln`) contains four projects: + +| Project | Purpose | +|---|---| +| `markmonitor-caplugin/` | The plugin itself. Produces `MarkMonitorCAPlugin.dll` per TFM under `bin/Release//`. `manifest.json` is copied alongside the DLL on every build — it is how the AnyCA Gateway host discovers the plugin type (`Keyfactor.Extensions.CAPlugin.MarkMonitor.MarkMonitorCAPlugin`). | +| `markmonitor-caplugin.Tests/` | xUnit unit-test project (mocked HTTP, no live API). Targets `net8.0`. | +| `markmonitor-caplugin.IntegrationTests/` | xUnit live-API test project — real `MarkMonitorClient` calls against the actual MarkMonitor API (authenticate, list orgs, list certificate orders, RSA/ECC enroll). Targets `net8.0`. Each test skips (no-op pass) when the `MARKMONITOR_*` env vars aren't set, so it's always safe to run; when creds are present it creates and cleans up real orders. See [Live Integration Tests](#live-integration-tests-markmonitor-caplugin-integrationtests) below. | +| `TestConsole/` | Manual live integration/smoke-test console app that drives `MarkMonitorClient` directly against a live or sandbox MarkMonitor API. Destructive by nature (creates real orders). | + +Key source files inside `markmonitor-caplugin/`: + +- **`MarkMonitorCAConnector.cs`** — `IAnyCAPlugin` implementation; the Gateway host entry point. +- **`Client/MarkMonitorClient.cs`** — the MarkMonitor REST HTTP client (auth, pagination, CSR + handling, status mapping, dedup cache). +- **`MarkMonitorCAPluginConfig.cs`** — CA-connection and enrollment-parameter schema, UI + annotations/defaults, and the canonical field-name constants (`ConfigConstants` / + `EnrollmentConfigConstants`). +- **`Models/`** — request/response DTOs plus `Enums.cs` (`CertOrderTypes`, `OrderStatus`, + `DomainControlValidationMethods`, etc.). Enum-to-API-string mapping goes through the + `[Description]` attribute + `EnumExtensions.GetDescription()`. + +## Build + +```shell +dotnet build markmonitor-caplugin.sln -c Release +``` + +This produces `MarkMonitorCAPlugin.dll` for each TFM under +`markmonitor-caplugin/bin/Release/net8.0/` and `.../net10.0/`, each with `manifest.json` copied +alongside. + +To deploy manually, copy the contents of the target framework's output directory into the Gateway's +`Extensions` folder and restart the AnyCA Gateway REST service (see the [README.md](README.md) +Installation section for the exact path). + +## Unit Tests + +The `markmonitor-caplugin.Tests/` project is an xUnit suite that exercises the connector and client +against a fake `HttpMessageHandler` (see `TestHelpers/FakeHttpMessageHandler.cs`) and injected fakes +(`FakeCertificateDataReader`, `FakeAnyCAPluginConfigProvider`, `ManualTimeProvider`) — no live API or +credentials are required, so it is safe to run in CI. + +```shell +dotnet test markmonitor-caplugin.sln -c Release +``` + +Coverage is collected via `coverlet.collector`. The suite covers, among other areas: + +- Connector operations — enroll, revoke, renew-or-reissue, connection-info validation, client + caching. +- Client behavior — inventory/sync, pagination and query encoding, order-ID GUID validation, subject + (`CN`) cleaning, ECC named-curve validation, cancel, error propagation, and enroll logging/redaction. + +When you add or change behavior, add or update tests here — a fake handler that returns canned +MarkMonitor JSON is the established pattern for new client tests. + +## Live Integration Tests (`markmonitor-caplugin.IntegrationTests`) + +The `markmonitor-caplugin.IntegrationTests/` project is an xUnit suite that hits the **real** +MarkMonitor API, covering the same scenarios `TestConsole/Program.cs` walks through by hand: +authenticate, list organizations, list certificate orders, and enroll (once with an RSA CSR, once +with an ECC CSR, both generated via `TestConsole.Helpers.CsrGenerator`/`EmailAddressGenerator` — +this project references `TestConsole/TestConsole.csproj` purely to reuse those two helpers, not to +run `TestConsole` itself). + +Every test reads the same four `MARKMONITOR_*` environment variables `TestConsole` uses and returns +immediately (a silent pass, not a skip/failure) if any are unset: + +``` +MARKMONITOR_BASE_URL +MARKMONITOR_API_TOKEN +MARKMONITOR_USERNAME +MARKMONITOR_PASSWORD +``` + +This makes the project safe to run unconditionally — in CI or on a laptop with no `.env` sourced — +without ever failing for lack of credentials. It is **not** wired into `.github/workflows/unit-tests.yml` +(that workflow runs `markmonitor-caplugin.Tests/markmonitor-caplugin.Tests.csproj` directly, not the +whole solution). + +To run locally: + +```shell +set -a && source .env && set +a # or TestConsole/.env +dotnet test markmonitor-caplugin.IntegrationTests -c Release +``` + +`.github/workflows/integration-tests.yml` runs the same command in CI, but only on a manual +`workflow_dispatch` — never on push or pull_request. The job also targets the `markmonitor-integration` +GitHub environment, which holds the four `MARKMONITOR_*` secrets and requires reviewer approval before +a dispatched run can access them — a second gate on top of the manual trigger, since a run creates +real (sandbox) orders. + +Unlike `TestConsole`, the enrollment tests have **no `MARKMONITOR_SKIP_CLEANUP` escape hatch** — each +one always cancels (falling back to revoke) the order it creates before returning, win or lose, +since this is a repeatable automated suite rather than a manual inspection tool. A cleanup failure +throws (failing the test loudly) instead of just logging a warning, so a billable order that +couldn't be cleaned up is never left behind silently. + +## Live Smoke-Testing (`TestConsole`) + +`TestConsole/Program.cs` runs a scripted sequence against a live (or sandbox) MarkMonitor API: +authenticate, list organizations, list certificate orders, then generate RSA/ECC CSRs and submit real +enrollment orders. It is a **manual smoke-test harness, not a repeatable CI test suite** — it creates +real orders and is destructive/live by nature. + +It requires real credentials as environment variables: + +``` +MARKMONITOR_BASE_URL # e.g. https://api.markmonitor.com (or your sandbox URL) +MARKMONITOR_API_TOKEN # the X-API-KEY value +MARKMONITOR_USERNAME # service-account username +MARKMONITOR_PASSWORD # service-account password +``` + +`TestConsole/.env` holds these locally and is gitignored. By default the console cancels/revokes the +orders it creates so test runs don't accumulate charges; set `MARKMONITOR_SKIP_CLEANUP=true` to leave +them in place. + +Run it with: + +```shell +dotnet run --project TestConsole +``` + +> **Test-environment note:** in the MarkMonitor test setup, an enrolled order's common name must be +> `.mmcertdomain.com` or the request is rejected, and issuance requires manual email +> approval — enrollments will sit pending until approved, then appear in Command on the next +> incremental sync. + +## Adding a New MarkMonitor Product + +1. Add a member to `CertOrderTypes` in `Models/Enums.cs` with the matching `[Description("...")]` + (the MarkMonitor cert-type string). +2. Add the same product-ID name to `product_ids` in `integration-manifest.json`. +3. No separate list needs editing — `GetProductIds()` derives from the enum, and enrollment maps the + Command product ID to the MarkMonitor string via `GetDescription()`. + +## Keeping Metadata and Docs in Sync + +- `integration-manifest.json` (repo root) drives Keyfactor's integration catalog metadata + (`product_ids`, `ca_plugin_config`, `enrollment_config`) — keep it in sync with + `MarkMonitorCAPluginConfig.cs` and `CertOrderTypes` whenever either changes. +- `docsource/configuration.md` and `docsource/overview.md` are the source-of-truth, customer-facing + documentation fragments. Root `README.md` is generated by the Keyfactor doctool + (`~/RiderProjects/doctooldotnet`) from `docsource/configuration.md` + `integration-manifest.json` — + never hand-edit `README.md`; edit `docsource/configuration.md` and regenerate. This `DEVELOPMENT.md` + file, like `LICENSE`, is hand-maintained at the repo root and is **not** part of the doctool + pipeline — edit it directly. +- `docsource/CODEMAP.md` is the orientation map for this repo — update it whenever you change the + architecture, add/move key files, or change the build/test layout. + +## Architecture + +This section describes how the MarkMonitor AnyCA Gateway REST plugin integrates with Keyfactor +Command and the MarkMonitor SSL certificate API. It covers the primary certificate lifecycle +operations — synchronization, enrollment, and revocation — and how the plugin routes each through +the MarkMonitor REST API. + +### Component Overview + +See [README.md](README.md#component-overview) for the high-level component diagram. The two source +files that matter most: + +* **`MarkMonitorCAConnector.cs`** — the `IAnyCAPlugin` entry point the Gateway host calls + (`Initialize`, `Enroll`, `Revoke`, `Synchronize`, `GetSingleRecord`, `Ping`, + `ValidateCAConnectionInfo`, `ValidateProductInfo`, `GetProductIds`, and the annotation pair). It + holds the deserialized connection config and a single lazily-built `MarkMonitorClient`. +* **`Client/MarkMonitorClient.cs`** — the HTTP client for the MarkMonitor REST API. It owns + bearer-token authentication, list pagination, CSR PEM/DER handling (via BouncyCastle), the + enrollment dedup cache, and the MarkMonitor-order-status → Keyfactor-status mapping. + +### Request Authentication + +MarkMonitor uses two credentials together. The API key is sent as the `X-API-KEY` header on the +authentication request; the service-account username and password are POSTed to +`/auth/v1/auth/authenticate`, which returns a bearer token and its lifetime (`expiresIn`). Every +subsequent request carries `Authorization: Bearer `. + +The token is cached in the `MarkMonitorClient` instance with a small safety buffer (it is treated as +expired 30 seconds early so a request that starts just before expiry doesn't race the token dying +mid-flight). Re-authentication is lazy and guarded by double-checked locking on a semaphore: callers +that find a valid token proceed without locking; only a caller that observes an +expired/missing token takes the lock, and re-checks inside it, so concurrent operations cannot race +each other into two authentication calls or send requests under a half-written token. + +``` +Authorization: Bearer where token ← POST /auth/v1/auth/authenticate + headers: X-API-KEY: + body: { username, password } +``` + +### Certificate Identifiers + +MarkMonitor identifies each order by a **GUID order ID**. That order ID is what the plugin stores in +Keyfactor Command as the `CARequestID`, and it is the identifier used for every post-enrollment +operation (get single record, revoke). Because order IDs are interpolated directly into request +URLs, the client validates that any incoming order ID parses as a GUID before using it — a corrupted +or manipulated `CARequestID` fails fast with a clear error rather than producing an unexpected URL +path segment. + +The configured `OrgId` may be supplied either as a friendly organization **name** or as a **GUID**. +The client resolves a name to its GUID by listing organizations filtered by name; a value that +already parses as a GUID is used directly. + +--- + +### Gateway Startup + +When the AnyCA Gateway process loads the connector, `Initialize` deserializes the CA connection data +into the plugin's config object. The `MarkMonitorClient` itself is not built until the first +operation needs it — `CreateAndAuthenticateClientAsync()` builds (or adopts an injected) client once +and caches it for the lifetime of the plugin instance. Each client method authenticates or +re-authenticates itself lazily, so startup does not force an eager authentication call. + +```mermaid +sequenceDiagram + participant GW as AnyCA Gateway + participant Plugin as MarkMonitorCAPlugin + participant API as MarkMonitor API + + GW->>Plugin: Initialize(configProvider, certificateDataReader) + Plugin->>Plugin: Deserialize CAConnectionData into config + Note over Plugin: Client is NOT built yet (lazy) + GW->>Plugin: Ping() + Plugin->>Plugin: CreateAndAuthenticateClientAsync()
(builds & caches the client once) + Plugin->>API: POST /auth/v1/auth/authenticate
(X-API-KEY header + username/password) + API-->>Plugin: Bearer token (+ expiry) + Plugin->>API: GET /certs/v1/organization + API-->>Plugin: Organizations + Plugin-->>GW: Ping OK (auth works and at least one org exists) +``` + +--- + +### Synchronization + +Keyfactor Command periodically synchronizes its certificate inventory with MarkMonitor. The plugin +retrieves all orders for the account, page by page (looping until `MarkMonitorPage.TotalPages` is +reached), and feeds the issued certificates into Command's buffer. + +> **Note:** The current implementation performs a **full** listing on every sync — the `lastSync` +> timestamp and `fullSync` flag passed by the framework are not yet used to filter orders by date, +> and there is no configurable page size (the connector requests a fixed page size of 100). Orders +> that have no certificate yet are skipped for the current sync rather than aborting the page. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitorCAPlugin + participant API as MarkMonitor API + + CMD->>Plugin: Synchronize(buffer, lastSync, fullSync, cancelToken) + Plugin->>Plugin: CreateAndAuthenticateClientAsync() + + loop Retrieve one page at a time (until TotalPages) + Plugin->>API: GET /certs/v1/order?page=N&size=100 + API-->>Plugin: Page of order records + + loop For each order on the page + alt Order has no cert yet (e.g. CREATED / DIGI_NEEDS_CSR) + Plugin->>Plugin: Skip for this sync + else Order has a certificate + Plugin->>Plugin: Map MarkMonitor status → Keyfactor status + Plugin->>Plugin: Assemble end-entity + intermediate + root chain + Plugin->>CMD: Add AnyCAPluginCertificate to buffer + end + end + end + + Plugin->>CMD: CompleteAdding() + Plugin-->>CMD: Synchronization complete +``` + +For each imported certificate the plugin builds the full chain by concatenating the end-entity, +intermediate, and root certificates returned by MarkMonitor, and records a revocation date when the +order's `RevokeStatus` is `REVOKED`. (MarkMonitor does not expose a revocation *reason* on its order +records, so a reason is not populated on the imported record.) + +--- + +### Certificate Enrollment + +When a requester submits a certificate request through Keyfactor Command, the plugin translates it +into a MarkMonitor order. It resolves the organization, contact, and (optional) group; validates and +normalizes the CSR; and places the order. Because DCV/approval is required before issuance, an +accepted order typically comes back pending. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitorCAPlugin + participant API as MarkMonitor API + + CMD->>Plugin: Enroll(csr, subject, san, productInfo, format, enrollmentType) + Plugin->>Plugin: CreateAndAuthenticateClientAsync() + Plugin->>Plugin: Check dedup cache (org|product|subject|csr) + + alt Identical enrollment already in flight / just completed + Plugin-->>CMD: Await & return the original result (no duplicate order) + else New request + Plugin->>Plugin: Reserve dedup key BEFORE any real work + Plugin->>API: Resolve organization (name→GUID) & contact & group + Plugin->>Plugin: Parse CSR, reject ECC explicit-curve params,
derive RSA/ECC, convert to PEM + Plugin->>API: POST /certs/v1/order (product, org, contact, DCV method, CSR) + API-->>Plugin: Order created — GUID order ID + status + + alt enrollmentType == RenewOrReissue + Plugin->>API: Revoke prior cert (resolved from PriorCertSN) + end + + Plugin-->>CMD: EnrollmentResult (CARequestID = order ID, mapped status) + end +``` + +#### Enrollment inputs resolved from template parameters + +The plugin reads these product/template parameters (case-insensitive) when building the order — +falling back to defaults or a best-effort lookup when a value is missing or cannot be resolved: + +* **Organization** — resolved from the connector `OrgId` (name or GUID). Enrollment fails if it + cannot be resolved. +* **Contact** (`MarkmonitorContact`) — matched within the org's contacts by GUID, then email, then + `First Last` name. Falls back to the org's `ORGANIZATION_CONTACT` (or the first contact) if the + parameter is blank or unresolved (logged as a warning). +* **Group** (`MarkmonitorGroup`) — MarkMonitor groups are account-/tenant-wide, so this is matched by + GUID or exact (case-insensitive) name against `/auth/v1/group`. A blank or unresolved group is + simply omitted (best-effort; never fails the enrollment). +* **DCV method** (`DCVMethod`) — validated against `EMAIL`, `DNS_CNAME_TOKEN`, `HTTP_TOKEN`, + `DNS_TXT_TOKEN`; an invalid value logs a warning and falls back to `EMAIL`. +* **Additional emails** (`AdditionalEmails`), **comments** (`comments`), **locale** (`locale`), + **provider** (`provider`) — see the Template Enrollment Parameters table in + [README.md](README.md). + +#### Renewal / Reissue + +MarkMonitor exposes reissue and cancel endpoints (`PATCH /certs/v1/order/{id}/reissue`, +`PATCH /certs/v1/order/{id}/cancel`), but the enrollment path does **not** use them. A +`RenewOrReissue` enrollment always places a brand-new order and then revokes the prior certificate. +The prior certificate's serial number is supplied by the framework in +`productInfo.ProductParameters["PriorCertSN"]`; the plugin resolves it to a `CARequestID` via the +injected `ICertificateDataReader` and revokes it after the replacement has issued successfully. If +`PriorCertSN` is missing or cannot be resolved, the enrollment is treated as a plain new issuance and +no revoke is attempted — a failure to revoke the old certificate never fails delivery of the new one. + +```mermaid +flowchart TD + A([RenewOrReissue enrollment]) --> B[Place NEW MarkMonitor order] + B --> C{"PriorCertSN present
in product parameters?"} + C -- No --> D([Treat as new issuance — done]) + C -- Yes --> E["Resolve PriorCertSN → CARequestID
via ICertificateDataReader"] + E --> F{"Resolved and
OrgId configured?"} + F -- No --> G([Log warning — prior cert not revoked]) + F -- Yes --> H["Revoke prior order
(with org-ownership check)"] + H --> I([New cert delivered, prior revoked]) + D --> I + G --> I +``` + +--- + +### Revocation + +When a certificate is revoked in Keyfactor Command, the plugin first ensures an `OrgId` is +configured, then verifies the target order belongs to that organization before calling MarkMonitor's +revoke endpoint. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitorCAPlugin + participant API as MarkMonitor API + + CMD->>Plugin: Revoke(orderId, hexSerialNumber, revocationReason) + Plugin->>Plugin: EnsureOrgNameConfigured()
(refuse if OrgId is blank) + Plugin->>Plugin: Validate orderId is a GUID + Plugin->>API: Resolve configured OrgId → GUID + Plugin->>API: GET /certs/v1/order/{orderId} + + alt Order org != configured org (compared as parsed GUIDs) + Plugin-->>CMD: Error — refusing to revoke (different organization) + else Order belongs to configured org + Note over Plugin: revocationReason has no MarkMonitor field —
logged if non-default, not sent + Plugin->>API: PATCH /certs/v1/order/{orderId}/revoke + API-->>Plugin: Revocation confirmed + Plugin-->>CMD: REVOKED + end +``` + +**Ownership check:** the configured org and the order's org are compared as **parsed GUIDs**, not raw +strings, so an admin-configured `OrgId` in a non-canonical format (braces, no dashes, etc.) still +matches MarkMonitor's canonical serialization of the same GUID. + +**Reason codes:** MarkMonitor's revoke schema has no reason field, so the Keyfactor reason code +cannot be forwarded. A non-default reason is logged rather than silently dropped. + +--- + +### Connector Validation + +When an administrator saves or edits the CA connector, `ValidateCAConnectionInfo` checks the supplied +fields before the connector can be saved in an enabled state. + +```mermaid +flowchart TD + A([Save connector configuration]) --> B{"ApiKey, Username,
Password all present?"} + B -- Missing --> E([Validation error shown to administrator]) + B -- Present --> C{"BaseUrl starts with https://
(or blank → default)?"} + C -- Not https --> E + C -- OK --> D{"OrgId present?"} + D -- Missing --> E + D -- Present --> F([Connector saved]) +``` + +`ValidateCAConnectionInfo` performs field-level validation only (it does not place a live API call); +`Ping` is the live connectivity check — it authenticates and lists organizations. `ValidateProductInfo` +is intentionally a no-op: contact/group values are resolved (and gracefully defaulted) at enroll +time rather than validated at template-save time, to avoid coupling template configuration to +MarkMonitor's availability. + +--- + +### Order Status Mapping + +See the [Order Status Mapping table](README.md#order-status-mapping) in README.md for the full +MarkMonitor-status → Keyfactor-status table. The mapping is implemented in +`MarkMonitorClient.MarkMonitorCertificateStatusToCAStatus`. + +`CREATED` is deliberately mapped to `EXTERNALVALIDATION`, not `INITIALIZED`. The AnyCA Gateway REST +framework treats `INITIALIZED` as a hard enrollment failure, which caused freshly-created orders +(that were in fact accepted by MarkMonitor and simply awaiting DCV/issuance) to be reported as +failures. `EXTERNALVALIDATION` is what the framework treats as "accepted, still pending". + +### API Endpoint Reference + +See the [API Endpoint Reference table](README.md#api-endpoint-reference) in README.md for the full +list of MarkMonitor endpoints the plugin calls. + +> The cancel and reissue endpoints exist in the client but are not currently invoked by the +> `IAnyCAPlugin` operations (enrollment reissue is implemented as new-order-plus-revoke; see +> [Renewal / Reissue](#renewal--reissue)). diff --git a/README.md b/README.md index 16f2a3e..e55d6ae 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,492 @@ -# cpr-cagateway-template +

+ Markmonitor AnyCA Gateway REST Plugin +

-## Template for new CA Gateway integrations +

+ +Integration Status: pilot +Release +Issues +GitHub Downloads (all assets, all releases) +

-### Use this repository to create new integrations for new CA Gateway integration types. +

+ + + Support + + · + + Requirements + + · + + Installation + + · + + License + + · + + Related Integrations + +

+The MarkMonitor AnyCA Gateway REST plugin extends the certificate lifecycle capabilities of the +MarkMonitor SSL certificate service to Keyfactor Command via the Keyfactor AnyCA Gateway REST. It +implements `IAnyCAPlugin` and is loaded as a DLL extension by the AnyCA Gateway REST host process — +it is not a standalone service. The plugin supports the following capabilities: -1. [Use this repository](#using-the-repository) -1. [Update the integration-manifest.json](#updating-the-integration-manifest.json) -1. [Add Keyfactor Bootstrap Workflow (keyfactor-bootstrap-workflow.yml)](#add-bootstrap) -1. [Create required branches](#create-required-branches) -1. [Replace template files/folders](#replace-template-files-and-folders) -1. [Create initial prerelease](#create-initial-prerelease) ---- +* CA Synchronization: + * Downloads all certificate orders visible to the configured MarkMonitor organization and + imports the issued certificates (and their chains) into Keyfactor Command. + * Orders that have not yet produced a certificate are mapped to the appropriate pending/failed + status rather than imported as certificates. +* Certificate Enrollment for the SSL product types MarkMonitor exposes: + * Submits a new MarkMonitor certificate order per product type. + * A process-local dedup guard prevents Keyfactor Command retries from creating duplicate orders. +* Renewal / Reissue: + * MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a + `RenewOrReissue` enrollment places a **new** order and then revokes the prior certificate once + the replacement has been created successfully. +* Certificate Revocation: + * Revokes a previously issued certificate, with a cross-organization ownership check that refuses + to revoke an order belonging to a different organization than the one the CA connector is + configured for. -#### Using the repository -1. Select the ```Use this template``` button at the top of this page -1. Update the repository name following [these guidelines](https://keyfactorinc.sharepoint.com/sites/IntegrationWiki/SitePages/GitHub-Processes.aspx#repository-naming-conventions) - 1. All repositories must be in lower-case - 1. General pattern: company-product-type - 1. e.g. hashicorp-vault-orchestator -1. Click the ```Create repository``` button +MarkMonitor's SSL API is backed by DigiCert (the only certificate `provider` its API currently +supports), so issued certificates chain up to DigiCert roots. ---- +## Compatibility -#### Updating the integration-manifest.json +The Markmonitor AnyCA Gateway REST plugin is compatible with the Keyfactor AnyCA Gateway REST 25.5.0 and later. -*The following properties must be updated in the integration-manifest.json* +## Support +The Markmonitor AnyCA Gateway REST plugin is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com. -Clone the repository locally, use vsdev.io, or the GitHub online editor to update the file. +> To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab. -* "name": "Friendly name for the integration" - * This will be used in the readme file generation and catalog entries -* "description": "Brief description of the integration." - * This will be used in the readme file generation - * If the repository description is empty this value will be used for the repository description upon creating a release branch -* "release_dir": "PATH\\\TO\\\BINARY\\\RELEASE\\\OUTPUT\\\FOLDER" - * Path separators can be "\\\\" or "/" - * Be sure to specify the release folder name. This can be found by running a Release build and noting the output folder - * Example: "AzureAppGatewayOrchestrator\\bin\\Release" -* "gateway_framework": "" string denoting the required command gateway framework version ---- +## Requirements -#### Add Bootstrap -Add Keyfactor Bootstrap Workflow (keyfactor-bootstrap-workflow.yml). This can be copied directly from the workflow templates or through the Actions tab -* Directly: - 1. Create a file named ```.github\workflows\keyfactor-bootstrap-workflow.yml``` - 1. Copy the contents of [keyfactor/.github/workflow-templates/keyfactor-bootstrap-workflow.yml](https://raw.githubusercontent.com/Keyfactor/.github/main/workflow-templates/keyfactor-bootstrap-workflow.yml) into the file created in the previous step -* Actions tab: - 1. Navigate to the [Actions tab](./actions) in the new repository - 1. Click the ```New workflow``` button - 1. Find the ```Keyfactor Bootstrap Workflow``` and click the ```Configure``` button - 1. Click the ```Commit changes...``` button on this screen and the next to add the bootstrap workflow to the main branch - -A new build will run the tasks of a *Push* trigger on the main branch +- A MarkMonitor **API Key** (contact MarkMonitor support to obtain one). +- A MarkMonitor **service account** (username and password) with permission to create certificate + orders. +- The **organization** name or ID (GUID) the certificates will be ordered under. +- Keyfactor Command >= v12.0.0. +- AnyCA Gateway REST >= v25.5.0. +- Network connectivity from the AnyCA Gateway host to the MarkMonitor API base URL, and trust of the + DigiCert issuing CA chain on both the gateway host and the Command server (see + [Gateway Registration](#gateway-registration)). -*Ensure there are no errors during the workflow run in the Actions tab.* +## Installation ---- +1. Install the AnyCA Gateway REST per the [official Keyfactor documentation](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/InstallIntroduction.htm). -#### Create required branches -1. Create a release branch from main: release-1.0 -1. Create a dev branch from the starting with the devops id in the format ab#\, e.g. ab#53535. - 1. For the cleanest pull request merge, create the dev branch from the release branch. - 1. Optionally, add a suffix to the branch name indicating initial release. e.g. ab#53535-initial-release +2. On the server hosting the AnyCA Gateway REST, download and unzip the latest [Markmonitor AnyCA Gateway REST plugin](https://github.com/Keyfactor/markmonitor-caplugin/releases/latest) from GitHub. ---- +3. Copy the unzipped directory (usually called `net8.0` or `net10.0`) to the Extensions directory: -#### Replace template files and folders -1. Replace the contents of readme_source.md -1. Create a CHANGELOG.md file in the root of the repository indicating ```1.0: Initial release``` -1. Replace the SampleOrchestratorExtension.sln solution file and SampleOrchestratorExtension folder with your new orchestrator dotnet solution -1. Push your updates to the dev branch (ab#xxxxx) + ```shell + Depending on your AnyCA Gateway REST version, copy the unzipped directory to one of the following locations: + Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net8.0\Extensions + Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net10.0\Extensions + ``` ---- + > The directory containing the Markmonitor AnyCA Gateway REST plugin DLLs (`net8.0` or `net10.0`) can be named anything, as long as it is unique within the `Extensions` directory. +4. Restart the AnyCA Gateway REST service. -#### Create initial prerelease -1. Create a pull request from the dev branch to the release-1.0 branch +5. Navigate to the AnyCA Gateway REST portal and verify that the Gateway recognizes the Markmonitor plugin by hovering over the ⓘ symbol to the right of the Gateway on the top left of the portal. +## Configuration ----- +1. Follow the [official AnyCA Gateway REST documentation](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCA-Gateway.htm) to define a new Certificate Authority, and use the notes below to configure the **Gateway Registration** and **CA Connection** tabs: -When the repository is ready for SE Demo, change the following property: -* "status": "pilot" + * **Gateway Registration** -When the integration has been approved by Support and Delivery teams, change the following property: -* "status": "production" + In order to enroll for certificates the Keyfactor Command server must trust the issuing CA chain. + MarkMonitor's default issuing CA (`provider`) is **DigiCert** — download and import the appropriate + certificate chain from to the AnyCA + Gateway host and Command server. + + Once the necessary files are copied to the appropriate locations and the AnyCA Gateway REST is up and + running, navigate to the AnyCA Gateway REST portal and configure the CA. + + ### Using file path for issuing CA certificate + ![gateway_registration_local_file.png](docsource/images/gateway_registration_local_file.png) + + ### Using Keyfactor Command certificate store for issuing CA certificate + > **⚠️ Warning:** The cert store must already exist in Keyfactor Command. + + ![gateway_registration_store.png](docsource/images/gateway_registration_store.png) -If the repository is ready to be published in the public catalog, the following properties must be updated: -* "update_catalog": true -* "link_github": true + * **CA Connection** + + Populate using the configuration fields collected in the [requirements](#requirements) section. + + * **ApiKey** - The API Key for the MarkMonitor API + * **Username** - Username for the MarkMonitor API service account + * **Password** - Password for the MarkMonitor API service account + * **BaseUrl** - The Base URL for the MarkMonitor API - Usually either https://api.markmonitor.com + * **OrgId** - The name of the MarkMonitor Organization to use for the API calls (ex: MarkMonitor). You can also use the Organization ID in GUID format. + * **Enabled** - Flag to Enable or Disable gateway functionality. Disabling is primarily used to allow creation of the CA prior to configuration information being available. + * **TimeoutSeconds** - The HTTP request timeout, in seconds, for calls to the MarkMonitor API (1-120). Default is 120. + * **PageSize** - The number of certificate orders requested per page during synchronization (1-500). Default is 100. + * **ForceCompleteSync** - When true, bypasses the skip-unchanged optimization and re-emits every order on every synchronization. Default is false. + * **PickupRetries** - How many times to poll a freshly-created order for issuance before returning it in its still-pending state (0-20). 0 disables polling. Default is 5. + * **PickupDelaySeconds** - The delay, in seconds, between issuance pickup polls (0-60). Default is 10. + +2. A certificate template must be created in Keyfactor Command for each MarkMonitor product type you +want to enroll. One template is required per product type (see [Product IDs](#product-ids)). Below is +an example of a template for a GeoTrust DV SSL certificate. For more on certificate product types, +contact your MarkMonitor administrator or support. + +![gateway_template.png](docsource/images/gateway_template.png) + +3. Follow the [official Keyfactor documentation](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCA-Keyfactor.htm) to add each defined Certificate Authority to Keyfactor Command and import the newly defined Certificate Templates. + +4. In Keyfactor Command (v12.3+), for each imported Certificate Template, follow the [official documentation](https://software.keyfactor.com/Core-OnPrem/Current/Content/ReferenceGuide/Configuring%20Template%20Options.htm) to define enrollment fields for each of the following parameters: + + * **AdditionalEmails** - List of 0 or more comma separated email addresses to send the certificate to via email after generation. + * **MarkmonitorGroup** - The name or GUID of a Markmonitor group to use for the certificate request. + * **MarkmonitorContact** - The name or GUID of a Markmonitor contact to use for the certificate request. Will use default Markmonitor organization contact if not specified. + * **DCVMethod** - The method to use for Domain Control Validation (DCV). Valid values are EMAIL, DNS_CNAME_TOKEN, HTTP_TOKEN, DNS_TXT_TOKEN. Default is EMAIL. + * **comments** - Comments to attach to the MarkMonitor order. Default is "Requested via Keyfactor Command". + * **locale** - Locale to use for the MarkMonitor order. Default is "en". + * **provider** - The certificate provider to use for the order. Default is "DIGICERT" (currently the only provider MarkMonitor's API supports). + * **RenewalWindowDays** - For a RenewOrReissue enrollment, how many days before its expiration a prior certificate must be within before it is revoked after being replaced. Outside this window, the prior certificate is left unrevoked and the request is treated like a plain new issuance. Default is 90. + +## MarkMonitor API Setup + +MarkMonitor requires **two** credentials that are used together (there is no OAuth mode): + +1. **API Key** — sent as the `X-API-KEY` header on the authentication request. Enter it in the + `ApiKey` connector field (masked in the Command UI). +2. **Service-account username and password** — POSTed to `/auth/v1/auth/authenticate`, which returns + a short-lived bearer token used on all subsequent calls. Enter them in the `Username` and + `Password` connector fields (the password is masked in the UI). + +Contact your MarkMonitor administrator to provision the API key and a service account with order +permissions, and to confirm the correct API base URL and organization name/ID for your environment. + +## CA Connection Configuration + +The following fields are presented in the AnyCA Gateway REST portal (and the Keyfactor Command +Management Portal) when creating or editing the MarkMonitor CA connector. All fields except `Enabled` +must be provided before the connector can be saved in an enabled state. + +![gateway_ca_configuration.png](docsource/images/gateway_ca_configuration.png) + +| Field | Required / Optional | Masked | Default | Description | +|---|---|---|---|---| +| `ApiKey` | Required | Yes | *(none)* | The MarkMonitor API key, sent as the `X-API-KEY` header when authenticating. | +| `Username` | Required | No | *(none)* | Username for the MarkMonitor API service account. | +| `Password` | Required | Yes | *(none)* | Password for the MarkMonitor API service account. | +| `BaseUrl` | Required | No | `https://api.markmonitor.com` | The MarkMonitor API base URL. Must start with `https://` — credentials and the bearer token are sent to it. | +| `OrgId` | Required | No | *(none)* | The MarkMonitor organization to use for API calls. Accepts either the organization **name** (e.g. `MarkMonitor`) or its **ID in GUID format**. Used to scope enrollment and to verify ownership on revoke. | +| `Enabled` | Optional | No | `true` | Enables or disables gateway functionality. Disable to allow the CA to be created before configuration information is available. | +| `TimeoutSeconds` | Optional | No | `120` | The HTTP request timeout, in seconds, for calls to the MarkMonitor API. Clamped to 1-120. | +| `PageSize` | Optional | No | `100` | The number of certificate orders requested per page during synchronization. Clamped to 1-500. | +| `ForceCompleteSync` | Optional | No | `false` | When `true`, bypasses the skip-unchanged synchronization optimization and re-emits every order on every sync. | +| `PickupRetries` | Optional | No | `5` | How many times `Enroll` polls a freshly-created order for issuance before returning it in its still-pending state. `0` disables polling. Clamped to 0-20. | +| `PickupDelaySeconds` | Optional | No | `10` | The delay, in seconds, between issuance pickup polls. Clamped to 0-60. | + +> **Note:** Credentials are stored in Keyfactor Command's encrypted gateway configuration. `ApiKey` +> and `Password` are masked in the UI and are never written to logs by the plugin. + +## Template Enrollment Parameters + +Custom enrollment parameters can be added to templates in Keyfactor Command after they have been +imported from the AnyCA Gateway. **All parameters are optional** and are read case-insensitively at +enrollment time. + +![template_enrollment_params.png](docsource/images/template_enrollment_params.png) + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `AdditionalEmails` | String | *(empty)* | Zero or more comma-separated email addresses that MarkMonitor will send the issued certificate to. Spaces are also treated as separators. | +| `MarkmonitorGroup` | String | *(none)* | The name or GUID of a MarkMonitor group to associate with the order. Matched by GUID or exact (case-insensitive) name against the account-wide group list. A blank or unresolved value is omitted (best-effort). | +| `MarkmonitorContact` | String | *(org default)* | The GUID, email, or `First Last` name of a MarkMonitor contact within the organization. Falls back to the organization's default contact if not specified or not resolvable. | +| `DCVMethod` | String | `EMAIL` | Domain Control Validation method. Valid values: `EMAIL`, `DNS_CNAME_TOKEN`, `HTTP_TOKEN`, `DNS_TXT_TOKEN`. An invalid value logs a warning and falls back to `EMAIL`. | +| `comments` | String | `Requested via Keyfactor Command` | Free-text comments attached to the MarkMonitor order. | +| `locale` | String | `en` | Locale for the MarkMonitor order. | +| `provider` | String | `DIGICERT` | The certificate provider for the order. `DIGICERT` is currently the only provider the MarkMonitor API supports. | +| `RenewalWindowDays` | Number | `90` | For a `RenewOrReissue` enrollment, how many days before its expiration the prior certificate must be within before it's revoked after the replacement issues. Outside that window, the prior certificate is left unrevoked and the request is treated like a plain new issuance. An invalid (non-numeric or non-positive) value falls back to the default. | + +> **Note on DCV:** The plugin passes the selected `DCVMethod` to MarkMonitor but does not itself +> automate DNS/HTTP token publication. For `EMAIL` (the default), MarkMonitor falls back to the +> domain/organization's registered DCV contacts; the plugin sends an empty `dcvEmails` list. + +## Product IDs + +`GetProductIds()` returns the names of the `CertOrderTypes` enum. The **Product ID** column is the +value Keyfactor Command sees and stores; the plugin maps it to the **MarkMonitor cert type** string +(the enum's `[Description]`) when placing an order. Adding a new MarkMonitor product means adding an +enum member with the matching `[Description]` — not editing a separate list. + +| Product ID (Command) | MarkMonitor cert type | Typical product family | +|---|---|---| +| `SslOvBasic` | `SSL_OV_BASIC` | OV SSL (basic) | +| `SslEvBasic` | `SSL_EV_BASIC` | EV SSL (basic) | +| `SslDvGeotrust` | `SSL_DV_GEOTRUST` | GeoTrust DV SSL | +| `SslDvThawte` | `SSL_DV_THAWTE` | Thawte DV SSL | +| `SslOvThawteWebserver` | `SSL_OV_THAWTE_WEBSERVER` | Thawte OV Web Server SSL | +| `SslEvThawteWebserver` | `SSL_EV_THAWTE_WEBSERVER` | Thawte EV Web Server SSL | +| `SslOvGeotrustTruebizid` | `SSL_OV_GEOTRUST_TRUEBIZID` | GeoTrust OV True BusinessID SSL | +| `SslEvGeotrustTruebizid` | `SSL_EV_GEOTRUST_TRUEBIZID` | GeoTrust EV True BusinessID SSL | +| `SslOvSecuresite` | `SSL_OV_SECURESITE` | DigiCert OV Secure Site SSL | +| `SslEvSecuresite` | `SSL_EV_SECURESITE` | DigiCert EV Secure Site SSL | +| `SslOvSecuresitePro` | `SSL_OV_SECURESITE_PRO` | DigiCert OV Secure Site Pro SSL | +| `SslEvSecuresitePro` | `SSL_EV_SECURESITE_PRO` | DigiCert EV Secure Site Pro SSL | + +> **Note:** The "typical product family" column is descriptive. Which product types your MarkMonitor +> account may actually order — and any per-product required fields — depend on your account's +> entitlements. Confirm availability with your MarkMonitor administrator. + +## How It Works + +This section describes, at a high level, how the plugin connects Keyfactor Command's certificate +lifecycle operations to the MarkMonitor SSL certificate service. + +### Component Overview + +``` +┌─────────────────────────────────────────────────────────┐ +│ Keyfactor Command │ +│ │ +│ Certificate Enrollment · Revocation · Sync Jobs │ +└────────────────────────────┬─────────────────────────────┘ + │ + AnyCA Gateway REST + (plugin host process) + │ +┌────────────────────────────▼─────────────────────────────┐ +│ The MarkMonitor plugin │ +│ │ +│ Translates Keyfactor operations into MarkMonitor API │ +│ calls and maps responses back to Command's data model. │ +└────────────────────────────┬─────────────────────────────┘ + │ HTTPS · Bearer token + X-API-KEY + │ +┌────────────────────────────▼─────────────────────────────┐ +│ MarkMonitor REST API (DigiCert) │ +│ │ +│ /auth/v1/auth/authenticate /certs/v1/order │ +│ /certs/v1/organization /auth/v1/group │ +└──────────────────────────────────────────────────────────┘ +``` + +### Synchronization + +Keyfactor Command periodically synchronizes its certificate inventory with MarkMonitor. The plugin +retrieves all certificate orders visible to the configured organization, page by page, and imports +issued certificates — along with their full certificate chain — into Command. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Start synchronization + Plugin->>API: Authenticate with MarkMonitor + + loop Retrieve one page of orders at a time + Plugin->>API: List certificate orders + API-->>Plugin: Page of order records + + loop For each order on the page + alt Order has no certificate yet + Plugin->>Plugin: Skip for this sync + else Order has a certificate + Plugin->>Plugin: Map the MarkMonitor status to a Keyfactor status + alt Unchanged since Command's last known status (and not forced) + Plugin->>Plugin: Skip re-emission + else New or changed + Plugin->>Plugin: Assemble the full certificate chain + Plugin->>CMD: Add certificate to Command's inventory + end + end + end + end + + Plugin-->>CMD: Synchronization complete (emitted / skipped-unchanged / errored counts) +``` + +> A record that fails to process is logged, counted, and skipped rather than aborting the sync - but +> the sync aborts outright if more than 25% of records fail once at least 50 have been observed. + +> The current implementation always performs a full listing of orders on each sync, rather than only +> retrieving certificates that changed since the last sync - `PageSize` optimizes the *mitigation*, not +> the listing itself: each order is compared against what Command already has for that request ID, and +> skipped (not re-emitted) when the status is unchanged, unless `ForceCompleteSync` is enabled or +> Command requests a full sync. Orders that have not yet produced a certificate are simply skipped for +> that sync rather than treated as an error. A record that fails to process (bad status string, bad +> date, unexpected null) is logged and skipped rather than aborting the sync - but if more than 25% of +> records fail once at least 50 have been observed, the sync aborts outright rather than reporting a +> quietly near-empty "success". + +### Certificate Enrollment (including Renewal / Reissue) + +When a requester submits a certificate request through Keyfactor Command, the plugin translates it +into a MarkMonitor order: it resolves the organization, contact, and (optional) group; validates and +normalizes the CSR; and submits the order. MarkMonitor never issues synchronously from the +create-order call - a newly submitted order always comes back pending (typically `CREATED`), since +Domain Control Validation (and, in some environments, manual approval) is required first. For a +product whose DCV/approval resolves quickly, the plugin polls the order for up to `PickupRetries` +attempts (every `PickupDelaySeconds`) before returning, so Command can get the issued certificate +back from the enroll call itself rather than always waiting for the next sync; `PickupRetries=0` +disables this and restores the original always-returns-pending behavior. Each poll is a single +attempt, but if MarkMonitor is slow to respond (rather than erroring) it can still take up to +`TimeoutSeconds` per attempt - size any upstream timeout around `PickupRetries * (PickupDelaySeconds ++ TimeoutSeconds)`, the real worst case, not just `PickupRetries * PickupDelaySeconds`. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Submit certificate request + Plugin->>API: Authenticate with MarkMonitor + Plugin->>Plugin: Check for a duplicate in-flight request + + alt An identical request was already submitted / just completed + Plugin-->>CMD: Return the original result (no duplicate order placed) + else New request + Plugin->>API: Resolve organization, contact, and group + Plugin->>Plugin: Validate and normalize the CSR + Plugin->>API: Submit the certificate order + API-->>Plugin: Order accepted — order ID and status + + opt Not yet issued and PickupRetries > 0 + loop Up to PickupRetries times, every PickupDelaySeconds + Plugin->>API: Poll the order + API-->>Plugin: Current status + end + end + + alt Renewal/Reissue request + Plugin->>API: Revoke the certificate being replaced + end + + Plugin-->>CMD: Enrollment result (order ID, current status) + end +``` + +> A concurrent duplicate request folded into this same in-flight reservation (the "identical request +> already submitted" branch above) receives the polled result too, not just the original pending +> status - the fold happens after polling completes, not before. + +MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a Renewal/Reissue +request always places a brand-new order. Once the replacement certificate has been created +successfully, the plugin revokes the certificate it is replacing — but only if that certificate is +within its `RenewalWindowDays` template parameter (default 90) of expiring. If the certificate being +replaced can't be identified, or still has substantial life left (outside the renewal window), the +request is simply treated as a new issuance and the prior certificate is left alone — a failure to +revoke the old certificate never blocks delivery of the new one either. + +### Revocation + +When a certificate is revoked in Keyfactor Command, the plugin confirms that the target order belongs +to the organization the CA connector is configured for before calling MarkMonitor's revoke operation. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Revoke certificate + Plugin->>API: Authenticate with MarkMonitor + Plugin->>API: Look up the order's owning organization + + alt Order belongs to a different organization + Plugin-->>CMD: Error — refusing to revoke (different organization) + else Order belongs to the configured organization + Plugin->>API: Revoke the order + API-->>Plugin: Revocation confirmed + Plugin-->>CMD: Certificate marked revoked + end +``` + +> MarkMonitor's revoke operation has no field for a revocation reason code, so the reason supplied by +> Keyfactor Command cannot be forwarded to MarkMonitor. + +### Connector Validation + +When an administrator saves or edits the CA connector, the plugin checks the supplied configuration +before the connector can be saved in an enabled state. + +```mermaid +flowchart TD + A([Save connector configuration]) --> B{"API Key, Username,
Password all present?"} + B -- Missing --> E([Validation error shown to administrator]) + B -- Present --> C{"Base URL starts with https://
(or blank → default)?"} + C -- Not https --> E + C -- OK --> D{"Organization present?"} + D -- Missing --> E + D -- Present --> N{"Enabled?"} + N -- No --> F([Connector saved]) + N -- Yes --> G{"Authenticate with the
submitted credentials"} + G -- Fails --> E + G -- Succeeds --> H{"At least one organization
visible?"} + H -- No / fails --> E + H -- Yes --> F +``` + +After the field checks above pass - and only if the connector is being saved enabled - the plugin +also places a live call to MarkMonitor: it authenticates with the submitted (not yet saved) +credentials and confirms at least one organization is visible, using a transient client built from +exactly what's about to be saved — never the connector's already-cached client, which could be +validating stale credentials. Saving with `Enabled` set to `false` skips this live check entirely, +preserving that field's own documented purpose: creating the connector before real credentials are +available. A failure at any step (parsing the submitted configuration, authenticating, or listing +organizations) is summarized rather than forwarding the raw HTTP response or exception detail, which +could otherwise leak transport-layer detail to the UI. + +### Order Status Mapping + +MarkMonitor order statuses are mapped to Keyfactor statuses as follows: + +| MarkMonitor order status | Keyfactor status | +|---|---| +| `DIGI_PENDING`, `DIGI_PROCESSING`, `DIGI_REISSUE_PENDING`, `DIGI_WAITING_PICKUP`, `REISSUE_PENDING`, `DIGI_NEEDS_APPROVAL`, `REISSUE_REQUEST_PENDING` | `INPROCESS` | +| `CREATED` | `EXTERNALVALIDATION` (accepted, awaiting DCV/issuance) | +| `DIGI_ISSUED` | `GENERATED` (issued) | +| `DIGI_REVOKED` | `REVOKED` | +| `DIGI_FAILED`, `DIGI_REISSUE_FAILED` | `FAILED` | +| `DIGI_CANCELED`, `DIGI_REJECTED`, `DIGI_EXPIRED`, `DIGI_NEEDS_CSR` | `CANCELLED` | +| *(null/empty or unrecognized status)* | `FAILED` | + +> A freshly-submitted order (`CREATED`) is deliberately mapped to `EXTERNALVALIDATION` rather than a +> failure status — this means the order was accepted by MarkMonitor and is simply awaiting DCV or +> issuance. Once the order reaches `DIGI_ISSUED`, the next synchronization imports the certificate. + +### API Endpoint Reference + +The plugin calls the following MarkMonitor API endpoints. This is useful for firewall and network +connectivity planning. + +| Operation | MarkMonitor API endpoint | +|---|---| +| Authenticate / obtain bearer token | `POST /auth/v1/auth/authenticate` (with `X-API-KEY` header) | +| List certificate orders (sync) | `GET /certs/v1/order` (paginated via `page`/`size`) | +| Get a single order | `GET /certs/v1/order/{orderId}` | +| Place a new order (enroll) | `POST /certs/v1/order` | +| Revoke a certificate | `PATCH /certs/v1/order/{orderId}/revoke` | +| Cancel an order | `PATCH /certs/v1/order/{orderId}/cancel` | +| Reissue a certificate | `PATCH /certs/v1/order/{orderId}/reissue` | +| List organizations | `GET /certs/v1/organization` (paginated) | +| Get an organization | `GET /certs/v1/organization/{orgId}` | +| List groups | `GET /auth/v1/group` (paginated) | + +## License + +Apache License 2.0, see [LICENSE](LICENSE). + +## Related Integrations + +See all [Keyfactor Any CA Gateways (REST)](https://github.com/orgs/Keyfactor/repositories?q=anycagateway). diff --git a/TestConsole/Helpers/CSRGenerator.cs b/TestConsole/Helpers/CSRGenerator.cs index 152cb22..37e2afa 100644 --- a/TestConsole/Helpers/CSRGenerator.cs +++ b/TestConsole/Helpers/CSRGenerator.cs @@ -117,7 +117,12 @@ private static AsymmetricCipherKeyPair GenerateEccKeyPair() { var keyPairGen = new ECKeyPairGenerator(); var ecSpec = SecNamedCurves.GetByName("secp256r1"); // P-256 curve - var ecDomainParams = new ECDomainParameters(ecSpec.Curve, ecSpec.G, ecSpec.N, ecSpec.H); + // ECNamedDomainParameters (not plain ECDomainParameters) is required so the CSR's + // SubjectPublicKeyInfo references the named curve by OID rather than spelling out explicit + // curve parameters (prime/coefficients/base point) - CA/Browser Forum baseline requirements + // disallow explicit EC parameters for publicly-trusted certs, and DigiCert silently rejects + // such a CSR (order fails almost instantly, with no reason surfaced via MarkMonitor's API). + var ecDomainParams = new ECNamedDomainParameters(SecObjectIdentifiers.SecP256r1, ecSpec); var keyGenParams = new ECKeyGenerationParameters(ecDomainParams, new SecureRandom(new CryptoApiRandomGenerator())); keyPairGen.Init(keyGenParams); diff --git a/TestConsole/Program.cs b/TestConsole/Program.cs index 14e4782..3e40f14 100644 --- a/TestConsole/Program.cs +++ b/TestConsole/Program.cs @@ -1,5 +1,6 @@ // See https://aka.ms/new-console-template for more information +using Keyfactor.Extensions.CAPlugin.MarkMonitor; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; using Keyfactor.PKI.PEM; @@ -55,79 +56,51 @@ private static async Task Main(string[] args) rsaCsrs.AddRange(eccCsrs); // rsaCsrs.AddRange(dsaCsrs); - var orders = new List(); - foreach (var (csr, privateKey, keyPair) in rsaCsrs) + // Every order this console creates is a real, billable MarkMonitor order. By default we + // clean each one up (cancel, falling back to revoke) right after creating it so repeated + // test runs don't rack up charges. Set MARKMONITOR_SKIP_CLEANUP=true to opt out and leave + // created orders in place (e.g. to inspect them manually in the MarkMonitor portal). + var skipCleanup = IsTruthy(Environment.GetEnvironmentVariable("MARKMONITOR_SKIP_CLEANUP")); + if (skipCleanup) + Console.WriteLine( + "MARKMONITOR_SKIP_CLEANUP is set - orders created by this run will NOT be cancelled/revoked automatically."); + + var orders = new List(); + foreach (var (csr, _, _) in rsaCsrs) { var csrPem = PemUtilities.DERToPEM(csr.GetEncoded(), PemUtilities.PemObjectType.CertRequest); var commonName = csr.GetCertificationRequestInfo().Subject.GetValueList()[0]; - var privateKeyPem = PemUtilities.DERToPEM(privateKey, PemUtilities.PemObjectType.PrivateKey); var randomNumberOfEmails = new Random().Next(1, 4); var additionalEmails = await EmailAddressGenerator.GenerateRandomEmailsAsync(randomNumberOfEmails); - var orgId = orgs[0].Id; - var orgGuid = Guid.Parse(orgId); - var orgContact = orgs[0].Contacts[0]; - var contactId = orgContact.Id; - var signatureAlgorithm = csr.SignatureAlgorithm.Algorithm.Id; - var requestAlgorithm = signatureAlgorithm switch - { - //check if algorithm is RSA or ECC - "1.2.840.113549.1.1.11" => AlgorithmTypes.Rsa.GetDescription(), - "1.2.840.10045.4.3.1" or "1.2.840.10045.4.3.2" or "1.2.840.10045.4.3.3" or "1.2.840.10045.4.3.4" - or "1.2.840.10045.2.1" => AlgorithmTypes.Ecc.GetDescription(), - // "2.16.840.1.101.3.4.3.1" or "2.16.840.1.101.3.4.3.2" or "2.16.840.1.101.3.4.3.3" - // or "2.16.840.1.101.3.4.3.4" => AlgorithmTypes.Dsa.GetDescription(), //DSA not supported - _ => throw new Exception($"Invalid signature algorithm {signatureAlgorithm}") - }; + Console.WriteLine("Creating certificate order via EnrollCertificateAsync..."); - var orderContacts = new List - { - new() - { - Id = contactId, - ContactTypes = orgContact.ContactTypes - } - }; + var client = new MarkMonitorClient(baseUrl, apiToken, username, password); + await client.AuthenticateAsync(); + Console.WriteLine("Authenticated."); - var dcvEmails = new List + var config = new MarkMonitorConfig { - new() - { - Email = "justin.mack@markmonitor.com", - DnsName = "mmcertdomain.com", - EmailDomain = "markmonitor.com" - } + ApiKey = apiToken, + ApiUsername = username, + ApiPassword = password, + BaseUrl = baseUrl, + OrgName = orgs[0].Name, + Enabled = true }; - var certOrder = new MarkMonitorCreateOrderRequest + var productParams = new Dictionary { - AdditionalEmails = additionalEmails, - SkipPrice = true, - OrganizationId = orgGuid, - // GroupId = null, - // Contacts = orderContacts, - Comments = "Requested via Keyfactor Command", - CertType = CertOrderTypes.SslDvGeotrust.GetDescription(), - Locale = "en", - Provider = "DIGICERT", - Cert = new MarkMonitorOrderRequestCert - { - CommonName = commonName, - Csr = csrPem, - // ServerPlatform = CertServerPlatforms.Default.GetDescription(), - DcvMethod = "EMAIL", - DcvEmails = new List(), - // Provider = "DIGICERT", - AlgorithmHash = requestAlgorithm - } + ["additionalEmails"] = string.Join(",", additionalEmails) }; - Console.WriteLine("Creating certificate order..."); - var client = new MarkMonitorClient(baseUrl, apiToken, username, password); - await client.AuthenticateAsync(); - Console.WriteLine("Authenticated."); - var order = await client.CreateCertificateOrder(certOrder); - Console.WriteLine($"Created certificate order: {order.Id}"); - orders.Add(order); + var enrollResult = await client.EnrollCertificateAsync(csrPem, $"CN={commonName}", + new Dictionary(), CertOrderTypes.SslDvGeotrust.ToString(), productParams, config); + + if (enrollResult == null) throw new Exception("EnrollCertificateAsync returned null"); + Console.WriteLine($"Created certificate order: {enrollResult.CARequestID} (status: {enrollResult.Status})"); + orders.Add(enrollResult.CARequestID); + + if (!skipCleanup) await CleanUpOrderAsync(client, enrollResult.CARequestID, config.OrgName); } Console.WriteLine("Tests completed successfully with orders: " + orders.Count); @@ -331,6 +304,38 @@ private static async Task Main(string[] args) // } // } // + /// + /// Best-effort cleanup for a real, billable MarkMonitor order this console just created. Tries + /// cancel first (orders created here are freshly submitted and never reach an issued state + /// before this runs), falling back to revoke in case the order somehow issued instantly. A + /// cleanup failure is logged, not thrown - it shouldn't fail the whole test run, but it should + /// be visible so the order can be cleaned up manually in the MarkMonitor portal. + /// + private static async Task CleanUpOrderAsync(MarkMonitorClient client, string orderId, string orgName) + { + try + { + await client.CancelCertificateAsync(orderId, orgName); + Console.WriteLine($"Cancelled order {orderId}."); + } + catch (Exception cancelEx) + { + try + { + await client.RevokeCertificateAsync(orderId, orgName); + Console.WriteLine($"Order {orderId} could not be cancelled ({cancelEx.Message}); revoked it instead."); + } + catch (Exception revokeEx) + { + Console.WriteLine( + $"WARNING: could not cancel or revoke order {orderId} - it may still incur charges and should be cleaned up manually. Cancel error: {cancelEx.Message}; Revoke error: {revokeEx.Message}"); + } + } + } + + private static bool IsTruthy(string? value) => + value is not null && (value.Equals("true", StringComparison.OrdinalIgnoreCase) || value == "1"); + private static async Task> TestListCertificateOrders(string baseUrl, string apiToken, string username, string password) { @@ -361,7 +366,7 @@ private static async Task> TestListOrgs(st foreach (var org in orgs) { Console.WriteLine($"Org: {org.Id} - {org.Provider} - {org.ProviderId}"); - foreach (var validation in org.Validations) + foreach (var validation in org.Validations ?? new List()) Console.WriteLine($"Validation: {validation.Name} - {validation.Type}"); } diff --git a/TestConsole/README.md b/TestConsole/README.md new file mode 100644 index 0000000..130cdda --- /dev/null +++ b/TestConsole/README.md @@ -0,0 +1,40 @@ +# TestConsole + +A manual integration-test console app that exercises `MarkMonitorClient`/`MarkMonitorCAPlugin` directly +against a live MarkMonitor API (sandbox or production). This is not a unit test suite - it's a +scripted smoke test you run by hand, and it makes real API calls that create real, billable orders. + +## Required environment variables + +``` +MARKMONITOR_BASE_URL +MARKMONITOR_API_TOKEN +MARKMONITOR_USERNAME +MARKMONITOR_PASSWORD +``` + +A local `.env` (gitignored) can hold these; source it before running, e.g.: + +```shell +set -a && source .env && set +a && dotnet run --project TestConsole +``` + +## Order cleanup + +Every enrollment this console performs creates a real MarkMonitor order, which is billable. **By +default, each order is cancelled (falling back to revoke if cancel fails) immediately after it's +created**, so repeated runs don't accumulate charges. + +To opt out and leave created orders in place instead - e.g. to inspect them manually in the +MarkMonitor portal, or to test something downstream of order creation - set: + +``` +MARKMONITOR_SKIP_CLEANUP=true +``` + +When this is set, the console prints a warning at startup and leaves every order it creates +untouched. **Anything created during such a run is your responsibility to clean up manually.** + +A cleanup failure (cancel and revoke both fail) does not fail the test run - it's logged as a +warning so you know to clean that specific order up by hand, since letting one cleanup failure +abort the whole run wouldn't help the orders created before it either. diff --git a/TestConsole/TestConsole.csproj b/TestConsole/TestConsole.csproj index 50b490a..eceea09 100644 --- a/TestConsole/TestConsole.csproj +++ b/TestConsole/TestConsole.csproj @@ -2,12 +2,12 @@ Exe - net6.0 + net8.0;net10.0 enable enable - + diff --git a/TestConsole/lib/MarkmonitorDigiCACert.pem b/TestConsole/lib/MarkmonitorDigiCACert.pem new file mode 100644 index 0000000..3f6b5f5 --- /dev/null +++ b/TestConsole/lib/MarkmonitorDigiCACert.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEjTCCA3WgAwIBAgIQDQd4KhM/xvmlcpbhMf/ReTANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xNzExMDIxMjIzMzdaFw0yNzExMDIxMjIzMzdaMGAxCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xHzAdBgNVBAMTFkdlb1RydXN0IFRMUyBSU0EgQ0EgRzEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC+F+jsvikKy/65LWEx/TMkCDIuWegh1Ngwvm4Q +yISgP7oU5d79eoySG3vOhC3w/3jEMuipoH1fBtp7m0tTpsYbAhch4XA7rfuD6whU +gajeErLVxoiWMPkC/DnUvbgi74BJmdBiuGHQSd7LwsuXpTEGG9fYXcbTVN5SATYq +DfbexbYxTMwVJWoVb6lrBEgM3gBBqiiAiy800xu1Nq07JdCIQkBsNpFtZbIZhsDS +fzlGWP4wEmBQ3O67c+ZXkFr2DcrXBEtHam80Gp2SNhou2U5U7UesDL/xgLK6/0d7 +6TnEVMSUVJkZ8VeZr+IUIlvoLrtjLbqugb0T3OYXW+CQU0kBAgMBAAGjggFAMIIB +PDAdBgNVHQ4EFgQUlE/UXYvkpOKmgP792PkA76O+AlcwHwYDVR0jBBgwFoAUTiJU +IBiV5uNu5g/6+rkS7QYXjzkwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsG +AQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMDQGCCsGAQUFBwEB +BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEIGA1Ud +HwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEds +b2JhbFJvb3RHMi5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEW +HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQELBQADggEB +AIIcBDqC6cWpyGUSXAjjAcYwsK4iiGF7KweG97i1RJz1kwZhRoo6orU1JtBYnjzB +c4+/sXmnHJk3mlPyL1xuIAt9sMeC7+vreRIF5wFBC0MCN5sbHwhNN1JzKbifNeP5 +ozpZdQFmkCo+neBiKR6HqIA+LMTMCMMuv2khGGuPHmtDze4GmEGZtYLyF8EQpa5Y +jPuV6k2Cr/N3XxFpT3hRpt/3usU/Zb9wfKPtWpoznZ4/44c1p9rzFcZYrWkj3A+7 +TNBJE0GmP2fhXhP1D/XVfIW/h0yCJGEiV9Glm/uGOa3DXHlmbAcxSyCRraG+ZBkA +7h4SeM6Y8l/7MBRpPCz6l8Y= +-----END CERTIFICATE----- +05EE9C2AC66F75D964AC5F1A3C7DE75D \ No newline at end of file diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 0000000..653b099 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,7 @@ +source "https://rubygems.org" + +gem "jekyll", "~> 4.3" +gem "jekyll-remote-theme" +gem "jekyll-seo-tag" +gem "jekyll-include-cache" +gem "webrick" diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..46f3368 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,36 @@ +title: MarkMonitor AnyCA Gateway REST Plugin +description: >- + Customer documentation for the Keyfactor MarkMonitor AnyCA Gateway REST plugin — issue, + revoke, and synchronize certificates from the MarkMonitor SSL service through Keyfactor Command. +url: "https://keyfactor.github.io" +baseurl: "/markmonitor-caplugin" + +remote_theme: just-the-docs/just-the-docs +plugins: + - jekyll-remote-theme + +color_scheme: keyfactor-dark +logo: "/assets/images/logo.svg" + +mermaid: + version: "10.9.1" + +search_enabled: true +heading_anchors: true +back_to_top: true +back_to_top_text: "Back to top" +nav_sort: case_insensitive + +aux_links: + "Markmonitor-caplugin on GitHub": + - "https://github.com/Keyfactor/markmonitor-caplugin" +aux_links_new_tab: true + +footer_content: "Distributed under the Apache License 2.0. Supported by Keyfactor for Keyfactor customers." + +defaults: + - scope: + path: "" + type: "pages" + values: + layout: default diff --git a/docs/_includes/head_custom.html b/docs/_includes/head_custom.html new file mode 100644 index 0000000..ac4e345 --- /dev/null +++ b/docs/_includes/head_custom.html @@ -0,0 +1,44 @@ + + + + + + diff --git a/docs/_includes/header_custom.html b/docs/_includes/header_custom.html new file mode 100644 index 0000000..fd597e3 --- /dev/null +++ b/docs/_includes/header_custom.html @@ -0,0 +1,22 @@ + diff --git a/docs/_includes/mermaid_config.js b/docs/_includes/mermaid_config.js new file mode 100644 index 0000000..c18f66d --- /dev/null +++ b/docs/_includes/mermaid_config.js @@ -0,0 +1,10 @@ +/* The theme's default mermaid_config.js is just `{}`, which renders with Mermaid's light-oriented + "default" theme regardless of the page's color scheme - illegible against our dark background. + data-color-scheme is set by head_custom.html before this script runs (see components/mermaid.html). + NOTE: this repo's layout chain runs through a compress.html layout that strips newlines from the + final HTML, so double-slash line comments here would swallow the rest of the script - block + comments only, and never write the close-comment delimiter inside this comment's text. */ +(function () { + var scheme = document.documentElement.getAttribute("data-color-scheme"); + return { theme: scheme === "keyfactor" ? "default" : "dark" }; +})() diff --git a/docs/_sass/color_schemes/keyfactor-dark.scss b/docs/_sass/color_schemes/keyfactor-dark.scss new file mode 100644 index 0000000..cd48bc6 --- /dev/null +++ b/docs/_sass/color_schemes/keyfactor-dark.scss @@ -0,0 +1,20 @@ +// Dark-mode counterpart to ./keyfactor.scss - same purple brand accent (lightened for +// contrast against a dark background), theme dark neutrals otherwise. +$color-scheme: dark; +$body-background-color: $grey-dk-300; +$sidebar-color: $grey-dk-300; +$body-text-color: $grey-lt-300; +$body-heading-color: $grey-lt-000; +$link-color: lighten(#6844df, 18%); +$nav-child-link-color: $grey-dk-000; +$border-color: $grey-dk-200; +$btn-primary-color: lighten(#6844df, 12%); +$base-button-color: $grey-dk-250; +$code-background-color: #0d1117; // github-dark bg color +$code-linenumber-color: #e6edf3; // github-dark line number color +$feedback-color: darken($sidebar-color, 3%); +$table-background-color: $grey-dk-250; +$search-background-color: $grey-dk-250; +$search-result-preview-color: $grey-lt-300; + +@import "./vendor/accessible-pygments/github-dark"; diff --git a/docs/_sass/color_schemes/keyfactor.scss b/docs/_sass/color_schemes/keyfactor.scss new file mode 100644 index 0000000..8508386 --- /dev/null +++ b/docs/_sass/color_schemes/keyfactor.scss @@ -0,0 +1,14 @@ +// Keyfactor brand palette, matched to https://keyfactor.github.io/integrations-catalog/ +$body-background-color: #ffffff; +$sidebar-color: #ffffff; +$body-text-color: #313131; +$body-heading-color: #17102f; +$link-color: #6844df; +$nav-child-link-color: #6256a3; +$border-color: #e2e4ec; +$btn-primary-color: #6844df; +$base-button-color: #f0ecff; +$code-background-color: #f0ecff; +$feedback-color: #f0ecff; +$table-background-color: #ffffff; +$search-result-preview-color: #6b7084; diff --git a/docs/_sass/custom/custom.scss b/docs/_sass/custom/custom.scss new file mode 100644 index 0000000..61a71cc --- /dev/null +++ b/docs/_sass/custom/custom.scss @@ -0,0 +1,40 @@ +// Dark/light toggle button (see _includes/header_custom.html and head_custom.html). Included by +// the theme's own css/custom.scss.liquid hook, so it's bundled into every generated color-scheme +// stylesheet automatically. +.color-scheme-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + margin-left: 8px; + padding: 0; + border: 1px solid $border-color; + border-radius: 6px; + background: none; + color: $body-text-color; + cursor: pointer; +} + +.color-scheme-toggle:hover { + background-color: $base-button-color; +} + +.color-scheme-toggle-icon { + width: 16px; + height: 16px; +} + +// Default (and dark scheme): show the sun - clicking switches to light. +.color-scheme-toggle-icon--moon { + display: none; +} + +// Light scheme: show the moon - clicking switches to dark. +html[data-color-scheme="keyfactor"] .color-scheme-toggle-icon--sun { + display: none; +} + +html[data-color-scheme="keyfactor"] .color-scheme-toggle-icon--moon { + display: block; +} diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..33d9c66 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,170 @@ +--- +title: Architecture reference +layout: default +nav_order: 5 +--- + +# Architecture reference +{: .no_toc } + +Sequence and flow diagrams for the plugin's core certificate lifecycle operations - useful if you +want to understand exactly what happens, in what order, when Keyfactor Command asks this plugin to +start up, sync, enroll, renew, revoke, or validate a connection. + +1. TOC +{: toc} + +--- + +## Gateway startup + +When the AnyCA Gateway loads the plugin, it deserializes the CA connection configuration first. +Authentication is lazy - it doesn't happen until the Gateway calls `Ping()` to verify connectivity. + +```mermaid +sequenceDiagram + participant GW as AnyCA Gateway + participant Plugin as MarkMonitor Plugin + participant API as MarkMonitor API + + GW->>Plugin: Initialize(configProvider, certificateDataReader) + Plugin->>Plugin: Deserialize CA connection config + Note over Plugin: Not authenticated yet (lazy) + GW->>Plugin: Ping() + Plugin->>API: POST /auth/v1/auth/authenticate
(API key + username/password) + API-->>Plugin: Bearer token (+ expiry) + Plugin->>API: GET /certs/v1/organization + API-->>Plugin: Organizations + Plugin-->>GW: Ping OK (auth works and at least one org exists) +``` + +## Synchronization + +Keyfactor Command periodically syncs its certificate inventory with MarkMonitor. The plugin walks +every order, page by page, and feeds issued certificates into Command's buffer. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor Plugin + participant API as MarkMonitor API + + CMD->>Plugin: Synchronize(buffer, lastSync, fullSync, cancelToken) + Plugin->>API: Authenticate + + loop Retrieve one page at a time + Plugin->>API: GET /certs/v1/order?page=N&size=100 + API-->>Plugin: Page of order records + + loop For each order on the page + alt Order has no certificate yet + Plugin->>Plugin: Skip for this sync + else Order has a certificate + Plugin->>Plugin: Map MarkMonitor status to Keyfactor status + Plugin->>Plugin: Assemble end-entity + intermediate + root chain + Plugin->>CMD: Add certificate to buffer + end + end + end + + Plugin-->>CMD: Synchronization complete +``` + +## Certificate enrollment + +When someone requests a certificate through Keyfactor Command, the plugin resolves the +organization/contact/group, validates the CSR, and places a MarkMonitor order. Because domain +control validation is required before issuance, an accepted order typically comes back pending. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor Plugin + participant API as MarkMonitor API + + CMD->>Plugin: Enroll(csr, subject, san, productInfo, format, enrollmentType) + Plugin->>Plugin: Check for an identical enrollment already in flight + + alt Duplicate request + Plugin-->>CMD: Await & return the original result (no duplicate order) + else New request + Plugin->>API: Resolve organization, contact, and group + Plugin->>Plugin: Parse and validate the CSR + Plugin->>API: POST /certs/v1/order (product, org, contact, DCV method, CSR) + API-->>Plugin: Order created - order ID + status + + alt Renewal / reissue + Plugin->>API: Revoke the prior certificate + end + + Plugin-->>CMD: Enrollment result (order ID, mapped status) + end +``` + +### Renewal / reissue + +A renewal or reissue always places a brand-new order first, then revokes the certificate it's +replacing - it never touches MarkMonitor's own reissue endpoint. If the prior certificate can't be +identified, the new certificate is still issued; only the revoke step is skipped. + +```mermaid +flowchart TD + A([Renewal / reissue enrollment]) --> B[Place a new MarkMonitor order] + B --> C{"Prior certificate
identified?"} + C -- No --> D([Treat as a new issuance - done]) + C -- Yes --> E["Resolve the prior order"] + E --> F{"Resolved and
organization configured?"} + F -- No --> G([Log a warning - prior cert not revoked]) + F -- Yes --> H["Revoke the prior order"] + H --> I([New cert delivered, prior revoked]) + D --> I + G --> I +``` + +## Revocation + +Before revoking a certificate, the plugin verifies the order actually belongs to the organization +configured on the connector - it refuses to revoke an order from a different organization. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor Plugin + participant API as MarkMonitor API + + CMD->>Plugin: Revoke(orderId, serialNumber, revocationReason) + Plugin->>API: Resolve the configured organization + Plugin->>API: GET /certs/v1/order/{orderId} + + alt Order belongs to a different organization + Plugin-->>CMD: Error - refusing to revoke + else Order belongs to the configured organization + Plugin->>API: PATCH /certs/v1/order/{orderId}/revoke + API-->>Plugin: Revocation confirmed + Plugin-->>CMD: Revoked + end +``` + +## Connector validation + +When an administrator saves or edits the CA connector, the plugin checks the supplied fields before +allowing it to be saved in an enabled state. This is a field-level check only - it doesn't make a +live API call; `Ping` is the live connectivity check. + +```mermaid +flowchart TD + A([Save connector configuration]) --> B{"API key, username,
password all present?"} + B -- Missing --> E([Validation error shown to the administrator]) + B -- Present --> C{"Base URL uses https?"} + C -- No --> E + C -- Yes --> D{"Organization ID present?"} + D -- Missing --> E + D -- Present --> F([Connector saved]) +``` + +--- + +Looking for the full endpoint list, status mapping table, or implementation-level detail behind +these diagrams? See +[`DEVELOPMENT.md`](https://github.com/Keyfactor/markmonitor-caplugin/blob/main/DEVELOPMENT.md) in +the repository. diff --git a/docs/assets/css/just-the-docs-keyfactor-dark.scss b/docs/assets/css/just-the-docs-keyfactor-dark.scss new file mode 100644 index 0000000..06fcdfe --- /dev/null +++ b/docs/assets/css/just-the-docs-keyfactor-dark.scss @@ -0,0 +1,3 @@ +--- +--- +{% include css/just-the-docs.scss.liquid color_scheme="keyfactor-dark" %} diff --git a/docs/assets/css/just-the-docs-keyfactor.scss b/docs/assets/css/just-the-docs-keyfactor.scss new file mode 100644 index 0000000..38160b6 --- /dev/null +++ b/docs/assets/css/just-the-docs-keyfactor.scss @@ -0,0 +1,3 @@ +--- +--- +{% include css/just-the-docs.scss.liquid color_scheme="keyfactor" %} diff --git a/docs/assets/images/gateway_ca_configuration.png b/docs/assets/images/gateway_ca_configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..1c705d978db466a06ff6f2b296fcd4408b515b2b GIT binary patch literal 244663 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�Sp4@#!`? zk8E5f1Xi`zyEzFoGDKl(u$(a2H0L|fU0mcqQ>iwzcA}&Z_SUmz7MiE5ddr@V+eYl% zVtElL72}dK69xBUR5Wc~uaEE4B+Ig}C?+eNQcLP%J+LbgyW<$-SpsQy2gw#y$Pdpa zc4A%XHjFhLD}u0o5&J@(FB0?yGox)e&7v3B^|YA{6*{KrJ8aNz%_CH>Gn{;)9pXx( zgL*q5^I4=mo#_?HwlSRKqi-KZ_QvzwUl)iwBN|*QHz18(!I;+bu%wh9sw;IUwTpWG zAUg0F#S{<{5`IIV4Z;@Tt12V;C9}v+Mz=L1re)w29e1&W1-cur|iR+zGkS>Wvx)fh+%9 z3^fh#Tcdv7=Zf(U(7KBE*YZ)8#t>9t4Xacxr&EA#OtFf)Qm@dsQ=U*q(N_5!Me!cC z7_C|tKn)Bo6w&^;kYl@As}-QKHcj;PY}#-4;j0W)awjf(gBJh!22B|;ma!`K@Y=k%?<7`;+^b=}U?(yl(2yn6^PyI~30 zOL-2x!A%IBcDZDMicU+9nxIQVo9R}i@l6G=MN=vD(rNde((dP*-u_3ZOybr{|E~{3DnI$>+9K5Ji_#PeM}B z5=JE*-38+yRk}PJIzmIC)5(3OGy1g{#l_+aNR#?WM;kf+(~+iN%lr|HNt4VdSY#4a ztVkUP<|NyY%NRj5=ZlU#^o|zJ5W89A&&TpH7uQ(qBl8iJ3{zKr^r@ewZ{`_h^tJxR zp!;Adqh*~I#^fIhQGZ@@2{}zeEB>7?^Y>0Vo)`kL2(A-12?v}$RT3kY7KaO#Q@C4L zpG5ayC7IN3y{6J7F-D8JG|tQOmD2Uq%eukDbAjujH|_1kc*u%1O(W4_783YH>k0xX zyx*;vcuos{e(4d?!6}jH{c)bsr2xBPOBz6C;e~cON@g}k1^YsXX7NPivIbshBuVrr z+nIpylP0%*UIpk3tM2gBGKv)8H1#zD2C1-qT=?#nCv9kAUyQB6DcD94=h)LnccMaR z=W2)*bYW{;oDWOo1H-RSb(!>{=Oe2IhT^*qBaRf+^V;i!yuSM{i_#bs4F}Wn&L#z! zD})cbS)7}QW-NAnV(&Z9!-;a!E*fIm9O_iJ1;oUDwd{MIUA*S7SCY9vx^KK-Y?)Q^ z#Pd~T;X(`7f}D{+IlV1O>5D~Ymx1F2Nv*`>NNFxa$q|qdK%YMBE~(j&UpjT#)Jb|f zVJL9S0=(mE)0x^#mMu={l^$$0an%H@H7?aTQOeU1)s9tErF+mftO*TY+xHBgMyC36 zj`=}x<&j94-he#cu!)KIjf06V&`Bzf^uD7sO;B38r5P_hXQRVzZ<)Y{U}8aEVYl_o zX}O~F2VAEyuh*JpJ5hA9JX)P4h#F%|3sqDGAG;P7^l8`6UONjImR(f6u$$9#nZ?Vn1OMM9hP$#%8nMrR?nT_WXM- zfB|nNUNB%(K1eHFVzOhq1hUjKt{k5DYHYHY8dehh?42F(Aj}S^@$sS|OlQT6gCIb{ z#DLm<4#{(}L9FqaYHu9fH>r7dMasb=(s>folpAt$?0UM~3!6gmOo~E{4s+=u>?g=! ze#((duR_NvN-0Y6Q8t|GynNq?{?5DD>vzG-rlSSp4RjBqs3$mKENm2 zh9}fGCq?G53@3kr9(b6$7AYA{>15wpxRm(GzNi{3ifLG11iRV)cuRz4Wxt?`RjRec@vMqoK0FWh zD49iBAfxm+7UjdSdT}F2c0LsQ2-i0`^w>hS_az?}4L!{)!wZEAm!$5~Mhe3~8 z0=!wT+(8?#2Y zx*BpOa-l9Ub`7kOhjc|kZrBP^TRqDpED!Sdk@_6RR|D|Ig^}<&P?JOfsO|oPrC!Y+ zvR10Mdh`;|rwiYFDYc1>%+Ah9PBssc>Ac``23nxfWy!8CzUDO*Z%E9C_t?PTl6)84 znMIX&lAVzmg}Z3kZY4BVR<3Fu6LpD3W}RAO<(cxySG8<>t=%I_<(KuiP3~xBK~7Vg zLXn(Tr&~Yjz~sD|=&TnO(aIpC^UiS5^Pt+^K30Nu-5&9uws1AC9x<|t&jU@bUMV+z zUyAaGdNag;mjo(hX&r&Q178UnnJoQqzVklk=-JztiP_XAFl}m6l$SEQa~W%(WQ$2O zSB6(2O`cE!Bkd6HzT8!JRz-<(JA2P(e9xpDK=kKbbITW#jy$}%q4GwC1!e}7^`uPp zRg)3~qDkPtxlLBIHZVyxgXE3-t8x`V)Wjw9jEmg=gXQPHr^)^?dmP>otS>$HREl_j z80rMct;aI$C3CCRv`4;8_a#3p_LRO6mBf zN?qwP+CKEe9%_~Y!?;xa1r}eu`%d$+Bwx#CIgg7~HzpWyq({&E9;Nru0%0;*+OHAK zc=zraN057Zd}-Z7>XAh!+`30ZJa}tPyZu;W&j@MyW>36)f-oC)jEqN`mm9w8sbYO7 zzN^t67$qCeol;_0nR;0C3TwSe*_h!F5DZnC6y^FHbZh-N6c8tywNx_)8I)(2A3P?e zXajmWWB4^=*uQ6&o5Q)K1S_(Ya#P~-Mi1QXRh^oqdlc>_Uub#oF2fNo8715<)8L(J z02e3hvVm_+igvkYWQV(aJ$@POa2CNb-4ZL$XxBC9k4W7S$ir-!>CQ*ztcnWIrZmj1*+|=^N4^2dpodp# z2ef+w8C?m`4KC&MQUBSMuM+^q4MS8$1Gx-KO8O=72WwZ3zIl!`&b^CUc1((+lm+HP z3JFR}mEXTAFO|RG&{jE~eQ}IYTyjhkV48&NHSjRYnwGRI!+xj+g=I|KUO5vYDm5N# zdgi9F@7-}PTjtYyT#TYW(|7(LszAkFVn@3S?|?m2ZHM{`AItS2Vl~CQ$WzF`V!Vr5 zZe-{49J=SMV{`G0p;)gL3~OD!ai_PEVxH2J|8W)XxGc|D1m+Ha^qumlkX!8UGxt8* z)*Uj?@9afPk%+JCD(~*WUy)F*csNsXl0 zL%Rz#gnea*Q%OnUo#f)SAg!Rs{9e#}Yin4-VBaT4gZPI`Wo!#c?-ht9F7_JIsVf!5<|@b=fA>tCxe|G6uN8>f+UCx_OyNFy=KD;&}+HxXZ1V zBYn$lFm_nSo>H8>D+-92qOi06(q^~Ya6T;qNME#NQixw#4ra`dn2>HcU@H4^TQZf` zlpvm#pkZ2Kne@IU@gfLbok6EA59PU+n)`k!nM^-%Q8jG?QT?STw8FwZ;(ND;@~O)b zu=4`5s~hF5vFIZ&rHi`(56vGI4D;jKoJ`!Hu8**mzH@q%hh{8|*!s!GrK0;xeZ`s} z#Y)cC^%aI#wX~?6L4M&>ea4>wL(;A*Q;&O4m$mfL^6+*%)porx5uE=~#-$LAn z%wEU*!_*O^(e$Xti8VF;f9Kn(j9B5xz0CaL#7SqDPh1B7_r`bx7PHLY}bZ<-!F znFNK>Jp`Z6w^oCL=bYZZI}Gq#qu}1MKOOxB`tgHC#HY=N=}Me$uNr_~29vIY=g_&& zwLt9W-!5n~C+Jf}I99QC7}&vBCM$QyH00x%YGr3#$EzibZIp3uKX6xgGXt*DDf+1A`)$9BcRlt)*KTlGMNLuKH-2dac4_bV+o=Y|Sz z@&Jb4lJwXCZ#~|ctANT>CK^d`sz!F26CeJG?O;f!XRi2UN%wPa z#$erB!}&3#i*F&e72E52bQEkm>&9u1GRra`&jq^!~2aR!@Pc0Infz0)JFhAmOk5Sqhowu#b3i>+@rAhSQ3 z#Ff}=o&5}#!W^?)Z;#+@dXn=LN~*@CwQoC22g`=hoR%(S_76dmH;<0J>xl*E!n4T`&ZDODu z@9!y@1F0=vY?k>hp-p)izHsQ8 z>LG`dRAw)(JaqS~{Mf)hLfq05GDD`JGH6UM-md7e*(y)mduc|&G$-K&V|NR61{me{ znze?u`87CeYYZVJY501gcUK>BosTY(WR4xQbswAosMHr6e}bTyCInWR@P`2kkJFg| zw1p_1V0E?;dtmde_Q^Sfc*LWjIT;aR=icWY`D;QvA5G9a)eo0;j+;ZIS?^T%?us(R z9MKy&seD5zn-$INh6oCy3M*uU{hJ_RG^v9}u*)CpsV4Z^-!IIP`=~mdYhJ6CoocaZ zuk{^)xFc_Fn9C%MHn(Qn%6y`_eR7S(Zjlu(PNQ&FH`$}gE0xH=;ej7*cwq%^N;YxfKF z;!2J!V|Rnnj5?5I6Et4NSnnB!_lN3)Ys9{-*6D@#Dfbr5;idSA>#(cpBL-@!J$fVh zFv}V)&JJvx;zX%ufj5IgY5i=6_|r17v!VBEO4W$nD&C8_b{kdO)TcUHI@Li!dTr^> zl&Uoh#~125$?_ME9LTIA;9_h3hyoMkkh`x8CQ6Qm($N7MuMKH5<1|f%@m@%Gqvn$j zr2Ti)&J+@T`yabn{`>Ope>%e_2+E|F!^`Vu8o>Ljx!YD0&GV#7x7rFll!iCjsQT?}};8A9-StxeFEi|!DlFy6^F&AGRNmEzT%UYP8Y^kAWVD$*_w znl?}rNg9G^VR$B{8)9v~4hT;GrjWRe9>&@dWgEU>70S|*;kUe6!dy{px2jNdCQl=$ zDN^9?QP#S-s&oW;#teHiIR9GMAw!b3wac`)9-B^bY+jD}(%ep7#h4THxG%acl??~| zZvMv5_b%4EEr!vEZj2A~E_e_J1{BSC`-evAS$jPfJ4&#O%BkD|nHOTJd#g*fg-xJl zwr-*qCkS>g17;~CO1tYMAHEY??@~8?VqKRG&K{2X!Z+ebPR4(lu@*DBhG(&{Q6BC0 zc^l)8*`*)%l`2N|ZP-Zq>r%_!^JE{^Sy|uZbs$I^ZX^TNc`r_&N8b?7GRpMCbJ`Rq z^2thUjmF5Jri_cXtQCv!VJ1dmT5MiZwokueVwu-5PdqDU1dixX7NIaz5euSfh-#x# z@;M|Ssjakp0=G=ig=yG`p(Zyq{-5RkLP97%O&3QmjTmsMvsE|Yt07^r0g;Ns?)q#m zR&=r^rElHUyk|R^fBv-yRT4!Q2q^s#fU9k?V_M8C#`nSi+)_SMTYbG@#E>XV#kq=X=!=lRuRI~ zk5vI!A-~_o#B_z*E2{Ck{%eyJ$Ji&u0+~i$%Tnccr$~#w3zLp#3u!~V>y?33U@uzO zy$4G<)zsYD$~kv$#-b#x-aCykq{~e?x7WxKFroQFj$ic`H4{E+KH-rNU{3P&~HWcP6J&i4MSiy~W=a4(b}Q%k?8dCzzn5uar67b{YohlHU-&MZPThT`TM`dYHVVRoNkd{tsl%p6Qk^PWL~vq zC4BpFu2M{xK)(uwrjPs!#VP0>pbDy`CbQi$&IDBH7&zd_LcpY5hSr>V)hR|A=W9h^ z+@uC0(kv@f=QC0Hvp?$i4kbNiJVBD58=xQIxwlAWBZ5h52L;l|mL!@jQA4y>M>flA zBpg=(PT#^eaZ#S1fDf#9yZs+^;wGJp6xx*-;c({>Tp>ntqeS<4iB<|{L+#r5!%;+| z-=HS;itf_ghTX+BV8#AoAR{fgM!DNlEn={%uomR`l|I>0MkwH?!%`^Fr(?kxALsO) zJJwlIBwUE@baux(72A9FAF6@gw?(F3Gtt#DSZHF27+HFTA~R|`#^02Ug-RJ^P)?C5 zwydHlw?-nn92Xg-g}2NnQeW;XDq`wip+?BQXLB* z2q=hj;)sY+rFT$Tlq#K&K*R#l2Wf_u5u`WiHHkkN^QfNJ!qC_dCyd zoO9-!GxI&)b$$Ol|J~P}d+)5h*4k_T*4lgRCBK5hZG+U$DNY|DQ;&S3vH1QA{o2pD zT)%1iB=Pa>vh;qxxNa*i@ss`Ikh@#dDW6{CC0x0jTf?jkWh)puKaW9!RL_19HKqJG9c0@o$Q)NcbX zp%#>Fd%w)uAP8w}3n)kRbhaF0Yp!#jU3ock4@shE-97PoC`9R z)dR`LgT(t}X3wPydXV?zF=PH*r|nKs9@W9fsNdICp^n1O_=bKg@g_J3g|U`HNVeR; ziXnV6#XmVzA2dzGoy&k%iH)xGRt4b7w$+b<(E;wLXO@)!xnALOBIAev82*>%yo7y4 zL{g#EJ7i`5uBspM*^MW!Om6l%heSqsqsy;suWwzMP7#+{UGMZG5Usx73Kkz5Ni40} zQkXnbsW96IHD1(id-GAI6gd;OQE6h5>6Jn;7`mMCGU1liPwVS>Mj`L?+E|}-AFFk% zV^w!}V&B-lDWsQ9hg`hd#_~WYXwARqs}DK7%vw(KB1tSho?SaS^6>;0<`|>7I8QcrMh1IBf;??C7icYzA=YqrdG_jsM z@|b))JM|;GX!OzLhh`N;A^z_Ug&h2E3;cK)*~r4i-7V)ft|r##o69ff=m4Y}5df1c;7)R_I zaZ93&@N#`RjVj8=d*tx?w({X`-7qJ>^Bc0~T&yxGfOp94^@PjLLNeSf4YuyRx{K>z z0KGhNui~QN>p(uRTO?+7h0)Kx&T}W<3z~Sj<$m~5K*KopA3!ATjl7ap8j5`U zbk~WRkC6(7d$v{F6ly)y1KfUR(?5=_h#A+ ze7BK(Pk3`V$}l(61Cw(e$Da=aee1>d&hfhwpr|_$hh}RWp%S0k?tivbnOHrb+&HA7bLMmlYY~@>E-p>C-=j$b;rYYl>)PhHK+40!H+5sz z``Ee@VTsCewNCbpIwOgCl>s+~GIk!M47!o7?!C!5sK_D84jEiJC>Kz7qA=j{mi zCEQNr5Bb?J>2e42(%y8dN6eAR$c&uEyJ$kr0rxBqh>#xiFtHJfgyz&OeVMFeJHqVF zG0-IP-Y@CC68@Lz19o-;-`_JBsK-BpXyoVQ+A`g1Jyc#^61Kf24{dR~FQ8E^Wz?>2 z9KxFlB<~nHzoj><56w_`;)5M#>hf|qGlh16tF;ma=?r&uKOwDJ(}_CsASVoqGu_6S zYQ@luH&mjB`mSKV-^ATFMnfs@kEbH)TgZ2k)FpB&+P5)*tDgX zLZ^7#3ETHZ%4Ada49*m!-r)IQq)B$B)K^qwK$_m_dzLA18n%WcD3{LfP*=vE~esu6IE^gWMfkH0W%=+#{#uDYju385UF3es@*&wi$}0o0l)=KYk@ z`!=S5)M|G`ssG#Wk+T)u|zW9rZM@9Gtp@ya^#|_?cbFiSzP*Bp^F!gk7 zBCz%_M|I!R;wn2lsVgv*ND7JCk)M1xI*soyJ+AU#ZF;U|f#T;F#_9HrDA3HcyvDuK zsZR!%xz8rOG!d1EBU>sLSa?zs*2(hW;(cck3p$f}T6)RIlmnT_;uv^xVM?CiBXavP zd9W;Gr?S2(QCmTT5R{bDl5B#UBy+_3*+`9Y1>VFVBoT-ez+yi-hnfCta3G@I_RyNU z%dMzzBjkm*33gc8WQWLn#QK9yArJ>k2B~KmnSG%A8L^#lqY?uWbNIsbh@|&Pf4lxU!Ng=mxr=jSE z4CiJw6Z{qq_J}rw!d$GSD{Rqra_wui2)-caF%-w7wgb*s26XN7*(>TSHpMR{U%&+- z%9#EYaNX}%d@Es86{MKd!Ri-s02KG_VogJZ&GP^T^8&1aZZV|(RmBF+q|b@vIGkC!T4`sR*$V^1~M-k z2EijAn_!xpS%~C25dcUpI3L2{Y0_mZ)8O&7psRFl%}b;(nZO~*wIG@gRD!imlX08@ zU_PXxgu0;v6(bW6DyfT&r?Gki%m5@O6{s!31Z)}(!(GJjtn6;cK@2Fj?4cm33#(Cw zAF@qj?~aRd6YxZodecwMTN5&=#b%t%sV3rKazTz(9AUQpwsHEm2ql7!z4n^}cDD7_ z!EV$}pq-f-u~z;xZC4^v9=D@1$I#@o0T}C#dYIbQ3Dv^X@otPrp;;s!E5sQCMb)F; zaJ1pn*lNyI5}ePMQ_#%*(8x;KOEl4JyqmFIIT_l^qIqe=Weu3*x$tD*gd9{e(4^*DX~d;CoM zrPTGv`|VQ5J=wY8>=_eX43v1gef2|UEQ*QskHjP?UFAb4pcXtD2kU|iFn$ax>2&nE z8XL}$H_n+dYX>Zq7S*=hJ<00e3xH_R+tl!+8K-B&;O9HEAtG#(k$2w&r2IF%^Npm!qZxhRo?s@$9V6ALvKXjv`?#pzQy zB6$~fP(<>td-{&w1y6vfe6<8BbH2Lk9`QC>O*t)9^O6SUZB5j_s-SZ>%IoGItVZ+n z_xs4O|Lg-eSTW%cZzb+Auu$=AC~HAN4>T7%sS6rXX5ZPm<b{*__@nqO`=oS*GiTz^G&_=A%G2MAfG5qcg zU0s=KjaaHQ{7!Th#_2s+eeBUeFUG7_s5#38kxig$wq>-&D`<(iA~)Ce2@ky zbh`#k+2tpu!YMJJua|9)V|(OoTT!b&yL{jLN~xlVKQxD^$**RW-~9E< z+;D$({C6c^U?m+>+Bf#?(nfVZE)X%3Fx8CMXBy7!+A}r2=6Y$4BDLOLEwgfQ1I(Y^ zzdK~EYqnA>F|^jtNUhycd*m>Bdfn5vM-I|+J5CK zNRdhoxTKMRyT)!r&d_dh!fTJxZ$c!@rmGI;*A9)|h&sCekz9HBCgp{#O^tZx8{B z7o?ujt?2X41}v;jXmwM zX&np`;~*CqYT)=>l@6!2r*x8hKV8Q2xWgvRMUuBE#5+-2`+i!XSrR<9#@dxx`o)EP zR!x9hK-wC*9y+^}p%ei#oNd}&QAIXI_)`(8{d`}saX@CHAQL4%$=NSug?13MX@(V? zp(Ug=>Z%I*i7gJ?qQKoDQJUV2)&kFupqOnOEi_=JQ5zk~8Ug4s4yq-RwrI}qR{;jj zlA2W%$l$LV|4Cj0=eUKE&wg@z{riUY4~g}MH*(xg8ePE8g1k9&dm-l&Mv&UJdtz3DGZ=55hY?Y- zV%&V=Xhfbd$a&*o-4s4qH3PZ^%vhQT_V;T;yMHT)I{OzGbxx@_xr>dJz<^3w(^fLX zkn2xrJ5t-i^% z#TS~ORE=~Vg+}Yh8xa=;Rh+j}(UD1$agWL!HUi|@HRQ+ed6Oa#&~C6vlH2Ra?H=_@ zAfuDrM?(m?oETPY5!n^N=rI%}&(83Zb1O5$dx7+V_8Z}>X`39SYUL1O@bQ?f&0txP z0PWSOv;*O)xF2%GBems~M^Z7lYNF&2#!>6*JDsZA-tKs(4Oltt!&1XAHOC0;*W&Dr z1}$n-OS)O><(^N}GwIz?q^k+W!yyt)6DtkjkwfKyph9fC+VjM1v3OkIymwMO6_G*B zL-BD1G*nXE>RDrt62m{#+2fwr>X3A; zI`NKWI3QS(pC16QX$f#ACJ=#p30q`6~W<@ zHoPaU9k=h_%~iEhH3HTSkG1rx9?XiY&}zhvmk*f^T=>-JtK-o8@G8GLO&-}&>KhxX zJ7SkoqN1FB&(fS!o5R{Dj!Obsjf>R9kWc8lYCjgzau`rH5=}1ja}OP`&#W1YoEtN} zErNu2SlJiFpajS|I7QI=?`Cs?2VJasV!oZTg9&BQi!f+ctx$8H8F1w8B z!uYZe9e=Vw;*}O|0n|%UAzv+5f3gQI4tSvb&9P+Kv1wDaxa(niq?MeP+Yc<`edb_C zrbFr#b}bIQDyn5;0S)qv&@WLHel;By=EWy_872b#5tf+>4G>76w_R&jP%F0 z;+(&owQCZ+ApJ{TY-j{CuzePCF4aUx10$8>?y_Qt(3KUr(S56TKOp~sr0v{&A0e#1c`V#lO5o*hdY#Lqo$rBXJ>E3xWKp#TsvhFzGBVz(Ed3_T`)p#K;TN1H}*wu zRgdW8_(A~7tG56-Ov#fbHOc_dOUm8uN+tCp(J8JMYTA7qkwSu+)yBC=wEcLdbLpp# znul})fOH>!hlPz{Y1vVm+}ALvZ|Qmn9_K1d$RL@pwb@RPqt#DPx{p=Ng08{WcpcY= z-y(-|ng$RWp;u6C-?p9XD(aR(8h3$;qvcseo{tT1}PhFmHnP){v&Jo}_l<;-tMR zqEysDh@1CXB&GP{@?HucG50`9QKkZt4pUORS3>^6bT#k2b)hp$DW#g!2wZ5-)dK?W z7@q{XjL$8=5*o;F4PQ7A9Lm3d*vp?Y^N|M;Qu!4ZA9v4W1B`45#jVzNCoBUce6CYqH0^HaZLb}Ib8V-U-M{81c38+gLk#H7K z8c5NBR&bA5PT&GLQm%+{$(wm<{xbYGBxGN!lV%gk7N^kbuV%=bsq3oB0g5uR^kOqw zR%K0d%b?A4jm2@$+aY_U{LM#D%i9ZM@%~>@hR=WTH*VW9_LW|0Vt3Z@D-}CypCLgd z=!HZo_ z{}JUKkl_L(TZUuK|6qmtVejSB7kUeyx4ysbQE!a}@^uAg)2Rtt8?dsj$`!+B>ic^U zHGsfY{le%TLw(QI$dEe1o56P_rDdKT5<5$FIv%I+yBk1PYZGSor5_r1+?WzMeY=22 zmyoUTZJWk0>TW)f7j~|`=#(jpH&-*0H0~Xu6TTzf*H!M2JzDNQ^~=HI%RFY5ho)<# zI+@gj8@YC=z1&c`5sLnD3hBDg-J+nQr?B!mQ3SleifFp@iEIEvbI1gYSlM`+@CNM^iJ3u%b!kA$XX(j`?Pe<@vg$$9jyG zRa=RjoE4E*wXY$n83)+ndW+U4vOv3tPF~P$ofI*<6?&MYBA#a7JO3F?+uj|jL6Z9o zZ(NZ|&hYYHZ3YO^6WOL|ft1b`L#uV1Z5pqd_N0Z;bsAPl*KEoq)pdZ^@sXO^DLrlH zSnccx7Xy0q)cr_JAl0$8A%k}gG{+Xz15H9}F85MD*K8vSd|XAX&pOpu$utDv1q^bX z!57hQ^~ZdYp6Vak_|!2)uozSzhI`Jzqm^NrQ==&tYW*G^SS{Agmx5mse5@BtjmHlfEtgbJfK^2wdToRsS9d$};}9Huc}H*;Rs3 zUey^%%e?}UpWejk&M}dqyeQCB{`@>uMN#sC^0QxyiWM(Zeb;V(vskI4xJEAZnfO%t zy;!nRiPtxzN%f0$#p)qqafc_waS}vKCrtBtF@yM`JfO?5(ldUYx3Z~wq)KbYld37? zuuU0EBDcGm=S-sjRGc9y@bRicNVDkJZcn-H60T?bRAJh&$39vn(W63kfjOEpq30*C zLr=T+KlX;E7zW!*K3%{3TEL5syiH-;66f>)wIwD+%6xBn%cU2^ca1Tk$+P}h3n=Q{ zlnt8|!b%AP+`aAxmkNLXaADn_)i{xADlT4bktUZz(?kg4u*N=#waU}9slD6?iIWZP zw?0#z>(qpv>VcW#eVF>&3 zj)QN%TR)|-)6~n^@|XGT4O&gaJ1K;EIgj^3>lA9CpQnJ;PiZ%iTEhQ21+X1ds0oOI zNADUYXug+Cl@f^wb^2V=?X5pKu0ka;tH>WlqZ*d_@X`|H`W12p@*(10E3-cqQ>KT1 zB#x)9*$DPC!WY(YE;{6Xi1w1Pm)e5W(wsH6XVaV;sLFX<>2RQ%DGPS;zVbRA^~*O2 zg$Sn7O3h4VeIKKB?3a64BH*ovz0#_}d!O2uar3wTXbJDXc^CSp#CZ?>$u_?UA3T^o zdQnrJDQC0J+xOz_L>14W`TN$A?~D?Xy7o67mPeO$#dudJ*<|ir2`~9Sht@RegAl)84)WKBqsA zY+puwfS(LLyKOBz_!+B0#)Kz}Vf#>(S|A69?PmbFng(XSj%lMPNCu4*qOk(U`OH?R zuAJqt(}hW(GCxY+?UrH=s*xccfIZ#qRB-jmH zu3W3U!x}o7bYgHQB%!>1vDv2TX|LI3QsrOKTn=)0HDqc3!`#auA*+UjU;3B&rV4>D)7#^v|59sH&0-A0yEV*+L+KxGQ88}m7!rsZh@38Lbp zUkoa0Fj%rFrMZmmsb-HO&+^qwSDw2+EjTh zv{jq<+rMx~JfwiwHVYz8*!v-b+lo#89k$4@{QOeL=@l78M^GInLYh^-w!T(zPf<<| zmqTx9{AO($(0`G03B%5Q$&fOAG=mJ8)ioqL~k3?YZ zxA@l>SCp=E_bl)Jo!|d29<>?F~fvAA%=r2ms?EV!Sxpd(ym$waCD2c|10Q-t+=hD%L zTqL;Y4zmExq)Wta8J>OjlUT?s=tiRiL_JQH1m+%5UBi68Czg0al#$D-(o`QmLv9k= z^Gwt785r#Xp};aUqe}YtRy}yrI`_aye68%7305VqN;tXuxcc)y4mz3@k5siNW|jWg z81`>0>WA^a##cO%ZTpQbM=>WfPx)ws-$+$Zit+2dVcl7ECd!a~b}Bpe0T7&6A-go; zn8=%ZCdp}MC-+tDcPH9~!DS}aPd{`$xg$!?eUv!iAwQ$<877&ZM_~qCU#;l~oNk^l zGR5Pwk0n*AEG|vPAL%Q=p6rT7;FNx>^&-5rq55DK5t`u)sKP;;6#w0r{aO@IU!=f1 zRI6DH-Qb7q8sPZnzp8a&%PW)}&7{}m)#?tN)pZ5mjad)?=2A$o` z4^x2ql$IZ+1eEgR$HH)bbO!u&PWXL)H|+X}KhxsBao7LTD#~5xmyPDNrkjVqyMnkG zI2qO47wBjJm9yq<38jBm54^P=h;?t#53kHVl5zXN{1m=~p3-4B=+!2hD$Ezulpa9BojJ;z&v?uA9H<;jhTg;UU*+s(vq0)KYg;(nKtl7tR@pH%-dR zjtgjgdkwAZBN4Zi3SW&4hzL9_v;FGArJ@lbFFrjeogrU+YbdkeuMFkfSP~;mN%p`#QLn@+7()H6P`zL6mA0 zhya42!`L#n+}Ms>|JmJk!%{lT@aAe+*gM?R1Mw#t)2aTfsS`IVntc0i!^IFF#Kg

kuLP0s?RbYt)e4KOzFjfU>I3gHnyJT}MhmwN$gkFM z;gq=Az?%2`u;%)@<_@J!*V4r{`7pMUBg?<;Sa*`7V?g`vL=yQ?(ks&XY(|z7nEv z8aJRNI)}I<$YY=eU6XzNQ(%akgk^HA(}H&%qf8MWM=A_630iLks1Mgw^`t5`Xf9N2 zAt5rUzn!^(Q{4Q-(@ z59fmIV~aKc+1KFDlZsY_b_zjA#;tg=1rlf{k+2iN>m0u|T%hKck%gBa=W=L-rAN@CbuCXf$b0C6#U{{>xLR|1{}-IQKq{JMA*ftmppGT>X1* z?6-#S!?Pn*j-O0Vo`3)GNKw374S4sY?m(6bUfkW!Pf|?T2ziQp_yG2xmY&ydL)giL z4K`gn{8+zm#c*3KfLc()S$4Z48?x*65nXit8-JI*>>5sA2Qyz&E9;n2Ox*2~Rn|Mz zM-y1ynnre#UjFPZymk%V_bx*W0eiob)Bti=aS*j)oDE+at%0;6G|+A0X!eZ+iR2wN zyTFt(m&>aiB%SOPTS?<^Pq8LGr;rEU!FF+q!_tY*N2%sCijb*k{?qBlR$SM=uFJ4!`OauI6ckp*8GrXts-+wsLQ1EI(#aR?>A zC{R&t6|YBYP4%Kh(ly`E!A2=*JL`T+{ybC-F{xyV#%Xsya0?rzuFxE$BdLHly;y%x zj5zS0x($?k84)n5;eseUBX4jD0v&$*o987_E z4RoldoyzBnS-?x@;Sk_J&GAU_0Ek$NRCQ>OOzP_!z5`7B`1YMK&bnVwC*Im~@-)u` zqZq$X66vd~KJ$8EAw>*!WFqwao8l%S?I2~M9biysL-n_!xVs}g!$Q4RkzUqmM8@h= zU9Zc*@`bhnZ|yYfrs1dQt%SP%6ukniPyjn1t#HDSn+fOYSOo`ZquFz?1Z$XN05yjY z`*w|>#Zw0`YFcC#(W?w0vMA_)IGBnd`C(XE#Y<(p!Qp_WAgxmZ)HfLVWXIbazecUC zlqr08=UR#ll~h?~9cWc-lGxRFUbVV@rBkd%8{C*3I5W%ZqXySLAhxu*802b_+S8*? z-q}eOq&DHTB(MWU4njom1e+|K%`wNoj~`HCQzJLc^GtRZBSfU}e!!VPB!QL!F>$tz z>~R0#A#q#nIFZiMQcL2AXRtFU5a&qM82^=Y5=|>;?Ez8^%Qi?7UVjuS zBuF@}(?&ytKDn;fCpSl=hfL7-Wf__PaD_H?y_T?ecS6JAqBvo~6r$GPrqPN!+50xa zSwo!oD0G}|*^(cg9)Cb7rHAh1_@^yASt9T;*x6_G=(j6;hzf`v87AGX#Hr4GKRv34HnN>3y!cKEXPGUr(ZsUrE1 zjRC&f)23n%>$UkaZ}{{bsnDR4Kss~d$DI84k4A2V53Q432#IHxw>>_(NiNQ|%j4`H zLxZ=_(aeQ*1h=9X4{Wlvp6ITv+ZIh{8rn`PTH)v079d)I`-NUpo%4fb zS+sa^coKBwQCg~qc*52I-y$QODP(U@7%T?cYyJ|e;X1%pAcn0wJu(C8IH4jU!iP>& zCzRQtB14#xF?n(1?L?15)}#w+Nud?xp0=P_f>{EyS1GoZa~qh$xp_%O*@`ePg)k9^ zC%9&{ZfT22pE9GZ>~&YoBSYOrR{7z5Ol^pymI3iaZ~ry}Jsc3h%*QKONL2~0J43yJ zYXqkgwDz`|%aM{X$Wz4Oe#5fW8Tw0`YU3$~$&_`C#z63zgj|nf#g%@O++Ne%InR)m z%ToAYmEvvQ!ggmbKSR{cx-z!CODtF%Xjuu%!jK}dZ^deW5k&vXJ?le^ob}nfd(S$n z7mtk2y~ZhUR1K2-4yFgDQycNpq>J@})D&J7iG%|jU64;dPno8XOY?&|OMbcG7okYT zS+zfs)e{uYRWms;n@aQDVQJB3t&MXU?l;i`z3@%hIK^)&ucy%l5_M6)XxChLlP#hY zv9-?^&!|jG@}cIL6ookYH5B{i$yr*%FigZkof>ip0uYGd(C*f}|3uB(a!1qdrPOB^ zyth!VyFmygmrJJ2H#lj7jn%Z%2!78~r&D}%Pmw3eA}gKYgqJGX{=l)#u?La#gkWN@ ziQ^XYiXQ$J>Ugoqww}g5W)V`m(+}~(MzFRbgF;SrZPI50YpCn02Sf1FT54~w5s!x& zr)pZZ&JXQYP_NwBCWbEeJ>qWbs#Q5S=c08Z>4Pn+mm;mLkwQ{+&qK8W&&dzxilz^6 z|C;u>h@Hbj6?sD<@X@qQx+6*)-nRcj>$%ly9{d{8k`Z9*#RUuSOmvL&AIJIM95Rr3 zGW2?)D&WsYPyahi`Sb%fTJQMb+R2~Z&mYOMi<8dlFnq5Tu;w`2qrp9yXKbK$u2ebo zQ6BqFhLTu+SJtS4V86bX(vQX0!(~qP6JP}c27b(YlJm;x+_Ha1s<-@iUptpxKLhT;3h-E58nVdUUGkK4n)~GNH1YJYTTN~wbL*(QSaYLpN>7rbX}5~{ z(nQcTdtr6ztI?&4iW#zAgOPre!EaCSd=jNx?= z&}L%$R&?_1Y1@J7YrWGGl`BeNswU+uW4D9A80*TEbRc`NHAo?muQ%Gj=u<^~aqU$B zgX*L~W6v48+%+3DZ6RTeR@b*=Y^|f7UabUt<_-NVtJyL)1n((%&L?8OyvBzN0?Ri~ zZBV8lfj^3>Xr`~{wK#$flnRyoXB#Q)66qfhW%}7Fq=VU@Fz6cW-d_fU^-P9#mwl^k z&2vzU3)%Ua?a-p4GJ^?V17@Lw(GcD;UJTx;E<`SPW18{5&?6+LYsz?rV4^lBa3h~> zK<6=_-P+{3P3!z9Dca^`pS`=1iQ_pF6QtCZU?a(ZCEVwBZRG1?p`D`)h_`oELT<6K zI|!drClvqKCtQ`(J$(MH3VdcdW@$zd0VlKC1v>JCRzFwxka~LKc0^H(^lRi_3>-?E zfR=$Xia*nO>_$DtzYH{GEo`TMnQyDUt2t)@F~;~?t&ySpW_F{uSVr@*lwt`b%cU1ni@aUAUTn*S2?GKYUF!| ztw~io*(S?*aQURePgwKH&5&u|UylFyJD~Y1ZT@;aD|h;wWvTF&e-5Gji8nSOQC^t{ z?#9UH^GEE|0Rlju2>;Nu!!dQ5{;INGkI)H~yBM5HXK$}(;pO$469N$ z5w;$3G>);=sdgCwEObOybojlSiKoYLpV`I>b`6_gT}A8yy?g(`Wx7gL|6(bxME}L? z%It|=c7}mrkf+bk3nb(2M7<#F@hI#?aN~CqUez9OjC9>*4OKTCpvkmLlQMR%o$623 zeeLYu5qkn6lWrGz${sKM`jZ_FFGi+aQcy<8I_eh&+_E;^Y%!#idTZ^6t=a5tprgm3 zVeUKx>1S6AR6Nc*D!UHH)8dM3oa~c=vcj|`XiXMb92TuCuG=stD@#?xt2z+~+D*@N zJ%PM7H?s?&w!%rV98aEKFi1pGJE_&96BP0IgT${A_;J(=nfzw2^_I87kp$ z7oA~pa9}yqI0$9f$u zoj1unMv%fEL+|+!wqO;!anw4V(e@_Pi!>-V%51@4akr#;xQ7qvcatXJj-M!IH@F83 zA5zy19&e81*tcg6C@f)KA~{Q5M!6)ITBdB?0>lW(*dy|X?xnm0fJ})tR#$D&QVQ^0 zHKFXfhueE~H9qZW{GE6U_O@lk`iFY~B!TBHy> zyHL4uBKt2`=!&xJ%+bub{AFVf5A!JDG)uYElB*d$&Ip}RXsx- z;NAfdvi?_hCb-^W5;?`5%@M0%ta2VxUTIUp)d%`(&j08yt;G|gbk@H_fgcf_^bSgW zd)VJ;GDo`plB6t8r4ccL$|;!h?})0|YQ8LG?(yz^;DAvLs_m8dszgriwoMkBT7zQu z+pTuz3 z>s{jj0%K{=OC7;^WUiJl%-~I+aLehr_8a^OBKps3e6|~M&a`Edh7!uhemp*^R;}$% zg7>bH?L&1L8xzwp>GIP`{GZD_5dl^M)LaAa&DtR)AH?t$@MMr~OAy?-J9HE}VzX%MKiyrrksw(=H zPN1Z5u&-QZcT_4YENCOoFhhh@ZYV!H!LCyMb!2dq5Wll&b_Ya_Mj?-n~`=N(wQVS}()m)hOor*##Rm`LyTd z%AU_Hf4s4A{%Ki}Aw2AS<2LY@i9vj{Ci3#(b^XqQ>Tcu;#oM|vr!uxqx6Q*7U09@9 zt?6w7t$wBG1HW5Mz9+<-c>6xaUM&hP>omPOaKo?Z(spz-l#a6bZaJvi!jOldG^EkjfU_(Dx#xQv$D`j@5;7!-|kr1nol7FAdZ9g zuPQ*-!$j3*=J?%Vr~oz}^mKf;yM8y&#yzyuV$hk0tz^w=_;H9%h8xlOZ%I8{OqbTQ zh4Q8KH>`)(uj@IMj;Rv>-twVMGLvBPW{3|__4wbl>pwq46>_z>xgP2H9};-}y=y9X z?p(>kZ|B7DWLT{D2XFpU1f3(jW+BzE;g7qtfxnJSU75!vC__$!U) z@?ZdR`PulcMwBqxt+uC16yQ_nBAS3qk$W_E+TA+QtyhKWu*SjM#W%GKVaTBnX&&@& zhhO(kI{YGac=Vnu9Hu29e@fnDFUN7hPOT?)B}uxm{vYhqR>Ke-D7T1kO&6kcKnF0=`_)^zW;5q{W|e19v|Kuy9}g%~>6tB&?ty+S6b6(6B!x+cn^aeJFTuDj8bC3PTD`Kw!a(R8djfrWaK}@Q$f`kJKm`g%)3l-F zut<*YmDeSt9IccCT#FW*Q_4*y`6;H=3jng!i}cGCzT9J;0zvNVu5tFa-e(1NY(?jU z;_>O!xyqzqEE{@~1vpMmnoVg26hDI#Pt^WAZ@jEc~ z!^fjlj@%@#i|@aSYQ!ykc65aOPzT=Fv_Ub)CiA@sPXg1Zedkg}#-2k_KmygbjEIgt9}sYzKkVD+ zT7Z~Ju>shDsK~lLds>LGlMmNRF6xX(1#x_t_t7dwMbyv3+nU3_98*EejoWI*d($jh zDV*)(`7R0$AnFdjoGQg}b(VaQr0j8M6nXwwEhK#+Ab(-l@ahZ#K=;PA-w+gbhF(Iu z9$tYIeK&GB+OZ`|e>#LI(Y007!M*+?kLeOoPbx5F_w1-?^Dt@Q#gbm*X{M&R@WBwi zHOz|wL}<~14+1t=kNim_sO;`JQ3wO*pF4q1)@#}OlD_^}`rExnDbm;LB~w#4qmr2Na2Z@_2OnZ@T~O;;@N#mE9%=gOxg zJxO`0)ucyXHm8bR5A^03qLAhiN>ECBNKl29kv}&t20Fd6k zor_s`0j7ZE(0R!oF0(tSy{-rp=XRRfK==F_{Cw;a`;@;xYO71AlpJ7_4^FhV$&f_b zb=gFo5tqfIbWhO+nUIj3aWA=GZa$6GdE!>vV)eIMAlCGL_WTIho_x@5NnfstF~eaE}knujeo_4#EC1i3dw3sgLFLJ3-k)Z*2fdY4`ln zbLyiFKRrgcd#w?6`wc5>;T_0b+Eah}dCu`>2yEa;A2zl&1{R0jR zAM7fqnkefl=rIgi)!KFwoebH#n|AQrmWr>a8slbgr206*KGauB@uNMjE3Afq}M1&Zz8=0r711aJAptzYN!bi zlDtpmoS6aC89lt$_v5?XU*vjtva|Op_bPkswMUFE9+dVtPiuL<@j(0$J+`1D&m=ug zU?S(;L5we(=b{P@p_mtoPS=`h!uSM8b^`CoF9=^ELDRpj$xpcZ21t0 zV{;Wu@;%D-vG&~(QAU?F)#@>vV!A1Fsp=kamun)cF*I=1~uZ~#MIrfGVu{p zJv(=-bOfHb7zyQaz0`+@3lCwwk*;)(<9JsV# zd^tDa5^X@-ExpNgj|_)_dWEHrU=8; z+-wQBh|QTDA(il%AA!i{A=pYiZ^&lZj2HL7$8lo_X2aM7iAe*rw@ZUsx6%4hmxa;Z zM{Wv=Vg7MPP7U?CG-wPb6sHw$R>c6@HHc#Int!Y>-=UJS())7KEzG9R?T6{hk$n z;~lNM-@wlLbz(;Ud<5s86O+|9=@zJixiKpDsegd^J7=U*2UOuhPNLimc9Ra^maAq1 z<%CJSV%bjkoxk>vD>6Pwv*y*H>Avg`|Apv$|3FzMeugcSsLwxj+*XVEV`?9DZC$|1uL4VR<+9|Ab`+*Z-fed`&X{pRjyYMgM;&ERW{6=F4;FcW6cCHOje9 zoeR=k%HM>X>gnSptKE9q+Rs)awo*%*(p)EVbN>wME-XRGalp4QJm_?TX{*5lz|6Dk zz{B1(CWmx|3;%%bP27)`YKtR_f6m$7OhEBG&?Do9j^@qphwv}egGU~)FMRS%dH*nh zfBjeWivxgtxo}sLa~D)P`{p#ozMST5_>q0XFY*A2=K=c?`BXFcUuV6Q&pTeOHlf%T zlLBVNUD4K;;*1>E3g6X&{3*_ef7@f8UD5UziZk+UVIhOvoc3JMzQb{V9CYP?z>ClA zEGPDgyt-iYQoObHw34ViTKoz7lQ@yLgcss8Pd3gtYF|9RfB(-ACtr&b&l#^e(xUyY z>AYjS;2m{fNnYXBfrDq>-#^y&+66Ugy5={#CPkpt3ke? zb611to*$tO=DpjsE2a75^BWsTG%=ZPH`4Lx_|IVHhX*rNcHq+wjp->*p)4J*!>$I2 zII#B4R8hxaSD+?*{*5Yoc-NQQNju>@-)E7yF!~I3a`7VvJS*$%_a$t2wp|3B$Lw3^uY&| z4c!+(Cz0Br6e-;NoWwu1m5J7PxARYui_2_ z!g#8L`v;vT+5(Hao_w32+wFf0-`N_|jvEfU>OUaN1q_m8GQHDJ-CG|e+oI%uB&XOM z290LY@cw`RnK}e4^f|GrPhL+SMmMSN|4@g~!b30LRFMQ5tYyZ^9H;I&ej_4Q3P>@8 z@Jr|X*$dz+>+!sJaE0i$5Z*S5qjMspwgDG>4>{q3lMq%_I8{0nG0*ARY!H&ceT7I^ z1v)+2jA}G!>)!#@a!iZ;1I5?eH`nc<@EiGKBk@4vn%d-sZUS~Sy;60% zT76QYXj^(Z|Mtg!#qZzs!B_`Cm!tm5>|YGxd6&jMwK)i0`T0~^-Hk~YA3D3CXiB-e zCZWXp>%#Wwd9`P5(6p^VoS;xuO5$S9r9Ri0AvzfJa~@qVTqHTsoa=h@0S@ib{`-qi zv7CU5sEyS-bf}^G)bWPobT?CPBS|;8S_joiQ8dB;=j*dvhQC&UtrwxQE&CkcLkkaW z1w#k9(StkS_kJpXvU8oH4BrVPUqudqG++>~x0k+bGI77OIxE!FN60loZgY4D5m>So z|E$3M{+@66PfUA{f+Y7#j5eR(R%jMF#=yvG5r15>HA@%qmij{1KGxxdx{{Ll^d1G! zm|qh+-#lyYL|{V|=b@v-PD?t3GZD`&<30#i0P)B`xBr4C?!bqIURH~w?T>$O(N}>% z#PlU^SedT%;Fzfd0v@r(;-K&$@P`r|owDlekv^w@&e z+#`yvsl-TtTUGUNr|3>q;mqjrXN&1__{Dc5Lak3dAI+N^-~S~OcSNgSuKw>QjetT#$i;oJ^7`oNvSl)l zRz*&$0~<`uwPrawfBNCeGv8pq{U_BL0EoD*e^^Hat#w)rvqJhLZ2fzQ<-ByZ>;2@Q zwK_WwW(Yw}TLEO(-NatCSU|&`fGZ5A%N>f}SpN|10)Ce4dIxt;pF9c!OQX$VH7?eQ z#jS;igJI?w_|Exq^k#SN5c8tmspOeH3&fd8MI*LXLBVcGt&zj!=h0;e`R(gwQ>exA zna}4kW=RbP2H+}3hI>ON*8Pt}D!l8;6gyJlQT@u+ce#Vq(MNX*Z&n+i!S**DD4c$o z4G^O!e8717W>qDlnJ9#r7i+5DGdtL*h^onV){zz?-DoW}2}#hD=#IZs=# z#5NK(+#cH9E@8hA)a)8zaAp$jF?r6V=KO2NWpicUC&3;ow(K_KI$Mq3dm?8}&FP+S zBA=I3abeAW*ki=;?1)?YrizZEhd$T=^^ASkbuPw78y+gCL_#OpdrV{z6aT-)p-NfT z{MFnJ|CIbORjIPot7pD(+EX50jYP274KLWoZ0Meb)n4&=i ztR+2LJ{&A(-r(n${N&?u(g>Isd_qy1Tb0($AgrZ1cXND7I^4mV=LT8DV?r5rs<4&$ zt<9W2a#E8O#w8I)7Mr~Gk%^Y4e}eIHup%R0?mB{Gr@z)6seZAgDj-VEVMovGf?omG zP4q0&ce?;z6RFd>z#y-n^~5ewY^!VhUsN8a)rlgpRDttNUCwkQjSOMktZQuz zLIoe#KzWcp5~cbm7w)~YJr94+kl7;Wrvm}C2&ykPZ{3A*83!B$@VwsUerCjSiWnkU z(_kiY8(k!Ij0wp3nUTKe{4Qravj*7CSpN%{|H_b4)q7Lqv znPYUG&MKtBSr&C`W4Ej>fRz$tAS(qmzRr;ELTLf>efON1^NYLRe<3BS2eW`%Z4%LC z8ySdOGpb1wMnfwhKA7f!Rh-kN9B0Q^H0J1Z!ZW`uQ`%xo1^D*jhQuOVWQ(NG{2oMo zUEE#5ku%4+kc1mIB`-vNJK8}y<)pViu=%w1z3r z2A~q>%Ji*fhkvs73kBM$7^klp_hRYJyylnN`t)B&?iq1_S)AMK(k2?iNk1x*sbT)U zD-y*pCJj&K4GA@`;%-H*uTY z^U*Rs=~33EQ&vKfxh9|b!L6E8|LQj*{-Byzn~y)h(X9hegIGro9?pWIJy$IAbymPs$Ax zS^KX6U0AP{`q@z(p;1ZzN%S|zN#u_fo%zb5|DN67F1E4oA;1ebgN>2+B5L`U$!(#w z=jDrMYsOBOze=)}a7%!Srfhy-M+B`Q$(zU|>w^;mo>bJV&c@BtpRUsSi{C}prnI)( z4cu0V$518c1;4+4;{K|g)EVXGXbNrWbE|))25L6#CYo6g2eh_tsr{4i$zKBIaNuW= z-Bfezl?M_?V;_#J3Q&1IVZk;z=Sa57bP8Sn%jR;9CUcc^|u zIf3or{rdns`&FQ8SA$H@06Qwn%B#D}SyDjp$dmN%SC_A7x3Ez)?f(VL@`Rqr%9Z?? z>gs_(SW7x&^~HdCvSljl+)*vQY1YIpn#dxkL=N0>(dk)EkJBm(WaZpnGwRUEz`|X3mo6KQa#S0ZPN#iSwQ&(z;UF-U*MB+Ve z)0b9}6MIBA@oKuV-JuiYb^r5xvs^|_!%@}qX;pVI3hX(3YDP2tsAn}Z#juqnJi3}> z1I}s1j**UzrHxKjc2;4r99AoCRh??<67wu~V1-x(7x&4pN%=p6>dRG1%44|qz>k0R zZ+(zG0${$?Po+vPWjqN<{S)W&#|pyKY#L%>lQv0mS1n9t*^=U3Wsw{GgEs_&cyBN= ztLBE6=Da)X))YA#F#5pkx%*-qb1;>sB;2b^TipUCH&K5VtS!`zLKeEncaYXaIJ}Ht zupn>tTT&Xv8y@=kznDD*&An3JkL2>|o-e*xqjj=py+WI<>LU_jds!VyE?4Vh_+bfu z`K#wJR^E#SOv3m`oq1?@r}87A+6{K*s=m{hDcvb}-dXg!#l9!O)*nX;{5!D04@f!b z?>K=h<=Lp|U6Jok#coKdE@G?A5WBa|p9Ow=Ee4&aj;2> zpf4CHAx?ld-V2i+!91m*Q>PLU9Zo4q4xp8}bCi(EheoW%cTUx9T+`NP`S*@;t_LYk3PL>8!!rXJ zP_U-twsEQ8*HD5#)7;CN>86F=yJEHWUs3IU7Tmw3uiE*<^HB(B*ulysv3mZqRn01A zjR_7H4w0$k#^``-bk96!nXraD+6b6P5sdY?vVmDG2!??-5XE9db@#i4Y`>*W9bW8X z>0wBS*|=l37!UD)C5&FiSTZG+D(>BXazXz{qu}tN@^*Y90Y$>-tY6^WFl4sP>i%yb zhcMqlN>WE`{u$f!eOnB}PSSB49CWa4jBCGPCwOX$ovcr*_MAE;;vcC+Fl!;^Er`f@ zH%wuHEaft4EI=(hf>+VIA);+M>c?Py`#jPp0g`KSC%ZtDELK|0l@MeP8BO0KBwhs4 zFzLB_d115<=Og9T0eXAa!kMR^jgGqGZJ5N8mG1dH&#NTJh@lDKH7q+T zK4uTQdEdMbla_}tI%d;J`3?>vZdCP49R-zJwfUxlqRi6Cygf!ICwpKpz1sNTxsSQ2 z5L)rI58|+a_Fy^v$IauLu5M3&y%LD%q3!h8;&uEjM&Bf`z*8VpIALv_Q2AO>^^Ol8aj+hC1xCU z7pc2_Ke0MUWJ;MnH9I}Gqftz?vnOX>mxX{|9@2S#K~X)cGGPV3`EjP5Y@?hzBzt6w zhiRB+6XW5QOEOU*27#DrBG{*ab)0dNnpuXMH73147-^= zXruEa#A7-zQof?f>DO9viSVl3LZ)AHfU4ZOfsqnn1q|zXEe_s@Z#wURPP>gwA9h2# z*C@l-7Ny`)VkVC7y67Tb*9NCQ{D35kO~+g~b#3s|2v!5gRvqt=`{C(t;mJ!DicPxO zciQxpu~XL6@IbLboTL86?{;SUE5f9#S_kOgc@K2($FmvyVmf@<{gNc?#u3u_s^wGn zyiM=C#4s{3)y?!G*nq#4;a~2E{tGpYu?IlMYK9BA%pBbx_QQOZHBVJ>n~`$8}qa^(~9K+H9hF18zj8J`9Sc65(2Jyl;( z?4G+VL4zg=jSJ5GF}k9t;6r#^N`O912W^6tNQOrxezXL4D`LZq95AiPRMuWDl!1-H z75P{M+b0}3lCu;Az+GUU-oS_Vu520MjKv|t|4Ttq(zOv!Dbqw0OtQtP^`JlcB|p7s zouDE8g$B5Q5Smw;46QAP#alRogjK9y6(BP|5W(++m8keip&BNw0$r&}&M^=5Jekrk zHPvGPM_2ocAn!S6-FUt8Mu)#+!tc=IPY(buMUOX&e3|nRc>Je$a zE6ij;m5>Q>tf4ltvE49S->{a35KE9ww1%qxL;clhe=3Ax^l^A=nTdl!#p5dmnQ`t5 znM^PYOIIFJq@~>QTzHd`ul|pE*V3H)dwS3;!8EXIzit;$J`hGNtomF5X6MywT zNdH5W+3~V25E+{`-FEUgnwPBN&n=Udx7hPlP3|E(L)d7KXEP7yKCPpa@ zxBHh=0fwtQ{AoA3^)doL|H7yG91G_?6?$MIt)ll__Sf#G=T-raUTyQ}x905Vo3Ng$ z0N0pqV3q+OcW?WYT;sku(>SNt<=4StS%Fbh=keo4Q$mB8=@$JvZC+1Q7}D?(m$L8n zPZ{~V2=~9q2%eck+G!qV(My%;e%<^gHJj1Zpw7XoDLZUTZSnGO)zLpd!%M)Y%434MzT^kDi)GCo~F zK8_jAzu`R3h936=)r|S)6ku+7HxvmlJ^iL--63~hL*~;rjp48O%7DA&Wj(!4B{$#g z;X9*ah`*!Vc)Cas`LY+qXQovlitOz*l6jj%hjhAEV>NV+s>S1I%#hJLVd&H<#MxTy zmQYGSC=I{T97A_j?iIVex|rcvkJwJsbp+ljk=8CjNOu{*B$Ar>u^7+q^aP zCbSki_*Mp;4qM6bp>CM;2YWDb%-HnB9O6K5pw*6;JGglp4QHv zohqLXNGe}mcBE!x9pJSA?MhCs06yNKHaJg6WwIqx{ z|K3eE^!;+vi7l1d)%WSdjpZAio%`xKOd2U}YqE1)y^q`5FkQ&fiX6lP$DtA=KKTh0 zY8tl+Q-WGd+qPC}%Z++x@&`IM3~0;iSFV7sReYwWd&^BWhcdfk{9xDj(F5AdJ{%@^ zoivGT30!LEiKAQeBfuCJLwL*r+%@A0=K(nH?wkH2%lI|*_%j-JvqjNy_q>GC@W z_4f>h}Kn8>?1_p#x%QZT&Y zd>vQUhCeu@TPPLr3k!ykE4MPo{gpUdfDi0xvtnn8s-~f$=a^?ZO2#Ht(ve%<8R#Df(0S>cfE%zy`w-4#?Lp2N zb2Z9yjg+#azr?v+ec6Sa8`cTE{D*|fX6|zwBBh^3XROvRS+?DQ`+6^@9L}xOYB}zF zQL^7-td6d@S&|=3aBWA}30s{Y9s?W&rz|Cu7u3kB!CfGt6#Y8s{JgeR8u`vx9(kyu2V^>Sm7~^06-m;R zce~i=G#ojN*Oa_y<_t11G4kE>9frhH4ak0vU8-_P*-ien-Va!sDMm$i$4=u}fsMUE z>&DG4bvG2`26Gz^B@B>OOCC=-$eHIGKuBx(>F>g3Eg%bliiqP7MXpwccn3$xvL!#C zndK!OMaFI!{nlgavm?Y6ktSM(_|<6f80`y%<2eK1lRddy`+2(8yM?iexjcg9M`m4c zFP0NWpqfGzm{lihKQEe$mC%!8nvm?3X6e?OL?g|4yt3`hQ}boq@apO}m@@yQmydGO z3{7R^Y`X^eKJ=({(jN?X;K?a{nJ9N>gY{C?#iGGtp+?k@28OWEXAf!wrt zL?*7siX%+T*4=E4%QH}3m@u0-WnZ0UnG^+30ca5K@7hz1@@1EZhv0m&|myj|*#=gR<^lerZe$=kyxe zkOOv^_cc^Lu3q&EbyJ`CsOTSHe)6RHuSO}gT*Pi^WYuEEy|-DX!Dcb#(~W*KYHvO} zqLjWz^mmZyZy0#lN7;hXyA9jvM0vXI+YqGd z9(b7+`53OuCAd#UFD%kD@bEJLbI-WXl!ZxT=Q>m}GV~bHDbIgiSE_Zvggu0^Oi*iX z3^}+po_5g;nX)F%wHXs)QEYh}OzsK!k#VPbP(2#FHF}LBjtw|4UzdMJV=&h;H&<(H zxS;89o?v!)lnn-y;Cpc(_y%wBI3sH@$o|TSm6aATtV<70{L)5dvwma`{eggUfbdQc zIQ8Hpm3*E$YR8sfO%+Zk98{FKBJH3ABm%CHq}K*%ig8x!L$V|Swp^JPiyWeuv$JeBZaG?w4mYZVy zH=aJT=KABd$`EQ1nBp^ye=u zdElXO#sk`~o6V%@XRN?x>W#uW**Md3^^0{?GYzlxpNA3-HBzS|ZWtsl4L2l>l!9tZ zrXECe&58x~LY0OEk<6uLJ*H{`{K$n~lx?Grb62Cfc`fPCp5Xbulas;mK*5k!4u7_r zdVJ0vsa%gD)aX=I3!mWaiD*`*D(;pf3-n0z3`3=e0k%nB8+t(dK!Ay7nA++GIm?4H z{)dBRiWT1FfI4Qw45lhd;>^}jU85Lmaa;Juy#Bz9PhV1ig zAUcp*ZH?MZ3Cw8)KxTuIVy)A6@J{yGLFVOmQJ?%k^pOD`ERHaF$#`FdYqa^x&Ea}W zhlBN4CC@dwT?`lMsbp^qRyxR`AX$dnEB||SSi;Jn#f*PIHmA%RD~}j5E)itZdYQ9k zj4nAKtK0@5&gCwGJT_3gwuGO}QHD%C;Z`K#M7}FfdLsrfelT{U{^H*__qSMlZ+Hj< zmkP9BgvZ8lhm;at2qv5LRo)m$FrZ^=5>nB+c*gx=4tQ9PY9{8yK24$9-Lv?-`-t+e zXlq>9M>QDA!{TlJjEVD>}H-5{?aY0jjG3SJ**71^qyge#r9G4&m_zZ}sqGgB zaeC;@%w(kif7kupOrI{Ps819C7v5(wK%YG}&=d+9Z< z6cOwFlPYWz{9A*Tms}Iyu&|wEoLy3KB+>-k>2!S9a4+!JmqS!jgfT$923PA)bsL_H zY(U6=mTZ_N(!`6O3*f@eOK_n*?vRKJUY)ktxWe4j!v#YP<08x0y7OK$73%x@AE4kE zNCuQYI0jq3^yJHv0{~fW75@f}anMNLQXf!#8aS;02|yV)?S{fhzse?fw>^rKG!ANL zj_LY2Utr%h>vO-j8V4WhnLiiUqvGkyx!hMC`8vQ)FQ;5Auu8^EzvAVG0xdHYit*K+ zP)=8WrLS*+=t~?+G(*-VdI=+4T=tjnu2&T4M+!>VaAs)M7Ua-Ylxpp7^z+s{lwoGi zBpxhh0lnCdFTefKxJRr}3jO(mD+{4t;;ew<-jtQs2rnMwtWMrr({|J{9TY_)7Z`RB z=W}Pu)lros?TFM)e4m^gP#~8X(jYwlI_I$};DTv#Ka0L0NH!cMpqwxc5?`wXdf7#( zE!Nc`Z;_(_1^~zun&Jg_oRaz>B^RJLP0Tf7J?&qJ^6G)vo@G*+<2%2wb8}3QDb4r0 z1UaZzIGAFZLE|$6NXM^>OAz!DfGL{5oFwQcp3cDm&I>YzMhXcCp^yZQxOdGQ| zKi`6duBk7#G0_j3N6UYcku{gg>G??%4UAbDLu#Rsmvh+GRCH#RgaoW-?(gOXWcuprPgnYQw&ftN+f zLvhoIPe~;=jj#Wa-qMF*!mfH}P5v2AZpV8`B8nbchEIirGPK4DW!QF?In0=lq!s#7 zB{FPZf83H*`6T=^!tmjl24 z;3+d*<}X(8b=!XCBv7xWc6s$XY~mKU+0J&)6dE9k&8#R3t-~2k$BFCXE`;2Nd7Mdpv6n{>EIthspqdz|PFnVtvPVAx*NWlw!hE)Vbvy zj)C&A-ayU z76Pz7j5!_Ml7;1ix2D;17^Eji-cd1cje=A@Rq03BVxpL^tF8dk+NMHnwW~$rT?5 zd9iNy+OU6%<@{$i%v1ExLtW^NfNr-&2|Cp%(Y(MUrVJMDvtjf1|_WwrC0uAGVBTfyE z>}Hp(INUnwrz`W{H3yw!Pi_9)N;{b)K~b9exx6|G}1Aa@OR-*_(QC32&Skk?& zBU6DQcZ$xo5{7j&lHrNOxcQ12_1^rXLEH2zE^$j3bVcJ@9i~crIZRyN!=&-L#4GHT za$3>)-(sDZnHHZ~7TVknTn}_6mbbg}8L&V!WCjB?T78r1`m*T=SeW4}H0kiLs+v?R zg6AkQUMe~F{u{4hDSltHm7i}I*U9BGd3xzaTl$4c-WbVogZ1C&xV*J!@GoNh`5{T^ zWgamsoWSU2TB!<(jTq7#p3t^K4L`ZxTZ|NR&{)lXy!p6mpV}>3Sf39*_GlH`qk2wD zwvhm9OT=iuiJqlaU3opo51OLU)WkCH;$bAJJqykfL{vfc8`(x!2b`guPhiT+Z1m{W zC9vk}60|cxs=upZWCppGd9fW?ZP-qhE}T_FWjot@FEQ<=xahc?QsFw2%E<|W!ye?H zn*+v&DF-+9+h$z&nlt!q`P_yEo^6za8!Qa~UTx&EID(*2g85 zD`$4Z>Twy`Yur9cTW!lR9{ZIPLDiyz6ysNmFc#M!_2s znjZ9R)el<#ajK2d9;6I%p5Zb(QsYv^J)Mt zV7BUk2E23sdnxxrtNRPB283VS{q{nWG)BflRaxWd#by|2#tF+>tJX?Z4=dE`-)HsG z7Q2pBdvM`+CkVo}RiNqY7JN@O?;MN=SJO4fraS4;SVm~FFdC-TDMi_j2ojJPv)Gx; z=UAqSSL23x2mz6_UQ}NXa^WZ|%7E3$c;aJBrHT@PO;smEP)aKkmS<_jz6M394w5orcFH@%n=u*AAwvmFEHwIf>UGpxz_*Gpn$s+ zk9wh{P8hCtjv&lK2we(tbBRZfTrFb~?FRf(PfRlg#pt@HH*DHl#ow6NgfW@fwpn*X8uY zQc5@rvGK7zsF29iOn!T(o6MTCwAprGvmt`e^5TPev3M<|tP`1YSndo>@no8C0*%J{ zQ%g>}k&i+h_1%TZ#B90Zc=`@fCpCfXX;goJM!RGqfj6IL2rJRVaII2V&ihmL0D4n< z-A+`bwI8o$jaqnWX^Hy0$us2BE;u0eEBl`SEAI>V2T9}d(HD1NQBOBfJSR-Km9^Ia z5R;iINVm*>;a4?*SGNaYF@h5gC!^_>#fBaZ5S?#JjJ_eo@XJg~-d_j^k&C}Elzh~m zhSz_cDM&?$kv0=inxY{jarB7BT;R1>EfnLCauvohD7mXU2PW_2ny}H3=@^y}oU`Jr zl_`AP#g)&k$@X5OkfEX0WTxjvf-NH}^<}N^Ziv;jkD)gC55UP#hal-IlesO&2KqHI zM;;|VfTpGs=`G#vYmptxb%DLJ0#w0G?}iQhNd}tSLWDpz_NABq1`8`3dj6u0$C(Fn zH7!SPs&)ssy9_KH_N!E_;JBI6O_mkjmp0)ZE9m!E3B0Kh1qETj+0XyYEBYIB{?yIC zp4e9aJY#|RD?OK$+SktH%Ua>$a9B6wz$4PzOJJw@FdsKZcOi5J(=;?x{kH9>0;xV( zf~Nhnp4fzGatY3Rv*5w$xtZKDfm7cGu^pkkEd5?}^LL?U5P;54nD z<}|dkl*|sFx@`N4eOmSFd3#ho$jhY2L9cm5yMc`n@?eqqb}Tucwl-W(D>*REph<>t z(ylC1R)xV1%O7sd*S{I&kfJneR`L?$O=7w2zQUuZuDt8 zhQ|$b(^b*;u!X&9qg4tHV_vEHI>7S|ek3=?#oZ~r<}r1RG^(G8mkoTmQX)08QxynL zu6+~f9X0BXG&I)^F zckHL{KOO!O;^~eWE^Sip@KXvFON|d85>9GV9;6O;5>E-VJ<0gXOq^Q3^m<}r&9G`; z1~J7Fj`lYfZ?4I1%fb7qr?gZJx0AX!Sm(G;x4nB>V}6am2xR-MUG&Sj9Q24DbAE?n zmz#q)`NwJGGCO3thXE&ZhC@l}lF7PdS|P2N+xelzDv$h?P5b2eMAg6h+$5<20@~(; zY~Ia*k^l*c6&d7ZVWa5}L-Zxj*FyWA{C218ycuaGCZaW8nJEc0;Ci)I&*FrwA7fNV z9=^2;QVFYA*&oID46}N%N-_s|y{@ll1s(Sg2n`h0<4gv{-9}CE@eq4u*t5FuyLEo6 z_n4C4EmA>&&hHCMq^Fc6XmNqD-IZKY7p8f^kOl4jhy5Y_EmJCt0{J}gDCpIyPxpsh z*bEv{99nwAy8Foc;q?=e8{P1Ee5OD3V=E81sCCfqKuTaLPz5P-3{xC7{8D&BP*2p+ zsOx)o#yl_5j7PIZ!rPfxa=CDfS_7$l(jwC>NW8QSmmu}9G)E&cUT;=UX?eDC`GxrB z0hmO7FWLECn3yftES!{)&92O!S&9;7G6xDZQ-w!Tx-7xdo$WGR(o!~ohpb`?TkK4h zqJ+SK<=M7u56&3RWyn+O9%E^l8bHP1q*Yo7s4zTY&buIpu}P7@x(v;V)wWfl=aR8V zQ3}iDD{3+KvIrV1keG`F;edUMgD!+dg0?-+UpbKi4S@5G516(e#{X`J_z#|)rWCCF zdgnxti|6K%D~gl00m%%u8-0#77>FS^{m7;nMyzh!HX=IzY`+Cy2BQ#=&oPSr%N63Z zLgp!9&jrA;D!|s|h$~S>eL325WFkfs(ely>j#wBpKA6??O)C}5Vobb~d zK~tmtVyA~yNL!6OWNs_ee_4^hmVXhO$_#;>Bq(RT=qkBYmtHT^btYcaz0_)6qHSVa zp~GWf)ckoI;-Sq-hi1&LJ%eUyf?x#M0qfSxaIGBJ*9p8M%Gp@nF51q6Qdz%JajwzI zIyK;?^=8zgTX*i61`HR|N}y0KHdU>nDlNDE3&5U5Kt$B5W#jdyz5YRd{Ks~9QM%$p z`Mrg(e-gom=5^bp4lypi?PAKzlCJE>jAJm(LCMqWv7W643Bzw5H)Q~NND2tqLvUHG zK?NKw!r1b0t#&V1<|SZ;(ovdqu|Zs}XT*ckIe#@X%8s!e`G`7}zgg>**fJEEa`<^& ztbLJm+;Fq7gKqj*6~#opBH0`Nv|3#iCru5sS@1nb~3B2iY6bXB{)E?sK?FF6(#<_l?^5A)5Nu6nn>0r_^bDj^Ds zh}W>xBh1t(G6*r ziF%)tjKamZ6o{F#($W7mHuAg->>7_nRTeVrrnpuvG!jCvJuE|l$?hk>>*Jwx z_#r2h55J2q>iW?M5v?X0)aIB@|K)u1z^)7PT@G`7YOS>;XD9OQ>jr(Mh*EA2e*3pX zZ^i)!X8S9pv;>pO%U_+eCig+r$ZKQ4wrK{bn!}G8CZgJ@Q84w|LaQFf{u3?FzUixc zQlsL4yFYH81R~a{G?$a1oFoGBy$dJ1o|;TQnzC=yD6Md0FjZoZTqV}uZCka~uee0B zwrX;xR^pqE=Lp#XOEMkLm@i*MCf?FWet&GSnh)L3zW2PziL`y~vtq9eWZ(btppfCv zbQZU6BtzFcZ6e3PyF@wRCkN)PP|@Dd=;J!___i;LZ^S&88uRnttglX6{(9h;d+2kI z@W8wZ|C4lwUvD03lxdx8jy5xQswl_xC$Qzh<}KzcCllOSXPoD`?wSv8o%0vI*dI=r zrzzipr>Td6*e{<#sB&wwxROu-8@7cKN9!|x_YJgdSd1hiPFeAe)nTFHe)k$&8QlJT z%&$|$z6$6K-)dwkw42;MFK`oC9wzd`PXkv+0!~jngYgIAP!H&WH6SCNZMT8rDg!9O z_32a>8jEdc^OAmV0*tgCRo|Vhmvr>V5jo!epGC$`C{fpvMQQ zbr*YVCBFU@n2-Y=61Vln>R1DA(@%q_~@|Te2gcf!l9Dk~yw(>Yn6P@+RW) zG8wvYuams|$zSn$mj5z*9mV-^tcHWPZE$VqZKGxh~0 zwi~{I#Sax%A8kB3vX#qP8Y2M@&UZh+rRRpzFpEDr%jb&gvq&Pfu@TieITD=DKTz>_ z*mY0fV^E$FP)x_{S$ztzR#&pIJ_!#75UM+^vVSq#NDC6zs_V9Hl=9f=lbzNjtw*=c>QBvC zrjqEp%=VG+f;ImGx(kNV8>~~?LMcfjS>U4c+`O$@Q{N!QHzC6_;?(nn-X+C*zwLNM zHub=5uJE#S{YUTi<&mc|bLEE$t+YGi_Le%%^_Sr!?k*0yVFSms^&xVd<=Cq7oFN67 zrI21*CD|t8#J#r^J?`fXzZ8vi0~A({;ErmE6>A`=$JWn~2?%oe{0k=Aipw}V7$99L zvy-)j9hnD{*WHKesGS_=2k$tg-6=1VcRX-RoR4aqNCfU*;-81pvym}IqzgEtG=4B` zeLWJcM+R2ZMp7Ax#i>)O-0o z7X8J^we+gji1SXs$ud0t1AB0-hsu)*B5uGGmK+NT0=~|{XJGl(R0Y)3BX&{6JTh)P zD)fxqm9e^0M$GsYK8aFZq!1QNn9XnF^Q*WC6dcz{HeLegi1Gjy~jM3BHP69A{d~*(;L#5Fbxy(0E*<;`R?7jG?!5N2jmf2 z(%GW`ORUuFz%GNOm0#Iae95%$@#C?_lL-TguKGDqj@#(_5TI{-WtF+YF6i42T+wE# z#}oSNUlGcG2|dU2oc_ZSKYirQs91(un&#FXJ&I5^Hs%q%a) zU5}u@z#V=wuJOi;QiJ@BP7T$%bp712>5N_knM6p!t*-tdR-NXtan41S9Vz!;(Dyzj zfO2O;=sEGTee}wFz(sm#v@&bPopFN^^qorp^#<*bE&Q5Pdv$N01yhrzb4eLCPbK;a z=SSYfZ+aj_;IU%tl=hc*1DyS&OeK-N_-HaN7fF`J zJR(50w|_4v2FyLq5S+Bdcl%+IvYZ3VJ$ppkFFRz|Q;T73loocnrU{|sUe9R3BRRM_ z)6=j>5xoa0-pvP1))O^Ur9})A9yfBX-!f?V=$i`naAk%^N2g062ICRL0YqSm#K%Q? z_}Vo<|Lfwad&R2&qr}laheCjXAu7g#q)ZTf6YOm3*N4()DUIC36X@CPUg!=ZKSl-K zh;)eW`{pT|AU|0WmMyc(WnQ&??1As}HZOGU0@Ng62tH|NcMFcab20>~5^ zy*#=1D6{ynnqCT8rY5*@O^=U{zx9p`J;y|UBGO@zPPlCLZ4-LhBu}TOX=KEB7K|UX zQv+O=;k06uhg)adn>FBQSAz!$gQ-yi%5??eKwo(h-Vr&?zh;lNsp(BXO$|zC zFYbgvW*Sd8;M_rCjW*Gz)EXKZlK8@VOYA0F?^9?H%3ueh;B_Lga=BFs;!Y+J)%dH{ z&}j-~ck<1Z?bW!#6NeoKtkuY?Mr4uciI&);1pD?IYRmlm$mZr+(x^==IfH)3q&3DANM4p@*;1_q(^$zodm{HyvO$C9UrM^4D+u z=L1lsJ^ssk?wpeI=0&&PnkJAoR%gaAL_CU3ghP&^3#B(Yf!=Rtr{{`MtRfs|0ozpP zK{CT2*8CAZ#IF8vmxuiYoMjZ@Py7pDta3^(PE#D`2^T2f?FADnT*gBb&}J$H593r5 zdj7!Y`6|MEn%J_E2?35x{a1}kC-^}h85g_Axgq-Gsyn6CD11u^kYBHB|ijzse23alA zHjxBth~c9K8CArdjtb(NpFlD1J)19oQkY7VhPr%-KN^tx(lWF}$&nb|`Dhn?A?jz> zdrGREG;4_<)?KUT@Xnjx5b;>;n%iny*i@L^`gBArO$cFSIyX>cHw_$>PN9s#BP(a` zc0Y2up-MN0*ruX9y?K{1lvQQ5ofy*{q6rX?I{Tv#6{iL+Hnl?4b2;u3N4rkstDHha z@5dW}-7RE%EofOd-sAI=M9(9`JDxAja(pvoYvL7UM6xAprG*P#HzbBhSCnY=4bwYe zII@cq{(}~vM{_;a1jd@|yY1<=e-dr{(;vsa_Fw<`_iy}B6MW)>Ilp~v&g8?^W6iI##sFNYz*wgpEax5k~;ra#zy9&}s1*Ja`O{@MP7o-<0cjmZCBN`82 zs=G3n>qlwyk&}3UCO72wGZmpQ_jeBA;)Q{WJA~#gz<-r+|Hj+og#!kzvysW%XSUJr zC)c?Av6`fMv9H?Fbo56F@CEPZl@Y1u=RBkEj(b1*_-%`ck`ouFTG3_&oM=j%NW_>KI-;`7<-?fx{;b6nzJt zcS!Ja2LePAOlV*viGiJPFUT7mleg8K>&-KrDu$nu$aUD65G}t8D0r8w0~@Ey%Ywm+{370n1zoT#QZmjcJ(ZYF-*1k5{tZ zanP?S0DH{2*FEMN!|}cgH8UAN3A2^49{!nbUo$UA1<<>ExUAz5tRZS_W}$2%o*&}^ zUULbM->G}Vseo|G>>m=m68izdG!Y11PyBzTF8Jdc5~9zZ5jZO)w$Yxkn##3f2WA|= zd(Rc=OKzK|@m*r=cF+Zt0mMkLXUgo(l=z%oZ!r~hNb79d{mnL5u&R6-i!jhPX&&Pl z1Y(rSmn?Rk0qqT<4;9g!wByu&Ml%DG?LCeG3O*MzUEVGVbZ~G^!00?!r`bw|&SHRq zA^q_BnOrE{+_!07t7;W_R$YCwux^bzx{ zd^){76knKLQ|*Nta2$QQ+Y|U7Nn$1s*(}THzBCL3ee$&Rrc5bGmp8`Y^z#EnnK`|R zUehXh(5{Iy=!x6V<*?i?JtPuIk7L2>KGI_XVnF{nt;y@aS<@E9GHx3X`O{}TpaPt= zM~+T!;Kpkoy60sEU_3@CLYA?m@kQL>)y3LVu$R0b1dUUAT{DoLxHV9P9gk50&y;wx zSY%q;hoItI5L$eN4F=E3C*SyuRQ?GQWc*SDY1_8{vwz^aA2rfTVkHqmaj~)f5m

ifR6TknlM>`Vu`NBe7hyl z31Bi@&yfEPSNA8GteMDUW!E@g-90w?=lf*ucN0^o34u259v+F~K$(OWbbZ9nZu*45 z`kewsyUpu4NQ-V(6yK8$_3+RlzMXw=rO>Bha8E#gQMO=zBF4V z22rbkOM9uRM*ld${tOi+d(DDyEvdmkp$Yo(rI1#IvvnnaLaeKi*W$Y)sE=a!PO4k+Lyl~EDvus&ADoBiu1I@uRW@j8U#9lFE-^^w=3GjblIRKfo!4go=#sru!p#;Ux zfuxA>TD{h_{(NIO8aUd(LWH`PlU=m55w!)lTbF#ivCRgOt!viKde!=02rg~2ezvn% z++|xp7nhrl!m-`7!lj{NB`yQzsrBixN8NzHdGFi=DXd`zO}J-E^!w~-4t;P4ujV$=8q1TNyR5l@!+QJ-+USXTvS-4YwU z*x^F+PMkL7@c`gpz>U}W27rKZr4`MZ16+g(_E)?D8xgwfRAy2_E95+SSBZKenBp`s zQNoX81-#WO`i{UnUG@b&#DowMs}Ku{1TII4N3t2ExN z3cZeY3czoo#kL$`H>Ne9moO!p4=&cNdv2Hd z3K+h$y}|&%zbV#YK8P<8Cm6r#R1jhl*Z0PbrD3VS_8kw2WB@MOL^n%VD%`WWziDX| zOF=8P^7<4{e8wQW@v$8K&2NO{#N-g#89^{oVSWpssb3;T)rxYLaKaFnP@fd*9|guv zdg;|S&xXT6!{t1I6S&b;KqR?UdID1D4KISPLxA%}jQRtBAYiED%|s`k1b z62fi_A)R{ls5DH2hSU)72?rotJH#F&Rx$SDk%ZHehasET=Gc$xL}gJ}V%2|^2TZrf zB!-olT^J~0nFfTXfr}_uf03wPP*`*%7VU{e2L_3(YQ~mqxBY+rQ)=t*4<7Lsj{t&V zzx;Wrlml{rCa{JW+m8T(V-89V0PJa68hx--e};PmZOYvia9fHpjZd#AghHVb)UY6Dk2_<(}Hdc7w(iqvgA!7SUd^p`?uE3N~ zPn7iKGs_Cj{8LGx%dZo)iMiQHF(y^^v8Z7JfL^Yg=H7|hbTdm6xZM}5ZkHiDVFLtA zmnRN6yg>!h3K?nw(IKbWX5YZFo;cxB2SB*?(3USXP|vIq1uBp@!a?aVM3x$M+pcsS z69CZ7>o{=jC%D5#)F5Nwb-#ySwFP9ERKZ^+795x;l?HejiitLTZ-1RujsemjlA%Hi zm0Z&+D~??;pz5-DSDO+bjmqzx6tgKODUiNQja-*>j0!yh7o5p59v%VmskxRV;4MNQ zyfLC|t6VbkZ6|BL9c8&Fqu%JfWn-NQzMUV%IqSPmCHGY(^ML)KQTwv)I(?eeU-cl$r z>3BC6N^qYwo$$Q1byj5_+Rwo`whGG_H?VJl&aMDvL|t|-U@%RdUd9fI8bHmAj{LBG z5sx@F3O|DYBm*Z}K89DqdQ%rcz~fM^1YJZ?uf7fw=F{U-J#!P@%kMVJ>ZtTxe=+;Y(^s10J`MsLiHZ^or4&@?r6Qb0&Zr`Jg|0o*@D6j^90UEAAT1#N;X z7W!~c0${uNp|Bf$dD}(T-i>enM34Q27&wxGmfmAF@3g?yCVJ-4@&uVf#im=;(Bz08 zM_>e?e4w}rC^fE3kDzNvpqT(7{pjTFR)QWgKukF*MB#pj$wD;flDlt)Q=S+lg%UGV zMQ-3S+A-4l*bBfN+Uq_}5vyx!Faj~MAVsvg5~~5Np#7O#G{7-qaFKENf$>L;5<=UfA&{KYfTd5_Y!$Lo=zf>E|HtV9Qd&ia z+!5|G*=6-l*MX#e{bwM}aCO?3DgFZHPYO>dd(K=1kyU(CCub24(`JTBs+s3ivX z7$d-=hwxHFvVr{1tcA%bnKCL{$D|He2{csYf%vB%S)F+DdP&_)G!@DhCd(5?}u)p5FT;dZD#1>{&83u|~e#MCp zw(t`#YIRl{rRcr52ME&|qN!z8++^GEH)(bNsXse8#v|~Fl2!z@T9b?@GBU|T9Q zWhKN(y9-N#sCF0^+xhX|=kdP^YVF?TDb{)}le zHR_M*Ddn!ECfhFIz}HJreMqIgkby9jis5AY*;AuW^VVkMd5&4;MBAzf>3b<%^rI3v zaYVcK7SiPn?`PRq`WcyH+E132`f^XEF0~bOdypxpP4x1&y>`U6+>2HO4G*81Z%M&g z&sxqx2W%Z(DkG_H@amf?F<}MH%g+2N+qcBp-UHhC2_%sfIP~iWXX1B5*|w0B*~qIMV{7NqRpz@< zSEGHWFWf$sKI__9UIxRlnThFKu?zSMy_l8cq}n?LNgu3h+il9DXL%w>uA%yJ`MPTg z?mWCzM9tD#S5~H7yRmfApDYC}aD|mAg-ms1ef|FPmW)IE4ebU}JEG0(PErbgo*D0Sin*IVJR4Hh2Z%OZfGgl~*83?7p4BlCW;RO)TQ-pVDGVzFj0QYI!48!OvAv7|eH*etg)8gf<^c0P9X#Is=VyYk ze(J^Dtg~B@0Nvg|h_13UWj{sB0}?=tt0L>A-JW2Q1<8#l3&BIWl*ezJ&UEI5PO>G> zzPI>YL)7!8nJu$^1d~+ay#DFi>ekvcG80lNBcE&99BVuNxc9yb{vgy&)k8>Axgz)} zY4)Ahe9RU?(g4*ARQC%6;T?fXrAb44;nU;wq1PRt%n*h1kvWV7$-4U2pm8aLnD54~p(U>Qnn|4i}w>UE3 zU=dD(;slkjR5(`HYSxQTW*~nywh^5J>eq=|a}~HI%`5kwRh8oAk%&{O;KZxL&5h6Q zPPqvd{K7o^%1+d1tkur&4L7ZmAe+nU7yKiAIKKMem#?CV7sMR?%ym$ns8I&<1ulxR zf43&c`Z{2Kkx{k2*rxt=E70$8w|FXGe$5tA^3d;6m#*DsGS9 zd`g&mN2O(F4v!)lbhc0J`f9E-gO;pGvu{l3;D#ZCNNv#p9yhy5JKnMn4@u&Fy%~kL zd{E$FZuBpMD|2PC@NDgnnPPi>h1L`%iS(P4xUt4*oINa9l&QnvbtR|Bsi&6cEQ4w+ zY}zsQgYV<|;Hy<&yw`Cas9~%b!mAvlFhrZ99}((mS#=(V8egBCy-TQ>^6SJq-%$f^~K+Qm04dU5_Nc&ee}s)KlvC_&FjMCw8Ecti9tVvc=ZWztC!}l0tq65Y zsM|TLh=~@mS-3Ha@EtiZRmQ0m@XJs;b*jeO^m~Jc8Vdy8fv&()tA~%<*xrv(m^h;S za5NI(QpT4V05TJ1kBYi3p*NL}30FS5tXsbMfF3i$^_!eHT>#+}ZoznNLFI0~Q7sf* z>bpH&{6*?b+5^%{k8rAHWk0BA0a9gFPt&U8H| z{$vZ0jbt&KU<%<9HJH+M*1T#d@Pm2rS5AjAWS&2+n)2!p3OT#-^vGeu7Nf^g0^tW2 z-8JUQ!shujW#QeQr_xIe(r;aKO51p)w^UIQve93xN-{RN-Du8Lngd60XMavLQX=*oIDe5=VLUGBzD(2CJ>i0XCds=`P{!nZ41xC zAgZ7yIpST9ed32tiFx`6cE{+JUFV6o?@Eqg7NYCii)h&o;hTwsk4nCIdN<)a4?TZ; zM;Q(fBY*xk$xLwz6eR@TGV^^_$w%4ZM@d6Z2dHeJr?} z+?@}$wDj6q$*1IHBDuoLH$66;FRawk8CB$8j_cGNf?040(7MPDu3d8*Bh7|zC*1k< zS_y6D!?EC(;nHc%s3^d7iSVkePXk!~O-j{}?6r@^B=swzeIn5a*ujHF2X00p>FZnb zpxW?k#5?5`zAio*r_zm~3&?hAoDVd;F8Kt-xz44$X}og$D2{@z)623kv{ooFLH0)3 zIm?650UBe|XsB+qFWy%f+(qMAdimFUmz!-7PczWg%R>olAYbR&?nj@mu05M4H|nJC z<&IGVbsGbw_W+qcnWWyj%Uc>4pZc(01sXX#?Y@#U6GQN_yg#4Cb`QKVXyy52bFIJ~ z89VDbMDT7f+nKZ8t@nWg7WW{MKgj8p>@MIt2mo#kO?Q ziBC)V)bn>MuJ?~<tFhuEp^*Q3zK=-VF}JsvS)t!6Xb$@l`R5LfjuGrT@@NQdN?tYvI2d_!4VLzlZv zX0(w_bi3sIf9U=9ACv!`s_R!1Komq)Y-;G{&>F&nBd`*P-6|;xFV&?n#eNbBAycKT z!Vx0{P-3JYal+hwhZufaDo)rskW;-eT~A%u*bYm$e@t6LUo@e$i}5bseIly(nMrOO zDAtvK&KjY-JW{vh$1TiU(Dj9}eh{Nyi5(_%VS}@SB?~X`&Q0Jgx0QA&qj=~>7~GuB z{$1R*E~r@z^(QSt~Ospvo>K)G7&xYlQ z(XsR~v*CA}KqH0S40+p!9VXqUv}3|RvPLQ!MEjRn0x@Fy?c$8D4!M<_3*E2?6~}X! z`(;`eXn&-Vn~_1+=f>LDPaj=%`MH#yGrOQ~((3JX0zQV5h^F?3H=BIiMjDz!fZCNh zuy;=Pwin*^^PO(u-@mD80&JR`7CFl=OCK{8$cVJ8V=T3K=dr@sw<_n2%&%ZmJR8Dk zvmoE7?fCbz*Z@~F?+F#`;|}`#j9>%gW64pVh^!>5&~1-f^W&>R&YuU0$jb-$AsdTz{CA=D_4j@C?$hSA7RHUcz`j2X@S3*F4g7ZXq49~8mzN9C2z2o1zIc;`>C?3+sZeIAZ zYWU9&zxBt*IHGuno3ZKHk9bHX79%Hz*FN|;DY--AiMtSskzH~sw7wTB_y)}&;b#Fo z60S}D_{Xz)dtZF`22qdfyBCtEM=S(Rezl+JTj%m`AULKH^~gU!*-ol|fbs<{`v)j{ z#pHhrDC^>K0S$Xa8|{tXe6<2FC+`gx&k6)eHV->oRq|`DR;X1!o#v0JyLtF{MPgfk z<~wywDkC#W$fhoh-vJE#{yjDf??t4QfP&R*OrT(XmxJAtIUo&}h^(GksnnasMc0u*8llve06zBJh@$bS5jns$m8i>@nHnEShxx~A#_$2DCV z1Lj2zre|bUvq7s|6v=6=Bp*kTi0+=Y=BrB1YYF63Fr$~KyY*?ELY+(T)&l*`Hv<*b zLhV>k>0Wl%$*EE@@F&l8EJgVe`12gf=A=>*y^!Lv(KPgms0+;Z>z4w$y^o`~@}P-t zuNBcN%r(F|#h-Typ$s>B??uD8ZaoKbUI0JTiD=VzoWSdiG9KQ;%rCsuoDmk zSCHqHyvy!{pPVnXu}SLt=;U=}z?R3(y1M2U$bPy#_E`I=u%5Ksyx6eJ=~%f zzP34|5tbLvfAcp@PtPLs3C&BeB3Gyp9%c82Uzmo+g{xfXT9a{L%GyQQ-XOmGZe$xB zgq<=?^i)HKkfoz=l>zfXqt8lFa=yN3P=YKCG71s+WNDh((pAn~;iSUL5l@i3!;?7{ zAym_6i+q$T=dc-&ungoA042P-)=Kz2?suT(177#*AQ>5>(C)e#T7mbhOuv#RF%&FCy=3jV@QGgsaRI+V z29m*(sZ&s$80$m!t!#8HXe#oQS-ll4%evJ=)q9Exi0j5g!VPg4$bc91*}lVaHy+xR z3RCvBhEIp~o1}J>GM>0`E1#dX_4pIvg*%seyNVq>9bKvytZ1%-vH~-syLh>JKY~{$ z<=CGv9t#PrHK$3=n9-dhOjWyi9~_iK)yzM=SMFI2;xFPzGU=v$A|7#~Md6Tm*@oz_ zk{9_&h1AiW^d{+8j`0$gYeh)j=sJPhP-?7FV|X&`bN<@=JMr(%T?!)AZ>k%2&9g#DY(E1I)wU1#Ys8-wH! z4|sDjuiY5`6BcY-&P%Nbns<@A1ipdc6BfCEb12)ArE{@Rms7VI09o)sTi0Y{UW|3z zkBv@~tW|4Jem^8`EF8$;m|M408Te!v(-_e@uOj!p1sw^Rr2L9eY~}$0YJt#cEf0at z3!mAw^{uspyX2sLCVH=xb~BHuB;Jvm8D2ML#^B!-uFR%;-(`1x+JBV=Y~{ zT(R4y1X^kinKZW#H&nlT$*(o%Nz6mGhGq2sS>&9K-@MR)?WohGVIHFh%X97Sj2!BV zT-T)Wb#`z_KYzR+4=6XIauVgt=Un0(=3}BKS5$k0mww1RUEKaI&7lgfBzITmjRHJ{ zklJjXl6aNEZqt^pvr~&TXv@~ae&?`_9Uj_FU73|aEIaDz+Rv?Umu)qHyvQlP);%La zAtT(_EC#(&{%q*K?bAZ`6E)D^#@gyV3H*gw6ynqL#H0SzNtyO7#=6o`MUAt1+9T# z9aT%91L6WRL&TJ0#T`zv8Lxm&-zix^ZdKXds@!+44b(%K{GKpqkFlK#FI9Z)I%yNP zE3)uaMGaxN{J9-Ux)0x6{8K5QN`&X-9{jTVDUjN8k+Fd%I#<1JKQ6d2Ws4G*RbV}* ze9Lf-y=b)IoD;t&*O}Ce1ODjNl#Je>`9P!kJF?O(jRCdwj-ENuo0=82&dmDZmcIUE zXP(u+;}_Gu@T}Zg=Mr-L{%j9#75>I0JNr_>K#MnHflud;S3S0qH#g&-UJU2ndiQj+ zxqms_5g13hbcnWo>aJCXD^Lcov`XeLG5D@5IBm-6^-XYsg$B0nS9j;_r#FwYnz7rwD|-$^P*e& zB0|nJtK4{eOR-5R%gO%c1$$v<6UOPQ$K@!}kyG(q3x5o1R9pa( z1G$$%ubz0)h5Tez^f37x$6=35Tv=DhvLXV(v%SbRC zpnf7Jk|Q=^$A6_7lG(;3<&rfeR23%a@-KfBJYN7uVGgm|e}3S?cPqQTxZ{64dGZpm z+dn#)cl&g*FFfpT0)O$VkLAPwTe+ptquo5b4ZGj_ikQgz{9j1q0Rgs|oPgjxmgyIF z{>4}%B!}4TpQB|#@uPC^ORt&D0tDEyD|jXMX41a+)Gw_;3IK(Q?jNA+IJ-Xe$R`K)Rhfc7*XFTsgrSR}~u{ms;f6}ivWJ?&H zgL9txa5;=`mXW(%ucZU;U^yU$QbM`jY_K(9P2F|ri;{}?`%iU;yw?W7{7V<3cUG;? zgaCH*U2QU>{U~=+psQ%<{+_O)8iC{MVy6>O88KX6-PkT{(D(t{G19t$+7l4^rkdL+ zwwYKzL0}a6x+**T=pWs}zaIp<0xa^+PIjEnKQ!4Z-~XY>KQ!4(fxVynpTo&w_c3^D z*DhsrfaJ)Pn?O>fcOac+o<@zYJ90=rIbQ?mRvWCQnX;t7aY<>_M#T-&;@bu*QiaB~ zDwka!OOt*8B59tIn9k&!OI}`OZi)aoCOAqMs z;4O*TJr-4!K1Tw))&~ud6;oLqni+$LoEdr^h@q}Qr2)9B23d+M!3{x|YRI$7;u0b@ zPl&*wi$BKIo}v)c`Sd8GVuP*aStw!Yd_p@WY23=Q9B zLrz;};qy9V+A)I$3Y}O#NwKirZtaTs+#c|poj|;VMLJ(pYCaM!)f1P58ic1W-ub=e zz|kRpOY?L1XkQfbqD;@EOuqEM9|I~3<8dhXZz{3Z1 zM)Ac3{9;jS^vH<7dHv#fqh?hj_cK86=6ySzaHr0}#yK_S-V)>m7a+ zM$>=RPV9B?Fd6!ani=begEpRq5(-W5Gbw&)EL49aodz`Yo9BFijHmtte!cQMJ$iZ~ z+aWY4(=2z=WzIuQ_d|0>)quBm6^+KPzYT4z^H=6>(|~m zgwE#@;yQCA{1UYu#Ur+&@@G8C+-M8z!532r(Uu8o)@#YrGaR{_xD3a%_aYt!zHk`~ zTJvP#3f!xAD{wHM;~d#{3YZq#fM_l9q9%GTPJaB88XKT0wj!WwPvB)%?SVkRpRXSV zC#jMtGoOtd2u|ZJ3-~k9;*UNr!!F}XTZN%a0mhwSpH>(A+@q#5yTOW=ysd- zHqRkxwiO-D`0j30K=}}uBQ;$=^?rtbpw8ny4HQqCh&P!}OsU9>7rWgk{wN7!0+9p3oPSh$^u)}y1VI8JCkvm}kwsk7wNs4j0VMQzp`szm(qtp)Iaocz!@ zzPA8|%4H;sbrX1N9FY=Q&n1^Tzq({ZlhPUt)yu>2&O^6JBmS6 z3mlK9RLms~v=zg3`rA7}O;{1g{?Hk{YBXf|k&+p-nLL&sbHQt+oJYnc~pt3^d{ zBY|qk>9^_(-s1+5MexoZug~U(HNGuW7PSGS3@8I#mH z-#Z~efK#kFdrXbo@;jO6u2e)fk-J=%GvZj3m-tuE$VM3s5+ zwLx!dT0V8~KlWX2fi^vI8aKB4Ij3sk9`d z2;~PaFHvV%AI$?hx(`oUl}nEeh+fbz*otO~_0p%7sy@|b7+bWumY(ajpu$Xbrc2!_ zVrr;1!kuHaf_8AFR)-F1fJj1_SKkGbhvNi=au(*H)1Jtc6qm&Q%W>pkxJwwsgyYR9 zNy8!6jT^KPjgU1p1B?y#WHN5Xm}MzvGj>!VLEHF=s|qM3-@QDoNXVRPezp$ws?_@K zMap}+H+IZC+kC! z1!@+ya=$2rkI9Hp1w8Y%@Q+C+Sj>*GRTZj?qzx11 zXG%=7o7R!uv5KcGwKgAyfCEe5S47h!E{~VS)}U4mL+O_aj&NI6tP1%>i&VmisU#hd5n;OV67wd`k+Z4}gHU6T2hNVFiS(^=h8kmdm~T+~ z`zs4?Cl@j%IoQQeJR2Nm-^JV2HZbd*38dDGWe|UGiX{8?^rNEZ%k0s7w2B;;(km6) z@cDHxZ0pS;uIW0_IC8qm+4AamRZah^$TcJC>J#UxrL%c6#3)W}2#%GY?HFi~M+_uK zMyx2KqO(1hjjJ?_&dn?eXqWrLr*8>W zA7hx7Sn|?ds*X`pW0(p5R7@q(fMM z95A2V&|uUvomq#(E~I-6Drcr0-pcJv(37cLld-FsZb75WOmV!lcuHTlVSNWVAs^>* zTYtL%lVDGQXU5()`(Wti$Kmw4;Ln3L{4Uc=Zt15C<8X7%7G|*=>l^&~eei-z82|IS zu{bCUP7oFL_ywe#=Pd^5LRkFjAcxs0nzJvrzyp|#Q+ni)-X0%IpYf(*H*`TNzsJlu zEYR;&g77+1a}L#%XQk)|EnT9my?QfDD_rWDTB`*W%`X<3sz^4Gh`sigr>>-9yOcsLNkE4 zr!Z->d9*~wtRvg;Y`R`F{-LSiu#;FfG}c+!4Z2lF;BQ-Nzj7llte#w#fp1kOPb?=R z*t0pN3$Y@&ibPCY&=ACSHQNX0v`NLOl6TBJj?n9+SH%wwTBA8uC#=ON!c6iXdc-O? zG2_GPKt{wSeq3}1D=cDYz^ssT`DOocEzUA%rcSn3gWf(OY|ys|OU zxfZzO73Dp!yw+VBK44>7PdI~`b21W}2D}xF!nJoe0`5GnX|xR2_o97li2*+K;tk3k-W}hi&8Ze=YXb6!K6g#On&&++!lKpII;Kuur!~ z@C9z2(POuZEacpl;noaCik3<1r&@0n_0C9`^vy9SKCrqc6wI>nKv*JVMC}^M4aFpF z3AC2=jOQ|Gvg{Sj{<~EX2>tBnbei5v=~>xi3~|*bGGdeXO2X%T))d)v4L4`pG!6eoYSCy&dUXVsP7r`d#t}=`2 z{xpEqey=lI&>SP}+#H=iU!+1aTdw~IKTl(jm(cbGDJis3rM0T8v9wWAf?bfgX*{RB zsecaD_&ll78n@|H4_kQ7Fe14!I2gjcxt>xY{M_x7jgcW$K5scyoY+aIoiyP{oP<(^6B?4P%;2Mr*wFGEjcWa_!9hEli`5;mGK3Kog? z#am!}aYHF+jVezO4ZESr54{dvBc!%RL_t*}bj(Ul(=&BGFt`7d;sasPTUYnYD~v6u zA0|H)zJ0<+-;IIoqnbTU5ww>V&7&Ia*djU zK|cG;F#|g}81#Q>C!aEFiCMBQqXtq!Wk#l+-tG#FeGICucju7*Y(Y8J4*!nUA}$6= z1a6LT<(4ykwI8@T9ui)3Ew{AXPbvE+Gg4rYe|EB6ApAp`zoHwyt!)40jzb*I z0E_&ylkE|ue`vB7Isee)ADZl?z}`>(@8M*9`gfR#*=`dV5_&!|$kN<*%fi_BYNnYe2x`!lsNeIP{tvHQBjb6RhRqj zZn6ZbJP@@>g`AQqP|Z0k6q2R=IE|{iKwBu}Z8UH|p1JYIIerYmVIIiW30u=s46>bmx~B*C3+~!mH9+aBU!wXCh5r|SK)ir5grSH+?_K{3K~ri< zlJ>jy$sZ0K%syih6QG?iQayh&tTRShaAxdGP_sFM81MP2G`@w@d~n?JETJ-aP)-KM z@3_+3ywgjBJR@3lHMJcvr}h$)kI3P(+bRub(pJxKVG4CjQ4?5r@e2e^VdiWIj?!-s zEgLFEwm=p6@#;)rC0eswQx7`jsu%RR4aHhYYBA9|XI&;x+8IJN<2W_3fs5m8{wA3# zIid6*mgmj`*nlzbp)#2gU2a1}mCWojym$NEcEj1`g6_)-qbTM977JsYaV7nPpw7X8 zfdHjM8Vw%7QpXmUKyz;e>y864^^$nE$)j)IvvfBz= zM3DGNOn(;iBh9^yPo`}ki_>Sgx0=eA4l(8kDQ@a{8ths0fuc}dV=T-yl*w}pV%k5- zd$y@bJonattY=TN3JuI{@U~G3@*F^gP|meL%3kUzcmLuKVY;B!i$JJd{1rkbbk;Z` zy;7^8T4i2N;N7N4BqBgC4`l4O`Cgk-(X;_8+1s>Mo2i~`Sca_k=4l(OQe^bs=*646 zcQ&sztKsd0&@nJreY;ma3iW4${e?VQgjx{3_e4?U~+Wy0jdl?r)Ezk8nyMaTGId7>p)e!qmM{Df8h;f_X%8_ie*-%CWd zhuwsAIFpEt+&T8%sin<@UWfPrma`0&{j9XP87HFZ@puVuuel@nx5RzE%hxqN#A2MA z?*AGF_KgGi=2uSuad79(p21VDAczeY=5+2tyB345Q_q#6<)pWE47yHC!JpLRe{0r$ z%$?SMeY)r>{|xqE95`WmHP?uy0CzN}GQgeLBY`PBR(}nRJ`Nm<#^u!~3LK>DAVcVM z7`3X^J-%8`FiQv-)nJ|W)cebdmxt6@ES)-%&73T=S!Wt*1UXxnm>ZJg8UuB-FOa=S zz}bxG1<%G9+u>C*JH)G^6jT*W-R_LGa-U@=na5$w*3gfl2h3H^{y7si-vhfyIgKT8 zE-*7a(;QipL8dw|=%mTuVd7@EsBLQ$94qV>MpFz@4h3?*-NuE4gJqUSbM|C`b_taO zBpyI|w$#*icpo0d0g@R&cK6E1?kSe8464CgDWcBRT5bB2iQ%-7f6;;qc$Hgm8J6l{ z!&}krOq!X!Rxs9LAB=p#^oFOTtGSpl#Jb|08wsg`-Ye;&E$pBU)rcy6<{30UU7+Ap z=~35~gQT5hsRnPxSKb6?V9;J~-Qhh+Fm*09FZbTc%v)Be?n~}#&NJSz86vK}_~L#~ z+i7_OyE2QP={)WUxFi7?5%k#`vB1+-nOJnCXO3W+T&9j{_q~o~MN4gc_q>8}wx&FYZMc)Xwa^4(? z9>XCo7YlB=2@Q?xO#}?H9GZLm%2oT~=_Fp8WdcX4oo6?T^Q?yBQhW*f`E<;cUmOSQ_GNyc^`IqTmzm z!4@#f@a%x%kh(A=#-C30SMg7dhYV9ER}7y<@O7@F@c56`O&k$MB;lTF1()(ab0%i9 zN)SGhag_;u?a`rqwm$e~NAH0$*)hT&bTR4BiFsVJM0`MBz@cXqDiri9%0WvLg5O7uWQZ_@;p5#T} zuOBb9CNER^XE-jFL}2-=vWtAuXBkT77kJSci{1>;dObH z(8>zdW{O`s<>7ATUb01u!;;KEaTBwKaftCfYk7{VQ~4i)t&+8gg^IQj$Oxu-{Svg7 z;W?bitT)G*=+veeNU@#wkSo$F4S|c@NVsn#HVb6o>`Vu}w?fiIGHqsYar#!Hcx#!^ z<_o>XV$P%U3=Om{Vws5=YRo-2_V=7c6uD~xf!PY1HpX+#<)UqgqRk0mtOoEAAC|4k zLS<{BsrCiqYnw4x!$~Y|Y*6De*$t*We7x6A`1=!EL!w1$bz6S7MausO@*(z8)|JfJ z&Xp@<#Y%ojd6;0S{BG9Vt?9aqp36>lLX9}t!NoWGAplY$NU{~8!LyPsAR&$+tn<9XJE7=$QJ#x1(Qc@3 zQqAp|CwK`5YJD_*(P7r5Q&=gV(PY`_t$dyY-a)TV?ep$RS5z^u{Gx%ejN7WT6beTOg<-vds?j{dPdtXR{3)YW~-YJZbj zYd#w_LJH% zxk5jF3oZh%_G6B%yN^uIAw~+|MHR#6|wu$#wwS{zH>JsQYix#DEt0A|UdA zB*^#S{^>NSH*OG_@^BNA3-${Aya`-^3J!JVzO!SGFknvf5`S-N+CCiY8W|#2rjKz0 zUhj51d{d6q5J(Bwge?K5RrO;*TPuoNh0u31zB^u!Tmg_k@7R0~d_^;Sp9VnC4NV-! z=51-y@Z($i1;Te`eGRy=x2p||?*%6>ZxI%@s?&yv7t+bC;Rm7kL8{?}o%tqyG9U|; znipvD?aJD3Z#j@ywWh?8@NTy}B`0YG^T#eJlE~MYE3_Jqzf+SmtTGY zbUWY$Ky`5mFc-zV$^3Wl#CMQldzM5(83kOU434k!yuWku$SQD6g&h>({`FV>0ULq$ zsOu-YgU?mIvyX4Hmp4!WQfdII+6V6(AfW~-KuQnP-`EF<#UDTcO*xcXg7{(4u=|vN z7ln`!7x{hU+_xF%+mCo_aNv~ie6J2@UxYmjEMg;Wx098={op+()tCGG5xTXRY`%RF z_A#&s-z)w-U3ojK#P1MnmRQ_{!}L&p=Xc+P?c3YHBGkXdexnB9`+Hht0lL)j?lb$D z7Js_$GO!5Qb%lMQ9!Ciz-@U6a`_$l-ITKZ%STbb{cI1CrqXk~pazux;Bb zO(1-fk*PfmMb6AV9M%;=GA={<7-cQ+6n;S!EKnuQ#+SmGLlp!PkY6+4elt6)pNvAp zGp$d%Rfgu89E&Zi5nio#%M44on9C$$v~%L%S5WQx6mUySFQ@Ocg?>^jROSMUtYNzM zL=zv#Kj79$b~qSpV#%ujLq2226JQq|o_v7ds| z|Hg&0eNO_^m$vGgtaU1i%_YSNW+rsB~M38j2&AT{xb@# ziVoNsq?95D%_fSCq-wSvVh7^ z+YQeeb;!et@Ei&6{vM05Cra@({Ar{#=P4y0OEYFsF)imKe9^)=98`9PVZ*5mfDMOVw&ojxFwjEcIN7|SKv%%1HWFR_w%IU3wlaxx63Mh-Fw^7 zR&4IKatALZ@f9e!7DE$KQHWPjO;h}T0v*}>^tCbzopNsAE=$EI8DldsZjg4mYs zx%WzP$iXvxVSVeH51m!IP0&~utDKANL7je*X+oMjX8tUwvTFH4UzG)$?1v9ncDDKEU3Akq`~)c`)-qxypo#hU-{Rj9%Qe#a~H4 zMNsRDo0)4-Y;%HNx=lh{oqXxCL=oAN*j1pL4bT732Wc0lYuY`6HCX!m;_ zJGsa1e+z;CK#{ND3!-}QEaXa=olb|59sZhi#?IJVDhELMmEOLS`|-Tr5uKp*Yq!Mr z;GOzJ3rP8Kt(DXtBlf}5|Bt=*4r^*#`$ZK+G>D*rxTIPs5fJGm6dNi6(n1Lk5UC*` zy@QB|ihzoMfDnq*6l&-l1qC6rP(lfU5PE1KkPx_8`+WPHz4lsq_xF6y{pZ~E4}{5_ zGh@8tEx)&n@$&e;fSf!<(sxU`868l)(4;-AtB|@VCuA|QQa*k;;AI+bM_#`<%&(<$ z&Pc{8tHz}|E9~>6vRhtaB2&}r-m)&fZI~a@0d2s2c=h_lUr^i6H|*Tk;@bh2V~BOO z0)M!nQUCYAe!HEFNd}r=+k-) z2EnpXpFVx9e1q9=JEsZnE_ju$a%V6wD$gWpW*O2ECtzZ?Mqp%jlIMGvX$yqqjhbk4 z@2Bp*6>k?!%ad@Pa(ualSgilEg@-44Vi->Txe5ml*CuMz#hEXAPtiwl4T*h|f&7Vx zp1{TH;Uhz#GtoZPx$>7?qsf$qrv_^V@&6#&P2c~dH6SxO!>psa^yIOWXN@7sCi{%t#t>zXp&a}Ts9t+NC*C#KDFcmAdorYoDfMh*?x`W`7;>i9rWi2v$>bhxs@ZfRY z8?s%F&s!yKP2J0M=bySN{adGF|3lgN3%6t?k8>P1GJ2;2w$mR@bai~~%5`SZH94nd zGq^B$U8S>uwt@C^9W!4xuq3XlwgoO+Ca?JuJ?B@&LKx>B?_)VE{NMYbG0u8ebtd?* zWuo(1qX&Hf{%{hPP`N>u)Q?Qc5$nI?aw zlm4dD-*o!h_WhM){OQ{N{r3288~nEo{u>AXC!WLKy5K+au>Pjg-*oziA^rb3&ZHw6 zzkT~w;v!t-q|)4y zgwon;d@0k5BfGA~j<#BXTpIiKAN=bd*6u6^1$jxWmcQV)*TPpoAo$IjH;*{*`kGGX zTX4c2X2pEQy6kq3dOR~eHPV_#e9*B%??+5;;ywlsKiUYWa|=56Si^_4gtB`dS-KkY z1#^qmTYQ(?V)m19{64^;P^J-CZm`wH{q(7 zL+hJ??yEa{yFX^T9N>=_b@F{T5Qonk(cq9RbEL}mhd}cOh-ncOxbwmT zd7-J#;|Po{*3HA?D*uS%_SJ7bukTDFLzY|)3%?fFU#GtD%EZX%avIDIUj*eYY_Czv7B`np%U%oK+4%Zw zA4>;tg3Jkm&9THX3orcAAsO`e9exLA>^o{&t0o2Ig`7^!e#gA;r^Jakr!i4{|JDpR@HY2l3%Vq8jBwgJV@w;+YUnE@_G~cXQRC!b6<+$)f(Q~%zO8RAIOhv zM(}#Z@_u}s_Cy|_LUWE;dtaEEYGUcynFw|MEYoLYG?_~?00Z7Xs=s3I zY}>CD@zCg2H9UXGaJa{~?crSg3(7Ihi!uKCk6i2FUS3{4J7ACd&h;T4f?+{NW|anN zJX~D9Im2KlQ;Pekk>juc-UTJAd|U~t3|AxZy^a*t7Vj!oc%1j=vtl-I<`!P5JQo># z>-qX$#At4Sr>Wq+EHd<0yvn$wL?;ZqzFW(Z7<6L`{u!l^SeB$s7guqprdXjuinqQz3sR>sRKW-g&aoVG&zJPZ?Tz2w0hRRwJRUWmHez(C zbX%q53~FVF+rn7lQguRB-Mg^=y+9eRvXpPR&+d9u;dgeT=RXE7;4wrqnn2gDBxeM*I4jO~s|iESmNT5iSjD=>EEtx8rx{R$uiFqtx~@>U(pD zP}E8#tra2o3r?S9nnU*Br;b8D*A=Xn)6<_ehy1Pq(Tg>kcVX-p$QSvL7Q8+1!b+ZX ze58Q3HfgV~<6Hm7cr_vU7c#&3jR~1Au)4ia;SuDs3M`BEU3>|GhOA^1w<$eubUtA^ zXQSoT5Q@nu9w8FlBCh5Dl*PGFdhm!|3|@9{4*2t-9KOK*ZO?@IBTy;)SB!6}vHu9C zHq#_sxN9`-88}(>@nm$0Q2E!e{XjHQyZWPbOwIM`Zilksd6R1F8DI=ZI$-+)86HZf zdd9e?Utv9U;+**xY{c-$XqmH`NJNndtvzNuWba$Fi%ow?Ljw_DcaQR6mRgY}^1F@t zv*i8rn#S29+`I<1j_kjf5sH6*#0Bp6qCo8!G6h~qoDZluH7bUFJmfhR&t5Mjq#&x8 z$s-5^0%Zz9X0~~-ZzUz+u6LB<@l$M6WS%r{3>GENX`$xrQo4!4NPn=eIi6f$db2yH z`3eil-^fLp_eAMdJTs}kL;}KfIXEFW4iiWZjgGP(JO&gJC^j(TIhAsbe{K$gMGB?$Us#Yj6F4Ruu!tPHa23#0ql#YdYA4n5RK z)e-P2GTs|xN7*mw|7P-5virT$grj2z*=37lV*1q+XFhD*5YNeBzCD!Z1UJUIpL;J7 z#}hAaMYN7|#7&P${P=EDcJ0VCc&r z6r_dpiieXber#7M7dTWbX{7jnhM~4=2hH@I@;eWPEq0MDA8zi*2uc(#e&jWqG9%sK z>666HrpP|SL2d#v~mD#evE>#EA< z5RC3K73y%gBfR<1JWZt^>v9?f7n7_pj7ic!@a%Cg!z9!;9(L?bWuJ@7pyzyes-pXE@;jQwSWd5-(9Xr+ID8IP@ z&od|aOe-dv2Po8-^I(znvX~f zc2-%jDF;+{o?wYZE3jrv4b?p1pE8rGs6MHut5`#NWcw)8?8+r~2>Gj2`I-za&C@x9 zT*0up7xB7-I?nI)>zpp@rPn)yeJn81PR*Y>Y5T&OkFVebfa04^S0>E|Jg4MJk%wAS zrPQfd@ClUQdsjYA@HVhtCk)7G79AVQ>nuZc8eAp^jV0Hw?x7^lE>_|`4-m<19d3n1$}t=ah-F=+QAyUOM`g%8P?=S7JfR=LEAtF5iX z%?N)mTYJGd+?b{5=Y1T~$pJJ~n zj2Q_YkwVWS)SRNFZL}IL(aZ+Noa_+We0;Q}*4gjI>%kXaIjtCcnG1BoA5{~$`3s8i zNN7yB-{cgE*81s9!c-Q)euJSx+0K`tb``{gp~~-s0GQ&`WtcL_Sl%GM%r(_)Dkl=| zAsltK=F=&ApKE7T!RW!9w3iGs+$*+?oxsJ2 zrlxuhDrBjm-sNJS;hn^XUbQYB&37Bts%}OYL&AB?r?KL`2}ShaDy5S4?Mvm+GjJu$?XwwCwD{wepe|?#P;1Bzu)zLsfZqn^AXF5P3=A zfVS4pO%!t*A1~7*AaY6z-1sT!to>QJhYTw7K7PDVJdr^J*>lt&bX3*-+UEkhSb;>2 zv>@|I?`+L0Xi_!sB#yNHlm#Z}XW{Zi++@i_xR5bEl4xNWOp;vKt_ZdAP|9b0wM=m8 ztRTJ(P=u-bT5zMhwih?;#2UWXqvjpdi;^aiZdc6t_jpc)wQZ+mWbSP}i|;bDucl>^ zxEB{|rUrYicWl;?^QKTA3j)e(ExP2ON_~jW*{Bu8kuX{4+Q8sMDun+ajHk%*TMkte zQmZlED(k3=AqK9p@c)8|_8$c3F*Wt~=pz!>eoBh;bXIOj15;#X=DFh3mO*H|pRS0r z74_NhI{pp0l_X zVXDdQr}-Km+z9%su#t)>@tqH*3-U$0Mi^=ub4tdGzT7isvcgK(-N>{pxNGoIbV%%@63lf z*5MIrla+n`Dl@0n-n&J#m8kC_1{jMnHjrF;0GhI>{#?e~d!5y2d`_>^&p*X9@cyIeB*sAr7VGa0Oi2vQvbyBe}!>0Y9F&e06g)D ziEU6W{-vtzTd+HaE$4Dp6F-1R6*=4&lq}`H2SpJ<1j7O!LkR$iHURtxy{ne z_fy}>*hc(Ja?O$(ZO1yS?Bdz#gv&p$3LPbw1d<9*xbYRhijqTj6L?I(%bq$Tka4Fm zO|Fvd8t4eAa<9A0J1Tm4$d!o`Rk8bfnhJte|Af4Lp(quw%FKDl+!J`X*0g2 zL>nzrM&e!}Pj*!(BISwDAqCI_jw6G5z%LMRLV)&GDN98SPHm7tuDrP8UyB-j7M{NR ziTzl4Ca<7Pd|N7aAarA5XlTgge&yv1K}+?M@6hq`$Y-Q3l7>8PG#~$*2u-gJbj?|6u`DQeW12u-V!Uf^S`Rkei>vBS>+* z%X^{oBQauNa2c`pjd1JPi4-+cqT@vb?TK8WlHX?Xq_FVV+B1dWi8pPg+q`Oa)0+D{ ztK ztMEM&YCUJ?5fvJT`E=1b6Kzsn=!7_q<0cCVKEVo}MY_y}lZ!L@aOKG+A7FBt)|acX zb=2?y&q*=xb~6_2{UsxTpB_DqrPhGYT^17?4ix?lS;%eRN=uqu!e+DyVP8n-y@v-9 z?9Zg28QGeOiZ)2a8NX84q+WvL*$w&iu-MKc-{le1>R|D9s)gaKewY?|tMVOsf>s?2 zBP_qNT#<*pcq)*^3v{fb+iBjW4)A40nv7AO@by_A^k9rbyu)=PkN+a$Fen%F@BDqwxnB&oXnvxyG-$@C1WiWP2fe z5{%2RB58v!UaIfLm5~hf#1G2rpJ{lRg+c!|%g*v(5Ym~eZht;>ReoWot)VmqvD5er zG5+9YQ^6}8Qmyz=m7D|>A};wn;B(BYS5E_>P-0MpshMq-+#z6QIpb>}YH13=Y|$60 zxS96G0Z|;&QSV?#+;d&@7r2~yT2D1``37_(4D37kbx!gKZaNSnwvu}GUUBBh zwMEz+2M=LC;lqvPwVMsC8xP4DGZl3st>HXECJW%_wgtssD1mO+7F1SGB{cPidkzGUuA8T`W$@HcHjyRVC$ za{TJ*oHf3w{d?1=1?^abx}ym%s!|bb<-{|U^n&)$g@YA73G&6A7WBfti#UYym2M&}1RgZCS3}-|NI)DDmPN&|n zlP_A;xO`kkV0KnLJ7|U zC@`SrWR0vxa}-K)?byqjB3VBnZy~Sea&Ey_mp4K}QCw}ZLgYF|Ncx=cFG4np%+p;3 zsmSjiWqxiL9%^YIbHwg_d<=b{0aS!m>@Jsah{9DG4+;8BZeT-c0g|wb2>G|x`{1otYc#m;|F!M3W6@2s%Rmz=j zxE}A^`%d4dJ6YC&ns%lzzf*A~uO_D}AYynraZy6J#SO~XgaD@+WCC&wW684CeWI{f2tO)!qv;=-}BGZ7#Ek3Z~m}v1Vh-B$Q2n^LXHl#TC6P zu3Z$Ikf_p+qK}4jejLdHC?+Ni{qByqC9x8DZ2`&BW*p9VQ77u`q@&6UlE(MD$cNS| z1azzgK_7nc@fRl=-pz>4H;*r*j(b!aocaY-gwdwfTA3_mUACw)F728?+rbMZ;kUb(UhRrwH#0{I>(h+1)GWe?`3eMJ%6LN3NdvRcM;^ zeEQ>r<{Q(~(=Xu3_0z4NJUhHIoz~CGE4{9r9QMG+IVlPH7;*Je(U1zlm~Sq0?rPs! zVu0o9r%wh^w`&_rJs&)L5!UWcP!RA8v9=aI%5jTN{v@irvK!4{2$hfJBI>$FW-JQh zukuOlR*QX5Bn}J=oWd;Uk@Aa+dk7;VC*9^Mf2e?|*|?`RZJ(k}J$g_a*4Fzh=autU zl0~0q9*-c;w}JX0bT>^|MlPuwc(JKHCm-VGR=7mK!VoPoVK@&rncoz79UgUhQ~G41jKIY}}AK(jYZcr;y9_{}P1|E!qhk6K~Y*z3_8x<1(#%94UZ( zVx!+I?mlIiI#4#f`q|{|_tb37eR(7TP^MP7Ch_YvO(3g4M|(Sp=@5XlaqrvFYLS{SIH|WIS~>|c+8>N3w(V(4kdxh1v!9T!AFhz>7yp^ zB3^HOQ$;#;9n4Sz@otX;;Pt~!NQee7$B9x_P*8B=c|B97%a?A&<4>^1DCzr?;P&LL()Th|ppRTHucZt6^i!FM zQ9c0yj_a?h;5tF@J_)$}5zYRu>2)Adz1nW;(b)1&s4I!z(ckTiBL&hn*Iq1R%1Dfd zH$xGjmMab|`MD{q^czK2t@MiSI`y>3vt(3jFxfI zepPo-)zl(sXH<*)J3zVuA&Un~`T)!76BN2Qs&3Nd$BI>Gwv*J}v~OuypI9E~etQ+& z%0Cw9SXa6N4 z4QMaeo4j-w%Xm<9GTnkX(QxoUyew*r82O51Cn*;SS> z8b4iYb)H8pH8AWZw=F)1qS2+r!uL(2l}|v%K7~_LQvH1vmDKa_H-V9nJ8d^Z6Ig*$ z*!t}y`zE!Ms0)M&rsXA8HoZjneVb1kv!9-_T~7c}`s3`KSYnf9nEEi}0_*eN^NDgC z7uXb4o}}A$Ktp>8Pk3$`R?G>zq?C0Y^p>&*-d!Ih8(ImHlGAG5ym`~@BNoZhFAc$aygP1d#GI}jo>Cy-I0GUo-3(HrGLJ;;sUUaP!m!X%>p zE#(~im5z>%^`VkF<3#>4dorgOu^^ne;n{~=@^bTlLDwRqcrSw@zuA2N?6G14u3C0P zsx3yG^70_FcC5h5>cym2Od0pN{607=(7%V8r$_`DH!w>MhGzTp2tUe+DIoeQ9ya71 z@Lp`JIsR;bp&UYbI(us^X%7R63&Yt29`H19f|p+npAj17 z!rUt;a_t>pWND*8;YF^a48tZ>iPR6TRO}4bQT58z+ZEpnvWgW*E7oUY@~aVrRI6ii z`G8;P1k*B&HK-x4*4sy?ulB9>C~*d#50irfsgU+P$tJPj@yfVQhsM{HY+Y8YOP}xmbKUGiIT%q@ZEv zetXYEoA3{_(Do>1USRKfs4FG4X2vS(ywj7Wknl7yR@;*mT``{wr@T49sa!t&I(@zj z<<;@Yx%^L_bGqC-B87`*>ZA~!a6i8x?k+2jiQ;{9<+@GL(x;8K!#|!b?ef_@CmWMi;TUVS?04z5;-2xNwsT-NB zOK9HOix!=d`J=tUsDbr$;9FhNVx`61yLX%M0?2{_R8CIo{QP_~!gJucERPemc^TVw z!K$akDa+exJ8o!QfJiSFdvtp22c`%Ldqng~jz645{YI_(!9&Wf`$(Z7%(RN`TF%RF zeVUTr&fl{G1lv`|8-dM+SJLx^+#yq`70dwp*L5>ZOs4R@4@^z6zt1ZrO)O%a`=t)S zzMVN7GkBXW->_iA%ZJQxvw4SYgHEk46J`vRx!jZ3PJ;nd+I{aplKGv>MlCk6w0Kgs zWkVTdGX*`>OTLxD8zL0s5~mX~c^zE;1utOy<;F_w1-Jx6umbbmcg5>IlMAIi<&VPlnvU zDT}x=3JOFp=Pd=;a$Vq8UAm0i#p~R;31RjazDkdyUP!~?k8pyV4%U?Gkz(vOXW?#P#3rpShxRfEQP#7F1C~0uSt!i6To|5VDH7W$;+qN*@1(Fjr_VwbqRcFiZnjbaQrh?= za~-w&>~w#*j;vz$6+_`tw*}8c{M?w#bFVx~xE4Ft95@XS$QgbK-JO?p=tC6Hr9vOd zXii8wg<-0N{RS$&hrkpm8yl>4+o;0FW)>DM1SW=T#$7f^abNWoNqZ}QCHska_@j4D zoaH6fp=vX{yZlsjCd7s>!I#`~PkEzuK;(*~&>g=A)_R`lt5pK_gv3g@`Z>6~`$+T) zo1&M+`mmZ^K+2KL9_xsjB(;jGE{CO;uYnBDpFjT{5IYAxhf<|g zR*pEt;(fh`HXPLK4@67YYo<8U0?_cZ@;Uq8VpQp`j0I@d81LgHpq}Vb8KtMm@iB)Y zW=aY#x&=gb22FduAYY>tJ2877EOk`!q8DZw_j z0&^0|t@O68(2gT|U~iK;N1c@a$k_!>-Y5@q3bnxc<$h z5qMD0Xj%Kzjpq4x*oByq@dKQ?gJtO;nVd#9%c3)+Ab8X%*;@DO8*Qi{9K|Az6eFP0 zOwz^KNLE--u-{*mqSjv}PM5%JEGeW9FlM>~xHD6$sg!rc#I^wQW34XnfO5glqiRfe zlc1BnvO8JtVwolU3woNO9)o>8eE3lI^5u`BjxQ9GY>E24EkjgZne39>dg=%N&;CwQ zPC<({Dg3i~fjW|U0Tb=&o@Tz))$=hbJK z)_a17s#&S_;)kvESds4}?SZhP%}t>jF`q}B0kytqe)E~jog|$qenW~3(-sC*8z}r- z+cIq-7c;XdL4xovHz@82m-a^hX|@G_E&(y-U~LNDeDSXs^v zq~35YE)&d@@MAm}eJvmpzz%puj2{sJ@~w!2hjpyF4S~>`0ZT!|ARRzzn)M_6~%J z2qVt6N1!mdJV2E$B^*s{E%fb6Y%5%E*w4gaa(i0&4YDdHeX2E@&%wm^UI0|Wq+zoC zt1&bxe8qpAw1@XW(Anf|lh6;9%+2h=g%}^brOx^d(IP`@)0OS|0~^nz&^8iX0^aPO zQ6yOicHrL^=v9S~r+eR2{~~p|FYGhm@)E+>$^|_d`BR;^kA)SO&h>`HjCPOkENv$h z&zjNp5nfdP_4iu0-nmz?yon~JP_6+dNT}~5=yStJEv{-#7C6OYY)tkDu zamIJdWj+9=B`qMk&E5U|3Fi`f2WWBOJcE)uG2Xiyk>CL8(m>I|u&{Er9AHWzb?yi_ z9#}siF|hTvbV};3QuVvd_<;elb@kxS)tCl?c*w3Ha%tg?STHWuycpv!CJkn!Q6UTL zoE1!1{`727W&O8#gahx~7-ti^M$)e$(f37kiyn0JO5JKy77kplHT= zp>q4#^XBG;<^1&vDOHnKVL?6+msD|M+~--P!t(Np`o1UJ1sulUOJMMaD`Z~UuIZ}n znZwK^S)!uohhOR+z>Rd#t?SN<&|+p*zU9)fqeq`2>~MQ+`?t3e_1Ql;8_Q2^1_~ag z2X`gqqT6@-ocN`(N>d#)9MB1u-8&3 zz_){oZ?z?hmqscg6YI&r&G@gzBT>zvjMDS>{e^#ujql|g{ zqlZJkCrN%ZhNE_~3lD>DL3Y|--4Qs=$=~YZQn5-(!_LKw$@dN0+-#DufiHniD84IH z`cy`Ha7RbS;COLch3lBJ`p$PwG!~0zRw}o^Wc3En5QjqlPS^wT3qhlrTTfoEe%d6C zd@EJCeEWO~EATUWb<@Lx+ztXU85O!77yhWHblc6^h8)|HOu{#Eh* z(0I%v==t~_&(DoH>cW2XqN23)ag16b+J{P^3|sn+@m#)DK_c4Ku6L;{Jz z9^*sEaVJ*e;Lw#Owk2l38=H`j-X#ke!pL-8?W@05G5rAsu-lu}QU@F`cP$95H6~+v zdU|TvB^;oA-nW1U9@sdFx5rAsRFX3W@=zWXl(V03w zpSkdBq5Z7SxLXY-ifd|AES9ACB&w+6fh|P_?(W4-4WzWd<{|_6`F5YA8eejn;Y|kz zlFNI~t~qTB&e33S?ySsa| zaOUbCYsoONK zS!rf(@x{Ldw6ECLnQ(uw??`K8P>F6t+CYU%UyjZ&@`6E0NP{b}9^`RB9V!&Mv$|t+ z5B>A0F~R3E=KN)zPX2;O;NOq1#;(PK{ezgtp(TPQJUb*Ro`&6JZ45FIUTo!alSQjy z4dhvo%av0xMODnrMx~vbWOJ-RlU6xiq!XVu4v64^`kiU15hffhA()`8wzqMiT4;+>R5J#1~Ha3 zK4i`M|N4%`5a5K376Yzf!^L`DSy_3pM@tCHOa!YPJt2WzX9`f^*rOH>n{NHH7ncB1 zb7U@nsoLtNlRmw7L?W89vj^fk=@egX^w#F6C(i8p^>8_P`DaK1K;N}hQ7YOTarplR!P_yH%JA1 z%8#8#wwrXD;i_o!q1P>Ab_-%4Zgu#2X4a4}F=1^Q2|jC7xy}>{%MGGaBzXsmUwp}_ zdrWAB1?fKwOw8H_<{a&e`@IJNCn>Jg2$$K+00;^(5AN&O-O0D;ghI{qy`3n!okFbM zo>(#2pkcej2>cv1!H027Qc8-GB)un~fw}c0;9sEOdti}WN5aYkyH#Uou98XQ`F|Cl zqBG2$ZkSems0QMQs^q>X?LU+XgfZ?vW*$qfnCErmAK}F?|AX8+_fJ1$hRA4idP^{= zD>a8}&?Zvg6z0By-tppGw8OJug#vq5PA2o9NtVX#WrbW?Cp%padJ<$ggGd3$4IKm~Oj)Z-^(R5lWFvHTM zdj<(*IG@fmID9YT8mmP@i4&z6Sy)e~r`C}pfOBHPA6JGS$TQf2d9D0xP74RFeHAG^ zA%7R1*h*qHk*Y{>trk1lAyK~6<3Sm95hq?Rl zr8$p^?{OdN+ri7^G6h>MEP^Gwu7GL&FB~77o&nhHpc19S;5U$!DP{;0xjFz zDrEcx$|6!i`-mD-Ti`(vlSa8AU=YE$V*EuwEPv2SlT9$Y+{Kkj6Bp|8n9XBj8?R_H zuU#K+?}&91^5ITm_OmKVjUo9d5L0>XXwm#{J@4lYac|OiI-MA<_+l5=fCSasd<+KC z;X3^F&GM1gox99!O#f%)ftJjLy(^?i_(PtkL*hR7j&_WUd&GRK17U+r6HYVH$IiuG zaY1TL{Eik?0)Iz~X}W!e|E3Jg_A}bb30>-YJHxg?|5ZO6#(*@o1OVE^US~9>?H)hK zs#&J|4jd5lRom(TjhDnDdzW`j|H>n#4*5sE8(uMXYP|4KMDtz1<2gg78qv8nC_a=M zK(TDfKB=eL)1^3dRAr^{0EvS;A6{*;pC>|z`@xG5qeQT3f9UO;eLZI*`5&0G>H=3T zMnJe-dx_fIR{D?U(*l=|(9!8}*QCYIpSfYMebun>27-x7Z9;WbmSj~Z{e~^VDd0S9 zT1pf+rVo^&;C8IV?M!%_p4zZ3v-{T-#r)TH)w^P{BA)1+e6@h*HyPbI!edcZ8=1r9 zpOmr%4H0F^Nwj*WzMLy7Jaw&YcYz6ZlZBgNmviE~YJ;uD-)IRsl^F2h2fb2ezA*u3 zOXKT#N`pi8c-D3XY&zrho0(F#e%-0XKe;X3Z)bW?+M zYU5rf^;=~mzpRjKVjK-!KAZGzokm$`F&35c^{yl2k&__-zIo7Us~Y*}>{k7n`S)&y zN`Q|}A08HTXSOHiH^;daq-W7)bLLCu2R+a0g}Tk9rjzdAQhh+kWWzhSv~d;j>zX$B zLXUne3jTo2d1l!Gn6Bt$Zw*eZ?gT5f! z0G99?$(M}I4-v{cR!5bsSKC|`V)TQ=p;S@F6mIK5?*KO>M}R8@gC|27 zm_D*wbZlBM=TQ;RUQhLQ%)ffj!zZ^sONAUih1r8P{##Pt`qso7v)5o|rLMW4?jKVv z^tye_Rudu5|5?A{d61iS|McAqp@<@GMS~T6V1?N0td-YnZZo6&o*GRYO8^f4)B0yQ zSmU{6`wAifNuuvFXxu&qhi?HdhzFIuu6|Ge9k?#Ytm3?J_9W{~ZhrmecM*Ve$GA9J z=HuvVZvl;>uM#?TD{IuUQkvxm8~K)JHCcN$=4x2(CLb^t!yS+T=m#WKtDCzzCn>8F zXY6iv^niLwHcDBP05bW}G^5#XEdj|X9#&swD7VNj2J$uD&g8Tjeivq)D}(iY@Z!ZI zty7mNSG@~os#v0{P2d9-CKLMmL9EfTTC$#1YsoaQv>nR!3^m7$KD$e7Wgt9T4qa345zty@NfJvw$A!XCU?>q^nK%~o?ZLEuB9 zwaW@=!{M;`+?mHzJU!ptgkD?doHA3m95q1lF0cw7%z=3orrcUsYfPR=zE%Tx-wM~} zP~F8t8OB??y|sp4?&F@fUYB%EY`yp0l7V^t?8Ow}ZK174OczwhBsy`Xa2%K1Kp0b2 z4wV}WQVkY_y$ZUAck6_L2Gw$CM%x6r99q9LKG#1>SuU+d8gJ1vx=Bs@=AAlIJQF=r zUMn+JOH6JMhmbFH@-fEO8jCLX%gg_(PW^&l^2^S!q0GN1?ZezT`$DTkzqw}^{~t~M z@1K6$Y&>uVpe6ch_Pcn5A~(xw`ZG12Lp?Kyo z0WwAVGlbtnY8YXWfESl5f6 zBWBqJ3|l3H2AEZAr4UmHYN>`bnM;O`?*=-XS;ZvgBe0#msq_7y`h|d{fIEj~vOOlgxG|kTp}bjk#BJOUHAZ^kSzBsoQzHlRB$Py-K;fRs<$RvtN>y{k8T zL?l-*dA)SrFi@`Ce2!AwCYa(Geax>RQ-o9+V}&G#)P>%{A%oz%bEF;fy^X05G$yfh zrqG3QSzHvU*9oQQ)t@n3TH7RE-^Cayngv=2SjDOtk_y|Y?s(r+lcWNiZ=v?meFm-W zxJfK^MBNxs-VbBcQX!sS>CD5(mC)NL(oIiu_=D^J<~;u4Prx0f7CRe#2>$cUK*Bf{ zfSTyO;~cJHKQdS1ukirx-v~F&*JO9A$Mh{XosIaYdN4=$ee+$K+1aBJ>SbaZ86_ao z{PKqeiGxXBb1SqF_4%Cj^y1lEj5jYUnES0hy^a$QnpuAw!Gj51eG5#c?j!5h6}0&ly49~4ZZ$0Dg0d*`idNP#u@^LY4?W(xv;Baj7m@$MTm9%<3Z}ZtRLs%+<3O3@f|_3oOrg zhDtduBbmUTmJx`z;_MFSR!~lu&%&(N=L{4o_e%!1-hJO4Z24=EtrS&0ye#O!| z{~n&CX@G^2IVm@($gzSJovCKOYF$!X`LllnO`hw-5c+lD1whLNuV@+xGKvj}R=H8A zBTgi*>J_#W>Y2pi@@IEewimkQbD7>neyfQ(os5{R{pz(#X`tEgkf*mWU5AoF+pFt_PT3}$*iX9P&~N^T(j z*}Zv#vHY;;%9SY0s^#=TpzP%=visSSmcWyo7sV7OZR8{D`xPSWRk=R;EW95rLylJN z`i<$UxFyc_Evqk>D^*po6=YHi)W^YCO}K%d*3y9cSk|Vav9wzX8+%;4VUlxXWQkFZ zPkiB2wcb>Y^=qH_1-Ma47Q}#Vlt9R(GhrRLEZE)7KS`NH+0KO)mS6*geq>lu1L$}* z{L;D}eAQ#ea1ge>HhOa@k-1-nlgG)*FTFinw*X3YHZ-G|QS*bA#%~F!unrkqkL~e^ zU}fFQqK|4K2z8xS*Tbe55>_CUsT+t%;l8VCd5UkRVOJ0yL391AWNk`V!==loTmn3)=k+R9F&BT`(>r=YKzL znYBMXzN%XPPKrfWg*I%&&P!PHM`8KJl!u6=B6()pAkFyV`=?L ze1)Fv@)V}Tuwz}?U4*fiGXH7->A8H44WDgE^tSL0u$Gz6P#$aPST6}u`*LI2ujr1a zxo3-Sr~h_M{IcP1gpIlB*$}uZdchmfe7~pL+Jfuu^sHL^G{Q>DnQk13=*uO$&M-Fg z8my*i@AEAKM7BIpYV8_SN7uRSZp@T(pzPsU+k7AY5u-?Xw+3|wH3b75yM>&!*yI2e z@4|)(FRQ`1wAs>JcfF-tRikH^!S{Kb<0c@|d}7y}6=$nIl*e@a|7q_#!$^~Ngyf+A|)an0>J{25+Wdk9w3ki z0Rn_1Bq8v{_q;QcIEL{(T<80)?_A***WNp8uXR87b3e~2d##$6(419hz3M)lDF<-9 zjem|rLJs2$43wCwUNN5B!h~4ZKZXHZ{9^>b+DaLteNw==)>j}(KLHGWiopc{VnJyw zRYl?BkN|sP6{s^<2}6j)X85%A<7ne56e+0K>%`nJ)o^yQReHYnk0T$o+Pp|d4N2x@3}`im4s#z8;RR2oL#-;}_98WE9_7`t?s`qv7_1BIABi6O=M5F{;(NY4ZE#BTbBGq_rt->ci zd(x`ScLKKNS#-U-CCxaq{>YWRkDgjY7FcdSmKvFRFvkRwTk}bw&JN}RM+I5tVA9;J+Mg_lX>??tMr~BPm3K=!%>Mj0XZ8Jat~I+pBI}C87GWB zH7!9^KVzNg{iGyqQZ{F9pNnEX)ye{0#RN*8)A`xLvdRitrmtNFH2cg>%`E*xgJ(a& zKQ2)Ej|5lB_0;Pr^pFudl@hXN?#HIBd!)Jq9MupmJ=Qx4BvU_IRyDTCtt-*%I6?pl zD}^oE*oy_`Cy^%G7S8pmLOaY$9BDb807Ji)-YH)Nwe{Qcn~2jD`z*^oWsje+->ctn z2G~}9HO#7XDev_{H+kly&kTKvLIhB(D8%HRoY0O=8{p|9gz!pru+U~C96Kj6(8u^@kw#fh=8!jq}$cUF0oSOR)Ri0E?0R-oc1 zeO4Z>vW0flsqYPp;yaa~3fPOGU8Pql_3Hs(s*zz+jco+j__-xjDebJ8#6le+om_z< z?WQzoP>xg~M4yem*dGIJ!~~bvPEv4;PhGCG!E&~y#!nfmbt-#~g;ir;VhOJSl%jOe zlJ2INn&~LcZspfp+Io{6J`ZnS)5CiKlR<<~Q2F7f>(}hw>UZkik&8lW^mXAQ5f47$ znXH^un-iWM{Q3R#t2+f&bgA)=6?Z;8uk?ql(-;=m1&SG;?T4L{)`e$~TG_gMaa)PW zo1d{A`X%;PLV^dR?Q==v-~!rUQsg$=1l)74WtDi2xzs}RhQ6cBY{s)GhV|%6Ku7)z zc`yT<(df6jW0ZAP9Ii_-tg1I34Na-UtUl!6V26d9Dw&VIfL~?$A$kZG4S_Tev+IRK zMR{D$5Y^iWMy?znTJ=_&QLN=0V1R02ZL!Hn436?rVsdI23P5Dw#L_HVNvA};vXgRL zPz2Mt6teeeEfBb@q4$OFwWsLMS=vAvZmhs6Wv?Tvt-v4|U&P2Q9fzyaI=t;Os7&4H zQY^u%FX-h)sMu6aW#1rZ~p z0GB#}^*W8Wv2v)6-gQ3@op-Y`$lv@T;6p?2b91N(U|q+x$(pg9ldUJOdLXl z+oAM@X{KK_yL&j#eCMD@ z@oJt=MF@ya@49z*3!~u4Z2{5N+VpiNpPf9{^>($`k5)mOj}C2^+-q`We5WVlL9WT6 zXY}z|W(HKMV8%SHeVb=eIL2ET6?9!T1nQVgb)^A5tL)Tm^{*MLVr09|#Z9^m_88*8i>exT^1-cLGX^ot<4v6<1M8Ib^>_g>-W{V?LbRl2 zAH#r^*rvJHe&8t@HOI6>rNFZi8K^M}IDQhiaN6Dv)^e;D#(+z=YFES0h*pG1FSPep zpR9DLLG^wf&E0tC=~j!jaj%2ZGY@0H2rOaK;+X%-{u;yHLE2byP3Y3Y0xQSj(C`lR zr76}KYlrY+R%_v0VNA&ps17{5Qp3Mp%PXF(uQ}*+W-y|9Bf^{( zR6Veklo~o_gHU8R%xPt!%e6*;(|}{l98!-}LD@0Sb~LE^re6qn9%5lsfI#R^WE5Cc z>(d*|Cs1CXqO|L8g|v%boP1g(y)d}0)E%S99-P)#BV}u2v#1{$_&e@>$(>bQ@kSp{ zi>_~ecclwN&`H8I=MAd)LF!AWXVb^&%^J zj6oxHku*x$13?-)2vw=T%h+yWGZc#s%O;E4V2nMfDUY>Wuw!a^G^ItRVF4<{7h9Ax z;az|Vli_)e&|sgSpcHyiyil6Q`4rcW3y2mQ-PnC7>b9KR0o8~{LUzriDjLY0l}1oO zwJdD2J+dMozQj4L1P!lob1XtOrv>*aW1I*2n);4VwV5dRWE|bs+2OFfP^sy?(aI9% z>IYf}!&`FuFlt5Ds5;PmifH{~R&$^>v+;3GDifti=nKV<7@>MxI;}&m3{1%2<}`~D z{$6BlW-7=X$S}p`#W~?e{R>cAV3r&U4++&PJv)xK zsi$jbvdF1Md(@$$A1qZJt3yik5lf5A{`PG1Ky<`gv zp&aq;#F7}*&ed?VCXxZf`*%JjciGT&eepDvCE$m^0|;nES#ug-OdsaLdO!sE=piTE zsjB|IK>Y@3o(FG4sBGOFr29^(F7a>YhyB-YYPE!9CE_j|7x-Dlto%~_BnV@0?CmzK zPIM`mz#`-gUt+0(n|rJbB^W_( zdt_mE4p`Gvi7;FrvPVTtgJo}uo*-Djy4xqb>-|CF&ieF)u0kr5PIMUqCKwhFj8LDh zn8N5D^-iJX4TLc@L`ntefzv|=V)`tIssdBNCkKZkm{@2ELa!jTY5@0?F_z>`4*j6X zG+WYA3AFbLap|ix!=|#g5|OYColJc!K?HRYiNq8gtW|+zC1w)n?BG^L(_;AmLz_XT zRkDOeMgvo2%-1YTmSL&p7fjb5GzTpVMM?)KIl#Ms?8$&CF9a(<`m8DIsf@W_7=3nh zDjN#wStn1HZMZGbzR&zob4qp$zPWNtCB3Mudnr$ugkd^j(uqVDGGnV+5jxMiqo-mU zPGScEpwdE1btg(?2iEs3F#x{8k}2^{ApOY2pR`NsKS_=2Kv9rx695$L92>{;V3_L# z0s>$H1JxzQ!`U@eB7{tugBmAMJ5|zs@_Rq)(Uft7yzWm0#OLTz%+5S(0-h2uRY=63 zdOIaU^!4PfKhi={)qRC26%8(9MU(y>sIjUveQ0=tcNHv`>L<>u7^_C514gSL1C}Zz z#CuIWmjw~MGQBLCXPxbNujDUz21fdU%H&GuBj*LV>+lz93k65EpVS&G&hkKp#VInGqiG?bYaRrEi^t9 z(Vz{jsy|6}QsmLnT?T^%YXqf84DnY0-jBqtY0*0BD;8Q6tp;NXL2&5>y<{o_F(g$= z^P6DhkknYdayOC>T)G(*yw@pxZk_-QpBktREyLQRFDA>2;&lT|VY*iiREu0Ug+azr z<@KD?1QiHEcab5iRDFF)pmso6NlTuKticT)HiM+HXZ{IRG zOnj;r6-F*b+A+g7={S(B%1wE{YI+SDGsLc}vphB8Us#s^6ya&1{H9*F+xu;7unmrg zf$87f1zsa18UV@Gad2>$V$as4>vl&J;+|&f%5B#&kAg@ApT3+vot%Blxmi@2 z?1#L)TLpWFcY_TEKe1gVds`=zhk^cmh^74I^U&F3s{0SKZ*Hxt!iFyaX?Rp>e{Y!= zE#d=>gbnXI=7wS1mKD7YArB8AJ8jtR zu&OSUHZ=*I*1U)ee(OY?X0w2GwzJmBZB`Zu5dz?wEv3nqk#k#vbUVtjm3ZS_dzQWV z(Y|3l-cNi%V)2lGXb434VjYu4B8m8gv8TKh%>y7$a1TU-nl%qK2uh3kKvXai%hmmw zrNQ8gdP)BBN7F}$t~c#c9;y@ECO?vV0~bo=FLUUjHm$DmA> zH;A<^8x~jy%EE-to#o5oIP~jVG>vdz?>?*XDdKMp`_{uesV49?9Bwl^k)JO)tSSX1v?_&nBN^+qL@X zrWMiaH}+n&0(<5E`DHxu6bxb8b--fXis;48fA_CS5M2qss@Zn+da-&X^s@MIy>8-- z#uXe1{R3Y%IEliS4Nm9e%Lb=&@@0cV`}wlLmknNd179}yvcc&ceA(a(svIdJKil90 zhA$g@+2G3tub|484NmXi7|Gzv1}8B5P6|KU;0&sK+2Hh!?~#ok`UN)ru@?Zx^Bh2O zFznC5`NN}}q5BDcc$9-Wd-$^|9AoYLSrrcb;L8SIHh5+HeA)Ojy0ZV_%LZRIcqO*{ zY=fU|aCiq_HaLSS2Qd6>gA*8jCxuf_`Pl|vHaNY5FB_cR!7=*7mkmx}__D#54Zdvf z>caD7gVQ_sofM9s$_WgAY=Z+BekX-fPx;vfKilB-tpi^+__D$29sF#AGpO>j4G!<% z1comg9Ki6i4Su%4tM|qq+u+Lvr+4sWgP(2i%EkHF28Va>WrHspyn-r^PD;emt3c!d zZ+q+2H(X?FPn>>#>~-S7D4m_rYg4xB8zGuZ?_7`gY?t}u)zOI3sH0A;yDF?t?K)*) zk$FVX<5XPRzBi7^A7T>jwsgu4o8Pk2JiUL?nFPG0r?Th_{nw*~cS400+>u=uLEM_siUE|S;HXK?1M-Be<>Ro%D3@WeRv!cB|?rqo;^gz6Ex!3$7 zMFiPQU%Tqginh1#W<%&f*ML8{1x^xB>kZL_g?E1T(pTUWIA z312+8oQp3WTzX}|7Y`1!NnE6cyMurpLy`b zgNqP+@!%o^_rMKbJh-^R7Y{D3{BQ5Jq=k-6{IM4Rw_k9<@XcHNEQFthaP?{VLc&D| zE)V+OE+pSn2rfeKvk)#qa0ABALb$lX&qBDk!WR#|cyJMdFCN^4;EM-8^WdF|a&v{> zZQ5Dz<{`VHT^sGTDsYoQ7atG>fx18rQ2RzuVdABVA%=3xwz}5>ryEPZ18x2=d%EtX{=Ucgy6l~Oa z`rT}`I2my#Qa}4vzNsV8yB0SGA}yj+TRf@Bo%E1NY>dd#i|~i_V>a$-Nn`YDzJQoI#WsR3Ypew8yC(IM$>8Uiz_Hw@ z&?>#G{n<1fRGq3BHMxVrxS&`45}k*K?G$$nD^*LaC(3m0yyqA*N%oV!8RgzMMpf&2;Z2P9=zq~slTHzHnGeuorv;0_YWj(WA5Nr$bksuO4J)%4IgEcyBmqz+%u%5X5wqETn zM-+4?o%XS-Iw`$O*e4QMM=re|hAqD&o%XIF_kLW-R|4bp(i@w=F3kDF@6_<5^Sc589%>iDdbbp=YiOIC ztE1*WTaC+?aLiSptpD7+gjOZJC}guuYQ{ugGK)kYg!l4YnRI4dLqX#G{9k+PkGKBfGBy!}E5h**{>$x&5A}rf{q)m8?OImxHue zxVQY$CU+XOoq6lou}cWEnE2?5BO_@&NAIUvLr*yQ)^3Y7WP(rkU2E;0J%qT^KB2#4 zhc>fC>6SW(bFYy$NLk|-w4XfLt;4f%|17L8?y>3ibHxV)WBU>VksVGEndM@2?V7Fg z?-5$%H_9%VaGUGjWzYXEP_b@UIJ9E*K;zsA8+doKQ+`KEAxNiMKOFhK@3+^=={ky? zn*w`rgjsSwJ}e~MUEwEEaZq#Gu0SYlOwjsvN2gErhr%B3kfO5CfXK$P$up~kB&tm} zNPe0nO|-;ZgoQp5nbL1Wgpi>j>2Vtp2RGW6@%OB^lu4gIEY0-bVRKy`Rb`ocr!&Vg1KMOEaH>MTa z2rbdVYjQdxAb0V}V+Q1ta^IB12)7?STKY}b_2!M9jW)mE675t{I0vdp z(diilJqWMS9xx%1u#kPjZPQfr;i(Y~Q2yugd34Lb?{s?hJBWA9%z-+^Pd#MM0Kc0a zy3J`a?!J?f5}0eFz|Ku&mg%uD>{RZ&syY;HDN#gZwunXcQs%}32+G>>AyYEH+wKMF zO>B!aWV-enR?!2?W}X!JJAu+|T6$Bh!y$lXFH}|`DWHH5EUYf|oGz+DbcMKWOWWOU zxuhQ>e#FbudVl5P`jikUCQ0_l#K!Wa#bA`CN$rvYdA}rX20VqZeb5Am|ykJ4C@`7nFB)ipAY+3SZFzNL{B>N zj)T-FMUGi|Ru@|nOO<{eRTZP-8un3!bUC*U=a!BLf25<)LQTe2Feu&Y#yaXVqEuV* z%%2xl1l6>}R4F-Z{S94lLAh$_iIY>fj0%_94L)1X7Qs{3-U7HT|Fa`=LRtGOyMHw! z;#iZx<;z^;K5g z{*9RijuCg_&0?0I_-h!i>_W$k_o$>`&^cs%N#BfjUI1ivq8}~!3qc({(AX2-x5@{^ zxc0dGY||=vW>>T1Li&cPa4JLY_iRNSYVe-~)K#?CxKlqeishuOrOD>RMoOYD)l`<*j zvBQBF)y?ApZ?gO&7wx3jnV=HdUgx*J0r%}v*NSvOn$otA)Crb-3uxi?`31b)&MF-_ z#Y~#8xRa~yKozw9tbBcmEgd*{Ah3mq=~iB|M0Xj>emCb0+Ku?_Q-R@0>m1n@BfaD?-Nkrjc(Vm#qMxY| z8k3-E7FZV4yv0QS`OI}d;7tjgW(7)1ukk_ooQ`@tnSQ@MF(2ddpknoC04w0J%HUYb zhtTetMui{6qOq7yA&ZhHKl#ePyB58vgVK$;~FYwXl| zQ_bo-Ran)2$^DIklXrR=9Nm#}>4;vIBeeenRyBKe5s~_VfDW&^wNo5DyHJzAk6fuj zDZ-F!o_?0-p3t7ZKu-(}csXIyx`8`nTeJ_gf>(g=`pw%bYOxLo5R23vFvC8We2&3B z7TpydLUG%v&oGJ^adjBr2xwnAE_;8}1u|46iM?Kk{NWi$)HiJ*Bl-dpO7RfyPTU_R zwC3?K`8u*xHKj^YbqY>L$sD+6U`nk2Q+*{xc!g)fZVo9Oo;fq#kxL3A z$}F32kYqkGNM89%QZ#_pdrmGrx&I||nK_&G?cUy3D*gAA=wDYJnX)sNhxW;n+?h*+ z@Nd&&+0d*}5Q~CQ9Vqw49Z~dB_}XHeWhQLB%A%EZhJ$lQev!P-d5821dn7CLi4fNs zkY$_vjjG?>$1dc$-j%N=%@aiC7s%-LV27Hp?tlU%#KJ*6$BJP`h2l3soI#tjI$sLE ze!n(V!>g^=5k!CPxiFp!GfSELnX^iYF!rER5^XANCA)msZI3`ygIEk~_GA`iNtVpE z_8f)XlW(7IHFT3TC(p)m*XxY+APpOCj$}@jVcX^j2y-Lc%#3#ec+%q=fc&X1cXwZ( z>?wIfh&Klq{Y=3_|@e+RL*zp5Zm#wFto!wj7AYhUpw%ScJC#%YA`$K_t zErf3Y(Or?$JuN_E6wLr>Xe}B9O&TC}v?hI%2JDdaIr_#LFfb=G_-jD^A)IkCEMn7! z^V3~J!#lLU6|=sxAbv%-;u_yH-ykHPBYckhlf?Z0#}P@`&$2)Kpnbsj=%F*qw2rT` zUq=!?B78)?5hb_=QTQC;bA-sPg^YxW00vI=Te z@D14y5mAEdLijb|%uxB5{N1PcnEcOSLNzb)1unOgH2M4m9A>QTxi8{GFD3Ertqqv= zl%cr94fRqECg&cQIhyt+;3-J4_PEg^PmQ1eCVfcBl36E;b*Dn87=Ug<@oV#zb3)z>8SEp`I1 zr6A}_Z_;EYt(yTlr^6cXt67ZKu9&hGpal9*`u)1gN#jKfpRZQ^{@G2QP+KJg4$U9N zn|vMJc**HEWYpmhyAargQyY0N3V)R(I4+xasyQS`O+-Sh?AO|akqRRtUCU!4!y^sW zw(-4Fqq6m*+EImb(hUJ78mY!HqYHJaA15bGmb7+|Q2EA>{6+fvb*J2ItF8+jb|K$2A-wfLl)M(#%EfQm5;rAq6T{LS z2U}pLr8ne~vL+KCLFfAyf_wB;82z205{{h<3L*F)Yohad^v9=KP3-5HRFoK8J!o!DE% z1NYvOzV>Ll`cO#s@+>RCV7CmnBZNiOVSUL z_g)x8XtYrsd&bWtfQG9=UU>JnAgx|nFshR`d2}k{RWuz6ia0-A=UT59uy@yxclM=% zl`I_>bSSS~6dTCcv|I|JYq?7vW)B`IA2OGT^C*zb?1%!#m1`t1_X;^@=)_HE=!Pn% zX$3KG#r8T|SgP@>e914hMF>f-4#RW?Zc$9R;H7r)Xc#aIAo82AhgMaE3eEYN2E$Xk zJV1R)2fhtA0DnE>j-!p$R)+O|hfQS)3uFfrNC$QlDBnl*+kx*u zc9konc#|9Ft;Pd?3t(?7(@A+DI=uUh?{nFF$*9cIL;lKYaG*SVQ__=~z4#@%n_05% z&*-{P!$mdwC1I^Ga{U`4*}QlFk$J4G{|&^nqU&?u6=nG!YNQ*&ycAdmD7NXyJEzVJ zFO-yf=|K--Awjg`W(?b!-yffIDKMV=PB2ySB+&XjBO88+41`2B}hhSbPjUV zopO6tGN3BzePwUiu$E4M+QXxSmq7yrUy(~H!G2|dspb74ntAy54WsV1qGlLCSctj1 zG`{lejBbKpcg2EkLM3cO@V%2cDa)oJm6!}AI5V517k%9-AXqY$f%JvH4pO!c_u7so z`lPAawjj%suBoRJ5@*zeVGo9xC6lb&_)WM)E0A;|5t%)?7=EH``zRrd8G7d7rXpJE zOxix70t&fr)*favkipP%2M(0Q22zT;q(7xwXUQ`0Bx=IK&;YBvG3=eUt)w_MZ7)^> zT+hAh5{KX<8yLLB2^uMKew@L@PmX7K%6`_qSK*cY#I$98XkfWZY>j@N(dj802s|yn^V-Q|xMPnb zgE^P0RpV2sy_x(NcH;D9AU;LE6A&d^MZv}Om7Pat1RZ;O(dyw);)%BY&deee>Eld$ zdA-ET)=pqeF0d5!F$Yn{K9>1=L@T2fv(sr_oYA+1<)l; zxhIHHAEVC|VJk%A9%=o-1xM_n^)#A=Vno-|6Zp@MQ0R7z94M(>TZ~p&yJS z2UnabD_wNxn}KN31A+&T6u4TBPmo$Yf?ji6|CXh9nBQ18$+e=O8$_<4AKCelwRgNQ zxWC+69Zm37us4@qi)xRbk_NwT!24QZG{PO#<0Vay^hGW2K#HAl3ozU6Yq&zvd-r(2W5{aM0e7HP?4TZF=h z3Jw0xS@WJ5EvU6x-LKr534=M)o(?rQRtz>(p}7R=<+{aINZ%V*L3siposHLV9Pz!??j< z=SMmpj9;Eh9M-$aFb_*j+@LWvdb`VZ1^}(-@VN-oM1ZZ%%#R#M@4bU(+Seq}gI}a# z{O>UfAkn15Dc6AZIOM`B?+eXSeZ8cteR#t-2`2scgV5`{257xyv&;ZB1X4?x>QGYU z-M_TE#?Wffp}4x<*9+vXG`;hI>yZjV%mE8Eu0D_sLhJ#en3NdW{y` zP4>D61eL`Zbm=;Z2&E#$nO6X*4YB&h=O(n3NwqXf=B*g!gkRwGp%Ax&`wzv7?N**_ zer}X0Ufr#UEq_x=jUne(84eg{uO&)9_cV43#RcdJ-^v(j?*a8j9S4%>^ozRsO>_$YJV(o5mhMTvx-+9ISmmIk%Ed^`0|8# z8BPA<)*yWi6->P3>@4Sax)f)lX}*lz2dxFLCi3gDcc;uWGvlsPJ5S4|+iN9?(oVEl zkG+(QAH7^tA}r%Q?O-+`o=B|s6pwPVl9_?!)9uWjUDFOvKW-(G$st#${w%2w)$r~i)#C9=~QJ+I3yPTNuaC6FgtuFo!{ znN~8a$Hy0=l+j+~yX^z8wD9<;Gx8tQ)5MMQkXd>KrHjJ1v6mJ%ouM!ndp}*8^nm}~ zJ3uR4w2770+-@A*F)rQqGcEUX8KtVd%^X-BccvockxhCuDceN&EH0f^iL_t5M{2f3 zUIJw-*cC|JCm|OKjr{Tn*80*_;+WVa;Sth|qI~ua9=7j_XPcgOx%=efKkT@S*?8T8 z+Xyfn^M|(o#N#FGkYAg=<%7`0)Tr3F59)A6^wC#g`M+&x2;3K)-4=Dq*hp8$_2HmR zv5uI~onO1XmF17ClS)08K7@{aybciA>DBjug`&1D$!8dC61Tf2Skh*0oSBEza~&Rx z3p_1$Yy48rHH23{a5xd3uCb-yL6rwP9mp&m>Q7!8tuuNEe@IZ){Mpz)!^FG4vG)}6 zP+H!(ak0sBzOy}9j(ua(t)E@=g=KQm&PQ@N5&m3d!_K3%FaH-4p0WAe2M;iHf+h&7K{$u zm5%8xdzOSJ_jJ;R;)f1|E8G8m~pbUH$*lLoKq6-e9dA(^}C zcZYTX3Y3@D%?1wL^28?igxm7+{tJ-WiSiAQ74CGTxqJeL1SkQ_*jB$v;rQ2stT;sc*s}=%=(_pN<9Zj+!v-jd=-q z6__u}934SCkIsp#%7zYrK--0Y(O1H>W{Ahl+HzkS?XuOB>^%sG<-gq$MKmsEAn`kuzWy`&0%y%h=D7@odqfAOb6s;jt5+SL@%`PgkA z3Rm}q95UOi7p|M0-IQ(e%(2D;0Hz)O6g+fVrtp>Q?}>CsEU0uK^W}-OaoMKTq)d~w zM6vdOA-_4>hbHUj!HCmWvOQVq&?>xSFEudnQ5hXD!aUg+w(H?4Fp3~sZ9bK`>L;_( z7~-e|Ow?Emr{`JYb?f4%aDe=cnp5&|076g`x%cc6gB8r6W$ZqK@q^QKeAMvO ze%Ja~xQgVaeqnN`5B@ZK9VM{1uV$2KSwkX_O5l+dz+kX?yo?D_^cs#aXy&+zbmlyr(Z4Q~WX+{BdT8ro$%uw`%tz)Rc6WQAi4=NnW)7ir(w%Ik* z23T7J1sCla8bovr{l-|>9~rQc@sm8~Fypd7o__mX?K7}K=>|>jdL}Nu6D+N7W+(*+ zOD+vxBrj!7X2{1a%ww`*wgvFW@%|0cE6WJ|thN6hM-*X zkF~)Ni*k>3K_b1@LSWp+G+yraUGGU(*fliM4QN?`i>?yD-mHDk9&)YTCIrUP%{-(5 z4>FPRV5dhaT0*n7+ly@f9N+!#{G%uO`*c^)&BvR#TGQMNSWzhiv!9d|3<#c; z^^^uInDhWZTbU{Q~bDSPvIu4>~KY>Q`8v{hX6ce{WAjzJQacRMTit zQK9-Q1>>j`*%si84{xWwxzz;-*_!P_t4;(pPZebyJi4%qTksq-`9lo^dj#{2d&GOM zWM_}f^PPfnWU8P*S_T%4WTKw68_Lm1bkRIeK2UPKs6*3-r3@MVf@=lK>q z$k{mqSouMES;_mehTs0@g87d|L4EO8G+b9u%Cwu%gyvA;Mue<(;%#I%Wbk~fe#l%% zoqp(}I5SXK`JTF{&%T=+2F5Z|T5>RFL*gqpL1;6QH0j^(C#{=s4q=gcl(guqwi ze(j#2U}RbgWpxu}kq@WOQ%%}%?2Sq-D~)=6!kP~0e3#3A8(MbKy_r2XAm8Zma0R6d zc5F)yo*sM?@4BflW#aslRcsP)MIq+`>5IjyN;Fo|-JEV*KLMp0IlDk>vV5>L!1kJw z<%WKE0Q8qEN5rnz1*%;#ThZz9c-(1R-w e9(F|*g~MN=8l)~}4F16WGd^Z^wBYcCoBs#QrY<`G literal 0 HcmV?d00001 diff --git a/docs/assets/images/gateway_registration_local_file.png b/docs/assets/images/gateway_registration_local_file.png new file mode 100644 index 0000000000000000000000000000000000000000..8a227611784303c7c314382b891434c839319385 GIT binary patch literal 266981 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

    +eDlSEgLYle6i9LQY#X!dKoKV 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 e>{GP5R*8WU{~OmlP=zQ@c#i1))tij literal 0 HcmV?d00001 diff --git a/docs/assets/images/gateway_registration_store.png b/docs/assets/images/gateway_registration_store.png new file mode 100644 index 0000000000000000000000000000000000000000..997151562d1687e234ea5d74e21a880863714587 GIT binary patch literal 257629 zcmb?@d03L^-)}WFjy2_sHd&cEmC3ZIQ|2yOrWt9N3tFx-Z5F2Hf(r;vduHk=m6_s} zE2fycD3EPtreumJD3quuh^PoC2%N`$@B997&ULPHof+rKWw`JG?&rS0_viar?xfRD z=Z)*PuV1xl)keq(M~_vjHc3{kQakg*_rN3WG<_EEV|A2=v%{*Y?j4iB|HNH91G#kS z)T({J??0?syL$Vob<0lyzU)@({Lk;lSO2!^yKj%LS+(l!l~rs1>p4*1=kkAl17FL3 z^PivJ<*)v)X9JJrulet1Z<6GH_us#(omu{~QRCj_E2&>QaW-nzsx5n#zg9y$3}#lX zI$(gMRW9 zlCmeHl`(3s7~<-iS7NRe_U`U9e_WJRn5DMMEp991)7LMny&Uhn{_*ukU&^46s>uCw z_;uv>7yh{AlQ@)z2#_xSvlpUz?5pB~b#!z#WQ8r6(nrs` z)9&hH&L9SBF5*M_pSus&Tuk1lw)UqZt5*N}Z%FLRxv|cA+_6noj^d5saW{Fh?fL}d zP(*wACLMFv`qoze`sdGG>s#*n$EqFLv;wdA?S04i|H_1&BVduZPc29>JV4NHuYAGN zS1mZxG6RuU+GE>X|NUqC_Daa|mro9!ud8)S7}3I);$oii@{iv1YRMjQIY(%+{PnL@ zYkv6m-#*o@*`tNR^)ZKrp6l8w7dZGJ1aosbfsp& zkzbhu16%DkLbt?v2tPd9PZM>xVLTocvGhI#LssNPuG60%G0*(5D`X`WCkr~1M| z2U-#tUI*Nq`nA8T%+k58xA`|Iqq4G6Ht~iPp1{$8+t0qy(sOWHnR~M8x?}$7-zIt+ z$zmhgET_FfFJY#wL|RM;^og5p=6YF# zvxZE4F2Gi3cqB)z2j|8gj~!zRh`_p_xttT~EqrR;vm%$j&H|mD4w5xAG{9q}Ls4nG zI~#S7?6AR~SEzK5yuO4d%Clq4Lm7u@4h5&{JXd(&$CSkcexXxxba9G~h2-NeXIE-r zflq%?%7yfR#n_fAGE5U?baaK*RKD7}52P5oJbL?`JKw_^(Yg0mWX}O+V(~hn3}>7~ zDi&DYT$yXWglhd}vU$DlgIg@zC1SSrNtL%vZnz=mDJ$>+^-?nTm-R-I*Xw>>5$HkO z`GqZz#kS^pEQLU&9xHRvpN{-dy8a=`Of^EMDf(E(U)Yzp*c4(+Ec+n&^a*N6qFKi6 z6ElLU-#9CPpZ*YT`Av)pQ0I~dGNQ&ih{`ew2OT5ztin3rtAs^T4Mw+*7wc9*RHt^wv4 z!QgM@qlx_~V>?!;Li{k5zbc7j^Ft%QY zHwRbp-mqNF`#U%H;kF&zrHRt88@+(|QCEVbY3EX4h_ebaypFkT0q>YG-C19>IHFjv zU71>tf99_@taBQ^D>HyU%-;h(FZdPFbc^`em7a6JZR1FU_QwTZ<$2}SO_7CgJ1x%B z?LOtC;&?2)N`Hm}UiP`U0i<-?F{N8SoerdPHNx-vi9o zFN+_?)`S&&arC2~_@sOA9KJ-)a-4+!?)wMsp;!GYiOrLHXbFdmGWpM9LPD@`L;l*~ z%Q330bd&wbKd}4zn~sE>cU;`G<9BZt()7exyxN0u4>Wv|h7X||pB5Kz?1r@Ap0w^yFr@yK3fZDc;!6yF&J{mjVmDa<+njvA_L9A4gE0`RxtR z?eTx<6_C-ptt^Lyvy+a2ASH5X=iMEJ1wgZb@60su5nEDY5fpl?7+D2fD_M-T0e5qU zh4Ef1P<dZnS91}L!WFp_4U+01e}yqELDP?)YId~bKAwDX#&%~j&dAT) zIdNwOyz|4zFCVxZ>r*K&RC9L64o{aQF5cpmxd)f`(^ZZLF}@j3ko?{C?p;owP2}ha zqeX&BM!;JPUAxJYI$ylUZ zGVJDKi5&R_FHf@!thZ7phYoGkuW7d9QTM1fRT}yAN!lui!|qs9$nW9gpE@WPo7ZoQ zC=4r|g*Y42gYq)IFkN@*i%hLR>)MY5+2@5nn1$33E_OaHM}NJY{`XR`2^u1( zrP}$4-)Omck>t}YFu7DCZI8?2GJ$V^E~FC+a`RRd+;amyzI{5aEyC>`J|QG z;HA(r(rTH8<%|IT%P%kT#>WSOcVeeZwFxK5do)qKa>)n_Qw5&2ur&`)y)Z(~I+NJ< ze(%$o$VC$`9SbLiFhh>dA;>1lt37bLpqv@`s|_ZXN0;l4jIC0z@!I~^uH&^LEAaR} z@-&g}MYR>V(lUcEXAz(BkK&vChg5B9`p+dn$~kQsH+KX5(S9F1_|I2sVW9b3ME_a1 zKBCVZAIRlZ5WM9J91i;0A%Yf0KVjx5PW4KgoX?we)<@Sd^cP;Lc{!))RT41@B(2yb z6EFM3*e<-yT#4c~pjb0o@phP^5%VuG%75>~FZGPR#Pxw?hOxpfr-m?>5Q8t5Ow<3! z4t1+DV&Sl{$tcsT=WYh-Bq(0M4A$Qm+7af3o-Do%fCg3-qp$8H?XJV0$@ciFGY6e% zoK1S#N!7>h9(TCvqPfIiXsQ$ad`GO&E>o1tvz6PMYvO1*6WLVe`HG`9UpX(Ye^>wE zUCIk8k!W4dR!UA7#6(tM({XWrK|zFw#-Ye$-ow3~UTjgWv`je_Z10KCtj1oK&rd#6 zqNT$=;^NFe4_({1YTmt{cYBf2ob}=zLqR+w305&;1y;=WS_gS=5q5m1VVfW0N zuzklf9@=J-uHHE|_H`)3)@0-ON(>^&0jOJnvs(w&uFRgDYkcHfc$)p!8&!XIEm-uW zfAM?YWX}i)-Ob((X=$#(Y-gBgr-cm@)o6kB@LZluoc;szMJ_#!kC>NxPVpDHyUQiT znbSQ-AAnFL<#I)mqol ziP;v;HzK2=YTrey0Dp6R*ktC*O%1q~e5y7Lo@X~}16AFRlnVdWT_KXST5W@4>y%!? zO_H#GSG)zu1SAGv?X~PKamvoc6VvEFX-06u8B7X1O7ygF&u2(m*2e~d=iw_A$L)kg ztWg zSp2ZX3pXVHbW9_(mJMlh0$rJ!T?4%zbEuB5m&h6V^bpPuJUiry!>! zzV>?PObYs9t$TL1cZi^*rWk|EZ4I+CVT>;R}D0_ zWqpJ_^d%xRH09RUnwo)3X6!J+r>Fljf8her9#_QU6J^9I=oZQ1d;;jjW1d?OTV6Ol zxCRp*BMFd^=21RyG$qzfD5Zz)`jY(3ER?OPoiP1L#u zPUO6U$p)&YfhpN#Qn5(~Q^UKHlK!Oyqu33%8T3if13Rt>x6bPAXf^86i5B-iK7}82 z%~;45K8vx_?jQ{sys*eL7&UAogBzlR7C6VJP=n!~wO$0F&IDXHh)xsvyL6e*^2lU* z!SuE@lTu0k%}t+EaLa{F!)_s;7uq=7aLghn&|VQ}okgc{dxbcyVi!`WO`VnD&VN~< zQPlwQM9sV&>tC7H44DR853D?}tF1pXV$G$_$KNAD2Tl`+#ql_v-Obd~l@k{Jh%foq z@l>#10a3o`t+eMeqo{J!Z+CfPeZ9Njs(H+luH)yzt3ExwYK1w*VrVLi{GQT+F5Bn* z$b`J@hHeK>RllyAD=*E(BR?K&FWa>J@CgLxT?#(UUfIN3S`@+fyj^<-`Ndi;W|wu; z(qhFw3EKreek5{*lFL*;7Q9UeC9quy zeH9v(D(rA~)-A5|Pndm+7mas$4zu0_qKb68Ejd3{T3r0FnbvkwtpXXO#MsWf{EkOa z%J?uH9S%yU2n&xSNICNULZ)R=yKdsr>~=GF-)}I~)$_a_MDJmOW~u7!cz@@jFhft9oM8{l3b7!tWub$R+$Iq%8jbZ!-`p7`p< zQwTm}9C{i@>@?5sym+W~MEbLO_@zu61Lnj)yQQ@CTqPSyI4c^FLSV1Az=sF1r4?a9 zzxn&wjN71!5bX)LnXX9nE`*1>2m>WQ+-8-PphKDJAP736sOM@hj4Cu3j6s zd%1NfRHOO6=buc;_O1xKa+bhoWdA^GI~G{_wDVCpply|H$;cn7(lj!Q)7D$R*hTbp z!2q0**_GgPuP-*A81K>^v8&07qcvPj!hn`89fHmeTV=a}yvQnrkp4Y-6Ro>p% za0ko&PAa#amWo{}gW!QkRk37D9xJwN3?P{ZU(>~LQdDb5dHkeYnn0gd_VVL$q+er@ z_S0?zZUn0|WO;+9P1E@(`)rGLX=f;f5*FJi1JBCsP%%rz`RTiz;YrMJN`RP!62io2 z4ShZJ5$HTv*eZ%v)^r+s2D~_T8!u#w`kHBNT)|_qo5m@suot8pzIJ0a36xt_0K!FQ z@J?9_7cm;cgJ9HH7}xvmyhyxPSWzKN=e8ho>3d;d7C(~_RK6&2p}G+GifB4r6ac35 z*_{+GKRi4C&-zeQ@)3mK$6;R4hvA2xn0^Jp$313m1>iR4oIFtVaiQ5UGGbC-*=D5~ z$H$MvLN)|D@0yBHvy%36J>Wq}%m)VLjg5Qe8^Uessb*13>dflvfx7|VO^Dxob?u65 zj(@mq`SnF(dtR79R0sw~xhskW)FuEcAR|c`zeSe*y zIyuYWMdROTx4N!2YoT^`m}jQ>7_+yFY%yw$J$6R8&GBvPv?qoVmE1(U_1AehTSaEX z4n;V-Q@D8;*(5LaoDgI;t6op93aF4V*-CF3r?=zzq(K*e^+H;)9wZG!gKo~>lcMR^ zQv|Mb&#-W9znH&Uogo6V)N_i*LkE89=$sSxZbETQ~qt`Cn`Jl$ExB$<(l#$mRZ#9g4oE(d#t{g^I!T5&NUHZu6NV>K6>KJK$`bjNd9od(;t4V zmM)_yscp#g%GeG5umErXle3WS#VobO9K&^P{QS#?+t2Y@NSlVA6=B+Q9i6lOU(m?Y}_Y z_m;Yu_|EJPTD;Ft$tfzozPvD7ppWB4&Xs8;nh+;;iP+S43YCi@ZiVbx$DYgyP76zHOe3S^cstdS2yd@iq{709lZG&1Ck^tB)1F3; zmw#i;Owf}qc;_7vxA3~cX0Bd6fymnjlb?F>Q{v!gZ=SMFreQVu6Ae)8@y7m5r)eG4 ztYGU|dPj3_$*JB2z-&^9Ki{4T6C=~Wk|zv`QcQrUlu}AX3B8uTypfAcgWs`F4%X~p zg|N9j&ia)iC=Wf;rbbh;q~uZ};2?v6rjg2{YPv;A4b03=Vu4br@_!FIh%kSd*p+E{OD16 z34QUUnq9uqqV?-WJhU|?aw<=?6fBm@zslz^_VWcAlS|70z&dW`58ASe37Mymi9O|v z5CRPS<+_@eLb2Wa>Jx@`P{Iq|*Sq?G(Jc9#6hzAFz=A?rDW#O9F%z0Z`i4G>UbM3n z*7ZVr7la918$8Ay48{5BZnB*@QqP)AjV`8b4?&Yg8X--jH9~Qr#s$h1h8*5`ociQO>eJHIh!+W$!fH~(D~1tE zBTd~S3t$)6NX~PX_xAaSuTu*`Mb}^i*;hX#*!6zZ8Zm+`Dgu0hd4& zlP7$6u7wMq>S{9dB0V(mq&?w#f_(r7+qk=TOz!@{s-BF!?-E)&jQ+emATi9A>1ys0k{cV0KP7;W&>TzmP>{eH zGJk)6)oBXW5!XkI96KqNBcXE$1wffsik3AG7>gwXfzM3?_%x&Pqhq8O?nCay}zU3W*%3YJhKh~ zgT2kW96$S3n-)lnF2`%7PywJ`&z>)_DDQr9@ED@)#yUI(DzRJ~#nSBeF1l8PHbbCs&{q?UzKoEcrf$SF{Fm|I{kuW8YW5%~Z@!Mtri{)#XeNEj|n*4bWjJM^1Hx3+6(0l^jx^iao2yjWOuiB0T^3>1aFxla584Y}F265lR|K zcRHka1mu@?YLu2BOMZi2oK>(8g#}nE5v>b=q|Tlk>ab7PV~#;*im1px7U1cQvYLb z+9{pK1|t7CWpy$>*87v#JUlSh-$I#j#8`(bT1_^^PA6;^_AKc6XPP5-u?`_h-~FUK)9l`<#r#BbpQy^gZ0j-JIZ;EJrH_sb!2(N`&w$_W&wjOj40}OgA&yO{?g=R{%^`s?{pz}kmR=L^OQ@G1Zul1Fu zIjZ?m`*P&a*{>0ekCMFsl+uYt)+ps>=kuHa7dxmVRd)fhlEq#>c+V)=xE zEW!!<;z4t=c+6sFkhki!hW&Hit&ym1E9X#9fs7P=4i63Ee31@FIgVTa-MKyMWpALU zm}l^1`*Ckj%+SWkR;_$=fE#gPBw5^}PW3E(7u0`(AOZ}rmvgkrD07bpW$4!%Ey}Dr z;<|IJ;BrNzLnHPEB2q^UWS%Gp3F zAEuOhYgp867|v&)G4F^!$~@yTHb=T3W_B)RM97DZri3~IjY?wePh+~YM@18A0c zzq#*Diozgq(QB?|{4Tp$^{&{$e*}+fIj^Nwy%~S7tV}seOK&?A(0%C#{B=b(Yfvt& z_jD~hmdeqXjKBP3PW`QtwO{*C=}Nn3Od6*qs>H4TZd1!hW$U^95b~+OWLL$|8IVGD zY21~5$o@&qk@`y>t--Y!YD@?SVmV#cy+5o(aDfpjiSC++4(h-dmbzJ{6Awk?1?<`u zdug7EJ5wsIDCxs{2bWZoWQLyE%Fdiecl&QVq_DpBpE<1!p*dJ6%^iD+b*?Q69<0AWvSU^Cmh%sI)7eCeB{bxi+#{NEb zwJ{^h^&|DdxxkwD#wLKWSrHP(S}NpyDo~X$D5{A8mz~pu`s$+s|AsU;c~4;THaI>AgWrtKj7cP2A$OL5k%tDa{c>ZsO#KgKeU@90xiaF# zCmaQ5N=5g4rjryO%Ut&C&rGC-n+>`BFVrKn4As;xNKbKFw;U>LEFvJeUp*+G$ z0viufLjE3M;!Fbs(4-oOLlyRx4XI0D63J_RK3O1zFI^MV9>UsEyG`PH(1@||wvCep z!FdyfF->Z3YB8r;o^X3<%8_8A1qBSTz+Drp!xBsSjx$t>dx_U#W*R(wnDVF1B;n)c z^D9Ku#*mhY{;*v7FF849Ph=oFKkV&p%lfc(#1K+UqwjZlJa_xtceh_{5r;GC9P3}~l>}K`E@a$P%gbjF*ckj`0v5=~ zeWV8GJm4V^$Wr|eA6iucKSok^u8_+`embgl z&U@G%%4!`v2K$z+1N=L`h)Z>#TM-nlRrz7uWnRSO+B2Xg8OEgx1#k?cTln^P39-hqP4fFUgI_9R3MlrgcsbE}byf zNh(Im#I!?W=yUZY?=r=IF4pk9e2i7iaM9z1;zUEpsF6upypd7*5HtOgPDf+b1Fi7k zRI!b0csj7_66euxn|%)#oPJ*sGwmX|#Q)|JvuW3c4GCFUl1*&=H5qxuxyRp=ymTFwjj|E4@Cg zLhCfRTOMfxrm8=mjGt`4Vng5~Ch<9uANKlwri&Fa>teW%G{m0j*3x2+4w{xGfNX7& z=u$yMSScM)>Ed+R6ebkOs=I5PU0DA?qwQ0RhO`qFmOtXrjw3t)e9*;K{0a&!SNju10J z$+kV`J*gI+Ek{6bV%E~otnv}@r8f$BJIz#^#=i=KO`*K!>>i{Y;kin+9(ZbJnVr(b z?&CQ5TcTo!xEX(;;V1u$598hlzjN!a%7r!Xj$&(>E`!JD!zdqaC zsity!=w1IRg59_%{S&{4}0q`r`nB&0L*Blcce*_KY#BGdCl<=o*?R`Mp)E!nHbg7)* zwE&)%b8hur|4t2gq7g406K~%>VshhoK#R9XK{``+Ih}#gP+*W48Q6{8$Q`sGS%LQI z$9=hOy&O~qx?M6kkzGo0&gI4+1B8SYfT$X$<`MP=EsbcyaJGCdM{LW&Ov9lE62PS9g>K^JqUL9f!sC;_ar*#HJPiZ=T8hPxgqy+tD-lPDi9nRR{N3VWc~8u>8#P)eDp=}|vljPx!on$v7#eWh0Gj%zSXO)~ zBL;%v8GOssTk74X|Myt{|KGg%A8DHR*e0%d`s&39SbCF9sQ1ulPS!AK@ZS5WA8w_n zrorCA*5l%b@8?`^z)W=^EeAP+W@b+hUs>8r#X? zC}rkmZ-XRpvv2)qVORaD7!fniB+Acb$5Xe?ZbEO3Jz-Gby-APx!jW0}r`#!0_`WCH zN9E~4dB*rOQ;pY3#@SBAc=noFt3I02%VP`@!`xBM8kLplOZ-IuP376y0h0<3%1fx> zEpqb+$YDf;BD(Mb5sa2ar^I>?uz%rlCKb!%2`3dSIRgZ%IVN#^fInPtQ_FNXrlypc ztliEwpRvnHm=q0HP8xVN;tnu|5it@=;cI>gb6SYEwxT69EPItpo&(M^T2k?qaDvUn zlS@t-jU)|wH)&}_d$GI)Aj4@Q+z?MXR)mFq)`Y$jD~jo0L0#{CVuH#EH+*?0y7$y} z1R(8|1)>D?cuC~B3aK9tJiow6wSkJ9Q??h&0FS43y&}O*T<%t$xHz{E+aZ@C{O@kk z#Yfy!)9^l(NCBG4nS{ikrKQj6bu8}gG{?eb>DLSXpl*qf9pr-2kGYm1X<;kEaIqtm z*hrE-NFrlrefY58VhfOCMRzQ-=Yov8>j3UujNMxBDrOgcZk0VQK!e%-?{`x=Y6$ z_(MsvHW_&Qg0MPxk0L-VZwu%l^y%iF^4g56pCya5`Z?U!(E&#r++iD$#RkNslc$!t zF9Q&g5mnNTIFvPVYw$uAxaroHLRp-hXUQ#R!z8ajFa4x?7;fmizu<;t-e~rv?Sa=C zuFNj}xgogoTBQ6tzVQ{;C)TlrhJAa~iK0t;6sDZ!Q>wPjxS-Qo^0TLP5!0`!d3`yK|pw^sZgP72A{M5@9|ERON8MC|ZW^iJ4JuxP6AomoKIE zN53k;8WEbuw;NdjuA8^X%K|rCKl;;A{5O+3kec_xB`h{Hl1_z!B*338%%&wiPXpK> zL?*zEY9;o3;pl5n&eo2YWLoz0cCqFRG3Cm6Yrs!YEJ@eP3@eq6iO5x2XVa{Czu}PWHoGEZsW#K6nMuXL zIT3dlSWtUV_nBHlvIg`wT1Vxk;;I(f-=P>+cBvK$9QXCrLZ=0b>ufJ`$HA{&^+Jr) zVMD$d2jq(ASI>o={Kt4qDw(W@ZJu=XXLDa&pRHQAg+4R66Y~QO`ebiCnM~;*C({`UV^0>6J8Cv1Ymp zk%_u7-i4^)7hQAJbMqUylEYROu^vWSzc9ls4Rvv!MtBHECy7UVAkSmUPimt0+6W=~ zlz{v!%K%2zBOO7T!DjV9t7`?E?HRW?&9AXi^w2e2NMbgc5;cN4Y!aW?D~vGYa1Wma zsN)Bv6~pQ8v!~9VT&fC=88MB5+fv@vcVI#?BHjjNO1MK^gxacr=&~x{eV-codJeRq z(LR6ScXVXmSCzh@6WEUTtBiTqWT2XT<8egSSt#*%l19AD~x2}0M)a1R#sRkQkV6dNs< zz?kYe;c>?d_Nqof_U;rddoUGJG%3H9A#h8Sd3HtJm{``28Z_(@r(VqFTD$ji1Ye6z zgYH|;E;Mmcdp!cWM9M0X#5V8bwaCetud~`VQ-TO+U_isw ztP()m3HzqeE0<+2@kp|XcR=+Y*YU#Mj$+1A`s_@Na+nH;9WKUzTCMl?t9JwR z8c#YarKm{IMa7If4rm}MRGxXVho$6mh;sxfADsXw`F*X&G{9a!iZLZoKj#R4)F1Rc zz_#^lmwq&*mRa}EItG-vR$0>JcKjVlAqe+DILrVT{&|B|U7FSS)_QahbaSpLNU8gx zC18mqC(T7Ibp|O55u0qLeg}fW{d*D%E{wiU=c(E>F!{u=VIVymXOqr^kc3EjOSDqL z4EIsIvmh71-9U%r&7{SySs@SR6Hpuhpo%5Aw4Q)I6)Ifj; z()NPV<)~;*%B*U?k}M+z-ujeayrv1KH6cSorf)3>$AT_GLk&$sa{DVPwwL+gh++NJ)GIr(n_zvP~S%g_%Pdx-RW5u*eoXivXs2?cj+L zz#99e|Eh6$N7L1eB4(+Zf%I|a#=a$hm)gu6Sjb@jWxag5CETEV+H+e+YKOTgbm3~} zG_7gAV0W8^1h+r=7MqMdx5UWYwR5gbZTGfF7m=t#Gm!9iU}R}sZxVJn<7&%ejuc~^ zsCM$JT~cz+5Wc(N7*ZeDTu@^MXM(7r)A`Xl5}}XK2f74>+ly(nH+FSxS(LlZ9Q&ZR}1~ zDM3n>lH3$wfJ~F<%~UUj2I|^lT4modCI&FGhKL!FDl>6W8;2MPL*{BlQLVT;Qc%PE zz*3%kIgomPT#mK`PVS+p0L8q_y7^2>*p60mUQ1~l8*6yVBNOn5c0wAKy(S2j5UZ8t zW;M3?KR&^1^S6}!7$qhR;CV0Lq-}f_l3&S-JS1GsCQF{B+2P^#1TJ^9h^dkA<-6?` zz)4)NAWB1nx8PeK@(bnKS78$N9*ImL0MZNDmh$jf9>4BN@8LdG>hhUqaAq(27=g>< zhG^T!k$PON1rVM=kO0dx49qKgX6qTKw|M<`RCO|YfaNnnNFTZUz&(qi`u1^?UQ!Jium)~hE z%ImU^hs#LUBo}CtQC`T|0$)@`!0Bh!nAxke4pJhAH1M!;XLTrGr)m^9n5@w9X>kPd zh5@gZ61De2%PPw(Px$DWju#FbZP*1bu!0+A#7B)OfGoO`O?EPny)oBBMnOEn&w7}4 zG}ZVUJib(up6~ZK*_UOZ2^ZZy@gbD4@VuYhbR`Q&3BDkF_;3PqV1F`yOa$#0qc6w# zRfo@O&-oSZwvy=oBxhDD_lk!aXFO;nCBYd#2e$JKhi#gRu-AG!ZL(^-Zd{7xqK4D8*}skkz;ZO&GJr?!i!}nIE9=W!g#F!5>Ga~@G&x)!&U>m zilGTbRV*KweEiK&Nr|C`5k4UPF~i44blAD~TsKk-jM z+;vhwzUPhb%wGxhw^&UDKy)E?HH?#?GsG$yF%H-Ygkr7$x43uLKXx7eZ*OYg_Od6& zVXDb1!XuPT-rWbjI=J`=POJ2R99>5Ug%{DT!TP_!bUzzN7WAA`x~lZw~|6BeAJk5|nJBDDOS%*ZGO zPViq;qm7AuD*kg4Oe7>F9`dX`S<4uAW>V4E(72w5zZ6QVFP*Gr?G!faBEetMS1T?Tk`NV9lFrs+6Q+~pS62wZQyQR4_ zf~g#^J-9nmNR_7R3FR~B_<%GiI%Vt6D*MAgeKjIQaE{Y97&je303ZObzxdwS3+%RW z6Ds!zqH_Am(Jlj;$59e4e5rm>yVRPk2L9(b^=0?ZzrKj&TGp&zp;};LaO9kD(+j}^ z$lDH5V8o~V^Wuon_qASkr%(^zAt446m)58Mp55h?5pwpd!Qv&{C!i*<{p0)W2FtQ8 zBp7RV)MdFwDh#fe`E3am;+q#Q1~it>uA|M(9mNCC*HhrBrw$~_{)!djZD>KNzBDhL z?bAL2%eXNIXYIUi8LpU?m)nAK3c&s`gBS7q{z^{;*IrdF12(e8G9bZNobk}?$?K5Q ze>|4h5~@xj{7Y@he5ga}o}7=Z)-*iyyX5w+sk%+N|6)v8JApA^&E_<_tO$Vs6#JiE zRFI;hP?Clmf4%{;i7Dpmf4-Zdv!!AaTV;e-+i{J|dx?IB54#fP(G@(0Z=PF?M}OGW zVZk3|<>*HMR(W?n-I@r6gPnvE@F>#<{^_slFTzTy0h4~snQ-)Lk9s~oF&{9Rcj4_W z)E=xleNS;Q11~P{)1>nN`2%2MuY-3kQuY6ghc`b)uMbx8D8hm-+pLdV#%iWOv9yseY#rj29fWgne zDM)B|+73hmoK2RO1E<;KKkbsZckM|c!K3*=l60|u{7H~^iSNOD0=)N~81Is~KVS)AiyzGUID^S)1eD*n|Y8ytA2T46O9AZ2iEmzo>xEGPZGG+SJrre}MQg^=t{Q z>uG5kEXyE0&OtLJdn&x`fiI4bYZ^e)gJ0$R9&*k=5XN~(iRA&Mi)fh?S+A#f<;moh+E@zoaZ#SY82|Yi8zL=Yl%9O<}t??h}7q&EP`fPoVj6(OXqwUr6{L-O-_;kx3^QZ%qzQEWMfE zSfm-w?e_^q`6F4Wfdn+}1Wz|N>DE_vkpvv&e&KtQt-2lLELZrE8mM^UPnj3xHwaHG ziyG(mj%@4o;=t{iIS7B4!CLB5t9rlW!>vC_>6L9i{*zqfe~qkU*Y%;mXu{CH4i^8{ zl505yz`Nn&Y|@5UgD=N33bi8X7Pdv}^e_|lUd|8Vl6g(XE|qQChJ3<%{KIrtU7cfL zn05M#@H~T_#^_~+FRk2N(tjB){;$;nOraA~0&&`V zodXlc3aXvVvISZK*9snwW>HafHj2Potp@efwUKDjFbb)=(VH1p<26WAVCOoWsKBy4 z14yzhG*`naZ08>O-Zx@gU-plM|5<3CD%M`=s_4a(wEpggc-1#DI>6hTe#`Id*>aH? z;viXJ_|EBbxL~A%_cYL!gnnWljR2=HS&W%iBLZB;cFJ)Rd+zi3tr0|vKSP?=`~ zJ>XYhcQrmTo#bNK zY=Qk>?7eqflV{sE-a2Zn6)IFvSrrhdG8AMlTV+@gM7B&Bf-=I!kdPF$QnqXn2nq_a zWrmS~G9oJx*((u32oORfA%qZ;yzzOT=f2zD({WdRf4qPA2Ym8@E9Z4x$N4?J$2`xo z=N3?Lv#Fud2E?xOw=J|v2V+v&Y^lAyUUu%ckBdMA3Gm!W6_tbKd}9zxqIe{Nuzx$m z+osIx`|H#rUe1#zu4R>fVdk-aVXv6jK_T^*Wj|)=xE>w4)7Yhyr0zT}5_G1Em*o z<9s~~z<2{PUeFQEnil+E5xQI1#y(K=mYo7CoB7kOJzswF-RYJ+_FchE;ytyr8HRo> zVM_K)Bxc!Su4>;}c266Pk1@dOl|_NaBm$W@Yi50Sx>AmJRI*gp&!}x)e{T#!h9W09 zF_bcz)c3?K#F`#ZFgD z`b-(41lgbB zk-o<#A<6qbO(+{!n-#i%CKUBW8 z(}%kv`r-xr3(uU7d9mL-bo+%b9X~zKpTqBye7^e)TK+fKKFQ~kd_K4ee+iQR4V!=c z8QJKXamNat~*lV;QlJcL*Q&GCg{Z>}0xrT3XA zmSyTfCUJ&HPjrFY-BE;ZnKN5QS&XI8U#6(!YeZ5g&6!vsniF+h`cjW=@?xHS$M z0atKij&LkgJ}SHrHxZ;_O|C~-{|SQs!+<6B(q+LowxBt?P&erGM2DJWN~n%gr1vY* z?&NECR)5)O{yxJ&IN&I7RvY?=2*_H8hY!Bqu!*EK&V=|25A;0k1IZYF%P~vr#OvB@ zbo*;ZMkt5@j2tTfjrsz{+sdtD%At4LiL7T|6A5PEaO)-8-yV&@gTKchw>Ot{NbKCH zV#$qi<3b%5uB0khrX1`n|4hucAzGTWUD?eyRWLIS1{v|Y=NyXSkUk=m16|wAh8gE* zdbh(Qjlmq>I@fKjV<7SQ?j~!hegVM*GqP#wR%6}I8ogN7#m=Zw%6NQ<5PcP(iJYVpIx?B%gD;RInDUNWU%^YKrC_`I7F&y;evY$IL=Rh4Hj*qE(&gVf- zk}px&@MEm!H0SW4=lHzkwoGO*j8Dl8Kp<|hemc7n7?4``Q?-iJDCE>~MWNVOO-d9Z zjZmB01&Y{a78QFUkopu{@kRk43ZXK|lvdelJ5`9GPqNBLfsN6Y$zqI(4Z+UyQqs(s zo51V)uqtl~_}bUpi)YZdE}8XPup}@+qKi;bpb^HKX+DD{jIfF}_1$?=k`MqO`APCt zwZmAhEOg&BQeiwV-IFWXxc|3kh0Gx~ntBq%7BsSD#@Ul^m&keaKDyM>3- zT_`MIghG9gk)!?1yt;Avtb_>S>W|o3ZZreXCgc*L69_FneEac1@O@wQ4KE z{80h>>Wag~s-yi5joc_W35e4+Rp=8^bd@fjgdwdJZdI#foDs%n#`SSp3^UHAO1m6l zVrcGCBw;PmZK2E_xE+TYvP~lC!k#&Y@;C1&``TYb4pxS&m#u^SETxUFC_J{`pA9r- zGUzKe(EGzS*DOl%-3>~0$9(7>UW{3trGY7WtAi$`D7m%bD_S6iY(^=lg5mHMN(K-I zH&*-0G{$wRjW&i&3M+@1o#6%UOY9u()y5!+lPdr_&1AQDNRV=MJ@C?s*0C;N7e05c zWZZ@MWAygppXgG+g4vBOdmuLiOUuzFa|w>}#sF-e_AwG8MsVQX+qS;l#nlF7Cwt`= zySJ!ks&&1Rg0M4j#a#>Ku6SCC?3tF;t0y!Gg%|sn^NXg3dN{FjoVu267vvg^_!Xub z3|m4hzuS#dBL^oB&55yzInEH|#8q2ivgA){!2|Dm8akoj``(XO!YZi2q_5+?D z8#qCG?#-NwIm)r`B@b^SE2jM!6>D#EiYeBFS<^wnotY4@?T_5?-EZdtVyziv;8}k7uXFxzE?oU=7D3fe{s=&@ULcX!8n#JW`#ZJ8kjHN_(x0uq_OgS z$iy6zjDvQ@Ew$^_77t?l$X3M7yyTO&G&jU?k}ZT~y_pK!J#>c}TErC(a!|Ns&xMO=q^M+&jinu#o-o!vy#HBN-^4yeek6wGuWKx! ztF}A@!O|_Rx^3T9@W~z`mM3@z1w?EWl(!zG39vNB*#J|KM++=m3<%M6z>t|-4ZuJZ z{R_+y+$P!Gvhq6IUi|h6A%k!bL`M47V5P-$6-u1MdOkP@M8I$W+8h`rQ4WL!j}Y!Q z#?2)N4E*wP4B$-4nTkI0Su9(#-Up-m-p(f-)E6m~Wc9cUanxPWw^4P$Zj5In?kWy7 zs{lH23(%U!z#c%&S}!Pq7D1HaMLoW9^<%OO;#UM-%HGb%?|16$I0(kc1Z{9b%rF|S zo6eMGn@?;|R|hVPkPg&I#^4p{ddU{QDyI@|2bPK}gN^`l(=sqDG4jmF0=p(g@z_Q+ z*FI4+D0wT+Su)U$+c~*@yU65j*QLaLVM8qiDbn9}+sS{<67xY$)uErk3);|IKqB59 z9FzZ6?@;~985(VK&=cLYze@B_Tft{eDHZljhUml#^D0xtccl){*&FsVB+v`0heDfu z{DYCT9%L6D~%COy%UBulTkvO`Dh2?O6m7jGXcB?^r8}(F^*hlcSjkMU!EsL zl|bgUMwpMnXmCS*U0wxtW-7NBZkib9zIiRvP8P7zxHdEgOj?R?)l&`ft^-Io9P`Zx z!PZRCd2mBJMCk!jw`vPzH%;}&5#Dkj;y15ZO9(#UxqEFNv{2ttp{6?v>Yigch~7OC zIQiG1{2zN{st*O$=YT2o#~lXdIdvbb7=674d+(L7GWOmKO$Ph4XY^uqO_v}92v+K4 zo6Pwge$fg64a+oxD*ZYT*fqbHGmz@UM665xm^4VTD@ObxvRG8|QVx}f$aOA`!Nlj1 zM)0@4Z;CWBGKHG7?F%AEQB(1wZk{V^#F`5nQ?Cf?$hOzs9l2rH8Cqv5ae55UV2JL6 z&!k5WpPAgO_a1yfKp~ zOb%rt8pVFQp~Jf{xI7!y1mSqN z`SP|Lib#`W#@402r^My0+^1k-Q^#PC-5JEVE`>bMp^HT(GIRr;!={{)@py!uoDCqr z8y)9fabjb203w7=+h2UC1{)#;K`i>lRH0RA*nFV>dUKSQigoi(^4J6TwyJxZH*?J1 zAlfRr4bekv_TH)Dj@+trBeHi}4{X@EY`Q^KOU5mq;q}2E;XS`6aV)6efA#`cl})?N z?lxe|iYM#`Ml_+LXv;e9xBVxqbZaW)r;>9Yv{jk!0c3rdk97Z;K&ehmRF-B!<{K+$ z&R!r}19y{$xDZCz{K>w`-4MJe=}atyE=3P6*padbxwB-KZK(-%)f^9QHql51 z+4wRlthZw(bu~mAvh?tbtHGYhdnJ-Z6hs7LR>+TkPKbPAk={Sw{oDY93%=tIW1TBDx9xvC z6qY}Mf1(@Z3l%05a#^ZJfOw?I)u3FL?S&HO;+OQsB^!lxReXctvWy!-ua{V37NT&R z)jIyLWiv}jrj=_0d~6XcMchi%CT;d!7&2h55W)?%>8Gq)ZZG*32NVqFUW79e=Vu!A z>-i*SIve0z$ZBkg=CP-xRae_WwpaYMkIg`g9A-8eo7dl_Q1M)%zzEr$)-YE zROGeLwaK{_0O)vzlUc#(Rd#`4{Z9~nr{BC0F?N2Db$ffh^;c z7wD%N&)?KaKGk^sTB|?Rc>au@{#zN}e5&#Mb&&Uof<95uUnAsiG7JI=${E9L4-mGK zp9|LXSF)?7#&?=mJ)PbDVLQu`%a!=R-l82B!lOR4c2t+*|1vE5Yoh%xIyrk-P{95^ z@&C5F{|D)_KO1u9!#HiQXt^DX@qzc=*a`~aCCVpv+5r*nAQ)#gdO7)@doaHP$2l88 z=R#iH^BouFT?ON`QOdM;1WdupT>j8%@(DnHI<21o^f%=H2|$0%nV$gk2|$0!F8_&j z`vjm*0Qv-=KX4S^eDZ<*8W*3O=)W<|p8)iC0BT0G%`8z1djO^_Oqm3-uB{R7rZqvs%OtaqzkyI9ke36`CQ-nhrcl-f1D^g%@j25St5OxQ~nxFe{0JXo(QU% z7dNjcgqok{>KAd;4C?fIV^8)(BvrtS4j;5!rzM7(IT>XO*4-Mjo;`Qhg!?9?sAhHe zgsy6Ybd=hI)q78fiv657MwxnHR9zqO*kZ8?TW`Oo_=6L*hRF$=~zM;OM{e?3j#=CRd z5yjcV`pBq27lsw>nh1%L@GD;ZIr~v}szQ*3O)dEeSXjD^))x{5vYgLr2pFEYyH#$`zEk&&O(GRsX&5 zgRH>Bt=OT`q7{y(8(@@}+Rdx`nwLzyG)J~oI3iOan}&%R8&kdn_svPBA#5<}hcp?v z1fwYX@E4(%P50ue4C7$SKwNSp1s0>#x5*s3>alo1a_eH+@KoK*i71cLtDENT*(55? z@gX56)usM;x%5PiS~rSDP33ALbLCz4T+As&GJaxsrW@7^q5a7m$(kNvRxy$Lvz5AG z$ML^apg+>ThmL}7SW!wv)Xt#z`7S}JH>%w7UPeraFO=u4&|?32-H?X$iM?y!0I^O>(#@JEqCw${kp$3VZU^P?NwL#SV1hFIJtdFZ+j+9JZ3sAwkX&VQbbRVzWVH2)TE2kDIF`N*G!3;IuUHA1 zCLMI}$LY!kBUSQTK%U=kdCZ7?M6=&-kkvjfB9K}O%uL)gBdrCr#S8Ry*Rb#A?Q4@x z(ly+2ZC1_zf-Hr)c-tnqZ-6nyNngXXLJd?{^zE12wxTX5KhI(p)j0CxMj!sz5WQ97 z1}UR?X8#`3aiJWl|Vg8zzH(%2VG;;Hq2Idr?(TX;O-V#`W;$Y1SBx8)`{g zb~4;lYa`Yhcya&s;J7lR?gqsWSWrcJGLf6Vos+7X_$YK(k)zegGj#5Q(Kkzc6Q7di zwylY(oT^^LlVllHK&8PIni{!pR2Y!-g%4$d!c*Un3Dm#U0uGw!h~l^&h%*x$Fgt~qI%?OpBuO}ABqV=%fvgQWIWpu3b)J#%`N^rkcO)!i^NEjoS zbXDo)u)?CY^2Mo#IQY80M%tVsx5Z9zSlemET3dWNHhLooXj9^@fyB^p#njHx6!h(ry@p&}nw1^R z4kGM3;3|TF@>A_iTNc5Jrn+iTeAo3cxEhV)7%}_Yh@mS@17(p9@?rfv?P*aTHoF3K z{s2^jX$4`{28_8Q2wj9&I%*6oi&hLP)rK0`K}VvhfNjmMos0v~1lPP&5^Md{wv;4l z1T4hu0*Jj;1u^8bYWT-N$RsCxmW-czgdrass* zzz60w(&{f^m?)iuf?+=!Tw{Skq4|v0-4@;k!9|g~nbKCip2T>b#rn*(Oe?Ibgo;c| zut{cpw}jN~Elh|TK|Jz8OT=TN6pO0{gZvI1$a1lr!p#-;P~%edT4wD&)G;{9x1Vgk zqkqCXguGVt&w?6hBYDh*Tozn>OGS@C=q& zfrWqVN&nVj|2vd@b3$OeT<;7Y+!?2R78|zT1yX%C1zL_%4b*FnJ63*eCWEdxLJ8*`FNg1Go&LLi4 zEqeBV!v*$cG4({dDG?6cm}fgn3>DoPm13E(dk!;-R*v>kP|=&>wdlnXwzVp7D_cpz zOx=kt+~h5Cv-r%ZWrrBzC2OI5uNF4-4xY_#TUc78E!hDlGGcPKw-oi?J{f$yHq8%L zm|a*T1c4x90~G~qLsxkNJj>jcT9$rxD9{ujw315eCu?yYA%>o0m=(nkGL{e(##RP1 zg+UTcZZa4&GAJl>!a1ND_huGTG=1gL=>n}{?PbAHeCC;qgwAo#*0c95c}mNvtDH6^ zbQ|YNrlKYJ9tEnN0T5PZhYz#t#jzokKs}^G!Ac?#x}i9MdW$knt*Lm7qZ+&*q85FL z)fV4WmvAdB8eGGo6x^}=s(#hgn@@+{RpegbIuHgfjGkAdZyTn1Lx;2srMcC4Q%n5` zLsOeQYb$&=U0kBgLUmHINtKayz3~x@G330$Mvz25V~gXKoSbo~n~hpn5}%FoT&%lg!g`g)?MZtCHZUJqcLanQ4UD#M(CWhGf5bGO@X$VuO|0uLB5DQ(SB}? z^*D;EI9J)0jZni$_XF$6ju7qpgefh(R0UD4z_@cgzi#+xS!H1=U6U<^ z_JSy=iWjbF5QgSx@1hv&6`co!Cqo!IlJ_cQ?;v4AjIgF{HlJ&vsVV4d#lgTQi5-GeUUoEAB@~WUp z@BQ;aaD>&NHN9S43Ml$5TIoKH67GL(&^=@VM&Gi70=H*K5fxjj0bipw#Rsjk-aE=m z;@ooLYg2{HL{pnRaFr&t=vy{=*r`^d4Q(;0g5@c}blNX4WL9sSrWE$e59J&BmY4Xx zqL5LrizQWeZh>z2sFTx+T+RyY{Bp9c`+ZAa`bt`?Y^`=4Mw7tHwb!xtiICThP9O`8 z^^%%CtO%|bL^?4O-&Xo=|A z(6n|hMEbIByG`BY5Z7IgPP;@z^u^KHO^_-2FK!L$v2a8C@Y65!w{AzAF7&Nnp<3U_ zPdr~ZuWNjZcnjntlwh`S`Qo62L*0$788`rpedL~Il0pyPX~p4G`Dm@+?o-gg`$OF%2b*O;jk=^ z{2$r}$0m$Ld6GEP_^;H&?Wo|zeP5FK)V%T2&&{&YhbXnLp{M(tzh)ua4FfL3lby3;OFi<7Z^iX(nsFT6dZ!@M<3 zVQnN^e3jp(Dmd^YZ*g41SoA0UX10Y#%+p2I8;x9Lz2@h3bKV7DQ`^ezclUe>M%6Zj zreuCyLv8lIdmVxs=$zgcCl_fZEz_8D@j)1^U;b?iDDpyL#+dt2(wle-NPvrtyr~dZ zd3j&WYqEw{w88_o`ep2MK-RFtzPxRVytIp@KD%z>?TXKwwZ&p&ziR1eA=_vQ&aUfT z%5uX=)$%?1p5pBt`qFAP)qwoAu~I_3jV?b*rumd*zTpqnxp&RzdLuCwZ6~VXeh^U5 z5ZUML^0cgV6FSY%kl|?*f4Dfk&RN%DWGkN)Re4ho8_qR>qM_P_=jB8}tZ%6)Ql|=S z8J+l8agC*xfDylW7GR)siW`)@`{V+tlmSA}U>4odi<|5P#MT=f(XqZki!Hh*UrKTd z{#`G@vLO_PbZn1v*O=ReP^6x6`f5RC6iX}@Pe+Vo#ugr*i z3`+j({@Ej$BP^s^Pe zmX4=m&YRG^4}CV(3YQ?hQQm)dAl|Zsa*nz-jR?5j0D$eAL{u0Y&v4e}Mr5lvZ}cag zr=ZrT*_TbFU(e4xd6JYQDY+RUX%s21VG+eYk44Phduza%$7$TG8*IMe9YsdwIOuKN zQjrLQC=|Qd^s|mp#vKY^`@7M04F-d+IY!%eJ$bB1ePAolGYnS;Mo$WT2}3EFZa;BW zA8bUMk4yizn;rt6A&g(8y%1w~A+*H`>o@j6W6s97hu~qJ$1-(?i#a_kVjQ;-sH;!F z{8E7WV$A#Ps+2aFF%zm(W3awFIDSM~Bp0*YkL?A%M{V4BY(~J#*R(7`_to^otG8{o zIYP#S4ISKEcein{}c-U z!o=@Cv_JdqLz>Ev#6pxNIre)G&^I6(H9lgC57Qb+--}-3ZTm7Sho=d(v%+(&`mK>n zi=u6K6TrCs%bLYWW~rl@VnQc=G7!m{5s!8&NH`=pRk$C~_JN{`cPkbdjOZ0LXweTe za_XDkcnASDi#Sc48_O{rb~EG0^bCLaY&Xa2HvbCBs>>q|Hua6O3}n^7461h=1vkzx z2IVB_@7^-lciPDk$13x+J$nm8Y%8KNLVpwz>p|Jk>ebosFs>xOjo>Ww^kJ%^`f(is z-qfqV6Mxf&a|yi07rG%!FA!EuG(!Wt+%rop$q1cw7X?+Bay$hLGt}-+jy#a#P2Z?< zuFH?P%tln?dVk!SjK}c;EmKe`|Gi}Y`NV`fpYsI3P1Hi6LqQJ@%RL-?J>RGP-Fo4^ zgnQG1fITWLZbIkGN!idM(@YjOLtVD+>$9-ueM?cEd%w`I4kgCq%1;>EpQbig2o;>+ z#+<1pT+8f9M{}HWCAWs<+KN!pj+4whom{}2RVzLuQ3$$G6Y}`$(aXPx1x}S)F79p{ zLa)H9Z1nwx(Wf$E_vKXnT92`aq`o_5c~d30<6wa=6E;Iha$*aXwH?X*4jP$v2?(m& zmRiYeQu(|19Os?R=Od1y6RG1Y*f-fu3 zBMd(eQxesZX(8t}W7Wh}<3k5OprpXMWyrH;@F8R%$+M#WTWq8-k6Bubf(JM@Ty>e- zRm$1zLAihJDy<>kOuMF8BLy1J^GXTOtl<7L%$~96t$n_u16SV|#ZA$#B(6p#H22=3dA5ig0_eR9PfmL{uJh`!_UAKI#|Cq6dwy5x zLdk&@VT69|EZ#HtgU%tLp@*M?`UOWZ-M)0qeC0xJ!&zuUu%C^ie}LG;i&tkZ=da&! zzcmut8*91-O^FpWmKPJG*QdF84#yXbJ+(jdfFYVoW3n>n8wns)nMz#65`5k2u zkldm5p0ekmKF=V)BJE439=O8~vX$t4SyIsNQ}1Kx&lj`JbPH}tPfPDlu*pEWDSjObu$&2aNff1C zu1r}(51p+T9@HnQCzsP0z2P!d`W9j=$Fd1~DaMyo@f%_eU)%i_ESb6dnQgahSLO5 zl4@bco3C)gLuR0ol(O5{$c={T$Xj_IqpL6Ig1S)kw!hyOAA_sk;O5jh!3yTDn$4vS zuH7;JjQj3#+LzINi{7^uh7*Zp+jmn<)=3y+pv|PJh@$N_WI|hGMljCeI!2c-m?O zsXd~`@L)V8^ZIVMvl2($^Ot>`Zr^ZP*Jryl*idp^jcZ&S@?VRdj7tm|8(9p%42P+8 z$Hyd#ftA}&!A*B9?-jb7%G`2tOh&=3PlIx{pGEa?UM;mF%fL; zDaO!EGlYH0$8FYJd0pT#`)|(W>HP))9|55Dx&7uVt_GA7OJ$`^rWFAOiClP{op;*Bq1&^m{D%7Eu?OtO~y z_BN)Lvf6G9r1NB7hA{TY#WUJfikA>QHfK<4R@=0jocL36y6^AO67Rji8{{%O*9j#= zLf)_5uLpN$t>sJf6l%Ldeaap7M3*H00&ej;f6Fi$XGwOu|Hdm$sFdqWSRb`@dr*+k zD{v7y8*1;kjgHBtwL}K%Bu8&|O^gNB8CO%7w0Nei3tXJBXZ(C|2vXSM@F}J0E5%RA zFgQwsS#NYo#KgQi3B#QiqBUC1hyce5$KGvibjNJyH^$j;>5%*+;0#^D{St?uaW=D8#i7!QwAX3V zh|?*0lY?WKUZoXdZs6wcY_|r)4_%#MBP^u9g1^2V)A-DuAM+~L`=9D&8V zh&5wjxQqa(=Ae#<2gjdWn%ynDt#b{m1vaYV(uOwPyveq8t2Kh@E0#bXG|6x>9OFPT z$q{K)sX*8DfPNi1gdq{GH17*_{-@=--bd8=P7hKzR~E+C=02bT!L;@ zl}Thm`GuWqv*l3|?J1+_uyA+RLmR~y<*f*pIowNp^XeF@n-wdo1ft_NQSWJJ@j~<% zKN=i_)I>w;OmW4xl?$^|fg^O9XyOKYsz)dz=y|@f7{MKUjm$wG$82F4PGn7bAQ=j4MI?Gu^u=G}dPT|%J?&(QU;8pVQ1^Fj< z=^tPbrMQ(}l`#it69ti)7SV1p@f9*i-Or3e0p28--r=62R6Gczhn`T^WfhqV#_*FT z-zc6M0-9VU4cn#-PAY}yiMVpKx|%Vmo!qcn>Z^rPcdc(slnk#zw|g-*EiH)S37ob1 zn|w3DIe#aOHPRHH!V>0}c1KaoIdWzi$iVj^#OCM5BG&w&D=s-~MeqBx*&5RRW)m8P z2yuPfjvxA=FzxF}nW5Jy(gXUCjntvM^BK-IKpWEir5FP38MhI``!0*f)>BUJp-qNF z_JncnzXcX@Jxdf{wOG>vTtSrbG5XC!;oM1GJCthYopgK zJ)m>8CYx)FfiW&G*fo76Qn>n8BCePd9LXfI3$=Jnvar$slZYc&Va9$D3n1R5_40Mn zmxY)r{8RW>Pi;S{03Yu9PSX`&efJ}{@%PqzSU{9ja!ytHvfqcFS4n51-WV4sM2CAC zWW@=|SdxT!TCz7%3x1V!rVaus3qFG0yt>K!>By{_NE#)A7-0@CXpa`jY8 z+G6vQ8sia8l(t)5?*Jw5^G>E4S~LAS^!xhSAQoPRGGE)%yQMVhPwO7$WlwUhI!#H& z=bHdBkmOSCgtz<{1Rkf!BW+X-=Z0ny%kx9kpF4JOGCTy{lIGUM$t^SnD z*p-GbQXKlhatxbm^_2b&|6YF`Y2I(R;o0K(b}bB-cyC1@meq_=?%O35bbj=@N4Y+% z1~=EqY=oDUGHVt2F!aGKhyh_a<@P53#VRa#tjxvrX zW9Dmh__kuc`8meg)wkW{ZxE&n6_c$nt+$}2GuOnatmzqzIqV{m7gjc5TxH@--;^N~ zHu1OPzo5|Xyr+Q7R7N;(=i(LT)_oyy%9lV=IV)i=z$qB6jsF^hg-BGj#G->uhzqv-sEpumUg1s3 z&oUcL#m`hf#>)IV>-$-((BADA@bfw!H;=!`(fFCQ3xlQxukQ2!igR(hAmdZV^M`&j z_D2PW4RY_|kW|02|9kq%$B*{-{O86i)NimicgmHMhu(MKBO8WKd{l({ZyCIKBAEKf zFUeD{a`QSs|Jw2nH*^$WS}^tc_ri|t6pN921Xz?(iP))@g)0fBUh0+Zj#oSC zf52i&cI!^3Uhmu6fpO&j^*oMW?82l-T`Imk`-}KhwiSQfs?Wpr{-3~u`qlQl70+AG zXQnlxY-MTbCVW5hj|Jti_e(+a^0|1=H-G&9->Cmz&zL<*K+{>!g9E?+#^~d7X~Q7; ze9u`X}V3HN~>p#}X z$AZmooUh(K|3{7Bq z{|gMK?B9Jjnto{fgDE$C*)J%v9}#6Ono z|GxNzh=9(bPPm-#+F^sMT5zMCyBqYlQ#luf_zmCtH~A^Miq)^A|mT{y|9 zz%XtlCoHW=Exmbn0eX^^G`bvb9;QriYB)V0qS zygUqdo0^#;2Xo72CWhv9CpYy5P&8A;#Mw^r?B&LXYvTG~$lh(xxHMEg`hUY9T(B|#E~@!)CH>z} zjGv95UYO@mUK11xn>2s)&T)@u^=i)}saTTi8&U1)UnKx7E{BK@FFj6gc9Q=g#ZGRu zZ_l#%0>1WLPgU5#CN>K7#Qa;qfqTnV#xN}f1tMzNP%E>^x8&#)O_!M2$kno%oEB{C z*LbZtId#=a+05S#-B@K;5YrLiSmijex{mlsBe4m%{@(M1uG(Z~wv$zkHH-LpbafGzsc~Q0L)WIBI15!NOyYj=JCFC9d8o zIN_Vcy&QN+g^KlrbddHG-<3TY>ZhQ7hSm}v=2ii>_VhmSeSqor=>zxgms~wi93c(t zaLRE#8UN5k?e6X~DXsIbzhKr^PHZV(3%a5e{{6D{P4p~#_R&5)vE-2)h9Mf&)wGdG zspEBDrk+L7B&y=x-_oIlqD0HMJVSWbZCa&)@qGpdIT#(}pRJLVnqt~E!l|wte8*G8 zPQj1E6eUdMLTW-eH}AS&$~QXl5LyCXT>InMws0k+KApBmMDo1@*ylu{AHt8uSN zZjQolTz=oL{{g^3JEi>-g5!`HXttDsK2wi+lm-YpW#FP$T zu^o?Y%sMKLP(a7D>?%266)V7ce!^E>tw+khhm@;v1y10?awC~Ujvr%oo1KS);_k)ICH!4;D-`&1O&hIiQNX!nzY(N07tz(brN;Rl#z=<{QHtU~}ckE$# zL7i-`tMd6B1`m!cyJ}op&TG^69)2x)c%PZ})1b&y6It7%Iu7!xLZ)wryS#w1u6Mo5 zYttqUIhni~dFLk|dw4%MnVhL;mu%wcuJz4DJBjl6mxsQLY|VXLBB>_wzB?feX9;Ty z1A8skJvytcks^CtS){*&exa&XJ-1p%dVhd^ccOgt1f$?)&C51}34r?`&k+Ji>&#XZ zO%?0ujH%~H%{)*%n({3p334NST(&n5Of=WKLg|sBQyk=f$zq)349I=Q*wc_Zh>Pr} zhh+6Pa5+DZkjJ4(cJzVFLGmo|}lrt5Qn%=v71BKb{l+P0opJS2i4m2yC<6}ZY%G)t5p z&@l?*bZ<#WrZ5{?z?P9y73!pfs2M%gYOmr5M_m+1dBLtOhl<(mc1EK00^wqUWl2t} zxr+G?#@c%B=)>sc8)8A-^Z&H=^1zLNP|$?ruZr+E4KNfCB1cV$FT=_?Rn z8aL?piwSAS=M3J^8jA5SaEE76w3ZhJU?HA7E#o(CZDUS65VDlHV!!4`^AAt@2f5D8jOo<|-!`9{2r5+ZOQkh2K(ZiYJI_g$@i}o5$$c zy5cy7_nN^WxZ-9#55KL;zMWKT53$aVfz*!pA+ssvTR>C`V$ep^j6u0to!EMT2KHc+ z7dyS>e_#=^X=-1*eXcAr%b=YyX$0_}-!A=!ewW9y4{_7?4!t@%H9QR;3{MO@JNUgx zox5iI`$gW_=Yz`W4y?20-OCaQowe6s2z?0ET(9N_rjWw1{f_6yvU8n)61A>-0+Ou` z=K@p|d`6Pxu@%XCF2JVj94eMl@b6ozzIvb-7Fc02=cvi9aY7qPaBRkqPV!%66O}}i z7!XReO(WsUAZ4pU>D12owQDd*2On%`&XlK{=-pb?lu^&N>gb8kdTk(m3T2S1Vx?1E zcep2`&3|{<%UN!kjzfjQv|XG3gL_&wDhrLZ#-k2djTVCa-hCsA*fI5OVnnrFHi;W# z5MJzEg-jeR(eAY3=*oBqso|ls30@leQniSn+-kGn4AMDbTtW?GnvAa|` z_vcVmM%}$3>n3-6R1zt6t2L;e3_VJTYYQKiNXlbMIXl*1#|Bq871@gR4moQ}<^%Fq z+;AnVu^$_qU48{t6PABD^=P1PiA>+;0XrLGO}agm$Kd8G>-T3!Ye#Oe?X=F~wCigC z0G>;=vvx8{JDg%viS@i@EZeugzP_`B54 z0(Ic#;|bu3`&rrV&t32vkca$YrduW36ZG`ay|IM{+AjH)e&3Eq4Bij!Rk)$JY)6ri z8W6qZ>s~z+NWOT3{i2uBa9reK1@+rvHBOcMhIC%Sy;lJSBE2X3igmb2>R{~n;Ovyw z5~7H6@UkrSSTdT4mHRw6{JRAw+_CuACZK11_XBS_V5+5H?n%YeP`%L+Td}bS@aa+O zp*C%FNFQ@pez1W&XI|nD0w;#QTHj0=9(w18LY?A9`X5$na3E8HH@KQcl9b0mGY&5F z#|z7NjVAH(8APH0X&PU&DgpW^=vzjLzV3t@IMR*RGp)kn(=Cs{?#Z7~Cmxne5+tnN z#$)6rnn&f2x8~wJr2tIbbk}cjOnfEXL_`!7!bQlKzLkRtUVV3<&z+gT=r|gc$vNy}M)U&^^k+;i^f8mqv1#52e zl^;n2w+;c?vb@_QmE5GxyI;siNjAy7Y<8cN^3r_nR7Sji+t9C=a_jB`XH)6X-=;nK zh2!W_3k%H`J)m*N1V(#hG1qTTwp^r2O=g@-CS6SQDVpC^3)3y?iZSLuf;1h~-ESo7 z538=*yJ6IyXs_nYc&!;w`fk+3sfM={J@U)!HzHhAwrw*}XJ6p~hnKekwF=d5Myrcl zlq=NgD}VW5V6sf#&7fxLG8nh}IAzlLiN4sj(aLbk6JM8~*J9ZF0MhSWA;Ny)_<3IV zyq^ln>@_W5k0yaz5R-Bk*~CG@opHHEd^_hzu2B+>%q5Xo!9@~EC}Hh8{j@3nshCx* zTWSPCj@gFgD#(DETW#`+KD)N*R;$ZrJP9bVXiZT|&w5O#d!+rxf#aK!_BGmfi>Pv* zc$jhl8~=aUd-8aw^Zs|cY>zD)m2%Z0%303b?UqoELhdV)oRf2m!K@B)hun-vWq~(yzQ9&d{)s^DDJY`uTW<1*;^eQ$sV|Dth^5 zH$@zEV@Yo*NHUU)M|7kKUrojh2>nc3nmG-ECxfn+w-KLDwN#UrmR8}iHj$`U7dy~U z)u}-eIhyz@9c(=Cy{6&P+cSXzjtD%t5~e20N#2qa$`y9Tz=V1jrHCWC)9fR63j)z$ z>KR={7`@RFS84eK=I zPrHz(o6GG{%|KbtsI<5gHC=l@pLBdUgO>Y!wDFl(0fE?%A;0`e^ZO3t#Uer#t{Z*z z!N*MD@9N5Q36d5uq-1$rvmUPIU5~~A6}q!~Y+S}%f)lyG7dut%W#fpXYg2y1+K;K# zXzwkJRyeIuc3Q1PsF^q89-J2Se7(!pL~hvYu+vbjrplw}AxKM0C~3@M?#bn4H|&C4 zFmAsNTC?a%awEw+MqEQE?{WsbhqhjsU5k6(*ywj$>fM{0#pyl1yZz~ng~Dxns6cdz z7Tw|Jt2RE;S~5T3N550hc!x6C5=+g*jYFjDxRq_~088g`B+b-h^|^O&&QovC^Dfz= zk^w2?HOWzDxyjo8{Vu&axNqbu=hWcdzj;-Fqa4`1X=*agoen zupB2omcT9+17|f>BcBret+mF-F9*fE4l;PLjJiGH|Le-$HrgZmv84xZ7gBn$7VpNE zh-L?SWsiUcsVXW34eMCw$}jR7qdu7g6h?*OdnpJmq3%Ob$~1p8v%cKr&a!^BLR;uM zZDH_2&0EF^dV~b>mSmOk^diZx{m_n7Li7}>2Q#_)+%6El@Pfcn!M{s5nrSLbjiI$e zpv$}qS~zvgaHId+3$=m@MUUo3k z(GoIwTWPOiVb;8AikK?S%}!b^b5?Ef%mbv%A=Ji5^Eun`z@V8<|GgUJWY+7s>Qd9apL3%^cB)QoZyX@+`0s8SdEme;qV5fSo-J@Q$#&SZvnOs@DvBD;F!ttcS zfcjP`t^~doYpLTQ(AL2A~#+2E{W?TVJoWHUak&y^*NS ztrf(dw%x~y`BQ;l!37KpNE_%X806lq?*J8SaO$uVUOLxn%9L|~Ouo_HS7Bn@i5anu zq=d0WyzI*P^+6k5_WN4Mwn1%SwElFT6E$D!)@5tX#W@0TxKP-Bnv(t^Ve-7-y&EwU zpOFJdwt7eZ{&ebWZRt8O|{S;z5-AV18xTJSKqv1kalXA6a=~?%a@mfxt zUCR{O^MH{!(Yrk_#oJ{ch}P@tTW7S(aJ_v!w;uTR@x}D;D?#Z-+iN-x(cYX97T!C5 zIGow0jLQ_A8!VyNvmngW5aM>%OLCU9w!r17-lr3X(D;EpBH^2@sD^#EA313wMiI>~& zRtY|pa((d70)18;D?;;i2MZJT%tz9rOyU(tY3`7YUm*v!rx2C9$hXzbsumT5F36LWSmfSU^K}W)$zhpu< zoyeDj_jU{x_f`fYK;Eo3N3h9zV{Fr5>Vr9%+2Q`Z#z@ehA2AD$_r&UU_jy+l@w!Yu z+%zh#;w{YQ;hI(K%4qQ3>eErz(KVN4Ghs1pwCoimO@T+Jh!IKrB@lZ}#fvz5`|bDr5aB6}3shw0g zM2~VYXkXIG;cL>pMm~HR`ziapGvq{2;yK;3d0& zKrNS`n}YGjX;J5LY^Ne5?K&hCtYbhfmdXxpA~`i}2aPTN74qm2_v&OYQ|8p86hBhfczETK0D zKcu1z!b>kC~_E{%kR)U2X zwgzjY)C%FiQnlK%k|@imhuE@UYLW9L5EO$U@MHviy2R#_@|QdH;i{?U{aJKke&srI zLFP!^#6LP&nrUVAbs7)(m94!*udFAz z&d)5#RR)<0w?#{!J^kFR1_~Z81@*ll3~Ef2b~@ktPbBwkX=~rJCAH#Or500g9o2En z;?X&bqv}*c=#cD9+fioVj``jzjyg2G*dSG^ZPshvkvcSNfoo<}k{mvN(Z=>iTH-rG zst}tYoo?V}FpU*zTheBYLp!!RchtJ>GJ=?U)?cMxQFdS&SA^P=5UN!ja+G*JlB470>RQ!h06v`>V5L>HCiq9r^Jv^D!a4>=0sf)MoI)I z<@e&yWcXg(Mw56Vn58M)#_Cz}b!HGt={3e!KL#k@%OSv>=?K^h#`NXvvsDI#!kj?8 zSM<#4kjiya@w&Zj+)Ld!v%sHYcVKR#aA}3-;2!3PyNYp9Dt-ozR_51cu>p$)M!YJD z@)ug8naOUAQiF`wupnzOTRO)CE!2I9_NG=6WWbQtE0b(erE3?yJM&|i>O|qw8)O1? z- z=IFdGAzycS@CiWxO}xXK^}>yhmfzf_RulJn)oe$Jl$F*Viv`|@bJz;OONGCvA>MN` zPoI4#+R_>;G007q4XrH1sdII{z?3zg(xZep6;(wG4o&<&$1`DP??<`3~xHagALEu3jvXVHaJ0dZV4_L#F!7cSbcKig%B--{9k!o z9drW?&STbuXlDH~i)Q}>-Jhoxy8^&_lcFAYrSTO%`XDpqKM-zB`|18LLPV-c=R;*3 zazJoV_u89<$luVZzu5Xg12zg|3hGY33w=kZBnj?bad3!xf?#G(uKr8Xphbq*il!B( zdvE+o4xC;p%a>ZvP)Fpu?!vOsdKx? zr@IeX*#Wr7gGkZ>n-TrjZYQlCHgb!2@9L{CBM7yBomiiwRU-K5&o-YF>jK;%PH8+W zzxDT@QsmZ8TK@$Y=7`^=QYJnE%Amwzmu%d;1$Vtl`6)d{WoSa|9J-Ff>VUjJK<-sN zw$Xk5C$6vvAy7jlu3@O&sDMB8_RI0^NoA{K+j48oYvi-gehA*+ygk_t&z?35`G`6< zQSvJOOovYM;LtIeiKg4u9s17D0NnfGj3d95NoD~*W+-m>dj~K_ZEWQ#2sgo<{H7=@A?!UA%ty`qEwrd(SZL%K&n8w%bQUV$EkODb@a$7tgL*~ z)*;kC>Ob>`{!~!^6bvs<05`Mx2UXsamz#nmWLkJ}xpP`B?e39_sK;@4nxs@7D2saq z}kMt$f=$ zvH}F>gRaInRFHl*ZX%rpiVX%G4MEd)eCLnR)R&Cc!y1dw@-F55EqYsP)1xQDfYT{m zn)}8Hx<_BR0|I0G;NZt&d|x%R9!q}gT{k89prM&V4Zfn<;B6%K$i(Kvfw+^5o(kT${{_?t@xin*J6*D`K$Dn;Bdc#u8fc12~V0~Wl=jBkD)s@8RjZNbaLOv2C zlL(DDm!s_`Jc>aq3{`KS1Td*xGN);&puG8t989(Enq&8k09qzvm*I%f9LP|;foNUO zj__++HPBkgn}_Z_r%`8hfD(8%!H;i?6t~5~*2W^Ca2f|N?PZ4-dYmI~`EGGrF4mY4 zl^ojH%wG#WKd^;Q_HPOaDFh%|c+dSa0RLje%f49^{QV_)oey=5NpmZ|<-mTNf5-au zMj-T45W?8CJcowc>R`~eNU20%PW$dEgM|wiB)H>o!TMycw*P!5pq8~()@{Tz%=J?A zpa}YM<7>0SQI>K{f8l>=FfYVi;|*^pYf^U^8kFvJHMH>>&o_+j3uEbtg|&Od;^TCi zoQ}ueq{%twvu>{LUC&P+$d)NkEL)xOuQr<=TXqE*$Xn>mO0G2*D;#3Zjl#QROd({m zQ5Hc9A24)o<>0kXN6Cbk?C8oJSIi&nK)1nY5oi;hC$DGxpos+c4;95<;x5D#5Y-lJ zpNfR9dvfrX&A9(j(#QOCwFBW%dRYNNfwokk{i+Z&WdW zifCVCYS%o6Dkj)yCW<=a+nsN3l~r=33Y?|eaRhR-D^=fK9l5gN!c66H3Igj0Gi{O) zYKHZW9JvDv8*9DBL&{;wuC%?MLZ#R%gf2ogfi#ZW)C6I+hC+EB0JPGXZqV}9-+wVN zMgm44xFVPOaS~g#)Z&`p zL%KM|{+0u5joX>g`aIiM;Kc2~NKZFi1`N_&_IO!w*Dk|`f^qpVvAfr zfzC3rNx6Q&kq56t%t+`$H?@O;x$ba(xOVxEJ6o9Zp#00tjB&C}=p$L-55NBtWhrH? zrpUFy*UvH7m0G&Obl}#nnQaS65H-lN`Llk<`c}o;Zyhw%n#T20H-aG5uzPE(>Qhzq znI{r=fg%p6yN&8wYw$0|)KCVnPHDqMkKezM%rE{7Zgx6Z2nuSEC$pR^hR)hT4dC!~bWK=4DGk~eH{quk? z-@loKy?=J?E3=9|UeU~ZbDjT@&}ZrOeSNbRv9O5PHnIVsp(j0Zy-3(y}s@6$I*d5 zjoH7EWPkp7>+EKE+n^_Z&&TfD7cTIpl(b9TEN_!Ro(a|Z*fROLmCBVj%iDadw5q=D zcb^>GjIe1Cy_CNHtyg-*dx1)AYkqW}#8;8Rr!OZpY#Qej_G|th5XC1u|J#EXo!zXG z?C_Oi{|qmF;gTVaQh-(cKQh`{j{JwT{~yT+sFI9vPSGsd2HTj#w-MotM!7C{BrD&T^=_wzTG?ewY09MKim0V@H;YrU=zBkCvqVwn;UE9x-9K6H z%lIus6PWOU(0raFY=!|mc=Rw;IzB+r&EF`Eu2iN1j^16oFvD7%K9av% zePgVuAOmDyMzwFQ7P4!uepItO>&Kv1F7Jp+`MNFtdC=B%Am-AGyTtyDY_lT`XwK+< zp}J8lL)lkGPuq|@+gRG>*1J(a8Nf^`b2C&VBmIh#^>-!%`O@9XE$ZFwKI1mh-R{9( zS!(zfM*bfo=72j+Kla^UEB~_(zIwGI{C6QF-a_>>&SIA8dBE!l=`q8Dke4G;|#|8XLkGuamLqd&ib)8e)^7 zxCZg&aWLMp%X*1WU_3?(G0622^iv3&-xy}j4DT7d&I6w~qqxJOr5ECqj9s+tM_40A z6S|U6pho?c_)$ixy|sY!5a~7qRdQhHa@&mm>UfKqYE~&9d}N*euC~uRdzzG?ID9kn zS~Q$nRwx`iuclGywz9fGye+AY?DD`RV&~VFdn)n=iMGMPzAcVb*sp~CU+h}`X0ty) zhS@jAa4U7~%dV8a+>tlnFR~Dui)De^7X?@zb7WM4DevCKtNkw6g;Lywd=EzdNWy7e zk%FY~oVapG))Y20+5Q&}xu#ypmC?oZl_8xGjHRHGuWj7Jv?Iq894z&NB`vM+pzETe zL&to%!?75cMn=TcluHg!E80}vv?uFGbYt@=&Q{vEnQ=alNSd|nf0N1CWGInYVi3Fo<3)-SQfWET}*a^aEv2m3C6 zxQ$MB^gwD*`)y|~Zgbz6`}F#Z4~`?JU4_@UI{gegKxCF@48OJSQET9)6gPcEw?5!M zfrz`4-i)s^L~xfz!uCxzs-{x9*T>sTN66=cc53N zi)6;tQ6o8_3Pm=H8O`LO&I?Xv3wRhMG44U;_=XkFEW3F=N9eS=5q|3gj=zD8L`|!a z^LMnMH(Ui7Pkto!^Rh0ER*_8cG&}R5hpZJ^UVz5BneY#|`x|^y1=4LSl@=4{`r$xg z={pZxv?MEds%($XigJ8ITbD}FLle-$PWL&18wE=kKi_ltW8>39T7^c!1DI=JC@ z_w+c)g==+m-uXO+hsn-2g38A$1}<I&4|JL}Ucx|2(_LiAuBq`=wZ0(JUj4P`cA|gK#p*h8w>O`w16pPI+Jv=Z ztspP}Dr|#Azj=`F z5e1t(${G*dl}H$4f}P16S#XLSNhNmU2B)+UC%EOYHv10FH8=9X6}o+M}8Eat5y@ z69OVfraPOCMCOjWXQ|%bt4b}pj2s~&v4IZ4iwojuMM)s~balQ)WbWAP#7>M2H)Y1Q z&Q9%y|DMgFpJ&{-*Z)AqzK`&O27tdiX-=Av*k-`rq{tuCs53cbWE&xjV`D9=6|hPh zVG|P)nN0z2SE~wskFCrym{w6<=jQ6leRZ)+f8J+UR~g+cv;S?svU#Yi<(0F_tVi0w z1Wp3e*@l}?rP5M(-C1S_3%0VL*j~Ea!p+=vY_HC5Z_oLkJm@hxnp-mwaYElXeW3k$ zZ^Z$Aky@V+kzc|~cT3wldfd4voUB9EL#a9ba3MUdG?uU6H}Rj-b};T{{!$n!z=fEJ z4${;O6L-t8<1{ov1NFcma@&wc(W*#l@sbU+mgcVtTY=N3+JaXsNam<4RMkq_Df24i zKcKVLx!u)kjOe_5lIxd7Yl>GP1KI2&OOYFNSnjMPI1#33r~+|!$B2Y@03C`j(M8u^ z{)0dHOCkUttVMzJGE$OT>7La#x$I{Q2OC#p<75+;)v9G&HFTW~l@IimeGXFsF)MCA znwghX;YkQV`ek26Y9!4{V-AF8p6!@yx-tUV zfL$c3n~Ho#9KX`A;5svp2WKK5IsLmoZR+gvc12g@+IY1Cg`V!L+Bx)kceN#P%&3U! z0S+#rcpInNuMrY5k$L$vFxgr)YN^z2$QxFN*mmEKV3OIci6A0bj{VY zZ|SESRC>#qtgfJV+U-ubhA%BPFtd${^;k>b2O<3U|ACg-@q-mL93^t62Eh_c+`z-I zDP3hjIiiW0OZH;m@eNvmRV{r(-*MgdoVnw+HjS*P9XNYU55?Ln`lxMgRn`fNnMz2l z@z1YjfMcoz-HrOjF#vY@0QF^Zb>HCp22Qps+$jhJQ@CJpJXl}i2D}S3?=mMUN{u;2 zC*VCeD^IbJ7L_*pkjB5jxR95=il0=z3{8Q*+6-Kc-A=pCj`|4HGxHUNacuZ&YK6u`RxL z2iuYLdOioKCClc24j*SA}8ze87;JCX}z0m5eJN9E~C32ob+=ODou{DPK)6iHnx@KSJJut zM?RhMIXk&%2OI%w>~R=AT)rz*KQDqQE@}c>bK%#~Bb$wJTl>7M&jYm+-RUo4eEdCe zZy-fA%Jo;B)@hN}yikiPGhIwAKM8&Of_SJQ#4AE-tPdz0gEot<BnEoXMjf$pW272=j%Y#k-Bp&kcq5EqXGJKsBUrgddO`?8rH){=xwJuG5g`?NZaJd(!jqqA8t1&wIrOGzFZC4EKQUgbgvs;8X3mFGHd|SK= z$rlHM%5;AhxHm;yJMM;xYF$jyPQiJ)OJ4Q5-Uu4MXaJO=C?9qtMI@;9JEN~+mgHE0 zF5j&Rqf|eN1fbu_Sjvw2Z^iCnq zW?F|=-4Une^YhAG$S`rTMaYCbBJ z_>Bhh54!pQGfjXip!5Fin!+ve9L{p{qjgI0Z)$&3MEg6TLJ#V=K4J*& zuCJSUzNa9YAl#dwist6u6P@+O|C*L?6E!g;{W3ihtqtcDkH!DjE>q-Un9zqbW=PLR({WS zc=_5K&J6LB1vE+01ntxiTqE3Bh-?N+qe;=Hb_E~lkv73dU%iJCv`@o{6W>i z-Gj5qG#dXPu_{kXDG z##tSAI=GP1d@fLaO^u!fNZts{bo4UEjS{HG@L}3SqNP3maxscUi0cKh)C6e*C64$Y zSy5`Oeq}W3;)eEV{+Z}33?90^L zK2I=@euVYJkZ9`^sX|6qyxjdf+&~z2K2vL%Of2GfJm1p{HEM9q4Gww@TgY{BkiG(Q z5Kq`^LhCf^&{J_3vz(=r;K1z`D>0u})&G(6x)uNd=FVjNqd7_MNff)uO~vo=_~SB( zSI*mjSthPGk8<|w6SVtf`bsW*XQ}kye6W|PgCW|CbEMWM5H~CH{oFa>cB)7C+F4Nt zn6IDy4-yH}rI~iWdn}Ymix$A$;&K}ywmhg8rS164c8zg-r%f|dsKO)HD$FGnQ+hTv zrBNsgCbI`(D*1gi*i&CW3TT(#6%G!PDa70T@xfq100FT04Sh8ylo<58w4%2JE&*EOyyW0v!Cq3=2xlp25L^^RxqNCst+nR!w zy?qO=7`s0!%>HycSn$@5kvZ#cGEZOTrP-b4KS6A$Tu}H4Z=0&YO}#p3wW!Y8kGuqNhki|Ax%rKbE+>^2T`XwT=*vHAGe|60)u5uAvTbp#G)%T z$`guQ&3n5UV}xTu1vBi;drA1i7iT47r+m9;bxAgk%*b`C*BwSUkBx>-(m@)H%YA|T z3`l3s@bv&e`0+&MY{N38Wo^A9v0>)vtmsNZ0w_3(>t;7DGEMvev~UFE-hDilOf@M1wYWeMxkOUPLdywcH~ zw+l}^)6&~zdpn{6$L4}W4%LU%&FSrN=L!ElhM8u_YI((tB$t*l1=7hH+$@Hves46+ zD2`@do zXzys6xp^7V=8HD|Su{E6a>+9#8L&g@kB38UwN3I(EB~a@&iR8wGkA*ENuQ_m*e#Rr zD94<)30jlh{kG%W4uso-R9+#q2bhvw0?cL$5iu#H{j`BOh4RLx1!&IL;Owqst{^Dh zTQ)Fv$=ftYp!-^zP{Xst3PCNG?L})P?U1XW(7JP8Q%Lls(h2V7o6a17b;)BoRK}Sxjpf+zjAD4v zf$jK>V51Etc+QV!?=f%Br%0GJFJ)N93QO}FWI7<|G|DoYw*2Dm79~TnG%k!ncZ6{) z=&GzF?Ve#Q+!J@2!?95r{^}Z|-N?OrYwz?@6F(x*Pt?Tc0+Y$@UtC52c|hi{tUWUp7#X3)6T2bA2MXhZS1wS$W1jcfVQ zX3v&9BmLGcSAzk{F)dT;VZ)OSan%!G3M0| zgocq~O{=RNJZ*Vy;H?$#8Ac|%6DvSB$=UC&``~Ad39UUjx)wdZJSA42tO0p*I!W$s zINr5m=;bAmAJMRw*K9`Cwp6NX-0+Bz2z2iQT3Br`buS4n$r&NNO0;gy8eO@Q@F0K9 z`!cUqkau;GT=P{Tf58P7pE0$FarGXk;Ml?tEKTlM5bZg&v0#1aq?NVk6%K5a_)oOR zv$wym^UiINSxWHt-HmwMsBuojwJ2)QNCV-@XVM|yW?F>Y??hYw z>}OgoA7;p$OxQ-IO0T_H2p6seWLfT<%KmTEbjtfyrjKq7;SM(A9S_CU z{5ds~OJ6$hO#(FvP8cUN! zH4iOzsx||#WbW4;ielgs9M2GLwvfm7bv_d9dNTZ!%OEeVM4~QoPh3cg^4TjiOua3K zDGi?jhB5sIR2{yfdM4H}?LqqL{P#Q)pSim@=BOyl@#$OvyGQMo3sMhzHvQ_x`kmuN zdewA7fL7NvvPv3<9t!@`taKT|gms%vv~JO7NSoBQxy_=37C@ou+-hh7WSYI8?ex4l z@{BJo3e{2M*iY*UJaT$tL^3vJA(Am^ce&I6157KYO~ozKo;Ni~20R%;Cbb5}J@e?Z zRGfp4k=du+n|MWTMExNxLQ3~9j$Ja9O8;ex!i1E|A?x6KvZDpPB9ee--|wUUjXCT` zPkMe&SLdor8%$Hg-h5WPQs(`E9)BwllC{2ix0mNqSk(2isr$hSKvTxIuii{?c39{+ zIl_c5!slXtXbeh+8Vxpw*+U&-R!S6KdApBRRqCdx#BFyZg7#ZkKk-CZHhKMiJ#q({ zOSJ3S(?q6oFrTT<#RJ&1;t2gJ?707v=RZQZ~sQR8&W$I1TtX!p@ zC+~^SFd^q!uvQ@4fH2kX6=VR9^6jN%WfW&@ccaL~^0|!3mN$B4YuQFKOiN);9c!?j z*At@<;vSc{tP>L*`sxd^pSle1n})g@L@`FiMij-STzD1k+Ae_JT@v?ALGOmK#y{^m7JyxXgT3 zq$gC($th8eml0a0nu_HcIg~|mY0xeS(+48NoK+V<>E|ca zE0l5Htt9D;Nd_A{!O@lt;^gj)_!k5RKi?UgjV$Z+Szfxs;Encup<#_TQsHg=t0clI z<2PccR4-~|3mrzd-Aa-6FRe}=GPegQmLyetTG#be=@mXDK+L?+8pyJ~e`X`ejXV+FVxc1SbeU;HxlrsA)HBq(B4{I0nfF7)2aiDQy#C%L1y;kj!Nw%}9d*!9>=aa0EW!f#7 zoW}V^s-no%WH5Qujxcb2z6Iz(M(JtO{`Eyx?5Vi+Ec|WW$zV(7up6B*WX2v%?qV_U z!R3$1mz2lUot4$W%(I@@$>o;774BA_-~sZ1D~2FQ^N-Jiu9~*YC+eWKTTT)+nXF64 z>}hSxpGEg|9FMSHDSgz=Fd*;TVEJk-k2d@~6x7i&Tw2D6QUont53wCsX z1*uG`2Uc2?FVphfC5N0>9uBN;)qvwYhxxbG^@I0^RgmA_YVo=@;KKj-3n}y?gRK5$ zNVv$#bnY`T=gND}D*~2B%_<%AYol_@L$KP$80hgFghG;z>)Gv&IcAZ$ZG>QyMh83^ zVR$#2tIq>uWb7zl`a04)1KHCMSiLYPrgW<8?15JbM#p&tN6L;T5D%gSWhwRTrQIgm zBkv)_4%h0QF18ieem2g(zUrQElVq6SOgYTa>V#U6;^Vyv4|az{vN;4^ne>@oORskl zw$`T-vlGvE%u6Szf-|FpTZ7UsZj1)RMk5I7en*>KF9epv5K$YqE1WDxP&MsZn(ux_o|31?AI$xk`` z{JU#kFSZOmcA`UgPxNL*r2}1rX=Ql~TewrIu4=V-X~)^===|yFVf)4grXOD1>y}H< zZ(L1#Eq!p+&^&c+J$|%b^~Tr~%DD)oSMrqJXg;neR0Zjntj`*Rl{&)Ll};M#5NQnLC7-;Gsa7MCs1vM?DgAes4 z>EOr7!C*1z=GQ=q9i0)~y*||;ojXx%i)={+NlpR6YhC?U8k|hoc9V;JKT6;#M{S~ z6FY`UxiK3o*TW4byzhUUe74O%gXuH7^bARE$UdBh=Ku6yA*EdYth@fD?_y1Za!Kv# z$!zOGmY~No*1`1Yf?`%MSPGbG@pp0Jk2vxZ@c2ZuB9tAEwtp@GvsW5u%B3!s;<_hS zvB;D#?;$P3V2r9}O{Aa}ld$iud+vCrpy%~0Z_qhwYEgto<%{;?lhOK^Ur})Tx3(lW z$+nro^;A>-*av3WpND*TECjep8Sn|Hd$6x|dTLkb+5m#@riv+{sS+lv=SYmxo-NUX zx}|MDJHsrEt_B~Ol0Nwh#g`WS&<$tiPEIK9+Y)X4~^1mjQ z+rc-Ba)|Vuc5Ckg|M<>jBu9u(GGKEpSV%wm#xWFc4ZnvCV;-|R4Zr^%pFh;6$Nb~T z_^~$}P=sr9RMOw^^Jka%_YNLj+_`=glq{8T^#fV=^@{=!0;UC)Qe`Z*`^}4;fe| zckP_Xrwkyj%(@h@3~n=2cR?v**vtR8TEE8CiLuYe_xHY&sN5 z^|SBmvEJ45rNSNWiTD&7ARIA3D)Rj{0DZp=Xk%T*e%0e&RtGzqf@qrY?zpiGNBN@L zv800Nv+5Kvzi6sAZ&I2K8_oHp~->Fd2O%Vcv$ImtX+Q1Lr&}aV3;f z9`Buz5CQN`LuEYSa~kD~Gz8Gwsc%!r20$A9Z_c;Si{=#ro0CLft07uOkdsDMFla!X z@8FEF2khM$G1DUGz$KRs`0`q`&VPdyVGwzskZ*Etp zL)-NwaEU}1*=N+oQ?6yE*k*osVd8X44KN^g7FTbgQFeT9u61k>=&D#pX+9xsG7{3W~xB+G-DYcmVKGXDL@PT+@X zo!Opk)82V!)nI8W?pEjQ^+P~mHUk5r_pPjy}s1hD+y!92;-(iQ0Xc1*mD$D@ZuKJrW zy4}cSx}F#H99Fi2_V{0zZjgOZX+C^eb?4_#{jqX9xpNzvA#beOPmY*f=;8}kk_bdm zEn9sIy`r@imAVi^ykI&_)YfuEr7EbIn!%(_!R6E{)ZxiiYXJy~!+8hPv3BohC_ED4 zhERfMxut<4pO22|!$Ez1O?r}9uny8vhD$KquPwsgqnb|dZNGjH%ZG}VavKZsD|)9A z_;5mdz`Ir{d{YuO-)7^;U!G3yB5LsV!her$^qz;{a#k`({RVB`FY6BAbZ-xPzgsh| zy=VvjeV=Q@`$xe8wP*avZTjzt?k|+gA6j=t;y|d?MUCj`T61ksronfxa{Yj7sz_~e zY2z_JKDGN@1CF`#se&y^5_=D}MPNV|Kpidn+}0`H%#~?rqr`!woi0u|TzqZvP=Yno zL!VKXh+9lj=%skAh25Tc>o90qn3=!q!#BG-A5*Gv-va0D0~QN2J@)`KMbpp4n{_;+ z^S&1G>T2*ElF+jp46ycd1g;Ih#l%F@Ow0=(2+zhK8)qb4Y$bT%2^<@>rv1^;ez=52d4UYWpB-C}_EL#`cZTs98IPF;6K zRNEa8LOSxIy#%I%qv|ha>enp-ANmD*|LRW9n8_E6^TXt~TLcitXNY^{=FF)4Yte(>D_DvT}td8gjxEI@!^T$^z`uz24 z%Vy}~eojdpIMp~TU-z@)T%n*s4JXUzfuKgU_Mn^KjGJpznF>XLBbj#jTxCO3V_c|` z(i3}g&tE5Yw zAj5`b6L@wE{^-;MrZx#T=jY8_)!p|1ce0MP@_HgdW&{vm&rbc;Bt@NQq8pCNRtJH_ zViR%2wbYgrRN>mv8lAr}s1J7o(_9T~%?;$>E%561yX=JY0;Q}NbJA70_eknJ6|*JewgSAj zF%U=NvmQ>(G7)aKfn51_ce2%0y@KMF&Z6U7?i?LUK8yLc3!4Az1u)nByEuM*rzRd8 z$d6%K6;>9mU9Ve0q2{ZlNu9s5^`Fqg7mE%OgfY~NG zD+h`J$wA(0S~+ZAjFmGFb&hgEOx>H+_?4PB@yrjTJU{E+)xS~*%<=st^(3#QQR1wQBCUb(%*bE6$yKTOEm9`CqJ+ITYobZ%1|gkMzkUcU+CR@{p$66{?0 zHOsPCbcZ61yR#jYh=MBUdI<6+w|QrYcO9K{(0T^**JMZc9mzAPx_CKI)?NCgx*C<} z_NbX?B46roSwucIT4h)H$&@s$;CDWwwC;W-Q8lF1_ljBe9Pi_YP`PQ-HZ>AH_BOu~ z$*)dr+O*eCD7znJ>;FvvdbDfk5#ktsqqyiSc0aDZcG52JEV^QRNzX=UUu{9AOb9h^ zIej=nkTV#BV4W#!B;I&H^(?MeZy6~%E*Mu^FrK6$XaSxnw9Gj_5{&RHHBaQS$ES}J z61qVOnBeSZPk2(`itI`5+Iw(*K|i{oc66Y7uLhilwwU14*ON-am4Q%sVGY=dyUu+) zMc>Tg*omw%j*c%^10j)|^%C%^v71oU4sfyVLp8uwdoI<3N?noA8!rX~&+?lcS+e74 zT)t3|l?-S3tfRhxKr_H=9~1L-6oIIT)T+Y9Qt(c`~;{}Ee|VAI=4>g za>Ma<5c$oc+XXh=zm3bELRAnIgc`wD2m3m^?+#@|A*p8^ZGM>)l7x&m0sD{m@ zzi8h$-!MC+TILnlFz!%x{?E|@Upk?OT{9VP4(+gtDr`yR6J>0-J5ow1nFWX894j~XZIdb)nFs`b4rX*Z89XC~P zrJtEs>T|hQmkS0@=VD!80PDfYO(m<>l`HdSApIwlHAMHAGHu_cYu~cIqHYRpoM{+6 zM0Bsq(%(Zqkq{$Yoh+!q4YfUe#AAj>l1Ox5B;9o~f;BXIr7ly-sR1RJ6GSH9F`Zx| zp=OeFy1*s(h=xbf=bA{{T}I)pQjzwIC_ z#Je^y|2USp0M1|TzsT$X-Ab8GKElVk%=0u_aqMKbP-^x9F7Sk}oN=Z-3$f!%ky&7EOMP9!#_CccpAf2j7K{+j;zA;}kQG>q3USNd`X3EiuAzRDDlszH& zS;5M_j0s$pC~8m7uFB1hc(2;FQ8zZqBlGRwexNyS?%PJkh2?hK52mb^PW?Vgcpu;7>s43|gyYK3|GG zmqU(ll`dNO#tHRr&xKr6@x0W2?u$H(_YKq!Aacg86v%hZbQK?^QW}(d>;{K0Mvwr; zg0X<>sWN%n;glGO1H+hKU%VfQ_;NY+hpc~SwCN{xT{y({zVQF*WqxbT*ree6v z@QAPTVi0Z5xsf)bQ$Ft_O!scBWY+ zs=TuD&Jt()JYd_s52}N|ey1P6n@|J9^fJ-k-bz$NJxTFCX#Wf9Lm-mC!HCr5bk+az))#!$s=FHqr>Djb zePCsLJ^EUk4sI6n1km-qv2fciZ^!yovaSv(>;sDU>K)nHY~B+`uK&m0o5w@B{*B|MMH@OPDxsCKhO#qGk`_x@ zD_hyKP1eC+(n7K&A$t*$?E5k^B!n2U4`%FR8)F}gnfcyxKIfb#Tg%hu_s{S3oL7I$ zG51{eb-nlf0t&HGttCf4Lj~N6<13BMt|XUEIz)P_LuaVBy$gap*Vu>*U&Y0UWSiz0NN((=Zn;cch$R@?qU0t-<4lWT3}O%N;q5 z?1}n4-hLek$cX<^MH7%aLMMpa|4nghLlf)WIkzi+vuCs+myR%s4q{tfVtSUi^-^Av zL~1cH*%p_#9K-#U!tU-{DI?n=rI?p~O<6YULnc;>vNj-I<_VL@JQ1Q^7bbI?PiH3MnNAbJdmgN8LJ&XyO9T18DA2qaTg^J3-$Y_R z&BWJ;QG%(L50lCzi|UKTol8RkX(VR|#kL{w6IH z@&RE;f%LS(mG@fNjcZbBiJ)V6kyM2jS$GYb>_ndHw|ml-KDeS%Fc z5ZNO*R)r%5kmWZy)HlapSlW{_ZQqtFq}XE7FC98xJ=S3mj5za5Cmu=GDYtwFT1p-5 z?%+Hh+a6SdQ1EALnXH|UAfedxtUB5WQ^i%PvvmSks;{xbFTjLuwXJve>1w zSu(mD`nTs}aR!Xe-Eg7UB^Q_FU_qm3P|>kgaxWq9ZDQWMDYczKQ4cC5P3lUyi|{WEd!2hQSkA5H@?Q6q!U?Qur)u}%>SBouu}h?S%aeeSsWfB6S1*1 zgSBBv)4m4FhCHl%H=oxm+YNmQpPkpiE@|-qJpKYGAZ|%d#9OArMYW^9P7gQ6C&S4k zVp3Mif?ZM}MH?|4k~3x>OVZ^5kvdRAJPdByKoPPfT2FLGy|^|elIeHW8*$_V=N z*wjLQV3Gi0HbF2!I4~UnORPMvH`B7B|NmLv;N$DtMpc9l%~yDzxa-ti&aVV!2e~?p zJW<@1KYS;y*yu=Ae{2)8O!8?!1r?1=@W(qv*89OwiZ<3wWua0rMG!s7)~ps^y;oW? zf=lL-S#N-lt}K)%>uK1_KZ=1SREZQZO_;`0 zsrsogwO>&3LpXHFjCuZ0O!pu>TbVuOoAYodMOx zj=U%$Rm$Ws`6#*EfIO<5e1x4{*+j-ujDVV(b`g<6`w*R)l*JNiK-5K)dU!B+>`Fej zN|d?z>~yUlxIHG>f7~7GPCV}rUe%q^wEbIdE4p=*J5M0+DRA{>KO3C1blW5|;BAME z0gLrHHeY900Z`U}#{+`T|XDuyuJo94o$58Xq zNzawkH>7CKTl+s>fnygc#lD`lo3?Skyy#LDEd@!GCzHv^B@;zsYKy60cixafc&=qz zB7XTru&e!7a1tmfqAGP&Zv*omK+NHfQ;xrAX0Ab=?pq+%?YlL~G70w>jir*Ys_LX_ zRgV`nQAZLxi*8?8eJ-wIuCA| zN0K{{3Btr|)4GTpJ(z_3kPRA#*^m zCfzjRA_^vpM`3k|UG}I1eAKHF>(0EKXk@PdOum~pz2wC_?o*$xAol^BOU^W9It&?A zPyF_-5YG|jryp7n#V6j(^+Kt_j^}3^T_0K*XEV-WBLhH=WAe#ew?8fVihe?>a(bNH zX8_8M7i2fk7&zG}P8fv7Tqf0)kC4YpJ{5%V`C~XK9)9+gVDPy3ftg{Xy|^{lxo={I zaRyL`bF!MPMYxh&ti(aG+j8sYJUFql5oQn|nYIKI&&_f8c;&OT6i5EYxFa1 z7*+{P9RgFhLdIHCubHUyrM4NAINM6b1iRS7m+S5?Mh@701; z(E0Hz*Ozjg=BZqe1hH_IF!_0B^#O|`chlhRsoI4GP%ZM|AG(($aOEE=zuui z3EYU;mZle3Q^MGh9CNy>rudC5+qazlN(HEL*YBn_%s1B-N%dnPL0DInDwBO4tZMflXc&<`SUAe5IsvoW%Y80ayay|^pyt9(X7iiqq@8UX$B!uw?8e_Z( z8|=FJU2qfK#Z8@T zHU-B*79-KqQ?84>OfYf0>vT0YpmAJPqr`*q(u+plYk2f*;k;}@J_UQ!H9Z*g{AI8! z&8B!i^rg8A)#Ueb-B|zj{@d_BO4DUQ^(}()6E)i(BAZG~Peem0xQ`abwb=3Tt zXOt2EMU&hdC2y@~TXEo?DCbgxw_13x#f;cHI1x@zCfQG0r6l79&{do;w=SO8Mn#>;E!HuEr zxZ4d^O_*-=KHi&eeTPsnKeoYTOte#a-aGIabqz83ad#6su=1OdP~b~BF`(=QU#Tf# zx{?R}iBzqD(gu(OdINxx1IKHk*;^1(m2B$X-b}#FfUxB%*ju~qB1ati=f-%&rYT+E z4sEP*r-Xzk0gD8^aIWuc7pDg-2#%^48K_z+?Rlj^bgpHUM9OKq<9NbyJ>hLXO%(IM zC^NB1(?*=6_5$2sG#>G1nx37FjoJHJrz>R=;RTv;1dTvN=(pnTsN9_kbZ{N@Trw%% z3aXNZjJH-k@EzhZy>S%O_9|A&eWp&V$()5|l>_9)AF^2ZW!VkK$9Su4)#{bBG{?c* zfbXpNGhYp519S&ei88-}QYv#e$-|1t^YoyFG7W)SS;ll`V%mS%DH0uTF+(gysw!yr z<*BNs02=G2zE31CvSAQY{@}Oxs7+l>O~HAJii%Y-AZW=#pYO=RH9`2xnz6KEfe;t{ zHUpSDx_)QHJ)^@0b|8r$v2<+}0g5+l!Mhn61Bo$HIT%y<=3d0NBCmf}33hjKcFdk$Hk}jrlSO-T&NO z=y~Xmcc3=szE3{QU=Pe+TE0`P>%KhC3~J`kp(vG=@G9loy^!9TU9zd@cZ21eG$Wx( zQq?t7qQh}Wj_l0QXh0fsf=@M~S=99D#mja%Fy(DhvjbB+x8Sd6L8; zF|X6cvK^$!)*-_^BfHS^C>baa%}cPW4dqWRp;Acd;mkfW()Kb~t1#zp>%!0OrsGzP zQG#HtZr5LRm-jX`tMx> z)fxmchH&aB&HPW+EpoWW^A88D-hyX1tuv6hX6a|O}=|Px7+RhpTKqnpI$Rr zMPYZ2(*b2Jm)<*79MD#JTO_#}Tz{SZm5?W3<_gcvEsdq4ZpKP(w3%CgaTj`hJ+fL4 zZ2rr6Dcvo5;MfUS7PfShMgzlPT9kAS<6@05|CQQJTCqaolk@y5&-^Q3qiqi;CIzxu(YYL# zR^P<>3o?Xu__K<%)b|m+{{o0SA&#y0{Sre;17XYkTHfO;%mYuC(;0>p&s@aE?33KY zt=-5k0Et8B0(vU9jLbEFDSRO*5do;L0qWQ*?BF7<8dd5TCWkztFzCz(lYti+JH|9t z=8*A8hTCHc&yPBGmDKdALK_Fv$87uan*w0nq!A6%*4zA%>man~YN@@vUas!;YpXaI z0M#9>tsc1Y8FJy*TX$m}l7P{0%D9WahnmfF%&dUmu}!&^x(LLYJhVt{5-TX!A+$8m zV>Z72aD$S6;?)we((D2rraTCK|GBf>eN-y)Yow)s&(^MRl>(XNxoc|F6kmBE1jzSO z_rY%G^rWx#1UDJr7Msu+bRBi%E+Lwhm*@{yRd8yZ*O-s((PN*ngA@XUZs zieuoQ;Al0xWr}by4or5oQC#J?(4_3^;H}bP%~w+H@~s0sN%bCjZ`_D|LUiE~YsFKU z`TRk<)_H7QX}u9u3+Mwu;R-ej&sCD))iKX<7;|_oiQ{ze{js3bL2(xMC7qG(e5AcH z50Vm1&b(^fbH|JrQ`h zO_kvPwDYsIwd`OsL^L6~&CS%Hzsw)2(n&26tM_ZIpOBo3&Ve&H3 zonY7EDJ_1M$>aGS)`QTQSJ2cm1uV@Cr3-go??~Byn~hWvzDr8veyXp%l-ISYQ<-L; z9#=k;ed#l@A9t*%o{&!rbr>+Zk~e7YP>(Z7C!67OJ;t(CIF4t{bhB~GD1@I~9=f2* zIa+Ib35;ZGs~|4LrPhjLncJ#TjQiZR`--@|dD8@xE9dSUA+V1YF;+znwiwHpfn$A1 zwbi-4wldIncQFN|ir$M+{HS1xx_e3$2pi_1P`(i9l!}8>uYh5NUuQ;IrG3Om$^wI~ zV~s;eeGV?M>gI*Zjm{Vy#92@X1sd3PV&F9Zw zeKs%f>5ps3;kErX3SiUev|zRWyef58m2>%F(guw1 z`U#+eb)JGPeovBkP5`D-rwr6OVdZ=7kaqD2T*S{Pa5V(XgZk7)x3($i1Ec9mv?M-g z8d_pCRC02-E}YNS!jZs=$F5yV36{SUBfxBs@)k2nwqvht!9nA3c2RLk4bkj%WA>V# zCYD16wY8#CRlc&9MEIoRLRt60p-aM^qBeHiT>74p zaoP(nVm(e0ENFtn9LGlT1UoT>kn{nKX}u@V8Nka`vkqY`0( zc}OIzgS1P=$iNt% zB5hOqUV25We_CyEWCl2<&K)ERJryGuAi62Kot2mki5j{)bu}j&XCKRj;txE+I6-bM?SVfW|Y*w+6LLpE+au_!N?Q3?RbUv>??cIN;XeIRas-l%)IZq7b zX7imOpZB|W4<2TFs9IahWG=kZ@z^7M-99VUG0tN>c4i_`v-A-tV56Ndqd2-~- zr#6Z|iwNj|40N6Y?0ljPdN$I_jH$@&Vw*C-Nb}mnXX8Uxq&uGXkl-EejZkg$JxvcqTqewDW=%!}4Ei(g9;`M>i$9{d#$GcQ^TaMjV|`w{H^yK| zaIEhb%~c5aE9;z-UNU_(2S$XzSn&bu;rAwK=`&mR+2KZW_Ei-2kBK2C1*A-@aosoA z{`t!)CA$#|tU}MiZ|`apq4Wz+6oUSBgx@V#vKLSD zeHBS{U=NYoYe@ZXm}Rg7(L@_>J+%|R2h7quz$7fj=Qq%;#F`v&#~y@>C<`a3v36;XwhxwA^9ds? zrYnrniHnPC%o;B$DWce6vDV|)iB{sbWKg{wyi;zr4(HGqLs>Lu=vjIcLI)F=c=L1O zVkX2unoZ_ab-8*rxN^=;%^?8P5=;_Da$S)ql3L?-6kY1chmrD)QVB?a`O}dU*BmJ) zW3MvMayjS|AfzeqQvyd;LgQaTEfob6U$L_2)z$N9|9#>oKXmEVt= zxNd8U{WWstL~@MMz_3Ku=ljQPboFYC+sZ1d9tGRt<~xML^OKU^D2B{Nl3Po#4aHMg zSJU|CP3bIA%N@!K%8kaUJXwVa}P9nxVeu`37zG!NI zx}e+U^JP$4n^i3%eac&NiLd4P)Y5jw5iwT*ch(594X5ie!^_vJa;|_g!?tU@t5D=U zg=V*y!}`TMPN0FdB>CK)oQjm#@#|$$A%Gi9%N`t>hvF8!fG?o?X-0z>KI}0ViSsimN-K~8R zPp@Y<#k`X%rm|@E(MK@&6bDohURPBS1Q{bv0L( z{H+g-HB|f!V1O7vW=V8ztkxO{zJj)XxNt)vo$R=Elm88tA3nN~|Mb_cwIDQC-^@9mH&S`p_g8nY@&K>1x5kWq7`(X}J`Id?w2Fn7w#12U z^H}%!4yV)C7*_uDZ?p6Cd!&vQtm@*rsRjV*F|@KA?qq9$br@sa1=k*y_7@M{WQ$>Fq%H zFK~0?-jy%;frY)!!>vF@q&Vg|Zq-+%iQ8!9brn)b%3Qh_IgNE)KFJ871Foc@{!y+C ztLmyL^i$s8{f7Z7RrFZ_*LQhxgOh$kZW-GEft$an<@w6ZzV6(Hn9oh$R@T*}n`5w8 zqg@pJX=!C>|37P+GkekuZ=S_^2%?GWz?nzuzp@CJ2Lu+w=jHxpj5Y`8%mCL8D}UR_ z4j@@l`%YEBGR()FJZ2E6Kmp?R{_`Q)`XgNmI)~O{erx_on#+6xD+Z)R&7rQY=py}! z^#!t=87=qy#XXnjH)&XumM1f1i(6F;+i-=>-Q7JiDj^}k{1nmY>%{FfdK6#){ITm~ zy{sju2^dV6KdrmL81jZ70GU#DI{YhUW~{{Q2IRDY7GHM*W@cVzz`IqARSvI9!;s5^ zH#JpNRdYZ~je&9QK!z^PeWDN-*Ij6DmO~R88#q=sReOL+mBzs)RS<)+FX^9I0RHnJ z>I^8J90pqqGe-hB>WjR|Vh1-c#9mj>;us~H6IXNQv@^+SbOVT|L@eJ@#o2{B+dp8Iw_|Cs-+cB>V?;idbR?)KcoPwAV6yKKRnO( z>yTX`zdb_$%R(=?_cvR39+a{GmIcK34#PSD^B*4O8(AlJC*c7TRNF%QH_7K{h5~S~ z?&CMhe^Z+6y?F+(2tp3muP0eofbs{J05HY`&EL_Q@qN1g@se7AsRK#yS~)QM$3I&` zUpgm&gZ&=~ZA_j2M?ya`T>g)Qe!$HCM?(KcLO+7Q|B=uSAn+pq{{L7Cm8$a!My>Ie zIg(1lMa&Efkc*K>pZWMeS#envNUD$rFPd671TP?eVw#h*83Lu-S8b1RX5d=4 zoOE4>6VC(Wz4RcL^nMfl?5BWr;`5peS6Vo7&>cWwgLb;U|3jepi}NCh*3b36l;#O9 z!Kfr`pwqp3XVCc=S4;K&{S|Y=FbnhJXy0<~_~=N>7bkC@N(nH@BGd)jHyTWupUpwt zox0F$=U^pi$;0e|QxP-e)F#FHAmqhr$>3}TJbU%y;le%l^_}!fSa4xB#uo_Hg+{jB z3u9z>B{5X-{^}~hZ!O+c21t$%VA+dy>@fMxGe7f{L!KN8==eH5I;79W>;7+i6`wH& z3a1{eSpcG|`0D|OR{-s`@>bb}qg3}Pe=&@C@H4HjDLfb^Wg~5+Mi^~;7I$?b^@S@I zMkQAYFqI%Yc!D9^&+1O)3h0X;?hoje-iOyU`e+$4E@hipz09yPMVTZvn{vq#4U*a; zc5-LioWA5iO8HR1%E{A|DQf z)_m$}YI)#D?#RCNb-c(?Ohw~E8t$uS`0x!>aU#sc=+RjE*sbga8KH)S!}&aaEZ9k7 zWdN!i86~q)udz%{QET&L(=bHLC{YWK4T@~E|4>axnf54l<|b(p&X1FZ+Jd)fAs=xy zu_}bP=~3((9b#nqh3@ndGVf92!tGlJ*W4R9%;HJJKm|jWMpG!oZ)`g3$JU|t$qYJ# zyxYyfRCfa4ObeCSqhwgEfw@YpDwZq8^!yAC*F1yR>%41?KiXrv+ikW{QD~r65V?HQ zE3GoQvU}lm_*>US!;npq8B^MXxpDUDi=AIm^`=ojgT-}RpV8Bdwxas3GK zToAg@s4A$g#yQ|fUiNbkpqWRj?wKZFsGGgMc79h@Z5b9p)=i1F-E>4Uk^K=w0<4h7iV@ z(hBlPAdP))WB~5j)CqYDl)2@*9uv7iG@G;zl1OXGrq4CGFcI!%v|uc+2A;DBmnO|S zb4>{ zKZ2GAhwRrimZ_D|l2STXugy&`l~K$hO^?;pvxpSVUn)#jK%7b5tj}2L0Ee6 z6UhUU*Bzwod++BYvC%#7CW0M~)v+wRBWhCv=KWBg9$3D&n3s|bC3P{F3WguMIc^n zuBb=|v@bC{+F8q*-A@Vco*GSs$ObrNem=mjFA)5Yh?5+fVpB?2v#=^xaGogk&#%fL2C=Eb+lD$auZLgZE0Dd(HXG ztX%5^r6$@y$T^m7+xjv7_MZ;|WM}~}yv+>xMe_U>et!|Dv=c1?AKm<56;qVn_N21q ztH4}NqN%xg^5xM~jy6`=>bDJ4^rS<17+mmDn_fkN`Pin;J$ZT@rbn4Aa5Wb(OMgZW z=wPdZxpu~ggG-o(=Y?Z{e{?z2cYV0a-*fN>Uv(%0HM()wxuBjr!?es3!xEQt3YW(q6SPW-S-*s5Q)bJ2zGceSz+8105xoJPN~ib#8NHA4n|q$9#zQMkilS&geA zfI&H(BVH*k`VfejSd}QK2qoWSJa;w&l;#aKo*rqx&XpK|dRbkvCH#Y=NK7@-$mo`N zIbTK0lA{ev{NbJyjI^AU^p`S70UnU1dti z(BUy2so8+H)auB>dY?CgAzDUmjao=wJ1K2h*GZRL3KxljeuTv=H&tS91arFO#zZ6> z+gaFXzhF$6s6@Rb&JK><=*;w7hBqTqMwVsv=zYPWs(CiMq(qAe4z6ls{tmNDegg79 zvO*Tj>!-$6L49Ls}jK*oqHqWu0a8?kc-W;`9oF$MEag5&)s~B*xBVF%Un6| z{p*VKy@9l2c(yQN~o#ruYPkbDKOH(t-X_-WVJz>ew|mZhp)|a{44;VeZ@*= zHzKj0Ja6|gAR9N)ZkDo6Na3e91MI;(69DvoC;tvqW>v}Rtm$=F9}XKGAK)+m(0vSN zW&Stl{-1ZrL3RL~AvNE@vqA&?&jUXR=dHK-06?>VAFR}5zrIe9Jir<26e#?%cr&C` ziv3qakg8*q@EQhlK0-&uM{iyN?24UpA+X!@o-p0suXPf<0H2 zS+D!f?`^Q?PZ~XB)V8h(8~&6A`IpBV>}d4hwtN4-fBD~iXkehJBrmYddJF9BCT`|znVT7fi`beGzl@kGx{fhgd#JS-q(K*q zo24LDE>Cz_Gk`dlE|6=OF7@EW+OF!1{Qlt@WC1&}(@aofqe|HC|NLLRX($8Mk#e@@ z_g_gjImpt{PiUQfksH&x@&h)}8d45CG3m+^*3=N2cOQMjrQLcbovv|U8b%#{rE1y% z4&;N|Pni%ousLho1K740K-cn5Gbu~%)I7eq>8xT zUwL1*?Mj&=a-;w$Z6%L9VzQ-5mwF$euY?SCEOBx@iGd?)YVLBD)ElCl9b%HJbh@cS zo^BqNu5+&QFL%}`+9YBxGIU!-r&Q^+K?nD(O@6N0{|_Me9M{Il{wsH73FC(5>^$`Kg3pSFQK57JM9ufka)g3 zy^2uxsaIxDG7uQ++Y%`_@xK1OXt1AP7@KGb3zwu8Mof%JUHR>=+|z4i3B(&aT}k_Y z)0xcBqjivlMXPbI#KG`(Pfw-9XkKQEu~UNjPn+V66yxD%?IqD(M>~q3H;hk?*Rk>1 zq)OIVp>wOVHIw|_x@QJtq)upCUusg>bKZ29HcI3;v0pgc>Gg=XCeyNL%OC&m7WnNUC}PpNF0y& z+^t*n1oAcEV62aaz2i&U#pU6fT?S(rHajE7pZD~Saq)odZg&5Qy~$4N5tbMID!c)k ztkfXuG30;5HyUV4149Xct9pdx%y#cFRwGP)y7*zHnNn!pww0(4Vk0JjU;1Q>T^ca; zW`&%>&W7){wJW&VZheG+cclN~`Q8<53^z+RGX!fA`kur$f~_REWhEedY4p?hI!>tl za(?w~NSR=FV)Eu80jXc~u}Q8Cw0ZSVgo0NB^bg zS3CpYenViI;zxnoYZBSNMj3LQw60YWzuM7NY+~%G90`Cg#Nw{h|9sF-H&w39*X>x_1QP?}jQO zkC;yi$LD_IBV3fn<=^U$ z&5eEKszacsyAbCWEPQ!|RyyT5!KL(^14u#I;6J=Z=ksx+E5oU##9XwQwNwM}f$%>03S@{0)SVi;}O zC0fvZjFZTqi z%KBJ%%x41=1Aw9~#lPnCqIqugcbLWcTdv=i{ek;F&?z@;hpUe^hXEZ(ic-L|2Rtxa zZ_b>wv=ryK(PmQt9oBi(-TrsOpZ+u>zQbboDtjW8d7%wPZhN&1Oe)02xs&JGbhQ1# z*V8b=r#;PL-9=l~b6fg=nepkLMrgwv&1o@wGB9yk*Kys6Z2(j~xdo195`BUrpZ_Mq zumP5#Q-7L{$V&QkzCai2Hhtxb#;G~RJ$t0zge$Mx?CQDSc`!s9$SzFaM@D?c5D3|e z8>svqA3(0V_YM3)DdD;+4bw)2br+1auF5~;-Rzk`fdUWxhk$^oW#B14uXT%2N*`@| zKY*bP@@$*}=2$#Q*nFEX;#Bdzs^<1DlOl=yo>_{ zh5>!bt7e4b9D0SHNlE^$b|~QxNcy&JIfct%NvAl?!y2O5h1p#ld~If!>SGa z3x-l7p!t(@Q-Wbt$-)k|W0NTcWS*n6OAzSRt&5P;*|`i%)i!OOnX2N<*VKEq?o*q9 zga*Kf|CM+>u+G|WG;o_B(2V{mi`J{Eq8oF5Jrrj6Z=*GkwZH&%+Ub1Y>bf)o^Z^2O zt&rl0sG{}Q_!l6X7Xru(>s-BOt7Jx}d`~t?*7pLf>lc3`W8HZ8@L|tULTC$CsMxfZ zWrItMtZCyQ`Sbq#V))$L38-A+q zVvcqgS3J94zdPfMx^1=@Vam;U(kdq(<$tL&5|Tf06BVoeL5I+)`SoiMF3Hu90 z595lQXlG8&PD@(8W##;p8GnQ7HP-SA;mr0tASRTLZ$0yy?SFTqfDA#mN^yeLN`|h^T-8xY+`yJ=%0xpr>zIaK`9cG9So-E8u z4tDE2d8JfJ*oWdZWF1B*b4Z#eInLPj;r`Rx(|96v&Ex5sf!T%HY~@(XmJTL<5N`tTPm=ATk%ptly=PFB2jZ%Q-4_ zgj{b%80_~+u|;UqtINEK9rbBSj(fIMmZJ^F6yrZXZ`_idsprR*?Y$Hyqx+JKGJ)?N zEP&RM%y8Lh<&JkHuq_GhQn6GoD>Yn$wrHbvF_>tqnrcYWz_`*?oP63L`P#uTChWkT#dAHrl<+ z;=IAYfpwVVzt{W#=+1hKLCPwf)T#7ZY_wa<^(>meZ~XP1(5u=4;mGQ&N5Lje6BjTB z&@Z-^P$nP8BXGMH4Fk0H$6HFi6jK@Z4Ype%&DI#BljTivz~Rk0+#?vAe}SW+a0Ji& z{L@(&ibY(R`&3C0-!n?VglecTQp~2}F6F8O6<{X#vVMS+WcbcfZ=!xR#iVb{4tZo@ zJhB!NX9R|wV}SHyOB+yZ@LesLfmFasE0`+(2J>I?Oi{=-vHUPYB4#+IVXQlPAZB0 z%cpkXP5B7;VldB)n4%;w#9rvr^00AEApc0-y}RM&#m~#iD#{uui87siWgjoRv_<&c ziLu%-ZtZ(G|Ls%V;o-tgiKRCPbCN4#dJMj&qX40IYB9}Y^cSWp3~vIAVD=23(C=uL zpZThR0?6M^SfIwL1aOh+o%;qK7C$W}o5OBi!p4Av4z=O>Ztf4)*3ti9#bVZPG3v}U z5(AG0`)TdW1jd`;vavPVVi1qxMXE8iMO-P5dy?I4VfV85-0UCO#6bk!?GYEK5A!Kd zxWVthEHC4eMkWi@mL2bAtzkG~)nvyBx+35(+oiTg=CUlV$5-}ZF2a!{J%2HaFX#1>EHRV@*`nS}cvCN{36+ErvWX+qK5h8>*2y%8jAhGv3s4ZZ;w<9^6XCAe3Ry^x(Mx%3$f?AJ((`#RMJx`YQrBwZR%kEl z27NVEy+tbBV>E#TG3B4HgyTvasP$z|6Lohpf-sk)&ja2X`qRMZNd#QE$$C z&47y`OhHrvrUX`t5nHOyVMG2ggdB<3BE=88r|hgJ3j1)2v&b$0AFI8ajFk8SlIvvj zyZT%drl?;mBDC~Lm}zm#c!ZeOdD-P^vQ&8t)JD@;CO>!-Pw&*4YhON_ zs#E^is*x>W0y3GZJ&tvC#23cyVn8~~m(w3Ut>#egL6S-<;Iq18-9n+%=gvp)er#f| zz(_90J+jnas+=4@4@RS4)-A1*OY>WfV4UYXC^{*vUL%?$-zT_b8tTwXmk{=cu6YQ< z+(6Tb`>CM9*cs2>{8W3&L^`pToirn;Qw(!cyW|t#ecqJF3Pa3y1$@DI-P2?vc6Qj# zdDL4DT^+r+l~JEAJ3Ct|q-b9AY=G5LuyVNW-u-BO0c*utmaj}!fAF~5?0<3PWo~_# znCGA{HH>&V8M3&qq3D%hVaUo;M$n>;{=YpfDDHnFsH%&3t9QpjXZocLo{YFOCPFeD4C$>h)u$#-? z(=E#e968OtS5Lfl%q+R|;UMbW1thb0rs2Y9UhNqcWS8QjLfeclfn6i-ymmZ&@ZEoM zLOV1V7#Y2guDkjgJoNPR4r*&(o6*_RQ;04x>DRj(GJ}#h(e|E4a18-x`0ea+Y@;9r z^<762Ogd_5_ax1x=#qJ_ncH3c>%>RR=$02adM_v|E7v>L!avT==1fsX^rCPSmTXkc z6=(v5xS61?3xi`9D=TvRRohkBp-0~w9CnqO2*t~J$uWDpLE-O}SYpiwg7*I8HX#=Y814k&)wq71$ zIVEOsuH0+({|`(0avx>y>pR3!{&8W!**q^d_q?ATQb)(H(pdewc$3@u?8>Gx`U}m5 zJ3-GzprU#4aeG)l7YY#CCIf(-98q3j^K7!YJ$bnF{b#S=*t*b29vCpbEu>17f!waeQOv5Ba>3=d zT4yL!(Kbvel=3lxH2+0UQPm5xxOvQNYO(RH3r^tnC5@ir`mCk(yszvUsriJAP?=&i zHKG9{q96QW?4hsG%;mSKK0ZDYLh@&}G6=|3pB&dyLS`r%EMMOGTzT#4Uey=QEL*sx=WX6A27wE!mx&$d|u(qf%Wv&FA|p zR{G~PxsRAfPQxv>f9&17;lFoEbOO3P-o$Z%$dmf74sm3mw-hgi#3gC|32nSCCiSzO=Ve)INSf+03NZidT}<-pmUjG`X5P=iN?gl0U6 z{H^<8;13Vpg!%qZk{-AUz;743cp?AyD4CvjGwY+{%jQ-}`K%U$`!0Mqa)9rIzT6!- ztc0MJoL~8$Iu(opa(_D4-elp;$k6Kg=n5rB3kEd8y4woeTwgt@%P2 z7BX8Q4i5YAGHJRCLTy>$Muqi8l>xX!kjTt|WWkmr*NcA$n-B#6HZ_L@U3k9>8=1|I z&y4T!KKQcRgvslHvnRsI(eXfPaZY1L$E|auWUoVtpQI{S=2>pP^c>z%rugEu@jyh% z2NP4t+~RxbYylu4YuRx6T3ytRxIMd1);)QbVuZqHyh(R2E8;A|vgDgNG+Q{~o;Lhp zWYTZu#G-k1>#l1@v84FILJ5b*5W3W$4*x5Ojz_VXa!QiI!uy^_xPv`dSkAUc4 zIQh}{g@JR7O?2F>VdcX>^PJq=C&giA7G`hEuKwZKwc~B1k#BgFb7MopUXMLSc6Mqr z68U#;-23jPY5P91^KyISiL(b-H<`T$~BWY__1JPrXRDh0-2}ELxDUq(=l=;g~2IUW!ED?n15=? zxay0n5COW(tvn`_DoKO4pWZs2LhFi}#0@&?cWiAJ3N_m)^k=_8NB=EGOj4x$$aGB^ zWHG~;?rAd<*PEq2pX!I-HKqVPAeXikfOyEO8sG0K1->(zKkfJM^Y=fsq=t;^bj2)b z`z*!?{V^V8aqlram^&sSggrn1r7a3e?N<}!>=ccAs1z#ncdzxp&aAkLi~;tstjVaTNAbi_ zlQ%mT+&8mlexPHMiY~Xhl97BM!iwFVaPe6r4YtQXV zx`duQb2+ck(I7b??V>L|4}T?427`}epiQO$?GWe8EcUucg%=ITTh5=BlO-9m7=2`W~Z_{3BMj{=}yqfbCPFI;9@2RNgtNnw1h zx6*ahk!5bX)xHM4lZ@rdU!GJ{*7;QG?7xEIRcbPdz;sFWT2XHL_as+?f4%pB>zNYw zO7KiQ?ms}^4cP)o}d*VM@ylfm)+6Gl4QJ;x!}VY$t3w%gaxbTcBWJY-PPfQQcP zfvJgGfkTD9`7VR$&QDa`xK-!*)BVAk`1;dDmx`SqeSPg8g#awWQc3|`Qs;bzi4qS0 z29=E&X=bm?(>i~aa&caUZxA=#q%Xzk@4ZN*wUv6+P#5;5t`!2IvV??tRdgP%!hA`Z zmt8BGKD!r2E)L2dzBQ=SXQCTTkw4x{(H>w12g?PEzqRL{m(`WJH>&}R*3R*KFO}od z*}w}@`(hlN(~hgW)3sBhbzxY_0|W``I;rwGs=IHB^dK>oIXPuK8FnB+^>yTg*UWBB zDW(1V8mJJy=c+n6{IR|=PPwDu%bGI|6guVVdanTiF*DvNY%*~(JtlS#6i|1#xQ+C3 zBNJ2t>uTCUTJ_=_)cA3UFHvkxQgpye*0#BbYjs*2~TB2UPU?Go*qX+OkZLbEM9LAmu zzkYTz^wH);Z!r!Z?fa9%aF^-%f{!m-|1rFF(%d4X=^Pyx;r}*Nz1R7?*_}8{OB=yM z8}WlxVB}^iyYqiWC@W)jPp_K_9rOOE5I@LOhnHp`HaHU*;ZRQ8dHbcSRJC^IN{l6E zE;CJjkHqmrncE5zd7zb=&93#wejUK{314a)Bam6;T19o5xg;SJ=j}qq$HOGq1Rm1I z8PN7dK~(96tbsx5C~Q+#W2fqZ0x^@~3gNq@&0)qJA$yJU6HS1HU~XuG1$p^H9%4J7 z+U2V;AC?DraFy%yq^R5l@d7NxA+WVMcT|3L5ZQ$2mqOLe8+MKbQL&jh7kBOy!A`Mi zTqUc`TP+UD;VT(3T~nphYnD~X}+Kx9T_64wEGe> zLhyTyE)z-y>~x=jp}y+%-{y|M0txlUTf7K%IwM2U!DSbnb;eUV^pvD-ruj|*6KS8b zER+mlp;;EEbBo)YvlhrD3z@RTRJ~Bw=6h&A7QIKRiLM|=qZ*>zW%H6P}=ObUABYnm@YYO?6e0wfY-3BujNC}RRKN4{z#VxJ7 z4%0NbK`|^5XbUShpqFOwXhGNr6Htm)*u&(~Xc`Zl13kA(jBLCf+#FJfuhmN1s}$Z4}nX&t}r`AudWBAO^$ilpN5 zkQHC(Qs6TvjXB&!yFz`Z3q+)aqEs)|CFkK9P0QEvaq*Y%kfXPrjc6@Hcx6?Hgjm~6 zr;aqxs0o=cs4gL*hI6G}o@S>ziXv}`yS;MZOE%XiX3%(Wu$~ybH1XQrIYCa$ym6Fy zAMt~B-bpEpPBE*q9=}<0Oy0@sCJVW4_t2JasN>#I{)^P?cw3*n%5jr)qkzTS#fk}k zL{$aelG@9kZ$tZn&V%71a21^fK?)G)@ypiPLe4y`&+OKk5_-u3c8R8got=I0BlJo# z#%#1mJhtRTsY9<#@Y4!RTgkPbYI9k-H>Y>1>KmMY)o8gbse{~C7kS?Ivxg8I!zd8L(O$BBEIWmD3&ASv_|1A1J-wC^V1mA>8!l zr&@u(%L?ykea_GClRdoe+o@6tmMmod7bK5iRqei{#CotRK=c3+5eJ9MiCT|S3G1a< zpvzmNjMy|f7KN%~gJwnxG5p<>93~AJ0rGy06=5pxspiC5UD^73kC4#=Gjh`YYPf{y zV=oOvCla>%6)Lz@m^OBl(jyj}54~)tF&2P5ie@o_;tit}t{3eInOm5mEXwHnpPdrs zGAfN`+f!IP9?zYb7124TK<8%>Tw)1zAX2{jk@Gh+73`@UJsvwuhmCiCy#7>g zuzsj+y71tU^7}vL7Lhb&ld&Jl8XI97;W^_mGmkJ&ERR2hPx$(9zD{OSEp^+b_x_c?mRIv zVK%FA5k=0jTz&ray4|poSjrMu{q@_wVtJ$j1(WYy^r=j(1=Qq?EKj=vt^@o3VcS{%9bqI*l-bZ1WfLt62_@ zb!%-ElkuzEk=K-P9~AjJL?xUYhCT22PT<#dz2)5Ep+%)%3j+c_Q(^ocetgb^G@Ost9*Vk(%*+K_#odVJw z9?KP1{aNjWmO`R=tbvKaVN8`qS6zfMWq}^SrsH?NDvG09Ud92Ldw7;aRE#Vc*iwTk zFMnZanKde65S@g zRd1f|=!a$)no-bZuI2Ao%#CREb@`$~$pv6tTi@Wp%5Uy^Vn!Kv1*vO1iCgB3KVPsz zY-!rDwMf#6ZHXqjl8Y+Ot20mUSII6$jMav<*k|{< zP#RB>(jeFo585w+`TZ1zb&oZK;eeH0FoR%BSt><4Z;ME92hL`~DlA`v3L|pRCWOs* z4U)VuVi+=XxKv_%V4cQr=l^WQ70>KD< zd`iVl(?-!%qVOjtvl<@oRo`FV2P^Q0?7eq=J%}y{pq18K21(g8&~7)Ov!f~`Y3em$ zWTuk&ia$(d#C-Z>u-C#gWGWENK{x zyblaLnrOiku=}ZCL5McD0nIe5_=S-UbMmp1DIQ_^snp0f{D+hLLdwN-LO$rI3FZZv zfnCC$+p=CD0m~OHNoh5b4ray31|JLWy)rV~uWRA(PQ`&?SM?Zr$zPinYi7ONMc!y> z)$cKBusI#~nLYwjZt+|FN*sfcQoIsEy&|yGfh`&fF(0YQs)45>Q<8Z<2(-{34vSr} zY9nj^mbl;1haKo=I(_=R4RY6m!0Qz!)q%m4uW$Q8k`j4Bf#kii#$8y}1ymqsVD4d( z3@xHVu;bDIitTN1*Y42(@dk!bL5*;5Fq`23zKRO?An$WLV{h8jzXrWF7P4x$w|frP zJZ11Ifb=47t43>WYT0H1+*U4N?N1y}HE>bE*Pr#hd*k9KfZHXY7)OxyyIpIg#f76K zP*uzt#_XT@w%r@sC*l`&8$Jj9J$d>;?F|6Nt|Px*aHkX3N$d^ii(;}aSNYcw;IpKP zX^?fM?lD(ak7#IYG||$EW@2H1zH6=C{PK*$_O`)FN>$hT#-{Stb&1`@+{i{v(o+>-|KXb?5QkEF&j2YjwsL8O?ezew8`S?J9%eS zwD>WFLLz+VD|bG91`FsFuE8sg`>WUnr#cfPHAIlxD%XX@0NKf3};NK%;PJi~|zHlSt@XYJe?&vA7W7Yc+)m{uV`c ze(|Na#r}1F88p^`IyHZ^0(S52J@K5_@use6d8nMnefi$vdDS;+RHfW@dVFXv2bFATV1j{pwvqj)~~t zjns_{y*OfDE`bgh2)QkoJbY;Q(_{*SPk|*x0dY=fBPfxKX!qy!Yur4-bk&*nv~`yv zLa!>ksyHROqC~suE4lr0MAwLy_Tr@M9UZ^818k$s_VuWQ4+FJs4v1rAG0aw;J zmb{D-nX??2VQZ#T9`%J6W!I8%w>c-U%_YfyjHRm9^tZPx8yGRM<$q?*VpJbcjq?Bz zv$JXvX}HO6iM4F6YqBzNl>;n0Y#}KxtO(<tQQM<9xrn zIfgPfhLtiOM7bRzJsK7zp>?T@;*F`)ZHcX;VE=Z+K~8%QX9QAnCZuX!vNqhAuIkReG>jk#-4O4?SVdDs+&52U-1=6Bl7-=b=|9w1s)tbJjU%WpcT5&`MZ;rZ3t&J)I-%+4<1=7ms}8QieN2h~*UN@)_oFskZr_ zIrQIY&|eg`eM<3fRn?oEXHXqc=Gt_#ElrNac1FKLCi5+-m|LuowYK6a^|*}<2F=R_ z0vpb*uG#Fw+A_{-x!&vt%rt5#mEX3CN~nz}#Ju1JSGn?|+p=;WO>R`V_+@E&zMwFa zrT_`YVePPmd$JF*OkEFS^4$)a*(+|qeH)G_@;&Ax)&^tuc&^Rg<7T`4d2_y`5*_|M zT4qxZ5rYbydo$jXqrnqqjsIi}q@wFT^sR4WCE>?ML+o-z^Pq zQSqDMs#wjk)VVF=H|QqE2qZ@E*eU2JOO4w%Ud3~eLv6-O^<6IP^~S|c#KagLT!&SB z_spI2^)o@w^lY_rJM}tNtMC1&a<89l17#VNN~@c`yTq9Dtk9%t>d+;vZU2cgHauAV}uX%fy9^sPGQp( zLk~j~=uOPIc5qlY*Y${POlfi3G4(`im{@q0H=M=YcYBm_;b$y9bbzz3hj`s5{;+0{ zw~kT#>E$sUFlX>Xfd}wdj4hW(4*NmECfptSG}|q`9p_$0-D?5Xbp!ej8t{0y){aR+ z<42!7zI|E6qiPOaOI+VsSopj-Q|F)q$B;dS_bwUooMQQdj5ii&Vw#{>MW9 zEt32F@N@X@%=mu94Z}Y(AP4NKW??Z+!f-E`f3W7ax5Z5j4O0&uJW%rzS0H#Nys6Lb zeaZJ>^kU)02K(ENx-g>_*1Xa}SQP7358$nQIlpbUpn#;SgHwiZJz!e=IfZoC*)QJ` zRArxE+J*}9HHNNbIJgeHzvM%e@tpBSVTAeq&$G=>@7*(=_~jW~qbh6k?M~yevCC6i zpZ(q^57QXG^POJyqWMdEA?HA=cn5!L9X2 za-}<;tnPVQWwE4mK#~M|%sMTuYg&*usJj##Fp}A%VmsOwk=ovbKO;cwvSqieseiO8 zpZ3@bTGM#wo_X}Vs-Pv)128dV`rbiJ9_0Ot#i#hCH~!QcR5yY^zf+KobNywRGMAI*kLr&(#=7> zt`8Dhh40dn)zF4M)oE>xA!-G>#o!24=Us%XdlKlK~6A^&5CUn zf#_?V>o?4Mar~cdyU*ox&E36c6|vb6IW<&5LW15%>}UUg0Qk9c=hS*UjD0^VSkPR+ zdkN;~Nwf6WO#1ByAI~w4R<HVJUvH0|Lv`0r)c=+oca^S)xk3gwqZAKaRBCO7eayN;(ocl2+Lcn`4zjF|n8+tZ23@OcE(miX0z%m@pir;HyxbA_a-#CFBPGxa2ZS=eCKwUH^JhYulGci-CyBO=%^08!7EkgAhSQiJmwTI|E*~B*eY!ToNMVK(1dig^*9u7Tq0P2 z9iwtm*&bmLP2v|1QiGZ-xXXqf1e;wW9ZIst{FrzP;if=`7;kVqDy&7!iFWB;{B$|? zQBsyUi~>pSX_ke{eY{A?`QE!s#Msv%h2_Uc-68%6tW4)Co;E+DTC8m4T5tW#J!P@m z=IzPeIZwVeqfczl#2UXC@~spcOP|T;zYQ%O`VyCRLkus;KkKKAR>V~`FEIcQW*jQY z%0z;Nz8MA^RxVp^xlFwVS1q`YNtn58`rM{KTw-j>hI>0Gl{{?7eY{W62Mpuq*)Rqn{(X^y6fKS%5T zptG|n^ox#K&EEk=)p7cA^EPQ$Tl~hU3O0n2WA|Ykz=48sAzDl{#ti?(#fYBKFvG$) zl;ABN(e!Nx2LwX2TAb@<$`>==OyrY})0xs!Dyl9q`}U145+#B01DX1wD`K4s0|S0= zc9A@!S!3=aWU|4IE|iGvhxDC(s~{`@aq;kIqD-fgtO?GOtYy2J`q)StWlwEw(yE7; zui*nyD(DZ8xX@`Gh0S{k=xiS_l*Lb1he3ZLL-S3EuZu$K^Ca(1u#Ujo=&QKafy2S_ z`Qa{mk*Y2TtKp?<$+6Wkxh?xY)LCYJk94R4A~9IXhY((^GwA2STP+H>c1bgg@rwkd z10#j?f+R5RNvgxDtl>n9GM6Ip?%R#qLj|)pDf^(|)U_&b3$(~+c?Z&YBcPIEZ+r{b z;~Nu7UOqJJHId?K_xZ}yqhwsFS56Qi$DGHd5|I9uhhyJ$K8N&Fwp9g9mBkSl z;EsVME!tbwV#{bA|2ga2Q>;S;#S(Nv$AmLQGW+>1WsVD)4u0mLmluSx zsA}W`ySkcuNEOZ#WMm5x;BXu z!I@rhxvEIHqmi%dIRjZ5BRlHd#-Q|xt)mERg}7Gix+_54U#DS?=2P-MIw0G z09BJl&|X7OIz1%)a=`2e!95YZi9ULH_;;hyLFmmI-{^3(jym*KmeTqp{3J>=arUK} z`K_0%%WzD9dhi*+bm>O2DMY%r8v20jl83gTT^U*bVg8C@ZmMRxWsIs zhOe*xj#oXyMn}ILVbnXW1>k}F>qb_kVbFeKegX+M*PCGqrL+XdgE#$fyR8M}DLUJ> zc5d)hH8rx6tE#D#h-*A3;%#dE{w})}p?J>4OnKY5QGtwFYJb8UzacZuXPxOVFFR#tQQ|YvODy(wSW=Er{ zlUdvl>P15LBk|hI7rIT2k`&yOprhU>eR61PFLNT>xa4XQTch9GueNywE1JA%cB@CJ z$+|DfbK1ZU>*nU>dwp0Q%%j_dAZVbJpUn3uNM=4)W?yRmzD81YC8RdB4=~HEu-ZCk z_orqX1{Z&BD3vx6n0UL6Z2M^!9XQdm)sz%L4QsY{gVa9J|Ld8M%kXc4X{@fNr)Qg| zuBl0;;)#GzwzFv0DL(veyluYp-f*tyLm}(^^yOYOa~q}Ya;1@8VTFIR_W6U~&nc)? zeyr=Jw8x_h!;WGOb%ou(R+4lZe>a2nqXdI!K!;IBP=l|ZUlf3;v|>uvHT4y5$+N#- zvwt5o&zQ7 zs~p5MxPfLjgdmccS)n$u6rxAG?X&jNr;dcWH?NjA_SFj4wF#N#$3t-=gJ6WUXvlYk z108$;2kW4ep1ysX`QTCdli5zxoU3`n={x-(>iZr9BDoDuqYzRQm7y95zPLNT>M7WT ze3^7|6Wx-$;*<9?WN<#%A0wI!_*yS1c`v!K<(-wbk!;e0!MoAh1CsoWi`-i*%9p(; zJ(xKG2dY@p^}J88(&O`hqIBeO0Avxqw@I$nmm!Y`Vm90Y1|Dab@x;`zm^%1s@z{rU*A>h zpovATNCi@3fnpQy7T@W83n!5;0Q>C;6cyW@mlK9jDeVdtFLYRC;dS zNtAl04d;sjM#sB`^kz;2E*XZ1xouPIwcw2P7R+SQh869sSsx`E*HP+}W9xb7(uNN{ zWWRjV-)8vfR)Dm0$g_8KlCh;=la_4s^U|u;v4rl|)dsM0y|vAEc*>{Nd*OXujQ*!j z4F$zKgu(P)p+?LE+VJ5%78S+0`@V8?KnmNT_F7>MW?i!M0x&VQa8+9Bo?}A=HiQ?z z8R~DD{!B*BI!B=?%geP@l8Y_7?Qq4Gx=TC>}_u&hxz5eE#{X&OFT}hLfy*A*a3Wgs5 zHG*@^?34(u^;;E*Ge3L{2Z=l}oU=07?n;2;bf)sBb=0oaS>}azl$3ZFZ11KhT-lA* zRZytOnhImJ!-|ld>*$x1Zylg~iYn$_>wbw}-{8c^;==n+3gSvX&(|`v0omIm+2|%d zX>`2IY}qt?=UX;GS1QUnDD<}U`}czK_K9I%u~lT=ZIK858|FGoW#5k>8dOs(TO8_; zOI96@t?NZz#x+h)4xZjzI31s#=iMr3y$$K=g_Vx`YC*)LR$ZFa+{uMEQpg*~>qPsen>U#0UCSrcI5E!CA9)s=)u z>QBKaKCoe<%7U|xmC_iS3#%o4OifLjEAMO#+qem@FO*6AZkOR_oR)H-#$#~4B}{J0x{xl6idPdV4`FBE!H)`w==d0PlgyK1|bmFTh$Vhk^){H zss)>?Rkbts`VCx>Hq?NCqIf0ZNci&(6tS=&^Z;a{&&dd+Ui5S`C5E?NWlx=1drg_= z_RidW6KS0fRpiO)LLcWE5d^woM+GEus{N(mkM0TI+nl$X=oqd0iekPGh*M_8A6+<2@x z_gzsPj+mR{eh+MNL)a%dDNpJFw~mZ~3SLtC%*l#20PbN)&IPu&5!^`HQIuo{{8_AgXcj>`@m&vM0)A>)vvwK)g2MAm1UK@ z7JmOtQ?^EclR}PQof9$$0qmD(Tq;>HC(HY7R+l8U4<1y=O$tu)+D{4e!J0RPG3%%_ zNbStaYM?nWw?ot|BjQHgak1@)H0f4jTSM57;FSqL-8$i1_%{wLN1-lu#_g1RbP3Z* zJgDzoH(9%DLs;m1%%mUxU7=Dso*A(~i*j0yuB?mVL6p1U+_?^kx{+-*MYG=zOnih* zpQk)?x51m#b$nOQZn8Ym#)Rzim&tA3E@K=@P-_038Icpz=EI6tvnc`7zwJ~>9o{RT z7+)(H#Tt8X=I(CvxU=7$Q;c2_Oh{l+JWpuk=RP+&q>V5$Jq;2@sF{W|%pd?Xm!LvAG_q8nw#Kb=f%xY-WE)kl*YG!|<>yt_O&kLa zOto-6<16sJ^$BQ#w&hU&bLgsCm2h0$yndSZxspG7_9?dZPMXW4R;!}}eI@pPLX|PB zzk-omuDfZ|T-WBCf80^FSDHTkVIN_88!qMDC=btbf88(d;IQ-_`jyGIGM)Xw*p0$$ zKCJJV)IniQ=GNiVE@E+f$S)*JmQr!!-(O@NmOd?8dp-oTd)c(b**EoTntu&sc?}nt zK8rX|>X6>sVS!sY@LgwI3w#2~#lK3&!By*}TSKz=OSPHw&DS-Z+(LlyeSMRaBTJ&< zSr=WzZhS0h-!ElyNLOkX9`}Obz(DCtFPc2jnpbOa6h`LaG0BP}AmK4fO0$7>2T4?# zxC;G>G;Q>?%56|iC)r+9_QO6m-HWcm57)k93!+fjw7nL7n>XhFlYhSj*KQ^MT6SF( zU@6!fe96b^4tnMZEsFHyK%MWk2=FyKAqq>Sk!mM>T7I}N&>XSG$F?;1;C@1d1OMqF z8h)#a_g;@V{>O6G4_slb2|8Q>%cgFH48}Izd`(`ilN6n$Tt4EP*Im}CmmOpP)mPiv z(Rc6YF`JtW>+9=w{N0ZQ(@cM-8eG6Z;CU~dyxz(>Xj2MB;8x2h3s9&SF#@Pwd2cuA|ytYpW*|x^<`J^d#2pOK0A7 zu=v1leRt5C?Z9BkWXgAO*p<*CE($k8p3gaMwjqZ}Xt$N89NtewCJl^S3{#9llIw$GBf`{K)ytsnd+41VA6T@pf zC;mgYsybT_|Qh6@Xh)TT>QaL1+?CA-Chx|RejT zcu=Hc{tdfn3o4wvqxW6O>{F>8{iLI@i)dX=x~Xk#zQI(dwnNfZsB= zwZmFXP0eN@!X$dJkIiJz=l?0Z8 z5h__`-=lzm54aMQ4&d48hS%P`Z8m7f5=NCzH4$~n9jZarqo>08qoR$t3S2$7E6C&d z#|Zh3^=$#QGeKf)pKHr}aYtParywHg!i=x-X{0uGh9{StIgNPb=4Z21YE`tLc9!x! zKbn~+h*<6oHe!}kzB$R@I;Wy%_Xm~TBztDFT_`+F4?_TmuX!b(ZJ7V%l8OGM7+s+9 zi5Dj1$nNUfVlUf%Ee=0(&vz9kZHW-OG;Pkk^2SEL`O1#?_;?6W`+2dGQw>QV;qegj z1Q%3RNV-cN-T++q;ad}UeODq87AyW}#Bw9<6LgiTk|G9XXH!ZaD3um1EI)5c={EfD z!ruQ82dWk63drS{-Cy}Z|8(--(NGlr2&8jaMUeD;x=DDlk&HRyH7A>;?*u6a`Ex3l z{^arbuz>4gBLy>W>u;%N<^8q2^u!IPEn_r=S81$t$bIi(bAQ%q`f*k>77q*gE^>Kg z;6`;8l43!1-JES$YnvZPi7lkmCpa0!X;vtLEJCatI?yjJgID{yZm}L+AH5NoH-&eC z+#7fs1=fdccPTqiOodMDG8P`2Eb|^r?DRbHdj1qs6J#v(op09;v_crJc_&Mc2m4FT zMZX91EqsmE?{YbVU+J)5L6)VH@j1vu{NQW1Ap7;Ludg?+spiUVKE<34k!w=2wiu29 zfI{jW1JwAS@p5igUr>Uww4UzhtmBJVsd#4bVm+P}CY6)VQ(Y^)X9LaAmaqDH#yawI ziI%WVhw1QOT~$}btlBmY8 zAd(*!=%~yUwQAXLKp}Fb;g0u!J#qkLxIgSkIR;AVHSqNl{gx zF`UqWog-2xfFM6tMW5LjdtFE@XvVs2Gcw5r^YO~o8dtFDHL>$FRHOuT=GbAA4~;KR z9?PXMwiN#5862!QM<3i0e9x+h}$szbMOD6vog_RHLdg=?LxMviAA53>WsI%yxGOr8H!4zcT0Y)&?gw z&XFg_0NK!+sjD!Y$vmnv>7z&Wbi!%v_*d$v^wEex7Lrtc)^s=HY;SF5L$nDo7TPom zYrNOs1Lb7gD*LGVmm*$+Z;O-nu8T|4#@Ho;Cijkp+)#VILa{CXz_evEHCNx|c$wcO zoEk7+Euz|5eJkPxztn?9WorQfioJ4FpE^XEYh-)_JO%T_GFEK%C&m7ZwNYeW;vPkl z7BUjI6C6ksnWbFtkgrFR!~CK{=a-3FeiaN52Z}zAILv23xPo$Lth$V=$Mh>K*emOp zdfGH5tTAzkw#mSSoKGyt+sqS`%&c`7cN+}ck^@qD>1|T_b~a3R9yCyhhalb}uHoln ztHH43VqEa;g)my)YAF}0o!8rOPISuIUr;|a=-1mX(zrJ-Mpb7>j{U$zJ?=4e`#(ur z)f?;|m}?ZZ5<$b)>l+)RYB2u8WXnM{e|+>m1o{m7RvlPsioc`dL@;r-6upKQ&WjR@>omIw3MJ6JzRSap*$ zJTI|krUOX$DOZ$A`AfGlyAL)I=%X$VlycU2zZL`8X1eX$GYu|=&A?LSD_)-QAtgbS zfWXUoP^)kccbDRB%*^Z!7)}+<`)hJoxYCsh`{VXA54*&?_CHsqvW9uz;IsBIw9ta+3V-YDnIy##7*ExyvU#|30 z#;9{z8khXWT_3_!H;%_D-KHYL`yYmGNwUb%X;hBEAVE_5f>^5W1+ZCwQ25~Y!8({H!E&zCe9%)rITiJr1p zv$54_)YkI}JPN5i5v~faDVme9hlfYwfW8im#=>7`XtJ?~lwKW59;01oFz`G-SS^qZ z-X6H8==CbE9Z~0y=r-3pZtvjGw|s!`XreH~Y8e#nsG8zJzHu?&0ZP=^pW^aYW=A#< zWV(*x{g|q@<@yw`x}m#C+qP%QMgB`T`yWW)zkk$oq`Gi$IkOo1XMa{Q(;1X@{FP@o zeM56QiiJ1!z{A`7=kG?iaEj9hyHQpJ8*`P=@ZX%ZBcDLY-0!ckc2p;so0?`dP)hV^ zr?H+|yvyoV!NB3yd{BktMchdQnSGGsyb&e43N!U+5UFgwHuwE* zW*SuP8n!4mR6e(~^aT}FjB(fYTk$KsFg03NpIpimKorwJ(%Z(|GNrXeCYiZAx|74v zR7Nl0PCG;tIrIwJxyfuuS6e$}F2#l(9^ii0Uzs=qokc4Xgcx8lkw_GAo^alR zPE_s+2-Z%)tKkg->R*NQ#FnG=(#*R9GCzpdL>%<%Ez`#Q~w|M|6d7i*glQ3^6_|LX!bRdx*%!s-2(Z_C5vB) zHw3o#8#k>HTHJo$J{^6I`rq+kD3Nl=f8UjqVdH7JKD!V9wPA-M{|Y}xLdk^BQ=*Y4 zx|34oGZR8UIw-2oNJ-~b`=E7*OB`KS-rqO`t#ea~=KODN7|rH-Pnab)%f0nG#W+b4m~(Q+Z%pNVlLnZM%eNO*_s#fs?&ate#0GG{czAeV zNTgetK?Q@Y-_|PXI>p5K#@bjk|3Xq3hqdbn8awuKwmPiwe%Mig*Qbq-<{L^1DRDV7w*L5b;3iLMNE zITIxywHUDAE^QgpK(L>_AOD=0ksG|aHNx(9Mr$E><)c;<;PSVYyw6lVDbl<2aY_n- zYwWxM3ulNU4$ADIs^P@jmH=<3tQyULVJ#7(vc0QWlLrCk$Qy=T44Mhp%BNP!J2hvN z|LXCPL=htb_hT(jdOPtI9&e!+P6jSRFYm(7c03=<^?mOku-AI=jDe!ZNfT8|VMcbgx;6J<@XI1W{}EXNl#ip-6Hv(h2G26?P?g%kA>8f9-zPfXaNbNs1 zZ3fRc}b%l=YoPx()oj8v0c8>OivwoC)IV&;9%?=}gx*p=+f&S__*H+3O zsX*D}o004~-(ppI*$*jQzrQ;jEmJFBdmKSNB~VVpjg4{W>n~oA_@Kj~W=WPS;sD89 z-TE-P_2d^i^ek%{@@>gNcW_s!vCCY`Ih@tMqk=5A2MyIoM!^v@`#xW!>P661jH407 z!6S=iW9);H`EQv-`K-~0;E9gQkod*mfbUN%Y{Y{X87JO{wu|j8&jWExnrerm9c!C{ z^il0%UqZJmXEmRW$(jc&zFjoyN!`=MBdXSAYykZUF|XEL%&bn*6Gv=k)!QEfx0Uge zFE%L%Vf3b$I&0KlpIUN;Ptc?YmL6h+3QgprIn;>IR)s5#dmKmToiroKbjHYHw`NJ^ za+Ntm1`N<2)JduiT^wvdgSqBa=GxZRuDM+IVawxIlh_i_FpQ)3l{0EuU;;tnB7jz} zUR~ec*`LsrS-ZV@0(jD=qe)uewLyDs2|y@~69N}q1Te;}t#K+;A#0p!#rTF861~DJh%WSD?vNSk&C6-J6)sH^Z^O%-1elvp%LZ1?P>>pS&V1(Vi}Y zdnrwKHf8US;`k+&p;szdG``KmsrW>-#+`9Hp8IZplJC3NzlY8C8Ka+;pVi?olH5*{ zgPwMqq+HJ|yiE{*T5bsi?ADyyaxi+P@?t?bpOySIGG8mdUxTSVjJC>{T+`hXvabGetwMIPZ8w#03}?M3^m z9FL~or~oQvEsSOMY0)e|+s?QM`g|aYnZM!jT^Gk`ACA?<2gOM)k2Xt^MyPi`LB!1! zhS%f*7}7Z3pLmqt`| zI6OTQm}u_SYmJ1BnqdnYv)quAK{FN;X)nVr`R0cT&}e*n6LaQF4DNZ9DnlhVodKLb z85HT6)$e(~{yxu!z|H&IJz<||5G#EQ2hVwQi^OP8*E0TMp(&iBo&zc-hMX^6CWOU)Jyl-GJksi{N}GQmVME|T%#&Zb zhvt-oQ~^ZO+>nmM61;I&;(5Pk{!yO&l`7OBJQ0TcQ~)0w!zv1A&tNsYitK1u zT?DuP0|*W4y|AD~IFZc-EbLK-aP;zBzaJSJ^9KI*@*|tGSPc+1@xwU@cE1{3B^q10 z+ef)O&vvc^dify*l@5Gt#BshS@+s%-I^6Gxn}}y_*>&*to*h#<@cVL`Re|sFV~*#W z{IG?XyIQWRZ4bP+zR({gpI|sc{ z5h`<4lkmN|3Jku3Qg|tbRtAH&me)p_+>xAHcdj-pqAdn(b#>jQ_uk1lPS|c}APU6J z&uAv|=uez&T9jBG$bL0qwC6|*9N}{H);&}lS|fS3!FzbAY{5KYsX~H3#0~<)h|R#K z#1h5gh|T8od*ZpA(U-ziYXAKoL-k<8?0anIH4t9>&H_>>w}2pLa3j*bRWrLYptR%+_erV7=?} z97jv5zWaz|e=jg&?$0A#APoU=#22Hwy`&}**^c!d6nozvBk;|~i$nSg6$2z%BF`Ia9gDSSixZmq@+;oqJ%ESEjI)e1FYk=uI*|BX4_*`kDm*-ryjdBkS^NNK3 zFPXiVD~nvV7jlZ$UE4w+;nHSLwX$ejttZarnhIwbb>C#zgGokm24A$AYGoDyncrE#lBl%s{2Wk-9{I{s#Ch({V`^4KCxx*gn< zW&)cK)-qL|AIUF1jM=dd4j##0zKD)!+Vr!Ia&tYt51bs3CX_J><=;lCBzAaA`bxXg znoi#EQ??N2wC%(3Y+Z%1!>;)0Yrwx}j+{m^VQat|(-$|0r^zKb#fgUt<+VHGn4nyr z3Pz9P?_r|hiKc}O-G~BaH19UQ*#BeftD~ZPyR`*TK$H|vY7j(_?q)zK=`JY&k?xKG zQ7MU$1}UYxI|k`yq`PD2A!mSL;G5rj&Ue;1>$qOeTF)Od&$`zdxc9yHzV>zRP!AFG zPg|cmt4n|CqIrbK7EBQuQtF8m01F<4R)&>%3~61#BDLnjs-q-&GJJj=WvP02dQ3~k?ZUEuOK(XTkgbGXUB3aC-IpAbf73;DeQ5?X zXQaH6lf6GmcnQ9#l=h*tr$3QuctwS%;N#{drjwSIKJAj;$iF}5MG_RDXB|;>@#(1J z94~9k>)Fg|&z8yZB z6LfG@IpQsZ#KLZTQjN%1lniUgTI)N8R*0M;FcWGP<{1#D*0cj-6zjt@<}D%(FSwUD zGv1d7FA%}D5Mhf%`yCOLABGkMd3Mfl4PD$`h7;5k?yXBvpY^8@H>(wbJYF1v%Xe-@ z?@SR*kz8kk2&eormnZT$k%`MnJIR_$y~LdH-7jt$(b@peeoGmOrZjazvV6~?|6-ME zdctbxiIQYi$r1GP{PE0qWy}Vb!*2=)SMSuCSAItf2*I7U`IBT!3iLA2tD@KceTzO! zm>KLlq%F>R4X(G# zs1>(a6xl(jTbC6fJSpiJ!VTV>~A^s5WPdsISo?b_8~jlBkORTLvD6 zz5e-TAo?$AL$ZR4;$)TD?j*V<;XTUs|3Z}WEG_cEqUOE38q^vjBn-S?sB_H7D(`nN z*)wRm9us3SBuI?jd<^?|_xN7G8f6_ZJ$;MR!#M3_2X(L;_JO*jG3`L}_T89I^(qo` z()#y^2r1XU^{(1mbIk!k&R7pW;Wf~ImBL%aHR{VYny>;8`2S=-ct@QYAIbz=jXz&|0o|~rfj+7{5{I! zf-TG1;oNjS|!ZK@J3w=jaoSX0MpRqyEp*GOnHc4Oa}j6qI9kvdQ5KsJzvdcD1yfXSJd--6 zx>3R@PJHfTf+S^&im)?r7Qz}j+o*EY-m;pq;x^uk*IeS}|M>GvZwSO3;HZJR7--jD zW473bQr&*Ufs&jQ$ctFLPK~$97%Ky3&*yW+pPwiR+|)!YUnrU4Upyc)wa@~2Wtyqc z0&sW7+O}U&1&NNt3EF`92RbqkPn-w=1m!S~MLlnM7~AE%@MR8;aK5EP#fR3qS@;{sdqXaoV)?g5O#fJ=^WW3( zKH_cs(+%0bzcAxZsw9Plzd$*6wJ^8@=#eydcS+P44_&x`a4&Hu!OtNSc{Ha7Twjih zr-sN`PRWpgfo%tTLLoO0_$6Ut<89%gPoQS+dSk^(Ej+;OiIb0CE|RZyxrqXcgay-z zyde{?e<~gD#WdjH(~kmr9#*O&phgDZhLK`L{+9DZYP(%zXGV^to#<9U{>K+@2G+OE zeqD}aZ3Wi1DVx{+a6+`N^z zuyuqd{>;bX>fF+T)&l5-v;@F(-}yITkcc$Mo&%I^4^(!U`88mbIoDgWHAvhc7C@vxTDf^5_h5Tz%BKh#MS)XxAtBAG>mCJ3TC_CnXiC*mGmwRqe z5V87(;~yDFBEN~;mQz)|B%rXDx&0{7E^l;zOfM0tW*yS`(f49_b$w5K!HNrhiYr&s zFAya7bbR|tnu^9c?ry4!gGFfPH2oG4tY+0h29PWkwrw;sD7uEsp6{i+dX*{s?h9=u zJhHevcj(aoaT*r-r})9|jB=lyo}eaR$YrGDxyU84fCYms$B!!rUK5uMX|)0G)e06ZKlK(&r2GR|XxfBtdDf zH-FIyK4GiJCzx~db0lb6(A}O1l3bA7*GTF_-N%Ke@||H$L4)MQn%yI}(9b@RfsTA{ z!EP``<11K6g*3=C@F>0R<$61)R}feHC|Js1ccmUFR>*mCxq4jy)xXfd3pfl#!7ER* z9j;c;&Nmk;ZiBt;C~Pjm^3NO%#4Kb&NiWqztmKqwuOiXbh8Oz|m--rXrl6Lm7J-n9 zYNo|xzc%u}*Vsz|F+tLB==a_K&8z?SH`))e0$SjbXW*~w#CM-@hdrRV#=Tt<+4ZFj zxPXFDB-YOK*iy<;v})2gD;;E%?DR5W_v;mmy9hYt=p}So+C6MR_N!WF^uzavCff5S zAnHrqM4aZ%$2gY9loVm~SwA^wk@D+@fH9j+P_CmbJ+wE}-(C}t$a%*F zOM#UD$utSvOq1437ru$l<;Wx(4Uk8BCeEzTNWR-X$Sa1eA25(^5u%xB4JRzwTW*1w zSr%*J)^T;|)FmMCEQ?oEkSk%-lV%lU(zW$bz#8?*FtBImD zM=}lxAIaMqTOGC(?uqk8)h;_F=dlA(X`zj%)r0Xw)IKaj9u?sIwy69p&Nn{WX^D>K zVD+xg7Z$tS%N7Rc{BczdNs9!)D^sg$hTgk5vKDZN3zSJ|me_UWcDgn}2!Q$hJ1O@s zM0eL-)+g=S)dT_wNA4e9ke)LegRVkN@x-zN%)mfm;rxdOV|1`Xwg6OGxLv5|8Gw2u z#`P@9H)YpX0@=IwVK=j$z~U;|eOc7*DoAZ9l*QtDYtBc#XE6BVC&@lH(^eG#^}uhn zxgV|8sX2blj^pz^Chov1eIC`C_E!eGW}!T1uorgeZ-) z3N@@*$Fy>4?*?EP?O3uehjtY&sofRVzE-X5QOY&7) ze(*~%_&SE8U1D9rL-C7K-<+R{zdW2OoAhoL&x;pwae<_4&tnVl!{xd|Ua)w|?$20L zNEN*?^sGZd;68^#d<(5^@br}Qs?HO!Oz5H;{3X<91i9dM$ckzPM>1O+qpfHnP<fHje7rZ7gcqfd&&lw!(i%9Bai3)= zbEeO(%?dkdcs!o`)wNR z&xg8*Ml4Gki0Z+08`!YGi)h5D)9lv)o= z^jOE0bNrN~tRr^M(&0VGQW+r&{dlnL5Dvc*Saah{@*sI}g?s^3L5QIj&g#0=Duv?Iavx;~uE<+f0xA)6R;V<*ZAuvPC%JIaG%8*Tj4YOw&wR}-kL(vg!n!PY zi41UoFy6XB-1>3UAjndsAtSD4l5>K{tO(v~xe)Cz_|}cnEwQqJ7W~X^K%_kAV#Gqm z4el&<{26ufw!i7CLka&o+~#Ujmb>|8igRZn=^n2C zFf2AF?VyT2?%q8H-xWdMX5Z8WFcIha=XnLm{(~#G^qDxG$VSMc`h;U|I)6?D|E;tX zJitqsr@f*77T=h3}DEWV@OujoGgHo81c0G=ncU!CM&f}h#pPHv^ zUSmdXy1ZY+rZ@;ZY577zkT}EDm?)yed85DyIcgY_+hUxKRRZ)!fg00qRy=zk3!$J$ zj{yI`O1vc4i*?tLLN3AD=yrg8oWtp}o89Se2ZQ=o0b{xY4MfZ~&_)dB<_6dre9c6s zH)T8$+`9B)p4iZzbDB50W)tEM4^ye^wscifFl;uGaat?BncWKDRWs{qTw;bK3SPO) zm=;;0@k9NbAi)NqI)`%%;HV^R(_jPO{9#s2k$>g^*r; z#3nCj3{`?0odKh^(QC(+MlX{pEg!Z%LSLWRb$jMYAYq~=)DT>6XgrU%I3KDiI&JT= z!q_7A(nSQ^xd$B$nym{%Ul?WPfO#lQySNTJEwA41Gfr0`$fGf4=Cq+B#H|$|9$oPb zV)Q}TH!#=a>M1CJ=e=@WH#(OV8RxNSG}2vmVZT|wM0sprPjyhK(kf9`nAx_J7>U^s z71zq2P)n1Jff-YOz7e%K!%h2tR2x~$O@7N5#eo({x>TeqEMLMH42(K;6HXtywci~3 z@P|7b8|kxfdFEu!tQa*Yl_6hY+7E~B2`fmhjx_Qp7}{_(o{&hs`W?M+C1rFUM35p7qjrMXz~B) z$?LFN9Q4U0h_F~sZK_N<=9Bcn2fNMYA*#81CC?9FUk&2;=lP`XU`t04$N@7f!u;8z z_0I{`U$ru_QinYI?hpRpIvV+_i6iYpEnPiM$c^+n+9^}BZVAzhwOgYHM|qUk8NpL# z3+@h>>X$t0#!F*zXM9P_79hm2uW_%g$xL`_X0U)uhc(mT`aE>_?TmiqQ!x!Igh`%6cmnpCk z3ZW%n3rq>hvA(LNwO9-2(A+&c@Fq+=4(a|y8^m$9-M<3Ga+Cji~$+GQcTYXzj)>ui9WN~>m@gg zrA8?!KM75gZpTBF?js(r%Ktz8ka2-^N` ztNwG(Gl*NG5oS(G5-`@S@wv?)Mu@w);D8%(NgK8UhRubHOxX-@Ng)KhlyMa2n{pR+ z1zAfy+cdgTd^-Ql(;VyulE@sa4Pbu?o{xBB)7$9$?MAcr0F!k6S4BzrM^RoF&)ol$ zqWqWYyivkFkw?Wc4=9k_>$2b)10MA$)H}5fOQ`5#jp3iqwvee$Vq{q?T$i zz;k6#!wAxTdt6H+*H=RI$l_)YADEHvoH?D|$kg2F2In1?67_IzPDzyG!*nLKhrsU5E@ z;uDFH-q0A8^7p4b(&w>@!0L!a{y@1w04yvaF`nU7crXwzl>WSHf{G-uNCaTcH&{*DRq+%9_GqRKu3 zuIs~asUJn+EH!5BQR#kiT&5O?P-DuJiB5Q9i0%)hkEFE;47ZH7 zkI*XFqqalo`}5kR?j8^MOFjJyl);GL3BGXDy@r2(eE$(y(0dYMOhb-?>UY`A&0;Yx z$Q;?8o*qWT^&c^&UkqN8a;z!TNUYC=FZZ0dx2e`G52g3MK?v{k7;L3G2IP)q-sqp+ zJmE`F=9$V+`3QHqF@6~X=c^31vVubDx&8j&W&TTf{`Kn+5~;2wh>JAWpH>EaA%0R~ zkb((Z3_KNCVjbySow(`ktaJL!V*I6bLgJ*p%y3X+cgL0E$?YcSuHPlG$p;h2)Pc_9 zq);z|?sODQ3YTssfAkwuy0>p!lHMlO{-&}0WBu5>>+bQ|aTl#=JD*>yF{6<+a61zS zkXXZe;mnYq?3vJg+%2E(4XLiV6wGbbIbRR1_{GMgR9nB^7hfDBJOlx!bYJOl73a^` zmHrj8xqfR4pOWcK!x}p3PvYg@!hXFHYxaf|CHQO7C7Zr;*Wvg1q)Yc*g$3LFm()9Q zY}f_-m+BmdS>qPu(GbQ33fU0f|=4l9_<@>o^bx^4>C;-&jkE9V?szEy@eK zp)!Qyj=Z8D#kqhag7`=4W;14%#t}vDE54}wX}ABob_Yp>O1a*+T0mDrQ$GC-ILo~H zD9gld^8Q%9>Pu33dir;30ov{uc2Bcg??d!6|It&hd84@_!|8g9#hFE|!u)tN>{yWJhultLFGi>En+q-rQCT;q^{cyNnHUitHZ~Y{AZl|VjyvBdEMdYm`-Vv3p>f^8k z>WB8lY)Ru%IP+$S&#dl}cd|<#+&9OEroE4R$&R>75?GHTjktezOVN_X=hqJzhCH6F zy!&AMNVT8eYGb^U=YOi>SfYGX>$mAD8^l-M(MMM(?BT@(^#%uP3swd({7bw+HP7g? zNX0^T^Gp>Qb;$EnsLHNI$TPV|YoZAZ^v5tIJ){XT91p82oSN{wWO{Hf1+N-bK zSt!}n+K~yfOuA~iAHL-T%Qm2eMqGYv=qq`Yq_Y&jM_y`Z`F4@pnuUBB)Mk^eW44$N zh_M<;-`IapQmWJJsCU2d=7y!w)m1t5=*r#Q-5Tiq z3G}L8e47m|ImWsY^ipVtIj&yXv945nKgH(e;s@D1wSSM;+u7baU?jBOVC zUs`Ww1M}8$m6R6?fr#g<%{@oAHtrm=g5bE6l#~i0>g}QR$A3cvcW~}M$HMc&-Ka9x z{PzJO{Wl;+v&W{UKCs;%vbM>Kd^aJKja-a+)RR?VSC{#dA+U;=Eq0r`q`K@QI!bXU zcTVR9ZZqJw`qY+2@asbTVqrCD0BgsRH=3Z{-n8S??AZ%~OvYih3;}BghezRw>#I(Z zsYh>900a@qF44i>iGHG~sqFB|$gM5sbwQ@6;d|JTe|bU zH!?HbWc&b%;U`XqgDZ@+C*wWCQzz%`ZyMe|)eurAp=c0%FVWOj|8uJ+&L!wc?dg{C zs4e>yy-p+|YW9o=$x1T$r)PNT_S%EK zb*_5`Qyea~`A2xRKGU})`O)A7FbevYJK>LC-5nNn(6x2#uif746fGwg#}(oH-C0>#-?n)tPc6*YpOK;r5>L8n` zwuXJn6 zqixG7Ro0G>*3u2`%$!B0x7yQ!eFtXn0M@IInOv8PEGcAbpsz@_OJlASi*~`kOX=Zb zj3Fe9Pv{c=3#O)5!4G@KMzv~an*Yn9qJlr83;PLhzpK1-Q>?({kcQQ`HkO8mP*-37 z2`QpyMxbnqy^ds+E#hljLafdFh?NP3Q_O!oGrv{--uu0XX*TpIiN@ad#!`V=^qA+9<; zwhM9C2WWJse?c*xpCz>8l=SsyvcI`fEaHmi-&)$1DriW_|7RNod{`tH;U_1{}bm=|U!e$S`K8_2tO_^Q@eO-ywLnFT<_FB_V%L4XC^{5)GV%6Roll zz+|4x%*{2;xQ{>mqLcfGX|nkozWxS^ zpbNnrzxUr^-Jd^eVRZPr`KxDtQgg9>1VFRek?n8Ej|)s zncP*q9-6~XEME2w_RkC;-nH@=OG{OY!i{2vZG-yx4(VN4kG2Dy_s&s;uHONUdoMdgcKv10f5eJMYePyH%tmo(<{NFT>KEptdV3ug}h zUao`b$$*$6<8n_eN%Iw0B*tG47l=((d3?wI_v~*e&q}ZAUfPB7YSk(9XnEY+@O_xT zI}#wlo$Bi9;Z{AA?o@RUm^?)YFJ3olDf5A2L-4?Z2w#EI{aT^XdbJ;Q1bLc^ATN!b z5P{a+C`t#6mB2A8Cm|^Fy8EyHUo4rdE&Kn#&)mVuV!UJKc? z4BPkD7UlTf(TD8Ci?sJOn;A1qQj0z$lnHtColkq0Q~Ch=z(as11L3h0WYz=48}ieb z_+`G%BmCs4@Dpw!e@89sb$C(OyX6P=k>Zw1K@Hu_a!Gh2u9Dk!&i}f%YZk*IQS4$} z*>-ebA}5VW(_JfEq*Z=+<0UAlF6Wrh!x-ZD(ut}((;u81ZrT_bEJRZ)WUQ&DMb;=z z$B@rwoAf?l;Z+8%5AZp7PCxz;I@A*J*NJ%ZytuJXi~hdCnF*`p4P__(m9)bCck#{33&#)G`KbXtK#`TTybSdHXR2 zb?p{krb-qGM#<$W6@GGbyXp1r=}ZfqN>qFd4@dbMFXzzI1B>QQ();i19Q_Au2HnRb*|}Iub0qhAeei>7go;T^%6u z;d#7Mea$LWH6TG*ltbI}ayh@Cw~f!eRI*>})ac|Pbr~10gq4|nRMq-SRfl8{L^ozEsMxA#PmHKCN!hd0%Fy~1`?+OSY74Jw53ujjg81Ikdv~11 zZhzEd{=`r%qLd2RxCsS3Uk-JW-`|zoFx=3Jkw&GFUSD6qimme}b@C2{L-u8ts-Z%q zd=!FCb5bhht=8;QWtVhF%=|RS}4^Nn>{JBbuuC?i-7hr3dM)J&HK!W zpHO*^>7fN;LID>Xvt3x)RLdnI#(CxrW67E-e3_@+E_*3 zQjpVvXlix#bFPvo)O(ULHQJ*&HnfpW5m(NytDW#fR7K(xRYhlARW|S5O&s-2xQ$NI z!7)zN_Sudhk!>AY{E2AsXF7C1&4OPx8-w;co*$cNUv3q*BG}?Sw0@24Zo`1{!sAVt zUlbGNWgL_dY0_Dv6d>4`4jW9^(1nW_pmYPK{ctsqUN6*-3$0QDWZf5AD#Y(dtt zt^dSzPu0X_m;@5?q$^gKweSO7r~OrPqU&yfssj0{&&o-+-pXQz!$1=Jo!UOwsy$%y zI;1ZrRZhvB125%|<j1FS^C@%}>S zGCc!!%6{*FMWc&?`kpUOE!eb>1jl*or-=jPT7bomsX()zc$FK z+N#iR*OGO>9&TOk0pR+1Xa&g6;z;dd<>Zot&MIyU%9oMWkuICswiboLr9~v0d7giq z06TduX&5Tif=6=Kz{`xLdie%%zlF7RUe&C!?fTxT6p1^F`#^4`2NtcA^)qGQ)K^%$ zdhEF)`G8#WbF5Ham7d~qoh*Hil-#WClbBu&C!Lxd!AZ!64jb(&v=XBnz;WI{71GUx z6r^f7VH;6d;&r{gtl!Y`%K-YsOHGW|L~myX{`?9})R=`jjp^CJu2uImHPSCDuKMnj z%f}3(yO2)D0(>3z^W^VYczmKrg;5h!N}8F#A0eb%wNX^ks!R{K#1Y(O%F>r6ql8#*P{xT2!0Ji^JeZ+yrmfSBh|7k4bytio8&cwT39I&&4#VpAddlFk z%`e@>DYsXtr3Lk#-@b17b_T}|^n_(nkS4nSojXg-Njj-gGHydvS6aW=uT|l06VIE)GxPW0z_D zAgBKXhW3AIi9VDw|7leedmGaj?==nQH_Pj!->o?fVw}7(0Y!f=yTum>ES1RwDM#y) zA0tMVNdo(Rak}t(R(C5+ubWT4k_->2fiU0zJg8bYD^sn6$&gD zNDxJ*27F-M6=;_YzM-8sE#8@EvS>E&=&Eu*{|A&j&3WHSCT&r;Op6X|j8n|K5b{x$ zY5nQh6sO6wad>(DaG*pRApYu~5aDmno2MAoPb-A#?q3kO)EQ0|3A=7VpP!}EcX{2& z4>{)Ko1CX2P4QI>k z2$cI$c9-|C*Fq74tRSMW&3$bv&x3AP)1e@EK8Fncugs; zaBs3QoQqFvuHR#xi^UMX!(fG0$=u9(99?a`Lu$LHB5kVG*!D$gTUGN|wd4XuqjFJ7 zEm)+b=Eg{#ARhpevwRr!7c%N!05gjL6F_Ju|Hk`^MbMQ0D67V<@7`#X__^v%?S8fw z$6j_ROTmJIfMS?kA}>Ki!NJ$e*`DC{uN=B_OgYui(at8D@;HL2Dw% zw_397OAsbHvY!wdtkKhb@m-CMYMK0-qc}JqI@*RgOX*BJ3ZZ{7lhlAA9zH@iAeWkyk?up_qT69k;z2*j@#KNuoknpHv++$(7&03}*{Cc~PtogtYxK$1 zNzl!3`_*1|-e0hgevvvX*<6|+Oyz5;xpOu7GDM@9x2NJqaX{8J_Y1yEjkxtvhu0?U9V8O~WB zZ)mQ!hsIcJFUg2BPK?jIi9WY0@E(RKHq1KAape~Vv6}iuw^(I5y`}4y3i_$3u z@dkR*my-!~(&y~A$$jsm1&FSL{cT$rbL;GdJl^~Djq5wHArSmR8k?ukZ^#ZMh7?RT z+u=IXhF|a7_q5foCZ9Fe2JhaKFr-6om}5x$n0Xsjli%B_eraXzf!!Wb^ILzjX@1x} z##(FH*e~H7rcFeK)>uY|#LjRBkwR9RAyt-bh zR&r39bmPA<^i*M(IA}y_!hyelC2hOR?Pq=Ru2IoEfbZ5 z!bZXR(5gefFn`5&=E~=6iJD8sZH&|dSJ~^%6vJ>O>V$WOKpKmJ=$*02McFczZWs1=)RM@TedXdlO#lrUh+@7LufKl(PyEAAzL)iUy4*-^w)*xB z&E`0}rS|?qHplX!oHaa+?qd1KXHbFZ;=Z-c@Z5Qt)#=;Jz*s%d$}h#Dtu4^{r^1{G z`}i=BG>sP;TS1tL?C2mx{VBo#l0wTHwa_BWqtXQ$DuR$sUY-S z=p2+mVFv&@(`dRr84O24WOCd$mdi3y678IFIvBzDDlyp)P!w%6O?9F>u1y7pCpOx= ztMO7~=X50(d+FMUm^mW$ShsP}i0^&fJ8O1Dh@?IlYz|Vi>W0L;-6_v~x?0~0U_3Iy zu<%C?|Hg;SYBlxa+l-3q8HIvps{a?~N2-bm5x+17zxpEpV#B6s4<0YlDX#Hf2HiDh zj4tU>V6c5}C}TNJwTkl3TQ2ihC$56FWX_FHA&dNhB%ncc@wBdk^B z78}3~;L11k`UMb@87O=yRLWdMjHtW3Z}?zCbJeQPth2wutkb&h+p{hWUN$y1={BdQ z-S+EZSDAt;P8oUz`Y8kWa( z6Uq!XUbb$P;Fo{4>&h~yB0+2gT46VaJ`^|)%|5Ez*hrD1bZT4^Wfk3Os0g@+$x{em zDnLryy6e+YHq3QoCr@!CmuJ28OsRvtzFqD8=CoBV5LCuLpdJGSO`E8Z+oA`6`t04U zC*tI<8nza@wM%g7!e@kLybof%3j1DEIft6-2KJM0h;0si;}U7iW|7C=7E==qE;?+9 zQWPq|pTxxeT!loU&N$~!GE;jx%m*$GXti?;2mc8(9GM0@nul&L4VIj!g&d!Ur&*tc zmh;We4}GnzDjRxJWs>#bygl?D0mX03%$U1MVxzh_Y_}nWNm_-fm^$KP;{bulKuF|+ z_;>T1I+;FnmogKBk0x&n5T~gHJ4I0T;1$kVwKIX-i1NZY)2!9_NX(FrPx%uW4rr{8 z19yAlkX!Se8JIT9lv;~npn{bpNtx@99~T!cZg(Q71ilUo4Ad<1VZLDQz-W0Um?ET7 zubdw;M?ZvyFXN|Ca6Gsk3H<#E*Jk>om~dz^R-Y_?MOYK{)ys z6NO)@JxAqh-+bp#NpyePCY0d%D9gmgh)E42!wtyxn0m_1 zbFWMuZJ!a@4G@9{$M z2qA3w8pG}D{iRvEuG%B)g>POjWd_vM)L3i$xXh?(E|2AQ7=E8WDC@&|QkdY(?Y9dK zcTBet@dvA%sUCKHGEo&53JB0lxk%~v--b_=cIC=FYfS(Y1_Vgt7qg5}beK@==(W~{ zDMFJ;x5{AExn`D{zrANP;rBLz&8g>-XipQdQLch{I?nSj>E0H!L&07!P0;UVe$Q+a~#4|KW? z+ok(0PRwvXxB5^q)4={Zr2_*PlJtC++NuD|63_BV0{&Sy#;>vErh2mrAQr}SZsaDN zEY-ZRG0vfKRNW6{k>AG*3#3g4A8maGE;o{2bRxFK3GXD z*wpl7)h-AnaI4aCV8AKAIsf^-7yV|@n@|xS)_5S>tberuAZKjs%kVve`2>s zAw}C1Tq0I+;J$(D@S+vJ$IDmWl@?JS3YkCshz$O8y>P@Ax7%3R*2wz3=oWyCfj3bP zFA%XQou3XOP13*08C#QgyY-97+&6O?ZxV=iA_IvbYx>Pj72m)5pb_&GuLSWDXs;RZ zb!*`Q!7!kI6=PW(8I3UUV5b@8BD$_uDF3=5d$1}WrxxXuV6bi?q zwN0GSiHhKB zp{(rHkoHAW*BPWTSSD5(!V3X<=V;$i9Qv!)hBS;#)84 zgIeDg`=pY5G@GK*rKY@Fy;=GcwVShHd5V(0p;SPzloKM6p^-@`V@dJ0gJqzGYz=5` zqP|1LuCTZ%9}O0(S#4$_!1NXv92JoeE_sdIFmlaawql80XTknCM}&TDeyY3@}TXxa$7y$!tni+a}Y= z@)RzESS|$$zDwXGjAZYEN_vZ9LY(%Ij1?f1 z=dexqgjm2eW_&s6(Ubp-MKoppVJbB3^*VA(O4tWA(goKZQ8bML9P9Q6$vrigs;PBu z@m^LJB!3SOk6Lg$tcWZs5Yq5!&)uM<2#d|-Qk(FZu4E=14t)N>4U-2GkAXBYyViQI zt3=6zt1&fJF?>&U*gkwF5j_jdRAq`?M}-HMqsd1T8Dzg{FEp(a>zwj+%JXjNmCLk> zw6%r46?FKKA?8%uvYgKDi|REkutF?^VISXk2Slh!rZ$;)>&nU!QYu)ncAIvQ=PF}9ISe= z2vX^}F~^rSjroGXD2c;~0E?BMe4+cf$X_Qd5<)~BCQ70OPgrmW#n_KXD8d&8+az77 zc;EL)r7&z^{i$m6zmiQVs7ag;%P-}SDwp7pHth?el&7L|4jt=DyH{xQ{UvHVW&j*kO`BurkS z2sOr)Jf*cBD_eMBv7qoS=1U|>zHrPl!;E?X)#27x9t7W2fB5xsZ(rZ=hV~g%yTiK7gd(p=Nz7a&xkca4pqqT^Zm+9XSSs!X=4{kftcOW zvTeXJRbXI38}JV{PF225Mst^^7?#$ddK0TN3WuSZhM4qf4}0Cd#vk)r3>mM=I68k6 zFeFpiOkNMjG#V0*;>(0^4n_TgTwaq~2>^7EhxBLBW7F3i8V-*({_!krQnBdA<$>%)iW`PbdL+$>p7 z9a=O}2eKyA`r!uY_-$bqQVn`8q}a%G89lFMR`#wmby|jG^{q^FnX}|Ea$h)WF|>%> zYGUj?uFp5zip_(JcMKb`=0E2fua+vEt7=&p7?+tEO~g0xo$h-TV7V)pX-E%aCmxj! z?YQq|V^i?HNqmT1cA#_x5#iH;T64W~q!J9TMrQYlU4OKiE zrp;%qLS0_#14gkM@bdC@APjYh1o>SnTk3Rn!1|q@`$at5wUWWX&dHuZ( z@H+OlW3p=H_o2`hv7Zg35zo^JU&~EpmYq)J14O%Dz|9tw@!H)^VlDEX^~fn6;q&#L zcU2bM%UkBH%g?b1($mt)E+-^@y}xWz+k0_xL&8Wi z|Do&b?c19?<4*B~S)rLo z<4!h@$(2?SesV|u;Zxz7CvYH+$z4YQxvyc$W6_%NJpX2?{?7$ zJ>oO{!7Q8kR>5`0_K&w}{~1qp+`QfqBT!@0fl*giFBWSyv^p?$0+KlvQvRhx`BX=A z@x_prMdB^_~?GkqxrfEvB$VU2>pu}8yYO@e((lX zIvO0zR=w-42Q_-WBoSap6&Ez`d0~;i!3T`MkN;KW+jT3KNRnAv$w+;mka;-b^c9k? zh0s#})P~sE%`8#!h@jbGH2H3xaXsmC?D`Utc9JfKneIP8ouX8Xz1w_W&_iKo7sI|q zlg%ifqRnntz4VN7NY9RSeSFC%VS-ocliSXoURvq6#wKG#F!&sri*o+8LjgS6PtUB&o2jS12+Q~AkeGU>=_6#Zs_8yHz9J6{NPr%ATI1U7MVYSmOi53= zq#cp;R#ogjx@i9HNB`*p=&k`8_>w}N@cm^D_V+iTYQJLuvAP}m;@VH?R=#NZ67!qf zeS}-Pj`enMhk^S0D4>QK60lwY=;1IRAwN##v|_gw+8vpmdx7{ z-VVJx5Oa}_^ZLi{ylLZNyx7J!_9i*E^X7%y9jJ?xY$!o}q~Ha{ePL2a^a(1$^Y=`+ z$&*s{$6Gxm2Nrq^0Pcov=ZUd=MJ&&D`e5tJ$jQn3a=}fFuhPIbl5Tv>bE|8cE+MX- z7#dYXWzqblpsQA-Fa7z&Jn|vO&l}X!9`#Op9A91w`^_yaLYDc;YGUoe#*LlN^VPWY z)437WZ^5oN09HeWnbmvd1ils*uyZa|R~7xpG7j{}R7SjzINs#9_3(4KEty91}U^ z9QD-pkx!byl;yR4TXWN}jxpA<_^}l=o@?fN2Vwz)+KMzQIa5D2Wc!LIMYSItrxnJQ ztu%(~U}fG`UTjt6P4hoNt7wVqopm^4Eq8FTBuBCY+@q;#OYs?$zC0)IFI==w`C^M} zx5{u}-OaNz_?SC!>2Lvs^FBL#($|Isjol}k_W%Mc-3Xy0(8;rU%gfJoF){>M z8JQ6-9U@Ht-ukRyhl}4u&e<>Tk;bwPC$-37w#cw_Yf^l_;G_3GyrthIC3KM2)f)dH>FE{Rm ziN2|rZOCc#nXGLw`5pGJv6;0l;7FKB;N!0T*Y_P4*cTDt9}=Q`LQrQqIPj8am)pwA z%roQfyw0;XZF<|5IY!L#_f<>H9OtbSp(~+M^WH%Lk_{F5`COturE<5NhTCKg@3gV9 zJe{t+6aZI8j0s9Ilj;gQFVz@(xb9cx01)?xWwPE8N$ppcV7yTyL8BqB%tOj<_a9tL zdt-c&I__k0Fio?4>QRhcuz6>%l)8q7Q3a#Z^t7q%)l2@j9ZuJ=oJDZPQWrNJ=}M$# zHx0B;2cpwK)nZx6^bHNlM+>Y1;=X`<%7>KKc~M4k1-%!J#qGx#SynM8N{9R>Yn*ib z2Wn1I14}lzXB*d6uh|u(&lgD0`kttbPb7CXv*}3=cXWtfkh<2;SBhimZ2baozRubO zm%^2w1(G(phg1v!9+00E69c3OF$Li4B7ipVh6YT~v9hnlImFlG87!=C-!=xv@X(VfhYOCozkCY^W@%&@gMz^{8@TL z?++s$J?su>2k@KpWU#Cmz(0)D37@OydifV8!2dWCfH{Y3&()=bLw$dFH}tosuU`GJ zAPfRQGgO7c;K128WPW}XPn7Fj zutt%_eNQRZ8OFTN;qDhI;rYWslyhZHh%-6Y1RzI-ZO*3bl1mM~r+th1*5CCL?znIU z%)c??%I5oU1LgI#mv}#oz3Zs9F4H?wno!p5Ci{?LX?@qm!lLxpF}KI@?4L?Yw|^EE z73szy)bDm;y69p|4UZ*>a-E%y*X?KIa!jk1F~W|tZc0U1{g3*((&3v2%Kb|~{_HUY zMqgnL?SY#Eet<&$GhKG>?U)TFKVKY0{|xjA4!porFN)hY5|5HskM(fALt;QL{xoex zeh_S)+b%ddT|G5l_*n@z7WQqBS?m8gd2hI6qU-CDb_4rWMOlc$VGovnymto2g_CVJtK)o_sM#2mahRxjpFbgs5Fka;| zlHWEJy4R(?<`#*M6#_yYE5D4nx{(A;*_x(!;5q+P;Q{ zh7KX4jF)e&t$sFq%?^%Rsc+DKMG<^wz+0rSSTC8{!g)Gk=3tz_fyPFvoSIY%^#3#> zn2oP&Bg<`#j%SSp+&472#0!D$cUxLE8z>RHySeiyIWt%eHgD&pv2d>UqPBG`BQ@wn zZ`Yz2LNDfLKTn)xb6RO1XvIj1zM;F++jHcag$o8RN;boB@(LHS4C<=w?Gj_1eT=x` zO5aQm4iDWvq3Uex3q4V?cF{o++l(N=1G3MqTpNX*XZe{wTdb_C{GGpMTy5M^S5%Jv z&9uyouD9elD@ssdeEtTEznIqD0JJtLq(*Tl*w6UZ$nt6O&-Yz>6X8aR!!5L;b;9H7a3ue1=9l5lG7u>O$sPN>042$uU6 zz560&b;ya~y|I30XdH@E)xm zfLRKL3#8F|KbM!!MJ7Z_gN{g#^VK^?h=yB=+%cIP_8ZB^+UX80ZxOJ2nGqXNZ)|fe zm`X7=Xl1UO(&@>B+9~@U+7P@SQ@{~r=ueCsQ# zl(Z*V+~8c^WxQuOD|J)dpvqf_$&FdKrd$RU1n4? zk9|`^gQpNAagF)ukf7~RXn4o73oye0?1xu@=T{5DF271o6G!Um@bXT|t^4h*6KYGw ziXz}E@`H96tkeh?$FPt47jke%$w0QS3kXuriVFM$7lk z9s92p|NDmcrwd>w46lsb#>jkJavd$VBAj?$lnH7@Xeip&UVwYaNaQaFI-hbc9e~_W zPhu%mIzqmKeq5E(2{12}@L1BZ4C-C_+As;ev23!%S=6a3f7|<NWEu}Y!Wzs4Lqcn~Oi{&eg<6bDzIt93gDNY~3M z_FE>ya+_w~9heb4LQPJfbAw(*g4#6lXJ!)M9Y@xmo-hZf%6tp00f)>-KSfi=f1cy} zcZ&e5$>lph%U##u;{*T3;(^%>BIc;q5$d&9;&Mr=RRw1Vf{(5$n=%iENS%75RaW!< zt)f3RS}`uRz5m)EyH4!&iHgH#>mLV}{lI75A8j*)88tkA^(t-kSR@$(4nani%9DoG z^=?+7m&8wXV!oXtnnU)V5_g!5Og4TOEB<-r<2S}c6*`_(0Akz8sjl{vOu@{lBsfrX+fh;(;2EH zQF{=+P-Y1b1Q;WrEE9nkRfz5*c_5t#Jhcr(2H|zJwKw-c+MHV-*HqaNh-g=?(KY4I zjZQLYX|CLtk+ClXeDS%vdYUEL)_ncULN*l?RJFjNah| zO@$M+rpG&OzQud{6(Ukhn^Xe^Uz+I|gqD8EXQY~gMn3}Fn~qaZb!zFu68#wQH}LOQ zEY;axUcbV4>y(f>Q8cfNe!zsTi}BGt@-8Ycg4f>$q$X$h4{56F0<6?)_oJZJp(Fbr z)%*SGbDY_RIP6F=+=Ux#tX_?3I`S_um&sq?3^Zx~5&rwsD?~yl$0QSbpBO`%WXT)+%DQ!UV0=EE}r8uDdxWhTS7k8pwB-3R%>kHs!fMDUT=$& z8^s4pzss=-d>mL=ULR;2th{Mi4x=aswgMy`p!;shSqdQej=(lvT1NC{nm@?q69hfY zvOLg}ZU--XR(`avQO0CVA!Z|63N%>*s59EcjrGyeUw6x1RF~%}Z6e-nH9Fz+OB+YS^>I{T<&H|W_3gwAzLWfUnGdwFjftfO ziO=j&w-bTe<^#KSbq_Vn3#jkMBXxtjNFte?U?oFwKK=46SN zyppLCDX;n>Mi32uEK0va?&}RP{<-4md35!=Wr%SFwy=_%bI!W^V4I-x4c`*ecUgLD z@WBde9zEMe!(XJ4ppmdrTU{}ErI=v9G1b|qTR!g0UI`#+F7=xfA8Gr+E46D*pYq%M zc~DdNOq%)Xx4CyiaWMT$yjN7s1ItT4YR9%tLSKN!zTaJNZ0UfW!1gV@VMQ~4yu_f< z=#FoZc1z5KIQbz!d(OE1)#UBlHr^ZB93hfwtd@}lPv=nyJOIjAm>M4`UsIL-bdT5-a@#oJwp4jxUFi$O=%m7D z{uj#*JW9r*vSdI_{&OZ2!a%{N=ZA*hT)8Cy0wM8JQ$4HHp$`Fz42|Xb)$RpaVj`C; z!^6-p?ksQc-tML+(W9QLh(up6wYrH~g&Ae$UM#L|XbzHKB9rt&xUJ}HzdXE=A-)0N;g;W*iHQVRE(kQw!aJl=>Pxud$ zUbvrY+Bvo#r^kQsN4qx6XfPI0y3}Gl$ca}I9LF=rOax#J8M${k?MXs7XQ&}1bqNs2 z6a~oX-~PN|pyqt{&m&=WYke_uL3=r4BO`ai!_jBWa%fW6Ih1ZWQaz}6M@Db;VYGe0 zAJn$h>dHU;LQFMDqY<0hI(vwSiVfob?ln_ykB8q zp&2W0h(Qk|&3{>z9T+KqnFgG=l)v-sG*Ic6xS~^OTXPfos_z$9PPKMa@4yn;^viEo z_w56Vz1iRhTI^{q9NwF`i|{}A_J1vcKAp+?4N${Fzwq^an)HIWyzI#p3u_{CNI7|w z7dC&1m+X(dj#kMQ$DMecl-K$&Iu!Fg|I?97H+l-uEA*A)p5xb9WPKzUC*QF5_MYcf z-O`{Eo$Y$yZ}pz1w@=>t{q`#!k$`&V#CtzBAJ^yTwh0V8+FI%{JCR~VDneKk#OYi} z`!rK;W(}6yym3g}6!^%Lepv&9OGV6!#}UuU*#4>8y#znGz>F1k+tPE&&dz48d2588 zQ9$jE;k^VgmiQv?ymDgGP7LP_?&e6J&v`EOoN2Se!zn#xP?bcD^w&w2q7B@{3hn1f z4~lNDU0Aqq%=(zsi^X7rJ)8=$*{>izDzgxium{NMJ^E?MCL9!19TlsPxQT zBM$?#>+4xcbm994PM$k=VE6fX7QLVAcmNu*~L@7=@~j(eTiR>q$kT_OmI~iCx#Eul+||@T%~~&xV-y8J#9T zdM{BSkJ(08hYf+nGedOw51))9T>_}u_I2(jc=`Ce_XV7aHXLz2+YVz<$FBu0eVNId z01BTC>Z{_PkGC;M(i%Vhe7@ZofJE8WJhN>LUaOIezjUE#{I<4J?$TG?S>IhBb@dHw z#+C+Nwn{biu~i5Dmh39}nK}jb^1!}`eKP&aNyltO&+d@sf&^-s-oJm7m6i2c7`DZ( z2Y5ZrltIlEyf>=o%B@$nnFf#5kI{%Yq-oq)+58L$EEC2UMh;EXxSrPGI{xhAb>WZX z>8D%saZejn-g5uDCwe{N^hfN65*p*9=D#egKGlBljBhIQ!LDW~@3W9V%ZDOC z`y#ObsdAt-@VAWGpDaMkoonFkPWIg!KVKki*k7Nt5`j%#&wc9AAoMI5BEX_-w2;U0 z+*~;i9D|mAh40AONQ$wq{5;ETtkP~9P)@(~{_XMa@73=e{#n-?N#Am&%zFs_yXKI; z^)4v_?SjHeH;?_*BYyh3;dcS$x}ewl$4)%?Gh}~g+Es;L_f4c6K6lVmpyv(u+1=W^ zDFyUEkx!t#dG30@nP%-H#=S%mjj4Qp63(UwMtpyI==ICGl`PwSCZJiKXN_{MidnYp zm(G85wl@aY;lYtfqhn)3&ki07b$F_FOdJVgcrG}0JkN>yXaf->X9aA3gL9a39kl&= zgYKKxj-3mO9+|=4G~s=Dt)WSdbz@?`@FsiP+L0t{Zos?pITK|n>jf-8RRa8UBSlD z=^4aJ`Ln5VzyGoSUz03>r#^7x!5V?x9`#pC^$%Y@clChn$xr!0nD1ppMK5>1AFhzu zAer6NKFbfplNiAMyN6avkS1qfv zGY4VA{VKfund5$I6E#_vM~gi>r1C(_&irdK%8WL#$wO~Xo@0uF5rO^<{^bZ|G8&(_=`G( zqA?4k65D{L_mfv#7tar$8~Omy<^U1&`@aOM^?!5=eF3pIlY*DiY=(etib79h;Mw~D z59TpD_zF{&a7gcY9%gGcRx?dY%B9?CL1Jvrv2}aMu!D9DM7fmIT^;9n5yhu>ndq@w zm|~J|VWO_v;%|IG{KFgJzF(@&_)8I8{2mYY4L^Q$Z+<0TH}1!h>x1_B%Js|(tRjMFyAsxKP*^Rq`G7O>kO|ME#2g1 z=aX7LuW~0|lP_h88Z=!u_|5o7M@+NKVWX|@r-Xenl%C3UC%d`-2K^(tjpekuXRUHKk}b8(T|AWXCR(g?qF7;0@NtLpon)KONd^UGgW9 z_Xf#E>|r>=bloXA?9OZwZ&+8NvCHK2bWSA-Wy;=}V^5_(m<^C@fqFR4$6w23I?LJ! z^O%@oFKHuatlY>g`O4QE%x;GwC-8+Pzx=q6FGarm!;C53J%r}iB=SbE!E|GDIu6UI zz~b4~bAFNGep~X9JuTOcY;tx5Ig6o4g0oIPj*bZ_Sl2lU(C^EAk0 zUG>rb_Qgkm2S}W&?0IhZuD%JQ0>bi&^Pb!Eb@HMjHKMB1Y`m;J+c}7DaAoh^5?7}6HNincYj}KUGW*w<6GD$RL zFPYjuTXdLXjHQ35D}@=Et4a@xPRjOVQ+qyu&kjt$*HNs7^l5uysC3G93JlSjxrBUc zX>O3_iCjgPB9NTfIVLoPh9O5W4bB-4Iq(o`%QwQX%$YG$MBD;}O~b;sY}maJPxmT{ zc3UlvFQR`4*Wf*lXPvAN8PNg+flWE zychY?AaocaxZw+EvBY@qbobm|HoQ*MP_(R)O&@xE6y1g%N9^t<_(v9~7Y+hcK|DeV zzLEhen-NCCC_0{;tv>mtw^(YGzi}ID-M?w639F@Rq> zN62nSDnaSG~HH0RG|D4GNUM}3%uo#SOl9nhUVt6=%uyMFuq*j>_D;{sj15V zg8qZE3TL6*li8F?aRt!k@_89~c^j%zpU461?m}D@EB{45Cn!jC8oQ0-tW>j(o3b~f zVL@9v93to9C43E%_7w{(QDCSRmt6>z%wb{Y5Vk?Gp@waJ)Gtt(o_IRn?;Qm?;O%~F z<>hhd9x}Qlj47h7R8d*%v_aL%j@xK&1qM(fZm0CCJ3duj)Y_SFm1R2)x7O`2mh1_3 zy}c{p95?JnveasB@?1EI5ROxe+n}CT!ac~VX;oFkGCV$n=#b;5rNa*`vr(I*y;en< zqqV&WJRH7s=@L8;5Nh2S=P)4tqa!b?It=}@rUQpTTOX_@|aqu!#7s_?=$QlSOrKO z5m0_Q#hz0jZyu0p+oK5x{_|1yx5IBu>@s(NYA!QOj-w@sWOyi0apnZh=}%0)lH?=* z%MlrKw)A#^$T?AUp`L5)h56q_z``+C(jKKgK!_;9=zWm9s*$V%x%eR)9v{SU#EU;g z7K;Voh|1*kP@S~L2t@}MgCWmG1D}>$_KrnU*Lksu4hevqk=`#JWSS4|trW|WQ@HqP9l6# zI!d-PG(0nymwSxV(-k+}H^4?lfnV31Q6gzGgCz?l*&^oRpB`b6^#jx|0<~^~ZfUH3 zx5qLRLyU-rXpB6q6GpUg?QH6*c+fPxKW#0euv`SP(KM$UWc z-}PcazM&e@`GjrM1PcE%XV7W-O51J62^*E)Q@orD8_YUVvkMo z&|s*=pP7|mhAzE9DQLppqnvmvqyUO2wdhe1Al;Q?S{a_`idfC1d2O`++TFLHNuvBU z)mFW&v@P1@aj9_`E~+ZZrHnmH`-w>oGuR+^B!{`;iHrw(S~PwT+?zZGlAGL;B)6I( zWbFP}u16~NU?w+~QUdB`HpDABW_yUF(TWtGu&o|tT&O0}an%QnRZ&sF!&PFU*t*={ zj{{0?p<+la`F5J&MnU`DadP)OG#KPM)@t6gQRI~Y-)x8PC2?weGa)QPovqm(@^oKW zN|-S_@4*@irs&sIL5$oDQ^T=#XKLqQqr!g`H2lqya&G?~gAv~>&sO^HL4}&)zTq@4 zP(Za_@MeUxf2E1d(#5JL&`|2w$0j-LQLdcH4->tssu3@Xda9(q>x7iipy3Uu+?LQq zd-6l5=gbZidVh|3khSApmllbfd3ea$;{=oboZ)Q0F1-&jwH9;QLri;Po%c1jmk8^Z z#eOt9t-o-aCkr8Ab;MMX0=}usBVH@YFWjTo-Z5uza!OXclt*c3?y7nrPkdl2-X_zP z3eJu!_jM_E9qs;5*|=DXAKeUJTy{)IW1UC!p0D5mgu=L>qSB)iqo!!FnhKs_b8(hf zS!JV0n494<2%?|RskH%Bi;iu=yD5JXnONH?qn8-9#wgSD5#CZ|s?v61W|BQ`z~6f| zb4*$BX-rA!HPISz2Lw=;kPN!etsGxMuvq@-I8e~5VH0A()s!QcXtiDrG~rb^5$@t{ z6W-je^qE8*D5yu#mmLWi2Z{x7TG6!bNAY-6jro}No5G^)Oy(7&npG`C8#?Mgh|9i} zNVH%j(JG94MTFfiR7*^q=Wct&TDmm7PT7K9%HCTugsX-B=mzDqvgKhzNmYDi#~f2inJ9!Q__ zv`Dma*Bughf@2mM>sWEE7NX`$y83E>M<-CRS>8{1>pN{qB3QUu3sPkWc|F!Do39P| zN1?*fvgENahN+;W(w&49l}R3t&MYQ0D5$RL_H;oD73y5MqB-?`F1D(dweoi)IF6dyG1Z-s0ojaPiWR)6(F)||+s>Gr z!v$HeEFIf7S0`FELaJS=<|L)_=3$9ek)y>h?y1D7CFk>g>JXYm8Xby&$K0W6uAy8| zwS%(d*%AEyduvPRGHj>1>IRBo#q*c3`QOZJTIzBQ&6*qgzs2uSe5FeIGU})HZrh1vb5mdRej%&@6*v+40TLymF6qGNtuYWQ zv)v(yM{#uvCMry$G?bmw_?s3?Tt?K?z4C5Q9TZB8;AxdSQy;`XNp~w{h=jXc5Vw%e zntM-P8&9vPFy&Y&qR+~Q%rnfl)%AY{l23G;I#qk3aXf$Tu|=>zY;a&NlM{d zzwnW0epO;hp+>xi8f@L>c!+FZ>w<|oIi*>dCS@VNdAtdO_qdc9ggA5>PRQmpRpN-8 zvAXG&_gnxMl&tO+p9Pt@08QXsv@M#8&yc0v(pgdJflVT=D$Aprta2z;XWJE-F&;k2 zu9O8MmJcklx54Lk3{%&Vjca9FjA+^scGRcPmI0MaK;cuKAZ(zfLf$)?J7T z%ZpPR(R_%S2+|JJuItpm4vWzs+U@PofVHdF&e=aWyV$H;H&Wpt?$%Y^$Y0Sl81jXk zuU?4l$Zk|liV!4*_eG`5(U<74h8QKOPpYo{tDq=r>?mzQ!k5UuyxWSqI+hhy?bO(j zxv4l8+u$PeJUq%ee#L*+qzu^RZv}Alc_$fx zQw8V7mLp`Mh;2L!8gn|ybu;^aW}5%`&Lf_KB0G5<6@G*NEup;rz4Wk;lW($Pb6{gy z1t9|rwAHSMuC_HbhrY`NHNhIv94acRrmM$c z8+-P4-rauNeus!nc(yyFG)&QsKd094Z%Hqg?Pc&;@EiR=3mv+)QMrDt8P6Kxo-H^Y zeB1!IR+sX0KWEJ-g$;-CT&pdbiyU&FfH@16+0+y!8OZR9NfspqnD_Yg2(8E?%PrhA z)mY_A8Rtp9t9=M}E~j1rs3;(J;}>fQMEr z@o7>^_4rqHB9D#eTw!GuqcrfGw@ZI|n=zvu1NWzWbPO5@ zG0ff0T}@w9#tIltIbxgTr8WX8`73g^BCU7=B9%gQ&>NGux2{cr=XM;JD=iGvs%?4* zXl*&UZK(U})u3Kdt)U^5Ek50Yn>Om`4HZZFN3A;eQm1Vn#F@JEV9reWprc=n2Wgos z3|iA3?bR;Z9#_nme%_FPj3c3r56LknNwC~7-wNj$z4m}%;-hImtHNWJT3NGtz8IzD zO`Uyhn7Eu0J^~dcC(bKbP!lF_qnccZK;SL*tM=EP=W zm54)nEW=|`V9oBc10a@IUPl@%5VQmldqY&jIcp1+)getgGtUjreZ9O%u+3YwS63~L zsmmj7MwxT1G&L$pjFalvx`#p_9y$HeLAY~tr*V}-lvxq@BJF*5wBV!UCZb(RZW z3AvO}2%{(6c36cg24j?x!!z!qp02SX-t(YFj=Wc`Ud-{~^=1rOce$muDTcDLU&+nhJm)8g4mteL)KtLRzYHvLhzF zoPn@TP??qm@64lkDqX9F$`X73Bp`P@TS}t{xoXleS7TmG;v##+ScI^|5^OwDA;?D! z8?P-OzU~Ec%c*fWUvXZXDm5t|mF|$Z%otcz_1%(;d#BgcyV+q+yR{KRsxXS+o>EAM z^S1%G1Jhuw3g*`oxl)uN#vuTpNvMCP(2<;)9!DPkSrC=0w=QFs=+vk9MLPp}&7sq@v5uSBzBTe*=kn!vh9L#wpSCfaYc9#-E9F(el5$ca$F6ssGUCTKiYE+F!?X&5y39| z^&mN9z*N6N)Y9&H{lMGF@+ki0tkIx6wO5NC@%=Rm)pW7y`rlX$<&xRHVXXqu}tK4=t;M$g%t z)tQP5kjDNEJNWqSu*mNP2z#j`!bdKGm-JoCMfVp8h!tBQ2Cu3MuS>rZi4v&+&KI0` zj9{9jA}Y%Gy^8^l9yJ*js1+j&&H>A$ZCmz;jKXZKpMevtDuLko1Tjy6D0PTR$cmUKP%wq6Q=2y#L$G$GJlZewpn#te>DiPY-SZqWhEZq&f9pOxy3 zpcf|L2{RWq4OkOyeXzu33)Jd(6 zL|me@Y-~;}p?jkcVRx#ny56dyVikf6e3q52^*Roz)Nm~h)NBT6#w%|YVw+K?y&1-P z0Qz>?W}$+1edf7qAE}991fd$a=h1U(UX6n;f8u44&RIJG68LtZF=WXH*mWl*byLFGf;P%CKYrI*e)X@Y6hv5=o4gYIJ=z* zVs%TodaxTtqcnqYww?~Sn|Ok4mwrn}a%ddhJ;%q>VqMX104m_^)E;l)fG^?z?y^C! zOT*8BW-(CbGE?O{4Y=5-hAP^c7O^9vnb$uddqNQ#zF1_uFd)vP%amsattdHkTGJdm zGnkSNIfR6a8XgFqn_MQ)Ctgg|D(S~q(H=TY#i9vWI^J9{QIWEJMH|b&W9zpu-<#2* z$v%SolllCAPxJJ&1dym4a1OTkg~R_(fAw@x^e*^Z+HdCIi(oDTb6wF0t9^Q+ZdN>c zh->9Z^;Iu23}nid(hNS7?NAT~LN?&byn2kjbcG?Yb((=mne-c#Ns^L$nFvwQUG$yE zhDh>*egVVm^GZD$%Wn>3^h-J{^p*$=K{_EUt09}-Z6rmxq`w5wf{+2eO ziR`+wqPc04lV)jAQw+r7>hTSTZ#@1o<|Wl`7and~1(~qcN{ku$fhL&=uBCG3pv^+g z8ZkvpDFZLH;bpOD;}e1j)LMKnI4Om$sQ&gLYCtAlCAkPZ*&0FwVfX!9zpFEL5iK&itz56)Qg0fGhAZ8HbxQ=eOZQE980L!b zu~(4nm8D;01u+N{KQ4x)XJhT!FY42O6)Hrj#dVeaZ|Uv_7uP)E;4X&!RITGEqT1^Y zCrZ+NZ9aADKib<~;dBB2)3vPH%678~@!mV%v{5ksp)BRClAmvT!0P!z=Sdq-CVV4h z-kSD+RN^c8(Msr{wnzJ_LsW(_A^qI2e=kXi(i>tLx#DroKaty2wxk(3tjFk$%7#%i z7Ym*7MYwSA6SQ2r=}ffSo3$#fu@!8Rw+Oyleu*2;ntyUfIo_*`d&efw$;T%p!kE|b3Q7yi)O;Uw#=Ps}GqWQ)coKs=G-MwwYp-px^TAEH}w9gG= zTV17#2~;-Reb%{$rgG?R?%zyk`ssDiM9XKoJcCaKYta!8aS|nW*T}#MNkec<%Q1mU2avXyD(w!EUY|)}M zp5GcS>^QMXl6+z+8gr!MSXx+Ky^T*c&f!I!IU)@}C57V+<=bPRIE=?Xrr5a$aBv!# zJ+rh5;Y29u-}K)|juwP{@C6^hktYZ#-fBjEIbqys{sY)}3xZ=c9N(!FRU|NFE$C+B z1|ViM*ItHYc4`@9T%PHc8PM0(brGvM1R*6Yn!?fIL~8bGRuDL{52Ki4!$3h5YOLlq zC9=2eSYrai?gHNGR`8exhQMIBb7h%Blvo##-rXNO0UGsR$mR3sGR%z)o7f568E&gK zOW^HeKy85f&m=DW?P>pNc<0qt=a{fvHh|NW;4O1PB4>9)kd}6?88(da8t8kr!SfU)$)6-i#% zwSjM#3&1LPQ;yFOqT#oi8cP%su(8#4Bn?sb0dp1GMaV%S1<7U zJ|^Fri59rD^8Z#$iQ?0Lri)N`b>uAgeZ`A6scEfdF;{rE-}{ON7b1b593wC)=62Cr z^Eqk+RmG!03S)e+4zLW=PkZj?zQ~m{%6<>)%&1+EeO?aA39>t$1RNTbYSFCYvb7+A z5+D>Aw90qxDqYH6vuSN-OLvh##Bywh^&KmMEhBT>CIR9`b)uBEP5ssqX%#6stOC{u z;f(C^x`rsNwcy9m_gi_xax0pZty$HSkf`#c@O2AS;L(P2Gb`F&Eq^UUtaw$X(q+z9 zFfK8y;iGaP03+$b8o>s?WWnNQ_HTBiG4DN=Uz)f&=#{+)CK$&{rhLy{`i6p0D^dmq z26_O-jQam$@6F?q+M>VVd%HGTSy|a&S~tsz)MjU~(QMF0%@ND1=16Laia=g(dCSzw z%uLbB%uEp{#0jx1&5_Jm6f{#3M4SKx(f4@ouY0cwW{=PF`8@CY@*f}0Is5Fr)^~l^ z+H0@9k2jx8jdp=D27rDlhn|$Fwy3)n*IZ7DrKFZ~b|9vGu*jD-3&{ zJuG}&oT~Wv$zcnU+wm3$$kM}sbVo~mpF*Nbkg-kB#rn*q+J=Fm)2G-8spnsYG<|}y zBitMN^@-|o@jgWkcb_=EH$@nO3-due^u5lBF+1FMB9`#YYV3H)?zOaCMT2JrwZjjG zYnsn3wZ@FneX$5GwcYg=0N0L7z)WJDcQdkk9ocvFduxk~R1h&oV za+_YtB0GaLWuZfI`jF`Wh*tsP5KcwL#FIE`GS{el z&nX4vHX$h^^piZD)TZ!mZ2~d@?ZtD$ek2)e#ijK`1O+lj*j2-H=gZltjRwxAjZCvM zYKu+4U}x9MrbelG&74XDo^P^C5{?QY4FAS(fD)}WYAyfvA1;Tj9zVV>aaZB$OWCc^ z7rCx($8d>mmV5MY32v5`!akf8+-1CQ2GX+T@knDxZf&B5{dw!9As5LfK9#WgjGPls z@lQBJ)Z5WJ&eP7RB8q${Y8UaPbTCmyJ)TGhv3GQK*Jt5~F_+H6z%hdsx4jdAMnM9{QiVAUg91BFoUY=ySzA{ zF|%m>qk*DCwe!$5jl2Y}k34gMwOWVJ91kbFXXWzA`207) zzjHM}p$$cAg)U$(+jwoK#I4(_SM~1liw(Y*ZMLV#h4xy2EcK_`fvw{Vg2KPN;&t1e z@px?^pdmTto7QWS|oZfS7g%3~-gU@8P1<1Qt$AxIwts2NmLPGILNcvhz#Zx+^XUzcJ7_#4m z-hIHc(m1l4#ZJhn9dkh#x3ut1p)V6!cqhSyIrwUpiwBFA-8Uj#c5rRCon?EU)Rpd> zV;6fAgI&@5T2I+xOCrlIsxTFn>r&_gub@38$-ispvTh)qMKcbPyF!FaK>m*0t~E<2 zaOCiyt(Fs|+pD{95a(g60&z@l((-s27VmJhSs${3`}Vp`bAB}IK*1+^2dBNs7J~aa zn2>+2$1{l1+Z0sm`6?t6;aNo~t(GAtq|@N2bR>z>Ua!mv`yFfEUa5E@h{p{7F%H| zil9#o*|XFN$D${a|c9&%vw;|KLVw zL)ae_r{Nc4>o(i)$`^%%)kNx`+GLQI`!n$b=Y9^JNZ2xDdsjg^-f~N({8sz-u*cRr z>HJ;AI$!gpa)?K_>J1MG_GQIb%Xc`s)mUrl*E1C=*srLt&!X3Y7Xvx{rTe?3MPquI z+S@t$pH5tXKDZXz5cvlg%ufe9>gVcz!3^m4SI`MS!jaPUIw&DjX<-h~<0EZJHT)vg zeAfrH-s$I{E8yu4P^4Yb-H6ocx&V>N{T7X9?FDk8u+EpOCQU=HJ)Hx>;Bk=)=MN|0 zSZ(!{n+wxHj)az=mc%7bnl&h`N2uuJJh*qxCsy!4XszefsxIwz6DAYSw{XZ!4CiYV z*(rh?5qSc`Yq^f_e}W*XDBTCHp}$40x*poVmqGQ(DEZ-o#{jd58X1lm^EP{Gvj`JFNL_yZFV z{tcJo6H)w40DtQNw&UK5W}s|slPaittE+19jz(^nv88?D5Kt_isFbY=;?}(;Bp5T# z6OHJn`(1cG)sd8%2k_93kw>TsQt<{WZiFuDJ}i0`^gnNFMgx7x9jJaXO`i+2WsW~^ ze&8JHWp+D9fAI94o)F|4x8h6eLIE!*d>K|nY`O%Z0yJg^I5@0r;w{BMjv9~60arKst`UI0yZai4fmRuFqY|5vCEJ6F(qbQ-DreM$BSfStp!wY#SowjW&O zo`S{g94@8hPa)dp;%5B06tJIaUfUAP=R|CNQz@`V=_+bT?XOc54%l+RCdryH7n3o~&P`JBa1s5v z7I|U92g|$2H>LKCDO<^qy z9kv>B4j?&X{i$~oFSmY>%;UGPTz2blo82+KG)=1a7wgp66m-s$|Pb=o$r;7kQ93-T5PBQ17*aC)S{g}lS7EpC;wvsx^ z!J7^HN%^+w9J9GPQ5S#r&>*bqV8ZTPuq?|E5EQ|%_trGr zGflMd&m}dJae($p z&Fly4%pD}}^Yxh#PdIy6&KVC56Z^-jx%YjH zDd?RD)``3@fq#WxQaoI6hoIQ55jn}bsjZk3Zy4j^n%BO8b+to&SjFC)dN!)QVRML<+u-lg%O^bcy|?-uUIB2-rZ@CQ(~$E_ zE)|^7y}~+EsPjW_pL#RUpL-4P<0(0_w7`wKR^DsStVuBxj*S^ZtM%Ua%xy)I%S7Xt zi9{yeGlR*>KlCxp4>biK5DSnyup(qW*T!%O%=1>x}O%*$_Q0Ze*K=>7k5 z&r*E=0%9nM(#-!ap(KWnn2Eka!H4}~){agk>a6fNBvg;Ta~8?hn;47CxH!`7PBR_; zqzJAnWg$nhjgY)PBiZ5cgN(I#?^iQqqRn%_yP=4LAbv>*0v{%i>Z!)$oiEzF7t4>e zzaYvgg>3Ew*uNRY>?~ z9qt>_pd2{&>J|#db2QGfjEi2hQ@ha=`D`!MUZv@KbLI)ncb^Bs9{wNaf`oQyI{uy* z_7t>?M=mad8IwJ6@U4QA5C>P^{=G5K4$10Qa{L+@G6fJnT`%(`TZhxa;kQ@E{VpF< z7o#j2wbgc{1GPorow#l_9SGK8fp^-;8V-;eE9Oo|YG2jF8;}=?j`z zhKN2%Owz8V5Dq(tBgmGjWU;ahjekSj{H%iL2iA&U;7{#C1bf-^s@0WT5aL6zPlb%- z&{e*mQHA3@TKB>F+yHveCsc(SQKuGK%p2<13xLK96%*k%s0LPFJIvkYD}25sTwn%C zzzo;0J5JSgc5nbb%?qFbp5VN5Qai0@B=WT^?r{Q1+Vwoh>o6F20Ncb;5zw!{Z_bq! z+$7bXAR?j+Nk%`7o?;AJSBJr4;K|qw{>b$XGRfRGAB}R$oCB5ma+Aa@0QbMAP~A@w zC^Vf0KED}zy11*Q;`vzrzF?98jX$(A_~-!Bk*U+)N1@8RCfetk6vv`vUV?giWN8DK z&i6F_ouU|I8Xw8Y#igZ&`RF}FPK-7uAZ(u%YvChOt`>%{D5XyKc{V)h{vD& z3Rih`ZzeX)yY%|9+!!vCTUElUz3;yr+{DMsg({vz;n@5SUs8>bUz)p5@d<-h!8%=% zf}Xo=vGUO3=;oz)0v&DwrNPs81o;S23e%5&LWf%=Bmw)8fcTzQ{C;#lMU?+(DhoC~ zA%fK%n>^22s^5B_=#zW0iej=cq=oYUpBv&HFK8L{mACh6R<1@D;rU7E$=3UyhNt-E zD03jG5#8(v?VP0!xn}?l;w~efnbb}})#?VHF7C^pb$krxAlh=xs$E?yT)h~%D%~2R zEW$o#t{09$WVsII7JdB@S>Gry0D9iD&-D-CkeY7L6GUI&H?Fh-eUIal{DLgPPX)h> zI64wc zCsJ-wL%Wt;qJx@80}T;z8%7%JbQ(%k40$K;F}xZ*cn8wwWA8Ojd45eSrX7n)DejBt z+7*JJ2RgGPaaOFWLm@i-EuLSjt35q-yYkVcrKg{&5cqM1oUm&|eqa6` zR=iBoSNPS-Ums6+?r+%n!MFC-Vv)EYHi-CnO!YeHa*YZN9xfH8*lj}hW&v_<|w4IlQ1!nx%4go6TIbwU2i8d z(Twfu?>Bm-NFY1kJPB@`V0+`&@qx|tx6vmTa9}i1SlLQ-IH+Y@bUkbvE^o5|BOKH*Y7sF7lzTT+Oxhq)?iHVX^&fMxgb zgDjkNF4lda0L2BFEl?DnjL8E|nFj$2si@S~+eGjau%Za0%d{0$H%@%{6j%Bk#TDp} zr}p*p=$)q~3ZUnH0hc%?IB*VA!v_vFqQ>4|A~cikr`!u9y`M5`N(u1>Xa}NUj82fK z<=bZW@wEzfw_koFmJDt`*GB zG@I)P;hQE71;g@U!?18PZncENDLyeCP|)2LP6C~*l;1d+&*cFOxFO`mQDL>% z1-F;K8f!@d7Vf0?x=IU=uKhM|8eau-T`O^LqIC-s-E^?%eJXie7=O=LFW(xMT?nLm z^*--e@cSeveY@d1eD&?A)`LKyE&nOx@_^{FoEbF*EW)gShrF{{Ch@~#nb3ZLzjE(h zDV{{dtt1Ko_jK4lf_Y zC4?7S_(T&L<`IzIxUlmT-hLU@WF123dqz0fz~a`;C5(5L_4dR*rzE_bA@dLCVi_vL zj5!h)Z-966jes>9W9pRaU44*xyL0o)m^IJ)JToGroCAuI$vuHRWy9PzZ~4&Tf`Q_e zv(9a7GK7C~pn>HPGxs{fBQL{;fQ}$Y*|Lvm#ttdAb3eS|RmQ;hS{ykUjq-W25E7vX zy+6;!t_p6S`w0^q={P{OCbJ!(D@ol*7OUztET3`_>q)}06zXgHlR-rC{ykW=fezK(2@Thi^nFy;m4B`Ox8f6TJN8&4 z;CTsQ5A5U&*}BC{)w*~P+dw(Z~^9I%vDX?XGY`E6auds?nqnGT2THE&~bM!F`^ zmP9SZdG;4|&)r2Jz69lgalV&W?~ylI9PgwErTnFMo(tG05n~_n+$YKhl$lv;}o$Jw6sdZy>sPW`~h7SnY$g#twNt2}YNgd$TTH-m^WR zL@_zDB*=Jii&rLgu}_@QAz76+jV&goOaUZspM^c=Q#JDx=BGR_o6DvY>1EiZ zy?hXG^4c@W>M+fimapv>1*Wbzb6ZKIfu^Y`p_%hivdv{ zYU^B>hoC4AYmC4$!obd&cjy%Z?2?~W*TSu1xt^8}DQWCt=Hd%5Od~9~>WNb{xVp3t zaiE9wG`iSyn3n?V2^(!>Rh1SRJG^fJ35KI;&9bUl#V4z2!*83|M()GiBV1BeNZ33uS%6r7lTOUmQU~BSOl2mw2Y?G2C^(XxCA*ay<=2|Y~HIwCWQQ=mP;BgH@atu z?EGn7OXK@!Ryg{!?52rxQsLmZ);(V5)2$qFLqs4yQxFBmj;CGPFG^23Z^-M6MCJkV zsRLUP+be22j!H8?S6w)BH!6avZ?45>hNn3#fm&c)&q9iahQcaV`;JAQdbG90rs__y zrkyG1Fb8K~3^P)@w>f>4u`z!U`XosEvt(%g=Ps|Cb&XHWjLAK5plW_w1R?qBiA17% zM>8_E+~`nr@&&E+c35=dopb`QA?aqSF$#vrC&e4-V8Wc>*9$9E$srX9)J;mS)Yo70 z_Rf*$iPPzMyDG{~sgvbYF4s*lY$1VQ3yG-|7QO_Bluu6PhNY@hNLll*T8yP9G8@=& z$^`Fc#_H}kFw7D6t~bdBY}prLyfNltBy(`RW8aC!NK7XoCptaFR!Z52{zscX`pt$v#f-pV?6e?G%_^qGN8C$;NXyU zPq@I+WmTqpqE2PE6veWFH8g^xRWqE&8ksIIt!}v`QglID@h$_Qvxv#2pQQqD1wo~I zp73~V#vz89{W#~?8#nt-giXQym6z<#Duu}WWNzwG%x^^dL0vej)D&rOZ~Dlq%Emxu z0lO>_BMSpZ40_TGVjO6speN9=ZcwOY9x{7_=?2*KIJ_3Z!Bq;=77Tn>w+w`M0is1a zYmVD}lw7ov7MV{t2U=f$C^)pjk{GOlj|u3-Rq=c|=3EVUUjzqkUwoWEsU4_Z1;ZK# zS?VBC<-vrj@2e{+>e|CfPJrrP4+p!tunJ21Z5>mP^y?rJ=?Ua2ydKyck`|(&sU8t! z(E|p~!74ppJ!~9gs?O~XUVp{3eI$b70xxiAD%-#<#KhYX4@5iX(vnZLqmz9#G$ER1 zkkRwPJYMFqdK(x4LOCiqm1iBfmApclt0 z8!J0yQppg3j!E>OkKyT<#I9=OK#sZ7MH!v?+OcC;?kQqkXd?NS?i{@J`!0KCTs$0Q zXUL5{@bbpqq6kz7%EP<19_Ay5f(9boN~_fIUzlKV>;?; zk%DCNuQE@G+Ry{h`Bdd7GpM#ji>Y(R^Ws;x$d_0HYUiaB_*Sy5<;)w&hv%N@K*kim zCbHZTYMYTs2jZ3ZeI}}~5w2}rAx4uQO|o^w3+!N{2pkRGS63x7YC428X?VL(_*`UC z++3_T?qg`Cw;#@wScFdnTGx!{pVvUNCY1#Gg@RIQU*>1;UX^tX!)$)6bg+p8@u6SW zMEW4SujdQ$hHH(ln`f9BeUYrM?4-}2RFArR=P1ze87ocJumAq2J;>~p~ zWobWf{)0U_8tbiWYU4v7D1oE%3ppaOLdq5C*feKA4|o&}?Y}`e1|t z1wMhgWbVbK4FvOjtO;na$4jhkUf$KY^rHe6cjz3kG92rixjMe`dVJ&Wb=CZ@pKnsy zoVHL#2RdP3Hx~le9pTfWY)D6T3z)vi@iee&0y~3uifDPV+B3aJrpGB`uQ7>RQ0GZ0 zAW+j0BZ=!BncUL1l4;kT3eaj#8Qy0=`&cSpYv}ctbF5fjKJT@DI?BH-DbT<|m~3Mi zg7M2=ut}$5sFgZ!q#>8=oz_0wf-1mYbf=Qqo!LI?!x-AW0l@i_o0)K(^sswyDb1cl zLB34!&qJpt6VN0${N z7WtK>dlKH#JMw>Tr+0fXPm!?fFjW#dyUD=mRQLsp1P8sB&DJ`&PxKdh`E`lZyU6Sc zE1R6RUDy3cCBJ!&8YniX9Km?`y11o!WOyAdw->Mn5CvT;l45TLz~;Gkb$NEXVQRAT znvpT+~q zHrw+{c`b1C?uMaHm=>JT%lusg6zJ}Tj#5+2eHN{r#a$(()y#(X=>iR4C+LX;O-*1q zc}GgRg_F0r>uSRgNB-a-G9o#{#}jAj;$obg4ZDot=I+yM;u^_l*RLmKKA|}@GjFBK zd6FA*GAITyF*=5!1Zb<#SeL1~hkdp{Cxw>USp{*&u*~vTTawHiTKMuF8q{&Td3$zdMDf3GEdu~o7UW>xLPw z^Epc8mHQu3Dwf$Pxmr~+kI>z)j)ow1{_mX;CAb5O_32?&{6)d(VLrx1G?|Ug7S4*w z7F~XS9fHjL>Y3S?Qxoo>jYz(@3ux??Ep43X3{92Qp!43TrC5G0HWQzZ8wY@ zhiXACR7e@~OJhlA%BQ!2^y;u%GDca|(tGREF#)x9JsGjXOruOiE#lj^u`L36T-TkX z>M)z|)phbQ4Nmh9*i}HCvzy~{@uOd}DOo=GQu~xvD`&wwt|!7A226p29hLBDo$hU> zkY8b(OBw0@Sj=WZ0#$E5S8Hieb8!!c-Q29lEKEFC-`4%!ET$N}*(KvJ zBfc`DpFW-j&}gruw{MP&WPS+S0E&?RR&~a>faRGHXcI9bJKl=y-l_?Pxx#f(@1Z+={edQAxGl%kF2_YS4KRqPYnBA zh0EDrS$e&z24olQ9B{x0?hC43B+0@ymcFU(Q_*fQtvOK;+T~#qqmgV$^k}x{!XUt* zI6BEu7S0`e;fwd?hA6Xn^(x%7C(OZ|^ksN{1VxXObXTM4DzV-WgLfPDA#OH`_j5|( z@&`v6yATH)DIl%XCcZX-!U~DE8)$G4SeSyTrRmkHp2W8pJgVa%_E_x7sqKPPdm6GC z>Xwb!$#xhuLMC@fbB;wu+TcO$5H8(k>C+xJSS*g1!=gQh3>^i@va-{L26Y~v8q+Cv ziS63Cl&(>J#$~`e3P*Og^Fbj$n1U^JK>WcV4~zV{~{2WNYTUgPpY=Q zc2~lvE*W=KV@j(u z)M{b;6InC^?jr=@-G;DCshUNx)vJ!!DJBm-iZ^679(FtjT2Q|zVy+9b$JG*it+T@zT^VN*>c3vGjtBOY4Czry@&ZJaEH7z6uLx_1wRk>faF_!rh zRGr6K3kon*elA0?B(OK2pw1k|o`{{S#E`gJqy^S6+JOzDgy7B%m}-Kf*-rNc?3#Kw z?rNHQTM`(=S22`0z-X9 zWe97ezG^)D#MB9?O)ed<mm=WNgFk`U%Cg zv_8BlYSG-~c7DI>ziPT<@afj;L-ajk`o`TRY^*~r=+Ggh1?#qaT>a|a#qG~`ew}x7 zo$ULqeZXOxOa0Fve;V$IQXjbFVEZA+4mkDV0It7ZkWJA;vwEJo2(zU%7~R1bYq<(o z*8`&Jz9y8ulEEb70usoro8}HKlV9Obf^tHki1~fMH+0xOcw+7s^}OJT(w&fPp2?+x zZF6PIG)o(lW)vh&?b^40Qk;H%Pq7Jv%g@f20Nq&$*ISz#H*rQglaWlg=aJIWhFm9C z)-3b>YvOKPVQsU<@0;bQ(tuHgEA=2mGT+SFk6n4DdxK5)qsgm+!hj{*RsZ##OPRo^ z(%us$FG5W7h_Fjm59felo0~pO8kFvNzuMYb-iSaT@Ubv6bL8nr2`worC|o2fXzu?? zdo0CAjLM3TfY-`72Hl92ccN#xHl^G8^LRr)-3yt7EI*b?@0U=+Iw)^sfW)Z1O`uXg z!i1U8$75D77+%KZGfG_v+7$DR{hbu^La^_K%2i5gEw#<=3vTywWnaPks51{G%HJ z$d$RAnmAFex<-D$SuQ!i4kdySmZZaXs=LUXv^VZAp%oNJczSx$--W9{#>9+@|3W?Cry*nl_+y$yVmwziFm;I{Y>y!t-( zKH4pG$L)3riZ>0NQ_SIb5)8J6u7sP2Sf#u*uEEP4Hm0+5bbgD}QejWutetdT@Zy73 z*4DAX>M;OnO9+RLSKR$~p#R9pZK15d9I&x4MZ@TF+*9X&E=>4gbq0{{h70Di-AK6R z^$lrwz>}!#iC8GOAz^^lxEPNjwbBKF$R+2dX;CqLg3>*(mnrVF34XdSl# zJl^Pi;5*JfEo5?HJsOSnX`xV(jTPBO^N7Mxpi3Hur20=-p}Zr)aD_CrCIA>t@%?nA ziNn!d;1?7Wq*1(=q;(!!kA-0CL%^e1mLUc;YHDh)#=1q0#KQwOdY{c^`)DIaya<;0 zzS)+Fq51^gO%Yu>vh3Ow=pQRZ8L$v_PtfW&*L=?spro$NnHwjX^`DBn&`1Gw9US;p zS^E;ZUw;gxK@w37p(H@m1oOhG}A#7g-3H$FQj0^pkprqRyC zOMb~Wu0V|owP)MRF+j*cR@#%wSth<~2Jg@{)=kAHwoNR4oig^RLY?%F?q)#9$5Q0} zJ_P;8pZ|vWr=X_|F51TN+}}Jg{Ws&M|AFdN1whDR+WAK9lNdluJJTS_PfR-^U^C8nV%nL` z|A=X4lGFU=^!`HB|3$R(o90hnzMTay-ZydNGeJ`mqZ@JL^DVB}Y0}!;d#waIs4*pC z_sa)@XZ{23q_YqwdESYFEij%_-IY;Jb6-8xY&I_ga(D+n7){DSOug~ne?BkVX+S4< zFpRQY+lyM-R{FBeWlgCodjaGIPp?gko7j_SwEvUehdF_BSa04O9R3mAnTy+RJ7QJ-t%mTUu>q72dQUDwI)eF6cHdK9AVRJK>&A#WA|^@uEnR?9oju|N^i<=HUXIe!6t|N@1K|W4Jykv_AZcE-9b^wAA0WO60IDL^hogSFF}=s zfsE-1gurSzV&d+l@jib6rl%EQ@gmYMlY2G(DnGx4<+h-XI*gz{&>gHoBgLr1Abn!Z zb3HN9ow?gah3qi-usP*{-Kxmx{Mf&P_#3~s6jQdbDs9s>hU)6F({gf5El~m$8)s*X zle2T!ds=A8Z(e~BlL}FR_FFXp6i_$yt^XIJ--VrD$AX=UasdT3=Of~~nJqh^z*nXF zNBLtr=0lJsqoX0*vTS#nLn>@{kQ>WwPv7dv%GW&!%+ns_ME}S_MOH{bTiaz56O-+z zk;0hLF;7?-fOl_tLd>IZOP)ugn#b!$-m83AzkJ<1`E@{I^5rj)^;thM#5a=Vw1J$$ z>lz?v{;*NRDH>#zuU*GrS9QmilAyHo0akygV)QmxPxIQ5%0s;oXx>E47P37$uu$8|jQ(iyud+UI#U9@s}-A2Xk`y znQn_k>ESRECH zPl0UD{0%W}Gf(&UJ(HA`lY7*4-PG_ag4Y!vkRLoe_356?y9gvZogdkOx$NrBlx=L~ z{MCwsm9&AhZ9L^#^J_hm?DY|!s?)#haQjzW4JFlCnYL}e( z1A-PtISaNvZCJl^S^JN`Sx7ry0B2eek%$p;=|@`r9Y_PtlYFN()$D%gA9cWL#IO;n z3o&ejisdiwE{2VmZKehp-~C4n8!>FY3zDh+OAH$^Y{ann%PzzrvFIRK91@G16NzCX zhRx(Glt`cQZ~j>f8!>Feu=zWOF3#JCM1nZoCptP6!$u4nVT*7gLp3qmi1xXEB_zdc zBW9baIim0WBZiF_Hs1xw)H#tDHe%R_Ve_|Lh*!WxB0*d@@o&~>a=0sojTkml9qV`h z5yM6do9}{TYH%Wk&Hrm)Q*a{1`>wl`A2A=nmWvs3o{%Y86I&oXDlb@Ljh}Sj=-(>e zyt0>j>)4u{u&EWB3zi*M0=CE3^qJ1`1e1+-ZVVuvE4YTJBl(dhxkK-u6H3zy9?wm- zBxrQ9nL^H00m`ha77XzZ$KGywE=(bJj{pU^n-?}c5q9xA8Ib>4g#g(6$YHRUvutKF zP^-H^|6|<`Y#k6*9rks6-z)?Lo#ochHMfCNM2`QSx%E3)vhT=Amk3m|3V3kM*)>ye z9N4Czw<2S|FsMx>Ad&y@#<$JZQ^~Vz=Gd=K8#Et0#Rxl-|G&ui4kA8cf#O=?C`BlC zXD+Z^D}Ykp`x4HlCm63t83+T-_|1Mupb(YM=6cSunfnX2ae@`DI?i%W@!daBFFIHjCb_2&K*mS`0sRB&74ilv1;8A{lp`Er|No(!UKFQi z^?_tZv!8mijg_vh->$HK&HnPaXa8Ik{%&K+vHOz0rc2J5vvcmHO<|{g4L!ce@aIR1 z7cVZ|>3`&y^3LPOoo^o5WQ$nW`ur8<^>bJ#fz(j)+twb(cuO5i`Mzj%Fr3N89DMX> z^~@>c8&r?~`ZQHl|5@BDiESAOXr>M#;?pU@>}&Fb^)EtFn6nNZy3%yE{y7zB##(T6 zmJU%Y8euy63u0o?h(#mjn!h+y%rzn>1pk{wgZo3)?!RXNd?(ia=HY}mAF;O*8PtkJ zBNmPDU|onE{bOQc)QC|dM$Nbc#F4Q$G8RY1;>cK}KM;#XESev8m15M0Q6ompHwpNO z^Ta|HzW&O?h(#kZEhH9=STrJYm15C|Me~Xqm5E zzI^!`))#**dua4vuD;}ESK&d-ke^*TdCGSmX4a*DMr4(7qli+aoIJ}4 z|7DL~0qxv&YZB32QAy1y^jC28=O99?h52khs`K~x5Zb8x?!g6-(CH&L9^-o#o5YPdKJ*lS%b)_p9q<$i2nxK8l~Q< zuVpi`uaS#>nq-x-#6)))J(oUum%vR>iV3>U4N;~vD$7HXE5q0{jHL;5r@Z!A9WCB7 zNZote#3Vx7dEbJ-)6Y@^IaV_Ia2naiWym*xRc_OJ>cv9Eb07V(*6p|?6kUEle+mJO&cb4!-lrr5~drf zGu|gyItC8D-#=PvARsIWP;Ww&!#g_gV~f$;uYzLg!}ubafU{L+!hXJg?aa?*;o}A} z#z$Rgrb-kpVqLwtr@EO}+hiwwUsuT8YVbM5p*|?(05aWTJEQLiS+9dHC8$lyPx{3> z(lrz=FNjCiz|SatF@PkpR4e*|p$AMUSgwo=HVmN$W_KD9+?{i@>SUdkaO|Z%}b1Q?dOJHkEQvQ7+S`Jy~8DRPwa zz-e5Ik@+5Dih+?GyxSxq-_w2HZdgJzDjvdBue9B@Da&A`<@&wZ_z1B5r`|JG5D|OX zbbkdLi1aG6*RwQM*Ew4`MU8={{$YPnKce>fC7zdYJT^bqWCT=sP=%bj~sO+`?jpvrZFrh=_Qk_LEn+<}CT0%5_{iqtG7#fto4u3{*X+ zv3>+5(!&@vmQg@4^1g15H)v>C8(pK>aFydSoRR*?AO~@dk)git9JjZzomZqPRhH9G zvoL$FnTJIdTuT#{;$gvHU5S&6HQ{9%j1uxq6a~@yzT)lMos?>+%+ku<7nFk;>&AKv zmeiOfx~?Xx`Nt=Tl2w5hAk1QN)+|4Rp=)&okfy=iPsc>P=pO^n_4MlyXe@-KqNB*D z;iH?fQ5{Am^QFC2T`at5e7K8$NzQza6|A6_20X&RppEw+#aHtR%sR!IKt!EUe4}i+ zUOSCjh3o1cO^oN3nNodJawJjbtXPfyyf38&CdC!i8=O?(c!*A&cb0!5w63tf!^;Ya zPSxChQBjaQ7#+rkGv85MU6obp^ob1k-i~1mK_eB`{gm2Y!vMoQ#^#^a^!75p@n(Q2 z@p<&julobv95xcgpH>fV+$O|cF#nNH-v}|#jk_)bYEWG4pegD_|6p@tYC(U{17B#i zK}`!X+cY1`VZ5m0G1+m(hGpzF{rry44Dh%J`5weK?4TBzj&=fkz=lv=bDN;&4xcaW zPh-4j^-N|l;^`7p$7*aTTqS>f-tGqP6w96Rokk3AzTSMfW@x=XrvDkNu$-#8Y#>|( zzYFE6o+RxquS$KmM6S+{fCblAW!D?KJYtYIKs$}8(jJUJNf_fx3#9_rPhlewtas-t z>lF=rle>9-;M|iPou{zL?a}6q3B+`1#YG|H0uK>G{df=%h32JwdRzaE8UGpm5B&HV z4XCCiF+y4d5C4aK?JS=fyd!wn4F1-v2hNc8MZF5Wt{S|Rx^yd}P9i>@T#_AFxUjw? zcYt}E5_Ir!hoHapAkkoOLo>9K!R<2k_{?hXBb;vGb_qZ>F=qaVfI|Lga6ykD7)K2` z#>{sgd!Z6Qk_*@KguxgZE}xjCmf0xS$OpdB|k!N$HSvjwtiY*=cnJ8lFh&{;t{mV}C+_pqKAT#qW)CJ0n6V|Ei+3 zdr?hQHd%#LyLprpph!_>$v>p6rV+O}YI@=AGv|kT#5`hfvCTUey{*mT4xC*(R; zQRFsE+2`>qt1VIE8Jq44AEUo_8?%B9BAI26#^MXQ*GYG^SZu zhUiT1Zmzhgu^#4_U_iHMOpty;cBV8v1%5LyVUC8YRm*a&z1`N__+CRDA2FP%MXZ(M zVuBdOjSL$LdzVM-MoaXNrsuBSw$T1&W{&ef3cB1(bs$`*3;+=h-2*Tq|H(B()D1I? zObh-1CQImLFTVfbG{5pW9xr=(0s#hMQ#{{frSI0-ghzL4f-O>!6cxs?YD=ghBj4w& zV%Aba`i2G25f-VVo!*Q~%XIgS?C5N9FR!RAA-JDLFU#A%rdzY&1CJ|Vo5#R>EW_=x3_yevz_W2ELJ8i4{;c+tFe@zUgY4WEYj zqCjKy2O!SPXUu2$aiopA?8n(r$pI|tMgP#kMod8w2DG2c47aghav2&s-OecDI4&8R zud@IU8mr{*FwAe*pqhwpxteXj)4r4>ZB4^7-cdV^5KwFGQSV+#v$=_iTn)`ot^uB^ z1;(3_S|HBt1bmIV4goUYT$sx50qrB07K(H$|B%j%ND%2gp0VTumR2R>hYQ zBDm7q>uL3l`H}udZo!%`%WZwyf5oYkW5cCLssYEOVg^S)!j)*f+kHiC_Ov@!@Q$+A zWOcwSg{=miGsf!xKFG#8eGXgyfLtt(GOt68nUSD=y_3E+7AoR~Q+do1T6+$!%TVZaW+}kNIf$zd7HnosTML`OPJbL25T$S~c zpa07W6_yXRhk#GKluRLmMcXUKedzY|z%S1at z1KB2WSHHTJi2img-6z*p7VBXxu?W9Zt= zoj1l6bf=RvBK`e^`_%u#`O?-w31y3%3%_rWm3_!AQz7n5T(~se_?P=aWBy(GepDnM zN5&_I=N1&t&;$SX+5g&r8WqU$MzeUO6AwSEOeml4D2Ei|YL%Os%E`fKNbA57i?i}QT4CIR zN6RQ1VmB^3a&YB^GkIe+bETIr4!@;ud8uvGZ|M%yPNAYb_w!|Fsr{@=D^@S#xX2h! z?^3=Gu7n#YsvY}gU3Vh60FDm?2_5b?I{X*UqW4X=VmX=aYNZbk%e zi0fuVOanKH>t;mphPZC#ANM-xhnQx>G$SHMAf_2nsYo%+h{_R6VwZm=KVq5@(~OvA z=7_6+MVLW>c(Z{BXCvNhAj;c{HyeoZwqlwQ)65TgTQSXuY34_R`v2Q#=Jl3(m!E#x zS*m~J;05viCSlG&ytpk2FVE><_8NXuo2og0K&tf7G{ij7)i-=%; z3hfjeY-Km2lffLhR;^hcu(oWQ#2;%!e(yAFgvs?i}g=JY2D}a7#?|w)=aOQ0ppty1To}?K%^d&x6dm z)0S!{Y8buqKtR4XO#bWKAiuP_xHa>GrfjeH%iEMYcDv8nEtl!>*VX^Rx7Cd z#*o>b=_C8c4S&M?XRoAYD`^BUFy=2`c29xwk4fIof7!JZ?#7kugWs3Iw7Pp50t^gs zLu;0wDcN{!*_@>uxj&xkh#<2W4{vb!wG_P6z2Zs8n(_1B5VQ1$Loz= zTmJPi_0RxFFDTd2O!8xxg;ajeozKe`5||~&FO51WQB@y2mx5;8zt$2Ri16~F+7IS& z;xF{=GA_oxt}6P@N6jq#ZoH!y-{_W}El3qOO}|XnM*fNqC7G}jY2Bwl+1KNBj&~g5 z@oQrq{IvddtPHDYpvV8gA7-lMGO-EWU*5HJRzHKGqFx_+EsKs^pM+X>`!#5DU*6IS z8~A4(sw{`q!aP3HPx*rT{oNHItKzArRi!td#S6lSad&FN9+R#K{H}7-P_QlR%5Jo; z`NjJRWOPoHPBvNn!5#8Ng_R_9$l5%}gP;N3GHy>4`s9A;z@X7}w?EWkF5wfo?(;pC zFU*u#FEHM+efY%PSQnkOp9gG+`=TKPc45tR9TL&tYR_nD&*#Lz`%xKMW)B{faj%#p z?ist;)=#jE*34+AmvnqstGo|6mPv~F5LE0o!`Fx#$p^YRP@E2HpV&tA`8+I{!8DmHFS^~dbv^DKD# z=!vO#&i;n}mavkTm)v6mWJX+g8!JBXLAlB6#2qUj#sg}vEpO*K-d~xMwPIlmE8P2` zM18ZNhmN9DxYWK-os)qR(+F~w-%Oh%7GICw$Zx3CU|K9kO97flp)dHHHNs2so&;w3bLpM4$6Xe zqb6$Mp}+HoSx=x{iYTs+T6rh3l(<*M<*1vRJ~E#iblcO7&*?(*nLYk%pz(KJG)o5F z??x!G5}y?zleu=+%`R$lYI%e)eWjd}yQ3=`F6E`J=Esj{?vF&lS`uhz;}OZsd!eC; zQD?Mcq+g%>%sFH^w&&EA>D(7It$>r=f=*x4;LQ+z`0#YxG6}qXh0E4x-8EoO_qBpn zk5$`Bp2J8-ez%K<{BEc6=Yv+$2M1_wdu*{Belkh_*_LO6K6mj3zikMVs2(Ptb%7E0 zuD!0Tm{8gITLsgzBJub#%eB#`rIJsNYz>pK-F%kaWNvUA1L2$Hm|EPva}xxZ{Y{>C z_MZwAQr%|(Z0qw;TZ7{+L_WaG*A!NqB(W_*maVC1-m-nr!N61r;v61`Yeuc2Vx>b8 zkK4MCj?Qtkw>K{^I6{?AKSc+C!`QD`N_Y8s{l@|DfXem5CY9N2yYe zj3RY9a>J`7$qV0Ca3TFjg(50^Xg8I#+IsBnsUvQ#=rh`!*nKxV!vvm76zgoXuyz*_ zD!4Urw{Hy5tjWG;v|6=1S%`z{q$a&y9o-6bQhuF5_5eAj{tf3L{bX%q;wdmPe{}Z-OEs@-tj;sAoA=hb$$09Uj^^{7-_xD zF}U52wV|8!2bc>Ql8oe%X-1mT2Vlf??OjoUe~_M4-_L6@x!d1KIDV`JJrYSRyZx5g z>H9>!^!D@GAj9g=4m!8$dBk9oFSfZ}$GZiH?+iPkdj2;X*FdQ+>OWDJtJJd)QOB}U z9!Oimx8!ubYOB1o0Rew!=Xs_u5Ml8koP5zBCmQgAyU?Lg)w{PR8Df9<_LGUkM-nOuCFJj(Mt5io2q3nT``FqyqbQ~+*Gm&dO(!O^X zhwJCLSAxcRO3kJhVtPScr_mEjbv!vL@g3#mpYZ8KJ{=0a8F|3QT@4OL_dvJLf33DK zFLf=%amn!>Z3&pgG$*gh?)R&{uQiMellFmDyj)&Mt<*;c^(j;Dcp4`*CmWuz)u$6o zj{e#`Ql2h-?d0#h$5qp;PwIAl^f&x;eDyJ8RH@^ZwoHX8%AbD7$Ds%D(#ZAFUdwLd zs!xJXNp&(_kdE)PcpZ9ze=4bp$#FI~B=}1Ee@eU7peD~OTw7MLqoBB6xCsgx3RJ4N zgftQuja-Zi(yG-Wfr6AvxD$ww3mc)jkphN5yag$RKmmb*0*jD@rKAFZ1VIo4lMo_- zTuHcvOX8-TZD)Th8D{eR`ewc}=R0%GbIzRSyfg2qicwu7l>M4n|+Cob-jzpB~@B_K;z9je7?=&;k4r0WAyP>YYAw*aXUL# zlOp0~mYWv}#VSSTcg%J4;~Y&IN=$kcf9ic6?8mwB6<#rT>>G55=IF4qa1l|$T%qRQN|1i$H>;#g5ayc2T!lln_o=b(ZhW@fB~Th zCzBa+N*mSLl{gw?U$_}K=#w!C{J~#peZV0SW7qK27m7pGl7|}`!0-O}dp7h(X%m`g z4EESdsO;a8k39S`g>FxGvn*Vr7-u}S)I1S(acASBFZB9;9CvgGH%dslcK=Q`zxvMg zA@-tgvsHES2~n@2Ntyr)*FWm0EQ8P(6a-wEfB>;`h*U?1&Ci*z}w znp@Ddt80`y8H`41xBpL!&gxQ6Q0KzGG1n%LLhU1b*7010ns;y z78MXqi?ro)Wm`kNN-N#>_=L966D_Y%oi041&^QNEWbiyy*7VklhV&-O?ObMQ@oNyB zu4%EixK}=3fNX!;xmRDSPzD&NZcf{AE=*x!0@N4%KMICE8F;RjB*%sB>yv5YiKEcf zE25C{3R)Cv4}htpfTf*St*sfdvc5|#fl3l) zkUR8lg4VIkP{e%nLm@-UdQ^2PU3J|t-x^Hr#V@?JF|J!&&4?>kIrHf7&p5@s=%4mK&zwl< zmcbZ*Uo1mIF6nEr{_z36J|r|H+-|2p&F6~JSjI<|_HEbK2I>j>pP%q&{u3-DPK=CPcC_)#+w;pK z%OqY5^8tUvOS0=06=o=IePE#oSN2$ZTwFPR=fNB$P3cWxc_ay-)ptkH&qn&AHtXjN z0!@$jFf}aU0SdI`n!nM#)yonVa%Cp4&@$=nzbxF-P7Rw{;re0yCl)t+;iv8z z?c0U`0!u1pDeeaYX}lFSYEaWd0(_Y+y^=R4J04w`gzoss;8Eq>58KSpFwr|`qMtmj z>Fe3Rs?2q@VpgmBQ6;z?H}9?fg0H- z^P&F#wX1(jgEwJA{goevW2i3VlxO{ol*&&d=2vjHof=S#us4RDEZx|GA1U+6Z-(<} z!SyFe8L+G`LgaeM+a}C4$}8~llYbgv9@OgMN26-b!U!}MN0Eo2@LAh+V8UlS(oL2+ zs2*(y=U_Nz3{}b7s-vR3TbJB?4AX?K5AOIkw;sEF#|DLJGj97$hCgnrJMU`wrl_B2 fSb66o_Ny~rCVQ8O}h=_=&2z=Y;{oeQce!t`R{&*g5k7Kj9``B=-z1DSI>%7kE zTr25d@%HI>< zSozL>o!7rw`@f$C?!8*~-%oG1e6{|+uQy*<`5N_Jlnro_xpB_@)|xfDK`X~vTPKZ~ zHET|;u{~|=61jG21bzd`iW7>7H3fPy6&oMqztwxM9(3T!-E-SCHWewH_dNGqcH@VMJWwZxjRVX8dU8~!}GX6-6JE*Eb|J!SMKQ~maubz4^Zp{R4=ME9CnudX^n zL&J;Ebz>*nD%4in!j)G%;kH&@jRJivS#=Y)sLzzhjM>M!eDgKVBDTX&i`Q^P4mnGG zyFb4F2Y&npa_f_YNF)s1rMl|(j<*A=hy3*2lR&yaJw6)waY)1Rk`oQ{X|*}f`(E2tW4|@4^qLi$+*7b733K;ep7QGbW=rhSx+n!TBVwu=l$i7IA9&v_+lWBx zPU(G#{0D~O#^}0+g~-vceGmSDmYvdj|L7lV*nL)<#^(JuHpL(AJBuzdemWD*n9oLZ zhYMVxVCa(ZOa@QH}&O&X4kq^`_0-7`p!U5Gw9tKQF6%4 z<+SggXUsM|jQu(!9}{7-)nV*W^wbC!*4(Y2k}LC7kH z_5Cm1ZYigtLuh`{Bc-XS@E~+RKp~YxipJ&S*p&Gl<+uuZGS^JBW0WBOKmf^11nfVv z4S6MFl|2QRyw|Rkx7(Gu*bH%Me{9_?^&Y&lj(k70J>A~v;>BQMb=XU4ULMc2z8>R_ zK*Ui3-7;$wWYi3{S(H>1v?!>yVaOv($;vg|fxf+P*Q~4>Peh2cJ1~M~i;I&<6}N4@ z(><^G;I`pr%T-S3@pj&?q@F>UOM&ic|HP>Fth{$mW`veQ7b6*Z)c4QGqrOKc=v%ki z3~C%W>*8sjNvZU3Inf$u{aVwSM4GM%_h;?Efn&F&%D^|9s2MQ&YYw(TeZ__gnjFa%}ds{%{VSXriX2s55xPhpr$)uznSoMG+lP zUaCvI|I7HS`w%Tdhleb%IbX%G@1)~N+0h+=F*wbWlgkcPA?)3A`n0Ur{i|*7wkp8w zKW^&^TfNt-KY;;bzijN*hi$rds*(NDjJdc=F{ar!U;;@Zmj%6{hDAT4{!Hb$D#U9V z_*HWHyT%;cWp63D$zWbW5bS5t1C!4l$nQ_<`4N~nINp6d#>eLcLd(Iv#>2(%L!fQ@ zRh*`Si#x)E*gIMBOs*_ELapXyXSh4nW=~)vN>$?|IAOIj);7%T(OD(z;PX{G)xSXa zBcN~nKh(;HYfl_`IxbCtADzgwe6i1`=mj|Ho9|-rV81HVk`m}%Hx%e&T|zA{S8%Nw zbS1oa42^4H$=tb6pHMJqDDSw_*OLU#@G5G)%_UOw>=@hC ztWK%y_ff>9TPRB~YTKz)HQ9vK<~o<3Z&)JB9zUOURCcxQwSs|e99+pq3T~bW;zxLF z{iEUcO{~}R^U?KhZ&c@8i;7C7CS`Qs-}F|M9ZUZbav9qR4tdw zs0wY2w?iY;>qc3eN{P; z0*4o(16CIW-v81B0>H0`&WlG@-*s+ffDO3~6hde7Qe~>#AzFuYX79CyEp0MmhBC>Q zkzt?K;Y#|na6bJZNkOEMA+Y5(dF9{EfTbgYz|s>=HM!q+Bw--Nzd#B?=D zUX5zS=w6)HwXSSvXkaXCmQ$?`_w@8^`it_;f?@7I_4Vv3JN?jxbFmGF^c5bRUNuGX zeezELP#h(9flnXOnz3_t8IwubwJW#k7;aAlj{5X~zq=kdndtFkPNU`VW{pigUB*I` zhP>n7SETaWvgvyS-ObT=cMHxCBTB~~jeZb_lTIQSD!&bHRl}@PlnyExXK_e+K3(t& zPb$N$!z_CyHr0;X?Z2sY9(s`+7MM;=m4~<-vU7764LrrWLb4-A0^w{+oOSwn?egnP zlg!B3D`)N#{97OI6}Rf>>yzd=HH=^+t=!x7*j~uHzEH5M%isCs{{H?&f{=iK3Z=8O ziI?#5iut}0XM9%{OXl^+$n-#W_hq^fSzZ}}H4mU;RLuN{jg2Fda}&Kl5DUP0BpO9q zre8FPA!)*!7Jfb=vERq9cQt}syH-dfrdY(xU-Y!iG-Z7I_6^mhW`!Cax>>PFZFRPO z!yQPq>Zd9%9{mRfa80}}6qw38=D#eN;gasz7#&PIFm?Xhuj3w#q`*RIA!Zs)jpT*LWR`2GpDJ~)|lsx^7x4it3l;2##D75U63 z2#TLsS%Tx$H~qfK2H*1w3R+UI|8gVc6s2ED=?835syX0`4f7u4E+`axVP$eHOx=^Q zP(1btW4ZJ>#ckc#@**FPAF~1J=}b8Cp>A%TWZSfZ?iQgx?@=3LgdWrd*utH9?Ihm! z4|hp0Hq}(|(8bGiCjar?W3421Ls<{s(Z%H|EaSQfVyGI$fk~HW{g%kdbSTKORlx|M zx!S?A{R4BAk7QiV?2P{DtMf}H>OhD2Q-Zk#wW}!cc6CXTS`KdHjC8YM( zZn*9aC(Fd`QR|9YIg_(v5cV+tX~!bcF>93|GPC?P8IPPO$7KAqT5zs@`#n?x7|mU` zDnv*3NF%}EJKOR!nok4sF@@8Tf4N2dvHZbXuQkVaolbg`^r~f(OXVfcEX~bWQ$aZ* zWF=*Gb8{vqee71)m+@qvpTw9~JMp$B(9`oS^tcw%#$4BhF+RGo-WtnDx-Sza6<&E=^ zI_>}EHAxS__p(iqr3lK|_7?`^-9&&d8S?=+jMI~SzS4#Co5A-juHGB6!f=Ftt0YhOHxmBV;?PMT~X?80$CDGe|^<9 z+03_f8@+t&EEHts@Y1k-UKhZ5n0-96lp2%+iQv^5b$tLxJDg}R5mxFOzk>&mvRnv4J# z!@Vnv;S0MXeOvbqo8cSRK8UYWZPbx*Y>#Qbv)}Wwac=-IpZOLb)#S=Z)eZi{#*s8t zGqbER{5>0Z_Q%9jwOb~+MfLSZl%yA2tSUV&S<(Ze`(#~@y-;vfu!V&@XOqJ9*|uq> zou}h9eI}QYP5p}sYK?RVGo7Ys3VTnB-2bD*xhSaGyFT1qHvhhkqod5@Mw;ft)5cP`QZ(zI{=>`B8NZR#g;|Qj@i;t<4i z80^t!O6AV@kgM^%|6#>8153#-5f8t}J{O*jF=jWHAZ<#<;gAgOiokazILtd6$ z&kdn(O~qcn=yfxh_~@Z-Swii0T%+3H73s^Fu{QOWMG?|7l5c%uNiV=oF3mnRiMefj zidBfNOJ1H=#`wicmx4ud`%YXI)UnH}OjoR0(;@QcZycd1kTV@j4xS`ve2%=Cm#WBl zg~gCa#-gF2p+KlO<9#u*y1IG*g`kOrS&ZdY5?svVX*y(I7t!e!@lN`tm-IczziaL; ztgh@B-{EvJq|p1>BmbU%Vic~eBt+M|DaW#tHI3&%hg<8fqpK}`)STWw7jdQj7`87W zuRU!oX5XS5d!Q%ub149&x}QIg-}&({T%;faiGF-mEewDU`YdKk8?6D4uMav;ZSLCx zhdf`nh68~zT&vFP#aUOEU;ReQ*!CzWW)JnWb^4l#MuVZE)U6pa&qMwKd-b6}2CAlG zG#h%x<9BE&iXJvM?ug?yiOTCPcKVIfGg={rN=izWJzu1PfeK%evk{E4U`mCsN9t(` zmQ4Due2&Y8gi|Mlh4SDG^Dp8P`tI-_j(R?>h-k|lVnb(5A z(WVXOI&V65_WTX3Fe=A#@Q9v9b0jZanKCoAW=G229Kq5yOQx*>NS_nS`O6>r&AbbGqv z$4h6S^ajPui`8cSpBvRl%e9S0&qA!|tM9jyYvO$rE;Nk1wf}rt(dL!Gksg-Z$LzR? z$>55i(P>+Zw@UKpU(q0v)-T(nGiL(m3JLVsLO`+^xVQ7fFcRr zRy7hH^rrqJ{7rA5K9dvleMhE`KDhXCs>-dTVwKZtUKHybb~fUEN$_v0J@_6Owh#py zpWI}|y&zDYI-wYSX&>hO;D)owO4sU(?6drc@7@he{`i=PpQhJPCNH43QN@s(V;5k1 zTTlI`nQ}bDQ#~5T?!_kX{*jK02TX3?!1z)24vfb6fu)aHrAHpi%N?tArH>9q4F?*> zduG%gz!~{~J}Csn_&n8oQRsv{^lZX32q69;cN)A5D;@9n>d%e6 zJg)LUfn zZ?)3U@@gdOR!9>2z$|FdU2>}C*V}a0y2`vawW3FDSM%Ur#$bd7 z1_m{Q!S8--!YLeFK%+@PgI75D0QvSYaNP7_`~q^%ROsBl?@8}mHn%T)#&3Yhn$4ZsfC$e{}xBn${T3?f}Cr&00L<*+$aa^o{SDV!vz^l zGZ6LR<{TE$k69i`t0K9D3x-Fc{&)p428e>VN07&W90dSf57_u6#&jH$TXAJbbdT3VPvE; zeD}x*cH#NC-52YxwrJqalsLMkIev53fB3*9^*LvmX_F_UgBC#^DDF_RS8J31Eo|iT zt@M17rdKIYv$Vxn>w`a^zfQJNsx2ccXK#&d@ah*Pe#~At5jA_&bGGtYM;S`YhSdNB zCfg;|(TJgAW4KlWO}1BiIx(^Te9 z5!JQ%`Lw3MidJv}AeU#8ai~%rax#)bI}ymj@ld?bFt3JO5)R!Yo-8UwnL5y+L>MR5 zXw-la$zw9xJ_+0C>rH^^tqnu46ETJMO`$*A+C(K5-S1vP#9`T~&PEvQaSQ*+h$blC zJ7NTB+yavdV4l!f=4fLKzA=PhiCZBJh*-z`<%ov5x*-x;fP)d2J{h2TCdm>u*~21s zKp|F;4ZoD^n`6m)Exy^q$C1kGxA#aEB9&~!>0VL%&g1lhAezqW%GyC`eIc`Ybm5&6 z1S%$4B4~AeT{TvgO|8A5Jn@j_1?q{HZbHgQpxy9&2uh8rpf{GsSDQlinkzv#vHU>k zNn~-G@^#Dkf4};$P5tep4|^s@YvKs?rwoQpinu{ixqi*{Q#J!L?ju~5Qd41+&tNOW^zsJ7nK;CA%aGqv$sKz!g87%hi#$m*bntQRn zYYJ3ikg>x)MYVw$BDbQE#(*Lb)hKL8l7P>&`{o-)btP07$m#P$`6%aVvH8{{3`?fX z=Rb!O|KkdW=YTAId*j3zl_T5o#{M?2wzf{f7ZqPFAn1ZmxXkA7&f?$xtp3NtzTX|B z1fTwXRX?#T>%7aYz3BC(T5}59^Y3+BZBE;Mx4=q1N$bavH2&3(>T}HI!{B?5QW(6g6$$wMvnTU;P7pg`fJU+mc!iUN#0&o*rn z>Xuv(Z}Mca``+=`IE|)v{FD5aHjI!aS!e*iHDidt%s@+T|709LseYn?3W2hFBUzq; zSkz(%jP#eG1cI7XfUBLj@jh@F)wej_G*bCVdTp~f_>f2S=M+&rS!9O8Sj<1CuJEI! zT{I>Ch3*Ca0i;8gVM=K^qdiR%k^Sb)L0lbovxi$#yAi5M%&LnkZWUFx^~4oNxljbL zd;z(yt)nKG^dFe3!}pXDUwr_Rjhc6^`%wil#m8JnvT;g83NzGGP4*)IxQ zD6U8=D|^sI{DlzB@?$KtdkM|d?>FXeY4CVcmQ!c`Q`Gi<_=tF)o$9>MJr#-mrT6Te zpUf#8w8I080Vru>JQqXI{(7b@>Nf1pjn?xT){~yg5A3S(Ep1w_9c?k-ps#1vVruVc zo;tYIyyWm+mCO}Xm2?vGK+_`Owc4KfFWWea9koEAXcHEoZ>U2<9yoBgh#*}ufa~%? zDOihs*E=s;djzgmykcVN1@+>2I^F?mJ~)Y}8Sz5`gr_SN(hdjjbk6%(9nf0_gF-W? zNeY@CDkk63&SZ@D4-8zV3%QICC{t~PTUByPx^m#`CvZdQxE%yG;= z>z;GOH-WmsvX=H2wSYTu%nl>Log#`3i54j&1L4$io~*cpQA zts9Nyce)~Twf{11(oe>*2_kFuBMO17cYGv5$)+j#64Dzv%4|)pDu*pJE0#?zUH7ho z{R&-}@d3!2b0fkfaS!(mR>2~|qh^|cv62k5_K14{CIMlAsk0Kq;CsUq9mJfobho{On2d++G*FWFh?Z>levZ z_!{Mgj5EZhJaQBChUX-f*H5dBU?y$;eT(0t8eefnVtL<>J-z=WWVf3Oeolj8lRmen zk3NBr0A?n*#flnH##V*)k8+W{7TCE3rfAvXxv0OKB(8Uj9J@BM>wffKnoKmyJNBi=6?P?wewbOFwSQnz$lFuZXKU{dH;k_CU30Gt65rjXSAg)Z@ZP{4D+US zCXtUmeWP)7F$Q%LBVUo8UAVytl&c+e-qw@6{L6qd6EFYSa2oKWGIHvNbge}y0YxS0 z#^308rq}N}o0-~~p8clfT@?SfyA|l6cKi9HcvCshJt|E^-tgA9ZM#{pXrAM0wKRSJ zw{)R$!2bBi)vRX*uwX%9=B3I~zT?edmZi{yUViT+NHk&otB?tc{IQX3Krx$s_i-rH zA5OWHoS=p;nH>;8fz^zUQ26&yZ`Qd6pN3D4+8Olli-E+8-SmxL%*GX*2gU2~97V`c@J^TgujQSo5ZW0@9VC6B zgnhtj1OhHjPm@1@MAc!4+r`rj!qJ%iGyH(KXsn=tEj&+_Q*x8sbgF!f)xGK+yazzuD(poRX+AQ4*0h>oF{P5JoOc!^1;sT>kIu;`59QMPnRG|9Q< zi4PWxSc~7>?@w7Ly7R@%{I8i9VRT|`nt84M(k*UNe4WQsOfO0*66MBG(xk?}Wp~d- zx#9)9%uYc@p_uadt~xlcEN0TixSTBRK0Xq_aE+e*UL_Yfdzt@6dd-`Z(s>N^osB4_ zUlpUmq?>RD)I5BVRC#I4$RAcCScC*++uP+IB$bnmjsx=Al`m_gpZS-n6ugn&g$ zmx_DAI5sx!eITNWBIU@Ue!?Yw6$rxQ{h5z-9?KTVic(mFcVlQK_XMYxn+U}W2gH;* zODsQ-jC9KyhwduHU_2r*xoxE(i!nRm_;nERGuY|2S~ht(O^7QNA`QGk$sCv`TOY?V zsF;u7hPK7zPUTEyH+_8!vVBv(ynI~xp1=x7$~eZY?Q^r6-b&Ta( zs^ZMaxduy8p9O96F+ANHu1Z?US(I3U&rCJF&9P9cvkDLLfM>bpgkPE5OI_QT$BGiZ z$YoKLV@G-rqh^s%E;mUHCLD00(_%!MQRvZK7XAzmCxl2hpAVi-X;ECA7~{W4$nX1C zN=r`--giS7nLP__6{j}-c~$|GH^SpIvL6U&^QZSywj`?Rc&yW9gaw>w6!5|Mr9H*75)uM1OySDTacY zuOfNd2EF7mq+$j_1YkzI&Ify@uA@`CANXY7J0Qm=G3Td8fVngmC<_u->J-lFUZ-x$ z__JsOF-|l;7z)1Kd*YFzi2URg-)aBLeZL4}hAKt;zC}hj9bw$$m683X;A~E2Lq_qN zC}@UD$vs1Fx2W+Z$18cMavAAGW2T$mF%Sbf{c(ft||eFdzqcXGE5; ztl8b%`&}^;PEy64V`Z$rld#d3+EP^DOr0H$!uT%MN**k(!(t<&EuyTv_h55<9btG(OibQ1qdjZh!v(kXSHXSy>rB zDLkD*s$iYse}<5cEm>UfWc30C)5O-c9%PP5uk_k>P^gZrv&e{&D;~@pJW-djLaP%6 zjIEvd8lOEw8maTTPn~E#BFLf~1npMARhMMl&EjeJhzCYxnEzUIfd*-R4OXQ_E^!~E z-^?G_3xInuW=9yEnG)#LZh@4!#81cL{~csL2WsCUKCmO(_YS zp6F*l5&&^CsFd9WJ~uoebHhy8yhra`%pK3pG9|W~J0}S(XZ{nNST9h8!3<*|YG{Iw zAVJMTdacK_?xp!(A)X^B`Y3dQ*$Mk0)=@S^h%Q^T9$IQbdOw{%Fv&Kr4e^BEM-;zM z!`Jku{i!xOu75z+W=PUnEdAYolxx*S^LA(2K9nN}$fqtfeMysxd&Xbb$854fy^VNn z{P`II+xPtCPktA^ypm(5x~zzsNcrUo$wCbZgG4IS9>EA{`muQT+4gj+$NNQ2-j=Yq z99W_+(>y6;K2J2YphjDeT+gs}{-{gxR?AY2`p{H9JZ@=Z=ek&~DPF=cP7;rTy_R`# zsL=_n#akV|mZJf-n5}N~C(5XCVN{seMm+(x^W8PK;T{EDx8?3MlU_8JhVJaYevNHW zJDXDJC(qXZ9Q?yl5|McOgvxk$jk646)EDL>#3~Kyyr4D6Y!h3?4SH^W| z9?O|NEMqIQyjpVNYUQXaIorFPD-yMx<;`!){@T%*H<^^^({0sWq4i6Y)}vd&F@fYw zPA(6mxTRhRIr{T$S=`~Yah1_*WY<*(kIr9t=p*XSuXC>MjC%1%Uj6Q2=3Q39!9UCw zk8F!=IA5b_xyibJNxSxooKhVn(&?EzH~nxC5GA>v{JUz(7v7mV$Rv>$J{bh1rSj6B zgfB0I0$A+`=)Lx9h;5>DF;^NOCL#Ff*VgPlb0Z_kn*|zKf}|I;d^F?E9iO*a_`aTA zu3@55RC?7KWH`ADi=F_n^Tv*V)O6yf0dnjO$1U}R{2u8~14%PU*ZRiCP3Qx#_Uj(x z)U9MOC&UvCveEG=uN#sUt~2@UE)xoV=X`T4+eG45-;dX5S*VkaK_o4|>qXP`_!Vxp zG?h0d2$9Z*kmA^`Qq2wN)g`CxK?8A2WyV_+_@eXQ`SSZSW)2ped9(~m7@wL$FJ9sM zp_!N3v%xp3t$~`r;hLZqQoAimFqv3hfr&|p&JG7LI}bhieb7IbsGVM|&lfm_mQrr{Qh zXcQ6+*UG7BsJ4JnPYe;5W2N`(Mpz!1^6HreLi7h~nMATgKtL2r7ckPdrGo3R&?xkT z9jwwGJmB)JK;B5upz{O5rXr(%+*h26^j1q&BY@NUxJfAgOR>B&>?I(ae=AKr%WTu_ zab$}U(F>c|c`fI>8GtHcARJ^q8F4xV+~?Aq|GPKt&1okULdzu!3|Nbb@|N>Hj`y^E zt0WZ*88zPE_u>xnvK^c)>El-g^uCZ5?olCZa1c))a<6P@1=t^HrfapOc$#f;!Q$rF z1A$xW)h2;w5mpZ5Jz3j>4lztwa{TwpJ6({=KT30l;u&sNV2?Bf76OcLXr3rxu`C#3 z?s+vB2l>lXDnfuPu|wpcCBh}&LLn22l%Q_2)aEw~So}hVpegy-?tZ!>OvmCWw_SjJ z<>t*n=f;J+?T?<@j;2K58&CJd%1R=p(CAD;e#BtUJMfy=pYd8Z4ZzsG>cv3Q5kx&n z{Mo`4@fa_vpB6Tcps>3#eDTt*Ttam;msuepVut3E*~{D+U0kMzDCM)z1fJ7oV+wA< z#eCf^nHRJ1t$uRP@Numq0+!nzO||3Bv>OX@qkhf0lN$HW>@c?4D>7qhIaY9+cw0W^ zE_1};!)c8&ahA)?M#`KHD}$0bS?f${g149@t2FE%(MYy(vS?>~ywRyXQ}r<6#Ho^o z4h)QzH8*gzktA-R2`(%zY47D(O6$j)=o9F{&I&CU6Inz(w(ntUubX_{O& z9&K4qXXRKiC^4;HqAV|s%pXgs4=Twez;dvx!Y&G{cDyBb>#}6@RZCl!uW^?yE-r>Z z@ox|}YGViX8ZL^=Fo%RJ-EgBATIGx**-8@ilyJF!wmz0|kc!BgI`du;Owh zeQx0q$qb>c+AK$CKFJ>52};!A9bs^7Z(z(AK+DI4BfgAqmY_$LQ1dAo^4Q=XU`%hn z|0J)~a8cnHw+Pg2_2I}C^AAV9F3umGIo)!4?hD)}9&H<4^QwwjtXEdMC<~C^*jLEe zF$cKtAZT76#y_)uE|`1*mR{W7^EzTMF3#Iq;um4t?&5jT(J`v}BrL*s?zr%7(3k?q z@?dJu0eL?>x)|lS?yBMECyJnE?Y(v~cK|lVKO6q40KZ^uZ$JH7<6U0fejw1D?8Fru z0im>IIE$>@8VUGtZ(a3vD5yqz;s(I*glEfB{3uui2T0>6rIzU%ibKJ6c8E;*q4e$| zfmSGIrI5%a(k@k%Za4`t4$Nj@`Dojd?U|+_pl>ikw!H-WJxz3svOxBFCFpRZok~KHMI+pxIMYi>(H@xT%!S1h*Nx{vx;ZRm#ImF-`!tbXT`SnP02`tu&2vA|Q5G>f-B6i^|lFEN2U@!In z;1?isBTia+)TG*HJTJL=R;(YOiZ_5koqniEW`HoqI*k-gkC42D^cA%uzEtc{^xN@H z;Zi%4-N$`84e`$G?{`)Hd;8MJ-eZ1`5t+^Ea}VpX;|51dXCItgcsxHzFJ4H%m>qi1~tCeeN#_mu~Y9v7t$9lB7d(Z*AJxe zoE&d{@9M6K zET%0+siI3^QpscY;Il8|joTa{edpuH92DeLJ*t6lO9e2&N5k&FoNdvNi8e@v`i59pV_saH|MbEJ!|Py&G|Kv&Uiy#g=KuHb=2o8kQDkoUQ7-GYrgESu$n323eTxqmNeaC3 zLi=NP_Rz?LOjMD>qH>F73i%ox5ajo+2=ci!j#$3uM5)iXOp*_GP6EQ-zIJ!p2OEYt z%2FoB!7zNk<7GzW;C37s_4TT`Ev~AUp<$rc*g9Y2q=4VOYf*VB>2wA0R_$Zz`I>_d zx{i&LIM&@U&5kkGAIVby{_eCf2>Z#uSF$i4ivZXuPBcoBLB254l6 z8R^9Z%?muhnHtl>-V{`>NRm%D7da41$BaR}0p>X&zWK1@pez-DDo=6FdoKSi>=FQ< z@?N)6Pk1ECQw&pNhxo5I90Lsm3|CejW#=vSS)m%H(IAF)lAa|tg|?LbwtsjysNS%= z%U3E9le}4f`6uTi;rnuO<)^Ck1#WqHsGRR+HVP4E7#6V)DuOb;xU)(^!x}Sg)WB)_%1%Ort!)w! zAb}Z|anov0l_HiSCl*TS7_PmAe}r|$!)P|sFKt*Qd>WD_a9x+1LgVA^IVTsDvWv#R z;^1}=3f4lgVJBmXm{hA#*V#Aw=FAHCE`Q_ui$YzDfOtjExL^{TEw$TUrwWesB7K$q zN?usL`R&9@m`njU!DT=0x7*MBY3Jkv$3Z1uY{@ZoAx0_k!E`zuArq~?sV=zgl1EKz z@A43VyNTo_3G2;;qNrg%_P#JP`@El`D)cEqOw*emW?@O`&RGcA;V6nM2 z+By_G`-x_yMU~Mg`Z_&>SVOZ6}nC* z-CRsvFWNK{)Tknh)i^QU(iY5RWPYU`|GAf(6Ij`4kR8e@s^z82qHc6=6%Y%0r$=fk zH_j7}{-GK)$V$3jK3s(hFXRv$ulS{DngoB%yfJ9@7SpRdwrAmiS|szyA2I^O2}6)fbd<#R?p&Ex%&H9_0cGsh#iYI3}gU0sSB z>b6rX0+@|)j9A7yfRD7oeKCj|-M(o0DG?vsxbtQcY38G4!M(y|*+rTlhnvP~&PK)GW52 zk%^^wv&fI?%3s>>zc}-?1}}&OF?sy25z=3D{fN#YlGmK5fd36yj>i)L85~von)wqd zZ1frMerQM1`sR!k04aa}uW&Kvp^*9L0v1e`$q+VnL3j zWE5qNVTA86<^TH<&BI&PQf}I9lt^q&J+cu&UG*w_$u-ew)Ln3r+?6uxu#&j~k`Y|m zYHCmdW|dHzEB zvo!QxJv|clf<)DS)OlaMs$=S#$Sk=}`jJw1grE7&a;#Zwhdd6Iz!b|p z{5M-g7RAhMDr`-d3gj{Fo~jpj<+$K=_pu{;UQW}G1Jqs&+Afc9obk^%?7%_qN2 zx>bAF_;!s#Qt?5H7Zry;18b@r(7wV28Azmg_#B9i$_v0z%O8_%_a&gbtm8+M1R9^p zFDREo4z(})>hnd=E_D87xnaV0+B6S2ub(4j+qih`Hw_&pHuU%Hy8t4wTYdKx1#CO z)GxaYE(M)hp>$o*B09qZDxWD&Hq4bDav{QGV1Q88pG#?}KASt;d^uyn)4I z8Wy06iMoJBC5YINQtO(W#$BFGR^$?pC1iPCAH-oujlg3PVSp+r?k%A4kQb%jC}DZn z-dA!1bl*_29KA+F-oooL;|~0_*yT(S9Vai^vy0f}A}5EH>bH37?n7@)5krPJK;XfG zCZz=G{^f$e(>9qT%H>2foic3d2U!7v|0kxFsF6NbDi@ck06=?qVxSbzT9(DF=%rsm z$XVdO8-Blp2a!|NGP;YIV}p;W;NdvW3zr9_5-a}*3s8D^W}w{`)}dMRIzU_$sfE3WY6amtcwFQ}zM_4sn{-$@wU&z|&pF}KNc9l7^g{qc*^`@%A! zsf!vC!l{0(^lTvs+I7)~GxTa`GH+7rR%LrG#y_@}WhFielYZ1)j&e#Jo3lX4mr;)F%>g8O#*ydJ_WuIc8;X+gLr4Bhk(EDc+;PSF;qgewL_zp+5Ch3q>Y zsqXuvJ^Srz4^N>d0xmjSioF{7?nlJRLPb5CiVD^%qjM>%5?D^BJ9d*~Hg0!$R_2dC zmhHLUzOnJAbc}ie_2-yoX4@~;H;%B}nqBrR@qCISg5uWU>HcidHgR>daf?V4+Fn37 zkkiz&y|j4d9&X3Art&vu(ayECi(~{jRV8D1*M^NGZ<*9uuS6n!D0W0eB@sU|R7VSp zS`5N%+*k;BdKTXAC@R}%>J;rGr6xr5y-7RCP9^~ShZ(S*QuZ)vIT8o%`c^ziU^3|$ z>TfuuO8$dK(R^>9I;9`OOg>(QOZ{col-iT7@rI-1h5&um*1lkS<=VAt{m?dDoJ}bc8xlVT_~e5-y7E_=ZhwFVT%uC=LadM{>iQ! ziNT)@^F#1{$@jZ*OZIQrh3v%@8Q{EuM|CmG%4m~E;!+Nr`VPRa((18cJJ_% zbfjAl3#@^hdZ!#RCrwFKwHO*IrFlo>5Hpq|7v4$%hUckA&5~}rGfUj>DPcr`;wKxz zvc1yJm#_u3l(??nRAdzpI#SF+o2BShUBUv|KZGm}2WTBIzN)bB6N&QTSX*gBMwqrD zpos~{S^W2xP@LGj7R`7SnxD4=eYwrD@oFQr9&R2#-DSie&L_kGYJ<`KJ$*Lm*WEaP zEcN?=hDfQ7*%Gf|z5ZKqPp)0A&q0cWPW^71!Phmn4tWSs+@Km3k-%(#3EpYB8_bYl z7N^>9G0r*lS{H78Ey#G9$WXJkW0@=+s+M35&5OV?$+Go7_oj@7bT;zw=rb2WkiBWV z2dxWpO;}%nXPiwAjY$9PA<9*RdgP$F`L2q=(VqkR%(jFRJ?Oa))z3j@k*!@rOLNlk z-1BvjWsGi5)!L3ai=D9W94i~b)TJvTZrMCp7gqZ%7gN$0kD&}m7Ji6Xs_&3(PF9$Q z#c;b3X+?;zEUDZV`&VGm(vIjrZ=pgC?8Mb%Ke?N--+T|c$DAa5G3pOtp0$!z2(s{E zvRfHx=}sJ$B;9OSbT~rg~sYxjtHR zaUsc+J}0TS2b>tey|+JtehbHIi)!r_0kc#S%xSZ25`wb8oJK1-;9Ygm7pEOc7+Sb7Y2z zu_Eb%&!y#;rdZKR?^P^>4wWlG{(dARcawfQs!T=lB)s{{ZAn7sZ&{?wXG^yfAf+*q zMHaqeWjz^GCK$*Ddg4k#iQZzD&2`wtlwRIlJot$-8t>Vjmwz_7(mQ&4ikek0VuZkB zonaP}Q}-en*QJZDpe+tB$D~K^q;6QjKJ%WLU3N)NUmA?|hvOkKcYEI~a;y3Yys`2Y zw;Wa##S(ssGf?rd6eVZaRQlWT+pFK&+S-np*3jhqE>i<2hZgtd>Ie5KzrnwjRC*W3 z>)O(`8Z}MZh^PDd`UcA3<+ZJ)D9R;Zw?~yLP;v)2+T}`KDT*~$50udVtktz9R#fza zYnup$;9{~rP{D3URYj`7E%B#lNWPym^C(b?BS(ODQkP3-`$BJan~oJrN~10NVC|_H z84~H%ImSkDIU}}88gWtPjlI3Su}c%rNN(4^tqJ=cyV1O4nn#5UuG!ij6LtmJNh=f2 zfEg%hH23&|dtDhkGgJNCF3F_|AS&>O5`lo%hlyqsUl3 zog{`EHRVSSn!*XgH^|h5o4Rh6L3G7M_#g8*m}4?i)yZuh&)o5)VT_^6jYPKb6v>0! ztgsR17juUZp&N&Wr53>`8SJJIv0_XWt6pjm)~ic0*`mXJYk=#IOl72k$v%_EqrzA( z$D?f;H+z#T=bYK~oV}2p*|6HrLvrQr*9GNN&$u#Em@p-p0dxPw5+xfol`Fbh`HO$n zu)ij{4$f~hB^*Q(elIpSCR;XB7~y0y+(=04@rQ`)hgv(39ch-i2Gh${%Jrrq6|d}h zpd@knC3idX+o+l7%&<{Hh!7z_2#|y%zqj|fyRY`z-g*B1fjlx^ z@7L?O_p8c}C(*CuxK6+UwKQy?hNjJaDhpMQ{sBlgY`ouSDhnR1?J5=noe(B`yDgAc z?$K1L_?(dh*(j_zL2hC;7Kyc?`yWTBxlThnl^$3p`hTpIO~JhC=)qXHxq&RV_8AqA z6kzA-VG;MK)evGySvFK^4hy(7wYBt;L#A+dTpn{BHX4B|E>9EVo$s4{&q+k_!kf`R zM58GuxUv0lw)zENhKBr14rDX}?q3ivz;$2&9YjBklP$Gz)LlYx3AB6Bv{_C1VP`2m zX}bX=X4WWO@*Y&M9w|F>g|{#+P&0bXTpfkhc|=Xb6b-1j)jAJ^Ntr@q5BnQA$Zql< z2U-i6b$~&`X5hlz0|H8RK04hAbnW8@){7fKa<=(_Iod$o;qVE3um_?H0=@<~QZ*3j zQ$-OchW$C}i|Yb4E8I%2)u00lNGITCdg9@uL3P8b<3cEI=|-b#I&wi?)}T9Azi(AZ z1DJXT$lfV=M>Ck{x$}rfjs772Kc2M zhxFG^c{UVV9<7}1-!#&QsD-Wx^Hn_>`x_OOfT$0Dg*PdjSfv|^rr7=uHL^z&w%QK4 zH4O{#k>i?3^HM%Ybab;4WfD5TTH2~brw(3WjY6ti?HTPMNq9of2*Y#oO3m@bd98qr z=9|R|Ugb|)Cn-;UMpnap1b+3+iOA<%(9o)|>b*#bX#Zer{KabnW>_9?M_Erom_Hx3 zft@JZ4)Xh9kx^A9_-542P3z^HB|+ua# zdBY+eKOO}P9Eo^@+^Zc}D`3R09Yh*urbIBJoY%N!0=Sby4FS5?CtozO+Q`Q*gg=51 zT!3z#@oD<-xpxf9B4XQPHiP%xcEg(99xyCgHmNmW0v#8;=j7=VYblOqww_4^Z^@uU z@Cj~g;i$}$TxLG9eCZOUu}HcmWYDx>WX^VmSinoEjc+#;H2pM%30eH|c+7#%Q$I3V({BXb~VKpg&1ffHj;ud(~4D5&-bI#(AuVH6M`1yl!~8$%zr4;Fi>1xHCRSJY4foxx~yQZgbrr(dvQJN z-9(xiZMgA+9HrwLCaLhrh-RSqmgi>E2t=^*As)Iwg8(yOPz^dxk1hXL5^W{x)nNxl zahZ3yt=LoekP{~VgMIX3^W0!*%{QL8JhG#>Q|ycJ@qkR1IDWD7xzWG%l@WxXGUCGs zQCAN~26IopIXL{}+k;S`;_QdI3uW@n&Cx^y20?Ys$%Tr*N^c&;95jvz=JO|OBPoYW z7Yvh(!Pv;V@*=A#%*0q*sT?SuxzcyLt?<>B{IT~GZ?lxRE(i@Aw;l6}*oQ5NBQ=*i zPvh&9@)LH(D>UY>nNhSnX8BF78_l_0NX~kR?!s*~+KUl8&G&s)MkOl?hYF(Fiyd?p zY?({E<|78!eZs!I-+rtB9yKM5K+zMU$6e1@^#PUjQ)Ikf1lybd!i@VJHuGE<#OnJiLrZqi72G?^X0QKYUBZqc~ zTS3CTbr1CVuU^P>E*v^(8F@0ww)(}Z)m!oVis|>L2a}Ak^V>atIC>LjghvPINW_&s zAd-f&A9yYk_XnQyQrxXrU48P*?zu9HmYF`?Ccc&)vL>Z>fX&eih=fPg z<(dvD&>^r2f2X|sFzbVK2YI!`ay8Qn7tn?U#}P-oh_-}-#HPq}XeD#F3X@&9L;dYp z2ivoDwqqR+OPdxNm3%udVe9bhvXESnkSzBMut%111|4Vbh?>XeUu;)PUL~vs5Okh&vi*K_llI%>(j7<7i!vvSL25~xpN;v+ z)zP?^z9VW4-KUDDf)Mrdk^vjQto0vcd`F6gcm*rx8FZ#)?`xJV~HIzXJCfr9>axydQ&X`cs zm|R{vBWIq$Agz|og?Ypv`bYU6D}{F~=^|LVcD`ccC|R2Rq6A?{!cI7&n@Nbi!+8C$ zrCspY9xnWDsYaN>e-ikk~ZoAt?L_-mTT3W{Tv*bnty&_{$ml{&Yd^d%;Un zG(AYp!x!b}nTgBiNWLaV$Q_^Ih7w#5%k8v=yu>?M;rFQYu)_tXVha3zeYb{p68lB# zsRpUfMhW3^w7^LX!698+eRq>IiF?h+CZ|aX>j21N#+xSC&#Ng0+*eu(c+d zTFe-5MMIAoC4HWSzm=xe95`C5GBHD^t3YF{Bq!t7#_b-T@+3>j^9y^d)R4xGf?wMU z&5{b|lC`>TX=2^V2_`lsPRos#mVM-Ed^bV!$(&_;*Xh3ScKTJhlQV2mgrCsJh6yvF z0iIRkGRrs(B>X@YC^tT~pTO$dNYmFXzl1#!A~(s-2Gc6f)dq}THrjng&}Z0f8rT=1 zl-bHz#bhj*G%QQ?2-0p!vG1fwSn*zBry!%5o9nTjQD)(Sxg)0}7v_nsdG2+Z-Qk@B z3hlAR^vueEXWz1=JdqM{g;tCUhLV0>Q_JOj{PCsdmxb5sGMLDf{J1NU*v6U-;i{0= zK_-R}DK(AxLCnl5QUs1o5I{8q4e}X)b2RRZ7fnmR=&qs-G0m|JrX~>%9O)n19g-j1 zM8uSiouqj5%;srtsL%VegmkEO$J!=AaFB~%6FgLKR&(qlx zy&^XPtBvGMBF$pTt2baeJSjmK1V1nk_+jV&E>ZwN^!ByL&oHCV)ilj8Ib-R#K(G;P znACkc##Zm06UJ!fUd(`jrbY!!TxV~duY<^4pz!OpOO@tqg^ZD}=A}V$wujh}rp69V z!oyeAzZhxF7%si4OtrTeK1hsPHQ7r`_%;p$o0~N-| zY=_k}y5{lF$?e+;ivw(y^f>74Q|sy2^*TEfe*Y;uxbUVBisltZ`26adF?%RQ?yYRv zGtGladx!BrQ7SPoM;Dr^xtF7PTsdthRsXU3P3!5{<#u@tA1IRID`*{2PHPXvD`R?& zsAcJ`JyMH5?oVLlF;6#KefL5^>-getdu?t}t#wFCT6>g9W4051J+qH8t+&Qa-?b=I zOk-%;Ej%sC?|5ui>&E;jtS+xnK|;L_5dXb}o$om>N!-dgkUXV;ui37$S5ynEGD_1! ztVJQjp;~v<(nd60$|g*BK3RML7b`ROFeO($ z?XXq?3+PHnU5)XelM6sZ{b0{J>sy_S(3vb+SRQo-&eG%go%58t=Zm^nM3G(du$?CT z)`;`Ws?P$)PYPD+FaZl{JUU$t3;f^vH&FEbjYkPFtd20vQJ+m0;HjY=7?nQxy;7!} z_T@TTPheys@s3|Xd?Y&Sw|hQtlVuYU<1T~D(=OPSHI_{|l4j7y019_QJJUpd$=b;B ziS?a&J1L9@zwV-+Trk}$49&G(?__cGUo&bV=STDg#>b_6yfdBstu#gh-tdkIE#KVH7)TTWMfL)`!-d4Qn~IBxU|-BEhf@>rju?i zz`f=jr4*1EIMs%7cjyEmhTv1^^HHoXp}$boTIaVkrc;QQipo6p`H&lA6PL6g!Y)0* zjChBTD0mtnN(^a#msFS6jN^`7uAAZuk9U}^cWD(GRV;<0MTN5Kd`rowwKYk_kJrG$K3%^=lo3$IA_*14wq>DCb zbHO|AlN^Ih>`O1ak?{`73$ONC^-^&$LehGh=5es zpRLsk1Ax!k}vs?J7V#z;0fT36j(F>#rIYXP+PQG zi5LhHIrcQfh<6XAtXFc|(@1?p4+Yp%bf0!#alkD!5=5y@L)-VP~ zq_GBOAJ3eSvO_F-EhS#d^prDL(xA6%rr|3)e`~V7542W>N@+DHr8Q_?P};joYgQSl zl?dhkDt8>0%DFy9yMscGb*4^C=* z@@bq@TSia!s;cXV0@t zer8IlF$r8;j7fZ-A+bGz&d+4WOag_Lszee$H@p`dqKJjok{GDOTl&GNP9XX|Y_wVU z8G@uK@Hw5`#mM7zM9z2Mq-WE~Mefih@|DyAUKe|YyUfbxb*{S1;8}W1hP&+qGsc8i z2C2gpuo_ePsb$dk0PB!J7n*JQB@~^@W?)PxfYL9w0DA>)QYz$?NyK7|>NXnR#J(P< zsfm`k)M}2D28{O}`~r2{VyC(|H#BJ&tUQ^+f#kF&H_VSO&CJS2nsfS75x18M@>M69 zR{%wqY{Pv7xy{{z%?8n~$fpY*RKemfJwv>-Wg!$kZ!5&=3ENZp48LExjf^*0T^fWa z@=V`Vqb|qvR><}&yXj^KvD_!%>f~{0PUiAF_84K8(*I;o|BDf|WlW?W>7JA`nOXHE ztG2_4QfoDMkE10hc7 zi$e;;6vaKEjt&KYj?_G;$#W37d*d~2TbMFg)dvtALkEpvQFt~;EZ!(Gcu!K%Z!S2A#10+gPUUeJtShDtB0TRrU@}7uB(O)t4EeXirqyR zUqw;?LCvrIXw12~`hj|pM3l70Ux2+3@go8=3DM9?Al)^zUcPaY<@sEPc&(-q%ji-u z39SniC3dpLzQ0mSL&vP6JGsLykPa7z7v5SfnrVmqobDzMT-SewK;Ys+pkUNU9rL>0 zLh+3L%)RBE%fnTcVwapw*bX#n+^PswrRk9`}$EQgUW5V;x;#YM7 z5@)!ESDBxi!4J#Fsk#sdjYw9#M;7%`7Ne`uLugdM=w@FMDpz@A=tHC_B*`MY@B?KI z7M~kfK*Pt=ST0b?oF0z`8!pcaYlbWw<55VB_9X&#Bs;`BZp zWDlD#OIAqSz)U`a9fSAu<;BMH>-&~m%djT46Q=VEIb4G|V%bbdT|h)Gqk~-?8Z-b9 zbFNXa)1Yw}Xm)ANiC}O;k5LNH1ZO%80|P>87$e??W!_65HZ-*k^wB#0!@G>%c(U@7 zSM??;dd0cGbJ^SDmBtsD(+N+H0rN-Z+_x)zjdQQ%>D8SquGjI6=F`Qu&&!8q1$^18 z*_MQYS4;WEqZpWggGgQeErxK2rc|;#3GZ^U`iX8BY^Ew9OLVRS7J&Czs7lMai|le-czqDq{v4%7{9 zV$ILA3tVagCg)(Qxdi%I^~{!&28bwsdPDoD2!-su%U4CN~r zj*hp;Cp&$ zG)h?1F)xTeKz)Ju0wO>OA$x$4cdE%-zlL-+x1GAr00J6VpAYF5*5;K&Vw<8eFEx`? zo0M&gR)@T)8d#0gJ1x(XH9M!<{G~h`ex-hJA)0lOJXfvkx=pWu(eioK+8qtVJV~Ej zRl*j5Ua)pY)Ma|-alT)dA~>b$5E0E92%!K3##7YSL@qyr>-xqIs8SH>bYtg*zP9Jz z_FNp)P)iDh$QhaNqe3?NQ&EfSD}AD^OCPLxJ|@p{kUFLWvXWn+AN(GvX~+8Mue zp#4DKPxnhoPAm9^Uc^|!jhtoW7A7I6oP5N)#36D*Q9e==X=^aM6Nq+_AQH3?V%~mQ zXU#X|!N?ZtABL*@Yy;zf)_1#w zks76r4gQg|=S7HKZ_jZF>KQWUQRhfPWj}(RXoZ>U-6Gq5^(_ovB6d*i9%!G#)mZ8) zqw!khySJ1wYi^q>v)4=n+cbI`{L&|1c9f==mw2Wq_AEP*6}CrDr9S83mI6eHiQ8il zCpu8j;mbRM9k|lm#;ISYu1+lwG2DrnO^zAVI@8^>E#l{u+$n)q->a)kV)e@OY6H*a z9mpQi(|b@g5=pu+Q!wcH%*Rju3&W}Rc7KzI-21}+>=&4}|Hju|+5kCNU?P85Iry`u za!&j7%WEloy9y`-eAXy>@w(nb(;B3Bc~-$Tca3b<9oIS)3i}DXp&z+WG8O%E;YE@2 zfs&gAvQFP1E+c&9zpMLM>d_h6G!unIWY&sabYS)SO^Y?qPy`oX+> znQ!YAje(7}1qG1WHz_ZzA!7Rtcm8M;a5CMefz^JX#37%WsIph{rpt>X4qZ#4PbC)S z4`yauYTsE@me@zKd^>&h%*`^1dF~A5b5IJ^0TfIKjx~D|16v(F z2TYY!N(Dx8N%-KyBWO`Ds~4DuM6}&MBt_5`$FW0aRP`{`u&Gpu0FUw{YF&Yw*i)u4 zp~K{ZQX;aZ&0DWC#mB)7KF6FD>ie z0h4P%L`*O`;Z-Z@&OLC7hlgwfFzBqvn;f@lw41gtKA93q(GuFDx7);6p|P;m7YcM~ zw?g=;ZfXiO;S~|3K71K{iI^KTSjz7S7ADXOVXIkCi;oV>UYeGn(4?a|&hjTaAabS| z;5gAsGi?60J=F&^YypP95^i@^7XXyND^qN$ky8uMhiq^UV3QXVPB=4J})s>b|pS zCer%Lp#K>eKQ8^Tje2Hyi|bJT?$o&VGrc1B`rg%CVGL;PLi-bRb@B0S4uSFJ~6X9o&9s{ z4mq{|+a1ubyj9+~8xegbIaJV*Y%Xc^{`Pju-gk-e84AxQ0Pl9IEM)Obt*riX!cJM2 zkTavN+FX07-G&_ob9ZmtveOK*g3;y*Z zb^pL7N`{?70~0*M(PZN_i~=x1jcB(^#%Pz#z0Ozd2@$8m{sGp%CD?s;>BU8`uMss- z@j``JueZ%JAfFRGs(5&*5sx|@eZ~7yVhV+w-uXIALX@~3V4kybZ+j4W`W4g2u8ck} zJ6u^&-Va$@4a3k92k=%wRbeDu#)1ks74atSWOYN0x{jkxa0+#Mw*oNe4ghDG7cefLP9%B%Zjev_(I5Pd_P^+-=>$m@Tb84Z&YSN#rAMx zVA|WZn-ac27SygeE(+}5@S&14wO&D#mMCv9*mQ04RgJA zXQLLq;JS7Fe!}M%gQNdQDkq=xG6O4&y>XKT)k^qBrN62V^r;R^_ZtGDu6yOIDyhH5 zX(c?9(O5M;D{EWpWjx|9;3e7eF=XT|1Qezb#QQ6?gVuvjF~nssqixsF|cr*x3HhU;-== zuiP!bJ&n01cUpXf!u&4TvqcG%Ghx!T(#B&Mz} z?SBLF|NZKK-!~ALq~F<>dw#$Cf0WXnKma4Y*h=gfo&Bd>^gpeYT=fylT2J16$&)`} zg}+;y2|e4_r>O7eS7g2hv~4Z`mWc=Zul|1dPtN=wKWcfuWhNP4lK;Cewpj0p24;mz zxy{ecCN7I3mc%hIVDhqw{dXV!3X?5Qwg6M}3d|;hMr+N6DHL%UFsC`q4*B#m#!vMH z#DN8CphovASVg^Svy6#N)pp;8&$sTSxkYn!=@^Lfvo$Z9f|Kj8w>3V|p&zzUa=jfV zJ@Zd-{s&h7z5GqU5YwdV&`G>;hgs5ovlu>`VsV_KaRB$}x9=Z6yi@^x_oar}XS=-m zaLX%A$yp^Y_~#H%zrF>|T!X7QW`dDL1#s>Uo@I~zistWSZwi}13w`PYlcUQ7V*Cab zRFJ*BPVv)KC69cB_IDH2pY7la39scWu*j)1{htEjql8Lt0kZjrn3bDP{gu3G8QQW; zAo%F7?n(Ldxd|96KnC|j7|(y9mivsrtpk9q^>LS7j6QpN_dVx?y*7GBrawe(1y%Y24pNgtHz<>L28Z7ZCM1K#2{{&dCbDII7e(v6xukzT# zj{=f3PvOd6Li*FK|IxOrZv*1X=KCt}SBWnh;5-$3WrMzI5%3;B9D^_Dhc>B7y5pU4UuDS~d_0d0y85dYkuw8iy8QKFnLk3_9|7P~e)=aM zf0PH#Gn9zZ`I<#q9)1VtsE6t~zx^kg`m1fdKMkD6(60Au7<~7=9{}~A`-5-VUp?tR z(oG(49&dTek*``L?IRPWy$BTh8hLPkFL0j!AB4(GxB;m^U>bk{5?k90<_o3%NdW)A zn0nV1yb$SD#Mz}>@E1sI=@%b*R)LsP>-}Ej6X2*P0>N1MJ)`Hpii+L=_UzK4N%t2f z20kb2G=+~)zXderf5l$jE&^N;9S!pP^pKxF=RdEW0RG{l)Ow|}?{~2NqJ^$TC+Oca zomc*%H4-$w$1Pqv@K!T}Ji1?MVLGll8G?8scvA`Wjp*6{3aj z+mYYD=d%YSHvu8v5cv~_KYRBRjQ=-hPrQi6(LvgSLNY>UmX#&QB z#`Rz^Xt5atdE?H-?E-a0)21b4p}S_(J)Pn|(YY->N8c#URx}XAr^czk4M31&psL29 z*E=lR50qHP2v#})q^~t6KE<||<@TRpxxJahsXtlsFJ#8QK5FUw7zL{;uN(h24&S;t z5(p`=1B7Ay;~N~*dOgNY*0WstvOyLz(s)F?&x4oXU^h`y_Hww+0er`$TnL+ujs>^i z1Q|I~^?vWxeNBU#c&i8Me0sfA5k$YKab4*~%??@Up~;A8?LVt%R+rtJ&xI>fdE{ER zuJ?#{2J5Dw;o`ugYa*MOn%2%>U+0D zzIx1b2P(p`4FUcK0-G4w&aat>`piB;jc{je0}zZSs}f@zKlk?S-2i;|<4qjDCcff}{)q30hMdl`IbOy|jf)i%S0+=RZcA#eOwKeqVme9x*Yz{^Bb~p3TvV5xAZLTehm7$>av{2ox4vT%TW4+w0CV{Ab zA&e3qud&p1>eyb=ulvz5s&UJ+XS2r<`sl8iEbAeJK8mUS+ zI+CIqrP=tWEk=FjUeoQ!yx=pv-bLp|KK0bS3;@S5cb8N9q2IB^??lA!0Qf0;0+kIr zK9;haQmqd9J?B%8Ka=0ed&hOK!>?tt?Sca|T2n#j&95U$ibMIgFLT~4iNFIj80X6; z_9ewl3#JDBABnriN96ivt_&3mXEV_Pr^zMi0zEsrlJ3tNs~@NzV>)zab17RNVv(OJA?ovpD0z>e2BW;BV^@R90CnQ*Rjr{7(Nke&o7l?fvFo!*%%|xh|?}{@y=< z^bdJtyeTSPVRd=N?2#m|&GO>pM3r8?A$q9CJ#6$Sps?c2z zn_T7RG>f1Y19hG!qG}I4s0J}9txiFSN9x=iW|~>wLQ|=t;|>M0b5GWLGf?O2>*2Ab zL_@gbv5osQJ?L#Mzg@d*0*7OJZ9deSK6WMGTa!svkEbOVYh5o;)9b603^+*Y7A*O; zRKf9YC!&0=MA=0Us_&Vd_!F+sE8grGUAhssOiods)!36iCuBwQ#J5j?9!>wh5`w?O z-YfQ_F*89S&wUNQ*~tQTOg?GM)%ksp#rjDLX03HGARsZmOJ7Y9j06eOP%F-&%DINn z3)&v|Mj6Y6_2*4f>obnj6WdmO6~7B?!fv$A9{DC~U@8L=?unB)G~`^)Lpk0>rudKD zG?C=1iE;Gysn(tN)Fk_VM9{K%J0Ply2sl|^F6Rk7?no@qTxe^?5oe+|^!zQQK0T%S z^^bb|LDGfepOE1nFZ(%xeEJ=)#~%SW8}$qS_i-|*?H|_P&0KE6m?4!W_!)Zkwy~1E zu!X57jnl?fg*Z<3wwu~^8tI#BTQ5qxBA`iTWw*FiWQlBc^yQn^#hc}KWx`gn6&OzO z{P`#gen(P<#qg@hZO4D5*nhX_mKCuBgoi{fUeXU4T`EcfRoWxHHr^TV!d=yTfcsNATf4za&g|zW`5ym&42|d zLg-#XsxFj?#|st{kST4m^j3TZn|y{5rP zVk^wAnZ>sg5ZiPMH~!)ONG+HxQ?Dw1Zl{fZ#BZIFZ}aa!_3x+q^LO4V><2E}`2jNa zw7RA&e!L=gqDIBBX2o{u^kgyWjyl1ts=WlR_;|!spnjg3Ylba;EC@!&i({3E0bI-n zm-D+=K$l_7Bf(={NwKau2eFdzQn>uaY{_@-L!GNH<^zD(Sj*iJOtB0Zy2`=E9=Ciu0Z>!E&nrSFO09 zYA&p*hC7zqw{kC6_Y`6xT!(qS0db?8uz|zP^wH>-guFR&+4BOVc~Zg4yyKTocyG=o zKR~|9(5)F-Pgh|UiQt*pjFL&F%KqZ)za>1_Bp!cs4j)63wNpJXauMZklN>XXs=QdC z5w&pFZAs?&4%4ngS^>j#+o9l8xapWHqw@H*6rCreUBjoh8!2tGTaE87l#{4T1XiP7_(uyNaZvlQ)Ws;IE^1N)(w<2*`t<*k5z?hj+70rH`&=lhB{*G#6C9S<=rC) zUtmwioYLYvD<$}OBl<<-k0<^pQT&kT*nSckH~J>uqSkj^2GhP~d%ZH>qIkOQk(Je^ zp~pD_%|n6n`R{p{@%TH8TshhX>Qd;-wsV6{Q?n>rKgn6bq%@k$rnB8P{yYDB3ael?C*wCd{*rqYvdAMg}U3Bo74Q}UE z?eC_Unay2vD?}jUMzVJI868vcaoWZudF#43n;C=j&EHvnn;_g1u#qV>aL#Z?=vbA! zq4hPDRJs@)FK6!NF3@<`qwu`$X6IRyC=>SNw27)|Jo+v&t{AvbP{P}^9-~M>;Ijk3 z=n`GHP6v&BrC1P!fQMrH)&?gIGGd+;$(X3>!w&mYv;WL9eGG`Jl!}L|Ku6Fr3b+^4 za1yldTQD*Pk0$0B*G?0mIQray_jPkZ53fb-)X$8ix8H5=G;d5e7VtM;5(vD?%IYKVnBpTLPyev!6H6P~B z?c!b0arPq3=;6zjCKM>J#p+PFeFIi{_?)cCF7OKpqvT_ofO1~TLvHp~v4MFlPO{_) zfqX@CS!U+LRy>7G3}L|S&r{`PXQS*fBTmMNLAO=oMpR2IGZ+oUMz(PT50rS^{(VC5 zXl6lXnz`{Y`C>7bZ76Bz_csq*!R`DnDs-CFgFv&Y53Y2;b+zV@qzm zU~YMXjQmi1f5w6KE=kH1zOuM8b)-sGjD@pOA~)SQZPM1wYz7R&RTV)r+So7hP<*}o z2vqO_sE5)j+a#f;fY`&u?ML*)P)<$i!GwB-->4bl_g|YJG;EkLWRHU6|2BN*k43rq zyG>Xw?cP)-Wa%s#X*BBJ){T;8G+X3utlzHkzEuTr0JVSKN?~mV1mx_OikJ; z5i8@W3NEhbu}3P)2Xy%^Cte7}XiPP}uyEtUjeJn>!I66NPi}C@W$1_mZyzhsya1)rWw(Q=8t8R#WhjKgH(*%$o3%9Z6B&jS0|nH9a#lh1R0Y^H5F=U zaN610D&ffGp^=7Ut!fYOp>g*$P$&q^(0NvZS{X*fhe(EwyXxuikgND$;OKUxf&$;9NO;$cK2}$ES8JSoM02d+8O^TWDpT0JikUZUQL{CW z#9g}K6am^}l*bS)oMZ-bSqh}S`A2nZIGH*u9M%I4Omgf#-~g0KovCdZgo+A` z3#mL`JC1(M1?taEV+&#V)S7jiZb98OgiRC~v;hlncQeU!DvHY0lId;P{o|dDU*wMGmW+%L^XoJO?FNnK( zmA}K#bulA~m@2$_a!E3~(|OLRnZ1S?pJ50UI?^-I2)JSV#M{lUjYn@Y^6Jtbz77~n zr@q(jBrTIj%)V1td+-A6eQLzZ6)vS1{s67LRwKBY)?Q_DbbWoCmv%AF~eqP3%oYYbpaScI zgft)iz;c5@SXA=K_Z4%^GF23fZ~yK7sFmggV_^KpjmTBd$n2Z7YZOAGoh;h{9Nd8S z-84XhBzG4%io_N*;yTPPf?r#%LkM|%#(%1W{Dxy!!fiud)Nc$b|5~PUW1sQA~ zO&0vD=V(?XFhk&R)&W-=_hGH*jfH#^y1FqcOnb;R4}?1G46372QPGsN9l_TXshLl^nuBOI{85E_=(lvok`L z!}1C;&Ak`b#!>k=J zS~eF?0)|#ACY~A}Adl{>kqCP$P@KOBgR@xiF?>Ps#>fUPu(}>PVz;9-0KFDZ>+9PX zL(?y@!urN2T@`3SD{Z4CtYrNAyaMNhWnTBHiciKP@eDHmRrm1aKq)rs(mEMZ!k&n< z=X4z_pzEIBsr9s`&hilXbni|H65jE` z(gEHbEUkI|sS9CljoQhbF^$@JWyqyu`ou7vCw9w}2AU&Kd_yv`_upe;G7hvETKhK=h5el!}FTah!Zd zT?#OG1J6mACN2}&;0qJyJU8M9`_9N354L{pe)@lOKSwCU&z!R_bw86o=1VZDYcj!+ zSHMFDvAKC=ld6f{SzcP&F0&354GW?fuU-mBR=+w6E8nHv%kXqQdhoIJxiea`izyYz zfMA3bn$143x3`hH(qff9R`G{jJp<&|t?Q##-q*M z`j0kndGF0?V!L;A8n)5FC*Jf1keJ47I!hm`M1G!&^?S|2Y{2v*u3XW$Gi{`Iq)KCY z?OrdQ#w^f(fNDwpLC-icz8#c48OB?XGI?;7)hKG#6m_1~k5TMN@KY^6x|um*=XNo% z(w#lH{LAI7%Bn!vdQO*Q`d+z|eQ5sOSgQ{XIk|l8z|@-QS=6q&l*krG{(ki4Zd({m zMyJ+QSbK9JdCy!zzW#?_mAaGaym!C?wP(^pR282iQxxB76vaGMCfJq{us^$3;>Hj+ zwHJSvv-lT_Sc4K2IZJiru*u)bIrUYO`>6!x2a&wCx1X_*`twaya?!AtU*%wKHUL5q zLmKHfjsce$pvF1^Fd8!I#nk6p<$D5w2t2j;F!5#bIn>T3x9WSPoA2-M6D<>f?~b5F zqA=T(yrG@vk{h7vWXvA(sQEpX_)&>Z`I>FvXEKmcyO`(Vel zy=lQYi<>JRC`r}&_B^#S4sU*03x68A7~j0|LI;fKdPoWdro}2#cgdKf^Z5Nvb=lC1 zb5XvUBacH(!?U&PR$llUCs~FLoUpPI4rE3V69*c`6h*>LCCLy1BdgIl{)zW7lTI=D zfs^OW>x1m0a1CYizc7P(re2RhRQC6k22UUcSfyP>PlmArIeC0a+td6UOJMVnQl?}} z@(kCU$2m~>i_X3*{<*EPzC5gu^4 zY;-K`jFNZZ#0a^`y549C{Icvozo^&{w{MwMTk(EzZT7wm^{V;=InBLyT_|vMZ;b0; zAtIm+%*?W`gCv$Pd(l}#`3+gKm;Ffgu`iLH4Ag3*t?W}TNc^YTsgr>3?#oXtuK(ZyO z4MP$wIImxydF;Q;>{~-VR{gDwxafa{+oLzPc}6nAu=2q%rNuc^Lrt|E>bvar@I3Q( zKIbk#4i-Tjz`dktO|aEV$i##8pR(TcfuuAa6b&!rzaw687`0XnK%c&ULIR>RQyoSw0)f7UkNz;f?lTf-Wdr^FhXfvd8F&#zQ8)L>t;^SJ4|aTk`}@@O3= z_;!<33g4@x|JcaZN$XnXIHG_*gMqp~H7s#q$yZ07QgB%Z+%pEX?37B4 zr|>I!-JvWx{meCl38(o|q3Zj~#CV5rqng->6eDn*%;{AKq@1;yFF1f5XH{`>@7<@j zUp`^5Q1@iRv+e@514``UrwDxgE2*R-XD!TSon`Ius1vz0s>nqCaHXLvE!p zm}P<(AGa$_Z%&Q)7n9C}ICRLS7-9t9J{q1Ts49#6S|H%IYpfLkF&K2zc#VFC zKPM%Dt(MGfILOh{-9_a4OuSf5ThBV=gH07Mwve407Xe$2P>XV;!*e2vyH> z0{x|4A*WZ5ozc3zFtBON0+bvH;d!PyD?xaxPn^#k@CVMW$HYzE?sn3)obqn?{$}!8 zGq&~lHKb!Al4>M8q7`HHFSFn;UnCqqq8?yb`r_yxn-qWf+fV3I4Hya*E|H9F*+4yc z6Ey#nV4`Hphu=NhAOC7lO*qLw-i#6%F+hTmRK z9`s&Rz~~>kaMVFdqs;PX4y3CgOgjt-Deyh_Ze+Qk)7DQF+OIW`R+KGrM>fPafNj)% z8gEC|GBfCAs)F5|CeAO=ce)kRFE{^H?qPX)rpHf{8ReGepPekf%Yr1Px=8GXj6Pt!gT!QI<>* zXZGgFHCB_=i}4!^m8-s+rj2P0)m2TfVB*F`&fl`L^rrPm0-4(8m1Q;aVTjq!b!QX; z<<2^_-v9*`>FSfyB1;YkSu}dJ-4Vz&-89I`CDYI54>JcKCn^o8&-guW#!awUG|{p;0CCP`#2p`UJ&(pD(^Er`KeWya8OP?;Kn>9 z@+-0yKnPeFXcYS%k~@p5PI#Dy@~SNj2?+E%l{8H(izn=*J3(Wi=m5v`OHJDE7ml-m zVWiO?y&Zewn$6|DoBGZ?5@x5!g6DH3p9Hy}0&L3K#lpn8y7+eoXFpKo8>9V~Vm$dvb}X3u~Iy>*WUJeGVqt)@n%#rnzEd83;$?*~xJH)5^3&aB~%@7v$p`&PbY2p|JeKPuqLy0-#s?Q${;EtO<@!j0U=6<=+IP} zNRt{B0hJm81PBlrX9TGhs+1rIC{=n-a0Eh4L`r}_qQnqtViF*v-?-1-`#R&Cb7r3T z@80=`Cl6WqzO~-=#$rQ*gasnv@R)Le<>_o6`bF*OOW$bvKzHXNBA zVX)#Khu|z-kU@p4&@T0jRkw47u{=hwyNqfK<_v>kzsA&(tX~4APF+vpM7#@lzg-_h zr3g;;fkV@qjaDh)Y{PQ69eWxIe`O$c%+Gn-u`gNa3t95}?Dpw#=cygP|J5ISPVCFi z?d4@|4~qQd9NuAeJJdQJ>pRuf+-;WWc+pdaxOeyc?|)D|*_SLco+cP5GpWbl-{o}F zEJbHQ1jDrUJ<`h;GX47E^?R^n@{8{&A=R8q($6muq!%3?hu#04RC)5^UA($lpU;5i zq(){M()W_0qfOw&r0Mp$a45D~Ih=33>K2B5zonVOi4;MgL3FJ$veV9dAE7E^PsRuy zZ$Mp(7;@KtaRxYt_&cMOT>GPgtwT|(?yisNn&+z{Q1bK+GW&eDVTvpWBUg&#(T3CSIl5;7MP`u=I<>%oR987BFW8T{Q8<{c(Nl4 zGzLV=T)3l}5{+}*?mH%M!chjeO&MEU1GQ#SDbP%lp52KSg?9$H&!%q0V6^Hl*bmV; zhw?a$;ey7W{h7RtYxr->Ca-61xuNzR6#J3uK+ONRkb6h$>fEkbb66)DdO zku^9wIexNbBRBF&V5o3i`$>RUb>K%ts&V7#t;9Kg!-urlx{7X!Hfs6_&?Prz3<&I4Z#}L+yx1m zD6*43XXSl4RXa;jvBkc&!x_KL{Qk!Y`U4-lYegLgn2+Uww7+o7t|e?271#egm0y$a zZ>szz6Z=o{{7sd=sq#m~^#2#UB7m<`fxTsm*8BJ`>&@b(&sCf;x);m)2kq^%!iXP! z`qY(lZCjSik6_Ky7w?vvJ-Kqx^vr{8rHaJ)&;|Obek2I4YGr6C) zv_DFl?bxg>vA<&?JqK;3+}#3L)CN`D`CJ%L7)~fa5GTu%5Zv!2h%z zUyv#i_nr!ENACX>&BOWJdc00)3;Zjv2!BuI_oT^Rqsn6qG1$Mc0RC-3{JmMf7s%t( zb=u11@!Gbv1Ih#lArr1QWn%by1OEqsHzg6yg6oy!9kTv12wec*-n%h@qBc!_QE>bR zU7r7VRk22@qDHf5&iX;w|NQUIf0ze-Zom9{D!-=O-&FZMp8lIEe^cd;%D=yP<^L02 z39?7X=e_>D`lPoin}l=)p#(01obIHUkqV^|W>j!ciQi!%zVo%W1?M&RK=u>hgAD=; z*)#-(H)=qCGqeD{L!>u>v^M82wdo&CX#C56k2N}RnB<9QSKVg%^)CycTRcPs&&_X{ zSfB#9_u&x7IZf9KDRg%lDVVTb*{5r%Tf+sdsI!q!x14AAD!gSAF18&kZ zqKcXRy2JaQ#%HWR@$Km7K0E(gx8~LDw0;kcD%#`y=WALtsG^HOu&HDJ_{yO%JR;gp zn-`1!6V}g{k+t70@}H`I{_)+URQDSr@n4VZe01cM4>mumS9B3y^i9j&Q@?YvMJ5=T zh+83aaKFt;KJjn6`ac8p)J0RI4AuXhIsf19^KUG|$O|HP3fQ-fO~1QvVY)%;rAlb({M|<>tA7u0_JDaGXkLc2VVH!E;&|yuL$En{>L%ZUt4g0 zkR1Qo?Y9x1K`z>}5B#_9`2$ZsC;r)S7Jt3?-&L*rA(GFxe+G#mSnm8wq>cLwdJ}go z^be+te}8o$pOM-015394{?~tKIfvgGf8J%|SFJ~X!_I$d*Y!Rlv*l@z{7Kl$Ur&7g z$md-?a`o%(|35RAywAvNn4H`Hg=79_e)$D+tv>u59{H{!;45kN#i0L_aVI|BPsYd#Qnp{>hrlMz-_%5wHz8O^+%BdW4}ADX-J43 zNzmcZs`sk_kw#$x(#}kC-t2krn5gKb#d!)BDDdwBb~W0&fJYQO12IP_CTZ-NyAofW z!?>&GdeFvEo87*)k^aOYZtWM5VeA(Vg}oDPF!Q9j2XVC2jZgP|6sdkuXK#4gLAu7R z+?V%M05xXC%u^D>dqx3@DRNrJ3$2LzZn-rb-li4EUT@r-s{>4N%E!HJY`~;Ur_$*M~a>pyuuVs9xhGqGPO*eNRW^ zW=l>zV%M1V?D@6O7F|#HP-OLoUtqic7N_A)>G<$Ak%1S8dj;>^@-)m~FU})kNlrpx z#x^~&BCp1aZX7+)j#?+jj$BZrk^v^dS>>y z<@1S`RjozAq#l{Vobt>$(0$^Fb?J~*vTYIFMzeUP;N8GVeNe0R) z@{Z!Xp&K;9r^NXZy%EnAR%H$IQ^t&h@&)$Q`+XB=0?c2G@`ASGBV{PV!Qw`|s~JdU z*te2K&`|m}qN%LJrZxsksXUOw&B8P^`ShSOElhg`cxU@1G#s8Be(STv02)2#c<|dV z=ojtwo(xa^MzG|&l3eGTt$-g|y&5rzOQ7!);(IR|tElLF<)M5xZzXb3V0QS1ua4B8 zQB9ja@7XzdWtjD0K)k>6`b=}z>{_f#LPK(D84cu77;lkyFS*Ob5TW6g?<0 zbQQz6Mo7xzNEjz};osLEpCgkv44u(3 zHr5^B4vEYpmSCsbj`TyVvt(;{Y4!C>+WOI}9k@WAIPQT~cPF%>O?CEhI-C8mA*`8T zL;5$RWCJ#}-RNYwX{gQ?`-(TwWz=Ke*mgpoI)t;H{~jX}e(%5Av5TMByn#c0ii;-- z>48df!-Af%n!(gO%<5H+4Y(#X=7X<<@W#BLsxs*-ucM&pv+VQ-N=Qy!H8=e+kAEb*A6u6nyTQ`wLZe58Xp44{Nd zQKlx^H4z@e`(w-pyn=nuQ$K?RGBApHJGK3O{N@|JBUR@-y&c=zj*fV?sYaIm(#RWt z%eYdZ?ApzqKC{|YiQ$C4mFWey5^~QC^_>Q70TFKCI__HlLmzOD)UkiNf<=*$G>-cb zvnGMdZ9c6(-pO#00?{smD0WaPN%aU1W zS!84nSwg=#Y0qie!0dFM4TaM`7J7HlTF!A(5rvvWr{==0?#5sH${3S7pwoEWY?MDG zReRA102FvF5atW`>*Qy0GWtr1mZ^Y4jOHlEuhpAQy~yJg;R`q^{}rQ`a7^TU<4-TI zKR;&|f()G;lPCumj*F097ucmsQc+%(vf>H;%39_=iPt@SOpAPhdTO&}zCyLxsqxWN zaJvs5swntWq-~z7Uy^5e*LI+!ZR?`4YP_10_og&8C<^A|JzlnWZNjJUmJ2Lfeqi?! zo;BAlM?;8Kno{rd?tSVm`%M*&0CtkO;g* zr|WQs@us-qbI@p`Q2a;HADQCM4ZLqFH^HA~i>vee<|bf)4wPz>KAP|-gku;!L?Law z7J^;7&Jv9bZxFG(gKz4O1l`(ljJOxaAF5rDNCloL3L3NCnUrz>0`>0cUzc?BE?NDo z!P&FQJ6x>x?m|=p?Y`Xbl6YDxeIj03!Z7Vy#9|RUn!G6ZIk@|xf11X zu3DHyH0?O!?<~!qc@=|=;mYaI6ONa*c*mIpU%J`gZE=-_LqMdMFR>O$T^91y);?TgM(WBrI*;=P*3WmBV%7U@n_)JSISFipaP>j|}X}`s)NgQunXtIB* zfM%@>PG=TD4G*Bp1N#vuCjz3zAoukf2tQX>88&hI!DIiGs z5$7?m^)%j)ub6I8HFaWnD#|9LF49Yo&p~JjePw};F?U_n7=j5ILnFRTo`zD2diEo9 z!)oMGi*K}eWjvT45?xitXg!ghK)1mVX*`FTm=c8UnMGD3%x&~n$U5%d%}33lQ#?#c z&?%Q*eg)e#zf&X@)_-ohw(I|j=s&Mz&wYF0p7)W}SDl!7;iL3aGrzL-sqJj3y6Q!$ zWokN3Iw&}ex5k!M0JR=X0T4;ZnG!M5MywS;2_pvyG5H+Bl-1aT*XpvDe;Fl#OHO1A zX9ry;3g&h4uOg&n95d~VG8)a;tya#bpV3ObPXPZ1gp`xtsiE;)(%k!4$(4m6ofu~F zA*C7S&D`dt`wAw!Nu?!4BlZurD8ZW=$kYNGvevEw08F0PoXAu?qW-Ckn`zQFyMGef z8f>ndznA>vm=||I4KsL6;m(4xkPj6)VdEn+Gpj`Ab+U7{rY$*N89>7A*7h;06jNY> zY*94_X+PC@qv_q5b6DaSDS5M`w20~6+FVKt65tmg!A8Mo8`J}2T=>? zf(h=Tbf)=Wo4XO)aWE+mY7~8b-`otG8^QJ8>XG`!zq~qW<7W#dsyM|=KpolB^ghPLI3fn({nphs1?N+OYH6C5u$oJy z-NCdQ4hz_E!G@|EH@uezcnM=g5fQLQ5{yMffJA^EucxyOg!6Nz!vz-#u1+?Kr9jOQ zIhk{OBlz{IxJ9lzGDJhr(9JnHJ4??7Gw1Y!+PrW)T{DG6F?tpow zwxb7=yBBIl9F{Q%HcXl4T$cktR@4_q&z-4=L4mO@OW!P z9;at8yk)V`wTSn+k}XBaNd)hf)jHV^)HvGFgK9aMQtd%_=PBzH$lx&|>PVxEgdLKU z>ZHetuYCq4dqQ{KfO~ieC7J3Et1J9og*uNSI)b7t6vU<{kp|Y-oV=P^>L*C1$?%WC z+uB@GiXVvjr23hPTJ~Y1A4qQEc=hsS!LY1~BgIvY{}e%#1UdglGJd zV={(34%W=HwHPf8RaNNlrf(5zk)#(&IlM%+zLt?}I?df_$>=61baPxc=7r5iy^Ym0 zz-;p~BtP3*Jnl}Lwp#l_?4X}(`X~AmQn0-0n*nXc{0U`~zC{Or(0jZ>FKY^O@d=4{ z9)c7T#)^ z#dx5Te_9cU=+9LYDgH>;_sKn=?xXPax=@LwQo=zxiLEiIm#bY%D6~PycmaiHgY+lB>Uva! zd%!DRfKnB4Zg*-9~-RF6X9EuEe6-@J~aQt2}R26w_meM3} z?P|*eeFy%iAt7q@xSW2Z*3mrsJcFqap?NY5aA8lCLkA+07IW+Tw>+;$3pHW)8xCF0 zaq4)z+p$j^JBy+Z6}Q>kpVWx=GZhkJGGYQ8yJA`VGqcmfXtU*wV`#{* zls=)*YG_C|b!(mAL;}b7Z8@1)k z4kM>S2kBBxAF-b3rpmCl=517V*y=FdGIhnRHawp)lZFy!Q%rr#?#-gnVTYjPRS}xd z%iSKz`q9Zy^k8-@pDVRNg-!nEp#M$6mSEV_sfhzO^x6gEEh5VVn&0 zEW9~=q9gBwD&YE%ORya|zBN2IyE&|4!19WP;~a<(Q1LX#i{)FUlfdCH=Hak0ow{q-l)j;_h=6)R>wZ)bvj z<458K$fGNLt<=1zWhZhk*b>WM;7;As@64WYb?ly`sbRph`S)EptbMHOD~wwxua*Az zwIb9$x=f~Zyw3NH(YNZf0WE$LS9OQoG<>Wk;M8|V6bx04fqyvB5uCoP61hM<4nnB{ zWC#0kcNCs}lF&@cOYJfVXr`vb=is^5Zey@TJ+u4{@7qW;P1rYo3qI_SZR_b5?Gznm z{zkPNDFdcYMaiFZatNh4d)jyg0)gxpm!|hi8qdjN3gNZ{j$0`ckuW#VF!+={PqAad<>=64(;hS@ zNCMC@C$6e}*ALQ-%_9Kb~|HK~rIPva%Z9CBhbQwu( zk*5k5rESTK&=xf{p>rch6mHFkhWM=guCPk13ftnIoxtZDSIU6IbwN6%^rx1TsNS0%dyM)4``%_m4`b>qBmJ1q*s+Y{)2uY9n=c ziVHug#ecm%=ym^b9VT+8QkdrTS)|szIzG=0Xrb0imj&&5-vSHHgL4XDg&yR^Nw=Gk zry2%Hb1$Hi*)0!Kqxmg5NFPF}l81eRAXwfP(H|+5($6+0WBgpIKnq#fJD`T^_vZZx zrV$GAWm&ydu&Q__FpKXaK}l67#_AZvTM>k?3`ffWpP z)+C6>PDhbb$<@nY0QUQT>GHo_+Eg7lgun$ZiA)Q|IT?615GcGAB#?KSL)RvK1z0jSJIc0j#a`nC|K zO_fD;6ixp1XA% z)zUUP#3dqxRq;;5Gb*$38HdPuvI}=-jWV2^h6LqN2{D8xn=1@y6}V|_2Vgp;vRZmv@MI6t9DbI^i(nJlW~Z1UJBIPit&Sh6sVkybYcrvzzkE;D zcSlKOftKU4k7*0oGZhIW{9}J&Ox1vx!o)r@fRgfHA|GzAm!xHmVj5~pjk7E(DK$An z7?!Xf=YAS4A|NX?)@e<4^pMkdV8EcIyhSy}QfqVI@o}HHzzNL!Eq^-Us>9iW8*Zv^ z%EJTgqpIr1tHNWdBDJjfLk`{C!U3#}cVqa?+un^69vXykmPANwMR+D=DPqKpoSAfACN)vRDHH91G2pX=C>l(-gQjwyu^7PB`pWU{gcu_dnpi8@x{H4JAv%$$&$Jinl=!(R=S?o-9%Wc;Y0arHcofyd^ zPSSb>m1FGaf-$idWprj<^=UK?%#lHkz!qeWCChuRT@^|O-2%0Tnb-TOd5^b;Ml8E` z_+99d!T82sEo#zfB3hBwk7HJlyDq+As^1f?Xah){ulg;`+aR*~7H+yfhs%C<@}? zh&g1NTlK9z&f6?@(K0prcJOKov#>kjN$tHb;Wa*WFsM1e*#kbwi@?2M6F_gNJN1B_P1BK9t9E${8UXk4R19V9F_Xb};nMq9 z6H3573O~ghk5qpO{m7lAA-TwA4;%uq+;lB!X|p;fhu%a?(y8QZR_}-2yfH9qr=HN- z_>vRVPw}2y9^7|@?_!Z^jT~>)YHVs)tfO^zFHud zITQz7z)DJJlW7O-6qXe_U^kqb4GKWPF6AoNE#0dlbHYByl~X#o*n}N*6wBnROiHpY zo3>&BPp1imkpbQ}TIYNu3up2Gzx$qA^^WI0!;ZO-AE{~elzxQ!Vk@^0!dIydnBJS8%7$&$m7X>#LUlBB~He#4vNjCL$o8so0?}RZM zMVDRc1ImOBp=Gc6VUXnwtO@()djJyYmwp*$o$@Si-It-ekUJNnF8wol&q>+Ro9*70 z1Tn816LC;7ttCG^D%9RN@6D9Wno!OQMwr093^>sry4Gcwe%X}r1Y+8VN&?&?&)e8n zzn@V&CA?M7|s;)@%wEk z>35^-|4nH0oN%vB8Qcoz2eW!l1lWyI4@t?cBcJM?zEeN1)ZGR!ep_2+X`+jal|)JC zfnGrwt_V>HMi`yyo<{ZajF+m z9efot0?nE0>0sUyD<2b4YG*{(rD*1SV3_y)$721PeHT9cG@kx|q z)@f|6X(=O~?3anA-5=CB^K3x9WS&rR<=XqM<1HeiNl~kw6?-KrKPeApH43k+VHiG= znh=<%#g~ZG=1@S>jNI;k$a>zzw3Pw81hu@}&xR;h#~GB#DgXypx<_e>nI7wrA$ zCB3iP9{@a%yzUiaU>H{ICJ5?EgtN-yg^b?K67U$fK(=Os;fHEALPPm^I5hj^idRq+ zbLfSS@%syV!>KK0`(WLxJ?64!&j4PAhG6ayL73~xBv139R!7>}twt_;d^*XW+sBO@ zMl;0jCQjuquMXScq2#qo5pcW^ddK6&DmRt3+AyWnOO)I#Kiyc5OF2e~iVNHL(HU~< zSZf958k@l!9;up@>MPRQG5KN1r+Ws^U~@~+!Ey#6fh8eP%QZaR@6Ct%tYL+mrR}yb zX-YqT;^94y*BYD^!`(zlGtL*0*!S@V=A%l`Jj0=0bvJo6xO1!aEDO%V$HQN|Oh=iA z&!O3{w+j1LP!n%kh}_X-!uGHHnAiY`aPy|sLdmbb`BUdr`&-$u-O=+uo@?l&_8cGZ zUt5667jC&VrnKPJhuJOsZg-=-x8k9P*)4OJ#cL(#Lz!}C)_FRR57pYHycmoAqRiP1 z>RR^8+rf{rUzlm1OzoFE2(Qdz&UI-VVG zcM*Ve?)Fm3Jj#pd=e=dxy?=@IR)HGW;ucX#HnJ~?Je5u}HU}7H!2D#ycI8NK1?4}& zF6}R8>Z+zQw${+4B7okhecWMJrdnz+o-;V%B=6AD9`cKG4R<(&uwG>IfJ5pTH=Ukf zc=XGIA`b(UmQQIKh1KKz{9RQaic>#E$PKPu9XpRyK4v+DEpo7Es;{Jvj(~Z7CjkGT z*s<47!bsOfHt(lp2B%AUcM;lCydzIFmB$+&^D*mBY>ZOHobqR1Q_V-T$v4h>x4AlcPXzbuA?CMh?AEwq2W8;2xbiZj*J$Juixq5U-yKv*|jb1Te)A7-F~C zkUH`&pOvjBE1Tc4GUN;e|~@~^!j)Xv8LLPPVX3YsT+T_AXBLdHd*`xRKDs*g%j4D@TirJ*&Dk+TVwvs!>Qhl_O8zFxEms z(dntWC6LWJ>siL>Ppcs$1D-EM{U07x8x1C@LrZYV8ezU>=jfsiZbSn;t_N>U7t#)X z%BS9sqCT5vEkaW!Tk9^J- zF5o?bqRkHj#{FXoPC{LF)d)tiAC-M5062S>J+tdc?t2+HJ#oKa;n8kzdu4C^*}|d8 zb#b%kkDFJVu8<10HuALqUN;G~O`+QBBj6x2F+f0jr5Aoif;1ccOXpyGBRg;M!^20W z=<5Ar1KH(^049F0#ncb)%94`{eJ^&H*&9kE-(jUWMFtxi0S&_x6293b9c{Ke_Bk(I zWAMsFT4#U)JLT;?u{$-*E~}yA?WYq(MFpg6X(lp*Xc5{Cd)eIpwpwk95qWm*mKX40 z5Bcm{oj+yqn=#1uDudg0$w?nwD<0gKs8w?fa5KHf_&`whtPYRrFIJ_0#CmOemQsz# zDA}){-4?j)1K7ME-gI+Ea)tx<9my8%>luUGv#<<?zcoFQm_2Na~XzemJq0p!Lr z8IoKaO3m7m6Kt>3VOD~^asrUdkK|*0lMH}3r(BprE($)&QY7dq3-c~d&S!C=#50-i z3_;G%#_4ekN)mRQvf(r>EPtWPO&d{kJl3Ov6$)WT&_a;W_amOFQ+v`84El>OXWIy{ zs0NOKAoCHC=XI5CI)*dE*tF-OB<3N@R--US9*&Wx-v9HVP3)V?CzVt5k!B4EvpC{$ z?H4*9Ugd0MBm+JP7v};(n?SMD0ZE-x90h|QROUj|hb0@+oMI`s#_URtO6x&G?Hw`A zA0NltnSI2TRyKrnQw^aF8TB&*TeV&>Hdpx(Ot_DX<#(4KI z+EbGA9)X$-Zup9VV(cWe)?j>Im3K@#Yk&QlTVAtO^M9b6snDXPx+hW@_^bs@gOAQ}(DZso^zyCk%>f%xDnC)s{pmpIV#rDXieorRB+`Da&)%M-uFh zxh^g;eBhL3VHCn|0B3dkigM=4UD3)S7w3i>lc=BYx(0+qbNKfF$KQ(>i`T-;6Rx)%hhJM0S2Wr{X_D>N z&|d4XsRdd}Wa5G7v$IZ6@B8I-i2?#YkR96=vo@nXpyt0+YhS@IU=z>pdbJyTyRZxj1}_PF|{| z&tlDa7YO4| zb8D1K>MHQ`&86L>Q_)Uli9e@j%O}Rnsbz@@BN;ed?t&o@%7PRg@2BtagAy8GI`6a3 zx19D>C%G1~12c+IUQy?)l)s3y=*Vu_hS*nRuwck$&cWf8;{{AH^tz^@VMs=n?)g4wG}c3+S0kOD?-ubw&?(oDeyGqFuW8H%L_&L)-UO=G!40%Soh+OWlVi#=A79V#i zU43!q(Nu5gDw}h*FnX3>xP3CEDI9$FL1x^Fv~W!u2Js4n752X0SZ%!3?CI(q zgJ-)`b@dny$t{2S&Iz9b-^6Gr;ir;VP>_uBT;-&YU6r9lUMjFJyA~Pd^XN$Fvr-xy z>7-rBrDXlkefm=I{q43f!I^-)H&6ZqmehFK{cH2iP&Eg_D;fL(K86!r1}xF1tKf41uz_TJ_@xhKKBFtsX<) zFmDs?5Mu>A%`qD2C|QvyiVD>|P**AQaOoou9&#hiGD}l$wpkIty3VM^+|b(e&8E2Y zPGK)=d?itH{1A*EXOn1G3d+dd6PTlMA_aKnm4D(RNI>$B`WA_bYA(9K*-U`#jfE~z z2;q4)F_F<`BW#M-M$pOeD8bB533VNESGOPma(}dTskj2#KPie~ zGTJC629*#6RIy~Khr-JEuD%FD5VKzgIX5lbUqkP*Q_PQkohKp0=NeRH#pKp4w4aN9 zbe_48O3~weu7XisDr@augYe(9>?u9Kig@xL-HHl-0O?QXNtgCVl)A*>WZSHgBTDp)9eu4}TR2JQ zJm-$NH=F@<7&IF?1ys#dCDp1O8uL1SRvX$;TIJSJHbjj=*#oPc>mqC_DJ^BCZ^{c6 z9vq|@%lK{tcBo>od3iNl<)*W(?NDRy@A6JZTwsBINHtV@1*6n)Q9XAD(=+jWC*7=f zMUiEsd(xwiM%Pcn)W>aHzT@m9W@ql0sfk=}J*uE!4 z4#D!Iz9`m6Emz?=f#}7@fymwpSYMh1*liklWnqmnyYZ}>sTjk3X#fo6AiC)v?SK;C z(Re>_GrQ}3+x5Ej!o;FXm7VB7E9_vh7y5HHbfDS*NHgyCpTKD?VTFS)hi#y`^6)5c zKatO;Taml?uDi*6_+yTGl1}TvPt;QC0}=|QiNH^7SAZN-r=5&6LdMJOk%LitY_OEz z(RWee4V?W|pp$Ct^N*VuX*Ucr;^-U*d)CE39VkQ`(l~2vC9La{u;H6%tE1JHwTYhxCV_wFg1{$idrz9uc4wLpj<+U4)P{#9w>=SPTo z1Vp+7(Dci>FFcw*br3!ej^))k$bK8r)H$q>BrkK{2QAao)X|v&=SS~b&dbeKiqt1s zlcu(U`Q-{RPF+vX$%#6*LwY2PBVi`s2$@ZWC*RhGIJZ15y${b82%2Aj zfH!Y;NhksLfsXbyFz&LjrxbOw48wh_4 zn{Y|#j#KF8m5S{3i`R!~9U-x+702fG;eVDLzJD^2x9feUm5qJ1YU1bIu)AyKO8r~kw~mE3PA zOj>se3c38x_rOEwxx)HzOdCsUS=>ze%V>?>vCB7Oc!NhlOIP`7<9dxBa&NI4?yH3r z{A$!c`Qu#mx1x4?l|i*HBfMWe>kn~Jh>55XE9Lmhk*%?uTO+6SJa5B1@kUzy@g!wd z$^)Ge+}=~(Jq49HP3Tb8a_@D+Rwc-D!`8XUSEv?)nw8bv~!8H0?$Pqlu%yKRN-_c75_Q>A}ZHi@EiI$`$S zKe(=mXWxz-r)2a*;pg1-zdQd(`cnp~KTOKYy1PN_&b!SNv%GBP!H&~H{s?sggkgJo zw8a5W!;n zOW8KD>2|o8fXhYi#3V(stNEL?7N+|Y?Ph;uv!CaoP6NUm=kzNl7v^=ri*ZD~v$O7q z0n61&tUuMTMiudJ0Zjus%)SOfCu#F7+Gw4aRbICQs=07LMQ2I@hzwWz{MJnHwTb_w zVdWe`O5`G9iHe)Q@H_uRXWoB_Ex!5t7Xp9-z;NFtV>6qif$?e#iZ^pr-h^2)f&X;V zdsZ4y(q{K4UEN*+>Rr-z=)v%%&Bu}ww>fO@C!~{9gj*RI5osdDRfS7fT77rsq&N8$ z_S;=4k9PHKNhp4o(zqEG=2H`VsK4b~d_L`EQ4bntf|Dt~;;}oG;Y@V>4$L^eXKAR! z=yC1JJhVHC;2`xZcfyx=9vLXYV9Twee%rU)0086|Zd}nIW<2}{qCMndT5je816Pdv zDuxi1s%|Lc4v+O@>=|Ld7Gr$&4rd3SjbNl!6V)4cy~V_Cx#O*aN$S;4M7KZV#fBFk z^@0NeV^WOpoYzw&V`BGZKPJAk3gmCRkB?TL%PEez>is_7J|(*|9P~r4+f`RwbwUm* z#KGIFk7pXVpG@F{+VrrUcgJy}_rG~{|h3Z^S4xiylOpw7&UJmgqL) ztX%0GabY;D@$k}zHfg=10Br%|!wHQC=@x+r%{M|L+{v`Q`>8ffx|weB6rWt(GdHjr zb3e)%vJ__ZPzGlK(P~J3DYzYZV+I8eF)Fq5@oB$lW`ss(<|lBlWYT4qoH*O{@wxRe z;XZC=GM4Q$REp1UTh)UMM}s>m>lEUfBgyU(IKhCVgaV#W`y;8DXMi}Pr+nIzv(?t9 z10BzFmQ?ID%Xr%0BdgWZ}o$2TElalh*~}CI@YAhD;Oe zt1_~Gk{9@US3K2vp5y(>-@)y@3Y-<*^$og1dG_I>?BQDskoU==Cr5udNsKqz%e=o! z#`gK4=|@ZL2F)w3aD_IQvRB8wp}S3?lP$x<-L5H#It9HKPDj4e1snMKRpqSM)EkIu z^=hTL3ln+aZAKj@Sz$^~^;Q zuRgj`|G5Q*cYkuh;MvKw^DRa4DOS~8TRr?D0$HEd_OPg8D0T0LY^zJfyfj$(aiWrq z!IOtidcy1yNdDP1A$IAmDc7!QM^`w85@|a)9GHest^w@qZOK_nWX}==%Q@guGq@4} zJy=G^)<11x&hzg2W<}k$Z<%d~kf?SUX{{|P07HM8&bTDTuQ}K;`LB)6lk6Rggh1y| zJLkfxz_c-=m?$@2Orc`fM*m3BTy37T{&d9)oydUJWrGV@=am>7+$ohCK4R}kYp`&+ zUHzbamMuZHgE#wsHUvB)m8vJEw1u~^8Vrr5Y(N>T4&U;*%79ugC!G7P!p%A7l{85o zre*qTHYe-Z7sJNi&`Ff8u><>Sj5AX%wRouUya;hsYMIm+>bB%dl$}!hYeeY8ooQ@@4laFfopPWAy2#Nhk63;&HnT>yEr(CbnIjAc$GgMYXSAS zUsx%LO^lIg&7Dx?&a8Ic8@927c<=JNGcAcuwt0^ALG6vxinhPjWe#}bKEp}Y_$8w~ zbtdDRK-bl_2;&-~ri_3}dJWQn!Uo-m`RKzrhpTf5XDfYt$)=R3BTs+*@y z%N{L*ck9viRR-67X`UEra%!p9_r&-PKDRL|4V8h&)mN~tv=ZBn0F*4V+(=tp5#;RD zs$8c}m1<4qD12?i%W~Fj)?DbYjp;1*c->^`Ig4XhgQl9<76LJ+Mser;L@V7kJx zkC|I$ORU9JyUW)cJz{IOj#?d0HDmwMG6~YHzPvB&+DN^Z*Jx|BrvtV8IPgR6VD2PD zdRp)F1&68qI+25EFCgQ0Ez`%J9zFwjKT~tlJvZ>`=@U16a1o>_hvBLQ(M^{sp|_Wl z^ow(^pLTj*z}V_?z|R)`W^Q8A@uthlYU`bT_Ng{KwB2MhINkWbwq&lK8*H{r*2ni3 zoa{n>F{_*X1eu+^biaYM=|yfIW^gqUznFOv+XbGP04U{8O~$bBuAv_YR^lcf?)igC zx&4eEC3`|SDUP7$N=J7~7LGe_W*A;=Q4{sQ4m4Ti?_Vo3PhYA>wp*+0tuaJuA&O8& zx;SVYvD_+~L|5+S(|YYkBPj||e6uLH^G54Dp?WXo2 z29k=;GJa}wY{H$0MRGj`m0^R=?`L5dD{O+AO%+|B&_iv#xKlCAXtN*kYJSvBA;LaX zp*P(zW_NnE%9mY0e}HL%=0!TsAY{Gj58f^D`)p>b?#jK{)(1(j{jc9aO9l;dzKxbw2x`bG|MPJDt-LG zW>4ts{!9~D{P4aTYuV2N$3M0e&7Aec&pn*3qjPNq4N?HRaWAHK54~@#VH;8(6X@D> zYW6WXJGT00onsmmziUu{)ND!ph%Cc`qY4g!dv#rtEH?7+s zYJfMF==A@?-h0P2nQi~VV;LPsMHy5;nj@pACs!~H$7%5UBAUzONIsrsVsEHvK>_3eNQnSq*lI0H==C!y?wh8X;bUp&)Aqw(wM?)R<}7 zYSoLgkr%Y8yKfER6-~k>@Gg^q*oy_in&5qMjna#Qt==~9;Xo{RVcaXq^tuuAjDq^1 zH}_0mSs$zX=~@@on=fopYo-h-NR}1rFGZ7D7j0S-FNg_DLjyK%YRyoX5Oq%y=hlLa z@>-V!r4CAiOg)fC<7jHxcxeDJa3{mKZ@hyWW|gII>ZUsC*4L zXlUp0tcs<86P2L2CAfwjNZHr1@$hm`vD~Nb zWYv;5nsN{7fJ+zql(UO$Z+(zmb6BUVmgdb?D3nCtk{mFXIgivpB`Sox$UvZrP1)(x zJi%j0hjrud$k3x8Z$HkR0#043?V3tGidVbQPJJUdP5QvreXNuv^^!o$>?|Bbl;?Oa z*N2&v7HLlp#WAFXRp2X+?Ew=zp7h4#KHf)=eRrV<7nuoHXqQeAVNW_!@kasdl2yA7xrI1+neMZVTvsv21HeLpgdL8*=Q%NYMpSnu-FCDX>NTRvXoi zwC&$0;{W_~Bf3ei?y=m(xa)aq-Z>1t!8*4Y+6T&L;T z%P;+U9E@Uh_;#69iKLzBvb+>jMSbho>p-n}H19*qB7G z8=devRrtW}C@3#BH3_>#5`BQw5g6y3h6x(aZ2_3Y@?hvKUDRudj&THP{<*HN0q z0K4e#90o@(ianl10M#lG?_=tQhmk|EK4ZLh4GF%nuf6;br(E`)ftL=qiZx!Fodvz5 z&LJRi!oxd@_Mc7+CP6vLCOJg|Xe18%$4YU0)h7Px;fY%CPjY!XAbT5BDC8A%XRG5 zwQ@wHQTUyxOjH7nSpb8o=Ze20~Ez^3Q-j-}}~ z-wb(n;?SYzpwrUyV|RZf@yEv}QKV5b*22U@(?T9_nW`PjiLyS#VHf+ARL-2|$gDWk ztsup-7sA4G_*{AU0>v~om%Fl;t1nmS5ttE7Pk*~U-od~X2z;|t-oCcMleczri)?44P&mEKwqzq z;57fel4xs%T+t{T50nQMs;K zCGmh8hZyOTXExlM7uK~O(P@aFr{^)?(D~)tKzl}mg>l%Q{@0Xcvv9UeipEnYF8Q27 z%xdOJJ@S%MEJS`-ah~+YzaJL=r z3PSw3;84}X-rF4WNSY;s7#%X@&JCNbz}@bP{?`^O{JF|Wjl)m*zY2LMu5)(W;)l>z zUk;{kS_7H!pOG^={tmF!4uf#EQ|QcNQhnM`5w3B6iz@!zFU?xBMqz>#m7?ImTk4+_ zZ#v)GK1U&dq5j;dlwC_$DZ>pLS2nNCk4Z)t3K!!^MLA!hCLI3LyJ6ROqu%~JGd&Z< zS0^@XM4fooEMak0(lXCK%?Z(qqsW&Wnh!;)5v~RQ?42)Cx+M>QC)>oXliK^mpZ_xgrILY6j#yWh z@9U2v1!w>5vbr~}`CBwiZ;fnf-=Hq`@{9SM)0~ZH6>>v-?q+in=NGrO@d-A+IM@9-G^9sNhXl#!BJ1*kNfOZn#a zEdadL@M%-C58(?R?s`A^83(hk+uz4b`apj-Y|K}BBdK7~d%@?U>3@-FpUmQecK}lO zz)dPt&(GSiz8<^%A7$IE4H&ouu5R>GYQy2G?-&>%gMr>{d~*6*dE|1#O|)2SYEvW1 zM5ZrB^Ghl-eI~q1m4M%6PdfFfnmNA#Fpad|mEINqkeeSdhi9Rg7QtIB}kKW$h( zZ2s{-x8Ry?ZIjr-dK3F4@ACOT|9CR}-aq;xWdF_q(dKo_CID$QzpC*|{P;jvAJhBE z%i+H7C0VU6_Fra5K9;lKD4OQ!K3&quiDU39#l zutfE5>9_p`!rJhO_?v%gKA7*!SZBt^aa(fBj@R|Gktgd{BSGMQzwP@m}Hn zpIiA@eE+xHiZ%hP*H3yUey!f`oat&+Cj4OOXw7jKxZk$Xh3K>kzGKp`o+q*5DJym1 zK+PXO}KznDFXi=^xcPdGy{N`gXIN|Z=)#Nd;o#C{tnk{FA zQ_V@@xNMDa)f@KOQ^U#?*%*)ecRY!d;mx*;QP_G2Z2(&*U%ag(RRQ);r7a;M zxNS{7^i5wR5}ifE2rGw6tc+vgcG18$Y@5B30pNtC)2MN+X=HE5&0WpoTZtVZ}7WJY0PF~wgR=;NK`S3$W^w)OuWm{{y z2UKLh+956yvXL8o>`Bc}s}vmftFf1MHs9ah|K^8w)6@1O@A#_g-W z(`oWf3zOqNd?!|RF0IE|T)UA$mYThjuX;BX@p{YaY0#P3aGvkopC^Di2!HEVi+F(r zW+5#y#Ua(zaB(hS@ogVwWFM@%b3D7^7y)wJtH(6VmN)L#D@0m^&NZq6xNO+{33m7} z^X4+Y`Xf}mtS)BQf=5`WqBb(SpUH~xQt*zo49+ITUT5l7gpT?f7l@i>4+42*e7`qFeuSFty2F~#sEnfx< z)#J`?=gFh=sU3M1CJtzK=zhoQnX+L&Ag`j}u`@YPGFRR--GSAm=^OKN_TpG|8_(w? zR!aH5(6~e(%$Du6A&q~ihhJZkK2p7=0}_D7-E%zoa{h=vwJGn&+5)OxQ8>HS5s8bH z+FLdws5q!n?+a`0FcYsEmW?mpls;sFXDk9{Pe{IO64SFo86*kSy8w-i-!yVzXa=1= z&$`l}{=_FFuejky!(xXAFzV~dGD4l^^L}NMoG_MwP9u`zwn+&hBR-Xzj*AQtQ1-El zJD$PA+Ge#I1J2y)d|e3u3#|NF{Zels_Ir;0Gga!_px=iT!1J?_B#fq|NgT`IbcRjg zpG?#R-)MnH3VHuxMUn{s&q5-@V-b)-$6bLL)JZL^ z!BzF#o_I0Y=rdDwX(26?R$*rcAe~0~NMxpCZp|f~EZW#JVb+ll{5&@jce#_P1zMF< zaryx^H1k59BF-pLQSs+3b*@yoy=>MdBf?thFmD>Q8)1xIMR`50U9)&@>skJ*3|Uej z$?Z;A+SJ~_(CVW@BMUbsmS0&=pUtA|PpP}yAVc~~8x7AJj$LA*nKixywsYy2tF42y z#-apF7z^ovNp_QVDZwY^YB+iq8P8FO2@C6hM;83E(BGIo@D)AXmx?>>O?C!&bp=*T zR%NO^(kWW1Qz^P}T-Ad|^r?*l%E!+3JvnIUX6V>u7aJLC=V73ad%`TKfkbhd_mUXw ztBaGm!JRsG9)p}I18iAINyzCqDUiV{5nXw^#dgu;Te*uOGD}|y27%F%dOOqrphWy+ zofkF4ATCSqM3$w;8rrvBmE>4vN||23PA^p*s`XWdTek>X-8GcUu5#>mfx-@D+uLh0 zYL0c2TDB=O-9w9ge60)>aJCuJyX{HzIzdYXLcuiKftO>b*Q@1pP3@0a4)#KFoAAkf zk?dmn7`qlgb?qA#bp?w!k$M=3x3S%K)?RUuy+cP>^Xxy%K?IY;lrp~X8NOU)tk<`0 ztx+OEIf-gG-k?S>@f}I>#syKWF$1SbsYZ=uv&%$ZoCY)uMg zXy?58tQh#;*y^iY8~tV?3~&6cD=v0VCpB>!o;>~`e8b^)=kH&i>+(X&Dte`@&qQY1 z2c2u)ZsA7H^0BXK5vHjMexyo@;LuB0P4ytMMdYvC_fmHq_YjVyX|KM41MR?d?$|}#b%*;u z&ed9)qiD2vR;N%bY+3^5yhw4BTl^yzTjtqCpD!cOWpv*7m39yX(K6NOVrUEFwa2;p(&d76xft37 zLZz+?lA4PuBP>Ky;%Zoq*b$aQcKzYibk(q@?b<`&oNyuM6dWie^gK_cvKI>OzhRjr1NjB=91nfRS|z*p7Mhd2pB&n)}bzT zD8%6$%OKt@55H3F25rA-BSu)T4&@y({kg9%qg!iNKB}irKFLAApqK|5WR@w zM&L_bY1eGh9U$qxd^_23p-YeVYz}?_uCnf$$U^)iCwx?bzTjAiu5yocGKqy3fhu6N zhQ9cPsRDn>dj3I8)L|Tne_?5Td6jFGpHkNn>*V2XGRPSGRw8FwB3h*40$;?B3SY&$ zV0dYMXYp(4wN9fF*_r8qK`wqUQE3oL`gVy?~p+Ipxvirq>tMIU3 z=ziYob%+tS{xAbM1HX{Q=2Hdsp~YMmGA1*NB4;=6lK(S{0XtE

    R$6-7m$=Qm5xY zT0PMr9Y%6CF1f5~0KewZbW(OzEBgMgICTLHO|KX<^hYciU|dUSnJsMelF|~&_9yk?XFixC=7K(;=Tr{GwFefqwT-U}7^XOa z&Kq2rhn11vSPd&_KCFpu_R`G4_TA9X!!ZLq}r6Wou!+k}Hwm zjXXqs)`4AGZ0|w3VtA~4BL`tT_N`B-&-vVre%czbka-aOb__vYsKs8)H^{Y-U2sVd zXlO8M4!i%6e|~C;c)MR;r>lsD>uy#*(H6*DlJy7-X+f}x+>DEG-kk{HT*&>!vQcNr zGf_FTGQrG(NBN7k^32Q8aQ%6YDPaU<@zNgDTL2rcYNalFHQ8KnW2uFRAJmb!vZ{rc zZ7yhB0D9^DXvwHDjO|^%zF8*2t_k&*Ip>1Lte1~#_<6xw5RuvA4oFL~RQBF=mav7lxFw^YXx7=>DQ#>6YV zW;~yFM;7HY*n5GV?xTs?R|jEX?qx*wtno!}^EvcM>MFy;B%@+>D6&#oOUXj?>yUke zIu+DX7oBN1awI z^(u{5oUgv1gTwb)yc1vez_BosYh3__QW6=~@9;Jxim*(Su}M!Rbk6^T^JX+SFa`U$Q#GxMhckN8!uf;_?Qo%viZQ0_Q?^kpSaQR(bC_?=F&B&gqp?uDYg z!c~Z>4)zat(CI4$!I)Fs9ZVfme|7Ezo=4%Qo)E6*%Nfu$Nj^t=vO%hn<9UA7)qA$? zZ@B(Ww{GpX-0}Seea4lf;lQEmju2hY7CTPR_0B|?QO?`Wo|jWMwX-V(jXiObb?CbF zEA_`)A)GQz9TpK`W?|H@)l2n)JrqC2vm+~5s;-|I(Dpyz>a#K{tY7N)LPj%!@0V$@ zMmn-kBmbzWmvCYiB@yFFA9}@aT*iEuWW)^7P@y6P~>WxMWL`FlS z6Chv_RoOPisw^OIJh%oP+-K`RshU_F13D}6#Vu!BA>59&0sIM+JW3Zt?2!xpxvfy_9AFJ{t~5f*4gYL!{FQCO&D zl`c@5K;^x1#}+PFo~WQU{po3(Ol-bv_RMNTzKvAUky^5h7oaq9Z7SbpS?J!}FS%^{ zB*Qyo^abJWMKcr~DIQ!}f5`O^=tP`nC}s|#s|p$;X6xvzwq?5C$=^m(jSC7Lb!HzL?xGJyX0R&sDQYM2>h`zQp+Q^CM{m>1kQJcQ78D!nywVLGS&1t&+Qn*j=Sg z>G{c$y)3G6DR3{BY(ut87-8>R{>B?zE_IPBs|nhsCb(3TZD$mOVaY z*IpFgU1iyv!@a)i(eqxcxqxvqSFqZp=i8q~rXczzD|AE>NqDyUE}#4!-MzBo+}{%A zirn&6S`D{3jN`L%;8P)?iL}fe5v&L*X^1(ex|9#N6 z4tc{DvM$AM4*l_6XV-+y{v_;bX>H({f%^3j=$h9A``R3fjFlFm8+}l73d2>0s2P{B zk34OCo)qd7QP*0{x8{UQ`=#Zz$=Vcmhfv>z4^ud9(5CTP2BSB zNDf#%nvj#}8+>()Fcd6QusVm4g|K2T1iHv zM;+cTMK2zeD%nYzx_n8Vf(#DBuOP97vmq-1v2jaz!3|o}W@+rBKs&EeLWBDz4_VM4 z?Y0N@(X&xOfvMwQ0sYDR>btkzBmg;mZSah0zP#_#u|hM>TL!$kXTN?S8sfoqmRqdK zqF>Y(kxJvDJotRpe5k$&i&4=)3B7bYUMsf#C&RdcxtKNP8SdegAZ-B5@QYzO{tZ7Rrkh*i0b$`sfbL< z@lk~-FMIWutg2z8D~RPs?Z^92x*mjUQd~0HIyqKqtX0I`z3aziqm!#u2%6N1m3`;) zg=~hU@&b_jpmQj{>%~rX{~_>V^QLyrOB&8jlvA;h)kCG}vx58JYOLOAy7t zH+joDi9jH7W;P&g$A6v>{mko1jlVC(SYT>7n_#Y5Vs9P>waTjeuvsIe#UO^?UO_nS z856I)KwYqq8cCEs;L+Vna0V9<{cpHHGD3P&2y!q+70@?h#^$*YbcvgEdK8oR(ae_y zs@=C~N)Z-aRP|QhsU$^i%DA84JbfMUuJ4AIZHCach%=UJBKpm00ew|JcW3(>{rNA4r0cu;QITD zoeCY&wA^$Emigot z-yh`Apkzn>)r4L3#A;~~;(iSRM&=fmw3`mU=58s?fB5IC4+--_qFvQBr7xO(G)}uAPcDKbj ztDEy;k&1*ga7OOR713^~8lKXmE)hh|&29Ua4WnD@CIJ&*D^ZI)2p9j;3HIdGgr4@6Sp_y}u4 zeB+fi3dOpVB?&){fx|pqj0kr3g<` zXRAY?&4$kofzEbc$&x0|(xY|mugH&DPhOHSP#wMAy9Ya^Hx#DPsnuA1l3Hyu*b#H% zEs`37?NAMJNx<6XIbkv7qUUB~IX9T${0jn-#X<(0-u=DOu5pPKYw}7$WQs~Jfru77 zD`lEI4#y*=PRIE6rx0Xdy#q3e=xXyVZTBS|_q4(73lp(kIq!C8Dg}GcZ*8*i5PN7o zXSAi-2aG;prx4f@6Pa+VMOXXEVc%UJ4Z>@QD- z1NM!YOf6r;6yNZqqUZs}9i>VVkWF0m{wpkckIl*~f9hTRG|H55YmGce#iL zD%JuZ>j^@m2n# z<416);!N)@&PwhS%4XBaB}Fbj(`h^yiM)opq@Q1n>tT%2B|)??63I+ zF~zTPSI+9TApWTUyE%wphHqHTd9Khb9G&Mn*&1jW=w{vMbhdZWtK_y7mA1Dg3U|w@FB_X=*a#xbGPf@1q+bU@sVAcOjGd-!z(!zNA^e~# zb*F(_W04rtG_T1%*aHo|R{K^4c8zI5GAiy)wK4Gf9jzVo^n{7#B3nG#&ur6;XE!ld zT}hkh9WsEVT;Rftcb_^~Mp*}-qOim2+FzE&A?vKi>+l68?BxbbgR#;^U< z3zA4~(}+e5%fwFh!GniXn$V zVm=d@Y;51S>^xo5aCIK)wt6Zs!0`JjKaufraF>Fi++t^!%H5E+cb6xCe0Q_3UvWwG zxoSherMc`y`lKan*0FjrP}Dq#-Bw)tpl28V0BD~anwL>f{iJ<|?P_qxpZLmT#+{3ENFtgamO9PfvR&Fj{2Id1DT;E3Suh3d2VHIoVA9*wkJ z;=#Th!c|eD(*>+9FfsUe{CF~UXejKhe+HNXC!Ng*`?<_KI_6fq!kT5G#g#N+J^`<8 zX~A0>-9JCy7-HN^cR^`%*Qu-sz>@&saokcg3LLWeXhrA9ym^oiLljDzSo= z{w}>EK}d28&v^i=e^4%~PT7&-r0cMDNfzU4;gr9XBO4_E57Oi`4B}Ls9;^_ay)7Lk zOmQvF;zNC5TjfFytYV%Tv_Vv_4iwBp=aL^N?3Hg>%L3SPkxX_l^s7=RC0(+@xc2W; zSg^mOZ$mGR62x{z!IB0;W8SCx1DUY3T(bCOvXhnf3H5CByQKKD9a|4G5(F=d5gMVH zE85Tdi(ah-4q1w3^e_m+h%CI1WyZV5_F_g3OC4Bo%3=gwwb~o4yUM;UtDxr_MZC2= zWs;4d+{tN3swGRFAfj6vGg#3|(VQ0Y%NAaBJ24}7cKC)3lD40ZmcMMKM%q8&GnUr- z*v4=vd^lUbv5#YKQ}G0%=_|CMzFG26&t0iAt0gRV;Qhd;DR&tE!4krj-7pz)2-o%6 z??iNHH&?eHXjr@VV1Gd66d5ITgo5;xlXpmB<4$bD8$RWFi45F{hkwv6r>Y+wPP5w3|TeScX0d0QKKj&n0yxxmhb9U zR?Nfbj}{)@9ovwll|Y~5!HKJ3=5wgyV~*-R)*1Y8DsMe<)0it}-lx`CvPYSmV6+0g;5{qo8*f6I`&u~R z+y=a?hi<1l$#U1u_~HukF|A2FQhVYm;4pUBg$pdayUKd&K`uCurg?`cN-yXJctzl4 zpYvj;k=A@ATTo3E20E@Hy_rkE<(JMvyju&1do#YC?G^Hv3x?MFh{j>xXgzZ?VJ{Gu zj0h)2N3!O}2@AP>3m6F6r@6f0{2|cpDk~5KZ5XG3*X&X@LMrEn&Z5!Tw&1@v*Z&hE0AM+QUmP>{03<@WHN5XrXnNFrF5D9P4B1P<7I>TZ< zW{K2!J+3`Qm!`yks1Tqd8Zfs2OWQ}T-k!E{-&Qx!vLa=w=HhB#jzV`1DJlb<3&27w zJ+4M;x^%6j?fEr#NtLN;5BHMIex?TM_eO-F=5QVKV?dL}X(2U=7!%w@?SSEX-chdv zr=PQ-hvbQtkr#a!>o?Y6_qRdM9G+&D-rXX1A%01>#B<&ES$$#qKqcA_aohMTcbcwz zki1qxyl2B&Uk>$$tJ9h&@tr$1dtvU0jUB5+x0>4TH=9@=Av&Klj4tZ7u*<*(`4&&s zun_t@(9{tKaF_;7ndeotaVDp=;7E#l&_2%P@FyhwEc_E8y0195my3&MIKYSL}pxALg>44>W=i*7qA_=R@n2= z3XwONT68!RzWC+@g^=535lx$CQPQ@CF!J=0Ppt{`XJ2MVtuoAr9AdmY5g{KEdOZ;^I?9u8H${x0pK8Tr6Wib`$PS(do$WLAAPha!sMIy2 zymPgAR-osXhTnAb5;o8)oxy~N%lckf1q6~Vy$J@B=0({ryDpTp9#3S zhmxOvB6ca1l1+7%Ojj(4KYQJN(ZG8l386p=LoQH>X*n>i(P~0>3$NBE*h<^~AZey} z1|!3Rh-eMsK-mgc*mGqaLucChjmI%_$v$NUf&E=9gZ!-5k-Y|`xpRN68@M6RIDF`O zjkbT9#mjzqSUj_^4dXG%E(mH6VDb%qPy!AioS%Lt8yzlO#mf4z$N9nUM&b>}ChVYA z86h60YF$mto;0glQY*PA{3Ru}tGhk)to{`@hhm>Rb+%6*`htdx@ZEa>*DZ#u#mRG1}iH2;c+PSgXHuTUkC2L#sWVN?3>ok-9CiD}l#%Tku1J z@2sB8Gn$8-vS^MvU;<$Ra;~~gdRq~L@vRdKlSL>E#p*fbCs$UoRh34EYcM`N9`^1| zr@}nu@yb3I(ZSg3WxpP^lM8xGt6`NEN3L^NsS0JqHr;bq>Knf&$g%8YR+y#fe3pO^p<=3})e;pRyG<$&SV-Bv!?Hc2nG{=;{le6@KM=o@oPfuOmkWzrUb zWYmFh6mQk&f`VwRO=f`Vd_B+gPTkFHRrT+KI-7#i*gDCDOUV%ANpn6wE>2p?%YF=^ zM03$_rA$cB67`ssmfhZ|CrCp@RhH1*4kR^@bAwP>Ls~}J2->Qi>ndP-dW7WhxI){p ztOqCeALFs+@r{t~Q?~S9ilr@9LZ=8c#!wgD7H;=glkFlLF0w4?`4*77IjMpcmTh|x z+FmRjjB6W%q5QJ#`^nhS^iYA#{)z=XDirchS@<+MaHm+3>r~uG3;4G~&EsZ0zN0 zf+jEL4Y&>KO=QKp=e1RJR%x^EB*z$NCfxl-&&DfjkGqG?lb-o3*g0LnD%SfUVqqk% z*cJMsp6O;@+}4lSFV{w@njbBA9T3b&le>`S8tmKl!il9p>UuTI+^1`uvDT1sT_I|XTBmRpAJ~0A(nb;^EqalX6)iA`_l{W`c-tq=C{B|ugG1Yo zR7nSI#E#H9JPdyT5zx0C9!{ukaGKz0pZ{0h{4`~on=zi_PQ{-eyYA7D<+)A(xF07;Jktd#?S%2yWflxie>P z-_PtyN_WNxUvwsBjTTY*ztIaw z#;S9`;_Q(jOJkxdAvUz|O5u~$nESN!#FWS7^Upwt)$x})C2EI7auW_C@-GVrjR9|y z?nJ;rHj_;a34zS=v+l+~L1d`m!YtFjV*zW24`j zUhQcIR}#Ewt*PYl4Z0n99nr3CMMF^8hc8bZ|0J}1D8A8^Zlau>9UR;&Q|g#iLWU@@ zX=Np_Fz(K=gPOP+u#3i-$yB2+_l877HmuX`aUWDXVKN;UvPO} zbqD`r_|B=@fmS)9Ke`-4gw=l1t4PCp{Ao4t>&{=W{i!w_iv(q1dYihoJXzv$6E|5*5s%KpN8nb^Bu zY}tAk*Hq@(Mr~*Jf)y5TOFB*O2I96UU5{g*9}rJp2;Z(!b07`F(4&m}7$_Yqd|S+`9UCk~gBSky-sSO4Ri;ljOZ{n^4ja*gj^Y?q_HpE6IhjuY))q=-}=99qaRq>2kP+NB5v9Oy|mB6R$?+g;})>5irL16yYEA|=Bn%=zMO!z~>1xEMA3u5ReQV3Jl%A%) zk>qK5^}e-b+R+m9g|^9)-rqW*Rt8gfLIF>)b6MLv<&V3c+StppZ{D*MYbac!i8F{; z2|z*aOE{+<-_ZYQKlGh~-?JBX^lkV0`ljyFx&F(FolgSI^x9ImG__ADdG9}7JwA<{ zfpsPxb(FXHyoK}Rsc$>8w+iA#i(r>OEc4Cf(j+vLKh>S4li~nJQXQ^+M*m-H?dPuR z=Fji-*gq-eOU+q;9>>Y)?Q1iMmzP_dV4;JnSL8lr)_1$5>^7R2nW;UZwZ)t8fwv?V z4OocYS7`?a6?QjFicD61Js%d^A)Q68YT7q>e z9?f5mY5HyV+Mue4@ms3#6yV7t5e@+zhyHR3xhC;(64|KL5s;Vj?^#ofu}#Y_q=t0% zhO84A?iv&uA133+y)+NCE1~$cXd;!6K z9rBRR{f*1c5h{esf9|^W{|KOaD(EEM?bOx*L)@d;0f|7CtUXIxb^oXaZza;BCMI-0 z@wzN{UtqO^hNep`5jocM2gpG+>AVRpof%l;442hefA=DCzWQ8ujq=LupjVA6g16qi z1jj&vWU~#vNZ|+Cd{XxP(YTn+i0tQP^|28DjVEn7@P7Tf=WyiZ=Svchg+8$Dc;xfr z*Sd+3HaI9ByYb1-A~nArAy7R89~WHZ(|HHJ$Jy8bP@uUoUbP0b(=TVmWqapHEcc73@&s}OhwGTFjm?34|RfB_7@H4AY!#UXK zgTBC*?ltuOi51L^zE-omp8s~hl=5{DrB@+p>7UWg|9nrd z9N*L>Vu@tr*jUa+N^6B`)AHG}&R9gyq6kU$&sMT!Wsa2fIHGV3!UJ6Rx+$L>ll~*a!OY7nAi+0@6DpT%FH1C|~un{~G+-Lm&j%**pN;g7=BfJx%*o zND{64oC@tTVnt~SAAsZ6lEsC2Hj2+MD_x?INa!6unF^1#abT}3Jr^X`MTA#wTX=HX z-MCg-%cu`**3J$!T?;u58gtYLx|orISb9=o4L&|Rj=IypRu_l3v+2ZJ)dlS}Hk$st zEQ6`G1=ss!EIf9q9n?n7BEg*`JbM>Z^UwD%<6Ls4rbi%Oow+1s_LiO(b{bMnm_xGZt?hJ=^bqU$Cu=6^2Oa^ zLm7J+3S$A6!}ix7A~ERF(Jq*am9?*@vZFvfCy7_~EBQLz+o?L6xNYT%EG59C52m*8 z7!*22NiERk<=p`5Uj3!}?#Qdx-A0E8jq0f(UNBVXY+m4*I{woK%-VkUl9}$0)qL6f zO=@;Me7ieSMy$F>x?1pvCqTe9p)QEfx~a`zQ%ti ze|P6kK)`2~%F{lRu=DhH8T#Byrt}BfM98yP`G}rMx&0vQ?*7!L2jC}tN0OxH_XV9l zlv-g><#iz}RZR~hW-aE9nD8;nYm-Jg#XkYGy|f6rSyrZvm3nVQ*P~b&w73`hEu21s2?A>~TspXfUv|}KJxb7X%5#RUrm?I1%W6h=w zaQPm-l+^QsSD{4alWiu7h7OFnw&z+}MtQxYc=N~{^_w0DN3XVv-2+$L==g^I5X;c6 z%ZQ1#tl%S~CqRBfDhZvtBwH4ZK&xi~Y`W3?Mo8GQsb=ki!-?JGup|3Bd>*UkU3nML znfSQcB9ex%4x1Z<5@X75mKMch8%~NHFPIEt4VRxZp6C! zG;udlpOL+b!!L;1DJGQTou;AnRc>OyW!tXzzftX(@$9er z5i}(5e@@rtTOdLiPe94WBlK^v<-UETMCV}3Okzki#Y(TS$1LbbAyoVLCF)>D!SLG* zF}IVtQg8RYGOK0?Kotup+htOnvf;SH(J-jitnR+~?H{sFDsN-< z`ar%5ox-PUDJDzHh+bmWc9l^^(?q|7^&-jrKTih}c#d-^D`<8)rCIprxrBo~*^whM+nF6s4s}*GjIAA@9a4Le(N*k4!ZWK`+fh1Ef1PfN3d6YpXZ!V zD|T!Pz+A;@mj<3mR83RUbD^u9V4pU=n3687<=$P6uDs;4rFAx(`Z8wpj{q=ebVaw1 z{AeePdN~?M@*2@QLZ$Ztx$>4)J@;eJ&$xg8Tv{TB`JjQVz4R*d%n-yRnuhHb| zx`7MRbLZoxB1iKF4a-$zOQxs*|LD9#z+9#*1 zsMJnA(0+#GEJV83yQ4necspNvpE@{&E3*B3LI01fCj963hanH~-dn!pOq+iHp#VB= zzvty>xiUyx<@lwx%7xCDfa>0b#QHMcb=fY{K%3a^Aj}m@WDO>!} zi)3YZb3%cfK`YH#f9cJ|RTJZKA}q8toL**%wP=eaox~nF*ts6qpGMQR?${8cGu9Iw z6Uzv-^U#ewGr0YMwB#7b)I9QVSJw@=T5k{bXzw#d8XI~%_K)uE0dlIN_jFE4lC5Ii z43}y*KK{M2;duO|k5hlw5}UFGBiTll0Klzn1+)c??Sri^&&bv3TJe!EU=x3_(Th|X zscsPDT>cqgt<=){)B*Q`_aC3D_kaAv`Q3XL7E+pY|8w-Z9p8pS!obk7$sv)R2WW;Z zPD0O%B8L+nJ9>}h%r$!1n2e7Y#g<0V$Cpm;QRO+?m?UYKAAs|_oq$xV!!viAX4maX zXU7BK&_*WeMH^A7b_xf;A@7p(jth$0S170Fv4^;Ru`oP+HRi#HD^reP!~{tS0-H}% zD8vo(n&V@G(sm0heqCMD|4CCK!0D!+U9H%z%6&Fhe+CLW{gS&w;Fj3T>NAf6^04am ztjM7M#oBv^HJNSg!!u$XD=HmCK@k+B_v+9@nt;-qM2fV4^Z<$2K&nWuQIOuGcY@NC z7LZ;e2@q)s5FoT9-;?vs%u(^21nSKDjd``+D22>?z56_s#X`m*C< z)#Q~BPv8)fb<1%!d=adDN*QPfek~WfIt8H9^6@e}w3WYhu_Va)SzAfls7Az$&y4F2 z^w^s!D4D`iqrHOq8+r`vvoWu#G!Clm$?^nl?;kbp(1^fC@MucKGo7y_a|p|AhzWxt z5?J9K(1r?h;uow#N5h$wJcByh>{};3_=EzXueIE=H#P`}0KZiyf#GaB331otHr`5} zZ97SNo9(&tWb?(=LU4&*Q?XfbWkxKIH=w(N4Y9LIc}VP!59MOcsoaeIU|$!hFSlEs^*mnQJA*0>20 zOgY)jm3?i%DT=?fx5Afl4eb=euQI+la?;Z`_B)osSMpSz(0|S)2Vkv#%z(&zsfYe} zIqt&-U^}qZK=pGUye$^^tzaXESk@TI`MVK*g|+ix0b{k8FKvYEY44xgc)HqUV8YT}@ow6KL)zi&h5%N(~baut_63ln|Z=qFPXt~+dwX~(W-`=>aYlTifg9bKARGdz4i`tB>s$A^ z`E7cpeV{!w9B_t07?9CqR*FL%Wxoo^XiYTz63kq(K@W*k{>bljZ?=UKli5s8o`vw7 zB4D!^JngZazl~PRBK6M6zGS+HO*ImJ{3V~G57S!I7LO?B6gJa0KG=KqSj=B>ype*O zoKP6KGk7Q+rNgM8+2i+le}=~SXZwvc1Ye&yFTgeIU2lo5Dd+MlgRc7@Esr~26ra72 z>)-OKA-?M7WB<5^^?nzjYhtuTqE{H7yr_P}%>Clj<0BjwUq^MF9siD3fs0x_fzT{cx9b(3_R}7hLCUj5+y>=lODnoswOe_gyhSs+N;a+#Dzcs~ zY7g8QBA|cKsm!)%VqUl+v^8MpLXo61nQtH~x6DC66I!Ah7FnSB9puf0`SoxsY&pJk zU-n=_uqTOCok zK``h?3#H_djrJg;*oLC|1q_U3CaH2dtCYXxT?|8(#ELA8eI^2K;TMtEN~r|6IBZcfIYh2WLrwU_TX|qV0+vgywiSFdV zrb-3jZ`S^ofLuV<`WZU^sM>w3f{F{^bC%n?UQ?Ie65b8tWlgx0{g8*+^&~ULBbG|f zbYvk`CnTztqrlH4#8Ni)rT~B=2)N6?Jf6MZ zUP$L#hosxWt)5iMf-b+pe)coIH*H5r+)(FRW( zO&L${+Ffdvh+l1WZxES8$e+SW>v6O?qFX2i(emy9S56zp8|aeWCx#mKhHZG7RmT~g zQmc(;s~gIQfN(vlMS^V|j-}U_gil>3gh+b^E?*&1e zzomJ;e&23*k~sFbZrv)H|IR|s(yr{uOz{9@uD6?arH#kgPZDGB8=AKD3;j~tc0ati zH{im><-Q#&L3!_M1v#Ym1k9`Ggkq~4C)ZhRei=SA8>KTB@AW4az-B>^JapcPHUeh$ zWR$%~ErF9V%dVS0GUah5?c;Ralp>N;VH1Ztu4~gu9N&nMAf@7BZhj*a1xrIJwRrxu z%C3KsSHGr0F?$;10{uORlfL-77LN~n6FeKI&Ug>xnR{$o>!QA!!Ke|Kh7`28-lQX6SLb%Sa zagBx*d?Ol#`h5{#p8BY&$!nvu=U*IkT-z* z+rVyHVHRP#BB(8Ef0*pXoc>l{k?KmRPiC9E_fA%tUrX)esg;2VW`yBp7s+*&eKj;< zW}yAMnJSO~r!xr7xb*W<+3S)78mSIm;O*32F+EFYtg38&CJ!|Uu1Aqvd#wjA>t(hY zS<}>ED`XynMz*HRd6AnEo{Pg%T2_?rUXBWKed~pv9QIoA?|rLe*Q$w_${!x6F51)w z=*L#-gYbzP6+tnmgU%rYR5d0tXe1A-l04oK8c~}%e43QnG0IVa%zZg0XkWTm%|5}P zD&O6)@4JcicmXxK9p|je-;M8`<$oFJK~i0}aQ4)XTsNa%fKIwf%Nqb)wD?)uS>;== z4?H#C0_R&Ws==`1OK*B$XCm(#`Te??EncQuv5fhIL|E|VRD=xe3i_yx5-ah2IxT{P z1aM!k&5FV$7SeeznCCk4+jf$xF*$E9l_M~RcrM-BiPppHMxVK?;^z@7qzPTuqi~kP zhPD7VJOfi2ubO26&Ml26%$w+bAz@p;JRr2dgS>~DiK?dCAItFVov}JgkH3w`B2;oM zO&=qte^LzuD>Gmpd3V7lZ0)NWX9e?oo+My5VYJ z>rr1^HP$L3>aw=;X#ELnSUtKw`qvfVA&q0t#+=O}(en9WRs8BX^gt@P%T4JTfYBF| zJbY~0xIO%ncLznxcNE2&Kh~06)tY^6VKV42JgFmyLYhB3vP#*im#A82$7x?S)>Zj< z1{E!IlU#{RrNhEJ2(YltlPs0Wep2d87b7BGp8RepU!4PVX+h`Hj}T@*tzL|0185QC z^&%p>VX+$g7zi3s)upT0FFMSC-PJ$Pf&Nm<6@l;t(?!J+GU=0_YS*Idddee$F} z^L3WoFc@VA)%FQjvrrg>g~KNozpzwRS(E(7Q%@q>x7zMjo-_4$$y_W1$e z%I74F#N9v=jrG}mnirSTcZS-W6K4>h6dBi>XUy14zQ)xxzCJ3_Rw*5bv)uok826OE z{)^=)SROviD!6~p^2pwI1V#Yp4O)|Io9wC*O2n{JB&>9Bacal*CN={1_Cwdw*;|Y= zHIwLzH=%YPczb@|Ys}jh0T>K?*nKa?=WlH04*m`V?SNaNdtqS;h$F22Yl4DvQ=2{h$g{2N zBym|8-u=Pi6vUh+IG7|y=oF@ft>;-N`=Os-=7_aD6%-}6S0N8-zRJkBG|L3;@FNkj8^b|G zzNF{0A>zv?arT{qU-ls=Bs}P-v==UPb4_oKY@g(!i*WApA1g|3f(j6q-Xab#pSFC9 z8++DV{8wu%;2Et1t_ovSpzIj`)P(zIUMk=&wKXbG^`T-ftn|P6jBgzbvoc_hD%HB0 zHQm_M9goGuCui$C+u-Kf8$YK zG9I$aZJgHl$ve&Vyu`mmWBGai?y~D=$FP62<5|;fJjw2RBvbNdlr|Coc;Lxq$3lE5%n|Fzo7qKR)U)mZ($jJwLNL5l4Od^)hLPqn_z z2D!5Q;q;R(_nXx+2oonac0c#IqCr=ogY{{~_upUAA>`yqbA%TTc5gj9{bk+%Rz2C%tkjqa*#Xin#oejnjJTj(o0T7 zUJI|Xa`2yUp!g40y4Kq8Q+$heyi=Au$o}J^maOaBQ2qsrZ9>%g27ap~pdF7f3luY7 zTF{Y02>mBn{bzYF%1~S6$We`-*ZjRosBj#3h{G>AT({tjpx(s*ptAoY`mXarFt}~2 z3%ik=Q0x%C8ftAOdgxq?&vcujU;s3H02+vzvC-=>9Rd85UdECU+BqG7>voD!1b90*w z5iGI5k9;ms^8ihjECsd(*wu_VqN*rtsK3p~+Ha9F+4&!dkV17QluQ-Y@O?=z#@Yt) z4j4fDd?u|%s|`u>p; z9#r`p1X5{jJSn%k+z60#?K{rv5(+-dvN>!?B#d`}BKd;;ZtOx3l{u1UMzBtu@6v08+Je(G&d-qneTDo3$ z%f^wpwctbNLLP^3t%GNq)xesF=G5ih9jjf{4R@g8Jro@=Qq>PL-#)M%oWT<{Gb@8h zZ+3i#Ngo2lX&xmC3hZSo&Z`y%l*I8NAVd`@-#(sdVp{kyO26!HFaMaikY|4|WwPgNQt^?mG9=&@O~E;$Lg^}M==L=+ zlJl1h4h)6|9KywL$H_wSk#G!<3g{eiO(cO^_cy?f;pv%^Dbm-hVo6uf z>3PnZu)!L{I%7ZNr2ALtEuQ?RmusnaD!jm!s?aEo* z+14}gQqp7EvJbxB6S2?4;ElMpX+v7W^{Xf)9ScN_$?*|+d9OD5ShHBGB~mhj=D&i^ zD$H>JS9IX#U+@p_&l=oVB#t^gAzv&adx$)~fDB%RBfKEZf(Tz;w3(NmIGRG5gN1CC zUM+g=-TNjwV5Q8*K*?v4%_6AEUYi-qf9)nF^qj>#d%tV*>~+A!_LR*i167&z-8Iv# zLz6E?Wh-|gB`A-X+ zccTWMgK9v+c>R%>X6cc|(Brb7wn~G}j8d*xS*z6Pp?Av?XiI#h`}pC+R>dl3yOC+6WZ6|qQbZ!L2tQkLEaSffXow-pErCVFE;wsev_0nb4km5_>4=It4lf{Q~P-SW$bn|7ot(YJaxCSDI);C^x z`^^#h8CO;WnDTD_02^%{<^6VXHiA@wR5o2%x}EByvwgrVd9kT&7K~!9ub>7ObX>nb z;}v{~Fj_Y66Pc@w|M`P;|8;*Z*}$lWJN6Q0OS!%irDD1IC^y~a4Tsh{PPvc%*P`uF z{lg+DjbIpy$+m|W7y3w%Q;tJOTlhJ60*d5Vsa%U$iz#YZH3{a z-0796|Zjz{r! zSC?>}u(wsxNMOtA(jejLv4O5{C6SxMV;W(;(B-)=2wr4z#pguD4%P(y80#dk1#95d zic|*IsR5x9Ix#EMfpG)>N{8^&Iegcc{HUzrQlLGhWrTIC^5|DF@h78+i{XLPkdey5 zZPR9Ck&h4>zbab48y_98IxNWZbo$K*_D$j)FI8S^Xy@2TeE{k4_D$D63Zwnhi%_^C z5ALto4{QwJ=`P?{Tct(o+*UPk{l#tVs>{}LzLtax9UL`-n#Z%t6dH|$Df&=W zJ$-x}67it848x2&v6?p)cKVOA^(y^dk*gbKq=Tn!B#s=7ZB96uViNmn+2qQ&fpuEf zo$(qD>)?7nW#rBkT>8umQ76WEJ$!6{^hUzerAw8gn|J4EK5iv=XMH}r@U?|hE)j~K zyn1!RYz3Q@Z-xq4C%dIPK1*N^KGQ+yY_cx@9vSezRkH`RPxTxV=eek*@Xcv{Vg{43 z2_$*Wz_$Xsep$(pZ45+cZ!bUvxeZ|x&QUD2AUHCjQyn?QZZe6flz%QPKFh@3k#{JM z7lW}>OWJdg_djo0_PXnA0DTJ5sI4R9%tJ(|;@erxuOoVYGvxf)7t({F% zZCw_nV0Nm3b(4xo=J*R7Jt*RJScHLqX3ZCM*Qz=R9pTJl(ZWSqB%49UqU)5y$D(~< z5o6jIwt3W!Xzxx{w;Bxr8J5^F@Nbu)aOStgDhy3=UPzqN;s7p_w~lYr0(RG-X#2P) z<`a3a^LY-qmi#_Q(RP5vN|r@TBTPc{sYD?b)bwejcQJRdCdkWt#Q)(Z@yw9qwD{jcBopCGEE$<$r)0YfsI*GAUY`O8+_xJxF6QCcgnPvRp{-il@8{4m| z0U`Y1RclYAIb$y|vvS!5mUOLYHD;6+-F$2s$6AYZkcnRD*dFxp4>|Ud0Xcb^#?%WN zLwm^4%(~y5VV(I^y&SW=Mu<1xa!LI=@NxRZ)?_wgU|We?L!u zR-fssx_2GyDNEggI;moF(LqsKHwfXKx|ttg)wu0`sJXG~!c{2UOqUnQp;?-JEN0#! z^>@5{-!>Sr=+?VF`Dbic&@|-1fLylrD(2r9dG-i!r;1Zo3~7Gkfx|BJKak5rszU8j%CH}wcp0`hZntP;~ooy z@O-Ud0?Yf_G-^b+wwhJBly*lAD3WLcFmMqkz9ib-b-HJ$`MbOBR$ip7d!H zc_KlFvgl->TsKz?R~?VcIQFtYhk5fPP2kVN2vV~ zM?)#;M8Es!_d%EWP3TvWeAt4GDkr_uj*7kk&_kC9u4-)ICeOe|+exazppsL0Gd zaZ78lFpX(rUdq#t&|+dn5kJc4-}hd;&qKf*l25XVu`$b{h%MO~4<)!q+vb}>6@8R- za7n7YwLwC1^ryeY>+a1W{_BX#F!hArVqD|CuhryF+qPp2kWmChzFK*-a3Yn)1ydqg zoFQ46aV)|s_LAdb`-^zb1_7|aO~5UNXKyyPFl5EY05NvRb*1DANj>2rLF0wq?3-t# z-H|bWUfBysZy($C#rT0vi4o+{La(a9=e-YZ#uj3tcyz4A$`_>urIS5>Mmy>O!iHim zfWGDLs?XO;Lc?emFVxRM=#Ma|EdtZ^NQpb*` zj9RqnO2v)G$3_>y)_ROSPnmsejh0$LkNEu7!kkzAxkkoq>fISR8>7^_t`OyCjnPue zWKkY~&h9Bs6o{t}BnV!3>bh3^ln3*<#Q_(w8h$iOwT_~W3N!e$aJ_ma@J=DNAu$>ybE1$jNIgHwO{0Ox@qnKv+2e(g8 z{66G3!veW8%)z&uTnpZHFGK9q5tVnBjf$4;P_8@d?rMW_rDLId==7~-?D5fk%=glG zj)GoS0)VEYIBi{=%?vaSm=$vWdZlMs3Xw;O0hX7mZ*dKRS`)70hd9k8R=xyt zX`T8~+87=^C#ZdD1bf$gF+*WW?vnNRt|9Wdq_1Sv?9W(GIkh8s=}qd_2JtiB`}#AC zBGh7X*r?Liga4;FifWeF2n2nHPnn+%ww}M+Z!>==c1Xzw6+1v12VIJEUXPI5z88(v z@KbD#buQ!yPt?t%Tuo?jI75DZn0w3GpzK z*C=DjUSG}uVhJOLd)3wZKK=B|(Kr18z~bH?l&R)q(~$MP`HoFnE_I&J`MAJ{e+SI- zKsmGXY5nAQxVr^5?}OI0<2|(=(KW}n9=prpHb04jGW2H0=~q4**nR-F{s4cpM=y?F z1(MJvbE%{Mge0d6==6XHW_r?ln}=U?KF8_oct=VW+nI3ofqL_;(c=<+cpm_PqFD>+ z?lAxWDZoketzae zvfSkiKhuguz2a=?Obhmv_Z;P)!==-9bF6tlfV*K2c@Vj>@}6jMYR1~&&K% z(+pI{B&0RVS${UTGpeH@de+2+^z=}_&B!yljx^KhFaS+7TpmH!>)iCzKqZ+O&hJ0X zbXMNQHQ6Z2_Ew!7%1#hg&>5F8b#T+N=~G#^HA@uUV~By_-owjcGC#_EzEdRyaX`gt zUAg~j1pBv{{lL!w3LZ#3T-cNYcHU#b0q+>R$s_S@wj-SYx31pB*pwoDR5r{-=xV9RIE&=MTczEUGDxjwCj zX=YQ`Q~9V$m?uoe4Z@dvs(cS+T&K0G7qIrOBRq*taNTGr1x-d<6gwQzqo1UI%AshL zV`JZ*?~U~s*v<-ldX!-{;nGkvWcCnG)YQ`<3x*lK(xPDRl||gus?RmIVeiEC{9CxU z}E`ydYLUF4)iKRW9>rPu@OTHtF2{4tE4-j!k6HbZd?NY)ltbk zJ^CNGc!5_ya&>~c=-ppVXph=|w?02`9|4oV$*f@(zHd+Z{@=><^Ss3~@Kjnw-WBYS zO0)H)2Dn@8B0jCs+97AWuuL56{%aq(kqMj6((W2920fVZw(dIXdzRbUT;m8C;%K5h z(|;8oYBN_FeolF|Ra)<0n-s(ytZPd-nui11hkDJV+;6#K5IN)pugmK1ku_)E&P5#0tH>&Jn zOG$e>no}AxUNmWb34^(hNh1%pr*{9Os=s;-q-~C0I&4>dW@i84Gq0+FFyL6Ya9@1y z2g>({pQGc`ZD=lR^#X5MpB;_xbsGA3F5Hvqm+S8jNpqSf*xESGy^grD$FBZ^u(API zFvy9M@Bcxo{(54-bs!wOzIdg%w|oN}+0#{Ni$ba|RPW&Y%)C&Hhu|M48CIHX*<=Wq z2EM#>a%P&vMmaY>;4sm?3~=DoHbyHX-a2BsnA1wfBGpw0d|Pxe-#9&uf1kAHVvsYH zp{yAIj(UddY%DEwyxrcrIIL+3>gwvD0stJu*|k4gN5|R8Nw%5EeQ#K>+Yk6MmZ>X7 zoPSN`@BhHaMK#f=qZ30;=UmtF(iS+A#5Oz*lfDt@tAGRH8(r6FEM(P-E(zd5y;P#~ z@LEhP?0iyZ6WG<6*g}F+F*$e{PUdJK$p&&iH$2hS&rigJWu}`iXX5FZi0}uovcOG= z|H^1X_D5pZlYNBny!|`?8y>$>$8i=hC0?QZz=k?fM-Cvx;-pX5A1*bY&AqeNr!blZ zP|t@8PEFSP*0$Kf{l(g~W!G;v%abwk;hQCKK17(pCV-`yIv|rZvK-fQ@T-Y@u?0{> zYySb}x%W@~cqE|V=!dZ$uiCoZep zU`B)L$r60l;mLaKpW`E5M4+JNSL73IU-+##@RWjhn(nnc$!bZEm&TOSiTX>qu4RAG zZ&yk<`G6P(4^Q{1!z}qTSLjGBP1Z}t8sCE?OL^EwQyCDsP2OsKZ!C>(PfN^ar&}SE zS*1N4D@pj#@~iD$6CMW5!rc;_XaJ;ITdoJp4al{6h5E4;c(b$`R^wo`jO*H4eU+M>F@ z1_yi9yZAR+m zrqFMB&{V$ko#D546#)W}By`E>{_pMkRc<4bZ8EI~YG;zj(VZxI72RRZby?w#2;KKD z5ODC+@{$&f=|%PbT@3rmWWKY3CMwoy>Osa*)Su%0cZSp`a0=jx&`Oc=U|bxe->W~r z0k@XCg6~dWcAeJ*L-cemeWiAPWLzTu;=A$g<^3l}C6PR!64nK=Uiyj_{ZF|y3Y;D; z2B|K30*;jyFd*SjPjKG%qWX0os4e{X6Dq9HkIE8q&THJ&Wv@(_ZvnD6SZ5dePq0jh zcYuf3)R$~1|67oMiq?|x$RYrd^z@yMR6UVyHg@IDS^W8dhYHn=w5o4Z(WwBLUiQnC zV$&OY1lPj|7_?ZcN6B6k>7K{^_1y1&5a6ZmHtFL=xb`mVVUbFOm4g(3lD@cF+}>-i zFlB!WWfr|M4};uE#Gz=a&b{#{~Hwxn5Axxs|&Lx_D05^9tn5` z5RMkV=7;|f+qe9(5r`c$Y2NAbbl>~VUjn9hZu!ZtEtVorX#Y~X2O1_q<%HCHaKY(2 zfc;Ou8dc^Z)P{eT3*FLQ2=K#30R}3+@nL|)^qAX`u{}Zm7#Ogk*XW(Jse-%2?`0j( zN(ao_wJ0U#AJnk|GS4hGwPn`65d+x&e_lnt+cPm601!PE;;7L-!RXmZ{VMP0Sfg&Q z`0Y$z=~`lODI@9>qWqo({Q8ZbH9Vv=h_4kz(tYJ>1m03{e{UO9_Q>|{EF$E>=fHn; zFaO^~1dx#$0`p@vv`GI4%k}HN`cuGqnOolfNA3M%`2f1}M1E244-EXLg zBJnhEWX4}UL~@ANg3eX1;ZZ3+$&yu*B?@jg*mH3Q0b{9N)`z z9Ry6r7rC@;I>sbh#3smTg$-V!HRu9sa^eh`TqidV&^qLctv^RruT)$4ZbJ(haSspD z_*HSXT1bNZnvFZ%I*783c?*cC5Pz}<^J++7M=iy(-{}pSeANjIy^Zyo_JDFd-j$z<(;%_vHP%O|#WVMcsKyH)&(nraWW77uLU(Y+HW+*~HdMhtX=RY2XB# zWz+vXN8#FeOuESre8A7E6r&I|TT4*Cdja4$H?jmlXvm6v&(yejCg`L0mIb~{PAC9knZS?! zIuURry7)tUb#Aa>q>hVU`!PwY>#k-eirgj`N(ddjWy82&{=tdT3(TI->JK6{9D`%` z#vFniEF*s)uoIPyH70WG>cg`5)gZUgaJg}HAsBprYJ~aNAa6t!1eEf48tF6n*7bpV zyzkZ+M@4!62rOP?ta8buxQ|8Osol%3TVSNx=}(J30Z0+^&Mf(#uq^C9LG{RizfMH& zpQpEzDsPNl#!hs^QWGY2%C1tGxSwDX=AaK8wC3YC`7j& z`(RRnkV6XlQKNF%0$X#O-%`6*7J<~zBNCzgV+Z#or7`o)N#(%%se}c#@l*HfcgW^8 zkbFa8rbH=ZYd9#b>g1It{{|*~p$65C_q1O-$Gr*7e;;v)r?z!E85-9Vl`Os5&u%_7 z!4;Ie`sfP9&45FO2X!-yTp=hV+OBJLZFXl3nwTck(cK_o?IPokuS8ED2Rda~rRueV zNmnpuNm+N)?pJ|LwyMnBveHX@+Vesl#B7Dk>n6XPT!W1yN53wi*Uqs(u)kR#Hdge3 zrX`(J*+-8B)=^RfDKs6<&#SIkbWQujwe=>I)^d27QR=SiL;X+4Y4vWmuv|G&6falk zK5u!b7Ekd@ZYVdrVU%uV7PzP{R`~D6R>13v%b%N0p3Imzwo_hpP7y;d(JKBV(EWl` z<%;XRRu?esp%cjCM(-AglBVTP)Nr{-`0!>dEQa2zo$U-Ox;rE`KeVRY zDMs^zOex5E+uXrVbh%`mZMbsG6Q~F{wpT{6L)Oiq)Aecg&$`)qi``Myhb(OM9bhBlj9Ct;C9Ve8g^o{< zwul?9AGb+5f*&f~iW$F!H6K*_On_@6uTlw{1u?E|Y(seoaG%)(JJ`-rrK)L_%iW@F zadi+XOROWN?Bu?#^8%7$I(R~K3{n^uO!g&S3K5(+$vWugT(rAYld5?Y%MV7?u9PT3 zC)YkBX|z(~QfXvnir4C<=EGW~^1O!(RacVdo>;{zhHZKHyh3j^U0Jx=<+V(*F@j9G zE#QRHXX39Qn+72`!Mycd`)CJj}{ zwhstjjg{I!UUx7F?MscQ@E)shzl|$?;FOG7iV`;blM6r)25l}}&zd!|&9yMSci7KM z&}tMl+Tv4tiOuy^|E%r8iKUQF#5)7qUgk+cSGo;N?_JSII8=LD!;^R}vLK?mL)a zmxa9q95qelj$ns3801uZS{mykvJ2aGhjK;8lf9b_8dhUyDf30-T;rik8T`&tW?jCR zN6qeH^ayZpmAI)7%)PM4Ay z=eqZ8JoJhX(=0gL#|3f>*0Q!{lQIGDPRvJ7cIsWCv200tyxRFh8?p6UAHR?+4+6!zFH%zHyr?m3^N^;(0t7Ao|#C zoW8GYCgECXx0B9fWQIqVMcKvnqc-`WRi16TL1s*6(>JZ&x3$b!;(~+NT2#CoLmt@X zcFk6lEJ>RUGnHaY+fF7-S*lab>7ijMo%YanMYAZOm_<>8`Nvn_Cr)CR>&#i}? zZu>PvizS)TQih7z@_zt?cGV;~+eOn7?rnp@orgI)Q!Z^4=-`Wi;lZQ~HRF)Z7{bn7 zUBz#bZiT+Xbr?2$P`%%*F#NgUJx7_H#nSZgkpyx*0RT!YRA6mWeYo0{YYR*&ReS(m zL0bO0<@e4@bX13C`SyTV%M)dlCUc~D>^p(0se!c_i(4JRSbBIwPDOzl(-Q+Ma;V^% zFS*$JT;VL?wTGOx5z$*xY0K?l3^GaoOcE>IfH3zg@_6A*a)!>8RDKOnI;2;u)Y_6I zzI)ZD4-%pgEvo9IhLoq~O|tq9h#fLovL{VhG;S5kP1sr8$?+c|#I{I0raMU{E7HKaeUO%n4VP(me3#PKR>DS3RK$r3l~mY z1#Is1O|FAwpQ#r-C!YObAXb6qkcH8>)6qz|C~ zY#Hr?UVg)H-ew`VGs9Q6watIzgWcvD$Qo>zD+Ctf`q-KBa+YuM$(=g2?1FZ9h?VHS zvzULGJ7em;rQ#(H8cf>03rKDWuwVOb{N)Fo^hicpK6+aox5;f%j;e2}(Ob@xZhC%3 z_9YcwpwFivpak+&<#kkx)#WKPt>tVdsPi0=P9Kk17AyycmHKaHqfI4sz1k|uucm*T z=glZI)wwBYG$Py`y%94nU76u;?KFl~8XXAPx-e$H_@b)u#CHdm(iJ4g1Zpq8C3_AB* z9Kqm-Fop#7qfgO(y}0Hx+M&4sX~1PGLFZm`Y7H|$g*Kk`Xv)rP33kdetFxg6)f_;hZ@=0M@OsmH2T3&Q|q+t#{EAniTrnKI(dP$y0 zD+9u=UFV0jXRm{Ucbh-B&UGmnkq^e%FKy%f$gSy;JTz7&0|9~dHf^~_!-MU?+{RuV zC)1&eb*VdE11A>Amm}1PdP9B#;h#u?6_c|WcR%@8=j|TX^f}nc-@ldn>Jy0%15z9O zZcm=g(<3FHm_G`)>V>woueCI99^e5@hB`>6*#jwa&{D`o)`PZkTGh@EV>3(}=zD(d zNXvK#@CV0xD;Oark?$XVIE{8L9sInS0#cy4CV%_vediTiUX;syXmcV zjZuFGq3fQ+Ti@U!0xm9Z4-j5Ckm| z^59X=7kqWzxn%5bA>?wvZ|<;2*4W86V;a`RF}M=zLC6Vl7D+M4#jv>4R!w48VLdp6 z;Ixi9Wi3oBFm$W;XVK^X!~ZqD1u_8FVRHz}KPg)&Y6I2g*It_WK>%^v4KO#rsTgah zsBG0(${$8B&|qf(A~0CF?(Us>uzv6?&1NJb;Jz_L?{>w?q+j7#gQ8qfk90g@klg=$ z!7A`dkB?LPDT#D9Q;Efr$Wm@9sMT@>-$|Ep73-G36LgCVX0AeLebZty)E0Y76fgsC=bzVy0pOA z4c2TaM3y~H^R4i9y6r*FBv{M5(bxNuF$)Qm9!-Ps(A<+Ru>W!*>e?{CWhi{VCf6*F zk5v6Z_61~zZ@;A zb3n8S7&qgiQXlIlTMJ`6WKor|h4U4tuCoBY+^_AoVbvD4DKr96`bq#MZT}j+2$CJY|WIR28>d9ijBDt8(wXU zS7$SiMO+=qT(8Kos<`LxJ0NMEYX>6+XTxhHy1b}KRW(BBP=)8kwrV40m=iXQ5m7%{ z(k|pwQKZdulA*jZ1GAOA|oEJAtU;ApX!@$3=#(rUukYHFagW5@wV_2)NA^CNh8 z#~2DCTw{4tXZqK&wvT(L zh#@j5mcQ21M^9v=TpU?vM1Ezr;n$C!(DQu*F)m|;7j{g`U@)07h32Uc1BAJB`a2qc zCaP?nL3`q5Drf>IrDenWVpDy2Q7Q#km(uzwOyL9jFCbQdV@RBIO+0Y#H5-8n}DJc=X07@wids*2?FiDkEZPKX^1gnpU_&ckA^X zGyDh1&Gr-c5kauVPGa4)rP882r#e#Bg8wehoLraKth9v}%=Cp5xD&N}`;FKHu~Y() zxfpiyc-$OedD7YDFJq)8l>t*6Jq_HRHPDafAYq%(8`AvN`(z}Pu;rL^t9SD)z~+kK08-+Z{UJF9n^Vf43w(VMcHj0z7LO?+lgViU(0XfsIkMZZz1Vq ze5-9YTFT|!qXWRXNS+c%o5=0dkp~0YPCDlVIjh4A6E9LZDmN$Avl!kv?&~dE6%{fu(`Y9hEx13*{22P%Mi;aBs}Elc??HJ1lsJ|J`dI8= zBD?a!7Fy?M4#Y;qmE^nSSdli3!#Sk{?71Pjg#GNv=deZb<}#J>3SKC<(1F-gMDoi9 zET53t28s}Ux#bBR=FXU^vAI6Mr_T{QSrYg9JDF!8_T|nLuN&i2BzHcoinqNH?<&*m5LR>Moje~E zfyn3fic3jG7}@AWMi%*ckTMh}kYzYRy?`ymLRQD^Cos|MljaB5CxC*1m*B7kWF3XrY}Ye3clZ%5(yINT?T` zm@-!zX+n6)+UN@ZC_>KTqp*Blw>V3ZD$-04Z5uLnnKF$X5jZIMIlT%x zHufp0u`NOyW8l)ySmXhHFoM#@$Z@ywSZ~W%3i7j6cs4(m(Xpv`RRzB}RLeKNK)LZL zq#{crCIw@wG_<;7j|&D)n~+|*%XfZRlv6B5EEyfosvCQGB|*Cu7kE*I)8d98CAaW) z(gee+Z#$e#zgxb45J&=M1=1p1 zI^GEj+W;rNB#5i48WGkZA5drATW03Mt~$hKi8o{s>FWC{b|l*5Nd=6Sdh+#xnZrnH z%%>{xvtYR^CN^7AqsBGj*;^{9yJ3QHT}(`D?8dP|zte*UeHQ1|GBYbG(rZup#ovrc zIO%JCgR+Fc`W$Q!tDm|*`raL`T}2@XT1QTmS&>Wol3o_Zr*7Zrm;PFj;Rig6G?^-$ zq4&U{g0q`_91Tmy=h!l7$OpO_CInHff$Yz#Z0;B%2^7_B;=_$W34jkTpy6<|HP>Rt zsT}Rp*I-!t#p>)K8V|fhZ@mXJ*|=Q3C3u@G*NY_3F)gPC}mys?_u^$ zL|ieW*c;r}fx`Na-y(W^5RTVp+I*2RZ>}11K;lPNRsf~rH`qgClQR5+a+1iml{{l- zX9iH(NIi4?dtV&Xk+$ZpK2jE2yVloV%sa>;M=X$f^riHe^)W(bOJjW~-_yQ~ImrQg zWIa$p7ZTPQOAr#)_ji69N3b=5nqjArC@r8o?j(18uDUM@tuzA4JCvUmhm;*;tuzF$ z#wT5hXxE5o@fVdHEOGEzFrn{8IC6LmF<0 zLkQD1qs`_5^j&W?4{0_*0vYv=a1D#iFLU-~3*VSc(+f*E94aqGOV>4EX>#F+ zkfvp5Ja^^U?04M*qG9e=R1RLSJh1z8-1{SO#5Mx^wu3C=+l_;gB~e75Nh}t70d~(H zMfB~IN`j{7UjVp9|3CJ=Gpxz%iFen!_C-Wgnu>@Bf=I7nl_E7NC?HjkCQW)v5i1>~ zcaSPw1nC4+iqz11QCeuB1qgwZ`)1pp5?uCjKiy})_jsG-E0A~&%FaY6!))XiJ{W+O$+sx|LNIuTd3K&37(I(VZ-ks9e z6`p7AyVsXVbs+C#zsx515m{=ul;;wxbh4%6jJVN0`wg^F%I2XV%s>C@N(H@MyR(_*4vnO80> zKxsiyDzgQn^Ka#*plF0{chl{{o(yMHQ(qt!N$kl@AVC$P#Y@1JkH5S;l0`%ye8r)^ zoCI%_;dkd;iSyXlVqbS^m(`gbKHHF>>oG@w?*{1jEqYIh(7PCp+k|NmW?al4C$F{b zB%;ZMO-P2&y&FBYzs(LZU=X#0T>(l8>ywM}@w7`>OI{D>8KA z>zJ<8C*idB`u+godd>0} z$=8r|eK_a`Y>+}O)#Y2PrzCVgHe1)MGXO{^SNr@{A|`cLl62KTxZjH9BU#+Cii&7H zN5ztK^n4btk_)evYErvN?2H1iSE$ssy(CKG zyaooTJAU4k@z+z_CJ(&kJCcYt<)x%g7_^r#=QMoU6n=6pZnxNXX_5OD>)FHA2A1wNkOXY^*_iZ*a$CP))B~@A*WvHLBs*l>Q?DP=Fc}M!|T^rU4Z#KnoV*9+| zl@T$kkE8O7R4C%R5$Udq!AqF~0$h3x0tH6(!Lgd8J2f{8^d@^Rp{&G<&R_YK`_6nd z$snTFYHr22*s^~tS7h;%$c^=JoW^e1$Wmq^3?z-&$GE z9^|OA%55N&ba^nGQZv{e973)C=@R)^tM$hJjyC_|ciplB@vT0}%6b)_KPTNutPBNQ zJ#mYk6W8QVg5C2o-(&Lc^aKeQIY+ccJed0wQOoTBbaV~&HFooOIZ{8=z;2p%!N3_} zLO}3Z%H0gz&o-srVy$j{yKW&QMU^*!SYe(34YHm1@&dn?^lbmJN={%;zq~RT-$(>k z3v%hn5mBu*M^AqoJ@An`i5_8ineeYS|F0zizNRZVcSV9ktGlUj^3S`@UHuR;&t2nU zn0Vr~(9BS-qI@iDE+9ZCt5K=4${iEN!<#!EeoaJ4z1Q&BC|&ZWfDe+d%@?~1M&+$i z&#`!Lq#4Vxo%al7?3w7wn*@vFhC9pPBrF_IXKG^WHvw3XMBW}BdZFV4(8AkecBb@^ zo0hvLg9}`J37PRM{@(q{>mFlP9GikH9s{f;Pjs zmn`o$M>uh_LV8<-QpM^+PfY?0zvyFb0K-qo#1h8ZU4Yg=0e3|Ca}G!EqmNX+cT!`i zHuVj2i?ojOctYnuCY&(omK0$vSK6DYxcS^P;2=4<_VQ5%;S+N}YgtE=-7J5`TK_j` zS8*0#+0nwBo;yh|B4_~1CPESRGMk9k_`o%Q`|%^W1vRy06}fRin}x(v52^>*sBAu0 zExqi^g-G(6sQGCm9`>5Vik+gN4o}tS9x>GNiS~|S53`VG=1BAHd|&L;hne@%ii!c- z0@>A|(~}VVTop46I4T^cp3J?uc~#Q~%mxr*`|^S6iz0#7{TsRd=Usf{b2CNyXHq-h z?w@y+0@B@7x_i_6f8I4ibxK_Ucj}|*#e@KF&m>#H4*i9m)`)QcqgrP=pL+r&{|)K& z{$OY1`9f=4S3rvO#MgiV>tTGr18a*LH@tF-od{JKaqRwW7SYs7HwTO)?v4T;Z#Ea8C8Hcwi*onlK|lYrnY1jsm}O+FntksimKT8JLaD>41%i0dHy=zk1axIx_d&JXj`dZTYPxq%lsv9SMWp&cE)CiNc-v-llF(?Dn=KM8tRJ* zZjLo^TM}QPOo-s;c%TVt>)w3IEW|^ z$*G*Mij|?~y+m-&$;jZWA*;A$*JF^gu}qsd(6yh&5y)@S|GazuQAtt9S>5t4ua3z; zhP(yNYdd~_K?N54ltK`=@+i!;nz(*1QFITIL>e)xrTM1A@az z`=GW3q#kje#6)Ofs@R8}>Y|?e*rDyYJm|?K&4E1oYand1P3^3xJNxYux2l$wR{7f- zucYb4A&%u%LzPksn=9cOOUY)>0Lqj?e*flu-r}1WFuAxt$tTs>6S{;;oKUndT(>jt z!phu<*0=ap<&^MCBoWQ(@7{_r;9tDxg|4-S>PM^PNUibB)-a$%Da~wzVX4@Cx;5r? zj3;oiVo#+cu35r+bN&JB|9JgDpti^Np zME-{QvdtU$qi;SaTVm<0ODdvoe|ora z`^qF}PtCCg@B5?^IX~n^T2QGeUPcxoHgSKi$R_gY5!gyZO1pkUm33-OLIwz= zO}Y8;uUo`+rnu%AiA=Jk$X<7GBQWgCl~|#!tA<}?K80A>zgy$W^k(B~i>a2)k)zR3 zJ}x_(*g?m+EY$+Vf8REG&1>nwWuCrOEmpo;Zr2)GZ1v38-JiL{moDd3Z?WF3{ZBo02Kr&PiUE30(%~=pW(lo4ZyU;%Z{Q9 z*liM#BHy@b)0}Ee%?|b2L`mJULtez$@!kDDZTe}edFGId#C!Os{}nAZK3u{948rv+ z+-JjU-$j-Akesue{ljsmenwdxc0Wjw8FDUvn@LXp@NT2cwUPzEGhz9$`A#|nEbsvq z*J`)>k@t&$pXZ-76ir-6qC(Y&(^`!+zGd(e1Pq)U4Ftrgd}U?D&D+}>=t!sRUDIJz z%@SPRI8^C9*?0m8B0+MBfNM#ZIn~~u9UM=J?te?1DaI(}XcSl*$gT?6j7s7NGjO;p z^y5MDO|8i@MKcIDRZT0Y@?vDMZ?FzbXacm-f-iUK`;KT(fiR&+NwXQJa=hpm zI&VO`8D1B%Ffb#$s`;?`?Ap?t1$i<#MzXrM)3s>BcK!`DW8r`fTdKFAd!I`Dehhxf zB^tQzqI~HZ&8Wf~!V$B+Lc6R4c_718&*k)00n2`Rbid<}w_E9IQ7K(kJIva!O3L$O zAV)gh^R|#pl9w-w!rB>bWUlq{79+E#Cc3BgnfOBE4Xe=Tfx1w78|km}b-p-a_eayX zfe!|?=SNX{9njr0BdgOzT!S>KnzyY%2iKZ-r(TouO1|pnnNVcMA5Y*fLAphzLHlTd z+TGAHAfO&M`iu#$OYUAEU8jR*Gu0;Zl}ZU=sfTJ+-muIcEMD+%fU6X59Z=;>N1KIb zgv)h}A*HWX`n5Mzr&5&uKdgq=(JggIrcnhip%(pdfi#oOFU7%+vQ_Q49zo=3+QJ2Y(+%P|ci zKunIqX#k3qa>6gqQOzJ$r`=EyHcI80kP&vOo|Wn$4jqJOSn*P~DHSb;TH~YOhytsg zTyrZB{B$y2UJh3)>-0K;`$LJBZ>nmh4<~8%80mG9G(C@@LV0lpJ|UrZjC{FuEq)}? z7doYXyMeJl%RW@VQd{K+gD|h2w(1hzvvk?>olYqXS`K)LX%|MFM(aYU7oAAxNF$t( zG%60{MBqX!>#3B?Rnk#mip>{m2~yi;m`0{ON9hG`eelLd=*W&VU58m%mb+0|u^V}a z4tep!Mnn(b7m`3){U75Y6Uj-^LLl1Z29X&_Azz(lwKY|5u0NCS%zh$h7`_o4|BVKL z-XQx_R!aA}I9`|j6u=`ss^E^3zm7Wu64D>oORM>-7>4#)%{iNwpJW)FE?8XA$mP(} z2tC}9p+$$ad08Q9sa*vpqTrPTpx4+XJ!11M1XJJ)u6hw*J}4C0Yi?!+0jFMni?5Xx z@;9&u0Js@3O>RCBHmnd(pfw$=Z%@X_3=cJgZv>UqcyoePX?mUS$m!#xIVKW!cQ7*h z!IzisxCSg$7zx!dp*Z~vq>>QEFatSRi&B9_;fgUUHl_1c)+84BAW47r%;IYTG}|^5 zB}!@ErKYlX>BIWDK?0$cqo`e2bWd>V`6$OhcPb3V2ZyTw9J|1r+7}QIXa?7=VOf!m zr+;9?6}KJ40~{xYp?ey?(-=+Fx-e6 z?vMn|6I6gqPKpZS((o3#F&Hc5dA}r@-R5N#fE+@qAJ5oa{Jey?8c+&p)lRIs$0~F` zw2BGfb>1$ZV86ULS`=Y4-{P1W8@MUv6`oimOJAR`+5~M$B9@T9E%j2zf}-1gIaRZDbUh}+t>b)i9IiGZ%Zd#DXtGMIL+&0${lerjmGzFSAgT%Y;%{V-76P%xhSd0EH`ykd>Bb@oCX6G+;0I*cZU3 zTYDyvnC-U$jybt!9`jV_%TP@qyS{p`mc4rQy!Fc}dU*@RD-jO;PAqpZC?pqKv`vH1 zZ3|;#w|p33#cy@3Dm|9NOqTr-#eg*+a!QwM z6ujS^r?qX2-z@aEYRN{y{J5G%_%3pY&4pRo%WZj~1st4n1^Haf8YA|CLBw8iJT1Gy zV>u6qxKd$gJ*-Kthy%WfD&JYFRfrqmB4zve{TCetd;A)j{@?as%NWRt3eXZ+==pGa? zo&O%i>y{}B*}f17n9pO}{74o?p0nVB9?r%I=Tr=|`zR-z<}nPonXX+@7~k93sdlFU z$wCGeD2$UE#H7AKZ2?CELr;V)!gq2s@bUKsR?)s~ADLhCEcL-w(M|JVrWx*?U0j4= zt|KLj?HVkE-z`0$I6^=VOd7Tu<)Xi$RmhvzS?pv(wlXqrD32Zv?t0Lkrrwk(s;{r{ zY=qdAonGhfq*aO^;nIIsJe^yKPF|S`;DL-{YKBm&0QJae?HWRHqk!BpjzFSt#0pv+ z`o#h`BY68tc(?jl5IiKh_IF{S#}yQt`9}-Xq31EqIO6i$(9ku|D_j*EUv;|yJ#XWV zD<~t|%MNR`+Np13hMa}}l)EY8;cr9ypFcbzU*~XN_=xFvjs(%VQ3w@54YetV+dbmt zfs_AD2e{KsuF&T+&&8So;u{%8_j$4fsT6YcZ9G)<5Uy5AX!nDL-Vh${T!CqFD;>oT zH;C8oxDe(E5p%OO?3rFEZK>bHQ~;HGx^< z^QePH^qRHPIe`%zK`xG<7%?_agjyb^K1*J+xw;ZSFjg?er^j#&Li{ta z*QNvKC-?E3X=oI9$<;o`u zvo&@fAezGLk3Sz650`C8RGc*H2zx{t9yQO3!ZbvxDNlYlwd>>A_vRWa162#-Ev65I z`n10Q%mgn#g{y5*RAfsS47#FG$h!nwmKUc3m}uod11Om~op;mtn32;=Ao?2$VQ;K| z@_A%h_9e4C678E*=UOU!?NSYVzVx0<@q>xixy~t>v1QXTnLb@y8vOi&dGHTsW4(Ou zik?tjf7YF2BW;;<3@*bOJBiEn!1K_1eou`fDBk74ks} zbnHFH=5|!uH>VaHTo=@5i3s^sN}-_`okPP4zHp2HoO(4v$i}dIGP6`%4~XRlFTuZ+ zxsG80XB{+X*P%r_7o=g~-nm%k+e8=x*ATET_A=D%acom=nyaj|l!oY4thi+-@k`S) zl&&*VHbeiP-z=Du{p%&1`sQ=wt-R^Yd^M&Di2hRQP|j%zx@fnuE}5f&N^z^DsV=cy zZ+N7Fe6eM_kCiV2yk_HD*Yf?hmkQpAM`+_2!DgMOX;;Jd8&@yq!{uAk@)x7rCgBL? z!Bm+rx}(BuoYLNwZi4WpyHu>lED;0r_8@0FO|4urvvR2cM*2CTX@?~K?gO>*ae-c@ zx$d0e&xa;wyymrznRzTvv1iJdg~HU%SWZk?N)n!WHh2kMfWcR@#WI4lmlxecM&Yc3 z_|GYB0{wH601(W0k9*d%?d`11DwPIH0jzS1~XJ~o@7MOEpn$E(b2aRXh+%TWVN zRf|_TeB76l4q5svk9;vX#~K-V?bx(t;5BpNh!~sxVCOiS{;*w(wA8Ad*y zoEKD<`0LL<^Bl``^L!PKx^h_lsDOfED952!%86e^N+ISs8rfWEhm|(Z*xq9A&+K$9 z&NKOoTyd~T8@6Xdg!il4xi`yg;VsuIk6KpOpT-`u1fQlY?TwJN z83-A_4PT5kp^~9#M(}6Ih0<9PYSV9%dh=#{^L4MQk5+x=iX%?bH48x|YK9#!uT@}n zX4ay;5$EP>J4k}v(flK|RJ0A?(?YLG!meqF7Y}}aR|>OV!D34p6;Jco&D zUYs52`>Pkg8Z9vP8-NBbzqZ`kf!Fv%0=s9QU1kx5Oax%mcZf0o>h-AX?CfZ?6c|BB z)u!rxk>&3JCNl+Xo^eaL0dAR(o4tUl6C>l^Qa%F-Na8IfbOr()~bS zx4K``D2U1k;I@&G`$bK#s2KYF=Hc1oNej<>-TO{2KcQk_ZE=~>^!!5_R5Qj6PdX#O zbH;tc@1jM~%v6@eW8qZMod_Pix87d9nM_Kd?3M_SfnG%KHRu`3skeKsp`sMI8;F@= zC+4Oro4pmH9^Yx5A)19@lhaN5UL;e;!ccMY%o$w*e1oxVY}wzrd(4-@`9~^^JC^HP zEullZlOcxpJ6Ibm8gvWJq4QwYDd22Eu1PmGPQF936soLjSluQNk1^>o>?NSH5?0s* z_@(Owf-`(OmnAOKVs0j4&REF;H~o3DebL8Uz4BnS+0Kfv(wQlx`Qd`MvWomI#4J)2-XM1T1Dh`E=}O$@K;4|5p6Pn1S#)Qt-?RihtDl_2y|T z0`|azfkC&iGqhQa|>P-@I)nr_p#r$2!c-DxL=3&O>2=%Pj z?E>a<+(r*%Ye$`s0JWDTYwH6htS47=62iFIS{{5a2$1C^%>345hG_>A)U|c-2K zudhujhP}Bq<^9Mst>un%g^B+~DbH-A!s(+n*AcmeG)I#ZJVbOHIm4!4CNkxU8g~*u zDT2k6o9(c~(ZMml3CwHYheJ#{*&%d0h3#-cpnP2yMULHDN^aHNyLMOnm1P{L-R>AW0Sqr)i?cI%i8d z9#!V)XGC+1ExFr1s^>uv{EY`jO!6Ea6<&XEv*v;@c6y=Ix2ve76tGuSt0X3w6hnW5 z6KB(J_pi))xbYyM@bbOXFD19c{WbI)Ga+OB{Z>ax>)&o1Ln4@*N^*_z?a8f$WnYmA zUfxCGs*~*K&_yw9nH_iI7ZD(q@S-PJGQwqP_8zMszSa9S99ekJ(xKQIUUSNEQjx7? z=q*V71eB@J{(gDOzTjgYc`n~;Q>d&Ow&{L1YG+~Y;TicNV2*nvnPcF_v4B_6C!d{2 zQsjJbfF^t{-;)u*nV-5IoA}h%V?i{u11s|a%o#3%22UeI&P8Sx`&Jp)QRsKN0m{b6 z7w~9Fv`~h)ZBp!=7cfYm72oDopX9eW-_~`g`xrOA$cyR>aG#0gzb1C_;H%iaL~k~K zojlq?Ou?za&{5Y!ftX>lmMZNxjGqeP*)U}cudZqutW%@piRa=nf zd2Nw`#fX=$av|)~@VS=(|V1(Y^{r&<4tG;8C)Mab+ZD z)bHm$LZRdA_R-K598-x%>MN-qqgW2$>dNtW=`J9Z^)JGoesBNiAXRLleCIT;nVF_S z$$|zIQ^?Yzasv|2#{q=C(Idfg2Im!C9K|1vKIwh3&*{=&Go7lWrpx3aRmWjrV5xIQ zsA$vjSpt~|dgZ3=7QV}$zk8mK3OdeSX_rYnEPMJiZ7(S@WNAvof578oo-}TS&xG%p z(is}sAufc_pt-7|PiF*(n@@N}erxJaX6k*@Q&}3indST{4mq$SLyia(uwC}JJ zNR+R;o}_diC1rGP@`-RU-;sX|sJMy)iQoE6Ac@)yB_{v8duucuLG~Ne5`h~nN;e-P z*E>OhY(6)c9w`X6?_PKw|MNoF+4oKwE6ppOBCw`o_WFm`jozpZ^kX6n_;R)+CMak} zqIKBO(LhO4kad3nwW)z@`)@IZdveX?Nvk2^Q0MxzWcEWi42XmoTk4yE36SFqsxM9Q zkgmJ;$JUPoCn>-{%b$*QqvJO81o@reG7bV6r{@ZlBF1KVwD?*xNe35#NyKd6L`pDT z2mje7jDXcija-w@(?|p8nWEUlwFkNDCckBDVvQ2IMdkV%&FQunf|4!}8YNhOH}tbb z9|Dq~O9;~U$%=j7o{7mxeVPFh5zE{VC02Ak6$q5#E?;y1jq+v!^$CtjHf0P2N7lHr zjXnT)qkk%(C=qKm?uScRhyn&FF*3hM2{tcZc+DfK4fJwn;ei0{lzpv%eUOF99NK@B z-YpS0s`Sb0wU(E8)wnTBg|e;bszh#*CwsM?@*1}X2Cg+g98pb3gLw@h{@$KO`CUMI ziD#(w#mfDRj%RCtED@)2;Oy1bgvFl~>;nVNE~qfeP6*B;Db(8|P!*6^$H8F*FLIbk3dJqB=1)J^wLo%!#5(s!37-Err#-@K zKnj=AQ)l1dw6JZe+SC ztM%Uu8siU8cIraNwyx!(yu(1n&j^sFx0Trb6G8tTH1Y&MS=LXyJ5ghME|YT?Yr4+- zo8+KPGaQQtC@XRxaVN*XXKx7sjDN48{p;Tg{J;1h!Aef(+&QWOjQ<~`tb?8ZSCDde z;-L#=op;O16-@9AzAXOgz`8g8p$Y>I;U`JBn@)k7(N%&5h?1r4DrDOc+O-3ov00zg z6-sz=_r$CLVY~H~5`pA2ocW(ac61%zB{KLLf8W^A>7P~E8rr@40LW!3v*O8>FRCR^k`HrXst|FOw`Y_cZUu*n|%Q!D((CjYU? ze{8Z=zix(7%HRB_bT-rF|2s6f`p$8jvU>ql)&)9ZL2bU@+Z;{3b=!5kB}vs5@@#Wh zNJSb*2Cd0Iv&G5xW|~s^=0`_)uH7e=TMMEy>R+hSY~pK)%!ByJ(dfkq2!(RaF?I6k zX?u(DkGvF0(^>0bNC*IN8;Tui{>7-SQ8Yl@X6HEufGrirIHaVE3 z4vt$B{@+TOZcUrMUxD=q%-ZfG6?>2KJs`p-Hfh4UBbSPfyqs z4Zj^B$F_HaRd=+>M&uA*c9b-w#N4fUeFI+?p1b;v4r)h{XUm@aDrh|%*@*%YA{pl* z9gZGzgZ4Z$*xL^rP*v?=jpV&B81q}QW|zA6HjWG4K>^?~C3&U2{uhMWFxg)Yp8^Ki zUw6Cb5+(9$(Kr$s-;N0{mmiZ%OHK7$MqqKdnyQNXtxFvS2#RJTZ-IWd<(0S3sKCU= zS=TzfnQd^*$)CX^Ik)oH!r#AMKnl6Q;v={WPw9QF#bs}pW%Rsn><8`_!n|tRe=>yU z1<(kd$*T>qG8zumZ43IlHSk7y{LiWz6C>j~vRi@DEB^P`kC!1K0;Cq@?jGi+MBP38 zSBmL=VU3s-x%$gOhy)QEK!PrImhIa{JZ!-VnB3~}&-cYC4!k|79s`p>4V+}cwZ#&@ zk+L1IpX?$RBg=e^j@W;-y%BO;{WWb%q#J+dg~mPcl_m<0{7zm+ztp;S@FD+|mQM%X z^1KMWcVBz(*TUl>JyUi3<%S{>!metyM?Z10X+1rd*pRmOfH{3qpPr$+YmVRbr1EfX z*_(zrqu2-=gUHm$)I9dSU?d1zfQmqgqOg!C=E=_CS&E{xfn|)X0078c-gP;8!w)~+ zpY;#t_yel1$AqtbC&@lJ`M@9=ke>s0QvA{_3xGU2Cv5ckwsB|kp5NC52DyTGQnQmF zE&9Uy+{laioRnE)md6!-^kpfjCNGxo0K)lgC{3{mr|N?AUGkFhap*U&bjNTxt9zS* zR-XyZ)?12Fq1iL=fyPJ;`1x)oA2@S&DTuNDGpNDkMubhh6sUC8CUQ+zMqqcmX&vXe z2G2a3DPZr8lSd3%mjA*;7`)PySlY+=ppliy#~&oNGGv@dC=rlxX*m8;6rJqbcluT4 z>MS-Eie#N}TMB!rb@i^z;9O>9Fn9*nVtkBI5zYmFfDX+f)bx{nMXx#___|dS`sVsJ z+z3GC99QWBHz8&LX;wRmF7G{b6QX%FlzQ_P0pB#<-(}}dODh;zICR&KzLcIBj)`TD zgAO@iyr17BG)yYGzd;2~t_Cw_q1cZl><-q-7DBWh4C08k2w%s&VUpkK76cHrnX$lFfuq-t5 zh-)5N!JMxuF3S}BW;uU+pkk>ZjF2kx-iXsRNgwsh<&NJ_6Kzs?y)R4@Yz?upYDkzf zs7bl~balorc-U1Ct5S;c$%)rpiSCI?U~wliXVyYjyU&2F#u z(xIl2*lYw98blbA%t1vu81^aKZ9p_n8o{|`)uC1}e1fNm5nnXagm|4mQkh8W&^+BE zP`v68S2A%IL~9M)0OXzVSn&x2f zcjZzQN)xjf$L5mAKIQ8R9 zsEVZZ$tN5)zm@AdNRu?g@xe_|ogsdQ2M9zRZ?sJm=r}r98Y|_3T4nNC8be2W*`pG( z()Q@|VpN;7U5qB+(}}G!pKbIVg2bZzjtZ2Bqcgp* zt&X;iSNF;qip?gP{_&uqY8+59i zbXH}B3G9{ql|Oi*612AyFJo0Kv_hLmX0;*rmVY6G~|4) zFLbh}iCDk<)|kX84u+|4I>NGy?0R^VkB`!2UaHCGMHEk`^c$Bt)+#pj^FSUB{V%J9ZYBDLYPpjp$>s?@(ih%;7OWnr?u#P!g!x*(yzW@pK3-T5#^#V!ESiC__;BZwj9K+A{W`5pO zn}($yGd?5fGF7cIm)gP`o(BnBFLz{s&53_fUKOOtFSR*Twq4icC)cGDua`TcCLi5f zx1_&3A~i8rBlxc!#L*iducZW9t<&jcRc#u_RoAL!35`R=V^Z8D!4KJ<&d$LhoQl|9 zyQIh^UtlvqQGSPY3L1w$&-Buv2BKKSh@b69EV-oFmpUFxQ;-EYObdxYha?Dwq)q9J zbAh3J8Ou%B{?lm83{fE`PseVhw1BjLqjpN*QZnx!7U82X%b>e}2K``tW^+Ta?E&HM zx=PIhpk>0CQ1Ci)>MxeRa(4F1D+K-BM0^GA1Vr1ma4M|6DG0+jD$?&1T*A^&`cAYA zBG>rW1($zPuTJ$_Tj?3GOy}xo85a^1ej0tmvX{!-?)4C#6^qa)3+C=6FO?8k6 zM_$AL3B`7s$7N)x6IL&8RJcqbs-#;$M#H>!bAPRd0uBH1Cs!%5=H-o~rU)gCX}ds7 zFSKkGqw@2IuLZjl7so83s)7Zy{kxrlaUTLCo$C28;x}a0iG{JLYe3HO%qtkPq0{Ua z_!;z-Qc{WW08~rvxhM)3FuR=41kED7VTz}wMju+55@&UR+efeG=|F56Yv`;L%lq3`X1jt5-5(){3h8J(nPAbC#T(u(YV3g zuv<((rU*4;>1|JR4K&CEd13}gt6)iumPyI585g3BT(d&K8!Hb=)kL+NXXmWCWRGkk zazFu#{$vY|d%8^|(gV+u7|N>UFWLLw2=9A$8Cevvye!7}1Sl+zgP|95L3UL-Qmfa4 zh|0;?+L)kD7)d6>*BsDQ6KQ;UZljdDP+c8iG9E817V zSFItqI))*Ws_uYG1zA{zEW#Ub{BU*BQtz)l4x&NF*`mK{)Ag`N#t04te&EF7t>j>7 zj_Hc-!I`}g#~DHRtN|Zk9RZSY_1Mh%JEVT+qcS}*TuRpq{ogR!UzVf94PX%d=WQ|D z8-zpgEX%oR{Gd+xRS}d>XK1Fg%>rbgYTiByb=OV=Rnxf$+&!3^a--X7X;OK923f8o_iRNC2)KI=k(E{EsF6W|H@QK>S8i*1TgI0i&(8f)e}tr5qWCH9aKO zV5jSplxYhnK^!v$zCPr&$o2NRZuPDT!b0Z!s%iD^Gi#pQY9Wmm0WI9~@SGwAZuv(t z{k7GS7x{ZbYxh=fffM+=5t+l=-#vdT-dXm<0&aNoSIG66Uq_0{BhDFj+BR+caNG;y;$pTM7&k4)<2s2?h#F13@W< z?AD7Ex@KJw6y`A{t-%PUMLp>KT$fyo8 z%?{2$Tz#m3bFM0mkM27eWRw;d1e5vZAVoF3e(4n1|Exrhdsz8jy#Ss_RFO}2^nW`A{(~zA70SNO^%p{ zB=Fzf$sl-O5Hlj*opamcQ;KsMJ4HV5s=E_T@!W>uUp6n*7zPZob7(2+_6bd<$h(cX zyG(WFGxaS7U<+?@BjemRdop!8G0WIkT=ZMkP1KO!A;*mp+io4&^waiHZ0zyR?!FAL z-60fCN?h%aFOPI+H!HPp({9>OSE+-L)h3yfPKhm>P2{lO0F>uRdwOQ`Puu^-6*%6G zqobrKw!L2CGvpntzjJ9P_gavr;j$e;-13?Krm*<@j6+< zzOA@Jx!=O}5Zc&*e4@O1Fq~=IXuNqU#^+o=UQtQCL(zn4Y~7{2A9P|7&8VRn+G9af zi^xwfwL*!Qe%yO8_Q`%rg5>4+whl}e+|3E{U^%;qQ8v3~Vju}AiHyS%Zs%Yb8^9c4 z<}==wMHyq9OUC4P#6<3SgeQhzPjJChZ5axuY2&m6W~lAVF1n(8VB$5WVN)NQa{Haz zouiy=>QIS28D6V5rM~w5~qO-0kdlo#E2Zx^SGx2B`7s5YPbRxWBs!v^clrs=n zL(McPC9cHaO$>~$f&`cc%k$Q=@lu)snU0CTI>UI6ZhKLbc!d255GhEg(4u_1hTR?? z$h1b2eyzEapF$+@D7EpvKQ^gT%ZImcSt|=Z<}qz}N%;tQijCKHv8m5|inDa{V0n;N z_xa=9x04NEci-^rfMv%E(S4mw?#sCelM6@zWtkSJ=rcb*1+KK<6GApmEw@^sKHyf` zPc?^cvlyD!)KCJ}D1Ny81qt3&1&+%-C3JRCKslkiE7xXLPYz2@lEqy}QVx9AQK{ms@%j z-(~DM9B#YB7R`r>K5oreyhz)Lix%lx2}nx~hGL*#Ji> zkG9D&&Z6D+T>+6#I)ghpw4ZMx(@Hyiwe(uQ9y0atx8E&N4#}A5=-RH{(hgq*F`8gD z5@W`q%lnkXuu|VqME|Hm;y_$DlYFVnjF_gEAa(}hjHIgQ`Z%gXaLHMQc2Fn5@)n9! zyi{T0$&5*3LJoZuO>!DTSiKR)dX!rM13QXA3F-Oeg}yf`+u3IXcdrszsuCHUxvCi6 zj9Hwnv9T9^+wT}S*P-*Pj(|?Y5_`D!U(b|p$hF^u(3KVO6!j0gDemvt#!o=>M#OPWG4fx)??zvf zHyjWqLk+4$iqaJGQsVA)d2d+7^m(hRsc-OV3$-5tX7g7wLdB9`J?$-#{F4{+Bb?i- zXQV!Zmofyes<7hbzoLkjR@xL^b4(O-vFKTdM;wPdT4IuyRn!@ill9|~y^Sol^XU)H z5bz&9QIslv*{<#8r4)c(KFOAnzFH#>>r*iEb_IO(d6&6Aq`#UbhhMoW7=G}j5~^v zl3$XaMSEui?ukD`h!$DFjj77+s`Ix(kb(m0I+W{Dt-lY}_F_`xKC}5TruywgMUmbl zCk^hB8XU5bDLv7{BkOCUBf!qu;l<#E@zGxLF?MmjQ)GH6lJw$xmv~Q#A3tX0rThV< zyFMd(;zg6k-?9%D7G;D)o;V?51dSj5oFbW|4h?#5#S2cOXRl{wvhEo%iR@@Ak(|D* zgwTwaQ3Z!N+-v0v@(W6|&RkGl%#QV&!7|Bb1YQdkp~}AY{`X8dAnED6d!eIvXlBi5 zMsUM~@M7cCK%RQrjCU)vAX?_KR9d@@x_5l-`SC1#?`=L(TEwmV;?h@ny-QhV3unIp zot?BeY}+v1Q;X{J7`1v-jcsK83|<$)7PY&j{{=il1SB?N-r!L_R!sQRqxU{4s_TFs zk^$V$qk5S|KC>0dt1R&hab*VD8gu^0=4)<$m%b~Pfjk;1TBR<^V!cs9DGMgU-uB#~ z_`1#4xRR~DbdLAvQT8~z-1WYdfEetOs4NPdP<@wmB|x~fua5c{mk88Pw}XbQ+DP>v zqo_fv=y*Z^uan#>9JDWJA1CYedn~w-xVx-}5?8o-gM__kWN(0k8AYOM@93%6H4pT5 z)ED;uiqe8x$?+HG-3&{6GvyzAw1PGqpW4N+WhB&LUx;6$Unz zEQ?7Y0zrp!;P(toUbVB}gT=W4@p<==%z<4Q?KWL2hhm@C(6M>Zn(ihCC4U~B)2{oGKH7n`J$N|ww zR8(KHKLd(Up!UvEojPBJh)w%77LkU-f|EU?83A7fO;Hha)sqp~qoR&sk>H9fR(V-? zS0}3;DI@e!WsBDv1DV8TK}#Lor;RpMNpeHtXL> zfAwH8Wvgv_@?`rO(0E7hn<-NYE$hD6JAa|z?c|+Zb=UnJFSjW{nGr|f84-uolswE- zb~W=@5#q2356e?@%kNxMPG#*->4heryVdKUS~-^?%C?Yb&NgS|VD)TRHtg6Egk!}# zndY|o&}GlQzBYfqOW9eXuGUk=hxzQJY9PYI&Z+3Q`fyISAx|Ps)9h^nklHTs>VR31 zQ*!CCuwkc%ZPB&DQuF&A3&Ww<7Cu{Z9a5))$?Mz+v9AX6~ zOODVti+J*IcjUTY~M zzhN{BDeZEhbOLZRvKBt~%s>AMA$@Qe9x~LjbhGTxi8#(QBNoxU|JW#lhaGahJQ0Ju z)X++f%}XdB;;q7bod5-2L7wNE!anYszlU{7vv67zP6Nv}g=0|F%s88hH&qB4Bl{6| z-@pgCi^HqzE`y${#<{PqY;<=2w5hHJ1Kd)eGPR?!gL_gyDn!crBFgdLptFycn*?#I zmbeOI&-gNwPvXs@ESAG1ua&EOlq9iNwEA!+CaZ6e2`eYBwbv{tR>J@Zl7*{Jhj_E( z#RUiY9gZfvx-@y{OE&dk+DO~3z~k^-12)&k9N;~LSU|}N7iCL(?PuKnV*?0eu%2j{% z{REO(ab7d`+ehQhneWblbp#jZim0lIKvk@x_X_6u_+VE0DMJn96skxMez)j4wn@Hd z9`)^f==@{n2I$zluavBY$CG)y&@!(+Q|=N0A!`YcXaQASbuj_PloE7v&?)aTMWp%(@~_8qSVd(?v3XI9<@Tyj#6 zaud9FVXUsjs%M1lww0Du-$nC|#o{ZMi-?1^@O~FTF5YO=Gcl>yTZNftMs5>qc<9V9 ziHG!LvRxW7x=#X-Dy$wO6eW`aFC8wOnGloV?Q7;6#Xe4#{Pca$2>{z0dL1;ic+uR? zh&JqR1y2O3d=7c;FK_-nfl(b5zwglAySH96FX&);QCG<7yJ>@sDXD*ov8&Io0A;9Z z&HO0J^5M>4b=iw@sJp6K%;Sm8+$_tYPNFR0OAGP#9k=A3 z;y=$C#TmUhp)QmjaH1<4HhR+rF2Yb%+4a2(JK3o<;5J0tZ*P#JDVc*TiT^*(&75>m5oOp^;_V_@HmHele)HP_>x#r zZA3{g_O^FzCxui}GJ7*z1k8;uCwpxvnfBY;peGVMhtixzLyZzqmuFwlYPSDHF)<@-!OQoVNA^@Q!7dm!xs0=zU!_xCH?Hf8gQD{{S6se__b(*Ai0W1$9P3?EIgC~C%@y4u(s}m#&3^jzIPoD7ts1u5#zmAo6e>PHdbR?)a{sId#su7cBkpe zPX@Yup2lmhuv$A_%+TJ#JF!CQIf{ezUPuVCZOa70nYi6>E ziaFUp9!ZarUHwjaq347EgJ_t23fRH}-quvQ)yZX6#f78)$R`JsL_QwFOoUM=_}TWb#@ysV z{y%~fU2_p|14Vuv<8ZYEt=u$H>@?e!Oys-;oI-w073D20gnwdvV4u>-VZghpN_~|0 zR^@=^$Ar8`(F~h^jAWhtxW7uove|G`b5&zzK(CnRgd|cZzS#x?|Dk*CYXOj%j(9q; zlgd={3jo^j-&atkSjDtWPEO|p2Dzv6+u}|NDfo{AXh(M?F?p@d-!?J+*hklUIC(oAa#1Bzrl6 zzK=?$X#WzbC|9P)#i6@+9G>9BkAz^ZW%HKK&GEkNZ!Y%GK4fmx4i{7s;}tuFE`G(t z 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 + + + + + + + + + + + + + + + + + + diff --git a/docs/assets/images/template_enrollment_params.png b/docs/assets/images/template_enrollment_params.png new file mode 100644 index 0000000000000000000000000000000000000000..ab9721831d1d020e567e44ba26099bb252c272ad GIT binary patch literal 218432 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 literal 0 HcmV?d00001 diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..792bc95 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,15 @@ +--- +title: Changelog +layout: default +nav_order: 6 +--- + +# Changelog + +The changelog lives in one place — the repository's +[`CHANGELOG.md`](https://github.com/Keyfactor/markmonitor-caplugin/blob/main/CHANGELOG.md) — so it +never drifts out of sync with a copy here. See it for the full history of fixes, security updates, +and breaking changes by release. + +For the compiled binaries themselves, see the +[Releases page](https://github.com/Keyfactor/markmonitor-caplugin/releases). diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..f5de100 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,106 @@ +--- +title: Configuration reference +layout: default +nav_order: 4 +--- + +# Configuration reference +{: .no_toc } + +Every connector field, enrollment parameter, and product ID this plugin exposes. +{: .fs-6 .fw-300 } + +1. TOC +{: toc} + +--- + +## CA Connection fields + +These fields appear on the **CA Connection** tab when you register MarkMonitor as a certificate +authority, in both the AnyCA Gateway REST portal and the Keyfactor Command Management Portal. Every +field except `Enabled` must be filled in before the connector can be saved and enabled. + +MarkMonitor CA Connection configuration screen + +| Field | Required | Masked | Default | What it's for | +|---|---|---|---|---| +| `ApiKey` | Yes | Yes | — | Your MarkMonitor API key. | +| `Username` | Yes | No | — | Username for your MarkMonitor service account. | +| `Password` | Yes | Yes | — | Password for your MarkMonitor service account. | +| `BaseUrl` | Yes | No | `https://api.markmonitor.com` | The MarkMonitor API address. Must start with `https://`. | +| `OrgId` | Yes | No | — | Your MarkMonitor organization — either its name (e.g. `MarkMonitor`) or its ID in GUID format. Used both to scope enrollment and to confirm ownership before a revoke. | +| `Enabled` | No | No | `true` | Turns the connector on or off. Useful for saving a connector before all configuration details are ready. | +| `TimeoutSeconds` | No | No | `120` | How long, in seconds, to wait on a single MarkMonitor API call before giving up. Clamped to 1-120. | +| `PageSize` | No | No | `100` | How many certificate orders to request per page during synchronization (1-500). | +| `ForceCompleteSync` | No | No | `false` | When `true`, re-imports every order on every sync instead of skipping ones that haven't changed. | +| `PickupRetries` | No | No | `5` | How many times enrollment polls a freshly-created order for issuance before giving up and returning it pending. `0` turns this off. Clamped to 0-20. | +| `PickupDelaySeconds` | No | No | `10` | How long to wait between issuance pickup polls. Clamped to 0-60. | + +Your API key and password are encrypted in Command's gateway configuration, masked in the UI, and +never written to logs. + +## Gateway Registration + +Before you can enroll, Command and the Gateway both need to trust MarkMonitor's issuing CA chain +(DigiCert). See [Installation](installation#2-trust-the-digicert-issuing-ca-chain) for the download +link, then register it here using either method: + +**A local file path:** + +Gateway Registration using a local file path + +**A Keyfactor Command certificate store** (the store must already exist in Command): + +Gateway Registration using a Command certificate store + +## Certificate templates + +Create one Command certificate template per MarkMonitor product you plan to enroll for (see +[Product IDs](#product-ids) below). Here's an example set up for a GeoTrust DV SSL certificate: + +Example certificate template for a GeoTrust DV SSL product + +## Template enrollment parameters + +Once a template is imported into Command, you can add these optional parameters to it. All of them +are read case-insensitively at enrollment time, so casing doesn't matter. + +Template enrollment parameters + +| Parameter | Type | Default | What it does | +|---|---|---|---| +| `AdditionalEmails` | String | *(none)* | One or more email addresses (comma- or space-separated) that MarkMonitor should send the issued certificate to. | +| `MarkmonitorGroup` | String | *(none)* | A MarkMonitor group to associate the order with — by name or GUID. Left blank or unresolved, it's simply omitted. | +| `MarkmonitorContact` | String | *(org default)* | The MarkMonitor contact for this order — by GUID, email, or full name. Falls back to your organization's default contact. | +| `DCVMethod` | String | `EMAIL` | How MarkMonitor should validate domain control: `EMAIL`, `DNS_CNAME_TOKEN`, `HTTP_TOKEN`, or `DNS_TXT_TOKEN`. An unrecognized value falls back to `EMAIL`. | +| `comments` | String | `Requested via Keyfactor Command` | Free-text note attached to the order. | +| `locale` | String | `en` | Locale for the order. | +| `provider` | String | `DIGICERT` | The certificate provider. `DIGICERT` is currently the only one MarkMonitor supports. | +| `RenewalWindowDays` | Number | `90` | For a Renewal/Reissue request, how many days before its expiration the certificate being replaced must be within before it's revoked. Outside that window, it's left alone and the request is treated like a plain new certificate. | + +For any DCV method other than `EMAIL`, the token/record still needs to be published outside of +Command — this plugin passes your chosen method to MarkMonitor but doesn't automate DNS or HTTP token +publication. + +## Product IDs + +Each row is a MarkMonitor certificate product you can create a Command template for. + +| Product ID | Product family | +|---|---| +| `SslOvBasic` | OV SSL (basic) | +| `SslEvBasic` | EV SSL (basic) | +| `SslDvGeotrust` | GeoTrust DV SSL | +| `SslDvThawte` | Thawte DV SSL | +| `SslOvThawteWebserver` | Thawte OV Web Server SSL | +| `SslEvThawteWebserver` | Thawte EV Web Server SSL | +| `SslOvGeotrustTruebizid` | GeoTrust OV True BusinessID SSL | +| `SslEvGeotrustTruebizid` | GeoTrust EV True BusinessID SSL | +| `SslOvSecuresite` | DigiCert OV Secure Site SSL | +| `SslEvSecuresite` | DigiCert EV Secure Site SSL | +| `SslOvSecuresitePro` | DigiCert OV Secure Site Pro SSL | +| `SslEvSecuresitePro` | DigiCert EV Secure Site Pro SSL | + +Which of these your account can actually order — and any product-specific requirements — depends on +your MarkMonitor entitlements. Check with your MarkMonitor administrator if you're not sure. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..4fc4527 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,61 @@ +--- +title: Home +layout: default +nav_order: 1 +description: MarkMonitor AnyCA Gateway REST plugin for Keyfactor Command. +permalink: / +--- + +# MarkMonitor AnyCA Gateway REST plugin +{: .fs-9 } + +Issue, renew, revoke, and synchronize MarkMonitor SSL certificates directly from Keyfactor Command. +{: .fs-6 .fw-300 } + +[Get started](installation){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } +[See configuration fields](configuration){: .btn .fs-5 .mb-4 .mb-md-0 } + +--- + +> **Pilot integration.** This plugin is a Keyfactor-supported pilot integration. If you run into an +> issue, open a ticket through the [Keyfactor Support Portal](https://support.keyfactor.com) or file +> it on [GitHub Issues](https://github.com/Keyfactor/markmonitor-caplugin/issues). + +## What it does + +Keyfactor Command manages certificate lifecycles centrally across every CA an organization uses. This +plugin plugs MarkMonitor's SSL certificate service into that picture, through Keyfactor's AnyCA +Gateway REST framework — so certificates from MarkMonitor show up, get renewed, and get revoked +alongside every other CA Command already manages. + +

    + +MarkMonitor's SSL certificates are issued by DigiCert, so everything you get through this plugin +chains up to a DigiCert root. + +## Where to go next + +| I want to... | Go to | +|---|---| +| Install the plugin and register MarkMonitor as a CA in Command | [Installation](installation) | +| Understand what MarkMonitor and Keyfactor Command each require before I start | [Overview](overview) | +| Look up a connector field, enrollment parameter, or product ID | [Configuration reference](configuration) | +| See what changed in the latest release | [Changelog](changelog) | + +## Support + +This plugin is supported by Keyfactor for Keyfactor customers. Keyfactor customers with a support +issue should open a ticket through the +[Keyfactor Support Portal](https://support.keyfactor.com). To report a bug or suggest an enhancement, +use [GitHub Issues](https://github.com/Keyfactor/markmonitor-caplugin/issues) or +[Pull Requests](https://github.com/Keyfactor/markmonitor-caplugin/pulls). diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..68bd056 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,80 @@ +--- +title: Installation +layout: default +nav_order: 3 +--- + +# Installation +{: .no_toc } + +Get the plugin installed and MarkMonitor registered as a certificate authority in Keyfactor Command. +{: .fs-6 .fw-300 } + +1. TOC +{: toc} + +--- + +## 1. Install the AnyCA Gateway REST + +If you haven't already, install the Keyfactor AnyCA Gateway REST following the +[official Keyfactor documentation](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/InstallIntroduction.htm). +This plugin requires **AnyCA Gateway REST v25.5.0 or later**. + +## 2. Trust the DigiCert issuing CA chain + +MarkMonitor's certificates are issued through DigiCert, so both the Gateway server and the Command +server need to trust DigiCert's root and intermediate certificates before you can enroll. + +Download the appropriate certificates from +[DigiCert's root certificate page](https://www.digicert.com/kb/digicert-root-certificates.htm) and +import them into: + +- **Trusted Root Certification Authorities** — for the root CA certificate +- **Intermediate Certification Authorities** — for any intermediate certificates + +on both the Gateway server and the Command server. + +## 3. Download and install the plugin + +1. On the server hosting the AnyCA Gateway REST, download and unzip the latest release from the + [Markmonitor-caplugin releases page](https://github.com/Keyfactor/markmonitor-caplugin/releases/latest). +2. Copy the unzipped directory (`net8.0` or `net10.0`, matching your Gateway's .NET version) into the + Gateway's Extensions folder: + + ```text + Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net8.0\Extensions + Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net10.0\Extensions + ``` + + The folder name itself doesn't matter, as long as it's unique within `Extensions`. +3. Restart the AnyCA Gateway REST service. +4. Open the AnyCA Gateway REST portal and hover over the ⓘ icon near the top left to confirm the + Gateway recognizes the MarkMonitor plugin. + +## 4. Register MarkMonitor as a certificate authority + +Follow the +[official AnyCA Gateway REST documentation](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCA-Gateway.htm) +to define a new Certificate Authority, using the **Gateway Registration** and **CA Connection** tabs. + +- On **Gateway Registration**, provide the DigiCert issuing CA certificate you imported in step 2 — + either as a local file path or from a Command certificate store (the store must already exist in + Command). +- On **CA Connection**, enter your MarkMonitor API key, service-account username/password, base URL, + and organization. Field-by-field details are in the + [Configuration reference](configuration#ca-connection-fields). + +## 5. Add the CA to Keyfactor Command and create templates + +1. Follow the + [official Keyfactor documentation](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCA-Keyfactor.htm) + to add the Certificate Authority you just defined to Keyfactor Command, and import its templates. +2. Create one Command certificate template per MarkMonitor product you plan to enroll for — see the + full list in the [Configuration reference](configuration#product-ids). +3. (Command v12.3+) For each imported template, define enrollment fields for the parameters listed in + the [Configuration reference](configuration#template-enrollment-parameters) — all of them are + optional. + +You're ready to enroll. New requests, renewals, revocations, and the recurring sync will now flow +through MarkMonitor. diff --git a/docs/overview.md b/docs/overview.md new file mode 100644 index 0000000..0d06e84 --- /dev/null +++ b/docs/overview.md @@ -0,0 +1,97 @@ +--- +title: Overview +layout: default +nav_order: 2 +--- + +# Overview +{: .no_toc } + +1. TOC +{: toc} + +--- + +## How the pieces fit together + +Three systems are involved, and each one plays a different role: + +- **Keyfactor Command** is where your team requests, tracks, and manages certificates. +- **The AnyCA Gateway REST** is Keyfactor's connector host — it's what actually talks to a + certificate authority on Command's behalf. This plugin is a DLL that the Gateway loads. +- **MarkMonitor** is the certificate authority itself, issuing SSL certificates that ultimately chain + up to a DigiCert root. + +When someone requests a certificate in Command, the request travels through the Gateway to this +plugin, which translates it into a MarkMonitor order. The reverse happens for revocation, and a +recurring sync job keeps Command's records of MarkMonitor certificates up to date automatically. + +## What you'll need + +Before installing, have these ready: + +- A MarkMonitor **API key** — contact MarkMonitor support to obtain one. +- A MarkMonitor **service account** (username and password) with permission to create certificate + orders. +- The **organization** name or ID that certificates should be ordered under. +- Keyfactor Command v12.0.0 or later. +- Keyfactor AnyCA Gateway REST v25.5.0 or later. +- Network access from the Gateway server to the MarkMonitor API, and the DigiCert root/intermediate + CA certificates trusted on both the Gateway server and the Command server. See + [Installation](installation) for the download link and where they go. + +## Two credentials, not one + +Most CAs Command connects to use a single API key or an OAuth client. MarkMonitor uses **two** +credentials together, and both are required: + +1. An **API key**, which identifies your MarkMonitor account. +2. A **service-account username and password**, which the plugin exchanges for a short-lived access + token behind the scenes. + +You'll enter all three — API key, username, password — when you configure the CA connector in +Command. There's nothing further to manage day to day: the plugin keeps itself authenticated and +refreshes the token automatically. + +## What you can do once it's set up + +- **Enroll** for any MarkMonitor SSL product your account is entitled to — OV, EV, and DV + certificates across the GeoTrust, Thawte, and DigiCert Secure Site product families. +- **Renew or reissue** a certificate. MarkMonitor doesn't have a true "renew in place" — so a renewal + places a new order, and once the replacement certificate is ready, the plugin retires the one it's + replacing. +- **Revoke** a certificate you no longer need. The plugin double-checks that the certificate actually + belongs to your configured MarkMonitor organization before revoking it. +- **Sync automatically.** On each sync, Command pulls in every certificate your organization can see + from MarkMonitor, complete with the full certificate chain. + +## Common questions + +**I enrolled, but the certificate didn't come back right away — is something wrong?** + +No — this is expected. MarkMonitor certificates go through Domain Control Validation (and sometimes +manual approval) before they're issued, so a brand-new request typically comes back in a pending +state rather than with a certificate attached. Command shows it as pending validation; the next +automatic sync picks up the certificate as soon as MarkMonitor issues it. + +**My ECC certificate request was rejected — why?** + +MarkMonitor requires ECC certificate requests to use a **named curve** (for example, P-256), not one +that spells out its curve parameters explicitly. The plugin checks for this before submitting your +request, so you'll see a clear error immediately instead of a silent failure on MarkMonitor's side. +Regenerating the CSR with a named curve resolves it. + +**I retried a request that seemed stuck, and got a warning about a duplicate submission — did it go +through twice?** + +No. If Command retries a request (for example, after a dropped connection), the plugin recognizes the +retry and returns the original result instead of placing a second order with MarkMonitor. + +**Revocation failed with an error about the certificate belonging to a different organization.** + +The plugin won't revoke a certificate unless it can confirm the certificate belongs to the MarkMonitor +organization your CA connector is configured for. Double-check that the connector's `OrgId` field +matches the organization that actually owns the certificate. + +Looking for a specific connector field or enrollment parameter? See the +[Configuration reference](configuration). diff --git a/docsource/CODEMAP.md b/docsource/CODEMAP.md new file mode 100644 index 0000000..f4a9946 --- /dev/null +++ b/docsource/CODEMAP.md @@ -0,0 +1,185 @@ +# CODEMAP + +> **Purpose:** a fast orientation map of this repository for humans and AI agents. Read this first +> before diving into the source. +> +> **⚠️ Maintenance rule — any agent (or developer) that makes a code change MUST update this +> CODEMAP in the same change** if the change adds/removes/moves a source file of note, alters the +> architecture or a data flow, changes the build/test layout, or changes config/enrollment fields or +> product IDs. Keep it terse and accurate; a stale codemap is worse than none. This file is committed +> to the repo + +Last verified against the codebase: 2026-08-12. + +> To understand behavior, read this CODEMAP + the source it points to — **not** the root `README.md` +> (it's a generated artifact; parsing it wastes tokens). A CI check fails a PR that changes plugin +> source without updating this file (add the `skip-codemap` label to override). + +## What this is + +An AnyCA REST Gateway plugin that lets Keyfactor Command issue, revoke, and synchronize certificates +through the MarkMonitor SSL certificate API. It implements `IAnyCAPlugin` from +`Keyfactor.AnyGateway.Extensions` and is loaded as a DLL extension by the AnyCA Gateway REST host +process — **not** a standalone service. Plugin type: +`Keyfactor.Extensions.CAPlugin.MarkMonitor.MarkMonitorCAPlugin`. + +MarkMonitor's SSL API is backed by **DigiCert** (the only `provider` it supports). + +## Solution layout + +| Project | Role | +|---|---| +| `markmonitor-caplugin/` | The plugin. Dual-targets `net8.0` + `net10.0`; produces `MarkMonitorCAPlugin.dll` per TFM under `bin/Release//`, with `manifest.json` copied alongside (host discovery). | +| `markmonitor-caplugin.Tests/` | xUnit unit tests (mocked HTTP via `FakeHttpMessageHandler`; no live API). Targets `net8.0`. CI-safe; run by `.github/workflows/unit-tests.yml`. | +| `markmonitor-caplugin.IntegrationTests/` | xUnit live-API tests (real `MarkMonitorClient` calls: authenticate, list orgs, list certificate orders, RSA/ECC enroll). Targets `net8.0`; references `TestConsole` solely to reuse its `CsrGenerator`/`EmailAddressGenerator` helpers. Every test skips silently (no-op pass) when the `MARKMONITOR_*` env vars aren't set, so it's safe to run without creds — but when creds are present it hits the live API and creates/cleans-up (cancel, falling back to revoke) real orders. **Not** run by `unit-tests.yml` (that workflow targets the `.Tests` csproj directly); run manually via `.github/workflows/integration-tests.yml` (`workflow_dispatch` only) against the `markmonitor-integration` GitHub environment, which holds the `MARKMONITOR_*` secrets behind required-reviewer approval. | +| `TestConsole/` | Manual live smoke-test console app (creates REAL orders). Needs `MARKMONITOR_*` env vars. Not CI-safe. | + +## Key files (`markmonitor-caplugin/`) + +| File | Responsibility | +|---|---| +| `MarkMonitorCAConnector.cs` | `IAnyCAPlugin` entry point. Methods the Gateway host calls: `Initialize`, `Enroll`, `Revoke`, `Synchronize`, `GetSingleRecord`, `Ping`, `ValidateCAConnectionInfo` (field checks, then a live auth + org-list call via a transient client - never `_cachedClient`), `ValidateProductInfo` (cheap static `ProductID` enum check only - contact/group stay a no-op), `GetProductIds`, `GetCAConnectorAnnotations` / `GetTemplateParameterAnnotations`. `BuildClient(MarkMonitorConfig)` is the one place the client-construction argument list lives, shared by the cached-client path and `ValidateCAConnectionInfo`'s transient one. Holds the deserialized config and one lazily-built, cached `MarkMonitorClient` (`CreateAndAuthenticateClientAsync`). Contains the `RenewOrReissue` → revoke-prior logic (`ParseRenewalWindowDays` logs a warning, not a silent fallback, when the template param is present but invalid) and the `EnsureOrgNameConfigured` guard. | +| `Client/MarkMonitorClient.cs` | The MarkMonitor REST HTTP client. Owns: bearer-token auth (`X-API-KEY` header + username/password → token, cached with 30s early-expiry, double-checked locking); list pagination (`MarkMonitorPage.TotalPages`); CSR PEM/DER handling via BouncyCastle; ECC named-curve validation; the process-local enrollment dedup cache (5-min, keyed org\|product\|subject\|csr); `MarkMonitorCertificateStatusToCAStatus` mapping; `BuildErrorString` error parsing; org/contact/group resolution; `SendWithRetryAsync` (3-attempt retry with jittered exponential backoff on network failures/timeouts and 5xx/429, honoring `Retry-After` on 429 capped at 120s - **not** used for the order-create POST, the reissue PATCH, or `AuthenticateAsync`'s own POST: the first two risk creating a duplicate billable resource on an ambiguous failure, and auth runs inside `_authLock`, so retrying there would multiply how long *every* concurrent caller on the same cached client blocks, not just the degraded call); `HttpClient.Timeout` from the `TimeoutSeconds` config field (default 120s, clamped 1-120 - never above the pre-existing hardcoded default). | +| `MarkMonitorCAPluginConfig.cs` | CA-connection + enrollment-parameter schema, UI annotations/defaults, and canonical field-name constants: `ConfigConstants` (ApiKey, Username, Password=`"Password"`, BaseUrl, OrgId=`"OrgId"`, Enabled, TimeoutSeconds, PageSize, ForceCompleteSync, PickupRetries, PickupDelaySeconds) and `EnrollmentConfigConstants` (AdditionalEmails, MarkmonitorGroup, MarkmonitorContact, DCVMethod, comments, locale, provider, RenewalWindowDays). Also `ConfigurationValidationException`. | +| `MarkMonitorConfig.cs` | The deserialized CA-connection config type used at runtime. | +| `Models/` | Request/response DTOs (orders, organizations, contacts, groups, token) + `Enums.cs`. | +| `Models/Enums.cs` | `CertOrderTypes` (product IDs → API strings via `[Description]`), `OrderStatus`, `OrderActions`, `AlgorithmTypes`, `DomainControlValidationMethods`, `CertServerPlatforms`, and `EnumExtensions.GetDescription()`. | +| `Constants.cs` | Empty placeholder — real constants live in `MarkMonitorCAPluginConfig`. | + +## Core flows + +- **Auth:** `POST /auth/v1/auth/authenticate` with `X-API-KEY` header + `{username,password}` → bearer + token (cached, lazy refresh). No OAuth. +- **Enroll:** dedup-check → resolve org/contact/group → parse+validate CSR (reject ECC explicit + curve) → `POST /certs/v1/order`. Accepted orders usually return `CREATED` → + `EXTERNALVALIDATION` (pending DCV/approval) - MarkMonitor never issues synchronously from the + create-order call. `PollForIssuanceAsync` (inside the dedup reservation, so a folded-in concurrent + duplicate sees the polled result too) then polls its own single-attempt order fetch (not itself + retried, unlike most other GETs - see `Client/MarkMonitorClient.cs` above) up to `PickupRetries` + times (every `PickupDelaySeconds`) for a product whose DCV/approval resolves quickly, stopping + early on either issuance or a terminal non-issued status; `PickupRetries=0` (not the default) + skips polling entirely. Whatever order comes back (from polling or straight from order creation), + `EnrollCertificateAsync` downgrades a `GENERATED`-mapped status with a still-null cert body to + `INPROCESS` before returning - MarkMonitor's status can flip to issued a moment before the cert + body itself is populated, and reporting a false `GENERATED` with no certificate would be an + internally inconsistent result. `RenewOrReissue` places a new order then revokes the prior cert (via + `PriorCertSN` → `ICertificateDataReader`), but only when that prior cert's resolvable expiration + date is within its `RenewalWindowDays` template param (default 90) - if it's resolvable and + outside the window, the prior cert is left unrevoked and the request behaves like a plain new + issuance (unresolvable expiration falls back to always revoking, the pre-existing behavior). No + in-place renew/reissue in the enroll path. MarkMonitor issues CN ∪ order `dnsNames` - it does + **not** honor a CSR's own SAN extension as authoritative - so `BuildDnsNames` uses the Enroll + `san` dictionary (`Dns`/`dnsname` keys, case-insensitive) as the primary source; a SAN extension + embedded in the CSR itself is used only when `san` is `null` (Command never populated SAN data at + all), never when it's non-null even if empty, since a non-null dictionary means Command's own + enrollment pattern is authoritative for this request and a subscriber-generated CSR must not be + able to add domains beyond what that pattern authorized. Non-DNS SAN types (IP/email/URI) have no + MarkMonitor field and are dropped with a logged warning. +- **Revoke:** requires `OrgId`; resolves it to a GUID, fetches order, compares owning org as parsed + GUIDs, then `PATCH /certs/v1/order/{id}/revoke`. Reason code has no MarkMonitor field (logged only). + `CancelCertificateAsync` takes the same optional `orgName` parameter and runs the identical + cross-organization ownership check (shared via a private `EnsureOrderBelongsToOrganizationAsync` + helper) before `PATCH /certs/v1/order/{id}/cancel`. +- **Sync:** `GET /certs/v1/order` paginated (size from the `PageSize` config field, default 100), + map status, assemble full chain, buffer issued certs. Still **always a full listing** — + `lastSync`/date filtering not yet used — but each record is now checked against + `ICertificateDataReader` and skipped if Command already has it at both the same mapped status + *and* the same expiration date (skip-unchanged) - comparing only status would otherwise treat an + out-of-band MarkMonitor reissue of the same order ID (which round-trips DIGI_ISSUED → + DIGI_REISSUE_PENDING → DIGI_ISSUED) as unchanged if a sync happens to straddle just the before/ + after of that round-trip; `ForceCompleteSync` (config) or Command's own `fullSync` flag bypasses + the optimization entirely. A bad individual record is logged + counted + skipped rather than + aborting the sync, but an error rate over 25% (once ≥50 records observed) aborts the whole sync as + a circuit breaker (checked per-record via `Interlocked` counters, but only enforced at the end of + the current page, not the instant it crosses - see below). Records within one page are processed + with bounded concurrency (`Parallel.ForEachAsync`, max 10 at a time) rather than sequentially, + since the skip-unchanged check's local `ICertificateDataReader` round-trips would otherwise + serialize (and block the next MarkMonitor page fetch behind) a large sync's entire record count. + +### MarkMonitor endpoints + +`POST /auth/v1/auth/authenticate` · `GET|POST /certs/v1/order` · `GET /certs/v1/order/{id}` · +`PATCH /certs/v1/order/{id}/{revoke|cancel|reissue}` · `GET /certs/v1/organization[/{id}]` · +`GET /auth/v1/group`. (cancel/reissue exist in the client but are **not** wired into `IAnyCAPlugin`.) + +### Status mapping (`OrderStatus` → `EndEntityStatus`) + +`CREATED`→EXTERNALVALIDATION · `DIGI_ISSUED`→GENERATED · `DIGI_REVOKED`→REVOKED · +pending set (`DIGI_PENDING`/`DIGI_PROCESSING`/`DIGI_REISSUE_PENDING`/`DIGI_WAITING_PICKUP`/ +`REISSUE_PENDING`/`DIGI_NEEDS_APPROVAL`/`REISSUE_REQUEST_PENDING`)→INPROCESS · +`DIGI_FAILED`/`DIGI_REISSUE_FAILED`→FAILED · +`DIGI_CANCELED`/`DIGI_REJECTED`/`DIGI_EXPIRED`/`DIGI_NEEDS_CSR`→CANCELLED · else→FAILED. + +## Gotchas / non-obvious behavior + +- **Two credentials, used together:** API key (header) *and* service account (token). Missing either + fails auth. +- **ECC CSRs must use a named curve** — explicit curve params are silently failed by MarkMonitor, so + the plugin rejects them up front (`ValidateEccCsrUsesNamedCurve`). +- **DSA is not supported** for CSRs. +- **Enrollment dedup cache** is process-local and short-lived — guards Command retries only, not a + durable store. Failed attempts are not cached. +- **`OrgId`** accepts a name or GUID; blank `OrgId` skips the revoke ownership check for some paths + but `Revoke` refuses to run without it. +- **Org name resolution requires an exact (case-insensitive) name match** — `ResolveOrganizationAsync`/ + `ResolveOrganizationIdAsync` filter MarkMonitor's `/certs/v1/organization?name=` search results down + to an exact match rather than taking the first result, since that endpoint's own matching semantics + aren't guaranteed to be exact (a configured name that's a substring of another org's name must not + silently resolve to the wrong org — [#9](../../issues/9)). +- **Order IDs** are validated as GUIDs before being interpolated into URLs. +- **Revocation reason** cannot be forwarded to MarkMonitor (no schema field). +- **`ValidateProductInfo`'s contact/group handling stays a no-op** — resolved and defaulted at enroll + time, not validated at template save (a deliberate tradeoff documented in the method's own + comment). It does now reject an unparseable `ProductID` (a cheap static enum check, no live call). +- **`ValidateCAConnectionInfo` makes a live MarkMonitor call** (authenticate + list one organization) + after its field checks pass, via a transient client built from the connectionInfo being saved - + never `_cachedClient`. A constructor-injected client (the same test seam every other method uses) + is reused as-is and left undisposed, rather than building a second transient one, so tests don't + need a live API. + +## Build / test / deploy + +```shell +dotnet build markmonitor-caplugin.sln -c Release # build (both TFMs) +dotnet test markmonitor-caplugin.sln -c Release # unit + integration tests (integration tests no-op skip without MARKMONITOR_* env) +dotnet test markmonitor-caplugin.IntegrationTests -c Release # live-API tests only (skips without MARKMONITOR_* env; creates/cleans up real orders when creds present) +dotnet run --project TestConsole # live smoke test (needs MARKMONITOR_* env; destructive) +``` + +Deploy: copy a TFM output dir into the Gateway `Extensions` folder, restart the AnyCA Gateway REST +service. + +## Docs & metadata to keep in sync + +- `docs/` — the customer-facing GitHub Pages site (Jekyll + the `just-the-docs` remote theme, + Keyfactor-branded via `docs/_sass/color_schemes/keyfactor.scss`), published from `main`/`docs` with + no Actions workflow. **Not** generated from `docsource/` — its five pages (`index.md`, + `overview.md`, `installation.md`, `configuration.md`, `changelog.md`) carry independently-written, + lighter-tone copy aimed at customers, and its own copies of the screenshots under + `docs/assets/images/` (copied from `docsource/images/`, not symlinked). When a connector field, + enrollment parameter, or product ID changes, update both `docsource/configuration.md` (feeds + `README.md`) **and** `docs/configuration.md` (feeds the Pages site) — they are two separate, + hand-maintained copies by design, not one generating the other. `docs/changelog.md` only links out + to the root `CHANGELOG.md`; Jekyll's build root is `docs/`, so it cannot `include_relative` a file + outside that directory. Preview it locally before publishing with `just docs-preview` (needs + Docker; runs Jekyll via the `jekyll/jekyll` image, no local Ruby toolchain required) at + `http://localhost:4000/markmonitor-caplugin/`; `docs/Gemfile` pins the plugins (`jekyll-remote-theme`, + `jekyll-seo-tag`, `jekyll-include-cache`) `just-the-docs` needs that aren't in the base image. +- `docsource/configuration.md` and `docsource/overview.md` — source-of-truth, customer-facing doc + fragments, plus this `CODEMAP.md`. Root `README.md` is **generated by doctool** + (`Keyfactor/doctooldotnet`, cloned at `~/RiderProjects/doctooldotnet`) from `docsource/ + configuration.md` + `integration-manifest.json` — never hand-edit `README.md`; edit + `docsource/configuration.md` and regenerate: + `cd ~/RiderProjects/doctooldotnet && just build && just docs markmonitor-caplugin`. + Only `configuration.md` (including its hand-written `## How It Works` custom section) and the + manifest feed the README; `overview.md` stays standalone. Images referenced from + `configuration.md` must use `docsource/images/...`. (`readme_source.md` is a stale placeholder and + is not used.) +- Root `DEVELOPMENT.md` is the hand-maintained developer guide (solution layout, build/test, + `TestConsole` smoke-testing, and full architecture/design internals with real class and method + names) — like `LICENSE`, it is **not** part of the doctool pipeline and is edited directly. + `docsource/architecture.md`, `docsource/development.md`, and the internal-only + `docsource/enrollment.md` have been removed/merged into it (the MarkMonitor login walkthrough in + the old `enrollment.md` now lives in an internal Confluence doc, not this repo). +- `integration-manifest.json` — catalog metadata (`product_ids`, `ca_plugin_config`, + `enrollment_config`). Keep aligned with `MarkMonitorCAPluginConfig.cs` and `CertOrderTypes`. diff --git a/docsource/configuration.md b/docsource/configuration.md new file mode 100644 index 0000000..cce4137 --- /dev/null +++ b/docsource/configuration.md @@ -0,0 +1,390 @@ +## Overview + +The MarkMonitor AnyCA Gateway REST plugin extends the certificate lifecycle capabilities of the +MarkMonitor SSL certificate service to Keyfactor Command via the Keyfactor AnyCA Gateway REST. It +implements `IAnyCAPlugin` and is loaded as a DLL extension by the AnyCA Gateway REST host process — +it is not a standalone service. The plugin supports the following capabilities: + +* CA Synchronization: + * Downloads all certificate orders visible to the configured MarkMonitor organization and + imports the issued certificates (and their chains) into Keyfactor Command. + * Orders that have not yet produced a certificate are mapped to the appropriate pending/failed + status rather than imported as certificates. +* Certificate Enrollment for the SSL product types MarkMonitor exposes: + * Submits a new MarkMonitor certificate order per product type. + * A process-local dedup guard prevents Keyfactor Command retries from creating duplicate orders. +* Renewal / Reissue: + * MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a + `RenewOrReissue` enrollment places a **new** order and then revokes the prior certificate once + the replacement has been created successfully. +* Certificate Revocation: + * Revokes a previously issued certificate, with a cross-organization ownership check that refuses + to revoke an order belonging to a different organization than the one the CA connector is + configured for. + +MarkMonitor's SSL API is backed by DigiCert (the only certificate `provider` its API currently +supports), so issued certificates chain up to DigiCert roots. + +## Requirements + +- A MarkMonitor **API Key** (contact MarkMonitor support to obtain one). +- A MarkMonitor **service account** (username and password) with permission to create certificate + orders. +- The **organization** name or ID (GUID) the certificates will be ordered under. +- Keyfactor Command >= v12.0.0. +- AnyCA Gateway REST >= v25.5.0. +- Network connectivity from the AnyCA Gateway host to the MarkMonitor API base URL, and trust of the + DigiCert issuing CA chain on both the gateway host and the Command server (see + [Gateway Registration](#gateway-registration)). + +## MarkMonitor API Setup + +MarkMonitor requires **two** credentials that are used together (there is no OAuth mode): + +1. **API Key** — sent as the `X-API-KEY` header on the authentication request. Enter it in the + `ApiKey` connector field (masked in the Command UI). +2. **Service-account username and password** — POSTed to `/auth/v1/auth/authenticate`, which returns + a short-lived bearer token used on all subsequent calls. Enter them in the `Username` and + `Password` connector fields (the password is masked in the UI). + +Contact your MarkMonitor administrator to provision the API key and a service account with order +permissions, and to confirm the correct API base URL and organization name/ID for your environment. + +## Gateway Registration + +In order to enroll for certificates the Keyfactor Command server must trust the issuing CA chain. +MarkMonitor's default issuing CA (`provider`) is **DigiCert** — download and import the appropriate +certificate chain from to the AnyCA +Gateway host and Command server. + +Once the necessary files are copied to the appropriate locations and the AnyCA Gateway REST is up and +running, navigate to the AnyCA Gateway REST portal and configure the CA. + +### Using file path for issuing CA certificate +![gateway_registration_local_file.png](docsource/images/gateway_registration_local_file.png) + +### Using Keyfactor Command certificate store for issuing CA certificate +> **⚠️ Warning:** The cert store must already exist in Keyfactor Command. + +![gateway_registration_store.png](docsource/images/gateway_registration_store.png) + +## CA Connection Configuration + +The following fields are presented in the AnyCA Gateway REST portal (and the Keyfactor Command +Management Portal) when creating or editing the MarkMonitor CA connector. All fields except `Enabled` +must be provided before the connector can be saved in an enabled state. + +![gateway_ca_configuration.png](docsource/images/gateway_ca_configuration.png) + +| Field | Required / Optional | Masked | Default | Description | +|---|---|---|---|---| +| `ApiKey` | Required | Yes | *(none)* | The MarkMonitor API key, sent as the `X-API-KEY` header when authenticating. | +| `Username` | Required | No | *(none)* | Username for the MarkMonitor API service account. | +| `Password` | Required | Yes | *(none)* | Password for the MarkMonitor API service account. | +| `BaseUrl` | Required | No | `https://api.markmonitor.com` | The MarkMonitor API base URL. Must start with `https://` — credentials and the bearer token are sent to it. | +| `OrgId` | Required | No | *(none)* | The MarkMonitor organization to use for API calls. Accepts either the organization **name** (e.g. `MarkMonitor`) or its **ID in GUID format**. Used to scope enrollment and to verify ownership on revoke. | +| `Enabled` | Optional | No | `true` | Enables or disables gateway functionality. Disable to allow the CA to be created before configuration information is available. | +| `TimeoutSeconds` | Optional | No | `120` | The HTTP request timeout, in seconds, for calls to the MarkMonitor API. Clamped to 1-120. | +| `PageSize` | Optional | No | `100` | The number of certificate orders requested per page during synchronization. Clamped to 1-500. | +| `ForceCompleteSync` | Optional | No | `false` | When `true`, bypasses the skip-unchanged synchronization optimization and re-emits every order on every sync. | +| `PickupRetries` | Optional | No | `5` | How many times `Enroll` polls a freshly-created order for issuance before returning it in its still-pending state. `0` disables polling. Clamped to 0-20. | +| `PickupDelaySeconds` | Optional | No | `10` | The delay, in seconds, between issuance pickup polls. Clamped to 0-60. | + +> **Note:** Credentials are stored in Keyfactor Command's encrypted gateway configuration. `ApiKey` +> and `Password` are masked in the UI and are never written to logs by the plugin. + +## Certificate Template Creation Step + +A certificate template must be created in Keyfactor Command for each MarkMonitor product type you +want to enroll. One template is required per product type (see [Product IDs](#product-ids)). Below is +an example of a template for a GeoTrust DV SSL certificate. For more on certificate product types, +contact your MarkMonitor administrator or support. + +![gateway_template.png](docsource/images/gateway_template.png) + +## Template Enrollment Parameters + +Custom enrollment parameters can be added to templates in Keyfactor Command after they have been +imported from the AnyCA Gateway. **All parameters are optional** and are read case-insensitively at +enrollment time. + +![template_enrollment_params.png](docsource/images/template_enrollment_params.png) + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `AdditionalEmails` | String | *(empty)* | Zero or more comma-separated email addresses that MarkMonitor will send the issued certificate to. Spaces are also treated as separators. | +| `MarkmonitorGroup` | String | *(none)* | The name or GUID of a MarkMonitor group to associate with the order. Matched by GUID or exact (case-insensitive) name against the account-wide group list. A blank or unresolved value is omitted (best-effort). | +| `MarkmonitorContact` | String | *(org default)* | The GUID, email, or `First Last` name of a MarkMonitor contact within the organization. Falls back to the organization's default contact if not specified or not resolvable. | +| `DCVMethod` | String | `EMAIL` | Domain Control Validation method. Valid values: `EMAIL`, `DNS_CNAME_TOKEN`, `HTTP_TOKEN`, `DNS_TXT_TOKEN`. An invalid value logs a warning and falls back to `EMAIL`. | +| `comments` | String | `Requested via Keyfactor Command` | Free-text comments attached to the MarkMonitor order. | +| `locale` | String | `en` | Locale for the MarkMonitor order. | +| `provider` | String | `DIGICERT` | The certificate provider for the order. `DIGICERT` is currently the only provider the MarkMonitor API supports. | +| `RenewalWindowDays` | Number | `90` | For a `RenewOrReissue` enrollment, how many days before its expiration the prior certificate must be within before it's revoked after the replacement issues. Outside that window, the prior certificate is left unrevoked and the request is treated like a plain new issuance. An invalid (non-numeric or non-positive) value falls back to the default. | + +> **Note on DCV:** The plugin passes the selected `DCVMethod` to MarkMonitor but does not itself +> automate DNS/HTTP token publication. For `EMAIL` (the default), MarkMonitor falls back to the +> domain/organization's registered DCV contacts; the plugin sends an empty `dcvEmails` list. + +## Product IDs + +`GetProductIds()` returns the names of the `CertOrderTypes` enum. The **Product ID** column is the +value Keyfactor Command sees and stores; the plugin maps it to the **MarkMonitor cert type** string +(the enum's `[Description]`) when placing an order. Adding a new MarkMonitor product means adding an +enum member with the matching `[Description]` — not editing a separate list. + +| Product ID (Command) | MarkMonitor cert type | Typical product family | +|---|---|---| +| `SslOvBasic` | `SSL_OV_BASIC` | OV SSL (basic) | +| `SslEvBasic` | `SSL_EV_BASIC` | EV SSL (basic) | +| `SslDvGeotrust` | `SSL_DV_GEOTRUST` | GeoTrust DV SSL | +| `SslDvThawte` | `SSL_DV_THAWTE` | Thawte DV SSL | +| `SslOvThawteWebserver` | `SSL_OV_THAWTE_WEBSERVER` | Thawte OV Web Server SSL | +| `SslEvThawteWebserver` | `SSL_EV_THAWTE_WEBSERVER` | Thawte EV Web Server SSL | +| `SslOvGeotrustTruebizid` | `SSL_OV_GEOTRUST_TRUEBIZID` | GeoTrust OV True BusinessID SSL | +| `SslEvGeotrustTruebizid` | `SSL_EV_GEOTRUST_TRUEBIZID` | GeoTrust EV True BusinessID SSL | +| `SslOvSecuresite` | `SSL_OV_SECURESITE` | DigiCert OV Secure Site SSL | +| `SslEvSecuresite` | `SSL_EV_SECURESITE` | DigiCert EV Secure Site SSL | +| `SslOvSecuresitePro` | `SSL_OV_SECURESITE_PRO` | DigiCert OV Secure Site Pro SSL | +| `SslEvSecuresitePro` | `SSL_EV_SECURESITE_PRO` | DigiCert EV Secure Site Pro SSL | + +> **Note:** The "typical product family" column is descriptive. Which product types your MarkMonitor +> account may actually order — and any per-product required fields — depend on your account's +> entitlements. Confirm availability with your MarkMonitor administrator. + +## How It Works + +This section describes, at a high level, how the plugin connects Keyfactor Command's certificate +lifecycle operations to the MarkMonitor SSL certificate service. + +### Component Overview + +``` +┌─────────────────────────────────────────────────────────┐ +│ Keyfactor Command │ +│ │ +│ Certificate Enrollment · Revocation · Sync Jobs │ +└────────────────────────────┬─────────────────────────────┘ + │ + AnyCA Gateway REST + (plugin host process) + │ +┌────────────────────────────▼─────────────────────────────┐ +│ The MarkMonitor plugin │ +│ │ +│ Translates Keyfactor operations into MarkMonitor API │ +│ calls and maps responses back to Command's data model. │ +└────────────────────────────┬─────────────────────────────┘ + │ HTTPS · Bearer token + X-API-KEY + │ +┌────────────────────────────▼─────────────────────────────┐ +│ MarkMonitor REST API (DigiCert) │ +│ │ +│ /auth/v1/auth/authenticate /certs/v1/order │ +│ /certs/v1/organization /auth/v1/group │ +└──────────────────────────────────────────────────────────┘ +``` + +### Synchronization + +Keyfactor Command periodically synchronizes its certificate inventory with MarkMonitor. The plugin +retrieves all certificate orders visible to the configured organization, page by page, and imports +issued certificates — along with their full certificate chain — into Command. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Start synchronization + Plugin->>API: Authenticate with MarkMonitor + + loop Retrieve one page of orders at a time + Plugin->>API: List certificate orders + API-->>Plugin: Page of order records + + loop For each order on the page + alt Order has no certificate yet + Plugin->>Plugin: Skip for this sync + else Order has a certificate + Plugin->>Plugin: Map the MarkMonitor status to a Keyfactor status + alt Unchanged since Command's last known status (and not forced) + Plugin->>Plugin: Skip re-emission + else New or changed + Plugin->>Plugin: Assemble the full certificate chain + Plugin->>CMD: Add certificate to Command's inventory + end + end + end + end + + Plugin-->>CMD: Synchronization complete (emitted / skipped-unchanged / errored counts) +``` + +> A record that fails to process is logged, counted, and skipped rather than aborting the sync - but +> the sync aborts outright if more than 25% of records fail once at least 50 have been observed. + +> The current implementation always performs a full listing of orders on each sync, rather than only +> retrieving certificates that changed since the last sync - `PageSize` optimizes the *mitigation*, not +> the listing itself: each order is compared against what Command already has for that request ID, and +> skipped (not re-emitted) when the status is unchanged, unless `ForceCompleteSync` is enabled or +> Command requests a full sync. Orders that have not yet produced a certificate are simply skipped for +> that sync rather than treated as an error. A record that fails to process (bad status string, bad +> date, unexpected null) is logged and skipped rather than aborting the sync - but if more than 25% of +> records fail once at least 50 have been observed, the sync aborts outright rather than reporting a +> quietly near-empty "success". + +### Certificate Enrollment (including Renewal / Reissue) + +When a requester submits a certificate request through Keyfactor Command, the plugin translates it +into a MarkMonitor order: it resolves the organization, contact, and (optional) group; validates and +normalizes the CSR; and submits the order. MarkMonitor never issues synchronously from the +create-order call - a newly submitted order always comes back pending (typically `CREATED`), since +Domain Control Validation (and, in some environments, manual approval) is required first. For a +product whose DCV/approval resolves quickly, the plugin polls the order for up to `PickupRetries` +attempts (every `PickupDelaySeconds`) before returning, so Command can get the issued certificate +back from the enroll call itself rather than always waiting for the next sync; `PickupRetries=0` +disables this and restores the original always-returns-pending behavior. Each poll is a single +attempt, but if MarkMonitor is slow to respond (rather than erroring) it can still take up to +`TimeoutSeconds` per attempt - size any upstream timeout around `PickupRetries * (PickupDelaySeconds ++ TimeoutSeconds)`, the real worst case, not just `PickupRetries * PickupDelaySeconds`. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Submit certificate request + Plugin->>API: Authenticate with MarkMonitor + Plugin->>Plugin: Check for a duplicate in-flight request + + alt An identical request was already submitted / just completed + Plugin-->>CMD: Return the original result (no duplicate order placed) + else New request + Plugin->>API: Resolve organization, contact, and group + Plugin->>Plugin: Validate and normalize the CSR + Plugin->>API: Submit the certificate order + API-->>Plugin: Order accepted — order ID and status + + opt Not yet issued and PickupRetries > 0 + loop Up to PickupRetries times, every PickupDelaySeconds + Plugin->>API: Poll the order + API-->>Plugin: Current status + end + end + + alt Renewal/Reissue request + Plugin->>API: Revoke the certificate being replaced + end + + Plugin-->>CMD: Enrollment result (order ID, current status) + end +``` + +> A concurrent duplicate request folded into this same in-flight reservation (the "identical request +> already submitted" branch above) receives the polled result too, not just the original pending +> status - the fold happens after polling completes, not before. + +MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a Renewal/Reissue +request always places a brand-new order. Once the replacement certificate has been created +successfully, the plugin revokes the certificate it is replacing — but only if that certificate is +within its `RenewalWindowDays` template parameter (default 90) of expiring. If the certificate being +replaced can't be identified, or still has substantial life left (outside the renewal window), the +request is simply treated as a new issuance and the prior certificate is left alone — a failure to +revoke the old certificate never blocks delivery of the new one either. + +### Revocation + +When a certificate is revoked in Keyfactor Command, the plugin confirms that the target order belongs +to the organization the CA connector is configured for before calling MarkMonitor's revoke operation. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Revoke certificate + Plugin->>API: Authenticate with MarkMonitor + Plugin->>API: Look up the order's owning organization + + alt Order belongs to a different organization + Plugin-->>CMD: Error — refusing to revoke (different organization) + else Order belongs to the configured organization + Plugin->>API: Revoke the order + API-->>Plugin: Revocation confirmed + Plugin-->>CMD: Certificate marked revoked + end +``` + +> MarkMonitor's revoke operation has no field for a revocation reason code, so the reason supplied by +> Keyfactor Command cannot be forwarded to MarkMonitor. + +### Connector Validation + +When an administrator saves or edits the CA connector, the plugin checks the supplied configuration +before the connector can be saved in an enabled state. + +```mermaid +flowchart TD + A([Save connector configuration]) --> B{"API Key, Username,
    Password all present?"} + B -- Missing --> E([Validation error shown to administrator]) + B -- Present --> C{"Base URL starts with https://
    (or blank → default)?"} + C -- Not https --> E + C -- OK --> D{"Organization present?"} + D -- Missing --> E + D -- Present --> N{"Enabled?"} + N -- No --> F([Connector saved]) + N -- Yes --> G{"Authenticate with the
    submitted credentials"} + G -- Fails --> E + G -- Succeeds --> H{"At least one organization
    visible?"} + H -- No / fails --> E + H -- Yes --> F +``` + +After the field checks above pass - and only if the connector is being saved enabled - the plugin +also places a live call to MarkMonitor: it authenticates with the submitted (not yet saved) +credentials and confirms at least one organization is visible, using a transient client built from +exactly what's about to be saved — never the connector's already-cached client, which could be +validating stale credentials. Saving with `Enabled` set to `false` skips this live check entirely, +preserving that field's own documented purpose: creating the connector before real credentials are +available. A failure at any step (parsing the submitted configuration, authenticating, or listing +organizations) is summarized rather than forwarding the raw HTTP response or exception detail, which +could otherwise leak transport-layer detail to the UI. + +### Order Status Mapping + +MarkMonitor order statuses are mapped to Keyfactor statuses as follows: + +| MarkMonitor order status | Keyfactor status | +|---|---| +| `DIGI_PENDING`, `DIGI_PROCESSING`, `DIGI_REISSUE_PENDING`, `DIGI_WAITING_PICKUP`, `REISSUE_PENDING`, `DIGI_NEEDS_APPROVAL`, `REISSUE_REQUEST_PENDING` | `INPROCESS` | +| `CREATED` | `EXTERNALVALIDATION` (accepted, awaiting DCV/issuance) | +| `DIGI_ISSUED` | `GENERATED` (issued) | +| `DIGI_REVOKED` | `REVOKED` | +| `DIGI_FAILED`, `DIGI_REISSUE_FAILED` | `FAILED` | +| `DIGI_CANCELED`, `DIGI_REJECTED`, `DIGI_EXPIRED`, `DIGI_NEEDS_CSR` | `CANCELLED` | +| *(null/empty or unrecognized status)* | `FAILED` | + +> A freshly-submitted order (`CREATED`) is deliberately mapped to `EXTERNALVALIDATION` rather than a +> failure status — this means the order was accepted by MarkMonitor and is simply awaiting DCV or +> issuance. Once the order reaches `DIGI_ISSUED`, the next synchronization imports the certificate. + +### API Endpoint Reference + +The plugin calls the following MarkMonitor API endpoints. This is useful for firewall and network +connectivity planning. + +| Operation | MarkMonitor API endpoint | +|---|---| +| Authenticate / obtain bearer token | `POST /auth/v1/auth/authenticate` (with `X-API-KEY` header) | +| List certificate orders (sync) | `GET /certs/v1/order` (paginated via `page`/`size`) | +| Get a single order | `GET /certs/v1/order/{orderId}` | +| Place a new order (enroll) | `POST /certs/v1/order` | +| Revoke a certificate | `PATCH /certs/v1/order/{orderId}/revoke` | +| Cancel an order | `PATCH /certs/v1/order/{orderId}/cancel` | +| Reissue a certificate | `PATCH /certs/v1/order/{orderId}/reissue` | +| List organizations | `GET /certs/v1/organization` (paginated) | +| Get an organization | `GET /certs/v1/organization/{orgId}` | +| List groups | `GET /auth/v1/group` (paginated) | diff --git a/docsource/images/gateway_ca_configuration.png b/docsource/images/gateway_ca_configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..1c705d978db466a06ff6f2b296fcd4408b515b2b GIT binary patch literal 244663 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�Sp4@#!`? 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

    ifR6TknlM>`Vu`NBe7hyl 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 literal 0 HcmV?d00001 diff --git a/docsource/images/gateway_registration_local_file.png b/docsource/images/gateway_registration_local_file.png new file mode 100644 index 0000000000000000000000000000000000000000..8a227611784303c7c314382b891434c839319385 GIT binary patch literal 266981 zcmb?@dpy(q|9%G@bfBBNbVA)3qEZTlQFlt_l*1fj3CTH!Ionb?NVppkGKI(v|GLUuawzzNI47?(LIV&7^SRZC<`uDoB&V$pyKT+OJW;ZP@*J%LHx2}^~ zzkl7P)wcjQqxA>=@A>8R>gzWC*XtYBt$XOZPU?T&V+A~}{`~{oRzLIKj~idE|DSgQ zuf5#xzwefTyxjP|&$qa*ek^|Li5%cT`t}v)uyyP9fL3qo&1_YEty_0~oteo6`>6G^ z!?EF++&uQY5BplewYtP)DeQ%RZteba6MnP5jnCsHRG}gPoB1kl#u*C+V`rxKw`ITn zlHJuEQSFlw*5E)byEOmRJ}&}ddOYlMh2neji_KCt8{b?wd`IO6>O3khubF2?Voat# z-=Zsh_?p~^xPm0)#UdzdzQ~T>fWW66(m*&C1qr&-wbr3MbmyJ)o{G#WWT#352_95zu}6-Vygy5MvT7Jd=C9%tubKN`Rhf} z|EQnqo>LdDJ*a&DQ*KJnMmx{yKzpj90Zvse$?nlZ{BIb`cjRNhtdrv+oeunlX+P+2 z$iJWnrD9i_Vfm}uT+4Zwgp_!wjUD<8$3AqsN$N_5p?mkWEx%*huK{Q3rJ7!mTuP(S zT!iluHeMudRW(^-Q;TLLZ#<>IEFS5tfZ_;Cj+EkxtD3}(UV zVA?EPQ}_*ondt_db_MWzVAA_w82>(1os7*V=(!T ze?zF;`r_7lIgs_D;&;K?Q}3aZx7H)n&)w3u`VFfuLH_tV+243(2}2k1$w^y*jlD++ z+L0JYZAA~oe?zt&Nal);2dk#*w?qpXW!l#qE+15#XTVe!Vh&|h2C!R$L;$KTgc*$iJ4O3;XS{K z+MAl@#dpT{I9tBf$El{r;%;i^ITUKu*MFozozCjudT>g&gzx++!%C=SWg8u0VHqdQ zD!t03*=vNY2~V|v-}8yoKD%}dnDB=taI8nogmynqNYEnR^As{MG;|yOh+ZU)+EqxY z%*oOt`)T*zf=k4;xQK|k%KcITe9*wa{rh$}D|B26wK8ct0LmpJGjkJ;xEeyU51}e7 zpBk>8bJeV}=>4y|Yuv<7Zm$wVAW}s03+v%H3=Y(|SeD2;+&dIk?TNPE=hd=b>Ghh?{*xU*_%dya_flAU z_PSn5D_?|SUC z{X=EhGqCD?OFj*==N+@?Cb?-$2tPQ+9AfAk`gJPQ;G{>3x5I%0VCTxxkQ9Qvv~`(9 z34Ay}xWJFTwAK{87Y&@S3`N+6S##9db^fL6>c+kI=#HGSsOu9&*}pycu?BumR@7au z3khoa6O#(ANLAJ($S&!&k@f8-A2Y_@>{n9qGV=+Y{TgLeO8t4#L!0!DZgb7BRgjyD z2!_MV@zm6%K!UF)9t(zKVCYG z-}9$Mg^SbKj+y7pJ}$$xY)kBxCAzbvN`z~N7YYb()pHkxi>afEYehZp$cKQKM82)y zv~jJ60)o#D2*8&wRP1a|7l>7L_i#);y?D`8lf4pW{rK3?JWtmA=%g#Opr{R$9*Z~5 z9tze;UovU4*!%8HG*xDU@kx9BlZxkRMwsFrrBm5f!rebZte+oKjJ2r~SK(3>_2_=1 zrV?*BdxVawi9F+E3BNBShdVdw{bBdVGY`E@Yt1*`i{z$+%=&ac-(#ECdaTvmc(w^3 z;}3cJ+DtQ>rpQmTpQs&ayCELz12S1nEvjPD70jyk!@l+?@UpV1Af%HWuz5*0vC|o9 zS2T{=l2bjtc|KR>x4*iWdDu6Lg|_6}7cR`57k25R$QvV6GUuvuvY1KP-ts3Zmij8t z8U0PMctT{5B!wCu3nS!QnXSwrFB^HDl05pPwKX-k#mjJnSNj$6?P~`YUW)fiHh!#d z?q=>^JqLE@1b(_BfGbj8xk&Du=sdJG1hCg;Lp<`nPC-rE%{6A;)hW1Mv>hOeH`s60 zPTtgZt7#n?I(eb8sC&R$zPwr=aU+x3vJ&EO+83#UatowcMS^gfPgxi5Xfc7XS4OcY zrP$b&JT>FXv1#!J*Q}qvEG=s3EX#oDk23cg&u#EeQ*sM}v*(iWx_adm4UPQWST{G8 zLoBZ}-g_|eY}}*AH08W9>=!mxkZD+&1Gz7x-g$e|Jh3;r!QI!lH1AYQwOXiZI{Iz@ z&@8#&sqek1rW~!ovnh_yO0V#^Y8bQUtfFIz68-ENnaPuDt66ET+1qFBS?NjC>am87 zFMVi@YWfzT8-Y_(OFe*0BAA;~2rl+#hW)HYRIu9~e3gP|?2tbynmX*BiF>nOQ4TEm zB)7Nc!hq`6#FCG91L)JS!xnAnvOT^GQ>$xfQHy%-(HTxow;L=^hTN#278IPuJ$qK? z%9-2mUt1IKHpfCq-=<4O=7)JmMY+%CjH9|(xxXT3`#f0tPTzEbhK_dT8Q`1!=_jxd zzv?y*_X4vgqixZZQ$zJ(EF20Yhh@^sYa3#DL0Az;@1}u~U$43WEGctfvLOwAIns1-P0299?$RLvv%=1sF)RNY;=tuQcYZEie&=AtI{x7XLUa2z z)%_ppq_dolYc>w~g^>9U+ZVpz+D6Yg*d5gzCda#T_oqeQ_0-=Hde8|ys!Ul@`Gl5^ zwdy?pbu)vC+(#42txaR)H;SU_3>9VmJljtlPeNr^(+@dZ_l#MRM?aO(+mp9mZ)!5c%BwEN_aIgkCs8bKjxa!dooMgButr3Ccms@*s zD|rlr^VTJ+*vbOAonfJd7v2^v8V+{t^I53}7QD4nhu4Zji7k5h&C6z|uSm_o+*?zB zq)%UI@j_a3nS4Ia(ePM!nG<*!2Gd}fJ%FUzLvMJi7Q%&wr!GMrOnPghRi2X*pJx9U zFWQqVVh zPQt|=>spM8DadTk?%mE3oO2bw^K^@Qw9tjBSK#pfRy11I94gRf#cT7S-p-^2b zx{dAl^86@XBA@?jlD>af3xeuxg1kF;`sS0J&h??Mp`e=@Hnu{#h!(d-D!Es@LF`}g zgCrZVb}F)NL&?k4$y+RLzj3Z66r?sW9=!n;V)L4t_3VYW&Ql9PUA5Y=%?bGmY0Q;` zOQx4ik7l2eUw#_yH0pu!+NFA}xKXB$+Zf}QOsHyBNk=qQg_-6b=0}U)XdFJdyFYES zkM>j1WreZ?59r+@KUI0vpa(%0j!`bBDuoqOQQcuUUEP=#FVjY~)0-0zVY8EiFONhe zsVde~*WE*bw1~?$axIh6%(G4qYUFln)sM;fYdTkym30nexkY4CX*36{a{S^`>d-Zw zy=07>jwca`BN)_S9&6Ai5M%E#I~Vjq z4L-Ayle6DIyfhf>3YM&J@K!lz$TJ*@aWGW)!XUDYkoop#zM{cOw2h^ToUWCY4UB8I zHWF}sdHWRItre*@yQWC|Khf9f+-lbPdYm5Y4*vU8rWLh0eyuXpcB?dcyY(`c11>n-4a zUd(v++$#3(*Qi68&!hO`S%b3>`-3`u8H98Xxnk6z+Q7k^q64}CZ(Z!|z2JhyX&|PP zU|LPT?h@c`{^6wR+Qt&OzgBnXKV^1TuU==Z<~Bt|MTgp8p0GF(0&=p-)$K^l%FJ{Q z3|gA>pqIJPXk3|tzf`&{b64uS;Ge&I3A|=FMEu><<=C21uTO6a)sAWh@X&0v6@%r_@uI&?mF=4F(3XPtKoGjIzCXfn3%E>t&`4ANO!Q=)4>Tzq^1vRz;ytrrXpofWD$4um?G=hDQOA1_cKh^*wA34Ub@S8geWQ#MzX%HVjIM$7Tcv zg3R0_`n_poI9xSGfhDQR7vbQR+1eldJUt7c9ffc|aQ3eRDnG|sM|D;k=F6Q#}3v9w`y; z1QZxUenny7xeRdJU9YoKFAKcLsWR3Y7AkSXr6rbbghYJYp*@xK&d--z?~qPzcJQ2! z!)AwZjaW^7NbC{#kogjPI|A=|otb}2pvs?R&djuMWB;CdsEoM9 zT8U%iqvXRvLvhAh6n6SdnOh?cMo#|t@gt2EJy;W1wM2{;;^z7)TK!@hQGbgNnx(eP ze&R6uqGJ{V1~Qz9nLinAZGK((&}Z;mT;adq_%Wa;VA zNi7lVkwB44$wZZv``Xycb(8HoX6fNaa_)5e4k_*SZeViiM(T0QxemiwgAYPak262t z$@2`)0pYMOe9J(s({Qa2jy*1P2WoY5W_PkJ&Rno%?z^_Z^Vo!05<~Bn&6u0>!@E3(wQAM2+ZaFeAICICoJQx#tV;l{R4QMJW9E0Ft z%-)r?;s*W(HF|mLWul(J?EJJPooG*f0Q|l?z z!bOD7zQq)^k2EuDYtbfqrJnL*x5!Klzn9J=62k}NRb5^61`ILv{84=TKn4>~cB}{k znN}`4wU1)Yg_O@b5qa$kxVE3@>(hB^b5QalMaB5^lZ3xO8X9IcB1i;4f=U{28Wr;* z9;3EKPLmPG=`b4Yy`p+i3!X@L_3ChU*wh5DEoSe`yfWQ%Av|w?iBv~NF8IQk0WD=9 zk)KuC067V@e7zEzI5{6R6}Iy~C-{dN?;xnp;-yU2wmJSA6C|YD1K>P;v2BN_GUL}2 zDJA9O$~MT{m&EsJiY&BL-w3f|bG2fh7opx4PxY$ovfd%+R9LL0D$5*L=-!=uYUs*$ zvwup9)UHQF2=svnqf31G_N$+xwuer--E|%GC^Mx!ZY1imvUI+dlB~R1;3An*AS})~ z-eo0%+{Bfa*IJsSt8ZyI4Vw0Kr%v%*vM_C>esMMYGbaW^@~kg?kJ_eAhH{-?1_J&$ z8r>7|pAXyhx@|z5zQ#Vtyu5ZelyH7N`YIsQgVKF-vn@W4sJ2SAEiI+thWlTAxT2g5 z`)>9mdJ~BDG>AK8md7r%8uQOk9Y;shnmp;`a*&H4XHQ19VywZ44AMG=G zBSdoL!`+k7r{|#34D0N`Siuj4Mgz-lN}||yeYN8 zRO_mXi(mRz0Dbx)h-w{kL-joaY?4IW1smISdMYgZ(M8kV*KEnF9QLCVo!9^K(ffWD z$a2vK|EZT+JBQnP@BjcM(^8nyFLZKF?yVxI`<}{MDEjE-N8(1RE;(7My2f{$LaJ=r z-tKI$hx6fMQ-1Q0iJT$v-85_O>Vj;p2?(x zT206nskJ>G8+8h{%I)K^dBWkLp@7k)xnX}o zbMvr<*49J2!ja0$3imKZ#_6h-+UQk^cKqmk;;X{OI$ET@)m4=B8fAdbJD_Uj z;<>k}=rsE6vu*NcdH{vgdS}a6$MdvgpM^k2$nzZ=tUE1K!8Y3IHrlV%0zUJiY}7*n zTcoU)Z~*Eu&kyT7=TKsu9|V<7kB%nJby~rArpobN?Rr5&x40d8jOvDH&Q0v`-Y+P!>B*kvO@eHHtZBLkggvD!-NMSegxh^X=3xgaZ46 zhCT=I!H`kIX~+EFyeta=Zy60n?^+p&W%n-+47gxjYl8?H<@TRR?Y%YkOn((HWfoVa zmb<%c8wctq(f;s-F|q?vILL4T*>vxHumXxvez3B^;?cjZ`rUrAY0u!w7nrjj9AVZ> z&75@i;hu<9{QBjX!8GlmgggVY&vZRLo&C9-V-l4Y8!ND$&HeZVR_{;Np>wO3VvTwHeS@6_Hg*)ciCrJ4eeHlDYPFp6C`fj z(9u`D6wG4nt_7Esr8fz9Ppa%--UeTLeEa+sS)s zrWWwNG`x{&F(AJOY^uHW=Q(uK-l7(h&Xea(?^!lIk{3~K@w{nYA{lkzr5Aa0G(<36 zGI*c3{87tA^x2Vk14<5cb0Z!BRU9=7{kqqBa|ea@;VUJ6E-YfiHMrTEOIFLT7WCR# zJ43bIkY*wE^$SU=*#l?5T96I);BFOzyb|sk3=GPdX^BB(?s_w-4;u|94s?yq&;c2m z8Ul55gpS%%%Q2kQJClpRYcaj44teDmCiZf>>7b~id_D)(=~9kqyM*nuOG%}3p@r>m zwBKUXVvL`ETzIpMf}7*ybl5BARJ1LrZD)-iSnvWlX~3u`&G6#SHL?Mz=&7ZpC5;x- zmda&^fI1M<=CI09AbJs~Y@|f!uqyaMwFXKiY)F_?tlx`){UsV%Z%UR*IGO6vKkh3G zltS9vNQh=aZf-7q2I1?TSI)eIZDYphD}l8d5FN^HwG%ytz%OE#`zhhg8FW#e0=O)? zH$M9Te`J*_t=<_z~ zPcK}ipQ5RelFyru36iM}B#ALGkh^uGYHRX~ZQf4$<87MW+&(9arOpg6h zAv--+FI6F@ zA+syq;qD8$pJOjMTU-h`%!W;y#9Ag(brWg&yhug9i9E}-RS#T>Lc?G?y(C-eA=^6MQZx&7kwd_Du9Z4OrB9) z%Ye?tX3@BZ_RsjpzG%G;UNl?WAL>8Jc>7`IaYCn0q4oW&b2a2p$?~QP&xZt4S>U7| zc1!8^lhv_LWLe=~AN=b~^#9qM2aQ)DT0S?V!S-vJd|GS=dEUefbfxWvAP}dVc0wb4 zUVQR;rGZ`-V`t-7$w}MOimF#I#SQxLUzGOl`|$HE?^m?a0GM!6SzLn&;+>B^+bCXef;0JY4OY{$E0Cj+$D#9!9FZrbgEQ z!KFI7f<=oxc*Ml%{0f0s$aV$a{(c7v+N@DwAsu)6=GV8Qkm48G-j4~%$>4f>a^!0K zE01O}nRro`sj@S*DTa7CWnq#lpTC@_=%|gB^LQS5a8`_mv5iW)X`OYKvT_83PmtIF#rvZSby`dP8^r6fs;H>a?uMhQMlP*GB zRcEDs%;GI91ZA&1l^aa-6)kj&UYzu}%VpO8gA5;DRY*dDo8})tS*GL&m)aFL;?kx2 zDUQ@I?VzEvOvi=%gW*U3e}E0jxR)pM4Wla+vuX$YX}AhRbYApCHjViG?snX>Ouq5c zmnuzdZI_vhx{yNXaQ@O#guiJycJfAdky*qwY3%s;IE@xo!Xe0laG%ZTwdtGZ<=nE$ z%DGRJjYn>ZK58L6xU5=64Te%EcZ|!Y$t_;{6x{k?XT%lCAe|(J`@^Ds+;`xJsIJwC&S%&yO750@jLnEA$40&?Sc;03J~fV?EoRRA7WMYgZ^~ z2_%`CydeA*=4xwuV=^Bp<~xj+COY8(I2;qii08Q-08FbkX0qcxEQ+PQad2aB1 zYts~`fV~?(DT`dbm-m`t(+k#rO)F&Y26p(jxhjVSnPz}Yhv%j28?){H;HFx<1}$Ui-R8#{}MSc%NoDKI!DO-x;&O{J)obV{_OY<3(j1BmD&)A?UspzG>6e+D28|qjWi9Q+q~WVL2#Jv4D*Dwbi`V$WlI&gOL#YwZ%=lqR z!eKT}!($Gpan{t(UP=88D)%*to{j_E)<~Ei@GmDskKqzqSAM}hTrDV;JG!cKjlyE4 zLDeJ)W**2pBcJggBIjYZwxoOn^VS} zj=gC1cpwXH%(6~;0;%ieaA~f={kw*PK^p(1beFR)f_V*TIgY$bbSkHe(l}RzIsjKb z16z#iz`~~xQ%362wv>lU<&?Cz%xk6G8N@A#O9{%2D|$(JNTg>3V7UH9cvB{nis+^B zvgIyi#+9n&BN0ChTkYyKEXSyV4+j^UQCu(_gJY=Q=c zQPVbvI12!*GD7S5cQ50fs>zRVjN{%lm3nBqpV_a~bz@S8O1i~uXApa4MxF0%SLmC6 zEh}81a^k!}IeHcixagn3fiEP2_ajOI@A*(B(z{gR7Q^{031aDZJ5R{QHSg5X3>;#d zi2mx=1(sarmhb7PaG4lnA@biw*x}P8Of7~#OJ_+?ktNKpXd9#w^PlB-(}>~Z$G5-T zz@-sn*Dgoh8068IEVehf5G#Yu2(NDcgtpbW7Yd=jL+Z5c8Rnq%vB| zshQ;WlsXv9H6d#m-{?4k$c8gR4NT24LDCEfrZK2Wd{6F_&v1Z9HjbU^pjCdXY9LJ5 zBBa~0Nny_QUniaSG$%Zrd{guu=~y|I6Fe9vF0HJ6s=(m2Y8hS^LA~J)u<|@VZp*o5 z&5Bexq*WG?l}~#8V-nu~+I;rcnOnKCwl)&L+ zh@;UR`i-!Rm&HY=xSAd|3M!b^Uxg&mgpvE(MX>8vZ!lK% zf;dZuU47dN&6(Kla+>ENIXd0R?$zcv$nGN|2X5aJX^i2YUBU z(udkhaMCRjOwgT$W7_2lGNAS9f7nZBLvGt|cv)7+^m~EQ;~Hw5vZvI}l`mn7tk3!7 zxzwT#!xizaXo%Q;ArHNUH3>wm+W2X{Z9%@=smy;$65j*;XI*XOKwlz8Zay3gHHeY| z&^phRCmGLz&7Dp*qPt|Fwh4F41Wg(FHl=>~K@u}bIA%}2xEdO-v}owt)MUh~r#NR3 zk&E?jO6QTxzw?iPQZz0=DG5u3W3J%#7{uTw^0@+68`uqC_ ziUh=fprD$XCF}=CUgR)bto3Rtrhx&e?B(UlSrClQ-Ezm9b3R!!P792#R+cOkN;$;` z&mb@w{m`Up$V_ht$Q1EoJM3-z41f5o$2|feNQ5-W*BaIXx%-JE^U4yB$!We#WfAJ4 zPCij#(U2KuP%peB>=N}%x(n(0T*)7KrvKjHdsaVT6VEhVMa1@ZjEhXNT=~@Ihy92( ztaw}5EpaDeS_Ul%N~h{N@2TC}d}#t2+x?xwCVlSIvfJRva`7)`jQHuOFMVk0uL37j zGN{(SdFbl{E`OozS{irvT9Y?;CWGgz? zH(59>UpzqQL+bv~OOMk2o{SgAKJJJ9h?$IS8I7k1jFP`3vzm%;uV5U4Dd8}_IezAq=X$txUCi|J;(zy{TFkh<+@53xIP_6shb zDr=(0D;P74!dg_izyCp!=#tmD7oTvSqc;vWo40s%Q5h7JO8s}l0m)ZmL70+})dllr z<4;&-K`Q!D{jxHcUp0mlFtQl0S-4-qdhr2-2ooAv_c8avvd_{Mc9DSO4BP9qPYN!M zTVX)mBZGL+6GuzWSbVxBY%=EIj~kVpu()yiFI%qZfK?5U^tMg#>n??@gi(d@ z-8V-4;_HXmU+~RQd@cNmJY^%Z zsvHRX{-|ihNG<={Wkx(GT^OK4E|UDLdwKmaVbr7OroN)8d7I&3?YyP{4&R4Y+HEqBS1+a26MmRwqg zALWrG%~sQPnb+Q!=&&S_Bw=2PU1c_EeP&#Z7g^4rObQIL&^ToyeP7c7_ckQBnfnZS zPP23l07L`?$WEi{s@Y>mhJ9r&3J9$wA6kL$>YL!Rf|34EcSxUI_fWogI)5Mp6sZvc zMD>N3Weq)Nurj4PrS4QmMmXICEb{oPG82WV)%+^>x1KKEoe1@V5$kmcS<*L=HS z1QmNRl){<2wO?CEC97B^m}Y zAOg85f+)9Z9A|R5!_j$KBG)!U6>B|EckZ?_`jBiS3yH}CH1d>gzC=(i@e7QXDYToa zx9y%_h=v*cy8yn1%+(F7M8w0UI3Uv$ySqhYC6p>7$v`;~MsNqc)R?#B9f=`j8e%Bp zgTbUgW_P@BRX+^`d5b6XNEJ(;GsRk2PNSY$0^%T0I_0{Db?7)K9A7||nldySNDXMC zEvr^Gcg7YLi$$aHUSi;g*-MOzf}ttl1x{Rmdhow5dTc)Y_WCr1g;Un}@;7AlzocbLX{OV{28!uCa#GlQ9A3?&-2^*-+Ffon!q!5wpUsL;dFbs%|YL8 zmviYF8oK&9 zP`)ifVOp+#JWsX?QQo5>r`*378$t3Tgk-73u?Be$2&eZ+Hi>@FZ~sh-2#?w@G15HO z)jv%-sC;_jnCmrnci*}z{AHrHN2u2^iwuj`VR6^=y>;@e9!zpAf9^1Nh*J--;+dLx zLmnl&tGmiMhrbwre6VZDEvo{QlLM%%EFY-ZO~^KTx#22`k$-#U)?yW6)DSWjk4ZEH z9Zfx;*V$=Tkb`1o;ELnl_@QkIFZV}7^zAmhmK&}{;H}#;Prfnv)KzFYXh<>SJfU{v z>bX*hnYT+4PvaX43R>ExSAg24ldBbN3SooFk(^{hiUtu*RKtaDla9)u31$cc0&IumW$AlIQ#G=#+hRniLAPf zEd^`17&jdY6Ly6eeS_b0H5UDQu6^R_+o<|x{*N2he;+gJb&Va5EU%4W@7FXHEqp?0 z2Bey9*0;N-_7^RXx8prTQnhlglj!+MjlEk6ZQ<1TIeohFc&zZT^58*ciwOz)SvF_k zo8nFaO)_=CEb+&$EyIDa&()o~evUd`N>|Z|?a+^7JPsOj@GQQzrJ zh3{i>BE|=JELQhP8*O9b7;o$E*c>HQdzx|ZsPf`>;v5hCiGO~|=`V?zWS|W=7T`$t z?#Lsu1t)DP|N6yX1|a`FBA_+2?P0(9#pMsr85CRlW7O1*LhYtpzH{iuwx^$$eY}4M z<%Hx}v-4Hw?~2EXUG0@BW-~ckjIGh{_U(Lfjjt&YE*M}iv%L$SU2&bVEBatuf|{bc z>$F+wg}>rbS4Llck!hlhczc#Neq)}uzE;(lpY{wm->obBSumq{g85*PId1*)9yZQc zuXCQATbha9yI)Fn$qIZY(!5or15FX7o6q6`YW23J-y}7ECRt~!xYWPn{c$WzSq`-2 z4rSMGfN*EeZ33#F=h$BkIb_y^87iOJ8Y8FDY_Ro)M>j0>a@5~9D#Ob2=#>;?S7W5L z6OR}q+9I>8^{BC7>ArtAAJZlE<#yjGtp+0I#1zY-xK&?HTJkYeW85q$FE52=9J8o~ z+wu=Qet2>*i6)@1qor4YDm*CqlCX*ZaN45! zDgG)swJWj6z5$g^fIPA<$VP3>JXq{y00k8_3+EbjDY5KkAMVd&ts0D!9*BALu%!@i zr5p8dskF18x4tmQZM(m61aP#Rd}g9gGQTewHIZ?w)C6$8&%_K&wp$TuXBjX-0*Zu`qs&JO3pR(>i(ToFw<|gnYTyb*{cMWn1Uxb-aUmJ$0X0I|9GEbx z5xo(l<_8n3_>po@0$4280`Rd~b%ni_vg|1QU=FI&$hJ*F1Eq#nllCJ64^b}TFWIu- z_6D?EIB@vaY^X?LGRg&GDR=?lgc~dn>p!8ZQ`YY!W$+)Y-MS~gc5Rm%6tQ1B-c0tI4IWspq?ON3LT<-2b!zgYnoBd4 z=ADe*(;fG0-mhecS5tC$=07eLrUj4_n;Y#RM4Pd-?`{)kqy@$Np8I8L6CuOjgXtn{*b#X^6jE?-nbH zMw2N$@_+7IenJ4t^LES%Re$ila1INV7M>ZahXpN=22XtR?D|Rak1_J^y?&MsB}$}o z8hX^8bKY&Fjh5?2-QLMjZj@ba)Rs-%(em!oAt&yeJp0&(%5|8b!o7v$^b1^qZkgWI zg=l}{8|4@0wZEu3zn$8K-Cn)~2QC%DPM98_J4qM<$L=l6az8llHxhKju>FkwvL|b| zIWEMPw9z=iD!*3G6aM}-_kYB0uhnW}a7iP) zk1(TGj=r;(Y4(rBpflvT1xTdO7sztOAsOhM4!OCo$_Aw5CSbQ0f8iav;@rr)B#lDk z&As{j>mNa^sZxF=XVzsdfcLK%L<2Yn9qt8=j-OTRzIvsV7;Qg+r9=LZ7E%VdNVSb$e9496j6v z?>%nvtYQMi+GGSNTE+!kP9G6&`Qjl1ZZfRjRQT>ICYh=CA5o6 zkc~%ZYKmY5R~Il#YVA{qf;s)NdEiV(A)&p*aN~@(fSfMS*K#2Q*H4{8rJ=PzWi$MY zTB31g^&951ETM5}L82*0eWre}!t>#A?^Od4_goLJ9Hq`Z*UOt+Vu`iFZ^bvrHU#$+ zTUPO_mCsG{9jQiRB~n(y?Qcjlya^0%M@B&&^q$Qt=TCIz`7^sEdS}v>K#_Sq_x=NY zb?==!J|6)D@QL>AC(`kn`wu|z86tI0)XkM0d7}C?Vm#FPZtV9T?7l~rcJ~+jC5k+F zd?(t_iE*yI&2f3bNLOeQo1b4^W)+)0rImfPHSKN989~hEIF}Ok=-%UMLhTj?Y#Ao& zqa5+=>D^DFt?Bw72b;ih>z%;E#aCZ?{nZ2$_Z~bG8*Ez7pqzYra_da|>!H=awP5Hm{AX!P~rvotKiElooD0 zoLyu-JGj^+n4GHMicPNV77s^xtJsEya07A)$9~24;`ZkpBX2U#8f=PWj46RH;GTk2 zTv`&_^kF4(?nhd!uG?7`Jv&*QFRUwm{qHM>|DWp}v|0j|+8+_^E!>+j+iow8eRBFL z`@wTWCe-i`?XDl>q}Wy|vRfm<|1>KI@!qfU3o=_#D#w)cikqkn(rCL8t!uQ$uDbwc z-G1*~x)4gbV6)$~^Ny)lJeZy8^K%1sy!rIq zyKXcka7+XBlxI`hsNj*hvz?B1FlEz&i4=el>?lb*1-hfif@UPv-2U-*E<`$X^iNm{saj5N-^~Czli*1$AS|JM z@=9t@e{kb`6*|PkF(BiL09Z6XY_}fXT5AgvOIJvTdYME=ap{3G#1p zLBq&CpBEl>8i(gsd-G~gpv;4%8s)1!l63&(8pHtB6mE2m(Xhn0NQh$&nhk4(cJug| zj_$q>R~u2VF=8Dn0Jr>;Ki5cVTM z`=9imY}WXWoNQPU!fND$zK|$0n&#k;vKw8t{#qhqx~tp7`miPOCwIfJ+tU}3z9q*o zzZhXE`++M-Rpc9az*#v|2mhF|QD)Rs|2PfiQLc>it-f5c^5$PZC_O(+;mXY)*+oHicC9%V^KC^tnfdZE0WQJ={^k0MQ*-Xtzi`N( zjk-S@py(%puhtm6+bPCmY+cNKLU8hB7>&>Am0K1-X5xnG=~`9u7rC~a4>7qIkEg-7 zriDHJ6j=@Y3EYm;$8%RW72R23M+;Z=91tZYv#eZVCc zjvR~ynxFc7;XbXBs)6o>2h`M5MTgVbMbweREB>3apG-Kmc)e0o*U0hJ(F(4lT6~`b zq}GZE)AlV6vWTSnZW}FcJW1ujKa3JnfBv){h?7@y_l5UP?Q`JGF2Szp>F~7*G7tK0 zVO`?H*xuAsa6tymsbc}D_HUz1zuKj%%|PV}Pz4X! zRRYd04Gj&!HCwZ5`milJX>y-?%P}7+v=H;jH28pT31C?qP!|8%;;-3n%h61*AbZWw zn;<88;F%^s32L#p=ro84heyl#)`)H)pec5-FQLpYx<(E80i&taFkT^vv$?T6fU~5R zkH#Jds(W8t2lO`LS1(W&545P_f`Iz&ZT4-4F`Oa48gCqAO2{;Unj<6ZCkh z$nGyRT8ohRykydmZsR&>O2={*uQ8jB;PqilTkRq_{vsd2#McJ+rDWAEVJVq%n?WKrGn~&C}AVpV3!vpJHTTAh_Nryg3vw zU_(U>$5hfAPbxnlSvmFXx81u2f57srBs~22z^aRlBiCwL`H$>ni zNK-OSQ4xKsDXc^yiKL*xx>h_p9xpwAQIeJdm}pWp6KteO0%EU3cK-np?CjIzPCMH- zOL!pxP(yO{8kC1k-Pm`xpLiRRFX$~1;Cg`W+=h|4;YK|3qXMiNLup=Wju%ES>0#hi z|I-(kSx!t4x9KxuGw0vSRkx)!;B{-JLoR8F355J>KwC!e*V5{k9^)YoZiSZdEodSB z)XS`sr^>t2Rqnm>i9(PABbM$ttKlj~y}kQSRDPD})foyVU~ofz_hBctKJzx9v_q|S zqzgAlz?L;#B>~73W9856+>`K-D}P)*ShLK?k{$9%*cm^ifh@~d*MD`AR}rbC%zIbc zB2->xzi=?xpK@mw+{)m`>}R$ne%@dHg(hHtBx4#RHk1+b>4BCLKM)I!eg-GPkUQ_9 z04MUNvO)z`5YN)68S_|MWi58fzGm@T z+O_>`0KLFJ9ufb<#SalMT29hzN^|Z+!+!Wo*~NYvc4r|a!?W+JE|3#Tb?r#*sl)c!g9ROSG<5^K6=8Kf%J5>4}YepbqwI@O3FPx=u?HFs92#cGuVI7OXunGCqMn+AOi0aIdx{* z?I~|DP$BDU&78Eiqm!bs_y+cpr;&#a`t$&BZG&u}1u)m2P)bfGF3p8xrOLoyyQ1!T z?3$`=aqpQf%FDVkTixJ8F?SdZfdy-flU_N4}WQ;&YeKgFDMv&a!ZE8OYp&zZE9_Jo}5;hVZ-swjZ1JG(H<%k9d61~GXFoeFNG ziG5RiAYDgaZ5isT@C$MDv5>@(dK}$1>+ZoBzDc~v#(&~*6HM< z%~|F`{0_;-&GA7QLpiJ%pq{{yYc}rhWR^>YBN>FlkZ`E&j~;7dpq%{TleMs?sf&^{ z;F6D0qUe7i<-t@^XkTx5}H5FsOXU4rohx8Ftc%GLC_YwL*G( zd;6L~zj4P)Cp}lKeph5%9yS$DmckhHa+0`V=TR+L$)>cE^G;^@VUq&MLk2<^c%Vcy zgYXA8$n5_2-ql;145iucCEP?yd+y>5Y-U(cbqwPM8&>(3zm(UrP2n!czn_M0Lfd4q zjkT`68*A_6lC%H`(vO*2c%|_WW8fpF^_AGC{QW(wAAYp$9O7kVOg%xtxaNajc)gth z!$-6o?9@5J2~|(v()#;;@?I4TrSF^EqKP9-ROn;5$>55&H&WH4Mr`KVW7C0l(i86D ziwBf98$^(Jq=z!d8hNR4gt!}7*WPwqgSVv^F|O^;*gX>LfAIa6oM4Iaf##+ALcBvJ z%$qy6#jt)M$AG>Zpp)k8=E!dUqPY^?Fuoo}pD_TcD23J%T&$sO#pl}oW_(Pp51gic zCI83M|Hs~Uhc%gP>(5w58QYA^h)S~%5D`!i>BNFy07Xmj57*P) zysOd+f6uWqByAkNLc~=yYFycnh~9U827#z%>gz2x211bh)!PRmACaF^#V6l~3xNb6 zevIGU>a$P{AXR=-rFND6-#m2r-=!@tG|EhD#ICL#4O~(9d;d07%Q;BYbEs-DYSvO# zK}eCMDtarfj!v&g-98CPS^Zu+a@~)3uo@}-xyJ#-m2=ndZ$9GH9Z1(9X+c3Q74Ubz zNsEl`euREk@>a1=8Q$Kd801!LQE;*TVGm;3I36zzgWI$l_Ce3@AMiJsk`^8Qy*&!? zK+SDxGUmDC`_i{@g_~`ahOj(d-{`0ESp@~L6&A9)GM@|#G?7!4MPoGMM#N=PtC=%n zIY{hi)cA(H(@B?MQ;j4|?68N}s>p>nikPnEWZ)m08-g;`lNNxuJeHFwDxEkCN??uP zXsKxNr&1{{G8YjGY6y>@N*5ZCX|wboT-&wrb(==g$)uoaf}otM!M905^bLrM_?f>w zmPpDeclrW3e)*{ZVt>o(>`Ex7bO!I|A|5E8N-LBL@->EvyXXDUd%I5pc|R-89UcA9 zEs5?C+r2>{k5IwVI9$eN8DRG_+P+@No@LA0UFl5pZ{TEJ?;oC(!CBeh=bD+bzf?v7 zJK=qOj3Y8PfXo(twMVV~_KKYjy%z`oyv)Kz*G6 zjU-!!FOGoxzCO6CTI`RqD(&H2NB)?(qn!Oc%aLZEnYejFxFV1^U&PG1R^ErE7PR>e zp^zb&Ys*z$m6z|uEwbZz#^`3k6p$t#Y|0SCzhNAvTX)Y}MV<4QFk~!C(=tvtInPLy z&%G%kr0J!V$H{LONfTp67vuchVzjuT8CWrw$tj~&BJH?hAaMFYO7#bl3hFMstviTr zPBj9;7x3;-kmC&JA$zsq3}HsPsTq3Dmh-rl#76WM>Z{Wt3 z>hm7Gu$61VSZjh_mk-KUQgYetR~*G3odUF>45F{!M%D8;9nr|K<6AG#dVtuUx`ukg zc&pNdt*flIy3W)3q~kY;b#$k< zIdy_Hdl}&=MG=Z6P1@AVNPBwv;Bpw(mERRM0$a|eWrs=^1vROzeWh{5n|B=k?Yr++ ztXlii|K`KZdqC*sK}2gzeh9>9xCK|J(rZ`XM36W3Ki9OFsBnhRZX7X-2^D>$WvGxa ziJ8~Sj&0JEaZ*%Fd^t~1XceUfEk&OHw9^}Iw+X#jc@tW&%{ani7BSz-Hiz>kH`qa= zAH|)G>M2F~MNc%QdrFt**`+hNc2L;MY70fZ^5oh8$J};w_1tZ7iob_qZ=HpsOtz&W zH_JdWNE1Qr(xO;0cAF}vu;I++e#!*7z}Wp3i;`U~r6{fxXr)tiWCBN;b%^7s##(Kr zOZ{O5Is*sNTXpO-Wfvo6`+sKX8qU%XVw$Hh@KeJ%;51vZ7`SlYau0CGM$11{nkHRN z!-#vUZt3cx9MEelm+RA?h{fuMd^p! zYv5whFx^6~Tcz5vp_-R1taWSg5e}nRF1>*$njW?m4maju%emaCh(0_eHzV@7%p~VP zrC^nXz2POQnlkV^pD2$5{StOWobpQn{dyQjcy8P~1_d!`V4nB@h zax4aQG0(?N!F@7HCS3qkg{ak}$V_cnE>&F`})K>f?u$+xJan1KOMS;$~Wwv>*o zl_L8isgD<0(s{m-p;_6@PZfC?%+Prk`nJT;rVAH)q&TaL*?6}*kP+m0S;)ns=MdsYt#Q-G+vO$)By5M?NMpFxwyb{z3w~z4sxws zZ8NMVYl& zcZKTg)ROJdkhXtm;AYCwGf z#4pz%M@$<6)V)BbU5n={6hxrIC-_aNCd83@oK7wyA~m}mrr}tXtfiZKFrB6I^FbPH z`F)}#&gM2yX~ik9#8!3x6t^RMs?m^b^ODTWBh|ti$bq@x>-(-YwWFG}k_!hqa|xsV5jbeqEfh{adIS`3MJBIj|o zGk6d#WP8voeG2--ua#o6C>r#2ADU=y=ta@BW3$I&7co>UPzjJ{dIvH6K&2BdDd$;4 zg0zECrle;~7d!w|y@>`^5~_HbJij+f2OGX7A`Ylu~2wd55pDaD+J!~`Df;H_|=J4_9{jZSeN z4Uq>!H!Jw^!VINzEK{q@vd4}gYd$o*UdV5hv`jX=S>OzqREMC1Q`7bO#r{KwWd2t~ z=nwjI%;Nsb?>6R6-}8g6Zc8@QIb}L_>uixyv==0PyY5tJ|LBN~*FJhd*UJ(+MNjlj za;1)c4)r)o{4cUmu*PnLfk)dX#R9z}Lv=*)!zu^ zr&Sjp1yHnQ**foa8M!p>hLEUZ`6%&Jc}VK|N`z&KaUhA{3-J zq6VV3f`Z2`9=Og?Gn}#snyI zJRG#?=;BVoc9N*VU0`jfc*b#DByt7dh@H&Jw^S{73^S7hOZf{W2Nz&@yda7$sa?2- z=R4*%s@znFN1+e|kt=y=z_xD~h03;R>*Rzf8B!I%2qiBt-{gFa7vxGVv+&@hGl90b zIw1c-)VOy|NR0QcOYwx-spg_|C}D#8Dtba9a-D>!AtV!wgDC7Yic$7W3~JR{1%re~ z9J4Lg6nXTJRHMj2<>O+JBmGzI`_?-}qcwGL+GCcO-aFajCCA5`l*Q&ff3mrwe7 z|71ccR5dEIv}I5x_izTp9yr{bv?bTvF(4TB`#NA-)Xc{q*cDPAdH`c<@_n6!CgIy0oq*pr4aVB6{JxS>oQK zX$m2USFA~eg7#=%aPG$}PM4$xg(oyo@YM@=k!V7UghVtIu-+Q;e6PB>vt4Z)s1l~w zTi9$HToSUBP6MT{VM3ys2%@+i*IonA4W&O7EVt%!!hhG{Kx;oad?`lPP;1;Jxmqlx)^=n{%U4y|z;Wl!hIJT{~T zW&`ioQcIuJ7Pg1`fDPICwk<@FiC0&+H?Gis3B@}b1E>RkrVQwHG_=HVDVtfrOQ&fB zh?^(Hg^Wj@@merrDs>(<~2(3Oc~~@S=m4N{HwRX`R2Ap0f?TEk=8C=-jc8Q6HPX5dv8I zli!I9g`N7(O6{tXGE)^}kM`_N%Rkq!N$U8C26OE!70(a`Ov+ zh%EA8XhV%;RdxMqdXAMp?R11{wj;HP3*!cpzC(S-;S#>R9b#d8P4V0?|4h%df;~2 z59H0DL7|N!l9+{nUR$)-FwH@aWS#B6a%NG(eF2RK3U`MifWD;B7}=c82qzf6A~z?u z{c-NOJaJ*%Li>C~Tk3(>D%7S8vfu(?vCxidGjAB5Eb0 zZ^wEDXp8l07(ai5blyyQI{(&VCyYT&6I5L)F*luWT!0sZCVE?V!CSORsoB_;t>NQ> z5KA$gH@uyj6-$=dD#*WhH%XUFI(q&poiDI-M60*w+0r?f{&+SQp}*e2a4{PwR`>yW zOye6m@(11er%l@J09**M7PqLV=;_&-sOUg=CK{v>3>%=aUi>y*|BKWV77&(6N>NNX zcIPxuVA%g$lGm)wt$mPGMf*2isY^K-I`njj7gHO>!&M~VuUUMM_jf(E1rrKoe6VJxf$DI{3h|3HE$#Yxfv}SLz zryX>-;m{1F0DQ;jJXGiVed#ovo%_4Ut!acig%2}r8tFK| z^X*z{N?pt`2=!1f;`W>^Cd{XVBsT+T&!r{#XW~PEQo{?`7YIxB)vc0hgqUd;Yb-Tr zUzgypLY$%E#CEUoa(j8`n<9@14>UfBio3C{+PAnjU&+;O_fPj35m$FadIPaM+EI^T zyO0z?bGedaP}U>%oUW5j`gXL+t5l=`ASGqFD!J{ciisI2gl>D}MCo2gja?8B2AJ2i zL*M=W_h`5B>V+&j`4q><;I!SYmPj!MeB)z~F#qR9gcf*Bk!zTume>iZRI-0lmu4<11!{ym3kRgC88F-Z*k zp6t!Er&Z@WthF;$N)@%ivO~mWeq=F0!u2&bjd>n&+;sMdzQu?e2s}3^_7BwGK52|C zw#fD(9n(2d<7uP7-fACQpPGs^&t;+0U9$c2%MTirPjnn3;R*S=F}^(`II@w2;+Zxe z<S0^}m$|)>2T!c9*uARM}al*;iCCc)@%%#Qc!>Z=Nqpq8C0Wtb` zUI6GSV=hZ`k}*rx&YqZZ!*x*KKVY5($vHrfE_0@uSvoD-D*N>YF83l!$ny@6q;=V( z`8zs4hQV<g=B9bHzdk8P#JKP*KY^500Pry4ED`bjesuspR>%|F<^u2G;dG!qxpGN z9;!VU8F})`a6MYZG2$F)(>6DxdM!WIF@B3_;OJsXDNtHRn$*m_p;i=3CmaB3FKZuX znZ?uQ%PoHVFA?5)cf}Ako4!WpNZ8_s1(-?t?#S6a?VUJXkC;~)nR}iMl+@q;WuK7P zLQnw;YrN0cqEWS3nX05r!Ukz{wblELz#}v91}!}fB<1*K6}?l&lZ}37EP@U?7xemN zyn2Z(JRjqV2%&|$!>BU`mzS<0-}MJS9UHE_^P(}xmc-wrueQHBkVrH)E`&$uy?E61 zLnyu^yNUEGsc^8edh=o9Yx~JRW`XTNeoL>PEsw`+nSHSCTXo3b)r#Vc3(GhE4ot3E zyXbVd$O|=nlbHl^3T04`ua^OSV&_jvJ&Ab-@FKTAd^q zy8{~dkm=Zg2aGLn>$7$0Tk$Q^|B_DNDjlyPufDr;-ERd9Ep^&~@y!`9BMDpdmA>)0FSPD;$coJ%VMW#I>mEG^2RoHaq&qo5=l!OCOUk@K>cYi;)q#T|0FT=maPX zldUZ+RZX*+0~{fZano`j%!eC6%&`i&hKf{y2tcuB7^ANg7s16wBnMCpqH9|EG)6OBRK7u}9%71G?w zOny)W>Pej_zTW$p`iSi%Pin)-*tF8Pn6r>4fi`}{=`9B@6(T$`U7NBGi81J2k+3)f z{*B0S`NAp{E2XWz#ozecm!x3j4uC9tcRJBAJNIc0dM~z9qdM@mA~nQmTli1|01hKY zdNT(|`EuOwYSb^>C&$u~n$e+tJrwiyDoC1QuMepd>D3fKqZW%fRD{NiZ9IP0j4gDJ z46-^<8XCv|=6&>yn=t6$4D*%lxqrkV4r?SJ-!;ZPtMl6*EN-zYp{)SPX%S1WTxMUg z<6JhxDGU;6O`!s$y?4GWHq#u)T%GCuU8vu2!8mrh4f$Ks{R2;ukS@)~12-O$;e6x% z#(lN#laQt|hNu3HGq>J3A(<{;Cwma{O!Z0az0>iehModrY^$UzkFbT?8bk+}lD>#p z3Y2lFCF^s8IIT0NDJ~mX;go;z2nd$-=ULt9Ljx6*#Vo4I4 z--lab9ebe^?L&W1pH+e#r$G=idyoNOBuly|6|c(4P1a*w1LI`2I+nJPck$hzdag>- zjwRcGa}eZPMr#C{qe3D@lQM(lQ)VyBg<^;bK?kjZqh|e?-ow|=E)C9Q$Ov;+MR#F~ z>0G&jt@Zc_Wq)|)gcH%E);88?yS9@(zqjNp2sZkbO{)|tu)cAYFI-r?FciGf`1a`E z<2C<~PD_hy&@)VT>8_pV8g#jKOWlF3?jv*&dXclxIg$hWqp!+hlrZMnfAc zAI|L4vqK0(`bCm4Ic70Iw7{{8WCQ!p3~Rj$Kt+S!BL9Ie3GP2$If+yt#@OW}2Jy-6 zvx6hUwbsb7#!yiCKFU8QnxQ;Xz%bZAA_WWy}!TOo5J0Z22rhS<>gcSQTA55+($ zX3q^ZSL<{i!0OIpW`WCs7-LT<1)$J9>8c3H9mFlMXPbgzI4QNu4k7UvAi{+=`$t=1 zeS3Vuyo-w)+=BN0F}-H%ysmme;!Q%~neX~{L39$Gj6!1YL768SFGoX+@TJ{2^H(>> z)~b_rZ8IMbcF=ScSWybHbD72MjT?m`b>*$ek{fK)7EO{pQ!6%44I5Xx_#XL7^uX2H z;x6QKAUbe<^AG^d@zPj9p~F#4++57NdjlA_vuAXVLp##V*1x6xlNbLkzP3T>`On`N z2i^Dtn2MF_gAKm%xj!t&f6c;u=_(_4pt4=~%*Lpt$Nj|8A(1l|$}BMqMn@l#f0@^0 z?Qq;}e~@eT${`2s+pK9*6tIa^duk%S99S@%vPd|BaPiTeth&9VBbdrDK1mk@Z%5= z|DM%xc44R8x1{g-O9}rs%0Kw?){#@Yzn+zZyPB6p^Q1LTfm19BT*vrH$0DWBmp|{8 zZ=3lm-cYymBTx{)0=+^0khz!%)PpMpijLUG`vx5SLI6xgw|S$#q%ZfBnElEH%ABSeg^s-}Ew&UouKWJ|jlYZYYrSm(!`tHl#E~X!r z@US9wsJN#x`14`y_gD?wSWx@do{=K>cXqJX$FllJA1{<=$FNIoz$g9|GNd!nC~ zZZQA)o38@Be>n|{SO7wnu%(hO$N6m?OIWE2z}cGQ!NY&~u75MW!-#c&@%z7N`DzaT zZ(9DPJpbRc{QsSn;vvOp7)ls-aHRKxAMY2|SNM>yQ|n_(32o#2uQ_I)L)+Isd#3%w zpL_2a7^1848M}D8V++8RZ)vBNeQsL58OMZMJ|1s}3l09^Q2iTx`4dcA@9~KizLX>N zeAV~A7}o#%Dgh3F*8~Bs@J$(qUoYVg7yykoj@|L}{|W^Dr0@TF#7_yUE!e^*#oyM( z(%B0_Uhy?;QLor8vQVsCMBw#cgae_pw^#%t#FGRyah1potc#bLV&GxYjc>zGyL|D2 z%dY{utF&l+;Y$+o*{c61g8+8uRjiimDbZiF{qGtPZYf2oNS7KOb(Ekzi{I}SZ${q_qeMYrOu4L;?!r{ zkrc95ChyMNzIFGE%Mi67eUqrjX8%1LaTreN_uUiXhdTswN< zEzfg19r2)KU{TYlhNRLic%prdGjMKWe%#TPgrF~UU~31kyOFris~h>nzrR-gzlNXv z&p*-HkMd6!zT({pclUgB-6tTR>5ANrHER-|-CR?ZoP=ldtPXkNjv!4blH8i7t7|3j zgCk3=(x17v%RFOE!s#0hy?jra6Lt{tdQ-Jp*qD9}$+tk+zRGLEE7kuAZ=e3Nep7<1 z)~#^S`!(@fxK!y>d#QIoh;^X0Qw@3af6({F-wgbGjostm6+ei0%J&xJb4`B`<@LX zP^UY@9h%{jt_1XtriO1a#~H`S?HTafhcl+cek@1sF(g5&f~hVV|9W+{B3F3Y7RYiW zFE(XN^Yok+;3?YXYfMon8_)4Bbs!lc|13E|$^MH~0m>-@BX*~~_5V8~zV%6UinOq; zUmi{aQ0lTfWR<9|K(6h%VEcN5&T}^@VGY^WNv-R)wB?igMjwOqA}CIuj>5P`S@fi* z&Iqzm*bwoNSw!FfA}NNerj#rI&YI5GOcVN-7vZ4W9FeseEA)vN%T#jP0^Gu6JlWX~ z6LTNYZR5sLo$qWu5>5A%_mJkxnp^e#7Wid%{t%X@`+xZmTjRy&Nha$Rb8L|Kz1tC| zkzU4rUj(!MKg)tx%wWZn9Nu*vR*z5t7BKE z(PLcmMRS{9HCkFST7}ejCZ$x)!7i_Ih#l&W*Hk138=Xnw{C7>#7+K zUxS5E#P%WBshN8_oVJG(QcY(b_8TzY)XYi4I}<&HQvPMg?-g2>oa^D(EODBylExWO(c{v*V9g{XwomnArm@nkapsik_WI6UqcNXj=jYh? z!r?xz9mzU#0vYINW&F9MuD1mCyI#zfJInsD5}!Z!ADYpvI{}EYe08J2=JTcjw7U;p z-C*epKHsooW=)mr7H;mAV}XK;kQ~?M`{h#4;5xh{d5hY5;fRapjQ}O};L5DnK9s9$ zVvH3sFkB)dm&K7zjD~p=7TZ=xs&YYP3(30inx{-3jHtBx-)99VB}a0vzse^$$z_F} z+G@NrqALzjhV8RG9~qz^?HIQ&n&_E5@@F9Y0(xJH1c4wMrMT7~KUcrkwLnm%Fs1I> z0QM{N`JoJGFg6;gqR)*ePt#7(HJgtLu~pDwA%0pHU9o@G z+s?O*u#ReQQJWM~i_Ql#DB5ihSPX2&eJD$%(=uxWLn}^ci}udXbz{J%ZaBV_K(O(< zW}2r4CMiy$cf}ZANl(q3`wy;%VmUYeWI5L#Pq4`nU2~$gErvK@njFanF@4_Ml4~Ub z{n?hQZ*x9>?1c?LN%rIJXZ@W3ss$35k-JywD>FZD8n6rc32VR#8ZkqmkLIKcR=eK$ z62pD3gug$)RkGgluI2{lM+|_HJx!<-Svm3i4LdbOd%*yqK3{rcwel@R$5C2&;u``H zTH=m5&^#Q~3bSJiUk??)jCO-ONib~IM&%}aoiVW)>YVJM|0gQ4 z)nUaD@vOv@4_yLyz|V)O8%;;!gP+^mfvg`Ve@^56f{A13TzQ5x;^B=;>ztTV;mj$qm(~-Y% zzc%DS>r8mpNX4wjTYOz(rlUh27OD(X^83p$%;(nBLl3s~?@tOtYhq zoB3Cs_s=CRVSJzGsoGmI2d)YYE}1I~9%^)GnoG!`DpqQ}9Y(4cdD9b+DQz;o=3p3Q zFFCeO=`=snJM!-zOlcT-)JH+L(95C$R>W@2|=!3Y&FKwpieI7@3x3nfq>Z9bt zyZ3Fb|0^=HX?zicm2cH7_?3n*KH47H{_y3!qW8j;pG)zRb#v=PK#?y1{XKZW5-4@k%RA(;aw6wqXs4ZODGi z4D#CgzT2L#P@Lc@^0zRG7;8>;(reSSJ*O|4_EzK@D(El+>m@s}L?&!%X$uGZ5tX<_ z_R?JNyvUCu2^jV5Ldhy86;?NibnWCe_EDX--MY4jJ?{VpYg+4 zo~~2qh@x_Gsu^bPVJX`Xt#Y_9x-FyMY&vH_t_+|lP-SUHB?jikJLXM&^F~@`?V{%w ziAbuzk0HUb?ft= ztvL%|*Rvk|Z%bMJ3U{AC0lLAvLv7bweXrfXK8!kPT{K8>7oJN)R_tpGZj!O5)>}rlx@Pb^hxOaZ#u2ZnDJmmOy3e#Bj=*ex zwGzw@qc1LU!W`}}`kqp$YhN7MfgtA7;|Li-@nh$rFtfxe!Ud~+!kLu?7e?N~!VFy3 z2khAIv8pgB(+peYd^xW>YY0k_wOD`7=|ewq*5J`9<3rmw_0gn$vyE)bW_3fxbu$aA z;A%k=SEHL=oLAmFo9h2mw^%Yjllt};axa#1l=0(F-Alr;qmEOtp^yv{UFqovy?{U4 z(ONH)uz^Q97<($dvo`~=GrnU@)osNB2r?SqgDIJV)=bDr-q{uv^ME7zhiMlBKX?3o zd-~HS0DP&HGySi9hR+4-FHA}SAT7q4c&1#!-X!*8AU_8*va7o}`4At89FBT1h`g*P ztttx@y#qZA&vh5d=OGk=XnH;tri{iV+upEE32I7dDMRwgNzKbMPAiQ!7U!D{XeZx%YVIhMX1|)-U~)U) zd++A?x}J+R>(@M^;~>n`kb3q!I%_5$J_li0XauJ%rD;pNdR$yqA1$<(j4f`{lz1%m zkqA%NobeCe;RBo1jNo2fmc@nYXTrYwJsk2ycuxQRoiQEwA{`>({ijSq1J~mL|H`cY>v#O~W&ixJ`y7BDYg<09Y?$o= zb68xAu>IG|-5+5;S+r$G*VLv93>r7N~Y`;wfjOESl0L-w_M z)7*r)<%#q(fwGUtzK3|;iRJFJS*xUaPkRtK#O%<`S=7z7NWE`9#Yo4fSk>Lgc@>*YEbg^S$sW!i0BWl>_bFOo=*YuKWy%brX;_i zhMTI~4+890_mg_qbV)3(W==0$8q7P=WLAI{gyP-iG0}E7H|&DR^=m@#rO;*yjUvLz2-UfE3Lu=o^j;r-PIq&Y|R-J|#oift-J}6uqUr|86#!i-3 zzAYPUgxyl#H!kMBHwYQ+K+e{xBvyjKKG{@Kujwe_(KY_t4hEPJK40q%uVfR|#$G<^ zg*EXN$b2uIAgr*uM0m)!bcCpB0vpYqq~4ecpS_gtEH#`xQqGSf#(G4@+cZZU=~QvU zRaW1yJO!@yMAs$A}b__l?q=~=B9YaSfS)`F`nxyJY1uya}U>mk4wPaBV< z&-?Y<6@+z0XScnn&N*#@Qv+v-*TpmG<~Y4O5`!6gxh%vf!}p~aw+{^=d#a#~EO4tt zBRh+wm9o^I0}F-J&Bhm4>3s0yX^s?g3q#aiw&_7d5j`4@=b|gbJnD#JyadmB;ayPR zo3*ynCEIi}P7BNtm9i!?B9_J!zp{sam}G-eAl8)no*v5|)=3%aAV#unvi3;}r5Qjh zn*^9<8iGxq8;-RBRCK5q-IPt#pJ|87KOUL(`|qrZ;Jgfa9?|bhI~j;iyUo5$5P-Rn%Cu3sy1FHKL?fNKK7BirN=#{*Q=yP+7e<_ z0BuT2MO%Z%J=sJ&9z5DoX7vkTyJOxsLzXTbqUz@!z9OB+loaM?K`dOXBBT41>Y1YI zfPJ?;$>@iT`B2^WGgpxp3^7(G^3H?yP@p&-rx|2FdQMg6k<~Bva50cv>&#buAJl&i z3cEz~57*VH%tz6tucl?OwzOwYzH@iaOL{oj?=2U}LiDvNC#|G)X(#On&{ij@u^*uc ztPZcYGe_(3o2=N>sU6tNm-W6HSbKd&LKxBO%}B3o0B|DK9`Z1^C*mw@z>SI;)#;ws zJ@77^s+H92&($vzUS%wwGSA40Aj?n2)LXrCbpd0VM#AHnnfwy{t$c!k(t zk|yU!#Zjo%f~=QqX!&|!t>KkTJjZdUC7D(i6CWrEtt~O7Pl&NI{WcStmU%qO-YAw^ zY+*e^m@mcm4|uMaBXw{L)8kMr=n7$TT;Yf-5!1W`2JGVjO1ZVw7`43B`x8NNMn#Gx zEH0z?%8<0W7p9h;sO{nkjocPCS)Uu|XcmcXj<1j};5lAGfwS{abWt4iG?BQMs1)yh z$az@bG~o&boyLPt>f-oKO`w~B@xk|)&Rd0!HtM82=G>*Lshgf0=EG+OX4cS>ok$x# zMm-YN!{ZBQ#T=Ud8!Xf%o=RcxPujn*xmo}P<@%0YVz5`bp?py>epdOpkZRK|BEP9z zEa``WtDP%p@he(3M?Fz-BeELL#D)VI&(-{~Hosn*_4!xg1EDc}YDMn+OlP&;I4uon z&g=7wB#=|snO|2oikmFQueT!3O~o>s2l>~0IGCLFW@Xo(!)G8v#la(ju$~vGd)IB3 zcM;C(EOi?2i>0i4rD-iVQNE_M2kT4prq-+`${T0f6Ji@a^a{&pmK+!B_leCvxQesBoot+Epom1yz9*x{|iLkx0@JerzfcuzJDD1iVCsb#> zQG#>L#0O$C_;Dj=R{9gS1#W|^sIJv@su5LV5c8MI@0~5JDb#eFPvMnb)GD@FR9sM zX*9jir*kjF=$fibN$x`f-6{ABF~g#gTAlmUVWVYUR2lMn$6lVk%P%PPTAwUajeBbb zW8db}EsMls!R-O|`t~(bW8^z*(In`ZpF^go|Lp~rzKm71nYta}q9{|p>BY^xp-!Ie zSHgM6*s1rDPMC7R7f5J6rHYERi?C_JC&vkE<UBRWch(TM1#-;Cmoz8ZbDYyWhAu>Qy2Y$|(Uk6};5afRm;yBg<5=Bp%eg`%Yeh0b}c zxh2saFjSSYN7LvUvxA{3Yaq`}MQ?PGNOD(}ud;afR0cD{b3GeRZ4qj$^AyhCYaO?? z_L!(B@7uWPYS-qIQEz%=ytOt3mv@z!duuIME+|}*WF2@=5!;HbzO|I@@5>E`&Gx*Z zv!tvw-L1m-YA+45x3rBe1^Vxw8!QYAS?}^f^FyL$34V^7)^`P`H7zDbxk%LYcuNnI z>;;B^O^tNIo@hq~HqGAM(EaYY;iQE5;>4*x3wy7D-nYt%qfR0W?!&gl&cqf=!6xB{ z6T1z+Fl_5}0A08?do^d{7yte|u<;+z)7PJ}>z69)W>cPaAb;TnhM%IR7dNYpRNyOB z>`oFJO4>V4;vl_hM;@)1kDGPOlc^h46XF4?9dleXp3pCBFBLU5P#mx)DBr ztxlN|Ss^q^>OWvdEi)gUr;osKt_+)}c?Zxc8CQrQ&8j*hX76OYM|_)Urs-)ZBO?qP zt&cc7z$Fv{KdGzpAMsPYq?M#f&3emQ8-H(`P^kI){un0T+gi1{av$#)4icg3V-H8U zBQe1_b`;{=Rit^0+eSDa8HFuBe&)g4Ojr6SWWnMiIT7K!j{E)?~4Js~-?|nT0=XK>1ECPKg8pe!p;^GrMb|BTuM~ z!A!y`nPR=NMCJ42B^h2F+h|KP_Ug*D%@lMsPrM9cw0@WE<}xE1q~dH|n|y$@Rc@VS z?|L#v>fO}&mdBGrYmF>5cGIcp3Qwd6gr-)lmKIgYoTA=&@R**po06=rKa8;MnM;}* zI0f1twz}<9^R6vYniS^JgOK8|7I1tJvaEaI9#xVTHkxSd@ z^UDM|>Fm)4qg{y(EpjIPN*IEd_bywGAOa|CL($Pi!smJ|e&WgLZni ziXltbYUrdxO-(m8^F7OI)>#I!#+eb#5hb)>`) z6SuJ^z4GRz=MyiJbjcl#8BF}6(3rq9+cc$_L7dea%80D;?JWJ1(=kNXhQ?)z=E&0P zp;w0a!JNGIOZ+$-=%)pKUm(r;o4uv)THlY3hNXa zi5v6X&+d=JgtVJ%!r#;#fNJ_Fe!Vpc23j*l)tw^)kbTm#ALUQ;k; zKx@{Mf~y}JMqGFt+w&0lB#JS!&ht0rxJOZ=aC%L@J8zj+Y$kYd(oOYuPX0nF;5i7t=}-Wg(LRx-xW01b zIJH1dmM}YbCL3&5SZu0#I9N*t8R;nFlfK1KzpWdTq`%UqPu$pScZw?S>&LIV7sP3* ztHJW1(eV{!!_I1(wqSi}4!R#EH|SqLr8(?a6NsRp$k4g>5`Wdr)IH$HANKtm`5Rj} z&luhO9Nj^x?Y7Br#i%ZY7-ALr*$n#kxYQT1_uFgbT37hGK2e#uJuoTY=9rAwG!|}S zj9d=Sfa4W%80}`N`wu5}Q14J)G8RlaueWPgs}I#u6y3p&Kde2A6|3&oi)r@oOwmHS8_KrglzV@-kcfSunoLh{0 z;{UIjKDfDSuS)@tBus+R^$LDg#8~#J&I(z~3$?a<&-|?-o^M~{K z3F!9ceA+3RLhD{<^yN@aG*XGcQChX5RN5~C0~EJ_sHDL zI;A}I#5&`Lu*dRb4 zQ4m5)LQ4V!2qcgYLXt0Y-uLY9?0xp^z0bG*dEe`sf4Fjmi-+e~&;48VUTdWN zc++;=64hS!roGC4=89!n6$QlD*N)NR;d1fSoz0di;G*-%g}=7e$Hh3zS8J?A^Gtr? zy_;(;5VU<}V^9_hd0sco!KZYYO3ZVVd5-RdZXEl_kIkzIhqHCBT$vpLk zZf$FpQ*MiOoS12#fsdcRz7CVIkeXUuINiOZ7?^K{wU9Zo;3CaBoxO-@c@l@J@eB`c zVvbXnNxGR)z>BRK!N%0~zBmpk|C=Tn*@^_&*GX!&v;c7LUIr{#bWVZ`4Cyw3u>hAc zXL6bGfc2n0eP)=}QSx*3#{mM;!4?Bx&E)dGKhmZPn> zfyr~A)opecMnGxlC&=E{sZ#zW;hO6)b`%m%RW;B%;b(rwMKmvppEEk7GhIbNp(h&s zF#I8_1D0NH8b|WomuoqZ@8~G+tI|zv;#bZMSi-T*DB*r)*KJ#=uDN z{*C3|m6^je!{-)K*C{f?zi^_OUfKABaGN_mqrm)0p4A#Ug@GI18SURjfjLyV5^F;w zbCNmjcdcAfG^wC6Fc9=cqop&6+Me2wUS12;Nj8rG$JcUQud48O<9zeP z?_}xjR|L!EW2a?4Xk7o{A1K$Pm(GjN;ke2edq=M;VHbzfOf}(QeBU1mZ;bikB7V@6M^^2C zt9u&nX@cxO&})GEj=RUxS8YF6cDl^LH>LcShlf$tVfVF)MNw;R)y_m^+~4ZZ%;rCr-sB8y@=0{-iH_#fU?Qq|F^lpN=$@{LLV za%Uo3MXPhyDGh{u4HT zM|%Hf!{%Q`$Y0+0pHTUGI^_Qc8s<-^y!}7Q7+IN)#E4f|gv=V`<~^z#eE6c(-$Ujf z+mZ4;o@Tl|d0UpZ)*N2h?<>Qg5F*1&{|;lEp`Nnv@+{~R`dQ8mB5-Tk`@u> zZ(U^Wki>=PB?E&0x<>s!yrx7fDLH?NFXaC3=qZQ5pDwIa42 zm+aWt$+PJ)x}&Oc{oRP24=fNj_!Nh0iQO8d^za8|yfg3c-YEeqgC7txB}<66C!fO< z7K}#%AK;Ac;6yiSultG-rOJrQHEt1AGCNeUZwrmfr5!0-*D4^vbercn>f3lge|$@y z{@tGiOFp#_`8PS=RbOmNJTjl<-Ad&2&i~gLME@)(_zz?E{nxS@DYr-eh@SW_L0eZ- zauK~sO40jh%LKpJH{lbp2ES2P)T5sc*ajug0nuve-*O8UR+b~kvGQl^whF`xW%gii zGe|DGM5W;E!X1{7lFg~#kg**%gLyvpeBHkjV(^QEY}B6`uaNR4VlD78GWC&WBF`B? zsNHvlu+*<1f7oR8;$#D}764zb+VF|@PQ7f>$g6a^m~gDOem%LaPEac$3f#-pzNug8 z$E1Af8!PVE!H32(3sEm;k^qUPuHwh%mQNf0QLo@1Jogm)`|q9D?0L<`|EZw=>Sa8T z{oX0^@WB+_`)6%WK&l~8lQq@G>Oa5_*+q6Q?Lxp-Si@h|n%yaBLmvum)2(5iuZ1D7 z0}Ex6?w0k>YWE&(=Da%%&weH@JGli0j=>zBWx_XRPb~ftVEIV)STihk&OXP0erWcV zZ9GTGm{XvwEuDJ8y$`Ciu%O-qp#|Svecp+njlOEK$Gczc3?C1@I2a8c-vpudTPn)|1_hn=s*vMI$NWZoBVhP{ zSY%D=J$3ZioZqs-#vhI0`2+F)bqHfCCy}Cynu2c4S=&XXaJ%STyPDO*Ms;ts#sC z$4>GF4yfXnD@B*G{qOY@1n;=umXAtrLYw8wT0$JezJT=EgcO5kb6cKel^Ex+y_(E6 zpogR2(Zwl}6Oyu`mNR#(x^(eBPNVfM_TCSK2~^q+v#oA7!h8BKB4SwH$aZV0jc(7# zTxMsV23~?_@i8K9!?IH)U)6U&m*~N>Yi#x`WRbiWRG-sUPIbSWLWgD8?*k=(te;Gh(gVBEmu{GH`-jGoMCURvg85 zoGVg_jO?}+s}?pv!#@O=vC6)OGJ>HS}xVA5W_)!x0JiXZmu)4Xjat+IsC8{CqdyP3`3TzS@8S$ZJ(pzg0T z2kH{~d$ds3>#W#-jaE5?6=yi}Xluw%Z~T-1!-CrtWTfC`1<%{~LdClt+UzfT`@son z>63-9Ut`{PA-4t))9B7cx=AAE7UCGbnh|JIWK99-?qfJ(Xji$*_mT(IeREWR$VgY|t49-Sp-swoXxfnkC)?e-6X<(62;4$R3 zMf0MmxAanveXO}wc@|p9bZ=mp$Ae`Djh|Mx$|I`bwF3z5m)QB|uhIpX=bs$^W#zE? zjslz5Mt|#Ol!H=ltyPYvZLT&`qxAX?nhBGYXnusdbVo+cqI;!tiQfB`aBD1#bjSL- zu3f2bC_1#D`t9eJn}l|@Sj#L1dRU+nqQ8UN=}1-@wx6g2SC}L_(wf?VQCC<lC;Tu#Ekp^o!lqJ5NtRCvjKsM1(*0|u8JxE0}Y^Ax2a-WQW{v(pp8 zOMV##1KK{2tPwoQHHV0P9LySsdH}xWfH~QO?loS$)I52FZ-&W5EXnic1b#!SK;S7= zKWkj6hqMhmA1(3VinQuW+G9FY1hGwXf`H`f)@5~2C2~B_FNC?}TCq$Ps4s^f-m2Fi zG*ccUbedy5RRuDWq7D1vL{VIY7O~mKDLp$w@1f(XEL>D4`(VrF%*x-(Ec}NS*{3J5 zeXF|gf2&`-AnA7v_OqrJ#ns}_Fjd&UVqcx4gtyi4l=sN?oVU;M=lh!pqUst~9Qg8= zc!>=Fu0h${*uYR{9hDOxqK#{i22vALC1&=q{*Dx$t#hJV`}f36sFHX#_yjq`7q;z6?qIZykAqy{A9@lumG;Jtgp5$460$s?o~@2){F0 z;H%)idY`PYqZWV-0G{HY;CnsX=)6TK<3Q`etzXZ?BV%K%4)ImV+zS;6{y*>KK-h}_ z$x>+8#!BY3hL$6(&r@&5dB~>K4l460iAJ2^Z{I`F0IIsGfIHH|>kDDo-mQPh>I2~K zQiL}~+A$ae8P~F_9!VJ;mjhZgHKtm-Wft6*EE?WyGdF0$E7xZD0_}`2u{1o8{OgnpKSKa7_Wi z@*(~naNY_MX2^Ceo5-bw4n)G`X73C<=m0SuWS(^~7qMqP0|0TFV&z*C`C$mYCc0BL z=yS(~=P}+E*ZMPd)JRMu0;|(X3}0>&L%yb=!_~%!n`=1^Fkt;cR&mMB8!7+bRr}vxO<( zb#X!Eoc1_vlON zD}@)N?$2JIDPVboaLV7hy;Svov z`X4_kF0L=3~Gd8r9M`bX+zh96y8r3*bJTHFIXe9mh*oCgbc%z+M*X zTNnK2Eml~f_&GtahNY1uKXM7{hT$DzeOAPjZA@Gd?0V6*;@{fHYH-YFb!pld9h0)pN-FZK8x?e<1L-o+D4cK- z4S8?`K?|0wMI|JxX?n#(JkTpfJH9ODuk~)TAp~IJCy?A;`qL`W7I;X#rVi=3~g()ZX@kPM@iW% z)>&c&1#G=&lCD8C2ix-Vhv+KQjsqUN#q^-KqmZRhN`V?q#=D>I&hsohZBEeJT*qeL z>C$PoyUR&mdTODVqT6p*7rsO;-B?@}_~$}4t@#!w!Oj-ILvv=_!Vocl*c-=~mS}p+BwK zPTs=7J&E+@z=}LtBf=v+Rl68PV#f!hnsB1>W{_$SNOqcbU+tiWGK@-6r-Hy@p*;|0sQwG8v=HGFV^Jy` z{fwCPr_OA9ZxFU2>f#UNSnDkjb3!fQmUAL(bFgIFY7Oeu^9)J>3;G5S;*TswOWbCc zxi6MYfZHPzk21Q%k{?9aGJ*HxG=P>JV9G>ewfY3Er!Ql-zL4tx-~c$@H-XqCD))%; zo@7tU)rqMp#NEaj9#K}JDPiWlC_z4ymAKtiVw}OygKyJtXTcN}5lq}&2zyO0GugHm=e4++OB z!hiTW=2_$7DYf$>ULa)|VZ^H=Cu?&bI}zCR>9HOsWsoJ)MM zt-|qHOL)P3&$gULXMB2P2c&n5Z*M0fqA4losFmSZE8NXM;@*fv-%Ead_1nG^m>-H^ zhMdKI-Y}Fvbyv7fdC~MJB9S115>b%S+FVuxOpYJmUAiF%=9SigFvM_y+nR9M@4Mjy zR@++^@A-uMh35PvaXai`ct*&0ykNjoC2@5z_8A4wN;o};W6VJ|cjD^304;(CCYW0h z7)=}@Rh4fsKDNd{RQobit=s5pVC$`!nL>7|*5s9C` z-~r`XI6b;RDDaQ>>VgRSw^gYy2x#QbP0PL^H*b_{!V`2A0`u= zK~s;Mv1!*gBfeA8R%TwHZ&f8E-#l zo~eInXqW(+|(KxWR;gv!Zj8-4IR%;yi5mPF)lB#rR$ncBT zaG;N(U2JsM{o=%E=L(|Of=Y5DRGma0)~hZEOFuxO)*?z}_5Zk|^ETq|O#QLGqfMLIa(hh>O}s5@#_)G=978fU3K+omw6}# z0_A1F(sBq{ncB;hs-fZ8oaCW5Cn`@!rlfR!&yexo(9#)B@0t!;MKGu8w(p)9r4W{Q zZPC#`;a+?A`}NL#C=<@#pxlxKIs)It1;^+FzGbV8YDEx~JL0j#SxBH>dMvXpd>x;)MP61AIDL(!=S`X=<$HL!j zF1T%Hpzl(a<&d6jakT{HlAdODWkR+(ihSL>mw^+umXzw0|J=EkI-Z*7B^XTbmDP`o z4|K|U)-lc*E;33@9c%3vcN(raFkznp52+V-Z|46LS3Owic_PC;i6;|td(KM|wN()F zg;yE5-+RQM6pGLQ((|Gjf;4)Z{Xi9+ET_zHQ|GnC=LpS4srMOh3yQb3wF=9kYM)Zb zm1!lDEVWbloRHg(>1LkhGFpwCYNPrf2%%vXA2mshxdhLQR2fFgyOTqslV9PcpCMON zuX{fqeBu?2&}{Gz^T@Xg^1nCM9jk&mUo8xDX*88`smd ziQlUw_9y`}`^0*tE*&7y%gRJIism0_{ht)Ru{y1A>Z$a^m#6A?q*; zx)bB06U^Cq$~;QJY?ITyMs}M*R7Qk{^9_ab^@or9bA#{Ft>Mi$jD#eeri#jra(HFh zm!%yS^EsO~AABvb)Y0kkwBdC<>2-QXTZ7<+=QV>1eHUC81wTfWnIUFFR@)}c*66Xb zRtyt_ERWWW3X~(YugBCin3`Y1U`hqq#zi-EMw4LP^4V}?r0}cT0e|# z%^fmkG2uI-FrZB0>DX%`+G?2(dDLk0tCOeBoT>6K4ldJ5ZVjOmz3gVbsAnHycHLtT zv9_k|$o`GB+m{lgm_P$`AS0@28LEChpIE%uQq@X4dNy?bNZ@>02G8@zU1V>YuJn4q zG07yXD3ywtPi?R_K$dZR>;`|mS$yce<>m*7dT03iSsh)TB$bHrM1B<0?Bl{J+Jg~#YG){mv!Qm}nq+g%Ixq z&mP~$!P`HK{&0o?3cEKt&eYpV{9s?&`onNzNTSi4BDu@rg! zjK|dO!@IuVE-t)5&d!da`;0(N;htaC=b7fuwlNnl#ukko+<{Y!js2kh2vBQ+!yJ|0 zJ#LRvTu7L@)v7kv=3E$`R1EB(u9)P~!beMZRbj(ZUL43}!FVWjXLBVEQ{IYw$$g*a z?j3gHLvTEYlTck^=hgV*qiThy@-;|A84~;Y`cUMCdVAu!{ z63vZrOU$0w&R9$Qu_pi14RtI}Y9W_xsxc`G4WCJU+5R?ZV}(#4q3dU3&39D9OB0`g%8NGbvwMhU6$H;Ldz+2C5usscON^p z{jH9~*{xr%Ww60ovC9{l4eq}!Oy(D~v6!MeO8i9JE!mxlpGr-XG})ZcZ(e99I8CKp zGRCb{2dkfy6UNp=x|Sf#dGG8c^X_sQVDCGOjaDWeZfN0a5AsQtZ0izm=QUVb<4Z9Q z3pk_y{wymYg1X=4n^(`80;}`*D)G+@rM+r`U0J};l0<`qBiWB?hy|>Ht=enXCS?78 zHr2hWg6D>rUsL`OG5rw*w%M9YSG8?RJbx@&6?fMNS0^cwD(qpk!Iv1=kbxcSTVAJ= zr7rsud7=c0xX?I6t-5SnE*@6T(^F5lWfLY~TQMnEaE2wwr1NM#wca@nUG#i_1@@E9v7zuMM?6wY`>}gnUjZ7j&q%O(7yN~vZ(Qd9^~fhc~{=t7SMts<>)zA zd%j(_tT#GZU|_oQTM|NqT^0CTdlv7P$f($Sk5ainw%#m^g$s)i zwb{xLGA3oxHP7DoZjW|9V@g?(ZP_%<%i3T1d0vXz!-6$W<`65TV*Dx!%Aytc6_@GB zyqQm*V-3`LK9}>S%-*oFOfbwm<#W0UJ*2l6p6}Kn)f=hDgqqw2&N16Iwk~RM)H>TV zSmG|VnG1sbIuX#%CHA($!zM)=X70Tkt-8P9UuyLHbUJBiKKLu-1$d>0pc^>8U9NDl z?rLVrcy-{2%B|OcU}%MtL1y%}-@X$4qy1;a=1%2F7o3xevY?yEyur0mb9cgL-@=uN zf`{l_S#z!G@+Xg2^0a{?t&{AfvxfJ+v`5@xdNuo94>)Y7LkFHl7lZqw=hlGX8Ct3> zTGYTM#yUznlyDcd^;pG0}3yHD-aBcUv@* z&LI93{+caZ=`JsdTT~F3kbcf9uZD;bsnvT&jbL@((@x0lBDQ|mMY-5qHoIR1CX5^KO4%>(9 zUomb2Chx5zPb&e3zxpkKmhrLcw;tXDN-dhUUsAdIwe8oOu4RTck$2B9PdUO54=1U2 zHfUsLuQAX1e}1L}wyDeOOBt@++pzZYp}3cWKhVNnKKP{4x@pSkV*$r7?^x#zNm*NE z*B`-h$!YQh%>JoJSQ(3#!Rh2?J;Ny4dNFK+M(;TWiaU|wP>-rJI+;1_iFy0`0q~hM z=c;XoL~xKvMgZI;KkAQs=eKu$kT8MFHkz9LjiPGO$>XcNCr4BU3bl7sI@((|T>h#8@ors`R%75-(Xft9NJO3=ac_1ZVWZ9f*zhxPfq0N*t!63w#w z0cBN5kL!+!k8eFze=$H1-GUqwU?ZsyPDFT6=u0u(J>wgbD<&fOY`=NpyRTq{bu2rD z(@$TR<=tnhq@9y#f;Zq8x@pYos@t{|1{kg}BGGu~%Py{+s!$46I-!;CmhDxP^-L9$ zcY5+_&?>e} zQ^j#{I*`6}SFMLS!tCmXtBI$I|8o|A_*IHxXusDQBZAJc!O>re=C8!8J3yj5Yl~Lj zf0^nY60S~eHz7C)Lu%G)ZhSm zgv-h{A6qa`>M3=R7nz-cfUV7JQ(9xlMWZZMpZ&?Ys1@9^yt-z7msn+i%<{X4Ab}?2 z1bVDKmaLa@d;+PX2E=o0pM^rceVo306JWJ{WAuZxw@(rW-jXL9svA*D6vs4lE11#e zLn4TmK)v5*dQeT=zx)W=UF;z`%0-8_ogR!fPI%03J~Vc`qz10lPE9l#)Hc4cj#L+6%H*>IWP3 z(A1U_$Z9stX+df7?95YtmbgJ!|D;UkDi4q{{?4E=TuHZ zU#4ZYwF#D6R>t-kMd0XzSXxofHNZtq!oqT3lw~1^g!R<|p{jI#IvlZf_RKn2?M(>h z7Hh0g+l~_tn<(&3Gl0eMjMbJs-8-%+-Bstt&M|*}9(jTqi|W)L8lPF@##+dyY_0Ud z3Oo(ExAG9@8FG79lFIqQCkdGd)#{DSqfF{XB^7>dr+8t_UKQI`4d z4(cqTv+kTR7r$SzWa18=uTR2H$|;;)0AO1Ikrrlvl31P|K-o8_sbBk z<-vNP@4s$4lE3t^bw?m&DUD1SVyFmjLCz~(gMr}%Yf=w;w8lpQ{W4U^1+q6@HJi2= z_W|yhsVkr!E4SzMy%ozVVjDt(D)x#@84R$a&}j*6$+G`dVS?E}3Yf$9y;JYX%9!f` z`^>s%umE?Dy?$EYcn3W$QyJ`VLhz&d_ZQDRoLs6Nv3Vzs_aczYn;90hE|E#2oS~)c z4U#|1^Hoeit>q+dc2qmWRRyixzs75=GlJTpLbR*^>gl7-UIq0ZeJ#gCzFj6qLh6RM zMqkSIq(Nqr`4)!_bNmK|^DdwcREPKPJ~DwRlr?xYCasb=00O#M7d6!1T=Ez3UYFWlFTXQk)0#y_gJ3t+ny&4WYI7o5^nsE}gGfp(_pPEDV2sq2 zlmzwOSG8_u&ask9Io<{*fbxg~^yP_XCB9J&9rrJpf(W@XgX~s?R;c8)PR$-LS@*Ps z#y>%yJhir2jkaw=1rc87ZB1oeihyQD_?(J5)NC!{>JOa#k|&eC+fbPlaNgstaR6pN z=Rqep{ugI0+2>vDyMRfBI%dt477g4;iMy2a~B za}${(_RW}ronn47r}GYN+x>%=i)ouWH6tp2f3g3^WMDsjcV3=PqEcLC>gz94iRy=p z`g`3uQKh%M8cYfKL9|XawIQA6k83D-u1#B$sd~ROwrF2e^2x}T@t16&9^^b~!`3N< z3$JI3w94<>RU=dy-fq`dCBQuD?7wlzX_X!MqXIRo8`*A(MB^GDr+{wi4`XcH!9?f6d? zo%2=pp!rZ!$5(|BLb<)^KGHN!1$3D>9Ma<9_aDw!O}{w)LPe0_ z{t_YofBN8w+JWrw)Iw3d(XBlzx<4eeEF7Ug-VG?M1utZd8_bfC%JSMC5nrfXuic}HFxY`IP!NwqC}o= z5>G5Pua0MWHs64Vx+JTeIu&g;wTYlN>$h_|c!5}DuC&8=WI`_%YZ01Xlstx}wVf%y zR`3d?>7BlvkOGF^`R!|P$ckxJY@qo3nZ&L*`OPEsW8x5JCHE`6*JLDv!IxW#_V$qt z6pAVzThTrTk8i7T^xkDBY`f^yjy+ZsXki}Hgax8){6;0-6Bj8GMIJ?>hwZ&XS4%*>j}HqdCob0z?9Xc{TIbXplx1@_IwzkD@>O1M8R>z{BC{C*|{b!g#{X%oUXV3NJOrAaR{y9i_BKLPx&$zsOB{$46a}(pE#ZY$R;ZB z%wy;+UK6>e-v@h~{v`Ni(wEr_rIJT;7Uqo;HS0SX%6nQ*mmaansd3R4hnPoM08drh zVY_}Z4bZ_ejR<(rSiPaT2KjSNUBaUJyi(TH7)m~MLdEhC0xDYL(;~J%d4VL&6n&)# z%$7??MKq#_eo%b*N~~JFBQ~4A&{@}@K29kZdb0RwIL1Geq=YJyWC>^AY$a&4vr3lS zXC%QJ+e={!1(5Oyd(su9tHcQ4^4P`c5#t53HCL^#Otv0Z_iHLZPweC?wJjIDFK_V( zyyQ1f|HDAzj~e&`Hf?RGen1seHuPFq@0+OjJ*U^>qS0}vWyPLEEvDra>kEoefB|B> zK~IjZm*K7&%t=n3#qeFvr7X4jxe0RXikGu=DrTub5F60hmwNwq?t(ed5o8$z=S@jMx2y#w^1?+Y70Z&s^1E*J*ic(Vt1J5>Jn z5}CgA8-|Gvbv7ovO5ujD*2;F&a28LyzFJ3ppRPm^pQDwgM^A|szdCvOi#1fI!GY*} z!wC~R**g9C#C-lG8S6IxF@SYjUHqIBSE_68MN&E1M#NtRq`v8d?%z5pwnT&Ry(Zr7 z4Mu~FwR|h9$OTpZ0VTy|Iu;Bb&mpE6kI?sD4+izHb(4_|Y^xA#5$n0fN*jP+`C1>% z3P;0c6*@MT++_C%CbDUQ!CpGSq;vYgGrA2wB%K?6WFz5}$G433s$^xAd*J_*1^wTY8T8odo_&85mHtbdfF!)@)T4rsuHoXh8geE= zz-&y)<$W*`QTX}&wByCq`Aj0z2<3UTH}!f7KJqeS1d(L%+OHqB2#xVvU5GEt?>evd z=4?zq7+#{#G^K$Y7!5FZU};{K?4ZWkQWg2Wm~CC(F=rWNCVsYxXiijkz6^_st>_d~ zt8eU>q(Re7evnt~15|hcKiy}hJe$7{JE(}%ih)$e_G53uR!Q+Ux&{~1GTI|v&u0%c zHurw_#@n2J-`D z2*DIqrk~rd0%CYx2~{yYsJJntNh$?|x4k7IG!&8+$NNw%U^pe)D9X}wyV%4tNLjOI z$&r|`SMPRMgMI;xL95dxTq|PYq75QT;~StQWxZ>!g(&PEVL`s%z30UqQC@A_@#>k) z_hW8l_{g|dXCxEwZfjG&Y7QGK8uPvph?w=7AWb?9~{{0@>fZ`NRDtAQ<(92}M#plnouf*^A8`N9DK$e*@1K116yi9eyf)3Vv$P6;qJ zsJt*9oce_4E1ngZyrFSlz6Z%n9#~NB+N@IQi{N~Ep=1a9G}ITQRY)OBJ1KJ~aeBhuhG);)+F`sf_A=_v+x9 zi16Y7{92)0b;e7ewNeMYPsuSEvBSW}Gf?(NRCTJwXv9FC(-lNJrqKp+1clo_?rM9z zGbrBmXy5O8lA`Y)yz{~cgBWiW+==&5eBq96vo9XrHWddmL6!+=M)YQw`pOq!c7$Bs52CFzY}LQD)P<~FCOgSCjV$G`n;Ki;F1w$JuW4R+`; z{7eh$G2?t7oTEQ@E1r0o_$V|ce(dnzx3e!}RNzl5esrfZ?v_>GdH%STfs(huc9seO z?4kMcoQASxYR|?3?OCG#+~+2(24u>Y>B-VauZe3T^OKL7h@hj$SsfXX@4-fXDK`C% z^BRS_Ris23X7Kx=dgdd%M?E}0*`L?0$p+Oi%xfboAi~hI-6W1MJVb*UWrS+|k&rEH zMY8m274_GrUbM3z-Ea~sGxGX%oZH|tL%vA7outE8^IY)^6m**4?d1i3Jy&FCAb2`hFdJqE zhBxPRLBKA1X&x#JrVnZdn{E-#$;?>z=ok8-3i4I}O^_M~%aNQd|YdFhD<8anYtf zIF_7ZEXRE(KFlub-6}J)-0sZY-VBMD0gHn+IR`AaCL&F%Zm#;YsCo) zkI*lUlBvNZ^z!rDL3-QEI!D`g=)!E#bjIb72gsFEvM1 zky@x^D$%V-ro6~BXIXgh5NND4Nv2vTDn9UgG^_67m|0)9`W|>E*ZeYjr~uz)0i;T9mm}ZfCJ9-N-2L8^nt&cS1Jb|*7fmg z!#a{Z3P~Fu zstw+MzC<1)v`@(6_`y$}I)Mw+!)PQ>dI{MeD$&y2`gI3wuEQiT+JO>C{=gT~*Z2yj zx%q%gq;o9j_xy1Nqm-cyQWRu2i$RD)CaNT5A|tg59Lul(p8=@o9Ow34I4uJdyXOuG zIqe*)jFhI^i6I05(h9l39~qiZr=Dv*#HmR=7QN9|Y^$w#`7%CRY3=tus*z@yxweD} zL*+Uu>C-V1c}1<>BkWlFJA68SGluI7OO6D_VwDRl+J92l_Zl0?vsv#{TEHYpdbtGs zVCrE(GD6J&ve5w0+&U|p7BagQN@eQ+ZS(6lgGG_$sr`4MUv@|GE!=bWB|l}I8l&8A z+2pMHD);Nv`5zL5ozWuOH?W(+om;$c$p>myJ=73R4-OIWQ!NX@(#0}+_cBd0B5aNBjaqA{eJs*XdXrTGELuAmSMF;he-BWC1f z^FD5XsgGGFsg$B+0bqs5l46zhpK_%-8qe{{k;a>eE=D)pqELb2RSr}JD(Mu7Sp4h} zWohAtag?Kmlu?n(?ya}x1upKCic5N{f`kR`FVju6BVm-`pX=B!pfEl^neT~;-(P#C zk#5#Jy&+JCk(QgS+iE$(_Ef@3+VV6Y68a`KP!x~HDvy;>{vYlP=| z3Id9Nf{ZY26%b{JEP+6*5RkozA&h!#MP!w27>R;{2!y>!;s7E65|I&hSRp`2VhALJ zkmOCz^E_``PkT;%`~La-$LB}#%Y9$>bzS%O+PRd88@rRB6qv{k&SYoL{y*z9hI_j?Ihp2Hq7 z$IECRR~loKCf#w^5h_zY2_H6$IY}HapOWhFNqqI}z_GikFIRdp$VqkF;FNKhUdd8Q zQqvtXr7SJe%Pk3+;oqWoBp?W{7hVrWoIcq;M5K=9=Zpv!L6?6L(GWX~pdVX9gh8WP z=#Lc!$4oJGx}tgB%Z8+fq0`Kw_Qcb{OSZA zvR#o6Bcr`LJ<^QF1zyjTrOpO{i-`GzEWs2a>E`ufa>d*iuEXO;oJpbykXegA=AP52 z#m@c5Dlf*SswtcUwTAX&esz0|SJPIkor){w~ta-P6Hav&zLo%$Ayzi%!uee#oL(YMn|}OmX;h5B%=L|AaYTb)aV{4E*!Jg6VxsjcFpY#>fMD>E_Mt9V! z?MrPI^x|gI&l^V)=Vh5~YJT<^DG;D_xR5j+xx}33^Ja!-pzhCRgCJ%LuI%WPRP9-f zTMLK7G(+d?I=GKQFc0>q(UvDSvuF4h(}uv0r|tm~YZ21OGySY17cgsunxjo})E3=& z>I4)^-WLInzyu~bn%&Do5=HTMR;7$K*e0Zs>-3-6r4f-l!!iB}Xn(I?LaVOBNsf`sPdWlG zyK#9c7kw*m4v9Ud06XjBBE=`ga#Byag*uq+HAEXw2OltUcgiiyh^ zpC+zam@~7{E4{MuT-F9BR1h2TQUK1un^OwObHBiz!L*tdErM zI_BRB!f&vo&q^2;*hZhRqYRT_X=pk z#T_*O^0rP^!pOMH9>dj~)XO6y`E;J*xyo&w?#a`ugV)mieG_NhXhUYuu@BNk{;n5V zrNhn=awX)QK(hB$M6FzCV_chR(EG6l0aymqc&l)4YDcsgM<%6)Q&b8-0@aQ`afPjq zH{#gPsL(p4?g0O|IzZ^NyD93&s9_~7nFRl49i&7SzP&(lR=%4C46BzuSMMLPJh9`# z^Ms8pIh$eUGm^*jN$oQ7XYrb+R|fjzJB0V&cCfwYZu!dt;6cTuG##!C1E#mM=EetR zqGfAg%npm+ag)=QN)x_@hoKSqrB=B~i^<-B9ZEx`=vxqt4U)*OC&1y9YgR*!`2K7g`lK=3z-(GJ2!hIJN#ADEOzO$8% z*zS^3@yH{Q&o3%hI-er{ke+rQzFHg2GktX1Fxw(K;vb|ly{ZNtK)WsPbHk#YaD8~6 zgmm~^q~`rW{HvD2?3oqGcXOB_&7Ui-oK=%eku%8x8Q{y`uDtt6&1R42g#Iza!O|>M z0is}R<}MMs*Do4#`HeP3Fbdpp-+@{{%ra@%?O%?9Y>P^#=B^&RYxa2N5kMwAu! z#;8xc6f43o<0^7n=|7W1DQ#fNL|OkvZTUigAbZ;LM4) z{74+DB$5(Vx;f%lI@kC*27a*_<$*#v^>wEfJ zDpY4)(dlrN5y-RhoC85`G^rYAjHf5!;NoU zp)vEl-tIq>eKl&>DULs$ zCQ20*N6mH!mvE29W@#_k?&biZ$J)v1m$L5V8pzZXef=8jYmzb-c1tniZD)?I3cx>H zMSpm+-pv-_%d^i+L=k_iMQPJ+x0cbPEAL*=qRhU-9Q7b)QeDCz99KO{04o}Dfx>QWvR2ab?W9@nm>; z@~1o@-mLEoLHP>tg+KMcjnUQ7@{QUH^-)pXIaDrB2<%ZFz5-IpXp1r=b)=HJxZO48 z;)rE{TLIE1qSD6>Go>G;W13}djy*zoV5EJZxMVU}z;iCm=lWGMevtX^+qL+s@#wha z4L+6_iVram->m1Z-OFQ&_Fp!rMeYtm`b_d1Y!Q3cP zPf`jgRn7q#aacLUhe647R7;n`@$UzkH8W;7jF`9&Je>QxZO`78MR~-T_dk1EJN%A? z*1xWo?4AB$xU28Z>>PiQowZhb=f+^7`g@G0^XkZj#|clMhfPKYtA0eE9I3eSQChm& zv%EUPIRzy&J5TNDjEY+cE%YM{ZxxZDTqW(PNBRybKJ-6F)zC_=8v^dH~PbF!O%lGlZ^4MGiDjY+f% zQ73R~Q983>`uBWq+;NmaHCKY-zA;LTKqY(~fm#YjM~54d{S@M|63QiM#d`Huo?${z z=~ukZ-M?0bkB(EHU!OF|rTOUviO#U@Z8e|ew{TW0Y>h6IY4j#)KIN~L4>)T-(fk)( z{qG&}Y)A1#@iz2@9cI7pGWAzj;MdPsDvMc4{~Mh2$@c@*I-}4Rszs%8(z*G|div|V zdcs$C%}xb6BQ5U0&7q7-DjABRSzWECD(o_Azskk=;hWe%XeQh{Ts)1Yl5PYy9Kked zq}Xpw?W_@$Ae;~Kk+J8-@&fh`4Zn5^5o(DipjvUWh76oKP`h&WJB=05!w%eWnUpMv z(4|I^UELV)DpI31sXKX0(VwmEQ7>6vw%Yf_DmY4jq{Md_GV=+GcoVsN|bfV?no zJ@na?(1NuVDb;y)FluacKGA)?{LbR$)zt~KDh_Z!B~M{O;HmU&gGr0hQoR-Tix&l5 z)#9WL%Qz*aA-O=85WnS(f{_N-vFinNmQ$@L0h)EV_H9-{Ev68>wN}+Y)3&A+K#HKZ z7;@fV?l7+qTU1I?&LA@rj~t!wI_Dd)TVbmLD~6sPtc0gQA5cmE z4i=ag)%zA!RBqfUmANg(H`uSPb#`s^Y}c}A-hds|XszWE@2z|;4w(q`)}S#S?p%}Y zqDBH*Gq&{jCJYOtN-f=0}QrWR~N!i@NacN`!ZFg$#3@P80!dmZ^r{_9~(geT-_<1_?Ez zECefg#?Wsng#>IASv~=_yqJ8&-c-0xPT@3g&{AOSX4MAcjXPZ&OrMrbP5lw@$_@9d ztKgH!#XCvsy^zoy6N&2AGu;<8gSvZqT4$xwS9mE)`vu~)4iC0{Juv-E* zqcHNcN#i1D$?mnFWo;}L$Q74ZN;`xO_kBXa2*?!|bDXpKNLZJU5 zP?ins%VC!JzT(`)?Au_B$>3~^R+3ei3-7p26V&B92;Fu1?TNuQN8^oqhw0%E3jd_e zFPTN3qoIN=#4~o=6gBd`{acQ7dGW}>y1nYCi(zI775t2VK4xLXKJ#W;u+5d-L{9d)OxW{*I=9tE=DoA zvzvVx@b}ILCxaKo;<|&^2+N_DMw1`1x{4dus8JO=zpF@+pFCV*7!Ap`QtOCuOkT+K zlA*-Z2l~{7H3ivZ4nFHB0*KnKsb*=VhTa}<0u^ZIJ}UpP)Rqd~G8cn2*q>F#?N@f{ z;1tv0&u%IeWUDoV2PRdzrflL=N`Ubh@VQZLu&oYd0|;b4feQh4iW$8+r42F*mfd}6 zFLjlHjT}LBz}}&3A$}QoHHRIoxl} zgD}jf)XAflW6bdeHBIW3oDN}pVkkb$-;f-pY~IZ#oON?AF_-J5X-|aB^i=fV&`!7~ zDD{lzWwC%E55eL_>(&fpD-u|L`iwuwj(^#&M}|rdt3Hj~hfbZ-zZ=HBW!bc$>Svgt z#P!GMa+sxJZ&4elytTz-H@mB^fzx-#dt#G!Z}9Q1^25Jc1AoQ(%6a<3<*x3Jg?XQQ zssHxnH&wPcsb?lU#+_1npTE<>$Q2{K6&rF+vJ^3HBr}Fv+GdlS3RZGEP^Ej{!u$61 zFqo30QPb&+<2hdEhIbPxole!F^mXY;Uz7IwC$CJq!NV_r*TIF3$4i|mM{dX2jRmj* z`iqjKm=|OT8^K_`6F2E%CYt~_SkS&e(>?#Tw&^?q-ILawQxJ7n)=EyIcu9n ziayVaTviH{PS$0O=Sucrj#1*=8Fanb%(nE_ph zh}p1}h~W`L!jE~7-5q_Wch5H8wjq4{w!cnK^8HZ2hFKlSDB_EfWXdKsMGhZQ!daxB z^5>@e{9t49JdNzC)m2jx<5V~5Bss2UycxPI@0{cAR==wOY9Rx{3ZAOOH3KU9%j`6+ z%gC!CG^#@$q!y=Gz8G&fouQr=FK>LQVr2O$shioH!)#>)5VsG_Or)CgDsq1uzY*F% ztR6zGg)9}(42pny7U|Eg7+21hz*sn`%Nkyvx(q@jc2MDpOa9*5kTf(|ug zDjOvR&|u;t%NM?&%mnM|+Nbgz>#&B)Wn|ZgGx)ccw%Q5@Zz;_P=&YWHFJ&Qi*Oa8| z$&Y83fmvNS6S6sG#g6Qiwm|YktVd5{5H8VHPETJ7Ob1ID2y2H;9J_veJCNv>(_!xC zq;%7W1n7^rp;)Mn(TNrg)&S*280Btfjf`x|6<5(XqzJ980Dr$WGldy8zWXe)0MRTO zEYq|I_wl12?xD3P-rufz|M-Os+p!VGD@@WcV68gMw8VS!PBPkP3}QCY!iTHyIaHpq zU(ho=xs#=UD|``d-M?8#u&jciv?M1}Qarz#MZB5ree->t*O$85R6!ISyYXFkU7@Pv z*;a$Fwt6W*u37B-Hgk?;Z+eouOPE`a!xPWv>BI`~gzWizj6(fv58X%skcvWt=bfxm zLB{7Hx_|8Q=&$H6PAUeDBi4dM_<}x9de{YK%V~6P6pq3lzeYV}`W=HCXd)G*&R@i$(wD|p>Rq>V7HfdjI4UIq>I)_IG+IIwjvi3PcI`^#?`zy zjl4DkM~f04IX`Oec@Q#D?HbG@a15J69D948H#w@Sd5|BsX^m<;&HQPlIXFP54jd9N zi(+k@jFIZY#5ZirL8;HXy)RAy#dD?+W%=x1ZH&(Z0AjRo4{&t7T|z$kBhg!`BVIoC zSSuOEM5|P`EWK2zYM09n3GTWTA2_b_iimF47~ zAPj1zWCLX53BQdW1()txFT-6Ed@W`2nHJe^f3YcPJE|>-8o2b^hrcc(_{;5>S{n6e zRfN?)QO>>EUE?sK=q~5$f8S@Z>XsObt3STxbMlYh`m`@-4)cCft7c-?=BM&WVp*y@%%O_;(goBX*8Koq=8%pBOs3u1(P! z$?i8LHKoND@!6aAinkkRN&d2)dpwOP@*cKG>i9RmJ+1lgrdnvIyu`pYi{D|-qc_D{ z*}h}w_XFNOlR?EP1&UYQ^<33H1*k`_T-5B@{*S@4;-yHb2VZ*YI&k8jt9o4eL!54p z{Z*si!U&+dSZ`}o(gGTOLo%T8FAtG^0mZ+0_?hdwcmUFBuhB2q z`j>k&q1WP*4ZZ??edX5UYcVmu9(U7)ZJVvrADXPqe$QUN|K^he;ulIkeX-}ar~cR0 z@~a%*vfj4&bS}S&miaf1a{rwle=y1P|FKZ#SE7CHLVnT82R_E9hrL1B{hbYosUo~y zbKueFuiEg}-G0I(f4;`~%dh0G5_Yy)|5kN>?tAW;eI=F?GZo+ae}}e@CBKYQ0Vpr) z|1Bqr)HhT6{+C%kmEZqmmQN}2PYL;7X89xK@&AiirtpA8hmu|HQ^DjMkCZ%#)}ry1 z8$p?}S_Qmm%nKf+_r7gp5cD*D^0@A~{*?I_lcksXSd61)Ma$0Q!<52My*&s~>Ff9+ z3M`}k1HT}kdcuufwS2RA|2AvcaoPU6(-R0462y&hbR$@AH3k}%X%53mQX0b0U%up0 z#ZHImNt^yA2iYZ~65I#aN4Uy9_tw*R?OharTy66Y@($$0dV+O_=MH&{E*{gMW{U}b z>fUw~7VEL7x8C#mF{wUp=rRD5GdtY(^cXoYu38sA{T3kXV-1(v=eo>Xb2S&n-sG>< zSEIu*#tiAzR`2C2aXn$Qp?fO(a!yz+RtXui)p58mTcAD`Qq1mJ?72@=IR9V*n}b#5 zrfB0h0b@cgO?;)g8oY&UG?&Sm5oA!JATIc-ms&qQZo&l>@Gs^?`vwf!EucBTs?;RUx z++j06HR^a7Y96Fy*5FpqN>)3l%*8Y*M;gWkDP4~Y8aY0OmW8k8)Ki7*%{Z>-%;I$r zfg22lS}q~t9ZjKhWv%bo{UwhUmYb0)of z=uo#@0y^Fqu?Qi;U#Y{_!i!&zea@g>y?tUdM7>9~|68;S6yte91$J^L@X$TeiLpXt zPK(A>i2gShr$YBHyt_P}HVtMJFA2A%5=J8Nh8ydV7*m8jb ziKtAd5wZ5zGI;ZLwvmS1E13nyH;HmXsVJk_e66>+o(lW81^=3-WF?B2*HWBMn9a?%s3 zKf`4b`EDike|iCIQxYS2>znI;D})BT{R?ET-sRPlvE6JRBSqFG1{RlTZk=KZm>iIy z%y6=7V+GQ*LST!^BdzHCM=|k{CX$qt*Kci8yne8LUV2Irs88}T;D*nNKmBRqQF{7J;KT81AXC^<1lOH-ix^KEhiervcdm&zcIO7Db5oOiG7}q ziUCdL)474EHH|gOcxA{wb7*;_d%qjD?^1}n2q`R4iQnrzXAjuCN{@Omdq_EM(>5T; zX<6#7k)S(bP~6XcnOvt>z=$>E=PgMMp2@NUU?zym4`uJiYn}IRyWx%{3}YiFjBF!& zk8tdj42^)msRT+EjouwY?_&(G4vQP*jD;_NnT_C&QYXEl=4N>-{IQ|7ayWV$D^<~ayGQJ;BEPw-u+ ztOOsCv>}jKX-RbmecH%1%%%5MHNzwH6J7SWn(qlU$R{Rh1QFIqXv*`)mO}T*VK_J)VM(oMv*KA$pUEHj#gRp6U{sMwr1CtzaOF@ym< z>$WD3AMB!EnhZaRO(gqCGSR!%Ce_B@-vxKwz1nwx&>m{~d zh)kupT(P3Wk2W5po%;GJcqOVVnn89fVeI-t$n(dB%PnJZuqZ#(spIh<|NpPq6Zekq z1Okd&&K!8`y=B%keIzDzU&p&6YFGvQh-7#f< zW)^;;jxP-AWTA_WQ- z6mu3|F9LK6?clp>F}jlISixwy6X5vZOZiLWs1q3ZrG!t zbaDa>ABNaG=WKv4SThL$eeIX4ZYYHq@#-t8MHjn!Z8@u6{}@Sj5@|Nr$l~X!j&hG! zcR7!6Ci1=K)ne@<&XO*Xx2ASL?|U>OTB5>?HuH)hx5XW4N61^>QnEDiXBOIV>(iDm zTSR#y%!PU=nq-tof`z2@tbwq|HE~y^L(1|aHCp(|lo~;T4so5nWEr*ToAwnKDbGyx zEosq&FVj?GjT&4NDcWi8!$HeTgLFZ7`C>9XLU(@84L2@qML&k#YlsPRRoa4p4)wJk zH%XyG^*BM|K1V}CSwb2Xp{9*>Rix8n&M)oZf(4-1rRL$-XJMg=6KN9wVLUgbgVoW^ zZZWAlLqmhc8&gdXv{IqqXPO^3W`sOhZRzEL(W!(%y7_&=I6+`G#pPYeVR{> zF$gtQ)1~r@xd_Y0s$}eQ+$^Y@AB1Pau6Ao1NUg>O(qqp`xtk!Em9pZxKxh6iy&6kj z>Qb%l)!iRoz2>IFEI1 zBS*=jwOS1#95P96eC*}s1rsVetQZTMd6sH|r*;)VCpd?gjc;XnZE>rdXd93NW=eCt zDrzHBg8~y`fVle|Y~eg28iXQ%flxLjdf%SqcicBDRvWVMu*pS&2#^68O^Q2u1bg&> z4iy%JO9OtR%gtoc{h1TG?AX|lC+C^;4?*FIW3uW8vx8`7V*&N^dQqbg(?N{583XiL z$voF#}_tFG^QQVmu7P57|vZMdJcQeA* z&^qWemddOfUE|>5)`LnM>*GJenm?Di4fWXErd^(fwubB!!Zw1Et3FxnO(QCP?phSHR?F6kng5> zrJzn!t7!RRW)PtXnUHNQ($UG@nxA{YakX)I#sT6&8>@zPC6mYF%mBCvQ!>3ReN-8pl;P`UhRBl@jEYkzI7jt1xo}Y zoOB~Qa0~B2mzyCMGOAk|4Q0pb6A;(*!=ktDBTM5_57E?h)ZdxkC)wVgSh8+DCEs=} z&~mX%6^cfojRo0}14eAaeHZQ)3?_N`8#4Lk5LBwdwX()*)qz1h{N-twR&(%rZ}h9x zx_MzDmhfR#B90S9c!t)+pH8UifO(E28_cYuQ;+IiMQF1C2qIaCv7B_P^MW-rHr(xV z^gALaZk9hB1~P{DA;q0VV%FL%KvJC8z;0Tk2TTd&@L+`(8grhRKpCFm2Ym2f3Torm z&hQ*9a2%qIvK_XfR@UdSx1W{9tXMOPEKrrFvB*bDBIXqqSS;}PKs?nVZ8@*3>INV> z0K?24GQ9qX6b0pEt_)un#!AcdCX}nCgGd8C;v?B~yDP|mm`f9P&odE46C=#m>{uiP zpSQ?-!*b$#$i&36p*3DGOk>GpEYzr_g>zZJXBd#Uk@>0kLRUVqkcF*NeF*%g>%bMR%-wRK6 zEsk1FmC68)Ijn>gM)K&A*q&{e?5hZ;ykm|-e&Hj{HA)sW#rKEE__ zSTvLZ=taGj!!1#^U+UaYJTj5r6$RO}Rsz-^iqA99HI*dO@<%^3FZ(QQ_~z@J`m)Bq z96&|CRFybq7_O2cQ#vP1Ay|GPVC=?eO=r@Rz^@j}1HAq*`cBBLrGgvHM;wTi0MbaV z_M%pks!dre0?#Q?uZ&VvC2mq27Tp0lG6n?Q>RNroQcm?crzowf>$;zBhGN+oTii_D zCVEj=D?^%0%g5}DzObrhP%(Y`Yh|`)u3`H5y&g)qmS@gp2Y^4`;hi8*mrX(5xXGk1<=%~z z)GTu>b;|fRU2`GxxgGE?a)a*o&#!waE$vCA3aZ<{7xu~-KBo9+E61tH`OUuN0S#{` zZlSsvH2Vhj_VJrvb6pQ8MiuY09)+w7_uV!i1qtzw?J0)3Qgmmne2(RE8)nj@ws>Pa zU|v5atZ9A1NwFNI5^HTO>r_pU-*lJ3H%?rxXxM=!78`miwLD&>n@g++4BR)>eWAKY zszmK$d+uzq%^{e}86HB~I1?Kt2Xq$^@;z$)l%zq!9__xsbUf7|g85v@j)MsGve|_OC!gf?X`@pd;?uG5YL*FpVulEwo zt8ka`D}!z$H|?%@MMZ>995KLrD6nv$54Pu6ZoJ$9aNwAsmF0+vY6{P+(b8k$^l!^Jp^sGu$+AhxAi}U=5|B+{>4H+}SisLa9pf`tMKKxt zvNl&GfV=!!WkKKsWCrPrgG;wDN)~4#A@K%aVe9*UHvn> zirUlNFBgHe!bfYa>N#R3pjqwP4AYgRm!oqvrx%)0M{~H)UY1>lz@>C9Y;Mpk)jYW; zxvVt0vv-E)W(c8CNB@hd$1LTO636h|D<~4EppOw9sWTep#iX;3vwi|J-qpy_m`A}e zqGD;Q`$#Rj7FEV-IeRF;Ox9ZX%?vr#ou@wGSLVopC<6{ix8`LlR zY802mjYK)q(>We6PdBBjk-c?qPb)N?Gx&v7-I+5~FK~!!lqDBd{b7Z6J`EU=g`Zy9 z_nsGNQV@d{u;fLopPEm&d`=|g!j+4Kp7&2^U;0=6`|D4D(f4*`+d)_*g}CjfK9*Vf zml~AJTi$YM6~JsMDR$xRmvD@)uQL8C2n)y zh;9xX4;x#nZ!ELPkjv2s|s8qZME=*a1gfIk23d8n_aU-U$q zLPnLfqlS}vNrxJ|Cp?CVf6=(?1plZH)Cnel%`DsnrD1`$RuX!haFIp1dE<8l6>K;2 z!Hcgp+y-QPs$8vTM}5N>L(ccT!~00i#y2ZB=fc@42oV`Tq{eBVkIWU$F9@PB+_4L_ zFXi0B1C*3>9d>w-(;zFahimVQCbjrVv%rSPGMh;OwVKDswX!v?@d~ZSLt$PsK&!GG zf){TRKs-Pk2`fhHnh6U6CT!iCkf09ck^sCdBD3!jIl$Dg&;i-K>=Wm4qubGQ81D=OfsF$WSoOJ;v=}P(tVFxY_ zoPWEJ=V2aapO3V-Rsjx+IFx$?{KkQlTXXhIir1SDDSXYYz>k%hr$Yj8L8d<~o!ckS zYe;p_^j!%hqJ4Z^56Vr@@R~ZRv$!2I-Sd3SYcJwXR0eTd!ig?gBE!gNaqDi*Pa!J{ zedVP5omT^nU%UyZ;pbJy5&MA3ehuJ%42^OMzw5o;35wC=ta=BN+WU&j$?0E4WlbwE z+pAd!87DNb(hipxVpW$(c3Ei)9g*7zIZ!Zko}{X(yk4sLH4BIHXagJH6!cLd^xc(S zsde)T1TPC7XzCx5CK{%3XZfmfkLb+kA}xIBYoC!mM4FcJRri>Pk+8`|TuI)myA6=l zIUkQlmGIqwzVRNz&Q$TW`vDlhrnXK@MGWXQvI~Z{>tkQj%0r6siy|D|Oqy?`%BdEv zy3maKZsT$6hL`p$ED-qdO%ph4!z(R%*l2AB3K13vT7gFQk%?g@D{TTM2<(L$wxPRr<+2oVXYto#r>1&|C_x$n(Z0VRbF?CwE2yZYewujJTP~S_nqgp~=;iR-o zcfU(336~Sm9cs8H#lL)toVrzO3=%brn_FlH;-Jeg3^znOz+V7gaS6_rK&oIBSvMdW6R3 z@G11ARj^)8=xYxYR^N5{!t<1QSW`MTkJ{7F1@;5c5 zrz(L^K}rF2yp!YokD=EFnjUw2)I8GmbDb{1e;gVwpp~F+l;2liQoj;MS4P~FEmn$D zkK#mLij`vn-+PM+RKuPw%Wi&ae_X%baI6A_UFpf^1*g4mE*jfwfzVSQkLqh3D68>!K#P55nT;=hM$skpG?O*j#krlI)lzx1{_m^RD#5riJJP_nWWmb z4as}<0Avbf#J&GxxLh;iLF~Eu=TUYhm4ak<^F3h(mCkNW8PaV8Dc$z~7w-zFNqECt z*d5|N&5;253gWQ~-6LQ*c#^u6663V>ecc7-*x`;CT|+Ba)(pVtW3Vx41II`>(n#+S zDl^{Zraba&NEF5ft_mFaCtenKHBV#`kp_%+WQDham=I6et2Ns|)!35E!IDhV&`5G4 z8>%;%j`hHNaK@C@`sY(K4**XZe3g=53SHBtJaTOgs(&0P^>1K`^enA0$}P`=gM)qZ5ePDJR|S>X=7 zPP=V%*n;NAc*oOF%Nfkv+bzo*=XpXf5D?kmn8Xfufo~?gV_&Xs%^JCwDh3E3-#E7< z*&ea`(DX#$NcVV_HuflY-jG|-%Ws;b=;{BA)!6HFFxYBMUZAKSB=B^6B|zNRYn&v0fTv44)Zv z+=~1fy~y*mQ(9W(40wrpLVG+GTh{I&aS29{@|2pQbc-BOsfMJ5csA@zfA&de&GPdK z%b&;d5-jo>=hN!TP{|s-Ow4i0D@3?4a2xkfH_E@*rGdO4KS{?9`aUy9}%)-@!sYVpRBY-7DUHp+IpeSUG>1iDOM%0x+(^ zQ2dAjQ;Cr99r6_;%wDU-bE_5M0{iKzxh0U9LdgSm6gSl~4*L=}md|!>RHukds}D3qg>l0DJ`O(cSazkCVp|}SDL|Xn%DJtMOTc0 zu8Mo*7gR_2F2>#@l-uDoR~$Qb4AiFaAoU27e3A#9i7{^GjaCfpz#{X?4n*===PEgK zg7vcJpogfO2JMa5vVy*mMpu%d)M2>|)>~WSYE`5;w$-GvU$!x#L)fqab!NBDd8YY~ zw`w8#WwnXKPN>&+>=AFRwS{QjgdOd@=prUH3DY^|GnogY4gK@QAXrhS6$HIF+b8Fjq$e{I8NeLruoRI zoargHG8-04_y{2`mRy*E@nuEkbsvn{0C=|!W(UM~s4q_gdkiPxZgL!ajRm{ayIaFN zKYXuzKdQuM)chZ_yc{S2l*w^9!Tw}{n~Q| zXwD?OsIOJXXcunsFIC6fRmq^dZ1%T;5BEp1bM-JB8vN(l3-^zdtk%5{7x=+8?8E`? zNRdzlVv^Q%VK&S1u}`4e5k9QZ`^^oAt5y4rFr}+&jB&ZOQ3zceH8?jGW0+TVLEHNc z7zR-?4sgy%xD)Z!)YMN!eFt%6hjjm+-d+V;;jLIbWbQhKsvL?2| zf2j3nYWvQ)^0`7rm)rz=XY?A1m}EXIxNbl3A)ofWA4q?>bZ*1PE!%nwR!eRecMHJ8 zO!Tt^)mKwsxLZm`jaa^pKE7S=5MV#K1X%-vI5|oqGxj82SH!O_AMVQqvsYB)qZ!pI zu81=z8_+$lh`33rwCeiXgytH89^uVa{Iv} zMjcI2E3rO+m~<`PWcseC*#^r8OR$>Gr@?OH7)=+xpoDGAUyA`H(&Htxsu=|=phV)M zv8L#~%fL)7U5n@$x{!k7v_q}b0Fw;d5RSu7rK}msxt7EY++B`U+RHfhZX=ZmZxhP9 zBH4HSaRb@bLG`v|>0hElI=#E|axVW=S>ClKSik7bRdzSo&xc|2h%AP)#tVIc`;!RA zlE$!MBVC&RZNVJ7s!bGWl1BXLDim4SO%0)5H)gJ==j!){3Je=nDyc{Yfod7Yno=WU z)dK37Wb--0>WWvw1qOg952X4*u zB%_gUej8>3GTTf(TuE7CrW2wu0WBq}OM@6?4=PT652w7r;H?IG9%5q@KhZ4rppy*+ ziMX>rL6KH8JH>;LAeeglQLe}*vvo%zb*YT<=ADG^*aa+d$*sXd0ZNrukBy%g%D^T* zA_b!Riy1*yCEBvBGs7uwd2N6TxwN{nFpp(2CsxR~TZ4^`^LE~-oXB27$!?-wV4+uS zc(HH}gqX=DgyHIFDr1$xz0ifU;Sh6gzs%ZbDMD10SeDxiy?q*^L00ZTBC<0f_;WIs z&&i8}IQ#CO+wu4Oxy@fi&)nZD(YinmiJ0c>KFIm zU&*9gjR6rXpS(W#E&KV&(>_XSJtg`jJ9OHE853C+0jZeGE_b-DKGMwhY}m=*Ga1!7 z%e;z(SpKONf<~@vWujSy!ao;!&h;M29j0d8yf)h48z-Dl6 z?%rQ>k;R#CuST|Q4$h8*%lx|x{r?Dp=IdW&v7^Fwh;xnZC7wKY1f3MkW~e|MqKd{j zSDZ2vXV|N$cGV%b*6%R`fQD)-a#$#MfyPnTWvA4Fp~2{Wi4Ot|0VPN ze@g2AmOBEfDmDct-KDlFT%5YSt1jI5pc`Y;Q_0MjO@BSifce{G&Sn*>xa#W{0kHyv zO6#a*nx?qa_C;O%>lQWVEpY1}Na5e5{5O}dEvMQq?p_eKHkk7q3#Kb#edA=HQ^op+ z)j15^$%k^}rqdGkdui>j1l1x`Oj%*Ha0H=JnLtc6S!pYA3QRK6$l*J2I~xZzxD*6W zhkQF<`4QCV5!9xqEdNSTw`AYcD*?o`89liLjv5=ZF-;b*y}q>4y@mUWBskY7&Y+?W zftddftn+`vKChs^im&KT#rJm@;q2vq3Se;rt)fxAeX;khb&w%ib15*I_drG0P~@L! zRDa+n?Szc1Jw$V~cZq${#8KgFa!FC@$^A7e144=0t(KYjfnW5C`yZ0tjLRS!XN`%p z^SZfFf9k(ffA&hXvh83mIka2tXpMBhZ^ii5>t70ww#Ow{{rrD7_4$9C1>RFV${6TL z`t+;8h%KgDrs^!x!Mdc?_C{~yhDD~TZeT*_RAR(Im2URD4|GO3i1H5As*E4~q8F;~ z|MsuCA?|fsik)ZR$k$dmpZ@A+i11lOF`C-7=$rd#0?_;G_jH9D6#t+#J6lfAg&VA5 zi9(@J;4M#(wy8||S~@XM$(Otzq-z*AuZWl2%Ehr-V{61YA7~>y-SmsOJ)&>MVrcvf ziK-BAWZg#TcpTLxF_Hr|Ae!(y?oi{oWbIP)Rj`MDWpuNQlai%y4mA!sJqnvDexbv% zRSZSt>%T6yYhqLyvDz=nU`42Wr}GsFk=;SsR42Eq53eGiBz#Or=ONw^ zg)JSg_@wUX&*b5i=@GH2OM4yhIeDS~k}`e4TI@NWJzM`Tr8&p$S$^Ozjsc!ZI}UpB z3TT)84sM{jpWy|3znXQtVrQ!+tNMnrbInSq(stpqE8*n<#VeJf_+txr-;c9%b681} ziUM;&Ep@~)e=}K=RdXY$Hg|K~EPp+mzDS7#2v1tnSXPxI+)ooUc0`JTOys?d$1;p< zj#{LX4zr^g9+cb&Fj3~L=7hHGTlL%`o*O^(w`zx-q9Sq*OJ$56KyQ=7>tA+YOD(@g~+* zgW7qLU5JcI;+VKE+%ocuM;n8eyR(`PDqh=>xbLq)i1~|RhL?Fl`<$rrzlg$}Byp8^ zr=IUmp9sy(S6fH|Gx#6`kzvSsd*>F}6@F}eAoE3gp&(C_$0{9E^}ux=)ts*MKAB$q z;xRqCR41fbPv5CSI!+K8iPq0JRx~SjS zT=yRAyprjE?D>P=-Q>Ud!0+_+AA<)mT2VV;yK*~`mih@Ho94Dn3VoC|90FhFjO)HV zU9fIpA6<6kyYZ&b2MG_4@7Al&kd8Ir6i{CjH^2z64~r#1-dn{}@W^Rk*jBFh?P*RU z!LTaI(9X|Bj_j)8-KyGXQvrb5q>bxAsoTf#?Y$a@C1FsIQW|1mvCBBFNdw;)c=IrL z;$qk05KbF=fC_T57)BoI-n5z?nRb4aZ-Z7xS-k%xQkeLe%nva=};8~pbBD zmw(Y?e~k+NC4TebXyKg9Yg+avtnyg2MKU3_^>)=(h_N)K?#my8+V-zCU?VPNNfx{q~^EtIzjQ>-TkKm5$iq!*E+5`Xh$N}#JSmHQ0Frm zME%pN<;l9jDQ)3xwkrHBdJt^IZvngkB!5DWCUJ7hVuHnFt-ho{XEGwr zdV{Cmm9D&FW?di+N?CazMnuk5Puk`Q!;`^p-E0HN>1)_^e~wn#zI8L1xF|}ec%!4x zhSBTG2;polIYnRBUYy}qeei71#)l=DvCdlM5DaTo9Js7rvCrgVGfNznlmd^aLnv!^ z%U-z8hi7|(v<~9CNfp;2GC1e8dxBLX8Jh$tPRbfrn} zM1~QNsz?i6kfQY72}*}Rq<11EbO*w{y!dn6fi7}0tzY4_tDptiUk0JU3ojO9W^XXkSbvf)%Y%bCt%UZ^b$Q=nk z5dhc+_K8+yjkq#C)TZ48kMQ(5TqoVg7&FzN8Yba+Dxy^otVbtqopF{iCKFQ;dEn)1 zi^P%#KdV}EF>6fU;Jl)|%1@m-d58ddTyXE_So$E7)F-0jI-{t)F5P~h=6es2HLx`s z^lfJN>sBM_)xpHg&py;-yz*%;Ad=4~RO7}1G4C^T0x$tQL@N}uYVTS0lWL!f`wapg zkGd^npR@(;ZU5YLM&$aL$toZoQp<584|2KB-%?CC$Musa&g3T)76BBwiSeP35%(TzqifYZ{dJV#y+>JdNCP za;14Y>ME>2Me5RjUQ~Xulg^?UJ_c>V>U;VPdK$#aPlzXRDQn|t_edX$8+ z0e1$4T~bP}n)nfV;lTKAccSCUXK<()%JzH0$TQK1?U)?fdtGP`4nF_(BXLriY*Ylk ze0$8H`%XS-5aG4)+eW7Co(KP}8Ea8jRxDr}7T4Dch$Ayn!Y?M+$m48=?&juPt*J^; z@_2r711$PJV$Xp=5q-cm&7H6L3c$aeRZ-ypoR#M77`K};?8NA&HHJdeAE?~+{S1DAC2XBz*+ZMZ5V9|SdP)z>+3bVu-i)o5)MR}J^ zg}$=be{#e72;W^YMcj{yB>+0+fo(tO(U`V7tStn(7>Y9SI(}m|>B|`c-*~%T0upKl z`cys__x#THd+iHa&g4Oa$23UIYojo+`pl^L>%DUP?>~J$c*0}ZJ~1$oGR{W6*s7kc zB3EwSnS8P*#dOyMKi~Ta@K?F@d5!kX2JM97zhCfgx!In?WgtL`tADgx!jGTP@;?aM zY~VN4(bRYBy&0Dvy1(|~WAaW*ON(AWK*(6GONs_UQDe7u&h)9qHvj&Asf(nG2hr6y zgCcA!3?F;?vFcxSxwhw6fg(IEi;*i~gvxTpX9hc`Df7@^`>a<~R729Y&~3kGfc!l$ z%9m;C+Dp85FDq`_j+(bKk5=}FYny%&k>cJ;q0HFfu0eK*=_X~cl3>oeAogf2ipr4o z_AkF_)wDkvHZ(%W@L$`EObRJ7eW5e`v#3c-UtE!WeFxW#7^9dZL`s>4p?Xb{pzo!a z01H;zdnMehVegV&$2JNrsAWwx*d6RK771;tK@!GdJ<*N$djipB6p{i++}3sTO^-ZD}K)$lbjEGs1-Of2jAQ+B>OS@>uPQBzyWah$f4P^ zZ_KuRT^G11)G}OhZ|daQ7b;(W`!17F%X(%-?tf(2i;4d;viPodT$A6c@sFS3(%?P* zdv!=$zhn?zRRJbEqtZrhpUe)xgheffx=fc}PfXPg0#~&N&&Zeeh%>FX*&4y^ zaF374$B|?hI3*o#JGjh|K^!3qhBy^rq>J+n$t84QlXNMRKb~RH(fEc|@l>imF6u*J zEXOwh;U5_5i3X%t&`I{{-#Nkdh2fa30!E21?fN1&`RS53UKPf;)OLcsvInmkoNnUV zENmam=ZrLB5sSZA;CQs@5YA01azqn)U32uhcq1gK`BWsOs_B`s^0&%cHTQ)SW1A=E zzw648Sa?#)+ssf2PX~t-C4@7O#BO2Igc!> z2t~6`KQA5|LW@x5G9dQLtcv3<1COp#-lg_tyLlNU+_9+cd~k9jVC&vQ%e@7CS<^I+ zt@d&?(d=g1WvQiFu2M^gQ#kbq&m=J&8DuxSB+a&NMNnAR^=rkquCwohwR2(zg-4#s zT5fDRyzC(?;w4J4$SPNR;9hQA4Z~`3Am98wNboLu`>ZzcuyObr^Dc$;bzQi>{yn4t zsQm-(3s>Xz{xi?rJMvTzG}E?42`ZX@iNnP7yXz28=j>Tj!)E{AoDY6Ch+f4a@G;%9sIES_}%?-^1O9C4T^No4zu40OPCuy0jsA z_uxNxf4FcB-CS+RgcTct6Ae11%2t=7ZGU+@p$^hY{t+fH4@Uo9qtGTN&_NGw?B622spoy4{2wIpN%KF)&BQBN@?PY+1&6EBy=~Kqup`MFI`9uq#Uf)oZW2#eu zjRo}}6N5a^7{W6ABsNyqCd96Ml(Ge;@U%KQI?|Z6$Mn9hKDe70vq9UsO0COxFFN)W z->;xC<2Il!EHEWnXLk>N;o7;w)6%10D5I{0m1T2K0QFhu>eH4rDm!MCSk^%>Opr#i<-I;z9>+#Wi`v6X2yMxK1o@!q6|+1b>gjM5&&TW#;@oaprMe!Eu^N--fq zKvF})Ip1Uck)LCM0-4=Obx=$cYPwe~{A(&nmk&1vw?PzKFfE)$l1&5yg& z1(lp5C*zzeAu4cV8bAQ0$ws z%KzfTqm0dQ+O!VVDciMKev%u`}eYp z1$cL5N*eXwp7joJ-=*DVS-n-ps9cs-ezFsTnaM7QeVRE)SSkf4A|CxV#&AxU1V6Xd zW9S4}M0*aE%*YqElcTnzqCHvFvGU>i7OkoTjjhfc8<+3tHcbtt^XHQdF1I{1mvR9YLO-6^xxk7`fL$#e zaQN1uft~;TQ|UeV1>n6-*~vo>PqW3?P5q#idTCc{9~qmI61X<-+Q!Sq1!`|wsG8j} z5q`#X>Q#C}mS434q#o21!H|DlWtmK{#MQo2N+u$D1ymy|*VUPwwOlVkxiQPWdT1yw zQ*%U?&Y9I_OASXyKNgMF8=`2u`Rk@+^XZJC?jw64^9LxBG7qAHUZLP&sGu;^R!)fU zz_7cjeID`=VMpOrQtlDJ9#}k@+#5#iN9#XE-{pXKUIwU{*!d+O^URKJvG#3@%+BQ{oT};V?T#o+Ky`@3wO02B)=A+fu&Gf39Med) z=+jp~cSB;mOxL7~n->(81^L^Q3<6vr1|jzU=)C!dg5Lo}86fN;PwbCUoJ#Q(cs30oq2dNjyl>l z1kmNfsPBl{-9>j#|B09F4@sWhGhX<>vZr0QIg61GpY=##nmK$7*$(|aEU??5*-2?n zzH3@!QhHS=?v4v2F&4Uu`aasVrL4!Wqs7AeL1EY9UtjRG<|7_zb}x|+hj*ak8~(RL z41oy)Q(?IDzp3nj<^QO%TMqw8p8qSV_@2g)23hyMA?ciyhYMHLY9kX3Zqylkb z2YL_PO(LQtQ4k8_Gu=GnT{1L#2r!O>A9`Q@#ozzqPcoF_&0K@h9j5Qt^Cm+fK|CkA1?G|=ObTnC{Vrg9NxXHuxJ3- zuTetTe^WR5=No(Sw$lI}_P!sxyhsZSMzLtO{tSOV<}C&q92tZhXZaBaE5&WXC@>0( zto2Y4_e3E7G**zjQs?e?1!0wIM}_|&Q7TKOIrs7h()tM1ugrnljlR8O=rZ7374U5ws6=l}H6(OiIOKDaTem+{q%3&g@l5Fwd93+SO=l2ER#Gnu&l#quRjbq+Uc z$wPt~8PW$fRR7b&ciGb242bZC>(iw^>-`sg2>h8-8h_hzqK=LHv>pS) zog&5$9@sVT+IGUd`rYHJyOy#GbGx4ZQ@D42NCI!WikjB1Pdj-#mO=zdT-sC0yDRK# zXgD?FM4WKCHdTT-kgWwu3BjpdlOonpW7qFWvk<$Wn^;9mX-hHen3&N4XK1`{TctOE zPNKot@mmKjeL~G789FynCUGg#aW7oov`so<%Ab&lXEp0@Atg(1Jc^QLqhsP4i&}uK zzV~kmeOHw;BIw=TNzCV|IcsaHJ_B@@nR$e3w1QS+5Dk5klD3wd6bWm_YaJEDD$O+; zU?hE#eT`vK>x_#MqHzJZCcGo}pK;*P#M;@;6kV%%1?erda8A_(W?Kr0B%Q1w^W(nK zZ?NP&VDjyHJ{JRBMh|J7Y&jYtXA1hj8xPKt|GZ-1<%B zeznF{{r)MBAC5a zwV~daZl)^&z8cV?N!v_^#mspXDRgf-8Z{#V5n0Wi6T=~c=NIh$rDM6wA|=S1lZPhF zqzT&fND3K8<9E6ZCdMdgXB>_LER;WCxzgs=zJ5BO<8w}I8|cnQfQh0hwHl_kZ3vkCG$?#V3Kt?gw|ayRTEh^BL(x5fi4XQe-P}N z?KH^B%) zkApt?Nwy}7EBSV&xhJWEG1Q94v*6xnX#G6r230+o(}3=fr%4?rhk?Di7l_243%3b( z#xWt+XS_HX#b=(wiB9cH3Uc_$nT@WGMmPN4T>e~s{)uyy9c*3Awj&rn^Vv5rCkQj~ z7>RI$RNeoL`(FW?`>#nvrFyolPkx3+Vuj6)Vx@`W)M{Si&xxqaR`886*)~DmeNhMO znw?^klIWANn`-vo4#?{}Qxp^cm3(tIn|gw3hp7WnmBlZ@O6`A*eQxz41}qf=Wq}Y9 zTGXU!yp&@jwO{df!3tY@b2M^wg`_Jah{GN>5L3-#=bkPpL4Sr3inZ_*;11NsfP?bc z`t6bL3NK9nW!d%aJW)W^3A%Mus7krE7*5I_yO&MMHuunjivA+Qjwr+sP_s=BT%vSH z*rKli!w>~h>`Oe4vR6bly_>5(ozy_;kAx54eV+F>y=U`!q>$O$#x)oq>%G4pvcIPI zBL+M7E1)u{-d37q7jx#BSY^$eX!$0An>Qj8?9 zo#%9vGkx#z?uNCeY7_5i{!?n+*Ap@?y3OcXxx+7_+c30%mA88Zu{LEL)3`(T_vNNG ziOyvS?>jK8Pbv6$;=Ln<(N^KQ#6;zMXuxJE1PAqRVijUHRI?1(9H0XSl$EVjrzMvO zw%T{JYB_fZCwnx!Fyf$>3!zZFD6wi}awro=%}OE)9wdq$#z{-eOWQ3|=vK3CqXWuj zsG#{+FkcLtl8dE_*N3?}hByY)iMB!mU?bPr558~eZ>NddkHl+t0Y{nj;Jj4P5d(u* zMuymV3{x{hkqVdgS=vylq{%=?z@`sd{7?C)*a0<%3!kJ9-pPhACe__mLacw}p@_w_ zZuY;4K3dK7sYnDeIME#_E^Iywu9($>sg%ASL?B=d^f{tHojjohfz@1YrC9emkNk4- zZ|kX9Iq&}SSOQCwmn8BKWa-n~^(}1%W=30h2YhXFrJ4e2MUtBYX=2H%zWy`H@Kd1> ze2c3ZdCC*2wo1@VQ@~?qrbP&_^tcn4-V9319ee^gSlZProPtS740LJv-4Zt+S*+%@ z=tnufI=;XctVQfDWlxBBakT#sr$%FXd$wcW@y{l=<14Mbp;UITtrp3^S^6938 zW*ZHdNAfAp;-?ILBj?@bm^NiQ+I?~UGKpsXi}N{8Hn1GB#+o*%8-Ldd41f;80v^;}F$6)o`wT~p>bq?FzLdN!i0sgqvG<|-G0h#n+M(iVWbjyzlBY!2)$L6l)kXoHFcg^=K!KN zsk&Hya3JzDi^;@NtNG9_fBu_vnD+tpmCSU*H_~3b{o+=AFKoNw@cHdRRDm(CO<8Dc z2TRF<6RHsPRxbP)my^f22q-tdR(O6L6`B-iF7T#jWhR%T>8GzF+zbz$8CfS~NTshg zNb$6A4Vo1l{pw9o-!v=0bZ+SY!d^o!L{2)ZRXUHf13S*hZS&e8i+p<7vD120n-XrT zZB##rSknHn*|E(!*fvI`jNQ-+DW+2CI>1a~C3r38E)Uq;D&MN95Dm7LRj#!cthaU{ z43CCEa)_ThaSiK6Hq66b;>CZTsSmIHNYpen^~gR)TPeO)J03rTs@#C6z8fv1DJ8zS z?_rZ(QQB>;&{Mq;%fOxk!3)!XH(Q4Mr70~i1-OlDwd0muC}+^>))tVl1)pR}{8p-b zO+05ofMF&C_0{^QUx1ygp6?tPU8M}DU2ZA3IqeqbbTg98eeIoywq`5WV6XB^e#$In z7IKFhG%PB-aTR3Z8nIwaxfjQ0-RkLyQe;H73K`;#NNA3hGBHakF*@=;i9dh~ARY+% zkS|xc6U^T@V?mykCs~#x9E^T7=2&8AwCkln!_8sr5y~qg0XbAXw5efzfswTlZ;7cEr2np69EYC)nkwAPp&gL>jAHZTR}7^~4GPp(p3;(DsG0@i%uO|Pd!td2 zL1Fki3l<%%Wo
      8W`1`$cePmY!uRemX89UvKnsAIjwrn&B@~JroT)CCO$f)0PGi+Oa|jI`Wakt^U%-TWGP1tnah6qk!&0MWp~s)LB3ccDVu(pb zS~NVONoN6HdTp%78_@5CxgSR=y3fk>i+qc>U3%7ERDSMY(>|;;->xlT`iXA$4FB{0 zcF;UY_=v#k$);(d6UE3hT;hfz zuirQ!sQIRP33y{tSyVLJ%dn@PO^0DsU(U3E_@S4=F$}@f`=c3G6KVQ+A=f4_j=Gqw zl~elCIe~nEh^=)0(B60k+wq8UbO{tRX%|W@ptuqJ>4)!F!n4|hpMdO>YD?^Q90&Fd zuN~$z^=+_#888rP7Qm6ldOc@s6<)n#Mm~TThVz$A(bA+>mxhZ902EkdYhO(x5o6Wx z1Etdn9+=;G*vFif2WfIEe!gjoErp!rq!gGtYMep@MfiDffi%d{{Va6r5G~?!|G+*; zw$)NO(+m&Q@F!@1eM_UXJm0m4DaM`GzmN+fo4Q*$FOM+x4wqO3mLa4Fw?^D;klB_9 zi@d&Ut$g;9jW^s18!hyZRc!I~Wdgrfu5- zy@wS;mSYuKpQ1ru8P>@cty;3Si*b>q+ZeCvm` zN+2&qQn9}Iw?$S zYCS$(0_uGie~N1S9-St`dtx)$n0NHF#h2xzJ9zn@bbZCo0M7L%y7nzJ`IfN&vVg<0 zQY#neJ5zNCt`9@h%lZShPW9p1GzbZZQ~kS1#nW42mNo&5k@}@#6Cc2B zcuw4URUCNQ}E-P8QzWA04LD^dI$MSh{ zO|n9~xtP}W6a`TB7kod}mG}`acNq0|f*G_%Z&)eG&DhYfz!F{U%^P-p)5A2LB=-KL^pUAIQU?=5PxTcI8R%ua*%WQ zJ+2y#CphAx_Au9ce}X|3*TkH@!97z;eXq&UPJ1g`hkAYkC%bwdg`f~E;j7Z2YUgD9 z5(uY~+I6mc1I=n*(gChn^OzeG=Qj()mrCXk7zpUSA=CtiV|8Q?*g41&zgK5E_T26w z-zVyy5yx7P%;7+Kr%swED+5%|v4x7*7?>tA0XrI{*0p`vx+zF%$Y!0t{Y*!2*~1UN z`Hyy7Ehn|iLV)d=DX;Dn4^%0CsEhLDvOuhc-#ym?7Ut@z!(|X>4%o-vFOQ-Bf&nx+ZF}<&& zZs}cn$ojS=e@rw~D&~4fB`XG7aFO;geM1X=rfv>Y09I-fwcVOcVbq^p80!m$PVrQOx`P8=&E{16(=ZU1nz=sigZ1%HJ)6>63k52bf^M>&tVnw`S8 zfyn|BL_D@qP;N3=^%jhOG-_0u9Gq%v_o1GTs`Mi0gco@tqSLn31RUr>o^mcaZ|>fW z;o`3l?T29o@2GhRQrt4Qe1iipn?_wrVWQB-c{w-WG0!>c*ZIvpeiX5B6v1zCNr|Pi z%OV@ilD#?|`{g{IF7ePf(?eSwdfrZ^c#s+R{Y45T9(A5W$)$U6PxyfBh^UCkrru<8 zJqN`&&$$|5_5=^lTf9ga$DV&qBoxY>J5SizEY<}>`QwlxH^ zo_Z>RF4Qr|kH7%ewHsZezB;$V06@77a(Bw-vZuTa%qfc&Mm2x+zZE1TkV$ zI9XxdH~pz9H{jS)_wEAo%9Z!J>{9rJuBtluTlggEDXhbXOEU_tPtp@p%$N6(XS#m` z06kSU9|=4;T)TX98O_5U3;8@c|3$8GhpG|0^imoDR#z%Gx7XCkpnuHLjpFWYg-)^ydyt_!@u)S{9du<9E|ZO^*~ec>;i zKQLGa2Lw-o>}Q|bo87`cqbUzrrygZOiJ!L)a`})6m3`Xso27Ge7Cg?iC8Wx0lmp7X zT7@^0C#DYi7jfqhGL}LAE&{Iqi<4O`FYxPjpf_ulmsRx9Kl*F`b@bnj)}OI z6LxDrb#gXA!?>}!@m@ePeGWXU)JxyAKCr`vMI*OOIk;h}Z{f;$P~B&YCdhsaemixc z8s)IYX?S8?IK3OwTVA70$4F{jxGFSN6KU1D9w%ULhfP(9Uv#+~lWoq0x)4VOa@ezW zM{Cbke|A?IPIPLD$pEhnDshbADrGqm9L7y(%$U!-87N{;ERD?}+`OM<4L=2S4qw() zGHta4OH^G@;geiTq2W)U4El=;oep)``~ab~9dVwPt8z4wQi#&K?-oMEZF3_&r8CD* zRsaOZHoj_1l3)6m1!p`%_H-hYk;yNr>79Tw_T_N*qj57OC{HP>G2Me5B;_SR`-I*C zT?wkVTD|<6KmT$w=1%I&!@966%ExTc@y*wKK~DBcFF6df*-(DV)f|R(!Gq*p=eOwJ zx=tt98F=v_7Cv$MatranL{vIzmIwXO31NtZ28OAR3e{oI>%hQ?KCXp@9-Z-c(d>x}JfEW775AX#xF6O-1vr*zbbjD>G3eOS-Hg2W# z@46B(9{LH3I4E~c+z++`n?6SVaOZwhr`Y1BGCS=eSCgI=n%wHgD)lYUyxek1&pYTF z^yf^0LrA*QP*EG%SL?4A(&UG4(<(6%Sz8?YRok~BCH$c+wu2wK7t&L&|J5Dk7s;B5YWM z!j}1Uh@j|^;V!*Vzc4WV~yjJvg=L>O9#YT1+s}XRFKJ zbF?6?{INzyrQ0A+r&CW$zkJoZaN9yu4Ql4ed=N2CUvMG7ygx53oZC@8$9-hVQWNf2mfG`#ku23Z#y&L2L7*mvFvK9I_SKHC#{qKNs4-k|NF3r-D6 zqL_q_0xN|}lc=}NlrolX^0+u?o>(V>|KFEd{v$UE8 z>*lRAJ9#*}`jH%cDC0T5_U4V$-^1iOEmWYk_O0;S<%tUdveWayKoz|PcF8(up)GRC zO&$)1$FwiBjIpo@oBDo$Cu*NvkFQo`3DtY@$~tp+>{A(8x!BgA{drYo^RY(_L(DU4 ztwCYy>W05>wZg-D8%K@SVWH6e94^U$bp|)OEnC+}37CRQ;f~N^EWMr}5?1S53m<9+A8R+i%)LNRr-8 zqfndJe^>P9$$l+MRbG(m3k=DG9`Wi8hi(KUi}pUOGzv-Zu2?e&K^vk)L_)bKF zoD(ba(^XQ^;X(Mzbp3LAHDaS?5$cLUrqgg#uBk5!3UY!aoO@ecS5}e1yLwi<_1)27 zi{b2wF6=!OZSASxstT;|4O5an_Vg&pek}XahElr6%NVZ*F^eh3nrKjlZ{OgTgpFcW$7kD$Asu#r_|{9R>+#dUo6<0-lvLVq-W4*<0`)nV(?m@ zIMQj0N{dfDfXNM#XIWY1V!M}k2qAHK7}9_l8rmCKiQtI86y(q}PemENh)v{`6Z zF)>dEEyv$qr~vGLYRbfW2-1t{a!u zDz-78@ADyXw3F_}emK zMW#_!#BjPo)nbkkN5{E-ubdC3mE5A$>>Nx5uA(4UHFAf~VCi1Fm*mS{Ht}tw5eFSY zRx~R24ixdRaC+v)1=>5nh2Mp@tk&G~Z4j&jr5Il~vDQn(gy?CgtwpG-JY8$)woeAs z>C`;Z>}YcuDp#I#pb%R#qpoJ4u4%XtXQxc2`z(7J>iV?dNK^d<(Cd`R1EtcmRvHq} zg&~JqPRx=LlVy=i=a+=S1(G%vbDXNOh918X&*tGASTw#ofaI^dR&tHdQH74;hxfe4 z>Bl2hH|C-m)+_nigL15-Bk_3cuDYPG6om+zhqCa}G;WZ8#}n~Kdd@on&i(U^cLTSR zAQSrem-kS3|G#|2u}V@0MsW(b{m+ioJ06gsoKTh^SX>`$;i+L>?F-Be5Lr%Z6F%w%DKj8>52O+vg?_5Qh!=P-c z(zAUT<*qGZ{s?%ha-@1JNHkJ>N-CjzLtV`l-?|9F;|fUEQ5&>{UX6M1=rT-S5bTP8 z;}psfwJM-KUEh-011Y^4a569;o@N1o*uvz=b(X5srJJVJ&ei4k<26U1&`ZKqZg;~~ zr7O}!8SP=pjh^IE)I`_8Yi!^2x``4~a+R0a?}h`Lp-nBsLi>^A zW@Yc!=~Lj-l54-3z9$mJ`9hp#?zF(YbFFn~Q0_LaS0{4Enm5$UXI4U-!|kt|!YZSt zJjBzK1Nzh#1f0j=qMQn@Em3R%BIvbs8fmXpSDN%w2zW$hl$r0xW129Ubw99!Q~k7Z znA%qNBg42m+$KMJWV{J~ol8#6NQ{0#JxNsc>jdJ*DSu56b}Bazet5Itc0@VWuDW`u zr|RXn`lLhS^*OiRIw;|$*9(_FdI8wa{E`^D#oeneDMa1*?zOC`LZJnJ+bLfL15f*K z1Qg16A{`$z~62CbVo#tBYjywt=JmYB$0hp}I6Mh#L}PzX7^eGNP4 zw=v8>u3;RNRHR&!6#j!KArsDn~m+W+U|{`Szr0>o6P>UUnawUd{OGO48QWj<6o#HZ|fg}+Jatzbz>MAV-=xO z*7{*k{Bqgyt8-=HA_ZK&CcYJ`Y|W>_7~-K&l4R173%~bB=th02k4nq>y2i~GjK`#@ z2d_$0pET`iB$G{Wnc?j%p(-7>Fkn@UheDd+sZkzFznKdc@_|_8AN9+M9-3!C1`NFj z6ySK&h7Aw)3vN~pRfrRizG7W=0rW(pGP6=8zY_Z*eFl4j1U=HZ_@>K#Z3RfnySf^T zjh?Bt&yK0PgBNu%Hk&J#;zHx(kgd<#-?z;qabd7tgURr$@|E`i2sx~0%c*dC>lPAg z-lBRwnP0N(vSD`!F)rdC=z+T0k7UIrQ^F3}jV;ilW=O-Dxj|d;sR&fYYQ#b=M(-B? zw<;)LW1S)r`+a*vhyHm?RCt)ld8UJS1aCE5(tz^Z804H7b0=7vxEuHsFTZ#|VbzUY zBjc$1c!zd%&Gr4gHmyC@DDhYj%Wx`53OGf4i||@S?41(nN%rdF^muxuEnu6K)^@7- zm1jYHwr*)-8IY(l)u;jvOc9J(eW(Py1y35uf?!or6VIJZOkvuRcZx-tqb>Jq)^bYT zTY=T}=aTiB6WPe_#bp@!v^Ws{d6EEc-ku0_6Sos62XD4z(DaX&bmf@v|KRu~bToA6g?`+1NxQtS(v++k&Q zjDH{4L@2ltd~(NEe|rfs+1nMA3(n13dz6Pa>&bA?ufRdz(q1h#!a!591dyW9SdZtm z9IX(Hi3Ht_oc!&`Nip%?oq(fwvWrd)AKf{m3LiVxH))`mR;L!sZZWecd>bx-`Ojtn zS}i`J>x<5fJA9olVvoHpREFsGKJ{{>)?FTNY4VkTHu^Ez{CtPiGKA-)j+9<@Z2)^0`jW&>8+xN;>Ids1Wn*Lzl6UB#E_53&s8;jY_0$;d$qU61K zQb+X$*|a#-aRWa)<(|-+#%QOj*E~hHzto8k8VhvE4y08wLg0Y`AjZPJjKQOWLd6vAMj2y%2Z7$Mu zj?>z!1dEIrefsgKLiZsx0~b|BC%4Rne{-X9`*WLDz1 zTeY+z6D`OOy3}#AK-as;#{Ei8XrlA|`sTI{xm@f6mqb;2$mR{;s08fjS^WSRQA3xOJXpAP#yw zw>tYx>u(|cTdHtT!HLb%2ah#!$dkDfmV+PN*@Yq(lmM{+I!{qsdtP`#KlU2-QvGaq z$_VkK=z~UXT%u6PjfZjro%cnp<$PLQukc5;J(%VPTZbsb(WKj}w492ri{)R#-Ii4@ zdq3wxW7g~FkRql94#mN^`$3cv|InzkSeM2ITcJWN)_fE>>U>eT^irt0wLUYhT%>v} z<4{cIkoX{`M^Mev-Sr|}aO=W+zHUQVz_)6$Yg&gZHl$33ag3#h>-(hBnxb3#iDDi$ zHf|1jXwa&rS09KgI5Sj3d7SW9Rfm3Lj;H%V@8$th|N?c0;FWJ2s zF}!45?f}*(cBSOCZpF+zhQQ=H&+zuyNL`tTzJjiES{pO!>?CA9NJuYG9mYM)%qqo5 zwo^5-Anz}EwkzfmFJwXTbkaH;Dm=X!F<$(<)wxVA|MunD0k#OKi+t0z`#uOgd~`cg zb7(0<+a~u%hfO6=dm%~{dsRO=|H*VUmDiheiIK@t6n{ez{!zT0k9A`QI{l()nWq<7 zKs{C&`oL>0ZN4C(nv;+B>JyGa<4H;AJ6l6D&@&C|tWX@%MU{+EHA(A?G`Uefw?sWn zf^J$$IX@VdPJmq~wzM>TZ`pEuu#^9EF?=(|SQfKpxVJk&vX=$c5mB6#D*!TV z@Qn#PRzFxIiuam}e2%Y~iw1Q0LX(j2)%g1@vs!~$dVDb0mZe$0`tpEqz7Y zcED@2{nh^1YLLATY+zh;o3x7kyQ*QwDo-5+Y|F7a{UX1dli^;jvl{{7A-w`}8svhz z!$Hqe;hvf2uk;B>w$5~j1F*sLs!%X$<+8`}3ki>3bLX$M-H?u_r`2=2PqsruCQkEj z+@N4oBTo5Pc|m6f7gr~4`!%^tD#0H1e3*Clzyk)0uc?d|qBgghO!9PeO0Gdd2r#|- z_&7S?XeJltklMpn7 zj5bBXzxnvp6Ro5*ud$EQ4BZtaeF3Ll$l*Q9hR^GSc28F~bh*b+kDXbHj2z3=)mbGQ z0Y6b8sh6e*;XpNZ(N-(&hv6EVA-7oG)GKJ5pfFdpu#4(*_gLJ?LfKfHcx=<$SPPqw zX2-Btw~1d$4KETB2k6?{8Ww;>#<(Y;=zI09AXBbNMukpQ=!}(K4ebWox+&ksk3AhG zyjrj#I+}*ZIVx7bp_?*m-~o@sVK)BrqJNsOA{xLMI{o6uZ}gr1{NK(GK-LSW8@Rh1 z?zr*3HZsk(Z!*G5&CFDvzq5=mO$ujRc^iNm7s?GyK=pqPNbXto!6)do<>9?%HXnBv&JX$qg_==#6(WX& zBj&O5x^?k1W>#bWgn^fI;SI1KI<_x@L4zi<8mVdB*T~IZH+0zxNhy+?Gd9Ln zRw_Jf*2>szZZ!xIY`jhXaNtkbZObM8bcy75F#cLJZ~~ke*l8RaqS-X+vGOdR=pu8Z z7`n(gDqRPy1#_DjUL_T%OioMRdaZq|xM*bE65hN4x*s`QWpCN=40Y0zUI~`rplGU< zMOG3mju8cV()M~Cm|GoA2naFi81SS-W_ngqUKn9rpFnemw58aLFsoU88Sz^le5Lov z2k&#&O&7-#xs#`7bmd!|f*$Ns>+*#cC*$ZnXFE6IsvyU#o;n_qt$QVBD$quWL8Ime z&CaayXj19)!W+36aOuLVXRDMOvPeuVuZFkomJG-sbH5FA;}q+k~cRr z8&h%N0T1eAkdWTs^8Kvl9kv55is+iubgg~s6-v-}iz zSgOj+;2!~=j^UES^YdLwu4`-os#$><>_zoHn-U5O;Ax|u4vaIB!bNbYGU;af>>zi zeDu{~I5}dp#IpU=^M-*9$dwuDSe~O<%t@6fv(j4#>9{ah4=Bwrj#pKmRQtAxh%NKpXp=Mw4e*S2*OOf?yz>N}VLkJS?8*9+z>g_sR$o1&A}1&R$?1pt--<%u zy!*-UvEj-!`@!NnrY*;?cN!ycbcLfUuOe(jrUPxP1T>uNlifm za=}OI1Suv`iDh>4;-G|14Xk1vH66eje@fcia4k^_I9sI^0C>xJz3Bcl^St-rw*|0w zYaTf2)-+WBvBTt6R>dnCoy7VmUMx9eE5xVy9P7D!^V>XVzlqNL7>Nhmp=U#yNYqFc2TOQ<- zhKedyWl@O~3(WRDLOXpOLF3xLjeHj1M#?y>d)lC3F z-R9I?#%4Z3k6*@Pi`m{_*QoE6kMrECZ9|HM^|H5hXf30@dV?-tQjJvE=3 zTWLdl3;{=QPMvJ1ZU9L6rJNMumn6Q=QwPa&I^(QNHklQeY>I#f_Z$D(^mhonn1__Q0o4W2{^aLl4 zLf=(C1a?b8`pTyyk7IDzbIzff4C~VRJ(PHbZjqeobWCN_gmab>rQoGlI5=176@PB4 zbgWet%R9_m>RM$>9VDUAQBAGJo`MQU{d1L-zsTHb8O@7Yd-WY|=ou|_U=%^^tP$+N z2HHUKeB<+TPrM2~IkS=|hUL0bADAc=TgEXHw}t9b)M{2g-c$_aWF{>*81QK@v=sNJ zo(V^`&`^eiaWzGQtEWn(Y0|fDB{X&emdC7>^N01ZVr)#I%Ws{$rF0$mmixu=imC}i zJd?25__-H4!t|;GR}zbQms;*L(3Vhv)lQmxyJL|-S2i18T3-@spm~e=>Om?e`Qys4 zVR1cT2YQYu4r7Isx)`Bwp~1XlNmSax!e;ejUhSyUf-3r6=|ibqHNvoUABuB0ewJqr zSHcvmUp(!NN^jrD=(;gaQ)PbJ9W^ zx2&bpgOrCi?K(faZ@yV%K&C3+^qlc*5Gl>Ki21{pSp4w-%_Zjs>#p11W7r<@0;BZb z%eO`zuL35`)98j2htbTLkxky1F3zb5uvMp@zg-Yk?ebHnC+;n0g~W!8+k`UDO%r!X z&FUL$bROw0_wJ>Z)G%OOmdn|D2{K*<_Z03dk;=r5)L*rC^qf##y%pn5CO!;zbrO?{ zgR3s%JCx>b-_?W_-UAAqHfrXAvdX*&y29l3VMb!#+TnNO?`|M+$&Hkd%l3zRLpE%b zRShf9KJWCJoOr&pk^6ijqk3=-=c9@A(4DF&@&AmAXMc-~N~jX*L%!ztp$0^f!q&KV zZFL~Q)AIckl2J$T13>cnN=;zG?Q}S(L3lh_jHFV$?3~*_7RfG61&d>s?ju|0AvTzT z4Pj*0Rl@MNH4Mgko(tlx7)Ue33uE{Dne442pc87`6Qn_?#Ieu2VQQj+2` z__Sd>1DDdzduxa$ANxEp)k!W~nd;A*3g`e9@LZt(BLe(W2LHwf?@^AY+qV&kS86yT zT_%IIJg4E%U-_$6KK{yIR!h;yK^1HEds@vw&kYgA2xHY^^;of-e#qTmqR4p?pqZ)V zV-j%o29+5*FJu8aFsXvQMCI*Jbed~|$!JnP_7!D1)@C_#Bnd=eWAm{6bSL94jxIl> z{*l-uoHL}B;s$iGO_4@>sS?mPgtu_jEP^8OJ97-RLO*WiHd)p8?d`_KN4>ot+_$sei%`rWg|W?QHN~qCKN#N67l(GR(g;5PO$onGaY?-Ba%?NLQYkoFdLMb#Er}$tv>I z2SDOg9uMhI+$P18g_K7;#|&LS;&smE6@`)r)nZVQd|hQE_rWY`R~`{^&cjB+T<>&P3|E7 z!%qj<6{&QzNPj~@zlervYY!7srfSU}eAk(wQ#!TM|C`EQ2L6vKUqj~q6;;M=?fB{t*^Do9jy7eZGEdJ+IY*p9X6ns&d(dy-SzX^;(y%A3Gzl z&7S%elftrR6|6)GQ{D`jPgo%E^xH2-G~-9?-_@@7o4qWW@aDj!olX>|o2#vOrL+3Y zaf!Gd;ClW)+TJ^?$!u#Mw)cjBC{>AwbVYg}r723JcThm-AYC8{!;FQR7!i<~k={c` zIu?3~)X-5WA+$(B2uTQh59hq^Ilvr8&pW^G53ehdC;QoZ?R%BI_Fnhqs{P$-=LN6- z*6p3B`4470lMOIOV~u}0C8KgWQ#H7K>3G0&g``@jg2BGm^A#gy57snGmMioqs-`^r zMT*H276iyeqVn4Z7p~}CY-w7o1kFOfMklY+PN*q~{ig}~4;?sPPzTuVk#YL?%+EWf zKiiu8Gk~WuA}A&Pse;QnL*>YVj5|fLYlaI9xz-(JrkB}X3vzL_!<)7Cr`h=VBWN>V!uqdzMg%~kL*TK){@cMVxa9;AoWua4~1NFJ#{ z7#)1cD?i3){=M)^KiBE*!rHoujXoIq~BJdlfiY)C%TTRstG<7cf9Q5P{w zo{hDWUq^A;Y0bzqZJ!G1ifYeKqAoQ>+vjy_pJuG;2@-T^z2COV1$QL)vS0o)%GL+} zD+L1{uFpSxip|<+A)kaD3=>;jpgNhiZENol_kIN%fp2xdq%F$4?51%Mkpur!Gj*9< zv4WN8D7Qu$f2~g1XgJ>vur zLma5(r_CbTf3{1HU;t1Rlow6^YpQ^)`c$R@*as06{ry}2xVd(_C$!(ta_zp(=&!tr zt`F=mSx!@hRn~Yopt;5YcT#2QB~+>f#HoHyk^E8KnD} z7V(?|3;zNZ^9fXf?;7?YmdH~6XZ^Tg^mJ3%n@{-o`2cw!6 zL;DHP>Y0y{YNnS20#9U`7=dF)fBw4H0>SgisSf`hUue_ePTVYv8L9 z@2cC+zi%#gf^ugkfr0_y&pdp^PhR~O`uZny4S4Ta*YUtEh;#idCb}YEJng5q^H2XL zQ~h0l0A>z*xY_|rHvY3n_MR~|F$p*zzBX&BD9}9oWbeIVM8v=%o+1snd51kr_ z+T&Keq`pkAz$JxAC|9h$KPnbJRSt0KBd7T}tsqMch4X)La`O-Apz*b7Y2;FS>@^pB z4!V}TO_|yP=7nz1$9eGk*@E|6klJ+LAx z0h}nuiic80*&N{WIuCRGB2g0L&Fe%x%za0_kz+9Wf+XL8;>sb!2y78tZfN!R%hP5e za80;64G#{K>n^WZa2XA4T)|oeDt0sTYnMzZ!`2=PTX}VAg&=M8rZDD$wpRC@6>GrEYJzsSSM`2lVx8{lCf4iZEk*TW>ThU9)B@iPKV4l z1uc~kV+Hdw%Qv$0r4N1$}8@OT@c&2R> zhImbx0|=uB%ZMEhuSL@t7Pe-5XST}w|DnMiMsWo$cWKys-Xsx79p$|+t@$e8&Ky7{ z;BgEOkoF^e!V0Klbf6-UL5!&jU#0|ZP(Y&&VzM5S49fU;f9Wi97Lc=~H2N^{4ZjxN zVy`|uSAk!oPVj8V+~Sh;NJVrPZAtL#GzZS5D)1}RFDCO6 z6j?rhKH2u9X3>_O?R@!5hdF_L8?!&>THfo45aF?&a^2R2pmMiD-%{&#TA=*MhLWPVtr+f#Y@`o3M zwpx;c=ljQi^zhkHPmCg4mgdWV$95d-Thx6U*a~v?p8%l5*qAk{W5)xRGP7)ICQ}iY zywrv^X_FOSA_k;5t@*OzQ zz&DZrT$+LC-A2vi&-%@w&`5x~6@LG%{DQdn0XqdB=94Q)Qh^5#EQI`mQ6Sycza}BU z;sDPyHliFAt3DO41lXAV2O(q>tv7?W1DxK96xyJoHe~y)fUAU%>pjX0y;N$5VIaLc zkfY68tRiXif@kCuPI<#G6}7&cffXh$`qs(!i;0M+#i6S8p}Kl7alQP>4mX%*bqDe? ziRMUa5QAMcWDM6a%!bn+7N2XYu%h17mhIUzH*TcJHy(9G8l5o~i&cbLWAAUD-)UL_ zW?YlUf98$m#>N)mvO-P@>oi(9LO#n|xi9|MxGZ7#QC}CCH7_`pfrx-OICDzkXmay=&tu zTb;d=z(yz9Woq{N`sf&dJnndpeXTk9mDw(`8sWLom^Q$|JgDxdI|^Ztu{N?;6zS$x zaNPywz&0`bZ*k<-!-0&8M-zdUOTp;8^8FbnE4pcJC-N*QGL*>t#6z{-%(a4#*r)cY zo#~k8z6LSKm!rr!QQfa82qpGmPt~T8MX^9?n=uL`(}}?}dB9%kEZXHN;P}uObMA2g? zdftK4j6^!B&0vn&9aGB^58PkBexVx-`N}Mtvvt-i1Yan#O=H|QExr$4)9d>u{|f5% zd8EGIwDSj&0>ykASdHezf?c>5;sIw`c7{aYB8?9d8`rAps{@HNEzydLW7FgE)8k^( z<2R=vvK_;ov^lE{IjO1f`_qtZ0ZlKE+cyC&8~mOr_!)gHnAi+BmZ~%lVpyBOyshA1 z|D^^t8&BB#yD(jS(Vm469oaoLlJD<{qIx)gAr`fXw&nES_DucY3ck_`Hk>_k)1yP( z&}f=Az6AGGjV3?|0m$j4Ng9bc&f{X|T56hO&7g=IV1SjmO+4gfH=Zjkzj;hwBVja5 zU8HgHkkv=kHD8`_5VJKsp@Rb0NYv%N=nBMBb0w_ruuHibejb_A+U6I~iE4@>O|9FN zS6gmLCe|;qHlrdvCTXMcrxpLS;QN>Po(Bi5(TlCtzOwE9v_J`>>p9G+Cqg|{n>SIX zLtUC^0(H&tB~bRd4lsWFjuQHDZsw&T0r|+K<%1uHE{O6!Dm|za3B-d z2I7d)`&%^yG6W#LNupT%v6qACF>v=cTSF~y$&p4J=+^Y1=d#__Fl!yO%OpSZlqLco zmvlDkdRRPIW^U08*3QmHi*AgLGc1O)K^pK95lZC?RPOReX0R%f)8wkgP&-oE^I~VE zKZ&`FxKg<`cuo0>!-EHWYz|t*ANXR-yUSpAkJhb|(J8Z>OvUkbK6J#!D&lfX8*bgj zcf+%4E7%V3KLR!Le37?P?WZp-821aUSz!l`XwTFR z^FXt75#!9Tixv9~+_YF_f1BRKnTrD$w8c>;1O{>H5WBU+6gLvP_I`g{LACpd<9@_( zC@o(l==kBu=9j3|kNn9HZO;b)^QeDy2NOR48Orn>7YDd-Y)@H4&QY);SwFXu*eV37 znS800Z6dstq3WImupq}y75=RgA_Fa(5&2|Iid*TPgD1JeT{c76)XlZQFwqbsQs$yy z_a$JQZYgZx*&&HspHN=6Nu?gvly!outddY03g{vIIFMrPoCP7&--B+oPK>dk0!|ZY zNY`^PYeq{s6d<-YmTf#C+eHoI95`#;)Mn>acCG zfQP0u46n(zD^nwtL#7hMHbk#(z)8Sbqat&QqL;sVo>$Oh<5exsq zaVXyGyv8vFzz@CZXsa=N1(KRR^fZtf6F6vCGU(h$wD28e#k19|HfYvSY6xonAC60_ zRu0Cj*`{)SxuWr`or$}uFL2YEM9;rK)%WI^k0pTwVPBb1!3KT_Ha0f0TB(B*J*agr zVH~Xd0sH6c+*shosTTXGr)-wN%eC~yFbM)?9x#DW=Z>+-<`mhDxY*n+(A^=yo!F(D ze+F!q{hU z8S@aV;qL*t+?_})68Dv;^r&{XW~}G6H>{*Q zzod%|;09OSP?Br%7e&PlFJk9CGW~yx&tJqXEDjDWkReItRjbkH4%oDTyo=9O^pM4Y zI(=Cy96g%LU%_o4rHTH>aa5oXHt5X6uLP7or%_6wBqfnSBb1Qb>KNk=RFYrO962R_ z0_T*}Pqw=|$Hn&h%h4|KG^yi&@}g8_;)b+YV2Tc-xp`|=}|WFW2KET$~t+Yj(vd(<~SRd6{RG0Wn>+{A`i6d(vG<;NCKj@ zIsCvDlA&x3(ER^$0ely3|H**-Yj0_wR_5*Z;6hxy&>o-gh_qlMlHN53 zM&T&?ZW}&wUHG>|kRK~HZ8oGjyx#kAE7$8eg52ApD{NEKVI=B+@t(xEn{x=4Re$!r zBvKIzK_1N`IU#tl46G`zWYP&`u?7 z+`g6w=6^n?K4``8F4f1z;P6@IftBk%J}J;zp35Y#deny-6UZcm_-;q}2%^6rw^Y*@pt*GZmo8DM^O+f@|c^sB!upxTOLgN`M zJo=r6waS7xHJaSR(u((WNT2$d{86z)UJldZ>uQ3!qr}1*_^^Rwb`G=MPz7LVa~iszcj5YZ^mZgrZ=kh zy8hmN;OO!CQsa^)8-OO_-HRNLvy=n^8O>}Q_V)_Z45L%lB|_D0-d5ZXez)S8fpxVk zC0rn7kJ`k?m@-X=HgoaEWgR35boY+Dza@-75b`IW4%2s+1FV%aF2;sWeUYf_#Bv7B zc@23j-(}xes^~IyFY;MyvAghmQkXZc`yfp27+036=unyhG<8N{s=yX5D4DY3j<^zl?#3AFwV_`qX*0; z;f8KaCdivYYFm&Hr_Q$`?z zr(56ZrT=Hw!Uqi)uPWbh{7w@0EBAuZp7SR^rE(5tNPYb@#C4AQ4x-*tVL1F)$Fj?+DYA{VwNgJW2H(&cS<~jBC#w}OG#B}i6xn_Bj}=3Xh{C~1d8HURnX3uW zm@`Oejt9!Rq?(nwQmbr{>HE1n0*@ThgD+M}aO^+RgyZGPdYcD7-ycJV$_Ahp`oAPp z6))g#mB{!4DO#>YMM{P)__#0DJ%;Y*QhowQTx}sKOI8<{dsUB&&8bB5PTY3?;}!B2 zE&Tkj_ZTa(y_IU=g*Fh)yNuK8kTIn`PpO}1aAzP}*AjSck{)Nvfy4aG$i4G#<2=;L zF*mbeIOovvo~6pyicTxOgX2Rat#Tj1CYwIAvosk!OttkIsHP>p@+&PR30jSH3!4)p zJ1Ead?uv@%VxK?nc2|~FWNHIhfNqxaNNW{mq>M~@$ZfFgF2~?Cryh%xm2|Q>sMX=J zh^uJTY4&)9k^oYEyz$P1)o#*DI^A-315lXQoh4Odc9QBG>p zQL2gNX_Gdx<4KG0XQ-e+7f@V;l$ATSBBH@IT5UQlx0v3!W$Hedt4_#&9+nZ0v`Jqf z`B#pWbrwe*$swVqZPaiI=-3z%z7ldzkVlzc_jfhhnZm)61b?fAHbV4s>#5b2Wk%zw zsfoXFdA0em)VH+}>5kaTvHrUImYr`K5Ze4l#2z$6k#1Bd)n&^GCQ|xb z1uVR>WUSiL-ElC(9z!Y_YD#q+GT}sIAistR6_OBzzBeL<5P zJ0d%%Vb|X}G$+#odc!~6%}fBJ?lAI?WlXg6C4#H97p8*wo}Uob$dF4Cw(z?Sg^8~Z zdW7Z~KCpdt<62=+ENHZ}DAkw5jD$~W#ymCCNPV`p zkGQ6~SS;|H+KLG3kdlW)DVE8vWayi=m1XFOXr}m9cSI9SVbM_a)AExQ^{Jcmyak61 zpU(2hyR^P}^cUVIP0iP5v9|6bK1R9WAdRHF_>+>X(WId(Y=J@6w+fu8$v`=NGUOlT1wLsL3> zkkgtDQ|^75q=)wf7J@se(L-%LPR>3Ov*$vweP76aR^99yUcChdq-6*XA%OgLW}`M$ z;fnPJoQ)~Ed(2XiE}Aisc{RcAZk(n_owaqJ+7WY;;A45iA0XEUOqv=zu7Wd#- z9sY)+t#fGeg=#iV2z)cNNq!6GZbsz@A-$xB+SA*nU{Y`mgQG$d$Y`EAd3H@)1#+Ue zaLUX5#tS7y6y5KQKUWKDDF&TYt9&xuPtH#&@p-(4o;)+v)7S5YUWwj_%rS8KM5;fu zwZ@e3m4B>X{gU&8T)*wu>#aYLXJ=_#6Z-qqcun%Dt*D?z=N7F%8 zVkGZxBX8Cg8R}?|Y%{0-&|{^29a2ONkx+ z4!It%bDt=^d5i@AvMxe^VJq`}IrN#`Dgo#0k^H6Om56-K^HB^bD-u*!Ht9wbJ?oZt zg^dNGZNuqO5%rNjM32;Tp{sjVP;`z#KZZia9H5Dboo3X4w>J)UQ?nH6k~#_&aKFO|2Z!Q|w^nlitF;5Xn{ltP!Im8V ze{Z6kp97K7j$?hB+m!cW4hw4pwly>NbQpJH)ZkBDAT7w(>`iRReNjtGn$p9lsEP?4 zFuYl&<}IwIC(?U3COPSOSST?vH3$5*^TMx<;M8VjPqmK?u@yEtwTCjhUdP`A_qwtm z`Lw;B6lsFc{gJ3D9np1G_Ym(J`I2oeWBAG>b=HQo003lU3IVQbG|9T=A|-; zsDh-{h%-za@l(vRk)A@o=>}9;fXYuG)Pw#R^fM$mwVY~FA=errd%^}Q4I9Z=R&c%B z9SSqD&ZbgY7rYsaWT>n2jO81V`KS?Ulq}lHplTOL!{PdqsG?y}0wUf^3TMsuGfg zoRS&XzMMe#YEcWRcN!GQvUf4=BEs-vosCX%*yo(&f2{X ze6p0?@{>-2d&!=w#w@X1S`%?I-muAMp}~CA+5#PUw`a+!e#%Cw5=u(a>~mmvhQzq2 z_lgZ4acVdSkN+wsTY73P2TPiDNAA5@#Y$* zq%Gw2_babgC2A06%X3GuUj2FClq~0yY`Gnw z%#N(lUoYB%TsEUBv)7V;imC>l)Ze{!;s6nOYGU$Fi4I1vCwwK zn$%dO3jD;yg?i52&g3UddDus2*BpoP*9XZKg!07R-xtBv1RtdqMaM=Cl3+k@nk2ov zd5lgi2R1N!7U3u(Z+HU@9(+2b@IuF;XIuJGOa?Y9c0k5=-Zs@c15-#lim!-5FDa4l zeZyr*#*Niy!!?b(aX3yY+TJFc{fo_B7m9A`usd=t)AHnV{vN1y(`cve&_*efSGQM7 zpAWb#I7DD>**@loBjIS6-_Q|(bF9;cj6Vn+EmV+3b+%1Jb{KOzwW|$PCS~lExAJXl z)UXMNi^_3p>Zw+i=gu(`YgqCsd0Xo{Vwe8Vj2bp)Ak_W!y0Z}7Y%({@c`!TkoLiNJ z@&QG#@9EMHl!`&eF;m;eDG&#NY?R#TDqrJ+|F4l#qx3!eB@ z{Hq?*FIn>#xV)&fagLbY(xq_zrg2T(61BFg7U_be!_D}ruB+-FX? z(xM917Rkh=Dz(>W7M=m?1(=BmT&hQB`~&5Rnr+c+Q$-r_=JveqgEFw zOToCZ+^Wh&+K_pi{n1c#ui0G9^z3x83&mwrZiJwaQ-jXA{o-qF)&@y4;JFh5@%1-p z6zFsRC3p^WNMm3+HD^T^piV7D8=@37^Jl`L-up3s`~8NY|&y za)0Y65@|E?@Vk%QdHB4bcz;}1%|qC$)ou@AGz(Y(t>i8zbz+%M@xH&8|3y<1F*CKGni2stVXuwJj{Caay?PJS?XNry+r8!#d{k9jk#JyR^!X;nTUiWno*!t(dpwZ z6a__%RH9S_kPeCUjclS@DvPq~fxbNc!{)ug>#~`4rmkm+En`pOdEp#=mm+8m*7uUefI*&kUDF6&#S}fL^xKC0jd42n{qxXOWZAciPioZ0h5CKp?WmqB znA@y<`uhjOfxYnP7uypPfWN&JwETp4N8@y+!tUCu0dl4@-1qb6HHYKBbm5I%)c{%m z6P!z*%jo-Os9;O{^{K;)-k28GC{uWOJp8uNe8z;@#TG-=G(gupKL}AHy!7@&X-aUQ zg%&cFA_ZQ~K2A#(C+aboEZEyDOkC0U)%3W)Imz7cjJWLLd(JDy&OC5zf7_?k7Gq;` zZR7=w(3OXAqrBDW6aIy#-xL{mq6xZ)&>mGAN7oBS^25`Ko@y$;;yJHh&Rb-7W4ZV{ z&YGQbe?vjKI%t!!k7oGw?a#z^;6tg8;K3s#s-(rI*5)8;wT|cdT&Xmf3Mfu1lTGM> zXu0bHedUnFXkz6R1KABxMb1If@X^k3wY(^Ljrhy^hzspRKkMA9Osp$rwKENJHw#gS z3>vQKA&7vFoIsxNel?QKk$7t|w)2^ssimiyU*Ky|+rf+qg{Y#FV(N0en#U!c_snwo zWrml;fxw2eLWygq_or8?W^0wMe3O%4k8SMv#=(3Pznb7I{E?Q$iL@)}Mh*=5w~&%2 zY9|#sdJHlC&={YO>I5y~DrL+axmF1qn`s>h=cFp}V~TA$DvXs;xPW|qy96`1q>z?? z2oCB#GC40#e%s8*(IPQc@r_;09+_>7Knq2)(%R}VVQ+atS-Fe^jMuRJjPy6=hV`M@ z=KBkI>#hPk<@oA>(BR=%Pp$rCNL|sp{?<7SL8}Nv**jCLfE3Fx(L1w?0LzIGHY~R4 z$KP~|&t@#-^};a*g9N-_wIw>nW+J`L$P^t?Tb4#IsBo!s%fU|?LdT8t7}G{*DCBn8 ziH~D(#wKuxUu~*s725(g9O{9@u% zD02eN9U8$L0pW5fdoZ@f&^PlQuDepl>5`81Pg+E3WuzoU1fpLDoa%eLrOq@a{jP_5aFg&4V}h4RA1N$L$_Z<&T3wv&;o{({QycOVD*uMFl1*E+Cw< zr&No26UZQ3nlW9vbWJ~LKsgG8JBC%@fIhgu-p;hx*ck7^)w~$=(#ss$Wxa0c54@bx%)XkTS_86 z3#pkA${1bBT~R>b^y;EPz8d+~F3|3-vF6*h+dslJ!W@?7^4%tIg(`Mk z@geBjUptsSYWMzvJt^QaSTu3b`@F{MS#F24(>MPJ=JZ)HE{p#GzkC8uOFLf3jyYPe_cG7gC`{K?Or$25XQ?RO0&bCk9; zV)Pu$scTmymmZZAN+_KJs2GNwQ*;tE>`d>vOhun*JziMr3jotf{nUK9)s3eVFCq`V z98yv{*5=_X4C1>ZZR2;@68ku7Btx?Dz2WR-P~asD=WdT`srS>m`d2*fUF=SSADYkF zI|Z|X$q)TG;@^XJMjfyZwea@xiBu16 zjK~vPi+!Yaa~@=YI3|?FZJ8ZQNSV-?8u)0Q+QgwIoWq+u{>ZhU@B<>O2sKxS4{jdt zOr?$E~cM$LlC9kYNE`f$I;Kf*>i#_&KxO_TiAH&8C5YNsdFSxOWo8 zBzNo#g;c+6>vg{GC9S*7X~pTbh{notWk0TUWv+E#-hL8%YpHC34{NpY;Tt^9TLu*?pZa9x-nN`TS@QPwq zN;!;lNsPIr_r^|Z>mpI$Z0(bxZku7mnm2e75m8e;$?qWz*H|Rp z+^BiQWuLU1O9nC|NU9z)sB5U*Uh?bctz48mPy+|Ck?U?a(!OeIs(ke&kqgBU0m;)$ z>hrfIIiCOHp??p-iMnr9zhLDsRc+t131+o@(Xe5p^1f%G%~m}P3g={p!pRvq;Ar$? z+{9(&!8%rxi|;yr^9R^f8mxaZP%l ztSPv=A&4&`wK=u}?yf%_u(Xdl)coQ@Q!={PCTldr`tzV$CIVUVVD#&R?dpKDzOs}g z6aG!?!_+>~Y^%B4_?`9)QkygPz=i8%MLwGI5O|kEe`(&CG-bu=M#t+swTCDY)mrJ(bRkVC3 zN=-wM=~XKoK~xfra@#-45%C*!O}Dp5`(-D~gMII)USCDfAVtGo*?fJB*PVS|M&9(3 zuZ*KuaBZB9sm-rJLVX&&+2(E@d;7dH&p8nbLE`7TQChC-N0c+$tOEnklN-Usa` zRXcK81%H)2J+3}$nsb}HHn1csz&1mG~?8Sp*;D^#;|z>PXld5j7lw7=DGcRq!^!gLK~0u{847gNba-Z^ za$@46a~$URCAdbPXG$L-qI*4|g>3{Tf0tpIk)PN~b(VbPSE4^swlX$bUz_2o&ZCQF z&*5Qv**5uT>JZ_qh6Ofk;@hOPt+6O?6OUX0XIq#ZKPa!ame$aDJ6HJyMMKHTpcBzY zqCF&JBzIX_3Zkw>$An#Xcw5tZwS;MWvznAGw^245&~QskWP1!7G=%s`t+1yw?zl{+zy)uER+T~sc>-JS$e`Kw$n&?7W?() zz`^ucL1ErKy^0sAE=Qw|K`-xrYu~H>Q7HZ6+Z@^d9C0Out%V^H@etJ)B#PWkT+*%+xRNj&%Qr9H2r+QMVcC4zR6q;t_7e zSF>{?b$)f}KF`Da?$T4qFnXaI@nn-GKjzZ6>8_H%lLo$zzUZ)By^JaEiC_s?`t(L( zT(BoqKQAYv{cd#&Q;s^3c^P5gx%}3=eWIsWOXu@lCOq!$tSd<46KB$GrZR2ms&EjG zbW}5IVoeJ!g!haJ(^dQG(bB8Ofp*s6QJDorA1be*F#x!lErP`5&N%3L&OTse{oy9e>2Y*aX zIVyj`v#HzNsF)&E=zqDjjCVLK+g}-+Mx5a9p?Z4dw^55{@B_|q_I5%{Hw~w|AGaNP z+9c(3z+UaeE&j2rST8$|Ty|uZVLsG+qG4Up)O@_#z%}o^+GI{oONw}P-=2ywqDt5; zbvZXLYiO;d=!uLo8tG@O8M^L_bBpA);W_AiCV}bY!6kcsveZ~v-7BWV?%AxuS9KG_ zXiz~+%)2;<+5%Osdf;-SnWr)mhrtg{=ny}t4%K-xUCzN~HR@L?MVu%r!H+c%%0Z$7FgI`F-pKhMsQ};uA0Z9?IJ%+Aj!5^`Ul8J8fI_Q z=v&h!-QGy$^4n94-X&@-b}4P{x{Gb8LVZI2e9V$1x;%c-Z6&K}yqRnC0v^aR>Ca<& zimw)=#Sy}YOLa2P%fyIOe9`XkHC+3|F!R@Na+n<(Xkop^ zUWw-nYWQI&eW5dSxDg9%vFEvpOs=m$EXR{chDmk~zEYQnWQD*a0VRqE&ixE!gN&n2 z%E~8A-@s9lYZ85{Fm=D>ugHB$CcEMettL))4zl@gNeI_3ZXOErU6ii*Tc^Sd_n)X< z8FIpR-DHJJk39zUC&+qU>IQ1$u5=$2{Z<#nnypx~x>;@x2~>c5NaD_Tx2=k}erOLy zAySEL3_|K~vK!!YLP3ZvGk8~?Cebfrjjm-HUiQN2=nA<#a?Umg3AK9}hlHp22gEwm zV?6e?v7oFomUWeV;(zrk9bOseTtrh#iYbUO7sGpeg0F>m?ZC$}n&s^%_=xNYXfeqF z{mR#TK1$JnbKeU5S3=ZEXYI&-kV#yKHn-+(4x_rpgzzaAUw5`;E4Fggdk+@vdp+%W z7yL-~JaYpU2ugkm(jx#jM|}LbTU&}33dZ-ZVJBdy-Hm_eDo>xn`gkAraqq-G?JV8{ zAJ*p$m*_`4DVK=key7y;`ovQ;#JzF7;&=C?1Yhu43*Sy7_JmC=J+x2h6VN!nuU&}w zzR>>mjJ#fb>}_BKs}$ z%|{=ezZ1kO{)>Ax%hF+X8`+mZr}hVUmY;;^PxsY_Pz?4?_tXxJ(!C3!g0GXFepvoG z_!!G%Y>$zX9izJ=+y@=kThfgC67vh5yQ{T7*KyTh6HyKy2)=fPF3S zb#jp5X>*o)Tc!0shBhn$I9Z=Cr@zGxH6R|e7hSVr>i^0it@Z!08uj1V5&QppJpq(O ztqhGriH}|1z5~vzOF8Ioi4^KDJO57yql>r|l09#BWk3xGfr`{3V&hzx(tj z4cPpOejOmETMQd@e(_(XE4ChDyytdgRimY*!YU&4KfdJWnw~$pd*gD2m{0L9+oP@R z!~OxSLr{&txAYoW;XezdWS?l|OtSGRPzcP72a2&rhGw|F-!xF<+8l^$38V}zarOVQ zZJq}VfkaJtl$p)X4Qs2Q{yiD>h5#*7MO57E&dKvhtxt=wWM{~EPTx)i>aLncQ}w?4 zq9D^CfTlpQj7#BhffVBSw&w~0H)}oX=wr=)W5=^Tf3wyXOSrywr`#(K>w|7t!l+ZD zp#wV)E^irf!SDMz6J(idHYNFsMbGxt^1$xR%CcV*|2Vp>=RaZCw)UpJaWh%{I$n22 zBlV)EWgdUKx4hD4WHqW*({HeC7PqzlP?>zA&7qry+eE8`(J!~dFGv?K#4q3fJdw_S z=>EO(&1%HqmDlUr+Xl*;jvhOHTrC#0Hp!2y1*-Uvn<9l`)BZw_>Q@f00R>@UjWBYK zl^QLHQf)_P$DZDX<#~1hqrM&a-8$bN^tK;tnX-TP{}13`x~;)S@f}YByqsej>y)N} zB>&kgP35&OCkcav>}Pj8_3vixi5*g)jCfuJ4%ETtpME*Jo#gqLCLrJ4@3N!+V#q)I z>TEUO=zf>(-$_bZaATk7+w+RoX1{&;(3N6`f=YE)SKp}2`V;5Uzd9cT75jz)7zge@ z+ARKx+vqGN+~2iLI`we?YV%vH`Tq5r|HFp@j!n=W54g#*Lpy^+Sl`YUwGGYEHz^(3 z0NN60>Sn>^u+Lv9$?vSIgBaME_QZD^@o$!mP5~4h65U~9wKBTfs;ajs;_f{)hk^Rfx{z>mEzL32 zt}`KI8K7E0EF0C)3{o}VoFU7<9sRiH@S*KZe2V-Pj8weZvg3f+wgvUSZSQx`G_Sg; zGhZ#c_;=_GK+{8H4pIIVbW*iStZvOC6(|rC<7F%%0y!PXEscfU+qg2ezf{F2C``2S zGLci^@fD!{7m&cFjp?RT;}ntpJGK!xHV>D89JkRu{jk^Dpb3mjeseE^tB}KM=U&9X z%{`ly%U=8$@>y=QE$fxTF~{lRmHG6tTS74bn^-c|WUMMWj_R~GyW75g_guFv9YP|#XG zUvYl=e9gm!u@jhYW_Ed!(4<(!;xn-u{ug%bKBTg1N`?K}T}|JZ)%*Sj84Cl`O% z1o4T=m9s30kAC)j%6rmaK~H}9VF%B%?c-H@+0X#lxW>j%iT$bOj|Aqze$es{<@K)zR2C24(-EgYRgVAbPv4s{ z-b1&wwOeOq?3>Griga&jQSI^$sg7L#p$s=4s5jiR7AAgU_m4(-9=GqeclR<+G&D54 zDIPO>W9#Qfz0KgA=-BsY_s@;l&1}yhzVR{(@P{8jP-Xp8!JeCDAXbgCva%syx7xNk zc9-Z6rSOjjKD%h$YvcDDFYCzo@>7`jsb*QkcMIP-<3Z5z{ekLS(b$}dTL9uqFJ`$i zXk;S564IQyGz^sf+TvgGUD#M!a@WaunU=P8&FIjfz@K`%ib}!dmh(T<*XF~!Sv5?h zWn?ZZDk`oRazFmOo4Qh72f{%~*QpFvBh2c_lPAMM`SSGK`A+<3y8nrtv9W!pZq?S% zQT;dm8cab6r-E5zvhBsqcU3s(Rppu#n~Xs`BSs!Gyge|Alu%Z~Y_*$n^WL^Fsf24k zXLs76d(u4XLP}2ksH^A44`+TZEb$svw&?5czvbsw5grlI?1ZklxXHPa7I;r(WiY_a zi>=)xaR_%AmGL^5TnI0Q#{&P0CK7p@bp}5+!EJWhiPY6QQ z^ojnv6z+h<(irnc?<&N(IHOUFWqyx^Qfyp0OIub(k|1e%|3z_&NoZ|(JnhG3c5~WQ zW&sqWcfR2K-_d>-innyKLz-M_Ld94yW&^`zh^AS2 zc}N?CVq-8L?&(W=+9RaxWKBoR&%#0xup&51R5$OBRFVG>3oGkQE2}!^p%Rm5Q43yx zn533TGrE`#J&a)<>}bE)e`z1S6W zo&T<`F0Vg;Ni8e4z)V?nX@Mp#-(*h6Okt6a%X9O zNY6Wm!`gS6e_Oz{6gDNEf6nQVTTN{BuUMx!O?Fl-N?6|%);a^p=-KsyG5#~0xq0gH z9p2+Ne+bs|FIe~J>FJ4Iy~-q*llfNj!1HIe-K!#F?guMYUy>f+yQxI_I0L=5l$~?& zEQ>7u3A63`nxBsMhay{+(+WRs9_UT`xjn|O60TX?yzzs_>qkJRB$At#mPD@Kbg|IU zDLl4(@)`TkT`Qp`o#b!*|H4=5ELKYa&vHq#^W7q6vgdTBYCS9%8DTX|7hfcHXkHF6ckuy z9GxH$%?Ey8G1!93nQv@bL)EUmKAKRx>(m)DCKCcK1YYL0X? zpE9Ka(}E-@nda9m9;hJq$EOag2@SY6aq%CW#++0$y8qzuP&2(*q2l?^2xwQ(`wOQS zVl7Ygd>xPc0KVq|*WTOTAIjY#$NI}+?XW0ulmIgm1s0`OFY!+ie8>4Yq+M6q#myz~ z=XQgCFu?zbyDy&w;351vKRNlYjn1SzP)p+=ASl>Mah$%x5a%;=wzq##+$pDZ;NZb2 zDx2ktKd2|$Ui$Scc$V?vR~Z=~gzV9`yEvlZ>$f$y_XooTalyZGxveCmINlZhD=?fF z06KL02uH|w;QE4n_vqu$w&S}8aL)oRX(b+oX1i$G$#=&ZU80Lx5w-aPS#Q2qu1zv9 zj6Hp8i2eVg>nr1$Zo{^36$1pG9)JdWck2^soKET-J2)Negm8KY`Aa(*^2TSHr|R2QJ9kwR|A_@m4(j@+|X-_6#=sf$)WtK{$o( zviHcmCmfs2dkN*mDT`Pge7^A&?|HL+)IQjjx@|B0pa1sl4ByF8%eq>S7An+hl=Jx`#@Q$USC{k?Wva-8F+PU!NHr)IbZCfZuFdZ-`i))?(+v8} zPo^bMZKs0S6VwHBF2n})S>B0C3QDShCAY%Ht7Z#B;Qe(oLMDoq+v>eqr++-pb{jyuj$eQMpY`6oqp}udteQACZ{KHeDvRy7~G=p?@o)+GQIPk zU-*h5;BRpkO)l!p5`Ks&nk_9YZJXOjBF4hP$~wvMXA17nF&`)`f;hKY$S%D)SyMGWBm5g< zN7pa5QMa;1n;lb&7y3Q;xqCWEIYn?oJA-D?PTzSnNPNTNr+X~#M7*&rg@rxhy0HNu zCP!hB!i|zNf!_I;_<7>F`7h#nzPBk&MV9QVc@l4D6O<)2>3}XAJ2~nCb|&3EHjcqp zq{%!#(MiK#Fsec6HtrB#;3?L%B0ryTTjOJp;KUaM)nUd?(6K|>>^I9#?MwVi2u^-s z4u$CkMi5SSVv%cl_#|b>@37#Z=U;m(grU)J=wljdd=?aOB?L_&s6YYi|CEjU4$FDl z1>jU9_mYgTvz+n3?L{p>b}jfD9D6HB)s7dH(&K`5xjOeU_V^Mv>mp~A5XrT*wR>EX z-av#YglDkVcTDm8nPL7S_q)m*{z&Ex?9~F0AJ-)yY_e$%M+Q%L{o$*-=yFYJf!Mm$ zjNfD67B{+dowIce2s_*m^Caj(H4oG{qf(7waW0E5K6BD1qIY=GcD8?|Fvrh}vAftO z9WblGTz1!Wt+RtKGoh0BV=$eU3A>UK`>l)RU4KsFC!ejZ9W_Vd|E#uuZt>o}y0)9; zyc>Aa-t|_Oz-zMDrRQiN8sWK233Hi*6C8-#R;v4<7xzx3R6R{&Uk~4endouqRRVQC z2%C#AK-yBXw)hUG9)E_nh>>N;lMVWKynD+Mb{{~5&mg#PDBamUa7O%|L#eKb6Q4ZN z(^|525m`Blpvj~vWPg#}I1hI0w9a=;0IGK2N@tXUtcKW3+~sPy5;TfIhQUz!_4V~J z=d+Gu(NeVI$s>lpi$*YXc!6a1)Fl64a_$e48i@zmS7MYsq^d<-NTR*py!+L>MON@# zxW=bADK?O68zWBfIo0rEVZp%x`r*QzXaSf<>ummDdO9@~H8r#WJ2QB^0HpMM6kTD( zYJ&<=p;@UI+H0XyX(s`KMYB@2d^wX&2g~VBF~!bn77S|^KEUk2ap$4#s$V?9Yl`3X z&d;q>PXEqUux*P$1HL3s`#C#vP4To=jShWx2lS^E;mnM5{X!@FG=_EZOxqUerZr|4 z8eIbd7MmcYBMWez*(Ol;r3~YNd0zSxFhsDQm!_ z=Q8BRlsu+r+mI5mAxGA9*yjX0p26CXE1oP><`D1$<{i9sL-i}x3O}%X+-u<_}mxn8+RE`z~10^)|m*%D8ZBJ>B z7_e}{C6_B60-iwH2`bxDPKNC}!y0e z@K-p5w&wx5qrC)3LrtBYCca81V#;8lSAP}AV}Y$?VCXzZd|bCZ+0xKBV+;i~>u+rD z5kKk~UNY>i;!f}X{X17sP;fT4#Iu3w&ZO-aQ3^```Fr2~>kIkYNcd}x4%|;MlN!fA zvm-1FS(6^Wu7`vTuTf_Z4%h)uso(v{lgHpb4jQ_Ma|r&`C}lBT4~+E3;QD-#dZ5^d z^?C*nEgF9d`&HmkyAm?lqUx{+TX+iRg!zhXM)I#!gSh$En4xv!j$+vj^vxHHUrQUL z7?3rGQ4$To|J@P1T_JV5w%X_dk_p|=7QS63d4Oy-H$mH-GhP}H6Dqs3nTlC~WlYC9 zjU%JiRZ=D&=X)nMxtMD7&IPQ_xy?5n5XK`fRZW{B0c}l}MYp!DgO2fm!A!??dpH3{V=Ke!u!#q z>eDZ+4yTd&AP{KtB)L>fn7aJknSYI^lSF5h`ZTlADdqw;R=quGn~jAZkvc%GN|VY= zNHY_@>%|TJZb5|yYzLGsL9~z;P~HWz?7%Yz{Kvgt09OrJeed&k=4;V(xjgstZ^UFz^Ga_OmSvdfhbMRAc&ThzLC4e7W zRBNdr`)D9D zwUGEeXMiot29viX)PHGnY0}y#+(9jdffkPrLWWu;!1|Ii4B@@ruRb zd@9%GnWY%O+cpmT4F5zby>b}lHLabp6dT9kaCu^Hn4W$WxP9!yFdmS(X`17@J1hEG z{l^W*R_bR0-37GZ{otRk{&Uy4^}zbmN0)<14J`bnU}6U160>~P#ewel6Ob1Bo?K0Y zab5!vc-l)eDe(d5NV`<8BX*4w*S#)?g1wY^_@QQK+_3q$(ghQpB3atJ_rXb$ z%}_M$Q4>w-WuH>*_K0=+A)o88ZipV(dZ<)eOC;|cXHqmYh6+dy%PKHugnCU`9X5Jm z7HWvM?)h{!YCSnp+r4Y0X7Y+^*{b1EQup+l=W8%!_T!USxFKI3K2m=7nT`FY?EAZk znCFI(LYAc_X8u>;L`$)(*sy@q;Vkk@z^%b5B{91)W6kp+=7BoTW~`_k*iko<_j;Yn zDVV}_Z!>WVc39zbz1kZkhx_IkE^sjOk9aY<|HZ~=1|=u>M~Kt;k#_kO5D26y@4V8) zeOqVN`&wimlee*kDvE<>>3=g#&AdY9L{SCkyq}Tl{}L;c1?bK?L*IYS&;DwvR&Slm z5+z@S^Ak6cRWTd)MHV|>1V|%X%~@p*1F45Ks2^_NwrKzgYHa5HrLjihP}~-&ieq1Q zP>bc!=LZqZkxM6$R2IlOw^OyZC_U+vEmK!y4ao9WP1ubfVdKfIFA1K-ybgr_4H2?Q ze`<`tPc=mr%U^KN>sS<}Pki7C_Od()OP%YV|N30ub0x{e0UEx|t9wxCDKA2M?iv)` zRKM6W*)i=6?;$lU*Pkyt#n}2c{QhI4SY+nfUxTz=)t^s8pP|gIhV)Qh)XkDcn!NRL znuu?S+x@M)^JAZn>TC=FbGS^e|E#m}VP7lodF{bw%IT-O4`n@@IW_mP#m!}OuE>cm zC5Lzy1}ses=#fS5)twhq;m8u3B?C-DP^AX6Q9SCr_e+GOWTe;ilO+Q++&b`nlob`Ln&p?Ny-Vm|#y4>ogYG5&+L~=r;;jd~P-H~xV zJ}PVFgvt?b#b%f+7TO7(d0!o$yS)wZn>q0Ke4ma* zf!Ub%@WY|^(PYhQx1X&N8J3qP3o#BVO|LcjbH)%%Nz)r9P{A!~AA=$?S|Mt~{|)XBzI=3n z*Jb$Yk*LNR8VrA5>34QWo)eJ-3M)}+q>aMhKfH3SR9nSi?=MXO+kk~o2VMdLCb@}y zR5|lrOM|+;# zYCehkv7^~KLzFxRNBsg2f`hcqOCWeu2hH?5CvnM~-txY92k5Y67=(m`5o8Cf zo9nTD_TS~~Rr5(MlRSogU22zRK>^(_sK47mBy%SpA0UBEjt08DFFEXoP`GZ_tNEGqmLM3`@-Hp0zYz(Z^}Lpx zm|7se+b^M^yu{8BdC<>vNpRq|9P13cWG@~*f&>W^02%}Ycao|n(^Q%WI$=>sAhi8>1cUZF-D~tI%!8P5y!nef3`l!QdJa4A* zz7pd(`VBc=?fd_^e1b(azPoHamS&y&9S{9TFn0FIbs}P!9(}bQq>8QMgsde?oYcF% z30`=x8LG0~IuMgM!#fdVHq_z{+n$O!3C#a0>+B$WHY()J#XIcH6&iy0-o#U{@&@(s zt<>Ro-<#O`EwMHr?-8^2X?1}tf%t1fo(f>AV6AGGEy(1?&^{CQatf|zekcKE8ew>nRFso-^uwJ!ZDdHQ7!$;XuH)ZTnh1!7${~Wf_%}wAj zI?ShoiiQTEa4%xfFDhJ)tu)>sT1rezj0xU2PR`MHoWV;J9A|V1JU{YDtr*6g>r1S& zE;L$CPJ+VklPBrxH77z&sSr{$lSUxSC1u)Pg3lNa9 z(Ja^oYez0fHgKF{}R}odGphzN`Tnpx?Np`dJ}WvY1qaL0jjte z3pf*-B6epDm(Gv%%p%)PopF+O2c5M0r~s|v>i)@c5Z4sbFuht=(xrHr@JLJlm#|hk z??uNE*DT+nI0o*3EBorp$MLd$>V9=&F(|4&8SUo7xSck7eAi0Vv3`$zu3l#7-Z?D5UVErNdYw9v(f-RFvVZvz z9riWcWBwKtf2r6Xw|{$lyTJB1NiH%iX)2=XfL`FO3UIgC#6C7>J=8k=S9?(BpgKY zovbkTyvSRd&4uU1;0^^xNN_DcKpi`#*P9)?E@|M4m!;rCq0;B{>8IQp zNl@Sl{9XLBZJ%7hw(~c|>u)luZ5&!mgZz1Td7DzQQDZb$uO{g-B)c7vo@M&m-v$Im zz-8ZH{eN_hW~kZu7||Yw=S`h=FX`ekkX^o@814p6??l|`r7_&?sdMO}H#Wz!!W^~VNW3We7pwD|=fjU;qa){c_Oh0q*J4!ahX{iax zrNBv_jETX*K6n|cj=K7nHOnhHIokN{kLd<3`WLRy-4F9f+uTmhcB)QdBx9XOW^mh6 zZyR{sj^L}J7^yH|Yp<%T#6?mcaKe|2eUIF;hKZBDvr4Uz0nD`HYf235dJ+IuSM~bQ z{ts^_I~AMU@0xQR{&DVjF=p0&C%T&X4{5Bvgm3kLk`!9Ky7Tnq;g4Guauq)ZsZ53! z#8}UJf4y!vn|75i>Fsm$nl8fWRzY0m>4^lKaK^xP^;BXGf+nO4M)UleK8w@R>rv0b z8COSZV|X=uQNrArgfWz(9j7(dabJ1uN7$h8xh=YLn}uEIL(f@^t4d8NzHeOr9>C5I zXqg=Wq=Easbs0*gByH+_ZK4tC6h)|-`TyZtjtB^-n<UQcv>q{XUbac%{?M**t6LcaIowyYO6r>nfqVOR*q5^hL7 z@Q0mYWE<+)ct!DOdV)*wu0Ggay44&(*QDw;ip~4&aLBd15ov#Mzxpcc(af}K)cfVn zx9uR74BCySe&#l-7DE(?v7pM+rT(FCzd!~-r>K;2f24zM%eye`pL;abA*%+GovKF` z$PTht%=tU41Yrl3%|Yy{UDsTPBssZbTq7Oz3nNsWhWaIQ*!Dcr&yrSXysB3zhfO1l zfq5g3nFGib=QWN?1D{OQlXZ)sJo%ZoGSQh*i7-m=I1$zLYYi$ez3ex*ncvj&%NMh$1Qy>1*e(?lZ3N&d<^ z%8PeirK~exd8BA`k4XJuZI{&e)V?_d1!^F9WPrSGGI=kjM8_)Bx+OI{zN;wG@#ONN zf8xNj{>7y7E!e~ZWsVpaJzxL8w#eXKm^3rDqWucWtGlp)116j6$lz|nvM_&rM3g4@ zsfdMX)hQ!>%elP8g^))C+IaN91n9rRP9?DKA1fwfDs@4~URAM3G3O4W`BkaF=p-}D z>BzD`Wn#&4CRiJd2dF6%<-92y*<%B_Kigfzcmy)yoGb$jduRb77dqhBpw4>gJd5}^ zH^ctegCmc?Pi8SzAk?Vt+EWpq?QaEoY^8>o@N2J-DQUMj0@~aBmvlzd!3p#e(Y7%wL9FI`JQeUPgDKWLCG2uN8OOW3`nF?KU);olNg6Lt|8FBvRzs zR96i?i?rzgMgiK_hqcf1{%oE#S^wz_dZ8ias`!SyQOL!TH@`np$@+pfC?WPF@a=8e z=w2-R`q-$nZHL1_$kU;alTTKVP77ZhPx+J(6HBliENXZlqgrhN;-jcYyyUa_cb22% zDEgfQ$g{(CXkG?&=Y{zf;SQ$u7n{$hs&l_up=y1U<4w*@t-xafnh>9`O$iHEfL=3>sV~I5z-v^FiSp1dUrC!raS*PmMGL;?o z72)ZKQ3;IObnLgm1l`1xlk~L#jz4r)u`86-f3p{0y(qtz5|xN^o4qwVl^POtaEo)B z8Vq3JByxL(^zc{o+aCWKpdKPtt+0*xg~i4lxyrapxiY5ZhqxBeqfFOj^g2ew`g=f0 z{@)Cw5QF?2b5if-MhyQ2QaZ`@@JFn&$YEQ_?h9KWwsnQNwD~t_X{LxYe;Eo=v~i~1 z?vDu&u&r>z1{BD8c8X5b{qVg}j^`)$PoDL%*In|P=u0qR60y=l>s9u=la>30JCxEC zOSEaxPQqQ?5r>_OcaR72bEDU@II-X2e3HOQ~y~R5J#pe zCZOW^w&+Z-Eq%N5vZelV$*hEop7+AES1H)6Dlt1bPHjm+daq&LK|y$K*0)@C^Y>jV zzWn?jdze1RQnPy&LC|H+giVD`;~TC=b0f7TQ0}^~uI?v4l3 zR6~zDq#Vw-MB{(xoH)iH8uFw#YWKDIP6zx@13eB5`$Vw|uGZGCo*CVJ8ki5gb!g^r zJlNpc)LtmG$dRPAxR+aYlFcGXGc(we&#Vha@Ry2ojh($Z_$A>V{j*{EeY{EcaGaFP zCk}eh17@MIX46rx2h4JQ&&w0UIx*(hTJ4heH5*Ysj4TuK87vrYg{7JfA9ygc?9SL3 z4fSB`VAnKAP^4J*q%Ao15ijQjTp6*T*2#KC5@Igex^YhUGc;y)mf4YE&a-85!rD5c zcCI+y1`A<9EXYFoMvmGl7sE!MmqKQZ3u4^h_Z~gxECZcy(U8=x8=}mze75UMD@3~m z5}!#5j4GjIfdC%!+FiYt5+@0pW8PVvBMWZ)to3+!FT+*7onfMOCb$mo^-7ao zvdN!zT5*lW#+Ax%6f?Y|Zu#xRe^!0Xo_yF8_b3}=RpQw$HC(2wn=^coZDS_{rTI@p zi9e`b>^}G#^htQPOfBTUDTNpR1p7XC)P9j)^X(6X^4*xHRrx|slMRqVtcAx$*YWkr z6SgIWC#u(2r1eC2g~!SiM>^3gsk@_l!TwpfeC3;#OqZ?c(Rq&4=fe3z&Tt1n4gLm! zY|dbD7ggg|RF>mnfXb3T{-}uKhMdVp%spFRd8D7mHve>Sqs4Y#x@tb7N`~RMM&Ih_ zw>b$3(Wm|+VNp5!FYSNU@LzOC1)x6e!CR{gq89?DU18W*GYg$p88)JvI&W`*`g9#) z(f}4v?#uKE$BONk3M&+)f>_{n#uxbn;kvT;mkyU}*YgX7V`8kBd!AVW7Zrt?9eWk7 zSG|2=_WV`eDNBXui5!)Mln(aMzS}jXY3eh{mrSM=)`!$pl_{a0pClJ`$0fvbq>S3s zWw-4`?*`;XZ>8s>lbbHz-$tOX5Wagxb>OFQ{nd|7s67mqJzE%p(F{s-geSn0LivUjWbQU(Yq}o$O@*sS z{MvY#C7&t9`{eRK8j|=7V_qFI(O}tc%hNm8;YN6)oN|@%qc%T}y8I3Drnf6kQ-w1k zl&-u&TtoUf%0ZMM{mlH~z?U$G+O0g<(T@AOaU4uJlBzM^D^B{PMa%6)9LitV4;Zfu z6k-34j>|!j6FNmMk(C#7F#Zn})h(Hg29;!`d+ZEf5~{#`2XWKI>6RfMfqfIUWmO%X zbw?LlN*!~Xp+W18{RxViO}R4ts*|Bj0ay~(ck$|K(>d2K#HxK;oT2LmfiKTWUvpCx zcTLOWv_RU*^{B4{&G=1->b`=-}9#d z(J%Ux{~o=7-cM-_(GWX1y1@079IeoEK#xfOnL9;{r^g3|=Wen}CwVaWDo>-+wFA%! zq=L6^@urN5PLyBxUYvPrXnrHpTApVRYXoicia_65RQ;VRwvf@K3(IB8fM6=@iEh>4 zOCqpuWU7rWwiVnY+2v|yk<#|}qT+mjCQGfWR}vjq70$(bAe9(U&&^>P8Q>jRAqU^p z^UFCXR|B2fI$RHS7JEN`xH$+vSU=BT6?Zi{x+p98hgUjAkXu2w!}+@8Z;gbP)b!O< zgBFtaD3d#7+ox220fseIN%pfF|2RoZRN63aZ9ZIH4!cH^j}?YUAQn!RoySEqQweTV z!>W+rDcfhlq&G-aUq};1yUepeP!OFd)sP&TIhXU2-^)r2kq+^)+`>4nMICs`7UP}K zN*zCWu(~wPx6nv)r=NoZ=F=L&ud_k%W;SwK%9$$y*f0RN+%ge4!Q{!lXm}IPjrg~( z_Wiw6PhrI8Nbps>nj=#8tM`4$1%v(&~@(V0!%HAV#U@+ST*Vu$;85ceMnc8oD|B#qp6*JAl={NCb^ zIl7mFF0iystCzzn1PzQ^&YAcH-leOFbPr7t79Px9qpR{BrBS>k+Rk0sQf1+EAz>cm zlu@&2jv^sl7_M^XNErEZ=;o_Yd&xs?>0OH$tZ=#`3xh3W-gr(3V&(dqj z$`6u&$N2-sP!55aTTbG_Dg`wk$cHr;j(1Af^qQ_j@w+LW?1wVtT&D}Rt-W*LH*~7N zS~ci$Tw$*xOksN-us%oC=5nc1FZ80#$yX!vrH|TL5oqOy0OC%}D8F~tpumZOV$XD& zFM0&hMrqNy!@SOLkvg^AuFf&_sfgsQ_mX>*pcRe=aKCqN-xw)5?%!g`%J>^?S9``*u(LG&rAGcb6HdkIveN{6_VNq6bc zoB~5rG7LFAcEL?X+5=j>T0=r)G*`vZUyB=yhwGd#=~AwbJP7rb%!+k}UpHJ|N$Qk` zSXLb^iz{ee{jSJ$h6Hjmg-;Y%JU1gTZtsm9-*|m+O zp>W_+ZqjsztG5FNC+bR(Vj`erEE_Kuhd!^WjKJXqI<2Vf7s7UJd^ehb6$3jw9(O^O(>nB1qYeciEN-yf2Mt4jdv zb2euUQPc~Ued*SpyG^&kNm%`dk+LSCSJrh}P05&`@CE-ars$(-bPUBT=^6NC9+`=Z$V5{6V z7To8RV1>-D$t<0-{b;(S9>hoal%@^!H1C-qKD^2zoQboF4%nA)c(eDFO1dGJs`=zN z%^wjGsGPSeV3n{@5W7Iydoea276lYlHL$SxQuRn1vENtD_$2R-@jG#?eM`3YnL%Pc3udOg z7gtzL-XASGz86*^Y=73=TrnbGNAA(U;9XxY>8r&Suo%rr z?yT zM{z)v?Oa75uFt~+J84WlN1eU%zYES?m>X@6&TeYw z;1>-F4*&P3X|~xABt6M148>m9OLyfW=DgGX6gWkWCBi!j=Nr{KwQMr{`Pa$IpB@Z` zNhZch>~BVE|EqWEu`&B*Jr|gb2KdciP5K$!bvTn+_sENrb%reK@U{GXz>Hl6CFzG& zK3?(LII!SoqqjuV%m`HrS_a->xQ?#>67fn%^S6MV+I1agFOKhihSrI{X5vS3m9pZ~ z_6EGlj{hjcE|X!AorR{pZQ|R=h7e@(Lp~Q&|oOG7k6HGz?2hCq({88 zSN-80r~MvTvY+kmH4}4#^+%P|^h7Zsd3T5t)0yI+>6J4Uz)#;%9j_#94+CH|%Vma} zi~N<`?06!ha?SjW7B!!FWz7*KPr@TtquzdLZjWCg-R-s(TK>k?TtYKnEL`&I)v2Y< z6^!;Mew^3ddG)kgHV>~Gxh0kjvgGm%cNa=GmGw6H@Hm7*3a!?)LlBXh*A>{m&%vsdrqWG*Qt8?{Dv#kH+i7%wzZF`4Ls)jhcq}r&OKPxa_#VS09VQ@+ca<4&t}ooeYG!yD95!^c-nm!LV@}c7k<_+% z`RksA049db)p_l#uoDx|ai#A5cGIT#Ue>bMyvO(wKg^+}V zBrHXFCw%W8OIINcPYzC?0Rth(+4JL2lL8QP=6CZfneD*7xA#k`(M^Q#zHi0*YxZb`^L>D z71)W0eUp@%`- z`#>YeI5R^WI7?M^OF^+-5R6eO+!(SFUyG5t`c|y1OJ?t{q^KxMlP17T1Ty?dV4bg} zWLWvtR4Fg9Ps~Iu8mYSX;!u45sj4GX!L@C5z%QeTT(#`EkcDRDZi#l8vqzVJ8hPK$ z#ZtKID4(tclbkqDGJ5Gafx2#`9XzP(Aa=nv?q!)h$2DAjA&bLWH5;cdY>1Xy)lKTA z@dNUEUV5b+&t_WAVJUtd(YuupjAWuvj^h{61UY^a;g<<@vPGWxW8@qY`!wSUMHZ%? zA|u+(YXFP$%^V4Me?h#!*qd%JY+K@B#?%3feQXyf8RY||AdZD+du`W8)hwPT*qM@t zdM|-x^7O@rK;=%wp-gsGs#b=By9>edFwzfGDf70S;hv~r+0bQptFMKu^l%60GRKHfS{C? zxT1*j?9*CvD>JOX@!If&xZx8dtc|mNRKx;ndismid023@tOVHlASZmG03s#)lR7-S zZM(4tWnls!Up2qp$Z%y$TAb-MzX8?e<`UvJ;?13cgBv#D@SL~jt+DZqo*nc-pT4Ea zFtO1Zrt%jF(3ZILQ}*6 zyJ1OQS7F(1dc5eV<>2V(p`bMwG-d2qdPFi3P3xCAMJ;26PfwmWxA`+}6k+=8$OGou zhFOxbEEJUInw*UFRY=xvsmM|sArzA~qW+aJoV@kE;;PTh;2}l&m21-c8!l)|t?qs# zJ;#*07*kv79!V+X`AB3Qk-rkKO-ue4?E7v2d$qV@&C0eFc{DOjTFu;v^ zl-NuxE$K-kH_!471upR&4t7Shfy4@KzCU4MAtP`VJl?_`JtjX9MLQN>hk5VPcRb5F z!O3|tPpKv4Am3xVg>KvSl7f~%dR#prA? zC2{dHi0yeE&rJ~_E?0}hxh4a=T&9SVN{mG*w;!UCht88m?MiqWgq(*e3YLW7!toRz_G*qI zfW@TI_Ppfr@sQLXBYhL}qsfmPo%I`^IW$wgJQvSFoyEpJ(aHOhuMj2s$=R-z@J6`` z(Wj5sJYk>gZztbK*Ihg~Y8p#K3rKSU@6%x@xjCFSlPPUBs}^7v)0D6(NTOhBOdVls zWyU))%@oH^(3wiMWDd($FoXx25IfOnayv@yeZS+;L!#7UVQb1{o2wNC>9OG;fCfn-n+W4) z5M4}0kJ69$GF{FPeAZO`;q*RxQ+Y~}<~|CG`@o+0EBaE%g$#*jN$<22093UOuv2kY z2#FyDjoF&$gs@`rS_cn*^w#bGFq`7i3ia>*R0^%uC0h(dy9v{ay#JDrP^djY6bQ1^ zFSiPG$mez52M z^R8hxOS|AW^7!JzHPW$TUjjU@OP*#h-bDw)bJ9v+yUPx*oJ;v^-+{VC_c}}R(+Azd z(B0iM9x5%mrg5qBijwKG_2EfZp*JbJx;4Iq0E-NL&I2jKsHl;!U~^4|sB(&(-$WGq zWU6qzQ6ly)Etb-I?uVlyYA}*yjITaE%#^zO@qcP+@eGRgYrIU2LfuG5=LX89nUEkV z(q_onK8qh}*yo6~sjX2d+5qwz;HiWuUICi-WNvsl=2tXcd`~?uau(^jI_Lq$+IIV{ z771wT7=T8$iXg)OoHNhFB!XvS=C`-EJxrdu@h^lwVL z!f?xm_l707@Xb5M1g{BPY&qX)g>{8*JdyhQd#|F-BP&9RJNAc2a%i%~->6gb+A)D--www{%*0dOlXlp!x<9X>Jq;awww5iI7l@;4%c{;I9eM(^Lm>C zI_IU}-c#c);Ky@7l0EP7nQ%l4;B*<15YH$@j_Poz*eD_IzWb133gs*F}lg`fP}X;6qxJEjk7;Bas}AhS{YnZ}cX z73FWEW3IgVFtyi=Zk}6&(=y~uz*nHYJJg3|#?0(( zo)np zpVj6JQkcwcnHsiTd{P(Znz=vfFVn7)QBk)`DVBrD+kFo1*zcpUvA0)VJ{|L6$!M^H zn|G-B8M2KC&|&A3h?u(%qT9F*{Ig#}%pLJpwtX;x`oQ$AWz(=Yxd%p;em0wPPAgp@ zc{L?#I{oZ7hFq|jeHR{lO?NH9V!W;$qg)Ijr9*rqWDK~rZVQ)|l_jjjin|!5K7Sa@V;KWN_Fo$L)|%)xAb7lpJ(ejpCS%Z3;#0zxFN=JA`}HL4q2lC>ZD*MBmw9;ieWjp~ zP{^mKk&F1qx>a&=wK4;h6m1XLkN~=jOohjte>3rBaWgNM-Ff#?b()t- zm+}3|ex6aBgV8~FRl04J0O;4h_(ag~z8bbIBpVLhq^;WW8UwYUpI-v`-I+CJrBghu zt!>n38lxwbuho~3f#=%?158iCrpEq%7C@Xb0I(MACVM`xei10G(7WT6ZY6v^WpM3w ztzOZT9`sTgPy|_ia-ZIN+wO8yB0Quwx}*MsEJSlO>FaCw6t~pe?*c}ZbN2}S`IMLw zcFN*_16~17v(B1OJWL=ls0AKEv&ER7afYT8p%_Bw@x*FSvJCBl_MsVK`{+%;JmUh zq6=SrlK9{_p2V>+O+td(|F8OBu}U|G9=&}}svN+o{k}2L^afF3?r*{pH^oZp5QbjI zG%k&dzwq6T?(kQxk!r6>`GGEQm23H;|n7U7AGY+UH*=KG4*}u3Fn(~c{ejU41ce` zyS?%2TZu{Qh`3gbUnFa8;epy;=PP`A&bpWQc8v1FFQ1E zAXnmNmnesS0S4V9Uxj_?QlTX2eYfkT?8yX2~v4M+;-am|}z zhd#P(uXPkEXIPZK){>c>$dmCf3Uu9Z(ypZ`iJM9jvP8&8J3;iG=(Irv<`8RU=J~^Ma`he__WOwAN?bf6YEwsNP+#-Kh*YxV*^l*JdU_8l$QDrS>pjBUDTe%-D zoYi#*c^y(;bxb~CUJcmI^c;(~8HTFZ*w}1-Tl*QwY_Z+L@Smbmd@##^>uvOP=jiE@ zrQ?krN?(%Kw__r)Rf3EvO*8_l*;nl+i3#iXm6w9Ulr7{6rqVX$s@oY4nldEGG|x9S z(_Z~aD=%rCDP`V-7T{_)W_1=J+x%)?Gu2C4f0CUmpCWO#9G3pr^B4%m>+@Yz*QXwDUL2( z2jf4^P;x`(O%L!0@(kna8rKXgQ`~^AoC~_DSDV+*HgzRt2%m*6e2=`c^iMnRn=I16 zXU{D7ZRoXM%P#Mc>UBN5g zixybz{q9w7uv8N6uvZeWX&E0E$iczN`Fi>kG-XVBOcs@t-hdd_05zW94eKh3{tD_c zZmNiWSv$H;OEnk1`amYg+L!TUze*{L9&E4NcGgGZI#Ll_F z9Imq)DV$H+@LMnl%RRM#o4*b;~QtbGhlK>ycZDd zakAtS)|XGj0y4))r0>+ECQIc$y`ckp`$GPoyjS?7&>NuV*MFU4MZr?65l@)DI-hR% zFy~TmF`55#b_BH)R+8R5>^{gaYV}$xB!7z8uyi8-$?0MqC~AvOWZrGcF2Y!A?1I4=Dc~K{ z!Vux%S{r;!#x@M)w|H?c-;Q^@D)p`Mm?h3o{%M<0v z@Hld1nqTfSqKp^Xd4`#578TehfStMKF5Ac5I(@+e~;P zv-oukdE`bb`T1P^<3pkfo$)S7{A3>11_P<(;{j)U1COe1Aw!zhrqmct`TWD_!8*VF z2IV%HbX3A5oPV8gy6$Q%F4>VzT-FBwQIrRonkl4MHl}K2y{8&t-Qg3 z_tu<%#maw<%C))C^7b|A17EAL&nq=U5pzT#WA8x1*VZsWtwK4XkdvFDvrHy}%PrLW1H<_sE#!pUTC+X^ni2d(*;B z{@W1i#pWHzJeASeBYBRr&hKeXprD-S23IH%gO2X?B&YQjniXcf606&SA7iwyeE={D zN~yhpKp+AiLe-tG7)&}f6_LIMEQk*F+V@${@Xj#YoK;F09fgXH3YsDhYMP;M*K_|; zQBc$yRY_`$>!Fa2>r}wT+|?sasjMwhRfA1A7oK?N6+r@Byl|c`A2tWN6Nx%cJs=(i zw^ibqeTc=q=n}ZgT;Q^X;H8zvlELzO!n1kN+Pb<)#O>`p9ah!R(IAhFW%w!y`r=T? ztfzg<*z9&F(pLjh-7+F#I6l^@HXOioFWL>lNuP3$fy7V#sD4p%(S_^v0@Bhr*6?@X z;nu)_vhl!{8adw?p$5$;{Ix@mVIYMlXSTmsQmH8vxY#BmA7_{S=oIJNsXP>P6!jCt zgBqBt6xJ(WNf1u?4#r=0ZvTrBA6>_>>fYi|XDDtFcP@7~o#kI~3Eb?&p-_! zEc#{BrnF_Abs1;?b#&%G(j%ZJ)g+n-;uN5WJU3e??C|t7?>%Z7P3gm6npe*hCQgXX zHSyaRN9t7Iw5VYY(*)Y%l!v^W&cOolfgBpL*Oq}LGsYUcXnFVJ)6eFq6MwoeG<}rG z=IzKEsf$L^w`_yjH$IjZ6VH6s7xPc?yt6&1<@f&(_U7SG@ZJCTU3Vq7%3bbAL}g0` zSsMGerAT5zg=|@dWXqOq##EGK%f1XViAY5DeS~adnGD&PEHidv7RHQOzSHyBp6B!X zJlF3Z*Ic^FrR#mpd7amJo!9B4H@_&HFwT`TDkB8k5Sq&vwkKDw`thV7vY55ch?hM* zJ?zrA*X&|;^=%%<6O@&$y@AgXIaqMvT8gAea!FFA)jH%ewv6`29}Kh8nKwI~jjzA7 zYfpW1?MF^V?U#8k3)PoTjqaTnkho_w^Kmz}rOr(x`|W|wx`k#g(Lv~RCQl*YS*Kd_qWdUZBfoW*MW+bV>{CQjA;u=5?9HXt#X3ac znt)U6_SJfKwI^(}5x^^vQvvO6bp{ROJmRIj)5uF23ri+`Cr!xI%PeMeg7&(u&$sk@ z@HSWm-o9CM7UowHu>|s{E`n37MA<`aCWNQepGVCRjdj$v$n(#A>1Tfqs9*d#B&u!v z>8JBzcS6;Z`Ht5%cD{Dz?6)V0oEw+BTNF>N`&I2=txcBum2XnVmEXEZ6>bM;x20#{ zJ#FK!7AzH7wWjp%<<*BW?XbHA;FM2MbDn;S+DWauZ)zMvUaI*n#$ho_f48NL{lLC) z?b63o6!+i{&iC?!oI+=*)m2AldAg#-CVg$ig->0@Mv@i-OK7{pqq6n(yacJJpz3w+ zno`2L1#kCw<#+zbgJUjIngKi-Fo{t0qquS{IeFV&*VVo7LN+#N3VOYr@FwBiAa=F- zV;+1Hx**c_y@Tk2pyUhk7CX9H_`2oNa<5OgR)5|OE1&f6{DQFTVj1$(dAzxg*=jyHVBd`2J2?(h-(ciscP9nw9zLR^@e zbL5e*l%rRV5HJe5>>t&2t_ATewLrI6B~{B`yAAzu*c&|I*gn5ZF|5q+UT|Ii==ZlD zPyZRrQ*Kz!jc)w)`_NxmF9j5iShl}=V0X9f@$oL~2i#bb5MFu2=+deTaYPk?hu&ij z>DgT#YQDo87+)zpdk)@Ynd8?uS9nkBUHv-n+Q8q@4|}>t>plgGoZh*rt{&a;`Lvms z94q&hPA9c*toDKR#)HRz!PedP9?6QzWhp~q73pImL$CiJ?XkH7yq)Z5ODXeXwgeTi zA)UwT?{U||KiP6HHFaja$iQpvQJWW_@Z1LxtiY065_ z#1V#f21G%}dCD3xwM^h`2%0qcHeR@udsbXB6$xh~)@YXT4wT<}9U1HawJ(y0`1{sC z7A0WEVN*4{-TK3NP14Ps1AHd_wvER`6;fq1oRkl!^%SoKm468=IIaJy9Dm4Q0&wwpx3H(~ z(v=9E!26YcsV5bia^LhK^jWc&3C81y(7<(3mlYHd3JBYR*iH2 zH#e*{>C+Ee9n#SCnQ)7MyM>xcVYuIY(XBb%OJ~EO<~-6)U4;UH7O`;pUr!E5MBY`>5_u#&^JCsJ!@cieQuaYavFxvfM?cyyvptZ>#mMkm9Nu20R*CNAgu@$& z>zucDr+Tl;7`>Z?vLd8fg_@Kndu$Mqto8<6TDZ--B!zrqX&9&WzD#iB55|~Z;!f{H z-wGbYWZYM64<6L0&^^st%cFcdDN3C+7T{cK7_7 zXQykAA3GL(T^OO^mvLMS*c*t|lZz8k&IlaRlDnJ`{uimHy0?HH@hbf+d35`ONZ+V6 zCuwx6sw<^8)Vi1^ns3wp#yI|IyJCmJ)%&8?78C@%Vs3yII(TATQB9J!sNI*Fmx1M} zzxY`0SeISdT-cauGxGA$Dwp#-oUve_SK5|o`r-3EBj|AJ;t;Ndc(0<&F!K1O7=*%7 zHpM;_aC6~Ylb4W4!329re_!@XzpZ$F48;)jKu;lSy~cS9a)_**xgSP@(&HK3uukXI^FsFn zM?bCnbT&3kKWP%ySk=eR&slL<)gsb|4qS&n##37|SH|8){^%=Tq|~l+kZsAYsmsqyDBz&J?s8^ww?aZ&Yk zba}n$+UO_WEQkZ#lUcXaq@93*GJ#27N|DpP8P9C-_T?U{zPPnNlbdnTtU+C^y+p$g z+GXfuvVvq2So-!QQLTzK=>C|UpVrG1Gh=bZ-{DQy*2LSa^O_IRxn@UD;n$2pCM;eY zH?yn?D^M3RsKn>YR*#h9a5Jizp=hKPxonJ|N`X74VdBq2lrn zSXYU1y?0k{=i4^*cB#2%Djtu`*k!QtOHglWN~RnEE%l^*e7PxAWJ!OI>foDM0P@gHqq$sp7md zgfQW7Vl(g&q-cQY2>%L<>-4|(T`ncjVqfW=g~iEJA1BG{seqDqyjYRBH-FG9Ev^y7 zThZ_OjQzqqDW(_Xz3^|<^8f!~@>Lnm=>IM|_wl#Id<4v)JfL3Bfj4SnmY?8{B-vZ^ z+pC^S%RxKxX9WU^T@sRyuV2^rXw>w+XwoIVcUxQP=16B#->%uN>as`k0SAq{Q)cKU z69)}uc;nsa2h;=sH`=t*sngnxxqm!B#A{m8UXScVt_b0#fLM*XKV&}dnMj$RA(!@l zm@>CUXVa|L{eF$;iM16vah|X~8?zss4XS~6W6EdXO@g|&rw;mT9hEICEmd&KA4rtJ z_wpYCM*i$n^(UQs|Nf@3wF>ZY+1~8=5#pJv!e@&Uezd$vcJ_=XM@V>kBTwF%hF05V zWZ1fu{efBY@FrV$_yj&A6!4y_$aIm%UE#x<7Hr-s`F9&p0I*}+TPIJdY{lS)>|-D6 z*~KJ%B~m24*>KzuzJ_hR^QtX4afJEaI_Ek|JL&3ug@k*K%GTvBHzcj0-&8>P9D`tz z-r)GDFMo*d-v?bdzV9cLcS%2DrKu{C9nSN@Y|T4th9vW6b9Ug&vk%HPNy$^o?8DT$ z-=uajQ|Ni_ejY==9_Hn@OE;RvrOu5%cChVAsjaQGsJ*PZF!nr5pwP2(>f@I+q|&mn zRELyDDY&zLpgULzsZu>$9+Y`fUHC%jImw1IIrXh+2(1pn)bz9mF)2vjx&f10%3-2u zyn&F;r?8CD@{sU>)7FncN5A8z>bfpAfeVgI)n#^nvH^buiH07Mw}O;-AtTR!jZEv} z-7;`&gl67qq#RB$;GvbEik-{R_j&6svO8b@&CL0?gD*`UZn2zL9ZTTP|Hh&F?frxI z-JCVZQ-j4#!{C>;O~d&9A6qS@G~fE~3Xi(MT^g6S?vP#lk6HY_`TT5~ynN=~VCN>_b?AI*d|{7L~WIWqw*T%G2AIeWUiJ zEZ>5uACPefcIb4z>L3bZ;R?gp0N?CHAn$m+$FtfV4BOWBy4yZ@!k#xa?G4A3J$T~E zKe|!X9E74cM<8~p6J7JVb zGh>cE@4a_R6xGC*f8p2yhgBulUYqMr`Df*Xm3I`)Q3@N?ZHd zITqi)7WqNKp~-9Dj|3fJeHOp#_1A9aq{4CSJh9EKrjEl|S409~O=ID4b}v(y<)!y! z9Ju&z-GqNry$>8+Qs$ZEFs3y||DEiTU+DW_QB$n7pu+v(YKf**Qi8_Z_RvUS=^m5u z{>8_j=Jzoq`ao4c`w3h#`vlS%iR}IaL2DD{Mi%R)(i7`|65$OrDADx70q|wT zOJv;ck4Iiw$qW#Wlh3a#6n5O`-p#r_%xh=@N8?+qbJWR!%StZYQ$A1 zzDq+gSvHun2xw``;~$?y4WfKI!1Z2XSb1C^aoP2a%%Z$?Pybgr^!cl%A>?@EVAb8b zsHrkD0y6 z+cXW6h}?4)8>E&|jeZEiW%UG}(vE?)o6f}!hg8XoB_d*LbvY#x{mdvf_eWKj>LNu*TX zX_NEk&#fo#nuNBkgx>FmDOsau^m^hyLub;xGvIa1p!@mR=)QI}_aa1EEUU*ctS{SV zbt^)vQ~h0awHhtAi2CYWJ(~Y0P39f-OYM`7@8J$3JocursYyF%CE|yDz=!^sz)T;H z#s@n?Z~Mox2D_T?zIsdWsME??AE_LR>Ad^AF!HA%_TLNSpYRvL`HbeP-Vy%|U3e+< zU{i^;24#$A&FsVqtD)D^DNf0iZrNDhMWg!QsynSC-^Ylq=6^QQL~ykeb~VCr*qgx#wA|pjL+I^v z8w*J1tK+;&P8HGD>+XA(iuD99t`wOeW>!bOn}-my1w5|^o5x^VZ!+zsQZ5&UG#|c@ z>~>>X7f*|dilVHQRtz0ITlTSC!{XF)MY&d|aDBFng#gcb7X9@pE@CJQ2i=H8+qzYk zjaivz@*3G&y-klvEr(Tuhd-QB-we}f_&Vv7`pce&XV>Ebv{o#68o82sN|SUA-!S68 z^g(om#|rlHB*suKn;rugVV=J8z*^Z%pH&hRxqVx-AsjTX}SMEKd0cCbau_ zVvVvcC{(Mhsc3M`oNIcEBoXL{sW7o+K1sG*S3&Tj}!h*N)Npox7Ho zpL3~ttD5AyQZ#e>i4sZUNBRqzo;xSgr#h;y8c$Jh0p^|IZZA`KvR8*&im)bob|fDr z&2=WdmGwel67UN^mAz1drlxuf9IKb#oNU``@yO6lQb(`f#9mo1xxcu{r>MGP@7$lW z&YQxOYT|e^j^?`sj5~%rFYT2_j~*RuwHuTpwA9*Fumi0}tA~ zNa*deN4=^AwPZ8><=Iyby7WD{Z2wvRVl|0 zR-HMf&OfPRqP!YZ+^0&9NOcNi?!rvDToPx5yG8ok1j9Fz%23rU<9%AN(|7(paQLtP z{PMg@=F2*FJjnkC7I*pGvx9$J`d?qZd^{vE=|>Z~B{4~Q78~qr^@l*H?azK9P}nT+ z%TK@cvCo@EeJEBR%3H&QCe!`uqtD>AiDo=?8M0$tu4u|Uc$GeJ^b5xmdx;OdrGd#Q z&a=sx{e6>|5mo0sC*O@DRuAI$9!$1*B-7_TTFbnBk+O9JFy206R*fld1~>($ndpFE zlzI0k>_^vC1HL5YqkXpj*q{<>bH2N^mndAmh*Z6CmRjQF@ap$5af=h7R8+?CaVM)f z80SURhL=X#?{z+(qc&*aBX90OcshoRdu^flHH*Zmp+NL4Bs`JVBCyLGbXt+Jg&JYitY1`PY+6XI-XNIorn<7Y`j}Kbi9=8u6^lF;=vD)<=-!jr04;T_1 zh%Ue!G>fpfUP}zFP!{BjVl(!Kw3-3?;nch@!Tr6ujAzHI=&joW0ekSh+JJA-azDrT zk82t8etYIEyWPP?Z=5YP)`Ij=n`erwLZktD7c9w253+ z;}S!<3h}~mLmoK>Rxd^A=d@QzRukl;!6mvfRfVdGm|$$=$4ERzX<9?-NBaF4q`yKX zG>j4!E!qsST(iBJd(dVujWW=CfK!MEywG zLAMSwB!$(R;;s}Kv@FLa3(^5TQ=U_<7dT2cY~6QSfm`*QLNstoW4RD`mQG*wXDBV% zCs6_Db(5GV@*v4J67IkA&(ZzQaW4O*kbw$o<-Sbf9__9494XqxaDV&x6MiUsL+@aw zW3Z3iWVN||FsY>G>b-wT5WIh4Lg~q7Z4$fn32tFy^CUF?*}>L>fSSeFJG?=g)4nvC zSKcy0B+|PbIod@BDa=3*SbwEwdy>@dh z0+Zox*hlxXwUcPw9K%W9y;Ys>f+|Ro?;p}E-H2Fm78;pI|IN;?^@HwrZ{A#T8h;r= zWq(iypRsFlflQJb7W=EL9KU;~Ou#s^^$6dll5Ls<@`~Ypxm|tvOhCUP0iqmXtHoR? zkh>p|5e%!b6>lS#@*eW6zg^f~xsK`nl37_s#U)cgC)*Q|9D#m=9&w$@+riJMLpl{u z-pNBnV~H@g<_jqbu*cJNK7=715&zHL<@O`$ z^${6CZ>1z4J971;aXJj)|KulG|LzIhfPjeN7TtVmfh7Bp*4oE{snlYj%A=XbEsBxa zEO->;w*EwXwU3!o*wR)rreJ+b$<*f1j5m6=xTJ?OSOh^Hss@jYQT2o`SMZHRHtRm= z-0^{Bc-wPr_RF-Y#GfowW1O*(L(tMn>#jCB9bR9?+G^V!V{BP-EN!X%+)8@&Ov~Ov zT>nX9@!_G<(B&BzeRgw%K4CKm?W526vAX?k=W3)#jFbFqoPbwdx08cI(v8RP)*0S2 zcXDPgf4Fi4!D-@F_M}H4NUvp*xcX(GW%Cs{djWp{51{!C94J*yE!4Q$ws>NHQDdj5mfXgkpBS9hn0aEjFPN{pYBK0v zM+}i~+h^$TwVBYf<>%x0xSbXsWAiE7r)=4n?xHO1g z%_?@s6A+P*pW@F@d z&)c@e>I>mNKHb~gTWyUw+ph_!5DESHobQO*Pf2apfTZocew~C_ZeGRba zH20r_j)flZR#h@(DHSY%*aWO=0SlgkX5c^8swjjJ z{d@lQDmF{lBcrD zxu?*^N|lshTvji85DHr5ug7zC>!-t_8l%vdcG6W~nKJEFb@oG=G>#r3w?$^Fu1B@0 zRhqm>9ZX>f6YIqmQFw3G5#mn_zFwCo`!}}`^;D20(u5ykk}PMnHwQ@~;pM3H5ZKgf z|G_MePOajY|1V_wh2Q|@2P6d>HKzwH75*2X`^TTUJa67=@_LJ-2Avk(uKtoK_gesE zNgHS$kkr*;dk4DJxLg+pRAM%9X9`%SW8&+OIF`%U<#VjqFeCJ{L!6YE~f$o#_ zj4JQhJjf3-JiypKFwB-JxSW|zf_qTYs<;+)ERI;WEDU=Xr4-}c;OCYV1wP9S8uH#9 zG*Tu0NlfDDg=*!f{B+JLic`|UWs{t0@cQ0s52eD0k>%b>s2>L5J4Pl%8=^fFPe;>h z!8>{P9E;TQeiM`N6hRgZq-*W#;2A>`b)i3L)!{;TZg&NJj$U+dAI5&=7_C^09FEY} zm<04%?d|DVaE%J^6hshM>!T~ZfxSE3T<=an28AtXi2bC}<;z=^WAnU`OCd9N7}&y7 zap#jQ*wq!EMGS%g3litQLNR#q7KD)n-)gPV4vUxsya9?lH zwm{z-q_r^@44Gv}ZXU1ZyfN*s5@bVcar>U~)4Tfb#DiwYQXtsIF7H%C9o!t{p7<_l zx%nf9!@F^`-j8BWqG|(scW=fmb=8hL+U*(htBM4$J4Dc5*!-^45+mSJvTWdCgtS(6 z1lhj%sZUss&fKtX84?VNaG9xqZF&)2i7_>D2J6u^0&SBki>uS#S*&giw2JB~L4Ti0 zn3ugxw~6fe4Cx>AYOaU1WeRvV?nFQsc{+Z~h??wl!TnV-_-89mdppgzL_Gvc1NHZL zM0AkZBzRjMw<&mDzN>of+jU1>`34RLga5F%e~%;4l{=6M@yLVMCq_{AE!e4Yg-q!- zy+%R^zKJY&gkX}g+df;L2gv?EqjBWu1`EDg6bm`?-+kA=J^{!9Va4SJ8qU1bN9 zMRLoXmyy0%VSffkMO2gUz z7G0Z_N~ht(rP9Et?O7Xp|4_zK1dToh00<>AS}y;O(+1#E+&* zjfMNkB%OmXNR|{~c&K%2`UgD1e3FK8v>s!V@X8@vG8aH+wZjz=aB3~2%Zb%ig*U{L zj^H_wi~MpvaJ{uI=Fa+bf>yT3>U6egsH%uu;4L(K;wV`TPLU%t<9R)jbV&2Q_d7-m zd@p9VIX(P|rLph`myPGLZ)3#tiPO;HR6e;P{QevrV>d_1Xh;3kqknXJCjL^2IA5DUX5=))fYqw1?LN6E&;v=lOWxcwvPuh@&RCSI-v(n#fg>YQaY$`nd zRa?Q(+B-dcax8dYNm4!QUiNJdy3kL_21J-3bESMqCo7BorH}tQC-Y?5hlk*|J;4!E zbNBqcO27Vg(0eb8w^P&4b2XnXHmIC@UTm57q=TP2@6^U$7O5sE`A77)8RvEA9%ts!hq z72WKYH8BSsugu=y-G%g?b`b^uXb|UJfFSZ3GZW6p+IrUw=8oIqQ91TX5yJN};C^vAgVb9MSp4ouzAgsT9Zsy)e$vFE^xN49Ll=95cJ6vrkhEW@ak20fw*Ms7!Kz6b;g-5L7Trl^rJ(=xSE zichE}P8@C5HI|%q@NtLe@+_NyV3<9e03p0H(+{n3b$Y<(J!^TwF~nMHseHP>ojz-| zi{E|d^yS=^9>vZNuwUU=-PyV&HuYL1P0m;q<%V9^k72~6k}jA#ssTgKN`dV@NUEIh zfDJsJbIaxYaAMzUu8ayxA@`?;Q@Dc@+kGKQJ6YIdE?-FdVUe_HKfkGuD$Y?SGBj1| zx6gHUUm#BZO5SRDA!HY;pAo$04ulg`h{e2wysCCCVl=8)-9-}>MM0BbB!#dlaj=3O zuiKdp1g*+$vFUiHAwBxc(M1NJ4tZD0{G<4|x_ zemtJTLjRO>ekf4{Cz8aVF{Ka$Sy3Cn3}D5H+kSm=Y09?lZd4tqZ4TlMEaO z!U}5x2$(!Hmg3MIdeIMfi!vKBYGGXKa|O?$XYA3Y!I6|yA9z;|x{r0ejj*49kKnSf z+?icZj)W>Iij*S=TQMZOk5hWQf0Di2u$YKg4Ht=&gl+|*ytw|qqlJhO+j>S?jOM7G zj-%UuO(sRs3OhxXoL-s$jVhLFhXuQ4QtUZ+vdzts&moA^>>HeZ&W-H|$HhfJsY8 zX<1%G@u(*C=$@%Vg7LOI6`7YIdFFL>jI^|jlJn3W+5re7@|K^`^sBDVmviG z1-5r?zY?k2x|!ou?zwK<=7#3I0leD*wlRp3{IpUx%)jb2BhHECvffejTF-M>l`15# zD5^7QuPM?aBd6b{OM8jUg!Sm23$Pw(-LDbJ>~tcpRSstfmh-^tQ_efQYUUMLDm%4z zK+-$<=h9Ueeivka&uufFocUIC0x8=E#q`;?%bsFF(f!$6UZea90z#2m`a|8f zoI!54Q^CxIsamh;gzV7}^kOd1BXMCh3CjKML~QbW>ECG|XGrA7m^r!m%dc7z8^sGd zp`EWRh#t87vKl_0=OR945ySP&L^h9oSkHk65#QR4ZEdT7{aWci4g1^WK!Gv)hAqw@ zg306M+(7gFbJz8=``c6TEBJV9<3MY?@zl%Xkm@~Tmgzb7b1^EtMcU};Wr~+UX&P2Y`A1P{}2p;^7Wc_|9(9;?>FRA&n zIbp9x4X;0Nqh=MlEQRTpoeOE(pWW17Yo`ObM^7PSs3DyWo_tJU?s-83l_5dY@h%s; zAxaNqE52mgbGN?w1p_-McFq@0teNNxbRj4zN!uZbNpRNUrfwInM<0W8H#r#&ufwzd z(HDK4Q~YVv*V@ef-1^VJY{2}X2~{#TgjIZ75{%&5479_K5qjYd2e@Z^{Fprw%1>7B zjn@V1uG6gOdrc4iHTwU4o_E;hZa0~d*#=z}Y%O@k%K~41A`kxnOt@8Q2^^h#(mwKj z;&u#svnY?(J26*OSAtNwpt3K%BBK$%Y zF1%A^lXv`$ceE@Vcy=5Ao9*}8Q-GtO^|ESAAd;Hg^TJa2LzVyQa7!o0z$EOIBEesheILe6Kb(Q>#C8O< zTI=oM9U9ky4_Tuh{L>_82?5%lSq9ZB(i_N~2fY`nD~UK$Wgn--XM%h?g~~WN(WFAX z)rTV@CunL+{!R0ocs=G3fv=)TSvYP(5ecVp#_*emze*8J3aEKU67yU@AjCMKtFT?@ zM=y$;9u=@1jS=BlBW=Fg@MPXvP`y9-SKmm^#5WNsT$$ijpv#Rg(GkF7562wh*CefE zt%L*cKKXL@8;C^K1-kvtY;32GpgyrczA6_MV-D|_=eU1uWasL1i5sBfan zVEsbDYX3B|fOu?;zY}PO6|IQSJ);8vz{zn=Gj*ac_Z-f+8N736Jk1clYs{nUTZZU1 z^ms|7(m5I&lLBM5rhwW+O7vY(r2MqJ-2%A#;_r0>A~lCAR`+SaM2(IQ3E57o+;{_A zF7dq5YSqUp;0pxD6I0vqYD14kK5(xT8J(k<5c!$EZFctQ_SwiPc`#2>C0vo@YrJYY zAf?R1{L^wqYIFQLYwzN-t@>h)i;JfvG2XVEF-?ml9VYToT%-QP>-f8t6Ze1q0_FW` zD8@huP}brp5Jx^|E?KxCUSp>>G@@j`u9dv8xX9>*-(29kG{p_!^kHD99- zwn<_{JEFjr#oWN@wB(4TKL53n;yUUf&!k%#koJ^f0JXKh#TYMrqAuQy=+}KU?7J{c zkl80TxBY52LUna?JZ1}jSAv=6q|E0V_73d;EYoTNzckKI39|+a$-el6f$}Qh|5nL7^In$sX(AqvBy(&m=GyQdnRc)vt>!fN1qVk zGTM@(I)cx(_WYfta??)kc6mI1_XX;2JGoC!6e+9JsTAe)z(Q1vdZSdVxJTNfwc=D0 z_m8Jkjg22~qcW>lTRLlYkbWLv_L#c>gP@{}^dXtMVaq!BNlwwjWBv=BbTL>ar;nsy zj)@nfp4`L|9Xk@e;E}%zWiryVj!6;=J)yV|c~`dBamj^os;L8+sc{woAiFCSI_x?A zBx%$ruv5|PE!QLo5icp0ptVen)*9*Pl9s$OrJ!XrFK8ts{s7U87!IwL2Qa8&agBgQ zFI=wGI1E(5I6;WG(8hg)_g_SWZ?|^(=@KCv$4Hj3T%H=+}rW2DG*Kb4Ee}NAiV9=Z?GF$45F@Jf0s zuGyg1qJaVU_KBX?=yo_?etC^p;FUSn5y_o%$+V9OcycauIaS~1TW)WNc%Zy>cOd6P zE+^Xz5o4v^R@Pc2g3Xw$rN=$-e0c*sv44S zycvx-oRak=E1A_`>4<44HO4O(t!WM#*ymQhd;PL3y5|iit0^S}^OtgYb9lU3cG~?l zaD%V5rxd7Q2#^AKeuaQdSLw(i3>Y149nCw5tpY zFy)q{obrO2M2bkDpjho=eVnYlIc4!Yj2WzXnl{Rf0qc~mFX+ti znsGZkb1XTIz+cbk_RH`gF{%Uhd^F^ylpG{Am%dQGw!wmJ*`!EM7u~5SIpFXKZz#qn zu0{hjg09ip{AzC?xx93hYJi3xwWdpnpHYbK9Jml~IHl!t+n)HgcJN{Z<+Vq7@Zp6V zFSae-3-^wz!u0^C=@WG__9wj!oeIp;UPjRFQL?=p<0Xj#l!7gB8**!$9lGAXx8Y{w zfMPuV#zKaFqKG-P=L-JMnD7Ai0Rl!3RM8``X}g?Sm+zozY>ABbr#O!Y&{G71=dbd4 z?l?>%q&Vk&iBeO~NSD?I*fb5E5z@81rZ$x?ooT?uTejD4 zQ`dwdM|S?O&LH@4+jL+xTURR-O5s}~Ax%#Bz0qROy*<8Dd+eUjWx8+%Etq+TdeSwQ z+*5Qh((8Ninu>j~M*sK-lSVMHH}6)*OR-+Luq=$b9}*3jI&B6el5K{oYBaV(3BIA_ z34zCt$2UIvGVqdSf$qOT2oaN`a_uRkQZ6!7d5C7#eTc1&a9SLIMGC2Hjrc8M=zaE6 zSMd<2(^9?k>i5J(cTiz`S}f)J@=62?DeZ@rq&OH%zD8*Kn@!a?;7Th}r_?=9CXVk^ zDy)u@k*~*LkYaHba-M#{HMS91H-wK6)fk}Kd-%Tv;ddCDhB~s!Q*XoGvRuq1ouO91 zZk;HVH zA`y4V_EFEm-@c_j!^yVKvS<_MzaIRm-RkY_I`4E2N$1D9zw*9#-YF4q z5t4jafYgXh=N*GCLPyb3joD#Nd)nR_=4%6~Uqk<}#3ySujyZP|GPmuuQmq%3V0jW1 zLP&+pZWr4!PYq!!mm$5|3~{He%4a#iE|s`&lcU zHu0EAYwHeK^ZoZs*SmY#=4+=@zxC~3Zrp`*1b$Ww9XvT=ZxZuz8}L;!SbDH9)4yA@ zC!_19KLHcLRxEjwy0|oFL7FUV&>#5bN~z?%zcd76Hin2 z9PU{a&?=Gh{JvEaLKK>lQwFMhDe;;a9*hf06;aZZQ3muXz?6UhDAHZ`2Vtd@2d=!F z_Iz8S2ZM7oqc1>*n0l+rOOfmxy7+($Aa_3-#mMgQrLn?#W3hmkmYqBZ)eL_b!CmdB z!iM->=9>$&)_OG3T}2x{hf+5Ihko>&<~!l!P^ZV(tHK6?~+ z>yEnf@I+rl>m);p@kFL|fN!85K$8QTw_M^Q z@}8H71Wj*>_1Z!I?9@bRoicSu&l0_}vdA1xG&avTFCN zMn@g@6H`Wi0oc_qhV(^QI}Pi~y3veGC~{^*%@gP(&7L36pNu|d7Amz2o%AR-ksFVm zKb!PzFrtGfZO{Af);a|u%L^EH1b*-dbpclFCl(H~%aoy%)mH>|!}e?_Kf)`|(E-^) zyfu;Ar%YCRx*oJPKCRUHF>)F`*U%L9p8m__i_JWOuh3^NmDlZ}W~H75fW9NsQOzJiO89^QJp;-G_Hp z#*}w3=|RL)Ydw5XuDl&uBITT7cz;WdF>D@xxV#XoixzxTfX06w z;Sl9~i0b89R@S%*Y+AY({ibcBJ9;Sn3ylheCm^a*L+H28_SHuas>S7b%g9G6n*AwA ztmdgYF%&&|un*cbnSeJdFsu1TWZ^G|A~@>sp6)DloN<=NnVw1ez6N*Jh)0TbUQ)$B zb6o#3YkKH^l$WLaYf?Y_UjrzcrGo%WsmNTl^JT;}8&>bKt-YP{tBw1J!x6y`02@+@ z=E82(D`|&|0i041I>g|i@R{muRe?YGO($(`Vh(nCU%zz*Gop7>*@IqPXom;el-s_` z!kXyI`8Sh=GPhgGlYA$j_m_nPwz{6$M;0dUed`jkj-Naq71;V(HO|jA-Za9k^AAWt zITq>N;odUhSM@|wz_3IlZd0p7Qs4%oY&ywO zX^R@x+MA`D8p-?C(e}PV)E3QGIK@cDi4?06^g$t;j{oD6LXK^Odd==k+ldoA||#s)go-+30Ii(Q<5> zh~u(&x^VCtE6nSYKIW}9Uy(PK3!hs9r9Z#}D~3Gm9m$KgB3BVhhLVdIJzVEuNpnh> z&t8i%YE))tVM?T&(~_9F{Y_NFPs!ghWG!#6#2Dp7Sq}e23yZY;JiIxQbZPP9;@jf9 zJDTf@$v$SN$G~7+TM~RX6|@D$2JLdN$n=b6cAh(yi#4U3}4B z)k76rgiVo!425Xkkn-z3$S7jnORjG#qhe+-GX@e%U0#$90l9$`<#~ChnO^-sYsy9` zZwMQIdR28!Gdrm_4!aUpW6~{A(dRMcj|86ooTgJ@a2|#cFAeqK`{X!!e^dwW3?)%= zg5<>z9V=jas*aa^bI%Je%uS}|_pR(UPXUTaHY1n56g+%GB;C4o?cP1l(oC}^zBa}t z#A~E&-SuATTw&DiSEQ>wf)ZBNXqg0++|G&G(=1H7?RqZtj713Ug0EwJYzXH(6l2I~ z;q}I3%~bu0W@F0Yl-|t(QkLmNS{&`BhUfBw$$+TT^a12c`6*EQtIUZ z!rg8rP7TWKfLox*$_Wu==XFqW%Tc^Y3^vvn)frFz8!?QW1rh=~7Usswmk^{p3&u&* zlOS17A+`EJ`LJUyBrs}Jn4|%i^zDsJW0SN-DRJ}A(AFUH4i8IY9Ovc|x zLv5$UrK($Xqk|T1i>An0Ck~i2)@kU#3y%fQXg2x3%bHfmD`DCBDR0`b%2ByD!+pSe5!wIwY!0P*e)?|o7Hy>BuuM38K)Mv z$B2ItT_Lz-aYQ)L{eTPRhWM7>R85IP8n!6OLO?AxwaV?l1yZW)c#AnlUJ!!q^N8-h zc4sZ`@Q2u*+98FoKz&9K^;XuBVP4oEOxQfdm?G_qce#Zz6&EgdKPe+{$=`kPIZMs47+esf*wpgTroXF)V}^gf!T% zuB?hdjWmgewk+yEnN7!NCvgkXv$Ws^x#PI`NaigEIoz%Av?P|6yc+C97jg8tLfFa7 zpvmZVBSj$fVP<6Z)0>T{B4IQ}vO80j@x&#&A?1 zPRpI^Y5HN#y)y=mjPiL{w*j$q0@5;yI9MVH$-lk0mQ~dg7tU*-TsO!_=*^hj-idx< z=aM12SB{M?cb(GSDQGP*Wb!-5f**MLVUXxKGhQxGV85!u0c-fFr%=hl5P}}QxuuBZ zDY=%)Nu`azEzL1Ep&KTMr^RMZ+H;wfzAY}n?49vUo-=5{aYWF%f>?@H2;saS#@trZ zMVzGld8)}zd|PXE{!g#Dq+1GOg)ap>FmE{$rnrxS3$h?`$`SfULri$-SsXS$S+t~?-Y)Uy~ctDWqQNoC&A*h=Qxxd{u+3s(U$bO{&pm=iIP`=R?| z^qyAq&X`^Qukrp}}=k$xBv5CFT{^7nD0kw$x-Pv)Rls#!02+JG_Gzq8_8A z67cL0QLcEQ0sEuC&f+`HfW_+K1Xivhv@TYkW4vja?b4{g7+)Qv2TxtL#+kNZYlo!f zadj==Tw088%eVQQ&{&~GUvUsPRGi0`SpjcS*xmS&NBU?lTnImQzed6JP1Ih^zWOGn zLAsTe4=qmC=UaRZN~tD=tT%vCX(ma!my|0SlMbw^`30IYk3W;~fZkNbCl#hMa)MM7 zM~r+R5?raF!t}7%2=N`L`eh~OSnD3MW_KmA)Ai+sxbsdOBavERcrz(NdBry~r-cWS z(WU*jB3qVk>Zu9R3F*)k$=p@mMF-u5*V1VLGG-m$czIM#$#Wc$hb#A&O-NIKEMoeS>w0TjCs_u$ONMivRtwHAAhSim z`11+ck(+b3nj<0FR~NY=jN=Uo!f{bwDZsq1Q8!ze@+#78Iw(M~Sh;WY&S zf16$h<(fn-f2-m`1JM9W*$zv&wd5OPvuK=IQjMh?=0^Bx+h`o8W4}g!)xrqq_(aw3 zXAjJLO3w$?vKAm$QN!;kCs}?*T6yhn30j4B#s=|*L~dUcO{+wN9w2Q$CkI_~iWzKJ zTetcqXFl{z%6kaiauh6Pp<(VQl&QJeWAB<-gTs1`@K%+7ZB!SxYz0?%QNa$vYs_pc zvAV5Ngv+E4qA;6wGb$|EKbK_N?b)s7X>|l+F6Mvd!~z5jW*8H0oR!yEO#$Jr zF7<>QXIP;^KX{KSx~5W+orrM*4x>7-kBatG^)##UyM*sc|L&%nOl~|QnC7NETSJrwkxl%{go!JIPa1iq+6D1kjEcftb8&Y0%;eHL7^hYWx&Zw-6eNkJ<^ zak9Q0-|Df^Pe$c}7v5+&SN_UK^qFR!Xu99R_}mYo3SPfAF49Qf4DY&u8&fID9ZiUc zUye7$^y@J%yDII%f)>ObOKLN&n_l4zE!yiW5kF5nW6qs(kG)K z-jw+9|F!qtQB7uR`|#-KsDpxnQlweHh#*Ms!43flDkv?0fPhFZp(hNABGN;X8kHs@ zAiaemRk{KaIsyTt6Iy72@9~_OGoXOZ;rp%iuCt!`XE0?ydtdvyuehVXt1zLF_|oe*GuiwGfLh zVIlmDv9sOkij+x1?a|eTMrPE@n_ltV2 ziVw?v4%eZ>7uA~FBt-1x3+N{`E`>U=Hd0mkEZhlKSUf(&c9u)=c0+u%bWUz_fS13e zdD(+=1bNgj-!+=xsZ%WYfI=Q_``+S8Bg)?EE8z@F?mmW{RMVl^uJH=v7ENR4q2Z-{ z&(VZK6HQspT^%OY@WvV3V51OKRSDURR`pd;K1Z=j^@+?;xGi#0Kl_w919_Wq z_d66+K}0j|8qB9GB7mKdLd8xc*iA&$GvvzCXmy_ZH5cCp9A7vXIYomNnY~!$aOhqy zO>7+}Q6~5tG6$nPETh@PPa(|l>w?~KJz5jYRa6r(kAlOZe4ldz#MryZkJO>Cl1@QX z@fE+{V>}g&4hXjNm!_=+a@U*aw#SdsR9)o?d-&l986SR|A^vEX{i{pxE-S3WY5v(` z1(FECIb0?Rc6Bq! zxn>xJEHj(w6Oz}4Qwt* zzl}G4a*hJ@navo6mPD*YSe6_R=9<@sRay2tq6_liDX?4mO>j{RLcCTpZ$moX<@{`oN@RR%X>gZ*=De;igN?L~1vQCvPW4#z#%RPXct1ZY6Sh(mvJfWmh0e3qNw}#y%u~Ib52Dv| zt&>A{Q3&P7hv8Q4QdHOvi&|m6WS?h+P|v9tk(L;i5ksoER!Us7A5t7@MAaE8RLO+4 z#K`kE8^*yb8Vg)KcH=E98q1p=;-4LIo3he3_52l?pyBR6HO*k}Gm-~X({A3Lf}txt z>W6WYFP!h<8nUJ&;aV>a?7d|FWbog0?C-WCdMFopVLYMfS6;AJ)Sr5P5#H-hIdtQ8Z_gDm zi|XQ@Ht)%3X@F=m4O%k6P9px$*`a2R{)A*+S&6CR5e3l0BO)}y$QWZ>>>JT9Qv1Rj z5hIJf%8M*L{(F@7KdC1#$}G3-q-p3m#^P;J`;rhXT1Q*$d0cZ)vj3WfbWSXy6tchn zIF!Psu^>QODdLF&)6@ws0*uVTZ%Bwnr#w~kyh+(m{KQ&B5!>Wm|4OmuOFM5h&d;(@ zS(L-EO#tO4FpR^X7a>U4>PznE5(7eoQwULMFwp6h90Ef%Vdbl-wJL)XGY(%|Rtzqc zW26xxv(Li2+%M(4Vuet4KqzNNGY{$Yv(!oKHUv&znUJ&V_0L3xlG^YEnVk~;PLH!O z^-JBWE0&G&!WrZ=%{z5QZJrLF(5U{;R>Re>`I)qtm>EbC3MFJBEoP|21ass25Nzkg zscl}ygJLh}%zW|2khM1!F_Sk_E!G(zMZ8H@(8y1Vq0@us=wfixK9+d<8^KL3Z$%X+ z0(f+HCb#qi5rc6w*yUVJ!Y5_vUQ4VPFXTot!Ef$3t7qe2yjGRWLM3OPxN=p|g^rp$ z4*ntQcKv`O{U>Tg4kg=EO1u+987hgo2e0_symxFE^gNDy3KLR&EBY9c7-`q*K4uo5 z`M_%VVH~W>X}Y!@t0T|M8-vy`s&a+&M^VO0=?x;Qm`6Mxrnie24OfN;ybrS*!uz+q zX2jz7Xh$r~rTQK^V6=t<3U=x(S{6SJ77;NwPb@)}#2$cUc}p`4^BWGzs`NG?ds&7m zP9k-U&nb7?cBA@%>n^!$JCVwwz=eUBrtqYiB|3!p1#uPz4=1Vy(wBsEe!YYPb_%SY zSt48I8Dj)*f3yp5CTCv6WKEePKDy z0cH_(T$=vQK)l0)%1K^@IE{r&rYn>yG@SHl;kN=MLbW62xC)LL=?Z@)4B@IsUg z0m%etMxtpuo8OGPzeJ8D_Ms&nDT~TJB{|$Q>vaIXc&#m-$|9b>UmmLZJRGXp&dyUM z9ili+P+sb{nmWOvjiH-9JY=xH$-e9q(Mq0qA$&%}iol=5n^^McwtI;n;F?HG(Genu zk&_lTlMpmKCRcG{2ZrD4EPOq{M_c)D5?Ddcs$wO7WDWdUR``09vUP4Qc{-xrXsTc! z)TjyqCA!;0A%yn6g}K#=g?l=-xh$G^*Cv0yw>nD2R4=-Vvl$}xA4MDf8cy{d$98G!D=yV={qkk z)>%6l4c(ymXlY!jd}KQFY@Z~SU8^d5sdEm-7!%3M&eLlZYa)|X_pn~%iN7_lQDTaK zMqQs!iILzCpUCU4MH~ulxqiE0U^G@WPR^-eP!qSe{(`2{<2_?F{*^6B`BPodcItMH*s<6yn9Pc;u^UtX*l@9SpEg z9y^W@)d?2DHr+-#Ek9A{2sqv^lj}M(5Vq(iwa`zHly2iqZV#(v-B*zTrH0yD^dDpD z|KbrW!odjK6mITy7UdSA(MUwVFyhqG^as{yui-~zU;LvB^K z0A@dYmxF(0MlWf`%>f;Qi?d%<3|os!M9(F$s~d z9INK+f0JB^|P3le)r0ORQ0G zEJ~*)&@mjTR@#Far;$qXOsHY5Oi1>GWz~5Q-=Qdb&z+(du8|6dh2cZmUnx^oU0AM3 zM&xxLay>rgz#^l@V1(+IZ{skl(u(_ZRyl%F?^+()*`$t>OtZ&UYfO;&`pj98ZtvqF z2X*}{qdhJ9QR6Xa#I%Ews{5s9*%eQhvlY-pm}W{+^3X{jsj&Y$^I7{>Q7^4|6rtBt zN-p`kpyc<{Z};v_-5XG5$JM6$f`wvX_>relf+o{@$KHN6(_Vuctk|*P8^P=p=T)t* zsaopa(5<=@PKdyFI?)6zaVQsC*5-5RyqT6oyNBfhb$Aa_-&6t$qlJn%j1`jYf+ZyH zpOqXAwo`p3S|@m_(oICvif5?Le+2_nS4dXA`c+}+mhz#M!WILT@+=4#cBN(~A>FVl zNa%I-t>CCI+hQv$umZneQD|D7JK^bpb@IO*W;ZR37t&M6g{383x@INc<_gR4U&%JA zy2!L&)iq+uykBMo1_5fW1u#gDdsyasqonA-G@ghiHzTb!7`8q{{CfXw$=_eN= zwAxN7_Yy;|bQ=dmkGsZob@UOegn-*WbXhsEz`n~W;4b*vbs~M9mIOcPQ|+P}tpWCx z?7;zYJo)Jz&a31^$TYC1)LN9GQ}%SOMxS}{EV3=|VQzFpHs&{E6x>idh%AQ>cDu?qdbm(GV6=_CZ z3vc4Ix9q=`ix|PpdphyWVbD`g45wtF2!ETTjFUano$p708VZcF|Gl7|k75Liwx!fq z5&h6yOmu|h&CF=^!U4@G6DvbU3k6fkwvTGrU{zIMw)nSY9VFdYTYE_`#|$>JM+{VZYl5I zDfT~;29BzzYgm}I1BC8eEFBnWC26}s|^IT!cz)xpj3}8@EJ)j4-B5M zisg2#X9}^#?CG!an~XQel5qDo>a~zZBq5hw$26CEPiZE(9%s=TZ?nXn)MJC!1;iYf zoM+t!*utsg(&NbheI139)3w^n5i3Ylr^F4c8aS}(A@?=kNXX|(+$i5*VJj-m=W2*j zQ~eN(N8PG@P{g%(^4j?9BkY`}1}&{mEZ1ytP4un7+TM%ax%+2dmW#p3Vm4E5{DarN>4eBc2Z4MIVQQ6WS}+NLIwnZ)TuG|ltK~;S(o3&g?y@>MOhl( z*gwnV6D<#I5;jo{=G2qxa#t*jyS5L1R;$=T>Nn&wLRo%+z+x|+^d#82A`olNRN5aN zb9SgldcjIw!xF_sVqFdqi>00Q?OQXGoBD^IavVRD?a{A4hOTiSs

      +eDlSEgLYle6i9LQY#X!dKoKV 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 e>{GP5R*8WU{~OmlP=zQ@c#i1))tij literal 0 HcmV?d00001 diff --git a/docsource/images/gateway_registration_store.png b/docsource/images/gateway_registration_store.png new file mode 100644 index 0000000000000000000000000000000000000000..997151562d1687e234ea5d74e21a880863714587 GIT binary patch literal 257629 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

      R$6-7m$=Qm5xY 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 z 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 literal 0 HcmV?d00001 diff --git a/docsource/overview.md b/docsource/overview.md new file mode 100644 index 0000000..0800c72 --- /dev/null +++ b/docsource/overview.md @@ -0,0 +1,158 @@ +## Overview + +The MarkMonitor AnyCA Gateway REST plugin extends the certificate lifecycle capabilities of the +MarkMonitor SSL certificate service to Keyfactor Command via the Keyfactor AnyCA Gateway REST. It +implements `IAnyCAPlugin` and is loaded as a DLL extension by the AnyCA Gateway REST host process — +it is not a standalone service. See [configuration.md](configuration.md) for full installation and +configuration details, and [DEVELOPMENT.md](../DEVELOPMENT.md) for design notes, local development, +and testing. + +The plugin supports the following capabilities: + +* **CA Synchronization** — Downloads all certificate orders visible to the configured MarkMonitor + organization and imports the issued certificates (and their chains) into Keyfactor Command. Orders + that have not yet produced a certificate are mapped to the appropriate pending/failed status + rather than imported as certificates. +* **Certificate Enrollment** — Submits a new MarkMonitor certificate order for each of the SSL + product types MarkMonitor exposes (see the [product IDs](configuration.md#product-ids) table). A + process-local dedup guard prevents Command retries from creating duplicate orders. +* **Renewal / Reissue** — MarkMonitor has no dedicated "renew in place" enrollment endpoint through + this plugin, so a `RenewOrReissue` enrollment places a **new** order and then revokes the prior + certificate once the replacement has been created successfully. +* **Certificate Revocation** — Revokes a previously issued certificate, with a cross-organization + ownership check that refuses to revoke an order belonging to a different organization than the one + the CA connector is configured for. + +MarkMonitor's SSL API is backed by DigiCert (the only certificate `provider` its API currently +supports), so issued certificates chain up to DigiCert roots. + +## Authentication Model + +Unlike some AnyCA plugins, MarkMonitor uses **two** credentials together: + +* An **API key**, sent as the `X-API-KEY` request header on the authentication call. +* A **service-account username and password**, exchanged at `/auth/v1/auth/authenticate` for a + short-lived **bearer token**. All subsequent API calls carry that bearer token. + +The bearer token is cached in memory for the lifetime of the plugin's client and refreshed +automatically shortly before it expires. There is no OAuth client-credentials mode. See +[DEVELOPMENT.md](../DEVELOPMENT.md#request-authentication) for details. + +## MarkMonitor CA Certificates + +Before the gateway can register a CA backed by this plugin, the Keyfactor Command server (and the +AnyCA Gateway REST host) must trust the issuing CA chain. MarkMonitor's default issuing CA +(`provider`) is **DigiCert**, so download the appropriate root and intermediate CA certificates from + and import them into the appropriate +Windows certificate stores on the gateway host (**Trusted Root Certification Authorities** for the +root CA and **Intermediate Certification Authorities** for any subordinates). See +[configuration.md](configuration.md#gateway-registration) for the full Gateway Registration +walkthrough. + +## Troubleshooting + +### Enrollment succeeds but the certificate never arrives immediately + +**Symptom** + +An enrollment returns successfully but the certificate is not delivered inline — Command shows the +request in a pending/external-validation state. A later synchronization picks the certificate up. + +**Root cause** + +This is expected. MarkMonitor SSL orders require Domain Control Validation (DCV) — and, in the +current test configuration, manual email approval — before DigiCert issues the certificate. A newly +placed order comes back with MarkMonitor status `CREATED`, which the plugin maps to Keyfactor's +`EXTERNALVALIDATION` (accepted, still pending) rather than a hard failure. Once the order reaches +`DIGI_ISSUED`, the next incremental CA sync transitions the record to `GENERATED` and the +certificate becomes available in Command. See the status mapping table in +[DEVELOPMENT.md](../DEVELOPMENT.md#order-status-mapping). + +**Mitigation** + +No action needed beyond completing DCV/approval on the MarkMonitor side. The certificate is imported +on the next sync cycle after issuance. + +### An ECC CSR is rejected at enrollment with an "explicit curve parameters" error + +**Symptom** + +Enrolling with an ECC key fails immediately with an error stating the CSR uses explicit curve +parameters instead of a named curve. + +**Root cause** + +MarkMonitor's DigiCert-backed products silently reject an ECC CSR whose public key encodes the curve +with **explicit parameters** (the curve's prime/coefficients/base point spelled out) rather than a +**named-curve OID** (e.g. P-256/`secp256r1`). The order reaches a failed status almost immediately +with no reason surfaced anywhere in MarkMonitor's API, history, or order details. CA/Browser Forum +baseline requirements disallow explicit parameters for publicly trusted certificates. The plugin +validates this at enrollment time and rejects such a CSR with an explicit, actionable error rather +than submitting an order that will fail invisibly. + +**Mitigation** + +Regenerate the CSR with a named curve. `openssl req -in your.csr -noout -text` should show +`ASN1 OID: prime256v1` (named curve) rather than explicit `Prime:` / `A:` / `B:` / `Generator:` +fields. + +### "An identical enrollment … was already submitted" warning + +**Symptom** + +A retried enrollment logs a warning that an identical enrollment was already submitted, and returns +the original result instead of placing a new order. + +**Root cause** + +This is by design. The plugin keeps a short-lived, process-local dedup cache keyed on +organization + product + subject + CSR. When Keyfactor Command retries an `Enroll` call (because the +first response was lost to a timeout or dropped connection, or because the first call is still in +flight), the retry awaits the original in-flight/just-completed result instead of creating a +duplicate MarkMonitor order. The cache window is five minutes and is not durable across gateway +restarts — it guards the narrow retry window only. + +**Mitigation** + +None needed. A genuinely new request (different CSR/subject) is unaffected. A failed attempt is not +cached, so a retry after a real failure gets a fresh attempt. + +### "Refusing to revoke order … it belongs to a different organization" + +**Symptom** + +A revocation fails with an error stating the order belongs to a different organization than the +configured one. + +**Root cause** + +Before revoking, the plugin resolves the CA connector's configured `OrgId` to a GUID, fetches the +order, and compares the order's owning organization against it. MarkMonitor's own +`ignoreOrgCheck=false` default only guards against revoking an order belonging to a different +reseller account entirely — it has no notion of the specific sub-organization this connector is +scoped to. This matters most for `RenewOrReissue`, where the order ID being revoked comes from +Command's certificate store rather than from this org's own enrollment. + +**Mitigation** + +Confirm the CA connector's `OrgId` matches the organization that owns the certificate. If `OrgId` is +left blank, the ownership check is *skipped* (and logged as a warning) for `Ping`/sync, but `Revoke` +refuses to run at all without an `OrgId` configured. + +### Revocation reason code is not reflected in MarkMonitor + +**Symptom** + +A certificate is revoked with a specific RFC 5280 reason code in Command, but MarkMonitor shows no +reason. + +**Root cause** + +MarkMonitor's revoke action (`PATCH /certs/v1/order/{id}/revoke`) has no field for a revocation +reason code — its request schema accepts only cert/`ignoreOrgCheck`/`additionalEmails`. A non-default +reason is logged (so it is visible that the reason was received but could not be forwarded) rather +than silently dropped, but it cannot be sent to MarkMonitor. + +**Mitigation** + +None available at the API level. \ No newline at end of file diff --git a/integration-manifest.json b/integration-manifest.json index 8421822..37abf51 100644 --- a/integration-manifest.json +++ b/integration-manifest.json @@ -1,47 +1,111 @@ { - "$schema": "https://keyfactor.github.io/integration-manifest-schema.json", - "integration_type": "anyca-plugin", - "name": "MarkMonitor AnyCA REST Gateway Plugin", - "status": "pilot", - "support_level": "kf-supported", - "link_github": true, - "update_catalog": true, - "description": "MarkMonitor plugin for the AnyCA REST Gateway framework", - "gateway_framework": "24.2.0", - "release_dir": "markmonitor-cagateway/bin/Release/net6.0", - "about": { - "carest": { - "ca_plugin_config": [ - { - "name": "ClientSecret", - "description": "Client Secret for Generating Bearer Token" - }, - { - "name": "MarkMonitorApiClient", - "description": "MarkMonitor API Client Name" - }, - { - "name": "BaseUrl", - "description": "Base Url for MarkMonitor API such as https://url:8443" - }, - { - "name": "MarkMonitorCaId", - "description": "MarkMonitor Ca Id. Example would be 2. In MarkMonitor Onboard UI, click edit on the Ca and look at the id in the Url." + "$schema": "https://keyfactor.github.io/integration-manifest-schema.json", + "integration_type": "anyca-plugin", + "name": "Markmonitor AnyCA REST Gateway Plugin", + "status": "pilot", + "support_level": "kf-supported", + "link_github": true, + "update_catalog": true, + "description": "Markmonitor plugin for the AnyCA REST Gateway framework", + "gateway_framework": "25.5.0", + "release_dir": "markmonitor-caplugin/bin/Release", + "release_project": "markmonitor-caplugin/markmonitor-caplugin.csproj", + "about": { + "carest": { + "ca_plugin_config": [ + { + "name": "ApiKey", + "description": "The API Key for the MarkMonitor API" + }, + { + "name": "Username", + "description": "Username for the MarkMonitor API service account" + }, + { + "name": "Password", + "description": "Password for the MarkMonitor API service account" + }, + { + "name": "BaseUrl", + "description": "The Base URL for the MarkMonitor API - Usually either https://api.markmonitor.com" + }, + { + "name": "OrgId", + "description": "The name of the MarkMonitor Organization to use for the API calls (ex: MarkMonitor). You can also use the Organization ID in GUID format." + }, + { + "name": "Enabled", + "description": "Flag to Enable or Disable gateway functionality. Disabling is primarily used to allow creation of the CA prior to configuration information being available." + }, + { + "name": "TimeoutSeconds", + "description": "The HTTP request timeout, in seconds, for calls to the MarkMonitor API (1-120). Default is 120." + }, + { + "name": "PageSize", + "description": "The number of certificate orders requested per page during synchronization (1-500). Default is 100." + }, + { + "name": "ForceCompleteSync", + "description": "When true, bypasses the skip-unchanged optimization and re-emits every order on every synchronization. Default is false." + }, + { + "name": "PickupRetries", + "description": "How many times to poll a freshly-created order for issuance before returning it in its still-pending state (0-20). 0 disables polling. Default is 5." + }, + { + "name": "PickupDelaySeconds", + "description": "The delay, in seconds, between issuance pickup polls (0-60). Default is 10." + } + ], + "enrollment_config": [ + { + "name": "AdditionalEmails", + "description": "List of 0 or more comma separated email addresses to send the certificate to via email after generation." + }, + { + "name": "MarkmonitorGroup", + "description": "The name or GUID of a Markmonitor group to use for the certificate request." + }, + { + "name": "MarkmonitorContact", + "description": "The name or GUID of a Markmonitor contact to use for the certificate request. Will use default Markmonitor organization contact if not specified." + }, + { + "name": "DCVMethod", + "description": "The method to use for Domain Control Validation (DCV). Valid values are EMAIL, DNS_CNAME_TOKEN, HTTP_TOKEN, DNS_TXT_TOKEN. Default is EMAIL." + }, + { + "name": "comments", + "description": "Comments to attach to the MarkMonitor order. Default is \"Requested via Keyfactor Command\"." + }, + { + "name": "locale", + "description": "Locale to use for the MarkMonitor order. Default is \"en\"." + }, + { + "name": "provider", + "description": "The certificate provider to use for the order. Default is \"DIGICERT\" (currently the only provider MarkMonitor's API supports)." + }, + { + "name": "RenewalWindowDays", + "description": "For a RenewOrReissue enrollment, how many days before its expiration a prior certificate must be within before it is revoked after being replaced. Outside this window, the prior certificate is left unrevoked and the request is treated like a plain new issuance. Default is 90." + } + ], + "product_ids": [ + "SslOvBasic", + "SslEvBasic", + "SslDvGeotrust", + "SslDvThawte", + "SslOvThawteWebserver", + "SslEvThawteWebserver", + "SslOvGeotrustTruebizid", + "SslEvGeotrustTruebizid", + "SslOvSecuresite", + "SslEvSecuresite", + "SslOvSecuresitePro", + "SslEvSecuresitePro" + ] } - ], - "enrollment_config": [ - { - "name": "NumberOfDaysValid", - "description": "OPTIONAL: The number of days of validity to use when requesting certs. If not provided, default is 365." - } - ], - "product_ids": [ - "ca", - "code-signing", - "https", - "tls-client", - "trusted" - ] } - } -} +} \ No newline at end of file diff --git a/justfile b/justfile new file mode 100644 index 0000000..93f5bc5 --- /dev/null +++ b/justfile @@ -0,0 +1,128 @@ +# Ad-hoc MarkMonitor API helpers for manual cleanup/inspection during development. +# +# Requires: just, curl, jq +# Requires env vars (loaded automatically from a root .env, see TestConsole/README.md): +# MARKMONITOR_BASE_URL, MARKMONITOR_API_TOKEN, MARKMONITOR_USERNAME, MARKMONITOR_PASSWORD +# +# Order IDs throughout are MarkMonitor's GUID resourceId (the `id` field from the API), NOT the +# short order number from confirmation emails - that number isn't exposed anywhere in this API. +# Use find-order/list-orders to go from a common name to the real GUID first. + +set dotenv-load := true + +# List available commands +default: + @just --list + +# Fetch a fresh bearer token (used internally by the other recipes) +[private] +_auth: + #!/usr/bin/env bash + set -euo pipefail + curl -s -X POST "$MARKMONITOR_BASE_URL/auth/v1/auth/authenticate" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Content-Type: application/json" \ + -d "{\"username\":\"$MARKMONITOR_USERNAME\",\"password\":\"$MARKMONITOR_PASSWORD\"}" \ + | jq -r .token + +# List every organization visible to this API key +list-orgs: + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + curl -s "$MARKMONITOR_BASE_URL/certs/v1/organization" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" \ + | jq -r '["ORG_ID","NAME"], (.content[] | [.id, .name]) | @tsv' + +# List orders for an organization GUID, optionally comma-separated statuses (e.g. DIGI_PENDING,CREATED) +list-orders org_id statuses="": + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + URL="$MARKMONITOR_BASE_URL/certs/v1/order?organizationId={{org_id}}&size=100" + if [ -n "{{statuses}}" ]; then URL="$URL&statuses={{statuses}}"; fi + curl -s "$URL" -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" \ + | jq -r '["ORDER_ID","STATUS","CREATED","COMMON_NAME"], (.content[] | [.id, .status, .dateCreated, .cert.commonName]) | @tsv' + +# Sweep every organization for orders still in a pending/billable state +list-pending: + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + PENDING_STATUSES="CREATED,DIGI_PENDING,DIGI_PROCESSING,DIGI_NEEDS_CSR,DIGI_NEEDS_APPROVAL,DIGI_WAITING_PICKUP,REISSUE_PENDING,DIGI_REISSUE_PENDING,REISSUE_REQUEST_PENDING" + curl -s "$MARKMONITOR_BASE_URL/certs/v1/organization" -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" \ + | jq -r '.content[] | [.id, .name] | @tsv' \ + | while IFS=$'\t' read -r org_id org_name; do + curl -s "$MARKMONITOR_BASE_URL/certs/v1/order?organizationId=$org_id&statuses=$PENDING_STATUSES&size=100" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" \ + | jq -r --arg org "$org_name" '.content[] | [$org, .id, .status, .dateCreated, .cert.commonName] | @tsv' + done \ + | (echo -e "ORG\tORDER_ID\tSTATUS\tCREATED\tCOMMON_NAME"; cat) | column -t -s $'\t' + +# Find orders by exact common name +find-order common_name: + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + curl -s "$MARKMONITOR_BASE_URL/certs/v1/order?commonNames={{common_name}}" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" \ + | jq -r '["ORDER_ID","STATUS","CREATED","COMMON_NAME"], (.content[] | [.id, .status, .dateCreated, .cert.commonName]) | @tsv' + +# Get full order detail by GUID +get-order order_id: + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + curl -s "$MARKMONITOR_BASE_URL/certs/v1/order/{{order_id}}" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" | jq . + +# Cancel an order by GUID (valid for orders that haven't issued yet) +cancel order_id: + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + curl -s -X PATCH "$MARKMONITOR_BASE_URL/certs/v1/order/{{order_id}}/cancel" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" -H "Content-Type: application/json" -d '{}' \ + | jq -r '.status // .' + +# Revoke an order by GUID (only valid for already-issued certs) +revoke order_id: + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + curl -s -X PATCH "$MARKMONITOR_BASE_URL/certs/v1/order/{{order_id}}/revoke" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" -H "Content-Type: application/json" -d '{}' \ + | jq -r '.status // .' + +# Find an order by common name and cancel it in one step (fails if there's more than one match) +cancel-by-name common_name: + #!/usr/bin/env bash + set -euo pipefail + BEARER=$(just _auth) + MATCHES=$(curl -s "$MARKMONITOR_BASE_URL/certs/v1/order?commonNames={{common_name}}" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER") + COUNT=$(echo "$MATCHES" | jq -r '.content | length') + if [ "$COUNT" -eq 0 ]; then echo "No order found for {{common_name}}"; exit 1; fi + if [ "$COUNT" -gt 1 ]; then + echo "More than one order matches {{common_name}} - use 'just cancel ' directly:" + echo "$MATCHES" | jq -r '.content[] | [.id, .status, .dateCreated] | @tsv' + exit 1 + fi + ORDER_ID=$(echo "$MATCHES" | jq -r '.content[0].id') + echo "Cancelling $ORDER_ID ({{common_name}})..." + curl -s -X PATCH "$MARKMONITOR_BASE_URL/certs/v1/order/$ORDER_ID/cancel" \ + -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" -H "Content-Type: application/json" -d '{}' \ + | jq -r '.status // .' + +# Preview the docs/ GitHub Pages site at http://localhost:4000/markmonitor-caplugin/ (needs Docker) +docs-preview: + docker rm -f markmonitor-docs-preview 2>/dev/null || true + docker run -d --name markmonitor-docs-preview \ + -v "{{justfile_directory()}}/docs:/srv/jekyll" \ + -p 4000:4000 \ + jekyll/jekyll:latest \ + bash -c "bundle install && bundle exec jekyll serve --host 0.0.0.0" + @echo "Building... tail with 'docker logs -f markmonitor-docs-preview', then open http://localhost:4000/markmonitor-caplugin/" + +# Stop the docs preview container started by `just docs-preview` +docs-preview-stop: + docker rm -f markmonitor-docs-preview diff --git a/markmonitor-cagateway.sln b/markmonitor-cagateway.sln deleted file mode 100644 index a53e910..0000000 --- a/markmonitor-cagateway.sln +++ /dev/null @@ -1,38 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31729.503 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "markmonitor-cagateway", "markmonitor-cagateway\markmonitor-cagateway.csproj", "{9D2D6ED9-4626-430C-879D-0FE0FEBED146}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{431498A1-F30A-4307-9FBF-B1D634326444}" - ProjectSection(SolutionItems) = preProject - CHANGELOG.md = CHANGELOG.md - integration-manifest.json = integration-manifest.json - readme_source.md = readme_source.md - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestConsole", "TestConsole\TestConsole.csproj", "{BE76E7C9-7DDE-49CD-8428-8256739BAD93}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|Any CPU.Build.0 = Release|Any CPU - {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5D2E21F6-120F-4B71-A596-991879B03943} - EndGlobalSection -EndGlobal diff --git a/markmonitor-cagateway/Client/MarkMonitorClient.cs b/markmonitor-cagateway/Client/MarkMonitorClient.cs deleted file mode 100644 index 3905b2e..0000000 --- a/markmonitor-cagateway/Client/MarkMonitorClient.cs +++ /dev/null @@ -1,849 +0,0 @@ -using System.Collections.Concurrent; -using System.Net.Http.Headers; -using System.Text; -using Keyfactor.AnyGateway.Extensions; -using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; -using Keyfactor.Logging; -using Keyfactor.PKI.Enums.EJBCA; -using Keyfactor.PKI.PEM; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Org.BouncyCastle.Pkcs; -using Org.BouncyCastle.Tls; - -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; - -public class MarkMonitorClient -{ - private readonly HttpClient _httpClient; - private readonly ILogger _logger; - private string _apiKey; - private string _bearerToken; - private string _password; - private string _username; - - public MarkMonitorClient(string baseUrl, string apiKey, string username, string password, bool validateSsl = true) - { - BaseUrl = baseUrl; - _logger = LogHandler.GetClassLogger(GetType()); - _apiKey = apiKey; - _username = username; - _password = password; - - var handler = new HttpClientHandler { UseCookies = false }; - - if (!validateSsl) - { - _logger.LogWarning("SSL certificate validation is disabled for {BaseUrl}", baseUrl); - handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true; - } - - - _httpClient = new HttpClient(handler); - // _ = AuthenticateAsync(); - } - - public string BaseUrl { get; } - - private bool ValidateConfiguration() - { - if (string.IsNullOrEmpty(_apiKey)) - throw new ConfigurationValidationException("API Key is required."); - - if (string.IsNullOrEmpty(_username)) - throw new ConfigurationValidationException("Username is required."); - - if (string.IsNullOrEmpty(_password)) - throw new ConfigurationValidationException("Password is required."); - - return true; - } - - public async Task AuthenticateAsync(string apiKey = null, string username = null, string password = null) - { - _logger.MethodEntry(); - if (!string.IsNullOrEmpty(apiKey)) - { - _logger.LogDebug("Setting API Key"); - _apiKey = apiKey; - } - - if (!string.IsNullOrEmpty(username)) - { - _logger.LogDebug("Setting username"); - _username = username; - } - - if (!string.IsNullOrEmpty(password)) - { - _logger.LogDebug("Setting password"); - _password = password; - } - - _logger.LogDebug("Calling ValidateConfiguration"); - var isValid = ValidateConfiguration(); - if (!isValid) throw new ConfigurationValidationException("Invalid configuration"); - - _logger.LogDebug("Setting \"X-API-KEY\" header"); - _httpClient.DefaultRequestHeaders.Add("X-API-KEY", _apiKey); - var requestBody = new TokenRequest - { - Username = _username, - Password = _password - }; - - var requestUrl = $"{BaseUrl}/auth/v1/auth/authenticate"; - _logger.LogInformation("Authenticating with MarkMonitor API at {RequestUrl}", requestUrl); - - _logger.LogDebug("Sending authentication request"); - var response = await _httpClient.PostAsync(requestUrl, - new StringContent(JsonConvert.SerializeObject(requestBody), Encoding.UTF8, "application/json")); - - _logger.LogDebug("Reading authentication response"); - response.EnsureSuccessStatusCode(); - var content = await response.Content.ReadAsStringAsync(); - - _logger.LogTrace("Authentication response code: {ResponseCode}", response.StatusCode); - if (response.IsSuccessStatusCode) - { - _logger.LogDebug("Deserializing token response"); - var tokenResponse = JsonConvert.DeserializeObject(content); - _bearerToken = tokenResponse.BearerToken; - _logger.LogDebug("Bearer token received and valid for {TokenExpiration} seconds", - tokenResponse.ExpiresIn); - _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _bearerToken); - } - else - { - var errMsg = BuildErrorString(content); - _logger.LogError("Authentication failed: {EMessage}", errMsg); - throw new Exception(errMsg); - } - - _logger.LogInformation("Authentication successful"); - } - - public async Task GetCertificateInventoryAsync(string caId, string sort, int limit, - BlockingCollection certificatesBuffer, CancellationToken cancelToken) - { - _logger.MethodEntry(); - try - { - EnsureAuthenticated(); - _logger.LogInformation("Retrieving certificate inventory from MarkMonitor"); - var certificateOrders = - await ListCertificateOrdersAsync(0, caId, sort, limit); //todo: providerId support??? - _logger.LogDebug("Retrieved '{CertificateCount}' certificate orders", certificateOrders.Count); - - var numberOfCertificates = 0; - foreach (var certificateDetail in certificateOrders) - { - _logger.LogInformation("Adding certificate {CertificateId} to buffer", certificateDetail.Id); - var certStatus = MarkMonitorCertificateStatusToCAStatus(certificateDetail); - _logger.LogTrace("Certificate {CertificateId} status: {CertificateStatus}", certificateDetail.Id, - certStatus); - - _logger.LogDebug("Converting certificate {CertificateId} revocation status {Status}", - certificateDetail.Id, certificateDetail.Cert.RevokeStatus); - DateTime? revocationDate = null; - if (certificateDetail.Cert.RevokeStatus == "REVOKED") - { - _logger.LogDebug("Certificate {CertificateId} is revoked", certificateDetail.Id); - revocationDate = Convert.ToDateTime(certificateDetail.Cert.DateValidUntil); - } - - certificatesBuffer.Add( - new AnyCAPluginCertificate - { - CARequestID = certificateDetail.Id, - Certificate = certificateDetail.Cert.EndEntityCert, - Status = certStatus, - ProductID = certificateDetail.CertType, - RevocationDate = revocationDate - }, cancelToken); - numberOfCertificates++; - _logger.LogTrace("Total certificates added to buffer: {NumberOfCertificates}", numberOfCertificates); - } - - _logger.LogInformation("Retrieved {NumberOfCertificates} certificates", numberOfCertificates); - return numberOfCertificates; - } - catch (OperationCanceledException) - { - _logger.LogInformation("Certificate inventory retrieval cancelled"); - throw; // Rethrow the cancellation exception to ensure it's propagated - } - catch (Exception e) - { - _logger.LogError("An error has occurred: {EMessage}", e.Message); - return 0; - } - finally - { - certificatesBuffer.CompleteAdding(); // Ensure buffer is completed even on cancellation - _logger.MethodExit(); - } - } - - private List BuildQueryString(int providerId, string orgId, string sort, int limit, int page) - { - _logger.MethodEntry(); - var query = new List(); - if (page > 0) query.Add($"page={page}"); - if (limit > 0) query.Add($"size={limit}"); - if (!string.IsNullOrEmpty(sort)) query.Add($"sort={sort}"); - if (providerId > 0) query.Add($"providerId={providerId}"); - if (!string.IsNullOrEmpty(orgId)) query.Add($"organizationId={orgId}"); - _logger.MethodExit(); - return query; - } - - private List BuildListOrgsQueryString(string name = "", string sort = "", int limit = 0, int page = 0) - { - _logger.MethodEntry(); - var query = new List(); - if (page > 0) query.Add($"page={page}"); - if (limit > 0) query.Add($"size={limit}"); - if (!string.IsNullOrEmpty(sort)) query.Add($"sort={sort}"); - if (!string.IsNullOrEmpty(name)) query.Add($"name={name}"); - - _logger.LogTrace("Query string: {Query}", query); - _logger.MethodExit(); - return query; - } - - public async Task> ListCertificateOrdersAsync(int providerId, string orgId, string sort, - int limit) - { - _logger.MethodEntry(); - EnsureAuthenticated(); - var output = new List(); - try - { - _logger.LogInformation("Retrieving certificate orders from MarkMonitor"); - var currentPage = 0; - var allPagesDownloaded = false; - - do - { - var nextUrl = - $"{BaseUrl}/certs/v1/order"; - _logger.LogTrace("Base URL: {BaseUrl}", nextUrl); - - _logger.LogDebug("Building query string"); - var query = BuildQueryString(providerId, orgId, sort, limit, currentPage); - if (query.Count > 0) nextUrl += "?" + string.Join("&", query); - - _logger.LogTrace("Getting page \'{CurrentPage}\' of \'{Limit}\')", currentPage, limit); - - _logger.LogDebug("Getting certificate orders from MarkMonitor {NextUrl}", nextUrl); - var response = await _httpClient.GetAsync(nextUrl); // Pass the token here - - _logger.LogDebug("Reading response content"); - var content = await response.Content.ReadAsStringAsync(); - - if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); - - _logger.LogDebug("Deserializing response content to MarkMonitorListOrdersResponse"); - var certificateListResponse = JsonConvert.DeserializeObject(content); - output.AddRange(certificateListResponse.Content); - currentPage++; - allPagesDownloaded = currentPage >= certificateListResponse.MarkMonitorPage.TotalPages; - } while (!allPagesDownloaded); - - return output; - } - catch (OperationCanceledException) - { - _logger.LogInformation("Certificate inventory retrieval cancelled"); - throw; // Rethrow the cancellation exception to ensure it's propagated - } - catch (Exception e) - { - _logger.LogError("An error has occurred: {EMessage}", e.Message); - return null; - } - finally - { - _logger.MethodExit(); - } - } - - public async Task> ListOrganizationsAsync(int page = 0, int limit = 0, - string name = "") - { - _logger.MethodEntry(); - EnsureAuthenticated(); - var output = new List(); - try - { - _logger.LogInformation("Retrieving organizations from MarkMonitor"); - var currentPage = 0; - var allPagesDownloaded = false; - - do - { - var nextUrl = - $"{BaseUrl}/certs/v1/organization"; - - _logger.LogTrace("Base URL: {BaseUrl}", nextUrl); - - _logger.LogDebug("Building query string"); - var query = BuildListOrgsQueryString(name, "", limit, currentPage); - if (query.Count > 0) nextUrl += "?" + string.Join("&", query); - - _logger.LogTrace("Getting page \'{CurrentPage}\' of \'{Limit}\')", currentPage, limit); - - _logger.LogDebug("Getting organizations from MarkMonitor {NextUrl}", nextUrl); - var response = await _httpClient.GetAsync(nextUrl); // Pass the token here - - _logger.LogDebug("Reading response content"); - var content = await response.Content.ReadAsStringAsync(); - - if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); - - _logger.LogDebug("Deserializing response content to MarkMonitorListOrgResponse"); - var orgListResponse = JsonConvert.DeserializeObject(content); - - _logger.LogDebug("Adding organizations to output"); - output.AddRange(orgListResponse.Content); - currentPage++; - _logger.LogTrace("Total organizations added to output: {OutputCount}", output.Count); - allPagesDownloaded = currentPage >= orgListResponse.MarkMonitorPage.TotalPages; - } while (!allPagesDownloaded); - - return output; - } - catch (OperationCanceledException) - { - _logger.LogInformation("Organization retrieval cancelled"); - throw; // Rethrow the cancellation exception to ensure it's propagated - } - catch (Exception e) - { - _logger.LogError("An error has occurred: {EMessage}", e.Message); - return null; - } - finally - { - _logger.MethodExit(); - } - } - - public async Task GetSingleOrderAsync(string orderId) - { - try - { - EnsureAuthenticated(); - - _httpClient.DefaultRequestHeaders.Authorization = - new AuthenticationHeaderValue("Bearer", _bearerToken); - _httpClient.DefaultRequestHeaders.Accept.Add( - new MediaTypeWithQualityHeaderValue("application/json")); - - var response = await _httpClient.GetAsync($"{BaseUrl}/certs/v1/order/{orderId}"); - var content = await response.Content.ReadAsStringAsync(); - OrderContent order; - if (response.IsSuccessStatusCode) - order = JsonConvert.DeserializeObject(content); - else - throw new Exception(BuildErrorString(content)); - - return new AnyCAPluginCertificate - { - CARequestID = order.Id, - Certificate = order.Cert.EndEntityCert, - Status = MarkMonitorCertificateStatusToCAStatus(order), - ProductID = order.CertType, - RevocationDate = Convert.ToDateTime(order.Cert.DaysRemaining) - }; - } - catch (Exception e) - { - _logger.LogError("An error has occurred: {EMessage}", e.Message); - return null; - } - } - - private string getCsrAlgorithm(Pkcs10CertificationRequest csr) - { - var signatureAlgorithm = csr.SignatureAlgorithm.Algorithm.Id; - var requestAlgorithm = signatureAlgorithm switch - { - //check if algorithm is RSA or ECC - "1.2.840.113549.1.1.11" => AlgorithmTypes.Rsa.GetDescription(), - "1.2.840.10045.4.3.1" or "1.2.840.10045.4.3.2" or "1.2.840.10045.4.3.3" or "1.2.840.10045.4.3.4" - or "1.2.840.10045.2.1" => AlgorithmTypes.Ecc.GetDescription(), - // "2.16.840.1.101.3.4.3.1" or "2.16.840.1.101.3.4.3.2" or "2.16.840.1.101.3.4.3.3" - // or "2.16.840.1.101.3.4.3.4" => AlgorithmTypes.Dsa.GetDescription(), //DSA not supported - _ => throw new Exception($"Invalid CSR signature algorithm {signatureAlgorithm}") - }; - return requestAlgorithm; - } - - public async Task EnrollCertificateAsync(string csr, string subject, - Dictionary san, string orderType, Dictionary productParams, - MarkMonitorConfig config) - { - _logger.MethodEntry(); - try - { - EnsureAuthenticated(); - - var additionalEmails = - productParams.GetValueOrDefault("additionalEmails"); - var additionalEmailsList = new List(); - if (!string.IsNullOrEmpty(additionalEmails)) - { - _logger.LogTrace("Additional emails provided: {AdditionalEmails}", additionalEmails); - additionalEmails = additionalEmails.Replace(" ", ","); - additionalEmailsList = additionalEmails.Split(',').ToList(); - } - - var orgIds = await ListOrganizationsAsync(0, 1, config.OrgName); - _logger.LogTrace("Organizations found: {@OrgIds}", orgIds); - var orgId = orgIds.FirstOrDefault()?.Id; - _logger.LogTrace("Organization ID: {OrgId}", orgId); - if (string.IsNullOrEmpty(orgId)) - { - _logger.LogError("Organization ID not found for {OrgName}", config.OrgName); - throw new InvalidDataException($"Organization ID '{config.OrgName}' not found"); - } - - var orgIdGuid = Guid.Parse(orgId); - - var comments = productParams.GetValueOrDefault("comments", "Requested via Keyfactor Command"); - _logger.LogTrace("Comments: {Comments}", comments); - var locale = productParams.GetValueOrDefault("locale", "en"); - _logger.LogTrace("Locale: {Locale}", locale); - var provider = productParams.GetValueOrDefault("provider", "DIGICERT"); - _logger.LogTrace("Provider: {Provider}", provider); - - // Lookup order type in CertOrderTypes enum - _logger.LogDebug("Looking up order type {OrderType} in CertOrderTypes enum", orderType); - var certOrderType = Enum.Parse(orderType); - - _logger.LogDebug("Deserializing CSR"); - _logger.LogTrace("CSR: {Csr}", csr); - var csrObject = new Pkcs10CertificationRequest(GetCsrBytes(csr)); - var csrInfo = csrObject.GetCertificationRequestInfo(); - - _logger.LogDebug("Determining CSR algorithm"); - var requestAlgorithm = getCsrAlgorithm(csrObject); - _logger.LogTrace("CSR algorithm: {RequestAlgorithm}", requestAlgorithm); - - _logger.LogDebug("Converting CSR to PEM"); - var csrPem = PemUtilities.DERToPEM(csrObject.GetEncoded(), PemUtilities.PemObjectType.CertRequest); - _logger.LogTrace("CSR PEM: {CsrPem}", csrPem); - - _logger.LogDebug("Constructing certificate order object"); - var certOrder = new MarkMonitorCreateOrderRequest - { - AdditionalEmails = additionalEmailsList, - SkipPrice = true, - OrganizationId = orgIdGuid, - // GroupId = null, - // Contacts = orderContacts, - Comments = comments, - CertType = certOrderType.GetDescription(), - Locale = locale, - Provider = provider, - Cert = new MarkMonitorOrderRequestCert - { - CommonName = cleanSubject(subject), - Csr = csrPem.Replace("\r", ""), - DcvMethod = "EMAIL", - DcvEmails = new List(), - AlgorithmHash = requestAlgorithm - } - }; - - - _logger.LogDebug("Calling CreateCertificateOrder"); - logCreateOrderRequest(certOrder); - var order = await CreateCertificateOrder(certOrder); - - if (order == null) throw new Exception($"Failed to enroll certificate `{subject}` with MarkMonitor"); - - _logger.LogInformation("Certificate enrolled successfully"); - return new EnrollmentResult - { - CARequestID = order.Id, - Certificate = order.Cert?.EndEntityCert, - Status = MarkMonitorCertificateStatusToCAStatus(order), - StatusMessage = "MarkMonitor order status: " + order.Status - }; - } - catch (Exception e) - { - _logger.LogError("An error has occurred: {EMessage}", e.Message); - return null; - } - finally - { - _logger.MethodExit(); - } - } - - private string cleanSubject(string subject) - { - _logger.MethodEntry(); - try - { - // Search for the CN field in the Subject - var cnPrefix = "CN="; - var cnIndex = subject.IndexOf(cnPrefix, StringComparison.Ordinal); - if (cnIndex < 0) return subject; - var cnStart = cnIndex + cnPrefix.Length; - var cnEnd = subject.IndexOf(",", cnStart, StringComparison.Ordinal); - if (cnEnd < 0) cnEnd = subject.Length; - return subject.Substring(cnStart, cnEnd - cnStart); - - } - finally - { - _logger.MethodExit(); - } - } - - private void logCreateOrderRequest(MarkMonitorCreateOrderRequest request) - { - _logger.MethodEntry(); - _logger.LogTrace("CommonName: {CommonName}", request.Cert.CommonName); - _logger.LogTrace("OrganizationId: {OrganizationId}", request.OrganizationId); - _logger.LogTrace("CertType: {CertType}", request.CertType); - _logger.LogTrace("Locale: {Locale}", request.Locale); - _logger.LogTrace("Provider: {Provider}", request.Provider); - _logger.LogTrace("Comments: {Comments}", request.Comments); - _logger.LogTrace("AdditionalEmails: {AdditionalEmails}", request.AdditionalEmails); - _logger.LogTrace("SkipPrice: {SkipPrice}", request.SkipPrice); - _logger.LogTrace("CSR: {Csr}", request.Cert.Csr); - _logger.LogTrace("Cert: {@Cert}", request.Cert); - _logger.MethodExit(); - } - - public async Task CreateCertificateOrder(MarkMonitorCreateOrderRequest request) - { - _logger.MethodEntry(); - try - { - EnsureAuthenticated(); - logCreateOrderRequest(request); - - var url = $"{BaseUrl}/certs/v1/order"; - _logger.LogDebug("Creating certificate order at {Url}", url); - var jsonPayload = new StringContent( - JsonConvert.SerializeObject(request), - Encoding.UTF8, "application/json" - ); - _logger.LogTrace("Create order payload: {@Payload}", jsonPayload); - _logger.LogTrace("Request JSON: {Json}", request.JSONString()); - Console.WriteLine(jsonPayload.ReadAsStringAsync()); - var response = await _httpClient.PostAsync(url, jsonPayload); - _logger.LogTrace("Response: {Response}", response); - - _logger.LogDebug("Reading response content"); - var content = await response.Content.ReadAsStringAsync(); - _logger.LogTrace("Response content: {Content}", content); - if (response.IsSuccessStatusCode) - { - var order = JsonConvert.DeserializeObject(content); - _logger.LogInformation("Certificate order {OrderId} created", order.Id); - return order; - } - - var errMsg = BuildErrorString(content); - _logger.LogError("An error has occurred while attempting to create order: {EMessage}", errMsg); - throw new Exception(errMsg); - } - catch (Exception e) - { - _logger.LogError("An error has occurred while attempting to create order: {EMessage}", e.Message); - throw; - } - finally - { - _logger.MethodExit(); - } - } - - public async Task CancelCertificateAsync(string orderId) - { - _logger.MethodEntry(); - try - { - _logger.LogInformation("Revoking certificate {CertificateId}", orderId); - EnsureAuthenticated(); - - var url = $"{BaseUrl}/certs/v1/order/{orderId}/cancel"; - _logger.LogDebug("Revoking certificate at {Url}", url); - var payload = new StringContent("", Encoding.UTF8, "application/json"); - var response = await _httpClient.PatchAsync(url, payload); - - _logger.LogDebug("Reading response content"); - var content = await response.Content.ReadAsStringAsync(); - if (response.IsSuccessStatusCode) - { - _logger.LogInformation("Certificate {CertificateId} has been revoked", orderId); - return true; - } - - var errMsg = BuildErrorString(content); - _logger.LogError("An error has occurred while attempting to cancel order {CertificateId}: {EMessage}", - orderId, errMsg); - throw new Exception(errMsg); - } - catch (Exception e) - { - _logger.LogError("An error has occurred while attempting to cancel {CertificateId}: {EMessage}", orderId, - e.Message); - throw; - } - } - - public async Task ReissueCertificateAsync(string orderId, MarkMonitorReissueRequest payload) - { - _logger.MethodEntry(); - try - { - _logger.LogInformation("Revoking certificate {CertificateId}", orderId); - EnsureAuthenticated(); - - var url = $"{BaseUrl}/certs/v1/order/{orderId}/reissue"; - _logger.LogDebug("Reissuing certificate at {Url}", url); - //convert payload to json - var jsonPayload = new StringContent( - JsonConvert.SerializeObject(payload), - Encoding.UTF8, "application/json" - ); - _logger.LogTrace("Reissue payload: {@Payload}", jsonPayload); - var response = await _httpClient.PatchAsync(url, jsonPayload); - - _logger.LogDebug("Reading response content"); - var content = await response.Content.ReadAsStringAsync(); - if (response.IsSuccessStatusCode) - { - _logger.LogInformation("Certificate {CertificateId} has been reissued", orderId); - return true; - } - - var errMsg = BuildErrorString(content); - _logger.LogError("An error has occurred while attempting to reissue {CertificateId}: {EMessage}", orderId, - errMsg); - throw new Exception(errMsg); - } - catch (Exception e) - { - _logger.LogError("An error has occurred while attempting to reissue {CertificateId}: {EMessage}", orderId, - e.Message); - throw; - } - } - - public async Task RevokeCertificateAsync(string orderId, string orgName = null, uint reason = 0) - { - _logger.MethodEntry(); - try - { - _logger.LogInformation("Revoking certificate associated with order {OrderId}", orderId); - EnsureAuthenticated(); - - var url = $"{BaseUrl}/certs/v1/order/{orderId}/revoke"; - _logger.LogDebug("Revoking certificate at {Url}", url); - var payload = new StringContent("", Encoding.UTF8, "application/json"); - var response = await _httpClient.PatchAsync(url, payload); - - _logger.LogDebug("Reading response content"); - var content = await response.Content.ReadAsStringAsync(); - if (response.IsSuccessStatusCode) - { - _logger.LogInformation("Certificate {CertificateId} has been revoked", orderId); - return true; - } - - var errMsg = BuildErrorString(content); - _logger.LogError("An error has occurred while attempting to revoke {CertificateId}: {EMessage}", orderId, - errMsg); - throw new Exception(errMsg); - } - catch (Exception e) - { - _logger.LogError("An error has occurred while attempting to revoke {CertificateId}: {EMessage}", orderId, - e.Message); - throw; - } - finally - { - _logger.MethodExit(); - } - } - - private void EnsureAuthenticated() - { - if (string.IsNullOrEmpty(_bearerToken)) AuthenticateAsync().RunSynchronously(); - } - - private static string BuildErrorString(string jsonString) - { - var json = JObject.Parse(jsonString); - var errorMessages = new List(); - - if (json["validation_messages"] != null) - foreach (var validationMessage in json["validation_messages"]) - { - var field = validationMessage.Path; - var fieldErrors = (JObject)validationMessage.First; - - foreach (var error in fieldErrors) - { - var errorMessage = error.Value.ToString(); - errorMessages.Add($"{field}: {errorMessage}"); - - if (error.Key == "options") - { - var options = string.Join(", ", error.Value.ToObject>()); - errorMessages.Add($"{field} options: {options}"); - } - } - } - else if (json["detail"] != null) - errorMessages.Add(json["detail"].ToString()); - else - return "No validation errors found."; - - return string.Join(Environment.NewLine, errorMessages); - } - - private byte[] GetCsrBytes(string csr) - { - _logger.MethodEntry(); - try - { - _logger.LogDebug("Attempting to decode CSR string"); - // Try to decode the string from Base64 - return Convert.FromBase64String(csr); - } - catch (FormatException) - { - _logger.LogDebug("Decoding failed, assuming PEM format"); - // If decoding fails, assume the string is in PEM format - var pem = csr.Replace("-----BEGIN CERTIFICATE REQUEST-----", "") - .Replace("-----END CERTIFICATE REQUEST-----", "") - .Replace("\n", "") - .Replace("\r", "") - .Trim(); - return Convert.FromBase64String(pem); - } - finally - { - _logger.MethodExit(); - } - } - - private int MarkMonitorCertificateStatusToCAStatus(OrderContent order) - { - _logger.MethodEntry(); - if (order == null || string.IsNullOrEmpty(order.Status)) - { - _logger.LogError("MarkMonitor order is null or status is empty"); - return (int)EndEntityStatus.FAILED; - } - - - _logger.LogDebug("MarkMonitor order {OrderId} status: {OrderStatus}", order.Id, order.Status); - if ( - order.Status.Equals(OrderStatus.DigiPending.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.DigiProcessing.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.DigiReissuePending.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.DigiWaitingPickup.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.ReissuePending.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.ReissueRequestPending.GetDescription(), StringComparison.OrdinalIgnoreCase) - ) - { - _logger.LogDebug("MarkMonitor order {OrderId} status resolved to 'IN PROCESS'", order.Id); - return (int)EndEntityStatus.INPROCESS; - } - - if ( - order.Status.Equals(OrderStatus.DigiRevoked.GetDescription(), StringComparison.OrdinalIgnoreCase) - ) - { - _logger.LogDebug("MarkMonitor order {OrderId} status resolved to 'REVOKED'", order.Id); - _logger.MethodExit(); - return (int)EndEntityStatus.REVOKED; - } - - - if (order.Status.Equals(OrderStatus.DigiIssued.GetDescription(), StringComparison.OrdinalIgnoreCase)) - { - _logger.LogDebug("MarkMonitor order {OrderId} status resolved to 'GENERATED'", order.Id); - _logger.MethodExit(); - return (int)EndEntityStatus.GENERATED; - } - - - if ( - order.Status.Equals(OrderStatus.DigiFailed.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.DigiReissueFailed.GetDescription(), StringComparison.OrdinalIgnoreCase) - ) - { - _logger.LogDebug("MarkMonitor order {OrderId} status resolved to 'FAILED'", order.Id); - _logger.MethodExit(); - return (int)EndEntityStatus.FAILED; - } - - - if ( - order.Status.Equals(OrderStatus.DigiCanceled.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.DigiRejected.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.DigiExpired.GetDescription(), StringComparison.OrdinalIgnoreCase) || - order.Status.Equals(OrderStatus.DigiNeedsCsr.GetDescription(), StringComparison.OrdinalIgnoreCase) - ) - { - _logger.LogDebug("MarkMonitor order {OrderId} status resolved to 'CANCELLED'", order.Id); - _logger.MethodExit(); - return (int)EndEntityStatus.CANCELLED; - } - - - if ( - order.Status.Equals(OrderStatus.Created.GetDescription(), StringComparison.OrdinalIgnoreCase) - ) - { - _logger.LogDebug("MarkMonitor order {OrderId} status resolved to 'INITIALIZED'", order.Id); - _logger.MethodExit(); - return (int)EndEntityStatus.INITIALIZED; - } - - _logger.LogError("MarkMonitor order {OrderId} status could not be resolved defaulting to 'FAILED'", order.Id); - _logger.MethodExit(); - return (int)EndEntityStatus.FAILED; - } - // - // private static int MarkMonitorCertificateStatusToCAStatus(Certificate cert) - // { - // if (cert.RevokedAt != null) return (int)EndEntityStatus.REVOKED; - // - // if (cert.HasCertificate && cert.IsValid) return (int)EndEntityStatus.GENERATED; - // - // return (int)EndEntityStatus.FAILED; - // } -} - -public class ConfigurationValidationException : Exception -{ - public ConfigurationValidationException() - { - } - - public ConfigurationValidationException(string message) - : base(message) - { - } - - public ConfigurationValidationException(string message, Exception innerException) - : base(message, innerException) - { - } -} \ No newline at end of file diff --git a/markmonitor-cagateway/Constants.cs b/markmonitor-cagateway/Constants.cs deleted file mode 100644 index b6f95bd..0000000 --- a/markmonitor-cagateway/Constants.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; - -public class Constants -{ - //Define any constants needed here (mostly field names for config parameters) -} \ No newline at end of file diff --git a/markmonitor-cagateway/MarkMonitorCAConnector.cs b/markmonitor-cagateway/MarkMonitorCAConnector.cs deleted file mode 100644 index 01bee0b..0000000 --- a/markmonitor-cagateway/MarkMonitorCAConnector.cs +++ /dev/null @@ -1,287 +0,0 @@ -using System.Collections.Concurrent; -using Keyfactor.AnyGateway.Extensions; -using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; -using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; -using Keyfactor.Logging; -using Keyfactor.PKI.Enums.EJBCA; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using MarkMonitorConstants = Keyfactor.Extensions.CAPlugin.MarkMonitor.MarkMonitorCAPluginConfig; - -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; - -public class MarkMonitorCAPlugin : IAnyCAPlugin -{ - private readonly ILogger _logger = LogHandler.GetClassLogger(); - private ICertificateDataReader _certificateDataReader; - private MarkMonitorConfig _config; - private MarkMonitorClient Client; - private bool _markMonitorClientWasInjected = false; - - - private Dictionary DCVTokens { get; } = new(); - - public MarkMonitorCAPlugin() - { - // Explicit default constructor - } - - public MarkMonitorCAPlugin(MarkMonitorClient client) - { - Client = client; - _markMonitorClientWasInjected = true; - } - - public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDataReader certificateDataReader) - { - _logger.MethodEntry(); - _certificateDataReader = certificateDataReader; - var rawConfig = JsonConvert.SerializeObject(configProvider.CAConnectionData); - _config = JsonConvert.DeserializeObject(rawConfig); - _logger.LogTrace("MarkMonitorCAPlugin initialized with config: {Config}", rawConfig); - _logger.MethodExit(); - } - - - private void logConfig() - { - _logger.MethodEntry(); - _logger.LogInformation("MarkMonitorCAPlugin config baseUrl: {Config}", _config.BaseUrl); - _logger.LogInformation("MarkMonitorCAPlugin config apiKey: {Config}", _config.ApiKey); - _logger.LogInformation("MarkMonitorCAPlugin config apiUsername: {Config}", _config.ApiUsername); - _logger.LogInformation("MarkMonitorCAPlugin config apiPassword: {Config}", _config.ApiPassword); - _logger.LogInformation("MarkMonitorCAPlugin config orgName: {Config}", _config.OrgName); - _logger.MethodExit(); - } - - public async Task GetSingleRecord(string caRequestId) - { - _logger.MethodEntry(); - var client = await CreateAndAuthenticateClientAsync(); - _logger.LogInformation("Getting order details for CARequestID: {CARequestID}", caRequestId); - var order = await client.GetSingleOrderAsync(caRequestId); - _logger.LogInformation("Order details retrieved for CARequestID: {CARequestID}", caRequestId); - _logger.MethodExit(); - return order; - } - - public async Task Synchronize(BlockingCollection blockingBuffer, DateTime? lastSync, - bool fullSync, CancellationToken cancelToken) - { - _logger.MethodEntry(); - - try - { - _logger.LogInformation(fullSync - ? "Performing a full CA synchronization" - : "Performing a partial CA synchronization"); - - logConfig(); - - _logger.LogDebug("Calling CreateAndAuthenticateClientAsync"); - var client = await CreateAndAuthenticateClientAsync(); - _logger.LogDebug("CreateAndAuthenticateClientAsync completed"); - - _logger.LogInformation("Attempting to synchronize certificates with MarkMonitor API"); - var certificates = await client.GetCertificateInventoryAsync("", "", 100, blockingBuffer, cancelToken); - _logger.LogDebug("Synchronized {Certificates} certificates", certificates); - - // Check for cancellation after operation - // cancelToken.ThrowIfCancellationRequested(); - } - catch (OperationCanceledException) - { - _logger.LogInformation("Synchronization canceled"); - throw; // Rethrow the cancellation exception to ensure it's propagated - } - catch (Exception ex) - { - _logger.LogError("An error occurred during synchronization: {ExMessage}", ex.Message); - throw; - } - finally - { - _logger.MethodExit(); - } - } - - public async Task Revoke(string orderId, string hexSerialNumber, uint revocationReason) - { - _logger.MethodEntry(); - try - { - _logger.LogInformation( - "Revoking certificate with CARequestID: {CaRequestId}, SerialNumber: {HexSerialNumber}, Reason: {RevocationReason}", - orderId, hexSerialNumber, revocationReason); - - var client = await CreateAndAuthenticateClientAsync(); - - _logger.LogInformation("Attempting to revoke certificate with CARequestID: {CaRequestId}", orderId); - - var revokeResult = await client.RevokeCertificateAsync(orderId, _config.OrgName, revocationReason); - - if (revokeResult) return (int)EndEntityStatus.REVOKED; - - throw new Exception("Unable to revoke certificate associated with order ID: " + orderId); - } - catch (Exception e) - { - throw new Exception($"Revoke Failed with message {e?.Message}"); - } - finally - { - _logger.MethodExit(); - } - } - - public async Task Enroll(string csr, string subject, Dictionary san, - EnrollmentProductInfo productInfo, RequestFormat requestFormat, EnrollmentType enrollmentType) - { - _logger.MethodEntry(); - try - { - _logger.LogInformation("Enrolling certificate `{Subject}` with MarkMonitor", subject); - - var client = await CreateAndAuthenticateClientAsync(); - - _logger.LogInformation("Performing an Enrollment"); - - var enrollResult = await client.EnrollCertificateAsync(csr, subject, san, productInfo.ProductID, - productInfo.ProductParameters, _config); - - return enrollResult; - } - finally - { - _logger.MethodExit(); - } - } - - public async Task Ping() - { - _logger.MethodEntry(); - try - { - _logger.LogInformation("Attempting to authenticate with MarkMonitor API"); - var client = await CreateAndAuthenticateClientAsync(); - - if (client == null) throw new Exception("Error attempting to ping MarkMonitor"); - - _logger.LogInformation("Authentication with MarkMonitor API successful"); - - _logger.LogInformation("Attempting to list organizations"); - var orgs = await client.ListOrganizationsAsync(); - - if (orgs == null || !orgs.Any()) - throw new Exception("Unable to ping MarkMonitor API, or no MarkMonitor organization exist"); - _logger.LogInformation("Successfully pinged MarkMonitor API"); - } - catch (Exception e) - { - _logger.LogError("There was an error contacting MarkMonitor: {EMessage}", e.Message); - throw new Exception($"Error attempting to ping MarkMonitor: {e.Message}.", e); - } - finally - { - _logger.MethodExit(); - } - } - - public async Task ValidateCAConnectionInfo(Dictionary connectionInfo) - { - _logger.MethodEntry(); - _logger.LogInformation("Validating CA Connection Info"); - - var errors = new List(); - - _logger.LogDebug("Checking the API Key"); - var apiKey = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.ApiKey, out var aKey) - ? (string)aKey - : string.Empty; - if (string.IsNullOrWhiteSpace(apiKey)) - errors.Add($"A valid `{MarkMonitorConstants.ConfigConstants.ApiKey} is required"); - else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.ApiKey} is set"); - - _logger.LogDebug("Checking the API service account password"); - var apiPassword = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.ApiPassword, out var aPass) - ? (string)aPass - : string.Empty; - if (string.IsNullOrWhiteSpace(apiPassword)) - errors.Add($"A valid service account `{MarkMonitorConstants.ConfigConstants.ApiPassword}` is required"); - else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.ApiPassword} is set"); - - _logger.LogDebug("Checking the API service account username"); - var apiUsername = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.ApiUsername, out var aUser) - ? (string)aUser - : string.Empty; - if (string.IsNullOrWhiteSpace(apiUsername)) - errors.Add($"A valid service account `{MarkMonitorConstants.ConfigConstants.ApiUsername}` is required"); - else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.ApiUsername} is set"); - _logger.LogTrace("MarkMonitor API Username: {Username}", apiUsername); - - _logger.LogDebug("Checking the API base URL"); - var baseURL = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.BaseUrl, out var aUrl) - ? (string)aUrl - : string.Empty; - if (string.IsNullOrWhiteSpace(baseURL)) baseURL = "https://api.markmonitor.com"; - else if (!baseURL.Contains("http")) errors.Add("The Base URL needs http:// or https://"); - else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.BaseUrl} is set"); - _logger.LogTrace("MarkMonitor API Base URL: {BaseURL}", baseURL); - - _logger.LogDebug("Checking the Organization Name"); - var orgName = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.OrgName, out var aOrg) - ? (string)aOrg - : string.Empty; - if (string.IsNullOrWhiteSpace(orgName)) errors.Add("A valid Organization name is required"); - else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.OrgName} is set"); - _logger.LogTrace("MarkMonitor Organization Name: {OrgName}", orgName); - if (errors.Any()) ThrowValidationException(errors); - _logger.LogInformation("CA Connection Info validated successfully"); - _logger.MethodExit(); - } - - public Task ValidateProductInfo(EnrollmentProductInfo productInfo, Dictionary connectionInfo) - { - _logger.LogInformation("Product Info validated successfully"); - return Task.CompletedTask; - } - - public Dictionary GetCAConnectorAnnotations() - { - return MarkMonitorConstants.GetPluginAnnotations(); - } - - public Dictionary GetTemplateParameterAnnotations() - { - return MarkMonitorConstants.GetTemplateParameterAnnotations(); - } - - public List GetProductIds() - { - // return list of CertOrderTypes Enum values - return Enum.GetNames(typeof(CertOrderTypes)).ToList(); - } - - private async Task CreateAndAuthenticateClientAsync() - { - _logger.MethodEntry(); - var client = new MarkMonitorClient( - _config.BaseUrl, - _config.ApiKey, - _config.ApiUsername, - _config.ApiPassword, - true - ); - _logger.LogDebug("Authenticating with MarkMonitor API"); - _logger.LogTrace("MarkMonitor API Username: {Username}", _config.ApiUsername); - await client.AuthenticateAsync(); - _logger.MethodExit(); - return client; - } - - private void ThrowValidationException(List errors) - { - var validationMsg = $"Validation errors:\n{string.Join("\n", errors)}"; - throw new AnyCAValidationException(validationMsg); - } -} \ No newline at end of file diff --git a/markmonitor-cagateway/MarkMonitorCAPluginConfig.cs b/markmonitor-cagateway/MarkMonitorCAPluginConfig.cs deleted file mode 100644 index d7aa5de..0000000 --- a/markmonitor-cagateway/MarkMonitorCAPluginConfig.cs +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2024 Keyfactor -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Keyfactor.AnyGateway.Extensions; -using Newtonsoft.Json; - -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; - -public class MarkMonitorCAPluginConfig -{ - public static Dictionary GetPluginAnnotations() - { - return new Dictionary - { - [ConfigConstants.ApiKey] = new() - { - Comments = "The API Key for the MarkMonitor API", - Hidden = true, - DefaultValue = "", - Type = "String" - }, - [ConfigConstants.ApiUsername] = new() - { - Comments = "Username for the MarkMonitor API service account", - Hidden = false, - DefaultValue = "", - Type = "String" - }, - [ConfigConstants.ApiPassword] = new() - { - Comments = "Password for the MarkMonitor API service account", - Hidden = true, - DefaultValue = "", - Type = "String" - }, - [ConfigConstants.BaseUrl] = new() - { - Comments = - "The Base URL for the MarkMonitor API - Usually either https://api.markmonitor.com", - Hidden = false, - DefaultValue = "https://api.markmonitor.com", - Type = "String" - }, - [ConfigConstants.OrgName] = new() - { - Comments = - "The name of the MarkMonitor Organization to use for the API calls (ex: MarkMonitor). You can also use the Organization ID in GUID format.", - Hidden = false, - DefaultValue = "", - Type = "String" - }, - [ConfigConstants.Enabled] = new() - { - Comments = - "Flag to Enable or Disable gateway functionality. Disabling is primarily used to allow creation of the CA prior to configuration information being available.", - Hidden = false, - DefaultValue = true, - Type = "Boolean" - } - }; - } - - public static Dictionary GetTemplateParameterAnnotations() - { - return new Dictionary - { - [EnrollmentConfigConstants.CertificateValidityInYears] = new() - { - Comments = "Number of years the certificate will be valid for", - Hidden = false, - DefaultValue = "1", - Type = "Number" - }, - [EnrollmentConfigConstants.Email] = new() - { - Comments = "Email address of the requestor", - Hidden = false, - DefaultValue = "", - Type = "String" - }, - [EnrollmentConfigConstants.OrganizationName] = new() - { - Comments = "Name of the organization to be validated against", - Hidden = false, - DefaultValue = "", - Type = "String" - } - // [EnrollmentConfigConstants.OrganizationAddress] = new() - // { - // Comments = "Address of the organization to be validated against", - // Hidden = false, - // DefaultValue = "", - // Type = "String" - // }, - // [EnrollmentConfigConstants.OrganizationCity] = new() - // { - // Comments = "City of the organization to be validated against", - // Hidden = false, - // DefaultValue = "", - // Type = "String" - // }, - // [EnrollmentConfigConstants.OrganizationState] = new() - // { - // Comments = "Full state name of the organization to be validated against", - // Hidden = false, - // DefaultValue = "", - // Type = "String" - // }, - // [EnrollmentConfigConstants.OrganizationCountry] = new() - // { - // Comments = "2 character abbreviation of the country of the organization to be validated against", - // Hidden = false, - // DefaultValue = "", - // Type = "String" - // }, - // [EnrollmentConfigConstants.OrganizationPhone] = new() - // { - // Comments = "Phone number of the organization to be validated against", - // Hidden = false, - // DefaultValue = "", - // Type = "String" - // }, - // [EnrollmentConfigConstants.RegistrationAgent] = new() - // { - // Comments = - // "Registration agent name assigned to the organization when its documents were filed for registration", - // Hidden = false, - // DefaultValue = "", - // Type = "String" - // }, - // [EnrollmentConfigConstants.RegistrationNumber] = new() - // { - // Comments = - // "Registration number assigned to the organization when its documents were filed for registration", - // Hidden = false, - // DefaultValue = "", - // Type = "String" - // }, - // [EnrollmentConfigConstants.RootCAType] = new() - // { - // Comments = - // "The certificate's root CA - Depending on certificate expiration date, SHA_1 not be allowed. Will default to SHA_2 if expiration date exceeds sha1 allowed date. Options are MarkMonitor_SHA_1, MarkMonitor_SHA_2, STARFIELD_SHA_1, or STARFIELD_SHA_2.", - // Hidden = false, - // DefaultValue = "MarkMonitor_SHA_2", - // Type = "String" - // } - }; - } - - public class ConfigConstants - { - public const string ApiKey = "ApiKey"; - public const string ApiPassword = "Password"; - public const string ApiUsername = "Username"; - public const string BaseUrl = "BaseUrl"; - public const string OrgName = "OrgId"; - public const string Enabled = "Enabled"; - } - - public class Config - { - [JsonProperty(ConfigConstants.ApiKey)] public string ApiKey { get; set; } - - [JsonProperty(ConfigConstants.ApiPassword)] - public string ApiPassword { get; set; } - - [JsonProperty(ConfigConstants.ApiUsername)] - public string ApiUsername { get; set; } - - [JsonProperty(ConfigConstants.BaseUrl)] - public string BaseUrl { get; set; } - - [JsonProperty(ConfigConstants.OrgName)] - public string OrgName { get; set; } - - [JsonProperty(ConfigConstants.Enabled)] - public bool Enabled { get; set; } - } - - public static class EnrollmentConfigConstants - { - // public const string LastName = "LastName"; - // public const string FirstName = "FirstName"; - public const string Email = "Email"; - // public const string Phone = "Phone"; - - public const string OrganizationName = "OrganizationName"; - // public const string OrganizationAddress = "OrganizationAddress"; - // public const string OrganizationCity = "OrganizationCity"; - // public const string OrganizationState = "OrganizationState"; - // public const string OrganizationCountry = "OrganizationCountry"; - // public const string OrganizationPhone = "OrganizationPhone"; - - // public const string JobTitle = "JobTitle"; - // public const string RegistrationAgent = "RegistrationAgent"; - // public const string RegistrationNumber = "RegistrationNumber"; - // - // public const string RootCAType = "RootCAType"; - // public const string SlotSize = "SlotSize"; - public const string CertificateValidityInYears = "CertificateValidityInYears"; - } -} \ No newline at end of file diff --git a/markmonitor-cagateway/MarkMonitorConfig.cs b/markmonitor-cagateway/MarkMonitorConfig.cs deleted file mode 100644 index a917e72..0000000 --- a/markmonitor-cagateway/MarkMonitorConfig.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Newtonsoft.Json; - -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; - -public class MarkMonitorConfig -{ - [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.ApiKey)] - public string ApiKey { get; set; } - - [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.ApiPassword)] - public string ApiPassword { get; set; } - - [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.ApiUsername)] - public string ApiUsername { get; set; } - - [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.BaseUrl)] - public string BaseUrl { get; set; } - - [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.OrgName)] - public string OrgName { get; set; } - - [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.Enabled)] - public bool Enabled { get; set; } - - public string MarkMonitorApiClient { get; set; } -} \ No newline at end of file diff --git a/markmonitor-cagateway/Models/EnrollCertificateRequest.cs b/markmonitor-cagateway/Models/EnrollCertificateRequest.cs deleted file mode 100644 index a53d961..0000000 --- a/markmonitor-cagateway/Models/EnrollCertificateRequest.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; - -public class EnrollCertificateRequest -{ - [JsonProperty("ca_id")] public int CaId { get; set; } - - [JsonProperty("cert_type")] public string CertType { get; set; } - - [JsonProperty("file_csr_encoding")] public string CsrEncoding { get; set; } - - [JsonProperty("issue_cert")] public bool IssueCert { get; set; } - - [JsonProperty("days")] public int Days { get; set; } - - [JsonProperty("file_csr")] public string Csr { get; set; } -} \ No newline at end of file diff --git a/markmonitor-cagateway/Models/IssuerDn.cs b/markmonitor-cagateway/Models/IssuerDn.cs deleted file mode 100644 index 1a078cf..0000000 --- a/markmonitor-cagateway/Models/IssuerDn.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; - -public class IssuerDn -{ - [JsonProperty("C")] public string C { get; set; } - - [JsonProperty("L")] public string L { get; set; } - - [JsonProperty("O")] public string O { get; set; } - - [JsonProperty("CN")] public string Cn { get; set; } - - [JsonProperty("ST")] public string St { get; set; } - - [JsonProperty("emailAddress")] public string EmailAddress { get; set; } -} \ No newline at end of file diff --git a/markmonitor-cagateway/Models/SubjectDn.cs b/markmonitor-cagateway/Models/SubjectDn.cs deleted file mode 100644 index 2be7f01..0000000 --- a/markmonitor-cagateway/Models/SubjectDn.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; - -public class SubjectDn -{ - [JsonProperty("C")] public string C { get; set; } - - [JsonProperty("L")] public string L { get; set; } - - [JsonProperty("O")] public string O { get; set; } - - [JsonProperty("CN")] public string Cn { get; set; } - - [JsonProperty("ST")] public string St { get; set; } - - [JsonProperty("emailAddress")] public string EmailAddress { get; set; } -} \ No newline at end of file diff --git a/markmonitor-cagateway/markmonitor-cagateway.csproj b/markmonitor-cagateway/markmonitor-cagateway.csproj deleted file mode 100644 index b466242..0000000 --- a/markmonitor-cagateway/markmonitor-cagateway.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - net6.0 - Keyfactor.Extensions.CAPlugin.MarkMonitor - enable - disable - MarkMonitorCAPlugin - true - - - false - Keyfactor Inc - MarkMonitor CA Gateway - 1.0.0.0 - 1.0.0.0 - - - - - - - - - - - - - Always - - - - diff --git a/markmonitor-cagateway/packages.config b/markmonitor-cagateway/packages.config deleted file mode 100644 index b5aed46..0000000 --- a/markmonitor-cagateway/packages.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs new file mode 100644 index 0000000..6fd0641 --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs @@ -0,0 +1,26 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests.Client; + +// Hits the real MarkMonitor API using credentials from the environment (see .env / TestConsole/.env). +// Skips automatically when those variables aren't set, so it stays out of normal CI/unit runs. +public class MarkMonitorClientAuthenticateLiveTests +{ + [Fact] + public async Task AuthenticateAsync_WithLiveCredentials_Succeeds() + { + if (!LiveApiCredentials.TryGet(out var baseUrl, out var apiToken, out var username, out var password)) + { + // No live credentials in the environment; nothing to verify. + return; + } + + using var client = new MarkMonitorClient(baseUrl, apiToken, username, password); + + // AuthenticateAsync throws on a failed authentication, so "did not throw" is the real + // assertion here - mirroring TestConsole's TestAuthenticate. + var exception = await Record.ExceptionAsync(() => client.AuthenticateAsync()); + + Assert.Null(exception); + } +} diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs new file mode 100644 index 0000000..1b31ad3 --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs @@ -0,0 +1,90 @@ +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; +using Keyfactor.PKI.Enums.EJBCA; +using Keyfactor.PKI.PEM; +using TestConsole.Helpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests.Client; + +// Hits the real MarkMonitor API using credentials from the environment (see .env / TestConsole/.env) +// and creates real, billable MarkMonitor orders. Skips automatically when those variables aren't +// set, so it stays out of normal CI/unit runs. +// +// Unlike TestConsole/Program.cs's EnrollCertificateAsync loop (which supports +// MARKMONITOR_SKIP_CLEANUP for deliberate manual-inspection runs), every order created here is +// always cleaned up (see OrderCleanup) - this suite is meant to run unattended and repeatedly, so +// leaving created orders in place is never an option. +public class MarkMonitorClientEnrollLiveTests +{ + [Fact] + public async Task EnrollCertificateAsync_WithRsaCsr_CreatesAndCleansUpOrder() + { + await RunEnrollTest(CsrGenerator.KeyType.RSA); + } + + [Fact] + public async Task EnrollCertificateAsync_WithEccCsr_CreatesAndCleansUpOrder() + { + await RunEnrollTest(CsrGenerator.KeyType.ECC); + } + + private static async Task RunEnrollTest(CsrGenerator.KeyType keyType) + { + if (!LiveApiCredentials.TryGet(out var baseUrl, out var apiToken, out var username, out var password)) + { + // No live credentials in the environment; nothing to verify. + return; + } + + using var client = new MarkMonitorClient(baseUrl, apiToken, username, password); + await client.AuthenticateAsync(); + + var orgs = await client.ListOrganizationsAsync(0, 0); + Assert.NotEmpty(orgs); + + var csrGenerator = new CsrGenerator(); + var generatedCsrs = await csrGenerator.GenerateCsrs(1, keyType); + var (csr, _, _) = generatedCsrs[0]; + var csrPem = PemUtilities.DERToPEM(csr.GetEncoded(), PemUtilities.PemObjectType.CertRequest); + var commonName = csr.GetCertificationRequestInfo().Subject.GetValueList()[0]; + + var randomNumberOfEmails = new Random().Next(1, 4); + var additionalEmails = await EmailAddressGenerator.GenerateRandomEmailsAsync(randomNumberOfEmails); + + var config = new MarkMonitorConfig + { + ApiKey = apiToken, + ApiUsername = username, + ApiPassword = password, + BaseUrl = baseUrl, + OrgName = orgs[0].Name, + Enabled = true + }; + var productParams = new Dictionary + { + ["additionalEmails"] = string.Join(",", additionalEmails) + }; + + EnrollmentResult? enrollResult = null; + try + { + enrollResult = await client.EnrollCertificateAsync(csrPem, $"CN={commonName}", + new Dictionary(), CertOrderTypes.SslDvGeotrust.ToString(), productParams, config); + + Assert.NotNull(enrollResult); + Assert.False(string.IsNullOrWhiteSpace(enrollResult.CARequestID)); + // The test org used for these live runs requires manual email DCV approval, so the + // order will be pending (EXTERNALVALIDATION), not issued, by the time this returns - + // the real assertion is that the order was accepted at all rather than rejected/failed. + Assert.NotEqual((int)EndEntityStatus.FAILED, enrollResult.Status); + } + finally + { + if (enrollResult != null) + { + await OrderCleanup.CleanUpOrderAsync(client, enrollResult.CARequestID, config.OrgName); + } + } + } +} diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs new file mode 100644 index 0000000..ca2dac3 --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs @@ -0,0 +1,34 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests.Client; + +// Hits the real MarkMonitor API using credentials from the environment (see .env / TestConsole/.env). +// Skips automatically when those variables aren't set, so it stays out of normal CI/unit runs. +public class MarkMonitorClientListCertificateOrdersLiveTests +{ + [Fact] + public async Task ListCertificateOrdersAsync_WithLiveCredentials_ReturnsOrders() + { + if (!LiveApiCredentials.TryGet(out var baseUrl, out var apiToken, out var username, out var password)) + { + // No live credentials in the environment; nothing to verify. + return; + } + + using var client = new MarkMonitorClient(baseUrl, apiToken, username, password); + await client.AuthenticateAsync(); + + var orders = await client.ListCertificateOrdersAsync(0, "", "", 100); + + // Mirrors TestConsole's TestListCertificateOrders, which treats an empty result as a + // test-setup problem ("no certificates found, please add some to run this test") rather + // than a valid outcome. + Assert.NotEmpty(orders); + + foreach (var order in orders) + { + Assert.False(string.IsNullOrWhiteSpace(order.Id)); + Assert.False(string.IsNullOrWhiteSpace(order.Status)); + } + } +} diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs new file mode 100644 index 0000000..6fbbcdb --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs @@ -0,0 +1,42 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests.Client; + +// Hits the real MarkMonitor API using credentials from the environment (see .env / TestConsole/.env). +// Skips automatically when those variables aren't set, so it stays out of normal CI/unit runs. +public class MarkMonitorClientListOrgsLiveTests +{ + [Fact] + public async Task ListOrganizationsAsync_WithLiveCredentials_ReturnsOrgsWithValidations() + { + if (!LiveApiCredentials.TryGet(out var baseUrl, out var apiToken, out var username, out var password)) + { + // No live credentials in the environment; nothing to verify. + return; + } + + using var client = new MarkMonitorClient(baseUrl, apiToken, username, password); + await client.AuthenticateAsync(); + + var orgs = await client.ListOrganizationsAsync(0, 0); + + // Mirrors TestConsole's TestListOrgs, which treats an empty result as a test-setup problem + // ("no organizations found, please add some to run this test") rather than a valid outcome. + Assert.NotEmpty(orgs); + + foreach (var org in orgs) + { + Assert.False(string.IsNullOrWhiteSpace(org.Id)); + + // TestListOrgs additionally logs each org's validations (name/type) - assert their shape + // is well-formed rather than just that the call didn't throw. `name` is not always + // present on real data - a DV-type validation, for example, comes back with only `type` + // and no `name` field at all - so only `type` is guaranteed non-empty. + foreach (var validation in org.Validations ?? new List()) + { + Assert.False(string.IsNullOrWhiteSpace(validation.Type)); + } + } + } +} diff --git a/markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs b/markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs new file mode 100644 index 0000000..b56bb67 --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs @@ -0,0 +1,21 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests; + +///

      +/// Reads the MARKMONITOR_* environment variables that every live-API test in this project needs +/// (see .env / TestConsole/.env, sourced manually - there is no dotenv-loading package in this +/// repo). Every test in this project must skip (return early) rather than fail when these aren't +/// set, so the whole suite stays safe to run without live credentials present. +/// +internal static class LiveApiCredentials +{ + public static bool TryGet(out string? baseUrl, out string? apiToken, out string? username, out string? password) + { + baseUrl = Environment.GetEnvironmentVariable("MARKMONITOR_BASE_URL"); + apiToken = Environment.GetEnvironmentVariable("MARKMONITOR_API_TOKEN"); + username = Environment.GetEnvironmentVariable("MARKMONITOR_USERNAME"); + password = Environment.GetEnvironmentVariable("MARKMONITOR_PASSWORD"); + + return !string.IsNullOrEmpty(baseUrl) && !string.IsNullOrEmpty(apiToken) && + !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password); + } +} diff --git a/markmonitor-caplugin.IntegrationTests/OrderCleanup.cs b/markmonitor-caplugin.IntegrationTests/OrderCleanup.cs new file mode 100644 index 0000000..10771d9 --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/OrderCleanup.cs @@ -0,0 +1,37 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests; + +/// +/// Cleanup for a real, billable MarkMonitor order created by a live enrollment test. Mirrors +/// TestConsole/Program.cs's CleanUpOrderAsync (cancel, falling back to revoke on failure) - orders +/// created by these tests are freshly submitted and never reach an issued state before this runs. +/// +/// Unlike TestConsole (a manual tool with a MARKMONITOR_SKIP_CLEANUP escape hatch for deliberate +/// inspection runs), this suite is meant to run unattended and repeatedly, so there is no opt-out: +/// a cleanup failure here throws (failing the test loudly) rather than just logging a warning, +/// since a silently-failed cleanup would otherwise leave a billable order behind with nothing +/// flagging it for manual follow-up. +/// +internal static class OrderCleanup +{ + public static async Task CleanUpOrderAsync(MarkMonitorClient client, string orderId, string? orgName = null) + { + try + { + await client.CancelCertificateAsync(orderId, orgName); + } + catch (Exception cancelEx) + { + try + { + await client.RevokeCertificateAsync(orderId, orgName); + } + catch (Exception revokeEx) + { + throw new Exception( + $"Could not cancel or revoke order {orderId} - it may still incur charges and must be cleaned up manually. Cancel error: {cancelEx.Message}; Revoke error: {revokeEx.Message}"); + } + } + } +} diff --git a/markmonitor-caplugin.IntegrationTests/markmonitor-caplugin.IntegrationTests.csproj b/markmonitor-caplugin.IntegrationTests/markmonitor-caplugin.IntegrationTests.csproj new file mode 100644 index 0000000..5299b5b --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/markmonitor-caplugin.IntegrationTests.csproj @@ -0,0 +1,33 @@ + + + + net8.0 + Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs new file mode 100644 index 0000000..b27c695 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs @@ -0,0 +1,36 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Newtonsoft.Json.Linq; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientAdditionalEmailsTests +{ + [Fact] + public async Task EnrollCertificateAsync_WithSpaceAndCommaSeparatedEmails_DoesNotSendEmptyEntries() + { + // "a@b.com, c@d.com".Replace(" ", ",").Split(',') used to yield ["a@b.com", "", "c@d.com"] - + // an empty string sent to MarkMonitor as one of the additional emails. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var config = SampleConfig.Default(); + var productParams = new Dictionary { ["additionalEmails"] = "a@b.com, c@d.com" }; + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", productParams, config); + + var orderRequest = Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "POST", "/order")); + var body = await orderRequest.Content!.ReadAsStringAsync(); + var sentEmails = JObject.Parse(body)["additionalEmails"]!.Values().ToList(); + Assert.Equal(new[] { "a@b.com", "c@d.com" }, sentEmails); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs new file mode 100644 index 0000000..a348166 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs @@ -0,0 +1,130 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorClientAuthLifecycleTests +{ + private static int AuthCallCount(FakeHttpMessageHandler handler) => + handler.Requests.Count(r => FakeHttpMessageHandler.Is(r, "POST", "/auth/v1/auth/authenticate")); + + [Fact] + public async Task ListOrganizationsAsync_WithoutAnyPriorAuthenticateCall_LazilyAuthenticatesRatherThanThrowing() + { + // Before the fix, EnsureAuthenticated() called AuthenticateAsync().RunSynchronously(), which + // throws InvalidOperationException on any Task returned from an async method. Every existing + // call site happened to pre-await AuthenticateAsync() so this never surfaced - calling a method + // WITHOUT authenticating first is exactly the case that used to blow up. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(); + + var orgs = await client.ListOrganizationsAsync(); + + Assert.NotNull(orgs); + Assert.Single(orgs); + Assert.Equal(1, AuthCallCount(handler)); + } + + [Fact] + public async Task EnsureAuthenticatedAsync_WhenTokenHasExpired_ReAuthenticatesBeforeTheNextCall() + { + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth(expiresIn: 60) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(clock); + + await client.AuthenticateAsync(); + Assert.Equal(1, AuthCallCount(handler)); + + // Token is valid for 60s minus a 30s safety buffer = 30s. Move well past that. + clock.UtcNow = clock.UtcNow.AddSeconds(31); + + await client.ListOrganizationsAsync(); + + Assert.Equal(2, AuthCallCount(handler)); + } + + [Fact] + public async Task EnsureAuthenticatedAsync_WhenTokenIsStillValid_DoesNotReAuthenticate() + { + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth(expiresIn: 3600) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(clock); + + await client.AuthenticateAsync(); + clock.UtcNow = clock.UtcNow.AddSeconds(5); + await client.ListOrganizationsAsync(); + + Assert.Equal(1, AuthCallCount(handler)); + } + + [Fact] + public async Task EnsureAuthenticatedAsync_CalledConcurrentlyWithAnExpiredToken_OnlyAuthenticatesOnce() + { + // Without a lock, two callers can both see the expired token, both call AuthenticateAsync + // concurrently, and race writing _bearerToken/_tokenExpiresAtUtc and the shared HttpClient's + // Authorization header. Gate the auth response so both calls are genuinely in flight together + // rather than sequential. + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var authGate = new TaskCompletionSource(); + var handler = new FakeHttpMessageHandler() + .WhenGated(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), authGate.Task, + FakeHttpMessageHandler.Json(HttpStatusCode.OK, """{"token":"fake-token","expiresIn":3600}""")) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(clock); + + var firstCall = client.ListOrganizationsAsync(); + var secondCall = client.ListOrganizationsAsync(); + authGate.SetResult(); + await Task.WhenAll(firstCall, secondCall); + + Assert.Equal(1, AuthCallCount(handler)); + } + + [Fact] + public async Task EnsureAuthenticatedAsync_WaiterFindsTokenAlreadyRefreshed_LogsThatItReusedIt() + { + // The caller that wins _authLock and re-authenticates logs about it, but the caller that was + // blocked on the lock previously returned silently once it acquired the lock and found + // TokenNeedsRefresh() false - no signal that it reused a token a concurrent caller just + // refreshed. Assert the waiter now logs that too. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var authGate = new TaskCompletionSource(); + var handler = new FakeHttpMessageHandler() + .WhenGated(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), authGate.Task, + FakeHttpMessageHandler.Json(HttpStatusCode.OK, """{"token":"fake-token","expiresIn":3600}""")) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(clock); + + // The first call wins the lock and blocks on the gated auth response; the second call + // blocks on _authLock.WaitAsync() until the first releases it, then must find the token + // already refreshed. + var firstCall = client.ListOrganizationsAsync(); + var secondCall = client.ListOrganizationsAsync(); + authGate.SetResult(); + await Task.WhenAll(firstCall, secondCall); + + Assert.Equal(1, AuthCallCount(handler)); + Assert.Contains(capturingFactory.Messages, + m => m.Contains("refreshed by a concurrent caller", StringComparison.OrdinalIgnoreCase)); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs new file mode 100644 index 0000000..5887fb0 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs @@ -0,0 +1,147 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorClientAuthenticateTests +{ + [Fact] + public async Task AuthenticateAsync_WithFakeSuccessResponse_Succeeds() + { + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = handler.BuildClient(); + + await client.AuthenticateAsync(); + + var authRequest = Assert.Single(handler.Requests); + Assert.Equal("POST", authRequest.Method.Method); + Assert.Contains("/auth/v1/auth/authenticate", authRequest.RequestUri!.ToString()); + } + + [Fact] + public async Task AuthenticateAsync_WithFailureResponse_ThrowsWithParsedErrorInsteadOfRawHttpException() + { + // Before the fix, EnsureSuccessStatusCode() was called before the response body was ever + // read, so it always threw a bare HttpRequestException ("Response status code does not + // indicate success: 401") - the code below it that builds a real error message from the + // response body was unreachable dead code. + var handler = new FakeHttpMessageHandler() + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), + FakeHttpMessageHandler.Json(HttpStatusCode.Unauthorized, + """{"errors":[{"code":"auth.invalidCredentials","message":"Invalid username or password."}]}""")); + var client = handler.BuildClient(); + + var ex = await Assert.ThrowsAsync(() => client.AuthenticateAsync()); + + Assert.IsNotType(ex); + Assert.Contains("Invalid username or password", ex.Message); + } + + [Fact] + public async Task AuthenticateAsync_CalledTwice_DoesNotDuplicateTheApiKeyHeader() + { + // DefaultRequestHeaders.Add() does not replace an existing value for the same header name - + // calling AuthenticateAsync a second time on the same client (now a real path, since + // EnsureAuthenticatedAsync re-authenticates on token expiry) used to leave two X-API-KEY + // values on every subsequent request. + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = handler.BuildClient(); + + await client.AuthenticateAsync(); + await client.AuthenticateAsync(); + + var lastRequest = handler.Requests.Last(); + var apiKeyValues = lastRequest.Headers.GetValues("X-API-KEY").ToList(); + Assert.Single(apiKeyValues); + Assert.Equal("key", apiKeyValues[0]); + } + + [Fact] + public async Task AuthenticateAsync_WithASuccessStatusButAnEmptyBody_LogsAuthenticationFailedForTheUsername() + { + // Regression test: a 2xx response whose body is empty/malformed deserializes to null (or + // throws on malformed JSON) without ever reaching the else-branch's own "Authentication + // failed" log - neither of AuthenticateAsync's other two failure-logging sites covered this + // case, so it used to surface only as a generic, identity-less error from whichever caller's + // catch block received the exception instead of this method's own identity-tagged record. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var handler = new FakeHttpMessageHandler() + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "null")); + var client = handler.BuildClient(); + + await Assert.ThrowsAnyAsync(() => client.AuthenticateAsync()); + + Assert.Contains(capturingFactory.Messages, + m => m.Contains("Authentication failed for", StringComparison.Ordinal) && + m.Contains("user", StringComparison.Ordinal)); + } + + [Fact] + public async Task AuthenticateAsync_WithASuccessStatusButNoTokenField_LogsAuthenticationFailedForTheUsername() + { + // Regression test: a well-formed 2xx JSON body simply missing (or empty on) the "token" field + // deserializes successfully to a non-null TokenResponse with BearerToken null - the null-body + // guard alone didn't catch this, so it used to fall through, set an empty/absent bearer token, + // and log "Authentication successful" instead of failing loudly. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var handler = new FakeHttpMessageHandler() + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + + await Assert.ThrowsAnyAsync(() => client.AuthenticateAsync()); + + Assert.Contains(capturingFactory.Messages, + m => m.Contains("Authentication failed for", StringComparison.Ordinal) && + m.Contains("user", StringComparison.Ordinal)); + Assert.DoesNotContain(capturingFactory.Messages, + m => m.Contains("Authentication successful", StringComparison.Ordinal)); + } + + [Fact] + public async Task AuthenticateAsync_WithMissingConfig_LogsAuthenticationFailedForTheUsername() + { + // Regression test: ValidateConfiguration()'s throw used to sit outside this method's try/catch + // entirely, so a missing ApiKey/Username/Password (e.g. Enabled=true with a blank ApiPassword, + // a state the plugin's own config comments explicitly anticipate) produced zero identity- + // tagged authentication-failure record from this method - only whichever generic, identity- + // less message an enclosing caller's own catch happened to log. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var handler = new FakeHttpMessageHandler(); + var client = new MarkMonitorClient("https://api.markmonitor.test", "key", "user", "", true, handler); + + await Assert.ThrowsAnyAsync(() => client.AuthenticateAsync()); + + Assert.Contains(capturingFactory.Messages, + m => m.Contains("Authentication failed for", StringComparison.Ordinal) && + m.Contains("user", StringComparison.Ordinal) && + m.Contains("Password is required", StringComparison.Ordinal)); + Assert.Empty(handler.Requests); + } + + [Fact] + public async Task AuthenticateAsync_WhenTheAuthEndpointFails_DoesNotRetry() + { + // Regression test: AuthenticateAsync runs entirely inside EnsureAuthenticatedAsync's shared + // _authLock, held by every other concurrent Enroll/Revoke/Sync call on the same cached client + // that also needs a token. Retrying here (as SendWithRetryAsync would) multiplies the + // worst-case lock-hold time up to 3x a full HTTP timeout plus backoff during exactly the + // "MarkMonitor is degraded" scenario where that matters most - a single attempt here is + // deliberate, not an oversight. + var handler = new FakeHttpMessageHandler() + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var client = handler.BuildClient(); + + await Assert.ThrowsAnyAsync(() => client.AuthenticateAsync()); + + Assert.Equal(1, handler.Requests.Count(r => FakeHttpMessageHandler.Is(r, "POST", "/auth/v1/auth/authenticate"))); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs new file mode 100644 index 0000000..2feb994 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs @@ -0,0 +1,118 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientCancelTests +{ + [Fact] + public async Task CancelCertificateAsync_SendsAValidJsonBody() + { + // Confirmed against the live MarkMonitor sandbox: PATCH .../cancel with an empty string body + // (not valid JSON) fails with a vague "Error retrieving order information (order.getError)". + // The exact same order succeeded immediately when PATCHed with "{}" instead. An empty string + // is not the same as an empty JSON object as far as MarkMonitor's API is concerned. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", "/certs/v1/order/11111111-1111-1111-1111-111111111111/cancel"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.CancelCertificateAsync("11111111-1111-1111-1111-111111111111"); + + Assert.True(result); + var cancelRequest = + Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", "/cancel")); + var body = await cancelRequest.Content!.ReadAsStringAsync(); + Assert.Equal("{}", body); + } + + [Fact] + public async Task RevokeCertificateAsync_SendsAValidJsonBody() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", "/certs/v1/order/11111111-1111-1111-1111-111111111111/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.RevokeCertificateAsync("11111111-1111-1111-1111-111111111111"); + + Assert.True(result); + var revokeRequest = + Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", "/revoke")); + var body = await revokeRequest.Content!.ReadAsStringAsync(); + Assert.Equal("{}", body); + } + + [Fact] + public async Task CancelCertificateAsync_WithMatchingOrganization_Succeeds() + { + // Mirrors RevokeCertificateAsync's cross-org ownership check (see + // MarkMonitorClientRevokeTests) - CancelCertificateAsync must apply the identical check. + const string orderId = "11111111-1111-1111-1111-111111111111"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{orderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(orderId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/cancel"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.CancelCertificateAsync(orderId, "Test Org"); + + Assert.True(result); + } + + [Fact] + public async Task CancelCertificateAsync_WhenTheOrderBelongsToADifferentOrganization_ThrowsWithoutCancelling() + { + const string orderId = "11111111-1111-1111-1111-111111111111"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{orderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(orderId, "DIGI_ISSUED", + organizationId: "99999999-9999-9999-9999-999999999999"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/cancel"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.CancelCertificateAsync(orderId, "Test Org")); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "PATCH", "/cancel")); + } + + [Fact] + public async Task CancelCertificateAsync_WithNoOrganizationGiven_ProceedsWithoutTheOwnershipCheck() + { + // A blank orgName intentionally skips the ownership check (ad-hoc/manual callers that don't + // scope by organization) - matching RevokeCertificateAsync's existing behavior for this case. + const string orderId = "11111111-1111-1111-1111-111111111111"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/cancel"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.CancelCertificateAsync(orderId); + + Assert.True(result); + // No organization lookup or order fetch should happen when orgName is blank. + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "GET", "/certs/v1/organization")); + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "GET", $"/certs/v1/order/{orderId}")); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs new file mode 100644 index 0000000..65fb3b5 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs @@ -0,0 +1,57 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Newtonsoft.Json.Linq; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientCleanSubjectTests +{ + private static async Task EnrollAndGetSentCommonName(string subject) + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var config = SampleConfig.Default(); + + await client.EnrollCertificateAsync(SampleCsr.Pem, subject, new Dictionary(), + "SslDvGeotrust", new Dictionary(), config); + + var orderRequest = handler.Requests.Single(req => FakeHttpMessageHandler.Is(req, "POST", "/order")); + var body = await orderRequest.Content!.ReadAsStringAsync(); + return JObject.Parse(body)["cert"]!["commonName"]!.Value()!; + } + + [Fact] + public async Task EnrollCertificateAsync_WithCommaEscapedInCommonName_DoesNotTruncateAtTheEscapedComma() + { + // Plain IndexOf(",") string-slicing would cut this off at "Doe" instead of the real CN + // "Doe, John" - X509Name's RFC 2253 parser handles the backslash escape correctly. + var commonName = await EnrollAndGetSentCommonName("CN=Doe\\, John,O=Acme"); + + Assert.Equal("Doe, John", commonName); + } + + [Fact] + public async Task EnrollCertificateAsync_WithSimpleCommonName_StillWorks() + { + var commonName = await EnrollAndGetSentCommonName("CN=test.mmcertdomain.com"); + + Assert.Equal("test.mmcertdomain.com", commonName); + } + + [Fact] + public async Task EnrollCertificateAsync_WithMultiRdnSubject_ExtractsJustTheCommonName() + { + var commonName = await EnrollAndGetSentCommonName("CN=test.mmcertdomain.com,O=Acme,C=US"); + + Assert.Equal("test.mmcertdomain.com", commonName); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs new file mode 100644 index 0000000..3a137c0 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs @@ -0,0 +1,18 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientDisposeTests +{ + [Fact] + public async Task Dispose_DisposesTheUnderlyingHttpClient() + { + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = handler.BuildClient(); + + client.Dispose(); + + await Assert.ThrowsAsync(() => client.AuthenticateAsync()); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs new file mode 100644 index 0000000..1294890 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs @@ -0,0 +1,411 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Microsoft.Extensions.Logging; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorClientEnrollIdempotencyTests +{ + private static MarkMonitorConfig Config() => SampleConfig.Default(); + + private static int OrderCreationCount(FakeHttpMessageHandler handler) => + handler.Requests.Count(r => FakeHttpMessageHandler.Is(r, "POST", "/certs/v1/order")); + + private static FakeHttpMessageHandler BuildHandler(string orderId = "11111111-1111-1111-1111-111111111111") => + new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, SampleOrders.OrderWithCert(orderId, "CREATED"))); + + [Fact] + public async Task EnrollCertificateAsync_CalledTwiceWithTheSameCsrAndSubject_OnlyCreatesOneOrder() + { + // Simulates Command retrying an Enroll call whose first attempt actually succeeded server- + // side but whose response was lost (timeout, dropped connection). + var handler = BuildHandler(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var first = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + var second = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.Equal(1, OrderCreationCount(handler)); + Assert.Equal(first.CARequestID, second.CARequestID); + } + + [Fact] + public async Task EnrollCertificateAsync_CalledTwiceWithDifferentCsrs_CreatesTwoOrders() + { + var handler = BuildHandler(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + await client.EnrollCertificateAsync(SampleCsr2.Pem, "CN=other.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.Equal(2, OrderCreationCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_CalledTwiceWithTheSameCsrAndSubject_DedupeLogIncludesResolvedCARequestID() + { + // Regression test for https://github.com/Keyfactor/markmonitor-caplugin/issues/7 - the + // dedup-hit warning used to be logged before awaiting the in-flight reservation, so it could + // never report the CARequestID the caller was actually folded into. It must now be logged + // after the reservation resolves, and must include that CARequestID. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var handler = BuildHandler(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var first = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + var second = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.Equal(1, OrderCreationCount(handler)); + Assert.Equal(first.CARequestID, second.CARequestID); + + var dedupeLog = Assert.Single(capturingFactory.Entries, + e => e.Level == LogLevel.Warning && e.Message.Contains("already submitted", StringComparison.Ordinal)); + Assert.Contains(first.CARequestID, dedupeLog.Message, StringComparison.Ordinal); + } + + [Fact] + public async Task EnrollCertificateAsync_CalledAgainAfterTheDedupeWindowExpires_CreatesASecondOrder() + { + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var handler = BuildHandler(); + var client = handler.BuildClient(clock); + await client.AuthenticateAsync(); + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + clock.UtcNow = clock.UtcNow.AddMinutes(6); + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.Equal(2, OrderCreationCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_RetriedWhileTheFirstCallIsStillInFlight_OnlyCreatesOneOrder() + { + // The scenario this cache actually exists for: Command's retry doesn't wait for the first + // attempt to finish (or fail) - it can arrive while the original CreateCertificateOrder call + // is still in flight. Holds the order-creation response open with a gate so both calls are + // genuinely concurrent, rather than sequential. + var orderResponseGate = new TaskCompletionSource(); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .WhenGated(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), orderResponseGate.Task, + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var firstCall = client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + // Give the first call a chance to actually reach (and dispatch) the gated POST /order request + // before starting the "retry". + await WaitUntil(() => OrderCreationCount(handler) == 1); + + var secondCall = client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + orderResponseGate.SetResult(); + var results = await Task.WhenAll(firstCall, secondCall); + + Assert.Equal(1, OrderCreationCount(handler)); + Assert.Equal(results[0].CARequestID, results[1].CARequestID); + } + + [Fact] + public async Task EnrollCertificateAsync_RetriedAfterTheWindowNominallyExpiresButWhileStillGenuinelyInFlight_OnlyCreatesOneOrder() + { + // A reservation's nominal window (RecentEnrollmentWindow) is stamped when the call starts, not + // extended while it runs. If the real work takes longer than that window, a retry arriving + // after the nominal expiry - but while the original call is still genuinely in flight - must + // still be deduped, not race the still-running original into creating a second real order. + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var orderResponseGate = new TaskCompletionSource(); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .WhenGated(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), orderResponseGate.Task, + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var client = handler.BuildClient(clock); + await client.AuthenticateAsync(); + + var firstCall = client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + await WaitUntil(() => OrderCreationCount(handler) == 1); + + // Move well past the 5-minute nominal window while the first call is still gated/in-flight. + clock.UtcNow = clock.UtcNow.AddMinutes(6); + + var secondCall = client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + orderResponseGate.SetResult(); + var results = await Task.WhenAll(firstCall, secondCall); + + Assert.Equal(1, OrderCreationCount(handler)); + Assert.Equal(results[0].CARequestID, results[1].CARequestID); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenTheFirstAttemptFails_ARetryGetsAFreshAttemptRatherThanTheCachedFailure() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}"""), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync(SampleCsr.Pem, + "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + var retryResult = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.NotNull(retryResult); + Assert.Equal(2, OrderCreationCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_ManySuccessfulEnrollmentsOverTime_DoesNotAccumulateReservationsUnbounded() + { + // Regression test: _recentEnrollments used to have no eviction path for a *successful* + // enrollment - every unique CSR/subject left a permanent entry (holding the CSR and issued + // cert chain) for the remaining lifetime of the process. After the fix, a stale completed + // reservation is pruned the next time EnrollCertificateAsync runs, so the dictionary tracks + // only "enrollments within the last window", not "enrollments ever performed". + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var handler = BuildHandler(); + var client = handler.BuildClient(clock); + await client.AuthenticateAsync(); + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + Assert.Equal(1, client.RecentEnrollmentsCount); + + clock.UtcNow = clock.UtcNow.AddMinutes(6); + + await client.EnrollCertificateAsync(SampleCsr2.Pem, "CN=other.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + // Only the newest reservation should remain - the first, long-expired-and-completed one must + // have been pruned rather than kept forever. + Assert.Equal(1, client.RecentEnrollmentsCount); + } + + [Fact] + public async Task + EnrollCertificateAsync_WhenTheFirstAttemptFailsWithAnAmbiguousNetworkError_ARetryWithinTheWindowGetsTheSameFailureInsteadOfCreatingASecondOrder() + { + // Regression test: an ambiguous transport-level failure (here, HttpRequestException - the + // exception HttpClient throws for a dropped connection) used to be treated identically to a + // definite rejection, evicting the reservation immediately. A Command retry for the same + // subject/CSR within the window would then find no reservation and create a second, real + // MarkMonitor order - even though the first order might have actually gone through server-side + // before the connection dropped. After the fix, the reservation stays active for an ambiguous + // failure, so the retry is folded into the same failed reservation instead of racing ahead. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + _ => Task.FromException(new HttpRequestException("Simulated connection reset"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync(SampleCsr.Pem, + "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync(SampleCsr.Pem, + "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + Assert.Equal(1, OrderCreationCount(handler)); + } + + [Fact] + public async Task + EnrollCertificateAsync_WhenAnEarlierStepFailsWithATransientNetworkError_ARetryGetsAFreshAttemptRatherThanBeingLockedOut() + { + // Regression test: EnrollCertificateAsync used to classify ANY HttpRequestException/ + // TaskCanceledException between winning the dedup reservation and CreateCertificateOrder + // completing as "ambiguous" - even one raised by an earlier step (here, organization + // resolution) that runs strictly before the order-create POST is ever issued and so can never + // have created an order. That kept the reservation active, so a same-second retry got the same + // stale exception replayed at it instead of a fresh attempt - a single transient blip during + // org lookup meant a guaranteed enrollment failure for the rest of the dedupe window, with zero + // risk of a duplicate order to justify it. + // + // Three consecutive failures (not one) are needed here since SendWithRetryAsync (added for + // client-level retry) now retries a transient network error up to 3 times on its own before + // giving up - a single failure would be transparently absorbed by that retry and never reach + // EnrollCertificateAsync's own ambiguity handling at all. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromResult(FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact())))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync(SampleCsr.Pem, + "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + var retryResult = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.NotNull(retryResult); + Assert.Equal(1, OrderCreationCount(handler)); + } + + [Fact] + public async Task + EnrollCertificateAsync_WhenMarkMonitorReturnsSuccessWithAnUnparsableBody_ARetryWithinTheWindowDoesNotCreateASecondOrder() + { + // Regression test: a 2xx order-create response whose body fails to deserialize used to fall + // through CreateCertificateOrder's generic catch as an ordinary exception - not an + // HttpRequestException/TaskCanceledException - so EnrollCertificateAsync's isAmbiguousOutcome + // check treated it as a *definite* failure and evicted the dedup reservation. But MarkMonitor + // had already confirmed (2xx) the order was created - stronger evidence than merely ambiguous + // - so a Command retry finding no reservation would have created a genuine duplicate order. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, "not valid json")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync( + SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync( + SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + Assert.Equal(1, OrderCreationCount(handler)); + } + + [Fact] + public async Task + EnrollCertificateAsync_WhenMarkMonitorReturnsSuccessWithANullBody_ARetryWithinTheWindowDoesNotCreateASecondOrder() + { + // Regression test: a 2xx order-create response whose body is empty/literal "null" deserializes + // to a null OrderContent WITHOUT throwing (Newtonsoft.Json doesn't throw for this case), so it + // slipped past the try/catch that converts unparsable bodies into + // MarkMonitorOrderCreatedButUnparsableException, falling through to `order.Id` and throwing a + // plain NullReferenceException instead - a type isAmbiguousOutcome doesn't recognize, so the + // reservation was evicted and a retry could create a genuine duplicate order. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, "null")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync( + SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync( + SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + Assert.Equal(1, OrderCreationCount(handler)); + } + + [Fact] + public async Task + EnrollCertificateAsync_WhenTheTokenExpiresDuringOrgResolutionAndTheNestedReAuthFails_EvictsTheReservation() + { + // Regression test: reachedCreateOrderCall used to be set immediately before calling + // CreateCertificateOrder, but CreateCertificateOrder itself runs its own EnsureAuthenticatedAsync + // check before ever sending the order-create POST. If the token expired again during org/ + // contact/group resolution (a slow lookup against a large account), that nested re-auth + // attempt's own failure was misclassified as "ambiguous, order might exist" even though the + // order-create POST was never reached - keeping a dedup reservation active for the rest of the + // window and locking out a retry that would otherwise succeed immediately. + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var handler = new FakeHttpMessageHandler() + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), + _ => Task.FromResult(FakeHttpMessageHandler.Json(HttpStatusCode.OK, + """{"token":"fake-token","expiresIn":60}""")), + _ => Task.FromException(new HttpRequestException("Simulated connection reset"))) + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), _ => + { + clock.UtcNow = clock.UtcNow.AddSeconds(100); // Expire the token while "resolving" the org. + return Task.FromResult(FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + }); + var client = handler.BuildClient(clock); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.EnrollCertificateAsync(SampleCsr.Pem, + "CN=test.mmcertdomain.com", new Dictionary(), "SslDvGeotrust", + new Dictionary(), Config())); + + // The failure happened before the order-create POST was ever reached, so the dedup reservation + // must have been evicted immediately, not kept "ambiguous" for the rest of the window. + Assert.Equal(0, client.RecentEnrollmentsCount); + } + + private static async Task WaitUntil(Func condition) + { + var deadline = DateTime.UtcNow.AddSeconds(5); + while (!condition()) + { + if (DateTime.UtcNow > deadline) throw new TimeoutException("Condition was never met."); + await Task.Delay(5); + } + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs new file mode 100644 index 0000000..5191164 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs @@ -0,0 +1,147 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorClientEnrollLoggingTests +{ + [Fact] + public async Task EnrollCertificateAsync_WithNoResolvableContactOrGroup_StillSucceeds() + { + // Logging the resolved ContactId/GroupId against the new order's CARequestID must not throw + // when either is null (no contact on the org, no MarkmonitorGroup param supplied). + const string orgWithNoContacts = """ + {"id": "11111111-1111-1111-1111-111111111111", "name": "Test Org", + "provider": "DIGICERT", "providerId": 1, "contacts": []} + """; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrgs.OrgsListResponse(orgWithNoContacts))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("22222222-2222-2222-2222-222222222222", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var config = SampleConfig.Default(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), config); + + Assert.NotNull(result); + Assert.Equal("22222222-2222-2222-2222-222222222222", result.CARequestID); + } + + [Fact] + public async Task EnrollCertificateAsync_WithCrLfInGroupAndDcvMethodParams_SanitizesThemInLogOutput() + { + // Regression test (CWE-117), extending the Subject/CommonName sanitization to the other + // requester-controlled, free-text enrollment template parameters (MarkmonitorGroup, DCVMethod, + // Comments, Locale, Provider) - a full-review round found the first fix only covered + // Subject/CommonName, leaving the same forged-log-line vector open through these fields. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + const string maliciousGroup = "no-such-group\r\n2026-08-10 09:00:00 [INF] FAKE forged log line"; + const string maliciousDcvMethod = "BOGUS\r\n2026-08-10 09:00:00 [INF] FAKE forged log line"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/auth/v1/group"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, """{"groups":[],"page":{"totalPages":1}}""")) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("22222222-2222-2222-2222-222222222222", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var productParams = new Dictionary + { + [MarkMonitorCAPluginConfig.EnrollmentConfigConstants.MarkmonitorGroup] = maliciousGroup, + [MarkMonitorCAPluginConfig.EnrollmentConfigConstants.DCVMethod] = maliciousDcvMethod + }; + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", productParams, SampleConfig.Default()); + + Assert.NotNull(result); + Assert.DoesNotContain(capturingFactory.Messages, m => m.Contains("\r\n", StringComparison.Ordinal)); + Assert.Contains(capturingFactory.Messages, + m => m.Contains("could not be resolved", StringComparison.OrdinalIgnoreCase) && + m.Contains("\\r\\n", StringComparison.Ordinal)); + Assert.Contains(capturingFactory.Messages, + m => m.Contains("Invalid DCVMethod", StringComparison.OrdinalIgnoreCase) && + m.Contains("\\r\\n", StringComparison.Ordinal)); + } + + [Fact] + public async Task EnrollCertificateAsync_ResolvingGroupByName_RequestsAPageSizeLargeEnoughToAvoidOneRoundTripPerMatch() + { + // Regression test: ResolveGroupIdAsync used to request the server default page size (no + // `size=` param at all) instead of the larger page size ResolveOrganizationIdAsync already + // uses for the identical fuzzy-match, filter-by-exact-name pattern - risking one sequential + // HTTP round-trip per fuzzy-matching group instead of one round-trip total. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/auth/v1/group"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, """{"groups":[],"page":{"totalPages":1}}""")) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("33333333-3333-3333-3333-333333333333", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var productParams = new Dictionary + { + [MarkMonitorCAPluginConfig.EnrollmentConfigConstants.MarkmonitorGroup] = "some-group" + }; + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", productParams, SampleConfig.Default()); + + var groupRequest = Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "GET", "/auth/v1/group")); + Assert.Contains("size=100", groupRequest.RequestUri!.Query); + } + + [Fact] + public async Task EnrollCertificateAsync_CalledTwiceWithTheSameGroupName_OnlyResolvesTheGroupOnce() + { + // Regression test: resolving a named MarkmonitorGroup used to make a fresh MarkMonitor API + // call on every single enrollment, even though a resolved group name never maps to a + // different GUID later - a real cost at steady enrollment volume. A resolved group GUID is + // now cached for this client's lifetime. + const string groupId = "44444444-4444-4444-4444-444444444444"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/auth/v1/group"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + $$"""{"groups":[{"id":"{{groupId}}","name":"some-group"}],"page":{"totalPages": 1} }""")) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("55555555-5555-5555-5555-555555555555", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var productParams = new Dictionary + { + [MarkMonitorCAPluginConfig.EnrollmentConfigConstants.MarkmonitorGroup] = "some-group" + }; + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test1.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", productParams, SampleConfig.Default()); + await client.EnrollCertificateAsync(SampleCsr2.Pem, "CN=test2.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", productParams, SampleConfig.Default()); + + Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "GET", "/auth/v1/group")); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs new file mode 100644 index 0000000..773d5e6 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs @@ -0,0 +1,155 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientEnrollTests +{ + private static MarkMonitorConfig Config() => new() + { + BaseUrl = "https://api.markmonitor.test", + ApiKey = "key", + ApiUsername = "user", + ApiPassword = "pass", + OrgName = "Test Org", + Enabled = true, + PickupRetries = 0 // disable post-submit polling - not what these tests exercise + }; + + [Fact] + public async Task EnrollCertificateAsync_WhenCreateOrderReturnsValidationError_ThrowsWithRealDetail() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.BadRequest, + """{"validations":[{"field":"cert.csr","code":"field.invalidFormat","message":"The CSR format is invalid."}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => + client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config())); + + Assert.Contains("The CSR format is invalid", ex.Message); + Assert.Contains("cert.csr", ex.Message); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenOrgNameIsAGuid_FetchesTheOrganizationDirectlyById() + { + // The OrgId CA connection setting is documented as accepting either a friendly name or a + // GUID. Before this fix, a GUID was always passed as a *name* search filter, which would + // never match a real org (org names aren't GUIDs) and enrollment would fail with + // "Organization ID not found". + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/organization/{SampleOrgs.DefaultOrgId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrgs.OrgWithContact())) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("33333333-3333-3333-3333-333333333333", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var config = Config(); + config.OrgName = SampleOrgs.DefaultOrgId; + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), config); + + Assert.NotNull(result); + Assert.DoesNotContain(handler.Requests, + req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization?")); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenOrgNameIsAFriendlyName_SearchesOrganizationsByName() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("44444444-4444-4444-4444-444444444444", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.NotNull(result); + Assert.Contains(handler.Requests, req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization?")); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenEccCsrUsesExplicitCurveParameters_ThrowsWithoutSubmittingTheOrder() + { + // MarkMonitor silently fails an order for an ECC CSR whose key uses explicit curve + // parameters instead of a named-curve OID reference (confirmed against a live sandbox: the + // order reaches DIGI_FAILED in under a second, with no reason surfaced anywhere in the API). + // Reject it at enrollment time with an actionable error instead. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => + client.EnrollCertificateAsync(SampleEccCsrs.ExplicitCurvePem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config())); + + Assert.Contains("named curve", ex.Message); + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order")); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenEccCsrUsesANamedCurve_EnrollsSuccessfully() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("55555555-5555-5555-5555-555555555555", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleEccCsrs.NamedCurvePem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.NotNull(result); + Assert.Contains(handler.Requests, req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order")); + } + + [Fact] + public async Task EnrollCertificateAsync_WithANumericOrderTypeForAnUndefinedEnumValue_ThrowsWithoutSubmittingTheOrder() + { + // Regression test: Enum.Parse alone "succeeds" for any numeric string that + // fits the underlying int type, even with no member defined for that value (CertOrderTypes + // has 12 members, values 0-11) - Enum.IsDefined is the check that actually enforces membership. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => + client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "20", new Dictionary(), Config())); + + Assert.Contains("20", ex.Message); + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order")); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs new file mode 100644 index 0000000..f4bfa92 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs @@ -0,0 +1,54 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientErrorMessageRedactionTests +{ + [Fact] + public async Task UnrecognizedErrorShape_IsTruncatedRatherThanDumpedVerbatim() + { + // Order/contact payloads can carry customer PII (name, email). An unrecognized MarkMonitor + // error shape used to get dumped whole into the exception message / error-level logs. + var contactPii = "Jane Doe, jane.doe@example.com, " + new string('x', 300); + var unrecognizedBody = "{\"someUnexpectedField\": \"" + contactPii + "\"}"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, unrecognizedBody)); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => client.ListOrganizationsAsync()); + + Assert.True(ex.Message.Length < unrecognizedBody.Length); + Assert.Contains("(truncated)", ex.Message); + Assert.DoesNotContain(new string('x', 300), ex.Message); + } + + [Fact] + public async Task ValidationErrorMessageContainingCrLf_IsSanitizedInTheThrownException() + { + // Regression test (CWE-117): if MarkMonitor's own validation response ever echoes back a + // requester-controlled value (e.g. a CSR-derived field) verbatim in its "message" text, an + // embedded CR/LF must not reach this component's logs unescaped - the same guarantee already + // applied to every request-side field must hold for this response-derived path too. + const string maliciousMessage = + "cert.csr is invalid\r\n2026-08-10 09:00:00 [INF] Enrollment completed successfully for subject: CN=admin.internal"; + var validationBody = $$""" + {"validations":[{"field":"cert.csr","code":"field.invalidFormat","message":"{{maliciousMessage.Replace("\r\n", "\\r\\n")}}"}]} + """; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.BadRequest, validationBody)); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => client.ListOrganizationsAsync()); + + Assert.DoesNotContain("\r\n", ex.Message, StringComparison.Ordinal); + Assert.Contains("\\r\\n", ex.Message, StringComparison.Ordinal); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs new file mode 100644 index 0000000..2af548e --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs @@ -0,0 +1,109 @@ +using System.Collections.Concurrent; +using System.Net; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorClientErrorPropagationTests +{ + [Fact] + public async Task ListOrganizationsAsync_WhenTheApiErrors_ThrowsInsteadOfReturningNull() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => client.ListOrganizationsAsync()); + + Assert.Contains("An unexpected error occurred", ex.Message); + } + + [Fact] + public async Task ListCertificateOrdersAsync_WhenTheApiErrors_ThrowsInsteadOfReturningNull() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => client.ListCertificateOrdersAsync(0, "", "", 100)); + + Assert.Contains("An unexpected error occurred", ex.Message); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenListingOrdersFails_PropagatesTheRealErrorAndCompletesTheBuffer() + { + // Before this fix, a failure here was swallowed and GetCertificateInventoryAsync returned 0 + // - Synchronize() would report "0 certificates synced" as if the sync had genuinely found + // nothing, rather than failing loudly on a real API error. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + await Assert.ThrowsAsync(() => + client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None)); + + // The buffer must still be marked complete (in a `finally`) even on failure, or a consumer + // blocked on GetConsumingEnumerable() would hang forever. + Assert.True(buffer.IsAddingCompleted); + } + + [Fact] + public async Task ListGroupsAsync_WhenTheApiErrors_StillReturnsNullRatherThanThrowing() + { + // Unlike the org/order listing methods above, group resolution is an optional, best-effort + // lookup - EnrollCertificateAsync deliberately proceeds without a group when this fails, so + // this one method is expected to keep swallowing rather than throwing. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/auth/v1/group"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.ListGroupsAsync(0, 0, "Engineering"); + + Assert.Null(result); + } + + [Fact] + public async Task SendAndLogAsync_WhenTheUnderlyingCallFailsBeforeAnyResponse_StillLogsMethodAndUrl() + { + // Regression test: SendAndLogAsync only logged method/URL/status/elapsed-time after send() + // returned successfully - a transport-level failure (timeout, DNS failure, connection refused/ + // reset, TLS failure) never produces a response at all, so that log line never ran, leaving + // only whichever generic, URL-less message an enclosing caller's own catch happened to log. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + _ => Task.FromException(new HttpRequestException("Simulated connection reset"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.ListOrganizationsAsync()); + + Assert.Contains(capturingFactory.Messages, + m => m.Contains("GET", StringComparison.Ordinal) && + m.Contains("/certs/v1/organization", StringComparison.Ordinal) && + m.Contains("failed", StringComparison.OrdinalIgnoreCase)); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs new file mode 100644 index 0000000..170ab42 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs @@ -0,0 +1,82 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +/// +/// Regression tests for GitHub issue #8: FetchOrderAsync (the private helper behind +/// GetSingleOrderAsync/RevokeCertificateAsync) used to re-set the shared HttpClient's +/// Authorization header itself, directly from _bearerToken and with no locking - bypassing the +/// _authLock discipline that EnsureAuthenticatedAsync/AuthenticateAsync rely on to keep concurrent +/// callers from racing writes to that shared header. The fix removes the redundant, unguarded +/// re-set and relies solely on EnsureAuthenticatedAsync (called immediately above it) to have +/// already established the header under the lock. +/// +public class MarkMonitorClientFetchOrderAuthTests +{ + private const string OrderId = "99999999-9999-9999-9999-999999999999"; + + private static int AuthCallCount(FakeHttpMessageHandler handler) => + handler.Requests.Count(r => FakeHttpMessageHandler.Is(r, "POST", "/auth/v1/auth/authenticate")); + + private static IEnumerable OrderRequests(FakeHttpMessageHandler handler) => + handler.Requests.Where(r => FakeHttpMessageHandler.Is(r, "GET", $"/certs/v1/order/{OrderId}")); + + [Fact] + public async Task GetSingleOrderAsync_SendsTheCurrentBearerTokenOnTheOrderRequest() + { + // Simple regression check: with the manual (unguarded) header re-set removed from + // FetchOrderAsync, the request must still carry the Authorization header that + // EnsureAuthenticatedAsync/AuthenticateAsync established under the lock. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth(token: "regression-token") + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED"))); + var client = handler.BuildClient(); + + await client.GetSingleOrderAsync(OrderId); + + var orderRequest = Assert.Single(OrderRequests(handler)); + Assert.NotNull(orderRequest.Headers.Authorization); + Assert.Equal("Bearer", orderRequest.Headers.Authorization!.Scheme); + Assert.Equal("regression-token", orderRequest.Headers.Authorization!.Parameter); + } + + [Fact] + public async Task GetSingleOrderAsync_CalledConcurrentlyWithAnExpiredToken_OnlyAuthenticatesOnceAndSendsTheRefreshedTokenOnBothRequests() + { + // Before the fix, FetchOrderAsync set the shared HttpClient's Authorization header itself, + // unguarded by _authLock, immediately after calling EnsureAuthenticatedAsync. Two concurrent + // FetchOrderAsync calls racing a concurrent re-authentication could interleave writes to + // that shared header. Gate the auth response so both calls are genuinely in flight together + // (mirrors EnsureAuthenticatedAsync_CalledConcurrentlyWithAnExpiredToken_OnlyAuthenticatesOnce + // in MarkMonitorClientAuthLifecycleTests, applied to the FetchOrderAsync code path). + var clock = new ManualTimeProvider { UtcNow = DateTimeOffset.UtcNow }; + var authGate = new TaskCompletionSource(); + var handler = new FakeHttpMessageHandler() + .WhenGated(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), authGate.Task, + FakeHttpMessageHandler.Json(HttpStatusCode.OK, """{"token":"refreshed-token","expiresIn":3600}""")) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED"))); + var client = handler.BuildClient(clock); + + // No prior AuthenticateAsync call, so both concurrent calls see an expired/missing token + // and race into EnsureAuthenticatedAsync at the same time. + var firstCall = client.GetSingleOrderAsync(OrderId); + var secondCall = client.GetSingleOrderAsync(OrderId); + authGate.SetResult(); + await Task.WhenAll(firstCall, secondCall); + + Assert.Equal(1, AuthCallCount(handler)); + + var orderRequests = OrderRequests(handler).ToList(); + Assert.Equal(2, orderRequests.Count); + Assert.All(orderRequests, req => + { + Assert.NotNull(req.Headers.Authorization); + Assert.Equal("Bearer", req.Headers.Authorization!.Scheme); + Assert.Equal("refreshed-token", req.Headers.Authorization!.Parameter); + }); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs new file mode 100644 index 0000000..01d0b9e --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs @@ -0,0 +1,112 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Keyfactor.PKI.Enums.EJBCA; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientGetSingleOrderTests +{ + [Fact] + public async Task GetSingleOrderAsync_ForIssuedOrder_ReturnsNonNullResultWithoutThrowing() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/55555555-5555-5555-5555-555555555555"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert("55555555-5555-5555-5555-555555555555", "DIGI_ISSUED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.GetSingleOrderAsync("55555555-5555-5555-5555-555555555555"); + + Assert.NotNull(result); + Assert.Equal("55555555-5555-5555-5555-555555555555", result.CARequestID); + Assert.Equal((int)EndEntityStatus.GENERATED, result.Status); + Assert.Null(result.RevocationDate); + } + + [Fact] + public async Task GetSingleOrderAsync_ForRevokedOrder_SetsRevocationDateFromDateValidUntil() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/66666666-6666-6666-6666-666666666666"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert("66666666-6666-6666-6666-666666666666", "DIGI_REVOKED", "REVOKED", "2026-03-01T00:00:00Z"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.GetSingleOrderAsync("66666666-6666-6666-6666-666666666666"); + + Assert.NotNull(result); + Assert.Equal((int)EndEntityStatus.REVOKED, result.Status); + Assert.Equal(new DateTime(2026, 3, 1), result.RevocationDate); + } + + [Fact] + public async Task GetSingleOrderAsync_WhenTheApiErrors_ThrowsInsteadOfReturningNull() + { + // Before this fix, any failure here (auth expiry, network blip, malformed body) was + // logged and then swallowed to null - GetSingleRecord would log a false "retrieved + // successfully" line right after the real error, and Command would see "not found" + // instead of a real, actionable error. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/77777777-7777-7777-7777-777777777777"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync( + () => client.GetSingleOrderAsync("77777777-7777-7777-7777-777777777777")); + + Assert.Contains("An unexpected error occurred", ex.Message); + } + + [Fact] + public async Task GetSingleOrderAsync_ForOrderWithNoCertYet_ReturnsAResultWithoutThrowing() + { + // Cert can be null for an order that hasn't progressed far enough yet (e.g. CREATED) - same + // class of gap already fixed in GetCertificateInventoryAsync. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/88888888-8888-8888-8888-888888888888"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithNullCert("88888888-8888-8888-8888-888888888888", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.GetSingleOrderAsync("88888888-8888-8888-8888-888888888888"); + + Assert.NotNull(result); + Assert.Equal("88888888-8888-8888-8888-888888888888", result.CARequestID); + Assert.Null(result.Certificate); + Assert.Null(result.RevocationDate); + } + + [Fact] + public async Task GetSingleOrderAsync_CalledRepeatedly_DoesNotAccumulateDuplicateAcceptHeaders() + { + // Regression test: FetchOrderAsync used to Add() an "application/json" Accept header on the + // shared, cached HttpClient on every call with no preceding Remove() - since Accept is a + // collection, not a single-value property, that appended a fresh duplicate entry per call, + // unboundedly growing the header list (sent on every subsequent request) for the life of the + // cached client. The Accept header is now set once, in the constructor. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/99999999-9999-9999-9999-999999999999"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert("99999999-9999-9999-9999-999999999999", "DIGI_ISSUED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + for (var i = 0; i < 3; i++) + await client.GetSingleOrderAsync("99999999-9999-9999-9999-999999999999"); + + var orderRequests = handler.Requests.Where(r => + FakeHttpMessageHandler.Is(r, "GET", "/certs/v1/order/99999999-9999-9999-9999-999999999999")); + Assert.All(orderRequests, r => Assert.Single(r.Headers.Accept)); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs new file mode 100644 index 0000000..25e857d --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs @@ -0,0 +1,112 @@ +using System.Collections.Concurrent; +using System.Net; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientInventoryTests +{ + [Fact] + public async Task GetCertificateInventoryAsync_WhenOneOrderHasNoCertYet_SkipsItButKeepsTheRest() + { + // A page containing one order with cert:null (plausible for a CREATED/DIGI_NEEDS_CSR order) + // used to NRE partway through the foreach, get swallowed by the outer catch, and silently + // drop every remaining order on that page - Synchronize() would report success while quietly + // losing certificates from Command's inventory. + var ordersJson = string.Join(",", new[] + { + SampleOrders.OrderWithNullCert("99999999-9999-9999-9999-999999999999", "CREATED"), + SampleOrders.OrderWithCert("77777777-7777-7777-7777-777777777777", "DIGI_ISSUED"), + SampleOrders.OrderWithCert("88888888-8888-8888-8888-888888888888", "DIGI_ISSUED") + }); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrdersPage(ordersJson))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None); + + Assert.Equal(2, count); + var collected = buffer.ToList(); + Assert.Equal(2, collected.Count); + Assert.DoesNotContain(collected, c => c.CARequestID == "99999999-9999-9999-9999-999999999999"); + Assert.Contains(collected, c => c.CARequestID == "77777777-7777-7777-7777-777777777777"); + Assert.Contains(collected, c => c.CARequestID == "88888888-8888-8888-8888-888888888888"); + } + + [Fact] + public async Task GetCertificateInventoryAsync_CancelledWhilePagingThroughOrders_StopsRatherThanFetchingEveryRemainingPage() + { + // Regression test: the cancelToken passed in was never threaded into the paginated + // ListCertificateOrdersAsync HTTP fetch loop - the only place it was ever consulted was + // certificatesBuffer.Add(..., cancelToken), which only runs after every page has already been + // downloaded. A Command-initiated sync cancellation issued while still paging couldn't take + // effect until the entire (potentially very large) order list had already been fetched. + var page2Gate = new TaskCompletionSource(); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert( + "77777777-7777-7777-7777-777777777777", "DIGI_ISSUED"), totalPages: 2))) + .WhenGated(req => FakeHttpMessageHandler.Is(req, "GET", "page=1"), page2Gate.Task, + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert( + "88888888-8888-8888-8888-888888888888", "DIGI_ISSUED"), totalPages: 2))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + using var cts = new CancellationTokenSource(); + + var syncTask = client.GetCertificateInventoryAsync("", "", 100, buffer, cts.Token); + await Task.Delay(50); // Let the first page complete and the second page's gated fetch start. + cts.Cancel(); + + await Assert.ThrowsAnyAsync(() => syncTask); + // The gated (never-released) second page must not have been allowed to complete the sync. + Assert.False(page2Gate.Task.IsCompleted); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WithMultiplePages_AddsEachPageToTheBufferAsItArrivesRatherThanWaitingForAllPages() + { + // Regression test: ListCertificateOrdersAsync used to accumulate every page's orders into one + // in-memory list before ever returning, so GetCertificateInventoryAsync's buffer-writing loop + // saw zero throughput until the entire (potentially huge) order history had downloaded. Page 1 + // must reach the buffer before page 2's gated fetch is ever released. + var page2Gate = new TaskCompletionSource(); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert( + "77777777-7777-7777-7777-777777777777", "DIGI_ISSUED"), totalPages: 2))) + .WhenGated(req => FakeHttpMessageHandler.Is(req, "GET", "page=1"), page2Gate.Task, + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert( + "88888888-8888-8888-8888-888888888888", "DIGI_ISSUED"), totalPages: 2))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var syncTask = client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None); + + // Page 1's certificate must already be in the buffer while page 2 is still gated/pending - + // proving the buffer is fed page-by-page, not only after the whole order history downloads. + var firstFromBuffer = buffer.Take(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token); + Assert.Equal("77777777-7777-7777-7777-777777777777", firstFromBuffer.CARequestID); + Assert.False(page2Gate.Task.IsCompleted); + + page2Gate.SetResult(); + var count = await syncTask; + + Assert.Equal(2, count); + var second = buffer.Take(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token); + Assert.Equal("88888888-8888-8888-8888-888888888888", second.CARequestID); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs new file mode 100644 index 0000000..d9e4e63 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs @@ -0,0 +1,88 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientOrderIdValidationTests +{ + private const string NotAGuid = "../../etc/passwd"; + + [Fact] + public async Task GetSingleOrderAsync_WithNonGuidOrderId_ThrowsWithoutMakingARequest() + { + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.GetSingleOrderAsync(NotAGuid)); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "GET", "/order/")); + } + + [Fact] + public async Task CancelCertificateAsync_WithNonGuidOrderId_ThrowsWithoutMakingARequest() + { + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.CancelCertificateAsync(NotAGuid)); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "PATCH", "/cancel")); + } + + [Fact] + public async Task RevokeCertificateAsync_WithNonGuidOrderId_ThrowsWithoutMakingARequest() + { + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.RevokeCertificateAsync(NotAGuid)); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "PATCH", "/revoke")); + } + + [Fact] + public async Task GetOrganizationAsync_WithNonGuidOrgId_ThrowsWithoutMakingARequest() + { + // GetOrganizationAsync's URL interpolates orgId directly (/certs/v1/organization/{orgId}), + // same class of injection risk ValidateGuidFormat already guards against for order IDs. + // + // Asserting the specific exception type matters here: dot-segments in NotAGuid get + // normalized out of the request URI by Uri/HttpClient regardless of whether validation ran, + // so a looser assertion (e.g. "no organization/ in the URI") would pass even if + // ValidateGuidFormat were deleted - only asserting ArgumentException (vs. whatever the fake + // handler's "no route registered" exception would surface as) actually proves validation + // ran before any request was attempted. + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.GetOrganizationAsync(NotAGuid)); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "GET", "/organization/")); + } + + [Fact] + public async Task GetOrganizationAsync_WhenTheApiErrors_ThrowsInsteadOfReturningNull() + { + // Before this fix, any failure here (auth expiry, network blip, malformed body) was logged + // and then swallowed to null - a caller resolving a GUID-configured OrgId (EnrollCertificateAsync's + // ResolveOrganizationAsync) would report a misleading "Organization ID not found" instead of + // the real error - same class of gap already fixed in GetSingleOrderAsync. + const string orgId = "11111111-1111-1111-1111-111111111111"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/organization/{orgId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => client.GetOrganizationAsync(orgId)); + + Assert.Contains("An unexpected error occurred", ex.Message); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs new file mode 100644 index 0000000..3f36596 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs @@ -0,0 +1,153 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Newtonsoft.Json.Linq; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +/// +/// Regression coverage for GitHub issue #9: ResolveOrganizationAsync/ResolveOrganizationIdAsync used +/// to take the *first* org MarkMonitor's name search returned without checking it was an exact match. +/// If MarkMonitor's /certs/v1/organization name filter does substring/fuzzy matching, a configured org +/// name that's a substring of another org's name (e.g. "Acme" vs "Acme Corp Europe") could silently +/// resolve to the wrong organization - undermining the cross-org ownership check in +/// RevokeCertificateAsync. Both resolvers must filter to an exact (case-insensitive) name match. +/// +public class MarkMonitorClientOrgResolutionTests +{ + private const string ExactOrgId = "11111111-1111-1111-1111-111111111111"; + private const string SubstringOrgId = "33333333-3333-3333-3333-333333333333"; + + [Fact] + public async Task EnrollCertificateAsync_WhenSearchReturnsASubstringFalsePositive_ResolvesTheExactMatchOnly() + { + // MarkMonitor's search for "Acme" returns both the exact org and an unrelated org whose name + // merely contains "Acme" - and, to prove the fix filters by exact match rather than list + // position, the substring false positive is returned *first*. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse( + SampleOrgs.OrgWithContact(SubstringOrgId, "Acme Corp Europe"), + SampleOrgs.OrgWithContact(ExactOrgId, "Acme")))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("44444444-4444-4444-4444-444444444444", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var config = SampleConfig.Default("Acme"); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), config); + + Assert.NotNull(result); + var orderRequest = Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "POST", "/order")); + var body = await orderRequest.Content!.ReadAsStringAsync(); + Assert.Equal(ExactOrgId, JObject.Parse(body)["organizationId"]!.Value(), + ignoreCase: true); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenNoExactNameMatchExists_ThrowsWithoutSubmittingTheOrder() + { + // Only the substring false positive is returned - there is no org actually named "Acme" - so + // resolution must fail the same way it always has for "no match", not fall back to the + // unrelated org. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact(SubstringOrgId, "Acme Corp Europe")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var config = SampleConfig.Default("Acme"); + + var ex = await Assert.ThrowsAsync(() => + client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), config)); + + Assert.Contains("not found", ex.Message, StringComparison.OrdinalIgnoreCase); + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order")); + } + + [Fact] + public async Task RevokeCertificateAsync_WhenSearchReturnsASubstringFalsePositive_ResolvesTheExactMatchOnly() + { + // The order actually belongs to the exact-match org. If the buggy "take the first result" + // behavior were still present, list order (substring false positive first) would resolve the + // configured "Acme" to the wrong org and this legitimate revoke would be wrongly refused. + const string orderId = "55555555-5555-5555-5555-555555555555"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse( + SampleOrgs.OrgWithContact(SubstringOrgId, "Acme Corp Europe"), + SampleOrgs.OrgWithContact(ExactOrgId, "Acme")))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{orderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(orderId, "DIGI_ISSUED", organizationId: ExactOrgId))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.RevokeCertificateAsync(orderId, "Acme"); + + Assert.True(result); + } + + [Fact] + public async Task RevokeCertificateAsync_WhenNoExactNameMatchExists_ThrowsWithoutRevoking() + { + // Only the substring false positive is returned - there is no org actually named "Acme" - so + // resolution must come back empty (same "not found" contract as before) rather than falling + // back to the unrelated org and letting an unauthorized revoke through. + const string orderId = "55555555-5555-5555-5555-555555555555"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact(SubstringOrgId, "Acme Corp Europe")))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{orderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(orderId, "DIGI_ISSUED", organizationId: SubstringOrgId))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.RevokeCertificateAsync(orderId, "Acme")); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "PATCH", "/revoke")); + } + + [Fact] + public async Task EnrollCertificateAsync_ResolvingOrgByName_RequestsAPageSizeLargeEnoughToAvoidOneRoundTripPerMatch() + { + // Regression test: ResolveOrganizationAsync/ResolveOrganizationIdAsync used to hard-code a + // page size of 1 for the org-name search. Since MarkMonitor's name filter can return several + // fuzzy matches for one configured name, that forced one sequential HTTP round-trip per + // matching org just to page through them all before the exact-match filter (above) ever ran. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("44444444-4444-4444-4444-444444444444", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), + SampleConfig.Default()); + + var orgRequest = Assert.Single(handler.Requests, + req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization")); + var query = orgRequest.RequestUri!.Query; + Assert.Contains("size=100", query); + Assert.DoesNotContain("size=1&", query); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs new file mode 100644 index 0000000..263366a --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs @@ -0,0 +1,245 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Keyfactor.PKI.Enums.EJBCA; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +/// +/// Coverage for EnrollCertificateAsync's post-submit issuance polling - MarkMonitor always returns a +/// freshly-created order pending (never issued synchronously), so a fast-DCV product would otherwise +/// always report pending status back to Command even when it's about to issue within seconds. +/// +public class MarkMonitorClientPickupPollingTests +{ + private const string OrderId = "11111111-1111-1111-1111-111111111111"; + + private static MarkMonitorConfig Config(int pickupRetries = 5, int pickupDelaySeconds = 10) + { + var config = SampleConfig.Default(); + config.PickupRetries = pickupRetries; + config.PickupDelaySeconds = pickupDelaySeconds; + return config; + } + + private static int OrderFetchCount(FakeHttpMessageHandler handler) => + handler.Requests.Count(r => FakeHttpMessageHandler.Is(r, "GET", $"/certs/v1/order/{OrderId}")); + + private static FakeHttpMessageHandler BuildHandlerWithOrgAndCreate() => + new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, SampleOrders.OrderWithCert(OrderId, "CREATED"))); + + [Fact] + public async Task EnrollCertificateAsync_WhenTheOrderIssuesOnASubsequentPoll_ReturnsGeneratedWithTheCertificate() + { + var handler = BuildHandlerWithOrgAndCreate() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "CREATED")), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "CREATED")), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.Equal((int)EndEntityStatus.GENERATED, result.Status); + Assert.NotNull(result.Certificate); + Assert.Equal(3, OrderFetchCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenIssuanceNeverCompletesWithinTheBudget_FallsBackToThePendingStatus() + { + var handler = BuildHandlerWithOrgAndCreate() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config(pickupRetries: 3)); + + Assert.Equal((int)EndEntityStatus.EXTERNALVALIDATION, result.Status); + Assert.Equal(3, OrderFetchCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenTheBudgetExhaustsWithStatusIssuedButNoCertBodyYet_ReportsInProcessNotAFalseGenerated() + { + // Regression test: if MarkMonitor's status flips to issued a moment before the cert body is + // actually populated, IsPollingComplete correctly keeps polling (it requires both) - but if + // the budget exhausts at exactly that moment, the order comes back with an "issued" status + // and a null cert. Reporting GENERATED with Certificate=null would be an internally + // inconsistent result no caller expects for a successful enrollment. + var handler = BuildHandlerWithOrgAndCreate() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderIssuedWithoutCertBody(OrderId))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config(pickupRetries: 3)); + + Assert.Equal((int)EndEntityStatus.INPROCESS, result.Status); + Assert.Null(result.Certificate); + } + + [Fact] + public async Task EnrollCertificateAsync_WithPickupRetriesZero_SkipsPollingEntirely() + { + var handler = BuildHandlerWithOrgAndCreate(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config(pickupRetries: 0)); + + Assert.Equal((int)EndEntityStatus.EXTERNALVALIDATION, result.Status); + Assert.Equal(0, OrderFetchCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenTheCreateOrderResponseItselfIsIssuedWithoutACertBody_ReportsInProcessNotAFalseGenerated() + { + // Same consistency check applies even with polling disabled entirely (PickupRetries=0) - the + // inconsistency can in principle come straight from the order-create response itself, not + // only from a poll response. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, SampleOrders.OrderIssuedWithoutCertBody(OrderId))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config(pickupRetries: 0)); + + Assert.Equal((int)EndEntityStatus.INPROCESS, result.Status); + Assert.Null(result.Certificate); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenTheOrderReachesATerminalFailureWhilePolling_StopsPollingEarly() + { + var handler = BuildHandlerWithOrgAndCreate() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "DIGI_FAILED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config(pickupRetries: 5)); + + Assert.Equal((int)EndEntityStatus.FAILED, result.Status); + // Stopped after the first poll observed the terminal state, not all 5 configured attempts. + Assert.Equal(1, OrderFetchCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenAPollAttemptFailsTransiently_RetriesOnTheNextAttemptInsteadOfFailingTheEnrollment() + { + var handler = BuildHandlerWithOrgAndCreate() + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromResult(FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config(pickupRetries: 5)); + + Assert.Equal((int)EndEntityStatus.GENERATED, result.Status); + } + + [Fact] + public async Task EnrollCertificateAsync_PollsUsingTheConfiguredDelayWithoutARealSleep() + { + var recordedDelays = new List(); + var handler = BuildHandlerWithOrgAndCreate() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "CREATED")), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED"))); + var client = handler.BuildClient(delay: (delay, _) => + { + recordedDelays.Add(delay); + return Task.CompletedTask; + }); + await client.AuthenticateAsync(); + + await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), + Config(pickupRetries: 5, pickupDelaySeconds: 7)); + + Assert.Equal(2, recordedDelays.Count); + Assert.All(recordedDelays, d => Assert.Equal(TimeSpan.FromSeconds(7), d)); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenAlreadyIssuedFromTheCreateOrderCall_DoesNotPollAtAll() + { + // A fast-issuing product (not observed for MarkMonitor today, but the check should still be + // correct if it ever happens) shouldn't trigger any polling at all. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), Config()); + + Assert.Equal((int)EndEntityStatus.GENERATED, result.Status); + Assert.Equal(0, OrderFetchCount(handler)); + } + + [Fact] + public async Task EnrollCertificateAsync_WhenAPollAttemptFailsRepeatedly_EachOuterPollIsASingleHttpAttempt() + { + // Regression test: each poll's own order-fetch used to go through SendWithRetryAsync (up to + // 3 attempts per poll), multiplying a single hung/slow poll far past the documented + // PickupRetries*PickupDelaySeconds latency ceiling. It's now a single-attempt fetch, so a + // failure is retried only by the OUTER polling loop (one more poll delay + attempt), not + // absorbed 3-at-a-time inside a single outer attempt. + var pollDelayCount = 0; + var handler = BuildHandlerWithOrgAndCreate() + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromException(new HttpRequestException("Simulated connection reset")), + _ => Task.FromResult(FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED")))); + var client = handler.BuildClient(delay: (_, _) => + { + pollDelayCount++; + return Task.CompletedTask; + }); + await client.AuthenticateAsync(); + + var result = await client.EnrollCertificateAsync(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), "SslDvGeotrust", new Dictionary(), + Config(pickupRetries: 5)); + + Assert.Equal((int)EndEntityStatus.GENERATED, result.Status); + // 4 outer poll attempts (3 failures + 1 success), each a single HTTP request - if a poll + // attempt still retried internally, the 3 failures would be absorbed within one outer + // attempt (SendWithRetryAsync's own MaxRetryAttempts=3), needing only 2 outer attempts. + Assert.Equal(4, pollDelayCount); + Assert.Equal(4, OrderFetchCount(handler)); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs new file mode 100644 index 0000000..d802f98 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs @@ -0,0 +1,51 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientQueryEncodingTests +{ + [Fact] + public async Task ListGroupsAsync_WithSpecialCharactersInName_UrlEncodesTheQueryValue() + { + // MarkmonitorGroup is a template parameter supplied by whoever requests the certificate + // through Command, not just an admin - an unescaped "&"/"#"/space could inject extra query + // parameters or corrupt the request line. + const string groupName = "R&D Team #1"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/auth/v1/group"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + """{"groups":[],"page":{"size":0,"totalElements":0,"totalPages":0,"number":0}}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await client.ListGroupsAsync(0, 0, groupName); + + var groupRequest = Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "GET", "/group")); + var query = groupRequest.RequestUri!.Query; + Assert.DoesNotContain("R&D Team #1", query); + Assert.Contains(Uri.EscapeDataString(groupName), query); + } + + [Fact] + public async Task ListOrganizationsAsync_WithSpecialCharactersInName_UrlEncodesTheQueryValue() + { + const string orgName = "Acme & Sons"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrgs.OrgsListResponse(""))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await client.ListOrganizationsAsync(0, 1, orgName); + + var orgRequest = + Assert.Single(handler.Requests, req => FakeHttpMessageHandler.Is(req, "GET", "/organization")); + var query = orgRequest.RequestUri!.Query; + Assert.DoesNotContain("Acme & Sons", query); + Assert.Contains(Uri.EscapeDataString(orgName), query); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs new file mode 100644 index 0000000..8b93941 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs @@ -0,0 +1,211 @@ +using System.Net; +using System.Net.Http.Headers; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +/// +/// Coverage for SendWithRetryAsync (transient 5xx/429/network-failure retry with backoff) and the +/// configurable HttpClient timeout - and, just as importantly, that CreateCertificateOrder's +/// order-create POST deliberately does NOT go through that retry path (see its own comment). +/// +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorClientRetryTests +{ + private static int OrgRequestCount(FakeHttpMessageHandler handler) => + handler.Requests.Count(r => FakeHttpMessageHandler.Is(r, "GET", "/certs/v1/organization")); + + [Fact] + public async Task ListOrganizationsAsync_WhenATransient500IsFollowedBySuccess_RetriesAndSucceeds() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"Transient failure"}]}"""), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.ListOrganizationsAsync(); + + Assert.NotEmpty(result); + Assert.Equal(2, OrgRequestCount(handler)); + } + + [Fact] + public async Task ListOrganizationsAsync_WhenEveryAttemptReturns500_ThrowsAfterExactlyMaxRetryAttempts() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"Persistent failure"}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => client.ListOrganizationsAsync()); + + Assert.Contains("Persistent failure", ex.Message); + Assert.Equal(3, OrgRequestCount(handler)); + } + + [Fact] + public async Task ListOrganizationsAsync_WhenTheApiReturns400_DoesNotRetry() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.BadRequest, + """{"errors":[{"code":"request.badRequest","message":"Bad request"}]}""")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var ex = await Assert.ThrowsAsync(() => client.ListOrganizationsAsync()); + + Assert.Contains("Bad request", ex.Message); + Assert.Equal(1, OrgRequestCount(handler)); + } + + [Fact] + public async Task ListOrganizationsAsync_WhenEveryAttemptThrowsANetworkError_ThrowsAfterExactlyMaxRetryAttempts() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .WhenAsync(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + _ => Task.FromException(new HttpRequestException("Simulated connection reset"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.ListOrganizationsAsync()); + + Assert.Equal(3, OrgRequestCount(handler)); + } + + [Fact] + public async Task ListOrganizationsAsync_On429WithRetryAfterHeader_WaitsForTheAdvertisedDuration() + { + var recordedDelays = new List(); + var rateLimited = FakeHttpMessageHandler.Json(HttpStatusCode.TooManyRequests, "{}"); + rateLimited.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(2)); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + rateLimited, + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(delay: (delay, _) => + { + recordedDelays.Add(delay); + return Task.CompletedTask; + }); + await client.AuthenticateAsync(); + + var result = await client.ListOrganizationsAsync(); + + Assert.NotEmpty(result); + Assert.Equal(2, OrgRequestCount(handler)); + Assert.Equal(TimeSpan.FromSeconds(2), Assert.Single(recordedDelays)); + } + + [Fact] + public async Task ListOrganizationsAsync_On429WithAnExcessiveRetryAfterHeader_CapsTheDelay() + { + // Regression test: Retry-After is server-controlled input - a misbehaving/compromised + // endpoint returning an enormous value must not be trusted verbatim, since that delay can + // execute while _authLock is held (the auth call path) with no way to cancel it. + var recordedDelays = new List(); + var rateLimited = FakeHttpMessageHandler.Json(HttpStatusCode.TooManyRequests, "{}"); + rateLimited.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromDays(1)); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + rateLimited, + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(delay: (delay, _) => + { + recordedDelays.Add(delay); + return Task.CompletedTask; + }); + await client.AuthenticateAsync(); + + var result = await client.ListOrganizationsAsync(); + + Assert.NotEmpty(result); + Assert.Equal(TimeSpan.FromSeconds(120), Assert.Single(recordedDelays)); + } + + [Fact] + public async Task ListOrganizationsAsync_On500WithoutRetryAfter_BacksOffExponentiallyWithJitter() + { + var recordedDelays = new List(); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, "{}"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, "{}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var client = handler.BuildClient(delay: (delay, _) => + { + recordedDelays.Add(delay); + return Task.CompletedTask; + }); + await client.AuthenticateAsync(); + + await client.ListOrganizationsAsync(); + + Assert.Equal(2, recordedDelays.Count); + // Nominal 1s/2s ±25% jitter. + Assert.InRange(recordedDelays[0].TotalSeconds, 0.75, 1.25); + Assert.InRange(recordedDelays[1].TotalSeconds, 1.5, 2.5); + } + + [Fact] + public async Task CreateCertificateOrder_WhenTheApiReturns500_DoesNotRetryTheOrderCreatePost() + { + // The order-create POST must never be retried at this layer - a transport/5xx failure here + // is ambiguous about whether MarkMonitor already created the order, and EnrollCertificateAsync's + // dedup reservation (not this client-level retry) is what handles a caller-level retry safely. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"Transient failure"}]}"""), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.CreateCertificateOrder(new() + { + Cert = new() { CommonName = "test.mmcertdomain.com" }, + CertType = "SSL_DV_GEOTRUST", + Provider = "DIGICERT" + })); + + Assert.Equal(1, handler.Requests.Count(r => FakeHttpMessageHandler.Is(r, "POST", "/certs/v1/order"))); + } + + [Fact] + public void Constructor_WithATimeoutSecondsValue_FlowsItToTheUnderlyingHttpClient() + { + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = new MarkMonitorClient("https://api.markmonitor.test", "key", "user", "pass", true, handler, + timeoutSeconds: 45); + + Assert.Equal(TimeSpan.FromSeconds(45), client.HttpTimeout); + } + + [Fact] + public void Constructor_WithNoTimeoutSecondsValue_DefaultsTo120Seconds() + { + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var client = new MarkMonitorClient("https://api.markmonitor.test", "key", "user", "pass", true, handler); + + Assert.Equal(TimeSpan.FromSeconds(120), client.HttpTimeout); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs new file mode 100644 index 0000000..60c2e97 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs @@ -0,0 +1,137 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientRevokeTests +{ + [Theory] + [InlineData(0u)] + [InlineData(1u)] // keyCompromise + [InlineData(4u)] // superseded + public async Task RevokeCertificateAsync_WithAnyReasonCode_StillRevokesSuccessfully(uint reason) + { + // MarkMonitor's revoke API has no field for a reason code at all (confirmed against its + // published schema - OrderActionPatchObject only has cert/ignoreOrgCheck/additionalEmails), + // so the reason can't change what's sent. This just confirms passing one doesn't break the + // call - the actual "can't forward it" behavior is logged, not independently observable. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/11111111-1111-1111-1111-111111111111"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", "/certs/v1/order/11111111-1111-1111-1111-111111111111/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.RevokeCertificateAsync("11111111-1111-1111-1111-111111111111", "Test Org", reason); + + Assert.True(result); + } + + [Fact] + public async Task RevokeCertificateAsync_WhenTheOrderBelongsToADifferentOrganization_ThrowsWithoutRevoking() + { + // The prior cert's request ID in the RenewOrReissue path comes from Command's + // ICertificateDataReader, not from this org's own enrollment - so verify the order actually + // belongs to the configured org before revoking it, rather than trusting the caller. + const string orderId = "11111111-1111-1111-1111-111111111111"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{orderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(orderId, "DIGI_ISSUED", + organizationId: "99999999-9999-9999-9999-999999999999"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await Assert.ThrowsAsync(() => client.RevokeCertificateAsync(orderId, "Test Org")); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "PATCH", "/revoke")); + } + + [Fact] + public async Task RevokeCertificateAsync_WithOrgNameGivenAsAGuid_ResolvesWithoutAnOrganizationLookup() + { + const string orderId = "11111111-1111-1111-1111-111111111111"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{orderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(orderId, "DIGI_ISSUED", organizationId: SampleOrgs.DefaultOrgId))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.RevokeCertificateAsync(orderId, SampleOrgs.DefaultOrgId); + + Assert.True(result); + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "GET", "/certs/v1/organization")); + } + + [Fact] + public async Task RevokeCertificateAsync_WithOrgNameGuidInADifferentTextualFormat_StillMatchesTheOrder() + { + // Guid.TryParse accepts several textual formats (braces, no dashes, etc.) that an admin could + // legitimately configure, but MarkMonitor's API always serializes organizationId in one + // canonical form. The comparison must be by parsed Guid value, not raw string equality, or a + // legitimately-configured OrgId in a non-canonical format would be rejected as "wrong org". + const string orderId = "11111111-1111-1111-1111-111111111111"; + const string orgIdBraces = "{11111111-1111-1111-1111-111111111111}"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{orderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(orderId, "DIGI_ISSUED", organizationId: SampleOrgs.DefaultOrgId))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{orderId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.RevokeCertificateAsync(orderId, orgIdBraces); + + Assert.True(result); + } + + [Fact] + public async Task RevokeCertificateAsync_CalledTwiceWithTheSameOrgName_OnlyResolvesTheOrganizationOnce() + { + // Regression test: resolving OrgName by friendly name used to make a fresh MarkMonitor API + // call on every single Revoke/Cancel call, even though the configured value is invariant for + // the connector's (and this cached client's) lifetime - real cost at bulk-revocation scale. + // A resolved org GUID is now cached for this client's lifetime. + const string firstOrderId = "11111111-1111-1111-1111-111111111111"; + const string secondOrderId = "22222222-2222-2222-2222-222222222222"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{firstOrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(firstOrderId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{secondOrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(secondOrderId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", "/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await client.RevokeCertificateAsync(firstOrderId, "Test Org"); + await client.RevokeCertificateAsync(secondOrderId, "Test Org"); + + Assert.Single(handler.Requests, r => FakeHttpMessageHandler.Is(r, "GET", "/certs/v1/organization")); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs new file mode 100644 index 0000000..5f2c22d --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs @@ -0,0 +1,161 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +/// +/// Regression coverage for wiring Enroll's `san` dictionary (and any CSR-embedded SAN extension) +/// into the MarkMonitor order's `dnsNames` field - previously accepted and silently dropped, so a +/// multi-SAN enrollment issued CN-only. +/// +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorClientSanTests +{ + private static FakeHttpMessageHandler BuildHandler(string orderId = "11111111-1111-1111-1111-111111111111") => + new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, SampleOrders.OrderWithCert(orderId, "CREATED"))); + + private static async Task EnrollAndGetSentBody(string csrPem, string subject, + Dictionary? san, FakeHttpMessageHandler? handler = null) + { + handler ??= BuildHandler(); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + await client.EnrollCertificateAsync(csrPem, subject, san, "SslDvGeotrust", + new Dictionary(), SampleConfig.Default()); + + var orderRequest = handler.Requests.Single(req => FakeHttpMessageHandler.Is(req, "POST", "/order")); + var body = await orderRequest.Content!.ReadAsStringAsync(); + return JObject.Parse(body); + } + + private static List? DnsNamesOf(JObject body) => + body["cert"]!["dnsNames"]?.Values().Select(v => v!).ToList(); + + [Fact] + public async Task EnrollCertificateAsync_WithDnsSansInDictionary_PopulatesDnsNamesExcludingCn() + { + var san = new Dictionary { ["Dns"] = ["www.mmcertdomain.com", "test.mmcertdomain.com"] }; + + var body = await EnrollAndGetSentBody(SampleCsr.Pem, "CN=test.mmcertdomain.com", san); + + Assert.Equal(["www.mmcertdomain.com"], DnsNamesOf(body)); + } + + [Fact] + public async Task EnrollCertificateAsync_WithDnsnameKeyCasing_IsAcceptedCaseInsensitively() + { + var san = new Dictionary { ["dnsname"] = ["alt.mmcertdomain.com"] }; + + var body = await EnrollAndGetSentBody(SampleCsr.Pem, "CN=test.mmcertdomain.com", san); + + Assert.Equal(["alt.mmcertdomain.com"], DnsNamesOf(body)); + } + + [Fact] + public async Task EnrollCertificateAsync_WithEmptySanDictionaryAndNoCsrSans_OmitsDnsNamesFromTheRequest() + { + var body = await EnrollAndGetSentBody(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary()); + + Assert.Null(body["cert"]!["dnsNames"]); + } + + [Fact] + public async Task EnrollCertificateAsync_WithDuplicateDnsSans_DedupesThem() + { + var san = new Dictionary + { + ["Dns"] = ["www.mmcertdomain.com", "WWW.mmcertdomain.com", "www.mmcertdomain.com"] + }; + + var body = await EnrollAndGetSentBody(SampleCsr.Pem, "CN=test.mmcertdomain.com", san); + + Assert.Equal(["www.mmcertdomain.com"], DnsNamesOf(body)); + } + + [Fact] + public async Task EnrollCertificateAsync_WithNonDnsSanTypes_DropsThemAndLogsAWarning() + { + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + var san = new Dictionary + { + ["Dns"] = ["www.mmcertdomain.com"], + ["IpAddress"] = ["10.0.0.1"], + ["Email"] = ["admin@mmcertdomain.com"] + }; + + var body = await EnrollAndGetSentBody(SampleCsr.Pem, "CN=test.mmcertdomain.com", san); + + Assert.Equal(["www.mmcertdomain.com"], DnsNamesOf(body)); + var warning = Assert.Single(capturingFactory.Entries, + e => e.Level == LogLevel.Warning && e.Message.Contains("non-DNS SAN", StringComparison.Ordinal)); + Assert.Contains("IpAddress", warning.Message); + Assert.Contains("Email", warning.Message); + } + + [Fact] + public async Task EnrollCertificateAsync_WithSansOnlyEmbeddedInTheCsrAndNoSanDictionaryAtAll_UnionsThemIntoDnsNames() + { + // `san` is genuinely null here - Command never populated SAN data at all for this request - + // which is the only condition that falls back to the CSR's own SAN extension. + var csrPem = SampleCsrWithSans.GeneratePem("test.mmcertdomain.com", "csr-san.mmcertdomain.com"); + + var body = await EnrollAndGetSentBody(csrPem, "CN=test.mmcertdomain.com", null); + + Assert.Equal(["csr-san.mmcertdomain.com"], DnsNamesOf(body)); + } + + [Fact] + public async Task EnrollCertificateAsync_WithSansInBothTheDictionaryAndTheCsr_UsesOnlyTheDictionaryAndIgnoresTheCsr() + { + // Regression test for a security concern raised in review: a non-null `san` dictionary - + // even one that omits a domain the CSR itself carries - means Command's own enrollment + // pattern/template ran and is authoritative for this request. The CSR is subscriber-generated + // and outside Command's policy/RA control, so its own SAN extension must never be unioned in + // (let alone let through unauthorized domains) once Command has supplied a real dictionary - + // certinext-caplugin reverted the identical unconditional-union pattern for this exact reason. + var csrPem = SampleCsrWithSans.GeneratePem("test.mmcertdomain.com", "csr-only.mmcertdomain.com", + "shared.mmcertdomain.com"); + var san = new Dictionary { ["Dns"] = ["dict-san.mmcertdomain.com", "shared.mmcertdomain.com"] }; + + var body = await EnrollAndGetSentBody(csrPem, "CN=test.mmcertdomain.com", san); + + Assert.Equal(new HashSet { "dict-san.mmcertdomain.com", "shared.mmcertdomain.com" }, + DnsNamesOf(body)!.ToHashSet()); + Assert.DoesNotContain("csr-only.mmcertdomain.com", DnsNamesOf(body)!); + } + + [Fact] + public async Task EnrollCertificateAsync_WithANonNullEmptySanDictionaryAndCsrSans_IgnoresTheCsrSans() + { + // An empty-but-non-null dictionary means Command's enrollment pattern deliberately produced + // no SANs for this request - that must be respected, not silently overridden by the CSR. + var csrPem = SampleCsrWithSans.GeneratePem("test.mmcertdomain.com", "csr-san.mmcertdomain.com"); + + var body = await EnrollAndGetSentBody(csrPem, "CN=test.mmcertdomain.com", + new Dictionary()); + + Assert.Null(body["cert"]!["dnsNames"]); + } + + [Fact] + public async Task EnrollCertificateAsync_WithCsrSanMatchingTheCnAndNoSanDictionary_ExcludesItFromDnsNames() + { + var csrPem = SampleCsrWithSans.GeneratePem("test.mmcertdomain.com", "test.mmcertdomain.com", + "extra.mmcertdomain.com"); + + var body = await EnrollAndGetSentBody(csrPem, "CN=test.mmcertdomain.com", null); + + Assert.Equal(["extra.mmcertdomain.com"], DnsNamesOf(body)); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs new file mode 100644 index 0000000..c30d809 --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs @@ -0,0 +1,52 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Keyfactor.PKI.Enums.EJBCA; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +public class MarkMonitorClientStatusMappingTests +{ + private static async Task GetMappedStatus(string markMonitorStatus) + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/11111111-1111-1111-1111-111111111111"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", markMonitorStatus))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + + var result = await client.GetSingleOrderAsync("11111111-1111-1111-1111-111111111111"); + Assert.NotNull(result); + return result.Status; + } + + [Fact] + public async Task CreatedStatus_MapsToExternalValidation_NotInitialized() + { + // github.com/Keyfactor/markmonitor-caplugin/issues/2, verified against a real + // AnyGatewayREST + Command deployment: INITIALIZED (20) is not what the gateway framework + // treats as "accepted, still pending" - only EXTERNALVALIDATION (90) is. Mapping CREATED to + // INITIALIZED caused the gateway to report a hard enrollment failure for an order that had + // actually been created successfully at MarkMonitor and was simply awaiting DCV/issuance. + var status = await GetMappedStatus("CREATED"); + + Assert.Equal((int)EndEntityStatus.EXTERNALVALIDATION, status); + } + + [Theory] + [InlineData("DIGI_PENDING", EndEntityStatus.INPROCESS)] + [InlineData("DIGI_PROCESSING", EndEntityStatus.INPROCESS)] + [InlineData("DIGI_ISSUED", EndEntityStatus.GENERATED)] + [InlineData("DIGI_REVOKED", EndEntityStatus.REVOKED)] + [InlineData("DIGI_FAILED", EndEntityStatus.FAILED)] + [InlineData("DIGI_CANCELED", EndEntityStatus.CANCELLED)] + [InlineData("DIGI_REJECTED", EndEntityStatus.CANCELLED)] + public async Task OtherStatuses_MapAsExpected(string markMonitorStatus, EndEntityStatus expected) + { + var status = await GetMappedStatus(markMonitorStatus); + + Assert.Equal((int)expected, status); + } +} diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs new file mode 100644 index 0000000..126297c --- /dev/null +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs @@ -0,0 +1,289 @@ +using System.Collections.Concurrent; +using System.Net; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Keyfactor.PKI.Enums.EJBCA; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Client; + +/// +/// Coverage for GetCertificateInventoryAsync's per-record isolation, error-rate circuit breaker, +/// and skip-unchanged optimization added to close the "one bad record aborts the whole sync" and +/// "every sync re-emits every order" gaps. +/// +public class MarkMonitorClientSyncResilienceTests +{ + private const string GoodId = "77777777-7777-7777-7777-777777777777"; + + [Fact] + public async Task GetCertificateInventoryAsync_WhenOneRecordThrowsDuringProcessing_SkipsItButKeepsTheRest() + { + // Simulates the realistic "bad record" failure surface: a downstream ICertificateDataReader + // lookup failure (e.g. a transient database error) for one specific order, rather than a + // malformed API response - MarkMonitorOrder's DateValidUntil/status fields are already + // strongly-typed DateTime/string, so a genuinely malformed value would fail JSON + // deserialization of the whole page, not per-record processing. + var badId = "99999999-9999-9999-9999-999999999999"; + var otherGoodId = "88888888-8888-8888-8888-888888888888"; + var reader = new FakeCertificateDataReader(); + reader.ThrowForRequestIds.Add(badId); + var ordersJson = string.Join(",", new[] + { + SampleOrders.OrderWithCert(GoodId, "DIGI_ISSUED"), + SampleOrders.OrderWithCert(badId, "DIGI_ISSUED"), + SampleOrders.OrderWithCert(otherGoodId, "DIGI_ISSUED") + }); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrdersPage(ordersJson))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader); + + Assert.Equal(2, count); + var collected = buffer.ToList(); + Assert.Equal(2, collected.Count); + Assert.DoesNotContain(collected, c => c.CARequestID == badId); + Assert.Contains(collected, c => c.CARequestID == GoodId); + Assert.Contains(collected, c => c.CARequestID == otherGoodId); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenErrorRateExceeds25PercentAfter50Records_AbortsTheSync() + { + // 50 good records first (ratio stays 0% - the breaker isn't evaluated below the 50-record + // sample size floor), then enough bad ones that the cumulative error rate crosses 25% - the + // 67th record observed (17 bad / 67 = 25.37%) is where this trips. + var reader = new FakeCertificateDataReader(); + var records = new List(); + for (var i = 0; i < 50; i++) + records.Add(SampleOrders.OrderWithCert(Guid.NewGuid().ToString(), "DIGI_ISSUED")); + for (var i = 0; i < 20; i++) + { + var badId = Guid.NewGuid().ToString(); + reader.ThrowForRequestIds.Add(badId); + records.Add(SampleOrders.OrderWithCert(badId, "DIGI_ISSUED")); + } + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrdersPage(string.Join(",", records)))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var ex = await Assert.ThrowsAsync( + () => client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader)); + + Assert.Contains("Aborting synchronization", ex.Message); + Assert.True(buffer.IsAddingCompleted); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenBelow50Records_DoesNotTripTheCircuitBreakerEvenIfEveryOneFails() + { + var reader = new FakeCertificateDataReader(); + var records = new List(); + for (var i = 0; i < 20; i++) + { + var badId = Guid.NewGuid().ToString(); + reader.ThrowForRequestIds.Add(badId); + records.Add(SampleOrders.OrderWithCert(badId, "DIGI_ISSUED")); + } + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrdersPage(string.Join(",", records)))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader); + + Assert.Equal(0, count); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenARecordIsUnchanged_SkipsReEmittingIt() + { + var reader = new FakeCertificateDataReader(); + reader.RequestIdToStatus[GoodId] = (int)EndEntityStatus.GENERATED; // DIGI_ISSUED maps to GENERATED + // SampleOrders.OrderWithCert's default dateValidUntil - matching this proves "truly unchanged" + // (same status AND same expiration), not just a status coincidence. + reader.ExpirationDateByRequestId[GoodId] = DateTime.Parse("2027-01-01T00:00:00Z").ToUniversalTime(); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert(GoodId, "DIGI_ISSUED")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader); + + Assert.Equal(0, count); + Assert.Empty(buffer.ToList()); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenStatusMatchesButExpirationDiffers_StillEmitsIt() + { + // Regression test: an out-of-band MarkMonitor reissue of the same order ID round-trips + // DIGI_ISSUED -> DIGI_REISSUE_PENDING -> DIGI_ISSUED - if a sync only observes the order + // before and after that round-trip, status alone looks unchanged even though the certificate + // (and its expiration) is new. Comparing expiration too catches this. + var reader = new FakeCertificateDataReader(); + reader.RequestIdToStatus[GoodId] = (int)EndEntityStatus.GENERATED; + reader.ExpirationDateByRequestId[GoodId] = DateTime.Parse("2026-06-01T00:00:00Z").ToUniversalTime(); + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + // Default dateValidUntil (2027-01-01) differs from the reader's stored 2026-06-01 - + // simulating a reissued certificate with a new validity window at the same status. + SampleOrders.OrdersPage(SampleOrders.OrderWithCert(GoodId, "DIGI_ISSUED")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader); + + Assert.Equal(1, count); + Assert.Contains(buffer.ToList(), c => c.CARequestID == GoodId); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenNoExpirationDataForTheRequestId_StillEmitsIt() + { + // Command not (yet) tracking an expiration for this request ID must not be treated as a + // false match - erring toward re-emitting rather than skipping when uncertain. + var reader = new FakeCertificateDataReader(); + reader.RequestIdToStatus[GoodId] = (int)EndEntityStatus.GENERATED; + // No ExpirationDateByRequestId entry - GetExpirationDateByRequestId returns null. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert(GoodId, "DIGI_ISSUED")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader); + + Assert.Equal(1, count); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenARecordsStatusChanged_StillEmitsIt() + { + var reader = new FakeCertificateDataReader(); + reader.RequestIdToStatus[GoodId] = (int)EndEntityStatus.INPROCESS; // was pending, now issued + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert(GoodId, "DIGI_ISSUED")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader); + + Assert.Equal(1, count); + Assert.Contains(buffer.ToList(), c => c.CARequestID == GoodId); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WhenNoCertificateDataReaderIsSupplied_AlwaysEmits() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert(GoodId, "DIGI_ISSUED")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None); + + Assert.Equal(1, count); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WithForceCompleteSyncTrue_ReEmitsEvenAnUnchangedRecord() + { + var reader = new FakeCertificateDataReader(); + reader.RequestIdToStatus[GoodId] = (int)EndEntityStatus.GENERATED; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrdersPage(SampleOrders.OrderWithCert(GoodId, "DIGI_ISSUED")))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader, + forceCompleteSync: true); + + Assert.Equal(1, count); + } + + [Fact] + public async Task GetCertificateInventoryAsync_WithAPageLargerThanTheConcurrencyLimit_CountsEveryOutcomeExactlyOnce() + { + // Regression test for concurrent per-record processing (records within a page are now + // processed with bounded concurrency instead of one at a time): a page bigger than the + // concurrency limit (10) exercises multiple concurrent batches, so this asserts the + // Interlocked counters aren't racing/double-counting/dropping increments under that load. + var reader = new FakeCertificateDataReader(); + var records = new List(); + var emittedIds = new List(); + var skippedIds = new List(); + var erroredIds = new List(); + + for (var i = 0; i < 15; i++) + { + var id = Guid.NewGuid().ToString(); + emittedIds.Add(id); + records.Add(SampleOrders.OrderWithCert(id, "DIGI_ISSUED")); + } + for (var i = 0; i < 15; i++) + { + var id = Guid.NewGuid().ToString(); + skippedIds.Add(id); + reader.RequestIdToStatus[id] = (int)EndEntityStatus.GENERATED; + reader.ExpirationDateByRequestId[id] = DateTime.Parse("2027-01-01T00:00:00Z").ToUniversalTime(); + records.Add(SampleOrders.OrderWithCert(id, "DIGI_ISSUED")); + } + for (var i = 0; i < 10; i++) + { + var id = Guid.NewGuid().ToString(); + erroredIds.Add(id); + reader.ThrowForRequestIds.Add(id); + records.Add(SampleOrders.OrderWithCert(id, "DIGI_ISSUED")); + } + + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrdersPage(string.Join(",", records)))); + var client = handler.BuildClient(); + await client.AuthenticateAsync(); + var buffer = new BlockingCollection(); + + var count = await client.GetCertificateInventoryAsync("", "", 100, buffer, CancellationToken.None, reader); + + Assert.Equal(15, count); + var collectedIds = buffer.ToList().Select(c => c.CARequestID).ToHashSet(); + Assert.Equal(new HashSet(emittedIds), collectedIds); + Assert.DoesNotContain(collectedIds, id => skippedIds.Contains(id) || erroredIds.Contains(id)); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs new file mode 100644 index 0000000..987bcfd --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs @@ -0,0 +1,34 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +public class MarkMonitorCAPluginClientCachingTests +{ + [Fact] + public async Task CreateAndAuthenticateClientAsync_CalledTwice_ReturnsTheSameClientInstance() + { + // Before the fix, every IAnyCAPlugin call (Enroll/Revoke/Ping/GetSingleRecord) built a brand + // new MarkMonitorClient - and therefore a brand new HttpClient/HttpClientHandler and a fresh + // authentication round-trip - from scratch. This asserts the plugin now hands back the same + // client across multiple calls instead. + var plugin = new MarkMonitorCAPlugin(); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + var first = await plugin.CreateAndAuthenticateClientAsync(); + var second = await plugin.CreateAndAuthenticateClientAsync(); + + Assert.Same(first, second); + } + + [Fact] + public async Task CreateAndAuthenticateClientAsync_CalledConcurrently_OnlyBuildsOneClient() + { + var plugin = new MarkMonitorCAPlugin(); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + var results = await Task.WhenAll(Enumerable.Range(0, 10) + .Select(_ => plugin.CreateAndAuthenticateClientAsync())); + + Assert.All(results, r => Assert.Same(results[0], r)); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs new file mode 100644 index 0000000..d10a1e0 --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs @@ -0,0 +1,77 @@ +using System.Net; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorCAPluginEnrollTests +{ + [Fact] + public async Task Enroll_WhenMarkMonitorRejectsTheOrder_PropagatesTheRealErrorDetail() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.BadRequest, + """{"validations":[{"field":"cert.csr","code":"field.invalidFormat","message":"The CSR format is invalid."}]}""")); + var injectedClient = handler.BuildClient(); + var plugin = new MarkMonitorCAPlugin(injectedClient); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary() + }; + + var ex = await Assert.ThrowsAsync(() => + plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.New)); + + // Before the fix, Command would only ever see the generic + // "Enrollment failed for subject: ..." message - the real MarkMonitor + // validation detail never made it past EnrollCertificateAsync's catch block. + Assert.Contains("The CSR format is invalid", ex.Message); + } + + [Fact] + public async Task Enroll_WithASubjectContainingEmbeddedCrLf_SanitizesItInLogOutputButStillEnrollsSuccessfully() + { + // Regression test (CWE-117): Subject is fully requester-controlled (straight off the + // submitted CSR). Before the fix, an embedded CR/LF was logged raw, letting a requester forge + // a fake log line that could be mistaken for a genuine, unrelated entry by anyone relying on + // this plugin's logs to reconstruct certificate-issuance history. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + const string maliciousSubject = + "CN=evil.example\r\n2026-08-10 09:00:00 [INF] Enrollment completed successfully for subject: CN=innocent.example"; + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert("11111111-1111-1111-1111-111111111111", "CREATED"))); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary() + }; + + var result = await plugin.Enroll(SampleCsr.Pem, maliciousSubject, new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.New); + + Assert.NotNull(result); + Assert.DoesNotContain(capturingFactory.Messages, m => m.Contains("\r\n", StringComparison.Ordinal)); + Assert.Contains(capturingFactory.Messages, m => m.Contains("\\r\\n", StringComparison.Ordinal)); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs new file mode 100644 index 0000000..c148183 --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs @@ -0,0 +1,27 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorCAPluginGetSingleRecordTests +{ + [Fact] + public async Task GetSingleRecord_WithCaRequestIdContainingCrLf_SanitizesItInLogOutput() + { + // Regression test (CWE-117): GetSingleRecord() used to log the caller-supplied caRequestId + // verbatim before the GUID validation performed deeper inside MarkMonitorClient ever ran, + // letting an embedded CR/LF forge a fake log line. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + const string maliciousCaRequestId = "not-a-guid\r\n2026-08-10 09:00:00 [INF] FAKE forged log line"; + var handler = new FakeHttpMessageHandler().WithSuccessfulAuth(); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + await Assert.ThrowsAsync(() => plugin.GetSingleRecord(maliciousCaRequestId)); + + Assert.DoesNotContain(capturingFactory.Messages, m => m.Contains("\r\n", StringComparison.Ordinal)); + Assert.Contains(capturingFactory.Messages, m => m.Contains("\\r\\n", StringComparison.Ordinal)); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs new file mode 100644 index 0000000..dced1b2 --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs @@ -0,0 +1,79 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorCAPluginPingTests +{ + [Fact] + public async Task Ping_WithInvalidCredentials_ThrowsWithoutEverLoggingAuthenticationSuccessful() + { + // Regression test: Ping() used to log "Authentication with MarkMonitor API successful" + // immediately after CreateAndAuthenticateClientAsync() - which deliberately does not + // authenticate eagerly, it only builds/caches the client wrapper - so that line was reached, + // and logged, before any credential had actually been checked. With invalid credentials, the + // log stream showed a false "successful" line followed immediately by a real auth failure for + // the same authentication attempt. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var handler = new FakeHttpMessageHandler() + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), + FakeHttpMessageHandler.Json(HttpStatusCode.Unauthorized, + """{"errors":[{"code":"auth.invalidCredentials","message":"Invalid credentials."}]}""")); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + await Assert.ThrowsAsync(() => plugin.Ping()); + + Assert.DoesNotContain(capturingFactory.Messages, + m => m.Contains("Authentication with MarkMonitor API successful", StringComparison.Ordinal)); + } + + [Fact] + public async Task Ping_WithValidCredentialsAndOrganizations_LogsAuthenticationSuccessful() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + await plugin.Ping(); + } + + [Fact] + public async Task Ping_RequestsALargeEnoughPageSizeToAvoidOneRoundTripPerOrganization() + { + // Regression test: an earlier version of this fix requested page size 1 as a supposedly cheap + // existence check, but ListOrganizationsAsync's pagination loop has no early exit - it always + // fetches every page up to TotalPages regardless of what the caller needs. With size=1, + // TotalPages equals the account's total organization count, so that "fix" actually turned Ping + // into one sequential HTTP request PER organization instead of the single request intended. + // Two explicit pages (rather than the default single-page fixture, which hardcodes + // totalPages=1 regardless of the requested size and would mask this exact regression) prove + // pagination still terminates correctly and uses the corrected, larger page size. + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization") && + !(req.RequestUri?.Query.Contains("page=") ?? false), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact("11111111-1111-1111-1111-111111111111")) + .Replace("\"totalPages\": 1", "\"totalPages\": 2"))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", "page=1"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact("22222222-2222-2222-2222-222222222222")) + .Replace("\"totalPages\": 1", "\"totalPages\": 2"))); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + await plugin.Ping(); + + var orgRequests = handler.Requests.Where(r => FakeHttpMessageHandler.Is(r, "GET", "/certs/v1/organization")).ToList(); + Assert.Equal(2, orgRequests.Count); + Assert.All(orgRequests, r => Assert.Contains("size=100", r.RequestUri!.Query)); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs new file mode 100644 index 0000000..28f9958 --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs @@ -0,0 +1,322 @@ +using System.Net; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Microsoft.Extensions.Logging; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorCAPluginRenewOrReissueTests +{ + private static FakeHttpMessageHandler BaseHandler(string newOrderId = "new-order-id") => + new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/certs/v1/order"), + FakeHttpMessageHandler.Json(HttpStatusCode.Accepted, + SampleOrders.OrderWithCert(newOrderId, "CREATED"))); + + private static (MarkMonitorCAPlugin plugin, FakeHttpMessageHandler handler, FakeCertificateDataReader reader) + BuildPlugin(FakeHttpMessageHandler handler) + { + var client = handler.BuildClient(); + var plugin = new MarkMonitorCAPlugin(client); + var reader = new FakeCertificateDataReader(); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), reader); + return (plugin, handler, reader); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithResolvablePriorCertSN_RevokesThePriorCertificate() + { + var handler = BaseHandler() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/order/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", "/certs/v1/order/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "ab:cd:ef" } + }; + + var result = await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.NotNull(result); + Assert.Contains(handler.Requests, + req => FakeHttpMessageHandler.Is(req, "PATCH", "/certs/v1/order/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithoutPriorCertSN_FallsBackToNewEnrollmentWithoutRevoking() + { + var handler = BaseHandler(); + var (plugin, _, _) = BuildPlugin(handler); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary() + }; + + var result = await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.NotNull(result); + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", "/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithUnresolvablePriorCertSN_StillReturnsTheNewCertWithoutRevoking() + { + var handler = BaseHandler(); + var (plugin, _, _) = BuildPlugin(handler); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "unknown-serial" } + }; + + var result = await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.NotNull(result); + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", "/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithPriorCertWithinTheDefaultRenewalWindow_RevokesIt() + { + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{priorId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(priorId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + reader.ExpirationDateByRequestId[priorId] = DateTime.UtcNow.AddDays(10); // well inside the default 90-day window + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "ab:cd:ef" } + }; + + await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.Contains(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithPriorCertOutsideTheDefaultRenewalWindow_LeavesItUnrevoked() + { + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler(); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + reader.ExpirationDateByRequestId[priorId] = DateTime.UtcNow.AddDays(200); // still has substantial life left + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "ab:cd:ef" } + }; + + var result = await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.NotNull(result); + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", "/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithAnAlreadyExpiredPriorCert_StillRevokesIt() + { + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{priorId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(priorId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + reader.ExpirationDateByRequestId[priorId] = DateTime.UtcNow.AddDays(-5); // already expired + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "ab:cd:ef" } + }; + + await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.Contains(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithACustomRenewalWindowDays_RespectsIt() + { + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler(); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + // 50 days out - within the default 90-day window, but outside a configured 30-day window. + reader.ExpirationDateByRequestId[priorId] = DateTime.UtcNow.AddDays(50); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary + { ["PriorCertSN"] = "ab:cd:ef", ["RenewalWindowDays"] = "30" } + }; + + var result = await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", + new Dictionary(), productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.NotNull(result); + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", "/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithAnInvalidRenewalWindowDaysValue_FallsBackToTheDefault() + { + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{priorId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(priorId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + // 50 days out - within the default 90-day window a non-numeric value must fall back to. + reader.ExpirationDateByRequestId[priorId] = DateTime.UtcNow.AddDays(50); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary + { ["PriorCertSN"] = "ab:cd:ef", ["RenewalWindowDays"] = "not-a-number" } + }; + + await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.Contains(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke")); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithAnInvalidRenewalWindowDaysValue_LogsAWarningNamingTheRejectedValue() + { + // Regression test: a mistyped/invalid RenewalWindowDays used to be silently coerced to the + // default with zero audit trail - indistinguishable in the logs from "not configured at + // all," despite affecting a security-relevant revoke decision. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{priorId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(priorId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + reader.ExpirationDateByRequestId[priorId] = DateTime.UtcNow.AddDays(50); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary + { ["PriorCertSN"] = "ab:cd:ef", ["RenewalWindowDays"] = "not-a-number" } + }; + + await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + var warning = Assert.Single(capturingFactory.Entries, + e => e.Level == LogLevel.Warning && e.Message.Contains("Invalid RenewalWindowDays", StringComparison.Ordinal)); + Assert.Contains("not-a-number", warning.Message); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithNoRenewalWindowDaysParameter_LogsNoWarning() + { + // Absent (never configured) must not be logged the same as present-but-rejected. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{priorId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(priorId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + reader.ExpirationDateByRequestId[priorId] = DateTime.UtcNow.AddDays(50); + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "ab:cd:ef" } + }; + + await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.DoesNotContain(capturingFactory.Entries, + e => e.Level == LogLevel.Warning && e.Message.Contains("Invalid RenewalWindowDays", StringComparison.Ordinal)); + } + + [Fact] + public async Task Enroll_RenewOrReissueWithNoExpirationDataForThePriorCert_FallsBackToRevokingItAsBefore() + { + var priorId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + var handler = BaseHandler() + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{priorId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrders.OrderWithCert(priorId, "DIGI_ISSUED"))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = priorId; + // No ExpirationDateByRequestId entry - GetExpirationDateByRequestId returns null. + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "ab:cd:ef" } + }; + + await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.RenewOrReissue); + + Assert.Contains(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{priorId}/revoke")); + } + + [Fact] + public async Task Enroll_PlainNewEnrollment_NeverAttemptsToRevokeAnything() + { + var handler = BaseHandler(); + var (plugin, _, reader) = BuildPlugin(handler); + reader.SerialNumberToRequestId["ab:cd:ef"] = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; + + var productInfo = new EnrollmentProductInfo + { + ProductID = "SslDvGeotrust", + ProductParameters = new Dictionary { ["PriorCertSN"] = "ab:cd:ef" } + }; + + await plugin.Enroll(SampleCsr.Pem, "CN=test.mmcertdomain.com", new Dictionary(), + productInfo, RequestFormat.PKCS10, EnrollmentType.New); + + Assert.DoesNotContain(handler.Requests, req => FakeHttpMessageHandler.Is(req, "PATCH", "/revoke")); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs new file mode 100644 index 0000000..005a600 --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs @@ -0,0 +1,94 @@ +using System.Net; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Keyfactor.PKI.Enums.EJBCA; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorCAPluginRevokeTests +{ + private const string OrderId = "11111111-1111-1111-1111-111111111111"; + + private static FakeHttpMessageHandler BaseHandler() => + new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))) + .When(req => FakeHttpMessageHandler.Is(req, "GET", $"/certs/v1/order/{OrderId}"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrders.OrderWithCert(OrderId, "DIGI_ISSUED", organizationId: SampleOrgs.DefaultOrgId))) + .When(req => FakeHttpMessageHandler.Is(req, "PATCH", $"/certs/v1/order/{OrderId}/revoke"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, "{}")); + + [Fact] + public async Task Revoke_WithOrgNameConfigured_RevokesSuccessfully() + { + var handler = BaseHandler(); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + var status = await plugin.Revoke(OrderId, "aabbcc", 0); + + Assert.Equal((int)EndEntityStatus.REVOKED, status); + } + + [Fact] + public async Task Revoke_WithBlankOrgNameConfigured_ThrowsWithoutMakingARequest() + { + // A blank/missing OrgId must never silently skip the cross-org ownership check on a live + // connector instance - Initialize() doesn't re-validate the deserialized config, so this is + // the only guard against a misconfigured OrgId reverting Revoke to "trust the caller". + var handler = BaseHandler(); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + var configProvider = FakeAnyCAPluginConfigProvider.WithDefaults(); + configProvider.CAConnectionData[MarkMonitorCAPluginConfig.ConfigConstants.OrgName] = ""; + plugin.Initialize(configProvider, new FakeCertificateDataReader()); + + await Assert.ThrowsAsync(() => plugin.Revoke(OrderId, "aabbcc", 0)); + + Assert.DoesNotContain(handler.Requests, r => FakeHttpMessageHandler.Is(r, "PATCH", "/revoke")); + } + + [Fact] + public async Task Revoke_WithBlankOrgNameConfigured_LogsTheFailureBeforeThrowing() + { + // Regression test: Revoke()'s catch block used to rethrow a wrapped exception with no + // _logger call at all - every other terminating path in this class (Enroll, GetSingleRecord, + // Synchronize, Ping) logs on exception, but a rejected Revoke left zero trace in the plugin's + // own logs that the attempt was ever made or why it was refused. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + var handler = BaseHandler(); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + var configProvider = FakeAnyCAPluginConfigProvider.WithDefaults(); + configProvider.CAConnectionData[MarkMonitorCAPluginConfig.ConfigConstants.OrgName] = ""; + plugin.Initialize(configProvider, new FakeCertificateDataReader()); + + await Assert.ThrowsAsync(() => plugin.Revoke(OrderId, "aabbcc", 0)); + + Assert.Contains(capturingFactory.Messages, + m => m.Contains("Revoke failed", StringComparison.OrdinalIgnoreCase) && + m.Contains(OrderId, StringComparison.Ordinal)); + } + + [Fact] + public async Task Revoke_WithOrderIdContainingCrLf_SanitizesItInLogOutput() + { + // Regression test (CWE-117): Revoke() used to log the caller-supplied orderId/ + // hexSerialNumber verbatim before the GUID/format validation performed deeper inside + // MarkMonitorClient ever ran, letting an embedded CR/LF forge a fake log line. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + + const string maliciousOrderId = "not-a-guid\r\n2026-08-10 09:00:00 [INF] FAKE forged log line"; + var handler = BaseHandler(); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + plugin.Initialize(FakeAnyCAPluginConfigProvider.WithDefaults(), new FakeCertificateDataReader()); + + await Assert.ThrowsAsync(() => plugin.Revoke(maliciousOrderId, "aabbcc", 0)); + + Assert.DoesNotContain(capturingFactory.Messages, m => m.Contains("\r\n", StringComparison.Ordinal)); + Assert.Contains(capturingFactory.Messages, m => m.Contains("\\r\\n", StringComparison.Ordinal)); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs new file mode 100644 index 0000000..cb4c668 --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs @@ -0,0 +1,183 @@ +using System.Net; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; +using Microsoft.Extensions.Logging; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +[Collection(LogHandlerFactoryCollection.Name)] +public class MarkMonitorCAPluginValidateConnectionInfoTests +{ + private static Dictionary ValidConnectionInfo(string baseUrl = "https://api.markmonitor.com") => + new() + { + [MarkMonitorCAPluginConfig.ConfigConstants.ApiKey] = "key", + [MarkMonitorCAPluginConfig.ConfigConstants.ApiUsername] = "user", + [MarkMonitorCAPluginConfig.ConfigConstants.ApiPassword] = "pass", + [MarkMonitorCAPluginConfig.ConfigConstants.BaseUrl] = baseUrl, + [MarkMonitorCAPluginConfig.ConfigConstants.OrgName] = "Test Org" + }; + + [Fact] + public async Task ValidateCAConnectionInfo_WithHttpBaseUrl_Throws() + { + // Fails the aggregated field checks before ever attempting a live call, so no client + // injection is needed here. + var plugin = new MarkMonitorCAPlugin(); + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateCAConnectionInfo(ValidConnectionInfo("http://mm-api.internal"))); + + Assert.Contains("https://", ex.Message); + } + + [Theory] + [InlineData("https://api.markmonitor.com")] + [InlineData("HTTPS://api.markmonitor.com")] + public async Task ValidateCAConnectionInfo_WithHttpsBaseUrlAndWorkingCredentials_DoesNotThrow(string baseUrl) + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, + SampleOrgs.OrgsListResponse(SampleOrgs.OrgWithContact()))); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + + await plugin.ValidateCAConnectionInfo(ValidConnectionInfo(baseUrl)); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WhenAuthenticationFails_ThrowsASanitizedErrorWithoutTheRawResponse() + { + var handler = new FakeHttpMessageHandler() + .When(req => FakeHttpMessageHandler.Is(req, "POST", "/auth/v1/auth/authenticate"), + FakeHttpMessageHandler.Json(HttpStatusCode.Unauthorized, + """{"errors":[{"code":"auth.invalidCredentials","message":"Invalid API key or credentials - secret-token-xyz"}]}""")); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateCAConnectionInfo(ValidConnectionInfo())); + + Assert.Contains("Authentication failed", ex.Message); + Assert.DoesNotContain("secret-token-xyz", ex.Message); + Assert.DoesNotContain("auth.invalidCredentials", ex.Message); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WhenListingOrganizationsFails_ThrowsASanitizedError() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.InternalServerError, + """{"errors":[{"code":"request.genericError","message":"An unexpected error occurred."}]}""")); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateCAConnectionInfo(ValidConnectionInfo())); + + Assert.Contains("listing organizations failed", ex.Message); + Assert.DoesNotContain("An unexpected error occurred", ex.Message); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WithTimeoutSecondsZero_ThrowsASanitizedErrorRatherThanCrashing() + { + // Regression test: TimeoutSeconds=0 used to reach HttpClient.Timeout's own setter unguarded, + // which .NET throws ArgumentOutOfRangeException for - propagating as a raw unhandled + // exception instead of this method's designed sanitized AnyCAValidationException. No client + // is injected here on purpose, since that's the only path that reaches the real + // (non-test-seam) transient-client construction where TimeoutSeconds actually gets used. An + // unroutable address (a closed local port) makes the live call fail fast and predictably; + // what matters is which exception type surfaces, not why the call failed. + var plugin = new MarkMonitorCAPlugin(); + var connectionInfo = ValidConnectionInfo("https://127.0.0.1:1"); + connectionInfo[MarkMonitorCAPluginConfig.ConfigConstants.TimeoutSeconds] = 0; + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateCAConnectionInfo(connectionInfo)); + + Assert.Contains("Authentication failed", ex.Message); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WhenNoOrganizationsAreVisible_ThrowsASanitizedError() + { + var handler = new FakeHttpMessageHandler() + .WithSuccessfulAuth() + .When(req => FakeHttpMessageHandler.Is(req, "GET", "/certs/v1/organization"), + FakeHttpMessageHandler.Json(HttpStatusCode.OK, SampleOrgs.OrgsListResponse())); + var plugin = new MarkMonitorCAPlugin(handler.BuildClient()); + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateCAConnectionInfo(ValidConnectionInfo())); + + Assert.Contains("listing organizations failed", ex.Message); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WithAMalformedNumericField_ThrowsASanitizedErrorRatherThanCrashing() + { + // Regression test: the connectionInfo-to-MarkMonitorConfig deserialization used to sit + // outside both inner try/catch blocks, so a non-numeric value for one of the Number-typed + // fields threw a raw, unlogged JsonSerializationException instead of this method's designed + // sanitized AnyCAValidationException. No client is injected here on purpose, since that's + // the only path that reaches the real (non-test-seam) deserialization. + var plugin = new MarkMonitorCAPlugin(); + var connectionInfo = ValidConnectionInfo(); + connectionInfo[MarkMonitorCAPluginConfig.ConfigConstants.PageSize] = "not-a-number"; + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateCAConnectionInfo(connectionInfo)); + + Assert.Contains("could not be parsed", ex.Message); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WithAMalformedNumericFieldContainingCrlf_DoesNotForgeALogLine() + { + // Regression test: the deserialization-failure catch block logged the raw + // JsonSerializationException message unsanitized - that message echoes back the rejected + // value verbatim, so an embedded CR/LF in a submitted field could forge a fake log line + // (CWE-117), the exact class of input every other caller-supplied value in this codebase is + // sanitized against before logging. + using var _ = CapturingLoggerFactory.Install(out var capturingFactory); + var plugin = new MarkMonitorCAPlugin(); + var connectionInfo = ValidConnectionInfo(); + connectionInfo[MarkMonitorCAPluginConfig.ConfigConstants.PageSize] = "bad\r\nFAKE LOG LINE: admin logged in"; + + await Assert.ThrowsAsync(() => plugin.ValidateCAConnectionInfo(connectionInfo)); + + Assert.DoesNotContain(capturingFactory.Entries, + e => e.Message.Contains('\n') || e.Message.Contains('\r')); + Assert.Contains(capturingFactory.Entries, + e => e.Level == LogLevel.Error && e.Message.Contains("FAKE LOG LINE", StringComparison.Ordinal)); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WithEnabledFalse_SkipsTheLiveConnectivityCheck() + { + // Regression test: Enabled's own documented purpose is letting an admin save the CA + // connector before real MarkMonitor credentials are available. The new live-connectivity + // check used to run unconditionally, breaking that pre-existing, documented workflow for a + // connector saved with placeholder credentials while disabled. No client is injected and an + // unroutable address is used on purpose - the assertion is that no live call is even + // attempted, not that one succeeds. + var plugin = new MarkMonitorCAPlugin(); + var connectionInfo = ValidConnectionInfo("https://127.0.0.1:1"); + connectionInfo[MarkMonitorCAPluginConfig.ConfigConstants.Enabled] = false; + + await plugin.ValidateCAConnectionInfo(connectionInfo); + } + + [Fact] + public async Task ValidateCAConnectionInfo_WithEnabledTrueOrAbsent_StillPerformsTheLiveConnectivityCheck() + { + var plugin = new MarkMonitorCAPlugin(); + var connectionInfo = ValidConnectionInfo("https://127.0.0.1:1"); + connectionInfo[MarkMonitorCAPluginConfig.ConfigConstants.Enabled] = true; + + await Assert.ThrowsAsync(() => + plugin.ValidateCAConnectionInfo(connectionInfo)); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs new file mode 100644 index 0000000..0b202ce --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs @@ -0,0 +1,57 @@ +using Keyfactor.AnyGateway.Extensions; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +public class MarkMonitorCAPluginValidateProductInfoTests +{ + [Theory] + [InlineData("SslDvGeotrust")] + [InlineData("SslOvBasic")] + [InlineData("SslEvSecuresitePro")] + public async Task ValidateProductInfo_WithAValidProductId_DoesNotThrow(string productId) + { + var plugin = new MarkMonitorCAPlugin(); + var productInfo = new EnrollmentProductInfo { ProductID = productId }; + + await plugin.ValidateProductInfo(productInfo, new Dictionary()); + } + + [Fact] + public async Task ValidateProductInfo_WithAnInvalidProductId_ThrowsAndListsTheValidValues() + { + var plugin = new MarkMonitorCAPlugin(); + var productInfo = new EnrollmentProductInfo { ProductID = "NotARealProduct" }; + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateProductInfo(productInfo, new Dictionary())); + + Assert.Contains("NotARealProduct", ex.Message); + Assert.Contains("SslDvGeotrust", ex.Message); + } + + [Fact] + public async Task ValidateProductInfo_WithAnEmptyProductId_Throws() + { + var plugin = new MarkMonitorCAPlugin(); + var productInfo = new EnrollmentProductInfo { ProductID = "" }; + + await Assert.ThrowsAsync(() => + plugin.ValidateProductInfo(productInfo, new Dictionary())); + } + + [Fact] + public async Task ValidateProductInfo_WithANumericStringForAnUndefinedEnumValue_Throws() + { + // Regression test: Enum.TryParse alone "succeeds" for any numeric string + // that fits the underlying int type, even with no member defined for that value (CertOrderTypes + // has 12 members, values 0-11) - Enum.IsDefined is the check that actually enforces membership. + var plugin = new MarkMonitorCAPlugin(); + var productInfo = new EnrollmentProductInfo { ProductID = "20" }; + + var ex = await Assert.ThrowsAsync(() => + plugin.ValidateProductInfo(productInfo, new Dictionary())); + + Assert.Contains("20", ex.Message); + Assert.Contains("SslDvGeotrust", ex.Message); + } +} diff --git a/markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs b/markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs new file mode 100644 index 0000000..df2f8a8 --- /dev/null +++ b/markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs @@ -0,0 +1,86 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; + +public class MarkMonitorConfigTests +{ + [Fact] + public void PageSize_DefaultsTo100() + { + Assert.Equal(100, new MarkMonitorConfig().PageSize); + } + + [Theory] + [InlineData(0, 1)] + [InlineData(-5, 1)] + [InlineData(1, 1)] + [InlineData(250, 250)] + [InlineData(500, 500)] + [InlineData(501, 500)] + [InlineData(10000, 500)] + public void PageSize_ClampsOutOfRangeValues(int assigned, int expected) + { + var config = new MarkMonitorConfig { PageSize = assigned }; + + Assert.Equal(expected, config.PageSize); + } + + [Fact] + public void TimeoutSeconds_DefaultsTo120() + { + Assert.Equal(120, new MarkMonitorConfig().TimeoutSeconds); + } + + [Theory] + [InlineData(0, 1)] // 0 would otherwise crash HttpClient.Timeout's own setter + [InlineData(-5, 1)] + [InlineData(1, 1)] + [InlineData(60, 60)] + [InlineData(120, 120)] + [InlineData(121, 120)] // never allowed above this field's own pre-existing hardcoded default + [InlineData(10000, 120)] + public void TimeoutSeconds_ClampsOutOfRangeValues(int assigned, int expected) + { + var config = new MarkMonitorConfig { TimeoutSeconds = assigned }; + + Assert.Equal(expected, config.TimeoutSeconds); + } + + [Fact] + public void PickupRetries_DefaultsTo5() + { + Assert.Equal(5, new MarkMonitorConfig().PickupRetries); + } + + [Theory] + [InlineData(0, 0)] // 0 is a valid, deliberate "disable polling" value + [InlineData(-5, 0)] + [InlineData(5, 5)] + [InlineData(20, 20)] + [InlineData(21, 20)] + [InlineData(10000, 20)] + public void PickupRetries_ClampsOutOfRangeValues(int assigned, int expected) + { + var config = new MarkMonitorConfig { PickupRetries = assigned }; + + Assert.Equal(expected, config.PickupRetries); + } + + [Fact] + public void PickupDelaySeconds_DefaultsTo10() + { + Assert.Equal(10, new MarkMonitorConfig().PickupDelaySeconds); + } + + [Theory] + [InlineData(0, 0)] + [InlineData(-5, 0)] + [InlineData(10, 10)] + [InlineData(60, 60)] + [InlineData(61, 60)] + [InlineData(10000, 60)] + public void PickupDelaySeconds_ClampsOutOfRangeValues(int assigned, int expected) + { + var config = new MarkMonitorConfig { PickupDelaySeconds = assigned }; + + Assert.Equal(expected, config.PickupDelaySeconds); + } +} diff --git a/markmonitor-caplugin.Tests/Models/TokenResponseTests.cs b/markmonitor-caplugin.Tests/Models/TokenResponseTests.cs new file mode 100644 index 0000000..62667af --- /dev/null +++ b/markmonitor-caplugin.Tests/Models/TokenResponseTests.cs @@ -0,0 +1,23 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; +using Newtonsoft.Json; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.Models; + +public class TokenResponseTests +{ + [Fact] + public void Deserialize_RealApiShape_PopulatesExpiresIn() + { + // The real MarkMonitor /auth/v1/auth/authenticate response (confirmed against the live + // sandbox) uses "expiresIn" (camelCase), not "expires_in". A mismatch here means ExpiresIn + // silently deserializes to 0, which makes every token look instantly expired to any code + // (like MarkMonitorClient's expiry tracking) that relies on it. + const string json = """{"token":"abc123","expiresIn":3600}"""; + + var result = JsonConvert.DeserializeObject(json); + + Assert.NotNull(result); + Assert.Equal("abc123", result.BearerToken); + Assert.Equal(3600, result.ExpiresIn); + } +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs b/markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs new file mode 100644 index 0000000..77856ee --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs @@ -0,0 +1,62 @@ +using System.Collections.Concurrent; +using Keyfactor.Logging; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// A minimal ILoggerFactory that records every formatted log message it's given, so tests +/// can assert on log output emitted via Keyfactor.Logging's LogHandler (which only exposes a +/// settable Factory, not the concrete Microsoft.Extensions.Logging.LoggerFactory type). +public sealed class CapturingLoggerFactory : ILoggerFactory +{ + /// Points LogHandler.Factory at a fresh CapturingLoggerFactory and returns an + /// IDisposable that restores it to a NullLoggerFactory - use with a `using` statement so a test + /// doesn't need its own try/finally around the swap. + public static IDisposable Install(out CapturingLoggerFactory factory) + { + factory = new CapturingLoggerFactory(); + LogHandler.Factory = factory; + return new Restorer(); + } + + private sealed class Restorer : IDisposable + { + public void Dispose() => LogHandler.Factory = new NullLoggerFactory(); + } + + public ConcurrentQueue<(LogLevel Level, string Message)> Entries { get; } = new(); + + /// Formatted message text only, for the (more common) callers that don't need to filter + /// by level. + public IEnumerable Messages => Entries.Select(e => e.Message); + + public ILogger CreateLogger(string categoryName) => new CapturingLogger(Entries); + + public void AddProvider(ILoggerProvider provider) + { + } + + public void Dispose() + { + } + + private sealed class CapturingLogger(ConcurrentQueue<(LogLevel Level, string Message)> entries) : ILogger + { + public IDisposable? BeginScope(TState state) where TState : notnull => NoopScope.Instance; + + public bool IsEnabled(LogLevel logLevel) => true; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, + Func formatter) => + entries.Enqueue((logLevel, formatter(state, exception))); + + private sealed class NoopScope : IDisposable + { + public static readonly NoopScope Instance = new(); + public void Dispose() + { + } + } + } +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs b/markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs new file mode 100644 index 0000000..a501904 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs @@ -0,0 +1,26 @@ +using Keyfactor.AnyGateway.Extensions; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +public class FakeAnyCAPluginConfigProvider : IAnyCAPluginConfigProvider +{ + public Dictionary CAConnectionData { get; set; } = new(); + + public static FakeAnyCAPluginConfigProvider WithDefaults(string baseUrl = "https://api.markmonitor.test") => + new() + { + CAConnectionData = new Dictionary + { + [MarkMonitorCAPluginConfig.ConfigConstants.ApiKey] = "test-api-key", + [MarkMonitorCAPluginConfig.ConfigConstants.ApiUsername] = "test-user", + [MarkMonitorCAPluginConfig.ConfigConstants.ApiPassword] = "test-password", + [MarkMonitorCAPluginConfig.ConfigConstants.BaseUrl] = baseUrl, + [MarkMonitorCAPluginConfig.ConfigConstants.OrgName] = "Test Org", + [MarkMonitorCAPluginConfig.ConfigConstants.Enabled] = true, + // 0 disables Enroll's post-submit issuance polling by default here - tests that + // specifically exercise polling opt in explicitly rather than every other test needing + // to stub a GET /certs/v1/order/{id} route it doesn't otherwise care about. + [MarkMonitorCAPluginConfig.ConfigConstants.PickupRetries] = 0 + } + }; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs b/markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs new file mode 100644 index 0000000..414ffc4 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs @@ -0,0 +1,35 @@ +using Keyfactor.AnyGateway.Extensions; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +public class FakeCertificateDataReader : ICertificateDataReader +{ + public Dictionary SerialNumberToRequestId { get; } = new(); + public Dictionary RequestIdToStatus { get; } = new(); + + /// Request IDs for which a lookup call throws, simulating a downstream failure (e.g. a + /// transient database error) for one specific record during a sync. + public HashSet ThrowForRequestIds { get; } = new(); + + public Task GetStatusByRequestID(string caRequestID) + { + if (ThrowForRequestIds.Contains(caRequestID)) + throw new Exception($"Simulated lookup failure for {caRequestID}"); + return Task.FromResult(RequestIdToStatus.GetValueOrDefault(caRequestID, 0)); + } + + public Task DoesCertExistForRequestID(string caRequestID) + { + if (ThrowForRequestIds.Contains(caRequestID)) + throw new Exception($"Simulated lookup failure for {caRequestID}"); + return Task.FromResult(RequestIdToStatus.ContainsKey(caRequestID)); + } + + public Task GetRequestIDBySerialNumber(string serialNumber) => + Task.FromResult(SerialNumberToRequestId.GetValueOrDefault(serialNumber, string.Empty)); + + public Dictionary ExpirationDateByRequestId { get; } = new(); + + public DateTime? GetExpirationDateByRequestId(string caRequestID) => + ExpirationDateByRequestId.TryGetValue(caRequestID, out var expiration) ? expiration : null; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs b/markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs new file mode 100644 index 0000000..c948b29 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs @@ -0,0 +1,111 @@ +using System.Net; +using System.Net.Http; +using System.Text; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// +/// A minimal routable fake HttpMessageHandler for exercising MarkMonitorClient against canned +/// responses instead of the live MarkMonitor API. Register routes with When(), most-specific first; +/// each route's responses are consumed in order and the last one registered repeats indefinitely. +/// +public sealed class FakeHttpMessageHandler : HttpMessageHandler +{ + private sealed class Route + { + public required Func Matches; + public required Queue>> Responses; + } + + private readonly object _lock = new(); + private readonly List _routes = new(); + public List Requests { get; } = new(); + + public FakeHttpMessageHandler When(Func matches, params HttpResponseMessage[] responses) + { + return WhenAsync(matches, + responses.Select(r => (Func>)(_ => Task.FromResult(r))) + .ToArray()); + } + + /// Like When(), but the response is produced asynchronously - e.g. via WhenGated() to + /// hold a response open until a test explicitly releases it, for exercising genuine + /// concurrency/in-flight-request behavior. + public FakeHttpMessageHandler WhenAsync(Func matches, + params Func>[] responseFactories) + { + var route = new Route + { + Matches = matches, + Responses = new Queue>>(responseFactories) + }; + lock (_lock) + { + _routes.Add(route); + } + return this; + } + + /// Registers a response that isn't returned until `gate` completes, so a test can hold + /// a request "in flight" for as long as it needs before releasing the response. + public FakeHttpMessageHandler WhenGated(Func matches, Task gate, + HttpResponseMessage response) => + WhenAsync(matches, async _ => + { + await gate; + return response; + }); + + protected override async Task SendAsync(HttpRequestMessage request, + CancellationToken cancellationToken) + { + Func> factory; + lock (_lock) + { + Requests.Add(request); + var route = _routes.LastOrDefault(r => r.Matches(request) && r.Responses.Count > 0) + ?? _routes.LastOrDefault(r => r.Matches(request)); + + if (route == null) + throw new InvalidOperationException($"No fake response registered for {request.Method} {request.RequestUri}"); + + factory = route.Responses.Count > 1 ? route.Responses.Dequeue() : route.Responses.Peek(); + } + + // A real HttpMessageHandler observes the cancellation token itself - honor it here too, so a + // test can exercise a caller's cancellation-propagation behavior against a route (e.g. one + // registered via WhenGated) that would otherwise hang forever. + var responseTask = factory(request); + var cancellationTask = Task.Delay(Timeout.Infinite, cancellationToken); + var completed = await Task.WhenAny(responseTask, cancellationTask); + if (completed == cancellationTask) + throw new TaskCanceledException("The fake request was cancelled.", null, cancellationToken); + return await responseTask; + } + + public static bool Is(HttpRequestMessage req, string method, string pathFragment) => + req.Method.Method.Equals(method, StringComparison.OrdinalIgnoreCase) && + (req.RequestUri?.ToString().Contains(pathFragment, StringComparison.OrdinalIgnoreCase) ?? false); + + public static HttpResponseMessage Json(HttpStatusCode status, string json) => + new(status) { Content = new StringContent(json, Encoding.UTF8, "application/json") }; + + /// Wires up a successful /auth/v1/auth/authenticate response so callers can focus tests + /// on the endpoint(s) they actually care about. + public FakeHttpMessageHandler WithSuccessfulAuth(string token = "fake-token", int expiresIn = 3600) + { + return When(req => Is(req, "POST", "/auth/v1/auth/authenticate"), + Json(HttpStatusCode.OK, $"{{\"token\":\"{token}\",\"expiresIn\":{expiresIn}}}")); + } + + /// Builds a MarkMonitorClient wired to this fake handler, using the same + /// base URL/credentials every test uses since they're never actually sent anywhere real. Retry + /// backoff delays are instant by default (no test wants a multi-second real sleep just because a + /// route happens to return a 5xx/429/network failure) - pass `delay` to observe or slow down the + /// schedule a test actually cares about verifying. + public MarkMonitorClient BuildClient(TimeProvider? timeProvider = null, + Func? delay = null) => + new("https://api.markmonitor.test", "key", "user", "pass", true, this, timeProvider, + delay: delay ?? ((_, _) => Task.CompletedTask)); +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs b/markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs new file mode 100644 index 0000000..8a05c8d --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs @@ -0,0 +1,14 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// +/// Keyfactor.Logging's LogHandler.Factory is a single process-wide static. xUnit runs different test +/// classes concurrently by default, so any two test classes that both reassign it (to observe log +/// output via a fake ILoggerFactory) can race and clobber each other's factory mid-test. Every test +/// class that touches LogHandler.Factory declares [Collection(Name)] so they're all serialized against +/// one another instead of running in parallel. +/// +[CollectionDefinition(Name, DisableParallelization = true)] +public class LogHandlerFactoryCollection +{ + public const string Name = "LogHandler.Factory"; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs b/markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs new file mode 100644 index 0000000..edea9a2 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs @@ -0,0 +1,9 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// A TimeProvider with a settable clock, for deterministically testing expiry logic. +public class ManualTimeProvider : TimeProvider +{ + public DateTimeOffset UtcNow { get; set; } = DateTimeOffset.UtcNow; + + public override DateTimeOffset GetUtcNow() => UtcNow; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs new file mode 100644 index 0000000..b11f4db --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs @@ -0,0 +1,21 @@ +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// Builds a MarkMonitorConfig matching the fake handler's base URL/credentials. +public static class SampleConfig +{ + public static MarkMonitorConfig Default(string orgName = "Test Org") => new() + { + BaseUrl = "https://api.markmonitor.test", + ApiKey = "key", + ApiUsername = "user", + ApiPassword = "pass", + OrgName = orgName, + Enabled = true, + // 0 disables Enroll's post-submit issuance polling by default here - tests that specifically + // exercise polling opt in explicitly rather than every other enroll test needing to stub a + // GET /certs/v1/order/{id} route it doesn't otherwise care about. + PickupRetries = 0 + }; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs new file mode 100644 index 0000000..ab7a996 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs @@ -0,0 +1,23 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// A fixed, valid RSA CSR (CN=test.mmcertdomain.com) for enrollment tests. +public static class SampleCsr +{ + public const string Pem = """ + -----BEGIN CERTIFICATE REQUEST----- + MIICZTCCAU0CAQAwIDEeMBwGA1UEAwwVdGVzdC5tbWNlcnRkb21haW4uY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAne7uDpjrruy7z2sv+RKbSW4U + erEOKO8DLd2H4/6x0NzWW0sMEZ9Z/vHx1JYgYHjoS1UIHPg30tBtL6/CZPuC3j00 + bcWbyBhEosrcfOb7xX5lKScNO3qvlZE9EGcY/kCl2m/2kvn0Jric8WIar8zbxe8f + A7VUA4DcGZUZTNfrmEGw3xVKvEOZQBH7OIUsSKSsdifzcldiwvRb2xiCcMd8hLp3 + XGMEU+9o6pZM8PYU3SWT1KPAsp29Uef1l4u4e4SreerIoNV1NgmCShpj8zf0lHp+ + JlocXOzxicf+2njnzBYYEXWkDoPBGLzKT6ShJR2MejpKMO8qviLfGP2jIN427QID + AQABoAAwDQYJKoZIhvcNAQELBQADggEBAGHPpJi5OqAnDmIJ3+i2HMeObiCddax0 + hBWeoEje2B2o2M+twsXDtmSUxp5CmZTT4SrJeft9jsH10ZG5cd7ypMR3SKYMBmAP + n3a8xGOQKODOaO1KUbZyJ4fxePXHHw6QrTx9AKrWEV9Y19K8kIgdnafqRiyqJ10r + uyKih/NvUzC0ETWXCCcGYP5BI2S+kEnT5r9osqYlTMTJwGiTuoutUkW1VB/o7SU1 + 8A0FAvkClJGY5DNOJ5AMTKdD6E5X+09b9YuDUAhqg+ivYPCBsluYDS3Ayc0qZpCD + OjqDSP9B1HX7+OIZRgHNQ7aiHocPlzqBzcW9M+byDjbL6sZHJtKf6mQ= + -----END CERTIFICATE REQUEST----- + """; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs new file mode 100644 index 0000000..616c888 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs @@ -0,0 +1,24 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// A second, distinct valid RSA CSR (CN=other.mmcertdomain.com) for tests that need two +/// different CSRs, e.g. to confirm enrollment idempotency is scoped correctly. +public static class SampleCsr2 +{ + public const string Pem = """ + -----BEGIN CERTIFICATE REQUEST----- + MIICZjCCAU4CAQAwITEfMB0GA1UEAwwWb3RoZXIubW1jZXJ0ZG9tYWluLmNvbTCC + ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbI0/Flsz3CyIIVQlVd95HM + MG1iVSLTsC+TDmIP08UQB8EWQu7gmC4fbKu3ip5dtKEn7hVMVveQohNMxbFNPZKv + 6TtmjizB9JD4sx/JpFNr0UJg9I55b09dZ/XeeewemUO+fodLhBxsEz0aU9tjqxkh + RXs4Ts84jhtXZ597yzsxPxzqMif1+ARh2uq9dOok/FCRNXisz9yI+WWOW89BiS3e + QnOVnrsh6eX7xwDbP4rz8nTf7g1daY3INruluT0g2gdJGPTThIu3haocnUTtEjkn + 2Qn4f0Wxg/GXckR1igNYHKIew927p7SxIqxZnWMH4L/YkAuguG3RwvWA+VzOnWUC + AwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQBTd2VIhGxwRpfS7mXiU3pumvY6TLib + dw18ALi57VFxo95ZAyIdD+t68ISt6sFF5e7TTV6Fy9uqpnwFGCYS9yXdbS7/VDjj + Xvz2JmZO1q+mYT85/bahvRLvX0mlZhViucu4ryUy5BgUEVyrLk4QiLn9U1fgiA87 + l/2NVswRTovqsK6pFrcsVT1nqqkbywDKgBXQD5RB8WFPeKpM+qlz4R/yx6jvlJ3a + 5Sa8oP/kr//U+chmQiTopPFA20Hx/uKD+geO02qgb+ThdHMnJp+QeZ1lkdMrxkLP + CvrDLqOiLH1B2+4ImzBVbg2UzcnolwSeeQUR78bUNhxE/Pifn6lFgyrc + -----END CERTIFICATE REQUEST----- + """; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs new file mode 100644 index 0000000..0bfca13 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs @@ -0,0 +1,42 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// Generates a fresh RSA CSR with a CSR-embedded SAN (subjectAltName) extension request, +/// for tests exercising the union of dictionary-supplied and CSR-embedded SANs. Unlike +/// 's fixed PEM, this is generated on the fly since the fixed fixtures +/// predate SAN support and none of them carry an extension request. +public static class SampleCsrWithSans +{ + public static string GeneratePem(string commonName, params string[] dnsNames) + { + var keyPairGen = new RsaKeyPairGenerator(); + keyPairGen.Init(new KeyGenerationParameters(new SecureRandom(), 2048)); + var keyPair = keyPairGen.GenerateKeyPair(); + + var subject = new X509Name($"CN={commonName}"); + var generalNames = new GeneralNames(dnsNames.Select(d => new GeneralName(GeneralName.DnsName, d)).ToArray()); + var extensions = new X509Extensions(new Dictionary + { + [X509Extensions.SubjectAlternativeName] = new X509Extension(false, new DerOctetString(generalNames)) + }); + var attributes = new DerSet(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, + new DerSet(extensions))); + + var csr = new Pkcs10CertificationRequest("SHA256WITHRSA", subject, keyPair.Public, attributes, + keyPair.Private); + + using var stream = new MemoryStream(); + using var writer = new StreamWriter(stream); + new PemWriter(writer).WriteObject(csr); + writer.Flush(); + return System.Text.Encoding.ASCII.GetString(stream.ToArray()); + } +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs new file mode 100644 index 0000000..93ec2e3 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs @@ -0,0 +1,32 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// Valid ECC (P-256, CN=test.mmcertdomain.com) CSRs differing only in how the key's curve +/// is encoded - named-curve (OID reference) vs. explicit parameters (prime/coefficients/base point +/// spelled out). MarkMonitor accepts the former and silently fails an order using the latter. +public static class SampleEccCsrs +{ + public const string NamedCurvePem = """ + -----BEGIN CERTIFICATE REQUEST----- + MIHYMIGAAgEAMCAxHjAcBgNVBAMMFXRlc3QubW1jZXJ0ZG9tYWluLmNvbTBZMBMG + ByqGSM49AgEGCCqGSM49AwEHA0IABE1FpjBDQ/1D3WBypTFej+WT8TflM8TfiS5v + wHtWf/ss/6XmNYcUp7y6JO0Hkzzn5bSRNUI4qcn3PtkytIXYwugwCgYIKoZIzj0E + AwIDRwAwRAIgROdwnkYWB1+GHDeLPMnRoP5N2SE0m6BpJQO68851t9cCIHpDUMnt + fPNyziHHK8YmUhMlGfNCUa5IjPgRwA51ByDR + -----END CERTIFICATE REQUEST----- + """; + + public const string ExplicitCurvePem = """ + -----BEGIN CERTIFICATE REQUEST----- + MIIBtjCCAVwCAQAwIDEeMBwGA1UEAwwVdGVzdC5tbWNlcnRkb21haW4uY29tMIIB + MzCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAA + AAAAAAD///////////////8wRAQg/////wAAAAEAAAAAAAAAAAAAAAD///////// + //////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLBEEEaxfR8uEs + Qkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sx + Xs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEB + A0IABEq7nGUCuVXEVLX4xbC3T+mPmMFXSDjpIxscIH5rAMz6Ho6xeXdQroQcn1Am + j3f/2c1XssmutrtIMrgaBox6Tj4wCgYIKoZIzj0EAwIDSAAwRQIgLrjt/SWWn46z + d7J06TvNsE3HXKWK1OLorkJK70daDXICIQCRK/BK5UmBpOLFuenlcIQjSj3B3lbk + 33B/in3asgYtcw== + -----END CERTIFICATE REQUEST----- + """; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs new file mode 100644 index 0000000..2689223 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs @@ -0,0 +1,65 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// Builds minimal-but-valid MarkMonitor order JSON fragments for tests. +public static class SampleOrders +{ + public static string OrderWithCert(string id, string status, string? revokeStatus = null, + string dateValidUntil = "2027-01-01T00:00:00Z", string certType = "SSL_DV_GEOTRUST", + string? organizationId = SampleOrgs.DefaultOrgId) => + $$""" + { + "id": "{{id}}", + "certType": "{{certType}}", + "status": "{{status}}", + "organizationId": {{(organizationId == null ? "null" : $"\"{organizationId}\"")}}, + "cert": { + "commonName": "test.mmcertdomain.com", + "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMII...\n-----END CERTIFICATE REQUEST-----", + "endEntityCert": "-----BEGIN CERTIFICATE-----\nMII...\n-----END CERTIFICATE-----", + "revokeStatus": {{(revokeStatus == null ? "null" : $"\"{revokeStatus}\"")}}, + "dateValidUntil": "{{dateValidUntil}}", + "daysRemaining": 200 + } + } + """; + + public static string OrderWithNullCert(string id, string status) => + $$""" + { + "id": "{{id}}", + "certType": "SSL_DV_GEOTRUST", + "status": "{{status}}", + "cert": null + } + """; + + /// An order whose status has already flipped to issued but whose cert body hasn't been + /// populated yet - the race PollForIssuanceAsync's own completion check (and, if the poll budget + /// exhausts at exactly this moment, EnrollCertificateAsync's own result-consistency check) guards + /// against, as distinct from OrderWithNullCert's "cert is entirely absent" pending state. + public static string OrderIssuedWithoutCertBody(string id) => + $$""" + { + "id": "{{id}}", + "certType": "SSL_DV_GEOTRUST", + "status": "DIGI_ISSUED", + "organizationId": "{{SampleOrgs.DefaultOrgId}}", + "cert": { + "commonName": "test.mmcertdomain.com", + "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMII...\n-----END CERTIFICATE REQUEST-----", + "endEntityCert": null, + "revokeStatus": null, + "dateValidUntil": "2027-01-01T00:00:00Z", + "daysRemaining": 200 + } + } + """; + + public static string OrdersPage(string content, int totalPages = 1) => + $$""" + { + "content": [{{content}}], + "page": { "size": 100, "totalElements": 1, "totalPages": {{totalPages}}, "number": 0 } + } + """; +} diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs new file mode 100644 index 0000000..c930f60 --- /dev/null +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs @@ -0,0 +1,46 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; + +/// Builds minimal-but-valid MarkMonitor organization/contact JSON fragments for tests. +public static class SampleOrgs +{ + public const string DefaultOrgId = "11111111-1111-1111-1111-111111111111"; + public const string DefaultContactId = "22222222-2222-2222-2222-222222222222"; + + public static string OrgWithContact(string orgId = DefaultOrgId, string orgName = "Test Org", + string contactId = DefaultContactId, string contactType = "ORGANIZATION_CONTACT") => + $$""" + { + "id": "{{orgId}}", + "name": "{{orgName}}", + "provider": "DIGICERT", + "providerId": 1, + "contacts": [ + { + "id": "{{contactId}}", + "firstName": "Test", + "lastName": "Contact", + "email": "test.contact@example.com", + "contactTypes": [{ "type": "{{contactType}}" }] + } + ] + } + """; + + public static string OrgsListResponse(string orgJson) => + $$""" + { + "content": [{{orgJson}}], + "page": { "size": 1, "totalElements": 1, "totalPages": 1, "number": 0 } + } + """; + + /// Builds a multi-org list response, for exercising resolution against a search result + /// that contains more than one candidate (e.g. a substring-name false positive). + public static string OrgsListResponse(params string[] orgJsons) => + $$""" + { + "content": [{{string.Join(",", orgJsons)}}], + "page": { "size": {{orgJsons.Length}}, "totalElements": {{orgJsons.Length}}, "totalPages": 1, "number": 0 } + } + """; +} diff --git a/markmonitor-caplugin.Tests/markmonitor-caplugin.Tests.csproj b/markmonitor-caplugin.Tests/markmonitor-caplugin.Tests.csproj new file mode 100644 index 0000000..10c5fa2 --- /dev/null +++ b/markmonitor-caplugin.Tests/markmonitor-caplugin.Tests.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests + enable + enable + + false + true + + + + + + + + + + + + + + + + + + diff --git a/markmonitor-caplugin.sln b/markmonitor-caplugin.sln new file mode 100644 index 0000000..3c599da --- /dev/null +++ b/markmonitor-caplugin.sln @@ -0,0 +1,86 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31729.503 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "markmonitor-caplugin", "markmonitor-caplugin\markmonitor-caplugin.csproj", "{9D2D6ED9-4626-430C-879D-0FE0FEBED146}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{431498A1-F30A-4307-9FBF-B1D634326444}" + ProjectSection(SolutionItems) = preProject + CHANGELOG.md = CHANGELOG.md + integration-manifest.json = integration-manifest.json + readme_source.md = readme_source.md + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestConsole", "TestConsole\TestConsole.csproj", "{BE76E7C9-7DDE-49CD-8428-8256739BAD93}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "markmonitor-caplugin.Tests", "markmonitor-caplugin.Tests\markmonitor-caplugin.Tests.csproj", "{A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "markmonitor-caplugin.IntegrationTests", "markmonitor-caplugin.IntegrationTests\markmonitor-caplugin.IntegrationTests.csproj", "{58B15D3E-02C1-43EF-87D3-DF2C546C11D7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|x64.Build.0 = Debug|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Debug|x86.Build.0 = Debug|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|Any CPU.Build.0 = Release|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|x64.ActiveCfg = Release|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|x64.Build.0 = Release|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|x86.ActiveCfg = Release|Any CPU + {9D2D6ED9-4626-430C-879D-0FE0FEBED146}.Release|x86.Build.0 = Release|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|x64.ActiveCfg = Debug|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|x64.Build.0 = Debug|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|x86.ActiveCfg = Debug|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Debug|x86.Build.0 = Debug|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|Any CPU.Build.0 = Release|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|x64.ActiveCfg = Release|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|x64.Build.0 = Release|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|x86.ActiveCfg = Release|Any CPU + {BE76E7C9-7DDE-49CD-8428-8256739BAD93}.Release|x86.Build.0 = Release|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Debug|x64.ActiveCfg = Debug|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Debug|x64.Build.0 = Debug|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Debug|x86.ActiveCfg = Debug|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Debug|x86.Build.0 = Debug|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Release|Any CPU.Build.0 = Release|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Release|x64.ActiveCfg = Release|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Release|x64.Build.0 = Release|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Release|x86.ActiveCfg = Release|Any CPU + {A07CCBD0-7CC2-4A99-ABC9-41EA20EE4B79}.Release|x86.Build.0 = Release|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Debug|x64.ActiveCfg = Debug|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Debug|x64.Build.0 = Debug|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Debug|x86.ActiveCfg = Debug|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Debug|x86.Build.0 = Debug|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Release|Any CPU.Build.0 = Release|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Release|x64.ActiveCfg = Release|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Release|x64.Build.0 = Release|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Release|x86.ActiveCfg = Release|Any CPU + {58B15D3E-02C1-43EF-87D3-DF2C546C11D7}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5D2E21F6-120F-4B71-A596-991879B03943} + EndGlobalSection +EndGlobal diff --git a/markmonitor-caplugin/Client/MarkMonitorClient.cs b/markmonitor-caplugin/Client/MarkMonitorClient.cs new file mode 100644 index 0000000..ea6d959 --- /dev/null +++ b/markmonitor-caplugin/Client/MarkMonitorClient.cs @@ -0,0 +1,2025 @@ +using System.Collections.Concurrent; +using System.Diagnostics; +using System.Net.Http.Headers; +using System.Text; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; +using Keyfactor.Logging; +using Keyfactor.PKI.Enums.EJBCA; +using Keyfactor.PKI.PEM; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Tls; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; + +public class MarkMonitorClient : IDisposable +{ + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + private string _apiKey; + private string _bearerToken; + private DateTime? _tokenExpiresAtUtc; + private string _password; + private string _username; + private readonly TimeProvider _timeProvider; + private readonly SemaphoreSlim _authLock = new(1, 1); + private readonly Func _delay; + private readonly Random _retryJitter = new(); + + // Applies to idempotent GETs, auth, and destructive-but-idempotent PATCH calls + // (cancel/revoke - repeating either is a no-op, unlike a second order-create POST). Deliberately + // NOT used for CreateCertificateOrder's order-create POST - see EnrollCertificateAsync's own + // comments on why retrying that specific call risks creating a duplicate, billable MarkMonitor + // order that the enrollment dedup cache exists to prevent. + private const int MaxRetryAttempts = 3; + private static readonly TimeSpan RetryBaseDelay = TimeSpan.FromSeconds(1); + + // A 429 response's Retry-After is server-controlled input - never trusted beyond this ceiling. + // Uncapped, a single misbehaving/compromised endpoint could dictate how long this process waits + // with no way to interrupt it (SendWithRetryAsync's delay call isn't cancellable on every path, + // e.g. AuthenticateAsync's, which additionally runs inside the shared _authLock). + private const int MaxRetryAfterSeconds = 120; + + // Guards against creating a duplicate MarkMonitor order when Command retries an Enroll call - + // whether the first attempt is still in flight (the retry races it) or already finished but its + // response was lost (timeout, dropped connection, etc). Keyed on org+product+subject+CSR - an + // identical CSR for the same subject/org/product within the window is treated as a retry, not a + // distinct request. The value is reserved (via a TaskCompletionSource) *before* the real + // CreateCertificateOrder call starts, so a retry that arrives while the first call is still + // in-flight awaits the same in-progress result instead of starting a second order. Process-local + // and short-lived by design: it's a guard against the specific narrow retry window, not a durable + // dedup store (that would need to live in MarkMonitor itself). + private static readonly TimeSpan RecentEnrollmentWindow = TimeSpan.FromMinutes(5); + + // Used when resolving an org/group by friendly name (ResolveOrganizationIdAsync, + // ResolveOrganizationAsync, ResolveGroupIdAsync): MarkMonitor's name filter can return several + // fuzzy matches for one configured name, and a small page size would force one sequential HTTP + // round-trip per match just to page through them all before each method's own exact-match filter + // ever runs - this fetches all of them in one request instead. + private const int NameResolutionPageSize = 100; + + private readonly ConcurrentDictionary Tcs)> + _recentEnrollments = new(); + + /// Test-only visibility into how many reservations (successful, failed, or in-flight) + /// are currently held in - used to assert that + /// actually bounds the dictionary's growth over time + /// rather than accumulating one permanent entry per successful enrollment. + internal int RecentEnrollmentsCount => _recentEnrollments.Count; + + /// Test-only visibility into the configured HTTP timeout, to assert that the + /// constructor's timeoutSeconds parameter actually reaches the underlying HttpClient. + internal TimeSpan HttpTimeout => _httpClient.Timeout; + + // A resolved organization/group GUID never changes for a given name - MarkMonitor doesn't let a + // name be reassigned to a different org/group ID - so it's safe to cache indefinitely for this + // client's lifetime (which is itself cached for the whole plugin instance's lifetime). Without + // this, every single Enroll/Revoke/Cancel call re-resolved the configured OrgName (and, for + // enrollment, a named MarkmonitorGroup) via a fresh MarkMonitor API call, even though the + // configured value is invariant for the connector's lifetime - real cost at bulk-operation scale + // (e.g. a CRL/lifecycle sweep revoking thousands of certs). A "not found" result (null) is + // deliberately NOT cached, since an org/group that doesn't exist yet could be created later. + private readonly ConcurrentDictionary _resolvedOrgIdByName = new(StringComparer.OrdinalIgnoreCase); + private readonly ConcurrentDictionary _resolvedGroupIdByName = new(StringComparer.OrdinalIgnoreCase); + + public MarkMonitorClient(string baseUrl, string apiKey, string username, string password, bool validateSsl = true, + HttpMessageHandler handler = null, TimeProvider timeProvider = null, int timeoutSeconds = 120, + Func delay = null) + { + BaseUrl = baseUrl; + _logger = LogHandler.GetClassLogger(GetType()); + _apiKey = apiKey; + _username = username; + _password = password; + _timeProvider = timeProvider ?? TimeProvider.System; + // Task.Delay's own (TimeSpan, CancellationToken) signature matches this delegate exactly - + // a test can override it to observe/short-circuit backoff waits without a real sleep. + _delay = delay ?? Task.Delay; + + // A caller-supplied handler (e.g. a fake in tests) is used as-is; otherwise build the real + // HttpClientHandler with the usual SSL validation behavior. + if (handler == null) + { + var httpClientHandler = new HttpClientHandler { UseCookies = false }; + + if (!validateSsl) + { + _logger.LogWarning("SSL certificate validation is disabled for {BaseUrl}", baseUrl); + httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true; + } + + handler = httpClientHandler; + } + + _httpClient = new HttpClient(handler); + _httpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds); + // Every request this client makes wants an "application/json" Accept header, and it never + // changes for the client's lifetime - set it once here rather than in FetchOrderAsync, where + // an Add() on every call (Accept is a collection, not a single-value property) with no + // preceding Remove() appended a fresh duplicate entry per call, unboundedly growing the + // header list on this cached, long-lived HttpClient. + _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + } + + public void Dispose() + { + _httpClient.Dispose(); + _authLock.Dispose(); + } + + public string BaseUrl { get; } + + private bool ValidateConfiguration() + { + if (string.IsNullOrEmpty(_apiKey)) + throw new ConfigurationValidationException("API Key is required."); + + if (string.IsNullOrEmpty(_username)) + throw new ConfigurationValidationException("Username is required."); + + if (string.IsNullOrEmpty(_password)) + throw new ConfigurationValidationException("Password is required."); + + return true; + } + + public async Task AuthenticateAsync(string apiKey = null, string username = null, string password = null) + { + _logger.MethodEntry(); + // The entire method body is wrapped in one try/catch, below, so ANY failure - missing config, + // a transport-level failure, a non-2xx response, or a 2xx response with no usable bearer token + // - produces the same single, self-contained, identity-tagged "Authentication failed for + // {Username}" record. Earlier versions logged that only from specific branches (the non-2xx + // response, or a caught HTTP/parse exception), which left gaps for e.g. a config-validation + // failure (thrown before any of those branches even ran) or a well-formed 2xx body missing its + // token field (which wouldn't have thrown at all) - each silently skipping this method's own + // audit record in favor of a generic, identity-less one from whichever caller's catch received + // the exception instead. + try + { + if (!string.IsNullOrEmpty(apiKey)) + { + _logger.LogDebug("Setting API Key"); + _apiKey = apiKey; + } + + if (!string.IsNullOrEmpty(username)) + { + _logger.LogDebug("Setting username"); + _username = username; + } + + if (!string.IsNullOrEmpty(password)) + { + _logger.LogDebug("Setting password"); + _password = password; + } + + _logger.LogDebug("Calling ValidateConfiguration"); + var isValid = ValidateConfiguration(); + if (!isValid) throw new ConfigurationValidationException("Invalid configuration"); + + _logger.LogDebug("Setting \"X-API-KEY\" header"); + _httpClient.DefaultRequestHeaders.Remove("X-API-KEY"); + _httpClient.DefaultRequestHeaders.Add("X-API-KEY", _apiKey); + var requestBody = new TokenRequest + { + Username = _username, + Password = _password + }; + + var requestUrl = $"{BaseUrl}/auth/v1/auth/authenticate"; + // Username (unlike ApiKey/Password) is not a secret - the plugin's own config schema marks + // it Hidden=false - and is the only field that identifies which MarkMonitor service account + // performed a given authentication. Log it so an auditor can reconstruct "who authenticated" + // from this component's own logs, including when multiple CA connector instances (each with + // a different service account) share one log sink. + _logger.LogInformation("Authenticating with MarkMonitor API at {RequestUrl} as {Username}", requestUrl, + _username); + + _logger.LogDebug("Sending authentication request"); + // Deliberately SendAndLogAsync, NOT SendWithRetryAsync: this whole method runs inside + // EnsureAuthenticatedAsync's _authLock, held by every other concurrent Enroll/Revoke/Sync + // call on this cached client that also needs a token. Retrying here would multiply the + // worst-case lock-hold time (up to 3x a full HTTP timeout, plus backoff) for everyone + // queued behind it, during exactly the "MarkMonitor is degraded" scenario where fast + // failure matters most - a caller-level retry (Command retrying the whole operation) is + // the right layer for a transient auth failure, not a retry loop inside the lock. + var response = await SendAndLogAsync(() => _httpClient.PostAsync(requestUrl, + new StringContent(JsonConvert.SerializeObject(requestBody), Encoding.UTF8, "application/json")), + "POST", requestUrl); + + _logger.LogDebug("Reading authentication response"); + var content = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); + + _logger.LogDebug("Deserializing token response"); + var tokenResponse = JsonConvert.DeserializeObject(content); + if (string.IsNullOrEmpty(tokenResponse?.BearerToken)) + // Covers a null/unparsable body (tokenResponse itself null) as well as a well-formed + // body simply missing/empty the "token" field (tokenResponse non-null, BearerToken + // null/empty) - either way, there is no usable bearer token to authenticate with. + throw new JsonSerializationException( + "MarkMonitor returned a successful authentication response with no usable bearer token"); + + _bearerToken = tokenResponse.BearerToken; + // Subtract a small safety buffer so a request that starts just before expiry doesn't + // race the token dying mid-flight. + _tokenExpiresAtUtc = _timeProvider.GetUtcNow().UtcDateTime.AddSeconds(tokenResponse.ExpiresIn - 30); + _logger.LogDebug("Bearer token received and valid for {TokenExpiration} seconds", + tokenResponse.ExpiresIn); + _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _bearerToken); + + _logger.LogInformation("Authentication successful for {Username}", _username); + } + catch (Exception e) + { + _logger.LogError("Authentication failed for {Username}: {EMessage}", _username, e.Message); + throw; + } + } + + // A page-fetch failure is already retried by SendWithRetryAsync and, if still failing, aborts the + // whole sync (completeness beats partial silence) - this threshold instead guards against the + // *per-record* processing loop below: enough individual bad records (bad status string, bad + // date, null fields) that continuing to silently skip them would produce a "successful" sync + // that quietly imported almost nothing. Not evaluated until MinimumSampleSize records have been + // observed, so a handful of bad records early in a small org's sync can't trip it. + private const int SyncErrorRateMinimumSampleSize = 50; + private const double SyncErrorRateThreshold = 0.25; + + // Each record's sync processing is an independent, order-scoped ICertificateDataReader lookup + // with no shared mutable state besides the thread-safe certificatesBuffer and the Interlocked + // counters in GetCertificateInventoryAsync - serializing them one at a time (as originally + // shipped) was pure added latency at scale with nothing to protect. Bounded, not unlimited, so a + // single page (up to PageSize=500 records) doesn't fire off hundreds of concurrent local calls. + private const int MaxConcurrentRecordsPerPage = 10; + + private enum SyncRecordOutcome + { + Emitted, + SkippedNotReady, + SkippedUnchanged + } + + public async Task GetCertificateInventoryAsync(string caId, string sort, int limit, + BlockingCollection certificatesBuffer, CancellationToken cancelToken, + ICertificateDataReader certificateDataReader = null, bool forceCompleteSync = false) + { + _logger.MethodEntry(); + var emittedCount = 0; + var skippedNotReadyCount = 0; + var skippedUnchangedCount = 0; + var erroredCount = 0; + var totalObserved = 0; + try + { + await EnsureAuthenticatedAsync(); + _logger.LogInformation("Retrieving certificate inventory from MarkMonitor"); + // Stream each page straight into certificatesBuffer as it arrives, via onPageReceived, + // instead of letting ListCertificateOrdersAsync accumulate every page for the whole order + // history into one in-memory list before this method ever touches the buffer - for a + // large/long-lived org that meant unbounded peak memory and zero buffer throughput until + // the entire (possibly huge) order history had downloaded. + await ListCertificateOrdersAsync(0, caId, sort, limit, cancelToken, async page => + { + _logger.LogDebug("Retrieved a page of '{CertificateCount}' certificate orders", page.Count); + + // Thrown outside the Parallel.ForEachAsync body below (never from inside it) so it + // always propagates as a plain Exception, not wrapped in an AggregateException - the + // only exception type a lambda body here can actually throw is OperationCanceledException + // (on real cancellation); every per-record processing failure is caught and counted + // internally instead of escaping the lambda. + Exception breakerException = null; + await Parallel.ForEachAsync(page, + new ParallelOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = MaxConcurrentRecordsPerPage }, + async (certificateDetail, ct) => + { + var observed = Interlocked.Increment(ref totalObserved); + try + { + switch (await ProcessOneInventoryRecordAsync(certificateDetail, certificatesBuffer, + certificateDataReader, forceCompleteSync, ct)) + { + case SyncRecordOutcome.Emitted: + Interlocked.Increment(ref emittedCount); + break; + case SyncRecordOutcome.SkippedNotReady: + Interlocked.Increment(ref skippedNotReadyCount); + break; + case SyncRecordOutcome.SkippedUnchanged: + Interlocked.Increment(ref skippedUnchangedCount); + break; + } + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception e) + { + // A single bad record (bad status string, bad date, null fields) must not + // abort the rest of the page/sync - certinext's model. The error-rate + // circuit breaker below is what catches this becoming systemic rather than + // a one-off. + Interlocked.Increment(ref erroredCount); + _logger.LogError( + "Error processing certificate order {CertificateId} during synchronization - skipping it and continuing: {EMessage}", + certificateDetail?.Id, e.Message); + } + + if (observed >= SyncErrorRateMinimumSampleSize) + { + var errorRate = (double)Volatile.Read(ref erroredCount) / observed; + if (errorRate > SyncErrorRateThreshold) + Interlocked.CompareExchange(ref breakerException, new Exception( + $"Aborting synchronization: {erroredCount} of {observed} records processed so far have failed ({errorRate:P0}), exceeding the {SyncErrorRateThreshold:P0} error-rate threshold"), + null); + } + }); + + // Deliberately checked after the whole page finishes rather than cancelling + // in-flight/queued iterations the instant the threshold crosses - the breaker's own + // purpose (catching systemic failure, not enforcing an exact cutoff record) tolerates + // finishing out the current page, bounded by PageSize, before aborting. + if (breakerException != null) throw breakerException; + }); + + _logger.LogInformation( + "Synchronization complete: {EmittedCount} emitted, {SkippedUnchangedCount} skipped (unchanged), {SkippedNotReadyCount} skipped (not ready), {ErroredCount} errored (of {TotalObserved} total)", + emittedCount, skippedUnchangedCount, skippedNotReadyCount, erroredCount, totalObserved); + return emittedCount; + } + catch (OperationCanceledException) + { + _logger.LogInformation("Certificate inventory retrieval cancelled"); + throw; // Rethrow the cancellation exception to ensure it's propagated + } + catch (Exception e) + { + _logger.LogError("An error has occurred: {EMessage}", e.Message); + throw; + } + finally + { + certificatesBuffer.CompleteAdding(); // Ensure buffer is completed even on cancellation + _logger.MethodExit(); + } + } + + /// + /// Processes a single sync record: adds it to and returns + /// , unless shows + /// Command already has this exact CARequestID at the exact status this record maps to - in which + /// case it's skipped () rather than re-emitted for + /// no reason. bypasses that optimization entirely. An order + /// with no cert details yet is skipped () without + /// being counted as an error - that's an expected "not ready yet" state, not a bad record. + /// + private async Task ProcessOneInventoryRecordAsync(OrderContent certificateDetail, + BlockingCollection certificatesBuffer, ICertificateDataReader certificateDataReader, + bool forceCompleteSync, CancellationToken cancelToken) + { + if (certificateDetail.Cert == null) + { + _logger.LogWarning( + "Certificate {CertificateId} has no cert details yet (status {Status}) - skipping it for this sync rather than aborting the rest of the page", + certificateDetail.Id, certificateDetail.Status); + return SyncRecordOutcome.SkippedNotReady; + } + + var certStatus = MarkMonitorCertificateStatusToCAStatus(certificateDetail); + _logger.LogTrace("Certificate {CertificateId} status: {CertificateStatus}", certificateDetail.Id, + certStatus); + + // Status alone isn't enough to prove nothing changed: MarkMonitor's own status model + // round-trips DIGI_ISSUED -> DIGI_REISSUE_PENDING -> DIGI_ISSUED for an out-of-band reissue + // of the same order ID (see Enums.cs's OrderStatus), so a sync that happens to observe the + // order only before and after that round-trip would otherwise see the same status both times + // and skip forever - silently masking a real certificate rotation from Command's inventory. + // Expiration date changes on reissue (a new cert has a new validity window), so comparing it + // too - using the same ICertificateDataReader lookup RenewOrReissue already relies on - + // catches that case without needing a "get current serial by request ID" method the + // interface doesn't expose. + if (!forceCompleteSync && certificateDataReader != null && + await certificateDataReader.DoesCertExistForRequestID(certificateDetail.Id) && + await certificateDataReader.GetStatusByRequestID(certificateDetail.Id) == certStatus && + certificateDataReader.GetExpirationDateByRequestId(certificateDetail.Id) == certificateDetail.Cert.DateValidUntil) + { + _logger.LogTrace( + "Certificate {CertificateId} is unchanged (status {CertificateStatus}) - skipping re-emission", + certificateDetail.Id, certStatus); + return SyncRecordOutcome.SkippedUnchanged; + } + + _logger.LogInformation("Adding certificate {CertificateId} to buffer", certificateDetail.Id); + _logger.LogDebug("Converting certificate {CertificateId} revocation status {Status}", + certificateDetail.Id, certificateDetail.Cert.RevokeStatus); + DateTime? revocationDate = null; + if (certificateDetail.Cert.RevokeStatus == "REVOKED") + { + _logger.LogDebug("Certificate {CertificateId} is revoked", certificateDetail.Id); + revocationDate = Convert.ToDateTime(certificateDetail.Cert.DateValidUntil); + } + + var fullChain = new StringBuilder(); + if (certificateDetail.Cert.EndEntityCert != null) + { + _logger.LogDebug("Adding end entity certificate to full chain for {CertificateId}", + certificateDetail.Id); + fullChain.AppendLine(certificateDetail.Cert.EndEntityCert); + } + if (certificateDetail.Cert.IntermediateCert != null) + { + _logger.LogDebug("Adding issuer certificate to full chain for {CertificateId}", certificateDetail.Id); + fullChain.AppendLine(certificateDetail.Cert.IntermediateCert); + } + if (certificateDetail.Cert.RootCert != null) + { + _logger.LogDebug("Adding root certificate to full chain for {CertificateId}", certificateDetail.Id); + fullChain.AppendLine(certificateDetail.Cert.RootCert); + } + + certificatesBuffer.Add( + new AnyCAPluginCertificate + { + CARequestID = certificateDetail.Id, + Status = certStatus, + Certificate = fullChain.ToString(), + CSR = certificateDetail.Cert.Csr, + ProductID = certificateDetail.CertType, + RevocationDate = revocationDate, + // RevocationReason = certificateDetail.Cert.RevokeStatus, // TODO: Not available in MarkMonitor API + }, cancelToken); + return SyncRecordOutcome.Emitted; + } + + private List BuildQueryString(int providerId, string orgId, string sort, int limit, int page) + { + _logger.MethodEntry(); + var query = new List(); + if (page > 0) query.Add($"page={page}"); + if (limit > 0) query.Add($"size={limit}"); + if (!string.IsNullOrEmpty(sort)) query.Add($"sort={Uri.EscapeDataString(sort)}"); + if (providerId > 0) query.Add($"providerId={providerId}"); + if (!string.IsNullOrEmpty(orgId)) query.Add($"organizationId={Uri.EscapeDataString(orgId)}"); + _logger.MethodExit(); + return query; + } + + private List BuildListOrgsQueryString(string name = "", string sort = "", int limit = 0, int page = 0) + { + _logger.MethodEntry(); + var query = new List(); + if (page > 0) query.Add($"page={page}"); + if (limit > 0) query.Add($"size={limit}"); + if (!string.IsNullOrEmpty(sort)) query.Add($"sort={Uri.EscapeDataString(sort)}"); + if (!string.IsNullOrEmpty(name)) query.Add($"name={Uri.EscapeDataString(name)}"); + + _logger.LogTrace("Query string: {Query}", query); + _logger.MethodExit(); + return query; + } + + /// Fetches every page of matching certificate orders. When + /// is supplied, each page is handed to it as soon as it arrives and is not also accumulated into + /// the returned list (which is then null) - lets a caller with a large result set (e.g. a full + /// inventory sync) process/forward orders page-by-page instead of holding the entire result set + /// in memory and seeing zero progress until every page has downloaded. Omit it to get the + /// original all-pages-in-one-list behavior every other caller relies on. + public async Task> ListCertificateOrdersAsync(int providerId, string orgId, string sort, + int limit, CancellationToken cancelToken = default, Func, Task> onPageReceived = null) + { + _logger.MethodEntry(); + await EnsureAuthenticatedAsync(); + var output = onPageReceived == null ? new List() : null; + try + { + _logger.LogInformation("Retrieving certificate orders from MarkMonitor"); + var currentPage = 0; + var allPagesDownloaded = false; + + do + { + cancelToken.ThrowIfCancellationRequested(); + + var nextUrl = + $"{BaseUrl}/certs/v1/order"; + _logger.LogTrace("Base URL: {BaseUrl}", nextUrl); + + _logger.LogDebug("Building query string"); + var query = BuildQueryString(providerId, orgId, sort, limit, currentPage); + if (query.Count > 0) nextUrl += "?" + string.Join("&", query); + + _logger.LogTrace("Getting page \'{CurrentPage}\' of \'{Limit}\')", currentPage, limit); + + _logger.LogDebug("Getting certificate orders from MarkMonitor {NextUrl}", nextUrl); + var response = await SendWithRetryAsync(() => _httpClient.GetAsync(nextUrl, cancelToken), "GET", + nextUrl, cancelToken); + + _logger.LogDebug("Reading response content"); + var content = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); + + _logger.LogDebug("Deserializing response content to MarkMonitorListOrdersResponse"); + var certificateListResponse = JsonConvert.DeserializeObject(content); + if (onPageReceived != null) + await onPageReceived(certificateListResponse.Content); + else + output.AddRange(certificateListResponse.Content); + currentPage++; + allPagesDownloaded = currentPage >= certificateListResponse.MarkMonitorPage.TotalPages; + } while (!allPagesDownloaded); + + return output; + } + catch (OperationCanceledException) + { + _logger.LogInformation("Certificate inventory retrieval cancelled"); + throw; // Rethrow the cancellation exception to ensure it's propagated + } + catch (Exception e) + { + _logger.LogError("An error has occurred: {EMessage}", e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + public async Task> ListOrganizationsAsync(int page = 0, int limit = 0, + string name = "") + { + _logger.MethodEntry(); + await EnsureAuthenticatedAsync(); + var output = new List(); + try + { + _logger.LogInformation("Retrieving organizations from MarkMonitor"); + var currentPage = 0; + var allPagesDownloaded = false; + + do + { + var nextUrl = + $"{BaseUrl}/certs/v1/organization"; + + _logger.LogTrace("Base URL: {BaseUrl}", nextUrl); + + _logger.LogDebug("Building query string"); + var query = BuildListOrgsQueryString(name, "", limit, currentPage); + if (query.Count > 0) nextUrl += "?" + string.Join("&", query); + + _logger.LogTrace("Getting page \'{CurrentPage}\' of \'{Limit}\')", currentPage, limit); + + _logger.LogDebug("Getting organizations from MarkMonitor {NextUrl}", nextUrl); + var response = await SendWithRetryAsync(() => _httpClient.GetAsync(nextUrl), "GET", nextUrl); + + _logger.LogDebug("Reading response content"); + var content = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); + + _logger.LogDebug("Deserializing response content to MarkMonitorListOrgResponse"); + var orgListResponse = JsonConvert.DeserializeObject(content); + + _logger.LogDebug("Adding organizations to output"); + output.AddRange(orgListResponse.Content); + currentPage++; + _logger.LogTrace("Total organizations added to output: {OutputCount}", output.Count); + allPagesDownloaded = currentPage >= orgListResponse.MarkMonitorPage.TotalPages; + } while (!allPagesDownloaded); + + return output; + } + catch (OperationCanceledException) + { + _logger.LogInformation("Organization retrieval cancelled"); + throw; // Rethrow the cancellation exception to ensure it's propagated + } + catch (Exception e) + { + _logger.LogError("An error has occurred: {EMessage}", e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + public async Task GetOrganizationAsync(string orgId) + { + _logger.MethodEntry(); + try + { + ValidateGuidFormat(orgId, nameof(orgId), "MarkMonitor organization ID"); + await EnsureAuthenticatedAsync(); + var url = $"{BaseUrl}/certs/v1/organization/{orgId}"; + _logger.LogDebug("Getting organization from MarkMonitor {Url}", url); + var response = await SendWithRetryAsync(() => _httpClient.GetAsync(url), "GET", url); + var content = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); + + return JsonConvert.DeserializeObject(content); + } + catch (Exception e) + { + // Rethrow rather than swallow to null - a transient auth/network/parsing failure here + // must not be reported to the caller identically to "this organization doesn't exist" + // (same class of gap already fixed in GetSingleOrderAsync). + _logger.LogError("An error has occurred: {EMessage}", e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + public async Task> ListGroupsAsync(int page = 0, int limit = 0, string name = "") + { + _logger.MethodEntry(); + await EnsureAuthenticatedAsync(); + var output = new List(); + try + { + _logger.LogInformation("Retrieving groups from MarkMonitor"); + var currentPage = 0; + var allPagesDownloaded = false; + + do + { + var nextUrl = $"{BaseUrl}/auth/v1/group"; + + var query = BuildListOrgsQueryString(name, "", limit, currentPage); + if (query.Count > 0) nextUrl += "?" + string.Join("&", query); + + _logger.LogDebug("Getting groups from MarkMonitor {NextUrl}", nextUrl); + var response = await SendWithRetryAsync(() => _httpClient.GetAsync(nextUrl), "GET", nextUrl); + + var content = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); + + var groupListResponse = JsonConvert.DeserializeObject(content); + output.AddRange(groupListResponse.Groups ?? new List()); + currentPage++; + allPagesDownloaded = currentPage >= groupListResponse.MarkMonitorPage.TotalPages; + } while (!allPagesDownloaded); + + return output; + } + catch (Exception e) + { + // Group resolution is an optional, best-effort lookup (EnrollCertificateAsync falls back + // to no group on failure) - deliberately swallowed rather than failing the enrollment. + _logger.LogError("An error has occurred: {EMessage}", e.Message); + return null; + } + finally + { + _logger.MethodExit(); + } + } + + /// Fetches the raw order content for a single order ID (used both to build the + /// public-facing AnyCAPluginCertificate and, internally, to verify an order's owning + /// organization before revoking or cancelling it). is false only + /// for PollForIssuanceAsync's own per-attempt fetch - that loop is already its own outer retry + /// mechanism (a failed attempt just logs and moves to the next poll), so an inner + /// SendWithRetryAsync there would multiply a single hung/slow poll attempt by up to 3x the + /// configured timeout, blowing well past the "bounded by PickupRetries/PickupDelaySeconds" + /// latency ceiling PollForIssuanceAsync's own callers document. + private async Task FetchOrderAsync(string orderId, bool allowRetry = true) + { + ValidateGuidFormat(orderId, nameof(orderId), "MarkMonitor order ID"); + await EnsureAuthenticatedAsync(); + + // Do NOT re-set the Authorization header here: EnsureAuthenticatedAsync/AuthenticateAsync + // already set it once, under _authLock, whenever the token is (re)established - every other + // call site in this class relies on that same invariant. Setting it again here, unguarded, + // let a concurrent FetchOrderAsync call (or a concurrent re-authentication) race writes to + // the shared HttpClient's Authorization header (see GitHub issue #8). The Accept header is + // likewise set once, in the constructor - not here on every call (see its comment there). + var orderUrl = $"{BaseUrl}/certs/v1/order/{orderId}"; + var response = allowRetry + ? await SendWithRetryAsync(() => _httpClient.GetAsync(orderUrl), "GET", orderUrl) + : await SendAndLogAsync(() => _httpClient.GetAsync(orderUrl), "GET", orderUrl); + var content = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) throw new Exception(BuildErrorString(content)); + return JsonConvert.DeserializeObject(content); + } + + /// + /// MarkMonitor always returns a freshly-created order in a pending state (typically + /// EXTERNALVALIDATION) - unlike some other CA APIs, it never issues synchronously from the + /// create-order call. For a product that resolves DCV/approval quickly, polling here for up to + /// attempts (every + /// seconds) lets Enroll return the issued + /// certificate directly instead of always making Command wait for the next sync. Falls back to + /// returning unchanged - today's existing behavior - if + /// PickupRetries is 0, the order already reached a terminal state, or the budget is + /// exhausted before issuance. Each poll's own fetch is deliberately single-attempt (see + /// 's allowRetry parameter) so this loop's real worst-case + /// wall-clock time stays close to PickupRetries * (PickupDelaySeconds + TimeoutSeconds) + /// rather than being multiplied further by an inner retry cascade on top of this outer one. + /// + private async Task PollForIssuanceAsync(OrderContent order, MarkMonitorConfig config) + { + if (config.PickupRetries <= 0 || IsPollingComplete(order)) return order; + + var delay = TimeSpan.FromSeconds(config.PickupDelaySeconds); + for (var attempt = 1; attempt <= config.PickupRetries; attempt++) + { + await _delay(delay, CancellationToken.None); + + OrderContent polled; + try + { + polled = await FetchOrderAsync(order.Id, allowRetry: false); + } + catch (Exception e) + { + // A transient failure to poll must not fail an enrollment whose order was already + // created successfully - just retry on the next attempt with the last known state. + _logger.LogWarning( + "Pickup poll {Attempt}/{MaxAttempts} for order {CARequestID} failed - will retry: {EMessage}", + attempt, config.PickupRetries, order.Id, e.Message); + continue; + } + + order = polled; + if (IsPollingComplete(order)) break; + } + + _logger.LogInformation( + "Pickup polling for order {CARequestID} finished after up to {MaxAttempts} attempt(s), current status {OrderStatus}", + order.Id, config.PickupRetries, order.Status); + return order; + } + + // True once the order has either issued (with a cert body actually present) or reached a + // terminal state that will never produce one - no point spending the rest of the poll budget + // either way. + private bool IsPollingComplete(OrderContent order) + { + var status = MarkMonitorCertificateStatusToCAStatus(order); + return (status == (int)EndEntityStatus.GENERATED && order.Cert?.EndEntityCert != null) || + status == (int)EndEntityStatus.FAILED || status == (int)EndEntityStatus.CANCELLED || + status == (int)EndEntityStatus.REVOKED; + } + + /// Resolves a CA connection's configured OrgId (which may be a friendly name or a + /// GUID) to the organization's real GUID. + private async Task ResolveOrganizationIdAsync(string orgNameOrId) + { + if (Guid.TryParse(orgNameOrId, out _)) return orgNameOrId; + if (_resolvedOrgIdByName.TryGetValue(orgNameOrId, out var cachedOrgId)) return cachedOrgId; + + var orgs = await ListOrganizationsAsync(0, NameResolutionPageSize, orgNameOrId); + // MarkMonitor's own name filter may do substring/fuzzy matching rather than exact matching, + // so filter to an exact (case-insensitive) name match ourselves rather than trusting the + // first result - otherwise a configured name that's a substring of another org's name (e.g. + // "Acme" vs "Acme Corp Europe") could silently resolve to the wrong organization, which would + // undermine the cross-org ownership check in RevokeCertificateAsync. + var resolvedOrgId = + orgs.FirstOrDefault(o => string.Equals(o.Name, orgNameOrId, StringComparison.OrdinalIgnoreCase))?.Id; + if (resolvedOrgId != null) _resolvedOrgIdByName[orgNameOrId] = resolvedOrgId; + return resolvedOrgId; + } + + /// + /// Verifies that belongs to the configured organization before + /// allowing a destructive action (revoke/cancel) against it. Shared by + /// and so the two stay + /// behaviorally identical on this check. + /// + /// MarkMonitor's own ignoreOrgCheck=false default only guards against acting on an order that + /// belongs to a different reseller account entirely - it has no notion of the specific + /// sub-organization this CA connector is scoped to. That distinction matters most for + /// RenewOrReissue, where the order ID being revoked comes from Command's ICertificateDataReader + /// rather than from this org's own enrollment - so verify it here rather than trusting the + /// caller (or MarkMonitor) to have scoped it correctly. + /// + /// A blank orgName intentionally skips this check (ad-hoc/manual callers that don't scope by + /// organization), but that must never happen silently - it's logged explicitly so a production + /// caller unexpectedly hitting this path (e.g. a misconfigured OrgId) is visible in the logs + /// rather than looking identical to a passing check. + /// + /// The order being acted on. + /// The configured organization name or GUID; blank skips the check. + /// Present-participle form of the action for log text (e.g. "Revoking", "Cancelling"). + /// Infinitive form of the action for log/exception text (e.g. "revoke", "cancel"). + private async Task EnsureOrderBelongsToOrganizationAsync(string orderId, string orgName, string actionGerund, + string actionVerb) + { + if (string.IsNullOrWhiteSpace(orgName)) + { + _logger.LogWarning( + "{ActionGerund} order {OrderId} with no organization to verify ownership against - the cross-organization ownership check was skipped", + actionGerund, orderId); + return; + } + + // Independent lookups (one depends only on orgName, the other only on orderId) - run them + // concurrently rather than one after another. Both internally call EnsureAuthenticatedAsync, + // which is safe under concurrent access (see its own comment on _authLock). + var expectedOrgIdTask = ResolveOrganizationIdAsync(orgName); + var orderTask = FetchOrderAsync(orderId); + await Task.WhenAll(expectedOrgIdTask, orderTask); + var expectedOrgId = expectedOrgIdTask.Result; + var order = orderTask.Result; + // Comparing as parsed Guids, not raw strings: Guid.TryParse accepts several textual + // formats (braces, no dashes, etc.), so an admin-configured OrgId in a non-canonical + // format must still match MarkMonitor's own canonical serialization of the same GUID. + var actualOrgIdParsed = Guid.TryParse(order.OrganizationId, out var actualOrgId) ? actualOrgId : (Guid?)null; + var expectedOrgIdParsed = expectedOrgId != null && Guid.TryParse(expectedOrgId, out var parsedExpected) + ? parsedExpected + : (Guid?)null; + if (expectedOrgIdParsed == null || actualOrgIdParsed == null || actualOrgIdParsed != expectedOrgIdParsed) + { + _logger.LogError( + "Refusing to {ActionVerb} order {OrderId}: it belongs to organization {ActualOrgId}, but the configured organization {ConfiguredOrgName} resolved to {ExpectedOrgId}", + actionVerb, orderId, order.OrganizationId, orgName, expectedOrgId); + throw new Exception($"Order {orderId} belongs to a different organization than the configured '{orgName}' - refusing to {actionVerb} it"); + } + } + + public async Task GetSingleOrderAsync(string orderId) + { + try + { + var order = await FetchOrderAsync(orderId); + + // order.Cert can be null for an order that hasn't progressed far enough yet (e.g. + // CREATED/DIGI_NEEDS_CSR) - same class of gap already fixed in GetCertificateInventoryAsync. + DateTime? revocationDate = null; + if (order.Cert?.RevokeStatus == "REVOKED") revocationDate = Convert.ToDateTime(order.Cert.DateValidUntil); + + return new AnyCAPluginCertificate + { + CARequestID = order.Id, + Certificate = order.Cert?.EndEntityCert, + Status = MarkMonitorCertificateStatusToCAStatus(order), + ProductID = order.CertType, + RevocationDate = revocationDate + }; + } + catch (Exception e) + { + // Rethrow rather than swallow to null - GetSingleRecord (the connector method that + // calls this) needs the real exception to log a failure instead of silently reporting + // "not found" for what was actually an auth/network/parsing error. + _logger.LogError("An error has occurred: {EMessage}", e.Message); + throw; + } + } + + /// + /// Order IDs are interpolated directly into request URLs - a corrupted or manipulated + /// CARequestID should fail fast with a clear error rather than silently producing an unexpected + /// path segment. + /// + private static void ValidateGuidFormat(string value, string paramName, string description) + { + if (!Guid.TryParse(value, out _)) + // The rejected value is embedded in this exception's own Message, which multiple callers + // (this class's own catch blocks, and MarkMonitorCAConnector's) log verbatim via e.Message + // - sanitize it here, at the source, rather than trying to catch every downstream log call + // that might surface it (CWE-117). + throw new ArgumentException( + $"'{LogSanitizer.ForLog(value)}' is not a valid {description} (expected a GUID)", paramName); + } + + private string getCsrAlgorithm(Pkcs10CertificationRequest csr) + { + var signatureAlgorithm = csr.SignatureAlgorithm.Algorithm.Id; + var requestAlgorithm = signatureAlgorithm switch + { + //check if algorithm is RSA or ECC + "1.2.840.113549.1.1.11" => AlgorithmTypes.Rsa.GetDescription(), + "1.2.840.10045.4.3.1" or "1.2.840.10045.4.3.2" or "1.2.840.10045.4.3.3" or "1.2.840.10045.4.3.4" + or "1.2.840.10045.2.1" => AlgorithmTypes.Ecc.GetDescription(), + // "2.16.840.1.101.3.4.3.1" or "2.16.840.1.101.3.4.3.2" or "2.16.840.1.101.3.4.3.3" + // or "2.16.840.1.101.3.4.3.4" => AlgorithmTypes.Dsa.GetDescription(), //DSA not supported + _ => throw new Exception($"Invalid CSR signature algorithm {signatureAlgorithm}") + }; + return requestAlgorithm; + } + + private const string EcPublicKeyOid = "1.2.840.10045.2.1"; + + /// + /// MarkMonitor's DigiCert-backed products silently reject an ECC CSR whose public key uses + /// explicit curve parameters (the curve's prime/coefficients/base point spelled out) instead of + /// a named-curve OID reference - the order fails almost instantly with no reason surfaced + /// anywhere in MarkMonitor's API (confirmed by decoding a real rejected order's CSR). CA/Browser + /// Forum baseline requirements disallow explicit parameters for publicly-trusted certs, so this + /// fails fast with an actionable message here rather than silently forwarding an order that + /// MarkMonitor will just as silently fail. + /// + private static void ValidateEccCsrUsesNamedCurve(SubjectPublicKeyInfo publicKeyInfo) + { + if (publicKeyInfo.Algorithm.Algorithm.Id != EcPublicKeyOid) return; + + var ecParameters = X962Parameters.GetInstance(publicKeyInfo.Algorithm.Parameters); + if (!ecParameters.IsNamedCurve) + throw new ArgumentException( + "ECC CSR uses explicit curve parameters instead of a named curve (e.g. P-256/secp256r1) - MarkMonitor requires a named curve and will silently fail the order otherwise"); + } + + // A reservation is "still active" - and must keep being awaited rather than replaced - if either + // its nominal window hasn't elapsed yet, or its own call simply hasn't finished yet. The latter + // matters when a call's real work (org/group lookups, CSR parsing, the order-create HTTP call + // itself) takes longer than RecentEnrollmentWindow: without it, a retry arriving after the nominal + // window - but while the original call is still genuinely in flight - would win a fresh + // reservation and create a real second order, exactly the outcome this cache exists to prevent. + private static bool IsReservationStillActive( + (DateTime ExpiresAtUtc, TaskCompletionSource Tcs) entry, DateTime now) => + entry.ExpiresAtUtc > now || !entry.Tcs.Task.IsCompleted; + + // _recentEnrollments has no eviction path for a *successful* enrollment - the dedupe key is + // built from the CSR, which is unique per real-world request, so a completed success entry is + // essentially never looked up again and would otherwise sit in the dictionary (holding the full + // CSR and issued cert chain) for the remaining lifetime of the process. Sweeping expired-and- + // completed entries here, on every enrollment call, keeps the dictionary bounded by "enrollments + // within the last RecentEnrollmentWindow" instead of "enrollments ever performed" - without a + // separate timer/thread to manage. Only entries IsReservationStillActive already says are safe to + // drop (window elapsed AND the call finished) are removed, so a genuinely in-flight reservation is + // never touched. + private void PruneExpiredReservations(DateTime now) + { + foreach (var entry in _recentEnrollments) + if (!IsReservationStillActive(entry.Value, now)) + TryRemoveReservation(entry.Key, entry.Value); + } + + // ConcurrentDictionary's own Remove(key) doesn't check the value, so it can delete a different + // caller's reservation that has since replaced the one this call actually owned for the same + // key - going through ICollection> gives an atomic, conditional remove-if-still- + // equal-to-this-value instead. + private bool TryRemoveReservation(string key, (DateTime ExpiresAtUtc, TaskCompletionSource Tcs) entry) => + ((ICollection)>>)_recentEnrollments) + .Remove(new KeyValuePair)>(key, entry)); + + public async Task EnrollCertificateAsync(string csr, string subject, + Dictionary san, string orderType, Dictionary productParams, + MarkMonitorConfig config) + { + _logger.MethodEntry(); + var dedupeKey = $"{config.OrgName}|{orderType}|{subject}|{csr}"; + // Subject is fully requester-controlled (straight off the submitted CSR) - log a CR/LF- + // escaped copy everywhere below so an embedded CR/LF can't forge a fake log line (CWE-117). + var logSafeSubject = LogSanitizer.ForLog(subject); + TaskCompletionSource ownedReservation = null; + (DateTime ExpiresAtUtc, TaskCompletionSource Tcs) ownedEntry = default; + // Only a failure at or after the actual order-create call can mean "MarkMonitor might have + // created the order before we found out" - a network blip during an earlier step (org/contact/ + // group resolution, CSR parsing) never reached that endpoint at all, so it can never have + // created an order and must not lock out a same-second retry for the rest of the window. + var reachedCreateOrderCall = false; + try + { + await EnsureAuthenticatedAsync(); + + var now = _timeProvider.GetUtcNow().UtcDateTime; + PruneExpiredReservations(now); + if (_recentEnrollments.TryGetValue(dedupeKey, out var existing) && IsReservationStillActive(existing, now)) + { + var dedupedResult = await existing.Tcs.Task; + _logger.LogWarning( + "An identical enrollment for subject {Subject} was already submitted in the last {Minutes} minute(s) - folded into existing order {CARequestID} instead of creating a duplicate", + logSafeSubject, RecentEnrollmentWindow.TotalMinutes, dedupedResult.CARequestID); + return dedupedResult; + } + + // Reserve this key *before* doing any real work, so a retry that arrives while this + // call is still in flight (the scenario this cache actually exists to prevent) finds + // the reservation and awaits it, rather than racing to create a second order. + var candidateTcs = + new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + // AddOrUpdate, not GetOrAdd: an expired-and-completed entry must be replaced, not returned + // as-is - GetOrAdd would hand back the stale (already-completed) reservation forever once + // one exists for this key. A reservation is only replaced once BOTH its nominal window has + // elapsed AND its own call has actually finished - a still-running call that happens to run + // longer than the window must keep being awaited, not raced by a second real order. + var reserved = _recentEnrollments.AddOrUpdate( + dedupeKey, + (now + RecentEnrollmentWindow, candidateTcs), + (_, current) => IsReservationStillActive(current, now) + ? current + : (now + RecentEnrollmentWindow, candidateTcs)); + if (reserved.Tcs != candidateTcs) + { + _logger.LogWarning( + "An identical enrollment for subject {Subject} is already in flight - awaiting that result instead of creating a duplicate order", + logSafeSubject); + return await reserved.Tcs.Task; + } + + ownedReservation = candidateTcs; + ownedEntry = reserved; + + var caseInsensitiveParams = new Dictionary(productParams, StringComparer.OrdinalIgnoreCase); + + var additionalEmails = + caseInsensitiveParams.GetValueOrDefault("additionalEmails"); + var additionalEmailsList = new List(); + if (!string.IsNullOrEmpty(additionalEmails)) + { + additionalEmails = additionalEmails.Replace(" ", ","); + additionalEmailsList = additionalEmails + .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList(); + } + + var org = await ResolveOrganizationAsync(config.OrgName); + var orgIdGuid = Guid.Parse(org.Id); + + var comments = caseInsensitiveParams.GetValueOrDefault( + MarkMonitorCAPluginConfig.EnrollmentConfigConstants.Comments, "Requested via Keyfactor Command"); + _logger.LogTrace("Comments: {Comments}", LogSanitizer.ForLog(comments)); + var locale = caseInsensitiveParams.GetValueOrDefault( + MarkMonitorCAPluginConfig.EnrollmentConfigConstants.Locale, "en"); + _logger.LogTrace("Locale: {Locale}", LogSanitizer.ForLog(locale)); + var provider = caseInsensitiveParams.GetValueOrDefault( + MarkMonitorCAPluginConfig.EnrollmentConfigConstants.Provider, "DIGICERT"); + _logger.LogTrace("Provider: {Provider}", LogSanitizer.ForLog(provider)); + + _logger.LogDebug("Resolving MarkMonitor contact for order"); + var contactParam = caseInsensitiveParams.GetValueOrDefault( + MarkMonitorCAPluginConfig.EnrollmentConfigConstants.MarkmonitorContact); + var resolvedContact = ResolveContact(org?.Contacts, contactParam); + var orderContacts = resolvedContact != null + ? new List + { + new() { Id = resolvedContact.Id, ContactTypes = resolvedContact.ContactTypes } + } + : new List(); + if (resolvedContact == null) + _logger.LogWarning( + "No MarkMonitor contact could be resolved for organization {OrgName}; MarkMonitor may reject the order if a contact is required", + config.OrgName); + else + _logger.LogTrace("Resolved MarkMonitor contact: {ContactId} ({Email})", resolvedContact.Id, + resolvedContact.Email); + + _logger.LogDebug("Resolving MarkMonitor group for order"); + var groupParam = caseInsensitiveParams.GetValueOrDefault( + MarkMonitorCAPluginConfig.EnrollmentConfigConstants.MarkmonitorGroup); + var groupIdGuid = await ResolveGroupIdAsync(groupParam); + + var dcvMethod = ValidateDcvMethod(caseInsensitiveParams.GetValueOrDefault( + MarkMonitorCAPluginConfig.EnrollmentConfigConstants.DCVMethod, + DomainControlValidationMethods.Email.GetDescription())); + + // Lookup order type in CertOrderTypes enum. Enum.Parse alone would silently "succeed" for + // any numeric string that fits the underlying int type even with no member actually + // defined for that value (e.g. "20" for a 12-member enum) - Enum.IsDefined enforces + // membership, matching the same check ValidateProductInfo already applies at template-save + // time (this is the same gap, at the point it would otherwise be discovered). + _logger.LogDebug("Looking up order type {OrderType} in CertOrderTypes enum", orderType); + var certOrderType = Enum.Parse(orderType); + if (!Enum.IsDefined(typeof(CertOrderTypes), certOrderType)) + throw new ArgumentException( + $"'{LogSanitizer.ForLog(orderType)}' is not a valid MarkMonitor product ID"); + + _logger.LogDebug("Deserializing CSR"); + var csrObject = new Pkcs10CertificationRequest(GetCsrBytes(csr)); + var csrInfo = csrObject.GetCertificationRequestInfo(); + ValidateEccCsrUsesNamedCurve(csrInfo.SubjectPublicKeyInfo); + + _logger.LogDebug("Determining CSR algorithm"); + var requestAlgorithm = getCsrAlgorithm(csrObject); + _logger.LogTrace("CSR algorithm: {RequestAlgorithm}", requestAlgorithm); + + _logger.LogDebug("Converting CSR to PEM"); + var csrPem = PemUtilities.DERToPEM(csrObject.GetEncoded(), PemUtilities.PemObjectType.CertRequest); + + var commonName = cleanSubject(subject); + var dnsNames = BuildDnsNames(csrObject, commonName, san); + + _logger.LogDebug("Constructing certificate order object"); + var certOrder = new MarkMonitorCreateOrderRequest + { + AdditionalEmails = additionalEmailsList, + SkipPrice = true, + OrganizationId = orgIdGuid, + GroupId = groupIdGuid, + Contacts = orderContacts, + Comments = comments, + CertType = certOrderType.GetDescription(), + Locale = locale, + Provider = provider, + Cert = new MarkMonitorOrderRequestCert + { + CommonName = commonName, + DnsNames = dnsNames, + Csr = csrPem.Replace("\r", ""), + DcvMethod = dcvMethod, + // dcvEmails is not marked required by MarkMonitor's schema, and leaving it empty + // has been verified against the live API to succeed for DCVMethod=EMAIL - + // MarkMonitor falls back to the domain/org's registered DCV contacts. Revisit if + // that ever changes; there's no documented case where an explicit approver email + // is actually required here. + DcvEmails = new List(), + AlgorithmHash = requestAlgorithm + } + }; + + + _logger.LogDebug("Calling CreateCertificateOrder"); + // Force any needed re-authentication here, BEFORE reachedCreateOrderCall is set. + // CreateCertificateOrder performs its own EnsureAuthenticatedAsync check internally (every + // MarkMonitorClient method does), and if the token happened to expire again during the + // org/contact/group resolution above, a failure in THAT nested re-auth call must not be + // treated as ambiguous - the order-create POST itself was never reached - but + // reachedCreateOrderCall wouldn't otherwise distinguish that from a failure during the + // POST. Doing the check here first means CreateCertificateOrder's own check is always a + // no-op immediately afterward. + await EnsureAuthenticatedAsync(); + reachedCreateOrderCall = true; + var order = await CreateCertificateOrder(certOrder); + + if (order == null) throw new Exception($"Failed to enroll certificate `{logSafeSubject}` with MarkMonitor"); + + _logger.LogInformation("Certificate enrolled successfully"); + _logger.LogInformation( + "Order {CARequestID} was created with ContactId {ContactId} and GroupId {GroupId}", order.Id, + resolvedContact?.Id, groupIdGuid); + + // Polling happens here, before the reservation resolves, so a concurrent duplicate call + // that's folded into this reservation (the dedup-hit path above) gets the polled result + // too, rather than always seeing the original pending status. + order = await PollForIssuanceAsync(order, config); + + var certificate = order.Cert?.EndEntityCert; + var status = MarkMonitorCertificateStatusToCAStatus(order); + if (status == (int)EndEntityStatus.GENERATED && certificate == null) + { + // MarkMonitor's status can flip to issued a moment before the cert body itself is + // populated - PollForIssuanceAsync's own IsPollingComplete check already accounts for + // this (it requires both), but if the poll budget is exhausted at exactly that + // moment, the order comes back here with an "issued" status and no cert. Reporting + // GENERATED with a null Certificate would be an internally inconsistent result no + // caller expects for a successful enrollment - INPROCESS (the same status used for + // every other pending state) is the honest signal that there's nothing to deliver yet. + _logger.LogWarning( + "Order {CARequestID} reports status {OrderStatus} (maps to GENERATED) but its certificate body is not yet populated - reporting INPROCESS instead of a false GENERATED", + order.Id, order.Status); + status = (int)EndEntityStatus.INPROCESS; + } + + var enrollmentResult = new EnrollmentResult + { + CARequestID = order.Id, + Certificate = certificate, + Status = status, + StatusMessage = "MarkMonitor order status: " + order.Status + }; + ownedReservation.SetResult(enrollmentResult); + return enrollmentResult; + } + catch (Exception e) + { + _logger.LogError("An error has occurred: {EMessage}", e.Message); + if (ownedReservation != null) + { + ownedReservation.SetException(e); + + // A transport-level failure (timeout, dropped connection) DURING the order-create call + // itself means we genuinely don't know whether MarkMonitor actually created the order + // before the failure - exactly the ambiguous case this cache exists to guard against + // (see the class-level comment). Don't evict the reservation for that case: keep it in + // _recentEnrollments so a Command retry within the window is folded into this (now- + // faulted) reservation instead of racing ahead to create a second real order. The same + // exception types raised by an EARLIER step (org/contact/group resolution, CSR parsing) + // are NOT ambiguous - reachedCreateOrderCall gates on that, since those steps never + // reach MarkMonitor's create-order endpoint and so can never have created an order; a + // retry after one of those must get a fresh attempt immediately, not be locked out for + // the rest of the window by an unrelated transient blip. Conditional Remove, not a bare + // key-based one: if this reservation's own window already expired while this call was + // still running, a different caller may have since won a fresh reservation for the same + // key - an unconditional remove would delete THEIR entry instead of (the no-longer- + // present) one this call owned. + // MarkMonitorOrderCreatedButUnparsableException means MarkMonitor already confirmed + // (2xx) the order was created - stronger than merely ambiguous - so it must never be + // treated as safe to evict either. + var isAmbiguousOutcome = reachedCreateOrderCall && + e is HttpRequestException or TaskCanceledException or MarkMonitorOrderCreatedButUnparsableException; + if (isAmbiguousOutcome) + _logger.LogWarning( + "Enrollment for subject {Subject} failed with an ambiguous network-level error - keeping the retry-dedup reservation active for the rest of the window so a retry doesn't risk creating a duplicate MarkMonitor order", + logSafeSubject); + else + TryRemoveReservation(dedupeKey, ownedEntry); + } + + throw; + } + finally + { + _logger.MethodExit(); + } + } + + private async Task ResolveOrganizationAsync(string orgNameOrId) + { + MarkMonitorOrganizationResponse org; + if (Guid.TryParse(orgNameOrId, out _)) + { + _logger.LogDebug("OrgId '{OrgName}' looks like a GUID - fetching the organization directly", + orgNameOrId); + org = await GetOrganizationAsync(orgNameOrId); + } + else + { + var orgs = await ListOrganizationsAsync(0, NameResolutionPageSize, orgNameOrId); + _logger.LogTrace("Organizations found: {@Orgs}", orgs); + // ListOrganizationsAsync throws rather than returning null on error, so orgs is never + // null here - just possibly empty. MarkMonitor's own name filter may do substring/fuzzy + // matching rather than exact matching, so filter to an exact (case-insensitive) name + // match ourselves rather than trusting the first result - otherwise a configured name + // that's a substring of another org's name (e.g. "Acme" vs "Acme Corp Europe") could + // silently resolve to the wrong organization. + org = orgs.FirstOrDefault(o => string.Equals(o.Name, orgNameOrId, StringComparison.OrdinalIgnoreCase)); + } + + _logger.LogTrace("Organization ID: {OrgId}", org?.Id); + if (string.IsNullOrEmpty(org?.Id)) + { + _logger.LogError("Organization ID not found for {OrgName}", orgNameOrId); + throw new InvalidDataException($"Organization ID '{orgNameOrId}' not found"); + } + + return org; + } + + // Unlike contacts (scoped to an organization's own Contacts list), group resolution can't be + // scoped to the configured organization: MarkMonitor's Auth API models groups as + // account/tenant-wide - /auth/v1/group has no organizationId filter, and the Group schema it + // returns (id/name/description/dateCreated/dateUpdated) has no organizationId field to check + // against either. There is nothing in this API to scope against, so a group name/GUID that + // resolves at all is accepted as-is; matching is by exact (case-insensitive) name rather than a + // substring, which is the closest available mitigation. + private async Task ResolveGroupIdAsync(string groupParam) + { + if (string.IsNullOrWhiteSpace(groupParam)) return null; + + if (Guid.TryParse(groupParam, out var parsedGroupId)) return parsedGroupId; + + if (_resolvedGroupIdByName.TryGetValue(groupParam, out var cachedGroupId)) return cachedGroupId; + + var groups = await ListGroupsAsync(0, NameResolutionPageSize, groupParam); + var matchedGroup = groups?.FirstOrDefault(g => + string.Equals(g.Name, groupParam, StringComparison.OrdinalIgnoreCase)); + if (matchedGroup != null) + { + var resolvedGroupId = Guid.Parse(matchedGroup.Id); + _resolvedGroupIdByName[groupParam] = resolvedGroupId; + return resolvedGroupId; + } + + _logger.LogWarning("MarkMonitor group '{GroupParam}' could not be resolved to an ID", + LogSanitizer.ForLog(groupParam)); + return null; + } + + private string ValidateDcvMethod(string dcvMethod) + { + var validDcvMethods = Enum.GetValues() + .Select(m => m.GetDescription()).ToList(); + if (validDcvMethods.Contains(dcvMethod, StringComparer.OrdinalIgnoreCase)) return dcvMethod; + + _logger.LogWarning("Invalid DCVMethod '{DcvMethod}' specified, defaulting to EMAIL", + LogSanitizer.ForLog(dcvMethod)); + return DomainControlValidationMethods.Email.GetDescription(); + } + + private MarkMonitorGetContactResponse ResolveContact(List contacts, + string contactParam) + { + if (contacts == null || contacts.Count == 0) return null; + + if (!string.IsNullOrWhiteSpace(contactParam)) + { + if (Guid.TryParse(contactParam, out var contactGuid)) + { + var byId = contacts.FirstOrDefault(c => c.Id == contactGuid); + if (byId != null) return byId; + } + + var byEmail = + contacts.FirstOrDefault(c => string.Equals(c.Email, contactParam, StringComparison.OrdinalIgnoreCase)); + if (byEmail != null) return byEmail; + + var byName = contacts.FirstOrDefault(c => + string.Equals($"{c.FirstName} {c.LastName}", contactParam, StringComparison.OrdinalIgnoreCase)); + if (byName != null) return byName; + + _logger.LogWarning( + "MarkMonitor contact '{ContactParam}' could not be resolved; falling back to the default organization contact", + LogSanitizer.ForLog(contactParam)); + } + + return contacts.FirstOrDefault(c => + c.ContactTypes != null && c.ContactTypes.Any(t => + string.Equals(t.Type, "ORGANIZATION_CONTACT", StringComparison.OrdinalIgnoreCase))) + ?? contacts.FirstOrDefault(); + } + + /// + /// MarkMonitor's API does not use the submitted CSR to determine a certificate's issued SAN + /// list - real captured orders (and DigiCert's own docs, MarkMonitor's sole provider) show the + /// issued SANs are the union of the order's commonName and its own dnsNames field. + /// A CSR's SAN extension is ignored server-side unless those same names are also placed in + /// dnsNames here - so the Command-supplied dictionary is the + /// primary source. A SAN extension embedded in itself is used only + /// as a fallback when is null - Command never populated SAN data + /// at all for this request - and never when it's non-null, even empty: a non-null dictionary + /// means Command's own enrollment pattern/template ran and is the authoritative source for this + /// request, and a raw CSR-embedded SAN extension (subscriber-generated, outside Command's own + /// policy/RA control) must not override or supplement it. certinext-caplugin's own history has + /// the identical unconditional-union pattern deliberately reverted for this exact reason - a + /// subscriber's own CSR can carry more names than an enrollment pattern actually authorized. + /// Non-DNS SAN types (IP/email/URI) have no field in MarkMonitor's order schema and are dropped + /// with a logged warning rather than failing the enrollment. + /// + private List BuildDnsNames(Pkcs10CertificationRequest csrObject, string commonName, + Dictionary san) + { + var dnsNames = new List(); + + if (san != null) + { + var droppedTypes = new List(); + foreach (var entry in san) + { + if (entry.Value == null) continue; + + // Command's SAN type keys (e.g. "Dns"/"dnsname") vary in casing across gateways - + // matched case-insensitively, mirroring digicert-certcentral-caplugin's own + // defensive handling of the same ambiguity. + if (string.Equals(entry.Key, "dns", StringComparison.OrdinalIgnoreCase) || + string.Equals(entry.Key, "dnsname", StringComparison.OrdinalIgnoreCase)) + dnsNames.AddRange(entry.Value.Where(v => !string.IsNullOrWhiteSpace(v))); + else if (entry.Value.Length > 0) + droppedTypes.Add(entry.Key); + } + + if (droppedTypes.Count > 0) + _logger.LogWarning( + "MarkMonitor's order schema has no field for non-DNS SAN type(s) {DroppedSanTypes} - they were requested but will not be included on this order", + LogSanitizer.ForLog(string.Join(", ", droppedTypes))); + } + else + { + var requestedExtensions = csrObject.GetRequestedExtensions(); + var sanExtension = requestedExtensions?.GetExtension(X509Extensions.SubjectAlternativeName); + if (sanExtension != null) + { + var generalNames = GeneralNames.GetInstance(sanExtension.GetParsedValue()); + dnsNames.AddRange(generalNames.GetNames() + .Where(name => name.TagNo == GeneralName.DnsName) + .Select(name => name.Name.ToString())); + } + } + + // The CN is submitted separately as Cert.CommonName, and MarkMonitor issues CN ∪ dnsNames - + // repeating it in dnsNames would be redundant, so it's excluded here to keep the request + // minimal. + var distinctDnsNames = dnsNames + .Where(name => !string.IsNullOrWhiteSpace(name) && + !string.Equals(name, commonName, StringComparison.OrdinalIgnoreCase)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + return distinctDnsNames.Count > 0 ? distinctDnsNames : null; + } + + private string cleanSubject(string subject) + { + _logger.MethodEntry(); + try + { + if (string.IsNullOrWhiteSpace(subject)) return subject; + + try + { + var cnValues = new X509Name(subject).GetValueList(X509Name.CN); + if (cnValues.Count > 0) return (string)cnValues[cnValues.Count - 1]; + } + catch (Exception e) + { + _logger.LogDebug( + "Could not parse subject '{Subject}' as an X509 DN, falling back to string search: {EMessage}", + LogSanitizer.ForLog(subject), e.Message); + } + + // Fallback for a subject that isn't a fully valid DN (e.g. bare "CN=foo" with no other RDNs). + var cnPrefix = "CN="; + var cnIndex = subject.IndexOf(cnPrefix, StringComparison.OrdinalIgnoreCase); + if (cnIndex < 0) return subject; + var cnStart = cnIndex + cnPrefix.Length; + var cnEnd = subject.IndexOf(",", cnStart, StringComparison.Ordinal); + if (cnEnd < 0) cnEnd = subject.Length; + return subject.Substring(cnStart, cnEnd - cnStart); + } + finally + { + _logger.MethodExit(); + } + } + + private void logCreateOrderRequest(MarkMonitorCreateOrderRequest request) + { + _logger.MethodEntry(); + _logger.LogTrace("CommonName: {CommonName}", LogSanitizer.ForLog(request.Cert.CommonName)); + _logger.LogTrace("DnsNames: {DnsNames}", + LogSanitizer.ForLog(request.Cert.DnsNames != null ? string.Join(",", request.Cert.DnsNames) : null)); + _logger.LogTrace("OrganizationId: {OrganizationId}", request.OrganizationId); + _logger.LogTrace("GroupId: {GroupId}", request.GroupId); + _logger.LogTrace("CertType: {CertType}", request.CertType); + _logger.LogTrace("Locale: {Locale}", LogSanitizer.ForLog(request.Locale)); + _logger.LogTrace("Provider: {Provider}", LogSanitizer.ForLog(request.Provider)); + _logger.LogTrace("Comments: {Comments}", LogSanitizer.ForLog(request.Comments)); + // Deliberately not logging AdditionalEmails (requester PII) or the CSR/full Cert object - + // just enough to confirm the shape of the request without leaking their content. + _logger.LogTrace("AdditionalEmails count: {AdditionalEmailsCount}", request.AdditionalEmails?.Count ?? 0); + _logger.LogTrace("SkipPrice: {SkipPrice}", request.SkipPrice); + _logger.LogTrace("DcvMethod: {DcvMethod}", LogSanitizer.ForLog(request.Cert.DcvMethod)); + _logger.MethodExit(); + } + + public async Task CreateCertificateOrder(MarkMonitorCreateOrderRequest request) + { + _logger.MethodEntry(); + try + { + await EnsureAuthenticatedAsync(); + logCreateOrderRequest(request); + + var url = $"{BaseUrl}/certs/v1/order"; + _logger.LogDebug("Creating certificate order at {Url}", url); + var jsonPayload = new StringContent( + JsonConvert.SerializeObject(request), + Encoding.UTF8, "application/json" + ); + // Deliberately SendAndLogAsync, NOT SendWithRetryAsync: a transport-level failure here + // means MarkMonitor may have already created the order before we found out - retrying + // this specific call would risk creating a second, real, billable order. That ambiguity + // is instead handled one level up, by EnrollCertificateAsync's dedup reservation staying + // active so a caller-level retry folds into this same attempt's result. + var response = await SendAndLogAsync(() => _httpClient.PostAsync(url, jsonPayload), "POST", url); + _logger.LogTrace("Response: {Response}", response); + + _logger.LogDebug("Reading response content"); + var content = await response.Content.ReadAsStringAsync(); + _logger.LogTrace("Response content: {Content}", content); + if (response.IsSuccessStatusCode) + { + OrderContent order; + try + { + order = JsonConvert.DeserializeObject(content); + } + catch (Exception parseException) + { + // MarkMonitor already returned a success status here - the order was definitely + // created, even though its response body didn't parse - so this must be treated + // as at least as ambiguous as a network-level failure (EnrollCertificateAsync's + // isAmbiguousOutcome check matches on this type), not as a definite non-creation + // that's safe to let a retry create a genuine duplicate order for. + throw new MarkMonitorOrderCreatedButUnparsableException( + "MarkMonitor returned a successful response for order creation, but its body could not be parsed", + parseException); + } + + if (order == null) + // An empty body or a literal "null" both deserialize to null without throwing - + // same "MarkMonitor confirmed creation, but we can't read the result" situation as + // the catch above, just without an exception to wrap. Must not fall through to + // order.Id below, which would throw a plain NullReferenceException that + // EnrollCertificateAsync's isAmbiguousOutcome check doesn't recognize as ambiguous. + throw new MarkMonitorOrderCreatedButUnparsableException( + "MarkMonitor returned a successful response for order creation, but its body was empty or null", + null); + + _logger.LogInformation("Certificate order {OrderId} created", order.Id); + return order; + } + + var errMsg = BuildErrorString(content); + _logger.LogError("An error has occurred while attempting to create order: {EMessage}", errMsg); + throw new Exception(errMsg); + } + catch (Exception e) + { + _logger.LogError("An error has occurred while attempting to create order: {EMessage}", e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + public async Task CancelCertificateAsync(string orderId, string orgName = null) + { + _logger.MethodEntry(); + try + { + ValidateGuidFormat(orderId, nameof(orderId), "MarkMonitor order ID"); + // orderId is caller-supplied - log a CR/LF-escaped copy so an embedded CR/LF can't forge a + // fake log line (CWE-117). ValidateGuidFormat above already guarantees it's GUID-shaped + // for normal (non-exceptional) calls, but its own exception message is sanitized too, so + // this covers the exceptional path as well. + var logSafeOrderId = LogSanitizer.ForLog(orderId); + _logger.LogInformation("Cancelling certificate {CertificateId}", logSafeOrderId); + + var (success, errMsg) = + await PatchOrderActionAsync(orderId, orgName, "Cancelling", "cancel"); + if (success) + { + _logger.LogInformation("Certificate {CertificateId} has been cancelled", logSafeOrderId); + return true; + } + + _logger.LogError("An error has occurred while attempting to cancel order {CertificateId}: {EMessage}", + logSafeOrderId, errMsg); + throw new Exception(errMsg); + } + catch (Exception e) + { + _logger.LogError("An error has occurred while attempting to cancel {CertificateId}: {EMessage}", + LogSanitizer.ForLog(orderId), e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + // Unlike order-create/reissue, retrying a cancel or revoke is safe - acting on an already- + // cancelled/revoked order is a no-op, not a second billable resource. Shared by + // CancelCertificateAsync and RevokeCertificateAsync, which differ only in log wording handled by + // each caller. + private async Task<(bool success, string errMsg)> PatchOrderActionAsync(string orderId, string orgName, + string ownershipGerund, string action) + { + await EnsureAuthenticatedAsync(); + + await EnsureOrderBelongsToOrganizationAsync(orderId, orgName, ownershipGerund, action); + + var url = $"{BaseUrl}/certs/v1/order/{orderId}/{action}"; + _logger.LogDebug("{Gerund} certificate at {Url}", ownershipGerund, url); + var payload = new StringContent("{}", Encoding.UTF8, "application/json"); + var response = await SendWithRetryAsync(() => _httpClient.PatchAsync(url, payload), "PATCH", url); + + _logger.LogDebug("Reading response content"); + var content = await response.Content.ReadAsStringAsync(); + return response.IsSuccessStatusCode ? (true, null) : (false, BuildErrorString(content)); + } + + public async Task ReissueCertificateAsync(string orderId, MarkMonitorReissueRequest payload) + { + _logger.MethodEntry(); + try + { + ValidateGuidFormat(orderId, nameof(orderId), "MarkMonitor order ID"); + // orderId is caller-supplied - log a CR/LF-escaped copy so an embedded CR/LF can't forge a + // fake log line (CWE-117). + var logSafeOrderId = LogSanitizer.ForLog(orderId); + _logger.LogInformation("Revoking certificate {CertificateId}", logSafeOrderId); + await EnsureAuthenticatedAsync(); + + var url = $"{BaseUrl}/certs/v1/order/{orderId}/reissue"; + _logger.LogDebug("Reissuing certificate at {Url}", url); + //convert payload to json + var jsonPayload = new StringContent( + JsonConvert.SerializeObject(payload), + Encoding.UTF8, "application/json" + ); + _logger.LogTrace("Reissue payload: {@Payload}", jsonPayload); + // Deliberately not retried, same reasoning as CreateCertificateOrder's order-create POST: + // reissue produces a new certificate, so a transport-level failure here is ambiguous + // about whether MarkMonitor already reissued before we found out. + var response = await SendAndLogAsync(() => _httpClient.PatchAsync(url, jsonPayload), "PATCH", url); + + _logger.LogDebug("Reading response content"); + var content = await response.Content.ReadAsStringAsync(); + if (response.IsSuccessStatusCode) + { + _logger.LogInformation("Certificate {CertificateId} has been reissued", logSafeOrderId); + return true; + } + + var errMsg = BuildErrorString(content); + _logger.LogError("An error has occurred while attempting to reissue {CertificateId}: {EMessage}", + logSafeOrderId, errMsg); + throw new Exception(errMsg); + } + catch (Exception e) + { + _logger.LogError("An error has occurred while attempting to reissue {CertificateId}: {EMessage}", + LogSanitizer.ForLog(orderId), e.Message); + throw; + } + } + + /// + /// Revokes the certificate for the given order. MarkMonitor's revoke action (PATCH + /// /certs/v1/order/{id}/revoke) has no field for a revocation reason code - its request schema + /// only accepts cert/ignoreOrgCheck/additionalEmails - so the parameter + /// cannot be sent to MarkMonitor. It's accepted (rather than removed) to match + /// IAnyCAPlugin.Revoke's signature; a non-default value is logged so it's visible that the + /// reason was received but couldn't be forwarded, rather than silently dropped. + /// + public async Task RevokeCertificateAsync(string orderId, string orgName = null, uint reason = 0) + { + _logger.MethodEntry(); + try + { + ValidateGuidFormat(orderId, nameof(orderId), "MarkMonitor order ID"); + // orderId is caller-supplied - log a CR/LF-escaped copy so an embedded CR/LF can't forge a + // fake log line (CWE-117). + var logSafeOrderId = LogSanitizer.ForLog(orderId); + _logger.LogInformation("Revoking certificate associated with order {OrderId}", logSafeOrderId); + if (reason != 0) + _logger.LogWarning( + "Revocation reason {Reason} was requested for order {OrderId}, but MarkMonitor's revoke API has no field for a reason code - it will not be sent", + reason, logSafeOrderId); + + var (success, errMsg) = + await PatchOrderActionAsync(orderId, orgName, "Revoking", "revoke"); + if (success) + { + _logger.LogInformation("Certificate {CertificateId} has been revoked", logSafeOrderId); + return true; + } + + _logger.LogError("An error has occurred while attempting to revoke {CertificateId}: {EMessage}", + logSafeOrderId, errMsg); + throw new Exception(errMsg); + } + catch (Exception e) + { + _logger.LogError("An error has occurred while attempting to revoke {CertificateId}: {EMessage}", + LogSanitizer.ForLog(orderId), e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + private bool TokenNeedsRefresh() => + string.IsNullOrEmpty(_bearerToken) || _tokenExpiresAtUtc == null || + _timeProvider.GetUtcNow().UtcDateTime >= _tokenExpiresAtUtc; + + private async Task EnsureAuthenticatedAsync() + { + // Double-checked locking: without the lock, two callers can both see an expired token, + // both call AuthenticateAsync concurrently, and race writing _bearerToken/_tokenExpiresAtUtc + // and the shared HttpClient's Authorization header - one of them can end up sending requests + // under the other's (or a half-written) token. + if (!TokenNeedsRefresh()) return; + + await _authLock.WaitAsync(); + try + { + if (TokenNeedsRefresh()) + { + _logger.LogDebug("No valid bearer token on hand - authenticating"); + await AuthenticateAsync(); + } + else + { + _logger.LogDebug("Bearer token was refreshed by a concurrent caller while waiting on the auth lock - reusing it"); + } + } + finally + { + _authLock.Release(); + } + } + + /// Runs an HTTP call and logs its method/URL/status code/elapsed time - none of this + /// class's call sites otherwise captured that response metadata (only AuthenticateAsync logged a + /// status code, and only at Trace), leaving no basis in this component's own logs for latency- or + /// status-code-based anomaly detection or vendor API call forensic reconstruction. + private async Task SendAndLogAsync(Func> send, string method, + string url) + { + var stopwatch = Stopwatch.StartNew(); + try + { + var response = await send(); + stopwatch.Stop(); + _logger.LogInformation("{Method} {Url} -> {StatusCode} ({ElapsedMs}ms)", method, url, + (int)response.StatusCode, stopwatch.ElapsedMilliseconds); + return response; + } + catch (Exception e) + { + // A transport-level failure (timeout, DNS failure, connection refused/reset, TLS failure) + // never produces a response at all, so the success path's own log line above never runs - + // log the method/URL/elapsed-time here too, so every one of this helper's call sites gets + // that context on failure as well, not just success. + stopwatch.Stop(); + _logger.LogError("{Method} {Url} -> failed after {ElapsedMs}ms: {EMessage}", method, url, + stopwatch.ElapsedMilliseconds, e.Message); + throw; + } + } + + /// + /// Wraps with up to attempts: + /// retries a network-level/timeout failure or an HTTP 5xx/429 response, with exponential + /// backoff (±25% jitter), honoring a 429 response's Retry-After header when present. Any other + /// 4xx is returned immediately without retrying - that's this component's own bad request, not + /// a transient failure retrying could fix. Must NOT be used for CreateCertificateOrder's + /// order-create POST (see this class's constant-level comment on why). + /// + private async Task SendWithRetryAsync(Func> send, string method, + string url, CancellationToken cancelToken = default) + { + for (var attempt = 1; ; attempt++) + { + HttpResponseMessage response; + try + { + response = await SendAndLogAsync(send, method, url); + } + catch (Exception e) when (e is HttpRequestException or TaskCanceledException && + attempt < MaxRetryAttempts) + { + var delay = ComputeRetryDelay(attempt); + _logger.LogWarning( + "{Method} {Url} failed on attempt {Attempt}/{MaxAttempts} ({EMessage}) - retrying in {DelayMs}ms", + method, url, attempt, MaxRetryAttempts, e.Message, delay.TotalMilliseconds); + await _delay(delay, cancelToken); + continue; + } + + if (response.IsSuccessStatusCode) return response; + + var statusCode = (int)response.StatusCode; + var isRetryableStatus = statusCode == 429 || statusCode >= 500; + if (!isRetryableStatus || attempt >= MaxRetryAttempts) return response; + + var retryDelay = statusCode == 429 + ? GetRetryAfterDelay(response) ?? ComputeRetryDelay(attempt) + : ComputeRetryDelay(attempt); + _logger.LogWarning( + "{Method} {Url} returned {StatusCode} on attempt {Attempt}/{MaxAttempts} - retrying in {DelayMs}ms", + method, url, statusCode, attempt, MaxRetryAttempts, retryDelay.TotalMilliseconds); + // Deliberately not disposing the discarded response here - no other call site in this + // class disposes an HttpResponseMessage either (see e.g. AuthenticateAsync/ + // ListOrganizationsAsync), so this stays consistent with that existing convention. + await _delay(retryDelay, cancelToken); + } + } + + private TimeSpan ComputeRetryDelay(int attempt) + { + var exponential = RetryBaseDelay * Math.Pow(2, attempt - 1); + // ±25% jitter so multiple retrying callers don't all wake up and retry in lockstep. + var jitterFactor = 0.75 + _retryJitter.NextDouble() * 0.5; + return exponential * jitterFactor; + } + + private TimeSpan? GetRetryAfterDelay(HttpResponseMessage response) + { + var retryAfter = response.Headers.RetryAfter; + if (retryAfter == null) return null; + + TimeSpan? delay = null; + if (retryAfter.Delta != null) delay = retryAfter.Delta; + else if (retryAfter.Date != null) + { + var delta = retryAfter.Date.Value - _timeProvider.GetUtcNow(); + delay = delta > TimeSpan.Zero ? delta : TimeSpan.Zero; + } + + if (delay == null) return null; + return TimeSpan.FromSeconds(Math.Min(delay.Value.TotalSeconds, MaxRetryAfterSeconds)); + } + + private static string BuildErrorString(string jsonString) + { + var json = JObject.Parse(jsonString); + var errorMessages = new List(); + + // Every value pulled out of MarkMonitor's response below is sanitized before it's woven into + // errorMessages - a validation API quoting back the offending value is a common pattern, and + // this component's own request could easily be why: e.g. a CSR-derived CommonName/SAN entry + // with an embedded CR/LF (CSR ASN.1 encoding doesn't prevent that). Without this, that CR/LF + // would forge a log entry (CWE-117) via BuildErrorString's result, despite the sanitization + // already applied everywhere else a requester-influenceable string reaches this component's + // logs. Sanitizing each value here - not the joined result - preserves the intentional + // Environment.NewLine separators between distinct errors below. + // MarkMonitor 400 responses: {"validations":[{"field":"cert.csr","code":"...","message":"..."}]} + if (json["validations"] is JArray validations) + foreach (var validation in validations) + { + var field = LogSanitizer.ForLog(validation["field"]?.ToString()); + var code = LogSanitizer.ForLog(validation["code"]?.ToString()); + var message = LogSanitizer.ForLog(validation["message"]?.ToString()); + errorMessages.Add($"{field}: {message} ({code})"); + } + // MarkMonitor 500 responses: {"errors":[{"code":"...","message":"..."}]} + else if (json["errors"] is JArray errors) + foreach (var error in errors) + { + var code = LogSanitizer.ForLog(error["code"]?.ToString()); + var message = LogSanitizer.ForLog(error["message"]?.ToString()); + errorMessages.Add($"{message} ({code})"); + } + else if (json["validation_messages"] != null) + foreach (var validationMessage in json["validation_messages"]) + { + var field = LogSanitizer.ForLog(validationMessage.Path); + var fieldErrors = (JObject)validationMessage.First; + + foreach (var error in fieldErrors) + { + var errorMessage = LogSanitizer.ForLog(error.Value.ToString()); + errorMessages.Add($"{field}: {errorMessage}"); + + if (error.Key == "options") + { + var options = string.Join(", ", + error.Value.ToObject>().Select(LogSanitizer.ForLog)); + errorMessages.Add($"{field} options: {options}"); + } + } + } + else if (json["detail"] != null) + errorMessages.Add(LogSanitizer.ForLog(json["detail"].ToString())); + + if (errorMessages.Any()) return string.Join(Environment.NewLine, errorMessages); + + // Unrecognized shape - order/contact payloads can carry customer PII (name, email), so + // truncate rather than dumping the full response body verbatim into an error-level log. + const int maxLength = 200; + var truncated = jsonString.Length > maxLength ? jsonString[..maxLength] + "... (truncated)" : jsonString; + return $"No recognized error format found in response: {LogSanitizer.ForLog(truncated)}"; + } + + private byte[] GetCsrBytes(string csr) + { + _logger.MethodEntry(); + try + { + _logger.LogDebug("Attempting to decode CSR string"); + // Try to decode the string from Base64 + return Convert.FromBase64String(csr); + } + catch (FormatException) + { + _logger.LogDebug("Decoding failed, assuming PEM format"); + // If decoding fails, assume the string is in PEM format + var pem = csr.Replace("-----BEGIN CERTIFICATE REQUEST-----", "") + .Replace("-----END CERTIFICATE REQUEST-----", "") + .Replace("\n", "") + .Replace("\r", "") + .Trim(); + return Convert.FromBase64String(pem); + } + finally + { + _logger.MethodExit(); + } + } + + private int MarkMonitorCertificateStatusToCAStatus(OrderContent order) + { + _logger.MethodEntry(); + if (order == null || string.IsNullOrEmpty(order.Status)) + { + _logger.LogError("MarkMonitor order is null or status is empty"); + return (int)EndEntityStatus.FAILED; + } + + + _logger.LogDebug("MarkMonitor order {OrderId} status: {OrderStatus}", order.Id, order.Status); + if ( + order.Status.Equals(OrderStatus.DigiPending.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiProcessing.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiReissuePending.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiWaitingPickup.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.ReissuePending.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiNeedsApproval.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.ReissueRequestPending.GetDescription(), StringComparison.OrdinalIgnoreCase) + ) + { + _logger.LogInformation("MarkMonitor order {OrderId} status 'IN PROCESS'", order.Id); + _logger.LogInformation( + "MarkMonitor order {OrderId} may still be in process and/or require manual intervention", order.Id); + return (int)EndEntityStatus.INPROCESS; + } + + if ( + order.Status.Equals(OrderStatus.DigiRevoked.GetDescription(), StringComparison.OrdinalIgnoreCase) + ) + { + _logger.LogInformation("MarkMonitor order {OrderId} status 'REVOKED'", order.Id); + _logger.MethodExit(); + return (int)EndEntityStatus.REVOKED; + } + + + if (order.Status.Equals(OrderStatus.DigiIssued.GetDescription(), StringComparison.OrdinalIgnoreCase)) + { + _logger.LogInformation("MarkMonitor order {OrderId} status 'GENERATED'", order.Id); + _logger.MethodExit(); + return (int)EndEntityStatus.GENERATED; + } + + + if ( + order.Status.Equals(OrderStatus.DigiFailed.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiReissueFailed.GetDescription(), StringComparison.OrdinalIgnoreCase) + ) + { + _logger.LogError("MarkMonitor order {OrderId} status 'FAILED'", order.Id); + _logger.MethodExit(); + return (int)EndEntityStatus.FAILED; + } + + + if ( + order.Status.Equals(OrderStatus.DigiCanceled.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiRejected.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiExpired.GetDescription(), StringComparison.OrdinalIgnoreCase) || + order.Status.Equals(OrderStatus.DigiNeedsCsr.GetDescription(), StringComparison.OrdinalIgnoreCase) + ) + { + _logger.LogInformation("MarkMonitor order {OrderId} status 'CANCELLED'", order.Id); + _logger.MethodExit(); + return (int)EndEntityStatus.CANCELLED; + } + + + if ( + order.Status.Equals(OrderStatus.Created.GetDescription(), StringComparison.OrdinalIgnoreCase) + ) + { + // EndEntityStatus.INITIALIZED is not what the AnyGatewayREST framework treats as + // "accepted, still pending" - that's EXTERNALVALIDATION. Returning INITIALIZED here + // caused the gateway to report a hard enrollment failure for an order that had, in + // fact, been created successfully at MarkMonitor and was simply awaiting DCV/issuance + // (confirmed against a real AnyGatewayREST + Command deployment - github issue #2). + _logger.LogInformation("MarkMonitor order {OrderId} status 'CREATED' - pending external validation", + order.Id); + _logger.MethodExit(); + return (int)EndEntityStatus.EXTERNALVALIDATION; + } + + _logger.LogError("MarkMonitor order {OrderId} status could not be dettermined defaulting to 'FAILED'", + order.Id); + _logger.MethodExit(); + return (int)EndEntityStatus.FAILED; + } +} + +public class ConfigurationValidationException : Exception +{ + public ConfigurationValidationException() + { + } + + public ConfigurationValidationException(string message) + : base(message) + { + } + + public ConfigurationValidationException(string message, Exception innerException) + : base(message, innerException) + { + } +} + +/// Thrown when MarkMonitor's order-create response indicates success (2xx) but its body +/// can't be parsed - the order was definitely created despite the failure, so EnrollCertificateAsync +/// must treat this the same as an ambiguous network-level failure, not as a definite non-creation +/// that's safe to let a retry duplicate. +public class MarkMonitorOrderCreatedButUnparsableException : Exception +{ + public MarkMonitorOrderCreatedButUnparsableException(string message, Exception innerException) + : base(message, innerException) + { + } +} \ No newline at end of file diff --git a/markmonitor-caplugin/LogSanitizer.cs b/markmonitor-caplugin/LogSanitizer.cs new file mode 100644 index 0000000..0cc249f --- /dev/null +++ b/markmonitor-caplugin/LogSanitizer.cs @@ -0,0 +1,13 @@ +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; + +/// +/// Escapes CR/LF out of a value before it's interpolated into a log message. Subject/CN (and other +/// CSR-derived fields) are fully controlled by the certificate requester - an embedded CR/LF would +/// otherwise render as real line breaks in a text-based log sink, letting a requester forge a +/// fabricated log entry (CWE-117) that could be mistaken for a genuine, unrelated line by anyone +/// relying on this plugin's logs to reconstruct certificate-issuance history. +/// +internal static class LogSanitizer +{ + public static string ForLog(string value) => value?.Replace("\r", "\\r").Replace("\n", "\\n"); +} diff --git a/markmonitor-caplugin/MarkMonitorCAConnector.cs b/markmonitor-caplugin/MarkMonitorCAConnector.cs new file mode 100644 index 0000000..927168f --- /dev/null +++ b/markmonitor-caplugin/MarkMonitorCAConnector.cs @@ -0,0 +1,663 @@ +// Copyright 2025 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Collections.Concurrent; +using Keyfactor.AnyGateway.Extensions; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; +using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; +using Keyfactor.Logging; +using Keyfactor.PKI.Enums.EJBCA; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using MarkMonitorConstants = Keyfactor.Extensions.CAPlugin.MarkMonitor.MarkMonitorCAPluginConfig; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; + +public class MarkMonitorCAPlugin : IAnyCAPlugin +{ + private readonly ILogger _logger = LogHandler.GetClassLogger(); + private ICertificateDataReader _certificateDataReader; + private MarkMonitorConfig _config; + private MarkMonitorClient Client; + private bool _markMonitorClientWasInjected = false; + private MarkMonitorClient _cachedClient; + private readonly SemaphoreSlim _clientLock = new(1, 1); + + public MarkMonitorCAPlugin() + { + // Explicit default constructor + } + + public MarkMonitorCAPlugin(MarkMonitorClient client) + { + Client = client; + _markMonitorClientWasInjected = true; + } + + public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDataReader certificateDataReader) + { + _logger.MethodEntry(); + _certificateDataReader = certificateDataReader; + var rawConfig = JsonConvert.SerializeObject(configProvider.CAConnectionData); + _config = JsonConvert.DeserializeObject(rawConfig); + // _logger.LogTrace("MarkMonitorCAPlugin initialized with config: {Config}", rawConfig); + _logger.MethodExit(); + } + + + private void logConfig() + { + _logger.MethodEntry(); + _logger.LogInformation("MarkMonitorCAPlugin config baseUrl: {Config}", _config.BaseUrl); + LogMaskedConfigValue("apiKey", _config.ApiKey); + // Unlike apiKey/apiPassword, apiUsername is not a secret (GetPluginAnnotations marks it + // Hidden=false) and is the only field identifying which MarkMonitor service account this CA + // connector instance uses - log it plainly rather than masking it, so an auditor reviewing + // this component's own logs can attribute actions to a specific credential/identity, including + // when multiple CA connector instances (different service accounts) share one log sink. + if (_config.ApiUsername is { Length: > 0 }) + _logger.LogInformation("MarkMonitorCAPlugin config apiUsername: {Config}", _config.ApiUsername); + else + _logger.LogError("MarkMonitorCAPlugin config apiUsername: NOT SET"); + LogMaskedConfigValue("apiPassword", _config.ApiPassword); + _logger.LogInformation("MarkMonitorCAPlugin config orgName: {Config}", _config.OrgName); + _logger.MethodExit(); + } + + private void LogMaskedConfigValue(string label, string value) + { + if (value is { Length: > 0 }) + _logger.LogInformation("MarkMonitorCAPlugin config {Label}: {Config}", label, new string('*', 32)); + else + _logger.LogError("MarkMonitorCAPlugin config {Label}: NOT SET", label); + } + + public async Task GetSingleRecord(string caRequestId) + { + _logger.MethodEntry(); + // caRequestId is caller-supplied and only validated as a GUID deeper inside MarkMonitorClient + // - log a CR/LF-escaped copy here so an embedded CR/LF can't forge a fake log line (CWE-117) + // before that validation ever runs. + var logSafeCaRequestId = LogSanitizer.ForLog(caRequestId); + try + { + var client = await CreateAndAuthenticateClientAsync(); + _logger.LogInformation("Getting order details for CARequestID: {CARequestID}", logSafeCaRequestId); + var order = await client.GetSingleOrderAsync(caRequestId); + _logger.LogInformation("Order details retrieved for CARequestID: {CARequestID}", logSafeCaRequestId); + return order; + } + catch (Exception e) + { + _logger.LogError("Failed to get order details for CARequestID {CARequestID}: {EMessage}", + logSafeCaRequestId, e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + + } + + public async Task Synchronize(BlockingCollection blockingBuffer, DateTime? lastSync, + bool fullSync, CancellationToken cancelToken) + { + _logger.MethodEntry(); + + try + { + _logger.LogInformation(fullSync + ? "Performing a full CA synchronization" + : "Performing a partial CA synchronization"); + + logConfig(); + + _logger.LogDebug("Calling CreateAndAuthenticateClientAsync"); + var client = await CreateAndAuthenticateClientAsync(); + _logger.LogDebug("CreateAndAuthenticateClientAsync completed"); + + _logger.LogInformation("Attempting to synchronize certificates with MarkMonitor API"); + // Command's own fullSync flag forces a complete resync same as the ForceCompleteSync + // connection setting does - either one bypasses the skip-unchanged optimization. + var forceCompleteSync = fullSync || _config.ForceCompleteSync; + var certificates = await client.GetCertificateInventoryAsync("", "", _config.PageSize, blockingBuffer, + cancelToken, _certificateDataReader, forceCompleteSync); + _logger.LogDebug("Synchronized {Certificates} certificates", certificates); + + // Check for cancellation after operation + // cancelToken.ThrowIfCancellationRequested(); + } + catch (OperationCanceledException) + { + _logger.LogInformation("Synchronization canceled"); + throw; // Rethrow the cancellation exception to ensure it's propagated + } + catch (Exception ex) + { + _logger.LogError("An error occurred during synchronization: {ExMessage}", ex.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + public async Task Revoke(string orderId, string hexSerialNumber, uint revocationReason) + { + _logger.MethodEntry(); + // orderId/hexSerialNumber are caller-supplied and only validated as a GUID deeper inside + // MarkMonitorClient - log CR/LF-escaped copies here so an embedded CR/LF can't forge a fake + // log line (CWE-117) before that validation ever runs. + var logSafeOrderId = LogSanitizer.ForLog(orderId); + var logSafeHexSerialNumber = LogSanitizer.ForLog(hexSerialNumber); + try + { + EnsureOrgNameConfigured(); + + _logger.LogInformation( + "Revoking certificate with CARequestID: {CaRequestId}, SerialNumber: {HexSerialNumber}, Reason: {RevocationReason}", + logSafeOrderId, logSafeHexSerialNumber, revocationReason); + + var client = await CreateAndAuthenticateClientAsync(); + + _logger.LogInformation("Attempting to revoke certificate with CARequestID: {CaRequestId}", logSafeOrderId); + + var revokeResult = await client.RevokeCertificateAsync(orderId, _config.OrgName, revocationReason); + + if (revokeResult) return (int)EndEntityStatus.REVOKED; + + throw new Exception("Unable to revoke certificate associated with order ID: " + orderId); + } + catch (Exception e) + { + _logger.LogError("Revoke failed for order {OrderId}: {EMessage}", logSafeOrderId, e.Message); + throw new Exception($"Revoke Failed with message {e.Message}"); + } + finally + { + _logger.MethodExit(); + } + } + + public async Task Enroll(string csr, string subject, Dictionary san, + EnrollmentProductInfo productInfo, RequestFormat requestFormat, EnrollmentType enrollmentType) + { + _logger.MethodEntry(); + // Subject is fully requester-controlled (it comes straight off the submitted CSR) - log a + // CR/LF-escaped copy everywhere below so an embedded CR/LF can't forge a fake log line + // (CWE-117). The real, unsanitized subject is still what's actually used for enrollment. + var logSafeSubject = LogSanitizer.ForLog(subject); + try + { + _logger.LogInformation("Enrolling certificate `{Subject}` with MarkMonitor", logSafeSubject); + + var client = await CreateAndAuthenticateClientAsync(); + + _logger.LogInformation("Performing an Enrollment"); + _logger.LogTrace("CSR: {Csr}", LogSanitizer.ForLog(csr)); + _logger.LogTrace("Subject: {Subject}", logSafeSubject); + _logger.LogTrace("SAN: {San}", JsonConvert.SerializeObject(san)); + _logger.LogTrace("Product ID: {ProductId}", productInfo.ProductID); + + var enrollResult = await client.EnrollCertificateAsync(csr, subject, san, productInfo.ProductID, + productInfo.ProductParameters, _config); + + _logger.LogTrace("Enrollment result: {EnrollResult}", JsonConvert.SerializeObject(enrollResult)); + _logger.LogInformation("Enrollment completed successfully for subject: {Subject}", logSafeSubject); + + if (enrollmentType == EnrollmentType.RenewOrReissue) + await RevokePriorCertificateIfPresentAsync(client, productInfo, subject, enrollResult.CARequestID); + + return enrollResult; + } + catch (Exception e) + { + _logger.LogError("Enrollment failed for subject {Subject}: {EMessage}", logSafeSubject, e.Message); + throw; + } + finally + { + _logger.MethodExit(); + } + } + + private const int DefaultRenewalWindowDays = 90; + + /// + /// For a RenewOrReissue enrollment, the AnyGateway core framework passes the prior + /// certificate's serial number in productInfo.ProductParameters["PriorCertSN"]. Resolves it to a + /// CARequestID via the injected ICertificateDataReader and revokes it now that the replacement + /// certificate has issued successfully - but only when the prior certificate is actually within + /// its RenewalWindowDays template parameter (default 90) of expiring; certinext's model, + /// applied here since MarkMonitor likewise has no in-place "renew" endpoint, so the window gates + /// revoke behavior rather than endpoint choice. A prior cert with substantial life left outside + /// that window is left unrevoked - this "renewal" is instead treated like a plain new issuance. + /// Falls back to treating the enrollment as a plain new issuance (no revoke attempted) if + /// PriorCertSN is missing or can't be resolved - a failure to revoke the old certificate should + /// not fail delivery of the new one. + /// + /// Case-insensitive enrollment product-parameter lookup, matching every other + /// template-parameter lookup in this file (Command's parameter keys aren't guaranteed to arrive + /// in any particular casing). + private static string GetProductParameter(Dictionary productParameters, string key) => + productParameters?.FirstOrDefault(kv => string.Equals(kv.Key, key, StringComparison.OrdinalIgnoreCase)).Value; + + private async Task RevokePriorCertificateIfPresentAsync(MarkMonitorClient client, + EnrollmentProductInfo productInfo, string subject, string newCaRequestId) + { + var priorCertSn = GetProductParameter(productInfo.ProductParameters, "PriorCertSN"); + // PriorCertSN is a caller-supplied enrollment product parameter - log a CR/LF-escaped copy so + // an embedded CR/LF can't forge a fake log line (CWE-117), matching every other caller-supplied + // value in this file. + var logSafePriorCertSn = LogSanitizer.ForLog(priorCertSn); + + if (string.IsNullOrWhiteSpace(priorCertSn)) + { + _logger.LogWarning( + "Enrollment for {Subject} was requested as RenewOrReissue but no PriorCertSN was provided - treating it as a new enrollment", + LogSanitizer.ForLog(subject)); + return; + } + + var priorRequestId = await _certificateDataReader.GetRequestIDBySerialNumber(priorCertSn); + if (string.IsNullOrWhiteSpace(priorRequestId)) + { + _logger.LogWarning( + "Could not resolve a CARequestID for PriorCertSN {PriorCertSn} - the prior certificate will not be revoked", + logSafePriorCertSn); + return; + } + + var renewalWindowDays = ParseRenewalWindowDays(productInfo.ProductParameters); + var priorCertExpiration = _certificateDataReader.GetExpirationDateByRequestId(priorRequestId); + if (priorCertExpiration != null) + { + var daysUntilExpiration = (priorCertExpiration.Value - DateTime.UtcNow).TotalDays; + if (daysUntilExpiration > renewalWindowDays) + { + _logger.LogInformation( + "Prior certificate {PriorRequestId} does not expire for {DaysUntilExpiration:F0} more day(s), outside the configured RenewalWindowDays ({RenewalWindowDays}) - leaving it unrevoked and treating this enrollment like a plain new issuance", + priorRequestId, daysUntilExpiration, renewalWindowDays); + return; + } + } + // Expiration unresolvable (null): fall back to the pre-existing behavior (always revoke) + // rather than silently changing behavior when there isn't enough data to apply the new gate. + + try + { + EnsureOrgNameConfigured(); + + _logger.LogInformation( + "Revoking prior certificate {PriorRequestId} (serial {PriorCertSn}) after it was replaced by {NewCaRequestId}", + priorRequestId, logSafePriorCertSn, newCaRequestId); + await client.RevokeCertificateAsync(priorRequestId, _config.OrgName); + } + catch (Exception e) + { + _logger.LogError( + "Failed to revoke prior certificate {PriorRequestId} after it was replaced by {NewCaRequestId}: {EMessage}", + priorRequestId, newCaRequestId, e.Message); + } + } + + /// Parses the RenewalWindowDays template parameter (case-insensitive key, matching + /// every other enrollment parameter lookup in this file); absent or invalid (non-positive, + /// non-numeric) falls back to rather than failing the + /// enrollment over a template misconfiguration. A value that's present but rejected is logged - + /// unlike a value that's simply absent - since this silently changes a security-relevant revoke + /// decision and an administrator who mistyped it would otherwise have no signal from the gateway + /// logs that their configured window was never actually applied. + private int ParseRenewalWindowDays(Dictionary productParameters) + { + var raw = GetProductParameter(productParameters, "RenewalWindowDays"); + if (string.IsNullOrWhiteSpace(raw)) return DefaultRenewalWindowDays; + + if (int.TryParse(raw, out var parsed) && parsed > 0) return parsed; + + _logger.LogWarning( + "Invalid RenewalWindowDays value '{RenewalWindowDays}' - must be a positive integer; falling back to the default of {DefaultRenewalWindowDays} day(s)", + LogSanitizer.ForLog(raw), DefaultRenewalWindowDays); + return DefaultRenewalWindowDays; + } + + /// + /// RevokeCertificateAsync's cross-org ownership check is skipped (not rejected) when its + /// orgName parameter is blank - a deliberate allowance for ad-hoc/manual callers that don't + /// scope by organization. Initialize() never re-validates the deserialized config, so without + /// this guard a plugin instance loaded with a blank OrgId would silently revoke without any + /// organization check at all, on every Revoke call this connector makes. + /// + private void EnsureOrgNameConfigured() + { + if (string.IsNullOrWhiteSpace(_config.OrgName)) + throw new ConfigurationValidationException( + "MarkMonitor OrgId is not configured - refusing to revoke without an organization to verify ownership against"); + } + + public async Task Ping() + { + _logger.MethodEntry(); + try + { + _logger.LogInformation("Attempting to authenticate with MarkMonitor API"); + var client = await CreateAndAuthenticateClientAsync(); + + if (client == null) throw new Exception("Error attempting to ping MarkMonitor"); + + _logger.LogInformation("Attempting to list organizations"); + // ListOrganizationsAsync's pagination loop has no early exit - it always fetches every + // page up to TotalPages regardless of what the caller actually needs. A page size of 1 + // (an earlier version of this fix) backfires badly here: TotalPages becomes the account's + // total organization count, turning this existence check into one sequential HTTP request + // per organization. Page size 100 - the same size already used for org-name resolution - + // keeps this to a single request for the common case instead. + var orgs = await client.ListOrganizationsAsync(0, 100); + // CreateAndAuthenticateClientAsync deliberately does NOT authenticate eagerly (see its own + // doc comment) - it just builds/caches the client wrapper. The real authentication happens + // lazily inside ListOrganizationsAsync above (via EnsureAuthenticatedAsync, properly + // serialized against every other call path by _authLock) - only log success now that it + // has actually completed, rather than before any credential had been checked. (A previous + // version of this fix called client.AuthenticateAsync() directly here to get the ordering + // right, but that bypassed _authLock entirely and could race a concurrent Enroll/Revoke/ + // Synchronize call's own authentication on the same shared HttpClient - reordering instead + // of calling AuthenticateAsync directly avoids that race altogether.) + _logger.LogInformation("Authentication with MarkMonitor API successful"); + + if (orgs == null || !orgs.Any()) + throw new Exception("Unable to ping MarkMonitor API, or no MarkMonitor organization exist"); + _logger.LogInformation("Successfully pinged MarkMonitor API"); + } + catch (Exception e) + { + _logger.LogError("There was an error contacting MarkMonitor: {EMessage}", e.Message); + throw new Exception($"Error attempting to ping MarkMonitor: {e.Message}.", e); + } + finally + { + _logger.MethodExit(); + } + } + + public async Task ValidateCAConnectionInfo(Dictionary connectionInfo) + { + _logger.MethodEntry(); + _logger.LogInformation("Validating CA Connection Info"); + + var errors = new List(); + + _logger.LogDebug("Checking the API Key"); + var apiKey = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.ApiKey, out var aKey) + ? (string)aKey + : string.Empty; + if (string.IsNullOrWhiteSpace(apiKey)) + errors.Add($"A valid `{MarkMonitorConstants.ConfigConstants.ApiKey} is required"); + else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.ApiKey} is set"); + + _logger.LogDebug("Checking the API service account password"); + var apiPassword = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.ApiPassword, out var aPass) + ? (string)aPass + : string.Empty; + if (string.IsNullOrWhiteSpace(apiPassword)) + errors.Add($"A valid service account `{MarkMonitorConstants.ConfigConstants.ApiPassword}` is required"); + else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.ApiPassword} is set"); + + _logger.LogDebug("Checking the API service account username"); + var apiUsername = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.ApiUsername, out var aUser) + ? (string)aUser + : string.Empty; + if (string.IsNullOrWhiteSpace(apiUsername)) + errors.Add($"A valid service account `{MarkMonitorConstants.ConfigConstants.ApiUsername}` is required"); + else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.ApiUsername} is set"); + + _logger.LogDebug("Checking the API base URL"); + var baseURL = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.BaseUrl, out var aUrl) + ? (string)aUrl + : string.Empty; + if (string.IsNullOrWhiteSpace(baseURL)) baseURL = "https://api.markmonitor.com"; + else if (!baseURL.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) + errors.Add("The Base URL must start with https:// - credentials and the bearer token are sent to it"); + else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.BaseUrl} is set"); + _logger.LogTrace("MarkMonitor API Base URL: {BaseURL}", baseURL); + + _logger.LogDebug("Checking the Organization Name"); + var orgName = connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.OrgName, out var aOrg) + ? (string)aOrg + : string.Empty; + if (string.IsNullOrWhiteSpace(orgName)) errors.Add("A valid Organization name is required"); + else _logger.LogDebug($"{MarkMonitorConstants.ConfigConstants.OrgName} is set"); + _logger.LogTrace("MarkMonitor Organization Name: {OrgName}", orgName); + if (errors.Any()) ThrowValidationException(errors); + + // Enabled's own documented purpose (GetPluginAnnotations' Comments) is letting an admin + // create the CA connector before real MarkMonitor credentials are available - a workflow the + // field-presence/format checks above already accommodate (they only require *some* + // syntactically-valid values, not working ones). The live-connectivity check below must not + // undermine that pre-existing capability by requiring real connectivity even for a + // deliberately-disabled, not-yet-configured connector. + var enabled = !connectionInfo.TryGetValue(MarkMonitorConstants.ConfigConstants.Enabled, out var aEnabled) || + aEnabled is not bool enabledFlag || enabledFlag; + if (!enabled) + { + _logger.LogInformation( + "CA connector is disabled - skipping the live MarkMonitor connectivity check"); + _logger.LogInformation("CA Connection Info validated successfully"); + _logger.MethodExit(); + return; + } + + // The aggregated checks above only confirm the fields are present and well-formed - not that + // they're actually valid MarkMonitor credentials. Build a transient client from the submitted + // connectionInfo itself (never _cachedClient, which may hold stale/different creds from a + // previous save) so validation reflects exactly what's about to be saved. A test-injected + // client (see the constructor overload) is reused as-is instead, the same seam every other + // method in this class already relies on for testability - and it must not be disposed here, + // since its lifecycle belongs to whoever injected it, not to this one validation call. + MarkMonitorConfig tempConfig = null; + MarkMonitorClient tempClient = _markMonitorClientWasInjected ? Client : null; + try + { + if (!_markMonitorClientWasInjected) + { + try + { + var rawConfig = JsonConvert.SerializeObject(connectionInfo); + tempConfig = JsonConvert.DeserializeObject(rawConfig); + tempConfig.BaseUrl = baseURL; // the resolved effective value (blank -> the default above) + tempClient = BuildClient(tempConfig); + } + catch (Exception e) + { + // A field the aggregated checks above don't cover (e.g. a non-numeric value for + // one of the Number-typed fields) can fail deserialization here - caught and + // sanitized like every other failure mode in this method, rather than letting a + // raw JsonSerializationException (which can embed field paths/values) escape + // unlogged. e.Message itself echoes the rejected connectionInfo value verbatim + // (e.g. "Could not convert string to integer: ") - sanitized here too, so + // an embedded CR/LF in that value can't forge a fake log line (CWE-117), matching + // every other caller-supplied value logged in this file. + _logger.LogError("CA connection validation failed while parsing the submitted configuration: {EMessage}", + LogSanitizer.ForLog(e.Message)); + throw new AnyCAValidationException( + "The submitted configuration could not be parsed. See gateway logs for details."); + } + } + + try + { + await tempClient.AuthenticateAsync(); + } + catch (Exception e) + { + // The real exception/response detail is deliberately not forwarded to the UI - it may + // carry HTTP response fragments, headers, or other transport-layer detail. + _logger.LogError("CA connection live validation failed during authentication: {EMessage}", + e.Message); + throw new AnyCAValidationException( + "Authentication failed with the submitted MarkMonitor credentials. See gateway logs for details."); + } + + try + { + var orgs = await tempClient.ListOrganizationsAsync(0, 1); + if (orgs == null || orgs.Count == 0) + throw new Exception("No MarkMonitor organizations are visible to the submitted credentials"); + } + catch (Exception e) + { + _logger.LogError("CA connection live validation failed while listing organizations: {EMessage}", + e.Message); + throw new AnyCAValidationException( + "Authenticated with MarkMonitor, but listing organizations failed. See gateway logs for details."); + } + } + finally + { + if (!_markMonitorClientWasInjected) tempClient?.Dispose(); + // Best-effort credential scrubbing: blank out the secret fields on the transient config so + // they aren't reachable from this now-unreferenced object after this method returns. Not a + // hard guarantee (the runtime may already have copied them elsewhere), but removes the most + // obvious post-validation reference chain - certinext's pattern. + if (tempConfig != null) + { + tempConfig.ApiKey = string.Empty; + tempConfig.ApiPassword = string.Empty; + } + } + + _logger.LogInformation("CA Connection Info validated successfully"); + _logger.MethodExit(); + } + + // Considered validating MarkmonitorContact/MarkmonitorGroup here eagerly (at template-save + // time) instead of the current behavior - a typo'd value logs a warning and silently falls back + // to a default at enroll time. Deferred: doing so would mean making live MarkMonitor API calls + // during template save (no other Validate* method in this codebase does that), coupling template + // configuration to MarkMonitor's availability/latency, and duplicating the resolution logic + // that already lives in EnrollCertificateAsync. That's a real product tradeoff (fail fast on + // template save vs. graceful degradation at enroll time) rather than a straightforward bug fix. + public Task ValidateProductInfo(EnrollmentProductInfo productInfo, Dictionary connectionInfo) + { + _logger.MethodEntry(); + + // Unlike MarkmonitorContact/MarkmonitorGroup above, this is a cheap static check - no live + // MarkMonitor call - so there's no tradeoff in failing fast on it at template-save time. + // Enum.TryParse alone isn't enough: it happily "succeeds" for any numeric string that fits + // the underlying int type even when no member is actually defined for that value (e.g. "20" + // for a 12-member enum) - Enum.IsDefined is the check that actually enforces membership. + if (!Enum.TryParse(productInfo.ProductID, out var parsedProductId) || + !Enum.IsDefined(typeof(CertOrderTypes), parsedProductId)) + throw new AnyCAValidationException( + $"'{LogSanitizer.ForLog(productInfo.ProductID)}' is not a valid MarkMonitor product ID. Valid values are: {string.Join(", ", Enum.GetNames(typeof(CertOrderTypes)))}"); + + _logger.LogInformation("Product info validated successfully"); + _logger.MethodExit(); + return Task.CompletedTask; + } + + public Dictionary GetCAConnectorAnnotations() + { + _logger.MethodEntry(); + try + { + _logger.LogInformation("Retrieving CA Connector annotations"); + return MarkMonitorConstants.GetPluginAnnotations(); + } + finally + { + _logger.MethodExit(); + } + + } + + public Dictionary GetTemplateParameterAnnotations() + { + _logger.MethodEntry(); + try + { + _logger.LogInformation("Retrieving template parameter annotations"); + return MarkMonitorConstants.GetTemplateParameterAnnotations(); + } + finally + { + _logger.MethodExit(); + } + + } + + public List GetProductIds() + { + // return list of CertOrderTypes Enum values + _logger.MethodEntry(); + try + { + _logger.LogInformation("Retrieving product IDs from CertOrderTypes Enum"); + return Enum.GetNames(typeof(CertOrderTypes)).ToList(); + } + finally + { + _logger.MethodExit(); + } + + } + + /// Builds a real MarkMonitorClient from the given config - the one place this + /// connector's own construction argument list lives, shared by the cached-client path + /// () and the transient one + /// (). + private static MarkMonitorClient BuildClient(MarkMonitorConfig config) => + new(config.BaseUrl, config.ApiKey, config.ApiUsername, config.ApiPassword, true, + timeoutSeconds: config.TimeoutSeconds); + + /// + /// Returns a single MarkMonitorClient shared for the lifetime of this plugin instance, building + /// it (or adopting an injected one) on first use only. Each of MarkMonitorClient's own methods + /// authenticates/re-authenticates itself lazily as needed, so this method does not need to - and + /// deliberately does not - force an eager authentication call on every invocation. + /// + internal async Task CreateAndAuthenticateClientAsync() + { + _logger.MethodEntry(); + try + { + if (_cachedClient != null) return _cachedClient; + + await _clientLock.WaitAsync(); + try + { + _cachedClient ??= _markMonitorClientWasInjected ? Client : BuildClient(_config); + } + finally + { + _clientLock.Release(); + } + + return _cachedClient; + } + finally + { + _logger.MethodExit(); + } + } + + private void ThrowValidationException(List errors) + { + _logger.MethodEntry(); + var validationMsg = $"Validation errors:\n{string.Join("\n", errors)}"; + _logger.LogError("{Errors}",validationMsg); + throw new AnyCAValidationException(validationMsg); + } +} \ No newline at end of file diff --git a/markmonitor-caplugin/MarkMonitorCAPluginConfig.cs b/markmonitor-caplugin/MarkMonitorCAPluginConfig.cs new file mode 100644 index 0000000..e9c8abd --- /dev/null +++ b/markmonitor-caplugin/MarkMonitorCAPluginConfig.cs @@ -0,0 +1,278 @@ +// Copyright 2025 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Keyfactor.AnyGateway.Extensions; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; + +/// +/// Provides configuration and annotation details for the MarkMonitor CA Plugin. +/// +public class MarkMonitorCAPluginConfig +{ + /// + /// Returns a dictionary of plugin configuration property annotations. + /// + /// Dictionary mapping property names to their configuration info. + public static Dictionary GetPluginAnnotations() + { + return new Dictionary + { + [ConfigConstants.ApiKey] = new() + { + Comments = "The API Key for the MarkMonitor API", + Hidden = true, + DefaultValue = "", + Type = "String" + }, + [ConfigConstants.ApiUsername] = new() + { + Comments = "Username for the MarkMonitor API service account", + Hidden = false, + DefaultValue = "", + Type = "String" + }, + [ConfigConstants.ApiPassword] = new() + { + Comments = "Password for the MarkMonitor API service account", + Hidden = true, + DefaultValue = "", + Type = "String" + }, + [ConfigConstants.BaseUrl] = new() + { + Comments = + "The Base URL for the MarkMonitor API - Usually either https://api.markmonitor.com", + Hidden = false, + DefaultValue = "https://api.markmonitor.com", + Type = "String" + }, + [ConfigConstants.OrgName] = new() + { + Comments = + "The name of the MarkMonitor Organization to use for the API calls (ex: MarkMonitor). You can also use the Organization ID in GUID format.", + Hidden = false, + DefaultValue = "", + Type = "String" + }, + [ConfigConstants.Enabled] = new() + { + Comments = + "Flag to Enable or Disable gateway functionality. Disabling is primarily used to allow creation of the CA prior to configuration information being available.", + Hidden = false, + DefaultValue = true, + Type = "Boolean" + }, + [ConfigConstants.TimeoutSeconds] = new() + { + Comments = "The HTTP request timeout, in seconds, for calls to the MarkMonitor API. Default is 120.", + Hidden = false, + DefaultValue = 120, + Type = "Number" + }, + [ConfigConstants.PageSize] = new() + { + Comments = + "The number of certificate orders requested per page during synchronization (1-500). Default is 100.", + Hidden = false, + DefaultValue = 100, + Type = "Number" + }, + [ConfigConstants.ForceCompleteSync] = new() + { + Comments = + "When true, bypasses the skip-unchanged optimization and re-emits every order on every synchronization. Default is false.", + Hidden = false, + DefaultValue = false, + Type = "Boolean" + }, + [ConfigConstants.PickupRetries] = new() + { + Comments = + "How many times to poll a freshly-created order for issuance before returning it in its still-pending state. 0 disables polling. Default is 5.", + Hidden = false, + DefaultValue = 5, + Type = "Number" + }, + [ConfigConstants.PickupDelaySeconds] = new() + { + Comments = "The delay, in seconds, between issuance pickup polls. Default is 10.", + Hidden = false, + DefaultValue = 10, + Type = "Number" + } + }; + } + + /// + /// Returns a dictionary of template parameter annotations for certificate enrollment. + /// + /// Dictionary mapping template parameter names to their configuration info. + public static Dictionary GetTemplateParameterAnnotations() + { + return new Dictionary + { + [EnrollmentConfigConstants.AdditionalEmails] = new() + { + Comments = + "List of 0 or more comma separated email addresses to send the certificate to via email after generation.", + Hidden = false, + DefaultValue = "", + Type = "String" + }, + [EnrollmentConfigConstants.MarkmonitorGroup] = new() + { + Comments = "The name or GUID of a Markmonitor group to use for the certificate request.", + Hidden = false, + DefaultValue = "", + Type = "String" + }, + [EnrollmentConfigConstants.MarkmonitorContact] = new() + { + Comments = + "The name or GUID of a Markmonitor contact to use for the certificate request. Will use default Markmonitor organization contact if not specified.", + Hidden = false, + DefaultValue = "", + Type = "String" + }, + [EnrollmentConfigConstants.DCVMethod] = new() + { + Comments = + "The method to use for Domain Control Validation (DCV). Valid values are EMAIL, DNS_CNAME_TOKEN, HTTP_TOKEN, DNS_TXT_TOKEN. Default is EMAIL.", + Hidden = false, + DefaultValue = "EMAIL", + Type = "String" + }, + [EnrollmentConfigConstants.Comments] = new() + { + Comments = "Comments to attach to the MarkMonitor order. Default is \"Requested via Keyfactor Command\".", + Hidden = false, + DefaultValue = "Requested via Keyfactor Command", + Type = "String" + }, + [EnrollmentConfigConstants.Locale] = new() + { + Comments = "Locale to use for the MarkMonitor order. Default is \"en\".", + Hidden = false, + DefaultValue = "en", + Type = "String" + }, + [EnrollmentConfigConstants.Provider] = new() + { + Comments = "The certificate provider to use for the order. Default is \"DIGICERT\" (currently the only provider MarkMonitor's API supports).", + Hidden = false, + DefaultValue = "DIGICERT", + Type = "String" + }, + [EnrollmentConfigConstants.RenewalWindowDays] = new() + { + Comments = + "For a RenewOrReissue enrollment, how many days before its expiration a prior certificate must be within before it is revoked after being replaced. Outside this window, the prior certificate is left unrevoked and the request is treated like a plain new issuance. Default is 90.", + Hidden = false, + DefaultValue = 90, + Type = "Number" + } + }; + } + + /// + /// Contains constant keys for plugin configuration properties. + /// + public class ConfigConstants + { + /// + /// The API key property name. + /// + public const string ApiKey = "ApiKey"; + /// + /// The API password property name. + /// + public const string ApiPassword = "Password"; + /// + /// The API username property name. + /// + public const string ApiUsername = "Username"; + /// + /// The base URL property name. + /// + public const string BaseUrl = "BaseUrl"; + /// + /// The organization name property name. + /// + public const string OrgName = "OrgId"; + /// + /// The enabled flag property name. + /// + public const string Enabled = "Enabled"; + /// + /// The HTTP request timeout (seconds) property name. + /// + public const string TimeoutSeconds = "TimeoutSeconds"; + /// + /// The sync page size property name. + /// + public const string PageSize = "PageSize"; + /// + /// The force-complete-sync flag property name. + /// + public const string ForceCompleteSync = "ForceCompleteSync"; + /// + /// The pickup poll retry count property name. + /// + public const string PickupRetries = "PickupRetries"; + /// + /// The pickup poll delay (seconds) property name. + /// + public const string PickupDelaySeconds = "PickupDelaySeconds"; + } + + /// + /// Contains constant keys for enrollment configuration parameters. + /// + public static class EnrollmentConfigConstants + { + /// + /// The additional emails parameter name. + /// + public const string AdditionalEmails = "AdditionalEmails"; + /// + /// The MarkMonitor group parameter name. + /// + public const string MarkmonitorGroup = "MarkmonitorGroup"; + /// + /// The MarkMonitor contact parameter name. + /// + public const string MarkmonitorContact = "MarkmonitorContact"; + /// + /// The domain control validation method parameter name. + /// + public const string DCVMethod = "DCVMethod"; + /// + /// The order comments parameter name. + /// + public const string Comments = "comments"; + /// + /// The order locale parameter name. + /// + public const string Locale = "locale"; + /// + /// The certificate provider parameter name. + /// + public const string Provider = "provider"; + /// + /// The renewal window (days) parameter name. + /// + public const string RenewalWindowDays = "RenewalWindowDays"; + } +} \ No newline at end of file diff --git a/markmonitor-caplugin/MarkMonitorConfig.cs b/markmonitor-caplugin/MarkMonitorConfig.cs new file mode 100644 index 0000000..5017b0c --- /dev/null +++ b/markmonitor-caplugin/MarkMonitorConfig.cs @@ -0,0 +1,137 @@ +// Copyright 2025 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Newtonsoft.Json; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; + +/// +/// Represents the configuration settings required for the MarkMonitor CA Plugin. +/// +public class MarkMonitorConfig +{ + /// + /// The API key used to authenticate with the MarkMonitor API. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.ApiKey)] + public string ApiKey { get; set; } + + /// + /// The password for the MarkMonitor API service account. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.ApiPassword)] + public string ApiPassword { get; set; } + + /// + /// The username for the MarkMonitor API service account. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.ApiUsername)] + public string ApiUsername { get; set; } + + /// + /// The base URL for the MarkMonitor API. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.BaseUrl)] + public string BaseUrl { get; set; } + + /// + /// The organization name used in MarkMonitor operations. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.OrgName)] + public string OrgName { get; set; } + + /// + /// Indicates whether the MarkMonitor CA Plugin is enabled. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.Enabled)] + public bool Enabled { get; set; } + + private const int MinTimeoutSeconds = 1; + private const int MaxTimeoutSeconds = 120; + private int _timeoutSeconds = 120; + + /// + /// The HTTP request timeout, in seconds, for calls to the MarkMonitor API. Clamped to + /// [, ] in the setter - a value + /// <= 0 would otherwise crash HttpClient.Timeout's own setter with an unhandled + /// ArgumentOutOfRangeException (verified: .NET rejects non-positive timeouts), and the upper + /// bound is capped at this field's own pre-existing hardcoded default so a misconfigured value + /// can never make a slow-MarkMonitor scenario worse than before this field was configurable - + /// notably bounding how long AuthenticateAsync can hold the shared auth lock across its 3 retry + /// attempts. A property initializer (not just the annotation's DefaultValue) is required here so + /// an existing saved CA connection - created before this field existed, and so missing it + /// entirely from its stored JSON - still gets a sane timeout rather than 0. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.TimeoutSeconds)] + public int TimeoutSeconds + { + get => _timeoutSeconds; + set => _timeoutSeconds = Math.Clamp(value, MinTimeoutSeconds, MaxTimeoutSeconds); + } + + private const int MinPageSize = 1; + private const int MaxPageSize = 500; + private int _pageSize = 100; + + /// + /// The number of certificate orders requested per page during synchronization. Clamped to + /// [, ] in the setter, so both a + /// JSON-deserialized value and a directly-assigned one are always sane - not to be confused + /// with MarkMonitorClient.NameResolutionPageSize, an unrelated fixed page size used only + /// for org/group name lookups. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.PageSize)] + public int PageSize + { + get => _pageSize; + set => _pageSize = Math.Clamp(value, MinPageSize, MaxPageSize); + } + + /// + /// When true, bypasses the skip-unchanged sync optimization and re-emits every order on every + /// synchronization, regardless of whether Command already has it at the same status. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.ForceCompleteSync)] + public bool ForceCompleteSync { get; set; } + + private const int MaxPickupRetries = 20; + private int _pickupRetries = 5; + + /// + /// How many times to poll a freshly-created order for issuance before falling back to returning + /// it in its still-pending state. 0 disables polling entirely. Clamped to + /// [0, ] - combined with 's own + /// cap, this bounds Enroll's worst-case added latency (and, since polling runs before the + /// enrollment dedup reservation resolves, how long a concurrent duplicate call can block behind + /// it) to a fixed, sane ceiling rather than an operator-configurable unbounded one. + /// + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.PickupRetries)] + public int PickupRetries + { + get => _pickupRetries; + set => _pickupRetries = Math.Clamp(value, 0, MaxPickupRetries); + } + + private const int MaxPickupDelaySeconds = 60; + private int _pickupDelaySeconds = 10; + + /// The delay between pickup polls, in seconds. Clamped to + /// [0, ]. + [JsonProperty(MarkMonitorCAPluginConfig.ConfigConstants.PickupDelaySeconds)] + public int PickupDelaySeconds + { + get => _pickupDelaySeconds; + set => _pickupDelaySeconds = Math.Clamp(value, 0, MaxPickupDelaySeconds); + } +} \ No newline at end of file diff --git a/markmonitor-cagateway/Models/Enums.cs b/markmonitor-caplugin/Models/Enums.cs similarity index 93% rename from markmonitor-cagateway/Models/Enums.cs rename to markmonitor-caplugin/Models/Enums.cs index 0028a51..2f9e044 100644 --- a/markmonitor-cagateway/Models/Enums.cs +++ b/markmonitor-caplugin/Models/Enums.cs @@ -133,11 +133,24 @@ public enum CertServerPlatforms [Description("MICROSOFT_IIS_5_OR_6")] MicrosoftIis5Or6 } +public enum DomainControlValidationMethods +{ + //EMAIL, DNS_CNAME_TOKEN, HTTP_TOKEN, DNS_TXT_TOKEN + [Description("EMAIL")] Email, + + [Description("DNS_CNAME_TOKEN")] DnsCNameToken, + + [Description("HTTP_TOKEN")] HttpToken, + + [Description("DNS_TXT_TOKEN")] DnsTxtToken +} + public static class EnumExtensions { public static string GetDescription(this Enum value) { var field = value.GetType().GetField(value.ToString()); + if (field == null) return ""; var attribute = field.GetCustomAttribute(); return attribute?.Description ?? value.ToString(); } diff --git a/markmonitor-cagateway/Models/MarkMonitorCommon.cs b/markmonitor-caplugin/Models/MarkMonitorCommon.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorCommon.cs rename to markmonitor-caplugin/Models/MarkMonitorCommon.cs diff --git a/markmonitor-cagateway/Models/MarkMonitorGetContactResponse.cs b/markmonitor-caplugin/Models/MarkMonitorGetContactResponse.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorGetContactResponse.cs rename to markmonitor-caplugin/Models/MarkMonitorGetContactResponse.cs diff --git a/markmonitor-cagateway/Models/MarkMonitorGetOrganizationResponse.cs b/markmonitor-caplugin/Models/MarkMonitorGetOrganizationResponse.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorGetOrganizationResponse.cs rename to markmonitor-caplugin/Models/MarkMonitorGetOrganizationResponse.cs diff --git a/markmonitor-cagateway/Models/MarkMonitorListCertificatesResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListCertificatesResponse.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorListCertificatesResponse.cs rename to markmonitor-caplugin/Models/MarkMonitorListCertificatesResponse.cs diff --git a/markmonitor-cagateway/Models/MarkMonitorListContactsResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListContactsResponse.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorListContactsResponse.cs rename to markmonitor-caplugin/Models/MarkMonitorListContactsResponse.cs diff --git a/markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs new file mode 100644 index 0000000..66b9671 --- /dev/null +++ b/markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs @@ -0,0 +1,57 @@ +using Newtonsoft.Json; + +namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; + +/// +/// Represents the response for listing groups from the MarkMonitor Auth API. +/// +public class MarkMonitorListGroupsResponse +{ + /// + /// Gets or sets the groups returned. + /// + [JsonProperty("groups")] + public List Groups { get; set; } + + /// + /// Gets or sets the pagination information. + /// + [JsonProperty("page")] + public MarkMonitorPageInfo MarkMonitorPage { get; set; } +} + +/// +/// Represents a MarkMonitor group that an order can be associated with. +/// +public class MarkMonitorGroup +{ + /// + /// Gets or sets the date the group was created. + /// + [JsonProperty("dateCreated")] + public DateTime DateCreated { get; set; } + + /// + /// Gets or sets the date the group was last updated. + /// + [JsonProperty("dateUpdated")] + public DateTime DateUpdated { get; set; } + + /// + /// Gets or sets the name of the group. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Gets or sets the description of the group. + /// + [JsonProperty("description")] + public string Description { get; set; } + + /// + /// Gets or sets the ID of the group. + /// + [JsonProperty("id")] + public string Id { get; set; } +} diff --git a/markmonitor-cagateway/Models/MarkMonitorListOrgsResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListOrgsResponse.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorListOrgsResponse.cs rename to markmonitor-caplugin/Models/MarkMonitorListOrgsResponse.cs diff --git a/markmonitor-cagateway/Models/MarkMonitorOrder.cs b/markmonitor-caplugin/Models/MarkMonitorOrder.cs similarity index 95% rename from markmonitor-cagateway/Models/MarkMonitorOrder.cs rename to markmonitor-caplugin/Models/MarkMonitorOrder.cs index 68d5a8e..ba2e396 100644 --- a/markmonitor-cagateway/Models/MarkMonitorOrder.cs +++ b/markmonitor-caplugin/Models/MarkMonitorOrder.cs @@ -67,6 +67,12 @@ public class OrderContent [JsonProperty("groupId")] public string GroupId { get; set; } + /// + /// Gets or sets the organization ID that owns this order. + /// + [JsonProperty("organizationId")] + public string OrganizationId { get; set; } + /// /// Gets or sets the contacts associated with the order. /// diff --git a/markmonitor-cagateway/Models/MarkMonitorOrderRequest.cs b/markmonitor-caplugin/Models/MarkMonitorOrderRequest.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorOrderRequest.cs rename to markmonitor-caplugin/Models/MarkMonitorOrderRequest.cs diff --git a/markmonitor-cagateway/Models/MarkMonitorReissueRequest.cs b/markmonitor-caplugin/Models/MarkMonitorReissueRequest.cs similarity index 100% rename from markmonitor-cagateway/Models/MarkMonitorReissueRequest.cs rename to markmonitor-caplugin/Models/MarkMonitorReissueRequest.cs diff --git a/markmonitor-cagateway/Models/TokenRequest.cs b/markmonitor-caplugin/Models/TokenRequest.cs similarity index 100% rename from markmonitor-cagateway/Models/TokenRequest.cs rename to markmonitor-caplugin/Models/TokenRequest.cs diff --git a/markmonitor-cagateway/Models/TokenResponse.cs b/markmonitor-caplugin/Models/TokenResponse.cs similarity index 73% rename from markmonitor-cagateway/Models/TokenResponse.cs rename to markmonitor-caplugin/Models/TokenResponse.cs index 6f033d9..b85eeb1 100644 --- a/markmonitor-cagateway/Models/TokenResponse.cs +++ b/markmonitor-caplugin/Models/TokenResponse.cs @@ -6,5 +6,5 @@ public class TokenResponse { [JsonProperty("token")] public string BearerToken { get; set; } - [JsonProperty("expires_in")] public int ExpiresIn { get; set; } + [JsonProperty("expiresIn")] public int ExpiresIn { get; set; } } \ No newline at end of file diff --git a/markmonitor-cagateway/Properties/AssemblyInfo.cs b/markmonitor-caplugin/Properties/AssemblyInfo.cs similarity index 86% rename from markmonitor-cagateway/Properties/AssemblyInfo.cs rename to markmonitor-caplugin/Properties/AssemblyInfo.cs index 176f3e7..4b0ef8c 100644 --- a/markmonitor-cagateway/Properties/AssemblyInfo.cs +++ b/markmonitor-caplugin/Properties/AssemblyInfo.cs @@ -1,14 +1,17 @@ using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +[assembly: InternalsVisibleTo("markmonitor-caplugin.Tests")] + // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("markmonitor-cagateway")] +[assembly: AssemblyTitle("markmonitor-caplugin")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("markmonitor-cagateway")] +[assembly: AssemblyProduct("markmonitor-caplugin")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/markmonitor-cagateway/app.config b/markmonitor-caplugin/app.config similarity index 100% rename from markmonitor-cagateway/app.config rename to markmonitor-caplugin/app.config diff --git a/markmonitor-cagateway/manifest.json b/markmonitor-caplugin/manifest.json similarity index 88% rename from markmonitor-cagateway/manifest.json rename to markmonitor-caplugin/manifest.json index 3d2dba6..bf0d33b 100644 --- a/markmonitor-cagateway/manifest.json +++ b/markmonitor-caplugin/manifest.json @@ -1,7 +1,7 @@ { "extensions": { "Keyfactor.AnyGateway.Extensions.IAnyCAPlugin": { - "GCPCASCAPlugin": { + "MarkMonitorCAPlugin": { "assemblypath": "MarkMonitorCAPlugin.dll", "TypeFullName": "Keyfactor.Extensions.CAPlugin.MarkMonitor.MarkMonitorCAPlugin" } diff --git a/markmonitor-caplugin/markmonitor-caplugin.csproj b/markmonitor-caplugin/markmonitor-caplugin.csproj new file mode 100644 index 0000000..31a69d5 --- /dev/null +++ b/markmonitor-caplugin/markmonitor-caplugin.csproj @@ -0,0 +1,54 @@ + + + + net8.0;net10.0 + Keyfactor.Extensions.CAPlugin.MarkMonitor + enable + disable + MarkMonitorCAPlugin + true + + + false + Keyfactor Inc + MarkMonitor CA Gateway + 1.0.0.0 + 1.0.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + + From 5e1e866487b8e9c91d3822ead76d5458ca985a1c Mon Sep 17 00:00:00 2001 From: spbsoluble <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 13 Aug 2026 18:54:14 -0700 Subject: [PATCH 2/8] docs: update architecture and codemap documentation --- DEVELOPMENT.md | 15 +- docs/architecture.md | 69 ++++++++- docsource/CODEMAP.md | 60 ++++---- docsource/architecture.md | 280 +++++++++++++++++++++++++++++++++++++ docsource/configuration.md | 238 +------------------------------ docsource/overview.md | 4 +- 6 files changed, 391 insertions(+), 275 deletions(-) create mode 100644 docsource/architecture.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 0eed198..cbb6bfd 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -156,12 +156,15 @@ dotnet run --project TestConsole - `integration-manifest.json` (repo root) drives Keyfactor's integration catalog metadata (`product_ids`, `ca_plugin_config`, `enrollment_config`) — keep it in sync with `MarkMonitorCAPluginConfig.cs` and `CertOrderTypes` whenever either changes. -- `docsource/configuration.md` and `docsource/overview.md` are the source-of-truth, customer-facing - documentation fragments. Root `README.md` is generated by the Keyfactor doctool - (`~/RiderProjects/doctooldotnet`) from `docsource/configuration.md` + `integration-manifest.json` — - never hand-edit `README.md`; edit `docsource/configuration.md` and regenerate. This `DEVELOPMENT.md` - file, like `LICENSE`, is hand-maintained at the repo root and is **not** part of the doctool - pipeline — edit it directly. +- `docsource/configuration.md`, `docsource/overview.md`, and `docsource/architecture.md` are the + source-of-truth, customer-facing documentation fragments. Root `README.md` is generated by the + Keyfactor doctool (`~/RiderProjects/doctooldotnet`) from `docsource/configuration.md` + + `integration-manifest.json` — `configuration.md` pulls `architecture.md` in via + `{% include 'architecture.md' %}`. Never hand-edit `README.md`; edit the relevant docsource + fragment and regenerate. This `DEVELOPMENT.md` file, like `LICENSE`, is hand-maintained at the repo + root and is **not** part of the doctool pipeline — edit it directly. Its own `## Architecture` + section below is a deeper, method-level tier of the same diagrams in `docsource/architecture.md` — + update both when a lifecycle flow changes. - `docsource/CODEMAP.md` is the orientation map for this repo — update it whenever you change the architecture, add/move key files, or change the build/test layout. diff --git a/docs/architecture.md b/docs/architecture.md index 33d9c66..d2de113 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -93,6 +93,13 @@ sequenceDiagram Plugin->>API: POST /certs/v1/order (product, org, contact, DCV method, CSR) API-->>Plugin: Order created - order ID + status + opt Not yet issued and PickupRetries > 0 + loop Up to PickupRetries times, every PickupDelaySeconds + Plugin->>API: Poll the order + API-->>Plugin: Current status + end + end + alt Renewal / reissue Plugin->>API: Revoke the prior certificate end @@ -101,6 +108,10 @@ sequenceDiagram end ``` +A product whose DCV/approval resolves quickly can come back issued from this same enrollment call +instead of always waiting for the next sync. Set `PickupRetries` to `0` to disable polling and +restore the always-returns-pending behavior. + ### Renewal / reissue A renewal or reissue always places a brand-new order first, then revokes the certificate it's @@ -148,8 +159,11 @@ sequenceDiagram ## Connector validation When an administrator saves or edits the CA connector, the plugin checks the supplied fields before -allowing it to be saved in an enabled state. This is a field-level check only - it doesn't make a -live API call; `Ping` is the live connectivity check. +allowing it to be saved in an enabled state. If the connector is being saved *enabled*, it also makes +a live call to MarkMonitor to confirm the credentials actually work — using a client built from +exactly what's about to be saved, not the connector's already-cached client. Saving with `Enabled` +set to `false` skips that live check, so a connector can be created before real credentials are +available. ```mermaid flowchart TD @@ -159,12 +173,57 @@ flowchart TD C -- No --> E C -- Yes --> D{"Organization ID present?"} D -- Missing --> E - D -- Present --> F([Connector saved]) + D -- Present --> N{"Enabled?"} + N -- No --> F([Connector saved]) + N -- Yes --> G{"Authenticate with the
      submitted credentials"} + G -- Fails --> E + G -- Succeeds --> H{"At least one organization
      visible?"} + H -- No / fails --> E + H -- Yes --> F ``` --- -Looking for the full endpoint list, status mapping table, or implementation-level detail behind -these diagrams? See +## Order status mapping + +MarkMonitor order statuses are mapped to Keyfactor statuses as follows: + +| MarkMonitor order status | Keyfactor status | +|---|---| +| `DIGI_PENDING`, `DIGI_PROCESSING`, `DIGI_REISSUE_PENDING`, `DIGI_WAITING_PICKUP`, `REISSUE_PENDING`, `DIGI_NEEDS_APPROVAL`, `REISSUE_REQUEST_PENDING` | `INPROCESS` | +| `CREATED` | `EXTERNALVALIDATION` (accepted, awaiting DCV/issuance) | +| `DIGI_ISSUED` | `GENERATED` (issued) | +| `DIGI_REVOKED` | `REVOKED` | +| `DIGI_FAILED`, `DIGI_REISSUE_FAILED` | `FAILED` | +| `DIGI_CANCELED`, `DIGI_REJECTED`, `DIGI_EXPIRED`, `DIGI_NEEDS_CSR` | `CANCELLED` | +| *(null/empty or unrecognized status)* | `FAILED` | + +A freshly-submitted order (`CREATED`) is deliberately mapped to `EXTERNALVALIDATION` rather than a +failure status — the order was accepted by MarkMonitor and is simply awaiting DCV or issuance. Once +the order reaches `DIGI_ISSUED`, the next synchronization imports the certificate. + +## API endpoint reference + +| Operation | MarkMonitor API endpoint | +|---|---| +| Authenticate / obtain bearer token | `POST /auth/v1/auth/authenticate` (with `X-API-KEY` header) | +| List certificate orders (sync) | `GET /certs/v1/order` (paginated via `page`/`size`) | +| Get a single order | `GET /certs/v1/order/{orderId}` | +| Place a new order (enroll) | `POST /certs/v1/order` | +| Revoke a certificate | `PATCH /certs/v1/order/{orderId}/revoke` | +| Cancel an order | `PATCH /certs/v1/order/{orderId}/cancel` | +| Reissue a certificate | `PATCH /certs/v1/order/{orderId}/reissue` | +| List organizations | `GET /certs/v1/organization` (paginated) | +| Get an organization | `GET /certs/v1/organization/{orgId}` | +| List groups | `GET /auth/v1/group` (paginated) | + +The cancel and reissue endpoints exist in the client but aren't currently used — a renewal/reissue +places a new order and then revokes the prior certificate, rather than calling MarkMonitor's own +reissue action. + +--- + +Looking for implementation-level detail behind these diagrams — real class and method names, retry +and locking behavior, template-parameter resolution rules? See [`DEVELOPMENT.md`](https://github.com/Keyfactor/markmonitor-caplugin/blob/main/DEVELOPMENT.md) in the repository. diff --git a/docsource/CODEMAP.md b/docsource/CODEMAP.md index f4a9946..bd08726 100644 --- a/docsource/CODEMAP.md +++ b/docsource/CODEMAP.md @@ -9,7 +9,7 @@ > product IDs. Keep it terse and accurate; a stale codemap is worse than none. This file is committed > to the repo -Last verified against the codebase: 2026-08-12. +Last verified against the codebase: 2026-08-13. > To understand behavior, read this CODEMAP + the source it points to — **not** the root `README.md` > (it's a generated artifact; parsing it wastes tokens). A CI check fails a PR that changes plugin @@ -153,33 +153,43 @@ service. - `docs/` — the customer-facing GitHub Pages site (Jekyll + the `just-the-docs` remote theme, Keyfactor-branded via `docs/_sass/color_schemes/keyfactor.scss`), published from `main`/`docs` with - no Actions workflow. **Not** generated from `docsource/` — its five pages (`index.md`, - `overview.md`, `installation.md`, `configuration.md`, `changelog.md`) carry independently-written, - lighter-tone copy aimed at customers, and its own copies of the screenshots under - `docs/assets/images/` (copied from `docsource/images/`, not symlinked). When a connector field, - enrollment parameter, or product ID changes, update both `docsource/configuration.md` (feeds - `README.md`) **and** `docs/configuration.md` (feeds the Pages site) — they are two separate, - hand-maintained copies by design, not one generating the other. `docs/changelog.md` only links out - to the root `CHANGELOG.md`; Jekyll's build root is `docs/`, so it cannot `include_relative` a file - outside that directory. Preview it locally before publishing with `just docs-preview` (needs - Docker; runs Jekyll via the `jekyll/jekyll` image, no local Ruby toolchain required) at - `http://localhost:4000/markmonitor-caplugin/`; `docs/Gemfile` pins the plugins (`jekyll-remote-theme`, - `jekyll-seo-tag`, `jekyll-include-cache`) `just-the-docs` needs that aren't in the base image. -- `docsource/configuration.md` and `docsource/overview.md` — source-of-truth, customer-facing doc - fragments, plus this `CODEMAP.md`. Root `README.md` is **generated by doctool** - (`Keyfactor/doctooldotnet`, cloned at `~/RiderProjects/doctooldotnet`) from `docsource/ - configuration.md` + `integration-manifest.json` — never hand-edit `README.md`; edit - `docsource/configuration.md` and regenerate: + no Actions workflow. **Not** generated from `docsource/` — its six pages (`index.md`, + `overview.md`, `installation.md`, `configuration.md`, `architecture.md`, `changelog.md`) carry + independently-written, lighter-tone copy aimed at customers, and its own copies of the screenshots + under `docs/assets/images/` (copied from `docsource/images/`, not symlinked). When a connector + field, enrollment parameter, or product ID changes, update both `docsource/configuration.md` (feeds + `README.md`) **and** `docs/configuration.md` (feeds the Pages site); when a lifecycle diagram + changes, update both `docsource/architecture.md` **and** `docs/architecture.md` the same way — each + pair is two separate, hand-maintained copies by design, not one generating the other, so it's easy + for one to drift stale while the other moves on (this happened once already — `docs/architecture.md` + sat frozen through a `PickupRetries` polling change and a live connector-validation check landing in + `docsource/architecture.md`/`DEVELOPMENT.md` — diff the two by eye when touching either). + `docs/changelog.md` only links out to the root `CHANGELOG.md`; Jekyll's build root is `docs/`, so it + cannot `include_relative` a file outside that directory. Preview it locally before publishing with + `just docs-preview` (needs Docker; runs Jekyll via the `jekyll/jekyll` image, no local Ruby + toolchain required) at `http://localhost:4000/markmonitor-caplugin/`; `docs/Gemfile` pins the + plugins (`jekyll-remote-theme`, `jekyll-seo-tag`, `jekyll-include-cache`) `just-the-docs` needs that + aren't in the base image. +- `docsource/configuration.md`, `docsource/overview.md`, and `docsource/architecture.md` — + source-of-truth, customer-facing doc fragments, plus this `CODEMAP.md`. Root `README.md` is + **generated by doctool** (`Keyfactor/doctooldotnet`, cloned at `~/RiderProjects/doctooldotnet`) + from `docsource/configuration.md` + `integration-manifest.json` — never hand-edit `README.md`; edit + the docsource fragment and regenerate: `cd ~/RiderProjects/doctooldotnet && just build && just docs markmonitor-caplugin`. - Only `configuration.md` (including its hand-written `## How It Works` custom section) and the - manifest feed the README; `overview.md` stays standalone. Images referenced from + `configuration.md` ends with `{% include 'architecture.md' %}` (matching the pattern other AnyCA + plugins in this org use, e.g. certinext-caplugin) so the diagrams/tables in `architecture.md` are + inlined into the generated README as its `## Architecture` section — edit `architecture.md` + directly, not a copy pasted into `configuration.md`. `overview.md` stays standalone (its + Troubleshooting section is not pulled into the README by anything). Images referenced from `configuration.md` must use `docsource/images/...`. (`readme_source.md` is a stale placeholder and is not used.) - Root `DEVELOPMENT.md` is the hand-maintained developer guide (solution layout, build/test, - `TestConsole` smoke-testing, and full architecture/design internals with real class and method - names) — like `LICENSE`, it is **not** part of the doctool pipeline and is edited directly. - `docsource/architecture.md`, `docsource/development.md`, and the internal-only - `docsource/enrollment.md` have been removed/merged into it (the MarkMonitor login walkthrough in - the old `enrollment.md` now lives in an internal Confluence doc, not this repo). + `TestConsole` smoke-testing) — like `LICENSE`, it is **not** part of the doctool pipeline and is + edited directly. Its own `## Architecture` section is a *second, deeper tier* of the same diagrams + in `docsource/architecture.md` — same lifecycle operations, but annotated with real method/class + names for developers, and it deliberately cross-references `README.md`'s Component Overview diagram + and Order Status Mapping/API Endpoint Reference tables rather than re-embedding them. When a + lifecycle flow changes, update **both** tiers: `docsource/architecture.md` (plain-English, customer + tier) and `DEVELOPMENT.md`'s `## Architecture` section (method-level, developer tier). - `integration-manifest.json` — catalog metadata (`product_ids`, `ca_plugin_config`, `enrollment_config`). Keep aligned with `MarkMonitorCAPluginConfig.cs` and `CertOrderTypes`. diff --git a/docsource/architecture.md b/docsource/architecture.md new file mode 100644 index 0000000..fa16cf5 --- /dev/null +++ b/docsource/architecture.md @@ -0,0 +1,280 @@ +## Architecture + +This document describes how the MarkMonitor AnyCA Gateway REST plugin integrates with Keyfactor Command and the MarkMonitor SSL certificate API. It covers the primary certificate lifecycle operations — synchronization, enrollment, and revocation — and how the plugin routes each through the MarkMonitor REST API. + +## Component Overview + +``` +┌─────────────────────────────────────────────────────────┐ +│ Keyfactor Command │ +│ │ +│ Certificate Enrollment · Revocation · Sync Jobs │ +└────────────────────────────┬─────────────────────────────┘ + │ + AnyCA Gateway REST + (plugin host process) + │ +┌────────────────────────────▼─────────────────────────────┐ +│ The MarkMonitor plugin │ +│ │ +│ Translates Keyfactor operations into MarkMonitor API │ +│ calls and maps responses back to Command's data model. │ +└────────────────────────────┬─────────────────────────────┘ + │ HTTPS · Bearer token + X-API-KEY + │ +┌────────────────────────────▼─────────────────────────────┐ +│ MarkMonitor REST API (DigiCert) │ +│ │ +│ /auth/v1/auth/authenticate /certs/v1/order │ +│ /certs/v1/organization /auth/v1/group │ +└──────────────────────────────────────────────────────────┘ +``` + +## Request Authentication + +MarkMonitor uses two credentials together. The API key is sent as the `X-API-KEY` header on the authentication request; the service-account username and password are POSTed to `/auth/v1/auth/authenticate`, which returns a bearer token and its lifetime. Every subsequent request carries that token in an `Authorization: Bearer` header. + +``` +Authorization: Bearer where token ← POST /auth/v1/auth/authenticate + headers: X-API-KEY: + body: { username, password } +``` + +The token is cached for the lifetime of the plugin's API client and refreshed automatically shortly before it expires — a normal enrollment, sync, or revoke call never has to authenticate explicitly. There is no OAuth client-credentials mode. + +## Certificate Identifiers + +MarkMonitor identifies each order by a **GUID order ID**. That order ID is what the plugin stores in Keyfactor Command as the request identifier, and it is the identifier used for every post-enrollment operation (status check, revoke). Any order ID arriving from Command is validated as a GUID before use. + +The configured organization (`OrgId`) may be supplied either as a friendly **name** or as a **GUID** — the plugin resolves a name to its GUID by listing organizations and matching exactly (case-insensitive); a value that already parses as a GUID is used directly. + +--- + +## Gateway Startup + +When the AnyCA Gateway loads the plugin, it deserializes the CA connection configuration first. The API client itself isn't built until the first operation needs it, and authentication is lazy on top of that — it doesn't happen until the Gateway calls `Ping()` to verify connectivity. + +```mermaid +sequenceDiagram + participant GW as AnyCA Gateway + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + GW->>Plugin: Initialize(configProvider, certificateDataReader) + Plugin->>Plugin: Deserialize CA connection config + Note over Plugin: Client not built yet (lazy) + GW->>Plugin: Ping() + Plugin->>Plugin: Build & cache the API client (first use only) + Plugin->>API: Authenticate (API key + username/password) + API-->>Plugin: Bearer token + Plugin->>API: List organizations + API-->>Plugin: Organizations + Plugin-->>GW: Ping OK (auth works and at least one org exists) +``` + +--- + +## Synchronization + +Keyfactor Command periodically synchronizes its certificate inventory with MarkMonitor. The plugin retrieves all certificate orders visible to the configured organization, page by page, and imports issued certificates — along with their full certificate chain — into Command. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Start synchronization + Plugin->>API: Authenticate with MarkMonitor + + loop Retrieve one page of orders at a time + Plugin->>API: List certificate orders + API-->>Plugin: Page of order records + + loop For each order on the page + alt Order has no certificate yet + Plugin->>Plugin: Skip for this sync + else Order has a certificate + Plugin->>Plugin: Map the MarkMonitor status to a Keyfactor status + alt Unchanged since Command's last known status (and not forced) + Plugin->>Plugin: Skip re-emission + else New or changed + Plugin->>Plugin: Assemble the full certificate chain + Plugin->>CMD: Add certificate to Command's inventory + end + end + end + end + + Plugin-->>CMD: Synchronization complete (emitted / skipped-unchanged / errored counts) +``` + +> A record that fails to process is logged, counted, and skipped rather than aborting the sync - but +> the sync aborts outright if more than 25% of records fail once at least 50 have been observed. + +> The current implementation always performs a full listing of orders on each sync, rather than only +> retrieving certificates that changed since the last sync - `PageSize` optimizes the *mitigation*, not +> the listing itself: each order is compared against what Command already has for that request ID, and +> skipped (not re-emitted) when the status is unchanged, unless `ForceCompleteSync` is enabled or +> Command requests a full sync. Orders that have not yet produced a certificate are simply skipped for +> that sync rather than treated as an error. + +--- + +## Certificate Enrollment + +When a requester submits a certificate request through Keyfactor Command, the plugin translates it into a MarkMonitor order: it resolves the organization, contact, and (optional) group; validates and normalizes the CSR; and submits the order. MarkMonitor never issues synchronously from the create-order call - a newly submitted order always comes back pending (typically `CREATED`), since Domain Control Validation (and, in some environments, manual approval) is required first. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Submit certificate request + Plugin->>API: Authenticate with MarkMonitor + Plugin->>Plugin: Check for a duplicate in-flight request + + alt An identical request was already submitted / just completed + Plugin-->>CMD: Return the original result (no duplicate order placed) + else New request + Plugin->>API: Resolve organization, contact, and group + Plugin->>Plugin: Validate and normalize the CSR + Plugin->>API: Submit the certificate order + API-->>Plugin: Order accepted — order ID and status + + opt Not yet issued and PickupRetries > 0 + loop Up to PickupRetries times, every PickupDelaySeconds + Plugin->>API: Poll the order + API-->>Plugin: Current status + end + end + + alt Renewal/Reissue request + Plugin->>API: Revoke the certificate being replaced + end + + Plugin-->>CMD: Enrollment result (order ID, current status) + end +``` + +For a product whose DCV/approval resolves quickly, this polling lets the issued certificate come back in the same enrollment call instead of always waiting for the next sync; `PickupRetries=0` disables it and restores the always-returns-pending behavior. + +> A concurrent duplicate request folded into this same in-flight reservation (the "identical request +> already submitted" branch above) receives the polled result too, not just the original pending +> status - the fold happens after polling completes, not before. + +### Renewal / Reissue + +MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a Renewal/Reissue request always places a brand-new order. Once the replacement certificate has been created successfully, the plugin revokes the certificate it is replacing — but only if that certificate is within its `RenewalWindowDays` template parameter (default 90) of expiring. + +```mermaid +flowchart TD + A([Renewal / reissue enrollment]) --> B[Place a new MarkMonitor order] + B --> C{"Prior certificate
      identified?"} + C -- No --> D([Treat as a new issuance - done]) + C -- Yes --> E["Resolve the prior order"] + E --> F{"Within the configured
      renewal window?"} + F -- No --> G([Leave prior certificate unrevoked]) + F -- Yes --> H["Revoke the prior order"] + H --> I([New cert delivered, prior revoked]) + D --> I + G --> I +``` + +If the certificate being replaced can't be identified, or still has substantial life left (outside the renewal window), the request is simply treated as a new issuance and the prior certificate is left alone — a failure to revoke the old certificate never blocks delivery of the new one either. + +--- + +## Revocation + +When a certificate is revoked in Keyfactor Command, the plugin confirms that the target order belongs to the organization the CA connector is configured for before calling MarkMonitor's revoke operation. + +```mermaid +sequenceDiagram + participant CMD as Keyfactor Command + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + CMD->>Plugin: Revoke certificate + Plugin->>API: Authenticate with MarkMonitor + Plugin->>API: Look up the order's owning organization + + alt Order belongs to a different organization + Plugin-->>CMD: Error — refusing to revoke (different organization) + else Order belongs to the configured organization + Plugin->>API: Revoke the order + API-->>Plugin: Revocation confirmed + Plugin-->>CMD: Certificate marked revoked + end +``` + +> MarkMonitor's revoke operation has no field for a revocation reason code, so the reason supplied by +> Keyfactor Command cannot be forwarded to MarkMonitor. + +--- + +## Connector Validation + +When an administrator saves or edits the CA connector, the plugin checks the supplied configuration before the connector can be saved in an enabled state. + +```mermaid +flowchart TD + A([Save connector configuration]) --> B{"API Key, Username,
      Password all present?"} + B -- Missing --> E([Validation error shown to administrator]) + B -- Present --> C{"Base URL starts with https://
      (or blank → default)?"} + C -- Not https --> E + C -- OK --> D{"Organization present?"} + D -- Missing --> E + D -- Present --> N{"Enabled?"} + N -- No --> F([Connector saved]) + N -- Yes --> G{"Authenticate with the
      submitted credentials"} + G -- Fails --> E + G -- Succeeds --> H{"At least one organization
      visible?"} + H -- No / fails --> E + H -- Yes --> F +``` + +After the field checks above pass - and only if the connector is being saved enabled - the plugin also places a live call to MarkMonitor: it authenticates with the submitted (not yet saved) credentials and confirms at least one organization is visible, using a transient client built from exactly what's about to be saved — never the connector's already-cached client, which could be validating stale credentials. Saving with `Enabled` set to `false` skips this live check entirely, preserving that field's own documented purpose: creating the connector before real credentials are available. + +--- + +## Order Status Mapping + +MarkMonitor order statuses are mapped to Keyfactor statuses as follows: + +| MarkMonitor order status | Keyfactor status | +|---|---| +| `DIGI_PENDING`, `DIGI_PROCESSING`, `DIGI_REISSUE_PENDING`, `DIGI_WAITING_PICKUP`, `REISSUE_PENDING`, `DIGI_NEEDS_APPROVAL`, `REISSUE_REQUEST_PENDING` | `INPROCESS` | +| `CREATED` | `EXTERNALVALIDATION` (accepted, awaiting DCV/issuance) | +| `DIGI_ISSUED` | `GENERATED` (issued) | +| `DIGI_REVOKED` | `REVOKED` | +| `DIGI_FAILED`, `DIGI_REISSUE_FAILED` | `FAILED` | +| `DIGI_CANCELED`, `DIGI_REJECTED`, `DIGI_EXPIRED`, `DIGI_NEEDS_CSR` | `CANCELLED` | +| *(null/empty or unrecognized status)* | `FAILED` | + +> A freshly-submitted order (`CREATED`) is deliberately mapped to `EXTERNALVALIDATION` rather than a +> failure status — this means the order was accepted by MarkMonitor and is simply awaiting DCV or +> issuance. Once the order reaches `DIGI_ISSUED`, the next synchronization imports the certificate. + +## API Endpoint Reference + +The plugin calls the following MarkMonitor API endpoints. This is useful for firewall and network connectivity planning. + +| Operation | MarkMonitor API endpoint | +|---|---| +| Authenticate / obtain bearer token | `POST /auth/v1/auth/authenticate` (with `X-API-KEY` header) | +| List certificate orders (sync) | `GET /certs/v1/order` (paginated via `page`/`size`) | +| Get a single order | `GET /certs/v1/order/{orderId}` | +| Place a new order (enroll) | `POST /certs/v1/order` | +| Revoke a certificate | `PATCH /certs/v1/order/{orderId}/revoke` | +| Cancel an order | `PATCH /certs/v1/order/{orderId}/cancel` | +| Reissue a certificate | `PATCH /certs/v1/order/{orderId}/reissue` | +| List organizations | `GET /certs/v1/organization` (paginated) | +| Get an organization | `GET /certs/v1/organization/{orgId}` | +| List groups | `GET /auth/v1/group` (paginated) | + +> The cancel and reissue endpoints exist in the client but are not currently invoked by the +> `IAnyCAPlugin` operations — a Renewal/Reissue enrollment is implemented as a new order followed by +> revoking the prior certificate (see [Renewal / Reissue](#renewal--reissue)), not MarkMonitor's own +> reissue action. diff --git a/docsource/configuration.md b/docsource/configuration.md index cce4137..ff00d22 100644 --- a/docsource/configuration.md +++ b/docsource/configuration.md @@ -151,240 +151,4 @@ enum member with the matching `[Description]` — not editing a separate list. > account may actually order — and any per-product required fields — depend on your account's > entitlements. Confirm availability with your MarkMonitor administrator. -## How It Works - -This section describes, at a high level, how the plugin connects Keyfactor Command's certificate -lifecycle operations to the MarkMonitor SSL certificate service. - -### Component Overview - -``` -┌─────────────────────────────────────────────────────────┐ -│ Keyfactor Command │ -│ │ -│ Certificate Enrollment · Revocation · Sync Jobs │ -└────────────────────────────┬─────────────────────────────┘ - │ - AnyCA Gateway REST - (plugin host process) - │ -┌────────────────────────────▼─────────────────────────────┐ -│ The MarkMonitor plugin │ -│ │ -│ Translates Keyfactor operations into MarkMonitor API │ -│ calls and maps responses back to Command's data model. │ -└────────────────────────────┬─────────────────────────────┘ - │ HTTPS · Bearer token + X-API-KEY - │ -┌────────────────────────────▼─────────────────────────────┐ -│ MarkMonitor REST API (DigiCert) │ -│ │ -│ /auth/v1/auth/authenticate /certs/v1/order │ -│ /certs/v1/organization /auth/v1/group │ -└──────────────────────────────────────────────────────────┘ -``` - -### Synchronization - -Keyfactor Command periodically synchronizes its certificate inventory with MarkMonitor. The plugin -retrieves all certificate orders visible to the configured organization, page by page, and imports -issued certificates — along with their full certificate chain — into Command. - -```mermaid -sequenceDiagram - participant CMD as Keyfactor Command - participant Plugin as MarkMonitor plugin - participant API as MarkMonitor API - - CMD->>Plugin: Start synchronization - Plugin->>API: Authenticate with MarkMonitor - - loop Retrieve one page of orders at a time - Plugin->>API: List certificate orders - API-->>Plugin: Page of order records - - loop For each order on the page - alt Order has no certificate yet - Plugin->>Plugin: Skip for this sync - else Order has a certificate - Plugin->>Plugin: Map the MarkMonitor status to a Keyfactor status - alt Unchanged since Command's last known status (and not forced) - Plugin->>Plugin: Skip re-emission - else New or changed - Plugin->>Plugin: Assemble the full certificate chain - Plugin->>CMD: Add certificate to Command's inventory - end - end - end - end - - Plugin-->>CMD: Synchronization complete (emitted / skipped-unchanged / errored counts) -``` - -> A record that fails to process is logged, counted, and skipped rather than aborting the sync - but -> the sync aborts outright if more than 25% of records fail once at least 50 have been observed. - -> The current implementation always performs a full listing of orders on each sync, rather than only -> retrieving certificates that changed since the last sync - `PageSize` optimizes the *mitigation*, not -> the listing itself: each order is compared against what Command already has for that request ID, and -> skipped (not re-emitted) when the status is unchanged, unless `ForceCompleteSync` is enabled or -> Command requests a full sync. Orders that have not yet produced a certificate are simply skipped for -> that sync rather than treated as an error. A record that fails to process (bad status string, bad -> date, unexpected null) is logged and skipped rather than aborting the sync - but if more than 25% of -> records fail once at least 50 have been observed, the sync aborts outright rather than reporting a -> quietly near-empty "success". - -### Certificate Enrollment (including Renewal / Reissue) - -When a requester submits a certificate request through Keyfactor Command, the plugin translates it -into a MarkMonitor order: it resolves the organization, contact, and (optional) group; validates and -normalizes the CSR; and submits the order. MarkMonitor never issues synchronously from the -create-order call - a newly submitted order always comes back pending (typically `CREATED`), since -Domain Control Validation (and, in some environments, manual approval) is required first. For a -product whose DCV/approval resolves quickly, the plugin polls the order for up to `PickupRetries` -attempts (every `PickupDelaySeconds`) before returning, so Command can get the issued certificate -back from the enroll call itself rather than always waiting for the next sync; `PickupRetries=0` -disables this and restores the original always-returns-pending behavior. Each poll is a single -attempt, but if MarkMonitor is slow to respond (rather than erroring) it can still take up to -`TimeoutSeconds` per attempt - size any upstream timeout around `PickupRetries * (PickupDelaySeconds -+ TimeoutSeconds)`, the real worst case, not just `PickupRetries * PickupDelaySeconds`. - -```mermaid -sequenceDiagram - participant CMD as Keyfactor Command - participant Plugin as MarkMonitor plugin - participant API as MarkMonitor API - - CMD->>Plugin: Submit certificate request - Plugin->>API: Authenticate with MarkMonitor - Plugin->>Plugin: Check for a duplicate in-flight request - - alt An identical request was already submitted / just completed - Plugin-->>CMD: Return the original result (no duplicate order placed) - else New request - Plugin->>API: Resolve organization, contact, and group - Plugin->>Plugin: Validate and normalize the CSR - Plugin->>API: Submit the certificate order - API-->>Plugin: Order accepted — order ID and status - - opt Not yet issued and PickupRetries > 0 - loop Up to PickupRetries times, every PickupDelaySeconds - Plugin->>API: Poll the order - API-->>Plugin: Current status - end - end - - alt Renewal/Reissue request - Plugin->>API: Revoke the certificate being replaced - end - - Plugin-->>CMD: Enrollment result (order ID, current status) - end -``` - -> A concurrent duplicate request folded into this same in-flight reservation (the "identical request -> already submitted" branch above) receives the polled result too, not just the original pending -> status - the fold happens after polling completes, not before. - -MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a Renewal/Reissue -request always places a brand-new order. Once the replacement certificate has been created -successfully, the plugin revokes the certificate it is replacing — but only if that certificate is -within its `RenewalWindowDays` template parameter (default 90) of expiring. If the certificate being -replaced can't be identified, or still has substantial life left (outside the renewal window), the -request is simply treated as a new issuance and the prior certificate is left alone — a failure to -revoke the old certificate never blocks delivery of the new one either. - -### Revocation - -When a certificate is revoked in Keyfactor Command, the plugin confirms that the target order belongs -to the organization the CA connector is configured for before calling MarkMonitor's revoke operation. - -```mermaid -sequenceDiagram - participant CMD as Keyfactor Command - participant Plugin as MarkMonitor plugin - participant API as MarkMonitor API - - CMD->>Plugin: Revoke certificate - Plugin->>API: Authenticate with MarkMonitor - Plugin->>API: Look up the order's owning organization - - alt Order belongs to a different organization - Plugin-->>CMD: Error — refusing to revoke (different organization) - else Order belongs to the configured organization - Plugin->>API: Revoke the order - API-->>Plugin: Revocation confirmed - Plugin-->>CMD: Certificate marked revoked - end -``` - -> MarkMonitor's revoke operation has no field for a revocation reason code, so the reason supplied by -> Keyfactor Command cannot be forwarded to MarkMonitor. - -### Connector Validation - -When an administrator saves or edits the CA connector, the plugin checks the supplied configuration -before the connector can be saved in an enabled state. - -```mermaid -flowchart TD - A([Save connector configuration]) --> B{"API Key, Username,
      Password all present?"} - B -- Missing --> E([Validation error shown to administrator]) - B -- Present --> C{"Base URL starts with https://
      (or blank → default)?"} - C -- Not https --> E - C -- OK --> D{"Organization present?"} - D -- Missing --> E - D -- Present --> N{"Enabled?"} - N -- No --> F([Connector saved]) - N -- Yes --> G{"Authenticate with the
      submitted credentials"} - G -- Fails --> E - G -- Succeeds --> H{"At least one organization
      visible?"} - H -- No / fails --> E - H -- Yes --> F -``` - -After the field checks above pass - and only if the connector is being saved enabled - the plugin -also places a live call to MarkMonitor: it authenticates with the submitted (not yet saved) -credentials and confirms at least one organization is visible, using a transient client built from -exactly what's about to be saved — never the connector's already-cached client, which could be -validating stale credentials. Saving with `Enabled` set to `false` skips this live check entirely, -preserving that field's own documented purpose: creating the connector before real credentials are -available. A failure at any step (parsing the submitted configuration, authenticating, or listing -organizations) is summarized rather than forwarding the raw HTTP response or exception detail, which -could otherwise leak transport-layer detail to the UI. - -### Order Status Mapping - -MarkMonitor order statuses are mapped to Keyfactor statuses as follows: - -| MarkMonitor order status | Keyfactor status | -|---|---| -| `DIGI_PENDING`, `DIGI_PROCESSING`, `DIGI_REISSUE_PENDING`, `DIGI_WAITING_PICKUP`, `REISSUE_PENDING`, `DIGI_NEEDS_APPROVAL`, `REISSUE_REQUEST_PENDING` | `INPROCESS` | -| `CREATED` | `EXTERNALVALIDATION` (accepted, awaiting DCV/issuance) | -| `DIGI_ISSUED` | `GENERATED` (issued) | -| `DIGI_REVOKED` | `REVOKED` | -| `DIGI_FAILED`, `DIGI_REISSUE_FAILED` | `FAILED` | -| `DIGI_CANCELED`, `DIGI_REJECTED`, `DIGI_EXPIRED`, `DIGI_NEEDS_CSR` | `CANCELLED` | -| *(null/empty or unrecognized status)* | `FAILED` | - -> A freshly-submitted order (`CREATED`) is deliberately mapped to `EXTERNALVALIDATION` rather than a -> failure status — this means the order was accepted by MarkMonitor and is simply awaiting DCV or -> issuance. Once the order reaches `DIGI_ISSUED`, the next synchronization imports the certificate. - -### API Endpoint Reference - -The plugin calls the following MarkMonitor API endpoints. This is useful for firewall and network -connectivity planning. - -| Operation | MarkMonitor API endpoint | -|---|---| -| Authenticate / obtain bearer token | `POST /auth/v1/auth/authenticate` (with `X-API-KEY` header) | -| List certificate orders (sync) | `GET /certs/v1/order` (paginated via `page`/`size`) | -| Get a single order | `GET /certs/v1/order/{orderId}` | -| Place a new order (enroll) | `POST /certs/v1/order` | -| Revoke a certificate | `PATCH /certs/v1/order/{orderId}/revoke` | -| Cancel an order | `PATCH /certs/v1/order/{orderId}/cancel` | -| Reissue a certificate | `PATCH /certs/v1/order/{orderId}/reissue` | -| List organizations | `GET /certs/v1/organization` (paginated) | -| Get an organization | `GET /certs/v1/organization/{orgId}` | -| List groups | `GET /auth/v1/group` (paginated) | +{% include 'architecture.md' %} diff --git a/docsource/overview.md b/docsource/overview.md index 0800c72..0a2b59d 100644 --- a/docsource/overview.md +++ b/docsource/overview.md @@ -4,8 +4,8 @@ The MarkMonitor AnyCA Gateway REST plugin extends the certificate lifecycle capa MarkMonitor SSL certificate service to Keyfactor Command via the Keyfactor AnyCA Gateway REST. It implements `IAnyCAPlugin` and is loaded as a DLL extension by the AnyCA Gateway REST host process — it is not a standalone service. See [configuration.md](configuration.md) for full installation and -configuration details, and [DEVELOPMENT.md](../DEVELOPMENT.md) for design notes, local development, -and testing. +configuration details, [architecture.md](architecture.md) for design notes, and +[DEVELOPMENT.md](../DEVELOPMENT.md) for local development and testing. The plugin supports the following capabilities: From de7ed34b23554dcfbb6ef6946de8011c87694290 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 14 Aug 2026 01:54:58 +0000 Subject: [PATCH 3/8] docs: auto-generate README and documentation [skip ci] --- README.md | 149 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index e55d6ae..00c575a 100644 --- a/README.md +++ b/README.md @@ -245,12 +245,11 @@ enum member with the matching `[Description]` — not editing a separate list. > account may actually order — and any per-product required fields — depend on your account's > entitlements. Confirm availability with your MarkMonitor administrator. -## How It Works +## Architecture -This section describes, at a high level, how the plugin connects Keyfactor Command's certificate -lifecycle operations to the MarkMonitor SSL certificate service. +This document describes how the MarkMonitor AnyCA Gateway REST plugin integrates with Keyfactor Command and the MarkMonitor SSL certificate API. It covers the primary certificate lifecycle operations — synchronization, enrollment, and revocation — and how the plugin routes each through the MarkMonitor REST API. -### Component Overview +## Component Overview ``` ┌─────────────────────────────────────────────────────────┐ @@ -278,11 +277,53 @@ lifecycle operations to the MarkMonitor SSL certificate service. └──────────────────────────────────────────────────────────┘ ``` -### Synchronization +## Request Authentication -Keyfactor Command periodically synchronizes its certificate inventory with MarkMonitor. The plugin -retrieves all certificate orders visible to the configured organization, page by page, and imports -issued certificates — along with their full certificate chain — into Command. +MarkMonitor uses two credentials together. The API key is sent as the `X-API-KEY` header on the authentication request; the service-account username and password are POSTed to `/auth/v1/auth/authenticate`, which returns a bearer token and its lifetime. Every subsequent request carries that token in an `Authorization: Bearer` header. + +``` +Authorization: Bearer where token ← POST /auth/v1/auth/authenticate + headers: X-API-KEY: + body: { username, password } +``` + +The token is cached for the lifetime of the plugin's API client and refreshed automatically shortly before it expires — a normal enrollment, sync, or revoke call never has to authenticate explicitly. There is no OAuth client-credentials mode. + +## Certificate Identifiers + +MarkMonitor identifies each order by a **GUID order ID**. That order ID is what the plugin stores in Keyfactor Command as the request identifier, and it is the identifier used for every post-enrollment operation (status check, revoke). Any order ID arriving from Command is validated as a GUID before use. + +The configured organization (`OrgId`) may be supplied either as a friendly **name** or as a **GUID** — the plugin resolves a name to its GUID by listing organizations and matching exactly (case-insensitive); a value that already parses as a GUID is used directly. + +--- + +## Gateway Startup + +When the AnyCA Gateway loads the plugin, it deserializes the CA connection configuration first. The API client itself isn't built until the first operation needs it, and authentication is lazy on top of that — it doesn't happen until the Gateway calls `Ping()` to verify connectivity. + +```mermaid +sequenceDiagram + participant GW as AnyCA Gateway + participant Plugin as MarkMonitor plugin + participant API as MarkMonitor API + + GW->>Plugin: Initialize(configProvider, certificateDataReader) + Plugin->>Plugin: Deserialize CA connection config + Note over Plugin: Client not built yet (lazy) + GW->>Plugin: Ping() + Plugin->>Plugin: Build & cache the API client (first use only) + Plugin->>API: Authenticate (API key + username/password) + API-->>Plugin: Bearer token + Plugin->>API: List organizations + API-->>Plugin: Organizations + Plugin-->>GW: Ping OK (auth works and at least one org exists) +``` + +--- + +## Synchronization + +Keyfactor Command periodically synchronizes its certificate inventory with MarkMonitor. The plugin retrieves all certificate orders visible to the configured organization, page by page, and imports issued certificates — along with their full certificate chain — into Command. ```mermaid sequenceDiagram @@ -323,25 +364,13 @@ sequenceDiagram > the listing itself: each order is compared against what Command already has for that request ID, and > skipped (not re-emitted) when the status is unchanged, unless `ForceCompleteSync` is enabled or > Command requests a full sync. Orders that have not yet produced a certificate are simply skipped for -> that sync rather than treated as an error. A record that fails to process (bad status string, bad -> date, unexpected null) is logged and skipped rather than aborting the sync - but if more than 25% of -> records fail once at least 50 have been observed, the sync aborts outright rather than reporting a -> quietly near-empty "success". - -### Certificate Enrollment (including Renewal / Reissue) - -When a requester submits a certificate request through Keyfactor Command, the plugin translates it -into a MarkMonitor order: it resolves the organization, contact, and (optional) group; validates and -normalizes the CSR; and submits the order. MarkMonitor never issues synchronously from the -create-order call - a newly submitted order always comes back pending (typically `CREATED`), since -Domain Control Validation (and, in some environments, manual approval) is required first. For a -product whose DCV/approval resolves quickly, the plugin polls the order for up to `PickupRetries` -attempts (every `PickupDelaySeconds`) before returning, so Command can get the issued certificate -back from the enroll call itself rather than always waiting for the next sync; `PickupRetries=0` -disables this and restores the original always-returns-pending behavior. Each poll is a single -attempt, but if MarkMonitor is slow to respond (rather than erroring) it can still take up to -`TimeoutSeconds` per attempt - size any upstream timeout around `PickupRetries * (PickupDelaySeconds -+ TimeoutSeconds)`, the real worst case, not just `PickupRetries * PickupDelaySeconds`. +> that sync rather than treated as an error. + +--- + +## Certificate Enrollment + +When a requester submits a certificate request through Keyfactor Command, the plugin translates it into a MarkMonitor order: it resolves the organization, contact, and (optional) group; validates and normalizes the CSR; and submits the order. MarkMonitor never issues synchronously from the create-order call - a newly submitted order always comes back pending (typically `CREATED`), since Domain Control Validation (and, in some environments, manual approval) is required first. ```mermaid sequenceDiagram @@ -376,22 +405,37 @@ sequenceDiagram end ``` +For a product whose DCV/approval resolves quickly, this polling lets the issued certificate come back in the same enrollment call instead of always waiting for the next sync; `PickupRetries=0` disables it and restores the always-returns-pending behavior. + > A concurrent duplicate request folded into this same in-flight reservation (the "identical request > already submitted" branch above) receives the polled result too, not just the original pending > status - the fold happens after polling completes, not before. -MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a Renewal/Reissue -request always places a brand-new order. Once the replacement certificate has been created -successfully, the plugin revokes the certificate it is replacing — but only if that certificate is -within its `RenewalWindowDays` template parameter (default 90) of expiring. If the certificate being -replaced can't be identified, or still has substantial life left (outside the renewal window), the -request is simply treated as a new issuance and the prior certificate is left alone — a failure to -revoke the old certificate never blocks delivery of the new one either. +### Renewal / Reissue -### Revocation +MarkMonitor has no in-place "renew" enrollment endpoint through this plugin, so a Renewal/Reissue request always places a brand-new order. Once the replacement certificate has been created successfully, the plugin revokes the certificate it is replacing — but only if that certificate is within its `RenewalWindowDays` template parameter (default 90) of expiring. -When a certificate is revoked in Keyfactor Command, the plugin confirms that the target order belongs -to the organization the CA connector is configured for before calling MarkMonitor's revoke operation. +```mermaid +flowchart TD + A([Renewal / reissue enrollment]) --> B[Place a new MarkMonitor order] + B --> C{"Prior certificate
      identified?"} + C -- No --> D([Treat as a new issuance - done]) + C -- Yes --> E["Resolve the prior order"] + E --> F{"Within the configured
      renewal window?"} + F -- No --> G([Leave prior certificate unrevoked]) + F -- Yes --> H["Revoke the prior order"] + H --> I([New cert delivered, prior revoked]) + D --> I + G --> I +``` + +If the certificate being replaced can't be identified, or still has substantial life left (outside the renewal window), the request is simply treated as a new issuance and the prior certificate is left alone — a failure to revoke the old certificate never blocks delivery of the new one either. + +--- + +## Revocation + +When a certificate is revoked in Keyfactor Command, the plugin confirms that the target order belongs to the organization the CA connector is configured for before calling MarkMonitor's revoke operation. ```mermaid sequenceDiagram @@ -415,10 +459,11 @@ sequenceDiagram > MarkMonitor's revoke operation has no field for a revocation reason code, so the reason supplied by > Keyfactor Command cannot be forwarded to MarkMonitor. -### Connector Validation +--- + +## Connector Validation -When an administrator saves or edits the CA connector, the plugin checks the supplied configuration -before the connector can be saved in an enabled state. +When an administrator saves or edits the CA connector, the plugin checks the supplied configuration before the connector can be saved in an enabled state. ```mermaid flowchart TD @@ -437,17 +482,11 @@ flowchart TD H -- Yes --> F ``` -After the field checks above pass - and only if the connector is being saved enabled - the plugin -also places a live call to MarkMonitor: it authenticates with the submitted (not yet saved) -credentials and confirms at least one organization is visible, using a transient client built from -exactly what's about to be saved — never the connector's already-cached client, which could be -validating stale credentials. Saving with `Enabled` set to `false` skips this live check entirely, -preserving that field's own documented purpose: creating the connector before real credentials are -available. A failure at any step (parsing the submitted configuration, authenticating, or listing -organizations) is summarized rather than forwarding the raw HTTP response or exception detail, which -could otherwise leak transport-layer detail to the UI. +After the field checks above pass - and only if the connector is being saved enabled - the plugin also places a live call to MarkMonitor: it authenticates with the submitted (not yet saved) credentials and confirms at least one organization is visible, using a transient client built from exactly what's about to be saved — never the connector's already-cached client, which could be validating stale credentials. Saving with `Enabled` set to `false` skips this live check entirely, preserving that field's own documented purpose: creating the connector before real credentials are available. -### Order Status Mapping +--- + +## Order Status Mapping MarkMonitor order statuses are mapped to Keyfactor statuses as follows: @@ -465,10 +504,9 @@ MarkMonitor order statuses are mapped to Keyfactor statuses as follows: > failure status — this means the order was accepted by MarkMonitor and is simply awaiting DCV or > issuance. Once the order reaches `DIGI_ISSUED`, the next synchronization imports the certificate. -### API Endpoint Reference +## API Endpoint Reference -The plugin calls the following MarkMonitor API endpoints. This is useful for firewall and network -connectivity planning. +The plugin calls the following MarkMonitor API endpoints. This is useful for firewall and network connectivity planning. | Operation | MarkMonitor API endpoint | |---|---| @@ -483,6 +521,11 @@ connectivity planning. | Get an organization | `GET /certs/v1/organization/{orgId}` | | List groups | `GET /auth/v1/group` (paginated) | +> The cancel and reissue endpoints exist in the client but are not currently invoked by the +> `IAnyCAPlugin` operations — a Renewal/Reissue enrollment is implemented as a new order followed by +> revoking the prior certificate (see [Renewal / Reissue](#renewal--reissue)), not MarkMonitor's own +> reissue action. + ## License Apache License 2.0, see [LICENSE](LICENSE). From 67cb9d3269b95f101183d86d1fcddcaed6e7e2c6 Mon Sep 17 00:00:00 2001 From: spbsoluble <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 13 Aug 2026 19:15:20 -0700 Subject: [PATCH 4/8] chore: add Apache-2.0 license headers, address PR review feedback - Add/update the 2026 Apache-2.0 header on every .cs file in the solution (plugin, unit tests, integration tests, TestConsole). - Bump AssemblyCopyright to 2026. - Remove the dead net6.0 ItemGroup from markmonitor-caplugin.csproj. - Remove a commented-out LogTrace call that would have logged the raw (unmasked) CA connection config, including apiKey/apiPassword, if ever re-enabled. - Add README.md for markmonitor-caplugin.Tests and markmonitor-caplugin.IntegrationTests. --- TestConsole/Helpers/CSRGenerator.cs | 14 ++++++++++ TestConsole/Helpers/CertificateGenerator.cs | 14 ++++++++++ .../Helpers/DistinguishedNameGenerator.cs | 14 ++++++++++ TestConsole/Helpers/EmailAddressGenerator.cs | 14 ++++++++++ TestConsole/Helpers/TitleCaseConverter.cs | 14 ++++++++++ TestConsole/Program.cs | 16 +++++++++++- .../MarkMonitorClientAuthenticateLiveTests.cs | 14 ++++++++++ .../MarkMonitorClientEnrollLiveTests.cs | 14 ++++++++++ ...torClientListCertificateOrdersLiveTests.cs | 14 ++++++++++ .../MarkMonitorClientListOrgsLiveTests.cs | 14 ++++++++++ .../LiveApiCredentials.cs | 14 ++++++++++ .../OrderCleanup.cs | 14 ++++++++++ .../README.md | 26 +++++++++++++++++++ .../MarkMonitorClientAdditionalEmailsTests.cs | 14 ++++++++++ .../MarkMonitorClientAuthLifecycleTests.cs | 14 ++++++++++ .../MarkMonitorClientAuthenticateTests.cs | 14 ++++++++++ .../Client/MarkMonitorClientCancelTests.cs | 14 ++++++++++ .../MarkMonitorClientCleanSubjectTests.cs | 14 ++++++++++ .../Client/MarkMonitorClientDisposeTests.cs | 14 ++++++++++ ...MarkMonitorClientEnrollIdempotencyTests.cs | 14 ++++++++++ .../MarkMonitorClientEnrollLoggingTests.cs | 14 ++++++++++ .../Client/MarkMonitorClientEnrollTests.cs | 14 ++++++++++ ...MonitorClientErrorMessageRedactionTests.cs | 14 ++++++++++ .../MarkMonitorClientErrorPropagationTests.cs | 14 ++++++++++ .../MarkMonitorClientFetchOrderAuthTests.cs | 14 ++++++++++ .../MarkMonitorClientGetSingleOrderTests.cs | 14 ++++++++++ .../Client/MarkMonitorClientInventoryTests.cs | 14 ++++++++++ ...MarkMonitorClientOrderIdValidationTests.cs | 14 ++++++++++ .../MarkMonitorClientOrgResolutionTests.cs | 14 ++++++++++ .../MarkMonitorClientPickupPollingTests.cs | 14 ++++++++++ .../MarkMonitorClientQueryEncodingTests.cs | 14 ++++++++++ .../Client/MarkMonitorClientRetryTests.cs | 14 ++++++++++ .../Client/MarkMonitorClientRevokeTests.cs | 14 ++++++++++ .../Client/MarkMonitorClientSanTests.cs | 14 ++++++++++ .../MarkMonitorClientStatusMappingTests.cs | 14 ++++++++++ .../MarkMonitorClientSyncResilienceTests.cs | 14 ++++++++++ .../MarkMonitorCAPluginClientCachingTests.cs | 14 ++++++++++ .../MarkMonitorCAPluginEnrollTests.cs | 14 ++++++++++ ...MarkMonitorCAPluginGetSingleRecordTests.cs | 14 ++++++++++ .../MarkMonitorCAPluginPingTests.cs | 14 ++++++++++ .../MarkMonitorCAPluginRenewOrReissueTests.cs | 14 ++++++++++ .../MarkMonitorCAPluginRevokeTests.cs | 14 ++++++++++ ...itorCAPluginValidateConnectionInfoTests.cs | 14 ++++++++++ ...MonitorCAPluginValidateProductInfoTests.cs | 14 ++++++++++ .../MarkMonitorConfigTests.cs | 14 ++++++++++ .../Models/TokenResponseTests.cs | 14 ++++++++++ markmonitor-caplugin.Tests/README.md | 13 ++++++++++ .../TestHelpers/CapturingLoggerFactory.cs | 14 ++++++++++ .../FakeAnyCAPluginConfigProvider.cs | 14 ++++++++++ .../TestHelpers/FakeCertificateDataReader.cs | 14 ++++++++++ .../TestHelpers/FakeHttpMessageHandler.cs | 14 ++++++++++ .../LogHandlerFactoryCollection.cs | 14 ++++++++++ .../TestHelpers/ManualTimeProvider.cs | 14 ++++++++++ .../TestHelpers/SampleConfig.cs | 14 ++++++++++ .../TestHelpers/SampleCsr.cs | 14 ++++++++++ .../TestHelpers/SampleCsr2.cs | 14 ++++++++++ .../TestHelpers/SampleCsrWithSans.cs | 14 ++++++++++ .../TestHelpers/SampleEccCsrs.cs | 14 ++++++++++ .../TestHelpers/SampleOrders.cs | 14 ++++++++++ .../TestHelpers/SampleOrgs.cs | 14 ++++++++++ .../Client/MarkMonitorClient.cs | 16 +++++++++++- markmonitor-caplugin/LogSanitizer.cs | 14 ++++++++++ .../MarkMonitorCAConnector.cs | 9 +++---- .../MarkMonitorCAPluginConfig.cs | 8 +++--- markmonitor-caplugin/MarkMonitorConfig.cs | 8 +++--- markmonitor-caplugin/Models/Enums.cs | 16 +++++++++++- .../Models/MarkMonitorCommon.cs | 14 ++++++++++ .../Models/MarkMonitorGetContactResponse.cs | 14 ++++++++++ .../MarkMonitorGetOrganizationResponse.cs | 14 ++++++++++ .../MarkMonitorListCertificatesResponse.cs | 14 ++++++++++ .../Models/MarkMonitorListContactsResponse.cs | 14 ++++++++++ .../Models/MarkMonitorListGroupsResponse.cs | 14 ++++++++++ .../Models/MarkMonitorListOrgsResponse.cs | 14 ++++++++++ .../Models/MarkMonitorOrder.cs | 14 ++++++++++ .../Models/MarkMonitorOrderRequest.cs | 14 ++++++++++ .../Models/MarkMonitorReissueRequest.cs | 14 ++++++++++ markmonitor-caplugin/Models/TokenRequest.cs | 16 +++++++++++- markmonitor-caplugin/Models/TokenResponse.cs | 16 +++++++++++- .../Properties/AssemblyInfo.cs | 18 +++++++++++-- .../markmonitor-caplugin.csproj | 7 ----- 80 files changed, 1094 insertions(+), 27 deletions(-) create mode 100644 markmonitor-caplugin.IntegrationTests/README.md create mode 100644 markmonitor-caplugin.Tests/README.md diff --git a/TestConsole/Helpers/CSRGenerator.cs b/TestConsole/Helpers/CSRGenerator.cs index 37e2afa..81f885d 100644 --- a/TestConsole/Helpers/CSRGenerator.cs +++ b/TestConsole/Helpers/CSRGenerator.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; diff --git a/TestConsole/Helpers/CertificateGenerator.cs b/TestConsole/Helpers/CertificateGenerator.cs index aa0dfd5..d952020 100644 --- a/TestConsole/Helpers/CertificateGenerator.cs +++ b/TestConsole/Helpers/CertificateGenerator.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X509; diff --git a/TestConsole/Helpers/DistinguishedNameGenerator.cs b/TestConsole/Helpers/DistinguishedNameGenerator.cs index ab38696..f6ff3f8 100644 --- a/TestConsole/Helpers/DistinguishedNameGenerator.cs +++ b/TestConsole/Helpers/DistinguishedNameGenerator.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Text.Json; namespace TestConsole.Helpers; diff --git a/TestConsole/Helpers/EmailAddressGenerator.cs b/TestConsole/Helpers/EmailAddressGenerator.cs index 5948ff9..918cf21 100644 --- a/TestConsole/Helpers/EmailAddressGenerator.cs +++ b/TestConsole/Helpers/EmailAddressGenerator.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace TestConsole.Helpers; public class EmailAddressGenerator : DistinguishedNameGenerator diff --git a/TestConsole/Helpers/TitleCaseConverter.cs b/TestConsole/Helpers/TitleCaseConverter.cs index 810e2e0..901ac22 100644 --- a/TestConsole/Helpers/TitleCaseConverter.cs +++ b/TestConsole/Helpers/TitleCaseConverter.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Globalization; namespace TestConsole.Helpers; diff --git a/TestConsole/Program.cs b/TestConsole/Program.cs index 3e40f14..dbae771 100644 --- a/TestConsole/Program.cs +++ b/TestConsole/Program.cs @@ -1,4 +1,18 @@ -// See https://aka.ms/new-console-template for more information +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// See https://aka.ms/new-console-template for more information using Keyfactor.Extensions.CAPlugin.MarkMonitor; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs index 6fd0641..cdad912 100644 --- a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientAuthenticateLiveTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests.Client; diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs index 1b31ad3..959fac4 100644 --- a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientEnrollLiveTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.AnyGateway.Extensions; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs index ca2dac3..38f515f 100644 --- a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListCertificateOrdersLiveTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests.Client; diff --git a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs index 6fbbcdb..445313f 100644 --- a/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs +++ b/markmonitor-caplugin.IntegrationTests/Client/MarkMonitorClientListOrgsLiveTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs b/markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs index b56bb67..969ad30 100644 --- a/markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs +++ b/markmonitor-caplugin.IntegrationTests/LiveApiCredentials.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests; /// diff --git a/markmonitor-caplugin.IntegrationTests/OrderCleanup.cs b/markmonitor-caplugin.IntegrationTests/OrderCleanup.cs index 10771d9..5663b60 100644 --- a/markmonitor-caplugin.IntegrationTests/OrderCleanup.cs +++ b/markmonitor-caplugin.IntegrationTests/OrderCleanup.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.IntegrationTests; diff --git a/markmonitor-caplugin.IntegrationTests/README.md b/markmonitor-caplugin.IntegrationTests/README.md new file mode 100644 index 0000000..b063bd2 --- /dev/null +++ b/markmonitor-caplugin.IntegrationTests/README.md @@ -0,0 +1,26 @@ +# markmonitor-caplugin.IntegrationTests + +xUnit suite that hits the **real** MarkMonitor API - authenticate, list organizations, list +certificate orders, and enroll with an RSA and an ECC CSR. Every test reads the same four +`MARKMONITOR_*` environment variables `TestConsole` uses and returns immediately (a silent pass, +not a skip/failure) when they're unset, so this project is always safe to run, including in CI +with no credentials present. + +``` +MARKMONITOR_BASE_URL +MARKMONITOR_API_TOKEN +MARKMONITOR_USERNAME +MARKMONITOR_PASSWORD +``` + +```shell +set -a && source .env && set +a # or TestConsole/.env +dotnet test markmonitor-caplugin.IntegrationTests -c Release +``` + +Each enrollment test always cancels (falling back to revoke) the order it creates - there is no +`MARKMONITOR_SKIP_CLEANUP` escape hatch here, unlike `TestConsole`. A cleanup failure throws rather +than logging a warning, so a billable order is never left behind silently. + +See [DEVELOPMENT.md](../DEVELOPMENT.md#live-integration-tests-markmonitor-caplugin-integrationtests) +for the full picture, including the manual `workflow_dispatch`-gated CI job. diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs index b27c695..948a2b7 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAdditionalEmailsTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs index a348166..9028df8 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthLifecycleTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs index 5887fb0..9d72e1d 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientAuthenticateTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs index 2feb994..cef545c 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCancelTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs index 65fb3b5..d6581ff 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientCleanSubjectTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs index 3a137c0..d627528 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientDisposeTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs index 1294890..b494721 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollIdempotencyTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs index 5191164..1e88f2d 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollLoggingTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs index 773d5e6..4c8f550 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientEnrollTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs index f4bfa92..283b568 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorMessageRedactionTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs index 2af548e..77e7e53 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientErrorPropagationTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Collections.Concurrent; using System.Net; using Keyfactor.AnyGateway.Extensions; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs index 170ab42..d8fc3e5 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientFetchOrderAuthTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs index 01d0b9e..bd0a660 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientGetSingleOrderTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs index 25e857d..b904d2f 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientInventoryTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Collections.Concurrent; using System.Net; using Keyfactor.AnyGateway.Extensions; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs index d9e4e63..0ee4e22 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrderIdValidationTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs index 3f36596..77dbb77 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientOrgResolutionTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs index 263366a..c01bf1d 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientPickupPollingTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs index d802f98..b5bd7c6 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientQueryEncodingTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs index 8b93941..67c318c 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRetryTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using System.Net.Http.Headers; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs index 60c2e97..de32388 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientRevokeTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs index 5f2c22d..dd2ffef 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSanTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs index c30d809..33ce106 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientStatusMappingTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs index 126297c..c8663ad 100644 --- a/markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs +++ b/markmonitor-caplugin.Tests/Client/MarkMonitorClientSyncResilienceTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Collections.Concurrent; using System.Net; using Keyfactor.AnyGateway.Extensions; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs index 987bcfd..b55bfb1 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginClientCachingTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs index d10a1e0..ca86a52 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginEnrollTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.AnyGateway.Extensions; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs index c148183..22efdea 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginGetSingleRecordTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs index dced1b2..588ae97 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginPingTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs index 28f9958..e4bdf08 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRenewOrReissueTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.AnyGateway.Extensions; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs index 005a600..c489acd 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginRevokeTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs index cb4c668..728db08 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateConnectionInfoTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using Keyfactor.AnyGateway.Extensions; using Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs index 0b202ce..120bedf 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorCAPluginValidateProductInfoTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.AnyGateway.Extensions; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; diff --git a/markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs b/markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs index df2f8a8..e4e11c3 100644 --- a/markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs +++ b/markmonitor-caplugin.Tests/MarkMonitorConfigTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests; public class MarkMonitorConfigTests diff --git a/markmonitor-caplugin.Tests/Models/TokenResponseTests.cs b/markmonitor-caplugin.Tests/Models/TokenResponseTests.cs index 62667af..6dbc25f 100644 --- a/markmonitor-caplugin.Tests/Models/TokenResponseTests.cs +++ b/markmonitor-caplugin.Tests/Models/TokenResponseTests.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; using Newtonsoft.Json; diff --git a/markmonitor-caplugin.Tests/README.md b/markmonitor-caplugin.Tests/README.md new file mode 100644 index 0000000..22dd426 --- /dev/null +++ b/markmonitor-caplugin.Tests/README.md @@ -0,0 +1,13 @@ +# markmonitor-caplugin.Tests + +xUnit unit-test suite for the MarkMonitor CA plugin. Exercises `MarkMonitorCAPlugin` and +`MarkMonitorClient` against a fake `HttpMessageHandler` (see `TestHelpers/FakeHttpMessageHandler.cs`) +and injected fakes (`FakeCertificateDataReader`, `FakeAnyCAPluginConfigProvider`, +`ManualTimeProvider`) - no live API or credentials required, safe to run in CI. + +```shell +dotnet test markmonitor-caplugin.sln -c Release +``` + +See [DEVELOPMENT.md](../DEVELOPMENT.md#unit-tests) for what the suite covers and the pattern to +follow when adding new tests. diff --git a/markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs b/markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs index 77856ee..0f191f3 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/CapturingLoggerFactory.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Collections.Concurrent; using Keyfactor.Logging; using Microsoft.Extensions.Logging; diff --git a/markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs b/markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs index a501904..27374a5 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/FakeAnyCAPluginConfigProvider.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.AnyGateway.Extensions; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs b/markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs index 414ffc4..d7712b9 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/FakeCertificateDataReader.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.AnyGateway.Extensions; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs b/markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs index c948b29..cb7840f 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/FakeHttpMessageHandler.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using System.Net; using System.Net.Http; using System.Text; diff --git a/markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs b/markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs index 8a05c8d..46608bd 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/LogHandlerFactoryCollection.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; /// diff --git a/markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs b/markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs index edea9a2..a0a203b 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/ManualTimeProvider.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; /// A TimeProvider with a settable clock, for deterministically testing expiry logic. diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs index b11f4db..0142930 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleConfig.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Keyfactor.Extensions.CAPlugin.MarkMonitor.Client; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs index ab7a996..7033512 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; /// A fixed, valid RSA CSR (CN=test.mmcertdomain.com) for enrollment tests. diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs index 616c888..87814fd 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleCsr2.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; /// A second, distinct valid RSA CSR (CN=other.mmcertdomain.com) for tests that need two diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs index 0bfca13..e06dbee 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleCsrWithSans.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs index 93ec2e3..849de24 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleEccCsrs.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; /// Valid ECC (P-256, CN=test.mmcertdomain.com) CSRs differing only in how the key's curve diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs index 2689223..488ea80 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleOrders.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; /// Builds minimal-but-valid MarkMonitor order JSON fragments for tests. diff --git a/markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs b/markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs index c930f60..4dae81d 100644 --- a/markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs +++ b/markmonitor-caplugin.Tests/TestHelpers/SampleOrgs.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Tests.TestHelpers; /// Builds minimal-but-valid MarkMonitor organization/contact JSON fragments for tests. diff --git a/markmonitor-caplugin/Client/MarkMonitorClient.cs b/markmonitor-caplugin/Client/MarkMonitorClient.cs index ea6d959..2e2cd61 100644 --- a/markmonitor-caplugin/Client/MarkMonitorClient.cs +++ b/markmonitor-caplugin/Client/MarkMonitorClient.cs @@ -1,4 +1,18 @@ -using System.Collections.Concurrent; +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Collections.Concurrent; using System.Diagnostics; using System.Net.Http.Headers; using System.Text; diff --git a/markmonitor-caplugin/LogSanitizer.cs b/markmonitor-caplugin/LogSanitizer.cs index 0cc249f..7c578d3 100644 --- a/markmonitor-caplugin/LogSanitizer.cs +++ b/markmonitor-caplugin/LogSanitizer.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + namespace Keyfactor.Extensions.CAPlugin.MarkMonitor; /// diff --git a/markmonitor-caplugin/MarkMonitorCAConnector.cs b/markmonitor-caplugin/MarkMonitorCAConnector.cs index 927168f..6194d78 100644 --- a/markmonitor-caplugin/MarkMonitorCAConnector.cs +++ b/markmonitor-caplugin/MarkMonitorCAConnector.cs @@ -1,11 +1,11 @@ -// Copyright 2025 Keyfactor -// +// Copyright 2026 Keyfactor +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -51,7 +51,6 @@ public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDa _certificateDataReader = certificateDataReader; var rawConfig = JsonConvert.SerializeObject(configProvider.CAConnectionData); _config = JsonConvert.DeserializeObject(rawConfig); - // _logger.LogTrace("MarkMonitorCAPlugin initialized with config: {Config}", rawConfig); _logger.MethodExit(); } diff --git a/markmonitor-caplugin/MarkMonitorCAPluginConfig.cs b/markmonitor-caplugin/MarkMonitorCAPluginConfig.cs index e9c8abd..e176f12 100644 --- a/markmonitor-caplugin/MarkMonitorCAPluginConfig.cs +++ b/markmonitor-caplugin/MarkMonitorCAPluginConfig.cs @@ -1,11 +1,11 @@ -// Copyright 2025 Keyfactor -// +// Copyright 2026 Keyfactor +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/markmonitor-caplugin/MarkMonitorConfig.cs b/markmonitor-caplugin/MarkMonitorConfig.cs index 5017b0c..76d4cef 100644 --- a/markmonitor-caplugin/MarkMonitorConfig.cs +++ b/markmonitor-caplugin/MarkMonitorConfig.cs @@ -1,11 +1,11 @@ -// Copyright 2025 Keyfactor -// +// Copyright 2026 Keyfactor +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/markmonitor-caplugin/Models/Enums.cs b/markmonitor-caplugin/Models/Enums.cs index 2f9e044..e887c1e 100644 --- a/markmonitor-caplugin/Models/Enums.cs +++ b/markmonitor-caplugin/Models/Enums.cs @@ -1,4 +1,18 @@ -using System.ComponentModel; +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.ComponentModel; using System.Reflection; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorCommon.cs b/markmonitor-caplugin/Models/MarkMonitorCommon.cs index e3c2962..82759b4 100644 --- a/markmonitor-caplugin/Models/MarkMonitorCommon.cs +++ b/markmonitor-caplugin/Models/MarkMonitorCommon.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorGetContactResponse.cs b/markmonitor-caplugin/Models/MarkMonitorGetContactResponse.cs index fdf0af0..8f5e7dd 100644 --- a/markmonitor-caplugin/Models/MarkMonitorGetContactResponse.cs +++ b/markmonitor-caplugin/Models/MarkMonitorGetContactResponse.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorGetOrganizationResponse.cs b/markmonitor-caplugin/Models/MarkMonitorGetOrganizationResponse.cs index d6ffae7..d616065 100644 --- a/markmonitor-caplugin/Models/MarkMonitorGetOrganizationResponse.cs +++ b/markmonitor-caplugin/Models/MarkMonitorGetOrganizationResponse.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorListCertificatesResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListCertificatesResponse.cs index 71eb3a0..532fbbb 100644 --- a/markmonitor-caplugin/Models/MarkMonitorListCertificatesResponse.cs +++ b/markmonitor-caplugin/Models/MarkMonitorListCertificatesResponse.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorListContactsResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListContactsResponse.cs index 4caad30..c4c5e89 100644 --- a/markmonitor-caplugin/Models/MarkMonitorListContactsResponse.cs +++ b/markmonitor-caplugin/Models/MarkMonitorListContactsResponse.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs index 66b9671..af86e73 100644 --- a/markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs +++ b/markmonitor-caplugin/Models/MarkMonitorListGroupsResponse.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorListOrgsResponse.cs b/markmonitor-caplugin/Models/MarkMonitorListOrgsResponse.cs index 7a24bc3..77403da 100644 --- a/markmonitor-caplugin/Models/MarkMonitorListOrgsResponse.cs +++ b/markmonitor-caplugin/Models/MarkMonitorListOrgsResponse.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorOrder.cs b/markmonitor-caplugin/Models/MarkMonitorOrder.cs index ba2e396..8afff24 100644 --- a/markmonitor-caplugin/Models/MarkMonitorOrder.cs +++ b/markmonitor-caplugin/Models/MarkMonitorOrder.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/MarkMonitorOrderRequest.cs b/markmonitor-caplugin/Models/MarkMonitorOrderRequest.cs index feecdf5..a9a2492 100644 --- a/markmonitor-caplugin/Models/MarkMonitorOrderRequest.cs +++ b/markmonitor-caplugin/Models/MarkMonitorOrderRequest.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; using Org.BouncyCastle.Crypto; diff --git a/markmonitor-caplugin/Models/MarkMonitorReissueRequest.cs b/markmonitor-caplugin/Models/MarkMonitorReissueRequest.cs index 7b8c039..5831c57 100644 --- a/markmonitor-caplugin/Models/MarkMonitorReissueRequest.cs +++ b/markmonitor-caplugin/Models/MarkMonitorReissueRequest.cs @@ -1,3 +1,17 @@ +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/TokenRequest.cs b/markmonitor-caplugin/Models/TokenRequest.cs index 287f9ab..cf7fc48 100644 --- a/markmonitor-caplugin/Models/TokenRequest.cs +++ b/markmonitor-caplugin/Models/TokenRequest.cs @@ -1,4 +1,18 @@ -using Newtonsoft.Json; +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Models/TokenResponse.cs b/markmonitor-caplugin/Models/TokenResponse.cs index b85eeb1..9f69671 100644 --- a/markmonitor-caplugin/Models/TokenResponse.cs +++ b/markmonitor-caplugin/Models/TokenResponse.cs @@ -1,4 +1,18 @@ -using Newtonsoft.Json; +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Newtonsoft.Json; namespace Keyfactor.Extensions.CAPlugin.MarkMonitor.Models; diff --git a/markmonitor-caplugin/Properties/AssemblyInfo.cs b/markmonitor-caplugin/Properties/AssemblyInfo.cs index 4b0ef8c..260d3e2 100644 --- a/markmonitor-caplugin/Properties/AssemblyInfo.cs +++ b/markmonitor-caplugin/Properties/AssemblyInfo.cs @@ -1,4 +1,18 @@ -using System.Reflection; +// Copyright 2026 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -12,7 +26,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("markmonitor-caplugin")] -[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/markmonitor-caplugin/markmonitor-caplugin.csproj b/markmonitor-caplugin/markmonitor-caplugin.csproj index 31a69d5..49ccc41 100644 --- a/markmonitor-caplugin/markmonitor-caplugin.csproj +++ b/markmonitor-caplugin/markmonitor-caplugin.csproj @@ -16,13 +16,6 @@ 1.0.0.0 - - - - - - - From 946db0af64de41b3cc21946a10375ef3a3ccb236 Mon Sep 17 00:00:00 2001 From: spbsoluble <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 13 Aug 2026 19:38:47 -0700 Subject: [PATCH 5/8] feat(scripts): add gateway certificate profile registration Idempotent create/update of one AnyCA REST Gateway certificate profile per product in integration-manifest.json, ported from certinext-caplugin's scripts/register/01-gateway-profiles.sh and adapted to this repo's justfile convention. Auth helpers (OAuth2 client_credentials, bearer token, or session cookie) live in scripts/lib/gateway-auth.sh. Verified against the gateway-markmonitor lab instance (DRY_RUN preview, then a real run with CHECK=1 confirming all 12 profiles present, no errors). --- justfile | 9 +++ scripts/lib/gateway-auth.sh | 110 +++++++++++++++++++++++++++ scripts/register-gateway-profiles.sh | 109 ++++++++++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100755 scripts/lib/gateway-auth.sh create mode 100755 scripts/register-gateway-profiles.sh diff --git a/justfile b/justfile index 93f5bc5..26e47b2 100644 --- a/justfile +++ b/justfile @@ -113,6 +113,15 @@ cancel-by-name common_name: -H "X-API-KEY: $MARKMONITOR_API_TOKEN" -H "Authorization: Bearer $BEARER" -H "Content-Type: application/json" -d '{}' \ | jq -r '.status // .' +# Register/update this plugin's AnyCA REST Gateway certificate profiles (one per +# product in integration-manifest.json). Needs GATEWAY_HOST + gateway auth - see +# scripts/lib/gateway-auth.sh. Set dry_run=1 to preview with no gateway calls, or +# check=1 to list resulting profiles after applying. +register-gateway-profiles dry_run="0" check="0": + #!/usr/bin/env bash + set -euo pipefail + DRY_RUN={{dry_run}} CHECK={{check}} "{{justfile_directory()}}/scripts/register-gateway-profiles.sh" + # Preview the docs/ GitHub Pages site at http://localhost:4000/markmonitor-caplugin/ (needs Docker) docs-preview: docker rm -f markmonitor-docs-preview 2>/dev/null || true diff --git a/scripts/lib/gateway-auth.sh b/scripts/lib/gateway-auth.sh new file mode 100755 index 0000000..a48a6fd --- /dev/null +++ b/scripts/lib/gateway-auth.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# Shared OAuth2 + REST helpers for talking to the AnyCA REST Gateway's admin API +# (config/certificateprofile, etc.) - not the MarkMonitor vendor API (see the +# root justfile for that). +# +# Usage: +# . "$(dirname "$0")/lib/gateway-auth.sh" +# tok=$(gateway_token) +# gw_curl "$tok" GET /config/certificateprofile +# +# Required env (export before sourcing, or set in a root .env - see justfile): +# GATEWAY_HOST gateway ingress host (no scheme) +# Auth - one of: +# GATEWAY_COOKIE a pasted browser session cookie (Portal UI auth) +# GATEWAY_TOKEN a pre-obtained bearer token +# TOKEN_URL + OIDC_CLIENT_ID + OIDC_CLIENT_SECRET OAuth2 client_credentials +# Optional env (defaults shown): +# GATEWAY_SCHEME https +# GATEWAY_BASE_PATH /AnyGatewayREST (the gateway *instance* mount path - +# on a multi-instance gateway this is instance-specific, +# e.g. /markmonitor-0 - check the Portal/Swagger URL) +# GATEWAY_SCOPE keyfactor-anyca-gateway +# CURL_INSECURE 1 (pass -k; set 0 to verify TLS) + +GATEWAY_SCHEME="${GATEWAY_SCHEME:-https}" +GATEWAY_BASE_PATH="${GATEWAY_BASE_PATH:-/AnyGatewayREST}" +GATEWAY_SCOPE="${GATEWAY_SCOPE:-keyfactor-anyca-gateway}" +CURL_INSECURE="${CURL_INSECURE:-1}" + +_gw_require() { + local missing=0 v + for v in "$@"; do + if [ -z "${!v:-}" ]; then + echo "ERROR: required env var '$v' is not set" >&2 + missing=1 + fi + done + [ "$missing" -eq 0 ] || return 1 +} + +# Base curl flags shared by every call (bash 3.2 compatible - global array). +GW_CURL_OPTS=(-sS) +[ "$CURL_INSECURE" = "1" ] && GW_CURL_OPTS+=(-k) + +# oauth_token [scope] - fetch a client_credentials bearer token. +# Echoes the raw access_token. Exits non-zero (and prints the body) on failure. +oauth_token() { + _gw_require TOKEN_URL OIDC_CLIENT_ID OIDC_CLIENT_SECRET || return 1 + local scope="${1:-}" + local -a form=( + --data-urlencode "grant_type=client_credentials" + --data-urlencode "client_id=${OIDC_CLIENT_ID}" + --data-urlencode "client_secret=${OIDC_CLIENT_SECRET}" + ) + [ -n "$scope" ] && form+=(--data-urlencode "scope=${scope}") + + local resp tok + resp=$(curl "${GW_CURL_OPTS[@]}" -X POST "$TOKEN_URL" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + "${form[@]}") || { echo "ERROR: token request failed" >&2; return 1; } + tok=$(printf '%s' "$resp" | jq -r '.access_token // empty') + if [ -z "$tok" ]; then + echo "ERROR: no access_token in response:" >&2 + printf '%s\n' "$resp" >&2 + return 1 + fi + printf '%s' "$tok" +} + +# Auth resolution order: +# 1. GATEWAY_COOKIE - a pasted browser session cookie (gw_curl sends it +# directly; this function returns empty and callers skip Authorization). +# 2. GATEWAY_TOKEN - an explicit pre-obtained bearer token. +# 3. OAuth2 client_credentials via oauth_token. +gateway_token() { + if [ -n "${GATEWAY_COOKIE:-}" ]; then return 0; fi + if [ -n "${GATEWAY_TOKEN:-}" ]; then printf '%s' "$GATEWAY_TOKEN"; return 0; fi + oauth_token "$GATEWAY_SCOPE" +} + +gw_base() { + _gw_require GATEWAY_HOST || return 1 + printf '%s://%s%s' "$GATEWAY_SCHEME" "$GATEWAY_HOST" "$GATEWAY_BASE_PATH" +} + +gw_show() { if [ -n "${GATEWAY_HOST:-}" ]; then gw_base; else printf '(GATEWAY_HOST unset)'; fi; } + +# gw_curl [data] - hits the gateway admin API. +# is relative to GATEWAY_BASE_PATH (e.g. /config/certificateprofile). Echoes +# the response body. +gw_curl() { + local tok="$1" method="$2" path="$3" data="${4:-}" + local rw="APIClient" + [ -n "${GATEWAY_COOKIE:-}" ] && rw="XMLHttpRequest" + local -a args=("${GW_CURL_OPTS[@]}" -X "$method" "$(gw_base)$path" + -H "x-keyfactor-requested-with: $rw" + -H "Content-Type: application/json") + if [ -n "${GATEWAY_COOKIE:-}" ]; then + args+=(-H "Cookie: ${GATEWAY_COOKIE}" -H "x-requested-with: XMLHttpRequest") + fi + [ -n "$tok" ] && args+=(-H "Authorization: Bearer $tok") + [ -n "$data" ] && args+=(-d "$data") + curl "${args[@]}" +} + +# manifest_product_ids [manifest-path] - emit product_ids one per line. +manifest_product_ids() { + local manifest="${1:-$REPO_ROOT/integration-manifest.json}" + jq -r '.about.carest.product_ids[]' "$manifest" +} diff --git a/scripts/register-gateway-profiles.sh b/scripts/register-gateway-profiles.sh new file mode 100755 index 0000000..55d4201 --- /dev/null +++ b/scripts/register-gateway-profiles.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +# Register AnyCA REST Gateway certificate profiles for this plugin. +# +# Creates (or updates) one gateway certificate profile per MarkMonitor product, +# driven by .about.carest.product_ids in integration-manifest.json. Idempotent: +# existing profiles (matched by name) are PUT-updated, new ones are POSTed. +# +# This only touches gateway certificate profiles (/config/certificateprofile). +# It does not register a CA connection or import Command templates - do that +# by hand (or with equivalent scripting) once profiles exist. +# +# Env: see scripts/lib/gateway-auth.sh for the auth/host contract. +# Optional: +# KEY_ALGS_JSON override the key_algs object (default: RSA + P-256/P-384/P-521 below) +# MANIFEST path to integration-manifest.json (default: repo root) +# CHECK 1 = after applying, list the resulting profile names +# DRY_RUN 1 = print intended actions, make no write calls +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +export REPO_ROOT + +# shellcheck disable=SC1090 +[ -f "$REPO_ROOT/.env" ] && . "$REPO_ROOT/.env" +# shellcheck source=lib/gateway-auth.sh +. "$SCRIPT_DIR/lib/gateway-auth.sh" + +MANIFEST="${MANIFEST:-$REPO_ROOT/integration-manifest.json}" +DRY_RUN="${DRY_RUN:-0}" +CHECK="${CHECK:-0}" + +# MarkMonitor orders are enrolled with RSA or named-curve ECC CSRs (see +# MarkMonitorClient.ValidateEccCsrUsesNamedCurve) - P-256/P-384/P-521 cover +# what TestConsole/CSRGenerator exercises. +DEFAULT_KEY_ALGS_JSON='{ + "rsa": { "bit_lengths": [2048, 3072, 4096] }, + "ecdsa": { "curves": ["1.2.840.10045.3.1.7", "1.3.132.0.34", "1.3.132.0.35"] } +}' +KEY_ALGS_JSON="${KEY_ALGS_JSON:-$DEFAULT_KEY_ALGS_JSON}" + +if ! echo "$KEY_ALGS_JSON" | jq -e . >/dev/null 2>&1; then + echo "ERROR: KEY_ALGS_JSON is not valid JSON" >&2 + exit 1 +fi + +echo "== MarkMonitor gateway certificate profiles ==" +echo " gateway : $(gw_show)" +echo " manifest: $MANIFEST" +[ "$DRY_RUN" = "1" ] && echo " DRY_RUN : no write calls will be made" + +PRODUCTS=() +while IFS= read -r _p; do + [ -n "$_p" ] && PRODUCTS+=("$_p") +done < <(manifest_product_ids "$MANIFEST") +[ "${#PRODUCTS[@]}" -gt 0 ] || { echo "ERROR: no product_ids in manifest" >&2; exit 1; } +echo " products: ${#PRODUCTS[@]}" + +if [ "$DRY_RUN" = "1" ]; then + # Fully offline preview: no token, no listing. + echo " (dry run) would upsert ${#PRODUCTS[@]} profiles with key_algs:" + echo "$KEY_ALGS_JSON" | jq -c . + for name in "${PRODUCTS[@]}"; do + printf ' [DRY ] %s\n' "$name" + done + echo "== done (dry run): no calls made ==" + exit 0 +fi + +TOK="$(gateway_token)" + +# Snapshot existing profiles once: name -> id. +EXISTING="$(gw_curl "$TOK" GET /config/certificateprofile)" +if ! echo "$EXISTING" | jq -e 'type == "array"' >/dev/null 2>&1; then + echo "ERROR: unexpected response listing certificate profiles:" >&2 + printf '%s\n' "$EXISTING" >&2 + exit 1 +fi + +created=0 updated=0 +for name in "${PRODUCTS[@]}"; do + existing_id="$(echo "$EXISTING" | jq -r --arg n "$name" \ + '.[] | select(.name == $n) | .id' | head -n1)" + + body="$(jq -n --arg name "$name" --argjson algs "$KEY_ALGS_JSON" \ + '{name: $name, key_algs: $algs}')" + + if [ -n "$existing_id" ] && [ "$existing_id" != "null" ]; then + body="$(echo "$body" | jq --argjson id "$existing_id" '. + {id: $id}')" + printf ' [PUT ] %-40s (id=%s)\n' "$name" "$existing_id" + resp="$(gw_curl "$TOK" PUT /config/certificateprofile "$body")" + echo "$resp" | jq -e 'has("error") or has("Message")' >/dev/null 2>&1 \ + && { echo " ! update failed: $resp" >&2; } + updated=$((updated + 1)) + else + printf ' [POST] %-40s (new)\n' "$name" + resp="$(gw_curl "$TOK" POST /config/certificateprofile "$body")" + echo "$resp" | jq -e 'has("error") or has("Message")' >/dev/null 2>&1 \ + && { echo " ! create failed: $resp" >&2; } + created=$((created + 1)) + fi +done + +echo "== done: $created created, $updated updated ==" + +if [ "$CHECK" = "1" ]; then + echo "== CHECK: profiles now on the gateway ==" + gw_curl "$TOK" GET /config/certificateprofile | jq -r '.[].name' | sort +fi From 314692abe8e55892a39e6ff03942242f29ef3441 Mon Sep 17 00:00:00 2001 From: spbsoluble <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 13 Aug 2026 19:42:56 -0700 Subject: [PATCH 6/8] docs: call out the gateway certificate profile registration script Customers need a gateway certificate profile per MarkMonitor product before templates can be created. Point them at scripts/register-gateway-profiles.sh as an alternative to creating each one by hand in the gateway portal. --- README.md | 18 ++++++++++++++++++ docsource/configuration.md | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/README.md b/README.md index 00c575a..395452c 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,24 @@ MarkMonitor requires **two** credentials that are used together (there is no OAu Contact your MarkMonitor administrator to provision the API key and a service account with order permissions, and to confirm the correct API base URL and organization name/ID for your environment. +## Certificate Profiles + +The AnyCA Gateway REST portal requires a **certificate profile** for each MarkMonitor product you +intend to enroll against (see [Product IDs](#product-ids)) — this is separate from both the CA +connector configuration below and the Command certificate templates created afterward. Profiles can +be created by hand in the gateway portal, or with the helper script this repo ships: + +```shell +just register-gateway-profiles # create/update one profile per product, idempotent +just register-gateway-profiles 1 # dry run — preview only, no gateway calls +``` + +The script authenticates to the gateway's admin API (OAuth2 client-credentials, a bearer token, or a +pasted browser session cookie) and reads the product list from `integration-manifest.json`, so it +stays in sync with the product IDs above without hand-entering each one. See +`scripts/register-gateway-profiles.sh` and `scripts/lib/gateway-auth.sh` for the required environment +variables. + ## CA Connection Configuration The following fields are presented in the AnyCA Gateway REST portal (and the Keyfactor Command diff --git a/docsource/configuration.md b/docsource/configuration.md index ff00d22..bb2f63c 100644 --- a/docsource/configuration.md +++ b/docsource/configuration.md @@ -68,6 +68,24 @@ running, navigate to the AnyCA Gateway REST portal and configure the CA. ![gateway_registration_store.png](docsource/images/gateway_registration_store.png) +## Certificate Profiles + +The AnyCA Gateway REST portal requires a **certificate profile** for each MarkMonitor product you +intend to enroll against (see [Product IDs](#product-ids)) — this is separate from both the CA +connector configuration below and the Command certificate templates created afterward. Profiles can +be created by hand in the gateway portal, or with the helper script this repo ships: + +```shell +just register-gateway-profiles # create/update one profile per product, idempotent +just register-gateway-profiles 1 # dry run — preview only, no gateway calls +``` + +The script authenticates to the gateway's admin API (OAuth2 client-credentials, a bearer token, or a +pasted browser session cookie) and reads the product list from `integration-manifest.json`, so it +stays in sync with the product IDs above without hand-entering each one. See +`scripts/register-gateway-profiles.sh` and `scripts/lib/gateway-auth.sh` for the required environment +variables. + ## CA Connection Configuration The following fields are presented in the AnyCA Gateway REST portal (and the Keyfactor Command From 01eef9f84a6e0c7268a684fcc1e9c6ba6b185a73 Mon Sep 17 00:00:00 2001 From: spbsoluble <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 13 Aug 2026 20:15:46 -0700 Subject: [PATCH 7/8] docs: add gateway certificate profile registration quickstart Standalone walkthrough of scripts/register-gateway-profiles.sh covering env var setup and an example for each supported gateway auth method (session cookie, bearer token, OAuth2 client credentials), linked from the Certificate Profiles section in configuration.md. --- docsource/configuration.md | 3 +- docsource/gateway-profile-quickstart.md | 121 ++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 docsource/gateway-profile-quickstart.md diff --git a/docsource/configuration.md b/docsource/configuration.md index bb2f63c..9c1b7c2 100644 --- a/docsource/configuration.md +++ b/docsource/configuration.md @@ -84,7 +84,8 @@ The script authenticates to the gateway's admin API (OAuth2 client-credentials, pasted browser session cookie) and reads the product list from `integration-manifest.json`, so it stays in sync with the product IDs above without hand-entering each one. See `scripts/register-gateway-profiles.sh` and `scripts/lib/gateway-auth.sh` for the required environment -variables. +variables, or [Gateway Certificate Profile Quickstart](docsource/gateway-profile-quickstart.md) for a +walkthrough of each supported auth method. ## CA Connection Configuration diff --git a/docsource/gateway-profile-quickstart.md b/docsource/gateway-profile-quickstart.md new file mode 100644 index 0000000..1383fc1 --- /dev/null +++ b/docsource/gateway-profile-quickstart.md @@ -0,0 +1,121 @@ +# Gateway Certificate Profile Quickstart + +This is a standalone walkthrough for `scripts/register-gateway-profiles.sh`, the helper that +creates/updates the AnyCA Gateway REST **certificate profiles** this plugin needs (one per +MarkMonitor product in `integration-manifest.json`). It's idempotent — safe to re-run any time the +product list changes. See [Certificate Profiles](configuration.md#certificate-profiles) for where +this fits in the overall setup flow. + +## Prerequisites + +- `bash`, `curl`, and `jq` on the machine running the script. +- [`just`](https://github.com/casey/just) (optional) — the repo's `justfile` wraps the script; you + can also invoke it directly. +- The AnyCA Gateway REST instance up and reachable, and one of the three credentials below for its + admin API. + +## 1. Set the gateway host + +```shell +GATEWAY_HOST=gateway.example.com +``` + +If your gateway hosts multiple instances, each instance is mounted at its own base path (e.g. +`/markmonitor-0` instead of the default `/AnyGatewayREST`) — check the Portal or Swagger URL for the +instance you're targeting and set it explicitly: + +```shell +GATEWAY_BASE_PATH=/markmonitor-0 +``` + +## 2. Choose an auth method + +`scripts/lib/gateway-auth.sh` supports three ways to authenticate to the gateway's admin API. Set +**one** of these — the script checks them in the order below. + +### Option A — browser session cookie + +Fastest for a one-off manual run: log into the Portal, open dev tools → Network, copy the `Cookie` +header value from any request, and set it directly. + +```shell +GATEWAY_HOST=gateway.example.com +GATEWAY_COOKIE='.AspNetCore.Cookies=CfDJ8...' +``` + +### Option B — pre-obtained bearer token + +If you already have a token (e.g. from a prior `curl` against your identity provider), skip the +OAuth2 round-trip and use it directly. + +```shell +GATEWAY_HOST=gateway.example.com +GATEWAY_TOKEN=eyJhbGciOi... +``` + +### Option C — OAuth2 client credentials (recommended for automation) + +The script fetches a fresh token itself on every run — best for CI or scheduled use where a pasted +cookie/token would go stale. + +```shell +GATEWAY_HOST=gateway.example.com +TOKEN_URL=https://idp.example.com/oauth2/token +OIDC_CLIENT_ID=markmonitor-gateway-admin +OIDC_CLIENT_SECRET=*** +# Optional, defaults to keyfactor-anyca-gateway: +GATEWAY_SCOPE=keyfactor-anyca-gateway +``` + +## Putting it in a `.env` file + +The script auto-sources a `.env` in the repo root, so for repeated local use it's easiest to drop +whichever option's variables in there instead of exporting them every session: + +```shell +# .env (repo root, gitignored) +GATEWAY_HOST=gateway.example.com +TOKEN_URL=https://idp.example.com/oauth2/token +OIDC_CLIENT_ID=markmonitor-gateway-admin +OIDC_CLIENT_SECRET=*** +``` + +## 3. Run it + +Via `just` (from the repo root): + +```shell +just register-gateway-profiles 1 # dry run — preview only, no gateway calls +just register-gateway-profiles # create/update one profile per product +just register-gateway-profiles 0 1 # apply, then list the resulting profiles +``` + +Or invoke the script directly with the same env vars exported: + +```shell +DRY_RUN=1 ./scripts/register-gateway-profiles.sh +./scripts/register-gateway-profiles.sh +CHECK=1 ./scripts/register-gateway-profiles.sh +``` + +Dry runs are fully offline — no token is fetched and no gateway calls are made — so `DRY_RUN=1` works +even before any auth variables are set. + +## Customizing key algorithms + +By default, profiles allow RSA 2048/3072/4096 and ECDSA P-256/P-384/P-521 (the curves MarkMonitor's +CSR validation accepts). Override with `KEY_ALGS_JSON` if you need a narrower or wider set: + +```shell +KEY_ALGS_JSON='{"rsa": {"bit_lengths": [2048, 4096]}, "ecdsa": {"curves": ["1.2.840.10045.3.1.7"]}}' \ + just register-gateway-profiles +``` + +## Troubleshooting + +| Symptom | Likely cause | +|---|---| +| `ERROR: required env var 'GATEWAY_HOST' is not set` | `GATEWAY_HOST` (or the auth-method variables for the option you picked) isn't exported and isn't in `.env`. | +| `ERROR: no access_token in response` | `TOKEN_URL`/`OIDC_CLIENT_ID`/`OIDC_CLIENT_SECRET` are set but wrong, or the IdP rejected the scope — check the printed response body. | +| `ERROR: unexpected response listing certificate profiles` | `GATEWAY_BASE_PATH` likely doesn't match this gateway instance's actual mount path, or the token/cookie was rejected. | +| TLS errors from `curl` | Set `CURL_INSECURE=0` to enforce certificate verification (default is `1`, i.e. `curl -k`, for lab/self-signed gateways). | From 86ad920ea859098499d054daf0b654bcdc140488 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 14 Aug 2026 03:16:44 +0000 Subject: [PATCH 8/8] docs: auto-generate README and documentation [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 395452c..61b3b5d 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,8 @@ The script authenticates to the gateway's admin API (OAuth2 client-credentials, pasted browser session cookie) and reads the product list from `integration-manifest.json`, so it stays in sync with the product IDs above without hand-entering each one. See `scripts/register-gateway-profiles.sh` and `scripts/lib/gateway-auth.sh` for the required environment -variables. +variables, or [Gateway Certificate Profile Quickstart](docsource/gateway-profile-quickstart.md) for a +walkthrough of each supported auth method. ## CA Connection Configuration