{ "cells": [ { "cell_type": "markdown", "source": [ "## Introduction to Modeling" ], "metadata": { "id": "gIPdySTgL9k7" } }, { "cell_type": "markdown", "source": [ "\n", "\n", "---\n", "\n" ], "metadata": { "id": "eeMKpX2jMDqM" } }, { "cell_type": "markdown", "source": [ "### Demonstrate idea behind MSE" ], "metadata": { "id": "6uZyaJdzL61x" } }, { "cell_type": "markdown", "source": [ "Complete below" ], "metadata": { "id": "RM5qknxdMU8T" } }, { "cell_type": "code", "source": [], "metadata": { "id": "i-e56REtMXSd" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "\n", "\n", "---\n", "\n" ], "metadata": { "id": "OLNuc4ZfMEwG" } }, { "cell_type": "markdown", "metadata": { "id": "BruPxyad0fWj" }, "source": [ "### Linear regression" ] }, { "cell_type": "markdown", "metadata": { "id": "tObKDZrP0fWk" }, "source": [ "**Simple Example with Simulated Data**\n", "\n", "For this example, we are going to keep it simple, stay in 2 dimensions, and use OLS to fit a line to some data." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Tmxldb2C0fWk" }, "outputs": [], "source": [ "import numpy as np\n", "%matplotlib inline\n", "# this accommodates high resolution displays\n", "%config InlineBackend.figure_format = 'retina'\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "tzo-Y8-C0fWl" }, "outputs": [], "source": [ "n = 10\n", "np.random.seed(146)\n", "x = np.random.normal(size=(n,1))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Rixag8Kr0fWl", "collapsed": true }, "outputs": [], "source": [ "noise_strength = 0.5\n", "np.random.seed(147)\n", "noise = np.random.normal(scale=noise_strength, size=(n,1))\n", "y = 1 + 2*x + noise\n", "plt.scatter(x,y, label='Original data', color='k')\n", "plt.xlabel('x')\n", "plt.ylabel('y')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "zfkOmO1v0fWl" }, "outputs": [], "source": [ "from sklearn.linear_model import LinearRegression as LR\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [], "id": "r2FlKS5w0fWl", "outputId": "b74fc26d-5825-4cb5-a5a5-e2981d7de01f", "colab": { "base_uri": "https://localhost:8080/", "height": 78 } }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "LinearRegression()" ], "text/html": [ "
LinearRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ] }, "metadata": {}, "execution_count": 17 } ], "source": [ "lin_reg = LR()\n", "lin_reg.fit(x,y)" ] }, { "cell_type": "code", "source": [ "np.shape(lin_reg.coef_)\n", "print(lin_reg.coef_)" ], "metadata": { "id": "wuYxG8pnAJgu" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "MBNgMrAU0fWm" }, "outputs": [], "source": [ "print('Model coefficient: ', lin_reg.coef_[0][0])\n", "print('Model intercept: ', lin_reg.intercept_[0])\n", "#y = 1.17 + 2.20x" ] }, { "cell_type": "code", "source": [], "metadata": { "id": "3I0cNfP-cvBX" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [], "id": "27KLyRGK0fWm" }, "outputs": [], "source": [ "x" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "gaU9JsPR0fWm" }, "outputs": [], "source": [ "y_pred = lin_reg.predict(x)\n", "y_pred" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "A6fd5KrP0fWm" }, "outputs": [], "source": [ "#What do you notice?\n", "for i in range(len(y)):\n", " print(y[i], y_pred[i])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "b7DDODQq0fWm" }, "outputs": [], "source": [ "x_range = [min(x), max(x)]\n", "y_pred = lin_reg.predict(x_range)\n", "\n", "plt.figure(figsize = (10,6))\n", "plt.scatter(x,y, label='Original data', color='k')\n", "plt.plot(x_range, y_pred, label='Model', color='r')\n", "plt.legend()\n", "plt.xlabel('x')\n", "plt.ylabel('y')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "fNXDdxGL0fWm" }, "source": [ "We can use the model to make predictions for new x values:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "4OvhmoXb0fWm" }, "outputs": [], "source": [ "np.random.seed(201)\n", "new_x = np.random.normal(size=(20,1))\n", "y_pred = lin_reg.predict(new_x)\n", "\n", "plt.scatter(x,y, label='Original data', color='k')\n", "plt.scatter(new_x, y_pred, label='Predicted values', color='r')\n", "plt.title('Our randomly generated data')\n", "plt.xlabel('x')\n", "plt.ylabel('y')\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "E7PehEyR0fWm" }, "source": [ "Why did the model pick the line that it did? The goal was to minimize the sum of the squared errors between the model and the data. Let's plot the errors:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "_3fEpRcf0fWn" }, "outputs": [], "source": [ "def VizSquaredErrors(x,y,model):\n", " # Function will plot x and y, show the best fit line as well as the squared errors, and return the raw error terms\n", "\n", " # Fit the model and plot the data\n", " model.fit(x,y)\n", " yp = model.predict(x)\n", " errors = abs(y - yp)\n", " plt.scatter(x,y,color='black',label='Actual Data')\n", "\n", " # Compute a range of x values to plot the model as a continuous line\n", " x_rng = np.linspace(min(x),max(x),20)\n", " y_pred = model.predict(x_rng)\n", " plt.plot(x_rng,y_pred,color='red',label='Fitted Model')\n", "\n", " # Draw squares at each data point indicating the squared error\n", " ax = plt.gca() #get current axis\n", " for i,xi in enumerate(x):\n", " r = plt.Rectangle((xi, min(y[i],yp[i])),width=errors[i],height=errors[i],facecolor='blue',fill=True,alpha=0.1)\n", " ax.add_patch(r) #in this case a square\n", " plt.axis('equal')\n", " plt.xlabel('$x$')\n", " plt.ylabel('$y$')\n", " plt.legend()\n", " plt.show()\n", " return errors" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "34uB7Vzx0fWn" }, "outputs": [], "source": [ "VizSquaredErrors(x,y,lin_reg)" ] }, { "cell_type": "markdown", "metadata": { "id": "RaF2RcYG0fWn" }, "source": [ "The red line is the line that minimizes the sum of the squared errors between the model and the data. That is, **it makes the total area of all the blue squares as small as possible**." ] }, { "cell_type": "markdown", "source": [ "\n", "\n", "---\n", "\n" ], "metadata": { "id": "bVH4RnZPMOJz" } }, { "cell_type": "markdown", "metadata": { "id": "vKeDwP3o0fWn" }, "source": [ "### Scoring the model" ] }, { "cell_type": "markdown", "metadata": { "id": "X4WVwEPq0fWn" }, "source": [ "The score of a model refers to how well the model fits the data. There is also usually more than one way to score a model!\n", "\n", "**Mean-squared error (MSE)** is one way to score a model like this, and it is pretty easy to compute. It is exactly what it sounds like - it is the mean of the squared errors!\n", "\n", "We could calculate this by hand:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Rsld8xbk0fWn" }, "outputs": [], "source": [ "#We will recreate the model just in case we ran other code in between\n", "lin_reg.fit(x, y)\n", "y_pred = lin_reg.predict(x)\n", "errors = y-y_pred\n", "mse = np.mean(errors**2)\n", "mse" ] }, { "cell_type": "markdown", "metadata": { "id": "9Cf9mNQq0fWn" }, "source": [ "Or use scikit-learn:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "kMa-JSdx0fWn" }, "outputs": [], "source": [ "from sklearn.metrics import mean_squared_error" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nL37LjY20fWn" }, "outputs": [], "source": [ "y_pred = lin_reg.predict(x)\n", "mse = mean_squared_error(y, y_pred)\n", "print(mse)" ] }, { "cell_type": "markdown", "metadata": { "id": "fLaAsnfW0fWn" }, "source": [ "MSE is useful for comparing between models, but we only have one model with nothing to compare it to!\n", "\n", "The default scoring method that is used when we call lin_reg.score(x,y) is called $R^2$, or the **coefficient of determination**." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "v4_HN3zg0fWn" }, "outputs": [], "source": [ "print('Model score: ', lin_reg.score(x,y))\n", "print('Model MSE: ', mean_squared_error(lin_reg.predict(x),y))" ] }, { "cell_type": "markdown", "metadata": { "id": "vUG1rY3B0fWn" }, "source": [ "**The coefficient of determination is the correlation coefficient squared in simple linear regression**\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "7F6Tq7Ej0fWn" }, "outputs": [], "source": [ "r = np.corrcoef(x,y,rowvar=False)[0][1] #rowvar=False indicates that the input variables are stored as columns, not as rows\n", "r" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "urospfFM0fWn", "collapsed": true }, "outputs": [], "source": [ "print(r**2)" ] }, { "cell_type": "markdown", "source": [ "\n", "\n", "---\n", "\n" ], "metadata": { "id": "SpZx8V_jY7vf" } }, { "cell_type": "markdown", "source": [ "### Complete in Class: Polynomial Regression\n" ], "metadata": { "id": "M7JtQVmhY99-" } }, { "cell_type": "code", "source": [ "b = 10\n", "a1 = 2\n", "a2 = 3\n", "a3=1.5\n", "\n", "n_examples = 100\n", "\n", "X = np.random.uniform(-10,10, n_examples)\n", "\n", "\n", "y = b +a1*X + a2*X**2 + a3*X**3 + np.random.normal(0,50,n_examples)\n", "\n", "plt.scatter(X,y)\n" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 445 }, "id": "N_MYO_9pY847", "outputId": "0bff2877-7c78-4681-8e15-8bdd1d3597ef" }, "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "" ] }, "metadata": {}, "execution_count": 127 }, { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "iVBORw0KGgoAAAANSUhEUgAABHkAAAM6CAYAAAAVB5+UAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAB7CAAAewgFu0HU+AAClN0lEQVR4nOzdfXzcdZ3v/fdvJjfTJNNgQ5lAWgNJmxYSbdlSzIilokez4A1U1uilqeCBkl2PSG1XvNBzsWfdPbqKrbDoruFGwOBddBdQLATPOUgLJkArxSYtTUpsTxuboTeQTJJOkk5+1x81MWnu5uY796/n48HjMfQ38/l9k0nQeff7+Xwt27ZtAQAAAAAAIKU5Er0AAAAAAAAARI+QBwAAAAAAIA0Q8gAAAAAAAKQBQh4AAAAAAIA0QMgDAAAAAACQBgh5AAAAAAAA0gAhDwAAAAAAQBog5AEAAAAAAEgDhDwAAAAAAABpgJAHAAAAAAAgDRDyAAAAAAAApAFCHgAAAAAAgDRAyAMAAAAAAJAGCHkAAAAAAADSACEPAAAAAABAGiDkAQAAAAAASANZiV4AkksgENCePXskSQsXLlRWFj8iAAAAAACYdvr0aR07dkyS9I53vEMulyvqmnyCxyR79uzR5ZdfnuhlAAAAAACQMV566SWtXr066jq0awEAAAAAAKQBdvJgkoULF44/fumll3T++ecncDUAAAAAAKSno0ePjnfSTPwsHg1CHkwycQbP+eefr0WLFiVwNQAAAAAApD9T83Bp1wIAAAAAAEgDhDwAAAAAAABpgJAHAAAAAAAgDRDyAAAAAAAApAFCHgAAAAAAgDRAyAMAAAAAAJAGCHkAAAAAAADSACEPAAAAAABAGiDkAQAAAAAASAOEPAAAAAAAAGmAkAcAAAAAACANEPIAAAAAAACkAUIeAAAAAACANEDIAwAAAAAAkAYIeQAAAAAAANIAIQ8AAAAAAEAaIOQBAAAAAABIA4Q8AAAAAAAAaYCQBwAAAAAAIA0Q8gAAAAAAAKQBQh4AAAAAAIA0kJXoBQAAAAAAAITCHxhRT29AA8NB5ec4VVzoktuVnehlJQ1CHgAAAAAAkLRs21ZL1wk1thzSM3t9Co7a49cclnTFknN1w7tL9f7lHlmWlcCVJh4hDwAAAAAASEpt3b3a1LRbHb7+aa+P2tKOzuPa0XlcBblOfeWai/X/XP72jA17mMkDAAAAAACSzo7OY6ptaJkx4Dlb/1BQX3msTe/55rNq6+6N8eqSEyEPAAAAAABIKm3dvapv3KXB4WDYr+1+65T+5vu/047OYzFYWXIj5AEAAAAAAEnDtm1tatodUcAzJjAyqvrGXRm3o4eQBwAAAAAAJI2WrhMht2jNZnA4qM1Nr8q27bmfnCYIeQAAAAAAQNJ4tPWQsVr7fX61dp00Vi/ZEfIAAAAAAICk4A+MqLndZ7SmydAo2RHyAAAAAACApNDTG1Bw1Gx71dPtPfIHRozWTFaEPAAAAAAAICkMRDFseSbBUVu+voDxusmIkAcAAAAAACSF/BxnTOr2D5kPj5IRIQ8AAAAAAEgKxYUuOR2W8boFubEJj5INIQ8AAAAAAEgKble2aio9RmtmOSx55ruM1kxWhDwAAAAAACBp1FWXGq1XU1kstyvbaM1kRcgDAAAAAACShresSBWeAmP1TIdGyYyQBwAAAAAAJA3LsrS1dqXmZUcfWeRkOTJmHo9EyAMAAAAAAJJMVUmh7vvMZXJlRRdbDJ8e1Sfua9WOzmOGVpbcCHkAAAAAAEDSWbN0oX7xd+9WyTnRDU0eHA6qvnGX2rp7Da0seRHyAAAAAACApFRVUqjnv/w+fX1dlaI5WX1wOKjNTa/Ktm1zi0tChDwAAAAAACBpWZalC8/N12iU+cx+n1+tXSfNLCpJEfIAAAAAAICk9mjroaSqk6wIeQAAAAAAQNLyB0bU3O4zUuvp9h75AyNGaiUjQh4AAAAAAJC0enoDCkbbq/VnwVFbvr6AkVrJiJAHAAAAAAAkrYHhoNF6/UNm6yUTQh4AAAAAAJC08nOcRusV5Jqtl0wIeQAAAAAAQNIqLnTJGc356RNkOSx55ruM1EpGhDwAAAAAACBpuV3Zqqn0GKlVU1kstyvbSK1klJXoBQAAAAAAAEzkD4yopzeggeGg8nOcuv6vFmnbnp6o69ZVlxpYXfIi5AEAAAAAAAln27Zauk6oseWQntnrm3SilsOSCnKz1D90OuL6yzxuVZctMLHUpEXIAwAAAAAAEqqtu1ebmnarw9c/7fVRW1EFPHk5Tm2pXSHLMjPbJ1kR8gAAAAAAgITZ0XlM9Y27NGj4qPQxeTlONaxfpaqSwpjUTyaEPAAAAAAAICHauntjGvAs87i1pXZFRgQ8EiEPAAAAAABIANu2talpd1QBjyXJss60c43JcliqqSxWXXWpqssWpH2L1kSEPAAAAAAAIO5auk7MOIMnVLakbIelr11XpeXF81WQ65Rnviutj0mfjSPRCwAAAAAAAJnn0dZDRuoMB2197Vd7leWwtOQ8d8YGPBIhDwAAAAAAiDN/YETN7T5j9QaHg9rc9Kps2577yWmMkAcAAAAAAMRVT29AwVGzgcx+n1+tXSeN1kw1hDwAAAAAACCuBmJ0mpapFrBURcgDAAAAAADiKj/HGZO6T7f3yB8YiUntVEDIAwAAAAAA4qq40CWnw/zR5sFRW76+gPG6qYKQBwAAAAAAxJXbla2aSk9MavcPxaYVLBUQ8gAAAAAAgLirqy6NSd2C3Ni0gqUCQh4AAAAAABB31RctUI7TbCyR5bDkme8yWjOVEPIAAAAAAIC4a/3jSQ0HR43WrKksltuVbbRmKiHkAQAAAAAAcReL485j1QKWKgh5AAAAAABAXPkDI2pu9xmtucxToOqyBUZrphpCHgAAAAAAEFc9vQEFR22jNW9490WyLPPHsqcSQh4AAAAAABBXA8Pmjzl/4cBx4zVTDSEPAAAAAACIq/wc88ecP93eI39gxHjdVELIAwAAAAAA4qq40CWnw2xrVXDUlq8vYLRmqiHkAQAAAAAAceV2Zaum0mO8bv+Q+TawVELIAwAAAAAA4i4Wx50X5JpvA0slhDwAAAAAACDuvGVFWrIw31i9LIclz3yXsXqpiJAHAAAAAADEnWVZuvuTlxqbzVNTWSy3K9tIrVRFyAMAAAAAABKiqqRQt9csM1IrFu1fqYaQBwAAAAAAJMwtV5bp7QvmRVVjmcet6rIFhlaUugh5AAAAAABAwliWpX/79CrNy44sosjLcWpL7QpZltkj2VMRIQ8AAAAAAEioqpJC3feZy5SXE97pWHk5TjWsX6WqksIYrSy1EPIAAAAAAICEW7N0oZrqvarwFIT0/GUet5rqvVqzdGGMV5Y6shK9AAAAAAAAAOnMjp7mjVeqteukGlsPqrndp+CoPX49y2GpprJYddWlqi5bQIvWWQh5AAAAAABA0rAsS97yInnLi+QPjMjXF1D/UFAFuU555rsy/pj02RDyAAAAAACApOR2ZRPqhIGZPAAAAAAAAGmAkAcAAAAAACANEPIAAAAAAACkAUIeAAAAAACANEDIAwAAAAAAkAYIeQAAAAAAANIAIQ8AAAAAAEAaIOQBAAAAAABIA4Q8AAAAAAAAaYCQBwAAAAAAIA2kbMjzxhtv6Mknn9Sdd96pq6++Wueee64sy5JlWbrxxhtDqvHwww+Pv2aufx5++OE56w0ODupb3/qWVq9erQULFig/P1/Lly/X5s2bdejQoZC/tkOHDmnz5s1avny58vPztWDBAq1evVp33XWXBgcHQ64DAAAAAAAyR1aiFxApj8eT6CVMcuDAAV1zzTXq7Oyc9Of79+/X/v379cADD+hHP/qRPvzhD89a51e/+pXq6urU19c3/meDg4PauXOndu7cqQceeEC//vWvtWTJkph8HQAAAAAAIDWlbMgz0dvf/nYtX75czzzzTMQ1mpubdcEFF8x4fdGiRTNe8/v9+tCHPjQe8GzYsEGf/OQnNW/ePD377LP6xje+ob6+Pn3iE5/QCy+8oJUrV05b55VXXtEnPvEJnTp1SgUFBbrjjjt01VVX6dSpU/rpT3+q+++/Xx0dHfrQhz6knTt3yu12R/z1AgAAAACA9JKyIc+dd96p1atXa/Xq1fJ4PDp48KAuuuiiiOtVVFTowgsvjOi1d911lzo6OiRJ3/rWt/SlL31p/JrX69V73/terV27VoODg9q4caN++9vfTlvntttu06lTp5SVlaVnnnlGXq93/Nr73vc+LV26VLfffrs6Ojq0ZcsW/Y//8T8iWi8AAAAAAEg/KTuT5x//8R/14Q9/OOFtWyMjI/rXf/1XSdLFF1+szZs3T3nOu9/9bt10002SpOeee04vv/zylOe89NJL2rFjhyTppptumhTwjNm8ebMuvvhiSdI999yjkZERY18HAAAAAABIbSkb8iSLZ599Vr29vZKkG264QQ7H9N/SicOgH3vssSnXH3/88fHHn/3sZ6et4XA49JnPfEaS9NZbb+nZZ5+NcNUAAAAAACDdEPJE6fnnnx9/vHbt2hmfd9lllykvL0+S9MILL8xYJz8/X6tWrZqxzsR7TFcHAAAAAABkppSdyWPaZz/7We3fv1/Hjx/X/PnztWTJEv2X//Jf9Hd/93cqKSmZ8XV79+4df7x8+fIZn5eVlaUlS5boD3/4g/bt2zfl+tifLVmyRFlZM78tE+8xXZ25HDlyZNbrR48eDbsmAAAAAABIPEKeP5s4DPnEiRM6ceKEXnzxRW3ZskV333236uvrp33dWGiSn5+vc845Z9Z7LF68WH/4wx907NgxDQ0NKTc3V5IUCAR0/PhxSbOf4iVJb3vb25Sfn6+BgQEdPnw4xK9u8hoAAAAAAED6yfiQp6ysTB/72Mfk9XrHA5Curi79x3/8h37xi18oEAjob//2b2VZlm655ZYpr/f7/ZKkgoKCOe+Vn58//ri/v3885BmrEU6dgYEB9ff3z/lcAAAAAACQGTI65Fm3bp1uuOEGWZY16c9Xr16tT3ziE3ryySf1sY99TCMjI/riF7+oj370oyouLp703EAgIEnKycmZ835joY4knTp1akqNcOtMrBGquXb/HD16VJdffnnYdQEAAAAAQGJl9ODlwsLCKQHPRB/+8Id15513SpIGBwf14IMPTnmOy+WSJA0PD895v6GhofHH8+bNm1Ij3DoTa4Rq0aJFs/5z/vnnh10TAAAAAAAkXkaHPKG45ZZbxoOg5557bsp1t9stSSG1Tg0MDIw/ntiWNVYj3DqhtHYBAAAAAIDMQMgzh/POO09FRUWSpO7u7inXxwYlDwwM6K233pq11lir1MKFCye1brlcrvF7zHX61Ztvvjke8jBEGQAAAAAAjCHkCcFsLV2XXHLJ+OPXXnttxuedPn1ar7/+uiTp4osvnrHOgQMHdPr06RnrTLzHdHUAAAAAAEBmIuSZw7Fjx8aPN7/gggumXH/Pe94z/ni6dq4xO3fuHN+Bc8UVV8xYZ2BgQLt27ZqxzsR7TFcHAAAAAABkJkKeOdx3332ybVuStHbt2inX3/ve96qwsFCS9Mgjj4w/92wPP/zw+ON169ZNuX7dddeNP37ooYemrTE6Oqof/vCHkqRzzjlHV111VUhfAwAAAAAASH8ZG/IcPHhQr7zyyqzPefLJJ/W1r31N0pmTrD772c9OeU5OTo6+8IUvSJL27dunb3/721Oe09LSMn4y19q1a7V69eopz7n88su1Zs0aSdKDDz6olpaWKc/ZsmWL9u3bJ0m67bbblJ2dPev6AQAAAABA5shK9AIi9fzzz+vAgQPj/z7WUiWdmWszceeMJN14442T/v3gwYO66qqr5PV69ZGPfEQrVqzQeeedJ0nq6urSL37xC/3iF78Y35nz7W9/WyUlJdOu5Utf+pJ+9rOfqaOjQ7fffrsOHDigT37yk5o3b56effZZff3rX9fp06c1b9483X333TN+Tffcc4+uuOIKnTp1Sh/84Af1la98RVdddZVOnTqln/70p7rvvvskSRUVFdq8eXOo3yoAAAAAAJABLHum/qIkd+ONN+qRRx4J+flnf5m//e1vQ2p3ysvL03e+8x3dcsstsz7vwIEDuuaaa9TZ2Tnt9fnz5+tHP/qRPvzhD89a51e/+pXq6urU19c37fWKigr9+te/1pIlS+ZceySOHDkyfmrX4cOHx08PAwAAAAAA5sTi83fK7uSJ1qpVq/Too4+qpaVFO3fu1NGjR3X8+HGdPn1ab3vb21RZWan3v//9uvnmm8d3+MxmyZIleuWVV/S9731PP//5z3XgwAENDw9r8eLFuuaaa3TbbbeptLR0zjof+chH9Ic//EH33HOPfv3rX+vIkSPKycnRkiVL9PGPf1yf//znlZeXZ+JbAAAAAABA2PyBEfX0BjQwHFR+jlPFhS65XYwTSQYpu5MHscFOHgAAAADA2WzbVkvXCTW2HNIze30Kjv4lSnA6LNVUelRXXSpvWZEsy0rgSlMHO3kAAAAAAEBctXX3alPTbnX4+qe9Hhy1tW1Pj7bt6VGFp0Bba1eqqqQwzquElMGnawEAAAAAgNnt6Dym2oaWGQOes3X4+lXb0KIdncdivDJMh5AHAAAAAABM0dbdq/rGXRocDob1usHhoOobd6mtuzdGK8NMCHkAAAAAAMAktm1rU9PusAOeMYPDQW1uenXKSdeILUIeAAAAAAAwSUvXiZBbtGay3+dXa9dJQytCKAh5AAAAAADAJI+2HkqqOggNIQ8AAAAAABjnD4youd1npNbT7T3yB0aM1MLcCHkAAAAAAMC4nt6AgqNmZukER235+gJGamFuhDwAAAAAAGDcQITDlmfSP2S2HmZGyAMAAAAAAMbl5ziN1ivINVsPMyPkAQAAAAAA44oLXXI6LCO1shyWPPNdRmphboQ8AAAAAACkOX9gRJ0+v3YffkudPv+sw5DdrmzVVHqM3LemslhuV7aRWphbVqIXAAAAAAAAzLNtWy1dJ9TYckjP7PVNGqbsdFiqqfSorrpU3rIiWdbknTt11aXatqcn6jXUVZdGXQOhI+QBAAAAACDNtHX3alPTbnX4+qe9Hhy1tW1Pj7bt6VGFp0Bba1eqqqRw/Lq3rEgVnoIZXx+KZR63qssWRPx6hI92LQAAAAAA0siOzmOqbWgJOaDp8PWrtqFFOzqPjf+ZZVnaWrtSeREOYc7LcWpL7YopO4QQW4Q8AAAAAACkibbuXtU37tJgmMegDw4HVd+4S23dveN/VlVSqIb1q8IOevJynGpYv2rSziDEByEPAAAAAABpwLZtbWraHXbAM2ZwOKjNTa/Ktv8yu2fN0oVqqveqwlMQUo1lHrea6r1as3RhRGtAdJjJAwAAAABAGmjpOhHVDB1J2u/zq7XrpLzlReN/VlVSqOaNV6q166QaWw+quX3yEOcsh6WaymLVVZequmwBLVoJRMgDAAAAAEAaeLT1kLE6E0Me6cyMHm95kbzlRfIHRuTrC6h/KKiCXKc8810ck54kCHkAAAAAAEhx/sCImtt9Rmo91XZUfaeGNX9ezrTX3a5sQp0kxUweAAAAAABSXE9vYFILVTRGbekj331h0hBmpAZCHgAAAAAAUtxAhMOWZ3LoxOCUY9WR/Ah5AAAAAABIcflhHnMeiumOVUdyI+QBAAAAACDFFRe65HSYP9VqumPVkbwIeQAAAAAASHFuV7ZqKj0xqT12rDqSHyEPAAAAAABpoK66NGa1TR3Pjtgi5AEAAAAAIA14y4pU4SmISe2n23vkD4zEpDbMIeQBAAAAACANWJalrbUrlReDIczBUVu+voDxujCLkAcAAAAAgDRRVVKohvWrYhL09A+ZPaYd5hHyAAAAAACQRtYsXaimeq8uLMozWrcg13xwBLMIeQAAAAAASDNVJYX65eevkKlT1bMcljzzXWaKIWYIeQAAAAAASEPz5+Xor6uKjdSqqSyW25VtpBZih5AHAAAAAIA0ZepY9Vgezw5zCHkAAAAAAEhTJo5VX+Zxq7psgaEVIZYIeQAAAAAASFPRHquel+PUltoVsixDw30QU4Q8AAAAAACksaqSQn3+fUsieu3n37dEVSWFhleEWCHkAQAAAAAgjbV19+q7/+dARK/97v85oLbuXsMrQqwQ8gAAAAAAkKZs29ampt0aHA5G9PrB4aA2N70q27YNrwyxQMgDAAAAAECaauk6oQ5ff1Q19vv8au06aWhFiCVCHgAAAAAA0tSjrYeSqg5ii5AHAAAAAIA05A+MqLndZ6TW0+098gdGjNRC7BDyAAAAAACQhnp6AwqOmpmlExy15esLGKmF2CHkAQAAAAAgDQ1EOGx5Jv1DZuvBPEIeAAAAAADSUH6O02i9glyz9WAeIQ8AAAAAAGmouNAlp8MyUivLYckz32WkFmKHkAcAAAAAgDTkdmWrptJjpFZNZbHcrmwjtRA7hDwAAAAAAKSpuurSpKqD2CLkAQAAAAAgTXnLilThKYiqxjKPW9VlCwytCLFEyAMAAAAAQJqyLEtba1cqL8IhzHk5Tm2pXSHLMjPbB7FFyAMAAAAAQBqrKilUw/pVYQc9eTlONaxfpaqSwhitDKYR8gAAAAAAkObWLF2opnpvyK1byzxuNdV7tWbpwhivDCZlJXoBAAAAAAAg9qpKCtW88Uq1dp1UY+tBNbf7FBy1x69nOSzVVBarrrpU1WULaNFKQYQ8AAAAAABkCMuy5C0vkre8SP7AiHx9AfUPBVWQ65Rnvotj0lMcIQ8AAAAAABnI7com1EkzzOQBAAAAAABIA4Q8AAAAAAAAaYCQBwAAAAAAIA0Q8gAAAAAAAKQBQh4AAAAAAIA0QMgDAAAAAACQBgh5AAAAAAAA0gAhDwAAAAAAQBog5AEAAAAAAEgDhDwAAAAAAABpgJAHAAAAAAAgDRDyAAAAAAAApAFCHgAAAAAAgDRAyAMAAAAAAJAGCHkAAAAAAADSACEPAAAAAABAGiDkAQAAAAAASAOEPAAAAAAAAGmAkAcAAAAAACANEPIAAAAAAACkAUIeAAAAAACANEDIAwAAAAAAkAYIeQAAAAAAANIAIQ8AAAAAAEAaIOQBAAAAAABIA4Q8AAAAAAAAaYCQBwAAAAAAIA0Q8gAAAAAAAKQBQh4AAAAAAIA0QMgDAAAAAACQBgh5AAAAAAAA0gAhDwAAAAAAQBog5AEAAAAAAEgDhDwAAAAAAABpgJAHAAAAAAAgDRDyAAAAAAAApAFCHgAAAAAAgDRAyAMAAAAAAJAGCHkAAAAAAADSACEPAAAAAABAGiDkAQAAAAAASAOEPAAAAAAAAGmAkAcAAAAAACANEPIAAAAAAACkgaxELwAAAAAAgGTnD4yopzeggeGg8nOcKi50ye3KTvSygEkIeQAAAAAAmIZt22rpOqHGlkN6Zq9PwVF7/JrTYamm0qO66lJ5y4pkWVYCVwqcQcgDAAAAAMBZ2rp7talptzp8/dNeD47a2ranR9v29KjCU6CttStVVVIY51UCkzGTBwAAAACACXZ0HlNtQ8uMAc/ZOnz9qm1o0Y7OYzFeGTA7Qh4AAAAAAP6srbtX9Y27NDgcDOt1g8NB1TfuUlt3b4xWBswtZUOeN954Q08++aTuvPNOXX311Tr33HNlWZYsy9KNN94Ydr2nnnpK69at06JFi5Sbm6tFixZp3bp1euqpp0Kucfr0aX3/+9/XmjVrtHDhQs2bN0/l5eWqr69Xe3t7yHWOHz+uO++8U+985zs1f/58zZ8/X+985zt155136sSJE2F/bQAAAACAudm2rU1Nu8MOeMYMDge1uelV2bY995OBGLDsFP3pm22o1Q033KCHH344pDqjo6O65ZZb9OCDD874nJtvvlkNDQ1yOGbOxI4fP65rrrlGL7/88rTXc3Nz9d3vflc333zzrOt58cUXdd1116mnp2fa6+eff74ef/xxXX755bPWidSRI0e0ePFiSdLhw4e1aNGimNwHAAAAAJLN714/rk/d/2LUdX6yoVre8iIDK0I6i8Xn75TdyTPR29/+dn3wgx+M6LVf/epXxwOeSy+9VD/5yU/00ksv6Sc/+YkuvfRSSdIDDzyg//7f//uMNYLBoNatWzce8HzsYx/TU089pRdffFH/+q//qvPOO09DQ0Oqr6+fdWfQ4cOH9ZGPfEQ9PT3KysrS7bffru3bt2v79u26/fbblZWVpaNHj+ojH/mIjhw5EtHXCwAAAACY3qOth4zUaWw9aKQOEK6U3cnzD//wD1q9erVWr14tj8ejgwcP6qKLLpIU+k6ejo4OVVZW6vTp07rsssu0fft2zZs3b/z64OCg1q5dq507dyorK0v79u3TkiVLptT5wQ9+oJtuukmS9LnPfU7f+973Jl0/cOCAVq1apb6+Pi1ZskT79u1TVtbUg80+85nPqLGxUZLU1NSkj3/845OuNzU16ROf+ERYX2O42MkDAAAAIBP5AyNa+bXfTDomPRpN9dW6/CJ282Bm7OSZ4B//8R/14Q9/WB6PJ+Iad999t06fPi1JuvfeeycFPJKUl5ene++9V9KZeTvf+c53pq3z7W9/W5K0YMEC3XXXXVOuL1myRHfccYekM4HPY489NuU5PT09+tGPfiRJqqmpmRLwSFJtba1qamokSY2NjTO2dAEAAAAAwtPTGzAW8EjSZ37wEqdtIe5SNuSJlm3beuKJJyRJy5cvV3V19bTPq66u1rJlyyRJTzzxxJQBWh0dHdq3b5+kMyFMXl7etHUmDoOeLuT55S9/qdHRUUnSZz/72RnXPVZndHRUv/zlL2d8HgAAAAAgdAMRDlueSWBklNO2EHcZG/L88Y9/1J/+9CdJ0tq1a2d97tj17u5uHTx4cNK1559/fsrzplNcXKyKigpJ0gsvvDDleqh1Jl6brg4AAAAAIHz5OU7jNTltC/GWsSHP3r17xx8vX7581udOvD62ayeaOocPH9bAwMC0dQoLC1VcXDxjjfPPP1/z58+fdi0AAAAAgMgUF7rkdMx8inOk9vv8au06abwuMJ2p038zxMTTqeYabjQ2CEk6E9BEW8e2bR05cmS8DWxinVAGLS1evFjt7e1T1hKKuU7lOnr0aNg1AQAAACDVuV3Zqqn0aNse87NPH209xJHqiIuMDXn8fv/444KCglmfm5+fP/64v78/pnXmqjGxztk1QjExsAIAAAAA/EVddWlMQp6n23vkD4zI7co2XhuYKGPbtQKBwPjjnJycWZ+bm5s7/vjUqVMxrTNXjYl1zq4BAAAAAIict6xIFZ65/+I9XMFRW76+wNxPBKKUsTt5XC7X+OPh4eFZnzs0NDT++Oxj1s+uM/Hfw60zODg451om1jm7RijmavE6evSoLr/88rDrAgAAAECqsyxLW2tXqrahRYOGT9vqHzJbD5hOxoY8brd7/PFcbU8ThySf3U51dp3ZQp656gwODobUgjVWJ5TWrrOFMvMHAAAAADJVVUmhGtav0oYf7lRgZNRY3YJc86d3AWfL2HatiWHHXMOIJ+5+OXumTSR1LMuaEraM/ftcNSbWYb4OAAAAAJi3ZulCPfJZcx0OWQ5LnvkzbwgATMnYkOeSSy4Zf/zaa6/N+tyJ1y+++OKo6yxevHjSEOaJdXp7e9XTM/Ogr6NHj6qvr2/atQAAAAAAzHhXWZGurvIYqVVTWczQZcRFxoY8F110kS644AJJ0nPPPTfrc7dv3y5JKikp0YUXXjjp2nve857xx7PV6enpUUdHhyTpiiuumHI91DoTr01XBwAAAABgxnrvhUbq1FWXGqkDzCVjQx7LsnTttddKOrPDprW1ddrntba2ju/Aufbaa2VZ1qTrFRUV4ztqmpqaNDg4OG2dhx9+ePzxunXrplz/6Ec/KofjzNvx0EMPzbjusToOh0Mf/ehHZ3weAAAAACA6Jk7bWuZxq7psgaEVAbPL2JBHkjZu3Cin88zwq1tvvXXKkeSnTp3SrbfeKknKysrSxo0bp63z93//95KkkydP6vbbb59y/fXXX9c3vvENSdKSJUumDXmKi4v16U9/WpLU3NysX/ziF1Oe8/Of/1zNzc2SpPXr16u4uDiULxMAAAAAEIGx07byciIbmpyX49SW2hVTNgsAsWLZtm0nehGReP7553XgwIHxfz9+/Li+9KUvSTrTxnTzzTdPev6NN944bZ077rhD//Iv/yJJuvTSS/XlL39Z5eXlev311/XNb35Tr7zyyvjzvv71r09bIxgMau3atXrhhRckSddff702bNigt73tbXrppZf0T//0T3rjjTfkcDj05JNP6uqrr562zuHDh7Vq1SodO3ZMWVlZ2rx5sz784Q9Lkp588klt2bJFp0+f1sKFC/X73/8+JidlHTlyZHyg8+HDhzmNCwAAAEDG29F5TPWNu8I6Vj0vx6mG9au0ZunCGK4MqSwWn79TNuS58cYb9cgjj4T8/Jm+zNHRUW3YsEE/+MEPZnztTTfdpPvuu2+8nWo6x48f1zXXXKOXX3552uu5ubn67ne/OyV8OtuLL76o6667bsbhy8XFxXr88cf1rne9a9Y6kSLkAQAAAICp2rp7talptzp8/XM+d5nHrS21K1RVUhiHlSFVxeLzd1bUFVKcw+HQgw8+qOuvv1733XefXn75ZR0/flznnnuuVq9erfr6+hl33kx07rnn6ne/+53uv/9+/fjHP9a+ffs0MDCgCy64QO9///t12223qbKycs4673rXu7Rnzx7dc889evzxx3Xw4EFJZwZFX3vttdq4caOKioqi/bIBAAAAAGGoKilU88Yr1dp1Uo2tB9Xc7lNw9C+bCbIclmoqi1VXXarqsgW0aCEhUnYnD2KDnTwAAAAAMDd/YES+voD6h4IqyHXKM9/FMekICzt5AAAAAABIAm5XNqEOkk5Gn64FAAAAAACQLgh5AAAAAAAA0gAhDwAAAAAAQBog5AEAAAAAAEgDhDwAAAAAAABpgJAHAAAAAAAgDRDyAAAAAAAApIGsRC8AAAAAAIBE8wdG1NMb0MBwUPk5ThUXuuR2ZSd6WUBYCHkAAAAAABnJtm21dJ1QY8shPbPXp+CoPX7N6bBUU+lRXXWpvGVFsiwrgSsFQkPIAwAAAADIOG3dvdrUtFsdvv5prwdHbW3b06Nte3pU4SnQ1tqVqiopjPMqgfAwkwcAAAAAkFF2dB5TbUPLjAHP2Tp8/aptaNGOzmMxXhkQHUIeAAAAAEDGaOvuVX3jLg0OB8N63eBwUPWNu9TW3RujlQHRI+QBAAAAAGQE27a1qWl32AHPmMHhoDY3vSrbtud+MpAAhDwAAAAAgIzQ0nUi5Batmez3+dXaddLQigCzCHkAAAAAABnh0dZDSVUHMI2QBwAAAACQ9vyBETW3+4zUerq9R/7AiJFagEmEPAAAAACAtNfTG1Bw1MwsneCoLV9fwEgtwCRCHgAAAABA2huIcNjyTPqHzNYDTCDkAQAAAACkvfwcp9F6Bblm6wEmEPIAAAAAANKaPzCigaHTclhm6mU5LHnmu8wUAwzKSvQCAAAAAAAwzbZttXSdUGPLIT2z12dsHo8k1VQWy+3KNlYPMIWQBwAAAACQVtq6e7Wpabc6fP0xqV9XXRqTukC0CHkAAAAAAGljR+cx1Tfu0qDhQctjlnncqi5bEJPaQLSYyQMAAAAASAtt3b0xDXjycpzaUrtClmVouA9gGCEPAAAAACDl2batTU27YxrwNKxfpaqSwpjUB0ygXQsAAAAAkPJauk7EbAbPMo9bW2pXEPAg6RHyAAAAAABS3qOth4zWy3JYqqksVl11qarLFtCihZRAyAMAAAAASGn+wIia231Gajks6bHPvVtlCws4Jh0ph5k8AAAAAICU1tMbUHDUNlJr1Jbyc7MIeJCSCHkAAAAAACltwPCw5f6h2AxvBmKNkAcAAAAAkNLyc5xG6xXkmq0HxAshDwAAAAAgpRUXuuR0mBmMnOWw5JnvMlILiDdCHgAAAABASnO7slVT6TFSq6aymHk8SFmEPAAAAACAlFdXXZpUdYBEIOQBAAAAAKQ8b1mRKjwFUdVY5nGrumyBoRUB8UfIAwAAAABIeZZlaWvtSuVFOIQ5L8epLbUrZFlmZvsAiUDIAwAAAABIC1UlhWpYvyrsoCcvx6mG9atUVVIYo5UB8UHIAwAAAABIG2uWLlRTvTfk1q1lHrea6r1as3RhjFcGxF5WohcAAAAAAIBJVSWFat54pVq7Tqqx9aCa230Kjtrj17Mclmoqi1VXXarqsgW0aCFtEPIAAAAAANKOZVnylhfJW14kf2BEvr6A+oeCKsh1yjPfxTHpSEuEPAAAAACAtOZ2ZRPqICMwkwcAAAAAACANEPIAAAAAAACkAUIeAAAAAACANEDIAwAAAAAAkAYIeQAAAAAAANIAp2sBAAAAAFKCPzCint6ABoaDys9xqriQo9CBiQh5AAAAAABJy7ZttXSdUGPLIT2z16fgqD1+zemwVFPpUV11qbxlRbIsK4ErBRKPkAcAAAAAkJTaunu1qWm3Onz9014PjtratqdH2/b0qMJToK21K1VVUhjnVQLJg5k8AAAAAICks6PzmGobWmYMeM7W4etXbUOLdnQei/HKgORFyAMAAAAASCpt3b2qb9ylweFgWK8bHA6qvnGX2rp7Y7QyILkR8gAAAAAAkoZt29rUtDvsgGfM4HBQm5telW3bcz8ZSDOEPAAAAACApNHSdSLkFq2Z7Pf51dp10tCKgNRByAMAAAAASBqPth5KqjpAKiHkAQAAAAAkBX9gRM3tPiO1nm7vkT8wYqQWkCoIeQAAAAAASaGnN6DgqJlZOsFRW76+gJFaQKog5AEAAAAAJIWBCIctz6R/yGw9INkR8gAAAAAAkkJ+jtNovYJcs/WAZEfIAwAAAABICsWFLjkdlpFaWQ5LnvkuI7WAVEHIAwAAAABICm5XtmoqPUZq1VQWy+3KNlILSBWEPAAAAACApFFXXZpUdYBUQsgDAAAAAEga3rIiVXgKoqqxzONWddkCQysCUgchDwAAAAAgaViWpa21K5UX4RDmvBynttSukGWZme0DpBJCHgAAAABAUqkqKVTD+lVyZYf3kdWV7VDD+lWqKimM0cqA5JaV6AUAAAAAADKXPzCint6ABoaDys9xqrjQ9ZeByXaYxcJ9PpBmCHkAAAAAAHFl27Zauk6oseWQntnrU3D0L+mM02GpumyBdh58U0OnR8OqGzg9qvrGXWqq97KbBxmJkAcAAAAAEDdt3b3a1LRbHb7+aa8HR229cOBExPUHh4Pa3PSqnt64hrk8yDjM5AEAAAAAxMWOzmOqbWiZMeAxZb/Pr9aukzG9B5CMCHkAAAAAADHX1t2r+sZdGhwOxuV+j7Yeist9gGRCyAMAAAAAiCnbtrWpaXfcAh5Jerq9R/7ASNzuByQDQh4AAAAAQEy1dJ2IeYvW2YKjtnx9gbjeE0g0Qh4AAAAAQEwlqnWqfyh+O4eAZEDIAwAAAACIGX9gRM3tvoTcuyDXmZD7AolCyAMAAAAAiJme3oCCo3bc75vlsOSZ74r7fYFEIuQBAAAAAMTMQByHLU9UU1kstys7IfcGEoWQBwAAAAAQM/k5iWmZqqsuTch9gUQi5AEAAAAAxExxoUtOhxXXe15YlKfqsgVxvSeQDAh5AAAAAAAx43Zlq6bSE9d73vr+pbKs+AZLQDIg5AEAAAAAxFS8W6dWLCqM6/2AZEHIAwAAAACIKW9ZkSo8BXG5F6dqIZMR8gAAAAAAYsqyLG2tXam8OAxh5lQtZDJCHgAAAABAzFWVFKph/aqYBz2cqoVMRsgDAAAAAIiLNUsXqqneG7PWrWUeN6dqIaMR8gAAAAAA4qaqpFDNG6/UTzZU65p3FBs7Xj0vx6kttSs4VQsZLSvRCwAAAAAAZBbLsuQtL5K3vEj+wIh8fQH1DwVVkOtU17EBbfzZbg0OB0Oul5fjVMP6Vaoq4VQtZDZCHgAAAABAwrhd2ZMGJS85z62meq82Ne1Wh69/ztcv87i1pXYFAQ8gQh4AAAAAQJIZa+lq7TqpxtaDam73KThqj1/PcliqqSxWXXWpqssW0KIF/BkhDwAAAAAg6czW0uWZ7+KYdGAahDwAAAAAgKR2dksXgOkR8gAAAAAAYs4fGFFPb0ADw0Hl5zhVXMhuHMA0Qh4AAAAAQEzYtq2WrhNqbDmkZ/ZOnqvjdFiqqfSorrpU3rIi5uoABhDyAAAAAACMa+vunfWErOCorW17erRtT48qPAXaWruSE7KAKDkSvQAAAAAAQHrZ0XlMtQ0tIR2BLkkdvn7VNrRoR+exGK8MSG+EPAAAAAAAY9q6e1XfuEuDw8GwXjc4HFR94y61dffGaGVA+iPkAQAAAAAYYdu2NjXtDjvgGTM4HNTmpldl2/bcTwYwBSEPAAAAAMCIlq4TIbdozWS/z6/WrpOGVgRkFkIeAAAAAEDU/IER/ftvXzdS69HWQ0bqAJmG07UAAAAAACHxB0bU0xvQwHBQ+TlOeebnqu1PfWpsOaTm9h6NGuqyerq9R/7AiNyubDMFgQxByAMAAAAAmJFt22rpOqHGlkN6Zq9PQVNJziyCo7Z8fQFCHiBMhDwAAAAAgGm1dfdqU9PuqOfsRKJ/KLLhzUAmI+QBAAAAAEyxo/NYREehm1KQ60zIfYFUxuBlAAAAAMAkbd29CQ14shyWPPNdCbk3kMoIeQAAAAAA42zb1qam3QkLeCSpprKYeTxABDI+5LEsK6R/3vve985Z66mnntK6deu0aNEi5ebmatGiRVq3bp2eeuqpkNdz+vRpff/739eaNWu0cOFCzZs3T+Xl5aqvr1d7e3sUXykAAAAAzK2l60RCZvBMVFddmtD7A6mKmTwGjI6O6pZbbtGDDz446c+7u7vV3d2txx9/XDfffLMaGhrkcMycqx0/flzXXHONXn755Ul/3tXVpfvuu0+PPPKIvvvd7+rmm2+OydcBAAAAAI+2Hkro/Zd53KouW5DQNQCpipDnz/7u7/5On/vc52a8np+fP+O1r371q+MBz6WXXqrbb79d5eXlev311/Wtb31Lr7zyih544AEtXLhQX//616etEQwGtW7duvGA52Mf+5g2bNigBQsW6MUXX9Q///M/64033lB9fb1KSkp09dVXR/HVAgAAAMBU/sCImtt9Cbt/Xo5TW2pXyLKshK0BSGWEPH923nnnqaqqKuzXdXR06Nvf/rYk6bLLLtP27ds1b948SdLq1av10Y9+VGvXrtXOnTt111136b/+1/+qJUuWTKnzyCOP6Pnnn5ckfe5zn9P3vve98WuXX365rr76aq1atUp9fX36whe+oH379ikri7cPAAAAgDk9vQEFR+2E3Dsvx6mG9atUVVKYkPsD6SDjZ/JE6+6779bp06clSffee+94wDMmLy9P9957r6Qz83a+853vTFtnLChasGCB7rrrrinXlyxZojvuuEOSdODAAT322GPGvgYAAAAAkKSBBA1bXuZxq6neqzVLFybk/kC6IOSJgm3beuKJJyRJy5cvV3V19bTPq66u1rJlyyRJTzzxhGx7cjLe0dGhffv2SZJqa2uVl5c3bZ0bb7xx/DEhDwAAAADT8nOccb3fu8uL9JMN1Xp64xp28AAGEPJE4Y9//KP+9Kc/SZLWrl0763PHrnd3d+vgwYOTro21ac1Vp7i4WBUVFZKkF154IZIlAwAAAMCMigtdcjriNw/na9dWyltexAwewBBCnj/7+c9/rksuuUR5eXlyu91aunSpbrjhBj377LMzvmbv3r3jj5cvXz5r/YnXx3btRFPn8OHDGhgYmPW50zly5Mis/xw9ejTsmgAAAADSg9uVrZpKT1zuleWw5Jnvisu9gEzB5N4/mxi0SGfm3hw4cEA//OEPdd111+nhhx9WYeHk7YNHjhwZf7xo0aJZ6y9evHj88eHDh6OuY9u2jhw5Mt4GFqqJ6wAAAACAs9VVl2rbnp6Y36emslhuV3bM7wNkkowPefLy8vTRj35U73//+7V8+XIVFBTo2LFjeu655/T9739fJ06c0OOPP65rr71Wv/nNb5Sd/Zf/CPn9/vHHBQUFs95n4hHs/f39k66ZqgMAAAAA0fKWFanCU6AOX2w/b9RVl8a0PpCJMj7k6e7u1jnnnDPlzz/wgQ/o1ltv1dVXX61XXnlFzz33nP793/9dX/jCF8afEwgExh/n5OTMep/c3Nzxx6dOnZp0zVSdUJy9i+hsR48e1eWXXx52XQAAAADpwbIsba1dqdqGFg3G6LStZR63qssWxKQ2kMkyfibPdAHPGI/Ho1/84hfju3fGjkIf43L9pX90eHh41vsMDQ2NPz77mHVTdUKxaNGiWf85//zzw64JAAAAIL1UlRSqYf0q5cXgtK28HKe21K5g2DIQAxkf8sylrKxMH/jABySdmdMzdpqWJLnd7vHHc7VOTRySfHZLlqk6AAAAAGDKmqUL1VTvVYXH3OeOvBynGtav4rh0IEYIeUJwySWXjD/u7u4efzxxSPLE4cnTmdgmdfbw40jqWJY155BmAAAAAIhGVUmhmjdeqZ9sqNY17yiecry602GpIDe0KSDLPG411Xu1ZunCWCwVgJjJE5KZthFODH9ee+21WWtMvH7xxRfPWmflypVz1lm8ePGkIcwAAAAAEAuWZclbXiRveZH8gRH5+gLqHwqqINcpz3yXCnKz1Np1Uo2tB9Xc7lNw1B5/bZbDUk1lseqqS1VdtoAWLSDGCHlCMPF49QsuuGD88UUXXaQLLrhAf/rTn/Tcc8/NWmP79u2SpJKSEl144YWTrr3nPe8Zf/zcc8/pk5/85LQ1enp61NHRIUm64oorwvoaAAAAACBablf2tMeezxYCcUw6ED+0a83hj3/8o37zm99IksrLy1VSUjJ+zbIsXXvttZLO7LBpbW2dtkZra+v4Dpxrr712SnpdUVExvrunqalJg4OD09Z5+OGHxx+vW7cusi8IAAAAAGLE7crWkvPcWrn4HC05z03AA8RZRoc8v/rVr3T69OkZr/t8Pl1//fXjJ1597nOfm/KcjRs3yuk8M3H+1ltvnXKs+alTp3TrrbdKkrKysrRx48Zp7/X3f//3kqSTJ0/q9ttvn3L99ddf1ze+8Q1J0pIlSwh5AAAAAADAJJZt2/bcT0tPF154oUZGRnT99dfL6/Xqwgsv1Lx583T8+HH99re/VUNDg44fPy7pTEvV//pf/0u5ublT6txxxx36l3/5F0nSpZdeqi9/+csqLy/X66+/rm9+85t65ZVXxp/39a9/fdq1BINBrV27Vi+88IIk6frrr9eGDRv0tre9TS+99JL+6Z/+SW+88YYcDoeefPJJXX311bH4lujIkSPjg6EPHz7McGcAAAAAAGIgFp+/Mz7kOXTo0JzPu/766/XAAw/onHPOmfb66OioNmzYoB/84Acz1rjpppt03333yeGYefPU8ePHdc011+jll1+e9npubq6++93v6uabb55zzZEi5AEAAAAAIPZi8fk7owcvP/LII3ruuefU0tKirq4uHT9+XH19fSooKNDixYv17ne/WzfccIO8Xu+sdRwOhx588EFdf/31uu+++/Tyyy/r+PHjOvfcc7V69WrV19eHtPPm3HPP1e9+9zvdf//9+vGPf6x9+/ZpYGBAF1xwgd7//vfrtttuU2VlpakvHwAAAAAApJGM3smDqdjJAwAAAABA7MXi83dGD14GAAAAAABIF4Q8AAAAAAAAaSCjZ/IAAAAAQKL4AyPq6Q1oYDio/BynigtdcruyE70sACmMkAcAAAAA4sS2bbV0nVBjyyE9s9en4OhfRqQ6HZZqKj2qqy6Vt6xIlmUlcKUAUhEhDwAAAADEQVt3rzY17VaHr3/a68FRW9v29Gjbnh5VeAq0tXalqkoK47xKAKmMmTwAAAAAEGM7Oo+ptqFlxoDnbB2+ftU2tGhH57EYrwxAOiHkAQAAAACD/IERdfr82n34LXX6/Hqx64TqG3dpcDgYVp3B4aDqG3eprbs3RisFkG5o1wIAAACAKM02aycag8NBbW56VU9vXDM+o4eBzQBmQsgDAAAAAFGYa9ZOtPb7/GrtOiFbYmAzgFkR8gAAAABAhHZ0HouoFStcG364S/1Dp6e9xsBmAGOYyQMAAAAAEWjr7o1LwCNpxoDnbAxsBjIbIQ8AAAAAhMm2bW1q2h2XgCdcDGwGMhchDwAAAACEqaXrRMxm8JgwNrDZts0MgAaQGgh5AAAAACBMj7YeSvQS5nRmYPPJRC8DQBwR8gAAAABAGPyBETW3+xK9jJCkQhgFwBxCHgAAAAAIQ09vYNIR5sns6fYe+QMjiV4GgDgh5AEAAACAMAwk4bDlmQRHbfn6AoleBoA4IeQBAAAAgDDk5zgTvYSw9A+lTigFIDqEPAAAAAAQhuJCl5wOK9HLCFlBbmqFUgAiR8gDAAAAAGFwu7JVU+lJ9DJCkuWw5JnvSvQyAMQJIQ8AAAAAhKmuujTRSwhJTWWx3K7sRC8DQJwQ8gAAAABAmLxlRarwFCR6GXNKlTAKgBmEPAAAAAAQJsuytLV2pfIiHMKcl+PUw5+9TLEc7bPM41Z12YLY3QBA0iHkAQAAAIAIVJUUqmH9qrCDnrwcpxrWr9J7l3n011XFMVlbXo5TW2pXyLJSZ0A0gOgR8gAAAABAhNYsXaimem/IrVvLPG411Xu1ZulCSbFppxoLkapKCo3XBpDcshK9AAAAAABIZVUlhWreeKVau06qsfWgmtt9Co7a49ezHJZqKotVV12q6rIFk3bXjM326fD1G1nLMo9bW2pXEPAAGYqQBwAAAACiZFmWvOVF8pYXyR8Yka8voP6hoApynfLMd814wpVlWVpfXar/74n2iO/ttKS/rjp/2hAJQGYh5AEAAAAAg9yu7JCPLW/r7tU3nnot4nt94X1LtOHKMo5JByCJmTwAAAAAkBC2bWtT024NDgcjrtHc7lNBLn93D+AMQh4AAAAASICW109EPYtnv8+v1q6ThlYEINUR8gAAAABAnLV19+qWxp1Gaj3aeshIHQCpj5AHAAAAAOJoR+cxffz7v1P/UORtWhM93d4jf2DESC0AqY2QBwAAAADipK27V/WNu3RqZNRYzeCoLV9fwFg9AKmLkAcAAAAA4sDEoOWZmNoVBCC1EfIAAAAAQBy0dEU/aHkmBbnOmNQFkFoIeQAAAAAgDmI1IDnLYckz3xWT2gBSCyEPAAAAAMSYPzCi5nZfTGrXVBbL7cqOSW0AqYWQBwAAAABirKc3oOCoHZPaddWlMakLIPUQ8gAAAABAjA3EYNiyJC3zuFVdtiAmtQGkHkIeAAAAAIix/Bzzg5HzcpzaUrtClmUZrw0gNRHyAAAAAECMFRe65HSYC2PmZTvVsH6VqkoKjdUEkPoIeQAAAAAgxtyubNVUeszUys3Sz//WqzVLFxqpByB9EPIAAAAAQByYGpDMDh4AM8lK9AIAAAAAIJ3Ztq2WrhP6YcuhqGst87jlLS8ysCoA6YiQBwAAAABipK27V5uadqvD1x91LQYtA5gLIQ8AAACAlOUPjKinN6CB4aDyc5wqLnTJ7cpO9LIkSTs6j6m+cZcGDRyfnpfDoGUAcyPkAQAAAJBSxtqfGlsO6Zm9PgVH7fFrToelmkqP6qpL5S0rStiul7buXmMBzzKPW1tqVxDwAJgTIQ8AAACAlDFX+1Nw1Na2PT3atqdHFZ4Cba1dGfdwxLZtbWraHXXAc01VsdZ7L1R12QJatACEhNO1AAAAAKSEHZ3HVNvQEvJ8mw5fv2obWrSj81iMVzZZS9cJIzN41nsvlLc8cbuRAKQeQh4AAAAASS/S9qfB4aDqG3eprbs3Riub6tHW6E/RMlkHQOYg5AEAAACQ1KJtfxocDmpz06uybXvuJ0fJHxhRc7vPSK2n23vkD4wYqQUgMzCTBwAAAEBSM9H+tN/nV2vXSVWVzI/paVw9vYFJg6CjERy15esLJM1pYQCSHyEPAAAAgKRmqm3piz/brWP9QzE9jWvAwGlaE/UPma0HIL0R8gAAAABIWibbn3r6AlP+zPRpXPk5zmiWOEVBrtl6ANIbM3kAAAAAJC2T7U9zMXEaV3GhS06HmdOwshyWPPNdRmoByAyEPAAAAACSlun2p7lEexqX25WtmkqPkbXUVBYzjwdAWAh5AAAAACQt0+1PoYj2NK666lIj6zBVB0DmIOQBAAAAkLRMtj+FY+w0rkh4y4pU4SmI6v7LPG5Vly2IqgaAzEPIAwAAACBpmWx/Clekp3pZlqWttSuVF+EupLwcp7bUroj6pC8AmYeQBwAAAEBSS1Tb0tPtPfIHRiJ6bVVJoRrWrwo76MnLcaph/aqoTvgCkLkIeQAAAAAkNRPtT5EIjtryTXPseqjWLF2opnpvyGtf5nGrqd6rNUsXRnxPAJktK9ELAAAAAIDZjLU/1Ta0aDDOp231D0V3v6qSQjVvvFKtXSfV2HpQze2+SUfCZzks1VQWq666VNVlC2jRAhAVQh4AAAAASW+s/am+cVdcg56C3OhP97IsS97yInnLi+QPjMjXF1D/UFAFuU555rs4Jh2AMbRrAQAAAEgJ4bY/RSvLYckz32W0ptuVrSXnubVy8Tlacp6bgAeAUezkAQAAAFKYPzCint6ABoaDys9xqrgwvXeGhNL+dG5BrnqimKUzpqayOK2/lwDSDyEPAAAAkGJs21ZL1wk1thzSM3snhxxOh6WaSo/qqkvlLStKyxkvc7U/7enu1afufzHq+yTqVC8AiBQhDwAAAJBC2rp7talptzp8/dNeD47a2ranR9v29KjCU6CttSvT+jhutyt7ym6bsdO4ZvoehWKZx63qsgXRLg8A4oqZPAAAAECK2NF5TLUNLSGHFx2+ftU2tGhH57EYryy5jJ3GlZcT2dDkvBynttSuSMtdUADSGyEPAAAAkALaunsjOllqcDio+sZdauvujdHKktPYaVzhBj15OU41rF+V1rufAKQvQh4AAAAgydm2rU1NuyM+OnxwOKjNTa/Ktu25n5xGwj2Na5nHraZ6r9YsXRjjlQFAbDCTBwAAAEhyLV0nopovI0n7fX61dp2Ut7zI0KpSQyincdVUFquuulTVZQto0QKQ0gh5AAAAgCT3aOshY3WSPeSJxZHwc53GxTHpANIFIQ8AAACQxPyBETW3+4zUerq9R/7ASNKFGvE8En6607gAIF0Q8gAAAABJrKc3MCn0iEZw1JavL5CQkGOmHTocCQ8A5hDyAAAAAElsIMJhyzPpHzJbbzZz7dD5q7efoz8c6dXQ6dGQ6o0dCd+wfhXDkQFgGoQ8AAAAQBLLD/MI8LnrxeeA3VB26Lx88M2w644dCd9U72VHDwCchSPUAQAAgCRWXOiS02HuxKe/e/T3auvuNVZvOjs6j6m2oSXqE8FmkqlHwgPAXAh5AAAAgCTmdmWrptJjrN6BYwOqbWjRjs5jxmpO1Nbdq/rGXRo03GZ2trEj4QEAf0HIAwAAACS5uupSo/XGWp5M7+ixbVubmnbHPOAZY+poeQBIF4Q8AAAAQJLzlhWpwlNgtGYsWp5auk7ErEVrOmNHwgMAziDkAQAAAJKcZVnaWrtSeYaHMJtueYr3zpqxI+EBAGcQ8gAAAAApoKqkUA3rVxkPekwFM/7AiJrbfUZqhSOeR8IDQLIj5AEAAAnnD4yo0+fX7sNvqdPnp/0CMZeqP3Nrli5UU71X5QvzjdU01fLU0xtQcDT+p10V5JoNvQAglWUlegEAACAz2batlq4Tamw5pGf2+iZ9OHQ6LNVUelRXXSpvWZEsy9zx0chc6fIzV1VSqH//9F/pg3fvMFJvrOXJ7cqOqs5AnIYtT5TlsOSZ74r7fQEgWRHyAACAuGvr7tWmpt0zDmgNjtratqdH2/b0qMJToK21K1VVUhjnVcaGPzCint6ABoaDys9xqrjQFfWHa8wt3X7mBkdGjdYz0fKUb7iNLBQ1lcX8/gDABIQ8AAAgrnZ0HlN9466Qj1ju8PWrtqFFDetXac3ShVHfPxEhS7rsIElVif6ZiwXTgYqJlqfiQpecDiuuLVumj5YHgFRHyAMAAOKmrbs3rA/bYwaHg6pv3KWmem9EuysSGbIk8w6STNhVlKifuemY/H6bDFRMtTy5XdmqqfRo256eqGuFYpnHreqyBXG5FwCkCkIeAAAQF7Zta1PT7rA/bI8ZHA5qc9OrenrjmrCCmESGLJHsILn+33+n+z+zSldWnGdkDWfLpF1FifqZO3sNsfh+mwxUTLY81VWXxiXkyctxakvtipT/GQUA0zhdCwAAxEVL14kZg5ZQ7ff51dp1MuTn7+g8ptqGlpDvO9ams6PzWKRLHBfpDpKh06O64aGX9fgr3VGvYbo11dy9XZ+6/0U91dYzZRfIWOD1qftfVM3d29XW3Wt8DfEwdnJWY+uhuP/MTRTr77epViWTLU/esiJVeAqM1ZtOXo5TDetXJfXMJABIFEIeAEDGStUjlFPVo62H4lon2jadaAKOaHeQ2Lb0xabd2t7xRsRrOFsiA694sG1bv3v9uP7u0V1a+bXf6APf2a47n2g3UjuSn914fL9NBCqztTxF8t9Iy7K0tXal8mI0hHmZx62mem/SzkoCgESzbNuO32Q0JL0jR45o8eLFkqTDhw9r0aJFCV4RAJiVSa0qycQfGNHKr/3GyPwQp8PS7js/MGt7iW3bqrl7e1S7OJZ53BG36fzu9eP61P0vRnzvMblZDv3H37076h0Lbd29qm1oiSh0ystxGp1LEwtzteRFK5SfubPXE6/vt+l7mfpvZLititKZn/d3LirU7//vW5Pum+WwVFNZrLrqUlWXLeC/zQDSRiw+fzOTBwCQMeI5myUTBtqGo6c3YOzEneCoLV9fYNbvp8nWMG95UdivNbVraej0qJGZMImeSxNLkYQJ4QrlZ25MvL/fVSWFali/KuzvwXQtTyb/G7lm6UI11XtDDt+WedzaUrtCVSWF8gdG5OsLqH8oqIJcpzzzM/u/nwAQDkIeAEBG2N7xhjb8cJeGTo+G9PxIjlBml9DMBgx/AO8fmr2eydawcEMef2BEze0+I/eXogubpMQHXrEUaUteJOb6mRuTiO93NIHKmFgcM19VUqjmjVeqteukGlsPqrndF9IOHbcrm1AHACJEyAMASHuPv9KtLzbtVrgNyuEcoZzMx2Qng3zD8zkKcmeuZzJkebq9R/7ASFgfOE3uWhoTSdg08bWJXkMsRLtjJlyz/cxNlKjvd6SBihTbY+Yty5K3vEje8iJ26ABAHBDyAADS2vaONyIKeMZMbJ3oHzo9bQtWLP4GPN0UF7rkdFhGwo8shyXPfNeM1+PdGiZNbs87fHLQyL0niiRsGluXqcDrqbajEa0hVkzsmAnVXD9zYxIdMEYSqMSzvYwdOgAQe4Q8AIC01dbdqw0/3BVxwDNmv8+vT9zXql2H3pzSglVdtkA7D74ZchvYmHB2CaUDtytbNZUebdvTE3WtmsriWT8oxqs1bLb2PNPCmQkzkcnAa9SWnu88pqvfcYGRetHOrTK1YyYUc/3MjUlEwDiTUAOVdG7nA4BMRMgDAEhLY387HW74MpOX/nhyyp8FR229cOBExDWTfaCtaXXVpUZCnrrq0mn/fCw0ML2TZro2nVif5jSdUGfCjPEHRvRaT5/RNXzjqf3666rzoxoCbWJulem5R3OZ6WfubPGePWVCurbzAUCmIuQBAKSleLZyRCOT/gbcW1akCk9B1MeaV5ctGP/3WO+mma5NJx6nOU0nlJkwsf5+/N+TgxH/vJqcWxWLuUczOftnbjbxnD1lQqLbywAA5hHyAEAay+RjvOPZyhGtTPkbcMuytLV2pWobWiIKSPJynNpSu2J8h0c8dtOc3aYTz9OcJgplJky8dhdF8vNqem6V6R0zM3E6rEk/c3OJ5+wpE5KpvQwAYAYhDwCkGY7xjn8rR7Qy6W/Aq0oK1bB+VdhBSV6OUw3rV43v7IjXbpqJbTrxPs1porlmwsRzd1G4P6+xOLnJ9I6Zmdi2rdKivJAD83jOnjIhFdvLAACzI+QBgDTCMd5nxLOVw4RM+xvwNUsXqqneG/Kuk2Uet7bUrhj/WY3XbpqC3CyN2qOybVuWZSW0BXC2mTDx3l0Uzs9rrE5uMrljZjajtvS5R3+v33WdCDkwj/XsKZNSrb0MADA3R6IXAAAwY0fnMdU2tIT8IXSsHWJH57EYryz+4tXKYVIq/Q24PzCiTp9fuw+/pU6fX/7ASNg1qkoK1bzxSv1kQ7WueUexnI7Ju8qyHJY+9I7z9ZMN1Xp645rxgCeeu2n6h07r0w+8pJq7t6utuzdhLYCzzYRJ1O6iUH9eTZ7cNNHYjpl42HHg+JQwaSww/9T9L47/fIwZmz0VjXDmAEVjLCwzIR7tZQCAubGTBwDSQCzaIaKR6FlA8WrlMCnefwMe6ns09rz+odM68Ea/nmnv0f/Zf8xIG6BlWfKWF8lbXiR/YES+voD6h4IqyHXKM3/69SRiN02Hr18f//7vjJ3UFo6z5xCdLVG7i0L9eY3lyU2mdsxE6+z5QaZnT8VSqrWXAQDmRsgDACkuVu0QkawjWWYBxauVwxSnpbj8DXio71H1RQvU+seTIZ/QZKIN0O3KDukD4veePRBWXVNOjSQm4Jk4h2g63/lNRxxXdEaoOzZifXKTidPaTDk7MDc1eyoeUqm9DAAwN9q1ktShQ4e0efNmLV++XPn5+VqwYIFWr16tu+66S4ODg4leHoAkEqt2iHC0dfeq5u7t+tT9L+qptp6wWhtiIZ6tHCbk5WSpIDe2f+8Sznu0/P9rnvF5c4llG2DfqWG9cOCE8brJaJnHraZ677QnS415seuEXj74ZhxXdUaoOzZicXLTRGM7ZvKSZOfeWGBu22e+5rHZU6G2boXynsdCKrWXAQDmRsiThH71q1/pne98p7Zu3ar9+/drcHBQb775pnbu3Knbb79dl156qQ4cSMzfZAJIPibbISKRrLOAUulvlf1Dp6MK2eYS7ns0HIxu18rYrgbTYV4qnZg2lyuXnhvyHKLp2LatL//HH2K9zGmF+rsVj5ObxnbMJEvQc3ZgHunsqXiKNiyLZ3sZAGButGslmVdeeUWf+MQndOrUKRUUFOiOO+7QVVddpVOnTumnP/2p7r//fnV0dOhDH/qQdu7cKbfbneglA0igWLdDzCXZZgFNlEytHKGYbuaICfE+eWmMqTbAiR57pdtInUTLclj63qf/SpJCmkM0nZauEzp4Iv47e8PZsRGvk5vCPa0t1s7+XY5k9lS8pVJ7GQBgduzkSTK33XabTp06paysLD3zzDP6yle+Iq/Xq/e9732677779K1vfUuS1NHRoS1btiR4tQASLdbtELMxNQtorLXBtGRr5ZjLWMhmUqJOXhoTbRvgRP7AiFq70qNVa6zdye3K1pLz3Fq5+BwtOc8d1of9h174YwxXOL1wd2zE8+SmuXbMxNNsv8vRvOexlirtZQCA2RHyJJGXXnpJO3bskCTddNNN8nq9U56zefNmXXzxxZKke+65RyMjZj8QAEgt8WiHmEkyzAKaS7K1cswm3JAtFIk6eWkiU+2EPb0Bpcgc7TlF2kpo27Z+9/pxbXjkZf1m7xuGVzW7SHZsmJyNFcocoLEdM//26VXafecH9L82Xan/8dFL5MqO7//djcXvcrykQnsZAGB2tGslkccff3z88Wc/+9lpn+NwOPSZz3xGd9xxh9566y09++yz+uAHPxinFQJINvFqh5hOLI9GNincVo6K8woUOD2q/3sy/q0w4YRsoTD1HkUjkjbA6ZgONBMl0gG1bd29CWtHKi3K0/c+9VcRfaBP1MlNE3dKXVa6IO7fO9O/y/GUCu1lAICZEfIkkeeff16SlJ+fr1WrVs34vLVr144/fuGFFwh5gAxm8qjwUI9FlhIzC8gfGFFPb0ADw0Hl5zhVXBj6h42xv51u7TqpxtaDam6ffCx4lsNSTWXxmePDyxao/U99qm1oiXubUzgh21xMvkfRGNvVEO0HQ9OBZiJEOqB2R+exhMxVcjosffmvl2nDmrKI5yqZmI0V7clNofz+v7u8SNs7j0d8j7OZ/F1OpLGwDACQOgh5ksi+ffskSUuWLFFW1sxvzfLly6e8JlRHjhyZ9frRo0fDqgcgscbaIUz8TXmoxyJLsZkFNN29bdtWS9cJNbYc0jN7J38wczos1VR6VFddKm9Z0ZwfQsP52+nSojzd+eFL9A+/bNfQ6ehOmgpVOCFbKEy+R9Ha1PSq/t+rl4f0Ps3EZKCZCJEOqE3U4OwlCwt09ydXRrR75+xA9p+vq9KND70c0ddg6uSmuX7/JWnl134T98AcAADTCHmSRCAQ0PHjZ/4GadGiRbM+921ve5vy8/M1MDCgw4cPh3WfxYsXR7xGAMkpEe0Q8ZgFNFd7SnDU1rY9Pdq2p0cVngJtrQ39A+l0fzs9W6AUD+GEbKFIpvamPxzp1afufzHs92kik4FmvOVkOfSzW6r1jkXnhPW6eA/OPntHWzjBylyB7F+9/Rz94UhvWKFprE5umml3SiICcwAATCPkSRJ+v3/8cUHB3KcajIU8/f2JPyoUQGIloh0i1rOAwm1P6fD1q7ahRQ3rV0V00kuk806yHJZWlb5NL/4x+uHRkQ7jnUlenIfNhiLa98lUoBlvw6dHI5rREq/B2blZDt39iZV6z9JzIwonQglkXz74piQpx+nQcHDuoGeZx60ttSviOtg3UfODAAAwKfn+H2CGCgT+cgpDTk7OnM/Pzc2VJJ06dSqs+xw+fHjWf1566aXwFg4g4aI9Kjw3y6Fvf/ydYf2tfSyPRo60PWVwOKj6xl1q6+4N63U7Oo+ptqElrA/TriyHvnn9O/TKnR/QT2+pDvnI4ZlEM3PEHxhRp8+v3YffUqfPL39gRG3dvfrcj34f1ZpiJdL3SfpLoBmNnKzE/F+fLzbt1u9ePy7bDn2HWDwGZ+dmOfTADZfp6necH1HAE+7vz3BwVLlZDq2+8G1Jd3KTiZ+vaOcHAQAQLXbyJAmX6y8fcIaHh+d8/tDQkCRp3rx5Yd1nrlYwAKlp7KjwSMKRodOj2vzzV8Nud4pFa0O07SmDw0FtbnpVT29cE1JoFWmgFDg9qn/81V5VXlCoqpJCba1dGfGg5khmjszWGuOwJEtSMIlH14T7Po0ZCzSj+V5/fd079JXH9sR9xk1PbyCslrV4DM7OyXLoF3/rDbuNbEykvz9Dp0fV/qc+/fjmd6moICdpTm4y8fNlYn4QAADRYCdPknC73eOPQ2nBGhgYkBRaaxeAzDB2VHgkfxM91kazo/NYyK8x1ZIwsY6J9pT9Pr9au+ZunzIVKNm2PR6yhbubypXl0J0fvkSlRXkhv6atu1c1d2/Xp+5/UU+19UyZHTRqJ3fAMybU9+lskX6vx+a7XHdpSUSvNyXU37VYD87OzXLoP6IIeEz8/tz5RLvKFxZo5eJztOQ8d1LMsYn25yveu48AADgbIU+ScLlcKioqkjT3CVhvvvnmeMjDIGUAE1WVFGrLx1coN4KWlHDbaGLR2mCqPSWUOqYDpUhCtsDpUf2//7lHK7/2G33uR7vmbOeJpLUsmUX6fof7vV7mcaup3js+ByiaQNSEUH7XYjk4Oy/HqQduuCzigEeKbyAbb9H+fAEAkEiEPEnkkksukSQdOHBAp0+fnvF5r7322vjjiy++OObrApA6bNvW5p+/GvGx3xN3p8wl2llAZ7c2mGxPebq9R/7AyKzPiUWgVFVSqOaNV+onG6p1zTuKQ55bNHZS2Kfuf1E1d2+f9sN/oo7SjqVQ3qeZzPW9nmu+Syivv3LpuRGtLRRz/a6ZHm4+xlQgEc9ANhGi/fkCACBRmMmTRN7znvdox44dGhgY0K5du/Sud71r2uc999xz44+vuOKKeC0PQAow+bfr3vKiOZ8b6Syg6VobTLanBEdt+foCM7Z/xCJQGruXZVnylhfJW14kf2BEv95zVP/wRHvIwdt0J1DF+yjteJnrfZrL2d9rX18grPkuc71eklZ+7Tcxa5ua7XdtbLi5qXt/8BKPPnvFRWEfjT6dWP7+JJNof74AAEgEdvIkkeuuu2788UMPPTTtc0ZHR/XDH/5QknTOOefoqquuisfSAKSIRPztuqnWBtPtKbMdWR2LQGk6h04M6mu/2hv2zqqz23nidZR2IkRytPh03K5sLTnPHfF8l+lePzZgPJZm+l0zee8PXuLRfZ+5TN7yIiNDgeP1+5NMov35AgAgXgh5ksjll1+uNWvWSJIefPBBtbS0THnOli1btG/fPknSbbfdpuxs/k8GgDPi3e40kYnWBtPtKQW5M9eLR6BkcrBzsra0mDDb+5QMTA0Yn8lsv2um7v3ZKy4yUmdMPANZAAAQHtq1ksw999yjK664QqdOndIHP/hBfeUrX9FVV12lU6dO6ac//anuu+8+SVJFRYU2b96c4NUCSCbxbHeaTrStDSbbU7Ic1ni7zXTiESiZap37P6+9EfOjtBNlrvcpGYwNGI/VTqrZftdM3Pvs4eYmxDOQBQAA4SHkSTKXXnqpfvazn6murk59fX36yle+MuU5FRUV+vWvfz3p2HUASKa/XR9rdQn3NTWVHm3b0xPxfcfUVBbPev94BEqmdt888ruDMT1KO5Hmep+SwdiA8dqGlpjNRJrpdy3ae5893NyUeAayAAAgPLRrJaGPfOQj+sMf/qAvfvGLqqioUF5ens455xxddtll+uY3v6lXXnlFS5YsSfQyASSZdPjbdVPtKXPVMTnvZLqgwmTr3PMHjhupk4xi3QplytiA8UhPkpvLbL9rkd57uuHmpsT69wcAAESOkCdJlZaWauvWrdq/f78GBgb05ptv6uWXX9btt9+uvLy8RC8PQBIqLnQpxBO75zTxb9f9gRF1+vzaffgtdfr8ER95HYqx9pRohNqeEstAyWTrXJpu4olJG1EshTtgPFSh7GQxNdzcpHgFsgAAIDy0awFAmjh0YlB5OVnqHzodda0PXuLRnu5eNbYc0jN7fZMCC6fDUk2lR3XVpfKWmTmtZ0w821NiOe/EdOucw0qvsCdWbUSxNjZgvLXrpL74s1fU0zcUdc1Qd7JMvHdj60E1t0/+vcxyWKqpLFZddamRY9LnkqzzggAAyHSWbdtp9H8bEa0jR45o8eLFkqTDhw9r0aJFCV4RgFDs6Dym+sZdxmaGLHrbPB1589Scz6vwFGhr7UrjLSGRfD1j7Snh7F5o6+6NKlBqqvdO+7V3+vz6wHe2h11zJlcuPVfbO5OrbevtC/L0f08Ohv26SN6nZPS714/rU/e/GHWdn2yolre8KOzXRTLc3LRY/f4AAJApYvH5m3YtAEhxbd29RgMey1JIAY8kdfj6VdvQoh2dx4zce0y82lNiNe9kbDCtCVkOSze8+0IjtUx68IZV+smGal2xJPSAIh5tRPESz9bC6bhd2VpynlsrF5+jJee5EzLXJhnnBQEAkOkIeQAghdm2rU1Nu42e+hPu/s7B4aDqG3eprbvX2Bqkv7Sn/GRDta55R/GU0CTLYelD7zhfP9lQrac3ron4A2MsAiXTg2nft/w847NgopHlsFRcOE/e8iL96OZq/eEfPqBvf/ydend50ZS5UKbep2Qz1loY6TDmVG1ZO1syzgsCACCT0a6FSWjXAlKLqZYR6cwOnmj+F2GZx62nN66J2YfWWLen2LZtdN6J6XaeaFpjTPvQO87X9z79V9NeS4Y2oniKV2thsjP9+wMAQCaIxedvBi8DQAp7tPWQkTrzsp06NRJdeLDf51dr18mI5ouEwu3KjmlYYFmWvOVF8pYXGQkqTA+mHWuNCTdQcDos2bZtdHDzbCcixfp9SjZjO1k2Ne0O6b1e5nFrS+2KtNnRNMb07w8AAIgMIQ8ApCh/YETN7T4jtQJRBjxjHm09FLOQJ55MBBWxOCks0kChtChPvr6A/IHT2viz3Tp0IvyByRNrciLSZMl28lWiZVrQBwBAMiHkAYAU1dMbmPRBMhqmNnk83d4jf2CED3h/Funum9kG00YaKIy9J9/71F/F5Yj6TMNOFgAAkAwIeQAgRQ0kwWyWswVHbfn6AnygnSAW7TzRBAqxCJ4wGTtZAABAohDyAECKyo/wVJ9Y6x9KvvAp0WLZzhNJoMAcGQAAgPREyAMAKaq40CWnwzLWsmVKQW5yhk+JlmztPMyRAQAASD+EPACQotyubNVUerRtT0/UtSyZmcuT5bDkme8yUCm9JUs7T7IFTwAAAIiOI9ELAABEbrajrMNx+UVvM1KnprKYYCBFuV3ZWnKeWysXn6Ml57l5HwEAAFIQIQ8ApDBvWZEqPAVR1VjmcesL719qZD2mQicAAAAA4SPkAYAUZlmWttauVF6EQ5jHjsR+d/m5RsKi6rIFUdUAAAAAEDlCHgBIcWNHYocb9Ew8EttUWMRwXgAAACBxCHkAIIb8gRF1+vzaffgtdfr88gdGYnKfsSOxQ92Ns8zjVlO9V2uWLhz/MxNhUSaK13sMAAAAzIXTtQDAMNu21dJ1Qo0th/TM3snHUjsdlmoqPaqrLpW3rMjozhcTR2KPhUWbmnarw9c/5z2XedzaUrsi4wKeRL3HAAAAwGws27ZNnJqLNHHkyBEtXrxYknT48GEtWrQowSsCUktbd2/IAUmFp0Bba1fGLCCJ5khs27ajCovSWTK9xwAAAEhdsfj8TciDSQh5gMjt6Dym+sZdGhwOhvyasVaniW1TySaasCjdpOt7DAAAgPiLxedvZvIAgAFt3b1hf/iXpMHhoOobd6mtuzdGK4ue25WtJee5tXLxOVpynjtjA550fo8BAACQHgh5ACBKtm1rU9PusD/8jxkcDmpz06tiY2Xy4j0GAABAKiDkAYAotXSdCGk+y2z2+/xq7TppaEUwjfcYAAAAqYCQBwCi9GjroaSqA/N4jwEAAJAKCHkAIAr+wIia231Gaj3d3iN/YMRILZjDewwAAIBUQcgDAFHo6Q1MOl48GsFRW76+gJFaMIf3GAAAAKmCkAcAojAQ4SDemfQPma2H6PEeAwAAIFUQ8gBAFPJznEbrFeSarYfo8R4DAAAgVRDyAEAUigtdcjosI7WyHJY8811GasEc3mMAAACkCkIeAIiC25WtmkqPkVo1lcVyu7KN1II5vMcAAABIFYQ8ABABf2BEnT6/dh9+S1ctO89Izbrq0pDv2enzc0pTHM313sS7DgAAADCdrEQvAABShW3bauk6ocaWQ3pmr8/YiUuStMzjVnXZgrDu6XRYqqn0qK66VN6yIlmWmZYiTOUtK1KFp0Advv6Ia8z0HgMAAACmEPIAQAjaunu1qWl3VB/yZ5KX49SW2hVTQpq57hkctbVtT4+27elRhadAW2tXqqqk0Pj6IFmWpa21K1Xb0KLBCE7bmuk9BgAAAEyiXQsA5rCj85hqG1piFvA0rF81JZwJ954dvn7VNrRoR+cx42vEGVUlhWpYv0p5YZ62NdN7DAAAAJhGyAMAs2jr7lV9466Idm/MZZnHraZ6r9YsXWjknoPDQdU37lJbd6/JZWKCNUsXqqneqwpPQUjPn+k9BgAAAGKBdi0AackfGFFPb0ADw0Hl5zhVXOgK+1Qj27a1qWm30YAny2GpprJYddWlqi5bMKV9J9p7Dg4HtbnpVT29cQ2tQTFSVVKo5o1XqrXrpBpbD6q5ffKspLneYwAAACBWCHkApA3TQ4pbuk4YadH69t+s0BJPgQpynfLMnz1sMnHP/T6/WrtOylteFFUdzMyyLHnLi+QtL5I/MCJfX0D9Q8GQ3mMAAAAgVgh5AKSFWAwpfrT1kJG1Pbv/Df3NZYtCeq6pez7aeoiQJ07crmxCHQAAACQFZvIASHmxGFLsD4youd1nZH1Pt/fIHxiZ83mJuCcAAACA9EHIAyClxWpIcU9vYFK7VzSCo7Z8fYE5n5eIewIAAABIH4Q8AFKWbdv64s9eiXpIsW1PDVYGDJ+m1T80d71E3BMAAABA+iDkAZCyfvzS/1XnGwNR1RgbUny2/BxnVHXPVpA7d71E3BMAAABA+iDkAZCSdnQe051PtBupNd2w4+JCl5wOM0dfZzkseea75nxeIu4JAAAAIH0Q8gBIOW3dvbrlh7uMza+Zbkix25WtmkqPkfo1lcUhnb6UiHsCAAAASB+EPABSim3b2tS0W6dGzM2bmWlIcV11qZH64dRJxD0BAAAApAdCHgAppaXrRMhHpYdjuiHF3rIiVXgKoqq7zONWddmCkJ+fiHsCAAAASA+EPABSynTzc0yYbkixZVnaWrtSeREORM7LcWpL7QpZVuhzdhJxTwAAAADpgZAHQMrwB0bU3O4zXtdhacYhxVUlhWpYvyrs0CUvx6mG9atUVVIY9noScU8AAAAAqY+QB0DK6OkNGBu2PJFnvmvWIcVrli5UU7035DaqZR63muq9WrN0YcRrSsQ9AQAAAKS2rEQvAABCNTBsbtjyRL6+gPyBkVmDnqqSQjVvvFKtXSfV2HpQze2+SYFTlsNSTWWx6qpLVV22wEi7VCLuCQAAACB1EfIASBn5Ec6pmcuofSbomevIccuy5C0vkre8SP7AiHx9AfUPBVWQ65xzN1CkEnFPAAAAAKmJkAdAyigudMnpsGLSsjXd6Vqzcbuy4x6wJOKeAAAAAFIHM3kApAy3K1s1lZ6Y1J7udC0AAAAASCWEPABSSl11qfGaWQ5rxtO1AAAAACBVEPIASCnesqKQT5wKVU1lMW1QAAAAAFIeIQ+AlGJZlrbWrlSewSHMsdgdBAAAAADxRsgDIOVUlRSqYf0qI0HPMo9b1WULDKwKAAAAABKLkAdASlqzdKGa6r16+4K8iGvk5Ti1pXaFLMsyuDIAAAAASAxCHgApq6qkUM996b36yjXL5Qwzp8nLcaph/SpVlRTGZnEAAAAAEGeEPABSmmVZuuXKcj3x+feofGF+SK9Z5nGrqd6rNUsXxnh1AAAAABA/WYleAACYUFVSqP+1aa1au06qsfWgmtt9Co7a49ezHJZqKotVV12q6rIFtGgBAAAASDuEPADShmVZ8pYXyVteJH9gRL6+gPqHgirIdcoz38Ux6QAAAADSGiEPgLTkdmUT6gAAAADIKMzkAQAAAAAASAPs5AEQM/7AiHp6AxoYDio/x6niQlqmAAAAACBWCHkAGGXbtlq6Tqix5ZCe2Tt5+LHTYamm0qO66lJ5y4oYfgwAAAAABhHyADCmrbtXm5p2q8PXP+314KitbXt6tG1Pjyo8Bdpau1JVJYVxXiUAAAAApCdm8gAwYkfnMdU2tMwY8Jytw9ev2oYW7eg8FuOVAQAAAEBmIOQBELW27l7VN+7S4HAwrNcNDgdV37hLbd29MVoZAAAAAGQOQh4AUbFtW5uadocd8IwZHA5qc9Orsm177icDAAAAAGZEyAMgKi1dJ0Ju0ZrJfp9frV0nDa0IAAAAADITIQ+AqDzaeiip6gAAAABApiLkARAxf2BEze0+I7Webu+RPzBipBYAAAAAZCJCHgAR6+kNKDhqZpZOcNSWry9gpBYAAAAAZCJCHgARG4hw2PJM+ofM1gMAAACATELIAyBi+TlOo/UKcs3WAwAAAIBMQsgDIGLFhS45HZaRWlkOS575LiO1AAAAACATEfIAiJjbla2aSo+RWjWVxXK7so3UAgAAAIBMRMgDICp11aVJVQcAAAAAMhUhD4CoeMuKVOEpiKrGMo9b1WULDK0IAAAAADITIQ+AqFiWpa21K5UX4RDmvBynttSukGWZme0DAAAAAJmKkAdA1KpKCtWwflXYQU9ejlMN61epqqQwRisDAAAAgMxByAPAiDVLF6qp3hty69Yyj1tN9V6tWbowxisDAAAAgMyQlegFAEgfVSWFat54pVq7Tqqx9aCa230Kjtrj17Mclmoqi1VXXarqsgW0aAEAAACAQYQ8AIyyLEve8iJ5y4vkD4zI1xdQ/1BQBblOeea7OCYdAAAAAGKEkAdAzLhd2YQ6AAAAABAnhDwAjPMHRtTTG9DAcFD5OU4VF/5lB89s1wAAAAAAkSPkARC26YKagtwstXSdUGPLIT2zd/IsHoclrb7wbbIl7Tr01qRrToelmkqP6qpL5S0rYk4PAAAAAESIkAdASGzbnjXEyctxqn8oOO1rR23pxT++Oe214KitbXt6tG1Pjyo8Bdpau5Ij1QEAAAAgAoQ8AObU1t2rTU271eHrn/b6qK0ZA55wdPj6VdvQoob1qzhaHQAAAADC5Ej0AgAktx2dx1Tb0DJjwGPa4HBQ9Y271NbdG5f7AQAAAEC6IOQBMKO27l7VN+7S4HD0u3TCMTgc1OamV2Xb9txPBgAAAABIIuQBMAPbtrWpaXfcA54x+31+tXadTMi9AQAAACAVEfIAmFZL14m4tWjN5NHWQwm9PwAAAACkEkIeANNKhoDl6fYe+QMjiV4GAAAAAKQEQh4AU/gDI2pu9yV6GQqO2vL1BRK9DAAAAABICYQ8AKbo6Q0oOJocQ49NHM0OAAAAAJmAkAfAFAMJGrY8nYJcZ6KXAAAAAAApgZAHwBT5OckRrGQ5LHnmuxK9DAAAAABICYQ8AKYoLnTJ6bASvQzVVBbL7cpO9DIAAAAAICUQ8gCYwu3KVk2lJ9HLUF11aaKXAAAAAAApg5AHwLQSHbAs87hVXbYgoWsAAAAAgFRCyANgWt6yIlV4ChJy77wcp7bUrpBlJb5lDAAAAABSRcaHPO9973tlWVZI/4Sira1N9fX1Ki8v17x587Rw4UKtWbNG3//+93X69OmQ1/XUU09p3bp1WrRokXJzc7Vo0SKtW7dOTz31VKRfKhAWy7K0tXal8uI8hDkvx6mG9atUVVIY1/sCAAAAQKqzbNu2E72IRHrve9+r5557LqTnzvWtuv/++/X5z39ew8PD016//PLL9etf/1rnnnvujDVGR0d1yy236MEHH5zxOTfffLMaGhrkcJjP6I4cOaLFixdLkg4fPqxFixYZvwdSy47OY6pv3KXBOByrvszj1pbaFQQ8AAAAANJeLD5/Z0VdIU1cdtlleuihhyJ+/bZt2/S3f/u3Gh0dlcfj0Ve/+lW9613v0smTJ3X//ffrP//zP/XSSy9p3bp1+u1vfyunc/rdEV/96lfHA55LL71Ut99+u8rLy/X666/rW9/6ll555RU98MADWrhwob7+9a9HvF4gVGuWLlRTvVebmnarw9c/5/MLcrM0OHxaoxMyUaclrb5wgWxJOw+9qeCEi1kOSzWVxaqrLlV12QJatAAAAAAgQuzk+fNOnrVr1+q3v/1tRDVGRka0fPlydXV1af78+fr973+v8vLySc/5b//tv+nf/u3fJEkPPfSQbrzxxil1Ojo6VFlZqdOnT+uyyy7T9u3bNW/evPHrg4ODWrt2rXbu3KmsrCzt27dPS5YsiWjNM2EnD2Zi27Zau06qsfWgmtt9swY1/UOn5esLqH8oqIJcpzzzXeNHofsDIzNeAwAAAIBMwU6eJPXYY4+pq6tLknTHHXdMCXgk6a677tJPfvITvfnmm7rrrrumDXnuvvvu8bk9995776SAR5Ly8vJ07733yuv16vTp0/rOd76j733ve+a/IGAalmXJW14kb3nRnEGN25U9Y3Az2zUAAAAAQOQyfvCyCY8//vj44+nCG+lMQFNbWytJ2rt3rzo6OiZdt21bTzzxhCRp+fLlqq6unrZOdXW1li1bJkl64okn5pwTBMSC25WtJee5tXLxOVpynpvQBgAAAACSACGPAc8//7wkadmyZSouLp7xeWvXrh1//MILL0y69sc//lF/+tOfpjxvtjrd3d06ePBgJEsGAAAAAABphpDnz1577TW9613v0jnnnCOXy6VFixbp2muv1Q9/+EONjIzM+Lr+/n4dPnxY0pkdOLOZeH3fvn2Tru3du3fa54VbBwAAAAAAZCZm8vyZz+eTz+cb//fu7m51d3frl7/8pb75zW/qF7/4hS6++OIprzty5Mj447mGJI0NVJI0HgyZrjOXifeZztGjR8OqBwAAAAAAkkPGhzwOh0Pvf//7dc0112jFihUqKiqS3+/X73//ezU0NGjfvn3au3evrrrqKr300kt6+9vfPun1fr9//HFBQcGs98rPzx9/3N8/+ShqU3XmMjEgAqQzp1319AY0MBxUfo5TxYWcdgUAAAAAqSjjQ57//M//1DnnnDPlz9esWaPPfe5z2rBhgx555BH5fD5t3LhR//mf/znpeYFAYPxxTk7OrPfKzc0df3zq1KmY1AFCYdu2WrpOqLHlkJ7ZO/k4dKfDUk2lR3XVpfKWFcmyrASuFAAAAAAQqpQIeUx8yHzooYemPflquoBnTHZ2th544AG1trZq//79euyxx9Td3a2SkpLx57hcrvHHw8PDs65haGho/PHZx6ObqjOXudq7jh49qssvvzysmkgtbd292tS0Wx2+6XeBBUdtbdvTo217elThKdDW2pWqKimM8yoBAAAAAOFi8PIcsrKydNNNN43/+3PPPTfputvtHn88V+vUwMDA+OOzW7JM1ZnLokWLZv3n/PPPD6seUsuOzmOqbWiZMeA5W4evX7UNLdrReSzGKwMAAAAARCsldvKYOEEqmvDikksuGX/c3d096drEXT1zDTWeuIvm7Nk4E4ctR1MHmElbd6/qG3dpcDgY1usGh4Oqb9ylpnovO3oAAAAAIImlRMgz15HisTZbu5jb7dbixYt1+PBhvfbaa7PWmXj97JO6JgZJ0dQBpmPbtjY17Q474BkzOBzU5qZX9fTGNczoAQAAAIAkRbtWCPbu3Tv++IILLphy/T3veY8kaf/+/erp6ZmxzsRWryuuuGLStYsuumi89tktYWfbvn27pDO7iC688MLZFw9Iauk6EXKL1kz2+/xq7TppaEUAAAAAANMIeeZw+vRp/eAHPxj/9yuvvHLKc6677rrxxw8//PC0dQYHB9XU1CTpzK6dioqKSdcty9K1114r6cxOndbW1mnrtLa2ju/kufbaa9lVgZA82nooqeoAAAAAAMzL6JDn2Wef1VtvvTXj9ZGREd18883jM4E+8pGPTDsDZ926dSorK5MkfeMb39Drr78+5Tlf+tKX9Oabb44/ns7GjRvldDolSbfeeuuU49FPnTqlW2+9VdKZgdAbN26c/QsEJPkDI2pu9xmp9XR7j/yBESO1AAAAAABmZXTI88gjj2jx4sX69Kc/rfvvv1/bt2/X7t279fzzz+uee+7RypUr9cgjj0iSzjvvPN1zzz3T1snOzta9994rh8Ohvr4+XXHFFfrud7+rl156Sc3Nzfqbv/kb/du//ZukM61d69evn7ZORUXFeAC0c+dOXXHFFfrZz36mnTt36mc/+5muuOIK7dy5U9KZoGjp0qWmvyVIQz29AQVHbSO1gqO2fH0BI7UAAAAAAGalxODlWOrv79ePf/xj/fjHP57xOe94xzv005/+VBdddNGMz7nmmmv0/e9/X5///Ofl8/nGd9xMdPnll+uxxx4b360znf/5P/+n3njjDf3gBz/QK6+8ok9+8pNTnnPTTTfpn//5n+f4yoAzBiIctjyT/iGz9QAAAAAAZmR0yPPlL39ZK1euVEtLi/bu3atjx47p5MmTys3Nlcfj0WWXXaa/+Zu/0bp162YNZsZs2LBBXq9X//qv/6r//b//t/70pz8pPz9fF198sT796U/r5ptvVlbW7N9yh8OhBx98UNdff73uu+8+vfzyyzp+/LjOPfdcrV69WvX19br66qtNfQuQIP7AiHp6AxoYDio/x6niQpfcruyY3Cs/Z+6f3XAU5JqtBwAAAAAww7Jt20wfB9LCkSNHxucOHT58WIsWLUrwitKHbdtq6TqhxpZDemavb1ILldNhqabSo7rqUnnLiowO1PYHRrTya78x0rKV5bD0yp0fiFkgBQAAAACZIhafvzN6Jw8QL23dvdrUtHvGY8yDo7a27enRtj09qvAUaGvtSlWVFBq5t9uVrZpKj7bt6Ym6Vk1lMQEPAAAAACSpjB68DMTDjs5jqm1omTHgOVuHr1+1DS3a0XnM2BrqqkuTqg4AAAAAwDxCHiCG2rp7Vd+4S4NhDj8eHA6qvnGX2rp7jazDW1akCk9BVDWWedyqLltgZD0AAAAAAPMIeYAYsW1bm5p2hx3wjBkcDmpz06syMTbLsixtrV2pvAiHMOflOLWldoXRWUEAAAAAALMIeYAYaek6EXKL1kz2+/xq7TppZD1VJYVqWL8q7KAnL8ephvWrjM0IAgAAAADEBiEPECOPth5KqjqStGbpQjXVe0Nu3Vrmcaup3qs1SxcaWwMAAAAAIDY4XQuIAX9gRM3tPiO1nm7vkT8wYuxUq6qSQjVvvFKtXSfV2HpQze2Tj3PPcliqqSxWXXWpqssW0KIFAAAAACmCkAeIgZ7ewKTgJBrBUVu+voDRo8sty5K3vEje8iL5AyPy9QXUPxRUQa5TnvkujkkHAAAAgBREyAPEwECEw5Zn0j9ktt5Eblc2oQ4AAAAApAFm8gAxkB/hKVYzKcg1Ww8AAAAAkH4IeYAYKC50yekwM8smy2HJM99lpBYAAAAAIH0R8gAx4HZlq6bSY6RWTWUx7VQAAAAAgDkR8gAxUlddmlR1AAAAAADpjZAHiBFvWZEqPAVR1Vjmcau6bIGhFQEAAAAA0hkhDxAjlmVpa+1K5UU4hDkvx6kttStkWWZm+wAAAAAA0hshDxBDVSWFali/KuygJy/HqYb1q1RVUhijlQEAAAAA0g0hDxBja5YuVFO9N+TWrWUet5rqvVqzdGGMVwYAAAAASCdZiV4AkAmqSgrVvPFKtXadVGPrQTW3+xQctcevZzks1VQWq666VNVlC2jRAgAAAACEjZAHiBPLsuQtL5K3vEj+wIh8fQH1DwVVkOuUZ76LY9IBAAAAAFEh5AESwO3KJtQBAAAAABhFyAMkgD8wop7egAaGg8rPcaq4kJ08AAAAAIDoEPIAcWLbtlq6Tqix5ZCe2Tt5Jo/TYamm0qO66lJ5y4qYyQMAAAAACBshDxAHbd292tS0Wx2+/mmvB0dtbdvTo217elThKdDW2pUcnw4AAAAACAtHqAMxtqPzmGobWmYMeM7W4etXbUOLdnQei/HKAAAAAADphJAHiKG27l7VN+7S4HAwrNcNDgdV37hLbd29MVoZAAAAACDdEPIAMWLbtjY17Q474BkzOBzU5qZXZdv23E8GAAAAAGQ8Qh4gRlq6ToTcojWT/T6/WrtOGloRAAAAACCdEfIAMfJo66GkqgMAAAAASG+EPEAM+AMjam73Gan1dHuP/IERI7UAAAAAAOmLkAeIgZ7egIKjZmbpBEdt+foCRmoBAAAAANIXIQ8QAwMRDlueSf+Q2XoAAAAAgPRDyAPEQH6O02i9glyz9QAAAAAA6YeQB4iB4kKXnA7LSK0shyXPfJeRWgAAAACA9EXIA8SA25WtmkqPkVo1lcVyu7KN1AIAAAAApC9CHiBG6qpLk6oOAAAAACC9EfIAMeItK1KFpyCqGss8blWXLTC0IgAAAABAOiPkAWLEsixtrV2pvAiHMOflOLWldoUsy8xsHwAAAABAeiPkAWKoqqRQDetXhR305OU41bB+lapKCmO0MgAAAABAuiHkAWJszdKFaqr3hty6tczjVlO9V2uWLozxygAAAAAA6SQr0QsAMkFVSaGaN16p1q6Tamw9qOZ2n4Kj9vj1LIelmspi1VWXqrpsAS1aAAAAAICwEfIAcWJZlrzlRfKWF8kfGJGvL6D+oaAKcp3yzHdxTDoAAAAAICqEPEACuF3ZhDoAAAAAAKOYyQMAAAAAAJAGCHkAAAAAAADSACEPAAAAAABAGmAmDyDJHxhRT29AA8NB5ec4VVzIIGQAAAAAQGoh5EHGsm1bLV0n1NhySM/snXykudNhqabSo7rqUnnLijjSHAAAAACQ9Ah5kJHaunu1qWm3Onz9014PjtratqdH2/b0qMJToK21K1VVUhjnVQIAAAAAEDpm8iDj7Og8ptqGlhkDnrN1+PpV29CiHZ3HYrwyAAAAAAAiR8iDjNLW3av6xl0aHA6G9brB4aDqG3eprbs3RisDAAAAACA6hDzIGLZta1PT7rADnjGDw0FtbnpVtm3P/WQAAAAAAOKMkAcZo6XrRMgtWjPZ7/OrteukoRUBAAAAAGAOIQ8yxqOth5KqDgAAAAAAJhHyICP4AyNqbvcZqfV0e4/8gREjtQAAAAAAMIWQBxmhpzeg4KiZWTrBUVu+voCRWgAAAAAAmELIg4wwEOGw5Zn0D5mtBwAAAABAtAh5kBHyc5xG6xXkmq0HAAAAAEC0CHmQEYoLXXI6LCO1shyWPPNdRmoBAAAAAGAKIQ8ygtuVrZpKj5FaNZXFcruyjdQCAAAAAMAUQh5kjLrq0qSqAwAAAACASYQ8yBjesiJVeAqiqrHM41Z12QJDKwIAAAAAwBxCHmQMy7K0tXal8iIcwpyX49SW2hWyLDOzfQAAAAAAMImQBxmlqqRQDetXhR305OU41bB+lapKCmO0MgAAAAAAokPIg4yzZulCNdV7Q27dWuZxq6neqzVLF8Z4ZQAAAAAARC4r0QsAEqGqpFDNG69Ua9dJNbYeVHO7T8FRe/x6lsNSTWWx6qpLVV22gBYtAAAAAEDSI+RBxrIsS97yInnLi+QPjMjXF1D/UFAFuU555rs4Jh0AAAAAkFIIeQBJblc2oQ4AAAAAIKUxkwcAAAAAACANEPIAAAAAAACkAUIeAAAAAACANEDIAwAAAAAAkAYIeQAAAAAAANIAIQ8AAAAAAEAaIOQBgP+/vTsPi+JK2wZ+N7Ts4IILIoqC4BKNGgE1SoBoNOIYRA3qRINGDNHoxJlEs5hEnZnELXljNEbBBY2J67hv75vEwR1F1JlERRFEBYyETZFFmm7q+4OPCkg39FI0Tff9uy6uq6SK5zld5emqfvrUKSIiIiIiIjMgb+wGEBnq8ZNyPHj0BMUKFRxtrOHW3A7Ods0au1lERERERERERsUiDzVJgiAg4XYetibcxY/XsqESBHGdtUyGEb3aYfJATwzycoVMJtM6LgtGRERERERE1FSxyENNztWsR/jbrv8gJbtI7XqVIODorw9w9NcH8G3nhP+J6IteHZprjFejYHQ9G6qKagUjKxlGPKNfwYiIiIiIiIjImFjkoSbl9K0czPguCU/KK7TaPiW7COPXncP61/0Q6NOm1vp6C0YVuhWMiIiIiIiIiBoLJ16mJuNq1iNEbdG+wFPlSXkForYk4WrWoxq/P30rBxExCRoLPE9LyS5CREwCTt/K0Sk/ERERERERkTGwyENNgiAImPXDZZQpdSvwVClTVuDtbZch/P+5e65mPUL01ksoUah0ilOiUCF666VaBSMiIiIiIiKixsYiDzUJCWl5uJdfYlCMu3klOH87D4Ig4G+7/qNzgadKiUKFd3f9VywYEREREREREZkCFnmoSVh5/JY0cX6+hYTbeVrfoqXJzezHOH87X5I2EREREREREUmBRR4yeY+flONiujQFlcT0fMSdTZck1vfn70oSh4iIiIiIiEgKLPKQyUv7vQhS3RglADh+/XdJYv3vtQd4/KRcklhEREREREREhmKRh0xeRoFhc/E8Tb+pm2tTVQjILnwiUTQiIiIiIiIiw7DIQ02ArLEboFFRmX6TNxMRERERERFJjUUeMnkdW9o3dhM0crK1buwmEBEREREREQFgkYeaAO+2TpLFkgGwlkkzMkhuJUM7FztJYhEREREREREZikUeMnnOds0woEtLSWIN6NIKI3q1kyTWiGfc4GzXTJJYRERERERERIZikYeahL8M9ZEszuSBnpLEkioOERERERERkRRY5KEm4Xnv1ujUyrC5eTxbOWCQtysGebnCt51ht4B1a+eMgV6tDIpBREREREREJCUWeahJkMlk+Pa1/rCV6/df1lZuhTWvPQeZTAaZTIb/iegLBxv9Jk12sLHGlxF9IJNobh8iIiIiIiIiKbDIQ01Grw7NsSHSD3Y6Fnrs5FbYEOmHXh2a14gVM6W/zoUeBxtrxEzpXyMWERERERERkSlgkYealECfNvjXzOfh09ZRq+192zrhXzOfR6BPG7WxdkUP0vrWrW7tnLErepDaWERERERERESNTd7YDSDSVa8OzfHjX4Nw/nY+tp6/g/+9+gAVwh/rrWXAy73aY/JATwz0alXnbVW9OjTH/819QYz1f9eyoaoWTG4lw4hn3LSKRURERERERNSYWOShJkkmk1VOouztisdPypFd+ARFZSo42VqjnYudTo82lzIWERERERERUWNhkYeaPGe7ZpIVYqSMRURERERERGRMnJOHiIiIiIiIiMgMsMhDRERERERERGQGWOQhIiIiIiIiIjIDLPIQEREREREREZkBFnmIiIiIiIiIiMwAizxERERERERERGaARR4iIiIiIiIiIjPQZIs8RUVFOHXqFL744gtERESgS5cukMlkkMlk6Ny5s87xrl69iujoaHh7e8Pe3h5t2rRBYGAg1q1bB6VSqXWcY8eOITw8HB4eHrC1tYWHhwfCw8Nx7NgxrWMolUqsW7cOgYGBaNOmDezt7eHt7Y3o6Ghcu3ZN59dGREREREREROZPJgiC0NiN0EdISAhOnDihdp2npyfu3Lmjdaz169dj9uzZUCgUatcHBATgyJEjaN26tcYYFRUVePPNN7Fx40aN20RFRSEmJgZWVppra7m5uQgNDcXFixfVrre1tcU333yDqKgojTEMkZmZiY4dOwIAMjIy4OHh0SB5iIiIiIiIiCxZQ3z+brIjearXplq1aoXhw4fDyclJ5zhHjx7FW2+9BYVCgXbt2mHVqlW4cOECjh07hrFjxwIAEhMTER4eDpVKpTHOggULxAJPv379sH37diQmJmL79u3o168fAGDDhg34+OOPNcZQqVQIDw8XCzxjx47FsWPHcOHCBaxatQpt27ZFWVkZoqOjdRoZRERERERERETmr8mO5ImNjYWzszP8/f3RtWtXAEDnzp1x9+5drUfylJeXo3v37rh9+zZcXFxw+fJleHt719jm7bffxrfffgsAiIuLw9SpU2vFSUlJwTPPPAOlUgk/Pz+cOnUK9vb24vqSkhIEBQUhKSkJcrkcycnJYpur27RpE6ZPnw4AmDVrFtasWVNjfWpqKvr374/CwkJ07doVycnJkMvl9b5OXXAkDxEREREREVHD40ieat58801MmjRJbbFEW/v27cPt27cBAB9++GGtAg8ArFixAi1bthSX1Vm5cqU4b8/q1atrFHgAwMHBAatXrwZQOd/OV199pTbOF198AaByZJK6XF27dsWHH34IoLLgs2/fvnpfIxERERERERFZhiZb5JHC/v37xWV1I3SAygJNREQEAOD69etISUmpsV4QBBw4cAAA0L17dwwcOFBtnIEDB6Jbt24AgAMHDuDpAVQpKSlITk4GAERERMDBwUFtnOrtZJGHiIiIiIiIiKpYdJHnzJkzAIBu3brBzc1N43ZBQUHi8tmzZ2usS09Px/3792ttV1ecrKysWreTVbWlvjhubm7w9fVV2xYiIiIiIiIislzSTujShBQVFSEjIwNA5QiculRfXzXapsr169fVbqdNnC5duugdJyUlBRkZGSguLoajo2Od21eXmZlZ5/rffvtN61hEREREREREZDostshTvdhR3+RGVRMhARALQ6YQRxAEZGZmireBaaN6G4iIiIiIiIjIfFjs7VqPHz8Wl+t79Hr1kTJFRUUmHYeIiIiIiIiILJPFjuR58uSJuGxjY1Pntra2tuJyaWmpScepz9MjiJ7222+/ISAgQKeYRERERERERNT4GrTII5PJDI4RFxen8clXhrCzsxOXFQpFnduWlZWJy08/Hr2h4lT/ty5x6lPfrWBERERERERE1DRZ7O1azs7O4nJ9tzwVFxeLy0/fSmVqcYiIiIiIiIjIMjXoSJ6nn0Slj/bt20vQkto6dOggLtf3xKnqtzg9PXFx9ZExUsZp3bp1vXFkMpnkI3OUSqW4zCdtERERERERETWM6p+5q38WN0SDFnnqexR4Y3J2dkbHjh2RkZGBGzdu1Llt9fU9evSosa5nz55qtzM0Tt++feuN07FjR50en66NnJwccZlz8xARERERERE1vJycHHTu3NngOBZ7uxYADBkyBABw8+ZNPHjwQON2J0+eFJcHDx5cY12XLl3g7u5eazt1Tp06BaByFNHTB6+qLfXFefDgAVJSUtS2hYiIiIiIiIgsl8U+XQsAxowZg+3btwMANm/ejA8++KDWNiUlJdi1axeAytE2vr6+NdbLZDKEhYVh7dq1uHHjBs6fP4+BAwfWinP+/HlxBE5YWFitSal9fX3Ro0cPJCcnY9euXfjyyy/h4OBQK87mzZvF5fDwcN1esBZ69+6NxMREAECbNm0gl8trPHErMTGxwW6hI+PjsTVPPK7micfVPPG4mi8eW/PE42qeeFzNU1M4rkqlUrybpnfv3pLEtOgiT3h4OLy8vHD79m0sWbIEr776Kry9vWtsM2/ePBQUFIjL6sydOxexsbFQqVSYM2cOTp06VeOpV6WlpZgzZw4AQC6XY+7cuWrjvPfee5g+fTry8/Mxf/58fPPNNzXWp6WlYcmSJQCArl27NkiRx87ODv7+/hrXt2/fnk/oMlM8tuaJx9U88biaJx5X88Vja554XM0Tj6t5MuXjKsUtWtU12SJPamoqzpw5U+N3VU+lKioqqjHiBQBefvlluLm51fhds2bNsHr1aowePRqFhYUYPHgwPv74YwQEBKCgoADr16/Hnj17AFTeTjVlyhS1bfH19cW8efOwdOlSJCUlYfDgwXj//ffh7e2NtLQ0LFu2DFeuXAFQWSjy8fFRGycyMhKbNm3C2bNnsWbNGjx48AAzZsxAy5YtkZiYiH/84x8oLCyElZUVVq1aBbm8yR4+IiIiIiIiIpJYk60SnDlzBtOmTVO7Li8vr9a6+Pj4WkUeAAgNDcW6deswe/ZsZGdniyNuqgsICMC+fftgbW2tsT2fffYZfv/9d2zatAlXrlzBxIkTa20zffp0/POf/9QYw9raGvv370doaCguXryIPXv2iEWmKra2tvjmm28wcuRIjXGIiIiIiIiIyPJY9MTLVWbMmIFLly5hxowZ8PLygp2dHVxdXTFkyBCsXbsWZ8+erfOR5gBgZWWFjRs34siRIwgLC4O7uztsbGzg7u6OsLAwHD16FBs2bICVVd27vHXr1jh37hy+/fZbDBkyBK6urrCzs4OXl5fYzqioKClfPhERERERERGZgSY7kmfq1KmYOnWqZPF69eqF2NhYg+OEhoYiNDTUoBhyuRwzZ87EzJkzDW4PEREREREREVkGjuQhIiIiIiIiIjIDLPIQEREREREREZkBFnmIiIiIiIiIiMyATBAEobEbQUREREREREREhuFIHiIiIiIiIiIiM8AiDxERERERERGRGWCRh4iIiIiIiIjIDLDIQ0RERERERERkBljkISIiIiIiIiIyAyzyEBERERERERGZARZ5iIiIiIiIiIjMAIs8RERERERERERmgEUeIiIiIiIiIiIzwCIPEREREREREZEZYJHHghQVFeHUqVP44osvEBERgS5dukAmk0Emk6Fz5846x7t69Sqio6Ph7e0Ne3t7tGnTBoGBgVi3bh2USqWkbd++fTuGDx8ONzc32NnZwdPTE5MnT0ZCQoKkeczRokWLxOOs7c+iRYv0ynXixIkGz0F/CA4O1np/S+XcuXOYPHkyPD09YWdnBzc3N4wYMQLbt2+XLIelu3PnDlavXo1x48bBx8cHDg4OsLOzg4eHB8aMGYMdO3ZI8h7L/iqtu3fv4t1330X37t3h6OiIVq1awd/fHytWrEBJSYlkeY4dO4bw8HB4eHjA1tYWHh4eCA8Px7FjxyTLQUBSUhL+/ve/Y/jw4eK+dnJygq+vL6ZNm4YzZ85IkkeXc/SJEyckyWnJtN3XwcHBkuTj9WvD0+VayJC+xL4qrd9//x2HDx/Gp59+ipEjR6J169bi/ps6darO8Yx1biwpKcHy5cvh7++PVq1awdHREd27d8e7776Lu3fvSprLIAJZjODgYAGA2h9PT0+dYsXGxgo2NjYa4wUEBAg5OTkGt7mkpEQIDQ3VmMfKykpYtGiRwXnM2cKFCzXuP00/27Zt0ytXfHy81jkWLlwo7Qu1QEFBQVrvbyksXLhQsLKy0phj1KhRQmlpqSS5LNXHH38syGSyeo+nv7+/cPfuXYNysb9K5+DBg4KLi4vG/efr6yvcunXLoBwqlUqYPn16nccpKipKUKlUEr0qyxUYGKhVv3j99deFsrIyg3Lpco6Oj4+X5gVaMG33dVBQkEF5eP1qPLpcC1Xt+8zMTJ3zsK9Kq679FxkZqXUcY54bb926Jfj4+GjM4+LiIhw6dMjgPFKQgyyGIAjicqtWreDn54dz586hqKhIpzhHjx7FW2+9hYqKCrRr1w4LFizAgAEDkJ+fj/Xr12Pv3r1ITExEeHg4Tpw4AWtra73b/MYbb+Do0aMAgJCQELzzzjtwd3fHr7/+is8//xxpaWlYtGgR2rdvjzfffFPvPOZs1qxZGD9+fJ3bqFQqvPDCCygsLISLiwvGjBljcN5NmzbB399f4/q2bdsanIMq+fn5IS4urkFzxMTEYPHixQAAb29vfPTRR+jduzfu37+Pr7/+GvHx8Thy5AjeeOMNbNu2rUHbYs5+++03CIIAR0dHhIeHY+jQofDx8YGdnR2Sk5OxatUqXLx4ERcvXsSwYcNw+fJlODk5GZyX/VV/V65cwYQJE1BaWgonJyd8+OGHCAkJQWlpKXbs2IH169cjJSUFo0aNQlJSEpydnfXKs2DBAmzcuBEA0K9fP8yfPx/e3t5IS0vD8uXLceXKFWzYsAFt2rTB559/LuVLtDj3798HALi7u+PVV19FYGAgOnXqBJVKhYSEBHz55ZfIysrCd999h/Lycsne83799dc613fp0kWSPATMnDkTs2bN0rje0dHRoPi8fjWeuLg4FBcX17nN9evXMWHCBADA0KFD0aFDB4Nysq9Kq1OnTujevTt+/PFHnf/WWOfGx48fY9SoUbh16xYAYMaMGZg4cSLs7e0RHx+PJUuWoLCwEBMmTMDZs2fRt29fvXNJorGrTGQ8MTExwrZt22p8m+jp6SkA2o/kUSgUgpeXl1itTE1NrbXNrFmzxIpmXFyc3u09fvy4GGf06NGCUqmssT4nJ0fo1KmTAEBo0aKFkJ+fr3cuS3f06FFxX0+fPl3vONVHBvBbjIZX9e2Vod841icvL09o3ry5AEDo1KlTrVF6SqVSGD16NI+9BObPny8sW7ZMKCwsVLteqVQKERER4r5evHix3rnYX6VRNepDLpcL586dq7V++fLlBo+IunnzpiCXywUAgp+fn1BSUlJjfXFxseDn5ye2w9BRQ5Zu1KhRws6dO2tdd1TJyckRfH19xeN68uRJvXNVHx1ADc/QvqgNXr+anvnz54vHZOvWrXrFYF+V1qeffiocOnRIePDggSAIgpCenq7zSB5jnhs/+eQTsX3Lly+vtf7s2bNiWxr6ulwb/F9q4XQt8uzcuVP8D75kyRK12xQXFwstW7YUAAg9e/bUu20jR44UO2VGRobabbZv315nhyPtTJw4UZKLVX5oNC5jFXmWLVsmHtft27er3SYjI0OwtrYWAAihoaEN2h5Ll5ubK94u27t3b73jsL8a7sKFC+I+jI6OVruNSqUSevToIX6gUygUOueZOXOmmCchIUHtNgkJCeI2s2bN0jkH6ebQoUPi/p4zZ47ecfjB0biMUeTh9atpUalUQocOHQQAgpOTk1BcXKxXHPbVhqVPkcdY50aFQiF+2dmjRw+Nt35FR0eLuRITE/XKJRVOvEw62b9/v7isaVIsBwcHREREAKgcHpmSkqJznsePH+P48eMAgGHDhsHDw0PtdmPHjoWLiwsAYN++fTrnIaCwsBAHDhwAUDm8NDAwsJFbRKamqt+7uLhg7Nixarfx8PDAsGHDAADHjx/H48ePjdU8i+Pq6opnn30WAJCWltbIrbFs1c+J06ZNU7uNlZUVXn/9dQDAw4cPER8fr1MOQRDE9+ju3btj4MCBarcbOHAgunXrBgA4cOBAjVu0SXohISHiMvshVeH1q+k5fvw4srKyAADjx4+Hg4NDI7eIpGDMc2N8fDwePXoEAIiMjISVlfoSSvXPxo3dr1nkIZ1UPU2iW7ducHNz07hdUFCQuHz27Fmd81y8eBEKhaJWrKfZ2NiInfrixYsoLy/XOZel2717N0pLSwEAU6ZMkfRJTNT0KRQKJCYmAgAGDRoEGxsbjdtW9dWysjIkJSUZpX2WqqysDAAMmvOMDFd1TnR0dET//v01bmfIOTE9PV2cI6au82H19VlZWbhz545OeUg3VX0QYD+kP/D61fR899134nJVwZ2aPmOeG6s/TbGuXH5+fmIRUZ/Pv1JikYe0VlRUhIyMDACVFdO6VF+fnJysc67r16+rjVVXLqVSKU6GRdprqJPfggUL4OnpCVtbW7Rs2RL9+vXDX//6V71GdlHdbty4gQEDBqBFixbio7bDwsLESUENkZKSApVKBaDh+z1p5/fffxf3b48ePSSJyf6qn6rj0LVrV8jlmp9lYUjf0Od8qE8e0s3JkyfFZan64fDhw9G2bVvY2Nigbdu2CA4OxtKlS1FQUCBJfPrD7t270bNnTzg4OMDZ2Rk+Pj6IjIzUeaTd03j9alqKiorEERWenp4IDg6WJC77auMz5rlR21xyuRxdu3bVO4+UWOQhrWVmZorLmoafVunYsaO4XFUYMtVcluzOnTs4ffo0AGDw4MHw9vaWLPa5c+dw7949KBQKPHz4EP/5z3+wcuVK9OjRA4sWLeKtBBLKzs5GYmIiHj16hLKyMmRlZeHgwYOIjIxE3759DTrRsC+anhUrVkCpVAKAeGusodhfdffkyRPk5uYCqL9vtGzZUnxaj659g33Q9FRUVGDp0qXiv6Xqhz/99BNycnJQXl6OnJwcnDx5Eh9++CG8vLzE2xJIGtevX0dycjJKS0tRVFSE1NRUfPfdd3jxxRcRHh4u3pqhK/ZX07Jnzx7xyVuTJ0+WbLQ6+2rja4zPpY6OjmjRooVWuXJycmqM+DQ2PkKdtFZ9jo36Htlb/dGTuj6i3di5LNnWrVvFD2+RkZGSxGzfvj3Gjh2LIUOGwMvLC3K5HPfu3cPhw4fFkSWLFy+GQqHgY34NZGVlhaFDhyI0NBR9+vSBq6srHj9+jMuXLyMmJgbJycm4fv06QkJCkJiYiE6dOumcg33RtFy4cAErV64EUHlRM3PmTIPisb/qT5e+AVT2j+LiYp37Bvug6fnqq6/E21jHjh1b56162ujduzfGjBmDgIAAuLu7o7y8HDdv3sQPP/yAH3/8EQ8fPsS4ceNw6NAhjBw5UoqXYLEcHBzwyiuvYOjQoejevTucnJzED+nr1q1DXl4e9u/fj7CwMPz0009o1qyZTvHZX02L1KPV2VdNR2N8LtX2XF89l62trc75pMAiD2ntyZMn4nJd83IAqPEfumq+F1PNZcm+//57AICdnZ0k30T6+/vj7t27tS6KnnvuOYwZMwZvvvkmhg8fjkePHmHp0qWYMGEC+vTpY3BeS7V371613ygEBgZi1qxZmDFjBrZs2YLs7GzMnTsXe/fu1TkH+6LpyM7Oxvjx46FUKiGTybBlyxaDJpBkfzWMLn0D+KN/6No32AdNy8mTJ/HBBx8AANq2bYu1a9caFG/u3LlYtGhRrd8PGDAAr7/+OmJiYvDWW29BpVIhKioKaWlpsLOzMyinJcvKylJ73nzppZcwZ84cjBw5EleuXMHJkyexdu1a/OUvf9EpPvur6cjMzMSJEycAVE6+6+vra1A89lXT0hifS3U51+ubSyq8XcvEyGQyg382b97cIG2r/kZVNamcJtWHp9nb25t0LlNh7GN//vx5cb6NsLAwNG/e3ODX4OjoWOe3XgEBAfjmm28AVM6KX7VszhryuNY1ZLRZs2bYsGGD+ESBffv2iU+X0IUl9kVtGLu/Pn78GKNGjRKHDC9duhQvvviiQa+B/dUwuvQN4I/+oWvfYB80HdeuXUN4eDiUSiXs7Oywe/dutG3b1qCY9Q39j46OxvTp0wEA9+/fx549ewzKZ+nq2t/t2rXDv/71L/F9cfXq1TrHZ381Hd9//z0qKioASDNanX3VtDTG51JdzvX65pIKizykNWdnZ3G5vqFuVfe/AtoNbWvMXJaqsZ42MHHiRPGxodUnriTpyeVy8YID0G9/sy82vidPniAsLAyXLl0CALz33nuYP3++UXKzv2qmS98A/ugfuvYN9kHTkJ6ejuHDh6OgoADW1tbYsWMHXnjhBaPkjo6OFpfZDxuWl5cXXnrpJQBAamqq+PQebbG/mo6tW7cCqBxZMWHCBKPkZF81nsb4XKrLuV7fXFLh7VomRoqZuNu3by9BS2rr0KGDuFx9sit1qk9qVX2yK21Vn0ArMzMTfn5+DZbLVBjz2CsUCuzcuRNA5TdXI0aMMDi3tuRyOXx9fZGUlKTXyJKmprH7dM+ePcVlffb3032xLubSF7VhrOOqVCoREREhPvElKioKK1asMDi3tiytv+rCzs4Orq6uyMvLq7dvFBQUiBd+uvYN9sHGd//+fQwbNgz379+HTCbDpk2bEBYWZrT8hr6Pk2569uyJo0ePAqjc3+7u7lr/rSVev5qipKQk8YlIf/rTn9CyZUuj5GVfNR5jnhs9PDxw4cIFFBcX4+HDh3WO6qrK1aZNm0abjwdgkcfk1PcIuMbk7OyMjh07IiMjAzdu3Khz2+rr9Xm0aPU3SW1zyeVy+Pj46JzLVBjz2B8+fBj5+fkAgNdeew3W1tZGyw1AsqcbNAWN3acN3de+vr6wtraGSqVq8H7flBjjuFZUVGDKlCk4dOgQAGDChAmIiYlp8LxPs6T+qquePXvi9OnTSE1NhVKp1PgYdUP6hj7nQ33ykHq5ubl46aWXcPv2bQCVt/AYc/QrwD5obIbsb0u8fjVF1UerS/VgEW2wrxqPMc+NPXv2FG+/u3HjBgYOHKh2O6VSibS0NL3zSIm3a5FOhgwZAgC4efMmHjx4oHG76kMUBw8erHMef39/cXKruoY7KhQKnD9/XvwbXZ+CYKka61YtoPINsGouIF2+HSP9VH2TBei3v21sbBAQEAAASEhIqPN+5Kq+amtrW+e3l6Sd6Oho7NixAwAwevRofP/997CyMu5pm/21blXnxOLiYvF2OnUMOSd26dJF3Pf1Df8/deoUgMqRt507d9YpD9X26NEjjBgxQnwfXbp0Kd5++22jt8PQ93HSjSH7m9evja+8vFw8d7Zp08aoT7liXzUeY54bq8719eVKSkoSR+3q8/lXSizykE7GjBkjLmuaNLSkpAS7du0CUFn51Gc2e2dnZwwdOhQA8PPPP2schrd3714UFhYCAMLDw3XOY4ny8vLEYch9+vQx+tNydu7ciUePHgEAgoKCjJrb0iiVSmzatEn8t77zR1T1+8LCQo1P6MrMzMTPP/8MABg6dGiNe6VJd3/729+wYcMGAJX7c/fu3RpHiTQk9te6VT8nxsXFqd2moqJCLKy3aNECISEhOuWQyWTirUE3btwQPxg+7fz58+K3lWFhYfxG2UAlJSUYNWoULl++DABYsGAB3n///UZpS/URfOyHDSs9PR0//fQTAMDb27vGVAXa4PVr4zt27BhycnIAAH/+85+Neu5kXzUeY54bg4ODxQfUbNmyBYIgqN2u+mfjRu/XAlk0T09PAYDg6emp1fYKhULw8vISAAguLi5CampqrW1mzZolABAACHFxcWrjxMXFidssXLhQ7TbHjx8Xt3nllVcEpVJZY31OTo7QqVMnAYDQokULIT8/X6vXYOlWr14t7tcvv/xS679LT08X/y4oKKjW+vz8fCE+Pr7OGBcuXBBatGghABBkMpmQlJSkY+upyr///W+hoKBA43qFQiFERkaKx2z06NFqt6vvuAqCIOTl5QnNmzcX3ytyc3NrrFcqlcLo0aPFOPX9P6C6LVy4UNyXzz//vFBUVKRzDPZX4wkMDBQACHK5XDh37lyt9cuXL6/zfBcfHy+uj4yMVJvj5s2bgrW1tQBA8PPzE0pKSmqsLykpEfz8/MR2pKSkSPHSLFZZWZkwfPhw8bi88847esWp71rnl19+EW7dulVnjJiYGDGGm5ubXu8HVOngwYNCeXm5xvUPHjwQ+vXrV+c1Eq9fTd+4cePE/X/p0iWt/oZ9tfFVv27RdC58mlTnxurXy5qujT755BNxm+XLl9daf+7cOUEul9d5PW1MnJPHgqSmpuLMmTM1flc1S3hRUVGtkTkvv/wy3NzcavyuWbNmWL16NUaPHo3CwkIMHjwYH3/8MQICAlBQUID169eL9ywOGTIEU6ZM0bu9L774IiZOnIgdO3bg4MGDeOmllzB37ly4u7vj119/xWeffYZ79+4BAJYtW2a0SdWauqpvlOVyOV577TXJ4j569AghISF49tlnMWbMGPTv3x/t27eHtbU17t27h8OHD2Pr1q3i7T7vvfce+vfvL1l+S7Nlyxa88soreOWVVxAcHIxu3brBxcUFRUVFuHTpEmJjY8Vhw23btsXXX3+td65WrVph2bJleOutt3D37l0MGDAACxYsQO/evXH//n2sXLlSnBh40qRJCA4OluIlWqTVq1dj8eLFACqHFS9fvhzp6el1/k23bt10HurP/iqdr7/+GoMHD0ZpaSmGDx+Ojz76CCEhISgtLcWOHTsQGxsLoHJ+q3fffVevHL6+vpg3bx6WLl2KpKQkDB48GO+//z68vb2RlpaGZcuW4cqVKwCAefPmcX4PA02aNAk//vgjgMprkenTp+Pq1asat7exsdFr1PKlS5cQFRWFkJAQjBw5Er1794arqyuUSiVu3LiBH374QWyHtbU1YmNj4ejoqN+LIsyZMwfl5eUYN24cBg0ahM6dO8Pe3h65ubk4ceIEYmJikJubC6DyGlbfW/N4/dp4CgoKcPjwYQBAr1698Nxzz0kSl31VemfOnEFqaqr476q+B1R+Zn36c+nUqVNrxTDmuXHevHnYuXMnUlJSMH/+fKSmpmLixImwt7dHfHw8Pv/8cyiVStjb22PlypV655FMY1eZyHiqV6m1+anrW97Y2FjBxsZG498GBAQIOTk5WrVF0zchglBZgQ0NDdWYx8rKqs6/p5qSk5PFfRcaGqrT39Y3MqD6+rp+rK2thUWLFgkVFRUSvSrLVP1bh7p+evfuLVy7dk1jHG1G8lT59NNPBZlMpjFXaGioUFpaKvErtSxBQUE6vU8DENLT02vFYX81roMHDwouLi4a96Ovr6/Gb4G1GckjCIKgUqmEN954o87jNX36dEGlUjXQq7QcuvZBTaOh67vW0fa6zNXVVdi/f3/DvmgLUDV6vb6fcePGaRwpy+tX07Z27VpxH6sbbaEJ+6rxaXsdW/WjiRTnRm1G8giCINy6dUvw8fHRmMfFxUU4dOiQIbtFMhzJQ3qZMWMGBg0ahFWrVuH48eO4f/8+HB0d0aNHD7z22muIioqS5B5Ye3t7HDlyBNu2bcPmzZvx3//+Fw8fPkS7du0QGBiI2bNnY9CgQRK8IsuwdetWcVnqCZfd3d2xe/duJCQkIDExEVlZWcjNzcWTJ0/QvHlzdOvWDcHBwYiKiuKEoBJ4//330bdvXyQkJOD69evIyclBfn4+bG1t0a5dO/j5+WH8+PEIDw+X7OlpixcvxogRI7BmzRqcPn0a2dnZaNGiBfr06YNp06Zh0qRJkuShhsf+Kq3Ro0fjl19+wddff40jR44gMzMTNjY26Nq1K1599VXMnj0bDg4OBuWwsrLCxo0bMW7cOMTGxuLixYvIzc1F69at4e/vj+joaKNOMEqGCw0NxcaNG5GQkIArV64gOzsbeXl5EAQBrVq1Qp8+ffDyyy9j6tSpcHFxaezmNnlbtmzByZMnkZCQgNu3byM3NxeFhYVwcnJCx44d8fzzzyMyMlKS60pevzaOqutca2trSUers6+aLmOeG7t27YorV65gzZo12L17N1JTU6FQKNCxY0eEhobinXfegaenpyS5DCUTBA0zBxERERERERERUZPBp2sREREREREREZkBFnmIiIiIiIiIiMwAizxERERERERERGaARR4iIiIiIiIiIjPAIg8RERERERERkRlgkYeIiIiIiIiIyAywyENEREREREREZAZY5CEiIiIiIiIiMgMs8hARERERERERmQEWeYiIiIiIiIiIzACLPEREREREREREZoBFHiIiIiIiIiIiM8AiDxERERERERGRGWCRh4iIiIiIiIjIDLDIQ0RERERERERkBljkISIiIiIiIiIyAyzyEBERERERERGZARZ5iIiIiIiIiIjMAIs8RERERERERERmgEUeIiIiIiIiIiIzwCIPEREREREREZEZYJGHiIiIiIiIiMgMsMhDRERERERERGQGWOQhIiIiIiIiIjID/w8cF6q1YiNa/AAAAABJRU5ErkJggg==\n" }, "metadata": { "image/png": { "width": 572, "height": 413 } } } ] }, { "cell_type": "code", "source": [ "# let's see if we can fit it with a linear regression using sklearn\n", "\n", "\n", "# declare how many input features for linear model\n", "\n", "\n", "\n" ], "metadata": { "id": "exXYEoTnZhMy" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "poly_reg.intercept_" ], "metadata": { "id": "aeBjBncSauFp" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "poly_reg.coef_\n" ], "metadata": { "id": "9wSurqBEaxvR" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "plt.scatter(X,y)\n", "\n", "# make a dotted curve for fit predictions\n", "Xt = np.linspace(X.min(), X.max(), 1000)\n", "Xt1 = Xt.reshape(-1,1)\n", "Xt2 = Xt1**2\n", "Xt3 = Xt1**3\n", "Xt123 = np.concatenate([Xt1,Xt2,Xt3], axis=1)\n", "plt.plot(Xt, poly_reg.predict(Xt123), color='r', linestyle='--', linewidth=2) #line width\n" ], "metadata": { "id": "_vvVrxhha2nN" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "\n", "\n", "---\n", "\n" ], "metadata": { "id": "4BnWFjIDMP16" } }, { "cell_type": "markdown", "metadata": { "id": "6kjoMbH10fWn" }, "source": [ "### OLS on real data (Multiple linear regression)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "XFi9DLXA0fWn" }, "outputs": [], "source": [ "import pandas as pd\n", "concrete = pd.read_excel('https://archive.ics.uci.edu/ml/machine-learning-databases/concrete/compressive/Concrete_Data.xls')" ] }, { "cell_type": "code", "source": [ "concrete" ], "metadata": { "id": "8jI3om7dJjlT" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "q7EjScES0fWn" }, "outputs": [], "source": [ "concrete.columns = [item.split('(')[0].rstrip().replace(' ','_') for item in concrete.columns]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 201 }, "id": "kgJc0wEa0fWn", "outputId": "973f60df-ec67-4c90-bc6d-67750e4a1c0f" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ " Cement Blast_Furnace_Slag Fly_Ash Water Superplasticizer \\\n", "0 540.0 0.0 0.0 162.0 2.5 \n", "1 540.0 0.0 0.0 162.0 2.5 \n", "2 332.5 142.5 0.0 228.0 0.0 \n", "3 332.5 142.5 0.0 228.0 0.0 \n", "4 198.6 132.4 0.0 192.0 0.0 \n", "\n", " Coarse_Aggregate Fine_Aggregate Age Concrete_compressive_strength \n", "0 1040.0 676.0 28 79.986111 \n", "1 1055.0 676.0 28 61.887366 \n", "2 932.0 594.0 270 40.269535 \n", "3 932.0 594.0 365 41.052780 \n", "4 978.4 825.5 360 44.296075 " ], "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", " \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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CementBlast_Furnace_SlagFly_AshWaterSuperplasticizerCoarse_AggregateFine_AggregateAgeConcrete_compressive_strength
0540.00.00.0162.02.51040.0676.02879.986111
1540.00.00.0162.02.51055.0676.02861.887366
2332.5142.50.0228.00.0932.0594.027040.269535
3332.5142.50.0228.00.0932.0594.036541.052780
4198.6132.40.0192.00.0978.4825.536044.296075
\n", "
\n", "
\n", "\n", "
\n", " \n", "\n", " \n", "\n", " \n", "
\n", "\n", "\n", "
\n", " \n", "\n", "\n", "\n", " \n", "
\n", "\n", "
\n", "
\n" ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "dataframe", "variable_name": "concrete", "summary": "{\n \"name\": \"concrete\",\n \"rows\": 1030,\n \"fields\": [\n {\n \"column\": \"Cement\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 104.5071416428718,\n \"min\": 102.0,\n \"max\": 540.0,\n \"num_unique_values\": 280,\n \"samples\": [\n 194.68,\n 480.0,\n 145.4\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Blast_Furnace_Slag\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 86.27910364316895,\n \"min\": 0.0,\n \"max\": 359.4,\n \"num_unique_values\": 187,\n \"samples\": [\n 186.7,\n 212.0,\n 26.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Fly_Ash\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 63.99646938186508,\n \"min\": 0.0,\n \"max\": 200.1,\n \"num_unique_values\": 163,\n \"samples\": [\n 81.8,\n 137.9,\n 107.5\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Water\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 21.355567066911522,\n \"min\": 121.75,\n \"max\": 247.0,\n \"num_unique_values\": 205,\n \"samples\": [\n 164.9,\n 181.1,\n 185.7\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Superplasticizer\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 5.973491650590111,\n \"min\": 0.0,\n \"max\": 32.2,\n \"num_unique_values\": 155,\n \"samples\": [\n 4.14,\n 9.8,\n 6.13\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Coarse_Aggregate\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 77.75381809178927,\n \"min\": 801.0,\n \"max\": 1145.0,\n \"num_unique_values\": 284,\n \"samples\": [\n 852.1,\n 913.9,\n 914.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Fine_Aggregate\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 80.1754273990239,\n \"min\": 594.0,\n \"max\": 992.6,\n \"num_unique_values\": 304,\n \"samples\": [\n 698.0,\n 613.0,\n 689.3\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Age\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 63,\n \"min\": 1,\n \"max\": 365,\n \"num_unique_values\": 14,\n \"samples\": [\n 91,\n 100,\n 28\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Concrete_compressive_strength\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 16.705679174867946,\n \"min\": 2.331807832,\n \"max\": 82.5992248,\n \"num_unique_values\": 938,\n \"samples\": [\n 33.398217439999996,\n 56.63355864,\n 25.559564796\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" } }, "metadata": {}, "execution_count": 27 } ], "source": [ "concrete.head()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "hyj9BDum0fWn" }, "outputs": [], "source": [ "import seaborn as sns\n", "sns.stripplot(data = concrete, orient = 'h')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nsI8vQvR0fWo" }, "outputs": [], "source": [ "X = concrete.drop(columns = 'Concrete_compressive_strength')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "8uonGP9Y0fWo" }, "outputs": [], "source": [ "y = concrete['Concrete_compressive_strength']" ] }, { "cell_type": "code", "source": [ "from sklearn.preprocessing import StandardScaler\n", "from sklearn.model_selection import train_test_split\n", "\n", "# Splitting the data into training and testing sets\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n", "\n", "# Applying StandardScaler\n", "scaler = StandardScaler()\n", "\n", "# Fit the scaler on the training data and transform the training data\n", "X_train_scaled = scaler.fit_transform(X_train)\n", "\n", "# Transform the test data using the same scaler\n", "X_test_scaled = scaler.transform(X_test)" ], "metadata": { "id": "Om1BL3qMV_rX" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "8r5QhVEh0fWo" }, "outputs": [], "source": [ "lin_reg = LR()\n", "lin_reg.fit(X_train_scaled,y_train)\n", "print(lin_reg.score(X_train_scaled,y_train))\n", "print(lin_reg.score(X_test_scaled,y_test))" ] }, { "cell_type": "markdown", "metadata": { "id": "7DenlaKR0fWo" }, "source": [ "We will compare the predicted values to the actual values we had for y. What does it mean to make a prediction?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "HfbuDyrZ0fWo" }, "outputs": [], "source": [ "lin_reg.coef_" ] }, { "cell_type": "code", "source": [ "lin_reg.intercept_" ], "metadata": { "id": "pp7P3oz5R0GX" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [], "id": "Da6A07Es0fWq" }, "outputs": [], "source": [ "X.columns" ] }, { "cell_type": "code", "source": [ "X.head()" ], "metadata": { "id": "q6Wh401uSPej" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "X.iloc[0]" ], "metadata": { "id": "R2uav7dISRu4" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "7bL6vGuV0fWq" }, "outputs": [], "source": [ "obs = np.array(X.iloc[0]).reshape(1,-1)\n", "print(obs)\n", "\n", "obs = scaler.transform(obs)\n", "\n", "print(obs)\n", "print('Coefficients:',lin_reg.coef_)\n", "print('Intercept:', lin_reg.intercept_)\n", "print(sum(obs * lin_reg.coef_) + lin_reg.intercept_)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "tTXXhqVl0fWr", "outputId": "12823515-e2fc-4eda-d86f-8984030a2df2", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([52.43959381])" ] }, "metadata": {}, "execution_count": 120 } ], "source": [ "lin_reg.predict(obs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "JAsJwEe70fWr" }, "outputs": [], "source": [ "y_pred = lin_reg.predict(X_train_scaled)\n", "\n", "plt.figure(figsize=(8,8))\n", "plt.scatter(y_train, y_pred, alpha=0.5, ec='k')\n", "plt.plot([min(y), max(y)],[min(y),max(y)], ':k')\n", "plt.axis('equal')\n", "plt.xlabel('Actual Compressive Strength', fontsize=14)\n", "plt.ylabel('Predicted Compressive Strength', fontsize=14)\n", "plt.show()" ] }, { "cell_type": "markdown", "source": [ "--\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", "\n", "\n", "\n" ], "metadata": { "id": "EQKcRcYVDU3T" } }, { "cell_type": "markdown", "source": [ "\n", "\n", "---\n", "\n" ], "metadata": { "id": "5yapCk2Isef4" } }, { "cell_type": "markdown", "source": [ "### Digression on Epistemic and Aleatoric" ], "metadata": { "id": "-qNasF3EKy_K" } }, { "cell_type": "code", "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from matplotlib.animation import FuncAnimation, PillowWriter\n", "from IPython.display import Image\n", "\n", "# Enable inline plotting in Jupyter\n", "%matplotlib inline\n", "\n", "# Parameters for the target and darts\n", "target_center = np.array([0, 0]) # True center of the target\n", "\n", "# Simulation parameters\n", "n_darts = 60 # Number of darts to throw\n", "high_precision_var = 0.15 # Low variance for high precision darts\n", "low_precision_var = 0.75 # High variance for low precision darts\n", "high_accuracy_offset = np.array([0, 0]) # No offset for high accuracy\n", "low_accuracy_offset = np.array([2, 2]) # Offset for low accuracy (epistemic uncertainty)\n", "\n", "# Function to generate darts with precision and accuracy\n", "def generate_darts(accuracy_offset, precision_var):\n", " return np.random.randn(n_darts, 2) * precision_var + accuracy_offset\n", "\n", "# Suppress initial plot creation by using a context where we don't show output\n", "plt.ioff() # Turn off interactive plotting\n", "\n", "# Set up the figure and axis\n", "fig, ax = plt.subplots(figsize=(6, 6))\n", "ax.set_xlim(-4, 4)\n", "ax.set_ylim(-4, 4)\n", "ax.set_aspect('equal')\n", "\n", "# Target center visualization\n", "target = plt.Circle(target_center, 0.05, color='red', label='True Target')\n", "ax.add_artist(target)\n", "\n", "# Initialize scatter plot for darts\n", "darts_plot = ax.scatter([], [], s=50, c='blue', alpha=0.7)\n", "\n", "# Function to initialize the plot\n", "def init():\n", " darts_plot.set_offsets(np.empty((0, 2)))\n", " return darts_plot,\n", "\n", "# Function to update the dart positions for each frame\n", "def update(frame):\n", " ax.clear()\n", " ax.set_xlim(-4, 4)\n", " ax.set_ylim(-4, 4)\n", " ax.set_aspect('equal')\n", "\n", " # Vary the frame between different types of darts (precision and accuracy)\n", " if frame < 30:\n", " # High Precision, Low Accuracy (Epistemic Uncertainty)\n", " darts = generate_darts(low_accuracy_offset, high_precision_var)\n", " ax.set_title('High Precision, Low Accuracy (Epistemic Uncertainty)')\n", " else:\n", " # High Accuracy, Low Precision (Aleatoric Uncertainty)\n", " darts = generate_darts(high_accuracy_offset, low_precision_var)\n", " ax.set_title('High Accuracy, Low Precision (Aleatoric Uncertainty)')\n", "\n", " # Redraw the target\n", " ax.add_artist(plt.Circle(target_center, 0.05, color='red', label='True Target'))\n", "\n", " # Update the dart positions\n", " darts_plot = ax.scatter(darts[:, 0], darts[:, 1], s=50, c='blue', alpha=0.7)\n", "\n", " return darts_plot,\n", "\n", "# Create the animation\n", "ani = FuncAnimation(fig, update, frames=np.arange(60), init_func=init, blit=False, repeat=True)\n", "\n", "# Save the animation as a gif file\n", "ani.save(\"darts_simulation.gif\", writer=PillowWriter(fps=5))\n", "\n", "# Turn back on interactive plotting to ensure the animation shows up correctly\n", "plt.ion()\n", "\n", "# Display the gif in the notebook\n", "Image(filename=\"darts_simulation.gif\")\n" ], "metadata": { "id": "ayRY7WzCK7Ff" }, "execution_count": null, "outputs": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.9" }, "colab": { "provenance": [] } }, "nbformat": 4, "nbformat_minor": 0 }