From c60ae3652a25d74b1d30b5584654c0e733c48822 Mon Sep 17 00:00:00 2001
From: Vannick Trinquier
Date: Tue, 21 Oct 2025 17:34:25 +0700
Subject: [PATCH] Adding hardened datasets for preventive and detective
Compliance Controls (#3410)
* Adding hardened datasets for preventive and detective Compliance Controls in stage 0 and stage 1 VPC-SC
* Move observability to factory file
* Update documentation
* Update local variable for use
* Update observability factory to use other module
* Add raw diagram file for hardened datasets
* Retrofit change
* Rename log_buckets context variable to be consistent across modules
* Update stage 0 documentation to mention hardened dataset
* Update customer ids list
* Update documentation, path to schema add ID to access level
* Comment organization policy gcp.resourceLocation by default
* Prevent duplicate key error by merging principal roles
* Adding ngfw roles files in hardened datasets
* Update script to validate files differences to support folder and datasets
* Format duplicate-diff python script
* Remove .config.yaml from duplicates
---------
Co-authored-by: Ludovico Magnocavallo
---
fast/stages/0-org-setup/README.md | 49 ++--
.../classic/organization/.config.yaml | 4 +-
.../0-org-setup/datasets/hardened/README.md | 269 ++++++++++++++++++
.../hardened/assets/diagram.excalidraw.gz | Bin 0 -> 2810 bytes
.../datasets/hardened/assets/diagram.png | Bin 0 -> 266836 bytes
.../datasets/hardened/defaults.yaml | 92 ++++++
.../hardened/organization/.config.yaml | 123 ++++++++
...contextmanagerDisableBridgePerimeters.yaml | 26 ++
...drunDisableEnvironmentVariablePattern.yaml | 27 ++
...cloudrunJobRequireBinaryAuthorization.yaml | 25 ++
...drunServiceRequireBinaryAuthorization.yaml | 25 ++
...oudsqlDisablePublicAuthorizedNetworks.yaml | 27 ++
...tom.cloudsqlEnforcePasswordComplexity.yaml | 26 ++
...custom.cloudsqlRequireAutomatedBackup.yaml | 25 ++
...tom.cloudsqlRequireMySQLDatabaseFlags.yaml | 30 ++
...om.cloudsqlRequirePointInTimeRecovery.yaml | 27 ++
...uirePostgreSQLDatabaseAdditionalFlags.yaml | 31 ++
...loudsqlRequirePostgreSQLDatabaseFlags.yaml | 36 +++
.../custom.cloudsqlRequireRootPassword.yaml | 25 ++
...cloudsqlRequireSQLServerDatabaseFlags.yaml | 35 +++
.../custom.cloudsqlRequireSSLConnection.yaml | 27 ++
.../custom.dnsAllowedSigningAlgorithms.yaml | 27 ++
.../custom.dnsRequireManageZoneDNSSEC.yaml | 27 ++
.../custom.dnsRequirePolicyLogging.yaml | 25 ++
...stom.firewallEnforcePolicyRuleLogging.yaml | 25 ++
.../custom.firewallEnforceRuleLogging.yaml | 33 +++
.../custom.firewallRestrictOpenWorldRule.yaml | 25 ++
.../custom.firewallRestrictRdpPolicyRule.yaml | 36 +++
.../custom.firewallRestrictRdpRule.yaml | 26 ++
.../custom.firewallRestrictSshPolicyRule.yaml | 36 +++
.../custom.firewallRestrictSshRule.yaml | 26 ++
.../custom.gkeAllowedNodePoolImages.yaml | 25 ++
.../custom.gkeAllowedReleaseChannels.yaml | 25 ++
.../custom.gkeDisableAlphaCluster.yaml | 26 ++
.../custom.gkeDisableKubernetesDashboard.yaml | 25 ++
.../custom.gkeDisableLegacyAbac.yaml | 25 ++
...tom.gkeDisableLegacyMetadataEndpoints.yaml | 26 ++
.../custom.gkeRequireCOSImage.yaml | 26 ++
.../custom.gkeRequireDataplaneV2.yaml | 25 ++
.../custom.gkeRequireGKEMetadataServer.yaml | 25 ++
.../custom.gkeRequireIntegrityMonitoring.yaml | 25 ++
.../custom.gkeRequireIntraNodeVisibility.yaml | 25 ++
...om.gkeRequireMasterAuthorizedNetworks.yaml | 26 ++
.../custom.gkeRequireMonitoring.yaml | 25 ++
.../custom.gkeRequireNodePoolAutoRepair.yaml | 25 ++
.../custom.gkeRequireNodePoolAutoUpgrade.yaml | 25 ++
...stom.gkeRequireNodePoolCMEKEncryption.yaml | 25 ++
.../custom.gkeRequireNodePoolSandbox.yaml | 26 ++
.../custom.gkeRequirePrivateEndpoint.yaml | 26 ++
.../custom.gkeRequireRegionalClusters.yaml | 25 ++
.../custom.gkeRequireSecureBoot.yaml | 25 ++
.../custom.gkeRequireVPCNativeCluster.yaml | 25 ++
.../custom.iamAllowedMembers.yaml | 29 ++
.../custom.iamDisablePublicBindings.yaml | 25 ++
.../custom.iamDisableRedisAdminRoles.yaml | 34 +++
.../custom.networkDisableTargetHTTPProxy.yaml | 25 ++
.../custom.networkDisableWeakSSLPolicy.yaml | 39 +++
.../custom.networkRequireCustomModeVpc.yaml | 24 ++
...tworkRequireSubnetPrivateGoogleAccess.yaml | 25 ++
...storageRequireBucketObjectVersionning.yaml | 25 ++
.../network_firewall_policies_admin.yaml | 24 ++
.../custom-roles/ngfw_enterprise_admin.yaml | 49 ++++
.../custom-roles/ngfw_enterprise_viewer.yaml | 35 +++
.../organization_admin_viewer.yaml | 34 +++
.../custom-roles/organization_iam_admin.yaml | 22 ++
.../custom-roles/project_iam_viewer.yaml | 24 ++
.../service_project_network_admin.yaml | 33 +++
.../custom-roles/storage_viewer.yaml | 33 +++
.../organization/custom-roles/tag_viewer.yaml | 26 ++
.../observability/auditConfigChanges.yaml | 76 +++++
.../observability/customRoleChanges.yaml | 78 +++++
.../observability/projectOwnershipChange.yaml | 82 ++++++
.../org-policies/accesscontextmanager.yaml | 24 ++
.../organization/org-policies/appengine.yaml | 24 ++
.../organization/org-policies/bigquery.yaml | 32 +++
.../organization/org-policies/cloudbuild.yaml | 35 +++
.../organization/org-policies/compute.yaml | 132 +++++++++
.../organization/org-policies/dns.yaml | 32 +++
.../org-policies/essentialcontacts.yaml | 36 +++
.../organization/org-policies/firewall.yaml | 32 +++
.../organization/org-policies/gcp.yaml | 29 ++
.../organization/org-policies/gke.yaml | 112 ++++++++
.../organization/org-policies/iam.yaml | 68 +++++
.../organization/org-policies/network.yaml | 50 ++++
.../organization/org-policies/serverless.yaml | 56 ++++
.../organization/org-policies/sql.yaml | 64 +++++
.../organization/org-policies/storage.yaml | 38 +++
.../organization/org-policies/vertexai.yaml | 38 +++
...RequireIngressInternalAndLoadBalancer.yaml | 25 ++
.../cloudfunctionsV1RequireVPCConnector.yaml | 23 ++
.../cloudrunRequireBinaryAuthorization.yaml | 26 ++
...RequireIngressInternalAndLoadBalancer.yaml | 25 ++
.../cloudsqlRequirePointInTimeRecovery.yaml | 24 ++
.../computeDisableNestedVirtualization.yaml | 23 ++
.../gkeDisableClientCertificateAuth.yaml | 24 ++
.../gkeRequireDataplaneV2.yaml | 24 ++
.../gkeRequireRegionalCluster.yaml | 23 ++
.../hardened/organization/tags/context.yaml | 23 ++
.../organization/tags/environment.yaml | 43 +++
.../organization/tags/org-policies.yaml | 25 ++
.../hardened/projects/core/billing-0.yaml | 29 ++
.../hardened/projects/core/iac-0.yaml | 179 ++++++++++++
.../hardened/projects/core/log-0.yaml | 35 +++
fast/stages/0-org-setup/organization.tf | 1 +
fast/stages/1-vpcsc/README.md | 16 +-
.../classic}/access-levels/geo.yaml | 3 +-
.../ingress-policies/fast-org-log-sinks.yaml | 2 +-
.../classic}/perimeters/default.yaml | 2 +-
.../classic}/restricted-services.yaml | 0
.../datasets/hardened/access-levels/geo.yaml | 23 ++
.../ingress-policies/fast-org-log-sinks.yaml | 26 ++
.../datasets/hardened/perimeters/default.yaml | 25 ++
.../hardened/restricted-services.yaml | 87 ++++++
fast/stages/1-vpcsc/variables.tf | 10 +-
.../3-data-platform-dev/data-domains.tf | 14 +-
fast/stages/3-data-platform-dev/main.tf | 7 +-
fast/stages/CLEANUP.md | 8 +
.../organization/scc-sha-custom-modules.tf | 6 +
modules/project-factory/README.md | 10 +-
modules/project-factory/projects.tf | 5 +
modules/project-factory/variables.tf | 1 +
modules/project/README.md | 2 +-
modules/project/logging-metrics.tf | 2 +-
modules/project/variables.tf | 2 +-
tools/duplicate-diff.py | 85 +++++-
125 files changed, 4120 insertions(+), 58 deletions(-)
create mode 100644 fast/stages/0-org-setup/datasets/hardened/README.md
create mode 100644 fast/stages/0-org-setup/datasets/hardened/assets/diagram.excalidraw.gz
create mode 100644 fast/stages/0-org-setup/datasets/hardened/assets/diagram.png
create mode 100644 fast/stages/0-org-setup/datasets/hardened/defaults.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/.config.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.accesscontextmanagerDisableBridgePerimeters.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunDisableEnvironmentVariablePattern.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunJobRequireBinaryAuthorization.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunServiceRequireBinaryAuthorization.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlDisablePublicAuthorizedNetworks.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlEnforcePasswordComplexity.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireAutomatedBackup.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireMySQLDatabaseFlags.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequirePointInTimeRecovery.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequirePostgreSQLDatabaseAdditionalFlags.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequirePostgreSQLDatabaseFlags.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireRootPassword.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireSQLServerDatabaseFlags.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireSSLConnection.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dnsAllowedSigningAlgorithms.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dnsRequireManageZoneDNSSEC.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dnsRequirePolicyLogging.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallEnforcePolicyRuleLogging.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallEnforceRuleLogging.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictOpenWorldRule.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictRdpPolicyRule.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictRdpRule.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSshPolicyRule.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSshRule.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeAllowedNodePoolImages.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeAllowedReleaseChannels.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeDisableAlphaCluster.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeDisableKubernetesDashboard.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeDisableLegacyAbac.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeDisableLegacyMetadataEndpoints.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireCOSImage.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireDataplaneV2.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireGKEMetadataServer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireIntegrityMonitoring.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireIntraNodeVisibility.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireMasterAuthorizedNetworks.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireMonitoring.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireNodePoolAutoRepair.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireNodePoolAutoUpgrade.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireNodePoolCMEKEncryption.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireNodePoolSandbox.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequirePrivateEndpoint.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireRegionalClusters.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireSecureBoot.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireVPCNativeCluster.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamAllowedMembers.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisablePublicBindings.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableRedisAdminRoles.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.networkDisableTargetHTTPProxy.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.networkDisableWeakSSLPolicy.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.networkRequireCustomModeVpc.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.networkRequireSubnetPrivateGoogleAccess.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.storageRequireBucketObjectVersionning.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/network_firewall_policies_admin.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/ngfw_enterprise_admin.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/ngfw_enterprise_viewer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/organization_admin_viewer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/organization_iam_admin.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/project_iam_viewer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/service_project_network_admin.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/storage_viewer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/custom-roles/tag_viewer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/observability/auditConfigChanges.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/observability/customRoleChanges.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/observability/projectOwnershipChange.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/accesscontextmanager.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/appengine.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/bigquery.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/cloudbuild.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/compute.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/dns.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/essentialcontacts.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/firewall.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gcp.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gke.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/iam.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/network.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serverless.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/sql.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/storage.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/org-policies/vertexai.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudfunctionsV1RequireIngressInternalAndLoadBalancer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudfunctionsV1RequireVPCConnector.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunRequireBinaryAuthorization.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunRequireIngressInternalAndLoadBalancer.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudsqlRequirePointInTimeRecovery.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/computeDisableNestedVirtualization.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeDisableClientCertificateAuth.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireDataplaneV2.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireRegionalCluster.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/tags/context.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/tags/environment.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/organization/tags/org-policies.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/projects/core/billing-0.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/projects/core/iac-0.yaml
create mode 100644 fast/stages/0-org-setup/datasets/hardened/projects/core/log-0.yaml
rename fast/stages/1-vpcsc/{data => datasets/classic}/access-levels/geo.yaml (90%)
rename fast/stages/1-vpcsc/{data => datasets/classic}/ingress-policies/fast-org-log-sinks.yaml (90%)
rename fast/stages/1-vpcsc/{data => datasets/classic}/perimeters/default.yaml (91%)
rename fast/stages/1-vpcsc/{data => datasets/classic}/restricted-services.yaml (100%)
create mode 100644 fast/stages/1-vpcsc/datasets/hardened/access-levels/geo.yaml
create mode 100644 fast/stages/1-vpcsc/datasets/hardened/ingress-policies/fast-org-log-sinks.yaml
create mode 100644 fast/stages/1-vpcsc/datasets/hardened/perimeters/default.yaml
create mode 100644 fast/stages/1-vpcsc/datasets/hardened/restricted-services.yaml
diff --git a/fast/stages/0-org-setup/README.md b/fast/stages/0-org-setup/README.md
index ef0b6cc21..13607dc66 100644
--- a/fast/stages/0-org-setup/README.md
+++ b/fast/stages/0-org-setup/README.md
@@ -13,6 +13,7 @@
- [Provider setup and final apply cycle](#provider-setup-and-final-apply-cycle)
- [Default factory datasets](#default-factory-datasets)
- ["Classic FAST" dataset](#classic-fast-dataset)
+ - ["Hardened" dataset](#hardened-dataset)
- ["Minimal" dataset (TBD)](#minimal-dataset-tbd)
- ["Tenants" dataset (TBD)](#tenants-dataset-tbd)
- [Detailed configuration](#detailed-configuration)
@@ -77,12 +78,12 @@ If this configuration matches requirements, no changes are necessary at this sta
# create a file named 0-org-setup.auto.tfvars containing the following
# and replace paths by pointing them to the desired data folder
factories_config = {
- billing_accounts = "data/billing-accounts"
- cicd = "data/cicd.yaml"
- defaults = "data/defaults.yaml"
- folders = "data/folders"
- organization = "data/organization"
- projects = "data/projects"
+ billing_accounts = "datasets/classic/billing-accounts"
+ cicd = "datasets/classic/cicd.yaml"
+ defaults = "datasets/classic/defaults.yaml"
+ folders = "datasets/classic/folders"
+ organization = "datasets/classic/organization"
+ projects = "datasets/classic/projects"
}
```
@@ -253,6 +254,12 @@ The organizational layout mirrors the consolidated FAST one, where shared infras
+### "Hardened" dataset
+
+This dataset implements a hardened design focusing on strict security and compliance requirements. It expands on the "Classic FAST" layout by incorporating more advanced and granular preventive and detective controls from the start.
+
+This dataset provides a stronger and centrally-managed security baseline, ensuring that projects and resources deployed adhere to stricter security and compliance from inception. It includes both **preventive controls** (organization policies and custom constraints) and **detective controls** (monitoring alerts and Security Command Center custom module detectors). For more details on the content of this hardened dataset and the various controls provisioned, refer to the [hardened dataset documentation](./datasets/hardened/README.md).
+
### "Minimal" dataset (TBD)
This dataset is meant as a minimalistic starting point for organizations where a security baseline and a project factory are all that's needed, at least initially. The design can then organically grow to support more functionality, converging to the Classic or other types of layouts.
@@ -293,28 +300,28 @@ The resources created by this stage are controlled by several factories, which p
The default paths point to the dataset in the `data` folder which deploys a FAST-compliant configuration. These are the available factories in this stage, with file-level factories based on a single YAML file, and folder-level factories based on sets of YAML files contained within a filesystem folder:
-- **defaults** (`data/defaults.yaml`) \
+- **defaults** (`datasets/classic/defaults.yaml`) \
file-level factory to define stage defaults (organization id, locations, prefix, etc.) and static context mappings
-- **billing_accounts** (`data/billing-accounts`) \
+- **billing_accounts** (`datasets/classic/billing-accounts`) \
folder-level factory where each YAML file defines billing-account level IAM for one billing account; only used for externally managed accounts
-- **organization** (`data/organization/.config.yaml`) \
+- **organization** (`datasets/classic/organization/.config.yaml`) \
file-level factory to define organization IAM and log sinks
- - **custom roles** (`data/organization/custom-roles`) \
+ - **custom roles** (`datasets/classic/organization/custom-roles`) \
folder-level factory to define organization-level custom roles
- - **org policies** (`data/organization/org-policies`) \
+ - **org policies** (`datasets/classic/organization/org-policies`) \
folder-level factory to define organization-level org policies
- - **tags** (`data/organization/tags`) \
+ - **tags** (`datasets/classic/organization/tags`) \
folder-level factory to define organization-level resource management tags
-- **folders** (`data/folders`) \
+- **folders** (`datasets/classic/folders`) \
folder-level factory to define the resource management hierarchy and individual folder attributes (IAM, org policies, tag bindings, etc.); also supports defining folder-level IaC resources
-- **projects** (`data/projects`) \
+- **projects** (`datasets/classic/projects`) \
folder-level factory to define projects and their attributes (projejct factory)
-- **cicd** (`data/cicd.yaml`) \
+- **cicd** (`datasets/classic/cicd.yaml`) \
file-level factory to define CI/CD configurations for this and subsequent stages
### Defaults configuration
-The prerequisite configuration for this stage is done via a `defaults.yaml` file, which implements part or all of the [relevant JSON schema](./schemas/defaults.schema.json). The location of the file defaults to `data/defaults.yaml` but can be easily changed via the `factories_config.defaults` variable.
+The prerequisite configuration for this stage is done via a `defaults.yaml` file, which implements part or all of the [relevant JSON schema](./schemas/defaults.schema.json). The location of the file defaults to `datasets/classic/defaults.yaml` but can be easily changed via the `factories_config.defaults` variable.
This is a commented example of a defaults file, showing a minimal working configuration. Refer to the YAML schema for all available options.
@@ -422,7 +429,7 @@ Principal expansion leverages the `$iam_principals:` context, which is populated
```yaml
# example principal-level context interpolation
-# file: data/organization/.config.yaml
+# file: datasets/classic/organization/.config.yaml
iam_by_principals:
# statically defined principal (via defaults.yaml)
$iam_principals:gcp-organization-admins:
@@ -445,7 +452,7 @@ Log sinks can refer to project-level destination via different contexts.
```yaml
# example log sinks showing different destination contexts
-# file: data/organization/.config.yaml
+# file: datasets/classic/organization/.config.yaml
logging:
storage_location: $locations:default
sinks:
@@ -475,7 +482,7 @@ Context-based expansion is not limited to the organization's `.config.yaml` file
```yaml
# example usage of context interpolation in tag values IAM
-# file: data/organization/tags/environment.yaml
+# file: datasets/classic/organization/tags/environment.yaml
description: "Organization-level environments."
values:
development:
@@ -515,7 +522,7 @@ The folder hierarchy is managed via a filesystem tree of YAML configuration file
The default dataset implements a classic FAST layout, with top-level folders for stage 2 and stage 3, and can be easily tweaked by adding or removing any needed folder.
```bash
-data/folders
+datasets/classic/folders
├── networking
│ ├── .config.yaml
│ ├── dev
@@ -542,7 +549,7 @@ As with the factories described above, context replacements can be used in folde
As with other examples before, the main use case is to infer IAM principals from either the static or internally defined context. One additional context which is often useful here is tag values, which allows defining a scope for organization-level conditional IAM bindings or org policies.
```yaml
-# file: data/folders/teams/.config.yaml
+# file: datasets/classic/folders/teams/.config.yaml
name: Teams
iam_by_principals:
$iam_principals:service_accounts/iac-0/iac-pf-rw:
diff --git a/fast/stages/0-org-setup/datasets/classic/organization/.config.yaml b/fast/stages/0-org-setup/datasets/classic/organization/.config.yaml
index d1bb3e90a..1677e3eee 100644
--- a/fast/stages/0-org-setup/datasets/classic/organization/.config.yaml
+++ b/fast/stages/0-org-setup/datasets/classic/organization/.config.yaml
@@ -14,7 +14,7 @@
# TODO: data access logs
-# yaml-language-server: $schema=../../schemas/organization.schema.json
+# yaml-language-server: $schema=../../../schemas/organization.schema.json
id: $defaults:organization/id
contacts:
@@ -119,4 +119,4 @@ logging:
# these are internally merged with IAM by principal
iam:
# reset default role on new organizations
- roles/billing.creator: []
+ roles/billing.creator: []
\ No newline at end of file
diff --git a/fast/stages/0-org-setup/datasets/hardened/README.md b/fast/stages/0-org-setup/datasets/hardened/README.md
new file mode 100644
index 000000000..9d29d6bb1
--- /dev/null
+++ b/fast/stages/0-org-setup/datasets/hardened/README.md
@@ -0,0 +1,269 @@
+# Hardened Dataset for FAST Organization Setup
+
+This hardened dataset contains a set of compliance controls that can be applied to your Google Cloud environment.
+It includes preventive controls (custom constraints and organization policies) and detective controls (Security Command Center custom module detectors and observability alerts).
+
+## Prerequisites
+
+This dataset configuration configures a set of compliance and security controls based on recommendations gathered from various customer engagements.
+
+The **preventive controls** are based on a recommended list of organization policies and custom organization policies. Many of these help enforce CIS Benchmarks and PCI-DSS requirements and are broadly applicable.
+
+The **detective controls** are based on the following:
+ - Security Health Analytics (SHA) and Custom SHA modules: These require **a Security Command Center (SCC) Premium or Enterprise subscription.**
+ - Log-based metrics and Monitoring Alerts: These can be used by any organization.
+
+## High level architecture
+
+The dataset contains the configurations for various controls, which are consumed by the Terraform modules using the factory configuration.
+
+| | Organization Policies | Custom Constraint | Monitoring Alerts | SCC SHA | SCC Custom SHA |
+|:-----------------------------------: |:---------------------: |:-----------------------: |:------------------: |:--------------------------------------------: |:---------------------------: |
+| **Type of controls** | Preventive | Preventive | Detective | Detective | Detective |
+| **Factory folder** | data/org-policies | data/custom-constraints | data/observability | Already included as part of SCC Subscription | data/scc-custom-sha-modules |
+| **Requires SCC Premium or Enterprise ?** | NO | NO | NO | YES | YES |
+
+The diagram below shows the relationships between the components:
+
+
+
+## Usage
+
+To use this `hardened` dataset, create a `0-org-setup.auto.tfvars` file in the `fast/stages/0-org-setup` directory and override the `factories_config` variable as shown below:
+
+```tfvars
+factories_config = {
+ organization = "datasets/hardened/organization"
+}
+```
+
+For organizations not using **SCC Premium or Enterprise**, the following error will appear:
+```
+╷
+│ Error: Error creating OrganizationSecurityHealthAnalyticsCustomModule: googleapi: Error 403: Security Command Center Management API has not been used in project 111111111111 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/securitycentermanagement.googleapis.com/overview?project=111111111111 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
+```
+
+In that case, the controls placed in the `organization/scc-sha-custom-modules` folder need to be removed to ensure they are provisionned.
+
+## Controls
+
+### Preventive Controls
+
+#### Organization Policies
+| Policy | Description | Compliance Mapping |
+|---|---|---|
+| `ainotebooks.disableFileDownloads` | Prevent file downloads on new Vertex AI Workbench instances. | |
+| `ainotebooks.disableRootAccess` | Prevent root access on new Vertex AI Workbench user-managed notebooks and instances. | |
+| `ainotebooks.restrictPublicIp` | Restrict public IP access on new Vertex AI Workbench notebooks and instances. | |
+| `ainotebooks.restrictVpcNetworks` | Restrict VPC networks on new Vertex AI Workbench instances. | |
+| `appengine.disableCodeDownload` | Prevent the download of source code from App Engine. | |
+| `bigquery.disableBQOmniAWS` | Prevent the creation of BigQuery Omni tables for AWS. | |
+| `bigquery.disableBQOmniAzure` | Prevent the creation of BigQuery Omni tables for Azure. | |
+| `cloudbuild.allowedIntegrations` | Restrict Cloud Build integrations to an approved list. | |
+| `cloudbuild.allowedWorkerPools` | Restrict Cloud Build jobs to an authorized list of worker pools. | |
+| `cloudbuild.disableCreateDefaultServiceAccount` | Prevent Default Service Account for Cloud Build to be created | |
+| `cloudfunctions.allowedVpcConnectorEgressSettings` | Ensure Cloud Functions Gen1 only allows internal and load balancer traffic. | |
+| `cloudfunctions.requireVPCConnector` | Ensure Cloud Functions Gen1 are configured with a VPC connector. | |
+| `compute.disableGuestAttributesAccess` | Prevent the use of Guest Attributes for Compute Engine instance metadata. | |
+| `compute.disableInternetNetworkEndpointGroup` | Prevent configuration of internet network endpoint groups. | |
+| `compute.disableNestedVirtualization` | Prevent the creation of Compute Engine instances with nested virtualization enabled. | |
+| `compute.disableSerialPortAccess` | Prevent the enablement of serial port access for VM instances. | **CIS Controls 8.0**: 4.8
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R5**: CM-6, CM-7
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC6.6.1, CC6.6.3, CC6.6.4 |
+| `compute.disableVpcExternalIpv6` | Prevent configuration of subnets with external IPv6 ranges. | |
+| `compute.managed.blockPreviewFeatures` | Ensures that preview feature updates are blocked unless explicitly allowed | |
+| `compute.requireOsLogin` | Enforce the use of OS Login for all Compute Engine instances. | **CIS Controls 8.0**: 5.6, 6.7
**PCI-DSS 4.0**: 1.2.5,
2.2.4
6.4.1
**NIST 800-53 R5**: AC-2
**ISO-2700-1 v2022**: A.5.15
**SOC2 v2017**: CC6.1.4, CC6.1.6, CC6.1.8, CC6.1.9 |
+| `compute.requireShieldedVm` | Enforce the use of Shielded VM for all Compute Engine instances. | |
+| `compute.requireSslPolicy` | Prevent the use of weak cipher suites and TLS versions on HTTPS and SSL Proxy load balancers. | **NIST 800-53 R4**: SC-7
**ISO-2700-1 v2013**: A.14.1.3 |
+| `compute.restrictDedicatedInterconnectUsage` | Restrict the use of Dedicated Interconnect. | |
+| `compute.restrictLoadBalancerCreationForTypes` | Restrict the creation of load balancers based on type. | |
+| `compute.restrictPartnerInterconnectUsage` | Restrict the use of Partner Interconnect. | |
+| `compute.restrictProtocolForwardingCreationForTypes` | Restrict the creation of forwarding rules based on type. | |
+| `compute.restrictVpcPeering` | Restrict the use of VPC peering. | |
+| `compute.setNewProjectDefaultToZonalDNSOnly` | Ensure project created use Zonal DNS instead of global. | |
+| `compute.skipDefaultNetworkCreation` | Prevent the automatic creation of the default VPC network in new projects. | **CIS Controls 8.0**: 4.2
**NIST 800-53 R5**: AC-18, CM-2, CM-6, CM-7, CM-9
**NIST Cybersecurity Framework 1.0**: PR-IP-1
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC5.2.2
**Cloud Controls Matrix 4**: ISV-04 |
+| `compute.trustedImageProjects` | Restrict the use of VM images to an authorized list of projects. | |
+| `compute.vmExternalIpAccess` | Prevent Compute Engine instances from having public IP addresses. | **CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R4**: CA-3, SC-7
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 |
+| `container.managed.disableABAC` | Require that Attribute-Based Access Control is disabled | |
+| `container.managed.disableLegacyClientCertificateIssuance` | Prevent the use of legacy authentication methods for GKE API servers. | **CIS for GKE 1.5**: 2.1.1
5.8.1
**PCI-DSS 4.0**: 4.1 |
+| `container.managed.enableCloudLogging` | Enforce that GKE clusters logging is enabled | **CIS for GKE 1.5**: 5.7.1
**PCI-DSS 4.0**: 10.2 |
+| `container.managed.enableNetworkPolicy` | Enforce that GKE clusters are configured with Network Policy enabled | **CIS for GKE 1.5**: 5.6.7
**PCI-DSS 4.0**: 1.2,1.1,1.4
**ISO-2700-1 v2013**: A.13.1.1 |
+| `container.managed.enablePrivateNodes` | Enforce that GKE clusters are created as private clusters with private nodes | **CIS for GKE 1.5**: 5.6.5
**PCI-DSS 4.0**: 1.3.1 |
+| `container.managed.enableShieldedNodes` | Enforce that GKE nodes is configured with shielded GKE nodes | **CIS for GKE 1.5**: 5.5.5 |
+| `container.managed.enableWorkloadIdentityFederation` | Enforce that GKE clusters are enabled with Workload Identity | **CIS for GKE 1.5**: 5.2.2
**PCI-DSS 4.0**: 7.2.2 |
+| `essentialcontacts.allowedContactDomains` | Restrict essential contact domains to an authorized list. | |
+| `gcp.restrictTLSCipherSuites` | Prevent the use of weak cipher suites and TLS versions on HTTPS and SSL Proxy load balancers. | **NIST 800-53 R4**: SC-7
**ISO-2700-1 v2013**: A.14.1.3 |
+| `gcp.restrictTLSVersion` | Prevent the use of weak cipher suites and TLS versions on HTTPS and SSL Proxy load balancers. | **NIST 800-53 R4**: SC-7
**ISO-2700-1 v2013**: A.14.1.3 |
+| `iam.allowedPolicyMemberDomains` | Restrict domain sharing to authorized domains. | **NIST 800-53 R4**: AC-3
**ISO-2700-1 v2013**: A.9.2.3 |
+| `iam.automaticIamGrantsForDefaultServiceAccounts` | Prevent the automatic granting of IAM roles to default service accounts. | **PCI-DSS 4.0**: 2.2.2
2.3.1 |
+| `iam.disableAuditLoggingExemption` | Prevent the use of audit logging exemptions. Detect also if audit logging are has been disabled. | |
+| `iam.disableServiceAccountKeyCreation` | Enforce the use of only GCP-managed service account keys. | |
+| `iam.disableServiceAccountKeyUpload` | Prevent the uploading of service account keys. | |
+| `iam.managed.disableServiceAccountApiKeyCreation` | Prevent the creation of service account API key bindings. | |
+| `iam.serviceAccountKeyExposureResponse` | Enforce Google to disable the service keys if a service account linked key is detected to be exposed publicly. | |
+| `iam.workloadIdentityPoolAwsAccounts` | Prevent creation of workload identity pools using AWS accounts, except if expliicitely allowed. | |
+| `iam.workloadIdentityPoolProviders` | Prevent creation of any workload identity pools except if expliicitely allowed. | |
+| `run.allowedBinaryAuthorizationPolicies` | Restrict Cloud Run services and jobs to an authorized list of Binary Authorization policies. | |
+| `run.allowedIngress` | Ensure Cloud Run services only allow internal and load balancer traffic. | |
+| `run.allowedVPCEgress` | Ensure all traffic from Cloud Run services and jobs is routed through a VPC connector. | |
+| `run.managed.requireInvokerIam` | Enforce an IAM invoker check for Cloud Run services. | |
+| `sql.restrictAuthorizedNetworks` | Prevent the ability to add Authorized Networks for unproxied database access to Cloud SQL instances. | |
+| `sql.restrictPublicIp` | Ensure That Cloud SQL Database Instances Do Not Have Public IPs | **CIS Controls 8.0**: 3.3, 4.6
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MA-4, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.2, CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 |
+| `storage.publicAccessPrevention` | Prevent anonymous or public access to Cloud Storage buckets. | **CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R4**: AC-2
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2013**: A.14.1.3, A.8.2.3
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 |
+| `storage.restrictAuthTypes` | Restrict authentication types for Cloud Storage. | |
+| `storage.secureHttpTransport` | Restrict unencrypted HTTP access to Cloud Storage. | |
+| `storage.uniformBucketLevelAccess` | Enforce the enablement of uniform bucket-level access to Cloud Storage buckets. | **CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 |
+
+**Note:** For organizations with strict requirements to ensure all resources are created and stored within specific geographic regions (e.g., for data sovereignty or regulatory compliance), the `gcp.resourceLocations` Organization Policy present in file [gcp.yaml](organization/org-policies/gcp.yaml) can be enabled.
+
+#### Custom Constraints
+| Constraint | Description | Compliance Mapping |
+|---|---|---|
+| `accesscontextmanagerDisableBridgePerimeters` | Ensure no perimeter bridges are used. Instead, use ingress and egress rules. | |
+| `cloudrunDisableEnvironmentVariablePattern` | Prevent secrets from being stored in Cloud Run environment variables. | |
+| `cloudsqlDisablePublicAuthorizedNetworks` | Ensure That Cloud SQL Database Instances Do Not Implicitly Whitelist All Public IP Addresses | **CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R4**: CA-3, SC-7
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2013**: A.13.1.3, A.14.1.3, A.8.2.3
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 |
+| `cloudsqlEnforcePasswordComplexity` | Enforce password complexity for Cloud SQL instance users. | |
+| `cloudsqlRequireAutomatedBackup` | Ensure That Cloud SQL Database Instances Are Configured With Automated Backups | **CIS Controls 8.0**: 11.2
**NIST 800-53 R4**: CP-9
**NIST 800-53 R5**: CP-10, CP-9
**NIST Cybersecurity Framework 1.0**: PR-IP-4
**ISO-2700-1 v2013**: A.12.3.1
**ISO-2700-1 v2022**: A.8.13
**HIPAA**: 164.308(a)(7)(ii) |
+| `cloudsqlRequireMySQLDatabaseFlags` | Ensure ‘Skip_show_database’ Database Flag for Cloud SQL MySQL Instance Is Set to ‘On’ | **CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 |
+| `cloudsqlRequirePointInTimeRecovery` | Enforce point-in-time recovery for all Cloud SQL backup configurations. | |
+| `cloudsqlRequirePostgreSQLDatabaseFlags` | Ensure That the ‘Log_connections’ Database Flag for Cloud SQL PostgreSQL Instance Is Set to ‘On’ | **CIS Controls 8.0**: 8.5
**PCI-DSS 4.0**: 10.2.1, 10.2.1.2, 10.2.1.5, 9.4.5
**NIST 800-53 R5**: AU-12, AU-3, AU-7
**NIST Cybersecurity Framework 1.0**: DE-AE-3, DE-CM-1
**ISO-2700-1 v2022**: A.5.28, A.8.15
**SOC2 v2017**: CC5.2.3, CC7.2.1, CC7.2.2, CC7.2.3
**Cloud Controls Matrix 4**: DSP-17 |
+| `cloudsqlRequireRootPassword` | Ensure That a MySQL Database Instance Does Not Allow Anyone To Connect With Administrative Privileges | **NIST 800-53 R4**: AC-3
**ISO-2700-1 v2013**: A.8.2.3, A.9.4.2
**ISO-2700-1 v2022**: A.8.5 |
+| `cloudsqlRequireSQLServerDatabaseFlags` | Ensure 'external scripts enabled' database flag for Cloud SQL SQL Server instance is set to 'off' | **CIS Controls 8.0**: 2.7
**PCI-DSS 4.0**: 1.2.5, 2.2.4, 6.4.3
**NIST 800-53 R5**: CM-7, SI-7
**NIST Cybersecurity Framework 1.0**: PR-IP-1, PR-PT-3
**SOC2 v2017**: CC5.2.1, CC5.2.2, CC5.2.3, CC5.2.4 |
+| `cloudsqlRequireSSLConnection` | Ensure That the Cloud SQL Database Instance Requires All Incoming Connections To Use SSL | **NIST 800-53 R4**: SC-7
**ISO-2700-1 v2013**: A.13.2.1, A.14.1.3, A.8.2.3 |
+| `dnsAllowedSigningAlgorithms` | Prevent the use of the RSASHA1 algorithm for the Key-Signing Key in Cloud DNS DNSSEC. | **PCI-DSS 4.0**: 1.1.1, 1.2.1, 1.2.6, 1.2.7, 1.4.2, 1.5.1, 2.1.1, 2.2.1
**NIST 800-53 R4**: 4.2
**NIST 800-53 R5**: AC-18, CM-2, CM-6, CM-7, CM-9
**NIST Cybersecurity Framework 1.0**: PR-IP-1
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC5.2.2
**Cloud Controls Matrix 4**: IVS-04 |
+| `dnsRequireManageZoneDNSSEC` | Enforce the enablement of DNSSEC for all Cloud DNS zones. | **CIS Controls 8.0**: 4.2
**PCI-DSS 4.0**: 1.1.1, 1.2.1, 1.2.6, 1.2.7, 1.4.2, 1.5.1, 2.1.1, 2.2.1
**NIST 800-53 R5**: AC-18, CM-2, CM-6, CM-7, CM-9
**NIST Cybersecurity Framework 1.0**: PR-IP-1
**ISO-2700-1 v2013**: A.8.2.3
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC5.2.2
**Cloud Controls Matrix 4**: ISV-04 |
+| `dnsRequirePolicyLogging` | Enforce the enablement of Cloud DNS logging for all VPC networks. | **PCI-DSS 4.0**: 10.4.1, 10.4.1.1, 10.4.2, 10.4.3
**NIST 800-53 R5**: AU-6, AU-7
**NIST Cybersecurity Framework 1.0**: DE-AE-2, PR-PT-1, RS-AN-1
**ISO-2700-1 v2022**: A.5.25
**SOC2 v2017**: CC4.1.1, CC4.1.2, CC4.1.3, CC4.1.4, CC4.1.5, CC4.1.6, CC4.1.7, CC4.1.8, CC7.3.1, CC7.3.2, CC7.3.3, CC7.3.4, CC7.3.5
**HIPAA**: 164.308(a)(1)(ii), 164.312(b)
**Cloud Controls Matrix 4**: LOG-05 |
+| `firewallRestrictOpenWorldRule` | Prevent the creation of VPC firewall rules with a source or destination of `0.0.0.0/0`. | |
+| `firewallRestrictRdpPolicyRule` | Prevent RDP access from the internet via firewall policies. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 |
+| `firewallRestrictSshPolicyRule` | Prevent SSH access from the internet via firewall policies. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 |
+| `gkeAllowedNodePoolImages` | Enforce that GKE nodes are using authorized node images | **CIS for GKE 1.5**: 5.5.1
**PCI-DSS 4.0**: 2.2.6, 5.2, 6.2.1 |
+| `gkeAllowedReleaseChannels` | Enfore that GKE cluster are using authorized release channels | **CIS for GKE 1.5**: 5.5.4 |
+| `gkeDisableAlphaCluster` | Prevent the use of alpha features for GKE clusters in production workloads. | **CIS for GKE 1.5**: 5.10.2 |
+| `gkeDisableKubernetesDashboard` | Prevent the enablement of the GKE Web UI dashboard. | **CIS for GKE 1.5**: 5.10.1
**PCI-DSS 4.0**: 6.4 |
+| `gkeDisableLegacyAbac` | Enforce that GKE clusters is configured with no legacy ABAC enabled | **CIS for GKE 1.5**: 5.8.3
**PCI-DSS 4.0**: 4.1 |
+| `gkeDisableLegacyMetadataEndpoints` | Enforce that GKE clusters are created with legacy metadata endpoints disabled | **CIS for GKE 1.5**: 5.4.1 |
+| `gkeRequireCOSImage` | Enforce the nodes pool are using Container-Optimized OS for running containers | **PCI-DSS 4.0**: 2.2.6 |
+| `gkeRequireDataplaneV2` | Enforce that the GKE clusters is configured to use dataplane v2 | |
+| `gkeRequireGKEMetadataServer` | Enforce that GKE clusters are configured with GKE metadata server enabled | **CIS for GKE 1.5**: 5.4.2 |
+| `gkeRequireIntegrityMonitoring` | Enforce that GKE nodes are configured with integrity monitoring enabled | **CIS for GKE 1.5**: 5.5.6 |
+| `gkeRequireMonitoring` | Enforce that GKE clusters monitoring is enabled | **CIS for GKE 1.5**: 5.7.1
**PCI-DSS 4.0**: 10.2 |
+| `gkeRequireNodePoolAutoRepair` | Enforce that GKE clusters are configured with node auto-repair enabled | **CIS for GKE 1.5**: 5.5.2
**PCI-DSS 4.0**: 2.2.6 |
+| `gkeRequireNodePoolAutoUpgrade` | Enforce that GKE clusters are configured with node auto-upgrade enabled | **CIS for GKE 1.5**: 5.5.3
**PCI-DSS 4.0**: 2.2.6 |
+| `gkeRequireRegionalClusters` | Enforce the creation of regional GKE clusters | |
+| `gkeRequireSecureBoot` | Enforce that GKE nodes are configured with secure boot enabled | **CIS for GKE 1.5**: 5.5.7 |
+| `gkeRequireVPCNativeCluster` | Enforce that GKE clusters are created with VPC-native | **CIS for GKE 1.5**: 5.6.2
**PCI-DSS 4.0**: 1.4.3 |
+| `iamDisablePublicBindings` | Ensure That BigQuery Datasets Are Not Anonymously or Publicly Accessible | **CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R4**: AC-2
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2013**: A.14.1.3, A.8.2.3
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 |
+| `networkDisableTargetHTTPProxy` | Prevent the use of weak SSL policies on HTTPS and SSL Proxy load balancers. | |
+| `networkDisableWeakSSLPolicy` | Prevent the use of weak SSL policies on HTTPS and SSL Proxy load balancers. | |
+| `networkRequireCustomModeVpc` | Ensure That the Default Network Does Not Exist in a Project | **CIS for GKE 1.5**: 3.1
**CIS Controls 8.0**: 4.2
**PCI-DSS 4.0**: 1.1.1, 1.2.1, 1.2.6, 1.2.7, 1.4.2, 1.5.1, 2.1.1, 2.2.1
**NIST 800-53 R5**: AC-18, CM-2, CM-6, CM-7, CM-9
**NIST Cybersecurity Framework 1.0**: PR-IP-1
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC5.2.2
**Cloud Controls Matrix 4**: ISV-04 |
+| `networkRequireSubnetPrivateGoogleAccess` | Enforce Private Google Access for all VPC network subnets. | |
+
+
+### Detective Controls
+
+#### SCC Built-in Modules Detectors
+SCC SHA Detectors are available only for organization have subscribed to SCC Premium or Enterprise. Refer to https://cloud.google.com/security-command-center/docs/service-tiers for more information.
+
+
+Complete list of built-in SCC SHA detectors is available here https://cloud.google.com/security-command-center/docs/concepts-vulnerabilities-findings.
+
+
+#### SCC Custom Modules Detectors
+SCC Custom SHA Detectors are available only for organization have subscribed to SCC Premium or Enterprise. Refer to https://cloud.google.com/security-command-center/docs/service-tiers for more information.
+
+
+| Module | Description | Compliance Mapping |
+|---|---|---|
+| `cloudfunctionsV1RequireIngressInternalAndLoadBalancer` | Ensure Cloud Functions Gen1 only allows internal and load balancer traffic. | |
+| `cloudfunctionsV1RequireVPCConnector` | Ensure Cloud Functions Gen1 are configured with a VPC connector. | |
+| `cloudrunRequireBinaryAuthorization` | Restrict Cloud Run services and jobs to an authorized list of Binary Authorization policies. | |
+| `cloudrunRequireEgressAllTraffic` | Ensure all traffic from Cloud Run services and jobs is routed through a VPC connector. | |
+| `cloudrunRequireIngressInternalAndLoadBalancer` | Ensure Cloud Run services only allow internal and load balancer traffic. | |
+| `cloudsqlRequirePointInTimeRecovery` | Enforce point-in-time recovery for all Cloud SQL backup configurations. | |
+| `computeDisableNestedVirtualization` | Prevent the creation of Compute Engine instances with nested virtualization enabled. | |
+| `gkeDisableClientCertificateAuth` | Prevent the use of legacy authentication methods for GKE API servers. | **CIS for GKE 1.5**: 2.1.1
5.8.1
**PCI-DSS 4.0**: 4.1 |
+| `gkeRequireDataplaneV2` | Enforce that the GKE clusters is configured to use dataplane v2 | |
+| `gkeRequireRegionalCluster` | Enforce the creation of regional GKE clusters | |
+
+
+#### Observability
+| Alert | Description | Compliance Mapping |
+|---|---|---|
+| `auditConfigChanges` | Ensure log metric filters and alerts exist for audit configuration changes. | **PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2 |
+| `customRoleChanges` | Ensure log metric filters and alerts exist for custom role changes. | **PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2 |
+| `projectOwnershipChange` | Ensure log metric filters and alerts exist for project ownership changes. | **PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2 |
+
+## Troubleshooting
+
+### Custom Organization Policy Concurrency Issue
+
+The following error below might appears when you are trying to create multiple custom organization policies concurrently.
+As per October 2025, a bug exits providing misleading error message `Error 409: Requested entity already exists`.
+
+```
+│ Error: Error creating Policy: googleapi: Error 409: Requested entity already exists
+│
+│ with module.organization-iam[0].google_org_policy_policy.default["custom.gkeRequireVPCNativeCluster"],
+│ on ../../../modules/organization/organization-policies.tf line 105, in resource "google_org_policy_policy" "default":
+│ 105: resource "google_org_policy_policy" "default" {
+```
+
+As per now, the workaround is to force terraform do not use concurrent requests. To fix this, you can run `terraform apply` with parallelism set to 1 the first time the custom organization policies are provisionned.
+
+```bash
+terraform apply -parallelism=1
+```
+
+
+### Custom Constraint Deletion
+
+If you delete a custom constraint, any policies that have been created using that constraint continue to exist, but are ignored. You can't create another custom constraint with the same name than a previously deleted custom constraint.
+
+See https://cloud.google.com/resource-manager/docs/organization-policy/creating-managing-custom-constraints#delete_custom_constraint for more information.
+
+As per October 2025, a feature request is still opened to fix that behavior https://issuetracker.google.com/issues/434909712.
+Meanwhile, we recommend to not remove any custom constraint created except if this is certain that the constraint will never be used anymore.
+
+If you need to cleanup Fabric FAST Stage 0, and want to avoid issues during next reprovisionning, it is recommended to remove from Terraform state custom constraints to avoid any future issue later.
+
+Retrieve the custom constraint part of Terraform state
+```bash
+$ terraform state list | grep google_org_policy_custom_constraint
+module.organization[0].google_org_policy_custom_constraint.constraint["custom.accesscontextmanagerDisableBridgePerimeters"]
+module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunDisableEnvironmentVariablePattern"]
+module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunJobRequireBinaryAuthorization"]
+module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunServiceRequireBinaryAuthorization"]
+...
+```
+
+Remove the constraints from the state. You can do that for every constraints. Do not execute this part if permanent removal is needed.
+```bash
+for x in $(terraform state list | grep google_org_policy_custom_constraint); do
+ terraform state rm "$x";
+done
+```
+
+### Security Command Center Management API not enabled
+
+For organizations not using **SCC Premium or Enterprise**, the kind of error error appear when `securitycentermanagement.googleapis.com` has not been enabled.
+```
+│ Error: Error creating OrganizationSecurityHealthAnalyticsCustomModule: googleapi: Error 403: Security Command Center Management API has not been used in project 111111111111 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/securitycentermanagement.googleapis.com/overview?project=111111111111 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
+```
+
+In the case you do not want to use SCC detectors and do not have an SCC Premium or Enterprise subscription, **the controls placed in the `organization/scc-sha-custom-modules` folder need to be removed to ensure they are not provisioned.**
+
+In the case you want to use SCC detectors and have an SCC Premium or Enterprise subscription, **ensure that the API `securitycentermanagement.googleapis.com`** has been enabled successfully.
+
+
+### Security Command Center Premium or Enterprise not enabled
+
+If you get this kind of error, it means that Security Command Center Premium or Enterprise is not enabled on your organization.
+
+```bash
+Error: Error creating OrganizationSecurityHealthAnalyticsCustomModule: googleapi: Error 404: Parent resource "organizations/1234567890/locations/global" not found.
+│
+│ with module.organization[0].google_scc_management_organization_security_health_analytics_custom_module.scc_organization_custom_module["cloudfunctionsV1RequireIngressInternalAndLoadBalancer"],
+│ on ../../../modules/organization/scc-sha-custom-modules.tf line 49, in resource "google_scc_management_organization_security_health_analytics_custom_module" "scc_organization_custom_module":
+│ 49: resource "google_scc_management_organization_security_health_analytics_custom_module" "scc_organization_custom_module" {
+```
+
+In the case you want to use SCC detectors and have an SCC Premium or Enterprise subscription, **ensure that the Security Command Center Premium or Enterprise`** has been enabled successfully enabled on the organization.
+
diff --git a/fast/stages/0-org-setup/datasets/hardened/assets/diagram.excalidraw.gz b/fast/stages/0-org-setup/datasets/hardened/assets/diagram.excalidraw.gz
new file mode 100644
index 0000000000000000000000000000000000000000..48a1f25bbb772eb8b8ccf6d7ab2db98b1fdd7315
GIT binary patch
literal 2810
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
M0WE8w^^{Nm0JdOyaR2}S
literal 0
HcmV?d00001
diff --git a/fast/stages/0-org-setup/datasets/hardened/assets/diagram.png b/fast/stages/0-org-setup/datasets/hardened/assets/diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..24e8aa35133c7cb4c3a2774bb90b1b775c950ff7
GIT binary patch
literal 266836
zcma$&cRbYp{}B}`MHv|tXOvCZqmYr6l#v;sGLB@NEhCqek&$tQ(lD~a#U&&2lD)Uf
z9%rxny^e@J-_Q5^`^V$ly4jfZdkiB`}z>%T@2M9-x90K2{
zKg(M^aNxuNMcJ#joCqemN#dY(-Kg1K?W{LH-hxb!vtB
zb(lYI-m|dWu!(WXbe}m$`wNz=TY0Gkt;f(fyAgNXl2C~Vu0UX_wkrnbnh+&`iJM+Y
zo3=AUCb%17YG)I1DV~I+?63CziRbQHKXu~@0rB2Hudu{%uL%d`jDm-77xq0qsELAe
z?E41ncLhTxEQ8;`OO=wh{Y~T4JFNQ7j(*Z8!M$5=eZRf`@0;+-5i2{;CJEKw-P*X8
zk-+8l&gz|&UiH*AetU1uTZmuOy;Rw7fmf4=KILz)NFNt_3f%f@8>3rCq9^!M^S@S{
z{?8EaJpm6SeiM2XLe`?dw?+NhJD1tQm6s}o4fo&Av;SBjtiJ(%k3I$#)gF3W^ydmR
zy@d4!`_T-pCu)eIy||4})C>u@ooilR>TmjZQ+~=JG%@H4m1k7cGIXx?zc&s#G8zve_0$t5Na2rJeJjIww)8PU3(?um
zY2J3zS2rW++z5jec3`71C3Ng{bG)3Wp(b&;-1hX$({18-pIGkf-PC+hJX=B6NKCDF
zgCS)6tm=P4iP3X`OYNr5ji|Kt0CJAd-P!ou^+@$AUOFc~Sz}0R`6>f(1tafM62`jV
zq5}IE_=;BysWw`$4>X^!DU0OLWsf|&!Q8L42>DAc~
zkGQw0@uGne_HvCp$QkJlXvqczBDwzB}A-8I9&gYFFAC#u9)eHBza740Iez)LcZmR)v!*KM}
z;5rtqwl-A+6`lVf(+H5XI3MD%Zla8?{2CI6^1!Y2YMQHw&&rOs9o&J^XoN6wmxn8!
zdRB1{4oZqCZQa6w5YOLU=P8^vS1>NQ^Idl61<@s0uT1WlHj|Jy>yr>IJ==0^#LrJ5
zC6@;3gunH?XL#&`%0^3ezI=+4e4y@xXUN)@p1FI)Xjx*OMemWt;C4A+g>Y0WHjS7P<4w2i#lMXAL0FwxeXUwIS9bI{xto!u#pBPqZ;JT#@7oE28K>NQeL=h)sbT`Xm6WEEiaGI^VnDzRWe+?DT-Ui
zia94ZcG=2be^7Ditn;tev}}wEC!OZ1*fbuSglTnQ~4g=D@?q`gbvBzDuM0<;renoiAO#=zoPs}*8yWHyG(y^
zymQz0^iK*U&d{FKmi)JuTlEAcKYcqsYI1f>dvy}(A(l8uOBsLp@Mx_5%OebPXm4`K
z=z0-MT$#I>Mj_y@#yb{iFM=f&+vdH`?yiXt)k}woY;+3kjSfK
zeVE7X&V_Kp)l)PBD5qtYO~9V{O$p9p?;o!WN9EU7&UsaFo2*QUIQ-_uU-t>vb}UPh
z9O_<_x*Z3-|F#Ikv-Jg5M54ZtOU32283*K4U;LO1^;qj1ZPA6QEcJSLtd1MvUZxk0
zeQ3E?FFKyul6hEw2rq<#$*^0SQOn5F=4+GrYLyI*dKW28UY2i|M;z&L=(Kv!ZW^U>
zcJ;^84;%W9-ObbAxr>(v$_QOftzr>4`lk%J9<$}t7L?ry?yIB0FEKY%M+(Q~Zs8
zzOfCVG-Y*&sb7O=D59n|7Jy9B;c1QfXYB)2_^$%x@Mg`yb<
zU0>b{y4-S~YX)PYZ5CrX*EkkUJpJvsSgPn^30HIvvOhe>?uEeDB
zx0P{Au3dh}D&TYQ!O{vtuW$on4AJYkv5$ruWBiwrF@v+yu$YOtr&8tFz?Dws971${nV#04?MB(~=
zt*tFPTER=5YX^&wHrX8ECb%)oYRHE3-nmxsz0^9kr%NXQcdiSe{;jg;YizWKg|0i
zkQm-Ok-L7JTnLIY#3%pRjL1{uYePV-QHg1o8smpxMJFBimEn(r%eFwuD_^g@MG2tA
z8`s;hXbZ!&js))sj9ILe=9dc?B(`43Wg=5PSG$JpP!nXBa#=qV(BC$Hlg;Qmk>#!jbmJB9oL@$t-)8fQPo6SbSG>GPT^BwYPTrpX
z&K#nAcICUgbNO7jieNiLN`)>X8`CQnQsVgE
znI9Tga~+@@{go7=id*u)X>F(!_WRLMOitu9s=n91d8P#CS~2Z5?P7Sx7|wE2OG_))
zW7?%xm!(6`ZJ}9anJ5qX%v_+PW2*N;ME|4)a8j;amJE9je5TwoUH9V>^FJN~ovuX(
zE$a_gjd0We>Q7V&)xI~LK{?@dwRo=^MzWYFE^XTc#T-CfH2x|gJ?*|!)L1J?ocZ+-
zo$TyG^nkrRZ}?fr#pgtsoz_LS17!L~NPctodM}SxXIR
zKU~ziVSVQQO>&a64ehlQki@S09S9(UqriYUF9>>iasRq$9l({Rkl{MaK?x_H296sg
zRLu!!3JorPatC*E$z`Jj`m9f4wgY8jk~2E5e5nnDC-ZyV;l97V=83e;4V!<_p0RE{
zgjiewdv+8ee_rRv4VItl6YE`3T^(YRim4aJ);wRrATvhb_bz_%Gv7S(c
zOR)EYACw&0foEjiLGQulWYXkALP@a{=DVCpe>!
zqT{_=Yrx31x64IYE4vo_^eQ;^e&sgT>NYa{$CpEgZ2+hLLS4
z(^*`utB**?po5EKcup;U4J7Q`a>lSuAfii8R(xZ=krIPc^ea0eng5)vH^&0{$u^96
z8Chu(BGCf9EqP7mQO!$>^cYp)exI=*rob-^_ivHGkzS@|iaaX=5NOM<{BHyXu6GFBjX*5%V+O$d^7i{J47f
z4Y}JdnNiP!%M70n@8klGD$zVhaT#YHP_PpoE~`1^NiU(X+z;T)=)kD9nCNjdG@S~T~;
zEjY8!(Fl0z85A%lGBT)Pf4j-uxa8-OFU%znIb
z-XXMB8LKgYYNhLdY2QvT5F9=3%CSd6&OK_Xb=04Vd
z&kRl>s>UCm##Rg|2S1YubUUWRVdZYFR7=dPJgYB`nBBZF6JsmqQeH&5%!*zL5z
zxmVpHC6tJjT5}4IrOp@dWq{xKNPUO)GD+i!v#_Dii#pKEaw?^wi7cgoUKZS12`-i!
zIa4~8Expc#sgqnkCbcpYzNXT{fncCGFv=`AW`eSdV(ThjD3mZAAE?+d%R5~6>k!$I|0&B4iTq%;e`=aIbbb;?PIKwgtqdTNX!Z|f3cwmaUij?zV)@P-x6VUj6
z%F7W93T(&+eIPzi>IKol2O&3E1}YVRI<&CWq~gqjC~awqnqaZ1wu_xpo@V@)Ij!VnobKd-Mm$S~>oh3dSm5V#D4
z+<@iQY|+_T}5DmpA73>cM3l`>p+LdWh(GfQ_tm~v>jpCkhNq-Xm!wkzyvxd+(G%3
zNOTENL_2*uq<9oK>rtcW=!#yV&HDKQULt}`Nm+p;V1}+y>qiu?)Il|&?#`W^JuTOl
z`?y%vzXZd|63_x5Ot2s2g2I#rmL`Gz`PlPWI`Qa|m(cZ4BI@CGtRUZ_ce@i=Esw`a
z4S`nwv;_Pv@>qau4Dg&JxeA8Da;uz8lhzrSGtFMy)>Om?t7pbr<@C#lI;-l%$x??^&zj|#FYcE$z
z*?(#`i>;ea<8BxLW<5$Fu;1#azP|p+sa&bqGRlv>ic~W$`qA#Ci9EP#tMiQpVqxsd
zJj*)bfn*S(8BNL_voJQpPrT?(UZ%qVUGyr5GQE
zFygmQKQK%__xxroIH~z{RLUt_*;+zE{GM3Y&AEyWw@sgWCnJnorVB4Nzz@;^@v4mhT2d5yA(
z9|R`c%D#e5SC05d2GtN?C(qgkc9I+
z2g+fVfE@7N65;7-N*VRHUEz8!DitmbO;eN{>~aJY@BKE{sE^e5%NMW$y0n=tZBB3?
zx`b?HnW?_SQNiha44ZK#8dvecz5rv7<4)=VQG7Ue$@<(_oe1)EfKU}@;jhF8AaN7&
zw);<_b^avpc9PJO(Bw7=qb+^!eM~O|}e5QcT*@x5$+V`TCp`qS+)&z9aW);t_;g
ze@Qi)tuH$Ixp;UKX7a*1HP&^`R~YJVr2gC&*5e=@Scp{j8f?>UVpI3A>q$p>NT6+t
zH^#I|s?{`HpCxPYinW8R17+0#op;Uw%KA)d#lkx7kC?`=k%T>6SF^r1YZ)^1w+CuTC}MWzS+_8BhvckaLTrGTpVmvW?kHn#dngXV#sjh5G0
zM4t9hBaXLk(SeswtsBhf@K7YNw^|RvnD4Tb)Uz2XL<}@4aav}L`CSn>gO~2_olWW)9J@}Y
zOl^Bl(U%D<{%{pLZ#6!PJ}mUT|H3O&+XE%!2oGcK
z6<-kZW8uEt{&%HsqJTM##d}O;x;LD%iJ%|+`6qPrFjfro`JDj~WCCBi}$yB!Tn(}IYNC@w1y_7^+Y+q3js%C2N|$*CR+$V)TAdO~OmXjYv(c`p!Ib*{c$Kyy*%OQ@3uccFl}o|C2%x1!&Bmqk|P=pW|7Ik#C0
zKN$sIfFk=TWyN(l^}?INg*>l$Al?IZ^h*S!N+_b|rppnslV=u(BfSfMXQ@R(t{H<2$sto?uind&Bxo=Y5=u
zL2!u2;TcC(q4TuQ^Is3~g;mU9=Y(;!YA`D^jAbd24
zU5{#HONV27=HHg#?D5#jk{&n>&4vrH+6Dz-*H^yd+@y^eOpRj!mMJ`@6+Z>gxVTR*
z6VakspyeOd#IA`5fs%(kf$pD#&ekUy27KuxcE#E3V@dd4jeX8dh}jw+oY3i0-!&f{4q;ZG2hkso}Pj$dH+t$VRI|1Z?7<
zNPQn)Z7O}3n36kJFsw#}zH-xtQdI%@#?M7Otwn?)!m
zCjknQ+mK_Nz$=9hQS?Y=gZT6oT+`G=Ji|0l=w3ugthhjz21Vs^H;b(qJ{A?vfVmm3
ztfWe2G_(Lq2Fa9-ohXQ+nS);jtg*UWDV3n`Yq0pPazWd2EFV1-at3IhalKN1iIOFV
z)oh#%BOO#8K3FJ0B7YJcF2~f;n~9(88hOu
zE+=h!R>N>&&t+eJ)?AvVq&T(`tITf@QL}`k4G_99D-=;;wUT>RJnz9jGJC&Vz0@zu
zfSh*oqz&&*0t_`nHlygbZpVrYGMXEzl4+U6XK+4pZF0C#`M3~Us45usaZ%gCWyyP3
z0aGYCvr``Nuhev>81>l1c-)lKqPnxvq#9vvD;aEpE|pR|Yg^BlJy+6)tAo0Kd(#q$
zi&~zf5~0?A+@J}g64GU>^OiX-lDuM9A(ayEaL0MAvsaRtcjFhx_fIY?MveBD(aDcd
zoEQ+b3mJ4pyXyED;&W0ntg)6iCkN%5I4~}4cb~p-fJ*gIUJ~lEky(gg?=hgTDo+r)
z(8MzFoaU>s5XnJELIi6Q4&>}&KcA&1A9ldRJJ#Q{n?3aOzE2rP&jbYqf?J-l)a;buqpt5QsG7E_u`7($`xKJnYLGeX{K
zVJcE-4)$;sy}tG#tk(JzK1{nkaI1PV#QZtYd(Mb~f*KQg4Tp1R4%4S&BFv#dW!xS2
zm}i58PP~A#>M`5G)eLRBvg?+sI)%;Rj@6w6{z&iVhRr3UE3;-gN>>q7D6%i+jJ&j1
zbpEChvwrJzwYyEoz$Hm@Y7Fr5B9p7cHS>ZVxPK`boa=QIN34s5we#cE*PH7GWMJ
zD+2%JUR3*QYs4;dSW+4FbDSlFYW9~9O;2ZEfUSI`$I?c5MR<(Fm{TAGo@F8V?wOJK
zspnavJ#5h_@^d)ngh!zelrdA4K-ruXs0^g3(4Win#=VrR9trqZ=EQu+MUd)Ndz5a%
zg!G((6Sj(KlVgLu1e4&xD(OfGK(w&0IvmjsigGtM;5P%8p0{&(`Crmb
zGk^6X?mSY)=2OZwfKMUPA9n`Hz{;f$-@c5UzHe6=D-dlGTa$gt0EDp}Ef^gL!80^%
zykie+6c{tR0r3o!?x{KKy1-SZ1mI-kDvILkM;#!wf&GwXLY1lb;XZMe_Z%$;b$526
zn^bj>?`|#tYaWCyAF85&-E}`3BDwlYylFfdEqcw9h>*f)Ag=d?!mDT6-Hfpy4aLTl
z^_}SpH+l?v-2|!c?PkfdATp?Nt>MsGhTEjY1)LjOMMbBp)3@W5_MISI7gkMFT=>X4
zDCkWIW-=^#`4R)P23{~2%VrdMgt~QXk&G+n21l*==R0ie1d2Ds&DVq2GFiDpuh3LZ
z9L5&OuDCMyXX!t>ZV)`UzT}HthaSPQRcLNbvP44HCkLjSsaqI;LlR
zL`VzD$aFp+I`(&E6wd?9Oh#ruUv+Qz@Yk5hhLRgK5R?-=S|KM~hJ{^0c;CFS_
zs~uvLze9YW6!3-gRJx8Qcy2+>khT>Pk{zj7fiK1NE4wi&rnyw_^<#!=u02S_bC2CJ~Y)*^|{aRfX$=1kg?C
z3x-atHo$_gtX5Ylx|-3URSo>mkuy{WsgNs2Dao24B{OoN_@W3r|Kamx6y~`?S=IRQ
zCB7;y
zAY|2kZ5=kaRKO|2MCmqSOA)Hz0MZFockWV%CHBr`>p_S^E#;(7!=+qXp55~XsZ#D)
zIGa0eS;B2xx3}XV&vCy2Sdi_t*zCEuVS}8d<-w3_3#)bOe!H>vDS5{9Gb6Dee0%Y&
zrNRvwf3)GMR%_deOMPr$^@BmprL}C3TFrSjm!ChS6GR9zK3pPTuNb>BZIlof$rky8
z(Zjoq{2ue`3p|w@Up80Au{RJVJ;D{e+6l3r6$VB?KMGaK1&^Ym!vkDKX@rgB)tQuU
zr$9PbXTz$W^1*r<8zY^h>p%!bz!)FPc&S7BZtSE^wsLb`1Z1Fn#^@s1Mcxh~`jFqj
zG3yonBTy6e-U(Fc87OmK2|vE#5S!QQzE;*LwVd&_sIc$@ItbZ+4649Mg|9-x@4aw^
zAaLs#Y-5=;>jLNkDV6<6tc7rEcy<0t#Lvk@c|nf{xR`AC-GfVXX_nH6W?YA&w$dLq=hG4`h#=pI47zgRWg
z=S`m8GheEW4d}`S6@BK=TUU|XD}F*y8}b4J>yH`5&K!>igM?U9wQJdElk8u^P_ZOV
z+@C!Tx~&~RYh^ziKid=cQ}h9&k!&I{!n+?U%1Ih>D@;iw5A+LUizKdk%&n=wfAR|r
zi7xqL;*(jZW^_jNz3xnTFS0({Z_Jn
z7_7dTzya>#vQk2P6*mXfRvW>>TeNtWNqL>CUqxx1OL%P}+vUaie#_w(TB_^ymLO%E
zW`TVDZaucWP?+qn$?&uY++yXDV)REPr$psV$5`xU&$Dp0q8pKFL75>z`6p)cIqR|L
z@fRd65c6vVF_VTX)mp3+vvZGf>NYS|w~^Q2LTS$@?0>y}%DNd}rRy|@3GdAS(V8GM
zadpX(v9C8~MWhmCH);HSMont5v($ZoSc)P9=Jj@x$v0l59U!67GJu&5s4#I>M-mrQBzA*VfS5VoQuazZj%p$H
zPp>MTI7Hkn`lUx@)6{hq3Zcm`GS%gDntli;568Wu7~e3dj$~
zUrJT?vba;n_7mVVSc_)FpWDz>sY0UCK%N|~7B=fB0gW!no!4T$rOw6^Rq}#$0D0A~
zSfPHsTB|sWRpn*GSoQ2Q9PPfCefuXFZpwdkf>|fX1jN((V`;fG&x0DTf`FG~Wps2m
zgEM%|)0bEBvh+_<=-78^YI8Fb;XqamcV|jl|I@Px%bY3*vJE19cwgobq!tUyR5${s
zAvu@1T>Hc{a48(Ies6U#zk~sVBKR6le!UJ&pin~2le&XF1Ja#!-`sKMW1b3GJ^vI=
z%}IG=jOt_*D9$0T50q4gprSyR5J3!|T*pZ9HGL{MMTH|#{@57W3g7dHBhQu{OV+xD
zQ@icdq~>3f=cbpZ$SXWQPjInT7lbpJCEIKe0=F
zxt=?i5Jgts?0a(aYL;pbi^B@cUC%x2gDV|L6)z-z$bKvs=2Fg;-xbExz*7B5+ko|!
zZBXy+o)fdrw2)64TOy^%(~M#dQrLFrjh#+t(i1m7zZnE|HOX+=bbM0o;0_Xk2L9;h
zDhc8u(EE|t|zJGujC)nV`N+<
z-;pZgzIH;EdFFXQwW}kUvf?_^VK|BFO*7}*mSEWv6nB|W#uoII3BLM0RNq8cVULKR
z_d%0`1qI^yfOD~Wq|mh)TK0-)!vGTsB5mPeJHC@9=+7Y1ODHq<|I7x;<1QcQq)f3v
zLIFQ`=%D#<3ybsuGkiT&!vlKHKWhRO{`Kxt22D2yxL|=iQqkWcb9V6z#k~aBNX(Ii
zB24%tWR;Il$I)TkyPzMk?09^5oJ`okN_#qzbK*+2L256`Y$sOq&!0?2vgxr^lnPWq
zkf)z&7tE$UKXIdime~LncQ0cdSzg?6CRajdVc|yk
z@;Wt6bqIQ-q;s-*PROgIah<`;dc8Y?qo&tRl8vgB*9CNm4CZuT#r;%HM{jzU6s)^d
z1gvDu!mjr8$v*0sH*OBjPrH41b63CY>7hUg;~RJ4y6&gE-(s~ZUp&=`S4ltpsAKa}
zxL+_;I8H%k>H2nPGzFmwdGqNCy3`8tYToKKTdA=CSqTIpzPUU&3aXu{lD=h61OrOR
zrPgg0bcm_uvB_Qu9Rlui?POy=4+Z#ua1|36P?vO#N(VA)xZr5Npi=n2z;$@GRcqIPM`mu^@I3$JrxQ4!dsss6OP7)kR|nbhYf+ts4Jvo1
zguIh^L~b<)J1==mmQ#?zdU@!O;#uL)AGTUC3M94bN
zd=uWcpX)tl(Z+UhOZjYGUS(`yiq#NE7{hVlKF=|jksjyUxvu$E##Sfywrqc~2R|Xl
zbvyCOx=i5OlT&Va+?U8_*ht{!zUW^!tkZH^u0v@0nmPF)xF3Qe5Se2T*ga5qc(BmP
z&F5Ff)T3QScj|uZ+P7&6g!bKjmtc`qoJWYW2fL_trGbFU1wiIey?)^tKqT=rwg;TA@Q>epZjK
zh?JZK8d{lhMrir-T_=Zb+_se5Ax7k(KrLlu$e<`FH2bCa`y7WyP$cJ%6DbH
z{z~kxv9aqA$_P03!L+l(PMrh+bG8Z7HNuGZI-s$I5_*?C{N|kV3SYp2YvD+8xaxJ#
zplR#=zLn1kUsj$vU8AO522p$>OF%(VSZG$vduD+zaT*GmCz?C;wC{yjcz0*tP<5Fc
zD<9xhybNKU&3htHFP!8ocC6~eO04zrT8AX=fI>QbBHz>aFXLmWVp
z!ZndzPask3)rlg|Gfe$HM9Kc-kI~t=Ks&Pa%t`+wfy*F(Yf8D~cFt<1fP=y+k&{GW
zSl8vV9N{r2A5)cQ@5#L7*iYRKowuQ3iF(Bnz{Oq}^$ezU+(bIqADgt3>x3{qKk|Kg
z8ShcahN-WRd~om{b`0&U^QF4;PCxV{96eQn@s5WKGJNkfaxYO3Wg7L7TwW`iK1yN+
ziF=M}X}*mss!KsAR4~Ir3bPAsLtrB-bd?p+PMe1txe-DG;hvE1GjYw$EChaK*Lyh2
z6MDT0AHf3iBSICv^&Z>&^3o8i?Pbf+SN2!`Pen3thD_%2>WZ&+X78}YkN1R}#g1cL
za>fSBvn|p1-b{Eh2~|8SmIS)gS9d8T?$LE7I9mm1eE`MFcx}&M?PAO^ao2i3H&F6c
zJlD@91G9vLz{H5F$mgrH+d`ItlD%*ny*R5_UYP*`T@O`cogWcmv-;@#9X4_EgYh4S
zZ!YAq^(2;depfK)x8i|B+ZP@qd4lZs70TQI{e=q1Yh!FuD~bzpygm27u~jVxc7v{L
z?Jw$9PZ=B(Acl3d<>Pl+_@gq*A$~eYgB=otF!}{)RJ_h;B_J=x>|PHYJYO?
zeC63lI?1&%^B4toJ?NJO3IwsPWoEgYtGL6vy*>$PpgO_RG*F|y0(=ran{fKX9m2dq
z{UAe*-Odif`Cs*1CUfCJ1vBpxt@7G|PkiY@d8`J=Z)J>W
zh`F-D^ULW$zOMt)NXKf$tX|ts{Mu^W~x*Qt>?Q#?LQ}A63148^gvvI|%p8^>4&-bjf
zyuOlY%lzJ0?uJo%!N_%dURYNGpOH>8A>WBNyzZX*^v^0z^ffQO=M($^0y!WNx7%=O
zMTGCoY&Mma~0mJ17Z*?cpoqX$*xFZB|;
z^JlwowR0Fv?_B*#JfO7w#ox_cG)08LAS6F@9yIQ8BrArq<~|e$gE$XBGw}{YySu1g
z?EAFy4>+Hu6<^^T@0=bwO`}Fwe|zgnUd~?lF4r_NyllM$RRCQK<1Wrf11}R)?)EEg
zf6dE??ALOu2@1Nh&2clpMZ~tH(01b@c
z1t!tHoZt_(&ePa!y*~AhI-2*cG`@XwR9Alt7I^VT1EH$w&M|-7z^zHND;O|@_7k?$
zM7w8u-j9SWe^1d|*)x(Cr~`V~D<;zH`hFvrcaCszzhb}x8qd>r^p7@^E5b|L#&Hoz
zAZrU5_(fgSVWjN5g+%m0
ze?R{p2OwYJHJqD5g)?e)H;1ru&h8NBKF+|CpiLDBoCE*gLz5K=p3Hy1{LM$dxq^2J
zkB6lY&jUN#gFy8vN@Oo8w?N!;YDECJ+~BaP*l%@w>K!HTUnRqTFp;P-xZ3fe*Q)a1
z)--1bbpI*$e@~8rMwe4SCtCIh$x9RwO=#@{7Z1g*qWL4UfbQ?8Xu`l?lZ4FSok^!Z
zkjXF^?KdiT(6*+CyfV)LeW(3dDOi2)Ida*aCiwRCeGL3Zppp~-RO*if=y$c`4;{jK
zxxb$O>!!>+;H2-dok@63Ksiy{Z2r06?@xaXHi1zg6>!kqq};mzd8wYm|D8>D*gg9q
zzBWU8+{4XfS9$CJ@&|^!hvUz+@yF{pCWY9)C`5Cdpz~h@5P;E#UlbShX3xz)Qwf;;
z*pIq>sJM~__$Zh2(C;-ysieZze?R`0YT+%$vup2CZ#xH&@RK%g_uhUB?th@}6b&_A
z^#^oLKtLPYwf}aZKeBv>i?{qXIQcZYNFO}9G|cj%$ew?e^@ekd9fBIX8gZr$K0(0A1_PveDW`57@w^h%6rZYdN4_+X!{l0)5
zNJI@^O&$fW2v8a%{u`i*m!5`p>-d
z3qSM2J{4lMS7C2~w~xDbaJIFHFe_fOQ07-%-EWeTv{0e{DkMgi@Dutkr~FL*D6wA<
z0?dDhGr2}+7CU0(ulGiL(-^3nuw#}5ga{HSqVAejXW~RL(3*ehqm_X@&G9R8?
zI(R%pl2{piCbl&EpK`l{prg%zfoLx(cK(5B`%Xr`h%NV7tu4B3lMHnZuP`Ce<$ED9
zx^zVN(0?Hr$R<{CFL2B4tO1jbeeZVu*}d;RRPfg0&%uy;HsbwH;2~iD)mH5CGp{6`
zv}c#vbuRu;MSb4k*d6orpB*FoaQpi&@jFIimskF1)ZP8@8{s*9LKgUkqO<9u`&FKi
zCQ<5N{ykXnTlBs7I00d4iebm~cL6rKM?A6X_3!GaJ)(j7MGXi$-^(n&?F^&tQ`@-i
z5xf7SEI@%AA8EZSIDK3eSVuL~UVnZY75_mvc1N9gSdRUX(%+x<5oQlIQI;=XS8->P
z^jQBz%Ze1w?0;^!d(y?dfi7T=^P5xWx^GD?bntRQLP4Fj7XWIR}zzBInc*m*T
zCGfT`y8>Qr@bnM2;XnOyB4FDe_3Xid*DRi_%LT3Vw{{um)v1|373H11_VCY@N_=bS!r*^PsO;P^kP*+W
z=r1-9aMG0&65+G^c^xnK|4es$1}8DAT0h-$yZ^yLpNZtuvTAJVemMLCW~2EdyQ$4R
z*v6lV;>G*pwJ5>;O)E!bQT+cndRID(?&A&Z8TmayHw`0!?!P&m+ayQ5!Y?`%<-2`7
z8ZN@%|Lqt4$=4Z8kP1Kge_)QCHytmvpnUvbzk`Rz{?6;Fb~Wgh+68!s4y)ppB>oHH
z|MG?`(m-ZB|1{J&eAu&So@z#U-`03!|6$u7Fd!0-d%!z}ey{mo=`}pXO*DZw&F3;s
zkN0Q(Kj}3f1YQmJF3S5QGQrUQXL=2PQj)9@4L-+qlwl|O+2uG=(59>MFDgPV3b1O@
zxV!L~z0~=2iU6~(YherIT^(VDPx)l~cB}62s@E(>U+vC6yExqEdGN*o^c_t}x7xl4
zuML6H|E4evA)u4rfd*C(i3k&0>h5m6qgwuuXIC?^gROz*V12ppy68TjXzU5Y+0<0S
z4;SEv_ebAYgY@-USf`SZ)BCA|?}geh=Xj*X7%dN9av`4h>G&N$&8y)$SNGmS
zF8d1P*ip!NFaConRHL9ysjt5QJ!r+jlMng_-ntnMP}y-UeRK1`Hx04Yjaad-o;{xO
znOa>6LN*A#4X+?|K1#jWcN95hCi%%y$&_;Eolk$rsMtG?uvQNi1a
znq~=aBG%-u9N6ZZ3U5!lTi{i4r_RAysCsn*F>$_Y+VgA=&IOxDWfOUZSZ6wN6!>Q4
zv|76~4@@)6bgEQmO-@y+I2QlF+|&=0o*dAt5vtA{&UC1>A09Jqf>L8TYV*D}F(|jk
zEYP(cZXCH%b3BLM+N4i}t?6|jK3GDV14&|LR!iD
zc!!3ZTddSJ?$~(r(tEjfeuY#{CAR^4Q#RFK8#w1&4y`<$ywjMb42y6l(DWC5Kbuo2
zZhS?vW%$hSJ20H7o@W_OGhFj1A!xR4Cl_EEI6m1ibf>t%Oeb>DA2Te>ct3E}G}imQ
znv`WzOuMF5uy(sg5#PzP{sP1Iv(qg_J6*jCbnj9aMe3xff9dz{6>?u1
zaO7Il*O!30KDa%%#jr+?j|h|QmFOFV2-&Bd%Tr%|4`M_~u$5
zHu1rz73D~>lSL9eo9RX&-!+};N~%mGPeoI@dpr38t%eR_5le%Ku+l<|XQ~GeA~{V&
zt)4Hz1?Q}I?GgD7YKn&^E|Evwpk|-C;GkS
zr&*E6i;YIs1@mFa1~UVxj@nAuvq6F+x0^7|mg-W_a0{!ECP77xj1Us5iO&li&6tt_
zD;}Zl71x2KTp)fO8WsPHFy-Ps58gCV#vA^(P=xoMpvB1b$R``sL^5bFd$^wQNvSCR
zYs=z%o{xmOXQd~ZHp|{%6jqodO&{=tbU((BJHCZ{D>fmigl@UwL
zdG4|KDZFpHd@==|B30_)t>y2~3vKL`wg!3K(F$Y2Mk%lhJspYelC0dvE0XCcHyY(6
zS?fD;haDx9mNa7GyyC?q(dBlNZq4QcSum&$oj*%@;JU85ed38sImZPPe)&86L{
zN8X;S83*W)k6W>$r{fF83U&s;vtUw9%yO~o33HKApaywTl@)pG=$|gF3XpNwb=u@Y
z@y7O-neZvRXnNIC*x*}WJPBo(uOyNMjBvifaAkd}hjl-3VGMX=Uqx}7u=bFEq~R%3
z?CSj0tZ!E+uDmmBHKR>ZsgA5VUiMjY(J*QP6>xG!;c-93Y4-R`7gB
zM`_yG%u{(Q>X!5d@@xev`m-Y}?vY-NNgQQHfGyWF;*n{fUBxX&M9o^+`US+&wbXdU
z9-)P?)#(iP9yJ505DkQdK!Ez&be#W-h4GOxiK?1h3#|WH!l)2i~r~@u#E#njE)-4*YKism?XLnF`{zCtJHz&E%S3`IS%-GyFtiRs*J?wD>m4
z!Rlt7vcow!kCi7ysnEKDuw?g>NMS@tq+omy?17jxgu`AKPo(dl7
zU^P8_v!p?SWmvVz;<1|58vH#HmuFIV|IUCxqo$?(+sQGl4RiECE1*zR%W5$1^#fN|
z+Ahcky3qnvont`R8_;j#4q=yaMeEZ!^8mu!)l^yj}*qTMD&4&!|hTsMV@B3
z6mUTPQ#RmtC5FNBTjU-=yyA7!QRd<0!84h18Ses(GB
zN->)h2c2IO-9JJ#s|5`9
zNqW}Qvkq1xrZG~(K&J+hPzIYM@laR|#7Qi~xELU|s4FinblyOcEk_ZVzG*aK*kZ0~
z8py}zz8VljQ)zE{n8IXTyvVfu18xMX+?hEmUN`3U;UhZEY^0VZnqwI6qk!g!N7ADv
zi1w6@wST(!+gaEyyf2skX>zYqiBh8IOXI$ky5_20&}PV$$|E7qLEvjQ7DwskI1?o(sdmu-MdU1n9E;?2<(K1J|z<+pQG{6ED
zXxG6>sW3LyT7ExU|0eO8U{QkIo|NG*gu?6}-c639Kx?S6V4ttwmU5s^BeI`vQ3?l1jSWO{1gY3`?BRDpXb
zEPJdYaE}a-9*sviS;K`2Klu_=kv22A*0I6ZDaocH29egx?Osk1!=E2!v+8(Rz(nd{
zx^nt~vQhqxQp0mJ_VDbGNA%gZs|XMNLOhB(FZUhm=;OW#gI%TavQ`73PqU7&JLJ(Ga0J5KFS
zJe%8c=i|!@0SiG>7vAfYnP+~{D`R`_b$v4I$Xq#Wtd(mb%Ic>R?)ydJBk6{Lf;zXJk5KH##)YRN}Z9y0@CAV<5
zB*ZmC6ce}qqnT!!@9+H2;dnes29NvRyZ3WH_wxZ!HsM|xW$PMSo;LZe7gwD8+2_=<
z7PTa)!faW#0Soi?i2)m>=loOb8Kxr3*Yz~kkZ4=p`uHlgrxxMsHQb`%O~CvU7r*Yk
zDE8B`TmhwQ4hkv+1#xz3X@BJ*$2c3mN^aDVYzE6N-n125$k9^@il3V#30op+y(v7f
z5Vqyc$(nr`n^6w$lfWk-4PLG=6N{>c#pb)Dpo)!L;Jr^<
z^gIf>=7w7D%oKIab!kxbn=@jKd4s$}V*6tqI#euus8+407{Yj)BV~0JVXOUR6I4Ja
zEA^%!7HeawrRSRch>X)IoxV(|^ZrOW$7Ki?Y7O8$-pjxYhYBSo(%^&coqpKk%%UZ^(SX^<8PSdZ>&9o-$
zV}dxZ(EQa!BGwI;qorcVJE!1Zs!D@xh+AV51Jco)0<|VxcCzWgeO3lK0uM4HRT`Py
zqTiZqdZP*1nHe&u2z}AbL8&B>F{yqrBida`Ycu@Dm-*84vr4|{8pgZ6gu2E$q>l_T
zg;@ldTf*qe^iJQsiaV8B?bj(E>xH$hOsp`g(xPG)^v@TK)OnDZoZ4$ErA~>g`Ci?c
zy(2o_B04{`p#QxTQ#Icc0bFXiZuMuNGonr9Ra)5N$yXvl3dWTEVU%Q}`bsOJv=b%D
z#;~=D`eBsxWK^|R!Pt?Hb#(7!#H&ZzXyDOSwHBxMIYtPuDTK^bgqix0P12=i3w}g}
z1j3wG{E7<0*hQexET*KgUrqu#{u$ajF)Y?hqv-Fly>=S6!qZ9DV7+7E>L9j*;e%3K
zt)4#unir45#bGm0vFLibj!FtXikk!-@342(aK|-xmw?=VZeHi;{|Q+w!Qg%gH&
zjI({BgNtD@fw75~omvg{)LgT4sCvnT+lq0UGuzAr_@Q+S!A?2cCtG>{!NF
zRTaw(qf-2#^v=c!cU)A)=D5@DFT|RsqS`d(m8nf|A1(fKb6gB;u{scBU)YpR(T-wo
z7dJu+t=E>!@M;N6{|)SzzG&&i>Tk!~E3X#{_(O}2pH2rX6S&pIQ-WvS3&i)XH5rgE
za!h1io;7a5Q2+V>5XA#ZkN;VUh)3ctzoUo|TLGgb^B3P-+rL$r*RH>8`KtFf+}5>{
z6dq-bWV6{CWeJH$?criIXu1BUXEq0(%v%2T%-LmGOEOAB3}3(DELm%Lj*O2F*r3Jm
zjL(QGMljup+Ht!_ESD3~x1t_{j(?G^d#hd?EdNd
zS_BU_>aLTrtXh{UKa1rA^>_oYfVL~fI|Wa}25(ZjnT;F7)32qsV4mQ~^?d``TCN@@
zFI)_9`x=yp9c}~Ps=!I?T;t$s7}u*j@oz$Z=x2@&VCn&=U?7N&=Y-kJd0_+1Bz_{E(fRkgpW!yRjB@Gg4G#s
zw?>Dv`2a2mpi;)m>VCI`V$q-_SP<=g`v(^A_Y*f)tclvHAoDqTRP9B{OS0yNl9yJF
z)OaQFGvx({O}~Jc1WB&hf|G$~Jj{uZY0%m;vm!6cu52}~EeJ1Qqg3pvqh!jRS_le!
zhCP}3t{<|mrNiaol<0nQnCV4+oG0?wrX5E%ZI2m&Jr4eIDy8dVisAm&?p?M$)+MIH
z7Z59vMT`lIt9>j-!8eINnpfc6^DC;aG0nGtnb6EaIg%LqlBgm&&8TL4EbU|42)gQg|AFX;ovGb1}J?vERQZ7ov8Gq`JY5~P`?{jmJk6RRMk{Sh`
z+LHVn^F?o)SR}puGC`gy$>s&RIMTbid`r!|_wMt^@^OXb2c?@k7SOIymF`M=qz7LC
zMX!|sSEY6{t<|ap6=4FtxY~6|(Tb6QQJVggvE`HPlfH
zSuU+nTIkO?36Ad+qV~O7HP(xi@N{@qHRtzyvv|*}cyZUU~i&DOi{swqZG7%@Ft
z(6E1Rk>8Xbwgal`!Fvwg45<%Q?>#k!OFoh{-CUa9CLZK3`C3B9+<6CFKjBUo?P`ToO*j_Fug+;!wEa(GVJXv8r<6Bc{{X|
zQ)^NGQ4ihQLX(4%_RuNDM3!efQgGP{`=S6+WPHgwba;{{D0QU5lwA2nwb=u^=5yO>
z<^1QP1n){F^A2Z1rbgJ(9xg-vsGMeL0U}%BREz1Kk8Q3|yQ7R!`Z?eBDE%KDlE3Fl
z4h4hAd2H~7{~bH{4g(9RMf11T3!Ls~N-e3#n28lVWW3R9+Bzr7<0(q^BM%WWTb`Q}
zrOkFhY!eZ%*cb;${F?2{COE+?xuWR^eWXdU)VxaH7(T9@RV(KX(lbyP-t7pg3%%=y
z%k~{oI53-f)Q5oby1l}KLB*Ao&rKv#+XmA=uT6ZxL^RC~l^W$!|J8L&B
zbhxF;IJ5wRrw3aQ*Gc!r6vK3@v(NcfKXy!+Z6VGC@cXo&aHoNO3EGOGN~+w9!k&zJV-xk=&aMPmPS?PgjWYs5dW=3b#igKf__sILew;F`
z>xczEoytEG#twyu{B7a!s&Yr=SS-i3>X5bj8tH{Uuxe>ZQR@J1r=a#OY0j)t895tY
z@mP+T&?2?CODSqSO8gYA%zjxk+s=1-bY}|b+!?B8JeL#NrdXuh4Ckp#0dzN64$8Ml
zLY7wty5O*95xz-&s8x#TpRXPo_&+yKGjdIW$uPT_F{;+bo((J!^}H!#N`*tCBzoqD
z6p!5a5xjCA&^_z$L>yJPHH#*_UtA5ncDV0_j3HNVHAKJ7F};WRjwC@fT_{GNEt=7Z
zDDLN;OIFU&`OwfMY-oX4p^PDO2Ks*W7*byX>oWe=CH0d!;g9v%7%{kdbztwo3+Ez!
zCf)-!huR_Z7(Cb#zdl%!&s)!P@Xo%tODWRaJJsW0fq
z>s!GE42c7gHj4CnavX`0iq~fpb>c40)JK{ewQ11L-YkRu;z9sOvA<6us!9nqpVRQV
z|8Q6DX!f-w%2=M=OYAMXo}1dlw8Ev`bC}f`Vvx6(#}cumZQEk4L90v$ndWD8dzazV
z=c)G9V;~7!_{>;0_uLRW^E=4Vq;K6a`cI-J?DBvf)~|*@2kTeg%Ru%0-;7rJ(%Lxr
zamhZ%$--!c8g+k&wL2BZfE2A^l#Z&3|DtT-C>o#NSDK4_)SFCVS{{XU-dg?I
z0%TnQf!&N5F9Pp}z0~YLK#`L&r>leCXdCx*kKSh`Z=-pOG5T=QOkPZ&i<`mxOQnSe
zS_{}t{I?OA*3_Um|4*d|--1h4{tS7at{8IFh|k$rj{}aGx@o-
zjAHH6k3Y_gA2-i2LlM`r$0Eu>9#@*l{VwnF1M$QCx>l0bY&0uvUw_CNE;+#~ru3@6
ziC?#U&M_IUlaBC@D#~_=?NK%_HUSs3F`SPj7Ng#rsPV&TTOWR=F1SRlFbky{;}E6?
z|Kyz9LofOZ{t%VnhuLoOIn=5Tjc^#;=HHVxaOjzHk0F#Qi*ny=quc7GsZ+pSmQbQ1
z=t&%Bq`Ygap?jtZdi+!hL?X`|@#%uTJjAxZFuvGwgv`Y2fSQl%zQoPhCum}*FeJIv
z!7i=wI(;oF(?@$zZn0$md$KS7%_otEhbAn8!&zY@zQW8=@GM-y<>B>zDtr(D5lIIx
z8vGRs76IH{|AfT%R^*|qbq?#?fC76iv;@}rCeUANd4t&w$OxKVw2`d&qU6v}{Gs=}
ztj*&uA59)FKGvD-Tx#Zb!fqtZD~c7#nesCj_j_l&I@uhk_6-vgEY2
zYohcVk0L@%W@N911;t6x7bq|u%nEDRrV(7OY(7vNPTj$ZHNa%cV%*8TXm!w8dRO*B
zjzhSVt}*`@dTKfHk@xY(AS+xwI+UT$d3V1E18U}B
zTs(Fp^hkB~dB#DMd%D~gH`iG3e@nBYN(!Un)#CA>40-wPTd2DQ^n7n*ej7xB^={&9
zdBN&)*1w&?i>B+m0fFtW4I`~9O#f4yrcQlN{{_EEe=mWhTSU~}Fx6jakLX)fk=D--
zMt_aDaw&}J@!+|MqvThffPzG#Nm}Sugl6**`gS}3FacO5)A)xWn~pZF(khB5R={01
z(1}~Wy9LfRgT`Ezb7m}NIRpH@slS=qVf;AxnA-Gx#B&BoU62m(XA!RwSj5oTMkq+K
zt54yIy`7QPd-z31o?v1qaRDgzf(7Xrhe0W{1ux9AqBISH{Igk1wb|w#Y_V3&ClLxN
zgR0jfm|1fQn!P2yHM5i|2mtNFw{UeyMKkQMbAK1aGVGb(*V6rBba*h|@uy*wv}*{(
zalXRN9kNoE=}m;B1811V={3`RZptRua?jfi2$O;~LuM6~Bu!JOKBGgmBF0>uOjo0M
z<03#&n9`})e0_^Vochewn6XXL0F3G9=o=5Q4W1PiL!iAl?t4iYw1Cm4KrPd!!nwto
z!!cR@h%hRFYoNH*LliGv-}sr**9g3X>a-k2lXkkQSc3z#
zjs(PD(KVjiV2tGjosIpZAUp4bZiao_36aL3!K48BOxDki&fiV
z3{|2h$aX&a@{W2EuG4$bjqm1>bkru>WuQ`$twMu&X;0txt9+@+>UsrO_QPiqjY0KyDHJ_IkSyd4limp8};}(v$c)kg50aOp-_gj6o-Jv
z#P&RAAn?qDObF)Sbhyhsk`
ze^=x$5WZZvN6QyyXs7T%r}FJ09?`oeBLP`IU>q}koEO?1XtUKTS3fzqHXb5Lw5m9@YHt>Mc?13f3*cQ9Ywly|`E<5;J!NIb7|#>NJKP{8U2{f;fg{KR
zRBcC(H~PGyvx()P2lOMc6_!1?Eo)7F5c|@FWaW=37oP)F0+S
z_61nAiZ75LkcMea&G^mI;4-M5q);P$>gmUkY*Z9`s!TPB)~wSkuqh}05_$&W_R&dyCgA663&p(;FNRvh+)F%uIDqNC#3td9%;8
zT#UE*B%KoSTtWsNi$1tWXQ)V^KtU=fkdg48DJI(1PeyZ;!WETIrgYmXl^b*WB^aD0
zxD1pOUF=)%y#`2C`}kv>e&DqCtU>5}Dk)>X-sJGJpoj;wmzgJ9nyN)xe>fRY6jhg7)OEqX(R5V`DGOp?;X-(1n)C(DK
z)UK;Nzw&-xBH*=%%$U>wWg01FW&um-2JzB0XIZP(jCCPOGqy2%VA+;oU&{~sS-nlBvMoumYO#~glqxxMqEO{)6%qwX_Fciszg>I@M{
zj^hi46f?)#N#W9a4HOIySTIq0{C(QPU1J5MC&iCZ;7ZV^FF*$VMA;;~6DjX_ClnWj
zr1m@?In0_;jT!S##{=neeUROJBI=mF__NP*$MTt2Ziz>9ao{07jI$dwz-A_+(C-lB
zZ5(g3I$a!z+>DFnmaCq0!$tVnkR4o;%DW?ljm3^@sIpJ}#Pc%Ht#rTsqoh3rjUNgu
z3pjJ|Y?t1>YwrUEYuYz2JeRV7)9M&L#GX1U)$yTmWGz(C#1hM!sBz4+Pa)cp(1cKQ
z%;IYVy)&jPL@_O7m+xWn(9Ha&k)v*=5=!sPcK#nFEb8N19d^eeo(TurpDXzMhah~<
zVlM(kc%mK$IaYkK>f&HYBtl*#!?9GLwrw#=;__01o?5qw`zCa6`sU~*XCwnI;{yl~
zgq%2$;@>yX#XaQa;7V(sY4kj`SQ7~agrOo2BuPQ?6i%nP+NNOksT$K=A5tQw*>{nI
zHMEKSyy->SmhoXR4good!(SyRQK7*)1wd);YQoU3+HsbZlE|l10Vri!Af0<(!e8Yr
zwK9?e?PZhB7*dVkblWd+<{D-~*Ek6%9X*`}K}9C{h_iOj_0RweyM=n}v9fhAPN}uZ
z*o7ZBf*u!FrJduS40UH49B}op1`?khkm7HcQ{5;)8mu_=Uoz6jjfr2
zD7~a{zkZVh1QT;gq@W1h`X;PL(QKVRw^mc~tBSp%`Flm54!Pj+NHmdVw)rVJGBsqS
zWDKX>YJne^OE2v@@02O@9~!Hh4)wjT_;y3a9)w_Hmy=WJE`Qbum)gnu#RSo4&)aZx
z{_IEM3|c)Fj<1H4v>D@@^@-&=;}qwV9
zeR%I=yc)W#l=4UTpgj_x^=*ow1ksgQ02DEm=R34lQ~9gCw2oagpTvNEH0{QlO-dO+
ziw5cfWNOA{N*YL#ZXw*+bh%~aIw0WMA{TwU;b$+*D#M<)st9yQMMf4n?mPG_;ifL|6+qv4f=un@lsGy+_3n{E
zwk*T5y`?el?i~&G2GDoDjIE2|l*Q>_f!ASjmsYFvOg+p)AB%%>7atnVmzofXvveN!2ADH4<5)y_bq`JETP2uWz=-
zCecCdm5HPHUf5-F#qpjcB9h*D!2C>Ny{SfIJ!od+=?1;m@$XSKSw-QlmbyscyXAbt
z6sP!^{vCUC$=2K}eZW7fpcVk?rHzCI1@eVQ68B|K+((=3Oj{P%1>l&TV`n2
zeStE)YIdJYe05eTx)`MVyic-FEBZ?tLrtkB4QHqEu8Ity*IX(PFB_Zfu(ozv`NGhl-A}=W;;n$Ul@z1ef9∨h8!w_0oBpcjw-0HB(^NEe5
z;xoE$U(Dd2oY~tc6x3*uQ<5bX=0JseroU+na*7p4jPY8={
zKm^2119dqxJ~i_vv=eD{>n=J@nSR$_F-|j?2AT!m#Imo|tPiBeZ?s8_!Ss3@odP{B
zw^vHWF1_lDSL_Qc4qrl)+O|gN@K!3my}8-WTCI*v>jJ1MqJ-DuHMOO}>i(Wu`)YQg
zQ#&xpy5Pc!(G)cZKIIQFOg4<#^vLr#vD@-y?ZcTcVW*aAjH`a9LT##5IXM8V2)KY!
z=&fM){#XC~l0FiP{Tzh--BliCsQrjkSiWAY95}g=&RE8a(2+0kF@vu@V&QoVrpX(4@S
z_IYYY$k>;0SlFo=l$!xERTrv3zbHq=4n!I)UytF{s?o5-fM#h9#e6XUP5)5VR4ILQ
zPS{M&y;GnsiELR+GoW(--cHnk$4+G(CF9>d>goHxK17O(p34nG}U$FDhOE~McAwJ6^UNY=?b-l&IA80NlgkmrTz+kN(2
zU}B{$v={7xvh>-1^5`ZPSc*wh&x0=2fgCr3assF0WYjH}w?(H*)h
zlr`MFlT8e*x6!ycyxZS1Mfdjgddh>EEM)k~MLl4+)j>n>p(n=z!_z4__vM3!aj6`5YZRbvO)9yA
zN?X`qs@9>y05g(kdrw{NYWhfv5iX&~R!5K)2Dd7Z@E})Ud8wKiQ4%8-`YgcvA1VGH
z6_Hnme(Np;yW@S7i1td-2PM|(x2k?)S=8s25YE9UiB6%&*3xJgG=rpQm|FP&@}$cR6x6#QYM)+7bvir
zmut_IT7rcF?PLoc!!SH;1%i3^nBRkHna$J;RjCtn6&8$3a8^PC%VgSD7N^MpgILa$
z@b{0BGOY^?J=~oMuhR}2e412hchMyg%X>dX&T{>$bNSyQ!d-@U`g}(BX8Mvs^>dny
zi3Xu1_(3le5Mv)W|X&Vb=voauPKIj0u7hYHjk2BNoto(=Y|J%FE
zYis@{W`Y^s_q>KR_)nW)H~y~qq*c}~3NNk8_%)(j_I|x0z$X?~HONb;7~^+vb`Qp?
zR!A;2Q=zEDGl5V(6|O0<9RPz5)`H(CF{0*un=NWA_-QtiCb7)8R`Lbo4r0Lrh`6kK}e*1!Di@Yq1KU1;6#
z&O%di?^o2=xcOEK=V(N??TU2;BGpRI^F%K=1UA{3!N}j<)5ps5_*QO13jIq@Ing-h!r}aO51pd6?y?%>tJ7!if7xfm?QaZl7
zpclVi61BGAz0(fQQ)8oZWmK2t=A)0ccj)?_4;4ga5P@;+K{)60Tc)L3-?bBZOQYJJ
z`!5NmYr=`H^VQ5upo*>cJv*&DiFm{xsc?Meb{L{+#d+*Dxm$ku>-+o;
zBpyK+NeO>F`+?0gjc!0!-T1tXZzlBQQ@P+nps|tDWO-%3m&EsztL{=Y*Ni=N=h~9y3%(grBJaP
zmFSrDWL4v6h?Mgn
zEPQYWS}?MU-4nH7t1DFQ1-u07LMNvlEgbW)N3xUEhp_|tt!P~I&{66R&|^xE
z8NH7wH|F(#TH`w%0k>=IhJR@Xe{m142#G95D$;nr4`r{tY$C7b0P6?*r9Mqqv9
z-~$k=JMsoy-wYpRZuEOcY7CGZX%;A~fA~tAt!(Zh7*2*oiNqXS>uxL}!c?XqeB+C8
zbr$(#8)%=D1~f@|6sr3|)C8UN>#&D`(YoNdI@g-Vssq3wNQ_#$35L
z^{!ljZ^|Ki{}{Qvf^y>^zM*v{m^#z1^Igv0m}$hRsqf{ngc7bHh*1iLbUN9)sI7L)
zWje@S@TUnPPSWv8U#XzR-rU-7VcUcAeftZ8e4cz8taH*(c=V!nCU-1~CU;t5sLD#1
zZ|26FO6go`@F0c3rs@~Jw4|Ri*cLNVhs1redp&|*FX`}fK|7NXc9EKm-}vy=>y&WV
z3hp0
z&Lx~X`H{fln{t-Nw{PvxsF`dJ%6q5EsjfSc4M0zm^abLf^Q4*)uQ}^EwIgJ1$WpiN
z6W&1y)5{c2{y25p$j&)d72DMW=SQg`Q{ecRK#0kLF^1S*1H(@c@}q5Z=#|rIYdwIa
z&W|GL@9$DI5A|O51e2gO^0EJcOWIp*);|;yfEFE(DM1z7x`F<22IIFFL0p3?c_yjdjQvJm`SV!;tN~$3W#SkFvdYaXQ_j
zXrjzUr}ya6*SC3}MSpuyzOrJM0;H(dWRIoh`4AK}3_Nz`iL}TyEDcGu3$7MEL^Mpv
z+WDDk6Y7hn9mhn22cB3hcKNo05;G}`mok*G%Me3MoK>4DpDzS+
z9AA=0o-CrqSQ9rgZLQ#$4|qVUpZ{F^*jJ=Ckd1`N_}+E|iBX3Q&5h{FADP~Mn(1~E
zRmP$1?}!hU4I7=VqYB=-Ey?fU4yd9x6~~y;^>AwJl{9@;l`|PQs$MiP;7;7
z7Vxw`Sm)Dd*Is6y>QvWtSCl-6zBd3u(mC{W)Tu|(@+kM3`PV94pMd>*u7M#)_B*ah
zesc=yJL^Ks5=y0at<3UP&JL_v>IR1Tx8hTGdt~X>quj49!8FT;vpawWI)yzhI}kuK
z1Xk!p;2menEq&bJH5F4{c%m?6dgO|nVJ^pGY#3hUd4W8%fv)?6@w);W7bPMGn@g6o+J`sC{&5njW*q9c?g-
zZap%tTOBO!Fatx4sk;3MZm4`9>F)>H(z59qoJpj`Y$H5a*dMWsy8(-xvNSJr+%q$R
z2lh4dz}8o}xt|<397W-TgS%Mwjo0uMvQ>kijh4#_Ut-C1tuVqZ^FND<%r2L2!er&x
zk}NBRmX4nAO2>!5Tk8J&H43iPDohV@xG}zVOxKFh;jt%%gLZpX8H*LBs)gLw875G7{LQo#e?eexkIIbXy{>0yH#TFm#Q%urvV=NDi*<>9(#b9|NOGdhu2uB2;3^aIlUfPs}ZePeuk%<3DlCSdnJH*p{7+$=%p&5
z6@BFcE?;u1>{6ev6Yn!|YTM1ia|fPXw{YRBs`VrY*+*MDI;C760}<|(@nkunF!6qy
zsN&}QO37!l;lOXbizFv3o!D^s^Vjqx7E0upQMAw)=_zW7aj?Sb^%%|{iwvj}NLx;V
z&jbMAto_CVFpi!Kn(sfyE7qpBmNZ151w=ubJA8yo4}Rq8hue*`y390llm>
zd>h^2GBYUPlF&15#pq6%xj!2m&nt8dz2`A~Tf@>9%iifFbXaIsE3weycOxZME4~${
zWRp{`L+*F+K|SlM;y9O&x8p2bRGZ``dkikL3ys;WI@Wv0lCC8$mCXwCz4G2Gd8HI_
z-_sQXGuh+4G~FScI?j{E5Qmve=*9#Ac`oj^<;eGV-bPPv;71T
zMMB&-R&V_IjrUEOg}uu8&)@Q!-Bz@?=TlPW^$twcH3zpN@%?Uf`|ej{UtjjU=}OjE
zo!hDs9xS?y@mW9(Q3`@eEGeWFj*;Eu0w;J-Z)UMC2%%|I1AMD&Y4eSgIFl4w)b`NnV6k6na=Xu?=?cOwKB_I9ciTSUh>YX+M!39
z*805EB<~^Fl2iqs^kh&Iq^4>Zbo^8(X?-j3X+fu3o{(a8yE~(TosrRjfEtBqL2{2$
z{r?Gxi_X8n{uPFe*eBFtGnMxFPR_Vkxz78$kmALV-%g3FDe({^ok|M1M7lfYS41`n
zk?eA`@UV8FbNNzn>tXm9(4lh%?r_*;0MF@+^KztOdq%(0E2L%6l8en5(gg{;edWxp
zc^N`qt+!W>0yWl-ig{-xpT(-V4xzCo_`$YJa5*2UL*6E5iMATR>ySOzT)$Z!rNe+c
z44h${a;3L+9p`O8rZp6XEGN$vV}lXRnAe5d%#TjKJSnvA$z`lP5^c9Sxm-5YE|cV{
z+oHSrhu!d>vVC<1`IW;D@^w=m-YV|j9h^NdZ=fx7fbQzMVEV4-%6<9v>6In-u3x!K
z4PN6oObuHi8bKz9*(6MIKg|V+TS_`yjG#D#htHv$ulWE9&-rmM%+J|VbWHC$BcTJ>
zF(sN7!)Hu9vV{d-s9$t`Ua`Vjb>MKGv-rx|o`rg$&{=z}XHR=}1^oFz4DgxDp8MdW
zxy;rK&k^_8s8zshsOL;+nXG>8yul-DT8A$z-)x7{AaB{FZN@TosOj*@BVBMqp%vdO
z1rwdEtF~xn)q!wZJaNJE6Ekz5+(kV!eEx1neNABk$U=$_7NKZ`Zpr0+-bJ%ZJOf|N
zeG8mFu8vsil~a5&2Lw$o;<&Q_$H^!~&N%fUodO0;UM}4X~qP$wGM!wATkn!Nc>*}*wnPny&
zh%+!nJd>RR{o!_yT+WpWJ$A-RxLJhn_UC;=D*?S;HQTb?R=mkKzOHq%bX#(_K4E$8
zBhOmlv}OILt}bb7L7RP^o-;0G4qCm6XIEFSfSyxht-f9Ue(9NVH~6gX}9ehYzM$THknFaj+RL^r)R|cl#1rua#r<#IQ13A>k{r
z(IMqit^ps+WYS9*EEH~$;ZG9f6FgJ_OG=j{N9PjR3=Bb4!eLZYX|Q$&s#}6Jh?xXT
z!e1m`KK&6KKiZ_fb#A=jP;B0^dCR|G4G<1Z-f5f+z3&y-X&N+t=y158FV3q&z5db4
zEHLP7SeYvv*FFmD8N7nrS6tdThASgGeBOt@<8iW=l=s|te>~rMOWRf_0z27}|3
zcYC-Vux#%b=_5bVfX{;?C`t2e=E1SM&`U-Al=-X;UmBDKFbsn+VAF0cv=t4Sy*qEW
zN#@bluUWcvD$6s(l#crQ&W~dCxdpR#E!`4ak6fxbe5uFI3Hd^}5A&7fdRD4$v=+u*
zA!U|QcVEpgk;N(uERCAvGImTYmuY6uuT~9I}!gosnO@8m2c=y4X=<82<9g
zDtLl9@T_*ZaFNT%%tsVoPq=<(`OYSZb`!*0%xp}0wjJ*s8Cbyc^(S*?Gu4BZcKtF>
z2z5y_ukk3xVYUHs%4{5Q>BAApzx$J%#LO@#ARS#vK@7cl`d0A#-cym~UryxoC!Dsv@>%4sY)n8Id
zO}|UYiTv|1MZ`*7{{u+W47X$Wr!6kNPHha6975`-F8kK6xR2G<3>E)lCM2+-_PN*&-Qc;
zG~Zh+9m2V}#AZykJ1N$d^n$zOVl6CTlT7K!8UjZeIr%28+S~c95Z>AC-%}!%P6qTv
zXL+nV9xOAz${OGXsx(uV5l6)bho8);94%USAds>0!tq!-eh~Tzvzvo7uwkOaiGA
zzZA~0RHf{aKyrd`(bYI@Ia>k>^bN9PzcWkcRBm>p8f@|*-2ADLck%hUe^k_{Lj7+R
z$MvY~Un_fhEdz9xBB1iGQVz`gzFx8!`Bklz_Qz3lE3YxYeF|WYFaDGomKiYEv;$0)
zoFRj0MzxPL?4*i0F;q6aWr;Xpz#B{TJkzN8`=v?KZ>DY
zv0m}q&rsr+A(&aFAPa~kM$6U3C>cWIA%S~A>G2e?^vy+nFDSb_dbXkI9ByQr2Gjj&
zr$XuVnBX@K$jy}9Eu19jDdS*@m$s(8ebNje8h%D|cfzZevpC&X+vTDAG)+P!M|dk{Yc6u@4;t1@=k^;JkWUWp=6Dl6#q5R9
zz+mo$(5>0lhAjexUr)jLogPH&DkV9*XB#`pq=t~Lfq77@S^v$wmuv2nwa2h7P_Qtz
z>U5wSf*tlbXX)#Bd2YN`PbKWoeb3wGr7@zcOv6}cYcu#mSYow5G!Es7zslAr5%kB0
zkZj2HV3hqG5(3(fvhxSy%89QE2Z2>0rS&>sBSpCzMv{s$m=X`lEd*h!r}x9Hh{?_yY+tLavC`MQ&Gw5+8>Swvv1yHfzSlw1uR}sjLWdz7
z^vJ0JFsU`t#0m7o3+HB1u;^CM({}_>kJAFeOC^(r^hC^41nal(R+W?_Bw}_C5(fnn
zm2&hBV?bIhp6r={FPvatNG2
z(YjYDe;kE^fmfp&!wVw%b3LZ(F3L@vjpcdbkvhX*RpS#4DPjhLRxv$J<8
z>!ocIuwcHor2&JkSFQQ_pvItfHdgtp4*_YVpupy3lXH*pOepf_bxHakUc~h#WEL(V
z%2Z`ozpZ-WXRvPiqC^^Lg3!1z98kbnxiPYb`h*=yjT
zigX*2PNlINj?4qYf8_xz2JLhxapH>#o37)<{IOksY*nx!KRN)eg14}U(D@Rd{x5qM
zG+ch$++69PmVHUMT#ftnL`TE`TebKR;TT+pUJQ6_B?;UaqL#N9{_X+{Pq_uOGd4l6
z?!Q2L|6Gg}fDhgu6%~K(p_1sCSnLRt4wdCAs2)E20!xQW%C#hNpH{KE~?DK#0zdVkz{m3!}Fbf?kH
zW1+dvrbWs#dr{9!cW$)#Ge;7;cF19Ep1hK-;_tgs^$zS~QMQYbuemAwR`qa?w0fUQ
zwb@RQoZJJw$J=7Ws}4SuKD%9sl7Bue`dIZ@(!oMTKc|QDm?6NIaS)3>`BmYThDWI1
zVmMQ)do(fm3#;TZ=niwFLAC>}%zv<6PdX|y;ZnO)@7H|HOlR1b3nms3oS9?KY(h77
z1!yL=QpRH%0*}m2cP|vDbj%%fdwz~Xmr`A>v^HnS7y2+Ev=e*R{qN)BzU`*l_H7rz
z#~+id(QlndEI9e|lRmnL1*-aUey=jS5&zXCdmyCRAx%@QJHdf%`9WSGneM6l+(f4--dS7joE;Meg*f
zFJwh(HD$H=(?s};8+?gtxI)_&K2^9}_I7%?u7R1;;bzoUD0{F_mRS1o)U~pO9p)T5
zk!4FOSDKn|(?3@qAJAOj21W-5$dJ!vLzw=4S5EzzQ-+du4z=x=b`Len+6x2r)(pRp
z@>?e-Thznr?c{V>FOUfLJ?U#)6iq{nXBY6=w?>D1sSt
zn8>k#!r{*A1ABNXZz*MkNH`kpTwhwZcy4e;;_dwOD$S&(X#2*9pC9+l_om)Gw($;l
zyt=LUuu)^1U?!vLpJ&ic?oGXSY-6pNh+-Q@p|*)%_43ua6`})EYT!fK-3uG{a;~gh
z(|~{$##ZJyt$CVF=hW&Me8^b2@@%aer&`mpmgr(1e#L#EWM*e`MUa2&<>t{K^{Ixh
zi>uN1SC@U4G`9^cf4RBMa2{hwV|za{XWN;(Zr$l?5#(o~8DBG8eYs(gu2R4FfbC&p
z#6*`rZ-guIN8&xg#V(KBunblUuVXBp+KL>-E)0hF)xUopZm+8|L#|YJ(i2Otw
z3VTeNyqQXdBy?aED_qg&cb*}6BnLHbkEIs%Jb3F&Nj?nAIr1zuBy2_0Lo^{boYVZ0
z%ypkbkhQrD-!KiF$-+%`B=3L2>*FU0)B7Ow{&{SR5XRu0yoa*FDE;_k)9>DY|L*I9
zb=RmO>&7h7`uI`H7uFn7`mk_8`qipb_?Mo-V}4eK+>juvB1wg0B3W?7yiw)zh_N7-;|jy76$9+Zh{BveY*1*~c=c>;NY_EPF!z|8rEjqF%^$EMm9%#0
z@V*BXZcmomyWaTot=;B&Cz`U8dg)F9n8nG9cK)MmkE<`Pynl@Bi?g#`^8*XeLhx%`
zFEG0vvy$d}lEdyzVAAJ97}mclecz!Uxe|YF{6AY&T|AI)IqjsDd=@MVW8>%Wf7f#F
zI#-KV6an#6cGRTAh~j%+#KOSI)d{JPZ>{SgrDHc|mRqg2YG)%wMZFgeam#H>KHhT8
zB3HeCRRvzUaR=w!*pl<}V-p5ZnMJaU`_xhCRDQ!sV+p#Q$ij=d?T$}zMe>+OaXE_w
zIkH{hfITA2MWXPY4|Bmaja#+wnYIBtm6Si6ng{J?<~f8dHRDGd3a?n!&9@dV)x?%K
zaLls@`Uh)xg@s?Av0TbLm)P6gj?8{`p2u99n~Y@ps#5FoL&{OZQ#Vu3qcbNwK8RI}
zyMzFC(wObFqV0j28-IWJPn7)pO(FT!NvFvffk`s%=O2Ub@o~4J&@s%6>d;>29e(W%
zy!hLVB1ayDwbw7k|1yLS(;Te&!bu)n&ArEJ_Xri7o`8cTZ&?305rTk;NPSlS#hnS4PWHJ@PP;P?!>4nwFZ0u~2tHfH?8#DsPyXsMd>hTxbnM
zxTv~C-w0Z^(|2Q{VlN5wsHKZtfuAqhMHjMqY!`0Ug%o`ev?$$NHB*H9O3t5QpK0JP
z6q8C?^AFE0%tI>M>HJ|;H=hN^9p`8}8<>k