Files
LLM_Engineering_OLD/week6/community-contributions/bharat_puri/fine_tuned_simulation.ipynb
2025-10-25 23:30:57 +05:30

446 lines
55 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"id": "db8736a7-ed94-441c-9556-831fa57b5a10",
"metadata": {},
"source": [
"# The Product Pricer Fine-Tuning a Frontier Model - Similation (GPT-4 mini)\n",
"\n",
"Submitted By: Bharat Puri\n",
"\n",
"A model that can estimate how much something costs, from its description.\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "681c717b-4c24-4ac3-a5f3-3c5881d6e70a",
"metadata": {},
"outputs": [],
"source": [
"# imports\n",
"\n",
"import os\n",
"import re\n",
"import math\n",
"import json\n",
"import random\n",
"from dotenv import load_dotenv\n",
"from huggingface_hub import login\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"import numpy as np\n",
"import pickle\n",
"from collections import Counter\n",
"import sys\n",
"sys.path.append(os.path.abspath(os.path.join(\"..\", \"..\"))) \n",
"from openai import OpenAI\n",
"from anthropic import Anthropic\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.metrics import mean_absolute_error\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "36d05bdc-0155-4c72-a7ee-aa4e614ffd3c",
"metadata": {},
"outputs": [],
"source": [
"# environment\n",
"\n",
"load_dotenv(override=True)\n",
"os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your-key-if-not-using-env')\n",
"os.environ['ANTHROPIC_API_KEY'] = os.getenv('ANTHROPIC_API_KEY', 'your-key-if-not-using-env')\n",
"os.environ['HF_TOKEN'] = os.getenv('HF_TOKEN', 'your-key-if-not-using-env')"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "4dd3aad2-6f99-433c-8792-e461d2f06622",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Note: Environment variable`HF_TOKEN` is set and is the current active token independently from the token you've just configured.\n"
]
}
],
"source": [
"# Log in to HuggingFace\n",
"\n",
"hf_token = os.environ['HF_TOKEN']\n",
"login(hf_token, add_to_git_credential=True)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "9c69e347-91bc-4eb1-843f-a17ed485667c",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🔍 Starting data curation...\n",
"✅ Cleaned dataset shape: (249, 2)\n",
" prompt \\\n",
"0 How much does this cost to the nearest dollar?... \n",
"1 How much does this cost to the nearest dollar?... \n",
"2 How much does this cost to the nearest dollar?... \n",
"\n",
" completion \n",
"0 How much does this cost to the nearest dollar?... \n",
"1 How much does this cost to the nearest dollar?... \n",
"2 How much does this cost to the nearest dollar?... \n",
"Training samples: 224, Validation samples: 25\n",
"💾 Saved train.pkl and test.pkl successfully.\n"
]
}
],
"source": [
"# =============================================================\n",
"# Step 1 — Data Curation and Preparation (Integrated from 09_part1_data_curation)\n",
"# =============================================================\n",
"\n",
"import pandas as pd\n",
"import pickle\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"print(\"🔍 Starting data curation...\")\n",
"\n",
"# Load input/output CSVs (adjust paths as needed)\n",
"df_input = pd.read_csv(\"../../human_input.csv\")\n",
"df_output = pd.read_csv(\"../../human_output.csv\")\n",
"\n",
"# Detect and combine dynamically\n",
"i_col, o_col = df_input.columns[0], df_output.columns[0]\n",
"df = pd.DataFrame({\n",
" \"prompt\": df_input[i_col].astype(str).str.strip(),\n",
" \"completion\": df_output[o_col].astype(str).str.strip()\n",
"})\n",
"\n",
"# Basic cleaning\n",
"df.dropna(inplace=True)\n",
"df = df[df[\"prompt\"].str.len() > 0]\n",
"df = df[df[\"completion\"].str.len() > 0]\n",
"df = df.reset_index(drop=True)\n",
"\n",
"print(f\"✅ Cleaned dataset shape: {df.shape}\")\n",
"print(df.head(3))\n",
"\n",
"# Split into training and validation\n",
"train_df, val_df = train_test_split(df, test_size=0.1, random_state=42)\n",
"print(f\"Training samples: {len(train_df)}, Validation samples: {len(val_df)}\")\n",
"\n",
"# Save curated datasets to reuse later\n",
"with open(\"train.pkl\", \"wb\") as f:\n",
" pickle.dump(train_df, f)\n",
"with open(\"test.pkl\", \"wb\") as f:\n",
" pickle.dump(val_df, f)\n",
"\n",
"print(\"💾 Saved train.pkl and test.pkl successfully.\")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "b0a6fb86-74a4-403c-ab25-6db2d74e9d2b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"📦 Loading curated train/test data from pickle files...\n",
"✅ Loaded train=224 | val=25\n",
"💾 Saved train.jsonl and val.jsonl for fine-tuning.\n"
]
}
],
"source": [
"# =============================================================\n",
"# Step 2 — Prepare Data for Fine-Tuning\n",
"# =============================================================\n",
"import pickle\n",
"import pandas as pd\n",
"\n",
"print(\"📦 Loading curated train/test data from pickle files...\")\n",
"\n",
"with open(\"train.pkl\", \"rb\") as f:\n",
" train_df = pickle.load(f)\n",
"with open(\"test.pkl\", \"rb\") as f:\n",
" val_df = pickle.load(f)\n",
"\n",
"print(f\"✅ Loaded train={len(train_df)} | val={len(val_df)}\")\n",
"\n",
"# Ensure correct column names\n",
"train_df = train_df.rename(columns={train_df.columns[0]: \"prompt\", train_df.columns[1]: \"completion\"})\n",
"val_df = val_df.rename(columns={val_df.columns[0]: \"prompt\", val_df.columns[1]: \"completion\"})\n",
"\n",
"# Save as JSONL for OpenAI Fine-Tuning\n",
"train_df.to_json(\"train.jsonl\", orient=\"records\", lines=True)\n",
"val_df.to_json(\"val.jsonl\", orient=\"records\", lines=True)\n",
"\n",
"print(\"💾 Saved train.jsonl and val.jsonl for fine-tuning.\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "c830ed3e-24ee-4af6-a07b-a1bfdcd39278",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"⚙️ Fine-tuning configuration:\n",
"{\n",
" \"model\": \"gpt-4o-mini\",\n",
" \"n_epochs\": 3,\n",
" \"batch_size\": 8,\n",
" \"learning_rate_multiplier\": 0.5,\n",
" \"suffix\": \"week6_bharat_ft_v1\"\n",
"}\n"
]
}
],
"source": [
"# =============================================================\n",
"# Step 3 — Fine-Tuning Configuration\n",
"# =============================================================\n",
"import json\n",
"\n",
"hyperparams = {\n",
" \"model\": \"gpt-4o-mini\", # Frontier model from the course\n",
" \"n_epochs\": 3, # Small safe run\n",
" \"batch_size\": 8, # Reasonable for small data\n",
" \"learning_rate_multiplier\": 0.5, # Trainer's suggested mid value\n",
" \"suffix\": \"week6_bharat_ft_v1\" # Unique identifier for your run\n",
"}\n",
"\n",
"print(\"⚙️ Fine-tuning configuration:\")\n",
"print(json.dumps(hyperparams, indent=2))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5c9b05f4-c9eb-462c-8d86-de9140a2d985",
"metadata": {},
"outputs": [],
"source": [
"# =============================================\n",
"# Step 3 Define Fine-Tuning Configuration\n",
"# =============================================\n",
"\n",
"hyperparams = {\n",
" \"model\": \"gpt-4o-mini\", \n",
" \"n_epochs\": 1, \n",
" \"batch_size\": 4, # Small batch = less token use\n",
" \"learning_rate_multiplier\": 0.5, # Gentle learning rate\n",
" \"suffix\": \"week6_lowcost_bharat\" # Custom suffix for tracking\n",
"}\n",
"\n",
"print(\"✅ Fine-tuning configuration defined:\")\n",
"for k, v in hyperparams.items():\n",
" print(f\"{k:25}: {v}\")\n"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "e8367135-f40e-43e1-8f3c-09e990ab1194",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"🧪 Simulation mode — running mock fine-tuning steps...\n",
"Simulated Epoch 1/3\n",
"Simulated Epoch 2/3\n",
"Simulated Epoch 3/3\n",
"✅ Simulation complete — no API cost.\n"
]
}
],
"source": [
"# =============================================================\n",
"# Step 4 — Launch Fine-Tuning Job (Fixed for latest SDK)\n",
"# =============================================================\n",
"from openai import OpenAI\n",
"import time, os, json\n",
"\n",
"client = OpenAI(api_key=os.getenv(\"OPENAI_API_KEY\"))\n",
"\n",
"simulate = True # Set True for simulation (no cost)\n",
"\n",
"if simulate:\n",
" print(\"\\n🧪 Simulation mode — running mock fine-tuning steps...\")\n",
" for e in range(3):\n",
" print(f\"Simulated Epoch {e+1}/3\")\n",
" time.sleep(1)\n",
" ft_model = \"ft:gpt-4o-mini:SIMULATED\"\n",
" print(\"✅ Simulation complete — no API cost.\")\n",
"else:\n",
" print(\"\\n🚀 Creating fine-tuning job...\")\n",
"\n",
" # Upload training and validation data\n",
" train_file = client.files.create(file=open(\"train.jsonl\", \"rb\"), purpose=\"fine-tune\")\n",
" val_file = client.files.create(file=open(\"val.jsonl\", \"rb\"), purpose=\"fine-tune\")\n",
"\n",
" # ✅ Correct usage: hyperparameters must go inside a dictionary named `hyperparameters`\n",
" job = client.fine_tuning.jobs.create(\n",
" model=\"gpt-4o-mini\",\n",
" training_file=train_file.id,\n",
" validation_file=val_file.id,\n",
" hyperparameters={\n",
" \"n_epochs\": 3,\n",
" \"batch_size\": 8,\n",
" \"learning_rate_multiplier\": 0.5\n",
" },\n",
" suffix=\"week6_bharat_ft_v1\"\n",
" )\n",
"\n",
" print(\"🆔 Job created:\", job.id)\n",
"\n",
" # Poll until completion\n",
" status = job.status\n",
" while status in (\"validating_files\", \"queued\", \"running\"):\n",
" print(\"⏳ Status:\", status)\n",
" time.sleep(20)\n",
" job = client.fine_tuning.jobs.retrieve(job.id)\n",
" status = job.status\n",
"\n",
" if job.status != \"succeeded\":\n",
" raise RuntimeError(f\"❌ Fine-tune failed with status: {job.status}\")\n",
"\n",
" ft_model = job.fine_tuned_model\n",
" print(\"🎯 Fine-tuning complete! Model ID:\", ft_model)\n"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "32a2b85e-e978-4c8f-90d9-d697731e6569",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"🧮 Evaluating simulated fine-tuned model performance...\n",
"\n",
"📊 Validation Mean Absolute Error (Simulated): 1.76\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAiUAAAGHCAYAAABvUSKTAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAd+RJREFUeJzt3Xd4VNXWwOHfyWTSCymkQYBQpIMUpUiHhK5e9KKCiIKIokgERNFPBQtcG8UgtgtEQUSleBWQ3oTQISJFQAhNEkIJ6WUys78/YkaHJJDAJDMT1vs8uZc5Z589a83OZJb7nLNHU0ophBBCCCFszMnWAQghhBBCgBQlQgghhLATUpQIIYQQwi5IUSKEEEIIuyBFiRBCCCHsghQlQgghhLALUpQIIYQQwi5IUSKEEEIIuyBFiRBCCCHsghQlQgghhLALUpTcBv71r3/h7u7O1atXS2wzePBg9Ho9Fy5cKHW/mqYxadIk8+NNmzahaRqbNm264bGPP/44tWrVKvVz/dPs2bOJjY0tsv3UqVNomlbsvvI2adIkNE0z/7i4uBAREcGYMWOu+7pb07XjERsbi6ZpnDp1qkz9rFy50qKff6pVqxaPP/74TcdYWQwYMABN03juueduuo+4uDgmTZpks9+PW/XVV19RtWpV0tPTzdsyMzN59913ad68OT4+Pnh7e1OnTh0GDhzI5s2bze3K8reiPHTp0oUuXbrc1LEl/f2xhmvHaM6cOVSrVo3MzMxyeT57JEXJbWD48OHk5OSwcOHCYvenpqaybNky+vXrR3Bw8E0/T8uWLdm+fTstW7a86T5Ko6Q/CqGhoWzfvp2+ffuW6/Nfz6pVq9i+fTsrVqzg/vvvJyYmht69e2OLr5jq27cv27dvJzQ0tEzHrVy5ksmTJxe7b9myZbz22mvWCM9hJScns3z5cgC+/vprcnJybqqfuLg4Jk+eXGFFiTVlZWXxyiuv8NJLL+Ht7Q2A0WgkKiqKd955hwcffJDvv/+exYsX88ILL5Camsovv/xiPr6i/laUh/IsSq41dOhQPD09ee+99yrk+eyBs60DEOWvd+/ehIWFMXfuXEaNGlVk/zfffEN2djbDhw+/pefx8fGhbdu2t9THrXB1dbXp8wO0atWKwMBAACIjI7l8+TLz588nLi6Oe+65p9hjsrKy8PDwsHosVatWpWrVqlbts0WLFlbtzxF99dVXGAwG+vbty4oVK1i6dCmDBg2ydVgV6ssvv+Ty5cs8+eST5m1btmwhLi6OuXPn8sQTT5i39+zZk+eeew6TyWTeZuu/FY7C2dmZkSNH8tZbb/HSSy+Vy98JeyMzJbcBnU7H0KFD2bt3L7/99luR/fPmzSM0NJTevXtz8eJFRo0aRaNGjfDy8iIoKIhu3bpZ/FdOSUqako2NjaV+/fq4urrSsGFDvvrqq2KPnzx5Mm3atMHf3x8fHx9atmzJnDlzLGYZatWqxaFDh9i8ebP5VEnhaaCSTt9s3bqV7t274+3tjYeHB+3bt2fFihVFYtQ0jY0bN/LMM88QGBhIQEAAAwYM4Pz58zfMvSSFf3hPnz4NFEwbN2nShC1bttC+fXs8PDwYNmwYAGlpaYwfP56IiAhcXFyoVq0a0dHRRaZu09LSGDFiBAEBAXh5edGrVy+OHTtW5LlLOn2zatUqunfvjq+vLx4eHjRs2JCpU6cCBafVPv74YwCL01GFfRR3+ubMmTM8+uijBAUFmcf4ww8/tPgQKhybDz74gGnTphEREYGXlxft2rVjx44dFv2dPHmShx9+mLCwMFxdXQkODqZ79+7Ex8eX+DrPmDEDTdP4448/iux76aWXcHFx4dKlSwDs37+ffv36meMNCwujb9++nDt3rsT+/2nu3LkEBwfz5Zdf4u7uzty5c4ttt3PnTvr3709AQABubm7UqVOH6OhooOB034svvghARESE+XUufO+UdKrl2tf/Vt6vWVlZ5t83Nzc3/P39ad26Nd98880Nj/3kk0/o378/VapUMW+7fPkyQIkzc05Of3/cFPe34vHHH8fLy4vff/+dnj174unpSWhoKP/5z38A2LFjBx06dMDT05M77riDL7/80qL/wlOo1yrtacxb/fsD1n8PQ8Gp9bS0NBYtWnTd+CsLmSm5TQwbNoz//Oc/zJ07l+nTp5u3Hz58mF27dvHyyy+j0+m4cuUKAG+88QYhISFkZGSwbNkyunTpwvr168t8HjY2NpYnnniC++67jw8//JDU1FQmTZpEbm6uxR8pKPjgGjlyJDVq1AAK/giNHj2aP//8k9dffx0oOH3w4IMP4uvry+zZs4GCGZKSbN68mcjISJo1a8acOXNwdXVl9uzZ9O/fn2+++YaHHnrIov2TTz5J3759WbhwIWfPnuXFF1/k0UcfZcOGDWXKu1Dhh+Q/ZywSExN59NFHmTBhAlOmTMHJyYmsrCw6d+7MuXPneOWVV2jWrBmHDh3i9ddf57fffmPdunVomoZSivvvv5+4uDhef/117rrrLrZt20bv3r1LFc+cOXMYMWIEnTt35tNPPyUoKIhjx45x8OBBAF577TUyMzNZvHgx27dvNx9X0gfNxYsXad++PXl5ebz11lvUqlWL5cuXM378eE6cOGEeo0Iff/wxDRo0YMaMGebn69OnDwkJCfj6+gLQp08fjEYj7733HjVq1ODSpUvExcVd9zTHo48+yksvvURsbCxvv/22ebvRaGTBggX079+fwMBAMjMziYyMJCIigo8//pjg4GCSkpLYuHGjxbURJYmLi+PIkSO8+OKLBAQE8MADD/D111+TkJBARESEud3q1avp378/DRs2ZNq0adSoUYNTp06xZs0aoOD37MqVK8TExLB06VLz69uoUaMbxvBPt/J+HTt2LPPnz+ftt9+mRYsWZGZmcvDgQXNxUZJz587x22+/8cwzz1hsb926NXq9njFjxvD666/TrVu3Mp86NBgMDBgwgKeffpoXX3yRhQsXMnHiRNLS0liyZAkvvfQS1atXJyYmhscff5wmTZrQqlWrMj1HSW717095vYdDQkJo0KABK1asMP8HTKWmxG2jc+fOKjAwUOXl5Zm3jRs3TgHq2LFjxR6Tn5+vDAaD6t69u/rXv/5lsQ9Qb7zxhvnxxo0bFaA2btyolFLKaDSqsLAw1bJlS2UymcztTp06pfR6vapZs2aJsRqNRmUwGNSbb76pAgICLI5v3Lix6ty5c5FjEhISFKDmzZtn3ta2bVsVFBSk0tPTLXJq0qSJql69urnfefPmKUCNGjXKos/33ntPASoxMbHEWJVS6o033lCASkpKUgaDQaWkpKgFCxYod3d3FR4errKzs5VSBWMAqPXr11scP3XqVOXk5KR2795tsX3x4sUKUCtXrlRKKfXzzz8rQM2cOdOi3TvvvFNkPApzSkhIUEoplZ6ernx8fFSHDh0sXs9rPfvss6qkPw01a9ZUQ4cONT9++eWXFaB27txp0e6ZZ55Rmqapo0ePKqX+HpumTZuq/Px8c7tdu3YpQH3zzTdKKaUuXbqkADVjxowS4yvJgAEDVPXq1ZXRaDRvW7lypQLUTz/9pJRSas+ePQpQP/zwQ5n7V0qpYcOGKUAdOXJEKfX37/xrr71m0a5OnTqqTp065nEvzvvvv28xPv907VgWuvb1v1ZZ3q9NmjRR999/f4l9leTbb79VgNqxY0eRfXPmzFFeXl4KUIAKDQ1Vjz32mNqyZYtFu2v/Viil1NChQxWglixZYt5mMBhU1apVFaD27dtn3n758mWl0+nU2LFjzdsK34PXuvZ9oFTB+7C4vyGFbubvT3m8hwsNHjxYBQcHlxhvZSKnb24jw4cP59KlS/z4448A5Ofns2DBAjp27Ei9evXM7T799FNatmyJm5sbzs7O6PV61q9fz5EjR8r0fEePHuX8+fMMGjTIYlq1Zs2atG/fvkj7DRs20KNHD3x9fdHpdOj1el5//XUuX75McnJymfPNzMxk586dPPjgg3h5eZm363Q6hgwZwrlz5zh69KjFMffee6/F42bNmgF/n365kZCQEPR6PX5+fjz66KO0bNmSVatW4ebmZm7j5+dHt27dLI5bvnw5TZo04c477yQ/P9/807NnT4tp7o0bNwIFU7r/VJprGuLi4khLS2PUqFHFTnPfjA0bNtCoUSPuvvtui+2PP/44SqkiM0x9+/ZFp9OZH1/7+vr7+1OnTh3ef/99pk2bxv79+y1OA13PE088wblz51i3bp1527x58wgJCTH/V2jdunXx8/PjpZde4tNPP+Xw4cOlzjUjI4PvvvuO9u3b06BBAwA6d+5MnTp1iI2NNcd57NgxTpw4wfDhwy3Gvbzc7Pv17rvv5ueff+bll19m06ZNZGdnl+r5Ck9nBgUFFdk3bNgwzp07x8KFC3n++ecJDw9nwYIFdO7cmffff/+GfWuaRp8+fcyPnZ2dqVu3LqGhoRbXM/n7+xMUFFTq92Vp3Orfn/J8DwcFBZGcnEx+fv7NJ+ggpCi5jRROO86bNw8ouMviwoULFhe4Tps2jWeeeYY2bdqwZMkSduzYwe7du+nVq1ep/2gVKpwGDgkJKbLv2m27du0iKioKgC+++IJt27axe/duXn31VYAyPzdASkoKSqlip5DDwsIsYiwUEBBg8bhwara0z79u3Tp2795NfHw8ly5dYuvWrUWm5IuL58KFCxw4cAC9Xm/x4+3tjVLKfD3E5cuXcXZ2LhJnca/xtS5evAhA9erVS5VLaVy+fNmqr6+maaxfv56ePXvy3nvv0bJlS6pWrcrzzz9/w9MrvXv3JjQ01Pz7nZKSwo8//shjjz1mLoR8fX3ZvHkzd955J6+88gqNGzcmLCyMN954A4PBcN3+v/32WzIyMhg4cCBXr17l6tWrpKamMnDgQM6ePcvatWuB8nmdS3Ir79ePPvqIl156iR9++IGuXbvi7+/P/fffz/Hjx697XGG/JRVcvr6+PPLII8ycOZOdO3dy4MABgoODefXVV294p5GHh0eRfl1cXPD39y/S1sXF5abvfLqWNf7+lOd72M3NDaWU1fK1Z3JNyW3E3d2dRx55hC+++ILExETmzp2Lt7c3//73v81tFixYQJcuXfjkk08sji3N+fZrFb7pkpKSiuy7dtuiRYvQ6/UsX77c4o/SDz/8UObnLeTn54eTkxOJiYlF9hX+117hnTLW0rx58xv2WdwsRWBg4HUvmizsMyAggPz8fC5fvmzxR6241/hahde1lPaCztIICAiw+utbs2ZN5syZAxTMOnz33XdMmjSJvLw8Pv300xKPK5wB++ijj7h69SoLFy4kNzfX4k4QgKZNm7Jo0SKUUhw4cIDY2FjefPNN3N3defnll0vsvzCm6Oho8wWr1+7v2bOnVV5nV1dXcnNzi2y/tsi7lferp6cnkydPZvLkyVy4cME8a9K/f39+//33Eo8rHNMrV66U6pqRxo0b8/DDDzNjxgyOHTtWZFbNWgr/buTm5lpcZ1ZYDFyPNf7+lOd7+MqVK7i6ulrM+FZWMlNymxk+fDhGo5H333+flStX8vDDD1vcZqZpWpELRw8cOGBx0WNp1a9fn9DQUL755huLK9hPnz5NXFycRVtN03B2draY2s/Ozmb+/PlF+nV1dS3Vf7l4enrSpk0bli5datHeZDKxYMECqlevzh133FHmvMpDv379OHHiBAEBAbRu3brIT+EV/l27dgUK1sf4p5LWoPmn9u3b4+vry6effnrddVPKMjvUvXt3Dh8+zL59+yy2f/XVV2iaZo73Zt1xxx383//9H02bNi3yHMV54oknyMnJ4ZtvviE2NpZ27dqZT7VcS9M0mjdvzvTp06lSpcp1+z9y5Ajbt2/ngQceYOPGjUV+unfvzv/+9z8uX77MHXfcQZ06dZg7d26xhUWh673OtWrV4sCBAxbbNmzYQEZGRpEcrPF+DQ4O5vHHH+eRRx7h6NGjZGVlldi28PU8ceKExfbLly+Tl5dX7DGFRU7hDFp5KHyPXPu6/fTTTzc81hp/f8rzPXzy5MkyXwTtqGSm5DbTunVrmjVrxowZM1BKFVmbpF+/frz11lu88cYbdO7cmaNHj/Lmm28SERFR5vOZTk5OvPXWWzz55JP861//YsSIEVy9epVJkyYVmars27cv06ZNY9CgQTz11FNcvnyZDz74oNg7awr/S/fbb7+ldu3auLm50bRp02JjmDp1KpGRkXTt2pXx48fj4uLC7NmzOXjwIN98843Vrq24VdHR0SxZsoROnTrxwgsv0KxZM0wmE2fOnGHNmjWMGzeONm3aEBUVRadOnZgwYQKZmZm0bt2abdu2FfvH81peXl58+OGHPPnkk/To0YMRI0YQHBzMH3/8wa+//sqsWbMAzK/lu+++S+/evdHpdDRr1gwXF5cifb7wwgt89dVX9O3blzfffJOaNWuyYsUKZs+ezTPPPFPmou/AgQM899xz/Pvf/6ZevXq4uLiwYcMGDhw4cN1ZjEINGjSgXbt2TJ06lbNnz/L5559b7F++fDmzZ8/m/vvvp3bt2iilWLp0KVevXiUyMrLEfgtnSSZMmFDsf+mnp6ezfv16FixYwJgxY/j444/p378/bdu25YUXXqBGjRqcOXOG1atXmz+MCl/nmTNnMnToUPR6PfXr18fb25shQ4bw2muv8frrr9O5c2cOHz7MrFmzzHcoFbqV92ubNm3o168fzZo1w8/PjyNHjjB//nzatWt33fUw2rRpg7u7Ozt27LC4Bmvjxo2MGTOGwYMH0759ewICAkhOTuabb75h1apVPPbYY+V6SqtPnz74+/szfPhw3nzzTZydnYmNjeXs2bM3PNYaf3/K6z1sMpnYtWvXLa8j5TBsdYWtsJ2ZM2cqQDVq1KjIvtzcXDV+/HhVrVo15ebmplq2bKl++OEHNXTo0CJ3y3CDu28K/fe//1X16tVTLi4u6o477lBz584ttr+5c+eq+vXrK1dXV1W7dm01depUNWfOnCJXzp86dUpFRUUpb29vBZj7Ke7uG6WU+uWXX1S3bt2Up6encnd3V23btjXfjVGo8Ar9a6+cLymnaxVe+X/x4sXrtuvcubNq3LhxsfsyMjLU//3f/6n69esrFxcX5evrq5o2bapeeOEFlZSUZG539epVNWzYMFWlShXl4eGhIiMj1e+//37Du28KrVy5UnXu3Fl5enoqDw8P1ahRI/Xuu++a9+fm5qonn3xSVa1aVWmaZtFHcXd/nD59Wg0aNEgFBAQovV6v6tevr95//32Lu2AKx+b9998vkvc/475w4YJ6/PHHVYMGDZSnp6fy8vJSzZo1U9OnT7e4a+d6Pv/8cwUod3d3lZqaarHv999/V4888oiqU6eOcnd3V76+vuruu+9WsbGxJfaXl5engoKC1J133llim/z8fFW9enXVtGlT87bt27er3r17K19fX+Xq6qrq1KmjXnjhBYvjJk6cqMLCwpSTk5PF71lubq6aMGGCCg8PV+7u7qpz584qPj6+yOt/K+/Xl19+WbVu3Vr5+fmZ33MvvPCCunTpUol5FhoyZEiRvx9nz55V//d//6fuueceFRISopydnZW3t7dq06aNiomJsRi/ku6+8fT0LPJcJb1natasqfr27WuxbdeuXap9+/bK09NTVatWTb3xxhvqv//9b6nuvrnVvz9KWf89rJRS69evV4Dau3dvkdegMtKUssH610IIIRzWnj17uOuuu9ixYwdt2rSxdTiV2pAhQzh58iTbtm2zdSgVQooSIYQQZfbQQw+RmZlp/h4gYX0nTpygYcOGbNiwgQ4dOtg6nAohF7oKIYQosw8//JC77rrrpu7ME6Vz5swZZs2addsUJCAzJUIIIYSwEzJTIoQQQgi7IEWJEEIIIeyCrFNSSiaTifPnz+Pt7W03a1sIIYQQjkApRXp6OmFhYUW+If6fpCgppfPnzxMeHm7rMIQQQgiHdfbs2esuoidFSSl5e3sDBS+oj4+PVfo0GAysWbOGqKgo9Hq9Vfq0NcnJ/lW2fEBychSSk2Moj5zS0tIIDw83f5aWRIqSUio8ZePj42PVosTDwwMfH59K9cssOdm3ypYPSE6OQnJyDOWZ040uf5ALXYUQQghhF6QoEUIIIYRdkKJECCGEEHZBrimxIqUU+fn5GI3GUrU3GAw4OzuTk5NT6mPsnSPnpNPpcHZ2llu+hRDCRqQosZK8vDwSExPJysoq9TFKKUJCQjh79myl+SB09Jw8PDwIDQ3FxcXF1qEIIcRtR4oSKzCZTCQkJKDT6QgLC8PFxaVUH8gmk4mMjAy8vLyuu5iMI3HUnJRS5OXlcfHiRRISEqhXr55DxS+EEJWBFCVWkJeXh8lkIjw8HA8Pj1IfZzKZyMvLw83NrdJ8ADpyTu7u7uj1ek6fPm3OQQghbidGk2JnwhX2XtIISLhCu7pB6JwqbtZbihIrcrQPYVGUjKEQ4ra0cSrHL2bx2IkuJKbmADq+Or6HUF83vqqziXpVPaDrxHIPQ/4CCyGEELe54xezqHf4Ix7MWGix/d8ZC6l3+COOXyz99ZK3QmZKhBBCiNuY0aR47EQXHjScZ5x+MVW0DN7Kf4zRuqWM1S9mmuFBvj/Rha0mVe6ncmSmxI4YTYrtJy7zv/g/2X7iMkaTsnVIVjNp0iTuvPNO8+PHH3+c+++/v8LjOHXqFJqmER8fX+HPLYQQ9mhXwhUSU3OIMQ7gu/xODHdexQnXwYzTL+ZDw4N8ZBxAYmoOuxKulHssMlNiJ1YdTGTyT4f/OpdXINTXjTf6N6JXk9Bye97HH3+cL7/8EgBnZ2fCw8MZMGAAkydPxtPTs9yed+bMmShVuqLr1KlTREREsH//fovCRgghxK1LTv/7c6eqlgqATlPkKmdijAOKbVdeZKbEDqw6mMQzC/ZZFCQASak5PLNgH6sOJpbr8/fq1YvExEROnjzJ22+/zezZsxk/fnyRdgaDwWrP6evrS5UqVazWnxBCiJsT5F1wp+Ed2lm66n4FIE/pcNXyGa1bWqRdeZKipBwopcjKyy/VT0ZOPpOXH6a4OYPCbZN+PEx6jqFU/ZV29uGfXF1dCQkJITw8nEGDBjF48GB++OEH8ymXuXPnUrt2bVxdXVFKkZqaylNPPUVQUBA+Pj5069aNX3/91aLPd999l+DgYLy9vRk+fDg5OZYF17Wnb0wmE++++y5169bF1dWVGjVq8M477wAQEREBQIsWLdA0jS5dupiPmzdvHg0bNsTNzY0GDRowe/Zsi+fZtWsXLVq0wM3NjdatW7N///4yvz5CCFGZ3R3hT6ivG9OcPwHgmKkad+TO50PDg4zTL+Z53VJCfd24O8K/3GOR0zflINtgpNHrq63SlwKS0nJoOmlNqdoffrMnHi63Nqzu7u7mWZE//viD7777jiVLlqDT6QDo27cv/v7+rFy5El9fXz777DO6d+/OsWPHqFKlCsuWLWPSpEl8/PHHdOzYkfnz5/PRRx9Ru3btEp9z4sSJfPHFF0yfPp0OHTqQmJjI77//DhQUFnfffTfr1q2jcePG5tVWv/jiC9544w1mzZpFixYt2L9/PyNGjMDT05OhQ4eSmZlJv3796NatGwsWLCAhIYExY8bc0msjhBCVjc5J4+Oqy2hy7hQALxmeAiDGOAANGKtfTP86Yeicupd7LFKUCAu7du1i4cKFdO9e8MuXl5fH/PnzqVq1KgAbNmzgt99+Izk5GVdXVwA++OADfvjhBxYvXsyTTz7JJ598whNPPMGTTz4JwNtvv826deuKzJYUSk9PZ+bMmcyaNYuhQ4cCUKdOHTp06ABgfu6AgABCQkLMx7311lt8+OGHDBhQcM4zIiKCw4cP89lnnzF06FC+/vprjEYjc+fOxcPDg8aNG3Pu3DmeeeYZa79sQgjh0HwuFcwi71X12a/qmbd/7zWI/nXCCtYpqQBSlJQDd72Ow2/2vGE7k8nE5kPnePb7IzdsG/vEXaWaOnPX60oV4z8tX74cLy8v8vPzMRgM3HfffcTExDB79mxq1qxpLgoA9u7dS0ZGBgEBARZ9ZGdnc+LECQCOHTvGqFGjLPa3a9eOjRs3Fvv8R44cITc311wIlcbFixc5e/Ysw4cPZ8SIEebt+fn5+Pr6mvtt3ry5xSq77dq1K/VzCCHE7eBMYjJVs0+CBkE9x7MgsDVrftlJVMc2f63oWv4zJIWkKCkHmqaV6hSKyWSibYQfIT5uXEjLKfa6Eg0I8XWjY72q5XZ/eNeuXfnkk0/Q6/WEhYWh1+vN+669A8dkMhEaGsqmTZuK9HOzF666u7uX+RiTyQQUnMJp06aNxb7C00w3c32NEELcbn5b/jF9tSySnKsR3vZBQoxGLh9RtInwr9Al5kEudLU5nZPG6/0aAgUFyD8VPn6jf6Ny/cXw9PSkbt261KxZ06IgKU7Lli1JSkrC2dmZunXrWvwEBgYCcMcdd7Bz506L43bs2FFin/Xq1cPd3Z3169cXu7/wGhKj0WjeFhwcTLVq1Th58mSROAovjG3UqBG//vor2dnZpYpDCCFuNynpWTQ/9zUAma2eBht/1YYUJXagV5MQPnm0JSG+lrdbhfi68cmjLct1nZKy6tGjB+3ateP+++9n9erVnDp1iri4OP7v//6PPXv2APD0008zb9485s6dy7Fjx3jjjTc4dOhQiX26ubnx0ksvMWHCBL766itOnDjBjh07mDNnDgBBQUG4u7uzatUqLly4QGpqwX30kyZNYurUqcycOZNjx47x22+/MW/ePKZNmwbAoEGDcHJyYvjw4Rw+fJiVK1fywQcflPMrJIQQjmPninlU1y6SqvlQu/uTtg5HTt/Yi15NQolsFMKuhCskp+cQ5F1w+1VFT53diKZprFy5kldffZVhw4Zx8eJFQkJC6NSpE8HBwQAMGDCAxMREXnrpJXJycnjggQd45plnWL265DuSXnvtNZydnXn99dc5f/48oaGhPP3000DBom4fffQRb775Jq+//jodO3Zk06ZNPPnkk3h4ePD+++8zYcIEPD09adq0KdHR0QB4eXnx008/8fTTT9OiRQsaNWrEu+++ywMPPFDur5MQQti7nLx8avz+XwAS6w/B16ViLma9Hk3JifdSSUtLw9fXl9TUVHx8fCz25eTkkJCQQERERJm+7t5kMpGWloaPj0+l+XZaR8+puLE0GAysXLmSPn363PD0liOobPmA5OQoJCf7sv7nJXTfOYxcXHAaewi9TxBQPjld7zP0nxzvU0MIIYQQt8RkUnjsKVgs7WS1e80Fia1JUSKEEELcZnbsiqOdcTcmNGr0fdHW4ZhJUSKEEELcZrI3fwTAH36d8AxrYONo/iZFiRBCCHEbOXj0GB2y1gEQEFn0y1dtyaZFyZYtW+jfvz9hYWFomsYPP/xQYtuRI0eiaRozZsyw2J6bm8vo0aMJDAzE09OTe++9l3Pnzlm0SUlJYciQIfj6+uLr68uQIUO4evWq9RMSQggh7NzZ1R/hquVzyr0xAQ072jocCzYtSjIzM2nevDmzZs26brsffviBnTt3EhYWVmRfdHQ0y5YtY9GiRWzdupWMjAz69etnsdDWoEGDiI+PZ9WqVaxatYr4+HiGDBli9XyEEEIIe3buwiXaXl4GgL7j86DZ17ITNl2npHfv3vTu3fu6bf7880+ee+45Vq9eTd++fS32paamMmfOHObPn0+PHj0AWLBgAeHh4axbt46ePXty5MgRVq1axY4dO8zLkX/xxRe0a9eOo0ePUr9+/fJJTgghhLAzvy6fTV8tgwvOYVRr+29bh1OEXS+eZjKZGDJkCC+++CKNGzcusn/v3r0YDAaioqLM28LCwmjSpAlxcXH07NmT7du34+vra/H9KG3btsXX15e4uLgSi5Lc3Fxyc3PNj9PS0oCC+7cNBoNFW4PBgFIKk8lk/k6W0ihcIqbw2MrA0XMymUwopTAYDObv0Ckc72vH3VFVtnxAcnIUkpNtXc3IoemZBaBBavMn8TeawFj073R55FTavuy6KHn33Xdxdnbm+eefL3Z/UlISLi4u+Pn5WWwPDg4mKSnJ3CYoqOj910FBQeY2xZk6dSqTJ08usn3NmjUW3zoLBSuOhoSEkJGRQV5e3g3zulZ6enqZj7F3jppTXl4e2dnZbNmyhfz8fIt9a9eutVFU5aOy5QOSk6OQnGzj4ondPKld4CpeHDWEc2Tlyuu2t2ZOWVlZpWpnt0XJ3r17mTlzJvv27UMr4zkvpZTFMcUdf22ba02cOJGxY8eaH6elpREeHk5UVFSxK7qePXsWLy+vMq3oqpQiPT0db2/vMudor6yVk06nY8mSJdx///3WC64UcnJycHd3p1OnThYruq5du5bIyEiHW7GxOJUtH5CcHIXkZDu5BiOn9r8JwPl6g+nV/18lti2PnArPNtyI3RYlv/zyC8nJydSoUcO8zWg0Mm7cOGbMmMGpU6cICQkhLy+PlJQUi9mS5ORk2rdvD0BISAgXLlwo0v/FixfN39VSHFdXV1xdXYts1+v1RQbJaDSiaRpOTk5lWlq98PSG0+Z30XTO0HlC0Uab3wOTEbpOLHW/ZRUXF0fHjh2JjIxk1apVpT6uVq1aREdHm79rBv7OqfD1uBVlfT2twcnJCU3Tih3n4rY5ssqWD0hOjkJyqni/bFhJN/4gFz31+o0tVazWzKm0/djtOiVDhgzhwIEDxMfHm3/CwsJ48cUXzV/s1qpVK/R6vcUUU2JiIgcPHjQXJe3atSM1NZVdu3aZ2+zcuZPU1FRzG1tTTjrY+E5BAfJPm98r2O6kK9fnnzt3LqNHj2br1q2cOXOmXJ9LCCFExTKZFK67PwbgZFh/9L4hNo6oZDYtSjIyMswFB0BCQgLx8fGcOXOGgIAAmjRpYvGj1+sJCQkxX5zq6+vL8OHDGTduHOvXr2f//v08+uijNG3a1Hw3TsOGDenVqxcjRoxgx44d7NixgxEjRtCvX7/yu/NGKcjLLN2PIQvajoJOLxYUIBveLti+4e2Cx51ehHbPlr6/Mn6/YmZmJt999x3PPPMM/fr1IzY21mL/jz/+SOvWrXFzcyMwMJABAwYA0KVLF06fPs0LL7yApmnmUzWTJ0+mY0fL+95nzJhBrVq1zI93795NZGQkgYGB+Pr60rlzZ/bt21f211kIIcQN7dqzk3aGgv8wt6cl5Ytj09M3e/bsoWvXrubHhddwDB06tMiHY0mmT5+Os7MzAwcOJDs7m+7duxMbG2u+cwLg66+/5vnnnzffpXPvvffecG2UW2LIgilF11S5lhNQ5dqNW94v+Cnp8Y28ch5cPEvd/Ntvv6V+/frUr1+fRx99lNGjR/Paa6+haRorVqxgwIABvPrqq8yfP5+8vDxWrFgBwNKlS2nevDlPPfUUI0aMKH18FFwEO3ToUD76qGCZ4w8//JA+ffpw/PhxvL29y9SXEEKI68vYNBMnTXGsSgfuqNbI1uFcl02Lki5duphvIS2NU6dOFdnm5uZGTEwMMTExJR7n7+/PggULbibESm/OnDk8+uijAPTq1YuMjAzWr19Pjx49eOedd3j44Yct7kJq3rw5UPCa6nQ6vL29CQkp21Rgt27dLB5/9tln+Pn5sXnzZvr163eLGQkhhCh0+PgJOmSuBQ38e4yzdTg3ZLcXujo0vUfBjMUNmEwm0tLT8fH2Lrigc+v0glkRnQsY8wpO3XR4oezPXUpHjx5l165dLF26FCi4tfmhhx5i7ty59OjRg/j4+DLPgpRGcnIyr7/+Ohs2bODChQsYjUaysrLkehYhhLCyU6tm0kgzcNqtATUbd73xATYmRUl50LTSnUIxmUBvLGj7ywcFBUnXVwvuwim8yFXnUvxdOVYwZ84c8vPzqVatmnmbUgq9Xk9KSgru7u5l7tPJyanI7Ne1i+Y8/vjjXLx4kRkzZlCzZk1cXV1p167dTa3xIoQQonjnLlyizaWloIFThzF2t6R8caQosQdb3odNU/4uSODv/9/4juVjK8nPz+err77iww8/tFgRF+CBBx7g66+/plmzZqxfv54nnnii2D5cXFwsvmMIIDAwkOTkZIvCpPBC5kK//PILs2fPpk+fPgCcPXuWS5cuWSErIYQQhX5d8Sl9tXSSdSGEtxto63BKRYoSO6CZjJYFSaHCxyZj0YNu0fLly0lJSWH48OH4+vpa7HvwwQeZM2cO06dPp3v37tSpU4eHH36Y/Px8fv75ZyZMKIirVq1abNmyhYcffhhXV1cCAwPp0qULo0eP5v333+ff//43q1at4ueff7ZYcK5u3brMnz+f1q1bk5aWxosvvnhTszJCCCGKl5qRQ5PT80GDtDufIkjnGB/3drtOye1EdXm55JmQzhPKZeG0OXPm0KNHjyIFCRTMlMTHx+Pj48P333/Pjz/+yJ133km3bt3YuXOnud2bb77JqVOnqFOnDlWrVgUKbsH+4IMPmD17Ns2bN2fXrl2MHz/eov+5c+eSkpJCixYtGDJkCM8//3yxXwUghBDi5mz/eT41tSTSNS/qRD1l63BKzTFKJ2F1P/30U4n7WrZsaT790rJlS/PaJNdq27Ytv/76a5Htw4YNIzo62mI11ldeecX87xYtWrB7926LYx588EGLx2W5K0sIIcTf8vJNhB7+AoA/6wyigavjLLUgMyVCCCFEJbJt4wqaq6Pk4UztvmW8g9PGpCgRQgghKgmlFPqdBUvKnwjti4vfjRfytCdSlAghhBCVxK69e2hv2AFAeB/7XlK+OFKUCCGEEJVE2saCJeWP+7bHK7yprcMpMylKrEguznR8MoZCCEd15EQCHTJWA1Clx1gbR3NzpCixAr1eD0BWVpaNIxG3qnAMC8dUCCEcRcLPH+Gu5XHG7Q6qNulh63BuitwSbAU6nY4qVaqQnJwMgIeHB1oplvM1mUzk5eWRk5NjcfusI3PUnJRSZGVlkZycTJUqVSy+ZVoIIezd+UtXaHNxMWigtX/eIZaUL44UJVZS+E25hYVJaSilyM7Oxt3dvVRFjCNw9JyqVKlS5m89FkIIW4v/6VP6aGlc1AURfs8jtg7npklRYiWaphEaGkpQUFCRL6AricFgYMuWLXTq1KnSnC5w5Jz0er3MkAghHE5adi4NT30FGlxt9iRVHWRJ+eI4buR2SqfTlfqDTafTkZ+fj5ubm8N9gJekMuYkhBD2LG7l1/TSEsnAk7o9n7F1OLfEcU76CyGEEMJCXr6J4IMFS8qfq/MwmpvPDY6wb1KUCCGEEA5q2+ZVtFCHMeBMhIMtKV8cKUqEEEIIB6SUQrdjFgAngnvh6h9u44hunRQlQgghhAPas38f9+TFAVCtzwQbR2MdUpQIIYQQDihlw0x0muIPnzZ412xu63CsQooSIYQQwsH8fvI0HdJXAeDTzTGXlC+OFCVCCCGEgznx80d4aLmcda1LUPOetg7HaqQoEUIIIRxI4uUU7k7+HgDV7jmHXVK+OFKUCCGEEA5k3/LPqaqlctkpkBodH7V1OFYlRYkQQgjhINKzc2lw8ksArjQbDrrKtXK2TYuSLVu20L9/f8LCwtA0jR9++MG8z2Aw8NJLL9G0aVM8PT0JCwvjscce4/z58xZ95ObmMnr0aAIDA/H09OTee+/l3LlzFm1SUlIYMmQIvr6++Pr6MmTIEK5evVoBGQohhBDWE7dqEXW0P8nEgzo9n7V1OFZn06IkMzOT5s2bM2vWrCL7srKy2LdvH6+99hr79u1j6dKlHDt2jHvvvdeiXXR0NMuWLWPRokVs3bqVjIwM+vXrh9FoNLcZNGgQ8fHxrFq1ilWrVhEfH8+QIUPKPT8hhBDCWgxGE4EHPgfgbO2BOLn72jgi67PpF/L17t2b3r17F7vP19eXtWvXWmyLiYnh7rvv5syZM9SoUYPU1FTmzJnD/Pnz6dGjBwALFiwgPDycdevW0bNnT44cOcKqVavYsWMHbdq0AeCLL76gXbt2HD16lPr165dvkkIIIYQVbNu8li7qIPnoqNW38twG/E8O9S3BqampaJpGlSpVANi7dy8Gg4GoqChzm7CwMJo0aUJcXBw9e/Zk+/bt+Pr6mgsSgLZt2+Lr60tcXFyJRUlubi65ubnmx2lpaUDBaSWDwWCVfAr7sVZ/9kBysn+VLR+QnByF5HTzlFKwveCswvGqUdT1CSu35yyPnErbl8MUJTk5Obz88ssMGjQIH5+Cb0FMSkrCxcUFPz8/i7bBwcEkJSWZ2wQFBRXpLygoyNymOFOnTmXy5MlFtq9ZswYPD49bSaWIa2eEKgPJyf5VtnxAcnIUklPZJV66xJN5W0GDBJ/2HFu5slyfD6ybU1ZWVqnaOURRYjAYePjhhzGZTMyePfuG7ZVSaP+4b1sr5h7ua9tca+LEiYwd+/f0WFpaGuHh4URFRZmLoltlMBhYu3YtkZGR6PWV4wpqycn+VbZ8QHJyFJLTzVs/cwTOmok/vFoT+fAz5fY8UD45FZ5tuBG7L0oMBgMDBw4kISGBDRs2WBQEISEh5OXlkZKSYjFbkpycTPv27c1tLly4UKTfixcvEhwcXOLzurq64urqWmS7Xq+3+i9eefRpa5KT/ats+YDk5Cgkp7I5fvosHdNXggY+3cdV2GtnzZxK249dr1NSWJAcP36cdevWERAQYLG/VatW6PV6iymmxMREDh48aC5K2rVrR2pqKrt27TK32blzJ6mpqeY2QgghhL06tuIjPLVc/nSpTdCdxd8cUlnYdKYkIyODP/74w/w4ISGB+Ph4/P39CQsL48EHH2Tfvn0sX74co9FovgbE398fFxcXfH19GT58OOPGjSMgIAB/f3/Gjx9P06ZNzXfjNGzYkF69ejFixAg+++wzAJ566in69esnd94IIYSwaxeupNL6wnegQX6bZyvVkvLFsWlRsmfPHrp27Wp+XHgNx9ChQ5k0aRI//vgjAHfeeafFcRs3bqRLly4ATJ8+HWdnZwYOHEh2djbdu3cnNjYWnU5nbv/111/z/PPPm+/Suffee4tdG0UIIYSwJ3uWf0Ff7SpXnAKo2fkxW4dT7mxalHTp0qXgNqcSXG9fITc3N2JiYoiJiSmxjb+/PwsWLLipGIUQQghbyMgxcMfJWAAuNRmGv7OLbQOqAHZ9TYkQQghxu9q66lvqcZYs3Kjbq/ItKV8cKUqEEEIIO5NvNBFwoOA6yDO1/o2Th98NjqgcpCgRQggh7MzWrRu4y3SAfJyo1W+8rcOpMFKUCCGEEHZEKYXaVnCd5ImqkbgF1rJtQBVIihIhhBDCjuz77SAdc7cAENL7RRtHU7GkKBFCCCHsyMV1M3HWTJzwaoVv7btsHU6FkqJECCGEsBMnzvzJPanLAfDq+oKNo6l4UpQIIYQQduL3FTF4a9mc19ckuGU/W4dT4aQoEUIIIexAckoarZK+BSDvNlhSvjhSlAghhBB2YPeK/xKiXSHFyY9aXR63dTg2IUWJEEIIYWOZOQbq/hELwMVGT4Czq20DshEpSoQQQggb27rme+pzmmzcqNN7tK3DsRkpSoQQQggbyjea8IsvWFL+dM0B6Dz9bRyR7UhRIoQQQtjQtrjN3G2Kx4gTtfreXoulXUuKEiGEEMJGlFIYtxYsKf9HQDfcgmrbOCLbkqJECCGEsJH4g4fomLMJgOBet/csCUhRIoQQQtjMhXUz0WtGTnreSZV6bW0djs1JUSKEEELYwIlzibS/+hMAHl2ibRuMnZCiRAghhLCB31fE4KNlk6ivQUir+2wdjl2QokQIIYSoYBevZtDi/CIAcu96Bpzk4xikKBFCCCEq3K4VcwjTLnNVq0LNrk/YOhy7IUWJEEIIUYGycg3UPj4PgOSGQ9H07jaOyH5IUSKEEEJUoK1rl9KQBHJwoU6fMbYOx65IUSKEEEJUEKNJ4bPvUwBOhf8LnVeAjSOyL1KUCCGEEBUkLm4LbU37MKFRq98EW4djd6QoEUIIISqAUorcwiXl/bviFlzXxhHZH5sWJVu2bKF///6EhYWhaRo//PCDxX6lFJMmTSIsLAx3d3e6dOnCoUOHLNrk5uYyevRoAgMD8fT05N577+XcuXMWbVJSUhgyZAi+vr74+voyZMgQrl69Ws7ZCSGEEH87cOQonbI3AFBVlpQvlk2LkszMTJo3b86sWbOK3f/ee+8xbdo0Zs2axe7duwkJCSEyMpL09HRzm+joaJYtW8aiRYvYunUrGRkZ9OvXD6PRaG4zaNAg4uPjWbVqFatWrSI+Pp4hQ4aUe35CCCFEoT/XzMBFM5Lg0Qy/O9rbOhy75GzLJ+/duze9e/cudp9SihkzZvDqq68yYMAAAL788kuCg4NZuHAhI0eOJDU1lTlz5jB//nx69OgBwIIFCwgPD2fdunX07NmTI0eOsGrVKnbs2EGbNm0A+OKLL2jXrh1Hjx6lfv36FZOsEEKI29bJP5O4J+V/oIFb52hbh2O3bFqUXE9CQgJJSUlERUWZt7m6utK5c2fi4uIYOXIke/fuxWAwWLQJCwujSZMmxMXF0bNnT7Zv346vr6+5IAFo27Ytvr6+xMXFlViU5Obmkpuba36clpYGgMFgwGAwWCXHwn6s1Z89kJzsX2XLByQnR3E753Ro+Sz6a1kkOVcjsEU/u34NymOcStuX3RYlSUlJAAQHB1tsDw4O5vTp0+Y2Li4u+Pn5FWlTeHxSUhJBQUFF+g8KCjK3Kc7UqVOZPHlyke1r1qzBw8OjbMncwNq1a63anz2QnOxfZcsHJCdHcbvllJFnpPP5b0CD36pEkvXzqgqM7OZZc5yysrJK1c5ui5JCmqZZPFZKFdl2rWvbFNf+Rv1MnDiRsWPHmh+npaURHh5OVFQUPj4+pQ3/ugwGA2vXriUyMhK9Xm+VPm1NcrJ/lS0fkJwcxe2a0+rvPqG6dolUzYfOT7yJ5mLd/7C1tvIYp8KzDTdit0VJSEgIUDDTERoaat6enJxsnj0JCQkhLy+PlJQUi9mS5ORk2rdvb25z4cKFIv1fvHixyCzMP7m6uuLq6lpku16vt/qbqTz6tDXJyf5VtnxAcnIUt1NO2bn55iXlLzR4jDs8fSs6tJtmzXEqbT92u05JREQEISEhFtNHeXl5bN682VxwtGrVCr1eb9EmMTGRgwcPmtu0a9eO1NRUdu3aZW6zc+dOUlNTzW2EEEKI8vDL+v/RiJPk4kLt3rKk/I3YdKYkIyODP/74w/w4ISGB+Ph4/P39qVGjBtHR0UyZMoV69epRr149pkyZgoeHB4MGDQLA19eX4cOHM27cOAICAvD392f8+PE0bdrUfDdOw4YN6dWrFyNGjOCzzz4D4KmnnqJfv35y540QQohyYzQpvPZ+AkBC9fto4FP0+kZhyaZFyZ49e+jatav5ceE1HEOHDiU2NpYJEyaQnZ3NqFGjSElJoU2bNqxZswZvb2/zMdOnT8fZ2ZmBAweSnZ1N9+7diY2NRafTmdt8/fXXPP/88+a7dO69994S10YRQgghrCFuRxwdjbsxoVGjryyWVho2LUq6dOmCUqrE/ZqmMWnSJCZNmlRiGzc3N2JiYoiJiSmxjb+/PwsWLLiVUIUQQogyyfnlIwD+8O/MHaEyM18adntNiRBCCOGofj1ylE5Z6wAIjBpv42gchxQlQgghhJX9uXomrlo+p9wb49+go63DcRhSlAghhBBWdDrxIu1TfgDApZPccVMWUpQIIYQQVvTb8o+pomVywTmMsDYP2jochyJFiRBCCGElV9KzaX7uawAyW44EJ90NjhD/JEWJEEIIYSXbV8QSriWTpvkQ0WOErcNxOFKUCCGEEFaQk5dPzd//C0DiHYPRXDxtHJHjkaJECCGEsIJf1i+nCX+Qi546faJtHY5DkqJECCGEuEUmk8J9z2wAEqr1x9k3xMYROSYpSoQQQohbtGvPLtrnF3zxa3jfCTaOxnFJUSKEEELcouyts3DSFMf9OuIZ1tDW4TgsKUqEEEKIW3AhJY3Ofy0pHxApS8rfCilKhBBCiFvgc249rpqBM+4N8W/Y2dbhODQpSoQQQoibdObCZaIMawHQdRgDmmbjiBybFCVCCCHETTr082f4axkk60Ko1vbftg7H4UlRIoQQQtyElPRsmp9bCEBq8ydB52zjiByfFCVCCCHETdj+83xqakmk4UnNbsNtHU6lIEWJEEIIUUY5BiPVDhcsKb/fuzuaq7eNI6ocpCgRQgghymjrhhU05yh5OJMZ3sPW4VQaUpQIIYQQZWAyKVx2FywpfzKkDwbXKrYNqBKRokQIIYQogx17dtHBsAOAkF7jbBxN5SJFiRBCCFEGGZs+wklT/OF7D57VGts6nEpFihIhhBCilA4eO0GnzNUA+EWOtXE0lc9NFSX5+fmsW7eOzz77jPT0dADOnz9PRkaGVYMTQggh7Mmp1R/hphk461afgMbdbR1OpVPmlV5Onz5Nr169OHPmDLm5uURGRuLt7c17771HTk4On376aXnEKYQQQtjUueTLtL20FDTQ2o+WJeXLQZlnSsaMGUPr1q1JSUnB3d3dvP1f//oX69evt2pwQgghhL3Yv/xTArU0LumCqH7PI7YOp1Iq80zJ1q1b2bZtGy4uLhbba9asyZ9//mm1wIQQQgh7kZqZS5PT80GD1DtHEChLypeLMs+UmEwmjEZjke3nzp3D29u6K9rl5+fzf//3f0RERODu7k7t2rV58803MZlM5jZKKSZNmkRYWBju7u506dKFQ4cOWfSTm5vL6NGjCQwMxNPTk3vvvZdz585ZNVYhhBCV19aVC4jQEsnAk9qRT9s6nEqrzEVJZGQkM2bMMD/WNI2MjAzeeOMN+vTpY83YePfdd/n000+ZNWsWR44c4b333uP9998nJibG3Oa9995j2rRpzJo1i927dxMSEkJkZKT5AlyA6Oholi1bxqJFi9i6dSsZGRn069ev2OJKCCGE+KfcfCOhh78A4M+6D6O5+dg4osqrzPNP06dPp2vXrjRq1IicnBwGDRrE8ePHCQwM5JtvvrFqcNu3b+e+++6jb9++ANSqVYtvvvmGPXv2AAWzJDNmzODVV19lwIABAHz55ZcEBwezcOFCRo4cSWpqKnPmzGH+/Pn06FGwFPCCBQsIDw9n3bp19OzZ06oxCyGEqFx+2biKHuoIBpyJ6CuLpZWnMhclYWFhxMfH880337Bv3z5MJhPDhw9n8ODBFhe+WkOHDh349NNPOXbsGHfccQe//vorW7duNc/UJCQkkJSURFRUlPkYV1dXOnfuTFxcHCNHjmTv3r0YDAaLNmFhYTRp0oS4uLgSi5Lc3Fxyc3PNj9PS0gAwGAwYDAar5FfYj7X6sweSk/2rbPmA5OQoHDEnpRT6nbMA+CO4F3W9gizid8ScbqQ8ciptXzd1pY67uzvDhg1j2LBhN3N4qb300kukpqbSoEEDdDodRqORd955h0ceKbjqOSkpCYDg4GCL44KDgzl9+rS5jYuLC35+fkXaFB5fnKlTpzJ58uQi29esWYOHh8ct5XWttWvXWrU/eyA52b/Klg9ITo7CkXI6n5zMU4btoMEpn/YcW7my2HaOlFNpWTOnrKysUrUrc1Hy1VdfXXf/Y489VtYuS/Ttt9+yYMECFi5cSOPGjYmPjyc6OpqwsDCGDh1qbqddc6+4UqrItmvdqM3EiRMZO/bv1frS0tIIDw8nKioKHx/rnE80GAysXbuWyMhI9Hq9Vfq0NcnJ/lW2fEBychSOmNOGGcPQaYo/fNrSY+BTRfY7Yk43Uh45FZ5tuJEyFyVjxoyxeGwwGMjKysLFxQUPDw+rFiUvvvgiL7/8Mg8//DAATZs25fTp00ydOpWhQ4cSEhICFMyGhIaGmo9LTk42z56EhISQl5dHSkqKxWxJcnIy7du3L/G5XV1dcXV1LbJdr9db/RevPPq0NcnJ/lW2fEBychSOktORE6fomLEaNKjSY9x1Y3aUnMrCmjmVtp8y332TkpJi8ZORkcHRo0fp0KGD1S90zcrKwsnJMkSdTme+JTgiIoKQkBCLKaa8vDw2b95sLjhatWqFXq+3aJOYmMjBgwevW5QIIYS4vZ34+SM8tFzOudYlsGmkrcO5LVhl9Zd69erxn//8h0cffZTff//dGl0C0L9/f9555x1q1KhB48aN2b9/P9OmTTNfy6JpGtHR0UyZMoV69epRr149pkyZgoeHB4MGDQLA19eX4cOHM27cOAICAvD392f8+PE0bdrUfDeOEEII8U/nLl6hzcXFoIGSJeUrjNWWpNPpdJw/f95a3QEQExPDa6+9xqhRo0hOTiYsLIyRI0fy+uuvm9tMmDCB7OxsRo0aRUpKCm3atGHNmjUWC7lNnz4dZ2dnBg4cSHZ2Nt27dyc2NhadTmfVeIUQQlQO+5d/Tn8tlcu6QMI7DLZ1OLeNMhclP/74o8VjpRSJiYnMmjWLe+65x2qBAXh7ezNjxgyLxdqupWkakyZNYtKkSSW2cXNzIyYmxmLRNSGEEKI4qVm5NDr1FWiQ0vRJAnSV61oRe1bmouT++++3eKxpGlWrVqVbt258+OGH1opLCCGEsIltP39DH+1PMvGgTq9Rtg7ntlLmouSf3zsjhBBCVCZ5+SaCD34OwLnaA6nv5mvjiG4vZb77RgghhKisftm8hlbqEPnoiOg33tbh3HZKNVPyz0XEbmTatGk3HYwQQghhK0opdDsKlpQ/EdyL+v7hNo7o9lOqomT//v2l6uxGq6gKIYQQ9mrn/ng65m0FDcL6vGjrcG5LpSpKNm7cWN5xCCGEEDZ1dcNMdJrihPfd1KnZwtbh3JbkmhIhhBC3vSMJp+mYXvBle97dXrBxNLevm1o8bffu3Xz//fecOXOGvLw8i31Lly61SmBCCCFERTmxchYNtVz+dKlNtTt72zqc21aZZ0oWLVrEPffcw+HDh1m2bBkGg4HDhw+zYcMGfH3l1ikhhBCO5fylq9yV/B0AxnbPyZLyNlTmomTKlClMnz6d5cuX4+LiwsyZMzly5AgDBw6kRo0a5RGjEEIIUW72rviCYO0qV5wCqNFxiK3Dua2VuSg5ceIEffv2BcDV1ZXMzEw0TeOFF17g888/t3qAQgghRHlJy86jwckvAUhpOgycXWwc0e2tzEWJv78/6enpAFSrVo2DBw8CcPXqVbKysqwbnRBCCFGOtq5aRD3tLFm4E9HzWVuHc9srdVESHx8PQMeOHVm7di0AAwcOZMyYMYwYMYJHHnmE7t27l0uQQgghhLXl5ZuoeuALAM5G/BsnDz8bRyRKffdNy5YtadGiBffffz+PPPIIABMnTkSv17N161YGDBjAa6+9Vm6BCiGEENa09Zd1dFMHyMeJWrKkvF0o9UzJtm3baNmyJR988AF16tTh0UcfZfPmzUyYMIEff/yRadOm4ecnVaYQQgj7p5RC216wpPzJoChcA2raOCIBZShK2rVrxxdffEFSUhKffPIJ586do0ePHtSpU4d33nmHc+fOlWecQgghhNXs+fU3Oub+AkBoL5klsRdlvtDV3d2doUOHsmnTJo4dO8YjjzzCZ599RkREBH369CmPGIUQQgirurR+Bs6aiZPerfCufZetwxF/uaVl5uvUqcPLL7/Mq6++io+PD6tXr7ZWXEIIIUS5OHrqLB3TVgDg3VWWlLcnN12UbN68maFDhxISEsKECRMYMGAA27Zts2ZsQgghhNUdWzkLLy2HRJeaVG3Rz9bhiH8o03ffnD17ltjYWGJjY0lISKB9+/bExMQwcOBAPD09yytGIYQQwioSr6Ry14XvQANDG1lS3t6UuiiJjIxk48aNVK1alccee4xhw4ZRv3798oxNCCGEsKo9y+fQX7tCipMfNToPtXU44hqlLkrc3d1ZsmQJ/fr1Q6fTlWdMQgghhNWlZ+dxx4lY0OBy4yfwc3a1dUjiGqUuSn788cfyjEMIIYQoV1tXL6a3dpps3Kjd63lbhyOKcUt33wghhBCOwGA0EXDgUwDO1HoQJ09Z7NMeSVEihBCi0tu6dSN3m37FiBO1+spiafZKihIhhBCVmlIK07YYAE4Edse1aoSNIxIlsfui5M8//+TRRx8lICAADw8P7rzzTvbu3Wver5Ri0qRJhIWF4e7uTpcuXTh06JBFH7m5uYwePZrAwEA8PT259957ZVl8IYS4Tew9cJBOuVsACOk9wcbRiOux66IkJSWFe+65B71ez88//8zhw4f58MMPqVKlirnNe++9x7Rp05g1axa7d+8mJCSEyMhI0tPTzW2io6NZtmwZixYtYuvWrWRkZNCvXz+MRqMNshJCCFGRktd/hF4zkuDVAp86d9s6HHEdZVo8raK9++67hIeHM2/ePPO2WrVqmf+tlGLGjBm8+uqrDBgwAIAvv/yS4OBgFi5cyMiRI0lNTWXOnDnMnz+fHj16ALBgwQLCw8NZt24dPXv2rNCchBBCVJzjZ87TIfUn0MCzS7StwxE3YNdFyY8//kjPnj3597//zebNm6lWrRqjRo1ixIgRACQkJJCUlERUVJT5GFdXVzp37kxcXBwjR45k7969GAwGizZhYWE0adKEuLi4EouS3NxccnNzzY/T0tIAMBgMGAwGq+RX2I+1+rMHkpP9q2z5gOTkKGyR0+EVMdTTsknU1yCwWW+rP7eMU9n6vBG7LkpOnjzJJ598wtixY3nllVfYtWsXzz//PK6urjz22GMkJSUBEBwcbHFccHAwp0+fBiApKQkXFxf8/PyKtCk8vjhTp05l8uTJRbavWbMGDw+PW03Nwtq1a63anz2QnOxfZcsHJCdHUVE5peXm0z3pW9DgUJUeZP68qtyeS8bp+rKyskrVzq6LEpPJROvWrZkyZQoALVq04NChQ3zyySc89thj5nbaNd9doJQqsu1aN2ozceJExo4da36clpZGeHg4UVFR+Pj43Ew6RRgMBtauXUtkZCR6vd4qfdqa5GT/Kls+IDk5iorO6edvZhGmXeaqVoXOw94EZzerP4eMU+kUnm24EbsuSkJDQ2nUqJHFtoYNG7JkyRIAQkJCgILZkNDQUHOb5ORk8+xJSEgIeXl5pKSkWMyWJCcn0759+xKf29XVFVfXoksQ6/V6q//ilUeftiY52b/Klg9ITo6iInLKyDFQ7+SXAFxsNJQq7t7l+nwyTjfuqzTs+u6be+65h6NHj1psO3bsGDVr1gQgIiKCkJAQiymmvLw8Nm/ebC44WrVqhV6vt2iTmJjIwYMHr1uUCCGEcFy/rFlCQxLIxpU6vcfYOhxRSnY9U/LCCy/Qvn17pkyZwsCBA9m1axeff/45n3/+OVBw2iY6OpopU6ZQr1496tWrx5QpU/Dw8GDQoEEA+Pr6Mnz4cMaNG0dAQAD+/v6MHz+epk2bmu/GEUIIUXnkG01Uif9rSfmaA6jvFWDjiERp2XVRctddd7Fs2TImTpzIm2++SUREBDNmzGDw4MHmNhMmTCA7O5tRo0aRkpJCmzZtWLNmDd7ef0/VTZ8+HWdnZwYOHEh2djbdu3cnNjZWvu1YCCEqoa1xW+hi2i9Lyjsguy5KAPr160e/fv1K3K9pGpMmTWLSpEkltnFzcyMmJoaYmJhyiFAIIYS9UEqRv/WvJeUDunJHUF0bRyTKwq6vKRFCCCHKYt+hI3TK2QhAcC+ZJXE0UpQIIYSoNJLWzsRFM3LKsxm+9eRmBkcjRYkQQohK4Y+ziXS4+iMA7p2jbRuMuClSlAghhKgUDq+Yja+WxQV9NYJb/8vW4YibIEWJEEIIh5ecmkHLxIUA5LQeBU7y8eaIZNSEEEI4vJ3LY6muXSJV86Fmt+G2DkfcJClKhBBCOLSsXAO1j88BILnhY6B3t3FE4mZJUSKEEMKhbVn7A405SS4u1O7zgq3DEbdAihIhhBAOy2hS+Oz7BIBT4fej8wq0cUTiVkhRIoQQwmFtjdtKe9NeTGjU7PuircMRt0iKEiGEEA5JKUXeLx8BcMK/M24hd9g4InGrpCgRQgjhkOKPHKNTzgYAqvaUJeUrAylKhBBCOKQ/V8/EVcvntEcTqtTvaOtwhBVIUSKEEMLhnDyfTIerPwDg2mmMbYMRViNFiRBCCIdzcPlsqmiZJDuHEXL3A7YOR1iJFCVCCCEcyqW0LFr8+TUAWa2eBiedjSMS1iJFiRBCCIeyfXks4VoyaZoPNbs/aetwhBVJUSKEEMJhZOfmU+tYwZLySfUfRXPxtHFEwpqkKBFCCOEwtqz/kab8QS566vSVJeUrGylKhBBCOASjSeG5968l5avfi847yMYRCWuTokQIIYRDiNsZRwfjLgBqyJLylZIUJUIIIRxC9uYYAP7w64R7aEMbRyPKgxQlQggh7N6vvx+jc/Y6AAKixtk4GlFepCgRQghh986s+ghXzcAZ94b4Nehs63BEOZGiRAghhF1LOH+Re1KWAaDvOAY0zcYRifIiRYkQQgi7dmDFJ/hrGVx0DiG0zb9tHY4oRw5VlEydOhVN04iOjjZvU0oxadIkwsLCcHd3p0uXLhw6dMjiuNzcXEaPHk1gYCCenp7ce++9nDt3roKjF0IIUVaX07Jofq5gSfmMFiNB52zjiER5cpiiZPfu3Xz++ec0a9bMYvt7773HtGnTmDVrFrt37yYkJITIyEjS09PNbaKjo1m2bBmLFi1i69atZGRk0K9fP4xGY0WnIYQQogziVn5FLS2JdM2LWj2esnU4opw5RFGSkZHB4MGD+eKLL/Dz8zNvV0oxY8YMXn31VQYMGECTJk348ssvycrKYuHChQCkpqYyZ84cPvzwQ3r06EGLFi1YsGABv/32G+vWrbNVSkIIIW4gx2Ckxu8FS8on3jEYzdXLxhGJ8uYQ82DPPvssffv2pUePHrz99tvm7QkJCSQlJREVFWXe5urqSufOnYmLi2PkyJHs3bsXg8Fg0SYsLIwmTZoQFxdHz549i33O3NxccnNzzY/T0tIAMBgMGAwGq+RV2I+1+rMHkpP9q2z5gOTkKMqa08a1P9GbY+ThTHjkc3b5Wsg4la3PG7H7omTRokXs27eP3bt3F9mXlJQEQHBwsMX24OBgTp8+bW7j4uJiMcNS2Kbw+OJMnTqVyZMnF9m+Zs0aPDw8ypzH9axdu9aq/dkDycn+VbZ8QHJyFKXJyaSgSvzHAOxzv4cL2/YD+8s5spt3u45TaWVlZZWqnV0XJWfPnmXMmDGsWbMGNze3Ettp19weppQqsu1aN2ozceJExo4da36clpZGeHg4UVFR+Pj4lDKD6zMYDKxdu5bIyEj0er1V+rQ1ycn+VbZ8QHJyFGXJaduuXXRSe0GDhg+9SatqjSsoyrK53ceptArPNtyIXRcle/fuJTk5mVatWpm3GY1GtmzZwqxZszh69ChQMBsSGhpqbpOcnGyePQkJCSEvL4+UlBSL2ZLk5GTat29f4nO7urri6upaZLter7f6L1559GlrkpP9q2z5gOTkKEqTU87Wj3HSFH9UuYe6te6smMBuwe06TmXpqzTs+kLX7t2789tvvxEfH2/+ad26NYMHDyY+Pp7atWsTEhJiMcWUl5fH5s2bzQVHq1at0Ov1Fm0SExM5ePDgdYsSIYQQtvHr0T/okrUGAP9IWVL+dmLXMyXe3t40adLEYpunpycBAQHm7dHR0UyZMoV69epRr149pkyZgoeHB4MGDQLA19eX4cOHM27cOAICAvD392f8+PE0bdqUHj16VHhOQgghru/M6hiaawbOutUnvFE3W4cjKpBdFyWlMWHCBLKzsxk1ahQpKSm0adOGNWvW4O3tbW4zffp0nJ2dGThwINnZ2XTv3p3Y2Fh0Op0NIxdCCHGtMxcu0e7yUtDAucPzsqT8bcbhipJNmzZZPNY0jUmTJjFp0qQSj3FzcyMmJoaYmJjyDU4IIcQt2b/8M+7T0rikCya03cO2DkdUMLu+pkQIIcTtIyUjh2Zn5gOQ3mKELCl/G5KiRAghhF3YtnI+EVoiGZontXqMtHU4wgakKBFCCGFzOQYj1Q7/F4DzdR9Bc7POelDCsUhRIoQQwua2bFhJC37HgDMRfcfe+ABRKUlRIoQQwqZMJoXr7tkAJIT2QV+lmo0jErYiRYkQQgib2r5nDx0M2wGo3neCjaMRtiRFiRBCCJtK2/QROk1xwrctHtWb2jocYUNSlAghhLCZ344n0DlzNQB+PWRJ+dudFCVCCCFsJmFVDB5aLufc6uLfJNLW4Qgbk6JECCGETZy5cIV2lxYDoLWXJeWFFCVCCCFsJH7FZ1TVUrmkq0q1ewbZOhxhB6QoEUIIUeGuZubQ+PRXAKQ1fxJ0ehtHJOyBFCVCCCEq3NafF1JHO08mHkREPWPrcISdkKJECCFEhcrNNxF6sGBJ+T/rPoTm5mvjiIS9kKJECCFEhdq6ZS2tOEQ+OiL6ym3A4m9SlAghhKgwJgWuuz8B4GRIL/R+4TaOSNgTKUqEEEKUO6NJsTPhCnEJl+lk2AZAWO8XbRyVsDfOtg5ACCFEJbZxKscvZvHYiS4kpubwuvNqdM6KbaoZQTuXUu/kKug60dZRCjshMyVCCCHKzfGLWdQ7/BEPZizEhwwe0m0EINHoS73DH3H8YpaNIxT2RGZKhBBClAujSfHYiS48aDjPOP1i7nb6HU8tl4smHx50/oVphgf5/kQXtpoUOidZzVXITIkQQohysivhCompOcwx9mG98U466g4CUNUpjQ8ND/KRcQCJqTnsSrhi40iFvZCZEiGEEFZ3MT2X/23ZxcvOC3lEtwFf7e/TNHnKmRjjAPPj5PQcW4Qo7JAUJUIIIazm8Pk01q1dQZ0TX/K2thNnZxMAKSZP/JwyyVPOuGj5jNYtNRcmQd5utgxZ2BEpSoQQQtwSk0mx8fB5flv/NR0vf8fzTsfNFwfsojHn83253zmODw0PEmMcwGjdUsbpF6MB33sN4u4If5vGL+yHFCVCCCFuSmZuPv/bcYSr2/7LvbnL6a5dAifIx5nUuvcR0D0av1++5+7DHzHtr4IEIMY4AA0Yq19M/zph6Jy62zYRYTekKBFCCFEmf17N5scNW/E5MIf71Ea8tBzQIMu5CvmtnsCnwzMEeAcDUK/qCo43ep7vT3SB1L+vHfneaxD964RRr6qHjbIQ9kiKEiGEEKWy7/QVNq/9H43PLGCkthcnTYEGVz1r497peTxaPgx6d8uDuk6kHrDVpNj+RzJrftlJVMc2tKsbJDMkogi7viV46tSp3HXXXXh7exMUFMT999/P0aNHLdoopZg0aRJhYWG4u7vTpUsXDh06ZNEmNzeX0aNHExgYiKenJ/feey/nzp2ryFSEEMIh5RtNLN9/ihnT3kI/pysvnIsmymkPTpriUkhHTIOXUmX8PlzbPFG0IPkHnZNGmwh/WgUq2kT4y7okolh2XZRs3ryZZ599lh07drB27Vry8/OJiooiMzPT3Oa9995j2rRpzJo1i927dxMSEkJkZCTp6enmNtHR0SxbtoxFixaxdetWMjIy6NevH0aj0RZpCSGE3UvNNhC7bi//nfIsrX/oQnTaBzR1OoVBcyGlwWAYtZPAp5fjVK87aFJgCOuw69M3q1atsng8b948goKC2Lt3L506dUIpxYwZM3j11VcZMKDgAqovv/yS4OBgFi5cyMiRI0lNTWXOnDnMnz+fHj16ALBgwQLCw8NZt24dPXv2rPC8hBDCXiVcyuSn9ZsIPjyXh9iCu5YHGmToA9HuHoFn+xH4eQbYOkxRSdl1UXKt1NRUAPz9C24fS0hIICkpiaioKHMbV1dXOnfuTFxcHCNHjmTv3r0YDAaLNmFhYTRp0oS4uLgSi5Lc3Fxyc3PNj9PS0gAwGAwYDAar5FPYj7X6sweSk/2rbPmA5HSrlFLsOHmZXRt+oFXiNzyv+xX+mvy44tMAj47P4dp0AOhcMBQEdVPPI+PkGMojp9L2pSmllNWetRwppbjvvvtISUnhl19+ASAuLo577rmHP//8k7CwMHPbp556itOnT7N69WoWLlzIE088YVFgAERFRREREcFnn31W7PNNmjSJyZMnF9m+cOFCPDzkanEhhOPLN8GvFw24J+7gX8ZVNHA6C4AJjRMeLUgK68UVr/pyekbcsqysLAYNGkRqaio+Pj4ltnOYmZLnnnuOAwcOsHXr1iL7tGveMEqpItuudaM2EydOZOzYsebHaWlphIeHExUVdd0XtCwMBgNr164lMjISvV5vlT5tTXKyf5UtH5CcyupyRi4/bP0Vp/h5PG9aTaCWBk6Q6+ROVqOH8Oo4ilr+tall1WeVcXIU5ZFT4dmGG3GIomT06NH8+OOPbNmyherVq5u3h4SEAJCUlERoaKh5e3JyMsHBweY2eXl5pKSk4OfnZ9Gmffv2JT6nq6srrq6uRbbr9Xqr/+KVR5+2JjnZv8qWD0hON/J7Uhor162j5rFYntC24arlgwbpriE4t3sa9zZP4OpexSrPdT0yTo7BmjmVth+7vvtGKcVzzz3H0qVL2bBhAxERERb7IyIiCAkJYe3ateZteXl5bN682VxwtGrVCr1eb9EmMTGRgwcPXrcoEUKIysBkUmw4ksgHMTO4/HEvxv7xBA84bcZVy+eKX3PyB8zFe8Ih3Lu8ABVQkAhxPXY9U/Lss8+ycOFC/ve//+Ht7U1SUhIAvr6+uLu7o2ka0dHRTJkyhXr16lGvXj2mTJmCh4cHgwYNMrcdPnw448aNIyAgAH9/f8aPH0/Tpk3Nd+MIIURlk5WXz/92HuPC1lj6Z/9IN6dE0IERJ1Jr9cavezT+4XfbOkwhLNh1UfLJJ58A0KVLF4vt8+bN4/HHHwdgwoQJZGdnM2rUKFJSUmjTpg1r1qzB29vb3H769Ok4OzszcOBAsrOz6d69O7Gxseh0uopKRQghKkRiajZLN+7CPX4OA9Q6qmiZ4AQ5Oi8MzYfg3elZ/KuE2zpMIYpl10VJaW4M0jSNSZMmMWnSpBLbuLm5ERMTQ0xMjBWjE0II+xF/9ipr1/5M/YSveMppJ3rNCBqkuYfj2mEUbq2H4ObqfeOOhLAhuy5KhBBClCzfaGL1wfMc3rCQLinf86LTMfhrAvhK1bvx7TYGn/q9wUlmhYVjkKJECCEcTGq2gWXbj5AWN5d/5S2nr9NFcIJ8nEmvey9+3cbgH3anrcMUosykKBFCCAdx+nImyzbE4X9wLg+wEW8tG5wg29kXU6sn8Lznafx8Qm/ckRB2SooSIYSwY0opdpy4xOb1P9Hs7NeMdtqDTiu43i7VqzYeHZ/DvcUj4CIrTQvHJ0WJEELYodx8E3uSjRyd+R96pi/jJaeT5utFUkI7UKVbNL51uoOTXS83JUSZSFEihBB25HJGLou3/oZh11xGGX8mVLsCTmDQXMhq8AC+XcfgF9TQ1mEKUS6kKBFCCDtwNCmdnzZsJuz3WIZoW/DQckGDTL0/Tnc/hXv7Efh6Bto6TCHKlRQlQghhIyaTYvOxZHasX8bdSYsYr9tv/vKPqz71+cO3E80HTULv7mXbQIWoIFKUCCFEBcvOM7Js9wnO/fIV/bP+x0SnM6ADExqp4d2o0nUMntXb8efPP9PcuegXgwpRWUlRIoQQFSQpNYfFW/ah2zePB02rqKqlgRPkObmR2+QRvDuPxi+gTkFjg8G2wQphA1KUCCFEOTtw7ior162nzomvGOG0DVfNABpkuAajbzcS1zbDcHH3s3WYQticFCVCCFEOjCbFmoPn2b/xezpe+p6XdQfNt/Re9WuGT9cxeDW+D3R62wYqhB2RokQIIawoPcfA4h3HuLTtSwbk/khvp8S/rhdxIj2iF75do6kSfjdomq1DFcLuSFEihBBWcOZyFos37cL7wDweZB1+WgY4Qa7Ok/w7h+DZYRS+fjVtHaYQdk2KEhsxmhQ7E66w95JGQMIV2tUNQuck/+UkhCNRSrEr4QrrNqym8ekFjHbagV4zApDhXg2Xe57F9a7HcHX1tnGkQjgGKUoq2sapHL+YxWMnupCYmgPo+Or4HkJ93fiqzibqVfWArhNtHaUQ4jry8k2sOHCWwxsW0SNtKa86/f739SJV78K36/N4NegLTjrbBiqEg5GipIIdv5hFvcMf8aDhPDEMMG//d8ZC6h1ezPFGz1PPhvEJIUp2JTOP77cdJmNHLA/mr+BfTsngBEZ0ZNa7F5+uY6gS1sLWYQrhsKQoqUBGk+KxE1140HCecfrFNNJO842pGz2c9vKY8zqmGx7guxNd2GpScipHCDvyR3I6SzZsp+rhWB7RNuCjZYMT5Dj7olo/gXv7kfj4hNk6TCEcnhQlFWhXwhUSU3OIYQDeZPOUfgW92W3e/7zzUgbnrOfk237kuAaS61YVk0dVNO9gXKqE4uEfhk9gNfyDq6P3qCJX7wtRjpRSbDl2kc0bVtDq/ELGO+1G56QASPeqjXvH53Br8Qi4eNg4UiEqDylKKlByeo7531+ZInlSrcRJUygFCg2dpgjiKkGmq5CdANlASvF95aLnquZHut6fHNdADO5VwTMInW8Ibn5heAeEUSWoOu5+oaB3r5D8hKgMcgxGlu05xcktC+mbuYzXnU6YrxdJDe2AT9cxeNftAU5Otg1UiEpIipIKFOTtZv73v5y24qQpcpUzrlo+MwwDWGjsRpCWyshWnlTV0jClXYDMC+izL+Kedxmf/Cv4mVLw0bJwxUCwSiY4LxnygPSSnzcDT1J1fmS5BJDnVhWTZ1WcvIPR+4biERCGb2AYXgHV0Dyrgk5+JcTtKTkth29/+Q3jnlgGmlbyiHYFnCBfcyGn4YN4dR6Nb3AjW4cpRKUmn0AV6O4If0J93fh3xkLG6hfzoeFBYowDGK1byjj9YhQa33sNou+AbiVeU2IyKa6kpZGSfI60S3+SfSURQ2oiKv0CuqyLuOVewtNwGV9jCoFcxVUz4EUmXsZMyD533dkXExppmq959iXfvSp4BeHsG4pblVC8AsLwqVodnU8wuFWR00eiUjj4Zyr/2/ALNY59yXCnzXhouaBBtt4frc0I3NqOwMurqq3DFOK2IEVJBdI5aQW3/R5ezLS/ChKAGOMANGCsfjH964Shc+peYh9OThr+VXzxr+ILdzS+7vNl5BhIvJTM1YvnybzyJ7kpiRjTLqBlJqPPTsY99zI+xiv4q6sEkIpOU1RRV6mSdxXyThbMviQX37cBZ1J1/tfMvoTg7BOE18XLGE75ow+oDl7Bcs5d2B2jSbHucBI7NvyP9he/ZaLTfpx0BdeLpPnWx7Pz87g3+zfIN/QKUaGkKKlg9ap6cLzR83x/oguk/n2Nyfdeg+hfJ6xgnRIr8XLT41W9GlSvBtxVYrvcfCOJqVlcuZRI+sXzZKf8iSE1CZWejC4r2Tz7UsWYQlXtKr5aFnryCTQmQ3YyZB+xmH2pBfD1R+bH2ZrHNbMvwTj7BuNeJQyvwGoF1714BYOcPhLlLCM3n8U7T3B+6wLuz/kfPZ1O/329SHh3fLuOwSeik8wCCmEj8glQ0bpOpB6w1aTY/kcya37ZSVTHNn+t6FryDEl5cnXWUT3Am+oB3lD/jhLbGU2Kyxm5HEpJ5eql82RdOf+P2ZcL6HMu4ZF7Ce/8KwRylSDtKm6aAXeVhXteFuSdu+7siwmNTJ0vWfoA8twDMXkG4+QdjEuVEDz9w/D0D0PzDi4oYNz9KuSDQ1betX+lGaOzV7L4bvN+XONjeYjVVNVSwQnynNwwNH0Yz46j8Q2sa6MMhBCFpCixEZ2TRpsIfy4fUbSJ8HeIDzqdk0aQjxtBPm5QMxgoukiUwWBgxYqVhHeN5Ex2PpevXCb90p9kp5zHcDUJMpPRZRbOvlzBXxXMvgSQhrNmwtt4FW/jVcg5UeK1LwD5OJOh9yfHNQCje9Bf176E4O4XhmdAGDqfEPAK+uv0kWfZk5WVdx3CqoOJTP7pcJExeqN/I3o2DmHP6RR+Xr+BO04t4DmnrbhqBgAyXYPQt38al7uewMXD37ZJCCHMbquiZPbs2bz//vskJibSuHFjZsyYQceOHW0dVqWjaVDFQ09VXw8I8QEiSmyblZdPclou+9KyuXo5iczL58m9mogxLQmnzGRcsi/hnncJ379OHVXVUvHTMnAmnyqGZDAkQ8YRuFhyPDlO7mSbr30Jwsk7GNcqoXj6h6L3Df27ePGsCs4ugKy86wj++PYVDh+4QKJxgMX2pNQcDn/zKk5uF3HLS+F13W/mUzRp/s3w6vI8no3vB52+4oMWQlzXbVOUfPvtt0RHRzN79mzuuecePvvsM3r37s3hw4epUaOGrcO7bXm4OFMr0JlagZ5QOxBoUmy7vHwTlzJyOZ2ey56UNNIvJ5Kdcp78tCT4x51HXn+dOgoklSDtKh5aLm6mbNxyzkHOObh6/XiynH3JcQ3kcqYHBlMNxukXc5fTUTaa7qSD029018Wz1tiS3ccMjNv9JZqTM2hOaE66gnUrtMLHTuCkQ9OcQNOBkzM4OZkfazrd38dpuoLvSDG31RVUduZ//7XP3Mbp7+0Wx90+62YYTYoNxy4zVr8YBeaLxt3IJUYfQ6RuHxgBHZhwIrN2L7y7jMEnvI1cLyKEHbttipJp06YxfPhwnnzySQBmzJjB6tWr+eSTT5g6daqNoxM34uLsRFgVd8KquEN4FaD4QtJoUlzJzCM5PYdd6blcSUn569qX8xjTL+CUmYw++yIeeZfxV1fNsy+BpKLXjHjkp+KRn0pbgL8+4zvpfqOT7jfzc0Tq9hGZvw9WlHfWZWdUGkacMP3j5+/HmvlxazQu7B9n0a64tsXtV9rf/agS9pnQFdOHhtJ0fx2n/dX+H/v/+rf6x+O/2+nM+4w4kWuEK9l+rHC6m3H6xdTTznGaEIbrVuKh5QGQrty5fMdAavUZi7dfLdsOjBCiVG6LoiQvL4+9e/fy8ssvW2yPiooiLi6u2GNyc3PJzc01P05LSwMKrpkwGAxWiauwH2v1Zw/sIacqbk5UcfPgjqoegB9Qu0gbpRTpOfkkp+dyPCOXbWk5pKdcJPdqIkl/nubqxfPmgmW4biU6TWFUGmtMrf/6uFXozB+9f/1bK/x4LXjsZP54VuaPaad/fGQ7adduV8X+2/xxrKkb5q7TFDqMFEwTlJPrhXHjEK3H5e9/3uu8w/zvqyYPPjI+wHfGzrzZoA3VvELBAd9j9vBesjbJyTGUR06l7eu2KEouXbqE0WgkODjYYntwcDBJSUnFHjN16lQmT55cZPuaNWvw8LDuuhtr1661an/2wNFy0gP+AK6QEVCT2AsFhcxo3VJ0/1h597CppvlUwVMNjNTxUeYP4sLP439+LqtrPqSv/cxWpW2nCv5H+6sIQhXMQxT8v0JTf/3b3MZUsA2Fk7ntX+3+2ld4XGGf5n+rgrZO5j7+0Y/6+/md/np+JxRgwumvtk7q7/i0fz4//4hPFbb/+3k0/t6nXdNW+6tdYb95+YqL2cpc9LVxOoKTpjAoHS3zPsf01zTXyUPxrDy3vzS/AnbL0d5LpSE5OQZr5pSVlVWqdrdFUVJIu+ZcslKqyLZCEydOZOzYsebHaWlphIeHExUVhY+Pj1XiMRgMrF27lsjISPT6ynHRXWXIyWhSLP5wCwMzvyl25V0N+N7rEcY+0skh7pq6VmUZoyc+3MKFtFye0y2lne6wuXB8VvcDs4wDCPF15bmHHHOMoHKM07UkJ8dQHjkVnm24kduiKAkMDESn0xWZFUlOTi4ye1LI1dUVV9eiqznq9Xqr/+KVR5+25sg56YH5dTffcOVdN9ceNo3zVjn6GE26tzGHv/m/EgvHRv3fxs3V5UZd2T1HHqeSSE6OwZo5lbaf2+JyfRcXF1q1alVkKmrt2rW0b9/eRlEJe2ZeeddrkMX2770GFdwObMWVd8XN6XV5PmP1i/lc97BF4fi57mHG6hfT6/J8G0cohCir22KmBGDs2LEMGTKE1q1b065dOz7//HPOnDnD008/bevQhD2yw5V3xTVMRuj6KsM7vkgjizHqA7/UKdgvhHAot01R8tBDD3H58mXefPNNEhMTadKkCStXrqRmzZq2Dk3YMUdcefe28deKujooOkadJ9g2NiHETbltihKAUaNGMWrUKFuHIYQQQohi3BbXlAghhBDC/klRIoQQQgi7IEWJEEIIIeyCFCVCCCGEsAtSlAghhBDCLkhRIoQQQgi7cFvdEnwr1F/fmFba9ftLw2AwkJWVRVpaWqVZnlhysn+VLR+QnByF5OQYyiOnws9Ode23j15DipJSSk9PByA8PNzGkQghhBCOKT09HV9f3xL3a+pGZYsAwGQycf78eby9vUv8ZuGyKvzm4bNnz1rtm4dtTXKyf5UtH5CcHIXk5BjKIyelFOnp6YSFheHkVPKVIzJTUkpOTk5Ur169XPr28fGpNL/MhSQn+1fZ8gHJyVFITo7B2jldb4akkFzoKoQQQgi7IEWJEEIIIeyCFCU25OrqyhtvvIGrq6utQ7Eaycn+VbZ8QHJyFJKTY7BlTnKhqxBCCCHsgsyUCCGEEMIuSFEihBBCCLsgRYkQQggh7IIUJUIIIYSwC1KUlLPZs2cTERGBm5sbrVq14pdffrlu+82bN9OqVSvc3NyoXbs2n376aQVFWnplyWnTpk1omlbk5/fff6/AiEu2ZcsW+vfvT1hYGJqm8cMPP9zwGHsfo7LmZO9jNHXqVO666y68vb0JCgri/vvv5+jRozc8zp7H6WZysvdx+uSTT2jWrJl5wa127drx888/X/cYex4jKHtO9j5G15o6dSqaphEdHX3ddhU5TlKUlKNvv/2W6OhoXn31Vfbv30/Hjh3p3bs3Z86cKbZ9QkICffr0oWPHjuzfv59XXnmF559/niVLllRw5CUra06Fjh49SmJiovmnXr16FRTx9WVmZtK8eXNmzZpVqvaOMEZlzamQvY7R5s2befbZZ9mxYwdr164lPz+fqKgoMjMzSzzG3sfpZnIqZK/jVL16df7zn/+wZ88e9uzZQ7du3bjvvvs4dOhQse3tfYyg7DkVstcx+qfdu3fz+eef06xZs+u2q/BxUqLc3H333erpp5+22NagQQP18ssvF9t+woQJqkGDBhbbRo4cqdq2bVtuMZZVWXPauHGjAlRKSkoFRHdrALVs2bLrtnGEMfqn0uTkSGOklFLJyckKUJs3by6xjaONU2lycrRxUkopPz8/9d///rfYfY42RoWul5OjjFF6erqqV6+eWrt2rercubMaM2ZMiW0repxkpqSc5OXlsXfvXqKioiy2R0VFERcXV+wx27dvL9K+Z8+e7NmzB4PBUG6xltbN5FSoRYsWhIaG0r17dzZu3FieYZYrex+jW+EoY5SamgqAv79/iW0cbZxKk1MhRxgno9HIokWLyMzMpF27dsW2cbQxKk1Ohex9jJ599ln69u1Ljx49bti2osdJipJycunSJYxGI8HBwRbbg4ODSUpKKvaYpKSkYtvn5+dz6dKlcou1tG4mp9DQUD7//HOWLFnC0qVLqV+/Pt27d2fLli0VEbLV2fsY3QxHGiOlFGPHjqVDhw40adKkxHaONE6lzckRxum3337Dy8sLV1dXnn76aZYtW0ajRo2KbesoY1SWnBxhjBYtWsS+ffuYOnVqqdpX9DjJtwSXM03TLB4rpYpsu1H74rbbUllyql+/PvXr1zc/bteuHWfPnuWDDz6gU6dO5RpneXGEMSoLRxqj5557jgMHDrB169YbtnWUcSptTo4wTvXr1yc+Pp6rV6+yZMkShg4dyubNm0v8EHeEMSpLTvY+RmfPnmXMmDGsWbMGNze3Uh9XkeMkMyXlJDAwEJ1OV2QGITk5uUjVWSgkJKTY9s7OzgQEBJRbrKV1MzkVp23bthw/ftza4VUIex8ja7HHMRo9ejQ//vgjGzdupHr16tdt6yjjVJacimNv4+Ti4kLdunVp3bo1U6dOpXnz5sycObPYto4yRmXJqTj2NEZ79+4lOTmZVq1a4ezsjLOzM5s3b+ajjz7C2dkZo9FY5JiKHicpSsqJi4sLrVq1Yu3atRbb165dS/v27Ys9pl27dkXar1mzhtatW6PX68st1tK6mZyKs3//fkJDQ60dXoWw9zGyFnsaI6UUzz33HEuXLmXDhg1ERETc8Bh7H6ebyak49jROxVFKkZubW+w+ex+jklwvp+LY0xh1796d3377jfj4ePNP69atGTx4MPHx8eh0uiLHVPg4lcvls0IppdSiRYuUXq9Xc+bMUYcPH1bR0dHK09NTnTp1Siml1Msvv6yGDBlibn/y5Enl4eGhXnjhBXX48GE1Z84cpdfr1eLFi22VQhFlzWn69Olq2bJl6tixY+rgwYPq5ZdfVoBasmSJrVKwkJ6ervbv36/279+vADVt2jS1f/9+dfr0aaWUY45RWXOy9zF65plnlK+vr9q0aZNKTEw0/2RlZZnbONo43UxO9j5OEydOVFu2bFEJCQnqwIED6pVXXlFOTk5qzZo1SinHGyOlyp6TvY9Rca69+8bW4yRFSTn7+OOPVc2aNZWLi4tq2bKlxS1/Q4cOVZ07d7Zov2nTJtWiRQvl4uKiatWqpT755JMKjvjGypLTu+++q+rUqaPc3NyUn5+f6tChg1qxYoUNoi5e4S181/4MHTpUKeWYY1TWnOx9jIrLBVDz5s0zt3G0cbqZnOx9nIYNG2b+u1C1alXVvXt384e3Uo43RkqVPSd7H6PiXFuU2HqcNKX+umJFCCGEEMKG5JoSIYQQQtgFKUqEEEIIYRekKBFCCCGEXZCiRAghhBB2QYoSIYQQQtgFKUqEEEIIYRekKBFCCCGEXZCiRAghhBB2QYoSIYRD0TSNH374wdZhMGnSJO68805bhyFEpSJFiRDCQnJyMiNHjqRGjRq4uroSEhJCz5492b59u61Ds4pTp06haRrx8fG2DkUIcQ1nWwcghLAvDzzwAAaDgS+//JLatWtz4cIF1q9fz5UrV2wdmhCikpOZEiGE2dWrV9m6dSvvvvsuXbt2pWbNmtx9991MnDiRvn37mttNmzaNpk2b4unpSXh4OKNGjSIjI8O8PzY2lipVqrB8+XLq16+Ph4cHDz74IJmZmXz55ZfUqlULPz8/Ro8ejdFoNB9Xq1Yt3nrrLQYNGoSXlxdhYWHExMRcN+Y///yThx56CD8/PwICArjvvvs4depUqXPetGkTmqaxfv16WrdujYeHB+3bt+fo0aMW7f7zn/8QHByMt7c3w4cPJycnp0hf8+bNo2HDhri5udGgQQNmz55t3jds2DCaNWtm/tp7g8FAq1atGDx4cKljFaLSK7ev+hNCOByDwaC8vLxUdHS0ysnJKbHd9OnT1YYNG9TJkyfV+vXrVf369dUzzzxj3j9v3jyl1+tVZGSk2rdvn9q8ebMKCAhQUVFRauDAgerQoUPqp59+Ui4uLmrRokXm42rWrKm8vb3V1KlT1dGjR9VHH32kdDqdxTezAmrZsmVKKaUyMzNVvXr11LBhw9SBAwfU4cOH1aBBg1T9+vVVbm5usbEnJCQoQO3fv18p9fe3Krdp00Zt2rRJHTp0SHXs2FG1b9/efMy3336rXFxc1BdffKF+//139eqrrypvb2/VvHlzc5vPP/9chYaGqiVLlqiTJ0+qJUuWKH9/fxUbG6uUUio9PV3Vrl1bRUdHK6WUeumll1SNGjXU1atXSzc4QtwGpCgRQlhYvHix8vPzU25ubqp9+/Zq4sSJ6tdff73uMd99950KCAgwP543b54C1B9//GHeNnLkSOXh4aHS09PN23r27KlGjhxpflyzZk3Vq1cvi74feugh1bt3b/PjfxYlc+bMUfXr11cmk8m8Pzc3V7m7u6vVq1cXG2tJRcm6devMbVasWKEAlZ2drZRSql27durpp5+26KdNmzYWRUl4eLhauHChRZu33npLtWvXzvw4Li5O6fV69dprrylnZ2e1efPmYmMU4nYlp2+EEBYeeOABzp8/z48//kjPnj3ZtGkTLVu2JDY21txm48aNREZGUq1aNby9vXnssce4fPkymZmZ5jYeHh7UqVPH/Dg4OJhatWrh5eVlsS05Odni+du1a1fk8ZEjR4qNde/evfzxxx94e3vj5eWFl5cX/v7+5OTkcOLEiTLl3axZM/O/Q0NDAcyxHTlypNi4Cl28eJGzZ88yfPhwcxxeXl68/fbbFnG0a9eO8ePH89ZbbzFu3Dg6depUphiFqOzkQlchRBFubm5ERkYSGRnJ66+/zpNPPskbb7zB448/zunTp+nTpw9PP/00b731Fv7+/mzdupXhw4djMBjMfej1eos+NU0rdpvJZLphPJqmFbvdZDLRqlUrvv766yL7qlatWppUzf4ZW+HzlSa2f7b74osvaNOmjcU+nU5n0W7btm3odDqOHz9epviEuB3ITIkQ4oYaNWpkngXZs2cP+fn5fPjhh7Rt25Y77riD8+fPW+25duzYUeRxgwYNim3bsmVLjh8/TlBQEHXr1rX48fX1tVpMDRs2LDauQsHBwVSrVo2TJ08WiSMiIsLc7v333+fIkSNs3ryZ1atXM2/ePKvFKERlIEWJEMLs8uXLdOvWjQULFnDgwAESEhL4/vvvee+997jvvvsAqFOnDvn5+cTExHDy5Enmz5/Pp59+arUYtm3bxnvvvcexY8f4+OOP+f777xkzZkyxbQcPHkxgYCD33Xcfv/zyCwkJCWzevJkxY8Zw7tw5q8U0ZswY5s6dy9y5czl27BhvvPEGhw4dsmgzadIkpk6dysyZMzl27Bi//fYb8+bNY9q0aQDEx8fz+uuvM2fOHO655x5mzpzJmDFjOHnypNXiFMLRSVEihDDz8vKiTZs2TJ8+nU6dOtGkSRNee+01RowYwaxZswC48847mTZtGu+++y5NmjTh66+/ZurUqVaLYdy4cezdu5cWLVrw1ltv8eGHH9KzZ89i23p4eLBlyxZq1KjBgAEDaNiwIcOGDSM7OxsfHx+rxfTQQw/x+uuv89JLL9GqVStOnz7NM888Y9HmySef5L///S+xsbE0bdqUzp07ExsbS0REBDk5OQwePJjHH3+c/v37AzB8+HB69OjBkCFDLG6LFuJ2pimllK2DEEIIKFinJDo6mujoaFuHIoSwAZkpEUIIIYRdkKJECCGEEHZBTt8IIYQQwi7ITIkQQggh7IIUJUIIIYSwC1KUCCGEEMIuSFEihBBCCLsgRYkQQggh7IIUJUIIIYSwC1KUCCGEEMIuSFEihBBCCLvw/7M+91KugjzaAAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 600x400 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"===== WEEK 6 REFLECTION =====\n",
"✅ Completed full fine-tuning workflow (simulated) successfully.\n",
"🧠 Understood how fine-tuning integrates with GPT-4o-mini API workflow.\n",
"📊 Validation MAE (simulated): 1.76\n",
"🔍 Practiced prompt alignment, data curation, and evaluation safely.\n",
"💡 Next step: Try real fine-tuning (simulate=False) on small data if credits are available.\n"
]
}
],
"source": [
"# =============================================================\n",
"# Step 5 — Evaluate Simulated Fine-Tuned Model\n",
"# =============================================================\n",
"import numpy as np\n",
"from sklearn.metrics import mean_absolute_error\n",
"import matplotlib.pyplot as plt\n",
"import re\n",
"\n",
"print(\"\\n🧮 Evaluating simulated fine-tuned model performance...\")\n",
"\n",
"# Use small sample of validation data\n",
"val_subset = val_df.sample(min(20, len(val_df)), random_state=42).reset_index(drop=True)\n",
"prompts = val_subset[\"prompt\"].tolist()\n",
"actuals = val_subset[\"completion\"].tolist()\n",
"\n",
"# Convert actuals into numeric form (if applicable)\n",
"def extract_number(x):\n",
" match = re.findall(r\"[-+]?\\d*\\.?\\d+\", str(x))\n",
" return float(match[0]) if match else np.random.uniform(70, 90)\n",
"\n",
"actual_values = [extract_number(a) for a in actuals]\n",
"\n",
"# 🧪 Simulate predicted values (normally would come from API)\n",
"predicted_values = [v + np.random.uniform(-3, 3) for v in actual_values]\n",
"\n",
"# Calculate Mean Absolute Error\n",
"mae = mean_absolute_error(actual_values, predicted_values)\n",
"print(f\"\\n📊 Validation Mean Absolute Error (Simulated): {mae:.2f}\")\n",
"\n",
"# Plot comparison\n",
"plt.figure(figsize=(6, 4))\n",
"plt.plot(predicted_values, label=\"Predicted\", marker=\"o\")\n",
"plt.plot(actual_values, label=\"Actual\", marker=\"x\")\n",
"plt.title(\"Validation Predictions vs Actuals (Simulated)\")\n",
"plt.xlabel(\"Sample Index\")\n",
"plt.ylabel(\"Value\")\n",
"plt.legend()\n",
"plt.grid(True)\n",
"plt.show()\n",
"\n",
"# Reflection Summary\n",
"print(\"\\n===== WEEK 6 REFLECTION =====\")\n",
"print(\"✅ Completed full fine-tuning workflow (simulated) successfully.\")\n",
"print(\"🧠 Understood how fine-tuning integrates with GPT-4o-mini API workflow.\")\n",
"print(f\"📊 Validation MAE (simulated): {mae:.2f}\")\n",
"print(\"🔍 Practiced prompt alignment, data curation, and evaluation safely.\")\n",
"print(\"💡 Next step: Try real fine-tuning (simulate=False) on small data if credits are available.\")\n"
]
}
],
"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.11.14"
}
},
"nbformat": 4,
"nbformat_minor": 5
}