From e1e6dbdcd0f7efa588fa2abefec763b1c57294d5 Mon Sep 17 00:00:00 2001 From: ra1han Date: Fri, 17 May 2024 21:19:49 +1000 Subject: [PATCH] DataOps for LLMOps - AML Sample (#126) Purpose of this PR is to add the first DataOps sample using AML The PR introduces the following new artefacts - DataOps folder: includes the scripts used by the CI/CD pipelines. named_entity_recognition/data_pipelines folder: a sample data pipeline to prepare the dataset for the NER use case named_entity_recognition_data_aml_cd_workflow.yml: this is the github CD pipeline under the .github/workflows folder --------- Co-authored-by: Raihan Alam Co-authored-by: mohanajuhi166 Co-authored-by: Ritesh Modi Co-authored-by: mohanajuhi166 --- ...ntity_recognition_data_aml_cd_workflow.yml | 114 ++++++ README.md | 12 + dataops/__init__.py | 4 + dataops/common/__init__.py | 4 + dataops/common/aml_data_asset.py | 139 +++++++ dataops/common/aml_data_store.py | 146 +++++++ dataops/common/aml_pipeline.py | 365 ++++++++++++++++++ docs/how_to_configure_dataops.md | 39 ++ docs/images/dataops_llmops.png | Bin 0 -> 106375 bytes .../configs/dataops_config.json | 40 ++ named_entity_recognition/data/source.txt | 16 + .../data_pipelines/aml/prep_data.py | 100 +++++ .../environment/conda.yml | 9 + 13 files changed, 988 insertions(+) create mode 100644 .github/workflows/named_entity_recognition_data_aml_cd_workflow.yml create mode 100644 dataops/__init__.py create mode 100644 dataops/common/__init__.py create mode 100644 dataops/common/aml_data_asset.py create mode 100644 dataops/common/aml_data_store.py create mode 100644 dataops/common/aml_pipeline.py create mode 100644 docs/how_to_configure_dataops.md create mode 100644 docs/images/dataops_llmops.png create mode 100644 named_entity_recognition/configs/dataops_config.json create mode 100644 named_entity_recognition/data/source.txt create mode 100644 named_entity_recognition/data_pipelines/aml/prep_data.py create mode 100644 named_entity_recognition/environment/conda.yml diff --git a/.github/workflows/named_entity_recognition_data_aml_cd_workflow.yml b/.github/workflows/named_entity_recognition_data_aml_cd_workflow.yml new file mode 100644 index 000000000..638823f00 --- /dev/null +++ b/.github/workflows/named_entity_recognition_data_aml_cd_workflow.yml @@ -0,0 +1,114 @@ +name: named_entity_recognition_data_aml_pipeline +on: + # workflow_call allows reusable workflow that can be called by other workflows + workflow_call: + inputs: + subscription_id: + description: Azure subscription id + type: string + required: true + resource_group_name: + description: Azure resource group name + type: string + required: true + workspace_name: + description: Azure ML workspace name + type: string + required: true + aml_env_name: + description: Environment name + type: string + required: true + config_path_root_dir: + description: Root dir for config file + type: string + required: true + default: "named_entity_recognition" + + # workflow_dispatch allows to run workflow manually from the Actions tab + workflow_dispatch: + inputs: + subscription_id: + description: Azure subscription id + type: string + required: true + resource_group_name: + description: Azure resource group name + type: string + required: true + workspace_name: + description: Azure ML workspace name + type: string + required: true + aml_env_name: + description: Environment name + type: string + required: true + config_path_root_dir: + description: Root dir for config file + type: string + required: true + default: "named_entity_recognition" + +jobs: + deploy_aml_data_pipeline: + runs-on: ubuntu-latest + + steps: + - name: Checkout current repository + uses: actions/checkout@v3.3.0 + + - name: Set up python + uses: actions/setup-python@v4 + with: + python-version: 3.9 + + - name: Azure login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Configure Azure ML Agent + uses: ./.github/actions/configure_azureml_agent + + - name: Load the current Azure subscription details + id: subscription_details + shell: bash + run: | + export subscriptionId=$(az account show --query id -o tsv) + echo "SUBSCRIPTION_ID=$subscriptionId" >> $GITHUB_OUTPUT + + - name: Deploy data pipeline + uses: ./.github/actions/execute_script + with: + step_name: "Deploy data pipeline" + script_parameter: | + python -m dataops.common.aml_pipeline \ + --subscription_id ${{ inputs.subscription_id }} \ + --resource_group_name ${{ inputs.resource_group_name }} \ + --workspace_name ${{ inputs.workspace_name }} \ + --aml_env_name ${{ inputs.aml_env_name }} \ + --config_path_root_dir ${{ inputs.config_path_root_dir }} + + - name: Create data store + uses: ./.github/actions/execute_script + with: + step_name: "Create data store" + script_parameter: | + python -m dataops.common.aml_data_store \ + --subscription_id ${{ inputs.subscription_id }} \ + --resource_group_name ${{ inputs.resource_group_name }} \ + --workspace_name ${{ inputs.workspace_name }} \ + --config_path_root_dir ${{ inputs.config_path_root_dir }} \ + --sa_key ${{ secrets.SA_KEY }} + + - name: Register data asset + uses: ./.github/actions/execute_script + with: + step_name: "Register data asset" + script_parameter: | + python -m dataops.common.aml_data_asset \ + --subscription_id ${{ inputs.subscription_id }} \ + --resource_group_name ${{ inputs.resource_group_name }} \ + --workspace_name ${{ inputs.workspace_name }} \ + --config_path_root_dir ${{ inputs.config_path_root_dir }} \ No newline at end of file diff --git a/README.md b/README.md index 187cc8a4b..f7be9601d 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ As LLMs rapidly evolve, the importance of Prompt Engineering becomes increasingl - LLM-infused applications are designed to understand and generate human-like text based on the input they receive. They comprise of prompts that need engineering cadence and rigour. - Prompt flow is a powerful feature that simplifies and streamlines the Prompt Engineering process for LLM-infused applications. It enables users to create, evaluate, and deploy high-quality flows with ease and efficiency. - How do we best augment LLM-infused applications with LLMOps and engineering rigour? This template aims to assist in the development of those types of applications using Prompt flow and LLMOps. +- Bringing discipline to the data preparation for LLM app development by following DataOps best practices. # Solution @@ -57,6 +58,7 @@ Each use case (set of Prompt flow standard and evaluation flows) should follow t - environment : It contains a dockerfile used for running containers with flows for inferencing on Azure webapps. - flows : It should contain minimally two folder - one for standard Prompt flow related files and another for Evaluation flow related file. There can be multiple evaluation flow related folders. - tests : contains unit tests for the flows +- data-pipelines : It contains the data pipelines to generate the datasets (experimentation, evaluation etc.) necessary for the flows. This folder will have sub-folders specific to the data engineering tool - Microsoft Fabric, Azure ML etc. Additionally, there is a `experiment.yaml` file that configures the use-case (see file [description](./docs/the_experiment_file.md) and [specs](./docs/experiment.yaml) for more details). There is also a sample-request.json file containing test data for testing endpoints after deployment. @@ -70,6 +72,8 @@ Additionally, there is a `experiment.yaml` file that configures the use-case (se - The 'llmops' folder contains all the code related to flow execution, evaluation and deployment. +- The 'dataops' folder contains all the code related to data pipeline deployment. + - The 'local_execution' folder contains python scripts for executing both the standard and evaluation flow locally. # Documentation @@ -133,6 +137,14 @@ python -m pip install promptflow promptflow-tools promptflow-sdk jinja2 promptfl 5. Write python scripts similar to the provided examples in local_execution folder. +# DataOps + +DataOps combines aspects of DevOps, agile methodologies, and data management practices to streamline the process of collecting, processing, and analyzing data. DataOps can help to bring discipline in building the datasets (training, experimentation, evaluation etc.) necessary for LLM app development. + +The data pipelines are kept seperate from the prompt engineering flows. Data pipelines create the datasets and the datasets are registered as data assets in Azure ML for the flows to consume. This approach helps to scale and troubleshoot independently different parts of the system. + +For details on how to get started with DataOps, please follow this document - [How to Configure DataOps](./docs/how_to_configure_dataops.md). + ## Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a diff --git a/dataops/__init__.py b/dataops/__init__.py new file mode 100644 index 000000000..cfb6b7af7 --- /dev/null +++ b/dataops/__init__.py @@ -0,0 +1,4 @@ +""" +dataops module. + +""" diff --git a/dataops/common/__init__.py b/dataops/common/__init__.py new file mode 100644 index 000000000..863836886 --- /dev/null +++ b/dataops/common/__init__.py @@ -0,0 +1,4 @@ +""" +common module. + +""" diff --git a/dataops/common/aml_data_asset.py b/dataops/common/aml_data_asset.py new file mode 100644 index 000000000..058725181 --- /dev/null +++ b/dataops/common/aml_data_asset.py @@ -0,0 +1,139 @@ +""" +This module creates the data assets. +""" +from azure.identity import DefaultAzureCredential +from azure.ai.ml.entities import Data +from azure.ai.ml import MLClient +from azure.ai.ml.constants import AssetTypes +import os +import argparse +import json + +pipeline_components = [] + +""" +This function creates and returns an Azure Machine Learning (AML) client. +The AML client is used to interact with Azure Machine Learning services. + +Args: +--subscription_id: The Azure subscription ID. +This argument is required for identifying the Azure subscription. +--resource_group_name: The name of the resource group in Azure. +This argument is required to specify the resource group in Azure. +--workspace_name: The name of the workspace in Azure Machine Learning. +This argument is required to specify the workspace in Azure Machine Learning. +""" + + +def get_aml_client( + subscription_id, + resource_group_name, + workspace_name, +): + aml_client = MLClient( + DefaultAzureCredential(), + subscription_id=subscription_id, + resource_group_name=resource_group_name, + workspace_name=workspace_name, + ) + + return aml_client + + +""" +This function registers a data asset in Azure Machine Learning. +The data asset is identified by its name and description, and is associated with a specific data store and file path. + +Args: +--name: The name of the data asset. +This argument is required to specify the name of the data asset. +--description: The description of the data asset. +This argument is required to provide a description of the data asset. +--aml_client: The Azure Machine Learning client. +This argument is required to interact with Azure Machine Learning services. +--data_store: The name of the data store in Azure. +This argument is required to specify the data store in Azure. +--file_path: The file path of the data asset in the data store. +This argument is required to specify the file path of the data asset in the data store. +""" + + +def register_data_asset( + name, + description, + aml_client, + data_store, + file_path +): + target_path = f"azureml://datastores/{data_store}/paths/{file_path}" + aml_dataset = Data( + path=target_path, + type=AssetTypes.URI_FILE, + description=description, + name=name + ) + + aml_client.data.create_or_update(aml_dataset) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--subscription_id", + type=str, + help="Azure subscription id", + required=True, + ) + parser.add_argument( + "--resource_group_name", + type=str, + help="Azure resource group", + required=True, + ) + parser.add_argument( + "--workspace_name", + type=str, + help="Azure ML workspace", + required=True, + ) + parser.add_argument( + "--config_path_root_dir", + type=str, + help="Root dir for config file", + required=True, + ) + + args = parser.parse_args() + + subscription_id = args.subscription_id + resource_group_name = args.resource_group_name + workspace_name = args.workspace_name + config_path_root_dir = args.config_path_root_dir + + config_path = os.path.join(os.getcwd(), f"{config_path_root_dir}/configs/dataops_config.json") + config = json.load(open(config_path)) + + aml_client = get_aml_client( + subscription_id, + resource_group_name, + workspace_name, + ) + + data_store = config["DATA_STORE_NAME"] + data_asset_configs = config['DATA_ASSETS'] + for data_asset_config in data_asset_configs: + data_asset_name = data_asset_config['NAME'] + data_asset_file_path = data_asset_config['PATH'] + data_asset_description = data_asset_config['DESCRIPTION'] + + register_data_asset( + name=data_asset_name, + description=data_asset_description, + aml_client=aml_client, + data_store=data_store, + file_path=data_asset_file_path + ) + + +if __name__ == "__main__": + main() diff --git a/dataops/common/aml_data_store.py b/dataops/common/aml_data_store.py new file mode 100644 index 000000000..ec7111c44 --- /dev/null +++ b/dataops/common/aml_data_store.py @@ -0,0 +1,146 @@ +""" +This module registers the data store. +""" +from azure.ai.ml import MLClient +from azure.identity import DefaultAzureCredential +from azure.ai.ml.entities import AzureBlobDatastore, AccountKeyConfiguration +import os +import argparse +import json + +pipeline_components = [] +""" +This function creates and returns an Azure Machine Learning (AML) client. +The AML client is used to interact with Azure Machine Learning services. + +Args: +--subscription_id: The Azure subscription ID. +This argument is required for identifying the Azure subscription. +--resource_group_name: The name of the resource group in Azure. +This argument is required to specify the resource group in Azure. +--workspace_name: The name of the workspace in Azure Machine Learning. +This argument is required to specify the workspace in Azure Machine Learning. +""" + + +def get_aml_client( + subscription_id, + resource_group_name, + workspace_name, +): + aml_client = MLClient( + DefaultAzureCredential(), + subscription_id=subscription_id, + resource_group_name=resource_group_name, + workspace_name=workspace_name, + ) + + return aml_client + + +""" +This function registers a data store in Azure Machine Learning. +The data store is identified by its name and description, +and is associated with a specific storage account and container. + +Args: +--name_datastore: The name of the data store. +This argument is required to specify the name of the data store. +--description: The description of the data store. +This argument is required to provide a description of the data store. +--sa_account_name: The name of the storage account in Azure. +This argument is required to specify the storage account in Azure. +--sa_container_name: The name of the container in the storage account. +This argument is required to specify the container in the storage account. +--sa_key: The key of the storage account. +This argument is required to authenticate with the storage account. +--aml_client: The Azure Machine Learning client. +This argument is required to interact with Azure Machine Learning services. +""" + + +def register_data_store( + name_datastore, + description, + sa_account_name, + sa_container_name, + sa_key, + aml_client +): + store = AzureBlobDatastore( + name=name_datastore, + description=description, + account_name=sa_account_name, + container_name=sa_container_name, + credentials=AccountKeyConfiguration(account_key=sa_key) + ) + aml_client.create_or_update(store) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--subscription_id", + type=str, + help="Azure subscription id", + required=True, + ) + parser.add_argument( + "--resource_group_name", + type=str, + help="Azure resource group", + required=True, + ) + parser.add_argument( + "--workspace_name", + type=str, + help="Azure ML workspace", + required=True, + ) + parser.add_argument( + "--sa_key", + type=str, + help="Storage account key", + required=True, + ) + parser.add_argument( + "--config_path_root_dir", + type=str, + help="Root dir for config file", + required=True, + ) + + args = parser.parse_args() + + subscription_id = args.subscription_id + resource_group_name = args.resource_group_name + workspace_name = args.workspace_name + sa_key = args.sa_key + config_path_root_dir = args.config_path_root_dir + + config_path = os.path.join(os.getcwd(), + f"{config_path_root_dir}/configs/dataops_config.json") + config = json.load(open(config_path)) + + aml_client = get_aml_client( + subscription_id, + resource_group_name, + workspace_name, + ) + + storage_config = config['STORAGE'] + storage_account = storage_config['STORAGE_ACCOUNT'] + target_container_name = storage_config['TARGET_CONTAINER'] + + register_data_store( + name_datastore=config["DATA_STORE_NAME"], + description=config["DATA_STORE_DESCRIPTION"], + sa_account_name=storage_account, + sa_container_name=target_container_name, + sa_key=sa_key, + aml_client=aml_client + ) + + +if __name__ == "__main__": + main() diff --git a/dataops/common/aml_pipeline.py b/dataops/common/aml_pipeline.py new file mode 100644 index 000000000..049bca6cb --- /dev/null +++ b/dataops/common/aml_pipeline.py @@ -0,0 +1,365 @@ +""" +This module creates a AML job and schedule it for the data pipeline. +""" +from datetime import datetime +from azure.ai.ml.dsl import pipeline +from azure.identity import DefaultAzureCredential +from azure.ai.ml import command, UserIdentityConfiguration +from azure.ai.ml import Output +from azure.ai.ml import MLClient +from azure.ai.ml.entities import ( + JobSchedule, + CronTrigger +) +import os +import argparse +import json + +pipeline_components = [] + +() + +""" +This function defines a AML pipeline for data preparation in Named Entity Recognition (NER) tasks. +The pipeline is identified by its name and description, and consists of a data preparation job. + +The data preparation job is the first component in the pipeline components list. +The output of the data preparation job is a target directory, which is returned by the pipeline. + +Decorator: +@pipeline: A decorator to declare this function as a pipeline. +It takes two arguments - name and description of the pipeline. + +Returns: +A dictionary with the target directory as the output of the data preparation job. +""" + + +@pipeline( + name="ner_data_prep_test", + description="data prep pipeline", +) +def ner_data_prep_pipeline( +): + prep_data_job = pipeline_components[0]( + ) + + return { + "target_dir": prep_data_job.outputs.target_dir + } + + +""" +This function executes a data preparation component for a data pipeline. +The data component is identified by its name, display name, +and description, and is associated with a specific environment, storage account, +source and target containers, source blob, assets, and custom compute. + +Args: +--name: The name of the data component. +This argument is required to specify the name of the data component. +--display_name: The display name of the data component. +This argument is required to specify the display name of the data component. +--description: The description of the data component. +This argument is required to provide a description of the data component. +--data_pipeline_code_dir: The directory of the data pipeline code. +This argument is required to specify the directory of the data pipeline code. +--environment: The environment for the data component. +This argument is required to specify the environment for the data component. +--storage_account: The storage account in Azure. +This argument is required to specify the storage account in Azure. +--source_container_name: The name of the source container in the storage account. +This argument is required to specify the source container in the storage account. +--target_container_name: The name of the target container in the storage account. +This argument is required to specify the target container in the storage account. +--source_blob: The name of the source blob in the source container. +This argument is required to specify the source blob in the source container. +--assets: The assets in the target container. +This argument is required to specify the assets in the target container. +--custom_compute: The custom compute for the data component. +This argument is required to specify the custom compute for the data component. +""" + + +def get_prep_data_component( + name, + display_name, + description, + data_pipeline_code_dir, + environment, + storage_account, + source_container_name, + target_container_name, + source_blob, + assets, + custom_compute +): + data_pipeline_code_dir = os.path.join(os.getcwd(), data_pipeline_code_dir) + + # Initialize an empty list to store components + prep_data_components = [] + asset_str = ":".join(map(str, assets)) + + prep_data_component = command( + name=name, + display_name=display_name, + description=description, + inputs={}, + outputs=dict( + target_dir=Output(type="uri_folder", mode="rw_mount"), + ), + code=data_pipeline_code_dir, + command=f"""python prep_data.py \ + --storage_account {storage_account} \ + --source_container_name {source_container_name} \ + --target_container_name {target_container_name} \ + --source_blob {source_blob} \ + --assets_str {asset_str} + """, + environment=environment, + compute=custom_compute, + identity=UserIdentityConfiguration() + ) + prep_data_components.append(prep_data_component) + + return prep_data_components + + +""" +This function creates and returns an Azure Machine Learning (AML) client. +The AML client is used to interact with Azure Machine Learning services. + +Args: +--subscription_id: The Azure subscription ID. +This argument is required for identifying the Azure subscription. +--resource_group_name: The name of the resource group in Azure. +This argument is required to specify the resource group in Azure. +--workspace_name: The name of the workspace in Azure Machine Learning. +This argument is required to specify the workspace in Azure Machine Learning. +""" + + +def get_aml_client( + subscription_id, + resource_group_name, + workspace_name, +): + aml_client = MLClient( + DefaultAzureCredential(), + subscription_id=subscription_id, + resource_group_name=resource_group_name, + workspace_name=workspace_name, + ) + + return aml_client + + +""" +This function creates a pipeline job with a data component. +The pipeline job is associated with a specific component name, display name, +description, data pipeline, code directory, environment, storage account +source and target containers, source blob, assets, and custom compute. + +Args: +--component_name: The name of the data component. +This argument is required to specify the name of the data component. +--component_display_name: The display name of the data component. +This argument is required to specify the display name of the data component. +--component_description: The description of the data component. +This argument is required to provide a description of the data component. +--data_pipeline_code_dir: The directory of the data pipeline code. +This argument is required to specify the directory of the data pipeline code. +--aml_env_name: The name of the Azure Machine Learning environment. +This argument is required to specify the Azure Machine Learning environment. +--storage_account: The storage account in Azure. +This argument is required to specify the storage account in Azure. +--source_container_name: The name of the source container in the storage account. +This argument is required to specify the source container in the storage account. +--target_container_name: The name of the target container in the storage account. +This argument is required to specify the target container in the storage account. +--source_blob: The name of the source blob in the source container. +This argument is required to specify the source blob in the source container. +--assets: The assets in the target container. +This argument is required to specify the assets in the target container. +--custom_compute: The custom compute for the data component. +This argument is required to specify the custom compute for the data component. +""" + + +def create_pipeline_job( + component_name, + component_display_name, + component_description, + data_pipeline_code_dir, + aml_env_name, + storage_account, + source_container_name, + target_container_name, + source_blob, + assets, + custom_compute +): + prep_data_component = get_prep_data_component( + name=component_name, + display_name=component_display_name, + description=component_description, + data_pipeline_code_dir=data_pipeline_code_dir, + environment=aml_env_name, + storage_account=storage_account, + source_container_name=source_container_name, + target_container_name=target_container_name, + source_blob=source_blob, + assets=assets, + custom_compute=custom_compute + ) + + pipeline_components.extend(prep_data_component) + + pipeline_job = ner_data_prep_pipeline() + + return pipeline_job + + +""" +This function schedules a pipeline job. +The schedule is identified by its name, cron expression, and timezone, +and is associated with a specific job and Azure Machine Learning client. + +Args: +--schedule_name: The name of the schedule. +This argument is required to specify the name of the schedule. +--schedule_cron_expression: The cron expression for the schedule. +This argument is required to specify the cron expression for the schedule. +--schedule_timezone: The timezone for the schedule. +This argument is required to specify the timezone for the schedule. +--job: The job for the schedule. +This argument is required to specify the job for the schedule. +--aml_client: The Azure Machine Learning client. +This argument is required to interact with Azure Machine Learning services. +""" + + +def schedule_pipeline_job( + schedule_name, + schedule_cron_expression, + schedule_timezone, + job, + aml_client, +): + schedule_start_time = datetime.utcnow() + cron_trigger = CronTrigger( + expression=schedule_cron_expression, + start_time=schedule_start_time, + time_zone=schedule_timezone + ) + + job_schedule = JobSchedule( + name=schedule_name, trigger=cron_trigger, create_job=job + ) + + aml_client.schedules.begin_create_or_update( + schedule=job_schedule + ).result() + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--subscription_id", + type=str, + help="Azure subscription id", + required=True, + ) + parser.add_argument( + "--resource_group_name", + type=str, + help="Azure resource group", + required=True, + ) + parser.add_argument( + "--workspace_name", + type=str, + help="Azure ML workspace", + required=True, + ) + parser.add_argument( + "--aml_env_name", + type=str, + help="Azure environment name", + required=True, + ) + parser.add_argument( + "--config_path_root_dir", + type=str, + help="Root dir for config file", + required=True, + ) + + args = parser.parse_args() + + subscription_id = args.subscription_id + resource_group_name = args.resource_group_name + workspace_name = args.workspace_name + aml_env_name = args.aml_env_name + config_path_root_dir = args.config_path_root_dir + + config_path = os.path.join(os.getcwd(), f"{config_path_root_dir}/configs/dataops_config.json") + config = json.load(open(config_path)) + + component_config = config['DATA_PREP_COMPONENT'] + component_name = component_config['COMPONENT_NAME'] + component_display_name = component_config['COMPONENT_DISPLAY_NAME'] + component_description = component_config['COMPONENT_DESCRIPTION'] + + storage_config = config['STORAGE'] + storage_account = storage_config['STORAGE_ACCOUNT'] + source_container_name = storage_config['SOURCE_CONTAINER'] + source_blob = storage_config['SOURCE_BLOB'] + target_container_name = storage_config['TARGET_CONTAINER'] + + path_config = config['PATH'] + data_pipeline_code_dir = path_config['DATA_PIPELINE_CODE_DIR'] + + schedule_config = config['SCHEDULE'] + schedule_name = schedule_config['NAME'] + schedule_cron_expression = schedule_config['CRON_EXPRESSION'] + schedule_timezone = schedule_config['TIMEZONE'] + + data_asset_configs = config['DATA_ASSETS'] + assets = [] + for data_asset_config in data_asset_configs: + assets.append(data_asset_config['PATH']) + + custom_compute = config["COMPUTE_NAME"] + + aml_client = get_aml_client( + subscription_id, + resource_group_name, + workspace_name, + ) + + job = create_pipeline_job( + component_name, + component_display_name, + component_description, + data_pipeline_code_dir, + aml_env_name, + storage_account, + source_container_name, + target_container_name, + source_blob, + assets, + custom_compute + ) + + schedule_pipeline_job( + schedule_name, + schedule_cron_expression, + schedule_timezone, + job, + aml_client + ) + + +if __name__ == "__main__": + main() diff --git a/docs/how_to_configure_dataops.md b/docs/how_to_configure_dataops.md new file mode 100644 index 000000000..f56b13cbd --- /dev/null +++ b/docs/how_to_configure_dataops.md @@ -0,0 +1,39 @@ +# How to Configure DataOps + +Implementing the DataOps pattern will help manage and scale the data pipelines. The following sections will explain the necessary steps to integrate DataOps into the LLMOps pattern. + +## Prerequisites + +This document assumes that you have already gone through [How to Onboard new flow](./how_to_onboard_new_flows.md) and implemented the steps. Once you have all the components from the document in place, you can start setting up DataOps. + +**Data Pipeline Environment:** You will need storage account containers to store the raw and processed data used in the sample DataOps implementation. + +## The Sample Implementation + +This repository includes an implementation of DataOps for the `named_entity_recognition` sample. The sample implementation uses Azure Machine Learning to run the data pipelines. + +The data pipeline loads data from the source system, processes it, and stores it in the target location. The processed data is stored as JSONL files, which are registered as data assets + +![dataops llmops](images/dataops_llmops.png) + +The sample CI/CD pipelines manage the lifecycle of the data pipelines. They build and deploy the pipelines to the target environments. The CI/CD pipelines also register the required Datastores and Data Assets according to the processed JSONL files for Promptflow to consume. + +If you are not using data pipelines to create the data assets, the Promptflow flows will use the JSONL files inside the `data` folder to create the data assets. + +## Steps to Configure DataOps + +Follow these steps to configure DataOps for your flow: + +**New Folder for data pipelines** The data pipelines for the `named_entity_recognition` flow are inside a sub-folder named `data_pipelines`. Create a similar folder under your flow folder for the data pipelines. + +**Configure source and target location** As mentioned earlier, the data pipeline loads data from a source storage account container and stores the processed data in a target storage account container. The processed data in the target storage account gets mapped to the azure machine learning Data Asset. Create these two containers and upload the source dataset to the source container. + +**Data Pipeline Configuration:** The `dataops_config.json` file contains configurations for the data pipeline. + +You can start by copying an existing config file and modify it with relevant values. Provide valid values for all the configuration elements. + +**Updating Flow Configuration:** The configuration of the use-case is managed by the `experiment.yaml` (sets the flow paths, datasets, and evaluations). The `experiment.yaml` in the repo uses local data files. If you are using DataOps,this config file needs to point to the Data Asset path. The data asset path will look like this `azureml://datastores/[data_store_name]/paths/[file_path]` + +Update any datasets elements in the `experiment.yaml` files and make sure the source field point to the Data Asset path in format `azureml:` + +**Create Data Pipelines** The `named_entity_recognition` use case provides a sample python file for a data pipeline - [prep_data.py](../named_entity_recognition/data_pipelines/aml/prep_data.py). This is a placeholder for your data pipeline code. Replace it with your actual data transformation script. \ No newline at end of file diff --git a/docs/images/dataops_llmops.png b/docs/images/dataops_llmops.png new file mode 100644 index 0000000000000000000000000000000000000000..6d1ecc07c78d111b8aab439d1b27faee436557cd GIT binary patch literal 106375 zcmeEt^;4Wpw`~%FJHg%E8EkNOcXxLf+=9EiyE_bS!5s#72<{L(5Fqz`&pG#=?~k~v zs{47mYX8)=cdgZXbw?>HN+BcQBYgVw30X#3T=ml@DC>XzkKthcnG40s;r{u2c2kuS z{Zv0oc=pfYtCfg?$fr+D35ahd(EqIAouzf$K7B$N`geRDbE-7|^yzPzjJSxpm*M5R zRU@^I4|TYJQTCispp*A*TUX5$nCOP}6AV;8YYY|MPj<}Wua2SMEs_OPI$C;B5eYce zuM-xGfwbcWHWG<3(Ab$HJh4}|4p!y8RoCZt8ml>TL-y{A5W4`f)Yd&88fu6BnDB1rR;r`{O(EC3E^lAQoz`xt^ z|M%g)lR}@SGB(n5cj$j`aPpmy!W=2+ed1@cbVT%KY=;IKy$AbAo3!aaohr#XBIn(s}IY!q@=|tg*&_w$Xvd z$P6ybPMv`I&?ZKpisomBF{tyon9Ly|7mXk@vA$>ZP(dgip&jpNncYs+3kydqu}um; z!IFe7p^X%g#eC65o2=WHur9hpI+(b^(N9kZE{unNeKR3)O|xr4>6xxpRxxmo=;%kd zuO{8!vFP<#Z;h_RWm^OvTRhM0!Lthqvn& zGr=l|q*v)wpy=V?NoFl9b|NAkXnNnj#=0E$V0qYC!ZhUyN4PRT=`{K{5_h&71&p^` zvw%4=fF^G$aM}>fay{Aur24$JRx^hg{G}_#*(j#F_y(O%>ty6ec!!Bg zUfK^$#mjyaL4@h4DzYW_=yQun6p}iljwZ!ditBtu`#f!zBx4DaO3*e&Ydd81u(gbi zQnjm*c^u?J&>(zJlU=7`*)E4up$l(5&pD7K}^MLROY#B|GLB7gXRK zC^S>DU9z5$T`o%zK1)y0%m8m(C;45Tg{J6M5Vs7Moe~iJ4Zl|=pZq8wdrDiA8l?+R zIzR}EPVSH;13*wlHC1Owg03OBFxKOEn<_+ZubrZ`>O@K#WW`b6CQq}AtezI)cC2gx z?#Nao0mSgCh}y<@tzS2%uW;a~#u~4R5r;hFcDh0U_*rUF_-Pb2p|=hZT!v4W`^L-+Vs>iU*&e?f04qmOqfO#5kN1SvbxH*V zRB?rz-my-hx05lw*~9=3~!~b7$g|Op516L3UrhJ!0#+xWtEh$4PqIk9Kl& zY}4it!tvVHR!ce~WbVqOrmpW8I$-H{Z)ax98J43>`sdN{_va98<~V(&s~nDd%(1?N zJ1TB9nvcv@>`DSh-%ciiZsyT1SnU(FG}oVr?tTDaCh%c~+$nW3;ujKKppX^?-Do@2 zMIdd#wAFXqr9!j$s1u*jp}fft11PpcqynO6v57c=8lO*Viw2ZWTF*InRcEsnB6GaT zieVZn6*Qab2uBxeFl~|Sm2{}=Dn#*I?tg{+M@d~5dQ(m5Y&sC9KW!xuaJn*&AM@lC z5jrJy;-zIc!Q>U)D)6OUV~LF>np%M45w|6Jw)-RR^QiQ-^?!_{Nz{T?8uK3@W%JuJ z5x5X#lDq8GEK4pp(fhUXA5F}YdLI1TCW5Bx_^9ycC!aR}eFSN^4*2`7OO|65O?DnA zZYhgvMtLJUqlA`>A>}SLgv{6yiFEk{g5c98~&hI!`OZoN+OtBj$yBKNVw z+A7r?>+T$%Eu~~~3qF}4Lx0eY@6KCiE6|jxrN^$YPG>-ra3BQvdrypAAsn&&!jV^faM|91%bmSN@2^YT;!wTgPWLSA^BxsdG43057&%l%rbE z!Nd|_C|W-bU8ux+bz73!);BPp6t4%1h#LImwYF>5m%T z?0vdWAgzf@PV0UfQoSOxNK(-0)8bA|myUAsK=#e)0m@PUuPn3-rbM4Jie`p>b8Osv z&S8jmtrMeZN&9z^=2%K2OV4`t85sXO6tMz>61pUK8C^&LSi{*FYwemn(v$PG3^+cK zyr|BWkhobpYRe9pKww}R25sel_6e4G9X*S;*A!qKVe?*eTt_kQ@y&>v1bib|ZWiju ziDF?k=t#^`(Yt=##W?AE!Or|YdPBBaoLp!&E`fgI*i@b0U_jcO0S{^h*D=Mp@>3%jg+w?>j%$6Cb6Y6BgbD_owobM6pa*o^11UdwMCdHs#^VK;DCJWXSP=}Z+$MH~a z)h`I-jM<)0YW`_3rSioOc_V}wV$N$8yqA{dE+a_vi=UNLocHJ+Dx*tk6D%zXY|Df!kzb|D+YRYJhzIy+j9M;EeqX*5b( zEZuEmX1jrn?5bdL$#zS=@@s$a!fS7-#_MVjKKEwYjIM}HQEY>-MOXwexDnGrhlgc$ z+-){qau{58+m3~+2Gas}#SXOC>hhTqS!{A!ivId`v?8%an;BPs8|;NyoGpcms=KzH zJu)z{-Es3%Wvlnu<8puzAF!0;dJ4ubI@a#;_F~pv*_uBOAWwzaxtv=TLCJ0{qFpWP z?<8&Mx$MSp4P}}nyo~iv(pe;OSUT`gvLo`>|KWP#&RE|Y9=BsN%503w*i6#h6aF@= z46k~Pvx=$Mh^~t0ndoAlQVKmw+u1k*c$pAksh*vID=cP|sbqf!j-D+~#q3}) zZ*vMKB=5b<^}bnyV}9C#L<@$)Y-}2{yf~D5G!^2KGz~VQ_&sS~9AZ9K7Ggd>)TfBW zHgoYG_a(AsizFPtLw-07uO^E`KGm)a1j`b{49%l(Nt<}1>s)w`_<2_;dl4Kr2pBH1 zoV~u74;T@)oWTT2{svk)k!k0Q9Smq%qlVW5>buT*^?sSt{)m5djm&i`_rFy$M$v^| zE|PXaQPG)m?dK;ZL*;aL{Xzby^9hF6VkK~&G%VJ?k}eKi(uTl=)j^FUXa4haEAgQC zy~o{{;W6hZphqgRm2fmVZn#RZO9y~oQ}$jbogvA+s_-8tptl|sZ7o+&+j`=xh+62S znVyzD8!v_r5nf(R=pQlAX>i>^Yg+rSG^@TilKcQ7JD1>A>+i^MRh);y^W!MFW|)vv z#3So@=aqdF`YOORpss0+q3yc1I8Wy437W{R9W{zd_x6rwkt^m-dWQC;P z>hij?zjDfAqkKPS{UHw-)y6+qnGpEB=AW<^GY1Y;#~S-S7_Ad+304$5AQn|CNoX zT_xBAD2{7)Bo>@!xhum!$T5b)IF(yxdMIDy3<)N2gM@lgyp@gd-ed1>F0FsraPu1_ zxvl=FWxT^lII@mQ298!oux)ptwj3lF^Y`Vvxn$C*bC)fFWPqOdoGng+E)=7*d&%3F z9b|-nXA2m%sAC~JuT9Igjl?c@`Sm>ne0mz3NSezL?U2lQ?GiW?59mOIbVl-FGKun{ zyJTb6SP;DZRzc8T51ppvgr?0(W83cOS!XqSWMI)-47(ToYTlTn4P-^Y41#=c_br+s zvpt{xbSNa+0)gru+3S)d%^hxCp2K4#{UsIKKb3zxxmJ-G|kh~Aw#dM=;2M&VY$ z-+0x)x6)^@F5rUQB<&W9&r(-XlsL-mM5s=~)nMXXmw^=Lsah=83?W>19ijNW6(#&E zx_!n|7`1U;&FphTNO6!}6ZH4eqp+TAp*6x+-Ls6~WkPaYbDiJCXJVdLA8paT>D$F1SBi&6LI2Ap zXUHT5h{U10S$>Acv*i2_B~=UG?bv&6Y@Uly>ftdRmndhdZ@C|lST_dOCXKd^tWNoF ziSMCtJ_df2RF>jv!AT+j6*SNe?a9Jf&!g1QuMoFO)??Gp%+@E$#+t zuCOahN4khb8eZl1W`39{ad)PJDYp&RA-S1;<|4Jx642YFir#=3RcaixOX{S@k!{qb z!c3h)(eGWnoGg3d|7y?lKp|vxQ8^$+84{Md_TkQp$hPne@G|c6Iq`?E@c(tsC1TEG zoTXh1p+DkTd_2u8(~0iTJnD2{-vC8K7f;xtpg{dqNS50%YBMtJPGzZoWt(U)y(DB= z>a!tpm}2iNSPwBVs2bkD{#k#Sf__!*BR-@D)1eu3*oseAQ-&_+{w(z?>W^R~MVbI^ ziOFuU;DTtdh5)EMrD#y@wQ9K8FQjHrAz}f*BDDxs?knerA1AAMk>lz9Z7|*Nffh1P z7rIO=CK~7w2}(_*JjC(O5qW~C;#`Q123g7`WAQq{=p=6@7(iI=tF4m~?j{R@uiooj zuZkM%5!cyV%Trkv)xoNzl2_rK@T>wjL*i zG9VrL+B&md>*zNN?cSPv5fxXz+?1zgiH|pxsRT5pZEK!%8@1a3^Ew@AFc!GC5y+!t z`5PGN!T5g@cbk)g+8}I0v-x>mQWL@`Qu?av5li+hCP@mg;gHXLQ8JIIl`LrrpfBdS zu!LAs91!W?J`BB{!8E^#mV3-eE^#4aGrS&$TNgI$*DRY|GH~zH8c@%==#v7^5t&Pk zWV(}CfgZz_kf4Qb@f8++y1nAMeaw_3mcgE}0E`0G-dov;h@+-Ex*vXAi0Hea?!?ue zgn>K(Dv-+j3oET;hE=b)ztvc7Z5-E*KMOWg!!hXV;Z`v68JZy~=sWO7VMh)B_5;Vt z3e{UHtS#BqvSrDgs?hURt78ow*p!|x%O2Z*wUYSb%=NsJr<0GaaH>htRhd~E9WG%3 zQLItdVhIN0?6HcxoGU!tOBdyX8D5j?y02YnVK?u<7T$PU7PBIYHV$>*nM?gYjDr|8 z+w~|5bio2WrSBLEXUS(-<-GfVAH#(~eC4P=zdZ+jO1SKUgMw%$Bu?X>rFiSDUVT9sq#D_N`V(RZ=T!?W zk{s(8m|cwBwvIKc=?qy3tLwm^*IT`)t&L2+6GE0h$Q*v!X6B&Fg5)_gK;3ri)vpPdp9G=u@;HEIpTKYpw`A# zoahNM=Jla$e=m)+X88S!zWeMShVIB6S?R}3RHGE6b+k_&q+^cb2AY7+3LO?^MNqm! zd^FE6z2fK)3~G8NXiA8oyv@Y}ioT0C!#&L1KcIQD3!5ql|LKuGQ=@01-zImeuwSNN z9u$0)wi1lBHK)6UCz?9v;fv+R0CyY-hBZL@2CJ7iXF!p(aA{n8s5+bzH#)7`J7p-+ zR!3^m76*KpL<-FF5ruG$n8W#h|rVZK^L;M~?7C>_YL1Ry%q z7Kl`c_%Fe+A>{@n`k|2H)h_|TETyjC!(PeBFF*^jkerS2x2le2)*_Td2X*O-sjn>{ zJv^%3MuSzloq7fg{XQ1`^t`h=){6S#q&jq=GzSJ*cC*csf`=NysqasT=|^+nub9H$ z!zGt1xenq8eT(V*4xglcO_bb>?KQnW1?U<#;C3`?)K^+#=bRaw%L+91OcV-Y*L}@8 zm01~@Je}%*ywD$K7>8t7#d0x%vUF5Iy!6D35G1k4=Ul{&nE*|i zic$y32u1@F(tac*m6x8lyQOUU5Uqgvqwxzu*^1Ju!@BjT~0$0#xKlQhfJFezavnGBX70bd-%OwqyF^&b2EVX zs59)5mUu+dduD3>w_{y&a>ll$H(BD5uy&gLupbw^I`!P`UXW`G^AE!ZVER0T0FL58OvM18DYu12xC(NS5qQx{)arf zW$0Tgy;@@wFzbX|xC3vgT^MDS3{ljs3)AanX%F>&I|af5YY}<>D8<#(9fj@?tvOby zxXLQ=<=#ezu;OUVS`9tEjD?-$BA%XjXEPpaa&R#EDs)c9%y{tyQ!^lU=0~gXeB0Dt z&+qIOQb*=b_C%-5U#6@QjrgO?<l`l-45G3pYi$3OOW)fR?YB7E+k`X^cg}#a@YG zme7sD6jpe$r=|2o6>?}Oa@vXtdvxT){NgdVgI*!cztNtijeRMtk$TfD` zSY-FV9*HBdw5M!6?|u5+>>+ysnC`0~omw8@GS&hXClamPm2P=jFB(K!@weyaso%3B z8Nb$X`lD!Y3`YuODS)%+G<3E)j&etK5@Q&fW%f~?DXp^I2BQq8koEDmz4+Ljg77;2 z+;Hbj42#@CfpcE}KhZCm!7y<*GKWKi$UtSV%4EBbk?6`D1vCW&@;zmw@8r zH#e%{*M-!E+LN_6Q-nBZz{h=GP+4f7u0`+Cbk`WOsX6c@HQuW=5M=-38Ky9>985;9 zM&ZRcR9%7RP@2`sLDhfg%WBvU+f5@Bezs9kxzCl4&e`2lekPxVVZq5n(W-!02j?0s z;k)S$>WFt1Bw1vk6hq9FwD}{gT7Ny9MtRKY#o=0m5og%gNdPm2t3md zwg?G}2jQ`hNI`T&>5q+JFvKuE`K15c!AtHg>4|I>l*&@mh73Bi*f_ zdhbX=yzeOlrWPCKT>{~UuI(_fow8D}Eg2%4KUeRgKAYwsZeY#J*-(wuqM7QM5P-Dr zqKT@VC9qf5>0Ar*J8X0jFDjg(4zohD%Eh=U&&re9oJ1g{5Zi6&B`32n67xbenvuDl ztrY14;9Y2UAR!U1+7?OpRJE3RP2|eW)7NUHq#yq(6Y3uxkH%8v7Ye>>{j(X)jxm?t z=wfk))M1!frS(Oemc%3_Tt74XK4;h+I0<<8I$J8IUGlkZPNIz83MKz2(7jom%S}?i zB;3(t%Qd2F;A)fYzTKbNyMkRd>iW{@=x86bthrT=C0@yBJDvEXn!P9$iS|6oYUrTm zi2^C~o{xrFstn9trp}&;EDHB=54V&jN;z;BC!4e5LZ8!O-~?3qZhn6LgLP>=W6Ydg zYFE-p#N`<_q7u@?j4zk+XquqnAYERWfIr6UsyjQs;3I#sY$EY&fK`jMe|ItU`>GMJ z4}BYokj5swHk}phX8vu`W&csk$GSv0eg)$nyCQ98bL}*5fV49bU_>rdx2U6M86P8G zuftL*JFdCFwiv00_GELjAkr2#@!B>zDc!)&YUBpNwWDYRLjltMX>uF1H{a>SB{H4w z=q!1|xLwN*rirZWIA1ZOq82tF<-Ab=ZO+XG+Fh%sWlE5Vp~2n@@TI*r-~+QYzGqxZ zz2~B+-X7a*&Lu3yoYg7w_G9>s?4hc{fWn!cy6Bv<`fpokDA{Yevtecqc&VFwhEhPY zZIie98~lyW&v7Ss)18x9G1%6SNIW7|eg3GUcEeHUy|3XhH0Yiu^V3|)BuN7;WOyB? z{2v{9Z>k+;?_DkFsd{mhofc1ZlF)5e7u4uD_}tFBgn$e^-fag=YY>yO8m_xr7$>C* zfwvjL{E}hpO+Qqt7@+6G8Z?$2qBq1^%rRh3S(z(V4eW3gZ&ekim93>KDo^;}ojgB1 zj&PIzx~do4{q8N7;uY_RJ@f4n(QO5Y#PAmQZH*_){*kh)S8WOU#Cry#L0?k+i~|Yn zl*&=&tHpk1gvd?k1eK-^KUdI6@Im%eA+1>i!XE=!y+8Zj&>8J6xxk!hrZkHw`U^U< z<73wgBCv_F+0xhG4aVS6^x--_6+FK4+}6UGOM>ZJY`4o3ZPOZZp?LBQ0|UcS zil|Y~&e4C9UNZC>DAjk1jcBIs%t^+gg_$cw8kFsqURxeZOa)Y$5j&|NsNl)c|AAxp zirx2dp28zkIzTi}SF)h^Qel&zBOofOLP(t@fZL;b+S>qtj7P=O#%X9=v6(K)sO4T| zxNLNBbzE$%JU}U}6|}{sz%V_h1>AExL7q%-%Xt8Os0r8JxNZs?4C?-7OJ<9pAG%;Q zT~JSTsYI$3F7gGg>Pu~C&FP831CXfJof}g0-a6Zujl{ZzYr6YD?DsG$ec z7_{UHo_qLZ&{kwmtT(LipqfZ-1#wg5wMIC{Sr5u#gIh18QIQ#)mC)e?JF~>UN`tr@)=&#zG{LSs)@gQUxe_EIQ=} zqaF51E;wERamY)>=93xNMvVx1tmfiY)X15rO27K`?MI0}bR!rV*~_5X&LVA$Fc)7i zHlLxF`|TTl#&epUZ}?d_w>6%R{^Q%9Dd{x7yFviziPU0;HgPC_3Gs~M)2Em(b2|}z z$AqG}h>x(ckHE8#pRLGTnK*Q)cG32RLHZ@@_O_M-Xs_M*|FS^WX9?BhOv*GKOtq#B zNuBQPOG&T@qU1%<_Z{dM`&o|eoZBKz=jk;Y0idPT?vFbLr6S)~DllwJF*qT~j7s_1s3z+5s}be)6#4oX)&l4GAc z4dGBBTZs89_R`aCNR}Rnu*Gg3U*SiD|O`QmK2YslA4#(q-jo0%-|q90*}8qf>dm5YFV-*A}Va zIUlK%Hhd#|Rz+BH=H?@WA{zrph}wKra!TEH*X9U9HWrWT)wHA7v<;dZB!(JC`|0(b zb(*?~Oqn+6HW~iQC_JDJ5zjRi)q-UnJPQ=y+DZ04%AZvS7%5PYFK-DlzrX$@6#P5L zeOBmCVAuMYeY8S1G4|}}ffD>Jy!DfR^e_5`m?_tWPxM+OxS9gF>ddz4xcl|>dL|dz zkS4BIrUs8cjx`7d0kbCJW?rfD$0NAQbrYpvouC1>Z-WN>lWO!T44(M{K&`E@FYSTo~ok8sx(u+_FOsP3`5L(s`Z++uN`*V%!+? z_(-+jiKip!laPMa!$ek%$~JA?0-;6$dm&z#JWr75h}0X#3u!yGkf;X=fYSwmEvb_IMyK>1N zCz(`^e@;wK){cI&@}1i&-+f|@6UZRn5&-j}C-mb^Zg=q4w4C+h$^1AhCbfVE5Ax>s zPB**7(b|+lxM=w3&CSV0CA>DVv#B2pock6O)EKFXjq7e)6z(n@J#vCF%2rY6)f91~ zsSIC$Vw>RuV)>}L+9z?H6e8rvXr@BI=WR{u_ZEm_QHV#Gn^lB0z0ouKg(8&@VjM|SZ(>0c>b z3pw|LR!ytr?ba#&0EsjR-KNU+_eZIdK8LW4;JJNk_bYonGL*fx}8F| zCo3iY&qn?iIeBsF-ToTE&nB_wy}!ST{xW?mB8w$Jkk3+H4}I7=!`Bc4i%w{g=Gn{2bnZY^~hT>oPOMTx$sh9{*HDJkn|&N(W! zD0MqV@*CF6_)QUf26ia6uGnk#UyZISG*o|`wl8>j&n*%k^pgQTkD0m(a2h_N`rfXc9NS4Px0av_hF$hTaaj_t zTM^D_GwM~fO7}0nD3%-ZED1!2*|vhn%{Ijjmx~=YGaaF|pgv@7*hj1G#uUuZrG!v# zvwT=eaObg?Z-bq{+wpZ=1O>fQ{ z{nfbKb`csK3hAjHS%V3w*AhI>__7kdZ@^8YYtVikC_wtg5^4IkD@@w5^qT;89!F3U z20%WMU6CX=VcgnBh85R=6v+oJ*}ZfuFtok@U1$35>4h~j$(Vds^cmK)$>|R zM~}A7$t5-MX1f$XV;&2PtO-vA+LR0K)@il3Hr=h?U#=~f5E4Odq;200MgawDEy6GI z*(6PJjZMe>#zhdpSN<^{FPVcPX}2U{@rcxQvO74L#eu8!qQFiT=7%;`Dr4=I;J_(N zVXP8}HTI@%*ZQ$NJfQ%aq#8#ZchsH%NGnF)Rp-oe`HdewwJUitm;upygCT0cf&3%8 z^bMr6OAZJZ>*|!FVlfG!^FpYT8tUSi?#To1GI=!+&j0kwIcJ1SPJAiRr&ZKuPajkc zU>F%NaEewV@diBS_z6d_i=r+Y!)vrrUFAtQ9bn$gvKNDdBjObO;vO@gv=!%=S~NZo zVi&F|%JL0*HrJvQBGYqd{^y7cmJ!UsphLM*8nySn3=S|it^kV}UgZt^ed}fU8Koxl z!__Sk8EB=8M!5u+bjXR-Ma)hEUK{#8o7HDgR+Ltp%kagbbt%+x(fUb36NY$m8V?aL z6=OWLr|0~K;_Bja;nkwHCjUic61_uO#*;z7rdW6(J&toETXm9A|GP?$&%OkI_Zxk3 zM+88pth}%t-TK8-0QZJ1CG|-rIQL1GI0;4LoH0D{57`CUf=$hYw;YD}GX6@J0b$_% z*HJ5KR&Fja4#qN%l6Z#5>vM^?VbZi#gQL6Dt8q##XI)(!Lne^Jx)g$iA-zn{7|n9djWmBs=W!~i|v&E{^dDgQDm9V5(F7X70D&5Mz)C$FAuzT4ujc5*zA;+dZv6W z$!JRAPiXzP*S_i*zPivR>5CKTiq~`y^58@zAn25sYHplnz`0!MDJxk?TEw) zV|;H5x4*Wl@t{q0u%vBRcGrTs0Bn%Dl3Fybp9Z(pZ%G%_Oip|QJ5BSdxyXMDZ5~s7 zfR$V6Ufuxg3o{g6+>6Q9cr*rB^x9MC$>%?P053v%E z9V0u|&{$OWjNMri@?JDSC|^3vDdKv z;nDs6BGf0O(R~i&v8vKmnDfJ+#PP2(br3h5(_%~RGN6%U)*Y3 zEqwYD$(Y)12m$UC=DU>?8YY(HJIxwZxIJEPaGoB?TL9 z**UY*(o>iPEA|`0K>!!x-VcV;C!=D&Zef%3L_F%49u49UKrr#WO~C*>FSW{=_`n#9 zRsFx0jkf@ak(;T$$rWYOW})U~>(m|#MUnWV15pDuZ_92*L)<$)DEG_EFjwdc%5nub zFtqo{YDHLCk26cQ!gc(ROQa1%j2A7q<>@ojV@2;e^ycR1C;Ui`a_!966;UY%MB9Rq zoIKTGtkq6G+!j1-l=fq!jZ-8dhVx!)iUFscKVW1T0;u3hf}zyMh2Kh(c88T^ zUFw6~{fV;O7!OZt!V~Hv z*{1Cy-3CkM%904)MAsDFN~s{xhdhO~M8LHatc7?{iG@AgIlFXP_KO90F@DFXV9f8? zhEV9f9anv)P}j(0w^O6kf#~Z8)mh?IVP26SoXu`H0b}_TD5mtxdz8t==%yr3DtS(= zV$RIM0y@oHsC?|nxbLt3LvqWw^+28#ks&g*BjW@BgEzmWcEKOt>N7wgk=;-iJIiUcsOpHo1wO3!Lw( zfuS!q0eELQb49H__^qWO)X-vat8(9QGc^>eDs61{n`Fo3mm^$@?T4fCs=T%}G!biL z=F@-!!`PxLVe)lM(6wJP%efjoV*JzrSLJ&@C<1Ps3^RRLQ|L~kOMoX5UES**A_#BZ{Byjhg*XiQ^ZBd-O z!1=^=kRUR%{3`%g_Lsp|F2muUTdR<~zXcC|NUgl>Rp{(@(Sj-GHcTSAv0w@R6tR-Og$mLR1XFUJC1C`n7dSK#0F zD!y{5O!$=cNF@-oV8=A75#Vj_}-p0_6NY zU(c9F<~T1w50~dCElE>;E`9CGQHVjZ&WW=wp{iU+w`q>$y09jgqfrM|E@ul(M-t4@Y;^Mh@jK-@p9oqU>&PL*uiiC+|MAz3#(GeLdpSL z-iwbJr}{{cWB2#_lSYqYerV#wl~HR@0$B{cw02v*mkqG;o?lxEek+IYJnA$2I%hBn z?e9mIvu{5ppObRm37gBDinIEpEt>3WTlk>B&_uHbWD_HaV7!~y9>7ZW}g?MTA(7a2%U+8K`_lD{e1WeMv7NQP1Rr@_L zQ?%;$9a1|B&w|4z`&5pH`e!2IVF;vE6eIw&IDBj6#*q@Y@mD3&lEo5qm!)(elv0p; z5x!KPOSI(JX4Cr`ydWwnYC;ZlYGW962D0+GIlRfW%(5CcpSd(`O>6W%KJfRx-R^)< zkBBd&o=DjU03?5h?tprnVgY8LO-Rf6_<}dFz_f9vO~I&jP*`Qjg&ga?nA*l~am68U zZE?GF?-M3Q&cFH~3Y6d_VkeR!bJxE$vB$f?J9sRz@n?`5^^`V18&@<=!>q`Xc3m@H zx)69qzfYr14Ozz(_p+X23q5e)ce#T;|5g#QHDtXk4oVd)RkZLusyz*=+OccF6R;Hu zv>D@qf#S;{Ie zS0K}!o`abZE215?y(w;og=)7PGbIws9o_%Q$J6_ORr?eeTG=`2rdy?AaAJM9J{gmh%T!^eIgjyPYNl*sI`;b@eRbrqp(zB%Kr`Gl0t*o_AW_4C zq%U2eavA<`JSk)1bGm-R_35U~tcYqS*?x!RZ8PHVH`f65!1)!XW>37-xr8x8nA=QZ zBKy`k5j_Jv$CzAD!dg84=eWZ8wiuhH1YjGzCFU|@>4Y$tjXK5OF=6=%qjgidj?3}b z_x&e6pEY@~GadR;Q6SDK{r0{`3dbpSeT!J}2l-&!;*VRJrnla?BF{G)K#B%n+?)+y zkQl2OA5EuiIjs;Y6I6ntTJLkH5?`LwT`RneF2cRgQ%QLaoMr8m5p&G2Z}~rZF(npp_Qm)zsB&QxvJHkfo2{Mu$$LFQ>s3yVjyK z_kNEYi^);q z%FwJ*5J}beErpb&hD!Q3yK7CotVA}gtQwG@R1c61>(gNDb$g*L@E0rjmUn3|MjZgU zU@MYlntH0hzc? z#Rir2ayms52W^@5vh0$9$*?$~rbeEc;ZFH}nd>n)xTIMTAqUGBcAODCKo$Sr3VSA| zepRSwCR~_`4wgg+Bl@zrBe5%znlL{){opY_t%z zjJl|bj~o$W)O9wqb>gnMr=Rb#_b_xLB5PbHDy!epm$rtzJ=f+?S>rVE%(oiPAv)B@ zOjwW7WIfC9GOBX5a&xPe)RycFjZ3X9O0o)k=O%A}S(R-cXzTq8qkO)7%CP_#OZ4Yy z&(}#Hp^vz*<>C9;QK%%NRE*2A>e<+*ZG3k{ae?CIqr|2j=8IMlt6GA2*=jXd8J5NP zdB)1fFeEAe+DBiW*2eED?x6;Y9Jpq7W&&%eZj!xJt+l|3BeYW9It~RQHzSXoIfN-u zAqlSvX0yDbPiJa~3n@^9W1WvQ&bGI5Ytn&{vJP2S*Bycx90ZM{y5iJpqzxckaA7Qa zdM~vkL;F#mB&4I^g8o(64Xf1{#tNd6-h z+#n(D!(YSx*h%*&)L??A8#~RUN3!^NpSh-{l^`>U_pj@3aCpc^08*^a*gwvW7I*g6 z!iTEPie!cmMF(B`RwP**vm?Vtl0{J)sdmZs=8*FmS$}Mi!S;malnev&vb*JTb=u}- z)dk$@ng~NKg-R1?sI=a~@Kemy(@#}C(ded2I%Kh2R~D*+d|!00JqGFgSGnPnf-x`P zT#lEulKyGiFJernb5)7RsF7Sfq-s*PF8Si&Y}Y~@do@P~M~;xP1x^H6J$)+}0JI|B zG%mK81AE3w0f;*_*2BPQb$uLhD3beY9!#%3gOxC1Y^>_b%i&w-pg z7i~k|TFVM=SJKmtdUKphryy%ZnUI^ZK;D(=rHXrNjzCjnp}g3N4-_t~w*oPKM6aPu zO;V4266NqL`P^_-|0xgWAHrkT%;+0#>kqZPV*C>jlA1`qxD?C=BM_$EU&RjtA3$HL zsC|Ik&_^+IT5BPK93-eu5x!_EpOjx1oi3k2$1)0Atvuj)$%sA$@wGZylpD3tm39C} zYQ6%RcL?O0fu@t8Q-7RiawfGIJk=89{%W5APheQ2}k2R%iJKbim5&lj&mGbuCdcET8m)E^m$O_ zBhvN&=~lM)NuS%?5NrFC2N98ntRc=cK*}7w-L8U zJFIC%rNyV1E$PCI$$%s-40VmxLGmRSI{vT%tj(5=+9~tbi)~uB@A68_B@yk;MfVQ5 zdfs0MChPzsnlc2dB=t(e-=>%DEEpvaJ)qP=XOwW-FoUp*9|Y%|~BsUKdf zLc4a9stAQL`(Mc(8N05|MT?))_u4NXC-XwL{C65Vr69wt#Jc)c5!b038j}_jk3&-G z1!do1KH-0uE6KhD9UBByWvOUw&}9Lcp%_{Xf22y?nkg-`NzR#C#8>J}2Z|_ZT5VrJ z1=EEkE8-Qz?|}~BRt|_xBT{f7I&!*vNeb5zf^LY(>wglbiNt#T8V>v3i23~@`#DbW zg9#NX;^yR51^m1l{EC|wzxV01Zt)lK!i2NZ4|P{;YdY2KP)0=w`d?!TP|64nQ{P6y zPqub_q2bZv9Bs(3;r)P=l4>go8XlBKB7-2;123^~oV6;XGn&4>x6e7TBFrUI|}O|(&_{68<1 zB^~2bZ!kkm`+vgTW*mG3SAZKNbpks|)3-9EyWcp-=m+S^=(}j=HH3SlPt+%UdN)M^ zJ7i(o5-O{m8o&zDc3AUwTy4$VHDyA1wCDQ!W7YeoMg5*UXaBq!b=elKk4RBf?Cbo2 z8^sn>?1+1$UG(A)6Z5;p=^ZP-`!|A53dQ-==jC9@SjkG8Y*GuqV!DWIZ0&LHjGUBk zRVr80(3+&!u4b=tD?PX0pg~Ky)LC4m1-Ll{C3T&EIQHHs9{c%#g)#pcfNoZNc%6UW z$mKU+a#El8#T|fiz(@C^jVjJMuvPoaIK!E$o3q+7Xw-jl_t2I%x&5x z@SS)R&bCR@Wl@+=(MsW5N{7d@C+~ORr)KpH9ToRWYe^c(^)YB`aLOS@6q?3JOHb*?hrH5{4H z{~nz#d|(hA!5Rx^JFbEDOACs(H-=sp!^!e4b&;bJ|Hh%lTsF|?FWwYRBrY>itlc~% z%Z0DUVwT~`BXnqQH;P>^$y^$DeCc`dXMFp~Fh1KCsT-KZ{ri)~_78hiDvA>8)DcI~ zsb7>0y*|eF9LChWbl_&`oP^WpL=?`-jyIbPKN(wS9VNQCEKW65 zD|jdJM~p4OTAaAnC}~x)OC(w=Otac_!x$G*5$NWW!mv8(dvb$iEOefy3cY|jo!(|R zfud;ne;1i21zGYoM#HyAzcWa)1+qbhyws)8Pta%5L7n|bfm$8ZsL(V$H9P!$pGD?i?#kbmT5<<4>eV8l{#U7A!U80hmjF$N>Q)+ zYnIB0?Hp%BxRzsY^AP^=@BA^o|LQmK)u+CWK_f+dhl-{WGLI~6GRrn;GD)*iVceXtn2wv?M~|Z#?JC-Yv@!I4 zqCOTaYctI@Fih8wjn*xs8Esa^<<&L%m>s5J+qTg~t+c~;b3N={P#Z;0(SgCXj4#iz z9roBkbY^|ry`ruAGqXgtpE;LR^8XA*-Q766^Ovz}@^Q3-yO@BEXr=)X?rz##)^XPj zuBn6O%s0D7+>NnWvIwmMNxSV(2O0J3$%4jSZNNHRM)vyCIP<;FB3gJ2lldxQIw#88 zR-j?piWUK}j^y!G(OhL;cA?eL1*3}roux6~@dNRVWJ&W1f@4=Xyw7n1TM%rmLcQ5PO9_y=hoC>IFcGD;j6!xZB z$|hY)s8XVZ%GKQLO{YXtF(meNQUYB|^%iv=zKq`dx3IqQEb{aWNlaxGwHYXc!X~1a zH*2-QKw%ZLZ3-&LoHzE#aDdU$1=4y6Lu!IL5M>;@4n2s55@#55}PewH3*+bb1Y!gCX)Slx~?rSy(1U?t;}2538M zVAt3T4$bVx!Rfu&+un(}coI|8e-lBAW@=sIXQRzBXHX0GqE$PHX7vCXq+2bTW{H#J)p62VBY7IB(=~-7L@oj2kf~?1VcQDZ?RvpAb1*G|x#zx$@ZyV@%9eN&Z!inFe`K71L>427 zDKvtnJS^`kgS$1<;YEbi(FqP$x3b>a>Udj_^J2@SmQcJ<+;ZelJ-@MUh}f|h-UatQ z8iiBXwz<|B9fD-{U1)srPmrEDj_%WcLxI&J^J&_i#y9i?gW@&G&}3S2BJFE^nLoDG zkMtI2kn)_-PmE1wueGs6rtj3pF@4+JXx;Nmz=03bDPejFNV&F}24Utit8RT|&ZwRS zsV%A}^AUM<(h^)ls0t#xy{Dy7uL%a$r&vPPy@snPjS_6D^hi&kzwkx$R=hN0QZ7URF1h8zU<#tC+qY3x#qoGV5or#ZJ@L|1 z2TkR4?cC%={>w!(=WNqKW3YU#0(5lsU?U$=IZ9~7j-I`sf_~*7CTIUcgfpKcAKk$+ zNEfRZD~c#1R7HQHl*jZEHK4bpSyHf z@TdRozri!f>sY42U5%Qirz6s^f~S{*D$BW{USn~nmi zWy)YWd3Fs`BuuI$>J?0q^7=Y;MLf(9(+(KV>!>cpI552rw;VW(BYO{G&&*EDwx?-s zkD*C3RSsFqit7aj)AJUTzZ2t5R=YasPY*q5Y1ru58Xb;>-U`mFT*Mn^PT=_I6F9wa z9!rg7Y}C7`M=ct|bR32a{PA!6K6Ygx{`dVYaX{Bd1a#-kdMTr3Bbg5>7EJl`W|FmdSl%_k{yIwlYbaM6; zFV3W`r>Tfz`DbwFzF)@4l|RFU)o;_GRWFK4>}fiGBif8HcA*&`z*Orfw}%+^ph3GQ zriJ9VLM^Uwuf;9vW$i43P*TL%CVGgW%BsI zqRVy+*xy6iRjw3UDO zV@+X{t;~M1s@5=F`#APB|2Nn%e!orO6f4=c;ViGM&Gmq5>Y&NIS2wFGoRL}tqpve@ z9l>2Xi8D*0seW>{y61s6p2q3#eIAvC*D+TkQ+JmToAJu?%F{SiC4}_q#bh)xjrdmz zRZ4j&==#fptL@gET?RpnrrW=aQ`$1{*qX>6)>Y1$6Wn4{aSBxcov2KUS@34lC(IVx z2QmGt|2tHc-p252|BCmr98!JfVnF6%yD5-CA!y6(Q!r?$)J(&>6c91<)?8fE0-F10 z3t7Y%%7F_bWYs#NUB@u?&~E_yX>gD2pb_5O6kw7uHG5(q8tW$4f*i4}++@vBM_GHW zEv&1xqk5?>MpwmWU#r zrl3463+7oN<)R7|bPa=G52kkh3Mv!7M`3$}=h{}Zs%+t%VDZXKQxi(?KH-UXyX1yM z=fz^j;jSC5jo8exfXYq*I2`xpNdUs`<@l~x1o z{y0@Q4bdtcG!y62_i}>dq?J-!(r;^T^Zj(D%FPJZG(hSUhL|!~59>1O?S#&XMx!(} zPL5t{I6|#E#B?6vaD6v^>By&WWco1n@7ja0T8p||t|jZw>)oT*AD6nWRI{Y)tkWdi zzeI&-^~4lf@lgwmt!7=ETb##<^QZ9TGhf0FR$stS)8K+8g0za?``|C*k%_(d)4%?g z_|bF+4UH%c2Xr!JpRf$tJ91d%0ITI?St?)q+A7LaBH`%hj? z*NxFZoa{w--^?xe4?glcxT|q1HF|^n*DyCll$B$rY!%EuRuIaqU=?C0RH4Rg?0^+8 z+SmwL2~jL$e=wz0eu$Ofn>e@fbdS3c{oUcNv5_#+-@O-DaE_cb zjYI}rL}b*N%0I@zxliHE`G1b}^!uziSqhc;cy z+GH^2QsazjQ!#pVg-B95k|CY7%2{-VZ{YmOGg#91W}){H*V%a;TX|d$Z7XytE94tD zTE@~wZVIfUe?j@pDrg#R+4gNv->W|=bO5tyGV&DLL7U80z|=c&>Z<|b-s3pZ{=eYB z?4#DIz#gayUZj8&w%T6c>PfGA#i_A+fl$DX`X6eN28aeAN1Ft`c zi%)+6mHF2&U0Gv>J%n`J)C8NBCnru%SCnB`r!P`t1GRvJa=r>ED}#Egtl4F-j=cPw zV;&dJOjIw+tlScI9e)a^g51f}0TK$^Djk5Vn;}h7)TYPqX1|TuU;C#RXPfgc{0rXq ztIV>)ONYFS`DL13N2g0J6`iqI2E7RaQe01RL_<+jW4RRa;&cf*#fs_Ig9*et@50yz z=%n59Fh=zqSZ6vXZs>=YdQ#oBNQ+())~Zv?O3f>(f32}eajSz`q9-M+t(*x}bwnq& za~$1se~z^OS8M|vdCim7lnN6DylJsvG_*%3`hs<$Ne|<^RwJN1wi}!I1nWrX@vVeA z=={x~&JZ;}hSttMLS^yKf%$()8McfxUNf4A9DzLvOlq4t zaF5np7%|^rmQd`DP!DN*XU-Y3?~Mg|^O+K!6^p3zX0kf=#1nY<;2rq*u@B%t^$;CM zy;trQa*#`=Qsta!-|3KTu==^6X1N+NC_*T=jL>2r8Y{8UJf27>)4S;7JWk`=uYCvK zeC-vyy|Qc{3I3G_9>ee7{V@L9FaH1VxBcU&(!aa(&o{-aO)KJIPbNt#qq*Y`}7NYF;k z4hwRcNpvb{#KSV^kVFw}ibF>uJJ6M~Cq!vYU6h@bU_JjKPF(yF&aHiw=Gl3gU;0K@ zF*WgOV0Ht`FCN0Ga5wr!`#>X5d5yLoot(UZgA;#@@#--gzwqCnKY9^KGKOlf2kq)% z8!?+1y9e!XFKawiwANZ|TeJao-^a!8eGcK`8<=3HMgw-N8IsCW#xHLU8I#5IEaj_w zT!&o^m~rV?sgE>;OM!W3#<+A;G(}FMU6nd--Uhb{bqXIko8+fFWa+w=b|&RmKlVfg$RoV{>d4mDVKE)h||1bTcd|%aD}jpSfGl{q}oU z*AW)ZT*MUZq=)t&#*1fO#~Xu-rbeWzM=>2veP5G~l*pthp6(R@Lgl+Xw^JNkQte`^ zRkqD(F4J&pjuf|Y0`oY+O0SDIPMpBhj%n;^?m$T0s1+maB4sLK(%7fl$e`LOnys?_ zR<1-@g#EZp8LYRYzxgMMj4E9$_g=@zg)d^U`)#E0>uldT&*|Z?UYn6ly$Z-i(S{DD z96^=t>{|u(F7Sqr75{CN7;5 z+Ogt0H-w^gkT&c$Bc@Pnt`u&Zk`&Eo4^{M@+Z1i5X^b~_qR|@1aLDuIZ=)I0jbyjd z(J$Yza}WA?Y?r?Se&LdYA4qMD4MPrVzPNVc1}EkmDM$b z(a@%Z>eZjp+7*Yopnc`_-r*X52h9=E8o$Z-nu9HKPsDU&QCGC|!H|UBuSU;KJcsW0 z{~GDV*U`wO`wIdD z6qY6kiblBXonY17Fd8MS7MY9=p4Gz`-D<@xGt@|ywkAomWhm-yHwl@_S+^3FBlP2O zjAjmDY-S9>sn_VgtR;DzY5qsSzRu=bVYTUA;9GPjyf} zVZ>WxIK54<^k5i{kVQOXqyIM2$+J>!^Xb&QJ39l)qSxU9K+^CQyG1%)byay+3etbbI*uBM=!ol{(bD%h`LkNtfmW~=b${iAq}RrzDULN&N&;>6V5cUMP`U>ik7@_-F-@UWzf4} zeM(TRyfi9;y~IkVE4T7fGIz@EOL(IXT+n-AqdwU?p;xYvDc8LkJu{)MBi1vea34|l zR-&4PQA9y32a|0#S5-GL6@s9}ECyuMQF{*UU30*NGjs~hkjcB2HdH+{QpUQa6x{mA zwLU1ERa!Kv+YFiyuF*aU33C?oghZ}~#G&T2lV+kH>l-J1)H;jkFP}$E?`KU-Qn-wv zubZD~^$7#JH&iz^$L4#hj`n+v!LmzXD$0^VfIhvj@guBX{C{KA`x>IbNyOp<8@?{; zNE&5wyvZkOyB77Z_svWoxSLT)MIAXK65=5RpPX5JgfSnsQ48)wW&CzBYz@PuS6Id( zucC0%R7N9+Q$C`#`$)P39Rq1BMWDQuLc{qA7E_W?TAOJ|UCT#)yN#q7;hBfc-RHis zQxPZU$)--QtYUR1mE%S`ucmLT5eyC1VvI_r%b*v$MGsa;0$tNn$PfKw1KsQ_nzdMmNP|TEqKx-hqGk=x6ZB1CL-QrqQ4gs>MHKbZfB)0**9mIUXE)>9a^KUq0bvjn;xXia>s%Fm~J-l!iBf+ z%>0{nO)aGEp-*Q)~2%*ONxhE_JmjnpZ#-mR+KE(9|b#l(x?PT@jMs zM4Q}JE0rz8`pNFfX^)O*M^$#BRj0FD9XEbT=tPfr?`XD7ZuXhlsZiE%J6vDsynX+b zeD4-kadqEk)oIJzfA47w3`taDBhFun1FE@DupN;(+BPyo=% zb`uHZNRkQ6A=5(XIh`^Z)LP7f#&tkL+l*@o(lWm&LZ3!)s_&KTJpil^uzuk*8kIh; zrGTJ7v?oEzmpQ6*F{Go1woX{-oH=v4F_nbZh)Ov{sas)6QzlY6VMFA-RrHoGSbGCa zcdWM&RjPCZ)h0GvHvkEsKb!VZlzQzT<)bHVY>!sDk|VBfn5}&m%V+XCX|BCw&Wvjo!~8}NlNK3$T6ef)B9wO)l%~41j6_Z1hcz<&M6E#FC&f? znO0K{Ys{0qN*)$%Ek6y{%jwoCqddn5ZVM$qewAyP8y}e`#&`*nl6U0(yTx@%R#W{o zI;OT89n=?_f?MsRGp#3T7Ou8uShniJ>@;#FdZ|vzU3|oo{AUQr69M^i*hM;^o7-Uf zwW>1A3lu@eVD6CJ!|6G$+s)wi4 zBYHp_#x-P}6uYa__~oM?z#lyLDcnDP3#PI$1a#P>#H9+PVq_eL+%cnF#Ypa20Vm$EacNy&+F{b>yvlU@v4q6Enp}N}aA!bvN ztxCQaWf6H{4$b&58nreZxg5jc8fn=TgRxqwn>t7BE$kxKv&^R08ZDje&1wFxB`7c8ndu>80|G^Wu_@i%Of<{k$v|>Z!sSIb{-1fx8jKqS7>`Xa9GO(3f zRK7n(W+?8!D}rig-%wySlr83r*+(B`yjx(3k~w6|8uM_gW$g8$rj}$^pb@K4y_8N` z!ZcbUSJNeJ$x|BgAv2G{gg2K~t?4tKW$+ri7X>(I@)_~;l*QEJa-ZeGI5X2 znMTY|sTWS;fLl3Yq5$ctM%c|L%A|JA=FpoU)ih1U%Bd~r8D%{R`VBf9yz#p$SYBC0 zWso5rpCK8=xXjS6#;`4VBtlqFZ~;&y)UB`T|`V;m|ziq zu>DqH^^MhCLP}3`>Zk*m$&`QY>^|g(kF;O_EU~V*yU%CDL`1H{aG~jA?3?773G` zvz56yBlfPE***-?`-161CQ`aG2;29SbX&aYClompr^^-<3Fs8bF0-UcV6$vgR>(Tg zSsQC(7>DRAuc5oqp$bf?X5Fg#9hal=XHw7r$F@t6&$jRgp~Z>=LHs zv5bB>gn24Ei)UD+)xkQ>EMKHy-o)g@G@?Mu%G3Uls&s0V<%@QDA5GL(q{>hooo<%m zl@%x3BE@;ECO^XY)o6j z9n?OSjegspsTQC;yM?Kt6ySdHts=ss2HVLhMGeW77+PbcD`$}IrXFPwk zP+mq*%hK{xCs>_%hHT2Z)zF9mUrB`bGsaB%AtEoCn!S%Na zFlX9k6zTpFZPW(lq0@9;_s@NdH&uqSOHYt*7RZMiyqtGYYY%FbN%D`TIx>pcyFBgi zJ;OD1&`N%A(4LDBiFFic5eKc_BBH(WB+fkjRZR3RqDjLr3}tSzb4d7*H<~)zE!IKe z7dLmzn_g2JBaNI`-ZIFQ^Ho4Sl5KfNT~H;>m^RZ>C}zJtPe*y9i&}dOn4BgpXpC#rPINCmw0YGu zzG~=(CB1U3x9>S>oFoKCk0d6a;hk@4nFlzB!lc8}xoxfwO+MVp? z14z>yNRtUF9p`|F_st2jYK!N!&-QWOp7yE!tjU!^BY=6RRkcJ0wn3wa;w>vf;J&7* zu!x*AtOi=dc?0?20^4{Hqxvmm6B!MKbEf;#Rnno{7O-=9`6F1wIf|Z z8K`%;yV(GrKk+2~_Utnlj@Il!YoD?%ODg!pZ4YB*V-Y`Ee4REqFLEN<>03g-&M}jo z(W?{GO5B%p)l3#S9aONIfKQuzNL5E&O`WZ8nEl4RAICp9`f(hk;ayLg%!qQ9I@#1Z zi*hA!tKk$LZRt0i)YhUcn0Zm|bE9BtP|%i_m@4INsYxtNaZ$P5%)f-p3yo^&v?@iT zTOZ4wo7iECoh&TQV?b-1HWg1JJXea%yjYj4 z&eB;In=+{f%o*EE9-*!tiyy>}*2mF~_puxFZq^H!vAUn`*ENx6FJTXBJ+gJ@z#1oF(2T1KzWB)T*GRspkq9!GTh;|Lilw>}0Orr~|?K00gn0Sw`Rdl4VJ z7mWjVqjumZT6=FpbN6Airgx#)nj%Bhk^|hN!H=9;16qAw$5|lR5R~XIKdeMeAc&@2}YHPsq zHT98Yv)y$%Z4D}jjin`fNjYjw*p$a1g{_{D$%irLwGf_ve<*v#^`QwIwI?}?Wbr9< z=0A&I_${<58>q7Vx*0WXFbxwr8l)WQV>yU4dSqh<;yBSk?R9N1Wu&wWIfbD)DhgD- znZ?JX)&bO~KE;F`q>JA}9(U=K(A73ML;xN_`B6kukD@mB z0aRx{gn0TxJpLfU$@il&@qW_vQEnN=<*+@BaQq>LhY>d(K#h)Cy?qxNty?L;c9LJl zOnAy?((^mxaT8eVLz_lHUJ&mZ%D&Nddw3_fb2;gjMt!4WnCY7>%xlCvMRUC)7l|&Cs*2%B)SnTgcQoDtGJL*4QRZdEyWMROH#)q7cH_c3Xddr^TzZ9u zW|j}BpMf_!XYn_$e;Y6LPEi~V5K|^q92b<2Kn3JR{ zN6i#rvwQzd4AoW6;2FANvG;`_4~bUuBlgn`TR}Q0i$pcuqqW zdcYL3oFDDIuomN{>#e!GxYuxx2tyOt+4h^CWzZG$E_c1})V zGHzgXc@b;t%Rr6oR2r+c9xTiD(1S;o&-T0bq)NT-LJ94QVjB6f2hc^Nd?+(_v}I7d z0tsfv((%&g{r)-@R?ef>-(Y`DVImqs%(AWWMm|?>J@T|gIQXY$uu75zJ<|OGmWEH` z?n;e+6b~{DkZxyJ9!l2^>LhC`5}7QafDH-tB~nq)nOHr%_DRYchj^HAF>!#&?@=f z;hH*VBC9#Knq$gN$@PR?Hvx@3jfPc3>@>lJ=e`ZR_BG7pOE!mim=&F2Hz6rzd8q5f zvT{Dy!7{uBlZIjn-MTr;qtj*vt4@YCrBCl>i8BH-)@jh{8YQ3sZd14DdCN&!iFaZ# z-i6iH0p$DcNBi!Np>^*kQ9b%0gtt75%Kp0nI!%?S-3Z##2;hosG5NTDxbrRogHxMb3q11#@u zte<%e_4RYSG0D^tiXw=tbup^A%7O%cA@J>w=PfY3h-dWB(>o^&o#5axPm$90r;()KVuz1l~3x#N8Ny^2t;q_LEgp}Qsg8I1F6-+>tu7&mJCFf13 z7R@q=sE-*|dKA2YJ*CuCI`qGd(fO}n{o;428IMyStBz;izk_JUC()RD2-S%@5VVfa5Zp&cZU_CBNmhZvm3Kh4vEIfrq5+-7as^27 z1qDz>1u3dXD7l9gqJtbdIba1H$UC-@rD$pIu`#H>6qK(if8Il+g+_cGKk5EbXGsu} zkJ44tn|pWm|RlPcpW$4#p3;#F)6Xt0OUt%aDgKv}80Bx_CYNjo`R zr3YSmwL)9HgCl2cW+TRDZhJre=>A{9fyxXTn#N9zW3%L$Pa#ElwG2)L#Ym?q{5VXl zy4`n%>c-7aOjAJ3u^$W4DbyYOQw`W^Zh1o0U__02cq(XM{}|iQq!wSfh;wTTW>4td z4_P7_skHa!G%b<)`VhAqv{FSB8-w;W4YZa~pK+@`5=}IsW=<=E(kK`uEY3M+`aA-v z3D%M&%+H@g(x)cfwaZ5O1>`8`-E_@(aeCCvY!RKV234B5aun%!gmPN+UKMSH0Uh?rVeFlI9CNMrlOJi5 znj=U3%xXB=sqrOGScKc!$uj=Z^Ciu%8YKgfhK@@Wp-e?j?W%9xhoyxPoykf*K__{d z_Co{7FhReo&l9X7sx6T2YwTCqyt3g)TejW4Imc{`wxRN3StG?KF)TS-TCb=m7H|Ct96}pOpqbBi<7SEf~oQCgEs+ ziv8Wkr0H()Ce=vJ==>Xq-~1Yy`6@=SRv{$8)CrbLd807G94s-rI$x0_s_q`U!IVbg zfrhFXq0FBKu%-_>$3^wfb-H1gn^uwGbs3H0KBJej8XcxPP`l+(?0MfO(7x~Eh>ko= z2kB1a695rX_9LIW zl@8nOnAyDxQxi1G$uyd)Jxnvikv={>L`DNW-S;4Ez_(FbJwv0HZL@EkvHlcjZW@5f zb3w!GI_LgGz~Uw`W14A|MmMqDD9(ab{f)xBnf1g_^a*oK#!QeMA(&b*w9(m`XCXuz$F%-Kkz zdt&D3me^CiUZshNvAa-dJOs@DkTrW6)tG702)*Grl4v&_r`yn+dz22@ClF130$J;m z>|;7rboLR8_(H!O=oPd4&w}S$fLc;Yljdt4x>JP zD{8IXY(^VHI!F3Oo`&}0D)V69P|7)SkoWDoeLSb9OQDp6?j5rb)LAOidV>EdK7@1Whd@D7^CyFgM*`bQ5WPt&;j((B*Bk1oE3K|L+rT^dpTS5Tv^5_bl;=Z<@^ zyxPT?3+FJ1wX!brkeK83%1c2%5#^}HIAY4fh~7mttstg|j1%tDu&i|=eCn3R@rRFo z2D`FxRH=g`Yh`-62cugWLvq?#Lxt|Mv+oR@DWv_6g%aE2ly-Z#Jgwl|50&f|Qgdr} z=L<+>&1h#; z0@_lOutHG2b>=yduTO0D*#_cv_u5RHaK>})M~q6I&+ zY`&Z{(bv^o`8vl<<=AUcyr;5+c3b@s>>odh(`( zAj+GjbGFd0V0H3#Oh53;*!AcqFn0SrsO+NRZqv9X!^qIhSf3I_4H(3DD(k0nwXJ?s z^nCdeY!uP)sMToLl3C|=p}OY|G$#*WHLGKZ0zXSS7)|U&Q=@H*r!Y8o!i2Kedld6V z4djd{Pe%t)%4lG@yPMTY)X(NY3H5=TDy4UKvnA8jq?h_jPqg&ylJ!m>olXZ$^~V@* zlKKS8kzp>CK>;MyAtl7VEqd1S(tw*pxN{O!K8=5FRhm;-Qeu5x%U0Qw9>OkktyG&r zte`f07Q^#j$MC{a6q<{ySC_)7%j@Wz(PeUdP+Vg{Wog5BhKlAN%IUE@Rg|V9NQxD; zH9=a2qOLY#)JA_aj#m4ijbwFKzC-2w1N8Ekj{QEw^$(*p{;P=RK8|qe0|@H3vFbZn zwI-J#4&3kxK(& zpeJCn@1tL~OJ~dou_+?TMs-&Is6XVS{YBSISYxj1)Wk7bZ%+~ zcI?=LGw04>etiLn=tnz9_K_C%aC);SWLsH6d1!TGInFs_u&vHAP~oVw@^1_7ctA(6 zLYqsfZJl=K0_$*bX#sP4ccU3j&>420`j*cX*yzj}+j0@-hEL=8xxYd;dzr*vqbk|JPrett4P*ewIVER&d$fi)PR|z&)@6(M^@<4x#&h8!9Kl3TvXNV*@{p&74oay zvhv(Fu5+oKBcwQX9J$5i#WQ4dt#P5zIYd?T={rs*F<@p7`DdJo zE;yk9R6a*8y5Ryik258gjB!J8yXa90n!oig$=cmX^0*aNgL#u!r8*{5N zGJ=9l!o_waT&yMQG=5*l=^~%R$2~vu5Lauk+G|EOtt2WEce$=XaS?mPX z`n2Xfez&t@}JR?(QvHr)j94%&?i@1S|S3nZ;1?bgx9ciw&$ z-#q;kQh8L2mEN=uF3VP-Eu$Flw0$c2sSIm5p_rJ$(T?W_GhLcB0Ponx0>YR#>A8czfeXyuI*s z^hVF1QoVptNV`W5ciI0zpasFG<4j-5Ns_LWo|N8|ZNrTCTk6p(g7`-(Du=XpvNlG; z9cV{)WAF4wuzTu*q~$KsiVh2Px!INSRN3IbM)Wl8Rkjf0#Tc7GQDr?ur^03`e_6v4gaJK$Z^>1r;=^6PO%3h>6CX%NdegjO z5>ZIIg87aDt$g06jX^qVN~&xT(VuOx6)5S%>2m`IW%!JcA%64QVWjJuAGY za;;3Q(b4V>w4%KjYmT!FUMsuBW;wlgxTX%8F^u|v44RWb5_nocke(Ru>bJ4{!V}n7 zUc%hbI}rD~SiW$EestH~wNkfQ1`6zKcf+|+A{m(GoLOf(CMX%w#fQ+c`vHT^DVEX7 z^R_r6nRlIDd2jq6#vk}KG(PwT!2WwENa&cQypdu$OVu$}v`J&!y}6@WxKhent*Dow zJfrZ=C>=6$f*8sXHH874o1xy>snpnRGRGJV-rf7ro|-~8nnp6d595PnR4%-ND(O~X zNO+w_C!OrXuQ=kPsD$_vY0HWF3(W>pk`bKIWWz^!Fdb&FrYV=H( zQJIhqxjqY^??^}>DLN2M*$eib18HLOy+v2jQo$1OeiY64=i*3H3P??h+{nqRyB=Xw zfU~bYi)Nj7UsH6MWS*jpu2&|KjuN8f@l68npxwCe4w}ciK$CvD7-At`!IxkDCSKY& zPQ5FgL+5}pQ19bbs3${>0K`1*R`AhV9>t|_lmd>JlBneMVObf_tZ4wCWwXEo^#amU`kvcMyR^eo4yhvphn znAks!a~CdPb!FYoCv0(`l~<&8HY;#xq2-8~7HyG^R;=aAZD4uai-VVLT&7cwSpR;2y2ZU+vHKR zVXGMRccPZviv6=6#UU*|hJ(n`I#sS50GvQ$zaOS$9&!|I))MWUB<+(grQb!zvIi8D zui{h=i?QDVc5tPPbU9RpYqu*~`7m&I#0D!kvqtupw(h*_V6DXHsMKP+CQ%J{U}9_> zd#7eG&QPsQFkO}H))YqCF_{*wqhmE{lTM@q?NU9!4r#ZwYCEu}br;?|_X^U=Njlql z@j^6b8Fb83Jy?-XFdRoCp2AprH)%S_vSn9^rtclDt%H`av&c1KS23izEYhgU;@en# z<_ieUzl1#LV`}eSV0;$y$6v=-wm_n*qXpN2t|Lj%!qF0&ZHK!NY#gb$LLDt;Q;CXj zDdY_G0y`6y@=P&qW9)=$T~}iw=VD@(iFv4T{dgqq6MW%^?b59447=)8czna?9x z_%7<%S(c%1jA-O+KpN>Aa!%M-=V+Hg(t5}QppF$-x&&V#6w7Ii5)P`Fagxrd@9hbU z966<9T>`0#HnRAAXw2M)#rX|7%(r5C=OgspA7ehZF*KM??GarI?ohcxS%<5EliZfC zgX!+b zhtYrznmzr~B0D8ikTynS2KASl&Y^tNU-bMd-`ScR$oRkTtsVf7n2@hUiHo9 zh~_4ORc{^MEbtE6jSKIfdAtiG=@ROJS9-_s*=N6qrEnd2J;pH9qEggp)IAaPa6(I6 z-)e1SHQcjji~FZ;!>4b148M2($MKu@eGDHv_%QC6IY9jq z;|Ck(@Z>Y!$Nbr|xMgNPcGqVpT{VA4=AwJ(Y45p5PLC;Qqxvaq%F^=SYC?&3I(K>4 z+St~LEze0G%2-l;8KGa*zYNmvN-LN1P_!3EW)9=x@;WZAFJsuC-qojVsNou9vvQ2=&tNAs1@~4{X~<3E}Q$sS^bp3@M95I1lQxT z>zr-p0^|8p2BmW8T<=%{K_uXHGAhJEo$d;bU-&E*Mqi-KJA=vUG3;(Uh@ImPV`l0; zw4ysP>g`9`Z6nYpkF?;324{w2xck5(=wKOV7hWJEt&`SzorV@^NSi2FW664;K52`F zboy)9J@tO}>S5MFd5BZrJ6ux-%`vSOc4yn!5i;|t!xf~jeg_*bd<|2Ba~LH9w6ucV zU5{bo^hwm#-h#ew=6bFO>{)Znn3rw=!JSbo9Twin?maU-anQ(!ZU86H>`8=-b6(J^ z??Cm|51{@2-vw^_2o2gfr1p_%8mP=WWhL$ThnR&-B1X}=3o^eIRGyoHrUTW$xq*VK z)fK{VtTAUS{^233VRe`Bo!6(4RO_e?))8HN1L^uas0-IQ0lH>uyVnc;jfL)0L^LEl{B>Zz2!Bk z;TFjD%ztDrIqT_PKtW`4hgB4vVYOx?=L?Id^q$1pseg}j;aeCBF7RTxusxQc4|}W4 zt}o3wGv}*tu&jqvS#GSqoe&fUs2Jy*i609Zv9Bvyj@3rKiePou2Q|AGRwfX(eg)O` zL%etn6La?=Y~H~ucaWpBxQw_>g{c`%KsrZ_usXQiD~4_qU0n2+)yaY#ShS|#e9W?*7}4;lq!903W&MqqysqW0;(qz{aqL9~^%f-+A#VeDm4w;tSvVCZ2lj6~s#e zeDJ_A+_U#iv?z<2`(`jnS&HEzY(F$??);pvy@2gu8!n07Jm8P%Ehpj2P_{!sknYv! z;$(9YGjlVxV8>!_1>GSH=xU)KsNb~&ejL#uqC+;!GLoFiOhy@VjJaE-B6Oo?GC!n~ zoXw-_<+M3lfxSdsmW3JW0d*f0XFAjjE%%_Cms3A!swkbm!4f*lFSA!)rL*)Z)4a_z zT3LL+{Pl`}^q*^mYmdq(!=-1+9=s%8dYmO$K6K7BnIoc%+RCjwA z!DB6M)=6K${Q8raUs%EX(ma;B^XO+A?2iQPMgzMhc46=AUW`r5pjDrx{XB(wv=3ur zd$6$jHU`-|^I2zpB&Pa9TeEMR9Ww&=$*<$}`_PUK(I(Q2uEK_Uk8o{A(8MVuxX5Go zEf3>`H?Z-8FJN^36}0s(Q8GlI9$f9-k0IPxM|$o>RAq>7GgO_Up?&*jV2m6w_Ntl5 z=FqVeJ#rDl>gMEDQ}%T0^ui{(?R{w6@j=ud`)w-aJ6YhgZc$#xOO#fB%zW#~hzssE zQ&7I*qLTZaD`b2{D9yX!@+pp6&XS%bWT?t%kl?5hDj_CQ_4*ie zI!MxZdisE z3ru?(SX*8~Wza`W)7cs=^1N2xWO=NYXrdBz8z{&yS0Bo~5{&9ryi!rfYE%rTk#?Rz z=iHZ&tvrcFevtyJ%R+e*QINU$#;OE^c*7>3)4`HJ(-cL;Sp!(Q=%79|;iacJ`cth) zXST@}!;o`Uj-IJ9x_Lv53b99cqxMF-(c1BA2q%ux;hE*R38rIPReKSG*Qod04Q(xA zd5Tv(+~%rLUTa&`Tdp93wTW$E`C=CyrHR4f6KDjdsMyvq zNN8p>@1+Kn^Uge2Pu+=b9Z%7$DD!53chGKJcn8hnU7*$e7O{rUJ^wYlv3wH48l@NI zpPoZTCNuTODMeI`Fw8U5@(6Kngu8FK0|#e!pw@_SVR-@HJnZPya-~H$beCe%c z@!bor;`ybMSQzy%U|wTU1CLD~#;@P{Fm|_hQZiB}-Q&3+;%-u53U8l%f%heKbGX5LnW+{=Q~t8^WasERYxIl*#z*Ns%(ZXf zb(-S%-rj%Lc#0#9J$vFoGgh=A1Lm)P6T=t3gl2yMQQk#N0uOkn)b>4y>cj-PZ$3-j z?Yn7lCJ5d23htN8s1Gg6*tEMx%t@llK`|$Vhw9}KZ-B^s2d&fGgYkPmh3Z4Uj?u0M zkVZ|4RtZ|=uJ>!oymf;(^HImz%JjB!Hl4Eq6+Lrtw?>)v-C+3_p@iFKdHPVd+%Or| zq?OshmO|fuaLen;(8k10gspK5J6-g)zMKJrmnFo+-PP> z!Ku+RIcS@?S~VS5?`#$6>UXd){{=c{-$V;1dDAhqR`uk~WZz(ubTmgyLA|0Ii8R|h z=6Pi*elVWUR`jJara(S(qFnj#S{pgj^{NQz9}bXfWa}4W?ONjf=QqaAHI2`i&aSGGjs7>wTMPt?$y)>Vbr=5x|^1B(}9kd%4-a+$t z7xXA6&*e+_%jfoDzsEKNBLxoTfNhq(&mu7)Cz!ul`bxjb?P{y)=F6 zOnoAqsd+h?EhGJCI$4@05yc}qXZrZK>;anORJdcq1T%EU@7guQJ-5WzIn`kqdJm1d z(XMAM@(Qh|uN15(%W^gp?G7^zbnI*s>FPYCmB!N%fAWM5TCxXIwMXdae-v}A2Uz1- zUQ0bXB7cw$Wld~mnArh>@>h`N-rC$aV1*0vy0*~~4>Q^s0}S#Lyl37<5Ovw<>qzrO z^oJ|x_SUe*`)z6YG&cHjin=U9BJkzuad~F)C2Ca|JWXYRX-Wut_kA*GM>X=;WB` zMpPO)W-(>3-3X|9!??4bbT zBJzC9QuTp%TYXW^o$isC})Wr0S>M=BC-8+=zJ-qDUX&rD z9iZ<~nF}B_LY*Q9!lt~){>uZLT)lu3gL!PwC>+%S467OXl|F_+f}lz{n+@n=q)6$Y z)v^$`P3*--?|lqA;#tZ@w!bk(rjeRe|4&Ab;lR}IVXpB$9_?i&8adME_A;|y~o75Rf#skTG)DeLsJW5}DXN713-d4mtlLIVRqtaEI#`=tiSdh)ccDRx|UG^QJO+C@1x3i<>H*P4Mv|qzVu!6&;2#x^`|hA zok7b4kKPCD+c#%)x$5MubdHGybFzv$8Cak_Q7Q|T(x*HeI#;bir4Zjk`To18PraW8>0S&o-UGUh4k;QLg&XUu zhbO!?m*GImBa@S5@8s!zVws|=9Joj?+tO(!?J5y@v3V5eEmOd~&a#z<@@}&K_3`TO zB3pl&bwC<3(CmU=3`i4D zk0n$LwAb_iwoYgDp7F!@y?Z`}5A3-Ydn&Vt2YN_I9Ynf_-kPddAzkGd=hR6VY46^@ zb~?o^v(MZa^juLRYx=a4*22^RA2!-a{Z+5j(ad7np=+29&*RqJ3pjRUgq>pvVtrmH zZJ?$Fu4r7Q=u+ytcuA_V_W374_8r(^|B4y*V}=q@H03# z`)inP9HUO%L5Gs{$h5$SX74aR8%$6xYP0MD@r=TDJE%~&Hwsi;l2^98Mi*@f{ZP|X z8yKtKhOye6G}8{#&X_|s9H)8PV&ABL7;Gd=j_x?AKnIv{nWl|~HKewfM94G+easG& z4MO_a%q-eGwDt2~1?#<&jF;8)-lFWqYXjMlWO$p-*I!0{@)XR9vSVwe=P!dkYMAq;9z_lI$0V}G3!S&bZGTT-~HDE7@0FrFe~0K?_}ItCIBCgq3$LA@_A$#Mya)ndqqK z`l~`&m$E(%;!>7d(HNqh8>x;gRrjTeuC{>LTXFD%zlGU*K8%&>PApd@t^K);3Q_Py z3`MQ1)}*7JHOUDx$Jk0_&ekSn>S|%{t{Kf8w)VE5??~7Ph?rm3*JHFs8>pOo78_50 z7TFK~23UTb`Osk3luJWlm}|u%Z1AYZ_PmMV%4gA8_#BP=XHgw3@;uwl>(XRMf0+u4 zf-RSaWQS#WXS6IERRiHY$2wP!&-fXq2SqkaS)H zhHo)$jX^DO-$C*4_(^#A&&W#udv1$k507h&9_9Gk3#Tb3HH$;K)7IoekWvmxN9svG zx1*GXB=t!p(w95?7|=mWD5|xryY!Xb+YWQ4p)L$*49YocYNkSxVMlEo5AM8;TBb<{ zrONZ~BHwQ|h%^~(KH7h>?)0b8#0e7aeG^CU2M_%!K6vnb7|X{n8aVwYU6fJB=G5iV zPnuaH8oO5lm;-G{Q|sFDPfnYAS6UC4H6w&&F+mv9SRAZxsXCXF0aUQ(!G!I^Bbjddh`QG`V*f{^X8%@(?W5ZLIMUXjpiKU%~r zMzu0cC+#Sm>N|L9C+VT@qD_!y8eOaL-fPh&p-r4mA|FnXr)0}8ji%j zh{$~y&lrD-2HoTy#0G74?4U^ew1Z@fTL`)IiL=qaxy0hVdZFK0EZuwz!E87xLS z5FC0GyC0)-Hgg22mf@subho*Kv9lSTVrHI~vnU6xaKuVi#szgLLh_s-Xd26 zYYv01xB3VwgZ0n^0JUCbxm*C_T}#Ni={s$6M=R43@&1L{z-H%{tbfu)2N3h*{oHbE1WuBq8By;J!!H> zVJeeB((3Y{_LzfK9uwxEk#d@%XXlC=&zvbazZ7s3x?0_-mxtt|9jG=Q!PKr_LOAnb zR`nL9qw|qZu==|BdB|#*{?tbf!8(d8qKA=32{aj1JSM8@gu+#zyv+JQnX50YV20wf zb}tWtE$OIL8Wp&2iMfsBq}|SY>!YYlzaPE&U0BKXp_A^SpS_3V-Hm)e0hcqK=oRY4 zYKT<3t9UF~v_ef4xkIHCp8tA^t>v?Yz zVg>%%zQ>i}FaBSo+()+s@4$F?{JlZ%pq*LNx36-9RK69>1Y*2RX{Q`xG$K7%mORVo zgfWer27PFm;?u_Sa7=6xH{5vLQr(OckEvhChm zTqT!XEyyH6h#`&o-uaUVmyV;JYxIGq>?Y+oy(AgN6jE#GpF6?$1}1myH;2R+w9H3D zHZJELZ@Pqx-sjCcV5en`Da6zJ(b#=E8pnPa?MHtPw|x9JfaxiAY~PkLP4#^c?hs-WjO>vTnySfYknSzQKAX;hX~ zwldCE5Tt!8Rx=A#q}9Dcqj!8K#vl14_T2R_(#8z3>Nrw8HL%A@Wmgvt8iU+U8QW@s z4XT$;n#Gh2Dbm_#o4eLsr}k#Z6HV`+GO1EvQdsKgqNItQB2Hu-H0NK#^3#6}JogvC zDjn`o4@1&^AjdIiQWz~DpZ^*L7rueo>g%XyH10J|I3{0IHCMQTIIK}{voAE_JY@Y; zJcY5oWw8~?V{PepoAqCIgxW75$Y4*vI(FWs8>rnBm>J`2C8=-{t@eXxPmy27KE_M# zBtKSdPJ4xPwC1r2Dl2D&+y@Ty5o`7btC(55DyT&_Bmfv}BvUlKN?0@02IXO{u}W~h zD$CXT4>rqD%1I-EHhLxDBF<$Kc!8$S*sErQvN3j;n8Vbe-@@)A{{+)J{#U3sevMAq zt>mj+?C*o77;*_N3c$RwX0)>vMRnh4p_+tYG>&?G4rnzn=$}P8SV5GN#+427g9Io0 zQ01m$?D{S`-4}Q~Z$?cSJgyvXodiDqpOXAvcj5oRxVyZQ=Hc=8f@SLE)xN%=M2CyA zb8BXa95kB9lCP9y8dcK+L}?fI0MAnJhnkZHjI^oKvC^h4$Pt?eS~xtt7qig>Ds;}w z$oK`3jcTU!r}UZW3ezv#(J^T|M(66za6f+MfnUXE9{3eBsaMlJZKa4dhaT3FuC`h< z^{;fGl!`V1?S-mlwNQDFGC4w8@XM?h`(|ArTOnD;j(P_VA8z2mJrO3;B|2pnaRJ05cM=S<=v(D{q5B8%pHy|?=ZQa_{{pM`d26m#MW$-m4NDte! z*hffvC+xESJM7~P_L<_DntfamBgih&md6gfInCMDYff^|^zfOxw1IOB=%cJ+n6F#P z_YzmfWmgTea%p=nqI>!c)CV0hB?+ddC$ zIUyyWQKlvtO(TO7`_OpkQ<%B?Ls+fuL^qzGl;SzkR~I=(S2p}D4E`UhuC+-)&`H&R zs)bIO6q5;1J5Qlft3w}-93+VaV}JFhI+Gq`ZPY<){R9?&_&Ic*`YfHaH|S`Rs(K)j zpQK~<1Xj;{iFW*}XwXU00wS(TS`lkN0mg(XP7BPWx`-#4zneDb95HiLY|CRhTcVn) zC+neMYz3>X9EajYwM-SMT(r7powwyID)nQi@BAn*^+BdP#IyRygVGeR%XB@RL6+nA zL!-VtRn)s^fD1n(JNzVU&(;;E`fLR!$Tv@JULelW_+Ek*727TB!v|5F`7oNdeH;@H zegLhz9|LCYMbN$zNq88YbT2x|9`r`M&w?q^iu@F{Da17Gc9QJ1pL|G#);UclP|l$g zjvjiD7J6beA_b|~@^phN@d~?#N|2|dL_K~!_|JcbKhJGBXn#s)?N7f6e4-d(`-^Sy z+ehBY_!5_l%yEAcZ*AqJ@QFVw;tTv|?{ej3w z1el9bG!y2T&~aj!X*fh0_1Q)2cUG*D*O^z1Tjsg>!21eOv@cCF>O*mn0wcu>{ax5q z{|~T#{EsnNyPrHV&U%p7Sd`kN;9k#g_J^aKW%v`I^EVhHl~tClYd3?YA?n>Sd;Gyu z0!LRg2HoI+Xb@+HBGe`QIp}8yG2(VFQ!QH z4Rp2O*L#d>+H-4x=6xmz7hk~W#E-~hGN2j9n=p$4bn_wNhy>5%{Wg*HQf$0Nt7CEu z;rMP`9JR36+=+`*_u~Ank0O8HKf=T>{}aspqyGYvzx7WMe)>NJj=i6K%A5O*7m)nz zXL0t2Kf-#CH+)1#B_3zKnv$i?($cGfx}1CV{+n)L#}W!UQ=Bzx>`xS>+ zDEHl&D~GOcF-$VJ_svu*1(j*P6*5@Bn6d&2dap>MQ8lgZ!!UIWt;hcW`8sx81F2R;8VwQZQv_sBbCl&UE3K8o3+%~*E|Tz6q-vz6NsP}2 zh#6I*XHtHs)>32^8FO}yRS2|Ar*?$Zi{l6C1{tt}!7hC7# z)V;iIH18{a_><#7$MG&+|8I-%2^9(m`~#1v|i=V zNE_2It@Q9O3O1W6vTQ#foiqc;9N^&y`!I=rboXcQnPVTt%xDtzeihY(4jhehsaieY z*31??pw#DhbZtbtQ!74JvXoAAANA3OO>5j)UBkWmVjMeA$9QEG*jPn_X{)k{hRi2O zXj3p~8lCJq)2)R=b(PTfZ3Eh$nHEH0zw2Yva{S`aeoQwW$E`d60At}Jv^VOGpR6bv zEH?Th`%K15;k;fBrQIIvM|RrJYJ^;CsBLPeg6b}-du!CPLVIm;>>!UC(0Ai(Bu$Q) zMoXF29-8Z6y*=!wJz^iDR-VkOc&)|kS#x$}&yqHB;Mm7n0M0&_fi8Nvm6OlO)t|{R?pk{=z&jQ?<2p0y&w5a9QpO% z!|lKRTbO;|7^>3^WG7z2`ioEE;+OssC;#$aRbICToXc({t?x1PlEbN`cBgF)wM8uD+@=hBo;-9&=; zfewy_^>xz-<{*|qWecJR9TH2YBTd6BPfI9?Cai;&Q4KWRkF{mKi3WJIRDQ(vX9MK% z6uQ}d%HH>5V$Y|6<}qHrlWpdWPF_(d3f3&Or)(2rOJQB6QE+kGE7NXX^E2QbuD?8c z7xX8ZIiW04I8$OfT&zp2X%?b&fU&7bwmHYS({Ez!tsh|ZxxYd0#8b$-7f6!;%{@CY zbL4i+-S!YB_kWb>KZJJcF|^0;XK{1DkPdd`IOW`$dV=&KKgv;8S?mX`d?sNTXbNkO z_jIB!`s)Q?5!T~p#h+>@j1HF^u@Zkmhidbf&eZ3gqfYFY#6Gzti-}cZ&aur``0-vTjG|xcy04 zkD{J`QaW=i>%V1M50Cc>l9m@b%NSBtX@M%ehbvPek%Jb|7?jaX2SPz|RoYOyI;v_B z5PJYBgOS%!Ny$mmhm;du*OL=LJ+rqpjX8bWidRb&J6-aN0ku_Mc9G`NIFVLjbVj+; z<1zz8?`B*@gX&^04fKC__owlD_kRX^vRSlyb<_rdeG4s8CVFLoc4R_3GSz!sdML>} z^=YS|zl3HwkAv+V9zRmY-7|fRWy@$#N5xU>9$XXEsvb7;fChzDezXNfR4p3)6^*)F zrQXtV3!01BY>cry+N1-Gx=v%)*r##l-v5}c#w~0tOO^>tNK4B$c21d~N{C|C(Bin* zY!3#bEQ21FYyU=p?zqxG27K16@%EU?UL4n9I<%@EH5uf2fvFa1kofBs)#^ymL2hF|;V2%r7e zsJ{MLOfEc!xxqXdbUMb4+>iFY!-yiSoTE;6uoru;dX($>gq$S_5>1c~bJ9!8nYSiT zz4L=;Kl+Cl?7SD9c$&_M7@ZD_9OaSTml6{fHvxlIxv?h@+k)7{Z3WR$LA^#sHUZ{t zCB^Hh#mK%jK~Ko05>m)k#*mG8Gg0tl*$M{z7tmS#K84{j^kS^OqvnK)%X@oYy(834 zb1d}qDW>upQ4uDHa@JCgfxa=K`o^m)eu2)|1zT*f+TTS*u!EYFoJfaZSgl|=ok2AD zL5%JBeW3j?6HT}x=rHQ3sNUPMmfO>-pHi>u3?k_zT)r(rMuxS<_<>EZDnV}4^5DV-}hXwpy8d3tYZNPX*;b!Tvb&mL$hRG3an@z?aNF1;&NXh}=W1U3VN zx~x`-=rGLC?U3%3Ls7`)Uld5+(-x^P$kNaQzSJHNGrBmf2d{c095KE!NU;l(`0YDB zfzKTM7T4-A+5l8LqmcP9$RQrm+tKprwJ=4q(#4KOg8L7&acnMNJ}Zdy zX_%yMZ$xOOjg}lySwXJpa#dP6bkOWQb!X(uant#$f=2l4)eV{r z*d9%9Y&IrIPC1`-Mlqe7G45&5LH(wwj(X7Vmeseb3ls#={b%=}>{$2eixxxEbSXJ# zgX|Y*uiX(zmem^*_V;FaH_N zed*6}>ZvcHcj`F=i*KT`avF`{I%;W$*X!j@Id%c+Q+qLS2MzAAS#}U_Rtm^aoPRT; zVaF~C#ob-Bnitt0`oJLjUj1U(>gl2K zE<=IMdN`=m#00obh-bLbN*Ok_Qhm(+=8cwVi%-yDdlH?sXOZ;JPC^7m7bcHM=q=A_dHl#!y%!9aEx6cq9NoVn!cYYL~xc7rN zG`$yftrDV7E-{^bq&k-U!3-3g4cHF@?3-=i*ug2>HWOkdU&U0ihK8J`JjI~WLlzJ1 z0kanF2-7hZ*I-{q=A31b7Kza`SLX;^4fH*)O4!A4kf0v##Qxb&VgKas&^A8katyjw z#>gBky?&usy}F>`4LWAhr{-Aj&@K>@s6I+B2d#9{WV{e%I!k+_KzG6apS?c;vg|m| z1JUoEVztT(whyfM`a_Q`#i#PZ#B~mh{k06FW3I7A)``hD!#>5*>VNZ4{dx%ijWQon$5rbM7ch<*HCl8wkvwKyPsZc{Ua` zHZu}6M_8ajYoKg;qbiq*r;9>&7Qu|DNpc)BmAuDfZ}64NF*fFxa^~+kv(z`GzCJ+(ZH8_K9uQ*jW1%J z1=6g6X}DVAjRMUYrvlX(rcLo(rr^IA`N7*TyzMhUMYAhV~$eb#}-g71R)l-C-IMY)>qoqIVL-{PP6W z_fmL$1C53MgoUa9hQ{2T2)dI9IwfLr30Lt+z>H;K!ceWeV;jKekk(!@$)^4ypUt1S zto!uyr*yRJ4_9o|@z-|%cM*7fT)>DV;Pi)oy$r6jhRoKP2{b*92c@pq;)!iP7ol+ukR))s>DOR;_U7VH?l85LZ>7MJR0)a@;-3oVIYlHZ499+4dW78H2xOZnA&WkWIW|p$i}1Ta)?=I0$|pw z!06%xk=70kZ$^3RMFB$DohN7M?kt)9EZ3)oCKISV4%EVF>c3Q*7{Mx=6#X*!V zybhx`d>);hH{y71JsK2UI$%>vm2HH{dim7b7f~p=(GCG;$0;cpRdW4W=AG_Tq19-t zVkeqTstqbi=#b~Fe4FJ_V|mmOZf+5rvC_wyg2}|HEEvC?|6%3A@>MY{m5ma9IyuPU z8ma5~a6KS;Cc&h-AYn>@YttRw>GBpa6>K{{f?BW(<+0l^u=$hJu$NHuRj5eYylSX> z#a9)loZ=C1Tjl2Rvye-=dnIU zQ}Ir*lOMjg#<;2|5I0i9i+&?|j@trPD!} zbXZY4Hfke47Sc8e1Q2MfyJ?Uz>IoXCN3{E&B%U^)kduxshDB6M>nJHp3?lQ+qy)3-a4g zZI`Hzw1HR5vROnqn#M%~ZCt;tge!+5jCLpJcar53p{aFX)MYaA)d$OxBj@=h^^}gR z(O$Xh{7d8mrRq&hEciEW>S`v69PM(cjo12gJ=}2J%+*LUDz@B z5p1h|gqFuew6zG%?Cd*jWTN$q{FVSI(+^vl-(s9vNAE_F?6c{o9VsmWFao#&_;Qv2 z_sFqzO_5<;yQ|ZY4`PMoN7GBi=MoCuM)GVJQMaQ_q*(+h4q% zyjtW>wX2OHXl!eGmGz{EsSFd4p&F?%0KrlqV>NBA%NCG}wAn>STc6D(^wEr(Xa^%0 z+3_ym=HEoT{e4!Z4pF<}77!3vQ?}(Y;I`IDg{Ug1&4DPhtcix&4b#ppdBhFpnRQHd=5>I2qLzEebc7Sdny|8?3AqT^^D`6`mxKSq&C!8d=s$Dk}~fpD}( zS<%SXP;>mLKIkgi%C=jx-5OQb^6e^_$``a2QD>oPajt+ag<#zqC1~G+>b8GEIr|Zp zuD1)-p9Ow;Mf#&pYl?=62(SK8`lC;MawMSiu5W%0T^jLS+9I0XsOkICQ9X5FT8E%Q z>VauU3nTqwQyLjYI#FxH-Fc$YZ(Y7e!5J0s?)-)Lz1#i~c9gbI-Kf)A+Emh6I_~Wx z9AAfweYo4v<`8$ipHtjmf|yCx=pk7$q;3bZL${@N|O9AAl@ zgTI3H!xz);+Qe8!___ue_+QmRW|58ZFkhsMEgDS|;Csh(Xe#5DRoP|41X^n*mayIE zCLwT}>D`Sd_Wc)h@=wAmE+S%GFdm($uDlttkv5X2{V_ZgdKcr?EqB|ab49KetQK{f zs7)TXE!o9=^+ZKKAe|dXtcb z^Y&{ne8U$ITy!&Pg>f`J3J4vlMg?LK*x6&07GhOI&}_oNi3;@`*_N}`+eIfOBSdHb zPw#6)G$BB1!Xr2v-X0>qj^$FECst}1hO!Ml1kNlD#Ver9i%N?MOc(xtO_DOSbF?I! zl`Db$u*p0K1oELBCdtM|aG_qZ4%5@Z7PS2jptR|eC~PJusBB_*hGi5sRfWKeDYYzH zmdG|`$u>}Vy~LdFB=(BZJUG~^Tsl#|)C5d3upWf#Q5xD!|8aQHAkd+o9k^Y9EgKc7 z=QnH+jLnfx^L(|=c9>W@)oxdOf$_;LH9+@W1G+xjKaHI36y<@|pe-x5KJ}?jeL5eh z8&j7MY~@TJs1LtqzccZAdUxW=U$PgoaPIEZxAOTAVJPivUa53me&g*=%&X}N>4Hoj zI9*|GB`Yi(?Gw$MvC%a;>UjZ}QHJc$ucJ@3{ysljnywm=TWe1;Q zQk7Ues?Q>-%|q)pCFEqxX#$&o%^M{I08r?@J)N24`0(!KL4?LH12KrlH5&5|kx@z&U|~txMxK zSU)t6Tx;>#C?U#Uh~kD%z#qGfVC^#2D)K;M*@{eY#hQDpt#$c6J}eXP`h2Z$7#BU&%S<0PB}DJ4SD3Xho&(x+i8$P+KJ}?j=PyYwnp8{WWh&vEY?B_$ zWatXAffbTnPJf<0lfO2}lA&py5}CZCb)%Rq$lITkPgy2%sXnmjYEEAmL#)G3)?Vf^ z-bl}AIYu4@{##F&cGIRS@Wq?2#Wmx=4Z922HPAq%yMVAmU8Sj~GQOp|G)?BLN#EDE zUtLC;nI-V9g!_I#71u+%rD=B_%EdB#PdYNsfK^6Ov}mk$X_rXTleCRY**daM(4FB^ z?*KZz;bgy^MPWOD%l5R+U-O|mJ5pRSmvz+{dM@sBORGD@@tHrxk?;H|wk*DAnUDN3 zjd`~fYB{bWAb{wx(rO16ty#%w%A*Z8@?A}rQqR4%!HmnS)Fre+Z4SbBu?RHzth@=+ z+pb6DF@&Ji1gYYPTWV zrW6TZu{D2mvEO3x#0a`-qYSIErvlX(Kz>Btb+wsK4h@!1W&J+_HhvkoJmY)2P=AW! zFO+8df%NVdKm*qT7i$4rpMFs^THK!AtsRoYyyUMwMcqlQr_Mk+9X#zi6Q$K8|D2Od zb)Ze}NwUgQ`bpiU1Y!gS+R@R04ZckS{rbVn@q4%YBW%o#(VH@o{}WAtG{eDU9@%oXEJIvR5NwT1%!_G&yt{N83NZi~H|DseA-MFw2l_T9lE& zzr@!8)LLhshaJmvHe_kC0$*`;q~-L1pSMvRO>y+R0NrkaJnhwurQ5Ns{A(B~?_ueV zQrEhifPfKb(8Ds$9wSME%&;I=ZIDppxyJYaO~diVpHp|18CY|P{Y$+ zjDoh;Pbl~dpoJ7<9foQ1S(8GH;6mH1niOO_v3m52G!RP$?(!_exXt*gJJGr769_-@ zB@}4@%22ntbH@0$JE<5|F{L0Jh>(wK(^(Pos^TWF>NM-bUKEDvxtn?sormwh#NH%K)0;HQJ?=SG+zE2tnWV0Hkh{&vK)c1dLTVbc_jaO0o$fHWlDt1Q!iG~ zrU4Vd)4D(cwnXR3@IA$=#q+k{kH1?%fc(h+fZUe<7jngQis0=*eSr20B>}YmI&fS1 zt50i*wp6dcXD?WLJHAL>Ui$UVQuj$WIDjUX2~9Ig&KGG&3(t|n= zO)H;lD{n=R6mV_jQvBYnU&dB{1Ldo98ebEDGkq!db|-0DX=QPZc7kn(&RgTJu6iz) z>ND9B0x`y9=Pl@!1OjKrad7?~9GUuC$Vs*!=ia@GO-BjMB zV@WBHKh?ccNaZbl(3ZF5EF`r(>)=?#Jnq611ZXX9uUm3K-sqSgo8fa7WHZkAx0fR* zr0r6OFUCivd4e)zB)`5sm}p?JS%1{AQuXvJJ&{0^0&tn7*_5$hSvN<9Au3#gE)53lr4?(zv*)wAh+iz* zoD_+s6!Xe9Yyek1zXH43u}W7L5ihKJ1`z3IZCS!ILdf@W(Mbl#dQSV)r#|)R{3K87 z#(lG5pAQ0HmbhK)JXLe3L(70G^UzA!Ye1ghq>lctWvYquW4lI$$pTe zYpr8gJ2+}>n(p68qyiQ{GX9d(1`W-s)1xB`)E+y(%$*%+TBGNCbhKe;8|SnX=N!|D z+OP_=I72|DkuZLi0!c&tIy^8)2(S$Gin*Ew$BX^e)Bu`~5{`6TuZ&i1n7;+q6bHlD z2oGUESV5yO0DolM-gn|t6?#Q0ep{1jsS|J#2?80e*Gc52J8D^(_-MjVAlKJ+vEmZ% zM|Pof_08CN&CTdm)?=DNOe35<#i`2g{*zKA!?LmR@w+tU+wezwsO%^aob?dp=FrK} zj{?cwlEP7UQXJ8EC*TqAvvbB=jE)#aKUaFa9t-YJ+VE!ldh}PbC^MC)gLpa6rQO>$$+0rZ(Dqag^!AyR}4VCR0-0 zMDlW`hI~{<1kz&r<-$}5UALj+uOlB=pA?PCP2n`f*dwU&HM-4v*Vt6WT$zYR0%&Rc zngOdfT@SLn)M>(cz%omsDOQa>KCxJDlSeX;=A@?k>qyd1 zPNYsMJzeRi-}0B#ZBs95rM;7na{QB?3Hr_;DG%ycElKIE(6PoW$2)N+Hh$A)p_e8{ z$r%N0n(8m(mASvcfs=O-$~+8|CTWAT(1`eMm`9TD(SB@E*S8Ir^|}Kr!?QQQ1-w-5 za&F@}YR8zGj&-Bc?V>9b$kZyFHi6N7r`x7JTwvOcVWxX8UY`8VI8l3ucF6+$X-8Rx zDweJ|CLmLXyVidjBedj1qiOFHQn@SNst;+aS-PkzLoKF75UeSX49jN%!P-^zY)S80 znX>KKnRQx|e~w8tYxSr;2QOUV24G;l^~2aBoiJ#<5O04HpWJ98Gp=)4bP%{zR_(gT3vX@4BExlh zd9+#iWR{m0MhlcX{s=+Z4pgqb0o$&)7UA$l0<;prmV+sZ-!&Qib!8*NURb%Zp@ix- z-VCr>8X9i4I*H(-Q ztu+!?GtMdpnRC9b9OagCS3o&lk72eoFJg_M0bytT#Hv%gQpsuC{0`ff2F|qQw2mZf z<=I|U|D50 zSj)!MM6cFhD|~dT_ftRnNj28&v@ut&IhEuh&7R8Vok3C*E3>@BQUWac*?K&)DQKFL z|E7w`yV$Ft*?S(x=I_VJ#Rt$04zRGM(e<0u>zd({rwg48psDtn!NK^{nS0jTv6G?< ztb0E1r9(Z0v`M>Nf^9w%XcIW|s2gSYC$w{ASEy6dKw@zki}8~PRQ3G+XzbKr1T(^PJtLr1NTp9opTR*$=|UF>MsHWvnyg?8!P? zWWNw3hu$x6z4M!-)h+SH90Hr-q~4>nL0Tnrlg?Zp6QA4sYdvGLq{VEf@)J}9NsLll zL!QQ>uiga(VgpG$9cSnxUmnspavHDxtU%xIBoc28z{q7@XrD^EA@Cy%OKe+bD`Qdx*n?AgqB-r3G(&jBpcQ9Z@e= z9Z|Q5JiklPWyAcYfh-*=E2WF&!a5)&rPJHB?|zRBLVY4OFF)5!M`jqO-ZQwZaui5Z znF=myCh8pp%0Z$i!)e1)SbQ;nyXqIq~hy4-*|)3Ac6W$DW?)|;Y!yhA7}8)ug+w+C^@@w3sK&!O_iNt)Pups&|$+Um#VDGG5|G7r`oOeRyB*~j8w5? zN*kFGEGHlJyAafvW!;0%D@Bz#EmqbRzor#5vP6FMe1hDeD}XCMh4t_KB$APf(6$Au z+F4T~EkeudqCG%CvYBPGjgN+P;`%IwQ3qu|K%PYtP*{Zquv|H6yL&^1=H*6ERHi*` zGb@0g4A^1Pax6b-LkrAzQXrrpwuVX5WOWEP?;CuykSk%)-voc~L&)#=?}5@SK)8cx z)q5J9oo9G{Q&>POVNx8k2>MavUv1HAV|{6Z&|jrXj)C>zG%IV1mJ_`)3(MKam?7s5 zX|((caOKOCQFJFhsMU4M8e&?^#pMC1n`As}#$;yq?Y7%rL1&+3=j}3t6=TlUoCu^b4@^f_(;>r{ z=I<T)%Dhftd7GvwQ<2YK0SEzq>=lGo(2X5d+8 zZ&q*4j@&Mgw1eXi#c(9`J$K}4(JE0K5qt?)k?X==#%TjtsqwASum)x0Ddyv9X-4ju zIeVN&qW_E|2-q+MI83mqac1{@GA6x>Qa%X`*~!mo^_JaUp+dUw-59^=Q;4=*iV3eo zFjPV_Owi8Hqq@C>{I(K$MZJ+Z*E^^pOpEa~NDmm^c3l)QRO6CA8wLfaIU4>t$lPtI z%CJ7uDrXUs1ia%alfIb%^4$o>K8^fNT73iS3>YYDF#%Q=Lx^&0XxhC=wOv`3TcT5b zte{r~d`FQ@Dbe=&9?OJ4JMCNIgN!FChqNq6R_69kwCwNRTggW~bHY^9K7N)t<9&KH z{m%bR*4~{u-v8nMN-*?i>BBztsZVD`BLjo*XoPzS0h)||Dif#UB;hg{w^GjW(Tbl= zKAsv%uP1z<_0Q7_bJSJpxR!KW3G3bgw30E_k(?RY^dKVyf}|!i`lwkt2_{g(b2vWx zBO5uZd(RPn&AMIbX*YODndPG&ZmqM~B-%tQE;9N&OOF0p3ue92XGaO^fq?$@ z+69|B($JYzvv*LPc>SEJnnY-$)2)%$;xWsUAk9W7e+DjD^<$&e{4b55mGYzR!8s&V zn^mJEjtrpLFu(bTnaeI4`gfAgeE8ReTn;D7{Fk4rQ8<7`w`7TD*FHH~$+OJS_@+>d zy%r*yzro5+*OPHRycM|UT8!RsJG`BHFh~Bzg8_!N72vH)&>ZMMhfkj!N#eHY+}8L; zHsYD5E3nZKB?^QwEt+#|n~bCaPp?|oXaHV!GloY$g6f9P0p*LCof4haq;;*iYK4>b zcj{PH_06mf_35>V%%ZaKa@x&Eb-?!=3EnWMic zV3{E5tm*Qh#oDJ|1l>gT5~SVrN2iWf{hz+iKjT^rN6Ssp(de+AIonm7S8#mVo4 zdHT7jiH>xml2pFZ>30NOIn6AgnPU_6XxI25L-_NUZ9a6-4#K z*UU1-^G+gW{B$xe!t~Z60b0wZH%4)n_P;ujRd0R<9$A|f4q=5Oh%Oa|(g){`oCUQ? zWDD>}j_ta471!3b@VDG+(W{xqjP{{8na(r?{eY(qd<9JUP z!@oMt5oofKCSCz3jsQE}jrG@FkAXdTcpDZGY@uOYA~<7cch<{Ukc5p*XB31|Jz#nS z&eVIMHEAkXdZ}kb&$S3tLYiWbe<}Abz4RWQFZNM)+gXL66OM@1yCr5fTMt03f7@-nMq@{`kVszP4WOKek`t{PoLf-5v2VNFLx1ui3F$)e3m7YjSU10yK-ZkoUKR>?r82y}351?dN!bxLJq;_!6PmC8v9KuvL+oSVj6ZQeAY z3w27YYlv3n@y(L>Age=D4p)G)lx%ZDV@C%I@i81a`8ZC_J&sQ9MfAcsbP^vC8LqWu z0l}G1kfuEfG*%YGIRpY|EH5qfFmPtZ1tV0POFGPcxZ77z_H6mNHVElcVmuP07?R4N4^0%rV&@zNRoTue4XaK>AexZ4tTR3Fhws9GSTjGtHM7TJ{n1Z#y5) z@%Hsb{FIMV`L_0nnSWKb^n(DcF;8IJB#&hqI)G-+mf8Q7$!!p#DAWxTu)PnaPtF}F zSF1__QqCw7GuT+H;z}$z(e!E{ra$t_9LXX$wIrO6;&7yx+}7TwhI?ny>+?WjL={0Z zyd@M=B6hTu9tx!8i@;!j>P{cU&3syzN9^lp1O`e$_gg2Hm8})jR}=?RU?XTMGY$XC zkKd9OZL6<)9b@U@ z?bGX%>Wg{;snX2SAotWWD1U2v;^7Ks7u5wl6UoCtekq?Uq`;cpX&s?PPOYZ(=@(7A z-j&{vKKr}CA82#al=STRqv?+`kO0+6u(WGC!QS!ohv;$OI|N>*5P{ntGTz_GzO#$> zpJKR&(%-K^ck%hk(YZeL>3pF}a+@%k8$g{#cir#Vj(`DmQy9@W)cR)AQBKZvDK4cy zHOi(<&IAx78?_;b-AXr6*ZE06Gcbp?*TE5g27BiZQX;ypMK7YkZ@W;)D3_d6%;{hK zk<;Vs-X1uw%zO1oY1J0V0$NN#madhFIwfH%0@yCzWRNz(FsIGK_(V(%X_xrZSimFL zfAX6+GIuAU!VxO=F5;v~{?EDU^c#=b><{rR{dHp zMlgS7l`%~#obg+{ms|0CiNyT1L@IR6pt8ndFv0S}pSHC=Cb7`jM}R&-{?x>H))lSG z(efA;#FaxW6EX542^wBonQXay|+H}lsY zI=g3+G~~+$qpdcrp}SbtTDAPyDdpXgJB?oJku(PdkY@{MwX2~vS|=`3TW?MS6o`!z z-$pAshJ0CuIxBD|My1oG>^xg8r)6kPf;qd_MS@NOje@5~;lvi|X)_r%9yCj6O(d8* z*g~;YzyOQ8x%WZL-t`}Vr|(42oMOYWW04t~02`Y+!vu5YhO%I44~PU#sq zCI{V`K;BZQ*_4Y^xXII|1{l%L%G3SUttm?S>rhs$J=3CIof~5!pijS0IzSM$l2%S7 z{HLcqI}@#(68X7rq@JR53S~AWGTV^E03YMMEPdxy@121J9RG^oFMFrIfk>auC)$c3 zY$%SPO1QPx1BL)cEE|0DQQ8oy_Z4rbB{33x^L0ABBM6jn3IRZTy^VtsBnKQEdJG;g} zn&pwV~KaKRzm?wj6 zxxOq1%=GeFA@Pb%*5PnhI>cF2umsK@)+#^zYQ+HZjE%G#Kg$H?M)Eiz`G*~y+^ zISY(y!nE=!> zzuz*M0Fz);HB4Kf%2EQ?ldyATnlqtYWO_=77DIH18NFHhEq38`o7hz9qBQ#=<{$Vv zLE2qFdk!H%fW)*3Els8D=^%!z9`)(xpTVf5D=#htDu9o-}I(?+Z~}9^hjC>3+XO5>A5J6JG{trhtbrmGq%*6B2Nv3gf?in1NdJqfo3rGk?9N)w%2Q-%oStEbqy?AKfbop?V zE%jPcq(n#P>U?Bnm-!@SVm8F*1PjdrXm(#FpU4LrebgCq3P2tRWSuSLXiu{Kbvr(W zs$1CdSU=7&Df_EN#Y%-$Si;8j7&ua4=;D0TtKgo{KMP`E(s1&ma9sI*5@}&*4xNS$ z7gj;Jp81t;z5OZ6X?9&=o_T2=_mXja$|HIj$YNEXFrv(%jO3r_2r&0&n1AIfC?(IJ zf+^g5(6 zZLu8Ol#ICBp`sFCR>fIvcS~-CfndbnuD4IUT4@-&(8x%7wv(0V3~lIQBXfQFg%H8g zZ3IoX5|C*U+(;@VtP= zv^orbhRhNa*^be)H3Z7QZwmO(3QCh0!w>i^zl$hpquF4|baDuTGW{4_oyc@c1y1KQ z8}n#+HZ4bQ#U~Kuj+fEssdS^|-@s}1oX=R#EPr8(;C~tub5G#l#J#BXo@Hz`#?Le> zO8#2PyImBAR@*D?G!5obN`tNqQewqd@{kQmxsi`L?z^lJ^Yxd}P7V>AD}Tzbt5ez@ z-+-?8dPcHF^BRtSJ-05t7nLwPu!FwY?gi(LR6ACUynK;@g^kc^w_H|9-Sg!eT{D*v z?~RWRoJsg)6zD!?qwWxKcbfdchO_e3cMP2&)2Y|e=>sH9EsM2q)ka8MBd~g|=K^b; z7tuZOH<+9J7TyO=#p0W}{GEDo^kdI$)_wPmiFaH2H$W)oaB?UX(2-5 zX1w@SS1x_}xsgV(vT23dE%D?3@zjy4KS)QqvgencHX`;r1asMQO*8zT|1tmkQ5v2O zE5h53jH$oH#kdU!5~SV9?>@gWEp$s~vZZU%Y-(gWQnqp$Ge$np0W(G?X@*?qPAWdHUldU_`s7WYr$7k}lX^{5AP5EvoZOq4Y zJb7#{j^HHfl)Kc3{3pe1(Jzti<*4;|rBJrflr%*4@LZ5Gt>jABJAv=WjAj|T8j;AH zMmn+pB;H2kYnu!;JcDV>Cr@Ml@o!^t;c@b68bP5)vr*@Wsk1O-mNnvZ_9G^46pBv3 zh5$*LO6Q~@9^$oVzzp6z%kPBk)F}TjD4|&7w*}-_(Au@pWj4*Y3Rj)Ww!Te{nbJ3m zWP>n%`$m-+9_4k+U2P3qz&JhHW_-^lNGrC`&K<_d+5Ti#cwTF z2ImZE zD0E19r24?R6ZYEndM7EOHE%tvoW^-pzBt!rnX&!n-Vgu6 ze+zHmVhi)Op!&1GPp?RS^y%kKGyVYn>%eX4uRg6M+ETp&pS^%6ehpF=vv|Dz3jTjT z{;zmy;UHR6g<22e(U^8yxl>&cjoH*kia{F?l4(VuC%KuY{?zDOW`rivwOS6$UHWtO-% z`0&zW1(vR${UJMmKh8|wMQ@v1xIsev+P&k#AE38@3)PqN(A)*#N?V&L?Z~z4V(5>yo0k=_h?BU}j|_KW4~A zb_kpjZNo3Sg>ev&X+sJJ0vOKDJ=2=HHtivXVZ2^WGnM2D1Pz1OG5AGntlo}tIKHBi}oSf>OrBC@&y>Q-Zhm;vtx9yI9)REi4b2vQv100+G9&OL(2-tmelNQ6U z9eO21ZEf(Ou(VI@P0?G(xqvZknF>CL_w4*F6mS(w=iIJCv!YxzDi4sM+GR(Bl`_t?Brag)z?l}CYV=9_ z9X2Td=7?+_M`!kHm_PY_`0bZb)>h~?55r>MixeD+uUE3Ni~SB2ks8ulCqCQKg zV)og;LG<+Z;mx09I0{^8fmE>f>Gg<$DxRafVx8zwaR_ut3EIMF34B!oRVc@I_m|F; zQ>OHsqVrVe%;}Nq;gZsb)ms>huoyLWzE6GXQ=iUX3MsSJmxi%xWHU-hVB%2ril#bB z7V4i!HizBuD%-{^5qikara1D4-jknAQ9D4*a+V-imuejdj$NzJUzPpVxx ze$O25C4tlKFLU}Qm}8Pxab|AS=?y-tU1^w zFTe{K-f!{?3(WgGa-~VM{e3vT_&rS2zCmm4DW-jbj`6Ab$+=3wxacfnnWuh;M=O|r z-V@u0_{c_KqlIS3H*I5(+16uh7qsznp^Y^5wEj#xZR#D?C!I6rcrT~8-b}s~FbAK8 zs76qS$~*XF&9guEwuwq{^=NQ}%q8mOXKgK-0W>B-S25{Typ%`E?37Hnr7rW4wA2BF zJxy<1U}M(C1|}L$dG(!3DXX-w)r1_mzYNfHzX;U#qc!tgG#CFfg6MHnP$M9sTIyEG z%AzZ$fI>zZA{n7T4XB(bY-GHj4Y6P}*V+U%1+7NWdIC^dmll_po+8@E63iYUfNWJU zKmnO=`v^O%IZR7rT_to;h(N%B_vw3>#gmLT1sZ*N z1ES!I=GctX*}*nNAt=5%BZT$9l#;bB1$K?hy7HWvAX14athH2uVsm;=RqPzzjB2lt+JTg3X20;c6MIf9lG2NjlZj~nk;I_8P{ulg zQXQ3XzK6M_j^~f>!^^e9gf0XyE8;dg+nF{dQzc9kjXxE{reC2ee@{+7>YX?ojA7 zva_d@X{M(LmU0A30%%@5MjPllY##V!x=*4ST*hq47UH+fcG0k!HVCo8u&9(l?Sk#5 zAL^Qwkiw*3%yO$|?&J~>FC+Ie3wsU&n-jo5Cmm3q60WtyBCwS$ElT%GsW6O zWd#c|J$y=Q>?dvzA6aiSVy)-q2&z4nokl2^I3j+e zw;9m@)>AoKN|XN9ACGZrq;jado%cGVTBDoima-bOIy5xQcBykFG^NhwPOU{-hGh4^jg40a~B>)Ti^DsF%t#;P#B~#Ja+e?dIrba*#4jQq9DheDo)y z6$Z@G9sel2Zh{~{SDP>qptY$7yM+X=%pb=iFF%DT%uqYKBT1HC*3|zF6|=1ccXHMN zG}%&VFcQ5twq;JbMC*xoYl-B4sRh~>+NdLDUZ=YnIr}zd+Yh3X)0uDt zW_+fde|yyF+O5xWtkJGSqg5VN($A7vy{kA_jsle49F6=1+d;bG@5H9+C$Vkt?_l@( z-@um9n^5vMqNn4C6rLqxqk1%w+>t=Erz|aeW}|3wGVo=yh?rS{G`nT`rC0qL?Vm+D zUR8qHg)l1f8@$Gvfuhb#+R9N0affzLzJ^-z6b_wy7)Pg`MI&Bt(TSJtjxOW9uFgnO z-B@cRv%&Us<27O3S%{v-bB^3q zCSTH_Q9nNoXsRO%?41kFUY&6pj(2x_tcI+{+eU410&^$s1Lpo5m3SXYF~J$ZjxFHR z
  • KbtN#W)D1(n-Ycd+(ZP^jH(*q%LTCQwGOb9L3MDNVjo@WHQ4+%HdD85G*^@2Q zW>}uhGJ)6t(?fvR6?kJ1^~UK&_liN=@=}O-OtVjb<}(6Mf}BFuW89Tw66J+QG5Pr4 z0#82z)U;i#IFY$Ny^08OJFQ6yDD~`-3}lH|ZmJVY>`SzH@fu_BhiJfkw{AUm_hpUWXz7eb_R5D>e>Yhdj2Rl-r2S zLpRdzqo{h0Z+M|Lk2!?nv-jfo+?|AC&oLv5wC4D2zSFZ& zNv4Z$GG%<1cCcN=^|eDjt4*XeVdO~*hjDV@Cs=G9Buf%H=2fEy;<0wWG%mT}9@jze z+N844=%hflc9fPAK=(Yx6%S*uxCeP}jB(`|=Ira%&x_QOR*yz5LsS|kGny1mHH6w6 zf(HWaW zUWOz1;2UmGIot2ZRap}dbZ;w?Ot8IsGw7^#~;7w_q`PQv_uXAb0Gm z$W8wkemCNi4#Hr8l|Mb7Bjo#e3ZFdh{krj7WtO)d9*umcfiN~FMN-n&`9T|MW+Tdo zWhGIeDXs!}9VSnQHM$@nfnEjCLILfg0fHk{49|^Vq*g^)qjb405~U?bm6WD8(y-T# zpi*$I_e(-j-(_@6lU8c`6oh$#$TI6jadsaTpZGKMUi=YIKfxq2j~XGOxD!x}Bv^Uv z@wX;R#;M3tKa`x3>G--9kOg5vV6Ko9FE%tV^1bVN7?%hT5+k!l{j36sO9?(>3KF>!>!Q>4t36rS&XJw%+iqTGtrrzJHJ2pD&^1X((=12-5bAmDk<%6^_@PQ zfv8htIIqhO;IhrTQH}$I6l=c3VJcUp&gAq{cB1?1YeI1CC>={x}Yv{2m&~Q}9bO1gQdI>bxbth-wq*jF`OXwW#(R@I&eC zhVjle^f*g0a24x2ZW_N&8?zejCK&q&Hda4~Vs9tHUR4vcn1emoJopi88@mlfT!f@M zfH+bf$$w>6HVSP{={YN68$nwE(Co}LZKE$<2%r`DZ8-rs*)f7t1Q}XNAO^{gc{6=V zUiiM&v9bI$3K^atXnzhvrNwe?G4->UsXvF= z=A($cDYhTl@-`By_P~4!1d~TL)l~UarFcE!^X#~wY_*HpkETj$TI*=_GM3Ofi`$Ke zo?BYoT^vt5i=*H9W0X&P50$7zW1mJ^FV8~A8#r(yA7nEP?L_lQDS-S~r(NaIrBPq# z5pwkwlxjK}`?)H^@?GU1lKJ05ZEzc^H+~j)*C#Ps+??da@n2e+!w*miNpg{ zxHNMD8#xWBn~-oqOoJc39qf3L;Or69kA4q68+abmWP6M6NdUMhhi;@w@hCD03poiL zi##R9#i-?FLd8h&XF@>_`Hqd4Xx*U#(oa(s;+W;H@AwpKG}z|@v?i#uCW@%ekMMN~ zE`|>&h=Ud)ZFNP`v=TeJgbm2e!m#GI`exMe*d3sPW?rC_An-{U5~xk zfPenS7xM24+P4pX@c9Yg+DUBq;-~SeIw;P7*PVFo#@q1a-yE=DXQnfRv-qCD-Y;Bt zS~^~v1kmo?@E4y2PCv=j}Efz<`EPG%<4>+b`xY^ z+O$0#5wtYLQ5=x6b?falTp&isrc!v1bwpj)LV{Xv=D?lKXX9&DkraQ2VQ7ySkD1<> z-)N24+PEF#w-ZplpLX0ud?>q#7e&K=I#X8UYye~ac~7!i5@`M59A?@t;lSkIV4?RT zvZYNf37CnXulsg6h}?By3#zXNUZe;Xa+rVNpy0r_DnG8juon)}v$<*lMPQ zF{Uf&3~R=;j7W{DP|#^7$L@*4Kz)`1&Gp@|8R%=~lwmpdX4-I4rwYB&C;Qr(pp+$c zWx{hB+0bSi^rXx;KKeQ_zei((!lilazaXjK$@YJoe)3l!2?hZlCm^!l=Eyx4xi0zu zm6CzDE`22g_;K6CNF1k7LzT}NM?k^jQSfN`K#%1dvoUoRC`JU%bQZ`6l9@7^M`A=L zD3}`>2_q2q=lSj|uPsZvO9$hZf}#-9*8UFisiZ_%oseVL70%W?8c3v=n%a-q`~RAj z%Y8t*&hNAC=u9;>YR~d4!RhLY#A}}4$y0C!bgsUv4RTPE0?dS!%1I+x0?j1mPnca* z#Ok@&n`rK~_%V&RHpMoo(KNLY{~-y8n^1>odwt1UsWbJH zY6Q*KOb|YgBDeXKCWz>queMJUHQ&Yqho8WY_CH8CqfIoZZ8K4tiB0~{tus6In;x<} z&lM?gui>=ugU(=en?B4DoV|!+lTV@9IZnMIgSkZeV4S*k3p2V25dlaN4I$|aBWaJ) zjiA%0(#B)B9$k(=R=VY^NW3o~?&KNoFvhCy!mjbp5S)FOdjCSkJIMH{^J%kCO&V`C zJ+XjY7%zSRJ2u>o!NS#+&ZJXiZ0Y79gmBut!#cZ9u}xfo*~p-6uEyu82#mQG3!D>- zwirjuxT0acK4uQxVf4CXx{zt5y%diz-NOic=0AwhroKLY@_8Jeet}wk(O7L{JeS3C zw){DlBzvWSCJx~E?A@4eK1-9O&UQhND$t~^9k+ve;y&z80xfsvgqT zSDUp?XF5iqWfz0xZ76!%=p(z?7)W<+X?07lSVnc-W^zcwl4PWS7n!d0Ojeo6D{bE{ z)7vaa@<-ro=|Djhh8c)*GC+0Bh|dEFxGokaj{?(2QAipF3RF>@b5Sgl8jzeSgq%QH zHXU-Uk(7XX5L}Om5%a1w#p-j&*=|9{fZ3m*dGx!8=N~}TCy%HETE}IiW$Bp2 zbN9P+Onmiz8zKAsCq7Mg8$OL^@E4ZG&G=RN{q`4tJ-_Ro+X$XU;r_IYe{SJFjeq{T zz#YGrfx14u7MXQGJ)jP!QGWmz@3;U%g$j*n>9kZvDhzKkDVd5^l5{iUpofCW&vckP z`ODMBY1A{+YzU>l7+%vMI~5NTxkY^cv3u~~@yD@1`E4*wcBo#>KBQ~rPVro2QicP5 zmj<*Q?q*m0cF&{|w8jdkqT3lnud^9Lr7N**{B~Th>5JGp@;QuEK1}U!BT&B%s9npD zA41i8KPujPQA%z^q4Pl$ySJj$dq2GHR&)v0GA_SW@@OA;y#WjbH)Gej-@sVmeJq1@ zG*y^p**gSFDjTIejx|F|`;Qlxopo3jz7Jd0eF&oi*C5DkKw?Wi)S1aV8*tF5mw=jF z`rCFNloe8hry)53I!%*|2T|zl!BF@C_|5AOw%?CJbUjMZ`%sGC&+9EHc0P)H`=cnw zpTU^_+t^h4GIovrkJ!2Hf533*J&b37U~Lg`q8%?SDJhBha%ab*b3-wjy=fesdJI#I z`)NWPryuP(*_g@COqAxIcA@~9eroNRjik}LSS(>=a4Xy2 zdOmVsTV-{wNv&n|C@jMt+k`MbLPwMg;~%R z#u?%=^c>S|m!C)if&XdzcjqS1Is5{!$bzkuXqo^3pKD1(K~%N#uNX)!^vL-VQv8lbgC(F) zjT!$$2dyJ~?__{VYmh>h2D`qku-cKw-f;@h*KU%m69RYwdxD*=%#;pSR&Gp90Fl5< z;Ec-70W;^+f6}clV6@mnVeTM~{z%=+4=}0)i%Dx17x{VhQZD6He38s}AwE zy-!ex0ffPB^0W`o`g9(Xfvoko>;nQ>1GxOg_1Jsg#2LZN)nCxa*76A3#QhW4`-OG5 zI{p3gqXCTVN^eOUe)9t>rZ2i@dyl@(nlp{Ut(c0rVH@9lq=6IZ?>?QGq;0f`gY=V* zkG^RA4s0A;kHE{*(V&wMl^#lUkw_zG=G@a$$U@Px)oR(unSR7^dfZGeK@fQ8gbC*S z7LK$g@vR5GhsUR%vCdYh?IrcZ`$)gD518FVCwXmB-q|zm&ZIi;mffpp<-^kgochT9 zb1^!n&SAIpyMTzCW@R*)v@Ufq)6HbnsC!=N%wd14hWf}DO4}|&u>Nx7%h#hi@IkB} zzXdyYeHxcv{+qb+^1q9Vc76dD@b?8fKaE|xK93z2{wj9w`Zes>`Z0o|i; z$+nN-s*7*KH5Y#n@80tvy!WCHKYsLBAaQ{HH9{%7f>vd5MB1FwO%%41lYNZNqY%Bb* zU?M_aQq6LCl~Y|a5BJG6LMjEN*Jcu1t^k=pX1}B~bf2&lQAt?2YI7L+(>Or=MKq_s zL%sR}iUiwaqml7)1w&tNnxg=kg1WM2xU4>zP-OYAu62ToQ5w66ZBv%!u!ZeYpWX~L zqj@|%{kQ3_Uo1_0>v`M}Z@}k%Yg7}qQLT3H^8ZD6_TlZ=HL4Jcc5+#E`Lvm z+M|!*(b+Ay?wV;JbhH0v>;sUYBpd$8K_l>%_e;;LzZyacI=-pZ(Tj7XG{6o2AbP-uDo|`&CX&Rv&H4&7xQz1cCtAk=dJr_&& zN%Kfw=4{D^bucO}#-Ztuo=_jX1k!A_iA1Zs7*9vGPC;_Ji-p=Oj!qoKIF0em#dXw| z1chD7QmV!}zaSl_5jZp%fj$vXhZ-nQXPnaonQi0l9qDs2zl=`5W|T&`?A$*Wt8l9~^oXKREgl?mPZGesb)2JUnv{kIWy&qqPYf>-KQ;a0ffr?ZiO2i4zmg z!z*aJd8WtGDP1DnCcA{z5Pxdgp&t@BCgereN9YyJDBoQC6m|^!8iw*0Q9EjyBJB-= zFv}gw$!3ojgY1vR=kyvK4bvbugn?i^h6aYwA<(WZ%oE75j>wMH%q`hTKI7swVqt6M zh_7!esr;k!$pepouvftaqrZ$syMS8vS=8eFm}?%zRBIn58ZY2P<4K%o{uGDiAHt!9 z`*C#PJ{(#2F^gr0WG)j#~i~( zI5PJr_D=o@;?iE^@>-AP{;A_a?Z`&B2(VpQFm|)iSl7jGhO=&G%dbjOJ6eYPoDK)q zU{C=uL0LZFyR<0-*42Ex8{0=ejP>EQe0Lqg@R^*YbvgCtf-;V+3U$a>R7Q{=+r|b< z0j4rGMyhaPGlG>M0W`-LIsH&crlo0q7An1`uX>z9RXhR`##1KlZciKl4m?GHrES&q zAxHX#1fz>Bi_68Mzpetf!g0Q9gS5gh>E z=cau|;)#?98?f4+{#Y-Q1WU%9l;5Y6hjU9)7i~vB!Wu2uB$)DY{BCZM-*8)O=!_6e zHv|=$j)3g?Av(Q_F*Ugp-Pr+xvm!zPFwMnG2%3B!?SMeZD=|eC3RR_%@2eGSOa5Hb zeeX1KsdZ^mvvj}GF*WAbjs;*1^z!u8u1(PtMuSO|CVz_AhyD!M`$PDxleTJ0H9~d7 zDk7cjCc4H*JWwsSGSVLvw?;b271z6|Yeo{74T9yD5Y?VQ(VudhT$11n&EW2!^Of(N zi5TA6GDWJjZH9N(!L2i_eeIXr}bxd;*MR{rBfW;l*ZSkyPm?o_{so& zI}QK)|7v&opii$yCcz~8Xt>d&V`-Og>G%cMRo!gI(uBn_nhhF(QG{}}jBeCLLO|EE zHCMDKC<8UyPw}`}2F`F7$uA=lm6V|Za)q3ZkI{6;7|~!3FEkG0YY%-Fckh1)ja)13 zMbt@YO+iH7Q%^0KGqMQuQ`U^Tx_|C*=1!r^im@%0fH&* zxZLp*Okf`OO+Svmc=Wq?bm1i&FV*o14e~=?4JQf_UWw~C*j>cF`ZS)IJ%OK29L9r( zUd99a_u{VSpTV~ue-wZE+XlJ@5H1X2UjRaW9x&`(av^pBS#|Y8v?|9 zsNE6;-2#L@K}&N3)|YO@wy|3=T)dooQYWF{t;>VT*?{wMwn)oARBQrQDo;(3EPJ~c z*N3oW^hThy9Z{>oxC9WXa%q#=4uKkiOPW{gqm8t}`TJ;Fy^OimQ#d^J6HK(8V3?y! zvD;M7EqxK6F=M@p{Loqu-kYS*d$r@p672l3ohRDz_4R)rZ>BwqCW zuFN{VnzN$xqbt7L2uQHWQr++Ld0=(t*hbnt#vpSbXs@Yxo&B|zl z76f$;D-gmZv6w8v#z$e~fSMNXc37+}hHDdh zsShha6zqmyy&3s+x1+S_HnfVn&<@Agme`Qg0Qr5k9X1*@WHxB+qNK)cic#sHqmNN0 zS$I`?%qvZuZ6Lz5_;N{?X<=RjN_kDXEqH|j1CvWpjG=)7qLVM-}kaj2X_5BEA z?I0u=6EfX=&U~tWa4nHI;y~Kc50(qdOXWiYBjq0RDnFK8_bD`MkHGIvqM)sU(|1+u z7S_rjb+1G2Tp0mFE#zf=SQ$K*C)OTBP})eDtw~m?0PRzs&NsU20PY|V`t)C>Kqhtn z{CC%5?^h0-akCKIx(+uH(EaCKRIizBJLfI8udkzKf9{9+WOtMUctEG128bO1~v zDJFE?OK*`RHp^67l}2KEDyoE-8}#td$$j|23lC%O+#$wHkVYL_W!iN5l?>6g^tS9_ zo9f8)(8khHC|VvM;FLKBE?i!mfR|h0nfZwnCRM-7jt`|f)OngY+HN)rP@TU`t#{^? zFyVMSi-#tk$Dcm(eLOa`AGJb)rk9}0=YF|}M$9y;gPpDyP=nK!OPIizVIqb}_}ee$ zQ5>isC>9Ww@+b`w1oK~qI^BS-0NRQvg-WozwM%2G!JBxHUS*nz1#B9*1>1-I0R{_K z5kK;~q-@%oXlXkCYmxDWc{965Gf+k_R(dbCth)uHn(6#9Fo~B!N2pFm3=@J7kDknz{0O`u?rB^0m+1Uu39G{v~ zKIAMQY318`hqjiMI5=ZF4afE(`yilYm2b0r=P*ZG_3-p#s1ba6#RW#m{G0{3*<=Odj-c!*b$kx|<4Q9BA8|1mnp3C^O2k@t>K zcs3~XI%xVWG{QNw3T*s3Q-qD*0W@+%S2o&A_{c4-|ISFO!Y<3$ z&ID;wK)O@K+FpRd2!+>%zXR;}EXLmdn;5_9BWPAPqRwXs6?e-(RYBX|Qt9Og(6pA! zJ|om_4Nu|dL4aj0s}K6Cx6|Hax?G8a21>4Xx z0m_4a4!rn%^6r?u$sExHax>|*4gcCAS5^kJG8QQd60TBIy!CC$4j*)Ch-Q9(PU}IG zSY|o3!IVzHW8%RZ@WH`lji6}*67^=Go;R4um+h?hMms5<8t!4>UlAxSZLvRqTmP3UfTb`* zYhTd!m&vV-d)S_97sn01d6jJ>l8p-9tF)$J`}Eo*5o%;|RL9u*1i1saVe_TfR@nee z$|wdU2M7pGq-T8Eh&cmkXGclYBWB4X2=i!bG_Dw+OMCZZYZk}a(|Eag9Ivz{ut4L! zK`qs$%@dS-!)8wAGqL6@Iwyu#IuW0_pEA?aztpp4(E8~mYnq$Qsv7Y$mI!Y3O*w8 zP+(4L>svAHI?aeF1n3Z)YR5|(8R08-c(KyN@^KxEZn~SM5$2*YlXWrH7e0?|BOk|5 z;S!eMfZ0;E3pn#&ph>U4p|00A1t4T&h-my1qz#0ZVEg!ov99s~gz;rGfkqib2OblQ z&>m8%v^j`0q;vX~_+Vo~@Q9psj6g1EA{Wx~2n5XPEKh8!rO5P0}>$@#{>hcTFOW@SwKhh#y^VJH95Pax92md_#{|Vsk_WsUXY@8 z5Zz;Uqc?jGg7^>x#0krb_!;SheiLK@GUNgIWnk0(HoN;G@a(b#fP@GIAq=bsr)Bui;14L`+th7+5~Ok#y#+^{SWQ+s7AP$xBTad= zLj$D!GEx8u{bZW$@op^6{0DfAr%{eNEN{MP<$N}z9!!FA@=Yb@$Le$u*L=3e4d_-b zMRn_cPu_lUUp>%LaC06lIh&3P6ODGa%sfmDHYHE!}h(Nj1u?_?MBXO8e(J!dEpZy8$Kl&`Db9HFL#aNrR5ny?~k1lm`Ge^LdC)}mY z5RkuG8lf>MErAK+F7k<1;!$_o8FLY!nQv(I8%^-Cz{hm9XH4IE73bp<%f?q8c^_ef7F-wLa#bF_~H z#0Zt=q9<`|=02QQ{E<{~!TK1?9pxM#@)W`_QkT=xs&8 zx3SixbZaW6oLPKny!J>ums46Z|JNgXCnLQ;4@JRSseh|y3S;3knm0q+@CYUsAHj6} zQ7kr(7+}9<=dWYFvw#ofk$+m%Nsybfhe3^ ztrT@fvip?WN6rrt@Zjb2O6z{h2%kjKdI8b#hk&^Uk?%fEKLR#MObWc1phO^6BP1Gj zS7VQSjdGA*Ha|D()o~0^yjm=o@kL+JrFTs@>c$t_MUz?8tvS{iG#litXg=6LI*wc8zjt4lE8 zQKsgp_bS9UyNc^@@x>S8@q;ho{=JXlmBxha-dq|ip`5Fjk(r(}Ym(LUmeQO#k&;iR z^tmojXHUC(X$t`a)553f{FKb^6i?>Z>!O}(;l=K8{P2}W@fT0ti3g8AhuN?}zPM2* zEn(=z8o{7#M?I~h20|Lhb|YuDTqQ2S>+Zy+fnUb9(GQ~AG1KEj2TB%!TRCr8P>;q z>nY}^u0+r&J~@4h?`Gdon)y$um6!fllKD()-efoVR!Q3g!8NqI^H``Ir#_y6U($k& zkZyplv92&)OPgM|I9x4or2LUAExNvr6RDD!EiNZJz-_LkfdP&BDcuR?nW_U=NC;x* z@4|_Nd(h}T$1rvBKg6ct8_;GMPu3pg=NIgqSJTRmo<_E7G;J82`KzOvR0rs1NBuB; zHk!${oA*XAl7AmIvR-Hnnr%A5D9`x0b4aTS&{SvaKtfhLFR7z>^hLC2lo!MlR(3nM z(KdphV6#@lDz6GnCOcB=)_ulB*QmvK6EwzM7KlCPUo|@3)fZ+7{1W81Zf7D2(AJt> z;Cd341ejGy_nuuu*=NreN^8%l0LlrM9A+qp9zy---=H=1w+N$sw2^BJ)TOb^y!ma0 zZNgVC6#-fxVTq0jLC+Rb4zcoTi&#}~#mQIYvKpK5#Q3fME`S7~QCy@V(QY{ePXt~q zP4&PYREItXf9#im($(Z=kupjnpH2isY{20LqgHvVp*nGD`QZ0*tQYVK z{Gx|OyMx}s43#e%^-vXFSR|i9Q+#WNT=B5{RGbvt%&E3Iwme&zvTn3qMm+URv=)Di zvNwl-ZA9z;%)-dZ^{tYyB&nv|b;$xqp_0v431r9AaZ)WJ(rN3hUq+7|gb^rjc~G#Q9GM^Ndl z$vD1-#LrVh>ofW$Xv6eSZuM|sbsRe{xDbz>co{D*9>bCL6i%Kzfyv2}OlE|!5sjtE z2$$5CV{B6BGLo`%q_^@~3CyxL^w9lV3hGD+GY<-S)4_6@vKHZ3G=WEsJ&ik_xd-3b z|1h5C@A+~Eoj|#uy`hn_p8JB*9MqIYt(#}=k`fC3MpP>m){8dkjY;|oWa}N)2?IeIMP$-*dD^2D zj1!pjXhTic9w#pdEErDKiSlgm(#bB?nkq;7ZtD2orUicXm9d9mY##a$7Mn36(20IpgQfA+0Jvvwj+K zpv~48u=3<)51~GD5+&Q&Mqo^Zq$yG~?NrkkPKzt`rU@BU8ml;pEv*!EVyfCp%o|l| z`=>B$WCd0#FKS}3R>vR>ZLHf&gS*VeA%NzfpPUJem8E3&bmu8$f<$CryNXw_>JT-x(fbwQAc`BPmGK$EiLw*@+^%ovk|vDF6=)83^biwO|hy#S3Q zKr2_YT_IbV*2q^R3^XaA%bOFj{{K)tw9 zT5M}Q3eD2xC~UZm)ovTbHQOM0sScR6#L_;UTj~R}wM%Pz1dT$m-{=!}ysuY5qLD z3v#-rv&}>l#)9*YWV#nwT-rsl!I(9b@lbRe4<2{|-+KDTxbwiHcy{g(W^#3O3xrh+ zFP-D_UFm57EzOJ)1Etdg8g3dzQ-{16&;)SO=rQfTAaP3@^m$vmMcov3bJ(6=hYwwP z5$d%^5z+3+c?1Fia~c64pVT`TdR2Ixt+-(QZ(u{^HdMSFj9>q>7E3%(sgcrx$?U1j zrpm5oB;yB3LDEQEEuco@Z|7utR#2&EuZ1!ibpoYio;H#uY_@5KG?;F!(I<@V7O`&N zdcIx8H0?J88u?+tEJbFTlD7h9bmW^=#+A;1oYL>E%whVj-SL*zcdteHd6EF=AZnc# zSt|~)o-UBLvavF9HlT}3Hh{WW<+4nt-!sSW$na+Uu{B?oF4c97R%z^0Yupz3_eIR& zCpbFyJsh3+5y989XvGt((*lr;oApVfXFkhp!@zsdjyssCKf-5cF@k1kXBvbrw4Z|R zjeqo4U1z%eXd~8_Zy^}GiDk5v&s>`po$+($kX99-X%{`Qs7s+0vS9pp3Y`;2k(WWv zLN-HOLz7zYs3Auoc=}p#uyHO|OjQ;+RbpQ0GrnLL{rW0%x5LMR2o0a8^g9dNIP`+mH-? z0FBBuSPU-0LT@{T=|u!j7o!#ILBqcQP46PKdi0AfWL)b|%)7N#Is{Ox6+YIPAodyY z-uP`loHMDNItoWEP>rat+Kj6gT#12^Pa?nW7NEG3k+IRUY^+0uZ%9y!^I;O9Q*RCl}TBZ0W)u_yT|{OTBb zj6WiHL}?Tq{%#IzLT8vDVRR=t>n=jF@ls&R6$p1+g~G0D;BC9YuC3ACh=#YIuzoAz zpro2*>0dLX>B0iVo1i=XMBku;*eUMFWn5m#Z<|ove*A`RzbS|k6(AF-k{V9(8Pp8{# zhJa+M`rk{Gn}v}o_8mEh>DGdEMAAlOK*=~~!@O1U1?;pRIssT$U5b>arLK=FhPPwG z)-8B+pSED1p(53UxforF-sz-+V+3t49eN4-Cl2Bm0Zh9XxtS_Vhvrh~*chtnWm1Op z9S!%Hoh85YUP?iLlQvm9*Fl}2ti^B5^6uIC%eZUr{rLV9_u{^NkKx(H!#J8-KrP=z zCnOLt<+lXT%$B2#81P@m=4I>ZY&JbAVSMlgzE{T7!lNu_ z?P4h2iC>IM0En@<0gmj$?whAL*{yc({^`Gkr&F5rJ@|91OD8Bt_oLB0gj)L*bO;wvur<_`pNq36P&5@fR>2>ssLJ-cHwkQBWR0^UXh74_87VqTgVJK6i^MP%P8ruT zk>0Vu%XHdLmlyfSxy9ZtKKX0pFeBZ`DLv+~O#Cg}EIp*Rq~N6(i@jq==BU_@evQ`d z{TQYY^tHojqeV854=l?#%0?}fepwkxAf2_hjMt(xFXqzpYPzh>w9~<$+JUPZpxqrt zp>iq04WA}J`#ic{g>5y^9wE+9Si#0V_38Dfze&j2r8T`tNG4x-jVP})4kO7ZO`@rU z8V#7qwegLY?!v!&@atG8HYo}t8k;meZOZstr!dJQp`K2P33X800NRFn0l&WEM(n!! zO8jfuPDkdcx61@*8fl^)Z6%sC7@|VJ6?77s0eP%1k6_EtI4&IDfjygcWBcGH?Ky}F zb(yw^kZG)pWv0E;G6v=BzDu1}C$L#$u8%h-@$BKf=8i8;Vy06=gLYjMXa`1hlDoGw ziWn2r*z6WH~Xbb z1N+92%kaA&xe+H${4wgy=MfiXX*)0v(&wE4l>J@UJorg$9lV8k+sH3fmfT;L9oZVi z#T))-6vK_=>%V5DI!OL$dZ2VRl_YhrrX{+P;fFQ2VEIwnb+wP!_m{%x>WnNsakn(U zG7zVCd$N-v9T+i$QaFxkafi8bu$5`qM7NIo8)WDT_H&f!P4jjN(J#yMY2-koaDdV%-m(7iTdL)LZw$TWc3iyWQ`lVj81p@7;d0u| zGh+V87GuwOM5_zX$T0P#2rm~Sf`()Uc=!is-TigmPm)Q~C>1F3x?OZwNMTtcAzIYP zf|Ok-<}anzYMgo5FMFgPWVCtn5C2DO=xX3a1)#ybK*O-T;WCWA|BLW1eIFKys>}SI znyR+ybL>#>hPq^!7OUU%qb2E{*smp0wN;r~0}$!zlHtgH>rWcsRqS3Fm?S7KQm+-i zrd}hb3gqa+pFyI=L11?L8Pp#80cv|6L8(han+CSHCD)_Cl6|fD@V=%-11iWg*WQf4yf~$$ez6TusD*XsTR8t9-lSB(vHA2aFa}=6Pldtbsg4trC*DGXl>Y4Fqdr?M()v_^%i^F`EKrwnTsNjA8J(rygA?~BM?Ge7|QxBMto zDuIXfpy?Z8WJCc-7gO@b0--D;rACJsYO$?BAqfbdbtbn3V^{t|CRHPX1bRC3IWFiG zlk-~ttEme>gKw!mNl5T{#IO<+z5}CHj!O3mN@oeAqzIKxIi-Q=w^Zq`w(9MOTd9xY zl4Ci#2H;3nI@`37SDgiC^_O)bw|Ey?uly<6tw)jf4znGy2B&pA@nduXoBYXgU>2mIx?-IItU|G0M$_9vHr$HgOMaaxzuc0i z)})RU%ZOZ``t&BK575>wt!02F5oxxYM4YdQTdu24PC8v99op)Cl7GMQlmCKy_dS9* zPXm?#nv$1iK>-E0%mD$kwmLJZtG6^t`1^Z4g5e8x;P-#@bxbr)qF2_6H|jBpU7g*j zO|%LLAyAh9hcdb#ebbB)c5)cX4-l}8Vze}bvFb3^4US@@GK7J071dIOHbQ_dbz-C4 z#A3aM+4>x&7iKZJIE&flJPuDEL(5~n%H&4LLnCPu6t>|NsOzaCG~#ES>EuUDoe+D3 zEVO0BJAtq~^-V|vAR?G+(=~KxFcmoW&kPtOATt-S+c0TSAA3F9v}eSCPs z)%b_ET#Mt!{s^t^J|u+&=qNQ`BUZ_Uc4+k0>SxJ`-Hcg!lw_TaOa;>*^<-=FO&?pS zzD1G-OKZfk;lB#NN~4s?bY=FsdNBdC1<2WP*BM)zfcv>D_J1f%s5whes= z<0E_U#DV`Cy}~QB2{M2tTTjabG^5NxXh*VhQ{}0A8D-DJf2A)?C+#K;ddN-_Xw+z= z(x=MYlP$-11QfLv4$&~}g^ef#n^DSdM&2K#=|GU?6XMW@kh$p581K;z(Rp*t_AJY# zhHkQePPD+fGf&r`J=H=to}<0lMxOOkM+kKJsV>V?ZAI%j4LE5UB5jRaQZ;~f&DMW_ zg;onM5PbLY$KEnP6ZliUb=-vxCl`+jw0)C^b#=CiUF$!G3&%gsc5x9y35_)AhWUNj zEqwLN(VjC}Re;8(Cf2d4xVg^g)__Bgp?mMw(Kz-bD$yiuKQhb?Eewg%Xo#~gwYXAS zb-z{K$=vRE1#2*6Rv4Y_l|)U<6*i;0?L#PD{y~(kx{;NTh1214E%x;bEHL6~R-{0+ zQIvgHXq>q?wa(~=8tRIMPA_He)#;V*nVzIC7>PU70`?IJFU{pm-=epM{GsjWk3Wy* zlix?}#rsjIA4S=w6ELrOhk@m6s;2TliPVh*I@H6Xc-{B2-?gpRVC0wn9tL}V15oHG z9(}v#(-@Z^V`MpkyGU`dl?9qQryeV&F-kNdIt;IR4N4n62#kDya_<5Pf# z{$g7Aw&jN+!97nKn=Y>BgWqkPBv^bFvp@Y2ng^c3aJ+zGqN%Vn{0Yw5j37?{nCtST zfZ_9sm1*iSjd2MxrHkNS``=;csu;DC{{~4*I}~bqgSrQpC--62EvCVmfbNw$lwsZ{%V=8z*11HqGTnXF#jLI{>9pNTIupK#7zu)e$*Yuk5Rq zj`ZH$@;!yMSm`u1MWlPx4FM?KD}Kep`1K8XrP)~O1rq-8)a}@taG%v^=HhqId*!QW zbzUSJrx0phj1o_Qp7=Bbs6}&H|JUmf^9~@VbM0*RDZXz9n+tdmh>|CX0H~C|l!x+e zy?tT?zp2qz{_OZ0P|IC~kzK!q+{pWw`prvRNVDNwpZfGBs1MNAF0EyNCUahrJV)T8 z9fVsHh??4{Y1*1_(W3z?8CYk?r*H_r|Cj$3hZc^ZJJ_S%kg;viyfu;lC*|@oZZ*Tm z$BxzjzI@du5pNpBzr6pOnC?s>$!ofp*86DmN@HT`yrgc|<{M0#j8*yBF3ki-rrH>{ zMpJy+KDJIyijH}aIjC6lQ=}ynvFsj3q)y9nrAXb;gm&N7X30JQmaK@F2+5{$GES*b zC0!$pI>Suomud7Y&u>dj%eBeO7Tu!y!1>MqJqoldbR>)bT8HU!BWV1tzyzICS+SAB zCw9CKfByql;n=Z%jaKUblCT9Y8Ad+02|GqVkImH&Gq*#GOP!+~rkx4UW)b`)XJug> zikZ(_B`HHOQSs7Q6#6X^@SvaW^q7EM_KefjW&YaFdT|$yP2WRc`y7G-pEGTntG|iO zBbVZ*2fmU5G#yM$n@u{^02<4XdfKho7RQwaxr~$ueV5lXjC)R}>3&+1$lG4RxYXfF zXXmfkE6%P^*u?6GmL({R^t)xkK%I_8P+hSpfr`uOgn*yw9_=c|lk?qLK$(g@TTGA7 z%*Iw?vFpJ$y?hqBs>M$puut%IZqu6tW>_11rg#byW3P5fK3XgHpx@x!2rX^2C|pVD{?hyl}Jrrv{ZLkVX<*1aLE4i3^)#KYMnCg~;dhVK_ePo&a8c5RLo4fyHMYK(R(6TS77rkYj8V zY8sg`r|A`u-f5xWB`5_sl*1ga6m)DvMdr6a0UGM82mv2aP-R>M(Sd}68Y9a@=XZ4T zw7FTWV>T|(X!i+of*N_XnRfq&P#V7tSa&V`H!=Mso6_zCp`5^(jCwlju@J~`{ICG( z?P2-kv__HXwh^KH24Kha7`gs42=?5F32z83p8!KBs?|n;4a#~wC`5W}_%XkkKt~Bs zu(0ex0*$;zdwiB?kH8KK@R?qpg331`5)+{4s?AgggBe~uLsohw(44=gv{Cp5m_ea& z51Pln4ov=p!H$quE$dC~kdF!_A?zn5*10OvRv}NBCgwS@3NO&>dN;)v3EqVDvBxsC z-l&u(<|w?hTcxivO&GC9LE_3(0$N)MR~f2e`6XPoIwxF8yoxAf9VA%qQ1E$}XBv+( z`Fn|XA3=TgSw_Cd_n9xnYX*Swtncd^8Xe^~Y{X1srL0#5$tkajvr8RNM6EN5V)asjvpvjo(cUmpus-#vPkmY=BpEN+C;3T@V^i`Z?=-p~ zp)TF7>4FzvBR>EBk6}}B9o3!F3};0qdns#$vJ|@j6~UHvjcm0ewD?%-?j>y{Pjj@F zLWUKvi8~$YH0r^EmLJe^psr~L)C;8;(Ev5hV1j0)i^XCC^Myssh4Yxr&p8*)+3)%M zqCIbx+vp7NDhpx^)RNXE`3e?rDZ5> zhSi2{q9UU$QN7qkAq=ngoPM+{*}Y=YG)Q|+Po0})X1MsG4#MsLs{UozJ^mSNtlmmH zax)d7rscUb*pAICBKu_O97lf^N;R3KFN;a_Kp@q9%g#!(RLf?n@S}NJ0T*KP;774_ z>^4+_i_xiT)QWbEY#A3BU)0NrOFW~$z?1-{?oHo1Xlc1H+bVTtd6J=Kvl#bM$B<@2 z3yd=^vq6?S@*~!pZfvU<$z0k;r3Uf?i^vboARL^4Up5LjlbhE+eX#1!$+tP125vW&Q1@YzMEW@)Q zfk&+`)GR35G=>p%Xa*K@7h%u#j}x3-$WYo4k9C%O&_1Hs@lxj_rL}Bzh(%x@q-}3S zLuq3hH+VZPgFn8Trh6H^0-2{Clm-i(;cPh8wbHX7S3par`3p?(%LT84;b@As>Txs| zrhsW0+mi=r_|Kw9fFyjVSJWH=RwM_Z6c>Fw8rlRc<~%kojY{Oy0F^UUEEnEYH0PV$ zuXLi*{mf}cLpI}x0!2v1vp>Mx!{0z_|4&ejXHYHBh^El)uz|a| zwycpIbTi5uKLHHiz<}Ese8{FkO1_x=uQ&}HDvioBM91#L%<=mXw-503n!V}Tl;UFy zO1KGk0W=Cr)g>xE6XHxv;uCDK%o75?guD91s*dQQ~~X?o33JCg3#2~!?!*m4zadDjOpRvk&7zIDo^tiEBo#Fi~kPvnbe zc4IVcRtz67DcW&S+wkY<0@?v#F^^UfVX@spllorM46Rd;IzO=kl3UdKZIq}F%hZb% zUWX{(M}iombOY3p@-H$>Uiy;ZwKiS4Frw|yrY)g$Z%UU`vFv}1ly#}Z1%#kM3%ZM_wTpTsWpSo&9Pe4K-O-M@{o`}o{&s8u| z*^SL3w_<(a(~M`U?L{Xu#S&z3N>j4r1PrKH8JqF;>`8GdZjm~jsXI+SrwJC>OdWlf zwo^|dH0t!^|2ROtw;LMl~dn=+G!=5K`YW1rfn?hvn7j(gu$N zz!g}wfY!kY*zu}Pa5)`I6!GiibHaEvdMl@AIggellMyq&zBh=#8)iC6EHlQ(dZiIP zTP~qA8u-jx$FR$t_;!}%L;fg_I%hA@QWn}ngVkYd7`h%~!HxVq$TTQ!eM7ZC-;@n= zeo|J;R)@%!%uesfu}*jWDthA=V)T-0(Jrq;!;n5%#>VfnmGvla9IQJ#at5Y8N~eu6 ztk&pI;u#Et6jH?;>MuWw)&oBTUV0Mw`ZP*Rq&6@p5Q2nsZe3Jjf=F|xJ4}w!?l220 zC~Le-c#&HH#>&t1%efJu)LEmElYlsrQ%{3>yo!j~Xf!e+L8G+d=o0{eS>ygcL-FWC z7)>;-QESB76qbTz1TL0M#!tbOeKV)+d6O=|u0R_NcOrn04Ljr;0%)4b7Uq0DAD{s4 zvO3Sxbtv1EBE>;|sdvXl&LkMMo6`*1{wVT;x1uC)HgpSX(xrU1iEow+CMcJVbf?B3 za?Q_?6OnQfF%p{=R*%`pBw{pb*z_sfwqAk38$OPKJ=dXL+{92-SAkR}Oj?&h-+JWe zC8!|arqRQ0yg&w0Au)_iYwR`%PBo=K3aU*fKqjz8P$m$@s~g43a**X;0+0YMoKl%O&K`MXs7E$2ZD4-S(*of)! zXU!=Bu|+~pLN+DI=WR!;BM=$*#Zrb%8tV0>aRu083jn#IJ&$U5P2(QbqbRk_{Yp|&B z!!B(P8pb}IXSyMze-V{V3FU^S{rTt)2B<|fgsldO1Zf2d;=t_Z$S$lzwykr;ajBV~iM&)}BQ%?=`JaBOZo|T;8N!v-fqi(LA5}i-1WZ zBbw%EVN<7o8cEB5o2ENTC#H{#bnkZG)^mbADoXkJj4y9GSGrVt7B~P_WjjqKSy%TIcH z#V5r}*$EYFWtx8p+lN1ga(n~21gf$(_1rBRAlRWE*76*IaO;FM<5{HmGe+5MN=x74DnB^YZCUWX9X5Azp^I4b7?q&hn3^rYr4*MMI z0Sj42Hi*}{m$lPlB~V>bT~Jsn2iXj?#k9`fB~{>4c7W2Fre87YxF@y~+0l{mC9oz? zs;QQ;J+wXd`;HZ76gv$ELv#5fER+nAJfn zdqpM2c$wFpY%e9@Jf&6MW?walj{ga~%_bGI^6F(M`)CpzHD->XKmZk5O=ZCmpa~6& zi~9RkNj+Zrrx6aT6xy}IM!^bbue$)f3*V3K;TO?*_I@l*9Y?-B$12o-Us0t{SdEnB zDM;8*6a}3bs4EhqTUCFD#I08H2YoXEo;f~eZY-n|^qCX!%E)ExY8qt_5g4KlEF2_o z{0Zuhejm-39zt>ch>ZlPhekp*W_UHIkl$Nc-DT2Lw@Pj5bid-aH8S4mJ{sMP!i66o zZg~v3HUS3@b~>H#wZCr5t;G{+!vd^dAq zq3WFjNA9r%z3R134d)4Tq;pd)^`4#))XJ$GX@Il~TM!j5$LRJ? zF_9NC;c9bwU2%vhjG4~7==#*BH$&(1Hv1FbdLDOd--3U7eF1;+oetjp$x)k(?C2Q& z;+i}0Z~o{7e3$O!(iU8I4co+P`ZK<--j9FwTaTIlcmHS_g%5AXuF=&0pB%(AX7RY5 zJsP-gX;kgjd+;Y|T(v!y;PPD-)p~yXdq4%Pdg&I$h?TJAJIZ@kUts zW8)*3?oOez*up@eio8#-RT@A!teC3?C36E|k=FvMVF4Ao5`k5*Foe(_#ArC=;_8*L zacCX(Ty`1uPaMF}SN2(_t8Y4ka+=CAk+E#{k^mc1BymfiC9$itxqrG#4Q}4qw0q`7 zOB!?}i>_`ez5t&KCt+>I?J566`sn8WT3w-e~x#@w!_{$m>X z9c9}-U?0&BS58^JPtU>GljVj^A5DMKxph;S|EbS3dX&@Q&B-7^#5e{ER}+Pfk^hre zH`K&L{Y7+QZ7M>3_$mwWMUh%b@K(Pg=VX}ik<--ro<^`#X1q6@?80d#kf~{g$U-l> zGyGFnEAOn#9awWuMGRo}62G51v!g8T>>r8tK+o2zD~!G+yMeZmM$9aPY&X3{yDHLA z1naSW93eL~*6H-G|No^2(c zY(+lagYn9Z*fR1VRC3$-#R9|eAM3hHOA10o%2LLZ^N47hn$^BK|} zHH8oUG+Kuq#Ox3L6vbDb#E7~|w0?@h&II9EBvWs6H43Mq(QuUFpmfNlXf0kqWpV45 zkbCGGs66^jG{ZdNa+Sbi3yK$B3+(wgx`W$5xoK%u@)f6CR*ov(%&B5$4<(E;%Dh*S z9%n(8f+~=D8Z;HLHG$~Zb6D8-FrrtU#=z_$+o=(~rhq>`sI7e^yz&%^Di^WZ~bzU-*BR&o+EU8Mg^I1fI3HiA-pyH_O|N>d=kw z$3D!$dq4R(Vtf&Q!~`Wne)7$KyCDqWxf%ah> zm_Cj=^-e>bocSJFv~BVl35p{FB?2u@)>4{MD9Xv8(1=8y@>amd%*%kluQY}`pScJ3 zJ@F7av`yL}Z2`@6&?uDj17)j6*=#c#R*}?Mr_N3QpFm*0*;mSk*;$qZYFOSlU2EAQ zIo)D+ylS*Z?@HZEzo_F-vtr}~6r*m8N*rQ@Anmtr{uSK5?OiBN*DyZ3i+XH5V_Dt2 zo;^8TYa3;#jA*X3x^*;@mryRAz@vx$E9&u!h=Y?fhBT_k;5n_SVp!G%*;P*Gt|ZyB zDT$YM!wMsi#$U!6fss|N5AORe4N9Zyq^DzAWDvN+q!YxnLA-b);pJ9bzV+j*<%4WB z%s=_$Qmi<{w=6y}MNY9UhtP5B24WdD7mv`bLnYjavVk*gTE`Y7hFf~{hDhmhaivk6 zSCpn~l}HSr(}cV{8KgaSw9ZVa=y^pHw_b|Ti{6XHa14>AwuNQdjIP#u`S*g@Bb^zeE$y-KlD}P4&F=P z@)Gi$6EyPYQPhSCEM%ps%d*z!u$6gM?);`U>rjKr(TJDelHgI*kQ39bE->Tt)yK?H2)NuC%%r>;r|=G6Tc7Czs~oc zX3TXuDK3Fk2}$O*SE7&BrVW~ln7+uSh6b!zn$_N+YoVicWV{BII>l5S1vYX<;H&zV@L9*(jPl^M2nVlA^GCjC z72kL*AC`?3Y@hn{HlVu>;EqRjV~>HO&Diq=;NAz1*`tj1-Zz1X^nN9s$^Xd*_hZlR z?n=QIu;Dj%;ig9>@a!9`Z9Dy&eLA;PjZ3%^d+^cmn{avV0+f$aUmT+BJJCk&WDB{8 zCUPgJdr$EGIA!Q@>hKe^S0*SMkJpf&oP$S~OwXb@GmW{alXznP<2ZccsIB$tn4`p& zqkOfc2?90g_g9moTQyRqtF0F!$-WWrayF2r(5F}XojU5&fcBE+C`r5W7xk+)$nsI3 zI`4JrDDo!qo2VxZ1my~~nwdcxL^@@Skk&`_sE4(rA{R8QoC;wDgT*U&cOikw zChF=6Rk7B_*9l(g3{QJg05=G6HwdqjTc7p>|Dn!aRBNo#zBuI)#GzsV{VUZ~NAqfeoJ?>Erc`yfX6JJ2|r zc1zTd&e@RG5RtUIUpp+=4no2lL)s1R;#&}3`>R;^@xQ~^f$y;1Gps;?hWBV_)`}x& z6^9WHZ$M@1MF@6WMoqa3D6glnU#8JnW<%1DZCdaYGzPLnLM*2X4lzJRt!?9rcjq0t!HZGS9ZE)xurd@ll4nK9w7^ zd`ciX5uIIEkVhC5u|W`gNr-CBdG3l^;obBbh)@1oJd_t)L#cjNLmEThuLV6o~yLA zL5qzjDh}pL-_u@`71fFPmk>YyASNHX3)RWJsIqbQay3&BUT+X{7>Bp(0~o&jO2jkw zp*H^@D&YZB6ym%k=5(?irj`D@UrN7HrN*p#P1B^abc@I2p`DE1Wj!t+^41|PT!x_X zE>@FwAuOrRY~i~CL8>c)qmKWIHRGCumV}1e>_eQ0**e4{-Al-d=}drj9c>;%(%Oek z<2fYFeFTXwvtGY`Dv*Gi7}sZXy*=j#ZXM#BC*uEX#Dv(3)qv=K0oh54H9cE5qY z8x6bT5qrFX*5lKE`2pOjjmTa#f+kw=-nCaOkG7pB^iCW>Gr=AusD*7DSUiUBJaHEu zI`B9asjIvS^=hKCE!BZ1VCBGxrWwjbPYW*}mswT)@(3L*6&Aq<4nk4&A zc7*H@)kqQ3u6!`>IojKreyJlGw2?@ssp*XC>4ua8_b$U~R*~hy;*n!s2tu`aitGoS z;bzA?_&S#1B8=s4#^w!|(%#!ZTaN%fQ5f-@Zi#)2$M_+adCEd@{5oG~RRNk<5?Xyy zWfAaT!}PQ?G7wCIuU!_SlLRS`RS9}C>cmF4h9J-qc;5P)EwDydZLvy3!AY{YIQy|jBEDWMFwhiU+9l%y< z$&pRKz&i7XZ2`~5CWBa`6n2&v<5SHLB9w~>EOcOUthHs6z~o`zpEWx_)Z>-35)Z>5n9(;6q8ortHfS`2L_Jafd?(%3A9qSCAni5RrQIP&6Y zoA0)dAb$A)%s%{G_(z{bDXgQwz`0I<8Gjh9T~}lCN8d&K`y`qZKf-9RpOHx*GGWDNQI2m)SF*hoI= z3^na+M8T`kL8~{)ECrbXUX`utj7Gp%U!qxNehN|h7+Nj5#!=q0twb~Aobs)s6to!( z`CH-J?xaw_OC)=^Ct<==Gne}NPu>PY#>033Iuim(u|>@__#} z9;$VNw#$;07x^z#r|Gt;e{54-wvld5qkvanX#69<_-7dALdM4|@NF&i*8FdcBD(sb zdG;DZ&(3-4Q=i_L&QE~mrZnE0{#r>lt(fMRkpZ#;uLe*n{ZH`zj8h*oIwL^KCyI|r_Y)y7a zHAFHcM9Q+(*&AP2UQ(?QWyz6+J8^9O+o&hcBMy(6O%V%Zur^SsrZ32P)623KWFW~Y zVs)UZ{zR^zT;_TpM4DFX6Lvisa!)l6`jBbtAFrX)p6w&yN zh|FoYHWp|PPoR1HAZDL`0`t#5j>f)c(0b(sG>_~>q^E6bAlINFJaZKB(O<9P0o*RcJa}SH+6V z^k~N=>!Gil3+09l2-C85frkv z#jWzgu==`lBK}no8Bw^ff+$p4YF1yY&ge1A(qm&c!J~N{VF}*GF_Z~9>+_4~bjTZm zjWDMJ$3rX*lrgev44r%(y~P74CYng3G)ibG#xprlc6|*>Te|^YD+f1Fuezg!+4(?c z%|$4&JcITjB+Ucpwhkb!y^LgGACfr&MRN!2-dkk7(Gdy@a{JJm-%J0!h-Y~{`7Gj- zPosYFAuLWmi00x$NZL;kAMGO`n?T85MA7Q0rihSp1We+f0Y@@UJxtmKDe^WVs9r*# zNMXtE+76d|Pe9*B%+g*iZKJOa00Uyi66MmBtEM?xrBj z{RiN0xQW3pCPvJ=z6vXIewSpMz%XsD9;h=xalZk-`_!kD&c{tcCcgR<{^Y@p`0Xb? zh`;-#OYpJOZJv1ncifw9;E{$E<@QhGUVj|Fdef=kYo)*L@Aygso4>RH8`I~f(98@T z{@M(x>Bb?aQUMFkynyfnIaZrRT)*Yr__b?4 zjrUd^IJ1rAoLaJQYll+X%@~o|HpVRXOq;$96h~01()Ox#&}ugk1O=LanpwlL*LkGY zi7OqP0$-8cWWRMypGeo5la02TwL;%#g*7`uX_bYvoCaGbnbXLir=|RebTpFcIPL5> zQJ$Ft+L(5Roa&TD+h|Afmf2B9v0Gl^HY*!MwQv!}2X4W}p$}p>zlYU=wqY(0p9~g{ zMOqD{9&8ox_ zpTPXx-^Aq8_hT%X#ZY&Oby$V`=E*)`4V_NXOIz$yxV1GpRNjoC_uLF@*opZ&{}Mwd zo?%&0@G(6dFQkA_Ped0ng{sCE3Skj>0s={wPFn^rb3%bC*wG>2jOZkIY^oP4O*f`N z%Sxc$0JRSrNz(|7hI9Fr4vy9#(Ro%}ZTGHqLgs9Qft7~Bxku=4ywaiAQChhbnZTos zS`;X#)AJ+PunoMB%My8R1Wo*6c*P+>$S}DeWZLK@fW>_I{GET#`+)b|g!;k1LZx{h z+F=#*5gR~p4@NiK0)On26d)TdJvz*g9AK;ib_@*dZ$>R(pi0i#O+O=R1afY~OwM`h zpKA8XtYN2g(HH*4s*x0+Xxm=jR-bgd;%x#|2DdZ zUceT9w_Oe}vu!=LeCTr2^3#Y8ejmf#=NTCd7JlQ^pH{D zlfY#>5>T4guJc8*sgV+7jE?0a1@0L#Tj&;;_N{3U1uQNy}J2M32)ZaET=A3LPmAeCN(y6ZV+kp@2RlDjVRtj{hNT-aT zIorggfffMm743fz_ylRRkt6L|E>OlcqPm;N{?NMy@MOcw##HU*Z`!-I&Av)LsiJ`G z7#nyGwywK{R_PAy=(%P^;Nh5!@ZY^!ZdZr1rT5l$&Lxtt- z)5vzC6^fG{`opy_v zh7a-E7w~r8;Z`MTWk7(^mv&tO45k zJw2mi+E(shDE8Q-Oq=${h99v^ioiVI8xsiXG=P^M!HEZd0Pi4ynAd@~YdzN8d?mX1 z1=Nq+iD55WVej~A$u;RFTD~r2!v#x89Hju^Ln$8%Fa9cwdV!cafi0!fHi(H^e8hA~ z;mBVLdDHT=ca))&V%8afGxaKEAJ@7AMeh;#8E`WYEFLlcst+2z6fZTER*i;EbI>(~ z)J81%ibB{{_)J3EzYL{KzXA*}P5bXb%K+LO@=B}tZUU4w$JSIT5Ber!Q(Tr<))hr) z)`kQwudIWeWE~cw&G0H$VszUr!05YKBHJ0Zyj*zni35H&r>%i>QjjH)zr`CDcc1$7 zX6XFg#j#IsMDIj^CJ`vDCX2_G>{7&QgQgm#s!kmJ^B2C0AHDQ2UYvUcagq8>j&Eo- zL_~m=qy6HmLzem=ie!J#PG`< zrh%kS-RPb+?uzIyjUvNbd9Wbe1O@7wSPHKs{X-7aJJ_CEhg&arA3k%<$8mwT4Mm1G zy&`U2Q(G*6W+HU2FtTF3YT*IeW>R*#fdF z=t!Ej=n+xbf!2Ia0}f_0(+S-6X#6FuEvN)nVe8oK*gSYG>(jW^22Bz+AZJdt#To32 ztO!mk3UlWXt@1f&+RQ>DSaJ@oX#z&TvJud4umK0EY*|lzrGiQ^kKV!r3iF4^?v>np zV={hAN~w2=fXf6xF+@FAq0znt)or_3_HEQ(c^>6>5fKr*PTSANkr}SGmAQ>xwfXHX zg$ltJD_hSt=3ql$0HJ^NdZ;q$V8I@dy{ENwt$BM-BW5ycJqk>p25q3B4NIH*C(=QW zmNn&>e%6B^dz`O|F+GolErC?5p>9@A8yZ%lV{qFMiD|P@6*g%DONvZ+wMgY0+1L1e z=WC$|(DLv$Zv!@LN4x$s?f$($^#%-W{50}o1hBa+E{e2w&r;2N3N*0U@R7d5AOaWs zZ*j9-5R=*yO>2~Z7I|84q_UO9qL-#-e{yu zkk>$pWs0R@-(`Hfs?ONxBP&BsfQ*VPr-K#MgOn5CW9u=Yt9RXBVRx0S9d0RJnSTed zKZ0<8Ks!(7&m19}=P0x_xmY7xYKbZoz07!-N9DoNsR+}wS>2MbCGV|77=ODrid^X; z42|D_+{ktO&Nei34vAh~od|rpNLq{p}toEdq?1q^GrW8VQtn(rI?62Xd$uWNf!+ z>y>DObdhg{xM*lMK5@l|@yW|?$IjeFR5ThQogs3c$u3KO*9M6x%1Gv%Jt%T@!ue@* zD2Ed5or+CyEaq89x;29I7Ry}ce$n2Mj;F0E8_Q<*(7A)69iybWGdo6gZT0mmzir=7 z$%-i}E2TvsO)FlJeA+6Q@XPB=$g6nj8+$*S%GN;%~cffLl}C=Mq>rlFr?e*jUE9D zt~!hoYufD06q+=EBN}@WNqR@dc>+y|qhn0A%ORachGZDq5?g^E#pf4MCt~jwhfvo# zs=_b^wh??Z=TLiPFJqyx%};tgZNs5=RETMbEft;;$411onOL+2MLz~t1+whX&o(rX zLGH^)XTwm$X*m560JABGE;{#);$k?9o6ge+9tE^J$d3ZMr^ctDamAztr^uX>F>iip z{MK7x70^8Bm407oCRm9y8CU6IBk&3Syd8Uhjk|GdauR-d14cG|1m4iQ8FmBTE%Q|| zM(O8OPFoJqPdz;@)|3yTQ!jQEuk_D=OQtz^v1E~SaU4~8^_)KXrg-9{Oy+A>cet~r zS&Dpu0lsZ%BpMhUL4IHa^X(qy3EalEZ34;(+6x+0(>g=(MX_XjV;%&s(tmDFyt}%u z@inH|{z*v~PaQOMPI*!plPA{pB`A5L#7ebI~r9n&zv0GzIn~K;4uA8;RCPSX4o~JC0s>1*&5oL~h;tSm$>#IvpS2 zxy}uxOV)xla&g7w#p*C0$I^kWR1>YMN|rKy+kvy}`&k<82mtzO%BD{}Qqn=g(lzZaDka)&1ZQKp5nQ|J8vN>e zKZOr&zMf|H7_>pUn{ko3RC$8jfL= zl6?dyR9fkJpVu@?O)?-ryYMP>*6+Z4XFWzX-;QwjYKGTA%UVE`@<8tj9Pr+O z7x@@Gv8#Meck-8@FkxYizV3mGju)nE$=P4=ECr7l7+D!kuiJVlwD>zjo}gPH^>vJtuQ-IyilC=Uk6mlx1odmMRa`FhO9{<}h#0pitMrlb@BZnYPUTGJo@Flmr}W52S64;cZ+S08 zsPE9Nj9}?jZKcf{wz7DDSsaF6Ay_RHkhB_z{5so+>N?BVXZzAfskffhwL(`S>nRjN z3i^Qc!!ILXTl2M3sp>>9!1Qe7{beW)e+XFj5w^eG^cy0N2+o)Q!`1pj_PF#3n9-%_ zb2k=9zxvdtH${Dbwsz^AIf5oVK$q&1OoK@Bsq;*xv^s=`C|fVudI2i5OB#z!)E8US z(+orzocJDEab&Yia)ms93+_qw(_@L;4~bNhs?u5JvwDm9sxxJR z`P~=@-iytnw_xM&^%(HCGgq4NqlO~rub9LK#UP?jYOA_*h_c@q$zSP^6OU3`?mVGY zUW0a)q@9au)94-Fk6d$#yqssf)Ha;-7no8GWYh}`DLXcrCBs{VomK!DqB>QY0L~Q} z3#82O&pn3e=O0HYt|9C;5DK}=u#`|erGU>D%8DzyX5?U>%dh@2{g!`S=~&q{7dZ*b z6!xtA`4YO_F75R^f)9QMy(?}S!@VB`4=U6(Ds*RU)@$p0)+;FSiD*M?a?7b8FCS1s%~^$bXe? zfI>Tma^#`R++4c*V%&7u`*7{Z6$EBw474jW=@^4llhhUC(sB;dSIRB*v_PM}Xph$j zxy{l9C<+cpSQ*J~;f?85{U)(a^l~~|m3p_Q4aUS@-ZHaoyo9;tqnNDShxyjC)bB_6 znBmC(oF}`Dpq}5bkveT0Cp$;qT5Ym*W&E%X)YgU}s*v*Y8oY`RBs*kVwuXpd?Fb%P zvIOsTR-8r$yCW!h7hqlaHjGz4jKTa?!YDy^jZBMoS}LNhk39Wln}`P_Xim@x1 zpnLhPbg9jI9?>dKaXd@X2!%I*+{kudU<;Zo!$yM@GG>!cwB@_DV+c^omC%Xv^bU~M zR)y+<$_=81Ay(fCYEd5T$TuN@W&_^zNz_gpL0p?hK8h#+C{)zjU@f2DQ~@s)^7%q% zPLRM^q>&%;A;-qx4k}bW$OldRqp<6ePu*Ub&9=;jUgSLme31tAw#$&)b{+DiQHCRc zwcU5ryOYjMTgiu|&u10>TmUqES56Ho{WdSIcZz~M7qC$)Z&e1NUuPb*`NK$(1(Z}J zwAh-w(55XNHrynjGNUlC5i%+P$rRNQ_fMl~RColb`jTMqS|F`^>*iR-erRXywEaBu zP(eN!L$AG&JQ+o=HE!2jmkK~TV^Sz;1D9SjLLP19Z-#5HWB4NdO61ot!Tko*;!EKT z-$0!99yG!YXs{dz>j;@OJy;5OEvd{tttIM@psihcXO5srYfv82o)BzL&3N*Cf;SIAltZD_!!U}te9La!e$`F*l`B4q%gcLcUKjZn-jAWT&u2^R@ekfbT4H~$2LX=Pr zM^G+rMBZDEBr2QDYdatkup~KcK|}jk07rIg$~{*St4KCd#&6m=X0jz!e)1D=GeeBd z0;X3I!KCu+C4*$mdYW$+W3+S=wv7A|HVj;kioc7`ON>cNE|fQQ32O>40b8$xUP3;I zNm+cxH07J$Hk&x(v+h|AnoVW*>F?zi&kI@`BWSitP)M27s9|pJ<2d^4gYc(c!bolr zVO%47C7f6|G%y90!>CJRG(r^8c;s&{)QoR}82V{CqjuQ~k{0}^&Uzwv$BLmwK_Sxa z@Lt35WR2_ZIv?rObZJUnmz7OB@Z}9V>A8BY62!iG7ZUWS3_|t2d1cJAGSB477~XRw zMsN5uu;p4YNixwzZ4F!3)QQq-2886C_+0Hutwhq<^uqstduJb8)pe%(=bYn@;}5`m zB_<&hlaOMRG%-zP3QDgg=4N!`+*AsvS1ML2&Cp({V-o33XrxZK{Ubv=QVJcZg{d^R zq*5!GKPsp+QHV61IJeUl+B+Fw+62=;a1xT(2_H6K@UeZ)+4p(gwfFJCm_R6XZFqmM zy!Tmq?X~w_d+oK}XRo!_;wlfXmoqk?hVCQpW;9YXp@!%rmBV2Se)uz-?fV603?H)j z!}Lv}TFi!(E)r%GvHE69Z~r7x>|xer(G@aztNd(oa2;H_i=McO;6e}fALvJP!rsugSEWlNZBo7DyX*bw_B zAj9RUhLCWq97&@-RgJ|n=HpMA?!r9_7Gp_f5gLn)w8t2b*I!htkGkz?9v`cR^}?7- zZqvxlN=IFr+9ZR3~f`<*6HY{##Kv7 zC81@9c%yl05$BQkr!BQ(c~Xx__Q}B15NH}@t~d~$OeOT0;~4qf0i62H|3$8QALdn^ z=M6p2ZBpknO3g6Wlg{u`Yw99N!G%itYlJ|(wNNQyZ!hSyjcADRVg&`AY*MaQYfh_4 zm^|a1Q4|X_^*yh&QGC=PkA6%pbup;O58B*oN|W4h250K#BeU>6%vkp4s91C#pWucN zk%%*@GJT@cMl-LDo}7V}O1p{8*~uB$!MuWjoC=wQc<)hor?M^si77$MyP$2f9wqu#aU*=L|jU9Z>Xl73g|rTod%yB4RJ5! zlu;o_fzIoQ^nIGrM%Tqlwu#PpFSVO}L&;~Uz~`pYG(HW&f~^;xGPx?u7D?OZ@ackD&C;k# z*Wi;kH{nzB@5DXx7GrV!e9WZis9`-)DFZ$nhEC_e9rfEhRH^8El5`2k!qH#-n@T7- zL( z?I7JS*O^wapjZ5QscNyXuGhV`yusrugxy`WRC05~dl+8A3mvu0ao>(Om%LQ~4?#v}Ao9aKD zN9ia!g=95Zw}WU!=-d+MS^l$}QuxWoln`iY6;U5s`v6ckNdtJ~DA*3~!+ZbnugIP{ zglWU?qiXm>NbHJA6w>v~y0xg#z#kHByi98~P(ek*Gb7_$nN%59DZuTT!7QQ?J3<59 zhQu%Ct;^eFLl4nd%*RHa%wUA#vcLyStsYgyAzlZKaSi!TfjXF~L4Wm4sB8W+Okeij zfVoSVUeiORz;rOJ%5}x3-}cC=c|9Z&U4k94Y&mi0EOb|NWZk~F9^r}p?Ll)K$8oM66~QdOHLbZV2DX!EV|=>LviCyURE3!j;drvTWgGB^Whgn`e9Hjxi@joOzj&!{-@>4I z`ptZ#7XZw2AfoDm=Xd_@+>c- z(y|JbxTy(dklZQY!#8mBUw(*b14rnNni$Ds(m0=)fq_&#Do1jt=fhvf(-}kqZ(3n(SqcYLlQ5ro^Hm!12YDSMG?McyOm#Um zc^1@aL8R~;9Eotet`T!T{Sa#Ie*~C*JHyYgc+Kg-kw7EKb5W#7l~^r5I(MSG@c0vn z?ueYufaS~Rnb;(Us!&wGWNa=uW`(dlbDDona`R!}_^)v4{a+)Ke;f6glgNymW7;v4 z<`z>|1HIizYh!oPbP*7H@>zbKn zEICz(TQ^Z&W|Xc+E?>({pF!QN6lXL3jQhUYz1%}$8oNf zSe1N)C1!W*aF#RvJb$k7mwvMFS$HE;s!F{{*7 zcd0Jd{AvZ87t{=2wT5wfEW7Nt!iTz_HU{eh?XDx+H)ON}aznDO^o^Ka!YK}g)%h{} z2yLjL2sK>J%G9B${$|{J>tZZhumlTd&d01uePLF^+F36OWnJm2EEfI>*Xeu&aa!}H z@lRrx2Af3pNoXG52iQ=`AmCo7uo|76~Vj+_ePd1O4WH+@!sKGEylE(+fY++GjqmthN)*v`lhTh3GvZ7GV)qJOlK-fxch< z1m_R^9Mf1x)fI9W(MOY+nlOApK|>gXJ!~OVz-TCUMV(~wu*C@3LRqcccOodAV7wf~ z-f-}C>0?`cE2p5tBPzlpRM~H?57YS8+b9aph=Q${XJK7ghd#`}$gC#JShf6Qt726;QedQN89Dcq%9HT0_|;Ev zf-m+eQF*EF4VF&8Y)XKD>9U4ETHp@;M~Z~sBO3x z^^Fe$wSU5}8d^Vmpsl1;l1d;Ob~7k+O}#0d9LI5-t3k!8Y8}-`r4n^W^&5Ru=&EZY z4ec{Dus^^64xfFWV(lwi-TyxNqkasf)WwYDbS6zxC%k}@KpQFKS({NFv7Fa{ zBU;K14wD=QQ5XC|K`#qYPA|qQD=KXuHBFFR7@-8zU~Jr|?vyiAGjK~?Bbsk*!aWP_ z#L}6cz%8^p)OjtVewcaIFIF$JvS9opJTEo0@xNW8su1TRP^J*pawdC5$X=n)P41Jt zl%Pz^h&d>9f&7p){%@Ekj^g<79*VXT7^a=97q#k1lc}JMqi&EEKIAdIqzyLDFmILo z%2B?E55jeIjkJ5J^Ppeo5-Cxp7v9x0tN6Rf99*nLRjL7%>Dea8ZkpYU+R9r{le&eu zLZ8^wh4^?_n-7_>xj>r|0!^81lq740EFuBc5A+{H{x|=IlL!AFs{7tYO<@St_PrUm zM;elyG05Pyl1Mu<(`Zf(WrI>C2rXu%Rx`CeSZ13@bft1Sr*K~3+EXF3%6QJ_nTdJk zX$mzfWc5(+oYn196A^1&&48Io>vm-O8=TUFgiQf?PawKGDnfK#IvYE@eSa9ls?Jf}92Fu#siI%jI;5&EIu4vW zgrT0F;rz*8qB{B=3k!)ieaomyL|p>a635kao>_${!sw^UH)uM|QGuqBj(ATgVAHJ7 z(>4jDu942FMhSE|O`BSQ^CQz)m)?r$bN>X{n?6Hv*31N)$88xplfI0H|5S!2*~A_d zJ#T-EXU1_H=Q=|bU8w9vD=>Q-Ne`9nDRpX7i<;z?zW>VOG|u9~+$rqqeI4)g_u!rP z-$n1q<2W}wh=N|+Rmnw7nj*|CFVBF#)4aJ#r&J+;qF;?qN#o!8qzaRO-ZTYqbeAa)@>jUJ5cOIQg_Iy z8k!na>mQGBd*VDGTSpl~i6%RR_f>f%38N$~C39$1lPz4dv6jzZpwNrHGjHSc*>`Ym z=zZj)Qw(*Q`CtI43bm5bPNG99$9=S~unfouwbXr7ODyjzm-dYro$CKE`eX$PgEt{l zY(%ztF6y(5m|jbpqW%`tWo9!+)G(}ahh9BshTj_IHBF8bu&luAbb&Sn1e(k~HN*`-Tq zAkgBL>#-FKH)D z%*>i2$2_JquBNAr@;DW+LYxr}J?6Z6Eo_tWw>I%wHGVV04HY&0!dzbRpCUWs z5ny%;v(YD*cww-aA}fErmD6lzHW_At&qq?(CRs$zaU93_{g5f5dMYVXxzu-J8t_5$ zi|M86sC5vQa_YEtn#TAb*Uq!N?k}9h2Yn~--iZ(JLH`My95{`EkwFX$=P;Nb;$bBA z7(L7IU=UNP6&M%mj10^7Y(*97t7}o4sm83j8JIh57H*w$Gv>{{3A3vkY?zN~)-lsr zFVu3GoKd;mU}wm>GhIy4ZVUBt94Ih#I;Z^c2)8+;lf8_VttStqvw96lD8*hDhO1nc z$zt!{iG5e7fkT)xQqXYxXP84y(w)HI@Clq7rF^_@hld&v8$ z?+sHF;OQ!w(^a%Vv$oVAdo$~AM_u);JhKM6nLN7&?kQoWo2}OY>g1|CtT^dsHg`B@ zV)O4-6BhR!-MmL*bDknx753;n>!H&J~3XE=ZO*BCzi0V?tXsGxAE zq=Bks%EXCEBUzowC@fGIxxPuWmZ)IHlh9T$vFMtTTcRsYid{NAT=Y>Na4ieGXk}pa z@l}CcOpWLYF_Oms?TQt^}ETapo8?}DE zIE0}BU49tD`V7KiWPEWi8g+A&m+H+7ZKSFUOZ>`eRMYUTOV!!w=(rj&I@G<|FJ9Wv z_^MdBUa4LgdhMN@Z|MAH=Nm2}I3ZI@(KweTNh?ck7>h4IBn-og;1GbUG?M!4^yb^!QjBZU}Wgun6_ta&b(rN4r|8@s#AT;UwTzA z6;MH4R_mn(`EVp%6?je2Gz{nK`0UgH)$@?4zZ2Q|`%pRkvq0@_3}1^p3&}9~Xh`wU zVZ~C@TzHwGw{hybPJzegDEK>$<2b($DqVvM;wC|Us>sxPMCC14)#EV~ysF=l^@OBQ zrc2^XUSoze5zP7!LGTI33@-Vn(%-^`U6Y_;nFJSHnq|pjt3FPS6k-V^OX2m#6_BL2 z63Xn-#0hzZR19}A*+xlDL6j=0{|~VY6QUW7Lui@gg;9bXHP$z|Q=`Y!Qs19xIl5H? zt;xQWkIqZmXhWFL8wY#Q8#@hJ#?UU%rhq^TMak&90WRpcMsX$s^1Oyguh7j`p_PYb zw}MoEp2qZvBNS*|IQiylIQQNWRG&MJ`rj(G3sKi}FJ>-Y2Hd zefZ2oRT$RL`Dj9>_6}rceG=)}izwt5@Oiq8SD58~dJ|?7PcZLD&1yfUq@q*Y7QbGJ z=sxI9RE7JX^p$fQ$8oL-mEA0{S;7XhS7IzUmEbI56(Aul>yv6wsE3ilBxQB^Hj%6+ zMYWd6dO79$B$W2iG2*4rSP)v3-$myblZZ8I)uYq8>Tvsfz(P2eCP`2(byG`sBBngO zOPga)CA=83i!q*GOt?eIok}P>4CVRvp%>20Up@yl^r)ecsXT3jd6lp%-Ee`#;fTrgRaTGzhoLkQ4O`} z2%SFotwu3Ym(AskfKoyMwwI-)bo>kH(BN3*FB=u+sB~w*MI~CjN zwqP=jglT5IBS>3m3vBdn8K* zEBCXQ?3b2_*=;`BoH(JSOfPP{Aj}2OgB!xBg@0OCtm>N)Vs|c$43oH$)k{-xQ5wgT zZi0w2gT0&&K7r&%68M6RB`!XMe3A?{9wDxfTS*cuS=we96tcaOcxao+*}!FF{8PE% zm>L32H_%#u%I>hfyWx|hKamx$x9xc{m`2P0bF-V6e{J{sKbq4>`4aPqC!G5Fy- z$mC9=rZ|XfA&2T>E(kUav|*WuvDyfUii5vHgglszVJ2`0BjH4+bFuT`@hdd9l-A=N znb5Wr>f;^ydzVMce>_&9z<3!}mK%IEyQ!6j+fZON-QgO&oFB^SE~8 zan_RW1LuySc>WEXJFyq(VlSe? zIfgoi%2W;&ENDXKT1II1So?;b`Yuo-ZK+9r^uy>lj7ZkiqG|glCnhJ9uPCNXSnGbt zPdO~E+O)gH!F1rp@D7su&`Sfqq^nZM7ppOpug6ev8luYCsII>q*=dVWReujqy_oss zX6{nQJQFI*Ai9+2HD^iugxL!ZdM8+4ahVSC497GLDOY~_j^jAaRgx5{31bV^F~7@$ zTD?%_kp$&3_?G|uXhwG}?M%woiPlv?C4nzu%#kj7>8KqqxwB*G7wUfPoo7^2&G+vg zLFAFD^vvNQlxhfM35>FX##;z0t5&Ty_Zk}A%Gw~p%Xg! zqrcy}>%O`#?z%7US@UMrS?iox-#L4K_MSO2GcnxS6(5u;1GuTl>|O+kTAbFEw{$D}SV zfqf}>r}0nxGwigCg^==${(?<6v2i2GH6knUyoMWme{w*^Ob|j}IfD~Zb9|Rj`8U)wi^*iMH zH(6KG?(X-G++4}DVq;(H+L;E{D~9|S7ebCTd2^uN^6}lqjo%jwU|Go(TJ9P#Gw^Ga z6O;&tN<&;oHK>a5!7oK&%^+;@?Pp)cJZNg`G?)ie`Y7!+Q^)fqOPeY64`V;Qe-~KN z65r~)B3{iFD0pP&16%JwYV}tOjvV-}rBTcNmd7-{-*7dg4X0La1dRTe{`7i8!dVu!|Ce@9_`nuk3@ixUL99 zJTfm;9(nw=fY~$hm!H~_VYzd1K&MAU%LGS}z(sw_x%StI0gcXCK`l~;X|dTe3xI<% z#k7Zm*z5kBXhjW&YFJvrvI%t`FZE41+{B#?*7wl96zd1!pvwp0Gsgd(IRARd)7Eoh zHK2E|#QmiVL~{6hY_avR<%`!*Id(LuC-|YFMHVSe(BxKr)*>@iyIf3#Rt(uJ>f4f+ zd$JdUf&TsPRRbzUG^-*~dd2y+rRq*NQER)`QQ9rpz8gFnqATffD?I43OO75WLy{Sl zWPdt>55(V1dpEvC>o55$tG+6XgNO4WU8OQOCP%EH7De(mz^xELF`lGn(8^?H@s_!| zSBlfIj7r-U3qJHQ4zuSEwyAz%N z7SFE0Ls2+5SYUT|U7n99&rjHu~$U`W;p!>o%hZQrVUi*ud&xtX2$9|m4QcOU6D?~=&GCOp`LnDNXIL-fDS3z^yBh7&Yw?t z{@^Z8iWfBA0_ky}P9?3-4`4RFj6_jHMD@lTi|)u5OS*1aO=O1OMzKBB58+EXCku;_ z+q7G^K=$}s9vd1Z;&A|2RKS@=T2`c3J2D{~QNQRkRI6U6m)_+Zw{L zu|Qk99*(=6f0Kj9T%5~%H9zh8&os4kletujXI8Y9Q1Wiq_X!X37W$s->ilsoTy~ZX z*FYoI*ZWe$d*=`*`YS@VoaEX$_cV)S2o z7DunK*E&L$b_xVCyc;lEsJ5GEow^|5D@~%sp68Q{VOnGP$#> z%qSkdxeJ<{nXJ1b&Mc@5qZ^caxR1U?>U<1aW7YZR zy~UVbTb#JmdjGImk^Pg8Lno^L2o*N*O9@6pA#LI;C(&a8Bcq@WEpR+T;Fm_Yi%x%{ z(65Gy?|}>zCJc4BO}MT=0w?vrE%{CUGPh(W5sDc2KDFJ|E)RyW*#9=t1x8}2sgLLT z#MUQmbO;ocV6a1cj~3qc8M{CGwI(p^e$dsm^nXr$)m?<)lHwEjUTt5J`Tr!gic-GWlA0w8^adJ1UPnFjHK2W{>p832@ zI!bh~;BCI>9K-I4OCVJ)qGqR}2K`^DB%MF9{0D%)8CVj0WaaiJT)4WO&R_rNck1@1 z{J*bc-aWX?<=)p5`rd_Xh^;L1l$#82U`5_o{P%OV39DCt1NYlH@%H?N-r9kV{M0Xo z7eH*~5zd5b zLI=_bGay>Iy!02-tXfkZi8c*75-6*8Vt*S132KV`)Bmp-sERIqd>>-@S!2sC&zGMN zbI-)8qn@cCgQ{+420A`H0q-@!2?~wiG1(p7hvU3MPNI~E{EJIl(X)P9%%V;I#_W1^S*A8`)?{zE?Fln)Um*kY3#?;7EDNh;!zIl7=*myk5be&iK2qs6mw`m zFg#+EIQ`TA?BC=PEAj?M61hn=7kgqJ^Vpcdryo~Z3}YwY^Xg3qb`f4sBsb+L`glzS zGc6Z|+QPh?4q^%jRq{ER2FUJx{m?RzFfr9O=a%K_670qODSJMq$P52?6=+#^2_ma0VEss|57w zGvJI(PefP|xJ`U56ug=^&b#bXyzsB4dI28i6I9lrt87U4;U*{AmkjI!X7t*giPG2X z3L60A9|pBV;f4i>lQ$d#MCMi=Oxdqf%2*Hkngp z5R_MLX;ZZ5`i#%f=?L)b%b_7hq)x%x8EjG5oI%}BPILe3{Ta3qgi{_EK@)TOV)XD` z$|WzP9ieKHUVVcT)gbI4!IpNT%#SEkHoB4Igt-Xuy|L&{eKB?hCsA(hJaeC=&+azc z?HpWdIv$yY0EgXej8yh~4gE-bhNL#1VD3LbJj0usyo=cWhALL9)<@HjG=vql0&Jl; zmp}}M&l{TIf(euEb`K|m_JwNRT;JXWpO|x^T`MNNtfmqVHy&C5C)YXaj`u%pv7&;B z%du_VK2=IHlNQ~1uBQUajqo!F7A_5czlQ%%*D}Yg3~_aSV3KQUQ1fmu17N%vXhR=c z`n3*W;kk#Kg1CP**w8G8pl0BU?l!y_Th0+C2=M9z(Gq+n@U&CnvpmU`J!6~105}H& z{i^Q71<)Uj0?Hhmnu|Xy<}|yS6T0784Hiroy&K{K2WW|0V4CajjC1u`o4lCB!Edig zJLQ@zd^JhCAB{I z^dBQjN{!^r`<{>6hY~PSTWPm9$Qt59N^Ux|yy#p%k{5`WJQ=$19&Q(q? zH*J59kfM8AT~!^>^N!w2v4N&vx$c_6TwjLiglrM3sf3gInH_KI3i%z6TGvR(baVJPdEe zB*q=6DYT4o4ef_q&}n4yjJw{dRrYpuT-se^q`i|Pk!A{Ud+Fw$`jlJ2M`^dP*v@Vo z&hO}8$sv$-xo40$P(e_5dbNn;x3vg{nR4e1@l2)Ge-c5s_c_MAYvhVYC~^cQ8c%sc zqGy=4?Eo5Q1EIu_Kxn7~6o39AYH6>Vp6kNPA4Si<8^iD1umYZNmw2iajgzaFm^pss zh)pT#Zc${`-B9=Opswg}C7TQJYSvX@lyNFxRob4RGQ4jwd`a+Gf!kX5XW*-kltPP8 zx!%t&*5vi()Pf#zRIWr`IS2&@xPPD#2_K_TcDh-c8%1Wej@TaT8m)OXpJtj<|{ks|6JW@|(jJjYtP%b^|&R)~f2<7a?9Crst@`EPB)Ilt zwzw4}y)X&Q!;r{;0E8_qC}iqs)j48B+Uwy9;(&x-7kln^cJ4;vyHx{Y^jD1OG>hVX zBB#Ygmf3VXuGjDyc|)ZNfvN6I)^%1e@PWV`kMeqGbmypC7zI|HcYh8S0oXiKiimuB z-PI?b8h1JuUo*>%^2Y8S*q5CZ!A2!fe=-0QURi%-9?@S0*vgB71-paoe^a*!wcGPp z-WKVfhwyZngzP5{-w)xg@~_2Bf|=>T1&p}J!N`agGH<2m&ew#>0^PdD)5j)HLKn#h ze$acqpU1)q1rXAGkAOr}C2i(6vq(>!8+9i|tSv_kZfuuJR@BJoroVZKbO3w&7FO0*~%dC~heqE>IXAel~f=wtGTd|n_L5m^&;1mW*U*#P#NP16-VB%lYao>%U=HpFuU>!~GV=EWk&D%~P zPMwq6H|hw&6d;lW0NQNBV~Z$LJ2Q8>-&uFq*r-8yPY4|+*gSpr3|73b`DDr=&&SCL znL&Jz+ExI|q6L3&ruRd7S&pS)eFV>(r13W168pZBzp1q`&>pS- z^UpRa4W;~mY){4r{sKe79b%5hd>Y+Vf07a8ElG8g7SOQ4EPZg0Vv-$h?c5hU20Fugc_@yU za0ruP*m?z^*u=ekB}}=6HLqc!_Hg+V&81~NNB?@c1GsV(Z6@gwYCE^xolpU(r1#_G zX;jNQ#o{mlt+#4}FImlME?k~cgSMnAVtWCW6YiU6*dgB;Jg7>0jqp2P9@3YTH|&|? zb?%hs1hrgqK#c_2nBL-bY!^P0wFV-TkI-TUAHLz(R>DoISR7PT%;tMvdL&F~t{O<> zkKxnw!Kiuvt~;?^-2jV=)!MoE3rZM%?AGdO8^w(0qb*!BhWLxBMj6*jR&d+Nd_F2+ zR4q=fXEL(ZnJU@Mt-`r8VpReikphO9dnClay3kq33SfUY7eL!(bvW{8i>y46XS#TgxjYbo3#8c}GOmO}Kj` zB5x@(Z~kOY0ukBz#PAUeV&scn_@`L{e{;S!Am!7aSljM}E{Eu^9)RN)G1qQTO`=F{ zS6+x$H&CIh(Q@i&GXGGb&Q$ST_aj!XkvaP_BM`W~G7&^b$Gh(Cu#uca`U8#@K2V5r7S!d_K_rtJfWOMeNNOR>T^80;|xz z8j?l530H`en>oPx7%QedZEu?d(=Kfu@BJt)(6z{ft|-*ZhwsN;Kh0-tndFe0Y3Pwt z(?05&f`6AHLXE40XZE&j_Dco$_j7TL!l1)P4+57M2=gW})j#vJ(Wp@qh{V(34tMC6 z(Q=Qhh~h)60pMQdAIKX#mZk?eJ~hElYRs#!gqV#EJ)aHbG%7Xjk=oBS?Lpb4bss9` zFApaSy#n+d@8=5O&m!e?V+U_@npDcHZP9vtJ{dORQ92w}+T~g1cdgSXRp!N)Muc0C z3i*cw6t{LCJn%hn*gc2Wpfd;{iJJGbdJR&pS9APpzJc25mF%9x1(hbjnPYm1r;BNWlt|x*MUWReo}PusjaYVbm6_X>gB9VUZPE&+{4?^e&U|o%b)EM zx#GP7#aO}*91QCfL5H>3XmnL{eSA(DRLoplK}TU|2CTX2Ls9xiqA8jgwq?sz%P9^g zd9Dz%z9FH8WK&n!nS)Q~9MA;Zit8PmalXF%N|ru4bqljiW)>&!cve72DYi2|xUid2 zbF#7Q#phBQsB;e!;^=bX+fCIPjyGe8{&r5|AlrMj0lu0wMOsu}BAg^|un+0zp$`0x)A&mUvLJxeAqF?9Gi#6L8N zD-U>iNjC=nu=~ny+a)iM{U0jn^8BhKgE-iK1|zlTz}es-1NpkwS@V><{2l+>L&U&; q-uBz6e7++1|F8UCXh60=BF~RX{S;)ZS@hS{^<4d>8tlotkpBV8T=if8 literal 0 HcmV?d00001 diff --git a/named_entity_recognition/configs/dataops_config.json b/named_entity_recognition/configs/dataops_config.json new file mode 100644 index 000000000..8519a1f9b --- /dev/null +++ b/named_entity_recognition/configs/dataops_config.json @@ -0,0 +1,40 @@ +{ + "DATA_STORE_NAME": "ner_data_store", + "COMPUTE_NAME": "ner_compute", + "DATA_STORE_DESCRIPTION": "pipeline data store description for evaluation", + "DATA_PREP_COMPONENT": + { + "COMPONENT_NAME": "prep_data_component", + "COMPONENT_DISPLAY_NAME": "Prepare data component", + "COMPONENT_DESCRIPTION": "Loading and processing data for prompt engineering" + }, + "STORAGE": + { + "STORAGE_ACCOUNT": "saner", + "SOURCE_CONTAINER": "source", + "SOURCE_BLOB": "ner_source.csv", + "TARGET_CONTAINER": "data" + }, + "PATH": + { + "DATA_PIPELINE_CODE_DIR": "named_entity_recognition/data_pipelines/aml" + }, + "SCHEDULE": + { + "NAME": "ner_data_pipeline_schedule", + "CRON_EXPRESSION": "10 14 * * 1", + "TIMEZONE": "Eastern Standard Time" + }, + "DATA_ASSETS":[ + { + "NAME": "ner_eval", + "PATH": "eval.jsonl", + "DESCRIPTION": "NER eval data asset" + }, + { + "NAME": "ner_exp", + "PATH": "exp.jsonl", + "DESCRIPTION": "NER experiment data asset" + } + ] +} \ No newline at end of file diff --git a/named_entity_recognition/data/source.txt b/named_entity_recognition/data/source.txt new file mode 100644 index 000000000..ee199586c --- /dev/null +++ b/named_entity_recognition/data/source.txt @@ -0,0 +1,16 @@ +text entity_type results +The software engineer is working on a new update for the application. job title software engineer +The project manager and the data analyst are collaborating to interpret the project data. job title "project manager, data analyst" +The marketing manager is coordinating with the graphic designer to create a new advertisement campaign. job title "marketing manager, graphic designer" +The CEO and CFO are discussing the financial forecast for the next quarter. job title "CEO, CFO" +The web developer and UX designer are working together to improve the website's user interface. job title "web developer, UX designer" +John finally decided to change his phone number after receiving too many spam calls. phone number None +"If you have any questions about our products, please call our customer service at (123) 456-7890." phone number (123) 456-7890 +"My new phone number is (098) 765-4321, please update your contact list." phone number (098) 765-4321 +The phone number (321) 654-0987 is no longer in service. phone number (321) 654-0987 +Please dial the following phone number: (555) 123-4567 to reach our technical support. phone number (555) 123-4567 +John Doe has been appointed as the new CEO of the company. people's full name John Doe +The novel 'The Great Gatsby' was written by F. Scott Fitzgerald. people's full name F. Scott Fitzgerald +Mary Jane Watson and Peter Parker are characters in the Spider-Man series. people's full name "Mary Jane Watson, Peter Parker" +"The famous physicists, Albert Einstein and Isaac Newton, made significant contributions to the field of physics." people's full name "Isaac Newton, Albert Einstein" +The Eiffel Tower is an iconic landmark in Paris. people's full name None diff --git a/named_entity_recognition/data_pipelines/aml/prep_data.py b/named_entity_recognition/data_pipelines/aml/prep_data.py new file mode 100644 index 000000000..5d684ecc1 --- /dev/null +++ b/named_entity_recognition/data_pipelines/aml/prep_data.py @@ -0,0 +1,100 @@ +import argparse +import json + +import pandas as pd +from azure.identity import DefaultAzureCredential +from azure.storage.blob import BlobServiceClient +import io + +""" +This function prepares data for processing. +It reads a CSV file from a source blob storage, +converts the CSV data to JSONL (JSON Lines) format, +and then uploads the JSONL data to a target blob storage. + +Args: +--blob_service_client: The Azure blob service client. +This argument is required for interacting with Azure blob storage. +--source_container_name: The name of the source container in blob storage. +This argument is required to specify the source container from where the CSV data is read. +--target_container_name: The name of the target container in blob storage. +This argument is required to specify the target container to where the JSONL data is uploaded. +--source_blob: The name of the source blob in the source container. +This argument is required to specify the source blob from where the CSV data is read. +--target_data_assets: The target data assets in the target container. +This argument is required to specify the target data assets to where the JSONL data is uploaded. +""" + + +def prepare_data(blob_service_client, + source_container_name, + target_container_name, + source_blob, + target_data_assets): + print('Data processing component') + + source_blob_client = blob_service_client.get_blob_client(container=source_container_name, + blob=source_blob) + source_blob_content = source_blob_client.download_blob().readall() + + assets = [item.strip() for item in target_data_assets.split(":")] + + df = pd.read_csv(io.StringIO(source_blob_content.decode('utf-8'))) + + jsonl_list = [] + for _, row in df.iterrows(): + jsonl_list.append(json.dumps(row.to_dict())) + + # Upload JSONL data to the target container + for asset in assets: + target_blob_client = blob_service_client.get_blob_client(container=target_container_name, + blob=asset) + target_blob_client.upload_blob('\n'.join(jsonl_list), overwrite=True) + print(f"CSV data converted to JSONL and uploaded successfully!: {asset}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--storage_account", + type=str, + help="storage account", + ) + parser.add_argument( + "--source_container_name", + type=str, + help="source container name", + ) + parser.add_argument( + "--target_container_name", + type=str, + help="target container name", + ) + parser.add_argument( + "--source_blob", + type=str, + help="source blob file (csv)", + ) + parser.add_argument( + "--assets_str", + type=str, + help="target assets to be created as a string" + ) + + args = parser.parse_args() + storage_account = args.storage_account + source_container_name = args.source_container_name + target_container_name = args.target_container_name + source_blob = args.source_blob + target_data_assets = args.assets_str + + storage_account_url = f"https://{storage_account}.blob.core.windows.net" + + blob_service_client = BlobServiceClient(storage_account_url, + credential=DefaultAzureCredential()) + + prepare_data(blob_service_client, + source_container_name, + target_container_name, + source_blob, + target_data_assets) diff --git a/named_entity_recognition/environment/conda.yml b/named_entity_recognition/environment/conda.yml new file mode 100644 index 000000000..6aed6c93c --- /dev/null +++ b/named_entity_recognition/environment/conda.yml @@ -0,0 +1,9 @@ +name: named-entity-env +channels: + - conda-forge +dependencies: + - python=3.9 + - pip + - pip: + - jinja2 +