Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save leriomaggio/30fc8892e1c6b7f5b3b23b46e734e5c9 to your computer and use it in GitHub Desktop.
Save leriomaggio/30fc8892e1c6b7f5b3b23b46e734e5c9 to your computer and use it in GitHub Desktop.
SOLVED:Flower Hands-on Tutorial-PyTorch.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/leriomaggio/30fc8892e1c6b7f5b3b23b46e734e5c9/solved-flower-hands-on-tutorial-pytorch.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "r41cmZoW1CF8"
},
"source": [
"# Flower Hands on Coding Challange\n",
"\n",
"Welcome to Flower Hands-on Tutorial!\n",
"\n",
"In this notebook, you'll build a federated learning system using **Flower** and **PyTorch** with **MNIST** dataset.\n",
"\n",
"We will provide you with the following code:\n",
"* ML model definition,\n",
"* train, test functions.\n",
"\n",
"You will need to implement the following elements:\n",
"* data division (clients partitioning and train/test division),\n",
"* Flower Client class,\n",
"* Flower Strategy (initialization or groud-up creation),\n",
"* distributed evaluation,\n",
"* centralized evaluation.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VHJaF8yX1CF-"
},
"source": [
"### Install dependencies & Import libraries\n",
"\n",
"Next, we install the necessary packages\n",
"* Flower (`flwr`),\n",
"* PyTorch (`torch`, `torchvision`),"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "5jU4leX31CF-",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "7d0a4b73-5ea3-4670-c792-4240d70dd6a4"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m157.2/157.2 kB\u001b[0m \u001b[31m4.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.6/58.6 MB\u001b[0m \u001b[31m17.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.6/149.6 kB\u001b[0m \u001b[31m10.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m8.7/8.7 MB\u001b[0m \u001b[31m77.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.8/4.8 MB\u001b[0m \u001b[31m45.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m64.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m201.4/201.4 kB\u001b[0m \u001b[31m24.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.0/3.0 MB\u001b[0m \u001b[31m64.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m97.9/97.9 kB\u001b[0m \u001b[31m12.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
" Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
" Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m128.2/128.2 kB\u001b[0m \u001b[31m17.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.5/114.5 kB\u001b[0m \u001b[31m14.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m268.8/268.8 kB\u001b[0m \u001b[31m33.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.4/58.4 kB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m468.5/468.5 kB\u001b[0m \u001b[31m53.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h Building wheel for gpustat (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n"
]
}
],
"source": [
"!pip install -q flwr[simulation] torch torchvision matplotlib;"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dEG3b87r1CF_"
},
"source": [
"Now that we have all dependencies installed, we can import everything we need for this tutorial:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "MlbJRGwP1CF_",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "270d7be6-a045-481d-8231-438334766816"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Training on cpu using PyTorch 2.0.1+cu118 and Flower 1.4.0\n"
]
}
],
"source": [
"from collections import OrderedDict\n",
"from typing import List, Tuple, Dict, Optional\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"import torch\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"import torchvision\n",
"import torchvision.transforms as transforms\n",
"from torch.utils.data import DataLoader, random_split\n",
"from torchvision.datasets import MNIST\n",
"from torch.utils.data import ConcatDataset, DataLoader, Dataset, Subset, random_split\n",
"\n",
"import flwr as fl\n",
"from flwr.common import Metrics\n",
"from flwr.common.typing import NDArrays, Scalar\n",
"\n",
"DEVICE = torch.device(\"cpu\") # Try \"cuda\" to train on GPU\n",
"print(\n",
" f\"Training on {DEVICE} using PyTorch {torch.__version__} and Flower {fl.__version__}\"\n",
")\n"
]
},
{
"cell_type": "markdown",
"source": [
"Let's define some useful constants that we will need along the tutorial."
],
"metadata": {
"id": "K5pZIQByAgFb"
}
},
{
"cell_type": "code",
"source": [
"SEED = 42\n",
"NUM_CLIENTS = 10\n",
"BATCH_SIZE = 32\n",
"VALID_FRACTION = 0.2 # fraction of the dataset used for each local client\n",
"NUM_ROUNDS = 2"
],
"metadata": {
"id": "G5YZJIkvzfc-"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## Data\n",
"\n",
"The aim of this section is to create a divided MNIST dataset to simulate the federated learning evironment.\n",
"\n",
"We provide you with the `download_data` function and want you to implement the following:\n",
"\n",
"* `partition_data`,\n",
"* `train_val_divide_local_datasets`.\n",
"\n",
"You are given the function prototype - function name, the necessary information about a function, arguments, their types, and the return type.\n",
"\n",
"If implemented correctly they should be able to run `load_datasets` function that creates the divided datasets.\n",
"\n",
"Firstly let's just have a quick look at the data (already prepared, just run the cells below)."
],
"metadata": {
"id": "qmi_O9qspq4J"
}
},
{
"cell_type": "code",
"source": [
"def download_data() -> Tuple[Dataset, Dataset]:\n",
" transform = transforms.Compose(\n",
" [transforms.ToTensor(),]# transforms.Normalize((0.1307,), (0.3081,))\n",
" )\n",
" trainset = MNIST(\"./dataset\", train=True, download=True, transform=transform)\n",
" testset = MNIST(\"./dataset\", train=False, download=True, transform=transform)\n",
" return trainset, testset\n",
"# Keep the testset for centralized (optional) centralized evaluation.\n",
"trainset, testset = download_data()"
],
"metadata": {
"id": "RaHMfzZipqdQ",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "54b14f43-ab49-45c3-9363-4c2365f8cba2"
},
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n",
"Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to ./dataset/MNIST/raw/train-images-idx3-ubyte.gz\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"100%|██████████| 9912422/9912422 [00:00<00:00, 101700593.79it/s]\n"
]
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Extracting ./dataset/MNIST/raw/train-images-idx3-ubyte.gz to ./dataset/MNIST/raw\n",
"\n",
"Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\n",
"Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to ./dataset/MNIST/raw/train-labels-idx1-ubyte.gz\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"100%|██████████| 28881/28881 [00:00<00:00, 53176336.18it/s]\n"
]
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Extracting ./dataset/MNIST/raw/train-labels-idx1-ubyte.gz to ./dataset/MNIST/raw\n",
"\n",
"Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\n",
"Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ./dataset/MNIST/raw/t10k-images-idx3-ubyte.gz\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"100%|██████████| 1648877/1648877 [00:00<00:00, 24754514.11it/s]\n"
]
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Extracting ./dataset/MNIST/raw/t10k-images-idx3-ubyte.gz to ./dataset/MNIST/raw\n",
"\n",
"Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\n",
"Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ./dataset/MNIST/raw/t10k-labels-idx1-ubyte.gz\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"100%|██████████| 4542/4542 [00:00<00:00, 16681723.96it/s]\n"
]
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Extracting ./dataset/MNIST/raw/t10k-labels-idx1-ubyte.gz to ./dataset/MNIST/raw\n",
"\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"### Quick EDA"
],
"metadata": {
"id": "ube7hvyewiha"
}
},
{
"cell_type": "code",
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"dataiter = iter(torch.utils.data.DataLoader(trainset, batch_size=64))\n",
"images, labels = next(dataiter)\n",
"images = images.permute(0, 2, 3, 1).numpy()\n",
"\n",
"# Create a figure and a grid of subplots\n",
"fig, axs = plt.subplots(4, 8, figsize=(10, 4))\n",
"\n",
"# Loop over the images and plot them\n",
"for i, ax in enumerate(axs.flat):\n",
" ax.imshow(images[i], cmap='gray')\n",
" ax.set_title(labels[i].numpy())\n",
" ax.axis(\"off\")\n",
"\n",
"# Show the plot\n",
"fig.tight_layout()\n",
"plt.show()\n"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 407
},
"id": "Swp-IN2Zqtto",
"outputId": "abe49e71-63f1-453f-e791-e119e77ede88"
},
"execution_count": null,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1000x400 with 32 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA58AAAGGCAYAAAD8VzUGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOz9eXTkV3kn/r9r3/e9VFUq7bt677bbdrtttxcMNgS3gSwDTsgCSUw4k5nkkAPhfJmBYc6QSUI4GSBhCEyAAGa1wcZ4aS+9ufdNu1SSalXt+778/ujf5yJZ3XbbllQl9fM6Rwejra/00edT97n3uc/DazQaDRBCCCGEEEIIIeuI3+wBEEIIIYQQQgjZ+ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7loq+Dxy5Ah4PN41306cONHs4ZE1VCqV8Nd//dew2+2QyWTYt28ffv3rXzd7WGSdfP7znwePx8Pw8HCzh0LWUDabxWc/+1k88MAD0Ov14PF4+Ld/+7dmD4usoTNnzuCBBx6AWq2GSqXCfffdh/Pnzzd7WGSNnDp1Cn/+53+OoaEhKBQKuFwufOADH8DU1FSzh0bWED2rt74rV67g0UcfRWdnJ+RyOYxGIw4cOIAnn3yy2UNbRdjsAVzLJz7xCezZs2fF+7q7u5s0GrIeHnvsMTzxxBP45Cc/iZ6eHvzbv/0bHnzwQbz44ou4/fbbmz08soZ8Ph++8IUvQKFQNHsoZI1Fo1F87nOfg8vlwrZt23DkyJFmD4msobNnz+L222+H0+nEZz/7WdTrdfzzP/8z7rzzTrz22mvo6+tr9hDJO/Q//+f/xNGjR/Hoo49idHQUoVAIX/nKV7Bz506cOHGCFgy3CHpWb30LCwvIZDL4yEc+Arvdjnw+jx/96Ed4+OGH8bWvfQ1//Md/3OwhMrxGo9Fo9iA4R44cwV133YUf/vCHOHz4cLOHQ9bJa6+9hn379uF//a//hf/yX/4LAKBYLGJ4eBhmsxnHjh1r8gjJWvrQhz6ESCSCWq2GaDSKy5cvN3tIZI2USiUkEglYrVacPn0ae/bswTe/+U089thjzR4aWQPvfve7cfz4cUxPT8NgMAAAgsEgent7cd999+FHP/pRk0dI3qljx45h9+7dEIvF7H3T09MYGRnB4cOH8e///u9NHB1ZK/SsvjnVajXs2rULxWIRExMTzR4O01Jpt8tlMhlUq9VmD4OsgyeeeAICgWDFKoxUKsVHP/pRHD9+HF6vt4mjI2vp5ZdfxhNPPIF/+Id/aPZQyDqQSCSwWq3NHgZZJ6+88goOHTrEAk8AsNlsuPPOO/HUU08hm802cXRkLezfv39F4AkAPT09GBoawvj4eJNGRdYaPatvTgKBAE6nE8lkstlDWaElg8/f//3fh1qthlQqxV133YXTp083e0hkDZ07dw69vb1Qq9Ur3r93714AoPNEW0StVsPjjz+OP/zDP8TIyEizh0MIeYtKpRJkMtmq98vlcpTLZcpi2KIajQaWlpZgNBqbPRRCyFuUy+UQjUYxOzuLv//7v8fTTz+Ne+65p9nDWqGlznyKxWI88sgjePDBB2E0GjE2NoYvfelLuOOOO3Ds2DHs2LGj2UMkayAYDMJms616P/e+QCCw0UMi6+CrX/0qFhYW8NxzzzV7KISQt6Gvrw8nTpxArVaDQCAAAJTLZZw8eRIA4Pf7mzk8sk6+853vwO/343Of+1yzh0IIeYv+8i//El/72tcAAHw+H+9///vxla98pcmjWqmlgs/9+/dj//797P8//PDDOHz4MEZHR/GpT30KzzzzTBNHR9ZKoVCARCJZ9X6pVMo+Tja3WCyGv/3bv8VnPvMZmEymZg+HEPI2/Omf/ik+/vGP46Mf/Sj+6q/+CvV6Hf/9v/93BINBAPSs3oomJibwZ3/2Z7j11lvxkY98pNnDIYS8RZ/85Cdx+PBhBAIB/OAHP0CtVkO5XG72sFZoybTb5bq7u/He974XL774Imq1WrOHQ9aATCZDqVRa9f5iscg+Tja3T3/609Dr9Xj88cebPRRCyNv0sY99DH/zN3+D7373uxgaGsLIyAhmZ2fxV3/1VwAApVLZ5BGStRQKhfDud78bGo2G1WYghGwu/f39OHToED784Q+zs/kPPfQQWqi+bOsHnwDgdDpRLpeRy+WaPRSyBmw2G1s5X457n91u3+ghkTU0PT2Nr3/96/jEJz6BQCCA+fl5zM/Po1gsolKpYH5+HvF4vNnDJITcgM9//vNYWlrCK6+8gosXL+LUqVOo1+sAgN7e3iaPjqyVVCqFd73rXUgmk3jmmWfodZiQLeLw4cM4depUS/Xu3RTB59zcHKRSKa2ybhHbt2/H1NQU0un0ivdz54i2b9/ehFGRteL3+1Gv1/GJT3wCHR0d7O3kyZOYmppCR0cHnSUiZBPR6XS4/fbbWeGw5557Dg6HA/39/U0eGVkLxWIRDz30EKampvDUU09hcHCw2UMihKwR7nhEKpVq8kh+o6XOfEYikVXnwy5cuICf//zneNe73gU+f1PEyuRNHD58GF/60pfw9a9/nfX5LJVK+OY3v4l9+/bB6XQ2eYTknRgeHsZPfvKTVe//9Kc/jUwmg3/8x39EV1dXE0ZGCHmnvv/97+PUqVP40pe+RK/JW0CtVsMHP/hBHD9+HD/72c9w6623NntIhJC3IRwOw2w2r3hfpVLBt7/9bchkspZaVGqp4PODH/wgZDIZ9u/fD7PZjLGxMXz961+HXC7HF7/4xWYPj6yRffv24dFHH8WnPvUphMNhdHd341vf+hbm5+fxjW98o9nDI++Q0WjE+973vlXv53p9XutjZPP6yle+gmQyyapUP/nkk/D5fACAxx9/HBqNppnDI+/Ayy+/jM997nO47777YDAYcOLECXzzm9/EAw88gL/4i79o9vDIGvjLv/xL/PznP8dDDz2EeDyOf//3f1/x8d/7vd9r0sjIWqNn9db2J3/yJ0in0zhw4ADa2toQCoXwne98BxMTE/i7v/u7lsoe5TVa6ATql7/8ZXznO9/BzMwM0uk0TCYT7rnnHnz2s59Fd3d3s4dH1lCxWMRnPvMZ/Pu//zsSiQRGR0fx3/7bf8P999/f7KGRdXLw4EFEo1HqDbjFuN1uLCwsXPNjHo8Hbrd7YwdE1szs7Cz+9E//FGfPnkUmk0FHRwc+8pGP4D//5/8MsVjc7OGRNXDw4EG89NJL1/14C00RyTtEz+qt7T/+4z/wjW98A5cuXUIsFoNKpcKuXbvw+OOP4+GHH2728FZoqeCTEEIIIYQQQsjWRAc2CCGEEEIIIYSsOwo+CSGEEEIIIYSsOwo+CSGEEEIIIYSsOwo+CSGEEEIIIYSsOwo+CSGEEEIIIYSsOwo+CSGEEEIIIYSsOwo+CSGEEEIIIYSsO+GNfiKPx1vPcbSUm7X1KV3jrY+u8c2BrvPWR9d466NrvPXRNd766BqvRjufhBBCCCGEEELWHQWfhBBCCCGEEELWHQWfhBBCCCGEEELWHQWfhBBCCCGEEELWHQWfhBBCCCGEEELWHQWfhBBCCCGEEELW3Q23WiFko3Blqbn/5Uo336xlugkhhBBC3i4ej7eq5Uej0aB5FWkKCj5JS1AqldBqtTAajejr64NOp0NnZydKpRJmZmaQSqUwNjaGTCaDWCyGcrnc7CETQgghhLQsgUCAXbt2oa2tDd3d3bDb7chms8hkMrhy5QqOHz+OUqmEXC7X7KGSmwgFn6QlyGQymM1m9PX14e6774bL5cKBAweQyWRw5MgR+P1+5HI5BINBpNNpCj4JIYQQQt6AQCDA4OAgdu3ahTvvvBMjIyMIh8MIh8N48sknceXKFWSzWeTzedoFJRum5YJPHo8HoVAIgUCw6mN6vR4dHR0QCAQQCAQQCoVQKpUoFos4f/48SqUSRkdHodPp4HQ6oVKpUKvV0Gg0sLCwAJ/PB5/Ph/n5+Y3/wcg1KRQKKJVK7Ny5E/fccw8sFgv6+vqg1WohEAggk8nQ398Pm80GqVSKUCiEb33rW7RKt4UJBAKYTCYolUrs2rULZrMZJ0+exMzMDPL5PIrFYrOHSN4GpVKJ/v5+6HQ6DA4OQi6Xg8/no1Kp4OjRo1hcXEQ8Hqd7m5AWwOfzIRQKwefzIRAIoFAoYDabIRaLIRaLUS6XMT09jXw+j1qt1uzhktfh8XiQy+VQKBTo6urC8PAwdDodGo0G5HI5jEYjewOAWCzW5BGTt4rH40GpVEIkEoHH44HP50On00GpVKKnpwfd3d2o1+s39L1qtRrb3Dl9+jSCweC6pmW3VPDJ/fLEYjEkEsmqjzudThw4cAASiQQSiQQymQx2ux2JRALhcBjZbBb33HMP+vr6cOutt6KtrQ3VahXVahVHjhzByZMncfToUQo+W4hKpYLFYsEtt9yCj3zkI5BKpZDJZOzjMpkMg4ODqNfrGB4eRjAYxK9+9Su6hluYQCBAW1sbrFYrPvzhD2N0dBT/+3//bySTSUSjUQo+NymVSoVbb70VHR0d+NCHPgSLxQIej4dcLocvfOELeOWVV1CpVCj4JKQFCAQCiMViiEQiSCQSGI1G7Ny5E3K5HBqNBul0GqFQCKVSCfV6nXbNWgwXmOh0OvT09GB0dBRyuZwFnzKZDCaTCSaTCeVyGTwej67hJsPn86FWq6FQKNhiUVdXF+x2Ox588EG8+93vBnBj9VKKxSJOnToFv9+PpaUlhMNhtnm3HjYs+BQIBJBKpSzAFAgE0Gg0kEgk0Gq1kEgkEIlEEAqFsFqt0Ov1q76H2WxGf38/hEIh2x3lgpU9e/agWCxiaGgILpcLUqkU1WoV6XQa+XweS0tLCAaDyGQyG/UjkzegVCohl8uxbds27NixA8PDw5BKpRAKr/5JNhoN9ofPrdwIhULIZDIYDAaYTCZkMhmUy+UbXtkhb457kHGZBdwZ243E5/PZ+d9isUgB5yYnl8tht9vhdDqxfft2tLW1rVhgIoQ0n0QigVgshsVigdVqhUqlgl6vh0wmg0ajgVqthtPphEgkglwuRyqVQigUQjAYxPj4OFKpVLN/BLJMo9FAuVxGoVBALBZDKBSCxWKBWCxu9tDI28RlIEilUtjtdrbDqdVqwefzwefz4XA4YDQa0d7e/pYWFIRCIWw2G8RiMfbu3QuZTIaZmRmEQiHUarU1n2dvWPApFAqh0WhY4CiVSll6ZW9vL3Q6HeRyOcRiMbZt24bOzs5V3+P11boqlQpisRhyuRze/e53o16vY9++fTAYDKhUKigWiwiHw4jFYvB4PJienkY0Gt2oH5m8AS6APHToEB599FEWjHJqtRpKpRJqtRqq1Sr4fD5UKhUUCgXa2trQ3t6OhYUFJJNJAKAAdI0YjUbY7Xa2Mjo/P494PL6hK6ICgQBWqxV2ux25XA5erxfZbHbD/n2ytrRaLXbt2oXe3l4cOnQIer0eEonkmn9TtPJOSHMolUqoVCrs27cPt9xyC2w2G9xuN7RaLex2O/h8/oo5WDKZhFAoxPz8PMLhMAWfLabRaKBQKIDH48Hn82F2dhYymQw6na7ZQyNvk1AohNlshl6vx8GDB2Gz2bBv3z6WRcTj8aDRaKBUKsHn899S2qxAIEBnZyecTicymQwGBwfxxBNPIJlMolQqrXmdlXUPPrlVMpPJhD179rAAUyKRwG63s2BCoVBAIpGsCFLfTLFYZJVQA4EAarUapFIplEol8vk8yuUyeyhOT0+z1Fyy8bgXLu46DwwMoLe3F52dnex9y9VqNXYI3uv1QiQSYXR0FGKxGDt37oRGo8HZs2cRDAYRCARYEEreGaVSCYvFwiYiqVRqw9Nx+Hw+ZDIZVCoV5HI52xF/fZl4sjkIBALI5XLI5XKW3ULXcnPgns06nY7dj9x1lEql7PNyuRwWFxdRqVRQLpfZYiFw9SxZsVhENptFpVJp1o9CluHxeJBKpRCJRDCbzVCr1XC5XDCbzRgYGEBPTw90Oh0MBgMkEglbBK7VaqwWAzeHq9Vq7JxZsVhEtVpt9o9H/v+461YoFJDL5ej+2+RkMhn6+vpYFqjFYoHRaGTPWh6PB4lEwubby+dtNzKH4/F4bPEfAEwmEzQaDVKp1OYLPuVyOUu3+uu//msYjUZWaIL7BXH/C/zm3OebaTQaiMfj+OUvf4loNIpCoYBGo4Fjx44BuLoqVygUkM1mUS6XsbS0hGg0SjtkTcJNOu12OwwGAx5++GHcfffd0Ov10Gq1qyajpVIJkUgEfr8fTz75JBQKBZxOJxwOBz784Q+jUCjgJz/5Ca5cuYJf//rXFHyuAR6PB4vFworCGAwGZDKZDQ0UuIefVquFyWSCwWCAWq1eMdElm4tIJILRaIROp4NYLL6hhUXSfHw+n01udu7ciZ6eHrhcLjidTuj1elgsFva509PT+P73v49UKoVkMgmRSIT+/n7w+Xy8+uqrCAaDmJ+fp+d0i+Dz+ezZes8996Cnpwe7du1CT08Pq6nBzcUKhQKSySTLJpNIJGhra4NUKsXw8DDMZjPcbjdSqRSCwSAFny2kUqmAx+NRvYQtQqvV4oEHHkBnZyd27doFjUYDgUCwYo72TudrAoEA/f396OzsxMmTJ+HxeFCv19f8yOK6zwLq9ToqlQpqtRqrksYFn2+G2+qt1+vs67nUzHq9jkKhAJ/Ph0gksursXyaTYV9fqVSoIlsTCQQCOJ1OaDQa9PT0wGKxoL29HVqtlp0Dfv0Nw+2WSCQS1Ot1lMtlZDIZpNNpKBQKyOVyqNVq6HS6axanIm+PRqNBW1sbCxJu5D5dKzwej+2omM1mWK1WVpAml8shn8/Tyu0mwj2vTSYTHA4HLBYLhEIhGo0GezZ7vV7EYjH4/X5kMhm6vi2AS93iVtkdDgf6+/vR3t4Oi8UCk8kEsVjMjkMIBAKoVCr09vYil8shk8lAJBKhvb0djUYDPp8PYrEYS0tLFHw2kUAggEgkgsViYRVQdTodent74Xa7YTKZoFKpIBAIwOfzUavV2NGlsbExVCoVVCoV6HQ6mEwmSKVSVnNDKpVCLBZv6OsFeXNcERqZTAaFQkELf5scF/cUi0Xw+XyIRCL2sVqthlqtxurcAL8JRJfvenJ/DyKRCAqF4prBKves4J4F67EBse5/iaVSCdFoFPF4HOl0GnK5nOUjvxnukHS5XEaxWITRaERPTw+Aq7/oRCKB1157DX6/f9WW8vLqa8uL1pCNJ5PJ8OCDD2JoaAh79+6F0+lcsbp6va9xuVyo1+tQKBSoVquYm5tDLpdDf38/q9SWy+WgUCg2+Cfamng8Hrq6unDHHXcgHA4jEAhs6L/PVW4zGo3Yt28ftm/fjrNnz2JhYQFerxeBQIDu401Eo9Ggr68P27Ztw3333QedTgeZTIZqtcr6zH35y1/G+Pg4QqEQstksrcy3AJFIhMHBQbS1teHRRx/Ftm3boNFo2ORVIBAgFAphbGwMEomEFcB45JFHwOfzUa/XWcu0UqkElUoFr9eLhYUFBIPBZv94NyU+nw+pVAq9Xo/3v//9cLvd7KyYSqVaUfCRk8vlEI/H8eqrr+Kf//mfUS6XIRQKMTAwgOHhYdbGo1gsQqVSQaVSrZgMk+biUquVSiWsVitcLhdLzySbU6FQwOTkJCqVCnbv3r3iY1wbutOnT2NmZgYArnlkSq1Wo7OzE1qtFn19fU0rQLUhO5/lchm5XI5NHrmIvVQqAQA7V8DhVthCoRAmJiZQLpeRz+dhNptRr9chFouhUChYai1NWFoTj8dj18piscBut7P0O065XGZvxWIRMpkMWq2WfbzRaKBYLLLUaQDo7OyETCZjFVlptXXtcGe0m7FCKhKJWFVULtWWa71RLpcpc2GTEAqFkEgkMBgM6OrqgsvlglqthlwuB4/HQ7VaRSQSQTAYRDAYZIEnVa5uLq7NmUKhgMvlQkdHB2w2GwwGAwQCAer1OuvD6vf7MTMzwz6fS+EUCoWs7P/y70uai+suYDAY4HK54Ha7YbFY2NxreV91bgclGo1iZmYGHo8HoVAI9XodUqkU2WyW3afLj03ROe7WIxAIIBAIIJFIrvm6LhQKWV0FLpuB0qZbV6VSQTgchlgsxtTU1IoiX9zi7fT0NGZnZ1fcj8sDULVajWq1CrPZDJfLxXbHl8vn8+zY4nplnK37DLNarSKXy8Hj8eAHP/gBTCYTtm/fDoFAAJ/PBz6fj0ceeQQdHR3sa2KxGOLxOH7605/i+9//PitioNFo2Lm/AwcOwOfzsQCWtB6hUAiHwwGr1YrR0VHs3LlzRWAJgJ3r9Pl8mJ6exsDAAB588EHU63Wk02lEo1HMz88jnU4jm82yg9Y6nY5e7NZJsyYSGo0GH/rQh9Dd3Q2bzYZGo4FEIoFgMIhCobDh4yFvj16vh9PpxN69e/HYY49Bp9NBp9OxQkO5XA4vvvgiZmdnMTs7y87ir2dDa/LG+Hw+JBIJS6394Ac/iG3btrFWG16vF5FIBCdPnsSpU6cQCAQwNzfHClwMDg7iD//wD2GxWDAwMMDOaNfrdfj9fng8HpYKRjYe19bM7XbjrrvugtvthlQqXXVeDLg6iU2lUnj++efxrW99C9FoFKFQiLViIZsH16OVa132+toJWq0WXV1d4PP5CIVCbLebnsOtKZPJ4OWXX4ZUKsVrr7224npyBcGi0SjS6fR1v4dIJIJKpcLg4CDcbjfsdju0Wi1bgKrVapienkYgEMDY2Bjm5ubWZYNvQ7Y36vU68vk8fD4f8vk8+0G9Xi8EAgHi8Tg7QyAQCJDNZhGJRBAKheD3+1GtVlGpVJDNZtl/u1wuhMNhWqVpQVzKlVwuh81mg8PhgF6vh1KpZCss3O52JBLB/Pw82wExGAxIJBKoVCpYWlqC3+9HOp1GKpWCSCRivasArEj5EovFbMWWvHVcjj+X59+M4FMoFMJgMMBsNkMsFqPRaCCfzyOdTq95pTWyfqRSKYxGIywWC2w224qzRsViEblcDsFgEH6/H/l8np7hTcbn86FQKFhRN7vdDrvdDpPJBOA3xd/m5+fh8XgwOzvL0vK5c0PLd8OA3xx1qVQqrNgJ3cPNIxKJWHszrVYLpVLJPlav19m1qtfrLNhcXFyE1+tlmSfc6wOdG9w8uGvLZZa9fn4kl8thtVqRyWSgVqvZgi8Fn62J6wJRKBRQr9dX3ItcL843O74iFotZAaFarbZq0bfRaCCXyyGdTiOXy61bBesNe4pkMhmcO3cOYrEYV65cAY/HQzqdhkwmg8PhQDAYxM6dO2G1WnHx4kUcPXoUV65cQalUYr+YXC4Hn8+HcDiMmZkZVKtVap3SgsRiMWw2G9ra2vD444+ju7sbbrcbMpmM9R5aXFxEKBTCL37xCzzzzDMsJYirqBeJRHDixAkkEgnMzMygUqlgcXERVqsV6XQafD4fnZ2dbCeU6zUWj8eb/eNvOjweD0ajEVqtFmazGVqtFuFwuCnj4ApYcGfH5ufncenSJbqum4jD4cDBgwfR398Pg8HAFjRyuRzm5ubg8Xjw6quvYm5ujp7fLUCpVGLPnj1wOBz4vd/7PbhcLlitVohEIng8HkQiETzxxBN4+eWXEY/HEY/HUalUWOrW6Ogotm/fju3bt0OtVrOFwHQ6jXA4jFOnTuHcuXPUY7uJ5HI5du7cyVqbcRqNBlKpFAqFAkKhEOLxOI4ePYpjx47B7/cjEomwgEUqlcJms8FsNlMAugk0Gg1WxO3cuXMAgAMHDkCv17PP6enpgdlsxvnz51EsFrG4uIilpSVaKGphXJCZSCRWbRI0Go033YBRqVQYHh5Gf38/tFrtqgKw3N9NLBZjKbfrsRixYU+QarXKggYuha5YLEIulyMajSIajbIU2kKhgFQqhWKxuGI1tV6vo1gsolgsvuG2Mmke7tyQXq+H2WxGV1cXuru7WXEhbiUunU5jaWkJi4uLmJmZgdVqhVgsZjtwoVAIV65cQT6fRyaTYX8HcrmcrcJwOyp6vZ61BSFvj0wmg0ajYT38lp8B2ghcixVudZ0LPnO5HJLJJL0YbhI8Hg9KpZKd7+b+lhqNBiqVCqLRKMLhMGKxGFU+bTIu1Vaj0cDhcMDtdqOnpwcOhwPlcpkVC/T7/Zifn8fMzAw7n8+RSqWwWq0wm83s+QFcfa1OpVKIx+Os4CAdkWke7vnK5/NRLBZZxgGXppfNZuH3+9nC/sTEBDuHzeH6L3MV6knrq9VqLHPB6/WumiNxfXuDwSC0Wi1isRhd202g0Wi85d1I7mynQqGA2WyG0Whkc+7Xnw/l5l3LN//W2oYvX3EBJPCbCH75w5DH46Gvr4/1Jrpw4QKlAGwSEomE9X+799574XK5YLFYIJVKWcoHlxJw7tw5XLx4keWTB4NB1h9OIpGgVCohkUiwv5Fr4VZfd+zYAaFQiGeeeQZ+v38jf+Qtgc/nw+12o7e3FzabjT2QNopAIIBCoWC9PbmgpVqtIpPJIJFI0MR1E+AqWHd1deHgwYOsjHu1WkWxWEQgEMDTTz+NhYUFWjxsAWazGQcPHkR7ezve8573wGw2w2AwoFwu48yZMwgEAnjmmWcwPj6OxcVFluq1nMPhwHvf+17Y7fYV5wHT6TR+9rOfsZ3uTCZD6dVNFIvF8L3vfQ8WiwV33nknNBoN5ubmkEqlEA6H2XM2m82ymhuv30ERCoVQq9U33K2AtIZarYaTJ09iYmICIyMj2L9/f7OHRJrAaDSiv78fTqcTBw8ehNVqhVqthkgkWhF8VqtVHD16FEeOHIHX61238TQld2L5Q42rZlosFtmZA61WC5fLBa1WC6FQ+IYBCGkdQqGQpc92dHSgra2NpVBy1ziZTCKXyyEUCsHn8yGVSqFWqyGfz7/lghRcjzmTyQS32w2NRrNOP9nWp1arYTKZ2PXiSnRvxMIPF3xy/Vu5lfU3OqtCWgtXeEatVsNgMMBut7MU+1qtxhrVz8/Pw+v10mJCE3Fn8tVqNXp7e9HR0YHBwUFotVr2LOYKCo2Pj+PKlSur7kGuyqlarUZHRwf0ev2K653L5TAzM4Pp6Wmk02nq39pkxWKRFffiJp2XL19GLBZDOBxGNpt907NiAoGA1Veg3bHNo9FoIBKJIJFIIJVKsdd2uoZbG/eM5ioe63Q6uFwuOJ1OuFwudiTm9Sm31WoVoVBo3QoNcZqeuF8ul3H8+HFMT0/DYDAAuJqT3NfXh4GBAQwODrLUH9KauJQem82G973vfWhra8P+/fuh1WohEomQTCbx1FNPwePxwO/3I5lMsrS7RCLxjv9thUIBvV6/qpIbuTFcU3mr1coKUWQyGXat1jsA1ev1eOihh9iChUKhQCqVQiqVYhMiCj5bl1KphEwmw+23344DBw5g27ZtKyY2sVgMx44dw+zsLC5duoRYLEbBZxPZ7Xbs3r0bPT09ePe73w29Xg+xWIx8Po/5+XlEIhH84he/wNjYGBYWFlAoFNj9x01mjEYj7HY7+vr6YDQaWXuVZDKJ48ePw+v1sh7cdK63+bgzuMViEc8//zyEQiFSqRRb3LuRFhtyuRwdHR1wOp105nOT4haWAVBG4RbHBZmdnZ0YHR1lm0JKpRIWiwUymWxFX95arcbqpmSzWVaMaL00/QlSrVbh8XgQDoexuLiI9vZ2aDQamEwmWK1W2O121vNz+U4M3Titgws+NRoNhoaGWB8xmUyGXC6HXC6Hy5cv4+LFi1hYWEA8HmdV89ai/L5YLG5ab8qtQiaTQaVSsdS5YrHIClGsB+4FkDsjODw8zHavxWIxCoUCmyxVq1W631sYV3W6v78fd955J4xGI1td587tzszMYGZmBqFQiFJum4wrs88t8MrlclQqFeTzeSwtLcHn82FsbAyXL19e1XtVIBBALBaztmdmsxkKhYL16c7n85iensbc3By8Xm9TCpeR1RqNBkqlEkql0nVrIyxvsXWtXTGxWAyDwQCNRrNqt4RsbrQLuvm82f2q1+vR0dGBXbt24e6772bZbdxO6HL1ep3V5eHO53Ptz9ZLS8zWq9Uq8vk8XnnlFQQCATzyyCMwGo0YGBjAhz70ISwuLmJ6ehq5XI6dRxgfH6dUnhYhk8lgsVjgdrsxODjIWmWk02n8/Oc/x8LCAo4fPw6fz4dMJoNiscgOOVMhmdaUTqexsLCAWCy2Zg8grqCQWq2G3W6HTqdDV1cX2trasHfvXhgMBnY++OTJk/B4PPB6vSgUCnRerEXxeDxYrVa4XC50dHTAbrdDJpMBuLp7HgwGcfnyZbzyyisIhUK049lEXODIZabY7XaIRCIUCgVWLfx73/se5ufnsbi4uKLKIbe7vXPnTuzcuRM2mw0dHR2w2WyQSCTI5/NYXFyEx+PBiy++iEAgQDuemwiPx0NXVxccDgcEAsE1F3Lb29vhdDphMpnA5/NZO7RQKASPx4OFhQXq5boJXOv1nBYQNgeBQACVSgWZTIaenh42l1pewZrT09OD7u5utpEnFotZr20ArG1hNpvFyZMnEY1GMTY2hmg0yjpMrOdxx5YIPrkznZcvX4bX68WePXtYL0+z2Qy/3w+Xy4VYLIb5+XksLCxgamqKdkRahEQigdFoZJNQnU4H4Ooq+NGjR3H58mVMTExQdctNhOu1u5YTSG7yq9Pp0N3dDYfDgdtvvx0mkwn9/f2QyWQQCoUoFouYnJzE5cuXqT/gJqDT6eB2u2Gz2WAwGNiLG9fb2ePx4NKlS1S1uMm4+89gMGBoaIjVVCgUCggGgyxwnJubW/F1PB6PVcPesWMH3ve+98FsNsPpdLLPKRaLmJ+fx9TUFM6fP49oNLqu54XI2uLxeHA6nRgZGYFYLF6RjsexWCwwmUzQaDQQCoWoVqusJ2goFMLS0hLV5mhxy3ezaO68+QgEAiiVSmi1WoyMjMBqtWJ4eHhF+xzg6v3Mne/kvP56cxXoU6kUTp06hcXFRZw5c4a101rvo04tEXwCV38R2WwW1WoVr732GkQiEYvcrVYr5HI58vk8BgYGMDMzg3w+z4JRrpgNPfiaw2w245577kFfXx8kEgkqlQpLo56fn4fP51vTiQiXbsAdml+efkDWhkgkYsHgtQiFQjZ5BcAKPykUihVnCQQCASwWC+sNxzWlNxgMbJLDFSmp1WoQCASs/H8gEKAJbIvi8Xiw2WzQarXYv38/9u3bh87OTgBXdzyTySTGxsbwy1/+EgsLC8hkMiiXyzThaSLueAR3TIFrf5VOp/HSSy9hbm4OlUoFGo2GpcBzxWksFgt0Oh2Gh4evudKeyWRw+fJlzM3NrWtvOPLOCYVC8Pl8aDQaSKVS9Pf3w2KxYPfu3ejr62Pnepe/zjYaDSgUClbVuFgsIpFI4Ne//jXm5+cRjUbpehOyTkQiETQaDcxmM+6//35YLBYMDAyw93HZRsu9WQHOUqkEv98Pr9eL8+fPY3FxEeFweMMyzVom+ASAXC6HfD6P1157DdFoFL/1W7+FoaEhqFQqtLe3s8/r6OhALBaD1+tFOp1mB+cp+GwOq9WKQ4cOwWw2szYpgUAAXq+XBZ9raXmwufwFj8q/rx2RSMQqG16LUCiE0WhkE1ixWIyhoSEYjUbodDrI5XJ2tmBkZASjo6PsutVqNVQqFSSTSczMzAAACz65amuRSAThcJiCzxbF5/Nht9vhdDpxyy234O6772Z/K9lsFl6vFxcuXMDPf/5zZDIZZDIZmpw22fJeujKZjJ3TzGQyeOmll7CwsIByuQy1Wo3R0VE4HA7s3LkTbW1tsNlsrDDR8mcCd00zmQzGxsbg9XpZ2zTSerhKxyKRCAaDAXq9Hvfccw+GhoYwNDS0Yp61/HV2+dyqUqkgkUggHA7j+eefx8zMDAWfhKwjsVgMo9GI7u5uPProo3A4HKxP5/W82YZMuVyG3++Hx+PBhQsXsLi4uNbDfkMtFXwCV1/MuAfZq6++ikqlAqfTid7eXigUCuh0Omi1WuzduxcOhwP5fB6RSASXLl1i5wkpCN0YKpUKer2enQPRarXg8XgolUrwer3s3NBaW/4i12g0kMlkEI1G6bzJO1Cr1VCtVtm9097ejrvuugv9/f3o6+tbNbGQyWRob29nwadAIIDVamXFR7j02XK5jHw+j7GxMRQKBeRyOWSz2RWNzS0WC1wuF8RiMer1Our1OrLZLBKJBJ3rbjFcCqZMJsOePXuwc+dOdHZ2rmhWXS6XkUqlkMlkkM/n17VRNblxXAGoSqWCYrEIkUgEsVgMvV6PRx55BLFYDLVaDUKhEN3d3dDpdHA4HKwIGLfAW6lUIBKJIBKJUKvV2PVeWFjA0tISBZ4thsfjsbP2SqUS+/btg16vZ9XNBwcHYbVaIRKJkM/nkclkkM1moVarodfrWcuG139PsVgMp9OJSqWCdDpNGwCEbJAbyfhb/rFrtdbh7t96vQ632416vY5IJLJhdRlaLvgEAL/fj0AggHA4jJMnT+L222/Hww8/zNK8TCYT7rvvPoTDYYhEIiwuLiISibCG5nSuaGPodDoMDg6ip6cHDocDcrkcfD4fhUIBk5OTmJubW5dqqdwkivvvZDIJn89HBS7eAW43ktt9HBgYQHt7O7LZLOLx+DWDT5fLxXpycteEO8RerVaxtLSERCIBv9+P8fFxLC0twe/3Y2lpCZOTk6yi7sjICN7znvdArVazFNxEIoFIJNKk3wa5Hh6PB5VKBZ1OhwceeAAPPvjgqhfBYrGIeDyORCLB0m1J83FZBVyRCW4HzGKx4M///M9XnAV7/TVNp9MrFvcUCgVEIhGq1SpyuRyi0SjGx8ffcesssra4hUGpVMoyFT72sY+hq6sLOp0OYrEY1WoVtVoNxWIR6XQaXq8XXq8X7e3trIr863t78vl8SKVS9PX1QSqVstT6jeoNTcjN6o0q3F7vc4HVZz7lcjnb1BscHIRAIEAul7u5g0/g6i8qn88jHo9jZmYGr776Kux2O1KpFPR6Pbq7uyGTydDR0QG5XI69e/ciEAjgxIkTiMVizR7+TYFL4eHOkABX88i5Ha1AILAmE08+nw+JRAKXy8XOGzUaDaRSKeRyOUxOTuLChQtYWlp6x//WzajRaGBubo5NUhqNBpuYlkqla6a+1ut1RKNRAGCluXO5HMrlMpLJJAqFApLJJHK5HDvAnkqlEIvF2K6YSCRCW1sb7HY75HI5RCIRisUipe21MIFAgPb2drS1ta1qucCJx+MYGxuDz+ejnZAWwu1ahkIhHD16FG1tbdi1axekUik7e10oFFCpVBCPx1EoFBCJRJDL5ZBOp1EoFFgRC+6sdy6Xw+LiIpaWlqgXb4vhXjcNBgOMRiMOHDgAh8MBi8UCqVTKajHE43HkcjkkEgmk02mk02lWHKytrQ0ymQxisZhNXvl8PsRiMVQqFQYGBqDVajExMQEALAOJ7vvWtLzP53JSqRQmkwmxWIyOL7Ugrg1KIBDAq6++CqvViq6uLkilUiSTSdYaZfl9x11rbmNApVKx1lg2m421W+EWGjf6urds8AlcXW3NZDKIxWI4d+4c7HY7tm/fjpGREfzRH/0RVCoVbrnlFuTzeZjNZlbghoLPjcEVrxCJRBAIBKxoVCQSwfnz5zE/P49cLveO/o3lPUTvvfdedHZ2wmg0ol6vw+fzIRQK4fnnn8cLL7xAabdvU61Ww9GjR3HixAn4/X7Mzs6ira0NDocDwLWr4vF4PCwtLaFQKLAKaVwrHY/Hw3ZL3+jNbrdj37596Ovrg16vh1QqRTgcRiKRoOCzRYnFYuzduxdDQ0OwWq3X/NuYn5/H008/vSEV88iNq1arqFarGBsbw1e/+lVs27YNbrcber0eAoEA9Xqd7VafPXsWwWAQx48fh8fjQaFQQKlUwm/91m/hfe97H4RCIZusnj59GhMTE3TPthDudVOtVmNgYAC9vb34i7/4C9hsNnYk4tSpU5idncXExATC4TA8Hg9CoRCkUikkEgnS6TQGBweh1+uhUqlY0MLn86FUKqFQKHD//fcjmUzC6/VCo9Hg7NmzLPOFAtDWxAUky6nVavT09CCTyVDw2YJKpRKCwSDi8Tii0Sj0ej1uv/12KBQKXLlyBbFY7E1bo3R0dOC2226D2+2G0WhkwWezMhVaOvgEftOLhluZW1hYgNlsZpMaLgAyGo0ol8swGAzQarXI5XJ0XmyDcSss1WoVhUIBhULhHb0AcefL7HY7LBYLenp64HK5IBAIUCgUEAgE2GJDoVCgie47wBX8CYVCmJqaQiwWu6Gd5FKphKmpqRXnbrldkjcjEolgMpmg0+kgFApZldtIJEL3botZ3m7DZDKx3ZPlL1xcwbhYLIZkMkmLQS2qVCohGo1ifn4eL7/8MtRqNWQyGWq1GrtuU1NTiMfj8Pv9iMfjrAKqXC6HVquFVCoFcDWgzWazKBaLlG7ZIrjUeJvNBqvVih07dsDtdkOtVkMoFLJq1AsLC5ibm2PXOJfLoVarwWg0oqOjA+3t7VAqlWzXk9sJB8B2yzUaDWQyGXp7e9nuOdd2JZ1OszZ6HO68MWktUqkUVqsVZrMZKpUK9Xqd7ukWwx2b4NLb5+bmIJPJ4Pf7kUql3nTxTywWY3JyknUUaPa1bfngEwA7k+Dz+RAMBiGVSlEqlaBQKFjw2dHRwVb5yuUye/EkG4frG1QqlZBKpZBOp9/2HzhXJMFoNOKBBx6A2+3Gww8/DIPBgFwuh0gkgmPHjuHChQvweDz0grZGuJ6s3GTzzXAPxOVnPm90EUCpVKK/vx/t7e1sNf7y5cvweDzIZDLv9Echa0goFMJms8FisWBwcBDDw8PQarUrPicQCGBmZgbj4+MIBoPUh7lFZbNZzM7OYmFhAcePH19V1ZS7p7mFxEajAbfbDYvFgo6ODgwODrKvKZVKiEQiSCaTtNPVArgdT5fLhfe85z3o7OzEu9/9btaYvlgsYmpqCn6/Hy+88ALGxsaQzWZRKpUgk8mgVqtx77334vDhw7Db7XC5XACu/l2EQiE888wz4PF4aGtrg1arxc6dO6FQKPD+978fpVIJly9fRigUwosvvogrV66wNnicZDIJv99Pz4Um4e7v1//+9Xo9du/ejXK5DIfDAbFYjEAgQNkMLaZarSIejyOZTCIUCrHuATfy7A2Hw5idnUU8Hsdv//ZvQy6Xb8CIr6+lg0/u3JlUKmU9B8ViMSwWC6usyOGqdXJn1GgXbONVq1UWdL7diSe3mCCTyaDX6+FwONDZ2Qm73Y5Go8HOeEajUVZdkXZY1g6XmrcR+Hw+RCIROz9Wq9UQi8UQiUSoSE2LEYvF6OzshMPhgMFgYAt/wNWS7ZVKBcFgEJOTkwiFQhR4trDlfXVvpLgE9zrLVbgVCoVsArs8+KTr3XxKpZJVoO/o6IDD4YBKpYJAIEAwGEQqlcLU1BQCgQASiQQ7FiORSGCz2WA0GuF2u1klXG5nOxwOY35+nrXGyuVy0Gg0UCqV7H8FAgG0Wi34fD56enrY4kS5XGZ/bx6PB4FAgP5WmoCbP4XDYcjl8hXBB5/PB5/Ph0KhgNVqRb1ep8rVLWr58/ut4p7fN1KsaL21dPCp1WrZw3BgYAA6nQ5OpxNtbW1QKBQsN71SqbBKmhMTE5icnNywik3kN9LpNM6fP4+pqam3/fvnGlm7XC4cOnQIbW1tOHDgAAQCAaamphAKhfDVr34VU1NTyGazbOJLNr9isYhLly5hcnKSdj5bjFarxR/90R9hZGQEFouFVbYGrq6oRqNRPP300/jhD39IPT23IG7hl8/nr9g5CYfDOH78OJLJJE1Um4jbie7p6cGhQ4cwMDCABx98kPUBDAaD+OlPfwqfz4djx44hGo1iaWkJxWIRDocDOp0O73nPe7Bv3z50dnaio6MD+XweoVAIFy5cwI9//GMEg0FcuHABjUaDnfkcGBiAXq/H3r17YTab0dfXB7vdjt7eXrbLVq/XWdGqJ598EhcuXKBd8iZoNBoYHx/Hs88+i9HRUQwPD6/6HIPBgIMHD2JmZgazs7M0j95CdDodRkZG0NnZeUNZbeutpYJPrik9V13NbrfDbrfD7Xajs7MTWq0WTqeTFUjgcOcRCoUCS/Ogyc/GWV4pi1tBe6skEglkMtmK8yYdHR0wGo0QiUQol8usBLzX60UgEFjrH4M0WaPRQLFYfMdnhcnaEwgEMBqNLPBcXqwgk8kgFAohHA7Ted0tqlKpIJ/Po1KprHhtrdVqyOfz9JrbZNzrp9lshtvtht1uh0qlQq1WQyQSQTAYxOLiIgKBAKtGrlarodVq0d7eDpPJhPb2djidTkilUmSzWcRiMVZXYX5+HtFoFIlEgs23stks5HI50uk0jEYjstksO7+vUqmgVCrZ+MrlMkqlEi1QNFkul2M1Mq5FKBRCqVRCJpO1xO7YzY5b9KvX6yiXy2+rlZFYLIZUKmUbeWazuSWKSrVM8Mnj8aDX66FQKLB792709PSgr68PPT09UKvVMBqNK1ZfuVQ97lxKJpNhh27pRXDjLH9AcWdAuD/2t6KjowO7d+9GX18f7r33XqjVaphMJuTzeVy4cAE+nw//8i//Aq/Xy1p8EEI2BpeSpVQqV/UOu3LlCo4ePYqJiQkKQragRqMBn8+HcDiMUCjU7OGQa3C73RgdHcVtt92G9773vZBIJKjVapifn8cTTzwBv9+PEydOoFgswmg0or29HTt37oTVasXw8DCsVisMBgNUKhXOnz+PixcvYnp6GufOnUMsFsPCwgLrAw1czVIpl8sYHx+HQCDA5cuXIZFIcOutt8LpdGJkZISdFwWAEydO4IUXXoDP56MAtEm4nuh+vx/pdLrZwyFvgDu7rdfr0dPTg1wuh5mZGZbp91ZeYx0OB0ZGRrB9+3Y88sgj0Gg0b3l+vh6aGnxyqSJisRhCoRAGgwF6vR5utxs9PT3o6upCV1cXZDLZilU0riACt+rKtfeIRqO06t5EQqEQGo0GWq0WarUaSqUS5XJ5xSF3rico155FIBCAz+fDZrOhs7MTXV1d6OjogFgshlgsRqFQQDgcht/vZyu3ZOvhVuK4vwladW0NXNCpVqvZc/r1u9LpdBrBYBDpdJp2rLcoLmCgWgqtSavVsj7YJpOJdQmoVCqsrzJwdYfUYrGwXul2ux3d3d2sg0CtVmO91WdnZzEzM4N8Pr/qGATXU5D7u0in0xAKhZibm0OxWIRKpVrx+R6PB9PT0++oCCF557LZLBKJBPL5PGq12qpMNa6iNdd3m8/n0zN9A3GFHpdnMjidTiQSCSwuLt7Qwg03dxIKhSyAbW9vZz2aJRLJimvOzc03+jo3LfjkekXJZDKMjIzAZDLh1ltvhdvthtPphNFohEKhWHG2iMO12VhaWsJLL72EcDiMU6dOsX5TZOMsfyERCARQqVRwu934wAc+AJ/Ph7Nnz7Ly/fV6nTWn7+/vh8vlgl6vh06ng8lkgsPhgEAgQLlcRiKRQDAYRDAYxK9//WuEQiFks9km/qRkvXELUBaLBXNzc80eDgFgNBrx/ve/n/XX5VLsufuex+MhHA5jcnKSqotvYQ6HAxaLBVartdlDIdfQ39+Pw4cPw2w2r+jHaTKZcP/997OdSqFQCIfDAblcDo1GA4lEArlcDqFQiLNnz2JiYgIvv/wyXnnlFXZO80YXHGq1GiYmJuDxeHDx4sUVuyvJZBLxeJx2PZuIO/Pp9XrhdDqxa9cuVjCKYzQacejQIdhsNjz99NPg8Xh03TaQ0WiE1WpFb28v9u7dyzITLl++jIWFBXas5Y3uSYlEApFIxOrj7N+/H+95z3ug1+shk8lWHJmpVCosJf6t7qi+UxsafC5/KAqFQrY75nQ64XQ6MTQ0hK6uLuh0ulU7nfV6HbVaDZVKBZlMBktLS/D5fKy09+XLlyk4aRLu+vD5fEgkEiiVSnR3d0OhUCAYDEIkEiGbzaJarbKKegMDA+ju7obFYoHZbIZcLodKpWJnEtLpNDvb6fV66SzZTYDP50MqlUIqlbbEmYSbHZ/Ph1wuR09PDzo7O1eVZq9Wq6wHcyqVonZHWxSPx4NCoYDBYGiJdC2ymkajgdPphFwuB4/HQ6PRYL15HQ4HGo0Gm5SaTCaIRKIVrbHy+TwCgQCmpqYwNzeHxcXFt3y+rNFoIJVKAbhaiIq0nlQqhVQqhVgshnw+zwpScaRSKWw2G6LRKORy+apdMrK+5HI5O7e9bds2WCwWDAwMsDPa3Pn6N1oMUCgUbNeUq53S1dW1qrNArVZDoVBAPp9nWRIbufu5YcGnUChkf8wGgwEGgwEPPPAA2tra0NPTA61WC5PJBIVCseqGSKVSiEQibCctHA7jwoULyGQy8Pv9q3pJkebh8/lQq9W47bbbkMvlMDg4yJrP12o1tvPJLTBIpVKIxWLWey4ajWJubg4LCwt49tlnkUwmsbS0hHK5TO03trhGowE+n08pty1AKpXCbDazvo4ulwtSqZRNViuVCi5dugSfz4fJyUmk02mqjLiFqVQqmM3mFYvCpHUUi0WkUinweDyoVCq2wK9QKFjwKRAIUKlUMDc3h1wuB5/Ph0wmg5mZGZZq6/f7EYvFKNVyi0un0/D7/QDAMlqA32SyUWp0c4yOjuKRRx6B0+lEX18fZDIZ+Hw+DAYD7rnnHiSTSeRyuevenzweDy6Xi6XrOp1OGAyGFRmk2WwWXq8X8XgcZ86cQTAYxJkzZxAOhze0beG6B59cmpZYLGZptFarFTabDfv27UN7ezvsdvuqVfXleci5XA6RSARzc3M4efIk+2Vx1Z9Ic3DnPl5/DSQSCRwOB+r1OkwmEyqVCqtg+voJDHed4/E4lpaWsLS0hPn5eUxPT+PMmTPXrcpGthbuYco9LygAbS4uM4VbFDQYDKy/I3fWy+/3Y2pqCpFI5E1XY8nmJhKJWHomaT3lchnZbBYSiQTVapXV0+DO8AFg2WPRaBTRaBQTExOIxWI4e/YsAoEA4vE4MpkMBZ43gWKxiGQyCb1eDwArjlG8nYqqZG2YzWZs27YNer0eFouFvV8ul6O3txfZbBbFYvENg8/e3l44nU5YrVZ2TGJ5PFUsFhEOhxEIBHDu3DmEQiEEAoENL0K1bq8kXGVal8uF22+/HSqVCna7HQqFAjabDSqVCr29vVCpVKt2OqPRKFKpFDv07vf7MT09jXg8Do/Hg0KhsOH5yWS1bDYLj8cDq9WK+fl5aLVaWCwWtsLC4/GgVCpRq9WgUCjQaDRY2ha3ze/3++H3+3HhwgW8/PLLyOVySCaTSKVStNN5kxGJRHA4HCiXy5Te12RcCrRCoYBKpWJ9lRuNBrLZLNLpNF555RUcPXqUFUKgSevWFY1GMTMzg2QyuarXJ2m+kydPolAooK2tDX19fSxNmptsZjIZTExMIJ1OIxAIIJ/PIxaLoVgsIhqNIpfLoVQqXXMxmWw9CwsLePXVV9FoNDA8PEyLvS1Oq9XilltuYec9r3eP8ng8aDQattEHXJ1rc4sNXq8XHo8Hv/jFL5BIJFg81YxNnnUNPqVSKZxOJ+68807WR0qhUMBisVx3BbXRaCCdTiMUCuHixYs4fvw4FhYWMDk5iWq1Suf+WkihUEAkEmH9/YCrKRzLe35KJBL2+ctvGO6GCAQCuHLlCo4fP44nn3ySXvhuYlzBoUwmA5FI1Ozh3NS4bBWu6h7X942bzGazWUxMTOC1115r9lDJOuNek4PBIKurQJPV1jIzM4PFxUW43W6EQiFW4bJWqyGZTCIWi+GFF15gaXvVapXa0t3EotEoxsfH0d3dzc4Hk9bALewtvy5c7YW3gvvaarXK5uqTk5O4cuUKnnvuOWSz2aZu8KxZ8KnVaqFSqeByueB2u6FWq2GxWOB0OrF9+3bI5XKo1WpWvnm5Wq2GarWKmZkZhMNhnD59GpOTk1hcXMTCwgIymcyGH4Ylb65cLiOVSmFiYgL/8R//AZvNht27d8NoNGJ4eHhVKnW9Xsf09DQikQg7XzI/Pw+v1wuv10svhDcxPp9PbRwIaVHpdBqVSgWRSASxWIxVSRWLxdDr9Wg0GshkMvQMbxIu5X1paQnnz5+HVCrF5cuX0Wg0WE0MbqeTm0vRtbp55XI5hMNhhMNhLC0tsXZapLnGx8fxxBNPwO12Y2RkhLWevJGiT1wwycVTyWQS6XQaPp+PxVbcMZl8Pt/0YzJrFnyq1WoWfNxxxx2s0pJcLodOp3vDlZVarYZyuYzJyUlMTEzgV7/6Fc6dO8dSM0lrqlQqqFQqrFCQw+FAsViE2+1Gd3f3NYPPubk5TExM4OjRo7h8+TLi8Ti1aCAAaDeFkFaVzWaRzWYRjUYRj8eh0Wggk8kgFouh1WpRKpXo/m2ier2OcrmMSCTCspAIuR4u7ToWiyEej6PRaEClUtE93GQzMzPI5XIYHh4GAHR0dMDlcr1p8NloNJDL5VgAWq1WsbCwgMXFRZZZmEgk4PP5WmbRac2CT5PJhO7ubvamUqmgUqkgEonA4/FQrVaRzWaRz+cRDofZmc1KpYKpqSnE43GMjY0hFArB5/O9aS8b0jqq1Sry+TyWlpbw2muvsVUWLlWPU6vVMDk5iUgkgvn5eSSTSapSfBPL5/NYWFiAUCikFLAWU6lUkEwmEY1GEQgEIBAIYDAYWI8wcnPyer04efIkent7odfrYTKZsH//fszPzyOVSiGfz1PRGkJaXKlUQjqdxrlz5/Dtb38bMpkMarWazdcCgQCrhkzz8I3DxUcTExOoVqtwu90oFAowmUzo7++HWCyGSCRCrVZDMBhk6bT5fB5zc3OshU6pVEIymUQikUAoFEIkEkGhUGipOdaaBJ88Hg82mw3Dw8MYGRm55gFmblUuHo/j9OnTyOfzqNfryOfzeOqpp7CwsIBcLkdFZjaharWKTCaDTCYDn88HHo+HH//4x2/4Na10E5DmyOfzmJ6eZi0AqJJm66hUKohGo1Cr1VhcXGQtHGQyWbOHRprI4/HghRdeAADs3LkTNpsN9913Hy5fvozp6WlWvIaCT0JaF5eKffToURw7duyan0NztI3HzaOXlpZw6dIluN1uRCIR9Pb2wmq1QqPRQCgUolwuY3Z2FpFIBBcvXkQ0GsW5c+fg9/uRTqdXtExp1eu4JrO9RqPBenCm02l4PJ5Vn1MqlZBIJJDL5eDxeFAqldBoNFAul9lZBFph2Rpa9Y+dtJZ8Pg+Px4NisYjvfe97EAgEuHLlCqLR6IaX/SYrcQ2oI5EIXnzxRZhMJpw9exZisZi9QHJ94sjNI5lMsnP6gUAAtVqNNUUfGRlBMBhEPB5HLpej13NCNgGar7Ueri1SKpVifbS5tkkSiYT16+XOdKbTaUQiEeRyuU3TCYTXuMFRvlkuONeb74169HH/1OtXRVvt8HsrjWUj3Uz5/nSNWwP3vODSOblnwVpMXG/Wawys3XXmrg3XN5DDXaNW2OG6Wa9zM+5lqVQKqVSKBx54AI899hhsNhv6+voQiUTw2muvYXJyEv/n//wfRKNRFIvFNbs2dI23PrrGWx9d47f+dct79i63vCru8rdmu9ExrFmeGzcJodVOQsiNoudGa2s0Gk2vikdaR7VaRalUQiAQwKlTp+B2uyGTyVCtVmG1WpFKpaBQKFZUXiSEEPLWLQ8ot9qzlA5ZEUIIIeRNcf0huXZoo6OjSKfTcLlcOHDgAKRSKaxWK8rlMqXeEkIIuSYKPgkhhBByw8rlMiuMMTk5iUwmA7lczipkcjUdCCGEkNdbszOfW8nN+qJJ13jro2t8c6DrvPU1+xrzeDyIRCJIpVIIhUJIJBJUq1WkUinUarU13fWka7z10TXe+ugab30bfuaTEEIIITcHrlo9tUcjhBDyVtzwzichhBBCCCGEEPJ28Zs9AEIIIYQQQgghWx8Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1h0Fn4QQQgghhBBC1l3LBZ/ZbBaf/exn8cADD0Cv14PH4+Hf/u3fmj0sso4+//nPg8fjYXh4uNlDIWvkypUrePTRR9HZ2Qm5XA6j0YgDBw7gySefbPbQyBo5cuQIeDzeNd9OnDjR7OGRNUD38c3j7NmzePjhh6HX6yGXyzE8PIwvf/nLzR4WWSM0t976Hnvsseu+JvN4PPj9/mYPkRE2ewCvF41G8bnPfQ4ulwvbtm3DkSNHmj0kso58Ph++8IUvQKFQNHsoZA0tLCwgk8ngIx/5COx2O/L5PH70ox/h4Ycfxte+9jX88R//cbOHSNbIJz7xCezZs2fF+7q7u5s0GrKW6D6+OTz77LN46KGHsGPHDnzmM5+BUqnE7OwsfD5fs4dG1gjNrbe+P/mTP8GhQ4dWvK/RaOBjH/sY3G432tramjSy1XiNRqPR7EEsVyqVkEgkYLVacfr0aezZswff/OY38dhjjzV7aGQdfOhDH0IkEkGtVkM0GsXly5ebPSSyTmq1Gnbt2oVisYiJiYlmD4e8Q0eOHMFdd92FH/7whzh8+HCzh0M2CN3HW0s6nUZvby/279+PJ554Anx+yyXEkTVAc+ub06uvvoo77rgDn//85/E3f/M3zR4O03JPGYlEAqvV2uxhkA3w8ssv44knnsA//MM/NHsoZAMIBAI4nU4kk8lmD4WssUwmg2q12uxhkA1A9/HW8t3vfhdLS0v4/Oc/Dz6fj1wuh3q93uxhkTVGc+ub03e/+13weDz8zu/8TrOHskLLBZ/k5lCr1fD444/jD//wDzEyMtLs4ZB1ksvlEI1GMTs7i7//+7/H008/jXvuuafZwyJr6Pd///ehVqshlUpx11134fTp080eElljdB9vXc899xzUajX8fj/6+vqgVCqhVqvx8Y9/HMVisdnDI4S8TZVKBT/4wQ+wf/9+uN3uZg9nhZY780luDl/96lexsLCA5557rtlDIevoL//yL/G1r30NAMDn8/H+978fX/nKV5o8KrIWxGIxHnnkETz44IMwGo0YGxvDl770Jdxxxx04duwYduzY0ewhkjVC9/HWNT09jWq1ive+97346Ec/iv/xP/4Hjhw5gn/6p39CMpnE9773vWYPkRDyNvzqV79CLBbD7/7u7zZ7KKtQ8Ek2XCwWw9/+7d/iM5/5DEwmU7OHQ9bRJz/5SRw+fBiBQAA/+MEPUKvVUC6Xmz0ssgb279+P/fv3s///8MMP4/DhwxgdHcWnPvUpPPPMM00cHVlLdB9vXdlsFvl8Hh/72MdYddv3v//9KJfL+NrXvobPfe5z6OnpafIoCSFv1Xe/+12IRCJ84AMfaPZQVqG0W7LhPv3pT0Ov1+Pxxx9v9lDIOuvv78ehQ4fw4Q9/GE899RSy2SweeughtFidM7JGuru78d73vhcvvvgiarVas4dD1gjdx1uXTCYDAPz2b//2ivdzZ8SOHz++4WMihLwz2WwWP/vZz3D//ffDYDA0ezirUPBJNtT09DS+/vWv4xOf+AQCgQDm5+cxPz+PYrGISqWC+fl5xOPxZg+TrJPDhw/j1KlTmJqaavZQyDpxOp0ol8vI5XLNHgpZJ3Qfbx12ux0AYLFYVrzfbDYDABKJxIaPiRDyzvz0pz9FPp9vyZRbgIJPssH8fj/q9To+8YlPoKOjg72dPHkSU1NT6OjowOc+97lmD5Osk0KhAABIpVJNHglZL3Nzc5BKpVAqlc0eClkndB9vHbt27QKAVQ3oA4EAANDRGEI2oe985ztQKpV4+OGHmz2Ua6Izn2RDDQ8P4yc/+cmq93/6059GJpPBP/7jP6Krq6sJIyNrKRwOs5VzTqVSwbe//W3IZDIMDg42aWRkrUQikVUT0wsXLuDnP/853vWud1G/wC2A7uOt7wMf+AC++MUv4hvf+Abuvvtu9v5//dd/hVAoxMGDB5s3OELIWxaJRPDcc8/ht3/7tyGXy5s9nGtqyeDzK1/5CpLJJFt5e/LJJ+Hz+QAAjz/+ODQaTTOHR94Bo9GI973vfavez/X6vNbHyObzJ3/yJ0in0zhw4ADa2toQCoXwne98BxMTE/i7v/s72hXbAj74wQ9CJpNh//79MJvNGBsbw9e//nXI5XJ88YtfbPbwyBqg+3jr27FjB/7gD/4A//f//l9Uq1XceeedOHLkCH74wx/iU5/6FEvLJZsfza1vDt///vdRrVZbNuUWAHiNFqwY4Ha7sbCwcM2PeTyelutXQ965gwcPIhqN4vLly80eClkD//Ef/4FvfOMbuHTpEmKxGFQqFXbt2oXHH3+8ZdNAyFvz5S9/Gd/5zncwMzODdDoNk8mEe+65B5/97GfR3d3d7OGRNUD38c2hUqngC1/4Ar75zW8iEAigvb0df/Znf4ZPfvKTzR4aWUM0t7453HrrrZibm0MgEIBAIGj2cK6pJYNPQgghhBBCCCFbCx3KIYQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7ij4JIQQQgghhBCy7oQ3+ok8Hm89x9FSGo1Gs4fQFHSNtz66xjcHus5bH13jrY+u8dZH13jro2u8Gu18EkIIIYQQQghZdze880kIIYQQQm4ufD4fAoEAUqmU7eLU63Xk83nU6/Umj44QstlQ8EkIIYQQQlaRyWTQ6XTo6enBBz7wAcjlcvB4PCwtLeHLX/4y/H5/s4dICNlkKPgkhBBCCCEMj8eDQCCATCaDVquFy+XCgQMHoFQqwePx4PF4oFAomj1MQsgmRMEnIYQQQghh+vr6sGfPHthsNgwNDcFqtcJms6FarWJ+fh6BQADlcrnZwySEbEIUfJJN7/WVxG7WimqthLsmPB7vuteDrhMhhLQW7tlttVqxZ88euN1u7NmzB1KpFEqlEqlUCslkEslkks57EkLeFgo+yabG5/Nx5513or+/n/3/c+fO4dixY00e2c2Fx+NBq9VCKpWira0NGo0GHR0dsFgsSKVSSKVSyGazSKfTbMKSSCQwPj6OSqVCkxhCCGkiiUQCsViMHTt2YPv27RgcHMTevXuhVquhVCpRq9UQDoexuLiIn/70p/B6vUilUs0eNiFkE6Lgk2xqfD4fu3btwrve9S62YlutVnH8+HHaWdtAfD4farUaKpUKAwMDaGtrw/79+zE4OAi/349AIIBIJAK/38+uy8LCAubm5lCr1Sj4JISQJhKLxZDL5dixYwc+8IEPwGq1wu12A7iapZLNZhGPx7G4uIgjR44gFAohm802d9CEkE2ppYJPHo/HdlCUSiU6OjrgdrsxPj6OU6dOUTBBGIFAgOHhYdhsNgwPD8PhcCAUCiESiSCfzzd7eDcNsViMzs5OaLVa3HbbbbDb7XA4HKxAhU6ng0AggE6nQy6XQ19fH7uPx8fHceXKFSQSCSwtLaFarTb5pyFk8xMIBBAIBLBYLNDr9ajVagAAqVQKrVbL2maoVCo4nU7U63VEIhGUy2UUCoU3vA+r1SrK5TKSySTC4TAKhQKSyeQG/WRkPSiVSkgkEoyOjsLtdmPnzp1oa2uDSqUCACwtLWFiYgLJZBILCwtYWFhAKpVCsVikRcNNQCAQYMeOHXA6nTCZTFCr1Th9+jTOnDmDcrmMUqnU7CGSm1BLBZ98Ph98Ph9GoxE2mw333HMP7rrrLvzoRz/C6dOnKfgkjFAoxM6dO7F9+3Zs27YNLpcL0WgUsViMgs8NJJFIMDQ0BJfLhd/93d9FT08PpFIphMLfPFr0ev01v9ZgMODIkSPw+/2IRqMUfBKyBoRCIUQiEdrb29HX14dqtYpqtQqj0QiXywWRSASpVAqr1Yrbb78d1WoVly9fZjtblUrlmt+X2/3K5XKYm5vDpUuXEI1GkUql6LV5k+LxeFCpVNBoNNi3bx/279+Pnp4eOBwOlkkUCoXw61//GvF4HHNzc0gkEojH4xS0bBIikQi33XYby0RyuVz4yle+gpmZGWSzWbqOpClaKvgUCoUQi8XYvn079u7di+7ubmi1WqhUKsjlcpTLZaqudpMTiUTo6uqC0WjE9u3bMTAwAI1Gg3q9jmQyCb/fT5OhDVSpVODz+QAA2WwWtVrthn/3RqMRd911FxYWFpDNZpFMJikIJeQd4PF47Kz1vn37MDw8zNLalUol9Ho9BAIBRCIR1Go1JBIJhEIh2traUCwWYTQa2U7ptZRKJZRKJTidTnR3dyORSGBxcRG5XA6hUAi5XA5LS0tsF5V2xloftxhhMpngcrmg1WpXfLxarSKfzyOZTCIQCCCTybzh3whpHQKBAEKhEHq9HlarFWq1GmKxGHq9nmWLUeYCaYaWCj65Mwf33nsvHnvsMeRyOeTzeeh0OqjVauRyOQo+b3ISiQQHDhxAT08P7r77bnR2dqJer7NiCJOTk4hEIs0e5k2jXC5jYmICsVgMiUQC5XIZUqn0hr62ra0N/+k//SfMzMwgGAzC6/Uik8lQ8EnI2yQQCDA6Oopdu3bh4MGD2LlzJ/vY8qrgy6tRA0B3d/cNfX9uYanRaKBeryOVSiEQCCAQCODEiRMIBoM4evQoUqkUyuUyBZ8tjsfjQSwWQ6lUwul0YmhoaFX1+FKpxNKsZ2ZmUC6XaXF3kxAKhZBIJLDZbOx4jEQigdVqxdDQEICrtRfoepKN1lLBJ4c7kyIWi1Gv1yGVSiGVSlEul9+wdQPZ+vh8PrRaLYxGI2QyGYRCIVKpFPL5PEKhELxeL63kbaBGo4FyuYx8Pg+PxwOdTofe3l4YjUbw+XzweDxUq1VUKhWWDsgRCASsfL/FYkGxWFzxcbL1SSQSCAQC9rei1+uhUCig1+tX7MAUCgXW4sHj8dDOy3XweDwYDAY4nU6o1WoIBIJVn1Ov19nZzTc7t1csFlGtViEWiyEWi9m1kkgkkEqlkMlkLK1+aGgIGo0G4+PjqNfriMVi103hJc3F4/EglUohkUgwMDCA7u5uWK1W8Pl89jmhUAjz8/O4ePEiFhcXEQ6H31JmC2m+Wq2GarWKQqGAfD4PpVIJ4GpQ+vrjMWRr4ubL3GusUCiETCaDRCJh7+cUCgWUSiVcvnx53TdxWvovj3s4ajQaqNVqVKtVxGKxZg+LNJFQKITdbkdnZydUKhX4fD6i0SiCwSAuXryI1157jVbbN1Cj0UChUAAAvPTSS/D5fDh8+DBL7xEIBMjn80in01AqlSsCCj6fD7lcDr1ej4GBAUgkEpw4caJJPwnZaHw+HxqNBlKpFCKRCCKRCDt27EBnZyf27t2L0dFR9rk+nw9jY2M4f/48vvnNb1LweR1c2u2uXbtgMpmu+Tm1Wg3ZbBbZbBaLi4vX/V02Gg0sLS0hm83CZDKxayWVSmEwGNDW1gaFQgGZTAabzYb+/n5MT0/j/Pnz4PP5LB2ftB4ejwedTgedToeHHnoId9xxB8xm84rPuXjxIr797W9jYWEBZ86cQbVapftuk6lWqyiVSojH4wiFQlAqlew+VqvVkMlkzR4iWWculwsHDhxgKdgKhQJ2ux1GoxG33XYb5HI5gKuvC36/H7FYDH/7t397cwefXPVbHo/HonayucnlcnbmQKlUIhKJIBKJoF6vv2HQKBAIoNFoYDKZ2Dnger2OfD4Pv9+PmZkZxGIxStlsklqthmAwCKFQiEQigXw+Dx6PB4FAgFqthkqlct2JS6VSYX8HtFOydQkEAiiVSnbeUCqVor29HQqFAhKJBCKRCH19fbDb7bDb7at2Ps1mM6vWSq6t0WjA7/fjypUrMBgM0Gq1qFQqK+4rLlMhl8vB7/df95nZaDQQi8VQKBSg0+mgVCrZgnBfXx8MBgOEQiHbPREIBJDL5TAajchms7Sr0sL4fD70ej1sNhsMBgM0Gg2q1Sri8Tii0Sii0SguXrwIr9eLaDRKvZg3Me4+9vl8sFqtAH5zxE0ikTR5dGStcHNrsVjMznFLpVIMDg6ir68PQqEQAoEAMpkMRqMRWq2WvQ4DV+dwBoMBAoEAQ0NDyOfzmJ+fRzQaXZfxbopXBwo6twY+nw+73Q6z2Yw777wT27dvx5NPPomnnnoKpVKJ7aBdi1QqxY4dO+BwONDT0wO73Y5isYh0Oo0XXngBL7/8Mubn5zfuhyErlMtlnD17FpOTk9i/fz8cDgfsdjukUimq1Spyudx1V1lTqRReeuklzM/PU9+4LUwmk7GghduZu+WWW2AymSCTySASidgLJPffnFqthlqtBp/PR8HnG6hWq/jZz36GV199lQXrXHXS5Z/DpdwmEok33M2q1+toNBps8VcikUAsFuPw4cNwuVxQKpXQ6XTs8xUKBUZHR6FUKnHixAk6AtGiRCIRRkZG0NfXh87OThgMBkxNTSEQCODZZ5/Fc889h3g8zlJtKfDcvKrVKs6fP49MJgOz2Yyenh6oVCo4HA5MTEw0e3hkDfD5fDgcDhiNRlgsFtbqzuFwoLu7G9u2bWPPcO6NO9q4/Hvo9XqoVCr86Z/+KaLRKL70pS/hF7/4xbqMeVMEnwBo53ML4PF4sFqt6OjoQEdHB5xOJwwGA+RyOer1+hsGnyKRCDabDU6nEyqVCiKRCMFgELFYjPp7tgjuTHY4HEYwGIRcLodMJkOj0XjD8yWNRgPFYpEKWWwxXEo1F0xqNBoMDAxAr9ezCa/VaoVer2cp2rlcDoVCAel0GpVKBaVSCfl8HtlsFrFYDIFAgCbCb6DRaCCdTrNz1plMBslkckUQyGUiVCoVpNPpt3TPqVQqdh9zrdGW/9tcSm8+n6fr1IKEQiFsNht0Oh3cbjecTidbIIxGo/B4PPB6vQgGg8jn89SGY4vgnp/FYhHA1WezwWBgcylucY+0puXBoslkYouz3POXz+ez11QuO5DLIFqeobI82OQsf/4LBALweDyWdXSjxSPfjk0RfHK/dKFQSAWHNjGRSIR7770Xd999Nws8z5w5A4fDgaWlJaTT6et+rVKpxL333ov+/n44nU6IxWK8+uqrOHv2LE6ePIn5+Xl6eLaAWq2G1157DfF4HAcPHsS2bdug1+vhcrmuWfwEuPpgff1OF9n8enp68Mgjj0Cj0cBut0OtVrM+sFKplBWcEggEbCfu4sWLmJ+fx9LSEiKRCGZnZzE2NsbabOXz+TdcpCJXMwnS6TQikQhLe3/9s7HRaLC3t6KtrQ19fX3o6+uDyWRi92yj0WBpm0ePHqUshhal1+vx53/+5+waajQa1Go1LC0t4cUXX8Szzz7Lzn3RPGtrqNfrCIVCKBaLbBHK6XTCZDLB4/FAr9ezugykNQmFQqjVajidTvzBH/wBLBYLjEbjimCSS6GVyWQs9VYkEiGVSsHj8UCj0aCtre0NN/G4I45isZi9Nq/bz7Ru33kNcA8/gUDA+pGRzYtraG0ymVjvVu5Gud615apzSaVS6PV6GAwGdk4hm80ikUhQC54Wwp0vkUql8Hq90Ol0EAgErCLmtQiFQpYeKBQK6VpuUlw6j0QigVwuh81mQ0dHB7RaLaxWK5RKJUwmE9vhLJfLbOetWCyiVCphfn4eHo8HwWAQ0WgUMzMzmJ2dZVUbyZvjAs21+n3xeDzI5XJIpVLYbDa0t7fDaDRCJBKxiUyxWEQkEkEgEMDS0tKbpvOSjcXdlyqVCi6XCx0dHTCZTJDL5azXYzweRyQSYf2aydZRqVRYZWvub0EoFEKlUkGpVKJeryOTydCCQ4vhAkGFQgGHw8HuXZvNtir45Ar3cVlEXNZLNBqF3++HVqtFo9Fgu5tc7QWBQLAqyOReb9cze2VTRHMajQZdXV1oNBqYnp5u9nDI28StjpdKJVaync/nQyQSXXeFRSKRwG63o729HRaLBXq9HkKhcEXrDkrHbh21Wg3T09NYWFhgq6rve9/78N73vpeV/H49vV6Phx9+GHNzc/jXf/1XSp/epLjV0pGREdxxxx0YHBzEoUOHIBAIUK1WUa1W4fP5kEwm8cILLyAajbIV+WKxiFqthkAggFQqxdJCKR27ubiJyYEDB7B9+3Zs374do6Oj0Ol0K567MzMz+Kd/+if4fD5cvHgRuVyOUjZbiFwux9DQENxuN/r7+9HZ2cla2U1PT2N2dhY+nw/lcpkCz5sAd4zNZrNhz5498Hg8iMVidO1bDBf7dHV14QMf+ADMZjN6e3tZoLn8GcxdUy4V9+mnn8YPf/hD5HI5pFIpyGQy1ueVO/P7wQ9+kLU14+bg9Xod0WgUS0tLyOVy6/aztWTwyaUDcb9YkUgElUq1rvnHZH1JJBIoFAqIRCLw+Xx2PogLQq+3wiIUCqHT6aDX61lRknq9zianlUqFJqYtplQqsTNE+XweyWTyDavdCoVC6PV6JJNJym7YxCQSCdRqNex2O/r7++FwOKBUKtnZwkKhwCppTk1NYWlpCT6fD4VCgf19cJWSSXNx/Ty56rYOhwP9/f3o6uqC2+1mExVuMTESiWB8fJwdn6Cq1a2D2+XgMoe4rCPg6jn9XC6HWCyGfD7/hrsd3C7M8gku8Jsz+3TGd/Pg5tYSiQRarRYKhaLJIyLXIpVKYTKZ2PP39YEih+u3zrVDqtfrWFhYwKVLl1AsFpHL5SAWi6FUKllrLKFQuGIjiPs+tVoNqVQKkUiEnRFeDy0106vX66jVaqzIBJe3LJfLYTabEQgEaJdrE5JIJDh48CDa29uxfft2OBwOFAoF+P1++Hw+zM/PI5PJrPgabkfUbDbjvvvuQ3t7OysDzZ1JOXv2LF577TWqqNhC+Hw++vv7YbVaYbFYoNPpsHv3bjidTohEomt+TbFYxNzcHObm5mi3ZBMbHBzEvn37sHPnTtx1111IJBJ4/vnnsbi4iOeeew65XA7ZbJYFK6VSib34cVVVKbW2+QQCAdxuN7RaLYaGhmC323HgwAGMjIywAiXAb7IcXnjhBUxNTbHnOO2etA5uAUGr1aK7uxsdHR2r2msUi0Xk83mkUinE4/Hr3oNGoxF79+6FXC5n6XoAkM/n8etf/xqhUGjdfx6ytvh8PqswTlqPzWbDgw8+iPb2dlitVshkslXV3mu1GsrlMo4cOYK5uTmWRn/u3DlWoK9Wq4HH4yGTycDtdmPnzp3o6OiAxWKBRqOBQCBAvV5HMplEOp3Gj3/8Y5w6dQozMzPr9rO1VPDJ7XhypeCXl9znzgZS8Lm5cKuuTqcTvb29MBqNUCqVSKfTSCQSSKVSyGazq1ZYuBdNtVoNt9sNl8sFiUSCRqOBRCKBpaUlhEIhVgqeNA931o87b2C1WtHe3s56yFksFigUiuveu9VqFYlEAslkkoKPTYTbHePejEYjXC4Xu+6JRAIejweTk5M4duwYcrkcisUiZSq0MO4+5kr29/T0wO12o7OzE21tbezzuL7MqVQKExMTWFhYQCaToR2wFsMFFxKJBDqdDlqtdtUiYLVaZanvyxf/Xl/NWKVSwe12Q6VSwWg0siyVdDqNM2fOIJ1Os7Rdusdb1+uvDXWSaD3cnIq75+x2O+Ry+Yp7l4uXisUiCoUCFhcXceXKFSwuLrKOA6/PIiqXy6jX6zCbzTAajaw3KADWcSKdTsPj8WBsbOzmSbstlUqo1+vw+/2YmpqCw+FY8YJHNhc+nw+VSgWdToddu3Zhx44dMJlMqFarOHHiBE6cOIFTp05dc7XcZrPh0KFD6OjowK233sqaYAcCAXzjG9/A2NgYJicn6YWuybhiQhqNBu95z3vQ0dHBSn5zRUqMRuMbvrjl83lcuXIF8/Pz65rmQdYGV7J9x44daGtrQ1dXF+x2O0KhEMbHxxEMBnHu3Dl4vV6cPn0ayWQSmUwG1WqV7tUWJhQKYbVaYTQa8Xu/93sYGhqCyWSCUqm8bsGwUqmEeDyOdDpN/SBbEHekRSQSoa2tDW1tbZBIJOzoS6PRQCAQwNTUFFKp1IqvdblcGBgYYAGoy+XCvffeC7VavSL4rFar2L59O+LxOL75zW/iwoULVASQkHdAp9PBbrdjYGAA3d3dq1Jt6/U60uk0stksnn76aXg8Hpw6dQper5ct8l6vKrxYLIZWq4VarV6xuFQulzE9PQ2v14tQKIRsNruumwEtFXxygQRXJv6NKmSS1sfn86FQKKDVauFwONDR0cF6ii0sLODMmTPwer2rUi15PB40Gg22bduG9vZ2tLe3QyKRIBaLIZlM4tSpUzh9+nSTfiqyHHeNDQYDbr31Vmzfvh1msxkqleqGV1QrlQprrUE7n62P20lxu90YHBzErl270NPTg1/+8pe4ePEilpaWMDk5iWAwiLGxMXY2m7Q2gUAArVYLi8WCPXv2YPfu3WwF/nrq9To7a8Tn81n61ttp40LWD3dttVrtinP1jUaDne96/WRVq9Wiv79/RfDZ29sLtVrNqlZzhoeHkc1m8fLLL2N2dpa1RiKEvHUKhQJ2ux0WiwUGgwEKhWJFoFir1ZDP55FIJHD27FlcvHgRMzMziMVib/h9ue4R3MbAcvV6HeFwGD6fD5lMZt3v35YKPsnWwBWQ4aqYtre3o7e3FzKZDDMzMwiHw+xmeX1vKYvFgsHBQXZ+zGAwQCwWI5/P49ixY5ifn6czni1EIBCw1FqTyQS9Xg+pVPqWUnlUKhX2798Pm82G5557jiYtLUwsFmP37t1wOBy4//770d/fj1KphIWFBczOzmJ8fJwVLcjn8yzNh7Q+sViM/v5+uN1uqNXqNww8uabnvb29+OhHP4pYLIapqSmk02nMz88jnU5jYWEBuVwOiUSC7ukmkclkcLvd6O7uRldXFxwOB6tym81m2e5JPp9nC0RqtZodd+ns7IRer4fD4YBarYbZbIZQKES1WkWlUmG9XLl03kOHDsFut+PFF1/E2NgY8vk8ZbMQ8hbZ7Xbcdddd6Ovrg0wmYwtG5XIZS0tLSCaTePXVVxEKhViW0fVSZLmuEFyfz9HRUXR3d8NgMEAkErHF/0QigYmJCczNza2qwbIeKPgka46rUOtwOHDPPfegp6cHJpMJIpGIpVR7PB4EAoFVX6vT6bBt2zYMDAxgYGAAcrkcfD4fiUQCY2NjmJmZoeblLYTP50OtVrM0Dq4gyVs5QyKXyzEwMACJRIJXX311HUdL3imhUIi+vj709/dj165d6Ovrw7lz5+Dz+RAIBODz+VhbFbK5iEQilqEil8vftBk5j8djqZzpdBpzc3OIRqM4ffo0IpEIyuUyYrEYstksBZ9NIpFIYLPZYLfbYbVaYTabAVzd5cjn88hmsygUCqzVEXD1eWw0GmE2m2G32+F0OrF9+3a281Kv11EqlVgV60ajwXZSduzYAYfDgcXFRSwuLrLzpISQG6fX6zE6Ogq73c76dgJXs8QikQiCwSBOnjyJ+fl5zM7OIpFIXPd7CQQCSKVS6PV69PT0sPP7KpUKAoEAxWIR0WgU4XAYXq8XXq93QyrOb4rgk9smXt5QlbQWHo8HpVLJ+nHee++9sNvt6Orqgk6nY8WijEYjCoUCtm/fDh6PB5/PB6/Xy1ZnuJ1Pl8sFgUCAQqGAhYUF+Hw+nD59GgsLCxR8tpBKpQKPx4N0Oo2XX34Z4XAYIyMjsFqtrJnxmxEIBFAqlatSS0jrEYlEGBkZwd69e2EymQAAgUAAFy9eRCgUWvfG1GT9lMtleDweVKtV9PT0oFKpQKvVskIXb9QGiQtyNBoNZDIZ8vk8hoeHkUqlcOrUKYTDYUxNTSEWi7E0XbJ+uEJDXG8/rjptvV5nhYWmpqYQCoXg9XoRj8dZFkt/fz+GhoYwOjqK/v5+KBQKdoZsaWkJqVQKV65cQaFQQLVahVwux0MPPQSbzQaRSMQyX0hr4l6TKS2+dUUiEZw9exbxeBw6nQ4CgQCVSgXhcBhPPvkkAoEALl++jHg8ft2znRyz2Yz+/n50d3fjzjvvhM1mY6114vE4otEofvGLX7AezVyLvPW2aYJPrtotaT1c3y+1Wo3h4WH09PTgscceg9lsXvGgq9VqMBgMAIBt27ZBrVbj2LFjCAaDkEgkkMvlsFgsGBgYYAUNkskkxsfHMTc3h7Nnz8Lv9zfzRyWvU6lUMD8/j6WlJbzyyisIBAIwGAwwmUwsNe/NcOdGKfhsfSKRCMPDw7j11lsBXD17EggEcOXKFRZ8ks2JW0jK5XIYGBhAvV5HR0cHgKtnkN4s+LRYLADAvqbRaCCXy8Fms8Hj8bAdtnq9Tn8n64zrySmVSqHRaNguB7fjmclkMD09jYWFBfj9fsTjcZjNZmi1WvT29mL//v3o7e1FX18fyuUystksYrEYxsfH4fV68fOf/xy5XA4ymQwmkwm33XYbCz4lEgn1aybkHYhGozh79iyKxSK6u7shEAiQz+fh8Xjw1FNPIRAIIJFI3NBz1Gw2Y+fOndi+fTve9773sXuzUCggFothYWEBTz/9NObm5pBIJDasPsOmeEJw5w9mZmZoctqClEol7HY7Ojo6cPDgQbS1tUEmk61oXJvL5VCpVCCTyWCxWFCtVmGxWNjXyuVyKJVK9PX1wWq1QiqVolwuIxqN4pVXXqEdzxZXrVYxOzuLTCYDo9EIn88HsVi8asGIx+PBbDajr68PQqGQJimbTL1eRyKRQDgchlqthkgkQk9PD+vLXCgUkMlk6Fz2JlSr1RCNRlEqlXDkyBFcvnwZdrsdWq0WSqUSUqkUIpGInR8yGAzQarWw2+3XzHDg2rb09PRAp9Mhl8uhs7MTJ06cWNf+ceRqc3qr1Yru7m7cdtttaGtrY6+ps7OzCIfDOHXqFGuRo1Ao0Nvbi56eHuzYsQM9PT0wGAyoVCpIJpNYWFjA4uIiXnzxRcTjceTzeUgkEuzZswd2ux0KhQLlchmRSARLS0uIRqMbUrSEkK0ok8lgdnYWuVwO+XwefD4flUoFsViMFQd7swwjrsDY4OAg9u7dC6fTyeKnRqOBfD6PyclJVkcln89vaNbSppj5cdWeJicnqR9RC9Jqtdi2bRtGRkZw+PBhaDSaFTueXD+4YrHISvc7nU4AV3dAA4EAFAoFNBoN5HI5dDodKpUKMpkM/H4/fvazn8Hn81GaSAurVCq4dOkSBAIB4vE47Hb7qmwFrm/crl274HA4VhykJ5tDvV5nqXputxs6nQ7bt29Hd3c3y1Twer0UfG5CXCsrAJiengaPx2Mtk7jgk0uP7+rqwsjICLq6umCxWK57H0skEuzYsQO1Wg02mw2hUAixWAyzs7P0PF9HCoUCbrcbIyMjeM973gOtVgsej4dkMomLFy9idnYWzz33HDweD1QqFdRqNXbv3o2DBw+yIJTrtx6JRHDx4kWMjY3hhz/8IWq1GqxWK5xOJ+6//3643W5oNBoUCgX4fD7Mz88jGAy+4Tk0Qsj1xWIxxONxXLp0Cc8999yKj91ogGg2m9Hb24u9e/fivvvug0gkYi2WuFYtZ86cwfz8PMLh8IZv7rTkzC+TySAcDsPhcLD3UdDZepRKJXQ6Hfr6+nDLLbfA7XZDLBaj0WigUqmgWCxicnIS6XQasVgMlUoFIyMjsNlsUCqVkMlkUCgUMJlMLO2WOxsqEAggFothMplw6NAhlo/OFUigc2Wth3uoxWIx1Ot1iMXiFZNSrkiJRqPB5OQkjEYjurq6IBQKodFooNVqoVAoIJPJWM9f0hxCoRAqlQqNRgPZbJa1wapUKrh48SJKpRK7lzUaDZRKJXp6enDHHXfg3LlzCIVCKJfLb3oehbQm7t7L5/Oo1WqoVCoQiUTIZrOQSCSoVCrI5/OIRCIQCARQq9WsOAbXZonDHcvQ6XQAgK6uLgwMDGBpaelNWwOQt0csFkOn07F0W27+VC6XMTMzg/HxcaTTafB4PPT396O9vR2Dg4NwOBxs8TgQCGBsbAxerxdnzpzB0tIS5HI51Go1Dhw4AIfDAZvNBrlcjqWlJeRyOVy4cAEzMzOIRqNN/g2Q61m+6FMul5FMJq9bKZU0z/LMwbfD7XbjwIED6OvrY4EnAKTTaczMzGBxcRETExMIBoNNyVBoueCz0WggFAphYmICLper2cMhb8BoNGLHjh3Yt28fHnvsMUilUvB4PFQqFeRyOSwtLeFb3/oWPB4PstkseDweHn30UWzfvh2dnZ2sGIJWqwWwcoGBK0LT29uLz3zmM1hcXMT/9//9fyxliCrotaZ6vY7FxUV4vd7rpuJls1no9Xr09fXB5XJBLBbDbrejXC7DbDYjk8mw9D/SHDKZDO3t7ahWq5ifn0epVEK1WkWhUMCPfvQjKBQK3HPPPejr68OhQ4ewY8cO3HHHHdizZw+eeOIJTExMsGwH2uHavLLZ7IqJKXdPX7lyBTweD+3t7ZiYmIDb7ca9994LvV6Prq6uVen2fD4fbW1tsFgsuO222yASifDKK69Q8LlOZDIZ2traYDabV5y7z+fzOHLkCM6fP49arQaJRIL7778fd999Nzo6OmCz2dg1vnDhAr7+9a8jGAxiYmICSqUSbrcbQ0ND+K//9b/CYrFAJBKhUCjg+PHj8Hg8+PGPf4wrV66wyrmktWUyGfh8PsTjcXpObzH79u3D448/zvovc0KhEH70ox9hfn4ezz33HDKZTFPu15YLPgGgVCohl8uxySe3YyIUCiGVSllja9Jc3Flck8nEdkhCoRByuRwCgQAikQg8Hg+CwSCKxSJ4PB5mZ2dZUQKuPLtEIlkVqDQaDfa+YrGIfD6PQqFAO2KbwPUazHP3sVwuh8vlgtlsZmkgyz+HbDyuOqZOp0N7ezu7t3O5HKrVKlKpFKLRKAtA6/U6/H4/RCIR20ERi8Xg8/mQyWSQSqW0mr5FLL8/uf/mnsGZTAYLCwsol8tQq9Ww2Wys5ZJSqVy1AyoQCNjumUQi2dgf5CbC5/NXVCiu1WpIpVKIxWKsrQqXRq3RaKDRaCCVSiEQCBCNRhGLxVj6bCqVglAohFarxcjICHp6etjuNlcpd3x8HPPz8xtasIS8c9VqFblcjhYJtxCTyQSNRgOz2QyJRLLqupZKJYTDYcRiMZRKpaYtFLVk8JnP5xGNRtnuFveiJZPJYDQakUwmEY/HKQhpsra2Ntx9993QarVIpVLw+/146qmn4Pf78dJLLyGdTrMXukajAT6fj1/+8pc4efIkcrkceDwe7HY7bDbbdf+NYrGI6elpzM3NIRgMIhKJ0HXfpLgFpPb2drz3ve+FUqmEWCxmfyPcW71epxfCDSaRSKBSqbB37158/OMfh1arhclkQigUwne+8x0sLCzg+PHjSCaTbBHo7NmzmJqawm233QYArIAUl07PZTvQtdy6IpEIEokEhEIhfvWrX6G3txcKhQJOpxP9/f2QyWSrvkatVsNqtbJy/2TtcUG+RCIBn89HoVDA5cuXWdVhPp8Pi8UCo9EIq9UKo9HIrtXFixdx5MgRnDlzBuPj46xI4Pbt2/HHf/zHMJlMUKlUSKfTeOqpp1gFTr/fT5sCm0w+n0coFKJijlsEV1Nj9+7dGB4eZgv+y+fMuVyOtVlqZtXxlgw+uVLs3C+M+wVyq/M30r6BrL9arYZCoYBarYZ0Oo1AIID5+XlWVOL1vYK4HWtuR1soFLKVcW5VlitywEkmk5ienobP56OznpucUqmEXq+H2WyGQqFgqXnVahXxeJytylcqFQpYNpher0dvby96e3ths9kgFApZE/psNruqEl6j0YBMJoNGo2HXsVQqsawVuo43B+6ZXi6XUSwWkUqlkEqloNVqr7uiXqvVUC6XKTVzHXHzJe71tV6vo1KpoFwus3tSIBCwNz6fvyLrpF6vQ6fTYWBgAAqFAgaDAZ2dnZDL5ajVapiYmEA8Hsfc3BwWFxeRSqXofPcmxNVpoHnV1sDj8aBSqVYsJnH3ez6fRywWQzAYRDqd3vDqtq/XssHntVL3uOCTKmS2hnA4jNOnTyMSiWBsbIxVp+UmIq/H4/Egk8mgVqthsVjgdDrZDXL+/Hn8+Mc/RiqVQigUYjdFqVRCKBRCoVCg6nmbXG9vL+69915s3759xQJSOp3G0aNH4fF44Pf7kUgkaGK6wW655Rb89V//NUvX8fl8+MUvfoH5+Xm88MILSCQSK87gCoVC7Ny5E0NDQ2hvbwcALC0twev1YnJyEouLiygUChR83kS4HpILCwvg8/kYHh5e9TmNRgPJZBLBYJDSsjfImxUu4QIQbs6l0Wjgdruxa9cuPP744+yYDFdw7MqVK/iXf/kXhMNhRCIRFItFqm5NSJMJBAKIRCIYjUZ0dHRAq9WuiKNmZ2fxs5/9DNPT0+z1uZnzrJaM4kqlEqtqyu2CcU2TtVotKpUKnQ1rAfl8nqXC+v1+1rz6WqspXOr08pYqUqmU9S9KJBLweDws+ORumGq1yprpUkCy8bisA65Zea1WQ7FYZGf/biS44FbhNRoN2tvbYTQaV9y/lUqFTWSaeQbhZsYda5BKpRAKhRCJRBCLxZDL5bBarZDL5exzq9UqhEIh3G432tvboVAoUK1WWZuV5TvYpLVxO19yuRw8Ho9lHHGp8G8V97y4nkajwXrBUorm+uHO8nHPaD6fD7lczqqJc/c6d78vr4grk8lgMBhgs9ngdrvZDmo6ncbc3BxCoRDm5+cRi8XYBJae2ZsXzaU3t+W1NORyObRaLXQ6HaRSKRqNBss2jEajWFxcZJXom5lyC7Rg8NloNLCwsIBgMIhdu3bB7/dDrVZDr9ejvb0dDz74ICYmJljkTppnYWGBpcpyW/jXCzy5F7rBwUEMDQ3B5XJBJpMhk8kgnU5jamoKx44dQ6VSWTFpbTQa7MwopYZsPJFIBJlMhqGhIbz//e9HNpvF+fPnEY1Gcfbs2VWp1dcik8kgl8vR39+Pe++9d1Urhlwuh/Pnz8Pj8dzQ9yNrb3FxEU8//TR6enpw1113wWaz4Xd+53dQqVTw0Y9+lN179Xod0WgU5XIZHR0dMBgMqNVqCIfDOH78OJ588kksLi42PaWHvDmRSASVSgW9Xo9bbrkFEomE9Xu7cOEC4vH4W/p+fD4fUqkUDocDDodjVcXber2OWq2GpaUlTE9Pv+XvT25cIpHAmTNn0Gg0UK1WoVKpMDo6CqPRiIGBAUgkErS3t8NgMECv17MgFLjaosFms0EkEkEqlbKWScFgED/5yU/g8/nYzvX1stTI5vD6wlRk8xGJRBCJRBgdHYXD4cC+ffswOjrKCroFg0FcuXIFZ86cwUsvvcQW/pp9z7bkX1yxWESxWEQ6nUY6nWYvYgKBABKJBCKRqMkjJMBvzni9GS7dVqlUwmQywWazsWITXIXcaDSKVCpFE9YWI5FIoNPpYLFY0Nvby87mcoVlKpUKu2bc6je3is6tmGs0Guh0OphMJhgMBlbduFaroVQqIZPJIJFINK3kN7l6Hy4sLECpVCKTybDznFyLDE69XsfS0hJKpRL0ej1kMhlCoRDi8TiCwSC8Xi+lTW8CfD4fEokEJpMJJpMJHR0drPhXtVp9S3UVuFL+MpkMKpUKarUaSqVy1Y4K1y80l8shlUpRK6V1VKlUkEqlWI9ePp8PpVIJrVYLu92OSqUCu93OeisLhcIVO5+vLxRVLBbZsRquen2zd07IOycQCCCVSmkjZ5PiWhIqFArY7Xa2oKRUKlEul5HJZBCJRLC4uMiONLXKcZiWDD45oVAIFy9eRHd3N7RaLSYnJ/H//t//Qzwep5SdTUQkEmH37t1ob2/Hfffdh+HhYYjFYqRSKTzzzDP4yU9+goWFBQo8W1BfXx/e/e53o7u7G3v27EGpVEJbWxsWFxeRSCSwtLTEVtK4+9JsNkOtVkOr1UKlUmH79u3Ytm0bq4TJ7XpGIhEcP36cVV5LpVIUtDSJx+NBMpnE5OQkisUiNBoN7HY71Go1Ojs7IZVKAVzNROAaVnu9XqTTadY3cHZ2FouLi/RsbnEikYj1UP793/99WCwW9Pf3I5FI4JVXXsH4+DgymcwNfa/lqdm33norOjs7sXPnTrYwwWk0GojFYkilUpiZmcH4+Dj1al5HXKZQtVpFqVRCuVyGSCSCVqvFxz/+cRSLRUgkEgiFQhiNRtajezmuMFQwGMSFCxdw+fJlnD17Ful0mlLqtwiz2YwdO3awdGp6/d0cuNZmSqUSDz/8MLq7u7F37164XC4YjUYAV+uonDp1CpcuXcKxY8fYZh6XSdhsLR18FotFJBIJ5HI5VlF1fn6e/X/S+rj2GhaLBS6XC21tbbDZbGxV1uv14sKFC1R8okUplUo4nU7Y7XbodDpUKhXUajXWJkcgELAzflyhKS6Vy2QyQa1Wo6+vD9u2bYPBYGDpPfV6HblcDh6PB16vF/l8viVSQW5WuVwOuVwOEokEU1NT7FprtVqo1eoVZz650u2RSATRaBSTk5O4cOECEokEstksXcMWx6Xbms1mDA0NwWazwel0IhgMolQqIZ1Ov+mu1vKzolqtFlarFX19fXC5XNDr9VCr1QBW9gXNZrOIx+NIJpNIp9Pr/nPezLjAs1wuI5/Ps/ZHQqEQvb297POW36vc13BptNzzPBaLwefzIRAIIB6P09GITYi7ptzRKO6coEQigV6vRzgcbvYQyVskFAohlUrR2dmJoaEh9PX1wW63s+scDocxPj6OiYkJTE5OtlwLu5YOPjnLX8Co8MzmwaVc6vV67N69G9u2bYPJZEK9XsfU1BSmpqYwPj6OeDxO17RF+Xw+PP/88xgcHGT93YxGI1QqFR5//HHkcjlEIhEUCgUEAgEUCgX09PTAaDRCqVRCKpWyYJRLn8/n86wx+ZNPPolQKMQmvK30cLwZhUIhPPvss2xHSywWQ61WXzMNM5fLoVwus0lpuVym7IVNwOVy4aGHHkJ3dze6urqgUqlY2yudTgej0cgKA3F9dzlc0NnZ2YnR0VG0t7djz5490Gg0cDqdrKDNctyZweeffx4XL17E7OzsRv/INx2u6nC9Xsc3vvEN2Gw27Nu3DzqdDi6Xi2UycBqNBmZmZuD3+5FMJpFKpZBMJhGJRBAIBHDp0iUkk0lKld6EGo0GO4MfDocRCASgVqvZAhHZfAQCAdRqNUwmE4aHh7Fr1y5otVoAQCaTQS6Xw8WLF/Hss88inU63XOAJbJLgk2xOfD6fVbd1OBxob2+HTCZjBUpmZ2cRDocp/aqFpdNpzM7OQqVSIRqNgsfjwWq1svO71WqVBZ9+v58FnyaT6ZrnsxuNBkqlEmu3MDExwSY1rfZwvBnlcjnMzc01exhkHanVagwODsLlckGn07HCFDweD0qlEiqVCrlcju1+LV8Y5IqTWCwWDA0Nob+/H4cOHYJEIlkVdHK43bfZ2VlcunQJsVhsQ37Omxl35lMgEODMmTNoa2tjZz2NRuOKgm8AWGAyNzeHcDiMcDiMaDQKv9+PcDiMqakpWljaxLgOEdx5a27xgdsBpYq3mwtXvVqpVMJsNsNmswH4TTVxbn7Vyq/lmyL45LaXTSYTRkdHEQ6H4fF4aLesxanVanzoQx9CT08PBgcHodFo4PV6EY/H8fzzz+PVV19FIBBo9jDJG8hkMvB4PFCr1Zibm4Pf78f58+eh1+tx4MABtrigVCohl8tRrVah0WggkUhW7ZZVq1UUi0WcPXsW3/jGN+D1epFKpVCpVCjwJGSDcNXFAWDv3r0s+NRqtfiDP/gDVpI/m82uKizD9Xzs6OjA0NAQtFot5HL5qnudy1LKZrP4xS9+AY/Hg+PHj2N2dpZSbjdQLpfD+Pg4FhYW4Pf7IZfLodPpIBKJVgWTkUgEyWQSxWIRhUIBxWIRuVwOxWKRAs9NjrsfK5XKiuxBnU6H/v5+pFIp8Pl8mlO3OKFQCJ1OB7Vajf3798PhcECv16PRaCCdTiOfz+NXv/oVTp06hdOnTzd7uG9oUwSfXDlojUYDl8sFHo+HhYUFulFanFwux2233YbR0VGYzWaIxWJEo1HMzc3h0qVLOHv2bLOHSN5EoVBAoVBAKBTC0tISq3Zqs9mwZ88eFnQCgEqlesPvxZ1Bmpubw09+8hPa8SakCYrFIoLBIPR6/YqgQqFQ4ODBg6jVavB4PMhkMsjn8yuCT4lEAqlUCqPRCIfDcd1/g9s1zWazeO2113Dp0iVMTk4iGo2u689GViqVSmyBd2ZmpsmjIc2y/Lwn18sXuFrToa2tDQaDgXY/NwEu3dZoNKK/vx8ulwtKpRLA1VT7ZDKJM2fO4Omnn0YqlWryaN9YSwefFosFo6OjsNlsqNVqyOfzWFpaQjKZpJ2STaBUKmF8fByNRgO33HILdDodfD4fJiYmkEgkmj088hYsLS3h2WefRaPRQLFYZAWkDAYDALDzYjKZDE6nk50/AK4GndVqFRcvXsTLL7+Ms2fPUpl+QpqES60WiUS4ePEiTCYT3G43O5PN5/PZue7X11gQCAQQCoUrClBxGo0GMpkMJiYmkEqlMDc3x/oBe71eKipHSBM1Gg2kUikEg0F23lMgEEAsFlOfz01CpVLh1ltvRVtbG/bu3QuLxQKVSoVarYapqSnMzs5ifn5+U5zPbum/OC66l0qlqNVqKBQKiMfj7AAtaW3lchnT09NoNBoYHh6GRqNBKBTC9PQ0pV5tMpFIBC+99BJ4PB5EIhHr16rRaABcTQdxu93Q6XTQaDQrgk+un+fY2Bi+//3vIxqNUtYCIU2Sy+WwsLAAgUCA8fFxZLNZ2O12FnzyeLwV9++N4HZWMpkMzp07h2AwiOPHjyMSiWB2dvaGW7cQQtZPJpPB0tIS693M5/Mp+NxEFAoFdu7cic7OTmzfvh06nQ4AWEYZt9C3GebXLf0Xl06n4fP5WHPkTCZD1W43kVKphEuXLrFqphqNBseOHWMrM2TzaTQaqNVqyGazuHjx4orCBdPT05DJZLhw4QJ7KAJgZ00uX76MUCiEfD5PmQuENEmlUkE6nYbX68X/j70/j477ru/F/+dn9n3fZySNdtmS5T2Ol8QJSUggJFAIIVBOEwiFthAu59vtdO+BS87p7b0tt5fTUloKtGyhYQkBsjmJs3m35diStWskjTT7vu/z+8O/zxspthPHljQj+fU4xyfJaKS8xx99ltf7/Xq/Xi+++CKsViuSySS0Wi1MJhPEYjFrZ2Y2m1laF/CbNHxeLpdDJBJBuVxGOp1GNBrF0aNHkUgkMDc3xyoiE0Iaq16vw+PxQC6Xs968s7OzGB8fx+LiIt2Tm5hIJIJarYZer4dMJoNEImF7dOfn5xGLxTA9PY25ubl1M9HX1MFnPB7HzMwMDAYDq95WLBYpZW+dKBQKbNPzs88+y16ni9z6Vq1WkUwmcezYsWWvX82eETr2hDRWuVxGPB5HMpmE1+uFTqfD7OwsjEYjtmzZAoVCwXp+btu2ja2SAEAkElm2bzMQCGBsbAzpdBo+nw+ZTAYzMzMUcBLSZOr1OsbHx+Hz+aDX69HZ2YmpqSm8+eab8Hq9lE3YxCQSCSwWC0wmExQKBaRSKTiOQ6lUwujoKGZnZzEyMoLp6emm3+vJa+rg0+Px4JVXXmEVNcfHx5FOp1EoFOghdp2h47Xx0TEmZP3gsxhyuRybPc/n85BKpUgkEqhUKkgmk8tScDOZDDKZDPtvvqR/oVBglVIpM4mQ5lQoFMBxHIaHhyGTyeDz+TAzM4NgMEj37yYml8vhdrvR1taGlpYWWCwW1j1gZmYG4+Pj8Pv9SKVS62bij6tf5W9cIyphCQQCCAQC9v/mb5arfZLcqCfhjVTtjI7xxnejHmOAjvONYCWPMd/3ke/5x/+dvrUH4Fv/ruv1Onvtrf9cSXSMNz46xmtHKBRCIBCwvdpLz+PVRMf42nR0dODjH/842tvbcf/997O+69FoFH/3d3+HoaEh+Hw+pNPphv8dX+3/v6lXPvnS0IQQQghZHXSfJeTGUa1WKUNhHSmXy4jFYqy7QKVSwczMDHw+H0KhEFKp1Lrrl97UwSchhBBCCCGE3Iiy2SzGxsYAXCzkWa1W8cwzz2BsbAwjIyMIhULrbgKRgk9CCCGEEEIIaTL8yufi4iJOnToFoVAIj8eDQCCAQqGw7gJPoMn3fDbKelq6Xkl0jDc+OsY3BjrOGx8d442PjvHGR8d447veY8z3V+dbrgAXi7/xbeyaKfi82mNMwedl0Amy8dEx3vhu1GMM0HG+EdAx3vjoGG98dIw3PjrGl7rq4JMQQgghhBBCCLlWgkYPgBBCCCGEEELIxkfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVUfBJyGEEEIIIYSQVddUwefJkyfxhS98Af39/VAqlWhtbcWDDz6IiYmJRg+NrLDJyUk89NBDcLlcUCgU6Ovrw5e//GXkcrlGD42soDNnzuD++++HwWCAQqHAwMAA/umf/qnRwyIr5PTp07jnnnug0WigVqvx3ve+F2fPnm30sMgq+upXvwqO4zAwMNDooZAVUiwW8ad/+qdwOByQy+XYs2cPXnjhhUYPi6wgulZvfJlMBn/zN3+De+65BwaDARzH4Tvf+U6jh3VZXL1erzd6ELwHHngAb7zxBj760Y9icHAQgUAAX//615HJZHDs2DG62W0QXq8Xg4OD0Gq1+L3f+z0YDAYcPXoU3/nOd3D//ffjqaeeavQQyQp4/vnncd9992H79u342Mc+BpVKhenpadRqNfyv//W/Gj08cp3OnDmD/fv3o6WlBZ/73OdQq9Xwz//8z4jFYjhx4gR6e3sbPUSywhYWFtDb2wuO4+B2uzE8PNzoIZEV8PGPfxxPPvkkvvSlL6G7uxvf+c53cPLkSbz88ss4cOBAo4dHrhNdq28Ms7OzaG9vR2trKzo6OnD48GF8+9vfxiOPPNLooV2iqYLPI0eOYNeuXZBIJOy1yclJbNmyBQ888AC+973vNXB0ZKU8/vjj+Iu/+AsMDw+jv7+fvf7www/jP//zPxGLxaDX6xs4QnK9UqkUenp6sG/fPjz55JMQCJoqyYKsgHvvvRdHjx7F5OQkjEYjAMDv96Onpwfvfe978ZOf/KTBIyQr7aGHHkI4HEa1WkUkEqHgcwM4ceIE9uzZg7//+7/HH/3RHwEACoUCBgYGYLFYcOTIkQaPkFwvulbfGIrFIuLxOGw2G06dOoXdu3c3bfDZVE+E+/btWxZ4AkB3dzf6+/sxOjraoFGRlZZKpQAAVqt12et2ux0CgeCS3wGy/vzgBz9AMBjEV7/6VQgEAmSzWdRqtUYPi6yg1157DXfeeSd7mAEunsMHDx7EL3/5S2QymQaOjqy0V199FU8++SS+9rWvNXooZAU9+eSTEAqF+OxnP8tek8lkePTRR3H06FF4vd4Gjo6sBLpW3xikUilsNlujh3FVmir4vJx6vY5gMAiTydTooZAVcttttwEAHn30UZw9exZerxdPPPEE/uVf/gVf/OIXoVQqGztAct0OHToEjUaDxcVF9Pb2QqVSQaPR4Pd///dRKBQaPTyyAorFIuRy+SWvKxQKlEolWhXbQKrVKh577DF85jOfwZYtWxo9HLKChoaG0NPTA41Gs+z1m266CQBoX+AGQNdq0myaPvj8/ve/j8XFRXzsYx9r9FDICrnnnnvwla98BS+88AK2b9+O1tZWPPTQQ3jsscfwj//4j40eHlkBk5OTqFQq+OAHP4i7774bP/nJT/DpT38a3/jGN/CpT32q0cMjK6C3txfHjh1DtVplr5VKJRw/fhwAsLi42KihkRX2jW98A3Nzc/jKV77S6KGQFeb3+2G32y95nX/N5/Ot9ZDICqNrNWk2TR18jo2N4fOf/zz27t2Lhx9+uNHDISvI7Xbj1ltvxTe/+U0WmDz++OP4+te/3uihkRWQyWSQy+XwO7/zO/inf/onfPjDH8Y//dM/4XOf+xx+9KMfYXJystFDJNfpD/7gDzAxMYFHH30UFy5cwPDwMH7nd34Hfr8fAJDP5xs8QrISotEo/vqv/xp/9Vd/BbPZ3OjhkBWWz+chlUoveV0mk7Gvk/WNrtWk2TRt8BkIBHDvvfdCq9WyPQlkY/jRj36Ez372s/j3f/93/O7v/i4+/OEP41vf+hYefvhh/Omf/imi0Wijh0iuE5/i8/GPf3zZ65/4xCcAAEePHl3zMZGV9Xu/93v48z//c/zgBz9Af38/tmzZgunpafzJn/wJAEClUjV4hGQl/OVf/iUMBgMee+yxRg+FrAK5XI5isXjJ6/z2iMula5L1ha7VpNk0ZfCZTCbxvve9D4lEAs8++ywcDkejh0RW0D//8z9j+/btcLlcy16///77kcvlMDQ01KCRkZXCn7NvLSplsVgAAPF4fM3HRFbeV7/6VQSDQbz22ms4d+4cTp48yQpL9fT0NHh05HpNTk7im9/8Jr74xS/C5/NhdnYWs7OzKBQKKJfLmJ2dRSwWa/QwyXWw2+1sBWwp/jV6/toY6FpNmknTBZ+FQgH33XcfJiYm8Mtf/hKbN29u9JDICgsGg8v2HvDK5TIAoFKprPWQyArbuXMngEv3kvD7hyh9b+PQ6/U4cOAAK0Rz6NAhuFwu9PX1NXhk5HotLi6iVqvhi1/8Itrb29mf48ePY2JiAu3t7fjyl7/c6GGS67Bt2zZMTEywKvQ8fj/gtm3bGjAqshroWk2aRVMFn9VqFR/72Mdw9OhR/Pd//zf27t3b6CGRVdDT04OhoSFMTEwse/2HP/whBAIBBgcHGzQyslIefPBBAMC3vvWtZa//+7//O0QiEat4TDaWJ554AidPnsSXvvQl6u26AQwMDOBnP/vZJX/6+/vR2tqKn/3sZ3j00UcbPUxyHR544AFUq1V885vfZK8Vi0V8+9vfxp49e9DS0tLA0ZHVQtdq0kiiRg9gqT/8wz/EL37xC9x3332IxWL43ve+t+zrn/zkJxs0MrKS/viP/xjPPPMMbrnlFnzhC1+A0WjEL3/5SzzzzDP4zGc+Q2k+G8D27dvx6U9/Gv/xH/+BSqWCgwcP4vDhw/jv//5v/Nmf/Rkd4w3g1VdfxZe//GW8973vhdFoxLFjx/Dtb38b99xzD/7H//gfjR4eWQEmkwkf+tCHLnmd7/V5ua+R9WXPnj346Ec/ij/7sz9DKBRCV1cXvvvd72J2dvaSyUOyPtG1+sbx9a9/HYlEgmWZPf3001hYWAAAPPbYY9BqtY0cHsPV6/V6owfBu+222/DKK69c8etNNFRynU6cOIG//du/xdDQEKLRKNrb2/Hwww/jT/7kTyASNdWcCLlG5XIZjz/+OL797W/D5/Ohra0Nn//85/GlL32p0UMjK2B6ehp/8Ad/gDNnziCdTrNz+P/7//4/SCSSRg+PrKLbbrsNkUiE+gNuEIVCAX/1V3+F733ve4jH4xgcHMRXvvIV3H333Y0eGlkBdK2+cbjdbszNzV32ax6PB263e20HdAVNFXwSQgghhBBCCNmYKNGbEEIIIYQQQsiqo+CTEEIIIYQQQsiqo+CTEEIIIYQQQsiqo+CTEEIIIYQQQsiqo+CTEEIIIYQQQsiqo+CTEEIIIYQQQsiqo+CTEEIIIYQQQsiqE13tGzmOW81xNJUbtfUpHeONj47xjYGO88ZHx3jjo2O88dEx3vjoGF+KVj4JIYQQQgghhKw6Cj4JIYQQQgghhKw6Cj4JIYQQQgghhKw6Cj4JIYQQQgghhKy6qy44RAghK4XjOHAcB6FQCAAQCASo1+uoVCqo1+s3bGECQgghhJCNjIJPQsiakkql0Gg0sFqt2LdvH/R6PTo7O5FKpfC9730Pfr8f8XgcpVKp0UMlhBBCCCEriIJPQsiaEovFUKvVaGlpwb59++BwOHDTTTchHA7j8OHDyGQySKVSjR4mIeQa8G0FKHth4xIIlu/YomwVQsi7QcEnIWRNqNVqGI1GbNq0Ce9///uh0+ngdrshEAgwNDQEv9+PcDiMTCaDarXa6OESQq6SWCyGRqOByWTC3r17Ua1W8corryAWiyGfz9P5vAHI5XJYrVY4HA7cc889UKlU4DgOuVwOzzzzDBYWFhAKhZDL5Ro9VEJIk6PgkxCyJpRKJWw2G7Zt24aPf/zj4DgOqVQKsVgM58+fx8LCAuLxOPL5PGq1WqOHSwi5SmKxGDqdDq2trfjABz6AUqmE0dFRFAoFFItFCj43AJlMBqfTiYGBAfzu7/4urFYrOI5DLBZDIBBAvV5HOp2m4JMQ8o4aHnwKhUK0tLRAo9HAbDZDpVJBrVZDoVBALpdDLpez9+bzecTjcfj9fhw7dgyFQgHlcrmBoydrSSQSQaFQ4NZbb4XZbIZMJoNQKMSxY8cwOTnJHnRIczEYDDAYDNi2bRsOHjwIg8GAkZERRKNRDA0NIZlMYm5uDslkErFYDMVikYJPQq6RSCSCQCCAUCiEUChEpVJBpVJBrVZbtfNKoVCgvb0dnZ2daGtrQ6VSwZYtW6BWq/Hmm28iHo9TWuY6pdPp4HK54HA4cPPNN6OtrQ1SqZQdT4lEgl27drHrvN/vx9zcHCKRCB1zQpqUSqVCb28vdDodBgYGIJFIMDExgXg8jgsXLiASiazq/7/hwadIJEJXVxdcLhcGBgZgtVrhcrlgMplgNBphNBrZHpJIJILp6WmcPn0aFy5cQK1WY9UxycbGcRzEYjG0Wi1+67d+C1u3boVer4dQKMTf//3fIxwOIx6PU/DZhAwGA7q7u3Hw4EF8+tOfxszMDA4fPoyxsTE88cQTyGQyKBaLdB4TsgJEIhHEYjEkEgnEYjGKxSKKxSLK5fKqBp9dXV3o7u5Ge3s7arUaduzYAZ1OB4/Hg2QyiVqtRuf4OqTT6bBt2zZ0dHTg7rvvhl6vh0wmWxZ87tmzB729vVCr1ZidnUWhUEAsFqNjTkiTUqvVuOmmm9DZ2YlPfOITUKlUeOqppzA9PY1QKLTxgk8+iFAoFNi8eTPbI2Kz2WCxWKBWqyEUCpHJZAAAhUIBSqUSGo0GUqkUdrsdmzZtwn333Qev14vDhw8jm82u9ccgK0wkEkEikUAoFEIsFrPX6/U6yuUyRCIRrFYrzGYzbDYbTCYTAKBcLqNUKlFqVxOSyWSQSqUYGBjAwYMH0draikAggKmpKRw7dgyLi4vI5/M0gUTICuE4Dm1tbTCbzXC73bDZbJibm8PMzAzC4TC8Xu+qnGvlchnRaBRmsxm1Wg1SqRT9/f3QaDR44403kEgkkM1mKVNpHdHpdLBYLOjo6EBPTw9bFFCr1csKDgkEAmi1WojFYmzZsgVWqxXT09OYn59HoVCgquVNTCwWQyqVstVttVoNl8sFkUgEjuNQLpcRCASQTqdx/vx5JJPJRg+ZXCe+xZ1arcamTZvgdrshl8shFovR1dUFpVKJ8+fPo16vIxAIrNoxX/PgUyAQQKFQwGq14oEHHkB3dzd27twJk8mEfD6PUqmEubk5BINBxGIxcBwHh8MBhUIBhUIBnU4Hs9kMl8uFc+fO4fTp0xR8bgASiQRarRZSqRQqlYrd3CqVCrLZLKRSKTZv3gyn04mOjg44nU52UczlcvRg04TUajW0Wi0OHDiARx99FIFAANPT0zhx4gR+/vOfo1Ao0IQBIStIKBRiYGAA27Ztw2233Ybdu3fjpZdewnPPPYdz585hYWFhVYLPQqEAr9cLnU6HSqUCg8GAAwcOIBKJ4Fe/+hVCoRBKpRJdo9cRm82G3bt3o6OjAzfddBPMZjNaWlqWTQ4DF5/pTCYT6vU6XC4XSqUSzpw5g5GRESQSCQo+m5hMJoNer0dvby/uvPNOtLe3484772RbmjKZDN544w3Mzc0hFApR8LkBCAQCSKVSGAwG7N27Fy0tLVAoFBCJRNi+fTt6e3sxNzcHlUqFN954Y+MEnyqVCrt374bD4UBbWxsMBgMikQji8Tjm5ubYns5oNMq+x2azYXZ2Fk6nE1u2bIFAIGB7RHt7e6FUKrGwsEApl02K4zjI5XJIJBJYLBaoVCpIJBKIRL/59VOr1dDpdJDJZNDpdOz1fD6P6elpCIVCtLa2wmq1QiaTgeM4lEolVkmRT80mjcfPrLW1taGrqwsmkwnZbBZzc3Nsf26pVKLAc4MQCoVs9UOj0UCv18NisUAkEi07x/kAJZfLYWFhgR5KVwnHcRAIBBCLxSxjZGBgAIVCAZOTk8hms0gkEisahHIcB6lUylZMgIsPOQKBgI2HrtHNiT9/5XI5pFIpHA4H7HY72tra0NfXB5vNBqvVCo1GA6FQiFqthnw+j3q9Do7jwHEcZDIZO8b8XmPSvHQ6HVvt7O7uhs1mg81mg0gkwtjYGMRiMUut5icWDAYDVCoVCoUCKpVKoz8CuQYcx0GhUKCtrQ2tra1QqVTs3OWzDEulEtLpNOLx+KpOFq558Gk2m/Hoo4/C7XbD4XAAAF577TV4vV4899xzmJycRCaTQaFQYN9jMBhgsVhw1113ob29nZX8rlaruOeee+DxePDTn/6Ugs8mJRAIYDabodPpcPvtt6OzsxM6nQ5qtZq9h1/RViqVMBgM7EElGAziF7/4BQqFAlpaWqDT6aBSqQCAPURVKhVWZIM0Hr/nbP/+/Xj/+98PuVwOr9eLV199Ff/2b/+GXC5HKyAbiFQqhVQqRW9vLzZt2oQdO3bg9ttvh0KhgFarZeeyz+fDk08+idnZWTz11FOrvqeEXNTT04OWlhZotVr4/X4sLCzgzTffXNHJH5FIBI1Gc0lKJml+UqkUEokEDocDBoMB999/P973vvdBpVJBo9FAJBJBKpWySYRCoYBQKIRKpQKO4yASiWCz2SCTyRr9UchVamtrw+DgIPbv34/7778f+Xwe0WgUi4uLeOKJJ1Cv12E0GmEymfChD30IbW1tcLvdiEQi8Pv9FHyuQ/z5azQaccstt6C7uxtms5k9h9dqNeRyOSSTSXi9XkxPT69qv/U1Cz5FIhFUKhWMRiPMZjP0ej0KhQLy+TxmZmYwMzPDlvXfWsU2lUpBKBQiGAzC6/XCYDDAbrdDJpOxNA+JRLJWH4W8SxzHQa1Ww2AwwOl0wu12Q6PRQKFQsPcolUr2oJrJZCAWi6FUKtksTblchsVigVKphEQiQa1WQywWg8/nQzqdZtUcSWNxHAeLxQK9Xg+n0wmz2Qy/34/JyUnMzc0hk8nQitcGwWczuFwumM1m9PX1obe3l2W0yGQyNlEEXJxE7OrqglQqRV9fHwKBANv3S1YPnyZps9nQ398PqVSK2dlZ5PN5FAqF61oB5Ve+FAoFXC4XbDbbslUvgUAAvV4Pk8mEeDxOW2SaBH9PlkqlbFWzra0NVqsVHR0dMJlMkEqlbFVk6TEtlUpYWFhAoVBgK9581hJpTvx5yk/6d3d3o7+/H3q9HvF4HNFoFNPT0/D5fPB4POA4jhUBrNVq7PmanrHWL/6Z2mq1oqenB62trcvipkqlgvn5eQQCAYRCIaTT6Y2x8qlSqdDX14dNmzaho6MDOp0Op0+fxsLCAp5++mmMjIygVCpdtvhINptFPp/HyMgInn32WXR1deHee++FRqPBzTffDJPJhP/6r/9aq49C3iWRSIT29na0t7dj37592LZtG5uF4dVqNVSrVfj9fpw7dw4ajQZ9fX2QSqW488472Q2Q4zhIJBIUi0WcP38eZ86cwezsLNLpNBWtaQIikQh79+7Fli1bsHfvXnR1deHll1/Gf/zHfyAWiyGbzdJx2gAEAgHsdjtMJhPuvfde3HTTTXC5XGxPmFgsBsdxLDUPAPR6Pe69914kk0lWCOfb3/42ZmZmGvxpNjaRSAShUIitW7eira0NR44cgdfrRTgcxtzc3HWtYvD7h5xOJ+6++244HI5l7dHEYjH6+/shEokQjUYRj8dX4iOR6yQSidDT0wO73Y59+/ahvb0dvb29cLlckMlkbxtIJhIJvPDCC4jH4+A4DlqtFk6nc9l2GdJcBAIB29M3MDCAW2+9FbfccgvGx8fxwgsvYGxsDIcOHUI2m0UymYRMJkN7ezs6OjpQKBRY1Wyq07B+qdVqdHZ2YteuXXjggQeg0+kuaWX5y1/+EsPDwzhz5gx8Pt+qTjasWfDJ7wuQSCQstzgWi7HVzrebEa3X66hWq8hms/D7/TAYDKjX6xAKhZDJZJDL5SztkmZmmodQKGQzbS6XC62traxMey6XQy6XY73nMpkMEokE/H4/xsfHWbqPTqdDd3c3pFIpm32t1Wool8uIx+MIBALI5XIU0DQJvvhES0sLZDIZisUi0uk0IpEIHacNgt9PaLPZ0NraipaWFjgcDhiNRigUChSLRSQSCfawws+48v+s1WqwWCwoFAqQSCQsSCXXr16vo1KpXLKneukKlclkgsvlAgD2gHGt903+HsxnNel0umWTivxkIZ+2SRpLIBBAqVRCpVKhs7MTLS0tcLvdcDqdMJlM0Ov1bJWsXq9f9rys1WooFArI5XIQCAQsE4k/vnScmwu/ys1nJ3R2dkKpVCKdTiMUCmF6ehperxeRSATFYhH5fB5CoZDt2eeft/j9gPSMvb7wCzdarRZtbW1wOp3QarUs87BeryOfzyOVSiEYDMLv9yOXy636JMOaBp/8ZnW+wNDJkydZD7CrEYlEcPz4cQgEAtZ+QyKRQCKRQKFQQCaToVAo0MnRJJRKJe666y643W7ce++9cLvd0Ol0qNfrmJiYwMzMDPL5PFvVPnLkCDKZDOLxONRqNdrb29HV1YUvfelLLOVWIBCw2bnh4WGcOHGCteUhjSUSiSCTydDf348DBw4gmUxiZGQEc3NziEajdF5uAHyKpUqlwvve9z4cOHCApeuVy2W2X2R8fBx+vx8XLlyAyWTC7t27YTabsX37dkgkErS1tbGtGEKhENVqlQLQFZJMJhEKhZDL5Za9zq+AdnZ24oEHHsCFCxfg9XqRSCSQz+ev6fyUy+Ww2WxwuVzo6uqCTqe7pBoqaR4ymQw7duyAy+XCo48+ir6+PjZ5z08E8X+u5HJB5tLvoeCzuQgEAvT396O9vR0f+tCHcODAAZw4cQL/9V//hTfffBOvvvoqisXisslhuVyOzZs3o62tDZVKBalUCrFYDPF4nO7j64xcLodOp8P27dvxyCOPwGazQSqVsq8Xi0VMTk5icXERw8PDGB0dXZNn6jULPvnZskwmA6/XC4FAgEAggHA4fNV7wMrlMjKZDLup8pvdJRIJVCoV1Go1m/UljScQCKDT6dg+X5PJBIFAgEqlgmg0ivn5eWSzWWSzWczMzMDj8aBUKrEJhFwuh1KptOyhtFqtIplMIhqNIplMsv2epLE4joNKpYJWq2VVTwOBAHw+HysKRdY/vmCB0WiE0+lkbbBqtRri8TjC4TDm5+cxMzMDv9+P6elppNNp2Gw21Go1VCoVCIVCyOVyKJVKlg1DfXpXRr1eRy6XQzweRzweRyKRgFQqZelV/OSB3W5HNBqFVqtFuVxeVuDv3eC3T/Cz628tNsTPqvNZLqQxBAIBZDIZNBoNy0JyOBywWq0AwPb2VSoVdjwvh18NvdKqKGku/DMy3yZHr9dDKpUinU7D4/FgcXERsViMHUt+kUgmk8FsNsNoNLJ+n9Vqla7R65BKpYLT6WT3a71ez85vPgs1HA4jGAwilUqtyaonsIbBZzabxdjYGDweD0ZGRgAAgUCApW9cDT6liJ8lF4lEUKvVsFgs2LlzJ3Q6HY4cOUJVFJvE0pQriUQCsVjMUqxfe+01/PrXv0Ymk2ETCul0GjKZDFarFW63G/fffz9aW1vZqme1WkUmk8GLL76ImZkZzM3NoVwu002wCUilUuzfvx/t7e1wu92QSCQ4c+YMDh06hLGxsUYPj6wQhUKBhx56CFu3bsXOnTvhcDiwuLiIyclJ/OpXv8Kvf/1rlrrFt0JSqVRYWFhAX18ftm7dCrPZDI1Gg3K5DIfDgUAggEAgQBkMK6BWq2F0dBSzs7OQSCSIRCLYvn07du/ezd6j0+kwODgIiUSCPXv2wOv14ujRo9dUDKhUKiGZTCIejyMYDKJarcJgMLAtEuVyme0hisViK/Y5ybujVCrZiucnPvEJtLa2wmazLXumyuVyLE2ev18v3RPGB6d8ochCocD2hi4NRul+3Bz4FncqlQoHDx7E7bffjnQ6jaNHj+Lw4cN47rnnLtkKIxaLodfr0drailtuuQUOhwMqlYr2aq9ju3btwqOPPgqHw4HOzk6IxWK2RbFQKCASieDFF1/E9PQ0gsHgJQs+q2XNgs9KpYJ0Oo1MJsNuQnw1ravFX/z4i2WtVmNlwE0mExKJBKX8NJlyucwq0fJFhfggMplMIhaLIRaLsbQdiUQCg8EAq9WK1tZW2O12dkxzuRxSqRQWFhYwOztLewibCN9Ox+l0QiaToVqtIhaLYX5+flXLdZO1xRcaam9vZ/u3+RuYx+PBuXPnLvmecrkMqVQKo9HIVjj5okT85BS151g56XQa2WwWXq8XFosFLS0tqFarrA8jP2mr1+ths9mQz+eXFYh6N/h6DNVqld2bl6rVakin00gkEtReqQH4461SqdiKZ2trKyssxK988DUUkskkFAoF5HI51Gr1ssJDlUoFmUyGFYDk92wDFHw2I773Mt932Wq1IhKJYGFhAX6/H+Fw+JJjJZFIoNfrYTabYbVaYTAYUKvVqC/3OsbXTdHpdFAoFCwtns8uTKVS8Pl8WFxcvO7q5+/GmgWf/EVu6X6Ad/sh+f5SfIn+UqkEs9kMoVAIk8mEVCpFLVeaSLFYxMjICBKJBKt4qNFoYDKZcOutt0KlUuH111/H0aNH2STCpk2b8IEPfACtra3Yu3cvC2SCwSAOHz6MxcVF/PrXv8b8/DzNpDcRkUiEjo4O9Pf3I5fLYWJiApOTk/B4PNR/d4PhtzbUajXU63XMzc3h9OnTWFxcvKrvr9frbI9RJpOh1PkVxqdQjo2NIRwOQ6vVYnBwkKXF8wwGA2677TY4HA6cOnUKlUrlXafHSiQSaDQa6HQ6WCyWSwoOkcZSq9Xo6elBZ2cnW/3ge3Lyqx+BQADRaBQ//elP8frrr7P379q1C3fccQd7ZgsEAnj++efh8Xhw5MgRVCoV7Ny5s8GfkFyOQCCASqXCI488goGBAXR2diKZTOLw4cN46aWX4PV62fV7KZfLhd/93d9Fa2sr3G436vU6jh8/jrm5OZpEXqdUKhVaWlouKfqWTCbx2muvYXZ2FkNDQ1hcXFzTVlhrFnwCuO59AtVqFfl8HtlsFplMBiqVCvV6ne1nkMvltNm9iVQqFUQiEQiFQsTjcaTTaWi1WsjlcjgcDmQyGUxOTkIikbCKiQ6HA319fbDb7bBareA4DslkEqlUCjMzM5idncXc3Bz8fn+jPx75/+PLuPP7e/miUYlEAul0+orfA4Bmy9chPouBP2apVOqSAjdL9wLyReH4DIZqtYpCoYBsNotCoUAVFFdBvV5nfTXD4TAymQxEItGy4JPvk53NZqFQKJalY13JW/cDSqVSqFQqqFQqyOXyZYUsSOPw559SqYTT6URbWxv6+vpgtVrZcxifiZRMJhEOh1nRP/48bm1tZb8LtVoNyWQS4+PjrBcg3wtyaSYaTTw0B5FIBLlcjk2bNmHXrl2s6rzX68Xo6Cjy+fyyey7/+6LT6dDf3w+73Q61Wo1sNotgMAifz0eTyOuMUChk9RVUKtWyZ65arYZ8Po/5+XnMzc0hHA4jkUis6fjWNPi8XnyKz9L0TXpobV7VahWBQADFYhEzMzNQKBTQ6XTQaDSw2+0QiUTweDyYnZ1Ff38/br75ZjidTgwMDLAKfJFIBC+88AIWFhbw3HPPIRAIrPlJQq5MLBbD6XTCZrOhq6sLLS0t+OEPf4ihoSFMTk5e9ns0Gg0cDge7ABaLRUSjUUrrWSfeWg2zUqkgm82iVqtBLBZDoVCwvfi9vb3Q6XRobW2FyWRCvV6H1+vF008/Da/Xi7GxMSQSCSoStwr4VLlQKITJyUm0tbXBYrGwYyeVSuFwOJBOp2E0GlmxicutQvNBZ0dHBzo6Otjrdrsdg4ODcLvdFHg2EaPRiL6+PnR2duJDH/oQbDYb1Go1gIvna7lcRiAQQDKZxDPPPIMLFy5gfHx82c/gi0OGw2GMj49jZmYGL730EhKJBAqFAjiOw/DwMCKRCJtEtlqtlH3WYHwGmd1uR1tbGwwGA5566imcP38e58+fRzabveReazQa0dXVhZ07d6KrqwtarZYVkXvttdcwMTFB+z7XmYGBAVabYWn7pEwmg/n5eUxPT+OZZ57B4uJiQ1a111XwCfwmar/cKioFos2lWq2yla9YLIZoNMpmz9RqNTiOg91uZwHnHXfcAZVKBYPBwE4UPoXT4/FgbGyMUm2bjFAohMFgYJXxdDodfD4fhoaGlhX+WlrCX6VSwW63s+rV/P7fy6UBkeaz9FhyHLesCqJEIoFSqYTBYEBLSwu2b98OnU6HtrY2SKVSVun6xIkTmJ2dRSgUuuZKq+Tt8SvUfJ9do9G47OtCoRBqtRoajQYqlQoKheKSHp38P/lZdH5Cgdfa2ort27fDaDSyIkNL8eczrWyvLZVKhfb2dvT29mLXrl2soTy//alUKiEajSIcDuPChQsYGhpCNBpl389XKear0g8NDWFubg5TU1MoFAqoVqvgOI4VmQqHw4jH4zAYDBR8NphIJGI9mPV6PRQKBebn53H69Gn4/f7LTvTxvy8tLS0wmUyQy+Vsa8TMzAympqaQz+cb8GnIu8Xflx0OB7Zv3w6Xy8Wu5fyWl2AwyFbBQ6FQQ/bjr6vgk08N4JvfikQiFqQUi8U1q9JErh5fiIJvOM8/hMhkMohEIrbaabfbYTQaWeGLRCKBiYkJzM3N4c0334TP56OH1CYkkUiW9QMLBoMIhUKIRqPseLlcLtbceuvWrdBoNLBYLGzlMxwO44UXXmAPQldb/ZqsPYFAwAqC8cVIenp6UK1WsX37diQSCRiNRtjtdpbhEIlEcOrUKaTTaSwsLCCZTOLChQtIpVK04rkGEokEPB4PjEYj6vX6JVtTJBIJXC4XSqUSS6+zWq1QKBQwm81QqVSsQNS+ffuwd+9e9r0qlQoWiwUymWxZ8FmtVpFIJBAOh5FKpVjAQtaG1WrFnXfeCZfLBbVaze6ruVwOx48fh9/vx+uvv46FhQWMj48jGo2y624sFsP09DRisRhGRkYQi8UwOzuLZDKJYrHI7uF8IMs/e5XLZZpkaAJSqRT9/f3o6upCrVZjgcbs7Owl22D4gm89PT344Ac/CKfTCalUikwmgzNnzsDj8SAUCiGTydD5uw5wHIcdO3agq6sLN910E3bs2AGn0wngYsHOWCyGiYkJ/PCHP2T34kql0pC4ad0Fn0KhkAWe/M2OLxdObTeaD58izVfU429O/D6wzZs3Y/PmzZcUospms2zFc3p6GtFolKolNiGxWIyWlhZ0dHSgVqshFoshlUohlUqx9D2TyYS+vj4cOHAAH/zgByGTyaBQKNh5yxeP8ng8mJmZoeCziXEcxyql8k3pXS4X+3cArMIq79y5c5icnMTc3ByOHTtGM+hrLJvNIhAIIJVKXfb+KBaLYTabkU6nIRaLWTaDXq9Hd3c3jEYja5e1Z88e7N+//x3/n7VaDalUiqVoUrXMtaXX67Fjxw4YDAbI5XL2rFQsFjE6OoqpqSk899xzmJ2dveR7M5kMAoEA5ufnWdukK6Xl8RWOKWuleYjFYrjdbnR2drLUWb5Q51snB0QiEdsXvG/fPjZRkcvlMDY2hpmZGSSTSZr4Xyc4jkNXVxduvfVWbNq0CV1dXVAqlQAunvv8c9bLL7+MWCzGtss0wroKPvnKenq9HkajEVqtFgKBAOVyGfPz8/B4PJc82EgkElZqXKVSQa1WQ6vVIpFIsFneTCZDF85VxOeZJ5PJd1zpSKfTCAQCmJmZwdGjR+Hz+RCJRC67T4E0Hr+/pLOzE1NTUwiHwwgEAiwtSygUor29HbfddhsA4Fe/+hVyuRzi8ThkMhksFgskEgl27dqF9vZ2zM3NYWFhgfUAJs2H7/MnlUohFAqh0WiWtbjib3b8Hv18Po9IJIJ4PE4rIw3g9/tx+vRpaDQaDAwMwGAwwOVysRRbjUaD2267DVu3bsXg4CAKhQKMRiPkcjkMBgMUCgWb7G1tbb2qon58AFur1dDV1YV8Po+JiQnaNrHK5HI5e0aSSqVsxTMYDOLHP/4xFhcXMTw8jHg8fsU9fHy67dLWdu8GFX1sLH5CuKWlBR6Ph6VEL50g4BdxNm3ahP3792Pbtm1Qq9UoFouYnp7G/Pw83njjDfh8vjWtgEquDcdx0Ov1UKlU6OjowKZNm+BwONhkAnAxo+HMmTMYHR1l2SiNjHvWVfApFotZWXc++AQuFlaYm5uDx+O55IGVr6TK9zlyOBxobW3F3NwcSqUS64lGwefqqdVqyGazSCaT77h6mUqlMD09jQsXLuDYsWNsryi1YmhOEokEvb296OrqwgsvvICzZ8+yfUD8PrHOzk4cPHgQr7/+Op5++mn2AKTX67F9+3b09vbi85//PEqlEo4fPw6xWEyzrU2qXq+jVCohn89DqVQua7Xx1odOPuMhl8shEokgkUjQBFIDBINBBINB6PV6bNu2DW63Gw6HY1nwefDgwbf9GUsLVlzNvVIoFLK2K52dnSgUCvD5fBR8rjKFQgGbzcZWq/kKxsFgEF//+tcxPT39jj8jn8+/6+yEt+4DJ40jEonYVpdjx46xom5LJ/6Wtrb76Ec/CovFApVKhVQqhTfffBNTU1M4cuQIYrEYZSKtA3zwaTab0dnZid7eXqjVaiiVSnY+xmIxDA0NYWZmBul0uuHVi5s6+OQvZHyKpsFggMPhgNFoXFYYQaFQYM+ePXA6nWhtbUUmk2ENkpVKJWQyGcxmMwwGA+t1ZjQawXEc5ufnEQqFaEZ+lfBNrvl9YFdqh5NKpRCPx3HhwgX8+te/xuLiIsLh8LvuO0fWhlAohEqlgk6nW9agfunDKX/xK5fLmJubw+zsLKamppBIJFjp95mZGQDA6OgoJBIJurq6oFAoMDU1RdX1mlChUMChQ4fg8XjgcDhY6ySpVIquri50dXWx92YyGSwsLGB+fh6RSATpdJrO5QaKRqM4e/Ys6vU6du/eDZFo9W//l9sjTFaeXC5nrTUOHDiATZs2QalUsmN8vW3urkQkErFU7be2zyJrSywWw2g0wuFwQCKRoFarwe/3w+PxIJPJALiYjq1Wq9Hd3c2q29rtdkilUqTTaSwuLuL48ePwer1Ip9NUR2WdEAgEcLlc6OjogNVqhVKpZM9lfOGoYDAIj8cDv9/fFPfhpg4+BQIBhEIha9FhsVjQ3t4Om822LPhUqVS4++67WS/IfD6PtrY26HQ6KJVKSKVSaLVaaDQalEoltlJqNBpx+vRpnDhxgvYTrhI++HQ4HGhvb4dKpbrs+/jA85VXXsG3vvUtFItFuug1MZFIBLPZDIvFAqlUCoFAwNIseTqdDlarFcViEWNjYxgeHsbZs2fZha9QKCAWiyGRSOD48eOw2WwYHBxEZ2cnDh06BK/X26iPR64gn8/jiSeegFAoREdHB0wmE3Q6HVQqFR544IFlwWcikcDw8DDGxsYQCATYAxBpDJ/Ph5dffhlCoRAf+chH3tX3Xms/XoFAAJvNhkKhALlc/q6+l1w9pVIJq9WK3bt345FHHoFGo4FGo3lXq9XvFsdxEIvFbGuTUChk/z+y9qRSKdxuN6ssXq1W4fF4cOHCBSSTSXAcB6vVitbWVtx33314//vfD41GA4PBgGw2i1AohOnpaTz33HMN3w9I3h2BQIDu7m7s2rULbrcbGo2GfY0PPOfn53H+/Hmk0+mmyCRc0+CT7xUmFovZPkyxWAyVSgWJRAKtVrtsdpS/oGk0GpZma7fb0draumzWln+PSCRijcs1Gg0kEgni8TgKhQJrhMxXXfX7/RgfH4fH46FUsFUik8nQ19cHu92O7u5uuFwuKBSKy76Xb6Hz1gb2pDkJBALIZDJIpdJlbXHS6TSbyCkUCkgmk5ibmwPHcVhcXLxse6R8Po+ZmRmUy2X09fVBoVBQz8Amxp+fyWSStVmpVCqXpEnzwefs7GxT3OxudG8NIN/NNZavZsp/D7+Ngu+7rVQq0dLSctl2K8ClvWHJyrLZbNixYwe6u7tZ1tdq/32LxWLY7XbYbDZYLBZqs9JgfPXhcrmMarUKgUCAzZs3QyAQsGwjvtdvZ2cn5HI5JBIJBAIB0uk0pqam4PV6kc/nacVznRAKhbDb7dDpdGw1m9+OyFtYWMDrr7+ON998E9lstuHptrw1Cz75oFMsFrNUrfb2dmg0GnR2dkKv16O3txdms5l9Dx+kGgwG2Gw2dgPj262wDyESwWKxoFKpQCaToVQqsQfi8+fPY2pqilVOLRQKyGazrPcZ/+BEVp5arcZHPvIRbNq0CXv27IHVal22Yr0UXejWFz7tVqVSQSgUolarIRqNIhgMsiAkkUggl8shHA5jaGjoinur0+k0jh49inA4jE984hMsVZ40r3q9ztrq8AWI3rqy6fP58Nxzz1Gl6g0gnU4vq5Y7NzeH0dFRtv/X7XbDarXS6maDbNmyBZ/4xCfgdDphMpmueJ9dSXxLj7a2NnR1dcHtdoPjODrXG6RarbK+2cViEUKhEPfeey9uv/12SKVSiEQiqNVqVmkeAJssCAaDOHz4MCYnJ5FKpZomQCFvTywWY+fOnejo6MDBgwexbdu2SyYAz5w5g3/4h39AKpVihcSawaoFn0sbyvN9wPhN8EajETKZDDabDSqVCg6HAyqVCk6nEzqdjs2s84EmvxLy1pm8crnM+gmGw2EUCoVlD7+1Wg2jo6NYXFyE1+tFMBhkfalyuRydYCtsaRoOP2HQ1tYGp9MJpVIJoVCIXC7H+n6Wy2Wo1Wqo1WoIhUKWvkPWj6UPOfyDKJ9JwBecqVarLN39cmq1GnK5HAtOBQIBrZKsA3w6n0gkYrPoS9Pu+OJEjeojRt49/ljxrVH4SuNerxfhcJi9j2/FAVy8Bmg0GjrGDSQQCNj9c+m1M5/Pw+/3Y25ubsWCQoFAAKlUCp1Ox4JOtVoNjuNQKpXYvZ0ymNYWX9gxHo9jcnIStVqNZRuWy2VUKhWkUilUq1XWSqlSqbC0zNnZWVYskDQ3/llboVDA4XCgra2NZX8CF++9fMu7UCiEVCqFfD7fNIEnsIrBJ7/S2d7ejve///2w2WysnLPT6WSb1Pl2DEv/yV+8+FQfsVjM0giWPuymUikcOXIEfr8fL730EsLhMGZnZ5fNwPPptvwfYPU239/oxGIxdDodDAYDbrnlFrS2tuLAgQNwOp1sdYxvueD3+xGLxTA4OIiBgQFWNfNKBYlIc6vVakin04jH4yzI5FOA+ON5pXOuUqkgkUiwhsdk/eA4DgaDAa2trdBqtWzSsZlucuTq1Go15PN5NqmbyWTw0ksvYXJyEkNDQ8sqpfL3U51OB4fDAZFIROduEwoGg/jJT36CmZmZFdtzLRaLYbVa4Xa78cEPfhCdnZ0wGAzLHniz2SybeCRro1QqwefzIZPJ4L//+7/hdDqxf/9+WK1WJJNJ5PN5nDt3Dh6PB3fddRfuuOMOpFIpxGIxnDp1Ci+99BKy2Sydx+uAQCBghVN3796N7du3w2q1ssnfarWKqakpnDt3DufOnUMsFmu6e/KqBZ9arRYOhwNdXV3o7OyE2WxmaTn8snChUGCzNfyMK793jM87LxQKcDqd6OzsZOWh+dz2dDoNj8eDxcVFLC4usrYc1MS8MUQiETQaDUwmEzo6OuByuVhaJr+BfWJiAqFQCNlsFvl8npXx5vfj0irJ+sFPBC0NLi832/1Ox1MgELBqjQBoxnydeet+Pn4FnL8O07FsDtVqlW07iUajrBoqfz8tlUrw+/0sVZ7fBzY3N4dQKIREInHJz5RKpWxV5XIEAgGUSiWrwcBPQtLvxNqoVCpIp9PIZDLX/fDJLyhotVq24sl3EAAuNrHnezTzqfbN9sC70dVqNRSLRfj9flQqFRiNRjaRlM/nWeEhfutaJpOBx+NBIBBg+wHp3Gxe/IqnXC5HR0cH7HY7zGYztFot6+fJT/7Mzc1hfHwcwWCwKa+5qxZ8bt26FY888ghcLhe2bdsGkUgEgUCAXC6H0dFR1vstm83i3LlzrJdjrVZDLBZjF8x0Oo2PfOQj+MIXvgCNRgOz2YxisYhoNIqJiQk88cQTWFxcZD0kadamcZRKJTZt2oSuri58+MMfZiWfi8UiXnrpJUxPT+OVV17BzMwMK0DU2dkJ4GJbBq/Xi0gk0nQnCbkyPui4ntVquVyO7u5udHR0ALg4KUUz5utHpVJZll4bjUYxOzsLr9fL0jdJ4+XzeQSDQUxOTuLVV1+FVquFyWRCpVKB3+9HPB7H4cOHEQwGsbCwwB5Y+cD0WohEInR1dUGv17P7Af8zyeqrVCrIZrMr0rJMKpXCarWiq6sLjz32GJxOJ9xuN2QyGXtWe/LJJ3HixAlMTEwgkUjQvbwBCoUCTp8+DaFQiNdeew1CoZBtY3vPe96Dbdu2obW1FTqdDq+//jq+//3vY3Fxke676wDfZcBut+P3f//3WU9PrVbLjvP58+cxMjKCF198ES+//DIKhUJTnoerFnyq1Wq0tbXBbDZDoVCgXC4jFAohmUzC4/EgnU4jGo0im83C4/EsCz6TySQr81yr1diNil9OzuVyWFhYwOLiIkvjpBmbxhEKhWxG1OVywel0Qq/XQ6FQIBaLsYqns7Oz8Pl8iEaj6OrqYr2IALBqmfRQcuMRi8WsD2+hUECpVKIZ83VAKBRCJBKxlS2xWIxKpYJMJoNgMMhSsCmboTnwe6/5e7BarUYikUClUmHHa25uDuFwmK2AXi+O46BQKFAsFtnKJ22rWF1LMxH4GhvJZPKKlYjf6WfJ5XLWuqW1tZVlNZnNZrZNKhAIIBKJYH5+nqV+0jW8MfgK8gBYqrVEIoFEImG1VsRiMZLJJKLRKAKBAJLJJB2vdYDPElOr1bDb7XC5XMv6+dZqNaRSKfj9foTDYcRisQaP+MpWLfg0Go0YHBwEAMRiMUxOTuK73/0uAoEAZmZmlrU/yefzbMVyaaP6Xbt2YdeuXdizZw9MJhOAi0vKIyMj+OY3v4nFxUWEw2EKPBtMo9Ggvb0d/f39+J3f+R1YLBZoNBokk0l8+9vfxvT0NE6ePIlIJMLev2fPHrz3ve9FS0sLgIuz8vzGaDqW68e19v8DwNJ/9Ho9Dh48CKPRiLGxMbb/kzQvjuNgNBqhVquxY8cO3HTTTXA4HEilUhgfH8dzzz2H6elpVuSNzunG4++1Fy5cgN/vZ320gYuTf3yKZqVSWdHiNHy/SZlMxjKgyMpamoGyNPh0uVz49Kc/jeHhYRw+fPiyqdNXIhKJIBaLMTg4iA9/+MOw2+3YunUrVCoV60rA7xn85je/ifHxcVy4cAGRSIQmkZuIQCBAS0sLTCYTbr31Vrzvfe/DhQsX8LOf/Qyvv/46pqam6Bq9TojFYlgsFjgcDjgcDjaRsNTs7CxOnToFn8/XoFFenVULPvn+ncViEclkEolEApOTk6xK3pXSeDiOY60W7HY7Ojs7YbFYIBaLWVP6QCCA6elpRCIR6kfUBCQSCfR6PUwmE6tYXK/Xkc1mMTs7i8nJSfj9fqRSKRiNRiiVSlYNV6lUguO4ZRVwSfOr1+vsgZXv9ScSiSCTya46/Z0v/a7T6WA2m6FSqeDxeBAMBqkSdRNbOmnApwAtnU2PRCLw+XxsYpBm1JvD0poKK7Gqyf9M/vxfWqV+KT4zhl8h53ttk5VTKpXYnj2+yinHcZBKpXA4HIjFYjAajUin0wB+0xNy6XGTSCTLHmT5yvV2ux09PT2sX7dQKEShUECxWEQkEkEwGMTMzAwmJiYQi8Xo2DYZjuOg1+vhcDhgMpmg1+tRKBRYddtcLkfP0OsEX2laJpNBJpMt66vLb3/JZDKIxWJNX/tm1fta8L2HkskkFhYWEIlErvhgKhKJIBKJcNddd+Hmm2/Gli1bMDAwwIoU8Xs85+bmMDExsWzFlDSOVqvFwMAAa3ANgDUsHhoawsTEBLshud1uuN1uOJ1OKBQKdvLwBaTy+TxdCNeBcrmMQCAAiUSCSCQCmUyGzZs3o1ar4dSpU1hcXLzi9/LBS2trKz7wgQ/A4XCgtbUVmUwGL774Iubm5tgqOWk+UqkUCoUCDzzwAPbt24fW1lZYrVacP38er7/+Ok6ePImjR4+ygnJk46pUKqzHayKRgEAggEqlumR1UywW45ZbboHRaMQzzzyD8+fPN2URjPVqbGwMP/3pT7Fv3z60tLRALBZDJpOxiQCr1YrHHnuMZRaVy2WMj48jHo+zdnU7d+5Ed3c3gN9co8ViMZxOJ3bu3AmJRMIq1h8+fBiRSARnz55FNBrF0NAQ2/5EmotYLMb73/9+3H777bDb7YjFYjh79iyeeuopxONxOgfXEb6Am1KpXHaNrdVqWFhYQDQaxczMDBYWFpBKpRo40ne2asHn0hlR4OJfTrVaRb1eh1QqZa8tbXsil8shlUrR0dGBwcFBdHZ2wm63s+qJoVAIIyMjCAaDSKVSFHg2Cb7FilqtZrnn2WwWiUQC8XgciUQCYrEYUqkUJpMJDoeDvZe/ERaLRTZzS5of35uTb2qdz+dhNBrR0tKC8fFx1h6pVqstSwXjq+xJJBKYTCb09PTAaDRCKBSiWCzC5/PB6/XS7HmT4tMn1Wo1Ojs7MTg4CJVKxYqOTE9PU+GwGwhfk6FQKCCVSkEikbB2WUtXQAUCAZxOJyqVCo4dO8a+Tr8jKyORSGBmZgZutxupVApKpZI9ZwEXn636+/vZdZXfqhQOh6FUKpHNZtHX14etW7cC+E3wKRQKodfrWTZTPp9HPB7HzMwMfD4fzp8/j1gsRiueTYq/37pcLvT19aFUKiGdTiMcDsPr9VKm2TojEAigUCigUCiWBZ98m6NwOIxEIoFsNnvNReLWyqoFn3xlPZlMBpfLhXK5jE9+8pPI5/OQyWSoVqsIhUIoFApIJpOoVqvYtWsXWlpasGXLFnR0dKBUKmFmZobNqHs8HgwPDy9rZE+aw9KHiKUTCnyaQFdXF8xmM+6//37s2LEDOp0OHMdhdnYWgUAAL7/8Ml588UWkUilaLVkHqtUqUqkUgsEgXn75ZbjdbmzZsgW7d++GTCbD+fPnMTU1BZ/PB5VKBaVSCa1Wy3pC7tq1ixWoikQi+Ld/+zcEAgHMzc0hk8nQ+d2kpFIpbrvtNnR2dmLTpk3Q6XSYn59HOBzG4cOH8cwzz1CVyxsIn3r55ptv4hvf+AY6Ojrw4IMPQq/XL5udFwqF2Lx5M1wuFw4dOsT6gtK1fmVEIhH2XJRKpdDf34/77ruPpefxk/r8hH+1WoXT6WQp0JVKBRaLZVmvXl4+n8fk5CSi0SiGh4fh8/nw/PPPI5FIIBaLXVc1ZLJ6BAIBbDYbDAYDTCYTlEolzp07h5GREYyMjDRtFVRyZTqdDvfccw86Ojqg1+vZ67VaDcPDwzh79ixmZmaQzWab/hlq1YLPYrGIeDwOvV4Pg8EAs9mMrVu3olwuQ61Wo1qtsgfNUCiESqWC3bt3o7e3FyaTCVqtFouLiwiFQhgdHcXhw4cRj8cRCoXohFlH+N6sNpuNzb5t2bKFrZZFo1FMT09jenoaMzMzdGzXiXq9zvYXzMzMoFarYe/evWhtbcXo6CjrKZZIJKDVatm+TpvNhs2bN+O2224DcHGvUigUwpkzZ+D3+1n1TdJ8OI6DRCJBZ2cnBgYGYDabIZPJkE6nMT8/D4/Hg6mpqUYPk6whvvp8KBTCqVOnkE6ncdddd7F9SUt7AfP3dT7rpdkfjtYTfh8vX0BKIBDg9ttvB8dxEIlEbAUT+M3kMF806K344JMPVIvFIkKhEBYWFjA0NIRAIICxsbEV2zdMVgdf7MtkMkGhUEAsFrPn6VAoROffOiSXy9HV1YX29nbIZDIAv8k+4Yu5xuPxdbGivWrB5+nTp/HlL38ZHR0dOHDgANRqNTZv3sxS7ur1Otrb29meEb4cv8/nw6lTp1ivOL49h9frpaq2TUokEkGlUkEulwO4+ECSzWYhEonw4IMPolwus4fV9vZ21Ot1nDhxAmfPnsXY2BjGx8fh8/no2K5DhUIBp06dgsfjYVWPnU4nuru78Z73vAfpdBpSqRRSqZRVTyyVSjh37hyCwSBOnz6NcDiMhYUF5HI5uiE2KX7vl9VqxY4dOzA4OAiNRoNSqYTZ2Vk2eUBuTPl8HvPz8ygUCvjud7+LlpYW/NZv/RbMZjPkcvmyINRoNKK1tRXBYBDRaLTBI99YkskkpqamUCgUkE6nYbFYsGXLFphMJuzatQsKheIdf0axWESpVEIikUAoFMKFCxfw7LPPIh6PY35+fl2k9N3ohEIhVCoV7rrrLmzatAkmkwmJRALj4+M4ceIEAoFAo4dI3gWJRMIW8fjtiRzHoVQq4dSpU/D7/Thy5AiGhobWzTV11YLPmZkZzMzMYPPmzSxa37Zt2yW5yrxqtYqzZ8+y2bXR0VFMTU1henp6tYZIVgi/D0wikUAgELDZUqFQiH379kGhUKC3txc6nQ7AxWM9OTmJV155BWNjY7Raso6Vy2WWOu10OhGLxfDggw9i69atbMZ96XsLhQImJiZw6NAhTExM4Omnn0Yul6PVziYnEolgtVrhcrnQ0dHBUvj4/s38jCu5MZXLZUQiEeRyORw+fBjt7e249dZbodFo2H0BuLjqplKpYDKZWK9vsnLy+Tzy+TwSiQQWFxdZam17ezsr3vhO+IyWcDgMj8eDc+fO4cUXX0Qul6OCgOsAx3EQCoWQyWRsK4xCoUAmk8Hi4iImJyfXxcoY+Q2xWAytVgutVguJRAKRSMS6RExPT2N8fBwTExOYnZ1t9FCv2qpXuw2FQnjppZcwNDSEoaEhiMXiyzaZrtVqCAaDSKfTWFxcRCQSeVc9qUjjlEolhMNh6HQ61Go1yGQy9PT0oFKpLOvtls1mMT09jVAohKGhIUxNTdEx3iAqlQouXLgAn8+HaDQKi8UCgUCwbKKpWq2iWq0iGo1ibm6OVVmkfV/NSygUQqlUwmw2495770VnZyesViuq1SqOHz+Oubk5vPHGG7hw4UJTN7Qma4NP/6rVanjxxRfR0tKCbdu2QavVwufzIZFIYHR0FIuLi6ztB1l5fM/WhYUFvPLKK5iYmIBAIIDVasXmzZuhVquh0WggFouRSqVQKBQwPT0Nn8+HZDKJVCoFn8+HmZkZLC4uIpvNsuw00twkEgn6+vrgcDjgdrthMplw+PBhTE1NYXR0FOVymTKM1hm+ZZLdbmcp1HwcVa1WWcu79WTVg89IJEJtEza4UqmEWCyGZDKJWq0GhUKBjo4OdnLU63VkMhnkcjlcuHABExMTGBkZwdzcHM3AbRCVSoWtYJ86darBoyErRSgUQq1Ww2q14o477sCmTZsgFotRLpdx5swZHD16FOfOncPMzEyjh0qaAL8Sns/n8dprr8HlckGn08FqteLcuXPw+XyYmJiA3++na/8qqlQqrBJ5IBBg+z1bWlqgUqngdDohl8shEolYm5zTp09jaGgIsVgM8Xgci4uL62olhVwkkUjQ3d2N9vZ2uFwuGAwGnD17Fs899xx8Ph+dd+sQXzfFarUuyzIELi7crcfMsVUPPsnGl0qlcOHCBRSLRbzxxhswm83o6elhTefz+Ty8Xi/i8TiOHj2KiYkJdhGkVS9Cmg/fakGtVmNwcBButxs6nQ4ikQjBYBCJRAJTU1OUvUAuq1QqwePxIBaLoVKpQKPRYHFxEalUCn6/f13O1K9nhUIBk5OTCIfDKJVK0Gg0UKvVkEgkbOVzcnISi4uLyOfzyOVyTd8nkFyeVCpFX18furu7Ua1WEQ6HEY1GEYvFqJXdOpXJZDA6Ogrg4vO2SqWCSCRCLpdjNXGy2WyDR/nuUPBJrls8HsfQ0BBCoRAUCgXcbjesViuUSiULOk+fPg2/348XXngB4+PjjR4yIeRtcBzH9pns2bMH7e3tMBqNEIlEWFhYwPz8PM6fP4/h4eFGD5U0oWKxiLGxMQDAiRMn2OuUttkY+XyenatvvPHGFd9Hx2f9k0ql2Lp1KzZv3oxKpQK/349gMEgVbtexdDqNs2fPolQqIRqNQqPRQCqVIp1OY3Z2FpOTk+tuGwMFn+S61Wo1lEolxONxXLhwAeFwGMDFTdLhcBi5XA6zs7NIJBJIJpMNHi0h5J3I5XK0tLTA7Xajr68PdrudrYicPn0ak5OTtJ2CXBUKaJoLHY+NjW+JJRKJWA9m6p++MSQSCTzzzDMwm80QiUQsYyEWi627CtQUfJLrxvd6y+fzCAQC4DgOP/nJTwD85kbH9wyjGx8hzU+r1eKmm25Cd3c3br31VqjVakxPT8Pv9+NnP/sZzpw5QylchBDSZAQCAeRyOcRiMS5cuIDJyUkEg0EKPjcAv9+P//2///eyoq18IbD19mxNwSdZMUtPAErvIGT9EYvFUCgUsFgs6O7uht1uRyAQQDAYxJtvvgm/389mWelhhhBCmks+n8fx48cxPz+P4eFh+Hy+dbcfkFxevV7fMAWjuPpVhsuXa4+yUa23GYSVQsd446NjfGO41uOs0+ngdrsxODiIL33pS6jX6zhy5AiCwSAOHTqEcDgMv9+PXC63wiO+djfqcaZzeeOjY7zxrfQx5jgOCoUCAoGAFXWsVCpNMVlIx3jju9pjTCufhBBCAFzMWMjn84jFYhgdHUW1WmVVMvneyxtl5pUQQjaaer1OK52k6dHK52XQ7MzGR8d447tRjzFw7ceZ4ziIRCKIxWIolUoAFyuXVqtVFItF1Gq1pphBX+pGPc50Lm98dIw3PjrGGx8d40tR8HkZdIJsfHSMN74b9RgDdJxvBHSMNz46xhsfHeONj47xpa46+CSEEEIIIYQQQq6VoNEDIIQQQgghhBCy8VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1VHwSQghhBBCCCFk1TVd8JnJZPA3f/M3uOeee2AwGMBxHL7zne80elhkBZ08eRJf+MIX0N/fD6VSidbWVjz44IOYmJho9NDIKvnqV78KjuMwMDDQ6KGQFTIyMoKPfvSj6OjogEKhgMlkwq233oqnn3660UMjK4Su1TeGRx55BBzHXfHP4uJio4dIrhNdr28Mk5OTeOihh+ByuaBQKNDX14cvf/nLyOVyjR7aMqJGD+CtIpEIvvzlL6O1tRVbt27F4cOHGz0kssL+7u/+Dm+88QY++tGPYnBwEIFAAF//+texY8cOHDt2jAKUDWZhYQGPP/44lEplo4dCVtDc3BzS6TQefvhhOBwO5HI5/OQnP8H999+Pf/3Xf8VnP/vZRg+RXCe6Vt8YPve5z+HOO+9c9lq9Xsfv/d7vwe12w+l0NmhkZKXQ9Xrj83q9uOmmm6DVavGFL3wBBoMBR48exd/8zd/g9OnTeOqppxo9RIar1+v1Rg9iqWKxiHg8DpvNhlOnTmH37t349re/jUceeaTRQyMr5MiRI9i1axckEgl7bXJyElu2bMEDDzyA733vew0cHVlpDz30EMLhMKrVKiKRCIaHhxs9JLJKqtUqdu7ciUKhgLGxsUYPh1wnulbfuF5//XXccsst+OpXv4o///M/b/RwyCqg6/XG8vjjj+Mv/uIvMDw8jP7+fvb6ww8/jP/8z/9ELBaDXq9v4Ah/o+nSbqVSKWw2W6OHQVbRvn37lj3MAEB3dzf6+/sxOjraoFGR1fDqq6/iySefxNe+9rVGD4WsAaFQiJaWFiQSiUYPhawAulbfuH7wgx+A4zh84hOfaPRQyCqh6/XGkkqlAABWq3XZ63a7HQKB4JJreSM1XfBJbkz1eh3BYBAmk6nRQyErpFqt4rHHHsNnPvMZbNmypdHDIaskm80iEolgenoa//iP/4hnnnkGd9xxR6OHRVYJXas3vnK5jB//+MfYt28f3G53o4dDVhBdrzeu2267DQDw6KOP4uzZs/B6vXjiiSfwL//yL/jiF7/YVFufmm7PJ7kxff/738fi4iK+/OUvN3ooZIV84xvfwNzcHA4dOtTooZBV9Id/+If413/9VwCAQCDAhz/8YXz9619v8KjIaqFr9cb33HPPIRqN4rd/+7cbPRSywuh6vXHdc889+MpXvoLHH38cv/jFL9jrf/EXf4H/+T//ZwNHdikKPknDjY2N4fOf/zz27t2Lhx9+uNHDISsgGo3ir//6r/FXf/VXMJvNjR4OWUVf+tKX8MADD8Dn8+HHP/4xqtUqSqVSo4dFVgFdq28MP/jBDyAWi/Hggw82eihkhdH1emNzu9249dZb8ZGPfARGoxG/+tWv8Pjjj8Nms+ELX/hCo4fHNF3BoaWo4NDGFwgEsH//fpTLZRw7dgwOh6PRQyIr4Pd///dx6NAhjIyMsH0Gt912GxUcugG8973vRSKRwPHjx8FxXKOHQ1YIXatvDJlMBlarFe95z3uoDccNgK7XG8ePfvQjfPrTn8bExARcLhd7/VOf+hR+/OMfY35+HkajsYEj/A3a80kaJplM4n3vex8SiQSeffZZepjZICYnJ/HNb34TX/ziF+Hz+TA7O4vZ2VkUCgWUy2XMzs4iFos1ephklTzwwAM4efIk9YLcQOhafeP4+c9/jlwuRym3Nwi6Xm8c//zP/4zt27cvCzwB4P7770cul8PQ0FCDRnYpCj5JQxQKBdx3332YmJjAL3/5S2zevLnRQyIrZHFxEbVaDV/84hfR3t7O/hw/fhwTExNob2+n/WIbWD6fB3AxYCHrH12rbyzf//73oVKpcP/99zd6KGQN0PV64wgGg6hWq5e8Xi6XAQCVSmWth3RFtOeTrLlqtYqPfexjOHr0KJ566ins3bu30UMiK2hgYAA/+9nPLnn9L//yL5FOp/F//+//RWdnZwNGRlZSKBSCxWJZ9lq5XMZ//ud/Qi6XU5CyAdC1+sYSDodx6NAhfPzjH4dCoWj0cMgKouv1xtfT04Pnn38eExMT6OnpYa//8Ic/hEAgwODgYANHt1xTBp9f//rXkUgk4PP5AABPP/00FhYWAACPPfYYtFptI4dHrtMf/uEf4he/+AXuu+8+xGKxSxqVf/KTn2zQyMhKMJlM+NCHPnTJ63yvz8t9jaw/n/vc55BKpXDrrbfC6XQiEAjg+9//PsbGxvB//s//gUqlavQQyXWia/WN5YknnkClUqGU2w2Irtcb3x//8R/jmWeewS233IIvfOELMBqN+OUvf4lnnnkGn/nMZ5pqu0RTFhxyu92Ym5u77Nc8Hg/1nVrnbrvtNrzyyitX/HoT/kqSFUAFhzaWH/3oR/jWt76F8+fPIxqNQq1WY+fOnXjssccoZW+DoGv1jWXv3r2YmZmBz+eDUChs9HDICqLr9Y3hxIkT+Nu//VsMDQ0hGo2ivb0dDz/8MP7kT/4EIlHzrDc2ZfBJCCGEEEIIIWRjoYJDhBBCCCGEEEJWHQWfhBBCCCGEEEJWHQWfhBBCCCGEEEJWHQWfhBBCCCGEEEJWHQWfhBBCCCGEEEJWHQWfhBBCCCGEEEJWHQWfhBBCCCGEEEJW3VV3HOU4bjXH0VRu1NandIw3PjrGNwY6zhsfHeONj47xxkfHeOOjY3wpWvkkhBBCCCGEELLqKPgkhBBCCCGEELLqKPgkhBBCCCGEELLqKPgkhBBCCCGEELLqrrrgUCMJBAIIhUIAFzfu1ut1VKtV1Ov1G3YDMyGEEEIIIYSsJ+si+Ny8eTNuueUWaDQaWCwWLCws4Pnnn0cymUQgEEClUmn0EAkhhBBCCCGEvI11EXw6nU4cOHAAFosFnZ2dGB4exvnz58FxHEKhUKOHR67D0hLU/L/zq9m0qk0IIYQQQsjGsS6CT6lUCr1ez/50d3fjwQcfxOTkJPx+P+LxOGq1WqOHSd6BQCCAy+WCTqdjqdQajQZarRZOpxOdnZ3IZDIIhUKIx+OYmppCPp9HIpFAqVRCJBKhVW5CCCGEEELWqXURfEokEqjVamg0Gmg0GkilUkilUpjNZjzxxBNIJpMUfK4DHMfBbrfD5XJBLBZDKBTC4XDA4XBg27ZtOHjwIMLhMMbGxjA/P4+XXnoJiUQCPp8P6XQaiUSCgk9CCCGEEELWqaYOPvkg02g0wuFwQKPRgOM4iEQi6HQ6aDQaiEQicBzHChGR5iAUCiEUCqFWqyGXy7F582YYjUZs3boVDocDIpGIrXyqVCo4HA4AgEKhQEtLCzQaDRQKBTKZDPx+P9LpNMbHx5FIJHD+/HkWiNZqNTruhKwBoVAIkUgEi8UCpVKJ3t5emM1mqNVqKBQKALjsJGAkEsHQ0BAKhQLK5TI7X2u1GrLZLMrlMlKpFEql0pp+nhuFwWCAyWSC2WxGa2srVCoVTCYTgIvZKMDljxsABAIBpFIpRCIRJJNJxONxJBIJCIVCSCQSFItFZLNZ1Go1mhgkhJAGUyqVkMvlcDqdcDgckEgkkEqlUKvVsFgsyOfz8Pv9KBQKiEaj7LpdqVTg8XiQyWRQLpdXfUGv6YNPrVYLk8kEp9PJAk2xWAy9Xg+tVguRSMRuoKQ58BME/Oq00WjEvffei+7ubmzatAlWq5UFn0vV63UoFAq0tbUBAAYHB1EsFhEKhZBKpXD+/HkEAgFEIhEUi0Xk83mUy2X2vYSQ1bH0nG5ra4Pdbsf999+PgYEBuFwumEymK56Dw8PD+OY3v4lkMolMJsPeV6lUEAgEkMlkUCwWKfhcJSaTCZs2bcLAwAAOHjwIm82Gvr4+iERvf/uvVCoYGhqC1+vF6Ogo5ubmMD09jZmZGchkMsjlcmQyGVQqFZTLZQo+CSGkwdRqNQwGA3bs2IGbb74ZKpUKGo0GTqcTg4ODiEajOHXqFGKxGMbHx9l9N5fLset5tVq9sYNPkUgEiUQCsVgMgUDAgsxCoYBQKASfz4disUgptw0mkUigVCohlUqh0+kgk8lgs9mgUqnQ1dUFvV6PgYEBWCwWqNVqCIXCq54wEAqFUKlUEAqF6Orqgtlsxkc+8hGEQiFMTEwgEokgEokgnU4jl8uhUCis8qclK0UoFEImk0Gv12PPnj2o1Wo4ffo0UqkUuwiStSGRSCCXy6HT6dDS0nLJxJBAIIBEIoFMJsOOHTtgs9nQ3d0No9EImUz2tj9br9dj//79yOfzKBaLy4JPn8+HZDKJ1157DfPz88smlMj1MRgM0Gg02LZtG/bv3w+XywWXywW1Ws2uv28t8raUQCCA2WxeNunQ3t6OhYUFSKVSyOVyZLNZNnteKpXYzykUChgbG0M2m0UikaBjSgghq4zjONhsNrS3t2Pz5s3YtGkTu1ZrtVpwHAe5XI7W1lYYjUZoNBr2nFUsFqFWqxGJRDA6OopIJAK/349kMrkqY2364FMul0MikUAoFLIbZTqdxsjICCYmJpDP51GpVGjlq4FkMhkcDgf0ej36+vpgMBiwdetWmEwm7Nixg/3S83/eDZFIxApN2e121Ot1HDx4EMViET//+c8xOjqKs2fPwuv1IhAIUPC5jojFYuh0OmzevBl/+qd/ikqlgq985SuYmZlBqVSi4HMNyeVymM1m9PX14X3vex8kEsmyr3Mcx25ie/bsgdVqhUAgeNvghedwOPDAAw9c8p5KpQKv14toNIpEIsEmFSlQWRkOhwMdHR1473vfi4985CPsfrr0Gvx2x43jOLS2tqK1tRWDg4Oo1+uIRqOIxWJsYrhYLCKdTrO0W34iOBqN4rvf/S7m5+dZujUhhJDVw3Ec2tvbsX//fuzZswc333wzu97z/1Qqldi0aROA5df/Wq2Gu+++G5lMBk8++SSGh4fxxhtv3HjBJ8dx7GHIarUu+1o+n2fBBj2gNt7Sfblbt26FTqdDa2srNBoNZDLZslWUqw0qBAIBxGIxOI5bNku/9L/dbjeEQiHi8Tjy+TxSqdTqfEByRRzHsWPM778tlUqoVqvv+L1qtRqDg4Po7u6GTCZDLpdDvV5HtVqlyaQ1ZrfbsXfvXrjdbnR1dV2Skslvd+CzHC6XMv92LpfpwHEc28e/a9cuaDQazMzMIBQKwe/3Uxut68QHm1KpFBKJhG1b4V3NOfbWBxeFQoFKpQKRSMRWRCUSCTtveVKpFDt27IDVakU2m0UgEGD7ewkh7x7/7MP/UyaTQavVsqyV69l+xncZKJfLKBaLKzhqstYMBgNaW1tZVwleuVxGLpdDtVq97BYXjuNYdpPNZkMmk8Gbb765auNsyuCTT7Ht6enBvffei02bNi27aSaTSZw6dYrNqtKDamOp1Wq2n/NjH/sYS+viOG7ZQ2q9Xkc6nUY+n3/HQkFSqZQVlHrrKgxw8cFqz5492L59O0u9jsfjmJ+fX5XPSC5PKBTCZDJBIpGgXC6jWq0iFoshn8+/4/c6nU58/OMfh8VigUwmQzKZRLFYRKFQoFT6NbZ161b80R/9ETQaDUwm0xUfZJZO/lwvPq3TaDTiU5/6FPL5PE6cOIHJyUn8+te/puDzOslkMqjVarYl4t1mnVyOSqWCUqlc9trlruPlchlWqxWhUAjJZBIXLlzA7Ozsqs2iE7LRiUQi1iVALBbDYrFg69at0Gq1aGlpgVgsvuafPTk5icOHDyOdTiMSidD9d53iOA5utxu7d++GTqdb9rVsNguv14tCoXDZ9pQSiQR9fX1Qq9Xo7e2FwWDA0aNHV22sTRl8ms1m6PV6dHR0oKWlBXq9/pIZ20qlQqueTUQoFKJeryOTybAqtgKBgB2nRCKBfD4Pj8eDeDyOarX6tsdPo9Ggra0NKpUKLS0tly2OsbQA1dK0bLL6llYq3rp1KxQKBXw+HzKZDHK53NsGn2KxmO31tFqt0Gg0iEajCIfDSKfTtI+7AUqlEtLpNKRS6RWLuFWrVVSrVQQCARSLRba/m19Vuxb8BJVcLodYLIbRaEQ6nYZer4dCoUC5XKbVsmvAcRwsFgt6e3thMplW9Nr41p91uZ8tFouhUqlQrVaxZcsWKJVK6HQ6RKNRBAIBJBIJ1Go1Os/XET7oeevxrtfrrDomLQSsHI1GA7lcDplMxs4nlUoFmUwGhUIBo9GIjo4OqNVq2Gy2S7JR3g2hUIhEIsEKwNG2l/VLIBAsu4fz+/GDwSDefPNN5HI59gy+9P0KhQIulwsKhQIKhQI6nQ5msxk2m409061kIaKmCz4FAgHLVd63bx/27NlzzQ82ZG2l02mcPXsWJpMJ27dvh0wmQzqdRiaTwWuvvYaFhQUcOnQIk5OTKJVKb/tQ6XK58J73vAddXV34+Mc/Dq1Wu4afhLwThUKBwcFBtLa24rOf/SxMJhN+8YtfYGpqCul0GvF4/Irfq1ar4Xa70dvbiy1btiCfz+O5557D7OwsfD4fotEoPZSusVAohGPHjqG7uxsul+uS4LNer6NQKCCTyeD555/H4uIi9u3bB7fbDZPJBI1Gc13/fz6AbWlpgUKhwLlz59DS0oJYLIZwOHxdP/tGxHEcbr75Zjz66KPvWBBqNQgEAmi1WqhUKnzuc59DoVDAyMgIAoEAfvjDH+LIkSMoFAqU4rdO8Gmel5vI4PcC8/d0CkCvH5/519LSgra2NthsNjgcDrYYwwebfJBxvdkoqVQKt912G06dOoXFxUXE43G2l5usb7lcDtFoFEeOHMHXvvY1pNNppFIpdmz5hQSLxYKuri5oNBoYjUbo9Xrs3LkTpVIJU1NTmJ2dRT6fRy6XW5FxNVVUp1KpWH8at9t9VZUUSeOVy2UkEglwHIfp6WnEYjEoFApIpVIkEgnkcjlMT09jcXERi4uLCIfD71iaXyaTIRKJwGAwXHH/YL1eZ4UuqOjU2hKLxTCbzbBYLCylL5/PI51Ov+OMKb9HWK/XQyaToVAoIBwOIxwO06png2SzWfh8PkgkEoyNjV12Fj2fzyObzWJqagp+vx8WiwXlchmFQoHt7ctkMtBqtdDr9ezh6GpTdQUCAaRSKRQKBZvxp4nHa7e0B+dS1WoVxWIR5XIZmUyGfZ2vaCwSiaBSqZal8V2uNdY74dvz8D2b7XY7xGIxtFotpFIprWhfJY7joFAoIBAIWIHFlf75/N59sVjMzr+lXxMIBFAoFHA6nZf8HpTLZXg8HqTTaUSjUSr6twI4joPdbkdfXx8cDgcsFgusVitsNhvUajUr4ghcPJ/5rSr8n7fr08ifl/yecD6NvlKpwGKxsLZZl7t2kPWH/33I5XKIRCLsPl2v19k1X6/Xs2s/n97NcRwcDgd6enpY1lMoFNp4wadQKMTg4CDa2tpwxx134JZbbmGNy0lzi0QiOHLkCHvYlEqlsFqtEAqFKBQKqFQqWFhYQDabRS6XW1aS/0pyuRxmZmZYgYvL4TfHZzIZpFIpmkVfQyqVCjfddBOsVivm5uaQzWbx7LPP4sKFC++439NgMGDXrl3o7e2FWCxGNpvF0NAQm1kja29xcREvvvgixGIxnnjiicuublSrVZTLZSwsLCCXy+HkyZPQ6XQ4cOAABgYGMDQ0hKGhIRw8eBAf/vCHoVQqodfr2QPt1aR+KpVKCAQC6HQ6qNVq2iN4jer1OoaGhvDEE0+gp6dnWd2ERCKB+fl5BAIBHD9+nAULEomEFarYt2/fskJ/BoMBarX6miqW88XjOjs74XK50NbWxiYVV+pBZiOTSCTYtGkTlEolhoeHEY1GV/TnS6VSiMVidHR0wG63o7+/H5s3b4ZAIGDbWUQiEXQ6Hbq7uy+ZEMpms3j66acxMzOD559/HrOzsys6vhuRSCTCPffcgwceeABCoZD9EYlEKBQKiEQi7L2pVArT09MsM6VYLLKtEVdiNBphNBqxadMm7N69G3K5HDabDZ2dndi/fz9mZ2cRiUQo9XYD4CcncrkcUqkUq5PDb3fhr/d8ZfOl2xzvuusu3HLLLay7yAsvvICf//znK7LQ0/Dgk59x49t1dHR0wGq1sjTLUqnETjzSnMrlMqs0W6vVIBKJkM1mIRQK2QpnLBa7quCQr6ap1+vZnsLLrZrwxYvS6TQSiQRSqRQ1qV9DAoEAer0eOp0OqVRq2Z93IhaLWSEU/rzm9xTQTGtj8Kth/ATR5W4u/H6PWCzGVq1SqRRmZ2ehVCoxPT2N6elptLW1YX5+HiaTia2gXI1arYZsNotkMskqo9Lvw7WLRqOYnp5me6yXBp9zc3MIBALsoRW4GIRUKhXodDq2z4dXLBZRKpUuSfFbOrHwdkEp36qH79us1WppYuFdWNrW6Hp+Br/SwQeWAoEAarUaMpkMra2tcLlc6OjoQEdHB4DfZBdVq1W2R5/vvc7LZrNoa2tDuVy+pBgVuXZKpRIGg4Htpc3n88hkMkgmk8u2IiSTSXg8HhQKBVYz4UrBJ/97VKvVWKsk4DeroXy105UqUEYaj6+rwO/Z5jMFpVIpbDYbjEYjO/cVCsWyWEuj0UCj0WBhYQEKheKyxT+vVcODT7FYjK1bt8LlcuGhhx7C9u3bYTQaIZFIEIlEEI1G2UWPNKdqtYpsNgvg4s2KT8Hk/5svEPV2+NSejo4O3HnnnbDb7di9ezebcX+rcrmMw4cPY3R0FC+88AKGh4dp1WwNyWQydHR0wGw249SpU0gmk1cd/PNpHvxKCmk8jUaDzs5OBINBzM/PX/F85c9lfvInm83ixRdfxNGjR5HJZJDNZvHKK69gYWEB27dvx0c/+lF2Dr/dBCJfWOjFF1/EqVOncPLkSYyMjNCE0jWq1+s4d+4cpqenWYESXqVSYWm36XSaTTRwHIfx8XEIhUK88MIL7EGD4zjs3r0bPT09LC2L19nZiQMHDkAikVxVphLHcejq6sLevXtRrVbh9/tX+JNvPOVyGZOTkxCJREin09f0M/igXy6Xo6enB2q1GmazGUqlEu3t7TAajejq6oLD4WBpt4lEAqFQCMFgEBMTEzAYDBCLxdBoNHC5XCwAlclkOHjwIPr7+/HKK69gZGRkJT/+DSuRSMDn87H+uWfPnsWpU6cwNzeH4eFhdt7yK1t8dsrbpd3yk74qlQq9vb2XBBOlUon1XaaJv41BJpPBaDTC6XRi06ZNSCQSCAaDcDqd+NznPgen04n+/n6o1Wro9fpLvr9Wq2F+fh7Hjx/H3Nzcim1vW/Xgk59tW9qjiJ9x43PO+eXetrY2tLS0oFKpIJvNIh6PIxAIQCQSUfDZxN7a4w3AVfV5BMBmYCUSCZuJ4W+CnZ2dUCqVl6T58Ps8/X4/PB4PQqEQEonESn0c8g74WVKlUgmFQnFVkwtL8ZX7+NUY/mLGT1SQxuBXtK620iG/v4ivggdcLERVq9UQjUaRTqevqjperVZDLpdDNpvFwsICJiYmWNVFcu34zJB3+z0AEAwG2Wscx7EJQLFYvOx6LBQK0dPTA7lcjnw+D6FQCJlMdknFxaU/S6VSwWKx0Laaq8RnBHAcd81pkCKRiGUTtbS0sNVtlUqFrq4umEwmuN1u2Gw2VCoV1ms5k8mwh9VyuYxIJIJ6vQ6Hw8EmDvnV00qlcl3tPshv1Ot1JBIJ+P1+Fkh6PB6MjY1hdnYWIyMj7+peyT9/S6VS9kzFt2ACfvNMxafuXin7haw/QqEQUqkUWq0WTqeTZSO5XC709vbC6XTC5XItq6/DP4vx2+ZisRhCodCK3pNXLfjkl3j5G41cLofRaGSFB7RaLfr7+6HVauFwOKBUKmG32yEQCHDixAmcP38eMzMz8Hg8uPfee9HR0bFi/eVI8+A30nd3d2Pr1q1wu93Yu3cv5HI56/O5dMWE7+eZTCYxMjKCU6dOUTXMNSQSiaBWq6HT6VhbDuDqGtbzjEYjdu3aBa1Wyxoe8wEP3fAaIxgM4siRIygWi+84ccS3NlIoFJDJZLj77ruxa9cu9nWZTMau5/zs+pWu3aVSCYVCAc888wwmJiZw+PBhXLhwgQLPJlKv1zE2Ngav13tJ+udrr72GX/3qVyy112Kx4H3vex/MZjO6urpYqhZ//DmOQ2trKwDg9OnTDfk861G5XGbpktfCarXiscceQ0tLC9xu97KCXvwx4h9KfT4f5ufnceLECTz//PNIJpMIhUKw2WyIx+Nob29He3s7e1gtl8s4e/YsFhcXV3w/6o2qXC7je9/7Hp599lkAvwlG4/E48vn8uw48tVotFAoFPvCBD2DPnj3o7u5GZ2cnS5mPRqOYmprCm2++ifPnz7PqxWT947c57dq1C1arlU0yyOVydh4vXQGv1+tIJpPI5XI4ffo0ZmZmcPjwYRw/fpxlOK6EVQs++SIDCoUCZrMZarUaDocDarUaHR0dMBgM2LNnD/R6PeRyOYRCIarVKvL5PLxeLy5cuICpqSnMzMxg+/btqzVM0iD8ijg/+dDZ2Ylt27axghSXe1jlc9X5Vh7hcBihUIjSbdcQf16LxeJrLvEulUphsVggk8mWVSu+2tVysvLy+fxVnUdLq2LqdDooFAr09fVhz5497D38viF+b9+VUqtrtRqbaZ+ZmcHw8DDm5uZoMqkJJRKJy2aXiEQizM7Ostn11tZWDAwMoFarXTKbzpPJZNBoNCu6f2iju96sEIVCgYGBAXR0dMDpdEImk7Gfx6d18lkMkUgEXq8Xk5OTGBoaQrFYRC6XQ61WQygUgk6nW9bTs1wuIxgMwuv1UgGpFVKv1zE1NYWpqanr+jl8ZplKpYJOp0NnZye2b98Om822LJswn8/D7/fD7/cjEoksa8VB1jf+Oc1kMsFkMl32Pfzebr5GSzKZRDqdxszMDFsIXJoNsxJWLfiUSqXQ6/Xo7+/HAw88AL1eD7vdDqlUysq4q9VqVKtVnDt3DvF4HGfPnsXCwgLGxsYwPz/PyvvSasjGwnEcOjo64HK5cPDgQdxyyy3Q6/UsFetyAU0mk8HRo0cRDocxMjKCSCSCkZERJJNJqsi2hiqVClKpFCsKw8+e86ugIpHoHc9ZPoDlH2aCwSBCoRBisRgAXNXPIGtPLBZDqVTive99L9ra2tDX1weLxQK32w273c7exz/w8G1W3qper7Mq1c8++yzm5uZw6NAheDwe9jtA1gd+vxnHcSiVSohEIpiYmECxWMTg4OAl76/VahgZGcGZM2cwNzfXgBHfuJbWX+ArpmYyGZw+fRoLCwust2MoFEIgEEAwGEQqlYLNZsOBAwfQ2dmJ++67j+0VrVarSKVSiEQiePnllzEyMrLiD6jk2vATxHxf0Lvvvhu9vb3YtGkTWltbL5kU8nq9eOqpp+D1epFOp6+qIwHZGCqVCiKRCGKxGH72s59hfn4eyWQShUIBPp8P8Xh8Ve7LqxZ88vs5bTYbtm3bBoPBAIfDwVIo+X0+uVwOCwsLWFhYwKuvvorx8XG2X4ivtHSlk4CKlaw//N4Dq9WKrq4ubN++HbfeeuvbVvPjH1YnJyfh9Xpx8uRJdoOk9ipri1+tyuVyKBQKrAKmWCxmVRAvtwd4KX7fN7+3O5PJIJ/Po1gssq/RKmhz4ff5ymQybNq0CVu2bMHu3bvhcrne9c+q1+solUrIZDIYHh7G6Ogo2+dJ1pel+735zKVoNAqNRoNqtXrJRGK9XkcgEGD3ebI2llat5bc4RKNRNul/4cIF+P1+xGIxVrWcf+7isxt6e3uxY8cOKBQKVjWTz0KanJzE6OjoVVU7J6uLv1bzLe/sdjtuuukm7Nq1i9VaeKtUKoXR0VHWXoXvAcmjegzrw7uNiWq1GkqlEtvXzU8iZTIZlEqlVV0EWLXgM5fLIRgMsj5iGo0GdrudBZ/1eh25XA7FYhHT09OIxWLwer1IJBIoFApv+6E5jruk3DdpXnxbDr5JtdFoxO23346tW7eivb39soEnH8Dk83nWk+7UqVNYWFiAx+Nh/YpIYxQKBYyOjiKTyaCvrw89PT0oFArweDw4c+YM6+v6dseIr3rb09ODT33qUwgGgzh79iwSiQSlcDUZvlWGSqVCT08Ptm7dCp1Od00/K5PJ4MUXX4TX68Xx48cxPz9PD63rHF/MxGaz4b777kNraytMJhNLz6/X6wiHw6wn4eTkJOLxeKOHfcNIJpN4/vnnodfrWWVpn8+HdDqN2dlZxGKxZROKtVoNJpMJNpsNu3fvZvt4+T2CiUQCkUgETz75JGZnZzE1NYVUKkVZSE1AoVBg7969sNvtuPXWW+FyudDX18cyDi+npaUFH/nIR1iBKT7ltlKpIBwOI5vNYnJyEslkEplMhrXaIs1Dq9VCqVRCrVa/bZ0F4OLzdSwWw6uvvopIJILz588jEolgenoa6XSaFblazQmHVQs++SIiqVQKU1NTUCgUsNlsrEAJv/LJV1C73ArW2wWffNELWv1sfvyGd41Gg/7+frhcLuzfvx87d+684oonH3zmcjnMzc1hYWEB4+PjWFxcRCgUohXPBisWi5ifn4dIJMLu3buh0+mQz+fR3t7O0rfK5fJlg0/+eItEImg0GgiFQtx9990IBAJIpVJYXFxEMBik4LOJ8NdcmUzGegFeq3w+j6GhIUxNTWF8fJxS9TYAvn+kwWDA3r174XQ6l32dLxQXDofh8/mwuLi4osUryNvLZrM4c+YMxGIxAoEAstksgsHg2+7zVqlUaG9vR19fH3bt2gW5XA6xWIxSqcS+/9ChQ5iamqJ7chORSCTo7+9HV1cX7rzzTlbg6+1YLBYcOHCAFYDjg89SqYSpqSm2Il6r1VibJtI8OI6DUqmETqeDXC6/bKXxpfiiQkePHmVtVBKJBLLZ7Jplna16qxU+iOD3GPAPnny6TrVaveJsGd+PjG+uK5VK2ex7d3c3ANDqZ5PiNzmr1WqoVCrcddddcLvdrKy70+lkJwef0rF0g3s0GsW5c+cQCATw8ssvIxQKYWFhgWZXm0Q2m8WJEyfg9/vR3t4Op9MJs9nMesHdfvvtmJ6eht/vZ8UsZDIZZDIZbr75ZnZxlEqlSKVSmJmZgdfrxfT0NAKBAK1qNxn+Os5PFvp8PhgMhsumcL0ThUKBm2++GS6XC16vF8DFgjb08Lr+8IWG7HY79u/fj+7ublY1dalqtQqPx4OpqSn4fD5ks1l6gF1DxWIRs7OzEAgE7O/+Sn//ra2taGlpwcDAAPbu3Yv29nZIpVLW2zcQCOCXv/wlvF4v2x9G9+TmIRQKodFooNPpLmlTdyVKpRItLS2sAODSHqIWiwWZTAYikQiLi4s4fPjwivZ7JNeG36JksVigVqtxyy23oLOzE/39/awWB/CbNjrpdBrBYBCxWAyjo6Pw+/04duwY4vE4u/+uZZGpNQs++QD03eD3J/DBZ71eh1QqhUKhQFdXF4rF4lWfXGRt8fsAtVotrFYr7rjjDmzfvh0WiwUqlYq9jw86+T/8BS0SieD111+Hx+PBL37xi2turk1WRzabxenTp+H1erF9+3aUy2Xs2rULZrMZW7ZsQb1eZ6tbfDVbjUYDk8kEs9m8LPjke5jNzMxgenqa9oI1KX4yMBKJIBgMsnYN75ZCocCePXvQ0dGBN954A5lMBoVCgYLPdYjvF9ja2or77rsPDofjkv6d/ETzzMwMm1CkrIa1VSqVMD8/f1XvbWlpwb59+3DTTTfh7rvvhlgshlQqRaFQQCqVwtzcHH76059iYWEBfr+fWnI0Gb6LgMFguOqK0gqF4m377hYKBUgkEtaJgv9dogC0cfhnbLvdDpvNhnvuuYdloS29L/NxVCwWw/j4OCYnJ/Hzn/8c0WgUc3NzDZsEbOrIrVKpIJ/PI5fLIZVKQSAQQKPRoFgswufzIRwOU2GSJqRQKNDT0wO9Xo+dO3fCZrOhq6sLWq2WXQz5aqnRaBSRSASRSASLi4vsZ4TDYQwNDVG/qSbFb1RPJpN4/fXXWdBos9nYBEO5XGZl+SuVClsF5y+M4XAYZ86cgdfrxenTpxEMBmnFs0ktLRJ04sQJRCIRuN1u6PX6S97b0tKCvr4+cBx32ZR6gUAAuVwOtVqNtrY2ZLNZRCIRJJPJtfgo5DpxHMeqk5tMJnR2dqKjowPt7e3Q6/XLZtzL5TK7Npw7dw4jIyO017NJGY1GqNVqbNmyBTfffDPcbjerSp5KpRAKhXDq1ClMT08jGAwinU7T81cTKhaLOHfuHKLRKAKBADQazRXfKxKJIJFIoNFoYLPZkMvl2HOYXC5nxaYkEgmcTicUCgXuuOMOtLS04PTp07QCusYEAgHrr93a2gqtVov9+/fD6XSis7MTKpXqkgkHv9/POoicPHkSwWCQpd43sp1OUweffGoIX86bX2LO5XIsTY/SPZqPWq3G3r170dHRgQcffBAOh2PZg2i9XkckEoHf78fw8DAuXLiA8+fP48iRI+xCtrS6Gl3cmk+9XkehUEChUMBTTz0FmUyG8fFxOJ1O7Ny5Ey6XCwaDAWazmX0Pn7XAz7AuLCzge9/7HhYWFnDmzBnkcjk6n5sUf7zL5TKee+45qFSqKwafd955J7q6uiAUClmBuaU4joNCoUC9XmcPNuPj4/D5fGvxUch14K/jdrsdu3fvRmdnJ2655RYYjUZ0d3cv2wbD13U4efIkZmZm8Nprr2F8fJyu502IP6Zutxv79+/Hvffey87fbDaLWCyGyclJ/OxnP2N7dqm/dnPK5XJ44403IJfLodFo3nZrmkKhYNfyvXv3IhgM4pVXXgEAmEwmWK1WWK1W2Gw2dHZ2olarQaVSIRgM4mtf+xq8Xu+qF6YhvyESiaDT6aDT6XDw4EG0tLTg/vvvR1tb2xUne2dnZ/HrX/8a4+PjOHz4MMrlclMcr6YOPnlv/YviU3iXbowmjcO3T+FbMZhMJrS3t6Otre2Svp3JZBL5fB7Dw8MYGxuDx+OBx+NBMBikwGOd4tM6fD4f8vk8arUaZmZmoFKplu3/MhqNsNlsLDDl+wLGYjFWXY00t1qthmw2i0qlgoWFBSQSiUvec/z4cUgkEnYdUCqVsNlslxRAEIlEcLvdbFY9FAohnU5T+m0T0+v1MBgM6O/vx549e1izepVKtWyioVqtsv5wY2NjGB8fX9a+gzQHjuOg0+mgVCqxZcsWDA4Ooq2tjbW7KhQKmJ+fx4kTJ+DxeDA/P49oNEr36iZWq9XYdbRQKFx2AlCpVEKhUECtVqOjowMcx2FoaAiRSASzs7Oo1+uIRqMIh8M4fPgwbDYbenp6oFaroVQqYbVaodfrodFokM/nKWNplYlEIqhUKuh0Ouzduxdmsxnbtm2D2WyGWq1+2+JCfIZaLpdrqv7p6yL4fKtKpYJEIsH2gZLG4vfuyeVyWK1WdHR0YM+ePXC5XFAqlex9tVqNVTJ9+umn8dJLLyGVSiGdTlPgsY7xKZmjo6PgOA7Hjx+/7Cxcb28vdu7ciZtvvhkDAwPI5/OYnZ1FOBxm5f1Jc6vX6yzgDIVCl51pPXv2LH784x9j+/btePDBB+F2u2EymS5JB5JKpdi9ezdL5eULT4XD4bX4KOQatLa2YuvWrbj99tvx4IMPQigUsorlS38XyuUyFhYW4PV68fzzz2N4eJhSNJuQQCBAa2srXC4XPvjBD+LOO++EXC6HUChEPp9HIpHA6dOn8f/+3/9DLBbD4uIiqtUqXaubWLVaZdfQK3WDaGlpgVwuh9PpxB133IFTp07hu9/9LlKpFMLhMGq1GjiOYxlNVqsVjz76KHp6etDS0sImka1WK0KhEAWfq4yvMt/d3Y0/+IM/YAUeJRLJZScXluLbXiYSiaaKl9Zl8MnvJWmW5eMbHR90Go1G9Pf3o7W1FQaDgc2G1+t1VlRkfHycpUyn02nk83maRd0g+AeSKz1kVqvVS0qA8+nVdB6vH++UDs8XmYvFYlhYWIBCoUCpVLpsGq5IJGJts6h1VnPhOA4mk4mV8NdoNOjt7UVPTw9cLhckEsmyrRTVahWZTIatcs7OziIUClGF8ibEcRw0Gg0UCgU2b96Mrq4utqevXq8jn89jYWEBFy5cwOjoKGKxGNLp9LJKqKR5XekaLZfLIZFIYLfb0d3dDZlMBo/Hg8XFRaRSKZbVwn9fsVhELBYDAPh8PqhUKlZdtaOjA7t378aZM2fYe8jK4rMJrVYrtm3bxiZyNRoNJBIJ21/PV6IuFotsVZvXrM9X6zL45PeBZjIZmoFrAiaTCQcOHEBfXx9++7d/G1qtFjKZjLVbqVQqmJ+fRzAYxPe//30cO3YMqVQKuVyuKU8Ksjrkcjks1NtNHwAAF9xJREFUFgu0Wi0FGRsYX7k6GAziyJEjKBaLeM973sP2ei499nzKPv8a/V40D6FQiJ07d6Knpwc333wzNm/eDLVaDbVaDZlMtuxY1Wo15PN5TExM4K//+q/h9/tRKBRQqVQQCAQa+CnI5YhEInR1dcFut+OTn/wk9u3bB5lMBqlUikQigUQigRdffBHf+ta3EI/Hsbi4SHv7NgCz2QyLxYKDBw/iPe95D86cOYMf//jHCAQCCIVCl6RllstlLC4uIpFI4OTJk4jFYmhpaYHVasW9996L/fv34x/+4R8wMjLSwE+1cSkUCrhcLmzZsgWf//znYbFYYLfbl0381Wo1VKtVVghs8+bNV9XbtdEaGnxKJBIWoCy9kS3t+8g3tQ0GgxCLxXA6nahUKhAIBBAKhRCJRKhWq+y/+T6D2WyWtWmhaqmrQygUQiwWQ6fToa2tDU6nE3q9ns261Ot1ZLNZ5PN5tl8kFAohmUyiVCq97Y2M4ziIRKJl+0mNRiPEYvEVG+jyExHpdBrJZBLlcpn2jzUJPvAwGAyQy+VszzalcG1c5XIZ2WyWNa5+6/nOV9FMJpNs1p16PzYOn2bHF7VQKBQsJdPhcMBisbBevfwKNt9+h0/tmp2dhd/vRzgcfsc+3mTt8dUylUolOjo60NbWBqvVumzfWCQSwdTUFGZnZxGJRNhqGFnf+CrVLpcLJpMJKpUK9XqdrWpfaT8g3985lUohHo+zjEOlUgmhUHhN7bbI1VGpVOjq6kJ7ezvMZjN0Oh0rIJXJZFAulxGPx5HL5eDz+ZBMJtdNCnTDgk+RSMT2ASmVymX9Ovm+gPwDaigUwq9+9SsMDg6yhrcqlQoajQZarRbFYhESiQRqtRr33XcfbDYb3nzzTfj9foyOjlIVxVWiVCpZX8f77rsPRqMRUqmUfb1UKmFqagqBQADf+c53WGPbfD7/jjOoEokEBoOBlQI3Go344Ac/CKvVyiYY3qpSqaBcLuP48eN45ZVXEA6HMT8/T7O1DcanVNpsNuzatQtyuRyLi4us3HehUKBjtAHxPUETiQQLROr1OptoLJVKOHnyJLxeL86dO4fp6el1c+PciMRiMdra2mA0GnHbbbfB5XKhvb0dBoOBPbDyezv5Y5hOpzE/P4+5uTk8//zz8Pl8mJ+fRzabZec0TS41D4lEgs2bN8PhcOCRRx7B5s2bYTKZlk3mvvbaa/jud78Ln8+HQCBAx2+D4DgOW7ZswXve8x5YrVZIJBIUCgX4fL53zEKrVqusu0QqlUK1WmV9nin4XD38Hk+bzcZWPAUCAQqFAsbGxhAKhfDSSy/B5/OxdNzOzs5GD/uqrFnwya9MCoVC1qfG7Xaz/OSlwWe5XEa1WkUul0M+n2fV9KRSKTiOg1wuh8PhgFgsRj6fR7FYhEwmg0qlQkdHB6xWKwKBAAtKycriV5z1ej1aW1vhdDphNBqh0WiWrWBXq1Vks1lWVCiVSl2y4imXyyGXyy9Jt1MqlXA4HJBIJJDL5TAYDGhvb4fFYrli8BmPx5FMJllvMgpomgPHcRAKhZDL5azvZzKZZHuI6FhtLPy1np+c0ul0l81W4Cvn8quexWKRitI0EL8qplar4XQ64Xa7YbFYoNFoWBEaYHmbpWAwCI/Hg7m5Oba1go5jc+JXqfhiMXxPZj57jK/BsLi4iIWFBSSTSVrx3GAUCgX0ej1LnVer1TAajZBIJGzRZ2mmIP+8LZPJ2LM6fx3gr+e0VWLlicViyGQy6PV62O126PV61roqGo0ik8lgenoakUgEHo8HgUAACoXibXu6NptVDz75B0+ZTAaj0Qi9Xo+9e/fCarXi1ltvhdFoXJbGwxcuqFarKBaLKJVKUCgU0Gq1kMvl0Gq1MJlMcLvdKBQKiEajqFarLB3TZrNBKBQil8tBoVBgcnJytT/iDUen07F9nh/96EdZH6i3PmDWajVWrlulUsFmsyGfzy/rD9bf34/du3cDwLJiJBaLBbt27YJKpWIXRz7lgK+wuFStVsPExARee+01vPnmmxgfH6eCVE2Cz24wm81ob2/H3Nwcjh07hvHxceTzeUq13GCUSiX0ej127NiBhx56CA6Hg13n33relkoltjeQipk0lkAggFarhcViwdatW7F582aIRCK2vQIAezidmprC2bNnMTY2hhdffBGpVAqhUAjlcpm2uTQhPpXaZrPhAx/4ALq7u9Ha2gqpVIpcLodCoYDnnnsOZ86cwcmTJ+Hz+Sjw3GD4tHqNRgOr1QqXy4U77rgDOp0Ok5OTOHz4MGKxGDweD5s8ksvlGBwchNlsxo4dO2Cz2dizHkA92FeL3W5Hf38/65ler9fh9Xrh8XjwjW98A36/H5lMBqVSCfF4HACwc+dOdHd3Q6vVNnj0V2dVg0+BQACJRAKVSgWlUgmn0wmTyYTOzk5WbYtPvRUIBGyvJ78PjJ9dlUgk7ObH39h0Oh2q1SpkMhnq9ToLfORyOarVKgtQ3q7/Dbk2AoEAYrEYarWazcos3QD91vdKJBLo9XoUi0Vks9llq9wtLS3o7Oxkezt5FosF3d3dLPh8p3LSwMUHI35FLZvNrsyHJddNLBZDoVBAoVBALpejVquxdMxm6jt1I+GzUCQSyWXTpiqVCkvFemva3VuPF3/ei8Vidq7zDzednZ0wGAyQSqVX3KfN/6Hfg8YSCATQaDSsf9/lZtFLpRJyuRyrZDw/Pw+Px4NCoUAF5JoUx3Gs767dbofT6YTD4YBUKl2WheL1ejExMYFAIEDp7xsY/7wsk8lgNpvR3d3NCtbI5fJle3yVSiXa2tpgMpngcrlgsVhYTY9cLodSqUR1NVYQ/xys0WjQ0tICs9kMmUzG6tckEgm2lZBfXKlWq+w+rtfr2f38rbVzmu3avGrBp1QqhUKhQGdnJ+6++27YbDbs2LGDlW2XSqXQ6/UQi8XsoYRPveL/0mKxGNsMfblSzvV6nZ0k/APQ/6+9O/lp43zjAP71AgYbg20ImNiYRQTqQBFJ1aSVmp5676n/R/+VXnrpubekUtQDbaUqbSUSASFNYkJYbbxvM4zH9niZsT2/Q/S+YnFSkh/GDjwfKQpiN+MZz/O+z2IymVCr1fDo0SPe/ICcL0VRkEqlcHBwgI2NDfh8PoyMjBwLKoE3q2Z3795FtVrF7du3oSgKZFk+tvPp8Xjg8XhOzYljNbxs5f0sWEObo22mSfuNjo7C7/fD6/UCAERRxOrqKq2ut9Ho6CiGh4fx+eef44svvji1cBSNRvHrr7/ylFgWgLKUy0ajwRvFsWyE+fl53Lx5kwedbrcb09PTZ5pFRtrPZrPhm2++wdzcHNxud9PPCQaDePXqFXZ3d/H8+XMkEglUq1Xate5QrMxpfHwc33//PcbHxzE/P4++vj5UKhXkcjk8fPgQGxsbeP78Ofb391Eqldr9a5MW0HUdoiji4OAATqcTADA4OAir1YqJiQncunULpVIJgiDw6313dze8Xi96enrgcDjQ3d2N/v5+NBoN/PXXX3j58iWeP3/exkd1udjtdgwMDOD27dv47rvv4Ha70dXVxcvV6vU6zxY6Ok7HaDRienoad+7c4YuG1WoVlUoF+XweuVzuWB1+J2hZ8Gk2m2G1WjEyMoK5uTl4vV589tlnxxrSsB1OVVVRq9WQy+V4YKLrOrLZLERRhCiK79U0iA24Zs1tyPnSNA3lchmyLCOdTsNut0NVVZ5izZhMJgwNDUHXdTgcDmiahkqlcizNkjWN+hBH6wXZiXkyiCXtZ7PZeHc9g8HAm4jlcjlqZtEmbJV0amoKd+7cOXXOOJ1OPHv2DDabDbIs8zQsNrO3VqvxbJPu7m50d3djYmICc3NzGBsbw8zMDGw2G+x2e9PzkTUHYyUW9Dxov66uLni9Xvh8vrc2ESmXyxBFEfl8nnerPtq1vtnNDQtMO3H1/bIzGo2wWCxwOByYm5vDxMQEXC4XjEYjJEmCJEnY399HIBBAOByGIAjt/pVJCymKwmsGNU3j6dis9rNWq6FQKPDzlPX2OLpJVK/XUalUEIvFsLGxQc+Zc8SyxAYHBzE5Ocm7ULONNvav0Wjwe122i83K4dg9uKZpvG8OK23pJC0LPkdGRnDr1i0sLi7i7t276O/vP9YkRlVV7O/vQ5IkPH36FKlUCtFoFJIk8ReparXK6z7fJ4hkKzysloGcL/bk39zcRD6fx+LiIp/hODs7e6oZEKs1YKkBR280P7QhVK1Ww5MnTxCNRqGqKjRNw+PHj7G+vk4Xww7jcDgwMTGBwcFBAG9ahIfDYRQKBQo62oSdiy6XCx6P59TH7XY7XC4XDxLZzUitVkM0GoWiKLBarejq6oLT6URfXx9cLhfPPOjr6+Ojkk4qlUr8pmVjYwPxeJzS5NuMjbNiXeSbNXQDgOnpabhcLpRKJeTzeSQSCQQCAV7reTK4VFUVgUAAgiAgnU6jWCwCwLF0MNI6FosFbrcb169fx9DQEAYGBmA0GqEoCh4+fIjNzU2srKwgHA7TOXjJNRoNrK+vIxKJQBRFlMtl+Hw+zM7O8kWK7u7uYxlsrMTqaOAZCASQSCTwzz//4MmTJ02zEsmHMZvN6O3tRV9fH+x2O2/GqSgKzzhRVRUmkwlOpxM2mw03b96E2+2Gz+c7NrYykUhgZ2cHm5ubiMViPKu0U7Qs+LRarbh+/TpPq2RBxtHAMp1OI5VKYW1tDQcHB9jb2+Nb/vSi1LnYLmM2m4UkSbBYLIhEIgCAqamppjedrMbsbTc1b/sZ7O2TqtUqDg4OsL29zdO12clJnRY7x8n5nuzcP5l+TS4Wu6lgHQ9PstvtuH79+qn312o17OzsIJ/Pw263w2Kx4Nq1a++VvVCr1RCLxZBKpZBKpSAIAjWpaSOWsWI2m2GxWN5anwu82RFnKXsAEI/H0dvbC1VVoarqqddtlvbV1dWFUqnEd0F1XYemadQUrsVMJhPvucHGYrDZrFtbW1hfX0c4HIYoiu3+VckFSCaTyGQy8Hq9GB8fh8ViweTkJA9ajEZj06yHo/ftiUQCwWAQkUiERtmdM5PJxBcBLBbLsV43oigil8vxGu7+/n44HA7MzMzA5/PB4XAcyz6RZRnRaBTpdBqyLHfccWpZ8CmKIl68eIGenh7EYjGYzWY+cHxvbw+iKGJ5eRnpdBrRaBTFYpGnd3XaH4k0x1IBBEHA06dPIQgCXC4XHA4HPB7PmQPNo1RVhaIoiMVi+PPPP1EoFCBJ0qmAsl6vY2dnB6Io8lQEQRCo9qiDsHSe+fl5fP311zAajQiFQshms7S49JEymUx8F4XVev7XnDfWPI4RBAGPHz9GKBTC7u4uZFlGPp9v9a9O3qKnpwdTU1OYnJx85451Mw6HAwsLC2g0Gk0X/Wq1Gqampni9v6qqEAQBhUIBgUAA29vbvCM6OX9HGzey19ZIJIJUKoXd3V2EQiG+G00uP1bi8PLlS8iyjKGhIfzyyy8YHh7GJ598woOek+d/vV5HJpNBoVDA8vIyIpEI9vf3+UISOR8ulwszMzN8pifbhXY6nfjqq68wOzsLp9OJSqUCn8+Hvr4+3Lhxg3eyZuWKuVwOy8vLWFpaQjQa7chj1LLgs1AoIBwOw+PxQBAEXmNweHiIJ0+eIJlM4tGjR7Ti9hFjF558Po9QKARd1xGLxaBpGoaHhz8o+NQ0jadlLi0tQRAERKPRpuM4WP1oJ55Y5E2tp8vlwvj4OPx+P5LJJILBYEeuwl1luq6fOdgwGAxwOBzv9f1ZkwSWalkoFLC1tYXd3V3E43HaAW+zrq4ujI6OYnR0tOk4nHex2Wyw2Wzv/JzZ2Vn+tq7rODg4QDabhdls5vXDFHy2BuupwUpTyuUyEokEYrEYEokE/d2vGHbPFo1GEY/Heb3+jRs3UCgUeMrnydcDTdOwt7eHw8NDrK6uIh6Pt+kRXG5sJCEbK8iuxTabDX6/H2NjY7DZbKjX6/D5fLyfBuulo+s6ZFlGIpHA1tYW1tbWOjarqGXBJ5s/8+LFC/z444+80QgbYlwsFqmr2iVRKBSws7ODTCYDWZYxODiIxcVFnu5jtVqxsLAAl8vFvyYcDiOdTkOSJORyOf5+RVEgCAIikQiCwSB/njQb90C7nJ2tq6sLvb29fPWuWCwikUhQjUgHKJfLkCQJoVAI6+vrvJX+eYynymaziMVi/EYnnU5jbW0NlUoF1WoV+Xwe29vbkCSJZrx2gGq1ir29PeTzeSwtLcHn82FmZgYOh4PX9fb09HzQYuLJBlXAm91Qg8GAxcVFeL1e/Pbbb3wXhZwvVVWRyWQAAD/99BOsVitisRhyuRwFnlcYS6NVVRX1eh3RaBR///03zGZz0z4cuq5DkiTeaJK0xuHhIba3t+HxeFAoFGCxWNDT08MzjIxGI6ampqDrOq/NZ9dV1rxvd3cXz5494yOwOrUMraXBp6qq2NzcxObmZqt+DOkAiqIgGAzCZDJhe3sbAwMDiEQifGC5w+HA2NgYDz7ZDumrV68QDocRDof59yoWizxtIBwOd+yJQ97taBc2s9kMXdehKAqSySRyuRzdaLZZpVKBLMuIRCIIBAK4ceMGRkdHAeD/Dj5FUcTGxgav3d/e3sbPP//Mx7bQse8srH5eEAQ8evSIj77yer28Vvt96vWPYjvdqqrykTuapsFgMGB+fh4DAwOIxWJ48OBBCx4Z0TQNgiBAlmVIkgSTyQRFUfguKLmajs6A1DQNyWSSxhJ2AEmSEAwG4ff7eQMwlgbNdqn7+vqafi07lqFQCGtrawiHwx276wm0MPgkVw978heLRezv76OnpweRSIQPLmbdTnVdRygUQiaTweHhISRJ4t9DVVUUi0WUy2W6Sf3IDQ0N8TqySqWCSCSCx48fIxwOU81nm7E6r0AgwBsTVKtVjIyMwO/3/+dczkajwRvEsfOV2dvbw7///stX1zOZDIrFYke/EJI3195gMAhBEFAul+F0OuF2u9Hf3887pTL9/f0YHByE3W7H8PDwqTS9SqWC169fQ5Zl7O7uolAo8IUoQRBQKpXg9XoxOjqKYDB40Q/1ymk0GlAUBQaDgTeGotdXQjoLm7P68uVLPHjwAFNTU7h37x5vBHdSo9FANpvlvXSy2SxWV1ext7d3LKOwE1HwSc4NS+NQVRWvXr069rHff//9rV9DLh+DwQC32w2/34+BgQF+cfzjjz9QrVZpR7vNZFmGLMuIx+NYXV3FwsICisUiFhYWMDMz85/BJ2u5z0alHB1vdHBwgM3NTb7zSef4x4FlKgHAysoKjEYjH5Hk8Xj44iEAjI+P8/nd165dOxV8KorCF5pWVlYgCAJvZsQaDvn9fkxPT2Nra4ueIy1Wr9epqRchHY41ZV1ZWUE0GsW9e/fw6aefor+/H93d3U0bQbGOtktLS7yXQiwWa9MjODsKPsmFoJuLq4ddKNm4hVKpBFVVO27Y8VWn6zoODw+xsbGBfD4PVVWPzXprplar4dmzZ4jH4zg8PDzWMVMURd61nM77jxNLycvn86jX66jVaseaA4qiiEwmA6fTiUAgcCpVu1gs8qAzlUpBURRUKhWYTCYUCgVUKhUkk0k0Gg1ek0gIIeRNKYQkSdja2sL9+/dhtVr5zM+j2NxtWZaxtbWFZDL50czrNehnvDs4azfEy+Cq3jDRMb78LuoYG41GfPvtt/jyyy/h8/kwNjaG+/fv44cffriwlNureoyB9z/ObMYb+/8s2K7myb/zRQedV/U4X9S5bDAYTv0s9r5mH2NYdkOzZnFHv8dZni90jC8/OsaXHx3j9/sa1jvjXY7W73bCgu9Zfz7tfBJCzp2u60gmk3j9+vWx7sXtvjCS5nRdp1Ro0lSrbmg64UaJEEI6Ebs+XtZeCbTz2cRVfUGkY3z5XeQxNpvNfGC90WiEpmkXeiG9qscYoHP5KqBjfPnRMb786BhffnSMT6OdT0JIS9RqNarvJIQQQggh3P830I0QQgghhBBCCDkDCj4JIYQQQgghhLTcmWs+CSGEEEIIIYSQD0U7n4QQQgghhBBCWo6CT0IIIYQQQgghLUfBJyGEEEIIIYSQlqPgkxBCCCGEEEJIy1HwSQghhBBCCCGk5Sj4JIQQQgghhBDSchR8EkIIIYQQQghpOQo+CSGEEEIIIYS0HAWfhBBCCCGEEEJa7n+PrKy0MNBOWQAAAABJRU5ErkJggg==\n"
},
"metadata": {}
}
]
},
{
"cell_type": "code",
"source": [
"labels = pd.Series([label for _, label in trainset])\n",
"counts = labels.value_counts().sort_index()\n",
"counts.plot.bar(figsize=(7, 4), color=[\"#F2B705\"])\n",
"plt.ylabel(\"Count\", fontsize=16)\n",
"plt.xlabel(\"Label\", fontsize=16)\n",
"plt.xticks(fontsize=14, rotation=0)\n",
"plt.yticks(fontsize=12)\n",
"ax = plt.gca()\n",
"plt.tight_layout()\n",
"ax.spines['top'].set_visible(False)\n",
"ax.spines['right'].set_visible(False)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 406
},
"id": "9nRkBQ_UvZHw",
"outputId": "0efdd1d6-b84a-4ea6-de08-276be6ad2ca0"
},
"execution_count": null,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 700x400 with 1 Axes>"
],
"image/png": "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3NKMWZSHh8dl+wAAAFC+Ku2Z2OzsbN1///06dOiQNm7cqFtuuaVQf8OGDVW/fn3t3bvX4bXx8fEKDg42nwcHB+v8+fOFrmwgSXv27DH7SzsmAAAAnKdShti8vDwNGDBAu3fv1po1a3THHXcUW/fwww9r48aNhT663759uw4dOqSIiAizrW/fvqpRo4beffdds80wDM2dO1cNGzZUWFhYqccEAACA81TK7QTPPfecNmzYoPvvv1+nTp0yb25QYNCgQZKkiRMnas2aNerWrZueffZZZWZmKjo6Wm3atNGwYcPM+kaNGmns2LGKjo5Wbm6uOnTooHXr1mnnzp1avny5uc+2NGMCAADAeSpliE1MTJQkffLJJ/rkk08c+gtCbGBgoL744guNHz9eL774otzd3XXfffdp1qxZDvtTZ8yYoeuuu07z5s1TTEyMWrZsqWXLlmngwIGF6kozJgAAAJyjUobYuLi4Etfeeuut2rx58xXrXFxcFBUVpaioqHIbEwAAAM5RKffEAgAAAH+FEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcipliM3MzNTkyZPVs2dP1a1bVzabTTExMcXWHjhwQD179pS3t7fq1q2rwYMH68SJEw51+fn5euONN9SsWTN5enqqbdu2Wrly5VWNCQAAAOdwc/YEivPnn39qypQpaty4sf72t78pLi6u2LqUlBR17txZvr6+mjZtmjIzMzVz5kzt27dP8fHxcnd3N2v/9a9/acaMGRoxYoQ6dOig9evXa+DAgbLZbHrkkUfKNCYAAACco1KGWH9/f6WlpcnPz0979+5Vhw4diq2bNm2azp07p++++06NGzeWJIWEhOiee+5RTEyMIiMjJUmpqamaNWuWnnrqKc2ZM0eS9MQTT6hLly765z//qYiICLm6upZqTAAAADhPpdxO4OHhIT8/vyvWrV27Vr179zbDpiR1795d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4uLidOONN2rNmjWV69NAZ6dolI89e/YYPXv2NHx8fAwvLy8jJCTEWLVqlbOnVe4KzlRd7vHYY485e4rl5kprVRU6C/3tt98aI0aMMG699VajTp06hpubm1GvXj2jW7duxrx586r0WehLVcUzsXFxcUb//v2Nli1bGj4+Poabm5vh5+dn9O3b19i8ebOzp1chfv/9d2Po0KGGn5+fUaNGDSMwMNB46qmnjD/++MPZUyt3e/bsMSQZISEhzp5KhcrOzjamT59u3HbbbUbNmjUNNzc3o2HDhsagQYOM//3vf86eXrmaPHmy0aZNG6N27dqGp6en0bp1a+Oll14q9gyts9kMwzCueXIGAAAArkL1+YozAAAAqgxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLAAAACyHEAsAAADLIcQCAADAcgixAAAAsBxCLABUEk2bNpXNZlNMTEyFHcNms8lms1XY+Jc6fPiwbDabmjZtek2OB6B6IcQCAADAcgixAAAAsBxCLAAAACyHEAsAFnTixAn95z//Ua9evdSsWTN5eXnJx8dH7du31+uvv67s7OwrjvH+++/r9ttvV61atVSnTh316tVL33zzzWXrL1y4oAULFqhr166qW7euPDw81KxZM40aNUrJycnluTwAuCJCLABY0ObNm/Xss8/qxx9/VJMmTfTAAw8oJCREP/30k1588UXdddddstvtl339+PHjNXLkSNWsWVN9+/ZVYGCgNm3apE6dOunjjz92qD979qzuuecejRgxQt99953atm2rPn36yMPDQ3PnztVtt92mhISEilwyABRCiAUAC7r99tu1e/dupaSkKC4uTitXrtS2bdv0+++/Kzw8XLt379Z//vOfy75+7ty52rZtm3bu3KkVK1Zo3759euONN3ThwgUNGzZMx48fL1T/5JNPKi4uTr1799Yvv/yiuLg4rVmzRgcPHtSbb76pkydPasCAAcrLy6vopQOAJEIsAFhS69at9fe//92h/brrrtM777wjSVqzZs1lXz9y5Ejdddddhdr++c9/qn379kpPT9eCBQvM9gMHDmjlypUKCAjQihUr1KBBg0KvGzt2rHr16qWkpCRt2rTpapYFACXm5uwJAADKJi8vT3Fxcdq1a5fS0tKUlZUlwzBkGIYk6aeffrrsax977LFi24cMGaK9e/cqLi5OEydOlCR9+umnMgxD9957r2rXrl3s67p27apPP/1Uu3btUu/eva9yZQBwZYRYALCgpKQkPfjgg9q/f/9lazIyMi7b16xZs79sT0lJMdt+/fVXSdLChQu1cOHCv5zXiRMn/rIfAMoLIRYALKhfv37av3+/evfureeff1633HKLfHx8VKNGDeXk5MjDw+Oqxi84mytJ+fn5kqTg4GD97W9/+8vXhYaGXtVxAaCkCLEAYDEHDx7Ujz/+qAYNGujjjz+Wm1vhP8qTkpKuOMZvv/2m4OBgh/bDhw9Lkho1amS2BQYGSpLuvPNOzZkzp+wTB4ByxBe7AMBiTp06JUkKCAhwCLCStGzZsiuOsXTp0r9s79q1q9l27733SpI2bNhQouvPAsC1QIgFAItp1aqVXF1dtW/fPsXFxRXq++STT/Tmm29ecYz33nvP4bVvvvmm4uPjVbt2bQ0fPtxsv+222/Twww8rOTlZDz30kHm29lLnzp3T8uXL9ccff5RlSQBQamwnAIBK5tVXX9XcuXMv2//uu+/q6aef1ttvv627775bnTp1UkBAgH766Sd9//33eumll/Taa6/95TEKLrHVqVMnNWzYUP/973+1b98+ubq66oMPPpCfn1+h+kWLFunMmTPatGmTbrrpJv3tb39Ts2bNZBiGDh8+rB9++EE5OTk6cOCAbrjhhnL5/wEA/orNuHT3PgDAaZo2baojR45csW7Hjh3q0qWLFi1apHfffVc//fSTXF1d1aZNGz399NMaMGCAbDabpMJf0JJUqH3u3LmaN2+efvrpJ9WoUUNhYWGaNGmSwsLCij1ufn6+PvzwQy1btkzfffedTp06JR8fH/n7+6tDhw7q06eP7rvvPtWoUUPSxf21zZo1U5MmTYo9ewsAV4MQCwAAAMthTywAAAAshxALAAAAyyHEAgAAwHIIsQAAALAcQiwAAAAshxALAAAAyyHEAgAAwHIIsQAAALAcQiwAAAAshxALAAAAyyHEAgAAwHIIsQAAALCc/w+F1JrTNLXXeAAAAABJRU5ErkJggg==\n"
},
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"source": [
"We see that the data is quite evenly distributed. Let's sample the data random - iid sampling."
],
"metadata": {
"id": "3_d59TyjwqDv"
}
},
{
"cell_type": "code",
"source": [
"def partition_data(dataset: Dataset, n_partitions: int) -> List[Dataset]:\n",
" \"\"\"\n",
" Split the dataset into iid partitions to simulate federated learning.\n",
"\n",
" Returns\n",
" -------\n",
" List[Dataset]\n",
" A list of dataset (one dataset for every client)\n",
" \"\"\"\n",
" partition_size = int(len(dataset) / n_partitions)\n",
" lengths = [partition_size] * n_partitions\n",
" datasets = random_split(dataset, lengths, torch.Generator().manual_seed(SEED))\n",
" return datasets"
],
"metadata": {
"id": "VaPcBizQwhMv"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"def train_val_divide_local_datasets(local_datasets: List[Dataset], valid_fraction: float) -> Tuple[List[Dataset], List[Dataset]]:\n",
" \"\"\"Split each local dataset into train and validation.\"\"\"\n",
" trainloaders = []\n",
" validloaders = []\n",
"\n",
" for dataset in local_datasets:\n",
" validation_lenght = int(len(dataset) * valid_fraction)\n",
" train_length = len(dataset) - validation_lenght\n",
" lengths = [train_length, validation_lenght]\n",
" train_dataset, validation_dataset = random_split(\n",
" dataset, lengths, torch.Generator().manual_seed(SEED)\n",
" )\n",
" trainloaders.append(DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True))\n",
" validloaders.append(DataLoader(validation_dataset, batch_size=BATCH_SIZE))\n",
"\n",
" return trainloaders, validloaders"
],
"metadata": {
"id": "p--8Tq020Kg7"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"def load_datasets(n_partitions: int, valid_fraction: float, batch_size:int) -> Tuple[List[DataLoader], List[DataLoader], DataLoader]:\n",
" \"\"\"Handles the MNIST data creation for federated learning.\n",
"\n",
" It starts from downloading, thought partitioning, train test division and centralized dataset creation.\n",
"\n",
" Parameters\n",
" ----------\n",
" n_partitions: int\n",
" The number of partitions the MNIST train set is divided into.\n",
" valid_split: float\n",
" The fraction of the validaiton data in each local dataset.\n",
" batch_size: int\n",
" The size of batch.\n",
"\n",
" Returns\n",
" -------\n",
" Tuple[List[DataLoader], List[DataLoader], DataLoader]\n",
" Local train datasets, local validation datasets, and a centralized dataset\n",
" \"\"\"\n",
" # DO NOT MODIFY THIS CODE\n",
" trainset, testset = download_data()\n",
" local_datasets = partition_data(trainset, n_partitions)\n",
" trainloaders, validloaders = train_val_divide_local_datasets(local_datasets, valid_fraction)\n",
" centralized_loader = DataLoader(testset, batch_size=batch_size)\n",
" return trainloaders, validloaders, centralized_loader"
],
"metadata": {
"id": "mI0JmcfA0ETs"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# DO NOT MODIFY THIS CODE\n",
"trainloaders, validloaders, centralized_loader = load_datasets(\n",
" n_partitions=NUM_CLIENTS,\n",
" valid_fraction=VALID_FRACTION,\n",
" batch_size=BATCH_SIZE)"
],
"metadata": {
"id": "9Ul4N6Fy1krn"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"assert len(trainloaders) == NUM_CLIENTS, f\"The number of train partitions should be equal to the number of clients = {NUM_CLIENTS} but is {len(trainloaders)} instead\"\n",
"assert len(validloaders) == NUM_CLIENTS, f\"The number of validation partitions should be equal to the number of clients = {NUM_CLIENTS} but is {len(validloaders)} instead\""
],
"metadata": {
"id": "POpUjm78bmEw"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "hg0T11jr1CGB"
},
"source": [
"## Test Solution using Centralized Training\n",
"\n",
"In this section you are not required to implement anything. You can test your solution by doing centralized training on one of the partitions of the data by simply running the code below.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "KmBV1kh31CGB"
},
"outputs": [],
"source": [
"class Net(nn.Module):\n",
" \"\"\"Basic CNN implementation\"\"\"\n",
" def __init__(self) -> None:\n",
" super(Net, self).__init__()\n",
" self.conv1 = nn.Conv2d(1, 32, 5, padding=\"same\")\n",
" self.pool = nn.MaxPool2d(2, 2)\n",
" self.conv2 = nn.Conv2d(32, 64, 5, padding=\"same\")\n",
" self.fc1 = nn.Linear(64 * 7 * 7, 2048)\n",
" self.fc2 = nn.Linear(2048, 10)\n",
"\n",
" def forward(self, x: torch.Tensor) -> torch.Tensor:\n",
" x = self.pool(F.relu(self.conv1(x)))\n",
" x = self.pool(F.relu(self.conv2(x)))\n",
" x = x.view(-1, 7 * 7 * 64)\n",
" x = F.relu(self.fc1(x))\n",
" x = F.relu(self.fc2(x))\n",
" return x"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "wFYFDFc81CGB"
},
"source": [
"Let's have a look at the usual training and test functions:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NICmNQgb1CGC"
},
"outputs": [],
"source": [
"def train(net: nn.Module, trainloader: DataLoader, epochs: int, verbose=False):\n",
" \"\"\"Train the neural network for a classification task.\"\"\"\n",
" criterion = torch.nn.CrossEntropyLoss()\n",
" optimizer = torch.optim.Adam(net.parameters())\n",
" net.train()\n",
" for epoch in range(epochs):\n",
" correct, total, epoch_loss = 0, 0, 0.0\n",
" for images, labels in trainloader:\n",
" images, labels = images.to(DEVICE), labels.to(DEVICE)\n",
" optimizer.zero_grad()\n",
" outputs = net(images)\n",
" loss = criterion(outputs, labels)\n",
" loss.backward()\n",
" optimizer.step()\n",
" # Metrics\n",
" epoch_loss += loss\n",
" total += labels.size(0)\n",
" correct += (torch.max(outputs.data, 1)[1] == labels).sum().item()\n",
" epoch_loss /= len(trainloader.dataset)\n",
" epoch_acc = correct / total\n",
" if verbose:\n",
" print(f\"Epoch {epoch+1}: train loss {epoch_loss}, accuracy {epoch_acc}\")\n",
"\n",
"\n",
"def test(net: nn.Module, testloader: DataLoader):\n",
" \"\"\"Test the neural network used for classification task.\"\"\"\n",
" criterion = torch.nn.CrossEntropyLoss()\n",
" correct, total, loss = 0, 0, 0.0\n",
" net.eval()\n",
" with torch.no_grad():\n",
" for images, labels in testloader:\n",
" images, labels = images.to(DEVICE), labels.to(DEVICE)\n",
" outputs = net(images)\n",
" loss += criterion(outputs, labels).item()\n",
" _, predicted = torch.max(outputs.data, 1)\n",
" total += labels.size(0)\n",
" correct += (predicted == labels).sum().item()\n",
" loss /= len(testloader.dataset)\n",
" accuracy = correct / total\n",
" return loss, accuracy"
]
},
{
"cell_type": "markdown",
"source": [
"Run the centralized training."
],
"metadata": {
"id": "I6rEAgbo5KC_"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "QhVEhZbc1CGC",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "a7255c53-ec22-4259-e66a-d43f012d7304"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Epoch 1: validation loss 0.04788221110900243, accuracy 0.37083333333333335\n",
"Epoch 2: validation loss 0.047523756523927055, accuracy 0.37083333333333335\n",
"Epoch 3: validation loss 0.046505961616834006, accuracy 0.37666666666666665\n",
"Epoch 4: validation loss 0.04789999047915141, accuracy 0.36333333333333334\n",
"Epoch 5: validation loss 0.04795777161916097, accuracy 0.37333333333333335\n",
"Final test set performance:\n",
"\tloss 0.04549221425056457\n",
"\taccuracy 0.3926\n"
]
}
],
"source": [
"trainloader = trainloaders[0]\n",
"valloader = validloaders[0]\n",
"net = Net().to(DEVICE)\n",
"\n",
"for epoch in range(5):\n",
" train(net, trainloader, 1)\n",
" loss, accuracy = test(net, valloader)\n",
" print(f\"Epoch {epoch+1}: validation loss {loss}, accuracy {accuracy}\")\n",
"\n",
"loss, accuracy = test(net, centralized_loader)\n",
"print(f\"Final test set performance:\\n\\tloss {loss}\\n\\taccuracy {accuracy}\")"
]
},
{
"cell_type": "markdown",
"source": [
"You should see about 59% accuracy after the 5th epoch and 60% on the centralized dataset."
],
"metadata": {
"id": "mvLPIhI3fVfj"
}
},
{
"cell_type": "markdown",
"metadata": {
"id": "kt4G4wHZ1CGC"
},
"source": [
"## Federated Learning\n",
"\n",
"Now, we'll move to implementing federated learning system.\n",
"\n",
"You will need to implement `FlowerClinet`, create Flower Strategy e.g. `FedAvg` and start simulation."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_CEdPhgl1CGC"
},
"source": [
"### Updating model parameters\n",
"\n",
"In federated learning, the server sends the global model parameters to the client, and the client updates the local model with the parameters received from the server. It then trains the model on the local data (which changes the model parameters locally) and sends the updated/changed model parameters back to the server (or, alternatively, it sends just the gradients back to the server, not the full model parameters).\n",
"\n",
"We need two helper functions to update the local model with parameters received from the server and to get the updated model parameters from the local model: `set_parameters` and `get_parameters`. The following two functions do just that for the PyTorch model above.\n",
"\n",
"The details of how this works are not really important here (feel free to consult the PyTorch documentation if you want to learn more). In essence, we use `state_dict` to access PyTorch model parameter tensors. The parameter tensors are then converted to/from a list of NumPy ndarray's (which Flower knows how to serialize/deserialize):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "8aRP3XFq1CGC"
},
"outputs": [],
"source": [
"def get_parameters(net) -> List[np.ndarray]:\n",
" return [val.cpu().numpy() for _, val in net.state_dict().items()]\n",
"\n",
"\n",
"def set_parameters(net, parameters: List[np.ndarray]):\n",
" params_dict = zip(net.state_dict().keys(), parameters)\n",
" state_dict = OrderedDict({k: torch.Tensor(v) for k, v in params_dict})\n",
" net.load_state_dict(state_dict, strict=True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "m5zn88po1CGC"
},
"source": [
"### Implement a Flower client\n",
"\n",
"In Flower, we create clients by implementing subclasses of `flwr.client.Client` or `flwr.client.NumPyClient`. We use `NumPyClient` in this tutorial because it is easier to implement and requires us to write less boilerplate.\n",
"\n",
"To implement the Flower client, we create a subclass of `flwr.client.NumPyClient` and implement the three methods `get_parameters`, `fit`, and `evaluate`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cjLscSeF1CGC"
},
"outputs": [],
"source": [
"from flwr.common.typing import NDArrays\n",
"class FlowerClient(fl.client.NumPyClient):\n",
" \"\"\"\n",
" Class representing a single client in FL system, required to use Flower.\n",
" \"\"\"\n",
" def __init__(self, net: nn.Module, trainloader: DataLoader, valloader: DataLoader):\n",
" self.net = net\n",
" self.trainloader = trainloader\n",
" self.valloader = valloader\n",
"\n",
" def get_parameters(self, config):\n",
" \"\"\"Return the current local model parameters\"\"\"\n",
" return get_parameters(self.net)\n",
"\n",
" def fit(self, parameters: NDArrays, config: Dict[str, Scalar]) -> NDArrays:\n",
" \"\"\"Train the model on the local (train) data.\n",
"\n",
" Parameters\n",
" ----------\n",
" parameters: NDarrays\n",
" Model parameters (weights) received from the server\n",
"\n",
" config: Dict[str, Scalar]\n",
" Server based configuration (needed only if you require dynamically changing values).\n",
"\n",
" Returns\n",
" -------\n",
" NDArrays\n",
" Updated model parameters\n",
"\n",
" \"\"\"\n",
" set_parameters(self.net, parameters)\n",
" train(self.net, self.trainloader, epochs=1)\n",
" return get_parameters(self.net), len(self.trainloader), {}\n",
"\n",
" def evaluate(self, parameters: NDArrays, config: Dict[str, Scalar])-> Tuple[float, int, Dict[str, Scalar]]:\n",
" \"\"\"Evaluate model using the validation data.\n",
"\n",
" Parameters\n",
" ----------\n",
" parameters: NDarrays\n",
" Model parameters (weights) received from the server\n",
"\n",
" config: Dict[str, Scalar]\n",
" Server based configuration (needed only if you require dynamically changing values).\n",
"\n",
" Returns\n",
" -------\n",
" loss : float\n",
" The evaluation loss of the model on the local dataset.\n",
" num_examples : int\n",
" The number of examples used for evaluation.\n",
" metrics : Dict[str, Scalar]\n",
" A dictionary mapping arbitrary string keys to values of\n",
" type bool, bytes, float, int, or str. It can be used to\n",
" communicate arbitrary values back to the server.\n",
" \"\"\"\n",
" set_parameters(self.net, parameters)\n",
" loss, accuracy = test(self.net, self.valloader)\n",
" return float(loss), len(self.valloader), {\"accuracy\": float(accuracy)}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_5czKJ8U1CGC"
},
"source": [
"Our class `FlowerClient` defines how local training/evaluation will be performed and allows Flower to call the local training/evaluation through `fit` and `evaluate`. Each instance of `FlowerClient` represents a *single client* in our federated learning system. Federated learning systems have multiple clients (otherwise, there's not much to federate), so each client will be represented by its own instance of `FlowerClient`. If we have, for example, three clients in our workload, then we'd have three instances of `FlowerClient`. Flower calls `FlowerClient.fit` on the respective instance when the server selects a particular client for training (and `FlowerClient.evaluate` for evaluation).\n",
"\n",
"### Use the Virtual Client Engine\n",
"\n",
"We will simulate a federated learning system with 10 clients on a single machine = 10 instances of `FlowerClient` in memory. Doing this on a single machine.\n",
"\n",
"Flower creates `FlowerClient` instances only when they are actually necessary for training or evaluation by callling `client_fn` that returns a `FlowerClient` instance on demand. After using them for `fit` or `evaluate` they are discarded, so they should not keep any local state.\n",
"\n",
"`client_fn` takes a single argument `cid` - a client ID. The `cid` can be used, for example, to load different local data partitions for different clients."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "qKtlrIZU1CGC"
},
"outputs": [],
"source": [
"# We can use the fact that we are using Jupyter Notebook environment and use the data without providing it as an argument.\n",
"def create_client_fn(cid: str) -> FlowerClient:\n",
" \"\"\"Create a Flower client representing a single organization.\"\"\"\n",
" net = Net().to(DEVICE)\n",
" trainloader = trainloaders[int(cid)]\n",
" valloader = validloaders[int(cid)]\n",
" return FlowerClient(net, trainloader, valloader)\n"
]
},
{
"cell_type": "markdown",
"source": [
"### Metrics Aggregation\n",
"Flower can automatically aggregate losses returned by individual clients, but it cannot do the same for metrics in the generic metrics dictionary (the one with the `accuracy` key). Metrics dictionaries can contain very different kinds of metrics and even key/value pairs that are not metrics at all, so the framework does not (and can not) know how to handle these automatically.\n",
"\n",
"The `weighted_average` function has to be passed to `evaluate_metrics_aggregation_fn` in your strategy."
],
"metadata": {
"id": "OnMl2zOTRPtO"
}
},
{
"cell_type": "code",
"source": [
"def weighted_average(metrics: List[Tuple[int, Metrics]]) -> Metrics:\n",
" # Multiply accuracy of each client by number of examples used\n",
" accuracies = [num_examples * m[\"accuracy\"] for num_examples, m in metrics]\n",
" examples = [num_examples for num_examples, _ in metrics]\n",
"\n",
" # Aggregate and return custom metric (weighted average)\n",
" return {\"accuracy\": sum(accuracies) / sum(examples)}"
],
"metadata": {
"id": "rNTUJd4nRO56"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### Create a Strategy\n",
"\n",
"Pick a strategy used for training. A good starting point is `FedAvg` but feel free to go throught the available strategies https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy"
],
"metadata": {
"id": "HABHoeyq6E1m"
}
},
{
"cell_type": "code",
"source": [
"# Instantiate/Create a Flower strategy e.g. FedAvg\n",
"#TODO: Choose the strategy and specify the arguments\n",
"strategy = fl.server.strategy.FedAvg(\n",
" fraction_fit=1.0, # Sample 100% of available clients for training\n",
" fraction_evaluate=0.5, # Sample 50% of available clients for evaluation\n",
" min_fit_clients=10, # Never sample less than 10 clients for training\n",
" min_evaluate_clients=5, # Never sample less than 5 clients for evaluation\n",
" min_available_clients=10, # Wait until all 10 clients are available\n",
" evaluate_metrics_aggregation_fn=weighted_average,\n",
")"
],
"metadata": {
"id": "EERIycCO6eLA"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "TFWQwL_41CGC"
},
"source": [
"### Run Flower Simulation\n",
"\n",
"The function `flwr.simulation.start_simulation` accepts a number of arguments, amongst them the `client_fn` used to create `FlowerClient` instances, the number of clients to simulate (`num_clients`), the number of federated learning rounds (`num_rounds`), and the strategy. The strategy encapsulates the federated learning approach/algorithm, for example, *Federated Averaging* (FedAvg).\n",
"\n",
"Flower has a number of built-in strategies, but we can also use our own strategy implementations to customize nearly all aspects of the federated learning approach. For this example, we use the built-in `FedAvg` implementation and customize it using a few basic parameters. The last step is the actual call to `start_simulation` which - you guessed it - starts the simulation:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "xBmL19b-1CGC",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "3651905a-9ec5-4bbf-928d-b4577adee3ae"
},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"INFO flwr 2023-05-31 11:14:27,876 | app.py:146 | Starting Flower simulation, config: ServerConfig(num_rounds=2, round_timeout=None)\n",
"INFO:flwr:Starting Flower simulation, config: ServerConfig(num_rounds=2, round_timeout=None)\n",
"2023-05-31 11:14:30,092\tINFO worker.py:1625 -- Started a local Ray instance.\n",
"INFO flwr 2023-05-31 11:14:31,517 | app.py:180 | Flower VCE: Ray initialized with resources: {'object_store_memory': 3897945292.0, 'memory': 7795890587.0, 'node:172.28.0.12': 1.0, 'CPU': 2.0}\n",
"INFO:flwr:Flower VCE: Ray initialized with resources: {'object_store_memory': 3897945292.0, 'memory': 7795890587.0, 'node:172.28.0.12': 1.0, 'CPU': 2.0}\n",
"INFO flwr 2023-05-31 11:14:31,529 | server.py:86 | Initializing global parameters\n",
"INFO:flwr:Initializing global parameters\n",
"INFO flwr 2023-05-31 11:14:31,530 | server.py:273 | Requesting initial parameters from one random client\n",
"INFO:flwr:Requesting initial parameters from one random client\n",
"\u001b[2m\u001b[36m(pid=2351)\u001b[0m 2023-05-31 11:14:32.953457: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n",
"INFO flwr 2023-05-31 11:14:35,998 | server.py:277 | Received initial parameters from one random client\n",
"INFO:flwr:Received initial parameters from one random client\n",
"INFO flwr 2023-05-31 11:14:36,002 | server.py:88 | Evaluating initial parameters\n",
"INFO:flwr:Evaluating initial parameters\n",
"INFO flwr 2023-05-31 11:14:36,005 | server.py:101 | FL starting\n",
"INFO:flwr:FL starting\n",
"DEBUG flwr 2023-05-31 11:14:36,008 | server.py:218 | fit_round 1: strategy sampled 10 clients (out of 10)\n",
"DEBUG:flwr:fit_round 1: strategy sampled 10 clients (out of 10)\n",
"DEBUG flwr 2023-05-31 11:17:15,276 | server.py:232 | fit_round 1 received 10 results and 0 failures\n",
"DEBUG:flwr:fit_round 1 received 10 results and 0 failures\n",
"WARNING flwr 2023-05-31 11:17:15,479 | fedavg.py:243 | No fit_metrics_aggregation_fn provided\n",
"WARNING:flwr:No fit_metrics_aggregation_fn provided\n",
"DEBUG flwr 2023-05-31 11:17:15,481 | server.py:168 | evaluate_round 1: strategy sampled 5 clients (out of 10)\n",
"DEBUG:flwr:evaluate_round 1: strategy sampled 5 clients (out of 10)\n",
"DEBUG flwr 2023-05-31 11:17:20,878 | server.py:182 | evaluate_round 1 received 5 results and 0 failures\n",
"DEBUG:flwr:evaluate_round 1 received 5 results and 0 failures\n",
"DEBUG flwr 2023-05-31 11:17:20,883 | server.py:218 | fit_round 2: strategy sampled 10 clients (out of 10)\n",
"DEBUG:flwr:fit_round 2: strategy sampled 10 clients (out of 10)\n",
"DEBUG flwr 2023-05-31 11:20:04,678 | server.py:232 | fit_round 2 received 10 results and 0 failures\n",
"DEBUG:flwr:fit_round 2 received 10 results and 0 failures\n",
"DEBUG flwr 2023-05-31 11:20:04,822 | server.py:168 | evaluate_round 2: strategy sampled 5 clients (out of 10)\n",
"DEBUG:flwr:evaluate_round 2: strategy sampled 5 clients (out of 10)\n",
"DEBUG flwr 2023-05-31 11:20:10,450 | server.py:182 | evaluate_round 2 received 5 results and 0 failures\n",
"DEBUG:flwr:evaluate_round 2 received 5 results and 0 failures\n",
"INFO flwr 2023-05-31 11:20:10,453 | server.py:147 | FL finished in 334.44558042200003\n",
"INFO:flwr:FL finished in 334.44558042200003\n",
"INFO flwr 2023-05-31 11:20:10,459 | app.py:218 | app_fit: losses_distributed [(1, 0.05944233487049739), (2, 0.016542544066905977)]\n",
"INFO:flwr:app_fit: losses_distributed [(1, 0.05944233487049739), (2, 0.016542544066905977)]\n",
"INFO flwr 2023-05-31 11:20:10,466 | app.py:219 | app_fit: metrics_distributed_fit {}\n",
"INFO:flwr:app_fit: metrics_distributed_fit {}\n",
"INFO flwr 2023-05-31 11:20:10,471 | app.py:220 | app_fit: metrics_distributed {'accuracy': [(1, 0.5691666666666667), (2, 0.794)]}\n",
"INFO:flwr:app_fit: metrics_distributed {'accuracy': [(1, 0.5691666666666667), (2, 0.794)]}\n",
"INFO flwr 2023-05-31 11:20:10,472 | app.py:221 | app_fit: losses_centralized []\n",
"INFO:flwr:app_fit: losses_centralized []\n",
"INFO flwr 2023-05-31 11:20:10,477 | app.py:222 | app_fit: metrics_centralized {}\n",
"INFO:flwr:app_fit: metrics_centralized {}\n"
]
}
],
"source": [
"client_resources = {\"num_cpus\": 2}\n",
"if DEVICE.type == \"cuda\":\n",
" client_resources[\"num_gpus\"] = 1\n",
"\n",
"\n",
"# Start simulation\n",
"history = fl.simulation.start_simulation(\n",
" client_fn=create_client_fn,\n",
" num_clients=NUM_CLIENTS,\n",
" config=fl.server.ServerConfig(num_rounds=NUM_ROUNDS),\n",
" strategy=strategy,\n",
" client_resources=client_resources,\n",
")"
]
},
{
"cell_type": "code",
"source": [
"history"
],
"metadata": {
"id": "KfMraHRcTKXu",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "7f8d6d0f-4de3-47d8-fc83-b83408dec014"
},
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"History (loss, distributed):\n",
"\tround 1: 0.05944233487049739\n",
"\tround 2: 0.016542544066905977\n",
"History (metrics, distributed, evaluate):\n",
"{'accuracy': [(1, 0.5691666666666667), (2, 0.794)]}"
]
},
"metadata": {},
"execution_count": 21
}
]
},
{
"cell_type": "markdown",
"source": [
"## Centralized Evaluation\n",
"\n",
"Modification of the strategy is needed for centralized evaluation."
],
"metadata": {
"id": "oyRS7Hey9c7u"
}
},
{
"cell_type": "code",
"source": [
"def evaluate(\n",
" server_round: int,\n",
" parameters: fl.common.NDArrays,\n",
" config: Dict[str, fl.common.Scalar],\n",
" ) -> Optional[Tuple[float, Dict[str, fl.common.Scalar]]]:\n",
" \"\"\"Centralized evaluation function\"\"\"\n",
" net = Net().to(DEVICE)\n",
" set_parameters(net, parameters)\n",
" loss, accuracy = test(net, centralized_loader)\n",
" print(f\"Server-side evaluation loss {loss} / accuracy {accuracy}\")\n",
" return loss, {\"accuracy\": accuracy}\n",
"\n",
"# TODO: Specify the Strategy\n",
"strategy = fl.server.strategy.FedAvg(\n",
" fraction_fit=1.0, # Sample 100% of available clients for training\n",
" fraction_evaluate=0.5, # Sample 50% of available clients for evaluation\n",
" min_fit_clients=10, # Never sample less than 10 clients for training\n",
" min_evaluate_clients=5, # Never sample less than 5 clients for evaluation\n",
" min_available_clients=10, # Wait until all 10 clients are available\n",
" evaluate_metrics_aggregation_fn=weighted_average,\n",
" evaluate_fn=evaluate\n",
")\n",
"\n",
"# Start simulation\n",
"history = fl.simulation.start_simulation(\n",
" client_fn=create_client_fn,\n",
" num_clients=NUM_CLIENTS,\n",
" config=fl.server.ServerConfig(num_rounds=NUM_ROUNDS),\n",
" strategy=strategy,\n",
" client_resources=client_resources,\n",
")"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "chLOL6VP9hXu",
"outputId": "b0fb0fc2-d12e-4ec7-91b3-ea4251a30e75"
},
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"INFO flwr 2023-05-31 11:20:10,546 | app.py:146 | Starting Flower simulation, config: ServerConfig(num_rounds=2, round_timeout=None)\n",
"INFO:flwr:Starting Flower simulation, config: ServerConfig(num_rounds=2, round_timeout=None)\n",
"2023-05-31 11:20:14,979\tINFO worker.py:1625 -- Started a local Ray instance.\n",
"INFO flwr 2023-05-31 11:20:16,383 | app.py:180 | Flower VCE: Ray initialized with resources: {'node:172.28.0.12': 1.0, 'memory': 7804784640.0, 'CPU': 2.0, 'object_store_memory': 3902392320.0}\n",
"INFO:flwr:Flower VCE: Ray initialized with resources: {'node:172.28.0.12': 1.0, 'memory': 7804784640.0, 'CPU': 2.0, 'object_store_memory': 3902392320.0}\n",
"INFO flwr 2023-05-31 11:20:16,391 | server.py:86 | Initializing global parameters\n",
"INFO:flwr:Initializing global parameters\n",
"INFO flwr 2023-05-31 11:20:16,393 | server.py:273 | Requesting initial parameters from one random client\n",
"INFO:flwr:Requesting initial parameters from one random client\n",
"\u001b[2m\u001b[36m(pid=4070)\u001b[0m 2023-05-31 11:20:17.849262: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n",
"INFO flwr 2023-05-31 11:20:20,947 | server.py:277 | Received initial parameters from one random client\n",
"INFO:flwr:Received initial parameters from one random client\n",
"INFO flwr 2023-05-31 11:20:20,951 | server.py:88 | Evaluating initial parameters\n",
"INFO:flwr:Evaluating initial parameters\n",
"INFO flwr 2023-05-31 11:20:29,433 | server.py:91 | initial parameters (loss, other metrics): 0.07208683090209961, {'accuracy': 0.0917}\n",
"INFO:flwr:initial parameters (loss, other metrics): 0.07208683090209961, {'accuracy': 0.0917}\n",
"INFO flwr 2023-05-31 11:20:29,436 | server.py:101 | FL starting\n",
"INFO:flwr:FL starting\n",
"DEBUG flwr 2023-05-31 11:20:29,439 | server.py:218 | fit_round 1: strategy sampled 10 clients (out of 10)\n",
"DEBUG:flwr:fit_round 1: strategy sampled 10 clients (out of 10)\n"
]
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Server-side evaluation loss 0.07208683090209961 / accuracy 0.0917\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"DEBUG flwr 2023-05-31 11:23:06,412 | server.py:232 | fit_round 1 received 10 results and 0 failures\n",
"DEBUG:flwr:fit_round 1 received 10 results and 0 failures\n",
"WARNING flwr 2023-05-31 11:23:06,569 | fedavg.py:243 | No fit_metrics_aggregation_fn provided\n",
"WARNING:flwr:No fit_metrics_aggregation_fn provided\n",
"INFO flwr 2023-05-31 11:23:14,960 | server.py:119 | fit progress: (1, 0.06729964368343354, {'accuracy': 0.6271}, 165.52080230600006)\n",
"INFO:flwr:fit progress: (1, 0.06729964368343354, {'accuracy': 0.6271}, 165.52080230600006)\n",
"DEBUG flwr 2023-05-31 11:23:14,968 | server.py:168 | evaluate_round 1: strategy sampled 5 clients (out of 10)\n",
"DEBUG:flwr:evaluate_round 1: strategy sampled 5 clients (out of 10)\n"
]
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Server-side evaluation loss 0.06729964368343354 / accuracy 0.6271\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"DEBUG flwr 2023-05-31 11:23:20,438 | server.py:182 | evaluate_round 1 received 5 results and 0 failures\n",
"DEBUG:flwr:evaluate_round 1 received 5 results and 0 failures\n",
"DEBUG flwr 2023-05-31 11:23:20,443 | server.py:218 | fit_round 2: strategy sampled 10 clients (out of 10)\n",
"DEBUG:flwr:fit_round 2: strategy sampled 10 clients (out of 10)\n",
"DEBUG flwr 2023-05-31 11:26:00,031 | server.py:232 | fit_round 2 received 10 results and 0 failures\n",
"DEBUG:flwr:fit_round 2 received 10 results and 0 failures\n",
"INFO flwr 2023-05-31 11:26:07,903 | server.py:119 | fit progress: (2, 0.009333141782600432, {'accuracy': 0.9676}, 338.4640598540001)\n",
"INFO:flwr:fit progress: (2, 0.009333141782600432, {'accuracy': 0.9676}, 338.4640598540001)\n",
"DEBUG flwr 2023-05-31 11:26:07,907 | server.py:168 | evaluate_round 2: strategy sampled 5 clients (out of 10)\n",
"DEBUG:flwr:evaluate_round 2: strategy sampled 5 clients (out of 10)\n"
]
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Server-side evaluation loss 0.009333141782600432 / accuracy 0.9676\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"DEBUG flwr 2023-05-31 11:26:13,931 | server.py:182 | evaluate_round 2 received 5 results and 0 failures\n",
"DEBUG:flwr:evaluate_round 2 received 5 results and 0 failures\n",
"INFO flwr 2023-05-31 11:26:13,934 | server.py:147 | FL finished in 344.49554322000006\n",
"INFO:flwr:FL finished in 344.49554322000006\n",
"INFO flwr 2023-05-31 11:26:13,950 | app.py:218 | app_fit: losses_distributed [(1, 0.06823034922281901), (2, 0.009110654158207278)]\n",
"INFO:flwr:app_fit: losses_distributed [(1, 0.06823034922281901), (2, 0.009110654158207278)]\n",
"INFO flwr 2023-05-31 11:26:13,955 | app.py:219 | app_fit: metrics_distributed_fit {}\n",
"INFO:flwr:app_fit: metrics_distributed_fit {}\n",
"INFO flwr 2023-05-31 11:26:13,961 | app.py:220 | app_fit: metrics_distributed {'accuracy': [(1, 0.6213333333333334), (2, 0.9670000000000001)]}\n",
"INFO:flwr:app_fit: metrics_distributed {'accuracy': [(1, 0.6213333333333334), (2, 0.9670000000000001)]}\n",
"INFO flwr 2023-05-31 11:26:13,964 | app.py:221 | app_fit: losses_centralized [(0, 0.07208683090209961), (1, 0.06729964368343354), (2, 0.009333141782600432)]\n",
"INFO:flwr:app_fit: losses_centralized [(0, 0.07208683090209961), (1, 0.06729964368343354), (2, 0.009333141782600432)]\n",
"INFO flwr 2023-05-31 11:26:13,965 | app.py:222 | app_fit: metrics_centralized {'accuracy': [(0, 0.0917), (1, 0.6271), (2, 0.9676)]}\n",
"INFO:flwr:app_fit: metrics_centralized {'accuracy': [(0, 0.0917), (1, 0.6271), (2, 0.9676)]}\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"history"
],
"metadata": {
"id": "1WMIs9lvE_-y",
"outputId": "e652064b-83b5-446c-abd9-6c1e8318ec5c",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"History (loss, distributed):\n",
"\tround 1: 0.06823034922281901\n",
"\tround 2: 0.009110654158207278\n",
"History (loss, centralized):\n",
"\tround 0: 0.07208683090209961\n",
"\tround 1: 0.06729964368343354\n",
"\tround 2: 0.009333141782600432\n",
"History (metrics, distributed, evaluate):\n",
"{'accuracy': [(1, 0.6213333333333334), (2, 0.9670000000000001)]}History (metrics, centralized):\n",
"{'accuracy': [(0, 0.0917), (1, 0.6271), (2, 0.9676)]}"
]
},
"metadata": {},
"execution_count": 23
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jyex7uv31CGG"
},
"source": [
"## Final remarks\n",
"\n",
"Congratulations, you just trained a convolutional neural network, federated over 10 clients! With that, you understand the basics of federated learning with Flower. The same approach you've seen can be used with other machine learning frameworks (not just PyTorch) and tasks (not just MNIST images classification), for example NLP with Hugging Face Transformers or speech with SpeechBrain."
]
}
],
"metadata": {
"colab": {
"provenance": [],
"include_colab_link": true
},
"kernelspec": {
"display_name": "flower-3.7.12",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment