{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# 20 - Recurren Neural Netwoks and LSTM\n", "\n", "by [Alejandro Correa Bahnsen](http://www.albahnsen.com/)\n", "\n", "version 1.0, July 2018\n", "\n", "## Part of the class [Applied Deep Learning](https://github.com/albahnsen/AppliedDeepLearningClass)\n", "\n", "This notebook is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). Special thanks goes to [Rowel Atiza](https://docs.google.com/presentation/d/1qjQkUwnr2V--7JPz0H_wkzRyTYX3UtJsYrB3MQPGKLE/edit#slide=id.p) [Colah](http://colah.github.io/posts/2015-08-Understanding-LSTMs/y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Recurrent Neuural Network (RNN)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Being human, when we watch a movie, we don’t think from scratch every time while understanding any event. We rely on the recent experiences happening in the movie and learn from them. But, a conventional neural network is unable to learn from the previous events because the information does not pass from one step to the next. On contrary, RNN learns information from immediate previous step.\n", "\n", "For example, there is a scene in a movie where a person is in a basketball court. We will improvise the basketball activities in the future frames: an image of someone running and jumping probably be labeled as playing basketball, and an image of someone sitting and watching is probably a spectator watching the game.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "A typical RNN (Source: http://colah.github.io/posts/2015-08-Understanding-LSTMs/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A typical RNN looks like above-where X(t) is input, h(t) is output and A is the neural network which gains information from the previous step in a loop. The output of one unit goes into the next one and the information is passed.\n", "\n", "But, sometimes we don’t need our network to learn only from immediate past information. Suppose we want to predict the blank word in the text ‘ David, a 36-year old man lives in San Francisco. He has a female friend Maria. Maria works as a cook in a famous restaurant in New York whom he met recently in a school alumni meet. Maria told him that she always had a passion for _________ . Here, we want our network to learn from dependency ‘cook’ to predict ‘cooking. There is a gap between the information what we want to predict and from where we want it to get predicted . This is called long-term dependency. We can say that anything larger than trigram as a long term dependency. Unfortunately, RNN does not work practically in this situation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Why RNN does not work practically\n", "During the training of RNN, as the information goes in loop again and again which results in very large updates to neural network model weights. This is due to the accumulation of error gradients during an update and hence, results in an unstable network. At an extreme, the values of weights can become so large as to overflow and result in NaN values.The explosion occurs through exponential growth by repeatedly multiplying gradients through the network layers that have values larger than 1 or vanishing occurs if the values are less than 1." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Long Short Term Memory Networks (LSTM)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Long Short Term Memory networks – usually just called “LSTMs” – are a special kind of RNN, capable of learning long-term dependencies. They were introduced by [Hochreiter & Schmidhuber (1997)](http://www.bioinf.jku.at/publications/older/2604.pdf), and were refined and popularized by many people in following work.1 They work tremendously well on a large variety of problems, and are now widely used.\n", "\n", "LSTMs are explicitly designed to avoid the long-term dependency problem. Remembering information for long periods of time is practically their default behavior, not something they struggle to learn!\n", "\n", "All recurrent neural networks have the form of a chain of repeating modules of neural network. In standard RNNs, this repeating module will have a very simple structure, such as a single tanh layer." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "The repeating module in a standard RNN contains a single layer.\n", " (Source: http://colah.github.io/posts/2015-08-Understanding-LSTMs/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "LSTMs also have this chain like structure, but the repeating module has a different structure. Instead of having a single neural network layer, there are four, interacting in a very special way." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "The repeating module in an LSTM contains four interacting layers.\n", " (Source: http://colah.github.io/posts/2015-08-Understanding-LSTMs/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Detailed process" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "The repeating module in an LSTM contains four interacting layers.\n", " (Source: https://towardsdatascience.com/understanding-lstm-and-its-quick-implementation-in-keras-for-sentiment-analysis-af410fd85b47)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The symbols used here have following meaning:\n", "\n", "- $x$ : Scaling of information\n", "\n", "- $+$ : Adding information\n", "\n", "- $\\sigma$ : Sigmoid layer\n", "\n", "- $tanh$: tanh layer\n", "\n", "- $h_{t-1}$ : Output of last LSTM unit\n", "\n", "- $c_{t-1}$ : Memory from last LSTM unit\n", "\n", "- $X_t$ : Current input\n", "\n", "- $c_t$ : New updated memory\n", "\n", "- $h_t$ : Current output" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Information passes through many such LSTM units.There are three main components of an LSTM unit which are labeled in the diagram:\n", "\n", "1) LSTM has a special architecture which enables it to forget the unnecessary information .The sigmoid layer takes the input $X_t$ and $h_{t-1}$ and decides which parts from old output should be removed (by outputting a 0). In our example, when the input is ‘He has a female friend Maria’, the gender of ‘David’ can be forgotten because the subject has changed to ‘Maria’. This gate is called forget gate $f(t)$. The output of this gate is $f(t) \\cdot c_{t-1}$.\n", "\n", "2) The next step is to decide and store information from the new input $X_t$ in the cell state. A Sigmoid layer decides which of the new information should be updated or ignored. A tanh layer creates a vector of all the possible values from the new input. These two are multiplied to update the new cell sate. This new memory is then added to old memory $c_{t-1}$ to give $c_{t}$. In our example, for the new input ‘ He has a female friend Maria’, the gender of Maria will be updated. When the input is ‘Maria works as a cook in a famous restaurant in New York whom he met recently in a school alumni meet’, the words like ‘famous’, ‘school alumni meet’ can be ignored and words like ‘cook, ‘restaurant’ and ‘New York’ will be updated.\n", "\n", "3) Finally, we need to decide what we’re going to output. A sigmoid layer decides which parts of the cell state we are going to output. Then, we put the cell state through a tanh generating all the possible values and multiply it by the output of the sigmoid gate, so that we only output the parts we decided to. In our example, we want to predict the blank word, our model knows that it is a noun related to ‘cook’ from its memory, it can easily answer it as ‘cooking’. Our model does not learn this answer from the immediate dependency, rather it learnt it from long term dependency.\n", "\n", "We just saw that there is a big difference in the architecture of a typical RNN and a LSTM. In LSTM, our model learns what information to store in long term memory and what to get rid of.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Example phishing URL detection" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Based on the paper:\n", "- A. Correa Bahnsen, E. C. Bohorquez, S. Villegas, J. Vargas, and F. A. Gonzalez, “Classifying phishing urls using recurrent neural networks,” in Electronic Crime Research (eCrime), 2017 APWG Symposium on. IEEE, 2017, pp. 1–8.\n", "https://albahnsen.com/wp-content/uploads/2018/05/classifying-phishing-urls-using-recurrent-neural-networks_cameraready.pdf" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import zipfile\n", "with zipfile.ZipFile('../datasets/model_deployment/phishing.csv.zip', 'r') as z:\n", " f = z.open('phishing.csv')\n", " data = pd.read_csv(f, index_col=False)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
urlphishing
0http://www.subalipack.com/contact/images/sampl...1
1http://fasc.maximecapellot-gypsyjazz-ensemble....1
2http://theotheragency.com/confirmer/confirmer-...1
3http://aaalandscaping.com/components/com_smart...1
4http://paypal.com.confirm-key-21107316126168.s...1
\n", "
" ], "text/plain": [ " url phishing\n", "0 http://www.subalipack.com/contact/images/sampl... 1\n", "1 http://fasc.maximecapellot-gypsyjazz-ensemble.... 1\n", "2 http://theotheragency.com/confirmer/confirmer-... 1\n", "3 http://aaalandscaping.com/components/com_smart... 1\n", "4 http://paypal.com.confirm-key-21107316126168.s... 1" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data.head()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
urlphishing
39995http://www.diaperswappers.com/forum/member.php...0
39996http://posting.bohemian.com/northbay/Tools/Ema...0
39997http://www.tripadvisor.jp/Hotel_Review-g303832...0
39998http://www.baylor.edu/content/services/downloa...0
39999http://www.phinfever.com/forums/viewtopic.php?...0
\n", "
" ], "text/plain": [ " url phishing\n", "39995 http://www.diaperswappers.com/forum/member.php... 0\n", "39996 http://posting.bohemian.com/northbay/Tools/Ema... 0\n", "39997 http://www.tripadvisor.jp/Hotel_Review-g303832... 0\n", "39998 http://www.baylor.edu/content/services/downloa... 0\n", "39999 http://www.phinfever.com/forums/viewtopic.php?... 0" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data.tail()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Model using RF" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.8000757575757576\n" ] } ], "source": [ "keywords = ['https', 'login', '.php', '.html', '@', 'sign']\n", "for keyword in keywords:\n", " data['keyword_' + keyword] = data.url.str.contains(keyword).astype(int)\n", "data['lenght'] = data.url.str.len() - 2\n", "domain = data.url.str.split('/', expand=True).iloc[:, 2]\n", "data['lenght_domain'] = domain.str.len()\n", "data['isIP'] = (domain.str.replace('.', '') * 1).str.isnumeric().astype(int)\n", "data['count_com'] = data.url.str.count('com')\n", "\n", "X = data.drop(['url', 'phishing'], axis=1)\n", "y = data.phishing\n", "\n", "from sklearn.ensemble import RandomForestClassifier\n", "from sklearn.model_selection import train_test_split\n", "\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)\n", "\n", "clf = RandomForestClassifier(n_jobs=-1, n_estimators=100)\n", "\n", "clf.fit(X_train, y_train)\n", "y_pred = clf.predict(X_test)\n", "\n", "print((y_pred == y_test).mean())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using LSTM\n", "\n", "In the previous experiement, we designed a set of features\n", "extracted from a URL and fed them into a classification model\n", "to predict whether a URL is a case of phishing. We now\n", "approach the problem in a different way. Instead of manually\n", "extracting the features, we directly learn a representation from\n", "the URL’s character sequence.\n", "\n", "Each character sequence exhibits correlations, that is,\n", "nearby characters in a URL are likely to be related to each\n", "other. These sequential patterns are important because they can\n", "be exploited to improve the performance of the predictors." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/al/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", " from ._conv import register_converters as _register_converters\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Using TensorFlow backend.\n" ] } ], "source": [ "import tensorflow as tf\n", "sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))\n", "import keras\n", "from keras import backend as K\n", "print(K.tensorflow_backend._get_available_gpus())" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from keras.models import Sequential\n", "from keras.layers.recurrent import LSTM\n", "from keras.layers.core import Dense, Dropout\n", "from keras.layers.embeddings import Embedding\n", "from keras.preprocessing import sequence" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from livelossplot import PlotLossesKeras\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create vocabulary" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "X = data['url'].tolist()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# For vocabulary only the intersec characters is used to avoid issues with data collection\n", "voc = set(''.join(X))\n", "vocabulary = {x: idx + 1 for idx, x in enumerate(set(voc))}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create embeeding" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# Max len\n", "max_url_len = 150\n", "X = [x[:max_url_len] for x in X]\n", "# Convert characters to int and pad\n", "X = [[vocabulary[x1] for x1 in x if x1 in vocabulary.keys()] for x in X]" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "40000" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(X)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "X_pad = sequence.pad_sequences(X, maxlen=max_url_len)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 0, 0, ..., 92, 33, 47],\n", " [ 0, 0, 0, ..., 76, 38, 47],\n", " [ 0, 0, 0, ..., 70, 33, 47],\n", " ...,\n", " [ 0, 0, 0, ..., 38, 69, 47],\n", " [ 0, 0, 0, ..., 70, 23, 47],\n", " [ 0, 0, 0, ..., 96, 70, 47]], dtype=int32)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X_pad" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create the network" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "X_train, X_test, y_train, y_test = train_test_split(X_pad, y, test_size=0.33, random_state=42)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "embedding_1 (Embedding) (None, 150, 128) 12800 \n", "_________________________________________________________________\n", "lstm_1 (LSTM) (None, 32) 20608 \n", "_________________________________________________________________\n", "dropout_1 (Dropout) (None, 32) 0 \n", "_________________________________________________________________\n", "dense_1 (Dense) (None, 1) 33 \n", "=================================================================\n", "Total params: 33,441\n", "Trainable params: 33,441\n", "Non-trainable params: 0\n", "_________________________________________________________________\n" ] } ], "source": [ "model = Sequential()\n", "model.add(Embedding(len(vocabulary) + 1, 128, input_length=max_url_len))\n", "model.add(LSTM(32))\n", "model.add(Dropout(0.5))\n", "model.add(Dense(1, activation='sigmoid'))\n", "model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])\n", "\n", "model.summary() " ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1gAAAE1CAYAAAD6akEFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3Xd4VNXWwOHfSicFSIEESAUSICC9ShWQIiIqFqSJDeu1XPv9vHrt2L0qiihcCwIqYEEpilKlBgSpoYQ0ILRQQiAhZX9/nAkMMUCASWaSrPd55smcOfucsyaB7KzZe68jxhiUUkoppZRSSl06N2cHoJRSSimllFKVhSZYSimllFJKKeUgmmAppZRSSimllINogqWUUkoppZRSDqIJllJKKaWUUko5iCZYSimllFJKKeUgmmCpSk1EjIg0LMfr3S0i75bX9c4Sw0sickBEMsr5uuNE5N8OOM81IjLVETEppZRSSpU30ftgKWcQkWTgTmPMvDK+jgFijTHby/I6tmt5ATuAjsaYXWV0jXO+HxGJALYCUcaYfWURg+06o7B+fl3K6PwbgKHGmL/K4vxKKVUZicgCoAUQZozJdXI4SlVZOoKllOMMAraUVXJVSlHAwbJMrsrJFGC0s4NQSqmKQkSiga6AAa4px+t6lNe1lKooNMFSLkdE7hKR7SKSKSI/ikhdu319RCRRRI6IyIcislBE7izleWuIyBcisl9EUkTkGRFxs+1raDvXEdv0uq9tr4uIvCMi+2z7/hKRZme5RH9gYbFrdhGRpSJyWETSbCM/FxvLIttp14nIMRG5udi1egO/AnVt+z8TkR4ikl6sXbKtLSLyHxH5xhZLlohsFJG2dm0jRGSGLc6DIvKBiDQBxgGdbNc5bGv7mYi8VMqfoxGRe0Rkm4gcEpGxIiJ2YS4ABpz1h6mUUqq4kcBy4DPg1qIXRaSaiLxl62uOiMgSEalm23e2PmqBfd8qIqNEZIndthGR+0VkG7DN9tp/bec4KiKrRaSrXXt3EfmXiOyw9TWrbf3LWBF5y/5NiMhMEXm4LL5BSpUXTbCUSxGRnsCrwE1AHSAFmGrbFwJMA54GgoFE4PILOP37QA2gPtAdqzO6zbbvReAXIBAIt7UF6AN0A+KAmsDNwMGznP8yW0xF7yUSmG07Vy2gJbD2YmMxxnSz7W9hjPE3xnxtf3HbdMv+wG7b/lHn/5YA1iedU23v70fgA1v87sBPWD+DaKAeMNUYsxm4B1hmu07N4ic818/RztVAO6zpLDcBfe32bQaiRaR6Kd+DUkpVdSOBr2yPviISanv9TaANVn8ZBDwBFJ6njyqNa4EOQLxte5XtHEHAZOBbEfGx7fsncAtwFVAduB04DnwO3GL3AWMI0AtrFoNSFZYmWMrVDAMmGmPW2OaPP401UhKN9Yt5ozFmhjEmH3gPKFUhB1uycDPwtDEmyxiTDLwFjLA1ycOaXlfXGJNjjFli93oA0BhrzeJmY8yes1ymJpBV7L3MM8ZMMcbkGWMOGmPWXkIsZWWJMWaWMaYA+BIr4QFoD9QFHjfGZF9gLOf6ORYZY4w5bIxJBeZjdcxFir6Pf0velFJKnUlEumD1G98YY1ZjrQceaktcbgceMsbsMsYUGGOW2n4vl9hHXcBlXzXGZBpjTgAYYybZzpFvjHkL8AYa2dreCTxjjEk0lnW2tiuBI1hJFcAQYIExZu8lfkuUcipNsJSrqYs12gGAMeYY1ohRPdu+NLt9Bjg1/c02ve2Y7dGVM4UAXvbntj2vZ3v+BCDAStt5brdd43esEZ2xwF4RGX+OUZVDWMlYkQisTq64i4qlDNknqccBH7Hm1EcAKbZk9kKd6+d4tuv6220XfR8PX8S1lVKqqrkV+MUYc8C2Pdn2WgjgQ8l90dn6qNJKs98QkUdFZLNtGuJhrFkaIaW41ufAcNvz4Vgf9ClVoenCROVqdmN9CgeAiPhhTQfcBezBmjJXtE/st40xTc9x3gOcHhnaZHst0nZejDEZwF2283YB5onIImPMdmPMe8B7IlIb+AZ4HCipHPlfWFMJi6RhjQI5LJZzvL+zyQZ8izZso2e1SnlsGhApIh4lJFnnKz96rp9jaTQBko0xR0vZXimlqiTbeqqbAHc5fXsOb6wZAHWAHKABsK7YoWfro6BY3wGEldDmVD9g+1DzSayRqI3GmEIROYT1YWHRtRoAG0o4zyRgg4i0wPrd//1ZYlKqwtARLOVMniLiY/fwwPrU7TYRaSki3sArwArbNLqfgctE5Fpb2/sp+Zf+39imv30DvCwiASIShTUnfBKAiNwoIkXJ2iGsjqNARNqJSAcR8cTqcHKAgrNcZhbWeqoiXwG9ReQmEfEQkWARaXmxsdi292Kt2yqtrVgjUgNs7+EZrI63NFZiJbVjRMTP9jPqbBdHuFil6Utyrp9jaXTHWhuglFLq3K7F6iPisaZat8RKVBZjrcuaCLwtInVtxSY62X4vl9hH2c65FrheRHzFupfkHeeJIQDIB/YDHiLyLNZaqyKfAi+KSKxYmotIMIAxJh1r/daXwPSiKYdKVWSaYClnmgWcsHv8xxjzG9bo0HSsP+4bYM3Jxjb14UbgdazpZvFAAlDae338AytJSgKWYCUBE2372gErROQYVqGHh4wxO7E6iE+wEp0U23XfPMv5ZwKNxVYtz7a26CrgUSATq8MqWt90MbEA/Af43Fbx6abzvWFjzBHgPqzObZftmunnPOj0sQXAQKAhkGo7rqhy4e/ARiBDRA6UcOxZf46ldAvw8QW0V0qpqupW4H/GmFRjTEbRA2t6+zDgKWA9VhKTCbwGuJ2nj3oHOIn1YdrnWMnYuczF+lBsK1ZfmcOZUwjfxvpg8RfgKDABqGa3/3OsQlE6PVBVCnqjYVVh2RbvpgPDjDHznR0PgIiMBuKNMVpi9iKJyEBghDHmvAmkUkqpik9EumHN4og2xhQ6Ox6lLpUmWKpCEZG+wAqsEa/HsaYJ1tcpBUoppVTFY5u+PhVYZ4x5wdnxKOUIOkVQVTSdsCoRHcCavnatJldKKaVUxSPWjesPYxXjeNfJ4SjlMDqCpZRSSimllFIOoiNYSimllFJKKeUgLncfrJCQEBMdHe3sMJRSSpWD1atXHzDGlPbebC6jX79+5sCBvxXQVEopVcmsXr16rjGm34Uc43IJVnR0NAkJCc4OQymlVDkQkRRnx3CxtK9SSqnKT0TO36gYnSKolFJKXSAdvVJKqSoj5EIP0ARLKaWUUkoppRxEEyyllFJKKaWUchBNsJRSSimllFLKQTTBUkoppZRSSikH0QRLKaWUUkoppRxEEyyllFJKKaWUchBNsJRSSimllFLKQVwuwSooNM4OQSmllFJKKaUuioezAyhuS0YWW/dmERca4OxQlFJKKaWUUlWEKchnd9IG0resIidtLb6Zmy/qPC6XYAnw4k+b+OL29oiIs8NRSimllFJKVTa5WeSm/8XuxFWcSFuLT+Zm6uYmUY+T1APyjDt7vCIv6tQul2CFVvdm8bYD/LppL32ahjk7HKWUUkoppVRFZQwcScdk/MXR5D/JTlmLT+YmgnJ34Q3EAIeNH0ke9UkLGoRXveaExrUjqlErIr184JkLH/BxuQQryN+boNr+vPTzZro3qoW3h7uzQ1JKKaWUUkq5uvxc2L8FMjaQv3sdJ9LW4XlgEz75RxGgBpBZGMp6ieZw9V541G1O7dh2xDdqTOsAH4eF4XIJlgDPDWzK8AkrmLgkmXt7NHB2SEoppZRSSilXkn0AMtbD3g2QsZ683X/hfnAbbiYfgJPGm+0mgs2FbdlTLRa3OpcRGtua5vXD6RUWgId72dX6c7kEC6BLbAhXxofywe/bGNy6HrWrOy6jVEoppZRSSlUQhQWQmQQZf0GGlUyZvRuQrD2nmuwniPUFkWw2V7FNYjChzagTE0+r6BB6R9aktgNHp0qjVAmWiPQD/gu4A58aY8YU238PcD9QABwDRhtjNolINLAZSLQ1XW6Muac013xmQBOufHsRr81J5K2bWpTmEKWUUkoppVRFlZsFezdZydTeDVZCtW8T5B0HoEDcSXeP4M+TDdlQ0JNNJopD/nE0iI6idWQgnaMCuatOdbw8nHsnqvMmWCLiDowFrgTSgVUi8qMxZpNds8nGmHG29tcAbwP9bPt2GGNaXmhgUcF+3NE1ho8W7GBEpyhaRtS80FMopZRSSimlXI2t8MSpJKooocpMOtUk16M6qV71+dP0YmVeXTYVRpHiFk5cvRBaRwbSJiqQOyMDCavhejPdSjOC1R7YboxJAhCRqcAg4FSCZYw5atfeD3DI3YLvv6Ih01an858fNzLj3stxc9Oy7UoppZRSSjmcMZCfA3knrEd+jjVylGf7es7tE5B/4vSxZ2yX0D7/xBmXPu4fRZpXfdYGdGHB4TDW5kWwhyBqB/jQJjqQ1pGB3BJVk6Z1a+Dj6foF8EqTYNUD0uy204EOxRuJyP3APwEvoKfdrhgR+RM4CjxjjFlc2uD8vT14sl9jHvt2Hd+v3cX1rcNLe6hSSimllFJVS+JsayTIAUlPqYkbePqCh4/11dMHPKuBRzXw8ge/Wqe2c8SLzFx39uW4sf24LwuOhDL/UC2yc6rh4SbE161O63aBPB0VSOvImtSrWa1C3he3NAlWSe/qbyNUxpixwFgRGQo8A9wK7AEijTEHRaQN8L2INC024oWIjAZGA0RGnnlDr+tb1ePL5SmMmb2Fvk3D8PN2ybocSimllFJKOc/KT2DWY9bzC0h68Kxm21+8/VmO97R7eFQDd08olgQdy81n294stu7NIjHjGIl7j5KYcYwDx3JPtQn286J1VCAPdLCSqebhNanm5fqjU6VRmmwlHYiw2w4Hdp+j/VTgIwBjTC6Qa3u+WkR2AHFAgv0BxpjxwHiAtm3bnpG8ubkJzw2M5/oPl/Lhgu083rdxKUJWSimllFKqitgwA2Y9DnH94MbPrMSoHEZ+cvMLSMooSqRsj71ZpB86PRpWzdOduFB/rmhUi0ZhAcSFBtAoLIDaAd4VcnSqNEqTYK0CYkUkBtgFDAGG2jcQkVhjzDbb5gBgm+31WkCmMaZAROoDsUASF6h1ZCDXt6rHJ4t3cnPbSCKDfS/0FEoppZRSSlU+O+bDjNEQ2RFu+J81suRgBYWG1MzjJNonU3uz2Hkgm4JCa2zEw01oUMufVpGBDGkXcSqRigj0rXJ1FM6bYBlj8kXkAWAuVpn2icaYjSLyApBgjPkReEBEegN5wCGs6YEA3YAXRCQfq4T7PcaYzIsJ9Mn+jZmzMYOXZ23i4xFtL+YUSimllFJKVR67VsPUYRASB7dMAa9LG4QwxpBxNOeM0aite7PYtvcYufmFgDUwFhnkS1xoAP2ahhEXFkCj0ABiQvycXh7dVZRqQZMxZhYwq9hrz9o9f+gsx00Hpl9KgEVCq/tw/xUNeWNuIn9sP0DnhiGOOK1SSimllFIVz4Ft8NWN4BcMw6dDtcALOvxQ9kkS7Uajttq+ZuXkn2oTWt2buNAARnSMOpVIxYb64+ulNRHOpUJ9d+7oEsPUVam8MHMTPz/YBQ93zZKVUkoppVQVc3Q3fHk9IDDie6he56xNs3Pz2bbvGIkZVqGJrXutRGp/1umCE9V9PGgcVp1BLevSKDSARmHViQv1p6avVzm8mcqnQiVYPp7u/N9V8dwzaTWTV6YyslO0s0NSSimllFKq/BzPtJKrE4dg1E8Q3ODUrpSD2axNO3x6rdTeLNIyTxec8PF0Iy40gO5xtWhcRQpOOEOFSrAA+jYN5fIGwbz1y1YGNq9LoJ9m1koppZRSqgo4eRymDIHMHTBsGtRtiTGGVcmH+HjhDn7bsg+wCk7Ur+VHi/Ca3Ny2aheccIYKl2CJCM8NbEr//y7i3XlbeX5QM2eHpJRSSimlVNkqyINvR0HaSrjpcwqju/Hrxgw+XriDNamHCfLz4pHecfRtFkr9EH8tOOFEFS7BAmgUFsDwjlFMWpHK0A5RNAoLcHZISimllFJKlY3CQvjhAdg2l7z+bzP9WCvGv72QpAPZRARV48VBTbmhTUSluVFvRVdhU9tHesfh7+3B8zM3Yow5/wFKKaWUUkpVNMbAr/+Gv6ayIvpeLp8XxVMz1uPr7c4HQ1sx/9EejOgUrcmVC6mwCVagnxeP9olj6Y6D/LJpr7PDUUoppZRSyuGO/vYmLPuAr0xfbt7ShcZhAUy+swMzH+jC1c3ralVtF1ShfyJD20cSF+rPSz9vIievwNnhKKWUchIR6SciiSKyXUSeKmF/lIj8JiJ/icgCEQm32xcpIr+IyGYR2SQi0eUZu1JKlSQxI4uvP36F6kteYmZBJ1Y1fpKfH+zKl3d04PKGIVr1z4VVyDVYRTzc3XhuYFOGfbqCCUt2cv8VDZ0dklJKqXImIu7AWOBKIB1YJSI/GmM22TV7E/jCGPO5iPQEXgVG2PZ9AbxsjPlVRPyBwnIMXymlTjHGsHJnJh8vSsJt62w+9nyb7dXb03LkVAbWquns8FQpVegEC6BzwxD6xIcydv52bmgTTmh1H2eHpJRSqny1B7YbY5IARGQqMAiwT7DigUdsz+cD39vaxgMexphfAYwxx8oraKWUKlJQaPh1UwbjFiaxNu0wvXy3M87nA0xoKxqO+g68/Z0doroAFXqKYJFnBsSTX2B4bfYWZ4eilFKq/NUD0uy2022v2VsHDLY9vw4IEJFgIA44LCIzRORPEXnDNiKmlFJlLievgMkrUun99kLumbSGzOyTvN/Li08938QjMBKP4dM0uaqAKkWCFRnsy51dY5jx5y7WpB5ydjhKKaXKV0kLEYqXl30M6C4ifwLdgV1APtZMjq62/e2A+sCoEi8iMlpEEkQkYf/+/Q4KXSlVFR05nsfY+dvp8tp8/vXdevy9PRg7tDXz74hm4Lr7ES9/GPEd+AU7O1R1ESr8FMEi913RkGmr03l+5ia+u/dyvUu1UkpVHelAhN12OLDbvoExZjdwPYBtndVgY8wREUkH/rSbXvg90BGYUPwixpjxwHiAtm3b6v1BlFIXbPfhE0xYspMpK1M5frKA7nG1uLt7fTrVD0ay98PE6yE/F26fCzUjzn9C5ZIqTYLl7+3BU/0b889v1vHdn7sY3Cb8/AcppZSqDFYBsSISgzUyNQQYat9AREKATGNMIfA0MNHu2EARqWWM2Q/0BBLKLXKlVJWwJeMo4xcm8eO63RjgmhZ1uatrfeLrVrca5ByFSYMhKwNG/gC1Gzs1XnVpKk2CBXBty3p8sSyFMXO20LdZGP7elertKaWUKoExJl9EHgDmAu7ARGPMRhF5AUgwxvwI9ABeFREDLALutx1bICKPAb+JVfN4NfCJM96HUqpyMcawYmcmHy/cwfzE/fh6uTOyUzS3d4kmPND3dMO8HJg6FPZtglumQkR75wWtHKJSZSBubsJzA+O57sOljJ2/nSf7afavlFJVgTFmFjCr2GvP2j2fBkw7y7G/As3LNEClVJVRUGj4ZWMG4xYlsS7tMMF+XjzWJ47hHaOo6et1ZuPCAphxJyQvhus/gdgrnRO0cqhKlWABtIoMZHDrcCYs3smQdhFEBfs5OySllFJKKVXJ5eQVMH1NOp8sSiL54HGig315+bpmDG4djo9nCcVJjYGf/wmbZ0K/MdD8pvIPWpWJSpdgATzZrxFzNuzhpZ8388nIts4ORymllFJKVVKHj59k0vIUPluazIFjJ2kRXoOPhrWmT9Mw3M9VdG3+y7D6M+j6KHS8t9ziVWWvUiZYtav7cH/Phrw+J5HF2/bTNbaWs0NSSimllFKVyK7DJ5iweCdTV1kVAXs0qsXd3RrQsX4Q1pLOc1g+Dha9Aa1HQs9/l0/AqtxUygQL4PbOMUxdmcYLMzcx+6GueLhXilt+KaWUUkopJ9q85yjjF1kVAQVbRcBu9WlSp3rpTrB+Gsx5EhpfDQPegfMlY6rCqbQJlo+nO88MaMLoL1czaXkKozrHODskpZRSSilVARljWJZ0kI8XJrFwq1URcNTl0dzeJYZ6NauV/kTb58F3d0NUFxg8Adwr7Z/iVVql/qleGR9Kl4YhvP3rVq5pWY8gP6/zH6SUUkoppZTN4m37eXNuIuvSjxDi78XjfRsxvEMUNXw9L+xE6Qnw9Uio1QRumQyePmUTsHK6Sj1vTkR4dmA82ScLeOfXrc4ORymllFJKVRCbdh9lxIQVjJiwkoPZJ3nlustY8mRP7r+i4YUnV/sT4asbwb8WDJ8OPjXKJmjlEir1CBZAXGgAIzpG8cWyZIZ1jKRxWCnnxyqllFJKqSpn1+ETvPVLIt/9uYvqPp48M6AJIzpF4e1RQqn10jiSDl9eD24eMOI7CAh1bMDK5VT6BAvg4d6xfL92F8//uInJd3U4f2UXpZRSSilVpRw5kceHC7bzvz+SARjdrT73db+I0Sp7xzOt5Cr3KIz6GYLqOyZY5dKqRIJV09eLR6+M498/bGTuxgz6Navj7JCUUkoppZQLyM0vYNLyVN7/fRtHTuRxXat6PNqn0YUVryjJyWxrWuChZBgxA+o0d0i8yvVViQQL4Jb2kXy1IpWXft5Mj0a1S76jtlJKKaWUqhIKCw0/rd/DG3O3kJZ5gq6xITzVvzFN6zpgfVT+Sfh6BOxeAzd9CdFdLv2cqsKo1EUu7Hm4u/Hs1fGkHzrBp4uTnB2OUkoppZRykmU7DnLth3/w4JQ/8ff25Ivb2/PlHR0ck1wVFsIP98GO32Dgf6HJ1Zd+TlWhVJkRLIDLG4bQr2kYY+fv4IY2EYTV0PKYSimllFJVxda9Wbw2ewu/bdlH3Ro+vHVjC65tVQ93NwetzzcG5j4N67+FXs9B65GOOa+qUKpUggXwfwOa8HviPl6bs4V3bm7p7HCUUkoppVQZ23s0h3d+3co3CWn4eXvwVP/GjLo82vFLRha/BSvGQcf7ocsjjj23qjCqXIIVEeTL6K71+WD+doZ3jKJNVKCzQ1JKKaWUUmUgKyeP8YuS+GRxEgWFhts6x/DAFQ0J9PNy/MVWfwa/vwjNb4Y+L4FWra6yqlyCBXBvjwZ8uzqNF2Zu5Lv7OuPmqGFhpZRSSinldHkFhUxZmcp/523jYPZJrmlRl8f6NCIy2LdsLrh5Jvz0CDS8EgaNBbcqU+ZAlaBUP30R6SciiSKyXUSeKmH/PSKyXkTWisgSEYm32/e07bhEEenryOAvVtHQ8Lr0I0xfk+7scJRSSimlqp7CAjiUYn11EGMMs9fvoc87i3j2h400rO3PD/d35r1bWpVdcrVzMUy7A+q1gZs+B/dLuG+WqhTOO4IlIu7AWOBKIB1YJSI/GmM22TWbbIwZZ2t/DfA20M+WaA0BmgJ1gXkiEmeMcdz/pIs0qEU9vliWwmtzEunXLIwAH/3PoJRSSilVbn5/EZa8A56+ENoUwppD2GXW19pNwOvCEqKE5ExembWZNamHia3tz8RRbbmiUW2kLKfq7VkHU26BoBgY+g14+ZXdtVSFUZopgu2B7caYJAARmQoMAk4lWMaYo3bt/QBjez4ImGqMyQV2ish22/mWOSD2S+LmJvxnYFMGjf2DD+Zv5+n+TZwdklJKKaVU1bA/EZa+b02pC24AGeutynsJE6z94gYhcbaEy5Z0hTUHv+C/nWrH/mO8PmcLczfupXaAN68NvozBrcPxcC/jaXoHd8CkweBTA4bPAN+gsr2eqjBKk2DVA9LsttOBDsUbicj9wD8BL6Cn3bHLix1br4RjRwOjASIjI0sTt0O0iKjJDW3CmbhkJ0PaRRITop86KKWUUkqVKWNg9hPWaM9148Av5PTrh5KtZCtjPWT8BSlLrcSrSEBdK+Gq05wjNRozYbs/H67Lx8fTk8f6xHF7lxh8vcqhxEBWBky63preOOo7qPG3P29VFVaaf4Eljauav71gzFhgrIgMBZ4Bbr2AY8cD4wHatm37t/1l6Ym+jZi9fg8v/7yZT29tW56XVkoppZSqejb9AEkLoP8bp5MrsKruBcVYj/hrTr+efRD2roc9f0HGegr3/AXbfqUGhfwTuM/HD/e6l+GZ0wI2WMkXtRqDh3fZxH/iMEy6AY7th1tnQq24srmOqrBKk2ClAxF22+HA7nO0nwp8dJHHlrva1X34R69YxszewqKt++kWV8vZISmllFJKVU4ns2Hu/0HoZdD29tId4xcM9XuQH9WNb1en8/aWrRzNyeK2hse5o+ExamVvtZKvP7+EvOPWMW4eVpJ1al3XZRDWDKpd4u158k7A1KGwfwsM+wbC21za+VSlVJoEaxUQKyIxwC6sohVD7RuISKwxZpttcwBQ9PxHYLKIvI1V5CIWWOmIwB3pts7RTFmZygs/bWL2Q13xLOs5u0oppZRSVdHit+BoOgz+FNxLN5XPGMNvm/cxZs4Wtu87RtuoQJ4e3ubv9zItLIDMnZCx7vQ0wx2/wbrJp9vUjCyWdDWHGuGlu2dVQb5VLTBlKdwwARr0PP8xqko6779sY0y+iDwAzAXcgYnGmI0i8gKQYIz5EXhARHoDecAhrOmB2Np9g1UQIx+43xUqCBbn7eHOMwPiueuLBCYtT+G2zjHODkkppZRSqnI5uMMqbNF8CER1KtUha9MO8+qszazYmUn9ED8+HtGGPvGhJVcGdHOHkIbWo9ng069n7T29pqvo65afObVqxaembV1Xi9OJV0jcmeXWjYGfHoLEn62pjfbnV6oYMaZclzydV9u2bU1CQkK5X9cYw8iJK1mXdpgFj19BUFnc4VsppdQZRGS1MabCLYB1Vl+lVIVlDHx1A6SugH+shoDQczZPOZjNG3MT+emvPYT4e/FQ7ziGtItw3Cyj3GOwb5NVZr1otGvfJsjPsfa7e1ul4otGuQ5ug5XjofuTcMW/HBODqhAupp8qhzIrFYOI8OzV8fT772Le+iWRl6+7zNkhKaWUUkpVDomzYPs86PvKOZOrzOyTvP/7NiYtT8HDzY0He8Uyult9/L0d/Certz9EtLceRQryrUSqaJRrj22k688vrf1tb4ceTzs2DlUpaYJlJzY0gBEdo/hiWTLDOkQRX7e6s0NSSimllKrY8k7AnKegVhNoP7rEJjl5BUyoI/QXAAAgAElEQVT8Yycfzd9B9sl8bm4XySO9Y6ld3af84nT3sEatajeB5jdZrxkDR3fDsQyo06p0a7VUlacJVjGP9I7jh7W7eOGnjUy5q2PZ3v1bKaWUUqqyW/IuHE6FW386c10TUFBomLEmnbd/3cqeIzn0bhLKk/0aERsa4KRgixGx7nGl97lSF0ATrGJq+HryaJ9GPPP9BmZvyOCqy+o4OySllFJKqYopcycseccqChHT9YxdS3cc4IWZm9iSkUWLiJq8e3NLOtQPdlKgSjmO1iMvwS3tI2kcFsDLP28mJ8/lih4qpZQqgYj0E5FEEdkuIk+VsD9KRH4Tkb9EZIGIhBfbX11EdonIB+UXtVKV3JynrVGrPi+demnf0RwenPInQz9ZQfbJfD4Y2orv77tckytVaWiCVQJ3N+G5gU3ZdfgEnyxKcnY4SimlzkNE3IGxQH8gHrhFROKLNXsT+MIY0xx4AXi12P4XgYVlHatSVcbWubB1NnR/AqrXJb+gkIlLdtLzrYXM2ZjBQ71i+fWR7lzdvK4uyVCVik4RPItODYK56rIwPlywgxvahlOnRjVnh6SUUurs2gPbjTFJACIyFRiEdR/GIvHAI7bn84Hvi3aISBsgFJgDVLiy8Uq5nLwcmP2kdT+pDveyOuUQz3y/gc17jtI9rhbPX9OU6BA/Z0epVJnQEaxzeLp/EwqMYczsLc4ORSml1LnVA9LsttNtr9lbBxTdHfQ6IEBEgkXEDXgLePxcFxCR0SKSICIJ+/fvd1DYSlVSS9+HQzs5esUrPPH9ZgZ/tJTDx08ybnhrPrutnSZXqlLTBOscIoJ8ubtbfX5Yu5uE5Exnh6OUUursSppfZIptPwZ0F5E/ge7ALiAfuA+YZYxJ4xyMMeONMW2NMW1r1arliJiVqpwOp2IWv0Vq2JV0m26YsWYXd3evz7x/dqdfszo6HVBVejpF8Dzu7dGAbxPSeX7mJn64vzNubvpLQSmlXFA6EGG3HQ7stm9gjNkNXA8gIv7AYGPMERHpBHQVkfsAf8BLRI4ZY/5WKEMpdX5Hvn8C7/xChiQPpFFMAC9e24w4Vym7rlQ50BGs8/D18uDpqxqzftcRpq1Od3Y4SimlSrYKiBWRGBHxAoYAP9o3EJEQ23RAgKeBiQDGmGHGmEhjTDTWKNcXmlwpdeGOnMjj8y8nUCN5NhPcBvPEzb2ZOrqjJleqytEEqxSuaVGXNlGBvD53C1k5ec4ORymlVDHGmHzgAWAusBn4xhizUUReEJFrbM16AIkishWroMXLTglWqUrGGOtmwX3f/JUu297goHc4wx95g2tb1dPpgKpK0imCpSAiPDcwnkFj/+CD37fz9FVNnB2SUkqpYowxs4BZxV571u75NGDaec7xGfBZGYSnVKWUmJHFv3/YwMqdmTwf/CsNCvbADdMgwN/ZoSnlNDqCVUrNw2tyY5twJv6xk6T9x5wdjlJKKaWU02Tn5vPKrM0MeG8xW/dm8W7/Wow8+Q00GgCxVzo7PKWcShOsC/BY30Z4e7jz8s+bnR2KUkoppVS5M8Ywa/0eer+9kPGLkrihTTi/P9qDa/d9hJgC6PeKs0NUyulcL8HKzQJTvLKua6gd4MM/ejbkty37WJC4z9nhKKWUUkqVm50Hshk5cSX3fbWGQF8vpt97OWMGNydo33LYOAO6PAKB0c4OUymnc70E6+B2mHQ97E90diQlGtU5muhgX178aRN5BYXODkcppZRSqkzl5BXw9i+J9H1nEWtTD/PcwHh+fKAzbaICoSAPZj0ONaOg80PODlUpl+B6CVaNcEhfDR9dDnP/D3KOODuiM3h7uPPvq+PZsT+bWyeuZHXKIWeHpJRSSilVJn7fspcr31nIe79v56rLwvjt0e7c1jkGD3fbn5ArPob9W6DfGPCs5txglXIRrpdg+dWCB9dAy6GwbCy83xb+/AoKXWe0qGfj2jw3MJ4tGVkM/mgpIyasYHVKprPDUkoppZRyiPRDx7nriwRu/ywBbw93Jt/VgXeHtKJ2dZ/TjbIyYMEYiO0Djfo7L1ilXIwYF1vv1LZtW5OQkGBt7FoDs5+A9FVQrw30fwPC2zg3QDvZuflMWp7C+EVJHMw+SdfYEB7qFUvb6CBnh6aUUhWCiKw2xrR1dhwX6oy+SqlK5GR+IZ8sTuL937chCA/2iuWOLjF4eZTwmfyM0bDxO7hvOQQ3KP9glSoHF9NPud4Ilr16reH2X+DacXAkHT7tCT/cD8dco8CEn7cHd3dvwOInr+BfVzVm0+6j3DBuGcM/XUFCso5oKaWUUqriWLr9AP3/u4g35ibSI6428x7tzr09GpScXKUshb++hssf1ORKqWJcewTLXs5RWPQGLP/ImuPb4yloPxrcPcs/yLM4fjKfr5an8vGiHRw4dpLODYN5uHcc7XRESymlSqQjWEo5376jObz082Z+XLebyCBfnh/UlCsa1T77AQX5ML67tU7+/pXg5Vt+wSpVzirfCJY9n+rQ50W4bxlEtIe5/4KPOsOO350d2Sm+Xh7c1a0+i5/oyTMDmpCYkcWN45Yx7NPlrNypI1pKKaWUch35BYVMWLKTnm8tZM7GDB7qFcsvj3Q7d3IFkDAB9m6Avq9ocqVUCSrOCJY9Y2DrHJjzFBxKhsZXQ9+XXe7eCydOFvDVihTGLUziwLFcLm8QzEO9YulQP9jZoSmllEvQESylnCMhOZNnvt/AlowsusfV4vlrmhId4nf+A4/tswqQ1WsNI74DkbIPViknuph+yqOsgilTIla1mvpXwPKxsOhN+KC9df+FLo+4zKcp1bzcubNrfYZ1iDqVaN08fjmd6gfzcG9NtJRSSilVvg4ey2XM7C18uzqdOjV8GDe8NX2bhiGlTZTmPQ95x+GqNzS5UuosKmaCVcTTB7o+Cs2HwK/PwqLXYe1k6PsSxF/rMv/x7ROtyStTGbdwBzePX07H+kE83DuOjppoKaWUUqoMFRYapqxK5fU5iWTn5nN39/o82DMWP+8L+FMwbSWsnWR9oB0SW3bBKlXBVcwpgmeTshRmPQF710N0V+j/GoQ2dWyADpCTV8DkFal8tHAH+7Ny6RBjJVqdGmiipZSqWnSKoFJlb336EZ75YQPr0g7TISaIl65tRmxowIWdpLAAPrkCju2HB1aBt3/ZBKuUi6ncRS5KI+pyuHshDHjbWnw5rquVcJ045OzIzuDj6c7tXWJY/MQVPDcwnp0Hsrnlk+Xc/PEylu046OzwlFJKKVUJHDmRx7M/bOCasUvYdegE797ckqmjO154cgWw+jPYs86aJaTJlVLnVLlGsOwdz4T5L0PCRPCpCb2ehdYjwc390s/tYDl5BUxZmcpHC3awLyuX9jFBPNw7lk71g0s/J1oppSogHcFSyvGMMcxYs4tXZ28mM/skIztF88iVcdSodpG3tsk+CO+3hrDL4NaZLrMEQ6nycDH9VOVNsIpkrIfZT0LKH1CnBfR/AyI7OO78DpSTV8DUlal8WJRoRdsSrQaaaCmlKidNsJRynIJCw9yNGXy8cAfr0o/QMqImL13bjGb1alzaiX98ENZ+BfcsgdpNHBOsUhVE1akieCHCLoNRP8OG6fDLv2FiH2h+M/R+HqrXcXZ0Z/DxdGdU5xiGtI/k61VpfLhgO0M/XUH76CAe6h3L5ZpoKaWUUqqYnLwCvl2dzqeLk0g5eJzIIF9eH9ycG9qE4+Z2iX837FoNa76ATvdrcqVUKZVqBEtE+gH/BdyBT40xY4rt/ydwJ5AP7AduN8ak2PYVAOttTVONMdec61pl+qngyWxY/DYsfQ/cvaDb49DxXvDwLpvrXaKcvAK+SUjjw/k7yDiaQ7voQB7uHaeJllKq0tARLKUu3qHsk3y5PIXPlyZzMPskLcJrcHf3BvRtGob7pSZWAIWFMKE3HEmHBxLAp/qln1OpCqZMpgiKiDuwFbgSSAdWAbcYYzbZtbkCWGGMOS4i9wI9jDE32/YdM8aUejVkuXRamUkw9/8gcRYENYB+YyCuT9le8xIUT7TaRlmJVueGmmgppSo2TbCUunBpmceZsGQnX69K40ReAVc0qsXobg3oWD/IsX8XrPkCfvwHXDceWtzsuPMqVYGU1RTB9sB2Y0yS7SJTgUHAqQTLGDPfrv1yYPiFBFHugurDLVNg2zyY8yRMvhFi+0K/VyG4gbOj+xsfT3dGdorm5nYRfLMqjbHzdzB8wgraRAXycO9YujQM0URLKaWUquQ27DrCx4uSmLV+DwIMalmP0d3q0yjsIqoCns/xTJj3H4jsBM1vcvz5larESpNg1QPS7LbTgXNVibgDmG237SMiCVjTB8cYY76/4CjLSmxviFkGK8bBwtfhw47WHOOuj7lkCVJvD3dGdIrmpnYRfJOQzofztzNiwkraRAXyUK9YusZqoqWUUkpVJsYYFm87wPhFSSzZfgB/bw/u6BLDbZ2jqVOjWtldeP7L1m1urnpDqwYqdYFKk2CV9L+qxHmFIjIcaAt0t3s50hizW0TqA7+LyHpjzI5ix40GRgNERkaWKnCH8fCCzg9an87Mex6WvAPrpsKVL8JlN7jkLxVvD3dGdIziprbhfGtLtEZOXEnryJo83DtOEy2llFKqgssrKGTW+j2MW5jE5j1HqR3gzZP9GjO0Q+TFl1svrT3rrNvctLvLKhamlLogpVmD1Qn4jzGmr237aQBjzKvF2vUG3ge6G2P2neVcnwE/GWOmne16Tp/XnrYKZj8Ou/+EiI5w1etWeXcXlptfcCrR2n0kh1a2RKubJlpKKRena7CUOlN2bj5fr0pjwpKd7Dp8gga1/Li7WwMGtaqLt0c53MuzsBD+1w8O7oB/rIZqNcv+mkq5sLJag7UKiBWRGGAXMAQYWuzCrYCPgX72yZWIBALHjTG5IhICdAZev5AAy11EO7jzd1g7yRrR+rg7tBkFPf8NfsHOjq5E3h7uDO8YxY1tw5m2Op2xv2/n1okraRlRk4d7x9I9rpYmWkoppZQL25+Vy+dLk/lyeQpHTuTRLjqQ569pSs/GtS+91PqF+GsqpK2AQWM1uVLqIp03wTLG5IvIA8BcrDLtE40xG0XkBSDBGPMj8AbgD3xr+0O+qBx7E+BjESkE3LDWYG0q8UKuxM0NWo+EJtfAgjGwcjxs/A56PgNtbgN317x9mLeHO8M6RHFjmwgr0Zq/nVH/W0V8neoM7xjFoJZ18fN2zdiVUkqpqmjngWw+WZzEtNXp5BUU0ic+lNHdGtAmKrD8g8k5Ar8+C+HtoMXQ87dXSpWoVPfBKk8uOe1i32aY/QTsXAShzaD/axDdxdlRndfJ/EJmrEnns6XJbMnIwt/bg+ta1WNYx0gah+m9LJRSzqdTBFVV9WfqIT5emMTcTRl4ursxuHU4d3aNoUEtJxbZmv2UVfhr9Hyo28p5cSjlQspqiqCq3QRG/gibZ1r3z/psADS9Hro8DGHNXbIQBoCXhxtD2kdyc7sI1qQe5qvlKXydkMaXy1NoExXI8I6R9G9WBx/PcpjTrZRSSlVxhYWG+Yn7+HhhEiuTM6nu48H9PRpy6+XR1Arwdm5wezdaM3ba3qbJlVKXSEewLlTeCfjjPVjyNuTnQHBDaDbYSrhqN3Z2dOd1KPsk09ek89WKVHYeyKamryc3tglnaIcoYkL8nB2eUi4hLy+P9PR0cnJynB1KpeHj40N4eDienmdWP3PUCJaI9AP+izWV/VNjzJhi+6OAiUAtIBMYboxJF5GWwEdAdaAAeNkY8/X5rufyfZVyKbn5BfywdjfjFyWxfd8x6tWsxu1dYri5XQT+rjB13xjrw+N9m63CFr5Bzo5IlYL2VY7lyH5KE6yLdTwTNv8IG6bDzsWAgdpNodn11iOovrMjPKfCQsOypIN8tSKFXzbuJb/Q0KVhCMM6RNI7PhRPdzdnh1h+CvIg5yjkFj2ybNtZp1+z3xZ3a5qoLv6ttHbu3ElAQADBwcFaIMYBjDEcPHiQrKwsYmJiztjniARLRNyBrcCVWPdqXAXcYr/mV0S+xapi+7mI9ARuM8aMEJE4K0SzTUTqAquBJsaYw+e6ZoXpq5RTHc3JY/KKVCYu2cm+rFwahwVwT/cGDGhex7X62b++hRl3wtXvWiNYqkLQvspxHN1PucDHJhWUb5BVXbDNKMjKgE0/wIYZ8PuL1qNuayvRanod1Ah3drR/4+YmdG4YQueGIew7msPXq9KYsjKVe79aQ+0Ab4a0i2BI+0jq1izDmxheqsJCOFk8GcqyFunab59KmM6SQOWX4pMfN0/wqQ7e1eFQMgSEwZXPl/lbVM6Rk5NDdHS0dlgOIiIEBwezf//+srpEe2C7MSbJdr2pwCDAvqhSPPCI7fl84HsAY8zWoga2ezbuwxrlOmeCpdS5ZBzJYeIfO5m8IpVjufl0bhjMmze2cM37VOZmwS/PWNMCW490djTqAmhf5TiO7qc0wXKEgDDocLf1OJxmVRzcMN36hfXLMxDZyZpGGD8I/Gs7O9q/qV3dh3/0iuW+KxqyIHEfk5an8P787Xwwfzs9G9dmWMcousXWwr2sysQaAwe2wv4t5x89st9/Muv85xY38A6wEiPv6tZzv1rWCGPRdlHidMZ2sWM8fU6fc8bd1iLg9qOhRr2y+Z4op9MOy7HK+PtZD0iz204HOhRrsw4YjDWN8DogQESCjTEH7WJsD3gBO8oyWFV5bd2bxfhFSfywdhcFhYYBzetyd7f6NKtXw9mhnd3C1+BYBgyZDG66Jrui0b7KcRz5vdQEy9FqRkDnB63HwR2wcYY1sjXrMasSYXRXK9lqMtDl5ji7uwm9moTSq0koaZnHmboqla9XpTFv8z7CA6txS/tIbmobcekLcQsLYf9mSP4DUpZAylLILuETA0+/vyc8AXXOnxDZb3v5Ob4IyRX/sn6uC16FQR849txKqYtR0n/y4vPfHwM+EJFRwCKs+zrmnzqBSB3gS+BWY0xhiRcRGQ2MBoiMjLz0qFWlYIxh5c5MPl6UxO9b9uHj6cbQ9pHc2bU+EUG+zg7v3PZtgeUfQasREN7G2dEoVWloglWWghtAt8etx77NVqK1YTrMfBB+/ic06GklW42uspICFxIR5MvjfRvzUK84ftmUwVfLU3ljbiLvzttK36ZhDOsQRcf6QaXL9gsLIGM9pPxhJVWpS+HEIWtfjQho0AuiLoe6LaFaoJUceQW47P3GCIyCdnfBio/g8n9ArUbOjkhVQocPH2by5Mncd999F3TcVVddxeTJk6lZ8+xrBJ999lm6detG7969LzVMV5EORNhthwO77RsYY3YD1wOIiD8w2BhzxLZdHfgZeMYYs/xsFzHGjAfGg7UGy5FvQFU8BYWGXzZmMG5REuvSDhPk58UjveMY0SmKID8vZ4d3fsZYH/x6+UHv/zg7GlUBaT91dlrkorwZA3vWnR7ZOpIG7t4Q18eqRBjXD7xc8xOv7fuOMXlFKtNWp3E0J58GtfwY1iGKwa3DqeFrV3GlIM96j8lLrKQqdbk1vQ8gMAaiOkN0Z+trYJRz3sylyj4I77WEmG4w5CtnR6McbPPmzTRp0sSpMSQnJ3P11VezYcOGM14vKCjA3b1iTuMp6fvqoCIXHlhFLnphjUytAoYaYzbatQkBMo0xhSLyMlBgjHlWRLyA2cBMY8y7pb1mpe+r1Fnl5BUwbXU6ny5OIvngcSKDfLmrW31uaB1ONa8K9H9z43fw7Si46k1of5ezo1EXwdl9lfZTZ+eiQwSVmIg1UlO3JfR+HtJXWaNaG7+z7rPl6QeN+lsjWw17gYeT74thp2Ftf54dGM8T/Rrx0197mLQ8hRd+2sTbc9ZzT8MjDA5OJuzwGiR1BeRlWweFxFnFPqK6WKNUlWXNkl+wNQ3095cgdQVEFl/uodSleeqpp9ixYwctW7bE09MTf39/6tSpw9q1a9m0aRPXXnstaWlp5OTk8NBDDzF69GgAoqOjSUhI4NixY/Tv358uXbqwdOlS6tWrxw8//EC1atUYNWoUV199NTfccAPR0dHceuutzJw5k7y8PL799lsaN27M/v37GTp0KAcPHqRdu3bMmTOH1atXExIS4uTvzN8ZY/JF5AFgLlaZ9onGmI0i8gKQYIz5EegBvCoiBmuK4P22w28CugHBtumDAKOMMWvL8z0o17cvK4cpK9L4YlkyB7NP0iK8Bh8Oa03fpmFlt0a5rOQes+7rGXYZtL3d2dGoCkr7qbPTBMuZRCCivfXo+4q1FmnDdFtFwmngXQOaXG0lKDHdwd3z/OcsBz6c5IagndzQ9A+OeSzEOyMBz+STkAzJ7lGcrDeQyNZ98GnY1SWLejhMx/tg5Scw7z9w2yyXveG0ujTPz9zIpt1HHXrO+LrVeW5g03O2GTNmDBs2bGDt2rUsWLCAAQMGsGHDhlPlYydOnEhQUBAnTpygXbt2DB48mODg4DPOsW3bNqZMmcInn3zCTTfdxPTp0xk+fPjfrhUSEsKaNWv48MMPefPNN/n00095/vnn6dmzJ08//TRz5sxh/PjxjvsGlAFjzCxgVrHXnrV7Pg2YVsJxk4BJZR6gqpCK1ld9uTyFORsyyC809GhUi7u7NSj9NHlXtPgtOLoLbvifFraoJJzRV2k/dXaaYLkKN3eI6Wo9rnoDkhZa0wg3z4S1X4FvsFWFsOn11khQef5CzD0G6SttRSn+gF2roeAkIPiHXQYd7uRE3Y7MPBzFxDVH2bI1C/8UD65rtY9hHX1oHOZa68scxssPuj9prafbOhca9XN2RKoSa9++/Rn35njvvff47rvvAEhLS2Pbtm1/67hiYmJo2bIlAG3atCE5ObnEc19//fWn2syYMQOAJUuWnDp/v379CAwMdOj7UcqVHcvN57s16Xy5PIWte49R3ceDWy+PZliHSOrX8nd2eJfmwHZY+j60GKqzL5RDaT91miZYrsjdE2J7W48Bb8OO36yRrXVTIWEi+IdZ99dqNhjC2zp+5CTnqLVuKmWJlVTtWQuF+dYNduu2hA73WOunIjueutluNax5Njd2NaxJPcRXy1P5OiGNL5en0DYqkGEdI+nfrA4+npXsk7LWI2HZWGsUK/ZK/SSwEjrfSFN58fPzO/V8wYIFzJs3j2XLluHr60uPHj3Iyfn7/dy8vU9PMXZ3d+fEiRMlnruonbu7O/n5VmE9V1ufq1R5SMzIYtLyFGasSSf7ZAHN6lXn9cHNGdiibsVaX3U2RYUtPKvpvRwrGVfoq7SfOk0TLFfn6QONB1iPk9nWSMmG6VaiteIjqBEJzWzJVljzi0u2jmdC6rLTI1QZf4EptG6uW68NXP6gVZQiooNV4e8cRIQ2UUG0iQri31fHM211Ol+tSOGRr9fx/MxN3NgmnKEdoogJ8TvneSoMd0/o9W9rofBfX0PLoc6OSFUSAQEBZGWVfK+3I0eOEBgYiK+vL1u2bGH58rMWvrtoXbp04ZtvvuHJJ5/kl19+4dChQw6/hlKu4GR+IXM3ZvDl8hRW7szEy8ONq5vXYWSnaFqE16i40wBLsuVn60PbfmMq9xR+VS60nzo7TbAqEi8/az1Ws+utUabEWVaytWws/PFfCG5oTSFsNhhqNz77eY7ttxKplKXW170bAWNVM4xob5WVj+oM4e0uqaJhoJ8Xd3Wrzx1dYliWdJBJy1OY+EcynyzeSZeGIQzrEEnv+FA83d0u+houIf5aqNsafn/Z+v7b35RYqYsUHBxM586dadasGdWqVSM0NPTUvn79+jFu3DiaN29Oo0aN6Nixo8Ov/9xzz3HLLbfw9ddf0717d+rUqUNAwLk/YFGqItlz5ARTVqQyZVUa+7NyiQiqxtP9G3Nj24iKUWb9Qp08DnOehtrx1q1GlLpE2k+dnZZprwyOZ1prtTZMh+TF1uhT7aankzGParaEynYfqgOJ1nGevlZCFdXFGqGq16bMqxbuPZrDN6vSmLIyld1Hcqgd4M2QdhEMaR9J3ZrVyvTaZWrnIvh8IPR5ybo3lqrQnF361hXk5ubi7u6Oh4cHy5Yt495772Xt2ksrrFdWZdqdQfuqiqmw0LB0x0G+XJ7MvM37KDSGno1qM7xTFP/P3n2HR1XmbRz/PimQAoSEUEJCCL330HsVFMGCigWVFVhxLVgWdV97WTsqdmQti1iwl6VD6ErvvUPoNdRAyvP+cYYiBghkJmeS3J/rmivJzCn3BJInv3Oe0rZKSQLy2myAl2LyizDtVbhztNPmS55X0Nsqf26ndAcrPwiLgkZ3OI/DuzyzEH4Pk593HqcUKuqMm6p/s1NUla2f6zMTli4Wwn0dq3BP+8okrdrNyNmbeSdpHe8mraNzzdI83KUaVUv7x9WHS1KhjbNg8vQ3oEGf02PTRPKqLVu2cOONN5KZmUmhQoX4+OOP3Y4kctlSjqXx3YJkRv6xmQ17jxIVXoj+rStya9N4ykX559qTXrV/g9PTpc4NKq4k3/DndkoFVn5TtDQ0HeA8UpJhxS/OHa2EllC6DgT6xz95YIChU83SdKpZmq37j/HVnC2M+H0zE1ZMo1ejOB7sXJWYiDx2R6vTM/BRa6cR6/S022lEcqRKlSosXLjQ7RgiObJsWwpf/LGZnxZtIzUtk4bxxXnzpnr5c9KlCxn7uHNBtfPzF99WJI/w53bKP/7aFt+IiIPm97id4qLKRYUxuGt1+rWuyLuT1zHij038vGg7f2tVgbvbViIi1D/W/7qomLpQ50b44wNoMgCKxbidSETE/+3fABunO21WTD0Iz9kioalpGYxeuoMRf2xm4ZaDhAYHcm2DWG5tWp7asRFeCp2HrB4La8Y6xZXaJZFcoQJL/EZUeCGeuromfVsm8Mb41XwwZT1fzdnCve0r06d5eQoH5YGrjR3+D5b/CFNfhqvfdjuNiIh/2r8Blv8EK36CHYv//FrRsk6hFVPXmR03pi5ElLvoLLlb9x/ji9mbGTV3KweOpSlH/F4AACAASURBVFExOpynutfk+kZxeedCnbelpcLYRyG6GjQb6HYakQJDBZb4nXJRYbzVuwH9WlfklbGreOF/K/ls1iYe6VKNHvXK+vcg5MgEaHwXzPkYmv0DSlZ1O5GIiH/IqqiKTXQmB6rSBY7sgh1LnNd2LoG145wu7gChkVCmjqfgquc8SlQmgwCmrdnDiD82k7R6NwHG0LlGafo0L0+LSiXy1xTrl2PWUDiwCW7/OdfHXIsUZCqwxG/Vjo1gxF1Nmb52Dy+PWcWgbxYxbNoGHutWnTZVS7od7/za/BMWjoTJz8FNX7idRkTEPRcqqmr2hOLxZ7YtWc2ZMOiUk8dg94ozBdeOxc7Fq4wTAKQFhLCaeJJPxlOpcGU6Nm5Oh7ZtiSkRmYtv0I8d2OxMvFTzGqjYzu00IgVKHl+ASAqC1lVK8uu9rXjrpvocSk3j9k/mcNvw2SzbluJ2tKyFRztTta/8FbbOdTuNFBBFihQBYPv27fTq1SvLbdq1a8fFphZ/6623OHbs2Omvr7zySg4ePOi9oJL/7d8A04fAR21gaAOY9KyzcH2XF2DQUug/yfkdeXZxlZVCYRCX6PQKuPptbP8kFvRZxmsVPmFwxj3892R7TFBheof8wf9lfMitS+4g5r3K8H4L+HGgMx5200xn3ciCaNy/wATAFS+6nUQEKFjtlO5gSZ4QEGC4pkEs3eqU4Ys/tvDu5LV0f2cGPeuX5ZEu1fxvmt3m/4C5H8PEp+HO/1107ICIt5QtW5bvvvvusvd/6623uO222wgLc36mRo8e7a1okp9dyp2qS3T8ZAa/LN7Gf3/fzPLthyhSuAjXJd5K62blnWU9rHW6wZ2+07UE1k+CxV+eOUhkhbPGdHm6GBYplbP37E8yMyA1BY4fcB7bF8Kq36DjU87kISJ+pCC0UyqwJE8pHBTIXa0qcENiHB9OWc8nMzcyeukObmtWnvs6VCEqvJDbER2Fi0DbR2H0I7B2AlTt4nYiyWMeffRRypcvzz33ODOBPvPMMxhjmDZtGgcOHCAtLY0XXniBnj17/mm/TZs20b17d5YtW8bx48fp27cvK1asoEaNGhw/fvz0dgMHDmTu3LkcP36cXr168eyzzzJ06FC2b99O+/btiY6OJikpiYSEBObNm0d0dDRDhgzhk08+AaBfv34MGjSITZs20a1bN1q1asWsWbOIjY3l559/JjQ0jy2zIJfOh0UVwIY9R/jijy18N38rh1LTqVa6KC9cU5trGsRSpPBZf74YA1EVnEeta848f3iXp+BadGZs14qfz7xepMyfJ9IoU9cZR+vmBbGMdEg9eKZQOvU4tv+vz539SE0B7J+PFV0Nmt/rytuQgkHt1PmpwJI8qVhIMIO7Vuf25gm8OWENn8/axHfzkrm7XSX+1rICoYX8YMbBRnfC7+/BxGegckcI8INMcunGPAY7l3r3mGXqQLeXL7hJ7969GTRo0OmGa9SoUYwdO5YHH3yQYsWKsXfvXpo1a0aPHj3OO5D/gw8+ICwsjCVLlrBkyRIaNmx4+rUXX3yRqKgoMjIy6NixI0uWLOH+++9nyJAhJCUlER3956my58+fz6effsrs2bOx1tK0aVPatm1LZGQka9eu5auvvuLjjz/mxhtv5Pvvv+e2227L4TdJ/JKPi6r0jEwmrdrNiN83M2PdXoIDDd1qx9CneXkSy0de2qQVRUtD0c5QpfOZ51JTnJ/nHUvOjOtaNwlshvN64Yi/Fl3RVS99Dcn0kxcuiP70OFU8HYQTF+rOaJxF7EMjnUdYFJSodObr048o52OpGhBU+NJyS97lQluldur8VGBJnlYmIoRXetWlX+sKvDJ2Na+NW81/f9/Eg52q0qtRHEGBLg4zDAyGjk/Cd3+Dpd9Cvd7uZZE8p0GDBuzevZvt27ezZ88eIiMjiYmJ4cEHH2TatGkEBASwbds2du3aRZkyZbI8xrRp07j//vsBqFu3LnXr1j392qhRoxg2bBjp6ens2LGDFStW/On1c82YMYNrr72W8PBwAK677jqmT59Ojx49qFChAvXr1wegUaNGbNq0yUvfBfELPi6qAHYfTuWbOVv5cs4WdqSkUjYihEe6VOXGxuUoVTQkx8c/LSQCElo5j1PSjnsm01hypovhvE8g3XMlPSgEStU8U3AFBl+gWPLcfTp55PwZTMCfC6IipaFkjSwKpVMPT1EVUhwCNHRe/IfaqfNTgSX5QpXSRRl+RyJzNu7npTEreeyHpQyfsZFHu1anU41S7k3VW/NaiBkKk1+EWtfqamJedJE7Tb7Uq1cvvvvuO3bu3Env3r0ZOXIke/bsYf78+QQHB5OQkEBqauoFj5HV//2NGzfy+uuvM3fuXCIjI7nzzjsvehxr7XlfK1z4zP/rwMDAP3XxkDwqF4oqgEOpabw7eR2fztxIWoaldZVonu1Riw7VS+XeBbLgUIht5DxOyUiHfWv/fKdr+Y8w/7Mz2wQEnblbFBoJxeKgdJ2/FkZhUX8umAoVVaEk3udSW6V2KmsqsCRfaVIhih8GtmDc8p28OnY1/f87j8YJkTzWrQaNyrswdW9AAHR6BkZcA3P/A83vyf0Mkmf17t2b/v37s3fvXqZOncqoUaMoVaoUwcHBJCUlsXnz5gvu36ZNG0aOHEn79u1ZtmwZS5YsAeDQoUOEh4cTERHBrl27GDNmDO3atQOgaNGiHD58+C9dL9q0acOdd97JY489hrWWH3/8kREjRvjkfYtL9m90CqrlP/q0qALIyLR8M3crb4xfzf5jJ+nVMI6B7SpRsWQRr50jRwKDnC52pWpAvZuc56yFlGTAegqlIprASAo8tVNZU4El+Y4xhq61Y+hYozTfzN3KWxPXcv0Hs7iiVmkGd61OpdxuwCu1h4rtYdpr0OBWp4uKSDbUqlWLw4cPExsbS0xMDLfeeitXX301iYmJ1K9fn+rVq19w/4EDB9K3b1/q1q1L/fr1adKkCQD16tWjQYMG1KpVi4oVK9KyZcvT+wwYMIBu3boRExNDUlLS6ecbNmzInXfeefoY/fr1o0GDBuoOmNflYlF1yqz1e3nu1xWs2nmYJglRfH51TWrH5oHfi8ZA8XJupxDxK2qnsmYudDvNDYmJifZi89+LXIqjJ9L5z4yNfDR1PanpmdzUuByDOlahVDEv9uu/mO2LYFhbZxHiDk/k3nnlsqxcuZIaNWq4HSPfyer7aoyZb61NdCnSZcvTbVWWRVUjpxuzj4oqgM37jvLv0SsZt3wXscVD+deVNbiyThn3unCL5HFqq7zPW+2U7mBJvhdeOIj7O1bhlqbxvDNpLSNnb+HHBdvo17oCA9pUpGhIsO9DlK0Pta93ZhVs3A+KZj3YU0TEJ85XVPnwTtUph0+Ps9pEUKDhn1dU465WFQgJ1syqIpI/qcCSAiO6SGGe7Vmbvi0r8Nr41bwzeR0jZ2/h/g6VuaVpeQoF+XjQcYcnnDVYpr4C3d/07blERI7sgUVfuFJUgTPO6tt5W3l9/Gr2HXXGWf3zimq523tARMQF2SqwjDFdgbeBQGC4tfblc15/COgHpAN7gL9Zazd7XrsDONUn6gVr7edeyi5yWRKiw3nvloYMaH2Ql8es4plfV/DJzE08ckU1uteJISDAR91VoipCo77O9L/N/gHRlX1zHvEKa626LnmRv3VHz9dOHHHuls8a6kwXnotF1Sm/r9/H87+tYMWOQySWj+TTO5tQJy4PjLMSyWPUVnmPN9upi16yN8YEAu8B3YCawM3GmJrnbLYQSLTW1gW+A1717BsFPA00BZoATxtjXJjKTeSv6pUrzpf9m/Jp38aEFQrk/q8W0vO9mcxat9d3J2072FlTZfLzvjuH5FhISAj79u1TUeAl1lr27dtHSIjuXPhURhrM+RiG1ocp/3Ym2PnHHOg/GVrclyvF1ZZ9x7h7xHxu/vgPUo6n8e4tDfj27uYqrkR8QG2V93i7ncrOHawmwDpr7QYAY8zXQE9gxVmhks7a/g/g1NLIVwATrLX7PftOALoCX+U8ukjOGWNoX60UbaqU5KeF23hj/GpuGT6btlVL8li36tSIKebdExYp5fyhM/Vl2Db/z+uuiN+Ii4sjOTmZPXv2uB0l3wgJCSEuLs7tGPlTZqYzvmry8876VeVbQu+voFzjXItwODWN95LW88mMjQQFGh7pUpV+rStqnJWID6mt8i5vtlPZKbBiga1nfZ2Mc0fqfO4Cxlxg39hzdzDGDAAGAMTH5073BZGzBQYYrm8Ux1V1Y/jv75t4L2k9Vw6dzrUNYnmoc1XiIsO8d7IW98Lc4TDhabjjV62j4oeCg4OpUKGC2zFELm7DVJj4NGxfCKVqwi3fQpXOufZ7JSPT8t38rbw2bg17j5zg+oZxDO5ajdIaZyXic2qr/Fd2CqysfktneS/SGHMbkAi0vZR9rbXDgGHgTH2bjUwiPhESHMiANpW4KTGe96es49NZm/htyQ7uaF6ef7SvTPGwQjk/SeGiTlfBMYNh/SSo3CnnxxSRgmXHEpj4jPM7JKIcXPMh1L0RAnLvjtHsDft47rcVLN9+iEblI/nPHYnUK1c8184vIuKvslNgJQNnr6wXB2w/dyNjTCfg/4C21toTZ+3b7px9p1xOUJHcFBEWzONX1uD2Fgm8OWENw2ds5Ju5W7mnfWXubJGQ824vjfo6g9AnPAMVO0CAj2cwFJH84cAmmPwiLB0FoZHQ5UVn6Yfg3LtjtHX/MV4as5LRS3cSWzyUd25uQPe6MRpoLyLicdGFho0xQcAaoCOwDZgL3GKtXX7WNg1wJrfoaq1de9bzUcB8oKHnqQVAo1NjsrKSpxdvlHxr1c5DvDJmFUmr91A2IoQnutekW+0cLpC55Fv4oR9cNxzq3uC9sCJ5iBYazqaje2Ha60734oAgaDYQWj4Aobl3x+jIiXTeT1rH8BkbCTSGge0qMaCNxlmJSP52Oe3URS+bW2vTgXuBccBKYJS1drkx5jljTA/PZq8BRYBvjTGLjDG/ePbdDzyPU5TNBZ67UHEl4q+qlynGp32b8FX/ZhQPK8Q9Ixdwx6dz2bj36OUftPb1UKYOTH4O0k9cfHsRuSBjTFdjzGpjzDpjzGNZvF7eGDPJGLPEGDPFGBN31mt3GGPWeh535G7yCzh5FKa+Bm/XhzkfQf1b4P4F0OnpXCuuMjMto+Ztpf3rU3h/ynq6140h6ZF23N+xioorEZEsXPQOVm7THSzxd+kZmYz4YzNvjF/DyfRM7m5XiXvaVbq8PzTWTYIvroOur0Czu70fVsTPeesOlmdJkTVAZ5zu6XOBm621K87a5lvgN2vt58aYDkBfa20fT2+LeThjiC1Oz4tG1toD5zufz9uqjDRY8DlMeQWO7obq3aHjU1Cymu/OmYU5G/fz3G/LWbbtEA3ji/PU1bWor3FWIlKAXE47la2FhkXkjKDAAPq2rMBVdWJ44X8rGTppLT8v2sYzPWrRvlqpSztYpQ5QoQ1Me9W5Mh3i5WnhRQqOiy4pgrOW44Oez5OAnzyf+8+SItY6U65Peh72r4f4FtB7JJRrkqsxtu4/xstjVvG/pTuIiQjh7d716VGvrMZZiYhkg0bWi1ymUsVCGHpzA77s15TAAEPfT+dy94j5bD94PPsHMQY6PQPH9sHv7/oqqkhBkJ1lQRYD13s+vxYoaowpkc19McYMMMbMM8bM88m6Mxunwccd4Ns7Iagw3PwN9B2dq8XV0RPpvDZuFR2HTGXyqt082Kkqkx9uR8/6sSquRESySXewRHKoReVoxjzQmuHTN/LO5LVMG7KHBzpW4W+tKhAcmI1rGLGNoNa1MOtdZzawIpd4F0xEIHvLgjwCvGuMuROYhjNxU3o29/XdkiI7lzpTrq+bCMXi4JoPoO5NuTrlemam5fsFybw6bjV7Dp/g2gaxDO5ajZiI0FzLICKSX6jAEvGCwkGB/KN9ZXrUK8uzv67gpTGr+H5BMs/3rE3TiiUufoAOT8LKX2Hqq3DV674PLJL/XHRJEWvtduA6AGNMEeB6a22KMcadJUUObIakF2HJKAiJgC4vQOP+uTrlOsDcTft57tcVLN2WQv1yxfmoTyMaxkfmagYRkfxEBZaIF5WLCmP4HYlMWLGLZ35Zzk3D/uC6hrE83q0GJYsWPv+OJSpBwztg/qfO9MslKuVeaJH8YS5QxRhTAefOVG/glrM3MMZEA/uttZnA48AnnpfGAf82xpyqKrp4XveNo/tgumfKdRMArQZBy0G5OuU6QPIBZ5zVb0t2UKZYCG/d5IyzCghQV0ARkZxQgSXiA51rlqZV5WjeTVrLsGkbmLhiF//sWp1bmsQTeL4/Xto+Cou/gskvwA2f5m5gt2RmwB/vQ/HyULPHxbcXOQ9rbbox5tSSIoHAJ6eWFAHmWWt/wblL9ZIxxuJ0EfyHZ9/9xphTS4qAr5YUOXnU+f8+cyicPAINboO2j0HEX4Z7+dTRE+l8OHU9w6ZtwBh4oGMV/t62ImGF9CeBiIg3aJp2ER9bt/sIT/28jFnr91E3LoIXrqlN3bjzXKme/AJMew0GTIGyDXIzZu5LTYHv+8PacRAcDvfNg2Jl3U4luaxALDSckQYLR8CUl+HILtemXM/MtPy4cBuvjlvFrkMn6Fm/LI92rU7Z4hpnJSJyPj5ZaFhEcqZyqSKM7NeUt3vXZ0dKKj3fm8mTPy0j5VjaXzducT+ERjkD3vOzfetheCdYP8m5gp+ZDhOedjuViHdZC8t/gvebwW8PQmQF+Nt4Z9r1XC6u5m/ez7Xvz+ThbxdTJiKU7we24O3eDVRciYj4gPoDiOQCYww968fSvnophoxfw39/38SYZTt4vFsNrmt41vTHIcWgzT9h3OOwfrKzTlZ+s24SfNcXTCD0+QkqtHYKrOmvQ+O7IL6Z2wlFcm7jdJj4NGybDyWrw81fQ9WuztIMuWjbweO8PGYVvy7eTpliIbx5Uz161ovVOCsRER9SF0ERFyzblsKTPy9j4ZaDNKkQxQvX1KZq6aLOi+kn4J1ECIuE/lMgIJ/caLbWGX8y/gkoWQNu/hIiE5zXTh513nORktA/KVenpxZ35bsugjuXeaZcnwDFYqH9v6Deza78n05avZu7R8wH4O9tK3G3xlmJiFwydREUySNqx0bw/d0tePm6OqzZdZgr357OS6NXcvREurPAaIcnYMdiWP6D21G9Iy0VfroHxv0Lql0Jd40/U1wBFAqHLs8773nhF67FFLlsBzbDD3+HD1tB8hzo/BzcN9+ZyMKF4iotI5Nnf1lOuagwJj/Sjoc6V1VxJSKSS1RgibgkIMDQu0k8kx9ux/UN4/ho2gY6DZnK2GU7sHV6QenaMPl5SD/pdtScObwTPrsKFn/pjLe6cQQULvLX7WpfD/HNYdKzcPxg7ucUuRxH98HYf8G7ibDiJ2j5ADyw2PkY7N74pm/nJbNp3zEe71adWI2zEhHJVSqwRFwWFV6IV3rV5fuBzYkIDebuLxbQ9/P57GryGBzYBAs+dzvi5ds2H4a1g90r4Mb/QvvHz9/l0Rjo9iocP+DMtibiz2wmTHsdhtaH2R9A3ZvgvgXQ+VkIdXeR3uMnM3h70hoSy0fSoXopV7OIiBREKrBE/ESj8lH8dl8rnuxek7kb99P6x0C2RjTCTn0FThx2O96lWzIKPukGAcFOl8CaPS++T0xdZ8HlOcNg9yrfZxS5XLtXOHeYE1rDwN+h57u5vp7V+Xz++yZ2HTrB4K7Vz0ygIyIiuUYFlogfCQoM4K5WFZj0cDu61CzDfbt7Yo7uYdNvr7odLfsyM2DCU/BDf4hrDAOSoEyd7O/f4UmnC+GYwc7EGCL+KLAQ/G2cM1lLqepupzkt5Vga7yeto321kjSpEOV2HBGRAkkFlogfKhMRwru3NOThv93C1MDmRC8ZxqOfT2JHynG3o11Yagp81Rtmvg2Jd8HtP0F49KUdI7wEtP8/2DgVVv3mm5wiORVd1S+XFPho2noOpabzzyv8p+gTESloVGCJ+LHWVUrSfMBbhJk0aq0fRqc3pjJ8+gbSMjLdjvZXe9fBxx2d9buuGgLdh0Bg8OUdK/EuZyr3cf+CND8vKkX8xO5DqXwycyM965elZtlibscRESmwVGCJ+LlCpasT0KgPfYIm0b3cCV7430qufmcGczftdzvaGesmwscd4Ph+uP1nZ8HgnAgMgm6vwMEtMOtd72QUyeeGTl5Leobloc5V3Y4iIlKgqcASyQvaPoYJCOLlqF8Z1qcRh1PTueHD33nk28XsO3LCvVzWwqx3YOQNULycs0hwQivvHLtiW6jRA6a/ASnJ3jmmSD61ed9Rvp6zlZubxFO+RLjbcURECjQVWCJ5QbEYaH4PZum3dInaxYSH2jCwXSV+WriNDm9MZeTszWRm5vKEEGmp8OPdMP4JqN7dGfAfWd675+jyAmCdSTNE5LyGTFhDcGAA93Wo7HYUEZECTwWWSF7R8gFnfZ2JzxJWKIhHu1ZnzAOtqRFTlP/7cRnXfjCLZdtScifLoR3w2ZWw5Gto9y+44fOsFw/Oqcjy0HIQLPseNs30/vFF8oHl21P4edF2+rZMoFSxELfjiIgUeCqwRPKKkAho/QisnwQbpgBQpXRRvurfjLduqs+2A8fp8e4Mnv55GSnH03yXI/nU4sGr4KYvoN2j51882BtaPgDF4mDMo84U8CLyJ6+PW01EaDB/b1vJ7SgiIoIKLJG8pXE/iCgHE585vUaUMYZrGsQy6eG29GlWnhF/bKbjG1P5aeE2rLfXkVr8NXzaDYIKQb8JUONq7x4/K4XC4IoXYNdSmP+Z788nkofM3rCPpNV7GNiuEhGhlzlrp4iIeJUKLJG8JDgE2v8Lti+EFT/96aWI0GCe7VmbX+5tRWxkKIO+WcRt/5nN5n1Hc37ezAxnrNWPf4dyTaD/FChdK+fHza6a10D5VjD5eTjmR7MnirjIWsur41ZTulhh7mie4HYcERHxUIElktfUvQlK1YRJz0HGX7sC1o6N4MeBLXj+mtos2ZpClzen8cGU9Ze/dtbxg/Dljc5sgY37QZ8fncWAc5MxzrTtqSkw5aXcPbeIn5q0cjfzNx/ggY5VCS0U6HYcERHxUIElktcEBELHp2H/BljwedabBBj6NCvPhIfa0q5aSV4Zu4qe785kafIlToKxdy0M7+iM+er+Flz1xuUvHpxTZWo7CxDPHQ67lruTQcRPZGRaXhu3mgrR4dyQGOd2HBEROYsKLJG8qOoVEN8CprwCJ46cd7MyESF81CeRD29ryN4jJ+j53gxe+G0Fx06mX/wcayfAxx3h+AG4/RdI7OvFN3CZ2v/LmexjzKOnx6CJFES/LN7G6l2HebhLVYID1ZSLiPgT/VYWyYuMgc7PwtHd8McHF928a+0YJjzUlt5N4hk+YyNd3pzG1DV7st7YWpj5ttMtsHg8DJgCCS29Gv+yhUVBhydg03RY8bPbaURccTI9kzfGr6FW2WJcWTvG7TgiInIOFVgieVW5Js4CvzPfhqN7L7p5RGgw/762DqP+3pzCQQHc8ckcBn29kH1HTpzZKO24M5HFhKecGQLvGucUWf6kUV8oXceZdOPkMbfTiOS6r+ZsIfnAcQZ3rU5AgHE7joiInEMFlkhe1vEpSDsK09/I9i5NKkQx+oHW3N+xCv9buoNOQ6by/fxkbMo2+PRKWPINtP8/Z/HgQuE+DH+ZAgKdCS9StsKsoW6nEclVR0+k887ktTSrGEWbKtFuxxERkSyowBLJy0pWgwa3wZyP4cCmbO9WOCiQhzpX5X/3t6ZCdDgjvvueg2+3InPParhpJLQd7HRD9FcJLaHWdTDjTTi4xe00Irnmkxkb2XvkJIO7Vsf488+oiEgBlq0CyxjT1Riz2hizzhjzWBavtzHGLDDGpBtjep3zWoYxZpHn8Yu3gouIR7vHnbs6Sf++5F2rli7Kd803833oCxzJCKJn6jMM21OD9Mud0j03dXkeME5XQZEC4MDRkwybtoEuNUvTMD7S7TgiInIeFy2wjDGBwHtAN6AmcLMxpuY5m20B7gS+zOIQx6219T2PHjnMKyLnKlYWmt4NS0bBzqXZ3y8jHcb9HwE/DyQwvinBA6dQunJD/j16Fde8P5Nl2y5xSvfcFhEHrR9yJrvYOM3tNCI+98HU9Rw9mc4jV1RzO4qIiFxAdu5gNQHWWWs3WGtPAl8DPc/ewFq7yVq7BMgDl71F8qFWg5zpyyc+m73tjx9wZgn8/V1oMgD6/EiZMrF8fHsj3r+1IbsOnaDnezP59+iVHD+Z4dvsOdHiPmcSjjGPOgWjSD61I+U4n83axHUN46hauqjbcURE5AKyU2DFAlvP+jrZ81x2hRhj5hlj/jDGXHNJ6UQke0Ijnbs56ybAxukX3nbPGmd9q43T4Oq34crXTi8ebIzhyjoxTHywLTcmxjndkd6ayvS155nS3W3BodDlRdi9AuZ94nYaEZ95e+JasDCoUxW3o4iIyEVkp8DKahTtpazwGW+tTQRuAd4yxlT6ywmMGeApwubt2eOnf8iJ+LsmA6BYLEx8+vyL8K4ZD8M7QmoK3PErNLozy80iwoJ56bq6fD2gGcEBAfT5zxwe+mYR+4+e9F3+y1XjaqjQFpJehKP73E4jLsrGeOF4Y0ySMWahMWaJMeZKz/PBxpjPjTFLjTErjTGP537681u3+wij5m3l1mbxxEWGuR1HREQuIjsFVjJQ7qyv44Dt2T2BtXa75+MGYArQIItthllrE621iSVLlszuoUXkbMGh0P5fsG0+rDxnPhlrYcZbTrfAyPLO4sHlm1/0kM0qlmD0A625r0Nlflm8nU5DpvLTwm3Y8xVwbjDGmbb9xGFIesHtNOKSbI4XfgIYZa1tAPQG3vc8fwNQ2FpbB2gE/N0Yk5AbubNjyITVhAYH8o/2ld2OIiIi2ZCdAmsuUMUYU8EYUwinUcrWbIDGgjvJMwAAHLZJREFUmEhjTGHP59FAS2DF5YYVkYuodzOUrA6TnjszJintOPzQ37mzVbMn/G0cFC934eOcJSQ4kIe7VOO3+1sRHxXGoG8Wccenc9m6348W+S1VA5r0h3mfwo4lbqcRd1x0vDBO74tins8jOHOx0ALhxpggIBQ4CRzyfeSLW7z1IKOX7qRf64pEFynsdhwREcmGixZY1tp04F5gHLAS5+rfcmPMc8aYHgDGmMbGmGScq4AfGWOWe3avAcwzxiwGkoCXrbUqsER8JSAQOj4N+9bBwhGQsg0+7QZLv4UOT8ANn1324sHVyxTj+4EteObqmszftJ8ub05j+PQN/jOle7vHICzKmfDCn+6wSW7JznjhZ4DbPO3VaOA+z/PfAUeBHTiz4r5urd3v07TZ9Nq41USFF6Jf6wpuRxERkWwKys5G1trROI3R2c89ddbnc3G6Dp673yygTg4zisilqNYNyjVzxiRNeQlOHoXeX0L1q3J86MAAw50tK9ClVhme/GkZL/xvJT8v2s7L19ehVtkIL4TPgdBI6PgU/PoALPse6vS6+D6Sn2RnvPDNwGfW2jeMMc2BEcaY2jh3vzKAskAkMN0YM9HTtf3MCYwZAAwAiI+P93b+v5i5bi8z1u3lye41KRoS7PPziYiId2RroWERyUOMgc7PwtE9zrisfhO9UlydrWzxUIbfkci7tzRgR0oqPd6dyUtj/GBK9wZ9oExdmPCUU1hKQZKd8cJ3AaMArLW/AyFANM4kTGOttWnW2t3ATCDx3BPk5nhhay2vjl1FbPFQbm3q+2JORES8RwWWSH4U3wz+Nt6ZzKJUDZ+cwhhD97plmfRQW3o1jOOjqRvo+vY0Zq7b65PzZUtAoDPt/KFtMONN93KIG7IzXngL0BHAGFMDp8Da43m+g3GEA82AVbmWPAvjlu9kcXIKgzpVISQ40M0oIiJyiVRgieRX8U2dbnM+FhEWzCu96vJl/6YY4Nbhs3l41GIOuDWle3wzqHMDzBwK+ze6k0FyXXbGCwMPA/0944K/Au60zpSY7wFFgGU4hdqn1lrXZktJz8jktXGrqVyqCNc1/EvvexER8XPZGoMlInIxLSpFM3ZQG4ZOWsuwaRuYsno3T11dkx71ymJMVsNjfKjzc7BqNIx/AnqPzN1zi2uyMV54Bc5stufudwRnkia/8MOCbazfc5QPb2tEYEAu/+yIiEiO6Q6WiHhNSHAgg7tW59f7WhEXGcoDXy+i72dzST6Qy1O6FysLbR6GVb/B+sm5e26RHEhNy+DNiWuoV644V9Qq7XYcERG5DCqwRMTrasQU44d7WvJU95rM2ehM6f6fGRvJyMzF6dOb/QMiE2DMY5CRlnvnFcmBL/7YzI6UVB7tWi337/yKiIhXqMASEZ8IDDD8rVUFxj/YhqYVonj+txVc9/5MVmzPpfVbg0Pgipdg72qYOzx3zimSA4dT03gvaR2tq0TTolK023FEROQyqcASEZ+Kiwzjkzsb83bv+iQfOE6Pd2fwythVpKblwpTu1bpBpY6Q9BIc2eP784nkwMfTN3LgWBqDr6judhQREckBFVgi4nPGGHrWj2XiQ225pkEsH0xZT9e3pjHL11O6GwNdX4a0ozD5Od+eSyQH9h45wfDpG7iqbgx14lxetFtERHJEBZaI5JrI8EK8fkM9RvZrigVuGT6bf37r4yndS1aFpnfDghGwfaHvziOSA+9OXseJ9Ewe7lzV7SgiIpJDKrBEJNe1rBzNuEFtuLttJX5YuI02rybx2rhV7PdVodV2MIRHw5hHwebiRBsi2bB1/zFGzt7MjYlxVCxZxO04IiKSQyqwRMQVIcGBPNatOqPvb02bqiV5f8p6Wr0ymX+PXsnuw6lePlkEdHwats6Gpd9699giOfTmxDUEGMP9Hau4HUVERLxABZaIuKpamaK8d2tDJjzYhitqlWH49A20fiWJZ35Zzo6U4947Uf1boWwDGP8knDjsveOK5MDqnYf5ceE27myRQExEqNtxRETEC1RgiYhfqFyqKG/eVJ/JD7ejZ/2yfPHHZtq8msTjPyxl634vLFQcEADdXoMjO2H6Gzk/nogXvD5+NUUKBzGwXSW3o4iIiJeowBIRv5IQHc6rveqR9Eg7bkwsx/fzk2n3+hQe+XYxG/cezdnByzWGejfD7+/BvvXeCSxymeZvPsCEFbu4u20liocVcjuOiIh4iQosEfFL5aLCePHaOkwb3J7bm5fn18Xb6fjGFB74eiFrd+Wgi1+nZyCwEIz7P29FFblk1lpeGbuK6CKF6dsywe04IiLiRSqwRMSvlYkI4emrazHj0Q70b12RCSt20eWtaQz8Yj7Lt6dc+gGLloE2/4Q1Y2DtRO8HFsmGqWv2MGfjfu7vWJmwQkFuxxERES9SgSUieULJooV5/MoazHy0A/e2r8yMtXu5augM+n0+l0VbD17awZoNhKhKMPYxSPfhGlwiWcjMtLw6djXlokLp3Tje7TgiIuJlKrBEJE+JDC/Ew12qMeOxDjzUuSrzNh/gmvdm0uc/s5m7aX/2DhJUGLq+BPvWwpyPfBtY5By/Ld3Bih2HeLhzNQoFqRkWEclv9JtdRPKkiNBg7u9YhRmPduCxbtVZsf0QN3z4O72H/c6sdXuxF1tQuOoVUKULTHkFDu/KndBS4KVlZPLG+NVUL1OUHvXKuh1HRER8QAWWiORpRQoHcXfbSsx4tANPdq/Jhj1HuWX4bHp9+DtJq3dfuNC64iVIT4VJz+VeYCnQRs3byuZ9xxjctRoBAcbtOCIi4gMqsEQkXwgtFMhdrSowbXB7nr+mNjtTUun76Vx6vjeT8ct3kpmZRaEVXdkZj7XoC0ien/uhpUA5fjKDtyeupXFCJO2rlXI7joiI+IgKLBHJV0KCA+nTrDxJj7TjlevrcPBYGgNGzOfKodP5bcl2Ms4ttNr8E4qUhjGDITPTndBSIHw2axO7D59gcNfqGKO7VyIi+ZUKLBHJlwoFBXBT43gmP9yWITfW42RGJvd+uZAub07lx4XJpGd4iqmQYtDpWdg2D5Z87W5oybdSjqXxwZR1dKheisYJUW7HERERH1KBJSL5WlBgANc1jGPCg21595YGBAcG8OA3i+k4ZCrfzN3CyfRMqHsTxCbChKch9ZDbkSUf+nDaeg6fSOefV1RzO4qIiPiYCiwRKRACAwzd65Zl9P2t+ahPI4qFBPPo90tp//oURszZyokuL8PR3TDtNbejSj6z61Aqn87cSM96ZakRU8ztOCIi4mMqsESkQAkIMFxRqwy/3NuST/s2pnSxwjz50zLajExhddlrsH98AHvXuh1T8pGhk9aSnmF5qLPuXomIFAQqsESkQDLG0L5aKb4f2IKR/ZqSUCKcWzdcwdHMYLZ8+QBHTqS7HVHygU17j/LN3K3c0jSe+BJhbscREZFcEOR2ABERNxljaFk5mpaVo5mzsRo//7yQW/cP476XX6Nqq17c3iKBiNBgt2NKHjVkwhqCAwO4t0Nlt6OIiEgu0R0sERGPJhWiuPXeF0mNqMgTgSN4Z8JyWr08mTfGr+bA0ZNux5M8Zvn2FH5ZvJ27WlWgVNEQt+OIiEguUYElInK2oEKEdH+N0unbmNZmFa2qRPPO5HW0fGUyT/60jJ8XbWPT3qNYm8XCxSJneW3caoqHBTOgbUW3o4iISC5SF0ERkXNV6QTVrqTMonf44N47WNO5Ku9OXseoeVsZ8cdmACJCg6kbF+F5FKdeXHHKROguhTj+2LCPKav38Hi36hQLURdTEZGCJFsFljGmK/A2EAgMt9a+fM7rbYC3gLpAb2vtd2e9dgfwhOfLF6y1n3sjuIiIT13xIrzXFCY+Q9XrPmLozQ1Iy8hkza7DLElOYUnyQRZvTeHDqRvIyHTuZpUqWvh0wVU3LoJ6ccWJDC/k8huR3Gat5dWxqyhdrDB3tEhwO46IiOSyixZYxphA4D2gM5AMzDXG/GKtXXHWZluAO4FHztk3CngaSAQsMN+z7wHvxBcR8ZGoitD8XpgxBBrfBeWaEBwYQK2yEdQqG8HNTeIBSE3LYPn2QyxJPsiS5BQWJx9k4srdpw9TLirUc4fLKbzqxEYQXlidB3whGxcD44HPgeKebR6z1o72vFYX+AgoBmQCja21qZeTY+LK3SzYcpCXrqtDSHDgZb8fERHJm7LTyjcB1llrNwAYY74GegKnCyxr7SbPa5nn7HsFMMFau9/z+gSgK/BVjpOLiPha64dh8Vcw+p/QPwkC/jpsNSQ4kEblI2lUPvL0c4dS01iWnMJiz52uRVsO8r8lOwAwBiqXLOIUXeWcoqtGTFEKB+kP8ZzI5sXAJ4BR1toPjDE1gdFAgjEmCPgC6GOtXWyMKQGkXU6OjEzL6+NWUzE6nBsaxeXoPYmISN6UnQIrFth61tfJQNNsHj+rfWPP3cgYMwAYABAfH5/NQ4uI+FjhItD5OfihPyz6Ahrenq3dioUE06JyNC0qR59+bu+RE6e7FS5JPsiU1bv5fkEyAMGBhuplip3uVli3XARVShUlMMD45G3lUxe9GIjTk6KY5/MIYLvn8y7AEmvtYgBr7b7LDfHzom2s3nWY925pSFCg5pESESmIslNgZdXCZ3f6rGzta60dBgwDSExM1NRcIuI/6twAc4fDxGehRg8ILX5Zh4kuUpgO1UvToXppwBmns+3g8dPdCpdsTeGXRdsZOXsLAKHBgdSOLfan8VzlS4RhzFm/VjMzITMdMtM8HzMgIw0CgiC8RI7feh6TnYuBzwDjjTH3AeFAJ8/zVQFrjBkHlAS+tta+eu4JLnYx8ER6BkMmrKFObATdapfJ2bsREZE8KzsFVjJQ7qyv4zhz1S87+7Y7Z98p2dxXRMR9xkC3V2FYO/j1AUho5RQyWRU2mel/fWSc/XXa6W1NZjpxnseVmelg0rExaZxMS+PEiROkpZ0kfXcamTvSCJqbQSAZHDaZFDYZBJJJoE3HXOhaV/F4KN8KyrdwHlEVnfeSf2Xngt7NwGfW2jeMMc2BEcaY2jhtYSugMXAMmGSMmW+tnfSng13kYuBXs7eQfOA4L11XhwDdfRQRKbCyU2DNBaoYYyoA24DewC3ZPP444N/GmFODE7oAj19yShERN5WtD03vhtkfwIqfst7GBDh3jgKCPR8DIfCsz08/HwSBQWc+DwiGoBAICMIEBlM4IIjCZ22fGRDEwdRM9h7LYM+xTHYeTmfPsQxO2gAybCAhhQtRMqIIpYuHExNVlJjIooSbE5A8B9aOg8VfOvmKlHEKrYSWUL4lRFfLckxZHpadi4F34YwDxlr7uzEmBIj27DvVWrsXwBgzGmgITCKbjpxI553J62hesQStzuoaKiIiBc9FCyxrbbox5l6cYikQ+MRau9wY8xwwz1r7izGmMfAjEAlcbYx51lpby1q73xjzPE6RBvDcqQkvRETylG4vQ6tBZxVS5z58U6wEAFGeR1XPc+fOXPht8kE2rDx6ep/yJcJoGN+Ghq2L0yJiHxWOLCJgyyzYPBOW/+BsFBp15u5W+ZZQpo5TCOZd2bkYuAXoCHxmjKkBhAB7cNq3wcaYMOAk0BZ481JO/smMjew7epLBXav9uRuniIgUOMZa/xrylJiYaOfNm+d2DBGRPOXsmQsXbz3I/C0H2HP4BABFCgfRIL44DcsVp1X0EWqnLyd0+2zYPAMObHIOULgYlGt6puAq2wCCfL+Gl6crXqKXjnUlzpqMpy4GvnjOxcCawMdAEZzug4OtteM9+96G08PCAqOttYMvdK6z26r9R0/S5tUkWlYuwUd9vPJWRETET1xOO6UCS0QkH7LWknzgOPM3H2De5v3M33yQ1TsPkWmdoVjVShclMSGSlqVO0NispsTeeZgts2DPKucAQaFQrrFTbJVvAbGJUCjM6zm9WWDlprPbqhf/t4L/zNjIuEFtqFK6qMvJRETEmy6nndJqlyIi+ZAxhnJRYZSLCuOaBs7qGIdT01i09SDzNx9g/uYD/LRwO1+cSAeKU7LoVTSKv42W1SwtC60l/shCgrb8DlNeBqwzJiy2oafgagnlmkBIsQtmKAi2HzzO579v5vqGcSquREQEUIElIlJgFA0JpnWVkrSuUhJwFsVds+vw6YJr/uYDjF1+DChGoaD21I29hhYNg2gXtpHqJ5YQtmM2zBoKM4Y4Y9HK1HVmVSzfAuKbQ1iUu2/QBW9PXAsWBnWuevGNRUSkQFCBJSJSQAUGGGrEFKNGTDFua1YegN2HU1mw+SDzN+9n/uYDfDh7H0MzigAtSCjRieZVQ+lUdAv1MpdTYu9czJyP4fd3nQOWqvnniTOK5u+1oNbtPsK387fSt2UFYouHuh1HRET8hAosERE5rVTRELrWLkNXz0K5qWkZLNuWcvoO1/i1B/jqaDjQhKIhLWhSLpyukTtoErCS2JSFBC3+2lmYGSCq0pliK6GlszZXPvLG+NWEBgdyT7tKbkcRERE/ogJLRETOKyQ4kMSEKBITnO5/1lo27zvmmTzjAAs2H2DwujCsbUSAaUStMg9wVcIeWgWvptLxJYSs/BWzcIRzsIhyf77DVaKyi+8sZ46fzGDMsp0M6lSFEkUKux1HRET8iAosERHJNmMMCdHhJESHc32jOABSjqexcItTbM3fcoChq4ry8skGQAPKFO1H9/gUOoSuo8bJpRRfn4RZ8o1zsPBS7r2RHNp5KJXy4YXo17qi21FERMTPqMASEZEciQgNpl21UrSr5hRM6RmZrNp5mAVbnG6FYzYFMfxgGFCXwkG30TXmKF2LbqB+xjJgnavZL9eRE+nc274yRQqrGRURkT9TyyAiIl4VFBhA7dgIasdGcHvzBAB2pqSyYMsB5m1y7nLdtyqc9MzawBeuZr1cwYEB3Nosf40pExER71CBJSIiPlcmIoQr68RwZZ0YwJk8Y/HWgzR7xeVglyk+KpTCQYFuxxARET8U4HYAEREpeEKCA2lasYTbMS5bWCFdnxQRkaypwBIREREREfESFVgiIiIiIiJeogJLRERERETES1RgiYiIiIiIeIkKLBERERERES9RgSUiIiIiIuIlKrBERERERES8RAWWiIiIiIiIl6jAEhERERER8RJjrXU7w58YYw4Dq93OkU3RwF63Q2SDcnpXXskJeSercnpXXskJUM1aW9TtEJcqD7VVeen/Ql7JqpzelVdyQt7JqpzedcntVJCvkuTAamttotshssMYMy8vZFVO78orOSHvZFVO78orOcHJ6naGy5Qn2qq89n8hL2RVTu/KKzkh72RVTu+6nHZKXQRFRERERES8RAWWiIiIiIiIl/hjgTXM7QCXIK9kVU7vyis5Ie9kVU7vyis5IW9lPVteyZ1XckLeyaqc3pVXckLeyaqc3nXJOf1ukgsREREREZG8yh/vYImIiIiIiORJflNgGWM+McbsNsYsczvLhRhjyhljkowxK40xy40xD7id6XyMMSHGmDnGmMWerM+6nelCjDGBxpiFxpjf3M5yPsaYTcaYpcaYRf48+5kxprgx5jtjzCrP/9XmbmfKijGmmud7eepxyBgzyO1cWTHGPOj5OVpmjPnKGBPidqasGGMe8GRc7m/fy6x+zxtjoowxE4wxaz0fI93MeDFqq7xL7ZRvqK3yHrVT3lcQ2im/KbCAz4CubofIhnTgYWttDaAZ8A9jTE2XM53PCaCDtbYeUB/oaoxp5nKmC3kAWOl2iGxob62t7+dTi74NjLXWVgfq4affV2vtas/3sj7QCDgG/OhyrL8wxsQC9wOJ1traQCDQ291Uf2WMqQ30B5rg/Lt3N8ZUcTfVn3zGX3/PPwZMstZWASZ5vvZnn6G2ypvUTvmO2iovUDvlXQWlnfKbAstaOw3Y73aOi7HW7rDWLvB8fhjnl0Gsu6myZh1HPF8Gex5+OejOGBMHXAUMdztLXmeMKQa0Af4DYK09aa096G6qbOkIrLfWbnY7yHkEAaHGmCAgDNjucp6s1AD+sNYes9amA1OBa13OdNp5fs/3BD73fP45cE2uhrpEaqu8S+1UwZVH2yq1UzlXINopvymw8iJjTALQAJjtbpLz83RnWATsBiZYa/0161vAYCDT7SAXYYHxxpj5xpgBboc5j4rAHuBTT1eW4caYcLdDZUNv4Cu3Q2TFWrsNeB3YAuwAUqy1491NlaVlQBtjTAljTBhwJVDO5UwXU9pauwOcogAo5XKefMff2yq1Uz6htso31E7lXIFop1RgXSZjTBHge2CQtfaQ23nOx1qb4bmtHQc08dya9SvGmO7AbmvtfLezZENLa21DoBtOl5s2bgfKQhDQEPjAWtsAOIqfd7syxhQCegDfup0lK57+1j2BCkBZINwYc5u7qf7KWrsSeAWYAIwFFuN0FZMCKi+0VWqnfEJtlZepnfKOgtJOqcC6DMaYYJwGa6S19ge382SH57b7FPxz7EBLoIcxZhPwNdDBGPOFu5GyZq3d7vm4G6cPdhN3E2UpGUg+6yrwdziNmD/rBiyw1u5yO8h5dAI2Wmv3WGvTgB+AFi5nypK19j/W2obW2jY43RzWup3pInYZY2IAPB93u5wn38hrbZXaKe9RW+UTaqe8pCC0UyqwLpExxuD0F15prR3idp4LMcaUNMYU93weivPDt8rdVH9lrX3cWhtnrU3Auf0+2Vrrd1ddjDHhxpiipz4HuuDc6vYr1tqdwFZjTDXPUx2BFS5Gyo6b8dNuFx5bgGbGmDDP74CO+OFgbABjTCnPx3jgOvz7+wrwC3CH5/M7gJ9dzJJv5JW2Su2U96mt8hm1U15SENqpIJ/GuQTGmK+AdkC0MSYZeNpa+x93U2WpJdAHWOrpMw7wL2vtaBcznU8M8LkxJhCnmB5lrfXrqWX9XGngR+f3FkHAl9base5GOq/7gJGeLg0bgL4u5zkvTx/szsDf3c5yPtba2caY74AFOF0ZFuK/K9B/b4wpAaQB/7DWHnA70ClZ/Z4HXgZGGWPuwvkD4Qb3El6c2iqvUzvlfWqrvEztlNfl+3bKWOuXk/WIiIiIiIjkOeoiKCIiIiIi4iUqsERERERERLxEBZaIiIiIiIiXqMASERERERHxEhVYIiIiIiIiXqICSySPMMa0M8Zo+mIREfFbaqtEVGCJiIiIiIh4jQosES8zxtxmjJljjFlkjPnIGBNojDlijHnDGLPAGDPJGFPSs219Y8wfxpglxpgfjTGRnucrG2MmGmMWe/ap5Dl8EWPMd8aYVcaYkZ7V2kVERC6J2ioR31GBJeJFxpgawE1AS2ttfSADuBUIBxZYaxsCU3FWBgf4L/CotbYusPSs50cC71lr6wEtgB2e5xsAg4CaQEWgpc/flIiI5Ctqq0R8K8jtACL5TEegETDXc8EuFNgNZALfeLb5AvjBGBMBFLfWTvU8/znwrTGmKBBrrf0RwFqbCuA53hxrbbLn60VAAjDD929LRETyEbVVIj6kAkvEuwzwubX28T89acyT52xnL3KM8zlx1ucZ6GdYREQundoqER9SF0ER75oE9DLGlAIwxkQZY8rj/Kz18mxzCzDDWpsCHDDGtPY83weYaq09BCQbY67xHKOwMSYsV9+FiIjkZ2qrRHxIVxREvMhau8IY8wQw3hgTAKQB/wCOArWMMfOB/2/Xjm0QimEggJ571qNEiFWYApZjByR6U/y0UBmQ0HtliiiprNP5nm33PUmOSS5rKN2SnNb5Icm1qs7rjv0XvwHAHzOr4LOq+137C0yoqkd37379DgB4xayCGVYEAQAAhmiwAAAAhmiwAAAAhghYAAAAQwQsAACAIQIWAADAEAELAABgiIAFAAAw5AkoDblwMGsEawAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.fit(X_train, y_train, validation_data=[X_test, y_test], \n", " batch_size=128, epochs=10, verbose=1,\n", " callbacks=[PlotLossesKeras()])" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.9731060606060606\n" ] } ], "source": [ "y_pred = model.predict_classes(X_test)[:,0]\n", "\n", "print((y_pred == y_test).mean())" ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 2 }