From 855d22bd80052bff45ab96b108ba13f8a5cec098 Mon Sep 17 00:00:00 2001 From: Pedro Juarez Date: Fri, 7 Jun 2024 16:17:22 -0700 Subject: [PATCH] Document TLS Certificates flow with Cert Manager (#2079) * Document TLS Certificates flow with Cert Manager Signed-off-by: pjuarezd --- docs/cert-manager.md | 453 ++++++++++++++++-- docs/env-variables.md | 27 +- docs/images/Cert-manager Issuers.png | Bin 0 -> 111249 bytes docs/images/Cert-manager-namespaces.png | Bin 0 -> 74547 bytes docs/tls.md | 56 +-- .../cert-manager/kustomization.yaml | 5 + .../selfsigned-root-clusterissuer.yaml | 6 + .../console-tls-certificate.yaml | 13 + .../operator-certmanager/kustomization.yaml | 13 + .../minio-operator-ca-issuer.yaml | 8 + .../operator-ca-tls-secret.yaml | 17 + .../operator-deployment.yaml | 17 + .../sts-tls-certificate.yaml | 13 + .../sample-data/mc-job-setup-bucket.yaml | 2 +- .../tenant-certmanager-kes/certificates.yaml | 35 -- .../tenant-certmanager-kes/kustomization.yaml | 3 +- .../myminio-kes-certificate.yaml | 15 + .../tenant-certmanager/kustomization.yaml | 9 +- .../tenant-certmanager-ca-certificate.yaml | 17 + .../tenant-certmanager-issuer.yaml | 7 + ...nant-certmanager-myminio-certificate.yaml} | 19 +- .../tenant-certmanager/tenant.yaml | 2 +- kustomization.yaml | 24 +- pkg/controller/main-controller.go | 8 +- pkg/controller/sts.go | 13 + testing/certmanager/mc-admin-info-pod.yaml | 32 ++ testing/common.sh | 35 +- testing/deploy-cert-manager-tenant.sh | 4 +- testing/sts/operator/kustomization.yaml | 6 +- 29 files changed, 682 insertions(+), 177 deletions(-) create mode 100644 docs/images/Cert-manager Issuers.png create mode 100644 docs/images/Cert-manager-namespaces.png create mode 100644 examples/kustomization/cert-manager/kustomization.yaml create mode 100644 examples/kustomization/cert-manager/selfsigned-root-clusterissuer.yaml create mode 100644 examples/kustomization/operator-certmanager/console-tls-certificate.yaml create mode 100644 examples/kustomization/operator-certmanager/kustomization.yaml create mode 100644 examples/kustomization/operator-certmanager/minio-operator-ca-issuer.yaml create mode 100644 examples/kustomization/operator-certmanager/operator-ca-tls-secret.yaml create mode 100644 examples/kustomization/operator-certmanager/operator-deployment.yaml create mode 100644 examples/kustomization/operator-certmanager/sts-tls-certificate.yaml delete mode 100644 examples/kustomization/tenant-certmanager-kes/certificates.yaml create mode 100644 examples/kustomization/tenant-certmanager-kes/myminio-kes-certificate.yaml create mode 100644 examples/kustomization/tenant-certmanager/tenant-certmanager-ca-certificate.yaml create mode 100644 examples/kustomization/tenant-certmanager/tenant-certmanager-issuer.yaml rename examples/kustomization/tenant-certmanager/{certificates.yaml => tenant-certmanager-myminio-certificate.yaml} (73%) create mode 100644 testing/certmanager/mc-admin-info-pod.yaml diff --git a/docs/cert-manager.md b/docs/cert-manager.md index 3d5041c8862..c6d8f6583d5 100644 --- a/docs/cert-manager.md +++ b/docs/cert-manager.md @@ -1,77 +1,466 @@ -# MinIO tenant with cert-manager [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) +# TLS Certificate management with Cert Manager [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) -This document explains how to deploy a MinIO tenant using certificates generated -by [cert-manager](https://cert-manager.io/). +This document explains how to deploy MinIO Operator and a MinIO Tenant using certificates generated by [cert-manager](https://cert-manager.io/). + +On a Kubernetes cluster, Certificate Manager requires a global level `Cluster Issuer` to generate intermediary Issuers and certificates. +At the namespace level, Cert Manager issues certificates derived from an `Issuer`. +The main difference between a `Cluster Issuer` and an `Issuer` is that `Cluster Issuer` can issue certificates for several +namespaces and an `Issuer` can only issue them in a single namespace. + +To learn more about Cert Manager Issuers refer to their documentation https://cert-manager.io/docs/concepts/issuer/. + +Below is a logical view of a Kubernetes cluster: + +![Cert-manager-namespaces.png](images%2FCert-manager-namespaces.png) + +This cluster contains 4 namespaces: + +- minio-operator +- tenant-1 +- tenant-2 +- other-namespace + +This guide shows you how to set up different Certificate Authorities (CA) in each namespace, all of them referencing a global `Cluster Issuer`. + +![Cert-manager Issuers.png](images%2FCert-manager%20Issuers.png) + +Cert Manager is installed in the `cert-manager` namespace. + +The global `Cluster Issuer` is created in the default namespace. + +A local `Issuer` is created in each tenant namespace. + +An `Issuer` is also created in the `minio-operator` namespace. More about services that require TLS certificates +in the `minio-operator` namespace are covered below in [MinIO Operator services with cert-manager](# MinIO Operator services with cert-manager). + +> [!NOTE] +> This guide uses a self-signed `Cluster Issuer`. You can also use [other Issuers supported by Cert Manager](https://cert-manager.io/docs/configuration/issuers/). +> The main difference is that you must provide the `Issuer` CA certificate to minio, instead of the CA's mentioned in this guide. ## Getting Started ### Prerequisites - Kubernetes version `+v1.21`. While cert-manager - supports [earlier K8s versions](https://cert-manager.io/docs/installation/supported-releases/), the MinIO Operator - requires 1.21 or later. -- MinIO Operator installed + supports [earlier K8s versions](https://cert-manager.io/docs/installation/supported-releases/), MinIO Operator requires 1.21 or later. +- [kustomize](https://kustomize.io/) installed - `kubectl` access to your `k8s` cluster -- [cert-manager](https://cert-manager.io/docs/installation/) 1.7.X or later installed + +### Setup Cert-manager + +Install [cert-manager](https://cert-manager.io/docs/releases/release-notes/release-notes-1.12/) 1.12.X LTS is preferred, +or install latest, for example using kubectl. ```bash -kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.7.2/cert-manager.yaml +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.9/cert-manager.yaml ``` -- [kustomize](https://kustomize.io/) installed +For more details on the Cert Manager refer to https://cert-manager.io/docs/installation/. -### Deploy tenant +### Create Cluster Self-signed root Issuer -Use the example to deploy a `MinIO` tenant using tls certificates generated by `cert-manager`, go into base folder of -the operator project and run the following command. +The `Cluster Issuer` is the cluster level Issuer all other certificates are derived from. Request Cert Manager to +generate this by creating a `ClusterIssuer` resource: -```bash -kustomize build examples/kustomization/tenant-certmanager | kubectl apply -f - +```yaml +# selfsigned-root-clusterissuer.yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-root +spec: + selfSigned: {} ``` -This file request `cert-manager` to issue a new certificate based on the following internal domains. +```shell +kubectl apply -f selfsigned-root-clusterissuer.yaml +``` + +# MinIO Operator services with cert-manager + +MinIO Operator manages the TLS certificate issuing for the services hosted in the `minio-operator` namespace. These include Secure Token Service `sts` and the Console `console` service. + +This section describes how to generate the `sts` and `console` TLS certificates with Cert Manager. +These certificates must be issued before installing Operator. +Be sure to follow step [Create Cluster Self-signed root Issuer ](#Create Cluster Self-signed root Issuer) mentioned above. + +## Secure Token Service (STS) + +MinIO STS is a service included with MinIO Operator that provides Native IAM Authentication for Kubernetes. In essence +this service allows you to control access to your MinIO tenant from your kubernetes applications without having to explicitly create credentials +for each application. For more information on the Service see the MinIO docs at https://min.io/docs/minio/kubernetes/upstream/developers/sts-for-operator.html. +There is also an [STS](https://github.com/minio/operator/blob/master/docs/STS.md) guide in the docs and example client code in +https://github.com/minio/operator/tree/master/examples/kustomization/sts-example. + +For the purpose of this guide, STS Service can be considered a webserver presented with a TLS certificate for https traffic. +This guide covers how to **disable** the automatic generation of the certificate in MinIO Operator and issue the certificate using +Cert Manager instead. + +## Console service + +The console service is the well-known UI provided by Operator, it looks like the image below: + +![console-dashboard.png](images%2Fconsole-dashboard.png) + +When you install MinIO Operator, by default the Console service comes with TLS disabled. This guide explains +how to issue the TLS certificate for this service with Cert Manager and enable TLS for https traffic. + +### Create minio-operator namespace CA Issuer + +To create the Certificate Authority (CA) certificate used to issue certificates for services in the `minio-operator` +namespace, first create the minio-operator namespace + +```shell +kubectl create ns minio-operator +``` + +Request a Certificate with `spec.isCA: true` specified. This is our CA for the `minio-operator` namespace. ```yaml +# operator-ca-tls-secret.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: minio-operator-ca-certificate + namespace: minio-operator +spec: + isCA: true + commonName: operator + secretName: operator-ca-tls + duration: 70128h # 8y + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-root + kind: ClusterIssuer + group: cert-manager.io +``` + +```shell +kubectl apply -f operator-ca-tls-secret.yaml +``` +A new secret with the name `operator-ca-tls` is created in the `minio-operator` namespace, this is the CA issuing TLS certificates for the services in the `minio-operator` namespace. + +> [!IMPORTANT] +> Make sure to trust this certificate in your applications that need to interact with either the `console` or the `sts` service. + + +Now create the `Issuer`: + +```yaml +# operator-ca-issuer.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: minio-operator-ca-issuer + namespace: minio-operator +spec: + ca: + secretName: operator-ca-tls +``` + +```shell +kubectl apply -f operator-ca-issuer.yaml +``` + +### Create TLS certificate for STS service + +Request Cert Manager to issue a new certificate containing following DNS domains: + +```shell +sts +sts.minio-operator.svc. +sts.minio-operator.svc. +``` + +> [!IMPORTANT] +> Replace `` with the actual values for your MinIO tenant. +> `cluster domain` is the internal root DNS domain assigned in your Kubernetes cluster. Typically this is `cluster.local`, check on your coredns +> configuration for the correct value for your Kubernetes cluster. For example, using `kubectl get configmap coredns -n kube-system -o yaml | yq ".data"`. +> The way the root DNS domain is managed can vary depending on the Kubernetes distribution (Openshift, Rancher, EKS, etc.) + +Create a `Certificate` for the domains mentioned above: + +```yaml +# sts-tls-certificate.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: sts-certmanager-cert + namespace: minio-operator +spec: + dnsNames: + - sts + - sts.minio-operator.svc + - sts.minio-operator.svc.cluster.local + secretName: sts-tls + issuerRef: + name: minio-operator-ca-issuer +``` + +```shell +kubectl apply -f sts-tls-certificate.yaml +``` +This creates a secret called `sts-tls` in the `minio-operator` namespace. + +> [!IMPORTANT] +> The secret name is not optional. Make sure the secret name is `sts-tls` by setting `spec.secretName: sts-tls` as in the example above. + +### Create TLS certificate for Console service + +Request Cert Manager to issue a new certificate including the following DNS domains for console: + +```shell +console +console.minio-operator.svc. +console.minio-operator.svc. +``` + +> [!IMPORTANT] +> Replace `` with the actual values for your MinIO tenant. +> `` is the internal root DNS domain assigned in your Kubernetes cluster. Typically this is `cluster.local`, check on your coredns +> configuration for the correct value for your Kubernetes cluster. For example, using `kubectl get configmap coredns -n kube-system -o yaml | yq ".data"`. +> The way the root DNS domain is managed can vary depending on the Kubernetes distribution (Openshift, Rancher, EKS, etc.) + +Create a `Certificate` for the domains mentioned above: + +```yaml +# console-tls-certificate.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: console-certmanager-cert + namespace: minio-operator +spec: + dnsNames: + - console + - console.minio-operator.svc + - console.minio-operator.svc.cluster.local + secretName: console-tls + issuerRef: + name: minio-operator-ca-issuer +``` + +```shell +kubectl apply -f console-tls-certificate.yaml +``` + +This creates a secret called `console-tls` in the `minio-operator` namespace. + +> [!IMPORTANT] +> The secret name is not optional. Make sure the secret name is `console-tls` by setting `spec.secretName: console-tls` as in the example above. + +### Install Operator with Auto TLS disabled for STS + +When installing the Operator deployment, make sure to set `OPERATOR_STS_AUTO_TLS_ENABLED: off` env variable in the `minio-operator` container. This prevents +MinIO Operator from issuing the certificate for STS and instead wait for you to provide the TLS certificate issued by Cert Manager. + +Also make sure to set `MINIO_CONSOLE_TLS_ENABLE: off` env variable, this prevents MinIO Operator from issuing the certificate for Console +and instead will expect you to provide the TLS certificate issued by Cert Manager. + +> [!WARNING] +> Missing to provide the secret `sts-tls` containing the TLS certificate or providing an invalid key-pair in the secret will +> prevent the STS service from start. + +A way to make sure that the env variables are properly set is using kustomization to patch the `minio-operator` deployment: + +```yaml +# minio-operator/kustomization.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- github.com/minio/operator/resources + +patches: +- patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: minio-operator + namespace: minio-operator + spec: + template: + spec: + containers: + - name: minio-operator + env: + - name: MINIO_CONSOLE_TLS_ENABLE + value: "off" + - name: OPERATOR_STS_AUTO_TLS_ENABLED + value: "off" + - name: OPERATOR_STS_ENABLED + value: "on" +``` + +```shell +kubectl apply -k minio-operator +``` + +# MinIO tenant TLS certificates with cert-manager + +## Create tenant-1 namespace CA Issuer + +To create the Certificate Authority (CA) certificate in the namespace `tenant-1`, first create the namespace + +```shell +kubectl create ns tenant-1 +``` + +Next, request a Certificate with `spec.isCA: true` specified: + +```yaml +# tenant-1-ca-certificate.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: tenant-1-ca-certificate + namespace: tenant-1 +spec: + isCA: true + commonName: tenant-1-ca + secretName: tenant-1-ca-tls + duration: 70128h # 8y + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-root + kind: ClusterIssuer + group: cert-manager.io +``` + +```shell +kubectl apply -f tenant-1-ca-certificate.yaml +``` + + +Then create the `Issuer`: + +```yaml +# tenant-1-ca-issuer.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: tenant-1-ca-issuer + namespace: tenant-1 +spec: + ca: + secretName: tenant-1-ca-tls +``` + +```shell +kubectl apply -f tenant-1-ca-issuer.yaml +``` + +## Deploy the tenant + +### Create a certificate for Tenant + +Request Cert Manager issue a new TLS server certificate for MinIO that includes the following DNS domains: + +```shell +minio. +minio..svc +minio..svc. +*.-hl..svc. +*..svc. +*..minio..svc.' +``` + +> [!IMPORTANT] +> Replace `` with the actual values for your MinIO tenant. +> * `` is the internal root DNS domain assigned in your Kubernetes cluster. Typically this is `cluster.local`, check on your coredns +> configuration for the correct value for your Kubernetes cluster. For example, using `kubectl get configmap coredns -n kube-system -o yaml | yq ".data"`. +> The way the root DNS domain is managed can vary depending on the Kubernetes distribution (Openshift, Rancher, EKS, etc.) +> * `tenant-name` is the name provided to your tenant in the `metadata.name` of the Tenant YAML. For this example it is `myminio`. +> * `namespace` is the namespace where the tenant is created, the `metadata.namespace` notes that in the Tenant YAML. For this example it is `tenant-1`. + +Create a `Certificate` for the domains mentioned above: + +```yaml +# tenant-1-minio-certificate.yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: tenant-certmanager-cert - namespace: minio-tenant + namespace: tenant-1 spec: dnsNames: - - "*.tenant-certmanager.svc.cluster.local" - - "*.myminio.tenant-certmanager.svc.cluster.local" - - "*.myminio-hl.tenant-certmanager.svc.cluster.local" - secretName: tenant-certmanager-tls + - "minio.tenant-1" + - "minio.tenant-1.svc" + - 'minio.tenant-1.svc.cluster.local' + - '*.minio.tenant-1.svc.cluster.local' + - '*.myminio-hl.tenant-1.svc.cluster.local' + - '*.myminio.minio.tenant-1.svc.cluster.local' + secretName: myminio-tls issuerRef: - name: tenant-certmanager-issuer + name: tenant-1-ca-issuer +``` + +> [!TIP] +> For this example, the Tenant name is `myminio`. We recommend naming the secret in the field `spec.secretName` as `-tls`, following the naming +> convention MinIO Operator uses when creates certificates with Autocert enabled (`spec.requestAutoCert: true`). + +```shell +kubectl apply -f tenant-1-minio-certificate.yaml ``` -Then it creates a new tenant including the new `tenant-certmanager-tls` secret in the `externalCertSecret` field. +### Configure the tenant to use the certificate created by cert-manager + +In the tenant spec, do the following: + +* Disable Autocert `spec.requestAutoCert: false`. This instructs Operator to not attempt to issue certificates and instead rely on Cert Manager to provide them in a secret. +* Reference the Secret containing the TLS certificate from the previous step in `spec.externalCertSecret`. ```yaml +apiVersion: minio.min.io/v2 +kind: Tenant +metadata: + name: myminio + namespace: tenant-1 +spec: +... + ## Disable default tls certificates. + requestAutoCert: false ## Use certificates generated by cert-manager. externalCertSecret: - - name: tenant-certmanager-tls + - name: myminio-tls type: cert-manager.io/v1 +... ``` -### Create `operator-ca-tls` secret +## Trust tenant-1 CA in MinIO Operator -Copy the cert-manager CA from the tenant certificate, this will allow Operator to trust the cert-manager CA and allow Operator to trust the Tenant certificate +MinIO Operator can trust as many CA certificates as provided. To do this, create a secret with the prefix `operator-ca-tls-` +followed by a unique identifier in the `minio-operator` namespace. -```sh -kubectl get secrets -n tenant-certmanager tenant-certmanager-tls -o=jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt +MinIO Operator mounts and trusts all certificates issued by the provided CA's. This is required because +MinIO Operator performs health checks using the */minio/health/cluster* endpoint. + +If Operator is not correctly configured to trust the MinIO Certificate (or its CA), you will see an error message like the following in the Operator Pod logs: + +```error +Failed to get cluster health: Get "https://minio.tenant-1.svc.cluster.local/minio/health/cluster": +x509: certificate signed by unknown authority ``` +For more details about health checks, see https://min.io/docs/minio/Kubernetes/upstream/operations/monitoring/healthcheck-probe.html#cluster-write-quorum. -Create the secret +### Create `operator-ca-tls-tenant-1` secret +Copy the Cert Manager generated CA public key (ca.crt) into the `minio-operator` namespace. This allows Operator to trust +the cert-manager issued CA and the derived certificates. + +Create a `ca.crt` file containing the CA: ```sh -kubectl create secret generic operator-ca-tls --from-file=ca.crt -n minio-operator +kubectl get secrets -n tenant-1 tenant-1-ca-tls -o=jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt ``` -Restart the minio-operator - +Create the secret: ```sh -kubectl rollout restart deployment.apps/minio-operator -n minio-operator +kubectl create secret generic operator-ca-tls-tenant-1 --from-file=ca.crt -n minio-operator ``` +> [!TIP] +> In this example we choose a secret name of `operator-ca-tls-tenant-1`. Note the tenant namespace +> `tenant-1` is used as suffix for easy identification of which namespace the CA is coming from. diff --git a/docs/env-variables.md b/docs/env-variables.md index 2f529af3a1a..5fd691b928f 100644 --- a/docs/env-variables.md +++ b/docs/env-variables.md @@ -2,16 +2,17 @@ Operator behavior can be customized using environment variables in the `minio-operator` deployment. Here is a list of the available environment variables: -| Variable Name | Description | Possible values | default | -| --- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|---------------------------------| -|MINIO_OPERATOR_CERTIFICATES_VERSION| This forces which certificate api version to use. | `v1`,`v1beta1` | whichever api k8s provides | -|MINIO_OPERATOR_RUNTIME | This tells us which runtime we have i.e. (EKS, Rancher, OpenShift, etc.). For example, if `EKS` is set, the CSR signerName to be used will be `"beta.eks.amazonaws.com/app-serving"` | EKS, Rancher, OpenShift | | -|MINIO_OPERATOR_CSR_SIGNER_NAME| The name to use for the CSR Signer. It will override the default | | `kubernetes.io/kubelet-serving` | -|SUBNET_BASE_URL| Subnet base URL | | https://subnet.min.io | -|OPERATOR_CERT_PASSWD| This is used to decrypt the private key in the TLS certificate for operator, if needed | | | -|MINIO_OPERATOR_DEPLOYMENT_NAME| This specifies a custom deployment name for Operator | | `minio-operator` | -|OPERATOR_STS_ENABLED| This toggles the STS Service on or off | `on`, `off` | `on` | -|MINIO_CONSOLE_DEPLOYMENT_NAME| This is the default name of the console deployment | | `console` | -|MINIO_CONSOLE_TLS_ENABLE| This toggles the Console TLS on or off | `on`, `off` | `off` | | | | -|WATCHED_NAMESPACE| The namespaces which the operator watches for MinIO tenants. Defaults to `""` for all namespaces. | | | -|MINIO_OPERATOR_IMAGE| This variable controls the image of the minio instance's sidecar and validate-arguments. if not set, the mirrors of the minio instance's sidecar and validate-arguments will use the operator's image. | "" | "" | \ No newline at end of file +| Variable Name | Description | Possible values | default | +| --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|---------------------------------| +|MINIO_OPERATOR_CERTIFICATES_VERSION| This forces which certificate api version to use. | `v1`,`v1beta1` | whichever api k8s provides | +|MINIO_OPERATOR_RUNTIME | This tells us which runtime we have i.e. (EKS, Rancher, OpenShift, etc.). For example, if `EKS` is set, the CSR signerName to be used will be `"beta.eks.amazonaws.com/app-serving"` | EKS, Rancher, OpenShift | | +|MINIO_OPERATOR_CSR_SIGNER_NAME| The name to use for the CSR Signer. It will override the default | | `kubernetes.io/kubelet-serving` | +|SUBNET_BASE_URL| Subnet base URL | | https://subnet.min.io | +|OPERATOR_CERT_PASSWD| This is used to decrypt the private key in the TLS certificate for operator, if needed | | | +|MINIO_OPERATOR_DEPLOYMENT_NAME| This specifies a custom deployment name for Operator | | `minio-operator` | +|OPERATOR_STS_ENABLED| This toggles the STS Service on or off | `on`, `off` | `on` | +|OPERATOR_STS_AUTO_TLS_ENABLED| Env variable name to turn on and off generating the STS TLS certificate automatically using CSR. If it is disabled, you must provide a certificate issued externally | `on`, `off` | `on` | +|MINIO_CONSOLE_DEPLOYMENT_NAME| This is the default name of the console deployment | | `console` | +|MINIO_CONSOLE_TLS_ENABLE| This toggles the Console TLS on or off | `on`, `off` | `off` | | | | +|WATCHED_NAMESPACE| The namespaces which the operator watches for MinIO tenants. Defaults to `""` for all namespaces. | | | +|MINIO_OPERATOR_IMAGE| This variable controls the image of the minio instance's sidecar and validate-arguments. If not set, the mirrors of the minio instance's sidecar and validate-arguments use the operator's image. | "" | "" | \ No newline at end of file diff --git a/docs/images/Cert-manager Issuers.png b/docs/images/Cert-manager Issuers.png new file mode 100644 index 0000000000000000000000000000000000000000..c34e5ae7584088b44b8f16bf15b8d733dea58e0a GIT binary patch literal 111249 zcmeEP2Vhg>+D62IizN<}scc&_JCxNn9f78$6Iu~%(~_o5o6@FD6N(6;2%;h=I1pTj zs3=1&Dk7lZLPZn-ML-cmhB8E^$p1X=IVTMi^!~1kTCdkMC+B?QozMGz-}&CreUsuZ zJg>!h_3G8T(3)ULtyi!9)Oz*KSat5%xKcee<~n?wQJxwfUGIetuiRGejB8qZV*7iF zs|Gn;`SscxW0b$z8*~Nka!-4srM25oM?)8)!(Z-_I8>d;gtTaMjX z;&GQ3v^PfMyS2oV@4_c8rs-F2d43~ab{&Hv#HE4D|fm})X5t|^`Uy@2am5bU%BdVyB#ic z$Ri7?o61{w2A`39Zo#MZSwimT$wa!Lzq z?mVG?UX?mPU3i2t>O7xz#VCy!bdEBuV|5(7kmmGjbCa3iwhCvSMgfgdZnw+hELF*( zUbMSQO7iWhoT%4w%F5i{<8K?}cB#`_v_;cSVWXV~M*&M1)iFn)?f+JoAOfnW{_^MeRfEr0Qoyc1|#FJJuz^@az8{nJ9;95^;99HB&9ZGH9sirC? zS5rlmjDI9g&1#z(Pc{Ap@l>y|FPNu+i>D7yAxjjeAl)u@mN?xZ?$Z3S9FM!K7Kdw8 zoci=DDz53W#=8KQPn3_}r27T#GN<2N;>pqMEcDo8ahAbTsTRdUky9-}I_-y;WA#F! z*c%I{aiXz^2)Y=pS`hrqDBsm)7c7UT@8q?YvjE0DC zbF6_49>-4nGD!ZxFQsl^UopMr==SDl08<^XN{lWv3}!G!*WL`A5+grgBDf4KI_@g) z%SoL}Fe3)KAj^N(nDufB81))V1x%p*? z74pkNoiLQ7Kxvs3e}SYW<)^f%!M5`c6SVr_UCw+f13&+>J(QNM%dlKD&giv9=$Kz91M{+7WZrInLvZBT z)QQtR3;R12&!7)AhX?7Mx{9Id-AT6KXb>pax14^98tR_7AlGudR;i(6omOEjT$bkl z+C6Ch=!s9wUtJAYTMb88l2I-j^s;heT_jO=KRdIq8OE!|# zB_0q{1#Oc2YvJH&zpnT@-4-@U|2?<1m}+Mqj!y>vzD2_S@%oQ&^}kssRE@^3uK!3b z=QpHsPxEy`Q|)N^kCXy#7ylow0{-Drpae<(KryHt-2IVa@J}-al7jjNNmK(oambz1}E72f~xZurxF z5%c#dpWzo*G5@xE18}s{iSKKjs9CiW9(5k)FZ4M7a?SetF0bfoZ|OWywQ5Hab*fdT zS~X{A{a&Y~$5|HtiY)@C+&F5`@L}ytU7f1csoGzrYJXohrkxEL6noX}5~zFoIH%_5 z$dhim`Ms{|B$?yC$F@+Dx@$aWJK7()CiFjE8C2N%-|Q1m$?&WD1eDy)Z^-VR?i&TP zwe*@ZSpP^l_#dwg{t0p*;nF`)4%7@wojs65)34hDq1Qi94%BqOpCkwWJbUmD-9Ve(5H9V(oq(0eZfxuY-!Ee|FE}lN8htRa)-{X!w^Azx?b2;E&IaXHg zIHmgkLw5~C@)VQ*#Zdx^p8W%7xtL6$;YQ`nO?f+7jT3`)&SVJX@gFreDMEZ2>0Irz1#0P8exB3Ax*9R%<*5}e zsT&m91)w14tUT?&d1tXy{`vKCA99#>bfA_`&>8)KllV_8BB2(7DLL4t6Ii4KUy;8m!;>s%>?G4dYsLo@E>6?&b$o55>a{E}yft{H9V8G7{NvszBkx8)T56`G2z#)5)mZ&8HZm}<_A&v4`= zxV+ivD0mc~Y08UPnX%xcIk&Mx#s_I4(jveL_Y_a$8uT;2hMC3v=V+{NxLs z_ks>Zebag;+58!%#KIy|k}pbVkyLE+Bson!(6z$mkM$>}$NCZrZC+biR8?Z3L!T6* zt4i{j%r;AwBPqtDxB262$>~`YNq(ErYKirO=Kds0??UA{M-`qkBo@Y2CCBJ|;8~R| zJqxt8S0oiW%!%n%ePW>%e2U_8I-9?sJTX1Xt6uYgrxmusOtfXK5Z-}*_|2Q-(^Vv; zTXj|opO5k-#jp>^K}?iCDNV*y0NKF!GaTBdEhfrqwM02E2163Z;4>MLEd}Kmj~V0h zC8b4S&fs~WqbkeqKz~^#%m;JEbtnICqO2)nx1>01e#|-DR)u?viG?ZtAbjy2XJ^sq!3axJljWO>%+!E>O4 zt;%MwfjJkex%r?r14|7C+7^8vh zKo+2nu^xPyp-X7Tif1wmiJ$@Ll<%}w24pn(}2Dl7z=2RKG_%T0O$xg!Do~My!9tj#|!an zA$hIJnkCCazJRyr$6A$~reoXW6J^sx9)dTN6VT991v}v2C;D+v#=##4##LqW+aXhE zN7V`Z=Cdif>gFM6cSTp;D9)UNM^(fFf1J^NE&WUpD zGr=|`m1A7cuM`JlrwZ~bG)eN4CUzhANZm9*KG-j89{CA5wNN)9i?EmAEAB1AoT4CC zS&(a;5jM~O{r7=RXw&9NPDkJAv~?N6Z|XemtpdOC30vvZ;d+XW@-_ZktdKn*czdO!-#o6UQ%dl^huTs%8d@=0}ny}bm((BNeAATV1F?e z*bUkN%mKO`g??#&QIQ`#2t z3w>FNFb~MBKLzpw8e5_u6R{Y7k(qjl`O|j$*cax5xtM(5k0SH%51_MO<^h{)^A}NO zA)6SJ6E*^4fxL;$XWz*dWo(K}i(NNEkNg-Pc$VT3d+U$FI2@EcFJumKCo+UF(^eJH z22-A@V8hh;$I%ag53%$Wn2$qb2C{(p!Oj6UP-bZJt>Q0Iz%TeFnLqCLLslSL$?2p6 zWUi31MZKj=fw#2JKJp*7#a{$}2HvNqK#pP!s(n&uPdiZvIpe4JRx4!?bC$8;IUAm% zJQR6Fjw~tUIp@eR(|=G;g)fvH+6?Fl?I7icGC-N4J;xZ~e+r`v7?ntBsgX4D1)>M)WX)_DcK@`Aa(?{88G+7?d`l1N<9pXm*tRfZdks zR?@?y+yj|HKeVkP7nEU35$v$lfc9}8Y#5$_%!41)H@TN~g0>epO?1`|e&{{nVjv9d!=+2VJ4ek#|;HkHY*FyA6y1UV+ZVUXcM} z5y-4R$q$@USOk2)ep0AUO8-9I?;t)we>Un2#tK^q{3|-;!?PGW^#nY?JR#TA2l4S% z_&&%EeuMwgWRAKHT3S6EFLeda0wX)vhS1t3IwL+1n74?!1b#tY1S5!E8*yFiCw&vz zH$$IEYa@IP$LLK$`+N@l2<>UFMaL9h2ODZP!FEt)48%g1Gi^#0XaO6N0$#+L#kPn~ zvU_CS(w^$K`8RL|ctkp>I$^7_0~-Rj>nLM3(90$=XsgPi|5WAx`-tm`A60ljJV#$Z z8j+5e1L*68y{BI?CMkX#cF4+c;6BiddLljvatiE5c}=!pob**<>x<|U=)26)9%u?I z4?Pt7VT25WpDB9iI6m!SUm!cG--!YqpqyfE^mUfJa*T`k(*u0&SLqG9@;57V)Q&ca z;QxhwdSEa7Cia;1?A>E=7J`Qb7c2G_x<`F5KsLb-!NicgEMHPT z8)%#X9Z=^Ey;a6<1%_q&DZs6?hr~1FCE^M3Zw}Zn+BL*r^bf>{g`l;>R>aQmr{Z%J zT2P1hoqR|CM#uwnFAFr{b-@sn6OIEqjX8qH;`2BjVtV=)#rKhyluOPZ&p6EZL|f29 z+A;Va$S1}D`|Edr4pzvc*mT@u)#Q?xko|ESpcnB4u{?Q2p8-3Y&gUS<{h-U_Gx3Y) zLY~AdumQM-_!qiG>{uwc8GaVHN6|I-7y1C=WY~;!@?UTw_%1kucANSSyDeB9_yBrW zNMFRZiK&341e+ipfP8{Bh+}~vRG$NR1xC(*o*;guZ3QOdbMW~xHpmKf0DjocF>(&D zUr~_h49X&DXTto65qoQB`+!(GR?#JXr!9jnV$6_Lu_xj`Nh{bVbxzPt`ech07@3$Bd=^_yITXFr zB`fncQvcbO=mYhd_JBGg{vCD_c$i~`%#d~_;0=r`1Nuu$Dj1151N6ms3F9V~Dny^@ z4t^&lBi_ODMW96#d>DQg`%6p)d52$t?sJT!7ie!+X(Vv~`XnugI~_*IIAUbd3OE7! z0UT(AEki$cCFZ7Gfjts@2A>Tc;(7RN#9|x=Wr}l9@FeUZ@B(5LmB+*$f;&yb6tLyM zIT#oCM@&pRDzPfYsmK)UfykegxR^Y{Tw%-T|7jzMQ|XHlTPSh}n)p>*j<{KA1F|CH zl9*754V4(0G73JYmQ&^h_lP{knvu;RPayk(88B~=6JS6ceJf~*SebDrF{q7FJ>6v8+?NGXg|nbiw%0mcI~k1 zhy%bA%w4c8#sMFPInj5DzvY-=V?a;Xf5vgN=cFIxUu+4+5vvD3z-PovKC#CNUx1k) zf4DAjfhrGTo4`w85WyT)##d~U{*iN}U80;)kN6BRAo{|0!7894?iboqXOvh1yn@an zrh`n8KEMOecj9p1Fa8EOrp*yPX2FL-*Xbi*i`f_QV&bnHz!H>6+G56OkbCG;ayoqw zX=?{f>9;Z<@5~7SA4)8i0Xov2$=ESw9|rQ*Z!vfwqe_RN^qfWAN8j@)16ge$~Mk z4S0*XMj9zGv10qRTmUgE^oE$DP;eLQo?sv3f1nG3=@=srU&$CiH#_=34ou|BVWN$v zy`gNw78wKwAuj{@HDk`C8*CeFtHeDS)OW}yd^}}_HoAYQ2iGuv*mmYMRG#EYoGUpt zBkq%UT)Bt-Cc6;*z(2s2)85n1(MAxLi>_m=h$qM+Mc&a)d@O&1e~^3lspRJrOs?8R z;0pLw=m*9}y+^yqD=9WZ^xI7Q4UFZ7UZW4%+E~aQf0G!9{3do+Y&w069~cPoAn_mW z!CYwzXqO?M65pYX4CpcSSMmXn|149Iu~dmc;j68dXyj!f?}c{N2NmIY*i^(|^l=yu zXaXFJ7#icnoEZ~Z^`N1FzC{_I_)f)s633*c76^^h7@V|Ja+Yd-5dHu*jyk4?eo~%k zli4ofZ+;>#ohGp;Z9l%lH;CM6Gz2{uLqaz4i;#=;OPo*p2EPZpSL{XXAvnMR{gQqt zJES*kyFW{?kApc;wvA8ZQo&z*SLaB7r1955`td$|D)-SY(5KO76EA}n7z=DY=z^FV zHia@Mxdh@(>JxD{Xbw4sF7i2y8FrI#ZwB!*^A6BC*k;8C=<tPE-?imyGW9~GA z@gi*u><9fn^}dLh4>ksKhy01(WsE5}hO$8{FLR^bBd#X?gdb*}TKtb-17Z|Bqxg5s z2V(+VB}Ss&tMrCn1i#P@<|lk(P8>E*d}$H&5^)LQ3XvJw2KpV+4t8AlNSsbyQUB?; zVl|nAZIyhNPNAjva>yO?~D9e84Y$5xCvqT=4|EFI- zt{8bW=D`^g(=J-#!g9&;LgX(c&ja08=%DHeY`w%`jNcU2`$3vgcH*|@-qWW!g?)VB$jYAzI!{Fc-m`7U3+{zZBR2?{pkIW{N!$3$bc;^+^D=Kp?Ck*N z22IFU=)Ds6BL@k+!+3#%i4l~%lKf8lrTWcuD`kjzDac+5^Jy3ZZ3x=rx)<`sh(VNj z($^MdmcuqH^bs2cUFip1LX4r<&LY}M$~Zm)wv+M+|3v#heQ{$wG)ZSKjx6K)U~X|_ zMRuAM>msSXT!Y7z*gvl{J0aDLbxX>jGtsZE@%g=#c4Kx)Uk3}6@!#k{?h=o-{F|3Q zNIiK*S%l^iaK5%HM!6JRFYULUMy0kG8FqZdNyAAF0npBjEXa2{3e>7k1C~QNl`B#1`u8L=Acbhve-*wzQ@@t+m2bJH8PxwK*YQTc7QXnq5 zkFzj4HKQQzrqtrTeosVZN=2eV=aQUawbEN(Ea`{Hexj2N<+yPeba@)Lbm1zM@&d=~ zYA>QW%Czp)El9kemf=I^+Oh183TK{dHsCd7P##nf@i&jTy_Qo} z=Jpw_OZ=Ss>&Kz5&RpAQS*cIcdC}(ZNQ*Wu&!#4cNmf905 zvb*vJK@3j0`9$47;&M7lz>6|Pp#yhEsn>Je9*-NEqwRT3RTUrG?zp)mFQ>d9pMu2k zDZ~GBt<(udDqLkw&_1Lv?OL#rGHDx@{!A-%N})Qb6sUU=gQTDq`~MaD<|9=WYKHM7 zZs#=Iw|r8T*50-(uNH@#vSj%2Z_xdUexJAlETEcyh~gKx%bb3Ij~w_<(PlsmkHuLA zU*dGrLbyC-HD(|^P&HQF3!f;)M(Vw)R|1v-uf7J%$DdVw@1*QFg_l0LABfL)qdsk! z4}K)bnEYKNul8QyTE?Vq!~E&DVg3&lTMcW@mBel_w?4@tXoS- zwcWb~9uI*&W)O#e?Rh2oP$!`NAZJNlep#p;5X}%LJA4gsypGoc;tF!S>R+r~92bV# zIuWK2{u-h;hKJ<2?G?qS)E#0+Sm_+(wC8y8L-dA-(9#m@48{|>UqNyw<-%{ZxvKDL zFijO!DGBr|MSoPp9*p+PTHK??JdS{E=d?hJUyTcJj~W`BDmeN7fxVLy{i$W3{}pJ@ z@L#~aK+GG=(|{*FeGt5MXh0BzS5HJ!JF zX!x%!c=TVsD|vEeisASTa;#y$e?zI|lTuE5EA(WxxDNOI`MB>lTVPdk!y`jg{H{Vj zZK)wB7}sE3Ff7onoj$0*@Lw3@e+SeYyIsVx*wPpwj_}3EhlPd(|D$dpI5qGy=|h9^*(QU!vmn@9 zpW>F&M`(@epnu7D*BvcUceF&^(GuK>imi;YJ+$sW-F>S1{_1mQc2<*Bvc^ zE&SL*Ew3@w9W7CJv;_PmeWkpXgI5IPwL-pr!RvKLOW?H+zJi8VLh6o|s5@Gs?q~_T z%7<5DU?=L1mH-{_s!-k05_LyQ;FaLIqb1~(|GJ|kcobpX(Gqn>OJvj?ErHjE@#?Jh z8ajMs-O&W-F>_iC_fJO(Eq1m3pMse4tz zPI&1DXNtDnGk8t^uQ*wv=BT`hrBz%M{uhg0+rPsC!@A@C(}Y zySH{Kdm>MFp{u=zt!^*p@o)b8eO}v9+`?}V+`wK=9rhy!ZE=&gXbn1TFQ;|}P>^x` zN4&CaQV&H6a;M6PKYUSJJrn2O{JyqHr~k9x*Z#etd%}4<8jK5)RPB}SV1uk(JB>iV zf3dgzUxDlbCnc%I$M`pXYsaK+Zx6CBJnSH(IHv^1m6g?Uxc`bbcm8L`@t8!#euI|` zGA4oWA=sJ(E}ll_MBURKBzd)@t?pHw<6plq#K`;Mr{AkOzgckq?eI=L2IH5MKzrRv zJ?AEH{^0-jSRE~5uQ~5f3%mdKg)*~U_L8L1T!RV4Epae04u;K%&n(S06zFguEQ&*9 z;PBYM0kO*Wco&Q5@ofkc@k5cTtn+b&qqt>4s>|*~(Mm&ArQNA7%`L(AlIThlvDD@Ci>yfOr`}Uy zi?o&`rKReuPOJ8uE3+b}e<}+L>g|S1Uj|O6$TDR1&2?q^d7y3(-B93&MIU3$IJ7yK zemE?eg$+=2A>D!NMWi_oO2+~3R!2T4fdk&LlF8ztD2nD(W}Tam>B;GbBButIEj^Jf%P_%+HltTveHCNO9!!L$T80z;{v%Gl}+P_fOL2vXE(U?-G13&W(?( z%#P73^eEIhrSNA^QAOc`+IC8Dl`FS6#gW@DvPeBh*q7Tcu3Q^uc5!A*ZhU4%Hi|9a zFl*4w1sdp_SuDtkzd^V3Tw|sWG)u4-$9Z$&U4>RBqO2hKz${`Si*x!_>9YGDFFBl_ zzQArMNB?pD9R2^77vN)!9IJfzWgckrlKy-rjz(nI7p;vI(vs=Rjd2v7f?K6pYuS`@ z98|59t<)&Y_UuYYRnZCgTPRrs>XBnQ9Q|K}eY19y7iFoK6umXx=D@ylIbuJ_>GfK1 zRD80OA&JF3N@>vJuA$@)*2H*JG=67!niQ7MU?~$EN$u61#qsRQeTg{6ANy04GD|FV zX2~kYk>c8YIQCq97G)%~esL7K_KY`?B|PQ16pmBt2gio1;|LmW&2!OV)_5K6XQ^C! zIZDuA%qZa*ixOxk0fHl~eTf!3%SxhLB96nCqu{OOC|8DKuv2)PI?J`9WT{ujaxOT^ zUG71d4;-b<(oig?Vn^u|Qx)dNGH)gv*1k(oW>74`rlSip_~}qErozlLy~e zLL%0Y;){YTrhvvg(p}0jDkYG8DBB<_2!8nz1w+y`$5M5{xFyN!rI;Smq=H@+hCsC6xbx^-fej zgYJXeaDFITpp-)Zk5K*$Wf0LGN;0T)!TeaJ1$05XDUM7hN`Ihi7WnI?9^+ofEoshD zDkgRFyuxuS@&*S(Z|14F3z4%`BvxY~MYqSTs!M-z= zAYlouG`SC-f%`Mxw>0$T{Q{yijxzWt6zzh4+w#xQEC2qf89O8skOj7SI}dXel33;sd4Z zC?6;V0RG#`)z1LGr975Dg*FX*XW0&vFN*P^9IYv+ED4YAx07$+Ul#a{a%a#Rj!)5_ zfZWj*LB@(4S(rcW$5?@gL~c->wFW-d>=rrsj=*K>RKw`u$ianJQBjf|@ALcFPKocp~D9;3XQ+FZD{9dFy z$5MJi50s>ZeS@4(=223bHdfP7(3`06bwhVqpv8kX@bUAzgeF=HMQkd|csx5^5!F&Qd0PRsKM#f0_ z>SHMsa^f*}NDX z`ar1_DGQN-vKdk$3$j5w62vRTKauw+e(jiny*l!nI*d8e9#IFR#4hbL^cV9MpMt+BzbvB! zBnJlK^ns3|RF&u|%e`ne+g1+w z1r1U9g!e+Gl+S=HaGZFKrAT5$7r76g{Gok=e9`WsZIrHw(ZNRXZ}cO!*TjD4SD*(d z=K`NgzX@7Eu2>FD!3OltazE$|J}dY^{3TGo$Qnw|u^seJ90W{3-GNO6HmZe~i5wFR z_S!hwgEHu4$Kgy%m4;UxS%%2+T%(nd1+aE+FCwCXym(h-u2Zkx(_2cYXB6edFj7!3 zdGE~JVwcYDM>&K3NiMr9$(z+L$(3#}XW9*j6ypnAIsNk7d5C0Sb5U*#Q9upqR?6V{ zttgEGEW_x>se?T)BK9z&p!mV-uAC6P>(KDVE%BG;HynwL=IK?#$> z+<2E4e!muu{^ckL`0lTaf(j8~{E<BQK$ML2gM>ajvnq2T>ME zy~I`6g`XL2*gontB2JWNcQTfc=)D9O&VU%Y*lH{&NJcx9qHJHZ`fPTky;z5sCe@eK z&+KP(oSlYpqf)*G{+Y6_M6!%)in98r79{pF7v%QKh_n{hCCl4!iwy;NMlz2Y;%7@q&_dcsx-Gaqc&d?q9LCSM|QER zJQwoCqCH8)NiIgtA|oa8J0e}1iDLpCU_%gdC}mCI?@>Y$dMb7n_<;TuzD&WyusyJE z#1+stlrn|Ql;4O2fC=FH@SB~!3Rnep-(m;;L>V$*7sf}>Zmr(AH{yYk0#b5{0yeLmhJEhoI`c2u>j`D12NjJO%HGiCLNqW#zZI)ML(sqDfF=G@Eh?Md=~rz%Q|w-D8Yo-+d)i;SdMg| ze9%u4Z^*dOmd0zL5#-LH@*3p@S=tNbtT;cxNGyBCl1(bF;YT1xENiUr8e`%!Qd)}h zgMU?c0jp}k7+G?h{((MB@Rq_m;8D&Kyp3YqRv~m3JjhXa+Z4rWzzfgq7* z1eapLRmlb^D24^bEH)sDC>682@&DjkMS~N!MSYt>lF1r3193C$A;95*^mj_C&cwmb~P+Yea@x;lAI8<|O-^DJMOh zBIm8F+0csl9VfL`z>&veLRYFQKOw~dELmiYPj%(R$Cc)4*j|219mL=I8v?(b5Y4Fa z5%1+6df_f|0PJ^twusRb+dJP$X(b!D#h9T+^OK`3}D-zY|r0epyQ90@(;; zU4RHPlx&Ga242b^=?N5M1wV+^kcDQ!c#$3S55$RR#6%vWFBTO=8z_1#MYR#>fTsAH zD4YF&&NiZ3$i0;j0os@E?1%m0cNB32sze4AJcAxF>wv5degmpRkyoYoI(}m|lMxE> zlSBtBq)ki(|1X(1W<5}Vl$mH`2wj6~n3=Y=y!P@?Wx~Tsh!4SkRht z1AQ3rjG@iU755Q+;p|FM?ALnN#NLhuqpNP&i4DjFUR}Ho@GqWq1d&)EEqh#OoioDo) zS`H&G%v)A4F=k}U5Jibi0uS&ve?yUL@}Db6EbtClA|HYMK}STys*K3Jv09`E83I2U zrI0?zoPb_viy2kO7glfZtP=I{6Du^J7vzjZdmV~=18a&*F!GOK7BmX06reL!%|Lf% z0q{HRH~L|wOEROphnZRwe5ZVox0Elj6Ii>aeiYI!V?KV7H(9~K^YlruKOBqj2jj+f zuI$hT$qFF8gKq)5Az4V$Mdhz#b|q>@+fsCytCV~O5x-Ih8T6!HU>s8L8ROszA_|rB z9@2>`1d^E-JBN$_9Qd?T0HM z%*1j0_>DG^D^0Yu$b3_`g)SQJaF1k&Kqst*P}b?gNq6#%_L3PXjGw$hdrG@Pe~Gvm z+k$qmFB!g5_|lX6PVVBKEuso{6nF0Meb56U%GGVz^bRQx&Y5&EUf!*(!RgXd{u>BD6eKr%zPhU^ME6SEWdwG`0udMLKXLN9-Hhha4lb$?q;(CJUOw4ueJ*Gv@(61DS*zLl<}-`pF=V;FoC| zh;1nw$UI5zg?b13!4++O7uprEJ?gtcJ7nN6R{AZpUnE&Sd=gvZyI^;GVn>MB{VeXL zz^X=7f!&C`Tfl~PpU!yF)e_A!Y5Q%|ERB-6fkYp-{|4RzC{)>h1CE0-f<_Ej!vIz7 zill4SRiqTsCF^IRm81j_prAC2T9sZ|H-z<)^)Of)L?en9lAJPTtyw+ZLxe*FM@<&) zigr*knfn75p*^6sXaXris^d99Ua+9dXVd!#iU38iSAr4;R75L+eGQaGNQR6X`8lrB zNv<1h*tmZ{Ynze-semVybt$w74}xc*E%c;zSTyE2v&cnQEVA;Sv#13MG=jd^lgACTb-l6`Cl|iS?%? zW;@^&q)p~aYt4K$tqj+(DSgViw_F!gL`_kwH1fo9KP&*}D9Dpii7~QG%@Ql9Ku{{J z9uOAp5yU{vRy-BgAn83}IWQNrr)rW_=tZr@IG6+0kRYuSyb-lP_Vtht3X(wfPS9kb ztS8di@Lm(FyaQQ3=A&szk=c{Tkh}r?p>blJ7)dD4D>8uZh`PiJkslhmQM?aiP9hBO zFbi|$ed2*=t)QjifiW*w5_(XvKwRIZbr7_VxkzL~xu+Jxasb_kcjq`_xfTl=|2c>< zxh7&m#uZ*x_Wdw_o~0sQ(G6He*)u~lMpR7i4{IhlchM7NUj;1~Q6wxF_TVYV0_*Y| zKarP2U+@kxPx6}ffwBj*#%M^9JJLwJk&3X0Y|x*^-y+B;t)y5{tfwosgPxFMh8$DB z6|aeQIUb@Bv`_lVxE0;U-W2&R-hgsL?*%!KHEWS4<-1r{JO>m-8$nrDP#^k%zREL1 zeb{FqC>nF(+5wT8q8FH#cpc6g?K5JfO;Pm%>-K05YblUVSt}8pBPteMqiuxT2nvL} za?J&LF0xEL;8+-$5iLOeWGx@#5ISHEjDRo>=$FtzJf}8q2jmP07j1w)Tz6o9)FnY` zqT^z-sas+{Km(u|j$KeO*8UY)rgy=-=-ogA;j@Vz5j3?4!jPy-L#7h>VSkTe%f<6y zeOr+gL3*@jqzzGzM5WwsLE6w}2r406K?}$fzQflj`jaJ5G_Eru;NM(NA*xX2hqf2< zl{HA{p4e2`7lC*{9F^`x)SYxx&{Np{wI0U;9ZRA7`5aP zvbahJ?r_%zchF^&V_!MB7uZ<@E5W=KMj9nMWfaNBXleCC<777-s7owK4~1AuG?Lbc zUO=c#JT6`oD{tTc?qNPcEITAdI86^FJHIHIlt^$|I0`9{owLG0N-a1>jgt03KlBR= zOI!#{MegAqtPs+pIq1E~3Bmld0N^-x+=?Yq#tW>cXfeD3R+wch@*Kts3@6XqFn4f~ z`Ak1!82N;CA)Oc-2oj(~E2u<^b%8$M-PsqB1Ti&G40j@71y^!ASTU!?W}HN94le~9 zFE|eKptJxZLW4*v@oa+YFn8GrD;9`zU~EjfsNP7^V8q#?(cB#hoGsF=SV6`x=!c$% zc^>S<T8}$N|y;(tz|c=ED8t8>|R5L}CQN*|d@hT~+K!8KU=|4K3fdt0ptchS(@KFR zf)Ehrk>}KE#losPdH(Pm3UUj993^%nq>x8gNzK3~ytmMf)>-(hSR7hdiA@mCQZ^VT z2?7-B0qa07#<>V;@rs3J4pKoYuuh7ctEfrxooIu3F<5Wv2N0v^CwFFpE)uWYdQSU-`7$3v+HlvI5p;3c8IJJHFIu?S5l(@@&)$7K@`D!4ec27 zlB5aZbJ@*DeUf?7W{8|%+$wKrM`&XNS>svQRLO%9r6VUN`A9y4@5lo~e+0!~x4z_i z8QV&}L$xnT-UMitHcaxnn5*P9AzwfN3OZ2Q!A>3(C5gOq>_i_J594LpMm3(qI*-^` zp(S`JIdS|>dqh-0y3oF=NE_Z$u~SMk0sr);c}T80EAb{`7IG9CjBGNacF|yPk=B?J z1>8W3O3xvjBS$1-i1;LdBbL3j@H*VbBk>O?#+Xj_!RWO1l$b=?gXfYA0X-JAm)?xH z2@;h-+)1rPh93J>mHk8Tei#qDAFMa}!2S}k7{Gn1SE6*NV?+iA@dz=N;%TtzLCHo; z3-2RR&-l&f#Wj&~MJt1|7|4WkuFwq7#m@K-V}v)N_afG$w#3N(Td~~ChC^Dh*F-QX z@FF}kV;p8j6w5;|LeH#Po-Dj00BeGMw$L8Uioj}7Drn`ghN&O|N*VfQOayEtUI1g~ zzG3nMo*6ig^oM3qV(49|bezj z)W8$JQ)-D2piLYP`jkvDy_4(#11*?oWb6jo1Ba#{_C)*4h^e0eq-7*;;33c^vd(cQ zU4i?ZSwpOP1@`CJiToII`S4a8XoUAMut!^2ec|dWG!S!vW#-C~33NtWCE0PA3*%YE za#6nF`{X?gtQ^rw;eN;)5GC^rlriNqz*pP@t*5o5_gCU-?!#l8q9ISl3;a$CBHmm0 z0oh}GCZ2$+UU(kwq6m_*N_?wYKE`~|TltOh3OOZ;V7x*(aA>OmjB{W~8RKD3COsfz zk8w710`nvd1RViAh<>Y|0iF?Az#@8?XM)#|F`_NSl2NY|IplZHi+L2x2lT<%1>H&< zgT5j2L}I*;I-0@^wvq|u+`$9Lmy){>^avRN4HY}U)dM`k6&A%CDH(kt1?mGmJ-q?Z zA%EuznDTA|Jr(Vfdc+9=Fj@u=uq z@zRuk=3S_doEPVg6<5&#*;D<;Be9^|gPHvTMM1B)Z(Oc2$(H0;gk(^g7 z_h{0);ynZMi84%7z|}liQC6ZN%BJGo$QQpg4z|aFCqz70ew;Bg=jaB3zD23 z?GXB8JSs8|TOeo+@=Nq8D@>3x%A|vGK(7fp!{&t zpOG`AAHW!BJH_iO2nD|>IYIUVx-xD?1O^15=ss-#QI4`7mxz-x%AF99GwirXLM{l1 z-D}|P64fR{m#L#-Ph}3!8+<3KQuGJBRiYt9-euJl{ZJm66H!nJ=gv71b;IXi4&s~8 z7iA4S_oIBB zLa!iPLcF3ND9OHK+>*IRABsg}mJT>t_I_yG6r>|D1lHov7voiqm69vjca=VDL$QX4 z!N@_bQ;T%dBXExcI1Q~-vd~0+^j@HgtTzH-5$zD&K~fcZD{E#%Ixy4Ctyti_)eP^<+ z^WUvpBC-fz5WHgs`^cOt^0kmq4QErADW&u;vNMN%UThg`6tYpwK1jBLJGG#9f`LIb zyc-LN2=ZmrQRY%%OZol*-**D;koO1$hvOPCr?z7z3K&Pjp2TwU-W|9_4UaNjoK0a^2r`Ow}<-cr$0@g<_AkUSG& zj6k*z-_`XnWWeHJB`kQ?8QCkLlagUVU$VEK{j1pm+IY|lRsvedwHMNaejYS|Phd7r z*@**fqpwx63krr*v`?&sU`p72vE!hvtiJ%GsL>*=T;N>`_y=ea@ge$vy(S-Fjg+~| zr%E6CI?_$`lZ;iwS3p*j&zk$#9<7Jm539!ZnB@Xq56A^%2^Nj3#k4Y9rG`93iM3UB zVUU)>OVNDX1D`AYj_pW>PW7|!bFe0ut4(>wlDm~aTZ}J|Ris}hPN5~hyGG1xa?H#! zO3Vjb0{*FEQ!*Lqnj6+l=!@ys>7O;7z&%P7&0P}Y73L=yQH&Y#f_ydSC!PWCnhK`H zJfUL}Bhp)7*Ag=YkX6VtFgN@k?vu4v_&;K7j2Akm?4(lKl8grQ9x@0E2&}+oB$mBUVTU{Z_+d?j6ZFL;Z7iFKfpiuIRWR*ZSU+o1P3K@a+KJj-{4H67&c zAcZfWy%GI^&anIm=D}t`f z5W?OmIEA{X^$Gi?+Cb18b0DUHtWi$U2X|0m>>LZ<%ja$i75B=H0(dTXMa@2t7vKqW zle!8z2Fo7jMfw8Yk@ko;xQ0RuP5FUMqOGZE3y454F4uHm(*=!G!LtjF(#8&1q75Mu z04Bo@9~rOm8R%P)S!S;(%gp$Jzsi~wGpIFfVV(gz3fm^{`7lchnPTQIz$5AcaxS!) zkSFLk+GG4feGHQ;7>C=4S?5n;-egtflshvSU|`fAO1QKfzy3zDZ-s8pe&CTc9Kn7O3Kmgv6`(6=PT#_qP?;Ne2w9eKo5AZaYpk4UgL|p} zHsmtl%hIBwL1!R*IcGsW13HHImg7eoemP-@xel=dGCs_eyFvMGy?nx3s(_{|S&NB}>HZeRhRIeU5U6Ai|6sQ9Vy8LGzooI|{ zZ-`S4_Kj_?5? z_9;)!J}_d;`e&AmIO~c|ZD!vbHM>o!rO8>AlwJ?78nWw{Z`82?lkyK7*}pFAh7G<} zt$$pwAng|8+^y@4<%6Ef$jr<-yPq6@1#XP#ZI~9@U||m9oe;LQMY{`#e6&` zzt1b*JY1A_c;B|YYwh zbjS+}ha8wVX3TkqRt)?3s^ZUIy6+*Qeml_^T@~3lUqNex8L!Sd*kb4mR@>O zb=x;bHJViP;=;_51>c3W@3Cvat{#Vu?izOOwXf|S(R6&*%;(1qJ+QvtK;M?;^U{YM z{c%lKcjt+_MqO}uyGaB6GY%g)_Va4cYTcLKgkB_b!ubZC{^x>xYkaJ*Rc`tg$W3y}xaDcv(#T{^Jp@v*IY4t!z3_t!0%b8PF>VWA8CKaOwd{URmw z@l@^uQl@Uw@>D;d?NPaXHuSgHfi90Tn}Xr>Un7Mge_Bse4mp0@%M** zI<$4_1B*v)o$LGIo5HEzK6!7CE)_dgKQJNbI%~*hFAiMzYVYd8;f1ZO?+n}esCVLR z7hRXoH#A6UH{agt`=uTCXa4-XcTw8%O`}@*3o?3Mb@1Dpjvbz~*Ai{XUN(JyQts4m zz~rZwZhf_4$NiI<9lQCJqtDO%aQv`iM>dun{AyIc(JN-8O@Fri!Pd7NjB1#E_2vaf z_pf`d`}B*a`W_nO>Zs|$tsh-;6KYEZlid zug4DmxMO+yNdwx&jJhae*pS^z&UxTq^*0YW^7ehZvP+`@x3zits(ZVo-gEu;5%aFS z_>E>8QmT5pU)vKGd1U9@{GDrO8*W})@5gYmI<<}JziDUkoh!C~`rLCzC;#xx2WbOscdmt$ zr-W?THFrgi5$(ML4(wm&e$Lpl;*HCnzz?%u`{BduyR;d-{CnRcWv*-0Np5}weNF$q zZ0C`s<0IOAc7Drq7kRd&R-E5$^6HUiZfVl6QF6!nqn~fstH}9F*QPaA2x(*+3*NWFFuUluUQR}DA?OXkDyA@?YLNcmBryk{Nx48@&h3hqZ zuwAb`&N1DVx7XTgGyKY?@7#WHsrS?ScHii2`N};TOJC^t^WFCG9TFdW?1dSbGqXR{ zExvTLXVb1L62_ewSvt^l*_oSrT~ys_ukW(Wk-Lv`{A%lUo`cUV-}3s( z<|&zqm5VfSUI}tF5PE21JAzV#kMs=j&3mdN@xFtpWgG* ztZh-H?UsD9t^HZeAD?mY)THI#4!n6!i<+hrt~$fjd{yV?^AD%SPJi@~o0>e_d(Vsm z*0qyXeiHFue@D%YyJHr&SdcoVO~^|xeLua`v@stoy(@X4V?y*ND@woY9%MWFj){LM zeP!fR!*0AiX-L9dgZFibZWhwxXqUser3bw=&Arp*jF5zR;kb3iD_;Nu{5bWtUH#Jy z&n`J?X|L)w?2cKwaseYnY zRdhwG)#qIuSDk&Y4=Q~BS#$EE{{x(lVFR@P8<$5Kh``FRR{_E^5hg~x^V3Oh+e7VPS z-o+ylmZnC$_E2`O?Hf(4zPP@6-3k>=)ZQx6*-J-GhPgG&#T z&Tcrd&(6q)&vJFq`t9Xv@Ws-OT^?KZ^uY0J-uNiA)x5Vq-X2xa^x2meebjW((2diZ z?0NUj{cGQ9b$&Zd9^Pp?JoiZV@9z6{|Bji%<{$eYwAcD>Q(7!&vZvwf(eCjdfAY|q zD_3-wplSQkq{Yrf)8{pIq12r$BYL*iruh!=+yg$^k~~{_M!>Pch0`| z`b!ctJL8dY6@?22`WxL?9bJ_>wPVlwoFyO4&eMc)_)krDw{Yb((zPi2 za$-iG9jg~*oi(G!51-r;S1^0pE&JlG-jp_M>Z5NM7o9mJBw%WE@r&;|cUA7kw|qE# z-s;uWU+lkaVhhhx2ZrA9{UOt+N7@IdI)7b-Yp3m~3ei|xuc0Mov9_d4;?0((_wTNG0;KBFs$2AyY&8&CVQ8Cc=4wp7yNYlRjt~!{@~`E7Xk+4>c(de zPi^qbkJZWdf9Dx6p?g8YH5asA_(Ye48GRp}`9`xf59~a&>PWY)UAw+{^PAm*mAqY> zFF)-%`iZ-Su3Mko{aVN9?K{5Pka5$dxqu57=*HZ9t1bxtoclo_nhAE+Rh^j^(jRgw>pa_IrfZRIAzjJxA-njd@$g|L6u%38=Tj$ zZ&jy`!{%j{-aVGI>pnwAO2Q^@Ls*FW+_DoTCR89b5SM z)1Lvou6gUyi>L0Z>QMgCtjr*WjqKI=rcPbbFWO(#?%=sm2?-zFlkob|j*IdxeyWd8 zbL#}_w>CSY--?b`eGz$cFyG$j(6?{(-hyef1{-_UOy->)!=s1vyu9@Oqdz;&4`_8l zo6P$Cqu%~GdHOrvF)R8n7;$@zkoD?u?&2fctkuyo_J6;A!MA5TerWMqnE?oc{zqDG zZnmOhdY3o8er2OE@%{Jj3gULX24PL6{&atbbIz{O!EwDVYcTo4qnoF!(7j^_qH~+! zwsRw57Xl$Yc3cP&U2jVA(q>s_-rK3iRZ$-#)(raA2EFQS`lLml^!7at#a?w$V|AAA zgb)95$C^HOw=j>1?mu_X-S7(JvLOjQ-E(gsc$CzFf33HKW(PVe_WNughL}NoMZ% zPrucBc3ID#588d-&0Dj1e4o(!79Bgft89J6ng`Yz1}4?Ndfe6Z2QKTl?~OCgx$?1Z z7Eav<#JD`_oR(KFpBOR$VUP90?gs`OI=th>qj}4QbZeY2X6W4QiBAscF{)AP(3@^K zH0`H-pClJvwLK-iW&0uDzcPJ*f7`V4wua3A;)%1reaJDT^U)&*CIML|`+wZtKIV=K zQik2I&_8cL^`2$#bv?W?zV*B2H3P0%(fz>W?DJmU|9R0_hhDsKL8j00;_HVC0nb0| zu--KEuqX2CvBo^$?>V0&UH|UP`5U?*jGE7&CvNOzZEtYRzP%fQi;rj9<6k+jVaT+h zNA`EQ7v!|uxFC1gd6E0q+P6$S_S5t)AMCQ~7{=PqJ(AJhH8;IJ;M4Ob%p7vy`@%W< zcYc=kQNy((*Ud=lIDE~11W}dGpEELi`|C%(U$Fe^dwYgX9lHOaQIEgX=e4FEO(+Hc)8d;??+)M4X~*iB<&UQAFMA}c_|=r_cfGnJ)ciuq zy$FRyZ!&(IviSY;n=J13bLsvT+crF%+3uz`6TTR7Rs22a`{#h5a}Yf~yLI&b>gzs> z>=wTJjnAI8UGd`ukvnI-x$5YC$N4*rQ`*kDt#sDn%y!2R)5Z>Z|G~$nM9p%5Ko5L2 z*U>e()AlzmZZ-U=&%%pVElAlj`h)4XYubRy&+_Md5Vo$8a%3HW#2V78iOprZBMOyGQO+6`t6q9gi#l@y#K3Z74O*Reh@YR5!`!-7+-7H5_SkpN8N4ICQB`@{msfsse(1}+8WunOWdmL3??!ymdCk>#ezfMM zVG9eNzxj)=woHqt6Wd z#Oj|9Z7rO<-n((=$Fp)`<}JN_Qs=Qz^CNFRvhT9nAAcrm?$cLQy=Ho&@yZ`AuO46+ z_3^nce_(%p;N;Kd-?AxF-@E9>ef{k3F35N;vuyuojy`K%xbcCzvtBNJ97Tnf(i%^kdBgmP(4^SzLuP$`&VqX!?=|ZA(_^mhi|4O@`n`4d z?-Op%MZFWA9lFj^9lbfK&9X<^^vLPf_R9Mn4tKvWw!I?lOae#v{~qtClxS;vuW zZ@I1C?12mY^>=M~&G*BzOFK4bJ@)BK9%b1LEHoKA(Etl7>re{VDG57VW{W$xW9p`uT9tr*p2~z9qBKon?2f$eKH-^W*Pd zJoeT#R_C>6wOh4n{A(45h9GBEIItS|pZ5wDC*0iUJrH^3Tc)KQzgaf%hLXc^i?DKnR~XGrt9ANadqS8TlC-hVd#RLskh&`$+-5x&FiN% z+kM@=oukj6d;820yFck#*#CpeuJb(Of8omN-AnGNOuF9kW#8f5%ZL2u=FSTrJh*wz zkZtxwAGI8~^>*u#r+<8UZ}oL8>$M1Ny7h}ThCSb$wWdeYi7$QCefZY1r?j}n8uQE& zyS@3;%(iEz9N0E}>a){^e0ON%t<^hczrFe1VLv_j-lg>~^}Y7f-sKX!UoqD7#ZS8j zMw_-bxOPXA_$wd3;JR+p{i&Jh>CfbkhDl0JiukI*yc-uk+-6|greNMvUp0vx(dpLR z%hp}}T1?gXFWr^A(>M6Jb2h~NxZ%Nw!&g6-fAG=!D_eCK`%p%8(&UJghP{Wpx^>Es zRm(@4zx^H*%eW!o=7imQM}BwBgO?tTJ^#5gv#YQBUkq76$`{aD*-ECU6Z9IGYo%@!Y)B2g>>#7DVZgu@|!mSYA5l8S(_o2HS+pJ;|{JWslK(m z>D0!bG#=N#X|EAEcdThL#5QZyJq_B99)0$0=iS@*=hn?G+Hh6XSXj^N^B>gD9ycrg ztPxF@pQYQ4^j_w=v&NP7oY-jAv5Ph}bB|ctb4*d&b6XAFm(u<+-F<`azOg#@p^YO8e?A zJ(@gp_~#?Lo}1bFv?~fkR z_o9i$S*@G*Ij}bA)}z-pZnk#Cw#-IV*`0eFy*J_9j(UeSy5*BY%i8z)abV}M&F}10)krsJcJlf5ORfz)c*Vrc>z8(XVae-V zt0EdtyQetp!A6&@>0jvu<7W8BMnCgvdq0{_-jMZRuZQn0YH|3IBTHw8H~aANrC0uh z>}%$Vi|rq9F2o?p=A>oejjS9GjDWY&Nex=&qOKDv{)!RL$LiM+gbRrRdrXHL5EtL7uT z=ML$7U*r6H+Ix5A%@$ z$se}PZQf*Prv?O5gE3)ftA>lsbvT{l7(x@Yv9nf9}qe6!a3 ze6ysq#WNa3n3vcfcUL}lMndBkFH2jy@ho?ziJ$G<)U5oxbpxN@@@mV5cU&6g>bxYZ zd55OwPUto2{P5?ywcR%Dhn%k`K0C=``OljNdtCR_Lk~~dp7q7k6TjT$e__+KCdX#( zT5{~|qkAvwaPO=i-l#OJ{nRmaXlDL}>&|a`-nuP=wl+ReZ%@M`=UzJlv|abrxJf@h zd*Q@`Up+Q_;hR6it(&)N(XoM#t{%Q+*v^jmd*j;7+;4OLVCvFiVcY%Q<`bW5a{usi zZ@i{;u5Uv~&iJl==YZ8PT3bN#OG`*y@l zt=`OSn$cs{;CV%BGG|}3dh@3rHuwMMnj2sJ>Vo{LsP#?n8TMwSY2gE%o~<0zd1I$< z;;-Cq8)i!jS@6i6p7~?US2lcd<2`-#KlL2{?#8cPS+#X+hsS$Zzn-w~@M9|m&5sz` zY<9t;1E%%3bKlIWLrcxwX?xttOOgj3{~X^7(_i&;O)kW8*yoXC_bW@xWzw4nDtcT2#`& z*8R`jw0Oz~(Np*Bd-&29jWLT~Z{6X76&SfYsI3D-#0qE_nC!{R{QpSa>Z*Mtqndd*?9lK*EWsm+NFu_;`v*R z)|T(Sns@K5pKQM1RoB+dk&hpIf5Y0GyWVg1&WOS0-)clEG8 zI1^(YNmo_-G?)RtF%D>NhIzK%e*XHI$|CBVMdsjS!36el>eY?NLop@HzkiS15A_iV zsG42gL*`mSvEL8p-Q~wKbkPgbKO1tR!;Eu4P`h!kR%sF%Ygu%egvHgz(>CdDc1K83OKhGmZ_d`gOieF7Zig9oURy(^{;y7=9 zCt#SDVR@Dy-|wB1P|Y^h71WF_mIOWzT|Y0M9ln*JD1q#DYxpe7lo@GX*w5UPtW0bj z{Qkw1>FKtXwpSh5@P0zD1oqKe#OB2%%J3>FA^0_iYn6?|Lw{@%sf@Tw-DjUdXbhf3 zSAQM%sk#rm@2R;aYc{2mTMpr1gmQAD;>>>qmYQ2yfwV?qHEHuGrJ%naf&J3vt-Ab& z-`69qS9_!j3Ec3OT&2}^IwYU^Y?O)jlCjgnot5`9On!DyFF6ZI7SR5n6x!lvtkH7y z`i;VeKyhW`q~|nccjrou5-Uex0~=t@IeVEhw_gSh*LIG;b3Jz@RpD{%t0YE^E_kkG|e$g3-7ZN5Kg+hD=9sW*O{tR1&+K zUT>;B7@Pa8IbS|9z?Jy!p&0BsiKOn)95e~^hydlbGKUB?*UX8zDpK!7PH8*Hn9(BP z-hK(2n?@wcU?Qh9(4_DL;aD4cB2y4@14N0#pLdzdA*u}(S@yRS5O7H~Zg`$nT!qkx zuEzD+8t14=wT;WC6gaB=7B04pL}8y1?nxcarB48!gyT&hw>$=1Xxr&2o^=vAe7N(l zvSC#Y6y+<2L2mz9NJ!m3g(N%Nmr=0O;vyCeSCiKp{#3MkIED6$=nQyn+j67(x<|e( z7WP(6cY|Z9GHv5)3Y1Kmi4bh*wpipfCu)b6et3=)Mph{tGpU`?kWfr^(Lzq-_HObbeMuN)D&iJ)mBH6m2T|PiLY-`C7>t z?#w&A!z_pg+4NJ8r&%vJ6i>hufA(iOq4D#DC=mVho%pi{8wajm$TqrWAOsgq zs?mueN)!u>ETO=WpW>g?bu88v3!52eH-RpZ?<3(TxTPaa>|RDN2f}&Zr{ASR6sCEl z8gF*l7vjm`bLq^zk*jiOFu@#AMGZ%6UdQqWNw_*-EJbekUe~ zG*R5}@|qz+Tm|A}f6K-3SuqwGa2hmXo@3;*e&BhUrnTV6ZfZ`rM|L7}vt3m7_V)4! zWNoP}r^>%&Jig6^C4WJ>jrMGNB4(l4W59XVMjCFLz|8Mv(=Ysym4BsPg~=zQlbeoD zPfbBmFrJv(>auhmC>^oBk~2U6GX>I4EI4{sL!Wtb6Ts`IA)4?iHSe>_0C5rMQ!0zJs>V->rK|o^Ll? z8rwz*_Qr{aUG#N#EQ&xA)4==6l$-u6EM?K%`lud= zIsHI$$osoBniceZe=e~I+xr`0({QWM zrTkK&s_>IKMoM@~n6UQpc9Cczrw@N(Z9H#aeIt(Qg3N#}^|h)uo!2w4_K=zxbPhPRz8LtpaHTEdX%X&rR=Ptep;)paK7T#&Mgr=CHBcZV9MPg_C{tY<0cA|Cm^ha($1axP8 zvpMpu6l9)X5jOBU{gGL0@tPPTS7QfP1LA7JX=Cb-jbytPMzvgpBlWXLQbDG&+?dNB zc9n3yG9r{l~Xs=jmkugn|3pAU0xqu;?f8W>~Ye$e?_A{WTa&Dl6BVRsIuQI*r za-2x$%JP%msobY$wbqGx3uOx1CqFo~Y9G#&Fxtf-YpB)q{OgylhM2xEkOnV&yjX{G zpZn>^Cvc8@nNEIVBTLlp+Lm+!mZf+I+h(#fb+=~HU=CkRoE)Kk9Ckx>Hcw`1I|pt2 zO0xB;65qeiP*vJjQ5@RSpyT%M;z1zt4{4cvu%CmSR0>B|b56qrS@D6WM3sF8>j%>nQV&;8cZiJgwqS`bTpug1!jqOR}$uCC%zui^FD%n{yk$M_R| zk8}=xuQCo4`(kI}^6SDZS#Tx080!By$Ylr1ih?u#SLxY~|DEaY6BOf3`@sPK2jvQ- z1B7P9fYV3cY?qa|%ylG)5$a$hZ1BY4tr~!CCMv9c2XJ~*ikc6nl?>enAe)B9`xdyp z9m|)N=W^XQ4jE?i&X0{rV@~)TQPejdlpwqMlNUcD%o~q?earFcy?4%>P)&ChJ{SW#c*nn827@?dH<4t^)*V*Ao!tGPbcI=VC-sViH zz7GpIhLUrGPJe^~ceS2i=x#;mf4$T-j>6{2X+9JSltC0|-B#@38MU4{8pWwPAsdw+ zDrR}uFwxWJ>p5&s7^LNs8{erZUf16I{CKq^fW_SEbMz*sSoZ*Rqx)V1xhs#8L=AT7 zzEECcPnd63_X5|GKk#pxM;u!M$z<+#$L!6&4(uDuhOsey(+gED`!VK{3cGt$jaeE! zY@YXLT`I%_*Q;@Ilw|A!ZaSr3_zRNIVM1dPhR~H?k4_20xM<<8=IjsNf6pb%rW`L?q=+kQbez4JfzNm9X1nDOUp`Lt`vz3jL+a13O zaD>zM#~)0x2kB2rJ%ZCHH#Utn-fSdP!VK2+%0>c{zNWzL=V{(3?!8Tuuc@?O`5ecC zu@@k;4n6olAJxKmf+*mm4XkSq4Y?Vh%^e)?NwenPKn`f2SUMzT9UC_S?>9w{i0ITG zyCrfYAtqT>%g`T%WJTdKYhzk9W5#BSxX2$7G0pfVszADXW~^nMkLul`k`%{RZ~8w%LC3+(Eu? zaPoUu^bY|u|K|nxYR*H<&@3blNHEHf{|aY&YRpPuB5-m=rH&F)3^+`ICr)-kXpfz4 z%ywXGr~{H98Ux^?7utcXIZWb2VuPgopdVV+t9Q&vm=!ks1rx4cZq)DY6X`BJRSXe@ z^3F95u|nyG3SxB^ijn6gf1{=eFV{U@2aiPley}n5oz1RhsC-OA43=6Cez+p>eg00T zZ&p4^^3O%s@|5b#EXdV`4HLBH$Now`JO4y&M;koY8V+VwI}zrBUW~n@)L*560`QJR zb)TdXZ=w9nZy)^iKQG#R zv%dNTy-F$QBNCrT{DcIL%6I&Tu`A&#wx6f%cMRgj%aqCtRVmMB`y1S4!uiF8!2fnR zc>2%T5mB$-C4;T^e+{_Z^g{iER$m-9%&FJqpm@w{KRy5GeFBvt%oFM1LkGtuAoV!Y zqG@GIG<4XNFPW+9VQVW^oWBO-nU?BwOC&hW=WJc(;pJ)uvA|1qd`GL5zEbt}Z9#({ z6}#I!p1Nmg8D?T@wW{}P%F0^3Y)!OiGhNM?_%n&Z``Vcy(~GqaUK$Z#qd9E^P(mFL zm&1uT*FYjK{`lC@ay&o!33~^DI)!#|2$(g&ssFX7DN&E=fq!xZeBZUkgO(WJg=<(% z6w>ldI_0H0e*vDXEqs6>pWGy&u}vo}ri3T!mBv~kBOZs9RnFjby{cv@UV*Os+dSZ; zMCljy88^nuHqVeuCU`*SZ-yT{fbUL)7PewP%uP*mJb^XjFz$fR3e=4JH~>!lShI)A z)=bTg6nyMTl|=$>voBe1X0WQ4*sG&@fZ%b{Z~RQw`VcJStFEq&tdzDnS(fhpqM9yr zSRI2%IgZzKTv%i1P|~|=qwqr}wDYPB32)4@$jVXmf@8Y&TW?Ai6^8dKR!$#m{yg)< zlnR%`@p4yDM(DiY+(Y0w7&B6K8PJx(W0S<;sB2Rb_kMd^wszK5umBL4p7(bb#~|tU zyzD82A@aQ+p=9Ree?PJQ!OE`ui>|9^ADGo{&i8Tv`>0xGAiRF}BWwkbhTmHFYJqnp zyV@O5RQU2}E62Q}zWbloaDN**?6RTWn@(O9mF2BPH%Y2aXBz*h#c(oI@6xfpNl5?g zX@Tk3w<|lJ>`R5T%eU1Ye8arM^_O_*+E(P8X5pd%WcF=vRt57(@oa{yn+nLIFVXq4 z`+tcaZPi=rv2i_|q!jH2M`S8!o>D3k%zbd*ng!v=#6SkO7r=UtLDHW|r2%AjPfn5$ z0|ObcEDH4=2g|dLm0b#L^*JWisjuyK_Gjz=im3YvQg>d4jOIeRtf{XxV?5CBZCF)3 z8(gAcp2WqMyvTbJ@IqU^@&;z@T3M#DXG`@3d!DqNT&;w$$<^7;zx^zHp0V-EhnIFm z3HTBXl);yt*IRiL?MEOFt3jsh@w(Bur0MLpZa=5{4=ic*z5DD9&a@Uu#s{-PMy~He zdxe)yT58DV<-#08f)p#e_mhW(WMR0SdSE@~D(<)ofxD13Sx|<+K@km68PJsXYkC7#yA)Fkl1YgpGxb<1^uh@r44D=)<{^ofLc=4H5@_N#xl2iR`s_Xcdz&a5#z7)(y#R)$)v z9G8iXZYMi(iC&Cdd6R$H9bh+9?!K0%_w7+nzi+C22TJ97ysp4+;+sJ-_f1MXLo2t zGFPAa@e&rt8_EgOqK4$(2eY(s#|hDRs#OiW`7z)^$U#z^24=@&D;2Zs=sC2)1=T~K zqO4f@Gg%~e$6wA}wprlfWy>e9f_wjrL^z7lPr-sm?8gRRYN@8|(2l0FWn&ayf47=o zA`)~iF4nD6LWf>16>2?sp7= z!@@@Mfo88h&hxcyxQX@8jqFRk@<>UQcChm_Npqg|AExIVn^-SA8!kQ-IP_aw*r(a0Ie~doY4b;T`gW~1TD8&HW*x4p z{aAbZO0IB#fo-IQNnn#VI395$4Y$`s4ljX;Z4h z=CiL#cfYHZ+oGf{=Weh1N$<8lFz18kR(_`Hc(gpp-{@bK+eQ-V zix{kOOLB!yDp1Yz^qB<4D$-{Lo{N=d;<=}o8AqXcWlPP^gx#wJC`~{Fx3Km-+oY!L zs`2X^fDvgu$H2_yb42l|^0`_k_&{fOu+Yp)*x4`F{_RvdwC7g%@8xQk>2NC&jgb{u zBG)!tw50dVqCs(#Llx87WvS^{ZC|c59bRD@2rf;3(BnB?7*Bu$jaTU!ClkX`C_CHD zw^1dIc%VWzUppVQk#rV!d^;|ecxsa~=Pi?nIyb#Mn;cyikMJD}Xh`92Uiy4PzUj2z zd|$BQ)E~>ZjjEhN^c?^&rh`0-o=#_$t)P~I>17^HI0fqSaEeR^5}tR2Z{&5$e}Ha+gSK!I)Xv1#Ln-c|0|j0Tf-M z^6rdKo2D^M!_c<1vnk#%NmvxvJy;xNsCiYicspR#YlbiV2V+1|V7}TrYj6q8=GXV6 zl&R*VXH~k1;|@@UZbJlDEehaUU<8z%CND>%a9hXEAO(J0r6iMA3@+^wJO0h(up%KQ z(Zt<;<8Mu=UXh|*IKon6pwqnYaDQvwjF#ws{rEKuApGB6Gq%Ymr@tSQrMGd!M$lv` zMsdR2@Pkzd#DGvbp85UVc-Tdh=ooU__Oe>y^U2`Y1Pl1(vnFTHPv1j^Ns!|E{_gR* z@-5&0I2LL-Ge}iZ?lCrc@Ng}wDrLNk2A_l|?^Js9C&f=~k3CMDDwUP!I<0I>zN}_# zq|fXqmS6_jza7 znhX;P6=-WtrYVD5v*7sn8fq);;EN~lAZ^XUK6Me|HKpCs zz3$rh!5??L8~datd!bN;J9Jo8^zVI5ZZ~7ryx05qKHcieUEnAvByq{^-Rw?R3$uenR-$Kr|AmBg^kM4~LMro7C;-wI|d^^~2Rp zzGGsQgnIdC&P`mOtg^<)iH-@zgJ8>6QKevjeiU+-%<{S#lTg@G3_%PV* z0j2I8ahbiFR9rHCI-k!2?iTl4i)q+A9qRRV@aqfQbQQmguVoKGvxh`X|3LL+v5F?+ zEDuAB$cF;D&kBW6>6)5yZj#{baL<^s=GDe^1bpG--TA7C&5=4Dhf<(GlwNt}=5vOr zPsEN6qPM%g&g`OZ*^6XhPZf00Wb?l~d~ARYTvcU}?{VT-7V$n)Io3zhwGP~3_M^~} zB9utOhRwJqS7r{hUFK75)cv1F_p$sUm~_2{=!d9x7n&QdHM!8Mq)vs-eN{aJmH+Ly zOGs5}7I>q&I;}DTCJIbxMi2$)Zg*nhrcdwt)Uq1DW2P&6t1?cKse?m%wHH3((ozuX z6Il@Dha0gu8-kuDb0{*N(U>N7D{VE;EL55o79Cnpy%z_3mF}|rJytVqGwIr5!!jyVB zkG2PcYIatJ8DB9xC~(o3*;Q1*9>6Oy`NanKjq0F>px|DnpEqZPAJNVYtHu*?Xw@4?A)If zh|hksnM=xKJc3F0u2G`!K+sM?k!WX%_O%1Le#_{Q6n1dz} ze4s|3vNciAr`Y?$$S`m|OW3>eWD86+^GAc`@g{Q?iXy38ovy zNDctjjTP{gv4Fo)>W(CRegURKO49Jdgofjy*F}MKN%}`JZmZZfYIk5{wL+AUU%7U? z!icQ^7w^Vj3F45C3&q!&+1k5U_K!(>5aM@>u zVT$j!#w5wSFO30iWcT*(?G+PStTkRbjBS~7=pijk4SMDnJO|zw7HTkmZJZ%@{tLnv3}AzO0D)$14z&Y%I1LD0}I{RittUfU@I!m7{Q^k0av!#!Hu2@q@PC6_{7jFy_W1qE+$ z^kh^rutG}F;D(7#DBNMhC5+Z|u$udRBo))n1Qh`_lV^Vf+)pjKwm`L~#sHpeYv-HW zJdrzDbfH7hIC?tbzwIxJV$bPJos*JMWG!1m+>H!oB2s3j+UM+(2QEtmB&fncJheA& zh1gx|ZH7w3Az@p;j(>JPLpU=~Q%Byt1-xxdsr~F2r5PDdGUq8{#|5_ySs?22HvD9Q zCIHAf4sesfZmYM>WL&!4EId3zGn1LuKK!aVdQ?65lwuDT2Ce;dJeep36_K zKC#~dJvH07GtkN)tI1)to6$qSY>1!wj*T{a5a{!IJI3jc03)r2LD{ryoT(F|0RpIH z&R&LUD7FEjTC$mKWywt=6NXQr~T<`4Y3w4nKbE#*w>oX z?$9IbaC788h2RRL|5GskRs1%SOsN$ByX*e6gGgkqqNXAB0sP2Wq4$A@0SQQhMtn!8 zZJekJbWOo8-!6Ts11C#%b7pGiA!%QSX*A`#S39eOBJR5Uf{udu{xC=+f7YlD6EnbE zI0flD;u~a?1<^sY+xdY?!Q%krP9bzED5XF}4eHQ05P|5>DW&8~ut9Q5k#-q1xsJv{ z?^5F8;;hcFUqA8?q(lZ)yBW`3{Wf*s3j+F!2ls_h8KqT4=;pcL@q3(fpQ{1GSk{pf zTy(a<0a!e6R8Zdog$u>C7#qrl&gh3J3wU4ol)MqZ zp9>h5L;UObn&y8d^C|-iX-!DCQzHlSYtCy>gm#H zT7)x`Z#=XNr6IIpzSvr$fzDrQchMU-riL>%#VfVG)D{d;CRAX4yyBK;czQVZ(IJ4B zUi&*zTZ84D9ZRbSq8H5Q~-JIR=23P*V?X{d!_{cnZSvb2?&yZdBJ+RWt zoj|U(^fhG_-5@<*PcRl04!_LTqD~mOcgQrM<^}w{*X=Z`6dhm{U-~c z{HCSgvvVC1wlPJ=<3f6LMB0U~hxT=$!?0mk$v(1UAoo1JN_@h-xtQDLE8RnQQ zyGAHCbAM zNU-o^c|x>8PcJ?4dZ z+qzGZ8OmxxhsC=QJSbBCaHKuf_V27Eam6s^Vh0y`&E@zoYIUcqr^x|L02y|;Jt*mi z4^tkbrhgM!nd05!NS(QMw!mMFlz9?JV*5%yW9lNJJ|ZANeH>>m@G^j&pq)yA<`KLz ziEjl24v~$#>0W!ZlL`I@L(@0=*fynh9e?2zOn>cMSW$lwylc5R?wgr?;~p~AaN#Lr z*R5slfIEMib~(g%`K1{BZF4`K(7Z!3Agn+`JRv4i9Y<;x%%|Q)=o!9P^fA=HcxV1G z5BKa7pQM*@qYB%g3-3{g!1>lM>E`zxMNd3J8W=4O zUVPK2&sfX5A8pk?^pana+;?wR+0O zzm9tMrem>LiBN%tkWRrwK}Z4BOAkSadTPfXZSm7KxM>avm&t@scaiSF_S_Cef!NX4 z@?5=Q9i6>5aY}AMg8dO%NOkSW#>Bem8mt zQn?VOwx#yq_UC?YI+s5983Tu@d7LR2-xRE>@F)#EU?Ee8H$IDwdJetF3w0~*3NO>^xsS$}cUbEWnJ9Tkbr#7k<^i$ZeV z70-x`Q;I=Mn3oZxJXk5S4_yYS!=Hz9{&>D*imqGE&a;g5Uceot19u32$B}D=`gBz8 z_qFJu*e#{89gpTAdzlKNe_)L?&I!5_mWQy>KzU{cPHhNfFy?)?{8wmwm-i6;ac5Ye zfohLDSsI3IYvTlt?$}{UyCxY;G4=}AqrqW{jYKKo(0`sLFpg8R{$8ZlDayj-C27N; zlI0Z|{tkb-EzSs(f}-JYspmM2%oVx6-52b$@4tLHA%2tr4u=B9OILoXp~e?78gai0dyK zcg!Axx;DES#}EeU@hEI0NS8a)6@zr z?#_Y{A~k6vz1-MLAbkg-r-HN%hp)Vw$EO>!&ly^A{5id9nHuszjsMOZ|#_G`8=Uc?u-|Lg#_M^nR+yKp_Gb78^o!h&3=p8wN@Fj|UXU z;fTvl&xov3gy0`8+q5PFqX-!zHF)r-vU}ckehXl*72HX*TQ6a9z)@W+pe5e}5-97< zK#FV|n;$U0H#R~C)NpJd)Mry$cQ@{^{>S=_DFZ>E4@}K*ir2b?=7lM^f^0R^=% zzD8>qwVAOdV`X9LK zQJe8Zl{~;*8@&eNy8vhk!(CUi2ENF&i2zaT#=J*RmVyH&&A&x6fqev^ci=XezW@%{ zs9F#RUbvJGx>dqs|A(4t3UYw6g0$Dh8_$Y3IOLJXM32bqX#G+Ec02AAn*8%z_F?#q z!|1CvSCnA;{|RE(m4hF}Vuz6~!KKQHPOgv#%q3_tXpk}M-w89TCYdgVeFluy{bg%b z<%P{|324#%s$Z@oC=#+@{BjM0g5W$pP=Rb-1J1e0K(_le?^En01v|w=U43Tjv5zE; zlmyd$Dsh2Vqi^uguBZ7&Gbcm-6hD3_{}w&{H-72GI%djs7;fx_RC)a{by>C<1 z|8U(r*OBt=BcR{$uUeAIQ~JHbd3b@|^Y8s~I}hVGH-%J?M*kBfNr+_36du+Ph?3mC zUnO(D`aYy>aWS503O52;w{o`bosQ>!j33&-90IuoNN%H#b5jh2irT2(Lh3ig!$-V= z5c>{M$pR4(NS49>FQ$$E|Ly<(@$DZIY~k|gJ19F+Cs?JGIdSOZs?~HsZ{51XJ!=VL7QjYQ2xKIqEd~?|Fff$IRs=Ds?g1y{;T~$ z8x366=sq3EQ00I9%@?vlZ^Sht{P$0##D6uNpn!{kgoBTK$2UOtpS^Q{$j|<=O}n}= z@lU1t|9q5i&-M%Szdh;q43_+i6i8P5udXa`zrcWO8<4c2|J7JxEf`oOr}1eOt`Gma zMs%Muk$Z%~;%-1Kdmqr1pTjEsPq!!JC(3{XTru$(0TgrK(j9^%j67gTvOy|DLK5^$ z;DnWZ=mZ7L&vk_n$OFp76sWbJ?cG3mmCMgE?Rx!2=Qxlf9zY<_qX5k#DqylQEaeYS zB$am`-im=5i+u=8^}WCB5n1b{{!BxM%^ zLdk=+iiSuQ4n#j$0D7i?=5yP;gbAQUpFzX>Evgtg#V-IJ)^T2NGl%ipIe@a{csIp9 z{pPc<`s`AUC*UyRjD$8bKCX3>*u?^%o3U&?it^Eiw0 zI-rgV1M(V&9}xTNpxv741@yR=dfU{lD-_QW6i@ey++QiTW6y#{a0R7}Te->Epcc;& zzyJe0v+t-uv`~J!H|vt+_@B)sj1b;*1fV#Mt4J5zur;5mejrUla#dRTbPVfb0b1XQ z0RcMi4{sWVtLArMLHm2qaBlp>0<_CJ4idQ)gZ0Fl1`|JVvXf+8sxq7j()=<&)W`w4 z`GfcmzHsUC-3@?D)&Kw&4{EFR=YuBja}SX%MnkS_6wS|z=*`cH$PL5>8J%HOD5P%A zPdouYWC}#h1Xxbs`r?31*yB7F5skR_6M+H4YR_jaj5AvK_+DvpFPgjSvzV6{!s@Wh zL_Iihur3D+?mH}3U^~S<5dX0<0rYDyt^3Nhq6@zg%yK_a`51wCQZ013^sy3PC?C>U z38eCYwxRLL_!Q`1R33XZ3D-8=;Y9sWZ49C`oTfp(_^IdkDgjcnJ(xk-8iYVXPFjRj z<-@uP{^S-yI?N2>cLAyKhinIA#Vpx|4%TlEmUGcRfywKz0`)T?U*DSC0k&4X(xzj% z`rXQbSW!|T*K&8`W>9Gj>r}VBeh&6qJcxdEOWrN<1DN-j21aqm64BcEZkv-i=vAQM z_L4o*)|D~P$QzbB0qC(oXzFp7Vy z;)#BoHLv(;_*LTX^#g>b_%eW;S_2z88svmP`AZJ04~iS#_GDSvkB#H?0n-7Ny4V+Q zx*6=c!I^`#ne6vnUWVE&2+=|*8ICA|;9#W}v3WQbzl*e#^)X&%C*16e7f{1`N2;ql z^bn9FT+k-Oab*WZ80)Cf!!Bw~#B`w}7TvO-$HdzI!{p&FY)(J?94f1f7AP-JS++-o7}INqPc+x6oNy~Bxb3s zoz(e~i0Tkz!qk0WBjxl<{+m&W|AwtYH3IkYOpL^`u#QdO)YCv}F0?38JRxg3rAd z_i)7+90sF-LCMOmt?3HT{iA^8@nPo5C;ST=kRvVB3)Vw6Yr3T}<|q9CU5k3Dmu_>I zwBp_*!+Ax&r1gGAeogOU5y@ep&*Fm5(!89x=rRQ+nmy@RU;ym^mbyQZrlB#ni&@Nc zZ2-V0FT58t=sUY^b`9z_HJc|A}lKfe?qw;;* z(*bse5Z086N6L$^{uTk`*tPR*kNMwkzS^2^bcvJ3eNOC3CTbz>X)*!7GRz9Ckgm$i z6u&b7bkr4Cw4C_i8YDa?LNfJWQ5NVjqolzl+JZcDNT+mb;z1fVI0I0hA_p9nI3hXM2MPk(7_pUy8$$(KL4F%zaHQ4Wy&v0z<$ zYWm3K&6N-#R2m6Szga0Bel?oDpEgg|pwgsg{=7_!#NU{^QZ ztjI#dV_Wb9+R^Gza-O2pYCL-iC!-xvA%cBF@uEkwRIi}6p>6dFwA7JqK7^5M+X%QG z+!ZW{MXhusSWACD?zxOAaNcdZB zcB%JYCx3g`rw@IGANOhf;Xt1?znYP<%mEs%khgyk3`aOOT2@d@Ee8U~huvn7_s}*G zTnVNgXK`(#CR_%$g6hI6SN7c%H6(PMff}+C$jAJXDii7V&F2KO$5iLx0kjV#g?O5VW^+Ze{4O&Y0zJWH< zx}sI68@x*+D133;R`E{TO>Fu)zefCGNkC#?)$L>R5+ErxY<$0V9}A!7zqvv8&sv(0 z41j(~H`jHou1bjUven%vNdIkRTzJrRPpzE026NbsuW63BD~WNQB|_K`u+J@*@1rjT z`2)DgiU%CMh0`^&BtEX~Va05?MOKMmjecHtezq9UCJCMF@M`Il8nkt|mXhChKH9X& z{_7lPkTzNL?DA>dbgbNqv>l>7GK>v{IDfIn!*Dn#Kg8Nv=m(V(oj*T8Q*{V+OW8nn z@9@@uyfm8lv-A-|Q(EMOF_D>^Zb){QQ;e8fROJ@%mE@qtW4V; zVLZj?em?w#SNs%KQwl_!ZmBwzZnLsc7q9*&-P+JoMnS2@AP5KBv^_s7o3Kqws`KOZ z$&;-$m2YB9bFC>Ge|mi4tuea|Yz4{bhv`d~^^_N6O#WlO``=KAuL#m+;Z^%g_a3Av zH(q9MR9*Tm3$YCaYhBVC%@33~p=@7`lYc9hYNWPfZN53k%ijm|wfbAm6t)P}KtWzV z#VTUP9phg)>L6c4WUrn=_HQ1@;p(b9KJH(=_kh0gyxz%UH~?Q7`<^q2H(`}yrUJz# z{ue=HsK&%!THKutZp+}%(b+?nAt$>OSB)*m?sH;+pp2DYHq)ukNpmh##$5onY1J{9 z4w0c?hqEazPXFz6J)Wj3cKh3DiPZ>^29wE;A%0#(EYE9MZwt9*M|>cBbpPA8w^Crv zRj}+&;$2xjFJP2qyON>+RmT!~gT_z|ewAX#{M3s;69w>wVQ-a=mmT$#1O)tko<0|4 z6p}ws7&;kCJc=Ac=0m`p`S?k$Z?t81$j$Icvuhcs0B&mHR3Uzh#W5ODU=#4mQNNkjfK97jDu#kJ_8#Isl|ETd_i92aI{TsZ4 z4whR|;N|)VgK0je+7#~YV!(@I_Yonqs8*#vLKi&|E^$f}p`0T82l59&d)*FH{3wg!NO&m74?-$ zrKUuKd^dlg&E}AXwA#~nhlNZfT0i`Y+zH3!#mqe9EH*(lEA1G4Q1*;p>Ej2kD+Jg> zI3r@844g!NG(ye#c7&UTn1N7|yq?}aW*MtGZBt*wCG67Pka8kKD6&9`;RmaKEYd7l zVGPd+kn)8s-=MM-*Y?$xbuCvbgm3s{_Tn8sii9HgFBKfKzyC_o|NTn>EQlZy=vFTJ z2YJLPp`O+Bql^&_e9FcaDK22r>=ua%_~{$5cA2Xs;ODBesn}=NQ#RT!kM>=W?bCWX z`FB-8l?c!1v$dYSw2w+dqByXZpn7tiLzy7yohixGsj^k$qYBh(nZ(8Hv z2SySJ_+-o_A?1S%u*U8;Loz@4rz4EaztLhZrFCKZO|xzYVRV0X>3QjUB1AT1oX}x$ zQ6BP#LPY8O*?ULCq+SQ&Vw^s6Qr2iyqzLPHL<1OE`(?}nY1r?ZYf$0C3 zZ!oz3!z1rZ_EGH9HoTEBL9Ha@iimm#mzeE0SR?7^>Nf}JY#Y^8uGC&>$5g95A=YJOt?5SWN z-cxLbXi*R~3<4Yh@I9nDO|BJ7_wtG`;>_mp#L|mb{%NP$PZ$(91xP_%nex! zV=kphVnjXB>u@6rCqIY`0y89((#iU1bl(`~r##l3pR2u<;%cc5PE4kmSK?a zD9qH_Jb#MM9K~ZZBLn!O98k!==IQ!T5Ui$A*2i1_qt*E%%q6~vAg8I?LG}3mWC3!( z=6aXO-}^a6A6DL^x#9$hid)>DtvCVv>s1F1**L(R`wcwyG%ArMw3hknL(&?JNPqrc z4Q)AOxKzKf|8(ouI%ur;1?qJz1FCtP*!`z|aKX0cOSXzgnkXeO)5YII%qU`zyO^rGh_p826AD2{1GU)Ek-E5xNk73x$hs3&-PjGtm#;1gWlbK z&+#>(e$T&*pz;ml%)B5g?6Ppdh;r?-gYZpv>N`)q#kzx9jWYoJFA>IBs^%$?qBlN* zS+Pe#Sm26_SUl89C?cT)?O!PfQ&nHQ*mfpA9=ky2w;y;VVPjb$zdw<((YKc@&JB#H zz|BvK68`CrVSrcm(k#>}V+EK`#(3dbvI|6-ulca!DLk9y{olI@ZiTFRi0?k%f+!}yu+ zHNbuCXcRa_%EfIdz*;ftIMzTD-P=nrfg{c+DHjL(z|rQHFZ7O?VblYQ80Ic4Khkgw%(fi)7_rk6SI z(48x-?|Yc{)o>kFqloO6vEhkt-3a! z>5rMH?~=bIk86b`;CcFFSe*AWeC)~GfQ7;zZtxOjtu(coDZ78qJ@I!&K7FWp(X`p0YaVVNSw?8A4+!zKojc`YL=ucVs= zN!80lqC+;_Z(R!3`B*v$aQbvGGg3BG2LEoJ0QdAXoKp*)UNB*vlQ(}lLlJq+IE_HC zu=o1ssfoCTbhaRA5pd3JrFj)ws&WLr$m;JnM&?CUvf(P)U5w-7WH2OzKvw8L8=UVU zRZR+*Mr|r|4bc(3FZ{$!##+Ml6Xj-_=tt3 zvTEsW@Q7XM!!PhU+xu_U6)`~XUNw7ksoA&nkt6 zpQ6a!ILH~C8*Hz;>Ftg?r5N+CW;X)S&q_4DsX# z-AqBtWVC4TYaf9~{9(hVJv1pzL7LHjOw-Mi0)uO8Y!{UC%6M}MB8sgWVD6m$UDpg< zfM`M5uu7Ix!J{njlOz^6NA+euiD5zp0~BYhu2`xTg%4$bFa9TJZ1-nE@no#gvX*&~ z9Guge)$T?|g$(th5Ly@JGIH=+E6L1_%Agwy4CaiV2bEYd!{#!pp=8%lqGrq_d3R|B zkDWRsR2T|{2OZxVbTy@0;-!NPA0F>|3^u$_3a8o=usj3%$gD7fpA868rX^$#L5JP3 z&mw;rz>kXrz5{)8VeNr6-6TN~jAz4Jw_y`|fi9=sZK1k@3$Eoe<}-@RmFD%mP?LpW zuKgRZ_`fe?8$kyE*_~+I|E;YnkB7R8`nH6WC1lM~wroYoI%5~IL}Z8-G3u)1Kh5tqbMLw5o_o&yp7T9J5s4Popn(gq z;RzeK0)BRX_XS`N<^{K*$!68|ZxNS3I=>E%K8Hvv0}u^Wo7~jzAZPiur&uDCjI-dl zZV6SogL|x2XWoQ&-gavjhMe++u9?%TaNq7tpg1N1HnL1Ncm&9Z7q{Sw8svOc z9kUpDn$lALhznlg_a^ZM%(FjPj2D>9{T80<+(sciASBQSUuU@XfA zNKZG48Y9>S-{VS9$5`woZ6;ck3+>9JG$>CvVc^2Z&$QzXBj_x2&t$i42-h#XtoF4O?M5eIOeoh* z8ujBoOqr~|NnF%5nr2w={nBqc9|+>N@7c?Sve=)VNERg3)p0<(J?uS6WIfr5HuOKR z(#Eqvu4h@L%=?yy&CQOj+pP<~BZ)QI8%LMv%}D8nXu{YF`ajSAnCrFO{jsezv;uD$^le@nYU@B z6lG##U};&(H-EUhz7DvN)X5kaItLWIH$}}-voTzarc>D;K3KmnQ&{FeRlgGko{q>y zo>?L{@AZvM?zzLZIsV};hk)Xl!Otr_&ABhW5M~&`DUDXU4=!eo7@P0JxjMsPFsugb z2#}*!fQpU7&nZOGe0r+W%UTbhbUQkJn=mli`Y&QcW@=QDl{1`6zaVTl6(2hz(k3)ZiAz%$? zdfpJJ{En(^`-a&bFLM1{vQAI?@Ch=yw`1A**W({uVYnM&tMw2PYzBqN$B?q3b4UwAY4#t4o)M5O$ z5q{63pd56r3Ep>qwyBd$$Mw18%xJ(p(M_&xHn-_;4E_u^`e81w)#sk{_*9qif{%nQ zU*~0NhT^*#sFSm)Jt$eMJ9f>{qmRnkCOh@RYUwV*Y}aSGw3bHU`tu^i__5ijfGjzf zdeL!4sv@$JZZucnsP-CJ<4{1M$>X&)LIx#1t09rle42f zFt42tPn^VzPA(~JE&oW;7e+ulH|P|qMj9G?>?SqTuHe&Bf-l7FZ4r+;zr(m|pks+E zZvrz|Mj2L8i5aQh^$+LdKNWUIk2jST*m}RCimA-DV*r-@<9tLHiVa}ffiyky*7^?$ z=H7S1u$8t&D-~BUSvvt{it);7S;J?eY+TVvr48?LQ&G4>k4^vOhAPcLagtMWa4x~N zhFqAObvEJa&{;lH5G&BNOQd=WI#mP#@JZ5c;G!%5Vy)KVAI=>E;KvR00_X<8jR3J% z7$|4a0zu!Y5qy+jc0$wfcG)K2yl)>*5oJlKdYmrZ4x3r{@w4h#(=T0^SP&|xd_lZ| za&KC|U-~TE`yup=aj+jVl1fI-XIC!6KalXOBj|bR@o+9 z!s7`oo`R(njm!n*N8$Aduq1H-_Bwh4*1tg3ejex|Ckd+8WkG~%11jT*=S8RNLgt0Y zH!FY8{xjXuD+Yk2;`9;mkb}ajPUE+uJ`royEPcM8umfybnLaa7Zp&{AxJFRF6^V-F&_ z0Lmo@u;;I~oThC=UYZ}zL`oBYLuCk9^7uwAyt8OIWemOsa!WhDJeYtUWeN{15~>k6bXr6pY$*?J~Wb-f#JVUU9`)N z=oc!;-&Ik*esDJJgCkc7j=!_Rss64+goJ68B_*!BekEIf4K_ULKpKrGew!o*TSx40 zf6g-|oPIcF*F&27wT1O@Z!SG>hur=1(n%Vl1A$`p0M>GWT+MhBK6ijv-XUB0bV?!# z+%1UoQ{JM)%!2AU;mbu_@?J?&7zLxB)o~5NONrA;oIORJ=e# zf_l)~Yz~Y(1-Os~QO1!l3mj+wSHsZ3EMn3Lt|qL@&^v}rn3q>n0bkOqlxca-PbZl~UvS6iA#x7X^YH={KFblz zTheL#YRJncu9F}GBx$epTe&j(L*M}WNrHwNpl;M;*bUk$hEomonE%WUr1w1Knyn4Er$^p?33BVCXsoJ7joqMz*dURPyvSLvsRad`ZmPRxm5*YH zJxwY=0hEg&r;M_Xs=ta%i&RE_QodrezyUw7JG7Ku>jjfN=V~GtJZmI!5Kfv*4_R%_ zZSK73U+MD2d8+ZR$brPicTmGy8F{*1K(dPy0FxVT)EDKyplnJ+zwPNRrVMOXRIwoG zi#J}JckAS}hn+vK>?2YB%Lt&?1yvwlqjcshLXdYWVcMqH_+84T7YO!@#fHyCyNzc{4`f>f(q}9V>Ncxd1^VFP1rX|0HE- z$j58fY}qNugF<4`?h8HoM3w!$q;a^mc;?US6dh?(DzQ2xHpCNCA6;^4-@tY@In1p^BJS(Usp!U&RzNS#!Ir+ zSFZY7eZ!p#O{Mv}Fl>9>0Kg-{{Swu08&od`(a(U|D&y?VE{ zRUKosq7}mK`nUCLXpr+xm_0`@V^NZ9nIcmA(m)N_n$geAxoC#PqB}p!jQvMg>vi@| zBxE2v*b$2ZD7CzuM<1@UeqPGZwRXdhS05@xNG?W|{_3_2@$3xtmILy~3kXgz8zMuQo%z;K)H8&NA$tH@?ojBzXYZ1l*RQQn!ak24!M z9-63iL29~I-z+V3`nE7m=}MT_trRUQA%7M(Rrk0hQr}6i4zXLh4^;%4T`F^kE=r$Y zO*giWMe5d)Eq%z>BL&;bdJmu|MBf048Ga?DwS=Cwr03ZKskji;wWrOoesPZ@+cNxk zzJN9Jo>yn4sA}2-F7|?ot|qPU(v6wxIOM#eC-e(q_4L%>*Wi zDvzMl@j6yDhM%>7b8_fT1alwbi<+Q-ll}4PiaKA{u`@>{cD>f9QET0HGEyp5vT6<7 zWf#^E$m4m96DYn&Mi<6(93sH;>9(t-oyes%%Uj7iCrTtlQGGk2kGr^_$m@695E+iU zUqxT|2JPi!*M}@-^BSyVx80sE!D2dae%xk_H7d?J-$s_3c_^$Aqt+*t;S?S9!$Zq&c!PZLdWrNgrtVM@EDrWE zL{Eu?j6PUNn@sh!Tlaab?ct^(!(TW#O%EI+8a-jrudC?n3tb5;dd11uhVu$bl73ZE zL!GcTRr8Zgk)r6Lf%}hA?J)lHx4#XbBra{Qms4DfQsZJ@Z-VC*G6wo}K-DbyDjoKZ zj>huzf1!9FCDUBXgPCjO%e9JmkaFtRS0j*`AM3REtx+za=&u@&cifyt4KWT=l`lWV ziS6whYz>}swZg7hs0=7lzID)=(%}4AmdawAQ+|j|}4BoigFTQN;B0e0-{o0QI=H<>;6gVkeVGngt_n9f3W8|4Y z-<{}pry?#<qGplXsrElYE zE8vgCa%*r4R+?9^H$76Dm~#$9Yv|X`X4yN~rlC{NSpfu2=)Dz=`;&fMUiVU6lB;J| zjnk_?C|}WUxk=L`MJii$&fS*H+{W`{L(`~xobg4OYVInRv`loCH42laFN@ZxLFkPL zRyCQe@QO^xTw728XZ8w5azg!JECb)#nt9l$iJqe}T z-g4?rTx&eN``Ww>8!gS9714Z=Y;V8pWjjS7bF4)VJ~24H;o`@)@YSNe@l>qU`@Fa{ zAdN=!=|xfs9uiV2CZ+qLY+YQT7B7&DU8@`iw?EqTTu?amQq2RO3AVvaN-CvSa%5__ zA}Kp*avE97t}~x3oJZl~97S-u*M_5446r2TG6WW9q?uly{- zzR5HRA1ZY?z>X<%cKOW4x!U)`&G54X6Uf=WM1x7nKa%z1*5 zsSY+3lRedw0*W2j>mT)UrKsP-9}8Sw_dHUF;m#kVZ^jI|#!b>-aph6c2Hbs9!Oull z`3P5gBR5XXYA#)+cv)a4)8YKoad%9OqmT~n(%i{R`@GZQB?F#tIWS32l?1BaBI_jr z?5M!FQh*GCT;oyX=d;b23?vyzaI-x{r`NsHV$7;UyF?r|DU}BU&qS6lDJj)$&EQT8 zPXQYx`Z_Ra32#F%{?aw+CE314YA^OItzgAysSw|?*@Xv3LRsM?f!X2it0tXZ@w!zZ z2d+DmF?T=GrxiTVcyf;ws$Ia_tf2dU#!-4dQVsVhCK4He&-Gv@+w*1bD>vtzP?YYc zTyDW~T$WUI%q9t(I$|Orp)lcB`qW?K^Op1XFqNA5gZHcwr-DvRgOBCYfzHvkU-($K+X<~GUt#Nxk{qaKJWrP z`Rgbnp->~icPRkXDY^iZS}swNhw3g-tL26JcKz*_vTSzUPNx+u$RI8aRGn1;D#N?g z=|z{TxpW)M@pj&9)$DlmlU$jb8E;R(UD}7#>5{+_K>l2Us@KiQ=Mgy!Gg6ep;mgff z4oR<%s{AV4j}-pgA^p!xM)mdeQEh_ZF(Gw0xtA9_CsO;BmB1>@1GDsAAmkn&a_5Kd zPGD(N=6~Z?LQw=VAaSIx*7zR$04K9ISy~YZ$%zduHRan&6p>$(os|#hLLLMACzH!L zwWw_i$H32|2p0l#pxka>_ihzND+LKW-yT0;M>V}*2WTM%Yy?~3Lc{Idv#YUe4PU-X z>bKCIZ2D^}2K%OmyWbEwP&aw5Z}D~sk~Nbk1ywZ|wP5*2`@pv4|8v{sF++PMM}~zV z`!m$a7T&N-wDX~)991MqU>{NBBNx92Lz1^kW4sZpi|Jgioc~=DpiEv=TjD5GL`Y3o z*mD&UvTO8UkAyL^kyC_IPcQgl=&=hM8}A9rUW{>@H5Ojz7Hp*yHPdTBY;bEu$zMEY+?6d8{b2UoRgZbQm*vyv{+je<{XtjDfoG0{A6s_CK7yg&6w-@~rG4Fdm=P+~f; zed#_8I|9-A*Se}R@Xe`ai7TrIs6PC_Z1zIiLPt0?XU&{JQT*H&m!r(}YQx4Rw~f@1 z!^_vYI_IwH_*ZOA9WYrP{cC`grelIVa>x=7e+II=fX%p@d~TrqEeak3v5@kNm;=g2 zQ-5*lN)sJqi1NR-JEWaTbT~A+P4E!Pk@0}`+;3Z{#`E6Pf86s}I3h}8QPB9Gol7+K zjyHKUjxi7M_4qNn^S_^0;^8Ib@bS>EgAFLmxKm&2{{05{iPmv9Hg$h(YIl+VE2)I< zK)L=Nc*qHg*OB_wB6wkj?$b9;6)Q3PR>vuzvl1BkdY5Uo;KR%V_r+0`ifJP3tE)0ZeUeCWd`&&dLWZ}(bX3p2}cDuptXND!Y z|9GvN|9$!%6C<^O;wrhAcj%YDT{^H|#(5H!$#RU_;2durCjI`ZSB_*ftjimFOxN!S zoJFcB_hct+{VR$PKkC*xY4=N6*5Kx|rND65h;-xpU#BE-0=Cba&8XF_L=&Isizs2q z1J-u|w-=0iAX zhP`p__cWTjDWsW^UXB+plsMWHMf`man#Tq?#$n&(FRu{h{o6@6dl!haIBmC zqMRsXRL~s1L|%EQvMsB#S+6H}aN?f@Yc`?COV+0P%6tK0)5*Cj=6LO+?Y~+UB27J( z`@&JFw90tqbt`<7NnS?gGD0;fvSukbhW&4`d|@Z$_&!vpb2fX~9X~Uup%#FLX)o4a zi+IrR?<8(sxPQl=d8t^K8byO&%J}lAcSTW&PR({0bi_`ba%exogX>P8;VMiyLWXz{R$vHs-7n??oG&)z) p1Hvu$j!|9{R8n0Groh0B-OI=T`RONo?{{R~4&PM}PLPb&% zQB*2aT2D`?3643_rm=cpRRng(GU| z=+krzR0(7v5&ow`)W(zWZi4&0nT$|jgH$%36&&oXinkzX=3wOp@S!AF2P9fsswXY92ss!e+Z^Rd&8ShZx}W9q&=8WOZYfTXmj29 zkJlpT5_Prk`Z^>n0$$HgOCRs+?N9I{GVnO!FIykzBP7N$!aFR0%J##o?H42HhD0zB z4BC$;yr82exWJ4U=vFuibYUTjKQJ?F9(Wv+%kpDH3Z5OX3Y#6wVTJwtqAxo%l;JDH zgz!f1hzNG{&u{Z*2MZ@FyeACo@Uzy@g@uDGtW6S(7hQK@`EdYN2*)})y26>E53Cq0 zW`MABeLSEC`N_xIH;5U*=7tJ;3}uH3Js9FW(2Q`FkpbR*>}WyD-#JiV;sHZPu-VYj zApZ{jc;Kdx7*j?tLj8b^2m0ag2A~7%2;hVSL!UYrQP7A1yZ`@93k@0hkDCtjj`&7d z;b4AOZ@%DWb4nD)-_bEjKY~iqcd%FpP!(7_$~%}V^rmSrH=3vy68dF@G987`(bB;ISxx-BBLlvTPdF{;k0B(~H`xAUPVCY@ zM#N9Juw;O6aUyu&?E#9S50UqU48;?K@1uW0JJCRREnpDPiF(3|-a?KszqS2;1rtC( z2-SZ)eiTZ6f#_ca0^vIxdfYVg*1iZc;$sCUw{Fyu96MyU<_#})Cc`hcsBokGV2_&I7$W=^n+PWZvrZ`m+ z35(pupe2q@j_&si}jt^Ir=wKqgmMB-oAB*+^bnRiLoGBYgyIdfh3yGi72fja5nthe22tRb z;;V~^i%*0qUYChv<_AT7&a(e3MZ(xfgnk*jzROhpZMn_An}@&1Rdo=5zGL1%@-vue zL}7{W=b;usC?SKm1u_@O{#NGyRJ8nvGCz+T!m#%5i8B9d6oRS~3uS{s*I$G{;C~c@ z2NCEuYl0sP`VTTFGRpUF9fZ(A&EV`0MInO0Pygr(7Xbfyj1mrf5TkyCBt)F=Dysi% zR`)+gr~!ig^%x}F-59hQ&hUc`1z|47j^G5ane0&SVDq1@n*4mh>Zf~b*xwd}0vQ|* zPq;hc&E>E`Uk5ENz|v&|&lN2?XzRi!*jqaGmNf9z3>C6y?E(AH46O@(duPvxV8Nm= zwu6K&3d9YK8}5QP!gY}UTW$~gQ*3Sowz2__{(3Dg4BQ;=2qx?RVtxGTjaX{`JJy;a z7{T5gR@Bdj|0l})g|*0k4I~Dzp7S%9fW8eNVL1AyI1!Xme?OpnpWq6pIS4ra z6WbYj0|m)H*v`NYEWr(~`u~L68Q-T^97d>jC}&_Zevof}9vA+m8yQ3ckRIXg#(#7p z10&b((2PMj31ALZg$Mm3+<*L&Lr|Eb49fDqla(L!@_(>i{v-PuzZb;=`x^QNup>jl z>k@QGdin-LJt2aHLaX(w>#Ki@osI90j0kl&42~CR;k1M${vbL2!HNGMC;s%Suz!$v zcpYt$-XPuycQJ&#`;{X&11Zqp*z)Jw)DWJD8x&f8&MILk`GZxk7mjVs|7RDH{`RcG zYwO^ClU3i=Z3m@re+^m<)Hc7#E8$+^4_^J?)vvCk{lRDj+Z&K3V)>!2J`u_uVHNwW z9*0i{{qvXI0MQY~r{Cn6Fg^akvmZSBx9|*03kUH`SgH$o_SX$y1R-$-5eqv=_G94z zYN|npB>%JN;Gce9@ehVAI3)eoJlaD1e)Zw!i@|?vlkmU1|ATq;|FTag6peqn|AVdN z{EnsEKlwf(@%w7|Ux@;AT>QVd3-~WbfuKnG8^YlG;_hDwgTI>?U`tScLlk^pdi*O< z@V65KOgsO6Fwpt_)cAKf^#A0U0OGGCdw-QP0XpATN5Wm6hYa#<5WNVqENe!=U46|H?g~|MJeDz^(t6a{@v${L^y+g0-FB zvAX+bKPWJ;m;TdN2K_5>@L%2={5RkLJ688M#DQ>y<%b?%viQ&S0JGQM5C`9X3&jsT z_y^xJq4PIAKsNBr9fOvIzDpSXCk_jc2J$)KLF!*SEb#5S0tWwt-M5Q>o^KC9(guHi z_O)l60Q6Po*w_0DzE<`hr-gshQv(L*TTK2NUnL;m+3$!WgH8>6L)xDme&3%}`A$=Q zEO-3}m%IMRF@fI=+<{{P*w-TCh$I~yyq>;}0Z9lBq0Ii;*CONfv~_fKbV)=V0*OG- zClG~lHW>DJU2U8mNk?DLK-a(kPt+G~3;u~T`1^$_worp%4=wTsA^w}|Re$rzeGa#i(n#u@w)-AF3AH|(Kqc02Vv&t&GClcaV2<*w}^~ls^U#z;J5SO zP3^60@oqd5qK``q*O!lDd0RQ+e9hQVHUvL{ACE+!@<>s>A-+-6KyozI)PV07;>)5~ z1#o;UNqoCdx&b950Ox0A!nb4TNBM;~2l`o>bG=>kqkKXvxIR1z(+?jUZ=9BoIV^5GhRN^{bI zes~nK-{{-yH~I@ChENCr0d~bm)6Xh6+KmRk@W|4c=x1sW=u4oo>{;|c zhNZcl=|U3U&&)*6EhIS7$BZ3FJX$CgFpfnB*&zB%89X3nz-q()O0l4EQFnL4(nxENa=kwi74Gi^ z`M{jvIt%?rL|7Ay-OPbW<-?q5)EKyjU=!%Tx3i4q+49Zdd2^D@LSnRS;DSIZ%>liK zF_Ymw3fu=c<>Am+NwzE)D+`U)oP*iJjEwg&GsoLu&r&(?9N2*xL&a0UKTO~b4r~cn z4P?R?z%H~Pg1~+bc$hcL0of48hv#7)!9qJy3APJygX{=CrO|c3H+-8wUmW-(2Ihr> zF~R)N{DPogC(H&mFgG+WTU<0BY!Ci&;KN*THi1qgD#8d4<_P`481bkbzyk2moCB{U z;1aY$foGiXHedr}CkBfW^$p{+m}t7IBb#Dr8%cMynV1 z=ESF(1pp41z)4@QBk0FMtWP}j#e}hd?V(T97t#T+Bj5yH$xQGq-wts+5S|T0z7}H5 zjLt!R0pCJDlo-2(IMg=s6T&7D`4D`AZ~`_Y#()km(JS=BL>LGEFkxIVRK71@3fd8J z0zTtW1zh4mdkAk}e`p8BZW~BP91)I@0%LSSK7;q>B-AhP2z-OEP6k^$!F8A`niIk? zj|kdi8wukAemO7!J28M?%qF&cWD{Q=_z`gv5BNa+g61KA0#3~kHvx;Fm*7{pHwflL z23*kr*Ej-bARhS713N*RRE`}D`lcbRbHekc@CH^d#Vosh@q zy)QNgm=oMf)dAe1&yY_5d!RL#9hd}|2jIm4X^oDpnG?bd4#o#Q1pCu~&oqR82hb%P z_=X7j3v&V8Kso?(0B)0^A1b;RXM@HI8V1?{pF70Z(1I`<3)&F)*3K-52YnL2rX0*C zG%5#tMWjOC;5)!S4tVNBg1N#R$cS5DHwUauXdBvuzW5aA3ysShjSKE$g63eh06qhL zXkagxpPd=fCgf){He?6jJqyMgXb!K)9!RG!%|bSXb{sIw0KQ0oJ%l+OI~r(AAhbaP zpTT$#_ibVRfN}62_yFU15b6_f6a*STg!qQ}JqGNFFbeNMuYji*j)CV?J`-tn4A=m> z4!A+MB7t_J>!6DWr$}3nzo0L(AeaZ>mhS-g0UMi<0Tbph{vZ_So%z^2Ky#`5AcR@KCX9&%8UbSgykVM;`nEF@j7@-POxH=kBR-4|eCEKx z^p;PCaWE0~q5*S&I}AfGW~5a?NP`icVnD-$^S3~82>f7yFNjUp{Na8+UJZPfp3vM^N{~RTlhf`&%pOI2f&dz zUZ_t3+asL_1e~E)EVfb*24T+F*x)%TJcsZQ6pi7?%mMiv%@K_m#Sg?&%r6K#NHc&d zNCy#q5C#yYkeeFpx((RC1HKWr zAwNX8MmYy)0P;7|Y>0DUI~X%y1@S-79F0Rqz)Ly_=^?T&Xgl=f0DeL5gYb4P(cmX6 zu3~evwWOlhhx8K%ed7@4fPcUhggN9p3S1|{`~|uVIR^L&>>Lt}VF2YKfLXpRAM%{Q zAjl6;KMsgbg8q5vekRIKpg$_&42%`D5b|G)Q#^PU#*TObK7e@wt`Q%w7*B!N2iSqn zAbt&C4sji9N#UUJBCf!*kRvlu89wc7!>AeWO9|QCuR}3gS5E5Cx3`?gN`4o?tNva00$U&sq4&t|&_4n20NkU4jnH*0hd?+%;{Z;>9Kpv} z%tPZrIX#Lmg4l`3@Ct1K50Q>R`~iHzI6!~-Ot1q5@Q7(T+(Q|_CCUj= ze`p+FFO*-PTpsxf#SG9{8hQ?J>;hayen$BV#sxpDW&sU=drX07*?*dUQLT#g*3UVndH-UNp@Cmko zIu>#WVax%%LXPYNJc0TZX)EMp=sAe_*w_FohyxIZebE@v96-OwfN3X$MPxf7%pc{5 zJcxrFtR^#~fbUQo#^N7n2iU_5<%{OP0npe$3ery)w>c5oCL#?%yhgSMA3%xcIiL(>TpMdy} z+QRsNc#ZS`aR!U;pp%dfqcHmfWIgw#d0LHW&nMmdI`pja;ZS*lg32v zQBH>P9e6$nY(a(?2A^a4i*ho+JH!>>J{lvk7ueocXd|o+fIg8eP~OQT0LGz4Mz(@H z0r&xVAOW-t`tcRi+(=hIkFfjHh)ZKfOkksh%j!@MZh<36R?l&#rdGzj|TA#s~4T{ z5F2<{u7~sk`PYmJyhH8!g04dy06u}aW4SGi17aM^3B^t<-l8#s#(+IR|4|)>^c>j_ z@Q-N;jKf?9`~iN3nu&+$vA{2oGXehKI#w45@qlR)_!4puEa#x0`UQANT#%n3-=OtCEHAMQ3p_1Ad*COm#>H@s*$84eT!T0OH5=q; zFn3hr0iPkZxd^aNh5Q7@K}6b#< z!Zv6T9?OGZT?X(=f;l6*fwqCRVs(!b;yd6IVm!hO(rDK(4qSuzgSMk}4WUnbusRo8 zVIvi{0p6hVk__i#)o(h?ZUc}Kr=9YlTiK*ITjyy4SgW3H3#gW&#)Q@`5Wc#0!>FT zh7UOq-~p@u;2xMO(gLK*fKRNxgEpLi$B4h!dH~>`PP8S232IP?)f6)mSeFI72l@(Q zP!K#1nhG@-ig7R=unFYBP(#CbVa})~r09SR@hG+k#)rjDfqtSqhUOT6*+^J}BU=jA zEQRZX5D!4(5XW?Yp9s%LlTo`+f1_7emtKg~qDcGUJ;VkKcLO#Ad!QN;u)zp|wOBq@ z=OcZCxCgoy5)HKnmIp9_Usyi~JILOk?R+|x`!La(C~6yCVJ#K>3-5(x1tNITW%FA(-T2DJrV$a}O#iulhP;5~}ZP@80=S+J&t zat`Eo7zbMS#9}zgT_KKP`LbZI0pb?u0@7%d+YRV0S{sIIXdMS(nUB_N0sB~QSNZFl+;7e4!0G(asY11bqXSkgpJba1aaOKa?9oyut8} z);5v7P+bmKMlmLEK_uosG}Ct~Fw7IJKLGAgUXF4D43B6p zLe~dd!^G-+K46E0VluRca%sd9#AT$NkOQN<5Q`xL>t*yl*UgmIHb zK^Q{oQh+@Nw4MfIKpFyVqJ1w|H-;KSFi#X~1Dzv5n+5j4Gzz%l0$hR`L!g~ONGlP> z;q{w#B78!8Li&LC!iN1&Tbyr*K?K?#^a(NGx-F!@zKA2w2hRz%arFyxvvOp^z9qsT z%Z4x9ftL#RLxdj)AMj_vZ$ZYI+wA$=cgPUMA>dwGjOWwX;pHx8 z-@e5k)j29HDLuznbD~*==aJ)E>>X-OB_Dcu<9c4+w#D(`M@QQ~H4z==Kt2^pril)# z`Z}l6;Cb=IO^ za0+Q$Z$|Aj-+_ywA|z@Xf!UmEH~;fyXIJmxZgC$T@D|`iHVjcdC5{tWWwuN0Jion! z#krt!?$YOXx4mX;&W^s75nBB@%8jwb>CxT9+51LLP`l(2eRB&vpqP1a-;(DQYsSre zY3vq!^eldB_drVuuDhEw%ITmy+`Qe2O)972g86@_t?M5FTDL=V&a?WRH{Y`sN zVT-wphnd3Cm+^`>^B?cu8Mo&_`l95j{@2#z{_WqUazgydRC@Kx)1$9c#V+~yvQ~n1 zlY8xOExZ5yD`HreapnC~>qnVE1yX*oy-j+T$IW?aEHS_Th~h1;WuLbgavmAm&3&~p zEc;#0H9OaPVf)`bYDs7|=$`uOQ}4z3c5>_!I!RLv9My-+*b%emeTQ0Buu?;C*$sbU z)Kk~p6N4)rq;uZgjJ`bQ#fdbRboU*|wnHs;?LkAj&ACjyvfobOLX&yU7V7MqZ0{cbwki;>la}_V%)6?u6J?P()2 z8YTv|m&~jgUfsH2mel6uYShfN5ff(E=1$UbyT3(wD^q}#Je&y0vdwhOxV;JE4A;i> zzp`|Ty20o%o8wzI=FZ#aZHMJ<#@tI?1WJN*c9~OSV5a16ac#r!w6>(l4p_4pr|at^B|{z=L71 zWboUsUv7V$kgjc|XVupF@vK4b!z{LT{l|;*zfN=}eu@8d+@;Wyb7z%ItI?;Y3oYAT zRDZ1sTel2czv9v+`xgL&navk6@_FHSK__{N(8*Z)t}1zg|Cq5;@MfYblH}*PNp=sH zaaUYXlPfnh-YZE?Z(s36qpallUt(T$gdDr6R{t?xOn%q?9sC7X;^&IHffGJII#N4s zLU+4jpzG};XJ%LTM;P8&IU(T8TB(wrg5&FNOOl%X4&%)YBrq;*Fs7!GRx~CXK2hgC zJ$mkm|B(8LHC~C@l>sN0v~}-XRwZs_Dk637IjNo>KYWs8cZ=83SF4U>l0R-V`j{7X z_*h6sdY6c0)mBeFrL!V^WOVsO!yZlkhX-5DhsYkU;YkT6mpk1)%}n(<^eBQi3Voo z^JKrt0K<6s`N}blca4O7Tp^0sw2`#pASI#6-g;aocgG6f zDz~h5PM1~rYEs}8^-OlvhbL-co(gH}z8Xo4tcwrt;_9%+;l{lU6MxE^OhjvpjbZf51%%auy38z~s~%+l~Ry*^QF=^_73-Y_k?rmK3>@FS+gN3hkd29 zj^s0@@id>FPUY&HZ8|B`3Uy@>L+8@D(dp?rU$hE2CrPh1UU25i_f$&yO*(F-@SnTjozVzgMp)3cd9iV9)Ho1PzR8IQD4Z062ol2I!wrxwzBezb~-=}J-Eo5@a za^vlzr{<2j#z_f#aNCcoKIi2Dub$?ty^N#?uJ-F8-j-LVJe6%e{GfO*edWXK{9;ae zuMk`~5xSI>VPX1xjbRs6Hm%n3XGw`^y;1kE{GhV+`16WVnW8!my|}G&dN}v`g|jpi z&&_sOb1}8{LqheMWuqrVZC*6@dUtC|>C(cii~G3yrV9MAT&jM(@f9BTNHXru-D8T6 z>o##|r(83AmRE9{4`(lG>n8@ZvFbid5d=(*lzl~!G-s9A#WYoKvGeY!;V;=_naTxA z_9_N>oT`{A0N@bi6zO>4>oIQUT1D(ei5hX>+t-6X*r=o|wk563Q&`1zy)P1t?*8CR#OQ$X7 z9lqx2>fV<+bLpfVQ6aPRlk*G04*6w^E!J)v;Ol*JV^X>1RQtA^%j3BP&%4-Uk*(1M z4|3FNieHrMr)K2$E=V6}m?jcm()(mr-_$Cm$Hh_OPRx>z-jPkJ*X*e%4R4e!V8QZoo3*Alk#HC64fB1oMxrKX5k1HPl#79vK=)w zO*GMnVr|guF^yBWUuqfc6uoUDe{yO5hjFD%taDu9)cnYbPfoav54!YZ%gU*0SIduI zd1TsZ?O${=uk1<1HNw&>wd!={&`m$#L08JSYwH*h>%bXL3P`WT&by62qVo17FJ|hU zbEQ3WJ|m+d3>@`SKhS?E67Y%OLxQ=mPFyobD51r zbqOs5!vm3HlD2|>GmU3NZ$cIdNdv>V7_52!!`qsq! z?ku*^EBus2SKGSf^iX~T_}jJ4c+%-{w+byH9j;a1t>S4Vw5C=bFuhW7-fe=OcHMxB z^v#X0J{eni#>p@*V(X%|;!YE<%P$YP9iVk6+G#hs9Woza&MEO2W5pg`M5{;Ohb#?x zty9&LlAg19TqCLMjQnuh!yVhiZiJ-?fxlt7vGEpHDc4C=b<+I}=_?oRh&<%_?Dh6V z@9rGA;FlB`D7xiwz=*kC1Buhnoxl{Y#@+y@SyRvK*eCjE$3n622D7&EeSN1#&&D}? z+Rp0K6)LN?XsWo}q?g+$%ToIFE!|8N-#KednzS+3Om%`;5}&Y%>$d+xw7}qy{)`dN zrC(R8OL_BhWb)>Y(xClIv(}$)Uujl8PUw@?>AND@^5^80$TV~v7~y^IWAOq^$F*!N$-V%{(^+OiqJYkC9RHg zrLEhh4)q-JI9z7H!11{<7rN$mzo7L_#XzYOd zvEq~P-YsUk;u%d2U0XI2B-RT@ZzjI7qI}{||B#Ndy~-QsrdDzuk00Gvze)LVis`uB zkiwKryt{4Q65X4T7w2)h;>B8h61AMy8%56etk@M)kXN<@^6GU4ohO$>&mR(gXoK-^ zDRBkL))o2ZlBZeEI$SdT@QK$AN0l;kLu6y$v{;s0bzZc^BzXSkHxsmubw<2-u+^(o z<50fidLx&Lv}+sR)5jE2d(HEj+>%C-XkL-3hi@Lc9hbF(_i&2gr>Dh_HxQb4SDLT6^H=087ni=U`n_1;Go(rZ*~aL%i4 zm3;E`-p2VW&&ER4(XuB|yWKcyf||{)d&zT>>o!a=)ml`Rd#JD~v+QQnBL3SOOjdo$ z^pf{?6E9!dZOZ!GcWr-GXyv*#k7y5vbGyh1W>|SKZr&Sv!*`vLBQqsGE`vO;Roca! z3@I`0^Xtahd%R|!d^0}e=-Ej=3p+xOKNDZEJj?f9lAc=3@VNJP*3`!tJCJXK<*X|| zJwN^!Dy^Bl{j=O}t5PH;>*RRe=0~}&=W~PI*M3>uJ?i1Rbu)ITKfDO_iOJ`WeK}3K z9UE>f?WI<}ZkWYN7^}N$QE0`gOd`u<*oZNC3l|?%!>#%9v1j(t0&PfCKSHJBdyQ6p zQ`*^ex4ir{uVp85%s&De1=9Ye*YD%MA4 zbK9nu-+EsCHLmhmS;wPyx0mhT>J?YfJT^J$$>xQ&QY%lkSjerbu3Z&ZGhF6Mk8I~s zEw>U$-r{Me78rM=sZsZI?^u#N&hU|<;gh_aM^NnThoWJ_!=20G$fxY)^=-D7FF5(u z&5eDs?~KK&rFp))S54ZZy45|^c3vOt=zt^kR!g3hZnf|K`1aYXhffn{S6RI{`EJKHrrzzP1g+u=_!7viM?RPk zi3_Ff-o8CY@!cvJPyO*R>NlFQ^q57>^R+5gZxBCo*f-`J|M`{jFwde5wTHHzOwNyW zzac{REgssUbh!NPdY`nK+uo1MLT|dc*4eA9@Efai_V(gZ?b0ibqCM}S(>&!MNfq5G zlxD#8p&03hH=}Rwl`wj5TynKM+}B~>!u_^HD9^}8tnwr#8N3`qujR9^}f-08fl#$y0t|O0(Sv>NT`52!Bb4isR#qfC1 zb4hYD+#lmljaj+mnn!et{F0~BpR6)jZYaO3KfIlL&ExFtBL|*AMR(e8#Q6r%S#h^x z-$~0UYDPYe+CgBB(>iiW1Y3QOvYa}-^IeT-(Ybx2it6@_NR%6yr9N@hi>gnyt_o>0 z>_Uy(HqLwN8a&^vG*DI7DY$(58!3B_PL|et*M4$Q+=DGHqC?kQPSU%jzPVy?$^%dj zjbx7TBYWNO6DzsXr5DERRH0iQK5*5=3%ngZb%OhxBX1c#MYdU_{^K)6IoFPEqa!gYuX+pwUr6AXvitgLF%HGNePM^+9u#BH0Fi)SoWQ^!57m6$(Kbj-22x@V%EwU2x^Z+ru) zj_>wM`i-46qWgAz;#khht{R_&;Wf&3*Nawn%qvjP-|1J>w(~7J4xg1g`F(cWa2-{T z%5w>RNy-yrl5n?G9-A1rM>dgG`K(i(V!%xByLmjC%?C|9>oDfEkI~)WMXB5?nWIuk zCp>FPhp{K5mA+z~m9A6VW!-w`NrOdujVqqqR`uMuwy2EUrXO8bsvc|;rd)gQ7A$Z) z&P}sDIAf0JwNp)NjOARP>s!`U=2B1c~;adbSoH(Ea}2Mw$5eVS8&&ZY(wpuF~I_+#{yRQw#b$Z;aX4)9EA0 zzHHkas$XP6LxM%{DPxwMyM4cUljRrf#x8b|k;}??u^-=5R*1Bk?UH%;bmWZfiVrm> z&by#oUVpD%mba@*sco1;=cOx0<#B~~Mr>3HN~r{vzb!wLUizi~e(HH~8u>=E^1ZG# z^F-;N^b6~T?5UTHcMtQj*3)m^AT>Pslt%C<2f5LjqslY(j+S&5%a_j1_n7X*-;y$fumnlgpJDT>%R)E1M>0bGG-M|44pbzG8UMYUy#a zhidlSjOw7ezOlMK6?DjR_gv$Q<&D!qsVN^!CFV`MA+f#t-i552T{reGjoB@>&aG|r z+}8)w`(NZ$PoFR1EE%q$T<@`o)IP3R+HA3MsEJyq?y1A#of>PEgUS!z2{945;cGiR zQ?5<7V9x6EvO%NH+1EtfE0}Cjb5=?sIZ0nfL`}-|#T(uZstQY5V)BP#`-4&+#xj3b;}y@@0VR`h?1WxTV4~piMxZGyJgj<$z=Vti&xE&@ZDgo z=p}k{aqT9F&CBz{=Z#5!cICjrRZc7F-7<{N=(E=ZNv4N8eh#zNKK``Gq-FW*_+^q! ziJ~%w`7*hAak)up%Qjjn+O)Y|;kn9Ns|5T1-tnpXs{EmUj;1f~;&JiMGi8m;Ur6}r^7i`5r39q}7dJ;g*4~;;ElzRmMYEKSo_P3b&CID?XWa{*#rJIv%CGKfU+88PZ$p-l z{qof9Msxe^usHTmfAeDxrAiVA-MKStdske1@Jvb4s8H9No^y_T+A>?$b8hXvZnyZd zSz`;brRrB3$9!HrZ_$mwoXYDHWg4Q|s#G6rEr1^vY|7e136Jpb7TqJV&_?rZSB6Y` z$%6&6D)EaN3F9J1Gk4+3hIZ$g^PUwfh#0xU#n+v;C4@yiZeK=iAX}^)t*7s9xP5ZG z#&k*ZHr~wuhtM#!9*w5V`$uy<6pBbPfns--S-3?pI&v@gnY~~7tmD|u(a~}f$|x}v z+PB45dIanv_U47(&_CvXG3~{aH+G*`D$}0NOpA)UQQ=tD7#8Z$J>s2t+leU;c3yHf zoh#ztmn~DM-YCm$SL`_v`{4BlN%6``kiynB^JKHdbp6T1Lb+k2b-Q8<){L6j8?PEi0KQ}p+BpSD@bxUqr9bKoL8WnVmdr|h}xDng7 zP#ng;%ePFDWypM3+kT^|d+O`VU|hL@ujz(QN_L$t{L@~qMrw0zEpF7?8|?m=5HB(- zZmh$YS&xXChW=$mfzH<6qHmczbP-u{qUW9Uz>)DEnR9Y_bW$jT>ji&OYC7Q zw=OiS_cF!hOF@16gMR$Rf}673lS+3yw`|JO8Ie5V*qrL}w<1crj(hv6Ki#Lf%b38S zTr-R`Z<{=7=c03?i5J_=4>Md=>&woq_36&PYHVz@cDJGI7tf;_j%S;;p2J5{+VUmU zE>8D2tv$yfF-OO1_MVp+?%{g6&u`2Zx5+l#lBpZ=Wa{{+gsfHW(P>*J(aZJLnyj{# zuJOZJuFF%!qf7%TUjv_88}BO~cmqqehJ&(m$HTQ1EjOg@x$zCC|w z@KxuTMQ{5$^R(`4%Xdi~U=!i(xnqoe;1#yx+y&>R`JkEg+=9Oujjvhqtv+6Y>tL!aW0`Jugc%x+{4J8xvd4E z^yCo|^}0QK#@UWmd&ZNvZ^@fZOSf}))=uzt}Fzm}XTT)c=C`m`jHxq{qajsVd|QLuUon_5=mB< z97j7>1Wnn#9-rxc^@(<)&xI8`8}~jQHQy`orps|{#-lx2(hR`JDwX~c2Qa4Eo|-h` zbz%=antxz?^b{qd%bG(xHrQ;QH7u_3p5{HZ2^<5N$G4Vdo~9FvqV}#m*i8L!XH5U` z0GC;p>+I{e6G{7E2Ip8;3-nUUo0OWI(siXmz83gwG3%S&Q#+n6zd^jrh137Ke!phc zn1|xYEAHN!8FsSmF3wKrsnRBH=An5Pw>P-yK08qzu)zGv`-69PA6!a|k-bsBOK0xs zO;?{~6JI@;qPv2Y+FYDybmQ{N#M)ER^y8;4Uh{c(wcyF>9dDj5p-roz%wcKEtjkaA z(psSW_{dU^eABBu`qiadHjdbMc^_HL>P|1?L$pm*{>=ADPLxYzy(L$aN1N}w&w5_# zrr1;DT2Aji6#6A!Wm@RD8LSz+cG_n4eTw6gdwXhfo+LZojeRagb~*OE^W}|YH;uL) zaNnC#bFW@4|73$iy_k%>Z1_3)#R$Tv*-y)hZz~0~8Wz;%Ql2*ySttbGJLfmgu2qp0 z{^?E{Z|AzEtfiZxoDb=|(06M5q+~cj#lz3~_#=6Zs~_T*Zb=$(jl1OR@HLdzbswfW zx+dB#d72ySceqDHOxH;%2y@<@rdr*K4~iijz70h~l?x^Il#yG_Rh}JG@7R(&;+kqt z*UH4>)`usU%UiY?O*+`%pSmVL$9)w=!KmK%u(b4i=?!VG-{10EDw%0beP#@L9%^#?sd z?GH{E_Q8hjPrv2Z+T-MssMcK%E6i|FHy;S8f z+E0D+_%hm|f$i9xu0^X;I3Ls0I!{z*#f>?e&Ipm4?=>mZ^8-Vx@X+=HqCO4LW!&UB z!G%dD%+jTq*H-SGQ&nz!qbtTqVcGiA^;`DrnYB|X{g59qCbKTTcxdh>?zY^$N4%Ys zRX2IHsD;YL8BVyNM(;RNIH}$+@xthA`YWP~K9VMqXZ5 zd)~COY@SaMyI>xzGSXzPyXquEAN7H=068_6C+%bv-SS>D&1wgA4H?FN@_kxoo`2kz z%=PZuyEn-XA#PvobtIC0@uibk`U59IR@TnKv(Jle5{sHmFR|`t`*S-sha6!a%-v_W z?B44NrI|P4+9Mk)Z<|=vlFvSAyRqhS``E9Z!1bb*F4kx}W@;|IZODX`GB&W3HPa)u z@9JGU%Q5|){Y#EsJr;<&?LND!WaLih@kIXyua{{n9QtOMC#>mh9INtVdPaTawLmkc zPuq7jQq>;6Qp^@x(fZKk$_vLfZ*~rqZmnY=HQj7IvC|b;p6okAv-*(@sCukylzf{m9 zy>gXXC58!~FKs%Y)o*j9CnAlqu$k68n_HLf6T92frKps8UAum!x|p;?#@NDjDgkd) zXWG^bm)D+0GYm2=wNcHfahkNf`L2s<4~|t^DL*GFSc86iTe-#r)8W-hsij)|OSPh0 zp6#Q1dFyd^6gQQKt-%%UG13XLE_3Lqsgs_eAW?0lnPYTh#pl@zCRLu9CX*;hd%b5O z+r@Ljme|5aJdG)13ruvi>kX~ipS71Jo@8qERv2bkXKmJaFTE*0sX! zGj_+r*2~;OjMDtt6}FLDG7MA4nvLfx0~%ec=ZC+xE#~jhw5PPKwL4XOf-IA_{^}&l zHdZV}cAn;V^+x<9!e~c)0If8i!WM6jgKhFNrFPkyb2~g<1arV{E z7t5}l$+h9!UtDDKU{8%xecfJ$)~YQQZ9H9-vj%W7pM*WLcZR)Sf z`?AWOmx{`$`?;y{KIJT`N^R*nNS3DOxc9oYX%sLz(ww=ed0kugWiBtHgO1 zX-7qx8*I&w>NxFD#baHs)Z5jIU*Y+8%y%a7D zFYA8wnP%^SRQ9Asw=KCXVmGNRZ|`67cv^6?OCV(>S$?sP?>@=QuN56BQhWQgBzHVn z?eH9rS*{E%%d1Ia=Z0>t?9nTjO@CXRXK3@za(J=Eg9CoV@`)+ydkoYs5L=zI^XZvoRP+ngWi$BEhxIYg^l`mLU=uV80JXJ!G8y?l^XQSMcuaZ=jIDV+S z-s8J3(=5d)4_53*EMHo))_aQ6LC5_U?uk@uq;cC9ZZ<4DeWNHpr(Sj?Dd3XgY0Jo$ z{9XMs5_=2-s~(r1a@ZJBl-{s*=}f7w>FXDy#})?og+xv}{?fie=~)BlM*QXJ!B?cz zp6M4g-+evqZPP%B1Fqo}R4 zzW9yP_^2Z``fIiAE>PUPS~qMd(YbCv=5jk{y2KWvZS@P!2fS2Y+^WW&x~)dB$orY{ecZLx1TFB_ZnU_!U9hUX{WhfKSG41db?-Guk!R_ z7Dc2*S1oz>oO-V=>5yFXON#G@b0tB^=EeCf>};b0`Lhu2FjO<=zR%cR!Z`K%f&m5Jw1*`NsCUi<%!QZ ze{hFEq?%UM`@6*OyJmqcd(3mK!VCIgf$q}G{o74EDmmvh-q!a!v~h60m!x;>Tlsi= z4z*D>wn%!3PlqYP?9`|&G(*|BbK|y9@|V+}YnG`oo+t06*&jlQd|8KGPrsN!SmPP@ff0DKlB893-RG!ZZ2j~#mtZl)WLDvcq87$X zFH*vBFaCJHVXe{y5y5+X&!%t5Pa1W~mjM~Y#?wv=rH;*O4n;aI^35~v4_;JW=C{R} zow+}EZ94aoNKjioJ-cJhZ1TlSQexTdxFsUzcW_!MC9vS%ina-&JHy3b4Kwn}Zd0+! z&u=?eum-(9dD@)TlkaX>!)YwhSUAXn&LYVgE!8g#yt;k_92?T>3`=-FmK>`16df@O zKR3^t=R>B9AXhwrMk+?>02e99Wh)Q212*u>{^ZugJ7Hv4ABto$P)Bv$Lnmu%OgmeaVK zVO2F=Vw&ORsE!c5J0rfr8sg*U$6xG&-4ZX?yFG=~Mtx6jEbJfFY8jXEx<*Vvv-5#m zNQqQ-?Ase}E)Xu-fBo{A)tXD$Gi~9_wdR@UR32s5w^oHTwzqvOd$zk_h4-x!kcQ3{ z@$Ly-%3Bq5=tR)zx9cE&haUHkp7Lbsjr-GkhPEnx41AI+e6w`SNPme+y?Wfm3#SQeg*er|$K|!wjF5Tz;~t zkGV5e&HaHD+K7T>=!DgTKqjpXYjwuJ=~c z@9=`wM+r@1=UKIhU*W@!<>q=>W*h8(1Pv>)IMtzZZmKDqd)$Z4BkrSSS&Y^^GGzC2 zNHZ^Awwq7w2rf>#I&$->BdS%DX^?9kRMFZ(&OR4St0{iA+wqy@t)(RCvGT*6)0-BE zJv}(S^vs?~s1o%k&2n1JYTGu7&YaHbFiZNVO5YiCcO9pRbZxS7&uH!P<>`w;4J!Lz zHy!}_Ao`pUH|$zI>=8P=2q((ynbr>4X-*loX@{@|3?#F!k6=h@Y(DyMPmRa;GOG11 zt4Lgre_{K(Jzd?WPdlAG<6M=Gw~0uav5BPH-!-9F<6e0929@)C*nLEMv=*s-tK~wi z;3Qh$&3Qe?pI2I&C5UPDwB%S`PLMFN3M!~j3#t0>@XaMtiI(L=MZCeh_Vsvg< z(~#c3qOT1?*yzO-NrAADeDrvz%ehf$V5HlP*YEcPU(}MJjx!7*YfS4+k|hO(?&$u&k?W3ty>ZEn%L}P$v%RxY z4p{FgW5kk&o|@%veq&K@jIB*Qt?iECt_!7W8dRKXDg%vVJ0~4+XLBWAqV+gTxLMcziuQ`$f0i@b{6gt5mD#rDny@BizIoKU132+38g$bk1)c}ePQUf$-AHA( zthlgZbOXuzlS<%Dd5z0ilPwdnEH?KXnka&;ImCuMG1BE^wXrvym&HdtFbI#$m%6ny zc&2ZGo^D>ER!Kih$eTVQ%P;9;qEc<%%y|}ZSK^`v2B75mpV_W3@X|9{z6w4yNdGZ*|D81 zeC{l4`9^L{+St=?84kW1v^%euZxEMgbm^Y=qNH?lpLGbU@70Um6UMjd+t2tT+0TSC z2&KU{@Xk9TA70oESj})d7W%CJ!2Fw(vh!+LmzI6$-FaFv{kcA;Vcy&8zIS`$VIOFn zZTLOL`p{`p6vC2d0Ug7~O>Q)9BPl&!Fs3-ArR%-^r*jI+G^=JMzG%F=r0Cm$fj0vO z241Ouf$du5FLC!bS+@FTg{aB5e(g$-Fq^WJ++A4xWzRr(dOx`zwv&~Nz9h4o4#<~ept#fR=3dFI`+SKcf0s`ezqF7h@{{$tg4IQa1h z4q!<7-h!R+fYNb^!kmJ z)o?^%W#OHE*vr2H+lEIcca*RezN?AZJmW?IxXMfsG;PloJH(0p~HDld-n=u-S7w}9!d zND5chEPd}>uuhacJbBD=sfnXD$X&O~BvKZ~U8d@_^j-6^g9E&`VA?%gGTuBA1 zQCy|nPhkswx~5kODZk-xS^EOb7)d$Jd9LO58uyvK=tw`=T_N_(CdD37o2%)4Q<3m{ zUmaxT4t<|1UpHoadT7`iQh~zzH}c|=edIg1j2&?wS>8Gqx9OOw53@S5-TNfuw230K z?~_GZ?!I{RNo2I9;%3#Di7Dge_lJ3V*G?G!d{zT_=FnRk=e}NR?;Q8_bM)>F6ulV7 z`HN!{uA`F!najR>ppL7S}QLP96e7#DWjHcK}t zo$jAenb8Mn)Oy{;yYJn5W%cOt^`pLzA(%>v%Jq-UErw0hbze+oimRnevy$)|yA`KN zQPK2s%?TKNYuHkg**0xQ?(Wt%>+`*S#CydMaNk|3TFUITVUQ1Tubwts{YhcHm{G4- zw0NNr*xC6bDiG?F4MY-&@R zkdzL|4H8PHAR!Xgo%@{gedCTh?tf>DgR)#}uDRa%KELOA4dnX>hbYj8jOZ>b4bNO@ zvz`iUr7nAf{sDd`)9w2QwGLII+{UV(ka9XMGB*X7rl$rpKfIvijwk)ctR5DXV3TlV zhp_mMi@?lms3H9`cdSHd`aQxr`~xjQ4>uLeoPKMuEeQ;EI1pfpCmyX5;j z;y#O0lGth~#{GgatiwC5CwmHTXBqW19OqpC+r!V9dlDjEW2Okok)fgV+x#fCK@pk`LjA%5iD!3 z)C*9@@(PF`?VRsXVGXPWlH4WV2Z+=oIs;sOIvmVwx#1gl<0PeOLi<|Z)4#tj2cCU- z_V;&8pq-(LjN-{s3Y!WjJK>PVm<~ovKZ4S}ocnSZP|W@r{I(K-$>_}+Out4o6suzp zHI(}c;Mb<>ut}vO!f*EP%Ko|9#C?7OEqa9_F{Skp2YR8Yo zQt*HVA$UT5u|F-_dzFIXxU-J^knZUM9xIK{xACze5AP5vIe>x~$vO#DuBV^$qBx1g znZY7lPoxHS-32EuGJ|3d4H{9g4=Vv+A?t#p_zn)92i5LwB|f207>>`|Uy{q79FsP_ z>SWn6f0Dl_{i=o|w4D?bomj^JV`hL8lA|w8^=-a7dynN_gaam}+IN}3yQ{x@Fc)g3 z9T)g*j$c z*Te@WFDjc$*z#2%Y=+00AODy_FfhUN%z#Feex>|sJ?c4eC}=6smL^O{3n{Thj0Kiu znpNHJz@vD}7zaKE&uACgqs+S%RSj6l4c|}79&)0{bZE>3;INGTYr#JZgx$Roq*8t+ z3Z4#}hl968Y%M0GE7Y+d(V7&)FREed{*SFQRpz9rIf8`KC|9-s`2~kwI3`}NY0lz= z^q=iIkwv0KAM#P#Ml$~F5!sG>-K@${Sw8T?TJ|}$#6tF}qMOW8@N-KY!6Yg7^wSH@>aoCe8!g$L-aNdxf*u-uoTQCmF1}vJSpJOHt$PX^N+RFDy#3L7`)DH?HXr+nR9l85PAlVFxJGc2qe%3Ot&j$7ZlB`2#90a?8IASmqBk0CdeuT(q zP(m7KXI&kOfS8P6Jz4Iv|Imf9+cq*J?h^NeEDHNn)pO3jwGtom89{Q4X*>fVk`TiW z|9ULYmzednlYqvYSm&bR=06u|E?>dm4C!Cx{W7D$vW6NYNkcQQwr{rRE)DR#xmefR zS)#bMb)q1<(fZ+;jec4Dgi)@;~vgE2CK-C7tA2{W`i1McW{$vMiNbJplis6|&` z_H~P4sabrj@`hgj@;*srUa?iQ#;u)M|18U#trR8k@?0zbV(`He;#SdN`tE*q)kHi= zRdVK9h0zMTx3?m$QlK7~oGh2Ogg@853fZ9(-YR=gkr3$Hh{ZCf)E9bjbwcvFJll+> z7Gr~gWd%+k&v1(jD}ywM&ddg8>br^cZP<}92y@ERh(wgQy#!LrSsSQ6LSt^@95saV z&3es{dz@xPh_Jkvce&j^xuh4Cy6Kk~;f#|enX^`&OjfaGp9}3f3=5*d_}HV(PkHQ{ zawm@OxXnrn)%&fxL>MYoBBX`#<526ks$z;lZWOM^63ZRrJd)$g_>nIpX=m}}1dDZD z5UW#$3>U+7Ub6?|Gfogq)JHrO5eVSH)V`d!kx|ph^WT-$IlAza!9$7qK5g0iug z8RWQQeJIv~w~D@&c~&c<7)g#FH~ZaBR8+??8KHNbuDA5{7W`J$zk#dOdvi;EnSX>{ zmHcw0hSS3WfF}}E?~~a*JYUxbr9vm;?qB+TJn6$_x)>MEz{}hXm^Kf~W+s%PC}Lc5 zl)p_z$vhnChgrsX<#|sspffUJD9+Bl-!!@LNf-%f%s0_@De4AJX_^BKl}5C=VU-+r2|=YNLY={+ z^47On{5MXqut?$d5gZ*VC))59x-6dB2kV3@$X##yw;HJu@{gli&!UgiQ(<8JSBf3y zd_lTCO$Qh8Nt}S5WnHQ7+2-%37FX*y#d!8(F-0AfKA1c`h5QNHs?uYodbO_~f;ONZ zcCa0AiPb#ba675e&Kh#YiDXZcz@rUMqhV1}O1Xpeu6XjexJNVOSdz38+9CRANvu=r zRp?(Rx=)U9GlC^!xT5e&xPp^b z{sjN**z+_{!#C@uTw1HX)mhPU6mHL1TSd!?M@?z^i}{wTerI0;;)35H{|yB+M)8wm zPO*Hy6*Z$NM<0`(@U}}lpZPo{wc4Mm-$`Rb(`&<W5(8TsQy#u!z!lXPG&qnZYNT z@(%9gWw&Qr&6D?nFBSe0S}L}{U$i34VPFCtF(^-HO-W^c^HD-d{=y^nHB-khFq83i zgL?={S$h~fgDW(roy;@N&(E}*T0+6%AUb=dOv?X6rkR70LsEve(Og~;e83(zqMs1Tx2vF(RasJ)|_6A zq8c}ibeCv`{uQw&)tNc>i{a@&k4lhNq6L7Wsm6?b@EpCnx!R{4x0BZeyh)|~1FxG7 zIr^^l4QzjlIxjlK3+%FQxQY$mLMWzX1uWfy)658M$Z4kQ&3$7eVOHdtkTt+WW@+V} z8t1Sb1jl!d0IS);sF&e4@nu%f__y)M3e1r+(dxkNCSjI+X!=Dv-5*8ip2zCGkQYoV z^Ar7LP3q^Kc%O@FoU?$E^~M-#N39#Jo`}A2zZisil!LoweJ~S?CU*3lVS`$Wl0zTry^tl0pH z!OzF7U;Ts-#Ed_cP=Bsj_xXYeY|eF=MfLft0GAPbx3e=ZE;JsX>>c!xdU{fsdX5tb zZ-n%Hw@079nY?=HDayUY7~uTV;%*NK%a|LGTS>p7#wsoUEItC%t4-}6O~{%J!L`0> zArbzin^Ak{l03?gIdO9or7Dg*#^e0xjbXc@f_0V~bL+=2dnrOU%;p!u?rnOjz}0>t ziLC> zGt>{)$S&KScyI(V9q!HTvCz2v z<_8}W3DAjbY#(a+VbZQ<=C!zg(6jR7*7BZ)%J4|4Jpzday(XmPU!JF^&9$pMotdcZ&E$My z=}@<3xxF%Uq$Wd>8x>7{rnyE-*_d5+E@e6=on~o`ePn0JcB(lDPtHAecZw7>TwvOy zc3g#RP}T|fC64A%QxvMAdLv9|u-W*!SoI)8Suf9nGWQWQ*IfU@0<0{R0bHU}lkd^K z+ezs;s+2_D%b)NI6Nx4GJW8oaQ;mz}1bnQXey)RPso4gvsnGI#PM($%CjT8?x6Du0 zcbySckvf!+AzpoV+tSL#+ifgL%l!G^mbBwu4Ot?)~1&5D;#5*3&<>a^F(oFAsjnu2G zw0z8rNVatI%P;@twLA#KY{T-W#vxADwdtaxJVL|c-{sjB@<`jbQ(?4fLbEuc`Jc*O zj6xR}Ow2$1b35dy7Ph&atgf^!4hzkP<{@T?AOCdfOXc=Ghg*i}&xsCcg|_HygCcLf z?{kz}8r5fgyhulZ2DC^r&BEvBH?KVIKupYeo7GUxGOa=->~s>C;AYs;BC_%fmNo)^ zheC$iE3dXQv#a&EwI5rj?^DQyTsEmkz^+kvaje3&d))984))yL+U zbN6ZM2tO0UPunNc!|ejv2!686(cH=O3N+c_WGs$A`SL0SaZ^bW?_28j3oq6lHz-$N4)Sy9MSYx)g#QtMdD`Y6X5RKeP(Ews_GhwD^MUr(w%9aY=6EWNGzB6sJjV zUDmMdN31bpR92Yt8e_lVPIPk8wa9T}CrVPI{|Bo_v}oGxduej+^4D1^vr zexHo^p&|7QO|3|>F=fB=8k6n3-OowF*6Q=6P(6vBYs<@nvTBVk%*?b<82=+YI(4P@ zE?K|uYqjnE#hHV|+>`daoa2oKo5`#&P-;WDzP0TZ!jw{5w(U#)tX zp&JHd5LcVKUG+*bLf zx7C)Q(aWs+cHJ{4{Pd7zM3on_6t(@VAsfMWv4mKlI`VNQg)e3_`UF?-b<%wF)=#DuFbg^-GX!@v7yURivE+#%)oD#tq5MI0;z8bC{>7Z@ z=A2;fT?Kn@?UJd@-5y9RCnBZ!7o*pSajurX<&bPso4W2oO_khR8&eey^dAq%p{}S3 z8U(D65M4@DdDUa*>J%7lTGo-vrwC5>j{4g3FtU|0207yJaw+q?i?$V~nGMXSOhhDu)raP)M`&$tVNUiX z$6-|+)$F;=MG*VMA%zC29b_on9c%ifyI_t+Gg1Piii^saxILJ%TfgS<7mG;PpRKu8 zk@bdHZvZf=Inp#s_IwzE#}GSWnN2-fI_1)9AyJpys)Ax_YU+0?&|r2Z;4vO(O}qxT zj+u*qNl(JfxmzYU3p$`p2hFfDbH-XEjWgPh)-RL;xCfp2phS4HDym2BRerPw_TQve ztxmoT&z)@#&8(TXwdm<7pW&2lr^f2we%cCOUs7>Kd|Ph^TQxJY8?)YgDaL3!<~-lO zyze<>%e&@2vlTf`@Lz<%8JU$LKmMgGU*(o|5mtOotG%E=7)5@?TxIK%e^1HnY2ak*;p~W)xhN8~HZM zXZn0jS3JmqymoSX^jJMUuctZcQBAtU*0-qoPw~bjM07DWT*X3BFSPX#`)!Z8>E(!s zmSc=BNGku)!=E-EIu@9`WSnVT`6c5?88|N&X=>QwAw)0d%|Uan05pMxEVN3)| zh@x_ody`VkJAs0L!+?{_lzD&d!}3}%#s(r0G|G;vZL*|+37eWMGB+7dxKJ9Yp{5!k zxWcX-`||_A95a>#1Bq>D@eaiyYmZY+G(CuZh>ujvlrxb4ANR!l5AS(I{}oje1c;9r z(CH1}X@XO!>Dj-hOjF4_8c<)cL`6<4Q-}s5$s|=i1rHCF=_e;5BH<_1>g1L2FXBsj zJ)HW^?p;v)qZ3!ZqRw^#fge@`!1N*L)b@FlwTIT*S#<>49!EO~LnAudGHfMyncyB| zS^f2)E6!IogMW^I%XxPLfNC=vLrAq(+i{Fo)P_|HVS!~AYSi&2{D$}a^-dnzNGe0q zH5Ld0dxS0B-p1|$RHzjA8C!d$HIf;%fU-dL`*et<3AA))Y(tMS;|90%kxCMOj!ofqO&zOqVJzu;O!MZUVQ~z(8XvE zsV84Pg2Q0!ipxtB7#?pI0Gj7J=sh~&OK1>gA8GqVAeIr%V1S7U40yAnm&$KN;fRX$7YY`dpIH3c|Y&$aR77uM^AZRL} zt>b7NP~@3#=ZP}tf4_0dan2GEqBF6eLDYtcOLO1m?gy4i%`xHbPK!BOb!ey^h|+^_73UM#3aOw|CqE15rZx;VA3{NZt>dBG`FRwJp`bVl3N7u$`zAH ztr&Q619x}#6qeziIF96^!Uv&73ABQ$4;Fu+Roeq#5ZB8Uf9VYpv}DKV^T^}q8TQ9> z#MB^j%OJ*U)=$EWWm99zqhY8yp)L9v7x(O4MImKrCkOx|!aV`rU%D9Bepz<>HEG!? zz|iR&Er1L>U_GE5QKNy(8PI?_kV0%+a$lekG z54hnw>mn+t)c~rC{n-~?0AE{dBg5T5S@}rlqXft(L(8k=6c-J0p^5&$RZJL5?(YPY zH;EP>(}rTO?f0AFC6VN%ThA>vp)Ki4fQQ4C;jpK`P6V2owQlFL--nN2&IUv10I)wT zV9~~t5KvLo<^j3O#zL?_7FK*m%w;M~M~L?zx;ZI{Bpws)Pp%+<`RgYjd}xBv`f7tn zpONrmhhOpg>cs5|>l5y)?ai-W{Aa=jxn4D@fThEJ4?+c$*}~A+765GKRBVmYtgULmE zypOz)4F45mNV}DI5sPzX>+q7xttSE#<^+fa&l@0;4}3F-Unh((*D3s@aQcDDq2MnN zguVlABrdF86}+fER>5 z-&p&`ItkDZ6#}e0YU_kWJ4F-}KPn~l57_8tL6QQu044IG{*?6yF(%aK*ISO)H!#RS zbr7LLo`oeTZb1UxtjE}I`v*vm5S1@a`Q;(~R?)%K`m7az#>fS+VPZj=;WX zn&!`+pZ$Hh-awQU87l|E;-)p+A<;eSxQghMuGr!PSe&CEryT|v<_(M7&kw!}U=a(S zA=y2$UgXNLQU$TRIQ&>5q*ed{ujI{=h4a#~@^om23x3!_w~fF(8CCNRf9vjoL};((*& z=ogZogB%U%sLAqOH(qO{N!-Y~PJ(zn_5=a;4D2APqA=EV6h;Oy4;NHttZC69Vg7e3 zKiHW*jBNtLJf%8mr_v%>Dyj4uhOc*02_?fjK1>$?PQKU<1;Kj>{0#MeZwH?JIvx7H zmHv>(d<~>=#F}DO(?^Qb({Bs|_M??{cdY(it`rD~qfaMQa;@jId%!W}0D{>Zu=@0p zCsfs=OXR3=kwYTx4ZVdxVecETo%?Wgovu5>ja}Vh)#@D;M^O}OK{T$Auj2SeDL7_6 z{(OfA(FL~QcUtM(eTO*CKPK;gD@7j+5m2URMW6?uT0QA@lY2Qo!YLB*a4|fHch~k_ zbh?05QFM>>iprKBx#Fvf%S9LI=j)1srj{_l1)GRJ-a&E5IrxrnLmK7gwlG!jLRsZF zT=RXO$Km-b)D{@*Kr`GpOk?5vU}F}e(8WSd*};1H24y7RMoGBt*jhaHcnn zD1K70yR*Yu+iS;+>qBezIdWXl&K@z?d{;H4Um{7&a~v{mk4ylz=OuLJKsW2WU5B9) zNo%>a57et~AgAdw`S?qTcvv(}EFF=c%Lo7OjeB=scTVGg@QSB>xJm*49$^YlG2aq|c&%lG;^r z;_R)_(?(fG5z>+_Mb0w?bmN}0Qc~`ULos`cg>|Z&feGP9Q=mvT`5KSSmlH;Nc@9bC zi%Gst1y*^SpAn32^Vhr6jgYHr^!>7ZvR7d5iESpkEZ5aKBry-Nb7s3Iq*FveO+hX` zdaVz3@%Xp#az(G#Z<9-rdZspgyS8ip4L0vQyu`!m2RKz5>WzXj`*`?<9QRVwAK_Rq zho81ihk)(L3u6$5q6K+)kI$Yr#~eBYWwY+}8u3rG>2ma(y?)`A`(jl5Sn{wM(2RO( z$m1o&9<*J}+e$g>k4oI%Z+xWDob?>jO6T3>T?Oc$Z< zWDa_?cJbyF8Tl*2A12psCkW!WpZ{fv^$>tMUOM5wtfB}C9)2v_lHM^Q`pdk31ArnZ zph*#}ZqNnn?H~V}HH2Va6Qu8iNBDOC7j6(fnQ*~tI? z&|^FxjMUvRJXiehPmRVau9x(lrbeg>GG%|8J_obb?V<2(n{qwg(R0Z~<(R0}OgRGi>2sC0vd zA;{hg_gA1!YHYa=bKktt$3TXE_$VH7=6TR&?D)9RjN`7Ci#sP$$PD6~DWK-Rt>@7S zsGpdJDutkM+h9Ol37rDiLK7eZp0$B(_rRH9PNT<4{0d!e11PLS#BtDIEK6{J{R^PI z-2o0(1aO5y^v;FOXLJK}FSU=uKg@~GXY?j92bzB(L}99b=8PYf0sbWp4RIOb$91`W zEG(V`44_5WA{uF{V~`lN4&Kge>cwN20y#+RUA_0T9A7~B zgw8n%0P&@9XDZKcQD~3+U)eBFrhfi)L zNqe9WEeEL`&jAql5FP5{yE#a>!6fPVdXcC8>NL_X1yyNSvIkO0>GBBWp|8j$S-=ke z&#A^a+eTf?WxR;)5wJ{xa3`fGaHMErJqL7S2PucAH2QlCE<%Tg*Z>Ee3S>x%gG3kT z{}jTjK<~%#EmmMPCg(ld6pLWpEJ>EtCf^1Rls7IAU_}++2^j_9=qvmVKu0|7gNA1r z=zbE$I)HCY1-cqRH)3y|cj*?&<)BlD4Cyk660v_r7E>&|0dOTDmkYoTY4X^qiFlX{ zdx4Q#j7s$zaXo#qC-RJpb{1GD|~-}vRXQ4IQ$BZXH@a0pmtCP zTz!WHo!Pf>5ApYZ%*uLVih&aTs8ivg=mtt2l!g`edfLl)xjd76NJ||?;s!m6sA*K?aGoh=gMZ%0jib9TYE6%3I_2&#I|w+ls8or3uJzJ=Oy* zddAXQ=AW)kHxCD=TD+{3Bw2g!K_2Ey8(M5Y8wHVTQGGXE;P%I6GU?Z=uQRI_5rdcx z5c6|()cPgK*9&zrtq@QnXkE_rV@HZy&tb-4B9I zeW;)AgVR z{YIaJFJ)GyHKok~aCsT)LPku7;+tFnX*8;Y4y5U@Z=c`qgG!xF$P1anMF>hfp+ivO z88SjZnii^0EW+PI>qot+0o~*~dznoZi@of%ag=kPzLFD;c~4 zw=^E11BV`iTFmXR>*q1mW)CFD1Wlv=odWF?VJsB6BK{%EZh|>Dzj*$v|K%ZqONZpN zu=u1&pxpcH#b2h2M^4<*=6h?O2m`;#VP!lF-3rSk7{^lp>JV!O`8QNG|x za)aii-C!@sMje~k25*PhBzQb({%bl)XS?T@>cZssdhaRleKK0p$@-xRzEmBG@YjL{ zp{6pcr|GUClIv6SmUI0(GU1%s5ARi@$0mz?bI9xGLG<@&_r1&0znZ3h?+?>2jM)j! z_XXLEUM6WZ9zbS-X+stffephR?o7yhx^mQ=WCRqn;SHU?cJnfN&SR5phIo;|Tc7)8 zaJ@8p@!e@W-el?Y?;_o33iy(OW!>xCoKGHsm)#P!SC-Xq@4=7CHBsZNW`0B#5!~Gq zDUXif#Cg?F>J0CAZfHALgG2ZwJ6jk3*)F(w=~L7}VlxzXvJI73JEwrr);{TTtUBpO z;~M@(KEEHS_%V@U2EmRPyQQ^01Xs6P4<)0AEZpvYq|bUv7CK_!O7Z4)a^F(0IMO51 zKeYK}gjS8*=x-M*4p)TG=T5y2`K`W9BRP|=-+B0mF(Mu$M=L9k_U}0se!7tc?m

cg%UHsZu_jzUpzeq>PSq}O>Oxyv)Hi_+H#199v4#(EjFq0K8z6NRv# z(X)--e*v*fjh^iLOXeM>v~JTQOWAZ4w?r2%;$w!))QbmiOVfAWYRve#M}ye{ec$KP zxwJ%ks4D*}%ll0d$@%mZj z6Qdz?7Bs}!*C3x|!ws6<_t9Jlhqp9C-<1$6+B5-8$h~ZKX@G|w&sogHhF5Zu ziW)0v2|mos@B-mQ=`yLjHnYt{e0(Ce9Yux1UR$#%$nu+mTz8Vg2 zuf^^nY1Mmx0JG$jh?U-efWLZMNm=cM0J%enQOP5=G-#MEFNe%pC-z@8#!AA_MW$|W zF$Z2PiCrba3=XZ&8H1^5DeQ&ITZPeZ< zMT{(w9hY00{+qVbK0QkyzG#-qaQ}$0fTM3>JfbQHL>R4%hpk!i{i{u_R=qUZ9?u4k}4Jtyax<)&KsUh@1~d{|o1|D@xre)z6^e@Hm0Q#X+cW-_1xHiU8)oCRaZ zzZ|0rh0{_wOYPWQLe94S1XYyeH}h;QTgZ;R;MTU=iDioDD-k*@X9U!rL|kPZo)>Ni zOr7cZbwq%yoT>$#_0W> z7-=N%vCh+$*JQ0LwtxJ!h2}ODr&q_Tmik*LD?GAHB2uunq9}LYx&M1n>W~DafBts0 zA>{5YO$I`iX=rM^`XYBGEd!^G%S>$=0_1=R1>$>0Qw+yNeA62oC}&Z_s@1$Ns4Q24 zY--FS;;C-$48Z*HJ~`kglPRE?^@>OSxkD$-BUg*xpQf~o{`OEQ)`fHXC_-w6b76}U? zg?--&79mv2GN)%Y{ZmlVTPMj%ag;v9(i?*${eGN}UBR)dE%G>FCRWJ+U9!PR2{Oz+*CMQTd9_Gm*2M|#hiBKX;3BN`$Gv~jp%Cjf$PV# zm;ls)b!f3<_24De>8@WJ6p$#qM4npZ&KF!-n>(LXrM=O%(F)d0h2(b5z+G2;D^psD zgWvt=)<$QERcjZVi(rvbK;Msi@cJXPn(G_0UrbgzS*J%1nb{O#bx$WU&3(Z+dVfRN zwn}IELe}UgTVEbT2q`6v-NVYFfVPcPA|tmU6Nd zr3jdsAU%}Lw@z*5d@J4>hQhV8oPL>32miqn2775m>6iBF=@@^tz-aCp(9GhKIc^oh zv9?4`;?X?Tod3;8!pb;T_Qy~hHBc)*{W z?XMyST!KuO9*mGf>nB*Bj=^-0IndV=M5sej!psnp#cOX#=IW|+IY;;tF4>Ny**&P+ z+_y)+e@;=OEnk+jVflBX&{8C8Arx+mLUX6&~vwaoD# zTFgg@^b*=yy!XIQ!CAfLAUMHyEF?*)rZV3qb#2w8m-L>qTNIrw^604_(z>}xEYO(e z>CXJ#5XfrwLg@RQ_eGIfbqBwsFC^hKO^}jSY6MOCS3eXNMc4lV&TPTXTI;g9(E`=1 zjH;D0X_4Xq5qU}VB{%&`Ey-h3hUPj8i9m|4S}mREc5`ByXIaBR5L4RN77ubx7;8{p zm+Sqi_nU%4#13Z4bg-S@3OE&%T9?`Pc1x*7l=SMz^UoYx<#vf0`5~Lyzm4|IA6QQ+ zyI;nSDWjy*v%I(DXnn~i<@^@dJl?VPq-iLwfOKs)ApMm$I1Zs;{9fwDHrDY$G1K;VvqLjB;fS#9C~&ld^k9 zoiw)hO?TajOMm(a%6h_BlKU(|{Y_L1j!`VJbvcMAm;tKg;h%C3`@A08c^aXQ zE7Lx|sC1#x3c$Y)V~!RNrb&YLpZV2$(u>4qN{!*vQr76pCCNNrEX>3x@7^|Nf|Lc=mT&}w=c{WxcM{0T2gm%$1Mts z0s~(S^#i4L+1uQ?aNo13Mewl5!?e&`$06FeMrEqX=>gDt(5e@D#1LBG8PKQ4iLGgx z(QX>$t2Que4SU_>yp|u|8Se%;9A_)js~!~f6%XpgsYS4sv@?d$-#gG!nzyH2PtCXZUregbn)nmHvbrs@@8w)E*iEJuDgfk^^UOj#{RH9Cj@;N!;H5j5jUmKBG!5bf5qPdp97Oy#<*l z>CZ`-w1I0IoJY`_)<3hQz^)|BECvDkHm=epONyNJ8i-e}Kp)66Fh2oX>Hm{9lF7*u zrbR5IVxz|C@#W`BFS5+|TY6jTZcr*7`YH}Dkt%sO%R&LNZa?O{k=vSu0(?;dJNR6S zWFH#ruz3WB=Qfpkdj3g+0}CPa@#oIAEBwC?KybLF-w2mGx(f=re^a2-WBm%gUK|eO zW3?wrgJ?hnJv9L4gbvf6z2lm1Xijz}2z=(~30$&!MbV;1j4fN4yW>mQod^tbF6X?G z-bT&O4xcOSSZEF*6*|6;bkkt_ZhNx7*F;YVkc&>#|NYh<$8c1~6oT3$ob_ z##TX)Z-!p62;(&U{qu7cxTqCDTD#=~1iG&olfdu}Sg+ZOJb@<{TncdfPoY)OZ!7d> zm!Mz6zj6dI&Q%sZ94mI(Pid|in#}4%tnD~3IqyF#>;wlL{0Az|n@u~NsDQN0f`FC+ zXMaf?Omiybo_X#PZHy|VILNSN_@V3-??mZKJDr!e(j>6@(0B+JVld|dFckDUC=h~> z1&!R)W%#SUiXIyUwAoysZZp)#)bRyt`7q{*xgI=f|C&UN2{ygB|T?J~ju?q+{s^URY2s8=w;A$cYsCcWq!B{xohA)_`ykLI{ohJv0-7T&C^PYttAk>@Ses*SjeLW)Os}=Xo}k7I zZ6R?p&jz#jWFGZ7)pYE4a6YE;iM*?)T<|KSQujdaEbXTb2raSxjHpv1;33|0F(x!l zO&yT~p9)I7r1rBkSW45n{zq+uZ=O2^T_Ij)nc#*;x*>^OJeK5bSGHHyCecI12mafu zBj-ntGYMT9|Hz#Y4Z>9ihAR{Gc6bk_bLwCjxcBG5VyunNC=2sV(3?lNAX+$Yf1JNr zaXKT9;9W%U6$CFeCp8~vJO~&p@(-_>)wjH39&c)?(AWL*#K8He1YL2OD~* z^B5(iARlLi8?NPc-v$qEr&UfrGa;b$d=nA)DU?l81LZ zGU1rdJ+MwhzF3beNJ19kI}yhe@()ZPKXWrc<)&Bs&d_}3lO2VC2TNWBUZPpTKb|j= z=zS1Mq7jkCUrqmdNv@T26h3-31KF$15Gm+#76i2;ghK3fH~2M<*b)Rj@2dG`xHqFP z!tz7SQsFiQkFvQ6%QO#pzCHhdKGBaG%J1h4v0I>STS91^Nkym;ZmE)YmT}g`qBrRs z>1v_6F3V?UZ!PwPW{QI<1AYpRf$xkhj(^5OD+4vQLs7wT#*H|^1GJGyij-j7T+XKY zd=z3`;QlRfIi&(Vn`tF0jc4v8NEq5P{07$-oP4&OAK!AWd4awcwYRchHR;VBhhyg% z@SGi+_MWGF1QHxm@njj`e-ld|3EWG72?|~aY~}u-=6nNLIGz{$sM8;E4s^n!gC9rB zRz3+MOLsny(DUWK(552vYi!+_Ej&7fx{43%+2$RwSYM1> z*RWpb(0|DeELb$&q&?+Z2S+IHUHxd3$u~rKY6}rWG0ZMVUup_kKd{yA4)ibN}WRZ&XD52OatL#i!j-TKV~yfIY`UkjPIr}N&b{CgPp zurH<!2xwL*>OWnIc~lhO-8BL#{E7pr;6PE4MS*exhq%u<}9ud=9Y}< z%XeD=$gEd+FnDCi~#iciwLIij#C3VK~#&%lEObt)>pPL^!nx2{dbNt24 zPlc?mmp|{pbe`6{`6tL&;!V8eLkjp3yTzqi=Bxd18l}(WgJ7kUr-)m;^61-%5RL8= zGcg4>MkQsdww#A^WEa(@_Rd-<6GfpB&7ZL9rEVTGp?YLiTU9fnw*$113ZTyAp(nu1 z7ptF@HUI3vCYu65Bs@2PQ%d-TyORa(AP+`jCeVlrFnb(mbZqW@=q27Kbo>;W83WR! zM-x!qW&zEn4Qh@sn=V$!D@K{L!{g zE|1p24l~u9a%*q8M+9)FgGIFb2sHi>V% z4N|$O(`XOD1sWfb;%Ag`I4@yo`<%XEBzy3koXPhC#Rl1KzCUS!@8BJApdYl~98~Xv zfiqNU{A zfWRju4Xs21ZMDLz#u6QJu@8m~c~5!QgRF;3TH1FetS8?<#rFnH>*4j^2i2h)T0BR? zsNDMbn&>Ymm`ekRlD@0^S`kb3 z5<1@}>g$?!7g#;+K#N0rP-YA@n79P2$Y+34SNX{*jP5s}4RDk*eIC_;6tE2v&n+g| z0JnnqPvFq0gkTj#CWZd^%KJyD%dP{+{gwE%!_MerICL5L>oSb`kkfAlOa${r@l8?mJjP1X#HCn@>_;*+MpZQN%)VTpr|t)}MexUwMdq zLjX6B+{3~*yUJ^tT$dfPx#4kE@yZ$>%T%+yO(*ay%e<*G3hA2TV;_8dmgt-##TP6? zZ;e}qwI!mr7^Yt%Wb!EC!6*qR-8zf`Ca?z}OB!q>c!=mS4+yL*gor;2-G8{^7zn*T zm%NgXs}d(UhxIzB zMDh%%r*^=YSGI5!D|94WePHPKJtgq-?N|4$CxL3qhgP~}VF#QC7N7(k@TsIji3@xM zOJ@l*n zvLf0h>j~lkX>^{MqN2BG?*t3&8K`Zo>%`+oWAK%+MEV_6Z!Ww4>Y)z~^%N z7%wOw88MF9@oW#7&cVTAsDkkNfi5m>q*>X52vx}v6nsY6g^>q7 zAPsB%!Y-IXD_H3d-?^TeStk2o8~2_Ym-KfLRmhpf1pXsGST^|9*}R=n|kL zUj;Qi$I7@80*|m~HL=kxKQ*ce`dk2n2B2n)UU3|v8R~o)f7SO10*E+i5A{b-TT=E6 zOzW$sVAL?o(HhJmj&UYYQ~E(HbOfS?ba*IOtr9V}8%TPUK_X1Wz_pwvLvV_s+X=y% zlom=FE8>ueaN8cT$@mAX3Q8jEn+A|=MBFMnd2Og5hrg#V%#`(DFd^nVj8R0hObwz* zaVOfTfLr)GO}t482y0D`*;Rvem5q#My9(4if;`)GJAudf{>fDV{jlsKz(VJ+V|+!c z$y;&$>v!LT86lJHwb=KFc6)&y9f3d-DL85932Fi0KsXEjLm5!Xd92ma2+|e?+W%A2 zb;q;yyW$}$X zT^`bE<3`Afhr7~OkfAwtf)G0u#h`ZazGosQi_H-zbBg`xVMg2074RFF=;#xqZz$TR zLYv^9sEim>a7I=&w-&$otwx4i%}N~XH;e-C z92fsip*b|TY3xgYa2eYYHOtO2@arxRnxaVF8TgLJLhP{vM59B$cZ zPeaAzLpIw23QRWMbG_%d$jsaq7{i~Q2a2Q2e@BW~6WpQ2szmPoi-_yqv5q+%y#VWAVwwyRF$$HEbs2Zp5 zdzDO=U9(j=aBfO+ZsyntAWsIOa98tJ2}M`9(9j3mm~$btD#qcz6~9LL#8r9M4>@!M zC|o%Q3L_*-TYql!FL#+rWWQIZ57Wr`=EBCvME4DpV82vu?(;%^Ve(sOG+S}FO?S$& z_OHtK0%F}du{5rNGLsA_{&AjVQuK8VljV5ch46hyO3L6=AN%>$!us`oDQpBVOx8cP zf0u%g(E*waP&M|jx|!p|j=5A5Td<6%_Ui!1sc9aY45QUwWK`$<2q(3;Lup7NT@lzs zQ&f@-F|KrSXfI2^k-w7DN_|WIrEn}{A~#E^&l(ottv}5%M_q~jChmpm#`cY0(p&%_ zDytV=i)y4Wk9}M^oqn8Z&K>>cr|ISg4o|JdhD!%T_BW2Q!H&0|nZ5=1`@XK1=eg*i z%80IV9J+E;Z2Q3<0=uZ*rVg*k=&xL2QIq$#y$^QNl&3wq0T#0NZ?q`MAC1?XE_@0g z3NWg&1*OyTY`sc|c4A_tn?}18n}{}X`3gT=yj49e&Z^zIVhSfBEF7+AbFnKnR>&8( zhinU6xMJ(I^XI;$W4VDK#`JrYphT6AK<|0^#FRXnH*FQjj>rj}{v&==Ad!NYwXWk-34F~e_46Hx zEZl9i!&+e5;A^fhO)b#-w%ezkisT@PUf!>`MCv#`{RNVBWAT^yR%0Yb@g9w+Z;A1* zD>pgfqPJObf``C=kta#EE4Npe;N|UANO|Fpf^7#h;2z`%)uYF@PzyZEa0jiR+|A5p zia)zLGBO3@5zpNk0?K<8(7AT5TKj-o7Vr~Qn#^Zn<3cnuz=Q;3A_i32qt z8i9w@{ga^S29VBF^6QJDsA$DdsvV^?;fOB29|%NJBo)E!zoPw2>fP{vA4W@cGw?*Sg+$e&ceS^=Key z6~@ZL$e@aj^yC7I&+BO;NN-@vfz!9wDCTM^{o6z@JKyuqlnlfO0DU{-yh>|4$3xC8 zSMQ%1(Z1FN&&WHgNBYL`{VwIz@#EIJKsv?kBqEn(hsIs!*0PF^>s=639_q`H+!q8e zo#b438y`yZ5X;b)AeK_P;JwtSkP8d<)t^Z5YD!wX3;pvl%YrnY-~iA0VXD+Z;lwX{ zH?ESqp1N1)I#%jeR6Xw=O&B`Ec^PvII72Q^gm(GMtbNT-8rQxZGHy4|zn8Ztd*A5u zaobdOL6jt~U?BbIB%bV+uIS2lqh6xV*;W)B_}5F}=NZt0p*R5!A5qktXIKW3_t+JX zwJN(1cYD5~qHjDFVMnjiS@A(r+8vTU$|S0HVcFgS6o1@J1<+V77xwH&c(j*%tk0}@ zbE9KGj-r0ezLG34|Bl)ZA$&cz!0Y$+`s{PzPUcyw+n-yjQ8|;=$IP7TMPe*0<@z}c zDK@j#8V`K;IhjlaH32{`zc*K8M}$+J1`>5MP|0E;fnFZaSvpo}`)F#`h&6Hso`(Gd zg+%h(=&21qtP@yyW%d{8;}w72pQ(11MqP-Ydi|MVddFT*Ih22x4que&aP&;GVhM8p zN>igE)ynA?S@B?#AhkU1VJ#gjJG!8?U6a%KgWF>ak^bdCbI#%`{hYyMAQdFA zF?N`WST>OqcmM$-JA3ka{kIQPNxOc(X;}1pID~jq+rc-iFw~iho!s&?NB-Isb_fUm zu&3*XbAIrk_36~9LGHGDd*|w)!SCkZnh0M0U?VMP6BLEE9(VQgy&Mqug=CcY$IhI# z`$d=WrCv&fP!o$(O{*V&E7GckpWzd*-wg*?*74l$t+lJ1KDew$*Oj&C4H)+RVx_UZ zSyDCpmSVyR>((e&=or`NP!wM3-38~QtZ>om@6P#(5q8gGlIt6oUqR`Ns7Y5q>HH8Nc|847>bD`tDl zhc{(yyA&h|Z{Bg~`Wd9%<|xQ8c~aQ=naHMp8Mwya@NBA~w76M!D`g6!kAU zk2BBJ!M-T|%9pC4?6>c<$CzHsOd~pjx26gq7ZrpKVn&ikvl3qKdeDLmbZpBD= z0hG^0Ox~GeLO_D#!Rto;^+OpeO{3g6#r^YDxC8e{(zomB{7je&619Npi<{=)?7p|h zvwrX~jcakkq3-$p+mG454##KtaI?}}I$lq5f0C(izp$btgp$Qck6YPON5|55t5k%Df<&b2)-=wm zJn*G-u2tzFO7^_!BD`0=*mJ@B&2!|G2DU`@iJffya8@T;t4*5NB1g~i>uwgJj&3ud2er?|XiYz@xCe6xx-8kvY6 zRLZGLUlGC=|5h~NtlIGVyMYwO89boS{pjk@)ErM%r=NY2mWWAUD-#iNVA>Qi5~(sQ zk*70N@TW~azq{w=SXyCb0qfHFBfI==d-UqC9? zObH*~HZ5wmCI!Tq{r6_$fi>%*wMDzwNwg|%_^o=| zb9^a++LnhHwigS+W$r>dR}~;5nD%_k2pT)t@ct`MRZuX6HT_D}2fmyj%vY8JUG>S-u)iHu9MFg|RI} zW5mNMU-xGZd`0?WxO5ys%HeoMyx<&rq7J=`#SoB1 zYZ=1c;-{G2vQJi7ItS5*xmn@xIr=5d`uGu%F*>+#{_=U+Ps!D(`Mh}N8+TT=2ip2q zgKm2V*~$8kMVgTvi$7KN!F^t9kT)`1SVKp~{8Ez}w2%f%M1yi%hqC zs0!OnmOgj;@DXkdIpsS)eeBrpF@_1@-J~eRLY+D2t(sXOBCEdHR6B%1NcXkbun4&G8Z_Z1m?egQ06lepG^*C(?DP#@E$XQ(M2Y(+FViL z8KpA!DpfSdoO2-~z+ba=F2NEP;8FcCwG>ccA?}o2da}%kQ2c^H&p1t$#NG=aMW~KtP z&+lCWAsE5)!pNC$YcoHIVyn7GocBw4!Mx~RP@1!i>8o~m@G~K|j%8tek1+RhsG&p) zUr-DQ&Bo&@%KXvu&@;2Bp3dlWr5Gy81~MLP}p`ENDW4W)Nub+-FlsXFv75N)oLH31#pHK-we5 zO+b^XE+`rr8Zy%z9PSf#cXZUk$XKd-G$%l{xL6==sQJ0MIq(#2xQQAvkYrIl;3j3T zQ5IvBym$*j3M=Y=Nf$0gGALORWizX{1$7&Dw0=#PMB#-P2EkY$`Fs)|4bmz0Qqw|g3>q8 zC`v{+K6l``cnTnm7{G<;4-^Fef^#f=fE%pNQkoJ7C$&1%nxoM`W^4xC4g4U)2(}F$ z@dPTCSgPqbTVs2T-f)~&n>g|0dsPp>gW%VUXSJ;%@;p&F`I3Tq%;8HXnC%h12IO@K zySQn<@#q4CEpvZ1ZanLS3jq1wKDhpvkPnRoB+>WZ2~J2c1aanOAmo4ou#dCf_U^k= zan8UsZciYU9|tTO;$A%bixdUY*$t^VM=nWHv_XW#?)Yn$Js%)F5DQ9^)V^)cDvUX% z!8XmRy#!!f#N`xuDPegR0KQXcNuY`<0=Z-rCkHV8)h^&i&;96JxDRk(i37;GwrfQ@*}-Lk22wr9Qgj3D{Yxr;zM1TU z6hSQD%G{a*pgRgkTyq@IbX*3~$=%?LKgwg;R6m0wn1MWn8+p{Pt*RshK%~1t0|F{P z*LXeWJbPmR2}?gO6!f@N@t}{ln}E3Dt%KZ<68?1HsbDdj%KqdDZEjc?k>ie0&MASt z4{{9xAa5c7D1A)(KqjFNDYwxK^#7|xrp)h#@Eej3b{#Tq66E%egxjo@x2sd8L8_x0 z!2ho}2p%9{Kxw5wDL|JWKFvuKXLCthl_N7V6MAi4hdALGo)F+1Ct&#VD? zfA@LuHh}r+cmp*CYPhTxfsE(nNTo(7U+L!Xo8xvI%;4_62b3$MnH@@N@X4n=H3Tee z7F+e|l}4=SLHO)(QDI{8>0+ZzE1)k2DtFpRR)Ct97%(OEZ$xpW4iJt%6Z8#6t{leK10GN}!MK1k zW>YU0dO)lWtMM303rTU_qQqPrk&}q`iUk+bXd%`v7!rTDZd9h%+jfPVvGcQ7lmHc)@7p2Wme?Tox z9KfVaRTw&GagTmo&5*c3TjtH@o$O)y4qP9Q02^N#PXMLMd$xgH&r&V#fB~e6OdqujvD0vc0%Jr@h`jJr%_F8=rKfZ)U+K9GDZ%M zoz%Okg9Rl|Vt@bqxO*}O7>)0198*a*S2B>~B=vO7uV6e_sVYsY+YO^*;E)9`I%1p# zhsU)@RvG&nzfmEa1qtXUbd=OdM4=`q8gn7bU9I|yGH7fk!92;U4dW%+yw@@A6Z<^4 z;tyo_CqZff2m)6g9>A}>@5wwXgG&I!>)T2m0aRo>%bMJ)* z@%8&X?A?I*DWKdYggd`F+edT~3OG>*mxa|N*{5pv*}LGV7&+&;h;}mk0(Y$tt>erw zHC5F%D91916@%aE?fSYeh#d>+5N+k9vcW>eX7&%<<; z#}Qv`{`ctmueNx2E-TdJ^8g7noBI>bB~t@zitylqHU_!{Gt7zqskgCKn3RsL_qe!R z#l%M;Rqzg^Pgb;Wn$>c1OaA9!&|RSOk`AHpbYnyh8txC;w1WGcPg8$ygCF}PH7pC# zo_-&Q#018h4q3&D9=>u(r{EA5gNb2IdKTmz)v>6doCb5#bOOE zP>yuvy_SMqL8t`JJd!&GHGs9HolZ5<+j4KLR-Gk8ZMj;B2NbnHa5i1o%byo~Re9^2 zDW9UiI6zk_(PfuN8oXhaQMzI^sopf5r3nwy z5vZ7Hi-?nrFZ8}NU4h4YOVY>G4)^C?LO16KUO|?+wC;N0-`)Kg2^3u%&?Ir5Vt5f~ ztItV7KiFZ(HzV>esJ-kSZM3N&aiX{@T6rYTDNi3uPoHQ%z_e4$P)(C{l9r{KHg`{4 zG`|Zj!z*w~IcoiPT5FrK46;7c1*cziNwpdbt1RC2wlJev~W zM-MG_EC;=dcwt(Xg)BrVE$s!!!hFL648O?43VVf21_=0B~jdqk%J7mmRbaLMQQy1QwfU5(i*=EWYe_Z9F>wN zl=2A?;pMNB7lBX+on3KmK#HDyA67&YHY$hCGFqzP9*Rx=ci0mQH!)cTTlliuS-X5s z1j8!Yq`&{x!mVy8-D227{`WcEEiQM4XIi-0mOnxXTK}D;5C0Qym780G@NlcN`MVo4 zM2P$UnhHB$h_4*pBRbC2Y>A6rX3{)j;bUf5e11J701bOGI>12jc8eu9knHt0g4(kK6 zj?XFohC-1Sb1acU(`y_jmo)0_Xy>T+ua}0z5CNzAFPYIE9gMAS-)hS$D3}wmmz?!V z6>M@PVd!@yUE@#x8_&B?P#k>;ANn!n)!7sku@cu9B(&)0T^)bkHRGM%jPkYd`S0ww zl2tix8aTnwHK9ZEL(@9oYX5iAije2scPNhl5kF3Z|Havfs6ylfp2Q)hGA@=F{5Sp_ z6dA6;u*XtD1Be!y0)>~ITm!vRl}5XLxh_U;k4RVAR1UB1$?OouGWb1 zE_ILBS*%SYVG^{RmryiSY84iD?%Y75(SNW&H|1x%xKc29nYNCJ?OK!)B{gt2jV#h^7-Z8T?5sW2P$XL#zoAe==jTGUDRwZ z(2>JT>bshfB@^SG=FIqAL4afm9jIu=wZS|EwSx8c7_= zwcqX->EKr5n;IpU(VB$G44^Z70Tq$J4wb4M3O!tw5$44gWx&-)o#ss0OqpzhRZ<8O zR;;SpP&>9@{@uG*C&p(Yp8es?8<#uwC)adh{7p`TQ1pc%&3~rQNw+a6rT&9|i literal 0 HcmV?d00001 diff --git a/docs/tls.md b/docs/tls.md index e6543074303..b6654bcd141 100644 --- a/docs/tls.md +++ b/docs/tls.md @@ -4,7 +4,7 @@ This document explains how to enable TLS on MinIO pods. ## Automatic TLS -This approach creates TLS certificates automatically using the Kubernetes cluster root Certificate Authority (CA) to establish trust. In this approach, MinIO Operator creates a private key, and a certificate signing request (CSR) which is submitted via the `certificates.k8s.io` API for signing. Automatic TLS approach creates other certificates required for KES as well as explained in [KES document](./kes.md). +This approach creates TLS certificates automatically using the Kubernetes cluster root Certificate Authority (CA) to establish trust. In this approach, MinIO Operator creates a private key and a certificate signing request (CSR) and submits them via the `certificates.k8s.io` API for signing. Automatic TLS approach creates other certificates required for KES as well as explained in [KES document](./kes.md). To enable automatic CSR generation on Tenant, set `requestAutoCert` field in the config file to `true`. Optionally you can also pass additional configuration parameters to be used under `certConfig` section. The `certConfig` section currently supports below fields: @@ -12,15 +12,15 @@ To enable automatic CSR generation on Tenant, set `requestAutoCert` field in the - organizationName: By default set to list `["system:nodes"]`. Change it to a list with the name of your organization, e.g., `organizationName: [my-org]`. -- dnsNames: By default set to list of all pod DNS names that are part of current Tenant. Any value added under this section will be appended to the list of existing pod DNS names. +- dnsNames: By default set to a list of all pod DNS names that are part of current Tenant. Any value added under this section will be appended to the list of existing pod DNS names. -Once you enable `requestAutoCert` field and create the Tenant, MinIO Operator creates a CSR for this instance and sends to the Kubernetes API server. MinIO Operator will then approve the CSR. After the CSR is approved and Certificate available, MinIO operator downloads the certificate and then mounts the Private Key and Certificate within the Tenant pod. +Once you enable the `requestAutoCert` field and create the Tenant, MinIO Operator creates a CSR for this instance and sends to the Kubernetes API server. MinIO Operator will then approve the CSR. After the CSR is approved and Certificate available, MinIO operator downloads the certificate and then mounts the Private Key and Certificate within the Tenant pod. --- ## Pass Certificate Secret to Tenant -This approach involves acquiring a CA signed or self-signed certificate and use a Kubernetes Secret resource to store this information. Once you have the key and certificate file available, create a Kubernetes Secret using +This approach involves acquiring a CA signed or self-signed certificate and using a Kubernetes Secret resource to store this information. Once you have the key and certificate file available, create a Kubernetes Secret with: ```bash kubectl create secret generic tls-ssl-minio --from-file=path/to/private.key --from-file=path/to/public.crt @@ -48,49 +48,5 @@ Once created, set the name of the Secret (in this example `tls-ssl-minio`) under ## Using cert-manager -[Certificate Manager](https://cert-manager.io) is a Kubernetes Operator capable of automatically issuing certificates from multiple Issuers. Integration with MinIO is simple. First, create a new certificate issuer; for this demonstration the issuer certificate will be self-signed: - -```yaml -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: selfsigning-issuer -spec: - selfSigned: {} -``` - -Now it's possible to issue the MinIO certificate using the above issuer: - -```yaml ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: tls-minio -spec: - commonName: minio.example.com - secretName: tls-minio - dnsNames: - # Ingress domain - - minio.example.com - # Internal domain - - minio-hl-svc - - minio-hl-svc.default.svc.cluster.local - issuerRef: - name: selfsigning-issuer -``` - -Finally, configure MinIO to use the newly created TLS certificate: - -```yaml - externalCertSecret: - - name: tls-minio - type: kubernetes.io/tls -``` - -## Using your own CA Certificate for MinIO Operator - -If your `MinIO` tenants are using `custom certificates` or certificates generated by your own internal `certificate authority` (ie: `cert-manager`). -`MinIO Operator` needs to trust the `TLS` connections in order to talk to the `MinIO tenants`, for that you need to create a new secret in the -`minio-operator` namespace named `operator-ca-tls`, inside this secret create a new key `ca.crt` that will include the public certificate -for your internal certificate authority. +[Certificate Manager](https://cert-manager.io) is a Kubernetes Operator capable of automatically issuing certificates from multiple Issuers. +For instructions on using Cert Manager with MinIO please follow the guide in the [cert-manager.md](cert-manager.md) document. \ No newline at end of file diff --git a/examples/kustomization/cert-manager/kustomization.yaml b/examples/kustomization/cert-manager/kustomization.yaml new file mode 100644 index 00000000000..8264beadc02 --- /dev/null +++ b/examples/kustomization/cert-manager/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - selfsigned-root-clusterissuer.yaml diff --git a/examples/kustomization/cert-manager/selfsigned-root-clusterissuer.yaml b/examples/kustomization/cert-manager/selfsigned-root-clusterissuer.yaml new file mode 100644 index 00000000000..479d3a4e359 --- /dev/null +++ b/examples/kustomization/cert-manager/selfsigned-root-clusterissuer.yaml @@ -0,0 +1,6 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-root +spec: + selfSigned: {} diff --git a/examples/kustomization/operator-certmanager/console-tls-certificate.yaml b/examples/kustomization/operator-certmanager/console-tls-certificate.yaml new file mode 100644 index 00000000000..7c14904810d --- /dev/null +++ b/examples/kustomization/operator-certmanager/console-tls-certificate.yaml @@ -0,0 +1,13 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: console-certmanager-cert + namespace: minio-operator +spec: + dnsNames: + - console + - console.minio-operator.svc + - console.minio-operator.svc.cluster.local + secretName: console-tls + issuerRef: + name: minio-operator-ca-issuer diff --git a/examples/kustomization/operator-certmanager/kustomization.yaml b/examples/kustomization/operator-certmanager/kustomization.yaml new file mode 100644 index 00000000000..aeaf5c11393 --- /dev/null +++ b/examples/kustomization/operator-certmanager/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../cert-manager + - ../../../resources + - operator-ca-tls-secret.yaml + - sts-tls-certificate.yaml + - console-tls-certificate.yaml + - minio-operator-ca-issuer.yaml + +patches: + - path: operator-deployment.yaml diff --git a/examples/kustomization/operator-certmanager/minio-operator-ca-issuer.yaml b/examples/kustomization/operator-certmanager/minio-operator-ca-issuer.yaml new file mode 100644 index 00000000000..9affeceb409 --- /dev/null +++ b/examples/kustomization/operator-certmanager/minio-operator-ca-issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: minio-operator-ca-issuer + namespace: minio-operator +spec: + ca: + secretName: operator-ca-tls \ No newline at end of file diff --git a/examples/kustomization/operator-certmanager/operator-ca-tls-secret.yaml b/examples/kustomization/operator-certmanager/operator-ca-tls-secret.yaml new file mode 100644 index 00000000000..719adf29795 --- /dev/null +++ b/examples/kustomization/operator-certmanager/operator-ca-tls-secret.yaml @@ -0,0 +1,17 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: minio-operator-ca-certificate + namespace: minio-operator +spec: + isCA: true + commonName: operator + secretName: operator-ca-tls + duration: 70128h # 8y + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-root + kind: ClusterIssuer + group: cert-manager.io diff --git a/examples/kustomization/operator-certmanager/operator-deployment.yaml b/examples/kustomization/operator-certmanager/operator-deployment.yaml new file mode 100644 index 00000000000..311d42d0694 --- /dev/null +++ b/examples/kustomization/operator-certmanager/operator-deployment.yaml @@ -0,0 +1,17 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: minio-operator + namespace: minio-operator +spec: + template: + spec: + containers: + - name: minio-operator + env: + - name: MINIO_CONSOLE_TLS_ENABLE + value: "off" + - name: OPERATOR_STS_AUTO_TLS_ENABLED + value: "off" + - name: OPERATOR_STS_ENABLED + value: "on" diff --git a/examples/kustomization/operator-certmanager/sts-tls-certificate.yaml b/examples/kustomization/operator-certmanager/sts-tls-certificate.yaml new file mode 100644 index 00000000000..41f686b36db --- /dev/null +++ b/examples/kustomization/operator-certmanager/sts-tls-certificate.yaml @@ -0,0 +1,13 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: sts-certmanager-cert + namespace: minio-operator +spec: + dnsNames: + - sts + - sts.minio-operator.svc + - sts.minio-operator.svc.cluster.local + secretName: sts-tls + issuerRef: + name: minio-operator-ca-issuer diff --git a/examples/kustomization/sts-example/sample-data/mc-job-setup-bucket.yaml b/examples/kustomization/sts-example/sample-data/mc-job-setup-bucket.yaml index 057fb55acdc..d7c96dea2c8 100644 --- a/examples/kustomization/sts-example/sample-data/mc-job-setup-bucket.yaml +++ b/examples/kustomization/sts-example/sample-data/mc-job-setup-bucket.yaml @@ -32,7 +32,7 @@ metadata: name: setup-bucket namespace: minio-tenant-1 spec: - backoffLimit: 5 + backoffLimit: 10 template: spec: serviceAccountName: mc-job-sa diff --git a/examples/kustomization/tenant-certmanager-kes/certificates.yaml b/examples/kustomization/tenant-certmanager-kes/certificates.yaml deleted file mode 100644 index 111e4216f44..00000000000 --- a/examples/kustomization/tenant-certmanager-kes/certificates.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: tenant-certmanager-issuer - namespace: tenant-certmanager -spec: - selfSigned: { } ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: tenant-certmanager-cert - namespace: tenant-certmanager -spec: - dnsNames: - - "*.tenant-certmanager.svc.cluster.local" - - "*.myminio.tenant-certmanager.svc.cluster.local" - - "*.myminio-hl.tenant-certmanager.svc.cluster.local" - secretName: tenant-certmanager-tls - issuerRef: - name: tenant-certmanager-issuer ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: tenant-certmanager-2-cert - namespace: tenant-certmanager -spec: - dnsNames: - - "*.tenant-certmanager.svc.cluster.local" - - "*.myminio.tenant-certmanager.svc.cluster.local" - - "*.myminio-hl.tenant-certmanager.svc.cluster.local" - secretName: tenant-certmanager-2-tls - issuerRef: - name: tenant-certmanager-issuer diff --git a/examples/kustomization/tenant-certmanager-kes/kustomization.yaml b/examples/kustomization/tenant-certmanager-kes/kustomization.yaml index 9593f2e0234..89a5a547ed8 100644 --- a/examples/kustomization/tenant-certmanager-kes/kustomization.yaml +++ b/examples/kustomization/tenant-certmanager-kes/kustomization.yaml @@ -4,7 +4,8 @@ kind: Kustomization namespace: tenant-certmanager-kes resources: - - certificates.yaml + - ../cert-manager + - myminio-kes-certificate.yaml - vault.yaml - ../tenant-kes-encryption diff --git a/examples/kustomization/tenant-certmanager-kes/myminio-kes-certificate.yaml b/examples/kustomization/tenant-certmanager-kes/myminio-kes-certificate.yaml new file mode 100644 index 00000000000..b7d5a7c2ff6 --- /dev/null +++ b/examples/kustomization/tenant-certmanager-kes/myminio-kes-certificate.yaml @@ -0,0 +1,15 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: tenant-certmanager-2-cert + namespace: tenant-certmanager +spec: + dnsNames: + - "minio.tenant-certmanager" + - "minio.tenant-certmanager.svc" + - "*.tenant-certmanager.svc.cluster.local" + - "*.myminio.tenant-certmanager.svc.cluster.local" + - "*.myminio-hl.tenant-certmanager.svc.cluster.local" + secretName: tenant-certmanager-2-tls + issuerRef: + name: tenant-certmanager-issuer diff --git a/examples/kustomization/tenant-certmanager/kustomization.yaml b/examples/kustomization/tenant-certmanager/kustomization.yaml index 106ddb022c1..802404daaf8 100644 --- a/examples/kustomization/tenant-certmanager/kustomization.yaml +++ b/examples/kustomization/tenant-certmanager/kustomization.yaml @@ -1,11 +1,12 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization - namespace: tenant-certmanager resources: - - certificates.yaml + - tenant-certmanager-issuer.yaml + - tenant-certmanager-ca-certificate.yaml + - tenant-certmanager-myminio-certificate.yaml - ../base -patchesStrategicMerge: - - tenant.yaml +patches: + - path: tenant.yaml diff --git a/examples/kustomization/tenant-certmanager/tenant-certmanager-ca-certificate.yaml b/examples/kustomization/tenant-certmanager/tenant-certmanager-ca-certificate.yaml new file mode 100644 index 00000000000..00568ea57b7 --- /dev/null +++ b/examples/kustomization/tenant-certmanager/tenant-certmanager-ca-certificate.yaml @@ -0,0 +1,17 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: tenant-certmanager-ca-certificate + namespace: tenant-certmanager +spec: + isCA: true + commonName: tenant-certmanager-ca + secretName: tenant-certmanager-ca-tls + duration: 70128h # 8y + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-root + kind: ClusterIssuer + group: cert-manager.io diff --git a/examples/kustomization/tenant-certmanager/tenant-certmanager-issuer.yaml b/examples/kustomization/tenant-certmanager/tenant-certmanager-issuer.yaml new file mode 100644 index 00000000000..facee06a396 --- /dev/null +++ b/examples/kustomization/tenant-certmanager/tenant-certmanager-issuer.yaml @@ -0,0 +1,7 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: tenant-certmanager-issuer + namespace: tenant-certmanager +spec: + selfSigned: { } diff --git a/examples/kustomization/tenant-certmanager/certificates.yaml b/examples/kustomization/tenant-certmanager/tenant-certmanager-myminio-certificate.yaml similarity index 73% rename from examples/kustomization/tenant-certmanager/certificates.yaml rename to examples/kustomization/tenant-certmanager/tenant-certmanager-myminio-certificate.yaml index c2c84f279d8..cb39810ff0b 100644 --- a/examples/kustomization/tenant-certmanager/certificates.yaml +++ b/examples/kustomization/tenant-certmanager/tenant-certmanager-myminio-certificate.yaml @@ -1,16 +1,8 @@ apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: tenant-certmanager-issuer - namespace: minio-tenant -spec: - selfSigned: { } ---- -apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: tenant-certmanager-cert - namespace: minio-tenant + namespace: tenant-certmanager spec: # If you see "Empty issuer DN not allowed in X509Certificates" # You will need to add spec.subject.organizations or spec.commonName @@ -23,9 +15,12 @@ spec: # - jetstack # commonName: example.com dnsNames: + - "minio.tenant-certmanager" + - "minio.tenant-certmanager.svc" + - "minio.tenant-certmanager.svc.cluster.local" + - "*.myminio-hl.tenant-certmanager.svc.cluster.local" - "*.tenant-certmanager.svc.cluster.local" - "*.myminio.tenant-certmanager.svc.cluster.local" - - "*.myminio-hl.tenant-certmanager.svc.cluster.local" - secretName: tenant-certmanager-tls + secretName: myminio-tls issuerRef: - name: tenant-certmanager-issuer \ No newline at end of file + name: tenant-certmanager-issuer diff --git a/examples/kustomization/tenant-certmanager/tenant.yaml b/examples/kustomization/tenant-certmanager/tenant.yaml index e8155b4453a..0ec92d16841 100644 --- a/examples/kustomization/tenant-certmanager/tenant.yaml +++ b/examples/kustomization/tenant-certmanager/tenant.yaml @@ -8,5 +8,5 @@ spec: requestAutoCert: false ## Use certificates generated by cert-manager. externalCertSecret: - - name: tenant-certmanager-tls + - name: myminio-tls type: cert-manager.io/v1 diff --git a/kustomization.yaml b/kustomization.yaml index dbaaf8f8a94..d480503034e 100644 --- a/kustomization.yaml +++ b/kustomization.yaml @@ -2,18 +2,16 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: minio-operator commonAnnotations: - operator.min.io/authors: "MinIO, Inc." - operator.min.io/license: "AGPLv3" - operator.min.io/support: "https://subnet.min.io" + operator.min.io/authors: MinIO, Inc. + operator.min.io/license: AGPLv3 + operator.min.io/support: https://subnet.min.io resources: - - resources/base/namespace.yaml - - resources/base/service-account.yaml - - resources/base/cluster-role.yaml - - resources/base/cluster-role-binding.yaml - - resources/base/crds/ - - resources/base/service.yaml - - resources/base/deployment.yaml - - resources/base/console-ui.yaml - - +- resources/base/namespace.yaml +- resources/base/service-account.yaml +- resources/base/cluster-role.yaml +- resources/base/cluster-role-binding.yaml +- resources/base/crds/ +- resources/base/service.yaml +- resources/base/deployment.yaml +- resources/base/console-ui.yaml diff --git a/pkg/controller/main-controller.go b/pkg/controller/main-controller.go index 91f7a5e0a1d..8e34682d458 100644 --- a/pkg/controller/main-controller.go +++ b/pkg/controller/main-controller.go @@ -417,7 +417,7 @@ func (c *Controller) startSTSAPIServer(ctx context.Context, notificationChannel } certsManager, err := xcerts.NewManager(ctx, publicCertPath, privateKeyPath, LoadX509KeyPair) if err != nil { - klog.Errorf("HTTPS STS API server failed to load CA certificate: %v", err) + klog.Errorf("HTTPS STS API server failed to load certificate: %v", err) notificationChannel <- &EventNotification{ Type: STSServerNotification, Err: err, @@ -501,9 +501,11 @@ func leaderRun(ctx context.Context, c *Controller, threadiness int, stopCh <-cha go func() { if utils.GetOperatorRuntime() == common.OperatorRuntimeOpenshift { klog.Infof("STS is enabled, skipping TLS certificate generation on Openshift deployment") - } else { - klog.Infof("STS is enabled, starting API certificate setup") + } else if IsSTSAutocertEnabled() { + klog.Infof("STS Autocert is enabled, starting API certificate setup.") c.generateSTSTLSCert() + } else { + klog.Infof("STS Autocert is disabled, skipping certificate generation.") } }() } diff --git a/pkg/controller/sts.go b/pkg/controller/sts.go index 1c9f1ac4472..6d64b6257a0 100644 --- a/pkg/controller/sts.go +++ b/pkg/controller/sts.go @@ -43,6 +43,10 @@ const ( // STSEnabled Env variable name to turn on and off the STS Service is enabled, disabled by default STSEnabled = "OPERATOR_STS_ENABLED" + // STSAutoTLSEnabled Env variable name to turn on and off generation of the STS TLS automatically using CSR, if disabled + // a certificate issued externally needs to be provided + STSAutoTLSEnabled = "OPERATOR_STS_AUTO_TLS_ENABLED" + // STSTLSSecretName is the name of secret created for the Operator STS TLS certs STSTLSSecretName = "sts-tls" ) @@ -398,6 +402,15 @@ func IsSTSEnabled() bool { return true } +// IsSTSAutocertEnabled Validates if STS Autocert is turned on, is enabled by default. +func IsSTSAutocertEnabled() bool { + value, set := os.LookupEnv(STSAutoTLSEnabled) + if set { + return value == "on" + } + return true +} + // generateConsoleTLSCert Issues the Operator Console TLS Certificate func (c *Controller) generateSTSTLSCert() (*string, *string) { return c.generateTLSCertificateForService("sts", STSTLSSecretName, getOperatorDeploymentName()) diff --git a/testing/certmanager/mc-admin-info-pod.yaml b/testing/certmanager/mc-admin-info-pod.yaml new file mode 100644 index 00000000000..0b2e6868277 --- /dev/null +++ b/testing/certmanager/mc-admin-info-pod.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + run: admin-mc + name: admin-mc + namespace: tenant-certmanager +spec: + containers: + - command: + - bash + - -c + - until (mc admin info myminio/ ); do echo 'waiting... for 5secs' && sleep 5; done + env: + - name: MC_HOST_myminio + value: https://minio:minio123@minio.tenant-certmanager.svc.cluster.local + image: quay.io/minio/mc + name: admin-mc + volumeMounts: + - name: certmanager-ca + mountPath: /root/.mc/certs/CAs/myminio.crt + subPath: tls.crt + volumes: + - name: certmanager-ca + secret: + secretName: myminio-tls + items: + - key: tls.crt + path: tls.crt + mode: 422 + dnsPolicy: ClusterFirst + restartPolicy: Never \ No newline at end of file diff --git a/testing/common.sh b/testing/common.sh index b2798de7547..c5a3300fd28 100644 --- a/testing/common.sh +++ b/testing/common.sh @@ -590,6 +590,12 @@ function install_operator() { echo "key, value for pod selector in kustomize test" key=name value=minio-operator + elif [ "$1" = "certmanager" ]; then + echo "Installing Current Operator with certmanager" + try kubectl apply -k "${SCRIPT_DIR}/../examples/kustomization/operator-certmanager" + echo "key, value for pod selector in kustomize test" + key=name + value=minio-operator else echo "Installing Current Operator" echo "When coming from the upgrade test, the operator is already installed." @@ -743,10 +749,25 @@ function check_tenant_status() { # File: operator/helm/tenant/values.yaml # Content: s3.bucketDNS: false echo "In helm values by default bucketDNS.s3 is disabled, skipping mc validation on helm test" + elif [ "$4" = "certmanager" ]; then + echo "Running mc admin info pod for tenant-certmanager-ca-tls secret..." + try kubectl apply -f "${SCRIPT_DIR}/certmanager/mc-admin-info-pod.yaml" + sleep 10 + echo "Wait to mc admin info minio/" + try kubectl wait --for=jsonpath="{.status.phase}=Succeeded" --timeout=10m pod/admin-mc --namespace tenant-certmanager + + # Retrieve the logs + kubectl logs admin-mc -n tenant-certmanager else - kubectl run admin-mc -i --tty --image quay.io/minio/mc \ + try kubectl run --restart=Never admin-mc --image quay.io/minio/mc \ --env="MC_HOST_minio=https://${USER}:${PASSWORD}@minio.${1}.svc.cluster.local" \ - --command -- bash -c "until (mc admin info minio/); do echo 'waiting... for 5secs' && sleep 5; done" + --command -- bash -c "until (mc admin info minio/ ); do echo 'waiting... for 5secs' && sleep 5; done" + sleep 10 + echo "Wait to mc admin info minio/" + try kubectl wait --for=jsonpath="{.status.phase}=Succeeded" --timeout=10m pod/admin-mc --namespace default + + # Retrieve the logs + kubectl logs admin-mc fi echo "Done." @@ -756,10 +777,10 @@ function check_tenant_status() { function install_cert_manager_tenant() { echo "Install cert-manager tenant from our example:" - try kubectl apply -k github.com/minio/operator/examples/kustomization/tenant-certmanager + try kubectl apply -k "${SCRIPT_DIR}/../examples/kustomization/tenant-certmanager" echo "Wait until tenant-certmanager-tls secret is generated by cert-manager..." - while ! kubectl get secret tenant-certmanager-tls --namespace tenant-certmanager + while ! kubectl get secret tenant-certmanager-ca-tls --namespace tenant-certmanager do echo "Waiting for my secret. Current secrets are:" kubectl get secrets -n tenant-certmanager @@ -769,9 +790,9 @@ function install_cert_manager_tenant() { # https://github.com/minio/operator/blob/master/docs/cert-manager.md echo "# Pass the CA cert to our Operator to trust the tenant:" echo "## First get the CA from cert-manager secret..." - try kubectl get secrets -n tenant-certmanager tenant-certmanager-tls -o=jsonpath='{.data.ca\.crt}' | base64 -d > public.crt + try kubectl get secrets -n tenant-certmanager tenant-certmanager-ca-tls -o=jsonpath='{.data.ca\.crt}' | base64 -d > public.crt echo "## Then create the secret in operator's namespace..." - try kubectl create secret generic operator-ca-tls --from-file=public.crt -n minio-operator + try kubectl create secret generic operator-ca-tls-tenant-certmanager --from-file=public.crt -n minio-operator echo "## Finally restart minio operator pods to catch up and trust tenant..." try kubectl rollout restart deployment.apps/minio-operator -n minio-operator @@ -852,7 +873,7 @@ function setup_sts_bucket() { namespace="minio-tenant-1" condition="condition=Complete" selector="metadata.name=setup-bucket" - try wait_for_resource_field_selector $namespace job $condition $selector + try wait_for_resource_field_selector $namespace job $condition $selector "600s" echo "Installing setup bucket job: DONE" } diff --git a/testing/deploy-cert-manager-tenant.sh b/testing/deploy-cert-manager-tenant.sh index 88326608e6f..1bd1a091f79 100755 --- a/testing/deploy-cert-manager-tenant.sh +++ b/testing/deploy-cert-manager-tenant.sh @@ -29,11 +29,11 @@ function main() { install_cert_manager - install_operator + install_operator certmanager install_cert_manager_tenant - check_tenant_status tenant-certmanager myminio + check_tenant_status tenant-certmanager myminio minio "certmanager" destroy_kind } diff --git a/testing/sts/operator/kustomization.yaml b/testing/sts/operator/kustomization.yaml index d41c4edaa38..9c9a55d9fdd 100644 --- a/testing/sts/operator/kustomization.yaml +++ b/testing/sts/operator/kustomization.yaml @@ -4,6 +4,6 @@ kind: Kustomization bases: - ../../../resources -patchesStrategicMerge: - - deployment.yaml - - console-deployment.yaml +patches: + - path: deployment.yaml + - path: console-deployment.yaml