diff --git a/v/latest/api/_modules/botorch/models/contextual_multioutput.html b/v/latest/api/_modules/botorch/models/contextual_multioutput.html index 16a76051ee..7bce3e456f 100644 --- a/v/latest/api/_modules/botorch/models/contextual_multioutput.html +++ b/v/latest/api/_modules/botorch/models/contextual_multioutput.html @@ -27,6 +27,16 @@
References
+Q. Feng, B. Latham, H. Mao and E. Backshy. High-Dimensional Contextual Policy +Search with Unknown Context Rewards using Bayesian Optimization. +Advances in Neural Information Processing Systems 33, NeurIPS 2020.
+Bases: MultiTaskGP
The Multi-Task GP with the latent context embedding multioutput -(LCE-M) kernel.
+The Multi-Task GP with the latent context embedding multioutput (LCE-M) +kernel. See [Feng2020HDCPS] for a reference on the model and its use in Bayesian +optimization.
train_X (Tensor) – (n x d) X training data.
train_Y (Tensor) – (n x 1) Y training data.
task_feature (int) – Column index of train_X to get context indices.
train_Yvar (Tensor | None) – An optional (n x 1) tensor of observed variances of each +training Y. If None, we infer the noise. Note that the inferred noise +is common across all tasks.
context_cat_feature (Tensor | None) – (n_contexts x k) one-hot encoded context features. Rows are ordered by context indices, where k is the number of categorical variables. If None, task indices will @@ -2424,12 +2437,13 @@
Bases: LCEMGP
The Multi-Task GP the latent context embedding multioutput (LCE-M) kernel, with known observation noise.
+DEPRECATED: Please use LCEMGP with train_Yvar instead.
train_X (Tensor) – (n x d) X training data.
train_Y (Tensor) – (n x 1) Y training data.
train_Yvar (Tensor) – (n x 1) Noise variances of each training Y.
train_Yvar (Tensor) – (n x 1) Observed variances of each training Y.
task_feature (int) – Column index of train_X to get context indices.
context_cat_feature (Tensor | None) – (n_contexts x k) one-hot encoded context features. Rows are ordered by context indices, where k is the @@ -2461,21 +2475,21 @@
David R. Burt and Carl Edward Rasmussen and Mark van der Wilk, Convergence of Sparse Variational Inference in Gaussian Process Regression, Journal of Machine Learning Research, 2020, http://jmlr.org/papers/v21/19-1015.html.
James Hensman and Nicolo Fusi and Neil D. Lawrence, Gaussian Processes for Big Data, Proceedings of the 29th Conference on Uncertainty in Artificial Intelligence, 2013, https://arxiv.org/abs/1309.6835.
Henry B. Moss and Sebastian W. Ober and Victor Picheny, Inducing Point Allocation for Sparse Gaussian Processes in High-Throughput Bayesian Optimization,Proceedings of @@ -2595,12 +2609,12 @@
Bases: ApproximateGPyTorchModel
A single-task variational GP model following [hensman2013svgp].
+A single-task variational GP model following [hensman2013svgp].
By default, the inducing points are initialized though the -GreedyVarianceReduction of [burt2020svgp], which is known to be +GreedyVarianceReduction of [burt2020svgp], which is known to be effective for building globally accurate models. However, custom inducing point allocators designed for specific down-stream tasks can also be -provided (see [moss2023ipa] for details), e.g. GreedyImprovementReduction +provided (see [moss2023ipa] for details), e.g. GreedyImprovementReduction when the goal is to build a model suitable for standard BO.
A single-task variational GP using relatively strong priors on the Kernel hyperparameters, which work best when covariates are normalized to the unit @@ -2712,7 +2726,7 @@
D. Eriksson, M. Jankowiak. High-Dimensional Bayesian Optimization with Sparse Axis-Aligned Subspaces. Proceedings of the Thirty- Seventh Conference on Uncertainty in Artificial Intelligence, 2021.
@@ -2773,7 +2787,7 @@The SAAS model uses sparsity-inducing priors to identify the most important parameters. This model is suitable for high-dimensional BO with potentially -hundreds of tunable parameters. See [Eriksson2021saasbo] for more details.
+hundreds of tunable parameters. See [Eriksson2021saasbo] for more details.SaasPyroModel is not a standard BoTorch model; instead, it is used as an input to SaasFullyBayesianSingleTaskGP. It is used as a default keyword argument, and end users are not likely to need to instantiate or modify a @@ -2902,7 +2916,7 @@
You are expected to use fit_fully_bayesian_model_nuts to fit this model as it isn’t compatible with fit_gpytorch_model.
@@ -3127,7 +3141,7 @@This model assumes that the inputs have been normalized to [0, 1]^d and that the output has been stratified standardized to have zero mean and unit variance for -each task.The SAAS model [Eriksson2021saasbo] with a Matern-5/2 is used as data +each task.The SAAS model [Eriksson2021saasbo] with a Matern-5/2 is used as data kernel by default.
You are expected to use fit_fully_bayesian_model_nuts to fit this model as it isn’t compatible with fit_gpytorch_model.
@@ -3581,14 +3595,14 @@Bases: Kernel
Orthogonal Additive Kernels (OAKs) were introduced in [Lu2022additive], though +
Orthogonal Additive Kernels (OAKs) were introduced in [Lu2022additive], though only for the case of Gaussian base kernels with a Gaussian input data distribution.
The implementation here generalizes OAKs to arbitrary base kernels by using a Gauss-Legendre quadrature approximation to the required one-dimensional integrals involving the base kernels.
X. Lu, A. Boukouvalas, and J. Hensman. Additive Gaussian processes revisited. Proceedings of the 39th International Conference on Machine Learning. Jul 2022.
D. Eriksson, M. Poloczek. Scalable Constrained Bayesian Optimization. International Conference on Artificial Intelligence and Statistics. PMLR, 2021, http://proceedings.mlr.press/v130/eriksson21a.html
@@ -4257,7 +4271,7 @@Bases: OutcomeTransform
Bilog-transform outcomes.
-The Bilog transform [eriksson2021scalable] is useful for modeling outcome +
The Bilog transform [eriksson2021scalable] is useful for modeling outcome constraints as it magnifies values near zero and flattens extreme values.
Bilog-transform outcomes.
The steps for using this to obtain samples of a risk measure are as follows:
Laming Chen and Guoxin Zhang and Hanning Zhou, Fast greedy MAP inference for determinantal point process to improve recommendation diversity, Proceedings of the 32nd International Conference on Neural Information @@ -5530,7 +5544,7 @@
QualityFunction
A function measuring the quality of input points as their expected improvement with respect to a conservative baseline. Expectations -are according to the model from the previous BO step. See [moss2023ipa] +are according to the model from the previous BO step. See [moss2023ipa] for details and justification.
Bases: InducingPointAllocator
The inducing point allocator proposed by [burt2020svgp], that +
The inducing point allocator proposed by [burt2020svgp], that greedily chooses inducing point locations with maximal (conditional) predictive variance.
InducingPointAllocator
An inducing point allocator that greedily chooses inducing points with large predictive variance and that are in promising regions of the search -space (according to the model form the previous BO step), see [moss2023ipa].
+space (according to the model form the previous BO step), see [moss2023ipa].A pivoted Cholesky initialization method for the inducing points, -originally proposed in [burt2020svgp] with the algorithm itself coming from -[chen2018dpp]. Code is a PyTorch version from [chen2018dpp], based on +originally proposed in [burt2020svgp] with the algorithm itself coming from +[chen2018dpp]. Code is a PyTorch version from [chen2018dpp], based on https://github.com/laming-chen/fast-map-dpp/blob/master/dpp.py but with a small modification to allow the underlying DPP to be defined through its diversity-quality -decomposition,as discussed by [moss2023ipa]. This method returns a greedy +decomposition,as discussed by [moss2023ipa]. This method returns a greedy approximation of the MAP estimate of the specified DPP, i.e. its returns a set of points that are highly diverse (according to the provided kernel_matrix) and have high quality (according to the provided quality_scores).
diff --git a/v/latest/api/models/index.html b/v/latest/api/models/index.html index e0582fedbd..f598b4e6ae 100644 --- a/v/latest/api/models/index.html +++ b/v/latest/api/models/index.html @@ -2347,18 +2347,31 @@References
+Q. Feng, B. Latham, H. Mao and E. Backshy. High-Dimensional Contextual Policy +Search with Unknown Context Rewards using Bayesian Optimization. +Advances in Neural Information Processing Systems 33, NeurIPS 2020.
+Bases: MultiTaskGP
The Multi-Task GP with the latent context embedding multioutput -(LCE-M) kernel.
+The Multi-Task GP with the latent context embedding multioutput (LCE-M) +kernel. See [Feng2020HDCPS] for a reference on the model and its use in Bayesian +optimization.
train_X (Tensor) – (n x d) X training data.
train_Y (Tensor) – (n x 1) Y training data.
task_feature (int) – Column index of train_X to get context indices.
train_Yvar (Tensor | None) – An optional (n x 1) tensor of observed variances of each +training Y. If None, we infer the noise. Note that the inferred noise +is common across all tasks.
context_cat_feature (Tensor | None) – (n_contexts x k) one-hot encoded context features. Rows are ordered by context indices, where k is the number of categorical variables. If None, task indices will @@ -2424,12 +2437,13 @@
Bases: LCEMGP
The Multi-Task GP the latent context embedding multioutput (LCE-M) kernel, with known observation noise.
+DEPRECATED: Please use LCEMGP with train_Yvar instead.
train_X (Tensor) – (n x d) X training data.
train_Y (Tensor) – (n x 1) Y training data.
train_Yvar (Tensor) – (n x 1) Noise variances of each training Y.
train_Yvar (Tensor) – (n x 1) Observed variances of each training Y.
task_feature (int) – Column index of train_X to get context indices.
context_cat_feature (Tensor | None) – (n_contexts x k) one-hot encoded context features. Rows are ordered by context indices, where k is the @@ -2461,21 +2475,21 @@
David R. Burt and Carl Edward Rasmussen and Mark van der Wilk, Convergence of Sparse Variational Inference in Gaussian Process Regression, Journal of Machine Learning Research, 2020, http://jmlr.org/papers/v21/19-1015.html.
James Hensman and Nicolo Fusi and Neil D. Lawrence, Gaussian Processes for Big Data, Proceedings of the 29th Conference on Uncertainty in Artificial Intelligence, 2013, https://arxiv.org/abs/1309.6835.
Henry B. Moss and Sebastian W. Ober and Victor Picheny, Inducing Point Allocation for Sparse Gaussian Processes in High-Throughput Bayesian Optimization,Proceedings of @@ -2595,12 +2609,12 @@
Bases: ApproximateGPyTorchModel
A single-task variational GP model following [hensman2013svgp].
+A single-task variational GP model following [hensman2013svgp].
By default, the inducing points are initialized though the -GreedyVarianceReduction of [burt2020svgp], which is known to be +GreedyVarianceReduction of [burt2020svgp], which is known to be effective for building globally accurate models. However, custom inducing point allocators designed for specific down-stream tasks can also be -provided (see [moss2023ipa] for details), e.g. GreedyImprovementReduction +provided (see [moss2023ipa] for details), e.g. GreedyImprovementReduction when the goal is to build a model suitable for standard BO.
A single-task variational GP using relatively strong priors on the Kernel hyperparameters, which work best when covariates are normalized to the unit @@ -2712,7 +2726,7 @@
D. Eriksson, M. Jankowiak. High-Dimensional Bayesian Optimization with Sparse Axis-Aligned Subspaces. Proceedings of the Thirty- Seventh Conference on Uncertainty in Artificial Intelligence, 2021.
@@ -2773,7 +2787,7 @@The SAAS model uses sparsity-inducing priors to identify the most important parameters. This model is suitable for high-dimensional BO with potentially -hundreds of tunable parameters. See [Eriksson2021saasbo] for more details.
+hundreds of tunable parameters. See [Eriksson2021saasbo] for more details.SaasPyroModel is not a standard BoTorch model; instead, it is used as an input to SaasFullyBayesianSingleTaskGP. It is used as a default keyword argument, and end users are not likely to need to instantiate or modify a @@ -2902,7 +2916,7 @@
You are expected to use fit_fully_bayesian_model_nuts to fit this model as it isn’t compatible with fit_gpytorch_model.
@@ -3127,7 +3141,7 @@This model assumes that the inputs have been normalized to [0, 1]^d and that the output has been stratified standardized to have zero mean and unit variance for -each task.The SAAS model [Eriksson2021saasbo] with a Matern-5/2 is used as data +each task.The SAAS model [Eriksson2021saasbo] with a Matern-5/2 is used as data kernel by default.
You are expected to use fit_fully_bayesian_model_nuts to fit this model as it isn’t compatible with fit_gpytorch_model.
@@ -3581,14 +3595,14 @@Bases: Kernel
Orthogonal Additive Kernels (OAKs) were introduced in [Lu2022additive], though +
Orthogonal Additive Kernels (OAKs) were introduced in [Lu2022additive], though only for the case of Gaussian base kernels with a Gaussian input data distribution.
The implementation here generalizes OAKs to arbitrary base kernels by using a Gauss-Legendre quadrature approximation to the required one-dimensional integrals involving the base kernels.
X. Lu, A. Boukouvalas, and J. Hensman. Additive Gaussian processes revisited. Proceedings of the 39th International Conference on Machine Learning. Jul 2022.
D. Eriksson, M. Poloczek. Scalable Constrained Bayesian Optimization. International Conference on Artificial Intelligence and Statistics. PMLR, 2021, http://proceedings.mlr.press/v130/eriksson21a.html
@@ -4257,7 +4271,7 @@Bases: OutcomeTransform
Bilog-transform outcomes.
-The Bilog transform [eriksson2021scalable] is useful for modeling outcome +
The Bilog transform [eriksson2021scalable] is useful for modeling outcome constraints as it magnifies values near zero and flattens extreme values.
Bilog-transform outcomes.
The steps for using this to obtain samples of a risk measure are as follows:
Laming Chen and Guoxin Zhang and Hanning Zhou, Fast greedy MAP inference for determinantal point process to improve recommendation diversity, Proceedings of the 32nd International Conference on Neural Information @@ -5530,7 +5544,7 @@
QualityFunction
A function measuring the quality of input points as their expected improvement with respect to a conservative baseline. Expectations -are according to the model from the previous BO step. See [moss2023ipa] +are according to the model from the previous BO step. See [moss2023ipa] for details and justification.
Bases: InducingPointAllocator
The inducing point allocator proposed by [burt2020svgp], that +
The inducing point allocator proposed by [burt2020svgp], that greedily chooses inducing point locations with maximal (conditional) predictive variance.
InducingPointAllocator
An inducing point allocator that greedily chooses inducing points with large predictive variance and that are in promising regions of the search -space (according to the model form the previous BO step), see [moss2023ipa].
+space (according to the model form the previous BO step), see [moss2023ipa].A pivoted Cholesky initialization method for the inducing points, -originally proposed in [burt2020svgp] with the algorithm itself coming from -[chen2018dpp]. Code is a PyTorch version from [chen2018dpp], based on +originally proposed in [burt2020svgp] with the algorithm itself coming from +[chen2018dpp]. Code is a PyTorch version from [chen2018dpp], based on https://github.com/laming-chen/fast-map-dpp/blob/master/dpp.py but with a small modification to allow the underlying DPP to be defined through its diversity-quality -decomposition,as discussed by [moss2023ipa]. This method returns a greedy +decomposition,as discussed by [moss2023ipa]. This method returns a greedy approximation of the MAP estimate of the specified DPP, i.e. its returns a set of points that are highly diverse (according to the provided kernel_matrix) and have high quality (according to the provided quality_scores).
diff --git a/v/latest/files/batch_mode_cross_validation.ipynb b/v/latest/files/batch_mode_cross_validation.ipynb index eab9277ed9..383bcc8d3d 100644 --- a/v/latest/files/batch_mode_cross_validation.ipynb +++ b/v/latest/files/batch_mode_cross_validation.ipynb @@ -1,329 +1,330 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "## Application of batch-mode regression to cross-validation\n", - "\n", - "botorch provides a helper function `gen_loo_cv_folds` to easily perform leave-one-out (LOO) cross-validation (CV) by taking advantage of batch-mode regression and evaluation in GPyTorch. This tutorial illustrates the process on a noisy sinusoidal function, similar to the example from the batch-mode GP regression [tutorial](https://github.com/cornellius-gp/gpytorch/blob/master/examples/01_Simple_GP_Regression/Simple_Batch_Mode_GP_Regression.ipynb) from GPyTorch:\n", - "\n", - "$$y = \\sin(2\\pi x) + \\epsilon, ~\\epsilon \\sim \\mathcal N(0, 0.2).$$\n", - "\n", - "Note: this tutorial aims to introduce batch-mode regression and evaluation in GPyTorch with CV as an example application. For alternative, more user-friendly functions to perform CV in Ax, see [ax.modelbridge.cross_validation](https://github.com/facebook/Ax/blob/main/ax/modelbridge/cross_validation.py). However, for larger CV tasks, it may be useful to exploit GPyTorch batch-mode, as shown in this tutorial." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import torch\n", - "import math\n", - "\n", - "device = torch.device(\"cpu\")\n", - "dtype = torch.float\n", - "torch.manual_seed(3);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Initialize the CV dataset\n", - "\n", - "For our training data, we take 20 regularly spaced points on the interval $[0, 1]$ and generate noisy evaluations with an observed noise variance of 0.2. Remember that botorch requires an explicit output dimension." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "sigma = math.sqrt(0.2)\n", - "train_X = torch.linspace(0, 1, 20, dtype=dtype, device=device).view(-1, 1)\n", - "train_Y_noiseless = torch.sin(train_X * (2 * math.pi))\n", - "train_Y = train_Y_noiseless + sigma * torch.randn_like(train_Y_noiseless)\n", - "train_Yvar = torch.full_like(train_Y, 0.2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The botorch function `gen_loo_cv_folds` takes our observed data `train_X`, `train_Y`, `train_Yvar` as input and returns the LOO CV folds in a `CVFolds` object." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from botorch.cross_validation import gen_loo_cv_folds\n", - "\n", - "cv_folds = gen_loo_cv_folds(train_X=train_X, train_Y=train_Y, train_Yvar=train_Yvar)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `cv_folds` object contains the data, stored as tensors of appropriate batch shape, necessary to perform 20 CVs of 19 training points and 1 test point. For example, we can check that the shapes of the training inputs and training targets are `b x n x d = 20 x 19 x 1` and `b x n x o = 20 x 19 x 1` respectively, where `o` is the number of outputs." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ + "cells": [ { - "data": { - "text/plain": [ - "(torch.Size([20, 20, 1]), torch.Size([20, 20, 1]))" + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Application of batch-mode regression to cross-validation\n", + "\n", + "botorch provides a helper function `gen_loo_cv_folds` to easily perform leave-one-out (LOO) cross-validation (CV) by taking advantage of batch-mode regression and evaluation in GPyTorch. This tutorial illustrates the process on a noisy sinusoidal function, similar to the example from the batch-mode GP regression [tutorial](https://github.com/cornellius-gp/gpytorch/blob/master/examples/01_Exact_GPs/Simple_GP_Regression.ipynb) from GPyTorch:\n", + "\n", + "$$y = \\sin(2\\pi x) + \\epsilon, ~\\epsilon \\sim \\mathcal N(0, 0.2).$$\n", + "\n", + "Note: this tutorial aims to introduce batch-mode regression and evaluation in GPyTorch with CV as an example application. For alternative, more user-friendly functions to perform CV in Ax, see [ax.modelbridge.cross_validation](https://github.com/facebook/Ax/blob/main/ax/modelbridge/cross_validation.py). However, for larger CV tasks, it may be useful to exploit GPyTorch batch-mode, as shown in this tutorial." ] - }, - "execution_count": 4, - "metadata": { - "bento_obj_id": "140675275377288" - }, - "output_type": "execute_result" - } - ], - "source": [ - "cv_folds.train_X.shape, cv_folds.train_Y.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ + }, { - "data": { - "text/plain": [ - "(torch.Size([20, 1, 1]), torch.Size([20, 1, 1]))" + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import torch\n", + "import math\n", + "\n", + "device = torch.device(\"cpu\")\n", + "dtype = torch.float\n", + "torch.manual_seed(3);" ] - }, - "execution_count": 5, - "metadata": { - "bento_obj_id": "140676807470216" - }, - "output_type": "execute_result" - } - ], - "source": [ - "cv_folds.test_X.shape, cv_folds.test_Y.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that in a situation where the dataset is large, one may not want to perform LOO; in that case, a similar process can be used to perform $k$-fold CV." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Perform LOOCV\n", - "\n", - "We can use the `batch_cross_validation` function to perform LOOCV using batching (meaning that the `b = 20` sets of training data can be fit as `b = 20` separate GP models with separate hyperparameters in parallel through GPyTorch) and return a CVResult tuple with the batched `GPyTorchPosterior` object over the LOOCV test points and the observed targets. The `batch_cross_validation` requires a model class (`model_cls`) and a marginal log likelihood class (`mll_cls`). Since we have an observed and constant noise level, we will use the FixedNoiseGP as the `model_cls` and an ExactMarginalLogLikelihood as the `mll_cls`." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from botorch.cross_validation import batch_cross_validation\n", - "from botorch.models import FixedNoiseGP\n", - "from gpytorch.mlls.exact_marginal_log_likelihood import ExactMarginalLogLikelihood\n", - "\n", - "# instantiate and fit model\n", - "cv_results = batch_cross_validation(\n", - " model_cls=FixedNoiseGP,\n", - " mll_cls=ExactMarginalLogLikelihood,\n", - " cv_folds=cv_folds,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Compute the cross-validation error and generate plots\n", - "To compute the cross-validation error, we first evaluate the test points by computing the posterior in batch mode. Next, we compute the squared errors for each test point from the prediction and take an average across all cross-validation folds." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "Cross-validation error: 0.062\n" - ] + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Initialize the CV dataset\n", + "\n", + "For our training data, we take 20 regularly spaced points on the interval $[0, 1]$ and generate noisy evaluations with an observed noise variance of 0.2. Remember that botorch requires an explicit output dimension." + ] }, { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAAEHCAYAAABFroqmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3Xl4VOXZx/FvEsJiWCIIYlVIRSrW\nvSoYBEGRJYgoIg8iUhH1xV2gqLRuuKFoFUFFrdRqBYUHUmRNBCJBCBHU1gUXVKzsCooGgpB13j84\noTHLzJDMzDmT+X2ui4vJWe85mTl3zrPG+Xw+REREyot3OwAREfEeJQcREalEyUFERCpRchARkUqU\nHEREpJJ6bgcQCllZWWpyJSJSAz169IiranmdSA4ceIN+12dnZ9O9e/eIxRNtdH380/XxT9fHP69e\nn6ysrGrXqVhJREQqUXIQEZFKlBxERKQSJQcREalEyUFERCpRchARkUqUHEREpBIlBxERqUTJQUQ8\nYdLSL90OQcpRchART5ic9ZXbIUg5Sg4iIlKJq2MrGWNOBuYBk6y1z1ZY9y2wGShxFg211m51J1IR\n8bJJS79kdM/fuR1GneJacjDGJAHPANWP/ARp1tr8CIYlIlFoctZXSg4h5maxUgHQF9jmYgwiUsfM\nmzeP5557zu0wop5rTw7W2mKg2Bjjb7MXjDEpwCrgz9ZazdsgEiHRWFQzdepUbr31Vnw+Hx07duTs\ns892O6So5eX5HO4DMoFdwJvAQGBOdRtnZ2f7PVh+fn7AbWKZro9/sXh9Jmft5YzE4B7sQ3V9anoM\nn6+UK6+8kjfeeAOA4cOHe+p35qVYguXZ5GCt/WfZa2PMYuAUf8kh0EQaXp1swyt0ffyLyeuTuSjo\n9xyS63MI5yuvsLCQH2/uzRufZZOQkMBLL73ENddcU7tYQsyrnx9/k/14MjkYY5oBFrjYWlsIdPOX\nGEQkNuXl5TFw4ED2fpZNUlISc+bMoU+fPm6HVSe42VrpTOBJIAUoMsZcDswH/mutnes8LbxrjNkH\n/AdIdytWEfGerVu30rdvXz7++GPik5JZsWIZZ555ptth1RluVkh/AFT7nGWtnQxMjmxUIhINPv30\nU9LS0ti8eTMnnHACe7rfocQQYuohLSJRZcWKFXTp0oXNmzfTuXNncnJySExu7XZYdY6Sg4hEDWst\nvXr14ueff2bAgAEsW7aMFi1auB1WnaTkICJRYdKkSQwePJjCwkJuueUWZs+eTaNGjdwOq85SchAR\nv9weSru0tJTRo0czZswYACZOnMiUKVNISEhwNa66TslBRPxycyjt/fv3M3jwYJ5++mkSExOZMWMG\nd955J3Fxca7FFCs82c9BRGTXrl1ceumlrFy5kqZNmzJ37lwuuOACt8OKGXpyEIlxbhcbVWXjxo10\n6dKFlStXcvTRR7Ny5UolhghTchCJcV6bge3DDz8kNTWVzz//nJNOOonc3FxOPfVUt8OKOUoOIuIZ\nS5cu5bzzzmP79u10796dVatWceyxx7odVkxSchART8hf9zZ9+/Zlz549XHHFFWRmZpKcnOx2WDFL\nyUFEXOXz+Xj00Uf5cdFTFBcXM3bsWGbMmEGDBg3cDi2mqbWSiLimpKSEW2+9leeffx6IY/Lkp7nt\nttvcDkuUHETELb/88gtDhgxh/vz5NGjQgCZpY5QYPETFSiIScTt37uSCCy5g/vz5HH744Sxbtoyk\nE851OywpR8lBRCJqw4YNdO7cmTVr1tC2bVtycnLo0qWL22FJBUoOIhIx7733HqmpqXz99decfvrp\n5ObmcuKJJ7Jj934AduzZ73aI4lByEJGIWLTowBzRO3fupGfPnqxYsYKjjjoKgClOR7wpy7zVIS+W\nqUJaRMJu2rRp3HDDDZSUlHD11Vfz0ksvkZiYyAn3ZFBQXHpwu+lrNjF9zSYa1Itn/cNprsYc65Qc\nRDxi0tIvXRvKImXcIr/Lq1v/K5mVt/H5fOStep281W8A0Cx1MMuPvJz29y7xe6iC4tLgzllFrJ5V\nxfUpc3uP9ozu+buIhhOIkoOIR4zu+TtXbhAp4xbx7WMXVbu8uvXlZWdn0737r6eELyoqYuTIkfxj\n9RvEx8czdepURo4cWWnfu+d+wutrN+HzQVwcDO3YhocHnBJ0/PfM/YTpazZxVadD2y+Sqro+Xqfk\nICIhl5+fz6BBg8jMzKRRo0bMmjWLiy++uMptf8gvYGintkx/dyNDO7VlZ5CV0iqSCi8lB5E6oLZF\nUqEsVirJ/4kdc8ZT+P0G4hs1pdnl93NrTjy35gQ+xvR3NwZ/vmrUpEgqIvwUK9VGuIqklBxEImzS\n0i9D/mX2VyQVqFioqvU7du+n44Qs1t7dg46PZAVdrLR+/Xr69OlD4fff0q5dOzIzMzn++OODeg/B\nFF9VVNsiqUhRsdIhMsacDMwDJllrn62w7kJgAlACLLbWPuRepCKhMznrK89VPlZUk6alOTk59O/f\nn127dnH22WezcOFCWrVqFcYoa14kJYG5lhyMMUnAM0BWNZtMAXoDW4EVxph0a+1nEQ5TJKZUVY5f\nttxfOf7KlSuZMGEC+/fvp1+/fsycOZOkpKSwx/visLMOxPnuRh6+9OSwny+WuPnkUAD0Be6quMIY\ncxywy1q72fl5MdADUHKQiKlUjh/CMuNIl4kHOl+g9f7K8Xd/sICflv0N8NH4tD58fOL1nPRQdlji\nDNe+FXmxaWmkuZYcrLXFQLExpqrVrYGd5X7eAbTzd7zsbP8fxvz8/IDbxDJdn8rOSIRX+hz46zc/\nP5/GjRuH5LjDM/cePG64lD9HoPNVXP/qpwVkby7GB8QBPqhy/9LSUl566SVmLpsJwLXXXsvQoUOJ\ni4urdcyR3Ldq28jO3hayo0Xj98urFdIVP11ln9FqBarsicYKoUjS9fEvpNcnc1H4r3X5cwQ6X4X1\nb2x+n6HnNDxQjn/OgfL8ivsXFBQwYsQIZs6cSb169fjTn/7EY489FrqYI7lvBHj1+5WVVV2pvneT\nw1bn6aHM0cB2F+MRiRkVy/HLmpeWycvLY8CAASxfvpzGjRuTnp5O/fr1XYpWwsWTA+9Za78Fmhpj\nUowx9YB+gP/+9iISdlu2bKFr164sX76c1q1b884779CrVy+3w5IwcLO10pnAk0AKUGSMuRyYD/zX\nWjsXuBF4w9l8lrX2S7diFRFYt24daWlpbNmyhQ4dOpCRkUFKSorbYUmYuFkh/QFQbSGctfYdIDWy\nUYlIeWXzLLz51tsMH3wZeXl5nHvuucyfP5/mzZu7HZ6EkSeLlUTEG6ZkfYXP5+P6p/9FXl4el112\nGUuXLlViiAFerZAWkQgoPwNbqyYNDy4/4Z4McDrBxcXFkXRaGkmnpbGuXjyNGjVyLV6JHCUHkQAO\ndIbbG3Wd4MqfI9D5Oj7y6yaNvtISCr//hsQjjiU+sSG+kmKIT/A/qF0Iro9XOsGVieXOcEoOIgGM\n7vk7zkjcFrJ26jUZYK4256jqfBWHySjToF48H97dnWHDhvH2niOpf2Q7fKUlxNer53dQu1C046/N\ndYnENY01Sg4iwQ55XYefHMr8smc3h7c/i4Ktn9Fy4L2U7N1FvSZH4PP9b76EakXhk0MsPxkEouQg\nEsQsbKHs4eqFJweqGO764hMPZ+mjY9my9QuOOeYYSpodyZbnrq7xTHC1iTmS+0rV1FpJJApMWvpl\nla9ro2y4a4Dexx3G3IxlfPHFF5xyyink5uZSv6X6MMQyJQeRKFC+yKs2M76V9+Kws3j40pPZ999/\nM2NMf7bMvJ/zzz+flStXcswxx4TkHBK9lBxEYtirr77KjjkPkJ+fz5AhQ8jIyKBZs2ZuhyUeoOQg\nEoN8Ph+PPPIIw4cPh9IS7rzzTqZPn06DBg3cDk08QslBxI9Qle97SXFxMTfeeCP33HMPcXFxHH7h\nSCZOnEh8vG4H8j/6NIj4Earyfa/Yu3cvAwYM4MUXX6Rhw4bMmTOHpmde7HZY4kFKDiIxYseOHVxw\nwQUsXLiQ5s2bs2zZMi677DK3wxKPUj8HkRjw9ddf06dPHzZs2EBKSgoZGRl06NDB7bDEw/TkIFLH\nFWxbT+fOndmwYQN/+MMfyM3NVWKQgPTkIFKHLVy4kO/f+Au+4gJ69+7N7NmzadKkidthSRRQchCp\no/72t79x89i/0GrQeHoctpFXnp9CYmKi22FJlFCxkkgElZ8/IVx8Ph8/v/MaI0eOpMk5hgbHnsxv\nL7rJ84nh9h7t3Q5BylFyEImgKU7T2CnLwtNEtqioiGuuuYamnQfT9q6FNP3DRcTFxTF9zSZSxi06\nOImPF2l0VG+J8/l8bsdQa1lZWb4ePXr43SaUo2rWRXX9+gQ1JHeUKy34hZ1vPsr+b/9DQvKRtL7y\nceo1aeF2WK7yypDcXv1+ZWVl0aNHj7iq1qnOQVwRCzfrSCrO38XOOQ9Q+P0G4g9rRsv+d3kyMYTr\nZj1p6ZeeSAJ1iZKDuCLQ/AleUTZPQCj+8qs4f4K/mdWqi6Pia4DPP/+ctLSbKfx+I8cffzyZmZn0\neOkLep90JC2bNGT6uxu56py27NyznxeHneX32FUtj9R8DrURDZ+laKPkIBIhZfMnTH93I0M7HbhZ\n19aqVavo378/P/30E506dWLBggW0bNkS+OJgIpj+7kYevvTkELwDiSWuJQdjzCTgHMAH3G6tfa/c\num+BzUCJs2iotXarW7GKhEKob9bp6ekMHTqUgoIC+vfvzxtvvMFhhx0WgkgPUOuh2OZKcjDGdAPa\nW2tTjTEnAi8DqRU2S7PW5rsRn0gohLMcfMqUKYwaNQqfz8cNN9zAM888Q716of06q6gmtrnVlLUH\n8CaAtfZz4HBjTFOXYhEJi3BUuJeWlvLT8pe5/fbb8fl8TJgwgalTp4Y8MYi49YlqDXxQ7uedzrLd\n5Za9YIxJAVYBf7bW+m1zm52d7feE+fn5AbeJZbo+1cvOzq7x9alun5oca8mSJUycOJHda98mISGB\nO++8k9TUVFasWBHwHIHOV9v1+vz4F43Xx63kULFdbZxT91DmPiAT2OU8YQwE5vg7YKCWEm63pvA6\nXZ9qZC6ie/fuNbs+zr5BL/ej9M1ZPProC2RnZxNXvxEZC+fRs2fP4M4d6Hy1Xa/PT0BevT5ZWVnV\nrnMrOWx1nhTK/Ab4ruwHa+0/y14bYxYDpwRKDiJ11ebNm/luxl1s/mEjRx11FPT+s//EIBICbtU5\nLAEu58DN/wxgm7V2j/NzM2PMW8aY+s623YB1LsUpdVS0TP/5ySefkJqaStEPGznxxBPJzc2l/pHH\nuR2WxABXkoO1djXwgTFmNfAMcLMxZrgxZoC1Ng9YDLxrjMlx6iPS3YhT6q5o6J399ttv06VLF7Zu\n3UqDY05i1apVtG3b1u2wJEa41sTBWjuuwqKPyq2bDEyOfFQi3vD6668zfPhwioqKuPzyy1nb9kqa\nN2/udlgSQzQqq4iH+Hw+Hn/8cYYOHUpRURGjRo1i1qxZxNWrH8TeIqHj98nBGPPfCq2IKrHWqgBU\nJARKSkoYNWoUzz77LABPPfUUo0eP/tUcEK2aNIx4XOopHZsCFStd5fzfEzgVmA78BLQChgIrIxCj\nSJ23b98+hg4dyty5c6lfvz6vvfYaxhioMAdEsAP1hZJ6Sscmv8nBWpvDgSeIycDZ5TuiGWPmAO8B\nT0QiUJG66scff6R///6sXr2a5ORk3nzzTbp168YJ92RQUFx6cLvpazYxfc2mgMc71CcNPRlIVYKt\nkG4FtAB+KLesGXBEmOIS+ZVwzP+QMm7RoW2XGdz2wZyjbHnRz9+xY/Z4indtIaFJSxpdNp6rM/Ih\nw/+5gom94yP/6+AUaPuQXNsaXJ9geGXCnlgTbHL4G7DeGJMN5DmJoQvwQpjjE4EwzP8QzBwF1HI+\nh0DzJPz73/+mb99rKd71PaeeeiqLFy/m6KOP/tW2FeeAOL5lY77akc9VnSrPBVHxSaO8YN5rbXi1\nB7DUXNDThBpjfg90BZo79Q6rrbUfhz3CIGia0Nqra9fH6zPN7fvmA3bOewxf4T4atj2NlgP+QnyD\nJLfDqhO8+KTh1e9XqKYJ3Q7sBRKttS8YY44OYh+RsPD6zd+f/E+W8WPGFPCVkvT77rToeztxCYlu\nhxUVvHjjr6uCSg7GmD5OS6WVwJnAs8CDxpgN1toJ4Q9TYpG/+RBqW8zkRrGSz+fj4Ycf5r7FTwMw\nbtw4HnnkEeLjA3c3Shm3iKGd2gScZnTka+9Xmhr0rU+/V7GSHLJgO8E9DXSy1g5wnh4Abi3X1FUk\n5KL1yaAqxcXFjBw5kvvuuw/i4nnuued49NFHg0oMZcqmGQUOTDOaX1BpmxeHnXVwlrmHLz25yjmj\nRYIRbLFSnLV2g/Pax4Fmrr8YY6osqxKR/9m7dy+DBw9m0aJFNGzYkCZ9x3LTTTcd8nE0J7REUrDJ\nYb0xZrzzBIExphFwE1B3/rQTCYMdO3Zw0UUX8f7779OiRQsWLFjAkHm73A5LJKBgn2lvdJqu/gh0\ncJqzdgX+L8zxiUStol1bSU1N5f333+e3v/0tq1evJjW14lTpIt4UbHKoZ629EGgKHA00stZeCqSE\nOT6RqLRmzRq+m34H33zzDWeeeSa5ubn87ndqZSPRI9hipQzg99bavWUV0saYJGCR03NaRBzz58/n\niiuuoHTfPtLS0rDW0rhxY7fDEjkkgUZlvc4ZO6mZMaawwup4ICe84YlElxdeeIGbb76Z0tJSkk7p\nybx580hMVB8GiT5+i5WstdOc8ZOWA+0r/GsDqGGziNOH4e677+bGG2+ktLSU8ePH0yLtNiUGiVoB\n6xystSVAmjPn82Zr7UZgH/BHQJ98iXmFhYUMHz6cCRMmkJCQwLRp07j//vuJi1NLb4lewVZIvwSk\nliuG2gecAvw9jLGJeN7u3bvp168f//znP0lKSmLBggVce+21bof1KxqSW2oi2OTQyVp7ubW2kANP\nE3uc3tEdwxueyKGbtPTLkByn/LwIVdm2bRvnnXceS5cupVWrVmRnZ5OWlhZw30jfrDUWkdREsMkh\nzhhzZIVlxx7iwH0iAYXixh6qYTfKz8BW0WeffUZqaiofffQR7du3Jzc3l7POOiuofXWzlmgQ7M19\nAvCxMSYH+BloCXRWJzgJtclZX7l+86xyBjagwbIM1j+cxsqVK+nfvz8///wzqampzJ8/nyOOOKL6\nfddsokG9eNY/nObK+xGpiUOZz6Et0MtpvfQDsNhauzXsEQZB8znUXnXXJ5qHxg6HvV+s4oeFT0JJ\nEY3an8MRF48lPjHwVJyxRkNr/5pX7z81ns/BGHO6tfZDY0xnZ9Gn5Va3Nca0tdaurklQxphJwDnO\nQH63W2vfK7fuQudppcRJQg/V5BxSe6GegS2Q8sNcBzustr9j1HSbijOwdT+mHqcVfc6YxyeCz8dN\nN93ElClTSEhICLhvVUNr1+Y9heL9hZpXb35Sc4HqHP7q/D+jmn/Ta3JSY0w3oL21NhW4FphSYZMp\nwEDgXKCXMwudSMT8anjsjm348IsNjB49Gp/Px2OPPcazzz5bZWKotG81Q2uLeJ3fJwdnPCWstb8N\n8Xl7AG86x/7cGHO4MaaptXa3MeY4YJe1djMHEsliZ/vPQhyDSLXKhsd+bdXXfD3rET6cNYvExERe\nfvllrrrK/zQmGlpb6oJAxUovBzqAtXZEDc7bGvig3M87nWW7nf93llu3A2gX6IDZ2dl+1+fn5wfc\nJpZ56fqUj6OmMQWzX6Bt9uzZw/f2XmZtXkejRo146KGHOOaYYw4pplBe00O9LpH8fXrp8+NF0Xh9\nArVWKpvg51inMnoh8JPTWqkv8K8anrdiBUhc2SRCAdZVK1B5p8pE/QvH9fE3zWe1Mhf9L47yr2t6\njCrs2L0fMrP4/Znn0KpJ1ZXJmzZtom/fvhRs/pTf/OY3PPDAA1x33XUhjaPGxwrmuKE8dxD0/fLP\nq9cnKyur2nWBipUe4cATxHLgLGvtwVlKjDFHAHNqGNNW5wmhzG+A76pZdzSwvYbnERd5oVlqVcr3\nQaiqovijjz6ib9++bNu2jcQWbcjNXck333zjQqQi7gm2n0OK88RQ3i6gbQ3PuwR4AHjRGHMGsM3p\ndY219ltjTFNjTAqwBegHDK3heUQOCqYPQlZWFgMGDGDPnj1069aNDaffSJs2bZQcJOYE1c/BGDML\naOUUI+UBzYD+wG5r7cCanNgY8xhwHlAK3AycAeRZa+caY84DJjqbpltr/+rvWOrncOjUf6Gy/E+X\n8+PiyVBazGEdunLERWOIq1f3xpYMRx8Efb/88+r1qXE/h3KuBkY4U4M2d54iFjoD8tWItXZchUUf\nlVv3jjPQn4RJxf4L4fjw1qStfbj7OVTVB+GhS09m4sSJ/HnhkwCMGTOGJ554gvj4+IPHqsn1CWVf\nA6/3c5C6J6jkYK3dD0w1xswHWlpr/xP+0ERCr6wPwvR3NzK0U1t27N7HLbfcwtSpU4mLi+Opp55i\n1KhRbocp4rqgBt4zxvzWGPMe8IkzNSjGmH8aY/qFPUKpc0I1ampNvDjsrIN9D+7u3Y6dcycwdepU\nGjRowKxZs2qUGNx8PyLhEuyorDOAv1prD3fqHADGAxrWQg6ZF+o6Sn7Jo0ePHrz55pskJyezdOlS\nBg0aVKNjeeH9iIRasMmhpbV2lvPax4Gipm+A+uELTWJZoLkUauObb77huxl3kpubS5s2bcjJyaFr\n164hP08oacIeibRgk8NPxpgLyi8wxnQE8sMTlkSCl4tD/M2HUBsffPABqampFO/aymmnnUZubi6/\n/733h+7yYn8RqduCba00GphvjNkMtDHGrAWOcuaVlijl1U5qKeMWHXwdyvkQMjIyGDRoEHv37qVh\n29N5550VNG3aNAQRi9Q9wbZWynHmc+gKJAPbgDVOKyYJk0j0RSh/IyZzkb9Na3/8IJZXp6C49JD2\nqbjtno+WsOutZ8FXStLJF9Ciz62cOmHloR3Lz/UJ1fsso/kQxHU+ny/gv0GDBi0PZju3/i1btswX\nyPLlywNuE2va3rXw4OtwXJ/yxw9medm6v/zrY1/KuIW+tnct9KWMW+i7+18f1/i8paWlvvvvv9/n\n1JX5/vKXv/hKS0v9xlDVsfxdn5q8z9p4asn6gNuE69zV0ffLP69eH+feWeV9Ndg6h/8YY64yxjQO\nc64SCdl8CEVFRVx//fU88MADxMfH8/zzz/PII48QF1dlh9CooScKiYRg6xwGO0NcvGqMKXGWxQE+\na61aLElIhWI+hPz8fIwxZGRk0KhRI2bOnEn//v1DHKlI3RVscugcxDYinlCy9ye6d+/OBx98wBFH\nHMGCBQs455xz3A5LJKoETA7GmBbAKUABkGOt/SUyoYkcui+//JLvXhvLlrzvOe6448jMzKR9e/UR\nEDlUfuscnL4NXwL3OqOkfmWMOTVy4YkELzc3l86dO1Oc9z1nnXUWq1evVmIQqaFATw6PAhdba1dz\nIFmkAY8DfSITnkhw5s2bxxVXXMH+/ftpdNxZZGdnk5SU5HZYIlErUGul5LLEwIH+DhnOxD8invH8\n889z2WWXsX//fq6//npaDrxXiUGklgIlh5IqlpVWsUwk4kpLS/nzn//MTTfdRGlpKQ8++CAPPTGZ\nuPiEsIzJJBJLAhUr1TPGHOU0W61ymbV2W3hDlFhRfrC9Vk0a+t22sLCQESNGMGPGDBISEnjppZe4\n5ppruGfuJ+BnfmgRCU6g5HC8M49zxV5DW53/fUBCmGKTGFN+sD1/N/a8vDwGDhxIVlYWSUlJpKen\nc9vKUh4I05hMIrEoqDmkvU5zSFdWV+eILt7zAztmj6do57fEJyXT6vLxNGh9vNtheUbZmEyTln4Z\n0Z7Usfb9OlRevT6hmENaIqiu3thrq3DnRnbMHk/Jnp3Ua34MrQaNJzG5tdthhUwoB9vTEBtSW0oO\nHjS65+8i8uUuPwl9OP6yqW6S+6qW3z33E15fuwmfD+LiYGjHNkxfs+ngditWrODSS++mZM/PdO7c\nmfnz59OiRYtfHWPka+/TsklDpr+7kavOacvOPfsPDsURbGzVbefv+lR3rEj/9S4SSkoO4gllg+1N\nf3fjgcH2yrU2stYybNgwCgsLGTBgADNmzKBRo0aVjhGKMZlCSYlBolmwo7KKhNWLw846eEN/+NKT\nD97oJ02axODBgyksLOSWW25h9uzZVSYGEQktV54cjDGJwCtAW6cvxTXOnNTltykCcsot6mGtrarf\nhXjQoTRLrUppaSm7sl5izPvzAJg4cSJ33HFH1A+3LRIt3CpWuhL42Vo71BjTyxmmY3CFbfKstd6r\n3pegBNsstSr79+/nj3/8I3ven0diYiKvvPIKV155ZZgiFZGquJUcegD/dF4vA152KQ4JsRPuyaCg\n+H+d6A+1v0HJvj306tWLlStXElf/MN7KXMj5558f5qhFpCJX+jkYY5YAd1hrP3J+3gy0s9YWltsm\nH5jnjOWUbq19qrrjZWVl+RIS/PfFy8/Pp3HjyE9kN/erQuZtKIr4eaNRcd4Odsy+n6IfN5PQuAWt\nzAPUbxmdQ3ld0i6RAe1jZx4st75f0cKr16ekpMS9fg7GmOuA6yos7lTh5zint3V5Y4HpzvJ3jDHv\nWGvfr+48gZphutUJpXt3mBzxswYnXE1Zq2qWWr5oqaqmnx9++CF9+15P0Y/bOemkk8jIyKDrcx8H\n1dy0omCaqUaiKWss8WonL6/w6vXJysqqdl3Yk4O1dhowrfwyY8wrQGvgI6dyOs5aW1RhvxfKbZ/l\nTDhUbXIQ7/DXLLWqiuqlS5cycOBA9uzZQ4M2p7Bq1TskJycDH7v2HoJV24p3Ea9yq85hCTAIeAu4\nGFhefqUx5gTgfmCoM3ZTF2COS7HKIfLX36BiRfVrr73GiBEjKC4u5oorrmD10YOdxBAdalPxLuJl\nbiWHWUBPY8wqZ/rR4RxICuOAFdbaXGPMJmCtM0T4fGvtWpdilRCorqK6tLgxxcXFjB07lokTJ3Lc\nXzIiEs/tPWo3Q1xtK95FvE4D77kk1sdP8pUUsfeLVfy0/GWanTOIpmf1dzskqYGy8aC89v3yGq9e\nHw2850GRGj+pOjt276fjhCz4XArJAAAOPklEQVTW3t2DVk0aRmRspbKK6tLiIohLIK64APvqSwwc\nOLDKfWpa0RvKCmJ/FdKBKt5FopmGz4hR5cvKI2Xbj3totOV9tr86hsLP36Zb736/SgzRpqziHThQ\n8Z5f4HZIIiGjJ4cYU11ZeWI8fBXGp94NGzaQ8/hwvvrqKxKatmL5EyPp0KFD+E4YAV4b6E8klGI+\nOcR62X+ZotIDRSihljJuEQXbv2THnAcp/eVn6h/ZjpaX30+fVzYAG6rdp6rXh3reQIKZP6G2Fdci\n0Srmk4PbZf9uqKqs/MLDfwxLncNzXcGYeyj95Rd69erFnDlzOOWRd6qtEyhfX1DT+RBCWecQa58N\nkTKqc4hBkSor3/PRW1xyySX88ssvXH311SxcuJAmTZoEvb9uzCLuifknh1hUVVl5dnZ2yI7v8/kY\nP348uzKfAeCee+7hwQcf1HDbIlFEyUFCqqioiJEjR/KPf/wD4uJ54fmpjBw50u2wROQQKTlIyOTn\n5zNo0CAyMzNp1KgRjfuOVWIQiVKqc5CQ+O677+jWrRuZmZkcccQRZGdnc9jxFQffFZFooeQgtbZ+\n/XpSU1P597//Tbt27cjNzaVjx45uhyUitaDkILWyevVqOnfuzLfffkvHjh3Jzc3l+OOPdzssEakl\nJQepsblz59KjRw927dpFv379ePvtt2nZsqXbYYlICCg5SI0899xzDBw4kP379zNy5Ejmzp1LUlKS\n22GJSIgoOcghKS0t5a677uKWW27B5/Px8MMP8/zzz1Ovnhq+idQl+kZL0AoKChgxYgSvv/469erV\nY9q0aVx99dVuhyUiYaDkIEHJy8tjwIABLF++nMaNG5Oenk6vXr3cDqtKGixPpPaUHCSgLVu20Ldv\nXz755BNat27N4sWLOeOMM8JyrlDc2DUmk0jtKTmIX+vWrSMtLY0tW7bQoUMHMjIySElJCdv5dGMX\n8QZVSEu1srOz6dKlC1u2bOHcc88lJycnrIlBRLxDyUGqNHPmTHr37k1eXh4DBw5k6dKlNG/e3O2w\nRCRClBzkV3w+H08++SRDhgyhsLCQ2267jVmzZtGoUSO3QxORCFKdgxxUUlLCn/70JyZPngzAX//6\nV8aMGaN5GERikGvJwRjTDZgNjLDWLqxi/VBgFFAKvGitfdmdSGNDQUEBgwcPJj09nfr16/Pqq69y\nxRVXuB2WiLjElWIlY0w7YAywqpr1ScB9wIVAd2CMMUYF3mGya9cuxo4dS3p6Os2aNeOtt94KSWJQ\nfwOR6OVWncN24DJgdzXrOwHvWWvzrLX7gBzg3AjHGBO+/fZbzj33XNatW8cxxxzDqlWr6N69e0iO\nrWapItHLlWIla+0vHHhCqG6T1sDOcj/vAI7yd8xAcyDn5+eHdJ7kuqDw+w2ceeYf2bVrFykpKTz+\n+OP88MMPEblO0fa7CPT5ibb3E2r6fvkXjdcn7MnBGHMdcF2Fxfdba9/ys1vFGtA4wOfvPIH+2s3O\nzg7ZX8R1wZIlS/ju9XH4Cvdx/vnnM2bMGPr16xeZk2cuirrfhd/PTxS+n1DT98s/r16frKysateF\nPTlYa6cB0w5xt61A+TvV0cC7IQ4tZr366qtcd911+IqLGTJkCP/4xz/Izc11OywR8RCvNmVdA0wz\nxiQDxU59wyi3g4p2Pp+PCRMmcM899wDQtNPlTJ8+nfh4dXcRkV9zJTkYYy4C7gA6AGcaY26z1vYy\nxowDVlhrc53XbznFSQ9Ya/PciLWuKC4u5pZbbuHFF18kLi6OZ555hic2p7iSGOpaK6a69n5EcLFC\nehGwqIrlj5V7PQeYE/Hg6qC9e/cyZMgQFixYQMOGDXn99dcZMGAAT4yr9CuIiLrWiqmuvR8RPFys\nJCGyY8cOLr74YtauXUvz5s1ZsGABnTt3djssEfE4JYc67Ouvv6ZPnz5s2LCBlJQUMjMzOeGEEw6u\nV3GIiFRHNZF11Nq1a+ncuTMbNmzgD3/4A7m5ub9KDKg4RET8UHKogxYuXEj37t3ZuXMnvXv3Jjs7\nm9atW7sdlohEESWHOuZvf/sbl1xyCfv27eOaa65hwYIFNGnSxO2wRCTKKDnUET6fj3vvvZeRI0dS\nWlrKfffdx9///ncSExPdDk1EopAqpOuAoqIirr/+el599VUSEhJ44YUXuO66iiOWiIgET8khyu3Z\ns4fLL7+cJUuWcNhhhzF79mz69u3rdlgiEuWUHKLY9u3bueiii/jPf/5Dy5YtWbRoEWeffbbbYYlI\nHaDkEKW++OIL+vTpw8aNG2nfvj0ZGRm0a9fO7bBEpI5QhXQUWrVqFZ07d2bjxo106tSJnJwcJQYR\nCSklhyiTnp7OhRdeyE8//UT//v15++23admypdthiUgdo+QQRaZMmcKgQYMoKCjghhtuID09ncMO\nO8ztsESkDlJyiAKlpaXccccd3H777QfnZJg6dSr16qnKSETCQ3cXjysoKGD48OHMnDmTevXq8fLL\nLzNs2DC3wxKROk7JwcN+/vlnBgwYQHZ2Nk2aNCE9PZ2ePXu6HZaIxAAlB4/avHkzffv2Zd26dRx1\n1FEsXryY008/3e2wRCRGKDl40CeffEJaWhpbt27lxBNPJDMzkzZt2rgdlojEEFVIe8zy5cvp0qUL\nW7dupWvXruTk5CgxiEjEKTl4yBtvvEHv3r3ZvXs3gwYNYsmSJRx++OFuhyUiMUjJwQN8Ph9PPPEE\nV155JUVFRYwaNYqZM2fSsGFDt0MTkRilOgeXlZSUMGrUKJ599lkAnnrqKUaPHu12WCIS45QcXLRv\n3z6GDh3K3LlzqV+/Pq+99hrGGLfDEhFxLzkYY7oBs4ER1tqFVawvAnLKLephrS2JbJTh8+OPP9K/\nf39Wr15NcnIyb775Jt26dXM7LBERcCs5GGPaAWOAVX42y7PWdo9gWBHz3//+l7S0NNavX8+xxx5L\nRkYGJ510ktthiYgc5FaF9HbgMmC3S+d3zaeffkpqairr16/n1FNPJTc3V4lBRDwnzufzuXZyY8wr\nwJxqipXygXlACpBurX2quuNkZWX5EhIS/J4rPz+fxo0bhyjymsvPz+f2228nOTmZBx98kKSkJLdD\nAg9dH6/S9fFP18c/r16fkpISevToEVfVurAXKxljrgMqznZ/v7X2rQC7jgWmAz7gHWPMO9ba96vb\nuHt3/yVQ2dnZAbeJlI4dO5KcnEz9+vXdDuUgL10fL9L18U/Xxz+vXp+srKxq14U9OVhrpwHTarDf\nC2WvjTFZwClAtckhmrRq1crtEERE/PJkU1ZjzAnA/cBQIAHoAsxxOy4RkVjhSoW0MeYiY0w20Ad4\n1BizxFk+zhiTaq1dD2wC1jrNWRdZa9e6EauISCxy5cnBWrsIWFTF8sfKvR4X8cBERAQ0tpKIiFRF\nyUFERCpRchARkUqUHEREpBJXe0iHSlZWVvS/CRERF1TXQ7pOJAcREQktFSuJiEglSg4iIlKJkoOI\niFSi5CAiIpUoOYiISCWeHJU1HIwx9YC/A8cBicBYa62/aUpjTqB5vWOVMWYScI4zt8jt1tr33I7J\nS4wxJzsTc02y1j7rdjxeY4x5HOjq3G8ftdb+y+2YghFLTw7DgL3W2q7AtUC1M8vFoiDn9Y45TsJs\nb61NdT43U9yOyUuMMUnAM0D1s8bEMGPM+cDJzuenD/C02zEFK5aSw3Tn5gewE2jhcjxeE7PzegfQ\nA3iTAyMFfw4cboxp6nZQHlIA9AW2uR2IR70DDHJe/wQkGWP8z2nsETFTrGStLQKKnB9HAa+7HJKn\nWGt/4cBfOm6H4jWtgQ/K/bzTWaYkeuBzUwwU63NTNWttCbDX+fE6YLGzzPPqZHLwN2+1MeZm4A/A\nxS6F57pazOsdiyoOLRDn1D2IBM0Yc4lTLNnL7ViCVSeTQ3XzVhtjrnWSwqXOk0RMqum83jFqq/Ok\nUOY3wHcuxiNRxhjTG7gb6GOtzXM7nmDFTJ2DMeY44AbgMmvtfrfjkaixBLicA5+hM4Bt1to9bgcl\n0cEY0wx4Auhnrd3ldjyHImYG3jPGTACucOamLtPLWlvoYlieYYy5CLgD6OCUq2+31kbNI3A4GWMe\nA84DSoGbrbUfuR2TVxhjzgSeBFKcOr2tzh9gUXUjDBdjzP8B44Evyy3+o7V2k5/dPCFmkoOIiAQv\nZoqVREQkeEoOIiJSiZKDiIhUouQgIiKVKDmIiEglSg4iQTLG5BhjgmrGaoy5vpbnGm+MUUdFcY2S\ng0gQjDEnAXnAJmNMaoBtE5yOTyJRq04OnyESBsOduS72A38EcjmQCK52hkYAWOOMWZUBNDPGfAGk\nAcuBq8rmDzHGfFv2szPO1Z+c7+J2YJi1dqOr71RETw4igTlPApcB6c6kNn2NMQ2MMSnOE0J34AQg\nCbgNGAGUWGs7WGv/6+e4rYBngZ7W2vbA18C9kX13IlVTchAJrDfwnrV2tzO0eTbQzxlhc7W1dpu1\n1gdcCUwK9qDW2h1AU2vtFmfRSmemQhHXqVhJJLDhztPCz87P9YDDgXeBsmWUDegY7NwGzhPJA85w\nzglAkwpj8Ii4Rk8OIn4YY5KdYqPm1tpka20ykAx0BEqAI8pt29QYc2QVhylxbv5lDnf+HwxcApxn\nrT0BuD/870gkOEoOIv4NAd4uP3qvM/vZW0AD4FxjTIoxJg54wZnQpQiIN8Y0cXbZDpzGgQQyGGjo\nLG8FfGut/cEY08JJFo1deZciFSg5iPh3ddkc0hXMBfoD/we87RQH+YCnnGSwymn22hl4CBhjjFkH\nnAh85hzjDaCFMeZr5/XdwLHGmCcj/B5FKtGQ3SIiUomeHEREpBIlBxERqUTJQUREKlFyEBGRSpQc\nRESkEiUHERGpRMlBREQqUXIQEZFK/h+9giAEniipOwAAAABJRU5ErkJggg==\n", - "text/plain": [ - "