[53d15f]: / Production / se_resnext101_32x4d-Copy1.ipynb

Download this file

2096 lines (2095 with data), 157.2 kB

{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/reina/anaconda3/envs/RSNA/lib/python3.6/importlib/_bootstrap.py:219: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__\n",
      "  return f(*args, **kwds)\n",
      "/home/reina/anaconda3/envs/RSNA/lib/python3.6/importlib/_bootstrap.py:219: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__\n",
      "  return f(*args, **kwds)\n"
     ]
    }
   ],
   "source": [
    "from __future__ import absolute_import\n",
    "from __future__ import division\n",
    "from __future__ import print_function\n",
    "\n",
    "\n",
    "import numpy as np # linear algebra\n",
    "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
    "import os\n",
    "import datetime\n",
    "import seaborn as sns\n",
    "import pydicom\n",
    "import time\n",
    "import gc\n",
    "import operator \n",
    "from apex import amp \n",
    "import matplotlib.pyplot as plt\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.utils.data as D\n",
    "import torch.nn.functional as F\n",
    "from sklearn.model_selection import KFold\n",
    "from tqdm import tqdm, tqdm_notebook\n",
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = \"all\"\n",
    "import warnings\n",
    "warnings.filterwarnings(action='once')\n",
    "import pickle\n",
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "%matplotlib inline\n",
    "from skimage.io import imread,imshow\n",
    "from helper import *\n",
    "from apex import amp\n",
    "import helper\n",
    "import torchvision.models as models\n",
    "import pretrainedmodels\n",
    "from torch.optim import Adam\n",
    "from defenitions import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "SEED = 8153\n",
    "device=device_by_name(\"Tesla\")\n",
    "#device=device_by_name(\"RTX\")\n",
    "#device = \"cpu\"\n",
    "torch.cuda.set_device(device)\n",
    "sendmeemail=Email_Progress(my_gmail,my_pass,to_email,'se_resnext101_32x4d-folds results')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_submission(test_df,pred,do_sigmoid=True):\n",
    "    if do_sigmoid:\n",
    "        func = lambda x:torch.sigmoid(x)\n",
    "    else:\n",
    "        func = lambda x:x\n",
    "    epidural_df=pd.DataFrame(data={'ID':'ID_'+test_df.PatientID.values+'_epidural','Label':func(pred[:,0])})\n",
    "    intraparenchymal_df=pd.DataFrame(data={'ID':'ID_'+test_df.PatientID.values+'_intraparenchymal','Label':func(pred[:,1])})\n",
    "    intraventricular_df=pd.DataFrame(data={'ID':'ID_'+test_df.PatientID.values+'_intraventricular','Label':func(pred[:,2])})\n",
    "    subarachnoid_df=pd.DataFrame(data={'ID':'ID_'+test_df.PatientID.values+'_subarachnoid','Label':func(pred[:,3])})\n",
    "    subdural_df=pd.DataFrame(data={'ID':'ID_'+test_df.PatientID.values+'_subdural','Label':func(pred[:,4])})\n",
    "    any_df=pd.DataFrame(data={'ID':'ID_'+test_df.PatientID.values+'_any','Label':func(pred[:,5])}) \n",
    "    return pd.concat([epidural_df,\n",
    "                        intraparenchymal_df,\n",
    "                        intraventricular_df,\n",
    "                        subarachnoid_df,\n",
    "                        subdural_df,\n",
    "                        any_df]).sort_values('ID').reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(674510, 15)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(674252, 15)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>PatientID</th>\n",
       "      <th>epidural</th>\n",
       "      <th>intraparenchymal</th>\n",
       "      <th>intraventricular</th>\n",
       "      <th>subarachnoid</th>\n",
       "      <th>subdural</th>\n",
       "      <th>any</th>\n",
       "      <th>PID</th>\n",
       "      <th>StudyI</th>\n",
       "      <th>SeriesI</th>\n",
       "      <th>WindowCenter</th>\n",
       "      <th>WindowWidth</th>\n",
       "      <th>ImagePositionZ</th>\n",
       "      <th>ImagePositionX</th>\n",
       "      <th>ImagePositionY</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>63eb1e259</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>a449357f</td>\n",
       "      <td>62d125e5b2</td>\n",
       "      <td>0be5c0d1b3</td>\n",
       "      <td>['00036', '00036']</td>\n",
       "      <td>['00080', '00080']</td>\n",
       "      <td>180.199951</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-8.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2669954a7</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>363d5865</td>\n",
       "      <td>a20b80c7bf</td>\n",
       "      <td>3564d584db</td>\n",
       "      <td>['00047', '00047']</td>\n",
       "      <td>['00080', '00080']</td>\n",
       "      <td>922.530821</td>\n",
       "      <td>-156.0</td>\n",
       "      <td>45.572849</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>52c9913b1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9c2b4bd7</td>\n",
       "      <td>3e3634f8cf</td>\n",
       "      <td>973274ffc9</td>\n",
       "      <td>40</td>\n",
       "      <td>150</td>\n",
       "      <td>4.455000</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-115.063000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4e6ff6126</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3ae81c2d</td>\n",
       "      <td>a1390c15c2</td>\n",
       "      <td>e5ccad8244</td>\n",
       "      <td>['00036', '00036']</td>\n",
       "      <td>['00080', '00080']</td>\n",
       "      <td>100.000000</td>\n",
       "      <td>-99.5</td>\n",
       "      <td>28.500000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>7858edd88</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>c1867feb</td>\n",
       "      <td>c73e81ed3a</td>\n",
       "      <td>28e0531b3a</td>\n",
       "      <td>40</td>\n",
       "      <td>100</td>\n",
       "      <td>145.793000</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-132.190000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   PatientID  epidural  intraparenchymal  intraventricular  subarachnoid  \\\n",
       "0  63eb1e259         0                 0                 0             0   \n",
       "1  2669954a7         0                 0                 0             0   \n",
       "2  52c9913b1         0                 0                 0             0   \n",
       "3  4e6ff6126         0                 0                 0             0   \n",
       "4  7858edd88         0                 0                 0             0   \n",
       "\n",
       "   subdural  any       PID      StudyI     SeriesI        WindowCenter  \\\n",
       "0         0    0  a449357f  62d125e5b2  0be5c0d1b3  ['00036', '00036']   \n",
       "1         0    0  363d5865  a20b80c7bf  3564d584db  ['00047', '00047']   \n",
       "2         0    0  9c2b4bd7  3e3634f8cf  973274ffc9                  40   \n",
       "3         0    0  3ae81c2d  a1390c15c2  e5ccad8244  ['00036', '00036']   \n",
       "4         0    0  c1867feb  c73e81ed3a  28e0531b3a                  40   \n",
       "\n",
       "          WindowWidth  ImagePositionZ  ImagePositionX  ImagePositionY  \n",
       "0  ['00080', '00080']      180.199951          -125.0       -8.000000  \n",
       "1  ['00080', '00080']      922.530821          -156.0       45.572849  \n",
       "2                 150        4.455000          -125.0     -115.063000  \n",
       "3  ['00080', '00080']      100.000000           -99.5       28.500000  \n",
       "4                 100      145.793000          -125.0     -132.190000  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_df = pd.read_csv(data_dir+'train.csv')\n",
    "train_df.shape\n",
    "train_df=train_df[~train_df.PatientID.isin(bad_images)].reset_index(drop=True)\n",
    "train_df=train_df.drop_duplicates().reset_index(drop=True)\n",
    "train_df.shape\n",
    "train_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>PatientID</th>\n",
       "      <th>epidural</th>\n",
       "      <th>intraparenchymal</th>\n",
       "      <th>intraventricular</th>\n",
       "      <th>subarachnoid</th>\n",
       "      <th>subdural</th>\n",
       "      <th>any</th>\n",
       "      <th>SeriesI</th>\n",
       "      <th>PID</th>\n",
       "      <th>StudyI</th>\n",
       "      <th>WindowCenter</th>\n",
       "      <th>WindowWidth</th>\n",
       "      <th>ImagePositionZ</th>\n",
       "      <th>ImagePositionX</th>\n",
       "      <th>ImagePositionY</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>28fbab7eb</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>ebfd7e4506</td>\n",
       "      <td>cf1b6b11</td>\n",
       "      <td>93407cadbb</td>\n",
       "      <td>30</td>\n",
       "      <td>80</td>\n",
       "      <td>158.458000</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-135.598000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>877923b8b</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>6d95084e15</td>\n",
       "      <td>ad8ea58f</td>\n",
       "      <td>a337baa067</td>\n",
       "      <td>30</td>\n",
       "      <td>80</td>\n",
       "      <td>138.729050</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-101.797981</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>a591477cb</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>8e06b2c9e0</td>\n",
       "      <td>ecfb278b</td>\n",
       "      <td>0cfe838d54</td>\n",
       "      <td>30</td>\n",
       "      <td>80</td>\n",
       "      <td>60.830002</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-133.300003</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>42217c898</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>e800f419cf</td>\n",
       "      <td>e96e31f4</td>\n",
       "      <td>c497ac5bad</td>\n",
       "      <td>30</td>\n",
       "      <td>80</td>\n",
       "      <td>55.388000</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-146.081000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>a130c4d2f</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>faeb7454f3</td>\n",
       "      <td>69affa42</td>\n",
       "      <td>854e4fbc01</td>\n",
       "      <td>30</td>\n",
       "      <td>80</td>\n",
       "      <td>33.516888</td>\n",
       "      <td>-125.0</td>\n",
       "      <td>-118.689819</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   PatientID  epidural  intraparenchymal  intraventricular  subarachnoid  \\\n",
       "0  28fbab7eb       0.5               0.5               0.5           0.5   \n",
       "1  877923b8b       0.5               0.5               0.5           0.5   \n",
       "2  a591477cb       0.5               0.5               0.5           0.5   \n",
       "3  42217c898       0.5               0.5               0.5           0.5   \n",
       "4  a130c4d2f       0.5               0.5               0.5           0.5   \n",
       "\n",
       "   subdural  any     SeriesI       PID      StudyI WindowCenter WindowWidth  \\\n",
       "0       0.5  0.5  ebfd7e4506  cf1b6b11  93407cadbb           30          80   \n",
       "1       0.5  0.5  6d95084e15  ad8ea58f  a337baa067           30          80   \n",
       "2       0.5  0.5  8e06b2c9e0  ecfb278b  0cfe838d54           30          80   \n",
       "3       0.5  0.5  e800f419cf  e96e31f4  c497ac5bad           30          80   \n",
       "4       0.5  0.5  faeb7454f3  69affa42  854e4fbc01           30          80   \n",
       "\n",
       "   ImagePositionZ  ImagePositionX  ImagePositionY  \n",
       "0      158.458000          -125.0     -135.598000  \n",
       "1      138.729050          -125.0     -101.797981  \n",
       "2       60.830002          -125.0     -133.300003  \n",
       "3       55.388000          -125.0     -146.081000  \n",
       "4       33.516888          -125.0     -118.689819  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_df = pd.read_csv(data_dir+'test.csv')\n",
    "test_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "split_sid = train_df.PID.unique()\n",
    "splits=list(KFold(n_splits=3,shuffle=True, random_state=SEED).split(split_sid))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "pickle_file=open(outputs_dir+\"PID_splits.pkl\",'wb')\n",
    "pickle.dump((split_sid,splits),pickle_file,protocol=4)\n",
    "pickle_file.close()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_loss(y_pred,y_true,weights):\n",
    "    if len(y_pred.shape)==len(y_true.shape):\n",
    "        loss = F.binary_cross_entropy_with_logits(y_pred,y_true,weights.expand_as(y_pred))\n",
    "    else:\n",
    "        loss0 = F.binary_cross_entropy_with_logits(y_pred,y_true[...,0],weights.repeat(y_pred.shape[0],1),reduction='none')\n",
    "        loss1 = F.binary_cross_entropy_with_logits(y_pred,y_true[...,1],weights.repeat(y_pred.shape[0],1),reduction='none')\n",
    "        loss = (y_true[...,2]*loss0+(1.0-y_true[...,2])*loss1).mean() \n",
    "    return loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "class parameter_scheduler():\n",
    "    def __init__(self,model,do_first=['classifier'],num_epoch=1):\n",
    "        self.model=model\n",
    "        self.do_first = do_first\n",
    "        self.num_epoch=num_epoch\n",
    "    def __call__(self,epoch):\n",
    "        if epoch>=self.num_epoch:\n",
    "            for n,p in self.model.named_parameters():\n",
    "                p.requires_grad=True\n",
    "        else:\n",
    "            for n,p in self.model.named_parameters():\n",
    "                p.requires_grad= any(nd in n for nd in self.do_first)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_optimizer_parameters(model,klr):\n",
    "    param_optimizer = list(model.named_parameters())\n",
    "    num_blocks=5\n",
    "    no_decay=['bias']\n",
    "    optimizer_grouped_parameters=[\n",
    "        {'params': [p for n, p in param_optimizer if (not any(nd in n for nd in no_decay) and ('classifier' in n))], 'lr':klr*2e-4,'weight_decay': 0.01},\n",
    "        {'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)  and ('classifier' in n)], 'lr':klr*2e-4, 'weight_decay': 0.0}\n",
    "        ]\n",
    "    optimizer_grouped_parameters.extend([\n",
    "        {'params': [p for n, p in param_optimizer if (not any(nd in n for nd in no_decay) and ('wso' in n))], 'lr':klr*5e-6,'weight_decay': 0.01},\n",
    "        {'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)  and ('wso' in n)], 'lr':klr*5e-6, 'weight_decay': 0.0}\n",
    "        ])\n",
    "    for i in range(num_blocks):\n",
    "        optimizer_grouped_parameters.extend([\n",
    "        {'params': [p for n, p in param_optimizer if (not any(nd in n for nd in no_decay) and ('layer{}'.format(i) in n))], 'lr':klr*(2.0**i)*1e-5,'weight_decay': 0.01},\n",
    "        {'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)  and ('layer{}'.format(i) in n)], 'lr':klr*(2.0**i)*1e-5, 'weight_decay': 0.0}\n",
    "        ])\n",
    "    return(optimizer_grouped_parameters)\n",
    "\n",
    "     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x7f6d9705c610>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(449019,)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(225233,)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to  previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAPwCAYAAADH/tkFAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAOR0SURBVHhe7N0HnNxlnT/wJz0QQu+99yJFUAELKHYP+9n1r3fnqSeWO/uJHRULh6IiYkFFsYIivbfQewshoSSUVEp62c3/eWafdWdnZ3ZnZmd2Z3bfb15f5/v7JWTDtpjPfOf7BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKBljMmPMBI8FGv9WA8XrgAAAAAYrB1jPRtrp8IV1EgAzUiycJ111tl4r732ypcAAAAADMZ9990Xli9fvii2m3TdgdoIoBlJbjkouuWWW/IlAAAAAINx8MEHh1uj1HbdgdqMzY8AAAAAANBQAmgAAAAAAJpCAA0AAAAAQFMIoAEAAAAAaAoBNAAAAAAATSGABgAAAACgKQTQAAAAAAA0hQAaAAAAAICmEEADAAAAANAUAmgAAAAAAJpCAA0AAAAAQFMIoAEAAAAAaAoBNAAAAAAATSGABgAAAACgKQTQAAAAAAA0hQAaAAAAAICmEEADAAAAANAUAmgAAAAAAJpCAA0AAAAAQFMIoAEAAAAAaAoBNAAAAAAATSGABgAAAACgKQTQAAAAAAA0hQAaAAAAAICmEEADAAAAANAUAmgAAAAAAJpCAD06bRvr57Eej7Uy1sOxToq1UaxqTIn1jlhnxro/1tJYi2PdHOuTsSbGqmTvWH+INS/WiljTY3051jqxAAAAAIARRAA9+uwS65ZY74t1Y6zvx5oV67hY02JtEmsgR8b6TayXx7o71g9i/S7WNrG+E+vyWJNjlTos1k2xjo11Saz/i/VsrC/GujjWpFgAAAAAwAghgB59fhRr81gfjZWC4M/EOipWCqL3iPX1WAN5MtY7Y20V602x0q/x77F2j3VrrBfE+nCsYuNi/SLWurHSv/P2WJ+OlULpP8c6PNbHYwEAAAAAI4QAenTZOdYxsdLKjVPSjSLHx0qrNN4VK63Y6M/tsX4ba1Xhqkdaw/Hdrja8OD92e1GsvWJdFetv6UbWGetTXW34YKwxXS0AAAAA0O4E0KNLmnROLoqVgt9iKTy+NlaaUH5eulGn1flxTX7s1v22L8iPxdIKkAdi7RArheQAAAAAwAgggB5d0oqNJIW95czIj2mVRr3+X34sDZqH4m2PCO/42fVhny9eMGC9+MTLw5UPzM//FgAAAAC0HgH06LJBfnwmP5bqvr9hfqzVR2K9IlZa0fHzdKNII992OkSxXO0Zq+0tX9URllZRDy9cFk65/MH8bwEAAABA6xFAU6x7//La/FiLN8Q6KVY6oPCNsbpXcVRrMG971Hp2ea3vZgAAAAAYOgLo0aV7yrh7GrnU+vmx0pRyJcfG+n2sebHS4YNpp3OpRr7tgyvU/bHa3m8+cFi4+8svr1h//dAL8s8MoXOtvB4AAACA1iWAHl2m58dKe5Z3y4+V9jSX8+ZYf4w1N9aLYnW/jVLNeNsj0roTx4f1JvVf3TrlzwAAAAC0MAH06HJ5fjwmVunHfmqsw2Mtj3V9ulGFt8f6XazHY6XwufsgwXIuy49pR3SpnWOlYPqRWOWmpykyZkz3thIT0AAAAAC0NgH06DIz1kWxdoz14XSjyJdjTYl1Rqyl6UaWDvYrd7jfe2L9OtajsV4Ya6Dg+MpY98VKP/d16UaWPge/1dWGn8SSqA5gbE/+HOTPAAAAALQyAfTo86FYaVfzybHOjnVCrDSd/PFYaf3F52MVS6FxqmIvifXzWOnzJ01Vvy/Wl0rqY7GKdcRKP29ZrD/FOjPWN2PdEOtNsa6N9f1YDGBs0QT0QwuKnysAAAAAgNYigB590hT0IbF+GeuwWJ+MtUusFEg/P9bCWAPZIVb3587/i3V8mSoNoJMUNj831jmx0hqQFHqnQwm/EutlsVbGYgDFAXSy1hg0AAAAAC1KAD06zY6VppG3ijUxVgqUj4u1KFaplHb2Tjy7wuvu+5Uqrfko595Y6eDCTWNNipV2P6fAOu2epgol+bODCAEAAABoWQJoaHMdEmgAAAAAWpQAGtrM2OJTCKNOKzgAAAAAaFECaGgzJRs4gvwZAAAAgFYlgIY2U3oIYYcEGgAAAIAWJYCGNtP3EEIBNAAAAACtSQANbaZPAO0QQgAAAABalAAa2syYki3Q8mcAAAAAWpUAGtpM6QR0hwQaAAAAgBYlgIY2U3oI4dr4DwAAAAC0IgE0tJmSAejgDEIAAAAAWpUAGtpMnwloATQAAAAALUoADe2mZAS6UwINAAAAQIsSQEObGSuABgAAAKBNCKChzUwc3/vLVv4MAAAAQKsSQEObmTR+XO66CKABAAAAaFUCaGhD22+8bu5CWBv/AQAAAIBWJICGNlS8B7pT/gwAAABAixJAQxsaM6YngXYIIQAAAACtSgANbagof7YDGgAAAICWJYCGNlSUP4e1EmgAAAAAWpQAGtrQ2F4rOHIDAAAAAC1GAA1tqDiAXhv/AQAAAIBWJICGNlS8A7qzMzcAAAAA0GIE0NCGxpiABgAAAKANCKChDY0tmoB2BiEAAAAArUoADW2o1woOCTQAAAAALUoADW2o1yGE8mcAAAAAWpQAGtpQ0QC0CWgAAAAAWpYAGtpQ70MIAQAAAKA1CaChDfU+hFAEDQAAAEBrEkBDGyqegO6UPwMAAADQogTQ0IZ6T0DnBgAAAABajAAa2tCYomMIHUIIAAAAQKsSQEMbKtrAYQIaAAAAgJYlgIY2NLYogXYIIQAAAACtSgANbah4AtohhAAAAAC0KgE0tKFeE9DxHwAAAABoRQJoaEMmoAEAAABoBwJoaENjihLoTjugAQAAAGhRAmhoQ2OLJqBt4AAAAACgVQmgoQ0V588moAEAAABoVQJoaEO9DiGUPwMAAADQogTQ0IbsgAYAAACgHQigoQ0V5c+hU/4MAAAAQIsSQEMb6nUIoVMIAQAAAGhRAmhoQ2OKjiE0AQ0AAABAqxJAQxsaW/SVawU0AAAAAK1KAA1tyCGEAAAAALQDATS0oeIV0AJoAAAAAFqVABra0NiiCWgAAAAAaFUCaGhDxfmzCWgAAAAAWpUAGtpQ8QS0/BkAAACAViWAhjbUewI6NwAAAADQYgTQ0IbGFB1DaAUHAAAAAK1KAA1taGzxGYTyZwAAAABalAAa2pBDCAEAAABoBwJoaEPFhxDaAQ0AAABAqxJAQxsaUxRAr7WDAwAAAIAWJYCGNtR7BUduAAAAAKDFCKChDfU+hFACDQAAAEBrEkBDG3pg7pLchfDIwmW5AwAAAIDWIoCGNnTjQ4tyF8LPrnkodwAAAADQWgTQAAAAAAA0hQAaAAAAAICmEEADAAAAANAUAmhoc2PH5AYAAAAAWowAGtrQ+w7fMXchfODInXMHAAAAAK1FAA1taON1J+YuhInjfBkDAAAA0JokV9CGxhbt3ehcuzZ3AAAAANBaBNDQhsYU7X3ulD8DAAAA0KIE0NCGxhYl0CagAQAAAGhVAmhoQ0UbOMJaATQAAAAALUoADW2o9wR0bgAAAACgxQigoQ2NKQqgOyTQAAAAALQoATS0ISs4AAAAAGgHAmhoQ+OKEmgD0AAAAAC0KgE0tKHiFRydJqABAAAAaFEC6NFp21g/j/V4rJWxHo51UqyNYlXrZbG+G+vSWItipRT0mlj9GRfrHbGujvVkrGWxHoj1i1j7xKJKxSs4TEADAAAA0KoE0KPPLrFuifW+WDfG+n6sWbGOizUt1iaxqvHhWJ+I9YJYj6UbVTgz1m9i7RjrL7F+EOvBWO+JdWuso2JRhbFFE9B2QAMAAADQqgTQo8+PYm0e66Oxjo31mVgp+E1B9B6xvh6rGt+KtW+s9WK9Nt0YwHNjvSXWPbHS2/lQrE/HelWs98eaGOsLsahC7wloATQAAAAArUkAPbrsHOuYWGnlxinpRpHjYy2N9a5YU9KNAaRp6RQmdxSuBpbedpJWdqTVG8XOyY+b5UcG0HsHdG4AAAAAoMUIoEeX7hUXF8Xq7Gr/aXGsa2OtG+t56UaDpbA6Sb+Hdbraf3pNfrwkPzKA4hUcnRJoAAAAAFqUAHp0SasvknTwXzkz8uPu+bGR7o6V1nyktR33x0oT2N+M9fdYp8f6fSwrOKo0rugr1woOAAAAAFqVAHp02SA/PpMfS3Xf3zA/Nlo6tPCDsdKqje4d0Gn6+Y5Yv4qVVoBUIx2iWK72jDUq9JqAlj8DAAAA0KIE0BTrTjWbEWmmX/vkWGny+Suxtos1NdaRsdLbOz/Wh2NRhd47oCXQAAAAALQmAfTo0j3h3D0JXWr9/FhpQnow3hPrv2KlEDqt3pgTa0msa2K9NtbyWOn+erEGcnCFSqs9RoWxPflzkD8DAAAA0KoE0KPL9PxYacfzbvmx0o7oweg+aPDy/FjsyVgpPE7hc/eeavrRewWHBBoAAACA1iSAHl26w99jYpV+7NM6jMNjpUnk69ONBpuUH9P+53K676/Kj/SjeAJaAA0AAABAqxJAjy4zY10Ua8dYpfuWvxxrSqwzYhUfBpgO9mvE4X5X58d0EGHpCpB0MOG2sdIk9L3pBv0r3gHd0ZkbAAAAAGgxAujR50Ox5sVKu5jPjnVCrMtifTxWWr3x+VjF7stV6ohYv8z1nXQjSis8uu+lKvajWHfG2idWejunxTox1qWxfhyrI1YKxdMjAyhewbHWBDQAAAAALUoAPfqkKehDYqWA+LBYn4y1S6wUSD8/1sJY1dg1VjpYMNUb041o81jd91IVSwcOphUfx8d6ItbbY30s1l6x/hjrBbH+EosqjCv6yr30/vR8AgAAAAC0HgH06DQ71vtibRVrYqwdYh0Xa1GsUmnUtmjj8D+lALv7xypVqRRCfyXWc2KldR8TYm0d6y2xboxFlcaUvHtNQQMAAADQigTQ0IZKDx6867FncgcAAAAArUMADW2oo7N3AP3YU8tzBwAAAACtQwANbag0gF66ytmNAAAAALQeATS0oY6SFRwrVgugAQAAAGg9AmhoQ6UT0KXXAAAAANAKBNDQhkoD5zUCaAAAAABakAAa2lDfCejO3AEAAABA6xBAQxvqLNkBbQIaAAAAgFYkgIY2VJo3d3QIoAEAAABoPQJoaEObTJmYuy6rTUADAAAA0IIE0NCGXrrXFrnrss2Gk3MHAAAAAK1DAA1taOzYMWHiuJ4v382mTsodAAAAALQOATS0qSN22zR3IXR25gYAAAAAWogAGtrU2DG5iTrX2gENAAAAQOsRQEObGjOmJ4EWPwMAAADQigTQ0KaKJ6DXmoAGAAAAoAUJoKFNjS2agO6UPwMAAADQggTQ0KaKA+gOCTQAAAAALUgADe2qeAVHfgQAAACAViKAhjZVPAFtBzQAAAAArUgADW2q9yGEuQEAAACAFiKAhjbV+xBCCTQAAAAArUcADW1q/uKVuQvh5keeyh0AAAAAtA4BNLSpax5ckLsQzrzh0dwBAAAAQOsQQAMAAAAA0BQCaAAAAAAAmkIADQAAAABAUwigAQAAAABoCgE0AAAAAABNIYAGAAAAAKApBNAAAAAAADSFABoAAAAAgKYQQAMAAAAA0BQCaAAAAAAAmkIADQAAAABAUwigAQAAAABoCgE0AAAAAABNIYAGAAAAAKApBNAAAAAAADSFABoAAAAAgKYQQAMAAAAA0BQCaAAAAAAAmkIADQAAAABAUwigoU2NGZMbAAAAAGhRAmhoU285eLvcAQAAAEBrEkBDm/r0K/fMHQAAAAC0JgE0tKkN1pmQu/iFbB0HAAAAAC1IAA1tqjh07lybGwAAAABoIQJoaFNjSk4hXLtWCg0AAABAaxFAQxsrzqDlzwAAAAC0GgE0tLGxRQl0pwQaAAAAgBYjgIY2Zg80AAAAAK1MAA1tbEz8p5sJaAAAAABajQAa2ljJOYQAAAAA0FIE0NDG7IAGAAAAoJUJoKGN2QENAAAAQCsTQEMbG2MCGgAAAIAWJoCGNla8A1r+DAAAAECrEUBDG1u8Yk3uUgAtgQYAAACgtQigYYR4YO6S3AEAAABAaxBAwwhxxfR5uQMAAACA1iCAhhHisaeX5w4AAAAAWoMAGkaIc25/PHcAAAAA0BoE0AAAAAAANIUAGgAAAACAphBAAwAAAADQFAJoAAAAAACaQgANAAAAAEBTCKABAAAAAGgKATQAAAAAAE0hgAYAAAAAoCkE0AAAAAAANIUAGgAAAACAphBAAwAAAADQFAJoAAAAAACaQgANAAAAAEBTCKABAAAAAGgKATS0sU3Xm5g7AAAAAGg9AujRadtYP4/1eKyVsR6OdVKsjWJV62Wxvhvr0liLYq2NdU2sarwu1vmx5sdKb392rL/Fel4sarBgyarcAQAAAEDrEUCPPrvEuiXW+2LdGOv7sWbFOi7WtFibxKrGh2N9ItYLYj2WblQhfb79NNY5sfaJ9ZdYKcS+KFb6fR0cCwAAAAAYIQTQo8+PYm0e66Oxjo31mVhHxUpB9B6xvh6rGt+KtW+s9WK9Nt2owidj/VusX8faNdZ/xPpcrPfHSoF0CqcBAAAAgBFCAD267BzrmFhp5cYp6UaR42MtjfWuWFPSjQGkael7YnUUrga2fqwvxpoTK4XQ5XZHrM6PVGmbDdfJHQAAAAC0HgH06JImnZO08qKzq/2nxbGujbVurGbsYk57n9O09O9jpc+7N8VK09dplccBsajDWF/BAAAAALQw8dXoklZsJA/kx1Iz8uPu+bGRnpsf05TzfbH+GOuEWD+MdXusP8VK4Xc10g7rcrVnrFFl3JgxuQMAAACA1iOAHl02yI/P5MdS3fc3zI+NlPZOJ5+KNT/WYbGm5sebY70xVtpPTQ3WnTg+dwAAAADQegTQFOsep12bHxtpXH5cHisdWnhjrCX5Ma3nSH3aP71NrIEcXKHujzWqHHvg1rkDAAAAgNYjgB5duiecuyehS6WDApNKE9KD8VR+vD7Wk13tPz0R64ZY6fPxkHSD6rxmfwE0AAAAAK1LAD26TM+PlXY875YfK+2IHozut/10fizVHVCvkx+pwlYbTM5dl7VrmzG8DgAAAAD1EUCPLpfnx2NilX7s0z7mw2OlFRlpSrnRLs2P++THUt33H86PVGHMmDGx8kXUKX8GAAAAoIUIoEeXmbEuirVjrA+nG0W+HGtKrDNiLU03sj1zDdYdsa6NtVesD6QbRdJ1up9+fzelG1RvXFEC3SGBBgAAAKCFCKBHnw/Fmhfr5Fhnxzoh1mWxPh4rrd74fKxi9+UqdUSsX+b6TroRpRUe3fdSlXp/rAWxTot1XqwTY/0jXy+L9d5YHbGowdiiALrTCg4AAAAAWogAevRJU8bpoL8UEB8W65OxdomVAunnx1oYqxq7xnpPrjemG9HmsbrvpSqV9kAfFOv0WAfEOi7WwbF+Fyv9nq6JRY3GFn0VC6ABAAAAaCUC6NFpdqz3xdoq1sRYO8RKYfCiWKXSeG3RluF/SgF2949VqnLS204rN7aJld72lrHeHqvclDVVsIIDAAAAgFYlgIY213sFR24AAAAAoAUIoKHNFeXPIQigAQAAAGghAmhoc2PHFk9AS6ABAAAAaB0CaGhzvVdwCKABAAAAaB0CaGhzRQPQdkADAAAA0FIE0ND2ehLotSagAQAAAGghAmhoc8UT0OJnAAAAAFqJABranB3QAAAAALQqATS0OTugAQAAAGhVAmhoc2OKJ6Al0AAAAAC0EAE0tLmxRV/FNnAAAAAA0EoE0NDmxsR/utkBDQAAAEArEUBDmyveAS1+BgAAAKCVCKChzY0t3gFtAhoAAACAFiKAhjZXlD+HtQJoAAAAAFqIABraXO8J6NwAAAAAQAsQQEObK56AtoIDAAAAgFYigIY2VzwBLX8GAAAAoJUIoKHN3f/k4tyFsLqjM3cAAAAAMPwE0DCC/OHm2bkDAAAAgOEngIYRZO6zK3MHAAAAAMNPAA0jSGdnbUugf37NQ+ETZ90eHlm4NN8BAAAAgMYRQMMI0lHDKYS3PPJU+Mq594a/3PZY+I9f35LvAgAAAEDjCKBhBKllAPrie+fmrvdBhgAAAADQKAJoGEGO2XuL3A1s7JjcAAAAAECTCKChze2+xXq5C2G7jdfN3cDGjpFAAwAAANBcAmhoc1tusE7u0gqO6ndwrKnxwEIAAAAAqJUAGtpcr1UaNWTKpQPQa2sIrwEAAACgGgJoaHPFOXItE9ClO6ANRAMAAADQaAJoaHPFu5xrGWIe0yu6Tis5OnMHAAAAAI0hgIY2V7xKo5YJ6NIVHB1GoAEAAABoMAE0tLkxRUnyYDJk+TMAAAAAjSaAhja3YnVH7kJ4dNHS3A2sOLhOapmeBgAAAIBqCKChzV09Y0HuQvjGeffnbmAlGzjCWiugAQAAAGgwATSMUqU7oE1AAwAAANBoAmgYpcaUzEALoAEAAABoNAE0jFJ9J6BzAwAAAAANIoCGUap0B7QJaAAAAAAaTQANo5Qd0AAAAAA0mwAaKLCCAwAAAIBGE0DDKDWmZAS6UwINAAAAQIMJoIECGzgAAAAAaDQBNIxSdkADAAAA0GwCaBilxsR/inUIoAEAAABoMAE0jFLbb7xu7rqsFUADAAAA0GACaBil1l9nfO66LFyyKncAAAAA0BgCaGhz73reDrkLYadNp+Sudl88557cAQAAAEBjCKChzb1y3y1zF8IW60/KXe2mz12cOwAAAABoDAE0tLkxY3oOE+y0xhkAAACAFiKAhjY3bmxPAF3LQYKlP3XPLafmDgAAAAAaQwANba4ofx7UBPT9T1rBAQAAAEBjCaChzRWv4OiwgwMAAACAFiKAhjZX7woOAAAAAGg2ATS0uUat4AAAAACARhNAQ5sb26AVHFMmjssdAAAAADSGABraXHEA3TmIFRz7brNB7gAAAACgMQTQ0ObGFn0VD2YF9FF7bp47AAAAAGgMATS0uV4rOAZ5COGpV84M37toeliyck2+AwAAAAD1E0BDm2vUCo4/3TInnHD+/eHkyx4MP4wFAAAAAIMlgIY2N7Ynfw6z5i/NXe1mzFuSuxB+cuXM3AEAAABA/QTQ0OaKJ6CT7vUZD8xdHL5/8QPhwXmLC9cAAAAAMNQE0NDmxhWPQEcLFq8Ma9euDW85dVr4v0tnhLeddkP+EQAAAAAYWgJoaHNrOnvvfU7XK9d0hqeXrS5cz8+BNAAAAAAMNQE0tLmVazpy12X5qt7XSUdJSA0AAAAAQ0EADW1ufMkKjlOvmtkncC6dkgYAAACAoSCAhjY3bmzvL+Nz73wizH5qWb7q0mkFBwAAAADDQAANba5kALrgv868LXddrOAAAAAAYDgIoGEEmjFvSe66yJ8BAAAAGA4CaGhzY+I/A+mUQAMAAAAwDATQMAp02AENAAAAwDAQQEOb23i9ibmrzAQ0AAAAAMNBAA1tbr1J43NXmQloAAAAAIaDABpGgQ4T0AAAAAAMAwE0jAKdnbkBAAAAgCEkgIZRwAoOAAAAAIaDABpGgU4BNAAAAADDQAANo0BnmR3QImkAAAAAmk0APTptG+vnsR6PtTLWw7FOirVRrGq9LNZ3Y10aa1GslGdeE6sW/xsr/XupXppu0BxWcAAAAAAwHATQo88usW6J9b5YN8b6fqxZsY6LNS3WJrGq8eFYn4j1gliPpRs1OihWCqCXFK5oqo4yE9AAAAAA0GwC6NHnR7E2j/XRWMfG+kyso2KlIHqPWF+PVY1vxdo31nqxXptu1GByrF/HujnWX9MNmssANAAAAADDQQA9uuwc65hYaeXGKelGkeNjLY31rlhT0o0BpGnpe2J1FK5qc0KsnWK9N1ZnusHgnPqug3NXngAaAAAAgOEggB5d0qRzclGs0uB3caxrY60b63npRpO8JFZa9/HZWA+kGwzeMXtvkbvyOiXQAAAAAAwDAfToklZsJJWC3xn5cff82GgbxPplrKtjnZxu1CntsC5Xe8YalcaMGZO78gTQAAAAAAwHAfTokgLg5Jn8WKr7/ob5sdF+ECsdcpgOQJSIDiFnEAIAAAAwHATQFOseo21GXPmGWGm/9KdizUo3BiEtPC5X98eijLUmoAEAAAAYBgLo0aV7wrl7ErrU+vmx0oR0vTaOdWqsy2L9ON2g8X79/kNz15cJaAAAAACGgwB6dJmeHyvteN4tPzb6cMDtY20aKx2CmA4/THFod70nVnJxrHT9scIVNdt/m8qbU+yABgAAAGA4CKBHl8vz4zGxSj/2U2MdHmt5rOvTjQZaGOv0CtV98OH5sdL13YUrajamn6/mWgPoieN9awAAAABg8KRMo8vMWBfF2jHWh9ONIl+ONSXWGbGWphvZnrkGY3asD1So62Il34uVri8pXFGzsWO6V3j3dcOsRbmrzl5bpucjAAAAAGBwBNCjz4dizYt1cqyzY50QK+1m/nistHrj87GK3Zer1BGxfpnrO+lGlFZ4dN9LxRAaWzl/Dv936YywpiNtP6nO08tX5w4AAAAA6ieAHn3SFPQhsVJAfFisT8baJVYKpJ8fK63LqMausdL+5lRvTDeizWN13+ve7cwQ6W8COlm2uiN3A3tk4bLcAQAAAED9BNCjU1qJ8b5YW8WaGGuHWMfFKrenIaWa5ZLNFGB3/1ilqsZ7Y6Wfa/XGIA2QP4eODgcRAgAAADC0BNAwQgw0Ad1R40GEAAAAADBYAmgYIQYKoDs7BdAAAAAADC0BNIwQ4/o7hTBaI4AGAAAAYIgJoGEE2WOLqbnrq6NzbWEK+rGnl+c7AAAAANBcAmgYQT70kl1y11cKoN/98xvD4d+8LJxw/n35LgAAAAA0jwAaRpBDdtw4d309OG9JuObBBYX+1CtnFR4r2WzqpNwBAAAAQP0E0DCCrDdpfO76Wra6I3ddnl62Knd9rV1rXzQAAAAAgyeAhhGkv3MIS3/ouN/fnru+5M8AAAAANIIAGkaQsWMqJ9C1ZMryZwAAAAAaQQANI0h/AfT4/sajS3QagQYAAACgAQTQMIL0kz+HmfOW5G5gHZ0CaAAAAAAGTwANI8iEcZW/pE+54sHcDaxTAA0AAABAAwigYQQZ18+ajTUd1YfKHVZwAAAAANAAAmgYYU580/5hzy2n5qsea2qYaraCAwAAAIBGEEDDCPPmQ7YLF3zshfmqPgJoAAAAABpBAA30kfLntdZwAAAAADBIAmigLFPQAAAAAAyWABooy0GEAAAAAAyWABooywQ0AAAAAIMlgAbKWrm6M3cAAAAAUB8BNIxQP3rHQbmrz1Uz5ucOAAAAAOojgIYR6uX7bJm7+ljBAQAAAMBgCaBhhBo3dkzu6uMMQgAAAAAGSwANlLXHllNzBwAAAAD1EUADZU0a79sDAAAAAIMjYQLKsoEDAAAAgMESQANldVoCDQAAAMAgCaCBsu59/NncAQAAAEB9BNAwgr1iny1zV7vL7p+XOwAAAACojwAaRrDn7rRx7mq3YnVn7gAAAACgPgJoGMHGjslNHVas7sgdAAAAANRHAA0j2Ngx9SfQy1atyR0AAAAA1EcADSPY408vz13tlpes4Ei/1ttPuz78x69vDktXCqcBAAAAGJgAGkawP986J3e1K13B8ck/3BGum7kwXHjP3HDyZTPyXQAAAACoTAANI9iqNfUfJPjQgqWho3Ntvgph2qyFuQvh9Ksfyh0AAAAAVCaAhhGsJz6uzx9unh06O9eGRUtX5Ttd1hQF0wAAAABQiQAaRrJB5sTTZi4Mr//RteGQr12c7wAAAABA9QTQQEV/u+PxcMecZ0KrDDw/u2J1eHjB0nwFAAAAQKsTQMMINmZMbprgpocX5W5oPLV0VTj8hMvCi79zRTjn9sfyXQAAAABamQAaRrBmDi6/+SfTcjc0vnPR9LB45ZpCf9zvby88AgAAANDaBNAwgi1e0RXYjgRPLet9ECIAAAAArU8ADSPYpPEj50t8TDP3iQAAAADQFAJoGMGOfc42uWt/4mcAAACA9iOAhhFsJA0NjzUBDQAAANB2BNAwgo2kzFb+DAAAANB+BNDtYc9YH4/1H7E2SDegOiMntZU/AwAAALQfAXRr+WKsJ2JtXLjq8tJYt8X6Tqwfxbo11iaxYECVpob337b9nse44oH5uQMAAACgXQigW8srY90fa1HhqssJsdbGOj7Wj2PtFOu4WDCgSlPDH3rxruH6zx4dzvnw4eHUdx2c79Zu6co1uWu+p5etzh0AAAAA7UIA3Vp2jHVfV1uwTayUDqbJ56/F+kisy2IdGwsG9Mp9t8pdX1tuMDkcsN2G4eX7bBl+/t5DwgbrTMg/Ur07Zj+du+YbN9YSDgAAAIB2I4BuLRvFKp5+PjxWmn4+t3DV5ZZY23e10L8jdts0fPoVaYV4qfRp1eOoPbcIt3whbXupzaf/cmfumq+js/fvGQAAAIDWJ4BuLWnJbZp67vaSWGnvwA2Fqy4TY/m4UbX/fPEuuetRLssdP672T6vZi5bnDgAAAAD6EmS2lttjvS7WvrF2jfXWWNfEKk750pqOdFAh1G1CHWHzcDtkh/QCAQAAAADaiQC6tXw71gax7og1PfffjdVtcqwXx7q5cAVVOu3dh+Suy5G7bZq79rH1huvkDgAAAIB2IYBuLVfHek2ss2P9NdabYp0fq9sLYj0cK/0YVO3oPTcP33nzAYXHSz7xwjB5wrj8I4N3w6yFuWsuZxACAAAAtB8BdOu5INYbY6XwuTRovizWgbH+VLiCKo0dOya86eBtw+nvfW7YdfOp+W5jXPlAWl3efOm/AQAAAID2IoBuH2kB7pSuFlrH2DFDEwwP1dsBAAAAoHEE0K3l6FhpD3TxaWubx7oy1oJYi2J9Lxa0jKHKhccJoAEAAADajgC6tfxXrDfEeqpw1eU7sY6M9WCstGz3uFhviQUNd9hOG+euekMVC4/13QoAAACg7Yh0WssBsa7pagvWiZV2QV8ca49cs2N9MBY03HtesGPuqrd8dUfumssKDobCHbOfDhfd82RY09GZ7wAAAACDIYBuLWndxuNdbcFhsSbH+mXhKoTFsc6NlYJoaLhX7rtl7qp32tUP5a65BNA024PzFod/OeXa8O+/viX87qb0XB8AAAAwWALo1rIyVpp67pZWb6yNdVXhqsuzsWrfkwBVGNPCIe9Y+TNN9qW/3Zu7EP737LtzBwAAAAyGALq1pFHSo7ragjfGmhHrscJVl+1ipQMJYVQZK4GmydZ0WrsBAAAAjSaAbi2/irVfrBtiXZ37M2MVOyjW9K4WGu/41+6du9p1dq4N9z/5bOGx0azgAAAAAGg/AujW8uNYv491SKzDY6V9z9+K1e3QWHvFuqJwBU2wbFX9hwoed9bt4RUnXR3+7Yyb853GGWcCGgAAAKDtCKBby+pYb4+1UawNYv1LrLQXutusWAfG+kHhCppg5vwluavd3+/oOkPz0vvnheWDCLLLMQENAAAA0H4E0K0pHTS4uKvtJe1+viPWM4UraIJxDQp6O9c2dg2HAWgAAACA9iOAbk3rxnpnrO/GOj3W9/L1lFjQVCvWlD+Ibcv1J+dueJiABgAAAGg/AujW86pYj8RKBxJ+PNb7Yn0sXz8c6zWxoGm612iUet/hO+aut6P33LzwuLZk4tkENAAAAAAC6NZyUKy/xNow1m9j/b9Yr8yP6Trd/1Osg2PBkKo0gLzxlImFx86SvLmx8XP8ZiWBBgAAAGg7AujW8vlYKbc7Mta7Y/0y1oX5MV0fESv9+OdiwZAaE/8p54+3zAlHfvuy8IebZ+c7XTpLE+lBKt1NvWTlmtwBAAAA0KoE0K0lBc9/jHV94aqvG2KlCej082BIreknUJ69aHn47F/uylddas2fV1XYPd2tdAJ6weKVuYPGmPPU8twBAAAAjSKAbi0bxOo9RtrXo7HW72ph6PyxZMJ5ILXsgD7hvPvCPsdfEL51wf35Tl8OIaTZBNAAAADQeALo1pJOfzu0q63okFhPdLUwdBYuXRX23HJqvhpYtQF0WtVx6lWzwuqOteHHV8wMHRVGp0tXQNc4YA0AAADAMBBAt5bzYh0V6zOxxqUbRdLH6pOxXhor/TwYcqe+q/rzLzv736hR8MPLZoSdP9f703lNhX+xdAK6lglrAAAAAIaHALq1fDXWk7G+HuvBWGfE+lasX8WaEevbsdKPfy0WDLkdNpkSXr3/VvmqfwMFxIuWrgrfueiBfNWj2ly50YccAgAAANB4AujWksLlw2NdEmuHWO+M9T+x3hVrp1jp/hGxrOCgaf7yoRfkrrfFK1YXHj//qr0KjwMZKIB+eOHS3PVWaQVHqf4ORQQAAACgNQigW8/DsV4ea7tYr4uVwuf0mK7T/YdiQdMctP1G4dtv2j9f9ejOe9dfZ0JXM4CBJpnHVThU8Kllq3LXv2qDagAAAACGjwC6dT0W69xYv82P6bpRto3181jp0MOVsVLofVKsjWJV62Wxvhvr0liLYqU08JpYlWwT679inR8rvb30dhfGujjWG2LRQt5ySHq+o7zSwwArqTcgvuz+ebnrbW3JsYPrTixdkw4AAABAqxFAD68UAtdTp8eq1y6xbon1vlg3xvp+rFmxjos1LdYmsarx4VifiJX2NVQTjqfw+eRYe8S6PNb3Yl0Y68hYf87XtIHSwwArGWgFR6Vfptrg+pFFy3IHAAAAQKsSQA+v9w6i6vWjWJvH+misY2N9JtZRsVIQncLhdABiNdLhiPvGWi/Wa9ONAaSw+8Wxdo6Vwu/Pxnp7rANjPRvr47EOjkWLmzCuum8bc55anrvyxsR/yqkUQJfm2e/7xU25g8Y4bKeNcwcAAAA0igB6eKWDBeupFOLWI/17x8RKKzBOSTeKHB8rnQqXdk5PSTcGkKal74nVUbga2F9iXdnV9nJfrLO62kJATYt60e6bFR7HVbmD490/vzHc+uhT+ap6lVZwQLNVO90PAAAAVE8APbweGUTVI006JxfF6uxq/2lxrGtjrRvreenGEFqdH9fkR1rAGw5Ka7t7/NuRPc97vO3Qyjuii/3br27OXV+Vsr4H5qZPRRh6Y/2JCAAAAA3nr9ujS1qxkTyQH0vNyI+758ehsH6sN8ZKCxZSME6LKJ0GnTSh59vFGw5K51gObOHSVbnrq1IAvfsWU3PXW3WboaF+JqABAACg8QTQo8sG+fGZ/Fiq+/6G+bHZUtrzs1hbxPpxrLSOoxrpEMVytWcsGmTrDSbnrq9q13DU44Dtqvv023ajdXIHAAAAQKsSQFOsO1UcqmHT78Z6c6yrY30i3aB1fOCFvVeNb7jOhNz1fKIMRumhgt2qPQhu0njfvmgsE9AAAADQeBKc0aV7wrl7ErpUWoeRVJqQbqQTY3081lWxXhVrZaxqHVyh7o9Fg6w/eUL4f4enMy9DOGbvLcJuRasxHl20LHf1qxRA//7G2bnrrfTnr+m0lIPGKh3sX9NRuiofAAAAqJUAenSZnh8r7XjeLT9W2hHdKN+P9d+xLo/1ylhLYtGCvvjavcMDX3tl+Om7D8l3utzyyFO5q19nhQT6gnuezF3/Dt5+o9xBY4wpmYD2JAcAAAAMngB6dEmBb3JMrNKPfRpvPTzW8ljXpxtNkNKdU2J9LNbFsV4da/CjtDTVxDKrLtabND539asUQFeytmQzzP7bVhrkBwAAAKBVCKBHl5mxLoq1Y6wPpxtFvhxrSqwzYi1NN7J0sF8jDvdL4fNPY30o1vmxXhcrhd20odcesHXu6tffcOm8Z1fkrrIOw6k0WOmTIjU+RwIAAACUIYAefVIAPC/WybHOjnVCrMtipX3MafXG52MVuy9XqSNi/TLXd9KNKK3w6L6XqtgXY30gVgqdb4/1mVhfKqljY9EGyk1F12ptP+nen26dk7vK+vv3oR6lT4rUOqUPAAAA9CWAHn3SFHRa6JsC4sNifTLWLrFSIP38WAtjVWPXWO/J9cZ0I9o8Vve9VMW6TrMLYZ1Yn411fJkSQLeJsSW7cqtx15xnwtHfvSK87xc3htUdneEX1z6cf6Sv6U8uzl2P0ixQOEijlR5C6HMMAAAABk8APTrNjvW+WFvFmhhrh1jHxVoUq1SKZMqljSnA7v6xSlXsvbHK/ZziSj+HNjCuxgB62syF4bU/vCbMnL80XD59fjhj2iPhH3c9kX+0r1VrOnNXmfPhaLRN15uUuy4+xwAAAGDwBNBAzWodgH7bab3PtbzonidzV975d/f/48n8xStzB81hzQsAAAAMngAaqNnY0l0FNbrhoXLD9rU5/ZqHcgfN8fjTAx+GCQAAAPRPAA3UbJD5M7SFr5x7T+4AAACAegmggZrVsgN6xeqO3A2OdQgMtetnDX5SHwAAAEY7ATRQszE1BNBf/8d9uaveVhtMzh0MHc9xAAAAQOMJoIGa1bKC49fXP5K76m2/8bq56yEcZKhttO6E3AEAAAD1EkADNRvX5CXQsmZawdgaJv0BAACA8gTQQM3GxH+a6cF5S3LXP3uhaabVHZ25AwAAAOolgAZqtrbJM8qLlq7KXY9yb7FT/kwTPbtiTe4AAACAegmggbbVaQIaAAAAoKUJoIGabbBOaxzOJoAGAAAAaG0CaKBmY4bhcLZyWbP8GQAAAKC1CaCBttVhCTRNNG7s0D/RAgAAACONABpoC+UOPrSCg2YSPwMAAMDgCaCBtrVk5ZrcQeO9Yt8tcwcAAADUSwANDNoP3nZg+M37Dwvn/tcR+c7gnXbVrHDO7Y/lq/LGj/UtjObZdfP1cgcAAADUS3oDDNqk8WPDEbttGqZOHp/vDN7Xz7svHPf728MPL5tRuC63bcMKDpqp045xAAAAGDQBNDBo3THdhutOzF3jfOeiB3LXl0MIaaYOT3AAAADAoAmggUHrzuk2WGdC+Oq/7NN10WDlokABNM20eIUd4wAAADBYAmigAXqC4Hc9f8fcNZ8BVZrpjGmP5A4AAAColwAaGLThCoJLVySsjdePLlxWeAQAAABg+AmggbqsM2Fc7kLYd5sNctccH/jVTWVT7tIVHB/8zS3hhSdeHnb67Hn5DgAAAADDSQAN1OWPH3x+ePV+W4Vvv2n/sN3G6+a79Zs6eXzu+rrkvnnhzseeyVc9OktC6QvvmZu7EK6eMT93AAAAAAwXATRQlzT1fMo7DgpvOWS7fKd+R++5efjrh16Qr8pbuGRV7nosXrE6nHfXE2HR0r4/9rOrH8odAAAAAMNFAA0Mq8+8cs9w+nufG7ZYf3K+U96aknUbyRt/PC186Le3hoO+enGfvc+l09FQydm3PRZ+eNmMwhMaAAAAQGMJoIFhtfGUiYXH9SZVXsGRrOnozF15M+cvzV2X+59cXHhctaYz/OiKB8MPLp0RVq7pKNyDbjc9vCh87Kzbw3cueiBcdG/PChcAAACgMQTQwLAaN2ZM4XFMfqxkoInmv942J3dd5i9eWXg8+/bHwrcvmB6+e/ED4fRrrOWgt1OvnJk7AAAAoBkE0MCwGje2/+C528o1/U9Ar1xd/se//o/7chcKQXS9HlqwNHzur3eFc+98PN9hJBjoiQ8AAABgcATQwLAaW2UAPeep5bkr70+39p6A7ja+yl9/IO//5U3hzBseDR8587b4e1mW79LuxM8AAADQXAJoYFh1r+AYrKeX9T5A7vk7b1J4bNRRhLMW9OyYnjZzYe5od2NNQAMAAEBTCaCBYTWuSd+FXrr3FoXHgXZH16PxvyLDpb/8edP1JuUOAAAAqJcAGhhWzdrB29HZtRO6s7MJcbEEesTo79NvbROevAAAAIDRRgANNNx/vHDn3A2sUSs4Sq3pXBueWbY6PLtiTb7TOGsl0CPGmH62QDdjeh4AAABGGwE00HAbrjsxdwMb26TvQitWdYQDvnJRvmosueQI0s/zH80YngcAAIDRRgANNFwtE8J5U0bD/eTKWbkbvEVLV+Wuy+PPrAhPPLM8X9HO+pu/NwENAAAAgyeABkakVR2NS7Z/cuXM3HU5+dIZ4fBvXhbumvNMvkO7GtvPChj5MwAAAAyeABpouN03n5q7gbVDxjfnqWW565HWM3zwN7fkK9pVfyvITUADAADA4AmggYY7eq/Nw+sO2Dpf9W9tG4R85931ZO56s4aj/VnBAQAAAM0lgAYabsyYMeHktx0Y9tyy+knoduSQuvaXPlcr8fEFAACAwRNAA03zvbc8J3ch/Ozdh+SuNxkf9Zr77IpwyuUPhlsffSrfqV1/E9DtMJ0PAAAArU4ADTTN3luvHy7/7xeHf3z0iPDSvbfId6ExPvb728OJF04Pb/jRdeHZFavz3dqYgAYAAIDmEkADTbXTplPCPltvkK/6Kh4yPUZITQ2mzVqYuxCun9nT18IhhAAAANBcAmhgyKQwuq+ekG/KpPG5g9rUGxav6ejMXV/pl7SGAwAAAAZHAA0MmV+897m5K2/dieNyB7XpJ0fu19m3P5678qzhAAAAgMERQANDZsdNpxT2QRc7bKdNcje0AfSfb5kT3nX6DeGqB+bnO7SzZq3LsIYDAAAABkcADQyptA/6U6/Yo9Cf+Kb9w0ZTJhb6ZN2JQ7OCY/GK1eGTf7wjXD1jQXj3z2/Md2lnAmgAAABoTQJoYMh96MW7hoe/+erw5kO2y3e6DNUE9MIlq3LX5aRLHgiPLFwaPvPnO8O/n3FzePKZFflH7ABuF6vW1L6DY+GSlbmrzIcfAAAABkcADbSMoQqgx40dk7suJ10yI7zoxCvC72+aHS66d2749J/vzD8igGwXf7h5du6q97m/3pW7ykxAAwAAwOAIoIGWMVQrOEoD6FJXFu2FFj+2h2eWr85d9S68Z27uKnMIIQAAAAyOABpoGbtvMTV3zTVQAN0tHVB45Lcuy1fVWbG6I/z2hkfCpfcNHG7SOG86eNvcNZYJaAAAABgcATTQMrbZaJ3cNdeYKvLnjs61hQMKHy/aB12N0695KHz+r3eH9//q5nD77KfzXZpt3Njm/HG2tvbV0gAAAEARATTQMsZVkwwPkdUd9SWPJ144PXchfPP8+3IXwjPLVocrps+r67A8BtaZd2Vccu/c8H+XzKjqgMFqmIAGAACAwRFAAy2jSUOsfQ1RppimqJMUjr7ulGvCe39xU/jsXwY++I7adaxdG2bNXxI+cMbN4fuXPBC+eM49+UfKW1tlsCyABgAAgMERQAMto9rdzEOhEbnjmhxA3zb76fDIwmWF/s+3zik80lgp7P/jLT3v23/c9UTuyqv247vCxDoAAAAMigAaaBljh2AFx92PPRNOufzBfFVZIyZfu9dCVDttS/2639fVqvbj+6ebPWEAAAAAgyGABlrGUATQx55ybfjVtEfyVWWNiIy7J6BbabJ7pKoxf67645vWecxe1DW9DgAAANROAA20jKHIabtD4YE0YgK6ewe0ALr50g7oWtTy8f3wmbfmrnZp+v031z8Svn3B/eHpZavyXQAAABg9BNBAyyidgP6fl+8RXrzHZuFPH3x+vjN0OjqqCyj7W68hgB46aQXHM8tX56uB1ZJX3znnmdzV7qoZC8IXzr47/OiKmeGb59+f7wIAAMDoIYAGWkbpBo53Pm+H8Mv3HRoO2XHjfGfoHPjVi3PXv2mzFoZ3//zG8Nsb+q71EEAPndUdnU0LoAfj9Gseyl0Iv79pdu4AAABg9BBAAy1jTEkCXXy591br5661vP20G8JVD8wPn//r3eGJZ5bnu11mLVhaeBw3BLutR7u/3vZY2HWz9fJVZStWd4Q/3TInXPvggnynfms6OsOPr5hZWK+xeEX58LsRH/k5Ty0LHznz1vCt+HYcaAkAAEC7EUADbeHbb9o/vOHAbfJVa5oxd0nueiudgH5w3pLw8u9fFd566rTw19vmhLf99Prwtzsezz9KPeYtXvnPwL+SFBjv+b8XhP/+4x3hA2fcnO/W71N/vrMQCqf1GideOD3f7a0Rzz18Or6dc+98ohB2+zwBAACg3QiggZY1efy43IWw7zYbhO+99TnhpXttke+0nkoH25VOdv/Hr28O0+cuDjc8tCh8/Kw7Cms8Pvq72wprJKjf3wcIZ39346O5G7w08fyXWx/LVyGcMa3vCpakERPQ1z64MHch/O12ATQAAADtRQANtJSfvPPgcNhOG4f/+9fnhInj+36L2n7jdXPXeqrdjjBzfvlJ3VVrBNDNVBzkDtZdj1V3MGHpkw+Dden983IHAAAA7UEADbSUV+y7ZTjrP54f/uU55ddtrDd5fO5aT/ehg6Wq3dtbaYKa1jN5Qs90fn9Kz598cN7i3AEAAMDoIIAG2soHjtwpTJ3UFUJ/8TV7Fx5bRccgA2Txc+PNmr8k/OGm2eHZFavD2Ab+iVf9wZK9f960mY2bwoahlJ5I+9V1D4ev/+PesGjpqnwXAABgYAJooK2sP3lCuOpTLwnn/tcR4X2H75jvVvbyfYZuZ3SlSedqg2UD0I21YnVHeOOPryscFnj8OfeEsQ1ch1HvL/WX2x4LS1euyVetIX3e/uzqWeGL59wd5i1eke9Cb5dPnxeO/9s94bSrHwpf+fs9+S4AAMDABNBA29loysTCoYSV9uu+dK/Nw+detWd49/N3CF89dt98t/kqnSFYbbBc7aoOqnPF9PnhqWWrC/1fb3usoQF0vW579Omwz/EX5qvWkILFr/3jvsJBil88W7BIeb+6ruegzbMdhgkAANRAAA2MOBusMzH8+wt3CV/5l33D5lMn57vNV24Fx1M1vFS90g5p6tX7/TlrwZLcDd6YktUalVxy39zc9XbnnKdz11yrOzrDnKeW5avyfnfj7NyFcME9T+YOevPdCQAAqJcAGhhxtt943dwNrc4yAfKVD8yP/1tddDPYHdKj2f7bbpC7HqXvzgWLG7e3drDD1A/MbVwYXsmajs7w8pOuCkd86/Jw+jUP5bt9pZAaBuIVGgAAQL0E0MCIc+yBW+duaK1a0zfIW1vD3GCnHLBuk8YP/MfZ+HGNW8Ex2AD66WXNP8TtH3c9EWbNX1rov3ruvYXHcsp93gIAAECjCKCBEWf8uOH51vbTq2flrkcaLq12cNAkav3KrS8pDYknDOLzonT6s9oVHMPpmeVd+68Hcv2shbmDyp4agidNAACAkUkADYw4Y5uUDR5QZs1DsQfn9V2rkNYgfOIPd+Sr/p1546O5o1YdZUL+0gB2wiAmoO9/cnHuGmPusytyV7tyq17KKT2kc/ai8rugrR6nGnc/9mzuAAAAaiOABkacsYPdj1DBgdtvlLvqpUPo7nrsmXzVv/PveiJ31Gr5qjW563HTw0/lrsuum6+Xu9qtLFlTUctqlXK2G8Se8mp3hZeu1vj7nY/nrrdNpkzMXZdqA24AAACohgAaaGsHbLdh7no0aznCcUfvFiZPqO3b5r7b9D81XWx1uTFeqlLuUL/Npk7KXZenlla3kqKc8SVj9QNlwCnEnfNU+YnjZN6zK3NXuxlVHmBY+kqAv99R/gmOhUt7r1a4Y87TuQMAAIDBE0ADbe3gMlPJpasHGmWjKRPDVZ96Sb6qznqTxuduYI89vTx3NMKPr5iZuy7TBrHreErJx/HhhV2H+5WT9kW/9afTwhHfujzf6av01+vPNhuuk7suH/jVTbnrX2kAX+3aDwPQVGPF6o7cAQAA9E8ADbS1cufKNWsHdLL51Mm5q84aad6I0NHZe53FR868LXc9Fq/omrC+5/Fn+6z/KFVNGDxr/pLCDvFSjz9TX5A8ebw/8mmc9HkOAABQDX8bBdra2DJpc+kO6NcesHXu6nfWvz8vd7WZUC4hp+1U80RCR/45y6uYDP3ldQ+HL5x9V7izwrqLEy+8Pxz13SvD6354beiscudzqTSJXezZFX33ZAMAAECzSUZGp21j/TxWOpEqLSJ9ONZJsWo5Ye1lsb4b69JYi2KlpOOaWAPZO9YfYs2Llcb4psf6cqzerzGHKo0rs26jNIB+3SAD6CN32zQctvMm+ao2pesT+jO1hrUMDK01Vezn7g6pqz0E8zfXPxpe/6Pr8lVvp1zetT7k3ieeDU9UOfFcqjS33nS93ocNJtWu5YC+Bv6aAAAASATQo88usW6J9b5YN8b6fqxZsY6LNS1WtSnbh2N9ItYLYj2WblThsFhpeemxsS6J9X+x0mt4vxjr4li9F5ZCFcaVmYAeU/Kd7ZF+9vVW4+oZC3LX5Z3P2z53A6tlenXxShOqw6GaJwm6p5v70/1zyn1OVlLNr1uvtSUB4ebr910f85Mre+/JBgAAgEYTQI8+P4q1eayPxkpB8GdiHRUrBdF7xPp6rGp8K9a+sdaL9dp0YwDjYv0i1rqx3hTr7bE+HSuF0n+OdXisj8eCmpSbNi29N3vRstw1xv+8fM/cDWx1mR2+tJZDd9o4d5VVs4KjZwK68DDsStZWh0lldkDPX5xeBNPbjQ+lF7UAAABAYwigR5edYx0TK63cOCXdKHJ8rDQm+q5YU9KNAaRp6XtiVXsM/oti7RXrqlh/SzeyFJF8qqsNH4zVItEN7aLsBHR+7DZubP/f6l66V3pOpnobrDMhdwNr5oQrjbG0isnzex5/JneVdeQ1HWNa5NtY6fT9Lpul5wt7O/fOJ3LX41sX3J87qKzO1eQAAMAoJIAeXdKkc3JRrNKxzMWxro2VJpTrO22tf91v+4L8WCytAHkg1g6xUkgOVSsXQJdOQE8YVzkQnDh+bPjpuw7JV9XbdL3qNsbc+uhTuRvY2w6tfrVHsmDJyrD7588PO37mH2FeP7t815jC7tdF987NXWW/vDY9b9e/pau6guwqV0A33f/86c7cdTlguw1yB4P3uxtn5w4AAKB/AujRJa3YSFLYW86M/Lh7fmyk4XzbjGDlVnCU3lrdzwFy600aH8bWsTOh2t3OVz3Qe390f6ZOru0Qwrf99PqwKofLh34jnQfa12lXzQr7funCcPw5d+c71GPWgoH3iP/3H+8oPNYaQK+tY5T00YX9r5XpLDN5b2KVRvrzrXNyBwAA0D8B9OjSPf5W6bXk3fc3zI+N1Mi3nQ5RLFfVL+ZlxFi0tO8O29JQur8VC93h37HP2brwWK1FS1flrn+r1lQ/fVzrvugZ85bkrrKvn3dfWLG6M/xq2iNh3uLKU9IM3j2PpzNVa1fPmpYP/iZ9yysvhc+vO+WafNWj3Nt50e6b5Q4AAACaQwBNse7Ubjjm5IbzbdPGTrv6odz1KB1oHt/PCo7XH7ht4fE7bz4g7LRpNevPa1NLqHzfE/UFmNV6dvnAu44Z2EMDTEPXOmncUcdo8r39fK5ccM+T4e7H+v54uan9F+yySe4AAACgOQTQo0v3lHGlRaDr58dKU8qD0ci3fXCFcnIWBaUT0K/eb6vc9Th6z83Dq/bbMnz8ZbsVrsePGxv+8dEjwh5bTC1cN0otAfT1sxblbvDumP10OPHC3l8S9ax6oK+PnXV77sqrdj1Lt87aBt8HNH9x31cFJOU+FesJvwEAAKAWAujRZXp+rLRnuSuJq7yneTCG820zypTu4N1oysTcddlzy6nh9Pc+N/zoHQeHqZMn5LshrDtxfLjgY0fmq8ZYU8d6hcFKaz/+5ZRrwymXz8x3ugzDb2VEWbG6o/CYwv1K0pqLpSu7fl61SgPrGXPTmbCNVy5sHl/H/nMAAACohQB6dLk8Px4Tq/Rjn8Y+D4+1PNb16UaDXZYfX5Efi+0cKwXTj8SalW7AYIwpSaDHlYRsJ/3rc3LXV/p333bo9vlq8Nb0cwBiOdfMqP7QwlLLV3UFn088k76M+1rSzy7sdjRl4rjcDY1qDl1LIfXvb3o0X1WnNBhelj+OA6m0O3rBkvIT0OUm4NcvegIGalH6RB8AAEAlAujRJY1DXhRrx1gfTjeKfDlWWoB7RqziBafpYL9GHO53Zaz7Yr0w1uvSjSx9Dn6rqw0/iVVbWgdVKF3JseeW3RtfymtksLKqxoMF75hTebp2IB/6beWD6ZJTLn8wd70tW7Um/OLah8L5dz2R77SHTdablLuh0R3w9yc94bDzpuvlq+qkQwOLVbsWo9x6l3TvB5eV/zjf/2TfyepKb+s31z8Sbn64cSthGHk2Wrf3K0sAAAAqEUCPPh+KNS/WybHOjnVCrDSd/PFYaf3F52MVS6FxqlJHxPplru+kG1Fao9F9L1WxlNy8L9ayWH+KdWasb8a6IdabYl0b6/uxoOG22mBy7qqz3qTxuWsvl0+fn7vyLrs/fen3dfrVD4Uv//3e8J+/vTXcNEpDx2p2f6/uWFtx6rjbsytWh+9fUtsmoTSxfPKlM8Kl980tXA/0NrotXtF3ov2WR57KXV9n3tB3MrvSm/rC2XeHN/1kWnjymRX5DvT21udulzsAAID+CaBHnzQFfUisFBAfFuuTsXaJlQLp58daGKsau8Z6T643phvR5rG676UqlcLm58Y6J1ZaA5JC73Qo4VdivSxW+deNwyBNmTQ+fOHVexX6773lgMJjf7auIrD++XvTl1HjVRs+VlLPv//di3sC0xMv6F7XPrqUrmkpp6OzM5x75+P5qryxdexUftXJ14TvxY/B+391c3howdJQ7a/w+NN9V638pYo1IcUGOpjyl9c9nDvobdMhfgUCAADQvgTQo9PsWGkaeatY6TW0O8Q6Lla50ceUhZTLQ1KA3f1jlaqce2O9OdamsdLfXtPu5+NjlV9aCw3ygSN3Dg9/89XhDQdtm+9UVrpDupyj9twi7Lxp2lrTWIM9tDCtYBhT8ctvYNWufxhpqgmg0wT03Gf7nwguXadRjXRoZLf//uMd4Xc3pm/RA1t/nb77m/9wc20B9EC/34ECakavRUs9ZwwAAFRHAA1Qotod0AftsFHuGufOQeyATtIEdOcgQsPBTmC3q2oml9P79SdX9n9O6mDff2mFxkMLluSr/jXiYzXQLzGYzyVGtlMuTy+oAgAAGJgAGqBE6QR09/qOoVBur28tUmB41Yz+d0H3ZzATr2n/cTq8btrMajf5tIZX7bdlqGZzRpqSXrR0Vb4qr9JBj7XYeEp1h7s1Yjr51kcr74xOTrv6odwBAABAfQTQQFsr3cV87HO2zl39SrPIdz9/x9z1VuWgdE1evs8W4bGnl4dnlq3Od2rT2Tm4ELt7BUcKN298aFGYv7jvy+zTwXTfvWh6uPKB3kH3l/92b+Hwureddn14/y9vyndb3zffuH+YMrH3wZPldnyPrWI0/o+31LYCo5wlK6v7+DViXcq5dz6RO6Bey1d1hN/f+GjbPfkGAABDRQANtLWX7LF5WGfCuEI/dfL4cMIb9i/0g1EaNE4cX/5bZbWrOrodtP2Guats+pNLwuHfvCwc8JWLwqtPvrrmncK1hJLXz1oY/v2Mm/NVl7sfe7bw+KMrZoa3nDotHPWdK/oEoh8/6/bwg8seDO/5+Y29diL/uegAvEvvn5e71jdx3Njw8Zftlq9COO7o3Qo7vkvtstl6uWuuFat7dkL3Jz3Z0C6eXrZqwOlxaFenXjUzfOYvdxWefHt4wdJ8FwAA6CaABtpaWpdx4+ePDr9+/6Hhli+8LKwzsSuMHoxqg+VaD/vbaN2JhYMQZ3z9lflOX8Uh7j2PPxv+fufj+ao6hR3QVYbW//rT68NF987NV72deOH0wuPilWvCL6/tvYZh2qyeKb9L72ufoLmStFrjoO03Cie/7cDwv6/ZO3zwRbvkH+mt0hMR1Tqkyp3ha6pMlttlP/N1MxeE53zl4nDQVy8O38mfVzCSnHTJjNyFcNzvb8sdAADQTQANtL2pkyeEI3fbbNABYbcaB5urtmJNR+Fxwrjqf58/vKy2ncIplGzA2XS9LFvV9fsuZzhD0LXxn0YYN2ZM4YmM1x2wdXj/ETtVfBJjsP+tB2w38AR8csSum+Wuf+0SQL/9tBtyFz+fG7Ajm+ZZ09EZVseifnfMeSZ3AABANwE0QInXHLB1WG9S107gtx6yXeGxnE2nVndYXLdrH+yZHP73F+5ceJw8YWzYedMphb6c8WXC6u9dNL2wpqOcp5atCntsOTVfNUZ/gXZ7RKD9G1vNCYTRJ866PXf1GV/l26l2Ar/WJxp22GTd3EFfjy5cFo741uWxLgsPWSNRtxftXt0TSAAAMJoIoAFKpPD5z//5gvDNN+wXvvCavfLdvv7zxbuGjafUFkJ3+8TLdg8nvfU54ZwPHxFm9RP2vHLfLXPXJe1cPvmyBwsHFZbz2+sfDZvVGIwPpN9J436mcNNBhu3szQdvm7suS/uZBK/G+w7fKXf9+/EVM3PXv7RupRaPLFwW/nDT7HwFvX3srNvCk/H7y9xnVxb2vFOf22c/nTsAAKCbABqgjDRF/K+Hbl9Y71FJCqqv+fRL8lVtJk8YF449cJuap5UXLFmZu/LS/uBGv4J+/rNdb3P5qo7wrQvuL/Td+stA1xT9YK1haSvYv8qVGdXYY4upYcsNJuerxqgn4P/Un+/MXZdN6nwCZSBplcOfb5kT/npbz05zWtutj/YEp0LU+rXj9zoAAGg2ATTAIKw7cXx426GV13QM1vcufiB31VnTsTb84LKeA7EaYd7irgD61Ktm9pnO7S8EPe+uJwpB5L/+dFp47tcvCdfMWJB/ZPT5ybsOzl390qqW4j3npTnXv59xc+76N2Pu4jDnqWWFcHjh0lX5bmP97Y7Hwyf/eEf4+Fl35DswMqWvpWK7bbFe7gAAgG4CaIBB+uyrKq/paITidRtjBjgiMU3fXd3goPe+J54tPJ50Sd9ge/rcxbnr674nFoff3TQ7XD9rUVi0dFV45+k9h9G1hQatENlvmw3CTnnP94brVp6oH0haj7DP1uvnq96TluljdNG9c/NV/970k2nhdT+8tupwuJ5J60/8QfDc7latcRhhNf7nj71fVfCcBr5yAgAARgoBNMAgrT95QviPfKhgPQaaoP7W+b3XXvSneO1Fo/S3JuR3N84ON8zqOVyx2LR4//4cXrejRr0niw8VfHrZ6tzVbtmqjnBb0ZqE9P7t9uzy6n/dZ+LPTU8IVMtGgdHpygfm5678kxCH7rRx7npLa4Laff97LYq/DpNR9J8OAABVE0ADNMA2G62Tu9rtuWXPVGs5K1b3HH5XHGaW07l2bZgycVy+qs9DJYciXjezfMDc7YO/uSV3vd0x++nw2xsezVftp1FB0tiiD9rUSeNzN3gnX9ozkT5+XPP+OB/pO20fWbg0/OzqWWH2ot6rFEa7S+/rmagv98TW2DLfi065/MFwyNcuCW8/7YZRFUIXG63/3QAA0B8BNEADjBkoGe7H2HJJTpHiAHOgMPDcO58IS1f1BNb1ePKZFbmrzlN5qnezqZMKj63m1fttlbvarK7iNMez/v15uavsJXtsnrsQPvSSXXPXWOMH+BwajPSkRiNdP2th2PEz/yhU2hE+nFJY+L5f3hS+9o/7wvt/dVO+S3LF9Pnh/y6ZET79pzvDwyVPSiXlvhWdeOH0wmOaCh4NBxnOW9z3e6X4GQAA+hJAAzTAYOK/cQOE1xfc82TuQvjDzbNzV7tqM8rx43r/xKmTq5vabV4EOjg3Pbwod7V5/YHb5K6yw3beJHeVffDFPetZ1qvyfVmr4icpGq3c9GvaOf3Vc+8NtzzyVL5TvX/96fW5C+Hfqjw4sVlWrO4Ms+Z3hasPzF1ierVI2jn+/UseCGfF7zkfKPNx6hzgybC06mWk+04O3Iv5FAIAgL4E0ADDrJrtCWny+amlq8IZ0x7Jd2qX8qIUsC0fYEK6NKhOO64Hkn7deYtX5qvWUu/va5P1+p/o/rcjd8pdZf99zO5h0vielSgDPdlQq8UrVofjz7k7vPaH1+Q7jTf32b5Tnm/88XXh9GseKjwOZor58uk9e4bLmTZzYSGk/sedT+Q7jTW25Gtv1TBPZLeqRxb2XU/SMUDSOhqC2D/cPCd3PaY0cM0OAACMFAJogAYYzATqmCpmh3f53HnhwK9enK/q980L7g/7HH9BeN43Ls13BvbY08tzV9mPr5yZu9b30aN3y10I73ze9rmr3ZYbDLz3u3Q3eKNXNX/mL3eFXw3iSYlqHP3dK8PTy3ofWpgOROz29CAnXef38wTB2067Plx879zw4TNvDUtWrsl3m2fVGgF0tYoPxCxnpO8OTw4rcxBjo1fWAADASCCABmiAJm5AaKhTr5xVmIROL69vpG9f0Pel6K3qkB02Cvd+5eXhkk+8KHzt2P3y3dqVbCopq/SJiUavymjWZHCpV5x0de76Gmzg9uyK6gLscpPYjdYpf26YtKZlpNtl8/Vy18OTGAAA0JcAGqAJPnpUcw6bGwojcXDx22/cP0wcPzYcudumhVp34viwa5nwqBYDHR6ZvHyfLXPXpXS/di122WxK7oZeesLi3DsfL4RrpXuSBzvwWe2kbDP2M5f+kmsk0DXpbyf9E0PwhMFwK/ctwBoXAADoSwAN0AClQcT4MrsWNl1vYu56u/i+ublrDc080K6Raskj3/Lc7cIdXzwm/Pr9h4UxDfrvW7qy/13ayeQJPfufkzUd9Yeo22y0bu6Gx0fOvC28/bTr+7zfVw8ycPv3M24OR377snDjQ/0fFjkUT4yMhrURjfSpP92Zu77OvOHRMK8JIXQrHRRZbn3SytUCaAAAKCWABmiA1+y/dZiaD59626HbVQhHywef1z24IHetYfKE5v7RkEK+zmEI+taZ2DsMHqzfXN+1e3nL9ScXHkvtvGnfieWHFy7NXfXGjR0T1pkwLnzj9fvmO8Pn5keeCrfP6b37N/3eBuPhhcvC7EXLw1tOnZbvlDcUu3XXjNIAullfj4d+49Lwvl/cmK/KqyVQ/vxf7wo7ffa88K0L7s93hlc6BLRUu6xjAgCAoSSABmiAKZPGh7986AXh22/aP3z+1Xvnu70tWFL+sLXtNh7eydZSp1/zUO4a74K7nygcqLhzrP4OnxuMdRscNFfSvZP4K/+yT+Gx1NYb9j2kcPzY2v7Y/Z+X7xGu+8xR4YbPHx22HeYJ6G7fOr93+DdUke1QbMf4v0tmhKeW9j5wcTQ4L35dNsvl0+dXDJkfWbi0sF/89T+6ts9Bl6XS94vf3vBoof/xFTPDmhZYdXH/k4tz12OwT8gAAMBIJIAGaJDdtpga3nLIdmG9PAldrUZP5g7WVQ80byL7g7+5NXchPPfrl+SusZatGng1RrXefPC2ueur++OWPu7llJuEnFDjDuj/eOHOYYv1J4f1J0/Id4bfDSWrMspNJk8a3/j/e3HNg/Nz1zhPPNN7RcRZN88OH/ptz+foaHHXY8/krjnmVXiy6eNn3R6mz10cbnv06fD1f9yX75b3zPLe08Z3zGnu77ka5QLo22Y/lTsAAKCbABqgCdbWMBf6mVfsmbvWMNidviPJ5161V+76mpD3fI+r8Jr7cru0l6+uLRwvt0u8GTabOil3tUv5851zng6f+fOd4eoZXSFxWhtSzg6b1D/FPa7G6fGBXDNjQXjJd67IVz2mzVqYu9Hj1Ctn5a5+/a3SKN2F3u3WR3vWuVz5QOOfYBgOdz/2bLj43tba6w8AAMNNAA0wzA7beZPctYZVawTQ3TaaUv7gyKQ7Yq2087VcoFY6cVurl+29Re4aazDrUB5ZuCy84UfXhd/fNDu86/Qbw/QnF1ecQq/lkL/SVRhXTJ+Xu8Z45+k35I5G6O9DW82O6aeX9d2n3K7+7YybcwcAACQCaIAh8sEX7ZK71rZiTd/wcOb8JWH7FttVXa0vvLryFPNgdAfPlaZ9y3l4Qd9DCH/3b8/L3cAO3XHj3LWOFAwXH9738pOuyl1fNZw312da/OoZrXVY50iQguF3/qwxQXx/h0SuquJVFdX8nN7WFp44OfHC+8P5dzVvhzUAADB4AmiAJth6g74H0L3jsO1z19rK5Uj/+ZtbwtKVa/JVe9lxkym5a6zuyfVyqzYqKQ3Zrv7US8Lzd6l+Av4NB22Tu9axpIbPi1omoGm+c+54LFzz4OCD/RsfWhT+9+y781Vf/YXTpU44777w6pOvDtNm9l6Fcs/jvXc+X/vgwvD5v94VTrl8ZvjP394aZsztu48ZAABoDQJogCYoFxRu1yYTxFPKHIr4wNwlYWHJSoR2UUv4Vc62G/V9MiE5/rV7Fx5rWU082D3GE5twuN9glR4O158nnx3cChIa6645z+aufq846arwllOnFVawVLKmo7qvwZsfXhROvWpWuOfxZ8PbTrs+3+1y4T1P5q7L9y5+IFxUtGv5z7c+lrvmm7d4RXjPz2/MVwAAwEAE0ABNMFSHxzXD0gr7e8fXsGqiGofssFHummuwAXS5tRcbrTshbD51cr6qXul/c62/t+6DD5th183Xy11tzrn98dzRbmoY3q/o/icHnjy+4O4nw8oyq31K3TGn95RzsTED/GYH+3Vei7f8ZNqIOTQRAACGggAagKoU7/lthEqrK9aWBElpxcOOn/lHoaqZtu0blA8uZfvEMbvnrscr99sqd7XtNS6dpq71XdroJwGK7dBiE/rl3jW1rPtgYE38dOrl6+fdF/b4wgV9vrZLre5nD/Rd/YTTyYJBHKRZq4cXLssdAABQDQE0QAv63Kv2zN0IVib8+tsdj4edPnteIWxetqorbNz3+AsLj8kBX74od5VtNGVieNuhXfu2N11vUjhqz80Lfb222bDvCo4zb3g0d7VNXu655fq569K9E3nqpPGFx4HUcuBhrb72+n1z11xTJ1f331rOj694MHc0wkBTxY123l2912iUWrWmcgD96KL+Q9+/3DZ0KzgAAIDaCKABWtDMeUtzN3KVi74++rvbchfC/559T+5q89wdNwpfet3e4afvOjic99EjBr03eaCQbpMpk3I3sNIDB7fPU8fXffaowuNAmhkYblXm4MxmmFjFGpHf3fhoOPybl+WrHguXtOce8lY1xPlzuPS+np3N5fQ3Ad1u0rT3z695KHz9H/eGRW26Px8AABpFAA3Qgtad1PcgwHaxxfrVBbIDTQ7/+dY5uRvYL9773MKk8s6bTQlfft2+YdL4ceGYfbYMm69f+57mWtUacF/9qZeE/z5m93DeR4/85787dfKEwmOxZq7bGE7VHGb52b/clbveBHmNVWkNTrMM9FqBO/tZs7Hdxo1/giStdPn0n+4Mn/zDHTUdplmNS+6bF75y7r3htKsfCiecd1++CwAAo5MAGqAFpdUR7er6zx6du/5Vs1P6s3+5M3d9rVjdc6hZOkDvqk+9JFz6iReFzaYO/ftuWpUTzMl2G68bPnLUbmHvrXuv4yj1tWPLr8Q47ujdclfZLptNyV37md/PLt+RcvBbmo695ZGnhj1QH+qnOAbaAT332RW562v2ouW5K6+e75mnXP5gOOvm2YUnu0688P58tzG+cm7PKzj+eEv1T6YBAMBIJIAGaEHN3PXbbNWuiejef9yf3904O3d9LShZx5DeZ0O907ZbM9ZXvPHgbXPX28df1vdQxFIfe+nAP6cVpScVZs5fkq/6WtnPjuBkxtzF4eRLZ4RZ/fwareDHV84Mb/zxdeGgr14czh7G3cVD/eVy/t3974BetqrnSaVSL9x9s9yVt2BJ7YcQ/uq6h3MXwm+u79nr3ggDBeYAADCaCKABmuQr/7JP7kK48n9enLvyfvLOg3PXZaSuXyg2mJB9zQjaFVvJhCp2JVeywyZdu6XbTQpE610L0dm5NrzpJ9PC9y5+ILz9tBvy3daT1j58+4Lp+SqEj511e+6G3rUPLszd0EhPIPT3xNPyolc1lHrpXoM7TDQ5987Hw/t+cWO4Kk/Sj4bvswAA0AoE0ABN8q7n7RD+8B/PD1f894vDDpv0vxLh5ftsEV69/1Zh0vix4SfvPKimSd4vvXbv3LWX7gP4ug308vxiHTX83Gb4r6N2zV1l604cvj3e+2+7YXj7YduHzadOCj96x0H5bmVpJ3UrWLqyI3z4zFvzVW2+cM7d/9zj+2Q/qxy6TRg3POHj9y9+IHc9nlnW2P3D1bp99tO5Gzp/v+Px3PXV3/qVy++fl7v6LF/VET5y5m3h8unzw7t/fmN4dsXqMH4QT/IAAADV8/+8AZokhciH7rRx2HHTgffxpp97ytsPCvd95RXhFftuVVN4ucG6E8J7nr9Dvmofdz32THhw3pJw26NPFcLnKjZy/NOMub1XLAx0oGGjbTJlYu56lO6gnTyhtgD6uTtulLsQ9thiau7q943X7xdu+NzR4VX7bVUIo/uz7UatMTGdIuH+QshKZi9aFs68ofcKhYGe0Bgz5BuQu5x+zUO567FqFEz0d6tl4nvZqjW5C4XgeDAWLu39eZUOBjQADQAAQ0MADdBCxuZEpJZg5C+3PhYO2G7DfDW89ttmg9wNbNb8peGl37syvP5H1xV2w67prD6E+8W1Pbtbk1rC60bo/jgVu/jjL8xdly+9rmcFSzVOftuB4cDtNwyH7rhxOPPfDst3B6d7kv7Tr9iz8FhJnVsvGu7ky2bkrjbl9v8O9DnRKv/NSS3T/6NJerc89vTy8Jk/Vz6MtFqlBz6m/fKle+QBAIDmEEADtKBapjMfe2p53XtzGy2tEKnHh357a1WHEnYrDeyGegK63IqUjaZMDNO/9orCSpQ0ffzq/bbKP1KddJDhXz90ePjDB58fNimZph6sDdaZkLvWVvrEQrXKfTz6+3xKO8QHOtBwKK0e6mdQ2sRXz703/L9f3BR+f1Plw0irdeNDi3IHAAAMNQE0QCuqIU9O+5DLTeQOh6fzDt56HPGty3M3sNId0OkAuqFU6d09afy48N7DdyqsvBjMIYvN8LK9t8hdX0Md4Ner0kF0HWWm5/v7bxoo0Dz065eEg796cXh6WX0Tstc9uCD8etrDYenKnhUS/VndQmH4QL5c42T/YKSP0/S5i/NV7R6ct7iwxmP6k4vD1/5xX74LAAAMNQE0QAuqJbp8ZOGyQe0y3X/b6tdmDCTt4k0+88r+Vz6UU/oS+UrS9PM5t/c+yGyoDyU857bKB6kNhTcfvG3uqrfpen33Vncrt/1kuA7p68+L9igfQP/51sdy12NNP09K/OLavnuYi81bvDIsjJ+Ph3ztknynemmv+dt/dkP433PuCSdeOD3f7d/qNtoBvcMm6xbWxQxGWqnx8u9fla+a44Tz7wsv/d5VYe8vXhheflJz3xYAANA/ATRAC6o1Th0/tvK38/Umjc9dX+tMGBf+8B/Pz1fVu/+rr8hdb91rDQ5s4k7qy6fPy12PGtZHN8SNDw/vy/mP2WfL3PWVDr4s5z0v2DF3fZUL8A/eoedQxJZR4YmG0gMIk2f7mcafOX9p7vrXX4hdSdpr3u2X11W3UmS4DiEsPviyWmndyesO2Dpf1Wewk83VOPXKWbljsO55/JlwzYwFQ/5KEwAARg4BNEAL2mnTKbmrTqVp1SN327TfgHnrDSeHyRPG5avq1fPvNMqvpz2Sux7NXiHxkj02y11r6G82+UfvOCh3ve286Xq56+vF+b9v56LPuyN23TR3raOWPeFpirldrO4YnmBv/21rf6Ko9ebie8xbvCJ3NEpaX/Lqk68J7zz9hvCX2/q+0gAAAKohgAZoQc/dsfwU60/eWT5cHD+u/Lfzr/zLvmHvrdfPV32tN7nrcLrNpzbm0Lup/UxbN8pNDz+Vux61BJP1+MhRu+WuNSxb3ZG73qZMHBc2rXCA4fh+9rRsPnVy4fHUdx0c9t1m/fDSvbYI//bCnQv3WkktQe2xp1ybu9Z34T1P5m5o1fO8TYucd1rWg3OXFB7TDu6hVs/aoXbwub/elbsQ/vuPd+QOaJZnlq8O02YubPr/rwGAoSaABmhR5aaaX7HvVoW1GcW++Jq9w7gKqVDal1yq+BCxb79x/8Jjo/ZAf/xluxcem/nXpiVlDnZr9g7o/taYDIerH5ifu97++MEX5K6vdFDlx166W+G/5RPx4/Smg7cthNL/8/I98s8IYbctpoZz/+vI8LP3HFI4ULHVfP+SB3I3dOY+uyJ85e/3hgvufiLfabwfXzEzd0NnTUdn+PkAu7DL2X7jdXPXv723qvzEV7MsWLoqnHDefYUd3M1S7ntqMnn80P5f6kq/j0Zbtqr8k11A46Xvy6/6v6vD2067Pnz13HvzXQAYGQTQAC3qrAqrM/7fEb13+R574Dbh/iefzVe9Tc0Tzj9/7yHhgG03CJ9/1V6FXcB/+8jh4bJPvijsseXUwo9vlidgB+stz90ud0Or2btJV+Xd1t2qDeGapdwE9KxvvKrfaffkYy/dPdx5/DHho0fvFr7z5gPC3V9+efjwS3bNP9r6ag3DGvF58ZofXFMIaj/4m1vD5ff33T9ei8efXp676t055+lC+N3ogwpPumRG7mrT/bmfPnf6M3GIA9nkxAvvD6de1dzdz5fcV/5z4K3P3T5c9T8vyVfN9YNLZ4QDvnxROOXyB/Od5rnvifJ/tlDeyjXlv0cN1RMGtLerZswPj+U/J6o9QwAA2oUAGqBFHbR9+QPC1s+hcrc0KT22wgT0Znm1xlF7bhHO+cgR/1yrkHa/7rxZz07gRq3g6J4UrvT7aYTn77xJ7no0+5WqD87vfWDaIcN8QF/p+/fV+29VmHCuRvHPG2iX99TJrTX5Xatz7ngsLC8TWu+8WfU71ucX7ZJ+3y9vyl19lldYnZIsWroqdz0eWbg0vO6H1xbC7/+M1Ug/rDO8TIcQJgO9KmBclZ+PjTR7Ue0Bf62+fcH9uettnYnjwibrTcxXzZOeVPnuxQ+EZ1esCSdeOD3fZbilgPkdP7u+8MTAObf33pX9p1vmhEO/cWk44fz78h0ob7jOAwCAoSCABmgz65WEgmnSMIUfg/H2w7bPXWM0M3uaNmth7npss9E6uWuOrTfo/eu/cr+tcjc8StezVFrBMlh//VDllR4D2WbD5nxMfnpV9esqPn7WHb122P7TMP0dv3R9TrHj/3ZP7np89dyewOqS++YW1oEwvPo78LSZT7x1K33rzX71B9W56N654doHF4YVqzvDcb+/Pd/tknZnpyeyTr1yVpi9aFm+W70nn1lhgnqUGIrvIQAwXATQAG2mdPJwwtixYd1BBtAbrtt7qnqwds+rPYZKs8LObnuVrLY4dKfyh0QOlbcf2vsJg2YF/ttuVP+qkbM/fHjuGusb590fZs7vOmyuGn+9rfc04orVHeHp5avzVeNtWucU7N/veDx3PUrXbpT7OQN54pnl4eRLZ4RbHul7eGep7ldMNEI1b68d9Zf3VpMdPb2s76R7LUqDyDUC6JZQ7XqdBUt6XlFRjf89++7wvBMuDR/53W35ztBJn2s/uuLB8Imzbg9znqo9OKd2w/DCEQAYMgJogDZTujYhrVQYaJXCQBo9QZvWhJzx/w4N737+DvlOe5s4rvcfl8M9pDSl5EmI1U0KodLn1Qlv2C/su03tB8ptMmXgIPaST7wwfPaVe+ar6k1/svdKlGqlMPawb1xadt1Fo/Q3wVbrR2l2SehTzxDkcb+7PXzv4gfCG398XVi8ov/g/dpPH5U7inXEr6/rZi4IzyxfHR5asDTf7Wug6cUUJj7nKxeXn8qvU38T2QydaidXH80T0CnQ/dYF94drZiwoXFfy6+sfKTz+484nwjPLmvfEWTlXxd/bty+YHv5y22Pho8MQgI9GJqABGMkE0ABtZov1+x4YOOgAuoaxm2++Yb/c9fa2Q3sfQPjC3TcLX/mXffNVeyt9/wz3XxFLM6cUTjTL2w7dPpz7X0fmq+p8+437V7WTetfNp4bxJeF+NZauXJO72vzv2fcUQsRmmlDy31PvS+fTaoVZ83uHnf3tkK7kxocX5S6Emx/ufyp5OA4ObCWVPla7fO688PbTbijs9+3PQJ/y3WHimTc8Wgi161H6b9X769BY1f4R2r2e48Nn3hZ+fMXM8M7Tb6h6KrrSAYfNcl7Rnyu3Pvp07gb2wNzF4fRrHgrzFlsZVCv5MwAjmQAaoIWVO+ir3B7Zcgfz1aL7YLFiP3rHQbnrceeXjgn/WrL+odtICZvLGV8aQA/z3xJbPSisZS1A6fu2Gg/WsIIjOf+uriDloQW1/Xv1KH2yovhQqVrC6D/fOid3PX5/46O5q0+aZKxki/W71m/stnnP4aS1eMkem+Wusas8htKdc57JXX36m14s3dVc7+Ry6b9mBUeLqPHPhDtm9wS602b2PdcgKd0XPX1ufa/8qFc9f8ytWtNZeLXFV8+9t/DqC2qT3n8AMFIJoAFa2Kv22zJ3PdZfp28o3YxAsnSSM0n7prv972v2zl0IN33+pWV//khRGjjXO9XaKLtsNiV3ramjs/q/RI8vOVCxGntvVdtKkP/87a2Fx1UlO5WbYW3JjGpx0FjLp825ZabaH39mcBOF/e2QfudhXetyPnLUroXHWh174DaFafmDd9go/Op9h+a77eXfzrg5d/Xpb+q/dMq13gB62are0//NmICeMXdxeGrpqvDgvOY/YTNSVPrQ3/3YwE9qVHplw1Ml+8LTCpehtKTklSbV/Ll3V/zvXbyi698rd2DwUBnuP6Pr1Z6/awCojgAaoIV97KW7/3Oi8qvHdk0Yb7XBOuHoPTcv9O99wY6Fx2Yo9xfq4rDw/UfsFB464VWFateJx3qNLwrih8NwT2APpJZQrJ4J6HrNXlTdQWGDUZp7pPdFCkMeXdjah3i97jlbFx7Lveqikrce0rV2Z6N1J4SX77NlYV/4n//zBWHvkkM728W8xbUdENftOdttmLvKfn/T7Nx1qTcfK52WXdPgJ1X+fMuc8LLvXxUO/9ZlfSZwqazS9PuzA+xdT657sPwe6DEly54eHuLvIaVPgv2tikNQH6vyMMZm+tSf7ggHffXicM7tlV/x0apKvy+0a5AOAOUIoAFa2NYbrhMu++SLwu///XnhHUWrL372nkPCNZ9+SfjS6/bJd/raf9sNclefTdbrGyqXW0XR6mFoo3z+VXuF9SePDx89atewzsTB7dwe6bbbeN3cDWxcP2F+95Mu/Zn7bHVTwaUrEJpljy2m5q5LmnQ94luXhxeeeHk48tuX57tDo5b/5u4numr5cj7+dXuHk976nHD2hw8f9B76VjXQ+3DqpPHhp+8+OF9Vlg6CLFbvNP7UyRNy12Xlms7CTukVdewHL+eTf7yj8LhsVUc4/m/3FHoGtrrCx3NSFa9OOvv2gYPdVnD5/fNyV1npYYVDHaDeNeeZ8Ieb54Snlq3+577tdlL6ZP4Q/bEFAENCAA3Q4nbYZEp43s6b9Hp5dwp9t92o/5Dv//71wNzVJ031fbkk4B6KsPl5O2+cu9byby/cOdxx/DHhE8fske+MLttXGSq/bO8twlF5Qr8a/e28fNfzdggTy6x26f48PPXKmeGwb1xa6AdSzfReI2yxQe9DQlOAUM9UYLkvtQ+/ZJfcVWdRyUv4+9MdQD/2VPW/13Unji+s3kjfo0pd+T8vzl0Ie27ZO5RvJx0DBGh3ffnlYfOpfQ+GHUhH0W7wWmw6dWLuuqQnNT7317vCnv97QcP3xz5qArpqv57WdcBkqXJPsFUKZZ9Z1ntaeihWBtUrTd6nSeN3nX5DeGRh78NSi82scV//YM15qr0/Z0tfgVLvqh4AaEUCaIAR6FOv2CPstOng9wQ/d8fBh8Hp5fm1+MKr9x70oYrNMlqmvcsp3W1cyWnvPqSm91O5w/Z6KfNLdd864fz7czewj501NNNwpeFSvROA5f61bTasfrI8WVNDyDkuf8yKD00cjBRKX/2pl4Rfv//Q8L23PCffbT+1vA+TH5c5vLWcgYLtex9/trCHudST/ewBP/irF+eOoTajwr7sct8Jy021fufC6eGAr1z0zwnitOs7HebXSoq/FM688dHCpPHVMxb0mXouNtR/Zjbmu1frkD8DMJIIoAFGoEb9paURB1xd95mjc1edfbfZoKqXtDO0SqfzGmWgz7EdN+kbui5f1RF2/Mw/8lVrKT1/sd4voSsfmJ+7HgOFlqXWqWEtRvcrLBr0raMgrWI5crfNwsTxQxtCNVKtU6hpF3YK3c/8wGH5Tnn9TTaedtWs8KqTrw4HfvXi8HTJFPun/nRn7vpaXHJoHMOvXP5abl3HDy9/sPCYXqmRnmT44WVd163k+qJDBS+6Z27uQrhjTuWDFodyx38y0iaGTUAzFNIT5enA1Gp21gMMhgAagIrWlKZpdUj7kms52CzpXgdQjd23WC93NNOzKxobbm2wTtdkfLkVG8XKHe71qT9XDuGGW2lgUE+A8HiFlR217rEu97bTXzTvmP10vurRPQHd6EPtkv72fLeaM6Y9HE665IGwJIe5tb4/UpCfQvfn79L/qzgqfWtNH5+vn3dfvgrhOV/pPdVc70GJjTDF7vualfv+VWlfdLclK1eH+59cnK+GR3qSr1Txk4XVDjbf+NCi3A2NBjxn3lIE0AyFn1w5K7zmB9eEl5x4RcPOEwAoRwANQEWlB+LUKx2kmA7wmzBuTNht84ED41oC6I8ctVvuRq/XH7hN7trHjZ/vmoyf0GbTsVfPmF8xCE7TQ3+8pfdKkXoChEov57//yWdrmkQv97bTb/1NP+n70v7uCeg1TUhwtttondy1vi+ec0846ZIZ4eRLZxSu611JMtDqgVkL+n6MU8D3L6dcm696LCqziqOSBUsaF1CXHqA30sK94XLro32fACqWvgaHM3hMn2+nXzMrXw3O//zpzvCzqxvza1WjdOVRu4Vppauu0ioeeksf4y+ec3c4Nn6vvHNO/19LVOdbF3StM1sYv/Z/e8OjhR6gGQTQACNQ6V/CarXdxl2BUTro8D9fvEvYeoPJ4aS31r/HdfP1J4cbPvfScP1njy5MBw6kexqzGluVHPo2Gk2Z1F6TiR89ercwaXzX7/nO2ZVfvt2K3nX6jeG3N/b9C9rSlWvC/l+6KF/1aMCLCP7pdzfODkd/r/oJpXKBYZq+LBeqdj/ps3k/TzodvMNGuavN+AGm3FvRT6/qCs0Gmlat14d/e2vueuz3pQvDnWXWGfy55EmN/qSXUTdK6bfhRrwiZrS5o0xA9p6f35i78tK7ebjy5/Tk2kFfvTh856IH8p0exU+E1DKh/bV/9Ez0N1tpcF/u1R7tpNEHi44EF907N5wx7ZFwe/zYvu2n1+e7NMpiaziAJhJAA4wQR+62ae5CePX+W+euPmOKjk769Cv2DNd99uhw7CCnbNMqjk3Wm9TvS3en5lUdtUxAb79xbQezjRSbTJmYuxCev3PPx76VvGj38k82vLDoc/Urx+6Tu96O2XuLwmP3qo5W8r9n3527EOYvXhkeXbissLahnHpCu/4++xcsWRXOuf2xfNW/Wp6I6n7SZ79tNyg8lrPrZiNj3c1L9+r63KrGyjXNmaB8qswk+7Iyaw+S5TVMca7fwK+XFat7f+6mJy7KfU7Vux8+BR0z55ef9m936dUQtzyyKOy0Se2HAVdawdNMsxctC6/74TVh7+MvyHf6l77vtaLSb7ftfnBwM16R0u5uKlrrsrTC90zqV+uqL4BaCKABRojvvPmA8MEX7RJ+8s6Dwk6b1v6X3mLN/DtbWmFQyQ/efmDhsdq/NO682ZSwxfqjcwL6jPcfGp6740bhXc/bIbxqvy3z3dZy4pv2Dx84Yqfw1X/pHTJPLjoc77k7bpy73r742r0Lj994w36Fx2ql98dQueTeueG5X78kvPDEy8NpVz+U7/ZWz0GeAx02uLLKqbha3nT3muY9tpja1ZTxoj0GfvVCO/jZew7J3cCWr6r8vk6f30Ohlu/nUybWtm+/VqWB2PHn3B0O+MpF4fN/vSvfqU5aFbL/ly8KR3/3yvD7Mq8oaHfp1RBv/PG08O0Lp+c71fv82eXfl0ftuXl4ZvnqwpR79xMBy1atCT+5cmb41XUPD+qVT5+LH780fV/6pEOpVg+nSr/fDseLL9ITD2nK/dfXP5Lv1K+ePz8a7YlnlodfXvtQ4UmKVlDrYbzUxvsXaCYBNMAIkYLYz7xyz/CKfbfKd+rXzJmhB+ZWnnh7YdF6jos+/sLwX0ftGi742JH5Tl9vaMPdx42yz9YbhD9+8AXhq8fu27JTXmn1yhdes3d48yHb5TtdJhSlApWm3Tddr2sVxC41Tt3usEntE/H/duRO4ax/f16+qt4Hzrg5d5XVs0N4zgB/0X94QeUfLz40r5Y9st0T0P19Lr1y39Z8oqOZVvQzAb1LFfvsG6GWEGr8uOZ+LyheSZICz19N6wrZ0t7Qan+fKXw+5GuXxH+/6/ozf6ktvG4naU1AreY+uzJc+UDfJ2rTOokDvnxR4bCwn+UnvE676qHwzfPvD8f/7Z6w02fPC2ffVt2rI0pdPWNB7vr39zsfD9+/uPyrPVrBLY88lbsuKwcI1JshPfGQPn7plTLVhrbp+/ZV8d8pXblR/GTtcPnP39wavvT3e8N7fnHjoJ7kaJTSgy2tKWmsJm2dAigQQAPQx3AFmt0HoSW7bzE1fPKYPcKeW66f7/RlUKM9jC35fEqHUXarZd1KNcbX+OvtueXU8PlX7x322rry51k51f6lt54JtnQifX9+fm3faes0mfiu028IB3714nDhPU923aslgK7i/TaY7wuHVph0H2qH1LjHur9926Wf181Sy8dx2cqOpoZExU+olH5qV7tu5tv5wCtqkw4I6/b187r2Kn+/ZPXPx866PUwv2c+cQtnvXfxAmPPU4CdYj/v97eH/8gGdxeYtXpG78kqD4WY56+bZuevy8MLhndot/VhUsuvnzw/v/vmN4XU/7H0IaaMOgh6M7idRZs1fGhavXFPoh9M9JQcznn/3E7mjHqXnBgznAajAyCeABqBgy6JVFvtuU3kP7GAVh4+D5f8mt4fScLPXBHSFEK/eya9aD7x71/O7VnbUGlyfdnX/IXG3eg6xe6zGHbDpbez8ufMKU4yLV6wJ//HrWwr3a1k/3ewnnU4rWXtRz+72Sz7xotzV76R/7TpM9YUV9pOXWtPPBHsth6UORpqIrdZrf3hNeMfPbug3hE5hYb2rFNK0bbfSJ1fSfvJqPDLMoWA9UkiTdq9XekJi0/V6dvIPt/Pu6gnk0uGob/zxdeHkS2eED/6m6/tCM7z0u1fmrry3njotd0OrnlfENFI1T8rMfbZyeN9qYeDQfMerzZynhn5neitYEr+2/3TLnEHv0X/bab0PcmyFtS/AyCWABqAg7UVNB9ttt/E64fi8f7cZGvmS0vR/vhkeJ7+ta193NUqz3eI1AeO7lw83SK1PcLw1rwep9fdxYpW7XWv5y1w9k6spfN7t8+fnq94aFV5ss+E64efvrX5vcjnpMMn/fU3X95VT3n5Qn8+JauxaZuVF2ntfrbTfetuNugKpb7x+36qedLih5OXexYYofw53P957Qm0g181cGKbFKudnV88Kh3790vD6H11bVwj9uxsf/efBjKWf23+6ubrvx81eE9JoKbA/9pRrC9O/P7piZr7b9bXXfWBgpV32wy3tde5292O9J0cb6dkV/U/GDsVheukw2FJD9SqFSv52x+O5qywFiZUMdxhY+mfS8P5uyvvLraPz/wd+9e/3hv/+4x3h9fF7U9oFX6/0pHUxE9BAMwmgAShIU8/TPnt0uPK/X/LP/bvNUOmQrDP+36G5q96jLXIozmj06v22Cj97d3WhZOl0bfHk6LgGh1HjagySuyema52ArlZ/022lVtUxLf2LMus4ujXqL5LXfuaocNSeW+Sr+r3/iJ3Cw998dXj1/ls1LBg67ujdcjewHTftmYZMQXT67/rtBw7Ld8pLB7xV0uj1MZX8487aX2K+oGhdQ7Gv/aNrdcMdc54pu2e4Gk8vW114LD2sqnQdRCVjWnKOsrJTr5z1zwA1TRInaWfvy0+6Krzgm5cVDgAcioC1HkP0Kdp0/b2S5IG5i8Nd8fP5v/90R77TY7jDtHRo5ED6+y0OdwBd+uZb8RDKdSYO/57s4dC9biY9+XPB3V1rtxqh1Q8aBdqbABqAf5o4fmyvPczNMGVS778sXP7fLw4Xf/yFVb8kntaQwreX7t07lDx6z81zN4CiT7FGB781buD4p2Z93qfdq9W65N55uaveafkwslJf/8e9fcKDeuy9VW27sas1a8HS3A1OCh/u/NIx+ap/Hzhy59x1SQe37rt15XVDDw3wexzu6cr+VDNNv2jpqsJ07w8unRHe/JPrwgnnd4XTA+kOxTrqOGCzXsWHa7aCv9z2WGEnbpIOALz43rmFvhUUr31o9p/nQyFN3e/3pQvDf/3utnynx51zng7HfP+qwuqZ0sPpkvueaN7UdzWO2buag1srfx1Vm5+ngP66BxcUVq40UmkAPtyBeDkrhuGgyVZzV8ke58EofWIRoJEE0AAMqfXXmZC7LjtsvG7YbYup+YpW9foDt8ldb1Mn90y0H7nbprnrX3Fw18gp0u+8+YCaJ6CLfftN+4edN5uSrxqjvxDzsJ16v2y/e1rudQdsXXisxsQKiXsKpq+YXnugnaxf9DF90R6t/8TQ+pN7f0+ppNyTHf1N4L/kO1fkrrx6n+zodsrlD+YuhPmLK+953mnTxnxOlh4UN2vBksI6ju9e/EC46eGnCpO+1ej+PK03qKglt09B+nt+fmM48CsX99ptPJTK/Xb7+3gNt19PeyR3IZyQDyvsVs+an2ZLq7Re98Nrwl9vK79K4bN/uasQMv79jsf7HJj2yT/0nXou1j3xP1SWr+q9I7yaz/X+nlup9mssvR/e/rMbwpt+Mq2hH+M+AXQLfv48OG/gHcgpmE/rh4bre0iznVH0NT9YLfgcAzCCCKABGFK3Pdp1onq3aia00u5Whtf33nJA2HqDroMqf/He5xYekzM/8Lyw2+brhZfutUV45/O6DvQbSPEalkYe5Pamg7cd1K/3lkO2C5d98sX5qjFWrimfLuyy2ZRwetH7Mek+TKiavaHdHn+m8gFM1YYvB2y3Ye66/OYDhxU+1un+fx21a77bGgbzBEG56b3BTOAPdHDjQN+30h7xWflj/s6f3VB4LOdfn9u1p7wW6ZDMD/76lnDzwz1ToV88+57cdTnl8srrRfrznbz/vJoD1gYrTRanVSGLV64JH/rtrfnu4KSA7rqZC8INsxZWFdaV+zNqVYWv61ZQvI/51pI/b1ttVUj6mkx7bNOu6o+f1X+YnDy8sPcTetVM/KbPoc/8+c5w/5P1TUPPeWpZ1ZPF//W76j5HF69YHX58xczCwZb9TRVXO3Hc/WdGmvge6JUbtSgNnFshf37n87bPXfV+dvVDhT8P0/eQWx6pvNe/XTXu/0W15pNUwMghgAag5X33LQfkrrd6ghnqk8K26z57dGGH70uKVm3st+0G4eJPvKhwiGX3PuVy/u9fnxP22mr98NVj9+21s7HRLxG/6N7G7UJsppnzl4b1JvXeh54m/GrViL8r/rDkQMn9t90wXPPpo8I5Hz48rFthZ/twGcxnS7nwbTAT+AM92fGykhU15XQfEjd97uLCYzk/u6bynu9K0oFzF9zzZGEislu6boRL7++arH+2iv225QwU3Beb/VTlJ1jqdfn0eeHtp90Q3vrT6yse1lis3G93RT6IcTjdM8DhlCtW9/09rhnCtSnVGChgLZ14/siZt/WaMu7vz5xuKRT+/U2zwzvix7xW6XvyEd+6PDz/hEvD08vK71Uv9mTJzv+L7im/muWHlz0YvnXB/YWDLW999Kl8t696dlhXmVlXpfTjU20g3kzrVDjIOgWnM+L30XI7jIv30590Sdce95GkUa+SSVZaaQI0kQAagJZX6f9cf/ZVe+WOVvcvz9kmnH/ckeFdZaakP3DETrnrsvGUibnrUrwSYiDLSl4C3U7Wq+G/s5G22XCd3PVo1d2xtYSXpfbcsu9E8mAm5gfaAV1NuL2wwmGBxdK6h+6J25e0yEqUdLjmS793Vb7q8pySSfpKanmPN+Nw0P/3y5tzF8J//OaW3FVW7uN8YQMP/arXa35wTe7Ke+X/XZ27HkMxtV6LtSX7j0vDw9IAOvnN9T3rBsZXcYht947gar7WSnXvnU5T5dUEl6XrIK55cEHuejv1qp51N2kSupJqDoRr9N7nYqVvvxUC6EorS9LH6mXfvyp8cICv6ZE44JsO9m2UG8rsUgdoFAE0AENq+43XzV31SoOcg3fYKFzyiReGDUr2SdOevvCavcONnzu6cODdFutPCr98X+/VFLXYdL1JuWs/3YeaDbVBZLAt7wW7bBLeduj24WfvPiRsuG7vJzaSwQTtA73f0qGuA3mmiqnK5K7HulYpDCaAb6Svl1nvUm0A/fjT1U81N/sQuUorcoo9XGalwRPP9J50HQ79BWnp0MZyqxiaOQH98u/3fkKiGqV5eOnKh3vLfPzT+opuEwax879W6dDOgdRzIN6qfpZAXz9r4DAwPRnULKtLPkD1TGTXo781EB0VnkQ5986u/c4X3Ts33JVfWVLOUP03DKXpT1Z+BU2tWu1JKmBkEUADMKRO+tfn5C6ENx60be76VxpAn/Xvzwu7bm4v9Eiy+fqTwz8+ekS47jNHF1ZAFKvlr4uvaeAk0EhUbg1Fq4Sa1ah1InbXzdcLJ7xhv/DSKtZh1GqgfbrV/F7TKpZqXPtg16qIVglPyoVeq/s7Ta3IjCoODeuWVic0VRXvzrRmqFQ1wfVw2vXz5+eut9JAsZH6WyOTpOng7gMsu5V+Ppdel30Couj71QPzGhe8DaQZ0/hJf/vEi1dHVDLQKzEG4+zbHstdl6GYgE57sZ/79UvCF86+K9/prdxBiKWB9Wt/eE14Zll9K4IqSW/jI2feGg7/5mXhmhnlJ9uHy/kNfEVGK0y5AyOXABqAIXXQ9hsV9gF/9KhdwxdeXd0KjQnjxv7z4Jn3vmDHqvY+0n5SEFpubcH6k6ufdJ86TGsshsv/vHyP3FUnTUYWO/FN++duaL1qvy1zF8J2G/ddAVJJCpO7pYMxB9LMwLbcjt1i1azg+MddT1Q1wdj9S9WTDdz7eOOniMutPmiF4OKRhUvDn26Z02tKtlv63D/1yt7rDkpXQJQzaXzvnbOtfADhQIbzY/TS711ZCO+KdymX/m5K8/Fy7+viz7wmfnn3Uc8Kj2oM9vOpb/7cuHdK6aT/UDwBlvZiL1iyKvzm+kfLPgFR7nO43HT6iRfdn7ve6v1PuPCeuYUp68eeXh7eefoNhcdWUs26lmq0wLdxYATzN3gAhlzaB/yJY/YIG5Xs+u3P147dL9xx/DHhS6/bJ99htPjB23sfktefMQ09D751zZy/JFz74IKyL7PvT/HU7roTx4U3HzI8B3mmr+NDd9o4PG/njfu8EqK/ScO05iG9AiKt1EjfR7rtsEn51T7NXDmw5fqTc1detZPlL/jmZbmrrPvX6u+l6f+/vfuAk6I8Hzj+Uo5+9N57770IKCAo2Ii9i4otllhi7DWWJCZRo8Zo/tbYk9hiL9gVBBVsYEFU7CJSRJr6f5/dd7jZ2ZnZd3Zn95bb35fP89l3h7u9u72d3dtnnnmeIFfNiX/oVg2f1gebKnnA3YbNP6nd//6SOuWehers+94yWyvcs2C5uuQR/6RUmLlLUwcV/vmJJWa19ansIYRrN2xWVzxV8Xj0Pp69p/9H+Rsh35597xuzyo08b7v9mOFAVibeA11x5ohreQ72Fzo56b2vhN9j+Ju1G8yqgiSw/WSbRH/PU+EvB1MuzeL5JF+eNsNhM1m+cp268H/vqEcDqqZHdm5qVgAQPxLQpUne6d2gQ8btyyv2Mh2X62iiIwp5hZLPk8+X25Hbk9sNO6d+ho7HdSzXIYeOZQrHPTrG6ACAUPR8Lk1SNX/QmPThhX4y5fzO3bmvmtS7ZWLQ4Y2HZN9rOl/kFF8b2//lWbX/P+cmqj2jcL95r8yBjS3L66i7jxyj7jxijCr3VLgfN6mHWaWTROyors0SLTXciZebZo1UR07oqm9vtNmS9NonK80qfo3rhT8f2SaLbapSncd1NskTOYMkbn7HCHLpHeq+rxZ/uVoddesCdcMLH5ktduS0eKmcFPe9IX+Spjr9v+mn9NskzaWnrNuGLPr8Fgtv6xC53216G8dJhmo6vA/9lz9MTfaP71EcQzfjJM/bcfIe6Ir+DBHMe0ZRvirovWfmOH7/0LvpgxB9ngOvevoDs0rnPcMk25/A7znvWs8ZFZXJZqCqOPb219X/6edWGdb46XfrzNYKrRuFH1gFgFyQgC493XTIK9QsHfN0/FWHJIFP0PGyjmY6bMjHycfL58mrr9yO3J7crtx+Vx1ef9DxPx1DdTyq4wod8k57Vx0v6jhABwAAaQ4d18WsciPVtTccMkLNP3OK2q53S7O1eDiDlBwnb9/TrFJlmwf436L0xFxlG9oxted3swbRqx67NK+vTp/eR43umvpnjE2CsV1j+xYgbpkqnONM1tQwXyuL/LO6/43PVefTHjLX4uH3k8vXCbPyh41q1o3yp2I691114P/NU4++/aW64H/vmC12CtVe4sdKPHCTK+/+3+X0h9XQC58w1wrD/Ry3wVP96+2JfoVPD+TC/Jaj+6CA/ajd4mq94GeAZx5DPvaxfa97RfU++1F15zz/iuVPPElSv+9h7kfBwxql93iKLH+EXAbWFoLt7+aNT5MDbYVf1XQ2Z9kAgC0S0KXnGh3yjvt4HbvpOE3HJB2SQJZGkhfpsHGxDnlXLJ83WYfcjtyeJKTl9uXruEmzx1N0SBlJXx2H65DP2UPHNB3yqn6BDgAA0tj00xWZBjItN30bK/vNZP1aqX1lg2zTo7lZxWPZimgtOwqhQ9PU9hkzh1S01siVTeV8vnp5epPhuXAe14XowWpjzhL/dgTu/r5e0hoj6PPc1dPuCtkoCpR/VnfNz/NgxDxyVzs/8mbqwa7K8NjbqW0AvJWwq9dvNqsKToJMKuWLyZS/PGdWheV9SogzSexNbsf9/HPMbQvUy0tXJFpDneZzhoK44cXUMyH8hr+W1w6e/eD9m8CvglrI4+qCB99JJMT9ek9/vdr/eUnaYBU6aRu19VYQv+876P4BgDiQgC4tUpU8VYe0zLhaNricq0NezQ7UUV82hJD/l4+Tj5fPc7tKh9y+JJXdVdDyDlAeb3Lemfdw6xwdUjZQ9c6zAwDEwm/omZ8M+Wf1/HvFMb3+X4ePMqtwDy78Qj1/6nbmWu6KcYCaN0FQp6yG2m9UcuhoNvYZUdHXOpfbydWgDo3VsE5Ru5v5+9JiUGExeMnTQsHtqZAepTl070AEE3tW/Kn95merzKqwJri+B29LkE0WyVPJj0niTNq0lIJMFc7epHCmBHSUCn7vbcWZ3BYPv+nfh9jtlpc/Nqskv/tjaUhC1nvwOiiJLq12JNktCfGDb0g9U0N+7ptekre36ba77Bm14xXPq00BbUTy4YcN6Qdm4lLAHwNACSIBXVqk0llID2bvy4skgKUNhpQhpTZQTCf9muV8Vfl47/lmcrty+8L9jlkmjkjZxUgd3nKuCTrKdTyZuAYAgIdtBXTQMDpHId4k2nyr0oNanLqDnHwUTCpKpUL4rfPluG7uijEB7b275P773bTe5lp0F+7WX900a4R69cwpqnZNu0rzfDlkbGezys3tc5Onpxd7cVrjLPv021bdhSVeZAihm7s/q/f/SpW7rUmtmpXzNvA51zA/6fHrZvP8/Iv+JznIZSvS+9fGKa4q01ydeZ9/ZbDDm1ANSrBK0v6QG+epQec/vuX5JBPvfpnvQaNBlcSr128yK6UeCRieF8R2SKN74OHXrrMwnl78lRr++/A2NYu/XKOmXV64Cvi4+vr73RVB/bgBIA4koEuL8y43vaFakjOW2r/hZIVsbkeac/1ORysd8tfvdTou0XG3DklYyyv7kTpsSMmDX2T/bhUAUNSq+XadrTDE9BGuV6umuv3wUYnWC/84cFhim1shEtA2RWJOJVl9/f2G2XlQ28Rlg9o1Va0Y3nRu3AreXEpv5UYZBvyFkTfn2/ZqqVqU1zZbKs96T4/bbDktKsJ6nRaDsiyTmj+ZxNbXGSq9l68Mbpdywp1vmFXSpY8sVh9+szYx2K5YznyobB+vWKfOf/DtxHqtT3uLQgmq6rVJfklFbLbP41Hajlz6SGpyvLLcMS+85Yv3rgyqUpbnjmeWfJN4DTjj3vCktsP7e7ptbmo1ctz8ehKLr1ZlfwZIegLa//4JcuhN89XKdRUJ8CBLPf3LM5GDaes2ZrcP1rNs4ZWJ310R120DgB8S0KWlkbkMOufO2Z46cSJdtrdzuY5f6ZB327N1SA/oPXXIX1Y36Qg+NxMAAB9tGtVRuwxqq67cZ4jZotTY7s3VBbv2V9P6tVbX7C9zbyvku4JLbKO/fibO+/pMvajru3pb1o6hYjHb/rr5FNQ2Zfeh7c1KqclFNjBy1ji7yuYm9aIPVPQT96nv+SQJHun3PO7Sp9WckLYbbk6l5d+e/iBxGeRfr0RLgE3+87Nq3+tfUYffMt9sKQ7HTepuVoV344vJVgL/fCG1t24h7XzVC75JaHl+Pu0/ixKPnafelbEx6das35z1/nD0bTL73E4+drmoyU8b3tsMqoD+dm3qc/97X61Rf3/mw5TKXy9vBfTz78dzICfofrhn/nKzSuWuSPYzsL3z1jSd9yXW+b2uWb8ppR1J+CtxvOS+H33xU2rURU9V2vBK4fdb8P/NAEA8SEDDzXntzfW1J+h2TtXxbx2SbO6mQ3pJS3naUh236fijDhvyOX6xWAcAoAoKesP68umT1ZX7DkkbZOfwVj9lUzk3e3wXs7Jz4vY9zCqYkySokaFpda9W0qEqqXZZ7n+2vbpspVkVD6l49nPWjD5qbLdmaninJuqimQPM1uLQr21wwsMtU0sYW1tL/nn5ynWJPtD/XrA8Mdxx1k2vJrZnShg6/+8eRujn1ogJaBvXPPOBuvf15QU99Xx456ZmFa5L8/rqt9PC2/QUwt/0c2yc3v58te/v8qUPv1V3vvpp4rFz2M3BBw38BtHFLfyZOTtr8tC713tX2D6Mp/71OfWHRxer/f85N3AQq3e/dQ+xzNY597+lhv3+SfUf/Rzh9ahnKKVDEuVhgl5D/Mhr73kPvK0GnPe46nPOo4nHXFx2ueoF9bHFoN/j73g98ViQOPb2183W/PNWXPu15NqaDnYC2PqQgC4tTmVy0LumhuYyqLLZkc3tbKvjDzoe0HGSDkk6S/M2KUWYqeMzHSfrcA8uBAAgoV7IlPswNT0J6CMnyvHPaE7dIVqHpwa1M7eP2JKAzvCXmLsVRWX3M86XoNxBk/q11O2zR6t/Hz1WtW5Ux2wtDjsPamNW4do1kZEZSWU1qqn+7Zw/kaLLR/Vk3CRR9MHXa821JOljvuTL8Co/J+nhHUjp541PvzerePzx0SXqxLsWqt3//pLZkn9PvGPXx/bkqT3VfiPjH6QZ5bE0fUBrNaZbM3MtPuc+kGwF4mZ7hkohWinFVe2bb96K56AEYlj//xsCquGDqqmzJc8N0kJFEtkn37PQbM3shQ++VcN//6Q6+W7/z4kylE8OfrgHCu53vczHj5bEDrJo+Sp1vKcVkB/pGe1wr21lOgCzat0m/by2WN344kcp+7r3MfDJd+l91ElAA8gnEtClZYm5DOrx7JRsBfV2dmRzOzuZyznm0k1e/WTcsDwe4y2xAABUCdID+XcRE8HCWwG9Xa8WZmWnY9N6kQf+yJCsTJxCT5uEmyOOFhzFKI7e1oVmezBAepLfcuhItd+ojuq+X49TV+2b2hLGz3UHDkt8rJe0Lags+47sYFbhJDHifUgfeauM6QjnnOpvsz9IH998JOMXLl+VaB1SCJt/+kUdPznzmRI7DWybOBBzwOh4k9BdTn/YrML9amg7df4u/VXzBoXpp26bSLx7fnhf5DAzrnxevRTSdsLxY0z92/OV0JN9QO6H65+Tmp4KQUnjsG9jZUBlc9x5/kw93sNIC5H/vObfosN70MsR5b5//v2K4Zi5WBjzATI/d74aPkTysseXqGue+VCd/+A76rG3K1rZSPsatzvmpd8OCWgA+UQCurQ4yd+pOry/eznHV97tyDlYr8iGEPL/8nHy8RXnBifJ7crtC3ey2fnLNeidv7M993O7AABV0tHbRq9e9ia0oiR8RTYVYDafUlEBbf/9ePtxVhV1ymqo30zpoRrVLVNnTC/8POGerRqYVX5M6NlCXTxzQKJtR+fm9dWf9xxk/sff1H6tfVuzvPXZarMqvHe+sKvSk+TFfE+bF5vBiU4/YJvd4R/PLU0kUKWHatxtM6R1yKvLKr5fGWKYD3sO76COcT2ftW4YXuEvSeBDxtr1HY+LDHL9y16DtwzzbOIZDDrUDH6N0+r1mYe9Calaz5ZUwO73z7mBgxCFTRsFW88sqeiD/kuMD9cn3/1anfrvReq/r8tJpBWCEog/hbS3CUxax5SMvO65D9XIi55UN7xY2L7jmVr6uH0YcYhgZXpHP4bDuNvbXP98xQGKTDMnBAloAPlEArq0SAOtx3XIX7C/lg0u5+uQnsy36HC/Ass7Qe+7Qflr/FYd8vHnyQaXY3XI7T+mw31I/nlzeYSOdsnlFjvqkGS2HBYv3PmPAICSEzH/bJVM9rKpFpREpIiSgP54RfrpslXFb6b0VG+cs706YkL0gwy56t06WluMXBNvNWtk/p1XL7K/0G2r+uQx+sDCz801e84p5VFOg/9y9fq89IS+ek7FIMS4EpGn7Zj6p7Ts9nLg5Z6jxujHfFf1r8NHmv/xJ88T5+3Sz1wrjHWuAW3Ce/BOeu+HySZhvn5TzCW3Ie5fmJq4dTvU9C6Pw1pXVXecBxEvfeRds0rl9zXWb/pJPRfSUiSopUMc368ksS9+eHFikKAkzQvprc8ydZUsvDjO3ojSgmbxFxXJaps/N6rqgW4AxYEEdOk5Roe8+l+p4z4dl+h4WseJOqRlxpk63OSvG7+/cM7QIR8v/Zyf0iG3I7d3hQ65fW+CW4YPPqmjlQ65vZt1OD2hH9IhL4mn6VihAwCAWHjzWTbvrfZ19VydNS48iTKicxOzSqpVs/qWikGvx34zQR04upO69bCRiZYiImpFdlUWRw/ObEhyxka5/p3tPrS9+vdRY82W7Nj8zsst+ohvTTJVtjpVd7a/C8c98/1Pyc9FTVf2/7Pvs28Z4Lb/KP8WGiM6N1VnTO+jurcsVzMG2vUVLxSpBnfz2z+v2GewWaU7dlJ3sypODy36wqzSxVkN637NiaOnshwU+c2drwd+j35Vy73PfjT05w36tuKohs39FrJ39L9eC209Uhk+/S594GPfcx5VZ977pnVy+pWl/meV+H3+D64DSTb3RSEGfAIoXSSgS49UQQ/XcZOOUTpk8J+UG0lCeowO2wSwfJx8vHye/IUptyO3d6OOYTq844rlUO10HZLofkeHDB6UzxmtQxrRTdMhyWsAAGJTLXF8s4JNAuC0HXoneq4eOaGrOmhMeALa2x/60HFdzCpdr9bl6sLd+qvxPSq6UZGArnyPv1PRIzPIuxfsoBadN1X9ea9BVqcxh/EOxvTTsVk9s6oalmZI6GXTkkY4Q7Ti7An95LtfqW/WbEis49o7vfu533c7pmv8g/7iJD143SQhHTacMK77Ll+kGvflD+Ope1m3Mbh3tftXH0dLi2Nvf13d90bwWQaSaHZ/nVeWZv4Z3/rcv1I4m4S57IvuA0lxJN2zJVXX2T43yFDSZd/GdyDC8Y1nPxJytsFtcz+xei0Kk+nh9a15XgsTV9sVAPBDAro0yeSOWTqk1KKWjk46TtDhdzhV/mwK+htSPl4+Tz5fbkdu71AdQeUoUv5yuQ5JOsv5rlL+1VKHDCiU1iAAAOSVu7oxSKN6Zer3uw1Qp0/vk6hoFi/8brvEpZc3YeadMp/JVjh/ryTVrVUjtgrtXBPYlWGnHKtzM53WLUP5RNS72GlvEHfO5Jz730pcRjnVPYzNgSabn72efhwWE5vn02J2wP/NNSs7QcnMZ5bYDbCL43H6Zoa2EtIT+lnXQL33vsrcvz2ovdOKtdFG80jF9B7XvpyouO582kPq7c9XVWoCWjwf0nokzIKPV1oNUI3q4of9W6eI1z5J7Z8fZFin1DOvHJnu68uflJOXw0U9CwUAouBtDwAAqLK8SZ12TeqaVTTtm/hXpHoT0HM/ilZR9/on+Z+Yj+ISVgHtHkxXTL5fZzccLkgdcyAniJM4WWw57NAr7iTXI299mbj8MWIy5qiJ/r8/b562cd30FisTe6bO6R7fo7lZVYhaIZ5P8p2EfT+V1VIniqgtJlb96L8fhB14dN8Pheqv+9t7FpqVUmvWB1dnh/ng67XqiqfeN9cqhFUU/2/R54nErWPGlS9Ueh/mvzyROekaZIlF8j4q9/3j5RyIyySoMjvT43mlxfP4HMuDKQCQDRLQAABgq3H74dLtKenyvYP7jzq8KZC4Ezg1PEmWt810+lYNMw8iFM7Ho3SEVUDvF9Ar2I889JrUK1N/2mOg2ZI/m3/OrRI4U09dSZx898NGNT8kORMmX1WWA9tFGzgZlKCUCujzd+mnatesrvYY1l51bdHA/E+FVg3rmFVSa8910Vj/vv0cObGrWRWOPP6Cnk9r1ahedNXacZh9y3yzShWW+JP7wlEZ7Q08L1HWTrr7DbNKtdonof3P55eq7f/yrLpmjrcDo7SyeNmskElYKxe3Ffq50k/Q06Bz0CDqARcAiBsJaAAAsNUY2725ev3s7dXLp09Suw1pZ7ZWnqBkYrvGdpXWGzbHd7rrpN7S1QrFriykbYE7gbDPiA5m5e/pk7dVr5wxOTEYMd9sK/OCdGtR36z8yeCrW15eZq5Fl2N+PFCDOslhobbumPeJWaWSBPTBYzurN8+bpi7bc5DZmsrbpsMvcdi3jXSwS7dj/8oZYOg9AOfYc3h7VaesRuDPmm/yGpEPry7zP0ASdgDkSlcVcbYHSlZFPAPh27Ub1cJPv08kHhcEfM+ZLFoe0Bfak8SUgy6/f+hd9f7Xa/NSMVwIB0ZsxZKNN/X9OeUvz5pr/u58VbpkBlvy5Rr1qel77yeowt5pQ5KpfYtjs2k9JI+hd7/gIDmA+JCABgAAW5Um9WupNo0sW2lkWf1l6/WAno2tG6VXL/qRN5RxGdCukVnZGdIxWnVnVTWoQ/j98OJpk8wqHk5f8UyODGjn4JBWHrVr1ihIT2lJEOdChoGFkcRc2KnpQaQCXOSrAvqnLDLbH10yXV2xT+rZGc6vKOx3b/NrDKo4DkoE55Pc5X7HUkZ2bqpO3aF3Yi3V3ssunZFYF5K8RhSS9IgP8o4rgZdtBery74OTjkF2vfpF9Y/nlqraZfG+3fcmOb9fF61PdDHKtk90FPv/85VEW5MwYU9jTy/+Sk27/Dk1/o9zzJZ0QY8vZ6iqrbc+X63mLP468Rja8Yrn1d+fSa9sB4BskIAGAABVVp/WFRWDTrIqTlJp5qd7y3KzSmoakBCR6fdxaWnZ9sOxbgPDhkSm1J1tNbutshr+X7F363LV3tWjvG5Z9i0MpvVrZVaZ/dmiSjXXU7f/9NgSs6ow3DVIS24/myRQf3PQJX8JaLOIQHr+Tu3b2lxLsumH7P0Yvx+pZbn/ga2wWYD57CvuHUIoz3N3HzVGNfLpcV1V/PWJ99Qjb35hriV1ahpe4e/I9nGa7cP70kcWqxYNMr8uRDmLwlsBnevBqarogH/OVYu/TK0c9mtdEsWhN/m3f3EL6s8d9XG329Uvqlk3vWquKfWHRxebVTx+1H/3zF26YkulNYDSQQIaAABUWVIJd/1Bw9Xewzuo22ePNlvzx6lQHNO1WeLSsWP/1ISUI6inazb20j9jFEdMKHzf2GLUsjxa4j5XQVWwdx05JiUJGZZU9GrrqbiX0+FtlNeuqbpmaI8hNuUhUVDm6o2bbYJ7m+7JQX2ZKqyzlW3va+n17OzbLbJ8fPndJb+Z0sOsKtQpqx7a216qkbfva39AwjGyS1Oz8iffnvfL3jxrpFlVXTKY7+jbXktJMLoTfAPbB5+Jkm2uNpcDQBst9t1uLe0S6MJbAV0Zfa2L3QsffKt2uPx5c61wpNJ5/rLvzLUKQT2jK4MkyWde86La+7pX1Kn/WbRlmySlAVR9JKABAECVJsmXP+wxUPUJ6J8apyb1kpXOwztXVHeKwQFtHu48YoxZZWfnQW3ViVN6qkXnTU1J6NnYPkKVbFV2nhkOJ/5x4LDEZT65h5K5eatGM7VVcCe9JvdJ/V1O6NHCrMIN7tjY6nGTjypHd9J0zfpoPW7dJDl3yj0LzbV4ZdtbWtqi3HnEaHX85B7qjtkVg1Oj8KtabGyeX9yGd2qa8bEiB+GiytRTXpJGcsBklElUD+vURA0ISL7OLGC/fifh/7d9hyTWUZ735bF09ZwPzLVwd877NFHBee/ry9VDrorosGr3bBPJuRwAkuGemfg81AJ5f4SgvsOVpWHEvu3Z8BsQ6ueaZz5IJIXvztDbOS7S4/nGF9N76UslfK5yeY52e++rtWqxaT3239c+Szy2u5z+sOpzzqPW3+fXa9Yn7lO5BLB1IQENAABgoUvzzFVizimw3qSeJIr9dG/ZQF24az9zLToZSHTClB76TXcyedm8gX3v0/CUVelo27iuevn0yeqZU7ZV0/r5V6rHyfZAQVhVq3Ans7wfavtzyG1k+jri7J36mlV8pErQccVTdkk/L7kHjrltgXr9k++TG2K24odoldXuMxp6t26oTtq+Z1o7Hlv3vv6ZWYWTdis2fcAn9LQ7KOGw7Sv9f4eMUNcdOEzdNGuE2ZJul4Dnv3yYd8bkxKU858r6T3sMTFy3cff8T33bxfiRAwT3vfG5OvGuheq655aarcl9Mei1ItsEdP3a2SdVH3v7K7MKFuX78vZ8znVAadzaN6lnVvlz9f5DzSrcHx9dok7998Itlb75Jr/HqO02bK3fFM9ZMN7By2fd+5ZZKXXts5l7TcvfWIffPD9xn87WlwC2LiSgAQAALOw/qqNZVejrqa5zv/mThOZxk7qr+349TtUJ6ed74JjOZhXdG5+mJt52Gmif6MkyF1IlSe/azhYHGOJQZjmEMFNS0f3781Zd2iSVhSQsZJhhJuNNq4t8edc1qC2KRcu/t0qwZevih981Kzu/GmLfSzcu+47saJUs3n1otCrkTI+/tmYQbIPaNdXUfq1VuTkI5sf28Zirh47fJmVfkPXylfYD/KRi1ZbsO36V99X11wzq855tbjDq2S1uQWdcuH3+/Y+JS+cA6vpNwe0QvN9LvhKe2aoZcN/HqV/bhmquOdCRyZwl35hV/slj8pG3vjTX4uU8NnL13Hup98f/Fn1uVnbkdW/R8lWJ9UJ9Gdf3BaAwSEADAABY2GdkegJaTjs/eEwncy31YyShefLUXoHtN9xsekHLm16vXE5tz0dfX2Tml5xq7jMoLFNSMSypZ5uvSiSgLT7YpsK2Mjz8Zn6SLY6vVkergK5bK/9vrZq5Bpo+f+p2id+fTYJ37YZoQ9Ay3WSUx0QhkoLCb2BolIrYT79LJmJtSCLMj9wt0mbAbcXa5OMoSruKHi0bmFVyP83WpbsPMKtgd776qep82kNq8AVPqFteXqZum/uJ+Z903oRzDt9aXmzcnP/XNTmgXMjZAe9/lWxZkUnYIOJce3WvXBfcgkP6Nx97+2vqkBvnqS9XhbfFeHXZSrNKivptefvyL/32B7OKj+yv/16wnBYfQB6QgAYAALAglX4yzNBNKsdOmNIzcbr3XsPbqxMmpw8Js2FThbr70PTqyl0Gp1Y8e3tPh/H2HEaSO5nnN/QtV/4VienvwjMlFTs3q0iseXPVYX1o3SSZZPPYq0zF/P3de8xYs0oqRDLuttmj1G56v//znoNUh6bJx4BNMti2tYRDKnnjsvrHePrHhrl878G+PbLledvGa5+kJsYyCUro+e17Ty3+OnEZpVrYvf9nOwxT2ByccKzSv6dz7n9bfRfSemaJ6d/ryCU5ng9Of+F8k9/zlD7hfdJz8cOGzeoyvc9e/9xS9V/LdjxH/es1s0qXax//aZc/p/b6x8vmWip5bvnfoi/UM0u+UaMvecps9ec98P1jSLW9H++u8F4eft9H3rogcXbDrBtfpcIaiBkJaAAAAEt3zU8dJiSJBWnfIAOv/rjHoNBWG2Eu33uIWQVr6JMw9iYzZwxok0iE28jltO6q7J6jxqiOTeupiT1bqGO36262xsf2fg9LAJ41o09Komu7XhWJEElM2yYPP/luXcGqU92k97mtU3foZVaF464+DTOkY+oBn0K0I5De0pfvM0TtPqxiPw+qlr96v4petd+HVDD6GdIx85kbtj74OrUiOKrjJ3UPPUtEnn93CzgbxCYBu/KHjepX17xkrtmRZK0faQvj9epH3yXaJYVVoY7vkdrmxv088drHyeT4AwujtSsQ2Twm73s9+OuccOcbZuWI/zEvz29bg2sPyN/Q2ptfXqaumvOBuujhd9Wd84Ir0t3Cqr9zOYjhmKcfx+98nt4u6YYXPzKrpLc+S7bI8NPM52yfIPK8IT3+u5/xsDrsplcT/aO9P4cMXozbfLO/va1/1qgJcgDheOcBAABgydvzOS7jujdT1x80XI0IqWD2G+TlrQ6VpKQkwpG9oR2bqGd/u626+dCRVu0povI7SOGXIwpLnEmlmZsMmJPq+yl9Wql/HjwiY/sEx7drN0aqkIxLPhM3cXg/24RpjLm4KGco+P0O/3fcNmrGwDbmmp19RybP8JADMAPbByega1n2MXesidj+w6tRvVq++4gjaMiraN8kvS2HV9Q+tOLRt/3bv/gNa7tnwXK129UvbqmE9uN9Lnf/Ts++/23139eWq+PveN1ssZdN3vGLVfatSPLh8PFd9XOE3aC/QnP/XuT1QQ5Y5sM985ebVXj7C1vrNsaTSP3Do4vNKtjDb35hVqkkgfxghIMo0698PtFmSaq3Zd/5x7NL0w785HvoZJEV+ANbPRLQAAAAlsrr2J3OHZUkjrfv20rdfWTFm9lTpvY0qyRJ+lx3YGriLujU+z1c1ZGIzu80+rj4JQv93uMG/GoTFpgKLbcTt++p/nnw8ER1cZT2CTWrZ/924M4jRqsxXZuZa/ZsK6D9Bn/amNw786nxA9o1UssuneHb2sbRtUW0wZRxVkAHVdj68XtM9dc/n9sf9xhoVsEu2LW/WnrxdPXcqduZLf6i9pPN9W4Z1aVp1hXZsi9fsc9gc81f1OrwbP39mQ/NKp33LvX2/T3p7vSBhzayaZER9im9WpWbVdK8j6K1LrG1Q/9oB08KRQ7OuI3o3NSs4iPtNz6Kubfxhph6Y9u0qgl6/Eg7kSi8Fd3Pv/+N+usT75trSQ1i/pvM23Kj2FrMAFs7EtAAAACW6tbKrsWGLUmWSFJs8YU7qGMnpfcfbtMotZovKM14xvQ+iapY72nd2HqEJcEznRbsl5AMkksLDhmMedyk+NuUOE7bsbdZRfN/h4wwq2Db9WqRuJQhbdLCwc+ew1J7vrv5DRetrFyFza97bLfMBwrkwIVNP+kow/TE3iOC70cbkkw/fUf/tgxHTOhqVsEa1gmvJr8uYmIsH7wHL36IqWL1trkfm1U8DnAN3RXZVI/nk7vtTD78de/wgxm5OGRs58Tl1XM+SFzG6bOV8VS1r1mfejbDJyvWmVWFoL7Jlz3+nlllRwYY/ue1ispw8fAi/2rrbHmfw0lAA/EiAQ0AAGCpbpY9nqMK6iXdv11qC5CgHKX0pb7l0JHq1sNG6dviz71id8mvBphVPCIloH0+1n9QYjpJkg/yScTGpbxOmaoWeJglnAzpC+OkFaTX7vQB/tWWIccA1B2zRycupZLaMbVvK7MqrPoWg/ZaN6xjVsFsHzZRK5q7NItWSe6ndkDbj9FdM1egZurNn2uLEK/hneyHwTpaWfx+srFwebw9cr3V75U1JNR7hpBDnvse/c14cy1+fgee4tK8QXKI5jUhlfLZmn3LfLOK17F3pA8+XL0+/YwCv7N2wtgO/4ujt7Wb90BQ3LcPlDrekQAAAFjyJqALXWHsrYoNq5LF1mP7Pv6JS2/LFVu2LTikxYRfslrawTjCehFLotom+enmPYU9iDN07peIjZWdhPDMIe3UP0Luv40/VSQW5D5w/8yOoJYa88+asuVsCKm4lK915vQ+alQW7UiCRGk5YTPY0qafeb6eT6SqOteDd1EOqnhJC49uEdupOBpEfHyL22aPMit7Uu1frr+W/ArCHreVbZNrvxF7j8iuTU6uwh7zNgdbsiH7fT5Jr+N8CWvpk8tsi0U+BzjumJc6rFl8vCJaSxHbg1wyGDFOaQnon/L3OwFKEQloAAAAS+08A60qu8VFlF6/KE7N6tcKbHswtV9rs0p1ZIa2A7bJOvnaZZ4e0Cdv31Ods3Nf1bxB7UTyTYYx+rlsz0GRh9EJ25YfTl/emUOi9TN3Kv7lPp0WcP+JG19YZlZJ5+3Sz6wqvP7J92aVyv0TdGxWL3Fa/myLVhCZuPs0x10VX9mi9tP2yqVVjDwWHjp+vOqTRaKtXhZtl2rXrKEfe9Gq4WV/e/mMyeqF300KfdxWNu8A1Kb17YdlxqW+/p3sF9AfXlomNK6XrCSOk7Qbkt9RPlVWu4cLdk1/7otblJ724pu1G8wq3GpPS5BceRPftOAA4kUCGgAAwFK/tqmDvQ4Z28WsKkdZDkkZVB53VWXrRtGr9TIl0mpYHJiQU+f/sPvAtOT3vqM6JtoBvHTaJDXvzMlbTjm/64jRiapkGUL2zgXTsh502cMMIPzttF6Jy0xalNdW/z6qYjhnJmfv1Neski4P6NnqroAW9VwVuk719RPvfJW49MpXpfAeQ9urG2eNUA8cO071bp19VWJUx0/qruacsq25lh+5VqUGPaZtW7RIGw6/KvdMduifXTI4m9Yx8rzQrnHqQc5i88IH35pVkm2lajb8DqRJa6knT56YaM/jZ3KfzANIs/H256vNKn8qK9lZiOPY5z/4jlnZmbP4a7MqLG8FtPd1IpO3Pluldv/7S+rMe9+0biMClBIS0AAAAJa6NE+t4sumAjROmXqbojhJklGSK9LCIpuhVkGtIRyNM1QlSrLxxdMmqa4tkslgN6fHqzy269WqSJRLe4l5Z0xJ9Fd1b4/KqTTeZVDbxKWN4Z0z9/l19GxVblZJHQJafnj7qZe59uVNm39WCz/1r34W+crXyMGA7Xq1VAPb56/PrJ+TpvZKe26L27DO0fsiuwVV9Udp0VLL54BdpiRRlMeem+fEgior7pzpTgMr+rH7PTfKcF3vMF63ynhN/Mte4f3mbUnv5yNvzU+v5jDFVOTr7I/5bEcSxvtlJ//5WXXRQ+9YJ5NPuWdhot/1bXM/Ufe+/pnZCsBBAhoAAMBSr9bl6vBtuiSq1PI9bT/IroOTiTvpdds1z0kj5MeIzk3Vi7+bpF46fVJawtTLr/q3U4ahbg0yJIgl2Rg09CysuleS0rlW/zrJo/I62Sexw3gTlUGJy+UrfzQrf5JICFJE+RpfQe0JciHtWnJxyNjOZpWdmgEZ3SiVxpN9eq0fcuOrZuWvLODxk4nNfuK09zh+co/E5dYo08EwG/uO7KBmjeusfjW0nTrf1QrHe5CqYZ6eM2yEnfHxq6HZnQ3i57G3/c+6yKcYfoUZSX9zG04V+IbNlTP8z+/xfP3zH6lH3/rSXAu3+Ms1ZqXUk+8W/ncJFDsS0AAAABGctVPfRPXoDFelViH9ec9BiXYIdx85Jm+tAJB/0nrDpqeoVGDu7kpwtCyvrYZ1Cq8mDeopHcSpOhzZpWmi5UUc/r5/+AGafPRpFd5WDUGtG5xK7yDvf73WrNLFkXTLp6ChYtcfNDzReiUb3U3rlGxJ1fyCHIa4VQt41xqlAtqvD/Wz76X2NPYKOoCRiU1//idOmqhumjVCnRBTAvrUHeza2sRB9h+pCs12X5D2PhN7tlBT+7ZSp0/vo87duZ/6y16DVTPPc6L7wMWDx21jVv5kGGi+SOuhuG3bq0XamRiVoRDPZ7Z/qjiVz2vW2/eMXh3hYzP5JSDv7e19bmMTAwyBNCSgAQAAtiI1a1RPtEOom8VwLGydLtytnzp3577q2gOGqnlnZp/EC3LFPkPUfb8ep/512CizJRq/vrXZ9s4NcvqOvc0qnDfREdQKISw1kCltkCl5XaykB/IrZ0xWjepGHxwn/cKd5PUNhwxPXEblTS667ZBh8F5QQjdKBXRQFXWYbA/y2TxGZL/ZtldL3yT3dr1amJU9OVA1pGN4+5aLZvY3q+x98PUaNfGyOWqHy59X3/2w0WyNpmV5ncSA0+sOGq4aBvRzFmfN6JM4cPK/47bJeObH1jaU96ZZI9XewzuYa5Un3wloOVBhOyzQSUCvDfj43q3TDwTc/eqnZpW7oPsiyoEuBwMMgXQkoAEAAIAiJtWjs8Z1UTv0z0/VvSTAZNhgtj3Nbz50hOrcLLXXctzV+UdM6Kr+tu8QdcrUnmaLP+/XDapgXZMhIeJXLevYms88kKr7Y7frbq7Z69y8fmIw5dMnT1STekcf5hdGKndPnx5+gCGocntc9+ZmlVm21czZeOjNL8wqO4eP72pWwaYPSE3al9Worq7K0Brqx40/mVX2zrz3LfXpdz+qJV+tiTxcTkRppSEHXOXASf92qQOA/eTz19sgby2DKj8d07V5g0jDLyWhfNljS1Tn0x4yW8I9uMh+X/ji+2RrpLUb/J+f3S0uHDe/vMyschdnMv7pShqkCBQzEtAAAAAAsta9Zbm6eOYAcy1YA8s+oH4k6bvzoLbq2EnR2hUEteAY7mlj4v2oyb1bmlUq6b3evEF+2ofEJVMlaNQWLY6WDev4Dq7Mhdyfh23TJVHdKlXuMpjTjwyXk9+/m7RnyPcgWNvhY3GrU5b552rhqSiXX6skEoP6dY/v0Vxd++yH5lr25n70nVll5/xdK/o8xymfx4WkP3U+ZNsSJ07SDuozk/i18djbX6qr5nxgrgVzksj3RxjG98l36xKXawIS0H7kYMifHltsrkWzYfNPKQdlgoqWl61Ifl8AckMCGgAAAEBO/JKa3iGZdx052qwKJyjZeuaMPmblz/t57ZvUTbSeuH32qKKvgM6U0yqCnNcWDxw7TtWumWwndOTEbuq9i3ZMrP1cuc9gs0pq29h/kGacKusk+h4WPYclKe/mPC5XBLTFmD6gjWpRnv/7LJOOTVPPlohLlHYsUbRpVGfLYzRuP27KrSJdqsML7ah/vWZWwc69/y3V/9zHElXSUZLJPVomH/dBLTiCXD3nQ7Xg45Xmmp1Pv1unxlzytBp58ZPq7c9XJbYFHXCa99F3avu/PKtujbHaGihFJKABAAAA5MQv9fN/h4wwK6W6taiv+rXNfBp93PwqDC/bc5Aa0jF4kKPkILxVxHXLaiRaT5SH9KutTPL9OYZmGFKZbd/eOBw3KbX9R6ZkfoemFa0BvB9biBartSNWWI/oHH7fO2T4YJiwvsiOmjVS749MBxbkZ/He/5UhrgM43kHAx0+pODuiPIezLbzqWcxb6NkquzMDogzb87OL56yAfOvkabUU5OaXPzarZPLWljNQMJv75a3PkklkW6f+e1HiuVDaMR31rwWJbWHPKTKY9uz731YbNwdMKvQIGgYLlDIS0AAAAABy0r1legKmS/P66v8OHq6On9xD3XnEGLO1sL5Zs8GskiRRu8ew9uZaBW9OzJvMiylnljdSXS6D687eqa/qmaF61q+PaqGctH3PRB9qIUPoMmkVUrHbpF7+DwZsE6HHtDh3Z7v2EhN7Rh8y6OUdqpip9crwTk1VfU9idr9RHc0q2NhuzcwqHtkMwfRzwS791FETu6mpfVup/x4zNqWPsQzbDNPD5/kqiE3C/N9HjzWraHLpAX3VfkMSfb8L6eM8t6L429PvJy6DekCHCRv6N2fJ1+q8B95WS79Za7Yo9c4Xq80q2cZj0fLv1U8WLXc2/WSXgC7EGRrA1oYENAAAQImR3qmo2qS3rp/6FtV82WjWoLa6ct8hiarE+349zmxVanKfVomkY4vy1H61ufjD7pn7TTu8p7jb9lz1JvMKUW2bi4HtG6sbZ41M9FPORIY5OnLpy50NSebNP2uKWnbpDKsk7KaQO75Jvei9uPcd2cGs7MgQvChsH+dxVAF7E8OZEtAdm9VLO7DSyaIdxgGjO5lV7kZ2aaq6xdRHXJ5zTtuxt7ruoOFqqOeMBkm0HzA6OLkunzNBP/6GdWqifuOqnBa/ndbLrJKC+si72VSsu23bK/nYzyV/vNPAtrEN1rQ5EFEIj739VeJy1Y/RK6D9EtBzl65Qwy58Qs268VV100vL1L7Xv2L+J90uV72ofrZ4ord9KQhLiAOligQ0AABAiTnF8wYbVY/39HTH4I6NzSp+cjr41fsNVYM75P41Rndtalbp9h7RUT147DbmWjinp6ijhqdtQRBvgvCHLCryipX0Dn7t7O3VNfsPVQvPnWq2FqfNnmrD83buq383SvVv11BN6RO9/+3p08N7f+cqhrzyFjI0MIhU8vfzHGSy+dreZGqmBOZdR4xWY7pGq4C+9oChZpXujtmF6wMfljiuX7uGuuXQkeo/R49Vs8Z22TL08YgJXdWvt0ttU/JLzJ3A5QCwcxAo1wrmuIYYnrNTX7OqfCffvVB9tTr1zBUbm30Svntf90pKT3S5XaeFhl+/55XrMrcnchLLX65ar2595WP1ecAAxzlLvjErAA4S0AAAACWm0FWPKLydB7VNDM8qr1MzJYF0/KTUar9i4rRU6Ne2ofrTHoMS6yAD2tv1k25SP7Uy8eiJ3cwqmCSc1nsqp+Os4C4GTevXSgyli6uCMk7uFikHj0k9W+OQcV3UvDOmqAd+vU3ggMkwUStVo3JyWo/+ZnxykQOp7g0i7Uu8ycdMFdDCe2BFrh8f0hdahiE20Y+VKAZ3CO6DXcjH27chvc7d1amN9PPOA8duoy7fe3DibA0v256/716wg1mFO2+Xflt6ydvedpBs9gE/clDqr3sPUi2L4HnuP68tN6tofvrZ7r50bn+1z6DDa5/90KyC/W/R54nLI2+dr86+7y110A3zAocXAkhFAhoAAACoYqQf6vOnbpeodP3nwcPVmdP7qCv2GaxGRaxmLBRJTL1+ztREa4aHjh+vOli0BrDh7ZMrrSr8VPOMUfQOMatTMz+tS5DurBl91EFjOiUSo7v79OuWgwFxJd7CZDNEzPmuerduqF46bZLv0L8DLVta1K8VfKBQht55q2fD8s/XHjAscekdXPjuF6vVSVN7BbYmkQMVwmYQn/j9bv1Vq4bFcbDmoUVfmFU6b7Gs9E3fbUi7RCLWa5ll3+O6+j7K1OJFktxuuQ4EtWkPYmvmkPZq3plTzLWtj20yX9p7fLziB3Mt1fKV/tXMbmfe+1bicuHy5NDDD75eq9ZtTD1gCcAfCWgAAIAS0rV5fbNCVSf9ayVJJf1QZ0/oqnYd3M78T/HJV79Mb57S9nR6byLq9zP7mxXyrXG9WuqCXfsnEqP5qJgdZNkipluEQXUO96OrbeO66vDxXc21CrY/U1huUQou5WZ6t062mJHLsHYMTgW/92v/e0GyGtR7oMZLWn5kIq0lpF+0VFVLK4tCVjtHFWfi1u2OeZ+alT9Jcrvl+ryXwwzDKmeD5XDAyx5bok686w1zLdUik1SO6tT/LDIrAGF4ygIAACghf9hjoFkBW7fTQ1oUOLwtB26b+4lZhbtt7sdmlew3LBWSqBpq17R7C3xAFoPZvGfiN6pbllbxbJv77BhyFoBU28pj+8ZZI9SFu/ZLnOXgfay7OT9zUJI6U6447LYd7g85Y3of9dZ508y1yiFngQRp3aiOWVWuWpaPxSBBifQuJXig2bYCWnpFv/bJ9+Zadr5ZE71HNQAS0AAAACWlVo5Dj4BicfDY1P7ANhrXzdwDWJKI7tPu3/pstVmhKsiUgJb2K3/cfaBVu5pMLRfEjv1bm1WSbfWtJH2d4XheTiK5TaO66sAxnVX7JuEta5yK/qCqZL8E84KzKtox2LxseIexSZLcrVnEXtK5cvcSL1ads0wUO4Neg36fR2+budd9VbMhx37aUYy99CmzSgo72AGgAu9AAAAASkgxnxYNRCFJtUt+NcBcsxuuKW0R/FjmBFEFhD0H3j57lFp03lS114iKxPJ/jh5rVqmGdmysLtptQEoVq9Mz2c379TZZtgoQQa0vwn6Go3wGbbZokGzB4e0b7fAbYNjMfI7I1KJDPPb2V2bl7+cCD2qT6vNit1vEtki9WpWr8T2aq7/tOyRx3a8X+gmTe6jdhxZ/8j1uGzYVLgG96afUxzKDnQE7JKABAABKiF+iAahsQzra9eX12nNYe7V931aqW4v66rbDR5mtwQpZJYfiFPYMOLZb87Rq4GGdmiSGY8pQT0nu3q4fZ3L9v8eMSyQA7z1mrDp4TCd195FjfFsqeAf/3fxyRXuXTPYc7l9hHdYS4zdTephVhUb1kslYb+L6SpPIXLdxc+IySLa9ht1tcs6c0desCiMkR180MrXg8FbW/nZaL3XrYaO2DGn1q6Y/cfueoQcobj1spFkptcugtma19WtaP/WAw4bNhRsM2CeLgaVAKSIBDQAAUEK8yRCgGNSpmXnImR8ZtHj9QcPVUydvazVcrp6nLQBKz4sfrDCraCTpd9qOvdXY7s3NlqR+bRup83ftr0Z2aWq2pLKpHg7SN4vElneAppu3B3TPVslBi/eYYYRBsv0ZpE3OGdN7q/N36ad2G1zYZKdfdfDW5jNPW5MyT8I6LNE8Y0Abs0o1vkeLRFX/RTP7q4tdZ5Bs7bztTBYsW2lW+Vdep6ZavrKibRMAfySgAQAASggV0ChGv+h/hTBzSOZT3gvbKACFtjFCC4w4hCUJM8k2iXrnEaPNKpX3e6lm6sF/+jn8UZ/tzyDJ8CMmdEskouVgUSHF9VoXpb3CxTPzm9Ad0K6RWSWt+GGjWaU7e6f0inOnpYtU9e8/qlOltY6wGSAb1WZPW4xCuvjhd9U2f5hjrgEIQgIaAACghOSSDAG2RtI6Yfb4LuqGQ4arVg3rmK1AYXjPOtlruH1/Xm/Fsi3pFezHW8m84ocNZhUu2++jMi395gezyk2Un7xz8/BhkLnyvn57Bz+6tW6U/lw3pW8rs6o82/ZqoY706VOeqw+/WWtWhbdo+SqzSvVzhgM7QKkhAQ0AAFBC/HpGApUtaNhaHKR1gvSfndS78pMvqHzZtLXIhTd527VFsu2FjWyreOvV9t+f0s40CMiPjfK0Eynw/MBY3PDiR2YV3QW79jMrvd6tYp1RyP1UK6ACvGV5xbDHTLwJ6EwHBp777XZmldTGJyldaDceMsKs4nVLhN7qhfLT1rjjAHlEAhoAAKAK2+gZupZDO1IgVn/cfaBZKXXuzhGSPHmWqR0Btm6FPgZXw/OkG6WYuK5Pz3KbgzW1a9ZQl+05SA3t2Fhds/9Qs1Up70N75bpNZpVqn5Gpww+XfLXGrII1rFM57RzyYZ8RHdWFu/ZTl/5qgNplUOa2PY6wp46g1i9/2WuwWWXmTTj7VTm7tfAkt2Voa2WSvtRhAzRtBfW3LjY/k4AGUvAWBAAAoArzviGmBQeKxZ7D26vbZ49ST540IW2AVGXyJqB3Grh1JDtgJ+gAQ7764XqThlGqmsd1a2ZWFW7T+4yNPYa1V/89Zpya7krWNaiV+jMGDU5767PVZmWveYRK3kLo3dq/DYmNWjWrqwPHdFb7jOwY6TVz08/R+4u3a1LXrDLzfi+ZBq96D2BU9glQtT1DFLPld2DGqxiqj7N4OABVGgloAACAEkICGsVCKuHGdmuuurfMPlEUl7DETN+2hW3ZgPz63Q7+A9D+dbhdYjcqbw/oKAloGdx3z1FjEmvpnfvuBTuooR2bJK5no9xTpdw7oB3JO59HT0DvPLCtWRWHpvVrmVXhbNj0k1nZC3s0HL1taq9kbwutqC1aFn+ZuZLda/GFO6iTtu9prgULGnzpJol9x3k7pw9JtGXTk/yCB98xq8rz7HvfmBUAQQIaAACghGTbUxQoVRN6tDArVAWSyP3jHgNTKp4b1S1TgzNUk2bLe9Av6jHAEZ2bqmWXzlA3zRppVfkZprrni/9iqkS9fbGzaR1w8NjOZlUcRnVJrx7Pt/Wb4i15ndgz9bnH+/uLOtNhpH4sRVWnrIbV42F018z39w79W5uVUgeN6axuPnSkuRaN937w8/7XlTeU0HHUvxaYFQBBAhoAAAAAAvRv18isUBVI5f1ewzuo+WdNSSTk2jepq249LLtEmI2a3h7QUTPQeeSkFW/zVH9n0we9fsDgw8pSVrPw93PLhsFtSKSndFSZ8r7e/PMBozuaVYXmDSq+p2audZAnT5poVhVVzZKEDjO1r92A167NKwZwyn4gCfaxPm1mMvHOtgCwdSABDQAAUEKKoC0iUHSqhZ4Ij6pIkmp3HzVGPX/qdmpg+/xUPwtvBXQcQ9ji0sYMsWviaVeRTQV0WZFNuJ3c2y4pGidpKeSQfscPHDtO9WjZQE3r10rtOzI9OSyC7mtJWGd6qHjPaGpVnj6U8N5jxqrfTuulnjhxglULru76+11w1hT18umTtlQ1B33aYdt0UYfr+P3M/mZLOL+HSP0seq//mEWrEwCVjwQ0AABACWlcr8ysAAD5TgiXeXpAR22bELcr9hmsWpTXVgeN6aR6t/bvAZ1NBXQxVXaLXq3LE61W9hnRQc05ZdstQwlP3aFX4jJfPrx4unr8xAmJ3slyYOOJkyaqfxw4PNHP24/3rpbhkaft2DsxBDFTyyybu7xD03rq19t1Vz1a2ffal0rpNo0qhiPOXfqdWaWaOaSdOmunvqqlT+Lbj18CvJP+/qL66Sf/x+eSL9eoA/9vrjrrvjfNFgDFhAQ0AABACSkLeBMMAIifN+n2XCUPJtt1cDs174zJ6oJdg6tWJWlZFUirlUt3H6i6NK+v/nfcNolq92O27W7+Nz/k992zVbn1gY06ZamvyZftOUgdNTE5fDDTTXgT1EM7ZT+gMkxQ5bT3gHafgKGWYY6b1MOs7DXwDNN0TLv8OfX8+9+qf73yidkCoJjwDgQAAKBElGdxqisAIHveHtCPvv2lWVWeTMlRqcKtaqQCuRgT6+2b1EsMxhTSzsItU4Wz99c4LE8J6Kn9KoYHusn37rbb4LZm5W/lD5vMqkLDutH/Lmnd0K7i2oYMIM2nm178SD3y5hdbBn4CpYwENAAAQImwLMgCSg77BvIlUxKxGGVq/YB43XjICPXiaZMS7SyikAMJuwxKJn1nDGyTcVhgtpyvkUlQm5EwmQ6GSE9qrzhbiTnV5vly3oPvqKNve03N+8i/jQlQSkhAAwAAlIhi69EJAFWdN8GW74rLOGQzhBDZk8dIu8YVPZcd369Lrxj2kp7ez/52W3XVvkPMlvjVqmmXNsr0J0bXFvXNyo78XLceNlJ1i/h5UYzrnhy0mG+/f+hdswJKFwloAACAElHZw6+Arc2uGU4pB6LySzQWg/ZNKr4vGZ7nVovZAZViZJemgf2XHZK87tSsfsZK4kIY3yPZSiRIlAptSTzLzyXDEJ86eVuzNSloeGY2ClXtvzmLwZ5AVcMrCQAAQIkohjeowNbky1XrzQqIR9AAtcp286Ej1cFjOiXaQTStX8tsTbp6/6FmhUIqr1Om7jpitDpxSk/18umTzNbi5dcuIxu/26F3WjL7tsNHJSqo9xvVUW3To7nZaqdf2+CEdaYEf1ze/WK1WQGliwQ0AABAiaCIDfAXlIKYS99OxOyM6X3Mqrh0a9FAnb9rf7Vd75ZmS4X+7eKrOEU0wzs3VSdM6ZGoBC4mO/b3H0yYjd2HJodeltWopuadOVkdvW16X+Zx3Zurp0/eVl08c4DZYi+so0yhEtAASEADAACUDAZLAUDhHTquS+JyYPtGanCH1PYWW4NqgYdoksZHrEjF1mf+WVPMKqlerfgq+c+Y3ludtmNvdetho1TL8jpma3zaNamr/h5Qxc/fRUDhkIAGAAAoEbzRAoDCO2fnvuqF322n7v/1OLOlatl1cDuzQlXVvEFt9ashFb/n2ROSB1W8bpw1wqzsNdO3fdTEbmp01/wMBDx/l35qxwFtzLVUQRXQMpxQWoEAiA8JaAAAgBJRnb/8AKBStG9Sb6vtw5/p26a9U2k4b9d+6szpfdT1Bw0PHAS4Xa+W6v2LdlTv/X5Hs6XytQ0Y/Dl7fJfA4cwHjens2wokW71alZsVULp4qQAAACgRVEAD/hjQCQRrVr9WaK9cXltKQ8M6ZWr2hK5q+76tzBZ/ZTWqq1o185tqGtox91Y2HZvWCzwwH5SYzlYH/bWAUkcCGgAAoETE/YYKAFD11axRPdE+5NjtuqtbDh1ptlYgAY1C++206O0xGtRO7VstifKgAytOYvqQsZ2Tixy9/slKswJKFwloAACAEkGOAACQjf7tGqlTpvVS3Vo2MFsq/PzLL2YFFMaYbs3UBbv2U71b27e2uOWw1IMncmAl6MC8c1DlnJ36qv8eM1YtPHeqmjmknRqU5RDRFT9sNCugdJGABgAAKBFUqQEA4vbf1z4zK6BwpE/zRTP7m2uZdfK0wZC/iIJahTiV0dX15dCOTVSjumXqr3sPVncdMTqx3dHD54AMAH8koAEAAErE+1+vNSsAbhyaAez47SvrNm42K6CwakSYrlyvVmoLDhHUgiOoMrpOWQ2zSuK4PmCPBDQAAAAAAMjKcZN6mBVQWKt+3GRWmdWtlZo87tSsnqoZkMCWymcb7321Vt1z1BhzLZgM8gRKHQloAAAAAPDRtXl9swIQpGHdMrMCCivqcOVrDxiqWpbXVnsNb6+Gd266ZdigV1BltJ8R+nYy6d3Gvlc1UFWRgAYAAABQ0oJyGMdN7m5WAITfvhI1CYjSEGVAYLbaNq5jVnZ26N9GzT1jsvrjHoMS1wMroGN+TDOnEyABDQAAUDJGd81cpQOgwqTercwKQJAo1aIoHQeP7WxW+ZPNY6+aK7kc9OlxP6Z/JgMNkIAGAAAoFXFX9ABVXXnt9KFVAFJFmAOHErLHsPaJNkbyp8eFu/U3W+OVa6LYnYx2C6vq796ygVkpNXt8F7MK9zP5Z4AENAAAQKkgAQ1Ewy4DpKqm/3nRggN+ympUV4+fOEG9fNpkdeDoTmZrvPJVfR92UOX6g4arge0bqYk9W6gTt+9ptob7hQpogAQ0AABAqbCd6g6UmqAquKDtACqsXr/ZrIBUNWtUV60bRevTHEVQD+dchSW2uzSvrx44dht186EjVb1aybNknjxpQuJSnLNTX7OqQP4ZIAENAABQMsg/AwDi9s7nq8wKKKyyGrn/YTO5d0uzqhD1jLHuLcvVkt/voBaeM1Uduk0Xdfyk1AG29IAGSEADAACUDFpwAABy4fcyMqILA25ROaTNR678zg7L5u+l2jVrqEb1yhLrk6b2UjOHtEus5abGdmueWAOljAQ0AABAiaACGgAQtyb1apkVUFg1M1RA/9/Bw80qWE2fP47i6C39170Hq2WXzlAfXTJDnTKtl9kKlC4S0AAAACWCCmjAXtfm9c0KQBheWlBZyjL0gJ7k017Dy68CmsGaQPxIQAMAAJQIEtCAPYZ2Aun89gqSdagsYc/Th47rYjVIdtW6TWZVIU+zDYGSxm4FAABQItZsSH+TBcAfSTXAThztCoC49WlTblbhXvjgW7OqwGMaiB8JaAAAgBLx4gcrzApAJlRAA3bYV1CMfjGX2di0OZfPBuCHBHRpaq/jBh2f69igY5mOy3U00RGFjDuWz5PPl9uR25PbldsPM17Hf3R8oUM+Ty4f1zFdBwAAAFBw3oJnv8FUQMnz2S04WwDF6Oefs08it25Ux6wAxIUEdOnppmOBjlk65un4q46lOk7Q8bKOZjpsyMfJx8vnfahDbkduT25Xbr+rDj9n6XhOxwQdj+r4s44HdUjye1sdAAAAQKWjqhOwQ7sCFKOx3ZqbVXQcgATiRwK69FyjQ0bBHq9jNx2n6ZikQxLIvXRcpMPGxTp66pDPm6xDbkduTxLScvvydbz21HGhjid1SIJaktVn6DhCxwgdZ+oAAAB5stPANmYFIJMa5B8AKwy4RTHZd2QHdcU+g1XHZvXMlnA7D2prVhU4AAnEjwR0aZGk71Qd0jLjatngcq6OH3QcqKO+bAgh/y8fJx8vn+d2lQ65/Wk63FXQ8lj7g451OvbTsUaHF5ORAADIo+YNapsVgEyo6gTSVfPpwcGugmJyya8Gql0HtzPXMvvrXoPMKunKfYeYFYA4kYAuLVLpLKTf8s/J5RaSEH5RhxwmHC0bQozRUVeHfLw3kSy3K7cvtjOXYqyOLjoe1rFSxwwdv9MhFdNyewAAIM+oUgOCefcO9hfADgdrsDWrWaO6+uiS6WrReVPVsktnqF18KqIB5I4EdGmRFhviPXPp9b65lNYaYbK5HWmxIb7S8ZqO/+m4VIcMMXxJx7M6WuiwIT2m/aK3DgAAEEC/xwJgiaQaYKcaB2uwlZPHcMM6ZeYagHzgbUhpaWQuV5lLL2d7Y3MZJJvbkb7Q4igdUj09RUe5jv46HtMhQwnv0QEAAPKEik7AHgloIB0vIyhmXZpn6iYKoLKQgIab8+fEL+YyW363U8Ncyv/toeMpHWt1vK1jpo7lOibqsGnHMSwgFusAAAABGKoDBPNWcZKABoCtS5tGdcwKQLEhAV1anMpkp4LZq6G5DKpsdmRzO9L3WSzVsTC53OJHHVIFLUaaSwAAELMalK4B1thfAGDr8kuupXQA8oYEdGlZYi6Dejz3MJdBvZ0d2dyO8znfm0svJ0Et7TkAAEAeUAEN2GN/AdKxV6CYbfrpZ7MCUGxIQJeWOeZyqg7v7176MY/TIdXIr8iGEPL/8nHy8fJ5bnK7cvvC+XriOR2bdUhyupZs8JBe0GKZuQQAADGjohOwx/4CAFuX+R87dW0Aig0J6NLyoY7HdXTW8WvZ4HK+DunYf4uOH2SD0duEm/RuvlWHfPx5ssHlWB1y+9JSQ9ptOL7VcZcOadtxjmxw2V7HNB3SsuNR2QAAAOL3S85jHoCqy5tupgc0AABAPEhAl55jdHyt40od9+m4RMfTOk7UIS0zztTh9q4JrzN0yMefpEMGCsrtyO1doUNu35vgFvKxH+iQryEV0ZfpuEfHIzp+0jFbR1CLDgAAkKM7531qVgAyoQUHkM47rBMAABskoEuPVEEP13GTjlE6TtbRTYckpMfoWKHDhnycfLx8XncdcjtyezfqGKZDvo6XJKblY/6qo4OO43VM0vGQjvE6JBkNAADy5MvV680KQCY1yLMBwFale8sGZgWg2JCALk1S/jRLRxsd0o+5k44TdHynw0v+9A7681s+Xj5PPl9uR27vUB3LdQSRz5FK6C465HOa6dhVR6a+0wAAAEDB1KjOWyUA2Jpw3BAoXvxVBQAAAKDkeTsL1OCdEpCGBB+KTf92Dc2KCmigmPFnFQAAQIlo1bC2WQHIhCGEAFD8frdDb1W7ZnXVrH4tdf4u/cxWAMWGBDQAAECJaFS3zKwAZFKdYWsAUPTG92ih5p4xWb2io2XDOmYrgGJDAhoAAKBElNchAQ3YogIaSMdxGRSjxvVqqTL6JgFFjT0UAACgRDSsU9OsAHhV83S3pQIaAAAgHiSgAQAASkT92iSgAVtUQAMAAMSDBDQAAECJqFerhlkByIT8M5DOe6YAAAA2SEADAACUiJ6tys0KQCYLPl5pVgCC/HGPgWYFAEAwEtAAAAAlYmy35mYFII2nsPO1T743KwBbePYTZgsAAGyQgAYAACgRzFQDAMSpGi8sAAALJKABAABKBHkCAECceFkBANggAQ0AAFAiGB4FBPPuHa0b1jErAA7vgczqHNkEAFggAQ0AAFAiyBMA9g4f38WsAAThdQUAYIMENAAAQImoTqIAsFa3Vg2zAhCECmgAgA0S0AAAACWDRAFgi8QakC5tr2A3AQBYIAENAABQIsinAcG8+wdnDACZcaAGAGCDBDQAAECJIE0A2COxBmTGXgIAsEECGgAAoERUI6EGWCMBDaTzvo6wmwAAbJCABgAAKBHkCQB71XmnBGRUgww0AMACf1YBAACUCPIEQLBqnkM0VEADmVWnWToAwAIJaAAAgBJBQg2w9/26TWYFwOF9FeF1BQBggwQ0AAAAAHjc/8ZnZgUgSA0yCgAAC7xcAAAAlAgK1QB7NWgtAGREBTQAwAYJaAAAgBJRjUQBEMi7e7C/AOm8u0VNpnUCACzwagEAAFAiSKcB9spqsMcAmXCmAADABgloAACAEkFBJ2Dv0HFdzApAEBLQAAAbJKABAABKRDVqoAFrXVs0MCsADu/rCEMIAQA2eLkAAAAoEVRAA8G8u0dNKjuBjBhCCACwQQIaAACgChvWqUniskPTuqpFg9qJNYDMqpOABjKiBQcAwAYJaAAAgCrs7/sPVRfs2k/dfvhoEmpAiF/MpeOXX7xbAHgLnqmABgDYIAENAABQhbVsWEcdNKaz6tC0ntkCwM9PP6cmnL3XAaSjAhoAYIMENAAAAICS97On4rl+7ZpmBSAIFdAAABskoAEAAACUvM2eiufm9EwHMqpORgEAYIGXCwAAAAAlj5bPQHQ1qIAGAFggAQ0AAAAALvS1BeywrwAAbJCABgAAAAAXqjoBf95dozoJaACABRLQAAAAAOBCVSdgpyb7CgDAAgloAAAAACXPPXSwTeM6ZgXArWb16ilV0HXLapgVAADBSEADAAAAKHnn79JPdW1RX/Vo2UCdsWMfsxWAm5wdcMnMAapvm4bqsj0HqWq0qwEAWODVAlXJgqHaggULzFUAAAAAAADkYtiwYeo1TZbJLUA0VEADAAAAAAAAAPKCBDQAAAAAAAAAIC9IQAMAAAAAAAAA8oIENAAAAAAAAAAgL0hAAwAAAAAAAADyggQ0AAAAAAAAACAvSEADAAAAAAAAAPKCBDQAAAAAAAAAIC9IQAMAAAAAAAAA8oIENAAAAAAAAAAgL0hAAwAAAAAAAADyggQ0AAAAAAAAACAvSEADAAAAAAAAAPKCBDQAAAAAAAAAIC9IQAMAAAAAAAAA8oIENAAAAAAAAAAgL0hAAwAAAAAAAADyggQ0AAAAAAAAACAvSEADAAAAAAAAAPKCBDQAAAAAAAAAIC9IQAMAAAAAAAAA8oIENAAAAAAAAAAgL0hAAwAAAAAAAADyggQ0AAAAAAAAACAvSEADAAAAAAAAAPKCBDQAAAAAAAAAIC9IQAMAAAAAAAAA8oIENAAAAAAAAAAgL0hAAwAAAAAAAADyggQ0AAAAAAAAACAvSEADAAAAAAAAAPKimrkEqoIVdevWbdqnTx9zFQAAAAAAALl499131Y8//vidXjZLbgGiIQGNquQjHQ11LEtc27r1NpeLzSUAf+wrgB32FcAO+wqQGfsJYKcq7SuddazW0SVxDQBQJSwwASAc+wpgh30FsMO+AmTGfgLYYV8BDHpAAwAAAAAAAADyggQ0AAAAAAAAACAvSEADAAAAAAAAAPKCBDQAAAAAAAAAIC9IQAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoCu113KDjcx0bdCzTcbmOJjoAKLWHjr/peF7Hah2/6PiXDgCpmuk4XMe9Oj7Q8aOOVTpe0HGYjuo6ACT9QcdTOj7VIfvKdzpe13GuDtmXAPg7UIf8LSYhrzkAku/hnf3CG1/qAEpSNXMJoPJ10/GSjpY67texWMdIHdvpWKJjnI4VOoBS9oaOQTrW6liuo7eO23QcoANAhaN0/F3HFzrm6PhERysdv9LRSMd/dOypQ94MAaVuo47XdLyj42sd9XWM1jFchxQFyFqS0wAqdNDxpo4aOhromK3jnzqAUicJ6MY6pJDMS97DXJZcAgBQOR7TIYmA4xLXKvxFh2y/NnENKG1yQKaHDjmAuq0O2TeogAbSTdKxsw5vpXNrHZKMln1nd9kAQNUxl14X6ZB95ZrENQAO+TvsSR0f6viTDtlPqIAGkiQBLQEAQNHpqkP+cPtIhzdZUK5DjpT+oEMqcgAkkYAGsnOGDtl3pJ0NgGByxo3sK08krgFwnKDjZx0TdJyngwQ0UIEENOCD/n9AcZBKNfG4Dvljzm2Njhd11NMhp4ACAJCLTeZys7kE4E/OIhCLzCUApfrouFTHFTqekw0A0tTWIS0C5aC/HLCRszilXQ0AAJXKOXXt5MS1dFfpkP8/OnENgKACGoiupg7p2Sn7zjTZAGCLU3RINedfdciwW9lPFupooQNA8jVkvg6ZT1NXNmhUQAOppPpZ9glvLNUxUQdQkqiABoqDDIQSq8yll7NdhhkAAJAtqVrrr+NhHTJ7AEAFSUCfq+M3OrbR8aiOqTq+0QFAqXN0DNFxiI4fZQOANDfqmKxD5m5IC80BOv6ho7OOR3RIeycAACrFdTrkqGhQ5cDFOuT/T0tcAyCogAaiOV6H7DPv6mgqGwD4aqVjpg6p8vxcx1AdQKkbqUNaN/0xca0CFdCAnct0yL5yb+IaUGKogAaKg1Ph7FRCezU0l0EV0gAAhPm1DunX+Y4O6UP4nQ4A/r7SIQkCqX5upuMWHUApk9Ybt+p4T8fZsgFAZNeaSxneCQBApZCKATkaKqfm+JHTpOX/5VQeAElUQAN2pJ2A7CvS+7mlbABg7XUdsv80T1wDSpO0AZT9wCYu1wEgnRSVyT6yPnENAIBK0E2HvBh9pMN7ZkK5jrU61umQHlIAkkhAA5n9TofsJ5JEI4EGRCfV0LIPNUlcA0qTDBz8Z0C8pkP2ERncKdf31gEgnQx/ln1FzkYDAKDSOFXOxyWuVfiLDtnunLIDIIkENBBOTpOWfWS+Dno+A/5665BBUV5SEHCRDtmHXpQNAHzRAxqo0E+H399cnXS8r0P2lTNkA1BqqplLAJVPqqBf0iGnR9+vQ4ZEjdIhvTql39pYHSt0AKVsNxNCEgZSSbBUh1TdiG91nJJcAiXtYB036fhJx990+M0QWKZDPgYoZdKi5k86ntPxoQ75W0uGEE7U0VXHlzqkBRoVa4A/SUCfq2O2DqmABkqZ7A+n6ZijQ85uXqND3ufP0FFHx8M6ZMjtRh0AAFSaDjpu1PGFDnlR+liHDI2icg1IcqpsgkISagAy7ysSz+gASl1/HVfreEOHHMTcrEMO2LyqQ/Yj/gYDwjmvN1RAA8mDl3foWKzjex2bdHyj4wkdB+mgCBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCEddbxi46bEteK29b0vQIAAKAEVTeXAAAAAApHksbPJJcAAABA1UUCGgAAAAAAAACQFySgAQAAAAAAAAB5QQIaAAAACNZbx306vtPxg44XdEzV4dZIx291PK1juY6NOr7R8YCO0TrcDtEh7TfERB2yduI8HW4jddyl4zMdG3R8oeNxHXvp8CP9oO/U8a2O9Trm69hJBwAAAFBpqplLAAAAAEmSyP1Ix3M6Bup4S4ckntvo2FtHLR376ZDksJAks3ysxIc6VuroqGMXHbV17KzjUR1isI7ddJyr42Md7uGB0hPa6Qs9W8ffdfykQxLZ7+toqWO4ju91bKtDON+rfF4/HUt1vKyjqQ75Xst0TNExRwcAAAAAAAAAoJJJUtepSv6TbHCRBPAmHZJkbigbNKmAbp5cpmiv43Md7yaupZLbDhpC2FeHfA2pupakspfcrsP9vUpS222aDtn+cOIaAAAAAAAAAKDSOUldqTQulw0eUrUs/39w4lq4K3XIx0pFtJtsC0pA/02H/P+JiWvhnO91mY4assFDqqylJQcAAABQKegBDQAAAPh7Tcea5DKFkzgeYi7FOB136/hUh/RrlqSwxHE6RDtzacPpG/2IubTxhg5p1+El30+T5BIAAAAoPBLQAAAAgL+vzKXXl+ZSWm+ImTqk//MMHQt0XKXjQh3n63hWh5Be0LYam0sZPmhLqrX9bNbB3/wAAACoNPwxCgAAAPhrZS69WpvLVeZSks0bdUh/aBkweLKOc3Scp2OJjqicZHKUqmkAAACgKJGABgAAAPwN1eHXA3pbc/m6ueyu4x0d3mGD8rf2Nsllmp91+PVsFq+Yyx3NJQAAAAAAAACginAG+0n8STa4SJXzJh1SpdxQNmiLdazW0TZxLamaDmnB4dyOk7R2fK1DBgf66atDvsZ3Zu3V3lwK53uVwYh+pF+1/D8AAAAAAAAAoAg4SV3p37xSh/R3vkSHJHl/1CHD/vbW4ThSh3y89Iy+RscVOubrWKfjAR1+Ceg7dMj2B3VIq46zdEzQ4ZitQ76ODDSU4YYX6bhWh9zuHB0OEtAAAAAAAAAAsBVxJ3X76LhfhySiJaH8oo5pOrwO0fGGjh90fKvjXh0DdEhy2S8B3VLH7TokaS2JZvkY+Vi3MTr+o0OqpaXH9Oc6HtWxhw4HCWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2Ioo9f9bBQROnq0NgAAAAABJRU5ErkJggg==\" width=\"720\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d45f34edcf9046ecbd8a533da31a8df5",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e042012c7ff94183b5a655b88f38c51b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=14032), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f4da88c1f9394b9ca1a6e4512dc5b6c4",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=7039), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'loss': 0.08772529098453985, 'val_loss': 0.08948538429140176}\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "0cc5e83c19b042d985983e2375d22c2d",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=14032), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "76fd8e9f70794760920f79d71a0a2412",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=7039), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'loss': 0.0739340802691105, 'val_loss': 0.0831382854234583}\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8ff1c04b4c97457d8f2541d888fa2f80",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=14032), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b4ae45ce45594ac89ba196e2b8923f09",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=7039), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'loss': 0.06913197829724893, 'val_loss': 0.08308981416888478}\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d219862452854b8bb5aa5d80eaa7769a",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=14032), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e9af2c6032044e8ca93744e7b78086e6",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=7039), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'loss': 0.06284379411734307, 'val_loss': 0.08409869243106527}\n",
      "[0.08308981 0.08409869]\n"
     ]
    }
   ],
   "source": [
    "%matplotlib nbagg\n",
    "\n",
    "num_split=1\n",
    "np.random.seed(SEED+num_split)\n",
    "torch.manual_seed(SEED+num_split)\n",
    "torch.cuda.manual_seed(SEED+num_split)\n",
    "#torch.backends.cudnn.deterministic = True\n",
    "idx_train = train_df[train_df.PID.isin(set(split_sid[splits[num_split][0]]))].index.values\n",
    "idx_validate =  train_df[train_df.PID.isin(set(split_sid[splits[num_split][1]]))].index.values\n",
    "idx_train.shape\n",
    "idx_validate.shape\n",
    "\n",
    "klr=1\n",
    "batch_size=32\n",
    "num_workers=12\n",
    "num_epochs=5\n",
    "model_name,version = 'se_resnext101_32x4d' , 'classifier_splits'\n",
    "model = MySENet(pretrainedmodels.__dict__['se_resnext101_32x4d'](num_classes=1000, pretrained='imagenet'),\n",
    "                   len(hemorrhage_types),\n",
    "                   num_channels=3,\n",
    "                   dropout=0.2,\n",
    "                   wso=((40,80),(80,200),(40,400)),\n",
    "                   dont_do_grad=[],\n",
    "                   extra_pool=8,\n",
    "                   )\n",
    "\n",
    "_=model.to(device)\n",
    "weights = torch.tensor([1.,1.,1.,1.,1.,2.],device=device)\n",
    "loss_func=my_loss\n",
    "targets_dataset=D.TensorDataset(torch.tensor(train_df[hemorrhage_types].values,dtype=torch.float))\n",
    "transform=MyTransform(mean_change=15,\n",
    "                      std_change=0,\n",
    "                      flip=True,\n",
    "                      zoom=(0.2,0.2),\n",
    "                      rotate=30,\n",
    "                      out_size=512,\n",
    "                      shift=10,\n",
    "                      normal=False)\n",
    "imagedataset = ImageDataset(train_df,transform=transform.random,base_path=train_images_dir,\n",
    "                           window_eq=False,equalize=False,rescale=True)\n",
    "transform_val=MyTransform(out_size=512)\n",
    "imagedataset_val = ImageDataset(train_df,transform=transform_val.random,base_path=train_images_dir,\n",
    "                               window_eq=False,equalize=False,rescale=True)\n",
    "combined_dataset=DatasetCat([imagedataset,targets_dataset])\n",
    "combined_dataset_val=DatasetCat([imagedataset_val,targets_dataset])\n",
    "optimizer_grouped_parameters=get_optimizer_parameters(model,klr)\n",
    "sampling=simple_sampler(train_df[hemorrhage_types].values[idx_train],0.25)\n",
    "sample_ratio=1.0\n",
    "train_dataset=D.Subset(combined_dataset,idx_train)\n",
    "validate_dataset=D.Subset(combined_dataset_val,idx_validate)\n",
    "num_train_optimization_steps = num_epochs*(sample_ratio*len(train_dataset)//batch_size+int(len(train_dataset)%batch_size>0))\n",
    "fig,ax = plt.subplots(figsize=(10,7))\n",
    "gr=loss_graph(fig,ax,num_epochs,int(num_train_optimization_steps/num_epochs)+1,limits=(0.05,0.2))\n",
    "sched=WarmupExpCosineWithWarmupRestartsSchedule( t_total=num_train_optimization_steps, cycles=num_epochs,tau=1)\n",
    "#param_optimizer = model.parameters()\n",
    "#optimizer = torch.optim.Adam(param_optimizer, lr=klr*6e-5)\n",
    "optimizer = BertAdam(optimizer_grouped_parameters,lr=klr*1e-3,schedule=sched)\n",
    "model, optimizer = amp.initialize(model, optimizer, opt_level=\"O1\",verbosity=0)\n",
    "history,best_model= model_train(model,\n",
    "                                optimizer,\n",
    "                                train_dataset,\n",
    "                                batch_size,\n",
    "                                num_epochs,\n",
    "                                loss_func,\n",
    "                                weights=weights,\n",
    "                                do_apex=False,\n",
    "                                model_apexed=True,\n",
    "                                validate_dataset=validate_dataset,\n",
    "                                param_schedualer=None,\n",
    "                                weights_data=None,\n",
    "                                metric=None,\n",
    "                                return_model=True,\n",
    "                                num_workers=num_workers,\n",
    "                                sampler=None,\n",
    "                                pre_process = None,\n",
    "                                graph=gr,\n",
    "                                call_progress=sendmeemail)\n",
    "\n",
    "torch.save(model.state_dict(), models_dir+models_format.format(model_name,version,num_split))\n",
    "torch.save(best_model.state_dict(), models_dir+models_format.format(model_name,version+'_best',num_split))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<All keys matched successfully>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6ac56489e1b84a8eb1e869dc01ba21c7",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=6546), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "model_name,version, num_split =  'se_resnext101_32x4d' , 'classifier_splits',0\n",
    "model = MySENet(pretrainedmodels.__dict__['se_resnext101_32x4d'](num_classes=1000, pretrained='imagenet'),\n",
    "                   len(hemorrhage_types),\n",
    "                   num_channels=3,\n",
    "                   dropout=0.2,\n",
    "                   wso=((40,80),(80,200),(40,400)),\n",
    "                   dont_do_grad=[],\n",
    "                   extra_pool=8,\n",
    "                  return_features=True\n",
    "                   )\n",
    "model.load_state_dict(torch.load(models_dir+models_format.format(model_name,version,num_split),map_location=torch.device(device)))\n",
    "_=model.to(device)\n",
    "transform=MyTransform(mean_change=10,\n",
    "                      std_change=0,\n",
    "                      flip=True,\n",
    "                      zoom=(0.15,0.15),\n",
    "                      rotate=20,\n",
    "                      out_size=512,\n",
    "                      shift=0,\n",
    "                      normal=False)\n",
    "transform_val=MyTransform(out_size=512)\n",
    "indexes=np.arange(test_df.shape[0]).repeat(8)\n",
    "imagedataset_test=D.Subset(ImageDataset(test_df,transform=transform.random,base_path=test_images_dir,\n",
    "                              window_eq=False,equalize=False,rescale=True),indexes)\n",
    "pred,features = model_run(model,imagedataset_test,do_apex=True,batch_size=96,num_workers=18)\n",
    "pickle_file=open(outputs_dir+outputs_format.format(model_name,version,'features_test',num_split),'wb')\n",
    "pickle.dump(features,pickle_file,protocol=4)\n",
    "pickle_file.close()\n",
    "pickle_file=open(outputs_dir+outputs_format.format(model_name,version,'predictions_test',num_split),'wb')\n",
    "pickle.dump(pred,pickle_file,protocol=4)\n",
    "pickle_file.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<All keys matched successfully>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7c7d8f1fd42d437b9db81ee768ecbc29",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=6546), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "model_name,version, num_split =  'se_resnext101_32x4d' , 'classifier_splits',1\n",
    "model = MySENet(pretrainedmodels.__dict__['se_resnext101_32x4d'](num_classes=1000, pretrained='imagenet'),\n",
    "                   len(hemorrhage_types),\n",
    "                   num_channels=3,\n",
    "                   dropout=0.2,\n",
    "                   wso=((40,80),(80,200),(40,400)),\n",
    "                   dont_do_grad=[],\n",
    "                   extra_pool=8,\n",
    "                  return_features=True\n",
    "                   )\n",
    "model.load_state_dict(torch.load(models_dir+models_format.format(model_name,version,num_split),map_location=torch.device(device)))\n",
    "_=model.to(device)\n",
    "transform=MyTransform(mean_change=10,\n",
    "                      std_change=0,\n",
    "                      flip=True,\n",
    "                      zoom=(0.15,0.15),\n",
    "                      rotate=20,\n",
    "                      out_size=512,\n",
    "                      shift=0,\n",
    "                      normal=False)\n",
    "transform_val=MyTransform(out_size=512)\n",
    "indexes=np.arange(test_df.shape[0]).repeat(8)\n",
    "imagedataset_test=D.Subset(ImageDataset(test_df,transform=transform.random,base_path=test_images_dir,\n",
    "                              window_eq=False,equalize=False,rescale=True),indexes)\n",
    "pred,features = model_run(model,imagedataset_test,do_apex=True,batch_size=96,num_workers=18)\n",
    "pickle_file=open(outputs_dir+outputs_format.format(model_name,version,'features_test',num_split),'wb')\n",
    "pickle.dump(features,pickle_file,protocol=4)\n",
    "pickle_file.close()\n",
    "pickle_file=open(outputs_dir+outputs_format.format(model_name,version,'predictions_test',num_split),'wb')\n",
    "pickle.dump(pred,pickle_file,protocol=4)\n",
    "pickle_file.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<All keys matched successfully>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "1f2baa9881e74623867fbd7944813878",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=6546), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "model_name,version, num_split =  'se_resnext101_32x4d' , 'classifier_splits',2\n",
    "model = MySENet(pretrainedmodels.__dict__['se_resnext101_32x4d'](num_classes=1000, pretrained='imagenet'),\n",
    "                   len(hemorrhage_types),\n",
    "                   num_channels=3,\n",
    "                   dropout=0.2,\n",
    "                   wso=((40,80),(80,200),(40,400)),\n",
    "                   dont_do_grad=[],\n",
    "                   extra_pool=8,\n",
    "                  return_features=True\n",
    "                   )\n",
    "model.load_state_dict(torch.load(models_dir+models_format.format(model_name,version,num_split),map_location=torch.device(device)))\n",
    "_=model.to(device)\n",
    "transform=MyTransform(mean_change=10,\n",
    "                      std_change=0,\n",
    "                      flip=True,\n",
    "                      zoom=(0.15,0.15),\n",
    "                      rotate=20,\n",
    "                      out_size=512,\n",
    "                      shift=0,\n",
    "                      normal=False)\n",
    "transform_val=MyTransform(out_size=512)\n",
    "indexes=np.arange(test_df.shape[0]).repeat(8)\n",
    "imagedataset_test=D.Subset(ImageDataset(test_df,transform=transform.random,base_path=test_images_dir,\n",
    "                              window_eq=False,equalize=False,rescale=True),indexes)\n",
    "pred,features = model_run(model,imagedataset_test,do_apex=True,batch_size=96,num_workers=18)\n",
    "pickle_file=open(outputs_dir+outputs_format.format(model_name,version,'features_test',num_split),'wb')\n",
    "pickle.dump(features,pickle_file,protocol=4)\n",
    "pickle_file.close()\n",
    "pickle_file=open(outputs_dir+outputs_format.format(model_name,version,'predictions_test',num_split),'wb')\n",
    "pickle.dump(pred,pickle_file,protocol=4)\n",
    "pickle_file.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f8a7ace928d04d278fcc24167c24934b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, max=3), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "torch.Size([78545, 24, 6])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "preds=[]\n",
    "for i in tqdm_notebook(range(3)):\n",
    "    model_name,version, num_split =  'se_resnext101_32x4d' , 'classifier_splits',i\n",
    "    pickle_file=open(outputs_dir+outputs_format.format(model_name,version,'predictions_test',num_split),'rb')\n",
    "    pred=pickle.load(pickle_file)\n",
    "    pickle_file.close()\n",
    "    preds.append(pred[(np.arange(pred.shape[0]).reshape(pred.shape[0]//8,8))])\n",
    "predss = torch.cat(preds,1)\n",
    "predss.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "78545.0"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "torch.Size([78545, 6])"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.sigmoid(pred).mean(1)\n",
    ".mean(1).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([628360])"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pred[(np.arange(pred.shape[0]).reshape()).transpose(1,0)].mean(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>ID_000012eaf_any</td>\n",
       "      <td>0.007760</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>ID_000012eaf_epidural</td>\n",
       "      <td>0.000215</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>ID_000012eaf_intraparenchymal</td>\n",
       "      <td>0.000772</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>ID_000012eaf_intraventricular</td>\n",
       "      <td>0.000473</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>ID_000012eaf_subarachnoid</td>\n",
       "      <td>0.001052</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>ID_000012eaf_subdural</td>\n",
       "      <td>0.005370</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>ID_0000ca2f6_any</td>\n",
       "      <td>0.004738</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>ID_0000ca2f6_epidural</td>\n",
       "      <td>0.000074</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>ID_0000ca2f6_intraparenchymal</td>\n",
       "      <td>0.000576</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>ID_0000ca2f6_intraventricular</td>\n",
       "      <td>0.000235</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>ID_0000ca2f6_subarachnoid</td>\n",
       "      <td>0.001335</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>ID_0000ca2f6_subdural</td>\n",
       "      <td>0.001597</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                               ID     Label\n",
       "0                ID_000012eaf_any  0.007760\n",
       "1           ID_000012eaf_epidural  0.000215\n",
       "2   ID_000012eaf_intraparenchymal  0.000772\n",
       "3   ID_000012eaf_intraventricular  0.000473\n",
       "4       ID_000012eaf_subarachnoid  0.001052\n",
       "5           ID_000012eaf_subdural  0.005370\n",
       "6                ID_0000ca2f6_any  0.004738\n",
       "7           ID_0000ca2f6_epidural  0.000074\n",
       "8   ID_0000ca2f6_intraparenchymal  0.000576\n",
       "9   ID_0000ca2f6_intraventricular  0.000235\n",
       "10      ID_0000ca2f6_subarachnoid  0.001335\n",
       "11          ID_0000ca2f6_subdural  0.001597"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(471270, 2)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "submission_df=get_submission(test_df,torch.sigmoid(predss).mean(1),False)\n",
    "submission_df.head(12)\n",
    "submission_df.shape\n",
    "sub_num=41\n",
    "submission_df.to_csv('/media/hd/notebooks/data/RSNA/submissions/submission{}.csv'.format(sub_num),\n",
    "                                                                  index=False, columns=['ID','Label'])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}