{ "cells": [ { "cell_type": "code", "execution_count": 14, "source": [ "# This Notebook is created with VS Code on Windows\r\n", "# Create python virtual environment\r\n", "#!python -m venv .venv\r\n", "# If you want to use it on macOS/Linux\r\n", "# You may need to run sudo apt-get install python3-venv first\r\n", "#python3 -m venv .venv\r\n", "\r\n", "# Install Python Packages\r\n", "!pip install --user --upgrade pip\r\n", "!pip install --user seaborn\r\n", "!pip install --user numpy\r\n", "!pip install --user pandas\r\n", "!pip install --user matplotlib\r\n", "!pip install --user plotly\r\n", "!pip install --user nbformat\r\n" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Requirement already satisfied: pip in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (21.2.4)\n", "Requirement already satisfied: seaborn in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (0.11.2)\n", "Requirement already satisfied: matplotlib>=2.2 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (3.3.4)\n", "Requirement already satisfied: numpy>=1.15 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (1.20.1)\n", "Requirement already satisfied: scipy>=1.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (1.6.1)\n", "Requirement already satisfied: pandas>=0.23 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from seaborn) (1.2.2)\n", "Requirement already satisfied: cycler>=0.10 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (0.10.0)\n", "Requirement already satisfied: python-dateutil>=2.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (2.8.1)\n", "Requirement already satisfied: kiwisolver>=1.0.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (1.3.1)\n", "Requirement already satisfied: pillow>=6.2.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib>=2.2->seaborn) (8.1.0)\n", "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from matplotlib>=2.2->seaborn) (2.4.6)\n", "Requirement already satisfied: six in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from cycler>=0.10->matplotlib>=2.2->seaborn) (1.15.0)\n", "Requirement already satisfied: pytz>=2017.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas>=0.23->seaborn) (2021.1)\n", "Requirement already satisfied: numpy in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (1.20.1)\n", "Requirement already satisfied: pandas in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (1.2.2)\n", "Requirement already satisfied: numpy>=1.16.5 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (1.20.1)\n", "Requirement already satisfied: pytz>=2017.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (2021.1)\n", "Requirement already satisfied: python-dateutil>=2.7.3 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (2.8.1)\n", "Requirement already satisfied: six>=1.5 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)\n", "Requirement already satisfied: matplotlib in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (3.3.4)\n", "Requirement already satisfied: numpy>=1.15 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (1.20.1)\n", "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from matplotlib) (2.4.6)\n", "Requirement already satisfied: python-dateutil>=2.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (2.8.1)\n", "Requirement already satisfied: kiwisolver>=1.0.1 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (1.3.1)\n", "Requirement already satisfied: pillow>=6.2.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (8.1.0)\n", "Requirement already satisfied: cycler>=0.10 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from matplotlib) (0.10.0)\n", "Requirement already satisfied: six in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from cycler>=0.10->matplotlib) (1.15.0)\n", "Requirement already satisfied: plotly in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (5.3.0)\n", "Requirement already satisfied: six in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from plotly) (1.15.0)\n", "Requirement already satisfied: tenacity>=6.2.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from plotly) (8.0.1)\n", "Collecting nbformat\n", " Downloading nbformat-5.1.3-py3-none-any.whl (178 kB)\n", "Requirement already satisfied: ipython-genutils in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (0.2.0)\n", "Requirement already satisfied: traitlets>=4.1 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (5.0.5)\n", "Collecting jsonschema!=2.5.0,>=2.4\n", " Downloading jsonschema-3.2.0-py2.py3-none-any.whl (56 kB)\n", "Requirement already satisfied: jupyter-core in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from nbformat) (4.7.1)\n", "Requirement already satisfied: six>=1.11.0 in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (1.15.0)\n", "Requirement already satisfied: attrs>=17.4.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (19.3.0)\n", "Requirement already satisfied: setuptools in c:\\users\\oli\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from jsonschema!=2.5.0,>=2.4->nbformat) (49.2.1)\n", "Collecting pyrsistent>=0.14.0\n", " Downloading pyrsistent-0.18.0-cp38-cp38-win_amd64.whl (62 kB)\n", "Requirement already satisfied: pywin32>=1.0 in c:\\users\\oli\\appdata\\roaming\\python\\python38\\site-packages (from jupyter-core->nbformat) (300)\n", "Installing collected packages: pyrsistent, jsonschema, nbformat\n", "Successfully installed jsonschema-3.2.0 nbformat-5.1.3 pyrsistent-0.18.0\n" ] }, { "output_type": "stream", "name": "stderr", "text": [ " WARNING: The script jsonschema.exe is installed in 'C:\\Users\\Oli\\AppData\\Roaming\\Python\\Python38\\Scripts' which is not on PATH.\n", " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", " WARNING: The script jupyter-trust.exe is installed in 'C:\\Users\\Oli\\AppData\\Roaming\\Python\\Python38\\Scripts' which is not on PATH.\n", " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 8, "source": [ "import numpy as np # linear algebra\r\n", "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\r\n", "import matplotlib.pyplot as plt\r\n", "import seaborn as sns\r\n", "import os\r\n", "import re\r\n", "\r\n", "from plotly.offline import init_notebook_mode, iplot\r\n", "import plotly.graph_objs as go\r\n", "import plotly.offline as py\r\n", "py.init_notebook_mode(connected=True)\r\n", "\r\n", "import warnings\r\n", "warnings.filterwarnings('ignore')\r\n", "\r\n", "plt.style.use('fivethirtyeight')\r\n", "plt.rcParams['figure.figsize'] = [18, 8]" ], "outputs": [ { "output_type": "display_data", "data": { "text/html": [ " \n", " " ] }, "metadata": {} } ], "metadata": {} }, { "cell_type": "code", "execution_count": 23, "source": [ "# Import Tables\r\n", "reviews = pd.read_csv('./ml-latest-small/ratings.csv', names=['userId', 'movieId', 'rating', 'timestamp'], delimiter=',', engine='python')\r\n", "movies = pd.read_csv('./ml-latest-small/movies.csv', names=['movieId', 'title', 'genres'], delimiter=',', engine='python')\r\n", "users = pd.read_csv('./ml-latest-small/users.csv', names=['userId', 'gender', 'age', 'occupation', 'zip'], delimiter='::', engine='python')\r\n", "\r\n", "# Print Table shape\r\n", "print('Reviews shape:', reviews.shape)\r\n", "print('Users shape:', users.shape)\r\n", "print('Movies shape:', movies.shape)" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Reviews shape: (100836, 4)\n", "Users shape: (610, 5)\n", "Movies shape: (9742, 3)\n" ] } ], "metadata": {} }, { "cell_type": "code", "execution_count": 25, "source": [ "# Drop unused Attributes\r\n", "reviews.drop(['timestamp'], axis=1, inplace=True) # Time\r\n", "users.drop(['zip'], axis=1, inplace=True) # Zip-Code\r\n", "\r\n", "# Extract the movie year from title to extra attrbute\r\n", "movies['release_year'] = movies['title'].str.extract(r'(?:\\((\\d{4})\\))?\\s*$', expand=False)" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": 26, "source": [ "# print movie table\r\n", "movies.head()" ], "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ " movieId title \\\n", "0 1 Toy Story (1995) \n", "1 2 Jumanji (1995) \n", "2 3 Grumpier Old Men (1995) \n", "3 4 Waiting to Exhale (1995) \n", "4 5 Father of the Bride Part II (1995) \n", "\n", " genres release_year \n", "0 Adventure|Animation|Children|Comedy|Fantasy 1995 \n", "1 Adventure|Children|Fantasy 1995 \n", "2 Comedy|Romance 1995 \n", "3 Comedy|Drama|Romance 1995 \n", "4 Comedy 1995 " ], "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", "
movieIdtitlegenresrelease_year
01Toy Story (1995)Adventure|Animation|Children|Comedy|Fantasy1995
12Jumanji (1995)Adventure|Children|Fantasy1995
23Grumpier Old Men (1995)Comedy|Romance1995
34Waiting to Exhale (1995)Comedy|Drama|Romance1995
45Father of the Bride Part II (1995)Comedy1995
\n", "
" ] }, "metadata": {}, "execution_count": 26 } ], "metadata": {} }, { "cell_type": "code", "execution_count": 27, "source": [ "# changed feature values based on README_users.txt\r\n", "\r\n", "ages_map = {1: 'Under 18',\r\n", " 18: '18 - 24',\r\n", " 25: '25 - 34',\r\n", " 35: '35 - 44',\r\n", " 45: '45 - 49',\r\n", " 50: '50 - 55',\r\n", " 56: '56+'}\r\n", "\r\n", "occupations_map = {0: 'Not specified',\r\n", " 1: 'Academic / Educator',\r\n", " 2: 'Artist',\r\n", " 3: 'Clerical / Admin',\r\n", " 4: 'College / Grad Student',\r\n", " 5: 'Customer Service',\r\n", " 6: 'Doctor / Health Care',\r\n", " 7: 'Executive / Managerial',\r\n", " 8: 'Farmer',\r\n", " 9: 'Homemaker',\r\n", " 10: 'K-12 student',\r\n", " 11: 'Lawyer',\r\n", " 12: 'Programmer',\r\n", " 13: 'Retired',\r\n", " 14: 'Sales / Marketing',\r\n", " 15: 'Scientist',\r\n", " 16: 'Self-Employed',\r\n", " 17: 'Technician / Engineer',\r\n", " 18: 'Tradesman / Craftsman',\r\n", " 19: 'Unemployed',\r\n", " 20: 'Writer'}\r\n", "\r\n", "gender_map = {'M': 'Male', 'F': 'Female'}\r\n", "\r\n", "users['age'] = users['age'].map(ages_map)\r\n", "users['occupation'] = users['occupation'].map(occupations_map)\r\n", "users['gender'] = users['gender'].map(gender_map)" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": 28, "source": [ "age_reindex = ['Under 18', '18 - 24', '25 - 34', '35 - 44', '45 - 49', '50 - 55', '56+']\r\n", "\r\n", "age_counts = users['age'].value_counts().reindex(age_reindex)\r\n", "\r\n", "sns.barplot(x=age_counts.values,\r\n", " y=age_counts.index,\r\n", " palette='magma').set_title(\r\n", " 'Users age', fontsize=24)\r\n", "\r\n", "plt.show()" ], "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-30T17:25:58.608318\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.4, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", "image/png": "iVBORw0KGgoAAAANSUhEUgAABL4AAAILCAYAAADmNVXwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABBXElEQVR4nO3df/xX8/0//luKaoVXKi+Vfqhe+dEPUcj2Zn4kM8SG+TXbaNqij5kfo9H8HBqiWYsLi80whPnN2EiI/CzDp3eWQpG8pugn1ev7x76en73W79Wrl07X6+XyvFyccx7nPO7ndXns7DxvnfN41pk1a1ZVAAAAAKBgNqrtAgAAAACgJgi+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwCAJF27dk1ZWVkuvfTStdoWAIDaI/gCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEArEVTpkzJaaedlh49emSrrbZKixYt0qVLlxx44IEZOnRoKisrl7nf1KlTc+aZZ6Znz55p0aJFtt5663z961/P1Vdfnblz5y5zn7KyspSVlWXq1KmZOHFifvzjH6dz585p1qxZjjnmmFK7mTNnZvDgwdl9993TsmXLlJeXp3PnzunTp09++ctf5p133lmtc5w2bVquueaaHHbYYdl5553TokWLtG7dOnvssUcuueSSzJo1a6X7Dxw4MNtvv33Ky8uz4447ZtCgQZk1a1ZuueWWlJWV5cADD1zu/mPHjs0JJ5yQHXbYIVtuuWW22WabHHLIIRk1alSqqqpW61wAgGKrV9sFAAAUxauvvpqDDz44n376aZJk4403zle+8pW89957ee+99/LMM8+kW7du6d27d7X97rvvvvTv3z8LFixIknzlK1/JwoULM378+IwfPz533HFH/vznP2fLLbdcZr9jx47Naaedlnnz5mXTTTdNvXr/7xbvnXfeSZ8+ffLBBx8kSerWrZtNN90006dPz7Rp0zJu3Li0aNEiJ5xwwiqf56BBg3LfffclSTbZZJM0atQos2fPzmuvvZbXXnstd955Zx544IG0atVqqX3//ve/5+CDD87HH3+cJGncuHE+/PDDjBgxIo888kj69eu3wr7PO++8DBs2rLS82WabZdasWRk9enRGjx6dhx9+ONdff3022si/7wIAnvgCAFhrBg8enE8//TQ9e/bM6NGjM3PmzEydOjXTp0/PE088kQEDBmSzzTarts/LL7+cfv36ZdGiRTnjjDPyxhtvZPr06fnggw/yl7/8JTvttFPeeOON/PjHP15uv2eccUZ22mmnPPvss3n33Xfz/vvv55e//GWSZMiQIfnggw/Svn37PPTQQ5k5c2amTJmSDz74IM8++2zOOOOM5QZqy9OpU6cMGTIkL730Uj744IO8/fbbmTFjRh544IHsvPPOefvtt/PTn/50qf0WLlyYH/zgB/n444/ToUOHPPLII3nvvfcybdq03HHHHZk3b14uv/zy5fY7YsSIDBs2LFtuuWWGDRuWqVOn5p133sn06dMzcuTIlJeX56677srVV1+9WucDABRXnVmzZnkeHADY4HXt2jXvvvtuzjrrrAwaNOi/atuiRYvMnz8/jz/+eHr27LlK/X7jG9/Ic889l6uuuirHH3/8Uts//vjj7L777vnggw/yxBNPZKeddiptKysrS5K0a9cuY8eOTcOGDZfaf7fddsvEiRMzcuTIfPvb316lmtbExx9/nF122SWVlZV59dVX07Zt29K2P/7xjxk4cGAaNGiQ5557Lu3atau274svvpj99tsvVVVV+drXvpYHH3ywtG3WrFnp0qVLFi1alMceeyxdu3Zdqu9x48Zl//33z+abb57//d//zSabbFJj5wkArB888QUAsJZsuummSVJ6rXBl3n777Tz33HPZfPPNc9xxxy2zTZMmTUqvRj7xxBPLbHPiiScuM/T6b2paU02aNMmuu+6aqqqqjBs3rtq2+++/P0nSt2/fpUKvJOnZs2f+53/+Z5nHve+++zJnzpx8/etfX2bolSS77rpr2rZtm1mzZuXVV19do/MAAIrBHF8AAGvJfvvtl1tuuSUDBgzIiy++mAMPPDDdu3fPxhtvvMz2zz//fJJk7ty52WGHHZZ73C8mt582bdoyt++6664rrOnFF1/M+eefn8mTJ6dv377ZZZddlhuUraqXXnopI0eOzLhx4zJ9+vRlTsD/n2Hba6+9liTZfffdl3vc3XffPWPGjFlq/Rch2pgxY9KpU6fl7v/F3GHL+1sBABsWwRcAwFpy0UUX5a233srzzz+fq6++OldffXUaNGiQXXbZJYceemiOOeaYaoHTjBkzkiSLFi3Khx9+uNLjz5s3b5nrmzVrttx9Tj311Lz66qt5+OGHc8MNN+SGG25IvXr1svPOO+eggw7K9773vdIrk6vqmmuuyS9+8YvSLyjWrVs3ZWVlpVcLP/nkkyxYsGCpMOyLX7QsLy9f7rFbtGixzPVf/K3mzZu33L/Dv1uVNgBA8Qm+AACSNGjQIElKv6y4IvPnz0+SpZ6a2mKLLfLII4+Ufl1w7Nix+fvf/54xY8ZkzJgxueaaa/Lggw+Wfu1wyZIlSZIuXbrk6aef/q9rX9EvGNavXz+33XZbXnjhhTzwwAN59tln8+qrr2bcuHEZN25cfv3rX+eee+5Z7uuD/+nNN9/Meeedl6qqqpx44onp169fKioqUrdu3VKb/v3754477igFY2vDF3+rH//4x7nsssvW2nEBgGIzxxcAQP4VWiUrnwtr4cKFpdfpvtjn39WpUyd77bVXhgwZkqeeeiqTJ0/O1VdfnSZNmmTKlCn5+c9/XmrbvHnzJOvmtbxddtklF1xwQR577LFMmTIlv/vd77L11lvno48+yimnnLLKx7nvvvuyZMmS7Lvvvrn88suz3XbbVQu9kmTmzJnL3Ldp06ZJ/t/TW8uyvL//F3+r9957b5VrBQAQfAEAJOnWrVuS5IUXXlhhu5deeimLFy+uts+KlJWV5Qc/+EF+8YtfJEmeeeaZ0rYv5ub6+OOP8+KLL/5Xdf83GjVqlMMOOyzDhg1Lkrz66qvLnKNrWaZPn55k+ec+d+7c5Z7LF0+VjR07drnHX962L/5WTz/9dOmJOwCAlRF8AQAkOfjgg5MkkydPzoMPPrjcdsOHD0+StG3btlr4s2TJkixatGi5+33xKuVnn31WWtepU6fssssuSZJf/OIX+fzzz5e7//z587Nw4cJVOJPq/r2/5dVUVVW1wr7/3WabbZYkeeONN5a5/corr8ynn366zG0HHXRQkn/9uuPUqVOX2v7yyy8vc2L7JDn00EPTqFGjzJo1K7/61a9WWOOsWbNWuB0A2HAIvgAAkuy5557Ze++9kyQ/+tGPcuONN2b27Nml7ZMmTUr//v1Lodi5555bbW6tTz75JDvttFOuuOKKvP7666WnwpYsWZLRo0fn4osvTpLss88+1fodMmRI6tevn2effTZ9+/bN2LFjS/NZLV68OK+//nqGDBmS7t27r/Q1zGXZfffdc+GFF+bll18uhWBVVVV56aWX8rOf/SxJsvPOO6/yBPdf/I0effTRDB06tDSJ/EcffZTBgwdn6NChy3wFNEmOOOKItG/fPvPnz8/hhx9e+qXGqqqqPP744zn22GNLwdp/2mKLLUpPzV111VU55ZRT8tZbb5W2z58/P88++2xOO+209OnTZ5XOBQAovjqzZs1ae7OOAgCsxyorK3PMMcfk+eefT/Kv+bo233zzfP7556VXAevUqZNzzjknZ5xxRrV9Z82alXbt2pWWN9544zRu3DiffPJJKQRr165dtcntv/DYY4+lX79++eSTT5L8a0L6Ro0a5dNPP632JNaECRPSpk2b0vIXYdX48ePTtm3bZZ5TmzZtSsetW7duNttss8yZM6d03KZNm+bee+9Nly5dVvnvdNxxx+X++++v9jeaPXt2qqqqctxxx2XRokW57bbbctZZZ2XQoEHV9p0wYUIOPvjgUqjYuHHjLF68OPPnz0/Hjh3zgx/8IOeee2722Wef3H333Uv1ffnll+eSSy4pTZzfqFGjbLzxxvnkk09KgWGbNm0yYcKEVT4fAKC4PPEFAPD/a9q0aR588MFcd9112X///bPllluWAq+Kiop8//vfz+jRo5cKvZJ/vQJ4++23Z8CAAenRo0eaNWuWOXPmpFGjRtl5550zePDgjBkzZqnQK0n222+/vPTSSznjjDOy4447pn79+pk9e3Y23XTT7LbbbvnpT3+aJ598slrotapuvfXWnHbaaenVq1datGiRuXPnZpNNNknnzp3z05/+NM8999xqhV5JcuONN+b888/Ptttum4033jhVVVXp1atXRowYkWuuuWaF+3br1i1PP/10jj322JSXl+fzzz/PlltumZNPPjl//etfS0/Rbb755svc/8wzz8zTTz+dH/zgB+nQoUOWLFmSefPmZauttsq+++6bCy+8MA8//PBqnQ8AUFye+AIA4Eujf//+ueOOO5b5tBgAwOryxBcAAF8KU6ZMKb1C+cVcYgAAa0LwBQDAOvPggw/mwgsvzJtvvlmaZ2zhwoV58MEHc/DBB2f+/PnZZZdd0qtXr1quFAAoAq86AgCwzvzhD3/IKaeckiTZaKONsvnmm+fTTz/NokWLkiStW7fOfffdl2222aY2ywQACkLwBQDAOjN16tTcfPPNeeqpp/Luu++msrIyDRo0yDbbbJMDDjggP/7xj0u/VgkAsKYEXwAAAAAUkjm+AAAAACgkwRcAAAAAhST4ghoyadKk2i6B9YjxwuowXlhVxgqrw3hhdRgvrA7jhdWxtseL4AsAAACAQhJ8AQAAAFBIgi8AAAAACqlebRewPtpp20Nru4QNzisT/1zbJQAAAADrGU98AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIVU68HXkUcemQEDBtR2GQAAAAAUzEqDrwMPPDBnnnnmUutvueWWtGrVqkaKWltuuummHHTQQWnTpk3KysoyderUpdq89dZbOeaYY9K+fftsvfXW6d27dx5//PFaqBYAAACAtanWn/haGz7//PNlrp83b1722WefnH322cvd98gjj8zChQtz77335qmnnkqvXr1yzDHH5O23366pcgEAAABYB9Za8DVgwIAceeSRGTFiRLbffvu0bds2J510UubNm1dqM2/evAwYMCCtWrVKRUVFrrzyyqWO89lnn+W8887LDjvskBYtWmTvvffOX//619L2MWPGpKysLH/5y1+yzz77pHnz5tW2/7uTTjopp512Wnbfffdlbq+srMw//vGP/OQnP0nXrl3Tvn37nH/++Vm0aFEmTJiwhn8RAAAAAGrTWn3ia+zYsXnzzTfz5z//OTfeeGMeeOCBXHvttaXtgwcPzpNPPpk//OEPuffeezNhwoQ8++yz1Y5x8skn55lnnsn111+fsWPH5uijj85RRx2V1157rVq7888/P+eee25eeOGF9OzZ87+qd4sttsi2226b22+/PXPmzMnixYtz0003pXHjxtltt93+q2MCAAAA8OVQb20ebNNNN81VV12VunXrZtttt82hhx6a0aNH57TTTsucOXNy88035ze/+U323XffJMnw4cOzww47lPZ/++23M2rUqEyYMCGtW7dOkvTv3z9PPvlkbrrppmpPiJ111lnZZ5991qjeOnXq5J577sl3v/vdtG7dOhtttFGaNGmSUaNGZauttlqjYwMAAABQu9Zq8LXtttumbt26peWtttoqL774YpJ/hVqfffZZdt1119L2xo0bp3PnzqXl8ePHp6qqKr169ap23IULF2bPPfestm6nnXZa43qrqqpy+umnZ4sttsjDDz+cBg0a5Oabb873vve9/O1vf0vLli3XuA8AAAAAasdKg69NN900s2fPXmr97Nmzs9lmm1Vbt/HGG1dbrlOnTqqqqla5mCVLlqROnTr529/+ttSxGjRoUG25UaNGq3zc5XnqqafyyCOP5O23305ZWVmSpHv37nniiSdyyy23LPPXLAEAAABYP6w0+KqoqMhjjz2Wqqqq1KlTp7R+/Pjx6dix4yp3tM0222TjjTfOCy+8kHbt2iVJ5s6dmzfeeKO03K1bt1RVVWXGjBlLPeFVE76YeH+jjapPdbbRRhtlyZIlNd4/AAAAADVnpcFXv379cv311+dnP/tZvve976VBgwb5y1/+krvuuiu33XbbKnfUuHHjHHfccTn//PPTrFmzbLXVVvnVr35VLWDq2LFjvvOd7+Skk07KL3/5y+y44475+OOP8/TTT6dt27bp27fvap3cjBkzMmPGjLz11ltJkokTJ2b27Nlp3bp1mjRpkl133TVNmjTJySefnJ/97Gdp2LBhfv/732fKlCnZf//9V6svAAAAAL5cVhp8tWvXLg899FAuvvjifPvb387ChQtTUVGRm266Kfvtt99qdXbRRRdl7ty5+e53v5uGDRumf//+paeuvjB8+PBcccUV+cUvfpHp06enSZMm2XnnnbPHHnus3pklGTlyZIYMGVJa/s53vlPq49hjj03Tpk1z11135aKLLkrfvn2zaNGidOrUKbfccku6d+++2v0BAAAA8OVRZ9asWas+CRdJkp22PbS2S9jgvDLxz7VdwmqbNGlSKioqarsM1hPGC6vDeGFVGSusDuOF1WG8sDqMF1bH2h4vG628CQAAAACsfwRfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEj1aruA9dErE/9c2yUAAAAAsBKe+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSPVqu4D10fd2PK+2SwAAAAriD+MvqO0SAArLE18AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACikGg2+nnnmmRx11FHZfvvtU1ZWlltuuWWpNnPmzMmZZ56ZHXbYIVtttVV69uyZ4cOHr3HfU6dOzcCBA7Pjjjtmq622yo477pgLLrgg8+fPX2b7ysrKUp2VlZVr3D8AAAAAtateTR587ty52WGHHXL00Ufnxz/+8TLbnHPOOXnyySdz7bXXpm3btnn22Wfzk5/8JE2bNs1RRx31X/c9adKkLF68OEOHDk2HDh0yceLEnHrqqfnnP/+ZYcOGLdX+pJNOSteuXfP+++//130CAAAA8OVRo0989enTJ7/4xS9yyCGHZKONlt3VuHHjcuSRR2bPPfdM27Ztc/TRR6dnz5556aWX1qjv3r17Z8SIEdl3333Trl277L///jn99NNz3333LdV2xIgRmT9/fk4++eQ16hMAAACAL49an+OrV69eeeSRR/Lee+8lSZ5//vn8/e9/z7777rvW+/r0009TVlZWbd348eMzbNiwXHvttcsN5wAAAABY/9R60jNkyJB06dIlXbp0SbNmzXLggQfm/PPPzze+8Y212s8777yTa665Jv369Sutmzt3bvr165chQ4akZcuWa7U/AAAAAGpXrQdf1113XcaNG5fbbrstTz75ZC655JIMHjw4jz/++DLbv/vuu2nVqlXpc+WVV660jw8//DCHH3549t5772qvM5511lnp1atXDjnkkLV2PgAAAAB8OdTo5PYrM3/+/Fx44YW56aabcsABByRJunTpktdeey3XXHNNevfuvdQ+LVq0yJgxY0rLTZo0WWEfM2bMSN++fbP99tvnuuuuS506dUrbRo8enWnTpuW2225LklRVVSVJOnXqlFNPPTWDBw9e43MEAAAAoHbUavD1+eef5/PPP0/dunWrra9bt26WLFmyzH3q1auX9u3br9LxP/jggxx88MHZbrvt8rvf/S716lU/3XvuuSefffZZafnll1/OwIED88ADD6RDhw6reTYAAAAAfJnUaPA1Z86cTJ48OUmyZMmSvPfee5kwYUKaNGmS1q1bZ7PNNsvXvva1XHDBBWnUqFFat26dZ555Jn/6059ywQUXrFHf77//fg466KBstdVWufTSS1NZWVna1qxZs9StWzcdO3asts8XbTp16pSmTZuuUf8AAAAA1K4aDb5eeeWVHHzwwaXlSy+9NJdeemmOPvrojBgxIkkycuTIXHDBBenfv38+/vjjtG7dOuecc0769++/Rn3/7W9/yz/+8Y/84x//SJcuXaptGz9+fNq2bbtGxwcAAADgy63OrFmzqmq7iPXN93Y8r7ZLAAAACuIP49fsbZfaMGnSpFRUVNR2GawnjBdWx9oeL7X+q44AAAAAUBMEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQqpX2wWsj/4w/oLaLoH1wKRJk1JRUVHbZbCeMF5YHcYLq8pYYXUYLwAUkSe+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQqpX2wWsjy7d+5LaLgEAAABghQY98fPaLqHWeeILAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKKQaDb6GDh2avffeO61bt06HDh1y5JFH5o033qjWZsCAASkrK6v26d279xr3vWTJkhx11FHp0qVLysvLs+2226Z///6ZPn36MttXVlZm++23T1lZWSorK9e4fwAAAABqV40GX08//XT69euXRx99NPfdd1/q1auXQw89NB9//HG1dnvttVcmTpxY+tx5551rpf8999wzN954Y1544YX84Q9/yJQpU/Ld7353mW1POumkdO3ada30CwAAAEDtq1eTB7/77rurLV933XVp06ZNnnvuuRxwwAGl9fXr1095efla7XujjTbKSSedVFpu06ZNTj311BxzzDFZsGBBGjRoUNo2YsSIzJ8/P6effnr+8pe/rNU6AAAAAKgd63SOrzlz5mTJkiUpKyurtn7s2LHp2LFjevTokVNOOSUzZ85c631//PHHufPOO9OzZ89qodf48eMzbNiwXHvttdloI1OeAQAAABTFOk16zj777HTt2jW77rpraV3v3r1z7bXX5t57783FF1+cl156KX379s3ChQvXSp/nnXdeWrZsmW222Sbvvfdebr/99tK2uXPnpl+/fhkyZEhatmy5VvoDAAAA4MthnQVfP//5z/Pcc8/l5ptvTt26dUvrDzvssHzzm99M586dc8ABB2TUqFGZNGlSHn300WUe5913302rVq1KnyuvvHKF/Z5yyil56qmncs8996Ru3brp379/qqqqkiRnnXVWevXqlUMOOWTtnSgAAAAAXwo1OsfXFwYNGpS77747999/f9q1a7fCti1atEjLli0zefLk5W4fM2ZMablJkyYrPF7Tpk3TtGnTdOzYMZ06dUrnzp0zduzYfPWrX83o0aMzbdq03HbbbUlSCsQ6deqUU089NYMHD16NswQAAADgy6TGg6+zzjor99xzT+6///506tRppe0rKyvz/vvvL3ey+3r16qV9+/b/VS1LlixJknz22WdJknvuuaf030ny8ssvZ+DAgXnggQfSoUOH/6oPAAAAAL4cajT4OuOMM3L77bfnj3/8Y8rKyjJjxowkSaNGjdK4cePMmTMnl112Wfr27Zvy8vK88847ufDCC9O8efMcdNBBa9T3uHHjMn78+PTq1Subb7553n777VxyySVp06ZNevXqlSTp2LFjtX0qKyuT/OuJr6ZNm65R/wAAAADUrhoNvm644YYkWWoOrbPOOiuDBg1K3bp188Ybb+RPf/pTZs+enfLy8uyxxx658cYbs+mmm65R3w0aNMi9996bSy65JPPmzUt5eXl69+6dkSNHVvtVRwAAAACKqc6sWbOqaruI9c2le19S2yUAAAAArNCgJ35e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VORXv/pVvvWtb+WFF17Ipptuusb9//rXv87+++9fWt5ss82WanPXXXelS5cupeUmTZqscb8AAAAA1K4aD77q1auX8vLyZW6rqqrKiBEjcuqpp+aQQw5JkowYMSIVFRUZNWpUjj/++DXuf/PNN19u/1/YYostVtoGAAAAgPVLjc/xNWXKlGy33Xbp1q1bTjjhhEyZMqW0berUqZkxY0b22Wef0rqGDRvmq1/9ap5//vm10v/ZZ5+d9u3bZ++9987IkSOzZMmSpdocd9xx6dixY/bff//ce++9a6VfAAAAAGpXjT7x1bNnz/z2t79NRUVFPvroo1x++eXp06dPnnvuuWyxxRaZMWNGkqR58+bV9mvevHnef//9Ne7/5z//efbYY480atQoo0ePzrnnnpvKysqceeaZSZLGjRvnoosuSq9evVKvXr089NBDOf744zNixIgceeSRa9w/AAAAALWnRoOv/fbbr9pyz549071799x6660ZOHDgf3XMZ599NkcccURp+aqrrsp3vvOdZbb92c9+Vvrvbt26ZcmSJbnyyitLwVfTpk3zf/7P/ym12WmnnfLPf/4zw4YNE3wBAAAArOdqfI6vf9e4ceNst912mTx5cpKU5tWaOXNmWrduXWo3c+bMbLnllss8xk477ZQxY8aUlv/zabEV6dGjRz755JN8+OGHyz1+jx49csstt6zyMQEAAAD4cqrxOb7+3YIFCzJp0qRS4NW2bduUl5fniSeeqNZm7Nix2W233ZZ5jIYNG6Z9+/alz+r88uNrr72WBg0aZPPNN19hGxPdAwAAAKz/avSJr3PPPTff+MY3svXWW5fm+Jo3b16OPvroJEmdOnUyYMCADB06NBUVFenYsWOuuOKKNGrUKIcffvga9f3www/nww8/zC677JKGDRtmzJgxufTSS/P9738/9evXT5Lceuut2XjjjdOtW7dstNFGeeSRR3LDDTfk/PPPX9NTBwAAAKCW1WjwNX369Pzwhz9MZWVlmjVrlp49e+axxx5LmzZtSm1+8pOfZP78+TnzzDMza9as9OjRI3ffffdqPcm1LBtvvHFuuOGGnHPOOVmyZEnatWuXQYMG5cQTT6zW7oorrsi7776bunXrpkOHDvnNb35jfi8AAACAAqjR4GvkyJErbVOnTp0MGjQogwYNWqt99+7dO717915hm2OOOSbHHHPMWu0XAAAAgC+HdTrHFwAAAACsK4IvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKKR6tV3A+qjB986p7RJYD0yaNCkVFRW1XQYAAABssDzxBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQ6tV2Aeujqr/fVtslsB7omKTq7y/WdhlfCnW6HF3bJQAAALAB8sQXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCEnwBAAAAUEiCLwAAAAAKab0Kvi699NKUlZVV+3Tq1Klam7feeivf/e5306ZNm7Ro0SJ77rlnJk6cWEsVAwAAAFBb6tV2AauroqIiDzzwQGm5bt26pf+eMmVK9t9//xx11FG57777UlZWlv/93/9No0aNlnu8rl275re//W322GOPGq0bAAAAgHVrvQu+6tWrl/Ly8mVuu/jii7PPPvvkl7/8ZWldu3bt1lFlAAAAAHyZrFevOib/eqpru+22S7du3XLCCSdkypQpSZIlS5bkkUceybbbbpvDDjssHTp0yN5775277767dgsGAAAAoFasV8FXz54989vf/jajRo3Kr3/968yYMSN9+vTJP//5z8ycOTNz5szJ0KFDs/fee+eee+7JYYcdlhNPPDGPPvpobZcOAAAAwDq2Xr3quN9++1Vb7tmzZ7p3755bb701hx12WJLkm9/8ZgYOHJgk6datW1599dVcf/312X///ZMkhx9+eMaOHVs6xrx583LEEUdUmyts2rRpNX0qAAAAANSw9Sr4+k+NGzfOdtttl8mTJ6dp06apV69ett1222ptOnXqVO11x1//+tdZsGBBafmggw7K+eefn549e66zugEAAACoeet18LVgwYJMmjQpe+yxRzbZZJPsvPPOmTRpUrU2b731Vlq3bl1abtmyZbXtdevWTYsWLdK+fft1UjMAAAAA68Z6FXyde+65+cY3vpGtt946H330US6//PLMmzcvRx99dJLklFNOyfHHH5+vfvWr2XPPPTNmzJjcfffdueWWW2q5cgAAAADWtfUq+Jo+fXp++MMfprKyMs2aNUvPnj3z2GOPpU2bNkn+9dri1VdfnaFDh+bss89O+/btc+2115bm9wIAAABgw7FeBV8jR45caZtjjz02xx577Cof87XXXluTkgAAAAD4ktqotgsAAAAAgJog+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAhCb4AAAAAKCTBFwAAAACFJPgCAAAAoJAEXwAAAAAUkuALAAAAgEISfAEAAABQSIIvAAAAAApJ8AUAAABAIQm+AAAAACgkwRcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCqlfbBayP6nQ5urZLYD0wadKkVFRU1HYZAAAAsMHyxBcAAAAAhST4AgAAAKCQBF8AAAAAFJLgCwAAAIBCqjNr1qyq2i4CAAAAANY2T3wBAAAAUEiCLwAAAAAKSfAFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+FpFN9xwQ7p165by8vJ8/etfz7PPPlvbJVHLhg4dmr333jutW7dOhw4dcuSRR+aNN96o1mbAgAEpKyur9undu3ctVUxtuvTSS5caC506dSptr6qqyqWXXprtttsuW221VQ488MC8+eabtVgxtalr165LjZeysrJ85zvfSbLy8USxPfPMMznqqKOy/fbbp6ysLLfccku17atyPZk1a1b69++fNm3apE2bNunfv39mzZq1Ds+CdWVF4+Xzzz/Peeedl69+9atp2bJltt122/zwhz/Mu+++W+0YBx544FLXnBNOOGFdnwo1bGXXllW5r124cGHOPPPMtG/fPi1btsxRRx2VadOmrcvTYB1Z2XhZ1n1MWVlZzjjjjFIb35U2HKvy3bkm718EX6vg7rvvztlnn53TTz89Tz31VHbdddccccQRS90UsGF5+umn069fvzz66KO57777Uq9evRx66KH5+OOPq7Xba6+9MnHixNLnzjvvrKWKqW0VFRXVxsK/B+jDhg3L8OHDM2TIkPztb39L8+bN861vfSuffvppLVZMbXniiSeqjZXRo0enTp06OfTQQ0ttVjSeKLa5c+dmhx12yGWXXZaGDRsutX1Vric//OEPM2HChIwaNSqjRo3KhAkT8qMf/WhdngbryIrGy7x58zJ+/PicccYZGT16dG699dZMmzYthx9+eBYtWlSt7bHHHlvtmnPVVVety9NgHVjZtSVZ+X3toEGDcv/99+d3v/tdHnrooXz66ac58sgjs3jx4nVxCqxDKxsv/z5OJk6cmD/96U9JUu1eJvFdaUOxKt+da/L+pV6NnFXBDB8+PMccc0y+//3vJ0kuv/zy/PWvf83IkSNz3nnn1XJ11Ja777672vJ1112XNm3a5LnnnssBBxxQWl+/fv2Ul5ev6/L4EqpXr94yx0JVVVVGjBiRU089NYccckiSZMSIEamoqMioUaNy/PHHr+tSqWXNmjWrtnzzzTdn0003zbe+9a3SuuWNJ4qvT58+6dOnT5LkpJNOqrZtVa4nEydOzOOPP55HHnkku+66a5LkqquuygEHHJBJkyaloqJi3Z4QNWpF42XzzTfPn//852rrrrrqqvTq1SsTJ05M586dS+u/8pWvuOYU3IrGyhdWdF87e/bs3HzzzRk+fHj23nvvJP+6P+7atWuefPLJ7LvvvjVTOLViZePlP8fJQw89lI4dO+Z//ud/qq33XWnDsLLvzjV9/+KJr5X47LPP8uqrr2afffaptn6fffbJ888/X0tV8WU0Z86cLFmyJGVlZdXWjx07Nh07dkyPHj1yyimnZObMmbVTILVuypQp2W677dKtW7eccMIJmTJlSpJk6tSpmTFjRrXrTMOGDfPVr37VdYZUVVXl5ptvzpFHHlntX1SXN57YsK3K9WTcuHFp3Lhxdtttt1KbXr16pVGjRq45lP5l/T/vZ+666660b98+vXr1yrnnnuuJ5A3Uiu5rX3311Xz++efVrj9bb711tt12W9eWDdycOXNy9913lx4k+Xe+K22Y/vO7c03fv3jiayUqKyuzePHiNG/evNr65s2b58MPP6ylqvgyOvvss9O1a9dS+pwkvXv3zsEHH5y2bdvmnXfeycUXX5y+ffvmySefTP369WuxWta1nj175re//W0qKiry0Ucf5fLLL0+fPn3y3HPPZcaMGUmyzOvM+++/Xxvl8iXyxBNPZOrUqfne975XWrei8bTFFlvUYrXUtlW5nnz44Ydp2rRp6tSpU9pep06dNGvWzL3NBu6zzz7Lueeem2984xtp1apVaf0RRxyR1q1bZ6uttsr//b//NxdccEFef/313HPPPbVYLevayu5rP/zww9StWzdNmzattp/vTYwaNSqfffZZjj766GrrfVfacP3nd+eavn8RfMFa8POf/zzPPfdcHnnkkdStW7e0/rDDDiv9d+fOndO9e/d07do1jz76aPr27VsbpVJL9ttvv2rLPXv2TPfu3XPrrbdml112qaWqWB/8/ve/z84775yuXbuW1q1oPA0cOHBdlwgUwKJFi9K/f//Mnj07t912W7VtP/jBD0r/3blz57Rr1y777rtvXn311XTv3n3dFkqtcV/Lf+v3v/99vvnNby41lYMxtWFa3nfnmuRVx5Vo2rRp6tatu9QjlzNnzsyWW25ZS1XxZTJo0KDcddddue+++9KuXbsVtm3RokVatmyZyZMnr5vi+NJq3Lhxtttuu0yePLk0r4HrDP9p5syZeeihh5b5asC/+/fxxIZtVa4nW265ZSorK1NVVVXaXlVVlY8++sg1ZwO1aNGi9OvXL6+//nruvffelT45utNOO6Vu3bquORu4/7yv3XLLLbN48eJUVlZWa+d+ZsM2YcKEvPLKKyu9l0l8V9oQLO+7c03fvwi+VmKTTTZJ9+7d88QTT1Rb/8QTT1R7t5QN01lnnVX6H26nTp1W2r6ysjLvv/++CRzJggULMmnSpJSXl6dt27YpLy+vdp1ZsGBBxo4d6zqzgbv11ltTv379av8iuiz/Pp7YsK3K9WTXXXfNnDlzMm7cuFKbcePGZe7cua45G6DPP/88xx9/fF5//fXcf//9q3Qdef3117N48WLXnA3cf97Xdu/ePRtvvHG168+0adMyceJE15YN2O9///u0bds2e+2110rb+q5UbCv67lzT9y9edVwFJ598cn70ox+lR48e2W233TJy5Mh88MEHfmltA3fGGWfk9ttvzx//+MeUlZWV3ktu1KhRGjdunDlz5uSyyy5L3759U15ennfeeScXXnhhmjdvnoMOOqiWq2dd+2LOlK233ro0J9O8efNy9NFHp06dOhkwYECGDh2aioqKdOzYMVdccUUaNWqUww8/vLZLp5ZUVVXlD3/4Q7797W+ncePG1bataDxRfHPmzCn9a/iSJUvy3nvvZcKECWnSpElat2690uvJtttum969e+enP/1prr766iTJT3/60+y///5+0bGAVjReWrRoke9///t55ZVXctttt6VOnTql+5nNNtssDRs2zNtvv5077rgjffr0yRZbbJGJEyfm3HPPTbdu3dKrV6/aPDXWshWNlSZNmqz0vnbzzTfPcccdl/POOy/NmzdPkyZNcs4556Rz586rFHqwflnZ/xclybx583LnnXfmlFNOqTYv0xf7+6604VjZd+dV+T60JvcvdWbNmlW1whYkSW644YYMGzYsM2bMyPbbb59LLrkkX/va12q7LGrRf/7a0RfOOuusDBo0KPPnz8+xxx6bCRMmZPbs2SkvL88ee+yRc845J1tvvfW6LZZad8IJJ+TZZ59NZWVlmjVrlp49e+acc87Jdtttl+RfIcdll12Wm266KbNmzUqPHj1yxRVXZIcddqjlyqktTz31VPr27Zu//vWv6dGjR7VtKxtPFNuYMWNy8MEHL7X+6KOPzogRI1bpejJr1qz87Gc/y8MPP5wkOeCAA/KrX/1quf/fxvprRePl7LPPzo477rjM/YYPH55jjz027733Xvr3758333wzc+fOTatWrdKnT5+cffbZadKkSU2Xzzq0orEydOjQVbqvXbhwYc4999yMGjUqCxYsyJ577pkrr7zSvW8Brez/i5Lkj3/8Y37yk5/k73//e1q0aFGtne9KG5aVfXdOVu370H97/yL4AgAAAKCQzPEFAAAAQCEJvgAAAAAoJMEXAAAAAIUk+AIAAACgkARfAAAAABSS4AsAAACAQhJ8AQAAAFBIgi8AAAAACknwBQAAAEAh/X+3x6KcPP7dOAAAAABJRU5ErkJggg==" }, "metadata": {} } ], "metadata": {} } ], "metadata": { "orig_nbformat": 4, "language_info": { "name": "python", "version": "3.8.8", "mimetype": "text/x-python", "codemirror_mode": { "name": "ipython", "version": 3 }, "pygments_lexer": "ipython3", "nbconvert_exporter": "python", "file_extension": ".py" }, "kernelspec": { "name": "python3", "display_name": "Python 3.8.8 64-bit" }, "interpreter": { "hash": "53e4db133e7a886bd36ef8c79c0b5519f0af174d53fdba9ad5d5d94e6d9f4b55" } }, "nbformat": 4, "nbformat_minor": 2 }