From cadd93b080b1ff3baa375411b7ff5e73ba2814bb Mon Sep 17 00:00:00 2001 From: Tom Morelly Date: Fri, 26 Jan 2024 23:28:14 +0100 Subject: [PATCH] feat(kms): add trousseau as kms plugin --- .envrc | 2 + .gitignore | 3 +- .terraform.lock.hcl | 236 ++++++++++++++++++ README.md | 1 + docs/assets/kms.png | Bin 0 -> 62700 bytes docs/esm.md | 1 - docs/home.md | 1 + docs/kms.md | 142 +++++++++++ .../files/encryption_provider_config.yml | 12 + k8s-minikube/files/kube-api-server.yml | 134 ++++++++++ k8s-minikube/files/trousseau.yml | 85 +++++++ k8s-minikube/files/vault-policy.hcl | 6 + .../templates/trousseau-config.yml.tmpl | 6 + k8s-minikube/terraform/kubernetes.tf | 25 ++ .../terraform/{main.tf => minikube.tf} | 0 k8s-minikube/terraform/variables.tf | 3 + k8s-minikube/terraform/vault.tf | 26 ++ k8s-minikube/terraform/version.tf | 8 + main.tf | 3 + mkdocs.yml | 1 + terraform.tfvars | 5 +- variables.tf | 1 + 22 files changed, 697 insertions(+), 4 deletions(-) create mode 100644 .terraform.lock.hcl create mode 100644 docs/assets/kms.png create mode 100644 docs/kms.md create mode 100644 k8s-minikube/files/encryption_provider_config.yml create mode 100644 k8s-minikube/files/kube-api-server.yml create mode 100644 k8s-minikube/files/trousseau.yml create mode 100644 k8s-minikube/files/vault-policy.hcl create mode 100644 k8s-minikube/templates/trousseau-config.yml.tmpl create mode 100644 k8s-minikube/terraform/kubernetes.tf rename k8s-minikube/terraform/{main.tf => minikube.tf} (100%) create mode 100644 k8s-minikube/terraform/variables.tf create mode 100644 k8s-minikube/terraform/vault.tf diff --git a/.envrc b/.envrc index 1e7dcbe..cb0208d 100644 --- a/.envrc +++ b/.envrc @@ -1,5 +1,7 @@ export VAULT_ADDR="https://127.0.0.1" export VAULT_CAPATH="$(readlink -f ./vault-tls/output/ca.crt)" export VAULT_TOKEN="$(cat .vault_token)" + export MINIKUBE_PROFILE="vault-playground" + export TF_CLI_ARGS_test="-compact-warnings" diff --git a/.gitignore b/.gitignore index 89d9a15..5bfdcef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -**/.terraform -**/.terraform.lock.hcl +**/.terraform/ **/terraform.tfstate **/terraform.tfstate.backup **/.vault_token diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl new file mode 100644 index 0000000..4790096 --- /dev/null +++ b/.terraform.lock.hcl @@ -0,0 +1,236 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/devops-rob/terracurl" { + version = "1.1.0" + constraints = "1.1.0" + hashes = [ + "h1:KJDCzx3jNEoghZ70MnWcFgpIzER7LAQwpbOqz7LWKl0=", + "zh:30b6484decca0ff28806a323af2a00232fc16a6571e26f490a67205b3233098d", + "zh:68580fcaf39986bee302e1b89c1a255bfec720684b1981197d75f36148146376", + "zh:b7b589eb8e09e07ef999c410f79c1fe8faaa0c9eb572fd557af9cd14720213a3", + "zh:beb145381895bec30a940ddbd9035e277e1e4b2ec3155c6d5a382cee1fbdf2e6", + "zh:e18113ad8c5e2de6e2a34cf40d2f27ff8cda308e9d89e91114fb8366946c0184", + "zh:e405ad705e14b841d5d827e9ce1d0a3b3149bab6b0ff14d266359b83cf144c87", + ] +} + +provider "registry.terraform.io/gavinbunney/kubectl" { + version = "1.14.0" + constraints = "1.14.0" + hashes = [ + "h1:gLFn+RvP37sVzp9qnFCwngRjjFV649r6apjxvJ1E/SE=", + "zh:0350f3122ff711984bbc36f6093c1fe19043173fad5a904bce27f86afe3cc858", + "zh:07ca36c7aa7533e8325b38232c77c04d6ef1081cb0bac9d56e8ccd51f12f2030", + "zh:0c351afd91d9e994a71fe64bbd1662d0024006b3493bb61d46c23ea3e42a7cf5", + "zh:39f1a0aa1d589a7e815b62b5aa11041040903b061672c4cfc7de38622866cbc4", + "zh:428d3a321043b78e23c91a8d641f2d08d6b97f74c195c654f04d2c455e017de5", + "zh:4baf5b1de2dfe9968cc0f57fd4be5a741deb5b34ee0989519267697af5f3eee5", + "zh:6131a927f9dffa014ab5ca5364ac965fe9b19830d2bbf916a5b2865b956fdfcf", + "zh:c62e0c9fd052cbf68c5c2612af4f6408c61c7e37b615dc347918d2442dd05e93", + "zh:f0beffd7ce78f49ead612e4b1aefb7cb6a461d040428f514f4f9cc4e5698ac65", + ] +} + +provider "registry.terraform.io/hashicorp/helm" { + version = "2.12.1" + constraints = "2.12.1" + hashes = [ + "h1:sgYI7lwGqJqPopY3NGmhb1eQ0YbH8PIXaAZAmnJrAvw=", + "zh:1d623fb1662703f2feb7860e3c795d849c77640eecbc5a776784d08807b15004", + "zh:253a5bc62ba2c4314875139e3fbd2feaad5ef6b0fb420302a474ab49e8e51a38", + "zh:282358f4ad4f20d0ccaab670b8645228bfad1c03ac0d0df5889f0aea8aeac01a", + "zh:4fd06af3091a382b3f0d8f0a60880f59640d2b6d9d6a31f9a873c6f1bde1ec50", + "zh:6816976b1830f5629ae279569175e88b497abbbac30ee809948a1f923c67a80d", + "zh:7d82c4150cdbf48cfeec867be94c7b9bd7682474d4df0ebb7e24e148f964844f", + "zh:83f062049eea2513118a4c6054fb06c8600bac96196f25aed2cc21898ec86e93", + "zh:a79eec0cf4c08fca79e44033ec6e470f25ff23c3e2c7f9bc707ed7771c1072c0", + "zh:b2b2d904b2821a6e579910320605bc478bbef063579a23fbfdd6fcb5871b81f8", + "zh:e91177ca06a15487fc570cb81ecef6359aa399459ea2aa7c4f7367ba86f6fcad", + "zh:e976bcb82996fc4968f8382bbcb6673efb1f586bf92074058a232028d97825b1", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/http" { + version = "3.4.1" + constraints = "3.4.1" + hashes = [ + "h1:WHowkin6m5sX2+SjPVI3kMOkWpFQf8jd2cDlZa0NF/4=", + "zh:2a79832069a34e88ec997fb8d2c2bdad6f40bfe93a4ae5e6e7f0caf4eea2a9e5", + "zh:37d3611857ab207e1565e441a2df9020b1326b7df31e5656165cb6817306494b", + "zh:48cc974b12544be18c18bfcb5ea21a4818d03b897e96fb9b4d0d9303883cb3fa", + "zh:4b8da2ffe868082830173fdcc8632e2705918e0396c72158d7822650bb1d3bf6", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:8148614299a21be04dd11268047e110df3ce9ef585d6240bed2f196839946efa", + "zh:a6d583cb70b1355fbc7b1c2cffaa53e4703b04ced9d0ecf78708129ce7072128", + "zh:a95f770e8913dd48fde8836cf993fafdbf7da5308a6fbd3d455cb10737742990", + "zh:b36784e6602e6ae7ba67560ebcfd055b4448cb0edf9bf35744c2f32ddbd8fa2d", + "zh:c23b37fd9e481269fc55735b24c7e8877057c08b42671c796816409d54486a1c", + "zh:df07252b27120020d91d7ad11f7ea92832d8df2e81b55a658ac1eb93dc6b8d18", + "zh:e44dc5a1fd5995bfd21d385949d539c619e8b37b69875bd92ad4aa18e2435722", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.25.2" + constraints = "2.25.2" + hashes = [ + "h1:QlTKoO0efmkzgX/9y0DQCEkg7VeidOSQW8epF6B4cEQ=", + "zh:044788ac936e0e8ece8f78a2e4e366ecd435ea8235388eaf2cbc8e7975d9d970", + "zh:24f5ff01df91f51f00ee7ff39430adeb63bb2ca4ea0042e68f06d6b65808c02f", + "zh:49984aa0aa1faa8c4f01e8faa039322f1e6fdaeab0b7e32f5c6e96edfde36a38", + "zh:4eeceaff56bac9fc782e7e33f157fa2c7e9a47b2c3c3d12da2642c312ace73f6", + "zh:4f49b6419345960d5af475e0200c243af4c9c140b0ee64799fe1fc9b023c49ea", + "zh:7958414d516867a2263a978792a24843f80023fb233cf051ff4095adc9803d85", + "zh:c633a755fc95e9ff0cd73656f052947afd85883a0987dde5198113aa48474156", + "zh:cbfe958d119795004ce1e8001449d01c056fa2a062b51d07843d98be216337d7", + "zh:cfb85392e18768578d4c943438897083895719be678227fd90efbe3500702a56", + "zh:d705a661ed5da425dd236a48645bec39fe78a67d2e70e8460b720417cbf260ac", + "zh:ddd7a01263da3793df4f3b5af65f166307eed5acf525e51e058cda59009cc856", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/local" { + version = "2.4.1" + constraints = "2.4.1" + hashes = [ + "h1:FzraUapGrJoH3ZOWiUT2m6QpZAD+HmU+JmqZgM4/o2Y=", + "zh:244b445bf34ddbd167731cc6c6b95bbed231dc4493f8cc34bd6850cfe1f78528", + "zh:3c330bdb626123228a0d1b1daa6c741b4d5d484ab1c7ae5d2f48d4c9885cc5e9", + "zh:5ff5f9b791ddd7557e815449173f2db38d338e674d2d91800ac6e6d808de1d1d", + "zh:70206147104f4bf26ae67d730c995772f85bf23e28c2c2e7612c74f4dae3c46f", + "zh:75029676993accd6bef933c196b2fad51a9ec8a69a847dbbe96ec8ebf7926cdc", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7d48d5999fe1fcdae9295a7c3448ac1541f5a24c474bd82df6d4fa3732483f2b", + "zh:b766b38b027f0f84028244d1c2f990431a37d4fc3ac645962924554016507e77", + "zh:bfc7ad301dada204cf51c59d8bd6a9a87de5fddb42190b4d6ba157d6e08a1f10", + "zh:c902b527702a8c5e2c25a6637d07bbb1690cb6c1e63917a5f6dc460efd18d43f", + "zh:d68ae0e1070cf429c46586bc87580c3ed113f76241da2b6e4f1a8348126b3c46", + "zh:f4903fd89f7c92a346ae9e666c2d0b6884c4474ae109e9b4bd15e7efaa4bfc29", + ] +} + +provider "registry.terraform.io/hashicorp/time" { + version = "0.10.0" + constraints = "0.10.0" + hashes = [ + "h1:EeF/Lb4db1Kl1HEHzT1StTC7RRqHn/eB7aDR3C3yjVg=", + "zh:0ab31efe760cc86c9eef9e8eb070ae9e15c52c617243bbd9041632d44ea70781", + "zh:0ee4e906e28f23c598632eeac297ab098d6d6a90629d15516814ab90ad42aec8", + "zh:3bbb3e9da728b82428c6f18533b5b7c014e8ff1b8d9b2587107c966b985e5bcc", + "zh:6771c72db4e4486f2c2603c81dfddd9e28b6554d1ded2996b4cb37f887b467de", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:833c636d86c2c8f23296a7da5d492bdfd7260e22899fc8af8cc3937eb41a7391", + "zh:c545f1497ae0978ffc979645e594b57ff06c30b4144486f4f362d686366e2e42", + "zh:def83c6a85db611b8f1d996d32869f59397c23b8b78e39a978c8a2296b0588b2", + "zh:df9579b72cc8e5fac6efee20c7d0a8b72d3d859b50828b1c473d620ab939e2c7", + "zh:e281a8ecbb33c185e2d0976dc526c93b7359e3ffdc8130df7422863f4952c00e", + "zh:ecb1af3ae67ac7933b5630606672c94ec1f54b119bf77d3091f16d55ab634461", + "zh:f8109f13e07a741e1e8a52134f84583f97a819e33600be44623a21f6424d6593", + ] +} + +provider "registry.terraform.io/hashicorp/tls" { + version = "4.0.5" + constraints = "4.0.5" + hashes = [ + "h1:e4LBdJoZJNOQXPWgOAG0UuPBVhCStu98PieNlqJTmeU=", + "zh:01cfb11cb74654c003f6d4e32bbef8f5969ee2856394a96d127da4949c65153e", + "zh:0472ea1574026aa1e8ca82bb6df2c40cd0478e9336b7a8a64e652119a2fa4f32", + "zh:1a8ddba2b1550c5d02003ea5d6cdda2eef6870ece86c5619f33edd699c9dc14b", + "zh:1e3bb505c000adb12cdf60af5b08f0ed68bc3955b0d4d4a126db5ca4d429eb4a", + "zh:6636401b2463c25e03e68a6b786acf91a311c78444b1dc4f97c539f9f78de22a", + "zh:76858f9d8b460e7b2a338c477671d07286b0d287fd2d2e3214030ae8f61dd56e", + "zh:a13b69fb43cb8746793b3069c4d897bb18f454290b496f19d03c3387d1c9a2dc", + "zh:a90ca81bb9bb509063b736842250ecff0f886a91baae8de65c8430168001dad9", + "zh:c4de401395936e41234f1956ebadbd2ed9f414e6908f27d578614aaa529870d4", + "zh:c657e121af8fde19964482997f0de2d5173217274f6997e16389e7707ed8ece8", + "zh:d68b07a67fbd604c38ec9733069fbf23441436fecf554de6c75c032f82e1ef19", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/vault" { + version = "3.24.0" + constraints = "3.24.0" + hashes = [ + "h1:LzPF3QEWQNaUzj/2L8dL/c3YMwTOWf43GEbQylC6ijw=", + "zh:07acaeb1a0de919b26cd5502e3fb3782d4d22beef6742f6dd6a69d0c03c5201a", + "zh:1267dd82d0dce502faa5f15a8851bf7fa15824747a63572d537f393a07977e1f", + "zh:344da6568e71a372f48eecdddb3fedf48c99d6f5ba9692edcee766fe53ff4039", + "zh:3fb980daacd9332a77138eee6ee29a0e5e830a6592a9110619ca7c22c7573c30", + "zh:44a1423f35c97f5b1a39d21f52ab73c3496bf9c5f03bee99462761edf353c5b7", + "zh:527757ebb26bfc1bae700931a03d1d12072a8612c9bc36532ab583e659e0dd7c", + "zh:61e455a8a8509a3877e28fbe3d34fb4c2858105dcd620fc77410268b1fb99c08", + "zh:62908cd52ad914134a436e01d88dacc6e71591dc9769a8e036175de9332769d2", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:84e137806a5908c3a07dead8e1ee2fdca528a39cd413c1f21384c5595ddd8f15", + "zh:bf9c2288650c1c625b1d412ebe6a9c8ef246b2f90581bb22a63940c6a461a6b3", + "zh:eac726bf8c59fe3cdcb905278d5bf0c53668b59f0fddad71707fd2def0c81aa6", + ] +} + +provider "registry.terraform.io/kreuzwerker/docker" { + version = "3.0.2" + constraints = "3.0.2" + hashes = [ + "h1:cT2ccWOtlfKYBUE60/v2/4Q6Stk1KYTNnhxSck+VPlU=", + "zh:15b0a2b2b563d8d40f62f83057d91acb02cd0096f207488d8b4298a59203d64f", + "zh:23d919de139f7cd5ebfd2ff1b94e6d9913f0977fcfc2ca02e1573be53e269f95", + "zh:38081b3fe317c7e9555b2aaad325ad3fa516a886d2dfa8605ae6a809c1072138", + "zh:4a9c5065b178082f79ad8160243369c185214d874ff5048556d48d3edd03c4da", + "zh:5438ef6afe057945f28bce43d76c4401254073de01a774760169ac1058830ac2", + "zh:60b7fadc287166e5c9873dfe53a7976d98244979e0ab66428ea0dea1ebf33e06", + "zh:61c5ec1cb94e4c4a4fb1e4a24576d5f39a955f09afb17dab982de62b70a9bdd1", + "zh:a38fe9016ace5f911ab00c88e64b156ebbbbfb72a51a44da3c13d442cd214710", + "zh:c2c4d2b1fd9ebb291c57f524b3bf9d0994ff3e815c0cd9c9bcb87166dc687005", + "zh:d567bb8ce483ab2cf0602e07eae57027a1a53994aba470fa76095912a505533d", + "zh:e83bf05ab6a19dd8c43547ce9a8a511f8c331a124d11ac64687c764ab9d5a792", + "zh:e90c934b5cd65516fbcc454c89a150bfa726e7cf1fe749790c7480bbeb19d387", + "zh:f05f167d2eaf913045d8e7b88c13757e3cf595dd5cd333057fdafc7c4b7fed62", + "zh:fcc9c1cea5ce85e8bcb593862e699a881bd36dffd29e2e367f82d15368659c3d", + ] +} + +provider "registry.terraform.io/scott-the-programmer/minikube" { + version = "0.3.7" + constraints = "0.3.7" + hashes = [ + "h1:ECEj1yLtfqOuKp0EAERE0FmBqMoRTgN97i7Z2mr5VpY=", + "zh:081c0e617fb4e6b5fd01f57400b1a6dda72e4cb7e443044e210036bd2ee6320f", + "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", + "zh:236ac62eb2e3d5f9af0d9cf4b1374e1538210bd077ddafc861a345c69e3ed8d5", + "zh:3eacd3a99507d35aae063d22246e03922726504c1e6d157c2ab2295a6a46a207", + "zh:548456b15813ac04a0df3e77dde1bb39c628235adda4f14984b6880d97d2f57c", + "zh:56d966f21517ac41cd2c15d7db9107fc9fcc6760cf719cd7d0c87bed2ba5a8e5", + "zh:959d9dca796f1307ad511ebf15991b5d96ddd468bb65ffd81bc7619511f5d46f", + "zh:965c2fab21a314fac02424c22498297f07417d04c60d2e8980cb1760b965e6c8", + "zh:aac2c2796916ae20a50c5ccd50591ff3df88f500dd983fecceb9a1a1cc2781ff", + "zh:aebf0590eb766235f55c82748818faed310caf3d0000ee026825ee36f193eba0", + "zh:cb3037e25e630845f07c8d98d754f4bf330c00b719614647868dc6bfe2486f58", + ] +} + +provider "registry.terraform.io/scottwinkler/shell" { + version = "1.7.10" + constraints = "1.7.10" + hashes = [ + "h1:yPUe5wSWvyz0d56XUdyoP+TqVj2xP/ruTzfk0yWXJws=", + "zh:0017ae6dcdcf320df10dd0a24f22dd7f1bd92cc62c2550f5696888d7bb042d81", + "zh:00574d8102685054080ad68db5ee99f1ee02c07709d3f77324be2d134eddf0d4", + "zh:0a9b84dccbfe0e704a81c1e76f75c95efdc4bf03c6a1a210b1b386dfd1593209", + "zh:2426358421619cb9125f2145f567908a904fd2a51e86c0afdf92082ea0532e9d", + "zh:425794426f7bb78921b3329c82f6373d5a5f072f28cc7296fdb21e13c595c0e8", + "zh:64d1a85a356ab75e84f12cbab41c548e069609098279eb5360c295b06a6f2994", + "zh:71612774c04cdeae2520a0ea19f938c17b9f6600eaa0356905f40d35caca1e81", + "zh:8d841d44c929bc4882d05c59ddd1bb1b91174c96139500ba29daacf74cf91406", + "zh:97ed1034b0962be59d2e03221031cb49f2ac9e992392bab3b08cbce9fa15e244", + "zh:9daebe55771a8e5b7b21c59cd53d86af9a1435e903ca60de119ccb3bc73a87b8", + "zh:a2d477ed687592a392439c7f96e378c9aa356151f7b2b44dcebc9aae956018e0", + "zh:c0f7e2656593ac97db96d82da41d8a3bd6584406f6d944b02d14ab132b3043ad", + "zh:cc24f9cd5ba535fbdb1bcabea69c5f150b43004ed180a3d14d740700d0d1a4b7", + "zh:cd7283a1a9fb857eb0c2e436ad9859b557127b594a1c7f818c1cb7a20df1c724", + ] +} diff --git a/README.md b/README.md index 05ae0b4..9371865 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Please refer to the [documentation](https://falcosuessgott.github.io/hashicorp-v ### Kubernetes * [x] [Vault Kubernetes Auth Method](https://falcosuessgott.github.io/hashicorp-vault-playground/minikube/) +* [x] [Vault as a KMS Provider](https://falcosuessgott.github.io/hashicorp-vault-playground/kms/) * [x] [External Secrets Manager](https://falcosuessgott.github.io/hashicorp-vault-playground/esm/) * [x] [Vault Secrets operator](https://falcosuessgott.github.io/hashicorp-vault-playground/vso/) * [x] [Vault Agent Injector](https://falcosuessgott.github.io/hashicorp-vault-playground/vai/) diff --git a/docs/assets/kms.png b/docs/assets/kms.png new file mode 100644 index 0000000000000000000000000000000000000000..d13984977e4f61ae717a4e62a1596c8a515d97b5 GIT binary patch literal 62700 zcmeFZcQjn@yEi$Bc(?q1=bZJt&sp#L&$HI^&)I8P_T00}y{~;=?Q?yuiPF(hp{8J=0D(Z% zs?U_3gFsh&K%mQISIK~pll(zl;NLa3XGR_%5GDP^9| zV)sPz2?$gfM|o;V3IgrDQB``P??bXNb?uwpV$=B!t^yxcRTwfu)&o~2h1st^C$0Vc zp3=CMv6S(!ESRaIxar`)xOUtrt8BEm)~~iU)L)RH_Pqk5zD@sO7>svnc$SOpR%{6Q z-yN>G{~7upN&L^603`4~s__456jE+d7$z&IYsMU|MiSg*DoD_s_cXpvSrZR{WKlpdj;5 z^PDW7Z-2LWsx?}2!fAe#6ID70?N0Zo8snYt&^nmJvdF~Ew)`ooaA^fT2K=>r1Inb@ zB8`+W=OUMdxb1`PcAHvPVCjEQeAvO2fZRg`o4!< zUzySTI&05g%UV|C>{a52PE3$(WZ77+!On5S&qnWmjT)C^vECg@UK5&|zK{1wBq zNDdkKSeXNCl^IDNKCULG8PP}yTUfA?Zv6f9(BZ3vTytS-17wQ!;tujsSAc^x{O0sv zft`!w9bst?APa@XD#ICkn15d`Jfz@IDZ^6_z(^mexmxBS{?MOXV&Ap0Xl>&?>NEiUeq`9P=T^2H8_&i#ta-yP6D zDnI^XXb*TjVSeHgTzda;_{H1kPV##2Un3U|Fr*ZGfPHlF=w+T$1|?A!Qd_@|#r4bN zl@OZRKHbl6`j_aGuE^NajY6@^rrs}-rdUnjY>ylxgv^@JiZD7BD$JGMT8u zzccvwj@$UIeYM>5tN3&iyJ{vEZM=hZqq5v{M`kZePRwOQN?frC-XCS0rQq{fnil{bi>K!mm-2#wFv#)~G); z{qFpKynaBeADUo!jp^XZXfdUt&@?64l>udL^msgGRQ0!rTijD|yPq_@Ow`1GpAi~D zPHNfn>k-q&J=)OJwbBxGC^>kU#@;zzMYKxVmSJME+!mGbSF*VZKf<1ss8+-~o76Jy z9l3S#Kl(fV`h5ubr!T!P`6duf*Z018ytKkhW`6?9NQg5CvTb2^)@T|7$ws6vjt#-y z0$z!~*WHca!AUCb&tL<@6K&LJ%%2|X>!^u4hp+bXxTox`Hy~=(56d5G`Zc(z4CSiN?X5(`#jgeZo!HR{ zhp(VTD7*HE%xnl>!uiRV0R~Z8H049pR`vG)udonuUp`!D+S*leski@{;pEdFVc&JH zwrJgKp}9CH6MnH~Y!>?>JtTj^pn^3o`P8zH{w_|C{?i|NFQ00>n1$PEZ@kjY46y|4 z*}Anssi~j~W*AW2+9l+#QcnxPUai9>=!v40T<9)Zg2GcCwZSzjv&=4KwwA zsTImZsyr4PeD3(KR}Ny7DU<-#&h-g5m42zblEwv=p{&cRP@E;greq>E%~qOugqb-e zto%y~S+JL=rPAG7@6c&CW37~!JKd=|-7RxM$@gtrK9}7P16JNc(7sA=G8D^3xE?Z$} zliMc2rk8YoENi`H>wI@Tc7EY;ET!H+e_8Mq}mk z@z;HYubhUeyghmw(~aW?f^bs#P1Kyg zMQOo4I`?nfn@ZXFvJysP?*gcBi6>!q1S3Ey(@AZwyRH|c?H2^Cz(WpcPV863SzSP{ z!{z!ZI%%4X6_mE?<5@Z%W{1u{7K@#4ZKD$!j*@=L1S-8 z?(Jj?4aGV2hVo!c6P{y?1OA$G&|40fLMFTO4N8K&>ZZ4}6Q;N;;=t7bn0omGXZ5zW z{Jtsc>h;X-KY;J!Wj80|@?V!=p?H>>NVWi$g$>R>e#+p+R?z8g`r^W;w5d0{jp?aN znKTa?h2b`5yxu^jj+S~j`~0Y2DrzI?LbbX!Xb+Yh!%CXpA;J^97_8)mUSP$rTgS(xj- zZDu$$^IV@H6=E+~O+g~xk`-F;gNg<9%M6`9{&RO^BMvz}?r&%e)fwqGlUw-+DSUKX z?}A0El*+}1$7<4~`F$&aha%l~M~D^nvwh~Rlj7te!vWT3#9phRILdW~f)aPr zfHOnVtAI`x#;_skbUjswPs0wBBGthAgcf*VAt+8j48r&Hw=?^NUQ~@ZMn@>^uT9nr zZc-+?cqAzLZ%)?@-ZLrQ8wd>kmVQRNxK(jd{7M^!J^TDD_Fv*xK%W3jmy#$+RETrOIht@| zb;IWWZD%Yj)x3#Ma&%Ni#HL4b-a|(_Q_ZXvOa~u4Fmv=@^B#`F;QeIg>B}hAiF59P z)Xl!Z7yl zm{Xjm9{Iw4zWz+=5MKJABylVsa$Dk#dhcC^T{!c^^!~yC(s=dWi>f?@m--38q-do2 zT@3|GpQ9)TZxy#eeKY#7_!_I&4ZGV~GFVWiK)_O_z}G9%>1Skvbo)iFiIA&)HO(h` z&O-PB#oOedcQ^e0S~2P{MxTY-V(hZ({r82&uKQ1!5>rRS1Gn;XdmV3%nYXNa9Hd!X zS>IU7*EozYM`E`c?gr9k%<>3UIsOVbs1Wzw@A6KJ+a(e|qiI-PyMHfo$bM)?RXrcO zV&|kLG2V7A(YF+|tva~)9#e~;wbQCP*t`l7X}NjQ+M0a6kxTgX$to26?M>jJs>y7d zoz_A2ZvBwxRoj%vr-cO+-h%_U=O{8yRtjrZ9aEA71 z(#YTkh$8vMiS_e$Uj(o_d!5mtOw_X!di$}X=sY7|Y$P8JcmG%oms=n;aB^J6M3#ha zbStQM9jY&Z#98CYdCy()TKMPs1nC{V_2)}8OHBC6@@ZaavHqi%jO zcFkZ;VpFcczAkm2_bapOch@BIFK4+_@@raJvP-26pgDn>FA@qo(^SdRs-CxQzMk@?0DHDrpe47Y2?hWiZ z>T~libla|ZFCdjOcsOkfr*DXy9XC_LM8TEzWT~D@{e)pUc4g(tEIQ3zl+YL*S)Xj% zH9AMVVls(%C=t+!E+TyTZHi<~@0Mn% zW-F663=Cm8XSF+M6%zN9_Ym+2VM#t|v28rkb~5XVx8JIQZavy3_8kl*iI1O4XNf(b zeGNn}UQdH{0=~2v74LPbm4)*vR}%XmTzQ`zE~U4ADlX^`2_jtKGqE|Ci8}vfseKDnYEteEANM65||MsGnw`2FR%Mvp+Uf(7?hy#XKBTT8UJNHFw zj%G811wq4QKIdsXMgCV$$a>;5aWlNxI`UT@wWrdy=eBSOS{?Q)GKC`5yP^w)lq_3$@$z!}ce6EPG~&~o9d7=tR5>Vf zOSK*RJUF;;UX7nFi{}o08(4|6ptTFHbtd@YhoJPNjaex;l}wN{UX9Ch4%9-l!?A?*^CNA26Iex`O))ux6UEA zGTI>Q!27S6q$Bcx`>1}YO1vT?B{}4|!eR#xVs03Y3>LyVn}xa_{1ezovudYjUMM3t z+K$tz)DGfFIW7bFv95pv92 z&!QJVWvx_gyVz55?oxM~Q%6L9o8cyrR*EyQCO4>=pc_@mslBy&s9{&LHpmSN9$B!; zSqun7Ei}%}C^_wd=Qlr4;!8a3rMex2!Ex7IrP2d%d~`Qb_b3km&PT6wJZVylp49 zc?0J1^F#Na1P3_CO)d@i80Wi`%l0LDttz)|HsdsE*XmZ+1_I*E<3tyalkzZ|8`7vQ zf$<%Z7<|DZVe1ZAcagoMm?UwYI?ee|JO;`djN(=Vlr6$*-D>1}AdS79VLB2uqTjnK zTM9L{JwR%fyJ$}FXk=KawykC7%3XS9xmAUQtS`SRWMbjH#4#L2s=m%Q{wK_&;Un)Uv#9Wq z>ELo-?(*p5o2e913pbuPhdty#7JzEh)U(c4+pQv07a`5kut95PP&Q!TYqf$+b5ka= zgzx^AbdjeVvo^vR+ZaE|Aqx8*3HI{r-vUy~dyd)I922|7d8RnSiE{<8DDRZWv=()9 zlnQasEleYHS-(Xq+c}IQ?VVUY6K(MuG}~L~)D23Xlq;ONhH;K|)w0tYXVagWq(m#5 zLf83S6DM}d5#$-#o1a}2dsQ)sC*PupO+f7P>aafF&F*%Ye8>k+T$y{nfGe42)-hvo zBrr{QbBbW(YTTEAyv($xqGpp(3%R=vX0o*`u zw<~4b%PsWN{oSHvjlkZ>kNl;wxcjMLf2OsWQrI8=rihSRRR{tMMr3q+q%=#S&g*^` zh{0q%S#OKPq9OtL?wsSSl#(1=baGlKG4U}hW!X7-)SnYxak$heAfd~(#I8TPFXOgMp zVFYaBs|7npz=7yBS$}Vj>Ij3*%=EsgzUEWkpRkv-V3XiN$(F9K6Q4KqY|z3|%dWxEb#)aA91C*PcF)8J zBfm+6L|C2{6-DrYk^OrsI+DZ89s+jz2bxu!GP3{3g`)g{@aej3^6v&Vs9 zHf^NX#bDZvapscgZV9%|F1uwaM@zXtho*#4w>^cpDb@+e$m`pgen70ow+9^rfY1+d zl&XxHxfLdVrb=O{!eqk*?Btuan5SDwyJs=3wN+`U)r64b@2#bWsnQ#}+%Z_Xp}0hs zzO`O4F~~t6Onh+`2H*u9Vk_yFkpYK5nJ5WB`ZJjnMg$q zBGoK8g`$W9bCEX}Q&{em?5=EBCipX*x=)^z5-0#Ct@(YSo?D#?*55c-8c2S5?TbPJ zsrvIPGR*q;m7_8J+a~L~39?c2%MGH6Y7$IW}amH-jj%gL`@vSN+anNd7H~6>*M{haVvv4hvoru&yq_heOz@~6tIh+<){MmBk9V$>6-_^hp#$>R zmG;$?nYUfqM(O;dGEsbHDK4kM;)w>1Fa3aAN^x>bY!+bt|N z_DPUVW|iB-Xf8K2zj`AEzcaH1q@YMi^Ql z15q!kENLf$WU0d(0gNL-X4xrcwZRWXx5Z^)?~^DS_F45{B5MMkPnKb5M?J;JQKB7J zNFEoN#Px+}vYC zLhkI7*o$urx7NrubgiSuuAJks-x?f`#yMh~JF?$%a%I3L9B@I-sl>%nu7&RGpXse> z0qc!z?jH(Ig86C?94$D;^Zi{vlNu@F`2vPK*a9opkVcJX?Yl?qaQgHs)U-6Vr|7@>mv!jdMB}G-Xz*$kuUh~ z?GghTVEl-?bGdZ75)ZDz($8J2OxW1o^T~b(J9Pc|GtY|2ie#<5z3Fu5 zTK&eqBgmE565v$h5Kqlq*J$QDeU^a8YnGOF9Ay$;ejNLc7a+RcoNDojVOnv_+zdXt zzV}ry<=%K%Hp9hylB?Z zrb)Xh?kS7?Cmc-g`iP-06_5O0z->&K$V=U%KH{%TNM6;lY{i3-Z@8VvuR6gVL|`H zNG})(y1M+H2J7})R*~owG2B0I6|;k6b=lJwwJDVOq7?0>9PVmR#+`g+ObIGu#aN&) z?UUqu0h=a;Y6V^CMmjtAJdU5r;RI(m%vZj}>+vW!-%^?mX2 z&oq2f{LK!kb6af~vCCp9-|XCE`F!AnBRKf<_0my6=tsNoT31XfN29BC9@#J5mcz_< z0^!nVD(CrDc4lcWf4VJwE$bTzTQ&5Y6F1&IuEa6!Vm&o1`-Z#SsX!AKDDKk{p_J~W zxS?t%`9!?us~3;*-P%f=)BN)$+7=-)o4t|tj3P>u`|=5oT!WLd{R&JcjE`wmECHP<5k-_HGCb{!cLnO;|(4%nd}G8s$F>o zW!Xn02q7wMB}+j!Srdzk2JW8)qYdg%b!L=;W{vz;-%M*UZ_9{3Y=B6u9>qTieqHFK zMe_;Iv4xT1*phh!Q<-$@)a&w?>cv2J-;LWPE2J|=!wek1vnjK6fB27Va&d|ZRDEfy4hXZM9!de~GMZoO2Rf!22g4sZ)|4_= z^)rul&}>W&L)N}Ap0ef72ep4Ra3R3VYWxQ~b>zR?n>n`czJYX|IC1bTXY<`G`*~pe zeo^#8iRb3hGs6Xaa=yrSDIRj;bmcR;!D-CV-ji(}L*!y94(q5m+=%;ZtRaj+sczn# z?RJkj0d0`l=$YDdk|A_p?$%^GPa`8V?bV9kSytpQBYZ6IOd#=k%KbhfocGVKUsV)s1q^$Ip(+V7sH>M) zAsZ`*tji{KnASF=%+yxoE1p4wKIxZVp& zTr;pU#e3C_SLS=i{+z0Ksi%P(<_p)|=d>A0hT7(v#UY<{^_HEBUUi~F_N!T&S0i5X zG*UgTs5Y@(!!a2vCTuLYZ6Y+u7ILh)(eKO?&P~Ve8B=p(cL38(O5uGnT{#$ZG8jQ& zsg-|&ocs5Fuo*s-8%kM7bBSXiraA(lHHo~1iMi?E@j=O4(~DLO+v3}lyT!uKh{Q|Lv5*y8*& zP=$eN2Ev}l$q>^UIoxJA9Q;=*YIgOGmH5ti(l06*Rf?&7|ACX^NaTLqgveQ_& z8I&*luXsE%8o<2{)|(n32G+5-=}wH^<*lsoYbD1YeKDVOhiYRY6kKceDdh_ zjm$UmmdAs=#Y}>ZHhpG>=#Jytj@Oeg64HAQxib2WWq{|H6KhH0PL0oaATX?p0(8YO zNP(FV2u>v^Uh2E&=8!A(K?F)&~4&oq-|;P~TEuc=tUgUa+q;0lx>8ou#1@ zI#E*`c~pEuV}$Uul1<;-AyN;ZoJxso(NpiTNUi5G{e* zWXRG7PU!-$Rz)#BFiPA;ZxK=U-V_J7)qH;y1_Hg~5_bRSE;j80l@ym;*eBujj$j#)TDo?c%UWWgz<;{`15ZsQHFx zLVKScM02()qzAYi{1#`7uu(G0YO)A%F62b#bJ^DmT!mh^HHX^%h8XFMQfX9$>B>l1 zkr~4knYG5YJu>+=&r{vB%{K)%j0SceIaSH*yHTFWlkbk@RIfGrb?VhA{Rs2CnH~PU zAU@k^Hxs8>ir139tn+v{&Q6c6uCUU-IKQ_(6HN=b<1($LXOqd@xcmL`MkAlM7-*o@ z-irun?=w>q;~1Q$yrdM$k_;Ebd_t@`K%aNz#*2W$?fmKLJe|kJUBGq{tc2bK1J=Fc zfl8a)fK0gcJmxEX zWdi+%8BQ+V*QI2UI43Bl(1fF&?UJp)^Zm`;KwuTg?|A_@OA};}YNhpF^RsgMWi4ay zCD1PJB*tK!h4CvCQ`r`@vs^1qY>Gj^Oa0EH^}S}^wV5>bv~{#RU2W7ex~Q-=H5_51 z9syPEC-AuWb3flO;$9xL0cXEtO*qld)5SmZH5=0nfO{iRnjGCVWo0su*LyTO*U979fsel}8ND3)Ci}ecVXhc_MgUsY?78D6rnVxC;EDL7 zvX8_E7NAJv1!6+wej|p&;9R0E&hmHu*V4XX{Ng1M`_o4-u>UKjUI_}%h_rnbSlX}S zCqMqoptTpNP`D^tY8l)jx& zA6s45ZTVjq5%eUqYi}cLk9*QSbNyzP%55YVS!#DPHUO8j-7oh9B^8ltyOB&$baTR@a_|wD*wG4k8k(e zy<-tv4JPhhGSTNqVUwuymtjyNCO3{c;1KoH8`UaBc_>u?B5E|x14KpD+xlc6JjXqEPN@D;$s8|hCQ|;Yf?%e+l4y>Zv;~!R zz}^fIg}aOXIVS~W?YcT1%52 zNU>hG&!};g&D>Ee*=zK>qWT!CODF2-c1S_UvcdTtC?KKWv%Rm;W~6Z(V`zq@QR;*9 zT}s;OfKTXu@r&e_E()IvxrMKIu^CTiyBL``91GZSB?=I2pV6{whHRS=?%{#{SUvco zr`)lZSW*4WomhO3mMP!&rfn(NnH@ql1#7rm(A}@0++}>hUqyRJWx5eX<_h!*aRr!K zVaR{*iQ;XB`NO#=3>bWldf3Bn8=fxU6Y_O3M9!mqyfj|b-3~hXQvU0oaFx%_>{ADO zxt|VZ&cD6FQ7R-^p9X~!t`PSZ$F~JYrDxqbUH`nNr16rAjI{YHNu8vXmN2OT9VLiR z!`R-vUTAlUX?YWv}kW#Iz;ITdomB9w^6Kg-dluL?07>BjPtB zX_J!0{wk{ufQRUmpNg(3x1f0zx#I+0Gt_KQXuSUnXQiCxYCZH}xAny_Re#fBYQEhJZVmu{0a1^rkmX#^eq3et5hwt_d_r@jbU>lP5?6~^{ z0g9PDYf98s?8t`IX(DQnDq{RLT3#G%U zjsW#1HAJlK_;a@fyQS-5j#|jr#QT$n{XVysG^p6WBOA|%@g9OylLFj#pT)u-0??TN0)3SHTPzMY!R`a_JXImZzm(`M)ql}0<8A&*CFI@hnZL^u z^zQM0@>wrZ{fqF}EJS1b-^9+}?K(QP_p#3M`96Q?aPpR!q5nI_p4%7{@{Mp5kKUZu zmO~l{rD7@-{Y;=fR-=~$%?xeL4#xY)_Es&a2TsG)p%cp`Ww3IWEiX_=p>e%mSzpQ@ z&ci>dZ8YK_`2zs+)9Ai=_CsaK2bGC%o++!p2z33QZGeyZL^D+!LC@R)61@q?e0+|_q9NlN;IX>__AQ9w=|sm1UsP*czUCu> zg{jwQ(Pkh;d4cTHk-V(eC!=yhod>;!%kH%(v5B#5?_8;JLnx8;7EAG;v$9_F2hYxD z&|n&f3fv;qSuPF)nwTGA1nJlX{IOY`sxH}I8SN&Xw${L=YEyXl)_Lafa<6nQDm2A| z#5|{7?CYSJFuYwCzdTHu*cD*^IOo(-){(wfg>IxXR$Ii6-465;Z&4qoC|wc@VrX` zhm%W%MXx~sqlMhmdcqp+x14JeXSfq%Ix|YU?9sR9eEe+NoXk z9j9lfJAA!iXe8rSJ*U4?MsE2Vxf^YL+qHNy>-IRW&qs&M`1**^bl1$L*CSHMa>qTkGuUdCoj(kvb#{IA3Iw@+ z=4LPAzZERdWPXObJ%P#!o~B4W^-yjTlensVO6WrcE8{Kt5J}JQ66ej-DBPZ`-)sU* zunD)99xV3w>{Loh>vZ{p1>eZSvOph?Q3a+g{W`fLVgfV16UjV{x9;?xTh71*73a5u z8@#*^S8u8vFyHMBn^)=eobW&%$*%f39_tgnY*fpm%{sF<)Yp&DLSR_9@}%w2AD*)p zuKm?wEm8nq_=1V3;V0}}C3|23rM@sb!;GBY-U-~>D|3M#yr*rI5M#I>RbHxFx6`pf z>Jn^+K1O;;&i+)upSE3ZqJn3yAIj9amW2hE%)KfmVPR=P-v~b$+<=&8oob? zn;qMS9?%TXWxLhQACwy+eV(Tl2_hUe)l zym@1TD3`PL=ZSp!Vn<`(WrfAc~M>dc%> z^cuL`53&Ax$+utObq%}6?ih40Bg^OcPMb&26voP({tnavrl-p>i1-)v%NFG9jb}S1 zwT?@&jeC=Kw&D}x+pQ+m12|^0KKo72qKVrF`q!?4y4V57sewsUzG#Pm4WQ)(07CnN zOvLJfdRyq8W*L6@vy+tXGw)aB7*RGZ@6R>s?SeAjR2aDu4(h+7l^?SWApfkcR0b@D z6dQR)rL~t)!6hJ*-U74nofOCMMw9^~+_1u;! z(!7y*MD%*2U(wWlrUEd5lRY^ZW>&mL#mT>rtNDRXo$!Yin0-QKaE|pkho&g@_6v!L zZjXW~%=I-`mnKIJ_U~n6At4;Ev;sD{&{^cLCFI#vu2FUt?Cc zp;#*XUKDls*q1E|sQ$>3AV$Cisp>2jI-gya66m-mbu{+0O)F3=t(c0qo=N95*6baP z!wZlo&VDU_Iay_6@;MM{>cHuh+G+&WDxgUydE2H~3j)mo_8Fefz1p*y1gM(a#%xmONuCRIpK#_; z7&6QpMRW%xCzf+KFy;^w z@s@XE!Z9t|vf6OO-B3@~d4D9h_?yYz1YDq_ed%{p-$xPMkq z&)fRDT+U;J>`y>n$e>xsWVYNXIW-o&->M_WsJelhNfbOsNPR6XHb>+!SJl|`9=z?G zV9YE$*D7X4T(=pzeG5C!C!?1fQ11u*9{F^TsQJfK-1;H3fm14*zI$-+5$w^rcF_6R zn*S3J!#d-f_OD6uC*2>*_cc&`_by2_^-K8J~uP=vVUl z1R^aoQ@6v(Ug0GI``@)*gQOPjln0G2$12RU7bD$J$+?(&!KiRt&T777`BqTy{L0yC zl7m6@q0eLIk)6W%LBn;PW?t9tO}`=cR$s_@%K!Y@QWK-!mqG$M4hty=(adNZP~$M7 zKM%xqLj}c#(jHZpwmy1PXy=g{U=&G#>^t*`j%h;9AzQeLlfFuGiHzQiO~WDhp~ zN*~V~gtn<0jPF7iwQXyf+9`4YQaq%n$NF!3Sm{w&Q+i~&_KT|JQlp#z4@=kf83V@F zhe)*QfAxXY?RVZU@ieJg{}&xOS$NSh%aza@AbUP zO_Q5(Z?%4W*0kb~t#rh}y`ILE6A#-AJqPFtUsw&9wUq@Zw?37xz0pfdGMv^m{0jO}rms3fl6Gz{71=zs0yhA|*=n1z~)RSt&v5l{5 z3I{}=)+p{jG^c^2r+s6ekCl1eegHmWd>+3Bo!3rg z5a$WHUB>ZX4XFn~r+EfE%a-TCCO@9?{Fz?z_{EEz;2> z^G;I7N-hT_29>-W9E{hR5!hr1ca;j3Gu?f8v8*kt!YT%F0R|YXn#v1=E@p z6mKiEq^39&?lW5k(VIQ!bh#Edoh(-*2A~!`s31tpD)2p!jpzLF0oVNlg_cIECGkT$(4uA zLBHUZ+}(*V+!8rqw!q{Z2;ArRk|s1pHgM$W5d(Le=r+%Ven!emSstLlGGbmwz6FyU zEHq7q7QUNJKILreRzdj!=jpqhDHi5<qVoZbA?zB)vF znD)3Wqrk=!dkk%0Muei3`vex_8r$d12s=RXA^0}!Oho)NIVz*^x@F~=crC6P7awEGw2)OLAtRlf#eHhT=)f+8nObicV_G2~#QPE^$+rCt zEYjV>2rIs4&?)_evZ1~0ZN4a}Hy&+Wb9}+jk`3m$)!Jc(9Y2?|9f)Nn)KNO6O48jo z?c1?@H{R8GsXCUiHO=|BhornWy^+tXU)u{lrV&?09Pyyl4x_n4PZ{msdHKqD5X@5P z^T&3y-y%-$jF^Ae7)vt6L<9Q_j^KQK)0_`;Sa`tyT@yz)#aYlD3jVb}yWJ)0UEnT3ku}g5r^=lY?qBEhny+o_( z#h6@rc}h1UZsx_{rgoJpp>6$y;@jF)Ly%1sJLJQ%BYh9>gYeS9zgdh_#$;5&e4eQ0Lg0}%|0*gVg2&6Gz1i4 zZ~5*9kjm?1>Nm}&-r?)tAP3zASggR1{F_}pREZy7ysSAWWaX8P5D2vY!CVC77-ma3 z^gt)DvoknY-s8@!j{(fWs3_#dIGehilKHtAU7pN~r zLn0z5I2LNlFo=oKGRzcu)er03^}6uOC2ohwno2R~^L@*YtN-di)ZzSFN&E53qGC9) z>`36M0ph3Y1w(y*bwrG#>K@@#FjYEOS0-S<@4kk=MDrtUV>p@55&D z9ENxiuSbj}sMNHdpX7Gy1Se=mF-0`y0!=*0=@>nitsRP_H@;$=FsyA&Y7rrvAs_?q-l!!L`v zcF3vyM0|6QTOPDO4SAPitI&8kB=GQqs~+ZgSB_1?Mt!3gz*w9r*gSUQb7zN;tp06P zmY2=!ezdE$I!P_;{K>8E_Q|o+S$g z?-|x;hA{`Yw1*y#u{-N4h}etd1lV@3Fv@fZTELB$;bIIu1T#@*4jAd#T#q1#WX4B~R@bHU7PfOz!Ll z5dC0H+l3i6-?gC4>A-V!u}9dGfG9d@={YI}n5K>P+VZXGN!TpB^-jQfiRB0&aw1y$ti4Yw@n*{3XB`&0DAng)G*I>s$jDmSqHy&Sn)tLR<|ju(zb{95mKR(~ z+x}fLxVzL_RP5;k23Eit%|%gu@J8T)%^-$x>sC6+|5c}Nb>#-pWLPxbeuPyLN(EAqc@Cz_e;%FEa%2OR!CyuD{sQ(Y7` z7)3-u1QkT-SSbQZReBQyq!W4(kY1(tAV{%Lq)H9FgetuVNKv|>2MD3}-UEcd+>7t~ ze&07UYi8D(S#y86OmaE*+;jGR_OthXj(gqqN*~{>VAUOjQco=W5VP+(X`iiO&FTWo z&>TIb5XA45+DOC~&tFN~ctJMxuNEPFK*xxD4ZCPTJ`*rZPsDiNYaJ0G`C!y7prm30 zOeow_kSvZ=aWaIieP9`vMVb62TeWIetxs`WetCbqK>Kq*ug#wyO5;3xwbx$VnEU&B z&zIG`^${k#9JX z#I54WSbdo>gZj42Yi@JDm0!w9#sWXN{CB4B0k%?VBIFjCo3I;VH9KFX&WfS+e1uYD z=X)b}GAvsR8B0y1W~+Ml{5R#jK#P&`)4{_knW{goZJhMQPlY|XfGUJaS?rf8H6@|( z2-@>6I-h?rVi0EDNy2U07s)xxEtI!iZ06tZylf&(=9DJIM=cRGuWmI9ZZ@&=HxiK+ zL<@ow#>T#Y|6^L~|GlnO!X4n|e(fwCZ$m*61rQ}!_GNH$)TO}{R>s7}gFK3DRhXrH z3sDuq0Sz>a{G*)HS?C2ymjD_%?j6Ls4OU)(Xt0p!yb;GjA!h8ps;;Y57&|=wAQ@`Bw^W0rXDhC}kP<9C!$|$+Q zOz~2X0KilTXEd1!iht7n>)`JGDrUbq!`BRwZjbp**97}qVB2+%AVQcS!tq*~^4~%f zsSgZt8Mg*1*=gPx6A$`@G3YxBDR}zoXE7Ow4T6gu0=e;IRVY~umt*2JVNK3PL*+P()$h@ET1NVSgGzq?61csY!n z;v#5d!Apu3ST5it)(R%_!0Vs?BENB-^?^8kHX#Z0d(;JdA|?eUCoalKYB5$luT;L0 z`+w!J|As|3RJhFe2_n2`b(t^y4XUKR0K6Zt_1kU}U--Wdm_kA#WrnLs{KjWSB$xmU z4UB^PhMHMy%_`7-N6K5}zHRKanC$ih@#)hio2A~g;UaxO$sPxrH1fZ5XAx0php{q; z`&7on#As9OFAua$0K5ny+ygB5^)tsp6`y z9JhZ_>1Igx39?f^cSue4T*9yxTwnm$V8rVz5f^#g>md+ zSKox>emLJZVga|af_@RvIY)$2^L9cQZ=Am{zstq)aU6VR-FLd&sxYpJ6_x|P|NV^o z#>4P}cT|Jd_h&|Jt4?eyy+(|JN87*NC;e|Vh`sml7$T~CyQ_JZv(Xj(2!}>^TxL8| zh}T}=$fd(=Ha3RR3y&cr%XBcXGrTKG-%b17yYI=q$IAzCjVHhKd9rHER{Qa_N!~jh zvF!U3HOtwF*D3*&Hq z>h(@X^Kk=SL}EG$K^{EjR|}o~svF^RBLMTqE{_SpaEcHy{k|_cChOr|iWUGUDQTgS4 z^FIm5oa4gi1a*L9vOXuh{+?I1dVR*vJnb^Gps^NUDgCA1Qst`fPhEX>@wcx|JLFh< zjNCspZ>EF1TAw^St;$bgVe2Z`E=pjrwm>EDTI)%gLdVB_u$YYod!JR^jpL(5xEl&_ zz{0}PVNn-wnY0vkx(f$3B|?f2umOau-y_@Zk6-XZtXEC?9t1F){9K7bxKUiXu>onn zBn(dc8N+gmjD`m(Q_tSL;+$!1{+x2Wopi7kM5=WyFp<BXXDUisTF&?(?0X-Gq4+Cwp%L+}z97c;?+{YAyT($*u{)CtEFd*(bl7$nX!!jRB2UeFDUhcD2io zBr&sq)nx>&yjW|3KU7D9F#^t4kT>7Oj#wfE zl)(|B!0*D($}_?QIvo{SYRvv5bqp>+5TWPpD>oKYvRQR#E5v?oTd!rjb1{9X{eF1) zjr-DCMfzUr6@Vy~)dynm-f!1I5H`a0SVuu<`zI;iOlu2iJWw+X-S7mmE!XyecmFuW zJ$ zUTVHB|0@@xbC-+TYuZc_Ps8;#BpG&kmkn8za+X83? z0izC+@U>N6RJS(g>7t~)5n1JQOE3*&kmB5B zlyc4gikG!#*u@xWQ0T!AlXch9*&dHAZJu=pieLidS-B_NC;gZOmQn-O>L&3;Lxa31 zJ<0v+eo22mwM09pmsd2>9OTz<6b%tF1iJe`ZeHcEeF;1r@lI4(@Ft_I-a?3U;OcCZ<^#f zU_rmz@LKk_7S(MCNcv8JZvPx@y{NF*jyvckv9H-$=x4a*)>0lp0|-tzQO$)joE^3e zQ5$DT_Yen1Fo08bj*lW@5Ep6om--wEn;z@g{`zIBXP=^e`2d6RV-^IK{CZ}TVy6`y zbW_jwXnr{TB?*C_9@F_+*SNfgdAz)yAa1>bnVoIS$Nou2YGfw8l&^JLeJd7iDP6c) z+&CfN+U*?@j&M^H#XAE(1tB>^Oe2i0pL2O#&CtCIl%HB{a$39Lv%Xkmu*B-D+Ee@R zz9O}a*dU$9+*j8z%N*140)(60k8No;Qb>*Zd3FUN7Nj2U)I0Tgw#+mT<2+JI(S)SYnIPY4OlMM&Co#j;z*sZA!w8T!WiJx2bAf*7sA z==V?cmSX-@(nZx@WL*6JRuW74j(#@@2JNpe4n3KzC!GeQzZ2LN8U6!_jDVJw&^YNY zL{VZ9y+U<>f4YH?rh$j)m?^~?t-*%{!>!;fB}TE2#6KnB0e^)AvgF;JEJqP)(cO9%r4}zgCu9 z!0l!_ibtf%ntnA#YHQR(IVpnFR?wlr<@C{Vde~GDKO1n>DSuRS=eK>9Dy~eZl)s?9GuPar^tz0Nv%CDId_#E+gZGS`+7@>zQp9!b z2HvK7$;dM2waid#;ird@`T{(BbC36DUd%_Utp!pUgiK~5lFx9BXC_vALcjmPb-9@~ zWv61isZAEcJk?LFF5dM70M&4v0@doUH$Oq7cFCLf`XO|4PlVRYtCX*)%{1`%r6+r6)h9@HJA8d1DCsmF*Hp@T=WeBUk zAf}&61W+cC`!u8$%GCUP)}!5iUjRC_NPJ{g5;L{1EHHs=($y8l=*ZG;&&_#@(d4ow525h#z7qwxq|>Up)(sp=}^V(M0P-81f%b^ z+&co9yAH+(z+bkB|Hy^9J)i-U8ZBx5-_ks6B{g zNf|`OZ5JcuIld!B&&G>t7N`M#hZ?sP_S`Fho#7^dUvkv}(a(Bnz;&)c(f@{;wL%B& znM+(WNU;RUDX&4SE1!NP;!bOhT`RpfbM34Kz*W4O$$@o>nv(kF(1Ui-j z(41TQ9*kaKEB;{&iC_bOonMm9kGFyI`D813qudZifrC+VhD1Kw1ch%;oA9UjP1vN! z>7fa_!KY5&x$ot0t&4Tt?jJ#n55eVY4)4QI*$Om?{Prm%{(LqgQyhlAM_IhKV}lsj z+*cW$s7DGm0OAG)DFD>6&Jn|zfh`0fw-_zWO7>WY-&i!L_pI5^hqa8E1LtLYbT+gJ-S0l_k#F3=?}No(t_z7heW_=lk_fED|Ewx86|qUO;+`z zJ4F}`y~rYT(NB+MEbl#_sP>^?(qib~xEs5^=VX`XSaYzhgZ|dnV$cAZ_IQo5{K!toy%YFE37+vAgQrPg}Qie@i z&%;WmZDW8+)1@9y^%Y!69!P)rIhtGVh^6=Q=g+nP463lPxTBR0xTadO?u0^lwK6gQ zfCJy>(Y_2BjDNx4Z4By%1@c2*V80lh>of)1pN`=Rwq#rz4r*=Biq9(7H4PViD*<6U zwo5RI%`0|~f#yH;xNL#Oy?*(1aC371dETNBnDVO3WZ74r-e*sxi?FA1e=2}%jK==Q zwC70(y>9qE5TA}kK9s)(K}Z0BQmSGPsYJ?mO+{zP?_t8}#egqca(9nFG$yZ9 zrln~K`tH{0w^Vd~yGRF7c0#0h0Jgwpx;c=~{0}XEvd0Jz>`s|A-QQgVvN z)ybtdp3HL&7wYm8_&I~%QBfm!&AM7|Y2$8;V`mY>c-;=CU}^ zT@r*HI}K6F7`#Id9~91#@k4S+1AcQlop(G9h8eXOpK+>&aQhtZ$z2FHYl*y0CouB! zJwaim4Z5;N+3jDTw6FL+lmoHy0$bOjHxh+FnD>lvdF{g))R%hH5&^>*7}{uOtg-5S zv<)YPkSnazWmqE50GM6vw>V~996DKLHN@(*S~&70eDd%&|Js0(XayLXh#XE4xWPRS zo!3VC6yilZ_bjXjbH65X>Boq9ZPeuG!|?mtw)hpzMn}AFnBYdWoUq&JVVme!G>h6e zlGxLCH*vB$O-I=4pj@7#rWL|?7hG=>%24FGczYT5;Ss=kYE~@D>KZ85>ZemCpmWUS+%7pH-w8E|FAWjjGLV*R8TEEC~gScz>WMutCEy z5k+kbu<`4_kclrK?}rN++cz9#<6bNcyW;;NN9qP{;cVDP?Z){`*$;p#0t zh7{|f8i3@X1bxV>44{NFk#D|;xXMM~&D#_6K!LM_(^XKy)y1qNGR0AiNNNKX_C{@_1}Q-;GdC z#}K`3SGSC7DlKFc&i+#WMv9zo{ni;C&OKQrD$Lts;KjyQUg%YVc^f{Bwd~)_8F6Zw z1@sc8Vlj2rj|HsVAY>gy}55fWJT(Gh`>) z!JcY~xcXmK?b?xhiM2_Zeq2go| z1=q{nA!WwDh*1G;O7=ygRZ>HOJaS>@m;vN!mAjg!6}60e->H*#9(L0A`4B5vNkE@Z zJD86j-Pa?Z2~Jpk_6Ikeyp2QRrjav7p+SiXC!5;B#Wv6LJpG&{}E^I6(Go%;4q$MhuYUfRJAW zGF-8rO)u3Nt+ltOdspo>ysyI!_xFp&UUgX?JR=>A zJUgAgb+DK59WTm8v5-q`uIbXB!!iDK@$^6=5WxV+C6l3ZiLS63>IAN}tT><_!w`nS z_yW(Mo1>UKj#LuGm-_%9!ET`-zo@qJV9c76|4SGDtIK}1QUI&l?geV-_M}rn-NxOG zvL?7bN@i1JyPJm|dkRh62xJ%{bw7T@<3sPd0(Bjn_9--k`{-9FSF@B~WCqHv*c{b; zG9skAmL2z|PQ|r`SQ}29(tO2qIBzetN+c(zwRwwDa2-uO;*(knnDR`(Y1e!G=0GfbUH!6 z1<{i%$RCAqsD}-bTmjtA`S3w^onGKor5IzUn@Dc_A@K%PumnY(>{Qy6#oAE|oBAcZ zER=t~-ufo)l>HuiU+#u4W&@GS13Bmyi%GKytodV)Uvt}bl$v(w z*~4F3TDc0RWWQ;giLf@BW4DqZU8Ek2Bcp|bWXBhXQzB`e)=8aMGu?EY*HJ*GU0$Q^hgW7pw|K^j4i*V_`Ip%48K`t3!u<(!WXB{01!Q13S!}BCcmp) z02I2CZ4BG2$Ns}<1JR4vL?U48E3GEtk5!vSz2@auaVpE#-ieD< zEO_tKc<7m+y;`$liG~_wETiyGxr9^vsr01=zD_!~5p2uR_6%nsQa3QoP?^H@G#re! zSfpQlDQkWpk*dmiw#fd+y4&_V<@ikpOLJCljVdZy{PV+OSMQb6&kICa!Pn_*IwBu#xCOqb&4q@p>6s3 zyM`6`F>?}hm<@)uU~$01V(TVHfemB@a*?ZhYoh~zb2)diUUO&J+G$6_{A9&jxKMGw zbO)&zp5qs5xlG^X67Jt(wc@Bh6+xA2HOaew+AG=RXc$O2(|yve@-Q?}ob8Ik;6NLZ zP`aOVBdpk4nw?Mv70R$K0nZ3}uz8m8yQ?8C;y}F2(DE=gK>|*bpf4Ye>&5e{YiTk? zas0AHkHF4$lqiq)KI{uxz}@eg>s#OX=AWf?mcj`{A5jw2qSx3c2?g3{on8l`Z=yzl z^aP;zm=?y7H~baw`_&?1kcg{)A7cB=*H}`qx;7QzPLZoe^?`|c=Rsb!6pE|CUxxBI zu|f0uU_(*L!dU`(!soTQaf;PM5tXCGND;gCn8^kbwIcXZb9Sq*_-q5eP{TU6j1T5? zZ;)-nZC!rm6lhUErbLA^&`wejN*D@m80U9ZlLWP)zKY^&wwgtNT%{fua5HY^bvTLy z3jP92#4p|@(#)wA!si%PvL@B1=~juY%gy?db06j_)>`4ARc~>*ep1*#)KwxrpcX93 zv~U--V<6lSyN{ztxnVPd zA`cwjaREYJ>YD*gq+Uu%$-McH2GjwytMx>6;KU_4Dqq5fyq||P2dyab(`Wa#U^7&< zdO2jTJ(|-xU$L%^M04f?l~n6GMFj_Tr2h=8ucRPcW93eAJ8S}*ACKS z>XG&r!kd%zuJv_7e+D#5f;qPIFfjT3BhLPBO3fSm&vt7tg7|Ilq7MwmGNr-)(gny_ zb z=SfaSgyE(SyWu*funbIs27(MhgxW740PARDusd4l{@P-*Sp;Z!a3*$jizJwc{XSUf zZPka&-3Isw@&BfHsNGz?v1H&+%`Xw%oxphl=*9^ECdjuKv(BHoOaS^nX)}(j{d^B( zhm~zXddpE!{L@8BXwP7kJss@%^z|LZ=i@9JZz^T@feFdI0ph!u!E*n{uZM&_ujWPO zz&3pf_3MT&t7mbrx!-I_-Yw#>o@@e!ZUv?Ym1Q{y=oyJuSf_wo3ItLSc+QTv_&E^O zlmI8pxLt_Q1!n~O!>mAs2C0Ir<`y7erwJO;^P?PqN)<41=P?D|F`mp#$_Uw-c#Uvn z0Y?h)^K3fL833;^1cU*Q)Y$*M6c*AOcE2=kff@$*(+;ej1NZv(GPdy?l;emt%o*iLi!mH%BOs@1 zjRqdt<%1l3YC0Ro^TFW)H0_zbcnHE%>b>H~yMPSskB(#8!kAsv-pD(ZX6(q#+mq!wGgXMt+Ystx5#d+86k!BSL8fuqrQ1i{|56^v|yPtN_s3u9yL~o{c(FUJ|k5sJf;AP ztS9?n`w-hee@W>3qdsCyMbWezjL$AV+a&>=jT9pDnoo&DFkiXAw!H@74dk}VM$Hk8 z>)6%$C$p%z%Er1+^nhkT+aI~R8_Xd)#hNpKe0Iq4QGTQxwtjbwkcD9vSUs)zfyCmH zqLs>bz@RvWhxBx_#OLz`QVA86Eg}`+As)6lOG8Gy+i(GUnG8Mbm)Vc)_dUtjkL<^5 zByL{e^@3UxzE@{U<<{Eb`2O)Wqst$?Zji*CblE19fZreFGlD{fLuff85P zi%pS@2ijGnfs!ecDHoac&#o3{$jg=p2XaokG>4~6y~47+R_&b$)>|K2?1^DDy9v{r znvsliP)bKwh;CfH_@GAcN|0&~*KNCoC!W5ZDV_@D$T2s=BPTs_sb49&d3D00z0U## z$A;&{-)JyXAAb*Q28%OtGiA5tp=H@-x|P(*TM7K3fkL?r<^X5^TmRX!=i(UUWf4N* z+SeZMvN790>gqf}min7QE(D>ZzMftpp~t93|3lAr+DOCksBgRT4m6qhn#!BqdKCgz z(nQtjTLv;{Rnt(3h*p;q6K3_AnP#o6jCmfDSc$LdO(BZ}jQdmX!i6p03MFkLvsh2x z{pjZz=)sx&A$CxIIfrGZJ;|*K-z3cZTq_pg#Fe8DBilxNK&s`C81a^{_g6{?u%Wq7&18W!3ZcF^kY74YZ2FV<`?A6h?6z?ua@@~WH`;{v~Sv@Es zmK+^E$t7%=1O}^8#%YrNVzo}t<@09DBxlt&q{A!_JR_APAyN|AxvN{_Fz8h} zf~n8?^?h^3MzHSYmF(k&q?3!U<_{QiYc{LY*mbMUz{4#rrkyqHOAsI=nL>(_uBw%! z|CC_*!fGX=uVeK&@&kQGka#k@H&Le9D5P>W*yMJ|R%n=ByXb0xZPNp8cEF=AC);MQ{cqfH4 zdD)}cTn}ei54Gi-0I}biJRLdk!jETbIjP7GlM9>hq}7yg|H9yuPtc2$#{2(r>JUh2 ztZX&+!WSd3k`o6dUwA;%?9xYhYrQ2t%KuiIMo{zdX#!<;8Z0=>!_MM8GdbAw)H`OqX7!Gu8b^DZFtd{NpFW!) zMWgN(H{)S@$Cd}2^>$>!yeLJ%22Jl=6jpk_N&-w^iO zOgp75V~3+Ql71YB#4Y^f-S3F3u*)5&Y7>F7w0AgPE@++4 zL7sG5$)$bXl+PS(K53vE&v6opsF@mDyqRr2xn|ba|B#m0qd~Qe6z|D$+ajjdi>O`q zyi%dPGacCgoMcwu;iw{AW(pXrybCpsI^KMRS`KM>eM9aeWIdgHezMYPWjJ~<&oB1j zUY&tJ(*R%)tI%k*A0r z4SmlPUn@64{svZ=_t8NS%R1p{KEtc&ZG+b7I8|N+4awz0^)*7h`u|bO0wg+hT!o~moahwOKEpzO}DY6nR9W`*jqcOu(yNU5I909P1 z9`^#mtVOkviBxt#1aLHgg#2EynoDiBsR6|(pb%J0gJSLhiOr))pFBY8ATWRH#X(2| zU+QGT#=)tNF{)!2WV{K40Lo&bJ+`}~On%<^>4oY!Jcju6`t)#Y1&=*CzF`fKa z=oyn{ZDsfHr8xCfP&wtcPbF8w>$2?7fcdde1Fto+iaeWHv&8KMZ|v@k08j0Abs8F) zdkNj~Rqge+32+Cmj*o#ImU`aS7LqjTbh=)oTeW6O7a;b~=Ct`CAFN3g>$I7InYr*G z+g9TaSZ!S@NwlFkKl|f_^?TbZ%@lVjo=o1?LOKnIA$4s4vO2%yPaE8OqdD9pd?{Ha zL|xz1^gCY8`(*53JEzNb9#OGj9%wL)x+FGz>@1t70IwOjzKj{Yd@$NV+>=m|xV{`m zHMhU(1!!^s8dHxzuS?+fb_wu<%y)=20b&tQKZ)X~dVa;cvoj!3onp%7)%P#M$w2Q4 zhn^+Si$#9Aw#gx~){8Im$C0SKLu*wi=WF!nSKRaqnl9#KFCi)N7;ez18{NTd!ab4n zo;&pg!$&gY2Fph*?U7y#?t-hfgOzOdI9+cz2rdDUv5Ldf?A?tYlpDN#52NPGVtN`N zx%yy)LM%~`ZuS-TLce;phr~bC87jmOOZ2jX`PI!p+BVugbOPT;{ARgKRald4k6wEw zYaC~Qd|DtQ(OO+x9mGNl3@+9O3P*yjFWVixj(JXOHCO${umTzHE^wv9cy-SKg%x_< zRfwzKoRg{OuG?*JxX^htkIN84fYM&oP0R4vsy5+yR#} z>g{TVcSz$R0YMgS+vD=_c>bzhZt>y;ic%JPTj#ji%w8!dH2`;vB>NiN#w3;IHDlxf>9h4FINZ3A zjAOb)9Ov0ofy~xJii#G(!%w%()<~`eGRLd_3Tsa83J_b&f1z31^`R@g(u>|54INKS zKYm{6r+3cOS~g6V1j)1L-R;eh8JqW!G=`1qw73#neej8P9KRX+7qVvq zPAbgli&=8_g?|s*qPZtD5Wl-RHaOW}r29Hc&!8TeTQXf1qv>zr!|JL+`SV?&BJ=30 zXf0p#k3jhuq$GM9X>#iS5ZH}y8owo3+6L!&rBnLipqhJ!9+M^;RlwT!IuXGamAnC? zPf@QG>vP|2dzwDgyu11*zUrRunH|BVYdGa~OA5Wi^(9|n#pflxo3)2+LUYkXo$xk^ zs<1|6SEj(iu$O_;Y7lPc16*mwcYJpWz2OSI9JuU@*T-}UgRr3Im#tc zI@~sWv-u}xcpo=)hDWfCHZ1YsH>!%e>YJ?R;Ba4*L#dRf;c^4-jV1i0IRcP3dz;ty zoy>&do()FF<;uNe3CUb_%bN#Axw1|O#NEP8$$OIyM}e9XF3=~$UI>$;PeVnW^O?nD z&N0vKE8claaO@l|`a6m2wl;8lUW9=pbaClB)Mqc$`k51Bh8J9 zfm3V2$>-UVMJRzQ9$Z%ukh!?lX?dWBz9lG4^1zjnyDjFdNIS*5IwQ)_P$45?`qR`~ z{TLche2z3DlB6h}TGRu(ngUyQI;dB{uQ#2&_ytCwc#$hm?>ppmXQRYu6+%V#!Ud*sP!e0^H90=c>_f?`L zp3gU@cvOQ(dqYEnT~6Am2`NscPPpgS@2bdvHOH30^Z~8bz41l>^`%Ntt;0{(0pxq+ zQbAVx%J@ob-dkKcIw)lyP%CU)E^qr2wk}D&v^)vjWUD_Vo@#E2^c{96^`;jfnxg?7 z=RJiX4q{h|EzpOM-st>rF+o$au(0>qsOF|cBB*5Ii#Nddn+p7*W-T^YJ>DsJGMQpW z(_6LkG|!ob_Q^Z<_=LM`tVYR8|Ln- zSTWUC3x?Ks!Mx7LLPFQXeC7GPWz&Kbt0{jliyaz7TGmm1h}QFUKEW!*6}U`)^89%? z{i2Sts$`%|#1!V^As%R}_pT{zoAIT1#~%Nt+v77GRIs?fGFH5&q3NJOC+Z1<_vfeJ;M=S{}I0y4)N|`oz_;8=C&STo#rFRrxg!TsY>Q4My#!alzItIm> z)i-6R>MI>fNYYeA}&v^e^K zW`et5@0?Vu{~c%&^EZ_%=__Afn-}dsg{BRJwkHJj1x*KcrMs@N!avHRRT}9<^;Ubd zN!C`|_S^=cJ*}B;j2K4n1Q@t^($rGB0R@ z4{A3z)FBhl78u>3G#qV%KOr;dGHYTOD%2O_t@3`QRry}^QPUm272qK2i4|37OPs1o z*~C-mduC>bn0w;iRQ1N27cM{AkLY{nb#yi4aSo}tuk{ABtSh7pQ7?$>w z;YoGG19#dp>O=ehz5`)(uw0uj_lxK`vAa4cMT)2J?I68~gBtZAhz?rSkTLMZwAH2 zUQC=j^9KFDPS707r6V2kgC9B~QBgGahH_TyPnw}ZpS!#k)uHtnM$%55iC3((pvDyu z!|Q-B8BjYdr>mx87Oz?zZL_3WU95~CXTFu!%mls8j`I#(y^!hf4ivp1B~ zurtVBvB2SX-Bgb`yY3hR6m!U=Y$qtrnD+EOZS&i*dS_t+_4)KiJ&3{W7?uWsU;EKl zNf}h{PrEI^RE!w@kon)*AMF#dI+_gjCnFV15G%aM_ne5gb5+y1eHZ&=)?7 z?uyQ4Pa-lccLzK- zKlqd4QcIc9!&w4CQccy|sbLQmyg=U4Gs@~iCiMntQ@C9R+tc!5PjB{|wtb_h;xJj8 zTD^CTiE+WIFSqX&os>MXReJxWX#ZqLPYWvG`#hexyw`-Syw5kuRic;}t$3hktQON| zQ2d%Tmq%R=H+#k|w9h3sF2lfcG$mC$Doobx82Zg8tAB3?hNagpgLevzHt5l>1*e3k zT5CX+T|t|N0rW=LXM zJ1w>__fB{2^v=!>n&*T?jrhw=^S%Dc6I;Y>1gp(9r5JH_^FU?X<>|0ZPKs>uZq4=F zNEs?#M*zHe%~zwy0HDF|&7zl<7IoAZ%bEBo=z=9(Pm*&x3t8>Y*=5=LK=l#`aII`tvk~H)vOoDeXN!t?1)Au8Kch zFt_s>TK9>n=KPMDf8quQrlj7^&O%EfFwE?92dX;#^qQC%*lrH-yK=N!#*L|e*=HUB7Mx z@Wgidckc4}wm5nxm{55;<)re90VC1n+%c&brXfshaeJQPCOsz~$xuQ$(B7oK{7#iU zYOTg%DcbC=8o9P?#!0D? z)Q7ZqKN6~J$`*xUjXUET^7#_nnVDR-n>v?7Vr1cP@Y;P!N!Q?0PhA0qJ{l4XQMr?i_o0($$>(*`Qqsu~ohC)&zzE;XYA;<)j2g{A z8G)E&DsXU-`HcdKf{G zg4C2;WY3o!?c$qWQ-d*ufOJNDn|f2!$dh9L7L*Vipv%U5`~U_5lsyBui=;$Ey|#%2 z9hgEp?=Jw!iE3#e8wgx}ul~02-!tyirTH(lc`hp+67t`~_>E8h*9QS`Ei>os4ZyGe zC-&oShwQ66KvV2LLj~(3!7JqXIW+_P>z~d}U`+pynmzyboD10123|MLOVS}yQh?6i zh9^e))7E=E?W%Xd7XnlNVP4V*baa5WTY!CG1v(^q45~-{m@|NUIH(lc@TpC6AJTrk zjhvYD{ElLm{uf;|+qJ4O4J~P`QoOdtbfs=vdDV1)F0|TqjZ+hfF!%<@qQxKrgW?KG z=JP8xtJ$^HbS6uN2VBeROHA{t&>>gZSc_0)H3|&{lE3g*4n$9cOr=WB9yaY>8MyW; z3Q*u8x%qD+FNz?9^`9w#-niUb4wPO(Ace!JG?DP@KYH4 z8FQ`D)8#J0FAI(*Ik6(J%6fV^(r_$+NKnBhhjjK%x`^e*X+c?Iu*>k8&mR$UGd~~q z#!M5lKchg2_OOAM*D$uAg3m9~OHtTwR3BJYEYFK{V4UiybNlM93V|9`V02XGKiU!US9&j#=Vb&Y$Xu$9_LXNLNj z`vH|l+B-*$578a1?;2;%@V^?pr~ahis%mk+jzym@{&`UR!{-z)dfJlgiK7~_6*=e& zuU68>C2qL+;#g4|r_-%SjA+t{hw8+nqrTc>iiu6Q@2NZro1u2Pc;p0|yueKMcdmj$ z{aImda}0Q-iO4fk<)`y9u(L2+pOWti>{J4klMgUhi#`lrzB)D1FJ_-ikh+9BZJ^Fp zuAivvd{ais~MZ8{zOmGEItZr6mSwGdW#d*J6|aU^6~hc z(UThj2@6^4yVBbhdw-Ul%avkhMLpWi1U>iKFiF~K`J2`PBQm1LfTQpiBEDC#%ACRi zr&~0Ha4>v1UrtZcdB&vgTV<*^EM_nidK2l}Q-p_30LNogPHvtI#{`Jry609;)H&*P z;y=yhJbl-`iPizt-qGz^|ZfF_nV`inw zqVS8a6ArSt0^5}7u?#0)VVjLTr`|oDV!QT7_?2iDLM`C6*YR3*et6K6C!0{2d{Jl2 zFxo(9r9JF1zt418(JZ2G=w&SBT)(H}_5o|$pHMo@w*KgvKKS9cu8b2zgHrwO=h`FE z)gl!-$Q_Y?rs3Y7%kPPV>k-x~tr9rQx63Z2(%U0TbPA27ye`I`>9H0F)LGe?LZedt zeHot4MXIwCK<2rjDst-gQJx|32D4V0&<1SwFxA^iRF|ZEm;iAk)Pc;$g&*_m$M+A) zD?UELoc#_*cnn9CsNc@YD{Z9^`rh}7c;m1%=kr52ZoiRKVB`G*+Zfq4=nH4P`r;oa zCXpIu!kI@EZ=%CYKI^m{g|3QObD9oa@SFa1<$R0ZZB1)Ru+i-6#Z&&$Uo059f>Tnm#MBJl*bsxWPc8M6?F-)?FlU!qU-}|_-4esdo>1`EWck?w zJlZcLN^;vw1VMbeZnlOlBgHfkPAz)n=hpOqI{ADhQrFzB^564XFGj^ z5yPQ0xQ0Wdp zUUh8P{E;F2=yV^I0>2(xVNn(%ymu;k)_Ioy^@a9(M1GVb`eHx6QGkD`-XUQ)uUt`G zGgSI_(z2)~wmOpXK`DN1(`_gkN;|-#Xwa zy!Rv`gV%s(C~s*g`3bQf^9Z+Kvc%hPV@^5ouTS^{aw8XDZ`b(Uq1Ot-XGQDo!G3)S z&r%z0=BdanKN&zGiPU|+URI|LonY}CFK|3KTd~VN45)3KoVGqgP0P1#!V=5+=>`gAe}{aeYklt-|Lb~fO4&+7qIv38$( ztN3FQB6GsmPktI-h^n1UROPzCJ3i-BX&gVy4es7C1* z*we<7&c>C{>ldGv{`HmBjHhpoa|YTzpXI=2RBuqf<9_FD`p&>BK||PxTKjoX1Xh{hd?Md7<|tKLf?xDFLhblQ3=S z^YGX2meRzP6jv3!(^lQ|xhYa)+$w_tiP)pLN59!-N)cEVII4RqF{JTrnw^vS+PebX6Gw0*jL;+qQCg z2EH+(UB%M!_!&5C9;+sj{n(PA+WoKfp7QVW?>b<%3%%3fS$?R@62T+rZWVj+wkON; zv>Q?h2fVm!7KN-lNN~T}n^sYT5b1`6R1Yi>GrDzE!^5L|>dU;6FCZjMyZ78tP21kw zX5WpbPc8bQZs+EaOeH*@UbBfIrp&;1JOM9;A|5605-W zx2H6#`!Yl|+>`GV29}+LG91AdCwFinen!i@i5h)EuFhW?-mH!s1|}f!)&r(BT1SM+ z44U_V8~9abO-XXAedBQUydPtBgIKGAYh}TBo=VK;HJIK7uKx)(wNZc#@sRe^wv^Rn zWr*_SC#9gc9SD{FPrm*CDadjQltc^eHod4aS@1~h#s8shYkNIW_hz3 zm8!yKc|NUv$L^mrXsmb~%?}ik?S7RKx>RWcI`JaTR9sBW9=_%VQckdyE1pb~i zXyWiUn2sz;onHOuro2KrFw#g72fB6wtNHB0rvZ1R(Dv-aQ;a(A_eTkh%gZN^?A6#3 z&tjR5d4D6sU17WWgr<>}mrQ9HDnnOB8mH1v0nIMwI!0_-^VM?lsVf~8k25XN3?>6_ zum;xpKpfG!t)M3dFwaWIn$dhB!aFZ|Lfd&!=(=bLXQPBjg*Js9ZMcweb|dfkhp2l2 ze)ON=C(_2KY5P)1+7Wse=gIK|VGr0>@!PRFF4_fBKWr{CBP4t0<2Tl8x>%N}k}q1F~M1FrL0>4-}63z(5VReBEK{efsXFfAK_5V43X@s1}@VhA9 z5P?_byNbdhDxpu<{dW^%d-FQ-j;n_V{5d4^{RtVC=@iMeBPZ>94TPNpP}e;Y){ag9 zN!5!QjC+Dll=U6VKh-G*G(w158?dUlp=!KB@ePfLr|L4HJ(=mg${hz31SO{sY70WD z4>y$~T*3&y-c61EXto?p-wx0^lb`dw)kcL-X%i=w9K?gQ#tco9kJ(oRms9n27ld*= z?CL74dM-w5>d!V`Q7TuIBYoq( zpCEosaFrT;p$f0>k(znHt})n#0hMshSnA+yN7CEL@<2_#8TPu;grRo4F&tnQ0H^x& z9u2Ur#I5MgV!^_B$m4w=p^d&=f18)QDqoFIF!^& zpQ3L`I&KKLPZig)nsIbdTI~_aLMiWizlGV|R#6@e61EDk?Ze))NG$5Fa<_50~8dcL>e2 z_61*+2Z6L`+(BykA9^&>c=RBHHf0{MJOGy-mmDvM48{=o%I|}+M_B|Up>*y zLwx=|>M8FoF9FM2xkw%ec%4SrLdgBv4arCd!5qbvb$EZr=bWWp};hCLP&(Q?z+I3#D!#2-7KG#j`-o@j$V2As3 zK&R&1Vq2e;IFE`F!eDn|sLw8_F~-Q%V)49VwchR%JQ_8mE?{@D6}`d2nI;7}@yHXz z2m5+fyA6B2t(NJB_Q>%XdHwnMYKiQ=fS)Wdd?K4gxAH&k9rtM{IoYn=A#wlfWDf^h z`xYPX0mmR^TH+$Usp^MOld)@gcd! zbf?|ruA5=!0DCk2lP>VQx`PkxF|iA&$jK~B^>X0}6YxAa^+Pbm+DX(P%2B9T zNyT=2r|ZcsGk(($lRjWDj#6~;G8#ahHgIA5)pvd%aWRRhWivWfX5E+ut9h2>Uh1Y$L-b&F->nrU-$P8Aoa#p6)k5+@KW>?C?={IjRBg{Sb9Hq!j`9 zx2Kx1GX$EYl$1^sO3Un+Db?bG$6D7wMs|7a#%oPKAajlu8$VkJxg5O{G;!xMRDKvE zRfggOc!D7C8Oa%g-Pxm5?LUEys~Om8_r2G67k)bYwH*aVgfCM5L*~X$=mL9@$hRO8 z?)H)~`!}Cbz5XH0cAzqG-D8yfTs`S>qwfO2znVFSy5W#*M`Lq(;GR!B>bzdeFFHC@ zcu?<|T2U>J9oiZDe-VvRsFc6X6wivsUpPCix_JWM*F*nx<)dm_{PscG%2-p3Q&3gU z*L>RTtu1jj&;$Lrr1f;}z6*16Xe_e@#lOH*`V|wW^ew3M9e)@EmXcv zz#cMV={Gk25`EB%BXga(#&OgxXb1Y{efqqiAr^SuANI-L^$JFB;6319nekXxPwq}! zsN8N5!D?Qv_GaPefn-y=2@?3%jUst=nb?#a$G*O5xlG3PX?>ZPgN&sd>%>euI$_^d z8Gq=yScitSb<@v=EpxmEqFE4K9I71GU9WYNVbUH)v6Q3CQYC({j!&!lC6V~8G27)k zf%NlxM|Nkcpt=LIfrvHyN$YAp%6J*HePB#&+TJZz!{<(HoOhp6MOok7jD83mF}z-@ z^uG+>Un{+3@CW1Hra6!_=+62wUfD(zMd7 zj_6ZKDKtK6HCk?8-Nlk`{yJkvdp)DW%Imq$luavaD>n84<(fAPs0d-)DMjF7EzF#u zB_%v!_zzvBS;W8$Ei`yDgv%JVT3}Hwe}&_=i6Ej(8Z>=)8Y9!mch5$R0$4flR=o_VQ|Wl-7a7oZnxwQxEPOJIuLH z0cS0)-Vu#}X0@3Mw&gBAF3(TW@c;H9N}bpD%ZnEa8`ohsbD6US)D4?)_j4hUz==69 z?~l3?$kfbgn62Rn9_%AaC)_mvZFwEj5#5G+((TEE1}|5V_X!Dnlo2{(_Q@dR=s@wl z;_R~R2nUNG-e($V`}BS9ST`OFl;AC!9q~3yfTLIX5aq2(0v)gR&`39{n8@((iytcjC&xi^v){4t zaQFo35lHBLj`^{B5}|~|bL7O=0b4=_Qb_^!5J+m7(H;$60k19*o)IO`-79f{vWk0( zh8p9+xtPNyVeeg59T@t>Thh#u*oy`go`Czdz0F%v07n;7*|Lvl6)4J9rM7uWa~eqONr7&71Np zy-+;6i0MRWo_={Eqgh~oru@NUCh7eL-<8Q&=_NkU6)CEcf_2r0*xP3tL}c<9csL`V zP44JcK0XuLN8UYdO?M>BlB0DSJvBw{NyzCJKEK@<-LUlglNArDnx(?~C ziM-uom7yzW(W|>bDiTHT@qn#dC_znhZJQ?AO1T$u4Jr4lS`xuuSR-|Dw+O=Dc&KXa z81B%#N4q(vSLrh4Qels>o4kf8hk9m=@XrMP{&Fx|<+_J8`skgCwQz7m1eJxNkqp9K;u6DZ`=Hoe)WzGeQQBNYh403q2=}cSc&onuL7fxv2iihHNehpJHD<$a`i%gOiPCU8-Go7#wUtW^I?eyd z6CuPC@EIcC902@;& z@ZpnzsoOk!U}*UzSv;l5I?5?h zW!h6vgIJvg4Z)uSPd|S`zzfdBRVvDSc=Q4kXU0qJ=&Mm|F-goo$=P3RP3}8* z<*vhN=6est;PUzeZqL8*GY~h{Iw3HwwzU?v{gfO>@{=K8bU*z%m}tH7m`|>~y-(nr zg0-)yhxa8eOR1w8Q-3{q^019_48vB1g&7N}f(Q|fn|fj-j@*;NI_>=Yr-E0zOfvyz z*F~(omqDB>N)9}I;2$u(t8TF3`?Jjc)zg}=BD>+3aX|YFJX6aF%D{LAH6x>u_RC3; zo5e1ad@*C~kma53?+zCt4 zpxfyndQ3Ct#MR5u>XqOAS@m60cb?BEJ~sVzA?H7^4M^YqeE^Wc|BV^`A1<$YhIweI z%>>Sc6Xzo*KQh!KJ_FTKP44!WC30PPagx*e=2^cVdG-IzR`Nj6i&wWP!%fVJ2F{qV z!G{^&(RqQnkiXks_W^JT+*?8cmOk(56R}x{jd#@7P;n z-|-kv3@p;I7{ac zxZ=T+AGsSVmQwXJMAB$Mci|PEj4FDwn3Mn3mdEJ3DL#>%?elJzsc^q|UeGB1$C0n) zV3&Z=6?cKLX7ig~-2g&K?KD+$WDn9Z@r&2A-TdqJUh8Cz{)^2yEK_brE|hLWRb$9) zd(f*i!zZG(&n9s4Yg4i%pVRRKD)?J^MT)w?X^tm_uwg~3`x^3#V&IPC~IQfu0y1SaLnD1jl z9!kw=gHKD(RyN)|=LoiCx%j_&bY0+Ze9z45LXB6gh!46m8u(h(fEK8*i^ys=UC&Fw z4id{5ipOy{O%Y?sjd;J?J}CVw0&!+m8ynn{fD-vMkoCOZ{?*NRGY1&7<@Pxw;rf;b z?0|XXn;GNQKJg79f^%||p5Z{tH>Y_ZuTu=ZBJnXf#k7fR^gt%QzleO^XEmgna#%0B zx?hy8au+XW5uG6IgIax;S~&#C94b$*vA^&CZn8M2ib}T1Zlr0n*=@@&Y2BrKD;SJ; zmyNwZQMN4qO>lQ;Qt_>EvwqSpt#&dEtq2Wx@(IWMb%@KFHslT~Y#j72s z`i<EI9P$OBExNW zH(fUN$=>o8fwp-O=}fkN7t#D<5XY4$b7|Wa$X|C7l9r&YWHBx_x+ez7Szi+?HwXYw zTd#~1?JNcGz1vs7C;!=~9+q+Frb0kgG%n-`3zq?2ZQq(9LX+Rg=|ML5ScXJCuJ&&?daGyH zgflx5vkFn2Qoqtv7Xjt}%_?Oi44 zvPOo8JsYI@Q1dnTHuNm|6w+VRv^8om1IM{ds+@fGZRV1eI|=qF>ZJ97Di8lD4{)Z< z!c2d$9;jtWv&dZQ(XgLsXvE}-msPtp@?mq_umdX05y%QWUl}_;(bH)wGuKcFMN9F@ znuypO8sqkyL-J4wLct#5PP-Go~<2wlAlnpZODW#M=Ho4|zU9c|6SMqIL$_WXI zXDwjw!d-5Vf(Cqi7P%|H%Ifaf$EPeTYQlI%2T``SNX!=hS^QIO_U4Y zL9FfAyta*pJGlS%A@$uWf?9NS^U#csxIU}vFqG*2^8(VAPSF(U`JIqhx@GG|JcgPD zDM^m(L^ku-Y?q0J>z(gHrkL}+^3JR{nde$0fqwqd_{YGW+~0!@hW7FG13z%GF}Q)H zi3hQuFNUQaOA6b;!?>~4SfIjED$(XHrSmoWbpTL|@zHxnJF}iYz{8ra@8?sm@|NJe z^@SBiZrZT)4!RF{1X+J@?Uuo%Eid zvLtpD+Y&}6*eCC+z9czsJ} z2fkl|k`p%N*mhUq5*KH#9QuObFAsu_-QVt!Vx_0eEY>+8QsyB?Jk@!$R%UGpe)2GN zq_wHHu=NZf6=H;9+(A4`xgFAf?Y^n^-rvfP)?>@!^!UzER!3u)F3Amua=U`F@QKPkb%KY(&31V^4KkN|ha&epmvgJn92f$j zXz(Z652ETSCe?N$qcny?eY zyuQO*&fS35-bSPiGv?crOyfzL+5mUz!I#51n9XnK?Yae@Z)pqSe_I*;{F_zWwilye zM~^rLxtfm7J1o6y2^nB={;0Z?g+vY^H5pWwKxVZvlgggb+vETtp##iRTh1RJvC)^I z)Pi3jX278DpSTo2!Bxnu@<_ZC=NB{e0P%%nya=q5TfSNiuihN%h-jJ9b}*3I zfDMqwGQd`NP+$|NVsm)OHC4OQ-+6mt>-6OiM4@j`7ybi?9@Prb6Q+!)rK(p3M-~-B6arcI)UFh?`_OqA z?n5>fD-gz~G=^5W&TVh!W^BfggZ?%nJbZ*%9qB$;Q(NA;~ib`xPnALAD_UQ_59 zKay-rnodvKO)#YW^mOO7wAN=<*nX@CznN>@LE&X}qp#Y#2r)F+ya$a@0GkN^7Sg|F z=XQwcmg-K@l(-xaK5wU9Q8U4fx78{W{WbHnp@Lm8IkdEbt6uS+37wBVy#umdekCVz zSx%_00szgoh3#MgRL#gjuKV^a`^vJlYt=$SIW*VbAWgO%6{4zcY-HKJCPiJPXFe_% zBHs9csSD6io=^FKpF6;BU5JJhQ1=H>K`6FD6Gp01Vq<@h-qpM>BpsUiTB>Q#)?^U- zxOi-;mXl~)0HOPPR-SxhN2K-kT;(^0%G@)?NO{I4i_<5=BvjIH0C|o0o_{t&rFhy_ zXcQItmW(vp_}sTkh*kw)jN6$|SQ5s6T@D2SIhB5{bp`c9)!767O{_ESeS;t80-p4n z-Z(r2;VVc|9=(*k|GK(;m?6~Fa)1rD!6CG2*Up5>_I9|v6i*Prd&G$ZKVhBGwzw(r z!CP1Rj*t0h>Y(fQZoM&qW({i(6~(W=ZoC_ajW0c}&l%8joH0klfWOjdU4Oz~LH#72 zL5yk%xww`uJ`xp z*P<{c9`6O;%Q$Ju&=<0Y3=30{+Or*RJ;u)H;O`ORP%i(`sSn&o_Xtz;AJCt!N z|2G#vg)hB$-XYHPQB_%Ztem$wA4WTb1x}B17b7H!bTe=sms*d&Ie@e1h=ZkZddLX%!hVc(zIE5WDOi znq>FE8z`&4UbAUn`c#QRA>maEGh2Phxp4S5GAYOP4%D5c#F_5?BlJhZp?662~@50{tcH^GOaYoD1ptzH&_j)L#p8mD4 zernW1LG97N{4#04d<&%7LA`!={i?Bz#V)&fmym9CU6OJt^r&cNfWkL&Wv#gnllP~m zFpmS2`;$-Q8=G^$w9;~z1fLJ>Bv8M~_D3_4L} z65{}E%HEw8#{cN#*073ec>CoMk3gY)AAj9(!1=ES-HD}m556SrzHy?qRbFo3L6)w) z9a>TDfzXwA<$?Z`%nL6H4GhA}HjdtrcoaGiFsQtz)xH$Hy?xY&KC+;5vj2fAiKP(2 zh$NObup*3OsPN*L>r8nASkWutYa1kcFt3wK!y1_bg~)`N9qFb3HRR5Qcir{nO@ z#?Ncz4@zAq(y-5uo1jmW`b!fR#u-&t&hU7U9mci_eTLCMR`==ar~go&nH+TVo9$2Y zb##9Gl!M&Xt!9-!O=ALYFCdbCAB(W`<%^|L+@N#K3Gh&0xs-?X5jVEV6kj9W@l#th z>F5KV2^O#hZv;=KA8J?ZcCXEhZrikJizV&mWqoyD`>R&1V#Y6eCo*^s1A&`T?c&pT zzSBio)(FK~Z{vB(yt%$b`Y!sfj_UqOsS8u)+w)mPCp}C@D*azErcC2Gwf=pvy{gOJ za;d3AuaOAfK{8F!7TSa03m>H^7n{U9dz9fab&u0iUw=Kw{?1R+Vgrz;_g-GVqW1@U zzv%Sl#uX2g+;uqhs&DWJv{{LGTS>M=8lkGt=(}6Apy1O4K}kErRGfE+$a8g4qf|pKbt^&G&)QVhwf#QQXwUOV zTT4^x=tVXzu#g|J36ZV^J7GhYd)dlCRy{6flGiL>2#!uL_XZjfGX*vHjS*lJy;Mi~)hy*i_z2n2FXeR1HjixG{9q^nO!N=qcM+>Ro69du}qO@Dx zf!Gmb>iyjhZ5D+FtlBgUD(+cUK$xAGe#I*VJ@mK?ON4eE`;M|H?-zP@KF1by_cc_! z&r@G6cJ#{NHwMu_FSPkxO%Ts}GPq3so#r)!ZfbjBp&g|LGSByX@$V8#aLiv8RgfWm z5%8E-t#-0PkO8BATwkB6<=u3~_(%Vw4+~RF`tTNc^^wrld5x@9y;_h|2fq1`Ahcxg zMzzN5QEwi!b%AJb`aJow9i4jJP!CBxrD1Jnskqu+=NV?MHw+puY%di5+s?Vv`dsY@ zRBezZK#T)nLi=NlUChvyqAx47fGYw&M1Jny&}OT{Vtz#Q zba~Bry*^CXxMIr{tTF#otiNky+r=tm;?YH?(Y>|hrfN|$ZPy_%@&Rp15ycmAer z{GoEV{CLym-ob?0yFoEkaeEx?gCVy-P$@=0rbSAcNrI9IIyReMxdoFyDjnJ7S!j}} z&}mj<|IM1N!TcLHY#_$9U6=gy0jeQV8ga{<)&Oaj1gqFG0Ru@yd_+XM{PI(hs zRWAPNLY-0}+0l~-s;eJx3hJ_r>1;3h^Cxn1Qar%LsC#QhE8r#Y+E0rQ-jUosUpYot z|Dew5-e_-<{fm#U@N4h3*-88B znL_Z03_%&FtU%I(}^N4Vxi>K!3Jirvb=smEr5qG0*v)#81yo%3 z!^WNx&#X`0rapDW3eEo;;-`W*v}f(vxG^t*k+Yfm{MVXRUmaccq?GM4i^*3huBj#|ie4l1NtCKpo=bi12Rjm`vQl(!6`O@qox>F=JO^?daU+ zW!`s;>}7r7vipTV$$N(}V3``Wv+}^+MF7~Qke{X9oe- zIAYRQd92|*x5G&NLjF9S&dc{@+nv_I%i5}k7bROoQ_LyH$InK1uzRerC--QaPV0VI z&UN3b(a;k4eLk30i#xcuda2dBLG^JTOra48P*ukJzX@r8rva)dd8<*1_Or|ucka*w z4Z09bJ)-|q!Oah#J)z(bceih0awD$`bCROeodzy7_-jP8=k$=lzfu}pL^ds&WHE5~ zwFSTqjr2s+j2`HaZB6Q0uqZUi=zfbxtLp#$cBgEwwP?FPb|JjOH0?_-tZ$ zLV)(S#)LYaZA`oV`EGl!(hCiCS$g;x;>+fA>nD1mr>CwI-qf+KIOij2L0vLzDz6K8 zk(r%eylR!kH{AshHGU8AvKo8RV7=azXU-cUaVq17Wy1WsX>-a~3Q3)cHc_SW(?!*p zTcPuqKC3Tgk=&tZihvgtleL~lHcpt&FeoLi$%IVFhhl}wpZzItfi&bM=X!1_dpq3i zv=5_}kDyL{DG#D{cTAemap{n`l?&V+Pph=s^*gifSaNXDQCDeHKXMSa{CD+tp??(? zS@k874}b!*b>iL0Z_-2X+SA$tD(tm}*+~l61!@x5v}or3M2~90*b3eeR6$>#6&TGIQU{?6;g$0S;|R$k7%A6(M4Y9BO8h zv!4b2`DMTj(;(;|V<hN{Ua=hvdNfsi;AD!cGlxY11-MlJZEd2{0Z6S z;ms*ns7`uvBwwR~GrNYWyK#D}Q6t0sQF|458908l6(B~qHT65B(q=4ax;t&Clnj0?HkqvlJjKX z1@_SJ!!elkL_oo24CV2Zs_%{wOj9HQEJECqXGWIQKzX6dZcg)c z+)PQ^LiQBjNd6y(XQJ2>`k^f#g$W~WObS0VF-WtuObT-V`rxz_;_j3ev)*S-WQJtZ3li<2-_^bxEny|rKSWZdD3$sQAUwH9K!u-h~^ zeBRZP2v6H1mpS)QODpDrlc!5J1PErVru*Ba|-c@<}oc_k<3c zBE67hQeDPCrPW`USAX{SYqlMvi6u2-R}gh~Rarf&zVyVv7O<3cogojNYKL~zS z@f{phF&BHx=_&B7{z8%zbEw{CrY>yTC^DQ;=de{eT4F4tkU}L*TiAy(AeT836PIZsS|T+DDK`#h3)ZVZ;HTc-=U6)+5XnEvy`Y5qdZ8{e7qM_FDNuR$#_6PW z$oo)6_Zeagyfk2ungqjSPxM{KAp|cW0|u;u6n``<`17W+!$&j}Ha2eKHGjP9r|%HD zOey8Y5=4$%8rS^U`+%3jxB76WQi{tnCE_*#@q5cosve`olie4!SEQ8Dk)C%)>Lq;8h!=AACv_yS4=>C;s zV;(Er_k%GWQ|p_YIK3&r**aS7^_1gFi-3)*YO&g1I#Ved-V0jVe=}9DuiFK;lMmQG zq-kz+ojw2yWTc5NA-Bd^s-?_}tw*?HRbfb03v(iG}Qf^&#tDYw89INR&2Aa3VV0JL(8L`+hrEG zT4C>a)yaG7oM*4vD->;;Rlzh-E3~Xl@OJXirq4Yr&Xpw4Rcmp>PB^-18tg%HXp+JH z4!l-6pr%RD{@Eg`t`P$|ZAWhM?1Y}*3hn!;HJVwGyiy6vxs+e=Usa#F<&{C%w!HW64FKD5-fa+Z8Me8D6;0y`~) zXCGpybz>18rPY7!%WU+Plto=^)*?py-cQ+p32R$HrQ|mu1io~=HrOv#~M=E>&)(6qOe@xVCG1+VO6uJv+AS-CwN(EM46*EBg z{bQ!~+LW5ifEmZ~dU1n~FI?oCaW{#HW!<6JIr$JqKtT~5S-QcVe_rS|9VVY_s)@F+ z7MolfRE9q5g60#dXv)LZGgwNzt=BxwE9JOB>r#K;vn|@e7w+`YU($^i$Z@(euS3X1 zCtAQDw&}prs^R(OG~ilvx3>%(X7OS5z-GGMvogxxyhs;@_3J89hx%W!xaoaAfYw|VE?B-9NB3e(VoEW>EVVC6L*00MiqA`uV;>0J! z8iX<4)1kS2XoiaOq#kRwx%4>5+m*2YE1h%GqWg(#2{9K-$&{TpT_0U^w1WX*ZOvYw zCjJe?xeGeL-rLBv8KT(bOg`!tXWAi_%4llDo_>B5NFpqeKd$hwCtcrJ&s>zxILJ)O z9GbeGFT?X(;JN(=lZTZ&rOKK*i1fV%GaVq|YsOAz9)EK4&omz^yPK5~)4VEDYFS`{ z-gCl3OnYWWuM)QH3(|{h<E)KRWu_>h~nz;rpn?(UTfPMn@Y9kPmHWUd=g-*R7nim^tqZ zsasDmY*MwK(WhFK-aa|)Le+JM8S)%GG<8?vP%`adQVtZ9SL9rUuPU<(0#L_^O2HtqxC6y3kol>6f_}Zp5I+4NF?23QZDqh zVNyczxcpDOX63@^nm+dK4fhY+V8{eq6BhO0^OnP$>N|Ms2PisD+7|*Y%0h1rYrkZC z*X6MnQqQ}aBCJs5%Sisp8LIUd+%GWFCoRY$Auqngqeq<$wREnH{xDA|X{-{{XW&a; z-+ZiDB9Ri%+oT|qG@KDR{6KGh_NSVuZflmPy35MC3(wHei>+d#sJVzg44R4Fl{hxiiXEzgys~R0TKSN=#TX5#Jj*1voBq&0)6}!0%c3L$H^!0 zbntZ*Cr8zvNl`K#K261vk2pgoV+M2kB0^9R?*;eXZ@4Io4f0EwY7YD^9|0r#D zFBk5+afs3Y_eY6m7~HNgZNiDU2rsP(O7`9`)3isoM2NJ?Z;6|`@v=)toWr`}>Ee543kZHm&t#fq~LIWWv-+~ZmWxl&z)Z!9~z z-o{$ms}O5>;St@rw^o5%a|g`6VmX!{_*w5sN+QD%HBl2s*BMw5fFM8Y_cOWVRkEN| zTe7@i?&5EKX_N~QL3pUcx1F+TV8r%c-W9>`kM3s#blwXux55u!^1Y&=$p>UkJeD=X z$<0%9i}Abt%Uz3~fBq`cB+-E<^}Qt@Dft6V@QE%or^N?s{dQqemUO9Ea<(sC^RHzkkfGRwHd`1Zi6G*E|mSg!FF zeL|$SChl+LVq3bl`8J)WA9BR|OAOS#4V|T&7m8nTt{GE6^3HzQa0Ix5SwUh2d!6fTp9qa(QP%*?yC z&XX#6RWYdAviECNjYG5$z74NWwm#=#=Uzrjr-p%+%zt8AX%C!Eq&48&4ZVDEotmDlgExC^3Z7{IYEXO@TrT^!R z4odlV%^Llo*gsRZMwr0BqJ?*7ciwS3xOKi|?78OCFWSf5>5^RI;GT*4G^1Swh(X5q zo_V7I2c;7e30daajyw95Pm7Os;4U%dkzJ>wFb9a$A2>Vgu_xz`jqld&eW&i=GAAT` z9pm3$J)1frbNPS116*eSJU4$VeT4k`^#7Y4B>w}<0SXl`6Oeq2z!6vi!2byVdT-PL znu8fCQf*s^tPHJUWNWu6*eQ|!Uow@3bwN>k--MI_Y=+juJ-hMXNb#^Lsf!8(~(2(IUB#e%)ON{?qa0EAtJ`D>FM9 zi_e_6#}w&2?Rr&MzzUa;(~ei65I4Nmg~ho=4ZYE&KT}P(*zWos*z|rIl}!A?Q!ZC~ zdvHgV0{pLY!aj>N=b#eAQOK1h69Oo~f+N z!usDe98Sy#Jk2>E{;J_z-Y}PK9tocr(ZCevwCdyHE_AOVo5q1Ll+sFf(7Veuzh$cn z29lCd>0z9L@$Y~>gqQ)|_9#3KOv@h$z^wqpH>V$}$R+VLe=+snWZGMWmY^igQZ7?q zp|{MoIfosC*F7)-rC#EWy;DD}<`^Mx^CQ66+mR1LzDIvAwBKfY4aejO)T%Fnj`%-xY3wWI+Hl%pkdY;WR#;5PVL-$ouuB}uDMWaP)LKiY*BAvC^9LAO9F?xttw+}>(vi1W{ z^{?yFA5qP?)<0jE;!32Lym%D#6&M=}&~9G`RM1lqg|&PFHGSWC!@QhcYH+A(^yq;d zJ+f*y`<+X>>lh$0MwYgRZWU#QF!pXYG0>}jBg0-M++~ln;PHVq3Ck`9)%`LRH3~Li0mW@q$# z7>6x$PiXpzkFYvUH}Vy#i>2H!vT@^6e{apTzalFiWIbFma8-dA@-ejoXh@QZ>tp2?OR_`e zqgzq406nEBlBNbaI&6X(owI+_lK?NE9&L>H$@N1zP-N`&o+3OmxA%yy<$)zeE;mn? z9hOCJIRc6<0%`dRSiO0_)lpfWUw*NJrX%i;c=K$AS8-Y4FjX(E=>`%R*4#gqD%Gy+ z&0#G-<9=yAn#Qbi*e7ehE=G7yxFUNdafJ1wUO4Bf+2NufEH9I>1an|H=F0<1q81N` zT&ArM{&1=HEyMF;Vc$&=8NqGJ<;=ftbt3P?u;EBZ8x25bnqOX(qkS|w6B*~icgq(P zue(v^Qa#v$-_eAb_lFP(n)WSvvQ$Yjd|xl~A=-8H+iBPXLmI#@G6bD$*c?7G3aGPI z?~egznkA7=nAysuBy2VZPIh;!)^4QGe0B(EdLpx4kA$Z3yUB$$ZS1&qxeb7{>jBeK z82JXORY}Qlj^G4{IkbfMV0&7onDvszQ~rQ5EnM?2|I-X@IaG?y+#yd;bRiw4B||1j zYU8$b)mY_;B-e=5l(kHy1)<2fx|f(LFBiZqG3fcwe9l+GOcw;TUsiNz$RN9+(D>Pa zy3c7{;4b{PM7$*~2qjDgc~ zZB+iQ__MIx`S6x!Ls9twAw^Z=PZCed#T&<3*yFp9b{K6U8IX^&*_PV^y>|cTX&i5% zx6VSXg|PcBDqqdPjx17A`DEUz>_+e)IRSyH7?nFmseV%K!o9me>d9M~qIgv?X_9eu zaELRwNv`x{Ei-0d3;O<>1mRun5sC@4R1pGszqXq{@@KaJQBk@#w_Vx(EFi14les;Z zN*p5!E)S=gho0NoV6_C!|9oZzp-lI zpErn-5fydyUZ{OKYS&cMG?qGYy3MC}cF>8qlBd)wob4idZ>GB(I`uTf9{mtelwG^4 z&RDKn76|TkT>yZemZf6tZdf`1P<(9U2e$U;u!ASkeRJG@Y?Y%0pgulhE^8h=?De!! zj&BzS;FKNbZvPlyT2lvl$fLiK!q+^FGj=7KugjygvU zaI^OzHfQwU%~O#!Y`b>52!FR0mo+3NKWVdBrnsT^{gqK>yc3pRz9n$;<5bUbW?D-y z_w~J&g?RABfC@4*BxsovLj2swjK{z&wK{fyw&|lo^i||jP5X_{ z>-Tk=@QZLP+Dp77tUU6}6uGDobl^N#czU$|O%Gx?V=XNSP3`nW6RZcD%SK3klQm^? z4`Fsrl#p8RgzIcTlmEPyhDlK$>j5-h@$39e7G|AZ+osmC#389fEV9jAq8GEIjlnC# zcHDhxb@*T^OS6T^9SbX(h9P3p`$9zC(50|Ozm-2g`pi~wkO0oJ;nM&PL~GL4t(b`q>aEAkGvnm*6fZ)*!Ymy+&2rxOZULH zATDovu*CY>uu^m@cyd%{KF3)U@US^i$2HOp!CcGC_o+LxBexC;R!TY0D2use;{9c( zI=xRjlfLhty6A}3(`Gn~xuf5*t0FT@Pa<6lC<*K$~IXSwOS*I%sGec`72G+ zdbd53O%nR{hkUM80`;>peTRD!P$>a9f$1=Q6aG-EDhxLd0`YTQO0ENtl{Z$ZDqH#z zl*jDBVOP(Z9)M+b`ba#bT317(F7&HLQqK_UYNU07!xV_x*n0%9@ToPJ|#2|)>@>bmFkN{_~5u9?~9n^=N zdP-MiW-jL*sj2+?4YGcD$A;t8{8~?l%fWbYvQy-+pCrQ`l#aUw_Mg9MRoo&Ko?g|B z&4TM@e2ZO@i{wkxxUY*vG)S9X0m2t)iJgWMk!NO(5Xn~WK0u}2dooh%O-J5}UA9A@ z%0B5QXwxUR2A9kM4#QF7CiC`Nt?zc^W9rxFkR5ri%gXPYCp7w7*p8M5l{9}F5zdrF z2?4A!nLR46i#(P_B#)V;-`Y{f$=G#SZ10pjdjQhl=V$KeYTLu~o{VU7Q|GHClO28L z8RWlcaj*YHD%-qha232Gp4Klm@(^;29)gOU!gQAwTD`WidFnLC$Z`0OR`#%2iuTIq z|7!0{zu8>dHm>dNMCoK`jeD2fQc~S&jJYM|sWfWV)*PW5G1SxvZBtZDCFT%QLXpH6 zQ8tQ7j0sXxQN+|Di1EGkdDinUywAJVn@{(LtaT^%b*(EokMlTwry=ra68}@13hdCu znStdUP9hr0{Jc7(54DS9M4PDGt#^3;o1uKccNag|dDuDZIh2nib0Xekp?;7+#v0Sg z+}R3VV{7zS2Q(^6bAiJ9*)GNK@xr}G4KdN?#0s$7GEA3JOD?bNOfn!8xQY5Y`R~3B z6rp7j3L9Xax4|G|%YT@lEZkbDf6f%aFJdQB0Us&_)EzUgbW<3{YKAREw?4}5K?jWu zRZkWAXZ79sBV3TCZ`nTMvi_SWV1`c+B)Y|naYZ2$OZ@W);`qRK;47TWMHBi+&&ZuT z=hx3Qw(Vgv9&mnyhx~2b#o!V>MAnjPrkv2}f`%LV&$T!k=KOJ!=K}+=YkZnVIv_FA z7W;f!r`H5h`d150p&6QpzH~N*5pQeIc|NFS9T%eiNqEKxebvhGc<4YJU=%|^Kq1F& zYzqIgo<%`JjzsNzG1a?l;++Sg8oU5PdaPpJFFlfR;ub<*D&@G_JoA%d&AT{1v?23K zM;RMeOYis~reC~OLAW6Da&#I#J`Rg}q|1P;Y)Z4ObIhJ4VJ!?p0zg|F#(nJSaCZS= zKFpIYX-j}1vE!eQ=Nllv0<;8{*ujHj{wG3sQf;)pC}$B0yC`8#HxV5I`>PP~XtwHg^6PA4X8 z9wY@Pc-9|SkK9BD0lz?R9{y&AO1o9+-;;>ZL0?#psl^Bst>rm4ZMUaFRRwJ7(7wKU zZyLGjRvZXh?@2R6-hj#$1k8MJ_d?G{N(nf7+a{BGQ!-!9a{!6qDe~SvF#^7!INHXa z0@X9KQ_FLY7^ohquQhs&`I)IBE>(hL@_%?=+bpZ0UIYIJS;-*$&}8l3o*h$jEH3=udk}io zx+{n1^-0oXr+;>m?WMz}fBr*=&(-yA9p|aHhK%gzq`+7&L7Pi23A#~y*ormp*(TW^ znSWEPVmLXZvc0%M#OGy#tw;wFWa*)N|H9+ROJQ3%0k%$?GQMifMl2Fw(HbzvNB zs%s38Ayr3oiwyd?#4ZcY*t>aqP>OeS0*B*d=;sgMo(*k5LGZV)^= zU?*9x&oEc_oSe9Ma6NIKn~}XL=;Qtk?1-Aa=h|6+@RExs#+6!k;+tQo&*CnfVah(k zFs3!n5+#40jnBID86AMzZ?5ZkIQmm1UciJR?VsU38dS;b8?gv>7`#E-^&Z`^OL!u6 zMJ;Z|VE!NEY&kdc`U==N!4)vnv_a-IdEmO@;C1d5^Ep(1uFUlCb=>F!whfR zR#F#xhwgOvCV&MERidY!l)6i7f=1kAAq>$nML{pj4Wy6iKp0Im4r1*&jd2iHti+0E zUIie*Pro0+!2~(Snc(y3-_2bFIiH3-xsdMBop)b&;>ZoXzkk7H@3b5mt`?;6tN8-B z7Olr8FA3Vc0!CaSVu0g;!?{SK^6F$yioBdw3zN{}5&1&zhnMoM(|+qQAJRA*Yl+ia-sZG*KXh~z{~K>e-O46C;p|t{MV3it(EblTVfghhmEWa^50)r zBASx`I4vtO^4k{7o<7h~7P=2qNxk;J>{T3{o&#FVx$vd2prO(56^z7Zf8uf==Z0F? z!Na5KzrJkJIlxIp^kOMiv)SqBB_#&nU?iH4iGfMLnOh9#mpNhOAlEMSH!oYlJevkqL^%yj1)kA+>iz*>sQ~zq#7GeXuytzbVJ2{g0Z2eG zNTbO2r+fJQKq)h58{biO?~v}1GHx9gHv^Eu{0?Q0mY#4RfB94V#^axWZdL3D z(rg@XI0aq-9{|s$$@~xiB}htCk|2kUo!RW{GOKw#Rlb3i!53A6|FV(qhM0}j4e`3% z4G}z!!gre&UKy&0uFQPyCY>Vdk)$&!F9>?&AfHWy(;8XKsa#Um>Z<-BAT8T>m-569acyLeU+g)61b0U-Y`I3gi|G4O5XlHD;(zXB3hr6r83t z^qm1Z+r+9az{dK;MM-Onr75)@wn@x1Yk)j+<1zF#57*&?wjRvT9FX#O0DJ0T!nG$F zv9rGgj^3av%}-V& zIg!eDJtn;vrs8m#uJ{eXSdZ87eBbFzy^Tfn#Ymn7U6|KDJ8cW4_cd5|_o29mPvr8- zB4ZY_e-)a4Lt)P_8zq-()=&M(X~f#7F`(fxm!Oy)v#}=(kllz;-(*+sR^SpP#7~ zS2@e9@dAI1KO5eTK$vczv3TW;m(%w1?wO^XKcz*iR2w~TdG&ofMS~SHmTuQvE5PRJ z#XPvTfNK$IlPz9kHu$3RVTdJ1&#K}^Nw31p2jzWRIv|Cd)t~z-Y}*FVG|~n>#q7Hi z2&WB1yudlQF7(rwg2JY#)tN$Wjfj|WJy!4BZnxbQFpBI4(8bhd{jj%<=k#W7mB=De z>Sw9z?bTquf`UNIL~P$(He4d5uP?MPF;d`5_M~2uiM<*fZq`}&D8?+)GK~<<3X@o} zoeibli}7dp1&+NlH>RHd`d!bHK{h_0CqUZL@6nELv_aC4r^^og38Dt*<^=1ANka*sx z8zi8&)f2zISOixt?0=HbDwP`vQ3oi4nrFQ%53QH!z~hBkVMbA%4O)k`VO#m9#8si} z?Wr$xYcYo6yMXs68ta}gnq(6rf#_S%$@dh4WsN5aQ-Ezov<7g<@TdW@%U&Z)sp0-w zEvbAe+GlT7JYxK2CUz-hd zt>jeR&q_KgVoi3Rame1QJn-&bVKL`MBqCGd_U}11j}yqNN%uB>Y(b#~?u!jkjJ-p( zXQkB@zxIIT=}PIca|~(rS2{OnJy#k}nixNL;Ae_0TcwOQt2SnZG_3r|wh$cWqBz~x z3>2*dq(cx%VP{06ep9r>z=&NrWj8vL89GQ3Sp#x?Co=2v;KNMgSqTjYTG0n_!O3@{ z5iZaLqeH*f#NkLoY)jGR@FiPhdDKn#p73{4Z-w``YvhKv+vO=m>CWsp+!~0syh?G( zs#(UCHT$2hF1}Agz}Q*rf}K*b9s4#^=_hGocp3~H19fA;A6KK`hose|ct9U{9XHKz z4Ywn?Odc$eEoe$BM(=%*)oNAEW+&%_FohcPc7Y`ME862%s|}I7?UwEGtGCCYnx#!i1@C8wT9_aZv>wEY5 zI7Td3U21Lja#=!X3g}0CF5QYVSsQ(oX_9yg98El3-OsjvH&7KTSV8s1r_37_c6$um zR_1Gim~2@%DREO!ln2#f6@Ia>DCX6HTHM)jUebK#v~_A+4G zLAbnvIK2#60rGs6aIla3hV&2S*4I@C4G|bfMEXmisl8v&Q=2u=p6I&r~DHrv!x{<@b5dbn4AdhW9OL1<>tZZ1`tURiQQ#)PK zXCv}M1S#GquH3<$8Ye9+(*776)2SN#$3X4i#9QzfD~tbXl@Dn=sOAYj713V^1$V%d zc*40_|H9mq`x^QbgkCLp_JOOW(Qiv_`S0hqXxLuQ74f-4d zmgV^%nhP0iM`FLOm&wo^t=djshO3pvRWi}98tR}N^3o6S_+244rM&`3II6Lu>)auuQMh-zQ~UQRPTkC zCYMr0Bt2XJI4;{XmNs?jg$d1Ok&FM~;9NqZ#{+0@QJ%7SLBe&p+3$uYEnU@T=(=h1 zs^}-(rY|H!<|_h>g|yF;bm&>ut%7XCb-Xr~GNuniX6y-B>y-*4@QI&&cikHfCzg0|EhozTOgXLdCNYk;~oW-%lqgxYgOt=P)uj@ql?0du+ zSXb=xBHfXif(mh4tJ>ZxT_KCxtJ>5IFbx6x@8QW8f0MMCXn`UujIMfrO5PHEoYQnF zyK@irC1>Godyfi!HOK@fZ1jv;qjs?`bV9#E5tDO2c+oK8MD^fD;lR;0u36a9^<*mK zWU(l76b0L`+WQ-+CnOfak!1lQ<=$%pc9qcPNP*SB29) z4M?6T$W870ELfZK$P*twGn&P$dKeN^VIgFY&K!bSKtnS~CTW#>EvBX59-0B6N&Ega zel3_hpDC-r`3=N+>$q*AT$xce1|#K7`*d#%uZ)}N#_SJpixwO?g;1vZcnI^J9%ip` zX`KZ}4vSxqzYAgaCZ%@r78*X*byew`&YQ612=fMqw=w0;X75?A>8KLg!nh2Ks^{eS^J+Fr$ER zJxAw657hez4SPJ1kTbXWT-TiNst|Nki2UuiAM&GaN-Y1T8u_N@%m*`{;EM0cw(|G5 z-nJoSUJaJ90FFrl9cmsc#yNiz1^ ztaP=~y_lsx%jz4VvV;i3Vhs^^H=)5;Vu!7Z3X(~**mKF8RTitj0-{D;r=0}YYPxPP zTovnE4_S|(A%voaiyzXI!)%CbS$(} zUU>EowMP8=l#%G6N2O~TLS7Nbf!@b7gWmNw_|z*QVoU{lmjh%kvE`8wO&xPy^{lwV zVF50w1gO!5{Wm2`C^ab;$(PyN+srVH|(_sx_l80=1$P=n_`pW_kh3 z<(Ik5>Rftm_(Q)32QTZFPr)VLn`Vg;R4==4d18N6R`f@FCj@7K&e+*%*ZkfX z>|eO^)!pau)7~pHMu4C4``3)MS35^$-FE5Jy30;mhebTc(}aI`aa}qy^Vef`AH~8+ z=Z{AMV7}F7Ia#g#vRmoAhj-&}4*pdg0#}kMv|nRL4zK=CO||)tqvXGC-p>Djvj63Q iNB_S7|IG_ https://github.com/ondat/trousseau/blob/main/assets/Ondat%20Diagram-w-all.png + +## Requirements +For this lab youre going to need `kubectl`, `helm` and `jq` installed. + +Also in your `terraform.tfvars`: + +```yaml +# terraform.tfvars +kubernetes = { + enabled = true + kms = true +} +``` + +You then can bootstrap the cluster using `make bootstrap` + +## Walkthrough +### Verify that Kubernetes Secrets are currently unencrypted in etcd + +```bash +# create any secret +$> kubectl create secret generic secret-pre-deploy -n default --from-literal=key=value + +# output the secret in k8s storage +$> kubectl -n kube-system exec etcd-vault-playground -- sh -c "ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cert /var/lib/minikube/certs/etcd/server.crt --key /var/lib/minikube/certs/etcd/server.key --cacert /var/lib/minikube/certs/etcd/ca.crt get /registry/secrets/default/secret-pre-deploy" | hexdump -C +00000000 2f 72 65 67 69 73 74 72 79 2f 73 65 63 72 65 74 |/registry/secret| +00000010 73 2f 64 65 66 61 75 6c 74 2f 73 65 63 72 65 74 |s/default/secret| +00000020 2d 70 72 65 2d 64 65 70 6c 6f 79 0a 6b 38 73 00 |-pre-deploy.k8s.| +00000030 0a 0c 0a 02 76 31 12 06 53 65 63 72 65 74 12 d0 |....v1..Secret..| +00000040 01 0a b7 01 0a 11 73 65 63 72 65 74 2d 70 72 65 |......secret-pre| +00000050 2d 64 65 70 6c 6f 79 12 00 1a 07 64 65 66 61 75 |-deploy....defau| +00000060 6c 74 22 00 2a 24 36 36 35 36 62 62 64 65 2d 32 |lt".*$6656bbde-2| +00000070 65 36 33 2d 34 66 62 61 2d 61 35 63 38 2d 65 61 |e63-4fba-a5c8-ea| +00000080 32 33 63 39 62 38 34 32 32 30 32 00 38 00 42 08 |23c9b842202.8.B.| +00000090 08 be ac d5 ad 06 10 00 8a 01 60 0a 0e 6b 75 62 |..........`..kub| +000000a0 65 63 74 6c 2d 63 72 65 61 74 65 12 06 55 70 64 |ectl-create..Upd| +000000b0 61 74 65 1a 02 76 31 22 08 08 be ac d5 ad 06 10 |ate..v1"........| +000000c0 00 32 08 46 69 65 6c 64 73 56 31 3a 2c 0a 2a 7b |.2.FieldsV1:,.*{| +000000d0 22 66 3a 64 61 74 61 22 3a 7b 22 2e 22 3a 7b 7d |"f:data":{".":{}| +000000e0 2c 22 66 3a 6b 65 79 22 3a 7b 7d 7d 2c 22 66 3a |,"f:key":{}},"f:| # unencrypted key +000000f0 74 79 70 65 22 3a 7b 7d 7d 42 00 12 0c 0a 03 6b |type":{}}B.....k| +00000100 65 79 12 05 76 61 6c 75 65 1a 06 4f 70 61 71 75 |ey..value..Opaqu| # unencrypted value +00000110 65 1a 00 22 00 0a |e.."..| +00000116 +``` + +### Deploy Trousseau +```bash +# troussea has been deployed as a daemon set in kube-system namespace +$> kubectl get ds -n kube-system +NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE +kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 116s +trousseau-kms-provider 1 1 1 1 1 46s + +# a config map has been mounted into the daemon set, specifying the vault server and the vault token +$> kubectl describe cm trousseau-config -n kube-system +Name: trousseau-config +Namespace: kube-system +Labels: +Annotations: + +Data +==== +cfg: +---- +provider: vault +vault: + keynames: + - kms + address: https://host.minikube.internal + token: hvs.CAESIJGPZdckGe6vN3-bMUzBmT3XywsQ8eNMWZljladJKsszGh4KHGh2cy5Tb3dpQjNjOEJuWHM2cVk2anhNcWtFSEQ # periodic & orphan token + +# Troussea creates a unix socket on the minikube host +$> minikube ssh "ls -la /opt/trousseau-kms" +vaultkms.socket +``` + +### Enabling Troussea as a KMS Provider +```bash +# create cfg dir +$> minikube ssh "sudo mkdir /opt/cfg" + +# copy encryption config +$> minikube cp ./k8s-minikube/files/encryption_provider_config.yml vault-playground:/opt/cfg/encryption_provider_config.yml + +# copy kube-api config to static pod dir +$> minikube cp ./k8s-minikube/files/kube-api-server.yml vault-playground:/etc/kubernetes/manifests/kube-apiserver.yaml + +# wait for all pods running +$> kubectl get pod -n kube-system +NAME READY STATUS RESTARTS AGE +coredns-787d4945fb-5fcwd 1/1 Running 0 5m +etcd-vault-playground 1/1 Running 0 5m15s +kube-apiserver-vault-playground 1/1 Running 0 19s # api server restarted +kube-controller-manager-vault-playground 1/1 Running 0 5m13s +kube-proxy-vqlvn 1/1 Running 0 5m +kube-scheduler-vault-playground 1/1 Running 0 5m14s +storage-provisioner 1/1 Running 3 (36s ago) 5m13s +trousseau-kms-provider-jrflz 1/1 Running 0 4m28s +``` + +### Verify Secrets are now encrypted +```bash +# create any secret +$> kubectl create secret generic secret-post-deploy -n default --from-literal=key=value + +# show secret in etcd +$> kubectl -n kube-system exec etcd-vault-playground -- sh -c "ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cert /var/lib/minikube/certs/etcd/server.crt --key /var/lib/minikube/certs/etcd/server.key --cacert /var/lib/minikube/certs/etcd/ca.crt get /registry/secrets/default/secret-post-deploy" | hexdump -C +00000000 2f 72 65 67 69 73 74 72 79 2f 73 65 63 72 65 74 |/registry/secret| +00000010 73 2f 64 65 66 61 75 6c 74 2f 73 65 63 72 65 74 |s/default/secret| +00000020 2d 70 6f 73 74 2d 64 65 70 6c 6f 79 0a 6b 38 73 |-post-deploy.k8s| +00000030 3a 65 6e 63 3a 6b 6d 73 3a 76 31 3a 76 61 75 6c |:enc:kms:v1:vaul| +00000040 74 70 72 6f 76 69 64 65 72 3a 00 00 b3 d5 f9 b3 |tprovider:......| +00000050 d3 fe fd 55 41 4d 67 99 56 f2 7f 17 01 79 63 76 |...UAMg.V....ycv| +00000060 59 09 82 73 bc 1b ac 11 32 a9 2a ac f6 cd 55 c4 |Y..s....2.*...U.| +00000070 0d da b9 49 a8 28 c1 65 25 bd c2 06 d0 dd 41 9d |...I.(.e%.....A.| +00000080 ed 28 57 96 06 9b 60 ff 9b 24 ae 53 52 d2 b1 23 |.(W...`..$.SR..#| +00000090 74 16 ec 8f 40 54 2f 6b c8 bc af a9 08 30 76 c1 |t...@T/k.....0v.| +000000a0 10 4c 99 42 aa 0b a5 85 d2 63 b8 42 5b b3 63 c4 |.L.B.....c.B[.c.| # encrypted secret +000000b0 00 6a 4d 1e db e6 49 6b 8a d5 df 16 d5 4d f8 ad |.jM...Ik.....M..| +000000c0 3d 9a a9 42 0f f1 27 fe 17 94 47 97 d7 30 d4 26 |=..B..'...G..0.&| +000000d0 ae 22 b4 97 09 25 ab 34 38 0f f8 8d ad 41 ce 01 |."...%.48....A..| +000000e0 45 fd d9 d9 66 d3 f8 9d 08 d6 40 35 87 09 72 2b |E...f.....@5..r+| +000000f0 b6 d8 ea 2b 3c 67 91 08 31 26 6b 21 e8 cd 53 97 |...+.| +00000110 7d 14 a3 17 fa bb 1c 5d d5 8c 7a 1c 4d e4 5a 86 |}......]..z.M.Z.| +00000120 52 6d 11 49 dc 39 67 83 1f 8c 9c d8 53 60 79 70 |Rm.I.9g.....S`yp| +00000130 ba 95 0e 80 92 51 1e 10 77 f3 72 13 e0 bf 18 a7 |.....Q..w.r.....| +00000140 5f 62 6d de 41 dd e0 fb 3b 5f 53 e8 2e b8 a2 c1 |_bm.A...;_S.....| +00000150 47 da 84 49 b7 2a 0b 0a |G..I.*..| +00000158 +``` + +### Encrypt all existing secrets +```bash +$> kubectl get secrets --all-namespaces -o json | kubectl replace -f - +``` \ No newline at end of file diff --git a/k8s-minikube/files/encryption_provider_config.yml b/k8s-minikube/files/encryption_provider_config.yml new file mode 100644 index 0000000..0a6c9c3 --- /dev/null +++ b/k8s-minikube/files/encryption_provider_config.yml @@ -0,0 +1,12 @@ +--- +kind: EncryptionConfiguration +apiVersion: apiserver.config.k8s.io/v1 +resources: + - resources: + - secrets + providers: + - kms: + name: vaultprovider + endpoint: unix:///opt/trousseau-kms/vaultkms.socket + cachesize: 1000 + - identity: {} diff --git a/k8s-minikube/files/kube-api-server.yml b/k8s-minikube/files/kube-api-server.yml new file mode 100644 index 0000000..3137c05 --- /dev/null +++ b/k8s-minikube/files/kube-api-server.yml @@ -0,0 +1,134 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.49.2:8443 + labels: + component: kube-apiserver + tier: control-plane + name: kube-apiserver + namespace: kube-system +spec: + containers: + - command: + - kube-apiserver + - --advertise-address=192.168.49.2 + # enabling the encryption provider config + - --encryption-provider-config=/opt/cfg/encryption_provider_config.yml + - --allow-privileged=true + - --authorization-mode=Node,RBAC + - --client-ca-file=/var/lib/minikube/certs/ca.crt + - --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota + - --enable-bootstrap-token-auth=true + - --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt + - --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt + - --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key + - --etcd-servers=https://127.0.0.1:2379 + - --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt + - --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt + - --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key + - --requestheader-allowed-names=front-proxy-client + - --requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt + - --requestheader-extra-headers-prefix=X-Remote-Extra- + - --requestheader-group-headers=X-Remote-Group + - --requestheader-username-headers=X-Remote-User + - --secure-port=8443 + - --service-account-issuer=https://kubernetes.default.svc.cluster.local + - --service-account-key-file=/var/lib/minikube/certs/sa.pub + - --service-account-signing-key-file=/var/lib/minikube/certs/sa.key + - --service-cluster-ip-range=10.96.0.0/12 + - --tls-cert-file=/var/lib/minikube/certs/apiserver.crt + - --tls-private-key-file=/var/lib/minikube/certs/apiserver.key + image: registry.k8s.io/kube-apiserver:v1.26.3 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 8 + httpGet: + host: 192.168.49.2 + path: /livez + port: 8443 + scheme: HTTPS + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 15 + name: kube-apiserver + readinessProbe: + failureThreshold: 3 + httpGet: + host: 192.168.49.2 + path: /readyz + port: 8443 + scheme: HTTPS + periodSeconds: 1 + timeoutSeconds: 15 + resources: + requests: + cpu: 250m + startupProbe: + failureThreshold: 24 + httpGet: + host: 192.168.49.2 + path: /livez + port: 8443 + scheme: HTTPS + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 15 + volumeMounts: + # mount the socket + - name: socket + mountPath: /opt/trousseau-kms + # mount trousseau config file + - name: cfg + mountPath: /opt/cfg + - mountPath: /etc/ssl/certs + name: ca-certs + readOnly: true + - mountPath: /etc/ca-certificates + name: etc-ca-certificates + readOnly: true + - mountPath: /var/lib/minikube/certs + name: k8s-certs + readOnly: true + - mountPath: /usr/local/share/ca-certificates + name: usr-local-share-ca-certificates + readOnly: true + - mountPath: /usr/share/ca-certificates + name: usr-share-ca-certificates + readOnly: true + hostNetwork: true + priorityClassName: system-node-critical + securityContext: + seccompProfile: + type: RuntimeDefault + volumes: + # mount socket + - name: socket + hostPath: + path: /opt/trousseau-kms + # mount trosseau config file + - name: cfg + hostPath: + path: /opt/cfg + - hostPath: + path: /etc/ssl/certs + type: DirectoryOrCreate + name: ca-certs + - hostPath: + path: /etc/ca-certificates + type: DirectoryOrCreate + name: etc-ca-certificates + - hostPath: + path: /var/lib/minikube/certs + type: DirectoryOrCreate + name: k8s-certs + - hostPath: + path: /usr/local/share/ca-certificates + type: DirectoryOrCreate + name: usr-local-share-ca-certificates + - hostPath: + path: /usr/share/ca-certificates + type: DirectoryOrCreate + name: usr-share-ca-certificates diff --git a/k8s-minikube/files/trousseau.yml b/k8s-minikube/files/trousseau.yml new file mode 100644 index 0000000..68085c7 --- /dev/null +++ b/k8s-minikube/files/trousseau.yml @@ -0,0 +1,85 @@ +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: trousseau-kms-provider + namespace: kube-system + labels: + tier: control-plane + app: trousseau-kms-provider +spec: + selector: + matchLabels: + name: trousseau-kms-provider + template: + metadata: + labels: + name: trousseau-kms-provider + spec: + priorityClassName: system-cluster-critical + hostNetwork: true + containers: + - name: trousseau-kms-provider + image: ghcr.io/ondat/trousseau:v1.1.3 + imagePullPolicy: Always + env: + - name: VAULT_SKIP_VERIFY + value: "true" + args: + - -v=5 + - --config-file-path=/opt/trousseau/config.yaml + - --listen-addr=unix:///opt/trousseau-kms/vaultkms.socket + - --zap-encoder=json + - --v=3 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 0 + ports: + - containerPort: 8787 + protocol: TCP + # livenessProbe: + # httpGet: + # path: /healthz + # port: 8787 + # failureThreshold: 3 + # periodSeconds: 10 + # resources: + # requests: + # cpu: 50m + # memory: 64Mi + # limits: + # cpu: 300m + # memory: 256Mi + volumeMounts: + - name: trousseau-kms + mountPath: /opt/trousseau-kms + - name: trousseau-config + mountPath: /opt/trousseau/ + volumes: + - name: trousseau-kms + hostPath: + path: /opt/trousseau-kms + - name: trousseau-config + configMap: + name: trousseau-config + items: + - key: cfg + path: config.yaml + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: Exists + # tolerations: + # - key: node-role.kubernetes.io/control-plane + # operator: Exists + # effect: NoSchedule + # - key: node-role.kubernetes.io/etcd + # operator: Exists + # effect: NoExecute diff --git a/k8s-minikube/files/vault-policy.hcl b/k8s-minikube/files/vault-policy.hcl new file mode 100644 index 0000000..878f8c3 --- /dev/null +++ b/k8s-minikube/files/vault-policy.hcl @@ -0,0 +1,6 @@ +path "transit/encrypt/kms" { + capabilities = [ "update" ] +} +path "transit/decrypt/kms" { + capabilities = [ "update" ] +} diff --git a/k8s-minikube/templates/trousseau-config.yml.tmpl b/k8s-minikube/templates/trousseau-config.yml.tmpl new file mode 100644 index 0000000..8198d31 --- /dev/null +++ b/k8s-minikube/templates/trousseau-config.yml.tmpl @@ -0,0 +1,6 @@ +provider: vault +vault: + keynames: + - kms + address: https://host.minikube.internal + token: ${token} diff --git a/k8s-minikube/terraform/kubernetes.tf b/k8s-minikube/terraform/kubernetes.tf new file mode 100644 index 0000000..2a32ffb --- /dev/null +++ b/k8s-minikube/terraform/kubernetes.tf @@ -0,0 +1,25 @@ +resource "kubernetes_config_map" "this" { + count = var.kms_enabled ? 1 : 0 + + metadata { + name = "trousseau-config" + namespace = "kube-system" + } + + data = { + cfg = templatefile("${path.module}/../templates/trousseau-config.yml.tmpl", { + token = vault_token.this.client_token + }) + } + + depends_on = [minikube_cluster.docker] +} + +resource "kubectl_manifest" "secret_store" { + count = var.kms_enabled ? 1 : 0 + + + yaml_body = file("${path.module}/../files/trousseau.yml") + + depends_on = [kubernetes_config_map.this] +} diff --git a/k8s-minikube/terraform/main.tf b/k8s-minikube/terraform/minikube.tf similarity index 100% rename from k8s-minikube/terraform/main.tf rename to k8s-minikube/terraform/minikube.tf diff --git a/k8s-minikube/terraform/variables.tf b/k8s-minikube/terraform/variables.tf new file mode 100644 index 0000000..6d0d045 --- /dev/null +++ b/k8s-minikube/terraform/variables.tf @@ -0,0 +1,3 @@ +variable "kms_enabled" { + type = bool +} diff --git a/k8s-minikube/terraform/vault.tf b/k8s-minikube/terraform/vault.tf new file mode 100644 index 0000000..b88fef3 --- /dev/null +++ b/k8s-minikube/terraform/vault.tf @@ -0,0 +1,26 @@ +resource "vault_mount" "transit" { + path = "transit" + type = "transit" +} + +resource "vault_transit_secret_backend_key" "key" { + backend = vault_mount.transit.path + name = "kms" + + deletion_allowed = true +} + +resource "vault_policy" "kms" { + name = "kms" + + policy = file("${path.module}/../files/vault-policy.hcl") +} + +resource "vault_token" "this" { + policies = [vault_policy.kms.name] + + renewable = true + no_parent = true + period = "24h" + ttl = "24h" +} diff --git a/k8s-minikube/terraform/version.tf b/k8s-minikube/terraform/version.tf index 45a708a..ddd2ac2 100644 --- a/k8s-minikube/terraform/version.tf +++ b/k8s-minikube/terraform/version.tf @@ -10,5 +10,13 @@ terraform { source = "hashicorp/kubernetes" version = "2.25.2" } + vault = { + source = "hashicorp/vault" + version = "3.24.0" + } + kubectl = { + source = "gavinbunney/kubectl" + version = "1.14.0" + } } } diff --git a/main.tf b/main.tf index 1af30dd..9396e4e 100644 --- a/main.tf +++ b/main.tf @@ -42,6 +42,9 @@ module "kubernetes" { source = "./k8s-minikube/terraform" + kms_enabled = var.kubernetes.kms + + depends_on = [module.vault] } diff --git a/mkdocs.yml b/mkdocs.yml index 22d52bf..9ca06a7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -28,6 +28,7 @@ nav: - HAProxy: haproxy.md - Kubernetes: - Minikube: minikube.md + - KMS: kms.md - External Secrets Manager: esm.md - Vault Secrets Operator: vso.md - Vault Agent Injector: vai.md diff --git a/terraform.tfvars b/terraform.tfvars index 9e42602..afdef11 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -20,7 +20,7 @@ vault = { # Dyanmic DB Credentials databases = { - enabled = true + enabled = false # enable mysql db mysql = true @@ -31,6 +31,9 @@ kubernetes = { # wether to enable minikube deployment enabled = true + # enable kms plugin for secret encryption at rest + kms = false + # enable external secrets manager external_secrets_manager = true diff --git a/variables.tf b/variables.tf index 34e150f..e4e8fa4 100644 --- a/variables.tf +++ b/variables.tf @@ -24,6 +24,7 @@ variable "databases" { variable "kubernetes" { type = object({ enabled = optional(bool, true) + kms = optional(bool, false) external_secrets_manager = optional(bool, true) vault_secrets_operator = optional(bool, true) vault_agent_injector = optional(bool, true)