{ "cells": [ { "cell_type": "markdown", "id": "299596ab", "metadata": { "id": "299596ab" }, "source": [ "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/fonnesbeck/Bios8366/blob/master/notebooks/Section7_2-Introduction-to-PyTorch.ipynb)\n", "\n", "# Introduction to PyTorch\n", "\n", "![](https://github.com/fonnesbeck/Bios8366/blob/master/notebooks/images/Pytorch_logo.png?raw=true)" ] }, { "cell_type": "markdown", "id": "d40eaa4e", "metadata": { "id": "d40eaa4e" }, "source": [ "PyTorch is one of the most popular deep learning Python libraries, and it is widely used by the AI research community. Many developers and researchers use PyTorch to accelerate deep learning research experimentation and prototyping.\n", "\n", "The PyTorch library is primarily developed by Facebook’s AI Research Lab (FAIR) and is free and open source software with over 1,700 contributors. It allows you to easily run array-based calculations, build dynamic neural networks, and perform autodifferentiation in Python with strong graphics processing unit (GPU) acceleration—all important features required for deep learning research. Although some use it for accelerated tensor computing, most use it for deep learning development.\n", "\n", "PyTorch’s simple and flexible interface enables fast experimentation. You can load data, apply transforms, and build models with a few lines of code. Then, you have the flexibility to write customized training, validation, and test loops and deploy trained models with ease.\n", "\n", "Many developers and researchers use PyTorch to accelerate deep learning research experimentation and prototyping. Its simple Python API, GPU support, and flexibility make it a popular choice among academic and commercial research organizations. Since being open sourced in 2018, PyTorch has reached a stable release and can be easily installed on Windows, Mac, and Linux operating systems. The framework continues to expand rapidly and now facilitates deployment to production environments in the cloud and mobile platforms." ] }, { "cell_type": "markdown", "id": "48b2244d", "metadata": { "id": "48b2244d" }, "source": [ "## PyTorch Programming Concepts\n", "\n", "PyTorch's computation takes place over a **directed graph**, which is comprised of a set of *nodes* and associated *edges*, used to describe operations and tensors.\n", "\n", "![](https://github.com/fonnesbeck/Bios8366/blob/master/notebooks/images/tf_dag.png?raw=true)\n", "\n", "### Tensors\n", "\n", "We were introduced to tensors in previous sections, when we discussed PyMC and Aesara. Similarly in PyTorch, a tensor is the fundamental data structure for storing and manipulating data. Like an Aesara tensor (or a NumPy array, for that matter), a tensor is a multidimensional array containing elements of a single data type. Tensors can be used to represent scalars, vectors, matrices, and n-dimensional arrays and are derived from the torch.Tensor class. However, tensors are more than just arrays of numbers. Creating or instantiating a tensor object from the `torch.Tensor` class gives us access to a set of built-in class attributes and operations or class methods that provide a robust set of built-in capabilities. \n", "\n", "Tensors also include added benefits that make them more suitable than NumPy arrays for deep learning calculations. Importantly, tensor operations can be performed significantly faster using **GPU acceleration**. Also, tensors can be stored and manipulated at scale using **distributed** processing on multiple CPUs and GPUs and across multiple servers. And third, tensors keep track of their graph computations, which is very important in implementing a deep learning library.\n", "\n", "### Simple CPU Example\n", "\n", "Here’s a simple example that creates a tensor, performs a tensor operation, and uses a built-in method on the tensor itself. By default, the tensor data type will be derived from the input data type and the tensor will be allocated to the CPU device. \n", "\n", "First, we import the PyTorch library, then we create two tensors, `x` and `y`, from two-dimensional lists. \n", "\n", "Next, we add the two tensors and store the result in `z`. We can just use the `+` operator here because the `torch.Tensor` class supports operator overloading. \n", "\n", "Finally, we print the new tensor, `z`, which we can see is the matrix sum of `x` and `y`, and we print the size of `z`. Notice that `z` is a tensor object itself and the `size()` method is used to return its matrix dimensions, namely 2 × 3:" ] }, { "cell_type": "code", "execution_count": null, "id": "a7ef87dd", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "a7ef87dd", "outputId": "a3277b42-ed6f-4411-dd44-9c40e8873ab3" }, "outputs": [], "source": [ "import torch\n", "\n", "x = torch.tensor([[1,2,3],[4,5,6]])\n", "y = torch.tensor([[7,8,9],[10,11,12]])\n", "z = x + y\n", "print(z)" ] }, { "cell_type": "code", "execution_count": null, "id": "0f2d3e05", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "0f2d3e05", "outputId": "aa76d01e-38f3-4c1b-a523-a1ff1d23d2bd" }, "outputs": [], "source": [ "z.size()" ] }, { "cell_type": "markdown", "id": "73e9cbf1", "metadata": { "id": "73e9cbf1" }, "source": [ "### Simple GPU Example\n", "\n", "The ability to accelerate tensor operations on a GPU is a major advantage of tensors over NumPy arrays. This is the same example from above, but here we move the tensors to the GPU device if one is available. Notice that the output tensor is also allocated to the GPU. You can use the device attribute (e.g., `z.device`) to confirm where the tensor resides.\n", "\n", "The `torch.cuda.is_available()` function will return `True` if your machine has GPU support. If your machine contains multiple GPUs, you can also control which GPU is being used." ] }, { "cell_type": "code", "execution_count": null, "id": "5400a935", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "5400a935", "outputId": "48dcf3d9-726a-4246-bddc-44b0f8622e30" }, "outputs": [], "source": [ "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", "\n", "x = torch.tensor([[1,2,3],[4,5,6]],\n", " device=device)\n", "y = torch.tensor([[7,8,9],[10,11,12]],\n", " device=device)\n", "z = x + y\n", "print(z)\n", "\n", "print(z.device)" ] }, { "cell_type": "markdown", "id": "3341393e", "metadata": { "id": "3341393e" }, "source": [ "### GPU support\n", "\n", "A crucial feature of PyTorch is the support of GPUs, short for Graphics Processing Unit. A GPU can perform many thousands of small operations in parallel, making it very well suitable for performing large matrix operations in neural networks. When comparing GPUs to CPUs, we can list the following main differences (credit: [Kevin Krewell, 2009](https://blogs.nvidia.com/blog/2009/12/16/whats-the-difference-between-a-cpu-and-a-gpu/)) \n", "\n", "![](https://github.com/fonnesbeck/Bios8366/blob/master/notebooks/images/comparison_CPU_GPU.png?raw=true)\n", "\n", "CPUs and GPUs have both different advantages and disadvantages, which is why many computers contain both components and use them for different tasks. In case you are not familiar with GPUs, you can read up more details in this [NVIDIA blog post](https://blogs.nvidia.com/blog/2009/12/16/whats-the-difference-between-a-cpu-and-a-gpu/) or [here](https://www.intel.com/content/www/us/en/products/docs/processors/what-is-a-gpu.html). \n", "\n", "GPUs can accelerate the training of your network up to a factor of $100$ which is essential for large neural networks. PyTorch implements a lot of functionality for supporting GPUs (mostly those of NVIDIA due to the libraries [CUDA](https://developer.nvidia.com/cuda-zone) and [cuDNN](https://developer.nvidia.com/cudnn)). First, let's check whether you have a GPU available:" ] }, { "cell_type": "code", "execution_count": null, "id": "7f6e2b82", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "7f6e2b82", "outputId": "e12e34a7-c52c-4fff-d6f6-a08e529862db" }, "outputs": [], "source": [ "gpu_avail = torch.cuda.is_available()\n", "print(f\"Is the GPU available? {gpu_avail}\")" ] }, { "cell_type": "markdown", "id": "f7bfde90", "metadata": { "id": "f7bfde90" }, "source": [ "If you have a GPU on your computer but the command above returns False, make sure you have the correct CUDA-version installed. On Google Colab, make sure that you have selected a GPU in your runtime setup (in the menu, check under `Runtime -> Change runtime type`). \n", "\n", "By default, all tensors you create are stored on the CPU. We can push a tensor to the GPU by using the function `.to(...)`, or `.cuda()`. However, it is often a good practice to define a `device` object in your code which points to the GPU if you have one, and otherwise to the CPU. Then, you can write your code with respect to this device object, and it allows you to run the same code on both a CPU-only system, and one with a GPU. Let's try it below. We can specify the device as follows: " ] }, { "cell_type": "code", "execution_count": null, "id": "7d3eab8a", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "7d3eab8a", "outputId": "02bc8ba4-b61f-45f2-8b9e-3598132fc262" }, "outputs": [], "source": [ "device = torch.device(\"cuda\") if torch.cuda.is_available() else torch.device(\"cpu\")\n", "print(\"Device\", device)" ] }, { "cell_type": "markdown", "id": "cfcec77b", "metadata": { "id": "cfcec77b" }, "source": [ "Now let's create a tensor and push it to the device:" ] }, { "cell_type": "code", "execution_count": null, "id": "f821672e", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "f821672e", "outputId": "7f41a420-e340-4a4e-a662-5671f111e5cc" }, "outputs": [], "source": [ "x = torch.zeros(2, 3)\n", "x = x.to(device)\n", "print(\"X\", x)" ] }, { "cell_type": "markdown", "id": "7d8ae1cc", "metadata": { "id": "7d8ae1cc" }, "source": [ "In case you have a GPU, you should now see the attribute `device='cuda:0'` being printed next to your tensor. The zero next to cuda indicates that this is the zero-th GPU device on your computer. PyTorch also supports multi-GPU systems, but this you will only need once you have very big networks to train (if interested, see the [PyTorch documentation](https://pytorch.org/docs/stable/distributed.html#distributed-basics)). We can also compare the runtime of a large matrix multiplication on the CPU with a operation on the GPU:" ] }, { "cell_type": "code", "execution_count": null, "id": "e802613b", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "e802613b", "outputId": "5e03f60c-6535-4bc6-a61a-b0898ad7ffca" }, "outputs": [], "source": [ "import time\n", "x = torch.randn(5000, 5000)\n", "\n", "## CPU version\n", "start_time = time.time()\n", "_ = torch.matmul(x, x)\n", "end_time = time.time()\n", "print(f\"CPU time: {(end_time - start_time):6.5f}s\")\n", "\n", "## GPU version\n", "x = x.to(device)\n", "# CUDA is asynchronous, so we need to use different timing functions\n", "start = torch.cuda.Event(enable_timing=True)\n", "end = torch.cuda.Event(enable_timing=True)\n", "start.record()\n", "_ = torch.matmul(x, x)\n", "end.record()\n", "torch.cuda.synchronize() # Waits for everything to finish running on the GPU\n", "print(f\"GPU time: {0.001 * start.elapsed_time(end):6.5f}s\") # Milliseconds to seconds" ] }, { "cell_type": "markdown", "id": "f9901033", "metadata": { "id": "f9901033" }, "source": [ "Depending on the size of the operation and the CPU/GPU in your system, the speedup of this operation can be >50x. As `matmul` operations are very common in neural networks, we can already see the great benefit of training a NN on a GPU. The time estimate can be relatively noisy here because we haven't run it for multiple times. Feel free to extend this, but it also takes longer to run.\n", "\n", "When generating random numbers, the seed between CPU and GPU is not synchronized. Hence, we need to set the seed on the GPU separately to ensure a reproducible code. Note that due to different GPU architectures, running the same code on different GPUs does not guarantee the same random numbers. Still, we don't want that our code gives us a different output every time we run it on the exact same hardware. Hence, we also set the seed on the GPU:" ] }, { "cell_type": "code", "execution_count": null, "id": "zhXTAiv2InvS", "metadata": { "id": "zhXTAiv2InvS" }, "outputs": [], "source": [ "# GPU operations have a separate seed we also want to set\n", "if torch.cuda.is_available(): \n", " torch.cuda.manual_seed(42)\n", " torch.cuda.manual_seed_all(42)" ] }, { "cell_type": "markdown", "id": "b5110173", "metadata": { "deletable": true, "editable": true, "id": "b5110173" }, "source": [ "## Creating Tensors\n", "\n", "You can create tensors from preexisting numeric data or create random samplings. Tensors can be created from preexisting data stored in built-in structures such as lists, tuples, scalars, or serialized data files, as well as in NumPy arrays." ] }, { "cell_type": "markdown", "id": "909e4114", "metadata": { "id": "909e4114" }, "source": [ "The function `torch.Tensor` allocates memory for the desired tensor, but reuses any values that have already been in the memory. To directly assign values to the tensor during initialization, there are many alternatives including:\n", "\n", "* `torch.zeros`: Creates a tensor filled with zeros\n", "* `torch.ones`: Creates a tensor filled with ones\n", "* `torch.rand`: Creates a tensor with random values uniformly sampled between 0 and 1\n", "* `torch.randn`: Creates a tensor with random values sampled from a normal distribution with mean 0 and variance 1\n", "* `torch.arange`: Creates a tensor containing the values $N,N+1,N+2,...,M$\n", "* `torch.Tensor` (input list): Creates a tensor from the list elements you provide" ] }, { "cell_type": "code", "execution_count": null, "id": "3861149d", "metadata": { "collapsed": true, "deletable": true, "editable": true, "id": "3861149d" }, "outputs": [], "source": [ "import numpy\n", "\n", "# Created from preexisting arrays\n", "w = torch.tensor([1,2,3])\n", "w = torch.tensor((1,2,3))\n", "w = torch.tensor(numpy.array([1,2,3]))\n", "\n", "# Initialized by size\n", "w = torch.empty(100,200)\n", "w = torch.zeros(100,200)\n", "w = torch.ones(100,200)" ] }, { "cell_type": "markdown", "id": "d5c06f82", "metadata": { "deletable": true, "editable": true, "id": "d5c06f82" }, "source": [ "If you want to initialize a tensor with random values, PyTorch supports a robust set of functions that you can use, such as torch.`rand()`, `torch.randn()`, and `torch.randint()`." ] }, { "cell_type": "code", "execution_count": null, "id": "fbd28729", "metadata": { "deletable": true, "editable": true, "id": "fbd28729" }, "outputs": [], "source": [ "# Initialized by size with random values\n", "w = torch.rand(100,200) \n", "w = torch.randn(100,200) \n", "w = torch.randint(5,10,(100,200)) \n", "\n", "# Initialized with specified data type or device\n", "w = torch.empty((100,200), dtype=torch.float64,\n", " device=device)\n", "\n", "# Initialized to have the same size, data type,\n", "# and device as another tensor\n", "x = torch.empty_like(w)" ] }, { "cell_type": "markdown", "id": "3d0871e3", "metadata": { "deletable": true, "editable": true, "id": "3d0871e3" }, "source": [ "In addition, functions with the _like postfix such as `torch.empty_like()` and `torch.ones_like()` return tensors that have the same size, data type, and device as another tensor but are initialized differently." ] }, { "cell_type": "markdown", "id": "cec02914", "metadata": { "id": "cec02914" }, "source": [ "## Tensor Attributes\n", "\n", "One PyTorch quality that has contributed to its popularity is the fact that it’s very Pythonic and object oriented in nature. Since a tensor is its own data type, you can read attributes of the tensor object itself. Assuming `x` is a tensor, you can access several attributes of `x` as follows:\n", "\n", "`x.dtype`\n", "\n", "- Indicates the tensor’s data type (see Table 2-2 for a list of PyTorch data types)\n", "\n", "`x.device`\n", "\n", "- Indicates the tensor’s device location (e.g., CPU or GPU memory)\n", "\n", "`x.shape`\n", "\n", "- Shows the tensor’s dimensions\n", "\n", "`x.ndim`\n", "\n", "- Identifies the number of a tensor’s dimensions or rank\n", "\n", "`x.requires_grad`\n", "\n", "- A Boolean attribute that indicates whether the tensor keeps track of graph computations (see “Automatic Differentiation (Autograd)”)\n", "\n", "`x.grad`\n", "\n", "- Contains the actual gradients if requires_grad is True\n", "\n", "`x.grad_fn`\n", "\n", "- Stores the graph computation function used if requires_grad is True\n", "\n", "`x.s_cuda`, `x.is_sparse`, `x.is_quantized`, `x.is_leaf`, `x.is_mkldnn`\n", "\n", "- Boolean attributes that indicate whether the tensor meets certain conditions\n", "\n", "`x.layout`\n", "\n", "- Indicates how a tensor is laid out in memory\n", "\n", "## Data Types\n", "\n", "During deep learning development, it’s important to be aware of the data type used by your data and its calculations. So when you create tensors, you should control what data types are being used. You can specify the data type when creating the tensor by using the `dtype` parameter, or you can cast a tensor to a new dtype using the appropriate casting method or the `to()` method:" ] }, { "cell_type": "code", "execution_count": null, "id": "0b891887", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "collapsed": true, "deletable": true, "editable": true, "id": "0b891887", "outputId": "a3d2fb12-6081-4e51-e374-e74e0e5429eb" }, "outputs": [], "source": [ "# Specify the data type at creation using dtype\n", "w = torch.tensor([1,2,3], dtype=torch.float32)\n", "\n", "# Use the casting method to cast to a new data type\n", "w.int() # w remains a float32 after the cast\n", "w = w.int() # w changes to an int32 after the cast\n", "\n", "# Use the to() method to cast to a new type\n", "w = w.to(torch.float64) \n", "w = w.to(dtype=torch.float64) \n", "\n", "# Python automatically converts data types during\n", "# operations\n", "x = torch.tensor([1,2,3], dtype=torch.int32)\n", "y = torch.tensor([1,2,3], dtype=torch.float32)\n", "z = x + y \n", "print(z.dtype)\n" ] }, { "cell_type": "markdown", "id": "34adf80e", "metadata": { "deletable": true, "editable": true, "id": "34adf80e" }, "source": [ "## Tensor Operations\n", "\n", "PyTorch supports a robust set of tensor operations that allow you to access and transform your tensor data.\n", "\n", "### Indexing, Slicing, Combining, and Splitting Tensors\n", "\n", "Once you have created tensors, you may want to access portions of the data and combine or split tensors to form new tensors. You can slice and index tensors in the same way you would slice and index NumPy arrays. Note that indexing and slicing will return tensors even if the array is only a single element. You will need to use the `item()` function to convert a single-element tensor to a Python value when passing to other functions like `print()`:" ] }, { "cell_type": "code", "execution_count": null, "id": "0256adf4", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "deletable": true, "editable": true, "id": "0256adf4", "outputId": "caed38e6-6c32-427e-d2ab-7ec7765d0661" }, "outputs": [], "source": [ "x = torch.tensor([[1,2],[3,4],[5,6],[7,8]])\n", "x" ] }, { "cell_type": "code", "execution_count": null, "id": "6fae3164", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "6fae3164", "outputId": "ca2cac9d-1a9a-4303-b140-9e01468b58af" }, "outputs": [], "source": [ "x[1,1]" ] }, { "cell_type": "code", "execution_count": null, "id": "ec137a3c", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ec137a3c", "outputId": "e79a325c-c33d-4fa8-9971-0ce39891cddd" }, "outputs": [], "source": [ "x[1,1].item()" ] }, { "cell_type": "code", "execution_count": null, "id": "59d887c9", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "59d887c9", "outputId": "149db0c3-b5ac-46ca-f783-9c641a1c8674" }, "outputs": [], "source": [ "# Slicing\n", "x[:2,1]" ] }, { "cell_type": "code", "execution_count": null, "id": "0d1effea", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "0d1effea", "outputId": "ea67c243-607b-4139-9a3b-b92264789cff" }, "outputs": [], "source": [ "# Boolean indexing\n", "x[x<5]" ] }, { "cell_type": "markdown", "id": "92011c5b", "metadata": { "deletable": true, "editable": true, "id": "92011c5b" }, "source": [ "PyTorch also supports transposing and reshaping arrays" ] }, { "cell_type": "code", "execution_count": null, "id": "576f54aa", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "collapsed": true, "deletable": true, "editable": true, "id": "576f54aa", "outputId": "c7c708c1-8948-4ad9-9f94-ea1d137265d1" }, "outputs": [], "source": [ "# Transpose array; x.t() or x.T can be used\n", "x.t()" ] }, { "cell_type": "code", "execution_count": null, "id": "cc098225", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "cc098225", "outputId": "9d9537ae-0c68-4ccd-c0df-d00acf294a61" }, "outputs": [], "source": [ "# Change shape; usually view() is preferred over\n", "# reshape()\n", "x.view((2,4))" ] }, { "cell_type": "markdown", "id": "c5a12a4e", "metadata": { "deletable": true, "editable": true, "id": "c5a12a4e" }, "source": [ "You can also combine or split tensors by using functions like `torch.stack()` and `torch.unbind()`, respectively." ] }, { "cell_type": "code", "execution_count": null, "id": "d1b38d4a", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "deletable": true, "editable": true, "id": "d1b38d4a", "outputId": "90b2c007-a332-4fe9-8317-c26ddb9dcf88" }, "outputs": [], "source": [ "# Combining tensors\n", "y = torch.stack((x, x))\n", "y" ] }, { "cell_type": "markdown", "id": "49b416b1", "metadata": { "deletable": true, "editable": true, "id": "49b416b1" }, "source": [ "PyTorch provides a robust set of built-in functions that can be used to access, split, and combine tensors in different ways.\n", "\n", "`torch.cat()`\n", "- Concatenates the given sequence of tensors in the given dimension.\n", "\n", "`torch.chunk()`\n", "- Splits a tensor into a specific number of chunks. Each chunk is a view of the input tensor.\n", "\n", "`torch.gather()`\n", "- Gathers values along an axis specified by the dimension.\n", "\n", "`torch.index_select()`\n", "- Returns a new tensor that indexes the input tensor along a dimension using the entries in the index, which is a LongTensor.\n", "\n", "`torch.masked_select()`\n", "- Returns a new 1D tensor that indexes the input tensor according to the Boolean mask, which is a BoolTensor.\n", "\n", "\n", "`torch.narrow()`\n", "- Returns a tensor that is a narrow version of the input tensor.\n", "\n", "`torch.nonzero()`\n", "- Returns the indices of nonzero elements.\n", "\n", "`torch.reshape()`\n", "- Returns a tensor with the same data and number of elements as the input tensor, but a different shape. Use view() instead to ensure the tensor is not copied.\n", "\n", "`torch.split()`\n", "- Splits the tensor into chunks. Each chunk is a view or subdivision of the original tensor.\n", "\n", "`torch.squeeze()`\n", "- Returns a tensor with all the dimensions of the input tensor of size 1 removed.\n", "\n", "`torch.stack()`\n", "- Concatenates a sequence of tensors along a new dimension.\n", "\n", "`torch.t()`\n", "- Expects the input to be a 2D tensor and transposes dimensions 0 and 1.\n", "\n", "`torch.take()`\n", "- Returns a tensor at specified indices when slicing is not continuous.\n", "\n", "`torch.transpose()`\n", "- Transposes only the specified dimensions.\n", "\n", "`torch.unbind()`\n", "- Removes a tensor dimension by returning a tuple of the removed dimension.\n", "\n", "`torch.unsqueeze()`\n", "- Returns a new tensor with a dimension of size 1 inserted at the specified position.\n", "\n", "`torch.where()`\n", "- Returns a tensor of selected elements from either one of two tensors, depending on the specified condition." ] }, { "cell_type": "markdown", "id": "a6dbd9c6", "metadata": { "id": "a6dbd9c6" }, "source": [ "Tensors can also be converted back into NumPy arrays using the `numpy()` method." ] }, { "cell_type": "code", "execution_count": null, "id": "74c8d44f", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "collapsed": true, "deletable": true, "editable": true, "id": "74c8d44f", "outputId": "45a84d39-99ad-4a82-9ef2-47f21a04aaa2" }, "outputs": [], "source": [ "tensor = torch.arange(4)\n", "np_arr = tensor.numpy()\n", "\n", "print(\"PyTorch tensor:\", tensor)\n", "print(\"Numpy array:\", np_arr)" ] }, { "cell_type": "markdown", "id": "23b70548", "metadata": { "id": "23b70548" }, "source": [ "The conversion of tensors to numpy require the tensor to be on the CPU, and not the GPU. In case you have a tensor on GPU, you need to call `.cpu()` on the tensor beforehand. Hence, you get a line like `np_arr = tensor.cpu().numpy()`." ] }, { "cell_type": "markdown", "id": "86b9d17b", "metadata": { "id": "86b9d17b" }, "source": [ "### Tensor Operations for Mathematics\n", "\n", "Deep learning development is strongly based on mathematical computations, so PyTorch supports a very robust set of built-in math functions. Whether you are creating new data transforms, customizing loss functions, or building your own optimization algorithms, you can speed up your research and development with the math functions provided by PyTorch.\n", "\n", "PyTorch supports many different types of math functions, including pointwise operations, reduction functions, comparison calculations, and linear algebra operations, as well as spectral and other math computations. \n", "\n", "For example, a commonly used operation is matrix multiplication, which are essential for neural networks. If we have an input vector `x`, which is transformed using a learned weight matrix `w`, this can be computed in several ways:\n", "\n", "- `torch.matmul`: Performs the matrix product over two tensors, where the specific behavior depends on the dimensions. If both inputs are matrices (2-dimensional tensors), it performs the standard matrix product. For higher dimensional inputs, the function supports broadcasting (for details see the documentation). Can also be written as `a @ b`, similar to numpy.\n", "\n", "- `torch.mm`: Performs the matrix product over two matrices, but doesn’t support broadcasting\n", "\n", "- `torch.bmm`: Performs the matrix product with a support batch dimension. If the first tensor `T` is of shape `(b, n, m)`, and the second tensor `R` is `(b, m, p)`, the output `O` is of shape `(b, n, p)`, and has been calculated by performing `b` matrix multiplications of the submatrices of `T` and `R`: `O[i] = T[i] @ R[i]`. \n", "\n", "- `torch.einsum`: Performs matrix multiplications and more (i.e. sums of products) using the Einstein summation convention." ] }, { "cell_type": "code", "execution_count": null, "id": "e4caa0c5", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "e4caa0c5", "outputId": "6194798d-8431-4a4a-8f4a-ff5448463cb8" }, "outputs": [], "source": [ "x = torch.arange(6)\n", "x = x.view(2, 3)\n", "print(\"X\", x)" ] }, { "cell_type": "code", "execution_count": null, "id": "00a0142e", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "00a0142e", "outputId": "2d01817c-f90d-4127-f0ad-f9ef3f4e8bb8" }, "outputs": [], "source": [ "W = torch.arange(9).view(3, 3) # We can also stack multiple operations in a single line\n", "print(\"W\", W)" ] }, { "cell_type": "code", "execution_count": null, "id": "4d25c340", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "4d25c340", "outputId": "1668a450-f2ff-4869-b330-cd2a2eec6bb9" }, "outputs": [], "source": [ "h = torch.matmul(x, W) # Verify the result by calculating it by hand too!\n", "print(\"h\", h)" ] }, { "cell_type": "markdown", "id": "ab630042", "metadata": { "id": "ab630042" }, "source": [ "### Dynamic Computation Graph and Backpropagation\n", "\n", "One of the main reasons for using PyTorch in Deep Learning projects is that we can automatically get **gradients/derivatives** of functions that we define. We will mainly use PyTorch for implementing neural networks, and they are just fancy functions. If we use weight matrices in our function that we want to learn, then those are called the **parameters** or simply the **weights**.\n", "\n", "If our neural network would output a single scalar value, we would talk about taking the **derivative**, but you will see that quite often we will have **multiple** output variables (\"values\"); in that case we talk about **gradients**. It's a more general term.\n", "\n", "Given an input $\\mathbf{x}$, we define our function by **manipulating** that input, usually by matrix-multiplications with weight matrices and additions with so-called bias vectors. As we manipulate our input, we are automatically creating a **computational graph**. This graph shows how to arrive at our output from our input. \n", "\n", "PyTorch is a **define-by-run** framework; this means that we can just do our manipulations, and PyTorch will keep track of that graph for us. Thus, we create a dynamic computation graph along the way.\n", "\n", "So, the only thing we have to do is to compute the **output**, and then we can ask PyTorch to automatically get the **gradients**. \n", "\n", "The first thing we have to do is to specify which tensors require gradients. By default, when we create a tensor, it does not require gradients." ] }, { "cell_type": "code", "execution_count": null, "id": "de424ba1", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "de424ba1", "outputId": "e13ce81c-9959-4dca-e878-49b311f59a89" }, "outputs": [], "source": [ "x = torch.ones((3,))\n", "print(x.requires_grad)" ] }, { "cell_type": "markdown", "id": "094b3e3c", "metadata": { "id": "094b3e3c" }, "source": [ "We can change this for an existing tensor using the function `requires_grad_()` (underscore indicating that this is a in-place operation). Alternatively, when creating a tensor, you can pass the argument `requires_grad=True` to most initializers we have seen above." ] }, { "cell_type": "code", "execution_count": null, "id": "52eb0a5e", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "52eb0a5e", "outputId": "af7efa87-344e-4c55-fefd-299fca77714e" }, "outputs": [], "source": [ "x.requires_grad_(True)\n", "print(x.requires_grad)" ] }, { "cell_type": "markdown", "id": "b381a4d6", "metadata": { "id": "b381a4d6" }, "source": [ "In order to get familiar with the concept of a computation graph, we will create one for the following function:\n", "\n", "$$y = \\frac{1}{|x|}\\sum_i \\left[(x_i + 2)^2 + 3\\right]$$\n", "\n", "You could imagine that $x$ are our parameters, and we want to optimize (either maximize or minimize) the output $y$. For this, we want to obtain the gradients $\\partial y / \\partial \\mathbf{x}$. For our example, we'll use $\\mathbf{x}=[0,1,2]$ as our input." ] }, { "cell_type": "code", "execution_count": null, "id": "4af38547", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "4af38547", "outputId": "7dacb327-f15d-4d57-b515-008fcbb84f62" }, "outputs": [], "source": [ "x = torch.arange(3, dtype=torch.float32, requires_grad=True) # Only float tensors can have gradients\n", "print(\"X\", x)" ] }, { "cell_type": "markdown", "id": "a82a7a3a", "metadata": { "id": "a82a7a3a" }, "source": [ "Now let's build the computation graph step by step. You can combine multiple operations in a single line, but we will separate them here to get a better understanding of how each operation is added to the computation graph." ] }, { "cell_type": "code", "execution_count": null, "id": "3b904ff2", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "3b904ff2", "outputId": "d566e293-1f57-4e5d-a87d-f8b45e1aff2d" }, "outputs": [], "source": [ "a = x + 2\n", "b = a ** 2\n", "c = b + 3\n", "y = c.mean()\n", "print(\"Y\", y)" ] }, { "cell_type": "markdown", "id": "8aa7f8d5", "metadata": { "id": "8aa7f8d5" }, "source": [ "Using the statements above, we have created the following computatino graph:\n", "\n", "![image.png](data:image/png;base64,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)\n", "\n", "We calculate $a$ based on the inputs $x$ and the constant $2$, $b$ is $a$ squared, and so on. The visualization is an abstraction of the dependencies between inputs and outputs of the operations we have applied.\n", "\n", "Each node of the computation graph has automatically defined a function for calculating the gradients with respect to its inputs, `grad_fn`. You can see this when we printed the output tensor $y$. This is why the computation graph is usually visualized in the reverse direction (arrows point from the result to the inputs). We can perform backpropagation on the computation graph by calling the function `backward()` on the last output, which effectively calculates the gradients for each tensor that has the property `requires_grad=True`:" ] }, { "cell_type": "code", "execution_count": null, "id": "b8b63b84", "metadata": { "id": "b8b63b84" }, "outputs": [], "source": [ "y.backward()" ] }, { "cell_type": "markdown", "id": "b5be707c", "metadata": { "id": "b5be707c" }, "source": [ "`x.grad` will now contain the gradient $\\partial y/ \\partial \\mathcal{x}$, and this gradient indicates how a change in $\\mathbf{x}$ will affect output $y$ given the current input $\\mathbf{x}=[0,1,2]$:" ] }, { "cell_type": "code", "execution_count": null, "id": "fabb19be", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "fabb19be", "outputId": "42c7e5c5-e0ed-441c-90d8-3e1be9fe1ce9" }, "outputs": [], "source": [ "print(x.grad)" ] }, { "cell_type": "markdown", "id": "f818f2d4", "metadata": { "id": "f818f2d4" }, "source": [ "We can also verify these gradients by hand. We will calculate the gradients using the chain rule, in the same way as PyTorch did it:\n", "\n", "$$\\frac{\\partial y}{\\partial x_i} = \\frac{\\partial y}{\\partial c_i}\\frac{\\partial c_i}{\\partial b_i}\\frac{\\partial b_i}{\\partial a_i}\\frac{\\partial a_i}{\\partial x_i}$$\n", "\n", "Note that we have simplified this equation to index notation, and by using the fact that all operation besides the mean do not combine the elements in the tensor. The partial derivatives are:\n", "\n", "$$\n", "\\frac{\\partial a_i}{\\partial x_i} = 1,\\hspace{1cm}\n", "\\frac{\\partial b_i}{\\partial a_i} = 2\\cdot a_i\\hspace{1cm}\n", "\\frac{\\partial c_i}{\\partial b_i} = 1\\hspace{1cm}\n", "\\frac{\\partial y}{\\partial c_i} = \\frac{1}{3}\n", "$$\n", "\n", "Hence, with the input being $\\mathbf{x}=[0,1,2]$, our gradients are $\\partial y/\\partial \\mathbf{x}=[4/3,2,8/3]$. The previous code cell should have printed the same result." ] }, { "cell_type": "markdown", "id": "150620b6", "metadata": { "id": "150620b6" }, "source": [ "## Data Loading\n", "\n", "PyTorch provides powerful built-in classes and utilities, such as the `Dataset`, `DataLoader`, and `Sampler` classes, for loading various types of data. The `Dataset` class defines how to access and preprocess data from a file or data sources. The `Sampler` class defines how to sample data from a dataset in order to create batches, while the `DataLoader` class combines a dataset with a sampler and allows you to iterate over a set of batches.\n", "\n", "PyTorch libraries such as Torchvision and Torchtext also provide classes to support specialized data like computer vision and natural language data. The torchvision.datasets module is a good example of how to utilize built-in classes to load data. The torchvision.datasets module provides a number of subclasses to load image data from popular academic datasets.\n", "\n", "One of these popular datasets is CIFAR-10. The CIFAR-10 dataset consists of 50,000 training images and 10,000 test images of 10 possible objects: airplanes, cars, birds, cats, deer, dogs, frogs, horses, ships, and trucks.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "62b5b16a", "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 84, "referenced_widgets": [ "3e0bd075e0174bc1bdcb137bafa82b80", "9c92e8e0174c44388aaf7e50297e0d3b", "378e399b9dde438e91ea576916fc7f5b", "3070edc6c79b40309c198b5c4845c569", "eccc0d3be2f84bd5954077b0c5ed0fee", "e0537b86f5b64a098a72b5452093d378", "0c08e5867eef48cfae0adf6a02915631", "7fa15f28033e4c0cbdca4d87019dde74", "9ecef5efa63041599041d76ee295a8c8", "208cd522e37a4d4e8a23bb7af68cbbc5", "fc8f946314f641c5af76cf7d62c7b4db" ] }, "deletable": true, "editable": true, "id": "62b5b16a", "outputId": "d39f21a2-21c1-4561-f00b-9cda6f722d17" }, "outputs": [], "source": [ "from torchvision.datasets import CIFAR10\n", "\n", "train_data = CIFAR10(root=\"./train/\",\n", " train=True,\n", " download=True)" ] }, { "cell_type": "markdown", "id": "0cfbb6c6", "metadata": { "id": "0cfbb6c6" }, "source": [ "The `train` parameter determines whether we load the training data or the testing data, and setting `download` to `True` will download the data for us if we don’t have it already." ] }, { "cell_type": "code", "execution_count": null, "id": "2e83360c", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "2e83360c", "outputId": "480d33f1-fbd4-4d4a-e94b-739a09aec922" }, "outputs": [], "source": [ "train_data" ] }, { "cell_type": "code", "execution_count": null, "id": "bb65de6f", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "bb65de6f", "outputId": "85bfca58-3950-4f64-818d-48fca7268b82" }, "outputs": [], "source": [ "len(train_data)" ] }, { "cell_type": "code", "execution_count": null, "id": "3e48da2f", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "3e48da2f", "outputId": "138eb1e6-fb69-48b0-e0a9-0a7d4101bc87" }, "outputs": [], "source": [ "train_data.data.shape" ] }, { "cell_type": "code", "execution_count": null, "id": "6e057ec7", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "6e057ec7", "outputId": "f8e5201a-3abf-4f5a-a2f2-f368c153ba84" }, "outputs": [], "source": [ "train_data.targets[:10]" ] }, { "cell_type": "code", "execution_count": null, "id": "1a2e3f61", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "1a2e3f61", "outputId": "2210d9cf-365b-4b36-e6f1-ebc4175ffb41" }, "outputs": [], "source": [ "train_data.classes" ] }, { "cell_type": "code", "execution_count": null, "id": "fc91dc6e", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "fc91dc6e", "outputId": "f464ed20-ad53-4f86-ae82-977e8b64fe22" }, "outputs": [], "source": [ "train_data.class_to_idx" ] }, { "cell_type": "code", "execution_count": null, "id": "aba65f5d", "metadata": { "id": "aba65f5d" }, "outputs": [], "source": [ "data, label = train_data[0]" ] }, { "cell_type": "code", "execution_count": null, "id": "08a358a5", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "08a358a5", "outputId": "d8fced7f-1d16-4258-d091-2d232df7f57f" }, "outputs": [], "source": [ "type(data)" ] }, { "cell_type": "code", "execution_count": null, "id": "e519b432", "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 49 }, "id": "e519b432", "outputId": "b767b36c-fbab-42b3-8ac4-8cc932678ace" }, "outputs": [], "source": [ "data" ] }, { "cell_type": "markdown", "id": "a2163963", "metadata": { "deletable": true, "editable": true, "id": "a2163963" }, "source": [ "The data consists of a PIL image object. PIL is a common image format that uses the Pillow library to store image pixel values in the format of height × width × channels. A color image has three channels (RGB) for red, green, and blue.\n", "\n", "We can also load the test data into another dataset object called test_data." ] }, { "cell_type": "code", "execution_count": null, "id": "219c6f38", "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 84, "referenced_widgets": [ "97433cc60d6841859129fcb83c67ec4b", "c41ea09afdd8433c9d4593ccf9a4d4e9", "a797b8179d314847915848d12720352e", "b6cbb990998e4ce890309fb7065803ff", "909d0ff2a5454898827ccb8b0c83f318", "f7325c3b35ad4414bd1c7ab3ffb7858f", "7fce1614a72d47e7b0fd3d59c692e2cb", "9af871bc187c47b89603944054aac415", "b528593e4a024f428b1a0a8fb49e2386", "7d4297ecd6bd41f58fa31e61c6cfa341", "068c5d4019c740019f30c75afaf877c6" ] }, "deletable": true, "editable": true, "id": "219c6f38", "outputId": "18ee6cdd-026d-42c4-f489-e832865a6cdb" }, "outputs": [], "source": [ "test_data = CIFAR10(root=\"./test/\",\n", " train=False,\n", " download=True)" ] }, { "cell_type": "code", "execution_count": null, "id": "5149dbed", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "5149dbed", "outputId": "e34cb70e-2f3d-4806-cc0f-e702cb46428b" }, "outputs": [], "source": [ "test_data" ] }, { "cell_type": "markdown", "id": "176bf8d3", "metadata": { "deletable": true, "editable": true, "id": "176bf8d3" }, "source": [ "## Data Transforms\n", "\n", "In the data loading step, we pulled data from its source and created dataset objects that contain information about the dataset and the data itself. However, the data might need to be adjusted before it is passed into the NN model for training and testing. For example, data values may be normalized to assist training, augmented to create larger datasets, or converted from one type of object to a tensor.\n", "\n", "These adjustments are accomplished by applying transforms. The beauty of using transforms in PyTorch is that you can define a sequence of transforms and apply it when the data is accessed. " ] }, { "cell_type": "code", "execution_count": null, "id": "47a5b599", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "deletable": true, "editable": true, "id": "47a5b599", "outputId": "7ff8c00a-ac25-433e-fe7c-1a10844ed522" }, "outputs": [], "source": [ "from torchvision import transforms\n", "\n", "train_transforms = transforms.Compose([\n", " transforms.RandomCrop(32, padding=4),\n", " transforms.RandomHorizontalFlip(),\n", " transforms.ToTensor(),\n", " transforms.Normalize(\n", " mean=(0.4914, 0.4822, 0.4465),\n", " std=(0.2023, 0.1994, 0.2010))])\n", "\n", "train_data = CIFAR10(root=\"./train/\",\n", " train=True,\n", " download=True,\n", " transform=train_transforms)" ] }, { "cell_type": "markdown", "id": "f475febe", "metadata": { "deletable": true, "editable": true, "id": "f475febe" }, "source": [ "We define a set of transforms using the transforms.`Compose()` class. This class accepts a list of transforms and applies them in sequence. Here we randomly crop and flip images, convert them to tensors, and normalize the tensor values to predetermined means and standard deviations.\n", "\n", "The transforms are passed to the dataset class during instantiation and become part of the dataset object. The transforms are applied whenever the dataset object is accessed, returning a new result consisting of the transformed data.eate a variable from an array or list of constants." ] }, { "cell_type": "code", "execution_count": null, "id": "addd9065", "metadata": { "deletable": true, "editable": true, "id": "addd9065", "outputId": "62e9e57f-ce4e-431c-afe1-8025f69a7f1f" }, "outputs": [], "source": [ "train_data" ] }, { "cell_type": "markdown", "id": "3e1572ff", "metadata": { "deletable": true, "editable": true, "id": "3e1572ff" }, "source": [ "The data output is now a tensor of size 3 × 32 × 32. It has also been randomly cropped, horizontally flipped, and normalized." ] }, { "cell_type": "code", "execution_count": null, "id": "bce5602f", "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 284 }, "deletable": true, "editable": true, "id": "bce5602f", "outputId": "9338dd4b-984b-43ae-d93c-fdb5fe1a415f" }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "data, label = train_data[0]\n", "\n", "def imshow(img):\n", " npimg = img.numpy()\n", " plt.imshow(np.transpose(npimg, (1, 2, 0)))\n", " plt.show()\n", "\n", "imshow(data)" ] }, { "cell_type": "markdown", "id": "9719bec9", "metadata": { "deletable": true, "editable": true, "id": "9719bec9" }, "source": [ "The colors may look strange because of the normalization, but this actually helps NN models do a better job of classifying the images.\n", "\n", "We can define a different set of transforms for testing and apply them to our test data as well. In the case of test data, we do not want to crop or flip the image, but we do need to convert the image to tensors and normalize the tensor values." ] }, { "cell_type": "code", "execution_count": null, "id": "016521dd", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "deletable": true, "editable": true, "id": "016521dd", "outputId": "90faee82-958d-42f4-cb81-90d2da69ac00" }, "outputs": [], "source": [ "test_transforms = transforms.Compose([\n", " transforms.ToTensor(),\n", " transforms.Normalize(\n", " (0.4914, 0.4822, 0.4465),\n", " (0.2023, 0.1994, 0.2010))])\n", "\n", "test_data = CIFAR10(\n", " root=\"./test/\",\n", " train=False,\n", " transform=test_transforms)\n", "\n", "test_data" ] }, { "cell_type": "markdown", "id": "d8bc68cd", "metadata": { "deletable": true, "editable": true, "id": "d8bc68cd" }, "source": [ "## Data Batching\n", "\n", "Now that we have defined the transforms and created the datasets, we can access data samples one at a time. However, when you train your model, you will want to pass in small batches of data at each iteration. Sending data in batches not only allows more efficient training but also takes advantage of the parallel nature of GPUs to accelerate training.\n", "\n", "Batch processing can easily be implemented using the torch.utils.data.DataLoader class." ] }, { "cell_type": "code", "execution_count": null, "id": "56ef5f4e", "metadata": { "deletable": true, "editable": true, "id": "56ef5f4e" }, "outputs": [], "source": [ "trainloader = torch.utils.data.DataLoader(\n", " train_data,\n", " batch_size=16,\n", " shuffle=True)" ] }, { "cell_type": "markdown", "id": "df4d5486", "metadata": { "deletable": true, "editable": true, "id": "df4d5486" }, "source": [ "We use a batch size of 16 samples and shuffle our dataset so that the dataloader retrieves a random sampling of the data.\n", "\n", "The dataloader object combines a dataset and a sampler, and provides an iterable over the given dataset. In other words, your training loop can use this object to sample your dataset and apply transforms one batch at a time instead of applying them for the complete dataset at once. This considerably improves efficiency and speed when training and testing models.\n", "\n", "We can configure our data loader with the following input arguments (only a selection, see full list [here](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader)):\n", "\n", "* `batch_size`: Number of samples to stack per batch\n", "* `shuffle`: If True, the data is returned in a random order. This is important during training for introducing stochasticity. \n", "* `num_workers`: Number of subprocesses to use for data loading. The default, 0, means that the data will be loaded in the main process which can slow down training for datasets where loading a data point takes a considerable amount of time (e.g. large images). More workers are recommended for those, but can cause issues on Windows computers. For tiny datasets as ours, 0 workers are usually faster.\n", "* `pin_memory`: If True, the data loader will copy Tensors into CUDA pinned memory before returning them. This can save some time for large data points on GPUs. Usually a good practice to use for a training set, but not necessarily for validation and test to save memory on the GPU.\n", "* `drop_last`: If True, the last batch is dropped in case it is smaller than the specified batch size. This occurs when the dataset size is not a multiple of the batch size. Only potentially helpful during training to keep a consistent batch size." ] }, { "cell_type": "code", "execution_count": null, "id": "43ecbfd5", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "collapsed": true, "deletable": true, "editable": true, "id": "43ecbfd5", "outputId": "2bfe85da-476b-4ab4-c44f-247cceb6d6b3" }, "outputs": [], "source": [ "data_batch, labels_batch = next(iter(trainloader))\n", "\n", "data_batch.size()" ] }, { "cell_type": "markdown", "id": "cf797ec1", "metadata": { "deletable": true, "editable": true, "id": "cf797ec1" }, "source": [ "We need to use `iter()` to cast the trainloader to an iterator and then use `next()` to iterate over the data one more time. This is only necessary when accessing one batch. As we’ll see later, our training loops will access the dataloader directly without the need for `iter()` and `next()`. After checking the sizes of the data and labels, we see they return batches of size 16." ] }, { "cell_type": "code", "execution_count": null, "id": "dd2c5c09", "metadata": { "collapsed": true, "deletable": true, "editable": true, "id": "dd2c5c09" }, "outputs": [], "source": [ "testloader = torch.utils.data.DataLoader(\n", " test_data,\n", " batch_size=16,\n", " shuffle=False)" ] }, { "cell_type": "markdown", "id": "3826f6b3", "metadata": { "deletable": true, "editable": true, "id": "3826f6b3" }, "source": [ "We set shuffle to False since there’s usually no need to shuffle the test data.\n", "\n", "PyTorch also provides a submodule called `torch.utils.data` that you can use to create your own dataset and dataloader classes like the ones you saw in Torchvision. It consists of `Dataset`, `Sampler`, and `DataLoader` classes.\n", " " ] }, { "cell_type": "markdown", "id": "f07c13e9", "metadata": { "id": "f07c13e9" }, "source": [ "## Example: Continuous XOR\n", "\n", "If we want to build a neural network in PyTorch, we could specify all our parameters (weight matrices, bias vectors) using `Tensors` (with `requires_grad=True`), ask PyTorch to calculate the gradients and then adjust the parameters. But things can quickly get cumbersome if we have a lot of parameters. In PyTorch, there is a package called `torch.nn` that makes building neural networks more convenient. \n", "\n", "We will introduce the libraries and all additional parts you might need to train a neural network in PyTorch, using a simple example classifier on the simple XOR example from the previous section: given two binary inputs $x_1$ and $x_2$, the label to predict is $1$ if either $x_1$ or $x_2$ is $1$ while the other is $0$, or the label is $0$ in all other cases. Recall that a single neuron (linear classifier) cannot learn this simple function.\n", "Hence, we will build a small neural network that can learn this function. \n", "To make it a little bit more interesting, we move the XOR into continuous space and introduce some gaussian noise on the binary inputs. Our desired separation of an XOR dataset could look as follows:\n", "\n", "![image.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAYAAAAGACAYAAACkx7W/AAAMbWlDQ1BJQ0MgUHJvZmlsZQAASImVVwdYU8kWnluSkJDQQpcSehNEagApIbQA0otgIySBhBJjQlCxo4sKrl1EsaKrIoptBUQUxa4sir0vFlSUdVEXGypvQgK67ivfO9839/45c+Y/5c7k3gOA5geuRJKHagGQLy6QJoQHM8akpTNITwEGzIABIAArLk8mYcXFRQMog/e/y7sbAFHcrzoruP45/19Fhy+Q8QBAxkGcyZfx8iE+DgC+nieRFgBAVOitphRIFHgOxLpSGCDEqxQ4W4l3KnCmEjcN2CQlsCG+DIAalcuVZgOgcQ/qGYW8bMij8RliVzFfJAZAczjEATwhlw+xIvbh+fmTFLgCYntoL4EYxgOYmd9xZv+NP3OIn8vNHsLKvAZELUQkk+Rxp/2fpfnfkp8nH/RhCwdVKI1IUOQPa3grd1KUAlMh7hZnxsQqag3xBxFfWXcAUIpQHpGstEdNeDI2rB/Qh9iVzw2JgtgE4jBxXky0Sp+ZJQrjQAx3CzpVVMBJgtgQ4oUCWWiiymazdFKCyhdalyVls1T6c1zpgF+Frwfy3GSWiv+NUMBR8WMaRcKkVIgpEFsXilJiINaA2EWWmxilshlVJGTHDNpI5QmK+K0hThCIw4OV/FhhljQsQWVfmi8bzBfbLBRxYlT4QIEwKUJZH+wUjzsQP8wFuywQs5IHeQSyMdGDufAFIaHK3LHnAnFyoorng6QgOEG5FqdI8uJU9rilIC9cobeE2ENWmKhai6cUwM2p5MezJAVxSco48aIcbmScMh58GYgGbBACGEAORyaYBHKAqK27vhv+Us6EAS6QgmwgAM4qzeCK1IEZMbwmgiLwB0QCIBtaFzwwKwCFUP9lSKu8OoOsgdnCgRW54CnE+SAK5MHf8oFV4iFvKeAJ1Ij+4Z0LBw/GmweHYv7f6we13zQsqIlWaeSDHhmag5bEUGIIMYIYRnTAjfEA3A+PhtcgONxwJu4zmMc3e8JTQjvhEeE6oYNwe6KoWPpDlKNBB+QPU9Ui8/ta4LaQ0xMPxv0hO2TG9XFj4Ix7QD8sPBB69oRatipuRVUYP3D/LYPvnobKjuxKRskG5CCy/Y8rNRw1PIdYFLX+vj7KWDOH6s0emvnRP/u76vPhPepHS2whdhA7i53AzmNNWD1gYM1YA9aKHVXgod31ZGB3DXpLGIgnF/KI/uFv8MkqKilzrXHtcv2snCsQTC1QHDz2JMk0qShbWMBgwbeDgMER81yGM9xc3dwAULxrlH9fb+MH3iGIfus33bzfAfBv7u/vP/JNF9kMwH5vePwPf9PZMwHQVgfg3GGeXFqo1OGKCwH+S2jCk2YE32VWwB7m4wa8gB8IAqEgEsSCJJAGJsDohXCfS8EUMAPMBSWgDCwDq8E6sAlsBTvBHnAA1IMmcAKcARfBZXAd3IW7pxO8BD3gHehDEISE0BA6YoSYIzaIE+KGMJEAJBSJRhKQNCQDyUbEiByZgcxDypAVyDpkC1KN7EcOIyeQ80g7cht5iHQhb5BPKIZSUV3UFLVFR6BMlIVGoUnoeDQbnYwWofPRJWgFWoXuRuvQE+hF9Dragb5EezGAqWP6mAXmjDExNhaLpWNZmBSbhZVi5VgVVos1wud8FevAurGPOBGn4wzcGe7gCDwZ5+GT8Vn4YnwdvhOvw0/hV/GHeA/+lUAjmBCcCL4EDmEMIZswhVBCKCdsJxwinIZnqZPwjkgk6hPtiN7wLKYRc4jTiYuJG4h7iceJ7cTHxF4SiWREciL5k2JJXFIBqYS0lrSb1Ey6QuokfVBTVzNXc1MLU0tXE6sVq5Wr7VI7pnZF7ZlaH1mLbEP2JceS+eRp5KXkbeRG8iVyJ7mPok2xo/hTkig5lLmUCkot5TTlHuWturq6pbqPery6SH2OeoX6PvVz6g/VP1J1qI5UNnUcVU5dQt1BPU69TX1Lo9FsaUG0dFoBbQmtmnaS9oD2QYOu4aLB0eBrzNao1KjTuKLxSpOsaaPJ0pygWaRZrnlQ85JmtxZZy1aLrcXVmqVVqXVY66ZWrzZde6R2rHa+9mLtXdrntZ/rkHRsdUJ1+DrzdbbqnNR5TMfoVnQ2nUefR99GP03v1CXq2ulydHN0y3T36Lbp9ujp6HnopehN1avUO6rXoY/p2+pz9PP0l+of0L+h/8nA1IBlIDBYZFBrcMXgveEwwyBDgWGp4V7D64afjBhGoUa5RsuN6o3uG+PGjsbxxlOMNxqfNu4epjvMbxhvWOmwA8PumKAmjiYJJtNNtpq0mvSampmGm0pM15qeNO020zcLMssxW2V2zKzLnG4eYC4yX2XebP6CocdgMfIYFYxTjB4LE4sIC7nFFos2iz5LO8tky2LLvZb3rShWTKssq1VWLVY91ubWo61nWNdY37Eh2zBthDZrbM7avLe1s021XWBbb/vcztCOY1dkV2N3z55mH2g/2b7K/poD0YHpkOuwweGyI+ro6Sh0rHS85IQ6eTmJnDY4tQ8nDPcZLh5eNfymM9WZ5VzoXOP80EXfJdql2KXe5dUI6xHpI5aPODviq6una57rNte7I3VGRo4sHtk48o2boxvPrdLtmjvNPcx9tnuD+2sPJw+Bx0aPW550z9GeCzxbPL94eXtJvWq9urytvTO813vfZOoy45iLmed8CD7BPrN9mnw++nr5Fvge8P3Tz9kv12+X3/NRdqMEo7aNeuxv6c/13+LfEcAIyAjYHNARaBHIDawKfBRkFcQP2h70jOXAymHtZr0Kdg2WBh8Kfs/2Zc9kHw/BQsJDSkPaQnVCk0PXhT4IswzLDqsJ6wn3DJ8efjyCEBEVsTziJseUw+NUc3oivSNnRp6KokYlRq2LehTtGC2NbhyNjo4cvXL0vRibGHFMfSyI5cSujL0fZxc3Oe5IPDE+Lr4y/mnCyIQZCWcT6YkTE3clvksKTlqadDfZPlme3JKimTIupTrlfWpI6orUjjEjxswcczHNOE2U1pBOSk9J357eOzZ07OqxneM8x5WMuzHebvzU8ecnGE/Im3B0ouZE7sSDGYSM1IxdGZ+5sdwqbm8mJ3N9Zg+PzVvDe8kP4q/idwn8BSsEz7L8s1ZkPc/2z16Z3SUMFJYLu0Vs0TrR65yInE0573Njc3fk9uel5u3NV8vPyD8s1hHnik9NMps0dVK7xElSIumY7Dt59eQeaZR0uwyRjZc1FOjCj/pWub38J/nDwoDCysIPU1KmHJyqPVU8tXWa47RF054VhRX9Mh2fzpveMsNixtwZD2eyZm6ZhczKnNUy22r2/Nmdc8Ln7JxLmZs797di1+IVxX/NS53XON90/pz5j38K/6mmRKNEWnJzgd+CTQvxhaKFbYvcF61d9LWUX3qhzLWsvOzzYt7iCz+P/Lni5/4lWUvalnot3biMuEy87MbywOU7V2ivKFrxeOXolXWrGKtKV/21euLq8+Ue5ZvWUNbI13RURFc0rLVeu2zt53XCddcrgyv3rjdZv2j9+w38DVc2Bm2s3WS6qWzTp82izbe2hG+pq7KtKt9K3Fq49em2lG1nf2H+Ur3deHvZ9i87xDs6dibsPFXtXV29y2TX0hq0Rl7TtXvc7st7QvY01DrXbtmrv7dsH9gn3/dif8b+GweiDrQcZB6s/dXm1/WH6IdK65C6aXU99cL6joa0hvbDkYdbGv0aDx1xObKjyaKp8qje0aXHKMfmH+tvLmruPS453n0i+8Tjloktd0+OOXntVPypttNRp8+dCTtz8izrbPM5/3NN533PH77AvFB/0etiXatn66HfPH871ObVVnfJ+1LDZZ/Lje2j2o9dCbxy4mrI1TPXONcuXo+53n4j+catm+Nudtzi33p+O+/26zuFd/ruzrlHuFd6X+t++QOTB1W/O/y+t8Or4+jDkIetjxIf3X3Me/zyiezJ5875T2lPy5+ZP6t+7va8qSus6/KLsS86X0pe9nWX/KH9x/pX9q9+/TPoz9aeMT2dr6Wv+98sfmv0dsdfHn+19Mb1PniX/67vfekHow87PzI/nv2U+ulZ35TPpM8VXxy+NH6N+nqvP7+/X8KVcgc+BTA40KwsAN7sAICWBgAd9m2UscpecEAQZf86gMB/wsp+cUC8AKiF3+/x3fDr5iYA+7bB9gvya8JeNY4GQJIPQN3dh4ZKZFnubkouKuxTCA/6+9/Cno20EoAvy/r7+6r6+79shcHC3vG4WNmDKoQIe4bNoV8y8zPBvxFlf/pdjj/egSICD/Dj/V/8NpDlJkL9+QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAABgKADAAQAAAABAAABgAAAAABPSEMJAABAAElEQVR4Aey9CZheR3WgXVpbS7f2fbElL5Ll3diWbUjANiYQMGAcQjIBbGfyZ8OQ4ZknMdv/DyQPW2BmksHLJEwSsGGy4MRgAgSC8YKDsWUb71q8ytr3raXWrv7Pe06dW3Xv93WrW1Lbcvctqb9bdbY6de6tU3Vru4M6JYQ61BaoLVBboLbAgLPA4AFX4rrAtQVqC9QWqC2gFqgbgPpBqC1QW6C2wAC1QN0ADNAbXxe7tkBtgdoCdQNQPwO1BWoL1BYYoBaoG4ABeuPrYtcWqC1QW6BuAOpnoLZAbYHaAgPUAnUDMEBvfF3s2gK1BWoL1A1A/QzUFqgtUFtggFqgbgAG6I2vi11boLZAbYG6AaifgdoCtQVqCwxQC9QNwAC98XWxawvUFqgtUDcA9TNQW6C2QG2BAWqBugEYoDe+LnZtgdoCtQXqBqB+BmoL1BaoLTBALVA3AAP0xtfFri1QW6C2QN0A1M9AbYHaArUFBqgF6gZggN74uti1BWoL1BaoG4D6GagtUFugtsAAtUDdAAzQG18Xu7ZAbYHaAnUDUD8DtQVqC9QWGKAWqBuAAXrj62LXFqgtUFugbgDqZ6C2QG2B2gID1AJ1AzBAb3xd7NoCtQVqC9QNQP0M1BaoLVBbYIBaoG4ABuiNr4tdW6C2QG2BobUJagv0xAKrVq0Ka9asaSBta2sLCxYsaIDXgL6zwHe+851w/vnnh9mzZ/ddJrXkAWGBugEYELf56Av57W9/O9x0001NBZ122mnh5ptvDrNmzWqK7wr4uc99LowZMyZ85CMf6YqkT+B33HFHuOuuu8Itt9zSJ/L7UmhHR0f42Mc+Fr70pS/VDUBfGnqAyK6HgAbIjT5WxVy2bFnI/77whS8E3g6uv/76Xmdx22239ZrnWDDQAOzYseNYiKpl1BZ4TVugfgN4Td++V1/5q6++OsycOTNcc801AcdK2oMPGy1ZskSHiXhToMdPeOihh/S6evXq4HgAOOalS5cqDLnwVN8soF+0aJHm2wyPHOQzZIWMhQsXAtIAb3t7u8aRkeMiSXFBxsMPP6w0ue5O0F35vBzIJ0/KhAwfLmsGQy55QgM/eVf197yrV3QhD+w7Y8aMBpshj/JS9p7KrOZRp/ufBeoGoP/d01e8RBdddJE6HYZVvAFgeIcePk6PeYLPf/7zemX8GodOg0FgaAnn9c1vflMd5Qc/+EGlw0nROODEectwuQx/IOPCCy9UZ4bTy/E41o9//OMqE0fqDpwhKpwjesFDIC/eZqoBZwkOvZDxL//yL5oXMigr4cYbb9Qhsa7Khx6U8aqrrtLhJvKmLMCQj60c9olPfCJcd911Khf8e97zHrULZcQGgwYN0iE2bzyUMPvJdUE2Tv6Tn/xkYTPywibYlHvhNvnGN76RSamjA9ICnXWoLdADC3zlK1/pnDdvXpeU73//+zvf9a53KX7x4sVK+7Wvfa2gdxhyPCAvT1966aWdf/iHf+jozu3bt3cilz+Cy3jwwQcLGvhlQrRIux7wErii1w033FCicZkFMIugN7q5DFDN9OiufOiIjLw8n/3sZxtg4C+77LIid3j4o6wE1/8DH/iApnft2qV4aQQ17fn8+Mc/1jQ/rv/KlSsVRvnJ24PbMedxXH0dWBao5wAGZLPfN4X2njW9THr/3qslN3qvra2t3Wb8xS9+UXuuTkQP2XvxDuP6k5/8RHvnxJlAfuSRR4jqGwS9W3q/8BK4XnvttfrWoIAe/Dgvbyf0qAm8ofBHoCfdrHwMvVQDeXu44oorNJrDKB+9/DzwFuC9fXShjAzf8EZSDfT+eVNw2eCxO7qgP4H7AT9vJQRk8+aT8yii/hlwFqiHgAbcLe+7AuOICD5mz6ohxrRxot44dJc7jgnnDh9OEaeVB/A4x1tvvVX/GH5hSAYYebojZbjJnTj87sTRxYdwcrnVOI6R+Qzk8Mc4PjCGZpDLH41Ab8vn+RxOB2TnAQdOoHwTJkzIUQpjiIghqzwwDOQO/1Of+lSQNwgdjkKWl+VweuTy6nj/tEDdAPTP+/qKlwpn4z1K4jgkHBkwHDfOuuqkqkr6uDvj/ThbevKMX+fLT3Fm9KBpHMAxPo+zZl7AAz1md5oO44oePQk4eHr79LjJgz8aAvK58847S3MV6OrlO5KVUM308UnqZrhmMGybv1U4jTeC6Pfoo49qOWgEKQ9vB/ncg/PU14FlgboBGFj3u09K+/Wvfz3s3LmzmHTEUcpIqjpLz5BeeLONZI7HMfGWwESrNyTgGOLwAA1DPB/+8Ie1x4/zpbFhohXevOec926h4c2ipw0ADhJ9kc9wCn/AcPDIIo6Tvvvuu0tvGuiQ6+569/ZaHerxN5tm+gMDn5eX/LAbOP6Io5f/0Yi++93v1nJQtjoMXAvUcwAD994fUcnpefsfjpDVJazCwQm7E6LnSYOAsyTgTOlBNws4L+i8t5o7PxoSHLcHaHBmDAF5oFEg4PxxdgxDkZfnjTx0lMnSIg/oceDOSzoP6EvvOMfLhKnOYZCHB3fM0JMHIdff6Xp75W3G86YclAf7uo1yefT8aXhy+2Ij3pr8LcjvE3oS0JHy5w1mLrOODxwL1G8AA+deH5OSVodxmGykR57v5sUp4XRwWjgZHCXj9Dhn4E775je/WYcigDGRCw2NCROsOCuGNpCNM8Np4XzBs5Qzd3jA3DGzuxdnTN4eyDff9UtPGB7yw9k6r9P7mwV4D0xg//mf/7km8/KhIw4YWspD/GgDcj70oQ9pI4os0vTamwUaXRqrvGFEV8rnDTKT68jzORrkEO9KZrN8alj/tMAgFj31z6LVpXq1LUDvFUeOg23We0U/76m7E8bR02DQcPhkcrUcyMz5msl2mq7keC/Y863mQdplEHdnStxDT8rntD29zp8/Xxs9GhnkN9N/69atYfz48Q0iXZ9mukLs+GYyG4TVgAFhgboBGBC3uS7ka8UC3gD4W9JrRe9az9emBY5qDoAexbEK9MiOpbxjpVctp7ZAbYHaAv3VAkf8BsAkFeOezbbS58ZiIo8xympwPl6zWV3BxCJjl2PHju1223tVTp2uLdCfLEC9qodo+tMdPb7LckSTwDj1fBKuuyLSq2fCqatXWibsWK3A8j7GcpmsQnZ9Tkl3Vq1x/dUCXY3f99fy1uV6dS3Q6waAw7hYtcFKinzzTVfFoAHgoW72YNP7Z5mfH9SFDBoKVnDA190EXVf51fDaArUFagvUFuiZBXo9B4Ajv+eee4pNP4fLhp49r7Qs5aNnT+Phwcf8aUw8uNN3nMPra22B2gK1BWoLHFsL9LoBYI10s2V3zdRiYpfAGmVWm8rJhjrezzru7gJzAb7Jpju6GldboLZAbYHaAkdugV4PAfU2KzbysKbZG423vOUt2gjQkHR15onT9javmr62QG2B2gK1BXpugT5tANjIU5389eEehngYGmoWODPGt7E3w3cH27bkobD8n7+iJIO6IxRcb3bAGW1ZYpW/szPhc1xnMHiCDdK8G9ORThDw5HxN05IfMhxn1xAOwas4w2s6yoP+UIGzPJze6bjqX6TL4ZpHCU5+gzU/o4v5qwyBo19GL0nTr9DR7kMqQ1Ye5Svj4Sd4WfN4sn+yixIrvfHk6SA6ENDRQjmd5Bm2SudcVXhKO0X3/GWqXJ8qxvSrQrvKr0rXm3SjzOZ590bmQKBtHTU8/O8/fe9rpqi9HgLqTclY0paf25Lz4vy9p5+P9zMxTPC5gJynv8WrVcrTXO3PqmF3aaczV45bDLhj3Gv8O3w60Rq/p01O4i/LTfKtueiM+aK7yXF+l8eVkKdT2bzMfs3lJ5gKaPLjcpqgalBtgdoCXVjgmDcAjz/+eFi+fLlmxxAPE7+5g+fkSMb4cfD8sUSUZaUeaDA4X6bZqiGn6ekVd9PdX0/ldEVXdTqDBonTkj8COA/J8TncHCR4o/O0OT2A5iTtanRGk2RJGjryVDnG63yDFe6w5MQVLwxlZ+5yoLd+vOJFxuBBWVqs6XDLJ8k3PbK0NgIxXZSngkfHiv6U1fvqlC8InuDl4pqnPR6BapOCP+qgOPlxnY3HocCbB80+Q6W06ZChYhQ4ZWweDs/fnO+VhqbSucZdleiV1qzO71hb4JgPAX30ox8N8om78OlPf1qXirKkkwPEGPqhQeBURg7V8t4/B1LxsQo/KphVQiwLPd4CVSBVjJ5p59UGvpzf4jgKpzDZToOj6sT7CaNRSFqpkwalNKQyXOLOEe3A0wgcsoRqgPPWNDCRP1jEHRIYvQDcvNMPFlnQOf1goT0ktEUaesnT+IHDL0Fg6OvwCOIS88vyV8pYnkx/+JECxhy2RrLyQVG2B2UlqN30mmKKEPrcOibBczFbuVSTY/l74yM3w8T08994N2IpB0aZ+/ktPWzxjngnsB+UVe2p8wYwbty4MGfOnCJz3gBw7Az78HWl6iFfrBZiJzArf/gQSBVfCOpBJJ8D6AF5r0jc0TRjKlcec8hOl3BWqTzt8pqlwTkcB0Q8pze8ydM+uhA43vrs8CQ+GgjghDIe5260Bgcvrj7Sk6+mhdfoEr/BJV3w00REvPJnaXRRusTv+hX6RLyXzfHFVfCEIh3L05iu2t/sgMs3/mQrT6fmAIjTE5eQ2dYACpKoyYskjorXiowMi41y3gylUcNXoaRTfjm2a/qcqvt4WUbzfLqX8Cpiy8q/ioqEoHMAf/bamQM44jcAevBV54/lzz333IYb4MM9DYgIwOEfjdPvSu5rGe5VsNmz7TjKB95cjUEt3azkuElzfMk1OaflYhJSX7n7tNPJm4NogRN3adWr4U0ntEj5A3N+w5uTy0ttWrvza17eVOoUcyftcutrbYHaAlULHHEDUBV0PKVzJ3Bs9UIywVyjxbv4db8VqY2zym9pd4k4RiCW9hiOzNymuzR35eTsTlqHK1Sc62ayjULiMoxjw+kmF15rDuQiOOmeF6VSCfITh98TPIoepD1xXH6cQlLZKY3+MDu/JOQfOsThIuV3/dBDOYhIyPUjZem80UiauiWiYkJLTH9NBeVGqsGJWTBbG5/jLGV5Ro2d2NRy5qO8Wn7lch6JyNyCR8LvPEmOW8Axr/I1KdanivQ0m+PMOsfEJv2wAbDbxE19JW8YeeUPUu5guFM53uOunzt419nlFE5PHCwb6ZJTMkqXYzkLVgUKTv8nanKHw8b4hYiEBnOYFk898cFCX5oDEAJLx6uIYNgn79nzYfLBomOJLvIhH20848GR39OGVyL7sSKo1nARtPTaoghE9eensJBTFEUDYxYz7tx6zpdkGyS3hmXiFI14MNY4IT8vHWmC6Wfx3v2a7N7xHAm1mvFIGPuCp5fK9JL8mGjckzx7QnNMlDlGQvphA4BlrOKmCuqQo7Oau4Me3+QuGaruKPq0qJ65teTcVIz8WCNQLp9lYb/m8oROkvhKzwV9oSCdO22gRVoIfCI5yYmNiAgoJopFSjMn7xPBftX80AN1M34Sqo8TGNrooAUPnxCZ/go0uFCpYy94ofDgLt/SiomvIPbG4qUCb5JNE3R0W6NZSrtshUadwBsVMQ9AnNphCdJIn2iOn1ij/n2mWw8M0gOSPlNvIAnupw1A/7iFVMlmFcGqKhhzXM3T2MCcXuHkFZLcHRTIcHxzJ+9aON/h6dEKLpfnpTA9E7+7SM9f1cn08bTx56UEUy2/URvU4k6VUhbzElXhdbq2wECzQD9vAMxpcFPNkdov6YQh1bOQ9zd7wpH6lZab55l0cQjSrFdqMXPtDjE3LrSRXEZaPKpqFPjoFBVYxB2byu5j/kbHb3TuIl+dtpB6T16vjC11pjF+pbcuunDyPgC/XjRNjzvxyxuD8ufWi/jYQ6fL77ZCTC7f034HwWk8yiRNyfwX+oa05ONvAYY3GVFroTcOLUPBjxzgqo3FMn0NruhIZZoBMa485pKNnl/TwCkb8Ymyb2Kes0nv4/zLmTUU6DDoBvoacOws0C8bAB6o5o90gnrldlMmjEN6f3UZ1Qe68FVRJHS5jh53nZI7NEmWtuZAacURMVyDFMsT92d4dz/sI5A1vkKT52byVI2KUuYMDd983b847TjGD7/S41hJqAPXiKbL/HGfgeSX80PtjQRMuYMGl+tDOpUji1MGLKn/4UjlM80y+8RGwCncKkgjuAWrcUWqXC2pJnNao0cFJCca47Pfal45rnfxXPuUm0N7J6uPqbtRqhtUHytVi69agDrYLwMPmf81LyDVMv3hKpy++oAarnnlbi67ChWJTdktR0e5NqZ50g5pRuNaAjDnZjwWb6ATZHmnLXK8NHIt8HGHr+YTdRL5Js/oGaZBlu8w1rQQFHCVG9MSNzrSvDlE+ZKf87u1XR+nL8Ez/Qye66/qqV18F7Lpa3C3oaUogwSVZzIsaWVTnKGNDmQsT45TMD/IEXxXwXkSvjktdEbbiG+UkaQdu1jS4NjJFEmV4pDM/45pXrWwo7JAv3wDOCqLvEaYqbqVehYh1ne2Yvh7AZRVl+LcSZJRMDxzSP4Nln+2actz8h57+dpIX+X3NUUuz8f8PV2WjzybaLYylPXDZbvzNUz35fWSe2mRaeX0XC2X+re2wEC0wIBoALzye8Xv+kYnCufpmrZrjDmmMr4KK6fdTSWeHI/DM8dnTiulbeABl2ZO0TB5Go40HIR8l+xXQBKX4R0gFqITFoA66TjcBE7TwEXltBpI6OXMoEOdqdFQJy50yLThHaM2fqGPw0nWWEBlwWKVRkD1Q5bdFW8EnMvTlpvb0miRmvCWhx2zkUM97jzWqKSUWlHytxwVTtQJJGpJB5T5ybVCDuhVC67lMVWgIrSSPKZZ1cKOnQWoj/0qMOxtRw5YZc0Lx0Ppfzn8lYmLkxGV+PNA1JN+BWdxnJLHuVqVcjpNS0JlFjh47M/kuAzhhTbiTG7CKVyAOpxT0PiwkF8Tv9IxHBRp7Sr8DEtlcM8vDe9UhoNK/Mbrwzno6PJVX5WbdKB8CZ+Xz2gayi8A9LFgZedpMB2BGsxtA8T1tzi/8Duv4GN5wZSD55NDk/wcSpw8TbZGevDTTH4P2PqKpKJOJdlXudZyj4EF+u8bgDyFRVWVGpYqv1ktf0itAh4Da/ZUBBnmCigf2iZXYCRGBJxYKoOnY4ZKnN4SDOpp4yRDfRNAkoptooS0JjhVDn6zENNCaj3+xFO8CQihHRSXvREImfhGLY3SCU3a/FV5E4j5GV3Kz9SsWAQ9ND9TEIupvqZsUb60nyFZTssv9G65Tpy3vtnAjDwwXnCj8+fHMJTdg92rRO22NnyCl9PR8ALMZbnMxqtTubxGilcZUlGsknyVlauz74kF+m8D0JPSv4ZpcA55hcudhTs5igdN8zTYHEO67MhS2nJyJ+05e56FkxcJtijUXFwVXuX3tDlxd+Z+jc5enWUqqTl9y8c09lKQQrPk5C1tuihS8SmdpBrWbepX56mvtQX6qwX6ZQNgTi+7ZQJQx0C3tElwqDu0JiS9BnXnRKq4lDZNyi7M3G2iMYdHeZIjFkcekw7l6vjkFBVYmhNIeZF3TLkQhcAjAGwn/91pk7A8EjpSKtx6/E4fr8Kg/FZMyE2GvHkMkn0GYE2mpIv8mBAGakzw8ybjcwiSlOCaRMGMizEWqIFGzixgMrK05KFUuow1p8rp4bL8sQ7BJPMb81V0Sht1SitT9mP4DBAlRW1iqoxvTCX5zeQ10h9jCNlnoZLMMHX0eLZAv2wAMHj+QFJBCLZ2XiICsL6vgoufZjwF8phEPAdVoKRk95UYPi9FUsQh5jii0wQtDq2AKXlybsYtaXW6yQ7m8tzxGRUKeh5mNNPfh4Py4Rd8LkbnYo1EN1ch8mEml89ZQvlEtDpbbbBlrkHk5o0A2qVGwCW4jUxHnRzpSSOAMBqCohGgDI1PB7mYTRO+lLOpj7QsmC6N8lzXjLQULeMt7xLBcZWIFj+udOqZMn4Hu6J+7ZasqxJV4f2yAUhuzG5guTqJCQSgNMX9b7zROaQgq1rvKNLdV2orgetgtOVSeT8WFUw/c/KmEpy526lSxLQ4Po3FjEq5ghCnmDt5y4nGQ2LKk/D+ZuD0mhanrmmhbcCLjGZzB0qX0eP6OwfJm0HMz92wqRfLWOCs9G6D6pxHbiHKktJWIGsE9PGg8GrBQlYpVVhC0W5pbzacU9UyAWrncjrlHkmUhnhO57jj6npcKsgTcazDkcg8Ep5jrXfP5fXLBqDnxe+flP4IluspKcPYb0qbFZwarMfNDbpTN7rk9Mtph/f02qRREIH09D2/aqNRzs9S7oo9lRox3LKVJC9vKplz2NVocvrcCmXaOlVboL9YoN82AObeUrXOK34BLYDiLBRYAEr316HOV0J2kXCeLtAGdoGRuJIssYJzmR6v9jidgR66Dac0p6DvmRynEPMmoExIyHCgVJT3ccETxEkLjw/jkNacIj2vCJ4z/Bi3OsafnDybznD6OH8kWf4lfoH7nIJEJaRGwpKSSxzuUX0FTzk0b5XofXIrnUmwfPw3UUOTdCDm5Us01ns3+Yk+ZigA51fmQp6l0m/iT7AUMxmethJ5yq+mnemXyubYrq7NZXVF3TXcc++a4lhj3GLHWu7AldfvGgAqqVed9IDikAgGcXx+263OGpU7nxyfuKtQql85pHzL8GrK+ZrTd+W0KIWVx/nQ15xTgsQh9UI3MEaHFuScS3GbOX/CKkbJjQduC7ERICFsXha9yo8N2WTwqJDTgdFGRNj9G8Tk5fn52UBGb79OT37KLxEaDQ1N5KtiIAXH/TX5Rm6lt/Ka7SAz1+8NmFsIOVV6ZDmfZpGl3faWk//m0hLMYskqpEmZZoYduL9luwxcO/RdyftdA2CmqlZPq1DeDFiFTkYtHrNY67SqKrBn1bBnVCk/16aAVGp8JdnEIZBjoXVJjCWiw3IvbK8E6rCMy/hLLkwQ+Ri46cBmL+uZmxIGLTIUoPbkBewTtUXPXmDdjfEjw52qrcmnRMiLx1Aof5Qf3aHTe/7VNBI8f6PJ9JWol8/s7/mbJvYbnxAagmgz4P7c+H1OUg0CPr8jVesmeqTZnXNZli7dCaWxH6dCgvFxdShxC5ajp/rsmmWcRfsgOytvHwiuRVYs0E8bgEopB2Cy6nQwgcPy6lV2HbHhKFxM2bGZ63EpZtTkhN35+rWrMX6H+/Vw9I14d4E+R+BpNDJ9TDdLU+7cXZVL35y+zJ9Sday2QP+yQL9sAMyp2VsAt8urfHID5T5d2QnaDS4PCQFL3EbxSvx6nl4Cy9NccHJdpn/qRTq+KLn0aBlScQrjTKV2fpsIkVTW+y1kUH7GNrhmeNNMfnnbgERVjH1iwJHee+bqtAVubwzeCMhVYPkbg8pRfsvS30SMXxB6g1J+nrnyiR4eSBeWqrwRGXe10Yv0Wh6VRgliI+LpQqJmkyR4xkKnGae0JlUSLPb8OdYgWgKV1yxdILqJmHZlOd2QC8o1cM7uqfsWezzo0LclPB6l98sGAEPzaFfdfP6I5XiovSrAW9BFoF7E+RVwiEocCujFT1kSqTx/BFVh3aUd5z1d3JPL0Ij8uJOytKdSrqlREAoV6FJdQpbO8ESLIAlNi1h3capTpO9RIyDC8L0uV6/KnzUWQtPsIzPokdNTar9rXmK1tBDZcBDlN+Gp/CmNIsovjY3jjcMbU7O4cbgkrpEehAQ+5Qk0JhVr1IqOP65LDvN4Gef5OdauZZoy7nhPuWWOdz37n379sgHIK6vfMqof1ZLgj5ulDGIwgzStSgIs6IU4VWf4CwyJIwsoUBGT9ASRcnQycz+wGc7hDknlVYWjI0I9t4bLNE6XAwXOLzlJhQD0iOJ5E3CnboiU9uEZH9NX1oy+eBMQxrznD9xoBS5Rk2Mw/KhrYPwxv1TwEn1Zv9xZS0lFUCofUqPTjlfSrohb1+3TSFm2p3EalQiJeRHLg0uznMDk99PSRm/Fc30M1t2vlaY7Ci9Z9zR9j/W72fc5VXMwm1ahPU+/epr3XMeeUPbLBqAnBR+INLv3Hwyrd+yWv71hxpgR4eSJbWqG/GF254WLcEfijslslqCkoS+cdHSa3igYHCdtE7tG36yRsNU8Tk9+5OLpsjykWKjiDZrkk0aS86e0NS5gzQ0n55qX3+j5tZCXHDoPDvd0fa0t8FqxwBE3AKtWrQpXXXVVeOSRR7otK3Rf+MIXwkMPPRTGjBkTFi5cGD75yU9qHMYlS5aEz3/+8w0yvvGNbzTAegLwimkuxDhwKFaxqare48opDOb9YXMMxsuvcaU0wjSfiEh8GY1RZIAGKRmuJ1ErAZRI0vwLtoTL8Z4jpb/vxc3hB0vXh90HioWTYaY0Av/p3Nlh5thRKjHRWw55umkjIASc3kPPPHeydHntc5S5E5dGQHb04rTpeTu9Ng5C73MCfDwGe6Y5gWyfgOZnbwxedG0ElN+XhNpuAtU90uf5wVc0CrwGSCq9CbhU5VYc1vaTQ625MH6zh9GlpyuPpefG7o5z5/fP7iLltZjlTyp/Ok1L181p0KMaHOL6V/FdpeHrLU9XsnoKP/b5eel7qsHR0HWVV1fwo8mrL3mPqAHAaX/84x8P7e3t3eq2Y8eOcM0114QLL7ww4NBJ4+w/+MEPhjvvvFN5kUUjcfXVV3crqzdIqzypChGzSpWklCudczgeLMFup9/Uhkc2IvQiyDK+nHLJXV2h9nyqNN3hoDW8lZI0cnIn8tS6HeFfnl4b3jt/bHjf6eMgCRs6DoSbH9kUbn7ghfDHb5oXJoxqEb7cUmIDBuORno2BK7P+ZFppNDl10H62D/HUU49vAhV6c+JCJ9mRo9HLVeh0GEiA+XAQcBodaAt4qREo3z8zUFk/SuqNkBXRnwiUQ7bbk1zEmswH6OR3joWKYLyJw2IlrIj1RjHRKbP8OL2nG69o5fLIj2C/ZgcFFD+Hl9c9fyGojyKu+dGJN9sfnYyBzt3rBuDrX/96uOmmm8LMmTMPa7tFixaF1atXh+985ztFj/+LX/yivjng9GfNmqVvAAsWLAgf+chHDiuvpwRWZZPLt8qTHjrHVCEpbZXK3YjlW61+FW0k0+KBFEG5rArlUSQ9B9PMUwgkP097nHISvvGLVeFXT2ornD+wKaOGhj9947Twxz9ZE779zJrwOxfOEahxuvTCjdBT7mUj4D1z1UrU6HEjIFqkOYHopCV7f0PwxsEL7GnPT5266Or5FVbRomVOX/KhfEYnCmoR3ZGTtKcENguS1gZRUtIQONbwPBsGK2gjhHSBjcJoCIzeqP2+Wcp+XX4OS3E4kmYJfjSxvpB5NPp0zdvMXl1T15juLNDrBoBe/80336wy6d13F6644oqS84eWtwCCvz3wBnDRRRfpEBEwGhYahKMN+eOcx49W7muNf9X23Trsc9mJrU1VXzh9VLh7RUfhTqq2snSClmOIxBEBtZA7wqoT9nQ+JwC/98TBm1NmOMfhfs0bER/usZzdFVble7qqn+eHxpafvUmQSvmDxQ27q7WYp1OJHZ/nAm8d3AL792wP+/dYvR81braD6+txYIFeNwDeU2dMvyeh6sxvvPFGHRJyOA3A0qVLw1133aXiiH/iE58I1113XU/EN6GRSiu1Uzut6pysGnvFhcGdVLkSW58LvDuUKh4cATdBcDpN5D+CVoqMIIvmlEU8z6sAZhH4qzQuM8Et1rH/UFi9fY/S7zlwUKVMHt38Vk9pHRq27N6vNEmeWchz1JQqgHzvm+YapbjJSGl1wvENgkzcKdvYPykJsUdNVJ2zDufYcFFBL71vezPIGgfJRvHJAHZPhN+HW5xfyxLpm80JqKtHT7FaeU6gWl5JF8NBlrE/T2YbSuEQw/v7QvHEaDZmS6hjrnIlpprqVXXStMHt1/FVfmXJfvweOn2GOtJoWYHDSsHxr13676Fj28qCdtCQljBl7uvD+FmvK2A9iZgle0JZ0/TGAs29Qm8k9IL2Yx/7mA75fPOb3yy4aAgY//c5gDvuuEMbAOC8GfQ2eJWzRsBSXhVyxw3Mg1VxKqLBEpdTWCXKOYDkD2XCJZ6cQGmbEmX0PY4irVEYq3y+t3RjuOelLSqJ9edDGDCXsHjTnnCh9Par4ZmNe3SsHSpKZNS50zMOxUUHicM2WuOCQm2MY7SE/CacOmF4uSkS3CkXPXFBpbN/0vCNvymU6XO8vQn4hDGyNX+uKfsiP7TUoLj0ZpEB4ZS/3L4WL5dXyh8bgRxrVkAa9km6ECcY1KjMHAljFJa2BsMgzX5dwxzXDJbju4sn3qo+3XF1jzt4YG94+bHbQxg6Ikw454OhZdyccOjAnrBr1YNh/fP3iH06w4RZ53cvJGJdqx4R10S9sgB1q88Dwz5M/DIngPP33j8Zk3bnT5r4jBkzlJb0kQR/YOjJ8UfwquXV0GkMl2gS3KprSpsM0gaDx/8chrRugjN3de2GFVTKrUxo2odw22NrwkOrtoUPnT8xfPny6WHUsMFh3oQWJf7aE1t04jfnfHhtR7hvxS7tWW/ZvbeQT8lNJlf/gzPG3dHHtMOhwKnrx9IVl6ytckSoTSy7TJy5xe0KP4M/Ao95FGmVK/hBER/lF/wFfSavIT/Tx3Sxu+j8Vs6Ih4/CRN0cBwR4kSZP+bNAvo43mohI9BEAP4FGQBuqWJaIlovLNIjTJ7zlY3Rl2pzG8VaWMqavU1tWPhoOHdwbJp57rTp/8hssjUHbnEtD64m/HDa+9PNAI9FdoGTdla473hrXMwv0eQPgzp8rK39y5w+MRqEaWC56tCF/cPL40co9Xvmf3bQrPLGuPfzJRZPDpSe0hn9ask0nev9MJnoJ9JJvkAnfmx/dFG5fui18+cGN+nfOlBGKHzVsiF6b/ZhjMwcHvprmIXKY4c0Ju6OsOtmu0ganETD+rtPNGgHn6+rqOqGrx+3JyNNeDtc9ldf4ymlSXnaL57/IGqihY9uqMGLK2er0qzYYPevi0CmNw572DVVUnX6FLdCnDYA7f8rEMtCqY2eFEG8G+XwCq4OYB2C/wJEGqjeB6q1VXN8EUtrwVPHUw3Ae5+PqVTvHGTzxWbqcn7kVp+yrazkXGoAFE1vCGZPNoT+ydnd4x6nWkC6Y1BImjRoWfn3BuLBh14GwaHWHlL0z/MnFk8PwIYPD+JFDw0htAJJF3AGmkrk1KI9YRBBOA8TjxVV75FjOrOdOXdPCm9LmzNNbg/OQR/xTGTkc/mojEOXE/Gw/QeQp5Qcs6lvId/09D0kX+lM6x9u1nAbpMsEQLG1Xu09uB/ImkPZgbwHA7A+40xU0Gb3D0tXzaOQzmpRX4inHqvmVsY2pw9Ez/j94mD2LVW7eBAgH9trEcBVP+vAaN+OqYb21wDGfA7j00kvDZZddFj796U8HxvNx5qeddlq4/vrrS7qxGYy3gTe/+c2K88nlW2+9VZeJHsn4f56BV0EeVB+/jUPQWrl5wNKYv1EnHjhSMBn2C9Qf/jKNQ6Ew/hwC9FiFpEmSuEp291bDZHHshN8+a0K44Z61YfKoIeGGS6aE0TI0tEsmim+XtwSGgf7o9XOUzh0RhTf7pIpoeZqFtnTsl4njvWHr7gNhetuIMH3MaOF3rbIr0SgMTpw+6/Y1SGbpw+7xTkRHCouyCqFe5UdQxmYXASR+ejG4f3PaklB+OP2OwlTJv0k6ldY48+8PICl32uW0YFTHqKRSJgr4PAWFS9KyqZbAjMY0JX/jIJ1LtbRx5vzAPQB3nu5gjmu8mpaN8AhplkGFeETrlHBQGoFmYf/OdQpuGT25GbqGvYIWOOIGgOWaH/7whxtUvfbaa8PcuXMVTo+/GQ3ItjY7huCWW27RhoJVQMBYWnrkK4DswafqEPPn1CqcpclbV3mIR/FK0oBXTquUSi8/yPJfqx7OrQiVZTQ5XaJJOKM/1r+zxrSEh1buLsROGjkkMMHLG8GcccO1t3/zo5tlzH9lGDl0kCwN7ZRe/+DwewtPCPMmtYr+mQPC2/LWJP+83BYfFH707Lrwo2VWgT2zkye2hl8/Z04YO2qE0Jt1wHnMJkztjhg+cuLEheqQtMzuxDUtmdq6/+S0faLX6IxfnS75SEboyZ/iC/6YhhykMJQaIQF6fqqsESW9Ja36Kq/rjzBKdrh0sh9W9JSJShDkKFYRJteUtRwKPJEiuGUN4DITX0GYRSxPAJ5LhtQocghd4Q3bs99x088Iq57+ro7/j5x2TsHERPC2pd8NI8fOCiPaphTwPHIs8s/l1fGuLSCr5bxf3DXRawmzcfEjYfHtf6UVzh9o9HfH4zB6ix4M5s7OoYkHiPM51uV5uhlNXpWq/DnfkcRN+yR1c8e+8Nn7XgxnT24JE6Xnv2hNR9i571BgDoAGgECv/7H1u8MtsgP4jKlt4QPnzYpDP6ZpbgGdQC8Us9L+mzj++1/aGN532tjwjlNseIlG5mtPbgkHwtDwu5fMDyOGWZ8CWT4og5hD2qCYHHQH7zQ4Zqe1K/S4ZodbDx+dDqnLjmnHN/ALXcyvJDfSqT55/pl+0HO3na/QVSKuM/wWr1z1pngZ7d4oSPMyWuPl1+iIeTzVxByX8EoqPy7T01yrMEvnFMRznaq4lK7KSpgsJkTN80g06567J2xb/VgYOfXsMGTEeEXsXve4jP/vCXMv+GAYNmJsIs5ih5ObkR530dZRw8Nf/9mvHXd6daXQEb8BdCXw1Yf7Q25X9KE6UWHtatVAVwdJIwBVeuDTo2dwk+F8XraES5zgnNu4gHiM/FNwaIIcfWyiPHhzxo0MD63ZFWa3DdMlnz9duSv8fz9dF948pzVMkX0AjP/f8/LOMLWtJXzwvJnirMsTv64XumoDKQ6TgPZbZdjn359dH649a3zh/MHxhsGO4g/9aHX4xcpN4Q0nTRVqs3WSJz1tsTXr+C0kDD12svH22DDQyz4AaQQa3gzENePc/U2gqx5/9Y2hoCM/5Y9LSEmjLxmLftBp+fVXEv6EQBA9tJevwGU0eqdFfnrmkGccSDPZVZhBVQdoJB+TAAfBuSwVVbVE6Rc6AtzGpcniJ+ELUJeRcp7NyMiD4FItlX6nnXpZaB0/O2xe+YvQsXlZGNoyRtKzwpRTLgtDhtrqtERdx14NC/TDBoAH0iugm9TT/sgCFyqpqPbwSlxQ8BHc4Tu1y1Ok/KSqYRRWwR1reFLOn2Kem9EmfOLtaQxedTbKMEhXAC3ZuEuXgLIKiPDb50wIN0lv/yfLd4a9BzvDqRNHhctOmhSuPG1KUW7orHxJXnI+pi9pThEleM9fE/GHOYWF00eGZ9ZtC790kr3WIzMfbtE0jQBWUbHJiogxBwyVh9hoSPJww0GFcxeRxdlA8IkwTVfgmknWCJCj5uuZCz1ljopGLMAIk6jZTCKRrpSWctLIpOcoe85UqkuHn+C0poA+i2RnSDVXro1xlJ+6Mt71igIqlzJtBSnJrvAs22TlDs5bh29c/UYRBaR10imBPwtIrsPxZIF+1wDwTLob8cfNHGX5sfYqx83QOBUudkOtMiPHnnDjdGnQJ4l2M1MFN3kG9fqRcxqGX5dukESTKHoT+97SDeFNJ4zWJaA5H40AY/4/emlnuPykiWHWWFuBYWXyvNHFnBIQL536O9JSkC0yxNRdYMJ5pbxhuI80KWZl5yOP1Ch4ic1K6sRLeCSYMxJwzxsB4eFNw8oX77Ik/A3D8jHB7qTRr4BLXHx3pDcp4F1iHjWbue3SVWmLRsDKwW/ZwikFzmUh3+NcCaZF4jeLAbdYTgd9wpNKaUsZpHxnEqYcM0kHD+wLa5b8KOzc9HyBHjxkeJh15rvDaOnh1+G1a4F+1wBwK7wCELcqZDCPO42nofc4uNdiWCmrgH7z9PL+Ccbnb/nFprCx42BokUbgrx9mAniwvgFcJo1BdwF75Hbk6GgCp4hykFw1PLxud5g8xt48zDHlFk2ScFapEUBKyqnaCOROGcrm+CQvx7tc3jjIDw3483R6U+g6f/J0OR5HhpXMypTKk6B5+Y0+/ZqcslRgSQuneOWv++S8Hl+bTw9/2IgxulnrxYe/qY3q+DPeF4aPO1FW92yTHb0PhRVP3C6NwLuyHv7R68xbxpZVvwh7d24INDIj2qb2+tiIo9di4EhorMn9oexS3zpTV1RK5NXLel1edb0qU2EVRtcPanpvFoucnlKg4Kz/ZFCDRU5NWH/O4Pw6ndE4vJzyHMGWMU5/+CuTvB5w1F9+cEM4fdKI8KXLJ+nST3DfWrwt3P70Ojn+eXg4Z5qtxEI/8sz1NH1ME+xxqqwU4iMybCD7zC9PLeQh8/vP7wgvb98Xrj5nssgRTrG9n8UDvizd7o02Ap6h5y7ZaY7Z8EzRCEQFcyd/SGDsByjPCUha8h/c6S7enL526SU/pZdcVI7y88YQhYumBV5A5TkLU1a/f4CleL4a5gS0sIKN/WvESsjfNJDiT0+k0jLbM+NNR9mGJo/7Yzo4nwpXecad0k5rCvBrnE7B1TQhhtNlZ+6WVY+RLML4WefJhO0BOcJhb5h80R8Vm7p2b1+hNIOHt4XVz3w/nHzRdXLiQ/MJ3UKYRlyLaJgyUhufFY9/KwySIaahrdNC556dYefmF8L2dU+HafPf1uWqoYqYOtkLC/TLBkArjFROawSwRlElo2k8zdWxXOMDGh2C1nHloMolvPNEYYIzzvRYp4rsNFz98SeeaEkREqTQwxAZJgLkYrISz7nTWsO9L+8qhoC+LitzJktPnXX/eeB7ADQUt/1iVfgfb89PXTWbQOt6WilIS/mlEXi/fDzmbx5+KfzJT9aGhTNGhtHDB8tS0716ztBvnnuCDC+NjLxme2sE0BGJfiUHk5mvs3e8lkhJqz17YVKkOGkRV+rJCxxn7Y1F4dylEWCBqb0BSGmgEzHVo6VtwlgzRTWhZxWQXKXM2qSqQRLedS3Gu0p4o/MnTGnpUEjm6alwLNdoX70WkpW2eH61obFnUMikTM5PygKyTZpDuKpicvXnN8cBNfyaJf8edsmBbX5mD1S71z0Rtr/wIyni4DBq5kJ1/vT8tzz9rXBw77YwfOyJoWX83LB3y4vhhUW3hWnzLg9jp51RzqAXKRohnH/LpPlhzClvLRoby/OfwrplPwxzLrimFxJr0p5YoN81AFQCrwhS7+wRp5ZJsEpiMa92VgXs16tYUcEMrM6PaI53KVy9OkZyQEJrcE0UGlmK3yptwhCLCkcg+jSGMs075k8Jn7vvRT3q4bqzJ4TFMvzDzt9mgaOh/+3F9rBSjoqeLU7bdIXS8yk7DMfvOXAgzGgbGZZv7Qj3r+zQg+amjxkZrr9kZjhZ9xKYjb30+iaAzKKH7ZJMK+ymbwIFODl9Uyqlcepohy30y2KSOHwjAL+9IViOsZGQ/LprBJIrbdQvt1ERz/Q3mAH8uVB7dNEIuCUSLRBzzUjRIBFbrW0Ql77+pUVh+6YXw56dG8MwWWEzevyMMOPUN8kkLfsxCu1izJ/eHB7CtnWLQ7uM7Y+efYk6/Y7Vi2SYZ44u3RwnvfotT3wjHBDHT9i27Lsqa/L5vyfLOtOztW3pnWHdc/eGUeNmdbm0UwV087Nl5SPa88+dP+TkM+HM3wgbHrpR5yDShHI3wmpUjy1Avep3wRxF+UF3WF5YYHmopnPc8R6fLZO7f7hwdlgkR0D89vdWhg7Z6EUPvVnwo6F3Z0NGzehy2EMrt4YbH3hJDvjaJx+XaQ2/NGtUGCJObX37Ht1LgMMx92Tuq6u0wXF39kceNAKefnnz9vDsuk1hxeZtEVbGGz2u3w+SS3iT4+nyFVwZ7+nqFT6Tbzq5HNfRy0faylwuk+MNh745naWNl7gHaHoTXnrq+2HjqsfD4DFzAmPzLbLZqn3rmvDcon/o9pC13bKKZ8VT/xqeuecv9W/dc/eLgkNCx9pf6GmdNDTty+8Nmx75qvbCh4ycGA7s2hz2blse9m17OYw77d0l54/OwBi2YbnnkYa90ogx7OPHRORyaASGjp4iQ0Trc3AdPwYW6HdvAG4Tq2LRpdMD5XVAqyK/3sczPH0ji+Vpj9P7cn6X7j3kjEZkpEpsffaUNvmei0vxK1ISrUPza/dYp2RM/3NXnBqe29wR/lnG+ZkE9iWhTsOV4x8I8yZxhIMFcrDSJPt4riu3d4T/+9iq0hJTuBhO+rTsM/iHx1fIZyXnqwST47YwiYedE5DSLxfH/50nXpDjJdJqo3Ejh4dfO//0MHVMmzpvHZaJuXS9T0DeEOR+2Vh+3EeQjddXx/h1uEhk6lWU16vyx+EfwWGRxn0MyVpquWK80O9mwtvTJsL1GbTnyZ8FoybFE5ugFk8yrAiWXvvSQ2HnttUyZHNNGCZOkzBChk44ZG3z47eGl5/6XjjpvF8TaRaMqzPs3LoqLH/8X2T45oQwbv67RJ/BYccLPw7D2qaHCWf9p8L5slt369P/JH/fCoNbWsO+7avC3s3Pq5P3/KLo4jJi4nyZuF1bpLuPWKlzmiFybtC+3V1/YtbLkvPU8aO3QPMu4tHLfVUleP+Kq/2JOlKpGUrVv1jRcrxVkkSfZGj1LvFTOKc3d2nFBWZ/9rh62rDgXH7j4+y0XI8mcKonDcF7z5ymRz3fu2JnSdzybfvC1+Vo6MvmjlcHkWtC3NN+hfle+aD8CWOGNTQmrP9njmH1jj3h+U07C3nGaxY0mVIqiVD6tdKYPLZqU1iybmvY1sER1J3hpU3bw9ceXBJOHjck3PTWmeFb7zlRryePHRr+74NPhu27d6vs/E0BuXo0tDjVhp69wCzf7E0h5k9+LgenztxGkY53SOEZnd018jN6T9vV87LylWHgDG933+xLnoQqLj0hYMtylZ4yyN/2TS/pSZtVZ+zHLe+SkzgZU/eALUivWvLj0DJxnh7RrMczyBzJof27Ss4fHuSMl2GXQ7Jjd7/0ukeOmSarfn4eOjOZLtuvnO5JIK8jCS2tk8P+nev1LaTKz9lB+3dtkCGmE6qoOn2UFuh3bwDmSO0x5Dc5VCoUVQ6g/EpNyvEWd2rvf+VyjD+xWy+fdJkaiFXfmFuhg0lrxBsk/aJFTpswPY/RCODkb5Hzf1ils3DGqLB8237t/bMhjM1gyTrNckvlZQ8An45sFnxJ6BrZKHaKzANYcFtzJcjZQ/sPhH+SNwU2i+Xh9XOnhMXSGJw/bVS4QU4n9YDcj10yWb9ZfNfiF8J7L5AJxmY9c8b4pSebJoYlLS4dR8lGv4Y3Abkbevs1ozTG33xOIL4RuFJSDhoLVh/ZTS0iRkGmBHvI5FI8cQLkaUj24G2gOjHsd92eG6NHnD+pzr1n56Yw/sTLQTUElmkSWM6Zr9Hf075RT9+ceMHvFzz72tfq20CzYRdgQ0dNCft3yLe7z7xSPuJyf2jf+GzYs2mZvm0UQiTCGwPDQ5Nmn2dF8GqUEzXEy0/52Glnhm1rn5E3mNtkzP99xTATzn+7zDGMGDNDVwNteOGecHD/Xl0RNH7m68Koeh9Cg2V7A+h3DQCFz5+/WCVj1bMqVK6Yid5pXUae7o1Rq7Sc08MJmhy+xqTr4QL0tz2+Nrwsk63s4J0tB71dcsJ42cg14XCsJfxvnDU9nDt9TPj5yu3h8Q37dKz+mvNmhEtmpwm8EoMkmBhmCImvi50qh7yxcQx7bpSTP7sLLCvFXl6t83sA360Pvyg9/t3h0780tTiymqGoG+X7BHtkLuLK85uX7Uo50ppGLDWm0QlHZfJ7affLnC5xHc4RzlIjoGmGd5K2LjvnR7yn1eln+eXpqsdL+rjbhsKtYTGTawLdXlF8QUnaNXScX4e2tElveW2DIwbvJ20OH1neE9K+ZbmM+Awvhnmg5bhm14x0YzDsyifvDHt3bQqDh7fKQW7fkTH/q4q8fWUQ66bGygFwRxrYXTzjtLfJJyR/qBO+w2TMn0DPv6V1qua/b+/OMErmOoYJnAZn5RPfCtOE52hWH2kmA/inHzYAVr3c1VsF86pkOKphPq5vLiOntDjuzDnz6qgw6V36q7xz0sPzAM0mcfrffGy1ONRdCmaCjUagRc7gnzN+VHj7/MlFg+BO4icvbA53PLM+TJdv9f6mjLFzhs/TG/aEb8mYPmf+/4FM9PYmzJdxfoaFmCRO2pUlqD2kpLc/tVY/J8mXxDhQ7vvLNoYJI4eF82aMCQ+8vCVcd/ah0vp/pPB2QZilG8XcXmZRd30Pr9wcXti8M3zpsunFwXTw8InKa884GP768S0kmwY/0lrtI0bFqXPv3Ambkxeg4OLIit4zhUd6mxOwMX2DCz/DHyoNVmM2fnPheu8FrAtHNb+4hJT8hb6rOQFYfM5D2SO9xe1JsTcBgWiGUjJ5LlSHeIcsVVAJtIwfM36m9Iaf1DH/au+9Y/VDcuZOWxgum7jQlLBx5WNhExO0vPpkYagc0LZz+/3aaFSHk3Ds9P6Htc0I+zo26kQzbxftL90btj4ja/Vlkxb7AA7u3hxaRk8KM86SyWFx4gS1QZZPT6NsPpt74TW6KsknfFvk+8EbnrtbTxUdK5PNeXnZjLZOGgyOle7qZNGe5j1Q6YZ8RkJ/KvzOjevCmmd8QwuPolU9q2BeUk9FvFwcYhSeyvnBNE/7m7/joaIH/dm7nxNn3xnedlJbeEnG3mfIIW2XyTk9J8vpnGt37g3fWbIpcIibHc8wKNwjY+13LF4f5smHXf788hn6OceZwnPetJHqLL/x9GahH6bO3PS0XxqGlfIR+P2yGH7sCGvTeYv4q0Urw62Prwn3v7w1fE+cOR+KP2NKaxgmDVA18C3hn63YGj66cFK4/vxJ4a2i89vlxM/nt+wJj67dGUYMHRIelA/JzGwdpo0S/D94YUf4lnxT4IpTpoSzp4+Nlm60+E9f2hTGDjsU3jO/cbPQSeNb5Atl2+3Y6rF2ammuGw3Mpt2d4eKTZiYwBs7umCaBxNtTpCNH07QQW6Ob7rXxZ+nI74JdjoGFLubnaSfXq8onlohccoOFVFBeIuPz/JzPr23SAGxY8agOx+CE6Znv27E6tMu6/T2bng1zz7oy+BsAu3uXy6TwkBY5jZN9EYf2qzMlB5z+Plnds3vD4jB8zMwwROQQeIvYuvgOkTs6HJD4mJOu0J73oMFDw4iJp2jvn8bjgPTOhwwZGk6++Lel0UkLCooHQaX15MdLarQtoybI0M4J+ndw7y45UfQXYeLr/nPJ+UM5fMwsKe9SmZvYE1onzu1JRn1OM1w6W++87PQ+z+dYZdDv3gDo5Fjvvmoi71cBt56YXUnKAyi9MSqYYbzPxdUqpsONmwcWSAzwSzrWY2K6CmfUsEEyjj0lfOb+deF0OTXzhovTpqz3CQff6aXXzZg84btLNuiGpv8s6/irgSOdf1Wc8gMrthVDOHwC8uu/WC1n++t2JWXhuwDvXjAl/N2jq/UDMHz1a5Qc/9AhNH8n+X3qx8+Fz77lVH0r8DxoLH7w7EY96TP/cDyTvNdfMEnH4Rnfh+5P/6O8FO9t86aEt582VUR1hs279odFq7aG52RCeLy8OcwaNzq8ce4kGeKR4yPkTaarMK5liOrGrmWfU4CWCet75ZvFC+dOL+5MYXcxeRpDz4d7sp6+yCjeBOR2+Sqi4io3TIeHSqeO2puB8kmu9qYhzJX8rCwRXzwOTm/YtA+CNM8WT4aH7tIm0J5IK7FnwZWe9mkX/kZYvuQn2ht3icOk53/yue+REzetseQJXbX0LhFwKEw85/3aYOx44d91Z++ISafp7t2RU84M25//Udj06P+RpZbcR/lS1671OjcwevbrZSXQP+rxD4qIPzQc/LE8k7eBZsH1bYbrDaxj2wppvMY0OH+XwYa0nq8+cq766hboulY6xWvwaq7ZHsH0IObpFKd4Rm8FdXquHsDnaYd3d31BnOCV0oN+ZtMePYuH4xiqgYPaFsk4+M/Fqc+Wo5wZ7yf4VRtX4AAAQABJREFU+f1Vehzyqu02nITz/9/Sw6dRYDkmOBwmZ/N/9eFVOoT03988oyQCB/vH8l3g25+WY51lLsCDf02sq5M+eWt5YtO+8NE3nCT57w6rZNUPQ0MTRsm3B+QNZpM0DD9atj48unp7aJW9B2fLd4Y37Nodfrh+R3hqLWUbFZ5as9WzK13Zlbxt70GRJx+tkR3Gl504Wvcv7JJvGfzghfYwZ0JbuHzebHWexuh3KDl9d5HefJeHh5JTNqfufH4F38zpd43Pnxhz0ukJIu35V/W1RsCfJXuqck7HuIG8pH7N4S0yxj/vdVfr6p6OHRulxz82Dvsk7Vj50yGTv0NGTVJnPXrWRXrdtuzOwIYvD4OGDJPOi5zwOWmegobKprDB4nT3yoQv4UDH5mK5qQLiDz3vvg7DRo6Tncc2zNgsr4N7t4dhceipGb6GdW+BftkAaEXT8U6rOoOkp+d9eczRtO8Ve/GKb0pvnDk/0gnF+0IcY+VNYPPu/drrfWnrPv1WLw66WThT3gyejXMEY8R57hDH19WBazhLn5Sl54/zpxHxQMPBskw2gv2GNArVgA7Av/aEOOOsAeiQ4arDBYa0KC+T2Bz5QMDxf+VnL8rchCwBlUJzGinDRx4oB/sEhspZC7tkYxofpM/xlIevlI2TxuSP3nh6uP/F9WHJ5vawtn2nfGpypJwtdFI4b/Zku3fZ/TFHKa5TFFKnrjimdaONRRc/i6hoFOQNr+G4CFFU+YXeP09paYGLeN4U7B7HRoLVRgIrnx0EHVTmysFXGwV9NSzG3/3pc5545aERESYlSTCspctYyUiohw4dHtomzMp4gYewTvYKrF/+kMobNjxNCLNfYNqkG/RAN3b47lx+XxjauT/s6diin3CkkeCLXbwFsPmKsf5tS+6QIaZVYawc0ZCHPXLG/0jZ/Wt6oWkWJGlzKq51hmuIUuoKf6RhdzGB8X50ywPzFEwGj517SQ6u472wQL9rAKgq9jjZVW0hlc8aAVIJC60Hr5aaLuitOvJwQmmNCBQ2WJRjvREAS12fKUMxTN4y9LFJHGFXgY+0zJJv6p4qk7UMwzBJ/P3ndpQcO7w4Uz7mcvnJE3W8n2EfjnSoBt4CCAz7NAtMquZDRtDYBG4oPiFZ5Vu8ea8M6QwP/+sBnH2HoieMGCZfHDsgcw5D1LbsE8idO0QM53xYGgSGjd42b2q4T74mtvxuO0eIHj67lnft7wy/f8mpWu5fmT9D747dQ7t/RcONN2nWCEg+fpZP3vPmfnMj0lMgTpxGAHoRVQwDkZa/hrSwk2X+hBRvCgJsaARifiJKgz8xnj5cIyBZCQm/EqScmo5PnD9tdkUne9qMOKYlfxo9+HD+G1c9Gcac/Cthz+ZndZyfcf18opfhm0Gy1JOloGNPOC+Mm7YgrH3+vrB7/VOhZcIpslfgmmLYhaWfrP4ZLD3ttjmXarbty3+qQ0onnvveqIZpHBNHfcHuSOSrYRNPvDhskYYKG/J1MSaC0WmHDF1xYun4WecfdX4DVUC/awC4ke7YSxVFniYqmOH8YeVKsGpu9DEdGwFSVq2gMjpL+yMKheESXQgLZ08MP1y2Nvz+uRNlCeVBXX+fj6/Dg7NeIs71/BMm6cTuBHHOE8Whck7PJuF5xyltYZI40ZeF7m+e2BzGyATvO2X9PpO+BD/SQRPxhy90ERjzbxaWy6mdNDJ5YIXQOXKY3M1ydPRnfnlaaRz+9qXb9LC3zs7derKozyn8jcwnqHsVO41p4YMwNo+RyyXu+oyXoaI/fuP88EP5pvDPVu8WHYaE06aOC28Vp8+XybgTIqqwsMnJbSzxwkEa1qjtHlojUHHm4jB8jN851NmLqIZGQGD5GwI549OV3h8T0e6wjQBPS1EOpBTMJpC0gtLTSdIo4xNGOfW/pXmuiNkVVIkaUsOKwvt375Ce/8Pq/Okx0+Pf8PAt4sDv1CMbvBHwQ9ZoKCfPfp1sLntBNn4d0PH2cQuuKpy/iFYZOH7mD/ZufVHeDjapbWYseGux1wAdGgJqSojFsUSXv1aKZuhJc9+g4M3i8HH6HkbLhPT0BW/zZH09Agv0ywbABgPskfSqkldEr05UquT0sV6eTpyxeql54zMdK12yeP74Er9Uvrz1vAxn/KV8ketE6R3zZS6GX95+sr2OPyzf7GW8/hSZAL54NrtyO+UzjbNk/H6F0i/ZtLs4soFcWP3zsTeepBn6R10Wy/xCtVGBYJq8dTDhy5h/PvTEkAurai6QZZ13v7glrNxmjnjS6OHhmvNmhv/5s+UyDr8mnDl5pE4gP7Npr35Gcrh410tmlYd39h08JKubxoR/kOOl54wdpieMqnJd/LAUlb0CvyWnhvqd4WrOzJnc1aU0tk/3zq0P3qTkeMeq0xYKu7rTBmt//qZQpnN6u5IDwZ+l1Jy6vDgclOmX8rM3DZPgWjXqa8+V52t4ezaNkzJ62rnBVCU6NddtG5/XJD1+eunDZffsuHnvDNue/Ved6B0mK2cILPGkJz337HfppPLuHbKiR1b9jJp+bsn5K7H80JjQAIwcMTqMnHJKaJt8SjHn4DR9eaURGD/7grBXNrgdkl3H7Bzu6pvCfalHf5Pd7xoAryhU3FTlgYqLlYvBpGLRvVMn4k7fq5XRUPVsyAFW4290OpYHWJdFzBuV/+fCuXKMwqbwlOx+7dgvRzA8uVX/oCFcJBuy3nvmdI1T0efJSptPvOkUWUG0NmzYTS+/U4eSrpRVNvnZ/ewvWDB5lDYgVSfP5qp1Mqw0XJZ6/snda8JvLBivzpyPwvzj4q1hj4zFP7hquxzktl0c93A5ZiGEh1Ztk4norTIxPFP3LKzcvjc8J28dZ0wdG94gbyV//8Ra2QOQ5hpQGHkcN01gqOcRydcnoxUYf/zcIT4okyxOyZJrsxg3xyjS6p4yh4kUmHYpHQfU4spOUkSVnLsgGOPnPuGa1akLS97jV3qB6TXyI4omwL4voGJVhjUKES5523CQUZscyy81GoYrflGUh1GDPS12BLXB1B5ZGQv7aDnRI7cdpUeGfLVt7ZKw5sVFssFrtI7x0wjsfPk+Pc556iX/Vcf7O2TJp8yqhqlzLg5T5qYx9SHDWmSx0OHngtiFO3zU+C6cfypTLJwXsYdvASWuWFqzOxhWPx2PO3+91OiYx0kf76HfNQBUB68wXFPg1qS0jpcWHsNdiNMkCcovY7Jp+AhIBa+SrSKTQ459k7wJ8DZA4DhlVtEwBs+4O716Qso1aC/59xeeGKGKLn6+v2yDbs5yAMMef/Bvq8IlM0eFfeLNmE94bste2TU8Lvy6nAXEh1+YeCUME2J67Qz/sA+B5an+dsD8wpd+viHcJpvWPnXpyVG8ORU+NTlJGgGnjUh9SyGvSSOHyL4Cm+Rlx+6Hzp9Y0OL8v/LwJlkKOlFXC5njcvtwTXfIbabypVypEfAczbKWkrg4SHxkcrL0zGPPO5JWGwF3ugVc6ODvbjjIc2f6AZ+t9ALM3wx8+MlpmzcCUSkn6mkjAL3k6/aRqDzF/qwhE1xn2N2+Kbwsy0JHzbgwjD01DYtwiicHu3G+v5/XM1xW1oyZNFelGP+gMEo2YYHfJ8suGR5i7uDQ/j26W3iEnB/kR0LvlB3Fu7a+rL3vE897b9EQlEtnWqpyvfqBj2Dlsvjx9+taHn+a9V6jfrcRbMfG9WH100+YJYrnyCJFMj5gVCR92CKiSBd2tMbEhTm/TjAqp/Ebn1VM/7VrlG+5yGqYwbp0clpbi46Ba96iQ+IvMi6kO+Sri1aER9dsD791xrjw/jPGh9fLkAyfd1wqTnj59v1h5Y79Ou4fV5LqSZ9vnDMhXCm7jdlpumLbnvDmOW1hZfv+8PlLpxdOGvk493NlsxlvCMwHTGtlR6dptUcaq5/KRjI2hQ0XR++BTWf/vGy7fnPgX59vD287uTU8JZPeDAmxtPUO2dzFx+jnT2kLv37WDC17sgZSTH6SmGCahyLcMgpRHo8ZjeBLAjL6CHc0V+6b0+dwUaURHgm6p0v5uVzXT/my/Azu0iIVTAXIIkVSSaL8AmjpnNLjLy+7N3QOkwnRM3xS1vIYymTv4GFymuezxQdf9u/eGjaveDiMkkPe2DCGDDZf7ZBvC+xtXxN2yRLR/bs26gar3RufCR1rHgl7Ni6VD8CcFKYsvF4nkzs2PCW7kZeESSekCVjkmD6WdykliEa80zW7Jkkp1ozulYH11Om/1jaC0Vnpd4HeGX/0mrhx9Nosbo8SMMdR+K7S4AhOy9XS/JrslDY5zdLA8kB+nJ7Z0/DT5VsC6/4/I+fosFaf5Z5MrrIE9L2yu3b4kKCnZ972zhP0KpuHw19Lg8HyTv7+/blN4R0nt4U98gbQJktN6al/5v71Mhy1RSeieQNgpdKUUUOkoZAxoSywSY23Bj4lmQd8Fz3/W5/aGk4ZPzz863PtQcTLuUXDw7qd+8OWPQfD6+X8oj+4SD4uIuP/1VCt1KQd5nG3cJ62uN0Jp6fn73cbWHdp9HD8sblW5dmT0VN9Unn86UKeO0ueFI+bXAXoT6JHBt8CYHNXs6Anf0YE8YnnXqsffVm59Mcl8snRmbN6aOrF/0Xppr3hBh3/7zwg80VT7KwfJpbHnfaecHDfrrDu+Z+WZNSJ15YFjngIaMeOHeETn/hEuPnmmw9b4jvuuCP85Cc/Ubr3vOc94Yorrijx3HXXXeHb3/52QObVV18doDnaoNXD6o/27mgErLLZFXcNjVZU3u8ZT1AKh3oaqA9WGMyGZxvxRgd9A4dK4FTNv398pUwO2yoeynjqxNHht2Tyd5JMkJILAT0JaML6++/I2UAXTB/ZdIMY4+70xPkmL2Px/LEXgA1f/yBj989skDPWRSC98o3i5Bn3nj2mU4dwnt64RzdbWW72e9fzm2Uj1tB48JwMDYjzvlb0+ytpUHxl0lJZufSP0iDQ+PDRGWQTdomu2/YeCK8/cUJ4y6mTZdjHzoZRS4nRdIe20FG+ZH1PI0Hvmv5iQeuWG5+mI2fOoVzSGvk6ftLgce56aidy5P5qWjA4V+Z/nJ50GtYxfJEWRRUvIkp0wAVW0GX5aT48T1oKuRBifsKCNopxfUBrOUtzApQAysxS9tAJzJ6S9IzFZw3SLkKzDVt8eUu/siXfCGgdP0vzW/fCAzqEVF1vzwqgg3u2y36A78imsC2yFPSNujKI7Dq2rmzI1bQGTBkIMkQY6TihVItiiNfEr5fiNaFsL5U8ogYAR/35z38+4LgPFz73uc8FGoCPfOQjYfXq1eH666/XRsMbAXDQgCd89rOfDatWrSrSh5PfiLfef6pAQiF3sDqGb5XLuYVAKi31loruzsmw3P5U3QoYxDzJGhrxDokEehrof7/v2YbjGf5JHOmX7n0ufOYtpxXHM1j+xvkNGZdHoznSs24WWEo6auggnVzmAzC8GbAyiGWZP3ppR5g+epjOEdy/apecSzQofFaGf2gkPLAqiF48p3SyrPReGbZh7mCXrPF/px7xEHQC+qOvnyNzBKv0zQHb/qqsAKLxIeQ7iGl42qURKDdo8W5Ee9n4vtuZq7kMbGbB70C0r4C7nhMwXnPqOOV0T8xpS1pJUiOgeTRrBIROnbqwJOcuzwRwgTU0ApIXB8pZY+Dy5fsCSu/pWCTJTycRYhKlum4EIBL6oixmo/I+AeuoGM2g0DZuRuiQjVlV540k1swTWsbN0Ss/7AMgsKKGwK7h/bLjtm1y128Ru9c/KcNDD8oy0HV6OBznEB3YX35jVGHZDx+aX//cvRkkhElzLgmT5c/vVAlZJMBiAwtlazi0vh6tBZIn6KGkhx56SJ0/TvpwAZrbbrut5PDHjBmj/N4AuPO/7rrrVJzjr7322kC8t4HHxhwKnP4QyVUcdrkR4PHKXa2kpRfG0BF11ULGD1zpwdjjyHnzUPjbQ0wJLOL1alrw1azJMsRSPZ4BZ43T/OZjK8PvLpyDNOFKkp5ct0OdOkdKVIM775lycujZU0bqgXMcn4BMlp4yZL91j2xCk+t6mSBmDX/u/JGH86bh+L4c7MZZRbqSR3r1tz61SVYatYYWmWdYvWOvzjf8/sITZCL7UPiLny1vugkNeWxO+9aS7URj6Sm/OSu1FXBpCLwRUEK1YrKuW8BdnFpQypB4CknC7vdIYkIj/w1kgpOTBSEEVadrPfYmzl3EHrYRkNyKfQEi3iaG47ESkl9+Cqmqow+WCHb1lT9OXEPQBK98kaGwh3ah/RmBQlaLzb0wPPPw7XquT75jF+ffLpuoWk/8ZRMVf5noJQyRnb5Iyj8gE0maXjgKmkll/YTkvvYwetLJym/PfGLB3GufvSdsX79E9yQwbERAny2yMolPQM48810K6/rHDaV3tWuyPsJ47n0k/rgQ2+sG4NZbb9UhnAULFmhvvrtSLF26VNHu7EksXLgw3HTTTdrLb29vDzt37iwNCUHL0NKSJUvCRRdd1J34LnF24/yhIUXcruZmPO2Y3qajo4ka5A9KnitoTzPsgwNuFvzM+yqOQ9UIF8gELb107+EDIw7s2rPGl3rgwL/80EZpDPbKR2BGyxvA0HC7nNjJBGizPQPIYjno3S+36xfENsgSU1/x878eeDkcKIYmoAzyfYE2vY6SRqJZYOdzdadxM7pmML8Lfs1pzI7elDgmv7cOK3PjmHKn313aeviJ3vJMzbGnXV6V/nBp07BRv9yV+xPppUlPEJDG8nujMLptUpi74PLw8rP/IRO2S+RjLhPCoX079Rwfds/6Dl6XS6MweIgsRmibHDgxdKWsIKIB2rdteelNwelZRcT5QKwI4pOSO168W1CyiWxO8zrKB2m2rn5c3xTc+SOLN5Shcr4/H5vfKR+jrz/y7hZ+da69bgBuueUW1ZQ3gcMFnPiMGenQMejdqTMc5GHWLNucQtp7/YsWLSpona4nV1yC9UbcOcBlcT933V6lrTqDTY0CKUmL01MZkaQBHyuiyYXeKKwHhwSrlkghMPZP6O54BvCM9zNh6prPGmu7a3HQnPvDkQpvl8lcvu7FTlzO3smHX5DBENB1Z9uXwG6Qj6kwYcwk709X7tLNWu7cofWwRiZtt+/lXB7p9ctR1C/LiiLCQbHDO+UN4YPSyBBY1snZPdiRTWhT5JA4hqDYdXyi6IjsRbLBjWMw8uAuzy2u5YtvAU7nNjZad2tmweLdSxyU0om9uXLn/N76vTB5DneKSC9gnDRvErkT11M7Y0PHACJckpW92Nk7oYoFpu8Fyp+9ISBX1MnfGJRUJcGT8iOlwov8FCA/lCcGMop4gyAtlVetE98CgPvTtm9PuwzpyLMm6/n3bvUD1GQeSRqElvFz1YGjy65VD+qqIFYHPffo7TL0sysMliGhUdPPl30D98sqn+nFGD/54/wZ/uHj8wSGj/ZtXxEmzj5fGpApCnMNNSE/O8S5c4pn7vwdx25kjrBeI5PQhw58V46SHhPa5E1ikpz9798UcNr86jbNLJWjj4M4GrqWx4E6PVCh1w1AD2SWSGbOnFlK5wneAJqF005rPg7ZjLYZTOuO1dYM7RVIQBrN0gJyB+QVzR2NpkVWwpvIcjpWQa/UQp+qpa3th6urr2o5fMTQoVrvbahKtuBLY4Az/ZYsqfzTX56q5wox+cowD+Hd85oPkbE5jMDOXwI7kGkA7pWzhKoNBg78ATnnv3qQmw8vvSiTyx54g7heVv19+cGN4auPbQ5/Jx9y2ePrToVo3oSW8KwsS2WoqOoQ3K7Icpw1xALQBtTuAfh0N6wy5c2AchdDSMkVuBOM7CqTPFN19FxVvOK9EdAco9M1eu63OHXJR5266GfOPQ7XRFHW44/DRwLzRgA0f/zoVdVs3ggoHlqlTOWxRgK4wUrlUyiNVKSXy4a1z4bVLz0chstSzf3tq+UM/zdrb5vPNXK4G0dBeBg0ZIQ6/EnnfDBslGMihoyYGCbHT0Xu3fqSHvE8VE4Q5XsAh2Slz4EOOfpBNpf55yb3y1JRzt+fdko+rIQuqTTk5fMMni9X9OGzj53SUPFWwtvAAfkW8HYZFuqQj8+fcK58DrLhdM+ybHKJJc9Fv4rxcrlfRUV6nTXPcJ+Grpw8mba12XBCVQEfOqrCe5bG+cpfdCoaJ60PZ8Q5Xp4iJvecBvkWt2uRjjSWdppMlsoHG2H6dBKH1ugvmD1BllJuL5wy1AScNHA2S3lw3Um//7zZYYn0tjlVk+Oi+ePLWny1iwPVmoWOCPfevu/Y5eMtfMTFA3l/9mfrw3lTRzQc5EZDwSqfZZW5BxoB9h9Ip1/H+9Hla1fO1uGtjTJ8BM6/b0C18KphV7dIgqsu4sicznVzerOoWdZw8U5G5+d8Zu3iDhTOEScf74rmUcRjno7XqwjTD78Lj8Fx7sIvtKV0hCHL4JYHrwzQ5nDnt3yjPPhVRsrP8ZTH//xJS1fHxfycVvJc/uzPZMfvhWGfnNXTduKbislgjnvgG7tTLpJFFnLsc9vcy8Qxjw0tMoyDg2b3b9vcS9W0jM/zha9WccwjJi+QbDv1ygfiBw0eErYv+66+DdAgTJLzg5Keym5lknIRhki+fOS9GjjL55AsKZ0iy0wZDmJimuvki/4o7JehqI0vPVBlqdN9aIE+fQNgnoDx/jwwLERgqIfVRASuPvSjAPmB90gD1YNK44G0tXQ5BhpzGNa7sxQVsUqV0v4moKyai8WsiqbfRvy7z5gV/ud9S/TM+7PF4eLU1+6UCVoJI2QVz/xJbaqxaWX8/OqQkFREzsz/h2e2hhnyRS6GdU6f1KJDMtUePTwMw9BAQEdgXoDAUJIfRzGzbWhY3W75c85Ps8BQE0tMGULKJ4/HjxgcZsrbSn4UNQ0Dbx7X/2h1YPcwm7+ONJTvnjk9l2V3ld9kKe6Zpy1mVCan0vNWPsMj056N2NOXtE3kVtNxYreCd3533jxjzfnjmwMMkj+NQmq687SXyfW3kplcg6GvU6E96b27beiHIR1Cs5VAOPuRkxbIKp6H9atgNArsEiYMij1uhobYSdxWmTBWInkG+fgLjcSEmefI0tHZCm72w5wCu41pDP0QOqdjKGnc/Hc1nDdEQzXm5LeGbdLITDv1Mievr31sAfOLfZSJD+W40ycb4q2trergmQ8gni8n9bjz9lY1qon9SeXhLUD+CFRM+7NKT8XxPxgcx7XgjzTwe68cHk0XdC4vXankjAYZrcljOOe/vmlBGDZsaLhblloyXMKkMH9niuP8Pw8vD4tWbo15k6Hx8RUuJnDZvctuXI5fJrzvtHEyDr9Xx+19qAc4PXzdoXuafX4R3N/KfAFLEzl59NK5E8IbThyvq4LGSCNB8DcFTTT58TcKUMhbIw3X5XMb396Q83aZq1gtH4yh9NWA5dx6OU5h2nNOeKc1eoNjEbOKWth62wWf303LV/nByR8h76mbbMNZjz/KE/neY3d6u9JTtyejSKOLyC7D4Rc64FFXTSMXXSKM/B2vMAFwJ3K8wckD7ZGX8ECM1q6kCQdlVc6QlsbPbhqWIZmxOvTCWD4Ngi8L7ZQloATG9Ye32dlUzuNXH/6ZOvfiMGPepQJOK4dw+LtkP8Fm+e7wsgf+Njz/878NK5+6U3r6++Rzk0+HTY9/XXcXM/FMGCx6NAsOb74iqfw8qVmaCXlFYWhxfGhypMU+5m8AH/3oR8O5554bWNbJ5O5VV10VPv7xj4cvfvGLug+A/QO+5BOlibOyiLkC3gJuvPFG5cknhntbOKqaOaB4c+TZoVIa3KXxQKWbVz0bqMSvlMIfGxNjy/mRTJV0WEyTBCa1mJxWb+8Ia8U5cl7OpTKB6oHeMzttv/306nDyxFY9IwjWp9fuiM406Pg9H4/5Nxn/p0dO755v7N757HZdvcMbwYsyns9hbzNkWSgTs+z0pbEZKutBf/PsGbKsc7SeyUO+bzt1ku4uvnPxOn1jQIdq8KWn/iaB82cSmMaE84e6CnwxzIIaINomUWMLuxtmf6gMZjQ53nA5NTSetqvO1sq94Q74PQVTHLAmArl3ON285633BnGCZyLf0zhbNpH5mL6mhQhn37juX+iEtuk+AVHH3y71Ch35oSbycn2y/MCW8PL8MPFelEew/sRBOXJkqwy52NseX8hiiWez8Xd67yPkE5Du+Het/YWqwgdf5Msv8jdIzvyRjwU1Cb5sdLR8oGXtc/eFrWsX24RzE1qGohjf52Mt7cvv1TH+nfKBGcpE8AZHE9nPIdlsRmicA3AiNZwkTI5DX53r8aDD0Zf8iBsAnPWFF154WA0+9alP6UavD3zgA0qLw/dNXwCIMwREI8GVZaDwHGmgYvBnATdA70rSRKQRsIcnXaGlghNAgynYLZUBFCtEIs+zgF5DXiUNYk2COCbkys/zm3cGPpySO//IrOvvfyDfAYBm9/6RgX0D9KShHyfn7bPk8xz51OJsOefhyw9ukDeHKXK2T2v4ofCcISt3GN7BifN93Z+t3hXueqk9tMtcADuNf+eC2TqUlKvMpxwvP2mifOd3v36MntVDuV4MGzHhzFfK+CaAfsBFhpZ2ygdcDoq32yj7CkbHISYvA1caCQ66I69oLUU3TxtF4br1/gifOnP47U66Ze2q4lS6w/VmCK/xea5mfXPeQi4KdNcIuJO3XOPtFR6Fi0jH67p/vgwmsAbnXtBF+gb+BDfjNGkERFUaEwsZvmgEYiOiBFjVwglzzw8vPfdzdfwMo9DLZ1jFA1/U4iPuIyafLkM/5pj3S49/2KjJeiwEDQfnBe1a+WAYOe08/V6w83LtWPu4yBseVovzZ6x+zClvC+0r7pc3Cvko0Km/qqt9mOBlxRDHRpM3jQBvDhsf+eswdtJJYfq8y8Lyx27XfQnNVgftFB1bdV8Bd6G7ANY6VVB1T9udnBonHV8GK/pPWP7M0+Gef/x7qbC4B/ujdFQV3gK8eciv4BM9hNDBk/MnGPRSHwtZPIKJHmw1DX1n+KsH5ECu4QdLH4eH2sN/++n6cMLEseGZdXJccxA6OdLBx95ZrfPf7l+nZ/kcEA+xWxwxPfOt8uGY9fJGwPJQHDi7eR+RL219TT4gM1M+3fjRN8x18apjkcgi/++PZXPO7gPa2MwVmRwZwfASYb58qexQfERw7FfKB2k4FmKw6HeVrEJi0tdXHdFosFSVVUAcX50eLKzTWFFzfIoLnfbGE71Z062qolQ2cOfTuPCV0gXeVvEg12XZgE66w47zIcASXvg8XeCjLN4IyFPhSpelJX/FC0HiN3xX+UFHByPRm+1cvpXPyklZlF5tOyi8sOyBsGbl02GwTNiyamfU9NepsfZte0mHd0a1Tgp7pZd9QI4mZ1iRsfj8nCCOj978+K3yMtASJp13nTYmOHWGbviGcNvEOWHX9rU6YYujb5eVO5PP/72Gtw0aGxoBJp55E+EtYI/Qz3v978jGsGVhzbK7BD5eGog3yZLTqTpZTB6H9m4LJ134gTBMhrH8PtrdbvZrdgFzeNpm/IeHdS835Z9LapWO1Vf/7OocdFzHj/gN4HgtFTeNPyoGt8j/VN/ijkoEDx4D1SnRS7WSCqiMGd4dByA4rd3UmFYme9eIaaFIaeitdzp9zMiweUfzpa/IXS6bt5ZuXq9HNvzVr84qjc3j7P9MvtZ1wz1SAeV4h9Ey7kCP7MSJQ8PcSUE+F7m9WB6KrDfJWL8d5YBOBNPI4qXihU9eekrgyInHZchphewBoGxtLUPD78qbwzxpAPLA4XKtcvrcY7In4M9/vlFRHDFxshwIR6NxsXzjwL9dkPgwfGOPLdcMrN8eHa6Te2DWjPZTfqPgXhhvnpZ4FIhzzaRpyXkL5C0MDvC4YY1LWp2o4ACknn42XCRyyz1+4Rd6G/bh8AnTx84ekmEilY9c5ElanrXEzzCSCETXJvmRv7Bn9JBFfQVOPO+zKX0UdvL814eJU+aELZtlPH7d82Hf+sd0lU/rmMlh3oXv1ZU5Sx6TsflDh2S56Mkl5y/Z6imfY6VnzxsE5wR54FOQc866Mqx+9qeyo/hN2rtnAnn42BMbnD88TELTADAENHLauDB05ER5a9geFt/zFy5SVxttkR3FNEQEvi0882xx/j4/wM3pNkBgvPwelrxbWQMX2e8aAJ4EKriOu8QHxG5vemA0DZ2QWQXiUariJV1qJPKHzKo8HCZL0kJbpCWWXJDL7ZTx/THhZ/JdXHrKDLnkgXX3rKk/SRz9BDljv9nELI3ARMG9bub48Pb50yTPlOP7z51l3xoQB80XwzjEjeAU5qI8ZXCrPrJBTWjpta+UbxX8x/KtspP3YJgqR0JD7RxOyymjjPEzeU3PnyEfzg9i4hnHz5fFPDiPyeDXIPy6XGgtbTYjrZQ4a7lBTuv3x6TgvA0HPRzJ4rk0zwVu5xCYkrhkfwaEBqcu0sxZm9MlDWXzOQGkSu7y48NBklQGaxwSvMqvfCLY+RqPjXA9VKIJ1dxiFK1KL+9WnnHjp4ex42eEOadcpIak1JqXXBf/4ruhc8hI0U8+Czqp+V6bFo5sWCar9Oa9IxyUI6EZljn9kmt1XH75U98LbdJjJ3DAnE8MK6Dyw2S0zyfYkFCLnCB6lfb4+bZAh8jlmwOTZfPX+FnnxnF/ymCBqlcqniNKV0pGSM+Jpevfnlqg/zUA+sDz9LgJJF44SnMDOH0N8oRpz7947mAqEvoEUoGUXsFlvLsVkyWcOK2MP+GN73TpDb1+zmQdJmG37ukTR+hkLcs22dzFuvvlO9LGK1Oy/Evv24M2dJKwfOXj7jLk46GsiZkjd5lAChMJ0w/ix2aYc6Dxeap9t3585jJ5k/j1s6Yr7d0vblbn/6XL04Fy0PqhcN+XMrBqifmFPGA6y8tzbKywicbugFrM7xsttcow6/JrtvW7ZdwOF4MU987cH9zpbpDS26RyXScD8maQnHXseQuKZ0Dh4Dvtc5Bw8pfojU5AKr9pIwB9lqXmJ9JtIjk1Oi5D8y3o3Urxqh0UQZbwyik/cn8Fr+WXcu5q3xjat63RbwKwNJOhnWbBTw4dOnKCTN5uCCPl04v75DvDK5beJWUaohO6TCIPHT1VloQ+q+P8VTnIZk5huNBte/Z78hZyQDea+cS0r0Da/twP5bsEj+hxElYELwjls1vE1aHEX8lgWnSVP1o5xSup1bHNq981ANyW5ITt0SHtTp8KYcM95i7s9uY3Mn/crAIlejO+yTM6OC2/7tPuft515gn6UZivP7mquJNDpPbTo/bVQPet2Kk96+pbAKt/OPb5inldr8AphPYi8qR8a+D7yzY2nCvE0Q/s+p0o3wxmwpiP0V8ox1L7vESehR9LvUoOjqs2ADndsYibzZOk6t1rTPs9VXdoTjGy21PgeLuXRhWdvlZyw6sz1mcpDuMoLjltx8OPDp42J+9puyKRP54tHSaiESjSPKMW/FnztDkdOM0KXetvVjDKTjnvx86VwnlzFEOHjMk32y/Qse5x3RfAJC5r9ifPPD08/9gdsmN3mkz0TtX5AOYN+HZwx5qH5ViJh0pycP40MIOGjZIloM/IpPCTOhfhzj8WSy+tsy82GXJU9PH4qcdc1/4a55nrd8Eql1VDrYoCoKL5XxXPqyZ06a+cxkD0th1P2mVxLeRBo73KJvwZ3S+dNC188crzw8cvP1O+wDUq/Iqs5vFlmO+Q83t2yVJOlnAyvOKBOM54hkzEnjWtPEmW8iRf+8NBpLhJ8TTXvPfyz0+taXquEDrxVvJ92dhF4KyiyfJ5yK7CSNnQxofmm4XnpfHgLYM/P+QOF2VuyjlcwzLch7oSfSqB8xtO77YIk6sA/I4h3eNmlZiWN4ym+wCgFxy0OO8kO6YFANz+7Anwdf44c8cho3GfALAoJ5MPn9FbfpYvdBGuephOzfTx8hlfpbzCMHSYbRLDQXNa6EGZcGVjV/4mwJfAOAuI3j3HNbSMaA0H9sn9lMaA3cBj571dxvzHhk2PfFVXFLFpjOGdLU//ozQMP9U/Vvzs2/K8HiFxaMcKKZM0bMPKw53cD4I3CpxfRJlSsPsbDV/BJaoUa3weEq6OdWeBrmtzd1zHOc6qkA2C0MLxeLDOX71CV7o3xSunclDB3NHyRGpaH02nya7SCFCZXQ+ooxYxdzCyCkM+mHLC+NHySccdhVb0+v/kosl6oufijWtkpY8drPb0xt1hvND/1rknWHmEnxwIKj3m6YJMG6tWronjuDoep75ZVgBdekI6iiKnY66C8X0mf+nZP7zOPv6e0xCngdotDVd10pghISaYn93coauMoONtY558aez35NvH7HRutI5rZ7loCnvGxhVosn+Ke2kLiA6RCLHcW7O4yaX0Ka3CBORaeE9d0pInwecEzGoRj2yeGfDyp2P5AuIKG9JKcIF5WlBKkCaGrUPR3ZsAAp1e+as/mT6GQgP0s+votokyzj5cD4JjeSbLROmpr//Zl8XhT1GHDp9OMO/ZEqbOPivMOOmi8NQDt4XWWZfoxC94vibGcQ7wEqA/IMtJD7avlZMmRsj8w8ww/dQ3Cb09ty8+9s/6MRklrvz43oJhLbapEE0JZlXXXQCCwKYGV5ImP4neS96EqAZVLNDvGgAqNn8EYlohY9oqLE+TWyE9NArRCu14w/FLxbVASgLOQv9XXaul6YVBU20EKi5bRMjqmUljw8+WlyeGcbo3v3Vm+ItFG/W4h7Onjwu/Mn98WCjnCdnnFckHFawgrkXhIKW2gInaKp3F7de4DM8O5Z4GVvj85QPbwr0yRJXvGYCfz0xOkLcDJqDzwKQxjo0zg3xDGUtab5KTR/nO8X/Jlqk6n+luJXQYV+ypQWxrWEu7M7crFI6NT0J0jk5nD4BZzSQJi2ZazdnS4LpsBMhL/ptzt+EgNz7vBjwLReNQ0GkpNE/lK+BxOKjYZ5D4lQM9JJLmEKJ+UZx1cEwfQHl5h4nzny17BZY/d79gBsvY/Rt1XH7PxsWynPM/dBL2tNfJslBZKopiIkX/9ssJo62ylNMDQ0PjTnu3/nHWz6ZHvxpOPPMd+lUxeCygl/GPn356WL3kxzpMxNBTHlht1DJ6UhgRTxTNcQ1xEVnc/gakA1wDqxmecuyRXitWPlIxxyVfv2sAsLJVPLN32ekC47Eo31IqStnJ2wNsVcjkAbE/c76W4tfTyObBszkGbQSKnDw/w+cPJhPDp08dG74km7s4tfMCGXbh6AV62k/KR9bfMm9aeJus+DHpeilKsGjVVjlqem/YvGtvmDVuVLho1vjYQBhdT39x3Dj16sok+JmgBs9KIXr3HCWBs2cl05n/P3tvAnBZVZ2JbialKOahiilQoCAzppVCiUN4YtKJdhSM+pKIGrsTI8NrXysq4QXQtETUdOcJkkTTMpl0ayLoc8qAAslLFHBWZhmUQYpJoShmqF7f+va319rnnvvX/1OlVv2wq/579pq+tfbe6+x9hnvP2W6B/Sr5EdN5wH+d/OaDdmnfPoLtV2/6iZ1dPFI+kG4ag4+F4JjnbOtfacULbw7YfvypptB9oiVGUCNFJI6+ckDZECPCXIhr8LSmXJM8rWLSFwqnTY4xPjn5axv6WhTUNuKGnDiKO+yhj0giDiFIAjn9g8OsE71e2WmX/d3gphu+Ypd6LvY6PhYs3Kbs+e9ebc/vyb/doP3GJsMTQsd+uKUjeLxTYFrZavt9yr13XG8LxUftYXVLDWcvO9tY5j8sw/f+lzz7N6eZPsX/GfTAvFwAsJfgu9fYAfSnndT7FEf6OCqsJSbtyhiRY8dC4RmFVZIO7CnH7skdDosQjlgeeuTR8u1b7rCJ+kGbHDcsS7bezI76saMBD/qlvP6gPco/XX2LXff/kT+sDTwcmf/GvjuVF+2+qGpRF7IH7TLKmZdd7+8W3st+BQykv192b7n4ujvKmw5aYvcVFtgJiCLOLWcbFC2wUH7THtyGo3H8COzXnxGTMZ4r9EX7pTG+IqryGvtG0LPsTWFfvu5Oexfw3f5DMHz76D8dtOvEzV+8YH6Jfato7KYxFgF84wg6WACiN+iJNNusKUwxoGPb29iMqf7nViMAW+aAtzddIkHPQFeFNNTZZziT6idpiwaDaf9j8qW9044dhx1A98dG1G8LtTMBg/HLPI7PXPIYwDc45RbabhDu0uXAM+d+JmEMM2/6ruhtcSvXw7d/wFIbc3t32mW/smjHPe1bQXfZQ+Tus+/db1Y2t8s2KGwRtmGx7Y57l5uv/f/9pm8+gse9A1wK2nzb3cqGdnYBW0ZAe1Cid7XfENx507fs8RGXl7vtPgMuD+GREtsf8LLytI03b349iIrDWBRRRdLG2JLIpt9CKu+9ZM1SiuJn4WvNRi60ebcAYEg8fW2C9h3BWzqSEGkChwp2ltiFAcLdADseFgtOLhpo4uH6pz9mwti9nPSVy35cPvOta32twUR4i/1690tX31x22nLTsse2m5c9Fm1edrffBiDilz5rJ/vbsVx353I/it5pS36lE55qixCJp/X/ssdE/NgWlHxZBdfW8UKXD//bdeXEw/Z2DEwUKIyNtpmj1mAC/rU9t7PF547yuWuX+3sHbrdHPdxp9wbAP8C+358Lvu8//LEXfkPwuW/cbK+gfAThlgN32Lzc9/Bj2WyijvsduAfhBhal4mGbI161O/PRNszJKJRr2gJNDtrNUkcHEyNKHVvKyZO184w1dREw82mXg9ZfiW8HpW/zzPLZQR5TbQ+iaWcERmDSZzNiEZC+Fo3JnmIfIDf1juSY0tcruByE3wqUraBnLe76A+jqmZV2L+CAsvzHt7Qj+A0XbFUef+RBv5eAiX/XvV9aw2EP0pr+FRfatO0vPNv+ftF18aGRQR3eEEcuoEKH49nkJqzrcWONVYQYOGNas+P18czOZl3QmncLANOpDr0ltiehMsFTqhGWYZwq8iSeFwEkptPA8ckjJyJ3KT8qa26IB58/sQkak//BOy6wN3Rt7bmAVzPeZN/zv3vF/eXbDz1oR+w/Kvh18KsO3N0f24Ap8Bm2MPju4y6Jl5efa22B+K49KiJP/gDHZHq0XVZ52wW3louuv6P8Gn4ohris6Pvglay7Gnc7yNEjL7MXwD9vl63KV3/Ih4HtaiE/32h+pVNxQHuy4FLPOXajF0f0eBk9FqMv29kIbgpjcgE9/EoreHg66XN3wTXnviAexQqJJgiNHGTOqxO6JgPJYeN9mFoaKCaCnY89e9bVqxdNvjDFIgA/UeDBaNtMXQQsY/Q7AeaS0SPX9IcPkIMPhOX+zYXi8G11C8c6E/CYkr7TCMzi8/4xMKQtccCBRO2RXqW7/qBm6JfyzAN+rSy76TvlJ3YpZ8Wyb5eN7T7BNjs8q+yw28F+Y1kW6iv6USSQwh8K4wiaXHz6eDY98nsrb1U2CLjgplros7VJtMar4WuNQ/+UAefhAoCjJiQ20ywSS4OEHQQ7EgvkPLVmupEeyrmj4DPwYA8k+st48HTRtTfZpY8N2otWzrRHMl9sb+XS9/1hje/1v/8rt5e//tq15ZgX7WdH7b4UQeQlIo5d5tZ7H7Dr/Ou3G6rSxRaT7P72wLh/uOZ2m0zWs6N3/moz68xUx2SPhQCFvTGTNmX4ls/ffvdH/srK/H4A/C7gjy6+reBMAvcM8ARULQKY/PGVVtxbGJ5JrNrj7DQUP/pQBTz1qXhBsxY0NERhqyIUTa6TtCZpTr7IpcGZQcs55Y5ycGYaETB3qU9acUR88i999QWsOTmrXWrhkBaW5MXOBA4si+yPBXuByXK3hMlTtXWoBzRvrUMhzxyqJ6apINHxh8UAiUqaWyCArz/XazrcXdyuYkAfR4PAJl949AE5fsovn6DvuHeFHw2jjm+94Fr60TYJ6vv+4OPa+LtftL09wvnR8o2b7mwx8njIFIBpfyiKnwQimV4W2wPh/tnOAv7K3jHgmmhbxYFVWAOb7RqihQ4kioG2Wfal6+4q29lClyd/WGCyf9chi+wNZo+Xq+01kcd96Uc+6WPiP+rvby632cKAewt6ZEWOCvbDkqNkNIzc+cbIEUoOTNnFFsjGdxvIK20b6IDmX9Wx04tGVzynna/v88sWurATX1ubpNfQ+wQwucM/txU/+VMbXI4YPU7Fxy1aTD3GO3sadiiMwfvQGaRdZB/ARvF+8prsKlHtRWmrmERrS5+ggBvZF/6lOdz2+kPpXOncnrnarq36824BQEcrrbmtaWW5kOnQY7pC5pO4TZSa5LUIiPZFAJNyTfG8BV5nnw6P8HgHHN3nyR/6KJgol9qva6+/615PbWFqN/IUxuRd4999m8380gq+hTMsOLK+wvgvtDd84bcE37Vv2OAPGCiK3+ug6x99qR8gLfZjrRX+3X/ZTu7C1MNzgfat7yAmJz6xwG1rf/h20tJf2Ko8tHID/8NZBh5Ah5vVKGM7ePACr484+IycOLRj1KjzTzR7VzqcQMBD4VajKzunu0k0MHxybZMvfElm28YfLAKNnyZxx5fe5KTeJnvoVV3EJ75i7Ogsd5s+PrSY8XKLTuhoKKQ+AQW5eLEt/njo++yFMCvsXgH7ErpRaEde8NFXvZ4spC8a27ADFVk5KQNnWOhryH2idB+LUPqYxF3bt/PuElBOUSZKGi4TQu6rnrNBJblJMdnb/lLZlR6OYpIjtbDjwQCJK/vNNllQrrAfP6HgWfoL7Vey08om9kjlB/31kDn1mxMzq/i2qOy4+SZlX/slMF7M8g57fIS+W4/JH5da8Cti/JoYCwu+IXSN3TPgL4djJ8BCgIlERZ4eMIy//ubN9qKY+GHazvZS+tf94s51ss5t4LVmHMHrpfbCy9v7DXMHw8BvCGYqQB5GJG/iB82Ig7bet/boLId8Xu6Az0ma9k0DCr6wRx/BTpYeWdXJUVJuWCbTPQHkgt+4reZ+GchUfGuKfjmo3RMQ37aGMdOzg2hf9T0WOpjmD1IE1uQ1fmzGbgyjXbpXhL5gO/steocc1h61bwLdeOWXyz12b0Bl/Q2eVnbe80Vlq+33rtpCar1dMWCBcUCUOe+dZR8cI1HYwjcKrZLcBEhn8qkz9tnbj2k8+XjzbgHAEEYiRLr6pG8ScHySti0TQonELVIxTwM9LWSlEjA46edFAPYv3GPX8jeXfMe/mYMfTd1hz+0fvlsXsaJcZs/vf+bibQyJMdFL3i0YBXTh+TXPXlLOvuw6/x49Xi25oc0eeJQ0zjJOfsHidq19U3uZy4/te/izKfg2zvsusm8sWe/gPsWu9oIZvPQFL5J/38XXleNf/IzuYXPCxG8DPn/VstG24VlCuBG8ky0AP4+CvtKIwf80mqPJ3tcYhCWljJ9Sjjk5GTUm+VgEkAuahEOOewLg82xzUk770J+kEQn+iJP9xaKCCLP/oKctAsRE+9AufLIAJfcS9a7+xqfLI/ZuAfyqGL8TwO8C8CyhH155gb1z4KGyXfrWj5Ce2q5dPcB5ce2KaTWjscS1zEXK6g+A2FH0h8T2yyFNJ/Shk+WNbrohz3is0w/sF22+WXnZAc8ql9z6oP3q9a6yqU3OuOGLI/Vc8NXN+2ySfP7ueOImsbXzgc51tWeBvZD9Dw7Zsxxkj2+4/scPlV3t2zev3nvL8oGX2GOA7fv1Krff/5idMdhvApxR467C3H6wPmeT+IP2GOgPGgYuVeHyDX4YhnsUz91+QcEvevvCCeFQe0jc1nbzGNf2ca9DBZP/6V+70384pks9ks11m6dg2MZURCTJ/fJIPbORTvQodIc9HFjT7wnEKOiSEZAwaQObf4ZjflEnP+Q44odM+k3e9PnsoA1gC73uXgHshvbINPPV7OE3+6Nswp9szA79gB0fOoon2mJyA4y2EL+Tm+2t119iD5hb7o+G0I/E8GwfPGZiU3up/G03XFIeszME9rltrAiDdWfVD/rIHI0f7IeFMnDZFpd7zB76UL3SgRP2U1RnwR7HSPHMAmNtUJl3ZwAcAhseVOoosZoY3vNG+6lu6PUDMpSHPWuWtLKHoe9YOS1Wlj0Wb1ve9IKF5Ts331buvO/+cuOdP/EboEt33MSP0vELWkz+/36fJWXLBRtbyPKBHQK7C2gUUcI3vvl++T4723uD7ajL3v/7MnthfC54v8AP7cmhrz5wC2cTicdxwvWQTQpv37PLPnihu76pk7GAjTd93Zke9cxI+Plme6bPuXbpCC+rwQPhcNSPgl8N4w1isy2pdWYCDHFYIyrRIFE72D+0gBSTo1/momrV1DEsmLBkn1KFfc2Xk5gX61tpJFS3c31zDnxMnljOEQumZeaATawGAbqTm5h8TLxApT7ahAMW4IDvxUS6hST+8JHTbmd6TZ7iEYb8CbTFYyuZ9x1AWjEw47I1JjUdf36Wt069EXI8WnrjRQe0B7o1GKtgEcBD5R6wR1BvttXO7muyt+EJPukVnz3NSCiXX1f3D0VLTpUTzocBnMkiLj2JmtSbHae6816bncXapzXvFgB0se9cXlHiGqHRAr8VyrGjQC7ttiNWTsgJE1DVEHip2uCNubndC3jhnkvc/UOPPmKLwbLyg7vs/at2zX93WyCet9uO/pA3+MbEgx+PXXzNDwu+7omCR0X8H3vsVHa0p4bGksDdaWM7E3j1gUvKOV+7zl7j+FhZar85WGjX5C+xxzd8zY7AX2G/JIYdQlOvsE571tmmu+1S0W72Vq+xokdE5Gf9w1b9gK+PvvWXdrf7DffZqyUf8W/24CueT/TIH7iKmfHQk/zluCH3vrNoslyLAOTkc3THabamacCgLQKwiAIRJl0HrZMurJEzvgggclPi5MtFoMnBNzl+J4CCT8iGkztk4GGBJm7dur3ZGN/tTI+Tuv34zGSjL5UBFpS9RDwkzQhISf6gPfv/rjt/6Jd2Ntzo6WWrbXe1p4LW36ZYw5CDKLjEs+GUp3y6gn08eB8WgJ2qVT/B0zOxAnVIEyl0UYsiilb4rBzboO/ID/2oUbe3D+mTqTaPFwANctutbVyZEkhF7oJIGRzFMQXxKXpSTl0kTVtgPFPoh0lD/JaIVU5/K8vT7ZG8S3fbyf/gh3+KqpQvXn59ueTGZf6d+t/ZZzu/XHShvW3r9H+5vLzuuXvYYrCF2YQ+6vvaAvGfX7RXueCaH5VPXMmbtzvYI6P/4PnPsF8b97/gZYzjn7hO/z179tDYN5VwOQeFPwobtwd3+CTQ6Zo/H8mw7xDFcMRiNFkbozlxc9nBKGIcUThZh5dpNC7raPTzmQL1iQM8ID1mnzpyp1/G3I78XT7+OwNgIDLhgiYq4wWV47/tR9eWa6/+qqnYr4XtkdCP2DN7fnDd18ruex5StrMfflGfCBvbc4MesIfBjRU9Iwg/GHuqrN09MO8WAO5Y6HTslkxv30HtaM33qCrhpE9Wk5sMOxaOHlclb2Cmz93M8LVf4fBDzrxW8ezQzReZEfkN9jVQTP74wVR+0ibquE/wd9+6rhz3kmfXxydrUaPDHTdfaM8TeoZ7xKTB3bpF1fqBUxYjYySu7PL9bHHBL4gP3XXT7j4C7ll88sp7yjPt8c241p9b1ppLGPukd3XEpLwprrICJNlHS2jWy9SeiExyjCOKLgep12BBbXlgroBPW+sdXPD36zCUSULb2nuG75MycqtGi5pHBN/2n5NvyJ1u2JDXG8KmMvYtoA0gd3x6QMTDMwYuIqaHbxdBXs9MtEjAnGcksEYs+GPx+C2eO2//Qbn6Crzz94V+CUdyvND9+1de5O8GiGcGrVd2sMdFX/nNz9oLX77dvVvYXwhjT/nEQ+Q233pnh8GvwblMwj+9D/OPchfbh/RFy4b2OX5ooDWUJHkwA6SrQZf9sErVzm6SWF37ScSfHWfeLQDoOqQPU4IDzO60Aa87EsTarSnTZ00K30SCNPuaMJ5tg0k8/FU/A3nnr8Onn2/ffLs/SiFP/ooKj5K4+Ic32cjUz7AAAEAASURBVG8FlvslIUTf4aHF1rY2wdsOrcmO6KLZH+RJm2h4dAR+M3DSv9zmiwDuU9xo9xA+9/3lfibyzhfvZuHInj2s+ICHQmmuUUJ/rrLGPuBLfuWxb1HIdTlI8bFv0CeMmXZ5Cqr9hYkaWrVvoUHU3J8mdzZl+GSxmueAJl/KIZtcBHjg4ZdxIDdITd48ICEP8Ta+wfV6OFOoZwImy4sAfCJG6Tvd2kLqmmsuKQsWH9BN/pDgej4e+3ztlReX5x7yW8ZhO7AYLN55v7LMJnu8IH6jzXbwZwQ9YN8Csje+l91/8ZWmWXsW+VgXAWCiHepB0ETkpA8acnyyv0VTjxIiuFr9IIY4lPvwGcvXcYm6LT0BubfvlGZFrK79rJz8FJTm8QKgxMq9xoRcHwsBRqymIjUGSeXkgNdDGcZQLtq27kM0DbVDuHMXhfwn9lhnPEdnrODG7C9s/rRy6z0ryt7b2xO8agEeCqdj7jDOwc5WF4Gq6inO1qtfYsJjFOuVd7x4z/LFq28rX7npbn9HMR45gd8QvGq/HQaPmc67rzywN0F51zpbNXmmrrikpn9KT63MyLDq5ZlWi4jtlI0VzgRkh4g0wUiL/Qgc2lPHpDBriwC1qSWL0NHlGmq5odtj8oU2MGMSr3KT+aJgRlwcYrIGjYLQx84QdE+B9qtaBOrlJDTPC/0/+ujD5SF7ZeTWz9KjHiTnFq+OvPvb53o71DeYVZfs+QJ7qNzO5dabvl1W3HVVwYtdttxq+7KL8fHET/Yi8wKTMRYBFGUesdgvjKSX0zL0GY2H4f3ImrjTt/Q9XV4j9GGGVuuemUzmiWxeLwBMLQ0oUgwpwx0QSQgOd0nKxvRpHXIH8Y/gYcfWjhr6kUZZTn8ACHtQW2yycbn8zntQHS14iNwL91zoskDWrkQT8IEquTxAKtmwDjoXnAn8ut4/UI9gs3w+13PfoZ2i2Y/swejHMRr9XCfZ1lFCISPLNWlrxERrEaHfGGPKB4uF+6tH/uaiXQ6yjBziMYLJ+DQRt5CnVB579CF/cQz1Gd1W2y0p+EO70CP4417llUqJH7ynamtHDzyhBeCSSy4pl112Wdlpp53KS17ykrL55v1XENW0m2++udx6660iu+1ee+3ldvfee2+56qqrOhmIpUuXTvBmw8BRnh9o6PzPUxPJGbuu75JQMh0/xU4y3p6rOy0Ou1C6I/3AcTOITc4dz7Xto+pgY2UoJ7oJhW/6u26zRfnst2/379Ln7/LD/pNX/MTfD7DYrvVjR2NraoyJjlbmGqKBFbZsj6QWGeDtU71DuunX+Nq1dNceWomuQtukHkoWtTNG5WE7VmPskAiDcUo35OQM6aZXF7R8T0AWtIl+Yp/wIMH7ox1G9hL1nmsavuNYv2kSF77nkIWPSRlakvsk3bCBxowEi+HqbpQZGs/1K04+k1jf8rnRQ/xEezwGLn3QeDw0Hu38sF3KwUvjh+XBO64qT3v6pq6HvkD8nhN1OJz2sUHr0T5yhNNoiv1MgFlMjdyj2V6jzR6DVhRAAZeFwBW+ciETx2pWrScg1Wa46fWH0tnQ8BYeZ2Px89eZ8wLwzne+s1xwwQXl4IMPLp/61KfKWWedVc4999zRReD8888vp59++mgrzznnHMe48sory+tf//oJnauvvnqCN1sG0s9HG6NupSVgA6gpy5WCXN/bNHyDZHBywKuo2CGRccNJ3plKh4E84gnM/XdaXK657S67Br/M3gy2Rdlnm439+/14I9cXrltuvxXYlb8VqAuXdho1qaetfTYJ4aUwKLGzec9YuOTIe6ZDn7qgfcL0riGe7JTubA80o4SOeOpb0Nx1M0das9tOog/tcn/ADyOnFsZKiwA5MSI9rTgrmueTIaFvay8SOWjUmH4xyVevxk9RpEUiLwLsE4yPTfam75O6mWGrMvWxEVXP8Uy5v6cwiGewCDxj9wPL1df8S9lo0x26t389eOfV5f5bLyu77/E8iwnxszc9Z7w9RltOKocYozQH/ScEN6EF9ANV1sGTHBz2CmXgIxIU2OfCCMGRhJrT9MOW+rG/hGS+1ua0AODI/9Of/rT/7b333gVH7694xSvK2WefXY499tiJPgJvyH/d617niwUWEJRLL720HHTQQeXjH//4hP0TYWAINYwtMTXyLhEBLdWrkRK6OU46XmWi4+gNtkjzduRvrPFFAGDmJ8nplRjNlVVe9Zx9yj9f8wN7MctNjb3xhhuU1z73WWXvxXinAP2jXTikgX+gOL5/ksKuAt321qw68SixaRf2VdvxgMbIenS6ZOSMQ15hAV19gmZhNFlPEnqUHFwhS2O4pcWQG/SYnFF5T9QeSfrWJ1gEUPhZ+7bR6ge2Vr3luu5MvegQbgUETb4ABb6O9Knlhqkaci0Crm+dTZwqNzPeQ2BMvigYb/yeAPnyhC1i4Q3g8OdBYBGwmIGzZJe9yv0PLC83Xf5J+wroorKhvb/30ftus6+C3l523HmfsvMu+6YxJjqnZDPGwtgWASBzZDVls2ejv5zvJtSLvgUurUOb4yNEyJXHqKNkXXKyDTiwNmzC+zpMPGkPt61lQ8G8o+e0AGCyxqUbTP4ouPRzxBFHFBzpDyf6sZ467bTTCo74L7zwwiYGLbzGXM0Khk9JyFrQgFZiInFCLqc1WWoSkwst1TTpUw8YbREwlclkRPrbDujmkepEk39Q9PGiPXctL37WrmXZPcv9xutWdm8AhSjUGloBn6XfNXJLogVtd5CRx5flTfAkq6APoi/V17FVd7Cv2LvqY/Vq0NCOqU+2QzSMpRaJmPSH1/SRYyyT+swtXxRMBVvEhz/iWaWWwA88aMr/Ps86qCzebpey7I4fluXLl5VtttqmbPusf1e2sreHjT9AbrLVffsl51ZxDPtZ/Ke2P/semNMCgDOAzTbrf1yEa/XTLvPk5uB+AM4UTjjhhO5y0S232CNk7QjiyCOPLKhjMTj++OPLzjvzO8QZYy51TpK0wE/a4/WQSHnumJByh6lpiw3KtDOBKteRPhcQTrq+CEyxb4tEsld8cc+Brv3T4l28xWY1zj5eDw/x4+gVe5KVaA8cxCJDvnFMFy0O/SZJ9kTip2s7Emj1loXF0p19NFjTY0BAz4VRZQ7q/TQwrtPb1OZW9EmLXp5tqTuUYxxRdDmotdNbTkpRsk1EcEk96kU7hpr0bNjQQbR+pkFflFW+bTAp5zMFn6TNTtfo26RtsfKInxlDvTrJGzT1uFXX5kVBvIZncUHuJfnbZuvFZeuttzcp2sXnZ+HbO+Ovl6Q59LwvaxOdRrtrCTr1HwIiae2XBm10GKM8otR7cgJRPjQKorGt8DUSYFcOXBsZEWarqPf2wZ9PtTktAGi4Lt3MtRNwloDFA2cMueAGMPhvfOMbnY2zBNwTwKWmaTeXs/1knYk7TAhfBHIC2PAjsZgGeSuWEia20McOhImQk4dSBFFgh6LcM8syTPqQQhO7LnakafYtQWFAJVTsLyb1jvaJxcVAdX9Geelp7kLc0QzBggHi9+3HZ9ffdZ/rP3ObTcsz7I89IX/C6tEQUnt0sKmoh6gNWruwOJM6QuYWCNTBNvcq6OmFdkMLtiGsSEeUE3KMlXWK+GottiyskZ9GI03w7H0hwCrVvZpoB010letIvE3u5j4mccstLAJA7vg26Zt9vhwEOPAQftjD0P6sDC8Hgf14WgSaoo+kCU02fRGgoxjzmWn0qLJLWYJu1CJgYvNKLdRZZBUUtDhi3kwXaLwgyYURgQMcFOPgfyXFpUyf9Fm1m6Wk82U75wUA1/2fSMHN4rHLRJjo8W0iTfY4o8A9gfPOO68tCnPxh2FTAmiH9dF2EI14TQDTlC59xKD7iHuGIH1UOMk7J6lKCs95EdCZAnZoJp++4yFSIMOtG5hJ5dcQ2J6Ip7WPM7rlNHcdtRc0CtuIT3IetJe1n/O175frbPLfZsEG/uyef7Tv/+9oj5D43YN290c+hLYiD3Rgomt0ViVJREaf8g99FEbDetZVvNKQXq9DO3yCLx1yQfXaQx3SsuLUIQoYGKuxRcBl7o2tEQ77smaPM9kLqEYRZZ6qDrTakXduSZVPLAIGFpM7DjAsTtPlJG5byO0vLwLw7wsF9FA399iivfjzXxI7v+JZ3fWwCCA+zztjWnyKB4sA8lH+IK2Natt2UIAAEafZT/ZalrD/EJP/bqX61ejU3q295FqmGV7ZGtD04kKX07dobBmROBULTCuey6wOPqGHUhVJzKvPOS0AuDyDa/a5LF++PJOjdXxr6L777ps4+ofy8Po/FgIsALPBHXVmTA2bUiPTTD8kPAeVu62QlCZ5wJFMRAKX+pIrgUVT3haBqg9attgqsa2a8BjlUB7xUnsY72xoWOZIMfk/bM9xzy+W1/uJz7rs+vJfXryXx8t2w/qpgh7g2MRWvQI+epijSTlp8ClFjWOZJlXncfrSooBxwpiiaLLlJBzf64fcJ33TmbZ1gIFcvCGeYqU/xMd7ENRnvIgIsWELe9Lkkcveifin9wo1Fc1kf0oy1BP/qe2a6wGM+awLjtSH3+vHfQFM2DMV6egoX7pYTHDtf3hWAf7wXoNsZrNVsmLixZ9oJjDSyvjGnCZv+nYkg6NC6Mu2wzMZfnKPA5eh3LElN4Sh3GnJR+yljy0awFi5bfFVXNt4nOI7PWi3eJffdo8f+R9rzxzKvzfA8//f8fxF9jTPh/19wsBSu2kbbRCNuPDHPvKqWFCxuvrNye6D+B3LCPa1uBVeZLeF5qpKj5bR6X0o90NBOxwUdo4edZReJtpsTEB9aBFD9vQDHf5BA5Oo/iBHHXJc5mn6VQfYmJSRzdxKjxjw09uTBk/vGfCt9Nyf4dm7B/T+AcVKHPlDLCkexWfxdPqGl/WMaHLwUaQ/Iw07+1P/KYNoHxiisWVhjKKwlZ+eB74K43LK4xV/bDuJP6a1LvLmtADg+v0999zjl2fQWEzUuLafr+ufeeaZ5aKLLur6Anpj9w6woFxxxRXllFNOafrvfe97vZ4xm3AWFQwrJiSmrlJItLYAsrpP3uJhm/U12dZJvpMNdYGVbQdyj2cGucci+XALLMvQEXxMCZBxayqpPWgh+4Apr/642R4ngcdK5MkfuihYBJbYy2VuqY+iZn8Ihzr49Hh8izqLFoFKNj5p9odk2gpfdGxjNwVvmh60QlORBIpqoUMO6dCXHFuv10k47KnL3lZPegbVEYCm8c3YJ3k3ZC9lG+xsoIeTPHXqIjAij0mZvp2WHiZl+AatrcefaPAn9Hp/sG32rp8XAWUa/Xi8aGv1p/gzbcIq5xZd0sndFrxern70rctCDgwU4HBLeycSHmnqSVc82cmG2WWUx5vxsgXqaPtM8qH+ukHPaQHAEfypp55aMEk/97nPLa985SvL4Ycf3i0A+KbPxRdf3LUevxoeO6IH3hlnnFFwhgA8/OFyEX4TMDxb6ABXQXiaeo7klMPwcRiVxo32iZOyPtVjEeCi0tsDp9M3n9ST36SvydkXgxE50nome6SfMKAL2v46/96+iIHtUwygaDP20hdIURbaayRRiO9Vq6PAJ/gs8i8+uFqAqkqnLz3ZS8ftMtHqjJUxkyn/Yxi9RgNpFaDlQnS0gmhZ7vW6CIgvPWDIVngaDfV0vwjQB3FikpUObUOnTcI+YadJ2uL0M4Fpk3vjMyO4yIQ/xwUm3jjm2PQpf4xnqG/+6xvK+jhrvNYo2akP1Deg0VG5nbnv1B/KNNevfes8V+CIByb7njiUyZ5jEfqk+Snsnpcp2FmhI9+QMfwcxx9qrUv0nO4BoGGHHXZY+frXv+5H//nmrRo9PPoHf6Zf9eLMAL8L0GWf1f36J/xxODGaSFTRkHCMMze0IKUEu1DNBdvyeieksoZWniahHyspb0BlOtKWkYU9MMf0wUdhdKHP+MbbB10USlnn9eTM2XGLheXL1946+g5fPPr5hp88Un7xF+ItYkIl3lOfuQc4OsERzT5Dr3PqmU4z4/IExbGOG8WZRk4xN2e6BxDX8KmPRQR22kqOLQ8gsAggWvyFXtbP8v6ehXLUTGtha0kwtyd7QbrDbCWtfgytp2o/rR6IeWqOHnDzdnWO0ofugLcmJn8mJFOOR6TwBJp/2IGY7Ez+TOcj2DH9JjcA2OmPO074gAPiiscdXZhDOSLs9M1euthKTn8mG5xFaKIJG+kIR9v17GmiW5Yd7D3BeIdvfj8x6md95+6ywl7n+KLdF3sfqd+Ej23wgMm/kHuoHh9rlW5Eb9/YVgHW9MI+yPKsPynNmlGn96BVY0aodeQ6ph0p476A8GM0qatehUXGcL4ZUR9SYkzQfkSeZToCx+Rr/CTXkTr5VW46PR9H+MTr7Qd6FlGcIfCdxDPqt7YIJ/x7m5JcbcxbdGA+U0CPhBwUYx72Jy+p9fLQBQb/Mg/akzT9URafYU+bJvH2NGqkonhHROsYa85nAGt7+zQpxbGvjSb2Y/vg1xahgaHXVi0SbVubYJGwk8MsHUOw6zVDPEzQWlEh9+9WCx7+q9xRBnLEl+2NNHzscIi1xl/rzsD1It4xMxLI3kLXdDkBWK0JjQiA9KoDdy8f/9o19n7iW8p+9uJ3lBvshe54P/Gbn7enP3gOPOqjBivhox4eISPqQF77EHIU6rBOmojBoQ5otjhLhlyghb4T3cfQWyes8Q95HB9w2b6Iw5ri94fDgroRp2jGBUvn+PgYzxdsjpF6IrzJobzKC3Kpngm4KNFQMWzJZ/pKqB/Rm71vkXNmxTMCs/cct4gsxO7IH/rG684c0BYothL+nTUiZ1tp4K03f15so4wlo/ZXG/noT1joK6LIGBT1HTBQ8CkL0PSi/hbNUaGcdqij0B61Gh84+F9JcaERZRI/ZOtObd4tAOh6JgYHSMngI+oJzMGFXj9l0dL1kAgTiwCQYMEdA9rcIQIPnvMk7ouA2fiPcmjgO5oSGfaubxAoQA97i99i0A4sudrmcXbtye11OPvAbmGadQbTlLu9XQY69kX7l2/cdKf9EIy/6zhw5y3KC+zIf4G9U5iwxAMSUeCRgU7ugNXPUA6/VnwebCgeufPZFtCIMgp7OujJGnB7m0mdmVHGEYTJlgZl7fMJjl76XlB71CtqD7PLdd1Zomuw3YhVnb5daZKtck36isRpk61yETADHpDYVzztncSY3OEfUU++YczwDHN0EVC/e+ek+BCQD7QJ1HE1H8RoGYWZ1f9HRrHXaKjel773rGHjx2LupmYMokfJelkuv8CjpqvXVqNDo3j3NhLaxqkqNdwmjUofT/DXndo8XQAwABzSfmDF1QAxNSI5qI2Ewo7Vo4CCBEdLTFHUuQtBhkK8mMQpH9eHdcjbmYP5CHv5w6IT+uRG1EBhyZKsX8Xuj7vF0zfasBxiE/4v2Z/alXcToQsZCOCJznXInowFfaF+Qvun0ewz9tiw34KrHuxRMKKjk77Uk7w7Yjf5OA28ye/5xxlATJeMO/wTTznOAMbim+wVBctFkrjgDelJS/UXtk+VNd8DmnfWPPLPFZFTGZKTiYNt/IEpGbYoQxqTcLvm3+TECH3eB8CBiezdzhSw1V/Iq77HQhv6oT4xGA9x4A/OeSaQ5ar7tvmv+gkfcocwDGA5XieHVDLohk9Isr7ohgmGlUwP9V3uTMZBfXxGkX1w5DdzhnXGGkvSUL5qWgjSDFqtCHTvlVBQr6q3RujA8B4yW2AAQj1GWnoms0NNXiuX7uCae5JjUZA9MOOaPvkuN/1xPhYHZSczTXo5QxlPlVd/9Dv0B7wUT2ureGoPt+iB3E6na9/k/mE/5f6BHbSBG8XHxkjwenvp9PrgykYa5MkeFP263ECzP+d1H5P4nXgtJubhGQCHlscpGEQNHQYphj2u4XN0IMnDCBqpjxUSEzgSlljcDvWrErQ7PSNYCCLCtopLLJyK0x842b8nPBYB7NC1DZDneMI/rNVW6RAPC5oXTCSOI3mmoQs9649RfXkdRwA+UdlDoB3NmLiWy4K+Jr8yWsSisYWOiixF91vG2/OeOEW0iFDo7HOLC+1Ae5qL4ZGsaLWTfcH2m6Evxso2eUvZ6Szy5QLamGRxpF6Hx3PTaVcK+cSRv0GNXc7RA+fkA82CV7wylWcEq/BneeT+faDCP8MxJOR8K0AO2jPO9ymylYFUr/3VenjQnxZo/+wgxE0d2MsTtij0Sg9B04a0NEGFvSydI1CqjHwSv0caUVvLWPNuAcBgYyj4ibRAUXopATlMvghAXCcmJpEz8OFJhQT3CRGmnrDKBE2Aacg94Y0e6AHLS5M3hlV6e190KgvxaBHyNtQds4Zrth5UbDt8tVm+6Ml7oLYlTTmOETRxW+9hIbA2eT+4ZvQw0Xta/Tih784NyhvAyRH26gGigK6KBPdPRpQYE1WhQDBpP6GeGLAcWpAnLlsSlMWONlQGPfcTEITqMdWaRnVIOUDkLUYALCzA6suNt9m+rL+JPaxvfR1rI2j2FHAYSk+Ljy18YBFAIR+60hcPUp4DBLZkCEh1bjVSgKUPV2n4QHMZ8sfr2oY++fhUG2iTadRDL+QO7hLxKtH0aZdtpTHcKv4hP9Pov+UrHik/uutBe5RKLL2hw54Ieu2vzbsFQF2OoUBBCuQ6eKIhRdqRZrIEDc0sJw1rJAt2w5BHotE+vLI2N3lM+vAwWATMa07Wmf1RM9o3Fxrthf8obHHQuTaTLOs9merKAm3V9sk+jd7LNeit9/QFZetffGEpT9vYXsm4kS0AGzgM9DwFnUIW9IU0PWVZzh1YhKzHGNVz5UlM4uRW9bi9H1AsOUbxtI24xJmGL/nM2x6vx5rZMqSPP/54efTRR8rjthJc9I3by222EKzrZV4uABjsPHVHnQPfT5omNQNfBrozgUiSpl+PsHE5iJN09kR9P2OAXsXiGQT1kCyzlU+/HGTQhs+voFY8343H/aNlffsr3WKcIk+Y3v56FoA2CE89NBPCqL53B1Egj94BFRGTik/oocgvqbHPVWsMrWAhfMmEwkMExMvCeGMMZKgplP0R7ZK+IgeenwV5Pg3bq2wzf5ZnC3fft2y0YLOyNc4A/Ohf0UUswgWnb4MiGuhWpdAd04MNWxx6jJVoA8zKzLpgoS+8JEFU1aMTKmTUz4bRcSeJwB3Kej9Dqejp9tKw9tjkf9fdy8pz9tqmfP5fbwnBOlqbnzeBcWpso4nE4R9GJ+pKqAk5bPy0GgnDnUI6QFBd18axCIDHbZKD3/yLr22NYxZy4cMHivz4ttlXvBZf9dPJYQ09xVBp6Hh7p8hdP9l4vxIn8GBLHW6d9H5hDTIU+a/cFB841Kkyp6fvtEPdsFq9Gkd9EoORhFdF1nreGOLBOvcQdYipHhAejhH8L/VQ6ON+jx34b7VtWWCXfjD5o2Q/QU/G5srdKMjWdCtIYCnDaJX54UOyMd1p/uGqygJU7g0Qsum29CiM0BN/uIWL5CaJV20L5en2AbWefT92k00Wls0XbqBjvBCug7V5twAopTxNjYiJOHY/yJTG1Feakt9PipVX00O2vgiYMa4LNp4lQNTNzv2HffiSH8SHuuy0Dbk/bbTGCz0tAu5nKn7F6eTIzj6WRvvEPoMcIrcFrv2lRUMY0Ii2gwqadXxyFwOGFwejHuhKUuY0422MVGkYibemqmOTCHkRYdbxETQGeOI7rwaUW0Ed9BRK7TEjpE/dJLdLPuv7D0mixfJR4RtWT4sSFmn5VaCBxVhklfngBQ1qCiZEVnrdaJsLqrDXmd42Igoz+l/8sW2PLY3wIc607bh9aG+04dP8DG7jp6/7i8C8WwAwTMOhHqaNaKUxae2CmohmQzNVwl70cDduu3qd5EIetrFbcVekDtqDSZ8Tf8afrq9dGdgogSdavLnQ1NUn4xYFvKfKqnpgOLGIxlZ/wIjsGCJGL8tWGqSnyZXp1J5JN+NGnbhBA2f2mNBGm4ZliCd5zxdXi0DQT9VWvwfm5QKQdyFP0+4om+nFSVFpzPQED9foXWb5yom30i5L8rybJvzuCL3a6IiZPsNXo82X6uP20+T1jGAO9twNcwxIokp3ZwLymeSmJ13/lgj8uu/QQU069EUccEGTR3/geXGM2O1lF+KBfphVPGmuuW1EE5hsPWi1Ai1l8QhxM8n+Mk+Rc8tRhkXwQRnfjMALftSpj0+U6B35IZ+xyB68Xg68KKj7V5srM2T0K1pb+Q0aWJOY0oO01wW9sixbdlu5/IrvQOyl15netl4/9MQfbntcSWG3altoj9sLp9/W2309cx2h5uFNYO5G+Iz0tBomN+ygXiZvY3LIIcfQ122oB8/t8UF8rKBeM/w+a4RFXUyYQzniayuwfEHdsy/bw4nRXabNVl71Ont4Rg+piA5d3KREuxiM5NBXXTLTMGw2T5iUTUcAqqSMAUOjG9uSeDdQbJ/iMqLGtkpEkrmrX5d/4OcCfvQN48kxIM8836oRI0eLVTxjvEXkVA2NL/rTpODmQr/ghLfghab8gSOfRJpEdV0HYXzhMXQDg357n6EX/tg78C7dSy/9t3LmmX9Zbr99WQv0l3/5pfba1z8om266qbfouLe/pRxyyIvL4Uf8luvIthnUCuNhHw1lmaYeeyvzgyONUi668B/KOWf+ebn//vvKdou2L69/41vKQUt/yc2iT3oU4tQ+MSjsYutaafPPuhb4TPFiHJCW3EbdZyksBCaAHKXXhU38UT7UhzzsdWnG7YAL/IZBvUabnG8Qk049gq/6OPtwvIYxad/jC6dun4D/Fhsa2+I2PDQy01ZHoT63pGsdvl2eZYoPmuTDnvVJWgBoY+h4tX6AD8zJMsab1HpiHEbT2w4jzDper2cC4ueowWPPYBv11iPGDP2+ZcKDrv6CFzGGPXmhoxHIulavB0ehB3mvSxnjmUkPlln3c589z94j8p6CCf/ss/+ufOpTf1/e/e73lxtvvK6cfPJxUK/6XrWPaHPvR3Ju2Yeh20uDmo7BPrz8e98qf/HhD5S3HHNc+V9/d0H5979+eDnj9PeX25f9yEGm28tH7RNT1Bouydq+nZcLADp9mBYcag0Hdw+ldx2+ZiNdYUBPPGKLZmpkOfWUmtTLl3VgD1oLR9Cxu0kWuD0e+YqBdj0v9Bkv+wM6vT8nrW3SFy3MTBMDHOFot1WbqR0202j1a5bP57omEG3H2gqZ5KpnOtuIv2pe9PTtd9xRPvih/17e8Ob/VF77ht8ubz/hXeWL//jFBkFM6g/xMz1dL7JCoNDFu8DPPOsj5bWveV157Wtf50f7kO+33wHlmGPebovA9QVnB5OFsdxww3Xlisu/XS63vxWGNSyXf+/bLtdkneU33vB9l2E7U/ni588rzz3okHbE/7KXv6osXLhpAX++l3l3CQhpg1TElMYtaHBzGhuNo0w/6tFpqnRkHUPvWPWoFFxcO2W600a+mgUOn9OhAOSY1LHFJ7b1monxEVn4lh7OFPJTRKHVygAfLZwmH+JDD/78KNsgezk8qP01RtDd5SDG27cfVtR3bHQtvdhnhwgHnQx08giyswGN1qFED6jHJKFcVOiRvyY+2Y4eSX6UX0HXWOtRNfqa9uo10rXXUn8QwbPL84f6vVdSxJOELWefiye9leX6H/ygnHTKfy0rN9q8PG2nF5YFG29Z7v7xjeXsvz63fP/6G8uxf/AWV4bLGEf1+yS22sKRlB4gNJL0jc8LL/xHJ172sle28dM47bbb7nZG8Kmy0C4BtUE2beAvt8n+3XZ2sGLFirLddovLHXcss/p95eR3f7As2e0Z5UZbGE4+6e1lkV2uwdcyr7D7Cr/5miPLq1/zevd38olv8zOMJUtM1840oHfiyR8wX5u5PH9A/suH/mpmOY0zA5W+v8kFL/hoFah1q8y7BUDdr1TM6avEY+JaqmtSbwuB73oO4RNZG948nZnYgGIRoMehvl9DGSwC/e5sIM0/MBBdTiBbNLAIQORsxtZO2WwRAF6Wd/arWCQ8XvfvjRn4z71nzg0rFgEGFO0F3esP7wlIF1tqI1JyQaN5Qmhy7x72R7aTPvV6OXgow54kd/U/6Y34GY3xh1fSoeG5Yn0te0UoC46kegl2qssCmpNl6KfvxdA/7S//opQFi8rWB3ByhGTjbZ/lf//6lXPL8w86qDz3Oc91A8fE/lDjDc95hDRmbEEfZa93//0rypIlu9uR/8IWUI5bfE/FplHK337yXJ/wz/jzc427np9JvOO4t5TLLvs3XwA+/7nzykF21H70sbyEdJmdRXz49A/4AoCJ+0pbED521nk+4a+4b3k5+qgjyw9sot93v2fXLAxnd9rismCTTYIxpaZ2DsXRHvRH9NhQb22k23yyNgb3RGNCCqJgm+vcsUJGHdOr2Sd9DmPo9XTFNRsNt+zCp3SIHXLGI1q48E8e7PRH/345qMqBny8Pkc4+YCss2xpYYCf+oF9cz3nZHujJBoE1mnrgoCh21qsMvl0WuopNesAjJjjCUb87w0Fgl4uHkhhDOURDnaS+2tU+GsJF1PQ81PFv3FTP0sVWf+ol0mpRbkWuRxOIFbRwxPnelVeUm2+5qWy2x2+I1bZP32pJWbD4wPIFuxSUcbxez14yf4hNWcQVuoqfrhbaEfp0Xegk/Qrypje9xe4PfKDGutLPABYuXGjX5W9zHi7RYDG46KJ/dN5BSw8pZ51zvvmxX0+bDOXv/vbjdqbwfV8Ezjrn0z75gx9xgmLBmQLi4F9lzmEzhjkH85+b6jw+A4iBxrDmARKdtxgB6YCvAh7Tk9pIsJBTKl0gUD7Jp04gyVvoU0O0/AAJk75WavAnaTyONxdYsQiPVEQ+6Z8yRi77YbyZFn51ZBtIFTe4QkGdvYfaU2WsB9jvIcl9B+5QHppjMo1EsW+13O+qGy7YMpu0+gYbb1Fuve17RocNhPTHUet9T+rBFtywQ416qF1+xXex6TBF32YT+uLF2xuZc5P3Dv4WE7gdteM+wXbbLfLLQZvggXim/Wq73INLQmd9DN/cWVF2tbOMl738CLvR/Ctlt92eWd5y9Nv9LOILdh0fl4jwjZ432DeOxi4BbWuXmHDGgLODJ1uZlwuA0lZTdT8tIRE1LWIL2jRxFtCOejSNKamV4BnZZDh0RjrWS0hM4kBvyQS9djlIOxBt2zV49x/X5CcmeZPrngCim0keOxN/t4BLMtm/x1xbjhij/WpB9Bw4ahEvWRltbaFG3z/kShsy2ApT0g4R7hs+0cihlYu9iq+IAkGFvScqMIMTCIGbpatXV7syivyob4Kmls4CkGu0Z3vUsujVqPX4eVyyJEY0c+Fjk3pp4/FHHizrb8TXf2Yd8BcvWlRZGmuSSFn32OKVZa8HboyudLBdWQ5e+vzyiU/+dfmu3azdf78DU7vZO29/+1Hl5TZx4wYxinPt4/3vP9kn9tfYRL/3Pgf4zeOTTny76+ADXx3V5R/cCL7I7jWccfoHy3bbLraJ/MByqF3Tx3V9nAHgBjIuKeER0kcf+w7HgB9lE+4x9DeYV/o3gMCfVnIuSgeYHr8Y68C2P3BcBwJeVYiccjS4HBLtZpDxDygcQsiaDSZh+wt94jR5s5dtxas2gc80kC/fGigmbfHCf/D8co1jEZ/6EV/+CilaEHhDf7RR2+SfvomtOMQDHv2zzX18kCY77yDRER+wULT1vkSfOg+fsBHNbS8DNfRPHgYlxyo9D6WpBH5l+SbrZP7q1tGCaEWgqYXiDHW0EIS9ekV4jJg9LBRuh9hZ2vshxu677FoWLFhQlt94cVb1+qMP/KQ8fMd3yv777NPJMo7X24FRVouYxVW82X733XYv++6zf/nYmR/x6/jQpXxl+dBpvMRz6C8fJgjfQn6FnTUstcs6+NvMJnt8mwhnAsqO9596sh/9wwATvhYD3CzGYnD0UVxQltjZAL7Vg/sFkOUCP/h78aG/Ur72ta80Ee4ZfM0uL+2zijMCZttPK7taOD/Vyjw9A9BRKPtOFBNPExQSmJw4Yqs1n4RN7ke6wMAgCwU07ZAA2lWpomTIctSrvR2B+JG7i8kDWpTKayId6Vd7w3H7CXlFwJE+Ymv4QnaGhTGUV35VQ3sc32n2DyxYBrRhjfcP+wlBqHf8hqJNIoGlvqR/aQ4tQaPA0msVYNVnAxohRk6MSV5IV6+G2KJtxCJPXLZEFDR0Y9jr9sE2sr3giYNa5opmbw4l1A0/uB6+STn2995c3v+hPyuPP/Zg2cSu+W9g3wJ65L7byr3XfLbstP125TWHvwqwtQ2w7uP1tmARsP3C665NC3DCH3lD++Pf+Uflj056V/mDo95Y9tv3APtGzuJyyaVfsUl9eTn22LfVS0AN1Cor7VLOYeVznz/foMyjOcC1ftixmNwm7Q/4WQJ/uIWjfL/UYxM9yln2o653n/S2su++B/qlo3+++J/K299xssuGH0vN5ovm6z32raJ9TP+yS//VfwwGH+yVyX7OGMzfmXWy/tpUt6sDPiusTTGtVizf/O4N5WMfv8Aw6qRR0ZSmGqaeZgqDl+XIPRbyh3LIAsd0TF86eSs9wLl+0+MTHxUrZHzPAPIePoPWa0AU0nR5jiPsFY/jJ/+KSXLfDuQ5Pvqv/eExonWVHvaf0Shu03QrPdBteq6f7CBIuk7W+LxePxiXOIxHlLa9jrhrZsuIe6zg0XPQ1PPLjtUktxh10RsfcnjZYqvt7CieNzazh/FWVuysaCOAm8Ef+su/tK9/3tUkv/7SXy2vtskfN1dVIsbJmDlTTPJrVguixQ5G4JXypS9fUG6vX+fEjdqX21dD/Sugbrle+ft/+FzZZZclZe+993POZz97vutvarovfvFL/ZLQpXZkjstCKN/73nf865+4fLOdLQ64/i888LBo4P4AYoD9osU7uN3YBxYj6N9pv1TetmHpK6N95jz88EPl7rtvK5+++Kby4EOPOZzGYtNNnlbOePerx1yslbwntADce++95aqrrio77rhj2XnnnddIw6688sqyfPlyO+Vbulp43/zODeV/2AIQk3ekJyY3lBhODVvWyfWq7wbURVU4mphE++QJeZ3sGt38CsNwDYhy8TJdeXURyDjy79uBPBYJs+/w5SNt5yRHryVbkJlGMI1mOzKtOu6VuKppc5vpfmzQZpWhrvONmXXAEzbtApt0fPZ6wV/dWkTcI/UtQ2/0RQuB+Ioc9AJbADbfatHoAiAU6YvWVnik2epl9oOw2++8o+y3d1z2GdqHHW2CrrF3l/XkrR8N2kzaT45a7o8Z9HMQ5jJI2iCK4Cmm2A7bGJKozWSfs+vhhx+0BWBZtwAABT7WtQVgzpeAzjvvvHLKKaeUzTbbrNx6663l8MMPL+973/uiFwc16B9//PEDbilXX32187CYHHnkkeXmm292eosttigf/vCH7Shg7wmb2TMsGXGJohrokkFwIADFpMWnKCYBJU1/5HIH000emNahb/A22eWkkQ94RuF35cN+iOd03dHYkB5vTB6Xb8wBDtfyKmgtzPHMTZ57BzEP6NY/8MGiHgSlup6P45c/Gh/yvv+zB9gzcmqB9l4zZn52kPSavKIGjRrLoCfEXu2tRjN6gZBsT3glHe68P+rlFXLVH6EzU039N9Tp/dD/4u22K4vsL5ehfdjRJmj2vT9TK8XL9jL7tQ/QZtI+ciciCPwZ9EPJDYOkDZjBC2zVhm0UP29hj8L2sB6f4Uc86Gef8IG/danMaQHAJI3J/E/+5E/KEUccUXDU/rrXvc6P2kGPFegcZD80OfbYY8fE5aijjio77bRT+cxnPuNy0Fhgzj0XPwB5YoVDxSEHAuZiLQKgh3IMY58g0oB2TQhjceJSmsCKV2JRQ8nJQCfAQZFNT/siICufrOmXNvisdGP39mPyiUUA+HIfwKxhkejkA/xOrklfIAO6LQJjculWfJ88rO9aXJP9DxGsUNTP0ELh9OiVSpvEF1wn1WtGDPQprjaSJuYaqjL2Hoy86N+hjhYBWE2PusfMVJ+/Ien90D97O3RQG9qHHWzY8xG9jQF3KgcJ3R6H/El7jiw8RgmMGfShhFINhzYQBQ9UX+RRedVLg5qOkSOGPmjldtivS7U5LQDnn3++X/bRZI+jdNTPPvts3441HAvAwQcf7H9DOY7+L7vsMj/il+wP//APy0te8hJfXFbvLECIsWVqkc51cMZo8Ac51xKMScJdCbYqkTxhSWzuRC173UD2vRXxaD+5Yw4XnTYdVsR8Ixes3LJhpEO5aGxzibYMI509HX0J5BzVbOgczZOlrl6fbXtjLHqLSf74pDWZa8pWjlbGYWyRe71syJ+0BzJtiISIA2Oavqbwvn2kIqMCZ0wv+xmXP5m4c/oaKCZzHK3ngskd9wOmFUzwsMFR/bve9a6CRUQFeCiHHXaYWO2egmRNMMcK0oEpxqTxg1lLMfAgQ+nkA770Asf07ZA1rtcycYlBLNkgxdyu6Vc6+acu+BUHulbH7wKyDEf0Dcvl1FNc4/L+K6Joe2DmesXq5NWf+x2To+cUA3X79kouPz3ddIHBRnj7xId26xMQVjINE+lWc+doXJywD+qJUpyiuc32vWT1KY5qjwOesgaSoKmHswCdyWS9MV1aDD85ykOu7Hs+e5V+QjLsqZCzt4I2GyMU79BHxoGNaNZn6499FNo1ExJIqppajDr400vFma5Qx2kGhU60arxOfS0i5rQA4Ih9eFSOewHTiq7rn3baaX7PALpYBN773vdOM3E+fuRxyy1P7IXLSlOlgmhPQSM46SAdmSIh50QDfsiGdaaYTzbAqrrUZ4qTh2YkGk4yXe002XeTeF0IFFf4QOyG6fLet3yGnL6JizrshjYDehZy4bV4azu8ebl9zmAMio3tDx56RG2zCv5bYayoQcatbxodvNjFaWs2tX9oQUzJov8ljS10Qi/4q1tDhBFloPUto07W06SaebIe40mmLXtZVGwnbdnqIX9o38s1Mgk3XX7LupM40csz6wl7LL7IKO/cChR44z6EGNuEE8yuBszADZF4kpMWXvgPi7W3NqdLQGjG5ptvPuvWQPeYY44pb3jDG5odzhiOPvroqZeM5upjLBgMAS+uUIpEFA8cP0E1Rr6JiOHDQFKPp7CyYxpQA3Jp+awKsl6/zz6h09E2AzfaM4Y0fwkMEBR6d9xZ3xNg+vX2RlUfmKzbKm8xwKvTVd5od1/9N0i2toL5jWvg+Y49EV9qX8WK3wkwOvYn7aVND8azykwv7EFIsEHpxyVohY2FQJMo9Gur3DJotQ0cFnGEI/7qbhl7j0If9BjtijgQP9oxVsbwhnrq60k+OWqremeIObTv5Rq9QPd4NT4GLvxJHOQgCvKg1+NIujDJoN3rQgO4+pQy8FDogVTwKBt+DuMbykHnOHs5YhiPr9dbe6k2N8wmRFzKueSSS2aj6jpYAHDzNy8autwz0yUefLtopjOLWQcwgyKGTSXXwRM905Yyphfq+pM9dpFs39OQZblo4VEmTOpKR5d34JN6OjIXnfURT5aTVrz0l+X0KV+TcbB9wQ+aPNIRW9D0Kf1+GzLwUdR3pHp6KJPOk2nLkZu5xTEik3q9PXu057XptRn3cmRZX7K/LMt8WFA25rPHDIwxXSCNZ0LGhxZKYJHOn8P4skz1meylsy5u57QA4Dv/+K5+LpdeemnZa6+9MqvVsVicfvrpjc4VLCa6n5AXA102Gl5qyrYz1yeHX2mFdOFf1THCLwnViVTySH2khvC0hXfyGxZwEk/25GX9itfpC5cyTsaISz6wzfjU98dCVD48TEzi1V542OoPeLSv8QztB/GN+Vd8wh9tP2KAsfdNtAGcvl9rG3HE63GHTa8Lu142Ljc9YKVCu2DIf3B+ujVEo7+hJ7Y+uIocR9V+ohWirjYNLysNsXtZptSzmaeRC55iI2eyF91fvSSUdYdxUBY+Q7fHzHz4DJoRANd5AwHJftQHKgSon8P4OmHT6bnAy36C7vXWZmpOCwC+848bvpqwcU8AN3V1VI+Gfutb37JndtzY2ozr//msATSu8WOCx4KCr4jmRULfNMKloidamBIcUqUAeKhnWrukT1J14gmd0FdKEgN8DTvrTjd72mnXkQ3awjq3CKSjm1yYJgem4xJTWNiiDJ8NlOXejhnsofs4Yqj4wOvsW3yKp4/B9R1fdtpSr2s/gkn9r/jDXy9n34gXfQ0OisMlPPKoF/KIBzwU2NHWSauzbaTiM+sEd83VItLAVK+Jk3WGMulom3XFy9uZ7Htb9Wy21sgFDzZhp9Hs5X5Nr9Mr9kL4H5UvXXhB+Z+f/Jvy3cu/WzGit7///Wvsl7+3m1WPmX3BS9CgUKp+H1jCDx+TtkTAJ/tppT9ALrh9LdurTrfho7dYu6k53QPAhI1r+vju//Oe9zxfCHCpBtf4Vd761rfak/gOLSeddJJ/9fOVr3ylX/PHhI6je/ydccYZ7bLQCSec4HiveMUrfEG44IILyjnnnCO4J7zFcPDKIdKDgxM0B1tDBj508EMlFG6QVJV2e1HCo5Xrux7tHdPNaE8f+Gxe4MFpm3259SOmLDe2F1p7QBUTqFq1wcI9hPUrTMOlsX3Kj1Wrfa002Yz2LT4ANicgvNReM5HJ5nRPgFiamNAm4PMT0NYXhlmHg7TJqQEpRxQ9hiJJllcBNxabfFE/eoF0Lx/TcaA1+BFtDVDFGO0IGSdUttcaPFHG8LIS+6zaZ4HVe1uNDUdcqoxNEZIbdoh4RFbdrVh+X/mbv/2f5f/73GfKbkt2K3g/wGfsMQ+b2tu5/vAdJ5Td7A1fiOLDf/6h8oJfelF51RGvMbrHzL6gG7QiTPpJGFW2C9rBk21sz7AH1OFxFSe/50+DOVIDBmMkrj7JHzFYS1lzWgDQBlzTxxE/jupxRpCP/iH/sz/7s7LllvHs8VNPPdUXCunjclF+fATOBPAjMFxKwhkFfmiW5cD8eZVIGUaQadRR8oBLThnTjJ/UlT5SVZMWJaEVVpJwshMFS1x24SIApLoIuIJwsGWZ9JQ9Z3vZqBVCyDRbJmRsA3/YakiJP5RMokAXhfFLroggAS/T4D1V5tYDGCu8HnLF/Q+U3XbZpXsGEHteeOztngeZRgZ1jkboYKzhIYpy4yP2JNCvXvrV8t53n1IOsHcBo9x334ryUeOfcNLx5aNnfKw9wweyaZiZD62gYYUyniWTetkHLfHsoLPO+vNysT00bh97/PSTpcx5AUDHYNKedo3+2c+efKnCTPrAw4T/05j0lYxKlaA5NSldmTZMV8SDA3L9cngog5zJFxOpEl0I/siDelQfnohE+1w3TjuCplQ48MNvCXlADMwTf2QRsMPl9ZNP2KL09olucu64j1sMfN9A3l2I0cen2LWFJ+sLHK7bf3K1aBGLE0Ntg2lMe5+ArIFXUT1KUuyVAaK3UfiQsYSu0+6aWtIgpqgYpeAwGtCBm6WrXxcuYsllEH0SVU2cbQ2NTGsaHgAu+frXy2kf/Ui5/4EHGt7S5zynHPMff68tBLAPWNS05zST5INySMJuchHAZZ8vX/Tl8taj31oOtMlf+HgV5O/97u+XG268wf6ut3cF9JMuMPGymEsv+6otWPd7APvss5+/U4AYK8sNN9gL5S/jY5zx7P5DD32pxcK4ltvLYi668J/8YXB8Sujz7WFwePEMCnsq4i7+yki8FQwPjcNjo6ePQTN3FGJMttvdrAMfupqwDoQ6uxAx/BgO/KkwYUDzj3SvJzvouNw+hBOy2EGE38vol/bEIQYiEU1ccCTzbfMnH9IPzHxPAPa8AUu549kkjLUkcFWvWC5PeB5T9BPvKdB/YFT9hluxWnsod/+NB6rXm04zRtljK11cA/KFxTjepylexKci2ZAGnzJW2KbersmrbqZ7PFFrfhsRBTZ7L+i+ZlGOGVWloQiT/6kf+n/Li3fYoJx66PblzJftXN5+8Hbl+qu+W0485Y876N6WvdHzqE5e9Fbo5JGxJ4Da5I9y2EsO8y30pItF4EN/etpg8ifm9fbS9/9y3LEFWyT19ddfV060R0pfYu/+hT22f3TicXzHgJl84hPnlhNP5Mte8GTPo496vV1V+FfTXOnb4447qr1OMmVFi+WNv2uvoHzPB9Mi0bLQ457+ofZyq7ZN11+7JE/oDGDtasL0aDQ02JkiVTGw5GiwqKfPJK9GcTYgCyaH8JlQcYQpJD38jFkGLndreddW9j57Q9ndhH60sAXkOrCPy0HQgtyM/YwCdMQLKuRWrT5QUd/0eOLCruIAF/VmCxkK5bhu7/FUudpLndQeh0l0jTv3h8bIbW0h6L/XL2n1W1sARBTiYEu6navVJmk8Xdk+aqvcErymD6KW0BFnzW4RaQ2vAcfINFaqmLbfdxkxNJbw7luxopz2kb8ov7b7puV3D9ym2S/dcZOyZIuNyjsuWlY+cf555bWHx7O8ZEtltrznUUJe9Ezo5LEt9g6A/TgmKd5puvJ5iV0yWrLr7uU/2/sCVP7vtx3jR/0H20tiLrRHSy+1t439xze92cTref0Tn/i4q+I1kius3X/8xx/0Pn3Na48sp76PbxjLftlL/OSz/+UptpGTwWON2eYnY5b3ysjJURzarV30vF4AnmhXK6W1HcMZykCjIMFUpEMZU0+fMUkhZSItJSfGUAKuPKHOtBtdBCCeQIZFP72BzvZj8vCoNEeUKiFVPIwa8mH8M9HEi56Y7EtoZM+04CeimCbLek+2+g0//EG5/8GHymv27p8Ain5YtHCj8uKdN7Z39l5eSloAIMvjwJzjcppHG3os0fthh7HmiGAyRpnMLWVz6FKvlN967W/b3+/4Ef4NP7jeJ/4V9mx/XPZB2Xff/cuZZ33Efexnl4/wxq93vesky7hi7w9e7K/CfNvb3uIvjtnXXkLzzneeDDMvEaM4w/YGH7Vh3L103abm5QIQ6cjBYXpF6lLOYdXwaWoDzQQJju4J5AlNUulqJ6E9J1l56O8JTCZUTjCPzY4o9Ctl+mxINVzTsqNifTMk21NBclwm0s7FVk+7J5AXAZ5BoGXDewZcLHCk344+XYvYrQ86uXo/dLzvms4Uue/K0ASq6eBykN/j6McH7mdCgDyPFWhAD88CnN8+Jnu0mrkGe6Ypr7GKcNFTsytVc4Z7Ag/YDV+UhU/bYBQS/NuX9a9KlCL7XhTHr+dxLKCBMRIVOvZGMvvGD67zq3jPpni/am8GW2QTNl4dmcsNdunnlPe/t9xuL2jZzV74vmTJbpaWK/1F8MD/jf9weMGLYvBmsdNO/2/G+W/l0F9+aXvD2Hve84Hyuc+dXz75iXPsPsD9/jax4447qfAbR8qh2n+eZYo+RxH1nBGoo3Br2Wft4ePnma9htfbX5t09AHa5higGAJNELhpCDXumlRaw4Z8luDNJAwdklkc6kE+dsMeETRvZQUM8xtZ8IVZTHscPzHxPoI+n4sJn8xu+mp8mpwyLQPPZ+R/aGj1VXuPu5H1bEau3HTo1vtwXTW5aue592PSjf4CGuLn1TaODpzZQDmC1NXSqzDd9vmQJY8qcVdVhkf9m1h/zPMYLFMOeorDJJgtc7fYVj4R6qt1x/6P1TVnjrephqdPzCEZeYEjn+Uv5e55/sks2Kj4StpjjPb/vPfW97ag+RrGUU079r2W3XXcrn/nU58uf/enp5a12KQgLBQte2n6bnwUc/64Ty/mf+mI59uj/Ui686J/Kl7/8j+0F78ce+3Z7rPx55YMf/LC/LvKT9mL43E+KkWOj6KZvBxnkUGo31rQY4+kYa5tkni4A6OYYLqWldvg8WUA2pGmb0wN1wzNl/hEbXogtGlvWY0t812sTLiyHevTHSbjG5P4CU3ERW/aIKXRCJrlt66TZy4Zy0hOLQMOWvtoD3Oxb8rTt5Goz5NRp7anxNXooh2nrL/l0pn9433qtjlNZckBpAABAAElEQVQVqb0gqdPLnYkYDVs6gUW+ZK6QPrJeYs+yCuuZERhRD8foe15QhjeisL+9+WuJfcvuz7/547LiYb6+UDaX3np/ufiHK8rLf+VXp/QANftYGHfPy3rRLuhsv3hxecXL/oN95fOvynfsFY4qy2wCP96+ArqbHdk/b+nzqn9I2eP32bd4Fi1a1OLCzeDL7UXxKv/jzL/0S0CicT8AZaHdWL7UbhCfdNI7eIPYeDjqxzeBWknBRzXibnojldCHsM8wLAJcCEYM11LWvLwE9LPua6ROTgyl0jTeUM6UJxc2vBwTdExC0pyGjJbDbigXLc/QyzzVwe3vCQzxII/IqB/xZTq0Qq745X8udEQMa7UkIh9GCq2nCnrg2N9/cznxT95b3v1vd5aDFj+9bLdww3LjTx4uX7hueTn0BS8oB9vXQVHQl+pXZ6SPXgYtXu4Y6lOPcpiDfrN91RTl+BNP8K+cLtpukV8Wws3h33/T7/mTAVyhfawsv/2a3yl/ddZH2+WjZXYp6OCDnue/FAbm/2n3B/6fE99Z3vyWN/qZwQ1243fpQc+3xeQQb8OF9hXQo456Q8FXO1fYYoK/N73pD5qHXIm2RWuClzXH69BFCWvS68KnXc7Fcdz8KV//zo3lLz5+kTdIA6OhCZrt1XGoWh/ymLIgk96EvDJCzq4kmxi5jjhANx4rCV9y4QTtRxfNPsvHdBLPbSptp92IVTGwnnhNjpfJs91Nx4xavckSr5PLR9p2cgNocVDH6aYzRe5+Q4Z7IGbif8KDFLxMg0LsKmNyGE3qyKKXBZc14g25mQ7fmdvXx1E2OOQ3y+ZbbmdHsP1L4VeJaGdVueDbQB/7m78u37NHMNzx43vKvns8s7z8117WJv+sq+zKPNV7v+Gj56P3UXr5bXavgY96oFw/CnNdi/caexTElltsaTdxF7n19XbDF3Gj4HcCy+2SEe4n6DcDpHlTGC+Z1/V96AMTN4wx8aO+334Hgl1LHWkGKabr4cwE9wyENVBx3YcfsZfC37WsfOHiG8pDDz/qdsqQhZs8vfz3k3+7Ya7tlXl4BtAnHQaAxypIihhOaGnqUU1S6PuNxzp60COHjEaZgePY7CwL4vYWksYOUeVae5M9U1cWRHM76GIVqJExhUGjIHKrO55tnV15Lq86mhRmIc839Ryi+a9YdNLQ3bfHJ5b8p9iaPPcPgsn9gfinyL2daF7tbWsP0Ht9+peOi+1DiKAZETEkB1M33iXxboKClWxPTnzWFgZjosY2TrA7xqpRsvoqEa0Pcc9EZdOFC8v/9Xu/L9L7oBGDCrHH4+n9QgcFvc1+ddI5oAMDclwOwh9LHTvpWrx7PnPPKiMWbwyH3mb2DLH999u/6ZDuf0AWEeHSz+4VnSaSAd3zA0GhVAHIxe3HYi6ZaBe5kgGHbeR8IcCstXbX590CgOHANW8fmDoeGnimKQYkpyboGEZKY5IBzQIwIYFDHz789qFvlTjteHnKyFzaEksBmnyWi4CjYuc2Hx1GTUSgR1V6znUB7POzg5yWWIZm9rjBo1fQynajqFtgYDTAnyqvep2c2JCwJNrVE+0KmVa9WmOiq4sGVDm6iJ/9y50TfNJoFyPq5c6EfRsLd1ytentK4pN4QU/W4KvGOymsHMkZ11S1KshasuxsPE+MkxYCyVcVDeVCzZ4i84TFdrG3ZQFZYNCetKw0hqRdw+J1e99/1VuTehq98DEdc1a6KbCoIhKPqrZDPmILKTWoC1+cSUJnba+1fXttD3Rtjk9Jv+ptpIsmI7RLaRP2TCPphFz2IYcN5eJxx8m8fGMX/vBVUNmRhq3+Mh79ZXvYkRbGpH5gDeOVTfiCf8WCLcrsaOrqkzaiuBVez32KUg9wdERNbmeST8rY20M+6RgJ0KGDTOlL1g9Zrwd+ZHvGA9akrjIK0sAM3Z6Xdfq4YYES+tFmxkT5uvQ5bxcATwMc+aSjHwxXHrKgOWSwUfpQ1tMc+sxT3bYOLDrSUP4Cl6kygW9x9v5BZ5xEm4C6w23oIJ6MlydxtHbG9wHAb41Hk31nb9jZXnHCn+sl37JXLL5NctiiXwOj0q6DNkyRGxtYssU4EyP0Ucv2oFFoR9mYHEbSob6btQ9vQ6OiEv6DN1NNkwa2fZkrUp6UeiSndCYwJhrhZRZjYy9lPuqKP/jUG7ZnDCN0ck8TiVcKh1js9bBTm4d6wOgxw2Zc1/XRR1CsykMboCYxyHafDHVk31AO/tpe5u0CgI7HcPtfWgQyX0MqPchQ+vQRnScY8aSPrckNSBMvOEpZ4KP0NPHE9y0mMWB4KmV9pmPYG131gpf1a93jgR/ad5O48WZ8HwDi9Xhojzb09nURaHFk/9GOyfhSbOgz/0PrURcG6Owf1FAuOmS+CNSFIPSBGTqs04+z7WNMTmbs0rKTDfCnlUldaQYeONCTriQ9atYQxvStMEY1VnMR4EiNIg96gi3q28He4ogFRugwQ4M2fSfGsJTNxKHNbPVgM6YrLMrUoIin8qnWPtknfQYP29iU19LKvFwAxoYLk1m3x9mAQI+6kUay7dMs68UQc+jDtqW5gWT7rIc8II0aU0g8bftFQPrhp+HBT/UlTMnQjlb3SZH2MYnDm47YlcrJxmOr9Kh9xpOdthXP4xM2tjPJGU+LWXsh2N2kLrysrzrw7S/ps4/Jb+MDdSvyxTo+0SbG6TyPX/yKDbKWbC/e7LbsO+ki5lyydOUjD5fHHhv/EVe2yfVsn/m4T+J/HZPEVJtOly3uWJXo7dminic/fWtDZ9LGF4G6cIUecBBHFNYn7cf1aI9P2GUc8mp8VRDyiPsRGxNgP/zIYxUj+iX0gbb2l3m5APysuz1So/c85E+jJ/maLIkHOf+YXqumY5LMutpt+kUAR/bcVZTG3BIDEdAu6LBXPBFv+GPMshcmabVH24g35OEPmLnQB32CL59ZR/zMG+Jk2dpaX3nfj8sD999XHn8co/TTLbOdvKbp9Xz2ds9j/DFyotWuSRvaT/Ix6hl7LnpZF54zDuk+U0Juv5FZ+Xh58IEV9vVUW5StLnvoDNvlwrX8Y959C4j9jaHoEwT8xrHx7Z8uicHDEHLg8UlKQ09LpQV0+e0CoNJ2grZDcz73HnJKaSc6/AUe/Xki4Si2uqe99KWdaPPFrzDWZ/V4O6qx6jhV4Hm1x4NJnKs/2obLQePvA0CKwz+u+fN9AZVu9qaQsNWH0ELxvmzxVdq4bSxcKWKDhlpI+0qhM9rRINtOjKwPXVrhLABj7P6NK49DuvPhtog89F3u4dEn9dU6GiiCau4b+smcYT3whhLQkq78wXfK41ttb8/EublsuMFGZb311/wxG2JlYe+JGm5Dbyih3ZicvB636XkFfd2XoCdxOebUn7Ne3aHCTjhT4nNxxIdF+NFHeTZ29bW31d3JMgu5ljKtb83aTc3TBQCdzp1Y3d8PsU0zbdBctQ2f9DVhkNbwMnXwyammp2UjefzGLiYj4cVEB46mEKU3Y+fjpA3NJu7Kobl9TtBtkiUWMIWGOix8osbW/+df/FITfeK62EBJdiCt7osAqhP2EDNOiFnoE1HAAA+QA7xiivhTbHWB6rWI5vo+ZoBj2zKGekja0nfa9Hu5R2SxwLc3x+OCDUqN2LZJblUs6CyUiKINPVQF39Ca+Jk/VqfPXuL4999THv/GF8p6O+xZHtlkCwRRlbQNG/kLzsw1jcVQawxnqBs6jCNo9p9a7Xwbt16ebaJOnaqbbOBb9ooj62ZeqyPZrEzTQ3wdphEdPbAFFu6Z3f/Aw+WmW+4pP7n3QUOoxSrwixwPVAnX7u28XAAwkBwcDdHkDothUbLw6ZaRALLNE0Cnb5ZMll5TUwCSgDFQ7hQSsh7BAqufkKDnKVRxVa8tqZOrcKN1gzgwySIF3Y88MAa2rtYrLPDiTIAtdGyX40MlMFx/mj3iRM9X9cAnFhY0nFHkMwmOQbUb2E8dEcPR0T0jhEP1GTjEg3+nat+jR5yu/EwTwcWuVSOq+mySh2ccLgTq+9ZcjwAG8uvG9pGxxOO2dpTirEJxm+6DK8rKG75ZtRrXKhOaLmSrsx57J3Oyjo+BMYa8oNmiSZr+ceAAGceSW9TJq7TriIet/kLOS4vxZQN+0wzy9V2/ySsW6Xofy/D0zbTGn6YH3yke6asdja5taLTZoIDGP7Qvj4Da70rryMe8XAB+3n0/TIyxeIY6oFGQULnuTE82crMc2khD6YtGgmKXQaG+0jQ0KcHnlEWAjgf4tCI+FYb2jIdTK7z1cu4ivgh4ZJSTm+MFNmMmHn2Bl+nwIjm3k63s5aIYn6intsMe6HONIzLsW/Zh9GTQQMNoaSRRQ5mOiotbyl3mCGl84kuX43J+HTP0hzT3hV6OnNeltJAjOuQi9h3oo8xMj7WPduvKp3phXYl31nEq3WiApONggd/LOMiZGTphlx1zwgqO6GynOn3RN6+BoA7c6rfGleOLevLfjljClj5GaBPAh/7ki3SVuY5i6PUdtzt6Cjl2UMh1tJXbgrrLTYF60dag0XCeCUyLD3KPAX6qvxy7t6fqcEJRfNii5D6p9YSp/nWcqh929E1ZxE+5K/NKGqv+mWW0S8JaHer0Goyx501S0Oo1gTqJ3OsQJ3qU+lnHZcYAT3z1AmmNsuSi66i4LethRxoTDHi4cuVb1MXzeqX9Mp2O9TGJwwb3paTPTCDf5J1+tWv6mU52hun25n/99bAEJHrgj3qTct07lDz3D2SSm4t1oszrMwDtGhwkjIdqPGoWBYmnWTXQIIY9UlcUUaCvZJe9aGj2x6o9bXlic1xoqBaIQqdPyX0BQRzNNlrACIOOa/I5GsmJSzwP1nuALUNrUEzHJk0vviGO870f7SjJ5H4E0clpAv+PW5w6wkB82BVJW/vM9nHssI4Fz+jh6EH1EdAYBeUVnfopPtlnXfJoAT5O8X2LHZUIpKuP2iudLFmjR7w0LARZi3qHpKKRlFtpM8ZexlZSo8ca6mVNySYtPEaJ61Z+lf1B1/7HLG3F+x7b1GL2viyQBexDNwCFnNQlvCbNLba6zJ0NQnKgGF37E48qYa7wSByXDHl55nHj40yg5pLx/cje9dORP/jGQ665fEg735i2CEBrfeSq+Ze+x+m5Tf+mZAXySpsp4hGtXIJO9Bmt1vbPeb0AqPOVZjZutbDGHQHD1hefKCZ2bmgRCZ+kZImdAVLSmniQDijhJ2jfyeoOR0tZwUJoSid6pIbJsKNhh0vItApPoF0PWN4W6TMGl9f2+ETvbLWMUsTlsTS2KrH1HUek9Jt57KhgIV7taN5m24m0g07KETbbw2840R6uPCb/rO01HG+m4UvOnmNbydMYAdek1ifaXdmPotRq2MoS8EPapPCLOGquUNtDATdF42rtA3q0bKyJyqp0sn1EKZgaVyUVV5ayp0KP/iqST+ZqPVvCiIVEu9zb0NZBjeeTtz76lL5hZxh1gwp6CTnQFZMPFwHaYNLFIhCTtU/aVV/RKacmFgFz4vqmiC0yAN79QMV4XA64DX85vpj0s5x+2SggrkvlSbEArC0DgtRAmqDk+jQafKZV2FE3uDHNUHtIh6c+TaHNkhM2cCUlnqJGHNjtQw+0dsjA6/WzvNcnEnc82gQ+0ajPHRbeKY/oZqaH/UZ6VX0v9KGe+E9to1+VPRpx9ln03JBG32lMUUcG6EgadC48Ih/Kg6ZckzkzXfZ5Ms96mU/dIV7QkE/GRznaxb+8yKkXiLwufM67BSAGBd0PKoqoGCbW4kgm6drRHRLVi6mhBo6KpkHSnIYkRdLkiUlIwatyA4WNjpxoB189QqDRg+P4Ua+iUjTjtM4YFHsfLbhml/Ccrm3FDgN9ynl05DQj98kftF8OUgdAP9vjFNuOKrEjori+fZK2tprvfDko+3f9ag879EX2DzTQfjQ+caaDOBhJ7lHv89behlA1GR9bIE/oX+oBD/FFC40yLJ0FUEqf+tTouGn9yPbBVwdCOvvi7enUe/RJOSNjK2CIPmSvkzJJPQsATbRohfe38WlFDfWvU24bbcgyatvY21jhRBZakE8sAjUgTt6UY8igz0uPPDKH3DFMpiN++EDBE23d3hSIU7fgG8/toAf/Fg/t0xlGtcf49vGZANZJTjTiw/e6Uua8AFx55ZXllFNOsdeuXVp22mmncswxx5Qjjjhianuhf/rpp5cLLuA7QQ8//HC32dleU4civCHAuefa+ztXo2Bwmeb4JCU4URhGFg7okI/ERBl+TdR5jioL+NBuQa9Mejc370RqeJUjC8xbvMxBPGFxCwyiAYelamCPQLENsSrtLHl1DYMw2idh8h94YHm5/JpvlmW33+QKG2+8sOy2425l72fsywa4r8DzBE/+nIbjVuoiANrZiDXJZ7EI6OurhOzt/XKQxR9lIEefpvhW1R8uN30gxuWgGKc2NpCblmj4r1ZpNEwHWL4AQWNYhtFQHqM5qQ+v0+VDffa09AM9+itqQGYRj57YKkgg94irgl8yqzzKowegov6J8TbEtghQo9eBx0F/mVNN0rDAgYftePYR1+jBQsE9AZ+0kdNG48+P7J1vcjBq8arxsdigSIRUwe90ZnNPwUI15VgEQMJ/Q6ty0Oi3damgz2dd7r333nLkkUeWHXfcsVx22WXl9a9/fTn++OPLJZdcMooh/U3tRQ5f+tKXyqc//ely8803l6OPPrrpYwEAb+nSpd1fU1gDFQxLJGcAYqhiuKDDEjzRNqzImFSoE7iZpj9ii58xQ450qX+uIBqOUBcG62yD+IzHdSy2wFQaJnn1AUAcPd2z/Mfl4q98sdy94qGy5bN+o2x94JFl/a33KVf/8Npy8dcu9LYyrsDq6Oqvxa42WLzYMdBXnb7k1X/YVX2Xmy+T+5/0vf3CsvaMyiNGU4dKw2h0xZvWf9i5Ycc+V79p6wJvD2v0QSzJ6hY49odCPPL5SR+T/DFdWBAHtTEb8IcFFvqjDJaT1oFMLdqEnuTCwsLW6u6DusGjHL44WuxJGNGWfHijfISuPnCkDR1uoW8ZZTLQ/PMMYx18t5M+tpP6btcw0rd/3D7wmt+q22jEBD/WnuwPkyfjrPLUN2jrulDmdAZw3nnnWYKvLKeeeqq37Y1vfKMfwZ999tnl4IMPnmgvzhKWL1/e9KFwwgknlFe+8pU+6eMsAAvA3nvvXY499tgJ+/nCeOzRh8pDD9xbFm62bWsSdiHsQGNFu2KWD3mZVh2ISNpV0d++/Ctlg013KNs8+w3N/dO3XFI22eHZ5c6vf7Rc+8Nryh677mEyRAC0YSSiw5N04B+7VBxZ9PaSA4F/Y/om9AKNSXt6HY+B7ZddtKACtpYocmkKDXq9x6CHfGE+GbfqN7Q910WrT/o+q0f+ElpPY7rHmAVKoPGMgHI/I3A75BYv09AGkzAOJLSVPP9uAPpDGnq+vNgWOSj78S0ixB9ymzXbeA04tAcN6bpU5rQAaLLODcTEj7OAsXLYYYf5mUKW3XLLLU5iYUABJjBwFnHVVVf5WQAWhDVdMHgaHiZceKAM0hi+fhqlro7u3N5Ue7uwYIqsV5b/+OZyw5VfLo88yLYCZfHO+5dd9nyB+2L6CweANUo71CAaI1JdmoxU1qCsjiNPO0rpZZP0vXb0v9z+tn3Ob7JR6XOjTbcvm+x4ULn19hvLM3ex1/NVPPpFq1QM1/2Bpg9tsSMpemqzN8BFcTnaWS/nSL9bNJq8xyYewxq/XET96A9aMB7F8b/ZexMwv47qTvRI6lar9251a98XS7JkS/IiLxhsGZuwgyFAQjIYk8xL5rFMeN98SSAzGcJA8iCZ+d4kLHnJ5IExZNjCjsEGA7ZZbFneZGtfLFlbt9Td6r1brdbyfr9z6tyqe///liXjBLVMfd3/W1VnreWeqlsr48yo0PhYKM2/CKUvg8NjVHx6iRicaXdNie9GjXF0jhV9DjE4f1P6GBt9zwWPmOajzCjFfXlNPNZpmS46/npaNYJh1IVY/4ljqSTc8O3Xwg4L/DgcRCz9OnI8y32GMp/WiRTPjDHhPkZP/tSORtdoUaeQLFs15Mab+DD6ZwpGH/zV6EOP2GichlrQD8ysLtoTIrI5Bca7UzrqGd5VhlU//OotejGLneSCfp5XA0DjzXH/1BXDKYz+hoaGXNQnPvEJWbdunfb6CWADQMPPOYL6+nqdX+C8wi/zRcCKcbZyYIEZnJjRechg/LWYIj+lVyNltAbP4/d27JU9T39PqlqWydTlt8nEiilycuCIdOy5V4YGumTFlW9ULVyCUZte/Mqyg+QMytTwK2L/M4/J4MAxVauuvlnmzlslU6rroYS9YP6CMnHR6JmOHh4dtcOsaOzLuYrqZuk6vNFSri+sssdPaS7YC024w+ypstTLVLlznBDOjDx1pSt8CWRwp/On4fpSTqcu6mc6WK6ysfH0k9r99rQYx1cKpCeliCHi0jk0hiifGtIxO9SohJhUc8KdH/1nd55/xjnjf3aiDJqnZnSeQyncSDUPgpbOTNOg5QwuqBeOQ7jlhuerhy2VRh+ai0CfqRG4GI5xVL96k3CI1EaAfk1GhJtRZiPAOpQYfTYCDAPfOhjWU7d9BcpUWZFd2oiQM3lSPRr/OGHs/JEe1ClW0dg4WKPEejSe3Hk1AEyYT96ebyI5H8DJY473f+tb38rI2fvnJDK/Fug4zMQvCs4JlBtWygjH9LD44qtNNMYUnRWTQYqFRphDjM5e7pQPq7eXtfaOFNEwTp88Lnu33qe96cZLXpWJptGtqJuhwyydbTukddbyQGX6ktpkI4za5aeJDvV3yNOPfVcmoBGpalkuEyunSHv7Jmk/vEuWLr9OZs6y4Zos1TTc+udGyfQifFLlZJV56niPTJrSlOnGcN+eH8hIz7Ma91PMBSxdsExmT0ODH/i5dhlR0NYeseJr3hCJbwgde0zqYs5a0MKxnSk0As6/5ElqSAGhSnD2FlLWzADLDwCpR9YIEJzAFFu5MMtMEoKWZOPvfIK0IMXNXqDJqJWhRtJI0Bk9n9Exj5yfx5oWeTyDuWaOeX7PUmpKitqUwg3K2rOrc1DmNlZLdeWkLHf9a8A5EM94ME1MuqfO4iM3g7OFHD5xWh472CXDoydVlxUzmmVWY21IGPRTRsYtRCqeDrdk0ZnHevTIbx0eKun5eyPgXwjKKjPsauQR5auGmFDGkbs3LoxjTBx+MgSFK4xw4icBi7qgf8+rAWBvnj3283U+GUy6L3zhC7lG5NOf/nSOHRsDfiVw/uD5NQA5dr+SwFB/p5w+dULqF60vkc9GoHrGaunueCZrAEqQkoiT6Plve+qHMhlj9I0r3qhfEgTXL1wvPdu/Jbt3PCxNTTPDl4C/as7AjEyskhOkoX6qVFXVwtjfK82rfksRR3r2Sffmr6BBaJT6BTeqjCHEbXjyZ7J43iWyZsWVgaG/cHy6I/cYplHLDecUXgjjMDa+Gcs83M2LS4zyihBPr0khfpRnuRAhkYvxjZLzKYpSXyy+YVx08oUnDsqm9jh0ObdhivzOFXO1MXiufEjzmLgMu2PebmnvkS8/sU/7BQsbKuXo0Cm5b+dhecmiGfLaVQscFU8vCT7dWU+bMfxPx+TVGGdGOvkSAJbVyTjmH+ljo2D0FnZp3jhEfJMfe/5m9E2P0MA58Th4nlcDwLH54oofNghcFTSWS40/l3amQ0KE+bh/Sp/ipPHn54/VkIWXVsIiH+uvMJaY5vI0Rp3vTzsmqNBdZK/IXX+3zXNw2Keco6Ed7e0CKPItmi4No+fad6xNTmAOYcZV/yEz/s6zCQ3C0Yf3SXvbLlm4+Epob/zUlGkX1lJRNG2Xr7pBHn38B9K95ctSPfNK6d15NxqYBTL1MmsQyL965hrhxPAzO74ts6bPlelTp0NdzxV/uiYIW5cZLxpTVWgEQg+c2A73tGsY8HSfgJUD0gK2Cs/kJvKyEkWqVTzTXtr3JEVMv9HHcC7HlKOlzDCMNtMmn7/KKslvlWNh7xFTf0Nz3UIwRKfSQ5Q+TIc0hn7jQV95OCFjO9PM4KZWnovDafz/6w93yLSaSfLH102TBY2TpWPwpHxlW4/89QO75U9vWipz8EXgXwHk6Jox1+iYLvMbVy8VQg71DsnnNj4jN82vlTtWT5XaSppdkY1tQ/LJxzpkSsUkuWU5l4iDl35B4cm6FXgTVyVqobvxjnA14vwSwGUt+eEg1DGwYg+e+lFT7/H7/gHWNaOHBIr3MJ4aUHprdNKJX+ppw09EJJfx4yz3z1FfDstw+ScNtzuO3TO+nHPjz3mCovEnPucUuKw0bVR8TmAsnuXkjB3HIrR/Frj/l8MnzHEd7vgGi/AYdkzw1kpq4bpmmyfhUFA5N4q5gMqKykQff3X4pL5e3SfIAL4mKmunlxh/58svg97uthxdxgM6Ua8sDN70N0+dJddd+zo5039Ijj39RTl9ol/YmBQdGwHK3t+2D3SWRudneWP8yDOFWz4yDQkcCBme45Mn/IqfwZ3G8RHWNHi4+DR8VSCRB6Y5eYSn8iOc9OZcFw1nMgmLOAwZHp/m0rDFFfA10srV6ANhgT6Ndd5pXFo/y8Pz2GOF8pqQU+T21c1tUlM5QT5840xZN6tGptdUyKppUzR8aUuV/DO+DJyejYB2fBDhcZTpqbdnzB3i/HBnu5DPe65qzYw/aSjrbSsa5ce7Dis9cUmv/5SThkMJuHzODdCQ0SgTX58gyIUJD/rm44Gv/ANdoDeeCT/yztFH/qZjDEPUuHHn9QXAIRlO4NJoc6iGwzQ02B/72MeyBK9fv15uvvlm+dCHPqTj+ezh06Vr/xn+sz/7M50I5pJQwjjpy5VBd955py4TfeGHf1iFrKLzl6Gi89eA/RfHdZw8DYvcsSMvbwRq6qdJZVW99KL33Lzqbc5CnxxuGenaKXMvf3UWb7xTnv49IFJRWSVjNSRkwLH7qhpOBFNjT1WBI4wZQVHCBEy4t8hNL/tN2bnrMXn24K4xG5iq1uUy2Lcj8A5pVvaeRy7TNFApJl41irnDYADgRTJntB6K8ADWPA78gcQX0NIY+KRwJck4IeR5GPW0s4UQVvkOJ6HJ8PxxSJxjoFSHGnYaYxIMg9xMuwK+6m9yiOEpID6d87OQ/XpqnCqF0f9c8CJ+Gjad0xjTaHfngLxuaUPOODvW2y5tkg//7AjG7U/l5wSYHvSCvViNk5WVyfHUnZE2fAG8fmmds8w91y+ok8893S17O3tlUSsuvwnloilVRkWtk3CA07inPXnt0UMhfYIf4Xwd8quGEEZc+iVAdvwASemZLv7HL4fCcBC/BDwTgDce3Hk1AEwQx/BppNlrZ8+eE7rpxPA73/lOWbRokaadQzlc0VPOccUPHfcUcOLXvwLYMJxtZ3E5Xhda3KSKKlmw8hbZ/cQ3pWvTXVIzc61MrGqU453bZejQIzJ15gppmmZ5NJbu9hJhrL9ptpza9QtMzu7TIZkUn8b/5EC71E6/SismK23qnAef5lIzxpgJmD+YLvue3RLgpQ9+rdTp14pxN7NGf+QaX1T6CsM/Bc0iPWXRMNhHM1+0cs4kUW+TGOlNvse7DuXheayi5uXCpEgdcYpxKfxi8XcNn5SFGPYp5xY2WfzB3mG5pLW8ES9HF3NfZPjkuQ2RsBzprOlwrlYKhEUuKXfHN1oz+m78/Rnxy8MNjxKJeQr/jsc4Omtk0jkGa9DHYx057waAGcANYPwv5971rndl0edqyIl3rrgZ87N4rPjLvbAsUnNWZOaPsQ7j04ylxaTxzpdUJqlY8PwSqG+eK8vX/Za0731EJ2vJobKqTuZe8lKZMW+NMox6mjauh/EzU8bNYzPmXiZHMUnLYZop6JHTjcLw92ISeEp1ncyef1mmifFwM2ivkYb0KyDlbPrX1U2VSRWTpX/f/TqxrMzDD2Xwa2XmqusCf06iMf3gE74qDNX40u/w0olg00zhuTkBbwTYm6IjbzzY/bKQyiPdRMqEi18ClOcmwnRS/qGHr8jEBw5Z0kfmxSWkBjfehkX8gEsKyHWZFhuhxXCkpzTjmXEzJTxpQSfTinQBHKgYM5YzqWNBzzXetIty6ZtaXSGPHB7SYZ8in62dNqQ5t9HmtlJ6zcNQZsx+pkXrCZ5WQhazpKVOtnSOyGuXFrnbPABjZzfWZDnHOuG5bRmH3ER5eE/fuIT8wEONtdYTy00NMx5BrUMg0AnboKTCEZfhEQ7cknjEkSP/rW5jjmFCaARy8ogxftzzagDGS/K8KLyi5vUOlQaRxCuHYxUvVmSnj/hOZQbGQ8RjJeVQ0OLVr3WyTIZhR5n+gqTyTIa9QnMXr1MeR7Z8RZ8TJlXJmVMj0ty6UC5ZdZO+IHkjFjmacGvMqJMxsDQRi/sIli5eIzt2/hSgiWhglunyUBr+3l3fl0osOd22Z7M8ueVhaW6eIQtxXtD82QuBCw294uuLT43pgtmDkfdlkBYfc03DSSNgWjFXcjmovGJesfHhOC1wwMoNMnlZLlkOqHwV5fxMr5ADik0GsREwDjH/TM8YNv6xEVAJ4GDalmKrepoSk0z8GEdpzot+OuNB39lygvDUOdeUPoWfu9+kGp9r5zXL/c90ys0YjvEePzkNjp7GRHCvLG2pwRwBl4TmtbaQpdiHgywU8g9pY56+ctkM+R8P7pQ7nzqmk8Cu5ZaO4/LZTcfk1mXYjBj4W02KXExDUEBh5mHZRgBgM94xfzLjjjpnE8NWeqy+1rEIT9BqmPEQSzp3ihtUcf62JBSNABoTHrFCxzSOJ3dRNwBeEF4kVkQey6fHpNU5hZufr7phOqesKiqCV1SHZlzTSoHICCeGySQDC9kLwrDJi/BJWE20ALuHp81aoZvIiD95Sp00NfvqK6vQZrTIIXJkyFOXwamX/hlk3vxVUoGvgO07H5KBZx8gSXBAqmqRqllXSg32DIx075Un0BDs2rtFli1aGRoC4KgxJwn8cJ5OjTdBGm8QwzFEYkKrLMrCBiMoHU6yXPFeHIV4I2DyokFWXwJXflmuWoi6pGP81MPyh8qYHll+OcwVhV6O7dzSsPs9WUVslQBe1N+dSfSQ6+Bh1yiGzRcl5OmLeOcWJrfXr5guT7X3yYd+2q6NwDWza2Rf7wn57q4+GTx5Rv7brUuUmWno+jPFpiOBmm+IYP7SmW5WR7mn4O1r58k3txzCl8awTK+tUPg2fF2smtkor1w+C2FQgNYolEX4MX7KEd4xGwHAfPOXSQ+NAsfoYeLdWJNpbBzO3ghoSikTNN44ZF8CSLHPIVDr8eQwL8a39+JxG5/aL5/8/INlE+TVpxRoWTA2nJWarnxWFWFFPlopksix8NPKk/eb7ISFvmRZWA2SvXiqJn5IT7jLyj8RX6Bx/P7+Lmk/sk8OHd4jE6a0SssVdzhLfXIu4timz6u/pXm6XL/2Bqxomhz4sYdOF1dUqA74Mf7UyfUyP3txVJLPiBPwoaPCwTHCnb+nwcokwpNwSCMpUt7Uj3o577HygjTuXG+G3XA7nLzo8mGTYZAIMzyLdT4Rx315fI91OR6OT9NzbHjEPBcfuX13+1HZcKBbjmFOoBpLNVfPbJC3XDZLJ3+dR5o7jIvh4E8aAINHDbuGRuWRA11yqO+4zMYegznYBHYZGgBPCa2S1QhSWs56DWEMOwJsADyXHabDO4QHGMPkmcIjb9sXQFgeP8SDh9EXnmDILwmlC/wVD/hVNTXyn/68/Lwn1Ljg3IviC8Bz3SqXhWJVZNhC1h8uBw8VOuD5i26YBrM+kMUUey6sKH6kNDGoR9pnsrBVUsLJX2kYgPOQ60dtCTdOwGdlh7HzdDh9Bk84GhY4gQaESuP4/f3HZNOmB2R4uA9GboJMv+I2wPOOewO4ke3U8V7pGTomj23Bhr01L4Uo8uOLYZrxhbDGAPT6hUB93UVd+SIzb55rH0DkZzmjw0GUSXqkI8KphuUYHhnctGLQ6InhPu1tJnnhHPiky/gpBZOD0gO+0ZOjcfdUpblq9P5rCmV4if7EMKhJzXQjILgU7nH2pJ7UIoaC93k9yO11+BLgvznLB2dWKsdk+ztAuGqkeQo/0mlxRsm0tdRUyquW23EklnuWfk8J65/Wmyz3DUIdyIVDgazz9GtdDqlnnSM/HZZRPGsMjIp0CGe8Q5h4YO9fl1kPH3GKDyH6dH7Jl0Q8UI58yYdcxo9jui5Cx8rC/7GdVcUiPNKVhxu+V9iUOo9vFT4PRxyQ+E/HB/k4r5Q+jbN452f6RbiHRU6OnpCujn1yAOcFHT6wBfsHujL+KQ+XqzrwxdSXc4J0dOyXDY98V45j05m+fEBIj4ogvjtuZDt9chg7k2+TtqOHpKe/x9IT+Hnea68IRJpOCNZnSLPrkcUhwvAtT3LwYEAcrr0/8PGwGYCx6CEX9HSZLA2R3uL0GWQYDhE8zw2HMU6v/ownQ45ruiucP4j3vGB6SsMamelnofibyoux1OPs7rngZ6PuGjqhYMsxx7TS8FAeZrGewzG3ktTCUMecYHw+N2I4TTH8IGJD67yNRxoO+Bn/ENaSotG2sK3pT8KIp8HP4I7HeIUFOo9X/vGrVnGQbOULmIUj3PNpPDwvui+AtKp6j2SsVyZ9UaySeZExdPYeFatIpDFOzs/iWa09xl4G/7UOcYQ5L8c36eQf+VrIwimcMYMw9jufvld3DFfWTpNTI30w0CMya95lsnjZ9cAwCpdv+RE5dh9rl6c2/VjPLuLxFVz9w2Ee7j8ot5v59KjF82uArre/VxpxOJ3z1UYOIqk/jTRfEJUNANPKl89ciM+CAb8cXFENnoEz/mAAePFLwPXRJwy299pdNnOAxt/4QbPQCFiElYppaHrHEg15FxoBfkkxxuTxN8BNkEqItIzMw5Uy6EdoIVcyfoS5K+JYKhh7/m4I6/o//8Sh3NEP181tlLdcPitMyDpP52+pLY21mCGc71NdaWP7jNH8RR6xIba8ZqzlaQbPhS11GYZmkOVgpI/5TB5BCDygdTUR8p67whGfhQONh9MD3xQLgqyzRi2AxTBp8HsGZw2x3pBW4zJcxiXCiX6Bu4uuAbjA8/sFV49nBW19/Nt6VlB6XMTxzh1yZMe3MLlbKfMXX61y8y+PqcK4bVt/qsM6fnAdzyuagL0M/XvvF49zxbn3YPjIU1gyepNHYbPaZFR74x6NvvPPNwJFuL1CUbNzgZsse9FIaY1MlOe6WAzxiBXxIzxycpNcDtM5GD/nFGxOiDTu+TjH57PII4X9Kv00/n/+w53Z0Q81FRNlCGv1P4MVOf/lBzvko7+xPDfuP5auO7GB7OvYRXywb0RRplZXys1LWuWmxfEOjCJtzOuYb8V8jPlmvvSX/GLYuadcDU6jzDriUhhmyfM/NeTkZXXJYhkmDamjafew01sHx/lQynhyF3UDYAXIIvRi8ZjSIiLEsQwaQ6wudDHGMCI3Mx8W65UypTAOKb31hgIHAEy+YVj1ZJyFWdWKcJM1QQ4+86ieEpoeFEcY9wucOflKOYDdyNNx6qgdG+0Gz3KEPI/jasiR4wM4str2JpCWvf6m5W/EWUFYdorv8BocCcHhoBM4KbRv9716aFzt3GuxsW0H0aUa10mSM28aO3L0oJxAo1TH/QnTZ+PJNd2FRgBdq7Jj/uDFF+lc5gS8NBTf+YfsZI/c4fDAhXCAl/8SYD+P+Y2U8Esg48GUxRIgNwsFXFKE3rvlboQTj86kOw/XzOgjXCUrvmNa6WsUtVK5FvI4e0Y893l9SbHL+/9lc3t29APP5dnXc0K+ur1Xuoa5BUrkg/dul5cumCqvxXwATwQ1F/IzhJ7GqqF/eGS/XD2zWn5/9QyN5bLOf0GDcKBnWN5x5TzLA83TkF/A8npuOea/JPcctvQoXjJun+YFMSzfQ+EqOWKt+x566WakUUyqh60CMnz/AoBIBVqY+Pl1/rbkk/FoNDgHAHIz+jxzCGHQ29xBogd1ucDdRd0AeN57kZjZK8Z62CoHQ6wLeWe1I/LJQxlKK6WFI46b2yJ9f/dhGR7s1CWYU+padN8AqdzgUCrvAeDhcsMDncqwqXUR8FqBYy/5IO4W0COiyxw8x7N8etAA8A4BNgCc5O3ueBbhLqnFBrDG5pm6goeMK5KjoRlmA8JjLHq2f1N3LzOOjvcbcEMaVwPxNNKF85brCaObdzwqe/fvkMkYgpKKajl9pF227N4sV1x6BfYOLFB9cz31szQCmv+Aj7mPgBlZMNAsAXshQZ2Dq9r40Uh7Fgx2LL2IM1YjYDUhLaFgrjKelFcGHmIJpTyTpCmNYUYyBAPj5ctwxDIfYalzrWOcaelYTh/h0ffwgR499M2N/5/8pE3P6uFBcPwa6MAqoDuf6pZdXYPyZ+uXKqHxtV8eC3HX4wfl1Yvr5V1rpmaMeX6QniGEoyPWzG7UVUSZPii7dDiIuWEaM92WO54DpntoENgIqAMnWvOQi/lnQFGw4zAu+mmsKZ9yrc4YBzb6uk8A7P1LQMOMB743FvoEj9gIhMYAccWyCdpcsI8XRQPgue8VkGGvag5Ln47HKhMdQwbhbx5mWFaNSyuB4UeKEaygObDtPhnoOYTeNs/6sc/maXPXyKzF12BnbpXqN9h/FJfKfF9vFJvcOF/P/Tm8d6M0TJ0n03Gz2KRJlZj8HcEQTPlTR133kydPyKH9m2Xvzl/IpMl1qPwnpbu3U/bvfVxm41IZOvbuq2fG+wEYx0agesYaGWx7Avb2lEychOpy6rh0b/qcnBg4KtOmzZOlS7CJbM8m2X94nzYYvlOZ9L277pFHNz8ijXWN0tzQpC9HZqQB33foWXnm0D7pHx6WhppqWTpnviyZbb1F0lsvDvmWZV2S8+q1sJlTQ/MXWg1E1kgoNzLEP5nhmRlsZ+6wiHu+cwJmlMjaeLkx8M4BY825eYsh0y2AVT3DYUwZzTQvA7Y+ijhZOsvQO51P+NLQ033q8U41/jwILnUrW6fIn/y4TZeGcmVQyEFF2dU1pMc7pMbfadkA8OC3TW292gDkchp5lL0vTC+IPL/MZ7lmvByaUQCFRKkmxEzD8Gs5IJrk6hK4emnUrRFweNbzB01sBNIefjD2IIhnAnGAyOMzYcbyAv99UTUAF0pZ7H36bjmJiaTWq/4P8Zu5OJzShTH7EyP9svjy12jPf+fj39Sx/anJUdDseXdv/rL0du3H6AyMBLajnwQt7wcoOuLSnT59SvbtekjxJ06uVZkcyz9xYkDaDuGgN/S2e3ffo5fVuD6kI/0QbgejnKuueqUOF/Vhwrmyoklalq3R+OHhAdn1zGZpWPIb2mCQzh3nD06P9MqWPVvlhitu0Gi+5DTS9298UDq6O3TuYVJDo/ShUfz504/LroP75VXX3KAvlPHhC8W31Rzp3QwwxvhZ78zDBrcXMb7yzsP5pfAIy+OnnFy+GysL89c4RbhDXJKHL7RnS42d7cNePod+nu0dlb++eVaJmjwR9KZ5tfoVUATuxxBPK46PGMutQuPxZKetLBoLp1x8LAeDxhKKZt5xHBZLxkvEIPzlsuHIyf2kGKMRQA00ox7h5cOp8bf6GASNi8fYJTcu1H/+StrLGatO/jU2vl5NIlb0ea+TmDHW6WLvzWJi1ew48KSu1mm96g9yyyzZc55Q8TZdfcMbwHpxYQxvACuO7XPlTTPO7ecqnebLfluOd+2QYfTQezE237j0lS5OvxZ6t39bmnBcRNuBrRpPI82xe3dc7dP15Oc0WFHdojeVcY3/pCnNcnKwXcf4q6YukZFje7DrGBPDOApi+sn5smfPE7Lx8R8qnd9clvb8nT+fPK66Y99PQm/KIBwaOtbfl2sACaFunTg8b8O2p+TaS1fHRoDjueHzn42H9RSR64jWMHp66fBSltsKxyuutCxNL6ng54OxSW/UmhdrZgwKOPBsOMoIYv/d+Lk+XicMn9JSiIeMKw2PQV3bKFO5qopRXw26QngWwwSZdjGVCfqY3uvmNclXtvbI767iKi6RO3EaJ6W24j6A9fPrsjOBOES0qyteEOOazW+qlu/v7FDacj9bsMO3BV93qcakNf1NY3bks68twCwn0lyOMZThXQClY5hfc1mOeM7E3OAXGc+RKmkEIJdGnfQlXwIldwqjjim+7SS2xiDQq/7j8wuA6XjROlYR/z/ba+NVKZ9RKPXgysGt7+gY9iTe8ECHVNTOyBl/x6Jxn1TVoMa/H8NDY43t+/LLM6ND0rTsdTouP3z4MVwO87c6Ls/J245H/1EmV1TI0pU3y/BQt+Kkxp8y2dtvXPoqNZB1C2/ExO8btOE40bNXvwo4B1A9zYaIiM80PbHpJ3Kwba/izrjhj6V55ZsJGtNxQlkNMBJPev7vO7xfqudck339ODH1aVjyStmxf69GMb+chm1A5g+vu4ezoZfA3+IT/Iw2ict4I46WJDinZdD584lAEibUTA59qd91Ziz9dPFp6S+GIw71iHw1zY4c+MSg4cUwuRSd8WNsEe8ATvTk+P+VsxqkH9cz/v0TmEuqmCALcEMXh22O4hIYHv3MxoGOZwFdgnOAim5uQxUmhydmeCmcE8HbukZkDWRYDlML08TChq1+GOmobcwFp4vPWEKWm8BliwvnuZvFQ5b72YrT2EUcGu8AD7KzsMYDjkaAvC0+4nP9P/k4vj4DHv3jyV2UXwBeBFZpzq04SMN+hDnnEGnTGMciheMbfcSnj9WEjpXFHSd1x9pgRRwaTGKPDPXK5Jp4sQzH6Hk0Mx0PbOOBcCf6DwvP6+dNXm0PfEQaG6fJ6EiHVE1pkOlY+jlr3uWKDwtXcpS0ATCpC3rBYp6B/T+X1ivepTeBOYzPTjQkLa3zNS28g7inuz3Xc6+efpn0bPuGfi0UGxjSj3RtxyRxk+UFLRpyY/j4oExFY1fOTcQmM7quvl5pwXHi5mI+xzwnxPhp7qrXwoEog1vYSkNxk3IzfohVUpdjFCy3FD8fJj8v2VjSpFQq9kphFJSt4jmO14t8OPKmRhZybbSHC17ujCdDhkEpjsvYCGeIjlDTheP+X8Ca/50Yu3c3CeCZdRXy0Ztm5e4BuH//gHz6sS7Z2zsiTx09jnN7quRzmPBlr/9afDnw0DYOI70VR0TcBZ7P9o3ilE875p09/6/i8Di6n+zpys0BmC75t001DGn0rwHPXepvaSyXypAvANmXACV6XilXRsCBhxpp9NQDmLlGg82vSMuiJMw4hYfVQKCxr0zDj6t+TJp+EUCcN0ZKPg5+LsoG4ELO9yl1rZhUteWTRT258Wp08Ci+v+fDkA/IaQzv1Mxaq/f1nsJYOieCT2Ls3g9sGzr8KMboH9UvCtwUL3WNM3HU9Gqty8bbavqEiWMX85lwa9mJ3gO67JPDRGygOEfAC21Oj3TLJWveqK/UUawg4iqgdJ6AcuoWvAzHST+gdOlQUP++B2W4c6dccdXLs1fS03wmTHx7uPisrbalpfFlNgx7pfnr4TGGfxI4X3Q3BWZKIrWbFosxQ+rmgwagPL7TB7uhwaJmEYf8osYx/lfh+0cs1+RE54deOkOHdzj2z5U//35NS874UzcOAf1434A83n5cJqOVaMCUQd/wcbn7SL/8GEb9D66Zp43Aw/u79YvxsfYhvdqRtFMwsfzOy5uFcwB/gS+Ju7cfwVLSGQQ9L+fl58TlwqwrXtaG5znvJcrStJ68Gn34c42AEuUbAYNzqedYcwJWtuTnXxjKZpz8jG0ZxkkCzqZmLPazYUVYxC9Wr4hDH/HyL7ThR/oivvd2cN76rJXSeXCTDtWk1zDS+HPopqq2Vfp7DmLo5VJMwj4jnY9/RjgO33r1H2S7cm0i+CvaINTOu04GYHzl9ChqYKVq5j1CM2cYW8ftX4O4iGaofRPG9o9gmKlR7wBuwJzBUPuTurpn5ZpXys4tD8jRDZ/IlJ80abLMnhP2ECBxo6OjUtm4MIO7hxPQ3B1M/StrsEQVE82nh7t1xdAa3CXQMnWG5pnjz5w2R7oPPVwyaUz48KEN2FdQEzaXeY6GHMfDx/yNl+/kDY2Ao2tP0krIKAHnOG8otGj03WCEHFP+yDXF449RZ/jhC8Z69g5nXRijmQhDS6X4ZniMv9UllpWZJ5fq0FK4pT39jbp4rGnuIT4nyE9wzPOxYUz0vnyWXvXI2H19NkHLFTvl3GUw4M/iNNBPv2pu1kBwOOhDD7bLZx87KL3HT+omsj+5fnp2f/A/b+6WwwOjsg4niXIC+Y7VzfiS6Mg1AGmOeco126EEe+r+FUCdPP+dxt8m5lCuhMJcj30JeA6kT0sh53N4hy8h9h+MflQAxjz09BWHdYdj/4VGAPg0+qwW+gUA/3gbAqLeF6FjSXppeiGfezK9UhiPyCflQJy8i3ilMNdhglRiiGPOJTdiaGQHxuz/TidvuZ6eQy2nh4/JgktvleNYt1+B9fRVzUth9Kt13X16JINNBL8Nk7N2lWPL2ndKZcM86Ti0GcdCcL+AmxLTcMLESdqj5xeEjuvPXK0rfI489P/ga+Kn2Cm8DnsCZsuCJVehMaiUiZPrdXVOBYZpDh3eKRs3fEtGsZS0Gpu7RtCjL+d4hAQnhKdh2Kap8pQsnLNAXnrdq2Xu7CWqD2lo5Jg3K5ZcBvn7pQeX0vNLg44NICey+cVw/WVXaYYZPmmMLnuCSebXcra8z/BheCnH/o1eZTBeYQV85eE8CTs7nDzoMnkaKoZNB8VL8NOyIX0+bDorTdDB/PjN0uyyCYnOeMUwfZ4HHvv44V65pHmyPIChnQf2D8rRIRjvsIKHRr2c47BOJVrOv3m4Q8/w57g+J4Rp8DsGT+hk8X+/ZXbu/uC/wkqiaTD8HD6icxm8SSx1lnrG5LXXFLIRAMRSG3PJ4pgygxnc6fnEv3YAjMZK33nFJxlHmMXTeDs9+WbhoF+cE+BgUDIHoLrGsCo3Tn4u6i8AqyIsCasw9mslYxXn7KXk+Nbj8FCkSWOMn3P1nknETX1NM1dKbdMc6dj/hBwfPMS6KC3YrTt93hW6B2AKLpKhO41lmlVTF2c9f40MP2wEeFzDSV4wj8lTGmCuDNq60S6NmTF3tcycv1qe2fIj6e9ty43bc5imdu51+nVRcWYUN4pdrpfP79r6gJ4HlB7/QAPd+cSd8ujG78jyFS+R9rbvyzC+JLjJLHUcLpqCOwpWrLgGk8+V4UXKGyG+NHzFeG7QDVfdLI9t3pD74uCxFeuvvlGmT52mmNq1Yu54tmo5hgC7Xe51TwYHjIWDnp5/mlNXytdxXIV52HpvDLl+ZE2WFjZKpydIHYy69ewZMkXy+EwpYwKfBD9KCmoGSYyns1yiLyRQuSiAkboiKcpKsaIeihh+qMMuHNVwsPe4nDh1RrqPn5L9MOx0ty1rwDDORLl7V5+8bWXcB8IG4eMPHZXtmMS9ela1LMT4z8a2Ifnenn55zZJ6vcwFrOS3ExplGH7Ii41G6loxX3AIjcBT7f2aIs4frJ6JzgbmEizNnn5Lk+2ngB955/lIfp6zFscYyw3PP81VsBp7ToByQB2+GJQ52YCP9/w16yE3C2dwzgkgHuRet6hHnBNgaPy4i7wBuHALYjImaucsuymnoFV/HK1Q2yLHDj6CrwBsusFk75iOlTCM4fu4fP2SV6ARqZaOPffK0UNbUEnPyOT62brZjLj+JcFnw+JbdNhmFOPxhw9sVnmp8adczgc0XXqbNi47tv1c5sxdKYdg7DkMVdW8SOUPtz2pcwVrV6/XncXxFeCr6i+Kpc5f1VYMC73qxtdL57GjMjwyKLUY9qHh9xcufpqSm+cMNcqHyc9fRELNOX4qnxAzvTaZ55ihUVC+Jsn0T/U1XONADQiLWOYzqKWviH+2FBRTFGlfKB8nfjn2fxmGed53dWs2lHP37j69hH0dDPy/7OiVuqqJ8Jnv3wAAQABJREFUMO428c4bu3gRDPcF+M1gNOo+Mbyk2eqlbyIr6urxnGNgo8GrJnk0BFcetVRP0qGh76FxqcZcwTuunCuX476Bs7mY46VYsbQN5mHmrDUWTmN1x+sgoQaPJciw10HnNlZYh3+ARGqvg+Q9ntyLpAHwKhELhz6Pfa4CM1xiR/oiTZ6fcWb1cleUVax4xHPsWYuvl97OvXJyqBMne+KkTWyoKjqu4ee1kBV1NrHGVUJ0egE9jDvH9k/0HUTv6TR49MOA36Vj/40r3pCtCJrctEBpBvuO6YmiU1pXarj448tOR0aGdGz+stW3yIH9WzCP8ZRMxj3HjQ3NsmztG6QGE7d8EewlQIo1QUip9sQtxcyHDA4/GwKG2Rljfjl9aqT1S0B7a64ZGRt/xccneMT3XDS4vuLwGtzoKK/8nAD5O288g0ziU3t3WTiIsiEHwg2PcEulIXiP35erPvecgEmI8jKJFgW2flwEI0yaY5eGaXinYV3/BzBsk7rXLm2QQSwBvXtPn8zAzVw88oH/7t59VUtm/D2OE8McBvrilm7h6iFuIivnPJ4NBr8cODzIISgeMbFuVo2S8CuDDc3nsbLoAzhmYmrYmGb5pSVsrFG+3pv3nE2gWa5byvkbOGj5Oa3nUr6MaNx1j4d+9tnXIOnV6HuRhy8BcuC/1iXVycNGZ/cBmMrj5Td2tMaLxr+UnixR/7fC80J9LraGxxcx0hdpSnlFXMKKjryMXx7C4yEuufI3ZUpNgw4DcY7Ae/rE5LBMDzZ5cUyfxpkwrsJhmD177io+0btf6ubfILNu+nOZcf37hWv22VhwmIiNh/Phs2pKvQ49cSL3bI4rgNradkvLtIVY2fMaWX/L78kNL32rrF5zq84PWHrIgem2F1HjNPFMaxKX+UMcgJ4fzocvWhZXBh5hxjuHn/GPeZzCAdZGwOcEyupGmTr8kKbH9CS962k4MZ7pJz97pn6NVJ70kT7iGszi+et0xIth8yNM3UL+EJrFM5DQMnQYQz/XBKPLcOrWL6zDUQ42LHTbyukw6hOkCV8CdDwCopzjhHEnDoubW1+p9/gW5w8YZgNBo3/v3gEMCcIgg+/b8QXhxp98OZfwnqtadR7hK08dDrlBiOcMU2Iujut7nOEQGksn4IbcsJIHHoy14XmOlYbZVmT4QT4bAcbpuv8EbvHAB1/+Z3jaNORLwjS6cH8vzgbgnMqA1cb/iy/Q2QvMq89YWKXiKcdklMKsuhfjKzFEtOyq35K5y9Zj4nUbJon/QYdrup68U45u/Hs5daJfqmdfrat7OIF8aqRHJ4sphw1Gzex1ueMh2DBwvwAbCTYWdFw9VIke/ORqjAPjcDhOTKcNDXEY7tr0BfgmyPGOrdjFPCjbtjyISWEbQ9ZXBMrzSWevTDGM10gTmH/FGJXiE8cNrsenRrsc3PDIn7ytd5bFeTgYccan/AC2cAZ3fYxXxqekEbB0kN5wTO80bHWLMRGHccTXOPDUp/66P4GH+Aw/wzPdNGgZGHkiklHmDI/hoZOnpHZy+VedRpju966aK48e7NUvhQrtOYMOXwflHL8aOG/wFzgziKt83nPPQZwg2iNbufYfz3cjzCNKrp7TKFX4TPg9LAelW4+L5su5a9E47cZhc+48N/Jh5F4wuIx3HMuxmEueO/EZcj1rBLwULPMiPXiAqcoIpUoZ0bgTHv4BZ7z/x0aAvMvnmaflQnuWrxUXmpYvYn1aZl8mK1/yLmnFJDG2fuF45VoYa5yxfuqE9G77uvTt+aFU1LTI9Gv/o47X+9AQ9w+Uc1NaV+DgN9zr+/SXcIzETt0pTLx5vDMAB731bPtm1gjQ+Hc+9r9ktP8Qdui+QqaueQd2AL9eurqPyMM/+zKujrSjAfj6BVukIs3IRmNkcH8lLd7jSFCkT19NwlOjTVgx7Lz4pCuGie86Ec5X1HEsnJqBCPM0xafzJ47hkT7KZcjpDcdi7Jc0dP60kIWLcQ57IZ5zcOfu1k47cLDIj0abrq1/BEdAj8p/wf6AT796ro7NP3I4bhZL6Ta2DeProEp78GwEbgr7Bf7ip0fk+xjvv3Zes54cemRgRFZMrdKvBNJ7Y5Pycv8ptO4P4w7iX8ZZ6dAIm0uf9HsNdH8eHmuEG32rFUZHv8dzH4XXqHy814RfJhX/trQX5RyAvkz48QKOnrEyl5gcG4wuo41ROZ/hGpb9ptT5lzzFIhOXlJfh1TNWVOc4Cb33mYuuU/knjvfJjke+KJWY2K3DpSw8n//M6ZPZ5K734H2yN6c0ApzUPYPGY6T7GVlxxRukvpm7jc9gCGiKrLzi9bL50W/KkZ//jW4uOznYgUloTNhd9/6MP/lx9/AxnCG0fdvPZO2Vr9EX6xhuFTvStkt3+fJFmTZtviyYfynRFa6vhiYIPnS1LA+sv2Qpt9zgpDVXfeBHaUlHOF857608130B/GT30tc5AtDr+DvYKn/w4tPO/w/6qUwViZ9Ib35GuU6mj6Yn4GX6mcraUzS48bPUOh3lWYzyBAp7kM6PueBpdi3SMDk6PXHVafIslmGnIybda5ZPl7/7xT6dwOUYvjtO0H7q0U5Zv2iqtA+cwEqfymx/wDvQa/9HHA+Bjry8dYWtDuLQDpd26uQw9hLQ0ajzJFD+c2/AjIZaeRtuEqPj5TAdgxPkauwH+PnBoRL5ioSfrZgM5saxgzhYbgIaD9ff3xNLcVYSWX6FKhLwLQ8t/2KOWTjkjX7ZhJqnX2ARz/KKklnUXOVj81EakfywDjqc2PxnHdNVQPo0HvCOC3feDUBfX5/cdRcO7NqwQRqw5vu9732vXHqpvehjpfjOO++UH/3oR4r/pje9SW699dYc6te//nX5xje+oXFvfvObhTgvhPOi8IoS3ocxWNvLYsBQScbALEZTDqtYrKJ5DIOncV5NLS6VzBivlvTz6IhhHA5HnGosD92/7UcyEUaca//puJmsCxO83FPAVUNYyK/x5Y53JuB453YoO1FWXf1mvVfA8shekBrwX3HF62Tb4zbnMKFistTOWZcz/uTBxqVu4fqwgohHTT8tz+59UuVziekJnOy5+5lN2EOwW665+pW6MsiNIOk5HpQ2AhqXvfaKYFmpDYVBMyNrQbQPKCN9oUNEQg8Q0ljMdYT1pQcowNJGQAUGuNWTsekJz6WH4iCf5eZ8UqNOaIRTXy/hQAG5rpNJNV5GQ+pIYdSRI8OEM/meHykdQZe01subL5sJ490ud+/ux+7cKukYOqWTszzf53XYoXvXEwdx1IOZA07afuHpYzDuE+SbO/r0SIeZgLXjfCAO6XAymUM/RTeEuQQeD+GO/ikI/tG6aXJkoE1vGeNyUl9VRDxOAvMr5KqZU9Bg2NdIyEVLlzLz91FTyqRaflpQOwwep+gGxW9AAIXneAZHHdCORuCmGWhA/VUjD5gO6JB50bHuaUXjMFFoBFRKOeQi8YUTLi3F59DtHe94h2K8733vExpuhr/5zW/K3Llzy1L+5V/+peL95//8n+XQoUPynve8Rz71qU9ljQB5EIf86D760Y/KwYMHs3BZpucZ6UWSNQSk97pRlheBVukcfFZ0xbaX0vBdolNb9crzMBnEIHYexrgJcnTvw3Jk34bIJPi4mSt1k7BxiyuGeNQzHSffenZ9v+R4Z67f53WOsxZerY2JSfZfM1INTbPksnVvkT1bf4zlmTgCAJPMRcddxcNHN6MdqZSf33+XGnMeJJfuDeBENU8a3bzlF7J2zXqwKBhB6GiNQOSeN5KgAI71rix3CE+/BOwFBCzLPMtJzX31FnM2wAOMGin/TIWAn5FlnoDBMBwbCv1L6wiVcHw8g1FnOXo89afzOMsRsjJ8X/fOmHxeRArSG8ywjJ/BA3sC1Jk0C968eJosa6mVh3Bsw86e47r2/t9dMUeuQ4+b6Bwm2njgmO765VcBd/FygpabxWigd6KX3jk0KCNY/F9uKMeOkz4hA6M90j9yUhqmVGhj8fIFVidvwmTznbhmksdOcHKZPPb1jMggGg2uNuKhc+vm8UIZas30mw8PdRa2FMV8c2DIPw8GHl46zo25ZFljMqyTACJjC49xVqOv0b4aCFRq7PNwVGAjBr01AsR3aoDGgTuvBoDGevv27bJxIy4lQe+fPfl3v/vd8olPfEI+/vGPlySXhpxfC6nBJ9Jf/dVfZQ2AG/877rhD6cn3gx/8oLzzne9UGRr5Ivw5sO0H0tf5jJ6z74aVBrwfRysP4vwfP3OHq4HYo59+7ft0eIdZxUPjup74rI7fE6+idqb2/HkMxATsEThy4ClsElujN5F51nZ37JWhcOsYbw9bc+1bZeODn9WNZr4MVCeEn7xLJ5yntGBOonkxziJ6HMNRs3LGnzw51NSAk0Y7cDzE0PCgLhFlvL0y9hryzQuvUHj1CPfemr2XDKdGmvi5RkDfXudn9OcON/kpf+poWrrP9LGQ6xdDrq9bEUuPp8o4ZfYlx9nT55Sp1AhzScFkefB5Pec2VstbL68uS3sL7u+9f2+X/PcNHbqLl8afjj396Rg24tDRDXNr5SM/PyIfe/iofOC66VlPnstCP/VYp8zDEFL/yCl55GCP8hg4YddKks9LQfst7DWor5qkJ45ymSjnDrgK6XvYj8CG4Pr5cSMaac7XxVw3yrHCjGcOh2ZT66BRWL5zCNPNOHEsbNxi2CmiFDYCxtthF/6TOp+z27Ztm6xbty5nmK+55hod3inH5JFHHtHodMiH+PwSYONAfgMDA1ljQGQOAdER9kI7vkT+r56zCsgXZfoSj0WW8R6jGkS4c6AMk5PyH+g+KD3t26QJPX2esMkhF/7TzzsATmD8nhux2CDQqHN1Dw2uu0os9+RdAhXYIcyvAR7vzDhO4k6/9r0K27/zZ/oC8Law7Rjy2fX0PXL06H7pwMasPVt/Ipse+Zrwa2Dw4MPZpDAviedqo2m4y4BDTzwDiAfNsQEo57yR4mQxXxz/J6760UvWjhVgfOFSOI14Fkbm5MLATcPk4bgWn/Inn1I49wEYDYAJ3OOMp9Gl8Iy/0pfCSW/4gCXpS3Vwfo7HOkD4scER+eGONvn7X+yUOzfulZ/utZ20zpP4dB42nowxevroKLecs7SVwsiHu3H/YN186cEu4XSpZsqHyz95kmY9eu/syd/+7f3yzu/s12OjKzAIfhXuBH7LpU0yCX4eK70Ux078+NkBZcEePxuVIxhG2tp1XBY1TWa/RecUuFGMJ4r6BTVMIR01TbWNYc8BRdMfG0KL+J4jRu/4lgOeg1YDKMRzxuHkE+MogPNKNJY2EWxP+jUMIY7P8Hhy5/UFQKPMHnrqOP7f3x8vikhhNPSzZ89Oo+Taa6/VMGHuyg0fsfFwXMd7IZ8spuceEkqrn39QsrDP7rz6eiUsYqvsXCQ5Rv6DPQekEuP53vNOURk3qRpLNo/tVuPLZZ2p8Scuh19OY5no1Mt/u+TkTsL5RdF35El6ZfdT98jx0ZO5oyJIfwy3jp3E7V+s9FxmqgfH4XYwDvWk8ngcxVjOJ6Q9x+KrYZ/Snk9sBYpzAsw7voLuYthyz8KEOk7M1ZibAaagPJz57fe8GguH8xmcGnmE8amfyjOu0M8NLSIIt1+jjxQA5tJH3g7l00p+W3uPfOXJvTruzh27g7jq8wcYf9+4v1PuWLdEjaPXEKMxHuRmklMNKRLwUMENTkxzzFfT12OMx7LWOmmu5oGCZ3c8H4gdC7QV6rDMX5ox2L/pyLAeCc1G4ueHsGkQ8fTz6+CO1VP19FEeRPdZDAV9B0dPMB2XQOYHb5ot8/B14o76eqros/TSZ87ClgqP0zT6C63l5mVCDMsby22jsNoVOXPMn0OOUVqEkUKlZfwZE+F8R3g8hJazlgbh48OdVwPAJD3XhG8x2XPmcJXJ+bkVK1acH8HzxLaKZsRatizTMV0scKc7Kzr4uAEzPKcyAV7VorjI/8Txfu2lR1jex3t9B3FURGUD513yfInJI6PpUkOtEeGnsm6WHgLHYR9ePJNeTel0nGQ+isPiJmIV0KmTQ9og0Ej77mHnxyMohtuf0rOFiiuP+PUwCRPJdQ0tqmU0O6ZzDIMbX75chnp+hEjNMP0hchCfECRwhxpeKb3DaRbYo+e5LiY78yj/DB7kub4pvfqVrKAvaBzflE3DJsfMEvZtDI2o8b92drX2kkPi9BIWrqz58pPPyv/5kkuUH2HeNMb6ZU0D5Y0F34mzgO7ZcTS71vESzAe8ejkufkfPn0ND7hY018j9BwZy5wI5jLt66f4Ix0ncgCsi6XicxFe3c/9AhTx4YFCWT50sb1jWqBfKc2joO4D/HPG8T2BWnTUunFPgGUC3Yw4inTRWhvjxnEzLOcYZloVjSaRwbfhCI0Bs5nPKNRS25qPBA7fQ0NtigSINtQk5TGOhoqNUNgI6ceyNBBmPA0e9z8tx6OZ83FhfB2fjwXmGF7ObUjcNvfjeMbPgJGCV9XMw/HNURnGOP3vsqfNzgfx4iBRG/0j3XpmC84Z49SS/NBw/xfPlpVXTVsvU1b+rN48R7o2L4/LL4DQviscXQ6oHJ4p50uiiRTzgbrK+PPrOgJBPvkylYb5QEWZ4Hia+0djT/c7P8Egfh4cc5rTGP8JTeYbj8s1sFOGEkn/UieGoF0MeNv0s7HEK1nR72hjz6IFO7fn7uLth2RJLnrq5p2tAdnfaAWoOO5/nBqyv/8Qv9kpj5WmdcOWkaz38XBr6sQf2yHu/vVk+dv9uHBY3LK/FklEu92SvPd3hS2P+/z15DOP2tZnxpw48TuLtq5qwzHNQD437CC6V4RASh4t4dtBHsE8Aw/s6tNRQPUUWTjXD/x+umV/W+J9Pup4L10qvPBZhRbiHvSY4Tqw9VmMt3kvda0oMl5d4Ycae1xcAh2S4/DN1HMqpq4tri1MYvxY++clPplHZ2D6HkriklI7PckNLOcJzDnixWWGdKxmxs8bba0IJsQOMt0vw2BL0EKG8tbo5hQHSkPGw34ZpS+QoVv8U7/klFePOwOA2X3q79vDbHvxL7Z0X5wF4iFz/3p9ojz3tmXOjGC96n3vJS+XUGEc/8CgJrhbinEE2DIWhp76992E38PYYB33Iu2XN7Tgx9HN6sucE3CHAfQZ0CxatlbnzV9H6oXdkuWCmkK9UmTB6bTSuviRSmehPyCnA1WW8GAow5i++ImjcSW+xAT/DscaB0rXnb9yMB3njT+UX4fp1EnmxHxj1NwOgw0FAsVSl8mkYgJ984eTpz8he3LXLYZ9yjpOwPDxtNxqBpVjOafxNftRIVVcYeTBe8fBzDAfBff3pw/KW5Y25Xj0ndbny5rvoof/hFS3yg7398n+jMfjATUvQM5+ry0I3HD4oCxsnyzAaBA77NGECl0M5RTcXPXueDFpswIjHJZ9sNHj89NYjfdJUPVn242gK3iDGg+BevqRFG50iT0+DxTM1TJel2EKWTsZ7WeTyg3UAZep80hyLpef8QhmBk+Jnw0HkTudcLET5/BpmfdOefwIn7/HkzqsB4HBOsXfOBmGssXofyuHcgQ8dEZ8Nhofpv++++7LJX/rpnPb5Z2a+0M6FT1Z08JDafspRKhQAo+Cvx5TDZpzhOJbRpbgpj8m4M2AW7gw4tO2HWIXTLlNwOQwd1/CzV+/j8JwIPnP6lEzEZTC8yIXzAZQ0OnAUB7/VY/J2WPcH8OjniuomXCHZJkPomTe2LsLR02ukB0NAo/se1Z57OlzEg+R47k9m/FU69hwsf6Ou/UftxwTwTWr82evn0RITznAzWpXMXbBaamubUMbNwtVEllK8WHgZz6kRQE6afedrzfzyvHI/nppZaY5RQQ9TFkKa1U4TEmCRVF/xyzYCgDjc5DstmBpAaa3EXSZD5o+mP5oZ6qaaBPlUkKbJDdeUygod8w+SSh5DMMA1wKEEd5Geso2XJgsIzp24D2NpZw3W86dHPTsPP93zUP+ofBg9dQ43fQH7AT6w/hL5yK3LZVN7n3xzS7ucPH1aVwNxkrfsElCcGkpXDsZ43gfQEI6iOIrdwf8RQ0icM+BXxfee6cJR1YPy/hsWETXnYno82nLA0utxXhJpWYTaoBUJeKx7eNiv5w+fXsKef1FiuTkBYlkHwfCtPoCzqkVa8tNAVO4C951XA8AVOlzy+YEPfECXaXKilnsAuNTT3fvf/35Zu3atcFknJ3dvu+02xf/Yxz6mq3/4RUCYO/q5LJRfAPX19cr/9ttvH3NfgdOd29MLlNjnVzDE9vqDUh3DOcBfe0Pz2CKRa8AK7Pr0d+6RzgNPyBBuAZuI3nNt8zyZvhCrfWauwjANNtDs/YX0PfMj4E+Qqsa52Xg9jX/35q9II74WFl7+OunGqqHejmfwv1sal71GanFOECdhuXLnOM4S4nCRbhQDp8WrX6u50TRtkQ4FHQOfqZe9LZsz4J6C6unouRccV/VwD0L31n/RhiSCJ0hz6zxZtupmXVp6CiuL7GIaXA2IRsBfUT/X3fIzNVPkZC8j80h98FhP3nNTS4SI5jRYiNNUhVdwTDj4K8zMSEkjAOUMTjEF/g5QlQhzF3QswEsNVagnbAiyRkBkUUuD/GTnAR1yKRpRGkke1ra4hV/ZMS9SzcwfjFKGZeHh0VNqvDmcw01XG3G8Azds8XRQns3DsXsuySSch7v9cN+ANgKcF7h5cYuswTHN3CS2qa1Pnu5w+Z5ue3KTGB15FPVnPPn34fyg38du4S/iq6MXS0VfijkEDhNdg/0GXFHEY6Kvwz3D5RylprltNSTq4nkR38L0DbN6FHoEgb2Z/nIcDMEkaiNAydpwGw1X+ZguiVaZt1ji5VJzYcVN+gu481GJSzrZS2dDwOGfD3/4w3LjjTdmLO655x6ZOXOmNgKM5NcB8Yi/adMm7en7pi+Hj4yMyJe+9CW5++675WUve5luAquqGnt1SSasjOcQPjM3bNpfBnL+UVkFyTznxuO50B3etvN+ad/9oFTgmsU6LPHkpO4Ieu+de38mvBSmrnmuNM1YIfUti9BAHJKRvsNY/bNHe9zDbY9LQ8sCmXfpK2QilmJWY96A4Y79j+Ee4StxPhCuZkT8lJal2hiwx35yEMdL49axaXNWKQ31aGiZL71Hdkjf/ocwN7AHE7pP6tp/ru7hhe9FN5ET0LhAfvaCK6Vl+iKZikZkxdpXyrSZS/VrZMfmHwsvljmKYyEOHdgiB3FsdH3jdDQENkyoaY8/mUlz4+Z5Q7mjp0axpHASfDE250PAwrlYvKBmACJZGXiIGpNeAW52Ir3mR/YloKHkx5lG/OgjmunFOLJw2LS6KfL4wU55+NCgrJ0Re9k0/n+NNffLpjXKy5bw2OzolEcMjgnb1z0kBzC2/7XtPcjPMzpmfxsmadlW0dj3jpzWRuAzWJnThRM+V8Io9x0fRUPRJ9uODshVONDtuvnNsqC5Wn78DM7qgWDe8+uORv+fQMvlo8fRsFyBr4TUcYMY4XTbMPk7B41M+8BJuTkcDNeELwHbbDaMfQDNKelz+NPcKKKWg+XjQg3JCPNhDxlN/I0+I8zzZNykysmy9KWvyPhe6B6sfNJuy4Wu5znrt+GpA/J3d/1M8UuLx9n4i+3h534qr7EZgkGe51lRgT3YfUCeffJfdDjHN3q5FjzNcwTDPctf8vt6TLPzHsT+AC4R5bk9tU04sCvcHBb6vEq+85F/lpHjOIIXl7UwnpvAaudeo0dA8yhougWX3oK7iW1YiWHidbVt10lhXkbfgy8JuuLqIMb17rpHhtoek2WX/4ZMbV3AKDM+6NFu2vA1GcG9wdwAxtVCHB4awmUxnHNYtfpWacX5QMwXy0vr8VO25ZU9j2PPwOatv5Du7nblzZ+F85fLsiWr401jyiOh1960pcP42dis+/klYXL59H9b210u3nH0GOBMVoEHCB3Pnh4OzwKc6SjBg14WL9LeOyBfe/IZae8flvk4LoHDPp3oOa+c0SRvW7tQ1+nb3Aj50Jk+Rh/5FMO8Cez/fXiPGl4O86Q9dBrnP8ewzyms1eSqnnQMn7CPo/GZ21iDy9+tnHlY2+cxds+dvKumWQftRzjumT36VnxJcI3/lWgA3nCJLRXnmUFfQo+fXwjvvrJVeLgcL55pxnHT//CaeVRVHecifow5go++YrlHnfVpqSWK5QR9MY4hD3tOhTgfgkvgKZ3VjICb5XLIaSA63HM+DZMP5xwq0NH5jQ983JiMg9/zGgIaB+nJqZgWbqwqRPFQipEjLQkQM7yvkTyH5TwZaZ+JaUwOFYE+DNVwSKZo/InHlTVHMAk7iGGhhtYliDFOtfgi4D9dypsVkcaFB8WN4nYtdMWxD2AQd8RXq7Ee2I9NXzgwrgbr/2mUB/s6pA5XUk6qrNIGhvQts1boP3k/cf8/6rESXdj1y6smbehoAoZ9NmA4aQdR9CIYk2upPbjnUTmOhmcaTiX1SeeJdTOzy2y24wjpG9a/Q2lJUW5OoA/7Dh599F4964hDTfwKOY0VT/txu1lX91G5/upbtREgveVAeGaFY7nC31wJFOCmBMZz8cLqxp0sM40yKFmAOywgs9+U+xIIurhuBTjLh/kVHfAhX2NQsWY11sp7b7pc9nb2yTNdfTrmz2Gf2TDARgX6gM+5FCtx4xhDzt2hopescIL2XZi8TY0/MTlB+3L0xLm8MzX+DvtT7Pbl8Ay/ILhOn8dGzMWREXdjOelDh+w4Ceq4FOcJteM00QHsAH766LA83j7siuQmnylvETaH8apIft1wCIiOQ0TcBFbInYxH0UM85rb/0mcpps+c4RiWw7wBzfIxKRHPQ1JHv2uEvEdZp/sE8jiUAzjLJTMSpseF/ntRNwBp5ltVsBgvVjMijEuhKVXen2HBozwiozyiQs0EEVAObQTDMZMbFxToLEgDyuWZw/1HpR4NQKR3n/H2EKlYIQ9su08m4FygadgA5pO6nAfgks7hDmziQ8PSibsEunC8c+ehp1QY5x0WrrwVcwmLwcFS2DB1nvQeO4iD4K5SWtMKPeaqBr18HuNQOEiO9xa7HhOkpweT1dNXZ8bfafism3edfgX0dLdJUzN3DVNzaAyDphI1IWdky5afyyQ0Gn7QHWnpePpox4a/k527n5JVK662SKVMcoCM9OXzVBBNIw0/gVuEwXUOIEPLPAElrBYqSwsU/XiGDpkaTh+eBbg1AmTtBMSDQz4wivBFrQ2yGP+eCsOwX1IpZ+Zb1ggYXTRIyhF4Zva4CojOja1B4y8N8vefCXrEaPXRYPPcfx7S5hu1ODfwh/pFEGmoF6+dvH/vMb3x6yBWDN3zTJ/8w6tjL99Zc4nofOwS9gbgF9gjcD92C7/zSuvYOJ6n1cPFZyncUkw814w4dKyl3ggwTCPt+WjwNA+LMUqBH9CwESBlEJDnyujQoSDJOHEvmgbgQisP3gk8hGMcxnKjmLSdPH/tWOCSeB4fwS8GDtu48ScSGxMafk4a83L3U7hovm7By7JD3ris85mnvydzsCx0BlYG0S1c+XLZ/ND/xlLQzTrpS368fpIbu/gFsBzHSKeO78PwACaOG/m1Uupcn5PZJTLEsVfYX2TCBgaOYenpa0sYMA01c66Rzq4tCuOLZs589j5aHF/QchO7kSmxnd5e/LPh5/mFNz+hN2uQ51fUqqifc6F08h8rHLmacYm/aQqKGuTDPOKBjkM6NOhFdxTj8X4DWBHGMIei3HGfQNeQXQTUgiGfdAOZx9PA7+3msM/YO4r5JfIjGH1uEuPhclxS+dWn27Dc9JS8HBPP/9aO+RzLwPK2GHadGB/LxZuWFOr+8fF8UTYAXrixIN3nkOcuPK0Iju7kOTJGGkI5tBqs9ulpv1fH5osbsQYPblBONRjnp1NZ6vMf4814HhU91HtIBjCnMBG9/yIvUtCAckkn1/ZzaMXP6CGM8RXVzXJo1w+kqXWx3g42CUMvl13/O7Jv649s2ScR4Xh72LIr3igNzbNDyizhNGL8khhr85pfQVk1pQ6YNHpMk6cKMejR9vV1qYzi0lONxA9PJT2GjWX6+a49OJPt5/trLoGPLtMDvKxRzwrCZSfr/kHLM93NRbj57EV3aEmJJMM9Kj9Lm6UzP9xFA+L8TE+G7SvApKVwyyvvvyqm0UNf++IhP6Nw0+QhhjmExOMdvoLdun+C+3hTxwnc7+I+YIovt4KHx0LTtWJ45i7c27sBQzypu3p2g8zBFwGXiXKCmY4Turx97NmwNDTFd38P5gyOYdhHj4cIE8qcH/jq5nbpHDyR3SfgxWGcnTo+Hc4Yw7Ffzy3HtDz0mme4Sot6orTIS+PlXJyDxzptgGdfAp7zJsFLwuWOh+eLsgHwgrHi9NeGsVbgBneoY5c+Mwx4lDIlV/Q0wkweoxnbNHOl9LRtwZHJd+k4Odfwc7jmeOdO7KB9QGYuvUn4leAukxXoudTyIE4M5TJSrr/nfgBW07EcefOAuNT4Oy4PmaPMHpw+On3eWuUzMtwnS1a/JtxHgOEqGO8puDqyv/uQHNr7qJLW1LXoKqABjN1z8ngUDQznNFIjbkNQ9+icQW19a/ai+qtjuXFGqnEvMR2/VFJ6jcTPCcZX1Voamd9JIxBfaeYSOOtjjEaADAPcZDOCDvhsBOjVbDRe/FWXGXmLNyaEhDzP4B5jRt7orZGL+yCI441Agk+jHljm4a6LaxNyLxiuOBxkNcDMleOKvH3tfPn0Q3uwoqhDXre0Xidsn8UXwWdxAfyUikk40+eMHsrGHcI8poF3BjzTPYLNXWcwh1Ap9+3qQHhIPoTbwnwo6X9sOCobsFJoM1YKLWqslG04LpoN6N044+e1mATm8RCc3C3uP+DREW346qDx5y5id+n8AE8F9SGnkB2KFlPkVPHJnIvwYg5YHvsbyNyjc3ytS1kjYBDnQByvq0ZlkhQeGhBjZFgst/HkXtQNgBeUF5kVsMdaQXvouZ5aUcozCqSRn+IiduEVb5W2nT+Rbqz6cUdjPu9y3NSlk7/O0KH2HMFk78Et35ORkaFsty572by+sZwBpRE+geMfKrCvYCxXUTtDTsDo73r8GzKAJafuuFeAq4ao/e6nv6+bxyZhLoBfFaN7N2L5aQv2AOCAOsRpLx0rjThcQyN+aqRXVwGdwr6CppZ4JhRfHr5+9sqYpCrsF6jFvcSDzz5Y0gBQf559NG/2wvB6gR5ZU2wEPIeVf4CX/RKgSC0E/TEF8MuXV/Gz6EIjQiNP3f3F13Rk5OBp8GjHU3poBQAxnMyMPFWh5iZf4WSgf9FkGZbh5WOpDjhBJ89Pk+LcRXcQ/6cbl8lncMIor210dxnW+P/u2nm6W/ifNu6TO3CyJ4djuHN3/YKpwuGhh7A0dSuMPDdvufGnYX+6Y0TH+/3kUH5B8Cjp7z+Dc6yg5pux8/gLm7tlX98JuRm7jukewRcFdwRzU1hq/F0fnx94sq0/1wA43FJvRedx6TMPt/wgXPMUzwi3cophwJB//Lqks1/mMnOUzvDjr0biJ3BgfbA/W1Tg4HHw/HUD8CsupFnLbhb+c1koh16m1ONWrzEce/sHt96Ls3dsYo/HLnCDF40th364e5ebw5qxqct70Vz1w41eEyaibxvoyrE/0btfOvsP60mjvgLnDG4j69t9j2x95MvofdfJCC4XT5eGGu8vy9HD20HXokdEUw/uJOaOY04aUw/uSTg1eiy8RlG6vVDxBV2x8mXy5OPf19NHed0lv1hOoxHh0tOa6hpZsuQKJSadOTN5/qIaPxpdDHtlGM4/vKwFLcxM2ovu9OTnjvAxGxHl5Zh8mj4pfp7eOJv+JiOa6Ugf02cmphh2iaavmyeP9fRm5kkBczAU9F9vXanj7Icwls9TOB2TY/lvuWyO/C80AvwKSK+NZA/+zx9ol2/s6pWXYKkoDT2Xcr4TV0a68acAjuvzC+E99x6SH2Jp6CiWlnKF+RNYEfQo7hCmm9tQJctba3H43kkNl/shH84FXAiOJVTMe89z6mcNcb6RuBD0Ph8dft0AJLnlhZ2+/hHs0BhT9DmGdhAjkwTNI63qOICx3AFcdG6IaCSO7n1IOnA+UM3sdTgaYoWicliEK3xODh3TYSSe0c89BFzvPxFHQUyqqJFRTDRX1bbKjMU3yKGduOULdwgUl57277sf1mKiGv9pV/9hTg2u5z/60P+UUZxQmhp/InFyl2cQdT76D3ISDQh76hxO4n/qjj78t9I6GxvFgmE1o+fG243cBKmrb5F117xRtm39aW7uYd68FWr8Kyoq9YV0eu9xs/dWNLoqSwsEP+ySKiW1cj+eAI05ZxB64WRBeSl/las8yU+FZHwpl8sFQ2dS4zN9iQ5877GbLhaX6qX4QT6hkd5kWQqK+UdMc4TTqS761NxQTadgUngpjL+lyzBZGx/CkRGXtlTljL8ywc/71rXKe2HYuXLHHXcRl3M3oZF4uO04GhS7I6IaBj0dzvnu9qPyyFkuf+dVlYta2Hx7vlKKp8gkeijFMEiEG8x+UxNNDNKnb6DlJOL1xQUMee849izmdUaRcfKzgVw3yhkP7tcNQJlS8oqVL0yrCmXQS6JIP3YjQPQ8L8Uv4RIjRmB8afwblvxGzrhaz3+WGks2CgzTIHfAIMPyo8c/pEc9NExbKo0zlsnxwS7p2vFtHSaqnomxfhjsYdwLwHkHOq4WKjoO9VQ2ztP9A+UmmNkI8OKZkwOHpRe8+fWQOh5eB2KZjn0GdPGV5CsYc9iNXBXmGa64yi6a7x/okgY0CoTxP9IzB53eci+GFS1ICvw5NKPeKM80cTjQC42IwmEIVCrQSvgrz1J+mWFRtUrhph3SQ96hkhjWWOkpn768PpGf8YrQPHWpJOrDWN4JsTZMyJqO8dfv/+XGLh4OR1fcUxCxuXLolCxDT7+c4/j+T3DzGOcCisNAHFoaPHlaXlJyM5iWAtiZ/s7XQw71eD4Ji/GeC4ZhIfPz13KeeWbOh4Ocf8QICAmFc1Ye7BSERsQxL/TnrxuAs5RQViEynFgl0uqVgROP0gYGSpWSKh4jXIL5SlACv562zTrGXuxZE8xJXW7U0klSNAAjPfvtfuDKWpwdtEg5dLVtxXlDj8uCy18vdVjjf2jnA7oiiEB+Hcxe8jI5vOenUgFjXs7xruHTI3Zyazk4h2pq6lplGDeP8XJ6Ni50J3r36eF1Sy5dL1WY5C2mNnnlFGZmi5SWE/WYX6CdtR48452DwTMzlxljRSZicOXCBHlO5+Hkl+vpezhDyzzG35TL2JWjD4oEmSk9jbaliOvL6bL0hNzQLwnqmjUUWfOi2MQ3FyizBosN5gQs2RzBCZy9GFLBJkD0/FfNaNSNYd6fjblA+gm6ISswLPug8Z8Wzv3h5rF0qMgJtmIymENKaUrZINyNnv+hftwt3Dkks+qr5HNPd2PCeUTPAiItVwFx1dHtV8xObgZzrv709DLs2psvhTi2YxgsYnj/PcXzRoBxxPRGgGHjYxjFsMOIZRhRDnEvdPfrBuBCL6Ggn6+lL6euTsjiHmDeE9C9+Yt6VwBvA2M8na3EuVf2PfVtaZmLVTroZbfMWoldxov1OInTGOtnA8C7hMvKwQojHhDHMf8inLxPYQJ66qxlshgbyg5jYnigc7OuHqrDqp9luGCeQzv6UiXK+2vCF6gIi2gO9RgLOy1fOn/tvHGIFPTF1zJySI2ovdxmLl2P+KI7fbFRMCrj6PJdrofz8hwa5aXwOGdxtvS4POpZ5JdqZHgbD3TJdzYfUMACHC3xLCZj793eJi+/ZIZUTpqI+wUGtNfP4aB1c6figpZG+T6uo3zrpSf18DjXj0/2zCehkfrbRzvkFYvq9arHz+BugIXgm+4t+Or2Hl1FxBu+3NH4/8+f78Wyz1F5zeJ6uX5WsxzFkRFt2DnMxsKXml6C3cT/10sWjPnl4Px+lc+Y66ZFufCvUr/nI/vXDcA55JobHBZ4dMXij5CiTw1cWSuXcoyGKY0lL579M9Yae8JPj2K9No566MIqIJ7Fnxp/wtkQcHjneNdu6T66R1cDHcNR0EcwrDQDJ4/OWIRxexwNMYC5AI75e8OhvGHgeQDdpMoanUxuWXt7BveGhfcT8JJ5TmIvWnkLyMxE+dOSjvTBo7kGY5IaSvNTGuPp3AgH0wxC6yUbp0ibhNH7JXFuXwA40XgTXwflFU40o6MkX7fPqwttHwA1INycaeBlQxhdgR768UpAn3jO4EDzOQZLeZRnfIxf2fQwMeqggabNZPqv5zBRUnpSbW7DEkzcIla8A+DzTx+T76ERmIwG4BrcPiYYzeGVkw/s6ZDfW7dIGqdM1gnff49TO3koHCd8H0BPn5O+N2Jsnzd+/QJHQFRh6Wg1LpThMRE8F4gni+7rxZHk2APwDtzylW4Q49lB/AL51Cvn5IaNeBjcX/zsiLxm2TR5/Yriwgem8rlcimP1Jo1JqZkneZiXasQyHMMKNeY55gTI00rBudkz8hwPvl83AOdRSl6J/NX0l7pYvcqxJG02PBgZJKixmipuAqnHGH7HvoexFHJDbg6AKIxj75y3iE2snSonZVJmoBMWGleJ4R724DlZ7LRH9vxAvwJ4quiujV+UY09+TmrnXY9J5EasMDqix0lz+Gbe8htl35Yf6BBPVfNCpR/F/QIc319y+WvAv0rjTHc3SW5q7VWxWMsH31Yf89ShZGOvoL9eGs4aARWTGL0kTEMJl03mBSNqsdAhwC3ac9mkkM7giM/KJ9EpMcLEtTLPEEkcGimDpnAbwUnNBXGcN3ioKlEfTW9msigDMMi3pZ4MuYkyUsf3lHxny35dyllcg/8UJnFn4zTO/1Y4FI63f3GJ6B/ftFw+8+g++Rss53Q3BRf73jC3Rnvq1+AsoHdcEY9s2ICJ4wM9w3IIR0WsxPDS78xqSIw/0yu4U6Bfl4sW5wz45cAJY95WVtoAuPRzfVreeWkwVHQhF5Noy0VGOH6kT3MYuYsC9IlhY2Bl6fjk4BQs1fHkLsoGwKrDv14xeBHHCuA+h5SX7dAwpFsGKfJJ08ANYTMvWS+Ht9nO4SmtK3SJJI9u5u7eaejFT190va4U4iUvYznliZvC3HFOgfsH2vduwFDN22XF9XfI4V0PZvsSaNRbZi6XWYuv0979pde+HaeGbsPuYwwHYdioCcM+M3BcBXv+5iyFprsbOEJSg84wXhcguT0mXOPUKBo8T1PkaPmUSkjxYYuVpcMZTOH6jioLQzQ4cQJheDAch38Q6YhhzD7DJymcHawLxqYeY/AfTAK8akg8DFg0445q+IkgANwxz4xXsYFzOZ7ebgy3rJ+fv7mLQy3Popf+yUJPnNy5KWtzx2G9PIb7Bba098mXcKR6/8hJHPEs8viREXn1ipmyfrFt5PPkXYsGgf8eJi9PAdPNe4jpFoSJYw0kP7wLgPsGXhhHyeaYr3QxxuPtGWGGkSsHAEntJt1xvRFguJR7pCB8PLmLsgEYTwVwrrpy53Allna277pfumH06TiBO183jS3WcDX2EHC1EI16ccUOx+9PYoy/NkzQKgF+2Jg4PxpyfgnMx/8pDP1UZIbdsAnnTmG60pcgffkNP/2NhsFii2HGepy9loZnr5b9Mib6LGRGL8ZGfKd3I25cx4YbftSiSJ/C3e/6mMkxCZ6K8vTUN21UoubEN1PEpsGc+Yqae9iag4CKB+OPj7GGfm/3CT2EzVf0RCpb0cMrKQ/32Xp9bhD7KC4kIi+uyZ/Kkzq115JSPbd/XmM47RNj/uXkclURl4leDM5LbLyl5aJtAOwlseL41yoclxH5u88h5auDQvHj2NHj+ISwD2LO8bhXYMk173CkwvOM7h6uwVi+3hS24g3ZZjA2CNwfUFk3o2QPAJeCFh3lct7BNXD5PoRiPVkzV0ZrmN6T8p5oRgek1LR53zf7rOYndoYRcT2HMiMfMkTD2gtnRMrZtFFTqCDTgPjR6JIC8nRIJ47Jp3CjBy3+sjkCBDJTxU+M8BUQ4b75DEQKN13I1+QDHj55mH9Rnht5o9N8CPlBDvk5DeAwp/gloAY5n+MM8XrJJpz9w1U1vnPXNMG5URjTH8txYrYOhp7OchWdA6wc4r/FuawI1wxSfEuDImrYINXQZSqug/zenv4SXYh7P3YFX9LC4z2cE2PpLJ3mfz6/xpFc6BgqurwEzfUcnsGN0lPujaByD19j5Kv1Cb988n88uaxOjyelz1dXFkn6f770z4XvvCOeV70YU86X0dFT4iKPsuAE3+CGzy+CGqy+4Waw9p/9tY7Z84gITg43Y49A0R3v2i5sNPKvsL805GlVOtVBjSciGGf/Jrs0bK8EZRJmvBzXn4AFw2ivj79CUa7r5q+XhsEwF1YZeRraYfJ2ehpd0zHIJkxlW9jghq94Ae5ycvCcfEtf5E+5UT9NOmTT/CovlUnj7rI8L0I4wE0u4yIv10XnBJJ4LyfKunXZXB1a8RU2jONwSwdu/Eo3czGejpO37I3PaajJ8opy3FE+lXB9QtDBeJqOSYTqzDDnDKgH7wDgiaR0fPJICsp962UzNU5lqO+F+rFcM63L82QK01TmS8NgsWQiD41DA5zSew5EfhH/QvZdpF8ALIaxq5RDXujCyvM9uw5ppSBd6NCl0YwNYe+LW9BjU2STjV4qeu7zsd6fdwnwGkm6kaEe6T68SecLanFOj7v+fQ/qJrBFa39To/yl98oc02NpiWF7reyCDJACTFqnI7M0bH7GRQ7EdXmE0KDFHpbJixxJZyGjCWFYWQ0nveEcTypGZ+iqH42uXgKT8KOxJip1MrhSRcIAJ6McPBIGggI8CCY5aZkCNgLa60Jk/kvA5Tvc8qNsepwfGyj6NZnGn+Er57XK4d5BGN2jOv7OCViu6KHjFZN/gote/OuAxvhTj3dJc02V3LjYzooiDy8B0lhZ4anCWFReFoQG8RmWhy3beeTEH71kIW4SO6irhoxC0NhUyfsRz4tg3AX2lpyggcN+uWfMm3J8LK0pJI9vcItLsZIMyUo6lEgO7UIOXKQNwIWc5f82unE+gP/uKiZPkQ7syh088DCOfGiS0f52HcWYi/F+3j38Qjo3IGfjWcTJv/xG6TgOY2w0TBY7dpjYRUrSu5GO9KlRN2NHrubKhVN8k5HHT+FRHvnRiNiw0kT1pfpEeUYf9TOqSF+ElAu/7rIFsmpmk+zp6pe9+F86vV7WL8NqngOd8mEsv6zG6p5aDO/w2snFGIb5d2sXBCNmeryQv8vQCHzkFcuF9wnwfoFWnDCaGv4XUtavipfVw1+V9Ocv9yJuAOJLadljr0maVWlMETvFO1+/82U/KTqPjTGpT6EBRalSUuUT6enLgVNG8Of7LwbkKqHmWatwFeUeneCdhBM8G3ALGFcYFfkV6Q1OiaaD47th0i8BgLMwfIZpWpoRpc4Wtn57NK0uz4eC2DPO4iA19jdTfuZn6uzsnSSs8j0ctGVvPYzb540y+aNRQG+63H0A7DcTzi8Uqu/h1MjreE9hTkDzAmSKj/REfEsZx/bLzwmYPKfX9IX8oL+YM5rr/BLQ7jnTHHNuUWtjuF3MKAnlHcNtfYNoGAZ0ff7SFmzsgoE2Z+Xm+U18usjRwhTlXwEG16yB1yhMR8ON8AnJEtEIK+cD+8ApalAO7/ziNEcDiZZojtwlMZLyPdXmc30cwnDkofUVZUAeKR/SXujuIm4AilmfFo0VZIoRK10a+8v5XYpJ5q/HnJ2v6lKiUF7/EnCBpb+0aXQljH3LvCvKVFJ/8SN2kd7kuQ55fMVVA2v0pbRuUgzuIX+J+Co5DeXQ2MZGgLmWgwIhcrA8RRjyy28WU4ZKo4aaqdc/N8qestAIEF2TWcxhhNkIEBzg0agjMtfAmM6BUVDR5ZGDpUcbAQoDa08voeZcvsk1uFE6fSwF8BujETAd8vk3q6FWL4rJS/JcJvc8PpPrMU5DnS2/KSFqYnAv0Qw7eCz/TEKWO0Wkf4NwSWpyMi29jGIZUM9o7C1sKWA8nZYUG2lFNxoFjIOfF8UkcGk5sOC8MkYoi87/Y+wv74tVwuWWyi5KUZoxlTH6McGBGas5/91xXoAXx0d9HFKeX5E+yivFVzkRAYztpXFZqR4WF+EOc3nKJhjbFNd4Op3rcC7hiKMyaCxDvtCIq7w0HOAen9OL+CX0xo8GwGFGw/rkMJNj8szP9GRh5ZngK52HyZdlleBr0QXeAZcJUR08DJyYBqPPygXyUqfsA77j8Bn9xC6EjbmmkdAQpBeuPP8Ulsc3iP+6Pim+w16Yp9UAS1Epx6L2+bCnzlLgMHYMwodgKcMLNOZF9AVwgZbAv4FaR/c+rDuJXRSvb5y78pU4C2iJR/3Kn3yV/EVyZTzOn2m8+0ljrzKxjEdpeCwI8b1nntIrK/2J/C0u4sewyYvh3JeBmsWYsjy9UXKYyHpiJi3NCeJH/il+1CxqbumxMPXxLyXTzWKin3ilEs2QR40j/q99F18OvMgbgLSax9eGxZyGUqznWwX8ZYv0/urFmKLPdciGd3MIkb6Ud0Tc98RX5fhAhzQtf4Oe83MSG8J4Efz+p7+j107GIaHIL1Kbj2aHhsidyYv4Lt8NlQ3HmPkhjZuwDK4xRXhq6oI/9Irj8IjpEM0adSCfICGoGPEJde1NS8MEBbvKobuW0RMd+PYAb/z5mL9FEtPknXXOALx9eCQwUyoSKz0KNDYSliv6q918yg06gIp4LtVUAyb0ZjpUQTxjflAaQpl8w4npM76On+4sdi2MA3+znCjwVwkq33I/IGpeGn8e73AQR0TUTJ6E1T5TZA2OiMjzY4jUhm9aMi7vDGqYecgLFXIJnqY8X0+fa8l8o3OqCPcyyNOPh9DzagDuu+8+2b59u9TX18ub3vQmaWiId3uWS/SGDRtk48aNCrrlllvk0ksvzdD6+vqUVxYRPNdcE5crFmH/OuFYIYv8WeBe2EXY+YS94pDG+DnXFFLKUeWXVSLSlwP3tG/FUtCDuYtceBYQ7w2YWDlFj46on7ZEJ4JTfYI5zSlSrOImr7x8xyUOXWZwLFjOZAWDYqaOr5jTKAkaAjfqlJgZcfjM5bCB4PiEGgUxnDLjnxlc4hVzEGEdJsFTk5nSMyo14nl6xSTv3HiA8ecvRXl6GDRncAW61wSH37RUHCE+TTtVVNlFo2/c8+Gz5y91cAxSmxSTkIaJRWfpFZwJNCz/G8s9D+JsIF4uQ/e9HUd1s9cfXDMfu359U5nR+K/JiyElLPmJ8ktAL0iEpZisLFWRaZTs6WVMxDO40Rsk0l7ovvNuAP70T/9U2AC8+c1vlq997Wvy9a9/XT7/+c+P2Qik+DT2t912m3zwgx+UO+64Q/Nm27Ztcvvtt5fk044dO0ri/vUj0uLLV4M0lGI9X53IL/KhL5VQylXxHSUSBkSjL4KHcM0kr4ksHgtBovqF63ER/E9lBF8HpSuB8ubCtWEVpyOULsorlZ/aP+KlJtqwLcb5GGeGyDdiWDjPwXnlObgMo6By1lNmmM54mN/CJoV+l57HyeeCaWXDNYbPnrb25J08yCAXdbkGhlKSRkNF5eUVdTT5ns8x1SbGDE4mCwIdX9MDABsZd45tMZZycjQHU15oNNO0009nORDlOD0bAh4b8U+PPCt1laLnDfnRD9xn8EkcNvePj+yXP7phkYlTXqplCJs+rq1r5ciMtziHOKZjvFBP4xvrVeRrGnr4/2/v62Jtq6o0FxakCrlS+NPYzUWxK0aQVDr4g3R8EYRUyhdRU294/Uk9CZfH8geS0gf5ezCpyIUX0+GCvBkF37qj3NgPXVGMxtQDyku1lIAGNQWi3alu9db8xje/Ocaca6199tlnn8ve+8yZc/aa4+8bY4611phrr7X2Wq4HjuLjhHhYscn3epf7mgBwJP/444/bP47ib7/99uHEiRPDww8/bDvNCyMAACjlSURBVP02NBT3qA/5ddddZxMAJhB8c3jyySeHa6+9dnj00Udb804fMAO44HtBfinMFNQF6UUyuDDMF9BPaZxbnnYkeZ2jWz70WZz0CQ53Wd9xfbfmLspi4kWTNip8spui4zl7yWGNBtpP75Bm8VWhqOXi0npaf2pUjC9K6J3xEI0jZG7Aj02UjzNK26jGdK092FM9/296Z/SXbqwf+4ynfp581xvsR2D/lB4y91/Sc4Z625wM7OsuIBTrq666qpzCQQG/6aabhscee2x2RCdPniz6UNLpH0wOaFiKZ4yN+dDuMw5IO89Ysj8OcBxr3p9Qi74bSZSWbi8xjuz1usegaF08y///pxfKxx+LtTrFXyNg2XEm/bl/SlLJSQI7CE4M1/FSBBxh+ZLW1Hc74tT6ruO+3Q+cMgblhv6AzxiK/2QkmeJAkY9yFPVCJxnprGP26Ed+TROP+kmNWBZfHUvBhaz4zPohX3h/AeVA8z54bMk+47scMvrznECaY0j6ljOwih6xjZU/5APjxT90n02nf95y8QXVM/9NlD4wCbw5yf4lXRegPiVuL835ZbRT7PPaB5VohDUOsxd5HIFn/PAji97X0d/XBIBvADjvHxvO1T/3HB85EPno61tC5OP00bFjx0rRxwTw/PPPDzfffPPw7ne/e7jtttuGZ599Npq8gn2tcq1iD0Ubb71hunw/PceQv8XW5tuNgrLbQ/zn6QmieKY/XgTfNrxMHo97fvUl/itgwy2KPuYpV+0uQh36d/1MZwYW0nMdLzDA5D+CyEUp2mQA+ZY+tNFEUy0UOnMmPOe7XoozEfJt6sU/9KM808WfmXKyyzaMJeAZdpwcFEvWsWIvfc+hCrjH5XaWH+DmiaIev/TyEoU9NeGoTJGmTsw3c2Em6OYmTPGJCcp1surEwl6ajjzaf61A+73xoLeMrxqdHuXZvbRaLW1rfSJax3ML6jq9Pb1yCuhXv/rV5GkcDOWKK64Y7r33XhsVTuGs2jCBnDp1yk4B6cIxiv/x48eHO+64w2Dvv/9+u05w5syZ2esKq/o/mB02nenND9zlN6zpKCKyzq3O+ROCjq7NdxUAY311enroa49fM/xrfhE8Hv189g//Nvyf9B6B//fiM8MV1/yNPTuo9ePjESjPbooq/vOoVUI0Bp5siTtF0kjB6poo8WFFC0brp2iQTciUB9ejJ93lUiPQirEREf3iwfzTnjqMr8gTsz6nTwl188gt4amfSaIXIpGwST4Ki7RhWFenf4RdFDNUtqfT9Jnt86LQDkjNLFc+iIpPZtHsUlB+4ZkGyoYyQQtAal0QKeYf0oAK0tJx/OILh//x8/RS9/Soh/blL3jo2zPpYXN/dWV6C1lqXLOIoW30Rw8hza2a0R7tpHgB070sUDIRY6QnWbmNONTiqMRzrc3ulQngwgsvHD7wgQ9MRvu61/nLJXAhd5WGi8V33323XfDVBWDgPPHEE1boNSHgWwOuCUA/6q3is9sMw3982w3pRfBvHl74538sz/0/lu7/v/zdtwx/Fp4VtEm5Ynmaj6iVcweEPgvXPM2iQjl3VRVNepN93I0dza1budPAi9cArPhaiZSHKI/YkuObgn4XQJ5LEIHKL7jR3sdD/z7KVqulo5dpVGrAzkdaW73nTa8b/uc/v2BP/fy7//ofyiSA4o8ngeLhb/38f52zTaDKBHDRRRdN3o0Tg0Rx1rl78V9+ee83+qCY486fe+65x+4eki2Wl1/upyBAYyLABLAMLvTPbYubf9yNpnbF1SPzHU3+al8tsum7URbDlnYo+Isu9E4dkdVwxCLauAi09rT10spRJNqOkJN9YkgHwaqkRXxgKn6VZeiiGQ2s/JXCi6JQI6Ks4ZQe6vvogVfrm56+rphH4irqeTmLt76hmGm0TzCG1PwOgHpMij3/37oYP1r2nceLyQHx4pMtysEJ4zUFrZ2kZ19NEp3GhhELw8dvBsRPuny+UI1IK1kwBmDhFs+/vfYvhv+WXi15639/dvjPl/A20P/94r/ZC2VuecebzCM8wEpR0WMZZSapAV9oGimpqCuJNKWx3FLW0N4LASNWJK0uo10GBTqb1fZ1DQCnanDKJjac1kHBnmunT58e7rrrruGBBx4YFX9MJriLqP1WAX57rWEO/5XjY7Xrv46i3UBq6XJUjRE31Wl708dHZejxSVSJAxQLbmBkKNf3GJzn+q09dejf9TOdGVhIT0vkNIvTMtpHPvwmOgPIN5ZkMVbS4DW0OXDdkTxjR3vhFl5ilH7wSyzGNifHeXs0XvBlfBFfF2LdPvuCTxTmxh9ts2xGrryaLQwKBrHBgYyNubE4DA9c8uQr0uof//ML7b3Cf33lfxouSmcU3vCai4aP/OXlw6fTu4bji+LNfUJ0LHptaXKnP4UxLa25y+hq5LVlSzHCKd0pXmu9ifS+JgDcuvnSSy/Z6RkMBoUadwCBr/bQQw8N3/nOd4zE5ICj/k9+8pPllk/cSYR/FH1MKE899ZSdGpI9fjeAFjElW3a5nw1pWczFeuPVrxiW2fjmsIVB+dhHa1f0R05r25E4A6ngTOF6DMDKBaJRbO1LPCP9ZB+CYNcLTMSPMvJbvRRPUlLxYgyRZt/lmTZgYPk/hgM2/xMfuKWgut9iMyl3vCn7UvRzYS10KbDB3mIRneOGXokp8Ip9jDnKMTphASPS1ANH+YOuGv2B8nVv5oEmNt8ihvcK3HLNm1PxPz5cm94ZjAaM2Mb2LnUZeaRdrh74ra5kqyw5ujjyORTPUtSQfeRter+cAlomUJyeue+++wYUaZzSQcOPuGKxxm8CbrjhhuH6668vEwUu7LbtkUcesd8E4P7/W2+9dbjyyitNBbeZgqdrAq1dp49eBrCT1+WDORBfS2UGu2csDSwSkOr0iDSJSzk9oESO7aN3R3Nrl8Oe5+Dlo45Ocljwv9aX3I/Mon0bGTAUL/2Rlm9FqPha+0jLnpNAzJ/QYiTgtbT0+nJ7MpBOV8ZjseUDx9H/Ou/fx62fKPoHLfzf+6efDf/wyP+aHIh2g0nhWpnYNeq2Dt81xthH9Gi6tUEQ03ZWnDRRSOaa27mO82DFwhLtKW/9ZjobO4bsa33FJCzpFzozoBd1vU/cEW12tEE3ylGIjU4CLP1fdF5OyPHmsaI/IYfMdNI1Afkt+snvq4wvDPkLuhVmlGedCjfKsWZqHKepN6YTP+GhIVbJ0RvTUa/WNf2Mgz5aa0+u+KBaPGn4UhjOGfeoM+bPceh1Thr5WGts5194bHjn3z0QhRvd39c3gDiSdRZ/4LYXg6OvdfW1koC3341hfzEAPXojdVCfQiTO2EeMEbplPxs5pm2NF625e/tm3cqUPwHHS4rQhSULjCwtnrKrS0Z73SIa45nSh5Uib4/ljU7HMoaYPqjLuBBPG1FFwy7bKF7JNbLZC7sywHFUc+G4+iYwIWeeEoANliMWHJjltIkNKspzH5gYcSM3sthjbODENRKzk2Q2fo5Y/pUx0pnSaRybWFp9DqPSz2DCYlxwlzhl43SPvrbIw+jQYM/4jeRw2S2fzETxUPix43iRO98XGjRkO62tfE5LN5m78gSwyYNaJra4QuOKXsZ2OZ2ISm/r8gkcostHRPboxLV9TapFDAY1HK8IrYPNGg27ettqG8dyPS8Qci2UtiCYBytCtNbuNKVPv8RmYfDSUKLIBUbxc5zyCh8+LvpIdOrwPvlaziKevaYYDVMDqvICDOpleMtbNQmYfjFOjsLpHzPN9gghNRZExkbMKEc/NxRm+2N8kihLwhFNK2VZGIm2u4MKaIKEBRr9Fsr80Z7SRm42U9ZEQwbiJEBrGEHCcbNnZP4wK+u7fpQfbt+9z/mxLaNkbE5r0/hHdgLYtBXR41k+A3sVAJYZlRPHlZ3k0GBRlM4c7bt/3QNCnhRyqZScS+GBUlMUpGE/NUkIR8VX1u7P7YWoZcRzfI7acRUhPTBbLGJR0/XlT5G0kTm/97YnA36taXtiXnuk2OC50a8dOgNiN6rbQf3V9mP86M10a4Mshh1tJ8VZS8c2ERN92LgdSk2koUF81wFPOq1+opOiHUSbjo+J9rU+YnJ/6mOZx5OOUt2v+kFe7DV+6hT7IKcf2hpmxoYuim2U2zN/EqPmc8w46rX/PL5ob/pBTnv3SbuxP8WL9xOgL5oxwW8aXyIkA5/TlnjTtKmlD+mDFob1kz/y8Am/jXyCbrcH5QMI9IMeGvHYjzL4jH6lwSVjQJ86tdSp2pfz9+rJ+2L0vVA2S94ngLA+tAGtuoEEqInueLORvwnlpVi1/Rg/gphu+lCBjTLtMDVerQEZ9cZ+KHO502aU7dTnMuK5PrDTzp8ZVcExsywvUJH2omFFDzqhoBouWPbPMQhf+ipIhS6FqNUHuBc95gXY4DEmOCLtPuW7nQRa+1ZecMp43Lf7bP2JZkw2ueb4mN6IkceDmHNhB6eMpfTBEz/rIiYo53ygRzv02CiXbc0DJX1iU66ciBIGaa0PYkpHS8Uj+jCWjOAwkM8tZp8AZvJdb3AzSvtm5+JgRcKN6w3f+cv2PFbhL7ZUga21fJN2vFrD43RdabQ2Y3psI9tYPMhLugFgXCCIFeOhOoudMCRXQWVR8cIHvaKT14nR6cN9tvr0wRzmfi6sxIs84gDL/WReLpyUySbqy0ayQJstc1B9U0DcWTbtM8oRbY0NDpowrA+65Eb6kQcFxiY82GmdYtzqWzd9OB76xii8TGJhMtobOaLJnf6MdlMae8mnbFoe1gDXQivZHrpfA9ieddUjDRnADjy382nnjvIpnuBYkKgBm+VoWFPTn92z3Dl/xQIE+KO9oo1xQKNujA92LLr4xCTgR3KwFxZ6U9coJI8jhR/FL581LStJ5UlL8bGc4kV5729GBny72Yx4NioKbMT6X39g7e50MF+I09sY22XszX8LoG2NV1tTNvbhuXKMiINyw5KTY0iLWu606Tlg0nR/tBnTri7/WLJQailb6no8ik3x6SiYfMRF3SJH7DjyJWCWSy8vTU7/sucRe5QnoBxjjMnP6UNXuLgGwD7fB8A+EIRvy2QQ6VYOQMeEFC3mLMnzUT1w0Ihn3UyzDxw04nmfvLn8Q0pcWqRPAWUGyWhfNLOq2zemrmg+XC8IrBtjbmX7oRnlfiw2R7dPAEuuC20s8xvbkkCV2vSms6qPOsb5DV8hoHhZARs5pK3wpB+XNJmOn3ruv4VXURGeY5EjfRUx7PGuE3FjAReaMHwMVmANQEUcOizM6MV4oFboVATp2LEoh1Uo7KFYyl56NoZK7jFofLYesl+3S65hZ7bBVyicNklUcsZOnwxdPhAx++TrtI3kHjfjM33zTzu3D3LLAWNzPGhmXuoBF41L5NFzyX7QzeM1g+rDdcSexpOUS44Jffqspeunzo2X9cbdJ4AV8qmNegXTGZPxpnNQH+0OMuPY2KY7cugxjUQZDPwpmfOAQRzn0RiFJzbKp/WlCx3pRTyXo1B4sZC+bMw4Ea5DfY/D/XvcScdsoCV8+Qi0FWLHpu85OflALOfwK3vZZTyTgSf8aA/e9D+Ksn+TYL6LPzgHbsEWvrCor1x5jms5YJiXtCh45OETbc5WcRd7qltMtKMvsj2+rFbG7esq6ktLPI7Hud5DHEe19WsAR3XN7/i4sVPHXV47ecsDTRl7TjNBTrfyKZqlTAUPyG4PPJ1Tx5J+UdamzuFLLi1GQ/yoD3v35/5pP++feFEOC7efywpxPTr1aE1UfE7l26W9tykZ6N8AVlwT2MD1vyJEY4ZdSP8UHRTf7dvds3GdSOiOB+TxmHxsZpxYgKRS69O/x0Mt2EVbl4/1caSqRuz6iLDGkT2W1INt8ZcApF9jSVfYgc42C/XzEXD0Rf3sGxh5HH4k7rHa0TgwEkCUg9aROvmNHLg5l2M5bCVvl3l82af5sW1QepCn+Ip9pkMuPY8ZK8eaFqnV+uTxU3ag4Ffrif3Ey3mCRLx2/4DMG/MI2vVdOsVz6bRNlO9qv08Aa1iz2Lj22sD258Y3ZtgdFJ+x1ZhT8RQ/o8HQtsgnjOMOLXGt7/5b+NaW8rG+CiTwXScUnomCIz35xNL8pQ6W/AcicRbSsMnFcqF+Ll6Or/xlf1k+KvKKJ/sYycE3GWOt5NV44ljkM463lTOh0/G2+cp0zmPJZ6HzestjmJKDhyZ/7OMTtoyNPMbOPj7ZYBeb8GQPmfNcM/pzrvcYq9NHodcngDWu5fVuQPVGjjAPgs8dgjsYd5T5gZsuDYKSxzMSZa25Hcz15X+8g07v1NP6dnSYQIFLbC8aCKX1F3VkY/4ywbg5CLKExwLk8kzn4sZiJR3a6y4dizGxYpGGRpTDV5S774SZfUzKF00CRYa4kAvFB8xE47/wYj/lOsl4dxFtEK/GjiXkisvoVm602+CagF0XyHppYU2YkUY/wdu/+mK4ryjHtuENtsu32nZ5u93T7NcAdm+d9hHlDKAozO3qKhhRjkKD0icZYCAnzd5imlMC7+unNfBQxHWkRZq48NbK6c2jWlXucbZZmBpd7W+s4Wjs7UVj7GyO3I5sTMumL89dBrRdnjuPR8ATdqC4E60+ZOw+cRci0qrYdVxj3Bin+agNciy0WxSDjthGeIXhGBGHR4Yel7sf65uPrEAMlErlnX24izKVXfIgg17CTgxbmr58jfGoD9QkyzYRv+BlHB5xEy8eyQPBdIGBo+TUohyYwsISLdImz0f6tGvsk8IivBg7cRt8xJVzM+U/CfFXdNr4nKaevgVY3sJ4qIdPYrHnffowoflyOXuKMfJho32m2EshL6NOIzKS8inJ7vF29BsAd5q8+b1ia00bkqJZPRAhCLEemaTL4gOFNrJ03Igh7vhx0rDzI2Wh1LY8uq15pNw3PXg8lGPH9hLOsYKjUUtfxYnP6seYiMz7YoCgEVAmmui0pkbipKp4NjzPn9YamSKKnjEJZLp6Pr7bMMtJJxVrPGoaRVlHXMI3/+mDj6KWLfJAO5MbG72xHJpkc9RG4yPF9sc0Hvlj7oI9Yg/jHcktd9CnX8VLOpliArINA87ajEYa8pS/BJPnukY/y6kFIqFxLFiWxjAmyUZUIlasrRwg5CkfoOo2ZVNr7Aa1oxOAVo5WsOjxipbkMJfy2kazf59CECIRVtlYIwJ2V+0sUzEZ/siJ24xEGaQU6LgjZ08ciY+nxVDJVTyUT+ubrhVwanv5oX4s/NDw8gJUtWRlBT3RyUz+qQEccaS/Fw09jUrRjyeBcroI1dEKKmOml6wvmILnMeRg86IoZvNsXyAbueEJi2M0ILBMVfpcqjBncE4CIHLcLo/61Aau8suJgGsJUmRSn6QVBQPX1KZvS3qZDLyg+fomjU9FQA63gJKGrBbtaZEFR2ix4xPAEVqTfah7ZoBFYVrNi4GKR63XylmiVLqg60VMunVpIhda7TcB0m4VPVM/vR7SmPRBX9RS0ZWkjV5yx4QfaLO53OPzHjRL+TUD98OeIwlxeqnRRf06krHdXvKxRefsNwP+DXG/llupj81P/+d+ANigtSMczHvcjYh0EFzajjFjjKaDj8qR57JiR0MzGWPX+pS38CivLLEEdPlYv9WDRdSXPy6Bi8b4JQPH+ji9Yf0oFw9a6mecoC8sxg68HKvpQF+xs1/R0EkA8i0MeOQveokX5TzXL7kwpZdpw5QMyyxP/mpcysr4YJd00BiLy42Zx4JzO8IUP9IaI3GFB03YiRaG+EQCjuIhx2MqtHWiPSWMAX35wDjGbYoHLbcf2+wK54hNAHG1YaPQf+Qffn89G5Zi58aNqA+Cy51AmNM5KPhUDkqMociDRF3t6KKxrPXrcdR6LpOddmqnE14C1Fmc6I/heoFoaWHBhv8IzvUhd5vYxxgyXfRBK172RdstlIgx2wCTfWKUfoO1tD3szFZ4wM8+zO+y/pBVtIyTMNFKfKUvHhjyyWWxrXIB/fRf8BIBmgvDl50vJRc+lYWRTfMCccp/LQFfTf5EY6kcR576U/qSbfuynwKyNaiN49yuanmT99U3JiAIjb1VMIWAc6oRr40LeqPT1cHG5K2RITKqdhd1fUU9PmeLHTTa0cb16Y60v2Te/UV9oqMkZH3LneOzGKTPXNQw2JiTIrcxwTNwoJ+zVi6uwqsa8c0Ws5S5pn9ptGsO442ni4q82MsyjkM8upg+vSS/zIpZIKQ0gEl/yE/KRX2hmjkBAhvGn9eQwdtILbMlPzHfBQ9S2Lk+zBkZ8SilHnwV3YSBxrjoxRgBDzSxKFn8GfOyWHNXpH0C2JU12cdx4AzMFQovcrHIoLCodMl1TYMK5cqUyPFCQxoi8lQKxRdtxvZRR+nFkYWOevIMVJVLSTT9idY4aN/qiyt0j8s1mR9KJBe64iOtUYrish6Re6y1OnUYGTjCp4Cm0onNV/9T8sPhxQKzugfE7e0gmL5DO17bMx18VI48dxW7MeaxXs2s9TmWFh520dbl4MeW6MCQTavf0iyX8k1MwqiPpcvhMdLES3IzchvpQbfo29EydeiXZkud04ffbF/0M7b5SP7Jpz/FBZvxOX+Ox36hnBSJi1hkyxiJm/rN2Iw0XcZvNHAKz/MFWaWPMaR/z4/LyTOR5yyR0Z7SxCsYkkviS9lpCiLtcvTAc72xrObsBrXSN4Bnn312eP7554fXvOY1w9vf/va1ZOJ73/te+ip33vCe97xnLXgHB8GGObWZHBx5CiF64i4xpbUXT5ZEE6a4e1mP5bIUUq0h7tzpoCKvzYxCgWBpcWGtD9/k4FORQLu1pRxo1Kdu+tQsgG7wF/WhK3xf6kg+H0knHGyb0JQHequPtFXIoQnf/F3BtDezRwGErp1iYoxG4gO+KMyDJ46JshynZdB4xgmxkaZY/o1KH8HeuqRhhcbRZfsip4TcgI/Acj6iZfSv/Bi44Qd7i9Q1UMB1ein6ooZ7yNkqI2Hkc3JZU444XJ+jdVpRcgl+zkQlmNOvlLaM2PcE8I1vfGP43Oc+N1x11VXDT37yk+HDH/7wcO+9984O+/Tp08M999wzkj/99NPGw2TysY99LG3sTO/LL788fPWrX115YgGKVpScTq1MyRYvo2WLutjyIFJ4ip73jwVrj3cVvNqmxmvjMd3aII8AzKr0GK0PFQzt2M7X+JUF4kiOJWyjHd1TX6Wm4FvBgpXjSZ9LWqhkaLS+TL2E4T8Uc2v2hA1KmU/xwQY+8wxJ/Iha3+cv/0QxKH6g0MPM1ql1spDebdeZkPsP1bJ6tE+m0+f8HRo1Hh5KHlNP/XEsCBFyNBoCXw12ldyQwMl2ZRKAhdYtxyqvQgNXeNA2jPSh9SM/QKHcoy76JiOi2Zumf0R857I3pd/qbAu9rwkAxRrFHwX9Ix/5yAD6xIkTAyYF0FPtueeeG6699trh9ttvnxIPn/3sZ20yefDBB03+mc98ZrjtttuGM2fOTOp3Zs/AYWeg3cFZJqysFdeRx/JCjooTyxJt9pYDlsWKxYt9OpMnUo4vevrCLfWgA3vHE77koKcu/NZy/Q4hjofY0gMFqYovKWNWxZocZUd4MULZcOmRy7Iv15mBfU0Ajz322HDZZZeVYn/55ZcPN9100/Dwww8XXhvcj3/84+G6666z/1b2m9/8Zvj+978/PPLII0WEieLGG28cYLeu00vahQ62MUVrIZaw196pd9tV4OtdM0YcR7IIubap8Vo7i1cGxYE6PDIUNbbVEZ9LDK+QKluFYR0d10GKFt1HezuasyN4U7MyBW3pmNxoRujeiAiu+UoY1k+Hxq6D4hWOfJNulMHjYjpHgcN4nssxb7DylmT5WwDO1QNPctE4t/+qYtIU9YBd9BPKqwADpHSkzpGRxmjjpAB/LW3n3ZO/PxZLywzQSnxwixbxqcWM+zpghjBGk+dTYrDlSJVBSGlFHNLZml+0oEA2ernJXrTjkuPbgmugJ6A8kFq4E9S+LgKjKB8/frwaOIo7TgXNNRR4NBzp48gek4ga8NCAoYZJBU0y8dexxGqM/6tjYsPQxrE6yl6WinUvvXn5dJyrbM60mcaT/xLvyAFzVeQyCMu6AFFQ62Mn5voLZtYducvrJuobfmZQ32MCSPSvPpf0Kx3huI5i8vhclnko3tkHQ4i07NIyCVFYYS899jMNGXRm5HaBN9hXF4KLneMXudkIN8jNH2nET33q2XiyXPuCxwob4aVl0jP9HPdYH1LZpC6MA21koCWDFhr8xub+MpQJA35UzjIsGLMLna7xpeua29sr3wBwNP6Vr3xlciSXXnqpneqBTntUjgvBc01FXKeIYP/FL35xwAXfRdcNjh07NuDU0Srt6r+4dPj7T92wiumRshlv0vsdPnfL/Vot0j9YTB7PKji1jWMp3lqeuBWjLUG0cpUaz/lCH9tTx+1qm8X65YtEhmfpG8dUY7ZlNQ5xsT/kosUal+Wo4+NCVGNbcMc+wY1tbFfjSnesJ8lyS9pPY7cI5/3Jn7SsjabLBPCHP/xheOaZZyaD/f3vf1/4F198cenv1cG3BVwvwGki2aGPi74f//jH9zJfSX7xsT8drj526Uq23ahnoGegZ+AoZaBMAK997WuHL3/5ywvHjoKOo/e5C7qtMYp+e3FYp3umTifJ/re//a3dYiq6L3sGegZ6BnoG1p+BfV0DwPl53KYZ27e//W27iyfy1MdkcerUKZHVEpOJrifoVBEUcGcRWnuqyZj9o2egZ6BnoGdgbRnY1wSAe/5xwVcFG+f0n3jiCTvFo4h+9KMfDT/96U+NxDeA+++/3741SA4a5/hR4DGh4BbROEnoTiN9U5BdX/YM9Az0DPQMrDcD6bcqullrOWD8sAtF/Oqrr7YLtbgIjB9u6Rz/9ddfP9xwww3D5z//eQO866677DZP/MIXEwaO8B999NFyhI/J5KMf/ahNBsB46qmnKvlyUXWtnoGegZ6BnoH9ZmDfEwAcoGjjH6dw2iN1fAO45JJLhre85S0llqiPI39NFlLAxPDkk0/aBBEvGEvelz0DPQM9Az0D68/AShPA+sPoiD0DPQM9Az0D5zoD+7oGcK6D6/56BnoGegZ6Bg4vA30COLzcduSegZ6BnoGNzkCfADZ69fTgegZ6BnoGDi8DfQI4vNx25J6BnoGegY3OQJ8ANnr19OB6BnoGegYOLwPlURCH5+JwkXELqZ5GipfUtLeYtt715rHIX8Yu6m96X2PEo7v1dNVFMeM2XTx8D7f1HoVfYOO3KNhmsK3s9Qa6uH3FHO5lF3W3tY/tAuNvb/WeGg+2OTwlAPvSMtvcFMY28vC7qE984hMLQ9/kbWirbwPFBooX0uiREihii94mhh0f7xpoG95HsMxG3tptGo0NDflAww/0kJ8777xz9DymGPett95aftOBR3efPHly6Wc9RZxt6euHjJjokB/8oBHbzFzb6412c3bbzte2hN/lLHr2F/TwmHfsW9gPsQ3hpVF7FcVtzw/i17ahtxvOjQk/nI1PO5DeXnbSO9Qlfgm8rS396vhseoBdCf9Tn/rU2fSr4kK3nW9961tn3/nOd7bsnaE//elPn73lllvKeB566KGz73rXu86+9NJLhRc7X//61y0fkqdfYZ9929vedhbLXWw/+9nPbHzf/e53bXgYN7Yh5GmuIaf4P0oN+Um/5rdcxf1rKgeQI4fahmCLbQi53tWGsaYnHNg4Mda9GupSegz+XmqviHxrrwHg6A0vpsfzidRwpIJfFONoZKrBZpdPcTz++OPV0T6exIqv5cjJVNN7GnTaDLnBV3jwd7HhOVMYn77tYdw4wo0vKWrHjVNFu7zNtOPFPoLHtWO/wnO69mp4GGT89T5yixwvyulemJsux8utcMoL33SWaZtcd7Z2AsAKQIvnG7Wjzr1MBisC+liBOFWCJb7C7kJTPnQ6DGNCgcPOiHFPNXxdj/rQWaQ/hbFNPOSoHS+2GV1DmhoLZDjQwPaCf7z+dJcbTh3iAY+LTvvE8SM/mlDFB4a2R/F2aYl3mXzzm99c+sAA2w/ytInb0MZeBMZ5s1/84heT2036Sm5Htniq6FRrH1ktHRRCFHxs3DpKef/7328voNdRsHS3dTm1My4aiyZN6WCCnJtApbPNy3a87YQQx6aJEw8oxLcp5AXvzMA3qgceeCCq7kw/HlAtOygU/NiwDe7yBNDuY3HsbV950DaEbWqTtqGNnQDOP//84YILLmjzafR5+Z13WrZK7QYpOV5DiR1eGzl26ptvvtmO6pY94hFWX+5+BrCttDcI4O4fnCLBjtxOJrufkT7C/WYA20i7DYGH00ebsA1t7ASQLpwszDV2xKkr64uM2pkbR/3YyTFLb/sEoCNZjCWOc+7bEPKE20SxEUb9uesni/K6LTLkCOONbdG3HWwfMTewEw27PgEwk+02hm1wV75Rx21llf7UNoQDT0wAm3D6eWuvAWgDiwVLO7eKYVxhSLZueYx89HdhR8a3GpwSiwUNY8a5x7nxgR/1kYupc7rg70KbGi+2mbmLnShkuMUxNu20c98yo+5R6CN3yFNsfXL0bOAiOa41xhZrVuS/Ev2tnQCwM7dvE8N1A/B0igdvJsP7CdAwYWBDjRfxsHJwIRR3MexC0x0tKlK4mweTgn609POf/9yud2is0McFP+mjGGICiHdWSXcXlhgvxqcDBYwb48cRmdoPf/jD4ZlnnjES2wy2kXhXFF5whG9O+iYgu6OyRPE6c+ZMGS5yF7ch5Ku9O68oH5HOD37wg3InIg4UcEdUnCTvvvvuzdmGXpGbT9fkFPer477+D37wg3bfMu5Hjvewf+ELXzj7vve9r3iDDDrQx+8FcA8v7oXflYb7k5ULLJEb3fOOMX7ta1+zMf/6178uQ8Y97vitgPKx6J74YrTFHaxvrHeMF+PGPdqxvfe977V7vMVDPqSPe+PbbUx6u7jEb0ra3wGkH81ZPn73u9+VISOHcRvapX2qDHKio988tKJ3vOMdZ7/0pS8VNn4DELch7JuxThXFV6Cz1b8E1gGFZtf2qAzfAF588cXhmmuukaod7eoIEN8idCqpKOxAR/lox4cj3hdeeGF461vfWo0S+YAMp8707alS2DECR7E4TYF1jxzFhm8Ar3/964crrriisBfpF6Ud7GC7wBFs3CbSQcbwy1/+8shvQ1jd2GeQo7bu4BvAG9/4xipvm7oN7cQEsIP7Xh9Sz0DPQM/AoWdga68BHHpmuoOegZ6BnoEdz0CfAHZ8Bffh9Qz0DPQMzGWgTwBzmen8noGegZ6BHc9AnwB2fAX34fUM9Az0DMxloE8Ac5np/J6BnoGegR3PQJ8AdnwF9+H1DPQM9AzMZaBPAHOZ6fyegZ6BnoEdz0CfAHZ8Bffh9Qz0DPQMzGWgTwBzmen8noGegZ6BHc9AnwB2fAX34Y0zgJ/wp+f62BuaohQPfbvyyiurh79Fee/3DOxaBvoEsGtrtI9nzwzgGUB4/wPe7KXnJuGZLnhG+8mTJ6ung+4J1hV6BrY4A/1ZQFu88nroB8sA3gaHyeCOO+6wbwM33njjcN999x0MtFv3DGxRBvoEsEUrq4e63gzg6B+vd8QTL6eK/+nTp+39AXhyaHoM8nqdd7SegQ3IQD8FtAEroYfwymQgPgp86sgfhR8v08Gpot56BnYxA30C2MW12se0ZwZwzv/EiRN25I932uJtcm278847+/WANimd3qkM9Algp1ZnH8wyGcDLOVT8H3zwweFDH/qQvSoUdwf11jNwlDLQJ4CjtLb7WO0tTnjRO95+hiN8NNwRlN7GN/ktoKesZ2CXM9AngF1eu31sowzgVA+KPy7q6hoAXnmISQCnhfq3gFHKOmOHM9DvAtrhlduHtp4M4MdhTz/99HrAOkrPwAZl4PwNiqWH0jOwURnAt4XzzjvPYjp16tRw2WWX9YvCG7WGejAHzUA/BXTQDHb7nc4Arg3g18FY9tYzsGsZ6KeAdm2N9vH0DPQM9AwsmYH+DWDJRHW1noGegZ6BXcvAvwN0H5KT3aW7fgAAAABJRU5ErkJggg==)" ] }, { "cell_type": "markdown", "id": "0dbf9668", "metadata": { "id": "0dbf9668" }, "source": [ "### The model\n", "\n", "The package `torch.nn` defines a series of useful classes like linear networks layers, activation functions, loss functions etc. A full list can be found [here](https://pytorch.org/docs/stable/nn.html). " ] }, { "cell_type": "code", "execution_count": null, "id": "a0eb8f0b", "metadata": { "id": "a0eb8f0b" }, "outputs": [], "source": [ "import torch.nn as nn" ] }, { "cell_type": "markdown", "id": "fe7eda13", "metadata": { "id": "fe7eda13" }, "source": [ "Additionally to `torch.nn`, there is also `torch.nn.functional`. It contains functions that are used in network layers. This is in contrast to `torch.nn` which defines them as `nn.Modules`, and `torch.nn` actually uses a lot of functionalities from `torch.nn.functional`. Hence, the functional package is useful in many situations, and so we import it as well here." ] }, { "cell_type": "code", "execution_count": null, "id": "3d8f322d", "metadata": { "id": "3d8f322d" }, "outputs": [], "source": [ "import torch.nn.functional as F" ] }, { "cell_type": "markdown", "id": "a469bc33", "metadata": { "id": "a469bc33" }, "source": [ "#### nn.Module\n", "\n", "In PyTorch, a neural network is comprised of modules. Modules can contain other modules, and a neural network is considered to be a module itself as well. \n", "\n", "The basic template of a module is as follows:" ] }, { "cell_type": "code", "execution_count": null, "id": "9fc8b8ee", "metadata": { "id": "9fc8b8ee" }, "outputs": [], "source": [ "class MyModule(nn.Module):\n", " \n", " def __init__(self):\n", " super().__init__()\n", " # Some init for my module\n", " \n", " def forward(self, x):\n", " # Function for performing the calculation of the module.\n", " pass" ] }, { "cell_type": "markdown", "id": "fefdd1a4", "metadata": { "id": "fefdd1a4" }, "source": [ "The `forward` method is where the computation of the module is taken place, and is executed when you call the module (`nn = MyModule(); nn(x)`). In the `__init__` method we specify the parameters of the module using `nn.Parameter` or defining other modules that are used in the forward function. The backward calculation is done automatically, but could be overriden with a custom `backward` method as needed.\n", "\n", "#### Simple classifier\n", "We can now make use of the pre-defined modules in the `torch.nn` package, and define our own small neural network. We will use a minimal network with a input layer, one hidden layer with tanh as activation function, and a output layer. \n", "\n", "![image.png](data:image/png;base64,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)\n", "\n", "The input neurons are shown in blue, which represent the coordinates $x_1$ and $x_2$ of a data point. The hidden neurons including a tanh activation are shown in white, and the output neuron in red.\n", "In PyTorch, we can define this as follows:" ] }, { "cell_type": "code", "execution_count": null, "id": "49e269ea", "metadata": { "id": "49e269ea" }, "outputs": [], "source": [ "class SimpleClassifier(nn.Module):\n", "\n", " def __init__(self, num_inputs, num_hidden, num_outputs):\n", " super().__init__()\n", " # Initialize the modules we need to build the network\n", " self.linear1 = nn.Linear(num_inputs, num_hidden)\n", " self.act_fn = nn.Tanh()\n", " self.linear2 = nn.Linear(num_hidden, num_outputs)\n", "\n", " def forward(self, x):\n", " # Perform the calculation of the model to determine the prediction\n", " x = self.linear1(x)\n", " x = self.act_fn(x)\n", " x = self.linear2(x)\n", " return x" ] }, { "cell_type": "markdown", "id": "ce9025ca", "metadata": { "id": "ce9025ca" }, "source": [ "For the examples in this notebook, we will use a tiny neural network with two input neurons and four hidden neurons. As we perform binary classification, we will use a single output neuron. Note that we do not apply an activation to the output. This is because other functions, especially the loss, are more efficient and precise to calculate on the original outputs instead of the sigmoid output. " ] }, { "cell_type": "code", "execution_count": null, "id": "d2d99a2b", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "d2d99a2b", "outputId": "c09a3ddd-e15f-4ce9-cde7-76ca8f356daa" }, "outputs": [], "source": [ "model = SimpleClassifier(num_inputs=2, num_hidden=4, num_outputs=1)\n", "model" ] }, { "cell_type": "markdown", "id": "1d82bffd", "metadata": { "id": "1d82bffd" }, "source": [ "The parameters of a module can be obtained by using its `parameters()` functions, or `named_parameters()` to get a name to each parameter object. " ] }, { "cell_type": "code", "execution_count": null, "id": "498aa1d7", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "498aa1d7", "outputId": "826feb33-b1d5-411f-e049-81ce14a746da" }, "outputs": [], "source": [ "for name, param in model.named_parameters():\n", " print(f\"Parameter {name}, shape {param.shape}\")" ] }, { "cell_type": "markdown", "id": "47146b4f", "metadata": { "id": "47146b4f" }, "source": [ "Each linear layer has a weight matrix of the shape `[output, input]`, and a bias of the shape `[output]`. The tanh activation function does not have any parameters. Note that parameters are only registered for `nn.Module` objects that are attributes of the class. If you define a list of modules, the parameters of those are not registered for the outer module and can cause some issues when you try to optimize your module. There are alternatives, like `nn.ModuleList`, `nn.ModuleDict` and `nn.Sequential`, that allow you to have different data structures of modules. " ] }, { "cell_type": "markdown", "id": "eb225d4c", "metadata": { "id": "eb225d4c" }, "source": [ "#### Custom XOR Dataset\n", "\n", "To define a custom dataset in PyTorch, we simply specify two functions: `__getitem__`, and `__len__`. The `__getitem__` method returns the `idx`-indexed data point in the dataset, while the `__len__` method returns the size of the dataset. " ] }, { "cell_type": "code", "execution_count": null, "id": "aae2bb58", "metadata": { "id": "aae2bb58" }, "outputs": [], "source": [ "import torch.utils.data as data\n", "\n", "class XORDataset(data.Dataset):\n", "\n", " def __init__(self, size, std=0.1):\n", " \"\"\"\n", " Inputs:\n", " size - Number of data points we want to generate\n", " std - Standard deviation of the noise (see generate_continuous_xor function)\n", " \"\"\"\n", " super().__init__()\n", " self.size = size\n", " self.std = std\n", " self.generate_continuous_xor()\n", "\n", " def generate_continuous_xor(self):\n", " # Each data point in the XOR dataset has two variables, x and y, that can be either 0 or 1\n", " # The label is their XOR combination, i.e. 1 if only x or only y is 1 while the other is 0.\n", " # If x=y, the label is 0.\n", " data = torch.randint(low=0, high=2, size=(self.size, 2), dtype=torch.float32)\n", " label = (data.sum(dim=1) == 1).to(torch.long)\n", " # To make it slightly more challenging, we add a bit of gaussian noise to the data points.\n", " data += self.std * torch.randn(data.shape)\n", "\n", " self.data = data\n", " self.label = label\n", "\n", " def __len__(self):\n", " # Number of data point we have. Alternatively self.data.shape[0], or self.label.shape[0]\n", " return self.size\n", "\n", " def __getitem__(self, idx):\n", " # Return the idx-th data point of the dataset\n", " # If we have multiple things to return (data point and label), we can return them as tuple\n", " data_point = self.data[idx]\n", " data_label = self.label[idx]\n", " return data_point, data_label" ] }, { "cell_type": "markdown", "id": "c91a11ec", "metadata": { "id": "c91a11ec" }, "source": [ "Let's try to create such a dataset and inspect it:" ] }, { "cell_type": "code", "execution_count": null, "id": "81f96424", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "81f96424", "outputId": "7cb501d7-98aa-415a-9479-ca9db49ea441" }, "outputs": [], "source": [ "dataset = XORDataset(size=200)\n", "print(\"Size of dataset:\", len(dataset))\n", "print(\"Data point 0:\", dataset[0])" ] }, { "cell_type": "code", "execution_count": null, "id": "47cc981c", "metadata": { "id": "47cc981c" }, "outputs": [], "source": [ "def visualize_samples(data, label):\n", " if isinstance(data, torch.Tensor):\n", " data = data.cpu().numpy()\n", " if isinstance(label, torch.Tensor):\n", " label = label.cpu().numpy()\n", " data_0 = data[label == 0]\n", " data_1 = data[label == 1]\n", " \n", " plt.figure(figsize=(4,4))\n", " plt.scatter(data_0[:,0], data_0[:,1], edgecolor=\"#333\", label=\"Class 0\")\n", " plt.scatter(data_1[:,0], data_1[:,1], edgecolor=\"#333\", label=\"Class 1\")\n", " plt.title(\"Dataset samples\")\n", " plt.ylabel(r\"$x_2$\")\n", " plt.xlabel(r\"$x_1$\")\n", " plt.legend()" ] }, { "cell_type": "code", "execution_count": null, "id": "4bd6b4e6", "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 297 }, "id": "4bd6b4e6", "outputId": "28176085-131a-4e03-946d-5d1ae3a712cc" }, "outputs": [], "source": [ "visualize_samples(dataset.data, dataset.label)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "0132dbf8", "metadata": { "id": "0132dbf8" }, "source": [ "Let's create a simple data loader:" ] }, { "cell_type": "code", "execution_count": null, "id": "458d8a43", "metadata": { "id": "458d8a43" }, "outputs": [], "source": [ "data_loader = torch.utilis.data.DataLoader(dataset, batch_size=8, shuffle=True)" ] }, { "cell_type": "markdown", "id": "225c5edd", "metadata": {}, "source": [ "The data loader is iterable; `next(iter(...))` catches the first batch of the loader\n", "If `shuffle` is `True`, this will return a different batch every time we run this cell.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "048bad12", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "048bad12", "outputId": "a99e8785-0ae1-4ac7-d704-c1d4b0e28600" }, "outputs": [], "source": [ "data_inputs, data_labels = next(iter(data_loader))" ] }, { "cell_type": "markdown", "id": "a9bc9781", "metadata": {}, "source": [ "The shape of the outputs are `[batch_size, d_1,...,d_N]` where `d_1,...,d_N` are the \n", "dimensions of the data point returned from the dataset class" ] }, { "cell_type": "code", "execution_count": null, "id": "6fea4669", "metadata": {}, "outputs": [], "source": [ "print(\"Data inputs\", data_inputs.shape, \"\\n\", data_inputs)\n", "print(\"Data labels\", data_labels.shape, \"\\n\", data_labels)" ] }, { "cell_type": "markdown", "id": "5584ab5a", "metadata": { "id": "5584ab5a" }, "source": [ "### Optimization\n", "\n", "After defining the model and the dataset, it is time to prepare the optimization of the model. During training, we will perform the following steps:\n", "\n", "1. Get a batch from the data loader\n", "2. Obtain the predictions from the model for the batch\n", "3. Calculate the loss based on the difference between predictions and labels\n", "4. Backpropagation: calculate the gradients for every parameter with respect to the loss\n", "5. Update the parameters of the model in the direction of the gradients\n", "\n", "We have seen how we can do step 1, 2 and 4 in PyTorch. Now, we will look at step 3 and 5." ] }, { "cell_type": "markdown", "id": "8a5aab14", "metadata": { "id": "8a5aab14" }, "source": [ "#### Loss modules\n", "\n", "We can calculate the loss for a batch by simply performing a few tensor operations as those are automatically added to the computation graph. For instance, for binary classification, we can use Binary Cross Entropy (BCE) which is defined as follows:\n", "\n", "$$\\mathcal{L}_{BCE} = -\\sum_i \\left[ y_i \\log x_i + (1 - y_i) \\log (1 - x_i) \\right]$$\n", "\n", "where $y$ are our labels, and $x$ our predictions, both in the range of $[0,1]$. However, PyTorch already provides a list of predefined loss functions which we can use (see [here](https://pytorch.org/docs/stable/nn.html#loss-functions) for a full list). For instance, for BCE, PyTorch has two modules: `nn.BCELoss()`, `nn.BCEWithLogitsLoss()`. While `nn.BCELoss` expects the inputs $x$ to be in the range $[0,1]$, i.e. the output of a sigmoid, `nn.BCEWithLogitsLoss` combines a sigmoid layer and the BCE loss in a single class. This version is numerically more stable than using a standard sigmoid followed by a BCE loss because of the logarithms applied in the loss function. Hence, it is best to use loss functions applied on logits where possible. For our model, we therefore use the module `nn.BCEWithLogitsLoss`. " ] }, { "cell_type": "code", "execution_count": null, "id": "b0e39ec6", "metadata": { "id": "b0e39ec6" }, "outputs": [], "source": [ "loss_module = nn.BCEWithLogitsLoss()" ] }, { "cell_type": "markdown", "id": "cefa4095", "metadata": { "id": "cefa4095" }, "source": [ "#### Stochastic Gradient Descent\n", "\n", "For updating the parameters, PyTorch provides the package `torch.optim` that has most popular optimizers implemented. We will discuss the specific optimizers and their differences later in the course, but will for now use the simplest of them: `torch.optim.SGD`. Stochastic Gradient Descent updates parameters by multiplying the gradients with a small constant, called learning rate, and subtracting those from the parameters (hence minimizing the loss). Therefore, we slowly move towards the direction of minimizing the loss. A good default value of the learning rate for a small network is 0.1. \n", "\n", "The input to the optimizer are the parameters of the model `model.parameters()`\n" ] }, { "cell_type": "code", "execution_count": null, "id": "65772a2e", "metadata": { "id": "65772a2e" }, "outputs": [], "source": [ "optimizer = torch.optim.SGD(model.parameters(), lr=0.1)" ] }, { "cell_type": "markdown", "id": "76006d49", "metadata": { "id": "76006d49" }, "source": [ "The optimizer provides two useful methods: `step()`, and `zero_grad()`. The `step()` method updates the parameters based on the gradients as explained above, while `zero_grad()` sets the gradients of all parameters to zero. While this function seems less relevant at first, it is a crucial step before performing backpropagation. If we would call the `backward` function on the loss while the parameter gradients are non-zero from the previous batch, the new gradients would actually be added to the previous ones instead of overwriting them. This is done because a parameter might occur multiple times in a computation graph, and we need to sum the gradients in this case instead of replacing them. Hence, remember to call `optimizer.zero_grad()` before calculating the gradients of a batch." ] }, { "cell_type": "markdown", "id": "1ad88a1c", "metadata": { "id": "1ad88a1c" }, "source": [ "### Training\n", "\n", "Finally, we are ready to train our model. As a first step, we create a slightly larger dataset and specify a data loader with a larger batch size. " ] }, { "cell_type": "code", "execution_count": null, "id": "ef0df3d2", "metadata": { "id": "ef0df3d2" }, "outputs": [], "source": [ "train_dataset = XORDataset(size=2500)\n", "train_data_loader = data.DataLoader(train_dataset, batch_size=128, shuffle=True)" ] }, { "cell_type": "markdown", "id": "dd5b80f0", "metadata": { "id": "dd5b80f0" }, "source": [ "Now, we can write a small training function. Remember the five steps: \n", "\n", "1. load a batch\n", "2. obtain the predictions\n", "3. calculate the loss\n", "4. backpropagate\n", "5. update \n", " \n", "Additionally, we have to push all data and model parameters to the device of our choice (GPU if available). For our simple example, communicating the data to the GPU actually takes much more time than we could save from running the operation on GPU. For large networks, the communication time is significantly smaller than the actual runtime making a GPU crucial in these cases. Nevertheless, we will push the data to GPU here. " ] }, { "cell_type": "code", "execution_count": null, "id": "1e12ea55", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "1e12ea55", "outputId": "f6a6608f-13bb-400b-e032-9fe8c426aa4c" }, "outputs": [], "source": [ "# Push model to device. Has to be only done once\n", "model.to(device)" ] }, { "cell_type": "markdown", "id": "a499ebb7", "metadata": { "id": "a499ebb7" }, "source": [ "In addition, we set our model to training mode. This is done by calling `model.train()`. There exist certain modules that need to perform a different forward step during training than during testing (e.g. `BatchNorm` and `Dropout`), and we can switch between them using `model.train()` and `model.eval()`." ] }, { "cell_type": "code", "execution_count": null, "id": "b4aa1325", "metadata": { "id": "b4aa1325" }, "outputs": [], "source": [ "from tqdm import tqdm\n", "\n", "def train_model(model, optimizer, data_loader, loss_module, num_epochs=100):\n", " # Set model to train mode\n", " model.train() \n", " \n", " # Training loop\n", " for epoch in tqdm(range(num_epochs)):\n", " for data_inputs, data_labels in data_loader:\n", " \n", " ## Step 1: Move input data to device (only strictly necessary if we use GPU)\n", " data_inputs = data_inputs.to(device)\n", " data_labels = data_labels.to(device)\n", " \n", " ## Step 2: Run the model on the input data\n", " preds = model(data_inputs)\n", " preds = preds.squeeze(dim=1) # Output is [Batch size, 1], but we want [Batch size]\n", " \n", " ## Step 3: Calculate the loss\n", " loss = loss_module(preds, data_labels.float())\n", " \n", " ## Step 4: Perform backpropagation\n", " # Before calculating the gradients, we need to ensure that they are all zero. \n", " # The gradients would not be overwritten, but actually added to the existing ones.\n", " optimizer.zero_grad() \n", " # Perform backpropagation\n", " loss.backward()\n", " \n", " ## Step 5: Update the parameters\n", " optimizer.step()" ] }, { "cell_type": "code", "execution_count": null, "id": "e6c86b96", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "e6c86b96", "outputId": "6a521e6d-09fe-4e81-9916-b7ca277a1c6d" }, "outputs": [], "source": [ "train_model(model, optimizer, train_data_loader, loss_module)" ] }, { "cell_type": "markdown", "id": "0b862513", "metadata": { "id": "0b862513" }, "source": [ "#### Saving a model\n", "\n", "After finish training a model, we serialize the model to disk so that we can use the same weights to reconstruct the model when needed. For this, we extract the `state_dict` from the model which contains all learnable parameters. " ] }, { "cell_type": "code", "execution_count": null, "id": "d43f7552", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "d43f7552", "outputId": "916eb44c-db76-46db-8e69-587029608aef" }, "outputs": [], "source": [ "state_dict = model.state_dict()\n", "print(state_dict)" ] }, { "cell_type": "markdown", "id": "88e0ab8b", "metadata": { "id": "88e0ab8b" }, "source": [ "To save the state dictionary, we can use `torch.save`:" ] }, { "cell_type": "code", "execution_count": null, "id": "d067493b", "metadata": { "id": "d067493b" }, "outputs": [], "source": [ "torch.save(state_dict, \"our_model.tar\")" ] }, { "cell_type": "markdown", "id": "adc2f9e2", "metadata": { "id": "adc2f9e2" }, "source": [ "To load a model from a state dict, we use the function `torch.load` to load the state dict from the disk, and the module function `load_state_dict` to overwrite our parameters with the new values:" ] }, { "cell_type": "code", "execution_count": null, "id": "e5ab5e1a", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "e5ab5e1a", "outputId": "727287b1-e7d8-4277-ee64-719c76e3d9b4" }, "outputs": [], "source": [ "# Load state dict from the disk (make sure it is the same name as above)\n", "state_dict = torch.load(\"our_model.tar\")\n", "\n", "# Create a new model and load the state\n", "new_model = SimpleClassifier(num_inputs=2, num_hidden=4, num_outputs=1)\n", "new_model.load_state_dict(state_dict)\n", "\n", "# Verify that the parameters are the same\n", "print(\"Original model\\n\", model.state_dict())\n", "print(\"\\nLoaded model\\n\", new_model.state_dict())" ] }, { "cell_type": "markdown", "id": "3c9333b2", "metadata": { "id": "3c9333b2" }, "source": [ "A detailed tutorial on saving and loading models in PyTorch can be found [here](https://pytorch.org/tutorials/beginner/saving_loading_models.html)." ] }, { "cell_type": "markdown", "id": "b9356299", "metadata": { "id": "b9356299" }, "source": [ "### Evaluation\n", "\n", "Once we have trained a model, it is time to evaluate it on a held-out test set. As our dataset consist of randomly generated data points, we need to first create a test set with a corresponding data loader." ] }, { "cell_type": "code", "execution_count": null, "id": "293a8e46", "metadata": { "id": "293a8e46" }, "outputs": [], "source": [ "test_dataset = XORDataset(size=500)\n", "test_data_loader = data.DataLoader(test_dataset, batch_size=128, shuffle=False, drop_last=False) " ] }, { "cell_type": "markdown", "id": "fc3c64bf", "metadata": { "id": "fc3c64bf" }, "source": [ "As metric, we will use **accuracy** which is calculated as follows:\n", "\n", "$$acc = \\frac{\\#\\text{correct predictions}}{\\#\\text{all predictions}} = \\frac{TP+TN}{TP+TN+FP+FN}$$\n", "\n", "where TP are the true positives, TN true negatives, FP false positives, and FN the fale negatives. \n", "\n", "When evaluating the model, we don't need to keep track of the computation graph as we don't intend to calculate the gradients. This reduces the required memory and speed up the model. In PyTorch, we can temporarily deactivate the computation graph using a context manager. \n", "\n", "Remember to set the model to eval mode." ] }, { "cell_type": "code", "execution_count": null, "id": "dc8df44c", "metadata": { "id": "dc8df44c" }, "outputs": [], "source": [ "def eval_model(model, data_loader):\n", " model.eval() # Set model to eval mode\n", " true_preds, num_preds = 0., 0.\n", " \n", " with torch.no_grad(): # Deactivate gradients for the following code\n", " for data_inputs, data_labels in data_loader:\n", " \n", " # Determine prediction of model on dev set\n", " data_inputs, data_labels = data_inputs.to(device), data_labels.to(device)\n", " preds = model(data_inputs)\n", " preds = preds.squeeze(dim=1)\n", " preds = torch.sigmoid(preds) # Sigmoid to map predictions between 0 and 1\n", " pred_labels = (preds >= 0.5).long() # Binarize predictions to 0 and 1\n", " \n", " # Keep records of predictions for the accuracy metric (true_preds=TP+TN, num_preds=TP+TN+FP+FN)\n", " true_preds += (pred_labels == data_labels).sum()\n", " num_preds += data_labels.shape[0]\n", " \n", " acc = true_preds / num_preds\n", " print(f\"Accuracy of the model: {100.0*acc:4.2f}%\")" ] }, { "cell_type": "code", "execution_count": null, "id": "0f7b7f70", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "0f7b7f70", "outputId": "4f32c18a-3411-4382-f832-4512bd53f120" }, "outputs": [], "source": [ "eval_model(model, test_data_loader)" ] }, { "cell_type": "markdown", "id": "e682dcd2", "metadata": { "id": "e682dcd2" }, "source": [ "#### Visualizing classification boundaries\n", "\n", "To visualize what our model has learned, we can perform a prediction for every data point in a range of $[-0.5, 1.5]$, and visualize the predicted class as in the sample figure at the beginning of this section. This shows where the model has created decision boundaries, and which points would be classified as $0$, and which as $1$. We therefore get a background image out of blue (class 0) and orange (class 1). The spots where the model is uncertain we will see a blurry overlap. The specific code is less relevant compared to the output figure which should hopefully show us a clear separation of classes:" ] }, { "cell_type": "code", "execution_count": null, "id": "ada53a67", "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 460 }, "id": "ada53a67", "outputId": "d6e10c9d-5401-4655-c088-01d1ec19a21a" }, "outputs": [], "source": [ "from matplotlib.colors import to_rgba\n", "\n", "@torch.no_grad()\n", "def visualize_classification(model, data, label):\n", " if isinstance(data, torch.Tensor):\n", " data = data.cpu().numpy()\n", " if isinstance(label, torch.Tensor):\n", " label = label.cpu().numpy()\n", " data_0 = data[label == 0]\n", " data_1 = data[label == 1]\n", " \n", " fig = plt.figure(figsize=(4,4), dpi=100)\n", " plt.scatter(data_0[:,0], data_0[:,1], edgecolor=\"#333\", label=\"Class 0\")\n", " plt.scatter(data_1[:,0], data_1[:,1], edgecolor=\"#333\", label=\"Class 1\")\n", " plt.title(\"Dataset samples\")\n", " plt.ylabel(r\"$x_2$\")\n", " plt.xlabel(r\"$x_1$\")\n", " plt.legend()\n", " \n", " # Let's make use of a lot of operations we have learned above\n", " model.to(device)\n", " c0 = torch.Tensor(to_rgba(\"C0\")).to(device)\n", " c1 = torch.Tensor(to_rgba(\"C1\")).to(device)\n", " x1 = torch.arange(-0.5, 1.5, step=0.01, device=device)\n", " x2 = torch.arange(-0.5, 1.5, step=0.01, device=device)\n", " xx1, xx2 = torch.meshgrid(x1, x2) # Meshgrid function as in numpy\n", " model_inputs = torch.stack([xx1, xx2], dim=-1)\n", " preds = model(model_inputs)\n", " preds = torch.sigmoid(preds)\n", " output_image = (1 - preds) * c0[None,None] + preds * c1[None,None] # Specifying \"None\" in a dimension creates a new one\n", " output_image = output_image.cpu().numpy() # Convert to numpy array. This only works for tensors on CPU, hence first push to CPU\n", " plt.imshow(output_image, origin='lower', extent=(-0.5, 1.5, -0.5, 1.5))\n", " plt.grid(False)\n", " return fig\n", "\n", "_ = visualize_classification(model, dataset.data, dataset.label)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "fe247b77", "metadata": { "id": "fe247b77" }, "source": [ "The decision boundaries might not look exactly as in the figure in the preamble of this section which can be caused by running it on CPU or a different GPU architecture. Nevertheless, the result on the accuracy metric should be the approximately the same. " ] }, { "cell_type": "markdown", "id": "283da4f0", "metadata": {}, "source": [ "## Exercise\n", "\n", "Build a multi-layer network to predict the grape varietal from the wine dataset." ] }, { "cell_type": "code", "execution_count": null, "id": "0b4aab25", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "wine = pd.read_table(\"../data/wine.dat\", sep='\\s+')\n", "\n", "attributes = ['Alcohol',\n", " 'Malic acid',\n", " 'Ash',\n", " 'Alcalinity of ash',\n", " 'Magnesium',\n", " 'Total phenols',\n", " 'Flavanoids',\n", " 'Nonflavanoid phenols',\n", " 'Proanthocyanins',\n", " 'Color intensity',\n", " 'Hue',\n", " 'OD280/OD315 of diluted wines',\n", " 'Proline']\n", "\n", "grape = wine.pop('region')\n", "y = grape.values-1\n", "X = wine.values" ] }, { "cell_type": "code", "execution_count": null, "id": "74726b3a", "metadata": {}, "outputs": [], "source": [ "# Write your answer here" ] }, { "cell_type": "markdown", "id": "5b4b7b9f", "metadata": { "id": "5b4b7b9f" }, "source": [ "---\n", "## References\n", "\n", "- [Deep Learning with PyTorch](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)\n", "- [University of Amsterdam Deep Learning Tutorials](https://uvadlc-notebooks.readthedocs.io/en/latest/)" ] } ], "metadata": { "accelerator": "GPU", "colab": { "collapsed_sections": [], "name": "Section7_2-Introduction-to-PyTorch.ipynb", "provenance": [] }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.9" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "068c5d4019c740019f30c75afaf877c6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "0c08e5867eef48cfae0adf6a02915631": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "208cd522e37a4d4e8a23bb7af68cbbc5": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3070edc6c79b40309c198b5c4845c569": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_208cd522e37a4d4e8a23bb7af68cbbc5", "placeholder": "​", "style": "IPY_MODEL_fc8f946314f641c5af76cf7d62c7b4db", "value": " 170499072/? [00:02<00:00, 66048766.89it/s]" } }, "378e399b9dde438e91ea576916fc7f5b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_7fa15f28033e4c0cbdca4d87019dde74", "max": 170498071, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_9ecef5efa63041599041d76ee295a8c8", "value": 170498071 } }, "3e0bd075e0174bc1bdcb137bafa82b80": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_9c92e8e0174c44388aaf7e50297e0d3b", "IPY_MODEL_378e399b9dde438e91ea576916fc7f5b", "IPY_MODEL_3070edc6c79b40309c198b5c4845c569" ], "layout": "IPY_MODEL_eccc0d3be2f84bd5954077b0c5ed0fee" } }, "7d4297ecd6bd41f58fa31e61c6cfa341": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7fa15f28033e4c0cbdca4d87019dde74": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7fce1614a72d47e7b0fd3d59c692e2cb": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "909d0ff2a5454898827ccb8b0c83f318": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "97433cc60d6841859129fcb83c67ec4b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_c41ea09afdd8433c9d4593ccf9a4d4e9", "IPY_MODEL_a797b8179d314847915848d12720352e", "IPY_MODEL_b6cbb990998e4ce890309fb7065803ff" ], "layout": "IPY_MODEL_909d0ff2a5454898827ccb8b0c83f318" } }, "9af871bc187c47b89603944054aac415": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9c92e8e0174c44388aaf7e50297e0d3b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_e0537b86f5b64a098a72b5452093d378", "placeholder": "​", "style": "IPY_MODEL_0c08e5867eef48cfae0adf6a02915631", "value": "" } }, "9ecef5efa63041599041d76ee295a8c8": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "a797b8179d314847915848d12720352e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_9af871bc187c47b89603944054aac415", "max": 170498071, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_b528593e4a024f428b1a0a8fb49e2386", "value": 170498071 } }, "b528593e4a024f428b1a0a8fb49e2386": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "b6cbb990998e4ce890309fb7065803ff": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_7d4297ecd6bd41f58fa31e61c6cfa341", "placeholder": "​", "style": "IPY_MODEL_068c5d4019c740019f30c75afaf877c6", "value": " 170499072/? [00:02<00:00, 64265175.65it/s]" } }, "c41ea09afdd8433c9d4593ccf9a4d4e9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_f7325c3b35ad4414bd1c7ab3ffb7858f", "placeholder": "​", "style": "IPY_MODEL_7fce1614a72d47e7b0fd3d59c692e2cb", "value": "" } }, "e0537b86f5b64a098a72b5452093d378": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "eccc0d3be2f84bd5954077b0c5ed0fee": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f7325c3b35ad4414bd1c7ab3ffb7858f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "fc8f946314f641c5af76cf7d62c7b4db": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } } } } }, "nbformat": 4, "nbformat_minor": 5 }