From 0c1a7607ce31aae6db8f53a583c1238e56f821e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Wed, 17 Apr 2024 15:14:10 -0600 Subject: [PATCH] reduce default warnings (#974) --- nbs/common.base_model.ipynb | 24 +- nbs/common.base_multivariate.ipynb | 18 +- nbs/common.base_recurrent.ipynb | 18 +- nbs/common.base_windows.ipynb | 24 +- nbs/core.ipynb | 5 + nbs/models.bitcn.ipynb | 668 +------------------- nbs/models.deepar.ipynb | 22 +- nbs/models.ipynb | 147 +---- nbs/models.itransformer.ipynb | 643 +------------------ nbs/tsdataset.ipynb | 17 +- neuralforecast/_modidx.py | 2 + neuralforecast/common/_base_model.py | 22 +- neuralforecast/common/_base_multivariate.py | 18 +- neuralforecast/common/_base_recurrent.py | 12 +- neuralforecast/common/_base_windows.py | 23 +- neuralforecast/core.py | 6 + neuralforecast/models/deepar.py | 21 +- neuralforecast/tsdataset.py | 17 +- 18 files changed, 209 insertions(+), 1498 deletions(-) diff --git a/nbs/common.base_model.ipynb b/nbs/common.base_model.ipynb index fd32e85d1..8ea7143c2 100644 --- a/nbs/common.base_model.ipynb +++ b/nbs/common.base_model.ipynb @@ -127,7 +127,11 @@ " **trainer_kwargs,\n", " ):\n", " super().__init__()\n", - " self.save_hyperparameters() # Allows instantiation from a checkpoint from class\n", + " with warnings.catch_warnings(record=False):\n", + " warnings.filterwarnings('ignore')\n", + " # the following line issues a warning about the loss attribute being saved\n", + " # but we do want to save it\n", + " self.save_hyperparameters() # Allows instantiation from a checkpoint from class\n", " self.random_seed = random_seed\n", " pl.seed_everything(self.random_seed, workers=True)\n", "\n", @@ -240,8 +244,10 @@ " )\n", "\n", " if self.val_check_steps > self.max_steps:\n", - " warnings.warn('val_check_steps is greater than max_steps, \\\n", - " setting val_check_steps to max_steps')\n", + " warnings.warn(\n", + " 'val_check_steps is greater than max_steps, '\n", + " 'setting val_check_steps to max_steps.'\n", + " )\n", " val_check_interval = min(self.val_check_steps, self.max_steps)\n", " self.trainer_kwargs['val_check_interval'] = int(val_check_interval)\n", " self.trainer_kwargs['check_val_every_n_epoch'] = None\n", @@ -355,9 +361,15 @@ " def on_validation_epoch_end(self):\n", " if self.val_size == 0:\n", " return\n", - " avg_loss = torch.stack(self.validation_step_outputs).mean()\n", - " self.log(\"ptl/val_loss\", avg_loss, sync_dist=True)\n", - " self.valid_trajectories.append((self.global_step, float(avg_loss)))\n", + " losses = torch.stack(self.validation_step_outputs)\n", + " avg_loss = losses.mean().item()\n", + " self.log(\n", + " \"ptl/val_loss\",\n", + " avg_loss,\n", + " batch_size=losses.size(0),\n", + " sync_dist=True,\n", + " )\n", + " self.valid_trajectories.append((self.global_step, avg_loss))\n", " self.validation_step_outputs.clear() # free memory (compute `avg_loss` per epoch)\n", "\n", " def save(self, path):\n", diff --git a/nbs/common.base_multivariate.ipynb b/nbs/common.base_multivariate.ipynb index e7cc67e02..959c047b2 100644 --- a/nbs/common.base_multivariate.ipynb +++ b/nbs/common.base_multivariate.ipynb @@ -384,8 +384,14 @@ " print('output', torch.isnan(output).sum())\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('train_loss', loss, prog_bar=True, on_epoch=True)\n", - " self.train_trajectories.append((self.global_step, float(loss)))\n", + " self.log(\n", + " 'train_loss',\n", + " loss.item(),\n", + " batch_size=outsample_y.size(0),\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", + " self.train_trajectories.append((self.global_step, loss.item()))\n", " return loss\n", "\n", " def validation_step(self, batch, batch_idx):\n", @@ -428,7 +434,13 @@ " if torch.isnan(valid_loss):\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('valid_loss', valid_loss, prog_bar=True, on_epoch=True)\n", + " self.log(\n", + " 'valid_loss',\n", + " valid_loss.item(),\n", + " batch_size=outsample_y.size(0),\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", " self.validation_step_outputs.append(valid_loss)\n", " return valid_loss\n", "\n", diff --git a/nbs/common.base_recurrent.ipynb b/nbs/common.base_recurrent.ipynb index 3d78187a2..835242309 100644 --- a/nbs/common.base_recurrent.ipynb +++ b/nbs/common.base_recurrent.ipynb @@ -358,8 +358,14 @@ " print('output', torch.isnan(output).sum())\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('train_loss', loss, batch_size=self.batch_size, prog_bar=True, on_epoch=True)\n", - " self.train_trajectories.append((self.global_step, float(loss)))\n", + " self.log(\n", + " 'train_loss',\n", + " loss.item(),\n", + " batch_size=outsample_y.size(0),\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", + " self.train_trajectories.append((self.global_step, loss.item()))\n", " return loss\n", "\n", " def validation_step(self, batch, batch_idx):\n", @@ -425,7 +431,13 @@ " if torch.isnan(valid_loss):\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('valid_loss', valid_loss, batch_size=self.batch_size, prog_bar=True, on_epoch=True)\n", + " self.log(\n", + " 'valid_loss',\n", + " valid_loss.item(),\n", + " batch_size=outsample_y.size(0),\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", " self.validation_step_outputs.append(valid_loss)\n", " return valid_loss\n", "\n", diff --git a/nbs/common.base_windows.ipynb b/nbs/common.base_windows.ipynb index ba4fcb3ce..f4b1da83b 100644 --- a/nbs/common.base_windows.ipynb +++ b/nbs/common.base_windows.ipynb @@ -441,8 +441,14 @@ " print('output', torch.isnan(output).sum())\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('train_loss', loss, prog_bar=True, on_epoch=True)\n", - " self.train_trajectories.append((self.global_step, float(loss)))\n", + " self.log(\n", + " 'train_loss',\n", + " loss.item(),\n", + " batch_size=outsample_y.size(0),\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", + " self.train_trajectories.append((self.global_step, loss.item()))\n", " return loss\n", "\n", " def _compute_valid_loss(self, outsample_y, output, outsample_mask, temporal_cols, y_idx):\n", @@ -513,14 +519,20 @@ " batch_sizes.append(len(output_batch))\n", " \n", " valid_loss = torch.stack(valid_losses)\n", - " batch_sizes = torch.tensor(batch_sizes).to(valid_loss.device)\n", - " valid_loss = torch.sum(valid_loss * batch_sizes) \\\n", - " / torch.sum(batch_sizes)\n", + " batch_sizes = torch.tensor(batch_sizes, device=valid_loss.device)\n", + " batch_size = torch.sum(batch_sizes)\n", + " valid_loss = torch.sum(valid_loss * batch_sizes) / batch_size\n", "\n", " if torch.isnan(valid_loss):\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('valid_loss', valid_loss, prog_bar=True, on_epoch=True)\n", + " self.log(\n", + " 'valid_loss',\n", + " valid_loss.item(),\n", + " batch_size=batch_size,\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", " self.validation_step_outputs.append(valid_loss)\n", " return valid_loss\n", "\n", diff --git a/nbs/core.ipynb b/nbs/core.ipynb index 2c2b15c50..14165c3a9 100644 --- a/nbs/core.ipynb +++ b/nbs/core.ipynb @@ -68,6 +68,7 @@ "import fsspec\n", "import numpy as np\n", "import pandas as pd\n", + "import pytorch_lightning as pl\n", "import torch\n", "import utilsforecast.processing as ufp\n", "from coreforecast.grouped_array import GroupedArray\n", @@ -102,6 +103,10 @@ "outputs": [], "source": [ "#| exporti\n", + "# this disables warnings about the number of workers in the dataloaders\n", + "# which the user can't control\n", + "pl.disable_possible_user_warnings()\n", + "\n", "def _insample_times(\n", " times: np.ndarray,\n", " uids: Series,\n", diff --git a/nbs/models.bitcn.ipynb b/nbs/models.bitcn.ipynb index 539f6c80d..d08bec764 100644 --- a/nbs/models.bitcn.ipynb +++ b/nbs/models.bitcn.ipynb @@ -13,16 +13,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The autoreload extension is already loaded. To reload it, use:\n", - " %reload_ext autoreload\n" - ] - } - ], + "outputs": [], "source": [ "#| hide\n", "%load_ext autoreload\n", @@ -362,131 +353,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\statsforecast\\utils.py:237: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead.\n", - " \"ds\": pd.date_range(start=\"1949-01-01\", periods=len(AirPassengers), freq=\"M\"),\n" - ] - }, - { - "data": { - "text/markdown": [ - "---\n", - "\n", - "[source](https://github.com/Nixtla/neuralforecast/blob/main/neuralforecast/models/bitcn.py#L79){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", - "\n", - "### BiTCN\n", - "\n", - "> BiTCN (h:int, input_size:int, hidden_size:int=16, dropout:float=0.1,\n", - "> futr_exog_list=None, hist_exog_list=None, stat_exog_list=None,\n", - "> exclude_insample_y=False, loss=MAE(), valid_loss=None,\n", - "> max_steps:int=1000, learning_rate:float=0.001,\n", - "> num_lr_decays:int=-1, early_stop_patience_steps:int=-1,\n", - "> val_check_steps:int=100, batch_size:int=32,\n", - "> valid_batch_size:Optional[int]=None, windows_batch_size=1024,\n", - "> inference_windows_batch_size=-1, start_padding_enabled=False,\n", - "> step_size:int=1, scaler_type:str='identity', random_seed:int=1,\n", - "> num_workers_loader:int=0, drop_last_loader:bool=False,\n", - "> optimizer=None, optimizer_kwargs=None, **trainer_kwargs)\n", - "\n", - "BiTCN\n", - "\n", - "Bidirectional Temporal Convolutional Network (BiTCN) is a forecasting architecture based on two temporal convolutional networks (TCNs). The first network ('forward') encodes future covariates of the time series, whereas the second network ('backward') encodes past observations and covariates. This is a univariate model.\n", - "\n", - "**Parameters:**
\n", - "`h`: int, forecast horizon.
\n", - "`input_size`: int, considered autorregresive inputs (lags), y=[1,2,3,4] input_size=2 -> lags=[1,2].
\n", - "`hidden_size`: int=16, units for the TCN's hidden state size.
\n", - "`dropout`: float=0.1, dropout rate used for the dropout layers throughout the architecture.
\n", - "`futr_exog_list`: str list, future exogenous columns.
\n", - "`hist_exog_list`: str list, historic exogenous columns.
\n", - "`stat_exog_list`: str list, static exogenous columns.
\n", - "`exclude_insample_y`: bool=False, the model skips the autoregressive features y[t-input_size:t] if True.
\n", - "`loss`: PyTorch module, instantiated train loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`valid_loss`: PyTorch module=`loss`, instantiated valid loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`max_steps`: int=1000, maximum number of training steps.
\n", - "`learning_rate`: float=1e-3, Learning rate between (0, 1).
\n", - "`num_lr_decays`: int=-1, Number of learning rate decays, evenly distributed across max_steps.
\n", - "`early_stop_patience_steps`: int=-1, Number of validation iterations before early stopping.
\n", - "`val_check_steps`: int=100, Number of training steps between every validation loss check.
\n", - "`batch_size`: int=32, number of different series in each batch.
\n", - "`valid_batch_size`: int=None, number of different series in each validation and test batch, if None uses batch_size.
\n", - "`windows_batch_size`: int=1024, number of windows to sample in each training batch, default uses all.
\n", - "`inference_windows_batch_size`: int=-1, number of windows to sample in each inference batch, -1 uses all.
\n", - "`start_padding_enabled`: bool=False, if True, the model will pad the time series with zeros at the beginning, by input size.
\n", - "`step_size`: int=1, step size between each window of temporal data.
\n", - "`scaler_type`: str='identity', type of scaler for temporal inputs normalization see [temporal scalers](https://nixtla.github.io/neuralforecast/common.scalers.html).
\n", - "`random_seed`: int=1, random_seed for pytorch initializer and numpy generators.
\n", - "`num_workers_loader`: int=os.cpu_count(), workers to be used by `TimeSeriesDataLoader`.
\n", - "`drop_last_loader`: bool=False, if True `TimeSeriesDataLoader` drops last non-full batch.
\n", - "`alias`: str, optional, Custom name of the model.
\n", - "`optimizer`: Subclass of 'torch.optim.Optimizer', optional, user specified optimizer instead of the default choice (Adam).
\n", - "`optimizer_kwargs`: dict, optional, list of parameters used by the user specified `optimizer`.
\n", - "`**trainer_kwargs`: int, keyword trainer arguments inherited from [PyTorch Lighning's trainer](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).
" - ], - "text/plain": [ - "---\n", - "\n", - "[source](https://github.com/Nixtla/neuralforecast/blob/main/neuralforecast/models/bitcn.py#L79){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", - "\n", - "### BiTCN\n", - "\n", - "> BiTCN (h:int, input_size:int, hidden_size:int=16, dropout:float=0.1,\n", - "> futr_exog_list=None, hist_exog_list=None, stat_exog_list=None,\n", - "> exclude_insample_y=False, loss=MAE(), valid_loss=None,\n", - "> max_steps:int=1000, learning_rate:float=0.001,\n", - "> num_lr_decays:int=-1, early_stop_patience_steps:int=-1,\n", - "> val_check_steps:int=100, batch_size:int=32,\n", - "> valid_batch_size:Optional[int]=None, windows_batch_size=1024,\n", - "> inference_windows_batch_size=-1, start_padding_enabled=False,\n", - "> step_size:int=1, scaler_type:str='identity', random_seed:int=1,\n", - "> num_workers_loader:int=0, drop_last_loader:bool=False,\n", - "> optimizer=None, optimizer_kwargs=None, **trainer_kwargs)\n", - "\n", - "BiTCN\n", - "\n", - "Bidirectional Temporal Convolutional Network (BiTCN) is a forecasting architecture based on two temporal convolutional networks (TCNs). The first network ('forward') encodes future covariates of the time series, whereas the second network ('backward') encodes past observations and covariates. This is a univariate model.\n", - "\n", - "**Parameters:**
\n", - "`h`: int, forecast horizon.
\n", - "`input_size`: int, considered autorregresive inputs (lags), y=[1,2,3,4] input_size=2 -> lags=[1,2].
\n", - "`hidden_size`: int=16, units for the TCN's hidden state size.
\n", - "`dropout`: float=0.1, dropout rate used for the dropout layers throughout the architecture.
\n", - "`futr_exog_list`: str list, future exogenous columns.
\n", - "`hist_exog_list`: str list, historic exogenous columns.
\n", - "`stat_exog_list`: str list, static exogenous columns.
\n", - "`exclude_insample_y`: bool=False, the model skips the autoregressive features y[t-input_size:t] if True.
\n", - "`loss`: PyTorch module, instantiated train loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`valid_loss`: PyTorch module=`loss`, instantiated valid loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`max_steps`: int=1000, maximum number of training steps.
\n", - "`learning_rate`: float=1e-3, Learning rate between (0, 1).
\n", - "`num_lr_decays`: int=-1, Number of learning rate decays, evenly distributed across max_steps.
\n", - "`early_stop_patience_steps`: int=-1, Number of validation iterations before early stopping.
\n", - "`val_check_steps`: int=100, Number of training steps between every validation loss check.
\n", - "`batch_size`: int=32, number of different series in each batch.
\n", - "`valid_batch_size`: int=None, number of different series in each validation and test batch, if None uses batch_size.
\n", - "`windows_batch_size`: int=1024, number of windows to sample in each training batch, default uses all.
\n", - "`inference_windows_batch_size`: int=-1, number of windows to sample in each inference batch, -1 uses all.
\n", - "`start_padding_enabled`: bool=False, if True, the model will pad the time series with zeros at the beginning, by input size.
\n", - "`step_size`: int=1, step size between each window of temporal data.
\n", - "`scaler_type`: str='identity', type of scaler for temporal inputs normalization see [temporal scalers](https://nixtla.github.io/neuralforecast/common.scalers.html).
\n", - "`random_seed`: int=1, random_seed for pytorch initializer and numpy generators.
\n", - "`num_workers_loader`: int=os.cpu_count(), workers to be used by `TimeSeriesDataLoader`.
\n", - "`drop_last_loader`: bool=False, if True `TimeSeriesDataLoader` drops last non-full batch.
\n", - "`alias`: str, optional, Custom name of the model.
\n", - "`optimizer`: Subclass of 'torch.optim.Optimizer', optional, user specified optimizer instead of the default choice (Adam).
\n", - "`optimizer_kwargs`: dict, optional, list of parameters used by the user specified `optimizer`.
\n", - "`**trainer_kwargs`: int, keyword trainer arguments inherited from [PyTorch Lighning's trainer](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).
" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "show_doc(BiTCN)" ] @@ -495,71 +362,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "---\n", - "\n", - "### BiTCN.fit\n", - "\n", - "> BiTCN.fit (dataset, val_size=0, test_size=0, random_seed=None)\n", - "\n", - "Fit.\n", - "\n", - "The `fit` method, optimizes the neural network's weights using the\n", - "initialization parameters (`learning_rate`, `windows_batch_size`, ...)\n", - "and the `loss` function as defined during the initialization.\n", - "Within `fit` we use a PyTorch Lightning `Trainer` that\n", - "inherits the initialization's `self.trainer_kwargs`, to customize\n", - "its inputs, see [PL's trainer arguments](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).\n", - "\n", - "The method is designed to be compatible with SKLearn-like classes\n", - "and in particular to be compatible with the StatsForecast library.\n", - "\n", - "By default the `model` is not saving training checkpoints to protect\n", - "disk memory, to get them change `enable_checkpointing=True` in `__init__`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`val_size`: int, validation size for temporal cross-validation.
\n", - "`random_seed`: int=None, random_seed for pytorch initializer and numpy generators, overwrites model.__init__'s.
\n", - "`test_size`: int, test size for temporal cross-validation.
" - ], - "text/plain": [ - "---\n", - "\n", - "### BiTCN.fit\n", - "\n", - "> BiTCN.fit (dataset, val_size=0, test_size=0, random_seed=None)\n", - "\n", - "Fit.\n", - "\n", - "The `fit` method, optimizes the neural network's weights using the\n", - "initialization parameters (`learning_rate`, `windows_batch_size`, ...)\n", - "and the `loss` function as defined during the initialization.\n", - "Within `fit` we use a PyTorch Lightning `Trainer` that\n", - "inherits the initialization's `self.trainer_kwargs`, to customize\n", - "its inputs, see [PL's trainer arguments](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).\n", - "\n", - "The method is designed to be compatible with SKLearn-like classes\n", - "and in particular to be compatible with the StatsForecast library.\n", - "\n", - "By default the `model` is not saving training checkpoints to protect\n", - "disk memory, to get them change `enable_checkpointing=True` in `__init__`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`val_size`: int, validation size for temporal cross-validation.
\n", - "`random_seed`: int=None, random_seed for pytorch initializer and numpy generators, overwrites model.__init__'s.
\n", - "`test_size`: int, test size for temporal cross-validation.
" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "show_doc(BiTCN.fit, name='BiTCN.fit')" ] @@ -568,53 +371,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "---\n", - "\n", - "### BiTCN.predict\n", - "\n", - "> BiTCN.predict (dataset, test_size=None, step_size=1, random_seed=None,\n", - "> **data_module_kwargs)\n", - "\n", - "Predict.\n", - "\n", - "Neural network prediction with PL's `Trainer` execution of `predict_step`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`test_size`: int=None, test size for temporal cross-validation.
\n", - "`step_size`: int=1, Step size between each window.
\n", - "`random_seed`: int=None, random_seed for pytorch initializer and numpy generators, overwrites model.__init__'s.
\n", - "`**data_module_kwargs`: PL's TimeSeriesDataModule args, see [documentation](https://pytorch-lightning.readthedocs.io/en/1.6.1/extensions/datamodules.html#using-a-datamodule)." - ], - "text/plain": [ - "---\n", - "\n", - "### BiTCN.predict\n", - "\n", - "> BiTCN.predict (dataset, test_size=None, step_size=1, random_seed=None,\n", - "> **data_module_kwargs)\n", - "\n", - "Predict.\n", - "\n", - "Neural network prediction with PL's `Trainer` execution of `predict_step`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`test_size`: int=None, test size for temporal cross-validation.
\n", - "`step_size`: int=1, Step size between each window.
\n", - "`random_seed`: int=None, random_seed for pytorch initializer and numpy generators, overwrites model.__init__'s.
\n", - "`**data_module_kwargs`: PL's TimeSeriesDataModule args, see [documentation](https://pytorch-lightning.readthedocs.io/en/1.6.1/extensions/datamodules.html#using-a-datamodule)." - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "show_doc(BiTCN.predict, name='BiTCN.predict')" ] @@ -630,225 +387,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\pytorch_lightning\\utilities\\parsing.py:199: Attribute 'loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['loss'])`.\n", - "Seed set to 1\n", - "GPU available: True (cuda), used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\n", - " | Name | Type | Params\n", - "------------------------------------------------\n", - "0 | padder_train | ConstantPad1d | 0 \n", - "1 | loss | MAE | 0 \n", - "2 | scaler | TemporalNorm | 0 \n", - "3 | lin_hist | Linear | 32 \n", - "4 | drop_hist | Dropout | 0 \n", - "5 | net_bwd | Sequential | 5.4 K \n", - "6 | drop_temporal | Dropout | 0 \n", - "7 | temporal_lin1 | Linear | 400 \n", - "8 | temporal_lin2 | Linear | 204 \n", - "9 | output_lin | Linear | 17 \n", - "------------------------------------------------\n", - "6.0 K Trainable params\n", - "0 Non-trainable params\n", - "6.0 K Total params\n", - "0.024 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ba6bbbee08ea4f9d8b59147465dac139", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Sanity Checking: | | 0/? [00:00" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -884,202 +423,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\pytorch_lightning\\utilities\\parsing.py:199: Attribute 'loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['loss'])`.\n", - "Seed set to 1\n", - "GPU available: True (cuda), used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\n", - " | Name | Type | Params\n", - "-------------------------------------------------\n", - "0 | padder_train | ConstantPad1d | 0 \n", - "1 | loss | GMM | 5 \n", - "2 | scaler | TemporalNorm | 0 \n", - "3 | lin_hist | Linear | 64 \n", - "4 | drop_hist | Dropout | 0 \n", - "5 | net_bwd | Sequential | 5.4 K \n", - "6 | lin_futr | Linear | 32 \n", - "7 | drop_futr | Dropout | 0 \n", - "8 | net_fwd | Sequential | 6.4 K \n", - "9 | drop_temporal | Dropout | 0 \n", - "10 | temporal_lin1 | Linear | 400 \n", - "11 | temporal_lin2 | Linear | 204 \n", - "12 | output_lin | Linear | 686 \n", - "-------------------------------------------------\n", - "13.2 K Trainable params\n", - "5 Non-trainable params\n", - "13.2 K Total params\n", - "0.053 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "3d1c9e6b4cb142a8826bccc0439e552a", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Sanity Checking: | | 0/? [00:00" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", diff --git a/nbs/models.deepar.ipynb b/nbs/models.deepar.ipynb index 7a6499781..8b7c8c902 100644 --- a/nbs/models.deepar.ipynb +++ b/nbs/models.deepar.ipynb @@ -345,8 +345,14 @@ " print('output', torch.isnan(output).sum())\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('train_loss', loss, prog_bar=True, on_epoch=True)\n", - " self.train_trajectories.append((self.global_step, float(loss)))\n", + " self.log(\n", + " 'train_loss',\n", + " loss.item(),\n", + " batch_size=outsample_y.size(0),\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", + " self.train_trajectories.append((self.global_step, loss.item()))\n", "\n", " self.h = self.horizon_backup # Restore horizon\n", " return loss\n", @@ -400,13 +406,19 @@ "\n", " valid_loss = torch.stack(valid_losses)\n", " batch_sizes = torch.tensor(batch_sizes, device=valid_loss.device)\n", - " valid_loss = torch.sum(valid_loss * batch_sizes) \\\n", - " / torch.sum(batch_sizes)\n", + " batch_size = torch.sum(batch_sizes)\n", + " valid_loss = torch.sum(valid_loss * batch_sizes) / batch_size\n", "\n", " if torch.isnan(valid_loss):\n", " raise Exception('Loss is NaN, training stopped.')\n", "\n", - " self.log('valid_loss', valid_loss, prog_bar=True, on_epoch=True)\n", + " self.log(\n", + " 'valid_loss',\n", + " valid_loss.item(),\n", + " batch_size=batch_size,\n", + " prog_bar=True,\n", + " on_epoch=True,\n", + " )\n", " self.validation_step_outputs.append(valid_loss)\n", " return valid_loss\n", "\n", diff --git a/nbs/models.ipynb b/nbs/models.ipynb index d48214601..9e437cea8 100644 --- a/nbs/models.ipynb +++ b/nbs/models.ipynb @@ -1133,18 +1133,7 @@ "execution_count": null, "id": "95850f3c", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-04-06 10:40:24,017\tINFO worker.py:1724 -- Started a local Ray instance.\n", - "2024-04-06 10:40:25,556\tINFO tune.py:220 -- Initializing Ray automatically. For cluster usage or custom Ray initialization, call `ray.init(...)` before `Tuner(...)`.\n", - "2024-04-06 10:40:25,559\tINFO tune.py:583 -- [output] This uses the legacy output and progress reporter, as Jupyter notebooks are not supported by the new engine, yet. For more information, please see https://github.com/ray-project/ray/issues/36949\n", - "Seed set to 1\n" - ] - } - ], + "outputs": [], "source": [ "%%capture\n", "# Use your own config or AutoNHITS.default_config\n", @@ -1164,139 +1153,7 @@ "execution_count": null, "id": "7c905530", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[36m(_train_tune pid=27632)\u001b[0m c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\ray\\tune\\integration\\pytorch_lightning.py:194: `ray.tune.integration.pytorch_lightning.TuneReportCallback` is deprecated. Use `ray.tune.integration.pytorch_lightning.TuneReportCheckpointCallback` instead.\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\pytorch_lightning\\utilities\\parsing.py:199: Attribute 'loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['loss'])`.\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\pytorch_lightning\\utilities\\parsing.py:199: Attribute 'valid_loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['valid_loss'])`.\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m Seed set to 11\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m GPU available: True (cuda), used: True\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m TPU available: False, using: 0 TPU cores\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m IPU available: False, using: 0 IPUs\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m HPU available: False, using: 0 HPUs\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m `Trainer(val_check_interval=1)` was configured so validation will run after every batch.\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m You are using a CUDA device ('NVIDIA GeForce RTX 3090') that has Tensor Cores. To properly utilize them, you should set `torch.set_float32_matmul_precision('medium' | 'high')` which will trade-off precision for performance. For more details, read https://pytorch.org/docs/stable/generated/torch.set_float32_matmul_precision.html#torch.set_float32_matmul_precision\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m Missing logger folder: C:\\Users\\ospra\\ray_results\\_train_tune_2024-04-06_10-40-40\\_train_tune_4d1da_00000\\lightning_logs\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m | Name | Type | Params\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m -----------------------------------------------\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 0 | padder_train | ConstantPad1d | 0 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 1 | loss | MAE | 0 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 2 | scaler | TemporalNorm | 0 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 3 | lin_hist | Linear | 16 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 4 | drop_hist | Dropout | 0 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 5 | net_bwd | Sequential | 944 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 6 | feature_lin | Linear | 9 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 7 | temporal_lin | Linear | 156 \n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m -----------------------------------------------\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 1.1 K Trainable params\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 0 Non-trainable params\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 1.1 K Total params\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m 0.004 Total estimated model params size (MB)\n", - "\u001b[36m(_train_tune pid=27632)\u001b[0m c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\pytorch_lightning\\trainer\\connectors\\data_connector.py:441: The 'val_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=19` in the `DataLoader` to improve performance.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Sanity Checking: | | 0/? [00:00 iTransformer (h, input_size, n_series, futr_exog_list=None,\n", - "> hist_exog_list=None, stat_exog_list=None,\n", - "> hidden_size:int=512, n_heads:int=8, e_layers:int=2,\n", - "> d_layers:int=1, d_ff:int=2048, factor:int=1,\n", - "> dropout:float=0.1, use_norm:bool=True, loss=MAE(),\n", - "> valid_loss=None, max_steps:int=1000,\n", - "> learning_rate:float=0.001, num_lr_decays:int=-1,\n", - "> early_stop_patience_steps:int=-1, val_check_steps:int=100,\n", - "> batch_size:int=32, step_size:int=1,\n", - "> scaler_type:str='identity', random_seed:int=1,\n", - "> num_workers_loader:int=0, drop_last_loader:bool=False,\n", - "> optimizer=None, optimizer_kwargs=None, **trainer_kwargs)\n", - "\n", - "iTransformer\n", - "\n", - "**Parameters:**
\n", - "`h`: int, Forecast horizon.
\n", - "`input_size`: int, autorregresive inputs size, y=[1,2,3,4] input_size=2 -> y_[t-2:t]=[1,2].
\n", - "`n_series`: int, number of time-series.
\n", - "`futr_exog_list`: str list, future exogenous columns.
\n", - "`hist_exog_list`: str list, historic exogenous columns.
\n", - "`stat_exog_list`: str list, static exogenous columns.
\n", - "`hidden_size`: int, dimension of the model.
\n", - "`n_heads`: int, number of heads.
\n", - "`e_layers`: int, number of encoder layers.
\n", - "`d_layers`: int, number of decoder layers.
\n", - "`d_ff`: int, dimension of fully-connected layer.
\n", - "`factor`: int, attention factor.
\n", - "`dropout`: float, dropout rate.
\n", - "`use_norm`: bool, whether to normalize or not.
\n", - "`loss`: PyTorch module, instantiated train loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`valid_loss`: PyTorch module=`loss`, instantiated valid loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`max_steps`: int=1000, maximum number of training steps.
\n", - "`learning_rate`: float=1e-3, Learning rate between (0, 1).
\n", - "`num_lr_decays`: int=-1, Number of learning rate decays, evenly distributed across max_steps.
\n", - "`early_stop_patience_steps`: int=-1, Number of validation iterations before early stopping.
\n", - "`val_check_steps`: int=100, Number of training steps between every validation loss check.
\n", - "`batch_size`: int=32, number of different series in each batch.
\n", - "`step_size`: int=1, step size between each window of temporal data.
\n", - "`scaler_type`: str='identity', type of scaler for temporal inputs normalization see [temporal scalers](https://nixtla.github.io/neuralforecast/common.scalers.html).
\n", - "`random_seed`: int=1, random_seed for pytorch initializer and numpy generators.
\n", - "`num_workers_loader`: int=os.cpu_count(), workers to be used by `TimeSeriesDataLoader`.
\n", - "`drop_last_loader`: bool=False, if True `TimeSeriesDataLoader` drops last non-full batch.
\n", - "`alias`: str, optional, Custom name of the model.
\n", - "`optimizer`: Subclass of 'torch.optim.Optimizer', optional, user specified optimizer instead of the default choice (Adam).
\n", - "`optimizer_kwargs`: dict, optional, list of parameters used by the user specified `optimizer`.
\n", - "`**trainer_kwargs`: int, keyword trainer arguments inherited from [PyTorch Lighning's trainer](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).
\n", - "\n", - "**References**
\n", - "- [Yong Liu, Tengge Hu, Haoran Zhang, Haixu Wu, Shiyu Wang, Lintao Ma, Mingsheng Long. \"iTransformer: Inverted Transformers Are Effective for Time Series Forecasting\"](https://arxiv.org/abs/2310.06625)" - ], - "text/plain": [ - "---\n", - "\n", - "[source](https://github.com/Nixtla/neuralforecast/blob/main/neuralforecast/models/itransformer.py#L94){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", - "\n", - "### iTransformer\n", - "\n", - "> iTransformer (h, input_size, n_series, futr_exog_list=None,\n", - "> hist_exog_list=None, stat_exog_list=None,\n", - "> hidden_size:int=512, n_heads:int=8, e_layers:int=2,\n", - "> d_layers:int=1, d_ff:int=2048, factor:int=1,\n", - "> dropout:float=0.1, use_norm:bool=True, loss=MAE(),\n", - "> valid_loss=None, max_steps:int=1000,\n", - "> learning_rate:float=0.001, num_lr_decays:int=-1,\n", - "> early_stop_patience_steps:int=-1, val_check_steps:int=100,\n", - "> batch_size:int=32, step_size:int=1,\n", - "> scaler_type:str='identity', random_seed:int=1,\n", - "> num_workers_loader:int=0, drop_last_loader:bool=False,\n", - "> optimizer=None, optimizer_kwargs=None, **trainer_kwargs)\n", - "\n", - "iTransformer\n", - "\n", - "**Parameters:**
\n", - "`h`: int, Forecast horizon.
\n", - "`input_size`: int, autorregresive inputs size, y=[1,2,3,4] input_size=2 -> y_[t-2:t]=[1,2].
\n", - "`n_series`: int, number of time-series.
\n", - "`futr_exog_list`: str list, future exogenous columns.
\n", - "`hist_exog_list`: str list, historic exogenous columns.
\n", - "`stat_exog_list`: str list, static exogenous columns.
\n", - "`hidden_size`: int, dimension of the model.
\n", - "`n_heads`: int, number of heads.
\n", - "`e_layers`: int, number of encoder layers.
\n", - "`d_layers`: int, number of decoder layers.
\n", - "`d_ff`: int, dimension of fully-connected layer.
\n", - "`factor`: int, attention factor.
\n", - "`dropout`: float, dropout rate.
\n", - "`use_norm`: bool, whether to normalize or not.
\n", - "`loss`: PyTorch module, instantiated train loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`valid_loss`: PyTorch module=`loss`, instantiated valid loss class from [losses collection](https://nixtla.github.io/neuralforecast/losses.pytorch.html).
\n", - "`max_steps`: int=1000, maximum number of training steps.
\n", - "`learning_rate`: float=1e-3, Learning rate between (0, 1).
\n", - "`num_lr_decays`: int=-1, Number of learning rate decays, evenly distributed across max_steps.
\n", - "`early_stop_patience_steps`: int=-1, Number of validation iterations before early stopping.
\n", - "`val_check_steps`: int=100, Number of training steps between every validation loss check.
\n", - "`batch_size`: int=32, number of different series in each batch.
\n", - "`step_size`: int=1, step size between each window of temporal data.
\n", - "`scaler_type`: str='identity', type of scaler for temporal inputs normalization see [temporal scalers](https://nixtla.github.io/neuralforecast/common.scalers.html).
\n", - "`random_seed`: int=1, random_seed for pytorch initializer and numpy generators.
\n", - "`num_workers_loader`: int=os.cpu_count(), workers to be used by `TimeSeriesDataLoader`.
\n", - "`drop_last_loader`: bool=False, if True `TimeSeriesDataLoader` drops last non-full batch.
\n", - "`alias`: str, optional, Custom name of the model.
\n", - "`optimizer`: Subclass of 'torch.optim.Optimizer', optional, user specified optimizer instead of the default choice (Adam).
\n", - "`optimizer_kwargs`: dict, optional, list of parameters used by the user specified `optimizer`.
\n", - "`**trainer_kwargs`: int, keyword trainer arguments inherited from [PyTorch Lighning's trainer](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).
\n", - "\n", - "**References**
\n", - "- [Yong Liu, Tengge Hu, Haoran Zhang, Haixu Wu, Shiyu Wang, Lintao Ma, Mingsheng Long. \"iTransformer: Inverted Transformers Are Effective for Time Series Forecasting\"](https://arxiv.org/abs/2310.06625)" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "show_doc(iTransformer)" ] @@ -507,69 +383,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "---\n", - "\n", - "### iTransformer.fit\n", - "\n", - "> iTransformer.fit (dataset, val_size=0, test_size=0, random_seed=None)\n", - "\n", - "Fit.\n", - "\n", - "The `fit` method, optimizes the neural network's weights using the\n", - "initialization parameters (`learning_rate`, `windows_batch_size`, ...)\n", - "and the `loss` function as defined during the initialization.\n", - "Within `fit` we use a PyTorch Lightning `Trainer` that\n", - "inherits the initialization's `self.trainer_kwargs`, to customize\n", - "its inputs, see [PL's trainer arguments](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).\n", - "\n", - "The method is designed to be compatible with SKLearn-like classes\n", - "and in particular to be compatible with the StatsForecast library.\n", - "\n", - "By default the `model` is not saving training checkpoints to protect\n", - "disk memory, to get them change `enable_checkpointing=True` in `__init__`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`val_size`: int, validation size for temporal cross-validation.
\n", - "`test_size`: int, test size for temporal cross-validation.
" - ], - "text/plain": [ - "---\n", - "\n", - "### iTransformer.fit\n", - "\n", - "> iTransformer.fit (dataset, val_size=0, test_size=0, random_seed=None)\n", - "\n", - "Fit.\n", - "\n", - "The `fit` method, optimizes the neural network's weights using the\n", - "initialization parameters (`learning_rate`, `windows_batch_size`, ...)\n", - "and the `loss` function as defined during the initialization.\n", - "Within `fit` we use a PyTorch Lightning `Trainer` that\n", - "inherits the initialization's `self.trainer_kwargs`, to customize\n", - "its inputs, see [PL's trainer arguments](https://pytorch-lightning.readthedocs.io/en/stable/api/pytorch_lightning.trainer.trainer.Trainer.html?highlight=trainer).\n", - "\n", - "The method is designed to be compatible with SKLearn-like classes\n", - "and in particular to be compatible with the StatsForecast library.\n", - "\n", - "By default the `model` is not saving training checkpoints to protect\n", - "disk memory, to get them change `enable_checkpointing=True` in `__init__`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`val_size`: int, validation size for temporal cross-validation.
\n", - "`test_size`: int, test size for temporal cross-validation.
" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "show_doc(iTransformer.fit, name='iTransformer.fit')" ] @@ -578,51 +392,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "---\n", - "\n", - "### iTransformer.predict\n", - "\n", - "> iTransformer.predict (dataset, test_size=None, step_size=1,\n", - "> random_seed=None, **data_module_kwargs)\n", - "\n", - "Predict.\n", - "\n", - "Neural network prediction with PL's `Trainer` execution of `predict_step`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`test_size`: int=None, test size for temporal cross-validation.
\n", - "`step_size`: int=1, Step size between each window.
\n", - "`**data_module_kwargs`: PL's TimeSeriesDataModule args, see [documentation](https://pytorch-lightning.readthedocs.io/en/1.6.1/extensions/datamodules.html#using-a-datamodule)." - ], - "text/plain": [ - "---\n", - "\n", - "### iTransformer.predict\n", - "\n", - "> iTransformer.predict (dataset, test_size=None, step_size=1,\n", - "> random_seed=None, **data_module_kwargs)\n", - "\n", - "Predict.\n", - "\n", - "Neural network prediction with PL's `Trainer` execution of `predict_step`.\n", - "\n", - "**Parameters:**
\n", - "`dataset`: NeuralForecast's `TimeSeriesDataset`, see [documentation](https://nixtla.github.io/neuralforecast/tsdataset.html).
\n", - "`test_size`: int=None, test size for temporal cross-validation.
\n", - "`step_size`: int=1, Step size between each window.
\n", - "`**data_module_kwargs`: PL's TimeSeriesDataModule args, see [documentation](https://pytorch-lightning.readthedocs.io/en/1.6.1/extensions/datamodules.html#using-a-datamodule)." - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "show_doc(iTransformer.predict, name='iTransformer.predict')" ] @@ -654,214 +424,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/marcopeix/miniconda3/envs/neuralforecast/lib/python3.10/site-packages/pytorch_lightning/utilities/parsing.py:198: Attribute 'loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['loss'])`.\n", - "/Users/marcopeix/miniconda3/envs/neuralforecast/lib/python3.10/site-packages/pytorch_lightning/utilities/parsing.py:198: Attribute 'valid_loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['valid_loss'])`.\n", - "Seed set to 1\n", - "GPU available: True (mps), used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "\n", - " | Name | Type | Params\n", - "---------------------------------------------------------\n", - "0 | padder | ConstantPad1d | 0 \n", - "1 | loss | MSE | 0 \n", - "2 | valid_loss | MAE | 0 \n", - "3 | scaler | TemporalNorm | 0 \n", - "4 | enc_embedding | DataEmbedding_inverted | 3.2 K \n", - "5 | encoder | TransEncoder | 135 K \n", - "6 | projector | Linear | 1.5 K \n", - "---------------------------------------------------------\n", - "140 K Trainable params\n", - "0 Non-trainable params\n", - "140 K Total params\n", - "0.562 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "db2340a0a0ea4ab79a8f3c3fbc5e8962", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Sanity Checking: | | 0/? [00:00]. Skipping setting a default `ModelSummary` callback.\n", - "GPU available: True (mps), used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "/Users/marcopeix/miniconda3/envs/neuralforecast/lib/python3.10/site-packages/pytorch_lightning/trainer/connectors/data_connector.py:441: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=10` in the `DataLoader` to improve performance.\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "b61339b3642d44bfb953a7b2becf4cc4", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Predicting: | | 0/? [00:00=AirPassengersPanel['ds'].values[-12]].reset_index(drop=True) # 12 test\n", @@ -891,18 +454,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABmcAAAKHCAYAAAB0L5wRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3hUZfrG8e+kk5CEnkLvvfcivVgQsSBWUNwVxZXFXrDg4mJZQazrDwXBXlBEERFEQOrSeycJkEYIBNL7+f0xnjEhnZnMJOH+XFcuJ3POec8z5USde573tRiGYSAiIiIiIiIiIiIiIiJO4ebqAkRERERERERERERERK4kCmdEREREREREREREREScSOGMiIiIiIiIiIiIiIiIEymcERERERERERERERERcSKFMyIiIiIiIiIiIiIiIk6kcEZERERERERERERERMSJFM6IiIiIiIiIiIiIiIg4kcIZERERERERERERERERJ1I4IyIiIiIiIiIiIiIi4kQKZ0RERESkylu7di0WiwWLxcKMGTNcXY6IiIiIiIhc4RTOiIiIiEilMGfOHFvAYrFY+Oqrr1xdUr56Lv2pXr06jRo1YvTo0bz33nskJia6ulyREkVERBT7vi7sZ+zYsa4uW0owY8YMZsyYwcKFC11dioiIiIj8SeGMiIiIiFQKCxYsyPf7/PnzXVRJ6aSkpHD69Gl+/vln/vGPf9CqVSt+/fVXV5clIlegl156iZdeeknhjIiIiEgF4uHqAkRERERESrJlyxYOHDiQ777Vq1cTERFBkyZNSjx+8ODBGIZRTtVZLVmyJN/vSUlJ7N69m08++YT4+HjOnDnDDTfcwLp16+jdu3e51iLiCHXr1mXevHkl7hcSEuKEakREREREqhaLUd7/lyoiIiIiYqe///3vfPTRRwDce++9fPzxxwC88MILvPTSSy6ry2Kx2G4X9Z/V586d45prrmHbtm0A9OnTh82bNzulPpGyioiIoGnTpgA0btyYiIgI1xYkDmH+rRo0aBBr1651bTEiIiIiAmhaMxERERGp4FJSUvj6668BaNq0KW+99RbVq1cH4OOPPyY3N9eV5ZWodu3aLFq0yPb7li1bOHXqlAsrEhEREREREVdTOCMiIiIiFdo333xDUlISAHfffTf+/v7cfPPNAJw+fZpVq1aVOMbatWtti5fPmDGj0H2aNGmCxWKxTZOWkZHBe++9x+DBgwkJCcHd3b1UU6gVpm3btrRs2dL2+759+2y309PTWbp0KVOnTqVfv37UrVsXT09P/P39admyJXfffXepHiNAYmIis2fPZsiQIQQFBeHl5UVAQADNmzenX79+PProo6xYsYLMzMxCj4+NjeWll16if//+1KlTB09PT2rUqEGrVq0YOHAg06dPZ+3atSUGYrt37+af//wnnTt3platWnh7exMaGsp1113HggULyM7OLvZ487UaPHiw7Tl6++236du3L7Vr16ZatWo0b96cyZMnExYWVqrnJiUlhVmzZtG9e3cCAwPx9/enQ4cOTJ8+nZiYGADuuece27lL6hi5ePEis2fPZvjw4YSGhuLt7U2tWrXo3r07zzzzDFFRUcUeX9i5fvjhB2666SYaN26Mt7d3oXWsX7+eSZMm0bZtW/z9/fHy8iI4OJiOHTty44038t577xEeHl6q56S8ZWRk8N///perr74633PUtWtXnnzyyRLrLOy6PXbsGI899hjt27enRo0aRV7T6enp/N///R+jR4+mYcOG+Pj4EBgYSIcOHZg6dSpHjx4t9eOIj4/n1VdfZdiwYbbH4evrS8uWLRk3bhzz588nMTGx0GOPHj3KnDlzuPHGG2nZsiXVq1fHy8uLevXqMXDgQF5++WXi4+NLVcflvPbm82dat26d7b68P1qLRkRERMQFDBERERGRCqx///4GYADG8ePHDcMwjN9//91237hx40ocY82aNbb9X3zxxUL3ady4sQEYjRs3NsLDw40OHTrYjjF/GjdunO+YvNtK0q9fP9u+n3/+ue3+pk2bFjhPYT833HCDkZSUVOT427dvN4KDg0s11rZt2wocv3z5csPf379Ux589e7bQGtLT041JkyYZFoul2OPbt29vnDhxosjHYu43aNAgIywszOjYsWORY/n5+Rm//fZbsc/9oUOHbK9vYT9169Y1/vjjD2PixIm2+8LDw4sc75tvvjFq1apV7GP08fExFi5cWOQYec915MgR4+abby50HLOOnJwcY/LkyaV6fa677rpin4/ihIeHF/l+L4sdO3YU+5wDhpeXl/Gf//ynyDEuvW4//fRTo1q1agXGufSaXrt2rVG/fv1iz+3u7m7MmjWrxMfxzjvvGH5+fiU+5/fcc0+BYxctWlSq1ysgIMBYtmxZkTXY89qX5hjA+Pjjj0t8LkRERETEsTwQEREREamgjhw5wsaNGwEYMGAAzZs3B2Dw4ME0adKEiIgIli5dSnx8PHXq1HHIOTMyMrjpppvYv38/ffr04ZZbbqFhw4ZcuHAhX8dLWcXFxdlu16hRw3Y7NTWVGjVqMHToULp27Urjxo3x9fUlMTGRvXv38vXXXxMTE8PSpUuZNGkS33zzTYGxU1NTGTt2LLGxsQB0796dG2+8kfr16+Pn50dCQgKHDh1izZo17Nmzp8Dx0dHR3HrrrSQnJwPWdSmuu+46goOD8fb2Jj4+nv3797N69eoiOw6ys7O5+uqrbetZBAUFcdttt9GlSxf8/PyIiopiyZIl/PHHHxw4cICBAweya9cu6tatW+RzlpiYyHXXXcehQ4cYOXIko0ePJjg4mNjYWD755BO2b99OSkoKt99+O4cPH6ZWrVoFxjh79ixDhw61dcc0atSISZMm0bp1a5KTk1m5ciWLFy/mpptuonPnzkXWYvrwww+ZPHkyhmHg4eHB6NGjGTp0KMHBwaSkpLBx40Y+//xz0tLSuOeee/Dy8uL2228vdsxp06bxyy+/0LhxYyZMmECbNm3IzMxk69ateHt7A/Duu+/yf//3fwD4+/tzyy230L17d+rWrUtmZiaRkZFs376d3377rcTHUN7279/PoEGDbO+n1q1bc/fdd9OiRQsuXrzI8uXLWbp0KZmZmTzxxBNkZGQwffr0YsfctGkT//73v7FYLEycOJGrrrqK6tWrExYWRoMGDWz7/fLLL9xwww1kZWVhsVgYPnw4o0aNokGDBmRmZrJ9+3Y++eQTLly4wLPPPgvAM888U+g5n376aV577TXb7wMGDGD06NE0btyY3NxcTp06xcaNG1m1alWha06lpqZisVjo3LkzAwcOpE2bNrb3aGRkJL/99hsrVqwgMTGRm2++mU2bNtGtW7cC49jz2i9ZsgSAG2+8EYD27dvz8ssvF9ivsPOKiIiISDlzdTokIiIiIlKUJ554wvbN7g8//DDftueff9627c033yx2nLJ0zpg/r776aon15d2/OAcPHsy376lTp2zbli9fbmRmZhZ5bEpKinHjjTfajl2/fn2Bfb799lvb9scee6zYWg4cOGDExcXlu+8///mP7fh33nmn2OP/97//GWlpaQXuf/rpp21j3H777UZycnKhx7/77ru2/e68885C98n7XHl4eBjffPNNgX2ys7ON66+/3rbfG2+8UehYEyZMsO0zdOjQQutatmyZ4eXlVWjHSl579uwxvL29DcBo2LChsXv37kLPefjwYaNBgwYGYPj7+xvnzp0rsE/ezhnAGDt2bKHPq6l9+/YGYNSqVcs4efJkkfulp6cbW7ZsKXJ7SeztnMnNzTU6depkG2PixImFvr+///57w9PT09bFsn379gL75L1uAaNevXrGnj17ijx3dHS0raMpMDDQWL16dZH7mTW6u7sbhw4dKrDPDz/8YDuvn5+f8f333xd53nPnzhlr1qwpcP/+/fuNY8eOFXmcYRjGb7/9Zvj6+hqAMWzYsEL3ccRrbz6WQYMGFVuPiIiIiDiPwhkRERERqZCysrKMoKAgA6xTRF24cCHf9uPHj9s+cOzQoUOxY5U1nLnhhhtKVWNpwpnz588bvXv3tu3Xp0+fUo2d18WLF21TK/3tb38rsP2VV16xjX/gwIEyj593yqSUlJQyH3/mzBnDx8fHAIwePXoY2dnZxe5/55132j4Yj4yMLLA97/P6/PPPFznOkSNHbPsV9sF2bGysLQAIDAw0zpw5U+RYzz33XInhjBmSubu7Gzt37iz2Ma5atarYoC9vOFO/fv1ip6wzDMMWCpVmGj975A1nSvNz6Yf9y5Yty3ddZmVlFXmul156ybbvrbfeWmD7peHMkiVLiq39kUcese27dOnSYvc9fPiw4e7ubgDGAw88kG9bbm6uLRABjK+++qrYseyVN2gu7HpwxGuvcEZERESk4nFDRERERKQC+umnnzhz5gwAY8eOJTAwMN/25s2bM2DAAMA6jdLWrVsddu6pU6eW+Zgffvgh389nn33GE088QZs2bfjf//4HgJeXF3PmzCnz2AEBAXTs2BGALVu2FNju5+dnu71jx44yj2/v8V9//TXp6ekAPP7447i7uxe7/4QJEwDIyclh9erVRe7n5ubGP//5zyK3t2rVioYNGwJw4MCBAtt//vlnsrKyALjzzjupV69ekWM9/PDDeHgUPevzhQsXWLp0KQAjRoyga9euRe4LMHz4cEJDQwH49ddfi9130qRJVK9evdh9zNdo3759ZGZmFruvK3333Xe2248//nixz+m0adPw9fUFrNe7+VoVplGjRtxwww1FbjcMg08//RSwTqM2ZsyYYuts3bo1vXr1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4MGDWbZsGQDff/89/fv3v+xaHalnz5588MEHAKxZs8YWUBUmLi6u2GBp0KBBWCwWDMNg2bJlZGZm4uXl5fCaL4eHhwfjxo0jKirKFrytX7+em2++2em19OnTh0OHDgHw66+/MnHixCL3TUpKYtOmTYB12rLOnTtf9nm7dOlCjRo1uHDhAuvXryc+Pr5UaxYVZuDAgbbbP/zwAy+88EKZx8gbTJV0fZsdNpejtK+9+d69nOkXRURERKR8qHNGRERERCqMixcv8t133wHWb4i///77zJgxo8SfuXPn2sZYtGhRoes2VDR5p9w6fvx4sfu++OKLdp/P09OT+vXr2343g6HSqlWrlm26p0vXULntttts61x88MEHJT4eZ7nuuutsU0Z9/vnnnD17tsh933nnnWLfN3Xq1OG6664DrB+8z54927HFOkDTpk1tt8v6+jpK3gBs9uzZxdbx1ltv2aY/GzNmTKmm9yqKu7s7d911FwAZGRlMnz79ssfq1q0b7du3B2DXrl18/fXXZR6jtNf3pk2bWLFiRdmLvERJr7057Vtpp5sTERERkfKncEZEREREKowvvviCtLQ0AEaOHFnsVEB5tWrVij59+gAQExNj1zfRnSUgIIBWrVoBsGPHDhYvXlxgn5ycHB555JESP7x9++23+fbbb/Mtan6p9evXs3fvXsA6bVPeroKXXnqJX3/9ldzc3CKP/+KLL2yLrnft2jXftvr169u+tZ+amsqoUaPYtWtXsTXv37+fBx54oNh97BUUFMTtt98OWIO/2267rdAPp3/++Wdef/31Esd7+eWXbSHUc889x1tvvVVsJ8LFixeZO3cuv/3222U+AquYmBgee+yxYqdmy8rKYt68ebbfu3TpYtc5L9c111xj64DZt28f999/f4EwD+DHH39k5syZgDVYefLJJ+0+97PPPkutWrUAmDdvHk899VSh5zalpaXx8ccf89VXX+W732Kx8PLLL9t+v++++/jhhx+KHCchIcE2RaGpZ8+ettsvvfQS6enpBY7bu3cv48aNK/Y95KjX3gxvDh8+bPsbKyIiIiKupWnNRERERKTCyDul2YQJE8p07IQJE9iyZYttnOuvv96htZWHadOm2daaufXWWxk/fjyDBg2iZs2aHD9+nM8//5xDhw7RoUMHvL292bFjR6Hj7Ny5k0WLFhEYGMioUaPo1q0bDRo0wMPDg7i4ONasWcOyZcts4cula8asWbOGGTNmUK9ePUaNGkWXLl0ICQnBYrEQExPDL7/8ki9guPR4sAYXe/bs4ZdffiEsLIwePXpw9dVXM3ToUOrXr4/FYuHcuXPs37+ftWvXcujQIdzd3W3TjpWXN954g1WrVhETE8Pvv/9Ou3btmDRpEm3atCE5OZmVK1fy7bffUqtWLbp06cLq1asBCl1QvXPnznz00UdMnDiR3Nxcpk2bxvvvv8+NN95I27Zt8fPzIykpiRMnTrB161bWrVtHZmYmn376qV2PISMjgzlz5jBnzhy6d+/OVVddRbt27ahRowbJycmcOHGCL7/80rZmTrNmzbjtttvsOuflslgsfP755/Tp04fk5GQ+/vhjNm/ezIQJE2jWrBmJiYn88ssv+dZFeemll+jWrZvd5w4JCeHbb7/luuuuIz09nddff53PP/+ccePG0alTJ/z9/UlJSeHkyZNs376d1atXk5qaaguJ8ho7diyPPfYYs2fPJiUlhRtvvJEBAwYwevRoGjdujGEYnD59ms2bN7NixQrGjx/P4MGDbcffdNNNNGrUiFOnTrF9+3Zat27N3/72N1q0aEFqairr1q3jq6++Iisri4kTJ7Jo0aJCH5OjXvvhw4ezd+9eUlJSuP7665kwYQJ169bFYrEA0LFjx3yddSIiIiLiBIaIiIiISAWwe/duAzAAIzAw0EhLSyvT8efPnze8vb0NwPDw8DBiY2Nt29asWWMb+8UXXyz0+MaNGxuA0bhx41Kf0xzzcv+zOjc315g0aVK+cS796dixoxEWFmYMGjSoyHPde++9xY5h/nh6ehovv/xygeOHDBlSquP9/PyMBQsWFPl4srKyjCeeeMLw9PQs1XhFPdfm9kGDBpX4HBb3vJgOHjxoNGrUqMg6ateubaxdu9a48847bfedP3++yPFWrlxpNGjQoFSP0dvb2/jll18KjDFx4kTbPuHh4cU+xoiIiFKdCzA6dOhgHD9+vMTnrSjh4eElvj6lsX37dts1VdSPl5eX8dprrxU5Rmmu28Ls3LnTaNOmTameL3d3d+PDDz8scqw33njD8PHxKXGce++9t9DnoE6dOsWe+9VXXy32cTrqtY+KijKCgoKKPPbjjz8u9fMrIiIiIo6hzhkRERERqRDyds2MGzcOHx+fMh1fs2ZNrr/+ehYvXkx2djaLFi1yyFRJ5clisTB//nyuu+465s2bx/bt20lMTKR27dq0bt2acePGcd9995X4XHzwwQfcc889rFmzhg0bNnDkyBHOnj1LdnY2AQEBtGzZksGDB3PffffRsmXLAscvW7aMDRs2sGbNGjZt2sTx48eJj4/HMAxq1KhBmzZtGD58OH/7298IDQ0tsg4PDw9ef/11/vGPf7BgwQJ+//13jh07xvnz53Fzc6N27dq0atWK3r17M2rUqHwLr5entm3bcvDgQd566y0WL17M8ePHMQyDhg0bcv311zN16lTq16/Pq6++ansc5vo6hRkxYoStY+Hnn39m+/btnD17lvT0dPz9/WnSpAmdO3dm6NChXH/99dSoUcOu+hs3bsypU6dYs2YNa9asYefOnZw6dYqkpCS8vLwIDg6ma9eu3Hzzzdx66614eLj+f/O6d+/OkSNHmD9/PkuXLmXv3r2cO3cOPz8/GjduzIgRI5gyZUq+tVIcpWvXrhw4cIAlS5awdOlStmzZwpkzZ0hJSaF69eo0bNiQjh07MmTIEK6//vpip0987LHHuOOOO5g3bx4rV67k2LFjJCQk4OXlRf369enWrRvXXHNNvrV28j4He/fuZfbs2SxbtoyTJ0/i4eFBaGgoQ4YM4f7776dbt24FpkTLy1GvfWhoKDt37mT27Nn89ttvhIeHk5ycXOyUaiIiIiJSviyG/mtMRERERESucLm5uQQHB3P27Fk6d+7M7t27XV2SiIiIiIhUYQUnUhYREREREbnCfP3115w9exaAIUOGuLgaERERERGp6hTOiIiIiIhIlbZlyxbS09OL3L5hwwYeeughANzc3Lj//vudVZqIiIiIiFyhXD8ZsYiIiIiISDl69dVX+eOPP7jmmmvo0aOHbd2cqKgofvvtN1asWGFbe+PJJ5+kbdu2rixXRERERESuAFpzRkREREREqrSxY8eydOnSYvexWCw89thjvPbaa7i5aYIBEREREREpXwpnRERERESkSjt+/Dg//vgjq1at4sSJE5w7d47ExET8/f1p1KgRgwYN4v7776d9+/auLlVERERERK4QCmdEREREREREREREREScSGvO2CE3N5fo6Gj8/f2xWCyuLkdERERERERERERERFzIMAySkpIIDQ0tdspkhTN2iI6OpmHDhq4uQ0REREREREREREREKpDTp0/ToEGDIrcrnLGDv78/YH2SAwICXFyNyOXLyspi5cqVjBw5Ek9PT1eXIyLF0PUqUrnomhWpPHS9ilQuumZFKg9dr3KlSUxMpGHDhrb8oCgKZ+xgTmUWEBCgcEYqtaysLHx9fQkICNC/JEUqOF2vIpWLrlmRykPXq0jlomtWpPLQ9SpXqpKWQil6wjMRERERERERERERERFxOIUzIiIiIiIiIiIiIiIiTqRwRkRERERERERERERExIkUzoiIiIiIiIiIiIiIiDiRwhkREREREREREREREREnUjgjIiIiIiIiIiIiIiLiRB6uLuBKlJWVRU5OjqvLkCuIu7s7np6eri5DRERERERERERERFA441SJiYnEx8eTkZHh6lLkCuTt7U2dOnUICAhwdSkiIiIiIiIiIiIiVzSFM06SmJhIVFQU1atXp06dOnh6emKxWFxdllwBDMMgKyuLixcvEhUVBaCARkRERERERERERMSFFM44SXx8PNWrV6dBgwYKZcTpqlWrhr+/P5GRkcTHxyucEREREREREREREXEhN1cXcCXIysoiIyODwMBABTPiMhaLhcDAQDIyMsjKynJ1OSIiIiIiIiIiIiJXLIUzTpCTkwOgBdnF5cz3oPmeFBERERERERERERHnUzjjROqaEVfTe1BERERERERERETE9RTOiIiIiIiIiIiIiIiIOJHCGRERERERERERERERESdSOCMiIiIiIiIiIiIiIuJECmfE6SwWS5l+mjRp4uqSRUREREREREREREQcxsPVBciVZ+LEiQXu27BhAydOnKBz58506dIl37Y6deo4qTIRERERERERERERkfKncEacbuHChQXuu+eeezhx4gRjx45lxowZTq9JRERERERERERERMRZNK2ZiIiIiIiIiIiIiIiIEymckQpt7dq1WCwW7rnnHmJjY/nb3/5GgwYN8PDwYO7cuQAMHjwYi8VCREREgeMjIiKwWCwMHjy40PF/+uknRo0aRe3atfHx8aFVq1Y8//zzJCcnl9+DEhERERERERERkStSbm4uf//733n++ecxDMPV5YgLaVozqRTOnj1Lz549yc7OZsCAAaSnp+Pr62vXmI899hhz5szBx8eHXr16UadOHXbs2MHLL7/ML7/8wrp16/Dz83PQIxAREREREREREZEr3YEDB/joo48A6NChA+PHjy90v3374OGHoWlT+PhjZ1YozqJwpgIwDIPU1FRXl1Fqvr6+WCwWp55z+fLl3HjjjXzxxRf4+PjYPd4333zDnDlz6Nq1K99//z1NmjQBICsri3/84x/MmzePGTNm8J///Mfuc4mIiIiIiIiIiIgA+Wb/eeihhxgyZAj16tWz3ZeTA3PmwHPPQWYmrFsH770Hdn5PXSoghTMVQGpqKtWrV3d1GaWWnJzs9I4Sb29v3nnnHYcEMwCzZs0C4Msvv7QFMwCenp689dZb/Pjjj3z00Ue89tpruLlp9j8RERERERERERGx38mTJ223z507x0MPPcS3334LQHg4TJwI69fnPyYyElq1cmaV4gz61FkqhW7dulG/fn2HjBUXF8eePXto27YtrVu3LrDdx8eHHj16cOHCBY4dO+aQc4qIiIiIiIiIiIiY4czQoUPx8PBg8eLFfPPNt8yfD506WYOZ6tVh/nxo1856zKlTLixYyo06ZyoAX1/fSrUAvb1rvVyORo0aOWws8w/goUOHSpyeLT4+vtAAR0RERERERERERKSszM8mr7/+evr378/Mmf/H3Xf7k5lp3X7VVbBokXWtmW++gYMH4fRpFxYs5UbhTAVgsVi08HwJLnc6s9zc3AL35eTkABASEsLIkSOLPb527dqXdV4RERERERERERGRS5lrzjRu3JjQ0Idwd59GZmYt3NyyeO01Tx55BNzdrfs2bGj9p8KZqknhjFR6Xl5eAIV2H50u5C9XgwYNAAgODmbhwoXlWpuIiIiIiIiIiIiIydo5E8CCBQNZtswTqAXsJjf3bpo2nYG7+822fRXOVG1ac0YqvZCQEACOHj1aYNvKlSsL3NegQQNat27N3r17CQ8PL/f6RERERERERERERNLS0oiLuwBsZtmy2ri5wTPPwFNPLQH2M2XKFOLj4237K5yp2hTOSKU3aNAgAGbPnk1qaqrt/t9++425c+cWesxzzz1HTk4ON998M/v37y+w/cSJEyxYsKBc6hUREREREREREZErz6lTp4DOQDsCAgz++ANmzYKXXnqW9u3bExcXx9SpU237K5yp2hTOSKV3++2307p1azZt2kTbtm255ZZb6N27N6NGjWLKlCmFHnPXXXfx5JNPsmvXLrp06ULPnj259dZbufrqq2nbti0tWrTg7bffdvIjERERERERERERkarKOqVZKwC6dbPQv7/1fm9vbz7+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5euvv+bWW2+1jZebm8vy5cvznfv+++/nzTffJCQkJN9+L7/8Mi+++CLPPfccCxYssG17++23SUtL47vvvuOmm27KN9ahQ4ds9f/tb3+jRYsW/PrrrwwYMEBr9oiIiIiIiIiIiFRQhmFw/nwdANq39yrz8eaXu93do4Dm6pypQjStWQVgGJCSUnl+DMOxjz/vtFx5fy5cuADA2rVr2bdvH02bNmXmzJm2EAXglltuYezYsSQlJfHxxx8XOv7bb7+dL5gB+Omnn9i/fz+33347U6dOzTdm165def7550lJSeGzzz6z3f/mm2+Snp7O5MmT8wUzAG5ubowePTrffUOHDs0XzJj7vfDCC9SvX5+lS5fm2xYXF2c77lJt27YtMJaIiIiIiIiIiIhUbPHx8eTkNAOgR4+AMh9vds5kZ0cAcOqUw0oTF1PnTAWQmgrVq7u6itJLTgY/P8eNN3HixELv9/KyJsnr168HYPz48bi7uxfY7+677+b7779n/fr1PP300/m2hYSE0KNHjwLHrFq1CoCxY8cWem5zqrC869n89ttvAEyePLm4h5PPuXPn+PHHH9m/fz8XLlwgJycHgKysLM6fP8/58+epVasWAN27d+eXX35hwoQJPPfcc/To0QM3N+WnIiIiIiIiIiIildXJkyeBlgC0b+9Z5uPNcCY9/QigNWeqEoUz4nIlTcsVHR0NQJMmTQrdbt5v7pdXo0aNCj0mIiICsAY+48ePL/Lc8fHxttun//zL16xZs2LrNX355Zfcf//9JCcnF7lPUlKSLZx54okn2LBhAz/99BM//fQTgYGB9O7dm9GjR3PPPffg7+9fqvOKiIiIiIiIiIhIxXDwYBRg/fJ4y5ZlP94MZxITDwIKZ6oShTMVgK+vtRulsvD1dc158049VtrtPj4+he5rdrBcc801tjVlCtOmTZsC5yipDrAm4vfccw+GYTB37lyuu+466tevT7Vq1QDo168fmzdvxsgzR1xAQAC///47Gzdu5KeffmLt2rWsXr2alStX8sorr7B+/XqaN29e4rlFRERERERERESkYti1y/rBr49PAgEBNct8fL169XB3dycn5ySgcKYqUThTAVgsjp0mrKoxF70KDw8vdLu1NZAyrcnSoEEDAB544AHGjBlTqmMaNmzIsWPHOHHiBB06dCh23+XLl5OZmcljjz3GP//5zwLbw8LCCj3OYrEwYMAA27RqZ8+e5Z///Cdffvklzz77LF9//XWpahURERERERERERHXO3gwG4A6dRKAsocz7u7uhISEEBlpTWXOnIHMTPhzRQipxLSghVR4V111FQBff/21reMlr88++yzffqUxfPhwAH744YcyHzNv3rwS901ISACsgc6l/vjjD86cOVOqc9atW5cZM2YAsG/fPtv95no82dnZpRpHREREREREREREnC8iwvo5XqNGGZc9hvXL6/F4eeVgGBAV5aDixKUUzkiFN3jwYDp27Eh4eDgvvPBCvqnAfvjhB77//nuqV6/OPffcU+oxb7nlFtq0acPChQt57bXXyMrKyrc9MzOT77//Pl8gMm3aNHx8fPjggw/47rvv8u2fm5vL8uXLbb+3atUKsAZHKSkptvujoqJ44IEHCq3pgw8+KLQ76JdffgHyr59jdhMdOXKkVI9XREREREREREREnC8urgYArVuXvFRCUcx1ZwIDkwBNbVZVaFozqfAsFguff/45Q4YMYdasWSxZsoQuXbpw6tQpNm7ciIeHBwsWLCA4OLjUY3p4eLBkyRJGjRrF008/zVtvvUWnTp0ICAjg9OnTHD58mAsXLrBkyRI6duwIWAOXBQsWMHHiRG655RY6dOhAhw4dSEhIYN++fURHR9uCozFjxtC+fXu2b99OixYt6N+/P+np6axZs4YuXbrQr18/Nm3alK+mDz74gAcffJB27drRtm1bPDw8OHLkCLt376ZatWq8+OKLtn2bNGlCp06d2L59O7169aJ9+/a4u7szZsyYUk/TJiIiIiIiIiIiIuUrKSkIgC5dLn8hbzOc8fU9B9RQOFNFqHNGKoWOHTuyc+dO/v73v5OcnMzixYs5cuQIY8eOZePGjYwbN67MY7Zp04bdu3czY8YM6tWrx4YNG/j55585e/YsAwcO5OOPP7ZNZWa6/fbb2bZtG3fccQfnzp3ju+++Y/fu3bRs2ZK3337btp+Xlxfr16/nwQcfxMfHh2XLlnHo0CEefvhhVq1ahaenZ4F6Zs6cyaRJk7BYLKxevZqffvqJ1NRU7r//fvbu3Uvfvn3z7f/dd98xduxYwsLC+OSTT5g/fz47d+4s8/MgIiIiIiIiIiIijnfhwkVycpoD0K9f7csexwxn3N1jAHXOVBXqnBGXyTs9WWk0atSoVOu9gLWzpDTj16xZkxdffDFfV0pJOnfuzOeff16qsd9///1Ct61du7bAfddffz3XX399qeto0aIFS5YsKfX+IiIiIiIiIiIi4jy7dkUB7YBcOnb0u+xxzHAmN/ckMIBTpxxSnriYOmdERERERERERERERBzsf/9LAMDLKxpv78sfxwxn0tKOAuqcqSoUzoiIiIiIiIiIiIiIONi+fekA1Khx1q5xQkNDAUhM3A8onKkqFM6IiIiIiIiIiIiIiDjYsWPWj99DQpLtGuevzpkjgMKZqkLhjIiIiIiIiIiIiIiIg0VF+QLQrFm2XeP4+/vj7+8PWFOZ8+chNdXe6sTVFM6IiIiIiIiIiIiIiDhYQkIdADp2tGPBmT9Zu2cS8fW1Bj3qnqn8FM6IiIiIiIiIiIiIiDhQTg6kpVmnI+vZM9Du8cypzWrWtE6RpnCm8lM4IyIiIiIiIiIiIiLiQMeOpQM+QAa9e4fYPV5oaCgAvr7nAYUzVYHCGScyDMPVJcgVTu9BERERERERERGR8rdx41kA3NzCqFOnpt3jmZ0znp6xgMKZqkDhjBO4u7sDkJWV5eJK5EpnvgfN96SIiIiIiIiIiIg43s6d1unH/PxisFgsdo9nhjOGcQpQOFMVKJxxAk9PT7y9vbl48aI6F8RlDMPg4sWLeHt74+np6epyREREREREREREqqzDh7MBqFs3wSHjmeFMRsYxAE6dcsiw4kIeri7gSlGnTh2ioqKIjIwkMDAQT09PhySmIiUxDIOsrCwuXrxIcnKy7Q+5iIiIiIiIiIiIlI+ICG8AGjVKd8h45md6iYkHAXXOVAUKZ5wkICAAgPj4eKKiolxcjVyJvL29qV+/vu29KCIiIiIiIiIiIuUjLi4QgNatHfMFfTOcOX9+D2ANZwwD9P3/ykvhjBMFBAQQEBBAVlYWOTk5ri5HriDu7u6aykxERERERERERMQJMjIgObkOAN26VXfImEFBQbi5uZGbGwFAcjJcvAg1ajhkeHEBhTMu4OnpqQ/KRURERERERERERKqgsDAAdyCRTp2CHDKmh4cHQUFBxMTEEBiYxcWLnpw+rXCmMnNzdQEiIiIiIiIiIiIiIlXFwYPZf946SpMmjR02rjm1Wa1aqYDWnansFM6IiIiIiIiIiIiIiDjIjh0XAXBzC6NevXoOG9cMZ6pXTwAUzlR2CmdEREREREREREREKinDMAgPD8cwDFeXIn/auzcDgBo14nBzc9xH8GY44+UVCyicqewUzoiIiIiIiIiIiIhUQllZWdxyyy00a9aML774wtXlyJ+OH7d+7B4amuzQcc1wxjCsqYzCmcpN4YyIiIiIiIiIiIhIJZOTk8OECRP4/vvvAdi6dauLKxJTVJQfAM2b5zh03NDQUAAyM08AcOqUQ4cXJ1M4IyIiIiIiIiIiIlKJ5Obmct999/HVV1/Z7ouKinJhRWJKSoLkZH8A2rf3cujYZudMUtJBQJ0zlZ3CGREREREREREREZFKwjAMHnroIRYtWoS7uzsTJ04EFM5UFMeOmbfO0KZNsEPHNsOZ8+f3ABAZCVpqqPJSOCMiIiIiIiIiIiJSCRiGwaOPPsoHH3yAxWLh008/5cEHHwQgMjLSxdUJ5A1njtGkSROHjv1X58whLBaDjAw4e9ahpxAnUjgjIiIiIiIiIiIiUsEZhsH06dOZO3cuAPPnz+f222+nQYMGAMTExJCT49g1TqTsjhzJ/fPWURo3buzQsQMCAvDz8wOyqFvX+lprarPKS+GMiIiIiIiIiIiISAX38ssv88orrwDw3nvvce+99wIQFBSEm5sbOTk5xMXFubJEAfbsSQfAYjlOaGioQ8e2WCy2MWvVSgUUzlRmCmdEREREREREREREKrA33niDF154AYDZs2czZcoU2zYPDw+Cg61rm2hqM9c7fNja0VKnzjk8PDwcPr45tZm//wVA4UxlpnBGREREREREREREpIJ69913eeKJJwBr98yjjz5aYB9zarOoqCin1ib5GQZERHgD0KhRRrmcwwxnvL2tXVIKZyovhTMiIiIiIiIiIiIiFdBHH33Eww8/DMD06dOZPn16ofuZH9irc8a14uMhNdULyKV1a8d3zcBfr7XFYn2tFc5UXgpnRERERERERERERCqYZcuWcf/99wPw6KOPMnPmzCL3VedMxXDsmHnrFM2bO3a9GZMZzmRlnQAUzlRmCmdEREREREREREREKpj58+djGAb33HMPb7zxBhaLpch9zQ/sFc641tGj5q1jNG7cuFzOYb7WycmHATh1qlxOI06gcEZERERERERERESkgjl+/DgAt912W7HBDGhas4rir3DmaLmFM6Gh1o6c8+f3ABAdDTk55XIqKWcKZ0REREREREREREQqkNzcXE6csE5b1aJFixL317RmFcPR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7bi7G2RmetCly7XUr+/qyq485oxbJbErnJkyZQoLFy4kPDycZs2a0apVKw4ePEh2dja1atVi/PjxBY75/fffsVgsdOnSxZ5T5+Pn50fHjh05duwYY8eOBazdMWbrHkBcXJytmyY4OJjMzEwSEhLydc/ExcXZFk8qjLe3N97e3gXu9/T0rBJ/WET0XhapPHS9ilQuumZFKg9dryKVi67ZgjIzM7nzzjtJSEigV69ezJ492/YcNWzYELB+WJ6YmGhbw1lcx+xmat68ucPfy40aNQIgJiamQlwnVeV6PXQoC3AHjtCx480V5jH1798fgLCwIzRpkkNEhAcnT3rSpIlr67oSlfY9YVc83q1bN/7zn/9gsVhITk5m586dpKen4+npyYcffoi/v3++/S9evMjPP/8MwIgRI+w5dT4ZGRkcOnSIkJAQmjZtSnBwcL42uczMTNatW2cLXrp3746np2e+fWJiYti/f3+x4YyIiIiIiIiIiEhF9sQTT7Bt2zZq1qzJN998g5eXl22bp6cn9erVAyA6OtpVJUoeJ06cAKBFixYOH7tBgwYAREZGOnzsK9m+fdbp4mrWPEuNGjVcW0weNWrUoH379gDUrHkOgOPHXVmRlMSuzhmARx55hOHDh7N48WJbt8rtt99O69atC+y7du1aevbsCcDw4cMv+5yPP/44119/PY0aNSIuLo6XX36ZxMREJk6ciMViYdq0acyaNYuWLVvSsmVLZs2aha+vL3fccQcAgYGB3HfffTz22GPUrl2bWrVq8fjjj9OxY0e76hIREREREREREXGVxYsX8/bbbwPwySef0Lhx4wL7hIaGEhcXR3R0NJ07d3Z2iXKJ439+el4e4Uz9P+ezio6OJjc3V9PYOYBhwMmT1sCzkI+/Xc5cl91iOQ4EceyYqyuS4tgdzoB1vsqOHTuWuN8NN9zADTfcYPf5IiMjuf3224mPj6du3br06dOHLVu22P6F8+STT5KWlsaUKVNISEigd+/erFy5Ml8nz5tvvomHhwe33noraWlpDBs2jIULF+Lu7m53fSIiIiIiIiIiIs50/PhxJk2aBMBTTz3F6NGjC90vNDSU3bt3q3OmgijPcCYkJASLxUJWVhZnz561Lfkgly8mBtLTPYFsunYNdHU5BfTr148PP/yQhITtQH91zlRwdoUz5h/8a665hnHjxjmkoNL46quv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kJOTw/79+11dTplcvAh/NscUCGfy/l205G2pERtz2kQvL2uoWNzUZtauGfO3GQwZMrgcK7syOCScOX36NBMnTqRGjRoMHDiQW2+9lXvuuYfIyMh8+82fP59evXoxYsQIDMMoYjQRERERERERESkL80PIwYMHl+t58k5rps92yo+z15sBcHd3Jzg4GNDUZvaojJ0zFovF1j1T2aY2W78ecnOhRQto1Cj/tj/++APQlGbFMf/GpKRY24+KC2feeAPS0sDPbz/wK0OGaEoze9kdzmzdupWuXbvy2WefkZmZiWEYRf7LecyYMezdu5fff/+dlStX2ntqEREREREREZEr3oULFzh8+DBAua43A9C6dWssFgsJCQnqrihHruicAa07Y6+LFy/aXrvKFM7AX+vO7N6927WFlFHe9WbySk9PZ8uWLUD5dxRWZs2aNcPNzY3MzLUAbNliDbsuFRcH771nvZ2a+hRQ/l8GuBLYFc5cvHiRG264gfPnzxMcHMz777/Pvn37ity/bt26XHPNNQD8/PPP9pxaRERERERERESAI0eOANYP1mvVqlWu56pWrRrNmjUDNLVZeXJF5wwonLGX2XXSuHFjateu7eJqyqayds4UFc5s3bqVjIwMgoKCaNWqlfMLqyS8vLz+XDdmL97eOVy4AH/+KyUf61oz0KpVAoaxnObNm9OwYUNnl1vl2BXOvPPOO5w5c4Y6deqwefNmHnjgAdq3b1/sMeaUZltLWl1IRERERERERERKZIYzrVu3dsr5tO5M+VPnTOX03XffAdC7d28XV1J2ZufM3r17ycnJcXE1pRMfD3v2WG9f2sSRd0ozrTdTPGsInE2jRmeBglOb5e2a6dDB+h7XlGaOYVc489NPP2GxWHj00UdpdOmkfkUww5sTJ07Yc2oREREREREREcH54UzedWfE8S5cuEB8fDygcKYyuXDhAh9//DEAf//7311cTdm1atWKatWqkZKSYgsHK7o1a6z/7NABgoLyb/v+++8BGHppS40UYHbo1aplnR7z0nDG7Jrp1QvCw/8LKJxxFLvCGbPFsiyLKtWoUQOAxMREe04tIiIiIiIiIiK4rnPm0KFDTjnflcb8YDwoKAh/f3+nnlvhzOX78MMPSUlJoWPHjgwbNszV5ZSZu7s7nTp1Alyz7kxycjJ9+vyLq656p8j1zC9lTml26dO9Z88edu3ahZeXF+PGjXNwpVWPGc5YLP8D8oczcXHw/vvW2489lszu3dZp77TejGPYFc6kpaUB4OfnV+pjkpOTAfDx8bHn1CIiIiIiIiIiAhw+bP22c5s2bZxyPk1rVr5ctd4MKJy5XNnZ2bzzzjsATJs2rdJOo+WqdWeysrIYPnwG//vfdDZs+DsffFD0muZ5FbXejNnBNGbMmEq39o8rmH9rLlz4BYCDB+HiReu2N96A1FTo2RO8vX/HMAxatWpl+1sh9rErnKlbty4Ap0+fLvUxO3bsACAkJMSeU4uIiIiIiIiIXPFycnJsnRbO6pwxQ6AzZ85w7tw5p5zzSuKq9WZA4czl+u677zh9+jT16tXjjjvucHU5l81cd8aZnTOGYfDAAw/wv/+9CfwE+PDII00paWa1yEg4ehTc3CDvpE6ZmZl8/vnnANx7773lVndVYoYzJ09upWlTA8OA//0v/1ozM2bA2rXWeeQ0pZnj2BXO9OrVC4BffvmlVPvn5OQwb948LBYLAwYMsOfUIiIiIiIiIlKO0tLSKs2i0FeykydPkpGRgbe3d6nXA7aXv78/DRs2BDS1WXmoCJ0zcXFxZGVlOf38lZFhGMyZMweAKVOmVOrZgvJ2zpR2ajF7/etf/2LBggW4ucGjj+4EtpGR4c/VV+dSXPZrrjfTvTv8uYoGAMuWLSM+Pp6QkBBGjhxZnqVXGU2aNMHd3Z20tDQ6d7bOlLVlS/6umWuugbVr1wKa0syR7Apnbr/9dgzDYMGCBSW2u+Xm5vLAAw/YWl7vuusue04tIiIiIiIiIuXk7NmzNGjQgHbt2rFnzx5XlyPFMNebadmyJe7u7k47r9adKT+u7JypXbs2np6eAMTGxjr9/JXR5s2b2bp1K97e3jz44IOuLscuHTt2xM3Njbi4OKe8/vPnz2fGjBkAvP/++7zxxks0aTIViODECTfGjoWMjMKPXb3a+s+ipjSbMGECHh4e5VJ3VePp6UnTpk0BaNgwEoBly/J3zSQknLf994DCGcexK5y5+eab6devHxkZGQwbNoz33nuPuLg423aLxcKZM2f49NNP6dGjBwsWLMBisXD11VfrRRQRERERERGpoJYvX8758+c5evQovXv3Zt68eU77FrWUjbPXmzFp3Zny48rOGTc3N9tSBJrarHTefPNNAO68807q1avn4mrs4+vra5sesbzXnfnll1+YPHkyANOnT2fy5MlYLBbuv38McB3u7sls2ACTJsGl//oxjMLXm4mNjbXN8KQpzcrG/Hvj778fgG3brF0zPXpYu2bWrVuHYRi0bduW4OBgV5ZapdgVzgD88MMPtGnThgsXLjB16lRCQkJsi15169aN0NBQ7rnnHvbs2YNhGHTo0ME275+IiIiIiIiIVDyrVq0CrN+iz8jIYPLkydx1110kJye7uDK5lNk546z1Zkxt27YFFM442oULF4iPjwdc0zkDWnemLCIiIvj+++8BmDZtmmuLcRBnrDuzfft2xo0bR05ODhMmTGDmzJm2bRMmTMDN7TA5OWPx8DD44gt44YX8x584AadPg6cn5F0549NPPyUnJ4e+ffs6/W9iZWeGM2lp/6Natb/unzEDLBZNaVZe7A5n6tSpw/bt23nooYfw9vbGMAzbT0ZGhu22h4cH999/P5s2baJG3okARURERERERKTCyM3NtYUzixcv5rXXXsPd3Z0vvviCHj16sG/fPhdXKHm5KpzRtGblw5zSLCgoCH9/f5fUoHCm9N555x1yc3MZMWIEHTt2dHU5DmGGM+XVORMWFsZ1111HSkoKw4cP58MPP7R90R+gfv36jBo1CljNyJHW4Ovll+HP2cqAv7pm+vYFX1/rbcMwbFOaqWum7MxwJizsCD16WO/r0QOuvdZ6e82fi/wMGTLEFeVVWXaHM2BteXvnnXc4ffo0n332GdOmTeOOO+5g/PjxTJkyhQ8//JDw8HA++OAD/Pz8HHFKERERERERESkHe/fuJS4uDj8/P/r168eTTz7J2rVrqV+/PkeOHKF37962D8DE9VzdOXP69GkSExOdeu6qzJXrzZgUzpROYmIiH330EQCPPPKIi6txnC5dugDl0zlz7tw5rrnmGuLi4ujcuTPfffcdXl5eBfabNGnSnzVM5emncwG4//6/1pkpbEqzrVu3cujQIapVq8b48eMdXntVZ4Yzx44d48EHoUkTmDvX2jVz9uxZ2xczBg0a5LoiqyCHropUu3Zt7rjjDu644w5HDisiIiIiIiIiTmJ2zQwePNj2odmAAQPYtWsXd999N7/++iuTJk1i3bp1vPfee/oSpgslJiYSExMDOD+cqVWrFsHBwcTGxnL48GF69erl1PNXVa5cb8ZkhjNRUVEuq6EyWLBgAYmJibRp0+bPTo+qwQxnjh8/TmJiIgEBAQ4ZNyMjgxtvvJGjR4/SsGFDli9fXuTY119/PbVr1yY6OpoBA37lttuu4auv4OabYePGwsMZ80sDN998s8NqvpKYf3NOnDjB+PG53H77Xz0d69atA6B9+/aVfl2lisYhnTMiIiIiIiIiUjWsXLkSgJEjR+a7v27duixfvpx///vfuLm5sWjRInr16qU1R1zI7JoJDg4mMDDQ6efXujOOp84Z51u6dCkbNmwo0zE5OTm8/fbbgHWtGTe3qvMRa506dWjQoAHguKnNcnJyePPNN9myZQs1atRgxYoVtvdZYby9vbnrrrsAWLhwAR9/DP37w8WLMGgQnD1rnc6sd2/r/mlpaXz11VeApjS7XI0aNcLT05OMjAxOnz6db5u53oymNHO8cv/LkZGRwerVq/n666/ZunVreZ9ORERERERERC5TWloa69evBwqGMwBubm48++yz/P7774SEhHDw4EF69uzJd9995+xSBddNaWbSujOOV5E6Z66EcCYiIoKxY8cyaNAgPvnkk1Ift3TpUsLDw6lVqxZ33313OVboGr3/TD02b97skPGeeOIJtmzZgpeXF0uXLrX97SiOGbIsXbqU5OR4fvgBWrSAc+es26+6CswZ0ZYsWcLFixdp0qSJFqy/TB4eHjRr1gz46++QSevNlB+7wpmTJ0/y5JNP8uSTT3LhwoUC27ds2ULz5s0ZOXIkd9xxB3379qVnz56cOnXKntOKiIiIiIiISDlYv349GRkZNGjQoNgP/AcNGsTu3bsZPnw4qampTJo0iezsbCdWKlBxwhl1zjiOOmeca8+ePQDk5uZyzz33MH/+/FId9+abbwLw4IMP4muuSF+F9O/fH4BNmzbZPVZ4eDjvvvsuYJ16bODAgaU6rnPnznTr1o2srCy++OIL6tSB5cuhdm3r9mHD/trXnNJs4sSJVaqLydnyrjtjOnPmjO1vfGlfOyk9u96tS5Ys4Y033uD333+nRo0a+bYlJSUxduxYYmJiMAzD9rNjxw6uu+46h/1H2yuvvILFYmHatGm2+wzDYMaMGYSGhlKtWjUGDx7MgQMH8h2XkZHBww8/TJ06dfDz82PMmDFERkY6pCYRERERERGRyijvlGYWi6XYfevVq8eKFSvw9/cnMTFR3RMucPjwYQDatGnjkvOb4cz+/ftdcv6q5uLFi5w9exZwbThjTmmVkJDA+fPnXVaHM5ifFwYEBGAYBn/72994//33iz1m+/btbNiwAU9PTx566CFnlOl0/fr1A6zhjGEYdo1lTonVpk0bxo0bV6ZjJ02aBMD8+fMxDIOWLa3rzUyfDg8+aN3n1KlTrF69GrCGM3L5CgtnzPVmOnXqRJ06dVxSV1VmVzizatUqLBYLY8eOLbBt3rx5xMXFATB16lSWLl3KlClTAOs3KhYtWmTPqQHYtm0b8+bNo1OnTvnuf/3115kzZw7vvvsu27ZtIzg4mBEjRpCUlGTbZ9q0aSxZsoSvvvqKDRs2kJyczOjRo8nJybG7LhEREREREZHKqKj1Zori7u5O9+7dAesHluJcru6cMT+PiYiIKHRGFSkbs2umXr16Ll3QPDAw0PaeckTnREVmdgQ8/fTTti9+P/TQQ8ydO7fIY8yumdtuu42QkJDyLtElunbtio+PD+fOnePo0aN2jWWGM+3bty/zsbfffjve3t7s3bvXtv5Np07w8stQvbp1n0WLFmEYBkOGDKFp06Z21XqlKyyc0ZRm5cuucCYsLAzA9h9ieX3zzTdYLBZuvPFG5s6dy/XXX8+7777LuHHjMAyDxYsX23NqkpOTufPOO/nwww+pWbOm7X7DMJg7dy7Tp0/npptuokOHDixatIjU1FS++OILwPpNhPnz5zN79myGDx9O165d+eyzz9i3bx+//fabXXWJiIiIiIiIVEYxMTHs27cPi8XCsLzzxZSgR48egPULlOI8ubm5tg/QXBXO1KpVi4YNGwKwd+9el9RQlVSE9WZMAwYMALCtQVVVmZ0z7du3Z86cOTz11FMAPPLII7z++usF9o+MjOSbb76x7VNVeXl50bNnT8D+gM7svOjQoUOZj61VqxY33ngjAAsWLCiwPTc3l4ULFwJ/rVEjl6+4cEZr+ZQPD3sONjtjgoKC8t2fmJjIzp07gYIXxm233ca3335rm9Pxcj300ENcd911DB8+nJdfftl2f3h4OLGxsfm+5ePt7c2gQYPYtGkTkydPZseOHWRlZeXbJzQ0lA4dOrBp0yZGjRpV6DkzMjLIyMjI9zgBsrKyyMrKsuvxiLiS+f7V+1ik4tP1KlK56JoVqTx0vcKKFSsA6zemAwMDS/1cdO3aFYCtW7de0c+fs0VERJCeno6Xlxf169d32XPfqVMnTp8+zc6dO+nbt6/TzlsVr1mzE6pZs2Yuf1x9+/Zl/vz5rF+/3uW1lJecnBzb1ICtWrUiOzubf/3rX3h4ePDvf/+bp556itTUVKZPn2475q233iI7O5tBgwbRoUOHKvvcAPTu3Zv169ezfv167rrrrssa4+TJk//P3n1HR1V2fx/+THogEHrvvYXee+9NUUEQRAQLD4hdsYL+BDtYERBBQURRkU7oNfTQQu81IfQQUkg57x95zwjSksxMZib5XmtlLcicc987yZyUs2fvzcmTJ/H09KRSpUrp+nz179+fWbNmMXPmTMaOHYufn5/1sbVr13Ls2DFy5MhB9+7dM/XXIyOUKlUKSCnIiI2N5cKFCxw8eBCLxULjxo31+U2D1H6ubErOmG3C/tsKbMOGDSQlJeHl5XVHVs18RYUtPStnzZpFaGjoXV+VExERAdyZMCpYsCAnT560HuPj43NbxY15jHn+3YwdO5bRo0ff8f6lS5dmyuFfkvUsW7bM2SGISCrpehVxL7pmRdxHVr5ezfbjpUuXZtGiRak+z7w3sGvXLubOnYu3t7dD4pPbmS+KLVSoEMHBwU6Lw7wfsmDBAqe0FMpM16xZYZCcnJyma9ARzBuLW7duZc6cOfj6+jo1HkcIDw+3Jjj37dtnTY7Vq1ePfv368euvvzJ69Gj27dtH3759iY+P54cffgCgSZMmTv8aOZqPjw+Qco2l92M1qy7Kli2Lv79/uq7XpKQk8uXLx8WLF/nggw+sVV2QkiwDaNiwobV9mqRfcnIy3t7eJCQk8Msvv1hb2pUuXZqNGzc6OTr3EhMTk6rjbErOBAYGcvnyZc6dO3fb+82LoUaNGmTPnv2u596a5UyL06dPM2LECJYuXXrfNf47uNAwjAcOM3zQMSNHjuTll1+2/j8qKorixYvTvn17p/YCFbFVQkICy5Yto127dvpDSsTF6XoVcS+6ZkXcR1a/Xg3D4NlnnwXg2WefTVP7EsMweOutt7h8+TLFihW7a+tzsb+jR48CULt2bTp37uy0OOLi4pg9ezZXrlzJ0Dgy4zX7ySefANC5c2enfk0h5boePXo0ERER5MuXj2bNmjk1HkeYP38+AFWqVKFbt263Pda5c2eCgoJ48803mT17NsWLF6dUqVJER0dTrlw53nvvPTw8bJoW4fLq16/PmDFjOHPmDA0bNiRPnjxpXuOff/4BoEuXLgDpvl63b9/OmDFj2LVrF2PGjAFSXhjQt29fAN55550MrdzLzMqXL8++ffsoVqyYtTCiW7duTv+e5G7MjlsPYlNyplq1aqxdu5Y5c+bQo0cPICWbac6budugoLNnzwJ3Vrak1vbt24mMjLztl72kpCTWrl3Lt99+a81yR0RE3DaUKzIy0rpnoUKFuHnzJleuXLmteiYyMpLGjRvfc29fX9+7vlLA29s70/wiIFmbnssi7kPXq4h70TUr4j6y6vW6e/duzp8/T7Zs2WjevHmaPwd169Zl6dKl7Ny5k4YNGzooSrmVOTy+cuXKTn3OmjOHzNkdGR1LZrpmza9ppUqVXOJjatasGbNnz2bTpk20bt3a2eHYnXkPsWrVqnf9fL/xxhv4+/szYsQIvvzyS+s9wREjRmTKSqL/Kly4MBUrVuTgwYNs27bNmmBJC3NmUcuWLTEMI93X69NPP82YMWNYvnw54eHhlChRgn/++YeYmBgqVqxIs2bNHviifEmdChUqsG/fPo4fP26t5mvTpo1LfE9yJ6n9fNmU4n3ooYcwDIPp06fzxhtvsGDBAvr27WttH/bYY4/dcc62bdsAKFGiRLr2bNOmDXv27GHnzp3Wt7p169KvXz927txJmTJlKFSo0G1lcjdv3mTNmjXWxEudOnXw9va+7Zjw8HDCwsLum5wRERERERERyYyWLl0KpNxAS89NR3Nw9N3aj4tjmDeWK1as6NQ4SpcuTUBAAPHx8daYJO2uXbvGhQsXAChXrpyTo0lhto9av369kyNxjH379gEpyZl7eeGFF5gwYQKQMos6V65cDBw4MCPCcwnmfdKQkJA0n3vmzBmOHj2Kh4cHTZo0sSmOMmXKWBM8v/zyCwBTp04FYODAgUrM2FH58uWBlM5YR44cwcPDI1NWzrkKm5Izzz77LJUrV8YwDD7//HN69OjBn3/+CaSUO5mvnrjVnDlzsFgsaSqRvlWOHDmoVq3abW/Zs2cnb968VKtWDYvFwosvvsiYMWOYM2cOYWFhDBw4kGzZsllL3QIDA3n66ad55ZVXWLFiBTt27OCJJ54gKCiItm3bpvvzISIiIiIiIuKOzBcvtmvXLl3nm3//my/IFMczB5k7Oznj4eFBjRo1gJS5Q5I+ZtVMgQIFXKZ1vpmcMWdLZzZmcqZKlSr3Pe65557jp59+Inv27Lz11lsEBARkRHguwUzObNiwIc3nmlUXtWvXtstzetCgQUBKUubQoUOsX78eDw8PBgwYYPPa8i8zOTN37lwAatWqRa5cuZwYUeZmU3LG19eXFStW8PDDD+Pl5WUtT+vfvz/Tp0+/4/i1a9dav/Gl9xe+1Hj99dd58cUXGTp0KHXr1uXs2bMsXbqUHDlyWI8ZN24cPXv25LHHHqNJkyZky5aN+fPn4+np6bC4RERERERERFxNbGwsa9euBaB9+/bpWsOsnNm7d2+qh+BK+l2/ft06/9fZyRmAmjVrArBz506nxuHOzOSMeWPUFVSvXp0cOXIQFRVFWFiYs8Oxq+TkZPbv3w88ODkD8NRTTxEVFcVrr73m6NBcilnxsmXLFhISEtJ0rpmcadGihV1i6dWrFzly5ODYsWMMGTIEgA4dOlCkSBG7rC8pzO9BiYmJAHcdWyL2Y/PkqkKFCvHnn38SFRXF2bNniYqK4ueff74tEWIqXrw4q1atYuXKldZf3Oxh9erVjB8/3vp/i8XCqFGjCA8PJy4ujjVr1lCtWrXbzvHz8+Obb77h0qVLxMTEMH/+fIoXL263mERERERERETcwfr164mLi6No0aJUrlw5XWsULVqUwoULk5SUxI4dO+wcofzXoUOHgJQqi1tn6TqLWTmj5Ez6HT58GHCdlmYAXl5e1iHrma212YkTJ4iNjcXX15cyZcqk6hwPD5tvo7qdihUrkjt3bmJjY9NcGWfv5Ey2bNl4/PHHAawvKHjqqafssrb8678JYiVnHMtu31V8fX0pXLgwPj4+9zymdOnStGjRghYtWqgXoIiIiIiIiIgLuLWlmS1/q6u1WcZxlXkzJrNyZteuXRiG4dxg3JQrVs4A1lkT5mD3zGLv3r0AVKpUSV107sPDwyNdrc3Cw8M5dOgQFovFrvNKbk3G5MmTh+7du9ttbUlRpEgRsmXLBoCnp6e1vaE4RtZL+YqIiIiIiIiI1dKlS4H0tzQzmR0ytm7danNMcn+ulpypVq0aHh4eXLhwgfDwcGeH45ZcsXIG/p07s27dukyVeDPHLlStWtXJkbg+MzkTEhKS6nPMqpkaNWrYdV5JgwYNrBWeffv2xdfX125rSwqLxWL9PlSnTh2XmYGVWdmcnImJiblvP9lvvvmGZs2aUblyZTp37syCBQts3VJERERERERE7OD8+fPWVjVt27a1aS1VzmScAwcOACmv+ncF/v7+1kSRWpulj6tWztSvXx9vb2/OnTvHyZMnnR2O3ZiVM6mZN5PV3Vo5k9oEnb1bmpksFgvfffcdvXr1YuTIkXZdW/5lfj9XSzPHsyk5M3/+fHLkyEGRIkW4fv36HY8PGjSIF198kZCQEA4ePEhwcDA9evTg008/tWVbEREREREREbGD5cuXA1CrVi3y589v01pmcubgwYNcu3bN5tjk3lytcgZub20maRMVFUVkZCTgepUz2bJlo06dOkDmam2mypnUq1+/Pp6enpw9e5bTp0+n6hwzOdOyZUu7x9OqVSv+/PNPihQpYve1JcU777zDkCFDeOWVV5wdSqZnU3ImODgYwzDo2bMnOXLkuO2x9evXM23aNCDlG3mtWrXw8/PDMAzeeecda4ZaRERERERERJzDXi3NAPLnz0/JkiUBCA0NtXk9ubvk5GQOHToEuGZyRpUzaWdWzRQoUMAlWwiZrc3Wr1/v5EjsIzk5mf379wOqnEkN874upK61WWRkpPXza895M5JxqlevzqRJk2x+0YY8mE3JmU2bNmGxWO5a4jRp0iQgZYjQ/v372b59OwcOHKB48eIkJSUxceJEW7YWERERERERERsYhsGyZcsAaNeunV3W1NwZxztz5gyxsbF4e3tTunRpZ4djVaNGDUDJmfRw1XkzpsyWnDl58iQxMTH4+vpSpkwZZ4fjFpo0aQKktDZ7kLVr1wIQFBRE3rx5HRqXiLuzKTljllzerR/mkiVLsFgsDB8+nGLFigFQvHhxhg8fjmEY1vI2EREREREREcl4e/fuJTw8HH9/f+uNN1uZyRnNnXEcc95MuXLl8PLycnI0/zIrZw4fPsyNGzecG4ybcdV5Mybz+8O+ffu4dOmSk6OxndnNp2LFii51Dbkyc+5MaipnHDVvRiQzsik5c+HCBQACAgJue/++ffu4ePEiAN27d7/tMbMH7YkTJ2zZWkRERERERERsYLY0a9GiBX5+fnZZ0/ybX5UzjuOK82YAChYsSKFChTAMgz179jg7HLfi6pUz+fLlo3LlykDqKidcnTlvRi3NUs9MzuzatYvo6Oj7Hrt69WpAyRmR1LApOePp6QnA5cuXb3u/OSAsf/78VKpU6bbHcufODUBcXJwtW4uIiIiIiIiIDczkjL1amgHWweEnTpywvqBT7MtVkzPwb2uzXbt2OTkS9+LqlTPwb2sz856fOzOTM1WrVnVyJO6jWLFilChRgqSkJLZs2XLP4y5evEhYWBgAzZs3z6jwRNyWTcmZokWLAnf2E124cCEWi+WuQ5+uXbsGpGTdRURERERERCTjxcXFWecCtG/f3m7rBgYGUqFCBQC2b99ut3XlX66cnDFbm2nuTNq4euUM/DvYPTPMnTHbmqlyJm1S09rMTN5VqVKFAgUKZEhcIu7MpuRMs2bNMAyDb7/91trGbOvWrSxZsgSADh063HHO/v37AShUqJAtW4uIiIiIiIhIOm3YsIHY2FgKFy5s91ePm3Nn1NrMMcyZM//tVOIKlJxJu6ioKOtMZ1dOzpiVM9u3bycmJsbJ0aRfcnKy9d6kKmfSxpw9dL/Wdpo3I5I2NiVnhg4dioeHB8ePH6dMmTLUrVuXFi1akJiYSO7cuendu/cd56xcuRKLxWL9gS0iIiIiIiIiGevWlmYWi8Wua5tzZ7Zt22bXdQVu3LjBmTNnANesnDHbmu3Zs4ekpCQnR+MezJZm+fPnJzAw0MnR3FupUqUoUqQICQkJ921r5epOnTrFjRs38PHxoWzZss4Ox62YlTMbN24kOTn5rscoOSOSNjYlZ2rXrs1nn32GxWIhOjqa0NBQ4uLi8Pb2ZvLkyeTIkeO2469du8bChQsB+/a0FREREREREZHUW7ZsGWDflmYmVc44zqFDh4CUVvF58uRxcjR3qlChAv7+/ty4cYOjR486Oxy34A7zZoDbxhe4c2szc95MxYoV8fLycnI07qV69epkz56da9euWT+Pt7py5Yp13pSSMyKpY1NyBuCll15ix44dvPvuuwwZMoT33nuP3bt389BDD91x7OrVq6lXrx7Nmzenbdu2tm4tIiIiIiIiImkUGRnJjh07ABzyt3nNmjXx8PAgPDycc+fO2X39rMyV580AeHp6EhQUBKi1WWq5w7wZk9nazJ2TM5o3k35eXl40aNAAuPvcmXXr1mEYBhUqVNA4C5FUsjk5AxAUFMTo0aOZOHEio0aNuucvCT169GDVqlWsWrWKfPny2WNrEREREREREUmD5cuXAyktqAoWLGj39bNnz26d5aDqGfty5XkzJrO1mfkKerk/d6mcgX+TMyEhIW7bts6s+NC8mfQxW5vdLTljtjRr2bJlRoYk4tbskpwREREREREREffgyJZmJrU2cwxXr5wBrDOGVTmTOu5UORMUFETOnDm5fv06u3fvdnY46aLKGds0adIEgA0bNtzxmObNiKSdkjMiIiIiIiIiWYRhGCxduhRwbHKmbt26AGzbts1he2RFSs5kPu5UOePp6WmtnHDH1maGYVgrZ5ScSZ+GDRsCKc/byMhI6/uvXbtmbZep5IxI6tl98tWJEye4ePEisbGxGIZx32ObN29u7+1FRERERERE5B4OHDjAuXPn8PPzs7YocoRbK2cMw8BisThsr6wiOTnZLZIz5syZc+fOceHCBfLnz+/kiFxXVFQU58+fB9yjcgZSWpstWbKEdevWMXz4cGeHkyanT5/mxo0beHt7u83n29XkypWLqlWrsnfvXkJCQujZsyeQkqxLTk6mbNmyFC1a1LlBirgRuyRnDh48yJgxY5g3bx5RUVGpOsdisZCYmGiP7UVEREREREQkFbZv3w5AnTp18PPzc9g+QUFBeHt7c/nyZU6cOEHp0qUdtldWcfbsWWJiYvDy8qJMmTLODueecuTIQbly5Thy5Ai7du2ibdu2zg7JZR09ehSA/PnzExgY6ORoUqdZs2ZAys14d0u8mi3NKlSogLe3t5OjcV9NmjS5IzmjlmYi6WNzW7N//vmH2rVrM2PGDK5du4ZhGKl+ExEREREREZGMYw5pN4e2O4qvr691D82dsQ+zaqZs2bIuf2NZrc1Sx53mzZjq1auHt7c34eHhHD9+3NnhpInZ0qxq1apOjsS9ma3tQkJCrO9TckYkfWxKzpw+fZonnniC2NhYihQpwvjx45k0aRKQUhmzYsUK/vzzT958802KFCkCpJQ/Ll++nJUrV9oevYiIiIiIiIikWkYlZ0BzZ+zNHVqamcznl/l8k7tzp3kzJn9/f+u1vW7dOidHkzZm5YzmzdimSZMmQMr39vj4eK5fv26tylRyRiRtbErOfP3118TExJAjRw42b97MCy+8QKNGjayPt2rViocffpgxY8Zw+PBh+vTpw4YNG5gyZYouVhEREREREZEMlpHJmVvnzojt3Ck5o8qZ1HHHyhm4vbWZO1HljH2ULVuW/PnzEx8fT2hoKCEhISQlJVGqVClKlizp7PBE3IpNyZnly5djsVgYOnSotTLmXvz9/ZkxYwa1atVi1qxZ/PXXX7ZsLSIiIiIiIiJpEBERQWRkJBaLhWrVqjl8P/PV9du3byc5Odnh+2V27picOXDgAHFxcc4NxoW5Y+UMpHTFAfeqnDEMw5qcUeWMbSwWi7W12YYNG9TSTMQGNiVnTpw4AfzbaxC4bRBYYmLi7Zt5ePDCCy9gGAY//fSTLVuLiIiIiIiISBqYVTPly5cne/bsDt+vSpUq+Pv7c/36dQ4dOuTw/TK7AwcOAFCpUiUnR/JgRYsWJU+ePCQmJlpviMud3LVyxrwPePDgQS5cuODkaFLnzJkzXL9+HS8vL7dLhrkis7VZSEgIq1evBpScEUkPm5IzN27cAKB48eLW92XLls3672vXrt1xjlk6qL6jIiIiIiIiIhknI1uaAXh5eVG7dm1Arc1sFRMTw6lTpwD3qJyxWCxqbfYA169f5/z584D7JWfy5s1rvb+3YcMGJ0eTOua8mQoVKuDt7e3kaNyfmaBbu3at9fu7kjMiaWdTciYwMBDgthLVvHnzWv999OjRO86JiooC4OLFi7ZsLSIiIiIiIiJpsHv3biDjkjPwb2uzbdu2ZdiemZFZYZEnTx7y5cvn5GhSx0zO6MW5d2e2NMuXLx+5cuVybjDp4G6tzdTSzL7q1KmDj48Ply5dIjExkeLFi1O6dGlnhyXidmxKzpiv1jh27Jj1fTly5LAOf1q6dOkd5yxfvhzALX/wiIiIiIiIyO1Wr17N448/zunTp50dijxARlfOANSrVw9Q5Yyt3GnejMl8nqly5u7cdd6MqVmzZgCsX7/eyZGkjpmcMSt+xDZ+fn7UqVPH+v8WLVrcNupCRFLHpuRMo0aNANi0adNt7+/atSuGYfDZZ5+xcuVK6/v//PNPxo8fj8VisfYmFBEREREREff1/vvvM2vWLJ5++mkMw3B2OHIP8fHx1pklzqic2bFjxx1zaSX13GnejOnWyhl9b7iTmXBzt5ZmJrNyJjQ01Dr2wJWZbc1UOWM/t84gV0szkfSxKTnTuXNnDMPg77//Jikpyfr+1157jWzZshEdHU27du3Inz8/OXPmpHfv3sTGxuLh4cFrr71mc/AiIiIiIiLiPImJidZ2VcuWLeO3335zckRyL/v27SMxMZHcuXNTrFixDNu3fPny5MyZk7i4OOvNUUk7d6ycqVSpEj4+Ply7do2TJ086OxybXbhwgebNm/P111/bvNb58+et65hzmdxNiRIlKFasGImJiWzevNnZ4dyXYRiqnHGAW194r+SMSPrYlJxp2bIl77//Pk899RRnz561vr9EiRLMnj2bwMBADMPg0qVLREdHYxgGvr6+TJ48mYYNG9ocvIiIiIiIiDhPWFgYMTEx1v+/9NJLXL582YkRyb3c2tIsI1vPeHh4WFvfaO5M+rljcsbHx8dapZAZWpv99ttvrFu3jhEjRty1jX9qGYbBoEGDuHDhAkFBQTz33HN2jDLjWCwWt2ltdvbsWaKiovDy8nLbNnKuqEWLFuTLl4/atWu7bQWYiLPZlJyxWCy8//77fPjhh5QoUeK2xzp16sSRI0eYMGECw4YN47nnnuOLL77gyJEjDBw40JZtRURERERExAWYLa6bN29OlSpViIyM5M0333RyVHI3zpg3Y9LcGdsYhuGWyRn4t7VZZkjOrF271vrvAQMGcP78+XSt8/3337No0SJ8fX359ddf8fPzs1eIGc5sbZbRyZnw8HCqVavGsGHDUnW8WTVTvnx5fHx8HBlalpInTx4OHTrEmjVrNG9GJJ28HLl4njx5ePbZZx25hYiIiIiIiDiJ2cqmWbNmdOzYkWbNmjF58mQGDBhgvWknrsGZyRlz7oySM+lz7tw5oqOj8fT0pGzZss4OJ01unTvjzgzDsCZn8ubNy/nz5xkwYACLFy/GwyP1r3vet28fr776KgCffPIJQUFBDok3o5jf50NCQkhMTMTLy6G3Ga0+//xz9u7dy969e3niiSce2J1H82YcJ3fu3M4OQcStpbly5vz587z++usEBQWRM2dOsmfPTvny5XnmmWfYv3+/I2IUERERERERF2RWzjRs2JCmTZsyePBgAJ577jlu3rzpzNDkFoZhuETlzJ49e4iLi8vw/d2dWTVTpkwZt3vVv/l8c/fKmUOHDnHhwgV8fX1ZtmwZ/v7+LF26lM8//zzVa8THx9OvXz/i4uJo3749w4cPd2DEGaNatWrkzJmTGzduWKtTHO3KlStMmjTJ+v8333wTwzDue44Zm5IzIuJq0pSc2bRpE1WrVuWLL75g3759REdHExsby7Fjx5gyZQo1a9Zk5syZjopVREREREREXMTVq1c5cOAAAA0aNABSXgmeP39+9u7dyxdffOHM8OQWZ8+e5fLly3h6ejrl5mTJkiXJly8fCQkJ7N69O8P3z2iGYXD69OkH3jBOLXdtaQb/JmdOnDjB1atXnRuMDcyqmYYNG1KrVi2++uorAN5++21rBeGDvPvuu+zcuZO8efMybdq0NFXcuKpbZ0pt2bIlQ/b84YcfiI6Oply5cvj6+rJmzRqCg4Pve45ZOVO1atWMCFFEJNVS/ZMgKiqKRx55hMuXL2MYBoZhkDdvXgoWLAik/PKRkJDA008/rQoaERERERGRTM5sUVW6dGny588PpLS2HjduHAAffPABR48edVp88i+zaqZixYpOmW9hsVisrc22bduW4ftntOnTp1OiRAk6dOjAxYsXbV7PnZMzuXPnpmTJkgBunZgzkzPNmzcHYPDgwTz22GMkJibSp0+fByaeVq1aZa2y+fHHHylcuLBD481I9evXBzImORMXF2dNjL3//vv873//A2DkyJEkJyff9RzDMFQ5IyIuK9XJmZ9++olz585hsVjo2bMnR44c4cKFC4SHhxMeHm4tx7x586ZeISUiIiIiIpLJ3drS7FZ9+/albdu2xMXFMXToULtVD0j6ObOlmclsbZYV5s6Yr+JftmwZderUseljDg4O5vfffwfcMzkDmaO12bp164B/kzMWi4VJkyZRqlQpTpw4wTPPPHPP73VXrlxhwIABGIbB4MGD6dmzZ0aFnSHM5ExGXNvTp0/n/PnzFC9enN69ezNy5Ehy5szJzp07rdfJf4WHh3Pt2jU8PT2pUKGCw2MUEUmLVCdnFi1aBKT84v3XX39RpkwZ62MFChTgq6++4qmnnsIwDOuxIiIiIiIikjmZrXzMlmYmi8XC999/j6+vL0uXLmXWrFnOCE9u4QrJGfMGbmpbQLmzHTt2AJAzZ05OnTpF06ZNmTRpUpoSlVeuXGHQoEF07NiRiIgIypUrxyOPPOKokB2qZs2awL/PQ3dz8uRJTp48iaen523J6MDAQGbNmoWXlxezZ8/mxx9/vONcwzB47rnnOHPmDOXLl7dWFmYmt86UiomJcdg+SUlJfPbZZwC8/PLLeHt7ky9fPl577TUA3nnnnbvOOjNbmplt0EREXEmqkzNhYWFYLBb+97//YbFY7nrMiBEjADh//jyXLl2yT4QiIiIiIiLiUgzDuGflDED58uV55513AHjxxRe5cuVKhsYnt3OF5IyZxNu/f79bzx55kBs3blhnMW3ZsoUePXpw8+ZNnn32WZ5++mliY2MfuMb8+fOpWrUqU6dOxWKxMGLECHbu3Enu3LkdHb5DmMkZd62cMatm6tSpQ0BAwG2PNWjQgI8++ghIuSdmJgJM06dP548//sDLy4tff/31jvMzg2LFilGoUCGSkpIc+jWeO3cuhw8fJnfu3AwePNj6/hdffJECBQpY52H/l9nSTPNmRMQVpTo5c/nyZQAqVap0z2MqV65s/bd++RYREREREcmcjh07xqVLl/Dx8bHeeP2v1157jcqVKxMZGcnIkSMzNkCxiomJ4fDhw4BzkzP58+e3duDIzK3Ndu/ejWEYFC5cmIoVK/L3338zduxYPDw8mDp1Kk2aNOHYsWN3PffSpUs88cQTdO/enfDwcCpUqMC6desYP3482bNnz+CPxH7M511YWBgJCQlOjibt/jtv5r9effVV2rdvT2xsLL1797Ym4I4fP86wYcMAGDVqlLXCJLOxWCwOnztjGAaffPIJAEOHDr0tyRUQEMC7774LpMw6u3Hjxm3nmgkzzZsREVeU6uSMWRp4v+GB3t7edxwvIiIiIiIimYtZNVOrVq17tonx9fXlhx9+AGDixImEhIRkWHzyr7CwMJKTk8mfPz+FChVyaixm9Uxmbm1mtjSrVasWAB4eHrz55pssXbqUfPnysWPHDurUqXNHO/i///6bqlWr8uuvv+Lh4cGrr77Kzp07adKkSYZ/DPZWqlQpcubMyc2bNzl48KCzw0kzs3KmWbNmd33cw8ODX375hYIFC7J3715eeuklEhMTeeKJJ7h+/TpNmzblzTffzMiQM5yZeHJUcmbdunVs2bIFX19fXnjhhTsef+aZZyhdujQRERF89dVXtz2myhkRcWWpTs6IiIiIiIiIwL3nzfxX8+bNGTRoEADPPvusW75q3t3d2tLsXi3KM4r5fDGTe5lRaGgo8G9yxtSmTRtCQ0OpX78+V69epUuXLrz//vucP3+e3r1706tXL86fP0+VKlUICQnhs88+w9/f3xkfgt15eHhYq2fcrbVZZGSktU1d06ZN73lcwYIFmTFjBhaLhYkTJ9K1a1dCQkLImTMn06dPx9PTM6NCdgqzcsZRVXGffvopAE899RQFChS443EfHx8+/PBDAD755BPrqAXDMFQ5IyIuTckZERERERERSRMzOXO3eTP/9emnn5IvXz7CwsL44osvHB2a/IcrzJsxmc+XzZs3YxiGk6NxDLNypnbt2nc8Vrx4cdauXcvzzz8PpLRgKlasGH/88Qeenp689dZbhIaGPjDp6Y7cNTljVs0EBQWRJ0+e+x7btm1ba4VMcHAwAN999x2lSpVyaIyuoG7dugAcOXLEOhbBXsLCwli4cCEWi4VXXnnlnsc9/vjjVK9enaioKD7++GMAIiIiuHr1Kh4eHlSoUMGucYmI2INXWk945513yJUrl83HWSyWuw7qEhEREREREdcVFxdnvQGdmpvIefPm5YsvvuDJJ59k9OjRPPbYY9bZI+J4rpScqVmzJj4+Ply8eJFjx45RtmxZZ4dkVzdv3mTPnj3AnZUzJl9fX77//nsaNWrEs88+S2xsLEFBQUydOpU6depkZLgZypxNZT4f3cWD5s381+jRo1m1ahWbNm2iT58+9OvXz5HhuYw8efJQrlw5jhw5wtatW+nQoYPd1v78888B6NWrF+XKlbvncR4eHowdO5YuXbrwzTffMGLECGvVU7ly5e47pkFExFnSnJyZO3fufR83y6QfdByg5IyIiIiIiIib2blzJwkJCeTLl4/SpUun6pz+/fszdepUVq9ezaRJk6yvahbHMgyD3bt3A66RnPH19aVWrVps3ryZzZs3Z7rkzL59+0hISCBXrlwPrJbo378/9evXZ9u2bTz66KP4+PhkTJBOYiartm3bRlJSktu0+XrQvJn/8vb2ZuHChcydO5c+ffo4vZVgRqpfv77dkzNnzpzh119/BeD1119/4PGdOnWiWbNmrFu3jtGjRxMUFASopZmIuK40tTUzDMNubyIiIiIiIuJ+zHkhDRs2TPWNR4vFwuDBgwFYuHChw2KT2508eZKoqCi8vb2pVKmSs8MBMvfcGbOirFatWqm6NipWrEi/fv0yfWIGoHr16gQEBHD16lXCwsKcHU6qXLt2zdqGLbXJGUipInnqqacyzcyg1DLnzmzZssVua44bN47ExERatmxJvXr1Hni8xWKxJv9/+ukn5syZA0DVqlXtFpOIiD2lunLm+PHjjoxDRERERERE3IA5byatczE6duyIh4cHYWFhnDp1ihIlSjgiPLmF2UKqSpUqLpMAaNiwIV9//bX1eZSZhIaGAvduaZaVeXl50aRJE4KDg1mzZo1LVHI9yIYNGzAMg3LlylGkSBFnh+PyzOTJli1bMAzD5qqhK1euMGnSJCB1VTOmxo0b0717d+bNm8fq1asBVc6IiOtKdXKmZMmSjoxDRERERERE3MCtlTNpkTdvXho1asSGDRtYuHChdSi6OI4rzZsxmUm9nTt3Eh8fj6+vr5Mjsh+zcqZ27dpOjsQ1tWjRguDgYNauXcsLL7zg7HAeKK3zZrK6WrVq4enpyfnz5zlz5gzFixe3ab0ffviB6OhoqlWrRseOHdN07kcffcT8+fOtnXtUOSMiripNbc1EREREREQk64qMjOTEiRNYLJZUtZj5ry5dugBqbZZRXDE5U7p0afLnz8/NmzetyYzMICkpydoCS5Uzd9eiRQsgJenhDu3u0zpvJqvz9/e3znixtbVZXFwcX331FZBSNZPWKpxq1arRv39/ADw8PKhYsaJN8YiIOIqSMyIiIiIiIpIqZiuqypUrExgYmObzzeTMypUriY2NtWtscidXTM5YLBZr9Uxmam125MgRbty4gb+/v24E30PdunXx9/fnwoUL7N+/39nh3FdMTAxbt24FVDmTFubcGfNzl17Tp0/n/PnzFC9enD59+qRrjQ8++IACBQrQrl07/Pz8bIpHRMRRlJwRERERERGRVDFbmqV13owpKCiIYsWKERsby6pVq+wZmvzH9evXOXr0KOBayRn49/ljPp8yA7MKqEaNGnh6ejo5Gtfk4+NDo0aNgH9bhjlKXFwcv//+O506dcLb25tPP/00Tedv3ryZhIQEihYtSunSpR0UZeZjJmdsqZxJSkri888/B+Cll17C29s7XeuULFmSEydOsHjx4nTHIiLiaErOiIiIiIiISKqYlQ7pTc5YLBa1Nssge/bsAaBIkSLky5fPydHczpxXlJkqZ0JDQwG1NHsQswplzZo1dl/bMAy2bt3K0KFDKVy4MH369GHJkiUkJiYyZswYrl+/nuq1zJZmzZs3t3mwfVZitrvctm0bycnJ6Vpj3rx5HDp0iFy5cjF48GCb4vH399fXT0RcmpIzIiIiIiIi8kBJSUnWV0ObN9fTw0zOLFiwwC3mTrgrV2xpZqpXrx4Wi4Xjx48TGRnp7HDswqycqV27tpMjcW2OmDsTERHB559/TlBQEPXr12fChAlcvXqVYsWK8fbbb1OuXDmuXbvGzz//nOo1zcoezZtJmypVqpAtWzauX7/OwYMH03y+YRh88sknAPzvf/8jR44c9g5RRMSlKDkjIiIiIiIiD3TgwAGuX79OtmzZqFq1arrXad26Nb6+vpw6dYq9e/faMUK5lSsnZwIDA6lcuTKQOapnDMNQ5UwqNWjQAB8fH86dO2dtu5de8+fP5//+7/8oXbo0r732Gnv37sXPz4++ffuydOlSTpw4wf/93//x4osvAvD111+nqprj5s2bhISEAJo3k1ZeXl7UqVMHSF9rs5CQEDZv3oyvry/Dhw+3d3giIi5HyRkRERERERF5IHM+SL169fDy8kr3OtmzZ6d169aAWps5kisnZ+Df1niZITlz+vRpLl++jJeXF9WqVXN2OC7N39/fOpfEltZmP//8M7169WLbtm0kJSXRqFEjJk6cSEREBL/++ivt2rWzzv558sknCQwM5PDhw6maPxIaGkpsbCx58+a1JhEl9czWZulJzkyaNAmAvn37UrBgQbvGJSLiipScERERERERkQeydd7MrTR3xrGSk5OtM2eqV6/u5GjuzmyNZyb93JnZ0qxq1ar4+vo6ORrXd2trs/Qyb+I3b96c3bt3ExISwjPPPENgYOAdxwYEBFhnl3z11VcPXNucN9OsWTM8PHTbLK3M5NvWrVvTdN7Vq1eZPXs2AEOGDLF7XCIirkg/ZUREREREROSBzOSMLfNmTGZyJiQkhCtXrti8ntzu6NGj3LhxA19fXypUqODscO7KTPJt2bKFpKQkJ0djG7U0SxuzVVh6K2dOnTpFSEgIFouFgQMHUqlSpQeeM2zYMDw8PFi2bNkD2ylq3oxtzOTMzp07iY+PT/V5M2fOJDY2lqpVq9rl54yIiDtQckZERERERETuKzo6mrCwMMA+lTOlSpWiSpUqJCUlERwcbPN6cjuzpVm1atVsakHnSFWrVrUODj9w4ICzw7GJWTlTu3ZtJ0fiHho3boynpycnT57k5MmTaT7/jz/+AFKSPHny5EnVOaVKlaJnz55AyuyZe0lKSrJWzmjeTPqUKlWKvHnzkpCQYP1e9CCGYTB58mQABg8ejMVicWSIIiIuw6bkTGYoPxYREREREZH727ZtG8nJyRQvXpwiRYrYZU21NnMcV583AymDw83ZFO4+d0aVM2kTEBBgHRqfntZms2bNAuCxxx5L03kjRowA4JdffuHSpUt3PSYsLIxr164REBBAzZo10xybgMViSXNrs9DQUHbu3ImPjw/9+/d3ZHgiIi7FpuRM48aNqVq1Kl988QWRkZH2iklERERERERciPnCPHtUzZjM5MzixYvdvq2Vq3GH5Az8+3xy5xd+XrhwgbNnz2KxWFz+8+1KzLkzaW1tduTIEbZv346npycPPfRQms5t1qwZtWrVIi4uzlql8V9m1Uzjxo1dturMHZjJmS1btqTqePPr0atXL/LmzeuwuEREXI3Nbc0OHDjA66+/TvHixXn44YeZP38+ycnJ9ohNREREREREXIBZ2WDP5Ezjxo0JDAzk0qVLqb6BJ6njLskZc66EO1fOmC3NypcvT44cOZwcjfswkzNprZz5/fffAWjbti358uVL07kWi8VaPfPtt9+SkJBwxzFmPGppZhuzKi4139tv3LjBzJkzgZSWZiIiWYlNyZmvvvqKmjVrYhgGCQkJzJ07l549e1KsWDFGjhzJoUOH7BWniIiIiIiIOIFhGNbKBnsOafb29qZDhw6AWpvZ05UrVzh16hQA1atXd3I092cm+8LCwoiOjnZyNOmjlmbp06RJEywWC4cPHyY8PDzV55ktzXr37p2uffv06UOBAgU4e/Ysf//9922PGYah5IydmMmZgwcPcu3atfse+8cff3D9+nXKli1Ly5YtMyA6ERHXYVNyZvjw4Wzfvp2dO3cyfPhw8ubNi2EYRERE8Omnn1K5cmWaNm3K1KlTuXHjhr1iFhERERERkQxy+vRpIiIi8PT0tPvAc7O12YIFC+y6bla2Z88eAEqUKEHu3LmdHM39FSlShOLFi5OcnMy2bducHU66mJUzSs6kTa5cuawzXVJbPbN3717CwsLw9vZOc0szk6+vL0OHDgVg/Pjxtz12+PBhzp8/j6+vrzW5IOlToEABSpUqhWEYbN++/b7Hmi3Nnn76aTw8bG7wIyLiVuzyXa969ep89dVXnD17lj///JMuXbrg4eGBYRhs3LiRwYMHU7hwYQYPHsyGDRvssaWIiIiIiIhkALPlVI0aNciWLZtd1+7UqRMWi4Vdu3Zx5swZu66dVblLSzOTWT3jrq3NzMoZeycuswKzOiW1c2fMlmadOnUiV65c6d73ueeew8fHh02bNt32vDPnzdSvXx8/P790ry8pzATX1q1b73nM3r172bhxI56engwcODCDIhMRcR12TUl7e3tb586cPn2asWPHUrFiRQzDIDo6mqlTp9K8eXMqV67MZ599xvnz5+25vYiIiIiIiNiZ2dLMnvNmTPnz57euu2jRIruvnxW5W3LGbJVnPs/cSVRUFEeOHAFUOZMe5tyZ1CRnDMOwuaWZqWDBgjz++ONASrt+k1qa2Vf9+vWB+8+d+fHHHwHo1q0bhQsXzpC4RERcicPqBQsVKsQbb7zBvn372LBhA4MHDyYgIADDMDh48CBvvvkmxYsXp2fPnixZssRRYYiIiIiIiIgNzFeW23PezK3M1maaO2Mf7pacMZNzmzZtwjAMJ0eTNubnunjx4mkeTi/QrFkzAPbt28eFCxfue+zOnTs5fPgw/v7+dO/e3ea9R4wYAcDs2bM5e/YsoOSMvZmVM/dKzsTHx/PLL78AMHjw4AyLS0TElWRIM8ebN28SHx9PUlISFosFSHnVQ2JiIvPnz6dLly7UqlXLLV8pIyIiIiIiklklJCRY5wU4onIG/k3OLF++nLi4OIfskVUkJiYSFhYGuE9ypnbt2nh6ehIREcHp06edHU6amC3NVDWTPvny5aNq1arAvy3F7sWsmunSpQsBAQE2712rVi2aN29OYmIi33//PadPn+bEiRN4enrSqFEjm9cXqFOnDh4eHpw5c4bw8PA7Hp8zZw6XL1+maNGidOzY0QkRiog4n8OSM6dOneLDDz+kbNmytG7dmhkzZhATE4OHhwddu3bl999/55133qFYsWIYhsGuXbto2bKl2/aZFRERERERyWx2795NXFwcuXLlonz58g7Zo2bNmhQpUoSYmJhUz56Quzt8+DBxcXFkz56dsmXLOjucVMmWLZs1keRu9wN27NgBKDljC7O1mVm1cjeGYVjnzfTp08due5vVMxMnTmTp0qVAytcyR44cdtsjKwsICKBKlSrA3efOmC3NBg0ahKenZ4bGJiLiKuyanImLi2PmzJm0a9eOMmXKMGrUKI4fP45hGJQuXZr/+7//49SpU8ybN49HH32UDz74gOPHjzNjxgzy5cvHzZs3ee+99+wZkoiIiIiIiKTTrfNmPDwc89o+i8VC586dAbU2s5XZZisoKMhhXy9HuLW1mTsxK2dq167t5Ejcl9lC7H6J2c2bN3Py5EkCAgKs3yvsoUePHpQqVYpLly7x1ltv3RaP2Me9WpsdPXqUFStWYLFYGDRokDNCExFxCXb5bW3z5s0899xzFC5cmP79+7Ny5UqSk5Px8fGhd+/eLFu2jCNHjvDWW2/dMeDLw8ODvn378uWXXwJYS+ZFRERERETEucxKBke1NDPdOnfG3eaOuBJ3mzdjMucZuVPlTFxcHPv27QNUOWMLMxmya9curly5ctdjzJZmPXr0wN/f3257e3p6MmzYMAAiIyNvi0fso379+sCdlTNTpkwBoF27dpQqVSqjwxIRcRk2JWc+++wzqlSpQuPGjZk8eTLXrl3DMAyqVKnCuHHjOHv2LL/99htt2rR54FpmNv1eP4xFREREREQkY5k3y82b547Stm1bfHx8OHbsGAcPHnToXpmZuyZnzOTf9u3bSUhIcHI0qRMWFkZSUhL58uWjWLFizg7HbRUuXJjy5ctjGAYbNmy44/GkpCT++OMPwL4tzUxPP/002bNnt/6/adOmdt8jKzOTM1u2bLEm3hMTE5k6dSoAQ4YMcVpsIiKuwKbkzBtvvMHBgwcxDINs2bIxaNAgQkJC2LNnDyNGjCBPnjypXsvLy8uWUERERERERMSOLl++zKFDh4B/b7A5SkBAAC1btgSyVmuzmJgYtmzZQnx8vE3rHD58mCFDhrBs2TLA/ZIz5cuXJ3fu3MTFxbF7925nh5MqZkuzWrVqYbFYnByNezPnztyttdn69esJDw8nV65ctG/f3u5758qVi4EDBwJQtWpV8ubNa/c9srKgoCB8fX25evUqR44cAVK+x0dERJA/f366d+/u5AhFRJzL5rZmdevWZeLEiYSHh/Pjjz+m+xVVZcuWJTk5maSkJFtDEhERERERERuZMwLKly+fITcszdZmCxYscPheruLll1+mQYMGFCtWjFdeecXaJiu1duzYwWOPPUbFihX58ccfSUxMpF27dtbOFO7Cw8PDmgB0l9ZmO3bsANTSzB7M5MzatWvveMxsafbwww/j4+PjkP3ffvttunTpwujRox2yflbm7e1tvUbM1mY//vgjAE8++aTDvqYiIu7CpuTMrl272Lx5M0OGDCEgIMBeMYmIiIiIiIiTmcPZHT1vxmQmZ9avX8+1a9cyZE9nSk5O5u+//wbg4sWLfPnll1StWpXGjRvz008/ER0dfdfzDMNg9erVdOzYkdq1azN79mwMw6Br166sX7+epUuX4u3tnZEfil2YzzPzeZfRrly5wrx581LdVs2snKldu7Yjw8oSzDkv27dv5/r169b3JyYm8ueffwLQu3dvh+1fuHBhFixYQK9evRy2R1Z2a2uzM2fOsGjRIgAGDx7szLBERFyCTcmZoKAge8UhIiIiIiIiLiSjkzNly5alYsWKJCYmsnTp0gzZ05nCwsK4cOEC2bNn559//qFnz554enqyceNGnn76aQoXLsyQIUPYvHkzhmGQnJzMvHnzaNy4Ma1atSI4OBhPT0/69evHrl27mD9/Pk2aNHH2h5VuZhcOZ1TO7N+/n7p169KjRw+effbZBx6fmJhobb+myhnblShRglKlSpGUlERISIj1/StXruTixYvky5eP1q1bOzFCsYVZybd161amTp1KcnIyzZo1o2LFik6OTETE+WxuayYiIiIiIiKZS3JysjU507hx4wzb16yeyQpzZ5YvXw6ktHTq0aMHc+bM4cyZM3zyySeUL1+e6Ohoa+vw6tWrU716dXr06MGmTZvw9fXl+eef59ChQ8yYMYPq1as7+aOxnfnq+kOHDnH58uUM23f58uU0atSIY8eOATB16lTmz59/33MOHjxIXFwcAQEBlCtXLiPCzPTM6plbW5uZLc0effRRzSl2Y+a1HRoaypQpUwAYMmSIM0MSEXEZqfrpdurUKYdsXqJECYesKyIiIiIiIum3b98+rl27Rvbs2TP0xn+XLl348ssvWbx4McnJyXh4ZN7XE5rJmTZt2ljfV6hQIV5//XVee+011q1bx5QpU5g9ezZhYWEA5MyZk6FDh/Liiy9SsGBBp8TtKHnz5qV8+fIcPnyYLVu20LFjR4fvOXHiRP73v/+RlJRE06ZNqVq1KhMnTmTIkCGEhYWRL1++u55ntjSrWbNmpn6OZqQWLVrwyy+/sGbNGgDi4+OZM2cO4NiWZuJ45cqVI1euXFy9epWTJ08SGBioFnIiIv9fqpIzpUuXtvvGFouFxMREu68rIiIiIiIittmwYQOQ0tIsI1+x3rRpU3LkyEFkZCTbt293u8H2qXXz5k3rTei2bdve8bjFYqF58+Y0b96cr776ij///JObN2/Sr18/AgMDMzrcDNOgQQMOHz7M5s2bHZqcSUpK4vXXX+fLL78E4IknnuDHH3/EMAzWr1/P3r17ee6555g9ezYWi+WO83fs2AGopZk9mZUzW7ZsITY2luXLl3P16lWKFClC06ZNnRyd2MLDw4O6detaE9JPPPEE2bJlc3JUIiKuIVUv8TAMwyFvIiIiIiIi4nrMuQ8Z2dIMwMfHx5qsCA4OztC9M9KmTZuIiYmhQIECVKtW7b7H5sqVi8GDBzN06NBMnZiBf+fOmC31HCE6OpqHH37Ympj54IMP+OWXX/D19cXPz4/p06fj5eXFX3/9xcyZM++6hlk5U7t2bYfFmdWULVuWIkWKkJCQwKZNm25raebp6enk6MRWZmszUEszEZFbpeolUFOnTnV0HCIiIiIiIuIizOSMMwbMd+jQgTlz5hAcHMw777yT4ftnhFtbmqkt1r8aNGgAwObNmzEM465VK7Y4c+YM3bp1Y+fOnfj6+vLzzz/f0TKrVq1avPfee7z33nsMGzaMli1bUrRoUevjhmGwc+dO67FiHxaLhRYtWvDbb7+xZMkS5s2bB0CfPn2cHJnYQ+vWrRkzZgyNGjWiRo0azg5HRMRlpCo58+STTzo6DhEREREREXEB58+f58iRI8C/lQwZqUOHDgBs3LiRa9euZcpqETM5c7eWZllZ9erV8fPz48qVKxw+fJgKFSrYbe3t27fTrVs3wsPDKVCgAHPnzr3n83vkyJHMnz+frVu38vTTT7N48WJrouj48eNcu3YNHx8fqlSpYrf4JKW12W+//cY333xDbGwsJUuWtCbsxL21adOG5cuXExQU5OxQRERcil6iIyIiIiIiIlYbN24EoGrVquTKlSvD9y9VqhQVKlQgKSmJFStWZPj+jnbt2jW2bNkCKDnzXz4+PtZWYZs3b7bbun///TfNmjUjPDycqlWrsnnz5vsmHr28vPjll1/w8/MjODiYiRMnWh8zW5oFBQXh7e1ttxgFWrRoAUBsbCwAvXv3tnv1lDhPmzZtKFCggLPDEBFxKUrOiIiIiIiIiNWGDRsA57Q0M5nD4DPj3Jk1a9aQlJRE+fLlKVGihLPDcTlmpYS95s7MmjWLXr16ERsbS8eOHQkJCaFUqVIPPK9SpUp8/PHHALzyyivWarIdO3YAamnmCJUqVSJ//vzW/6ulmYiIZHZKzoiIiIiIiIiVOW+mcePGTovBbG0WHByMYRhOi8MR1NLs/sykoL2qpr744gsAnn76aebPn0/OnDlTfe7w4cNp1aoVMTExDBw4kKSkJGvljFnhI/ZjsVho3rw5AOXLl6dmzZrODUhERMTBUjVzJjV27drFunXrOHbsGNevXycpKem+x1ssFqZMmWKv7UVERERERMRG8fHxbNu2DXBu5UyLFi3w8fHh5MmTHDx4kEqVKjktFnszkw5Kztxd27Zt8fLy4uDBgxw9epSyZcume61z586xbds2LBYLH330EV5eabsF4uHhwdSpUwkKCmLDhg188cUX1uSMKmcco3///vz111+89NJLamkmIiKZns3JmYMHDzJo0KA0lRwbhmFTcmbChAlMmDCBEydOACm9kN977z06depkXX/06NFMmjSJK1eu0KBBA7777juqVq1qXSM+Pp5XX32V3377jdjYWNq0acP3339PsWLF0hWTiIiIiIjcX3JyMnFxcWTLls3Zocg9bN++nZs3b5I/f36bborbKnv27DRr1owVK1YQHBycaZIz586dY9++fVgsFlq1auXscFxSYGAgzZo1Y9WqVSxcuJAXXngh3WstWLAASGmVVrBgwXStUbJkScaPH8/TTz/N22+/TWJiIh4eHlSvXj3dccm99ejRg5iYGPz9/Z0dioiIiMPZ1Nbs7NmzNG/enE2bNmEYBoZhkD17dooVK0aJEiXu+VayZEmbeusWK1aMjz/+mG3btrFt2zZat25Njx492Lt3LwCffvopX375Jd9++y1bt26lUKFCtGvXjuvXr1vXePHFF5kzZw6zZs1i/fr1REdH07Vr1wdW/IiIiIiISPo8/PDDFChQgD/++MPZocg9mC3NmjRp4vRXrWfGuTNm1UzdunXJnTu3k6NxXV26dAH+Ta6k17x58wDo3r27Tes89dRTdOvWjcTERCBlNoqSzI6jxIyIiGQVNiVnPvroIy5cuADA4MGDOXDgAFFRUZw8eZLjx48/8C29unXrRufOnalQoQIVKlTgo48+IiAgwJokGj9+PG+//TYPP/ww1apV4+effyYmJoaZM2cCcO3aNaZMmcIXX3xB27ZtqVWrFjNmzGDPnj3W/r8iIiIiImI/ly5dYt68edy4cYPevXvz0UcfZbpZIpnBhg0bAOfOmzGZc2dWr15NXFyck6OxD/PvzTZt2jg5EtdmJmfWrFlDdHR0uta4ceOGNRnWrVs3m+KxWCxMmjSJvHnzAmppJiIiIvZhU1uzJUuWYLFYGDBgAJMmTbJXTGmSlJTE7NmzuXHjBo0aNeL48eNERETQvn176zG+vr60aNGCkJAQnn32WbZv305CQsJtxxQpUoRq1aoREhJi/SPgv+Lj44mPj7f+PyoqCoCEhAQSEhIc9BGKOJ75/NXzWMT16XoVcS+6Zv+1ZMkSDMPAz8+PuLg43nnnHQ4cOMCECRPw9fV1dnhCSntos3Kmfv36Tn/eVqxYkSJFinDu3DlWrVrl8Bktjr5eDcOwJmdatmzp9M+vKytTpgxlypTh2LFjLFmyhB49eqR5jSVLlhAXF0fp0qWpUKGCzZ/vvHnz8vPPP/PWW2/x1FNP6evnAvQzVsR96HqVrCa1z3WbkjPnzp0DYMCAAbYsky579uyhUaNGxMXFERAQwJw5c6hSpYr1j4n/9pMtWLAgJ0+eBCAiIgIfH587ysgLFixIRETEPfccO3Yso0ePvuP9S5cuVUmzZArLli1zdggikkq6XkXci65Z+Omnn4CUaojChQszadIkZsyYQWhoKG+++SY5c+Z0coQSHh5OZGQkXl5eREZGsmjRImeHROXKlTl37hwTJ07k5s2bGbKno67X06dPc+7cOXx8fIiKinKJz68rq1y5MseOHWPSpEl4e3un+fwJEyYAKTNqFy9ebLe4PvjgA6Kjo/X1cyH6GSviPnS9SlYRExOTquNsSs7kzp2byMhIcuXKZcsy6VKxYkV27tzJ1atX+euvv3jyySdZs2aN9fH/9kc2DOOBPZMfdMzIkSN5+eWXrf+PioqiePHitG/fXn9MiltLSEhg2bJltGvXLl1/+IhIxtH1KuJedM2mMAyD559/HoDnnnuONm3a0K1bNx5//HH27dvH6NGj+eeff6hYsaKTI83apk+fDqTMQ+nZs6dzg/n/oqOjWbFiBUeOHKFz584O3cvR1+t3330HQLNmzVzm8+vKvLy8WLhwIXv37qVTp05pmoGUnJzMM888A8CwYcNo3bq1o8IUJ9LPWBH3oetVshqz49aD2JScqVu3LosWLeLQoUMZ3nPVx8eHcuXKWePYunUrX331FW+88QaQUh1TuHBh6/GRkZHWappChQpx8+ZNrly5clv1TGRk5H17K/v6+t615YK3t7e+sUimoOeyiPvQ9SriXrL6Nbt7927Cw8Px9/enZcuWeHt707lzZ0JCQujatStHjx6lWbNm/PXXX7qJ6kRbtmwBoGnTpi7zfO3YsSMWi4W9e/cSGRlJ0aJFHb6no67XVatWAejGVCq1adOGbNmyce7cOfbu3Zumew6bNm0iMjKSwMBAWrdurc93JpfVf8aKuBNdr5JVpPZ57mHLJi+88AKGYTht3sytDMMgPj6e0qVLU6hQodvK5G7evMmaNWusiZc6derg7e192zHh4eGEhYW5xOBLEREREZHMJDg4GIBWrVrh5+dnfX/VqlXZvHkzjRo14urVq3To0IEff/zRWWFmeRs2bABwqb+J8ubNS7169YB/n0fuKDEx0ZqccfTsnMzCz8+Pdu3aAbBw4cI0nTtv3jwgJbmnm4AiIiLiqmxKzrRr147XX3+dVatW8fzzz2fYUKe33nqLdevWceLECfbs2cPbb7/N6tWr6devHxaLhRdffJExY8YwZ84cwsLCGDhwINmyZaNv374ABAYG8vTTT/PKK6+wYsUKduzYwRNPPEFQUJB+URYRERERsbMlS5YAKfNm/qtAgQKsXLmSxx9/nMTERIYMGcLrr79OcnJyRoeZpV29epW9e/cCrpWcgZQb7ODeyZmtW7dy/fp18uTJQ82aNZ0djtvo0qULkPbkzPz58wHo3r273WMSERERsZdUtTX75Zdf7vlYlSpVaNy4MZMmTWL+/Pk88sgjVKpUiWzZsj1w3QEDBqQ+0lucP3+e/v37Ex4eTmBgINWrV2fJkiXWV9W8/vrrxMbGMnToUK5cuUKDBg1YunQpOXLksK4xbtw4vLy8eOyxx4iNjaVNmzZMmzYNT0/PdMUkIiIiIiJ3io6OZv369cC/N9n/y8/Pj19//ZWKFSsyatQoPvvsM44cOcIff/yBl5dNnZgllTZt2oRhGJQtW9baDtpVdOjQgQ8++IBly5aRlJTkln+zLV++HIDWrVu7ZfzOYs4Z2rx5MxcuXCB//vwPPOfYsWOEhYXh6elJp06dHB2iiIiISLql6i+dgQMHpmr4Xnh4ON98802qNrZYLOlOzkyZMuWBa48aNYpRo0bd8xg/Pz+++eabVMcrIiIiIiJpt3r1am7evEmpUqUoX778PY+zWCy8//77lC9fnqeeeoo5c+Ywd+5cevXqlYHRZl0hISGA61XNANSvX5/AwECuXLnCtm3baNCggbNDSrMVK1YAammWVkWLFqVmzZrs3LmTJUuW0L9//weeY1bNNGvW7LYZsyIiIiKuJtVtzQzDsPubiIiIiIhkbmYrKnOw+4P07duXYcOGAf/OjRDHM5MzTZo0cXIkd/Ly8rImNcwWee7kxo0b1s+vkjNpZ7Y2W7BgQaqOV0szERERcRepqpw5fvy4o+MQEREREZFM6H7zZu6lW7dufPnllyxcuNBt21i5k8TERDZt2gS4ZuUMpCT3/vrrL4KDg3n//fedHU6arFu3joSEBEqVKkWZMmWcHY7b6dKlCx999BHBwcEkJCTg7e19z2OvXr3KmjVrACVnRERExPWlKjlTsmRJR8chIiIiIiKZzNGjRzly5AheXl60bt061ec1adKE3Llzc+nSJTZu3EjTpk0dGKXs2bOHGzdukDNnTqpWrerscO7KTO5t3ryZK1euuFW7KnPeTJs2bVJVPSa3q1+/Pvny5ePixYuEhITQokWLex67ZMkSEhMTqVy5MmXLls3AKEVERETSLtVtzURERERERNLCbGnWuHFjcubMmerzvL29rYO8zRZF4jgbNmwAoFGjRnh4uOafiMWLF6dy5cokJydbkx3uwoxXLc3Sx9PTk44dOwKwcOHC+x6rlmYiIiLiTmz6zbt169a0adOGkydPpvqcc+fOWc8TEREREZHM69Z5M2nVrVs3QHNnMoI5D8VVW5qZzOeR+bxyB5GRkezatQsgTdVjcjtz7sz9kjMJCQksWrQI+Pf7h4iIiIgrsyk5s3r1alavXs2NGzdSfU5sbKz1PBERERERyZxu3rzJypUrgbTNmzF17NgRLy8vDhw4wJEjR+wdntzCTM40adLEyZHcn/k8Cg4OxjAMJ0eTOuY1UKNGDQoUKODkaNxXhw4d8PT0ZN++fZw4ceKux2zYsIGrV6+SL18+GjZsmLEBioiIiKSDa9asi4iIiIiIWwsJCSE6OpoCBQpQs2bNNJ+fK1cumjdvDqi1mSOdPXuWkydP4uHhQf369Z0dzn01b94cPz8/zpw5w/79+50WR0JCAklJSak6Vi3N7CN37tzWyq57Vc+YVXZdu3bF09Mzw2ITERERSa8MT86YVTZ+fn4ZvbWIiIiIiGQQs/VU+/bt0z3HxGxNpOSM45hVMzVq1CBHjhxOjub+/P39rQm7JUuWZPj+CQkJfPXVVxQqVIjy5cuzfv36+x5vGAbLli0DlJyxh65duwJ3T84YhmFNzqilmYiIiLiLDE/OLF68GIBixYpl9NYiIiIiIpJBzJvn6Zk3YzJvsq5du5YrV67YJS653YYNGwDXnzdjcsbcGfPGf7Vq1XjxxRe5fPkyx48fp0WLFrz99tskJCTc9byjR49y6tQpvL29adasWYbFm1mZc2dWrVpFTEzMbY8dOHCAo0eP4uPjQ/v27Z0RnoiIiEiaeaXl4EGDBt31/e+88w65cuW677nx8fEcPXqUrVu3YrFYaNGiRVq2FhERERERNxEREcHOnTsBaNeuXbrXKVu2LFWqVGHfvn0sWbKExx9/3E4Risld5s2YzLkza9euJTY2Fn9/f4fut2vXLl5++WXr7JgCBQowatQotmzZwrRp0xgzZgxLly5lxowZVKxY8bZzV6xYAaQkvrJnz+7QOLOCKlWqULJkSU6ePMnKlSutlTTwb0uzNm3aEBAQ4KwQRURERNIkTcmZadOmYbFYbnufYRjMnTs3VeebQxvz5MnDyJEj07K1iIiIiIi4iaVLlwJQp04dm4egd+vWjX379jF//nwlZ+wsJiaGHTt2AO5TOVO5cmWKFSvGmTNnWLt2rTVZY28RERG8++67TJkyBcMw8PX15aWXXmLkyJHkzJmT559/ni5duvDMM8+wbds2ateuzZdffskzzzxj/ZtZ82bsy2Kx0KVLF77//nsWLlx41+SMWpqJiIiIO0lTW7MSJUrc9gYpvyAVLlz4jsdufStZsiQVK1akVatWvP322+zevZvSpUs75AMSERERERHnMltO2ePGeffu3QFYtGjRPdtHSfps3bqVxMREihQpYv37ztVZLBbr88oRc2fi4+P5+OOPKV++PD/++COGYdC7d28OHDjA2LFjyZkzp/XYRx55hN27d9OmTRtiYmJ47rnn6NGjB5GRkSQlJVmrbZScsR+ztdmCBQusL/68cOECGzduBJScEREREfeSpsqZEydO3PZ/c7Dn0qVLqVKlit2CEhERERER95ScnGytnLFl3oypQYMG5MuXj4sXL7J+/XpatWpl85qS4taWZv/tkODKOnbsyJQpU+w+d2bevHkMGzaMCxcuAFC/fn3GjRt336qiYsWKsXTpUsaPH8/IkSOZP38+QUFB1tk0OXPmpG7dunaNMytr1aoV/v7+nDlzhj179lC9enUWLlyIYRjUqlVLs21FRETEraSpcua/mjdvTvPmzdU/V0REREREAAgNDeXixYvkyJGDhg0b2ryep6en9dXy8+fPt3k9+deGDRsA92lpZmrTpg0eHh7s37+f06dP22XN48eP06dPHy5cuECxYsWYMWMGGzduTNXnxsPDg5dffpktW7ZQtWpVIiMjeeuttwBo2bIlXl5pek2k3Ie/vz+tW7cGYOHChcC/Lc3MKjsRERERd2FTcmb16tWsWrWKkiVL2iseERERERFxY2arqbZt2+Lt7W2XNc2brvPmzbO2MhLbJCcnW1tBNWnSxMnR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Ecp/bdq0iVOnTpEjRw46deqU4ftbLBb69esHwK+//prh+zva7t27OXnyJP7+/rRr187Z4biFDh06AA9OzqxevRrDMKhcuTKFCxfOiNBERERERO5gl+SMYRhMnDiRoKAgihQpQvv27enTpw99+vShffv2FClShKCgICZNmoRhGPbYUkREREQyiYsXL/LVV18BKbNm0lM1Ayk369XaLOOYVTM9e/bE39/fKTH07dsXgKVLlxIZGemUGBzFrJpp37492bJlc24wbqJjx44ALF++nISEhHsep3kzIiIiIuIKbE7OXLlyhWbNmjF06FD27duHYRh3fdu3bx/PP/88zZs35+rVq3YIXUREREQygy+++ILo6Ghq1qxpc/smMzmzYMECvSjIgZKSkvjjjz8A57Q0M1WoUIG6deuSlJTE7NmznRaHI6ilWdrVrl2bfPnycf36dTZt2nTP4zRvRkRERERcgU3JGcMw6NGjByEhIRiGQZ48eXj++eeZNm0aS5YsYfHixUybNo2hQ4eSN29eDMMgJCSEHj162Ct+EREREXFjFy5c4JtvvgFSqmYsFotN67Vu3Ro/Pz9OnTrF3r177RGi3MXatWuJiIggd+7cTm+5ZVbPZKbWZidOnGDnzp14eHhYZynJg3l4eFifj/dqbRYeHs7+/fuxWCy0aNEiI8MTEREREbmNTcmZmTNnsn79emu/52PHjvHdd98xYMAA2rdvT4cOHRgwYADffvstx44do3///hiGwfr16/ntt9/s9TGIiIiIiJv67LPPuHHjBrVr16Z79+42r5ctWzbrgG+1NnMcs6VZr1698PHxcWosffr0wWKxsHHjRo4dO+bUWOxl7ty5ADRr1ox8+fI5ORr38qC5M2bVTK1atciTJ0+GxSUiIiIi8l82J2cAWrRowfTp08mRI8c9jw0ICODnn3+mRYsWGIbBjBkzbNlaRERERNzc+fPn+e677wAYPXq0zVUzJs2dcayEhAT+/PNPwLktzUyFCxe2tqfKLC8AU0uz9Gvfvj0A27dv58KFC3c8rnkzIiIiIuIqbErOhIaGYrFYGDZsWKrPGT58OAA7duywZWsRERERcXOffvopMTEx1KtXz5pQsQdzrZCQEK5cuWK3dSXFihUruHTpEgUKFKBly5bODgeAfv36ASmtzdx91tClS5dYu3YtgNpBp0PhwoWpUaMGhmGw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9OvXj/3791O0aFH+/vtvfH198fX1Zd68efTt25e///6bRx99lJ9++okBAwZYz1VLM8fp0KGDNTGreTMiIiIi4kpSnZxp2bKlXVsYWCwWEhMT7baeiIiICEBcXBw9evTgwIEDFCtWjEWLFhEYGAik/D6zfPly5s6da50HkVUdPXqUDz74AD8/PwoXLnzHW8GCBfH29rZpj5EjRxIaGkqePHmYMWMGnp6edoo+bbp27crkyZP5888/+eKLL2z+uLKaW1uauYuyZcvSoEEDNm/ezO+//86IESMcvue7777LggUL8PX1Zc6cORQuXNj6mK+vL7///jtDhgxh2rRpPPnkk0RFRTFs2DBOnTpFaGgoHh4edO3a1eFxZjVdu3bl7bffpmjRolStWtXZ4YiIiIiIWKW54a5hGI6IQ0RERMRmycnJ9O/fn/Xr1xMYGMjixYspVqyY9fEePXqwfPly/vnnnyyfnBkzZgy//PLLPR+3WCzky5ePwoULU7lyZd566600DYJfsGAB48aNA1KGcd/6dchoHTt2pECBAoSHhzNv3jx69erltFgc7fLly7zwwgt07NiRJ554wub1zp8/z8qVKwH3aGl2q379+rF582Zmzpzp8OTMrFmzGDt2LABTpkyhXr16dxzj5eXFlClTyJkzJ19//TXDhw/n2rVr5MiRA4AmTZqQP39+h8aZFQUFBbF8+XIKFSqEh4e6eouIiIiI60hzcsbf358ePXrQrl07/XIrIiIiLuWVV17hzz//xMfHh3/++Ydq1ard9niPHj0YPnw4GzZsIDIykgIFCjgpUucyDINly5YB8NRTT+Ht7U14eLj1LSIigqSkJC5cuMCFCxfYvXs3s2fPZtCgQXz44YcPbBF19uxZBg4cCMCIESPo1q2boz+k+/Lx8eHpp59m7Nix/PDDD5k6OTNjxgx+/fVXfv31V9asWcM333yDn59futYyDIOvv/6a5ORk6tWrR5kyZewcrWM99thjvPTSS2zZsoXDhw9Tvnx5h+wTGhrKoEGDAHjttdes827uxsPDg/Hjx5M7d25Gjx7NO++8Q86cOQG1NHMkzZoREREREVeU6uRMjhw5uH79OrGxsfz++++sXr2avn370r9/f2rUqOHIGEVEREQeaNy4cYwfPx5IqdRo2bLlHccUL16cOnXqsH37dhYsWGC9oZrVHDlyhNOnT+Pj48O3335LtmzZbns8OTmZixcvEh4ezrlz55g6dSqzZ8/mxx9/ZNasWbz11lu89NJLd73pb87duHTpErVq1eKTTz7JqA/rvp555hk+/vhjli9f7tAb9c4WEhJi/fePP/7Ijh07+OuvvyhZsmSa1jl58iRDhgy5LYnnbgoWLEjbtm0JDg7mt99+47333rP7HufPn6dHjx7ExsbSqVMna/XM/VgsFkaNGkVgYCAvv/wyUVFRQEryWEREREREso5Ul76cP3+e3377jc6dO+Pp6UlERATjxo2jdu3a1KhRg88//5xz5845MlYRERGRu/rjjz94+eWXAfj00095/PHH73mseQPUHMCdFS1fvhxIaaP038QMpLy6v0CBAtSoUYNOnTrxxx9/sG7dOurWrUt0dDRvvfUWlSpV4vfff7+j5e2YMWNYs2YNAQEB/P777/j6+mbIx/QgpUqVolOnTgBMnDjRydE4jpmceeedd8ibNy/bt2+ndu3aBAcHp+r85ORkJkyYQLVq1Vi2bBl+fn58/vnnPPvss44M22H69u0LwK+//mr39szx8fH06tWLM2fOULFiRWbOnJmmuUovvfQSU6ZMwcPDg8aNG1O2bFm7xiciIiIiIq4t1ckZPz8/evfuzYIFCzh79izjxo2jVq1aGIbBnj17eOONNyhZsiTt2rVj+vTp3Lhxw5Fxi4iIiACwdu1a+vfvD8Dw4cN59dVX73u82Tpo2bJlWfb3FTM506ZNm1Sf07RpUzZv3sz06dMpVqwYJ0+epE+fPjRp0oTNmzcDsG7dOkaNGgXA999/73LVKc8//zwAU6dOJS4uzsnR2N+ZM2c4ffo0np6evPnmm2zfvp26dety+fJlOnXqxIcffkhycvI9zz927Bht2rRh6NChREdH07RpU3bt2sUrr7zitu2MH3roIfz8/Dh06BChoaF2W9cwDIYNG8aGDRsIDAxk7ty55MqVK83rDBo0iBMnTrBkyRK7xSYiIiIiIu4hXX9l5c+fnxEjRrBt2zb27t3LG2+8QbFixUhKSmLFihUMHDiQggUL0r9/f4KDg+3+KjURERERgL1799KjRw9u3rzJQw89xLhx47BYLPc9p1q1apQpU4a4uDiWLl2aQZG6jqSkJOuA97Zt26bpXA8PD5544gkOHjzIBx98QLZs2di4cSMNGzakb9++9O3bl+TkZAYMGGBNmLmSTp06UaJECS5fvszs2bOdHY7dbdy4EYAaNWqQPXt2SpYsybp163jmmWcwDIP33nuP7t27c+XKldvOS05O5uuvvyYoKIjVq1eTLVs2vvrqK9asWUOFChWc8aHYTY4cOejevTuQUj1jL9999x0//vgjFouF3377jYoVK6Z7reLFi5MjRw67xSYiIiIiIu7B5pfAVa5cmbFjx3Ly5ElWrlzJwIEDyZEjBzExMfz666907tyZokWL8sYbb9gjXhEREREAzp07R6dOnbh69SqNGzfm119/TVVLIYvFkqVbm4WGhnL16lUCAwOpU6dOutbIli0b7777LocPH2bgwIHWG9RnzpyhfPnyfPfdd3aO2j48PT155plnAPjhhx+cHI39mS3NGjdubH2fn58fEydO5KeffsLPz4+FCxdSt25ddu7cCcChQ4do3rw5I0aMICYmhpYtW7J7925eeOEFt62W+a9+/foB8Ntvv5GYmGjzejt37uTFF18E4JNPPrG2yxMREREREUkLu/7F1bJlS3766SciIiKYOXMmnTp1ss6n+eabb+y5lYiIiGRhUVFRdO7cmdOnT1OhQgXmzZuHv79/qs83W5stWLDALjdr3YnZ0qxVq1Z4eXnZtFaRIkWYOnUq27Zto3Xr1hQtWpQ//viDgIAAe4TqEE8//TReXl6EhISwe/duZ4djV3dLzpieeuopQkJCKF26NMeOHaNRo0Y899xz1KhRgw0bNhAQEMD333/PihUrMt3sk44dO5IvXz4iIiJYvHixzet9/fXXJCUl0aNHjwe2URQREREREbkXh7wczmKx4OHhgcVieWBrEREREZG0uHnzJr169WLXrl0UKFCAJUuWkDdv3jSt0bhxY/Lly8fly5dZv369gyJ1TWZyJq0tze6ndu3arFixgjNnzlCzZk27resIhQoV4qGHHgIyV/VMbGysdabK3ZIzALVq1WLbtm107tyZuLg4Jk6cSFxcHO3atSMsLIznn38+01TL3MrHx4cBAwYAMHnyZJvWunLlCrNmzQLg9ddf1986IiIiIiKSbnb962vNmjUMHjyYggUL8vjjj7N48WISEhIoXLgwL7zwgj23EhERkSzIMAwGDx7M8uXLyZ49O4sWLaJ06dJpXsfLy4uuXbsCWau1WUxMjDUZZc/kjLt57rnnAJg+fTrXr193cjT2sW3bNhITEylcuDAlSpS453F58uRh/vz5/N///R9VqlRh8uTJBAcHU7JkyQyMNuMNHjwYgIULF3L27Nl0r/PLL78QGxtL9erVadSokb3CExERERGRLMjm5Mz+/ft56623KFmyJK1bt2bq1KlERUXh7+9P3759CQ4O5vTp03z88cf2iFdERESysHfffZfp06fj6enJ7Nmz0z0zBf5tbfbPP/9gGIadInRtGzZs4ObNmxQrVsztB73bolWrVlSoUIHo6Ghmzpzp7HDsYuPGjUBK1cyDqjk8PDx4++232bt3L4MHD84S1R+VK1emadOmJCcnM3Xq1HStYRiGtdrqueeeyxKfNxERERERcZx0JWciIyP56quvqFu3LtWqVeOTTz7h9OnTWCwWWrduzc8//8z58+eZPn067dq1y5TtEURERCRjTZw4kY8++giASZMm2TyEu127dvj7+3Py5MlMN3vkXlasWAGkVM1k5RvLFovFWj0zYcKETJGcu9+8GUkxZMgQAKZMmUJycnKaz1+zZg0HDhwgICCAJ554wt7hiYiIiIhIFpPqrElcXByzZs2iS5cuFCtWjJdffpnQ0FAMw6Bq1ap88sknnDp1imXLltG/f3+yZ8/uyLhFREQkC5k/fz5Dhw4FYNSoUQwaNMjmNbNly0b79u2BrNPazBHzZtzVk08+iZ+fH7t27WLz5s3ODscmhmEoOZMKjzzyCIGBgZw4ccJ6LaTFhAkTAOjXrx85cuSwd3giIiIiIpLFpDo5U6BAAfr168eSJUtITEykYMGCvPTSS4SGhrJ7925ee+01ihQp4shYRUREJAvasmULvXv3Jjk5mUGDBvHee+/Zbe1bW5tldpcuXbIOjG/Tpo2To3G+PHny0Lt3b+Dfm+7u6ujRo1y4cAFfX19q1arl7HBcVrZs2awVL5MnT07TuefPn+fvv/8G4Pnnn7d7bCIiIiIikvV4pfbA6OhoLBYLfn5+dO/enfbt2+Pp6cnu3bvT3QpkwIAB6TpPREREsoYjR47QpUsXYmNj6dixIz/88INd23F17doVDw8Pdu7cycmTJzP1UPRVq1ZZK54LFSrk7HBcwnPPPcfPP//M77//zrhx48iTJ4+zQ0oXs2qmTp06+Pr6Ojka1zZkyBC+++475s6dS2RkJAUKFEjVeVOmTCExMZGGDRtSo0YNB0cpIiIiIiJZQaqTM6a4uDj++OMP/vjjD5s2tlgsSs6IiIjIPV24cIGOHTty8eJFateuzezZs/H29rbrHvny5aNp06asXbuWuXPn8sILL9h1fVeilmZ3atCgATVr1mTnzp1MmzaNl19+2dkhpcvGjRsBtTRLjRo1alC/fn22bNnCzz//zGuvvfbAc5KSkpg0aRKgqhkREREREbGfVLc1g5R+1vZ8ExEREbmb+Ph4unbtytGjRylVqhQLFy4kICDAIXtlldZmSs7cyWKx8NxzzwHwww8/uO3vp5o3kzZDhgwB4Mcff0zV13zJkiWcPHmS3Llz8+ijjzo6PBERERERySJSXTmzatUqR8YhIiIiYjVv3jy2bNlC7ty5WbJkiUPbcPXo0YOXX36ZtWvXcvnyZbdtbXU/x48f5+jRo3h6etKiRQtnh+NS+vbty2uvvcbhw4dZuXKl283jiYqKYs+ePQA0atTIydG4hz59+vDSSy9x6NAh1q5d+8Br4ocffgBg4MCB+Pv7Z0SIIiIiIiKSBaQ6OaM/5EVERCSjLFiwAIBBgwZRsWJFh+5VpkwZgoKC2LNnDwsXLqR///4O3c8ZVqxYAUDDhg3JkSOHk6NxLTly5OCJJ55gwoQJ/PDDD26XnNm8eTOGYVCmTBnNEkqlgIAAHn/8cSZPnszkyZPv+3fOyZMnWbhwIQDPPvtsRoUoIiIiIiJZQJramomIiIg4WnJyMosXLwagS5cuGbJnZm9tppZm92e2Nvvnn38IDw93cjRpY7Y0U9VM2pitzf78808uX758z+MmT56MYRi0bt3a4YliERERERHJWpScEREREZeydetWLly4QM6cOWnatGmG7GkmZ4KDg4mNjc2QPTNKcnKytXJGyZm7q169Oo0bNyYxMZEpU6Y4O5w02bhxI6B5M2lVt25datSoQXx8PDNmzLjrMTdv3uTHH38E4Pnnn8/I8EREREREJAtQckZERERcitlCqH379nh7e2fInrVq1aJ48eLcuHHDmsjILHbv3s3FixcJCAigQYMGzg7HZZk33ydNmkRSUpKTo0md5ORkJWfSyWKxWKtnzOqY/5o7dy7nz5+nUKFC9OjRI6NDFBERERGRTE7JGREREXEpZnImo1qaQcqNWvPma2ZrbWYmm1q0aJFhyS539Mgjj5A3b15Onz7NokWLnB1Oquzbt4+oqCgCAgKoVq2as8NxO/369cPf35+wsDA2bdp0x+MTJkwAYPDgwbp2RERERETE7pScEREREZdx7tw5QkNDsVgsdOrUKUP3NlubzZ8/320qJ1JD82ZSx8/Pj6eeegqAH374wcnRpI45b6Z+/fp4eXk5ORr3kytXLh599FEgpXrmVgcOHGDVqlV4eHhYK2xERERERETsSckZERERcRlmxUK9evUoWLBghu7dvHlzcuXKRWRk5F1fRe+O4uPjWbt2LQBt2rRxcjSub/DgwUDK7KFLly45OZoHM5MzammWfmbi5ffffycqKsr6/okTJwIpFXwlSpRwSmwiIiIiIpK5KTkjIiIiLsMZLc1M3t7e1n1nzpyZ4fs7wqZNm4iJiaFAgQJqe5UKFStWpHr16iQlJTF37lxnh/NAmjdjuyZNmlC5cmViYmKs131sbCzTpk0D4LnnnnNidCIiIiIikpkpOSMiIiIuIT4+nmXLlgHOSc4ADBw4EEgZCr9//36nxGBPt7Y0s1gsTo7GPZhtrmbPnu3kSO7v4sWLHDp0CICGDRs6ORr3ZbFYrBVTZmuz33//natXr1KqVCk6dOjgzPBERERERCQTU3JGREREXMLatWu5ceMGhQoVolatWk6JoW3btnTr1o3ExEReeOEFDMNwShz2onkzaWcmZ5YvX87ly5edHM29mVUzVapUIXfu3E6Oxr0NGDAAHx8fQkNDCQ0Ntc4ceuaZZ/D09HRydCIiIiIiklkpOSMiIiIuwWxp1rlzZzw8nPcryrhx4/D19WX58uXMmTPHaXHY6tq1a2zZsgXQvJm0qFixIkFBQSQmJrp0azNz3kyjRo2cHIn7y5cvHw8//DAAI0aMYPPmzXh7ezNo0CAnRyYiIiIiIpmZkjMiIiLiEpw5b+ZWZcuW5dVXXwXg5ZdfJiYmxqnxpNfq1atJTk6mQoUKGmieRo888ggAf/75p8P3MgyDgwcPMnPmTK5du5bq88zkjObN2MeQIUMAWL9+PQAPP/wwBQsWdGZIIiIiIiKSySk5IyIiIk536NAhjhw5gre3N+3atXN2OIwcOZLixYtz8uRJPvvsM2eHky5qaZZ+ZmuzZcuWcfXqVbuvHx0dzbx58xg6dChlypShUqVK9OvXjz59+qSqlV5CQgJbt24FlJyxl5YtW1K2bFnr/59//nknRiMiIiIiIlmBWyZnxo4dS7169ciRIwcFChSgZ8+eHDx48LZjDMNg1KhRFClSBH9/f1q2bMnevXtvOyY+Pp7hw4eTL18+smfPTvfu3Tlz5kxGfigiIiLCv1UzzZs3J0eOHE6OBrJnz87nn38OwMcff8yJEyecG1A6KDmTfpUrV6Zq1aokJCTYpbWZYRiEhYXx2Wef0aZNG/LkyUOPHj2YMGECJ06cwMfHBy8vL5YsWcI///zzwPV27dpFbGwsefLkoUKFCjbHJ+Dh4cHgwYMBqFSpEs2bN3dyRCIiIiIiktm5ZXJmzZo1/O9//2PTpk0sW7aMxMRE2rdvz40bN6zHfPrpp3z55Zd8++23bN26lUKFCtGuXTuuX79uPebFF19kzpw5zJo1i/Xr1xMdHU3Xrl1JSkpyxoclIiKSZS1YsACArl27OjmSfz366KO0atWKuLg4XnnlFWeHkyZnzpzhwIEDeHh40LJlS2eH45bM6pnZs2ene40rV64wbNgwBg8eTO3atXn99ddZuXIlCQkJlC5dmqFDhzJ//nwuXbrEG2+8AaT8fvqgVnq3zptx5nymzObFF19k9OjR/Pbbb1gsFmeHIyIiIiIimZyXswNIjyVLltz2/6lTp1KgQAG2b99O8+bNMQyD8ePH8/bbb1uHe/78888ULFiQmTNn8uyzz3Lt2jWmTJnC9OnTra8onTFjBsWLF2f58uV06NDhjn3j4+OJj4+3/j8qKgpIaS2RkJDgqA9XxOHM56+exyKuLzNer1FRUaxduxaA9u3bu9TH9vnnn1O/fn3+/vtvlixZQps2bZwdUqoEBwcDUKdOHQICAlzqc+ouevbsyahRo1i6dCkXLlwgV65caV5j6NChzJo1CwA/Pz9atmxJ+/bt6dChA+XKlbstAfDaa68xffp0Tp06xf/93/8xevToe65rzkWpX7++vrZ25OnpyciRI4HM9T1WUi8z/owVycx0zYq4D12vktWk9rnulsmZ/zKHp+bJkweA48ePExERQfv27a3H+Pr60qJFC0JCQnj22WfZvn07CQkJtx1TpEgRqlWrRkhIyF2TM2PHjr3rH8pLly4lW7Zs9v6wRDLcsmXLnB2CiMPs3r2bxYsXk5yc/MBjs2XLxpNPPpmum7EZJTNdryEhISQmJlKkSBEOHz7M4cOHnR3SbTp27MjChQsZMmQI48ePx8vL9X99mjFj3I7B8wAAS+FJREFUBgAlSpRg0aJFTo7GfRUrVowzZ87w0Ucf0apVqzSde/r0aX7//XcAXn31VerVq4evry/APZ/nffv25eOPP+azzz6jePHiFClS5K5rr1q1CkhpxaWvr4j9ZaafsSJZga5ZEfeh61Wyigd1QzC5/t2FBzAMg5dffpmmTZtSrVo1ACIiIgAoWLDgbccWLFiQkydPWo/x8fEhd+7cdxxjnv9fI0eO5OWXX7b+PyoqiuLFi9O+fXty5sxpt49JJKMlJCSwbNky2rVrh7e3t7PDEbG7uLg4hg4dyrlz51J9jo+PD/PmzXO51jaZ8XqdM2cOAI888gidO3d2cjR3atSoEVWrVuXMmTMcO3aMF1980dkh3ZdhGNZh5s8880yakwryryeffJKPPvqII0eO8Nlnn6Xp3H79+mEYBt27d6dp06apumY7depEaGgoS5cuZd68ecydO/eO70Fnzpzh4sWLeHp68r///Y+AgIA0f1wicneZ8WesSGama1bEfeh6lazG7Lj1IG6fnBk2bBi7d++2tne41X//mDUM44E32e53jK+vr/UVj7fy9vbWNxbJFPRclsxqwoQJnDt3jmLFivHuu+/e99j4+Hhef/11goODmTp1Ks8++2wGRZk2meV6TU5OtrYr7datm0t+TAUKFGDs2LEMGTKEDz/8kP79+1OoUCFnh3VP+/btIzw8HD8/P5o3b+6Sn1N30adPHz766COWLVtGTEwMgYGBqTpv7969/PnnnwC89957nDlzJtXX7Lfffku1atVYsmQJixcvpkePHrc9vm3bNgBq1Khxx4uMRMQ+MsvPWJGsQtesiPvQ9SpZRWqf526dnBk+fDjz5s1j7dq1FCtWzPp+84ZJREQEhQsXtr4/MjLSWk1TqFAhbt68yZUrV277wzYyMpLGjRtn0EcgIiKOFhsby9ixYwF45513eOaZZx54TmJiIi+//DKvvPIKbdu2pWzZso4OM8sKDQ3l/PnzBAQE0Lx5c2eHc0+DBg1i4sSJbNu2jTfffJNp06ZlyL6GYXD8+HF27tzJzp072bFjB0eOHLlve77r168D0KxZM/z8/DIkzsyqatWqVKpUiQMHDjB//nyeeOKJVJ03evRoDMOgV69eVK9enTNnzqR6z/Lly/Pqq68yZswYRowYQbt27W5rnxsSEgKg31dFRERERETcnIezA0gPwzAYNmwYf//9NytXrqR06dK3PV66dGkKFSp0Wx/DmzdvsmbNGusfsnXq1MHb2/u2Y8LDwwkLC9MfuyIimcjEiROJiIigZMmSPPXUU6k6Z8SIEbRo0YIbN27w5JNPkpSU5OAos66FCxcC0K5dO3x8fJwczb15eHjw7bffAvDzzz+zadMmu+8RHx/Pjh07mDp1KiNGjKB58+bkypWLsmXL0qtXLz788EMWLFjAgQMHOHTo0D3fwsPDAXj44YftHmNWY7FYePTRRwGYPXt2qs7ZvXs3s2fPxmKxMGrUqHTt+9Zbb1G8eHFOnjzJxx9/fNtjZnKmUaNG6VpbREREREREXINbVs7873//Y+bMmcydO5ccOXJYZ8QEBgbi7++PxWLhxRdfZMyYMZQvX57y5cszZswYsmXLRt++fa3HPv3007zyyivkzZuXPHny8OqrrxIUFETbtm2d+eGJiIidxMTEWG9svv3226m++e/h4cG0adMICgpiw4YNfPnll7z22muODNXlpaY1aHqYyZkuXbrYfW17a9CgAQMHDmTatGkMHz6czZs34+Fhn9e5fPfdd7z00kskJCTc8ZiPjw/VqlWjZs2a1KxZkypVqjzwuRwQEEDNmjXtEltW9+ijj/Lhhx8SHBxMVFTUA+cMjh492npetWrV7vo1fZDs2bMzfvx4evXqxSeffMKAAQMoV64csbGxhIaGAqqcERERERERcXdumZyZMGECAC1btrzt/VOnTmXgwIEAvP7668TGxjJ06FCuXLlCgwYNWLp0KTly5LAeP27cOLy8vHjssceIjY2lTZs2TJs2DU9Pz4z6UERExIEmTJjA+fPnKV26tPXnQ2qVKlWK8ePHM3jwYN555x06depEtWrVHBOoi3v77beZMWMG06ZNs+tw+fPnz7N161YAOnfubLd1Henjjz/m77//Ztu2bfz0008MHjzY5jWvXbvG22+/TUJCArlz57YmYWrVqkXNmjWpVKmS+jI7UbVq1ahQoQKHDh1iwYIF1hf63M3OnTv5+++/sVgsvP/++zbt+9BDD9G+fXuWLl3KiBEjWLBgAdu3bycxMZHChQtTsmRJm9YXERERERER53LbtmZ3e7v1xpvZSiI8PJy4uDjWrFlzx001Pz8/vvnmGy5dukRMTAzz58+nePHiGfzRiIiII9y4cYNPPvkESJk1k56b24MGDaJLly7cvHmTAQMGcPPmTXuH6fJ++OEHxowZw6lTp3jooYfYv3+/3dZetGgRkNJq9NYZca6sYMGC1lZVI0eO5MqVKzav+d1333Ht2jWqVKnCxYsXWblyJV9++SX9+/cnKChIiRknS0trM/O50adPH6pUqWLzvt988w3e3t4sWrSI+fPn3zZvxhGVbCIiIiIiIpJx3DI5IyIi8iDfffcdFy5coEyZMvTv3z9da1gsFiZPnkyePHnYsWMH//d//2fnKF3bmjVrGD58OACFChXi2rVrdOnShcjISLus704tzW41bNgwKleuzMWLF60trNLrxo0bfPnll0DKnBF7tUkT+zKTM4sXL+b69et3PSY0NJS5c+fi4eHBe++9Z5d9K1SowKuvvgqkzMJasWIFoJZmIiIiIiIimYHuAIiISKYTHR3NZ599BsB7771nU+VB4cKF+eGHHwAYM2YMW7ZssUuMru7EiRM88sgjJCYm0qdPH3bv3k3ZsmU5fvw4PXv2JC4uzqb1b968ydKlSwH3S854e3vz1VdfAfD9999z7NixdK81adIkLl26RJkyZejdu7e9QhQ7q169OuXLlyc+Pp4FCxbc9RizaqZv375UqlTJbnu//fbbFC9enBMnTlivmUaNGtltfREREREREXEOJWdERCTT+fbbb7l48SLly5enX79+Nq/36KOP8vjjj5OUlMSAAQOIjY21Q5Su68aNG/To0YOLFy9Su3ZtpkyZQv78+Vm4cCG5c+dm48aNDBw4kOTk5HTvsX79eq5fv06BAgWoW7euHaPPGO3ataNdu3YkJCTw7rvvpmuNuLg4axJx5MiReHm55SjALOHW1mZ//vnnHY9v3bqV+fPn4+Hhke7nw71kz56dcePGWf/v4+ND7dq17bqHiIiIiIiIZDwlZ0REJFOJioqy3vB+99137XbD+9tvv6Vw4cIcPHiQkSNH2mVNV2TOcNu9ezcFChTgn3/+IVu2bABUrFiRv//+G29vb37//XebWjeZLc06derktq28zJlGM2fOJDQ0NM3nT5s2jfDwcIoVK8aAAQPsHZ7Y2SOPPAKkzEqKjo6+7TGzauaJJ56gQoUKdt/74Ycfpl27dkDKjCZfX1+77yEiIiLy/9q77/Ccr/+P4687OyFC1Kgde++arVlKJUXVFrFXrZb6GmltKTVKbEJI0daoTVFq1xalFVVixZ6xMz6/P3zdv/oaNe6R8XxcV65L7s/5nPM6muPudb9zzgcAYFuJ89MQAACeIzg4WNeuXVO+fPnUtGlTi/Xr7e2tkJAQSdL48eO1adMmi/WdkAwbNkyLFi2Ss7OzlixZoqxZsz5xvUqVKpoxY4Ykafjw4QoNDX2tcRLr82b+qUSJEmrWrJkkqW/fvq90b0xMjL7++mtJUp8+feTi4mLxfLCs4sWLK1euXLp//77551eSdu3apdWrV8vR0dHiu2YeM5lMmj59uurWrWux59kAAAAAAOyL4gwAIMm4efOmxowZI+nRs2YsfUxU7dq11bFjR0lSq1atdPPmTYv2b29Lly41f/A7efJkVaxY8ZntAgICNGDAAElShw4d9Ouvv77SOH///bciIiLk5OSkmjVrvlFmexs2bJicnZ21fv16rV+//qXvmz9/vk6dOqX06dOrXbt2VkwIS/nn0WYLFy40vz5w4EBJUsuWLZU7d26rjZ8jRw4tXbpUtWrVstoYAAAAAADboTgDAEgyxo8fr+vXr6tAgQJWe7j66NGjlTNnTp0+fVqfffaZVcawh8OHD8vf31+S1LVr138tGAwZMkSNGzdWTEyM6tevr6NHj770WI93Hbz77rvy8vJ6/dAJgI+Pj7p06SJJ+s9//vNSz+GJi4vTiBEjJEm9evWSu7u7VTPCch4XZ1avXq07d+5o586d+vnnn+Xk5KTAwEA7pwMAAAAAJCYUZwAAScKNGzc0duxYSY92zTg6OlplnJQpUyo0NFQmk0mzZ8/W7t27rTKOLV29elUfffSRbt++rapVq5r/Hl/EwcFBoaGhKl++vG7cuKE6dero8uXLL7zn0qVLWrdunebOnStJ8vX1tUh+exswYIA8PT114MAB/fDDD//afvHixTp27JjSpEmjzp072yAhLKVEiRLKmTOn7t27p9WrV5t3zbRq1Uo5c+a0czoAAAAAQGJCcQYAkCR8++23unnzpgoVKmT+7XZree+998y7TB7vgEisYmJi1KhRI508eVI+Pj5auHChnJ2dX+peNzc3LVu2TD4+Pjpx4oTq1aun+/fvKz4+XsePH9fChQs1YMAA1alTR5kyZVKGDBn0wQcfaN++fZKSTnEmXbp0+s9//iPpUaHmwYMHz21rGIaGDx8uSerRo4c8PT1tkhGWYTKZ9Mknn0h6VARev369nJyczMf8AQAAAADwsijOAAASvevXr2vcuHGSHj3/wVq7Zv6pX79+MplMWrZsmX7//Xerj2ctvXr10saNG5UiRQotW7ZMadOmfaX706VLp1WrVsnLy0s7duxQoUKF5OXlpTx58qhRo0YaMWKEVq9erfPnz8tkMilv3rxq3Lix5syZo3z58llpVrbXs2dPZcyYUSdPntS0adOe227lypU6dOiQUqZMqW7dutkwISzlcfH38VF+bdu2VY4cOeyYCAAAAACQGFGcAQAkemPHjtWtW7dUpEgRNWjQwCZj5s+f3/wb9Il198yUKVMUHBwsSQoLC1ORIkVeq58CBQpoyZIlcnJy0okTJ3T79m25ubnpnXfeUfv27TV58mTt2LFDt27dUkREhL7//nu1bNnSklOxuxQpUmjQoEGSpKFDh+rWrVtPtfnnrpkuXbrI29vblhFhIaVKlTIXY5ydndW/f3/7BgIAAAAAJEoUZwAAidrVq1f17bffSpIGDRokBwfbvbU9Psrohx9+0LFjx2w27psyDEMjR440P8h+8ODBql+//hv1Wa1aNW3btk3z58/XkSNHFB0drd27d2v69Onq3Lmzypcvr5QpU1oifoLVtm1b5c2bV1euXNE333zz1PVffvlFu3btkpubmz7//HM7JIQlmEwm87GGHTt2VLZs2eycCAAAAACQGFGcAQBYxJ07d9SoUaNnfihtLdHR0erRo4du376tYsWKqV69ejYbW5KKFSsmX19fGYahr7/+2qZjv674+Hj16tVLffv2lST17t1bX375pUX6Llu2rJo2baqCBQvKycnJIn0mJk5OTgoKCpL0aDfX+fPnn7j+eNdM+/btlSFDBpvng+UEBgZq9erVGjt2rL2jAAAAAAASKYozAACL+O6777Rw4UL16dNHP//8s1XHio+PV1hYmPLly6d58+ZJevTBty13zTz2ePdMWFiYTp06ZfPxX8XDhw/l7+9vfj7P6NGj9c0338hkMtk5WdJRv359lStXTnfv3tWQIUPMr2/fvl2//vqrnJ2d9cUXX9gxISzBxcVFtWvXlrOzs72jAAAAAAASKYozAACLmD17tvnPbdq00fXr160yzt69e/Xuu++qZcuWOn/+vHLlyqUVK1aoTp06Vhnv35QrV07Vq1dXbGysRo0aZZcML+P27dvy8/PT/Pnz5eTkpLCwMPXq1cvesZIck8mkkSNHSpJmzJihiIgISf+/ayYgIEBZs2a1Wz4AAAAAAJAw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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "#| eval: false\n", "# Plot predictions\n", @@ -941,190 +493,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/marcopeix/miniconda3/envs/neuralforecast/lib/python3.10/site-packages/pytorch_lightning/utilities/parsing.py:198: Attribute 'loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['loss'])`.\n", - "/Users/marcopeix/miniconda3/envs/neuralforecast/lib/python3.10/site-packages/pytorch_lightning/utilities/parsing.py:198: Attribute 'valid_loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['valid_loss'])`.\n", - "Seed set to 1\n", - "GPU available: True (mps), used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "\n", - " | Name | Type | Params\n", - "---------------------------------------------------------\n", - "0 | padder | ConstantPad1d | 0 \n", - "1 | loss | MSE | 0 \n", - "2 | valid_loss | MAE | 0 \n", - "3 | scaler | TemporalNorm | 0 \n", - "4 | enc_embedding | DataEmbedding_inverted | 3.2 K \n", - "5 | encoder | TransEncoder | 135 K \n", - "6 | projector | Linear | 1.5 K \n", - "---------------------------------------------------------\n", - "140 K Trainable params\n", - "0 Non-trainable params\n", - "140 K Total params\n", - "0.562 Total estimated model params size (MB)\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "f118cbdd019d4bb0990b028bc6e8ddeb", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Sanity Checking: | | 0/? [00:00]. Skipping setting a default `ModelSummary` callback.\n", - "GPU available: True (mps), used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "/Users/marcopeix/miniconda3/envs/neuralforecast/lib/python3.10/site-packages/pytorch_lightning/trainer/connectors/data_connector.py:441: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=10` in the `DataLoader` to improve performance.\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "7d07116f871b4263a25d7874684e167a", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Predicting: | | 0/? [00:00=AirPassengersPanel['ds'].values[-12]].reset_index(drop=True) # 12 test\n", diff --git a/nbs/tsdataset.ipynb b/nbs/tsdataset.ipynb index 17e633f55..a5b6bf711 100644 --- a/nbs/tsdataset.ipynb +++ b/nbs/tsdataset.ipynb @@ -54,7 +54,7 @@ "#| export\n", "import warnings\n", "from collections.abc import Mapping\n", - "from typing import List, Optional\n", + "from typing import List, Optional, Union\n", "\n", "import numpy as np\n", "import pandas as pd\n", @@ -157,11 +157,11 @@ " sorted=False,\n", " ):\n", " super().__init__()\n", - " self.temporal = torch.tensor(temporal, dtype=torch.float)\n", + " self.temporal = self._as_torch_copy(temporal)\n", " self.temporal_cols = pd.Index(list(temporal_cols))\n", "\n", " if static is not None:\n", - " self.static = torch.tensor(static, dtype=torch.float)\n", + " self.static = self._as_torch_copy(static)\n", " self.static_cols = static_cols\n", " else:\n", " self.static = static\n", @@ -206,7 +206,14 @@ " return False\n", " return np.allclose(self.data, other.data) and np.array_equal(self.indptr, other.indptr)\n", "\n", - "\n", + " def _as_torch_copy(\n", + " self,\n", + " x: Union[np.ndarray, torch.Tensor],\n", + " dtype: torch.dtype = torch.float32,\n", + " ) -> torch.Tensor:\n", + " if isinstance(x, np.ndarray):\n", + " x = torch.from_numpy(x)\n", + " return x.to(dtype, copy=False).clone()\n", "\n", " def align(self, df: DataFrame, id_col: str, time_col: str, target_col: str) -> 'TimeSeriesDataset':\n", " # Protect consistency\n", @@ -303,7 +310,7 @@ " # Define new dataset\n", " updated_dataset = TimeSeriesDataset(temporal=new_temporal,\n", " temporal_cols= dataset.temporal_cols.copy(),\n", - " indptr=np.array(new_indptr).astype(np.int32),\n", + " indptr=np.array(new_indptr, dtype=np.int32),\n", " max_size=new_max_size,\n", " min_size=new_min_size,\n", " y_idx=dataset.y_idx,\n", diff --git a/neuralforecast/_modidx.py b/neuralforecast/_modidx.py index 208162bd1..5c10130b3 100644 --- a/neuralforecast/_modidx.py +++ b/neuralforecast/_modidx.py @@ -1209,6 +1209,8 @@ 'neuralforecast/tsdataset.py'), 'neuralforecast.tsdataset.TimeSeriesDataset.__repr__': ( 'tsdataset.html#timeseriesdataset.__repr__', 'neuralforecast/tsdataset.py'), + 'neuralforecast.tsdataset.TimeSeriesDataset._as_torch_copy': ( 'tsdataset.html#timeseriesdataset._as_torch_copy', + 'neuralforecast/tsdataset.py'), 'neuralforecast.tsdataset.TimeSeriesDataset.align': ( 'tsdataset.html#timeseriesdataset.align', 'neuralforecast/tsdataset.py'), 'neuralforecast.tsdataset.TimeSeriesDataset.append': ( 'tsdataset.html#timeseriesdataset.append', diff --git a/neuralforecast/common/_base_model.py b/neuralforecast/common/_base_model.py index dc435f156..bc89c1618 100644 --- a/neuralforecast/common/_base_model.py +++ b/neuralforecast/common/_base_model.py @@ -78,7 +78,11 @@ def __init__( **trainer_kwargs, ): super().__init__() - self.save_hyperparameters() # Allows instantiation from a checkpoint from class + with warnings.catch_warnings(record=False): + warnings.filterwarnings("ignore") + # the following line issues a warning about the loss attribute being saved + # but we do want to save it + self.save_hyperparameters() # Allows instantiation from a checkpoint from class self.random_seed = random_seed pl.seed_everything(self.random_seed, workers=True) @@ -202,8 +206,8 @@ def _fit( if self.val_check_steps > self.max_steps: warnings.warn( - "val_check_steps is greater than max_steps, \ - setting val_check_steps to max_steps" + "val_check_steps is greater than max_steps, " + "setting val_check_steps to max_steps." ) val_check_interval = min(self.val_check_steps, self.max_steps) self.trainer_kwargs["val_check_interval"] = int(val_check_interval) @@ -320,9 +324,15 @@ def set_test_size(self, test_size): def on_validation_epoch_end(self): if self.val_size == 0: return - avg_loss = torch.stack(self.validation_step_outputs).mean() - self.log("ptl/val_loss", avg_loss, sync_dist=True) - self.valid_trajectories.append((self.global_step, float(avg_loss))) + losses = torch.stack(self.validation_step_outputs) + avg_loss = losses.mean().item() + self.log( + "ptl/val_loss", + avg_loss, + batch_size=losses.size(0), + sync_dist=True, + ) + self.valid_trajectories.append((self.global_step, avg_loss)) self.validation_step_outputs.clear() # free memory (compute `avg_loss` per epoch) def save(self, path): diff --git a/neuralforecast/common/_base_multivariate.py b/neuralforecast/common/_base_multivariate.py index f24f14bbd..70802c7af 100644 --- a/neuralforecast/common/_base_multivariate.py +++ b/neuralforecast/common/_base_multivariate.py @@ -383,8 +383,14 @@ def training_step(self, batch, batch_idx): print("output", torch.isnan(output).sum()) raise Exception("Loss is NaN, training stopped.") - self.log("train_loss", loss, prog_bar=True, on_epoch=True) - self.train_trajectories.append((self.global_step, float(loss))) + self.log( + "train_loss", + loss.item(), + batch_size=outsample_y.size(0), + prog_bar=True, + on_epoch=True, + ) + self.train_trajectories.append((self.global_step, loss.item())) return loss def validation_step(self, batch, batch_idx): @@ -444,7 +450,13 @@ def validation_step(self, batch, batch_idx): if torch.isnan(valid_loss): raise Exception("Loss is NaN, training stopped.") - self.log("valid_loss", valid_loss, prog_bar=True, on_epoch=True) + self.log( + "valid_loss", + valid_loss.item(), + batch_size=outsample_y.size(0), + prog_bar=True, + on_epoch=True, + ) self.validation_step_outputs.append(valid_loss) return valid_loss diff --git a/neuralforecast/common/_base_recurrent.py b/neuralforecast/common/_base_recurrent.py index b9c167644..334f22e8a 100644 --- a/neuralforecast/common/_base_recurrent.py +++ b/neuralforecast/common/_base_recurrent.py @@ -343,9 +343,13 @@ def training_step(self, batch, batch_idx): raise Exception("Loss is NaN, training stopped.") self.log( - "train_loss", loss, batch_size=self.batch_size, prog_bar=True, on_epoch=True + "train_loss", + loss.item(), + batch_size=outsample_y.size(0), + prog_bar=True, + on_epoch=True, ) - self.train_trajectories.append((self.global_step, float(loss))) + self.train_trajectories.append((self.global_step, loss.item())) return loss def validation_step(self, batch, batch_idx): @@ -438,8 +442,8 @@ def validation_step(self, batch, batch_idx): self.log( "valid_loss", - valid_loss, - batch_size=self.batch_size, + valid_loss.item(), + batch_size=outsample_y.size(0), prog_bar=True, on_epoch=True, ) diff --git a/neuralforecast/common/_base_windows.py b/neuralforecast/common/_base_windows.py index da5686ff1..ea2ba71bb 100644 --- a/neuralforecast/common/_base_windows.py +++ b/neuralforecast/common/_base_windows.py @@ -434,8 +434,14 @@ def training_step(self, batch, batch_idx): print("output", torch.isnan(output).sum()) raise Exception("Loss is NaN, training stopped.") - self.log("train_loss", loss, prog_bar=True, on_epoch=True) - self.train_trajectories.append((self.global_step, float(loss))) + self.log( + "train_loss", + loss.item(), + batch_size=outsample_y.size(0), + prog_bar=True, + on_epoch=True, + ) + self.train_trajectories.append((self.global_step, loss.item())) return loss def _compute_valid_loss( @@ -531,13 +537,20 @@ def validation_step(self, batch, batch_idx): batch_sizes.append(len(output_batch)) valid_loss = torch.stack(valid_losses) - batch_sizes = torch.tensor(batch_sizes).to(valid_loss.device) - valid_loss = torch.sum(valid_loss * batch_sizes) / torch.sum(batch_sizes) + batch_sizes = torch.tensor(batch_sizes, device=valid_loss.device) + batch_size = torch.sum(batch_sizes) + valid_loss = torch.sum(valid_loss * batch_sizes) / batch_size if torch.isnan(valid_loss): raise Exception("Loss is NaN, training stopped.") - self.log("valid_loss", valid_loss, prog_bar=True, on_epoch=True) + self.log( + "valid_loss", + valid_loss.item(), + batch_size=batch_size, + prog_bar=True, + on_epoch=True, + ) self.validation_step_outputs.append(valid_loss) return valid_loss diff --git a/neuralforecast/core.py b/neuralforecast/core.py index f0a52224b..b4f4ad1e8 100644 --- a/neuralforecast/core.py +++ b/neuralforecast/core.py @@ -14,6 +14,7 @@ import fsspec import numpy as np import pandas as pd +import pytorch_lightning as pl import torch import utilsforecast.processing as ufp from coreforecast.grouped_array import GroupedArray @@ -59,6 +60,11 @@ ) # %% ../nbs/core.ipynb 5 +# this disables warnings about the number of workers in the dataloaders +# which the user can't control +pl.disable_possible_user_warnings() + + def _insample_times( times: np.ndarray, uids: Series, diff --git a/neuralforecast/models/deepar.py b/neuralforecast/models/deepar.py index 8de22369c..8721542d9 100644 --- a/neuralforecast/models/deepar.py +++ b/neuralforecast/models/deepar.py @@ -278,8 +278,14 @@ def training_step(self, batch, batch_idx): print("output", torch.isnan(output).sum()) raise Exception("Loss is NaN, training stopped.") - self.log("train_loss", loss, prog_bar=True, on_epoch=True) - self.train_trajectories.append((self.global_step, float(loss))) + self.log( + "train_loss", + loss.item(), + batch_size=outsample_y.size(0), + prog_bar=True, + on_epoch=True, + ) + self.train_trajectories.append((self.global_step, loss.item())) self.h = self.horizon_backup # Restore horizon return loss @@ -339,12 +345,19 @@ def validation_step(self, batch, batch_idx): valid_loss = torch.stack(valid_losses) batch_sizes = torch.tensor(batch_sizes, device=valid_loss.device) - valid_loss = torch.sum(valid_loss * batch_sizes) / torch.sum(batch_sizes) + batch_size = torch.sum(batch_sizes) + valid_loss = torch.sum(valid_loss * batch_sizes) / batch_size if torch.isnan(valid_loss): raise Exception("Loss is NaN, training stopped.") - self.log("valid_loss", valid_loss, prog_bar=True, on_epoch=True) + self.log( + "valid_loss", + valid_loss.item(), + batch_size=batch_size, + prog_bar=True, + on_epoch=True, + ) self.validation_step_outputs.append(valid_loss) return valid_loss diff --git a/neuralforecast/tsdataset.py b/neuralforecast/tsdataset.py index 7886ddfd8..824ed16ef 100644 --- a/neuralforecast/tsdataset.py +++ b/neuralforecast/tsdataset.py @@ -6,7 +6,7 @@ # %% ../nbs/tsdataset.ipynb 4 import warnings from collections.abc import Mapping -from typing import List, Optional +from typing import List, Optional, Union import numpy as np import pandas as pd @@ -89,11 +89,11 @@ def __init__( sorted=False, ): super().__init__() - self.temporal = torch.tensor(temporal, dtype=torch.float) + self.temporal = self._as_torch_copy(temporal) self.temporal_cols = pd.Index(list(temporal_cols)) if static is not None: - self.static = torch.tensor(static, dtype=torch.float) + self.static = self._as_torch_copy(static) self.static_cols = static_cols else: self.static = static @@ -145,6 +145,15 @@ def __eq__(self, other): self.indptr, other.indptr ) + def _as_torch_copy( + self, + x: Union[np.ndarray, torch.Tensor], + dtype: torch.dtype = torch.float32, + ) -> torch.Tensor: + if isinstance(x, np.ndarray): + x = torch.from_numpy(x) + return x.to(dtype, copy=False).clone() + def align( self, df: DataFrame, id_col: str, time_col: str, target_col: str ) -> "TimeSeriesDataset": @@ -256,7 +265,7 @@ def trim_dataset(dataset, left_trim: int = 0, right_trim: int = 0): updated_dataset = TimeSeriesDataset( temporal=new_temporal, temporal_cols=dataset.temporal_cols.copy(), - indptr=np.array(new_indptr).astype(np.int32), + indptr=np.array(new_indptr, dtype=np.int32), max_size=new_max_size, min_size=new_min_size, y_idx=dataset.y_idx,