From 443474cfafea03e98bb3513672a1a166106385c4 Mon Sep 17 00:00:00 2001 From: Alberto Cattaneo <84471416+AlCatt91@users.noreply.github.com> Date: Thu, 28 Sep 2023 15:25:58 +0100 Subject: [PATCH] KGDataset.from_dataframe + custom data notebook (#25) * add from_dataframe build option in KGDataset * mypy fix * add tutorial notebook for custom datasets * update CONTRIBUTING for forks * add dataset disclaimer * refactor dataset.py and README * add openbiolink dataloader * fix typo * resize image * fix link * change dataset in notebook 0 * minor update * fix typo * Tech Docs review of notebook: Using BESS-KGE with your Own Data * isort + fix typo * restore download output --------- Co-authored-by: Jaynie Padayachee Co-authored-by: JaynieP <92803120+jayniep-gc@users.noreply.github.com> --- CONTRIBUTING.md | 43 +- NOTICE.md | 19 +- README.md | 17 +- besskge/dataset.py | 325 ++++--- docs/source/KGbib.bib | 10 + docs/source/images/Terminal1.png | Bin 201111 -> 0 bytes docs/source/images/Terminal3.png | Bin 0 -> 91608 bytes notebooks/0_custom_KG_dataset.ipynb | 988 +++++++++++++++++++++ notebooks/1_biokg_training_inference.ipynb | 248 ++++-- notebooks/2_yago_topk_prediction.ipynb | 250 ++++-- notebooks/3_wikikg2_fp16.ipynb | 237 +++-- 11 files changed, 1788 insertions(+), 349 deletions(-) delete mode 100644 docs/source/images/Terminal1.png create mode 100644 docs/source/images/Terminal3.png create mode 100644 notebooks/0_custom_KG_dataset.ipynb diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index da0ec10..2fb654f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,27 +1,36 @@ # How to contribute to the BESS-KGE project -You can contribute to the development of the BESS-KGE project, even if you don't have access to IPUs (you can use the [IPUModel](https://docs.graphcore.ai/projects/poptorch-user-guide/en/3.2.0/reference.html#poptorch.Options.useIpuModel) to emulate most functionalities of the physical hardware). +![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square) + +You can contribute to the development of the BESS-KGE project, even if you don't have access to IPUs (you can use the [IPUModel](https://docs.graphcore.ai/projects/poptorch-user-guide/en/3.2.0/reference.html#poptorch.Options.useIpuModel) to emulate most functionalities of the physical hardware). ## VS Code server on Paperspace -Setting up a VS Code server on [Paperspace](https://www.paperspace.com/graphcore) will allow you to tunnel into a machine with IPUs from the VS Code web editor or the desktop app. This requires minimum effort and is an excellent solution for developing and testing code directly on IPU hardware. +Setting up a VS Code server on [Paperspace](https://www.paperspace.com/graphcore) will allow you to tunnel into a machine with IPUs from the VS Code web editor or the desktop app. This requires minimum effort and is an excellent solution for developing and testing code directly on IPU hardware. Here's how to do it. -You can launch a 6-hours session on a Paperspace machine with access to 4 IPUs **for free** by clicking on this button: Run on Gradient +1. Fork the [BESS-KGE repository](https://github.com/graphcore-research/bess-kge). -Start the machine (this will also clone the repo for you) and open up a terminal from the left pane. +2. You can launch a 6-hours session on a Paperspace machine with access to 4 IPUs **for free** by using a link of the form: + ``` + https://console.paperspace.com/github/{USERID}/{REPONAME}?container=graphcore%2Fpytorch-paperspace%3A3.3.0-ubuntu-20.04-20230703&machine=Free-IPU-POD4 + ``` -![terminal_pane](docs/source/images/Terminal1.png "height=200") + where `{USERID}/{REPOPNAME}` is the github address of the forked repository (e.g. `graphcore-research/bess-kge` for the original repo). -In the terminal, run the command -```shell -bash .gradient/launch_vscode_server.sh {tunnel-name} -``` +3. Start the machine (this will also clone the repo for you) and open up a terminal from the left pane. + + ![terminal_pane](docs/source/images/Terminal3.png) -where `tunnel-name` is an optional argument that you can use to define the name of the remote tunnel (if not set, it will default to `ipu-paperspace`). +4. In the terminal, run the command + ```shell + bash .gradient/launch_vscode_server.sh {tunnel-name} + ``` -The script will download and install all dependencies and start the tunnel. You will be asked to authorize the tunnel through GitHub, before being provided with the tunnel link. Please refer to [this notebook](https://ipu.dev/fmo4AZ) for additional details on these steps and to connect the VS Code desktop app to the remote tunnel. + where `tunnel-name` is an optional argument that you can use to define the name of the remote tunnel (if not set, it will default to `ipu-paperspace`). The script will download and install all dependencies and start the tunnel. -Once VS Code is connected to the Paperspace machine, run `./dev build` to build all custom ops. You are now ready to create a new git branch and start developing! +5. When asked, authorize the tunnel through GitHub (with an account having writing privileges to the forked repository). You will be then provided with the tunnel link. Please refer to [this notebook](https://ipu.dev/fmo4AZ) for additional details on these steps and to connect the VS Code desktop app to the remote tunnel. + +6. Once VS Code is connected to the Paperspace machine, run `./dev build` to build all custom ops. You are now ready to start developing! When closing a session and stopping the Paperspace machine, remember to unregister the tunnel in VS Code as explained in the "Common Issues" paragraph of the [notebook](https://ipu.dev/fmo4AZ). To resume your work, just access the clone of the BESS-KGE repo in the "Projects" section of your Paperspace profile, start a new machine and repeat the operations above. All code changes to the local repo, as well as VS Code settings and extensions installed, will persist across sessions. @@ -43,10 +52,14 @@ pip install $POPLAR_SDK_ENABLED/../poptorch-*.whl pip install -r requirements-dev.txt ``` -Finally, build all custom ops by running `./dev build` +Finally, clone your fork of the BESS-KGE repository and build all custom ops by running `./dev build` + +## Development tips + +The `./dev` command can be used to run several utility scripts during development. Check `./dev --help` for a list of dev options. -## Tips +Before submitting a PR to the upstream repo, use `./dev ci` to run all CI checks locally. In particular, be mindful of our formatting requirements: you can check for formatting errors by running `./dev format` and `./dev lint` (both commands are automatically run inside `./dev ci`). -Run `./dev --help` for a list of dev options. In particular, use `./dev ci` to run all CI checks locally. Run individual tests with pattern matching filtering `./dev tests -k FILTER`. +Add unit tests to the `tests` folder. You can run individual unit tests with pattern matching filtering `./dev tests -k FILTER`. Add `.cpp` custom ops to `besskge/custom_ops`. Also, update the [Makefile](Makefile) when adding custom ops. diff --git a/NOTICE.md b/NOTICE.md index cd44ef3..18e28d2 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -2,9 +2,7 @@ Copyright (c) 2023 Graphcore Ltd. Licensed under the MIT License. The included code is released under an MIT license, (see [LICENSE](LICENSE)). -The ogbl-biokg and ogbl-wikikg2 datasets are licensed under CC-0. - -The [YAGO3 dataset](https://yago-knowledge.org/downloads/yago-3) by the [YAGO team](https://yago-knowledge.org/contributors) of the [Max-Planck Institute for Informatics](https://www.mpi-inf.mpg.de/home/) and [Telcom Paris](https://www.telecom-paris.fr/) is licensed under [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/). +## Dependencies Our dependencies are (see [requirements.txt](requirements.txt)): @@ -18,8 +16,21 @@ Our dependencies are (see [requirements.txt](requirements.txt)): We also use additional Python dependencies for development/testing/documentation (see [requirements-dev.txt](requirements-dev.txt)). +## Dataset disclaimer + +This repository provides dataloaders for third party datasets. The use of these datasets is at own risk and Graphcore offers no warranties of any kind. It is the user's responsibility to comply with all license requirements for datasets downloaded with dataloaders in this repository. + +The tutorial notebooks make use of the following datasets: + +* [ogbl-biokg](https://ogb.stanford.edu/docs/linkprop/#ogbl-biokg), licensed under CC-0; + +* [ogbl-wikikg2](https://ogb.stanford.edu/docs/linkprop/#ogbl-wikikg2), licensed under CC-0; + +* [YAGO3 dataset](https://yago-knowledge.org/downloads/yago-3) by the [YAGO team](https://yago-knowledge.org/contributors) of the [Max-Planck Institute for Informatics](https://www.mpi-inf.mpg.de/home/) and [Telcom Paris](https://www.telecom-paris.fr/), licensed under [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/). + +## Derived work -**This directory includes derived work from the following:** +This directory includes derived work from the following: --- diff --git a/README.md b/README.md index 909b229..20cd1ff 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # BESS-KGE ![Continuous integration](https://github.com/graphcore-research/bess-kge/actions/workflows/ci.yaml/badge.svg) +![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square) [**Installation guide**](#usage) | [**Tutorials**](#paperspace-notebook-tutorials) @@ -77,6 +78,17 @@ Additional variations of the distribution scheme are detailed in the [BESS-KGE d All APIs are documented in the [BESS-KGE API documentation](https://graphcore-research.github.io/bess-kge/API_reference.html). +### Datasets + +BESS-KGE provides built-in dataloaders for the following datasets. Notice that the use of these datasets is at own risk and Graphcore offers no warranties of any kind. It is the user's responsibility to comply with all license requirements for datasets downloaded with dataloaders in this repository. + +| Dataset | Builder method | Entities | Entity types | Relation types | Triples | License | +| --- | --- | --- | --- | --- | --- | --- | +| [ogbl-biokg](https://ogb.stanford.edu/docs/linkprop/#ogbl-biokg) | [KGDataset.build_ogbl_biokg](https://graphcore-research.github.io/bess-kge/generated/besskge.dataset.KGDataset.html#besskge.dataset.KGDataset.build_ogbl_biokg) | 93,773 | 5 | 51 | 5,088,434 | CC-0 | +| [ogbl-wikikg2](https://ogb.stanford.edu/docs/linkprop/#ogbl-wikikg2) | [KGDataset.build_ogbl_wikikg2](https://graphcore-research.github.io/bess-kge/generated/besskge.dataset.KGDataset.html#besskge.dataset.KGDataset.build_ogbl_wikikg2) | 2,500,604 | 1 | 535 | 16,968,094 | CC-0 | +| [YAGO3-10](https://yago-knowledge.org/downloads/yago-3) | [KGDataset.build_yago310](https://graphcore-research.github.io/bess-kge/generated/besskge.dataset.KGDataset.html#besskge.dataset.KGDataset.build_yago310) | 123,182 | 1 | 37 | 1,089,040 | CC BY 3.0 | +| [OpenBioLink2020](https://github.com/openbiolink/openbiolink#benchmark-dataset) | [KGDataset.build_openbiolink](https://graphcore-research.github.io/bess-kge/generated/besskge.dataset.KGDataset.html#besskge.dataset.KGDataset.build_openbiolink) | 184,635 | 7 | 28 | 4,563,405 | [link](https://github.com/openbiolink/openbiolink#Source-databases-and-their-licenses) | + ### Known limitations * BESS-KGE supports distribution for up to 16 IPUs. @@ -178,10 +190,11 @@ For a walkthrough of the `besskge` library functionalities, see our Jupyter note 2. [Link prediction on the YAGO3-10 dataset](notebooks/2_yago_topk_prediction.ipynb) [![Run on Gradient](docs/gradient-badge.svg)](https://console.paperspace.com/github/graphcore-research/bess-kge?container=graphcore%2Fpytorch-paperspace%3A3.3.0-ubuntu-20.04-20230703&machine=Free-IPU-POD4&file=%2Fnotebooks%2F2_yago_topk_prediction.ipynb) 3. [FP16 weights and compute on the OGBL-WikiKG2 dataset](notebooks/3_wikikg2_fp16.ipynb) [![Run on Gradient](docs/gradient-badge.svg)](https://console.paperspace.com/github/graphcore-research/bess-kge?container=graphcore%2Fpytorch-paperspace%3A3.3.0-ubuntu-20.04-20230703&machine=Free-IPU-POD4&file=%2Fnotebooks%2F3_wikikg2_fp16.ipynb) +For pointers on how to run BESS-KGE on a custom Knowledge Graph dataset, see the notebook [Using BESS-KGE with your own data](notebooks/0_custom_KG_dataset.ipynb) [![Run on Gradient](docs/gradient-badge.svg)](https://console.paperspace.com/github/graphcore-research/bess-kge?container=graphcore%2Fpytorch-paperspace%3A3.3.0-ubuntu-20.04-20230703&machine=Free-IPU-POD4&file=%2Fnotebooks%2F0_custom_KG_dataset.ipynb) ## Contributing -You can contribute to the BESS-KGE project. See [How to contribute to the BESS-KGE project](CONTRIBUTING.md) +You can contribute to the BESS-KGE project: PRs are welcome! For details, see [How to contribute to the BESS-KGE project](CONTRIBUTING.md). ## References BESS: Balanced Entity Sampling and Sharing for Large-Scale Knowledge Graph Completion ([arXiv](https://arxiv.org/abs/2211.12281)) @@ -190,6 +203,6 @@ BESS: Balanced Entity Sampling and Sharing for Large-Scale Knowledge Graph Compl Copyright (c) 2023 Graphcore Ltd. Licensed under the MIT License. -The included code is released under the MIT license, (see [details of the license](LICENSE)). +The included code is released under the MIT license (see [details of the license](LICENSE)). See [notices](NOTICE.md) for dependencies, credits, derived work and further details. \ No newline at end of file diff --git a/besskge/dataset.py b/besskge/dataset.py index 85e760a..17a12d1 100644 --- a/besskge/dataset.py +++ b/besskge/dataset.py @@ -8,9 +8,10 @@ import dataclasses import pickle import tarfile +import zipfile from io import BytesIO from pathlib import Path -from typing import Dict, List, Optional, Tuple +from typing import Dict, List, Optional, Tuple, Union import numpy as np import ogb.linkproppred @@ -75,7 +76,153 @@ def ht_types(self) -> Optional[Dict[str, NDArray[np.int32]]]: return None @classmethod - def build_biokg(cls, root: Path) -> "KGDataset": + def from_triples( + cls, + data: NDArray[np.int32], + split: Tuple[float, float, float] = (0.7, 0.15, 0.15), + seed: int = 1234, + entity_dict: Optional[List[str]] = None, + relation_dict: Optional[List[str]] = None, + type_offsets: Optional[Dict[str, int]] = None, + ) -> "KGDataset": + """ + Build a dataset from an array of triples, where IDs for entities + and relations have already been assigned. Note that, if entities have + types, entities of the same type need to have contiguous IDs. + Triples are randomly split in train/validation/test sets. + If a pre-defined train/validation/test split is wanted, the KGDataset + class should be instantiated manually. + + :param data: + Numpy array of triples [head_id, relation_id, tail_id]. Shape + (num_triples, 3). + :param split: + Tuple to set the train/validation/test split. + :param seed: + Random seed for the train/validation/test split. + :param entity_dict: + Optional entity labels by ID. + :param relation_dict: + Optional relation labels by ID. + :param type_offsets: + Offset of entity types + + :return: Instance of the KGDataset class. + """ + num_triples = data.shape[0] + num_train = int(num_triples * split[0]) + num_valid = int(num_triples * split[1]) + + rng = np.random.default_rng(seed=seed) + rng.shuffle(data, axis=0) + + triples = dict() + triples["train"], triples["valid"], triples["test"] = np.split( + data, (num_train, num_train + num_valid), axis=0 + ) + + return cls( + n_entity=data[:, [0, 2]].max() + 1, + n_relation_type=data[:, 1].max() + 1, + entity_dict=entity_dict, + relation_dict=relation_dict, + type_offsets=type_offsets, + triples=triples, + ) + + @classmethod + def from_dataframe( + cls, + df: Union[pd.DataFrame, Dict[str, pd.DataFrame]], + head_column: Union[int, str], + relation_column: Union[int, str], + tail_column: Union[int, str], + entity_types: Optional[Union["pd.Series[str]", Dict[str, str]]] = None, + split: Tuple[float, float, float] = (0.7, 0.15, 0.15), + seed: int = 1234, + ) -> "KGDataset": + """ + Build a KGDataset from a pandas DataFrame of labeled (h,r,t) triples. + IDs for entities and relations are automatically assigned based on labels + in such a way that entities of the same type have contiguous IDs. + + :param df: + Pandas DataFrame of all triples in the knowledge graph dataset, + or dictionary of DataFrames of triples for each part of the dataset split + :param head_column: + Name of the DataFrame column storing head entities + :param relation_column: + Name of the DataFrame column storing relations + :param tail_column: + Name of the DataFrame column storing tail entities + :param entity_types: + If entities have types, dictionary or pandas Series of mappings + entity label -> entity type. + :param split: + Tuple to set the train/validation/test split. + Only used if no pre-defined dataset split is specified, + i.e. if `df` is not a dictionary. + :param seed: + Random seed for the train/validation/test split. + Only used if no pre-defined dataset split is specified, + i.e. if `df` is not a dictionary. + + :return: Instance of the KGDataset class. + """ + + df_dict = {"all": df} if isinstance(df, pd.DataFrame) else df + unique_ent = pd.concat( + [ + pd.concat([dfp[head_column], dfp[tail_column]]) + for dfp in df_dict.values() + ] + ).unique() + ent2id = pd.Series(np.arange(len(unique_ent)), index=unique_ent, name="ent_id") + unique_rel = pd.concat( + [dfp[relation_column] for dfp in df_dict.values()] + ).unique() + rel2id = pd.Series(np.arange(len(unique_rel)), index=unique_rel, name="rel_id") + + if entity_types is not None: + ent2type = pd.Series(entity_types, name="ent_type") + ent2id_type = pd.merge( + ent2id, ent2type, how="left", left_index=True, right_index=True + ).sort_values("ent_type") + ent2id.index = ent2id_type.index + type_off = ( + ent2id_type.groupby("ent_type")["ent_type"].count().cumsum().shift(1) + ) + type_off.iloc[0] = 0 + type_offsets = type_off.astype("int64").to_dict() + else: + type_offsets = None + + entity_dict = ent2id.index.tolist() + relation_dict = rel2id.index.tolist() + + triples = {} + for part, dfp in df_dict.items(): + heads = dfp[head_column].map(ent2id).values.astype(np.int32) + tails = dfp[tail_column].map(ent2id).values.astype(np.int32) + rels = dfp[relation_column].map(rel2id).values.astype(np.int32) + triples[part] = np.stack([heads, rels, tails], axis=1) + + if isinstance(df, pd.DataFrame): + return KGDataset.from_triples( + triples["all"], split, seed, entity_dict, relation_dict, type_offsets + ) + else: + return cls( + n_entity=len(entity_dict), + n_relation_type=len(relation_dict), + entity_dict=entity_dict, + relation_dict=relation_dict, + type_offsets=type_offsets, + triples=triples, + ) + + @classmethod + def build_ogbl_biokg(cls, root: Path) -> "KGDataset": """ Build the ogbl-biokg dataset :cite:p:`OGB` @@ -138,7 +285,7 @@ def build_biokg(cls, root: Path) -> "KGDataset": ) @classmethod - def build_wikikg2(cls, root: Path) -> "KGDataset": + def build_ogbl_wikikg2(cls, root: Path) -> "KGDataset": """ Build the ogbl-wikikg2 dataset :cite:p:`OGB` @@ -215,130 +362,82 @@ def build_yago310(cls, root: Path) -> "KGDataset": with tarfile.open(fileobj=BytesIO(res.content)) as tarf: tarf.extractall(path=root) - train = np.loadtxt(root.joinpath("train.txt"), delimiter="\t", dtype=str) - valid = np.loadtxt(root.joinpath("valid.txt"), delimiter="\t", dtype=str) - test = np.loadtxt(root.joinpath("test.txt"), delimiter="\t", dtype=str) - - entity_dict, entity_id = np.unique( - np.concatenate( - [ - train[:, 0], - train[:, 2], - valid[:, 0], - valid[:, 2], - test[:, 0], - test[:, 2], - ] - ), - return_inverse=True, - ) - entity_split_limits = np.cumsum( - [ - train.shape[0], - train.shape[0], - valid.shape[0], - valid.shape[0], - test.shape[0], - ] + train_triples = pd.read_csv( + root.joinpath("train.txt"), delimiter="\t", dtype=str, header=None ) - ( - train_head_id, - train_tail_id, - validation_head_id, - validation_tail_id, - test_head_id, - test_tail_id, - ) = np.split(entity_id, entity_split_limits) - - rel_dict, rel_id = np.unique( - np.concatenate([train[:, 1], valid[:, 1], test[:, 1]]), - return_inverse=True, + valid_triples = pd.read_csv( + root.joinpath("valid.txt"), delimiter="\t", dtype=str, header=None ) - relation_split_limits = np.cumsum([train.shape[0], valid.shape[0]]) - train_rel_id, validation_rel_id, test_rel_id = np.split( - rel_id, relation_split_limits + test_triples = pd.read_csv( + root.joinpath("test.txt"), delimiter="\t", dtype=str, header=None ) - triples = { - "train": np.concatenate( - [train_head_id[:, None], train_rel_id[:, None], train_tail_id[:, None]], - axis=1, - ), - "validation": np.concatenate( - [ - validation_head_id[:, None], - validation_rel_id[:, None], - validation_tail_id[:, None], - ], - axis=1, - ), - "test": np.concatenate( - [test_head_id[:, None], test_rel_id[:, None], test_tail_id[:, None]], - axis=1, - ), - } - - return cls( - n_entity=len(entity_dict), - n_relation_type=len(rel_dict), - entity_dict=entity_dict.tolist(), - relation_dict=rel_dict.tolist(), - type_offsets=None, - triples=triples, - neg_heads=None, - neg_tails=None, + return cls.from_dataframe( + {"train": train_triples, "valid": valid_triples, "test": test_triples}, + head_column=0, + relation_column=1, + tail_column=2, ) @classmethod - def from_triples( - cls, - data: NDArray[np.int32], - split: Tuple[float, float, float] = (0.7, 0.15, 0.15), - seed: int = 1234, - entity_dict: Optional[List[str]] = None, - relation_dict: Optional[List[str]] = None, - type_offsets: Optional[Dict[str, int]] = None, - ) -> "KGDataset": + def build_openbiolink(cls, root: Path) -> "KGDataset": """ - Build a dataset from an array of triples. Note that if a pre-defined - train/validation/test split is wanted the KGDataset class should be instantiated - manually. + Build the high-quality version of the OpenBioLink2020 + dataset :cite:p:`openbiolink` - :param data: - Numpy array of triples [head_id, relation_id, tail_id]. Shape - (num_triples, 3). - :param split: - Tuple to set the train/validation/test split. - :param seed: - Random seed for the train/validation/test split. - :param entity_dict: - Optional entity labels by ID. - :param relation_dict: - Optional relation labels by ID. - :param type_offsets: - Offset of entity types + .. seealso:: https://github.com/openbiolink/openbiolink#benchmark-dataset - :return: Instance of the KGDataset class. - """ - num_triples = data.shape[0] - num_train = int(num_triples * split[0]) - num_valid = int(num_triples * split[1]) + :param root: + Local path to the dataset. If the dataset is not present in this + location, then it is downloaded and stored here. - rng = np.random.default_rng(seed=seed) - rng.shuffle(data, axis=0) + :return: The HQ OpenBioLink2020 KGDataset. + """ - triples = dict() - triples["train"], triples["valid"], triples["test"] = np.split( - data, (num_train, num_train + num_valid), axis=0 + if not ( + root.joinpath("HQ_DIR/train_test_data/train_sample.csv").is_file() + and root.joinpath("HQ_DIR/train_test_data/val_sample.csv").is_file() + and root.joinpath("HQ_DIR/train_test_data/test_sample.csv").is_file() + and root.joinpath("HQ_DIR/train_test_data/train_val_nodes.csv").is_file() + ): + print("Downloading dataset...") + res = requests.get(url="https://zenodo.org/record/3834052/files/HQ_DIR.zip") + with zipfile.ZipFile(BytesIO(res.content)) as zip_f: + zip_f.extractall(path=root) + + column_names = ["h_label", "r_label", "t_label", "quality", "TP/TN", "source"] + train_triples = pd.read_csv( + root.joinpath("HQ_DIR/train_test_data/train_sample.csv"), + header=None, + names=column_names, + sep="\t", + ) + valid_triples = pd.read_csv( + root.joinpath("HQ_DIR/train_test_data/val_sample.csv"), + header=None, + names=column_names, + sep="\t", + ) + test_triples = pd.read_csv( + root.joinpath("HQ_DIR/train_test_data/test_sample.csv"), + header=None, + names=column_names, + sep="\t", ) - return cls( - n_entity=data[:, [0, 2]].max() + 1, - n_relation_type=data[:, 1].max() + 1, - entity_dict=entity_dict, - relation_dict=relation_dict, - type_offsets=type_offsets, - triples=triples, + entity_types = pd.read_csv( + root.joinpath("HQ_DIR/train_test_data/train_val_nodes.csv"), + header=None, + names=["ent_label", "ent_type"], + sep="\t", + ).set_index("ent_label")["ent_type"] + + return cls.from_dataframe( + {"train": train_triples, "valid": valid_triples, "test": test_triples}, + head_column="h_label", + relation_column="r_label", + tail_column="t_label", + entity_types=entity_types, ) def save(self, out_file: Path) -> None: diff --git a/docs/source/KGbib.bib b/docs/source/KGbib.bib index fa9e948..d1ad271 100644 --- a/docs/source/KGbib.bib +++ b/docs/source/KGbib.bib @@ -192,3 +192,13 @@ @inproceedings{TranS pages ={1202--1208}, year ={2022} } + +@article{openbiolink, + author = {Breit Anna and Ott Simon and Agibetov Asan and Samwald Matthias}, + title = {{OpenBioLink: a benchmarking framework for large-scale biomedical link prediction}}, + journal = {Bioinformatics}, + volume = {36}, + number = {13}, + pages = {4097-4098}, + year = {2020}, +} diff --git a/docs/source/images/Terminal1.png b/docs/source/images/Terminal1.png deleted file mode 100644 index 98ca224fe763d1a6f4f289f19a9f34c6ab24b31c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201111 zcmdqJc{r5s`!`N1twbRSA!ILW2qh(ivW~G$$u_p^8Otb@WUFl1i|oeOhODC`+1D9a zr|kRAFqnBRmG`I5=lTAQ@9#LC=ljodA4ki~ao^WBaSUt^(tds6f zT3@&NniK1I^$jQHQ+1WHb0}EkE|tHo{g?Jb_WpmO`vi>o&xfmbuKVwj`RlrNoSJ#> z|NEu>M;_3;co4GL8?GBRaJvsNzaFmYczehdweUQrCE5%{YQY$O9q@I6stpzGAoZHSd0ph;8q@6j8h=z5+qN%vsmF}f zHK+N-2PLNc5CPs(OjY3trW;3s$dEV2;raD3%w|z@Zp(|WQ5;3E53O2&*d;6$g zetaxn^y|>j6*+`jQT|wHPhK7t?mIXZZznpqZgkII-*O1=nITNsYVSq6vl*pt8j9h` z%Q8_pWD*KbG4}d$R0{d%{n9+4v}$8w{(wThnb73psAZyP7L#0hb=UmQEe8$*$IZnN zE7q#Oi5v4W`2Bl(^G4U~hZwdE5Vl(iHXTYu;bpeAMfpsC1jl^!wVJr?`S!2KtgQ-) z*A#_}rMQE?Cl&f+!!y^_sJzIu~tvLtfVC_+{0jAhsv;>Pz& z7O1_A?(7qor<%b>sm3EO%cp95nWgKWz#OMkkEQc!)-wAQxYf`G*u|iT{pMv+#=UDT z=2enE($qVgkna&Nh3(ZQu%<$`DW!wOy~s+dLHmVF$==FT>Zj_?z~*`pzRGA{-ReI1 zB8@Ml>>kZd74A1jEX@sUC>4~QoamcgBm7uz_h~jxlg&&&Ai)g3K9;r4GdL|f9iEAa z8(%&47QEW<{_Vcp3~dT)$$H~t^`#N-x%f`sg%DAO5#!ukiem<$`bX1b<20Mt_Edi< zL2UN1{=(hbCsabHO=}~GK*~zPNsIWs#onF2bCw#PT3qRMw3VLI&BhJ;_Hb2-YB7Dz z%C%BL<>E_b+0EKE%4*N?sGL*lHQBL4!z-(JoOoaf;?1Ml@8Wyw971e!zy{0XaZVdS zpRR}bC|vZ=BfOPf%h>rz94mg?KqwL0BE5#{cf}#2@#RoxMR=#Yeyfse`*+2EmT=r= zgRx(U>a%k*q5R}ONUtF0^W*(AC$S?X?f%L$%I4g+mq-mKQ<183HQ8@E)&eRsrM?>M zxsIzRM(U~T+BzcVM_SjDW*-%_wQ+-lVvHBe?{>4eL>Q#CXjU$o1LY2{Xztae%s-}euQ69O-fBJrZ@3}+j z+l;V5%?3M}wfh-r6BSJBHJ#ia{QIl6g|cZ4ZZ04ntO`*iMS8zG{_}*Q4<}5)i_}J~ z;fRU%$m;sAGFV@a)yaDv&3PbzeTWo%Bwu{X@LN*z%5T6e#EK#G`?lRG%t9SQ7ot*kJA|gkW zky|r_vkr!$7VQLy!04v4OQeW+{t$&dALsw>Qw%kJRe}EKzFa3K$uq8_GGhAeo!m~_ zZRR^MGvmMIaWSmS7fT)(iD&1|uG?}?AJTC~dKF`PJ&|mGk*v_y}O?fRHLn~^x2p`XX!U2g* zZ5lU!DURQxi|W&3u;6QXPMq=EZkzcz(#bGN8>d;1ate2EL6hMn+WVnn<-?1wQ&IgM zozZvB3stXfeW7-;3VXz3ce{5$pFMPJkG881f5cPSE#L;?f+O_lb4zECC|;F$<07rv zfP%o#XUxwm>b1L_x^ElDZPD#)@a~>&+k9n2hVAHH$nrl|BSUSF>@f9=+CXQnA>+!t zpVU@`*Vo}ImVF^k#g^p@Q%ROZUn5)2PXVwRzzhw=;gq8gM``Gxn^fPDgM$fy=7 z8OK5GmUiNbM7KRVD$I8l7R;7s3$Cet>m;ujVteqzozqU+W@|N#N!u<%tz2IV_mtyY z`^LE%c#-T#QJR1h3qQ8Yy&(EX*+`gaMd*ReFp;1A#h8yH1suo*;n~MgJHAX7*Lagh z__f?8J1hJ~@QQlOkA@#46zs8+N@>Kw-~G~BL%mREH_uZsWVcrEQxiFNlCZ_KYO8h6 zm16fYH=h=zEDlI-7kPVh{xDcCK@c}xy*O;ASUR1t7V?k%Zm>GhE*DDVB=pYJ%ycR=*O2wwth&@MUw#h+$u} zO*OI633nROD`DOoZtfs_bZ?J+frixh&W$TLnw;h0lTgOdfyV(@Y383VUkrK^$n~^+ zvrgn4PVe>dNsg$9h?U8X)X~vVG7T+d1}r|Q^?a>@#q6RtOhIuuv|vw9sScerI{@hl z9|zJJn%|6w-Y@GpQ^Nk0JE73pDN;HW2i6WnNN2824^?@WIu1e$S2K{Cr4;EMCCa)v zWqE;;D$+PTcvmdzQvUKfofPvw&h2q+4wc;``7EH;zN-LwY;>T)^JM6a%V`7s3vdaj zZ^iJ|&8mrph6Xha4Gk@=YWJD-C?P|Sh29*JnUO^<(mml`-TG$H^y4U&p&}>?^gncbuqw6GDF|U`VH#^idN0YIL=+Se9W))l~rhOr$q_CnKc

bz94JD7#8J z6{S<3xib(EfL*PU^BMg{-noSI8VjYYI8kw*!QDguWwo(Xt2KgK>Bb82B)ZcnEjD(gXi{clSy@?hwV@$6 zM;+5@)ytru-XhNhCqK#?%t+KvYz}gb$S4XY*LQZ)%zR(cos(PZPNH7b;o$m{E&30C zk+FbP;a%QH(YVZ0wvq{~EAp0uq~m=dC3(;yE%=!!+|E{8hN0?_&Kw2rQYXUF0%das z#EzTjoF_Iuc9w90=8ZhJVzbeCa`OtWeoVEAX&4E?c$@U2wRWR{TOYYB`cHdfoV&)~*WR=lF;n2Q*vYP;Y+!m1&)gy?<@`2-lD$|$_1kER zys~NWv=MaiWpCue&MFK+o(gfNrcl<`EBa=^nI008ZW;QbJskTgE$8~y+^cPD&Kn$f zA5}D|?&bVl13WvzLpaU$Pni8>TQgDh@MF2*6J{8ztD-x`Kf93gMOF^q4HdRZYzE&i z_;bzRonA3YR3Y$0K`znxRR%i*#&)F-GZT&8*c^Lec%qMu*m%u9>PmXZ85$uaKMYiU zPxbeo07h2pxdH-jTXZ@ZOQ^IDeQZ*$H2$t2G9@A=CMGF~{Nqyqu&EwKM$s>cioUDg z3utKRW4^4G)w>B~Geuk2slsOWH1+e!Mn{ zh%ES5BD(8`WH%|m5`0S}*TOj^yFQHl*d@NzL^|`|4=nS+vf`U_q^~*ywWLwlHAK{_JFm>xMQ)*wB%K|w zU9HlY!fhWQP^z}&Z`KRRkj#RR+bu_pMkvsB8oRz^4$e5sT+GvzpY<5bYy-bRmO&3> zPd)sTm!xaT-;z|;YO*mKWC~dyY5GnByXlcvaL(|pFM57RWYXLH{ksKRtVMko=VeGc z5kAps8ejSpZOpR1(x|T_YE%OInId+^Z)*IbVfvt=&n3HUbD#|Tp4z8{M1P)@_scfT zNa~aDH*4g1`bTN*Bs^k+9d?km_9>A}8y_B(VGHf#=JFgUmK}h+vJlp$>s#=~c&$Xc zw~@?5ARE3!jw*~ZI+r!NggRZwIP#w~rfyFOPuTdJfcd(f-zrMW0tt{|vd1`3(E8Wov=Oo`cPe*)+(~ zj~Fk1-5g|e%N}%>@W=P|dHnTvwkKGVU3ziJ>G(~XPp{<3q*7#GwM9(9$BDaB`s(V9 zVpF(SiTW^h@A-yLYxk5Wm2kCt2wd5W;eobeP?DL#(fkC3D;L5@vuz+L2JvON%|YDY zpL$|2$Jn=h0Sitsj8FFE{)x>Ux$;HHkL-3o0}seBfot4GSh=L|M+OB z8EhBMsr2Zgv>==Sd{W6%Cw*UZw6JN(;#OT~yrkG!;xrb?N^A_BR2N>UAec-Mq4>9; z;`H>guvptW+==}gd^LUEQif|a@XN&Y{xvLqn2U(&dDrkdwZ2;%<%`6x^4snsgM zTj)Sr|J)iQ~i?IqWS=wV$T?aQ@Rjx&FiX zxvyO({fLcQP-VUI#wGJ7PP(@D5vNmzh=TVuHt=gRwFY@6J8O%tqjC%+Tym^Ca7ERI zd8tAL%}z+~G$LCp&(OCsy3(Hdsusw-EzVtDH1c;JwaS}*j9cwz)9-7=DW{~6(3GW_ zQlV-BN_BxVMmSjZ;g9CnqI%&eTuPl%*lF4Fdm~mzpQ)(bNVz6PStmdVIot;zsfu2* zu8^{32DEjkXgpG&@jK_UTaaFXY6F}-W5KL$v)>N*!-S6 zMxab6k!PL}$UoC!%)LhHV$47eM6~0{A@LR?{04G94>SVb<}*@9Fr8W|-7WOaF5R3b zk-sMGZF05!M-$bI$$hhH^tr!Fy$r**%uHoY*S7WE8t*h=1&-=uQ&P9Flrd^osPP0YYj%)o{1gJ-cc!o{t^7(Ja2c=P;+7ww>1InXI)IBb;-PdP32Z=`Us?Hm4ocmc6sjeHO?|^25u0no!sC>VjUIH@*Qv-67NV$YC&2mQDZ<#Uq z4hUVUn%NSpX`D19+d>Nq2LEA?&jxP|<8a;sk2tsLt&I({)Dcqn<)vW_N;~&?qR3>R zC7(fhQkb{?3R=w4Z5QC6VS*`?CBp14?JcpNmwY7use-C*Im>#@w9NLGA6%+KqJ&#b zZvb{dDqb z2P5z9_G5z|4Vx56s)!jlcw7g#rWE{X-+n3WESO^SB_D^tCukX^tK% zmT^PF5&G&LlN+}4YZWP~i7IEniSluzi@x&@)N_wMcUyusbZ##X@&EC4fjWBef{4@5 z_DU@+$C*JfD*%nv_M^~yn3F`A#kKos&#PU~3;MC_X+=;>Oww8Rf(57HE)=0rMnS!k-QCNp&4xdRH@juesF@xuF2YY z4#`5s4UwmpZq^-5#vxX345}WtV>t*(wrn{|ZsXSuaoDR>{oh=@bO7>F!5FPQ$)qrr zQzcQM;?sYxe!IljTGDLYvThx_Md1Dl(b_VL+QbF(G*)}RpJoY%OCt3C!tW&h6TgG( zvhx22)>!o+?e6^67KQBF#6lqb4An+g6Gng5w{ZB8ECEDVK~5E$wrWXulYGL-eosxQ zA}_p@uhB74a7C`j)Q^`AmS>Kor?q@GkTk0(|CF6yE+pLpmEIhDA4<_7dQwIl->d~v z5CuC6Lqb&vJ72f)sSsdiG~XalVmq zRT~-#_}aP0)^|@&ZcsIy=lw~3maJX3ejLE6Qexu)3v^XmElV#YhKF>h@gH-L?7jeH z|Dr_ay}0#>o_zVowb*I_hHsty1HA zNV&g`Dri~k35SaBf21q&Ki_xxKih#qcwN+Ug5l2*1Pgt6ECpS^g&B}&cA4K9QLbu@viMp@;{iJ09x z85pV}shSo}z__^YztGsd^Ti7@b^kHXL-{8dE`8wzcY;fdw`N&>Kjg)W)5DD5PHyg$ z7)ID8`|c*koDYLL85lY=4(D&v?QZh?Q1>bi``pEW@DTeB!yFf(I7GjDYVkB;lII zZ>?RQ-@VD14K6UO_Q$sG3V|e8Q|?Yo>OG~Z(iXXOtD@+odG9gQejtT3kTR<4BGOjx zJ>OfM5%$`Qi`3|E4JkYhJq%>0;d=r$HaccEr9IVd*v7cba%NX!031IW8EDnd#!w}b z-^SQ@(1sTXQFIMBuI72o;Q3!zUZHr|6uO-=2ge@I}2Sf?HQ5+-qy1jEQ`Ol7o*9Y zDV>kgbW~Z5aqC<{^+=-v%4B68pryUS`bH1=VB zaSFi(vklUo>iVuN_Cri^R}0M!LYAbDJE^Ril@%3xqrOLC?0%hyx5njtL9$uRpQ9Yh zZ(f(?CK=3`2}#p@gab1wV}zBp|7#tf&7ZP7&`j~vCQ{to(I$uUO>F)}_dek-KlCbk zUbax>0XAyn?T3g;u6G^XI2!uf=Qhz;()v_{MmB<&t00o3`hR;V98AEmoEoY z!*2I-D)6~1EDkc%a(gsjmy05W^=1>evAX6uP#$oC4;67ts9HFkKGTer0e z46drEoC>&DBj-D>^F7-1`pw&!rr0raGvvfG7W1vi6;dMhOuk!P`H1rbrjgLRb4~E0 zQ=sFHJqx$`dtr0@vTe&vu__%iI2omkD-VS>SlRco3dDcFl_D0usrBm3KqZyXJ7bFl zy6ZPNJFVRE=I&Rlo$*<|{luVUT3bjaGgQX3O3@_8V(oj@2AUAgW(4P6tnL1FGL?IjCgerULeYn96@%#oCmtrC7M`L(`i zyPS-3(nt_@%_{-Z4IamTWY_WXhtUUb@K(VKt@P^- ztdOON@~Vw`Sr&Mfo+Q~+5s5D?tu6g*Ou8A@f@7KtW+h-7i7KQlt`ze<-T97fPv_VV znTqYT$Y||JckHhsnDFh!lyZwZ2O#pqc{It$SL9s#w(+xUA-uh~^^$mvOHz!H?^M(> zAhCTPU0OVKw9Cd@0cWi(*VsPO*>0m13_N{{?(Al+$4ON63RTnkB+j;dy5@BRR4S)% zX(Xc=Px6x0$yT%M-#LEEe@!j)c?Gc!I&%WnE9IXvbb`|<-O&7*Q`UAZw@9ALhwey{ z)pN|;XV*5~ryrfI+mMSLV#Lpx&bnO^Ma6P2UJPmYk11OyRh{!kzDMoG%KPt*B~dk% z(A-UHlp-Bx6@h0(uQ^|I+LyaiP|qf5o1yiO2AM$Iah2_MG*a z)vGkn-Q0PTjA=}Xpwb9-iY)Y+k#XpO$2C?rF|=Db&ugF~IWKu+d$jLkgaujfwG?}N z7S!?QmEScD%yenHeP^Mo$|&`WNwv)=O(Q&5`_ngU(7@C|U z1?7+Yq>JGvc2k0b+Wr`Rx%H9h<1GdTTdlrf30HFX60byDwC{f4`evhLfU~*G&#b7! zZR(}_@%R#%9Q~bKatf~yib>ib^fJ5oiS)DbOoYuGYAa1kz^&)uiOXG$$8}tnI&q2K z$Mgao##XPYZ}z$(yOUI088Nq7UVNiz>2s6Hc&Vj)A;*J8*jCx8w^}tvppk1DZbW5oKq@4U9j#z-5KAhfB!?noXUn_kpPQp_+Lk;WexCJ5@eCy6o{`}6i( zSLwc1r1g5Auu+_FmmH1&2Z4w+Q$Ien1j$sLmN^xrGcLY$FEn&u>!Ogc@iTe3!}+(( zMU9vG%Yr%6Ep1i~X0V`5D3z^Zz7qVmW20gdb8y!{1p4FmskdEVpi6c}*10v|hLD44 zxr=UNs+*LdhvQIm;@0Ue>>wSx^k`o$hONY?mO&y#2kxapxW=PTmzH&d5i?VIW%9@4 z%Ob(AlU2jwt>T5|hFEgyv`e&8%0i$i7U4L%fxg@yR;TXE)G*fHe)}GGiYJAx&zIDx z=5Kl2U$B}u1$6A{&OoM7;Pv|9;>P={pHih}q$I2vEHmuoITK}(Mh4l>RH0TZnN%8Q zrQwBMW4l&xE{9J0)}2ogljMkilE%t$mvytH2dV>y^CJn(o7F1kuZ28*_Ag&W;RD^V1kqEfA+f?S1+r?} zm0A(OhIw{HJRsrz6XN%6jMWGN=XAfp#c=dfbRuo|+r`1e^PYi5ujAMe$71M5j~f$h zBKFxW?uS5!e`IPzx(*)8$2;{oh8kAecQiOA^XQ_gnYqeN!fclk@Yv?OuzkY4j1F%F zWz|vg>)qJ`><1ut4&%Zase8s1L{@mKWq*T)e7=iEbRHxFR{-C-HR5?R`mHX_X;=_& z*>@B3ixUe?4^SH{J>t7`_l8!=iYHxps_-WhsItpz)z5_oA)LPJH+(+xx^`mXOXDz8 z_qCXK)^En^g7k0T-JyKEd9_;1;8n`TRN)nY@-K5?-0}H9|6G#Gy_v)7r*~`-nSs^ zre$Y0_hD7)Xgp_QL(WcQVTi$8wfKzPPS8vKnm5NU%BwY8D&Tmv$o`tL@xxUr%YsOr zrcFzwYU)c=ukvb-qm^R8v@eZ;&kId z#TqEqD`riiudFWl9xKS_cI{f~4mBPV@3}>v3`bdEG?F_eM9pwkYURn|&f`S_zg*O6N0;=rtNZ5bQbn3caX3R2@@YQh)g@orP(7ud+#X@l zkGnGBtAU>rXJ)s55u$o7NS^PwJG^f05IV?448mJe7_pmwXgC zn>(IYbxCSkN^0g2E3751;?e2`>o|IvT7M4CRinealFeylsol$oT27B^im|;LY2E13 zy|4b}O?ZxL7Ko{G`X&|kf*s0M%5rrxnm5KQ-Y>jkpzjjb;Yb%DIp3(diTW^#bBXHn zoM$gvxN6WUMw#GRX=H3JyHCf_(Apx;;8|iwxi?L>^8pdSTEqgOEmyy-PAdGwP zwgS7GUYMAJcYt>mb~RZFska=|?0@bs6dnEAc96#?D;F9M67Pb?^!eF6J7eAf^31N! zEkT05f3fK?&VN6oexy}u;c`2)-XQDY{AV#%gT~ZVhLhE}X&Vrq?_bEY)X@?bCfXfr ze0OA*$=f5#QcQ#`y{#wr1S6^wiK*`P!kV7@gi&GfpPn+uKq~Gu2qw@%6j{IcetU6P z18Ii#^8@LJ5^CUGHoKx)+C>W@r}&#>yy$;jL((1=0b6?lU)m@6lgM`T(#OVqen-)&rB5tDHw51f9|_@3u0 zQUQ^&DFmv7Ox6vm86dglwsSJ<@>6UMT;$yf>(FlOuj7Q7R{K?0PJF^2S&Lgct>pW& z+X>mNgCf^v3~Bp*81E}|O?H3t{hj^-V0Tp6gH25JEFUi@r%rR1N8CPuMDQNe_fNa> zXmm8wxr^PsjxjJicKAYVCwGuPEhMAOw6Dw)yUuZaF3KmY_;`M9+fuCWyWA1i7V}~g zjkwu^5Q5ldZ!S!c&P$H`rngqZ9yc!}>oP8!cCJRwmAw2`O`_!u$If$hIcDoBMteh0 z#~vHq)3V^#LKZ1Atr+HDq=AGp0S7R%<|P=si8StZr?#jSn)w)4qC`Eiw((BBUd*t zY=>{E`qJ9no8!e!NJ)O2{eaYT&0YOGcWm5t%l()(PhHqCfqQ!nTi z`pdav`H{{Oq9`-Yp={sq7&8I1Z_GpSCm-dhqp_S^Zh5(_i4(Lp`l*`YE`fB*52QD} zED{gy@`}<3i)0qkd0NVR*CDMjD0{9d*1Y))%9rGxOB`YsE;HCkgX{^~oKwAWq2*Y7 z@!3YU7E3eD&9RvRd1x))ipbM0s}{RKvXI@vhqf6>S=ad|gJoBa=0~>lyG6PC0tLc{ z{s>GH!U;pC&o_q3-fw;o+Z3l01l(G+^Gr$eu$4b=xryF2p5gdSyc(QYRwc25*n@Cl zfN?#KOOvP(A3VYF9+j85TQ2XqSIk?Q+@>B!qY9&jHl6#e7rxe+=MqvfjP89+Nb4>0 z3h$J_a>(=xpUOa%e%U6RR{7H2eOKLmMN4OwN$-y5-?pGjJT0@yHdm&sn)nuEFDh8N z;dvAO!Fovt8esv+WbRWFVo(m>MVl5xOE-EDaa_@h?~|o}+VOhPV1*U?E0080U#E`R zh!VhKVTyUS5;iTSDlmjJ3!a#vg^9Ov}D_k-mG$WHNPK54tiL0#oE zZ2s}sw{eH^Bn4zghY66o1lIKJ>%>&PxzLvd>w#zFoy$phRGJq4tjO3sXfkzei`s%8 zWM_2hk$~qf3yndWqBox{J?1Ha_w0~bp1?FBzkbekkI!Xg-ZfOCMw;Ad_jq`YQ1)KL z78$3q>!07jtAS!lyRBK;`cztaw~Wy079x9_wP^0Kevxy}QWuL^nP0z;Fek&M{Z)W5 z=`(j$ithR;I+J{YwE~*olne$QZ~&GH9Eu#dGabdCgzn7*-oC#<;xPV5zsHSOr`IQy zat0p|9)rqPU4}+@#=>(rMnn$S9Y|8LaZcU20hsFC&xuqsVrVSSaXpzXp}WSpNAh#8 zy_uaNYWPWeXYQJ`;KyV6xeRYFVB;c+6Iw~9-h03j-Ja++PR)Q^-pE{!$3Xz&rZyLs zUa|$auVOcvF?FTpONNkrf8m(v#Wi8gL>!_Tor!fQ>D3cIlvIpOH{F zhf?h<=DZwzz8NCTClsNn8XC{x;N|pAz7IG*dMffrK${Y(_tuU*$B7B*==JR%#tS}I zTwA#%WKQ*aOj~M2jRh{ekeo=w+LXzvMOtvHeoe?OyWhe$bHNIljG;ORNs&$ks7~Qq z!?~W)6JfzGn@fyRT@z^`_rd6Y3q#gy>zI*0u7c8&72ermRDAKrUv|G(I#VHB*47rJKnF81ehm!DB)jT|$>0ad4fLxc7YX_@|P9@aRe( zld7LdlMuTDyVd;1#d>p+XwdS?H|H*UPK|*oF$1kW5q+)42onhQ!u5KE zv#={o55UYl(3YAKelU4=rEYj>CYDs;+G-S+_S^4cqQ^ph?#jP#>nfUoWtF3 zJ?dzo(il@uAKDL@7jBfJiXQZN2_U)1Kgi-QMFCC)Tm7tkgi7PKriS^)2PnkPccv4< z&{*3p)ES0Lr>^+Uzgd5Mfft&1P7+jnxS3j1kPfbG8cnFY?(X)6r_A2+Ek-pw#sU^3 zUV&+gDbyJ|Q(LdKX*>2jxyRn5(#?H>gNCw9lE)t@d{#6;wwd$eWp)MbN;OTA<_u7f z*|@cH6?*cm&}sfgG$@l3v5(58YoxqL35d{sh|mj{;e-s0y0fq#sFOG^P>T&iUr;rS zY2F9OO|fKlCP>fH5-U8ljbk*}pJ`UC&lb@wO2Q^5BLi*6P3&asFY!kWQ`xm{n>)(Q z#j5fGA9Ud#>;nY2gP_cngx_?Vbw=gH;A;6>ZFaKf&+}69uQbasR@zosDQG2ajwOPO zn2TE>ztWIAPz)zr-^yP6RPVm)K|_C#JB7wr$Qwn{6`ea&8pXcS?P(r?FtKqejhPTW zXb}@Xb#(K0uwQm5)Cw>d|A4I|w@$dn!JR`k0LPl;QkZwX zBvwfJHQLLb!OMk3!gYG3mybU3=j~hPbLD`^>NIWmWd1_2jocq8KT%Ko(x@cdDK0>a z@@g4V*{$f$g1t9`W0cS<8WXBB0Z$78!;QDB!5mEO*~y*mSXX>PrV1@YHLTu<5W1nC z%%w)0&mk3JmB_`73Fkp7{XFik!We!D+^YSx$CeZ&tL8W4x%gJr;%-ZGYa&QxTy42Q z+59{bir`h^443bz91(NkI<|aFD083iB^S!Qem_V$(rYL2(n+h!L4gl+02;FdFxtbq zR(6S%l9sYU22Kwp8@-okA$__}@vpNJ_CuD7qzb1%oLJ9ROz(e5Ys=cQcqyXu2*KsiX5U(z`4t&uldaY&Yrl$zU*0y15l~hlVja{5F6!|5JYUop z7(Zo~@ft5ST8UFqGI)1uHwXM1Dg&lA=>4kCwSE6g_dyf_Jy<;RdQ7TznT7Oq?gM9Z zpu->&N}VIky4AE&5afM!QcIs|i@8#*p)n;6L_fO&DqnPR9S~`S+3}ul)YYFe*;7Y9 zA`PU8$nyk-yuDL;S4e6eN6Xn`i!Yx6peM+7+6CPFijj)*GHRO|yt1Mrmi;kTQ?(ebWEIJ1t)3-4ZAFfw?-R==>WVePHy zv<;T3w8w61CMjBLyX8g%Fdw6izF<8NH^~4KputRoK7gP%qr6ier2Cl0bd$+A;{)5i z<-u+>e_lRbB^yFnsnJhRig?cT@{h&#mVv}sya^SJEQJP&`Zk*b0DPpMqma;AEgIkH#w@%=v>-C$ z8UY|Jhd6+;%bd(ae=hw<5q{q-xn&k4FKX5u zJzL#MBkXM6%r#@-2E1mO*H&I6sFS{Dn|cToDhn14H93fc{2= zyltPoYqX;R?Vz@=P2y1ojnX}f-D2r0-T-lw9OpR1fP1I!WGB@E{FOSpKEcu-_feBD zxJ3uLi1#l{Y9Z2&k&gxc)qyf_ta$k8%&j1YT6_<*dUof=QJm|uW%RZ%uTCCrz>jcR0~O33C`vhsI(ExH%_s7889!;U=5<$m@r;u}bV+oi z{UL&dgC(#<(@GbM-f0ov=UU=IIrWECwUgM`y-nEIjxrRSvSZ(Bv*b&&gj}!pOVvLF z;JJVLbr{>vRig#3y)h3P%XA1M&ggdjd5~@^n%H`*DStWf`j4b8{_4lQu>|7W#L_vG z(^Vx-maF1I`_)?H>GX;u9SG*}XCQxfz;ft|3W;WA;_w9yP(`_aNg8}@nD=PC^_p-t zi>SGA#XXJ2T1nLQx24N#vmbQ)svnJ&8_@oX-%mz&Ta?klwVpQ&oxYb@pkL1`(LWmT z&Gbr!n zT`3oXP0yS)PI0)!Mp))#z_QcC{0_jSJNg>8mNN81gr58=ND*T#o~UG%YJKLsKc&^R zwcYk>0hr-ZKBk2MUD9JevJ<_Pcvh^YYjXqyfEW`Tbg6@{IZS$1gn>{{63omUjiBL# z;WB$}Z(Uh_U-)n@`Rn`LT;%zyxfuEhy+SopB`9S85QwieA760U{-DWSi}$omR#$Wz z!4LjPt^f35|K{*9zbeHTp!v6k5h%s~w9^r+u)6-@a)u7?vDQw| zkJZKJ{p#0)$%tJ`rbfO8P1G-I;x+0YeFp7acv8@j@*1F{qG?p|yYc;RZC%jxo&j*T zRRkM@Z`y#-t^oI%)PLf^zZ%qFaG-@xhMT1R-?XSzlDJh?QPe(ucOs9s|LTf^8I9dO z)7}X--^1x_U^x;Ua^MJX|T$=q>7<~ZOpNA9(~`SBO|Bf1`qT6N-zHOjo%%nATz+-c zf#Lt#fXc5X{<;60b@?Sx5C{I6QyDr4$zqj-4(rB6R!M;7{lCw?tV!3XH#OpvlRH1m zCW1Qf>c7p?WR>pDbW}5wBKa&ALUva7{rgZ1n09#D35r?mB+gU+u`B?jpz`-NKWs() z$BOj(gt>U+wKb6H<%OzWtG&SV(BIVV4h45c-rKxb#rPj98u{~%j*i8wF6BSi@?9H! zclbXZJeGe-)@#$&sEk*r;SDOvVcp9OfMtKr0)c54W}E+w<^M;+K&q`~5m?a81{Vh? z5IjdO*bzp+z|i$Z9&0o!^3<On)$EcoZBwNNJY8u+d$;Rs2p69tR*kg5=p;T3c zOipugDIX&wR-_hZ@j|uaqE%*)y#~Jfn&|P%qqJG^CG!cFy#3nzYR||lv=`VB0ANfh zc1Z-I3kTl+O~Utmxgoi;1oG5zTb3PgWJ{|FxUS~Ohy|=UCLMllXKW3bAa@e2f5DmK zg#z@wjub{UY$!Va_G`^s_!qdE&ld|l&a_(E3H<7)4I`WR}6hs--lNnX6I7X}g z=HZe$g)4Q`wZGC$%D7~PxtZPSaQ-d>f2o01KFDd?%=J)-<;RWT5t0k%hqivCLbI21 zoDAd`JPmU0Jc+FGTN*PLKf_O+Z*#IAEHI9*I#ogWanBBswo6Anhrm)Bqf2MOX!Zd} z(S)cDW$DKNVP~@?NEh4C+*%+ic#slxkA;g0a`ble4!Fc}-xGqh?!XnL=*rudZz#^jYhZ;C`^YQ8bj;Y_nT zdJN3o?Q-Ck4rG9GZMdaB$m;o8AAunDo)xcwHh48hnM)peD6Z37TO0y7lda(HSVvS; zcsTi1+B;}vGU&29wd@;-B@<>`3%%B zurDS%8DHV4bi=(40U9Vl4a6M1oD9Ayk`-@OR*NzB=m(1+ymXBqP+kvZeR;pn{4}R1Kl?pDzsdDG%vnE5#kx#Q?Mql~e zi`7aLZ~0yZK(y>-4^-E?F(3(55tRPcd|xH+H$D;h?5Yi*Ak$Jl0Gd`Js8w3i{S=dG zDN}!y;3nMB_$)(Ib`0nvk)}WuBUdt1nYdxKN#9bo&UqzQ|IoX?`R)cfhPWA-7C#7R zujA4W7L_jWWwm(pvevUlaDE_!tn@aun3q*do%O@f= za$B<^Pdkrv@(CbGUJk(}g9f>DU5#~3hEA31L?UjsbpAYCHvlgmMC_KXm<=hiuREi< z<%m1GDSxT#-GYvqq`Zt69GN@qoz@MiZbzNM?$>cvYKJ>_ICd=nu{9WujmJWSdL%18 zL=8lQ@!s0>G3bduDdX6i*OCS(G%gC07Vu~M^@fvQ{yFg-8;y|SH7R=lFIZC6lWzNt z%+X_9(t2|RuU+Ta>13_fkN)XH&{W#UjE4Rg{P4g*r(sPS>8r6m*@mt}MaA41ye-17 zxn-b#68zplD;~a98*Y~aPn-H+(Jr?!Q!pMibxV~RU;XyFRpO5_Fr4=<2N1;eWzg%@ z-9j2+L+yw%*5S9*(VN?*0{M{#AoCxh0sj7O`mG#7SVK4}i}xU^$7zsN+$X_js1HMq zaj^C+y%S$Iz3MdX+wpOYzR3VSMh(X9b{GE>91egPTTfvOb#y>P^<+I$_LKBTJE^F& z#{ii~;qt`wbHqRefB^aQ?ykRr)L}9QL^ZrVi;+JGI8MQsLJr7{K2Kc)>;P6v zi`2Wqg51iG>DH?NLszLSH~gPXhWAJ)CAGop^}$Fgp$&Kb zn(0o9tGm@~;r2Fw-HKdX`rYSwl}^I$UECPa&Z)K;AjQiP?8XcL`tc61XUw8E@49LT z)^8?ETI1c{Uho#Eh}O$-j?XWz)*SHzF(Sn`GHJ6OyKQRf0_Kdm(gg<(=b!a$ zWx@Xa7?seEH00`xwyoERLWkP;=-Le=CEIrC1x?=d`{fQIVE ze<%aNtk+YOr}b^MVOlyAcE50j&+_8;)P*~kPyL>AIKJ5O0Z#yYsYIu19#ICIJ7Q8i zYVD2-!oeloh8EoWTNT8rpr3Nlza{Lib3LCH(m@;UJ}avn$r+NOd^U=fi+7$uc_NP5 z;4tFp9iL6i%j&+_h>Q_j3Yqj(zVE|3_rBaRczleoIZD%oP^S@EvI>mKHsVRw38g8B z+-!&Si}LkIaE5*chBTb)!^!XM3?nGq?Y-lkn58zD7)s5SnH6rNzj>D{tTEukzFb(o zZB8q^Xjk3gz8xm(pCv4Z2-{2Un9S(8a$CE@(9*eq)RHowsl{sZ#xucIaITWMi64?* zwB@4D*x~K6MU}e5Erqg!ivXiwO6*$riI)>%Cgkg}*enrZP+_r#A=(Zc4$K-3p-fC2ylT_u zqJ_=bLH_28+_u%<5$n(F1&-9f$|I~~`_E}53JdGC5|%2IuB^|1)=l4aGr*oIVW zZHsvZ$#`jqHU)jkK`>o%^9E--Ur=wa?AK}`0A)%{K6a{FDG3dTPCw!L=R;8NuXlues_`iBqF4!u(VlMQEAvOKj(o4g;Q?BNk+ zUvxIKesl9C1CZkW7qG*ij}qFIazRYN=L$qT7mOQ-nw1%pnDF8%m#)Uf&}OM;c9Kl1 z;l9{wJXo87K6@&8LpaEZTul<(Fz40fX+D6Mp(ARzq* zX$0vmrKFV@q%pvtq#KluAso69kw&DMfdP?*0R#jj#CHwo-tPO}&vCpTp5ytd!_0M^ zvCg&DFV6aTVOvzxKW^C^pLLwyoNORatbVv-A0I5*9$A2-5VYSeJEe(nS#nuJq?FzO zF$EiBA~dz4lI&+7Bip#vn_IZpynNAlnKg=FA%2-Gr#pMn*t9|Xm)p;#JPMci0f!MG zN8>a5N9+;i_rxas4&CaCZ>ozQ#@9Bb99Dwb4eHj9OoUNq>(aD^?_dRJl-ctM7BoiC zj-)xxOQYPJqJ~PCce!88OH7$>i@WX}`uBI~7BQ!`(0i6p(MtYq8AK^J*hd;IitWrs zzm0swUhn=otOuz%b1E_?QP4xVZEbZ`CNOr_5&epi-%hhtgXOr+Sf@S%ueEZF$QsD7 zWzJ@bxUDiQIqweAGi&5_t90rY8TG~%&0s6NnzP1zM@B}nW)F+*oQqtebE?tHS8FfD zHt_oklMi`AAX3u}HnXr8*giY1W;`9{maY=zbYn3fBWMAPnPbw%|wpK_o zlf=BN`yTivG@G*zv}mSTc-C2WdLNc8=cR|LTj1}i+xgR?QH_QA_m5{Lw51;&)wz=_ zmMB54XN-VA3SZuP~b{p2J+SyvhkY?X7_x zbgBENoV1|Xk8;_Np1>Sfv9&tYGwdqon~Mjkb@#E3Bgb#i+RO4bGv=o{g@*# zufmwF~)6y0ntbmKE89bf?T|9wcnS-aU)x& z=cfX#tmbS!@aJmS%zk^Q>>dOM#-qc3bt>99UtO2vzh{ zIf+RtVMLsxj;-tBL+`y5+URzT$jcPzT`Ih#bKm;0Rq`_3ygj@;+h?h+sy8dgBt>U3 zCt1_NXs&&En+pF2^Iz$GtDI^EvmQTI?J~^b<&O(!!%TM=+YYmG>=`sbb!Y!MZLwx@ z2R>~!;jvE1#@qI|v$K;=A^GhwmGDRzTrkfom=8~dD~FM@Pn(4{sO|!DYh|Nh+bf%71{xqNtUT4Cnwczw6?xNu5(!S~AP>4Ox1s?>IF}qg2dQI$&jz$&X zd)7_b?V7J%iJ4p!?RpvhaEeXiokv!`7^buIS#k0AbB5b;N6|-9XURWxNxI9(gp5Az zRBU*KiDBXtYFoN2O=i{%XX@8a<50PO3;gGpPNGLhPXkl>^@{U$VTM6De)q#8{`Z3s zH<5RBWqEPw_X5ahfniX&Jfxh;{p}P`YMXF5DfV6`{U$aExsuIiypq_rwOBEULVnMY>eX2x9V6s z!wnkSiCs^@`1YuRrJ<6p+$px~e$6ZmyWwE0Ops+ctx1h>2@~E1%UAqACg3Px)G~`M zVU*?Y8~}Z76T7=kGu&sW#gvs_FW%Jph**M=q>}incjDLs;m_xvo-^E5#-FuKbty3`|=)9nY1c<3A=Vj=58#v!4b@BIV|X|tBd}5Eco^6 z?9X@j>n6LVux?j{s{j6 zwOdXUdddR&?^up;nP=tGMjBYcK3%6Qv+lFggX79(&>p`)SK<6jcqMED{|E8tY+SKd zi9vd5voeKr*SDMXVZ^Moyxy3J<`8&r)pwYolf7^_LcxLGhO4l})6&r)!*rV;TUzbV zrIh=Ve)vBo9S*7Bd*=$Dk+KiUcM^%`dwuP*f|wApwpN!|C6}>5dxM9Ux1EJkib*Mf zN0F&yp>J*P>BZFVB z>4*47hnLIH9n(6*;W25RCf3y-(?DP|BR{bz$&<8jXyPpVCQOTxqT(HSc|OsH^Uh#s z^>X!Ti3mM!Z%i|xTIS8e$d~FCx&mEVXl_pH)=!__X$_H(bGFZ6eTHB#E#6|W;B`W= zyRMVH>)jv6uKhe)_R#Nh?1Cv%u4C2XZohzNn?5@>(#aO7bZ4f*x_wJQU!Wc4+`MkmBCttf5vm*Jey02fqE*}}+@=mYrs)2IyP3Ips z(R?o7&Bo{vvYG`y(>sRV*(7_kZfbhLb{HeZJuSaPYRuXE{13EXt~kH)?MZPP-$F_O zMbV>|5Su8z$WOauFXk@XPGlLQnxuuL7{T6T-PHn*bu&%d`(AA$t#P8Lm!SR zCkS7`GS<BtsrQR z;b>FFZjZv5mW7`oo4@gbQnTj88^mlgNc2UI-k6VybO_m+m4V}mQF%AK%bN3sUFQYt zv8kIT3o&2kU-EM16fQI;58f$%&>GW8gBtpT-GPviv6j&8LB_57)-K+#gcG>c?y#(} z9vkFqB3euCFUB_h&3Su z24uVWnWJ5a&)I6%yc<}QZ{b3o!2j4G$Qe&I5iE=+;(n5#_{&=L20z!{RVs2w{yeh^ z;uc`wK~;8kYtXdeRB!ILA$>n|q+g&@)oEU&OK5Z;G5$O7M<8_e%*EO;J<4~Gwr6eP zoHirG3PKnFK0E`xDd$yg88Qov_;Utj0wbF97uN5OCml)M|I`?aJX`%#XLL{vfpxxWfmBgI0kR~??`d+|f>-CPs2W3gUSac8I6 zw2eqgrS(xUQK97T1h#WWpXQw&yKsSV3dN%PCRL^5=}&2?Gc+d)Ur9Bg6X!|&-U$T# zYl@HPltLrV0`X~8a{&tM5r{%-mpF$>NQ;y{_x+GANdNuKSlX^4Evy!c^?pPtBw5 z0=8;VvD#5_x_{wDXlD^tSNBoo($C6GioR@pV-REPKRo}*!V$(_%DCw#->uiTu`6>j zll9{vyS8JzF zcQ{-c%Fs^1J!wyj%vO^jj) zGM;kYnVdl@9@7oas_WsnRNUO_@d+wFl{RRgEedV+9OCHOxOCw<-orq8FY#79#KHdY z=kf*k2f!V~Y8Zimuj%48Q*ppvG-bN&04oI)(OY~V8tN%V8{e?^`Z+)iw7F*i+ByBU z_ZQ_{CVynZE`8W1+IEAJ-U)^X76V=Un$UbNvH&xo^-@lzwVLM!!=#k(W12#Uby(_ReFJE&m4$n7(6U7Lq z2s1TVQo}WCk9;m%c&c=WgL!f+*lS>G{zT&btN*TJ;MJqrZ_65#AX3Rq7-9GaD%)Y@ zOb5fxe#gZOGP%cq1^-a#Fxy*oWB!0IZHt05`HXbn}|Vhv^|&mI%Q^ z0yFr_&`Vy3US=LrY2ncX`HsufFCbz%;Ab5`d{juRk>6tQ9f3CZU4nWpeD8Yp5VFXo z_(!XUc`QaRVZp*T{n%sc!3yowry5(D(ju?~x;h3X(&%ENLMs5@gZGcHyNO59`{&bh z2dg$IzBdFEpwB%_r@4CjcCEM-rfiDci?~F5K&U?l2f-mSgeIi7jSqAJ#*5r^_v#tz zQMdLIhdTY{`s2RQm(6+NPqQyTC#oZHCLHLO+)pDLf2|LAG)B(=$T z8T)IYPj+s=I>~KoKFA`ks(9}6t)TPEEgiUo^!C9BR{e()QHukPV7hj@UCu3n-(>ba zGx5K5I5GAKCZiAH<)ECZ`J>dDM#dZwwN% z6pVZpVO|TZCCh}TFds{S5Hyx&fQ_Sq9sbTekqN}_ywIWbkTQ!!k>bI!NE;?`xy2sS zdf&IHwCTTikf4=o?PB}jUZBwFb^UqAsSLnfw^AN1K)kx?)}f-&k0gwm-G3m!)hM!= z%Pt{m^{7jK-OJ(SSq&7#&yOTzM)*O|8lAuiXQDQP+Aw{3At|rsr}@!4O_L)oD-RN2 zuMj5&o`H?Qi`e(_z(-Dw>PJ(0>q1K2yH=5F*IJZJMZCn{+&^2`*f_c4b?i*p&h2{^ zh^1$&MSv;o_Vh1c7;?4A@2fqI6iR7OLULvYw*q!w~4-OymVcX|bLXNu;xB!l;yuz~aX%X1$!K{7{O>67+?~8j-Ix0X%r095* zVrjAh-!wjhKVkQ;5OHdZrn^>gS?sVsp2Cm_wBIVbnIu@AR6_Tv?W)rq>0(8<>#r_O z`GRZ?$f}E@HlHC}Bd6N6^FoB3louM)n(8UU+|~5_S4>PAKC+7!oa-IPYN~fHb6lry zzN6a?OSZeCu((=Ys|FT6NirjnfM~3M4Qe+<7g!v?FJ@emuOR(b4pcn!f2am+@S*aXa znK$d-n%3<2{Dh>3M;rEoW;wlLY2wOVy(XA^Vdq74SRiV;;PYdi4xZNO^Pg{cuOb1I zkmFPJjuCSD6lo)n*B=34N|hhKc1mjR+wVL`;ZPuB*|~4OR<=f#D^Y8v3jhC3?)SlQ zP|O{in9j1KCQ5Pq@&BBLF$55-o3}>yEfIRypb(-|f*k2!jltlq2(=Jj;T8e}EFa8MZbrJ9R4p{uK zGTymBHzl#`<~;{zv+wUAynUzT$?;6TljhkLD43@GLg&?g{t}DW?e-UeVmARGxRWFB z2;9LN;Y7AV=MV22oVe-d2ENc~`_H#O;E?`3k_RSd_yPPM{KE7Yz;q)bG_FHqhGmuY zplK65CGPoS7J5SX7SP+{e>d!}ZlPU2NjZ!a+hgY?2avjTO&n##df#dRLV26(0$2ONvJ(nmF zhK0Pb^7ZPY;-fyV@7+cO+73T{`rKoKn(erhg(vhZf(>_C-i6Uy01Pw|Z#mJ`-uVMs zNj#|?T&D%kdo(6e^0Lm2;snQXhH1Q+9H~8 zeV+YAf!X#>b#iT=qRri}5xO}N_BK_@qRS&nH*)+%dVbJeGm8-7p%if7Rq*PpEaXJ( zI@Idl-!*bxVjL59p47QscGzLGl2bcC=w?R0jgK2VORE2}T=|2!iLM2kh1Jax3Rj_8 z<)>sA1!=1(`{8%PS!P64vNEiv1I43F`idm-%b=5lt`UHdi3~2^PQzLOYh#w-slloDltccVBldH(u#SST_p8` zwr=LvPut&mW$e1X6f{py{H=xhf1t?6 zf;NLD$;Udv8Gmr!E0X4l=cld>i>x&+nFeSGKswSpW1_kNNE;ZP97}Z=U+f&w6k*S` zC`yUEuVy3Uy325tg2PC)C~)UkBT5vV2D7$B2Iz|%U1F>g+P%tn?-jItp~4#XT=|7q zqAU4!bc|bG@lJFD4oBtG^!7tDdQq8?vJ?QNS2bofshiDh*F!sBH_VsRIiqA8ULS>a zqAD2|EyZg0RoPowY&16?mCGhywKk=)dvFqX!9HL~VOZ&@xpX?jvdoVl_sHK3E!0(E zZ`X14r#20y4pZdj$F^M0*{NO7D!${PEO$#=Z!f2lRmo;JGd8Vz^o_iJZKHlDS$W-a zBesWxTHbpkXgyui#ABSFmJbOy!> zInRYhX}!L#8=6g$*%6lAQ!M6=OHO4M((w?x1a5;d6g)I@46c$Z3s>X#>VRYJRTJBv29@KW#B-mmN&LWK#wsH zpe|koMXJjgZ#-lp(lK37Z0K+n>S5#i!0W1@?gx$rh7bMIRlVq=_-(j17_ARyN z?9%{5Cp;TILc5$Ze8Azv;63V(doen?D2PN$(jcx_gg!!V_Z^OZ2Cf@Pn&$m$V0fQp8`T+kgaAo8TB&b zn1F)fmH+mFp*{#p39%9j*C$WyMdhDEOGxRRyv$=Fm7wcZ9>Q)(EIa6|I{=qndsW{R zQBJ_lw(X0|*RFdDLkVvucYtu%%75R}No|pZuA3^^!tBZN>S~eoD{t*K>0H?2OXhJb zC86|8%}Vq4Gk5l$Ml^L|@SEALj?<5#sa7Jq6cbj2LhYQTS~b;(%Dkq?_cH7bE|H-0L_Y*&`6d{mWWYkzQVup?vGb2haJDr6;Fy zU3YR$!-@+(8E)Bj$vOIPFNc1uUJh^{f}*dJ5;1bshbcw&AHCI>Ekx@j;1Ie}6{6DI z+e-dU|NU(Q)17$EvUpYNr9CF^jJh$&*yCk*b903FAOXSLt;cD6^hLgurXWcZM4DHK)<5I%X!Q&9}0|9o@ zXMB#)cDP#pXztaBF6tlI&{)a*aG-F(a_LzT-3d&weB|lC7Pc(@nlWZDq=P+~&CxTk zmH*Mkg|u&bqY)$wgSUVbFsTy5jwKUecG3s&ny>g6>YAyLogX zEu(}*Xh4zW*jrR6Pe2Dt{Nk$fquXx|aV*xit zItpO8QI&UZ*3ZD*UFPu2&ZumV5W0R(h_jvPKpz#9{3Stew~+PXZI^FBdhpHysm3Oq zl7K$nbT0Zv`g&H}EFwCUqBS_ejehgvWzYgMOP16c%zJ;IX6lKfhBFz7b@RS^i8=Z; z3#Vm;LQu}qh1bd?)9N0243pEG8Ko6jPt~YJoHeGcd&hHA_y_w74FD*1ig-Xu+EqIC zs(CYGWOaNPk^M+oUAZ~ToP81DxrU>c8-HJ8MWw4`bH>hGKa7x%!47Ugjz3sp?3Sz z_t#`t<&q(*efwZN*x$$~)iu|Uhi$6B?2t@{ zuxJBiZG|J3CextTWj)Jl^(%M14ct1dv1r2r+n5_!X$GuHD%o?&xiT2-`5=d&xDsKA zy&STq!k5KkAndw$QgJrhGAM>?2H)+eF%v9wd^B~1h=O0H&93+O<~}f(O}$A9+!5-^ zi_Qxy^FuPzj0|hR@iz_imUG%8sTL!1KWGS#ZGCVpgR$g)I(XB;#b7_1#kZa7@G zilvm^P!WxJ6~PkgX0IA@2N+@QIjUTbh83~A8W9%5mpZ&eY6bew{}@=1^*Yj8;5Z~* zRdYym?*y?(xqwpN>FZ{>?whoTrQM_Jj{&M@q-2f1x`v^a{#32hNaxjaYCtqnvkPD^ zjERKz>k2b&vy-J>D@)>Xa0f(YVvC_klz5!Ad4+AioQIkV*7|c=-oQJ_bAx40 zLCwT~sq{QSd1c0T|%dZJ*edlWL~1L5bI}t+KC=U*xOrVVSQ< z-oZ&He~?w`<02O10X|YYLnuM6)ZZDal7-cdc$`7&m4vs!>tD$yw{>=R9jP+E(XhsTaR3Qt7DBZN&{X=7h?O6u|8XJ3d4CyC?g z9=xVAOLO0Kofem@^z_^}jSd@o)$XL>^dNCgzXlnJ>UWVGUZem~5GFn5Fo)(?w`S(K zC$=H&A?_!R?YC)u%lWwEg$#ZeH5i`=sJ_fW80Bt#d)noDj<QQ_U_dNT)0evikj^Pblw>V=po|1| zGFsohK1^2>1MIro%ZE5BXeM(C^R=yZ$RxX#l=vjwfJn8-Bs`DmOCk4js~7!oVih;q z;WXhDfe_cJ-by3wOTvhrU@A=}g#srkSLI{tt&Hi;g%uAfU%{S*9u4@G`!mv=;5ocqGp6|dnB16gNmuuIQuO>+h>W}}gBjS`lt4b!5y_X*%! z!y0U_P?RrXu!yuRh9H*I;`9CQ-|FUmDz#Jgv(6NJshCDiuP$JRwvU(60RUd@ESB(= zjNm+d(U+Yk)GJrO?du_MT!(vDc_Bnh+zia+0a&LC&rh> z#P=Vm*y~jNU`u<~NfH(b)i=oMH)nYPjI%=&ZAJ;hF5HO8y~NtapfudxqrI6y>Y|Gg z&B3o5ghP%=`%-Ou%SpZO6RVJX5A@E%!g<3a_^O-K(WlkWVv#3fqgy`dzP~Wnn2A0E zn0%;J%}q+kx#$v`M4tG2aHQ!)y*IZTPS|*TCrxe9?;G@Tjq5DUa!a%%3#NF@HRIB= zda>ieU8HGkOlmBLL3M{}?x=QbFnH(aVLQ-kRCXcOVt%&Z-orRaC~ep1-T?(8brqSj zq!qd}KD8T(t^PQIWV+PjucU9xsV#4SvQ6Jn4JOrnA!r>|P}v1lmsfDA=-Tb8p3co57JpR$PcJ^SUjzjjXn77cs@^DG#QnaoYqWb+R8D{ z=hCh?HmPv!6>dC)U;z@N!Thm=8!m`W_oGCPn0bbQ6&!s_kw@>AWgN*!g;D~?NYSuF z;yHkqpImwTcXHqycJK7@j~M5cz038|(tIBHObd}(Ox(-MgS^G<(TiNoSkF>%phVh{ zw;7h)ur)qx`B6Le9AT8dkg;@7%1FgCk@_MskI+ZEwik0Ya|c8o&1R`u6A3t6caatp zzc_88FGlWTIKVO(VjFM!R(0~|l5O3WH3CKDMo53~voh_Hh8=E<-yizuWUJtB)8Sg* za0r#m59ufw!M!GtTHpUsEv}1br<_hYe-G;Q(?s4YAy6G!$VEW)93_qNkBVavAG2GJ^N18>9@(D%MU1cGCI zDi&NMf%CxHMucGir7Y|X(K}DtG7!QZ&t`RfN#~G}vtmni=JGXTSfQc3&8OwUZYBzG z);%UgiQTU#P=;rx@?}0ce&_chF*X+hXW98TP;+&v27g)A{ONtF&Ki~EQ7%lKuCdP|R4EO^ot?N|sct9Gqagd3flu9`uHRAEx`kH`+&isgeD z24jnSbep5!O~Lkg8l-N)T#1c9ARYHLNcF_BqF${{;)b-=zKm)#gPjHRKd>a@ll&{w z`%5lSVuXYwe9}5PYrd&M+{YgTS-RT%lXf$bq^Qx%a$)o z^SAJ5?mqnTeV+S z(GVtO+p}cuTcoA@WB-cN(85PJ5*gJ!ROAw=dKY?pGo#(x2b>CZQ;*Y1Bw^#1q+;jO z?nmbfK;myn7=>tPzUZTqdb4 z2S?5mf%;cskC3Ka7y2m?h-{7UwkF&6vY(IY#D<_si+f4f^*_W-kBFvs=?8-JjxLJg zWZ{jlbEM}Ul(_H6AAj0omVm9uf76hmlgvmY6RuX9s_4NXKIUDdz=x4u_%XXW<-OPN z-5v-r;65DI!{*F36kpH^y#dtAWW=Wx9drn0Djv?NbPPr{R3o4 zP^++M=3nhJu{uL3O_uhuKVSWhZ2Jl_)b^w5_f(W_yvXUsPo}%*h%EmC&=Pki!|(FA}Lt~9TQubuxV7jY6O>N4=WQB`Pn(N!Mj2zWY5|T$p|8W^H{tfnwsrs@RNq#dPzj z`7atji<7WoNgyyNwm1GZ!UZ+gl}Cq>pK4^SBqB-DQP=gqU9ct8+US=P&2=>UhnE9y z7_A1r_sUwkOAWsJvJ1y>3m>TK(yGF>%M)^XVU#R_Ahn8k$y; zU70SYlsCoNEUQ<93JH#ycu0?ya=F?aT!_^6JAoLk9K90H7T_Wn6X)-C%tr^+z%Q@b znvIie@KcltrOb-Ti8}NsMDSE(LP1~ObD3<)n5`$cxfPP_txC_SxXQY1=o76Yt~;ba zydMF6W*r5|$UlbSJOzsrE+|nbTElNg9;Wp9B+Gq+)3ZnED2i{MzeGvYjB=y7u?-!e z6xKyP?6vY`G~%?yYB8E8+Q6gqQV0&;v(0__g`s}+3w_Ikhq?F=ytT(>_M^U~ z;~CBPqPRCjMsix3eMaLGQg!&zQ(W;Zi~U$dGmGC>KRm$sf2Lv?%Y(Q@#~MI%#)*-o2FoLU zh2OlIxknW^zYKhw2#wcxR3g-&Tsp&)~c`c%Hnk^K6!J&!XAX0 zmnd|1eT+(sA_L$ENDD4*GrQ{e4EUw3@2i~z@K)|-`7mY9eM(KHeY~>4LN9MhD#unn zld|d`D|gdRl(MSLxy3NGc8Tj<5Hr=?VARDL@d1|AqdnJXgzr}3zJNF)%G5r|S%1;! zn8go94~CueCv1W$!t@(Cl<${*x&S)k5*i2vxqg7ApjK&F42LIl?s*D^N}7Ek!)!l# zrR}cj_3)9wrND7bh7KBQ)C1irPv4g5R)wj1;fkutuMWDcwhcudyn6;u5-u!$4Gm|U znx>dCW+sf%=?l5yu%r~(+J=LYQ84;}s@D~rf@c>}nXTksnT#^2y_Gu%pC(Co4r;5p zDNQnP*jt(u-9p`uR=zw{NWo|03jNy!>3plrIPI(u1Hmhf@>zZ@GC3sHn?rH5-D+bv za^`jr?jCokmyU)&Y@42X`tYujin!#^UT#6jo3?xrNgalwI|Y5}Y|9h86PzQ*RwftRCN_2t>cK3^FSkd!}ed`zBmwI;rKp)tnVy-ZpDJF~C3C z%httgGv=M!N=vem_9;n%VM=V)j+2wb;2CPpdMQ)2|7@SloWZ#n2!w=#{9XBu=W*w_ zm|R~g1lvYVyN}F0N=-UylRH#_sEVJOp61$qSb>e#TZ%3W8b{D3t`Vb^w#q+iWkzt$ ziQiAd%E^7hjXHb#v{tC-`mYhR=PQdnsjd)6ba;?VXv~aNl`5r1C;b!GiS*`gYGR7L`mOU8*pg(GLa zF1aeeWqs2lik}C**8D#3Ii637SGw@H?_{{ZjlX;g4GpeM3G%BeFT}d&$0oQ9szt2k z!3^@$-k@OwZ7q$UL~We#cAb4V9Q1Ndl9=%xTapDnTh{i_bV2LUEPl<6gNTf<;4N9XDEA~h{t zJSYDFUbE@Fdp(%KPM%ckfNJAXmcZz?Nh>O{X}K#^=t%3hBl&RaUA#st;eu``)nx7A z=gC3h%WD>yuakdC>Di;A00wW%7Er*-oI_EOxSVX2>?^qhNS)l(_KIf#IbAOn!?ld= zZPYtv=S5l)?y>()BZ}c|6 zSydl%mP^IwI|OGN?OXYB~VqQjt?c$H%kQj8)QvO|7LG{l-`K`F&P(~ zdNtYcmVb!)b8Un%oA9s0Z>e>*B=T7*@-+mCVcEA@@#SD{@#{+)qMGpC>U5QAJncpW zZoDTcy>GJumq+ZMiCQgRl`;v~c|7oahMKEN9I07SZ}-MVr+k*9FCvNBI1Q>f=8RC{ zVLbXtB5q+ZF$^{uN@I8&H|laP0d71ukp-9E1rAtfbW0bW)>;sZ(tx>{*adyL}*7EV-Mg*1a)D;wZo!Oa9_ zhSoK~)17UtU?HMYu=fEOUj{S_9zLl?I(c7G)Q_C?N1%?YIHl>iR~xa^((}3G)mc zb7ro0oSe!Pz&OvU0=)p}qnyB$<=OrM#>aSKG+3={pSkS4*u*LOhsBz%x22FAc$wGD z^v5|q2cWQ~O@bX+I)kvlop?poDPg*lv|zZ?1yc<~pBpy7_n;Jh=#LS}E@Wo20Mba_ zun!|65LP;@@%LLDLcadUoY$OrC;3x?;WhhDph`&;AG^S^x|V!9Mnt{z^HNoZS&sYj zxYYLs3M_DYwtkr`WK~Lx3ipm~%CNAr&GQ9VlLCf6RBB43Td>%UC9u6(e~88WfU!}P zB}8_w72Ej%XWg%`9^hksw&(QmZ*rInzZ#S{|xv3 z_w5r;pMkyz9!v+)`C-Dh{W~pEi=9j9{&;>vgSLNqdiu_UuB2`Thi)F-O_JLu^iC8K zD3D8Ro_HJYK;z61a=!A$!Xjz)ufI^;F0v&Ifa5 zmsRI#epYKATvcRlfkDw#c4qDPG&cd(3iI^UjU9xyY}{E%Zj>Q zML$r@+CVUTbl-_-s2KaLJG_U7r&ChjVNA&y=per@@R5vOWBX0HA7DNO*QuGFER-Z$ z)(>%WbA#H%8wez1Tt-?V^nM<o**~oKBJI2h-uY&s z+p-0CrU}QvD^?BsG}4di=$A@Iup4iE?k2H#Nq>p^X9W<9kzLz%BPgtW8AnxHAkR+1 zmiYZCSZ$Aw=v)nmc0gQ8L!&c3X!jgZ0;LJdse7=u9lsB?LdeV=oXj5FZB7i1c1%4+ zaFKr0=Lq3HDi@o|WKgY^XK^b!F`fof z?RV{fzN(~$sE&`Y)pDAA|DhRZq~&1zyv--dYcrJf60FcYUvGa#PBaz=c8sSoYZmlQ z0<(F)9?$thEP~q?@H+9Y%(U)59(}>*@trY4^!V9tzqExurc=tO4A^ba!(StIKt8P` zNw`XvlK0ocQj{&`rYnnSkl7=d9>A#N>s56ZL7=J0Dkf;3kU#^8=~F`0=hWrTz;E-` z%6<4_<3zN>HMo-xXtH=J(6_Mq<2rhilTJbXM}ps+F8q|={grt+(i|B7Deg62fM2Os z0qpB^g=1%^f3noH6kMqGSl$C)^iMIOV@MSZaOfPZ8GLie$P>?nhs|7^4U;bQw*%OJ z&_0=IL}|41J*QsObRT^2v4_7Y$VGAVB@!dFX<|5_xdJU3+#x!Ir1{_qwz*Y4)DY0L zZNlMlu$O<{{9TrWsh@h9h&V2M82LP@E|S zTWvrGyQYX^Q{1!Py9Z7O_o7-T@)(owuIh>*g!UVUZb?aj|1*A64qR#~3D}n(ZX~Ls zcVx`%tn*}5rCprjabBj5OO=l@ifF*DN&GlpFk<%v?K|akc{T4_42dnk(5rYmx<}r*oUW5DMSgb z4Ijl5vq7{_B67gf{!P@?Ghzr2qXjYwXp5=EtlQpLg~JS9ma$xMrqAJ8e`R+;mnBOJOw|2#+8H;Tg79aV1{HBSUaS z!2#)0d>a=4Q;TUoVqOEJOwscm8b9M6th9CIekit6H#Mozuc)+rTSB!Tx~Is%Iw9}} zc#gx6|AUvx;O}XI3E#?DFR0bc2GK=$M(1d$(;e6~x?`NSAk_u}oxdF>YL%t4`-8g` zdF*MQAM(?YarDi~=*zYA2WMy+>LM)lmB&M=!R~Tc`Rc)6gP%-V_hwu>SkwCZ zE$t{0FwYfqnNIl4$7_qo8+s!@d^8{$TjOfXBIA5HFK zEwH~deK{dSQIyT)O8+`K1s(rSmN30 z|M`IfMcI>_yk_;FFw6h)`|05+#~g?PYR%4#?w$EPJ_ni50pl`>dH8a**RXuefBpUe zCx#~c1HkJkZL&W;m^ZjQ@ZWBa>`m>*v1ZM!vQ3`&SG#(kCpfUXY**;%ZdfT8F?(Lq zdGbUv@U$PAc_AQkH4Si6~Vzu68#Tw2HNiM!TP^{8AdO!Mn5P+$a*RvU{X+XnZ+yNoVH_%AkZBAk>wwB~kJnaop^$tj8LzhMrvBTy4NP><+Vtzlw$OC;50!9mLV`BvFp?AL@n63Z4&SG2%>I0> z!8@!w-xYS4p3N{Ae~zLpZeljroh{F!J?#sJ1-)fg@ zNL>1>QWYzkAn1_~coaUHnFjbGm`Zr7;bS|{efe^t=U9ro(4By0RX7QBvz*oH zaO%S|T!AW3+;^d)DmFS=0MYOrm?w?Niq~E#&|A&T0kFV+LEz|-^Deo6%w1GpU-c>d z)RepoDsH?TLEZh_LHlbNk6ppFg;Tc_C4-c4i%ru4`uC|Cn^L7`FU!jl&1N05KUm)TR+ z9Y5!idv4F&R#`b%_2O-jPhH8pKJP~I=GUa~6k-4~D8k>Lp1flT9LtWw?BG2@N~k4w z{uCIeH;~zJO0W>Z)iwKS2FgGJ8%u*6QyTLb$`UU>>sNBQ>(B=5@dW)lPd>0g=PBnu zk58m6nsunKz22xO?lB*<9#<48WPJHajw?S9s!qNnSop4B$N5Q9SM4_L z!j>RtnxH_@t~nkJzEqxK;GQ-;n95{W>5kPK8-O$zj_OrAeXzO5TRk=1NrKC^{J_J` zMyZ5LQ&zprJf{TpNPKD>l#6l2IGv1d9{nH=Xt_si7s6NH*6}G+biUsw26JIc8==6j z#@{a#kb&EKe5=|23@tOenm(g=OMx0ocyU|Y677+6@M9+91Ld0TCop>(a4c~fNSyy% z(gkO&qJqWq7ZP+J-j(q!sd_}Ks-|?I%FAeS!Rkk;;e2*J==RCe(+{Cbii@4C^4sg) z{|cOhM(-r9Wx&GBfyby{|zq~U0vRu#j2Df_YJrF%c zaT$}4dp!UvImk)!jWSYZ^YAv6Q} zn(of*$zHSAfkiYZP8T;~2nP;I{}s?vK-v;YjfTv_^?e9LV9Xu*Yj^U5Uk=DCbe($wYT9{jooXDYKR1^G-r4)_ir{6d z0a{#b3f#sucR3}boVj4}K=?lCy2LbKGo&^TW)OU@2qfV+-d`1k7FZc{>GCuukN0uf zhrc8gCM*`8ZoKu_PXx?!+rlb0s6g~~dDu)=gR~Z$K?9UO8J8Q>D3esVz0N-6idS0k z<2~R(O$GXurTeX5V}@Af%kqjIg{l}i1?s%enpxoojnKj=?q^L`VTy$I1{5v>tKd-z zjh=CqWVM`UHc%shT6e%Pgy;!m()`QtPIf!dSS1Df9@GR}PJ&yyM0YO~K!~eyhmp{= zfVHWZsJ3zOs_)Ku6N&n(^^VW+1bDmQa<}*u;U6c~r^By!e(*oAokr)N7*xGKGqHlS z1ujk$FF=6n7J1TOZLY1XgV@<~dqSqGqtX-xsN;Va+BRju(wtA%8GxAwDyfvtI z)4YjlYeeJD1-uu=j)Kp$ z^xU^0d;)C4>skn0>zxf+&xGX%|Lg%{whw7poiI ziorQ_C zuf&MPQ-!Omt4+!=`82P=y~J?MQ63kBS)Lq-QfEqzn&xnfnAB-~sjTQE zDiv|uN1#RuFQ=$nG5g?mG$y^szXKlE&e~k-a4+zcH06K1StVQ zxF#ck5Trpm1nKU+54z8H_TKm0-~Cry?|Ro0GsYZqOgZrq zC7cA2w#}xSJ+ctxjiknjdkU8GY-ZXzm-uQj7$gGL9iB+edRuBB-Bs^^F#+TmuUb_i z*jkbSV^vf;RfWpP^hpSchwvkq(`Y_ZR1mBA8_3hi^QQ_^!Ay(k7O4O7c;QY*$JWA@ zQrlLc)d5P3E1-w~#)P&jHTg@Yaav4z1}+r*!>mTLAC!92Lga9RjI%xeZgPx{d|!J? zwjs6E4Y0)i1iPw}~yIF7O;^k>O0gzAHvQgNl9~^_Ji>7D5O$+q&5=9ArjDOB<&>|VHMmoMlZK}u$_9i0KpR7~l7SeF za*)Y}@+ZB>R*j|`&^~TB03r}eB*KiiyDYU`df?CN^SPzLtnBKAHz;nob+#p73?s}- z{4$4n&=Bwg^RtFdheIE274Q?&mOpbmdE6fK;!V#NwimuA&;1=Vr}Xy(3GYY7OQ}~n zCttYdn5c{V2KX%K*S7^DOf67J^yI)Z?TN&wamw#016cR z;-NPcZu1A|I~E%!!tM)Sx5v$6D=NqLq7QGL1WVh~N0K{!S|Z5S5lmgmnUFqJrvP<2 zStW{4pFUYDq19j)=~JM!vtCzX#?0uTym8a(-36fK) z*9-KUuA$nfe$O#y$_5Mw8E)>*E&Pb1!o}88jXGApNB>ljh-6b3Bd45ac9_X%q-c;A zTt_t(>H@3f2S0$Yk#3AH)!f?BpC7ms$yR&>lhb}15Md4gg)u&4rJd}!06f6L*LnxW zyp$R?xM_2@u;uw;>ni;Xm`%+L98K07_Zi*~?j!k<-pT_lQMqzvK+Xl0jm2_Wn^i33 zKqUIDY(tW{Qh}w%FQ5&z*b0occNgiDb}%>?N?rGnMEpn}9{HgWW`5*fo2+axzLUwr zQ{{l&S*k6UCLh*m6k2qG2fTG4T?CpkW|D?|7iPfaCbcz6=knsW#G{gwkkA3+(DT#< zgCZy7nF2U+-5m#x8U)7A7$Xg8g%&Xt@>%r_Y2Z~Fk|k*V0!PGcR_cS z`&?zn)qI0;ph})N*O-e0RMr1=C2sYQ{$7dxDRU`P^IM?*NXDZ6a~&v0*bRVS#^kR; zfSFi>_Vcm|#@dpdVg2$s$C)(BlB;Urz7{YuO{a|m79iFuqYP^Opq#@lUJ+NF0Ajbq zlzGPkn_0D&f3R9sEFgw3eaM}zr+7|G-2_IGl_AWNpzkmn6AxnnZKN7uY71hsT#2ZP zUnj$=>NOFzP=ILkxeyQtN~WVj?x^XE)T-S#J)=&(^Oi_G^<>Ph$^Sb4k;XHk=}T>M zR-22?mdPCL7Me z7ME){rUu)R-JPA{ z%ua%V31jpUR9<=TKkFLoKDWNUhPRTxWxS(9d;yM?`tjs2u_R}_&W$#jkd z`tB52#WO$FOVoY;`O9tMWu^X(&red3ZKk2AB8o#mTwmYW0s5VbV(=!`gBL$N!=3$H zlDPETu=_1YzQ+|+zXwDx&UnW|DLV(y+|l9kef3z5 zt?0HY+C_dH_NU_xhtq@a+#GD`V{+7>PGlMp6A~ed9EM&T21zP4X1pZzcmf)QrDrA0 zki>_G9zZgiB_KN=qqq#akjtfio~%FbB!-bw-(?xMJ-jS662+%c?Du6cY`V25-9A&X zP~+Qx3bal(?>hsndN0^@s|i5lnO{`@CzMX3V6Ued0p%anTs#WH&EKGTd;YKVMK!(C zB&)9Yss?PCSyjmp2~$eRQZ-%o@GEgmQ1ED$w?guTuY5{0+oWT~CfXe`w5hC?q@S{$ zy(^)OnIj=3Q%hhxPmRXebb$mGPI$7A2QX zvKqiwi^z>lfFT~n`k*P0H^_qL;D7w`)EwksLkCq#4Ly}8 zzv@^k%|C)7_=b4I9}&>VotAau1$&41!Qm%w3F!Bx%p?|V1k0(0-YlT8z(N$Q8k2GA zAXEGkx3*P+Cg{!Ab(|6G%CvyswL5fR+J2SdDaa&gEKxN zMqEuRh#uPGOIZs{GzxrQ12$hCI8HXLuNGbGXjzAf}o^#1vF7?BWZjoGvJOCRil{S_(_3IcPPG95Q1Q zeb*sx_F0goe*e|{#XRRDjH+SJxaB4e2NLLuExs|~ng19*NgRWn*9){ABWuH!u2-0x zM53KQv18xGgq_2cKx*!}DP9i4uL7PYrZC-CgZak7&qm1Be4X-cJB2NS`&>@AEM_xC zoin`1m1*Yly%H+xjFoMXllk>e6veKI#NW_{Y=ep_Mf1iMs6eZa*lvHR zX5{MLWpXppB7&;%uG2;>yYMn=a1Jy|^jp3nDh#W6Y7zexM4fMMuRF|M%?z#T$RrxD z|50V82Ec*kU1! zq$Kx_5${!D{N){xR4=+A#>6rLiIX@{lQ~5pA;7Yl)rC^s&7q&e-={t|cJ9*Gaq5;| z{*nH(ZRY*FXr`jzjLWHvgMXC;J{$hYDtiK8De|0nHBDWpyleZMEFo+io#Y;#28pc==%<%((~~!P(>-&dEMa5nPr;>>K;6q>zxGUanyNz+&y> zd7nW5$)ewHbTh8-#E@Ke`Tc-cl$*)?oAZgzPnrZGG{5Dl@f8NvL5Hs}AAKUS*D0d{ zMfWvDnYc>bBlXeA(;e*FNq2{W+sPW}_;z?fnej~G9^I}Qg9E{qem&e+2Jv5;RxVuS7b7^Q6Qkxnl6SbVh_=q2+y`lCy=|I|^ zIk?3Lrt4{@1t3Fc)E#P1zI=k7o@%lXVCuyTIWY+*7(kd1t^rpt@@B#IY`OgUxCH^V zv@(gLwm>ttJ#79-yb?6<*QT}>KKdq9)STo^Q&#hPEZ5zd#~JAaSj<}$XK&0rlZaAo zz=6<;`?ds(BWTEMJYD_;R(IT7mPtJKDY4*k+!t$q>`dBYwIt^lDr6d1rCT$o;IYBJJpwqVp66dJg_ej;|Z6o z2Lk-0EM|gsKwNSVaoCQLaNEqL*a)bF!r!-Chm}>uX(8kD$d$Vr?3ek1fRkmwPu38i zk#i-e7GT;eKGR260K~+^5EjP#mHNT~BVN8okG%yN_P|;8N_eqK0J8~7-HO=CWp7iy zAEY{HQsXY?^?5@Git>pYsX7VSgSOk8SXXy5e&0H#9}kbAZh@v~VoXmo)$t4lhm$Ey z*<}L*k;DYwXA(f1K^@4M1Hsk-+I&Fg)oRrbz@y2H;rVjjZm|0U^x~--J;?(Ah=v2l zVi1E(L+!x*T&1rP4NA59b816SWXjb}jZ;ntqZOERcp)U>HnBWRPv0;+Mpj18MK4caz=Vu8Fxq@9IKL+r17)lHK@*_UYB2~;~q5d!<|T&6+&scsXWG&7{S(qHck z)BWNl&{6-F5LRp7tdq3CA#QwKQ5}IW`qZ!mP+b~m+MSjaR|YPMvBr)W z!CQ@X^XnZzk4tI_Vb*Kd|7iiFPMCiKZG<*YL1#dH92TjlO?i@wc6w%l_;;h6?3=af zKZi{^U%VW_i3NA8+QOD~m(7w+qtJXj=TmgXooxuPcJ^W=--q&c^xplhTIo{S8E)G) z0H|I=%~btMnSA>14}KzZ__70^G%Z6`zHA?Wz{47J6$6^nfL^-sC991KwU#pFIM0@+ z_c`d+oFnxI_eLOHp~Dl$Su)xZdxY0+@}T7x&<-z+{OD?D-sUY+g*Fq5Bh9OFWRv z1^w_!EsKO!#P-z|5%eZb>XFh%E7a$|m(F-QV-{6L=8LlzHp0(#*c360xvEI$H*t<}tubkv){m;!f-ec zx97pn%nIPIP6JgZ+hDvr#SDC?7KntxdLfAk)CaGNhp#2Yq!xsMkKu=IZf(2wu4R|o z51tj<1@nh9GD8zmMx)Y_>QdoypC;KyPO(1MkmDHT+Dsb@Fn{xg<+l-$)3+6peP#VD z*~s9P+}SmKW7v+={_&n265dMtbe(3#oKjuMPI5>A2dWcl@K4RTWC5ktfWg-OU!>AS64CV0u|Y6k!nR^*`}4r-yHbzcom@poT`q;ngv$m{cKKkG(w zkmu~A;OwJ(lF6JNPVabmOcz1H_S`}JzCoO9OP{Ud$BXjSu_zk~-7!hCi+B+P=j#P~ znCkr1L$_r~}T-!EP{g_{jY!ypCly2z9HrgTCkEO$XBWGum|I-HOEdR^gh zw3s}zHy&i=WD(A)?YQ@c*te_poce30<-Sd8E@83SHbL=H>O3J z1gEO&KJK6@RPxb4pJ!{)K6F6eRS2UJO>xQirhjEX zf1+-6f;@!g&53C=>=9f))rq|lHJ_YSl@Ba00e2xF4eg|-Ilj?tx}dg@SZhVWb5%RL zrVisf?BO78vRM39Hdqpd(azAt>U(LeDut?6>crr@{*}|m3}RQ$oLgM43jd`D2ZjR< z93r3O?;Mh)a49O??90%sgm<@==@`AeWJlv;%ExdjTN>sV%QdGjur&J@B#olsBaoqK z=lLxdB+aF^U5gfiec#OI8b#9|n<_$i)wgC=@O~Fo^$UuIvHN78Yit!z zSE=;QD`11fs9FBC9n zfd{MAyn?)P_E&x+T-L*_`(xd&5X-wPx~t<#3{`M}IaqM2wV%RJNqFTQt|dk{bIF7J zh1FX(M1|@%>Ay;6w!PZO=31LxE}ggK;+ar>b5e^!3q>0>*;W;67#$eUVzlHH9MhlQ z=_Sj*i($x^EGby+okzk(-zt_V&OBX!1CL6&?V165jQD56;0XhHlRNfy9Rka#Nbv5+ z&`>bwv;xknU@b(rP%B?SjM1`^M!97gZ{p5i8Hi%1E$?^j>r>NFK#G$Y&<5E zNmTtfdM&?lEg1}coW@s`t=OsZos3M(=NGHF1(Y#C7}d`}84jD~~UMu)Xq*v=&(`K>QAB^?bRhhvHw%RF8gk?ue;#yvk&9aNiXs5vQ#OmG(YpF52MdvieS<9UA3 zLg-L)J0t)$yV_znLr*cC_dZbHh!2%tN*Ch$p)N$&0I+}QX|%fAvMzNd$jbd=Tg>S# zaH+S_Q&2+B6Vz(cZ#`??2i^wuBKOnwn*TA*8m7 z3SM6$7lQPD@}4aANNG4yr)Hm79~gWbi{wU>2+N5%V6y)zbdMlge-mc`b+~H6vbq@; zuM$jzxZ;rOfg0xXO)?x2I~(5<&r)!=1R=t90{lPF`!airN-g8E z;E{v%J$oQu(@l8IFGXaxyFBs60`1soZ>gd|#ZsHMII;u~Dx9ZIdKre$0WGhatS#I( zkSrRhHXV_`a5JmZFX%H2A|cendm30(dBbk@@eZws@?bc47o2vE-C?^4eBB!d+=i5R zWhB%25!%`aux4iw%FQk`N>D7%EyB7iRn;-TXkU!VBuVnv*?|Gb1OmkC+5zBmnC~Rr zO{HzfWYf}9u;_dRbINZ{?k>oq-mU5>Q76V|HNUV}YDW0+CV(`vhj`WM!gxWb)xH;} zhs9*&K}Ltx)}-)S=8v%r8;9| z7;0b4`Df@&)_-r;7G2#^M^p2KrtR>9rX`OZ(08=0_BIGk2?{BQfUgthzuLxy<~{9u zL_A?wC=;(5)ol4#a%NO3w6bQftfe4W<$u(Y6L}u_^ce0l zeH_H=X?P1^-(MJOB-SH;Wf;l(rRL|K<>gB9hURuo;&DGiQ{$%_v)oEBc1Nir)8u1o z^Xc^u5mgm8O$j!NP<~zcEKDx2-RbV@c4D)Wvl^g`sdnlCS71m%fuNf2texyY_j}Un zY*6>Z2US&P#j`25_!lsSSCH0ktL8Fz&3v>;ts$>CzzM9v3+j{DmAEsy9(35oR=Xj~ z7t;3R2P#oKZB*zE!#8xcnUhUhVO|fr8b_mB6j{i`>}Zvhacta)Dmud%Z7|>%QT~?4 zyJwk)EZn=$x{YE&f3|xF!0O;&?vHX#L4y%$&vP~^v}Cla-C5v6jE!rfKNaA!Pd3g- zejVli*V-on$%2XwEL>!oD6Y@H_t~u3&Gi>A7a;1in_OR8>XY~VbTn};dw1hcWj7j5 zNr$~*EEISC>L;Olp~Otq)@kBbE14BN^PG3D3x1??+VQ$8P8y$1YyD`6f^_v8xoCTn z=^cnQN9ZJE2N>wkTDt?W#lRAie3j+2VS`37b_XG0I48kkG)~aP3vf*|6gX>H4hS-x z9Zt?%wvJXtQC>%8vVS`E;dr0ytE+(aFgS&42p{IpN*w%{6;()XK@E)IJJrGv(4v6s z%&c$TSH}`Z1$&9l=ne@_#I}>twP-gXL7CUvarVZRU7!t{k>1j`7WOtVImb0})(uvNoc*0M@G&HJ@Pr2^PzFz|7e55(2&^X-YyrS;JJ)nKfR$*%eQM|<`E z<12ryg7`c&wY{>*_MDus-MU!RL2CF+4dLNx4j05>LQya3q%y~QrhZXKhY^YF<}_|I zMYr)0#3VcDKrvuFKp?1k!XT&uLq4##t`8B`rTdPP;6we^I142`uNc%dVr`evkUzG; z20BS0Tty0B=jNf7?n{I(c}C#`eD~|y#x-=dF9R$72G$tBATV-qsCDYS!wQdpxp`PQ z8dFHiygI-k%QMLRCe^e50vR{cd4n@u{Nd_2mS-8pX&VPhL?}b|+`nt<=)c@J1J+9s zn4Z(kkwlNS1E-G1iKTlOby1GN;qQb@A7304R)T}H@;u0bueJ}o^fT4}yihM+_>FZP zfo}o4o3`7Ehd*xlQBFt4iINtu8~dBzaA2EHv%Y)4`tt z6Jd!UXja8f(t3AaL?lg_tq9Es+3MSFxEA*_KkNKI-YDcfN@YxW9;JL-Vyi8wEHmx@ z`s1gg_4n!*y>MCP_bf2A@|uICaHyz{R2r z8i%MGl~>t4JTKjTjhDwD&hqUVb1Z@M3;`REX6a^#lZ=OzecOz zN1Be70;w;Sr$`p8s-MV+92(`@ke9;K7Ks1*ixS{)1})R!FuUVJ`>)bCQRrUDY24ax zhq9~_p{!Qlh;E)V$JFLmyNK4;ur9lu8Tdc*`N+$q0Kk@;Usi=A_&9`~xGd*til52|u= zAsa{AJvd@hVQnf5x#uqt5#NGX4Vf={xpNis(=Q$7E1M3iq7Po~`=0@P6+*;yHRvT` ztM6NCefe~0WdmQJL{p5i^DG@YF_XY2pl1KJ{wO8V@*F|c$NRAUFaW)CzvUu?s3ZH_ zfRw4ydkXu%&M@QqUPNLYVJ$k@^UO^(hBJ}XqIGc;G}(TaxS88u#Hw`#c}BtD3;m7ORHDn%A%__ayTd^~K>zJq7!lXs2P+e;T%T?xwYO#{B^mqz#xt;l3;M{f{YEMAP|fu2|5mM;Q8yC$xfDn8T4}^hcMe z0irK-sdoT^PBe7sk7oql>Hk`R|1w-f{aO1;38I=xn+6Ng!~LiCPU+h1?#VGJ_4?O4 z!2jx%E$5ky0@H|uk5p3TL9M5n(*~+P>3Xdi|BgKqw3@ zTz`*(f*VKy@Qkt&cKgGkw6B4MB?JkrAzjk*8jPLB)%pFcLdx~(ikUHP zR>SU>+-5?Mq|T;N)Zt-Ng*tVzuQ5ms&-VVHub+QmQ;tC5D!|>I0p;*0i1sx8Kw&h&4!oX}eAO4-vn+b0yS|&Xc0#{~K zCzL7;0ncU$iJEg@33fzr4y#(NlI;>Gdl7U2Ts16rK@4u7!d3QM? zU6I5O$?1ifqTNyD@hnFZi8j+ax2)m#q(Ekc$FhPfK<7%uuQX=Z7Q4~xtlr`is&RB= zm=IUBC$2$~@tf=3GDM-&Z2F#+{VBe)VflWmJUVdWM+$vDks>y7+{GK+ZJE}bOekzA z`TxAWXlQRtp-MM#c{s zKhiuCMrk1%#WBXXam94z{kE+gGgNvDLaUrMQpij`FHa_p0JNz161M9LJ6+11`t;AY zy{;Z-*u{eLoU&4AxSlBPaH^*l>Gq+e&}(=g-*Z&0wV(0}nian#8o>uGDNE6I5C|L5 zsoAYnh7MAQ98-pj@T=Ps%}u9?#4dXqLMW5r-)%y)S{y_bO4Vz`<`IuxAM@8(W;tw* zhPPbYscOoH);@di`^KN~p`7nUImm9m1bIFWlE^h~f#8J0Nh7(1KPaZ!4Ti00S55O| zd(8vCN@*c5&O&XG=_y!ULn!A?r;EajfSS|5H#pq4|0>u=5FZ(iKNCTHxy?^by(X&|u6iafFEZw=L-QQ)C0Qs>a z(Ot#Rac|OWBBjQ)qeA+Gy$Vu*vSQ0)Nn3i|GPRE0N(+Gg5W)1O*d7Q7+@nDeL9I51 z2J+ycO6Livhf@K%f)zBae#C>HxlPzvIPDIfaUSVvpX|%#+>czjBH#e}?g_jjQBP$Q zwXH>OX4ojoJRUluf~$c=i%1YH0XFOtK`y-ye2&CQJEMNfSa#4s>9!tx4ve@PYNgO5 zc~XEe6@Bf$yD<2#5c?m;2An>T3Z_0(kZ^M@UcLo`8Sz9UNX5w0g@fiLnlw=S~KlD`SS11!mksKdx7L zWDt2iDxR*q&88el0h$XfdC;Lg-AQ$kXN{$7A16~Ep9_>3WkkH;W!ZJc~)67vl zbNT?q0-@#ldqFsG>g&j`1}*{+zLmF~LH{rU?+3l_9TSWo6;;M;x=?!(ilKpI5=@LI zg2_KzSYDLO<%L~-qdaJ@C8gGvM>D-uA&w1AUkGdZ;%=S{2wsp2eILDoOb^G|wAPa9 zJpU>5wih3fMRXzV0-|e;kQjg<>VSXOH|F;>L_K)r%gP117-RU%jZHaMR7z8!BmtY9PqlV9ZMgWnMWy`^aJ>pO-XL6J)9r^G`u zD|LX1q#q9nnwI*F9uB9pwKymng_js|2`%^x8vZT;xe-*`ghq!0WPajOyKM*&e< zMa{GtaJdj?*@9&+ohbGX>eFul*zqAuR;sQX(`V^D^X`jvjc)Ae?@-=nrC=DmNh4oQ zak1;p(6#v67%c$4x5Apj2?f60T+jRPv^T}M*`LHZxxFz)T`Qr)VGZ?{Ui0I~k`iTu z%P})`W@sK5K-f?STN+-X<5eT)BK#vYSs9+$P%GHA<+WPq(E6L-8Hc#gDQ&mNTM{(T zEIl49bYanT#MSFuj4kAl*{$ZjpcL0bA=EZzV6eX*IR(p*R5+;MnkJF#CGe4V} zobV!A7?YZs`rvVv@?KKU47k%9>-(CKJ(I1u6nh0sg;yZG6eWUJjYQa?ukds=pPZ=l z`Sy}fKG91->M7ik%%=fB_^A+9O53BUE}zqcYCyl-i2Ekl0_coxZma6i^K3UNq!TgzR?>4ZQ4xuW3AQ zA@yaQ&yV(nqh4G?2V^4QGr29H_7)Wu7Zb3Vu+A}&ocP0zL)3}*gKCr-q4P34Bt{M~ zm=hP)uM=PIH~)MyXe}zD62OzaBK87DAf0$=MZ_Qq?$lB_aaQ#>z2+w_Rbh;ghU%0M5UsS;-V2+Z%Iyz^sf3`>RF)uAW z@hjXGN*1Qhn?jGX{XOtmt^RIDkSjD};dUJMWyV`>yUOnNoR9GK6l9y3L6%G4HbN%E zS|NoJN@cyG>kX(E$%0dLK>nmyHW>aeSy{d)napc6wm5Vv?!0?+))ZE=Nk>OZrO*v> z``B&dr-Kczx_azF@g%!H)VjQv>9IKZ?DO!(?#gt{95CYXpZcDk z9d%`T`dgSIyLGDWquPeUxx|>1e7yP`Z%xQue7tE}Zy^BL+efsx_X!%iVJ+<$b>az(fLED_q{a z{Z}>VMD06jUw2lR0CJ#{);`;y_Om8H)Y;Xbyk4aacO1ZL& zWevKHx*VurcIA`7sZb=Ty{LMH_LltMgThu z%%nbrBiQ)e!;#3#8eEUV<9P#ciJoC{!*+j+`UsLP(u(+%B9;v!ridfvNcHWP~&PfIbymTF=#Kh43t(}R@+tf_PoV}XXOOmVKj z?v67vx@=c%a%wa*t&C{YE`J&F4Bzd`%)s(8xJG)56?oM(f!Aq4f1(d?RmFKqixrou z=r^Kl5hwsM_XMpWKUMeBgxU7$0CtTi(&uvvRaYk?r#M;im=$d=3KZ;*Z8&c z7s7!(&h^+1ho;qNB$)i;G>)E}hWGAxHNaKvogon1m1D9OdK3Pn`-Ypuz(nC3q?w== zsCHJ1w!E&a_3lYaj|DR>q}i7WeXTkKi~~U_c??r;6*GGsP`2wyA;KKB#<0h&_m({` zb8FASpI*`OW*zT@-!gEMp;t4sCy&kTi~|p~{BUIY&wj58o_BF*syywsh7^Uu=Ypee zDS=0Z<~h$qNpt=L??s1h(#2M+6E~Fz9D6-Ug!v=d!KrJ@AkDnNj7lH!0oO-5pGXiK zQG^*kb;9z7mX9*le=P9)1dYG6KE*tDhGNJe-N&k(_y(pjk{|sgf^$+Z>p>HXG85F zFG0YG-LCc<*;zqqW{Fg3Vof8@9wQ0at%YsMo`K$g)h@?)U1t_6 zf*L0}oosR1dUz!v8N?-)#YTGu@QfMIvwX$zP2j7qzGh&rv*8U*id@Ib5W=hKON9w8 zY`=B`?rE3!0AOEZu>a68R{oev`yfzlKhds$2tEp$S;FFWzXJ>oW$vPJkyxR-`R!y0 z<FF*mZMV!m-|EdU2WXN<725ue(3XA56gBl7zuBt}y%#x1$I z%1(ywgT2+glU0xDc-7YQlxW%5${X|$B2wVC7;DJUvC0ww>K*F8-tUjc-FS@Kz8JA^ zM$tH5AL+p6XjBnabxau_P!UG#NV~&aU3X-{;|n%mpC_h|*Y1F%2YEF+!rnZ2zt9HB zsu*NmbM=w4QfyseG9gqI%2O6ul1a z41ismT8gumeDejFeT!c&^rM)j9~3V_Sk&)AD~*WnuA_xkTezB%LW|q758$(i z0NlXo;QIKkw{bZ~dgR{LC9wkv@y0#v;WVJmVdP@ZD*W-faNySK1{(X}%x)_#`4olF zDVx1vf@xbD_|N?*C+o=~yR+9{$u_Uw0Y^GP3jC;`pKN7!&O|tG;L@o3&~1_axi|Vu zC#p55OsE>ClszCIgjGrQrCd!WpOW;$PG@wCK)_g?HxCC|J}WypkEku{+W@(=l+TMQ zSumlxE_j7XmLLw^fXNQGa8Z_;3^HwV(G8caKMC&DTO6F}(q&&*8s)NvrHxgAPTP-C zRKf0#J^Z!AE_3TYY1NzIkBLt%h(l1YiU3r4q^|4?|#V??C)OhsH#n!6YQ*ic6Ts!r$np~FY#xchEosR#JMDm)tuGJ5ddLHYOxv1 zVw1mqB+Q?E#(<&&WfGNsAI!UGY#}9|887+8HXGA;e4NQzfhm`WP5$@{k}!Vy-D)g_ zQY|_xC|i@!YfFtqPfa@sS2|MtL>w*S>FrG6y<7)p6;u z9o5g+h7tnvrYhjWrPB%If4HZL8Rc7g-~T`=-#&JflP=g1x_{Nch6H22f~x@u!zuW8vew@t8!HX9KG@J@x2^HVq?+S zB+Q&`B45u@zC1o3G4(nkp0n|udY6!7U5xSois*1+GnCcX>N=gi^Y6VP2tY0s3Wg_L zzvBv8BHQNDO?ptmv4WzVM7oy9hzt=PQq!TOr=?Bs3G9>pxG%lbKaIbG zY$qgR%|VZb;156o@s=w@Jhr-7l;otIA9!^NTVAp~=LYre>$@N#qXk9Fa{k(MH_t3C zUySFY(5+SZyH(dKA6eC2*SEOP#FvJwZ`B3~c7GKA!eh@K&N$f(GW6n?Slw9t%;iN0 zQW?C+tA;&LWyG75ub>Z(Jv(HABKY;Og9rGj=xoWSl-#(ANe$srMBba3k)W3nF?C_R zrKFv!w_ipevm_e)+jDwMwP_CL=$n;*YM?zBS2~9)w3>UvW*^p2T z#R&ooBZR2MXAN1is6Ldq@b7b=@4Yij#qw!;9$j-*%;~1 z`RuTTyJdBv5qmSf1Jm-rP>f96Sf9U3MJWqa+7vcJ10RHv!4&P5}(dRC(Rf@K5x;Ay_y`Wi@0&ahP+Z z#HS5eC)xzw!tVXiu%#>UNkX+2?%n9~_2+0!F4u2fY{NaLyEV0N_+0hER8Aerv%%x7 zOW?FMg)Rhv+UqRLudfO~!0d9ph9GS(&+gp6PKR520Wu2P%rk#cc(##0b|2$?;P}4E zmUXZT)StK*ve9I6pk~}{29+$kTlM98Ob|gXg%8I~GJEKdk@RS}c`~~VPp2kN>uKhi zX|*{jWY*WaXr$4d>u^_6Qme<;;%b;B#3e+t7LcV-o*92xHDo|@-VZE$mmCB2heea6 zNMb5ML`-Gr>Up$Upl`4Yui6Q!1y~4kZYX2CmE;efSR-1KP3ZP~eXQ@kn)EdAjsc>LiD>r3EwQKAYYY%T~!v8zTbJVt;$iEj2m7YtGuGmfm><_{f_20{Fw$P5AD zJi1uv(h$Zh|Fc12cy6PIaV`@lx)j*NQKfgAXWKJ{(LPtm`H=HX63dm9KfsZc48$@3 zh^iACmD+O<J*%TJ0HXH~P>XD-^ig%&#kVb}}nKOc={gYIg!3C!ucmm#WN|o%x~8&gy8F|4^$njq;c3sAT5} z^Pixb6XbG#SQUVy@D}Agq_QaV-$&trpMH3=|MTAO?v);Z6K4zJ8A~gjBXMxdt(b@n$w%d{6Np4Pk}m={}*h+b_b!+r9f$ zUA5j%`$}|lP_&~i{~X&tq>O*#YY3_%sDd!`bBI*s#{QWk8OIe7*JX(nt0Q3j@-<&x zZ*R)>#IBS<)8@pwKhYnz{Xu^EuZOgP74a19gj01AK))VvBazvludnqCINF^`HQn8b zmmsLhDqIK8db(WsLurwZG%D$^szST}-w#6mg!VrV0xJz3(xKgEGL0!govBEZ$Zeo? zf2y#lr;Y4tb$f7s)o~F6g528vAh1Ho(*2PC%K~}gs6eH7pO@yJn0(y~h1@_V<@Hj& z6>1B^ABLiRmFRkopLR~90q4{;*K9D$8Ab1b0&u^XV_^sAZsOM}<+J(k|3L z6rn$7;19DV;u%^cq>oLA%HxA{#rh;O8D42w$)jc8W!nuBD|c@C)tOpbESLSy8d{5N1x3_CB3YthgK_01KmC?@ggQ~uyc{fOA zrIR=>`5tekGwxxm-(ttA9)B@i%Bgr5Ya5AJP@TK*y@VkzJYm0$b14=UkZ;SBIsxsA)^wug*QseuM47?bhZ)J_ z(*YDkwIg@QQrL5rAHq694^O4|JHvOa?|1Fhb+U7L**pT2E6M+p8YjVj9RGn>c9!@= zyb8SGLd)aPqStw!z$qxXdnBck3Oq*!2;!44VnqdJ$3AEyLsT^Fiisb|;CapO^SRUw zIWRKAmvI;Fd7W>R;$QaC+^r+Rj)~1O@C*&|2l|GKm>t*n1T#>| z5q(&;Sf=r8fUz#93n*YJt60gIaDD!^WL7&P)#Cqn*`UDYVsQ!m-iK*Q-E^^{*Hm}U zXxpox`lxFF2V{0OQpnibN4W=Zju0F1NcxfXB|3dY7XcfH(i+tI_ZPjM@zGFIBfy6V zM2cM8Y%%#eA?$3o9?*}D9@zr!RHIynPtV(L-+D$cF^Bl+7b?eM3HdI5A@K(yWR2u* z_M~7j0=+7X>;&tN!xxmgHU)KoVad}f)?+4GJ-4RyVVj1yIq0Q;IR5WkyA!M?n^j_B z;%uYwyKBf<09F?l7lXGre*5rN;Q32@jZUz#Iv|x1N9f>Wd#mHmnp@hccT)=8$O(#{ zk8Ki3r<4_!eS$0Ve+W%nl^C!3JEOX?0!`A4qn`nnlLZ(~ofFc#I7=!uTHI{&7!URT zwa4EDne}`91N{B{wT4a()!TVG13Jbcpi2KmrI-UuRc)v`p`HEOEGO5F`vXysTM9*0 z@augIRoYGOQ0P&AFADkeO%~9l%7PR{hJ7Fc{&#-mcP4Hro{6g)U46ZB*sYJrzd8iKq@o#$_&`1hQq5mNLt z!_JU0?&TW9Le;fcUW5u4>|aSu*=S7r8Kvpt#XectYo;?YlK=qd`{jqC0zuw=F(>`t z!3cd2VeV`O%AOBDMk4w&sdZ;IT!eV*;$>uIm;I#Ec`^Tpx?h02*VAJcSH+R>Y`k*_ zB*=9HlFV)&lKqbceB|-HNZYlm-KQ<5a4?I}Ie(xkM#{-_GPgueRIJMD8@2KIg{xsd zTqGmoi?a*RB|~VW0N23qSPUqMZiZU!M2@p6*70O>%9cYCod?Fa;b~&lgVH(4LaqZ) z_^!+${E~zPIp*(b1Z@AFPcnNRyzGln+3H7 z_6Khu9a*_1b$dN%aqoyu$_zL8irCf^|DUT@sBKU0La2cn`}v83lNXzHZEY|kotun9 zrwt|&R$z!xhSr9RbD;?GEGeM<_Qsm` zcs5ZpRWuLJ#&kMwDstyv%31SYN@chMDjcsoI`gHY19n*FX ziSw2_@1%yJ>_-6CWM#v}!`#G&P~p{Xoioysft?=u8lP%ZZD&Sr=PeiH4+kAVVrQ6)oAWkyCe?$7RR zy;M!T9>Zwd1o{GVx(1sb=6j6gN!gW0>#(^Qao;50(|#WPqxnmtWJ8!jwjU=Ky=R5Z z)wm+H{hW0)ap~h@Z@#_n)N>n)ksTB%CUBeoH7#c4 zxxWCv2;B)mr}S<-l*=i^zwC_{LTUD}z-JZpy{`6)V)V4zRXbVQ>{6PV&mo*PYkr;) z*U~k)W3{G#{`@eP(DU&U4$Jl8w89mDxLW1aCEY+w&{JvLk&?z3Z1BkF0JmJ!P_dEx zDkfoM!N0Unm9*J|2ZsO<=F&PnEO#aiB9c8K8W9jUC{nEdT<-R#+#d4ItXh9LB^(m` z!x;ZRo+_M9WxKcPKQl{W>E9r^LDX#yFL5$YmE z0Y9ZI84M{H?&oFKt}^2QHyaifKyfwGzmP3erlYMtG3%$s+j8yb$_J-^6QCgrRYE@u zhF%K5y_EOr+pwK)aE0DVq_rUyy%8Jm~`t>B8= zAFT98*7KrNnBqYNi_ATvjb6G&M!Ybxj51VCmyFT7gUbQM(=|!2R*L;@&bw5zDWRK> z;Ne&1Pj2+wYe{c?6oNl{)7Fb{7-xME_tssLFpVI`fx0U~xA11a(l4V2ekQXj-4^qe z7j|xI1DK~I;zv)1`{{HPPJw}umXZj=+&2(krlnjtqQ0$iNg;m_VJC8P)>D&;tNfN- z_^JJ=$@v9_n?bp4lis(DOk2AX7ZH1MGH)X^3O}^_52*>#3`GV|F>V>e`erPUA*t<> zj5GRjOsfY(RDj*9al{iCxf+tAzDFe=Ik=`ZVNmxo31qp1lQ=rjGfLW6KYK`IYRzyy zjkL5Zp!mx_^ywa+)|o3#bicP#J{)MKNHVP$P#I8b!|r(UBkK$H zF|Q|)qMdT%rUtu+vR>hUo=oKi>^E5r-{y1yV?99QnfVCvPQ2lfHBk?lpOy)8WQ zh4Nb!;~TG;nCWSuJ(w$qvJRn%)v z)_jaVsh5x;sJ2^e07gxb=Nu%k3u(8N;xxSjO7tscc8zcDTh5E#H2IX`JDI>{gdQk+ zehqKud@uT0&qKAf8*l;wTv|7eX^`8yT^~_D{YC0Yct2t`dL9aIouk#UF63MO=HDOw zOAPVsuFo4`(^iuqkV?T1jH{Zr5_PN}G$pCoifB*BSrMaPyLNZfvAi~<|0A`?P5NoG zCgrsiZBhlK^}a)Kb1^?~W5b@^QBPHj%Ed6To~wpn>$v=!6QEojv#E(IBvJ2-_-q@j ztkRN=-1Fl9t>y+=U}9t9u_ijmzCSqrD2O|Yzm*wRZI=@4bp-iI%25OTG0 zQ&Zi`a@BF(L7!Z1gH5RjY9nu(A|SOCLQ8EWCiZ;8h(#nz6#b0io#!Zd__{2ec}diL zK2g#Ty!RV0BG>UFuE#s4He6U{wky_b{}58IxWX@>M2}ASg~hgG7n8JShm86}2#s#a zbt^NK$nneN*;rM#$rjziC`!Q|1f%oFg7MAPjaW)#W?LGcBJJxA);NPlhf9wB07O|=VOsJQR+9`?~)PBDBo2&;~YfTle_*MN=Hp(g!qhzZxEeP zk$guM-|ez&hIYPHgwNSa?J7uGotsSuL%1PD_OSDr?R;?})<;png8ck%s)=@Xs>76o z2YjJ+;Ia7hhy<@_y#@}7I|+UY{~ZNBHkEv&6I z%Gl?SSgqOJdxx7q%Ms9zM@Z5-bi5DV(M;(D`wi}O?uQ%j6oM+n`)?!PuL*fC@CU9* z){1(b@UkT@-Z$H|a(}6YLmhgbD;Awi#+?I#$n+J50Slr4{PK5;*JBy%333%ecb znaE9vvX2!4dFox(8ZDJ2mH#y|x~T6lEZnYNV9^a>#tq~cS^OtXHtl??y4mu7j}SAV zU+WDQJ3t}h`Ef!nWp*S{J?l^4ZE!&z;foY&EPt_rU@t@4;Ke{{MKBA@3N)< z?mS{hcwK7LN&w}1ix!b3ECf@#<=&rcREB@!$6r;Sa60dwcLo1Bxy0Cu?^64WxPPl6 zrmCU&cO${S4tB0B%7cYPo-gIXH+~!?L|7@mC9#^*TZ{zh zacgkTl}Yvq6k9*>OVvc~=%` z&;a$)s-u=|DVzdOP%SR__o?>3=kVEEa+;Z3Q|ek9N1Jl-`Tp~N7rXowEPcQ`7Gw1= zO!@gg3c1cVrT4R_=gUMBu1(*uAlzwto9TjZaWa%|LT#}9BSTqdd*;)3+zi^Hg-e>l z%a3T3Kd3Ekiz?>8`|hZYNx@dKET($xJ>c2EYwV411YB`v*w12UQkcWWJ+*@;lk+5@ zr&vCKm%CxfCzR9;Im#ePB3gnhy#hGrc?f|LZ${ zN_;b|*x1`b3*HXiav#=Coe(lKXtL>7 zke_)^3dJKtglZ)}-)3tn5{<~p>|Na%YWXinyAaqxjlJXgmu7la|C!osJ#1KQjL0gt z4W=!5hiuim>$xIAc3r_~i5c_|8(FU;=2lk++?`D)d!od`QhhaLbTUvNPc#KfAO4G4 zxbyiTKh7aL4U#35;6-vb%(UM9CF9wRuEzr$M&0GU|C~G(Vr}*5^Gw-<;dVva`FTx> zMZXDLAO4T`5Q~mns#6@KL8stCS1L0_HLK>h<~?34FLs!a+}bkhX0>k;_xEeBTQmGH zkCjrio&Yfl_~LHF+Rzh|5V@9Ctzi+|l9oinG!(?AV#Zqxa7( zx2mkF!mv{960){~Ytp>tj_F@~2>Njd{Q6zbTI#z_xp}YtuHXCXdA`f4ITguypmWa6 z26b(P&3q5Z6Fb5t_pB?xxHrlEJ&9uQ?9=x&ZyKst{WB1s1h_KNM_DoRMnJAv`L#5n zztYi4b!-F*v`B}9^?k%o?= z?kLFjxvhQNZOLo}^~>gaB!@f#G#bQQSqNAOeQ5g~9SW+flG+z8;2&yy z_bVtT_a*#-SgOg%<8dg3$xJLj-a(ipY4EB&%i5H-2vG5SbfWF?dee#PXiF>0i!Rmq zJ8mYZ)I<}nZ-3h(&LMoQG*B-FuXTfm3uv?K&&P zLs0j!_;yGl!_dx2XQ@0nSqWU8SN!{3=WKL1D^YW?)8im<14OxmCb$d*7k~ofhg5)* zrYbs~t(PDJ_Ogu1xeC1q7jr8T%b3J5#ngwC6GQLZqs6_F_M|uWgQaateMzhTuSJ|q z0EhG7-j+VU-h&5vIyy>&G3PKslM?4Nmv&>Bz0>&QAgfDjtQk_AVV!UNNwqI~igzP> zR{hb#8+^yof5aWx=XN@cHTA`4@GyPK=G?H$9Hs8fkFe{$j-^xz0gqJnn~wHyU4LD>(#otfC5jHNoW!g`6Q?^_%F zMIjFvIT_jaCSV5%r!Z0shbnxRYli66$6wQTq+F>biGK(4Ov4qVoK}$yx#Pd{mBhwM zzmJw56!6g1Gu2c>A(@QAyfD3?`e3{959Clao=Ce1LwW=R1C7``UzTSHnuWVGqqzCw~)g#_2^do1GUoDjT*%H+@WO{YyAk=0P zvuCP*>H7C=osiD`Y5k;NRJcJ5L?c|;MWM2F`w=b=>6&2MQ0aGM=#&P?++#;(cW`i@ zVLzUCZWb{FKZ!>ibdGza4(uE>;koxw>&Wj3?H0sM5h71u@4T5-y0qI%-`7I}$hl2| z$`~^eo1|CR<|GKc=nLK$^z=%VnIEU7G5`@r}$z-Y|sgCU~QoEoJ0;2f4n(aWK#xRH* zr&7M{XbKpM3!-3W(h@LW_{++SG*y&lroBW1mEGTm*i5sAu^U_D_f&r9hm(5$?TH<+{%*zF`4#@KQ`=}M;b%}%j z#l0z~zPA(_SpYi6bDB<<9ZM+PbNX3+HJGyMTF8y}62wJD^_W|sa>SC6enB-rM}u{e z&I+lcGE<-awV@?y!z|Rb~pRM5GX}q#M zoAIe2yU);UT*Jggc`2%P&V=8_@fc`U<1g;5D(VMBS*LSyljLbu-5G(8EU+}^`aR0m zcG02=G35{Xe7vv;+jia~wseX`xDr_*3t;i#8`%}bp`bBm6dg9j^59Jpo-0=_4-{o2bqb5U z+=b@5#tH-vFQ4heH-@-+!PU%W{F3;v-puCMa`U&*6tw3s;DFlQ7~fQSnoQ_Qlwzy_u7?;Tm&r6P7~Bi*C7mNB>rQaJX`drlcJ2<~9-(1rWTwv&fk(3|1vCHwpwC`Wkh zKB_fk+$+VR@!tPkk;KN^kX7L;@T5)VmB<1)ww{KET7pnxTCR*DdSaeJ(D3Z^ce&ej z0)bICLV?ou00&P%_NdGeO+pk`WGO2JW;~W9yW!}VdYbX&bwMa04!^ap- ztqJeu*eT63weylVK}onY5$4ML!rb#Ez?c1(rnuHh>d9l4Tu;#G)VfU=OXhvg%BjSU z_-ZOEi&8jm=28aUeOXvSh6$Y|I@`8AKnsXpx|hQU-9K^c@8ny>6?1I+@=~Nnqk)Z; zJ>ib)-j4TW4%E0+z9e5j37-gs4uj?8Ggu~JO5fjM$Pk$mJYDNh{PH_ehp67yLLu0l zfSxr|-9+lJFQqZS<8VXd#Kk=uhXt67KaPm}?4z7i=}Y)XQ*M(y2ghJ^X2Tz{%BvA( zHzHb^ag$ur1l|<{m6Ia+lkcA`{X)9)9S8eckVeH7(7N}Y2S>U5yqK@0p5=%~jevxW z@$H}PosD;ME-o8t9w`{@e|Zy_!Lr)Lo zeMI)$`#pY=y3Gq=UkkA2!LuLs_H#YO_KPF}KcuLIkn0-V4jwPL3{u^5Q4IcLo5@|uM> zp;kk7=?C-I@!t~Rs|trXR`Y!=hwSMX$<<)UxU+bmSRI8nUA#6_Wa~rN024a@$dIqzR0Uur_ zRWkGcs4mF+GD3_5^gQXGnNChJx_LdDRr44m(|kPnNYLpR-}=v*Lsu06tQe z;3OZKx!XIf^6t{nD&VfhXPz~qT1~lBA{0^Y{g3xK#!z)7H9MQ=9v=`={ry0)i~6Kj zjX=P_Nn(96nEKulb#yU5k%zqG=jBB1MDI0!!-KO~aPDE(A2!}N~>&p-5v zCoOU(irdZPN2Z$)YLX9k=abP<8?6cnu$a6ik+Lc zW@lR8x1yPw#wv8Mpmw0={0^-eD>B6HWpT@J7SYP<-I7D;Oh{U0jtG(#}pDM|19 zF0OR-dj%MD==s`I@}OW}ihEqd#2R~8qLRfR_XColA)0~wJ=u^DS8qKpLkw#|H5^BO z*%>7NHGdVwwk<1g>%2!&Op{?)dAMKXN2goAZbsaD!w5wlGr!{($`VWj2f@BCIRv(f zZh2L1P3k>7R{63NfT>sP>UEwx=TE0p%~fE#*B5*_;Wu#4a_Z5GQuJ?63!GR zAu7s8F1qyzVNW{1;;(6HJ>q(Ff|oWCKM4XFAC4U!x)x6>3|#vY#%ShMX8(P~&f^{N z!axT(cYFP1JJeadF`cIg1Z2K-Xit&&k_g}}bW6Bi>7 zeK`9AMt5zbb!P?{-cDjf zFB}*zsap5nrMX%3+lG_=b-c1;W-hl{{yf(kT2tUG3i|YNYrz?H6qaNYtUuS^${N6L z@EC>hz57^*UP#BltaU#I!sj6f;64b8(+K>Y>>=?=`8#wVQF!qyJSg(xlWGw-LEknl zIiT3iMc+Y}{rb&V`yuYF`wfU{oi8$37;t1*D98@w{epYP;H@hq|03Qn*OM`(bT|_H zqLAz%uZauG%&}iO)ocR@1pKh3M=30C-|+JVmrQ1ZfrfwF}G3FEpoPEmb1E5SjW+spw$#Z`F=PG28XQ2{xM6B zlA5Zt=Q`C?wJW&Yru+Ce0EY~$FC0iPi=Ft77@VeM3j*Rh>5IVaTmb{^!As$WXbQ~*I zvAU#W6tN$*b;lU>#7a7AZ@Mbw8s@}sB$@v~DURO<^S{G+qbB#GpU8N6r{)su_x>Vq zy#$1>Q1jgDW_Lh+`O%KB%ghbn-ClSQis?7eV{9p9nh5ao zlaR%m*2jIaqUi2bJP7#ldJwMKVL`IR#_(ET=jIZ3WIce5!5PVZ-55i^?R7>BJl()Q z$10s{eF8R_o$9{tqh41&hOF`?qH8BfI@Kzi(mc+X~vp z-F=`y$T_Jr`+~6TVl;#sk3(ut5i#v+lvw&AE|>lFPsPux&N!_; zMA6wDvXP^Xf(^IYb}#ZCa=HBbVSqx$lZ8m|3XUco%QBUnzCH6~B${-{nSC@t=kl5V zKOeQL0If>FOzv#2LJ%qTYJ7P6hFypR0m2Z4(`*7BjuKXSl!swxg&ds}$G7$-wz}mk zm)|i?chjOMmpp1uz|ar*;?z?`#vUa2pUdG2*Pji=!^SB6jIys$GF0(&WH@Lj*mcP% z69qeS6TjYf71;!}3?VJUS5G=$OiI{R7WppkZo_*ed8nP4Gxb>`Drms>_W@_i{ZAIAG9Yb@SYSdxD}Yt7$$Y@_K+`q3Tw9<()bp8*$`Bq`>4r zl;yVYUHv8-S4e!|iV-2or%J$W5Ul5Y;1(p?ZsuZ{A+9qrtUGpp#G$2>0LjMdmCO#p zAQoPq;MEvh{f`=eDqj@ImH#SnFi=)bBSyzU{@Oy5FIrcqORm?u?m5wWQ(~zP$2gq- zY8@7Ft(Yf!_7G)rGU8ovNh9=YD#W>yl}??Yf-O9Z@XR&w<21|5ts@*^RX3=kQxHKQ zE#hVy0yhs`pFi&`78CatcE<6_F9fO&B)4Agl6bgJ@%}5WG)&|W*)fmX>tp=Rn zGICjOht+$HHDqL%6Sh)yP~CYePV~A1<@b-;9h%2(5&0V%(!s4zG93J5OQ1BxmAeWO zl-_S`=3MONADXmnwUT%YYw|0PtSv{q$~%+9{&a}Q-4eHO+ZPNI1R&$b0@9@FNx;&( zsg9h>rDT zcBha%>m8*JV|z=*q}Z60;4Z?omOKNu`#+#C8C%6oPQn|c@kmmB8?$M zsiSwB(ly$0BqO-_T`x*+3OY3Fk={YQ0`ywu9WYId;&$J1-v@y8YO zDv_?|%y%I4b3gG*mG0`|xV_W4KHaX}{rl?h_s^m8F8uULB6Rvy_ynVj;63$$BU<+e zZJ4~GxX_bx0Uc*IOHEO=m39O#+SFStjODazB#EE}_5D*wBq-F-D;$PZnm#Ihj1r#r zi3D+wgh1N5;}!6VVt&7g5^h3w=6=Y$HN#Efuoos^>7MYOwfkuLv?xlJMOZUUqRa{} zc9oPQ;)V#R@~4kKJo)C?gy0S1<6R9>xZ43vaAo5#OMf&_2bS~wQ^v|+U*ULSfRp$0 zJ$&qV&%>28Mr?iI5I#h2)^Mordn>ma%46E8VFWycPK>X0KUeZUeE7KijfxdT5rNRo z@B8DULdO`D57i18pw{>aUv?c+eH|QH0k_<=u}9LJBL_tKJ|LuIij(R42a0U;-{?&o zUJ3ct9Gps-El~FuNTR>)PCsS5yt%ZYkfYCl8Rp>t01%Ef%d872;tIYm|qn-QB#W#09d%`3x~hOda*e0GOc z2T8#YMC{_6w8e&S-$ArbS#;Fx&eF5Q&kf5$AF=iIRm~|FVg#;ke#|7)>_CCa5Yi+L zS^hVJ8f!L}2-_;S#fcc5i}(qmj)n&X0RVWpJ-wOPHdb}x3<41n&O z4lE$H(u70GfJm*5*HKOAUxih%7pkX8PT~gK*3gdSVCu4_=`iI>d28rwo~1`%^iUg1 zf4I^yAh%$yAylupl}`R-Je2P+Wu#~69iWZ=AYBMad(XX$(|({c|J+*k}tx z^eU9V6K2`G?~(ky#ALVo*?ax!P*}>vuw#f>6CIU7(<=FcOBHD~ zm}rGE*=J#?D!~y?8w<=Rzy2=Ig?cCMb!@{V_ZB!cfvV7udeZ~C>tAG?@f4I;{2)B+ z@4E)Xcq#TH#6yQu8-ZwFSsCpgb#Y3cWcR=%TOzi5kks~o`ok~<4?1V}l3Vwq8tGR0 zy7EG*KJ4!B!zL+*{@24Cliq=9 zn6PAqW6(GU5lhUREU07(8G|4TVxNbK+++#3yB)lyA2Hwp>5z!^dr#`VXj1ije*3~}GNz5vW?$0gwon3N!mT+4JBOm1h!pbaK;%vj3A9SQTs_-=0fE zR&>-3)t+4s80(ycP}Dr;3NP}?bHC>cBprBLyBsmNO$W(6w}a*)^QPxB#OrQA$eF-T zNVx>;#L*f$PW`dGZqCE95DCftU*9%!Q(ntmKa=?L`@nh{NDd9riR338hc~NO1FrbI zabZcPx8i`Ja-QA#F?afe>kjVMPkXUX84@wyB0eH=7dB8{Qw~fthaujhP@N|OW-L-ELDOHZ>E%QzB(EFjEIc?&R zc9%9!ze46*jQ8mi(1gD+7~cE19G+Tqjm->6_Fk$9uI~q7vHi5t_reUv7^DYN7wr|X zv#iEfX`+8na)W<0XEgmDmmwt>(s&``Ky}-Vf5owT2@DQw{J@46_N|#YVY;e>fVC~s zpp?R8Qdh1wQ&f}}Cp_%ptUX@pvjxg`K4Ef%LOp8#%`47bIqIp|vpgD%IF?UWmJ3`# zG)Q6JQc8;GV!x%H{CgP+L*dHbE9SS+0JnL;tdeX?r#awy4*D{61^q0OWl1NJ6*vR^ z3Px+oL-0shk_C2(m*61QH*iIkAv15x{s(*GXI38L`sW2ZzVqT#_e4ErwEnZ!_C$G#*VA0217v4k zE%5yAYCRMj6)N8dTvYX8c;IVsryhN-)#5YsbP>X|v>qDd14CCNaq4B9p_WpS%lxAS zE;J0U15bw&(*`NseFH!*vZlNlA@Ir9qFNj~O@y-Msm>(0p{69|gi&_b0Jc$QG#qLiG5_o$MFS$gd0roL%J zW|7?xe^oheB$){67KiaaX&H(2R-7KS4TQjiWdO%0dXAM`T3x3!!1E#bqgIoaT8k6C z8N9^BNA3khr4C+$8VVc$KOlGiK19gvA}ti;myQ5@2u-;e5{QWZqn z!k`Y8JyN|8ldnSO7K-#0$-%s@{*$T%6sd~^$JY;ctOp!W;>tgHm3_X^@9KgmAo?%hVgNoH~= zRJ4m!4gtTU*KLxb=?Aqpmb~wr+gjWveq+HrTYle2`PQ%)T(z|xIf+IbC?8*^fzC3p zBu~@gK$;ZId*dFeE=;~E1I&DSKsWA7w3?E64@b0CiZ?iRCo4P}#@c+K6qo78=J#lD z7|sEJ?Ru3CNY@{H3)U_dOydsQ$RvcH1h&b7&w_84pmUa0#^p!z-o>3CFdJx@AAdI_ z(#;NRH^7OF^@q(M>)v~Kb(6Vt++n;c8rOTx@dF@9F(kNC3Fw?0Ak)u!sK|<{t0-GR zZ*n^UTJhz%oh?0oP$7b{sp&lrb%^ZVv(mza&p72|h}$cqNCES>VwqHH6vxynoZr>? zD`BuhPS;02RWsUEU!rj?`2YL?CAhjV+bg6*4b31~jYf-SefsbIcD708=mTeHlR==oI}+Ysm+1WvD80ajQ!m2BNlzP~ zR-7Q}mGUe8!(2A>Eo`nyWaLMCO|0M@QbG8r8eFS!^awZ}5H2MPu>GLt3MCKn(9*az zc@;I4CZ!R>4%KdzLfAYbHr~|`rI;zIAMsV2jf)@Km-k!af-7-HQ3ZiqCmSvl*7@{f zCx5ggj>cS{9_tpm4y}L|Y`{`*a%_Ti1nHvjSXXL;GE9`N!0dSdaVHAO{x$xW1OMqj z#3kvJ)X*BMSx1QA{E8mx8^Y|JB)zWFJMZ~y@ZRfs=m+!5iY4^MCKwmx@@Ugj-LJe(Y=KsaR|FCJ}+`^r{e*lDw7wtiWX#N?{8_5GpT?k|8d{Q7LB zi4ft7=b*~s6cpGlW~c6}^jc>PpI+g5t4LS9+3k8@(^p|-Bewc1wQ&vQOub;b^lyYq zSSRC9k$+{nN0S7;bMeLc{vAk?8hoPfc^!FL8+@sLhPTPgy9u=Y6dqf!e?#(Bsiv9_ zj*mw(US5^!ma@N3S1J`09~%>Q^Oe#Qrj0!5SSKb4xY{x!+}rsXF!kfq^A%e2Um40% zk|8@+l(hnNhi*Wgbda|@&dDeHiH;+CJ>(dne0kwpk3T=~XX<8WtH4?|+?wVz?e9}v z;XLoWenqoxU@<2(DpcUi|E>iq!$YtXa7BHuBUsL|rk!FLd{K`1ZeZSMA8{Cs;>083 z>pP-YxE?^}6#DB3jZ@SGv-Q5*VkFjM)w0hMU67*a9B%{P_5~G?#lDr<2bJVqhv~R@ zQ(F3UvuPR2`uf91rx;~7@a%ZZ+L@V@=Q~&5)H*4DNtTzv%SaK%*viM$YGN-c)a1uz z*52PA5rMJ;teQz&ShX?*%a?-g!%&LI>s{lbsRcgLAE%|3ZX@BN7n!*8gVUZ>__ z=j_SwLFf$%^BC1W9kFBy{NC*ZQtX0pfiY|-NXdsU%Kt~NTteb5|Mk@E(dOmFq^oP z0`eQG_gQ%L>{kij`sY4X#+c8?TvNPKpof=WtnvAz0Cz3C?ectfC#BZ;LFl5xwb#Cf zSv7KS^@j4Pr#P4)JcB$~0TXWkzs2w1-5`;tlnjAipM+j9Z81NOc)-Bw&7bZ?jqJJT z15#B`Y!>AekxFuDg1NWOpO<_Oer>sm*CfqHF(2Rg2(1})bn4)-SFHkPTb+2@^a7QY zThgx3A!bEdYv}r}gRp$(&(weyBb=ARq_r*!c73fejL#hR} zSwS3r6zsL#(cuQ#bwZ=^oUP#9Cup)M(PffIJs-(<8n?}!01k+k;cPX3B^!ugBlTen zb#!d@ndjaD{0UR|u=^*P7uOG5vZnd*?wVt>sa`Lo;CB*xyKnfuf2#@YcK6tnb}=lI z{;}L?|Hs81CNNCZI|I2`mNHVf23U;*uErWpEE>w@?_yR6hZ8rP&wTr=$fm^X_qFij z0$UlGbvX5zasbh{*=JCtEzF3CY>q)C1JeuWW3!7K(6EwQw!_(leN{xOPh@{D-*7EE z6#Vh{UMJF^-K$m2yLQ^VKJul|Xd7_)T-@A*aHCL3jRE6cpRtOWM^E&<3{=Yw`8Bi* zg9MI2&OCj7{v$YgmZ8iMv95g(7P}ZBkk|8;3>nb-t6IS&#`?Jo_P$JShxq;ZF2B^9 z@lPOcEcLQ&`HJtL*hjcp%#kI(C!&wse=clO1xmRjuP;$;@4)s#xK4meN4DDUTZURI zYmgxVoZBIHlEq7GkkwbxL0s8IuJQ2nAgN+DBl`oLtj3gIO>W?zYFJUj9`efAkBX?q z7;I9!sZ`C!J?HprQg>+Kw^j0JA($X9F?9b_PClq2Yjv?i`5vagy)i+=XiRvPW#UJz z)zrmSXmo0~_<`l(Jo)~eJ;Atp7nW04`sJA6$i`k1c^#nnd*1M%BSELk-#kB7U7#It zpXIwi$H;KW^L1sOT6;meB~6(annKRfVC(rS`Q3CgE9 z=RxM%RJUxbb6{7e@`ByNFuN})GZddIZ7^eAjdL!7K@$RIXc!`3Xn*cervDLef%eDjv?m zOd>gRqydi>;cbwho+@xz!?Im713l!Z2k9qfb2_txbGyvk+-k_Bb{FO~B|k?AeoSmk z__dTk{Z1^Heox(&(ib5_Tw&ipy6~mSAOz%6ABkMg@U2)%vZKJiqj0`8*Zfk^$4KMR#YCgaH_qB3u9XnT9W(gBsFq9EXq0l2ZoR%TY3wrgu=ELv(wd#F+ z^6Yh@cZH3=iJ**trlE8u_`rNX%i;{>zzY-kz!K!jg0pBgfaUjpGsAvus zuF_WBkVd5EGQ4P(emNMMtn2gji%RZJIYI&a>V9DBU4u+pnvytc87N$FLcMKdg6Z*pH4zjzzmDa4clDCfaou`NJ$ zx1{~yR}(2LeTHvp93a$6?@4<#?uZpb`FWm%I@K*MQmBdmA@N4wQ)vINm7|f;y}{J?`&I7*Sk|MG_JFUUSlvOOE`MPV`XI+<9KM`zmK zs1m_rB^3SC-G%gz+ zR67ImAaWsvU|mq{h)O(I%hp4amXcz~jMaJ(#&J{gW9)M=X5M$)0rELxA>$3#bU%l` zFK&5(0OC72yaD65Fb#ph;l{}X5%_xeGr|%I{iEn&KSn^9ghg25N2PWX5kcT#_f2uH zx(+Q&a;5`ll_9=TtM7eKz9x<-2GvAh%3=_=SpL;iVm(4GAg$Sz=OO8p%bEX1c~j7C zC|u2tm+|MXyM66MOLVl%R_Dx_$I*C6m7yAS&`dIVu>5C1 zMd=@+;v#5aNzmhV=Wfcv+-y>n*8B#o=fd!ppqg|ttzpN3;|J^-&inVLIBtSuC(t2Uvcj z>E99*+=C=7Ko9RoRP42n_e@pG@2w{&Mn5P%aZqne3MCA7?8f{M$y$m!wuSlhR-mNe z52>So!BVHhR6@LsB&BH_`=Vqo6HzN9louxGf{7HmR+>$vD*S>@ zUBHig;~MMWzdnQl1IN%eBYn3zKvzjw@T3jfpkEoK;N{osa^~!ND$Y;r571PCK3uav zIXJ&ffL{3V%-jx*M}X5#H-)HER_r0FSI6u|99>11vd4r2sV@!{O87rrz5ZT*42rmBH1O<=CK4ETh|w5&5=n+9gjsph_i6#Y7s?gfyCmdPqj1uPB<*f&-YP zqD3jx*kL{Gd#Gik#hy_aAYu#e6X_Q6ksVQR8fQmuY|o7PbG=~+MgO24FNF z)h=Qah*twj(5x!>^2U+Nm#5#}Tk?z$8DVovT(4wCRXiUcmP7jYv0=Mc+pC9vX0skQ z`g`XzXn_*;jfVHRzDxKSwY_s_hC?@rUc@KhMY6er`-PGxy`@wl4(?Pi=OCcxt(e4H zL8H<)!^SDwOw?qKH5NAW#A9cYK3h-Y_8)^b^2U)^Y1)Ku>Gl>;5#L=D{n%j%vAu(= zjm^_Xv<*@xJ=yi@o2FKa&n8}Kgf4!Z^b}=^33soQNy^oOEbM(isQ=xw-*IqXqEjdi zXwIAS>HclZIGk`Y{93p%42ib;^P=W;|8Z>JE<1f%*$avW>LvdxUPuc!JdA9YQ-^3xgC+tmmQch%7|hM zv2Ax~fw%;!BpB1zTxGD;6OUx!WItdf9Kk!_eRp9YZ2O}jmOEMf^2-BclL02M)5}P` zy#~2zN7KCCHE9x7ufA8OurGO^e zxP8kzq2Z~$9S}A_)Jf z!=SBa5)yvTMHtb}xy)2k>k)Ms3vGEXU{hu%4gLuHoaqCk?=bqWq>nyNPMfqkgrL%h zbjQo3Y@$c(gQG~uwO<2yFVt4VKnFJYBiYwtK%K<4E1@l82hPfq)y4*kaa3PB2bS{Q zamKkkWT`M_xnP|QKgql>8BP)!-vlJ~>hST3Sew_ht2is=`%N$XNtM5IZ=-Rslt-^p zPDzcW56EGZObWH&ayatlPQQYDs)(O^p3ThlzX_I|w92CpO7*-eXBpC6hRu#g9l9Zc zcwYQbz^A=lo++gAEa|KEL5Q{`S63IC-2IM-jCr!yr`#$v32LtvMw=UDXr~}b;6mw# z*v~o6DxHR6#`aevjr;K_6sQNarhA#Yye-sJO| z^VE8itXuE+4iEjx> z$x%aUlBn+|iUn6C_U{l|HZl3LFu$hq?=_S&yiD$H*~NI)Ga7JsL7D1{hq04=I_!%N ze?8}0`5i-IKhe8ab(&DUK0UI2vHK2ri+poer$hp{^B*Hqsopbg*ZfjwJo!(4wsY`i z)0=Jm-W#iLPS3jV&7z@8q-Qr)Qn|%jxi#C=3b4YQq%IxHci=zZ~uGv!xOLS?xBpslN;yurag!LjcVl zpe7NU^46mA<{IEe1LhaR2+G7p7Be@cH0WZfJI4_H%@VBm=MuS2NpNjPzKSVPJ+z7S zP+}xMd?q!Oua{N?*!7*?^)nIjQXdHQ2!rW4P)A#qH!G}h(F>aynDHs^YF-RGwN)o* zKjqOx4fVMwse%tmOL~omUij#7Hq4^&#qd7Z%Y}wEvT0L`54qh+LI0+flH@IJ`c;sl z2`&^`jYC6vfXc}-{mpNbL48mz2bJr*YQ2GBbY>oWAX0?9q->$pSzkn?SmhNqf4C0+ z)6sL1Rk#rbD*L1$@=PIqv5aVkLVn65tTH(HeZe{7v~T-95*^#wt?Lqd>78bLrhq`PB- zl!An$w2~qqAt50pNH<7{AdM1=fP{dwptN+yJ2#%^x#!-`d(OY-u=oDOT64`g#&>*a zrTN<@L8b(V5X^k?Kb|auR^^yqWcg$(D{A7z>%4RMCN3EM$wz1S0c2?Gj8vZEY3b6V zm=kfxce6s3<{0q2GU?#)C=8;7+i#4pK6y+)UV(ZIMM4m~!wj%12-3HBnm?n7NDL<~ z>q*x)pNn#P->`fdeZ@?vDWXL;9qbzO_vhiXzscKt@@eg{+fY0MyTcfz>TFn*rF%sA z6`OaS>CI10|NIH7nwDY<4TM?sT0^Kpw8Hse^HgFIIj1p)Mw^J|(sFE9RZpwo!SmaE zO{GD3)gglZW?DoQMRs<7f8+&flID^GQN?0}J79VW3kpc3BRz0x^ZKMQ_OkUb{)Vfr z&2@zR*!FdXo}0Ps{PR8TLpWD#TsgshLxwC|DN!C@(O0)v_?D15KP-&XG(wwR_K+uQ zyNj&*(?+_iCI|cO;r-F5AN%vU)9RnPRA$DVJU^=>kI9kb^TZ@UdU;RdxAg^IiFy}7 zRy+Q9*#w<+>kN^MjltP2y_I(aw3~mb>Z^m|El}cFj-t6In+&U$wJj?NkVXk;06vD>>7)S3q`eFLe*_K^5{g#C@{zrB++<|Y;bb93z=f)I?XFlk4I__?pIOSV^n=PBm!^MIF zNMXwYUR`tJWHG$o)?yT{xJslb5xQLBmrYu}y*_z{C_nY^oQv8KHF`gWPBu<048i0U z3-B%)Z5!Np@aZY+0k@Z|>m!$f{%3*yN9AwI09i0o8R|XVJR|a&d!|<6Uj|KwiIb{t zK3Bf>&zC5|DlNA#!bI-9zc~*Org}ry?|587;b>S;T2m%#GHuW^bv3-CRQ>zyU{bZ2 z6PiE1c$w^W*#GCV`q4R0Q=bMhnxmAKApc_K9%eprA0Kbp8i6(^^G1GqbN9h_ohpe{ zNfXmbu9ozY3FN}FxiOvZ7|7;Xb&P+FjWJaq_6`_P;5^O+Z{L5E`p>1FJaZmfUel}T zE6Nyg8YM3=K}BBH)@&JOl8OW~`gj{Pyw9*!)+e8}Dm=9cKHvS_%wy8Dt~fu|LA{hj z{1P_x(Mo==lc7Tw11Fsmd^+>V$GUtDUx_Kh+DVCE zz3h3uu~HMSdeYHs?0LS^e13d4{P6nSdN#71`2WxEmm+Z4r%(9dEsNZ;ut4=U3yHp^ zc@{=EhQiMh9zVUq)zpDur{jJJ1!p!S10U^t-@mz-E7budex(1=>iqkq{cSc3Pj~|$ z-5v4237ct@=m>^G}48e>+|G;`4Cy4 zzJr_{*nnkL(m+&|6rcFq-XZ+az*VFK_yR2INB~-2G3Ogdq9GEob#vg<`il{1h8G!! zKT&%hrlCFGI1RL1+AfJ9bIbTeFhu4bRl(%|^0HE6_ix!>J!@hNu7rQ@Ca}{0h~|{; zYxu=O`M<9`@^t9VVuESF&cI{!RwjD}0?+3^5m1XCf-apQ{!J?^vd8!~E>{*|?0-V< z4IR6>1XosobsVf+vY74EdW{TxYrafv_ycG#M=-&tj$#w`KKg)ECJsAo45hfc_m$lR z>(FOll;YwwojP8v?|14{51*DmuebU(ymI3C>{2k0J!g!OUwt&^excA|nu~!>{J(Bx zkbVoQGJ6r(SWq|9e_yU|*(~CShYi?xlJ0E6`E`|*mA8L;OcYwHajZU(PY?TS(*Z&b zWSsf@r>cNl1%MZTy0~8!$)QVs86i+qH}fAD>%OAWLj_dwly#6=yVuTU=OeAZnH2?D zS$yJ*_JfJ()ztQ@9m$wPSSOdRjxcGs{|C>CE6;zzZhk26C`8D4a{~8?eJyY@Kd~_P zA?iF@Hj=fyw&F5gq=`QssITLA7yoxGHAWl-q7YIPoW97pEq1y0=6ursy&LRQm6k6A zyLD$D#C@icrF%20loC^m)Qa+630NQ>nFjr%Kurxp*c)kp#czoG`eKIAyUP`H0$X>6ba%GZ1J4E3IBRzRLDyO--dYzYJWx#OL5=6R{mU6K_ z&I-G#3P=x_h7E$;4c+~nx`2}I?Av`rkpUW;Q+nNOr#NjSe(+zk?7>fP6(Uilha^A? z74h8@3m?BInXi=pwAj4UJF47yV7moTd$=8^K*IGZlvNB z_J2#S8reJJM%2DVTL@j9NS$syhTzr;DY#D%-1?WV2S`ceC&|!j4SC}jEWR@%0#G63 z-h&XSeG4LvV>D*JB9{bCK$N!AgY0+Ojn!P-_o%wQzP_l4{nRgz!Gc$m|6d;{ZFxT% z-p`LG*A^MViHXzcQ7Le7>NMj&NOzJ~bop0l1{ECrN1ZXRQ&$Do1{Vk9RL+>>72`tS z`4SKi(9_d{vAGsfAH#xW_}`fum_uu15!H>indc0jo0w)6)gSfGR>0HL|9l80UcdzS z{Y3R4B#nnz1kKIGfxjNcY!o6_k?G3NPZ4-B7!ECfet-qYsTcr>xc5taGlVi9RZ>sh z+&W;ZQsb5afzy0+7vf6epeWa5Y*FaK7<8po63g>Mvs!NKU2shILa`GP6BzSKtox=e z$MylRv|@wg=98$u5P4v<piIc`d6>*3%<=$K-E8*{DKU9-oBx6B8Y;0&3$VXaE>9&3IZ;J zV7J#2xS4FOjCIb{W2t$$0s;QN0anhN?&hei2MnoM2BR#U@i1qWaHD2Ii6yVXMyQ(L zGi46uJ-GkIt1_rIeGigtcM>NbKOLxD+^BRYbm6r%ZmtOz&CAKNcx98ilVldH|9z+g zm;v;GEau)vQZ9J6muv#3t`m4~@KU#v>t}My%1cLAo|Y9fu!Z3&|6XYIsK`t^GS7zm zX3D9nV{`Ja?(k+3RspyQpv!F(Vt#YDj^Tv!hX9AcQ^-x~Q_CC%e!}O=FlC3i&|s)8 zTFLTw{@)D~0t*mrmr*$8KSaMXw^(wOU`b4T?t@P&C?U#fAnSm2Ti5W}%b8rl&zlgh zOwFCwO{S1WAaOFpTl$gay7h0m1mf%aZQ7L1F)$RmF`0NMGU#d@$reRf3#f%bCUCA zi()8Cqvpm_)}4hIS75d$^9xjBcivrn^J2hm1mJ%PPd_I@_f${QP__`0q5|{XB%#93 ztLiK!Y7hquvYn;-t62PPl7~%HjQ%I#7UuUGn!9jbP z{{^b`=?dJGaR5e3p6#dr=x>mPiE1k8Qy8%WQXV{0A7xBUHS~V+ zCWn-&_Igwf4UNnZ6Ya|YkHr`TrwJSTc^VQJqVj0`Q;_JCe+-gf6r7DdW1x8-eMrJk zHCqJWqy>zqvGmI7YgGVx`M5)-to&I%%6>;R=KO8J;Lw3hF6hsX`~|URtL+0ANMOik z!+m?tr@;&RH{=t&2U@utA6`yCu7mLogYMde`m@*ZRX??T{bjx+nHK0R12{Ph2fsgM z#EskBSHvyS)#N+q&w~5-C4Wc6#JJ%N>^wsC^Me3ZlVu=4<>4Et39D){4n;6<^o#rk z+GPuuje1M-fuw`*%`_6Et{1)EU%zw=?OkFXoh%#ydA*xMbTm^h-L=^s`DDkQz6bE# zqRclem@!i*cE!(~t1Hs7@Tf7!6n0(6E^jz1-WHIE;-O;c01qs0d{+~q&M&hrgtS7c zn(GLc5?u)V49%-6?wFmbmIuz8*4S}Z^y0Fcc)9bg>gxNOQ87}`4566&bVzq09Z)pg zgsLndM=$dG)ObplsLGNsIL(a)YQPn4tb#hye&UKWaj0jp#suhX9$@{a&ry~dgk`Z)F1=s<&^$?T#*nRz0?KMu^rRVGa~C$5 z)PR~8H@O|G1#GhOWuad{Q|~0cW}uN#b3RVxO;;CD8bJ0~m}nrT%I}>D^jiWVa{~3(ol2?%Z-AaS%O<=oSNMT=X=3GO&RR}rJ^A>OrwEmZVk+u9(>Qfc#C(m;dJ9I#Mq!n#0RZ3DD{b*Caf+_3+fQn zmg((3TzLQ9@3&h;qy7u`P&k0W!ifQ`2`7)KPVi?CN_)S>ET;K(b;gUjY~U?+J`Kmw zaI?vqlvCmK^~H`Ak2=Cog}3()?PLcZv!QM6;BE)<6C_Qok~`Pt_aSDCS(C>x9Do0n zY38J~3O6UXDxguerq9n(aXVr>zzv}VoumaZA9lgR8!$^YMLkt>T%(^mhjQ_u3n}6U zVvrFfLc%SqO);Np_jKWVwsU@N(hHOZzAUm1Zc?MF#tq_U@IM5yx|D9-P-UXc}#*ca0Uel01d3yid>1<`4u z0(JOwZ|3GMxF_&x1|T(h(LIb16OfYxq~BvuN1%$u-Pg5z2vvabxz!b(e7ZtKs^tVJ zX$vG>KcP^=Rs(XnW(NtKX?3!8Av5&vE0i9fXJBApY;1h@ZhFeujE8j@!+l;+RvrFF zPLuC7kca`hzjY`Bjv@Q&yw^8}^Qo}o7IA{rHo)`G3`T-@vn zUZ!B<;h(2|N6lmnSA^@KBX#o!CgUmhiow-MCEBvtIgfes)Fm8iYHY~9(zt|i3}rb@ z8Yj}9eFv+~q15)aS8u@Wu;&MFlStTt_wLinhBM}jLgU8`n9edxnts6w8O=<7@6g7^ zH8WAV#7zOrWhA^i%*tV`Aw6^;F&*(6|92M8*OjX+K|uw)F(Xr8~ju#IASiX zPMHSPoN3+x6Idr4e$>)`wvWlU9j{umnI}_zr?x*LztIB4px@=tpQf2_?)<17$*Fa{ zVUALrq@YaeHbI7Yr{x+Z{cyXbPz>b-LYAEOB_d!vFSQ#zFMGY6`&*j&jl@buBliR6{sDmZ8r;~*ls+HM5dWHPaojX zHjMjPC_i4#SE$0$A^3fhS*$Woh>oMdkQTC0<#^CbST$ZVO@2s?+fhIRrB<{61pO+{G0QLQwDUc;m}2wOsh4uL%mwM9uLBlx z1$1y42l^$9laU?bJ)a1VhNERC}*K@m_ zw-qe8;m8KW%e3R1S^sbnrIv8@D&gDXH%%JQrVgmf3<`X1n}ogOnGLp9N1xaQGt`nh zdp8u(W7nTx=90xeLA#Tr6!^@ONqTK!6OHo^G``I@uY>C@9Gg8<^7w~y-zQfSI9}nd@dEZMZhPkz$8((hS5&g8?dymvop3O z%4gJC@zxS*FAj5G04ViV{SIFrycy>6#sfOO^wq^I6xfCu84?Mo`fbChY)kt;%knk@ z*VCgaZm;66TqRFZL@C}Zk1PtU{(mD}o>xF_zh z>S)ef!jri^KrP{;3^hn&frW*cF(Z|HMY^2r6YufWud}gg=@1<{*n_K%XmLIfp{yX^ zaMLA@-y711#?J@|*nUOKEngryx`$TfIP-sa7@DG5eTjcnqNq6m&+wH~D->IlKctu# z>ZZByu+IAUT);pS;CYewQm)y7Z{0ZqW#s5p{g6@%mr$WNP@ z^I`ZKJP4<^`Eh5WSK?Cmo@_A#sx>=o7f?(XKc$j^3S!4b&|-O3EH7ALWar9#tE-0?H9>b9=r^?_eu&|wGQ2pRhTv3M>jUsmG8~=4vjc&!d*M9%t zXC5;Okkp2JwD4Tp<5)X>ia;qYJA40c&AQ$5km{C z%DyS*EFIfOH#MW{fB&_|&bW!!YWBoD`2{oIMBE&l&xX(tZy2~3z)eW^V6;2wD{O`7 zPa-)td)&RE^S`EDZBDgVK{Ra3b4uYk((7rK5_QfMJ6x)%%8v`RH=MvP4gIz(xr_de za2AllAajPf>5=B2c|0QA>i1d5dh zi|>q6i7RMXYO_@dgwd0+Zb>QGQYtrjwCkHiseP|VXXaeBPaWY6O8e1!L}n`=HltM~ z8k(%8C9V6?REJD@N?gve$gZT@u^AMH-PYk?{z+V zXJhIqMn}oNS&T_o>WuxHbgSUpawy`U6 z#v0$bD1>B5bU9Zw%X~Jl)-OSnuZqWV=+4^~qzt_4Bj>vN%)J(qFR&f5TF2lNEA=|R zkBWn82bFZ|d6*bIq}MWw5>xr%rAy(TgE*yPibQ&f95!#Sl$Eu_=A*hHG}3sV45DFpk*e=If=xcO!FX}zRsk~UmkpEb<~5%%=Zz#yS!ceN z2h_D@PSu1WlURnAqRNH0lc=U{(JxVj2V>F-G(3v=xSO3Sn9Zhf&58C#nKVD{)-?e~ z1X3D391ueAsl4*?_s?tv;@F1&bN^8oS-3uc9wqCn+A~Yu`VRpy?;aD?LUAH0Ih~Nj z-S@EwZGCkr^0oG$!$-6WL1V(vwD%v7D4`5!hcll2++0MPOO7z$TR$~^ag%Y5E>AVr z#J!8AVGq4=yL|g*QoQps&u{DMuf%XV{BO)#yDGz(;*(kmB{8|h=SNq$;pRt{9Gh_? zZd!iHiT~kweSR!9h{-Y_UQxOxs^%^RGYwBU677IN)5q4Y23Izk2Su7u$RhD#>dfIf&pRwc9x zzasjrH3cC2?bgXt-Y2CzO(yFV)%by*kU(xDTNUNcGmf+D>-N8JNdPv?poWJ2^kw!M z!F|m;fuGU?7NP|1J`Gn68L>AkV5GEK{&J{n50%e?z2%K&D7*`;L)3y#T&^;qXbINS zbl1@#S~k!;saQf7sk*-U4S~FiX&*v-6bJe>S)e4uaClKXLcM98dDKx48Cb2{sQt) zeyd%R@y2Den7CxWhd#pSH44ZK;`%FUZe4@Ud~XeD52RW|9@G1cf6${@y5Tv5E>Jn@ zhu#uS%w&!Nh)}Prmm$pXoHTkjYV<`MLhwX{<{a z_+MvRN5)%Cp8QpLy(t89l6)^n*c0Q(nVz;)R`3)W>}=7MnCWX30+A%w=i`5b_bQV{3TfQuP_9ikOKQ?(63WjifsL)>rKjh<^K6v9omCSBD97FJ zar8xr{Z#Q^LV3%ok)hy;b_#$D4-g>BoDDJeZ}y*>^T01e?ctmgxU4q64v#EiFdN5$ z?&aOZyjMzuj)uA|scc;%nIT~Hc0HYlhbdv%tdIB1WfYvz_kT7j1w=(cLY^TqxeH-xCg;8`={+(T$w}EOtmBxE zMI!gUZnr z1qT>sn&p=`5fw4a{u+Hi;{j@RcmY?S0Q2if!$J-vsf&zgt`#yHgMyH25{D>KGm~u&zPVR{Nu=eAQNpmuMJDdj3D!KK zzH6mC=5H8V9}Mne=%P)%2+IkyN5O$k;`f4*C#n*q^jZoLB$ea+DK;2&r$d2=bFK3}BFoJ(!f^$=C)gITaOP|EN3yHIbNAhG)b6$*QJvSA(2ayJ zJJetQ_$etiRbab1*ADDiOuaWw$sIgfkY%80*cA4yr zR-GL*jbZ-ZuahC+>mz=s?!EA{GQ8*8R`}ev%1@qHsqZWU57D2=5=)bQ%cDKt+{v|% zdth1KY5Jb*G4sc?cZ3S5vfaJ(<ME%cW0!d0&MqxSX&XjQXux~;4H4VvGu2|R`rVSN` zcWQtMUI~eG`D?WxFlymz-<}()j^WC`9ioAw|?lnc)CAY@ z8bOi}-SSel@xG8DWMztJ|FHNLG7>Bq6etK9d#X2g6jYIuvK~h6m4IbBs&SpB zvS%_`^EYaDy|wEGUFJ}HVyBVc-B;HUeB7IMf1)Li|M-89bpLe{D*T@B+UEC?>8+{e zBgP()svL7DN%$kz7G#?w9mjn~5Y1&WG~*M60{ytMY) z?fpbPOGSIM+XZAyqq>I+!E9B-#-iDlYz)b9UzAx`mcoHht5g2B_XuiBcLXQ~%z05U zc7ld$(~locU$$~%st6zpfPkG|K-jThq8I0eBs>v)$`pC=3jz_8D(ptJId~Eh_dQGp zK5}?k#yLJ#&XIv%5N)VyvUM7basEBy?6{ZqdYNI31m~RB{h`7d>gE+u^U>+4lbPS` z7Q)_#V3oe~Xd5S?n$l>WRqcH4{Ghp>jxUbxjcP;-JSEKeQ(AF~Q>yPz%OQHW)V`mG zULirnhkeaS-d2H+Bl*>rHONOa$yV(3%GhmR+VtqugjH6xLxG+7y61=V z#LeFNUh%2(1NhhNu=zaWyCm)HCo5n7{CObRmK&5c2MjRiY71h$t^U9u@@s1-+3XCk zSKZYs&66JD!gAP3A+p_&r!u{gEnVoj&Ym=(WiNYY3A@A_!8**rW^OyoanT9w1l2}5 zIXqMVM9v0g{>2xr4Tdi)1!pAEl8})2>XMXv_u(3i+z@6f&cgdjcEg0$0XlEfs|&07 zIMu1kcb5M)(sW|cOVn{dGY)dIfm%>KUxGh}RI>FFV(V9hB#bke6BXNMq_7zw*n2Sf z`wK=RZa65{C&ZUY$<===HrQB?AINtZE_J2j@S6(~u-+ zZ|@U=F3NGbQN!+8mJK1f8cpHvVYF)rSHJ3;z!N<&pjNq>j!5bzguLJ zgj8#>{f`1>=Er5e@l}cHh*juD-%6>j_I>ykl7|439Z=JdWyLE>R%4n*`QK~M`<205 zpx7Ylw$mRnp?Kzu*iEuvdFEe3&%Mq%E>wUNd3Qx$PzjYj1(4RyhV$jIZUY{Ink`T>{{!24BiBA;3a_`_W2-)t0Xl%@m65vRx z>ny0j}iS_1uEl z{5k$DyVr~*Z^}4XjjTz$hj|*Fokf8T25E8$&Di~DS+WEfV$9rboGmWTj>D~7GW_m< zNAJ02MphM;pUJGO7W#W!9BjqP|a$ZGZ=G6=`efj|zv{tmu1My91@ z^#A0xcsxN-DKdDY^*~+dv`@aJNJ(OnRFX-IMdh^E{m$9&4WC?IIQa)3qC)_dWrFa7 zvu{Pqc0@x&NR2iGuyMZFEYFY?0SOz8Vaqa8OUr&~0JE>V8$A)JBD{H2>B=o_+l~;} zMd}B^A&c)AhR&TQE%6`oK=wzdehby3lCVxx2kiH`K!)o-_l< zomzp7;UzZi)dT_0uQ9>yztn$z<@A>-`w5Cyo*)WGST!3i!>WuXaTQDwF!0IN0qGnW z8I+Z)6rYzkg z^>%3%kauxSOcVt{4CGXe_&W`|vm^fq^4@@QsPqyP4kSkVv=GBQ4f<7tcNWlNCjrus z$5?yKcllyP$yl919cdme=I^$$6*bA7e#d!vR>xOYA5()H}iHiUsN zp89+JkU4qq5$0K?%3tAkVZg{m;i2%+&_!~i#MoQ(lE`f}5nV60@t^+9n2S;^#N)bN zPhMm4%1oB(M8(Q{%{h9ouoRnt)CcLG{Jv-T(TRqW0W!~buHSM6Mj1f*O3KS6U6v;f zx~ss!-iEplZ#I-Kp>bgaRAT;TPr$-cEse{4W9u9wgcCv9Tt-bt;3BNLT&kI^^)rt? zFL7kSKog-~)_4zOfG(Xt#7v%yO=IYYd{4T6L&$%7)>CJvD$T>97z3)$D z`WJoLqaN|L3R>km@-D(L5T^;jN5mDp^#_%TF?>))-a zDBA4JY;&1lDlJw+Ue99nEx~kL67g|u?5Hw+Sn# z22o-SIMctm5v>&Q-~-$j**ijr|8V_0GHLiRJYKD0SA&zGKd#zXvk%Jsu-u9d5ll~> z!#+Swg_zKSM2+TSB5xe*SUY&hn8{G=%}N3i4l+s3;r%p#cQ!6O2kG~~C1W;1@B;xc zJF|Z$JMO*rVOS;;Jzy`tv}uGqj;z&-vsvPhtc64OV%T%#Um?}bt6W9Gu){!{JyD-$ zKs(kuo%czJ)_$DzNDkCD{2i0`K7(MYWGMP`=_(P8D#!_Gwl3J7p|A{r>-S4YH?)^d z^9kx9#Ry`7VfB31Pr|r}j9YJDrWN#W(bX_U&#BzHdCiNNjOdgdhT>rl&>~{9oES19 z)ieUnLdZ3@gyxssQ_Vhj(Z|{L+ohBDg{c{Pu)pK|Cn=sz_)}zo%;JDzJ1dd-T{ST~ z-`j#*JNnP+kTKv4$ydnJ$=jJEX2ZiCU_klyMP2D%cfrS0$0%F$-lS(@q;$J*iBx||(7l8p@L8{cz@PNkJ}K`_|_ z=@Wwz?f~?FJ6C5QCjcC^z$UmHx2U5;Cw$F7$@LY$JdrRn8h3 z;<1H~Jh|-)Mf^Tlb{^>2%#HwzHsU@N9mY6$=$t3M{1^=hv-K(9`~r|TfrFfo9EZhFOB3e1 z+t?L(wTZt7m2RzqUNUv}TF~m_x_e!*m{d;-j!!YhC`vIE1ZL-T?xVZr*s!AIs5Pf5 z*-rcIXE#vQd_R7>gbH4?FO3wx7>xK4RfE6|be@K1{X)0+4AX081|=t+JUCZ&H8Ctq zEUo3$m=jcd7wU??mg1d7|yS!h+4^x5(GW?K-6vm0HL3Y4s zcdy0|2?rvpOWLv4z81cq#sEFp9$m%i-RU+O`A0aR9CAS#Xq=o8KS|2W54pK-N&E0^ zjP-D^%NEEJFN>N}xDvkUjd9$7Fv#=|(f5q~Q1yRQ2MM{c!@@Enf=?kvMVpOj7vgRk zp`twSwa(|Lq!r^jD1X|Sb+50-VA{#MtMvjA(%BuB+HjIEkL*9$?KS;LzgyIFBwB3K?FQOPf*5J?=3R4jbQj=eWdyR@Bkmb0>F~cjdWAdMN23D33Lu=eD40kb*$z# zcY#K@$U39y!Gd@8#Cyl%rTBmdE z`{9QZ<-`W#dWxaI(glgU*MwKliNvoR8O*Pw910E#2*3%IcSq>HEzHd>^~na?5rU+o z3<<~FYQv=R2RvfI@jnv1w#Deoyg%8D7A8;PFuz^$G=iqo`Xa03hz@J=oU!i94(XvC z{T>>kc^dO)y~fm0jw35w3?a4nIFc_^oQH9v@53%zb(>U!Cdfphibd`iC@aQ1-d%R! zw;yu$zkcE{?pFt*)T1cgQUcFmG!vw_5%Jcpadri<_>x@iTf08Wn}JYF5I<6Wy&@dF z<>N2b!HZFUUtGIimOOXY?cos`KC7Y34-W(c_`t9Um*BUI=-{<7Uq2$7xSPd!X}Qfm znhekmslGmA^2s!G8~>Yh&nVO`*$$Gbe?Q+a8$}Vx1>$5=Qa|fEcYd+0J8;Q>wegch zpoznxPCk?a{asP#@#)N+@J#Db@(_s!Wln3xY@T3QmUyy5S~tc}z9lz>@@&C0#wu5IO z;Ie}Kn$5hG|0=+xbaf|yb^Nu|R&-R!_?;KC{@zVrr~FvUn`MO}QTXa4I` zys{XNn)poRiuvw`M|}k22G$QJaidQNL(j-Y7I#c(v7g)&oSNm33vjUbf)FjSt?C0D z?-%kTh{rQ1{}FjRyj+Dg=-KZ(!pGgwyF*I&c*nic%$h0)}MG(TU~-`s3V4$6--U^M6)a@&T3cGlC{Bc;B>2Q>B%TPawF z#N@Q7?+N|3?upkFT9A>Bj&w0}(JW zkQA4am-arpr8XttB~=ZJi7rV6O`A2*!{R@M0uC6W4#m>fI!L8OUhR6YGJd35|7FZ$ zVNb&azi>Q7g8&$LFOw$HZ#@%o=4MKESL8~Q)B(TFKJra~`Ixhaa}$KF)*_ScbZ4!9Tzig%#SE1Yv)0Y=92Lg}2cvxO(vu1%0dm z?u)Q9p>J{}#ffiC+8HG~YxXhg9u@q39HUP-+9E=(#GkbE(F3a@@wErs7*-912nwoE z@=qm11?IJ~Uwif^9ZsRYsoCbiYEA_7$hIdox7HLkLHJyL&YA8Y5D2U<%&)~*qxcq8 zn4oJcHENa<&Y9>|d>ev%i2n73A1+X|FY5>pIerGLitV-mX5k>B)9p;v#m@}=?@>-6 z0LRdKK_hyyY$8>&mj7$OW8xn5d`WKatURcGRapkHU}2Y0H}Sd`zi}W&WF8D69Kgz@ zDG5j{cNlxk|E}AkMe)Q>C{3M>y*?M~pW6x8@STQaBzkBKH(IX};)xkGTTKp%YtKR+ zJ!nT4t0{bGH-7PS{U{8`m4nvEBF@_z#E$urTVHBZq*|~I5rzgN&f@4b2>}abtPQUT znI?MQnYN9HAgUemcNbfwVMJJ2me&lu$aZFku&7TrbztvOatNqb0-f6Bqx071eJ_9*k< zb=;w3X?$#Z@c{9s!VdiPFmMx1H;5(R^KyWG{YLjD$per>e`}Br1t=U!uj~Ki?v0Ej)dG@ly*?!X zOfZqpRC+wcnCBHXuOS9KDh5X(?_R64TX==MLcAk=obVR4^2M&*CSt>_d150&cYW@~ z>%!INm;brV7sVK*5ktW+teA6mCMdZGyHH0~yJX~w`F>_T^-h+nQFcW>uY9GjztGF3 z#qita6*qjSn@-6}>#Go+80ETFMv7I|sL+y4tu*TMyq2iCf=jYhFlDTMqL$Y>%K4@s zEhS=66VMkTEi81ZY1bRT&$ZcrrK=Xvrg@p+ z>zj59hAz=Ajn5xV)k&qfV%`5p!%MrQ#v*xa^A;zh=+B++@v`JAy;LFTRey;SN6uXR zwpwZj-^epi9BAswSj$pf+CjAR*1%ebY! zG9gt1`NVG|o;{*h0T7{QHZGcDf`Jkh?Yp{aa>+(TVUABeLCBCZl z?DGK1(1EaG1vnBDU+E_ zTby4l%Esi;?1;o`h``)Q@LlY^d~m5o(Dmwm@H|I}mkt(e)qipGaZ?O;bp2w2@}($w z%UlwrE}DlbW$00A?er|7Q~g9Fy?a;eW(Rz0U<{+#AB)D>&q|e;fmU*Wp_g$U7b=oiu$Z!o#T(u_ z)f_pV&O6&(Nu>k+HKuNsclQe(bMf-RhtDxw)KEvp?!#gzaMaukbK2_;+J!Q0>K`AF z4hgX9;kjE0cMntxb1>anwriT6=OA!rK6vQ->n)Qn%zxVHXLp*Y^$)>8xFI!TJ3~xC zhf0pEucwFCsTU_k;-v%O^kyGtmEVZys+Ii8ef;#5vs_-EX_(5!Mnw3K@1xq>8XL6R zYtHv#_$MCT9^J?$4D(0ka?ohKg1$L~WE^~oci!6ZhQ9i|TkGI$Vn1AU%r~e$M25ZbC#{A=*r#Pe84{17app6uievt}-yYpucwZVdQw1whrAL zF>w?6K@Ud(<5!rLncS_ID-#T7`23u_0b1_rc`ziCHo1MIx^CwHwr=#bfP?d@{b?sX zljC!tGyk-VuROy0`+~nug{QuI+e`e8nYW4jbT5kQ6IFwJl-9k7#!pk0-)*u!U112% z3JXHldKi{TXZdEI;V$8qeXMc|D?=SfO?!rSyj%DB>eUh>`(8Vpk(bE=*_~?byo7jR zu}=iHj=J1M9yg{$A~ij>zC756UHo|e2w56Dyo()6h7~$F87B9 zIy-q)`E-%0d=+#%G%xVS*^X`rGm~}Vx82+;F-RWov6&~dtj?DI-Oe2$p5^KMfsPCN ziQo=HkH+S3!C;o!4K6A)RD#Y7f3#FvdPnqASBuQy0On}$`c&<`axYxG2gH#U)wqK1PgS!%u`w#u=~9T@ z9vGkxVHZ>P3Lm6viz<`7boo;64N`Y;s?7(zcO&u10_!=ZXNl<;q;3oQ?|lp?mygVM zQEBT&xpzmYAC20OHb0%xFlL1|@dsYXhi}X7TIiE|`TG*_Z_m}WS7~hQQ$u*Bb8Zj98ZQghy+BVaIE=xLMAT;PtxI$P8aa#k`u;l)hy!)5kV{!~wSViGS7xF$a=)=OY<}zO7vYGU z+w~%D2X%3ISb`N|>c{*QnHHUumErEH3=xpDonU}yq~rXveY#Y2=aJb}k>4d_f)!1- zV{Y#3f6A{{H{y?T!{aRap2?W3F3$V$3VFmwS2+$DGnE$!WrS+VHX3V_Fj9)tyvB+V z{K=Y4388J4NOqlsh+MTC_sW$k7@;9%{xOK6D$9`6?w+rZ)`Oe3FaJ5zzBQ6z^&8n2 zZJUum+tGPjNfX>=gt2kNp?2rjyNub6>{@!GqeKP8#m0>uIM%?=;z*UPurc=)u>7#j z{<%)U|Md}Z75*15HtXoAJI)zV@1q9NdMs>d1W_Fq210B!QbK?JeuXuiE=>KaVt`jt z(nkza$7-20-uuUk#!(va&e?}mqUco1w%@9rseJD*(`p4LVTz<$z#CV_BSET{ALvg` z_8Q(7)OoWT^sl>oJ+Xo(DEqU=y0FbRE2$r~z)g@tXgukRicyZR5Hs(x!TmTNuNx{V zm;e80`^u=Sx360jL6MS1QjkVcIwhr%dg$(MDFF#Vx{>bgct9GYQ@TsK1f(1829N)E z-*LzNbk8_roDX`Q-;TBCT5ImP*4~?TeV&1vCnON0Z&%^{)@)EdAS?&zwRT-Rt295( zt$g-C9IxF?0-J#`2|fXPA{8w%;}N}!ioYpRARJa$zCRNR5zh;Go8tsCk@|v?Cb#uu zQHd-bcc#guMf2r5Xb441r^##P>(dHgibdg5f-4Hd!2J4a?iTOGweiYo0h{r{6sdK< zTLY00o9Le!i!`P!w)^_xV0_aGs}Vm5huu+ zDjtG^gVP`$Pd?dvz`irw?3L-bpBRCMRG5Ac-#>v+wM4)?=5glWK477Q^IuTl95zD6_9bK}aOClEGPNLr(-EzCpDb)1`d z>3Os#U`ya)R0}s=g%?~x!f7U4=Gm@W_G?qfJXv3sBWimOt=zMn0de_qP!EHE6K?iP zW6|StHj%y0;O{XMA^h{9u&4xwn%?Ff>f&Uy#N}U49*)@#HB(cUsJM|e&D^FI`)tdGXW6Wz^Z^LD#lr7qu zw`^YOZN(*S68pA5+GHuhZ7b*;Unuiw(4H;5?a0bx+j^U`QtJt;A!BhB@v{qECGXsK zY>1_FiHW-Ls(*`GRlr=kO!+llybZUaZT9PD@L7e4Xn4wqz#bAZ>eF>Qetq^Zx%j=% z{<{G7voJ@EbKNPy)*$0gDlmadCy%g|B{iS>?PjnD z$EMc;$h<`#Z{2Hs*_oikmd___P15I3o zgN(Hl$5$toRa{JLGp)7r2@=8K*QT2W!Ol-&@<#78LOT=`rurCyCQS6;uxgZ4R5+HK z)CB0F{XKY-QFyxBpzW& z?11!oqo<;SBp9X7UGXIaBV(y(2|@vuX5V%dA3+QKnS8)YA-EX-_uN$Qf$h5cG(Nzp z?hPxuA4hpblSfQ^^JcYeAR&<|LSK7RygMDt6D|fx3}6gsXzd-M|D!G}r+{_>p+aKC zXe0>n56Iz7K&PFG-d-@I3&I52Un-t=p$89C6WdP8U$<{|H^)DZqQz9CWN%auZvhxr z|Ap)RqlhEfCI&Fu*O#ZDMgoXV&P>XuIctf+kt)Pwjl*%D}K8{=iTNy>D5{Ip;691O`5qfCJv1j zo_!NAJxQ|bY?Ytmw{mpNvK*43I3TqG4}-vYQhMhEhy?5o#iJn(IBo2TQ#H==2*7gIg@i@=F_GoeW7gVBeL36fsK?HR2y+mYPtbq}(%b}RmcqaP*CjaP|b5L|%gSX210C-_1s;THuS z9F`A3S`t}Fz`Yv_cvNq~yG1(}l>8Yqc8+Y>-4CtMV zuc$P-$x;wmC?Un#+FH>J^t7T;k8h9d=I{nRll^_u;)vcJPhWR86_8&K3}{uI7*ToM z4-cuxlcj$MS9uQQ>IG56A9o?V%2H6W;y9DicR!vzk{>R9svS zIOZBd9hEzo5Qk#I^!jGb7WQhuVI95xWw$@;R8hmF8W4Fb{enxd^M)q;4Io_F0X-ABMEHfI|!zr%vV3N|R z7J-F&q8YH=-wF_ikaV&Z?`tK+@3G+y3|L43Wa3F|l4n>P?>A>Mr# ze1a_qLIyYh-Z+1XLbJ4m)a@WwAh9=;a)N)eQ)nP2*8L@j)M}xzsHDVW;qeRQ0@mFa zIrx7@Uwd4B6{yA36=o|gig{SB-qT;(6}EM0)`5~%b4a(cY1-6dQm*UNKv$^hRJPyh zp-?YNQ7#NwhN-y3H!UQuy1_5{h!rLTHx3dgl5z+Q$$=Iobg~5GYWA#Y(94GeFlO$` zgq223T5pUJ72_XeWl5iJ8ILC^aRy7mjr*kX(d0(g9s{pmfH`)91m*@PM1zS}&E=kC zvox7~CX)Y}A|sgM!-LZKdgsWbB)9XPN$f#zQou`~qZwd^cw!&BK`_ zRQsy%TCAn1(3bo|8F7?Zs%dmRG0+u7lx%f5sw<3SuS0YzC%q6yIdk+X|JpG?B&loH z;XUJ8?T*YII0;8#iCTMDW_%D)xR}YjVrWNX1sp`yxxd2;HSCVFHgsjiGL$+Gjz+Zw#@q9~r@5V<;I$AFGYd2Y zvu7KKjE)}1V5o@tPl*5XvrUSZtfdhoFff7{@-$I=@DgwkTYc^4au8|{w7(7yXXL_6 zTf;x#T=!=tAq@F5lC--(h8=axExw8 zeXaqdqEWz7FJ%9K-XOw4(8mL zePW@#sq2jDi1hEF#KS>0vM9SvNKnjL90M&y7Tkeq>wsk@>#6B65ibw#qKSotg@%TP zv-7#>UA%iY9>y}y)yMz&6XT;qkYjx2n)Ot%vvc7QnX5*(fkh)Ks!gfP>}<&DX1xx%61$4#T=vKe!!t}!b^_h&>e}F%h>$F=Bm(Okg`bns* zt*yAYIB@Lqtg_%A1%)VZ0DkFzvCbfMW3-k#rSC++=XJO#4<07}uTA)0gLHOwwzRao zT5gj!qRY%~Y~C|4FjzYD0=Tv}-%wCo?0&e0#QNDsGs2t-?S-<2YiNheAHVE%hpX+n z=S7pvwvX-uau9w5nMlDDR8>{g*Vm_}zGP#==G*5Iz{SOl>i4+fXT^Hd+tc%$f}13N z{U^DM`0-&NzZ4uKg&anrBHEpLsuCC%Flww`t9G~;bYP2jFovin3H&n{4glM+u`zHq z&iog~cB9|!=x8*(I9wo>zu~GLic3%7c_OvNsC{MRCbFEvseUcrog1wUb8j;4G_0kG zpYC%<;7RpVN17iU1u25wWbR9jWD4HXtpN?Lw*`z9H#7RuEEn>$NUw{0LoWHdv;J>C zFx6Zh0{$;o3_kY@l7k$4TxGLwzZA=j$w>cv@O2YN`5-#~L}VSYta_kc&@VdnO#cLw ze>?t;O7i;9dAhaid_?QLnh(O7iU4v#6sYpXobi3l;$dECSiTO@Q`=GMF+M zpKF!=@p!T~#VHQ^Vnt)dzPz&18|*^(&@VlGeVLVu(QW@aaCT*$2Ed;FWGX>-xzKyp zyB5E*r49?&Fy!{zm;Kl<6i2vB25VO=fHVX@&^ItZPfJ?_%&MS3UasozehiEyBNf() z&sya=V~*$xYWOSNSfkq>5YwJE`c82357^|1ozRz>zI^+Yh2|l8*Drtiq1rT_bgIb%3uU}R*skK7nKn{ ze||B=BoYoX^Via9rb|2(BXQEsB$1y6_sd04j*==%yuiRs$Rqs|`tBRu(K!DY(ZH&b z+27zi8SH*&>mLNUQvZAC8R%NzVmiS#-QkKm-QT6c!PbH4UH%6O`LO@uXi#9O=c>)$ z!3X{|rw-x&{3aj^|D;FDB<9-A`2U>d^?wKFsDO_IJjgu)ferd&;;q$B0aMf2iB!1t z&EdR#^@TIpW=*>)aeXQ@JsTqZ2kIUE$KM9=QF%}NS(IcSP2cf~@CV^BH7eTssbGDU z@VAxK|FiKpYInm1F^S6wr;LR{+{XT4Ux4Y!J$gyY?e}40GOyRW z`mqE1-F6i4z<)(qP4BvgoK}V^ZD0b>H!ujcbFCyW+jnGAOO{y=O+jYST7F*9Oy%D5 zVeqpwyo{R*8ZH_QShSy&#_Ev}nw~9U|LX@QkXO?uck@I85aAyae;bZ|{$zBO&)@$k z0{4}iWY-?+hcXkq5{BTOuC{(A9-BKYRWPiTqN>qh4y#% z%X>|~Qkmia{TTt7>Mm@Mh1SME_j|>}cKs6}dnz|u?$yfV5p4Zn0^%PAS>o;2d9iLP z@%IG+*PyjZ6-WT7_^VP~bgr%dRhC}-jwUVW@Xj=*Q#@gL+>;frtEBG&z2=K*Gop=M z?{~uxy9TGEdC&zsB&ik(=1P9zK0yeR%qtPy65MuomP}<@J`2`RR$0Z*6^Nw2o^@8L z4}h0Xmw2odFrY+Is6O8(kfAM#cN5eb z-Nm#v)*f4LOSTGlfq`bjRtYVpDkP^^{lLx>jENsDH-a%ls{m2dNvGL7Mdz=MOn&2` zqN&*kg&(Q#^@Ss21R$b^&=<*w(kaXOVabu#O#8gM)UhF6b3+Oaq+aFWHFb!uN#Buo zJ#%fc-Y@?DP0YeGB_v>Wny9;=d2QQj_5wbR^6@64)R0$;Zbf`O4Q6zAxD+Ae_c6Bk7r&>- zHQM`)i2%#W_yq-FI?#|)dh)5sy5>qf4NxZvHb2knzjb9PeQ*-8?=5>&Jm0YW_zW8W zTjGhSHa{2^8DgOiMR&sm3OEq&rHZn!(FQc0?tybP_awAxce3*yaVs$wBhu6{X2@C^ zo*~zzXry?sLH8Z)U*MI<*$qK==?6m8Oau~+Df?Pbt+rt5wee@>07s_4M zr;S=%SFcj#-=5YWC_RSrBe_YwZaOC7#`Ua)L=`Lg7>fqZE#|Oxj~L|%zLOU66?LNf zRX*ANgvcFwJ1Bb`p-Hc0q#oJ`Q?yXO44^BC(=Fu2XNiz6FF!9UyA({CfwAng?il~e zvtsqSb2*{WF|(mBvz46>d=l%P7t`K(n95q~?)P*7J3)MN1z*lcR%NO069oBk(NKIUJl+SZ~gm8zsrwbu4J zY;pNbxm}jADe*J_+w1}L_X-Da9=I=*#i;UN{6aWh*h9+Q#d~@{H}OfT)XVGY&Mj+E zGt9Bk@ua%vH+ysqVKSB3D#@gLdt)AxE1Pzi6v^*fUUhl}anol2c^_3Fo-&(ddpcGx z#GuK)-}?s#&&Yh?;+K#wT+F2{ z=XWMAb8+2Ri1;XEE*Evr6#a;bsY`O%-I<(@s!a$uS$R`~HRx3uPfUj2%$W{POuY-a zuF9TING8 zjWWYm<(vnXRAjj?6!ZrN856$kh)AI#ktH%aupU#1hwvLf7obo?48);PrY$a7914Kl z`Jp95YxGj?C-seuI=v@6wdd8K6VJ$0+WbeH(^waId@2Q1e0yVSviyhV=diA)x4!(v zgm5q7rg{wZ%oRr3=N}KlKOAfO6k1ET^IOsjwc2ctA5mbM3Yj@lb{)&we2KEvB(4MH zS&*(@B0@nPV?Af}WWw;&0~4DljaqzvVjj1(k4GgkFO=UHUVlM%SgAC&p?;gA{mWo| zg?j(!Ed@z-W+h%#gX^iZzs|Fc&|00L_r}Eu-*%mJ;b~osR9RTziW=U~-Z>E|9OaVo zXIWAr0+Qk4)A|}K(@(wEfUhLra^P?zRwsBT_fdBkL>vL^B5+s&!xgrfZ{=JJSuMpt zc&({8(h@nWDhy2UrcQ!>Q-xa2U1#6N%E;}FjtfLO8453OHMU)KLclI}$(o{u_*y@( zZ=F_E1+?l!rofD@2X6mifS-VP!dzhp-lpc+|46vQl`>F!+>Qs%Y zts+w55(5gl-`eWq3nnawAaCgDi5$r%aouPj@Waa@M;2}19pXpXyW;QPWMx?my6MuJ zrjbrqbx`il26Rg^E^>T4(sygPDP(y=<9fBSmqkj-Y;GISs8)Bp-tgs9+?bIT;(H3> z7d!hZ;#(fPdwxZ+#5DZ4xpj;x0X1$)@TR`3Iyp^O7hHy+!_veV*NxH=dsC-07Wy<5 z29n~8enR>dwtd91(sLip@e}m@#fR)yqg3=@xB5NYrqL}5=EDceqql?c(V;RwH!GNH zqJ3hfZhLjQF>M>-i;uF;;lHm)>T34yaGh{4H<`azP-oH`4;|hWB^P$cVv{-%EuZ{> zOnj)+Gb^e}j~C`?0K^c3aqlxC=LhPLMfZsVQS5k}aIEZkE^hpU*?&hnS+>l_#gy_G z?^^wGt$x^+-*l6)wwcF8|$yCibhOWML+|#&1)jET=SgWiCQOHn# zY#ou~PKCv~dyy+FfMDrUMmpjQHWCfC()TyOy=~U&32c3Ptpfav;~zhxHL4f`=}CER zALtp4X;;h`8a6|y@u)Z3^K)Gvmm|^W7|VElem>`s0Q;PNiDupBM`YHgp)>NczCYsY z*w3fzE+%Z8o!d9V4w>uJp!UJteCHOQG|Xp)oajUFY-SZlV6dNlJYo;G3H5+9$ zSr3x{xrR<{5FJo9mn-5ue`3e5NlsWpEMp##e}14i9W;f28giY!PgP#`HZ;;TYu*IJ z9NE=06XpW+g0=4I{5nIE{tLu9K!lWnQWx~``IqUrdIvxC`gtv6k7Lz!A^s8SryM0J z-^ke5QV6N2UsKQ5tiRlmy_9n4`x^6FD^S6hXHEw`Bn45#2X#S`e<~`~aP-x~{%Xft zE6@mMlD?T9+_sW%iJhvQMJp=e5R*n>wGuKCNVkU{##QKi@lTXB7)AEn=m)q6JZgY= zdO~Qh-bihQ_p77s5q+{auICMTgnV0&_H4H&$Yv?C;H?3jNxj^c$d86v*qNVy@#*4s z3#!hFKXE}Hgnt-5w$5YU1Mrjmap_2$9oCTSOBB0cPgiI<(f5K88?6VbeGVlLOI+4GO6TDwLhmj z{>x(P;bI^w)452vcI#xvimD(69xV<-0=G^M7wVzBf^u?dM_;C?(@RJ!=gLaz%f$)& z6x1&ar~A$$N=W_lS*?b8$^)=Csx7s%j8+lxISogu=Ew`wSJ$wS@p#}@zqSDD{RgLx zVAR=4sZ&G-L1E4D?amIXIgWB<_K)!&CpHDau7e>-b-dC}`Hxw=Yo4!}h@Kr5!%W|P z*VXj%spes+z5Mos$IV-eiu@4ZPBjG~izRiB_ht-QrogPE-r6T|sv_33qJ%ToIOEVj!rd9w`wP$tujr~5Re}+ zZ@VJk#0%T>h7A9pWmM!kn_)D+*13_(LuGIvE-1eJDQm1x27R$;VS@gMv1q#5fTHHX zqbvV7OjfC@4^=18Vx~lrMU@)xZC%{f8K@uNwqQN8tr5PKJj%+@|Oil^l9F< z^?gjPJdHLE{c^s&xGcxg-aOLZc~VA|s^PkhDX=9qrza21-(7r3nAe&JF(nFrZhO|8 zL^B4RPgwH#bk1G##&md?2@df^k(#Rb7pWY<9}XtT zZ!dzB%;aBs5gr|>n1bvOnSg`%v&3|*UP_gDF$lNxc9(uPy3nfn7%M_#S*(V{=M441 z9R>u0?nRIA5Q_C!bG~Q*_ed{d*S>TqU! zQ_53;$2)U;Yr{tnf}X<1m83v^WuCo2B zgaG;04;whvuP&<4Mk6v;F#0;}-LT>zX>_#%Mni-S1ys`?Zt4A^Ut&(`fe!t7|Jk{-Y@LN9V6b>SmmZwTyN2R=KBE$|{xL;a@*obC2vp-R9OTqMRETTfGLr{gn zlJSLTH{yCgTr|d_&-guC$ybW7+O8pf+%*zeEd%{g>YHxhcPKsB1mT18#ojeo3Mi$P z<+u)`k5}xT*_5#bBh#5arr9xvnE}#^?-}-ARWlBQTIC<=3^k_6mSBPinYqwL7BN1>689P(SN&a%f*FK~AEOCbx;JH-I#vfsi zG?+_+Y{PtfmUH@Ezov`6M*z(GNChAOQ|XqS?f_dhGB$w zg0(6`qsHsW-qU%g`|OJ*KoG~s#-R0Vg34O$*5l?pZ@2g5r|jo?6z(}mox}aiyFd4EL28ww*vC$nS_OF4fu zstEMfi|tzr+C?_gv|t+ z5xP=Cg z_c(y`J8rY&xoMV}w!!*ZC?TH(VAh70y4i}%M9SP zvnG62y^|IKS7bWPM#w}n?$Pn&LoK(%>%{iKu&+8&fAkXygOPvmLe_Azcs<+r*%Z3s}^1MGZ6%%2NzAn zGg<+Ro&ot>p;-wgku^wDB44~?#RrKz6qF|V;+p#E<3~SD(w`JRW)a*I*=*btNhqz0 zTBiq|I~S{#HStsO0fUNmuS(Z5#a04+xUwh!BpMxLt#czp!kMJv$cR$?0{_^)^J%~$Ne6162~f`v$W`Vc?(-O%PYkz z$xjHLQj&j#cWn?GW9C?wm*Frsa;=_geuO;3|C52{Ai~h5%P|p_FNx^~ zip?Jl>~k#jcZovfefW3;^9xrQ$R3DSG(UH)LX|yQ^kVxYNqETjOuq?ihLWV#~kKQJX;GNvun|6lp%+w zArrtD_FbT^f4r#j_DfY|cg=RN85|}z3KhRwQy^H;G{6-9mtX}*o3Kkp!26PU?rIEM zB9b|ucBfCD0eO{pqx&Ip#>9hQ#Me=zC8fsKYe|z6!D?k&MW*d-^S6#)HTV6+9K0%Pfe>k5qv>Nuw%5l4$xTU<2d!%bLayxOGr(!rl(*G{q(A06b6 zmhd!MX?k@UM>A_%sb;lP!Sv2Y&Cdhd(}=G0YRzl3eC)RagHPyNtTX~-0@2UM94Qa8 zOCRR@Rty3OvAyNRtPiAixl^#gr0!wSAO!LCr;3r!fv7OPK_Y0x>OgwzikSCH0p)))mo)(rm_N$|sPDPT&QCc5EBJS;*y%rL4+6aC?*0;F z5i;lHvG0cVd+!{|*u=6GmTty`s;L~8X?%p+$tu=q!#@yr=ODhmpr|^MMxteBG2XzL zt9f>ugjqCG-S9(7OYPf#t=E1fe_6bw4NxywWrI#G&+RVhJ{y;@6%B)n9H0MQEJwsb zAnU*TQi*0xFd>`N^k>q!{pGZI=-elWu^=4Q(BR-FgfXO-i1cx!S7BwT}?J%w~xpM?{em-`I zvXQR#qT@j+@9y-wiL9P}dVE%w2xwxx@SQ!;+Oh+Rzz1-&5H-|)!k_Wx{DBY)_p`0W zQ^H15fm3${Y}ZKr&>w<9&lg^`M%{Tv)xD0Dkg55;9&wg_q}Th|2@ERpY#!V{HfAKp zFMkA2&gZp)NVR8n9x5*7B!uDe?)5668x596$eCfl2LngX29szkK*-@sA3MBaHz)e} zo58*zex9+kuVC{7X#Zf?r}>4ob6~}2z~)AQm06F;oqIH)3UBb4#gAsWk-@>Rm}LJz z0l$!kxn2~F0>%T)@9@#6vK;-i?F_$#Jw6wv-b{g$F(PK$R|;Qj?n7 zW}fAI=VxhK`nO$#+mNg&FUCL?z&}!H15Yb9Fcznbxzen$9HX%eIxf^Q| z*}c_LyY2SHRI?f7@6mE0KBaSkO8-uMD)(W!Y{KK`jiDki-%NP;cx6E3<9ot8hE=Ax(I zyWk}l*AZ%3ETdjzJ_GFoB-cBLi|o;D33}+C(z8IfY@J_%_kAR=TCFgzc7C%x$zE`Gxo-eNv#a7eeW%o+0kQg;;Rs+w zZ+C~cC-dHbaE{I8r>L1WAV@8yt7bMZTO!I2gnQj_xoms|!G`p7UmCU?XV~(Y$0U)aLbfEjVElx+=uV>zqVK)_gdoPZy^FUD9-E-Z1k&hYatEgAtDX(o zT9j!+uP|c=-A~#d%zflG)z*;?f!3W6D%^Z{;TrQKnC8&OzAN_QkG^|n&qzLDaWU0} zk?~4k3qw{alEMr;9|0Z?t#Thh_M@-}98_#xnKfW?|8<;wR_!;$$0{jOw;gLw67mxN z-Ly;{C$|@Vm3Ola#HUr-W&&OuX{_Z>n5KDuP26a%P1f{7(N#_w-Xv?bFi;)u6)5Qe zwQng$_?))7B2_n;N6o=&=xZ^iBqq=*~`c8nDo4cvp&0u zj)DEi8--7`=0nBF5QDxg)5fpnG(D(Dv>IYze*Cvw*ptTfW*rlB1%(4c0O{|7&LO5) zch1aVF(2H=Tt6s)gSbimIwwD+ru^kzH9^#9>a`m|FfR!+6REG7tj?{Rxq8u$(?=!} zny^L(6DWxl`7Tnj52H4&10reQV3Z6pE!~2Xicbns8Qq6K`tQMq>hqM`7h`FV%Ny{* z?x(v+tvNnnp-%at@TTw$FMO(a@LXi!ZC{kh7xfE)7FWkNwoWMzTStbOqEg8z@jo-h zmy?s_T&*9vC&9S1-6dA>X(rJ_lNs+KIqeaheluvo4|_lR9*-;jQ(5H4*na2B@*wvrkjVLv=Vz*prO*_i&xE@@ZVJAqCTGCc*iq&$K( zvoXEs27>^e@yn4+@gAuL*mCj2SL`v~U*`&FKv{6nPEA)35mQ-C3EGiTv2Bw~fPyuz zbj!An;99!r+P!B(_LT;VM70DE@yu7;vgzB>{bD*9E|dQ%HSy7P3 zmwzoGR{3?cS&H<-xpg{qPae(CM(>m}0^+Bgd#lm5%Ro5pm2Wyvc(vo?=kZwkU9Xar zkXY#{@KD+PiJ{HOZhj(~O^OyeJnnaJnr*!ZE^XXDvA`5C`Hx$mJPUN*>35h>dwclU zk8LEiZI_gTjm_hCsm&zRb%D4KKWfmBsiNFwJ)mf9&yEAuFesKym(X^77luq!Sk|Wd z+d_XkA@E3ZenH7OjilJ*zmHVFrNA^5+SYu=LP)~`N2;Ht01Gq43s%$N$eix3{;MoR zMw++bnhi0b^nL4$c%6hG%7_k+EApv@afyOAa6Mv|g*S!cnggU>mFW(#J&%fQZ5A!% zYg~Ypb3UK46$kIASV2){uX8WRTZ{*`lc>$Ta9F91qKwiEsvu<$msl7?r>Q-k7@V^v@l|wAXqGSfE5|F|iE7UFViDoZT(``aBZjEaD{!R@%zJ%bEu63~kJEoRI zAax-9HRhoV67R|m^bZZ-W-n2P@9g)h=^+rs(F+Tut;k76fGg$U0%#wwtJ51>oFwDg zQ`{hGtVPORYkx7=<`ImbWfnE#QTT98 zob~{ovaTgOt!gbfEl=bc9JnP?dS!LAb;=?q70)>{>t_ATrr^5U$W0o~_lw8-uV0mf zGy_FwOW~Q=N?%^tUK=82KYQ9a08|Zr!SO!7sYcd8`PTc7EGu%vkMbkKVufU|w6Xn= ziE@5}gl?0Uo1__Xp*i1Gwy=}~@WW@%+mM^+LtN0CU)aGxCU0=@-{|*IW_HI0riyMD z{8E^!hsxVNd0w0p^+;Bg*?i-(H8qg>&4K4@;oNwz7QrzaP7(+-!8C;$&SC9~B20f6 zxY5ds&*g=U|4qr8rng=UedU*(YypEH~kA)QhDF7T~Ts!bLgk{8Tl zM%g65)?y(gBt~#LbZ`$nN@gg1u%sPD;t_-HAL9aKk-s#t!nS|$ELI$5i| zPt6(m0LqZP|J3ip9#^J?GRqIh$Oo%OHUh@#_&j8oD#XwIWZK5e>?4NeUX_zzv z`XRnfY~B=;yBK_88u0yX4t*j%v@;w;5t#(<>Z~+#HkLAp@2H z@x!khGA;^i9auPCxV7CTtujkV&D8^#buiv zZhVQ6G4QG57A^rtnIt3%tHtNtsl~Eq2DPgfrfp|FZKPzH5^Yd%rH$7?bTnfaW|f7S zb;75L*eq2@uU!QC)9e?n8BLVYL_UL63euE}t$adtK|{eNdMom(j$$cbDg`4Y*onGP+@sMC4v9 zeK0%4C*xN0@fhycm)*27GmHoAsUA0ayO~LLy4&F0aCg-vOms|f=|h?O;?LL%&X2#- zGBb}h_EU$JvxnNio-KmHPq*I;^Iaq1U41>-o#DQr$>u{71w};-sBW%niNXpBzpzbE z2zZO#xjJ@IIYHG+E-nlGj{V-vLfh>;C>J%$(lJpzzVv@N`n2xtlSLW(jZefGj0OU1 zDv9lBJbVP=iP??zt6h?tn44Sf9b5Xm<9hn)xxx#!NI z(ptIL(l4P1S6(CGP7%F3gUziRDv2WR4HJ8;1v1v7?K?vQ8}fMYQXf#leSm_P`^w}d z3l^Kd!J7B{SKvda8FR^ycN}u)%M4Rh=2FRc(OS#&MEe%|lX`tv>;dS>U)J33A5m=0 zmFb;8aP~{LAigxe%r_m?5RMwO(GR(0^%rPBn~yZ>kbV5iXT!MJSEcR$Jv6xDqx|D{iyY^5EcRyE18dy5j<7`5_j2`>u7 z4sO)NVEatK+gi`TCoh2-_8k4c6p44A6ApaAaaF2E*kkfHK~VQRMw!| z-!VO{N*1Mq)8Pibb_M^Rvc(`C^%Tg^>66=&#dr6#CvP`UEr75swY(R?QcQ7ubA1VF z7?ny!?lR0~a4Z^}&Q<+;K&>hSXee)d{w~y=!nK32Sf&6FbUTwZW`N8NYGhh_Rqt`j zyXC^{7A_?R?gJ0Eln`5;kXcJ(`Tm}jd%b3vU#rY9*Gfx!ugB%@4BDAf(UP@uax(Cy zG?QB^Atn)z<@A2!_vABEUa$hq$8U-z?u32+wRZQl692!oo&U0nyXoHRE!Dva{68hB zd`$mYxRiJipGYyZnD+g9u>T_%Z!bZ5ji%dLxv8F9rvv61ySJfDSI2uJMn6h&SI7^r zi$&(oX8ec<&aa~m*p?ZQ33x-65f0SNnw;hDBxq1<;v=ikV`DP7WpbbzypdE?JO=RX z>cNqS>pYn&2C7qgsvudk$qW+W;-Q2nxIC7sfCey@RNrX2)fobt4K&%}K{0nyroW=t zUM<8z!_)lmTnw_o*bBD&Gg^3maa})=rTJ_2cb8hRmKOKC- zc2?55WnbJp9R1p}&?qIb{SOH?TPbYD)TxXoqGf(Rx}cDooXHHe4rNa4|w^n^Jt4 zxz+kW3Sq+-&*EsK>aqs1q-Z3<<_@Y{q!-G@wQr1CH_CZkW}$(LN_Mt~*3zQVVsqtg zC_KR|Iz5s;l<@KYDMePgWVc&vcikGa7PDbMdi zCDAY8fX3)2IpJyfoyUK^{N!HFM;i(%teB#I2coSwZ}1ZXQfS)P>HOspIP9%X9^ZE4oi)^=6pzTxt z#;ppJVfH2&4O6>$dCpu`ivdk;XR=O0QD`e-)89ND&c!hTragY=21zC<87wq;c${sB z3B__4$to&VqD>3cF_nfq(b!Mt}_s=;i_oKllCitgW)5{V}s zo+4f6t#oxf^$fpyinY9cw-cwm>g0 zpoaGs-Azm2AmR#G zI%*)E)&n7ThDU=JkbSL$cA3K3Zze^VcaNJH8-tA9z5AdN`VIr99k4=9&Na)QC7uNa zpvo&$yxSx0qSzhM8{nC{EpEIyNpgL&{#x$a04R)KV{0x%FkK$Hd8W%5y!-fu zY(+g*?6CGx#{i&gb+1zUD9=HN{~m!%M8X(HGKHflUGBE2mmJlY7qly5#f9d6t(8wE z=dqils&XAU(Z}4e-gBQ#JnzkA8xl9BIoy2s6`>m*zz6ZfvneZ;SWR>mB zOdvH^kPieMER>}Ag$nQ!iiQ(F;C{?M1Ni~?bqFyXGj#4~x~= zl0FA;Zfuv;rrN9Ci`l0?}RL{fA&`SW2Lf@!^6=t)bO*XPk>na5M8Xga}Efh=HMU9dAyPa z4PG|0S*Dh^q4t>(OL|(d^i+&N-z_-T+~ri!w%o4`gV1DPrYY_km6&EKWP(R)U0cw4 z`g#cY&RtEkNTD*e0cpWvk+&c~HlHb*m|Ck0R#sD@=~K;$gIl!5HAM3y=OAa=#4vKL z0Aj>L9;*0a$)Hhix?WVcM=eE4)_T_-Xr-JmQ||z^R@QJfw};LsY6OFDUw8Dn%1;3C za*|z3=2Mz1l}^*mwyPMA>pz%RSz1jOWC!!p7^53a1DgdIq$p!B)UA`(&o@a>oewrH zg`uC`qpBp~#3?4?B4yx`_z-lfSb`ITuY3zOz^y4+d_Xd(?rdGvc#kGvK3PMy?6=@l z+3;BC?cU5!vb|n}s5V}>e;s0_`$9FjLpKV*OxKQXOKDLeA~vkwkd<0?&UYp*T1llm zka0gr+{Fd21(b-)Z;b7k&5HjReI5IZVJdY%LlB%1=VMMJ$E~M*{rw97&>w{Z;jZBE z@xe}AERR4Jkz@0b*y~?xC-Z`RFP;})CYh&~=RZpjoy6`jZ*Oktd-7T6M~WNcOTekb zH|d1ZYi0GvHauT6_H;d6rYwJ4i9(*3EA7rty!GX+{+9^(OK|0#s9THBr`#cZ6*9g4 zaniu_BXk&?4+eQ*CqR*Be5WdZEcH?>Hg>M&@>4vh%DUXJ8F_9wT+iwRy2`Bb(-*2& zz>iqPm+Cl%E}>}xR;(n)FXzkwvfAt&U=N%ry7t86=< zfTihHNWEO6Qx16wuADj;$z0@rp&sf)C6W}NYUB|@DH#HSTOwgd6h~@T_s72M50fxG zwrve*BR<)%Avv*ZKPc6ZqSbs;`ZB6NPd)gf#Adt}9Uv?)rYX61G zS9wcE&h{8IlD4@LroeF099d5R^E_^1X1-Z%-VWquf1vg{ z$Up^8T>5eNqOCAZ_WJg7m3D%7IjsmVaBV@`e&-SoGNgXq|-uCY5 zCT9@v0j|OrpBYsI08J23jM@i}KGprD(;>WPnrG9%Mu4S;5X>_-F9aW+u&eVZmxht5 z!S2)({M}r`CjM7%DiF0MD))!ue2y=si?gxvtFaMZU)gVAjMjE$Pq>Ukn@$r#Ep{bo zN+H(<%2@amv1sPV6Ig96sDr2LK(hY?UA5mqE(pjmB?B+_Uf znwE8p^crfeD)PaiX!whRV~Eo0GY@^cp7O19kBpBWpZs-IpwN-HCtukE4K2>xWDzar zX`ManH-Df-Wm2_W+9-P~6gKYBUW7Y$ytJlyx~6zVr0A+9dAcx}$tC*``i|z1IS>xZ zvhpiX{}}@bhs3u%A)xfy9dbCNqM{<;btxaBvo7EPN>7p7#;PZkD3-HULJJTtRRO!2 zzp}HuR54gvQRf>0cvCT;4Hjy~m|l8DzxE#crQnku{^uCs|?TVeh$j+OrpzgXt<(KgFmHlNYR2>UByIiN(z2T zF7wuDq`4eeyMhfpj`ELWFG|qwH$ih-N-5vOb+D@DO;NLMK`jDaT?YDEW?qFuYvCUd8-nVrOpSv+d*(Y3FSuyI#{>8m4Udw&%CwSDbk#(~TF{WgerI z_CQRq^?wLE>wqe=w%w1S2q;L0l%#Y?N=dhLh?0twAd=D|Al;ypbT>%1lz<{3os!bs zAe?*S%)B$_d%tt$Z-@Qt^{ll7YizNHoOaO4+qP)mM!Z?0epX=!1WFVXvT90Tb}%h`RXa=hkX6k+is zHE=+{c_%Al{3|gPWTwEBtBTR&m8|48|a@Y(q$2i zDtU=!Hu2=UdEJsMm&MIdZifuKVct8HZ-ORzdyRMTnwFPiVWzMtYbxB>6QYjaeMF#+ zLRNzr%kG@KE_KaGES!i!0^;h0TsVFsZ=>5LqE8dhWTB$*$jBXZ zjcz1_|(B;<7a_`dz>KJM0mqoLsHLjVRD*u|gae zV-K@fstdd zD!qn$1|*6>t|HY5v4wP53nDd7qA>xbaEx$&UM%#h-@5e zle&?Y_oh#ZJ|*_6weRM7IQd(bUlJJ$jt372v8qkUEA zs5Ljll(_8#uk<=7J-2gVOb6{+{5`*$7qAeCCN5Eg!lQt7=1fXLWiE#H`ilH6BTYMc zWORL*!Q~0DIA?ju7=C&4IyHQBCMte0^og032N>7U0%#R1TsZ$&Ch2*yRgzdR75H)^ zhuqAh^C{=ZZF$)htIJFFY%6Wlp`)2#?Sm*t+>-#B1##$BhhI^Ff=}T)*noge^aW>mUSu zqOTt^>RsW|+~{;(Z}zC6I-1J8*1_j|R7ua-)qNl%VZEcv$fc!G)+H>TJ5GRlRbsTT zp#9+JM{~$!Pcd_|m9+fo5<~CE$f%9U19Mm=!j%bUblrNVS?D^-Om!WHH97B--g5k< zu{SmB&8ml2K)Ihg@WC0zi3!mmE&)A_&E_``Gj;dJ-yJsOl8YQ(b*EJF zU%;Qfe9@%jA=CmVWFncET$NPy8XlTEd(k58n17&U3&dUkjyoD5KJvc+l7^ekOI zc85YGZ@x9J$L^JA?Z=gb6lY=&j^{oKjoGhub!ybNQ(wfWpQiIVS{g5dEg)!ws_{O0 zjjhpkDY?mhdQ@G3E#W8V)YO@oZS4}4Uu^u36U16c=pRh4?teoqFD~W>O&2nLdI_aw zTbe4AsmP28aq+_IQKoT_2W#fc_qyli$#mv)3=eCrD1Jcu&?I$(sjO>GS>|K_??{Lj zxq6S}5IVS}>Y5n&q0n;=CgI;hv~kPLngfQGwDt0G7A$txYH*D~PrdLiLc+MyfOB;h z`uU`1SUn#%dgQQ_t9vnjZbhVB3&HO9SZh8;RK&Iwt_m|9Zj`s2zc7j~DC$__#xKCQ zkk~>D_uMe91hp==VYC`O?~w#HhVko0I-9YNQp}b-MF7v$&8*mG+bXCh^A>huvVsmg zY3$JZ*2lm4=A~)g@>{*so`*fm2QGf-2X@D!pMU|PspE=|AxQO-EcD`7!E5*Cc@EdvSV#Df9Jypch?g8^OK9X>zq)_%w->b>-+IP zC=qMJmXlotAN$G%Kj5duGH0oZP9X_CQLpr^t5RPb?Td_5SWi-<7~ZM4MG-J*{VU6WIVUgLw^@= z1<(-0DOuDF8(%b-UQR;D13=)3=BOH$!SmDK!%k5BXv`>&X(r+Q`-b!P&6OY3&Mceu zB*qmoD5KR4EwdG}T2nmipgY|E5?TW4>deCW7MIjqK+-FjXwWogHiq%}by|D!{-)6BqHMnceK0i@V_HV}dc~AtOpUU3RAf|lLPhCD zV;HOMiefkD4-h8AL7N|MT64Q>*nY3>8k(Ed?T2a@^92s5FaO$QjOS-ZZFHY_U$Ve=6sA~yY92@+ALp$$LQt%RO&3#C2KnJG0M6p$L>x)d)unS7P(MQRcn?=7NI^ne0&JzV%UOrK1{DpS33?QaG$ZcxphETb!zdt*^=^cb_Tv;h(Qjny@v|D2s8V=t7YrOOJ$R`>9OV4@) zF5+2ZMUmUX?_dYpeJ6WL5+`g7hLs!)1Zm&^or$inGM;;yz%)V%o#|8sbSeM{05|bn zy>J(Hyt#)xnZte4xz-iF!XMBy>(NmPU1#v1Q}>Is7$rAC}q9JK=bKO}?o6S-$V6 z)|3>*rpIw^8W2HTnn*6zl)6ZW7j8JX&+jX_OYL(ieTdGIhMhaZ7rLjsCcH2H^-`U3d zb@JTl653HbdR-PMmsKxEbbEbgl3s}#rWK^hJ$T=&9KHCcSXN1nt?;n>=P#@GOr)c1T(#bU3yJnsUz_2?#0f{$z2B+*H$%UUfK6 zPF=*nn%ix6o2xhBR}=i?`?N0YjT|(an2Q^xV=s_F%@XjRuWj}^x#CJ+s0e`j>Cq{uh7B#J z)ZfH9z6Or=$-r05nA`=3>zicU7^XlqR(}%+v39Zm zxJR1ElnK@t88((zUVaXdKmJp#!Yww?LLxcD2vyL88vUx)KJ6<(eq#=)efYTeK_3oD z%MBZ<2a_}JoMUsk^<1vDA>5kjez)eFCi3P}IW+d3_t`N>aM@*gbCP?Oo@Em{6Y9`+ zgGjBbax(5IzWz`&dXBmHtOoy3y5KT~UFf@aB8ir}p$M89`_|ZquP44LoB%RO>#yJc zZyTVz3t|=gM*}*%&S;kj*>LraYG@?iD{B_Sl_#gDNadPKB?b4>L!;=ub{sTDzJq9( z%JEaV5?e~FaZw|dJ&e`{KKp6{lOpNiU5N|4^OPI;2aa&t!8I zmTT$O&xr;?=Gna;%9pprX-&Kue<-DiPTWyU^i%`ooBWq{#O=I|)pc)A>M z;LtwH%4M?X$c?5&T9K{YcEE{>J*U*9mEx|WLJ@7UY)gN})%ry?sD?~-L0#WBxMKbu zz_exy2zb1MuCryP^--Z#8iiCk1!XvX(I^FLIlSAO8zfIs;{uHiNI zm`3ET;XcaV^1&V)#JJal$ps&PI|RE4KJ=nC8r%-^U#KbD) z$NPx2x&<}391Lr*V$FgPuM~u%=r{QMYNd}PbLb`*#(%ig6=g*?u?IBPVllr}ptI3U z7@J(Vl2U4t1sR)~_UhI`K0jz=1FXIhmEyc;`X1rVY{FyKNLu6G@vS4BTbuyuQA%Se z_$G}0dB}Iw*BZsRK!$R=-q;u*ma4{IQ;U5zp;(HO`R%sisx738qemf+oFe>#bdu}~ zzxT1vDe2#;7^S+pc0YvD@P|%Nt;i!~?X;$8&->5c2t3ul)XSgs>VYL02IIYgpjZ?I z3Je+)pE>aG9-6hh%AwD$trfke@;I9|g+eThPyC_5b{>ZKr^qWTvz-^I%f>D(l=j9v zFE%4*eC;#+OPLQYu7a!2^>{2iiEqZ!6iJyNnqx*%L`t82X0slgTN6G(nkH-p@HFG^ z*4JUBhx)_(C-PZHbx-uw2WlruEh;)hSF7J*TxHQME=b8~t=7Q@&?gHodcCcY{f;t2|Pkk5Yf+uqyU(D#ZDe`p6M#qYxmpMygS#f(c`x9jkr7B@pa^GnD^19H=IO&SF+Fc11)G%Aq zZxs9M!DYq7R_46OE26h8-G=i?TX7iWitIrU_nhf&jJrIt5>{-B znFw?F+HgRe9X%fE$4|!emX9>_LSv#73SXFb3tk}HIV*)^?C~QE{xB$c2^y0LB8sv*vBZU&=gxdog+lRQQ7f>*DOaTUE@TgkAnqJ3EPETWW^qF?zS-v(?O!6C$2 ztw#5dgYIEAWTwqipvriOQDS1px)a~JwY^9j^3O(>{0#6l`R1We`J86b1E&n=*xH#%v*8k)TT174>eqD zUzrqb_p2*eNo$FJjc}2zQ2Svy0RuSn}iozG9m@u!6d!6Xj^FgG58gL%n8Brtk)Men5!HeQCb zo+sr+s_xuiat6euZF35z6;mkvSGh#%j&GR6`-t@mf$M%T*49#lAwO#WQWnNC9+92u z(b%IbACKzNYEp{(%^B&&DF)tn-uP{a08)TLQ*`d4{XFDWr2Gy+l}_ji;1hO&RFBgn z%pO{F@QeH2{8$pMp!R8?N{plQx`7eg20E@0ZX%9KIZ!k6^YB4hTij~96POjd!fjdj zUBF>}pYd;vtVmZ*!)(b2LonSo~J@EFB_<|IZR4;oAZ$HPhx3Q@Qp!-G}xZI_ch1sGk_E&lmmawCA`$A?3V5kz-i~KG?-my3S~emHhxUU=e$YFr$kA)grLQJR z(a}Bgg*PPXTG$$^eu0=El^7ebfi{S>mW3%!>4~(0WVU6+ebYK)M?ZIe6kq7m&>`CpFQTTU{Jwl%$DFBWAu+*tqvO7|_4T2p41@ zZC^6gom<^+^+FW7zrN!R3%>Ri?9H@-j8b0x{ex?x4(-zndyBW`z5?B5{yN-Jrg*jI z=VqYlxRm&YFyjM|Yd&v*P?*9y9dGxJ+owcrr0Wb$sW0Z!p3SLV35UdAa$iZoVxlAI zBe~0=vc6STDdD?plbKp$X0IHdGM4MpXy^DzsA5$D=l<}_xQpuG7<-3+3;-?n< z&0xZ#_-)v9sFeNnWr)c2S}+23w|y0;(DJ#BAEn+JXk!UoWtZpoMBMPSH}Wdy0y~#0 zFyV2kku?l+zRmJIyqaFBF72Phh~u0Ec&y2ks0k+wm+;far0aYarau+lrz)alwy9OU zjknIaB4Oy^3d7=8#{fomWk-4K4udOZ#;3Rx4(qMI;JvB)EOrKUhXJ~dpf#ZKZvN$N zGNQMp5{I}gY-=|X*@`9`>^7uQ@B||BKb8X8Sk@`(dhbRxfKNF-wthbAWXNr$rLem~ z6*DH*ozMW<)?pxHWD|%Cm5H`H_Ug2B`a>^sZS=|Of|pNpMJXmscF~eMa1=G>Bv*X2 zWgPJAu_f4Erh<6>7P?HRlGh@lruW4G_q6E#zk-MMLm~m^r-T`J)2f)wrFUJL8gmq@ zMwI3j9*w=7`RX7O)=8c(`-r`$pM#?)sdk2=cxmYi$sTR^uoI{Mi6irn(m`K<=|*44?Tr%pIC{3aww&^CL+oeNy+&L+>;lzIEDsqtYO zqt^y;jstpr4ME!J5=VQE*~xo%&R26M-@o;JyOHP9u{7|4cp{}VUbsOZ>z%X-Jg1U+ z*BHDkht>Z1(Jn$Xh~#9yFg)wh;c)Bx+BBmAk=z;-`YtT~cK6yZ9u~fWX8uH zBPkRss2n018wtlPvzm?9(3uGKR_zK3)+ECBa~T=;5fC}JjKQk7zv?)<%_ynS4!^d0 z_RH1>9^c73I$4<{&+a~BWuj+%&n==Mi$Ww(W3{vl>v~{A&@=$>X@KO-dQfPP+`Fh9 zepfVD3YRdV6n_^!c9AB)@@dbf&H@?k%EgayS}dSabAuf5h(X+g1%=D&iEet2(w`Uo zK{?c#kTuDt)nRZj)QL=<^ovNVC)GGc#W%E6Pv>E&&z~uLtpuZ7XJ=4eDEMfF)&?EG zTRUSU7Eq0Cw*%!Rj_qiscRh5sT+?3sX4~~o56;gb4|>aKo=>D}x)_F|^dbQE?{0Rc z_{>Wlpk1V<9KXSJfy{_@gWki(Wp%=QN6XiSJzcv!+`f^Jh($X;cgx`W~N>;aKT?(U1rRwEi+t za0nFWR+IrSinzisU4b^`bIon2*-}1aN>=8KBr%fgPr~alb8Y4h1>N}Y z+p)=KJ16cm(vw{DeJ{=-)>#){&IFseq39LBy5j8yyc8^$c8Rh*<7o zg29y9|EMBYPgGM*--04C(Qm+E8-Bf!K3AWTp3U~Pj&~(lu~WvU%IC17jNuWlGZZ?- zg*{s3qi{D3kt{K}8OHH(M>6oJ9B_od;xd2gJswzf0_iD0wOo#w)JLhaD|fp(%i>6d zh>eQ97J9=~RKRdL0$i$eUpnoh$!d7iH;bfSA*c+B-D=Ap20MoRYX1dS?jMxMdSiVq zArZ!bT}MiPvhKoz!JkpBx5z%=5!@piWfcjnOC79DNk1*brJBw9yBz2cj0W zI__f1=;f;8@4GzWKsQ6eZ`bD1#S}neOSm?_5?G95oHX~{m__{ZP8{T-w07;H9U_TUbrzIfykk$vji_k3E&TPxf#k6VE zoPtq#7GNvGR0$&CFKZUQj41>qgv!r~X6 zj)f-Wh0q?kWwodJ=;zP;ee(uBHQ$k)jP#?P6QihDtHJQSkF{7bY@`drh%9KXw^|JUyB0pKEQ|r zxqI_xos-k~LU$kVg^~-pjRKTS(EVt1Cf5aaa2+L3FIgnSLBvtyT=+>X2XbOUu-vPg zS3LHs&eoCfzro~hN-ch$Gwh0yR;`N#6tg2#v}>i7U~UuOCY{4iT{`^t`bV?+A-P8K z6zkO+UT!0xc*vv?hyNcw>7kd0-Sl=4K%G%sd0uoOw1yTIJ>l$%wlHZr*Xw@4RQ9iCF)lCYlsWIs`sa7PwTF>7zmceA?%<8m6fwYhALnK>+L#mAFdogqSxV3M z*Vkm;f{6*;ZzUciRMj46PO&_y*-?1tjXlbOh<^|q*8+P>ge#GE)y>}ZY$D@lRy=3X zvfkqtF3xOpluIw4KC%95BWTYsB5UyfN4)qEAzlpKtXy@vGR#pVJIlgNi&ppkTngF_ zzYpwt{}j9CPTcwn=zZ}82dH_NC*5c{(vNTc^#Qj3Qg4EOOC{x2T}ESQdm4|w^VN8s zqHWWy{msJ+)?vs+F36*)*Pt@`w^(>I*CPs-h>-Bshf(XL2gc}mou8+Jw!~6YJFdXp ze8Iexgb(`iSdmn;p4jej44g8!t|4kQq~9QqOIp?-^C zkdTj)R;ShzFx$UhDcQfp>2it7X&J3!NK^@fbQFKHl>hbDfLF{SE8md|5%GU{v|^8R zF$tINGi#s1=yN{*XHtOEKi3qfy66C_qzLL|X^Uc@==$%=GTazWpWHeomZIm|Iu-|8 z?Z1B9K=>`At$n$z?ODzL?Rhn>ZyUxLdbOpQlQn=C|Mw)1MMV7m_x|NB>ZikEvgWIo zm-&40hGvKUuLtHjx*0pzP||KxH+19oO>_FMcY+{ppQ2Ix*H!%wcCxmg|NC+vsK~b*ihC`szs4+T%3@3X@Bb`)+esuh}F2FT620^0#v;h^kr>aJJv?w;Mjxv=r$b zN~N_JuYQDPT&%Tr|F2i@8_c}*XW$@9n}G@c%SGU@tl&5gK;rZ5p$7ATlP?Cs7Q<&y z#!;~N5b2ML;2J=5chJ9Nqr&@8SmhJ7sp?TIqOUMoY!w78!QThKZ`5#b2%(lAYstW~2p_LH zX+&FB1oE%(Qi}sK`3MYE=pnBoFSA=goMB(gq2;wXW#M-|)yb=45HV)Kgeb63 z{w8EM5C2x>zth0@l?3t*_>;?EGGH&_D6xT$Zg8F|L~wak^!Vt?n=eNc+5MapLxd@i z7aGkk3S50_n5qI0y(g_)s<|2EmfarBh{kRhTomxhc)xJpvG8eBi*nK@GyXf~M(k%H z6MdsO{9GPE*O=5vf8l{g0bdvf9u35WhB)EKkbaWZI8FL9+=nK7pP?2!Re^56`fp&g zQ&`XRu@Y!NP}0$FVEh6Z#k+#Xg=JaojoKxKf;sq!(bN`PSbUc4IKuxJ3)kEHKOf_t zO~!m9{a(tIQC@J|Llg#eH<5*52>?VwvP8lnYcz3T^@R#R4OHL(t0fzkwfV`o`7JDz z{p^0ut!n}G*AWy{(~5eiue%7E{cbuYKm;$1A0<|`q9gi0)_(Q`89!3<@q@U{fYR(T z2tjuCvSg~RG7m;rPc){qra_`A;=Vq4umTl+4tKIndZg`4UFc6fGF8IU;C+$2+G2)U(IdfjXic93TS zDf#9A58YifHYoW@p(+ksZF4&yzb7mAMb&G}fjrj53rjRXgo1$9g+CVp(a`1D0@t3_ z$ctJ*YRT3iUI+8d-`($j{&M0$@=XNmlNVq6hNAg%p>~agQ};KCznJ374#)v=Q}S_q z?jT4w@_ySjlLzDB>hOcCXEN_8;U*>{i)L~skqo2;)H@miAe*gjMFCFB}Yn}(x>`XbSk8L z_?(W%Bx%|Wj>g)O5Ck&4`^mY|FZZuf=D&Vvv$FtfDhnP;!g$UMos<5q^P``c2u`{c z0XQWmm)nbP+uc4ph3zcAU232&==yFHsJ~k&lrlPpCoe;wlJ;IUWdO)0m@x5Zs_vQo z2R?_F@RjM}M*SHI^MLtAj^-II4E;kmmrpRr)ElTC{wm*p+VfDnhvn=lq%i>sfH8uS zT0^&Q`K^1_Gmt&O54{^vMx)rXJ^Lks4a40=FcDRd;tAC-Tq0}~QOk5jisQ&OJ+r`P z!Kw0j;eT?{U+4YFNvC(zu>S@|M)3M_-{A=nEsfMvlaCR)lO(qR@HT{k?mfrQGFW+_ z-l;7!OA8teGJ!z75*G^?qG`gK)jIjB0S|P;>^EMWpSemt+b<_|hOwm&P`9q1iSyI3 z@ABFn@=9GvZ=2kiF|6*G+A;RlVt}tD4 zQc)IR-3~~sd2fVaeh%m*Te6ZY1uqn%NE@`NeWRC)ja|PY904*YsUFuTT)-^~<51vX z$`wT^4}vm0oBICz+X>gLJk{*)z=3OIm0q zjvge2#H6I^6lRR4Yh9g6d7+}|s5n_x{BA)eL$40iZ@wJwXKjLYs+WxN9eTAczmD9m z?X4ov_F`h_-~B+^N;QCh)GOiOvKSTMVQa@=Kf2S9WVK&Q)2AyP-KcM-qgN>0{pqRm zMBADzF*B;i3eOr_tdhkq$3k2^&1h@=8IQvdoCN#TarIF%7WuQpbWRLE*l%r#xo)GY zR%TA%kuo&gejVoqYLKjrK!{w1I&-g zF2#`q3u4)TM&$6rWe@;oa3##(GV)~4X4M5MQ&6~cQ-Sx$G`{xMuo^iN%oTl& z+53g?kG|Gi^`rnU78QiUKm-}YKk}#c-2Scz8TQkW#wH4KKtIu#LPGLml^*3b&;PF* z5OXL3G2g~#K{7aZeA%b!T|Q7)c!TWUdgr=NP(s=S>j(=V#-XOG>~kGzwC!rzwT3zp z1BrTek!bFB7c4=;@RL;+3yV7JBP|IdqDH^L4S(yhIwFtX{rcP#X9-AI{o!-O0C3)J zHUFr%ovPa&gNTB}K;k}|HNmLg1*1>txH9tET+e?L=H)b5B&JO%UYTy;2e#0~3P>k+D7_HolTSBPWs=^|iV|0>stw68hV8?g#%K@eN68>@A)fa<+$CT7 z5qjPCi4nsJTZWV6^U2oNlw$p9q8;?vkIFZaWu&1m+TfILQ_DXlRG_M= z?)F5naX98yHva4#_red?W_-s0@G;Mn<7d*|LroDx=TnaIfWA^woc6*;tRQ`dazZuq zcutHEUEp4p_fE=~kngh%+^3v|>^F-1$mTvNa=s65R7gVGd3+aiS+bHYcfDs)XE0o2 zpoRQ$n34k{6yD^Fq8g4T43jni^Dq_3fNf#bckRy^&@iIoL)Y~2?hVSW%Uje{YDxDp z$sa><&b&R>_Mf&*r|1%>P|eVpvKE8t9U@}G6tSeCr4&Zq57RIJrvdS@o=MlS1xS@v zHbY*+X|sU0oJV&v?AlYx{01sqJE{e!4c`OY7n)DIV3pNU4(@{z3w;?Gm=6?qSNfoe zdfT;MHyq58+V>e(Xfk#3rfS9Nv}&}~uG+@ScohgD3%Kt8ylY7(Z01o-NJCNQ@}bw^ z2MVH+bJI_cVwVZbjc5UtZ2Rcar8PSN?2tJpz-CGOK(C8>xzD z9H>+>h>s0YX=UzOQMb&Y$FW^U121Q6*GxB9|CZhzgKSnd3oRC}I*FB5D{JC01uKkVQR)kXmdR3Kik4S@t9hSYP!Mz1 zov71h+RzIw@liD9x64T?vY}+nsvx(236pN|-p4CH{DqGg(K^&9 zD?i{kLz|lvS&k-yWh>!^DVdgr2(^4duHr}4hRx(kAa{Z;Z~)Xdh&)b48p_zYgO*Ex zb6IBmAR7KM)%76g=~!d?;%*lF^j1>v$gbW3~2)IaT<-?*Li6O*|sSptlyjb=Fx%eog4u1&a5b zuVxV28YqP^8}i0>KR&g|ddZ7z+1g^baKkjenfs}JShjKL4Rr0j&E5##ADcmPnQU9h zf7r{e=M28Gi{1p4r+6qbGi6BPsbJH~!<9i%>PQ#?ptn$tQa5k5z0NRQpo$r+z>!gA zzBMd#m5-ztrr7LCrZu=6#@ieJL;fI_Vc_;*nhm`W+A17oikC zH+|{gD)dtfzg)d*zbH}t243z~TWJ;sQ3=MQ4)Y)P8>e4y|L9SAb3@v7YxyH9@?VbM zzGh=|rm;WI0aF~vjCL6aQlwn)&q6dlbk#V{m#m{Ei|+g$g9 zRIG=pd30d{qkMtQPgby}A#~TgQ#c!xrgCyU5u_jD1|MN5S}Y#l_G& z=u9sVM9Z?k8wjPS{Bx&c4yign>hjq3_M3<{P=!hQk)e#XdrQhU9TX|i)c02?{F6=| z-X}&L1cLz-3&KkICz=xPxvqmoaTX_{-vjFPsh<@i2BQvQJ&eHpcq0$$K}oOZ(*A7I zW$x+yoT3!}TSQuZ_sq7CawZ_s*#2VWHv#UH&NY>~pP(x+n^Y4Re4mhW^iI^cQIA%K z&q4)8qF+)KQEbyp#)v~+UOJ=uluXKS4HN_(asl7Ge0j{jxEpM zr7?$%jrTx}vtLX#(exc#Ib73jU9@s=z$_IRAFb^| z9r3T`@mfG+mLv`X8#TvLSK^C!s0d%-GH~8EAs(e#_C9$+BQ4gyxA>wVF8A!XvUgSU z`m@Wv86UVSza$lhhm@$CpQ|L$5n`ki=SQzCu(GE09ZhTTe^? zS8~HTwvwX1+}G0!guXpR9+};4JT@YthT+(Amay!D{k4KXLUgKPJPpQ-IDhntXibD7 zfkjO(fr*SCt`Yp5iav+YCp}TBnAT4qLOe|Jm`_Qlt9qAk{f|G+cV)yy)V>Xr)k*ic z*%{4TQ@@xfp=16F#q<{zV@mf?P|W6sQr<{v@ju6y(O1Dx8W@gbdiSS!9ot0H5J*+{ zth9cW-yX35`0ZGhhn)ah+J!hOQVr_t_+PFc(=+LmWXXHAt5}a+6sO8r|1y}@^BZ^NLw{?W^?)zvzlnB3qYiRVluOH9EW>2It=N$2 z>|VV^uGHXMv$JSHGjR%$PeJ6R><{xtI;C%`%JVb7)I1q(JEndpPY|RbwsU2lEba0j zj{is@p)f{`*ufS_*yAC5teQu~&r(OF`@Dl`E8^e$5yVc<0|zrB)jPC>uAMl(nbnH? zqZ;(xPuJG^OfSDABZO!rl{ca7bBF?~*tHMG#H4d5V#~!rVSboCK1IK``5OCT=U?|V zV&0k4J9=*vaO6Z)k&8cz=#^T5^BWJLin!pRTWzwxI+jniANqDnOEbmt4CF1XiuB`I zo25eUhgtoTYf7Anxr$gGS06*WJT0@M^y1tOMogQwExdgpB0EWeQKu?9LOyUbTI-xe zELu6;3`0RfZHVbV6-qJQS|nwFt-pw7_|gdX1g^Cm0(O+*#lU7eT@w}x!HCNjCyJB+ zvo~29=9bb8Y5`vD`JqJ-!ex!Un!CH!K{8VOB&deklrc<=I%`jeS0bJkQ}UKtchN3U zt&=q+-;|JhXzG&{IIB@!)YH||$?Z(1DgWFwXETsSl8)>L%V^|+8pt_t6?{e7o81xt}s-Or;Uh^vs z5=yyg%PZjJ`W@lZ_Zq(_tQzXm)VFJl$&+F4Q$nSA!3{G%)3Ox%-5~i(I&C`ACe}V$ z8AEP`D9r$)R_#{1O`O9w1f}cU{@a#+{M2+~zw$B|?5jE=Z=P zrIz=6&~w=&J-)g-?T;6?wC?*$Ivk-WUyFT2JlB%_{&ug<+M}T6Fe?asaZ|yg7d_?x zfWM2tR!9apS`W(iXjk7Vk&Z_vvkM-#_=u7F2WzZJAv4j6PpBp|Bw^lTz*_9FXTQf{ zQoB?@@^sE|Nz};Zy@y1VBV59h;gcS>8o(3K%4kiSP?D6KJPk1rCsv9G?;R-2EKV9N zb!}}u`Tj*ZpW;mClHdK_e2i-e|J=40^JRn#^^Nc%g=E=Xo_8{fo(%_pN`-IN^S3jC zU}CSo?95k;VjJdsrNzZ*KttWX9g2JX9)sw4GkrWZ1O`A8mWu=I;0ijOW~x z11%W@n3NK)N3%R6UWh+H;CJVOP$B_QSOZ}T^;3kV450$~dT+1fCz#80exX2=`+aQ? z4|NFSAb^0i(7)=f>mDwlXgx4Amo{$cMh3RY+>ES*=4^ho7F)VCCgt(WSo68z7ZYa< zw(|MxII0_0ckX?i>HK0x`)su4DOEdb&m^b`KRu4NY@Kw@qGoHHaq%SM#@et7Bi;jd zpVHOdXvC!71eie9=3e-&z;1*PYNIBE}LwG2U)c?ik@NU zDVOq2-N(aJ*d@)dX?KCq1a#5SjjHF%1>xqq2?R9k)?$GRG4ptMa8LFWNe3i4tP3e| zXIUYR`>f4{Br_N*WQ%SAB@%~o$BFZX??i&2XyB7e=BQdu7%CNgm4A7 zU?n7)?spM!^lERAxKRW?DG#d^=)r%o>b)2)L39e<2FJtL#k1|5P{-*Fp;x=^!b?Zp z?yi=*MbX6QOlnWJw#x)hFkDZ?e~S6gcA3M~nd4Xkg-0ih2g@j>lb{HSocmf8Pzy29 zfG+gOky{(l>cetQ7Q~i3i`u%#+)%#2uVoRqqvQO`XgD|JsY`Kmo;SHNG$CjOpWmwi z7@B(XMszgH{|!cc9UU#BSb}&tY&=EWmLv4)3d~>SNm$yAUe=4WCV9Ipk>cPA%`9`3 zmeUb)uy=MY3bG#O#IENWG)_OBhn(keHA(i$bu|4G+Q2X`n z-J>K7uHN049UB|FXA2lODPOClXt+nXi~bOt8Uh;AYW!mw>9QG>-Fz*Yc3hD3W1IwA zf9FB~xJJRo*?(BtNRDPYLE1(?zy8YyqLbkuSaLDI}8n@ z?`!|4Q%^hV!SfJiKj)E^$oI1!dm8Uj?%!z!(Ov zOCo5>xN#G}P0%QTCn1ar)J5mM{4><6B@M2Aiu|zbHT;WY-cX}`sr9@G-bRx7 zmlUqm4{!1UwYK*9F8Ve3UM8pDpiVb_>KAr@bh7kY-qW>*S1cyoH|eOSYAq^!$U=7^ zU^vP8Oy>FqGxMbx&8{zpqnV|R3U$l?e+`q&ozMX#eeafn zS>^@r5oLQ>icYg+>u7rnFBhFgRw<{-Y_-1h(!Mx$tiC9~Z`G!q|645ho?7v7LszAG4n`4w7dL!6eHbzO-jW;#XSf{5vb|qxm}Rf%H7_ z)x@jkW)~asqRaHRuI9P^2xx(bea8%K$YuH0aK9%2szt>Yt8!YBbL~#u?=QZPt9I3i z?m3`%H>MgIYz{8D>D8`g*4Da|)~*K#a~{2MmmO4}1v{;!Yuu2LY{AYiTiYq&U#@-6aUI*JN;%fX$E#1~&_IUYKM zIUHQ1bNj2kWKE5t1Ch4{vm~nzzAxlcY)=(A`t0JquDNk5;K(=paV4S1Ms!bqFzvl_PP{r&yCD4*$6-s~o^FKiAMBkqt%A2a{&hkz6Z0!`XZPNnp8e29Uc zUS9kIi;EY(Oy&u-65b1U>tFgsxO2r#AAgrZW^E;&tW@WD_}C-)U?=hq7!}E{rjNVM zxA@I%KrwEr&N=gnY2)r665(dz`5q&p&os)h(dc!nM6j&UHIPrHreGts=CBt;L<>tk zo!J_Bn~`V9S#;l}2}kY96R{IEQqs#%tagpxR7351edDv@8ClH6xDDp40;)R2v;G;K zI}z=O9ka_svnQN*@Lgl@qTeR5$MbyB1BQ(z4kc}brci4?(YfEPBU^}^I?{WH!lUQ! zTiwz2qty3e)do$ZJoOrgJU!Lo{g>SFz@?P-$yYr;;yQC4U;cn7>EPe#m@!hpVf|xGOcyogt>q^GBU)IjfkC@ieMN$jqw5Cy*pMsc zO;V?Oa{`q5CWuLFqFg;x(!RE^Ge80w0px4NovsF^J@Q zX~|8dZM8Zur18#a#0l{Gh24F!FWOSP-4rW`xbTEbu9YH--*N2SwyktMZ%)~G#&VxD z-{oE-6p7)Q`?vT_PHgE{hH=s5ZgE;up?#eg5~A@^c7e%N3DlvjT~Y?98A7lt@T|!p zi-2~3uc}037)H-H8%82{Fuu7%kv+6tS3UEgek6-S{WUZs@kSf%B6MYD8a^S`xZm~s zq_A6=U<(_k8k^MLN*hyZtSakjQf>GO+Wx zbf4?+23OMHlvsD zrXhZ?*3YpeKPRoJV*X3{`q4vO^WkW?Cc6UiVAQMm4O#}S^NND*44*t8--=RN-pTmM zBl$&9E-*;#4N~*Evy;Z0H@_O%XWf(nsaXdqgOcgCo24*@K#`~Z(C^VX)UApG-ZZ7G z@H~Ohr9M`XHuJFxqvyvO>go|ENEEa)R8jXRN^M*3O$>P>Zh>y8I{cbr8OB(v@H8pB zmJ_ap4M&5Bb$`AEs!Q2!Fy}(88pkwe2*7g#zY3yi$hPhqbbev%=M#2{KZKO^_Gtneix`4%0 z^7HqF;)q`Qeu49I%Gf&9&|Y7K2Qsa+_nP(D#;Z>5%k;?lrVi9@UHY(@p8RGGQZZ$R zRPSD@C8CE}w8%(ruW;!A+4mX-DVNh?$HUR_;_SB=JmD+G&Q$$Ac-4{urrtQL4;pX_ zTt)GJG%EAl7WZl33}pYqijBeaMpExg?-&xC-v7LM%Jh(OIoDGRdH8-H5K0}1YW2bB z!l}>Sqg0W+pZzp2hF5FlBRg&DV^(mTfGU!c#S;~gPeeW(y^4BQQNAtknNu|158Xt| z4>Sh&6$U#P;z}vyEhotDoEXyA#g{e0BX8!1dXMtCbjvxklK4W1CSuqzFR@c^@|3{`ZinYNTfrVQXW#$GF3ef}lqYyI zz-KkD-6cl){t#s0WPdpS&-DWjYH>V?erc?_j_I=J%Jk30s85ZJKYoN3wV$xc3YPTv zzReBeu?hj=n*Gja-I5X;WSHEm^H>u7SzNS@8vu|^x9?B)1!Zegy2Hj&2klc%PENOv z&Kcl)IN6(7V5*D#?kgn&>e7C&!V82-z7_O<kWT<664Oi;w z%_O2Lb3Wfh7of-Rx|}*pcuM;@1KPyBz7kx<-yYfm)bwcffv(tr(tvmDWv-yW>g+4o zboBHR*A!w$E8mdi_z8UwSiAOrSo_PUD!4D~8&&D5vpeIz&n-&)Rzb>p9OkRa(8hm*<^!oc1sr+?!~Tl*OjjcoIiID-zEuju23R_8E4ot@W0r@qjmFt zha5^xXw%28R!9wEh5q-t_@kB1Y{3*${0WK>mmvPQ20$VHkLn-%Pp~10QdODJTQHCP z6QHpH!x?1r|9vn2Rp~oJz+1U{iY+MU?Heg+zuN!b{t^0D+W*T3Ab#Wi|3|F-?-7K5 zKFk}7|3|#?e+@nm6aDw(1JS?cCu0BK$E^QK3fBFPQZT+eD1{(Mg!b^Mn-vc>J~<&y zijGd5lQ-30*?G^+YATS{h_`W9#dJ;CTUgHHH}&_Aj{XjDf>$DCtp zWOjJs9I%?p79s-|MUCv7q&?1)eLpC!^~2>k_`=fdUcOa%Rj505k^bt(Tw` zggb{M84A<(v6R&Uu(r;sNFfA}@kMf_F-!T`d3cuy6uAysmH~A;wt{ecIdn1X zVS+_nSW6h<4rtl1vao{Z)ql$fp&-plBPMaLN^vKaO8!cLa_ zxnLmneN5vzMvH*Sjy^Ctzn^R{bt}gzNAll6`|V$YMrc&SudfS-acIM3caP3V86f`k zFGFKQyzIM!Np1j$UG^C;>M|6u5%y!#C=MXLGC*+#KgiL$a8|pjTEB}MBV}4_`-z;M zVtB(|Z@%D;QpP^9yP}`)45}&aT)?QFIldSe&H*cARum(Gv4?D=1|CFg`szlrb1R_4 zo*MH7^m!bq*3lnmsLv;!NekK8Ov|S3{PE;{MlHDYDEYR{`T{^))2PLuLY>oDKo1_9 z2YWf-Rn@SEIemN=y(qz5!X?cv8d427D}4&AjRM>^Hfa=y zex3ydQvXs=`zGdz60oiTUD(;T&!)h0`u>55m$#jhq=SI$Bkcg$NeWvao3q$f7gCf~ zH$m^I^mcmI0O=ilZnR8nr_A?1+K42A}$rQk}Yu#?2Zf$^!loq@7%XF-C0G;^DML~NGeN96laF|1N zA+8U&`Gno~V;2!pQ?h(+t+`a&MUc*WMKyqAa1DyOSjCtRkWGTXE04E8%byAV`(ZM?eWQ z8~@bY+Ptf(uB>b=(YrTs3Z&ts&#f&ufBFKND^Oa+VRHLV23I)KGBFF;OilCYfc6w- z#Swu&B4Oei)(>`*$;AbZSQh4QQ$K@Y-rVa(@Y2(O!k+M|JaHH2T6GE~vC4VE=PeIc~p2pDl6-=t4M&Gs8Xo07nhpY|3M2F7vkXjJXEqdNS5 z(};~1IIi0{Ge#I3dOCkPK2nWgD4V`Nn8{sq{R1a%Ov7L)&w?V(*JK*_{dknd&K^({ z#vhsp(le{7V;Wm5VJ=n3E_h0Fl4Gqf1GsR(tk$01wF1B|_7QB_*cotrZq-ufq*35# zUJ%NtniB`}<^ivnz%M?MGHFSHh*JmlYpA3(`bZ_!3mSPg1nM;yaH5=b_cNaYt(nG) ztyj0!^|<>F+4N@OLg)E`H8)JLJc_7iXruZ{nQ@z7+wTW$XW@QLYC3H4kS(UKM7Eu& zMFn^?kb6sXivM=8`+5=&_@>LM_93*mUZrw?WLalmV1adRX5x;fHZH*BG2cZ{`ZT@9 zSi*k|_o$|qmj5^tN9sn}?1rnp7YuRkeTES0WCsRJ!323*lqrCrsm z4N#m5dml$L3VZNBy^{!f_^1H|$McBnKwC9cTgG4U7fjRnZi1az#Cfl>-_qWU}e;1QgzVUcU>MgN}27UE2N~7vLUAB3Z zK8tnO{u(a&tI=0S@e&}c+8dH`Bs=K(025u>z#V)(5N+19DIA`7!dm&cAGVn36dS^Y z#`w$sl0Lmk{s;+9qnt@)+44@urPj{F|4jUT$;gP`-MicU&h{y=44=cIo1LGxoR1Sx z8++xs1H~+p2OT_#SLgJ!<@#;Z??h`JU6#h^xpbcWg@svWvLUY;8C3J>;!Pc|1qs?p ze;s`d_8arE&g3hlRh!*SXAx4kakD};4rY?maeUcMQeS{99=g`iHgA||7V2yjU{B9h zj>e7fepu(;+e!-;3+*Xx6v$&92mB(N^ zN4`er+5NQKjF?`&4O$wiMp;Y47QebQRKI+CQbYWKpMwdPP$7n6eu9PYfWe~VWI)(* zDJ8eFUQ6`~(`eb?L>2a)$Vq14KEX4~k=DN058nB{5#k4kIZO}Lbe6b*p$hp8TG$Gb z1a;`+oQ|(!fXR_>>#ouG3fnxEEv&V&tEvU6OEOP*Uc76e97|5dezzKK@~ zI92xPwy<%KO>sN2WHQawd+0wS$J)Ajae?6|;3UJnVnf@81B*y4-s?B1=WnG$wpI2y z@M4w@S3JIVos#wzMnP*6FDd{Au*}iJ+tt;GO(>0UYJ{|Zt$E@mvR?zd90L4-X{ zwf36_Q^j(n&N4`)zIaJZMI1H%2|`Qyl+pao?(X^CkE5eh=NAU4>#v%rStO?A*Q0eq z&c93Z1!qh^E$Nrr@)ZqQMWF@~RR+}=VQJlXJ41g!+{Z)8e5)dM&Q@Ilu-+E%;Hp~#BVyK!Bh)rmw4TnA&~Iq8HZPg{ zs#~gJtZQ8&s`T{3^l$6#XKvoz!8a;?sqzNsAaFJ&r^7-MAph0on0in(@>o>LL|Ii`ivGGHaJxnbI}w%=%-|`C&GDa)&D>1a|BeUi~YDP zRppRYJDaac&j&lAD;?}vt7?EA52%Lvz5yrf7EaRjA82uE&O!`OOLJ!TM|5I81M?9; zBz?Ijz~f&ro6eH*Jd2Y6AaP#EjL}=tsns(ur30!|phEd)BNDoHRuDVD^(oXFI94*s z$t=uV9X6lnM%nlL@bS3UD`fx%L*U--eizx(8!h`uhldDq zeI4Hl2CoeVExYL1E-485KabT|l|YUupe+q+S>STb_O>;bIx*qde5H*VCSdZdkqj=k_HV)B0=9#e?Q(72Ohkj1awazRCAQq!V7^?f`eSe9 zsCv7%w+Qh|M&8@&JAIdzYJJ@N+hpgw7+tC|bs`pxam=k#u)v9oE(kOT{r&?a zM_C+3?~Y0r+C;^Onu7<8wE5(CjQ|AGG|g{GeUi11S1pzLafA3A{(s+~TD(O&0kaV_ z;X3*YV{d!Vxy7#TlQ=NP!qaCqN_wX;fdN*m%>DA;zAn7$Zi0L)Y%HY&@3F{* zS=bY|zS$Gh3z$G(E<2z0tgH=N)>J@fA-gb>#!}=kus&_3?*GR{SQF{Ja~ul7M|t9= z97_hZppdp81}U;BGZPIaTu{r|BcFsTf$#*x`;7<2L^KUvw)&I{hw~;^BotpKb@JBd zFMJl?lB!>dUhL(;Av37G%8x0#z#&V{-T@9- zjjpk9o@`8^I(oZ4%XLF4u1jz?9oW?K{QIOmngjOV8&}%~YTyMD4-jP>hWm8E;c@*C z=;~-PzP`9Oe$*WmJ$tYNX~~HSEP?lh?{N0=?xrF9elPL+778RaKzWJG3vne@jpKSB z-*x2%-h~!t|GH2toy_?98X=UIMmllqIV;4pt{zSF_Pw0!)@M+?0Xzvz6}1vwg(A** zEHXZ&R}gJs^oIllQ&1%2M(H;CtH5xLkH*tM;wMB`BhwX-R$f32=an|5|``oJ~ z<8`$Q4v0;=DR4l9?|;*9=p->X6ghw!qSULj??TrDd3f~|BWT-{b&(n*rjo^c({M6> z3rp9Kb{y*REGNgcysQppjG$VEJiF#sNq2zy zBt6l?q65w0<)1G!`8BMpJR?bii$Mwx*}dr7MgW@{v>c)Z1p^zJ%oqN;(@-h^A*kQd zG4kT|TSE%YsAC#cREnU{l8p32v%4(*P~PM-B}TR}WrTOju~_X$8mS63O; z;5QJ@W^d^klsZ6NN~$(7%fn#f)A30#)u3mKCo};$Te&HCWgHzH9j5dO?|4_`dYZ=+ z6YxBscM)6^H5u|8%{kqiq)eXzkSB)MBcI;s!9dUshy^2B-yEGzi;j ze#ioD#Bbtq&!uK;+5q|lHm|?w)gc_OS2xYmdLqmP%EcrHFl3E9z<7vH19hbF@{KLd z!VaRPNv?vcSvUss{y^{nNb++4C?EOS4h%;7rhbQ(>OBu=hUFV2mqMW z@+`mk6$U$o)b*9##zmgp;eUqUDav(cd8U z&h*q?{&S5kmjpB9=C%dwP=?!;-8q>HflNz}LiOfd z!X;NRh>3o+5;8JhO*eBGWEaXz&8yjWjIsqRHwTBzVYy_U;719>7q zhXG=eH(0C3k7U5S{95-v`t4hJKYePgcxi!6h-5ZeMcWSID)OOAk_wSz+)3~O4I zee(RN@Sw0}{avUQ%`&Lcv{|;I;1b4&XqxG)=vTvjY9F8(R8X9s8}7q~re}rF(qS|s zFFM^U_{yuK!wXABb8_Ye`afZqBH0ha8xhmmy(80u1ZcziGVSNsurB(MsDS* zupdf4orQs=Y7i0S(Zi;- z=gLau=a`;XegXQS8J;O|mOHTJzjs`X0;%*7Yzzd1aTAQY{9#Ztz86guwO29kPU@yW0Nw< zbbHr4r#77h0``>r*anGUnOG@4M$zQ~cfvKq?nbZ1UL_~f4yEKM((G54z7 zM*=g*0ZWF31(#MRoOr_q4lPVUmPQ(QcLIAn=7G%(r-r*Dib}NtiVv^n1MqI|U>Wjvye#^1d4~-cJ|^@25iV$zwGY zU%j3hF^^+f@95Qy-jr8N8zbd#3>H=VH21R7ABY>ZI>9gNe?i3$VqnjLL00?)+iuYP zFM9xJv<`P#>F@_y5$I@L&GG2HG)ygUK2|sr;yPHIqi+0)(bqTy ztgyMk*NH)vTG7G-%u|vOevd#~@1pl*guaoi3oevAuink~zNoYTw7vzGmH1aYjUIAO zl>l}l5%rEW98I%-zr*Y5D`gQO@R@@lH+2os~t!#+IaYW{3r9YY#Wtzqk}beX5~}Xs;1R$n1fhnl7Yu& z^hf0*2fO()$fKB?+VRg_UG@!Isag1{nW1eYL$jLx#L;jA7Wbh0_T$G7caM;q#(-MQWE;W_4WCwD#$r$FwtxqPC$7AD|@}^9UFLtUVDwo{Hs1W6k&PO^!C~C z|5PY|B;l8)%jC?13kw6rgTl`j;N~H!Gbn4;q4q16b<9bOrBtLrl6AaG#Ew*@;_cGe zMSvSE_GaQo{XHJGcRrR%-$<_!@L_qW&Fd+u<}SS(d`LSm>5nis#~~pVR<$H4Dv)#+rVh zd6O55h%2i`>!-(4?*v6(Y5~9w{W`fAY$X7?urRBrL&qX_5HMM&s4Tq%WC!YBO*@=( z8w)P{-mIuam|;&FEgOvF+N}S`+oOYZfAbc8$OaR{=$z_RueL}vg`vQomYw^IRAkZHEb3U zyJT9=7+I_hSO?))b7kps%UR zUWlT33tkH{W7U@`k`7Ye=0q@-=p!)02SkhQ$NQdD8?c?A{k_dWS$=P4TGSQSEnPln z*S!H60U$j$ckQtI*7EEnMs8O5;t;G>>6qH>stgR3x3#r#EW0B}OM7B_7b$tBl$trJ zM0NHEwzIDJd(OKQQKp#p#XA0Un%3Y)(BnYa&deItsN?0Dt>i$?V5l zqp(_`|4;XXm9sAM=aG|jt=G|Nc$!0p&*ajO-=CcCB?eoKowu0t_N!Gn-;o$@Gc_iG z9=F9^B>-c@qv=p5wwH4W2Uc=LOElP7V^n;!Mb3aNYeNu3ibs}}o{_wUfnP|!)Q7AY z1`v^?w;o_PJ$Eg zDvH3NC!O1OXkW_s(NNjai@9jh`2jBg<-~hy-1#{Zg{66?*MiRflZ75zdPex)Q;&_r zAgI_B%O%$4U8MisT|Mw*#fjomj=VYTd)1#-@vqzPqjPKKx!-QkLalkjypHOs9WgOX z!LfvpD_)gz*%S0Ta5;Xc7dVixaxeqEk@*aGb;&1b#&R&sb3omF`v|#*Ns9Evi!)$^ z#Xdf~vYbVzq9&sw0C~B#^Jx`nsXwt==ECO`8hP*Luu%(T8rzqh)P3@uoi&3Z7OYOUQ{X8uHT!)%PJCM^-Wu67-&jf{!K{Ji<@je- z-`U&!{BLig))+Kj$!p~Q-3KeWs?!X_GL-K9-$Qh;w~>Zf034ppOMzMkwqqvbl#F$j zQZ@v-XM{C6%aS9`;3sYWg}D|!dr?p>s+IpI6La*)TsYoqnguiJit5t#;aka5R@QgO zZxyKFR8}oZYzP1epPOeX?06;S2B2hS3Cd6@vCwg7jA-rwMQB<))K*8a(Mp)4r}4QA z)34vRXWA8`P-zPd`sQGpPMh7Sc7S=6Lq=&{285yhQzZ(&VxyiZb!Gb2u^a5dc)6YW0D+NA75JHyZ~mH(%68PU3$d3qm6 zi)`}~FjTfD(x9lYBa}BThpdqo}EXD2;l7OL!5XFbc>n-dyTP>&|!;CFj!(sX0~0|0K=9fhFSLCV5>x0{Sj= z@t!UPzT$|tIh|Ok`RQ9gf=q?;d=L@`$l%K5|D3<`X`qz{u1b|EG6O+`n&mbMp&&lX zcfa=cK;S}L$p6*FBImD%^5mJ&kw3#xK+S-&)rljjU>D)G*W}+l{bC`y1hX#xY2QsAMb-ezWi@$UC}}7p z&)Q^uH(v^MgTfiXITt$FJqlXu`u!aUDP>^uK=wIkWQc@q07_6xlC1KC;~e%nz00#Z z_LLI^}Jq$a%?vj~fE97w_|< zR@x!-oGh-0I|(nKHHy*JIr}4`6HxdkP1XmG0nQ7(T6rPG{R3SF)um)eHO}DGoaQHi zG&qW#tv8)k8?Y222~b$WOeH;b1tmL%qJ4c8J5Wv^q1EeZI z+j)hn(k=m7^V3U);^r!+R&>u}>7Qk**Nox;rI@iDI5U73#jL^VVBoP(0nCvA`RTA# z|F=a))kR9RHQ2D)unjwSsQ{XzDyDi{RkCKoHia>w@u^V)p{b zYlmwfzM~XV(-}_HF*Pm7b)|-HU0sv|HuqjoU_lJTjW8eG@sOHK%JRJPsc>6mdZNcE z^7&g#JssKQY?akD%^kX+K164;RyolnAuts+4xN|G%D0&mpOrl$s^N8|g@l5wW|FF^ zuhnBtf4Jro`9l5!P&Pn7*a;YENaH`09@-d&J_U?M9hNz>Ef3=4&#VWeo(?Fm0AuaaLT}7n96y?sjaO@EpW>syE1pbv;`|a| zL?w5iv-jBCP>%i5RIN||8j$mFhew=w_9pH5`49H9r`UinHX%n@MpKwz7f{PeYBK0k z4V5Otrsm)y9(p#AAz1`D*+uu2j&BENe$lroc5xoKJyO;d3X6l_yuLv8d@6xiyMLho94ay~!kPw=@^Rcj=s&e!`q~WxS zIo`-FeQ-381-w1ebG-rK0zP(TdSp~6|! z`@fq6h%vrBH_p_{ls4-i-y5xaWrg#w9RQFtwOJYs5cqQ)$UVngOiqHGEeIF)xr zsC(jBDc756T+H+Z5Q~i3%pk$!f8NAeIGLdJkks}hF#0}g2sc_#?3yh64)O&*tgEP0 z`O$=V7o-=+B=|j#(}Yckz{Gnnicn{IfrdNG`~Xz|r~Qdu z`hx{NJtq;KpLi%q#uRqBWPM&l5igj4-rssf&^S(ob$J}YkT)$Ku=3I*obN#jP&%HS zuwGK5=PAl1>xZGO4~)ybM=_FWn%LFEg1ML(qs zGB|-h8Jv^rEWJEad!AOL479lv&eM_4oN?o%HcER7>oPyfAl9 zcijt~9Bq!g zf>-SzJNo{`;ugHM`=7hKnkMl`1JlPMPK7`_8Kd=f#7?uauh4Sqb+VNYbl6$s($?Dc zfRv%dU)%YKP%3l?k8%0;PF^0RxS!UqXEIt%4QR+n5zCiA&XFTTX4_TnS?=d~N*zmbhNu5h7XJ<2 zN0>Gr8iiZ=NMYbe`nLg&wtJVXETifKR3+q_?Y$peI?rm*F>w&UreI7z0^|3 zI`}=Y7S!YA{_XegpT8R$>M)L$=R_IB>6O!y zAv^y1>|@47f=c)P?IX2}{4a%OPieoa9gvbgS}-jeZ6g6;S!O@ht86d(q+TsIUiX#D zgdXpQ!IR2m>>6xN3doP9tJimai}YI`A%D8YS#WbDDs4GGC$NMoi4q%iCo$M&2^^kY za}>nSBG6k@HFr=0Zw~39_*~H${^G9nxgsa8-4P{z<3-HdEoBEQgA8iXH&-A-m8X;X@Q#&iF27v$s4lCy5oV1U84!V{YXP>agDXTHSz z^eY`!@PA0cUjfp0VuP=~T1$i)s{4E>+R#EINRFjAt&hQZ|eC#rfn0|_lUH=aZSqtS$U?4;J9 z8u(?C45=nr5I-Maqs&3*gRw44O91tFhnE0uG`zTLPvz+KWZ6o#{I*(0z}4E#@8iOk z6{yOp6NmS6l2r{_x7D6~TZX7tkDrLN{{8~d4=D-ziH9KNJ{G(`P2*425=KKd5(`zT z$tN?I1k1Vf1}fpcpN%|~)bX0$2?NY0v@1%}o++*-ePm_XD|%=PhxS7MiL^*iRKB4; zN-LhGz9oOUk;6iiDP=Z~Rrk+#4Z88j}{~?B`NI;d}xZ!%Z?XfQao(YxoOn~+Gkpe-JucAaRiX; z@Bn4Uzzkpoe9K_@J@OQ(C;?%#S9-0Fu1KTfmx`XDnU;+2l`Q#B5V!WNro;x5ImI{S z4Zz!AP3>tq%h9ixk6``4L@tBs7Ro@c^vL@CeYck_-oC|6yjcmNTp-wXXW-Yk5BwP> zWNcPQXV_yKIZYuHxSzryHpS50coS9<1HqwPKU%KvcoTO`7{Tw#QdhoG&v0mV)Jd5j zFqgrSBd;&V7k*u}Fj-76m-ELg;Y&CHx{hX9CiS9wFkz z?=mx=*KxV4UYqVLeY*#sw=67Xo7haGJZ}z_4CMp^Gth|=z$5wET?8O{Nta*{^LUS5 znlSxL`dXG=gL<^stRFYp@-polr&kiay6`!Jw(Xe0LjjjxI7mjV7Rw+~kSE4DWyOkq zOm*v!**WrVf+fD6uQ!RVa0m?lQES|ZgCM27>GoKCIC{E($fV7aT|{7gzBgq5*%Mm| zQBVB0CqI1iQWd;RTT0qB%d<~x*;66J!v6QT!Vgg6;R+(2-n(%8kmSUY*6YNJUJOD; zDhzKJYg|pkj~H~|+8DA}`L~}20nkXOS@GBB|A_v$(w7X)E}T7-rU1h<2i1x-iScmK ze&_T7Ack|q55gZx%ywHP>@^YPM0MFw{6e#sX-Ij_z2th~J+2?Nepi3i7B!=u8(%`N zHiXJ7QfKbCSnFaI7$*q!&O+7i`tKu5MlVJ{r{43qdD5<%m>))8gREWxxda2D5YMOx z023>d2|HLWCti-ARMwvKYAy#YId^L4Qv;4yidntgXCv~+*n&m0AtaI+o~8v?OuXjc zmRvs9&merKv+0QXDC?;XG5FY&9~-5UGdu&X3;N@k;hV3f{J)R+s;G?SW%UoDvn_LK z(pHsC3>M(Jv2A&SgQNXdcvj0%?^F&8c}b?Ajd#YxjrhxK2h7%EWk2S$K?g3Np z-wzKY{<$+F7}e>F;SGH-fm;I58vP|<<57c!1aq5lK+y^Qpw|zc%m32)86`oL2MT!7 zv_Ino)o=bSrGNSwya0p20zMX)Qwz9-IRB-+&wK#1_a2MA4mvO@jb#I=>A$h+4`GKz zeehg4Oy)Fb$@lKx>i$On|2|;>SEU&RG(N!f=jH!?@P0(SqCY@saQHe%A?n#%j@`S} z|9(}8W2xZYHw957CGYw*rih2m!_(ApMgICG--w3FQ~9Yf|Mcxi(6?_B!|D*4!G^h3 z?dNnnB}-k8wU+kvfkh$FhkozFQpsCs8olEcRlmo@{UCud>+-XK|0PJ`amiV;9JMNJ zKlZbt#KuM*(ve@t@3eMrllLB)cO||r3aphnqpm8es^W+-@d*e{mMErzCU^Cmr4z9~ z-)t|FfWAe*-E}h#-ODyd)rTLG({tPTJw0|@x|kV(4c1}}PJhS@j^@}#QIA-_pUPZk}Gm%n~|>tm=IN1!iwa{kM2pc`(gFryM@Ztkus7}&hYm%|nI zs}#zA`0#;mb52Y5!tYn526LlX4ce--iKc{aU10x@A85PzxQlZDtqTsBwSpNUe3EvP z7M}CKk1_{urJJLLMZFm3ksCuHi!A|ruk^E9gd<}@FFI%nb`jfn^1GCkmE+3a%bdF@ zwdJCd@!^1(I753`z5>H1I^Gpug7H)0SsB9I-pkh2A0gTr8;8Ji)I!zDGUsAL66(IfWVZu2nxz(I%+~{FKu}e6Dg%rQe9v#Jn zeuZaxcDNTJ>Rd~_?0RPr0iCOJ!%uoOewD?n!5!HBf{zlXJFEHoU<{FbV#3H>1XGO> zfOH02>s%sni{H8ryO81=hL?SRKA{|2?)AQRZ*s$mxE-(&fp)&Z5BuR}EguTHXGX1o zLJ@)zvT+N~?0nIw|G@kHp3{R__(ww$#0XOj-X~GK(xIwygE7oAJ5kbxbEh+PwZrSY zmLeYfmm!L{{`bi^`>%Juw@A~;AI4NxUR$}vb8i4QffBpG=2yB*N3!d^`)3!(%XnM@ zoI#tZhFaDI;J{LP9$h{c+C#-1atLU7$E!ht!UfH5_FkO`*ri@T=ip0B8(*=1t5>L# zQX?Yla~0_Q5V&oejU%F{aascRb`C_OLc+J33fu9?aLo>LM6IX7wJG@exL=NO;f>Ag z=gKlC0pGZUOj$$HcUbjjJf=nWj3M_`u&$$ku;B|G@;#>?&xUHnt`Qcl1=jKVt|+;r z52OReE{pZn-Q2^Onb>#=A?ANJJnT@>L(`ApsvkQh&>%G+R?>5v#L#MI}UA|iPU#CSA_^8(UI(7+oq*ukfAt8?Sj)kggR=H000;L%&5)R=T#llGB1R@uS zV8LYf7^x7G3?(F(se2Z+!k(mnEXYlGFvQZlor#fxh$Ju>;-VIV#@O+YU#dkPcOfHR zvKHD>mZ>`*iiprOb*7ZT>E1y?#zu{`nW{gaLu@e5Qy5quRXX~s%X<#Zquoulm)X{d zODX`phB3!|^9@?m{D2(XXFLJpJs#=5r#<+E39G`ZevujUbwx*t2aa83QNfK;?YZ;$ zM+xTc{&Y1Gm~1M&-ZMm6xOtxfo!Qk1p&YR97za-*&Sq8x8!0Kl-}=7vwpERbP|^B# zUdbxg8JT~<57>gIylWsR@}z?jqH}Ur4oCqrI6I2p#+|u9f~EF5-#emHPg1HS{7BlC zYf&b!*m6@nHAf!PB0WQ3PGNvJise0>W7IY|jcZIsjTAq~elp&sIXj`T@UBQpIn@xx zmfA7OO^D09@HmUrK-+EDZ7sJx2bipZOeKbrN`X)1{ma+J0Pz5mJE-;0O&|&iB;^6! z1+~OU!0a#UF~bj(a!8%8F0OmT@9}ZK9l+62>8P7Of|zp>Ol%PyYMerH~u|j-KteM*;F&Uc%mE^bEbqR6#u^Nd(F8_8s-R z^3gEWSdsnZx#KVx%M%R!FTlGcHgXNdDqAz7u+rEb@TNq|sOA?r0mun(xBeN(U^gCL z>BT+PwLYI4t6UlFUVww+sjt-fBs+h2;-u`hP~|4pmS*=_ibpKcDm7#Sb@Q1R9kwT2 zjHy3x9xgl*#HM34Vzb@*cv2!If}sXm==5BB__w`HKS7a#Ep@l87~sBuY6;&KIOA=< zt4N(#iW#uf&3kRE?nS=AwWz-h_4%_iXQ(`#g()F*l zHang-g%X>YUA9YEohlmC`bIrvnLd+y-{W01y+0NdPM2fldzg0n1@tCDh`gN3_}ZV; z4{Z9p--mj>mvXne&YE+2v^o3a%Aq5_Kn>Srl{ndu$7KZZz&+}Zav?)oK9SSzI>(SY` z6ScFDBh4xNHCzZ3(DlZ%+#A%naeBQ2NP^2z?IEu};n)Yh2Q1`}dj?LP8at8~MpR;v zL%}4PuLcuyQk<}vd3y=tSEo}B@ zSv0I=W=h>dp0YwvA1fEUOi_8<&pW{pIRsT>O^kElSLbsay6huXl=rv z(I&JVmAfFd(RWC3^1gA@XnhpMjVS4equVRs}F{)z)*MA%- z;DsEUwNtGqzZ6qM+}wND*!TiGxV0nK)eA&KHPk~#Wc;oIA>_T-0NQO4`U%HGznk=*$;7RgOi$N{Cji5J8}q zgc~)uXIUI=#d}Zc;tLjJyX$_6CrB4C!@$bQWO;v z3v|0##$X0c>;_#b@<_`iY(43*kV0TY4hSS@P|sBF!9tyivU0fCxh)18dZxW!b4Gy-tJ z_@5Q>Gt@J-HB=Ykf~yKi??Ju(aTIp&z9wuT)Y?2ycsPZdJ&dNEKuVyVi@Lb3hb|(k z<=#%DqaHz~qJ(vxhK4t2N_lWeQffesbyq#FU?H{mxBrb;A#pl<00x_b_E~<8?PQys zP0ud+Ud=C@$OY4Z;iiFXv_ZS^lM%cw3XC1=w6X#3VJk(>(TBFDt? z7*Cl$l9>y*MXc-9UvlIdK4~Eul8oNFYMXb!`u93`DnkI%C1qrfzC@h5MOfAGg|m55 zo{Q=MCQHsP+!Qe1nn>n+8Zfp}H7G0E(k>-7T6-mTt)^83sn9%9=85tF^?*UI;XBc@QwUlw7;ujyq zJTnc&7*f=1F+ZO%Fd@N5MUrMUs6l2d6XxF(xyB200q}XoNR6roXw2w#PbOw3&L$4NE z=ThfyA37C}hIl24+O9wY96oU-ueuG+AAF26Lz_v;nUMuOYITHRn;GEX~j<#&B%VK28PW12if zgr#<+-n-Cw^m{-J9h;wYtWWWo!px}Mdf1N@7sQra| zNs0DT_QRd&v;+ANb86GV;yQK3;1-p7O)4&;Y*VFlTQhz&IJC*WGux)z>&*ZA(oqim zIGQs3r9bp%^?uyQ$AY~@EtX?t&}g%a8J4+#QGgQ$;k;q$qp*UwIP?NdV*VQFnxuoJH&ElFA!}ePAhCW?YzwSuS^w{7vZ=&$EbjwQ3 zmac1-ZrWkj6&dY4@X)qkEqAZfMUms*o#a4gbGO?Yjhd~?{#ZDJk@)IsdOfuo)RRS= z$Af3vX;{6dPpYOY({@~AVwShwGkVX{*jN-N54{x7{EWPxOVEH42HXM> zsfmzD(A7AF-=i0GAw?mFZPaS@9q239EFW=vyoYvSU#`es@_)#LTAuDrXg zr|6WpRu?$LOWqb|>ZRf8-oKO!Qr_jY80OifsvK(0O-cm+SU$AUg&~FuMFMJ|goKP?{8dU{uel znmGjr+1(PVnji@SZnTr&XNEwWQ4^(|$%UDo#^FP;d5|2FVKvn6xYjY-Y3XVW1XT+~$vI&rd+)evu{b`> zGh{zd{lLo^%OJ@=iBudi17$o@Iggv~?Q2#u0lN8 zqTU!oJ-u99a&h=xGIe(*XnkpmzWT9JKs-G&T5Ksr#kv(mtsj9&^(4eW>iH05v0McL zDqPjqGP9hxu6&{KVGw5PdWkPXf#X`s#5InXF_l|dFXOU6`|KyR-%>?*E~_ZDpC1nN zu2q7@8+pem(lb2me@?cPc*iQv8+38cpMtf4^0P*d-oZ0}_b-{__6fm!dkAXnGzel) zVOPEVRjwjkIpIE>*87?n2x(0)LUH)c=UxY30Q$Gr#KB*GtL-`0dYh&Xk^)#xZi+0~yz@gF< z4$WCMC-1kOS5z$--8dv{yZMU}@@1R(#Uef_yCs$Ru>A)38j(ya)c$kUY?yN0$|kO=sdN?b#VqMNTGUSe1%R+(b=*C&OdkGhsu|g+C=U% zfOg*|RDIbcF)c^NyYiRGHg$-M#_7b6DK=6#=-(0Gk^L+8+-n>8o-*s1MA#=DM@$IT zsY27to@}ib*Gt5CI|S579t0ceM$v12d3}016(D!8SEcQCgj2C-?0n53sI@MWMhJW9k;EGTg3cus42<#!<@=D&{^mAj~xS%Fk6wiqnw!Eg) zcEhM1t9Cjhyy3lXk%{ddBVpwT>;Sb|?C@A!tWxC81vO^gpEN5q=vg^tiAB^Aj-~@X zYSO{Crd^q@2F=-PphhJ2zOG?lwFYCCBDUbX(h8?DUMD}lUMapi$nGOLL-EgL{*>_dR0J915- zTSl9vZD+hyEc^CgU_z^7xdYC$c!%Th} zDvp9ir)wmv%w7hz%m#1qRZO{Qvy+7XbCDmO7MOkkE`<1m7l%*a4S$G)zInmn2eGYT zY24`Jc*tvmjxyKS{oz}x1 z)`O?MIAhn@HA&c}_(`E|Rw5ZnYi$05e6;vx&F^IfFvU*0ehk{pm{3g3$yyFi9wW*gw!Ws<}Wxv9;HiXF3m*o=?xXYg;U^9_1 z5h*{1|GdFl{UR<#54#`Hi(i(zByA)o-oWH0Zp5$aq$qSo;2nHw$u;KBxya3Doq41m z(dFMP)IKJb@{-b*(sRxlv)@v3TsKddvuGFuX9aivVC=5FWyf2CHPgFkY*nL%9NceU zK|D>b>TWa@gI~U%^pj`mc*uSl+L2rx(L2>64JlZtuJ-VyxAV(~hM7?hdQQ>8+Ar^> z_cKMLWIbzu^LK%ud^w7yJhRFyl9Rf{8I*DPS+N?4y;_x*lAzBd!f*>#WcZG|wxm*t zscKbdg-AlV%!l*mp!Z4I9(-{-IQs85s4DDSePbg{<}%owMW|xtWX^0K`E42HpMtgb za*rIjZfm)sX(BtOpL0GK6~k~2j-GV{m#35xJ~@xp20iU{Wj)0UwCo|4;4ifVF!^(GXQyk~Sml_uiHZ9~#a)pBmUBGkvsC_R~Z~j%qN`G;UqjA0O?3P@L%0Mr-(y z*2#PFv*1p%R+G+qy!VTlcy62j>7exgs=@{$9u6q^)o|`mZ9ruXm_FbMpTNEN32&k$q9t=j8$80x5@&Ou0P3u4qn{?B zVHc|7s@IsXG)e)v%kzgdB?Q&AD*qqW-ZHAncU|KZLAtwBx};mWL%K^q8flQ0k_H6? zq`PC%B^?3^(y1UJ(%pHUss7hmd!4<<`Eouw2FRT6`@|i;>$(X@7oJiQbF5Daa7Rv- zjd@{GFNW7iCwkr%?lv6}=79FmgP6HaZ*A>&Z_{I)L-jq$Es~Nt-j3Hm1I+@)Zwk?A zW+>T<@Y=yF|GukK;PJBy#2^U;%pJ1nV1Jom785$A3lM~@D$p=2=PBRe<4sVY);~r%C5+xN2adJxS|LkEWjj7z3NQ`1 zLd;LuLuCO~+6Ps2X!fR?zI&a#vE7{yxhqO^I-Y~#a4-8Q4@ByAXSV(mA~I^rkJ&Sr zG1joybbjBHM)fNEb=(#T!5l2xhZ!FGcS~3>BABdeT7h_MDkf7al*e;qY5r$ScFAU@`)h zEj6P+XulCCs=iCw&8EpUT=v1xmDQe`YvyL5;PSU^lkv9wRv+Y)YVR7=()R!kjtYe7e1))hi0`F^Hyu4<8Lc)WDKhzhTX3*zF(-k7^M84Eu=UQ=mPKb5h%X!?xTr?M{J+^nqMLC6kxHz&UA- zw*aLz#JE{~CM~5vS`mdP=dLBN30Z!^>S1q2;3HLYYtJ zjV02_eLQ}HzUBv1Pp^2<0~hVkKQ*&|KKA`o6O0Zrg>PSxBel1ymRpN0r z^BZo&^93~A1V6*zn^rD}>MX2U*d}pks+3=@b~WGRlgMYRoR&A5c2RKZN+7p$@`Dy} z6^mv82Vb1UKlo8B#ZIb1VZU8IoXxg9iV6d)bomWh@Ayeul^041DqVC(!K#WNE$709 zLxsLxu@}4D$8YO(R)wW+N40S;!2q$1x~AxClL!?%A0lWLLR=g8;;hK6mpn-i?>&3K zo%{aM{ox^CR|=G&ZEH>xPt4WA*>4Q7qK4+8msTb_G&J&LOfN5!I*$A=JtP90?A};5 zjcOF?zj~@&uJZ8UF&Qq{eT1oLupcOHkw7aHPv*z8)gFkFID+Cs?4P9wPuPT(udEaS z_BSye@p*YcB@qE=Cg;|bqXv@_Q^|D`z5;db1+B;%@^_Y0&*=%3h{a)kc*-;8mY%hJ z{3j_vdjK9!#oOI;Wtl_bL<{K>G!`)&!AWKWm|^3<3{#!ioLGCbRFE7+XjsZ~$ZzOy z{bK1SdM;IgV*9|L;Bh`!o4eq>s=)f!D7s0RG)?G*glF?L=YLLKdigq*e(`O0b@XT_ zxGwa?+j7nZdf$bRjeO_;Jwo*Slu9&~zpchi++*gBrM`*45%xrt!#$?wMnN%GuUBvj zb(|R+8{m^9z#{hD_Q=H&A}j_Uu$I!f7aMn86cQu!c8cJVB1Xvx+_Bbx^mPEskjT`mM^OquoQ~Iq6BoNibeOLf+HYc>T?6r<&J|OChX0 zx4*@2j3NLyuL}ww3d#y&x)Zj7X6C#3Ph&8C4~S|Ts_<+NopIVxhCUnee*X%%5kIPy)Bsz_CD>-hnf|d^EKU3e~A?61p+|q2A%3<|L<0AgD3gv#FHBmhW0< z%DnQ$s3{#gR~3xl`|e4p|J}FAdK4GCUW!LuYs1iCqvdgZlM3IflMDGGz_p@wmsr3( zdUJ<2jvqeR*;%ae^wJfxMGHN(@NCtz&IyUph%%2f17 z-`u=n2?oQs_H=uXodZu1r`i1~{V=~PTcv~m-q@qW0BMR&>ICU18SkG%$n5d-Jd z1GB5$Iw;!1#RZ`}gM^S572Y4LvP11p(%p8}=D;Gg`h_RAEIu|7Uvrw))4p^OjJqcx z{tcjchmn%mv9#JLk&mc*VFI(|1$`{8Rj=98+ZB z@jaq4Rx#C^P#!t!uxOi4tZZlwR@dO=$|J#Iy(ImOEdIt~41Zs;im)i&>6;M1O^WMAl6A8jVqMH;+WBrW^%gTav>GwJm-{qf2@k(~dx zAAVcMhyS?>O57}F<8B)ZAj#)vG~xV(Cjb2jAb~Hm%v^>#L@$N+#)5_0na^bUM?az7io7=qh+hcZb)r~8s?;cli@w7g91grH@X=TII2awHqM@(zZe5q83g`7Z%Oz>t)7G3X zXKyeY?w6lfr$%a^9=RCgT6j|@TMDSDw%elb(q9#%zWicmVmEAmy0<`72OJQH8x(hm zs0Qmv8lBvRfO1<0zEOW>Cw z4fdTdtE>o~bw(B%e~x?H#Rum}A+rpv*onn7~W$CWE9~{kCVtDsM3Z*Z5vo{G`+$tBnW3PfCle=ttoXsOW|ke;&81KMh5W z%A!UGC&ruIn^UEozJr0{Wpg?zdN5mXc<9}y%G}oimyZCr_i5x8i*9Us3dzRCAlEv4 zOM)9kYbc${hws&PRo3=rw@A-%`o!OiXb$+jKi(&{`>I$T92= zg*tuy?@b_2sN1+_mDmBvN;kt_p)8c6b(kU$pahtpKcC%l3)+Hx(Pg?wKtwv$pctdK zc8$Fj120vO04Y<|t7?ziX>G@_o11N8o2;)UntMX82od_0iTgX%llN4{Z$axBu#xh> z-E;r|lotz2OBiv{@uV$aW2>ZdUVk$30du%d51doICMtyFXBT!ZKdTB92STCIHXVA! zlFbh$7(|jdO<$HVUrgX@^|j9~cuFgq!yOLxlQM0rB9O1fa!>PnHoTN5e^ z9#KE_`*Q^O|N8;Oak>>H{eCp#;L+GgHjbn>PTH1;VUQPjTz;&Y5~RYz6(QsD2M!!K z`FuwMFxC2^kHN-m)0}+(pOounQRpjTfjayl9!hHi!kD3b&7lG;R)DUaZScq`>2adG za3mS`SKdeh+th(%d2)_ls>yfvjR2;5jm-kO0pDAxb##xH==l$0uPnDFiBRlG!l~_N zu`L}C>0wducx>hk4Wg7yY-f;SP60(LvmDCA*7X{LT*T*&bAjmDV;6bwu3ebOPQc=HATze2`QGlc4+!|VOT`cYr%*>CMn+Wz z9-8grOjyk2qO5@0(|zc8w+#_~`(IV-VnbVn4np<`V&F{bS58O&5W}SKg0%@#->EBp z3IOeiq%t7PMvi=*zbNn37xmtbZ@et1p6dOQ<4spX5!5!w9~|({p`OTZY{sEY{g3cT zT5GSP$wliSvzE>;kIb|yzi+ISih*4MMlu`Vv`B}{jy$Q^YHULw`TfBkR?CY_g-16q za;=Lp-}XcsEE^arc=M@-$1^C=Mndehikr22Jnl;6BqU>OfeAs06L=$+;NbH@EI4)4aA>gdjMw=OEW!7$8D^ZV1T=paJb>^IL- z=+L0lrzR>3K|DC&T*SVdCFuQHVY}b_8X)2&sEy3Gt!HzYNOU~Ri+MI(cK@W~v;D%A zY9a-rYCM34ZR%|%3tD~He}cm<|AVSFRkOtjzn-YX79!BB+m&DFZH5firbqMUMCq(7 z*?u1}bYl9kcW_JH%hY@S3xTY{bu^t*Z+ZWP4B2LrN(aT$z-VxI$g}4{acRwPJ;7G9 z>eQrHSf0N>D`BDhAMo!5o&cpvR+4M#M;aR-ISrPL{>skMzpw4tFW>MK_opm!q6P5h z(XTCK%h>fVmpEd}I_F@Yjy+OI5iYyXD?xl0f*45*(SBDbE7>RDww90U!nRj~SUpsd z!k?b-IqBVdE{nC02C7}p-B^f`{^u$;g^-nJY0XYwE^HP&Z{{~^jnDTM;=X_pOFW{| z#$OZu&!tT2A3DlZ|GbXQ?Q_=MjSksw@#91_iG2*7yT4q+AMK-nY8zMu=n*$%w7WzF z8bWSch}y8s0zcKlMoi=o+~eosT#bw{IX8j!F|_X)AV!b1w>|d#XT28UL=8F!i<1hs z-RL);9>wMHSDa%&UvJWt<1KVVtPTBMh`}3Y4U69k^EsgobY&`=W1U|+nqqmpIS!*>?FqPh1@vrLZ_Pz z_Fphd?iUGbQcOy7NMj_2)b+?H19-Nfre-``|8o=pJK#$(okwq@DG>n7B2EVQ!E;b- zr`ZU&_xa25exlAv_MfwQa;B%Q4#vBDZd*$X@VhBV9MT4L6+#;p-Rs4Ju_bcQ_cf5# z6xedjiVXgeSIHnHnkA9tcF76AFNM9-=r84Z=`ghua1!Fwxcx=_?h5Oroh|iNtXYgl|1i39GFp z=zo?fUPKr<`fD4jDVkY@V}{=-Xd}DhuHkD*WV(v2{HX(H$Hup~$EuFSO0JdZC%cn# zTMGChL;FUvo7iwUdRD_m@oxL=SX1Z(eQ=dR6?V{5p6nI!y!4I6 z9mQm6X6lOKju3IyW<^A(th})5cmk~qqf9Z`yKB33baT_Vq4P#jb z0kh&lGX&)4eXbwt_zZA~dQymJysE8g4@d(pHslx7w!sopw*Unuc5hHs3O7ogsWPDu z^o{QK*N!3Pqot>x2`3gNZchn(o0crpOk*=jU)dA2CUHEvMu1i9b7xr(4tD=9bU%>2gSZL_ZmagUz^p7t$Wc<27#> z8mI-}bCCD`uK9UgKI(@Tx-kw?<=U2L)NS+WmgWfD28z1>O-Wbq^Q+Z}!Ir0pOSpD; zGP?5RoX?N90;iZD&gRP2~n$B~vJJb4(lX_*=+4bbiUIvS{X};sdi|306Sc zwFIG6qE7%&^TiQmo7~03*N(Zp58xo;N-7M)lR8KK9fI(h119;v&Qz-)eePEj5s^C` zReg51l};PW=OzNr$=R=CA!a5@j!)uhCf5_Y={adcuG>pXyJyK)(Q2REKE=jtv)TkdJrYr+=2uR;isg2a0WxG(6Xo;o)z$q zjK?x@(4Ffm<@P4rPi^a4();AJgqs^XIBGEFlAfMk2W};#M&)Nu1b%}#pO$GO`xT8M z110t9FOYgu+!m2^tGQdd(F9^hIo0^UX2i``v-!m2Nbuj4y!!E36AUo|I`i*zyOTw+`7?uPL9z2#d2 z`pBH-iQIdJs|b`0Y>NtNLs}=Qg5Y`ZEB4Q9<%=mgxJI@@M{Wm(J}0veH@7$+^V-hN z%Y<7#hU7ttivdUFl1ym7o1N#jj8mxiF5t<3Z<5d_l&fzk5Fp=2Nx)WcbMwkTSj$Knj*B-mW$j{nVuoWBsrwVd%FyCYbNr;Hk<)NP!X5anh zucgI%PlAOxC!nE8ZKSUH#W>y5U1-`S!0`K)wy#7yXQIBk;8=3JLoJU+X}7*M!_Lyr ztTnOhm7cOk6@6Fi4MBS#%mH;2{8|G_?p>}{Gvv3NwKXvg`02jXNEucp!hKg{yf}hB zwZnv&@nJEk;ZC?))4NhMbxEK^2qjpwQ3rvJg;T;V=ebsgcpd}?G`vx}zkV{3V3L}J zc(tBT#^x}_Jb=>G4a?znGdQY)vrLy{fd?{?o2h?WKUsg7XB#jl4Vcyq^2VbR%W+I) zpqZ}%keRB&YmuU}=_RN-hM1S_S|DJ-95N!v!oZUI?aFVs!g!Q+pd_-U)^%{F zfj9Dw>~RxZL0GHZx3qSfIBT*N?-0hNmxbipnxaj0d*APc8s?3kh*QERMg2XGN(gn? z9`AyT1|dJc-1lln+Pwc+*$nYwiAh5jF!Q#DCo&*_g{za5e)d%iJSKLZ3`xDx);y^OUL6e3{0 z@f0?$mxv?CokjJ0u0iVb8WiPGTim7p99vK?cOpNYTBh@wuf9j-rUm_%@lu}_o(+~L z2&@|5ZC^Nu=IJD_t*x!7gkVk9ZzFL(jSvYKoV65pW%(|LTE0O;j~R||0%99tardqV z*ugNpA8JjTxdqkvg&y=63E$ELo!-`f?k&|vyEuQFP2T+ss^#A(_mRTGlLjs)~rC# zDOMNmE>AOK{CX+G!c9LaVgikxY-@MpP(w!5=;e|;>ScBU7^OyBANYvPxcyDJe$>Q6 zv~r`4kk!%8I-&g+#_;M(Qj_rbm`3vrEI@b$|F<#2o4-Yy{~jbk9q5R>x5vS;k#W7^ zHXr6J*$YAarn|rnV(|Q#oJ2_db|Xl&F-DZObD)JY-uzo2{#ECfLb^sJwE1%1dc`;S`t{nFHdJo}&XTYU%z%t2N6~ z6gH_Bh7b#Puh8LZh_xa2AyZRVe7X>8D363)N6ge>1g&yaoWo`8Ovgg^GTx#iHSQ6L#OBu5fy6O)- z4f>H0NIOKWye#gX6Zsb32Yj#~jR*7(vEhH(id}%tXP(@>-q>cN@c}?yYLohN?&_vI>hr#qbe$IJDS0g}x|P|PTERZ~52TTP+>Z;o+zXmDWY(t98U ztZk#_Ov+0vPz=y6FYy9vs;h^et0Js$P;a*A($z;5NU29msNv%X1D;%^@BqcFWNq|_ zhK~$7Y<%jEUF3j5NLMLiL`LIRxw!xkVJnB5!d+&2N>@L#7}v)q>j-|D`D12iQh1Y^ z8iP9Z#5?|LjdAmr8T`}N|!3- zbH8P%yx)u5Y?)|z132aXKc&xzu0DcdKv;D8TTsfhC>JAOGm))?9D^eC zvQyDWzr*~M2DpX?r=T@)BQQQ)`lll4LutwWw<3&Xh@bZ3g;w7MKKkBz4*>=0;yM_~ z{+Dy@D33&4ZYFEAa)8dg)OilSD*ow1!tg+?lX45ttz!5A^hkJhzD7UCB0Nt-s z>T_9~73=3Lu1&j@U$DT;igu?}PXW3JL8fh63tdPrtd5ZZDpDAdVoo|v#_ zf>t*&M5THlt*9dz8Cdt!u{325^J(G|5h*_@dJDk8uDCkQw%mA&N{h>l>OR}sYU=1r z%x^KoUW&*Dj;NZrLacTdwBKgEx8uEtf&Zhlg&pyJt`1#0u2{W`W>G2ydWw%(#y~T= zbQ|H36!$j$;x{ioK?hm-N4aEzzTXg!mgiAM<*m~=6vCZ~*z&;j`nNO5w>4wVE*HQirZ^FIE{dX-a1&sw1961{yk6DWt zcv@9u!y_(W+I0$6U%w?6kvD1fFbDmvWw)St&m9iX>ENm+pmqJkVlU`%v;)#k{WhcH zz8Fu@9pRTNCkaL7j1dXd5&PaSY=!*GHr2ANqbT64d zXIkbkAuov4PuqSESHr*-cU)GIStT?r*JMX{X zT#a%*iY@wTrPr1I&iC%4+4!VD(}5r>M>O1c< zqM(a~ZjU(?+KEGVih)RBXL*Y1!Jc9VA!Niy?R_j^%eB7R7~Wjto)LC-FLDu*V}5|VBS15 zUsW4{E^|9N%={>$rnG-R>Z*`<2aCCWEWGghY4cJ#&X+x1hTksKAYRs26wv zIHg9{ZuLtu|0D_T=@#D(2>%USd7FyS%E5yHp2Hy2N~~17@_hT_NCwzFyX%%W?Q8mW zz)y!N>TG_-Yp^@34eTTQPYpi!_AjCe1GQ@Xr=Mmi;$cBkm&~<|5u08jj3-M=|D_ml?<7uO{K<)R7O|<2u3a5AI zEBu#aVB9olN=t_Twnbn!B)g{UnIKd4iW9QiNN?dw)6JQ<4J37kSKvvAD865xM>$A) zE6ByB>`cH$B3}Q||JEDOP-?zw2wS4oCxOL1w!u7N8>yxh)N7By0IkU;#@Wd7J957- zv#L=l9j8IrCkI!&Y?r0LBjR?W`Vfw`B_@Gh5zBrX0qqJ1eywdfu*~V^?vneAIE*~? zXZ}d~{?qip-s=O_uP9qZi!a};j8iDg#Ho)XXUxR$ZHVk8tc2m+GW|}&DC+pgK5)tC zoes=(IXyH-lG6QXAG0fa2;AqddeEa=F~dTZ=#?^w0#+@Z=y^WQnN276+nC}Jh-L^o zu&Fb)$1uE!0uH}R0Z)iKQVI zR^D%Es%Iiz5HekhI(8PaFDoj`)X_%v9ouRfh*E~xghz0zQ4Jy4c0u|eJC$K2Lb4s( zY4l$b0_51{vWkO6)CSe~Cj&M2jbarctP-rDj*5=;t6{W_nlg z6v!N+zf2{pI;D#*!PivF(YuNn+OcdvE|w@F zQ#HTK#_yne=zaapoFi33+@#&t>vHSV8K+2tz56S`wqhK*URNSbGkI%iy?5Jx8ms8F zSmO}pr6u&b=6bhLRnM#W9i<$|+%-sSjFI|WbjItfIgI8#0wuO|rZZ8U_E4B7HfgZ` z9SQzVs}R}**9fK3+ahcSW88A@Btl8o+T2R`sc!5tVgnt&{$sXGZwH8LCZXOuKi zsC|K&b^P;7!P{w+pz)sVsiqSol(LBsV#&7W2`9tIL09i{{lTcE4YWhx)u5ly`hP7s zsUf{A(RxwdJ{x|+_b&a7y*_KrvNCc{FoV;U4_}gMu#k&p`2Q-rmkKpfDy{Tz_K-Gg?JY1%@st7S=n3Fv5OP-d1!=c<^oXA zr^&C!1U4bAxR_&@bBHe4FNk$xE}27A?iHPOAE`~d5gu^Ofrmc?G3dJrboOTt)aXZ%EHkjuVk4C z#k+(`wiRJXbZKb|BxR>BJdx){BJ#+~Dk%=Jsr9=MOGD9E`hg_?)PbkosX9^KqloZp> zPjh%F)79lwBW|?w&>aErmqVn)pSzpOYH1B&UC)Qp{bCy9etN#T<{9qf=c@WEA4lV> zy$Kzsxr1|t#O4B@IME_AV6P*X7lG_xYH30W1`DlC)BCGR2mF_fx{M3rot&Oe(UcTW zjdCcBXhQ;o`d>C8>WuUIcv zk#}%b2p@Nt)1HtoKO@an=+QRBiKZ0Vh{Tc#3-Tzg%!Q`jv6mAc#EO=@#ld@?486i2 zjyWP0r<01S*UpXwS_H4Y{1R78SGU9x)nzJ{W-?GxMfYM_E#~5lM@b`F$r55t&#`r1Xhid2C&b^M9u_e)EzN9j z+gzBzKO7eAemQ0VYMa1D>YOZG=GIj1&0zx;u`Wk2&-Bz%-26V~dbSD$1mw@4&x?Rc z6qTa#i*8_KWOvLCGuAHCyF`P*@49e|ShqVJc%5t`kU9QV11JZ>gEqhzcwoRTULVdm zsZy6-pcd3u8CF57hu`o#6Bc-7MUU!lq&fQIe(T)~H|G_D?FB8A1sidQ%GMS1 z!M$qJJT!sh5Ymd26wy`_-9Qz+Ck_m0m}rIOQBXz^YWf3InVj`^niu=dCE9$OFZyYh za4QbNR~v)Zs1R`!ZnHd63trs5x&;0o7GghObZU@{wX}9YAD`aRdMVJ_201tc?6Ug6 zP%37>_R*88>^*7yfFvvKOEEU1@smUHm1?6QoTA;&I1RIpDWs2t#Rw<;V8)%eYN{x4bQmtkI+C`K~@Ee zjESw#z(*l3EZgohz@T9H3dQC;mC^E9Tc5~g83)q{rg%YC#A$gW6L5R;kR%ss&9}rn z8iWf=u2FbL27sgnq z7;)i|&AviBGX(5>JeOA=iV^1_qI4x+!pWYTgwK^K4}c~B$fr+;3CN!pz>xGWf+pD* zKjvx}DDwaONq~!sZ`AY(ng=2F7B-_KU;FVX1Y9i7cRmDsGGG??cym4iIZJmF$|q&z z&xlJt*&r)W<9~BI{mHYwHtz|gs*?q5S~hSy5pbu&KMfA1rU!lVz-o$asH)ce=S=b& zc1y}^iGe=J?YK04G7*H^u$IwDqT>=f(BK{u4F2l=_bR+N6-xgiJ}EH&5CJ<^4;!>q zzKo3Ugc%fdQnC&Qga8s+)XYRv+XLN9LCfuC%?8?)JTNF;2cwR+5wOrHL?W)lKlSK6 zF+Zd3m2GnP1e*&#N~(FU!ob6}_~C4k+(U`;zES^DnNTzmOQy8LTh89-oV0PCs~c&R zA|1l6tX>a^cj7G(wNo`I4qNSJAd`!4HUbSBZb#{~+&2|5c6-8d((H!J>zde;!}*_^ zHmawun%_Aox?O<6*8F0*5iU;CUR~vX3Yv9}c_5Li7zuN0aemcFrw+6obTvI?QreKo43jqQ_@l+BRf!GJ~iF@6G2gN7Nl-Yk&AdKY5Vv*p6yK=*c5 zexU|a3manyz5vh|?V4sPF!ePezbM(?+HX2qy^5>bu$NI~-4JbRV7~ea68LcQUUYaj zB=usj5RKYAdi13yhtw?$phZDo_*Wcu{l3}gaqGS$Shf0EkgqcaZ;la<+vd+NXJ zp)LJH7KPIO(@SCTmBFcfYB~_?tq^&B3)#1~S_0z{%yfWuA(~$mT%A>D-_w&aOD?mt zc5rA8fLeKHX1GfYat}(ugaHfUdhSfPG8F`D#vi!d(Uo6!2j9J>GUrgy_`)Pni8)-d zlU=&SGc1Mj{UUgZTb%aWGp}$CF>qFIylayzVz(SN3L4XQ3Jb7=QYNq4j9N2a3yKd@ zHco~nRiG*>sHjm4NOM%n*VdMdEn!?OgBz7YB}%{@1Sn7+Dxl=q`&Pjx<0qrK8^0(B zb<3L&mW_sza2ul5+?=md1`e{HuR^RAn8q0sRh$tsYI!ihE#aiHTtmaE=g{vM0UE79 zSeR=^u!W%f#B=KHF*0*-D*@zi1)bv?2HK7fF5h{DuVXUx%>or+0ojNyLj zR*D!V({K63*kU1cG+@*KI4{fH%F;Jh<|w{xmU>J|Oh!28w6zA_EK?aIt4H=3u}u)n zcd^@{Z@0Z2FgII(dU@7<|5{y5Xv@%{m??ikW6XTh(v9yhbH#EuH>LA$dG}vOsQx6e z?jHs}n&3ZenEqeRme9}$>S*y_R+#?;On{+e0- zHQWMysz0CPulwb{#O8l~_#eB>e_f=1e)u1MO{jphEcAbV>~xuzrXm4{|0-gSGKKuY zOV-vLD)}AgjsKTP=l_?&5?Dw7{+s`})lRp460pou$Voe&P|T_ggMMBXzHYx>sO9m0 zfV}aj8iL zcmCRXQmy|r`V5&rJo@=LR8c$4lkEgll>VXF>e;|~c?V)Ob!>yseG$`q4(DGlp~ep& z_iamiW8F zNq^W1%H=o13o+U7Ve?qcA}%cbh%W2EXfoVpk7V-sWLsa!Ai&b8T_4Retp%$!BsM)tukTaAD=$fmP5e~hrBA`5jSoO<3@8oHz3DWw6@r^hH$7%XRx%Dt?A#pdVlSG>hfHY7 zzFSJ=hn{btsp(H!;St7ky#ZLQ9pF|PX^^?XMpt6&X+dV(;qM3ZiXh_f+&Fne_Rzi6 z{>8>^V%QdngkKaRTW#bu)|4b>)owG;oZi<<_tU-|L|=oJ9B0Anhsh-7K`S4eSZB&y zFDo@R&zI%!0ZDB+sR0v{vC@a9&vxdRP}QbGUzU`YgDPgOK)Hm=!gIXL@7487*=oE2EMBTcX5$Zqj#D|<>dO>;wSD6Yg$8|Uf68>Tl0Kvr@xDpK zn*3q9!D-dyVxhJC5K)!1m%EkZ-8BZ)TB{z4$;VgXRNCpOJ6%1WDDE4DcuPXDh?yee zRpGa2(}{DxZl@cn(B?XI0Qjq16TD@Ke^5g*RBkjDO?!Z&$`DiJMng$0_;DF)qvEM8 z_lH{=Rf?GPbQWhBw8ckLw-Y?Teh|PjvR+R-x#&S!0mcrD0ryCTh{xQrz3mK>ud#$6 zikOH83Q^;%M%5z?G*nJ=L#lROQIU~8=M*Z=+7;g~u1+ala7dzg9-PzkFLhD=?8*av z6B9YKZRcvg!09~SBH_PpCed|EA^Fny4zMiwl8B6Kh-{HI?Oy~1-fLo5Pj4UcF+T2O zW`zRiUrs;Ku8ag6RP&v%T@XksH}Ea82QEHgBV`m&^2rzPdG^h%dB0M z+)dS6bQlcz0y;#1}wzxe?Y6kHBWwqEK78cwKxvKROJIO|3)AchUj%_q~1N z*)@mB6WC@rtjel7;0&f_6CSNi2;BKUxH>nnq>Ej(4DYEWMi+CIjxNE7 z1BGQ}qi2dkbjoS1K=Sjf1DyBDicQYoykC!Ws-n(~qd2}Tus*0$I&r(p@-h_1es_*yP#&ct8`yh-P!!;;0k_u0C=rYWY|}2&1+1#wThfW@&|_@IjAc}x zpq5{qsWV?yluUT2(2g^futt&thSTrq9`*-fl{adtqdRq){Q)2Ek(i)HIv z2eRdklq(VHJBlO<1pB%G_qKnsToUNM)62Ny3leRbPb&TFAciC+*^yKHx&xXXxgZoD zhVtTd`03sTjr+aYxD;N%!pg}nZgi(-BMCH3sVu?MZW3%OEp`Xzml>Y?Woj~Oe3_1%4JK{c?*=GybPm@~k;=w8^b=TY$@imxX%wF{u znZTefzQy6jPyK>evwC?PDX;M>dmNqYsU_TIJs1bn&`1Bo0^k>(Qcj%FK|z*91)QKZ zX8|Pe2T>LETP0vNn<6HjEig3#9ln_94swDFKbJM=Wm`hYq=Nx%o9i{ z_Opw4{%eiCnOr}PSUNb@-Be;j43#fU5cpo2oxzmaS1?v zR1K8JbhH!q;}!QOg;dm>ug9u(pA=G!m8&l(OxOtVLhPg1G53c{iVom@KR{~YTQi}G zK_S?(_GC&X+?q(#RRV*hPeQO!`Z07L!z0Z7(`L`!+rqd+t$6N^v2!smAlCGpiUg%j zIXb9vThOq6A5+7lOP;&Jf}aKiDFSMVm*R*=JH}5@hRk{K3w`8P{6o&M27c$YF0aHQtvCep&7qY{%|CD? z*PT<<-76f`p3b3`wJ2YV%>YezC_$<=4{p%uK(+u&IHjI zsWw*XwdTYVP~0+*;(XZa77Yj&?)$h~<##EGq(|cP9d?$#*4C(dCMBaO+ZtSLIe8(7 z9Lcg)WPYC39{Nl)xj)y}p@uwKwi(lF8G%|$if<3ZHyjKXLVuMU8P%nl4AkXH?`=#% z{N!V@HOfKZ9H6$KhI_LY2Hnq_J-K}P$xWOzEO^Hsxt^OYM;Csbof|pFLbJLdd!T8) zQQV+th*UhWl3o3aok;wt6eEzoVYhh$_ln4S16_8+KwOP<2+(?SGtRcOKPAys#sKe7 zOYQOqh#>*E)OMY-Pm|#oc0$H)3sjwtqR7h2zVXLw3}l{`Iou3g5l9rE@QRW zuG~izm|aXE=FHLt)t0OIHm+Goi4h_3)+LN~q^{jZkp#}km9bgEwGMJVI~1ayR4(>_ zGBzI29N5Zg4%x54wvr~20V;80x8xlp zeaVj>CoT(pDv|$+Q3kxg`63*_9wu=dP6)IHO&Gf(wvHw3;qfxgI2behaF8U+|516{ zBlD5N_I>@-juNYd62Oq4u`H~lAr0wOiMifu%1GgmmrcFKTwNAZ5i{8G0Y^32&8^&v z7e9e8|De^~VlN|5x(W?wFk$?LTtN(O?rKzQ{oMzBVBia9(2m&qTr-0YPg`xGwihLK z%PP^H*IeB0k#oMbUPo$hqZ=n;rTd^SqB`c(zXU^>F76(q*0++a4$A`xr1fR!aAhrd zDUAahD~^#A*`MfF81q6>$(8#$fdyac1q1V;T0?CO=BIQiFgj+4+1MU!;S}UkfDr;H z`}V&kgxHofN|sL)Dhv%Z+E+zy}{|2=@g48&F-Q$#*{ zlW_x>*U#FaE1uZheaY7k`5@$f28#eSS7xizBhFwJD)U#my^JyH7C+ZMXk2Om5(y{+ z-{JdYKg<*+Ykk?ndvmGP@f-wk#eq-)Epj7|9yE@5oQLey*cgQPOm>j#1DT|afD{)= zE3yI*lbSmGy4aPP+&>%7^F#V58U)^6!K)@ zlbl|und3^BNI){2;EK)Mnb49Iw!>Ix4VP#bNVev)YmvroyalHv)bs`Oq=WTMcDeZs zU#nhUwY@>iQz)&2=Y?#18*5f?^S^BYDv73Q;Iir49qG?pQS}vGdm`^2#dC3DgMKJ~ zIHS6}!RhJsG7ePY3J_A^DxcBv^p8;8@LRCU>}DJtNXE(E6$~n$Q#{?{GF_XI?6+>B^#y@ho zl22A)F3PtoRok&oBB{%#kqfJU8*?0JlHbJLB|#6-ze9|8*^QI%lJ(MY&|sN)M$T83 z$KZZ-$v6wM2H}y@1Yj_TK~K@i8RBedz5`RHJ1!;sH!EsW`!wu+T;y1>6~7n%rr<{sez%E6_3MJGBm1p(7^uINaVT{>BxFP*(>wNK9-_*g$-^|Oq~^rU zzjPCH_%&%^Z;CZt%f9jZT$OfBonCtv_;Ur@;!ON4(Lcv2aVgw!tH0Y2zq@6s^13IF zm@;@nZdZ^y7OE@6yvr%`+Q3lJjP>gj5;igJqJ{`Ym+_Ex@OFw5qNvObu*9Kk`9IHih^Inf#hMbhgz-1lP zhn)LckjDA|4YrJWIpu4*ORUCw3#Crv`&(P5B`P-&ehv*2yVvC9LVnZNW9E7E;q*R5 z?q0ZYA888;fQknrPv|iPhh@B3y}pE%F71IG!p10Q$P~+`Mu@Elr^ZWV zJ8*5*{f>nQMl;p$2G1!#6IiBpLS03w4m1n@ALiaWp3A@e|1TnY@3J=`vPF?Cdv6KZ zD`bQSnc0Qxkv)=?tc2{n6;Wi%9vR=`Mc4JY-q+{z&+otA?baXfTer8oUg!BdpXc#B zj>qHvm@TJKwApHJa&|(Gd5YIrS23Lotcw&H1VDNw3vZ=)%7UfvQ>U~ympD=ZohyHy zw`(s`f&TU(JGo9KO3tB}+GiA`c-dTmNq)cGLGZOu3^7ER$}<-o;D&m5dly`7jOazx zqR%`}Nvk2(Ibx4~Wbtc{`nD%90tOA3Ga#Oak$u$rBFjwZEAYXXvxV(|YykQY2>0U@ zXjGXrBX%DDE4HtRCDMEX%n5$GJA$N7bTI@l_3_VpZ-3Wp)g@lo2^yCz{ZAgDg_Tll zmnMbyNv(X4CA?ybj50T1Op7Ix(m?JIl-kQD^TcQE5+%3{k<6~#ebn1Ja2tR3OFKov z^71l>QE9YI=ZUZcRfXU{{pLgVFm=l{qbrpuFN+kV>or0xMqq3)vaPjjW3tpfdCgTm z^!DnvvyY&3agD6^Sm9J6JlAo}{V~0qIboF_PM739+ipwiVP^87=89@Yz%C6*s(`*M z%-rVU`#?d_s(S;;j&v=v2$lUBY(`fqONFnA^OjwzpJY{}jG^Gf%aatYAE-iiSvSR# zkK6hl9nEwJ1P3UKly2JwdWf|PzVqzk=DAPwZGFkr6&1%HD&z(`hTehTotZ<86J7rd zq~=^kAp%!D5p*k1FDD`w({U~79doc6sM-6>Hf8*PSX_u7lbHO;z>FMb@E!zuLPFjQ z1s({6lGbO;YAoOvA@xIu`2O*pQ<|vxFJ(>h0jl7)4kjTl+?R%A-6z|!3Wk(is7?@r z%uRt~5y>5w5}{i4smn>c@P-S2hByr2gudOhFNqLQxvt9MiJJoj5U9JN^anUK9IaBA ztVJkw-`pQ++WLe4tPPxeqe~J>qWq2NczofWZKD9s$lwphrb(w9X)W}BRz zz*`!f`U-k60MO@cjP!Z&9Yo~Q0?qvoZQ6Q6%`)pY2d4X){U%yggTcxJeXu|~Zn+c@ zl|%tKRUchTC?3%Ot~(FAdxw&4ZbCa5ulL&eZ1aG*wIQdXfDJ>9lXAN_lF{-A^_7l| z^ihi-N05K_cmq+E`_Ifig=!9Z*y;o7}$oFm_FW z+lSgC76et_SXQdn7#Eie9=nW5Vi&~>4#Gx7PdkZ%Y)D@*aM$}1cBloTz-7MU#ZAIt z0*XyJ>!a;o#9%%bkB}pIt~4dYr(5rtk90CRY$cLQFjDwBDPwM`;6i4m(#M5~k(BbP z)AFSS93BGw=GO@%19|??jQ%}4AbGw+v{uxxzbk8C@`q?Up~Q`tn1BAph^F$V;61(z za+mPTmr2Kx41%Q{=_w{WR4o;rAEY)BRsdqMQ`WKa_D1X!#~2yKz=(ks(L(X)8U#vi zS5fd_8U!LzbRn7>NG41R~m{nmcB<4*ANO-A<3BHa_VJd8pM$D4~wRwjykl zp#A|S3SBnmR(}0Ulc*$lo_oKoyEmf6azlf|!^L8wPK%a(KfG>l3YCj{WN;;Dc` zx6LKw;mQm?nN=7nNmIB>@YxtHlGv7e+mCwugcd0goy)&Yjn6Muw7qQo-2sa6CZwGV zZw-oqUNmdo1e>Z%-ANPSD?%b4#y#AOB0Go#2zG-KBjJda=GoMpam_zezpb zG4KuSH$+_OO|3uB&NpuK=|NO`RyXE+8fQtI1Xc!OcMij}D?LSie!~@k9K+^1z~1Q) z=5~t_dJUAWGkhaO&k(RNv1;glQSUwCpyOubcfM%^J_JWQx#~k?B+-=z$sC z`*gIbHYOuBcPMJ8k`o51Q5U_rudC8dy*72B@@Ulw4r)+Z#45a^1lO_O7q5D5X>n6g zoHD2(Soz0bWyTxsvW(VmxRhc_idJi?!hz1#EFkGB04r_Y~jHQuGbED+Ry zuC+=mm@IMV^@hK_$-uE>XMAjtG_q!qQcgzDfI#@2>%VshBp(rG9`3pn1(x%bJ=?L) zwfp?x`Q+FJpJcMVT29Ds;3S{d#j}(8dRk1=`XIniV!okUzZ0PNz1rUbObb9I-@-`Hz%N#E8o1f8JeBgW@Mj%43|{1i0CkRXE|W^ zp9MHcRu*x!F5cd<#=&(7(nMkw$TotvmiTAq<(p)O^l9xJ%~qr1a9i_bkO<(@Oj-9;O$IDC)te_Q;#g}v#NT0h|W@BLNpZpYWyLnsVQ2h3i zC1<#?oWo>hG5+EcRO|vGVui<45i}yV>#xMWijR2nn=(@_&8EyBizdlKFEQ4Sv3_!C z*pV~6_eXVGo~e^cJ}I0QHC1#Z**gzYzDc{XC(%Ti3a6AEs25$FEfBSq2k_AXAl#8k z)Z;DWhGOeC{}z#eNK?`qx}p!ZiomM6kRZHeW3mfLqEKRCkh0zI5%xUR&_`By)H@8W zKG)T3@UXaMCeE9gSe0DuLxl2qs-K_J5H(iO*TTjzNui|gwJCFUOJ$Ss~&1auuN>jhGd_If@9NK(f<9bYCI~K zqz^WyK2f>XBA)FE)MPDG?jIFLL7-vV_B=kF(Sh0@0@g4CM#vrull&m(4tTp;hKfV! z1)3N$Dh|$wDOU^-mfLNLLpvnT`lkVf_EpLrB?a?}2&T7uhILPStZuLR!$eO>Ot#W$ z_VCuPx!($9O2V5}S+2qfpg5<1GlqxV>4gaLt{{hyS%BVMZShBCy^rI59}!3nwA=Fd z-w4i`z=cVGe;g`_XIR3<4_K~vI7Ia`)&Y9y(_vV5JPm%S=K5jZc<^j4G?eoJ;&1(H zi3ux_Sl>1`5k!zZUQV9*C}e_Mh(B<_BOqp{IDrgRYvVSyN=dR!vWvXc66r!kbcp3^hE9HOPemBZpcOCahAfsdi0EDvLoh--PpLW!qHT)H#?B6Y zTfgF%8GIK+zhQtsDPc4~3{Mi7Jqr5Houi)VQm@OVE>OiOF1*q5^=Q?0*JtxHmiyNt z`fK9=Ve=Tz5Q*|LTIJ^z1-wHF7c_nCO-)T=a&AMf9R-E6&p$J74J?JfJrt`y!hQod z2p{xUk0eVJA?Bd&-*Q72?Ur|1wx9)lHr>{WKR^O{!hX#?kQ0u@FORx%6Qhz)yna=E zP1t!305eDR0n5f#6F_PCJHo%Fwo3rPw3sSpiwSG-a9Z0CIPHhlfmMXt`_#s~3Z((M ztS?s1>UtJ?r1e+(QX9MLEb8!HjsR5^M&7U)zKP|C^r2MjXl3xWA<%^Khe^Tb@)iVSfG*IeVD2ao<9KM*0q7sn56m-uPC z@Y*=@!*-L2EWz^9y)?O!o6Y_&5EX_ZR2UMs!wb%4x!%eKa}5z%BV#Jh!Zg9k4ZV%y zU})Ur#X?!Ar4;}}Jb+w5wkzJH6@+Sj-5xW3g?hu+-yK3v-?6%5p zJT-!F@66tq=&tizW0NK^&9!- zFKDVeiQf%?GgUX=Mr{IcZTokxqSNxSKr1*1ZYrZ_FTdBtO&!vJbKf3iW2luDgC6oq z8nw&u$#3+>?$TPl&|fhB_+F79f z?Li9?$a+z$RI3P^E1Hb6J~E~sv`pH6MgPdnK8B8=Vj_1VbchS<{kgRKa2}|O{-aXQ-}MO zQ9pi4K?cZOLi+1qsQpM_cJ(R1n%ZO++G8BiuD8o>H=bpDUnrIh6V6PMg-YhfEjpkwpr6nSHI}=^6e1^sde?e?;8Nq+9>0n>2s!1JMf?F~4#s*Ro$QQv&T;9>7V6{L7-zh3_bw{;X+aKN+>-zq)Ao+|eq z18`vQEvw0|&@#Gf0VK`2Cxrv|P)P>qrrLeMz0G<@um#Nfjy1})J9X}i)5!sn8|$YWG305X<+4(+I4`qy*llv8|=_y9pD=){4B zYtVTWs{Yq{6+|F~vjk7eW(5u(7#Eq>vvUu1%A4&3${5vXKSO2qF*ni)C1H!98^=Iq z-t5!oR&QFCm+e>JUZ}Wx`$z;m@&nn;*RMKuC8<9QMXyDru3n-HQ5J+&*`OBlVG3H7 zkY|O&^WR4=bF8}WdSHgye7|BIX~vlX$L<#%!hvenbWDFK@jP+W-+7@4$0H58$0sZd zOr_{Rz)0W!hW87MI?^haf)C||^~&5w3bjka<0{Qv3aB@m@rmL}$i6cM>kV~y;$imP z+ZA21&FDg_O`NlnX|@_Dfeu;Wn0?fk39&qB!~QeleGJ3`s~emfjKCD^WS0tZl+R?= zDP416Vq4G%Ex|zSdWmE`bzjts6R8pu`xJ+#iB?(vn$Ul)wpTtPZqWy*$8Xo8}MdB!vV z{PyQ{E68FWeDXaHg1&PFE?c3Fh6{zI(3$-rKCZFBb@MlT@S=SXJlphp)G>2~*f(N? z9%`uOS!)RL|84VVfsB{Uo?75G^BqaU&YLmAv*zn-H9rQTqos@5y;WuUT62F2mt;~1 zJ`i#HfjX-VkR9Fd`R**F%HK3^o}OLK>1^*_2B?I`9VHXn=lD3N9Nf9RZ2R&Bb70un%nrIlJqH8ktNu!|*v3o2F9KnKNc z{#fH;qw0?1B!bR^v(wXtOdrb;4+ae)nKanYEEQQL=YZcbY<9lH+>XopOgdhbXL6F3 zSiydS3j(we1|J-Vp&wfhKK7TO54yw4C4Sk+>N4kd0GJtFtNrk}Iw|Cipe4eX(pRx_ zf67LLFE%r@1=D3Y=t$3eEv0EFibRU-`rr^c4e{kcRu%nNA0yAE zM7iY-=Px7RmL5ZYeZ$xIT#;9{DzDkyoBU!}%NF<^F&IO@MJbqfq{of*s;8dNOzu@u zB7Vr~_P>9~3c2tCQUgfSgwfCNi;9AXuIXS639_W^ZJHK@|>S+85`ij5{bBkZ{vntS z08_-Cx5Lk+LXC6*>SX#G3ZE1KIDBH??OqrmA|}efz9^Zw?zZK!dNHR=xb1BOg&&&C z!bCm%0}hZb|4$|Ci0yE@F|A}YQo(s!axteWSC{Qy#nR_WCGx`=QQgYBH zGS!N~wWqM4fL;3svtr6N=y1;9OIKMF4nk5ltlqA!v}@eU&O8gNupIQupROS`Z5k0M z8QZ4aPLHphd;t5?Y0>Mqy$Ks}S4oGf6A&smM9?qzyfYI%WoFJvbuW!WsJu4B?}L-Q3IQX@T=m#{z8Ur+VW82a2m`f>r5HL zJ|7b?LqkL9_oOm*2d+k4Etmo)?}=L#Jfvm^U1HA%&Z5gemA=4f;B#mGfvamJeimm* zm|QLyLFS(fLW&I6j`KaODPdDxp{o-td_+oLG+8dRtA;fA~c(BLn)81TPUbp97p% zy)sTA+}ii*rCmP+e(Kb10SY{g$`9fLcz}yYch27hZe`{^s(VfjRw0*VQuU?AMdN$j zdZe}UyDMX|O2zq$9nVT;tBP5blq>6Mu4MSykJlL*$T=z`@jdDI*5ak4O&|^vvS%eX zGX<5FPe+=HRQ@Z(QJ9uNM&Yc=+8cX5>Ga^XrnxLFeJ1!7Nk zvUfWKozG}(PwYpVNx6*3#NCPxeQsrXH$J#_5<;6i{{HPv_w5x{%el;i^vt2j|%_T?Y*a;(+1cs+doxc%);1=Ty;fFSN9Mc9cJ#jF!3*fEL!>kbdZdxV;wEt z`F2y7Phw^3`|Jr}QW#?c^`L0elT+7@ukV7-5;u-eb{Tp@Ps$1zse@LU1H;Z%X({dnkX|c8%)KiU2 z?e7S4@gAQCc(;8wo@qju8CYzeY3nW3+F|bYHTCtp<}&WpEi*8?r(UzF!kj%SsV`zk z;8zo*udnX?i6}|b!3vK{e3`ui-mht3rOg~|g&uo9aa$=oA`rJqF_-(u%xAK`6mBlB zIMC^36-WbMHf3&M{s(6rjZ$isJ}cz)4P%8r8-UOs+Kv6kExrYcMIJ7x==qAXgPg0a z4IcB(ip6<_d}q|yOk~%d z92HqCAf?i8@y2?Y$7LJI|}wh5~5e9Nz?AD9jL2!tL=pKBflpy_i*|_f1>) z#fcjL?)bRv_t!|jcVra~UkOMgaTTo9b4M$xvOE?S%?Pi2Ybq!y0irI&#Ao{fYL)6m z%UBT+}!djJB z*kqG`UYZDce$hu_Z(LD3yTygdg+S@~FCgd00q^p{w-`jfB|%M_fwp1d z1}E6M98M0$&=`_=U6o+}LaXSp_Bed3K|z;w3Y0mY1%vCg!U4w85pN`PrB-CUalHtC zH8UGFNJjEOcsd0q3n~d;j*>uCLk1-SD&UqhW=4Bt# zLM~5A-I~bw``Y^pRApZKG7~C-Nck`Kt#uWumZtSr@w71_Z`OPKyqyFOpHgZ4B!74$ zPT5KD@{k~C<4&yFuRt1=cn`j$)zUl#@u%2WxG6w%X&HI|rx^QhO1u&_teif=z+AO$ zeWrCpoxiXs^@t|mk#Qq^)Fmgw`{`uI?vi?*Oj{xJro1t!(N+PY{!u>9r61UUhp324 zj+G5Ep9yBiCl^w1xl_3%o=5oDsA=63TMS6MC!>Fp_>#ER+b2g}P5 zX<&t}_Yu5CA`HE2wYn5NrtPGUgD7X*sP)7wKG`?r)BK+ z#(fC0G7^`J;;AR5g-WD@Li=_Z{(tOTH2#476yZ~pJ(xx&o4$7K>GwWxlB>D~<7w^B zD=ufs?)sh`km;vPuVx)zoiA#1KcsNugN-ylv8bOsRLp|^fWbh(-n&oHb;^oA)`m9> z46uy=bTnE{0;jd(5zXhtG__o*EE#GcKX&vgqZ;>CwBpv?^GDk=Bacfs;^m5UpV&P| zAKgb!foT28f7XTUT3X4vbi) zVG}T!48yVe%~o{;^X7rFK~Xsxr#%%vcr$j{EpbE+cive1|BpOr4}14i+*db{j-;7 zWcCmG!7}Y=cwe|R>Va^@8m0?4=v|Id6Lx-9V}7VY&HL_iO_YxV`B1VOqRbVfFZtcY z+QkRO&W3nx4GNtMUcX+UeVIhR-_rt~sjgcD37@Bo44@Wbu?OuJuB& z>!hdLVg;tR0w*Ve8QA%N<~0rIR7h~d1=JgvTX5QL<0p(egUgoG zli`u?G**+|@at{u8tbye<;-dY?Aw4Vf57BLV?)Kg0JdVxt? zd2cwb6~D?^$NKN(XBti&*+J|7z&4P&u~;WpG@i+7EsU?>J29D%&<9B32)-)0>z;~A z;NG9jsE6J&5Z3$quCLDg%e$fIFjUTqmNZdg$O~ohg~OqGxOW z@5;;)me-cbJf=eR={j7C8KWC$pZ3z)N~q0>7jX-};>(`zQyTAlWGFPOMhy;&9h0!; z#=IRB;em?trI^-v&4ydzCnYmHagD+-oGL{)hp*CTda50_NtE;wF5rm$?nY}Fg za7;0upKqhaSxo*@rNTel^KJ zKc><4(T7}tThQz>_-weZHr6k7X%bG!OB@m*@Xen!U+Zqlw1l=2$;N8z$(0Z~6WnoJ z30q}uC)3a;99ExhZ-6DhC{iN$5RVm?iuRgM zpCW%*_aae&D!EQg8NyzFRVr1$?nL#M0p@RlEAX6W#^SiXO!|_RdG=;V%-4t;q(8ap z38O!5IpnBI5A^?IQ;9~^(w##;lAL8cl=^ht`R!_hlBM*mB&wa81=}hL%7+VIw0f@U z{^OA_e{+>x=`2=TyG9nk?_bjsh_v9_lT^z0FmPy6Ng{XUw;f9`@;n+rr*Kv}6jtrIee9B>q0(@BJUV3+#&=?&dQ!W_egBF(I+6>?!3dy_FsQK?lixgB zAPBXJrajJ|k6QFG+t+KcU?t(eMruMP97z-9aOuL$gtR~9Ckk>?5K)BE!La>D80aGeLssn{pEojc9j|NaHUwMBA*F!5Hu805jB{qBNx z$;30;;Ds#zKZbd4I@iZ0-l@$zR+ss-%%Q~_1_yIWU48Z3>^$y9hk{!A#`K%EU)I6X z&QEOv*#mv4@nqaj5nnzDbrjBY#-oPlN)o@mUa{oiO|}$CQbHVCof;x-)uvertJ2u< z$AIut_2xDDJ=UnN`3nDO5-&6-*FnUVJnbDiO^}?*i5PDhB-8ppA7zTPdGiFQfKi&v z@o{n1CGCZ6{J2`fsIOvGIsm`U!E%Gg)az0~rqOe=?Wpcr4G)N#duG8+?|m|wte;dL z*aU`KRWwS-cK3Hg8;~lNNFhUiYPlz>Xz8E`$**8YqDwkg%Ap{cKLin&C956*TH+m_ ztqLLLJoc7N{f8QExew})*lJEce1HSnfM(GVoQPV`wH)4M>fZkufZ+;9Kp`&+^GClR z4ri!}4@9d>>U|0rcwYsf3jOT1dJ3oYC~`~iM|Epk{iKBdcw;jkFUcYJrJY!A)V-fWdkr^UeGD!B6JeNC5hyx-6axE*5*RQbLN77?jCWIY zFXHFUid;UK!}muL&YpumR#*KWjkC2rf(|N)f(%D{6PsfAX7N|5hBM2jZ$DG4*_v2k zoxfZBZi@Ny#c4i-XO0uA2xd@$+|z|@^V&#AAh}^JT+pk8RRspLp1-RK$_y7tW-umE zy|9=W3fR+{nMBoabmdP*UDo2oE&|sgEQmH7E`vG=+R-4)fR^l^kSQ};BPh&)9)LxI z=N;2_X!#YSzu$ugACVW;*chn53j5|J+(U$hDA3~ODAsFVdtO#r21A9UZWQCT84FvM z-6>;oFQzc2i@m=!FO)UHkw4~?kA$!AD0c|hPQSc+RFJ;*=h+Ttv8yu)PUyXdu{#;W z{s>+%8>$wh<_N6k7%CKP78gkzz;!DB#g(mrurZk)60g&P-_=7s-gW6o+Akt}?~#sr zB;Tij{b*%ho|ode{Yxfy@2N!l@ge_z@5aP&rFcoqL@=4-FsefJ3&oAPihnX%!G~ta zN5^fAo#_|IZ&?16W6wh5Kozg06c58CR4zBcWj%O8pO+_l)4B}n#xB9F-Bu`UQM3hW zJvoEOlTHTS_eBAi4kLq;P4ne}ZKGfb$h+FU((!%@(2IEKy!hMcWF`D#8_KSz0ElPZ z9j)j-emU0dX4)r~cpMmZ7-UJ)*#;mlc6Rm@H%&;p;IDYA3Uy-&L}cv!6#{agAxyy< zSVi4+b2cG-(($n`Tt&J0Zf)ep0r48vOk=Ym&<6M)brM*8+xvaOEyvGpoG2T<*&0?G zV{>IZ#;m2bAUp?MRPl(CHu#0=wtBUiBG$V zSm~a4z?;_xn`kGa*+ue)T&0Eu$ztd-cBDn(Jd~=B94uY9Pd?>8)OojN1)T~}apAn* zx;L35aq`Wfq8-3@mHr^eThMy&`EttR8IsPR+Qj6eMq--`mf}k1Y;6&{YrT9fD$XSB z=67=?CMLWuoqc;Jj1AHQy=PZr$jq^U}pt$&T+R zLW%ezv~*8OQ4~W^b6USGN$Hh$6*Cf?y-{s;^9Q zNz~X7OX%G(#uG&3tZja0?R~D}KpEqXt^GMI>*Ni-&xnK6B@slmyS8z#M$;X2bJ`jo zQ&Z6Ik>c%xx%`3K6EfT4T94e*?-V&hBJ!2cPm!ekPv0T(ej&Kz%7ou0x-@GZuT?zW z6h>)*X9Qk=KodjJ5l&2TrL|GP*U_ilwN7bs|LYeT?t1ag)wZ20!7w6qJqy7#? z$57oqN|zt}8&72kc@ZZr1yP@0Y=en&`vDit05~6X%Vms36RGqGD6?mAS{Gkm8d1uH zi4JzxQeC>-1F!>WYip~gWZBGv8Bbey#vkhY`$IfsE^Iy4+9_4(+~y(jTe!A& z=qdR?RaN`}{+9G>tpbmgWS&~%hp~F20(OYu&RcU6cmj2ImTNyV6umVyG5$~Y-$E(}`&WD&8 zb+5~FIk$JiaR2AFl9ie8J&?{WX>3nWu5-qg& zME1U7fBmm#;oUbdGCGi!XVcubr94rfkz!S3X(zwE%CTJWi3bpOR4FPx#Uy{LL{r() zC6t62%(tA@`a(O_%xzO-t|ENNB9cnrgjIUzB}|y#3k?A;`dO0l>>;yt3ew^IuNu`U zO1Dt_Ex27VMgW^?hN_E@aeYmCOx(_h##`qn#r>#PH~e0;$FF;x1c$w#vIP$-v55E; zn=qAT(Dr4SN6-*vhL4`lp%lBC)Cyr8!f5sE^yfB&ImI>W!Y;Ne9Uy|pxqgYZZ+(_8 zxm)<$-{4{G=%(Zs=Fj0Z&l^~BW1g4eRlBRa9g7ZE!Q|D<27wE;=xJ7m6W?_Rhu5jZ!`qkog<`t9Ru3~^#7>$M4S*i#vm3H7dn@Jl@2UrOwjI_tlll^(s$DQ3111=um(16ynGVM&Km9 z-~_?l-l$+OAB-?z1;6vU_Am|Nzlkcn9pC&&EUnViFH08L z>i(72e>vvO>&RTAmc(kyz{7bIZfvu*RVgwmvJ57G8_aT3;Qzi+;$x=>4FZa>)+@lx zL^no$E`T))of8Ces5tmNhwW=#71i)BgM+s=`y-2ew2^QE;MupciPxfUR(e%(Oy%Uy zCrh#sj7`P^-i>~=V$7pufO6x1F{m~*3r;nen!iHgJV!zXq6(Xg+otj zHIXQ-4(cnVna?4SPw8In-j8;)!&dop!e5)95qxj_rK=NqW(URM-r})z9=LZ9rI8$@ zPcYq24Ken2AEi$lr)~QMJxikPvBi;QP_sw~oIWeAxQ*BP1m3)GTC~26`YHjZC;{CI z8pEOVJ&st=YoVBKqASFa$yN>yeuJZUC;65yxn9o^1<YyDhtMkO+Qx4RQWL9nzC4W)8+w!3-YYr?E=18|7_Ds zY+VfmeJxtym$Nf&1if^>`{f}^#m3zVvvOHDg&PpcazjczQnOX_kS`+kO%FN%OdfXb z!PUK@aF6;i0LrHt+duO)@opaMH&t2#zUNxSY#N*x?uyTsaQ{e#Wqph2*Mm6=*suMH z7nuho>mV&QLuDM|nexUHhTc`^hmU3#!~5@{l&gA-zq!ff$20HuIEn05_EN?}o8{G+ zi&$ziDcEXeq-7ZUvn47Npo1Ip!o1S%0{#Eihz zv=-(ZRx?AauA_+Nx=aGAUk(P4#RRsdECPEHsIzoclO0|QtIf8Y}+ zLscJ@tf~4#LsOF|o2jM$XVLHA#lpl-?@OP;gCMKi?VfH>Z$AXlYTOL6un8uVA$WKP zz$IJ2r}3km1DME;Yy@o!jH9*y(1;PnX;8;w{gns|gFtJ^X%#Gj`-k+&mHXOs6B1$u zGtllu?K%zEZ!@Y7tq8FZMsq9zMIn@DI8MOT5kdrT73g;s zs22~a%?DpXaf%8@5T6xO_Oi}greH7hzBKW<540aFo=Bb|JuCtJhJR-;(=VfEK{;*t z0wxF*O8hQ{_bJ$g`En9`uYd}Zw4ACo?FJMs+<)4hEzUbB!aMEc_B#cxbQ|8#)c$-kyq z#Xxa#mR6zV#f~6qd7oSxA?Q>*>@iQd*5FLTqEQZ8xK&(s~iSr0%9xWR>qLX zXt~eMOK46UGyOFH;@4~x2#8{tpc zCCe~o$K?mKiY5d>UzW@Ga^nu59CUsp5Wdo`3;yT=Fy2HEEId3r5OQmN0%^vt;^N=L z<^_rdhi8OCZf}Xf#{q*j>L+U*z3excAC4J8?ig)@(7!BsZ~KfiN{_*R_e!R@ zry1&Ac4wOzsvU(L&5!%b1sDV`uUW(gwlCIvNy4-qiHy4%3FS1$dZfjJ1S0RB0Ym}od@_+QC=Yi(48uo>2+-1L6e0L|Yx73T4_oRGnEA?=jHrivS zqtr^TXX6%sr{{S~!f`~OUL-tH;4VXqu}(u?{1l$It;@v{%7Vb>v-_5L>#XKswVi{^ z2GHp3?TsMmF<`}XkftY}6_`p~#>DdIDOfiq3!*$sSXK7x0fiB;A^Lp`j*?7h>Dr+# zW`8<@VUCo;J{m&%PM3wU01ZDpud*LS23|IWDHXA>RhZF5b=xUoE0$}G!Gjjqnop7> zU0>928n2bR#xm9OxoL~NG3~676l&;ZllTDt`*60k3Pc#t5Zgp0=6uiB;01-)IBL%n zlG)IGc62>|_2u7xm&3Yf2e*hyQf;c)nN{ znTKH}2w5R)SMWIv8aQJh%bZj9U5WPD14t64>o4dUv#-FmiVT;Vy{NR_1VW{y6-=&k z8Z4M(vK>K5t=Y#zfKZnVvOk}ljgAJLnSlZ;&g9uMyQbJpV1Y3yrrbmJx=n$QR{?3Y zRR$FW;uS!H<_jB4YDR{=@s9DeS|JY6p;44F|9d8up+5>_jKx1maRb8rgJXwvIJv1( z$}NA2P>7cRA~uECk^WD@4^pWzFH^2R7S`IFvEsdwWb&m%v~7k2c0W|yGgOhfr@OWI zM3+ptnHnWf+6-%K8Mgh33T!m%c;36T*3$Goqq*5ISt*hUj7naL>{?Mg*KvmzeZ9Tk zNUFj-MF`y1N4?gY=YeRX#8kRsnhH^{=b|#!)|DvWS}~i8(BCTb>bpFiO%gLx<1r!noPJCnT5)vM@# zRF;{DmLkDgGRu;$5mA-YXld@~Eo{J9VyLWB{?zV;l5sz6zt`(xEKLKsE4%eqE^FW@ zJy;3MY*-W!E?D_EIT5{Z7<7=6wn6M}xmTC7pqE23wv;x!sP?=ZvU?-?n`)zz?cLIm zUVHLKX+mJ~W_4p@BlBF-Hfj9A@Bfn(Ao-uHfQ}W%d@w)5KjX@rzduIrbLv_eM;&Jl z$DHK}5>Oj~v!|apgRkL8KHxGQ9DXRN-qcCe;(v&785%UD;Mo z`C_2_^qN%y!p}e8eXz@RW4_amk4m=pR*rJvP{r}X(@{HxM_)o|FRHkG86z^he7Bvz zp1I*{gA<~PqN>1>908f))#|?l=db#W@BEdN^G}4r1K|eo_DZRUY&`fZ6ar4Q!FNlq za_W@V)@8mtVU{cXkkf8-Rp&;4_<5)#8Tck>-aYG9JKANTE2+9~D zEXlM-n)Pcz_v+Wv=Q0S(f)y=ulJyQ)93k{=!4Z6a#>JAMSW*mqODPN*Mj@rRoq z%Z5MQlbNbG`HnDce`SLd<|3V6ystwgZx!&{AF2j?y+}U)v`&GLVI0Mya7tBDp@F)~B6*Nteq**W9)Hnhogh3-i!SwaT=*g9HnWf~Dx zgzk<+riU8=aCG>GU!@BLIXKQO@Aj}x?=e~z~Q>q4MvDb3!pDvu8nxSFvNlHZ~Hlk1XoLD|6)g#Jxi ze_IEWro*4jU;cCx#GO4{s{r0evu?C17!9puw}!l(e8QM^^&#G}W6oz%ofs(4M?aF&dG&4u1?jA&wCe$e6YJ48MXL2H0bcJ_bmHM3$?) z#|-4zP93#5bSs3sskBCSP+i?a_;Vq1t~;zU)(_g$tB^W%vJAm;(RiNkQD3d;M^p{+ zmZiqOQcmPH7UtzJ;Zm%cJO8aeh}LQT`?o3~7iMmmOWSWg-?=?2%_!E%ZCReJh8*00w^URke?!xeE6K}4q8$3q~{agj^&Pu)@1 ziRe0z;BUG%U)ZlUx7NVUhJW67YQG?d-Yh{(UMX_@%r&juGA0Vk<3U@k0X(9`j$2S1 zIgArXzpwpIXX38W!>&@lkw;Ckt!%0lmbJxxyBBDgg}a3~ltQ|trFe6>M4TZcBQc|g z{we`}_r4Sxe2lhU-TUT6?Y4Mvw_(+Z|M#+AMjhR48Ad#SAv5*2%F+R>0?0vLeTBv~ z(Z%&Z!Ad{ks_ijwEqNRWDq@f}<2xDXBX?~it^E9G#hImq`l{k(ye2%MRaSre60FQg z27S({6>cb8GreHVeRtj_x}cz9{Xi&fb0MW^Q!al3rO!Uc?E4dC>>IL4bCS}7;F^)X z6~2?hU)I}d2uZCjJ3@a* zky~rEWt5YpQ#}sdK(8wps2}p*$@HyFo_c#bY!UJE5jqBA`g5@CFCRDsSJxA-hB|ZRz0cT!5UfnbehyE z=eXsN#OaRP){QDoePX?xqL#YK?4sje#`}o+uVb2S;Pq8t?XTE>@`4VG^`-xfuZ8QL zo@?HxKDad(JJ{VoOytY8ChlpZ@|B%Mps}p)Su`MU$whsv-OWIK8wO_$GT`sboSvRS z-Kmw!#Lm3&M(!3u`MbBsXZbD24sNr=0g5l3Bluq6*dQ;L{{9zNB@}<(;9D#M)~REr zr~b)V#yEUfv)MsD*;9C6^s6=i`h?>I@WiRNYggOviw~#=`UO_B^KZ>m%J_ET;&A(R zuw7q|QeHM}&Kk3{$?7#g3&k zNh%1_SKU()`1%#i#fWyiw$Z|LgX3*aV>7{bT+54zg^{URqf>FX?$NNTc~{JCLu)1 zBWr`7@u=qk_>MpzFLFD!a%24AMaZ5=@wHvx83%TaK`PfS%*XJl^V_@S?<+aU`~M#L zHP`-Aq5y(o7l?;F&Z75(e73qFLX!1mJF?<;XPz<^NcP@|w-KQGB|8Pyrv_x1KpAN{ z^}GPfb5}_YT60tL#?LUw2@GFGbVJL0ueV;G(VA~)-MDyq5=QEzE8_SALQ`wh_dlB29FVQ4Ogj-a zWSvB&@qW&CX?gx4^3JKllTh12VE=b?_Hvt! z>1n!nLp{{`mlSs6LJG^}{oq0g%dcg2-#L&g6Y0Gd%5B~<=$?S7`44lNcICpK9s!4M z9BgdT-{BK^?o+?~-B@A&1dgTjRUvQ=nd#A!#fLm}gyd80f@b=&tUIATFSEJr0qt{( z*5zHnR}yq~uCA_fa`_d+dbOr0Lq2%a`BD5Jqizw`I`I_sd6*=c53uILgAi-e>rz2^ z@_~@0gutm3D5ALyF1??Qq?$@bgG8QlFUGrndoh%d!$$x8-QM#7nDhtE(f!;-1#+>C zPDx$U@V?KXx7Ba)wMXCiTDV9kn#$#HM0*C{e8!S&1hB2T;VfyW_= zbRI6lS42x2LUhq*yzY8l!|`38CX~DN9^n#|P>d4aJ_)jGo3S65=xgm7!+QjC;d3(a z^(G%Yc$O@j8;bggik%2^Bd?2)HztP*+1Qpn$GX9s#?C5);`%aW{K))M!Ns@O`}eny zKrUR=MNcihSa9tl2G~Ufaks=G+1NNo>;tnh3kUf0iC@M6fHkYsOmn{9jI$K#?3h8I z2AnSS`NB!9YqSzp!4fnTB!eMw8f>shuf$KgfR$-C<}3lMObXJ4zeLo2JpeG(Qu%Ik zK|1F8ow~fdakO&eR^tyA$a__g9!j6bsi|2CTIw(~=<}{0FcI)N~o2re* zs0UYu#cQEzR(=(t5#3O|R=cFi^ zw=O4YU1Y3hdB-H0+g7DNOdhz;xq`I)zdlN5ljmusvvP|c>{xxRhOaKb%jy?mIqr9!#(vW^Hr>(i`2?6m8tDqlb&R-(3j9?PC7($3Lj?zP{;2u-F;aDWo ziN@(_gEUG+4Vm=sm5GYXF3@<>WoU0?#$jE=ktp@a-;yH~;d_cu>~X_?a)+#xOxpN; zooNCQAr(IH8#Rk#Id_oB6(|2;#f?z$MVsncvJ<&X&O55T21}2C@DpN8Mr%6H_1;j* zL0$Mz5unIll#~1zSnvZSC8=7{fbz!S@fhiZTnFs^<`=8%E24-8`l#(N1gV$42>%p| zU`*mr33sj&!&{NSIs;Y9GkJsK(}`1C9W^0WS7_JIJ`ztm6F*QL!1l^&PY00iKR}-j z)$BmoLHY)U9(CU!-2O*@9KB-1OveG{mcYSSm%9_*t^9Fc3XS1*4RrTF15~{(dezL# zLN%D&IjegEYw%hihHq!7U#rczf$IMEe~4A2D0Iw2m=_5HU)#QRtp4PMTv%Is^z>^E zG~%K%hStJP!CeCp6%=pQXl$f6t5Uvqj<~N5ST$d`8No%o zdU(CYo3{SPgarx51^3G{o9Q1CtZ+Wg$;?*Qd zwi?S2m8D3wmngE8Y+0g&$Wqp1ODNfQ*_w(`8rhd*ExQ(y8B5k|Ste;{lI?dN`o5*! z>vw&>*X6HsnRA|V&VBCZdG62W{(NA+a~@mB$0qIzUT;ut3@JZ{(JFgj@E0PwMv0#E zk`WgZl7>#I(ZIY{C-}S0m$b4q*|}1;aJ6?9yKM4 z=57Lk|Fn9|`54Q5Z6JhH)yJ3}q#V^cJ-u85qZ(%kXxz5(p$4`C-dk9JF_;w!ci2^D zyG`Fd*mmchrgfT@*nncj6Y3tCQr`(jdZku^qG( z0wO&T*YEvFPkEN`{h7f)*e=6+0EV?ju^_8q9~oCSXzE}{&)JGTNfr)(tQPeu3A7wv zIg;OE=*BA)PWS)?Wk&JunNv!Bod@klZ-CntnNx7__TP5f4q%e*`zyiPfmJQLp+DVG z{w6p#)E4-!buRuExHS;C>8|fpMPZg5;s!Go8#Nesk->G1 zxubeAr0bBx4KMX7-V)WeHJ1pmOn}Z!h?z9{b*$9uetL1PU1RcKI%C%Kcx70a=PbBM z+8npaI=~p+>mLB5l80L{jalppHaG87s383093~yqMV(Gie}~rs-)hY?&|u#*HIaIK zpOS3#hx_OCpl=Dp=Ix--dQkPjoq!)cCl_C=W;TRtlf{;8{iOSho+Fbm!pVUqu42l_q<@4PW@1;h+-(>o61Cq?wEq4%Rl>Qb2SaTxD zCCZbP^5{({rvXfSVCw}1{;%4VuEc_TXE1exZ5V78r(qG14YG4X7;TRG@&TLupMX`9 zDmM|jPod=|kDlRu9!FFdQxR}MSjUsazaot{mg8%d+;mgBuu0>d6*0nGtm-K6U z80zY#B$!=EEMAGO1BO6ny$K{LCr3zcmqvdrHS(Ff2o_I$LApGJvbq;rJ z0t?Y5MtJos$0BG=!_#7_1(Gfa%$tEyOeP|8m}!SOcd8Tt$%{{Z98uTPMmis5_G~^& zSk32$*X47GL%Ba7Il@NXuzQE)yE{MLYV2${7F`VqH(btl+@jxoChHm|y#~6QiYF8N z*8s02oU4owE9@v5LF_)rT=|JQ=(t!(HB22;`EF$umA=%@CKyO!dh3BreSR=KJb|g_BF>IMZkoA zk^}L|D8||S==p`2HUn2g$DoT**y_5oAyv#X>Yz5$$b+oMhkW0js596d#eRYQZEI4Q z553gChD&*n%kXW=c%@dksm6xU@uy>xOfRy&AP1`p?;Tm= zU5>9m2_l0eCyZBB)oOUE^hAbPT>Yh)strPJs%zWs!2f%F)rxwuZ-}$t6t4C4!Z@y_ z3t5(m#B&VF|BJ)XhiP1*>E0qRIXZpKNJkP7WY$ZPClEA`pc{}3yr~N?Ln40$$UTBl zlla2vBj=eX!&Zgv3GIOhw`$%0yaw)YXN~RERjI(FXO|a#hanQ#4NneHa`VXyK=de` z9yljdej8f%;fn2np0|EKTTAr~hrX7p%O7xvy~8?J4qb#ik(IH(2P96`V+-*#Y_o?8 z{_Zv&Lj8vdQwG{*>&Ho`KB20W@RfM=9}*Md6S1y#37d}HHjZJ(|6ytTUO~_Gv&08C zC%8v{Y5~0uDAcb&TCksUQ|G%Av%Jz+-`SoHLk({e2_wk7}Nsxx+ z8Rw~hX|22A`-Ft0Ff(}2u|Hr^36BOeKbX0X*vcOqIlj{{;%<5ll%XGQoRhpT9AJTI zAyS?qPd0K@GjE+c7LW{0)ipG|V&lFEzCUv&$U+NE(li6rtKyp^M2`Wf3XvA)G^XlO ztCT~z6^aP&_YiGP^IMJ>7k4Os>P}n9c%qPcgu`9*dnah}qe=m%qkK}>F195E3$*La zo;6y_^NJ0Yc%>N`dW50y?~3kF-1-hh=indUv+i2)P_X;6Sj-FFv|OH8m+Htoy4z(g zdde&`M8Fw?h)_t}&NHG!y8qXe9(HFobvJGV@Zw(80A2U`VnlNtdRqj2PYKxb4{0b>&k5D;YEkO*?}t)fUtki zZf^NP;DEb;?Yi%w0@Q`MYHK_~DZf0cA+x~UX+?K=Y$teMM&~b%or+>ngMOOa} zTzMugHMt*z&!E2d-8EHEA!u?&QNjkqi4oA_>{_6Td7x_(x{E~!3tL*MUYGlEUX-MG-?!`=g} zS4!st0YIG4NK%=9exEgJXus(a_+v>`T}1>s!j2=(3hTg8&@@zQJ|My^dwvmsGxe8P z^<=(OSuWuxG?uLFQaf^Llc@nDiNpfG;gz30m#j;n=6mMsy8h@F{68=_j*>;eKx378 z#S3Ilq(H_E+M9vlT!!9;*KnUsQvrhidm^XHfzPno3Uj0Lu^1C*5v7WpcO6lqj-uxcbMFgvM%p%L^ln z?9%r^{SpkZQ;0I|PEmYatB(%2ZLDSzF55Jpv?VeIdb!P)AIQHp{7vX#2j8CNmK%t; zD5n{@-B&CI)+f8p{`u%~ws!yjAmQ?&0hd~Rm^)4Ukv+G|`M9XJoM?G9Z`G!;eGuyH z6fRl2GUw)q?i7$Nfl##iWBgk03~QHsYW96_Af{oUOCZM<^j1JhrEgw6z=LhuPsP~u zlFy)ls@FgA2(V7{%1~wM43y@vF5~Rpv%}`TCCqNMRSOhk>UntUqW6slA3ou4vucr{;YHlAJ)r5L-5VrscpKioP4~PPH z`m@p(R~v+qvM;~B0qHt=*WzL2bW}go`eCUnr!}8Q5lFCN+vxg1NZe$X%+0EO% zL9;zTr$8_-HjrN;R%|zMH-q?1^n*whNe+fheD&_1HciN8n@v@CJ7B%PUpC>9$9l85 z%kp?GU+4KmE^Tqdl8S~HWw%pp*s$UB&Rn}4+}P?}%f9k{xKZ*-Z{L+e@^7ycKQ{7- z=RJ#ENoC;)Tps;G_})S#EGJ=Y_2!98_NdR(+#GY?R;o*5*;AQa9;D}SMa8Z==gsK+ zN9Xo+v`g043LGpc#?!Lr1_}1W96vU2pAN2d=f!nPnM&%H=4bnz#`By=g}N)21rl|K zWS@;nG02(gb+q$8%!mjLn+(S{$uuv}aOFz!OFQ~ojiWVt3X;SPZ2D8FLV{k% zd0g1U9SrBaF2rb9Y}`Vvzfy69w7V!{*rb;rQaqbL8Hlpz9;}}v`zsZ##m2P5v#5a} z8=_vvZ#kYQ%`A}NS|#51Dn;g!qmPFQ?ueh5IqK9?jCNS{Q4|bBG?410+oVVJGZ{%- zZ#pqH1z(o*+-kIEtm@He1uI;-7cDV^Z>*!=Cr56%VR%+JXT-iMsoOhEo8n7u5<1Fj z;jx)kKU=c-18-FlMdYIof79(9`w0!T0`2XR*SueLn>B5g$aflfn!@c;9qrGgxz7n} zpCIE(k&u=%Hql|jel(PJWcn*Y;GtDxY4<{uzbliOO;whuP9?Q^wl98V$J}meHdLVJ zmv*|J;Z<^%R)q4vfKsGS6H|aZIYvo|F|C$Y9v?Dmy*Dp#BpGG9^=D<;d&%W|ZnBod z;wv8+$EG)pcS$iYtEe>KO24MaFPv$Jb5Qe%^lg4#euKIythXZ-?P@w5rtQ*b`F_8< zq%Ya@t?}_`rm#m$t_P4>L1Ec9`+oIHfWwa>O~(LRgcMd<7JdO+Reg} zyp@$}>~aRze!2O{-aRDSG}7Drm1F(dj%-{$U+3+=T$5I3FQB2hWgw#xZdOW63pH`l zuS;|;Aaj$p#9m_C&K0cfBA9b(T9G|epCdQcKdnkZFy~RMj6r;6Xjae747T2e%=TDq z^SE+vlZA~QY4@Y@hNiJTGyDlA%F#T-Nlun?hfb`1HDczF0IJb6BJZD&sX{^@a^(gE zHC|;jgfPnuf-qw=M6tk4MwRZ&g+t~j>Uh%5T(kg<2paAD^S5H=DjIM)<zm=1A&_DkuCt0kB%=~TsJ6f%HZk+Aa4O;R=d00Z@g3A`a7g5Q zbv_rher@e_73B;2X++?VVJ+kfe5H$rr`p3LDf^w3M@z%y0Z3BQ diff --git a/docs/source/images/Terminal3.png b/docs/source/images/Terminal3.png new file mode 100644 index 0000000000000000000000000000000000000000..fc684dcf91a89bc1608e2c4308a88c1205f5983e GIT binary patch literal 91608 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ΠuxeVRb_DdH@^QvCYDAIp2`)eZ{PYw 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 G!u|)flAu=r literal 0 HcmV?d00001 diff --git a/notebooks/0_custom_KG_dataset.ipynb b/notebooks/0_custom_KG_dataset.ipynb new file mode 100644 index 0000000..f788047 --- /dev/null +++ b/notebooks/0_custom_KG_dataset.ipynb @@ -0,0 +1,988 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Using BESS-KGE with your Own Data\n", + "\n", + "Copyright (c) 2023 Graphcore Ltd. All rights reserved.\n", + "\n", + "BESS-KGE (`besskge`) is a PyTorch library for knowledge graph embedding (KGE) models on IPUs implementing the distribution framework [BESS](https://arxiv.org/abs/2211.12281), with embedding tables stored in the IPU SRAM.\n", + "\n", + "In this notebook we will show how to use the `besskge.dataset.KGDataset` class to easily pre-process a custom knowledge graph dataset for use with BESS-KGE.\n", + "\n", + "As an example, we will download and build the [OGBL-BioKG](https://ogb.stanford.edu/docs/linkprop/#ogbl-biokg) biomedical knowledge graph. While BESS-KGE provides a built-in dataloader for this dataset (see [besskge.dataset.KGDataset.build_ogbl_biokg](https://graphcore-research.github.io/bess-kge/generated/besskge.dataset.KGDataset.html#besskge.dataset.KGDataset.build_ogbl_biokg)), in this notebook — for didactic purposes — we will show how to import the dataset from scratch." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Environment setup\n", + "\n", + "While this notebook doesn't contain any code that needs to be run on IPUs or other accelerating hardware, the best way to run it is on Paperspace Gradient's cloud IPUs because everything is already set up for you.\n", + "\n", + " [![Run on Gradient](https://assets.paperspace.io/img/gradient-badge.svg)](https://console.paperspace.com/github/graphcore-research/bess-kge?container=graphcore%2Fpytorch-paperspace%3A3.3.0-ubuntu-20.04-20230703&machine=Free-IPU-POD4&file=%2Fnotebooks%2F0_custom_KG_dataset.ipynb)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dependencies" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We recommend that you install `besskge` directly from the GitHub sources:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found existing installation: besskge 0.1\n", + "Uninstalling besskge-0.1:\n", + " Successfully uninstalled besskge-0.1\n" + ] + } + ], + "source": [ + "import sys\n", + "!{sys.executable} -m pip uninstall -y besskge\n", + "!pip install -q git+https://github.com/graphcore-research/bess-kge.git" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, import the necessary dependencies:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from pathlib import Path\n", + "\n", + "import ogb\n", + "import pandas as pd\n", + "import torch\n", + "\n", + "from besskge.dataset import KGDataset\n", + "\n", + "dataset_directory = os.getenv(\"DATASET_DIR\", \"../datasets/\") + \"/biokg/\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The dataset\n", + "\n", + "We download the OGBL-BioKG knowledge graph using the `ogb` package (see the OGB [description of the data loader](https://ogb.stanford.edu/docs/linkprop/#data-loader) for details on how to use it). It shouldn't take more than a couple of minutes for the dataset to download." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading http://snap.stanford.edu/ogb/data/linkproppred/biokg.zip\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Downloaded 0.90 GB: 100%|██████████| 920/920 [01:18<00:00, 11.67it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Extracting ../datasets//biokg_test/biokg.zip\n", + "Loading necessary files...\n", + "This might take a while.\n", + "Processing graphs...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 1/1 [00:00<00:00, 4860.14it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "dataset = ogb.linkproppred.LinkPropPredDataset(\n", + " name=\"ogbl-biokg\", root=dataset_directory\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since the objective here is to show how to build the BESS-KGE `KGDataset` class from scratch, we will not use any of the pre-processing utilities provided by `ogb`. Instead we will use the raw source files directly. To start from the most generic case, we will actually undo some of the preprocessing already performed on the data, namely the mapping from entity labels to entity indices for the different entity types." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# train triples: 4,762,678\n", + "# validation triples: 162,886\n", + "# test triples: 162,870\n" + ] + } + ], + "source": [ + "label_dict = {}\n", + "for l in [\"disease\", \"drug\", \"function\", \"protein\", \"sideeffect\"]:\n", + " # labels for the entities of type l\n", + " # we append the entity type to the label to prevent label collisions across different types\n", + " # notice that some entities, like proteins, have labels that are still numerical\n", + " label_dict[l] = (\n", + " pd.read_csv(\n", + " Path(dataset_directory).joinpath(\n", + " f\"ogbl_biokg/mapping/{l}_entidx2name.csv.gz\"\n", + " )\n", + " ).set_index(\"ent idx\")[\"ent name\"]\n", + " + f\" ({l})\"\n", + " ).values\n", + "\n", + "# labels for relation types\n", + "rel_dict = (\n", + " pd.read_csv(\n", + " Path(dataset_directory).joinpath(f\"ogbl_biokg/mapping/relidx2relname.csv.gz\")\n", + " )\n", + " .set_index(\"rel idx\")[\"rel name\"]\n", + " .values\n", + ")\n", + "\n", + "# collect triples in train, valid, test DataFrames\n", + "# replacing the entity IDs with their original labels.\n", + "df_dict = {}\n", + "for split in {\"test\", \"train\", \"valid\"}:\n", + " triples = []\n", + " data = torch.load(\n", + " Path(dataset_directory).joinpath(f\"ogbl_biokg/split/random/{split}.pt\")\n", + " )\n", + " for h, h_type, t, t_type, r in zip(\n", + " data[\"head\"],\n", + " data[\"head_type\"],\n", + " data[\"tail\"],\n", + " data[\"tail_type\"],\n", + " data[\"relation\"],\n", + " ):\n", + " h_label = label_dict[h_type][h]\n", + " t_label = label_dict[t_type][t]\n", + " r_label = rel_dict[r]\n", + " triples.append((h_label, r_label, t_label))\n", + " df_dict[split] = pd.DataFrame(\n", + " triples, columns=[\"head_label\", \"relation_label\", \"tail_label\"]\n", + " )\n", + "\n", + "print(f\"# train triples: {df_dict['train'].shape[0]:,}\")\n", + "print(f\"# validation triples: {df_dict['valid'].shape[0]:,}\")\n", + "print(f\"# test triples: {df_dict['test'].shape[0]:,}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
head_labelrelation_labeltail_label
0C0038586 (disease)disease-protein1653 (protein)
1C0751849 (disease)disease-protein718 (protein)
2C1320474 (disease)disease-protein8622 (protein)
3C0270844 (disease)disease-protein3569 (protein)
4C4279912 (disease)disease-protein8856 (protein)
\n", + "
" + ], + "text/plain": [ + " head_label relation_label tail_label\n", + "0 C0038586 (disease) disease-protein 1653 (protein)\n", + "1 C0751849 (disease) disease-protein 718 (protein)\n", + "2 C1320474 (disease) disease-protein 8622 (protein)\n", + "3 C0270844 (disease) disease-protein 3569 (protein)\n", + "4 C4279912 (disease) disease-protein 8856 (protein)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_dict[\"train\"].head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We put ourselves in a very generic starting point, where the **edges of the knowledge graph are represented as a list of (head, relation, tail) triples**, with *unique labels* for entities and relations.\n", + "\n", + "In our knowledge graph, moreover, entities are of different types (disease, drug, function, protein and side-effect). This is not always the case, but BESS-KGE can leverage this additional information, for instance by constructing negative samples corrupting entities only with entities of the same type (see [besskge.negative_sampler.TypeBasedNegativeSampler](https://graphcore-research.github.io/bess-kge/API_ref/negative_sampler.html#besskge.negative_sampler.TypeBasedShardedNegativeSampler)). We store this data by creating a mapping from entity labels to entity types." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ent_labelent_type
0C0000737 (disease)disease
1C0000744 (disease)disease
2C0000768 (disease)disease
3C0000771 (disease)disease
4C0000772 (disease)disease
.........
93768C3665444 (sideeffect)sideeffect
93769C3665596 (sideeffect)sideeffect
93770C3665609 (sideeffect)sideeffect
93771C3665624 (sideeffect)sideeffect
93772C3665888 (sideeffect)sideeffect
\n", + "

93773 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " ent_label ent_type\n", + "0 C0000737 (disease) disease\n", + "1 C0000744 (disease) disease\n", + "2 C0000768 (disease) disease\n", + "3 C0000771 (disease) disease\n", + "4 C0000772 (disease) disease\n", + "... ... ...\n", + "93768 C3665444 (sideeffect) sideeffect\n", + "93769 C3665596 (sideeffect) sideeffect\n", + "93770 C3665609 (sideeffect) sideeffect\n", + "93771 C3665624 (sideeffect) sideeffect\n", + "93772 C3665888 (sideeffect) sideeffect\n", + "\n", + "[93773 rows x 2 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "entity_types = {l: t for t in label_dict.keys() for l in label_dict[t]}\n", + "entity_types = pd.DataFrame(\n", + " {\"ent_label\": entity_types.keys(), \"ent_type\": entity_types.values()}\n", + ")\n", + "entity_types" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ent_type\n", + "disease 10687\n", + "drug 10533\n", + "function 45085\n", + "protein 17499\n", + "sideeffect 9969\n", + "Name: ent_type, dtype: int64" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# entity type counts\n", + "entity_types.groupby(\"ent_type\")[\"ent_type\"].count()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The KGDataset class in BESS-KGE\n", + "\n", + "When using BESS-KGE, the knowledge graph data is stored in an instance of the [besskge.dataset.KGDataset](https://graphcore-research.github.io/bess-kge/API_ref/dataset.html#besskge.dataset.KGDataset) class. This class has built-in methods to download and build some commonly-used knowledge graph datasets, or it can be instantiated manually with custom data by specifying all the required attributes.\n", + "\n", + "The `besskge.dataset.KGDataset.from_dataframe` method is perfect to **build a custom dataset starting from labelled triples with minimum effort**. It simply requires a pandas DataFrame containing all labelled triples (or a dictionary of DataFrames, one for each of the dataset splits). If entities are of different types, like for OGBL-BioKG, this can be communicated to `KGDataset` by providing it with a mapping of entity labels to entity types, in the form of a dictionary or a pandas Series, indexed over the entity labels." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ent_label\n", + "C0000737 (disease) disease\n", + "C0000744 (disease) disease\n", + "C0000768 (disease) disease\n", + "C0000771 (disease) disease\n", + "C0000772 (disease) disease\n", + " ... \n", + "C3665444 (sideeffect) sideeffect\n", + "C3665596 (sideeffect) sideeffect\n", + "C3665609 (sideeffect) sideeffect\n", + "C3665624 (sideeffect) sideeffect\n", + "C3665888 (sideeffect) sideeffect\n", + "Name: ent_type, Length: 93773, dtype: object" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "entity_types_series = entity_types.set_index(\"ent_label\")[\"ent_type\"]\n", + "entity_types_series" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To build `KGDataset` we only need to call `KGDataset.from_dataframe`, specifying the names of the columns of the dataframes which contain the entity and relation labels." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "biokg = KGDataset.from_dataframe(\n", + " df_dict,\n", + " head_column=\"head_label\",\n", + " relation_column=\"relation_label\",\n", + " tail_column=\"tail_label\",\n", + " entity_types=entity_types_series,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was easy, wasn't it? Let us have a closer look at the attributes of the `KGDataset` class we just created." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of entities: 93,773\n", + "\n", + "Number of relation types: 51\n", + "\n", + "Number of triples: \n", + " training: 4,762,678 \n", + " validation: 162,886\n", + " test: 162,870\n" + ] + } + ], + "source": [ + "print(f\"Number of entities: {biokg.n_entity:,}\\n\")\n", + "print(f\"Number of relation types: {biokg.n_relation_type}\\n\")\n", + "print(\n", + " f\"Number of triples: \\n training: {biokg.triples['train'].shape[0]:,} \\n validation: {biokg.triples['valid'].shape[0]:,}\"\n", + " f\"\\n test: {biokg.triples['test'].shape[0]:,}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that only the entities that appear as head or tail in at least one of the dataset's triples are counted in `KGDataset.n_entity` (and the same for relations in `KGDataset.n_relation_type`).\n", + "\n", + "If we take a look at the `triples` attribute of `KGDataset`, we see that it is still structured as a dictionary, with the same keys that we used in `df_dict` to identify the different dataset splits." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['valid', 'test', 'train'])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "biokg.triples.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[10120, 0, 79687],\n", + " [10137, 0, 79168],\n", + " [ 5659, 0, 78209],\n", + " ...,\n", + " [73643, 50, 73701],\n", + " [80650, 50, 72104],\n", + " [80643, 50, 76000]], dtype=int32)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "biokg.triples[\"train\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each row of these NumPy arrays corresponds to a (h,r,t) triple in the dataset, but now the **labels for entities and relations have been replaced by numerical IDs**. We can use `KGDataset.entity_dict` and `KGDataset.relation_dict` to recover the mapping from IDs to labels for entities and relation types respectively." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['C0393778 (disease)',\n", + " 'C2677109 (disease)',\n", + " 'C0796093 (disease)',\n", + " 'C2931278 (disease)',\n", + " 'C0149910 (disease)',\n", + " 'C3668942 (disease)',\n", + " 'C4225263 (disease)',\n", + " 'C0393814 (disease)',\n", + " 'C0342883 (disease)',\n", + " 'C4017556 (disease)']" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "biokg.entity_dict[:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "meaning that the entity with ID 0 is \"C0393778 (disease)\", the entity with ID 1 is \"C2677109 (disease)\", etc. (and similarly for `biokg.relation_dict`).\n", + "\n", + "Let's do a quick sanity check." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('C0751495 (disease)', 'disease-protein', '7249 (protein)')" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "part = \"test\"\n", + "triple_number = 1234\n", + "\n", + "head_label = biokg.entity_dict[biokg.triples[part][triple_number, 0]]\n", + "relation_label = biokg.relation_dict[biokg.triples[part][triple_number, 1]]\n", + "tail_label = biokg.entity_dict[biokg.triples[part][triple_number, 2]]\n", + "\n", + "head_label, relation_label, tail_label" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the original dataframes, this should coincide with:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "head_label C0751495 (disease)\n", + "relation_label disease-protein\n", + "tail_label 7249 (protein)\n", + "Name: 1234, dtype: object" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_dict[part].iloc[triple_number][[\"head_label\", \"relation_label\", \"tail_label\"]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It checks out!\n", + "\n", + "It is important to note that, when entities have different types, the numerical entity IDs need to be assigned so that **entities of the same type have contiguous IDs**! This is done automatically when using `KGDataset.from_dataframe`, but it needs to be kept in mind if you are instantiating the `KGDataset` class manually.\n", + "\n", + "Since entity IDs are now clustered by type, we only need to know the ID ranges corresponding to the different types, which are stored in `KGDataset.type_offsets`:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'disease': 0,\n", + " 'drug': 10687,\n", + " 'function': 21220,\n", + " 'protein': 66305,\n", + " 'sideeffect': 83804}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "biokg.type_offsets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This means that entities with ID from 0 to 10686 are of type 'disease', from 10687 to 21219 are of type 'drug' and so on.\n", + "\n", + "The type IDs (assigned following the order of the keys in `KGDataset.type_offsets`) for heads and tails of all triples in the dataset can be immediately recovered using `KGDataset.ht_types`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['valid', 'test', 'train'])" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "biokg.ht_types.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4762678, 2) (162886, 2) (162870, 2)\n" + ] + } + ], + "source": [ + "print(\n", + " biokg.ht_types[\"train\"].shape,\n", + " biokg.ht_types[\"valid\"].shape,\n", + " biokg.ht_types[\"test\"].shape\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each row of these arrays stores the ID of the type of the head entity and tail entity of the corresponding triple, for example:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 3])" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "part = \"valid\"\n", + "triple_number = 0\n", + "\n", + "biokg.ht_types[part][triple_number]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This means that the first validation triple has a head entity of type 'disease' (the 0-th key of `biokg.type_offsets`) and a tail entity of type 'protein' (the key of `biokg.type_offsets` with index 3). Indeed, we can check:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('disease', 'protein')" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type_head = entity_types_series[df_dict[part].iloc[triple_number][\"head_label\"]]\n", + "type_tail = entity_types_series[df_dict[part].iloc[triple_number][\"tail_label\"]]\n", + "\n", + "type_head, type_tail" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Random dataset split\n", + "\n", + "What if no custom train/validation/test split is provided? `KGDataset.from_dataframe` can perform a random split, with the desired ratios between the three parts. This happens whenever it is provided with a single pandas DataFrame, instead of a dictionary of DataFrames as before." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of triples: 5,088,434\n" + ] + } + ], + "source": [ + "# Merge all triples in a single DataFrame\n", + "df_all_triples = pd.concat(\n", + " [df_dict[\"train\"], df_dict[\"valid\"], df_dict[\"test\"]], axis=0\n", + ")\n", + "\n", + "print(f\"Total number of triples: {df_all_triples.shape[0]:,}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of entities: 93,773\n", + "\n", + "Number of relation types: 51\n", + "\n", + "Number of triples: \n", + " training: 4,070,747 \n", + " validation: 508,843\n", + " test: 508,844\n" + ] + } + ], + "source": [ + "# 80/10/10 train/valid/test split\n", + "split_ratios = (0.8, 0.1, 0.1)\n", + "\n", + "biokg_random = KGDataset.from_dataframe(\n", + " df_all_triples,\n", + " head_column=\"head_label\",\n", + " relation_column=\"relation_label\",\n", + " tail_column=\"tail_label\",\n", + " entity_types=entity_types_series,\n", + " split=split_ratios,\n", + ")\n", + "\n", + "print(f\"Number of entities: {biokg_random.n_entity:,}\\n\")\n", + "print(f\"Number of relation types: {biokg_random.n_relation_type}\\n\")\n", + "print(\n", + " f\"Number of triples: \\n training: {biokg_random.triples['train'].shape[0]:,} \\n validation: {biokg_random.triples['valid'].shape[0]:,}\"\n", + " f\"\\n test: {biokg_random.triples['test'].shape[0]:,}\"\n", + ")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusions and next steps\n", + "\n", + "The `KGDataset` class has a few additional attributes, which can be defined when instantiating the class manually. For instance, for each triple it allows you to specify a set of negative heads and tails that should be used to corrupt that triple. This is useful when you want to find the best completion for a (h,r,?)/(?,r,t) query only among a specific set of candidate nodes, or you have already identified good negative samples that you want to use during training.\n", + "\n", + "For more information on the `KGDataset` class, have a look at the [BESS-KGE documentation](https://graphcore-research.github.io/bess-kge/API_ref/dataset.html#besskge.dataset.KGDataset).\n", + "\n", + "Once you have built your dataset as a `KGDataset` class, you are ready to use BESS to train your preferred KGE model and perform inference with it! To learn how, we suggest starting from the introductory [KGE Training and Inference on OGBL-BioKG](1_biokg_training_inference.ipynb) notebook." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv_3.2", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/1_biokg_training_inference.ipynb b/notebooks/1_biokg_training_inference.ipynb index 1d1b59f..3e7a78f 100644 --- a/notebooks/1_biokg_training_inference.ipynb +++ b/notebooks/1_biokg_training_inference.ipynb @@ -112,7 +112,7 @@ "source": [ "## Sharding entities and triples\n", "\n", - "The OGBL-BioKG dataset can be downloaded and preprocessed with the built-in `KGDataset` method, `build_biokg`. `KGDataset` is the standard class which holds data from the knowledge graph dataset, such as head-relation-tail triples (with entities and relation types suitably converted to their integer IDs), triple-specific data (for example negative heads/tails to be used to corrupt the triple), ID -> label lists for entities and relation types, and so on." + "The OGBL-BioKG dataset can be downloaded and preprocessed with the built-in `KGDataset` method, `build_ogbl_biokg`. `KGDataset` is the standard class which holds data from the knowledge graph dataset, such as head-relation-tail triples (with entities and relation types suitably converted to their integer IDs), triple-specific data (for example negative heads/tails to be used to corrupt the triple), ID -> label lists for entities and relation types, and so on." ] }, { @@ -137,12 +137,16 @@ } ], "source": [ - "biokg = KGDataset.build_biokg(root=pathlib.Path(dataset_directory))\n", + "biokg = KGDataset.build_ogbl_biokg(root=pathlib.Path(dataset_directory))\n", "\n", "print(f\"Number of entities: {biokg.n_entity:,}\\n\")\n", "print(f\"Number of relation types: {biokg.n_relation_type}\\n\")\n", - "print(f\"Number of triples: \\n training: {biokg.triples['train'].shape[0]:,} \\n validation/test: {biokg.triples['valid'].shape[0]:,}\\n\")\n", - "print(f\"Number of negative heads/tails for validation/test triples: {biokg.neg_heads['valid'].shape[-1]}\")" + "print(\n", + " f\"Number of triples: \\n training: {biokg.triples['train'].shape[0]:,} \\n validation/test: {biokg.triples['valid'].shape[0]:,}\\n\"\n", + ")\n", + "print(\n", + " f\"Number of negative heads/tails for validation/test triples: {biokg.neg_heads['valid'].shape[-1]}\"\n", + ")" ] }, { @@ -227,7 +231,12 @@ "seed = 1234\n", "n_shard = 4\n", "\n", - "sharding = Sharding.create(n_entity=biokg.n_entity, n_shard=n_shard, seed=seed, type_offsets=np.fromiter(biokg.type_offsets.values(), dtype=np.int32))\n", + "sharding = Sharding.create(\n", + " n_entity=biokg.n_entity,\n", + " n_shard=n_shard,\n", + " seed=seed,\n", + " type_offsets=np.fromiter(biokg.type_offsets.values(), dtype=np.int32),\n", + ")\n", "\n", "print(f\"Number of shards: {sharding.n_shard}\\n\")\n", "\n", @@ -235,8 +244,11 @@ "\n", "print(f\"Global entity IDs on {n_shard} shards:\\n {sharding.shard_and_idx_to_entity}\\n\")\n", "\n", - "# If the number of entities is not divisible by n_shard, some shards will have one trailing padding entity (ID >= n_entity)\n", - "print(f\"Number of actual (=non-padding) entities per shard:\\n {sharding.shard_counts}\\n\")\n", + "# If the number of entities is not divisible by n_shard,\n", + "# some shards will have one trailing padding entity (ID >= n_entity)\n", + "print(\n", + " f\"Number of actual (=non-padding) entities per shard:\\n {sharding.shard_counts}\\n\"\n", + ")\n", "\n", "# Entities of the same type maintain contiguous local IDs in each shard\n", "print(f\"Type offsets per shard: \\n\", sharding.entity_type_offsets)" @@ -280,7 +292,9 @@ } ], "source": [ - "train_triples = PartitionedTripleSet.create_from_dataset(dataset=biokg, part=\"train\", sharding=sharding, partition_mode=\"ht_shardpair\")\n", + "train_triples = PartitionedTripleSet.create_from_dataset(\n", + " dataset=biokg, part=\"train\", sharding=sharding, partition_mode=\"ht_shardpair\"\n", + ")\n", "\n", "# train_triples.triple_counts[i,j] is the number of triples with head entity in shard i and tail entity in shard j\n", "print(f\"Number of triples per (h,t) shard-pair:\\n {train_triples.triple_counts}\")" @@ -316,8 +330,8 @@ "# Put original triples in the same order as train_triples.triples\n", "triple_sorted = biokg.triples[\"train\"][train_triples.triple_sort_idx]\n", "# Pass from global IDs to local IDs with sharding.entity_to_idx\n", - "triple_sorted[:,0] = sharding.entity_to_idx[triple_sorted[:,0]]\n", - "triple_sorted[:,2] = sharding.entity_to_idx[triple_sorted[:,2]]\n", + "triple_sorted[:, 0] = sharding.entity_to_idx[triple_sorted[:, 0]]\n", + "triple_sorted[:, 2] = sharding.entity_to_idx[triple_sorted[:, 2]]\n", "# Compare with the content of train_triples.triples\n", "np.all(triple_sorted == train_triples.triples)" ] @@ -356,8 +370,14 @@ "metadata": {}, "outputs": [], "source": [ - "neg_sampler = RandomShardedNegativeSampler(n_negative=1, sharding=sharding, seed=seed, corruption_scheme=\"ht\",\n", - " local_sampling=False, flat_negative_format=False)" + "neg_sampler = RandomShardedNegativeSampler(\n", + " n_negative=1,\n", + " sharding=sharding,\n", + " seed=seed,\n", + " corruption_scheme=\"ht\",\n", + " local_sampling=False,\n", + " flat_negative_format=False,\n", + ")" ] }, { @@ -394,15 +414,20 @@ "# Micro-batch size, which means the number of positive triples processed on each device at each step\n", "shard_bs = 240\n", "\n", - "batch_sampler = RigidShardedBatchSampler(partitioned_triple_set=train_triples, negative_sampler=neg_sampler,\n", - " shard_bs=shard_bs, batches_per_step=device_iterations*accum_factor, seed=seed)\n", + "batch_sampler = RigidShardedBatchSampler(\n", + " partitioned_triple_set=train_triples,\n", + " negative_sampler=neg_sampler,\n", + " shard_bs=shard_bs,\n", + " batches_per_step=device_iterations * accum_factor,\n", + " seed=seed,\n", + ")\n", "\n", "\n", "print(f\"# triples per shard-pair per step: {batch_sampler.positive_per_partition} \\n\")\n", "\n", "# Example batch\n", "idx_sampler = iter(batch_sampler.get_dataloader_sampler(shuffle=True))\n", - "for k,v in batch_sampler[next(idx_sampler)].items():\n", + "for k, v in batch_sampler[next(idx_sampler)].items():\n", " print(f\"{k:<12} {str(v.shape):<30} {v.dtype};\")" ] }, @@ -456,7 +481,9 @@ "options._popart.setPatterns(dict(RemoveAllReducePattern=True))\n", "\n", "# Construction similar to PyTorch dataloader\n", - "train_dl = batch_sampler.get_dataloader(options=options, shuffle=True, num_workers=5, persistent_workers=True)" + "train_dl = batch_sampler.get_dataloader(\n", + " options=options, shuffle=True, num_workers=5, persistent_workers=True\n", + ")" ] }, { @@ -486,17 +513,23 @@ "# Loss function\n", "logsigmoid_loss_fn = LogSigmoidLoss(margin=12.0, negative_adversarial_sampling=True)\n", "# KGE model\n", - "rotate_score_fn = RotatE(negative_sample_sharing=True, scoring_norm=1, sharding=sharding,\n", - " n_relation_type=biokg.n_relation_type, embedding_size=64)\n", + "rotate_score_fn = RotatE(\n", + " negative_sample_sharing=True,\n", + " scoring_norm=1,\n", + " sharding=sharding,\n", + " n_relation_type=biokg.n_relation_type,\n", + " embedding_size=64,\n", + ")\n", "# BESS wrapper\n", - "model = EmbeddingMovingBessKGE(negative_sampler=neg_sampler, score_fn=rotate_score_fn,\n", - " loss_fn=logsigmoid_loss_fn)\n", + "model = EmbeddingMovingBessKGE(\n", + " negative_sampler=neg_sampler, score_fn=rotate_score_fn, loss_fn=logsigmoid_loss_fn\n", + ")\n", "\n", "# Optimizer\n", "opt = poptorch.optim.AdamW(\n", - " model.parameters(),\n", - " lr=0.001,\n", - " )\n", + " model.parameters(),\n", + " lr=0.001,\n", + ")\n", "\n", "# PopTorch wrapper\n", "poptorch_model = poptorch.trainingModel(model, options=options, optimizer=opt)\n", @@ -504,10 +537,10 @@ "# The variable entity_embedding needs to hold different values on each replica,\n", "# corresponding to the distinct shards of the entity embedding table\n", "poptorch_model.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "# Compile model\n", "batch = next(iter(train_dl))\n", @@ -605,11 +638,20 @@ " cumulative_triples += triple_mask.numel()\n", " res = poptorch_model(**{k: v.flatten(end_dim=1) for k, v in batch.items()})\n", " # res[\"loss\"] contains the summed loss of elements in the last batch, for each IPU\n", - " ep_log.append(dict(loss=float(torch.sum(res[\"loss\"])) / triple_mask[-1].numel(), step_time=(time.time()-step_start_time)))\n", - " ep_loss = [v['loss'] for v in ep_log]\n", - " training_loss.extend([v['loss'] for v in ep_log])\n", - " print(f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\")\n", - " print(f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\")\n", + " ep_log.append(\n", + " dict(\n", + " loss=float(torch.sum(res[\"loss\"])) / triple_mask[-1].numel(),\n", + " step_time=(time.time() - step_start_time),\n", + " )\n", + " )\n", + " ep_loss = [v[\"loss\"] for v in ep_log]\n", + " training_loss.extend([v[\"loss\"] for v in ep_log])\n", + " print(\n", + " f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\"\n", + " )\n", + " print(\n", + " f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\"\n", + " )\n", "\n", "# Plot loss as a function of the number of positive triples processed\n", "total_triples = np.cumsum(n_epochs * len(train_dl) * [triple_mask.numel()])\n", @@ -656,15 +698,28 @@ } ], "source": [ - "valid_triples = PartitionedTripleSet.create_from_dataset(dataset=biokg, part=\"valid\", sharding=sharding, partition_mode=\"ht_shardpair\")\n", - "ns_valid = TripleBasedShardedNegativeSampler(negative_heads=valid_triples.neg_heads, negative_tails=valid_triples.neg_tails,\n", - " sharding=sharding, corruption_scheme=\"ht\", seed=seed)\n", - "bs_valid = RigidShardedBatchSampler(partitioned_triple_set=valid_triples, negative_sampler=ns_valid, shard_bs=shard_bs, batches_per_step=10,\n", - " seed=seed, duplicate_batch=True)\n", + "valid_triples = PartitionedTripleSet.create_from_dataset(\n", + " dataset=biokg, part=\"valid\", sharding=sharding, partition_mode=\"ht_shardpair\"\n", + ")\n", + "ns_valid = TripleBasedShardedNegativeSampler(\n", + " negative_heads=valid_triples.neg_heads,\n", + " negative_tails=valid_triples.neg_tails,\n", + " sharding=sharding,\n", + " corruption_scheme=\"ht\",\n", + " seed=seed,\n", + ")\n", + "bs_valid = RigidShardedBatchSampler(\n", + " partitioned_triple_set=valid_triples,\n", + " negative_sampler=ns_valid,\n", + " shard_bs=shard_bs,\n", + " batches_per_step=10,\n", + " seed=seed,\n", + " duplicate_batch=True,\n", + ")\n", "\n", "# Example batch\n", "idx_sampler = iter(bs_valid.get_dataloader_sampler(shuffle=False))\n", - "for k,v in bs_valid[next(idx_sampler)].items():\n", + "for k, v in bs_valid[next(idx_sampler)].items():\n", " print(f\"{k:<15} {str(v.shape):<35} {v.dtype};\")" ] }, @@ -710,15 +765,17 @@ "# With reduction=\"sum\" the returned res[\"metrics\"] has shape (batches_per_step * n_shard, n_metrics)\n", "evaluator = Evaluation([\"mrr\", \"hits@1\", \"hits@5\", \"hits@10\"], reduction=\"sum\")\n", "# BESS wrapper\n", - "model_inf = ScoreMovingBessKGE(negative_sampler=ns_valid, score_fn=rotate_score_fn, evaluation=evaluator)\n", + "model_inf = ScoreMovingBessKGE(\n", + " negative_sampler=ns_valid, score_fn=rotate_score_fn, evaluation=evaluator\n", + ")\n", "\n", "# PopTorch wrapper\n", "poptorch_model_inf = poptorch.inferenceModel(model_inf, options=val_options)\n", "poptorch_model_inf.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "# Compile model\n", "batch = next(iter(valid_dl))\n", @@ -750,13 +807,18 @@ "n_val_queries = 0\n", "for batch_val in valid_dl:\n", " res = poptorch_model_inf(**{k: v.flatten(end_dim=1) for k, v in batch_val.items()})\n", - " \n", + "\n", " n_val_queries += batch_val[\"triple_mask\"].sum()\n", " # By transposing res[\"metrics\"] we separate the outputs for the different metrics\n", - " val_log.append({k: v.sum() for k, v in zip(\n", - " evaluator.metrics.keys(),\n", - " res[\"metrics\"].T,\n", - " )})\n", + " val_log.append(\n", + " {\n", + " k: v.sum()\n", + " for k, v in zip(\n", + " evaluator.metrics.keys(),\n", + " res[\"metrics\"].T,\n", + " )\n", + " }\n", + " )\n", "\n", "for metric in val_log[0].keys():\n", " reduced_metric = sum([l[metric] for l in val_log]) / n_val_queries\n", @@ -835,16 +897,23 @@ "source": [ "n_shard = 1\n", "\n", - "sharding = Sharding.create(n_entity=biokg.n_entity, n_shard=n_shard, seed=seed, type_offsets=np.fromiter(biokg.type_offsets.values(), dtype=np.int32))\n", + "sharding = Sharding.create(\n", + " n_entity=biokg.n_entity,\n", + " n_shard=n_shard,\n", + " seed=seed,\n", + " type_offsets=np.fromiter(biokg.type_offsets.values(), dtype=np.int32),\n", + ")\n", "\n", "print(f\"Number of shards: {sharding.n_shard}\\n\")\n", "\n", "# All entities in the KG are now on a single shard\n", "print(f\"Number of entities in each shard: {sharding.max_entity_per_shard}\\n\")\n", "\n", - "train_triples = PartitionedTripleSet.create_from_dataset(dataset=biokg, part=\"train\", sharding=sharding, partition_mode=\"ht_shardpair\")\n", + "train_triples = PartitionedTripleSet.create_from_dataset(\n", + " dataset=biokg, part=\"train\", sharding=sharding, partition_mode=\"ht_shardpair\"\n", + ")\n", "\n", - "# There is now a single (h,t) shard-pair, containing all training triples \n", + "# There is now a single (h,t) shard-pair, containing all training triples\n", "print(f\"Number of triples per (h,t) shard-pair:\\n {train_triples.triple_counts}\")" ] }, @@ -862,9 +931,16 @@ "metadata": {}, "outputs": [], "source": [ - "# Reducing the number of shards by a factor of 4, the number of negatives per triple per shard (i.e. n_negative) needs to increase by the same factor\n", - "neg_sampler = RandomShardedNegativeSampler(n_negative=4, sharding=sharding, seed=seed, corruption_scheme=\"ht\",\n", - " local_sampling=False, flat_negative_format=False)" + "# When reducing the number of shards by a factor of 4,\n", + "# the number of negatives per triple per shard (i.e. n_negative) needs to increase by the same factor\n", + "neg_sampler = RandomShardedNegativeSampler(\n", + " n_negative=4,\n", + " sharding=sharding,\n", + " seed=seed,\n", + " corruption_scheme=\"ht\",\n", + " local_sampling=False,\n", + " flat_negative_format=False,\n", + ")" ] }, { @@ -899,15 +975,20 @@ "accum_factor = 24\n", "shard_bs = 240\n", "\n", - "batch_sampler = RigidShardedBatchSampler(partitioned_triple_set=train_triples, negative_sampler=neg_sampler,\n", - " shard_bs=shard_bs, batches_per_step=device_iterations*accum_factor, seed=seed)\n", + "batch_sampler = RigidShardedBatchSampler(\n", + " partitioned_triple_set=train_triples,\n", + " negative_sampler=neg_sampler,\n", + " shard_bs=shard_bs,\n", + " batches_per_step=device_iterations * accum_factor,\n", + " seed=seed,\n", + ")\n", "\n", "\n", "print(f\"# triples per shard-pair per step: {batch_sampler.positive_per_partition} \\n\")\n", "\n", "# Example batch\n", "idx_sampler = iter(batch_sampler.get_dataloader_sampler(shuffle=True))\n", - "for k,v in batch_sampler[next(idx_sampler)].items():\n", + "for k, v in batch_sampler[next(idx_sampler)].items():\n", " print(f\"{k:<12} {str(v.shape):<30} {v.dtype};\")" ] }, @@ -937,26 +1018,34 @@ "options.deviceIterations(device_iterations)\n", "options.Training.gradientAccumulation(accum_factor)\n", "\n", - "train_dl = batch_sampler.get_dataloader(options=options, shuffle=True, num_workers=5, persistent_workers=True)\n", + "train_dl = batch_sampler.get_dataloader(\n", + " options=options, shuffle=True, num_workers=5, persistent_workers=True\n", + ")\n", "\n", "logsigmoid_loss_fn = LogSigmoidLoss(margin=12.0, negative_adversarial_sampling=True)\n", - "rotate_score_fn = RotatE(negative_sample_sharing=True, scoring_norm=1, sharding=sharding,\n", - " n_relation_type=biokg.n_relation_type, embedding_size=64)\n", + "rotate_score_fn = RotatE(\n", + " negative_sample_sharing=True,\n", + " scoring_norm=1,\n", + " sharding=sharding,\n", + " n_relation_type=biokg.n_relation_type,\n", + " embedding_size=64,\n", + ")\n", "\n", - "model = EmbeddingMovingBessKGE(negative_sampler=neg_sampler, score_fn=rotate_score_fn,\n", - " loss_fn=logsigmoid_loss_fn)\n", + "model = EmbeddingMovingBessKGE(\n", + " negative_sampler=neg_sampler, score_fn=rotate_score_fn, loss_fn=logsigmoid_loss_fn\n", + ")\n", "\n", "opt = poptorch.optim.AdamW(\n", - " model.parameters(),\n", - " lr=0.001,\n", - " )\n", + " model.parameters(),\n", + " lr=0.001,\n", + ")\n", "\n", "poptorch_model = poptorch.trainingModel(model, options=options, optimizer=opt)\n", "poptorch_model.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "\n", "# Compile model\n", @@ -1011,11 +1100,20 @@ " triple_mask = batch.pop(\"triple_mask\")\n", " cumulative_triples += triple_mask.numel()\n", " res = poptorch_model(**{k: v.flatten(end_dim=1) for k, v in batch.items()})\n", - " ep_log.append(dict(loss=float(torch.sum(res[\"loss\"])) / triple_mask[-1].numel(), step_time=(time.time()-step_start_time)))\n", - " ep_loss = [v['loss'] for v in ep_log]\n", - " training_loss.extend([v['loss'] for v in ep_log])\n", - " print(f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\")\n", - " print(f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\")\n", + " ep_log.append(\n", + " dict(\n", + " loss=float(torch.sum(res[\"loss\"])) / triple_mask[-1].numel(),\n", + " step_time=(time.time() - step_start_time),\n", + " )\n", + " )\n", + " ep_loss = [v[\"loss\"] for v in ep_log]\n", + " training_loss.extend([v[\"loss\"] for v in ep_log])\n", + " print(\n", + " f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\"\n", + " )\n", + " print(\n", + " f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\"\n", + " )\n", "\n", "poptorch_model.detachFromDevice()\n", "del train_dl" @@ -1037,7 +1135,7 @@ "## Conclusions and next steps\n", "\n", "To recap, these are the basic steps to run distributed training/inference with BESS-KGE:\n", - "* wrap your knowledge graph dataset with `besskge.dataset.KGDataset`;\n", + "* wrap your knowledge graph dataset with `besskge.dataset.KGDataset` (see also [Using BESS-KGE with your own data](0_custom_KG_dataset.ipynb));\n", "* shard entities in the graph based on the number of IPUs you want to use, by using `besskge.sharding.Sharding`, and partition triples accordingly with `besskge.sharding.PartitionedTripleSet`;\n", "* select a negative sampler from `besskge.negative_sampler` to sample the entities used to corrupt positive triples;\n", "* use a batch sampler from `besskge.batch_sampler` to create the batch dataloader; \n", diff --git a/notebooks/2_yago_topk_prediction.ipynb b/notebooks/2_yago_topk_prediction.ipynb index e1b4d62..ff9e0ef 100644 --- a/notebooks/2_yago_topk_prediction.ipynb +++ b/notebooks/2_yago_topk_prediction.ipynb @@ -153,12 +153,16 @@ "\n", "print(f\"Number of entities: {yago.n_entity:,}\\n\")\n", "print(f\"Number of relation types: {yago.n_relation_type}\\n\")\n", - "print(f\"Number of triples: \\n training: {yago.triples['train'].shape[0]:,} \\n validation/test: {yago.triples['validation'].shape[0]:,}\\n\")\n", + "print(\n", + " f\"Number of triples: \\n training: {yago.triples['train'].shape[0]:,} \\n validation/test: {yago.triples['valid'].shape[0]:,}\\n\"\n", + ")\n", "\n", "# Print example triple retrieving labels from yago.entity_dict and yago.relation_dict\n", "ex_triple_id = 2500\n", "ex_triple = yago.triples[\"train\"][ex_triple_id]\n", - "print(f'Example triple: {yago.entity_dict[ex_triple[0]], yago.relation_dict[ex_triple[1]], yago.entity_dict[ex_triple[2]]}')" + "print(\n", + " f\"Example triple: {yago.entity_dict[ex_triple[0]], yago.relation_dict[ex_triple[1]], yago.entity_dict[ex_triple[2]]}\"\n", + ")" ] }, { @@ -205,7 +209,9 @@ "\n", "# The global entity IDs can be recovered, as a function of the shard ID and the local ID on the shard, by\n", "print(\"\\nReconstructed global entity IDs:\")\n", - "print(sharding.shard_and_idx_to_entity[sharding.entity_to_shard, sharding.entity_to_idx])\n", + "print(\n", + " sharding.shard_and_idx_to_entity[sharding.entity_to_shard, sharding.entity_to_idx]\n", + ")\n", "\n", "train_triples = PartitionedTripleSet.create_from_dataset(yago, \"train\", sharding)\n", "\n", @@ -237,10 +243,21 @@ "device_iterations = 20\n", "accum_factor = 2\n", "shard_bs = 720\n", - "neg_sampler = RandomShardedNegativeSampler(n_negative=1, sharding=sharding, seed=seed, corruption_scheme=\"ht\",\n", - " local_sampling=False, flat_negative_format=False)\n", - "bs = RigidShardedBatchSampler(partitioned_triple_set=train_triples, negative_sampler=neg_sampler, shard_bs=shard_bs,\n", - " batches_per_step=device_iterations*accum_factor, seed=seed)" + "neg_sampler = RandomShardedNegativeSampler(\n", + " n_negative=1,\n", + " sharding=sharding,\n", + " seed=seed,\n", + " corruption_scheme=\"ht\",\n", + " local_sampling=False,\n", + " flat_negative_format=False,\n", + ")\n", + "bs = RigidShardedBatchSampler(\n", + " partitioned_triple_set=train_triples,\n", + " negative_sampler=neg_sampler,\n", + " shard_bs=shard_bs,\n", + " batches_per_step=device_iterations * accum_factor,\n", + " seed=seed,\n", + ")" ] }, { @@ -268,11 +285,13 @@ "options._popart.setPatterns(dict(RemoveAllReducePattern=True))\n", "\n", "# Construct the dataloader with the dedicated utility function\n", - "train_dl = bs.get_dataloader(options=options, shuffle=True, num_workers=5, persistent_workers=True)\n", + "train_dl = bs.get_dataloader(\n", + " options=options, shuffle=True, num_workers=5, persistent_workers=True\n", + ")\n", "\n", "# Example batch\n", "batch = next(iter(train_dl))\n", - "for k,v in batch.items():\n", + "for k, v in batch.items():\n", " print(f\"{k:<12} {str(v.shape):<30}\")" ] }, @@ -301,9 +320,15 @@ ], "source": [ "loss_fn = LogSigmoidLoss(margin=12.0, negative_adversarial_sampling=True)\n", - "complex_score_fn = ComplEx(negative_sample_sharing=True, sharding=sharding, n_relation_type=yago.n_relation_type, embedding_size=128)\n", - "model = EmbeddingMovingBessKGE(negative_sampler=neg_sampler, score_fn=complex_score_fn,\n", - " loss_fn=loss_fn)\n", + "complex_score_fn = ComplEx(\n", + " negative_sample_sharing=True,\n", + " sharding=sharding,\n", + " n_relation_type=yago.n_relation_type,\n", + " embedding_size=128,\n", + ")\n", + "model = EmbeddingMovingBessKGE(\n", + " negative_sampler=neg_sampler, score_fn=complex_score_fn, loss_fn=loss_fn\n", + ")\n", "\n", "print(f\"# model parameters: {model.n_embedding_parameters:,}\")" ] @@ -326,19 +351,35 @@ "source": [ "def evaluate_mrr_cpu(triples, evaluation):\n", " # Unshard entity embedding table\n", - " ent_table = complex_score_fn.entity_embedding.detach()[sharding.entity_to_shard, sharding.entity_to_idx]\n", + " ent_table = complex_score_fn.entity_embedding.detach()[\n", + " sharding.entity_to_shard, sharding.entity_to_idx\n", + " ]\n", "\n", " # Score query (h,r,?) against all entities in the knowledge graph and select top-10 scores\n", - " scores = complex_score_fn.score_tails(ent_table[triples[:,0]], torch.from_numpy(triples[:,1]), ent_table.unsqueeze(0))\n", + " scores = complex_score_fn.score_tails(\n", + " ent_table[triples[:, 0]],\n", + " torch.from_numpy(triples[:, 1]),\n", + " ent_table.unsqueeze(0),\n", + " )\n", " top_k = torch.topk(scores, dim=-1, k=10)\n", "\n", " # Use evaluation.ranks_from_indices to rank the ground truth, if present, among the predictions\n", - " ranks = evaluation.ranks_from_indices(torch.from_numpy(triples[:,2]), top_k.indices.squeeze())\n", - " return {k: v / triples.shape[0] for k, v in evaluation.dict_metrics_from_ranks(ranks).items()}\n", + " ranks = evaluation.ranks_from_indices(\n", + " torch.from_numpy(triples[:, 2]), top_k.indices.squeeze()\n", + " )\n", + " return {\n", + " k: v / triples.shape[0]\n", + " for k, v in evaluation.dict_metrics_from_ranks(ranks).items()\n", + " }\n", + "\n", "\n", "# Sample validation queries\n", "n_val_triples = 500\n", - "val_triple_subset = yago.triples[\"validation\"][np.random.default_rng(seed=1000).choice(yago.triples[\"validation\"].shape[0], n_val_triples)]\n", + "val_triple_subset = yago.triples[\"valid\"][\n", + " np.random.default_rng(seed=1000).choice(\n", + " yago.triples[\"valid\"].shape[0], n_val_triples\n", + " )\n", + "]\n", "evaluation = Evaluation([\"mrr\"], worst_rank_infty=True, reduction=\"sum\")" ] }, @@ -357,19 +398,19 @@ ], "source": [ "opt = poptorch.optim.AdamW(\n", - " model.parameters(),\n", - " lr=0.0016,\n", - " )\n", + " model.parameters(),\n", + " lr=0.0016,\n", + ")\n", "\n", "poptorch_model = poptorch.trainingModel(model, options=options, optimizer=opt)\n", "\n", "# The variable entity_embedding needs to hold different values on each replica,\n", "# corresponding to the shards of the entity embedding table\n", "poptorch_model.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "# Graph compilation\n", "_ = batch.pop(\"triple_mask\")\n", @@ -471,11 +512,20 @@ " triple_mask = batch.pop(\"triple_mask\")\n", " cumulative_triples += triple_mask.numel()\n", " res = poptorch_model(**{k: v.flatten(end_dim=1) for k, v in batch.items()})\n", - " ep_log.append(dict(loss=float(torch.sum(res[\"loss\"])) / triple_mask[-1].numel(), step_time=(time.time()-step_start_time)))\n", - " ep_loss = [v['loss'] for v in ep_log]\n", - " training_loss.extend([v['loss'] for v in ep_log])\n", - " print(f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\")\n", - " print(f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\")\n", + " ep_log.append(\n", + " dict(\n", + " loss=float(torch.sum(res[\"loss\"])) / triple_mask[-1].numel(),\n", + " step_time=(time.time() - step_start_time),\n", + " )\n", + " )\n", + " ep_loss = [v[\"loss\"] for v in ep_log]\n", + " training_loss.extend([v[\"loss\"] for v in ep_log])\n", + " print(\n", + " f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\"\n", + " )\n", + " print(\n", + " f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\"\n", + " )\n", " if ep % val_ep_interval == 0:\n", " ep_mrr = evaluate_mrr_cpu(val_triple_subset, evaluation)[\"mrr\"]\n", " val_mrr.append(ep_mrr)\n", @@ -487,9 +537,14 @@ "# Plot loss and sample MRR as a function of the number of positive triples processed\n", "total_triples = np.cumsum(n_epochs * len(train_dl) * [triple_mask.numel()])\n", "ax0, ax1 = plt.gca(), plt.twinx()\n", - "line0, = ax0.plot(total_triples, training_loss)\n", - "line1, = ax1.plot(np.concatenate([total_triples[::val_ep_interval * len(train_dl)], total_triples[-1:]]),\n", - " val_mrr, color=\"r\")\n", + "(line0,) = ax0.plot(total_triples, training_loss)\n", + "(line1,) = ax1.plot(\n", + " np.concatenate(\n", + " [total_triples[:: val_ep_interval * len(train_dl)], total_triples[-1:]]\n", + " ),\n", + " val_mrr,\n", + " color=\"r\",\n", + ")\n", "ax0.set_xlabel(\"Positive triples\")\n", "ax0.set_ylabel(\"Loss\")\n", "ax1.set_ylabel(\"Sample MRR\")\n", @@ -539,10 +594,19 @@ "device_iterations = 1\n", "shard_bs = 1440\n", "\n", - "validation_triples = PartitionedTripleSet.create_from_dataset(yago, \"validation\", sharding, partition_mode=\"h_shard\")\n", + "validation_triples = PartitionedTripleSet.create_from_dataset(\n", + " yago, \"valid\", sharding, partition_mode=\"h_shard\"\n", + ")\n", "candidate_sampler = PlaceholderNegativeSampler(corruption_scheme=\"t\", seed=seed)\n", - "bs_valid = RigidShardedBatchSampler(partitioned_triple_set=validation_triples, negative_sampler=candidate_sampler, shard_bs=shard_bs, batches_per_step=device_iterations,\n", - " seed=seed, duplicate_batch=False, return_triple_idx=True)\n", + "bs_valid = RigidShardedBatchSampler(\n", + " partitioned_triple_set=validation_triples,\n", + " negative_sampler=candidate_sampler,\n", + " shard_bs=shard_bs,\n", + " batches_per_step=device_iterations,\n", + " seed=seed,\n", + " duplicate_batch=False,\n", + " return_triple_idx=True,\n", + ")\n", "\n", "print(\"Number of triples per h_shard:\")\n", "print(validation_triples.triple_counts)" @@ -571,11 +635,13 @@ "val_options.deviceIterations(bs_valid.batches_per_step)\n", "val_options.outputMode(poptorch.OutputMode.All)\n", "\n", - "valid_dl = bs_valid.get_dataloader(options=val_options, shuffle=False, num_workers=5, persistent_workers=True)\n", + "valid_dl = bs_valid.get_dataloader(\n", + " options=val_options, shuffle=False, num_workers=5, persistent_workers=True\n", + ")\n", "\n", "# Example batch\n", "batch = next(iter(valid_dl))\n", - "for k,v in batch.items():\n", + "for k, v in batch.items():\n", " print(f\"{k:<12} {str(v.shape):<30}\")" ] }, @@ -607,9 +673,9 @@ ], "source": [ "# Put original validation triple in the same order as validation_triples.triples\n", - "triple_sorted = yago.triples[\"validation\"][validation_triples.triple_sort_idx]\n", + "triple_sorted = yago.triples[\"valid\"][validation_triples.triple_sort_idx]\n", "# Pass from global IDs to local IDs just for the heads\n", - "triple_sorted[:,0] = sharding.entity_to_idx[triple_sorted[:,0]]\n", + "triple_sorted[:, 0] = sharding.entity_to_idx[triple_sorted[:, 0]]\n", "# Compare with validation_triples.triples\n", "np.all(triple_sorted == validation_triples.triples)" ] @@ -639,16 +705,24 @@ } ], "source": [ - "evaluation = Evaluation([\"mrr\", \"hits@3\", \"hits@10\"], worst_rank_infty=True, reduction=\"sum\")\n", - "inf_model = TopKQueryBessKGE(k=10, candidate_sampler=candidate_sampler, score_fn=complex_score_fn, evaluation=evaluation, window_size=500)\n", + "evaluation = Evaluation(\n", + " [\"mrr\", \"hits@3\", \"hits@10\"], worst_rank_infty=True, reduction=\"sum\"\n", + ")\n", + "inf_model = TopKQueryBessKGE(\n", + " k=10,\n", + " candidate_sampler=candidate_sampler,\n", + " score_fn=complex_score_fn,\n", + " evaluation=evaluation,\n", + " window_size=500,\n", + ")\n", "\n", "poptorch_inf_model = poptorch.inferenceModel(inf_model, options=val_options)\n", "\n", "poptorch_inf_model.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "_ = batch.pop(\"triple_idx\")\n", "res = poptorch_inf_model(**{k: v.flatten(end_dim=1) for k, v in batch.items()})" @@ -689,10 +763,15 @@ " # triple_mask is now passed to the model to filter out the metrics of padding triples\n", " res = poptorch_inf_model(**{k: v.flatten(end_dim=1) for k, v in batch_val.items()})\n", " n_val_queries += batch_val[\"triple_mask\"].sum()\n", - " val_log.append({k: v.sum() for k, v in zip(\n", - " evaluation.metrics.keys(),\n", - " res[\"metrics\"].T,\n", - " )})\n", + " val_log.append(\n", + " {\n", + " k: v.sum()\n", + " for k, v in zip(\n", + " evaluation.metrics.keys(),\n", + " res[\"metrics\"].T,\n", + " )\n", + " }\n", + " )\n", "\n", "print(f\"Validation time (sec): {(time.time() - start_time):.5f}\\n\")\n", "\n", @@ -729,7 +808,7 @@ ], "source": [ "start_time = time.time()\n", - "cpu_res = evaluate_mrr_cpu(yago.triples[\"validation\"], evaluation)\n", + "cpu_res = evaluate_mrr_cpu(yago.triples[\"valid\"], evaluation)\n", "\n", "print(f\"CPU Validation time (sec): {(time.time() - start_time):.5f}\\n\")\n", "print(f\"CPU validation MRR: {cpu_res['mrr']:.6f}\")" @@ -792,18 +871,21 @@ "source": [ "def check_prediction(val_triple_id):\n", " # Recover the non-padding triples seen in the last batch using triple_idx and triple_mask\n", - " triples = yago.triples[\"validation\"][validation_triples.triple_sort_idx][triple_idx[batch_val[\"triple_mask\"]]]\n", - " h,r,t = triples[val_triple_id]\n", + " triples = yago.triples[\"valid\"][validation_triples.triple_sort_idx][\n", + " triple_idx[batch_val[\"triple_mask\"]]\n", + " ]\n", + " h, r, t = triples[val_triple_id]\n", " # res[\"topk_global_id\"] contains the top-10 tails predicted by the KGE model\n", " top10_t = res[\"topk_global_id\"][batch_val[\"triple_mask\"].flatten()][val_triple_id]\n", - " \n", - " print(f'Example query: ({yago.entity_dict[h]}, {yago.relation_dict[r]}, ?)\\n')\n", + "\n", + " print(f\"Example query: ({yago.entity_dict[h]}, {yago.relation_dict[r]}, ?)\\n\")\n", " print(f\"Correct tail: {yago.entity_dict[t]}\\n\")\n", " print(f\"10 most likely predicted tails:\")\n", " for i, pt in enumerate(top10_t):\n", " print(f\"{i+1}) {yago.entity_dict[pt]}\" + (\" <-----\" if pt == t else \"\"))\n", " print(\"\\n\")\n", "\n", + "\n", "check_prediction(10)\n", "check_prediction(1000)" ] @@ -835,7 +917,9 @@ "source": [ "# complex_score_fn.entity_embedding has shape [n_shard, max_entity_per_shard, embedding_size]\n", "\n", - "print(f\"Current embedding table ({sharding.n_shard} shards): {complex_score_fn.entity_embedding.shape}\")\n", + "print(\n", + " f\"Current embedding table ({sharding.n_shard} shards): {complex_score_fn.entity_embedding.shape}\"\n", + ")\n", "\n", "# New entity sharding with a single shard - to use on 1 IPU\n", "new_val_sharding = Sharding.create(yago.n_entity, n_shard=1, seed=seed)\n", @@ -843,7 +927,9 @@ "# Update sharding of embedding tables, stored in the scoring function\n", "complex_score_fn.update_sharding(new_sharding=new_val_sharding)\n", "\n", - "print(f\"Refactored embedding table (1 shard): {complex_score_fn.entity_embedding.shape}\")" + "print(\n", + " f\"Refactored embedding table (1 shard): {complex_score_fn.entity_embedding.shape}\"\n", + ")" ] }, { @@ -879,9 +965,18 @@ "device_iterations = 4\n", "shard_bs = 1440\n", "\n", - "validation_triples = PartitionedTripleSet.create_from_dataset(yago, \"validation\", new_val_sharding, partition_mode=\"h_shard\")\n", - "bs_valid = RigidShardedBatchSampler(partitioned_triple_set=validation_triples, negative_sampler=candidate_sampler, shard_bs=shard_bs, batches_per_step=device_iterations,\n", - " seed=seed, duplicate_batch=False, return_triple_idx=True)\n", + "validation_triples = PartitionedTripleSet.create_from_dataset(\n", + " yago, \"valid\", new_val_sharding, partition_mode=\"h_shard\"\n", + ")\n", + "bs_valid = RigidShardedBatchSampler(\n", + " partitioned_triple_set=validation_triples,\n", + " negative_sampler=candidate_sampler,\n", + " shard_bs=shard_bs,\n", + " batches_per_step=device_iterations,\n", + " seed=seed,\n", + " duplicate_batch=False,\n", + " return_triple_idx=True,\n", + ")\n", "\n", "print(\"Number of triples per h_shard:\")\n", "print(validation_triples.triple_counts)\n", @@ -891,11 +986,13 @@ "val_options.deviceIterations(bs_valid.batches_per_step)\n", "val_options.outputMode(poptorch.OutputMode.All)\n", "\n", - "valid_dl = bs_valid.get_dataloader(options=val_options, shuffle=False, num_workers=5, persistent_workers=True)\n", + "valid_dl = bs_valid.get_dataloader(\n", + " options=val_options, shuffle=False, num_workers=5, persistent_workers=True\n", + ")\n", "\n", "print(\"Example batch:\")\n", "batch = next(iter(valid_dl))\n", - "for k,v in batch.items():\n", + "for k, v in batch.items():\n", " print(f\"{k:<12} {str(v.shape):<30}\")" ] }, @@ -927,15 +1024,21 @@ } ], "source": [ - "inf_model = TopKQueryBessKGE(k=10, candidate_sampler=candidate_sampler, score_fn=complex_score_fn, evaluation=evaluation, window_size=500)\n", + "inf_model = TopKQueryBessKGE(\n", + " k=10,\n", + " candidate_sampler=candidate_sampler,\n", + " score_fn=complex_score_fn,\n", + " evaluation=evaluation,\n", + " window_size=500,\n", + ")\n", "\n", "poptorch_inf_model = poptorch.inferenceModel(inf_model, options=val_options)\n", "\n", "poptorch_inf_model.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "# Compile model\n", "_ = batch.pop(\"triple_idx\")\n", @@ -949,12 +1052,17 @@ " triple_idx = batch_val.pop(\"triple_idx\")\n", " step_start_time = time.time()\n", " res = poptorch_inf_model(**{k: v.flatten(end_dim=1) for k, v in batch_val.items()})\n", - " \n", + "\n", " n_val_queries += batch_val[\"triple_mask\"].sum()\n", - " val_log.append({k: v.sum() for k, v in zip(\n", - " evaluation.metrics.keys(),\n", - " res[\"metrics\"].T,\n", - " )})\n", + " val_log.append(\n", + " {\n", + " k: v.sum()\n", + " for k, v in zip(\n", + " evaluation.metrics.keys(),\n", + " res[\"metrics\"].T,\n", + " )\n", + " }\n", + " )\n", "\n", "print(f\"Validation time (sec): {(time.time() - start_time):.5f}\\n\")\n", "\n", diff --git a/notebooks/3_wikikg2_fp16.ipynb b/notebooks/3_wikikg2_fp16.ipynb index 3b2306e..26de2a0 100644 --- a/notebooks/3_wikikg2_fp16.ipynb +++ b/notebooks/3_wikikg2_fp16.ipynb @@ -118,7 +118,7 @@ "source": [ "## Sharding entities and triples\n", "\n", - "The OGBL-WikiKG2 dataset can be downloaded and preprocessed with the built-in method of `KGDataset`, `build_wikikg2`. Sharding of entities and triples is performed as shown in the [KGE Training and Inference on OGBL-BioKG](1_biokg_training_inference.ipynb) notebook." + "The OGBL-WikiKG2 dataset can be downloaded and preprocessed with the built-in method of `KGDataset`, `build_ogbl_wikikg2`. Sharding of entities and triples is performed as shown in the [KGE Training and Inference on OGBL-BioKG](1_biokg_training_inference.ipynb) notebook." ] }, { @@ -143,12 +143,16 @@ } ], "source": [ - "wikikg = KGDataset.build_wikikg2(root=pathlib.Path(dataset_directory))\n", + "wikikg = KGDataset.build_ogbl_wikikg2(root=pathlib.Path(dataset_directory))\n", "\n", "print(f\"Number of entities: {wikikg.n_entity:,}\\n\")\n", "print(f\"Number of relation types: {wikikg.n_relation_type}\\n\")\n", - "print(f\"Number of triples: \\n training: {wikikg.triples['train'].shape[0]:,} \\n validation/test: {wikikg.triples['valid'].shape[0]:,}\\n\")\n", - "print(f\"Number of negative heads/tails for validation/test triples: {wikikg.neg_heads['valid'].shape[-1]}\")" + "print(\n", + " f\"Number of triples: \\n training: {wikikg.triples['train'].shape[0]:,} \\n validation/test: {wikikg.triples['valid'].shape[0]:,}\\n\"\n", + ")\n", + "print(\n", + " f\"Number of negative heads/tails for validation/test triples: {wikikg.neg_heads['valid'].shape[-1]}\"\n", + ")" ] }, { @@ -189,7 +193,7 @@ "\n", "print(f\"Number of entities in each shard: {sharding.max_entity_per_shard:,}\\n\")\n", "\n", - "print(f\"Global entity IDs on {n_shard} shards:\\n {sharding.shard_and_idx_to_entity}\\n\")" + "print(f\"Global entity IDs on {n_shard} shards:\\n {sharding.shard_and_idx_to_entity}\\n\")\n" ] }, { @@ -210,7 +214,9 @@ } ], "source": [ - "train_triples = PartitionedTripleSet.create_from_dataset(dataset=wikikg, part=\"train\", sharding=sharding, partition_mode=\"ht_shardpair\")\n", + "train_triples = PartitionedTripleSet.create_from_dataset(\n", + " dataset=wikikg, part=\"train\", sharding=sharding, partition_mode=\"ht_shardpair\"\n", + ")\n", "\n", "print(f\"Number of triples per (h,t) shard-pair:\\n {train_triples.triple_counts}\")" ] @@ -250,18 +256,29 @@ "accum_factor = 1\n", "shard_bs = 512\n", "\n", - "neg_sampler = RandomShardedNegativeSampler(n_negative=32, sharding=sharding, seed=seed, corruption_scheme=\"t\",\n", - " local_sampling=False, flat_negative_format=True)\n", + "neg_sampler = RandomShardedNegativeSampler(\n", + " n_negative=32,\n", + " sharding=sharding,\n", + " seed=seed,\n", + " corruption_scheme=\"t\",\n", + " local_sampling=False,\n", + " flat_negative_format=True,\n", + ")\n", "\n", - "batch_sampler = RandomShardedBatchSampler(partitioned_triple_set=train_triples, negative_sampler=neg_sampler,\n", - " shard_bs=shard_bs, batches_per_step=device_iterations*accum_factor, seed=seed)\n", + "batch_sampler = RandomShardedBatchSampler(\n", + " partitioned_triple_set=train_triples,\n", + " negative_sampler=neg_sampler,\n", + " shard_bs=shard_bs,\n", + " batches_per_step=device_iterations * accum_factor,\n", + " seed=seed,\n", + ")\n", "\n", "\n", "print(f\"# triples per shard-pair per step: {batch_sampler.positive_per_partition} \\n\")\n", "\n", "# Example batch\n", "idx_sampler = iter(batch_sampler.get_dataloader_sampler(shuffle=True))\n", - "for k,v in batch_sampler[next(idx_sampler)].items():\n", + "for k, v in batch_sampler[next(idx_sampler)].items():\n", " print(f\"{k:<12} {str(v.shape):<30} {v.dtype};\")" ] }, @@ -289,7 +306,9 @@ "# Enable stochastic rounding on IPU for more stable half-precision training\n", "options.Precision.enableStochasticRounding(True)\n", "\n", - "train_dl = batch_sampler.get_dataloader(options=options, shuffle=True, num_workers=3, persistent_workers=True)" + "train_dl = batch_sampler.get_dataloader(\n", + " options=options, shuffle=True, num_workers=3, persistent_workers=True\n", + ")" ] }, { @@ -321,12 +340,22 @@ "loss_fn = SampledSoftmaxCrossEntropyLoss(n_entity=wikikg.n_entity)\n", "# Initializer for entity and relation embeddings\n", "emb_initializer = [init_KGE_normal]\n", - "transe_score_fn = TransE(negative_sample_sharing=True, scoring_norm=1, sharding=sharding,\n", - " n_relation_type=wikikg.n_relation_type, embedding_size=100,\n", - " entity_initializer=emb_initializer, relation_initializer=emb_initializer)\n", + "transe_score_fn = TransE(\n", + " negative_sample_sharing=True,\n", + " scoring_norm=1,\n", + " sharding=sharding,\n", + " n_relation_type=wikikg.n_relation_type,\n", + " embedding_size=100,\n", + " entity_initializer=emb_initializer,\n", + " relation_initializer=emb_initializer,\n", + ")\n", "\n", - "model = EmbeddingMovingBessKGE(negative_sampler=neg_sampler, score_fn=transe_score_fn,\n", - " loss_fn=loss_fn, augment_negative=True)\n", + "model = EmbeddingMovingBessKGE(\n", + " negative_sampler=neg_sampler,\n", + " score_fn=transe_score_fn,\n", + " loss_fn=loss_fn,\n", + " augment_negative=True,\n", + ")\n", "\n", "print(f\"# model parameters: {model.n_embedding_parameters:,}\")" ] @@ -360,21 +389,21 @@ "model.half()\n", "\n", "opt = poptorch.optim.SGD(\n", - " model.parameters(),\n", - " lr=0.001,\n", - " momentum=0.95,\n", - " velocity_accum_type=torch.float16,\n", - " )\n", + " model.parameters(),\n", + " lr=0.001,\n", + " momentum=0.95,\n", + " velocity_accum_type=torch.float16,\n", + ")\n", "\n", "poptorch_model = poptorch.trainingModel(model, options=options, optimizer=opt)\n", "\n", "# The variable entity_embedding needs to hold different values on each replica,\n", "# corresponding to the shards of the entity embedding table\n", "poptorch_model.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "# Compile model\n", "batch = next(iter(train_dl))\n", @@ -413,16 +442,32 @@ "n_sample_queries = 4000\n", "\n", "val_device_iterations = 2\n", - "val_shard_bs = 512 \n", + "val_shard_bs = 512\n", "\n", "# Partition a random subset of n_sample_queries triples taken from wikikg.triples[\"valid\"]\n", - "subset_val_triples = wikikg.triples[\"valid\"][np.random.default_rng(seed=seed).choice(wikikg.triples[\"valid\"].shape[0], n_sample_queries)]\n", - "sample_val_triples = PartitionedTripleSet.create_from_queries(wikikg, sharding, queries=subset_val_triples[:,:2],\n", - " query_mode=\"hr\", ground_truth=subset_val_triples[:,2]) \n", + "subset_val_triples = wikikg.triples[\"valid\"][\n", + " np.random.default_rng(seed=seed).choice(\n", + " wikikg.triples[\"valid\"].shape[0], n_sample_queries\n", + " )\n", + "]\n", + "sample_val_triples = PartitionedTripleSet.create_from_queries(\n", + " wikikg,\n", + " sharding,\n", + " queries=subset_val_triples[:, :2],\n", + " query_mode=\"hr\",\n", + " ground_truth=subset_val_triples[:, 2],\n", + ")\n", "\n", "candidate_sampler = PlaceholderNegativeSampler(corruption_scheme=\"t\", seed=seed)\n", - "bs_sample = RigidShardedBatchSampler(partitioned_triple_set=sample_val_triples, negative_sampler=candidate_sampler, shard_bs=val_shard_bs,\n", - " batches_per_step=val_device_iterations, seed=seed, duplicate_batch=False, return_triple_idx=False)\n", + "bs_sample = RigidShardedBatchSampler(\n", + " partitioned_triple_set=sample_val_triples,\n", + " negative_sampler=candidate_sampler,\n", + " shard_bs=val_shard_bs,\n", + " batches_per_step=val_device_iterations,\n", + " seed=seed,\n", + " duplicate_batch=False,\n", + " return_triple_idx=False,\n", + ")\n", "\n", "print(\"Number of triples per h_shard:\")\n", "print(sample_val_triples.triple_counts)" @@ -450,11 +495,13 @@ "val_options.deviceIterations(bs_sample.batches_per_step)\n", "val_options.outputMode(poptorch.OutputMode.All)\n", "\n", - "sample_valid_dl = bs_sample.get_dataloader(options=val_options, shuffle=False, num_workers=2, persistent_workers=True)\n", + "sample_valid_dl = bs_sample.get_dataloader(\n", + " options=val_options, shuffle=False, num_workers=2, persistent_workers=True\n", + ")\n", "\n", "# Example batch\n", "val_batch = next(iter(sample_valid_dl))\n", - "for k,v in val_batch.items():\n", + "for k, v in val_batch.items():\n", " print(f\"{k:<12} {str(v.shape):<30}\")" ] }, @@ -479,15 +526,21 @@ "\n", "evaluation = Evaluation([\"mrr\"], worst_rank_infty=True, reduction=\"sum\")\n", "\n", - "inf_model = TopKQueryBessKGE(k=10, candidate_sampler=candidate_sampler, score_fn=transe_score_fn, evaluation=evaluation, window_size=500)\n", + "inf_model = TopKQueryBessKGE(\n", + " k=10,\n", + " candidate_sampler=candidate_sampler,\n", + " score_fn=transe_score_fn,\n", + " evaluation=evaluation,\n", + " window_size=500,\n", + ")\n", "\n", "poptorch_inf_model = poptorch.inferenceModel(inf_model, options=val_options)\n", "\n", "poptorch_inf_model.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "# Compile inference model\n", "val_res = poptorch_inf_model(**{k: v.flatten(end_dim=1) for k, v in val_batch.items()})\n", @@ -693,11 +746,20 @@ " step_start_time = time.time()\n", " cumulative_triples += batch[\"head\"].numel()\n", " res = poptorch_model(**{k: v.flatten(end_dim=1) for k, v in batch.items()})\n", - " ep_log.append(dict(loss= float(torch.sum(res[\"loss\"])) / batch[\"head\"][0].numel(), step_time=(time.time()-step_start_time)))\n", - " ep_loss = [v['loss'] for v in ep_log]\n", - " training_loss.extend([v['loss'] for v in ep_log])\n", - " print(f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\")\n", - " print(f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\")\n", + " ep_log.append(\n", + " dict(\n", + " loss=float(torch.sum(res[\"loss\"])) / batch[\"head\"][0].numel(),\n", + " step_time=(time.time() - step_start_time),\n", + " )\n", + " )\n", + " ep_loss = [v[\"loss\"] for v in ep_log]\n", + " training_loss.extend([v[\"loss\"] for v in ep_log])\n", + " print(\n", + " f\"Epoch {ep+1} loss: {np.mean(ep_loss):.6f} --- positive triples processed: {cumulative_triples:.2e}\"\n", + " )\n", + " print(\n", + " f\"Epoch duration (sec): {(time.time() - ep_start_time):.5f} (average step time: {np.mean([v['step_time'] for v in ep_log]):.5f})\"\n", + " )\n", " if ep % val_ep_interval == 0:\n", " poptorch_model.detachFromDevice()\n", " poptorch_inf_model.attachToDevice()\n", @@ -707,18 +769,24 @@ " val_start_time = time.time()\n", " ep_mrr = 0.0\n", " for batch_val in sample_valid_dl:\n", - " ep_mrr += poptorch_inf_model(**{k: v.flatten(end_dim=1) for k, v in batch_val.items()})[\"metrics\"].sum()\n", - " ep_mrr /= n_sample_queries \n", + " ep_mrr += poptorch_inf_model(\n", + " **{k: v.flatten(end_dim=1) for k, v in batch_val.items()}\n", + " )[\"metrics\"].sum()\n", + " ep_mrr /= n_sample_queries\n", " val_mrr.append(ep_mrr)\n", - " print(f\"Epoch {ep+1} sample MRR: {ep_mrr:.4f} (validation time: {(time.time() - val_start_time):.5f})\")\n", + " print(\n", + " f\"Epoch {ep+1} sample MRR: {ep_mrr:.4f} (validation time: {(time.time() - val_start_time):.5f})\"\n", + " )\n", " poptorch_inf_model.detachFromDevice()\n", " poptorch_model.attachToDevice()\n", "\n", "# Plot loss and sample MRR as a function of the number of positive triples processed\n", "total_triples = np.cumsum(n_epochs * len(train_dl) * [batch[\"head\"].numel()])\n", "ax0, ax1 = plt.gca(), plt.twinx()\n", - "line0, = ax0.plot(total_triples, training_loss)\n", - "line1, = ax1.plot(total_triples[::val_ep_interval * len(train_dl)], val_mrr, color=\"r\")\n", + "(line0,) = ax0.plot(total_triples, training_loss)\n", + "(line1,) = ax1.plot(\n", + " total_triples[:: val_ep_interval * len(train_dl)], val_mrr, color=\"r\"\n", + ")\n", "ax0.set_xlabel(\"Positive triples\")\n", "ax0.set_ylabel(\"Loss\")\n", "ax1.set_ylabel(\"Sample MRR\")\n", @@ -752,9 +820,16 @@ } ], "source": [ - "validation_triples = PartitionedTripleSet.create_from_dataset(wikikg, \"valid\", sharding, partition_mode=\"h_shard\")\n", - "bs_valid = RigidShardedBatchSampler(partitioned_triple_set=validation_triples, negative_sampler=candidate_sampler, shard_bs=val_shard_bs,\n", - " batches_per_step=val_device_iterations, seed=seed)\n", + "validation_triples = PartitionedTripleSet.create_from_dataset(\n", + " wikikg, \"valid\", sharding, partition_mode=\"h_shard\"\n", + ")\n", + "bs_valid = RigidShardedBatchSampler(\n", + " partitioned_triple_set=validation_triples,\n", + " negative_sampler=candidate_sampler,\n", + " shard_bs=val_shard_bs,\n", + " batches_per_step=val_device_iterations,\n", + " seed=seed,\n", + ")\n", "\n", "print(\"Number of triples per h_shard:\")\n", "print(validation_triples.triple_counts)\n", @@ -784,7 +859,9 @@ "n_val_queries = 0\n", "for batch_val in valid_dl:\n", " n_val_queries += batch_val[\"triple_mask\"].sum()\n", - " val_mrr += poptorch_inf_model(**{k: v.flatten(end_dim=1) for k, v in batch_val.items()})[\"metrics\"].sum()\n", + " val_mrr += poptorch_inf_model(\n", + " **{k: v.flatten(end_dim=1) for k, v in batch_val.items()}\n", + " )[\"metrics\"].sum()\n", "\n", "print(f\"Validation MRR: {val_mrr / n_val_queries}\")\n", "print(f\"Validation time (sec): {(time.time() - start_time):.5f}\")\n", @@ -824,16 +901,29 @@ } ], "source": [ - "validation_triples = PartitionedTripleSet.create_from_dataset(dataset=wikikg, part=\"valid\", sharding=sharding, partition_mode=\"ht_shardpair\")\n", - "ns_valid = TripleBasedShardedNegativeSampler(negative_heads=validation_triples.neg_heads, negative_tails=validation_triples.neg_tails,\n", - " sharding=sharding, corruption_scheme=\"t\", seed=seed)\n", + "validation_triples = PartitionedTripleSet.create_from_dataset(\n", + " dataset=wikikg, part=\"valid\", sharding=sharding, partition_mode=\"ht_shardpair\"\n", + ")\n", + "ns_valid = TripleBasedShardedNegativeSampler(\n", + " negative_heads=validation_triples.neg_heads,\n", + " negative_tails=validation_triples.neg_tails,\n", + " sharding=sharding,\n", + " corruption_scheme=\"t\",\n", + " seed=seed,\n", + ")\n", "# We do not need to duplicate_batch as we only want to score negative tails\n", - "bs_valid = RigidShardedBatchSampler(partitioned_triple_set=validation_triples, negative_sampler=ns_valid, shard_bs=256, batches_per_step=10,\n", - " seed=seed, duplicate_batch=False)\n", + "bs_valid = RigidShardedBatchSampler(\n", + " partitioned_triple_set=validation_triples,\n", + " negative_sampler=ns_valid,\n", + " shard_bs=256,\n", + " batches_per_step=10,\n", + " seed=seed,\n", + " duplicate_batch=False,\n", + ")\n", "\n", "# Example batch\n", "idx_sampler = iter(bs_valid.get_dataloader_sampler(shuffle=False))\n", - "for k,v in bs_valid[next(idx_sampler)].items():\n", + "for k, v in bs_valid[next(idx_sampler)].items():\n", " print(f\"{k:<15} {str(v.shape):<35} {v.dtype};\")" ] }, @@ -868,21 +958,25 @@ "val_options.deviceIterations(bs_valid.batches_per_step)\n", "val_options.outputMode(poptorch.OutputMode.All)\n", "\n", - "valid_dl = bs_valid.get_dataloader(options=val_options, shuffle=False, num_workers=3, persistent_workers=True)\n", + "valid_dl = bs_valid.get_dataloader(\n", + " options=val_options, shuffle=False, num_workers=3, persistent_workers=True\n", + ")\n", "\n", "# Each triple is now to be scored against a specific set of negatives, so we turn off negative sample sharing\n", "transe_score_fn.negative_sample_sharing = False\n", "\n", "evaluation = Evaluation([\"mrr\", \"hits@1\", \"hits@5\", \"hits@10\"], reduction=\"sum\")\n", - "model_inf = ScoreMovingBessKGE(negative_sampler=ns_valid, score_fn=transe_score_fn, evaluation=evaluation)\n", + "model_inf = ScoreMovingBessKGE(\n", + " negative_sampler=ns_valid, score_fn=transe_score_fn, evaluation=evaluation\n", + ")\n", "\n", "poptorch_model_inf = poptorch.inferenceModel(model_inf, options=val_options)\n", "\n", "poptorch_model_inf.entity_embedding.replicaGrouping(\n", - " poptorch.CommGroupType.NoGrouping,\n", - " 0,\n", - " poptorch.VariableRetrievalMode.OnePerGroup,\n", - " )\n", + " poptorch.CommGroupType.NoGrouping,\n", + " 0,\n", + " poptorch.VariableRetrievalMode.OnePerGroup,\n", + ")\n", "\n", "# Compile model\n", "batch = next(iter(valid_dl))\n", @@ -914,10 +1008,15 @@ " res = poptorch_model_inf(**{k: v.flatten(end_dim=1) for k, v in batch_val.items()})\n", " n_val_queries += batch_val[\"triple_mask\"].sum()\n", " # By transposing res[\"metrics\"] we separate the outputs for the different metrics\n", - " val_log.append({k: v.sum() for k, v in zip(\n", - " evaluation.metrics.keys(),\n", - " res[\"metrics\"].T,\n", - " )})\n", + " val_log.append(\n", + " {\n", + " k: v.sum()\n", + " for k, v in zip(\n", + " evaluation.metrics.keys(),\n", + " res[\"metrics\"].T,\n", + " )\n", + " }\n", + " )\n", "\n", "for metric in val_log[0].keys():\n", " reduced_metric = sum([l[metric] for l in val_log]) / n_val_queries\n",