{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **WhatsApp Chat Analysis in Streamlit**\n",
"\n",
"This notebook will guide you through building a **Streamlit app** to analyze WhatsApp chat data. The app allows users to upload their WhatsApp chat exports and provides various insights, such as message frequency, sentiment analysis, and the most active users."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **WhatsApp Chat Data Processing**\n",
"\n",
"In this notebook, we process a WhatsApp chat data file using regular expressions and `pandas` to clean and structure the data for further analysis.\n",
"\n",
"#### **Import Libraries** \n",
"\n",
"We will use `re` for regular expressions and `pandas` for data manipulation."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"d:\\WhatsApp-Conversations-Analysis\\notebook\n"
]
}
],
"source": [
"import os\n",
"print(os.getcwd()) # Prints the current working directory\n"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
User
\n",
"
Message
\n",
"
Day
\n",
"
Month
\n",
"
only_date
\n",
"
Year
\n",
"
month_num
\n",
"
AMPM
\n",
"
Hour
\n",
"
Minute
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
+92 303 6123098
\n",
"
Assalamualaikum wa rehmatullahi wa baraktuh
\n",
"
Thursday
\n",
"
July
\n",
"
2024-07-18
\n",
"
2024
\n",
"
7
\n",
"
pm
\n",
"
6
\n",
"
39
\n",
"
\n",
"
\n",
"
1
\n",
"
+92 303 6123098
\n",
"
Agr koe kr skta to mjy bta dyn Mai unko cv per...
\n",
"
Thursday
\n",
"
July
\n",
"
2024-07-18
\n",
"
2024
\n",
"
7
\n",
"
pm
\n",
"
6
\n",
"
40
\n",
"
\n",
"
\n",
"
2
\n",
"
+92 328 9460713
\n",
"
<Media omitted>
\n",
"
Thursday
\n",
"
July
\n",
"
2024-07-18
\n",
"
2024
\n",
"
7
\n",
"
pm
\n",
"
9
\n",
"
36
\n",
"
\n",
"
\n",
"
3
\n",
"
+92 328 9460713
\n",
"
Remember Brothers, Don't miss it !
\n",
"
Thursday
\n",
"
July
\n",
"
2024-07-18
\n",
"
2024
\n",
"
7
\n",
"
pm
\n",
"
9
\n",
"
38
\n",
"
\n",
"
\n",
"
4
\n",
"
+92 310 8668380
\n",
"
<Media omitted>
\n",
"
Friday
\n",
"
July
\n",
"
2024-07-19
\n",
"
2024
\n",
"
7
\n",
"
am
\n",
"
3
\n",
"
18
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" User Message \\\n",
"0 +92 303 6123098 Assalamualaikum wa rehmatullahi wa baraktuh \n",
"1 +92 303 6123098 Agr koe kr skta to mjy bta dyn Mai unko cv per... \n",
"2 +92 328 9460713 \n",
"3 +92 328 9460713 Remember Brothers, Don't miss it ! \n",
"4 +92 310 8668380 \n",
"\n",
" Day Month only_date Year month_num AMPM Hour Minute \n",
"0 Thursday July 2024-07-18 2024 7 pm 6 39 \n",
"1 Thursday July 2024-07-18 2024 7 pm 6 40 \n",
"2 Thursday July 2024-07-18 2024 7 pm 9 36 \n",
"3 Thursday July 2024-07-18 2024 7 pm 9 38 \n",
"4 Friday July 2024-07-19 2024 7 am 3 18 "
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import re\n",
"import pandas as pd # type: ignore\n",
"\n",
"# Read the WhatsApp chat file\n",
"with open(\"WhatsApp Chat with Group discussion(AI).txt\", \"r\", encoding=\"utf-8\") as f:\n",
" data = f.read()\n",
"\n",
"# Regex pattern to match the chat log format\n",
"pattern = r\"(\\d{2}/\\d{2}/\\d{4}),\\s(\\d{1,2}:\\d{2}\\s?[ap]m)\\s-\\s(\\+\\d{2}\\s\\d{3}\\s\\d{7}):\\s(.*)\"\n",
"\n",
"# Extract matches using the regex pattern\n",
"matches = re.findall(pattern, data)\n",
"\n",
"# Create a DataFrame from the extracted matches\n",
"df = pd.DataFrame(matches, columns=['Date', 'Time', 'User', 'Message'])\n",
"\n",
"# Convert the 'Date' column to datetime format\n",
"df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y')\n",
"\n",
"# Extract the Day name (e.g., Monday, Tuesday) and Month name\n",
"df['Day'] = df['Date'].dt.strftime('%A') # Full day name\n",
"df['Month'] = df['Date'].dt.strftime('%B') # Full month name\n",
"df['only_date'] = df['Date'].dt.date\n",
"df['Year'] = df['Date'].dt.year # Year as a separate column\n",
"df['month_num'] = df['Date'].dt.month\n",
"\n",
"# Clean and split the 'Time' column into components\n",
"df[['Hour_Minute', 'AMPM']] = df['Time'].str.extract(r'(\\d{1,2}:\\d{2})\\s?(am|pm)', expand=True)\n",
"\n",
"# Split the 'Hour_Minute' into 'Hour' and 'Minute'\n",
"df[['Hour', 'Minute']] = df['Hour_Minute'].str.split(':', expand=True)\n",
"\n",
"# Drop the original 'Date' and 'Time' columns if they are no longer needed\n",
"df = df.drop(columns=['Date', 'Time', 'Hour_Minute'])\n",
"\n",
"# Display the first few rows of the DataFrame\n",
"df.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **2. Basic Statistics** ###"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Year
\n",
"
month_num
\n",
"
\n",
" \n",
" \n",
"
\n",
"
count
\n",
"
960.0
\n",
"
960.000000
\n",
"
\n",
"
\n",
"
mean
\n",
"
2024.0
\n",
"
8.801042
\n",
"
\n",
"
\n",
"
std
\n",
"
0.0
\n",
"
1.377988
\n",
"
\n",
"
\n",
"
min
\n",
"
2024.0
\n",
"
7.000000
\n",
"
\n",
"
\n",
"
25%
\n",
"
2024.0
\n",
"
8.000000
\n",
"
\n",
"
\n",
"
50%
\n",
"
2024.0
\n",
"
8.000000
\n",
"
\n",
"
\n",
"
75%
\n",
"
2024.0
\n",
"
10.000000
\n",
"
\n",
"
\n",
"
max
\n",
"
2024.0
\n",
"
11.000000
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Year month_num\n",
"count 960.0 960.000000\n",
"mean 2024.0 8.801042\n",
"std 0.0 1.377988\n",
"min 2024.0 7.000000\n",
"25% 2024.0 8.000000\n",
"50% 2024.0 8.000000\n",
"75% 2024.0 10.000000\n",
"max 2024.0 11.000000"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.describe()"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"RangeIndex: 960 entries, 0 to 959\n",
"Data columns (total 10 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 User 960 non-null object\n",
" 1 Message 960 non-null object\n",
" 2 Day 960 non-null object\n",
" 3 Month 960 non-null object\n",
" 4 only_date 960 non-null object\n",
" 5 Year 960 non-null int32 \n",
" 6 month_num 960 non-null int32 \n",
" 7 AMPM 960 non-null object\n",
" 8 Hour 960 non-null object\n",
" 9 Minute 960 non-null object\n",
"dtypes: int32(2), object(8)\n",
"memory usage: 67.6+ KB\n"
]
}
],
"source": [
"# Basic stats and general information\n",
"df.info()"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(960, 10)"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Analyzing Unique Users in a Dataset**"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Overall',\n",
" '+92 300 4974756',\n",
" '+92 300 6372500',\n",
" '+92 300 7045809',\n",
" '+92 300 8760724',\n",
" '+92 300 9480599',\n",
" '+92 302 1104820',\n",
" '+92 302 6188000',\n",
" '+92 302 6550280',\n",
" '+92 302 6791109',\n",
" '+92 303 6123098',\n",
" '+92 304 1933595',\n",
" '+92 304 4770248',\n",
" '+92 304 5561462',\n",
" '+92 304 6510483',\n",
" '+92 305 1859128',\n",
" '+92 305 2142860',\n",
" '+92 305 7933007',\n",
" '+92 306 4258670',\n",
" '+92 306 6785416',\n",
" '+92 306 9287947',\n",
" '+92 307 3732356',\n",
" '+92 307 4641982',\n",
" '+92 307 7789508',\n",
" '+92 308 3769685',\n",
" '+92 308 7112492',\n",
" '+92 309 2095756',\n",
" '+92 309 3108513',\n",
" '+92 309 7095014',\n",
" '+92 310 4361015',\n",
" '+92 310 4943542',\n",
" '+92 310 8668380',\n",
" '+92 311 1323932',\n",
" '+92 311 9396966',\n",
" '+92 312 3478519',\n",
" '+92 312 9581399',\n",
" '+92 313 1029011',\n",
" '+92 313 2040046',\n",
" '+92 313 4997451',\n",
" '+92 314 1721775',\n",
" '+92 315 1521759',\n",
" '+92 315 4292972',\n",
" '+92 315 4534792',\n",
" '+92 317 1476609',\n",
" '+92 317 9661942',\n",
" '+92 319 6457650',\n",
" '+92 319 7200178',\n",
" '+92 320 8587480',\n",
" '+92 320 9099349',\n",
" '+92 321 2226008',\n",
" '+92 321 2721004',\n",
" '+92 321 3605311',\n",
" '+92 321 4122103',\n",
" '+92 321 8788609',\n",
" '+92 322 5305720',\n",
" '+92 322 8485616',\n",
" '+92 323 5114548',\n",
" '+92 323 6606342',\n",
" '+92 323 8862333',\n",
" '+92 324 0849609',\n",
" '+92 324 3909940',\n",
" '+92 324 7280468',\n",
" '+92 326 0927271',\n",
" '+92 327 2636962',\n",
" '+92 327 6110594',\n",
" '+92 327 7179560',\n",
" '+92 328 8822005',\n",
" '+92 328 9460713',\n",
" '+92 331 2470902',\n",
" '+92 331 3632939',\n",
" '+92 331 4484468',\n",
" '+92 332 2080596',\n",
" '+92 332 8021821',\n",
" '+92 332 8298997',\n",
" '+92 332 9620056',\n",
" '+92 333 0229088',\n",
" '+92 333 1727254',\n",
" '+92 333 2203353',\n",
" '+92 333 9365986',\n",
" '+92 334 1352612',\n",
" '+92 334 2763208',\n",
" '+92 334 2787399',\n",
" '+92 334 3391992',\n",
" '+92 334 5332804',\n",
" '+92 334 7636590',\n",
" '+92 334 9417243',\n",
" '+92 336 0367246',\n",
" '+92 336 2710451',\n",
" '+92 336 7509812',\n",
" '+92 340 3832748',\n",
" '+92 340 5790021',\n",
" '+92 341 0113675',\n",
" '+92 342 1485637',\n",
" '+92 342 1822526',\n",
" '+92 343 2078351',\n",
" '+92 343 6411185',\n",
" '+92 344 0544757',\n",
" '+92 344 5881772',\n",
" '+92 344 8693214',\n",
" '+92 345 0944813',\n",
" '+92 345 7962931',\n",
" '+92 345 9138794',\n",
" '+92 346 2764766',\n",
" '+92 348 7906778']"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Step 3: Extract unique users\n",
"unique_users = df['User'].unique().tolist()\n",
"\n",
"# Step 4: Remove system-generated notifications\n",
"if 'group_notification' in unique_users:\n",
" unique_users.remove('group_notification')\n",
"\n",
"# Step 5: Sort users alphabetically and add \"Overall\" option at the start\n",
"unique_users.sort()\n",
"unique_users.insert(0, \"Overall\")\n",
"unique_users\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"User '+92 300 4974756' is in the list.\n"
]
}
],
"source": [
"# Step 6: Display the specified user if they exist\n",
"specific_user = \"+92 300 4974756\"\n",
"if specific_user in unique_users:\n",
" print(f\"User '{specific_user}' is in the list.\")\n",
"else:\n",
" print(f\"User '{specific_user}' is not in the list.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Fetching User Stats for WhatsApp Data**\n"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"from urlextract import URLExtract # type: ignore\n",
"from collections import Counter\n",
"import emoji # type: ignore\n",
"from wordcloud import WordCloud # type: ignore\n",
"\n",
"# Create an object that will help in extracting URLs\n",
"extract = URLExtract()\n",
"\n",
"class Helper:\n",
" def __init__(self, df):\n",
" \"\"\"\n",
" Initializes the Helper class with a DataFrame containing WhatsApp data.\n",
" \n",
" Parameters:\n",
" df (pd.DataFrame): The DataFrame containing the WhatsApp data.\n",
" \"\"\"\n",
" self.df = df\n",
"\n",
" def fetch_stats(self, selected_user):\n",
" \"\"\"\n",
" Fetch basic statistics for a selected user or for all users if 'Overall' is selected.\n",
"\n",
" Parameters:\n",
" selected_user (str): The user to fetch stats for, or 'Overall' for aggregate stats.\n",
"\n",
" Returns:\n",
" tuple: A tuple containing the number of messages, number of words, \n",
" number of media messages, and number of links shared.\n",
" \"\"\"\n",
" # Ensure selected_user is a string (in case it's a pandas Series)\n",
" if not isinstance(selected_user, str):\n",
" raise ValueError(\"selected_user should be a string\")\n",
"\n",
" # If the selected user is not 'Overall', filter the data for that specific user\n",
" if selected_user != 'Overall':\n",
" df_filtered = self.df[self.df['User'] == selected_user]\n",
" else:\n",
" df_filtered = self.df # Use entire DataFrame for 'Overall' stats\n",
"\n",
" # Count how many messages the selected user has sent\n",
" num_messages = df_filtered.shape[0]\n",
"\n",
" # Create a list to hold all words from the messages\n",
" words = []\n",
" for message in df_filtered['Message']:\n",
" words.extend(message.split())\n",
"\n",
" # Count how many media messages (like images or videos) the user sent\n",
" num_media_messages = df_filtered[df_filtered['Message'] == ''].shape[0]\n",
"\n",
" # Create a list to hold all the links shared by the user\n",
" links = []\n",
" for message in df_filtered['Message']:\n",
" links.extend(extract.find_urls(message))\n",
"\n",
" # Return the statistics: total messages, word count, media count, link count\n",
" return num_messages, len(words), num_media_messages, len(links)\n"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [],
"source": [
"helper = Helper(df)\n"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Stats for User:(4, 94, 0, 0)\n",
"Number of messages: 4\n",
"Number of words: 94\n",
"Number of media messages: 0\n",
"Number of links shared: 0\n"
]
}
],
"source": [
"# Fetch stats for a specific user (e.g., \"User1\")\n",
"user_stats = helper.fetch_stats(specific_user)\n",
"\n",
"\n",
"# Display the results for User1\n",
"print(F\"Stats for User:{user_stats}\")\n",
"print(f\"Number of messages: {user_stats[0]}\")\n",
"print(f\"Number of words: {user_stats[1]}\")\n",
"print(f\"Number of media messages: {user_stats[2]}\")\n",
"print(f\"Number of links shared: {user_stats[3]}\")\n",
"# Fetch overall stats (aggregated for all users)\n"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Overall Stats:\n",
"Number of messages: 960\n",
"Number of words: 7960\n",
"Number of media messages: 145\n",
"Number of links shared: 52\n"
]
}
],
"source": [
"# Fetch overall stats (aggregated for all users)\n",
"overall_stats = helper.fetch_stats(\"Overall\")\n",
"\n",
"# Display the overall stats\n",
"print(\"\\nOverall Stats:\")\n",
"print(f\"Number of messages: {overall_stats[0]}\")\n",
"print(f\"Number of words: {overall_stats[1]}\")\n",
"print(f\"Number of media messages: {overall_stats[2]}\")\n",
"print(f\"Number of links shared: {overall_stats[3]}\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Visualizing Top 5 Most Active Users in Groups**"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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1/Ogb7/91mbEd9SoURo1alS8265YsUJXrlyRr6/vI6/v9OnTSVLPk2TPnl3Vq1fXb7/9JsMwtGjRIq1atcq6/sFRbsn2d1C4cOFHrrX+oCJFiiSohowZM+rPP/+UJJ09e1aGYdi0rVOnTj2yfZyn+d0+/P6OGDEiUfMSeHh4xLu8ZcuWatq0qXbv3q3g4GD98ccf2rBhgw4cOKBbt26pU6dOqlevnvUa3M/qwS8rpMT9f3z11VetRzXExsZq3rx51i+/nJ2d1a9fP0nSokWLrPM7PEl8701i+7eHR5Uf/PIlNjZWf/3113/WIyW8X3ze/QQAxMu+R7cDgGNzlHO6Z82aZfz666/W/cT5559/bM43zpw58yPbPM6DNb733nvW5f3797cu/+STT6zLH3dO98GDBxN1TndwcLBx7969R+rq2bOndft69epZl3/33Xc2z5PQc+HjFChQIN5zYR93+/zzzw3DePSc7mzZsj1y+a2rV68aN27csN4fOXKkdfuMGTPGW89/nfe9YMECm/Vxs8u7uro+Mut97969bd7j+M5TjoqKMn7++Wfj6tWrCXq/HtynJOPLL7+0rrt8+bLNbPXOzs42+32a3+3D7WfatGnx1nP48GGby24l5Bz/K1euGGfOnHlk+dWrV20eu3fv3v98P57mkmEJfdzjXLx40UiXLp3NeeK//fbbI9uVLFkyQed0P3zetWE8/TndBw8eNAzj/mXtHlw+dOhQ62NmzJhhsy4pzul+2n4CAMzASDcAmMTX11cdOnTQV199JUn64YcfdP369UdmL5fujxA/OLr7oLVr1+rVV19V5cqVtXXrVpuZid98802lSZPmP2s5cuSIunbtqly5cqlWrVoKCAjQP//8o4ULF9oc9tmtW7dnPgf0/ffft84GXq1atf/c/uWXX9arr75qfV1jx47VqVOnVLhwYa1du9bmXNBevXpZR8r69eun3bt369VXX1VAQIAyZsyo8+fPa86cOdbtHzwK4OFzb998802VL19eTk5Oatu27SOHpz5o586dOn78uPV+mTJlHjkMWLo/a3Tc4flz5sxRz5495eTkpP79++v999+XJP39998qWLCgdfby06dPa+nSpdqwYYOKFSv2SK2XLl1Sx44dVahQIVksFnXv3j1BI7mNGze2zqp+9uxZ6/K6devajCpL908LmDFjhiIiInT16lUVK1ZMzZs3V0BAgG7duqWjR49q48aNun79uk6fPv3YozIe1LVrV02ZMkXR0dGSpC5dumjixIlKnz69Dh8+rBs3bli3bdmypc0+n+Z3+/LLL6tmzZrWkd0ePXpo1apVKlmypJycnHT27Flt375dx44d0/Dhw1WxYsX/rD3OyZMnVa5cOZUqVUovv/yysmTJIhcXF61evdpmu6Q+2uRZZcyYUTNmzFCbNm1kGIZu376tGjVqqHr16ipXrpw8PDz0999/648//kj0czg5OalPnz4aOnSopPunMVSsWFG1atXS8ePHbWY1r1atml5++WVJ90ee8+XLp5MnT0q6f8TIgQMHdPfu3aea4Tyh/eLT9hMAYAp7p34AcGRJcZ3uChUqPPE63XXr1o33cTlz5nxkFuzH6dWr13+OzLZo0eKprtX94GMfHOl+nMeNdBvG/et0Pzjjcny3h6/TXbt27Sdu7+7ubuzevdu6fUREhJE5c+Z4t42bhfxx3n77beu2Tk5OxtmzZ+PdbujQoTb7PXTokGEYCb9O94Pvx+OumR03Sp6QEdAHryked1u+fHm82y5ZssTw8PD4z3Zy+vTpJ75XD/ryyy8NFxeXJ+6vePHij4yeP+3vNiws7InX6Y7v/2dCRrp37Njxn/ts0qRJgt6L5znSHef77783vLy8/vM1PPw6EjLSbRj3j0Rp3rz5E/dbsGBBm9nYDcMwZs+eHe+2uXLlsjmi5Ekj3QntF5+2LQGAGZhIDQBM5OHhofXr12v27NmqVq2a0qdPLxcXF/n4+KhKlSqaOXOmNm7c+MTzQfv166eFCxeqZMmScnd3l6+vr9q3b6/t27c/MpnQ4wwcOFAzZ85UgwYNlC9fPnl5ecnV1VWZM2dW/fr19fPPP+v777+Xi4t9DoDy9/fXnj17NGHCBJUrV05eXl5ycXFRxowZ9dprr2nRokX68ccfberr37+/evXqpbJlyypr1qxKlSqV3NzclCtXLrVv3167d++2mSzMzc1NK1euVK1ateTp6Zng2iIiImyu712jRg1lz5493m07dOhgc6RA3GiaxWLRl19+qbVr11pHkFOlSqW0adMqf/786tq1q82kVv7+/vrll19UoUKFx55rnBAPn7udKVMm66RSD2vUqJEOHz6svn376qWXXlLatGnl7OwsX19flStXTv3799e2bdviHeF/nM6dO2vv3r3q0qWL8ufPrzRp0sjFxUUZMmRQtWrVNHXqVO3YseORkfOn/d36+flp165dmj59uqpXr64MGTLI2dlZHh4eKlCggNq0aaP58+erf//+CX/zdH/m8AkTJqhJkybW/zfOzs7y8fFRhQoV9Pnnnyf5RGpJqUWLFjp9+rTGjx+vGjVqKFOmTNb3MkuWLKpatao++OADbdmyRT/99NNT79/Z2Vk//PCDFi9erNdff11+fn5ycXGRl5eXypQpo3HjxmnPnj02s7FLUqdOnfTll1+qYMGCSpUqlfz9/dWtWzft3r37iUecPCih/eLTtiUAMIPFMBJ5bRgAgCnOnDljM8P1hg0bVLVqVfsVBAB2Rr8IwJEx0g0AAAAAgEkI3QAAAAAAmITQDQAAAACASTinGwAAAAAAkzDSDQAAAACASQjdAAAAAACYxD4XZLWj2NhYnT9/XunSpbO5lioAAAAAAAllGIZu3rypLFmyyMnp8ePZKS50nz9/XgEBAfYuAwAAAADwAggJCVG2bNkeuz7Fhe506dJJuv/GeHp62rkaAAAAAIAjCg8PV0BAgDVjPk6KC91xh5R7enoSugEAAAAAz+S/TltmIjUAAAAAAExC6AYAAAAAwCSEbgAAAAAATELoBgAAAADAJIRuAAAAAABMQugGAAAAAMAkhG4AAAAAAExC6AYAAAAAwCSEbgAAAAAATELoBgAAAADAJIRuAAAAAABMQugGAAAAAMAkhG4AAAAAAExC6AYAAAAAwCSEbgAAAAAATELoBgAAAADAJIRuAAAAAABM4mLvAvB49d9bZu8S4CB+mdDQ3iUAAAAAiAcj3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYxMXeBQB4sbT4vpu9S4CD+OGN6fYuAQAAwHSMdAMAAAAAYBJCNwAAAAAAJiF0AwAAAABgEkI3AAAAAAAmIXQDAAAAAGASQjcAAAAAACYhdAMAAAAAYBJCNwAAAAAAJklWoTsmJkZDhw5VYGCgUqdOrdy5c+vjjz+WYRjWbQzD0LBhw5Q5c2alTp1aNWrU0B9//GHHqgEAAAAAiF+yCt2ffvqppk+frilTpujYsWP69NNPNXbsWE2ePNm6zdixY/XFF19oxowZ2rVrlzw8PFS7dm1FRETYsXIAAAAAAB7lYu8CHrR9+3Y1bNhQdevWlSTlzJlTCxcu1O7duyXdH+WeNGmShgwZooYNG0qS5s2bp0yZMmnp0qVq2bKl3WoHAAAAAOBhyWqku3z58lq/fr1OnjwpSTp06JC2bt2qOnXqSJJOnz6t0NBQ1ahRw/oYLy8vlSlTRjt27LBLzQAAAAAAPE6yGun+4IMPFB4ergIFCsjZ2VkxMTEaNWqUWrduLUkKDQ2VJGXKlMnmcZkyZbKue1hkZKQiIyOt98PDw02qHgAAAAAAW8lqpPuHH37Q/PnztWDBAu3fv1/ffPONxo8fr2+++SbR+xw9erS8vLyst4CAgCSsGAAAAACAx0tWobt///764IMP1LJlS7300ktq27at+vTpo9GjR0uS/P39JUlhYWE2jwsLC7Oue9jAgQN148YN6y0kJMTcFwEAAAAAwP9LVqH7zp07cnKyLcnZ2VmxsbGSpMDAQPn7+2v9+vXW9eHh4dq1a5fKlSsX7z7d3Nzk6elpcwMAAAAA4HlIVud0169fX6NGjVL27NlVuHBhHThwQBMnTtRbb70lSbJYLOrdu7dGjhypvHnzKjAwUEOHDlWWLFnUqFEj+xYPAAAAAMBDklXonjx5soYOHap33nlHFy9eVJYsWfT2229r2LBh1m3ef/993b59W127dtX169dVsWJFrV69Wu7u7nasHAAAAACAR1kMwzDsXcTzFB4eLi8vL924cSPZH2pe/71l9i4BDuKXCQ3tXYJVi++72bsEOIgf3phu7xIAAAASLaHZMlmd0w0AAAAAwIuE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJjExd4FAABgb+HfVbN3CXAQnm022LsEAICDYaQbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkyS70P3PP/+oTZs28vX1VerUqfXSSy9p79691vWGYWjYsGHKnDmzUqdOrRo1auiPP/6wY8UAAAAAAMQvWYXua9euqUKFCnJ1ddWqVat09OhRTZgwQT4+PtZtxo4dqy+++EIzZszQrl275OHhodq1aysiIsKOlQMAAAAA8CgXexfwoE8//VQBAQGaM2eOdVlgYKD1Z8MwNGnSJA0ZMkQNGzaUJM2bN0+ZMmXS0qVL1bJly+deMwAAAAAAj5OsRrqXL1+uV155Rc2bN5efn5+KFy+uL7/80rr+9OnTCg0NVY0aNazLvLy8VKZMGe3YscMeJQMAAAAA8FjJKnSfOnVK06dPV968ebVmzRp169ZNPXv21DfffCNJCg0NlSRlypTJ5nGZMmWyrntYZGSkwsPDbW4AAAAAADwPyerw8tjYWL3yyiv65JNPJEnFixfX4cOHNWPGDLVv3z5R+xw9erQ++uijpCwTAAAAAIAESVYj3ZkzZ1ahQoVslhUsWFDnzp2TJPn7+0uSwsLCbLYJCwuzrnvYwIEDdePGDestJCTEhMoBAAAAAHhUsgrdFSpU0IkTJ2yWnTx5Ujly5JB0f1I1f39/rV+/3ro+PDxcu3btUrly5eLdp5ubmzw9PW1uAAAAAAA8D8nq8PI+ffqofPny+uSTT9SiRQvt3r1bs2bN0qxZsyRJFotFvXv31siRI5U3b14FBgZq6NChypIlixo1amTf4gEAAAAAeEiiRro3b96sS5cuPXb95cuXtXnz5qfeb6lSpbRkyRItXLhQRYoU0ccff6xJkyapdevW1m3ef/99vfvuu+ratatKlSqlW7duafXq1XJ3d0/MSwEAAAAAwDSJCt3VqlXTunXrHrt+/fr1qlatWqIKqlevnoKDgxUREaFjx46pS5cuNustFotGjBih0NBQRURE6LffflO+fPkS9VwAAAAAAJgpUaHbMIwnro+MjJSzs3OiCgIAAAAA4EWR4HO6z507pzNnzljvHz9+PN5DyK9fv66ZM2daJz8DAAAAACClSnDonjNnjj766CNZLBZZLBaNGjVKo0aNemQ7wzDk7OysmTNnJmmhAAAAAAA4mgSH7hYtWqhIkSIyDEMtWrRQz549ValSJZttLBaLPDw8VKxYMWXKlCnJiwUAAAAAwJEkOHQXLFhQBQsWlHR/1Lty5coKDAw0rTAAAAAAABxdoq7T3b59+6SuAwAAAACAF06iQrckHTt2THPmzNGpU6d07dq1R2Y0t1gsWr9+/TMXCAAAAACAo0pU6P7222/VsWNHubq6Kn/+/PLx8Xlkm/+6rBgAAAAAAC+6RIXuDz/8UMWLF9eqVauUIUOGpK4JAAAAAIAXglNiHnT+/Hm99dZbBG4AAAAAAJ4gUaG7aNGiOn/+fFLXAgAAAADACyVRoXvixIn66quvtH379qSuBwAAAACAF0aizun+9NNP5eXlpUqVKqlQoULKnj27nJ2dbbaxWCxatmxZkhQJAAAAAIAjSlToDgoKksViUfbs2XXr1i0dPXr0kW0sFsszFwcAAAAAgCNLVOg+c+ZMEpcBAAAAAMCLJ1HndAMAAAAAgP+WqJHuc+fOJWi77NmzJ2b3AAAAAAC8EBIVunPmzJmgc7ZjYmISs3sAAAAAAF4IiQrdX3/99SOhOyYmRmfOnNG8efPk5+en7t27J0mBAAAAAAA4qkSF7g4dOjx23YABA1SmTBnduHEjsTUBAAAAAPBCSPKJ1Dw8PNSxY0d99tlnSb1rAAAAAAAciimzl8fGxio0NNSMXQMAAAAA4DASdXj544SHh2vz5s0aN26cihcvnpS7BgAAAADA4SQqdDs5OT129nLDMJQ9e3ZNmzbtmQoDAAAAAMDRJSp0Dxs27JHQbbFY5OPjo9y5c6tWrVpycUnSQXQAAAAAABxOopLxhx9+mMRlAAAA4Glsa9jU3iXAQVRY9pO9SwBStGcejr5165ZCQkIkSQEBAUqbNu0zFwUAAAAAwIsg0bOX79mzR9WqVZOPj4+KFCmiIkWKyMfHR9WrV9fevXuTskYAAAAAABxSoka6d+3apapVqypVqlTq3LmzChYsKEk6duyYFi5cqMqVK2vjxo0qXbp0khYLAAAAAIAjSVToHjx4sLJmzaqtW7fK39/fZt2HH36oChUqaPDgwVq3bl2SFAkAAAAAgCNK1OHlu3bt0ttvv/1I4JakTJkyqWvXrtq5c+czFwcAAAAAgCNLVOh2cnJSdHT0Y9fHxMTIySnRp4sDAAAAAPBCSFQyLl++vKZOnaqzZ88+su7cuXOaNm2aKlSo8MzFAQAAAADgyBJ1Tvcnn3yiypUrq0CBAmrcuLHy5csnSTpx4oSWLVsmFxcXjR49OkkLBQAAAADA0SQqdBcvXly7du3S4MGDtXz5ct25c0eSlCZNGr322msaOXKkChUqlKSFAgAAAADgaBIVuiWpUKFCWrJkiWJjY3Xp0iVJUsaMGTmXGwAAAACA//dUofv8+fOSpCxZsliXOTk5KVOmTDbbWCwWZc6cOYlKBAAAAADAMSV4WHrfvn3Knj27Fi1a9MTtFi1apOzZsys4OPiZiwMAAAAAwJElOHRPnTpV+fLlU58+fZ64XZ8+fZQ/f3598cUXz1wcAAAAAACOLMGhe8OGDWrRooUsFssTt7NYLGrevLnWr1//zMUBAAAAAODIEhy6L1y4oJw5cyZo2+zZs1vP/wYAAAAAIKVKcOj28PDQ1atXE7TttWvXlCZNmkQXBQAAAADAiyDBobto0aL65ZdfErTtr7/+qqJFiya6KAAAAAAAXgQJvmRYu3bt1KlTJ02ePFnvvvvuY7ebMmWKNm3apNmzZydJgQAAAABeDCPeS9ggHjBsQn17l5BkEhy627dvrx9++EG9e/fWypUr1aZNG7300ktKly6dbt68qeDgYH333Xdau3atatasqQ4dOphYNgAAAAAAyV+CQ7eTk5OWLFmifv36adasWVq7dq3NesMw5OzsrLffflsTJkz4z1nOAQAAAAB40SU4dEuSu7u7pkyZooEDB2rVqlU6duyYwsPD5enpqQIFCqhOnTrKli2bWbUCAAAAAOBQnip0x8maNas6d+6c1LUAAAAAAPBCSfDs5QAAAAAA4OkQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTJCp0d+vWTdu3b0/qWgAAAAAAeKEkKnQvWLBAlSpVUu7cuTV8+HD98ccfSV0XAAAAAAAOL1Gh++LFi1q0aJGKFCmiMWPGqECBAipTpoymTp2qy5cvJ3WNAAAAAAA4pESFbjc3NzVv3lzLli1TaGiopk2bJjc3N/Xs2VNZs2ZVvXr19MMPPygiIiKp6wUAAAAAwGE880RqPj4+evvtt7V582adPn1ajRo10sqVK9WqVSv5+/urc+fOCgoKSopaAQAAAABwKEkye3lISIjGjBmjunXravHixfL19VW3bt301ltvafny5SpRooSmT5+eFE8FAAAAAIDDSHTovn79umbNmqUqVaooMDBQH374ofLly6eff/5Z58+f15QpUzRx4kSFhISoQYMGGjFiRFLWDQAAAABAsueSmAc1btxYq1at0r1791SmTBlNnjxZLVu2lI+PzyPburm5qVmzZlq6dOmz1goAAAAAgENJVOg+cOCA+vfvr3bt2ilv3rz/uX3NmjW1YcOGxDwVAAAAAAAOK1Gh+8yZM0+1fcaMGVWlSpXEPBUAAAAAAA4rUed0Ozs7a+HChY9d//3338vZ2TnRRQEAAAAA8CJIVOg2DEOGYTx2fUxMjCwWS6KLAgAAAADgRZDo2csfF6rDw8O1Zs0aZciQIdFFAQAAAADwIkhw6P7oo4/k7OwsZ2dnWSwWtWnTxnr/wZuPj4++/fZbtWzZ0sy6AQAAAABI9hI8kVrp0qX1zjvvyDAMTZs2TTVr1lS+fPlstrFYLPLw8FDJkiXVpEmTJC8WAAAAAABHkuDQXadOHdWpU0eSdPv2bf3vf/9TmTJlTCsMAAAAAABHl6hLhs2ZMyep6wAAAAAA4IWToNA9b948SVLbtm1lsVis9/9Lu3btEl8ZAAAAAAAOLkGhu0OHDrJYLGrZsqVSpUqlDh06/OdjLBYLoRsAAAAAkKIlKHSfPn1akpQqVSqb+wAAAAAA4PESFLpz5MjxxPsAAAAAAOBRCb5O94Pef/99HThwIKlrAQAAAADghZKo0D158mS98soryps3r4YOHarg4OCkrgsAAAAAAIeXqNB98eJFzZkzR/ny5dPYsWNVrFgxFS5cWB9//LFOnDiR1DUCAAAAAOCQEhW606VLp3bt2mnFihUKCwvTrFmzlC1bNn388ccqVKiQihUrpjFjxiR1rQAAAAAAOJREhe4HeXt7q1OnTlqzZo0uXLigCRMm6PTp0xo8eHBS1AcAAAAAgMN65tAtSVFRUVq+fLl69uypYcOG6ebNm8qWLdsz7XPMmDGyWCzq3bu3dVlERIS6d+8uX19fpU2bVk2bNlVYWNgzVg8AAAAAgDkSHbqjo6O1cuVKtW/fXhkzZlSjRo20ceNGdezYUVu3btXZs2cTXdSePXs0c+ZMFS1a1GZ5nz599Msvv2jx4sXatGmTzp8/ryZNmiT6eQAAAAAAMFOCrtP9sE6dOmnp0qW6du2aMmTIoFatWqlly5aqXLmyLBbLMxV069YttW7dWl9++aVGjhxpXX7jxg199dVXWrBggapXry5JmjNnjgoWLKidO3eqbNmyz/S8AAAAAAAktUSNdC9dulSNGze2nsc9ffp0ValS5ZkDtyR1795ddevWVY0aNWyW79u3T1FRUTbLCxQooOzZs2vHjh2P3V9kZKTCw8NtbgAAAAAAPA+JGukOCwuTi0uiHvpEixYt0v79+7Vnz55H1oWGhipVqlTy9va2WZ4pUyaFhoY+dp+jR4/WRx99lNSlAgAAAADwnxI10m1G4A4JCVGvXr00f/58ubu7J9l+Bw4cqBs3blhvISEhSbZvAAAAAACeJEHpOTAwUE5OTjp+/LhcXV0VGBj4n4eSWywW/fXXXwkuZN++fbp48aJKlChhXRYTE6PNmzdrypQpWrNmje7du6fr16/bjHaHhYXJ39//sft1c3OTm5tbgusAAAAAACCpJCh0x52v7eTkZHM/Kb366qsKDg62WdaxY0cVKFBAAwYMUEBAgFxdXbV+/Xo1bdpUknTixAmdO3dO5cqVS9JaAAAAAABICgkK3XPnzn3i/aSQLl06FSlSxGaZh4eHfH19rcs7deqkvn37Kn369PL09NS7776rcuXKMXM5AAAAACBZStQ53fPmzdOZM2ceu/7s2bOaN29eYmt6rM8++0z16tVT06ZNVblyZfn7++vnn39O8ucBAAAAACApJCp0d+zYUdu3b3/s+p07d6pjx46JLirOxo0bNWnSJOt9d3d3TZ06VVevXtXt27f1888/P/F8bgAAAAAA7ClRodswjCeuv337tikznAMAAAAA4EgSnIyDgoJ08OBB6/0tW7YoOjr6ke2uX7+uGTNmKF++fElSIAAAAAAAjirBoXvJkiX66KOPJN2/HNjMmTM1c+bMeLf19vY25ZxuAAAAAAAcSYJDd9euXVWvXj0ZhqHSpUtrxIgRqlOnjs02FotFHh4eyp07N4eXAwAAAABSvAQn48yZMytz5sySpA0bNqhQoULKmDGjaYUBAAAAAODoEjWR2ksvvaQLFy48dn1wcLCuXbuW6KIAAAAAAHgRJCp09+nTR127dn3s+rffflv9+vVLdFEAAAAAALwIEhW6f//9dzVo0OCx6+vXr6/ffvst0UUBAAAAAPAiSFTovnTpkjJkyPDY9b6+vrp48WKiiwIAAAAA4EWQqNCdOXNmHThw4LHr9+3bxyRrAAAAAIAUL1Ghu1GjRvrqq6+0fPnyR9YtW7ZMc+bMUePGjZ+5OAAAAAAAHFmiLqb94Ycf6rffflPjxo318ssvq0iRIpKkw4cP69ChQypYsKA++uijJC0UAAAAAABHk6iRbi8vL+3cuVNDhgxRVFSUfvzxR/3444+KiorS0KFDtWvXLnl7eydxqQAAAAAAOJZEjXRLkoeHhz766KPHjmhfu3ZNPj4+iS4MAAAAAABHl6iR7seJjIzU4sWL1ahRI2XOnDkpdw0AAAAAgMNJ9Eh3HMMwtH79es2fP19LlixReHi4MmbMqDfffDMp6gMAAAAAwGElOnTv27dP8+fP16JFixQaGiqLxaKWLVuqR48eKlu2rCwWS1LWCQAAAACAw3mq0H3q1CnNnz9f8+fP1x9//KGsWbOqdevWKl26tN544w01bdpU5cqVM6tWAAAAAAAcSoJDd7ly5bR7925lyJBBzZo10+zZs1WxYkVJ0l9//WVagQAAAAAAOKoEh+5du3YpMDBQEydOVN26deXi8syngwMAAAAA8EJL8OzlU6ZMUebMmdW4cWP5+/vr7bff1oYNG2QYhpn1AQAAAADgsBIcut955x1t3bpVf/31l3r37q0tW7bo1VdfVdasWTVs2DBZLBYmTwMAAAAA4AFPfZ3uwMBADRkyREePHtWePXvUsmVLbdy4UYZh6J133lHXrl3166+/KiIiwox6AQAAAABwGE8duh9UsmRJTZw4USEhIVq7dq1q166t77//Xg0aNFCGDBmSqkYAAAAAABzSM4Vu606cnFSjRg3NnTtXYWFhWrhwoV599dWk2DUAAAAAAA4rSUL3g9zd3fXGG29o2bJlSb1rAAAAAAAcSpKHbgAAAAAAcB+hGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADAJoRsAAAAAAJMQugEAAAAAMAmhGwAAAAAAkxC6AQAAAAAwCaEbAAAAAACTELoBAAAAADBJsgrdo0ePVqlSpZQuXTr5+fmpUaNGOnHihM02ERER6t69u3x9fZU2bVo1bdpUYWFhdqoYAAAAAIDHS1ahe9OmTerevbt27typdevWKSoqSrVq1dLt27et2/Tp00e//PKLFi9erE2bNun8+fNq0qSJHasGAAAAACB+LvYu4EGrV6+2uT937lz5+flp3759qly5sm7cuKGvvvpKCxYsUPXq1SVJc+bMUcGCBbVz506VLVvWHmUDAAAAABCvZDXS/bAbN25IktKnTy9J2rdvn6KiolSjRg3rNgUKFFD27Nm1Y8eOePcRGRmp8PBwmxsAAAAAAM9Dsg3dsbGx6t27typUqKAiRYpIkkJDQ5UqVSp5e3vbbJspUyaFhobGu5/Ro0fLy8vLegsICDC7dAAAAAAAJCXj0N29e3cdPnxYixYteqb9DBw4UDdu3LDeQkJCkqhCAAAAAACeLFmd0x2nR48e+vXXX7V582Zly5bNutzf31/37t3T9evXbUa7w8LC5O/vH+++3Nzc5ObmZnbJAAAAAAA8IlmNdBuGoR49emjJkiX6/fffFRgYaLO+ZMmScnV11fr1663LTpw4oXPnzqlcuXLPu1wAAAAAAJ4oWY10d+/eXQsWLNCyZcuULl0663naXl5eSp06tby8vNSpUyf17dtX6dOnl6enp959912VK1eOmcsBAAAAAMlOsgrd06dPlyRVrVrVZvmcOXPUoUMHSdJnn30mJycnNW3aVJGRkapdu7amTZv2nCsFAAAAAOC/JavQbRjGf27j7u6uqVOnaurUqc+hIgAAAAAAEi9ZndMNAAAAAMCLhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASRwydE+dOlU5c+aUu7u7ypQpo927d9u7JAAAAAAAHuFwofv7779X3759NXz4cO3fv18vv/yyateurYsXL9q7NAAAAAAAbDhc6J44caK6dOmijh07qlChQpoxY4bSpEmjr7/+2t6lAQAAAABgw6FC971797Rv3z7VqFHDuszJyUk1atTQjh077FgZAAAAAACPcrF3AU/j8uXLiomJUaZMmWyWZ8qUScePH4/3MZGRkYqMjLTev3HjhiQpPDzcvEKTSFTkHXuXAAeRnNpz1J179i4BDiI5tdvwu9H2LgGOIhm129tRUfYuAQ4iOfW3EXy+RQIlp3b7OHE1GobxxO0cKnQnxujRo/XRRx89sjwgIMAO1QDm8Jpq7wqAp+f1FqcFwQF19bJ3BcDT86LdwvGMdqDPtzdv3pTXE/6fOVTozpAhg5ydnRUWFmazPCwsTP7+/vE+ZuDAgerbt6/1fmxsrK5evSpfX19ZLBZT60XSCg8PV0BAgEJCQuTp6WnvcoAEod3CEdFu4ahou3BEtFvHZRiGbt68qSxZsjxxO4cK3alSpVLJkiW1fv16NWrUSNL9EL1+/Xr16NEj3se4ubnJzc3NZpm3t7fJlcJMnp6edEhwOLRbOCLaLRwVbReOiHbrmJ40wh3HoUK3JPXt21ft27fXK6+8otKlS2vSpEm6ffu2OnbsaO/SAAAAAACw4XCh+4033tClS5c0bNgwhYaGqlixYlq9evUjk6sBAAAAAGBvDhe6JalHjx6PPZwcLy43NzcNHz78kdMFgOSMdgtHRLuFo6LtwhHRbl98FuO/5jcHAAAAAACJ4mTvAgAAAAAAeFERugEAAAAAMAmhGwAAAAAAkxC6kSwwtQAAAABeFHfu3LF3CUhGCN2wq8jISElSVFSUnSsBAADJzblz57Rnzx7r5wXAEZw4cUKVKlXS/v377V0KkglCN+zm2LFj6tKli6pVq6b33ntPhw4dsndJwH+6fv26rl27Zu8ygKdy+/ZtjiiCwwkKClLp0qW1fPlyXb9+XRJHxiH5O3jwoMqUKaMDBw5YP9vGxsbauSrYG6EbdnH48GFVqFBBadKkUf78+XXw4EEtWbJEEn9QkXwdPXpUJUuW1IwZMxQeHm7vcoAEOXLkiEqUKKHvv//e3qUACXbq1CnVrl1b7dq107Bhw5QpUyZJksVisXNlwOMdOnRI5cuX18CBA9W9e3eNHDlSERERcnIicqV0tAA8d+Hh4erZs6e6dOmiGTNmaMaMGSpbtqwuXLigmJgYRURE2LtE4BH//POP2rRpI4vFoo8++kgzZ84keCPZCwkJUcuWLXX9+nV17dpVixcvtndJQIKsWrVKr7zyisaOHSsnJydNnjxZ77zzjj799FPt3LnT3uUBjzh06JBKlSqlXr16acCAAWrXrp2cnJz03XffSWJQKaUjdOO5i4yM1Pnz51WyZEnrsujoaB0+fFilSpVSy5YttXz5cjtWCNiKiYnRtm3bFBAQoC1btmjUqFEaMGAAwRvJWnR0tFasWKHcuXNrw4YN6tKli9q2bUvwhkMICgpS5syZJUmVK1fWkiVLdPLkSa1cuVItWrTQL7/8YucKgX/duHFD7777rvr376/Ro0dLkgoVKqSsWbNaj+TkKI2UzcXeBSDliY6OVsaMGbVu3TplyZJFv/32m2bOnKlx48bp3r17OnnypHr37q3s2bOrWLFi9i4XkLOzs1566SW98847ypw5s9577z0ZhqH3339fktS1a1d5eXlJuv9NNn9YkRy4uLioePHiypw5swoVKqQJEybIMAy1bdtWktS8eXM7Vwg8XuHChbVkyRJ9/vnn8vDw0LfffqtMmTLpxIkTmjRpkkaMGKFixYopICDA3qUC8vLy0tSpU/XSSy9Juv9lvYeHhz7++GO99tprWrp0qRo1amTfImFXhG48d5kzZ1bz5s21ePFijRw5UgcPHtScOXP0xhtvSLp/eM7KlSt14sQJQjfs6uTJk/r999/1v//9TwULFlTBggUl3Q/W/fr1k8ViUf/+/SVJb7/9ttKlS6dvvvlGZcqUsW4LPG8RERFyd3eXJJUpU8a63DAMTZw4URaLxSZ4R0dHa9WqVQQY2FV0dLRcXFwUExMjZ2dn5cuXTzdv3tSqVauUI0cO6znd+fPn1xtvvKGlS5cqNDSUNgu7unv3rlKnTi1J1sAt3f+yXpLy5MmjEiVKaMOGDWrUqJFiY2M5vzuFInTDdOfPn1dwcLAMw1COHDlUsGBB9ezZUy1atNC9e/dUvXp1ZcuWzbp9QECAfH195eJC84T9BAcHq1q1avLw8FC9evVs2mjcaPZ7770nSerfv78Mw9CxY8f066+/as+ePfYqGync/v37Va9ePe3bt0/+/v42R13E/TxhwgRJUtu2bRUTE6ONGzdq5cqVnCcLuzl8+LAGDBigsWPHqnDhwpKk1157TatWrdLkyZP10ksv6fz588qSJYuk+6PgmTNnZkZo2NWRI0dUp04dffnll6pdu3a8R7rFDTR98MEH6t69u/Lly2enamF3BmCioKAgw9/f3yhRooSROnVqo3jx4sYHH3xgXR8WFmaULVvW+PHHH42bN28ahmEYQ4YMMXLnzm2EhITYq2ykcAcPHjTc3d2Nxo0bG97e3sbixYsNwzCM2NhY6zYxMTHWn8eNG2dYLBbDy8vL2Ldv33OvFzCM++02Xbp0Rq9eveJd/2D7NQzD6Nu3r2GxWAxPT09jz549z6FCIH6NGzc2nJ2djQoVKhhBQUE26/73v/8ZFovF6Ny5s3Ho0CHj6tWrxqBBg4x8+fIZoaGhdqoYMIwBAwYYFovFSJs2rfHrr78ahmEY0dHR1vVxP1+6dMmoUKGC0adPH+PevXt2qRX2x1AiTHP9+nW1bNlSb7zxhkaMGKHTp09r9erV+uSTTxQWFqavv/5afn5+ypUrl3r06KFcuXLJx8dHe/fu1apVq2xGFoHn5cCBA6pUqZL69OmjTz75RO3bt9enn36qKlWqKGPGjNbtnJycFBsbq5iYGIWFhcnb21vbtm3jsHLYRVBQkCpUqKAePXpozJgxku4f9njjxg35+/tLuj/SHXdoY1RUlO7cuUO7RbLg5eWlOnXqyMPDQ507d9asWbP08ssvS5KmT58uPz8/rVy5UsWLF1fJkiX1999/a8WKFdZDzgF7yJUrlzp06KAcOXKoUaNG+vnnn1W/fn1J/54uIUkZMmRQtmzZtHnzZsXExMjV1dWeZcNOLIbB/PUwR0hIiOrUqaO5c+fqlVdekSTdvn1bq1evVocOHdSqVSvNmjVLkjR+/HiFhITIx8dHbdq0UZ48eexZOlKoM2fOqESJEuratas1uCxYsEAffPCBFixYoIoVK1rPN4yzZs0aNWrUSJs3b1apUqXsVTpSsOvXr6tcuXJycnLSkSNHJN0/dPzUqVM6cOCAWrRoocaNG6thw4aSpNjYWP30009q166dtm7danMlCcAevvnmG/3555+qVauWRowYodu3b+unn37SkiVLVL9+fQUEBOjs2bM6fvy40qRJo1y5cilr1qz2Lhsp3NatWzVkyBAtXrxYAwcO1Lx587Rx40atX79euXLl0ptvvinDMOTk5KTw8HBdunRJuXPntnfZsBNCN0wTFhamfPnyady4ceratat1eVRUlL7//nu99957+vjjj23WAfa0f/9+HTt2TK1bt7ZZXqZMGfn6+mrlypWPPObatWu6d+8eIy6wm8uXL2vGjBnW6xjv3btXUVFRatiwoVxdXbVo0SJFR0dr+PDhqlatmiTpxIkT8vDw4IgiJAvffvut5syZo99//13r16/XlClTtGXLFt28eVMXLlxQ+vTp7V0i8IjDhw/rzTff1Pbt2+Xm5qaBAwfqs88+k7u7u/766y/rUUZMngaJ63QjiUVERFh/zpAhg1q0aKGlS5dq//791uWurq6qW7euqlatqn379km6PzHVg/8C9lCiRAmbwB0TEyNJ6tmzp06ePKlt27Y98hgfHx8CN+wqQ4YM6tq1q/r3769PP/1UN27c0Hfffadu3bqpc+fOGj9+vC5cuGDTfvPnz0/ght3F9bGVK1e2Tor26quv6ubNm7p7967y5cuny5cvSxKTpiHZiGu3RYoUkY+Pj65duyZXV1edO3dOHh4eunfvng4fPixJ1pFugFaAJHPgwAG9/fbbunDhgqT7l0t44403dObMGc2aNUtHjx61buvj46M8efJo3759ioyMtM72yPWN8bzFjaT8888/1mVxf1DjDiOvWrWq7t69qxUrVtilRuBhV69e1cmTJ60f7Pz8/NS6dWtNnTpVAwcOlK+vr6T7H/iKFSumXLly6cCBA/YsGbD2t+fPn5f0bx/r4+OjS5cu6cyZM3rrrbd09OhRjR07Vrlz51b9+vV17NgxggvsJjQ0VPv27dOGDRsUGRlpc4qZYRg6dOiQunfvrq1bt+qXX35Rjx49VKtWLa1bt47PtbBiIjUkiUOHDql06dLq2bOnMmfObF1eo0YNDR48WIMHD1ZUVJTatWunKlWqSLr/oTFXrlx0SLCbw4cPq2fPngoJCVHatGlVpUoVTZo0yeYPamxsrLJmzar+/ftr3LhxatWqlc21OIHn7fDhw+rcubOuXr0qZ2dnVa9eXVOnTlXmzJnVtGlTpU6d2qZfvXfvnpydna1zawD28Lj+VpI8PDyUPXt2vfbaa4qIiNCaNWv00ksvKUeOHPr222+t150HnregoCA1bdpUHh4eCg8Pl2EYGj9+vCpVqiQ/Pz9VqlRJbdq0kZeXl1auXKlixYqpaNGicnFx4Wgi2OBrQzyz4OBgVaxYUf3797de//XOnTu6ceOGJKl169b69NNP9ccff6hz586qUqWK6tevr4ULF2rIkCFKlSqVPctHCnX8+HFVrVpVxYsX12effaYmTZpox44d+uGHH2y2ixtdqVq1qiIiIriWMezq6NGjqlKliqpUqaKvv/5aHTp00ObNm3XmzBlJkqenp82XRjExMRo5cqSCgoLUvHlzO1WNlO6/+ltnZ2fVqFFDUVFR+vnnn61fbNarV09ff/21AgMD7Vk+UqiQkBA1bNhQbdq00fLly7V7926VKFFCnTt31pdffqmbN2+qevXqKl26tJYtW6ZixYpJun/kxqeffspVIWCDidTwTEJDQ5UlSxY1aNBAS5culXT//Nfg4GDdvn1befLk0Zw5c+Tm5qaDBw/qzz//1KpVq5QzZ041a9aMDgl2cf36dbVu3Vq5cuXS5MmTJUmRkZGqWbOmChYsqJkzZ8b7uPfee0+dO3em3cIuLl26pNdee03Vq1fXuHHjJEkXLlzQm2++qZEjR8rNzU0lSpSwXs5uyZIl+vXXX/Xrr79q7dq1Kl68uJ1fAVKip+lvr1y5YnNqBEfCwZ5+/fVXjRs3Tr/88os8PDzk7OysNWvWqGnTpvLz81Pfvn3Vo0cPXb9+Xd7e3vYuF8kch5fjmfj7+6tmzZoKDg7WihUrNGbMGLm4uKhGjRqKjIzUTz/9pJIlSyooKEjFihVTsWLF1KxZM3uXjRQuPDxcGTNmVM2aNSXdHw10c3NTo0aNtGPHDuuyuBHDuOttxh3JAdhDVFSUmjVrprp161qXffnll9q1a5fatGkjNzc3OTk56cCBA3Jzc5Ofn588PT21detW5c+f346VIyVLSH8bFRUlV1dX+fr6WsM2gRv2durUKR05ckSenp7WZW5ubmrRooUiIiI0ePBgtWrVyvpFEfAkHF6ORLt3756k+9cpLliwoOrXry9fX18tXrxYgwcP1ogRI/Ttt9/q1q1b+vTTTyUxOzns6/LlywoLC1OGDBnUtm1bNWjQQNK/h5AbhqHr16/bLJMkFxe+n4T9+fn5qWvXripatKgkafbs2frss880b948rV27Vj/99JNiYmLUq1cvSVKlSpU0btw4Ajfs4mn62wf7WMI27OnChQs6cuSIpPunN/j6+qpr1646d+6cdu7cqfr16ytfvnxasGCBsmXLpvnz59u5YjgKQjeeWtxlweJmeJbuH4LTt29fNWnSRBkyZLCG68KFC8vLy0tXrlyRxB9T2M+RI0dUokQJrV69WmnSpFH16tUl2R7CGBMTo8jISEn32+qQIUPUvn17u9UM3LhxQxcuXFBoaKhcXFxsRlRefvllrVy5Us2aNVPevHlVsGBB5c2b1+bSjcyZAXugv4UjOnz4sEqXLm09XdLPz0/vvfeeNm3apBIlSqhOnTrq0qWLPvjgAxmGIRcXF129etW+RcNhMHyDp3LkyBENGjRIERERCg8PV9++fVWlShX5+flp/Pjx1g97FotFhmHIMAxly5ZNefPmlcQ5WrCPQ4cOqXLlypKkzz//XK+//royZswoyfaLIF9fX+ssuYMGDdJnn32mLVu2PP+CAf07S/mdO3f0559/at68eWrWrJliY2Pl5OSkUqVKWbeN6289PDyUL18+6zL6Wzxv9LdwRIcOHVLFihXl7e2tmTNnqk2bNsqRI4c6duyoJk2a6OjRo0qbNq1KlCgh6f6EwVmyZFGuXLkk0d/ivzHSjQQ7ceKEqlSposDAQDVq1EgVK1bUG2+8oQ8//FCHDh2SJJvLehiGoU8++URBQUGqVauWJEa68fwdOnRI5cqVU48ePfTjjz/q2rVrCg4OlmR7tIZ0/9ztNGnSaPjw4Zo4caK2bt3KZZZgFydOnFC1atVUuXJljR07Vu+8847eeecdhYeHWydKe9hHH32kbdu2qUWLFpLob/H80d/CEQUFBalcuXLq2bOn1q1bp7Rp02rNmjWS7p8OkSFDBlWuXNkauG/fvq1Ro0bp4MGDqlSpkiT6WySAASRATEyM8fbbbxtt27a1Wd6kSRMjderURteuXY2//vrLunzTpk1G69atjQwZMhj79+9/3uUChmEYxr59+wwnJydj8ODB1mWlSpUyateuHe/2EyZMMCwWi5EuXTpj7969z6tMwEZMTIzRpUsXo1WrVtZlBw4cMBo0aGD8888/xpkzZ4yYmBjruq1btxpvv/02/S3siv4Wjmjv3r2GxWIxhgwZYl1Wt25do0SJEtb7sbGx1p8PHDhgtG7d2sicOTP9LZ4KI91IsNOnTytbtmyS7n/LJ0kFChRQ1apVtWjRIi1ZskTS/UNurl27Jk9PT23cuJHL1MBuVq1apd69e2vkyJHWUZYBAwboxIkTWr9+/SPbFyxYUCVKlNCOHTtUsmTJ510uIOn+COC5c+eUOXNm67Jly5bpt99+U+3atVWoUCH169dPFy5c0N27d/XHH38oOjqa/hZ2tXLlSvpbOJx9+/apd+/e+vjjj61HEI0YMULnz5/XvHnzJNmOYhcrVkx169bVli1b6G/xVLhONxKsW7du2rRpk3bt2qV06dLp/PnzKly4sFatWqXt27fr448/1rFjx+Tv76/o6GhFR0fbHG4OPG9GPOdYnTt3TpUrV1bLli01ZswYm3Xh4eGKjIy0nn8IPE8RERHWPnPgwIGaPHmyBg4cqHPnzmnevHn65ptvVKZMGe3fv19t2rSxnncYERGh2NhYpUmTxs6vALBFfwtHdOXKFTVo0ED58uXTnDlzrMvj5tMAEoOWg8eKjIzUzZs3rfc7duyojBkzKkeOHHrjjTeUN29etWjRQmXLllWdOnXk4eGhy5cvS7p/+Q8CN+zt4cBtGIayZ8+ufv36adasWTp48KDNOk9PTz4Awi6OHz+ufv366c6dO5KkDz74QO+8845CQkIUFBSkAQMGqEWLFsqRI4caN26ssmXLatWqVYqNjZW7uzuBG3bxxx9/aMGCBTYz5sehv0Vydf36dYWEhOjvv/+2Losb5TYMQ76+vurTp48WLFigTZs2WbchcONZ0HoQr6NHj6p169aqUqWKWrVqpUOHDql06dKaPn26evfurVy5cmnq1KmaOXOmpPuXtUmbNq1Sp05t58qRkv35558aOHCgWrZsqVGjRlkvVRcnLoRXrFhRWbJksc6UGxMTwyQosJugoCCVKFFC06ZN0/LlyyVJXl5eGjt2rKZNm6a0adMqe/bskqR79+4pNjZWqVKlUv78+fkQCLsJCgpS+fLl9fvvv1u/cH8Q/S2So8OHD6tevXqqVq2amjRpos8++0zSv4H6wXZbrlw5LVmyRIZhxDt5JfA0+GuNRxw9elSVKlWSj4+P2rVrp507d2rixImSpEKFCmnYsGEaOXKkOnToYH3M4sWL5eXlZXMNWeB5Onz4sCpVqqRjx45Jkj755BP1798/3m2LFSumypUra9SoUYqOjpazs/PzLBWwOnTokMqWLavOnTurQ4cO+umnn3Tz5k3rBzwnJyflyZNHX3zxhUJCQnTx4kWNHDlSBw8eVMuWLe1cPVKqkJAQNWzYUB06dNDs2bOt8708KO68bvpbJBfHjx9XlSpVVK5cOX3xxRcqWrSoli9fbj3CSPq33fr7+6t69eqaMWOGbty4wReceGZcpxs2bt++rffee08dOnTQhAkTJEmZM2fW8uXLdf36dXl6esrJyUnOzs4yDEMbNmzQzz//rHnz5mnz5s3y9va27wtAivTPP/+oVatWat26tcaPHy9J2rNnj6pWrapOnTqpQoUK1m3jzslq27atdu7cqbCwMGXNmtVepSMF279/v6pWrao+ffpo1KhRmj17tnr16qXTp0+raNGiiomJkbOzs5o1a6YTJ04oR44cKlasmMLDw7Vq1Srr9biB5+348eMqUKCAxo0bp6ioKA0ZMkRHjx5VunTpVLVqVXXt2lXOzs6KioqSq6sr/S3sLioqSuPHj1fz5s01btw4SVK2bNnUr18/hYSEKFWqVAoMDJSzs7Pu3bunVKlS6a233tKKFSt0/fp1Pt/imRG6YcPJyUk3btxQrly5rMu2b9+uPXv2qHjx4ipcuLCqV6+uvn37ymKxyNnZWZcuXdL27dtVpEgRO1aOlMowDK1Zs0b+/v7q27evpPuzP+fOnVvZs2d/5FzDuG+rixUrprVr1ypDhgzPvWYgPDxcNWrUUOfOnTVq1ChJUqdOnTRv3jyNHDlS8+fPl6urqyTp1VdfVeHChbVx40alT59ehQsXJrjArg4ePKjQ0FBJUr169RQVFaWyZcsqKChIM2fO1NGjRzVp0iRrG6a/hb25uroqLCxM6dOnty778ccftXfvXtWsWVPp06dXzpw5tXTpUqVKlUrS/dHutWvXysvLy15l4wVC6Iakf0f/7ty5o5s3b2rz5s3y8/PToUOHNHv2bI0fP15ZsmTRr7/+qp9++knly5dX2bJlVaVKFZUuXZpzuWE3FotFFStW1OnTp5UlSxZJkrOzs9KnTy93d3frB8OHpU6dmnYLu/H09NS2bdtUsGBBSfe/PJKkWrVqad68ebp06ZKyZMmi6Ohoubi4yN/fn8PJYXdxV4QoW7asVqxYoa+//lqGYWjevHnKli2b7ty5o8mTJ+vnn3/WwYMHVaxYMcXGxtLfwq5iY2MVExOjvHnzat++fXr33Xfl4uKiGTNmaN68ecqTJ49Onz6tYcOGady4cerfv79iY2Pl4uJC4EaS4QQF6NSpUxo9erTu3LkjX19fffXVVzp69KgWL16suXPnavr06erWrZsaNmyokSNH6vDhw9qzZ4/18fwhhb3ly5dPI0aMkPToZcLu3r1r/fnHH3/Uvn37nnt9QHwKFiyoB6/aabFY1KtXL127dk2TJk2SdP9KEEByEde3Zs2aVWfOnNHo0aN19+5d6zXl06RJo44dO+r48ePWvpZzYWFvTk5OcnV11TvvvKNXXnlFMTEx2r9/v0aPHq3mzZurePHiqlOnjry9vXXu3DnrY4CkxF/zFC5u9tHUqVPrnXfeUZo0aVS6dGlt375dLi4uql69ugICAiTd/6Ywbdq0KlGihM3hOcDz9tdff2nLli06c+aMqlatqsKFCytjxozWUcG4f1OnTm39lnrw4MEaPXq0/vrrLztXj5Tq7NmzOnjwoMLCwlSnTh2lT59eHh4e1iONYmJilC5dOnXr1k2rV6/WX3/9pdy5c9u7bKRwp06d0rJly3Tu3DlVq1ZNlStXVq5cufTNN9+oXr16unz5sjZv3qxq1apJktKnT6+yZcvKz8/PzpUjJTt79qy2bNmiU6dOqVatWipYsKDy5MmjMWPGyNXVVXXq1FFkZKR1+9SpUytTpkzWz7cPf4EPPCu+xknBDh06pHLlyqlt27by9vbWmDFjrOvSpUune/fu6fr169q/f7+k+9ftHj9+vP744w+biamA5yk4OFilS5fWihUrtHjxYn3wwQdq0qSJTp8+LRcXF5vL0cRdWmnUqFGaNGmSdu/ercDAQDu/AqREce125MiR6tevn6pXr64BAwbon3/+kZOTk2JjY62zOteuXVsnTpzQjh077Fw1Urrg4GBVqFBBmzZt0urVqzVs2DBt27ZNklSlShUtWLBAd+/e1Ycffqi5c+fqyJEjGjp0qIKCglS0aFE7V4+UKjg4WBUrVtQ333yj6dOnq0uXLlqwYIFiY2NlsVgUExMjX19fBQcH69ChQ7pw4YKGDh2qrVu3qk2bNpJE4EbSM5AiHTx40EidOrUxaNAgwzAMo1evXka5cuWMixcvGoZhGDExMYZhGMasWbMMJycn46WXXjIqVKhgBAQEGPv377db3UjZrly5YpQpU8babg3DML755hvDYrEYAQEBxokTJwzDMIzY2FjDMAyjatWqRkBAgOHm5mbs2bPHLjUD4eHhRtmyZY2+ffsaN27cMAzDMEaOHGlUqVLFqFmzpnHu3DnDMAwjOjra+pjmzZsbZcqUMaKioqztGXieTp48aWTJksUYMmSItW2WLFnSGDNmjM1227ZtM6pUqWJkzZrVyJcvn1GoUCE+J8BuTp06ZeTKlcsYPHiwcffuXcMwDKNTp05GyZIlbbbbtWuX4e/vb2TNmtUoXLiwkSdPHtotTGUxjAdOKEOKcObMGeXJk0cDBgywzpq7a9culStXTgsWLHhksp7169drxYoVCgwMVN26dW1mNgeep5MnT6pRo0aaN2+eXnnlFUnSrVu3VLNmTd28eVP37t3Thg0blDVrVt25c0dlypTRkSNHFBwcrMKFC9u5eqRU58+fV+XKlfX555+rbt26ku4fuvj9999r+vTp8vX11cyZM5UxY0brIY2rVq1S/vz56W9hF5GRkfr444918eJFTZo0Se7u7nJyclL79u3l7u6uW7du6eWXX1bz5s0VGBioa9euKTw8XHfu3JGfn598fX3t/RKQAkVHR2vChAk6cOCApk6dKm9vbzk7O+uPP/5Q1apVtWnTJuXJk8d6OcY///xTu3fvloeHh0qWLBnv9eaBpMI53SlQlixZNHfuXOshNDExMSpTpozat2+v6dOnq3r16tZzsQzD0KuvvqpXX33VniUDkqSIiAjdu3dPFy5csC77+++/de3aNfXr109Tp07VggUL1L9/f6VJk0bfffedXFxcCNywqzRp0sjHx0dHjhyxhm6LxaKWLVsqIiJCU6ZM0ZIlS9S1a1frYeZ16tSxc9VIydzc3PT6668rTZo0SpMmjSTpww8/1KJFi9S9e3ddv35dv/zyi7Zt26Z58+bJx8dHPj4+dq4aKZ2Li4s8PDxUqVIlmy9+XF1dFR4erhs3bki6f4UTwzCUJ08e5cmTx17lIoVhpDsF+fPPP60TSsTnu+++U79+/bR8+XKVLl3a+k0gkFxER0erRo0aunPnjpo0aaLAwEB16dJFXbp00YQJE9S2bVtdvXpVK1asoP0i2TAMQ+3bt1dQUJB++OEH5cuXz2Z98+bNFRoaqi1bttipQuDJwsLCVLVqVX366adq0KCBJGnmzJkaNWqU1q1bp/z589u5QuC+B//2xx05dPPmTZUsWVLLly9XgQIFJElr1qxRqVKlmBgYzw0TqaUQR44cUZkyZTRs2DCFh4fHu02bNm2UJ08eDR8+XJIILLC7CxcuaM2aNdq0aZOOHTsmFxcXrV69WtmyZdOiRYs0YsQI9e3bVxMmTJAkBQQEKDo6WhLtF/Zz/fp1nT59WmfPntXt27dlsVg0Y8YM3bx5U127dlVISIjNpcLq1q2ru3fv6s6dO3asGindg/3tiRMnrMtjY2OVKVMm7dmzRw0aNFBMTIwkKU+ePEqbNi2XDYVdnT9/XmvWrNHvv/+u4ODgRwJ33M8xMTHWtjto0CB17drV5pKigNk4vDwFOHjwoMqVK6dixYrpr7/+0rlz51SkSBHrZWokWX9u3769Jk6cqEOHDunll1+2c+VIyYKCgvT666/Lx8dHoaGhSps2rXr16qXevXvrxx9/1K1bt3T79m3r9WGl+5e2yZs3rzXQMPsonrfDhw/rrbfe0t27d/X333+rc+fOevvtt5UnTx6tXbtWNWrUUIsWLTR27Fi98sorSp06tXbu3Clvb2+uCwu7ia+/7devn7p3725tl3GHmceFmlWrVilr1qzy9va2V9lI4YKDg1W3bl1lyZLFOq/Ae++9p549eypVqlTW7e7cuaPLly8rJiZGH3/8sT777DNt2bJFWbNmtWP1SHHsMXsbnp8DBw4YHh4extChQw3DMIxy5coZjRo1MqKiouLd/urVq4aLi4sxePDg51kmYOPKlStG/vz5jffee8+4du2asXv3buPjjz82LBaL0a9fv0dmc/7zzz+N/v37Gz4+PsbRo0ftVDVSuuPHjxt+fn5Gv379jN27dxuTJk0ycubMafzwww/WbcLCwowSJUoYL730kpEvXz6jbt26hqenp3Hw4EE7Vo6U7En97YABA6xXM3lw+4EDBxrp06c3goKC7FQ1Urrz588bgYGBxgcffGDcvn3b+OOPP4zhw4cbFovFGDRokHHt2jXrtlevXjWKFi1q1K9f33B3dzf27t1rv8KRYjHS/QL7888/VaFCBfXs2VMjRoyQJDVq1Ehz587V6dOnlTdvXpvR7piYGPn4+GjatGlchxt2dfv2bbm4uKhVq1by9vZWqVKlVKpUKQUGBqpjx47y9PTU0KFDJd2fSG3JkiVasmSJ1q9fr4IFC9q5eqREN2/e1JAhQ9SwYUONGzdOklSqVCnt2bNHM2fOVLNmzRQbGys/Pz/t3LlTy5Yt0+HDh+Xp6amJEyc+cp438Lz8V3/r4eFh7W9/++03ffPNN9q1a5fWr1+vl156yc7VI6U6fvy4smXLpkGDBilNmjTKkyePqlSponTp0mnMmDGyWCwaOXKkJCkqKkohISEKCQnRjh07VKxYMfsWjxSJY9leYMeOHdPEiRM1evRo67JOnTrp8uXLmjVrliTZHM4Yd8hYp06dVKhQoedbLPCAqKgoHT9+XP/8848kWQ8Xb926taZNm6YRI0Zo6dKlkqRs2bKpefPm2rp1q4oXL26vkpHCXb9+Xe7u7mrUqJEkWecWiJuU0mKxyNnZWTExMXJ1dVWzZs304Ycfqm/fvgRu2NXT9LfVqlVTvXr1tG7dOoIL7OrmzZvav3+/zpw5Y13m7e2tmjVrauzYsRo7dqzWrl0rScqQIYO6dOmi7du3025hN8xenoLEzeg4evRoLViwQD/++CMzjiLZMf5/8pOOHTvq1KlTmjp1qooUKWJdd+vWLb399ttKkyaNpk+fLldXVztXDNy3efNmVa5cWdK//e3PP/+syZMna8OGDdbtQkND5e/vb68yAaun6W+nTp0qNzc3O1cM3Hf8+HH973//U8GCBdWoUSN5e3vr9ddfV6dOnTRmzBjVrl1b9erVU69evexdKiCJke4UJW4ku0qVKgoJCdHevXsl3Z9EDUgu4iY/a9q0qaKjo/XFF1/o5MmT1nXp0qVThgwZdOLECQI3koW4767jAnfctbYlKTw8XBcuXFBUVJQkaeTIkerTp48iIiLsUyzwgKfpbwncSE4KFCigN998U3/++adatGihxo0bq3379ho7dqycnJx07949BQUF2btMwIrQ/YJJSIAuX768WrRooU8++URXrlxhxlwkS/Xq1VPr1q21f/9+jRw5UgcOHLCui46OVkBAgCIjI+1YIXDfw7PkP9inurq6ys3NTa6urho+fLiGDRum999/X+7u7s+7TOCx6G/hSOI+63bt2lVz5szRzp07tWrVKk2cOFHS/XkK0qVLp1KlStmzTMAGE6m9IEJDQ+Xp6Wm9pMd/adq0qX7++Wft3r1bderUMbk6IH6RkZFKlSrVI6ElboK/d955R6lTp9aiRYtUo0YNVapUSVFRUdq6dau2bNnCyAvsznjgWrDxLU+XLp2yZ8+uoUOHaty4cdqzZw9zD8Au6G/hiOJrt05OTtY+Nlu2bDbbh4aGavr06dq9e7cmTZr0nKsFHo8hzhfA8ePHVblyZc2cOVPSv4c6PkmtWrVUunRp5cmTx+zygHgdPXpUH3zwgQ4ePPhIm3VycrJ+k92xY0d99tlnGjt2rLy8vFSsWDHt3LlTRYsWtUfZSOFu3bqlCxcu6MaNG4qNjX3steDjlt+6dUsrVqzQpEmTtG3bNpUsWfJ5lgtIor+FY3pSu42v7/3777/1/vvva+bMmVqzZg2fcZGsMJGagzt48KDKly+viIgIvfbaa1q5cuV/PibuW+3HjdAAZgsODlalSpXUsmVLDRo0SNmzZ7eue/AydrRRJCdHjhxRr1699M8//8jT01Ndu3ZVx44dn3iKzm+//abevXvrxx9/VIECBZ5jtcB99LdwRAlttw/buXOn/Pz8lCtXrudVKpAghG4HdujQIZUvX16DBw9WgwYNVL58ec2aNUstW7a0d2nAY129elWvv/66KlasqPHjx0uSwsLCFBMTI19fX7m5uVlnfgaSiyNHjqhy5cpq3bq1atWqpW+++UZnzpzRpk2brKf1PC60XL16VenTp3/eJQP0t3BItFu8iDin20EFBwerTJkyeu+99zRo0CCFhoaqaNGi2rRpk1q2bPnEbwEBe7p7965iY2P17rvv6t69e+rQoYNOnDihmzdvKiAgQPPnz5e/vz9/UJFshIaGqlWrVurYsaP1A2C+fPnUs2dPhYSEKH369PL09Hzkg2BcP0zghr3Q38IR0W7xIiKVOaDY2Fh98cUXGjhwoEaNGiVJ8vf3V/v27fX1118rKCiIwI1kyTAMnT17VufOnZOvr6/+97//6dq1a/roo4/0wQcfKDY2Vq+88oquXr3KH1IkG2fOnFHjxo3VvXt367Jvv/1WO3bsUM2aNfX666+rTZs2unnzpk27pR+GPdHfwhHRbvGi4vByBxUREWG95EzcaMqVK1fUqFEjlShRQuPHj5eLiwvnZyHZiYyMVLVq1fTKK6/o2LFjGjVqlEqXLi1J+vPPP9W2bVvVqFFDI0aMoP0iWYiKitK5c+eUO3duSdK4ceM0YMAAzZ07V8WKFdOePXs0ZcoUdevWTV27drVztcC/pzpERESoevXq9LdwCLRbvMj4Gt6BREdHW/91d3eXYRgyDMM6muLr66tSpUpp+fLliomJkcViSdBM5sDzZLFYVK5cOa1du1ZBQUHKmjWrpPt/bHPnzq2MGTMqNDSUP6SwqwsXLlh/dnV1tQZuSSpbtqzWrVundu3aqWjRourQoYPu3r2rkydP2qNUwCruWtoRERGS6G/hGOI+38Z9ZqXd4kVE6HYQx44d0zvvvKO6detqwIAB2rZtmywWi7XDibvcx9ChQxUVFWU97JwOCfb0xx9/aMSIEXrzzTc1ffp0nThxQqlSpdLgwYOVK1cuXbp0SaNHj7Z+u22xWJQhQwZlzJjR+qUS8LydOnVKWbNmVbVq1azLHvxQWKlSJb366quS7ve9d+/eVf78+VWoUCHrNsDzdvz4cXXp0kWvvvqqOnfurD179sjNzY3+Fsnag59v+/fvb70mPO0WLxpCtwM4fvy4ypYtq+joaHl5een48eOqXr26Zs2aZd0m7hJgqVOnVoMGDbRx40bduHHDjlUjpTt8+LAqVKigY8eO6fz585o7d67Gjx9vncl5/vz5atiwoVauXKn69etr5syZ6tq1q5YsWaJ27drZfKkEPE/Xrl1Tjhw5FBYWpqpVq0qSXFxcrEcQPcjJyUljx47V4cOHrSGddovn7fDhwypfvrw8PDz00ksv6fr16/riiy90584dpU+fXt99950aNGhAf4tkJb7PtzVq1NC0adP4nIAXj4Fkr1evXkb9+vWt9y9fvmyMGjXKcHJyMiZMmGAYhmHExsYasbGxhmEYxpo1a4z06dMbYWFhdqkXCAkJMQoXLmx88MEH1mWzZ882cuTIYZw5c8a67MaNG8aUKVOMmjVrGqVKlTLq1q1rHDp0yB4lA4Zh3O9L9+7daxQoUMBYuHChUbhwYaN69erW9SEhIdafN23aZPTp08fw9vY2Dhw4YIdqAcM4ffq0kSdPHmPw4MHWZaNHjzbatWtnxMTEGFevXjUMwzCuXr1qTJ48mf4WycaTPt9++umnhmEYxrVr12i3eCEwkZoDeOONN+Tm5qZ58+ZJ+neiiUmTJqlv375avHixmjZtanMuzLVr1+Tj42PPspFCGYahhQsXavHixZo4caJy5MghJycnRUdHq3Dhwpo0aZLq1Kmj6Ohoubj8e9XCu3fvytnZWalSpbJj9cD982LbtGmjzz77TEFBQerXr59y5sypjBkzKlu2bBo0aJBcXFz06aefat++fRo1apSKFCli77KRQi1ZskTLli3Tp59+qkyZMkmS+vfvr1WrVsnNzU2pUqVS37591bx5c+vnB/pbJAf/9fl24cKFeuONN6zb027hyLhOtwMoUaKEPv/8c505c0Y5c+a0Ln/33Xd19uxZDRo0SGXKlFG2bNms6wjcsBeLxaL06dPrtddeU2BgoKT7f0jv3buniIgIXbt2TZJsArckpU6d+rnXCsTHxcVFZ8+e1e7du9WkSRN5enqqYcOGunbtmvbt2ycPDw9J0vvvv6+IiAh5e3vbt2CkaNWqVVORIkWsgXvcuHGaOnWqxo4dqzRp0ujw4cN68803lTNnTpUqVUoS/S2Sh//6fDts2DCVL19eAQEBkmi3cGyc0+0AqlWrprx582rMmDE6f/68LBaLYmNj5ezsrMaNGys8PFyhoaH2LhOweu2116yXTor75jpNmjTKlCmTzTfUc+bM0eHDh+1VJvCIqKgoOTs7q2jRooqKipIkTZ8+XZIUGBioQYMGWbd1d3cncMPuvL29rbPrR0dH6+zZs1q2bJl69Oiht956S71795a/vz99LZKdhHy+DQsLs3eZQJJgpDuZ+euvv/T111/r8uXLypMnj/r376/SpUurYcOGmj9/vsaNG6fevXsrR44ckqT8+fPLy8tLt2/ftnPlSMkebLe5c+fW+++/b/3jGXdJO+n+pZfiJj0ZNGiQJk+erH379tmrbKRwD7bbvHnzql+/fnJ1dZUkvfzyywoODtby5cv1+++/a9WqVbpx44batm2rRo0aaenSpfYtHilWfJ8TnJycFBsbKxcXF02ZMkWSrP2vxWJR5syZraOFgD3w+RYpHaE7GQkKClKtWrVUunRpubi4aO7cuYqJidEHH3ygvn376vbt21qxYoVOnDih4cOHy9vbW3PnztWdO3eUL18+e5ePFCq+dmuxWKwfBOPmGoiKitLly5cVGxurTz/9VJ999pm2bt1K24VdxNduDcNQ//79JUlp06ZVr169lCdPHq1YsUIlSpRQVFSUvv32W+XKlcvO1SOliq/dSrIJ3tL9WfXjvvCcMWOGIiIiVLhwYXuVjRSOz7cAoTvZ+OOPP9SwYUN17NhRo0ePVkREhN59913rtWGl+9fgzps3rxYuXKhy5cqpcOHCun37tpYtW6bMmTPbsXqkVI9rt5GRkdZt4ka2nZ2d5e/vr6FDhyokJERbtmxRyZIl7VU6UrCEtNuOHTvq3Llzqlu3rkqUKCHp/pEaNWvWtFfZSOES0m4fPLLo+PHjmjVrlubOnasNGzbwOQF2wedb4D5mL08GYmNj1bdvX4WFhWnu3Llyc3OTJLVr104XLlyQh4eHsmXLpiFDhsjf31+SdPDgQaVJk0ZeXl7WyVOA5ykh7TZHjhzq27evcuTIoejoaNWqVUuHDh3Shg0bVLRoUTu/AqRECWm3WbNm1fDhw+Xn52fnaoH7nra/PXLkiBYuXKj169dr5syZ9LewCz7fAv8idCcTV65cUVBQkKpVqyZJGjNmjAYNGqQePXooc+bM+vzzz1W0aFGtXbvWzpUC/0pIuy1evLhWrVolSZo/f77Kli1rnfQHsIeEtNtixYpp9erVdq4U+NfT9rfHjx+Xr6+vMmbMaM+ykcLx+Ra4j9CdDDw82dSpU6f0wQcfqFOnTqpdu7ak++fDFCtWTBs3blTlypXtVSpg9TTt9vfff1fVqlXtVCnwL/pbOCL6Wzgi+lvgX5zTnQw82CFJUq5cuTR9+nT5+vpal129elVFihRR9uzZn3d5QLyept0+eP1NwJ7ob+GI6G/hiOhvgX9xne5kJu7Ag/Tp09ssX7t2rXx9feXp6WmPsoAnot3CEdFu4Yhot3BEtFukdIx025FhGNaZnePE3Y/799SpU/rqq680bdo0bd68+ZHOCnjeaLdwRLRbOCLaLRwR7RZ4FKH7Obpy5Yr+/vtvWSwWZcuWTenTp3/kfJcHBQcH64svvtCmTZu0ceNGZh+FXdBu4Yhot3BEtFs4Itot8N+YSO05CQ4OVvv27XXnzh3dvn1bxYoV0+TJk5947tWNGzd05MgRBQQEKCAg4PkVC/w/2i0cEe0Wjoh2C0dEuwUShnO6n4OTJ0+qRo0aqlGjhn7++WeNHj1ad+/e1eLFiyX9e57Lw7y8vFS+fHk6JNgF7RaOiHYLR0S7hSOi3QIJx0i3yW7fvq2uXbsqderUmj17tnV5586ddezYMW3bts2O1QHxo93CEdFu4Yhot3BEtFvg6TDSbbLIyEj5+/urWrVqkqSYmBhJUuPGjRUbG6uoqCjFxsbas0TgEbRbOCLaLRwR7RaOiHYLPB0mUjNZ+vTp1bJlS5UqVUrSv9csdHV11Z07dxQbGysXl/u/hqtXrzJ7I5IF2i0cEe0Wjoh2C0dEuwWeDiPdJggPD9ft27cVEhIiSdYOKTo62nqphFu3bunWrVtydnaWxWLRkCFDVLt2bd27d++x58AAZqLdwhHRbuGIaLdwRLRbIPEY6U5iwcHB6tatm6KionTlyhU1aNBA3bt3V+7cueXi4mK9hIKnp6fc3d3l4uKioUOHauLEidq8ebNSpUpl75eAFIh2C0dEu4Ujot3CEdFugWdD6E5Cf/75p2rWrKlOnTqpQoUKunv3rtq1a6eDBw+qf//+qlOnjvXwG3d3d6VPn169e/fW9OnTtX37dpUsWdLOrwApEe0Wjoh2C0dEu4Ujot0Cz47QnYS+//57lStXTqNGjZJhGLJYLDp48KA++eQTpUqVynqJBEm6cuWKtm3bpgMHDmjHjh0qUaKEnatHSkW7hSOi3cIR0W7hiGi3wLPjnO4kdOLECevsjdHR0ZKkrFmzqlWrVjpy5Ii++OIL67a5cuVSnTp1tHv3bjok2BXtFo6IdgtHRLuFI6LdAknAQJKZPXu2kTFjRmPDhg2GYRjGX3/9ZaRJk8ZYvny5sWvXLsPNzc3YtWuXdfvr16/bqVLgX7RbOCLaLRwR7RaOiHYLPDsOL09CVatWVb169VS7dm0VL15cQUFBeuutt1S/fn1dunRJPj4+unr1qnV7Ly8vO1YL3Ee7hSOi3cIR0W7hiGi3wLMjdCeh3Llza8yYMWrYsKH++ecfZc2aVQ0bNpR0/xIK/v7+8vb2tm+RwENot3BEtFs4ItotHBHtFnh2hO6nZPz/BBIPi46OlouLi/z8/Kwd0YOmT5+uu3fvKjAw8HmUCdig3cIR0W7hiGi3cES0W8BchO6nFNchrV69WoULF1ZAQIBiYmLk4uKiS5cuyc3NTZ6entbtf//9dy1YsEA//fSTfv/9d2XKlMlepSMFo93CEdFu4Yhot3BEtFvAXMxengg7d+5U79699cMPP+jcuXNydnbW2bNnFRAQoO+//95m27x588rT01Pbt29X8eLF7VQxQLuFY6LdwhHRbuGIaLeAeSyGYRj2LsIRzZ8/XzNnzlSbNm308ssv64033lCdOnU0ZcoUOTs7S/r3UJ2YmBjrMsCeaLdwRLRbOCLaLRwR7RYwB6H7KT14zsuKFSv04Ycf6s8//1T9+vU1b948O1cHxI92C0dEu4Ujot3CEdFuAXNxePlTslgsunfvniSpcuXKOnXqlNzd3fXSSy/p/Pnzdq4OiB/tFo6IdgtHRLuFI6LdAuZiIrWnZBiGUqVKpVOnTqlKlSpq3769ihcvrlmzZsnFxUXNmjVTQECAvcsEbNBu4Yhot3BEtFs4ItotYC5C91OyWCy6efOm2rVrpxo1amjixImSJBcXF40aNUqurq7q1q0b57ggWaHdwhHRbuGIaLdwRLRbwFyc050I4eHh2rNnj6pXry7p38ssLF68WKVKlVLOnDntWB0QP9otHBHtFo6IdgtHRLsFzEPoTgKxsbFycuL0eDgW2i0cEe0Wjoh2C0dEuwWSDqEbAAAAAACT8PUVAAAAAAAmIXQDAAAAAGASQjcAAAAAACYhdAMAAAAAYBJCNwAAAAAAJiF0AwAAAABgEkI3AAAAAAAmIXQDAAAAAGASQjcAAAAAACYhdAMAAAAAYBJCNwAADu7DDz+UxWLR5cuX411fpEgRVa1a9fkWBQAAJBG6AQAAAAAwDaEbAAAkmYiICMXGxtq7DAAAkg1CNwAAKczkyZNVuHBhpUmTRj4+PnrllVe0YMECm23++ecfvfXWW8qUKZPc3NxUuHBhff311zbbbNy4URaLRYsWLdKQIUOUNWtWpUmTRuHh4YqKitJHH32kvHnzyt3dXb6+vqpYsaLWrVv3PF8qAAB252LvAgAAwPPz5ZdfqmfPnmrWrJl69eqliIgIBQUFadeuXXrzzTclSWFhYSpbtqwsFot69OihjBkzatWqVerUqZPCw8PVu3dvm31+/PHHSpUqlfr166fIyEilSpVKH374oUaPHq3OnTurdOnSCg8P1969e7V//37VrFnTDq8cAAD7IHQDAJCCrFixQoULF9bixYsfu83gwYMVExOj4OBg+fr6SpL+97//qVWrVvrwww/19ttvK3Xq1NbtIyIitHfvXptlK1as0Ouvv65Zs2aZ92IAAHAAHF4OAEAK4u3trb///lt79uyJd71hGPrpp59Uv359GYahy5cvW2+1a9fWjRs3tH//fpvHtG/f3iZwxz3PkSNH9Mcff5j2WgAAcASEbgAAUgCLxSJJGjBggNKmTavSpUsrb9686t69u7Zt22bd7tKlS7p+/bpmzZqljBkz2tw6duwoSbp48aLNvgMDAx95vhEjRuj69evKly+fXnrpJfXv319BQUEmvkIAAJInQjcAAA7O3d1dknT37t1419+5c8e6TcGCBXXixAktWrRIFStW1E8//aSKFStq+PDhkmSdebxNmzZat25dvLcKFSrY7P/hUW5Jqly5sv766y99/fXXKlKkiGbPnq0SJUpo9uzZSfa6AQBwBBbDMAx7FwEAABJv4cKFevPNN7Vu3TrVqFHDZt2dO3fk5eWlTp06acaMGY889t69e2rSpIlWr16tW7duydXVVT4+PqpXr94jM5o/bOPGjapWrZoWL16sZs2aPXHbW7duqXLlyrp48aL+/vvvp3+RAAA4KEa6AQBwcK+++qpSpUql6dOnP3KN7FmzZik6Olp16tSRJF25csVmfapUqVSoUCEZhqGoqCg5OzuradOm+umnn3T48OFHnuvSpUsJqunh50mbNq3y5MmjyMjIp3lpAAA4PGYvBwDAwfn5+WnYsGEaMmSIKleurAYNGihNmjTavn27Fi5cqFq1aql+/fqSpFq1asnf318VKlRQpkyZdOzYMU2ZMkV169ZVunTpJEljxozRhg0bVKZMGXXp0kWFChXS1atXtX//fv3222+6evXqf9ZUqFAhVa1aVSVLllT69Om1d+9e/fjjj+rRo4ep7wUAAMkNh5cDAPCCmD9/vqZMmaLg4GBFR0crMDBQrVq10oABA+Tm5ibp/sj3/PnzdeTIEd26dUvZsmVTkyZNNGTIEHl6elr3dfHiRY0YMULLly9XaGiofH19VbhwYb3xxhvq0qWLpCcfXj5q1CgtX75cJ0+eVGRkpHLkyKG2bduqf//+cnV1fX5vCgAAdkboBgAAAADAJJzTDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASQjdAAAAAACYhNANAAAAAIBJCN0AAAAAAJiE0A0AAAAAgEkI3QAAAAAAmITQDQAAAACASf4PsSmfiKbqgrwAAAAASUVORK5CYII=",
"text/plain": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt # type: ignore\n",
"\n",
"\n",
"x=df['User'].value_counts().head()\n",
"\n",
"# Assuming 'x' is a pandas Series with index as users and values as counts\n",
"name = x.index\n",
"count = x.values\n",
"\n",
"# Set figure size for better visualization\n",
"plt.figure(figsize=(10, 6))\n",
"\n",
"# Create a bar chart with customized colors and more aesthetically pleasing style\n",
"plt.bar(name, count, color=['#4C72B0', '#55A868', '#F1A340', '#C44E52', '#8172B2'])\n",
"\n",
"# Add labels and title with improved font size and style\n",
"plt.xlabel(\"Users\", fontsize=12)\n",
"plt.ylabel(\"Activity Count\", fontsize=12)\n",
"plt.title(\"Top 5 Most Active Users in Groups\", fontsize=14, fontweight='bold')\n",
"\n",
"# Rotate x-axis labels for better readability\n",
"plt.xticks(rotation=45, ha='right', fontsize=10)\n",
"\n",
"# Adjust layout to avoid overlap and improve clarity\n",
"plt.tight_layout()\n",
"\n",
"# Show the plot\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Display Top 20 Common Words**"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"# Filter out rows where 'User' is 'group_notification'\n",
"temp = df[df['User'] != 'group_notification']\n",
"\n",
"# Further filter out rows where 'Message' is '\\n'\n",
"temp = temp[temp['Message'] != '\\n']\n"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"f=open('D:\\WhatsApp-Conversations-Analysis\\stop_hinglish.txt','r')\n",
"stop_word=f.read()"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"words = []\n",
"\n",
"for message in temp[\"Message\"]:\n",
" for word in message.lower().split():\n",
" if word not in stop_word:\n",
" words.append(word)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Word Count\n",
"0 145\n",
"2 ہے 35\n",
"3 کے 29\n",
"4 message 28\n",
"5 course 25\n",
"6 quiz 23\n",
"7 null 23\n",
"8 میں 22\n",
"9 link: 22\n",
"10 کا 21\n",
"11 link 20\n",
"12 free 20\n",
"13 deleted 20\n",
"14 share 19\n",
"15 کو 18\n",
"16 group 18\n",
"17 کی 16\n",
"18 plz 15\n",
"19 اور 15\n"
]
}
],
"source": [
"from collections import Counter\n",
"import pandas as pd\n",
"\n",
"# Assuming 'words' is a list of words\n",
"word_counts = Counter(words).most_common(20)\n",
"\n",
"# Convert the result to a DataFrame\n",
"common_df = pd.DataFrame(word_counts, columns=['Word', 'Count'])\n",
"print(common_df)\n"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Assuming 'timeline' is a DataFrame with columns 'time' and 'Message'\n",
"plt.plot(timeline['time'], timeline['Message'], label=\"Messages Over Time\")\n",
"plt.xlabel(\"Time\") # Label for the X-axis\n",
"plt.ylabel(\"Number of Messages\") # Label for the Y-axis\n",
"plt.title(\"Messages Timeline\") # Title of the plot\n",
"plt.legend() # Show the legend for better clarity\n",
"plt.grid(True) # Add gridlines for better readability\n",
"plt.show() # Display the plot\n"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"