{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "23e1eb32",
   "metadata": {},
   "source": [
    "# Detection of the ball\n",
    "\n",
    "The idea here is:\n",
    "- I seach for the ball in the first rectangular of the image\n",
    "- When I detect a ball I restrict the detection for the successive ball whitin a rectangular not so much larger then the ball\n",
    "- I use the detected rectangle for the successive detection and I resize it with the new ball detected\n",
    "- And so on"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bdd7e1c",
   "metadata": {},
   "source": [
    "IMPORTANT: understand how to set the first rectangular in which detect the ball"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "id": "8a26dead",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import libraries\n",
    "import cv2\n",
    "from pathlib import Path\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from IPython.display import display, clear_output\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4bc2cfff",
   "metadata": {},
   "outputs": [],
   "source": [
    "# --- Configuration ---\n",
    "VIDEO_NUM = \"2\"\n",
    "CONSISTENCY_THRESHOLD = 5\n",
    "POSITION_TOLERANCE = 35\n",
    "RADIUS_TOLERANCE = 10\n",
    "ROI_MARGIN = 10\n",
    "MAX_LOST_FRAMES = 15  # TODO: this can be used dynamically"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "id": "1b6ed990",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Video opened: FPS=30.0, Total Frames=118\n"
     ]
    }
   ],
   "source": [
    "# --- Paths ---\n",
    "PROJECT_ROOT = Path().resolve().parent.parent\n",
    "VIDEO_PATH = (\n",
    "    PROJECT_ROOT / \"data\" / f\"recording_{VIDEO_NUM}\" / f\"Recording_{VIDEO_NUM}.mp4\"\n",
    ")\n",
    "CSV_PATH = (\n",
    "    PROJECT_ROOT\n",
    "    / \"data\"\n",
    "    / \"auxiliary_data\"\n",
    "    / \"lane_points\"\n",
    "    / f\"Lane_points_{VIDEO_NUM}.csv\"\n",
    ")\n",
    "\n",
    "# --- Load Data ---\n",
    "df = pd.read_csv(CSV_PATH)\n",
    "cap = cv2.VideoCapture(str(VIDEO_PATH))\n",
    "if not cap.isOpened():\n",
    "    raise IOError(\"Error opening video file!\")\n",
    "\n",
    "fps = cap.get(cv2.CAP_PROP_FPS)\n",
    "total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))\n",
    "print(f\"Video opened: FPS={fps}, Total Frames={total_frames}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "id": "daa2b55a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# --- State Variables ---\n",
    "last_circle = None\n",
    "consistency_counter = 0\n",
    "lost_counter = 0\n",
    "use_roi = False\n",
    "search_roi = None\n",
    "frame_idx = 0\n",
    "first_time = True\n",
    "scale_factor = 0.6\n",
    "r_approx = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 174,
   "id": "1de43fee",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_points_for_frame(df: pd.DataFrame, frame_number: int) -> np.ndarray:\n",
    "    row = df[df[\"Frame\"] == frame_number]\n",
    "    if row.empty:\n",
    "        raise ValueError(f\"No points found for frame {frame_number}\")\n",
    "    return np.array(\n",
    "        [\n",
    "            [row[\"bottom_left_x\"].values[0], row[\"bottom_left_y\"].values[0]],\n",
    "            [row[\"bottom_right_x\"].values[0], row[\"bottom_right_y\"].values[0]],\n",
    "            [row[\"up_right_x\"].values[0], row[\"up_right_y\"].values[0]],\n",
    "            [row[\"up_left_x\"].values[0], row[\"up_left_y\"].values[0]],\n",
    "        ],\n",
    "        dtype=np.int32,\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 175,
   "id": "e3b6f0d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_modified_polygon(points: np.ndarray) -> np.ndarray:\n",
    "    top_indices = np.argsort(points[:, 1])[:2]\n",
    "    top_points = points[top_indices]\n",
    "    left_top, right_top = sorted(top_points, key=lambda pt: pt[0])\n",
    "\n",
    "    left_top_mod = [left_top[0] - 50, left_top[1] - 70]\n",
    "    right_top_mod = [right_top[0] + 50, right_top[1] - 70]\n",
    "\n",
    "    return np.array(\n",
    "        [\n",
    "            left_top_mod\n",
    "            if np.array_equal(pt, left_top)\n",
    "            else right_top_mod\n",
    "            if np.array_equal(pt, right_top)\n",
    "            else pt\n",
    "            for pt in points\n",
    "        ],\n",
    "        dtype=np.int32,\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "id": "7f31b1ac",
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_upper_polygon(points: np.ndarray) -> np.ndarray:\n",
    "    top_indices = np.argsort(points[:, 1])[:2]\n",
    "    top_points = points[top_indices]\n",
    "    left_top, right_top = sorted(top_points, key=lambda pt: pt[0])\n",
    "\n",
    "    left_top_mod = [\n",
    "        left_top[0] - 500,\n",
    "        left_top[1] + 150,\n",
    "    ]  # TODO: calculate it in another way (proportions between the lines?)\n",
    "    right_top_mod = [\n",
    "        right_top[0] + 150,\n",
    "        right_top[1] + 150,\n",
    "    ]  # TODO: calculate it in another way (proportions between the lines?)\n",
    "\n",
    "    return np.array(\n",
    "        [\n",
    "            left_top_mod\n",
    "            if np.array_equal(pt, left_top)\n",
    "            else right_top_mod\n",
    "            if np.array_equal(pt, right_top)\n",
    "            else pt\n",
    "            for pt in points\n",
    "        ],\n",
    "        dtype=np.int32,\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "id": "8f6f5d5f",
   "metadata": {},
   "outputs": [],
   "source": [
    "def remove_background(\n",
    "    frame_number: int, df: pd.DataFrame, image: np.ndarray\n",
    ") -> tuple[np.ndarray, np.ndarray]:\n",
    "    points = get_points_for_frame(df, frame_number)\n",
    "    polygon = compute_modified_polygon(points)\n",
    "    mask = cv2.fillPoly(np.zeros(image.shape[:2], dtype=np.uint8), [polygon], 255)\n",
    "    result = cv2.bitwise_and(image, image, mask=mask)\n",
    "    return result, polygon"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "id": "96fe7325",
   "metadata": {},
   "outputs": [],
   "source": [
    "def preprocess_roi(image: np.ndarray) -> np.ndarray:\n",
    "    return cv2.medianBlur(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "id": "4f624b03",
   "metadata": {},
   "outputs": [],
   "source": [
    "def detect_circle(preprocessed_img: np.ndarray, frame_number: int) -> np.ndarray | None:\n",
    "    min_radius = int(\n",
    "        (total_frames - frame_number) * 0.20 + 20\n",
    "    )  # TODO: change with more accuracy\n",
    "    max_radius = int(\n",
    "        (total_frames - frame_number) * 0.20 + 80\n",
    "    )  # TODO: change with more accuracy\n",
    "    print(f\"Frame {frame_number}: min radius={min_radius}, max radius={max_radius}\")\n",
    "\n",
    "    return cv2.HoughCircles(\n",
    "        preprocessed_img,\n",
    "        cv2.HOUGH_GRADIENT,\n",
    "        dp=1.2,\n",
    "        minDist=50,\n",
    "        param1=100,\n",
    "        param2=40,\n",
    "        minRadius=min_radius,\n",
    "        maxRadius=max_radius,\n",
    "    )\n",
    "\n",
    "\n",
    "def detect_circle_roi(\n",
    "    preprocessed_img: np.ndarray, frame_number: int, r_approx: int\n",
    ") -> np.ndarray | None:\n",
    "    min_radius = max(0, int(r_approx * 0.9))\n",
    "    max_radius = int(r_approx * 1.08)\n",
    "    print(f\"Frame {frame_number}: min radius={min_radius}, max radius={max_radius}\")\n",
    "\n",
    "    return cv2.HoughCircles(\n",
    "        preprocessed_img,\n",
    "        cv2.HOUGH_GRADIENT,\n",
    "        dp=1.2,\n",
    "        minDist=500,\n",
    "        param1=200,\n",
    "        param2=10,\n",
    "        minRadius=min_radius,\n",
    "        maxRadius=max_radius,\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "id": "5b46d8a0",
   "metadata": {},
   "outputs": [],
   "source": [
    "def update_roi(\n",
    "    x: int, y: int, r: int, frame_shape, base_margin: int, scale_factor: float\n",
    ") -> tuple[int, int, int, int]:\n",
    "    height, width = frame_shape[:2]\n",
    "    dynamic_margin = max(int(r * scale_factor), 10)  # Ensure at least some margin\n",
    "\n",
    "    x_min = max(0, x - r - dynamic_margin)  # -10 to avoid cutting the circle\n",
    "    y_min = max(0, y - r - dynamic_margin)  # -10 to avoid cutting the circle\n",
    "    x_max = min(width, x + r + dynamic_margin)  # +10 to avoid cutting the circle\n",
    "    y_max = min(height, y + r + 3)\n",
    "\n",
    "    return (x_min, y_min, x_max, y_max)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "id": "ac46ced6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAj4AAAH4CAYAAABKa+eYAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAf4hJREFUeJztvXu0LUV17z+711p77b3P+8CBA4iggBA1PoMoBpFckKiYHyr6I4kKBh/DSzS+rqKXn2gMiZqooCPmXrzXt0aDqCE3KuoF4zuJb+PjKiroRYHz4Dz3a63V/fsD2WvWt3bP6upeaz9Ofz9jMMZuurq6urq6Vp2a3zlnkud5LoQQQgghDSBd6QYQQgghhCwXXPgQQgghpDFw4UMIIYSQxsCFDyGEEEIaAxc+hBBCCGkMXPgQQgghpDFw4UMIIYSQxsCFDyGEEEIaAxc+hBBCCGkMXPgQskIkSSJ/+qd/utLNqMRrX/taSZJkpZtBCCHRcOFD1jzf+9735IILLpDjjjtOJicn5ZhjjpFzzjlH3v72t69008bGLbfcIkmSLP6Xpqls3bpVHv/4x8tXv/rVlW7equH44493+kn/Nzc3t9LNGwmf+cxn5JJLLpEHPvCB0mq15Pjjjy8se+WVV8of/MEfyJFHHilJkshrX/vaJctZ/XbSSSeN50EIWSbaK90AQurwla98Rc466yy5973vLc997nNl+/bt8stf/lK+9rWvydVXXy0vfOELV7qJY+UP//AP5QlPeIIMBgP58Y9/LO94xzvkrLPOkn//93+X3/7t3x7bfS+//HK57LLLxlb/KHnIQx4iL3vZy7z/PzExsQKtGT0f+tCH5CMf+Yg87GEPk6OPPtose/nll8v27dvloQ99qNxwww2F5a666io5cOCA8/9uvfVWufzyy+Vxj3vcSNpNyErBhQ9Z01x55ZWyadMm+fd//3fZvHmzc+7OO+9c9vYcPHhQ1q1bt2z3e9jDHibPeMYzFo/POOMMefzjHy9/93d/J+94xzvGdt92uy3t9tqYPo455hinj0LMzMzI9PT0GFs0Wv7yL/9S3vnOd0qn05HzzjtP/uM//qOw7M9//nM5/vjjZefOnbJt27bCcueff773//7iL/5CRET++I//uHabCVlJaOoia5qf/vSn8oAHPMBb9IiIHHHEEd7/+8AHPiAPf/jDZWpqSrZu3SoXXnih/PKXv3TKfPGLX5SnPe1pcu9731u63a4ce+yx8pKXvERmZ2edchdffLGsX79efvrTn8oTnvAE2bBhw+KPQpZlcvXVV8tv//Zvy+TkpGzbtk1+//d/X77+9a97bfrEJz4hD3zgA6Xb7coDHvAA+fSnP125P8444wwRubtfNHv27JEXv/jFcuyxx0q325UTTzxR3vjGN0qWZU65Xbt2yTOf+UzZuHGjbN68WS666CL5zne+I0mSyHve857FcktpfPr9vrz+9a+XE044Qbrdrhx//PHy6le/Wubn551yxx9/vJx33nnypS99SR7xiEfI5OSk3Pe+95X3ve99lZ+7Ko997GPlgQ98oHzjG9+QxzzmMTI9PS2vfvWrRUTkH//xH+WJT3yiHH300dLtduWEE06Q17/+9TIYDJas47vf/a6ceeaZMj09LSeeeKJ89KMfFRGRf/mXf5HTTjtNpqam5OSTT5bPfe5zXjtuu+02+ZM/+RM58sgjF8fBu971rlLPcPTRR0un0ylV1jKDhfjQhz4k97nPfeT000+vXAchqwEufMia5rjjjpNvfOMb5r9y7+HKK6+UZz3rWXLSSSfJW97yFnnxi18s//t//295zGMeI3v27Fksd+2118rMzIy84AUvkLe//e1y7rnnytvf/nZ51rOe5dXZ7/fl3HPPlSOOOEL+5m/+Rp761KeKiMgll1yyuNB44xvfKJdddplMTk7K1772Nef6L33pS/Kf//N/lgsvvFDe9KY3ydzcnDz1qU+VXbt2VeqPW265RUREtmzZsvj/ZmZm5Mwzz5QPfOAD8qxnPUve9ra3yaMf/Wh51ateJS996UsXy2VZJk960pPk7//+7+Wiiy6SK6+8Un7961/LRRddVOrez3nOc+Q1r3mNPOxhD5O3vvWtcuaZZ8pf/dVfyYUXXuiVvfnmm+WCCy6Qc845R9785jfLli1b5OKLL5bvf//7lZ7botfryc6dO53/ZmZmFs/v2rVLHv/4x8tDHvIQueqqq+Sss84SEZH3vOc9sn79ennpS18qV199tTz84Q+X17zmNUua+O666y4577zz5LTTTpM3velN0u125cILL5SPfOQjcuGFF8oTnvAEecMb3iAHDx6UCy64QPbv37947R133CGPfOQj5XOf+5z86Z/+qVx99dVy4oknyiWXXCJXXXXVyPujCt/61rfkhz/8ofzRH/3RSjeFkPrkhKxhPvOZz+StVitvtVr5ox71qPwVr3hFfsMNN+QLCwtOuVtuuSVvtVr5lVde6fz/733ve3m73Xb+/8zMjHefv/qrv8qTJMlvvfXWxf930UUX5SKSX3bZZU7ZG2+8MReR/EUvepFXT5Zli3+LSD4xMZHffPPNi//vO9/5Ti4i+dvf/nbzuX/+85/nIpK/7nWvy3fs2JHffvvt+Re/+MX81FNPzUUkv/baaxfLvv71r8/XrVuX//jHP3bquOyyy/JWq5X/4he/yPM8z6+77rpcRPKrrrpqscxgMMh/7/d+LxeR/N3vfvfi/7/iiityPX18+9vfzkUkf85znuPc4+Uvf3kuIvmNN964+P+OO+64XETyL3zhC4v/784778y73W7+spe9zHzuWO65F/53xRVX5Hme52eeeWYuIvl/+2//zbt2qXHw/Oc/P5+ens7n5uYW/989dXzoQx9a/H8/+tGPchHJ0zTNv/a1ry3+/xtuuMHry0suuSQ/6qij8p07dzr3uvDCC/NNmzYt2Y4invjEJ+bHHXdcsNyOHTucfgjxspe9LBeR/Ac/+EHpthCyWuGOD1nTnHPOOfLVr35V/uAP/kC+853vyJve9CY599xz5ZhjjpHrr79+sdzHPvYxybJMnv70pzv/8t++fbucdNJJctNNNy2WnZqaWvz74MGDsnPnTjn99NMlz3P51re+5bXhBS94gXN83XXXSZIkcsUVV3hl0Tx09tlnywknnLB4/KAHPUg2btwoP/vZz0o9/xVXXCHbtm2T7du3yxlnnCE//OEP5c1vfrNccMEFi2WuvfZaOeOMM2TLli3Os5999tkyGAzkC1/4goiIfPrTn5ZOpyPPfe5zF69N01QuvfTSYDs++clPiog4O0gisigq/ud//mfn/9///vdfNMuJiGzbtk1OPvnk0s8dw2mnnSaf/exnnf/07l2325VnP/vZ3nV6HOzfv1927twpZ5xxhszMzMiPfvQjp+z69eudna2TTz5ZNm/eLL/1W78lp512mtMWEVl8zjzP5brrrpMnPelJkue5837OPfdc2bt3r3zzm98cTUdUJMsy+fCHPywPfehD5bd+67dWtC2EjIK1oU4kxODUU0+Vj33sY7KwsCDf+c535OMf/7i89a1vlQsuuEC+/e1vy/3vf3/5yU9+InmeF7riao3EL37xC3nNa14j119/vdx1111Oub179zrH7XZb7nWvezn/76c//akcffTRsnXr1mDb733ve3v/b8uWLd59i3je854nT3va02Rubk5uvPFGedvb3uZpUH7yk5/Id7/73UIx6z0i8FtvvVWOOuooT9h74oknBttx6623SpqmXtnt27fL5s2b5dZbb3X+f9Xn3rFjh/N869evl/Xr15vXHH744XL22WcXnj/mmGOW9PD6/ve/L5dffrnceOONsm/fPuccjoN73ete3qJ206ZNcuyxx3r/T0QWn3PHjh2yZ88eueaaa+Saa65Zsn0rIdLX/Mu//Ivcdttt8pKXvGRF20HIqODChxwyTExMyKmnniqnnnqq3O9+95NnP/vZcu2118oVV1whWZZJkiTyqU99SlqtlnftPT+eg8FAzjnnHNm9e7e88pWvlFNOOUXWrVsnt912m1x88cWeGLjb7UqaVt84XaotInfvBJThpJNOWvxRP++886TVaslll10mZ511lvzO7/yOiNz9L/ZzzjlHXvGKVyxZx/3ud78KLV+askENqz73qaee6iyirrjiisJYNGXROzv3sGfPHjnzzDNl48aN8ud//udywgknyOTkpHzzm9+UV77yld44KHqe0HPeU88znvGMQi3Vgx70oNLPMg4++MEPSpqm8od/+Icr2g5CRgUXPuSQ5J4f/V//+tciInLCCSdInudyn/vcx/yh/973vic//vGP5b3vfa9jDvnsZz9b+t4nnHCC3HDDDbJ79+5Suz6j5L/+1/8q73znO+Xyyy9f9A474YQT5MCBA+auh8jdQvGbbrrJc+e++eabg/c97rjjJMsy+clPfuKYQ+644w7Zs2ePHHfccRWfyOWDH/yg41133/vedyT1Ip///Odl165d8rGPfUwe85jHLP7/n//85yO9z7Zt22TDhg0yGAyC72clmJ+fl+uuu04e+9jHBmMEEbJWoMaHrGluuummJXcJ7tGcnHzyySIi8pSnPEVarZa87nWv88rneb7oRXXPv9B1mTzP5eqrry7dpqc+9amS57m87nWv886V3cmpyubNm+X5z3++3HDDDfLtb39bRESe/vSny1e/+tUlA9bt2bNH+v2+iIice+650uv15J3vfOfi+SzL5G//9m+D933CE54gIuJ5Ib3lLW8REZEnPvGJVR7H49GPfrScffbZi/+Na+Gz1DhYWFgYeWykVqslT33qU+W6665b0jNxx44dI71fLJ/85Cdlz549jN1DDim440PWNC984QtlZmZGnvzkJ8spp5wiCwsL8pWvfEU+8pGPyPHHH78oWj3hhBPkL/7iL+RVr3qV3HLLLXL++efLhg0b5Oc//7l8/OMfl+c973ny8pe/XE455RQ54YQT5OUvf7ncdtttsnHjRrnuuutKa25ERM466yx55jOfKW9729vkJz/5ifz+7/++ZFkmX/ziF+Wss84ae36uP/uzP5OrrrpK3vCGN8iHP/xh+S//5b/I9ddfL+edd55cfPHF8vCHP1wOHjwo3/ve9+SjH/2o3HLLLXL44YfL+eefL494xCPkZS97mdx8881yyimnyPXXXy+7d+8WEduM9eAHP1guuugiueaaaxbNRP/2b/8m733ve+X8889fdBFfK5x++umyZcsWueiii+RFL3qRJEki73//+8eycH3DG94gN910k5x22mny3Oc+V+5///vL7t275Zvf/KZ87nOfW+z/Ir773e8uCvlvvvlm2bt372KwwQc/+MHypCc9abHs+9//frn11lsX3fm/8IUvLJZ95jOf6e3MffCDH5Rut7sYpoGQQ4Jl9yMjZIR86lOfyv/kT/4kP+WUU/L169fnExMT+Yknnpi/8IUvzO+44w6v/HXXXZf/7u/+br5u3bp83bp1+SmnnJJfeuml+f/5P/9nscwPfvCD/Oyzz87Xr1+fH3744flzn/vcRTdz7YZ80UUX5evWrVuyXf1+P//rv/7r/JRTTsknJibybdu25Y9//OPzb3zjG4tlRCS/9NJLvWuPO+64/KKLLjKf+x539r/+679e8vzFF1+ct1qtRVf5/fv356961avyE088MZ+YmMgPP/zw/PTTT8//5m/+xnH937FjR/5Hf/RH+YYNG/JNmzblF198cf7lL385F5H8wx/+8GI5dGfP8zzv9Xr56173uvw+97lP3ul08mOPPTZ/1ate5bh+3/N8T3ziE702n3nmmfmZZ55pPncsRffS93zAAx6w5Lkvf/nL+SMf+ch8amoqP/rooxdDJYhIftNNNwXrKLr3Uu/9jjvuyC+99NL82GOPzTudTr59+/b8P/2n/5Rfc801wWd897vfvaTLvoh44+ge1/ul/tPPlOd5vnfv3nxycjJ/ylOeEmwDIWuJJM/HvPdOCFnTfOITn5AnP/nJ8qUvfUke/ehHr3RzCCGkFlz4EEIWmZ2ddbycBoOBPO5xj5Ovf/3rcvvtty/pAUUIIWsJanwIIYu88IUvlNnZWXnUox4l8/Pz8rGPfUy+8pWvyF/+5V9y0UMIOSTgjg8hZJEPfehD8uY3v1luvvlmmZubkxNPPFFe8IIXjF2QTQghywUXPoQQQghpDIzjQwghhJDGwIUPIYQQQhoDFz6EEEIIaQylvbrOfOhDneOyyQjrkioFUuieVrJI61o8l4p7rDN3i7iJB/EctqHdHnYxyqnwvrm4WbU1mBQR68rVGtZ71o77mnVdE5Oup86BAwec41/+6rbFv2+//Xbn3NxC3znGhIyJLJ2gUUQkS9x+0m3O0z4WL8Tr04BibedvUlOMmq2HVc/JZbY5Lx7TedKsf7fkefH3MTaSLFzmN9y1u3x07xjqjK1REvq2qldcPE+sdVaLhLbO73Xla7Pq96zTbzvvuiNYplkzJyGEEEIaDRc+hBBCCGkMXPgQQgghpDGU1vgsl6YH76OPLA1PqB7rvH/PpLCsiKtl8a6F48FgqEvA9nt2zIgujrkWdUi9Xm94GeqbjD5GDU+36x6jDkny5RkzmtWo4SHNYMvWLeb5qhqg3bvs7Owcm2SULNdv/UrCHR9CCCGENAYufAghhBDSGEaSpDRJwbU6whWt5dloDBNOYAfO3aILtEGX9UxdbShabM4KbQtafYGmIW1m8tzXQ89TUI+ISL/v1jU5OT08l7kuwvv373eOZ2dnF//WZjsRkR7Ui6Yw69kTaKNuc8hpeeeOnYES1aDJYHWzIlvwI7ynNb5C5iwLvJbjeGnqjB9zbvbmOT23rQ539twICzO+72p1PPtScMeHEEIIIY2BCx9CCCGENAYufAghhBDSGCq7s1cNKe3ZEwPVaNvqKMNu62PUxLQghPqobKCeu3fkeY2f7qJavXiu3y+fLgLxx8Ro+m1cmp7DtrpaiBXwvidERHxdzqg0P9T7VMPTM6oQIBgeBLF+G4Npi8aU4sJJCRRoQxPgjg8hhBBCGgMXPoQQQghpDFz4EEIIIaQxlI/jk6BORNsJq9sIQ5nrU9H3LX8fX9OD54drPtT4pEkKZVe/DdRqI+p2tI0Xbdlzc3Nw7bDswoJbNmmNZ908Sk3P4YcdVnguJjYSIcvJqGL+rIkYP1l5zYmlT7Hj6fixw5ySaaCsOsyxvfC7lBuaSnwy70mNeDv4fFF6ICdsHdw1ov9jWM2zK3d8CCGEENIYuPAhhBBCSGOonLLC3mKsjpcdPC/v4m1hZVjHe7ZbdrfEuAbGbNvaNy1fNOY+6M6u3TbxPJrMJtpd59h/VuPZ4fiOHb8qLBuDZdpCvPaukEXTvq1xdg2YYEfJmDx91xx1XN+tsqvSDDZCYty4u113bvN+lxQoF9BzJt7Tkh0g2D4rLAld1OPgjg8hhBBCGgMXPoQQQghpDFz4EEIIIaQxVNb4aJtiSIXTMuyNlu1URCRLilNWpGAe1ed9rU2xi3qMLme58G2/tg3XSu2xYcOGwrrnegvOuYNzs85xpu47vX6de67v2rZRuGNJMnbsut04W57Dt26LKp8lg+KTNTQkdcYMU2WUY2W+y1a4yApz2GHF38CuXTtK1+O5vm893DnWn0cdXac333r//i7WUGYZunQPf338ebx8G0Ou49bvBWL1Tbs1UbpNqB1CkZs+rzWrd5c1LsV+gt/gkWnpIvp/ueGODyGEEEIaAxc+hBBCCGkMXPgQQgghpDGU1vigFseJKTDGGAJWXTHnvJDkxrVoW/XspyPCsgWHND6jworbM0ru2H1n5Wu3HXZE4TmmnSCkGNT/RGl+drupYzZt2lJYNjTnm7HPjOuwrBUzB9vQbrs/b51OxzkO6Uut+5ZtI163bnpDYdml6rKIiaVXNQ3IoQp3fAghhBDSGLjwIYQQQkhj4MKHEEIIIY2htMYny0Hj45gFjdgoEmdLRUzbZEX9j4hr1xynTVM/e0g/o+O5+Bbb4lgXIna8I+8+6tkXZl2NT5KBFiofqL/Naj2q6nqO3Ha0c5yZkaKwUePRKJFmEorvstaoo/nZu/euxb8tvc9SWP020XVj2+h5cn5+3jk3NzdXWHZyctI5t26dG3dsenraOdZzM+p/sKw+H9Id6Xxcvp7J1YvOzMw4xwcPHhyWDczjMbm7YmiC5oc7PoQQQghpDFz4EEIIIaQxlDd1Gdtq49wKizFJxbTDCkGeGuktgtcabv+h7UfrfMyzxWxV6m3ZutwO7q8xHHX49sW/s0NvZ5WsIOMMr7ESpi+8J845MW3Spq+qZi8RkS1bDnOOY/oczVkaDCUyMeGaxbR5a9OmTc65o492TeYbN250jnV5vM/U1FRhO/C3MMbU1Vtwy+7c6c6ZO3YM3wGa9fbu3escO2mjoE14jK79o8KUoozljqOBOz6EEEIIaQxc+BBCCCGkMXDhQwghhJDGMJqUFcC47N7jcrPzU1KAHR9vkxT8LSKDHPrFcFH3ekn9j1AfWik48HlC9l8N2qvnF4b2d0xvceee3WYbLbZtPty9bzK8bxbrN6/w3hVpPHXC+YfmvZhUADFY32hI06O//5hQItu3u5qY22//Velr77prl3N8+OHFaWZ8ivsQ5zJ0Wd++fagN3Lp1q3PuPve5j3O8ZYvrgt/tdpf8W8ROd4H9jTpJrc3B+XRudsE5Rrd5/Xy7d7vzK9533759i3/Pzs6KxbjCt5hjfBXPxdzxIYQQQkhj4MKHEEIIIY2BCx9CCCGENIaROPeHbNnazhmKe2MRY5u0NDChumLKIlZf4DnrODZmkb4W7dMDI+4HlsXj+f1DO/LOfXvMNllsnNrgHC8kCwUlRfIUNVfFeOMnDejAauiHVgQzttMytmMVEKOZGVdsMdSc6PEXM5eFtENW/C/UlOC1CwvDb6tOn23e7Gpm9kRo+nbudNPVYKoMzWTX1e3oPkbtDaahOPbYY9U93FhCxxxzjHmtvg9qhzCOj35fGHfIej/4bvbu2e8c43yr24T6H6ssolNfiNRLG2Vhfmc1vkHr2UYBd3wIIYQQ0hi48CGEEEJIYxiJqWu5wrgvV9bYkKkr5vl02ZCpK6ZNiHY199oP24Z6y7TbcUPAr5tyt1d/dOvPSrcROW77cBtaNuFZd82tt2K9kAARzMzPmOfzMfm7J2Pz3TT+bZKtwn+3JNXfHeJnti5+Xs9UpMYQnrO+w9A3apmZssC4zSOC+E9PDr9D/J7R5IFmjHY6dL0OzRsxz75189BctXtP+fQWIm46jM0bXZPUxsM2O8faxINpKNBlXael8MpCGg00HWkzGqbCsFJWYH/jmNCu5XguTdz7JIk7N+v5qd12y3Y6rtlvYmJyyb9FXFf3pY5jqPo7i6mfou45Zl/4VThzEkIIIYSMBy58CCGEENIYuPAhhBBCSGMorfGx7eTlQ8KH3OpG5TqOocJ1yPHY+1RtQ5nzo7qvfj9oV+4YroHoNviNH/3HCFp3N0ceeaRxtngcoAzHCt+PzC64odvRdm8xKg1WnVAEflnDrTNfhf9uGaPGp6peDueC0H0srHAcowyDYblEh55dP2+ddB3Wud0Sp/HR7Nnnprc48aH3c461jmfbNtcNHnU6GzduXPx7wwY3ZAa6qKM7uwafFceM7kf8LUG0BgvrXb9+vXOM86+uG6+1whaEUqmM63fIIs/t786+drztXYUzJyGEEELIeODChxBCCCGNgQsfQgghhDSG8nF8PNv90AYXWj1pex3aIn3JD9qVi2uH7ASSKrtmMOS11kcsk1bCjyFjaQBCZd3j6e5Qy4JxPiamXNu2tl9v2bjFaEMcT3jMOc5xvtmIu4KZJNS7w27Cd2lpxrBePN9qldfiWDoLvLZlvMtQ+hQb49rAuNVNDulElri6TON86mh84Hmwzdb7MDVjgfhfztjz+iUQm8fQHZW9bqk26awtsXqNmLQ5MfXqPr/3797LOXfTl240r7U47l7HOsdat7N582bnHMbq2b59+5LXiYhMwbyHer+5ubnCNiUwkeiYNN45GLcdFUepnbhz8d45N2XF/Iyb/mKwoHQxKJGB4+nuUO/UOsydIzetd/tp/5bhfS1N2FLnqzM6vZ9VdxW9Lnd8CCGEENIYuPAhhBBCSGNYluzsmpCLnmWiQpNBCuYFfa1lHhEZf0jsKowrBQf2sXaZ3LL5MCxemv/vJZc5x8nvwLs1+hhNUu511bfyrXpFRBKVnR3HE9arszDjOS9NgNoK98ZphKnLf7biNuaBh9Wm1fjt7JU3dUVdmpc3B8X1f5wreVU8053RjzFtqGN+i+GU55ziHP/d/3hH6Wvve9/7Osc6XQS6f6OLuj6PaSawLLqha9NpjDk0JrwGguY4NL9pd33rWUXc1BiYjR3NePra0PihqYsQQggh5BCCCx9CCCGENAYufAghhBDSGJK8pEHvsQ9/iHNc1Q7o207denxtzvDYc002ND4hXUUixWXruB/b9tLq6TpCbeh0hvZg7MO040q5tB357z7wHrNezXvffo1zHLINZ+p5vbKWO3tq6zWs8AghfVDZekVEer1e4bUYMiDJilMXhO5bHVujZKUuqKPx8aIyaEao8bH0TiEtlB4XMZoG/93ZYQxiiHvv49RHLE2dcRlK1/GqK15Ruq6/fetwnul2u8451MToNBX4TeI8iNdqjUxIt+M+jz1OrboycEnXaSdE3DlHt0/ET0Wkv++ZmRnnHGp+LD1TfKiLkgTmghitlP/NFs9tb33Hm4L1cceHEEIIIY2BCx9CCCGENAYufAghhBDSGEYSxyeEto96odlT2zZsXRsh5zjkiLHDoq07RtejwfDxGBsGyaw0AlYcnwgZBeqxJMXxVV77gc+j7eI49lBPIIPicRrSmFTVkA0GAY2V8axh+/rKa3z8dCPDOCx+H5fvQ3zP+tjvl/LPE9K5xL1n+9saB3VSYYySS1/yvMW/P/CujzjnUKeDxxorLpeIO75CcxnU7BxZGpmQFs2KW4f14rPqNmPMn3Xr3HQdWju0FjQ+4fQpxZqlMnDHhxBCCCGNgQsfQgghhDQGLnwIIYQQ0hgqa3yq5sLxNBl+icL7+PmSivNxhezp4XYUUzU3Toy2IzZeiFUeY2HE8E8f/Oji3+0Jd7gMQs+TFtuvLd1Lnth51jT4bFni2uqt2B4hnYtjf8/t2E7zs8N4HL52yLapW/F2EPd8dT3NSsXx0c+qY7CIiHQn3FxLqGlI07b6G7/fYi0X5i3C2Ck6BgrqQPp9tyyix4GXvw3Gnj5GbQe2yep/jC+F8V00offsxM8aYRwf5H3/44OLfz/rOX9cul7Mr4VtxHg1bpsgnpkx54f1WPrYnvfMXIIRsWtwjFj5ArFebJP1GzAubVednGbBNslwHmGuLkIIIYQQAy58CCGEENIYxpKywtp68tIpBNJD6Ptg2Q6YUqyUFUiaFFv56rmhWqau6u6uoe3Uqan1hWXfd/11hfUin/6Hfyy8j9eGQL8kreI+RvdRy9SF29162xbdODuT7j2981CXBsemPu73bJfPHXfsXPzbDxc/utDtcGXF61bO1KX7dMuWLc65zZu2OsfoktvpDN97yJ1dm3/QfIVmpf379y/+jWaxHTvuKGy/iDvP4JxjjT00g/nfw/AYTVuYygCfx0zpYqVTgHMxcoCYORLLXvisp5W+9toPfqJ0WW0aLdOOUZXV/ej1d15skhWx3c5jZBRV5RhLUXV+qmM6DV5rzDPPufSZwfq540MIIYSQxsCFDyGEEEIaAxc+hBBCCGkMpd3ZLY1JyE1b28WruJ4VYbnwoX3as1erJo+yTcuF1cdWGPTYejWeHTlQV2aEgbfCpqP1FvUQ09PTi3+jm+a6jdPO8fr1651jy6XYch/tLdgh7WcODHUXvkv0HBy77sde+ovS2P9uGeTFbs4SHPKW3qxYC4Kv3HKrDYXZR3f3dnvo3h5yZ9d9jPMEamJ0m1A/o/U/IvYYwWedmnKfR98n5KZt6XSmp902and8EVenFHJ9d9tfPZXKcs2hmMnDum+W2d9sjAYlSuOjbov38MYPNlHl60nwG7Tai7/BRvuSFM/aGp48qbY/koUnmeJ7BjU+xemEysAdH0IIIYQ0Bi58CCGEENIYuPAhhBBCSGOonLLCSg+Bx9pGHQrDHWOvC8UEWsuE+tQKX/4/r/tw6fvccO31hfWI2DEcYqI0hOJM6OOJrpuqAFMXaO0H6kS2HL7ZOdZ6IBE77oqpb4JuwGwcu3fetfi3lSZDxI/ZUjV1SSi+hvU91Aknb+nnQrFgjjjiiMW/N23a5JzbsN7V9OC71XFZWi0cp24bY7RqWnuDGhgr7pOI+y7xvVopK0JpZCyNQ7dbHNdKRGTfvn2Lf4diGOnzdXQ6dWKd/cP7PuEcP/1Z5xdei+c+8t6Pl75PTJuQmOcb9C39q/37F9Mmt961p1NdSQ6dlQIhhBBCSAAufAghhBDSGEqbujATtyaYb12lh0igdJLa23l6qzzkpm25s1vZdkPbhDHZd2PqqQPWNTt7oFpF0KUZuDY6R9gPgSzF+nTIpGmF87fSUkyuc7f50X3dM60a4816npAVdXJ62I51G1zzGroUW+k6vDZZYy3w7Vi2yKBZ2AgJnxV/SpLBdd1J9/20u8N3t2Gza9qamnKzs2MbWyrcPw41/9MalkXzFbptt9va/OnW0um448eqa906t/0bNlju7G6/eOEd+sMxgubDPrgJZy0w3XWG38vCnDv2sj6M8Xw0//b1XK8taqQy8KuqkRbBGch2+2Nuk6IdvPCeruv73QXUGPfaYDQiKQ7tErw2+Ate8ffO89WPIKbDK4wB7vgQQgghpDFw4UMIIYSQxsCFDyGEEEIaQ+WUFZpWQC8QZf8FrNDt7VZlb/xVj5WSYqnzH/rk/ypd9z/8z/cO69lqvxvtNozaFMR3hS8+Z2GlOcBjTHPQBk0Gmqcta3AdDda2bdsW/969e7dZFvtC60ZGGZKhlqbMdLEvfx/Ua+n3hZqekOt4anjg+03Q/8NtA+oddP9j6AR0/9bpIETcsYjvDp/HSpfiha9oD6/1dUWj0RzitavFJVq7t1uu7SIiF178lMW/P/yej42pRaNjlG7zcGG16w4BmLKCEEIIIcSACx9CCCGENAYufAghhBDSGEqLZCztQT8Qpl5bs/1YL3ZqBh2fYKVSUoTSLSwHqG9CLUJVsE89HY96HUkLYyO5RXPUKaTFMSmstAfdCYj9AjqRgVLq5CnExYD74I1zyxxcw0yey7Df2h3o08xNG4Cxq9qOFMSOx+GWtMehF28nCkPjg7GesmKNEo5TnULETzkTaJH1PNAVeqi2WphCxz3WcXywLOpr8Fg/T+ib1H3ThnGL/dZWsc/6CXx3mfuwA3Fj9ejhhaGe8FjXlabVB0zMlTh9DsyPMqZit59C83SdtC1mM6z7juu3IxiPqUZMnVVOld9j7vgQQgghpDFw4UMIIYSQxjASf/BgKglr23xMbnih7Oa17BoR99XU2eXE7bz3/9M/Vq5Lp3VA0xZuuedGao8st80yidqiR3MVoscQlrW2pEMu0KMixg01ZPJAl2htLom5D2Yo997P2Dxc3fdhhZzwM6yXHxMe1j/TrG6DXX7LzIpzGT4Pvh/9DDgWrfsgZriQgOv7SkkAVhsXPvt85/jv31WcuT1EvRABVU+6rJbwAtXbEUoDUr2P65op+cUQQgghpDFw4UMIIYSQxsCFDyGEEEIaw0hSVoTKJoZOJGiv1u6W6JoJGgdtC6/T3nG5q8e0aZRt+NRHP+Ecb9s+TK+wd/8+5xz2f9Iq1tBMg0bDf7fD94H6h0GOLtHD44kOpKiYcnUimzdvHp6DdBbYbTiczPQplhcqHsONduzYsfi35/K83k2rgd67+rzn1gx97JxvldeQjBLtvh7CSjeC+rKQVtCPVVCMHl6eHiCB8But4nP9vpuyIs8HxnlsYPFxmhansxBx3dnn5yEcQmAe0ec93ZehjViuMB14H+hy5/xH/qer0/l/L3ly6fvg74XfkOLvxeqLoA7PPFv+2wlEq7Db4P2mjSZtVAyhcBsrCXd8CCGEENIYuPAhhBBCSGPgwocQQgghjaGyxkfb/eroaRC0QeuVWUgfNK64BzEpK+q0oY5d2WLbtm3O8caNGxf/XrdhvXMO9QQ6nDw+24YNG5xjL1WJ0gd548dMP+DWg/fRcYhG+cqtPg7Fc9m9e3fhOR2nZ6ljrX9CLRTGwdExgrrTU4XtHSezswedY0u3g1g6PE/74eVEKd9GfWlrAv5958p2zDg+eqyJ+FqcLVu2LP69detW5xzGc9J1d0A7h8+qdWKhb9/T5am6QrGEVkusmCLqxGsJjUXr3/0rkZZolPi/WSvUEIOY+da7tqZ+iDs+hBBCCGkMXPgQQgghpDGUNnXlXvx7nbY7sO2k/RWhmlZqb/kmyn10LYRmt7aOBwN3+w5NHr3eMMvygQMHnHN1tny3H3WMc6xNE3N9N33CFGwP9wfFJs316zc6x2immZgoHl44nKznw/eeqRwE2mVeRCQZVabnSNZvGppE8FlCZjIrwze6g2tzSbe7MqauyUm3jbrNCwvo/u0+qx4j8WaWitvbXtZxMKer8YX9f/Qx253jqSm3z7UZFk2y+nsWgXQjMPWiWSYPZtse4skD1PMslxygDjhG9PPUSx0R9GevXDdZ26z+lQQhhBBCyIjgwocQQgghjYELH0IIIYQ0htIaH8S1FQfcUCvXa6cYGJXmZ5Sui1ZdaPNH/YZ+dnQr/9zX/61ym7TLrQikVIAR4LmAKg0N9vfkpKt3QFffbneo5/Ds+PBarTD7SKszbIeXjcC80qZOShHXxd6tB/sFzztuzp5OytWcuP20PP9u8bulOI0JjhF8Hus9B7/DqvMKjBGrjdgGDAWBGh/9fiz3de94YD9Lb274HWIKFGw/frMroeOJmUP9suNp7x8//2nO8Qf/+7VjuQ8ph6XlCpX1ztOdnRBCCCGkHFz4EEIIIaQxcOFDCCGEkMZQXuOTQCwSfUpsW31iaHFyQU2Je5gaOgYrfkUYHQvGbr9vT9Qak/LxdbB5CcQ/6kwOtQYLA4irH8Fg34x7382ulkjHL88DcW9Qa+RU48VHcUnaKj0BnLPeVCgUj+7y0Cv3Xo8ax158IPNd4phwy27YNIxpFBoTON5QN2KVXQlirOmTU13zfG50jafvi/ic7XrdY09f1h7+jw7EFdvS3uQco25Hx5HC9k9MgBZKnw48WysZTs0L8AnOzbmanyxDDZBz1m2CF3NNx8xZnrGG82sf9RyqGdjaD7zzo87xM557Qen74nvP81BKi9GTrlDooNz6QMZ1z4iZI6jp8fRBlZq0CHd8CCGEENIYuPAhhBBCSGPgwocQQgghjaF8ri7DBlcn/kkIbVOP1U6sBDGxCQ4ePOgcT28YxoL56U9/WrkNKcROkRoxNnRsEjw3ABsuamZ0+XG9m7q2Xo2lEcP3ilqPVGkyQs9qnV8NY3icWLqdOjIErFfXhfVa49SLuZS67xkZly5m0B+2KaRdxPxoK8EoY6GR5uHpgkO625rjjTs+hBBCCGkMXPgQQgghpDGUNnVZK6TUc5l0t6lSYw87ha1i8Jr3XBCda70t62IXdQt/18xeD1rmLGyvNonkfTANddzuX1Ch6Qd1tvKm3HrzBdfdVfdN7vWTYYaB41aoi5XvZgKu72Nzrsx64TKLlO/jBAcmklY361U3b9lmmBWhThoN7OMadSkvc8nhe8XwGon+aL3wByGzpXESt+czNUbyYnObiEhLfVyDQWaWxfnISztjoOfQwWB5zFX+/Ml/f9/DoWwyxPduPWtMP8SElLkHjjhCCCGENAYufAghhBDSGLjwIYQQQkhjKJ+ywsALNY+Gb2Wu89yAwd5uHcfY8urZSm0bunZh9fRMhusp2t7Xr1/vHO/YtavwnjHkB90Y98lERGaSGL1JoGgaSGmxlohxUY9LneISlwJlFf67ZRVKFKyUOeO9McyLVlnot77S+83OzjrnDhw44BxjWpncSUmzCl8IISvMKpw5CSGEEELGAxc+hBBCCGkMXPgQQgghpDGUFn9YIftbEE8kAWt22hqur3ythB2q2omL04LYF1ZY64Gtlaijj7D0HD3Q8eiy3W7XObdLaXpE3HD5dx6ciWqTjtWzkLk2/wnpYnHVvkC96jx2WUjBk1nygnHJf9JOuMxviFFRZTimrfQWEfV6QIoEc5Ri/1p9Co2KSQ9hpYPwyuKMAm20JUzwfXupJqxra6D6rU4GCtTTpPh+dOArN7SWl3bi4L5hOpu5uTnn3IEDbqqb/fv3O8daE2Tpf2Kxrq2jv8wNYViove+/5trFv5/5vKeZZfH8+/77P5jlx8EoNVerXb+V5XbcHkuLFtINO7HoKvQDd3wIIYQQ0hi48CGEEEJIYyifsmJEpiHf/ds2IYwrtUEdd3HdRnyeDmZGV2DZDRs2OMd37NhRuU3aZoUhA0ZFdJcdQsvq1eg6ju/D2/LVKRICW8dWGgRMtWJtS2MqhtXYb+PC38qHAqofsZ/Q1KXNV747+wwcu+7t2jTW67kpXDCkhvOeV7flpBGsdvPVoUJzZiVCCCGENB4ufAghhBDSGLjwIYQQQkhjKK/xydw1kqMRQHfXCDtlKBWApcVB/YDj4tay13Rpbrgju2Zw8z7Y/gG0V1+L9vXJyUnneO9ddxU3OER7eJ98Fh6gA8e6zQH33Tpe54m1rh6TKTsbl5v8KgT1G+i63F8YnkfdV0jjpsctjn+dTkFEZMu2LcM2zLpalWA6m0MIby6AftI6nkHP7f+9e/c6x3v271v8G93ZZ2Zcjc/BOde9Xb+fAUxmGGJCu5JjGBIPY86M+p7x9wHjJVSueHVg/f7FjP46OtRxEaPZG2XoBEuTSHd2QgghhBADLnwIIYQQ0hi48CGEEEJIYyit8bEI2ePKnlutxDwP2smta9GuPzU1VaF1v0GZ8ttGLCERcWzsIevouN6XZb5uUOiXWtx+++3OMcZ70RofjC+F+iArnDzyoIc9qPBcd2oC2lCcwuVQICaNg9ZgHdzv6nT27NnjHOvYPKjd8t4zaIm0ltBv39rq/3GOF6vu1RBPZ5RtqNOPVWNxhWKFrST8iSGEEEJIY+DChxBCCCGNobSpy3JLxV20teDC2s/7hedSdK/E9htunV52eb3dDVuGcxCmfsth2wrrDTJQz5PaW4zL9T4sc5bVJrwuZqd1pVbyo0qB4mFYKvbtARdoMJd0VKZ3fOcz866LtJ9KZtimx/zeY4rbF6A94brR570a293jGrY6ugOG5oBpwvO8zvS4dcdAD1zJdZ8v9F3z1dyCa77atXuYvgbrzSNiNvjmhuKyuZdOHs6rbNveeA+FNNFzJk6nSfG3M07zSNW6Y67Dsv3+wDyvj0MmJtNtfoRmJgzDUrZNoWFaK+yNGjPz8O2UgTs+hBBCCGkMXPgQQgghpDFw4UMIIYSQxlDZnV3b3FqQHmI1htoeJVbKCjRr6lQBC+B22m673X/XXXvqNGrxzx5ohzrdCSy9LKwm98VDkfXr1zvH+N1lveF4w3HaDoyJh5/28JqtW5qko9LK1NH7rAEwTYjWbKAL+gJ8sxpPYwEaQyulDpKmxedC32ueD6/Fewa/ddVmLDvIQcO0TPNG1fvEaCQ97VzH3mvQ33BIW+OkaAqEoxiV635M2IvcGGux90HqrjG440MIIYSQxsCFDyGEEEIaAxc+hBBCCGkMleP4OOfAHNeCYBf6fOrVY9vy2l7gDHWlEaugjg0Q4w9gk1MV7wJjX6Rgf9d2/imw+aOdH0PRxzAzOwyBPzk5Wfq6QOgOO/CHF98I7L9ZrorasZ1y9b78mA0RtuLVFzJqtKguPuKII5xT09PTznFvbhgrZmLC1fQM4Ls76tijRtTA8mi9j8jq0PzgvJEE/m2op6ckd58H04TolDSo6Zlc57679sS+YZsCc6T3bRlxxswYQMH4QMN6sZ9i0hrgta3c/RlaLo1PzDypqaWJCcTxcbWz7u9FTDydUDssRpVyqk4cH3x21MPmKkcT/o6WgTs+hBBCCGkMXPgQQgghpDFw4UMIIYSQxjCSOD4xZdF2Z+VpCd2njiVY2xdDz2LHxYAYRoYZttfrOcdot6xjwx1VnIZR5vHC5y17X9RGLJdwZ63Fn9KaERGRbrfrHOs4Pji20P5+cO9B53jdpnUjaKHNatD0LCdaU4LvY//+/c7xunXD/vfea8Q49TQmWbEuMkbjE4s9j5fPfRh73mLLli2V6g3pmcxrMYUZxjRS4yL0nld7vKPZhflwoQJCGp+F3jDv3cGD7txVBu74EEIIIaQxcOFDCCGEkMZQ2dRVFdy+C5m69Lai57aZgSugU7HdDr17hxuTuONrbfX5bp3FXYpbpGgK2rdvn1Sl2xm6K6cQAiCXYpdJpI5ZzApnjlv7eKy3NkMh+NNWcfvrmKswLMOqAB5VP18qmLrA3R6WieI0AaHjwcxwbLam0fRYnTrmrZh3q8dQ6LoYV2yLkNlFhxTA/t62bZtbtlWcUiTkvmulMsB0F851wVcznn5KWvb3Pi6Ov8+9xn4Pr/8HdnoOMwVExXN1sd9H8ZiYnbelDjFt9kz1+fAbqPLs3PEhhBBCSGPgwocQQgghjYELH0IIIYQ0htGkrIhwOfTscV46iOVfi4XaNKq60UXvrrvuco6ruOXdg/MOxvg8mhy0E6il0MeoZ/K0XqrN6M4ecsl1qDF8EmPs4bN65w0783JpFpa48fBvIzR+iGzW1ZSkU+WlgTGanpCtvqomIPSsUe7hERIyT4umDidyV8ODrtUtAb2WbkONfkqMetPgRDH8PkY5Tw9iOnWEbN26dez38FJSZHFau5i6x4X9fYCeVLVpY2Ay1mVDz4JtGGTD3xNqfAghhBBCDLjwIYQQQkhj4MKHEEIIIY2htLEeZRVpOvwfmRFXRUSklRafT41zawG0L6YQk0LbJlHjs2nTJuf4EY94xOLft8j/impHMqF0MWCSTdCG7gQxgpgaVowfiKWAz57B+YXZYVjxAwcOuPdpu32xYcOGwvt6cX2KZQqSJDXW8j37+dz74AdRrGPz7PxwrRObZ0wat1GG/s/n3H5KJocvxNMDZeXt76EWZFm1vqmjsaoV2wkz0KjmtxKMweQWXb9+/bANgXhZll4OQY2Prhs1Pn6/FcdUq0MS+P0YF5s3bwoXqkmGseYCGp/VSNU2ZoG52NRqAozjQwghhBBSES58CCGEENIYSpu6cAveSiXRZDCcvDZv4Zb03Nycc9zJa/SjNj/gvnkXjvtZcVlsgtpF7M+72XbRRR2ffc+ePUv+LSIytd7N/q0zUGMm3skpNzu1k4Ejssv0lilun3bg3wF43iJXpi40aQavNVJ7mN9W6J8terjV+UYDpjrH9FVj6z64ZV0xpEYd62co9Y3u41DIA10WQyfgMWZkj8E2dRn9FHOTOlM+ZtHA08tk/VmOyCm+mXL89xw17Xb5+Uyb9kLrAv1zF/p0PAmASr1CUxchhBBCiAEXPoQQQghpDFz4EEIIIaQxlNb4tMFQrm3FacjEpmx5vrtuRLj4iLDWobKJ4RPdwm4BqYfWcKQ5PA9cmquLsxzuiXb+vLymxCPT+hpoU8+478BwdYdjfM+d1K13fmEW2pQv/beIDBZcfdDM/qG7+7rJKbeaBbdf0gl1X2g+uo/iOOj1hv2EepqDCwvOsdZgZT1Xv4R6La1ZmpycdM75eo1izQzaxX0tiD4QG10WP7PAZ5hb35Lhoo4ytZh0ECGUB6unJ8N3OTMzs/g3asYwJYqek0LhBPD9VNU6JoGQB4N++XD+1n1Rb4Z6pxWRZ2ImDwy/sVzNqHijGEkJ3iOHD225+r+e27zVSPweVJibiHUBDgI/jRT+LukwMfH7N9zxIYQQQkhj4MKHEEIIIY2BCx9CCCGENIbSGh+0FWsbHNopLZuzb/MfnQZgtYN2S9SCHL516+Lfr33ZS51zr33zW8y6k/XDugb7ZtxzmLIiggWle5mHOD4HDx50jvH8vn0HCsv2Bq5GQ48Z1GQsgPbGipODqTAQrQ3BsYjt379///AAtFAYw6iXDTUmsekhtE5kYmLCLYv/NNGXxpjtMc1Bz7ap62Pvm43Q+CBW34T0NbOzw/ejNTwifkwsPWbwnpYGC/sf9UDLRUw4/5j51orHtnzqGhdMhRPDxMbSP2GysM+dc3peTpFy1NHLtFaoj+tgxzMr/mazwLPG9COOY90m1PtNi/sNLwV3fAghhBDSGLjwIYQQQkhjKL9PCK7WqTZNoEu3t4NVbGqJ2NEN4mydBcLsW7twoe1huxHly2K9evtuenq6/D2BvXftdOuNaBOiTQZo3jk465ob8PxeZeryMki7ViWznn379jnH2hSGZjEJuDZa7tXe8ynzHG73muk6wCw2NeW653vZ5pV5Dk0rnulLZ9MO7BTr7yHk/m1tJce4s4dwTeTuR4gmTOyn/QeH4w3NkrOzbigF/Tz47JY5C9+VN74AzGjunDPmDS9sgRfGoF14LuY+tmkL616hfwdnNcJ4bCxfFM2hVamTognDwiwXowwrUZZBDbMezjnYfv27hN/3ZlkfrJ87PoQQQghpDFz4EEIIIaQxcOFDCCGEkMZQWuMTskmXxQ9FXb6eemG3VwatW8jBTom2SQ263MZwxx13OMd5Ul7KhWi3Yez/uQVXZ4G6i4HybfZ0CKn73rVGA23xlvu3pwvpuM9qjdOQbseyI+O1OgUHnkP9iae76BS/H0v3EtIL6PeF7w7bZNnUYzQ+IS2BpfGxUkmIiMzMDccX3gffnT6P4RBQ46P7GPsl5M6OkfSdczW0IN3J8hq/mJQVh5zG54jyRffs2VP5NlHpSIyySQ19XB1W4rezjsYHwflXf9M43x5dYlBwx4cQQgghjYELH0IIIYQ0Bi58CCGEENIYyos/QJOhLYaDgP0wNc6HbJ7aXorVoN1Sl82CNlkjthAuB+E40X1hS1ccDVMC7e2A/V3rCTDFQwxoy+6BCV33Wyiei6XZyAI5Exb6w2u9NBR9Iw4OEIr3EoOOGxXz7NgGHHuD3lB/0h9Aio0DbnuxL7TuAuu1NBmWviTE3OxCuNAqAzVlZUkgjlVv3n12U5MRoe2IifcVqjdXE0sdrVAMeSjfyJiok1JH7le+6M0331z9PiMiFHvLYlQ6o9hrq+qD8rT8PB38HnC+VXM3zuMPkJOD9+OODyGEEEIaAxc+hBBCCGkMpU1dllkphuXatg1hudXWwUp3gefQrXbTpk2Lf2/ZsqVyGx71uHOc449/4MPOseXmHIVn13PpDYZ1o3kKd9WtFAmWO3vsuxtI8bPHmPmQTmvYDnSfRixTV5S5JCJlhXcukCsmZoyMy1UW6+1nRhoNAzR1rQXyFfg36Vowdf2/Fz2t8n127NhR+dqqeHNZZs85MWlORtWmEDHzoK47G2F6jhhTVxnW3oxACCGEEFIRLnwIIYQQ0hi48CGEEEJIY6icy8CxuXlZKFaHjsdC6yO81gaab+kf8Nkt+yhqPTT79+93jt/9trc7x89+0QvtRir27t3rHOs22iHs7XcZkgRY7uyIdmdHm62l8Qm1H7HaXEer0suH7Q/Vg31R1T2/lsYnpNsJaIBWArPNSQ2X6BXRAK2+f3MOanRhHcxxXOO9vuvv3uUcH5T9BSXHR0jjg+erfrMhnYv1O1RHw5dI8dyFU0idsBGe3k/9XsRokO5h9X19hBBCCCFjggsfQgghhDQGLnwIIYQQ0hhKa3xM+9xImrJyjCsOSeg+qO2Ynp5e/FunrxAR2bdvX+X74rX6XWIbYjQzIY2PFccH0TZqK30F1hVKZzE3N+cc6zaHYuZYbfZiAOXFGqXQezf72LKvRwzbWN1dmgynhhjdV937Vq6rhhbE0imMMg0F1GyexXG7HBxqGp86c+a4qJOyoo5mr2rZYHlDHzcIpDTSUONDCCGEEDImuPAhhBBCSGPgwocQQgghjaFyri5NEmHLGyWjjAtQ9T4IxmjRtsh+7mo/elnPOd57YK8q6+pc2i03r1cMs7MHKl9bi7R4eNUJE2O+j0BMlqp6LtQzeW1QWgQvlhMU7WXlc8uYmoBsPGNYRCRNe4Xn6vR/LQy9h/VeQxoA69qgJmNMzzvKPEelWaZ4Rl5/V3yvIWZmZipfe6ixEjrWfmZrHcvWMw6440MIIYSQxsCFDyGEEEIaQ+WUFVWJ3cJaC+kvNJYrdig8ea83NC+gK2Yrdd3bY3jln7/OOX71n724cl1RjMnUZZLHpbAoXe0ITV0xtA2TB7oBj9LNvPK29AqZumJcWmOebblMXV54BOO9j80MsApNXW+86o2V77Nnz57K1x5qLNfvKE1dhBBCCCGrDC58CCGEENIYuPAhhBBCSGNYdo3PoQbaIjFdgeve7tqys8zVAzn2UdAKzWXzzvGLnvds5/ht17y7VHtFRHbt2lW6bC0Mjc+4sNIPiFTX24TSc6TGbetofCyNSShlhaV7ScboCq/xUj7U0JFkqaXjKQ4RUCdNQD3ssWiyTHobzXK50PvjcjS5Mp77rEuc47tkmea5NcBKaHxCc+aoUnBUgTs+hBBCCGkMXPgQQgghpDFw4UMIIYSQxlBahIE2wpUIgb1SxDy7F8MlK47vgvUsLCws+beIyCB37eAHDx40WmxT59ooGqTxMWPMjEnjk0r1WDxY77LF2KDGZ0lwbtDjeLn0Gcul8fHHz2g0Pss2r61BVuJ3FH+zYqDGhxBCCCFkRHDhQwghhJDGkOQl95TOf+xjjErsa/VWM96ujhnJImheMPa/UzDR4H11dm3Mxm630d3663TcNBRJa3iMKStyWKO2Wu42epIMj6//7GeNNrj8P2efU7psCO9dJtW3+iu3YYVMXblhalkpd/Y6Jp5xmb7qvOfEMCeuSsyQAYFvI+Lb8S6tmLqkjqkrNAZs12X32/mnz/xz6fs+6XFPLF12NTAuE45nKjXGQGh8jErWkkn1Z63TT/90w/8KluGODyGEEEIaAxc+hBBCCGkMXPgQQgghpDEsuzt7HftiSB9UFS+sPoD31eUx/DpqfvS12F5Mb9HvDY9nZmbccwO3DdPT03Cfan2BqTFGSb4Cmozl0vh44189K55bKY1PTFqKGOrY32O+Wf8+xTqq1RD2AskH1vh3x6k3ByXV3dmr9kVu5V0ZI6jxiWFubm6ELRkNVTVWdRhnOIqq44nu7IQQQgghqwAufAghhBDSGLjwIYQQQkhjKJ9TAPUCWruCcgfDbrlStnivTUb7JQ3pkHQ1oOcAzY9ju89bUNa9dqB0PHnmlm1BkwY99z76vuec/mjn3Ge/8mUp4p8/f5Nz/HunPbKwLBK0T0ekrBiZrTsgqKmjt3HuE6HxGRcrlYqhXiyeGvFFlBYENTHLk9QhjpjXg3q/LC8eT6OM2aL7sd9fMEqOjxu//PnSZc86/UznuC/j0yiOguXS0yCj/EbXWhyfMnDHhxBCCCGNgQsfQgghhDSG5U+fDaxU1vc66DZj+zGVhH6e+fl5s14rxQNuhVuguS2GUbq314i6X51A9u9Rmbq8evPl2XLXpolWwP14VN8SmpXqpJXB70MTGrf6vjHfw0ph97/dTzGvzjKF4TnLNI/fRujasufwPnUIzaGrnVGZ9EOEQrRYjOo3me7shBBCCCGrAC58CCGEENIYuPAhhBBCSGMon7Ji4Nr90mS4ZvLtcZaNEM6BOyLaFy1NRm65y4FLeuK5qKtHrxES3rOlgsYkV7btHO7T6/Xc48HQnTRpufW0W52oNmoee9ppzvHn//VfC8t+4Rtfh2tPr3xf/e6Wy7Yduk97TGkcrE9plCkr9PO1EvvfLZ2J4ZgJ9QtqMGI0GZbmLcb1OpBtRBJDvzXOkP2jqsvt08B1KhQE6u7yQK4SZ7aF/k5hHnQ0PqDJ8PV+o9FVfeXr3yhd9pG/c6pznCWrX9u1GsBsKTHjtE7KDec+WXmNWCx16+KODyGEEEIaAxc+hBBCCGkMXPgQQgghpDGU1/jUCTVvxJVYKUYV0hs1PinoLrSdfHZ21jmHsUgG2jzqaSyK4wNhm/xz1eMpfP5fv7L49+8+/BFR12pty3K99+BYHJvGp5hRanw005NTbtkRxu7Q8XZiUib4mpLybQqnrChdVRR15jaLOnFvempqwDb0Bq72BucKay6wtFwYd8WPlVRdX/Ov3/p2pevWQrymtUCdOEox37BzH2p8CCGEEEJWHi58CCGEENIYuPAhhBBCSGMYSa6uldLtmLZ5sEuOStMjYkfgyGAt2VPCnV7PtVfPzc259SbFugoR265vkUMeqYeecsri39/60Y9K13NgdqZ02ZUimCsqkCNptYHvWWtvOq124TkR1zYfiqeD11q6HcTUvAWOrTZ55418aHX0NOY9I+aNkJ5Gnw+2KS2Ok5YERGO6vKX/EXE1NBnMMXmO+prR5NsK8fAHP0TdMXTPtaUBylYkgWEg5l2A/qD4u0MNohvHB8fT6NYJdXO/cceHEEIIIY2BCx9CCCGENIaRmLrWIqNKoYDbd4NB8fYeurOjqUubxUL3iQFNXVWf/ds/+A/n+H7H37dym8ZFyPVyNZq6qqY9QPfuiYmJwuva7bZ5jFjmK8tMhmXxPjHpLbw25StjJqjK/Px89Wt7w/eMfdjPXPOOl9Ii1+b1XuE5EZGFhWGanH7ulvXfR7F5Aev9zg9/XFg2BLbZZq2ZupbHXOjd1zAN1Un3QlMXIYQQQsgqhwsfQgghhDQGLnwIIYQQ0hhKa3yyxHBDXSVpKFywvdXdUj1bd65cTcG1FF1A5+eHuh5tTxcROXjwoHM8yIv1DyH7aNW0CMceeZRz/Ms7fl362h/f8jO3rqOOrtaIZSQ1xoGVHmKcVLWxt1Nb8xKTisE6xvbhsdb4oB4F3eQ7nU7pNiBpRUliPX1c+ZQPCGqutBbHcnUXcfvC00n13HnEIvTu9H36vWK3ZRGRTGk2sJ4f/ezW0m1CTjz+3s7xwXxf5bqWgzrjaaXc2ceFNWemYwx/wJQVhBBCCCEl4cKHEEIIIY2BCx9CCCGENIbGxvGxiIlzg2X7EINCx+qx4m2IiGRZ+ZD2nragVX4Naz3fMduOdI5v23FH6Xp/+etfuXUdub30tcuH8W5XoVQN37OOk4NxYizNTKyexsJMexBIkRBTLx6nFV/QKOOHWM9jaZ+Q0Fyg4015sVMCsap03agrRHTMHHx3+r3efX5Y782/uM2s1+K+93J1hf0a6XhWgnoan9X9bLFQ40MIIYQQssrhwocQQgghjaG0qcvP1KvO1ckCkNjh8M26LXfdwG21GzreE13Dva19tRWL29m4ha3NEfsO7Hfb4Jm6ire3g+7qg/Kh2x1X5UC92w4/fPHvHTt3lr6HiMiCkdV3pdBbs55ZptbuaXH/h9JD6DHjlR2g6Wh4Pk86zrl5cHNO5offVtqG7OsD97vDcaCP8VwrKc64bpnm8Dx+O1Z6i6XuW5bQtrh5Hvofv0P9eL75CitT350UzykibtiFBTCf9xfc46zvjj1tvsI2Ifp9hFzf65ig7nPM0Ow9gJQbGfTFKE2T46CWqUsOLXd2y/qcp8Efreq3pamLEEIIIaQcXPgQQgghpDFw4UMIIYSQxrAs7uymS2vIzTZCPxRy8yzbphgX3FDo+ZmZmSX/FhHpdrtQ29D+W8ddPYRuY8hSmtWwpWpN0GFbt1auZ6Sox/HsxMaj1nH/RrdgC3zvbRjTlm0bz2l9WZ32e/cxND7YBuvZPXf11Nb7BSUDBdTR+CQRExBqlCx9DeqbvHe3UOySvnfvXvO+us97oA+yQO0Nvruf/d/y6WwQqy+apfE5tNzZzTkz/OtS/bbU+BBCCCGElIMLH0IIIYQ0Bi58CCGEENIYysfxqSERyA1bH0oPvLK5Los2/3ZhWdRKtEAjo+8T0j948USUfd7TNOTufecWVFoBaMMAnlXfBs9V1TeIlIgBpPBieahrtx7m6nR279pdut5du92yWNdyod8OjkrzXwFjGv9YdwZlIdyOM0bm513NGGo9Op1hnJ9+301vMRigLsS9T6oCHg0wlhDcZ6GvzqduWd2Gu8sOH6A3gHQv0Ea8dlT/SsPveaLVLjyHwZ1araTwdAofKcZOmldxreZB84I6nsFA97/7clAv48UOU/GcQhof/b33MrcNt/76dvNai3sdcZh7H+s3AD6uxEjXsSoINClPirWaWRKIq7Qa8+ZUpD1YvXom7vgQQgghpDFw4UMIIYSQxjASd/bQduQoXWnLEnKNjcHbGldb8JghW2djFwmHjNfofsT2Yx+Pqk/rbCXXMX1h2ZUyfZUl3E+WOdd+V7rumPeKJhDLJGulUhFZYkteHfthF1z0fULZwK30HP3UNQ2hmaZVMQRFaC7I00HhOZ2RXMTvx978girr9iH2he7z+Z6dnb3dnSq8J747PK/N7aH5R9/31jurm7aOPnyL26YsZt5b/t+HOgTDIxi5b4JpHNZWV6xZuONDCCGEkMbAhQ8hhBBCGgMXPoQQQghpDBEaH2ONlATCopu6hZB2ovi+XloH47oYzU8SSH2xoMLJz8669vaDB2ed4/n5Yd9gG6xw/jHpN+oQMq8PIjRAm7a6dv69u+8qfa3W/GA9SK2eMR4nxu3fp1V4Jklst85cXwvpIFpevaqRLXB9h4dbUO7THdAWzPfdb7afo9utboTbpo6hB8IxbaV0wbQN3c6Ec4waIDG/92LwW8I2Kc99T7+B7uuWxgefHevS1y707TQms2qOQd1gSOOjXaK9czDGb9+9U6pw5JaNzvFAyqdl8VlbwpbE0PDcXaB4nObGPCGySt33DazfUZyPVhPc8SGEEEJIY+DChxBCCCGNgQsfQgghhDSGynF8HFvkKjHRalt+jBzAi+sRcU+068/OuhofHcuj3XU1DDH23JWIhVQXrdWJ0ftg2ZDmp6mExoTWsqDWI3StjqHjxZSCeDtai4O6HNTT6PvitzOA2DZ4347SBMVo4EIxi0SF1sdvEuP4eNdmRswW4/vuZ3gft16t8QlpejDekdbtYT/9atedhW0Kgboe554jjOWmy45T81J1To1pkpcCKCJ9zVrAej+r+VG440MIIYSQxsCFDyGEEEIaQ2VTl7MdaZwTEUmNTa8st21S1m4kehW6mZLtNV2eD88nCZbFsPWQ6b09LI/b0AcPHjTvq/HTUgzv64XOH+FW8kqYKeu4ultlY81gtjPpuAjddTzb+fo9o3nE24I3xhee68Gg0W7paOrCY53+wh+ztvlH268987Rnoio2X1kpIPwUD8Xu+HgfKzwFXpsF/s053xvW5aWkgEvxWFPLtHWY+23lifF8ofnHCh9ixNQIvWfT1BJwO48xWel2BOdao2wemHCDprCKLJebvGWmXE1yDe74EEIIIaQxcOFDCCGEkMbAhQ8hhBBCGkNljc9qxNIdWWVj6hVx7froSorh5XXZsAvuUCux1kKXx1JH82Ndt9Zd3y0NiQiMoRo29JAexaI/cNukdTyeizoca72KpwcCN3nfjV7r8mzthwb70NPMqDb6ZRecYzxvpc3B0BbOdYF/c7Y6Qy2Ul3YCdJFV004gR2zd7Byj3sTW09jvQ5/30gflxSlF6syDo3SxX+uM61nN1E+r2KGdOz6EEEIIaQxc+BBCCCGkMXDhQwghhJDGMBqNT27HwclN+2LADhsRcsaxIyd4Du+jtQdon7bv01Oh9UOaBt0mHe/k7vugnsO+b1G9IUzbfOBZl2tlvEVpc+6qqPcR8TU/W0ak+TFCjZS42O7kVMefWibdAY6JGM1PYqRbQP0G1qu/AdSuYLwvrGve0MzExCHCNlmakiwijk9MjJkQg4XiZ71tR/XYPKjjqUooRouXbqTTWfJvEZGFOVcn2WT0NzDKODjj0ozGtGg1aaq440MIIYSQxsCFDyGEEEIaAxc+hBBCCGkMI9H4jNJ259VlmCatuDhoR8Z4G3lEfhi8VsfnwFxdMX3hxwApzum0muyj4wZ1OXU0P9a1W7csT8yf0LvTZ0O2eK1PaY/xny2W5gc1Pvo7RB2bGYcICMXxmbPi4kQI5Py5oLjPB3lE/q0YkR78mxOf9Ze7d0XUVcyRWzY7x3W0ambMFjiHMZomJycX/56ennbO7entdY7rxJgaFzEaGTPfVnOm8VUNd3wIIYQQ0hi48CGEEEJIYyht6srT4u27tMb+aYLmHbiNdkP3QtgnED5elYVI835I9aT4XDtx29TL3K1XM/VEyz3XVyktQiaPPFH3QXd8sV3hLZKk/Ba870JZ+tKxuUxuPWyTc7x7196CknHsvss1g6HpS7+v5dqhDoX+d8eeHUbC+GT9dwWH2mzT79vjfzDQZcunCfC+h8x1b0dzNaaP0Fhjr5UUm5BFRKyvA6c2z51dpY8wTRxLXKu5rYY5F0HzliYUvqIsmI4A6x303Hc5MxiaKWcOFJssRdzxFTJL2nOq/d7Hhe4L//u1r81WoSmsqsyihcuLVZSFiTs+hBBCCGkMXPgQQgghpDFw4UMIIYSQxjAWd/Y4/UnIfljNMIj14vFA6XZQs+BpieB59u/fv/j3LLjYojuvrqvXs0Oz67uslPu69y4j+n+52oyaH00d/Q9qfjSHbd3qHI80hMOY6jXvGaUlcolx27bq8eYJqHdhATU9Me7i6qrcvc7qY69NXuqb4tQMoX759Z595vmqbIfwDzHfrCY89orPm7rHEVLnt2Yl8OfT1dGOpsMdH0IIIYQ0Bi58CCGEENIYuPAhhBBCSGMorfGxYoKE7OBJbqyv8lBIe3Xsmd/hWnXfXNzYI+02pLDop+qc2w1oN0ZtTm9+qOsZ9NyUFW3oi1RpfnoBjUKeDNsUtAWj7VgFgAjpm8w2oNaj9JXjs7fHtP/wrdvM8zt376jUhl27d5vnj9h62OLflg5kKfLBcHyliVs28wLJqL/Xotk+Kz9GvPFkdCPGkdHvIPX6CWMYDY+9oRZKN6LO/99do4vFozlm21a7AIZCG5uQpM6/k4vnvsSIs7Rc2qHlYpDbvwG6J1CrhbGTVru+SZKRSIjHwqE1qgghhBBCDLjwIYQQQkhjqLwXNSr3ONzKtMw0uLVnWt/QfX2AYfdbhWX7fTfcOrqsazdbdLkdZGhiG3YxrjIt91fsl5AHcdX3EdpKjss4PR5ini1N7TD12w47ovDcjl13lr4PcmdENu2jjzjSOW61iz/DJLG/D4uYERFVb51v3zEr4bduP6tOUeOlLjDaWMcF+hc7RpMlPcSxh7vmLJ26oMmuyGv92WPCRCChudf6bRwl4/qtX0lWT0sIIYQQQsYMFz6EEEIIaQxc+BBCCCGkMYwmZUXQvGjZKgNrL2XXR1NjAtdqG2LIpVh7CaMsJAGX2/7A1fFoeyraVlEfNDExsfh3C9rQaoGOR4p1CQKpMOJsusW6l9z39XWo4wo/KqI0Ppldtm24zh592PbCc7/adXvpNoT41Z13VL72+G1HLf6d5H2jpBuCItSHeF53o5/GofxY9MfxQJ0LlEXS4umqjd+wquuHv/y1Xe8ycSykltDgo7f1XBAdt8DQRY7oGx1tmqLRhd9YbWDzQq3Vz5PAz6av+9QFxtdn1uuwdTtwbuXlootwx4cQQgghjYELH0IIIYQ0Bi58CCGEENIYVm9M6d+g7b0Y16BOTASt8WmBfgbr1TodEZFut7v49/r1690bzbkxfxx7dcB2jekKXGw7eFVb9ygt5CsRcyM2PUdqnPdiw6iyxx5xjHmfX9zxf837jopbdlTTq5yy/WjzfJTGBzRjMbGeUkNThp8zfpff/8UvS99nJbjv9sOd4xz0ZnmrvBbKSblRI/6JN+8Z84Q1/sfLofvvb++7iphxQ6mU9PcReld6HIzqtyN0X08auIpiMh26I44QQgghBODChxBCCCGNobSpK/HSs4/GSNLytr9gu1VtF7cwO61RbwqZYS1XwKwHLumZ6yZsuYTidvwkZIHXDAJbybmxDs1MM5hIYm5XDgrPhIwUmCF41YHbvzX6KQm49mvQZHO/o4pNST/+9a9K1zsufnT7yrdhLfKgY10TJ84FjukiQjgQMi+EwkyUvw+E8TDmsiwbzxwfIpCw3L7WOOf9ZAGByBdjInBTyxxUw1SE6WA0MW/ZG7fGOE7RH38V/ZRwx4cQQgghjYELH0IIIYQ0Bi58CCGEENIYSlul7XDZ40PfN3RPy13OunYwcDUwCz03RQWmodDHeC1qfhxCGh/DDpsYqRbuPl/NgBoyGy/Xex4VrVA/GWkcaoXdNy49+WjbFT5VIgdsww9/vTrSLRxKnH6/k5zjgfHysq7tDp4b34/lHo7fFc4xaWc0kUawDThfxbi3jwpfJ1L8rEEtlKUxWYUanzqzaR13cKufQnP8ak8LUgXu+BBCCCGkMXDhQwghhJDGwIUPIYQQQhpDaUOylS4igUAMls0QtUIhbYq2L+K1Oeg5dMqHYHoLFWMghzg3aAfH46L2idh2WFSf+OHMi69NAvEfrPtizBndZkujcPfFtmZmHIRtysVtSgNWdB3Hp14EdbeNqepIf0zY1zrfAJR94DFHFbcAymKI+5b6vL95y88L61krnP2QBy/+HaU7gPg0+UTxtd63D2G5Yu4bo6vodty0OGLE8YlpAz4PxgNz5oIaWo7gtbmh1TRiCwWxUiYE/lm//DNbWFdk/XbWma+seGzhjCirJ9XEqOCODyGEEEIaAxc+hBBCCGkMXPgQQgghpDGMJlgE4OlpalA1dgG2AW3dOvcY2lW9fDxwXteF7bPi+IT0QImxDkU9E2JJpdK0+HmCGp8xYY2RcOyg4r4I5eqSiLhEMTGk2sZ9Q+NL67dC412Pr35mx5BqqX467aT7ufeEMWHGnwK8OESqn1qpK4qZmHC1K1pP549/0OyhHrA7vDakA9F147dh56ty31VPAu8uKdZ2IdZ9vHg7dRJYKfC9hu5b9hwS/GaV4MarFzVYI4obs1Jzm9MGfK9i/7ZUJTRv1IkBFIOlGVtN8YC440MIIYSQxsCFDyGEEEIaw1hMXTHg1p+3jW5c20YP9aR4my1tufX2jS25LHPDx2Og8VaittxT91ynDf6vitxwUf1NAeNksRtqkATC1GszX/laRkqSGCEPguk38P0MaQWcVFtV3fMD1+n3gWO4Ddd6285JccoKi0n4ADodd+yl6fDz9r4HuI3VL2guwRAU+nyn03XOoYt9rtITYL3tlmsW801hxmjNikNqtFrF4RxE3HQRnlk7YPa26rXOh8wAaMaMuY9V1jJ1eWE7IlK65EF5g2HqAnfpUZl/QqaugdHkUaWzwGpaGX547uGowgvUScczMow5fqXhjg8hhBBCGgMXPoQQQghpDFz4EEIIIaQxLIvGx3Kli3Hf9cKvW2k0UB+A9xkU2x897QHoFPR9UFeBx7qNQbux0vj47t7ucYwdvNUu1gf1I9xbl4s6bUgDa/mgfEiXtdKPwBixND54T0vjE9Mm1KJZoRWwvZ7Gx9PxDOsKpZnRY77bnSo8h3VhvegKj2iNjzf+zXFcvn+x3tn5ebcNEdoJq6zWFS1VT2akGKiVssLQQlmpeUL3DbfJ0PgMDl2Nj/+sdnonK1SKnZYIv9HqD1DnWud5A/PaSv7WcMeHEEIIIY2BCx9CCCGENAYufAghhBDSGEak8Qmtn6rb8vr9hcW/PdsjmBBzFeY9aWNcErCX6jgZA9fenmJZaP705DBWCdpWfRu6CmkfMJ2mKpaKX69bNjdi/vg22mL9A0qJRhlmvHLMkxr29VZgrLUi0qk4aQ88e7tXurBsCx7It8dXa1OeB9KYqPt2Ulu35qW7cGLzYBoK91rdJtT44LPqukJpMrz0EFo+4OmoiuOBJRATx0o70ev1nHNTU+7zILq8lcpDRGRhYTiXhbQ3On6QpQNZCl0eh9YAPo9UxRbDdC915gI/XpDqG/h20sB9LayyIaWQNRVYc3WdOXGh52rG8LcmbRX/JMdob0ap8YmLGafmp9Dv/jKl0VgK7vgQQgghpDFw4UMIIYSQxrDsKSuCGcpx+ytily0mK3yMayZmmO50hlv0uDVuuYtaYehDxLgrRpm6Qlk0jC33EJaLdx2sdxdKWYHpI6x6LVNXDGjq8sf8aLb20SSl/12D50IhG/R5HP+YAkKfb7exbPF9Qt+rFRYArzVrAlO2NY490xxa1+Habndo9kYTFB7rZ8d+8cqqZ0fX95B5XdeN5/A96/Mh01aM6dofp8Xu7Gm+tkxdMfMgtm9yctI8X5U6Zkgk5nfUmhfzVbyvsnpbRgghhBAyYrjwIYQQQkhj4MKHEEIIIY2htMbHsvvVcX9LMrD3poZdPxDqX2slPMujod/w9AKuSV26bVcf0e/rRrm2+gzurI8TzBMApMr1Hdsf0kK5bs5gmwd30Uy5/WO/INrV2g8RYBM1DiI0S1a9aUDjo19BLbfNCDwJD6awMK71vjtVGHU709PT7rVq3KJOBzUlMVqcPHev1TqXkD5An8d7hvQobSNkAM4j7k3t96z7IqSfGUixa3zg8zbHuKW76Af0QFb6C0tzKCKSqTYNAjqddlqs00H8Ph4ee1fiBxLzHZp6vwDGh2fJ7qJmCXjng5Y3s7t1V9Q3hS7TZVGjt0Tp0m2wpI95KH7LCsIdH0IIIYQ0Bi58CCGEENIYuPAhhBBCSGMYSxwfXzuRFZ5LIvIT+HFWYtpgxw/S+JqGYptnTHyXUL1mTIRIm7oms+LTQNm4+ECjY1T3DY2nqk8Q6n8r5k84TUb5uCB6DPnxdSDthNLIhOKHxMSJStM2HBfHC/L0c2lxLBv/PhhTR+nNAhofV/Nmx8/SmplQPBo81voa1N4kg2LtTWgu0McYKww1PdiP+jyWtQjFd4n5dsall1spRjX3tYw4YiLV4/HU+X2og6m3DOjlNLH9W/d5uONDCCGEkMbAhQ8hhBBCGkNlU5ezlQypGLwsxSokuWeKSOyt5NTY3vZc3yPMJY6bPGbIheMBbNF1VAZdTIHQTxecY737jZmRMXttbrikY1oDfHa9rej1E9xHb8n7G6+W+S1uOzUxzlm39bb9oahlVvLepeEOjiSm+2X1re5UMOyC7dJqlx1y8OBB51i7lYuIdDvDcZqD2aXVQXNVcb+hKcU3X5X/91Nb3afdSuFccdZ3ETsFykSneCoLZR0fDHqF5zDNjJU+wkt1kxWnysA+nZmZcY7bnaEZc2rCfa+zs7PO8Tx8IPPzwwzgobQTTiZ34/sVcfvRCYmxFEYW+AzMkgPvCy82CVpjzc8IH/TxLjw1wG9W37eGm3boyqoZ2NHMilhpTOrQgWzyus8902+MNCUilVIVsxd3fAghhBDSGLjwIYQQQkhj4MKHEEIIIY1hLO7sMcTYNNEubrmphuq1bJ4YKt/XGhTft9Uu1iUMwC7u6QWS6q/DtH1H2FZjzodcfZ02RNjf67gqaj2ZSGS4gTo6HqP/x/Wvi43r1jnHqPGxCPWx5aKOx/p78Vzq4VhL1fA767SK60XwvbaT4l7G9AO+HqIjRfRAG4XfrO0K797H0dMEUtBYMox1gfeuU8ugHsjSguA5TwsyGB7jeMdrvXQj6hj7sJ8Xa+BC/aSJDUXQMs4lWXFqkjp6vxCWjg2x0i5Z4DcZ0gdZWPNIaC4wfwPGnO2COz6EEEIIaQxc+BBCCCGkMXDhQwghhJDGUFpU4ukfnDg4YLvLIjQaRqh5EZEsUfZHiJmTGOIVjMnipRFoq1gR2H5PJ+JqAAZSbBO1tCztlptiAG3ddXQvSdJSf9sxEfT5dru6JgbBZx8MimMtxDzruMKtW7GdgmVjtGle/KnyfW6dC2k9RN3HS//QccuiJkOnuMDUGPg+tOYH74OpMjI15j2djpSP4+PF+5Li94O6OyuNQ+i94rU6nYSOn3M3xXOBp4mZdOeYTM0xobgrnnZFaSkmO+67Q82Pft65nhuDzJufkuI2hTQm+j44njppeZ1IjMYnpF3pGykf2oPi2E8Yj81qRyiOUkxcIkR/s6FUMbrfsN6FBfe9W7GeorDEpRKY19Pxiny440MIIYSQxsCFDyGEEEIaAxc+hBBCCGkMY4njY9nmY7HspS3DjtlpdwrP3X2stDeBuD1oL82SYpunqV0BmyfaVq1rsQ1+jITh83o6KSP/Fmp8sN6i65YCbeq5EheF7O36fCjmT51cM3a8nYhcbxGaH9T4hOouC74r1PhMr1+/+Df2/+TktHOM34CuG+9jxfXBZ8E2DZQmBst2kuJ4OiL2e88HhnYiseN0xcTXQX2K1vhgv2RZsYbP0gqJiEyo94PPbcUSupviGEyIrhvj6SC5+j5i53grNg8mDEwNbVqMxiekVRlEaHGc+SkQx2dcMcpQL6fHsaebgvc+Nze3+DeOF9Sm1dGeOlqoXmTuNA01PoQQQggho4ELH0IIIYQ0hmVPWeFtKYIPcYpbmeq0t60mxhYcblnjlqk67ARMXZ4pzHC/tLZi5xfAjRa28/R2PW61hsJ/d7tTxe21zDAde+0bY1byQ94X14PvUm+vhrZaLXNcnbU8mrr0NnvIrdbayu+Y7XUJpQ3QfTE57W59d8CspLe/sf0TE3CtYRKx+9s2H+LzdNrFaTXSzDZrtFrF7sedtrvVb+F9D5lh8kjs9zHRGn5rvRaa0Ird5rFf0OydKBd8bFMP0nP0E0h945iK3Pv2+2B61Ck3YF7r9SAtxcLQHOePS/c+UeZbw5yFY89KYxJLzzCvx7h0+78XE4XnklZgvlXF64QWQbNla0J93+CqP9m2U0noZ/flDMZvYSCszbhMgmXgjg8hhBBCGgMXPoQQQghpDFz4EEIIIaQxLIvGxw5nbmtIrFDbqeHyFgqhrvHC38O1eNwfDO3xofQKus0Z5o4ALNs22lY9F3vDJde0i1t5GqAdIZf0mD6PqSfOFjw6jY/ux1A4AatsO9Av+hmwXktbEApTr7VS1nhZ6rjquwx9O5rYEAGJ0rbge7dCUAS1EsY3kEf2mwY/F2sce7q8tjXv2d/HQOk7QqEI9LWh1CRZr3g8oTu+9w2o58Oy7U6xJjE0JurM821Vl5XGZC0QE14jZn7F8yGtpj7uzWEKl9FRVwPEHR9CCCGENAYufAghhBDSGLjwIYQQQkhjWPY4Pj649kJb5dBGnaYY2xyuVLbLwcDW7fT7OoaDwDn3fywsYIj4oY06pPFxQnjnAX2AinuANlpsQ7vtHus2h/RAjg3dCBePhOy7Pvp92PqgGDuyFVcG41eE3o/GCM+0REyZ8qk9Wklx/4eutd4Hhpq32uinR7FTDujYQ5hyo2/oWrBfPP2cFccENXuYeiU3zhlSwTS19UD6u4zVNplxTKz0CtimdvH7CMUW6ueuZqanjhcy9733BeYyVVcLtE6QzUYWEj3HQOwg73MoTvkQE4snJq4VEpqfdE0h7Zb1PjxSe64z21Qxjk+dOGOhMW+lE7Li+iR5+X6I0RmVKR+COz6EEEIIaQxc+BBCCCGkMax4dvaY7LteKgBwg9Tbbugy6bepeBsOt/OwLr1JGrMdiVnScZuwN+9uS2vQ/IbbxVZ6AizrhLRv2+13ti4984K9PazNlDFbyYhlwvHalNhreWvLGk1duo2htA0WIVOXlQnd+j60yVUkziW318Ns7W4Ki0SNJ+/dGfXGbJt729dJeZNmzLyBWFv9nkk2sZ7WDueP5iBnfsrAPOXNMUPwvaJpa3Z21j1eGJpA0cSJ93He7cA2Y+hj33Rqmx4G/eF5nI+y8q8uGMZAExqLmNZIY5lwwia06qkmqpq6Ytz+Q3MMHh84cGDxby90gpXCYlA+y/tywx0fQgghhDQGLnwIIYQQ0hi48CGEEEJIY6is8XHc4+BcjC0vVNYKPW/pRnrzxfb1u4+LXdLRDu6FY28XuwYi2j4fDHdvGLtjXMd9+65bUtvY84CGYSDFGp+grduoepRjRJOm5Ye0Z9uOcGe33jva0CfabpoALz1BhK5Ngzo1fB6dniCUsgLHiOV+PImpDbS7aw9eOkrplDu759acdqAsuMb3tT7IbfAAlEe617xUMaBlSZU7uzfWAm7/uh/x3FzPnYP0PDLIbe2Nfu94Dl3UZ+fnCuvCa72wBWqMzM4fNNvktB/m05C+rLdguERL8YcX6+Ycgz3zjemerer6nxjNTwwxfRyn8bHvU3Xeq1P2HrjjQwghhJDGwIUPIYQQQhoDFz6EEEIIaQyVNT6uvc7WP1ixYGK0EyGNj7ZBz8254fzRvrhv357Fv0P6h7k514auxSAxuqNQ2O1UWqXLatv83e0YXuunh3Db5GhQLGGL2PZ3xLcVl09/4VwVeB92G6rbwVsR8TcsezW2v53Gxc0oqtdvg/uedbwNEZENGzYs/r1582bn3NTUVGG9IiLdbvF9e8b33UKdjkdxHB8cp6gB0u/H6xc4tFKgePNTVhzTK2YsWvofEYiD07c1Pvq+GKcHNT6YukQfHzzo6nZQizM9Pb3494G9+8x69byBcwyWRXKlX5yZmXGv7RfHMApRJ2WFlXrFqquO1ibHPCAR2HNB+Xk6NJ+OKm1REhGgaVz6pSK440MIIYSQxsCFDyGEEEIaQ2lTl7W1H9pmszLDxoTa9reSi0Oq4xYvbtHpkOt+6Hy3/ZhVHTO/W/dx6s0N1z8RaVtmPlijeiksJlQah5a9Pe88X8iVUYpNBnXMANbWZp30FpgWJMYFf6FfbPKoQzuQsqKqW+f0pGuu8t3ZW0v+LSLSamEb0LSq+8Kt10yv0HJNKX4m7uG79MeLe22SoIlWhWHAuSAvDhGQ53bo/JZ6Ps/k1IF+wbQz6hjNwl5KGlX3/IJ7H8+sNKHczBfQrdw1dS3A+b6a2zJwqZ8DM5M2H2IaCj/chnrWQLodb4woUzya7szvOWABqWPqGlQMqVHLLBOTnwMYlakr6L4ecR+rrn6gSSuZwoI7PoQQQghpDFz4EEIIIaQxcOFDCCGEkMZQWuNTx64Zo2HAcP+aULhsK2w62tC1HsJPZ2FrcSyvZ9RZuOG+i6/Dsl4/ZLYuxLKXWm2SgCbGIuQWaYU6j2l/nCamuA0hUI8SY9c3U1gE3OStay3XUhzvWHZycrLw2hhbPY7FVuIe69AKlkYPz4dSd+B9c0NjkkDIAH0+TcuPPbxn5un7BoXnQ+7slou9F4JikJYui3qaTJ33Q1sUg8/u6bOy4vaHQjSoS737WJqx0NdbRydSNS3CSmpTiqiT4mGUKSuc62poG8cNd3wIIYQQ0hi48CGEEEJIY+DChxBCCCGNobTGBzMbOPa5CF1FjAZAxLUloz3R0wA493Vt0N2uG0p/bk7HncD1H7a/OLR+yF7qpjKYEAu3j8Ee2grpRCw7rZF+AHU6UI0T8ydSP5PodwtFMTaSHgfmo4TATAYx9uzM1oKYtzVjMNn1WDqeqvcUcbUTnt4HYuTgsdZ3oNYD06Xo8xNQdmICUquotCwTE+73kKaVM+hImhdrA3WajLvvA/oTFb+pB7FsWphiAMZt1lfaD5hHvOwpqYpn1gbdFPSTbiP2E37rGH9HkmE/YgqRVgrxzOaHOrGJjjtGUHuj+2Z+DmIH9SDmEtw31Xq5ia5btl38jYa0aAMjRU0w1U3FGEC1UlbUkLXEaItGNXfhfbGsH6drSJbY89qoNJRV4I4PIYQQQhoDFz6EEEIIaQwjcWevE4I/JmUFMhiAG6extYnn9Ha955KX2uaRDM0ERlmo2DnynlVdGnL/9o+r2Yc6LXdL2ntWKd52DpuRil1yrbAFdUxdoa1ka4wkgffulI3Yek0DW75Vt3G7XTAZoCu2elZ0fZ+ccs0naE7RdVvnRMAsltpmMW0CwXqSpNglXSQwZjIrw73tep23h+e9rXuw8WNf6H7FPu718fmUK3/XvY+ZBgTr7bl9im2SwfB5MHUPHut3gPfBLOr6u8Q+tEKJ3N3m4fPhd5UO3PGv33soREBifPAh01Ba0dRVh+UydY2SoMmwgEHAxK8JzYFV5QCF9Y20NkIIIYSQVQwXPoQQQghpDFz4EEIIIaQxlNf4VPOWHiu+6XG4jmu3Xbt3nhdrZDxthNgpKwZGIPUss2zdbnd7Yd5zQ38C+gdP42Nci3ZlfS1kwljCfbTY3i6pFU7ABttvhj5fJtt2HW2RmXYiUG9V+/XU1JRzjFqPiYnJJf8WEZnoTDvHk931hXVhvfht6fP4LXmu761h2Q7Ui99z23PjLp6uchzI+hx8z5jXpD2h5gLUn2AYBhin7fbQxdvTn8A3q9PmDDI3hU6vDRofdSm6q/d6dh/rNqOOCo/1u8O0Pt43qtzQ8ZtEjQ+2eXZ2trBsO7FTlzhtwFQlNTQ+S/yAlL+2InU0PiuV4qFqX4xS40N3dkIIIYSQinDhQwghhJDGwIUPIYQQQhpD9RjximDqghr2uaqht1FrYMWc8XQtiRX+PqTxsXQvdndrjY8fs8SOAWRpfDJor6Xx8ft7WK/fT+VDkscQihsxLvt7rVQZBiGNT9XvI6Sn0doh1BHhtRi/xtL4oKhP14Vl8T5Tk1OF53CM+ylpVFoT/J6z4u8b03F4cWTU31ZsLRF/bOrwO77Gx61L902vb8fxSVQaB9TLzM+7/eKlrBgUzyNWLCR8d1jvgu7SQFwx7At/DKmyqNsxvgdsf52UFas9jk+dtBOjjHtj9aOVUgQ1PnXiolHjQwghhBBSES58CCGEENIYuPAhhBBCSGMorfGxdCJ1CNWj7YJoa7Rshl4+HozFk6tYEoFH8eynSbE+yLathvpsaL9GqyrG+PEeXbXRs78bbUoF67ViCWG9hUV/U1dxASvvV8g+Xcf+Pi4dTwwx7ce+cN4BxFHyjhV+Diqwv+PQVHWhlmty0o0JpOPxpCnE7QHdkVNXijojN8YMkqvvfxCImaPHfAvixMTk9MMYQNY8iO9qcp0bK0nreLpZcV41EZHO5LDfdAwcEZG5OVcvg+cHC8P7oE4Hh4huE8bT2XrYZrjv3OLfGPOnA7GF2h23Lyamhs+DeqbZeXc8OXm9oP91G0TsGbWV23kIxdBqYrwgSxMalbcvIPjTUrVc7N+WxJrzR6iJSY15HNF904LrrD4tUXNE2TDc8SGEEEJIY+DChxBCCCGNYSTu7CtFnRQJ2i0ytHVpnY/bUrTXmdYWfFrDtdG3iunz9hap9Xy47V/nfVQl2uy1DKau5Qotj8+OJoS2Mmd5aQLA9GWFf4gxPYa+JasuHP+WKzaeS410FpKVN0d77rnwSfrvdnhfvBZDRWiX7hTmAnx3GgxTkOeuSRD7rW8ZgMC13+oLa0zgeOov9ArLLnWswbGoTSJZbrfXGnsxWClzQkTdN1DWOmv+Plgm8ZpUDksS6FPdxuVKS3QP3PEhhBBCSGPgwocQQgghjYELH0IIIYQ0htIan0TAD9IIX+5fq/QC6HYa4c4esgO659E2DGW1+dHzcgTbpKdbKG6Dlc7Cd1J3STJDOxRhsvX6qYa914r67lWbm4eliXnP0bbsZbYljxrHLg4u6X3QQ2jVxTzqQPru8WBQrNeK6eMYW70V7n6pY6058TR7abHLep7Y9SbGXJZDvYkfR6KwXkyJ4NYNGiVI6ZCkwzlokLrzka/ncOuaF+3eHvi3rZIPoYbEc+1X81O/B/NrbqfR6M/ODNuLz54Wa7u8d4UpN0BrpEENojeHqtNWKg8RWwMUM+bt3wcxf1fruNETF+74EEIIIaQxcOFDCCGEkMbAhQ8hhBBCGkPlOD4x9kUr7k0dTYBld7ViHsTe14+LM5p4NVYbQnEwYmILYTyRsvWECGo0Iq7VhGJqWDFmDnW7t6V5w37T3wDGiTlw4IBzjLFidMyZCdCfoB5C39fTYBgEtYHGN+DFzDG+d2wvlrXSmOC37ul4MBWIUdZ9nkBsJKXQwnrwfXjfXX9QeA51hvrd4beEsXp0+7tdN5ZQp+X2A6aW6GdKs+SlLih+z0kgzph5DjWHI9KfLXfMGTJ6uONDCCGEkMbAhQ8hhBBCGkN5U1fixW5Xf4bSmyvXUjyX2yYcvS0dys5ubUFGbXNCNmp/G73Y1bcFW7N5VlwW/SvzWiG8dRthezgr3nIfCIaAL3/HcBvVe/fKhvq4HF6ag0DKeMxyPw5we74W3rtTpzLXFJGBTXPQH147N+u6F7dbrrlkasGta1Jl37bSveBxjCnbNwWhiRNNtsP7ZFhvWpzaIMMwEjBEtKnLH4e2+cSa+qxxkAbnPdWnGJoD3nO3BQ+krFAYpgDRJlA0dbVaOL6K680HdrqR6elhpnrsYzTDLuRDM1m9Ob58qJTQbwuJB8eTNcfXkcBUgTs+hBBCCGkMXPgQQgghpDFw4UMIIYSQxlA+ZUUNN+FQOHCNFTY9ZPfTbUQNQIxt2MtgEZGyIkar4tdb3E8xbudRqT1G6P7tp8oY/hljQw89a62UFWscp28CLt3zSqeDLsRtcMPet2+fczzVHbq3o6s7ujlrMB0Bul7rNoZCEVjvFq+1CKfUKV+v5wofoedy6g5ob6yQDaHvQ5cP6bPqzCNW2RhtTh2sEAch3YilH42BqSTKYX1b3nc15j7kjg8hhBBCGgMXPoQQQghpDFz4EEIIIaQxlNf4YNgMZa+DkBSmLc+3u2L4cozloW+MOhG8VumBoE2o+UlyIz4QXDsqO3iIwWAYzyJsi0ddUmaUHRMY2wnalDh/Q1nsZEXmxdoB7YeWKGGsiNyOJ5Koi8cWK2KU/e/FjSnWNPipPobjKeu5upz5BffTn+gVpxxAjU+n7aYr6HaHbWq33Db1+xhfR//tvps8Ry0LzCOWtssrq48D70OPJ7uktKDNqGnSmP+qbGP73X5rDbQWqg1F3bJayyUikg6GMZtQy4VTvh0nzW1jOx2Og1QwlhOMkQ7EYFI922q5MaUWFtxjtw3l9Yr+b4t5qfsbVkOTNMr51ko9hFharlHGxan6fKs5FBJ3fAghhBDSGLjwIYQQQkhjqOzOrrfZBrntihZjKrJcDv2svuUzNFv3jc2+boU6twi5ylpbr01ykQy6Kqu+iXFrRlbDdnAdQt+OleUeXdLxeGZmZvFvNJegqUs/e7vtuq9jOoKWSpWBJrQQ4wpjEDM/WRnAvXnPvqt5NjVCgGCbsI/1+8LvIyY0gZcORrUJ6w2FJtBhDbANs7PufS1zj+WeHwo1YKVQCI0nprCIZ7nTUMTAHR9CCCGENAYufAghhBDSGLjwIYQQQkhjKK3xycF1eWDqLNAtcvi3b0u1XdQHg746Z5fVdWFZz/3bMOmGwtBnubKLe17m5cNye/2WGDZnz3V8NKToZg74fTwkC2qhisPuZ95713XZ6/Ek1QMKdAjo+m57DUPZ0ehGRqv3KbaT54LfCqSlUK77nrZj3nUhnm+5Qoted3JYFnQgTv+LSEu5Znc6rjal3XbfpZau5HmxvuTu8/h/dF2gvWm79x1kw7rTJKCtsycDt01ei1qqKI69HhyrlDoRn3NIy4jflta9YDiHFNrYVu75OH4whIkeB6Ex7mkf02Ldzqi0H94cUyMtiNcXyxTSxKoL22Clf1mNWO/d0l9h2VGw+nuLEEIIIWREcOFDCCGEkMbAhQ8hhBBCGkNpjc9yYdkB64QvL3tdmfPaHhmK4xNje40JV758epTiFAkxdeO1qD1wtSt2n+VZsW0YdQnLxXLF8XFiPQU0VppQzB+MBaPTIOiYPiIi69atc4513JiFjqsd8tJddLQOz26/F5clLe5ja94IaWJidBUWXh+jDqniGAm1H+vtdodxljAdRNYvjoUWillktT+kkdF6m9B9nFQMud0Ga45BYrRFOD9ZMbFi7hkzBuqkrIitaxyMUpYz6vZzx4cQQgghjYELH0IIIYQ0Bi58CCGEENIYInJ1ocHOMuBZ9rhlsjV6cW/QrqzOBINqFD9rWMNTPh+MBcbfwCZpU3jcfQLP7vRjzBhwT/tNQt2UinEitj0dolnYbQhcverBcaxjjyTF+ZxERFIp1gDgsMV4TVrzo/U+Ir5uZG5ubvHvdsvN1aVzNImItNvDelFHYeWGuruNxeNt0HPbqJ82zzBGCMwFEWPCizdixCLKBu45a66w4pu1WqhNseOZJSpuEeZZ6w3ca3Wfh3Rg+n34sYXc1g8ghk5vMBwzVn6wOmAftiG2kxePyojjY+mQxplH0QlRNsKyVqiqcVHr927McYm440MIIYSQxsCFDyGEEEIaQ2V39tUYItvZWotwXRynq1/Vur3rxuYaaPdTnS1eO1UJllWhCMBt2XcJLXnTJViO0PPLNZ6wtWjWSFX6lND3im3Wpi505UVTl75vb6Jnlp2YKE6F4aVXQBfpiJQJrju7WxbvE2P+9FzLjWtTeEP6eXGsodu/JmQStMw0Idd3KwSIZfrCNuB7xnfbV2a/kGu446ad2XOBNa4xLIbloh7j6l5nngiFoNCt8McplDW+AS+9RcSUNDpTnv3urFAw43a/X32rF0IIIYSQMcGFDyGEEEIaAxc+hBBCCGkMy56ywneDtN2RLTtnAq7MqWMXBHsumFZdl+mQLgSuNdtcfS1p2jWNcP0i2Bdgm4drtZ05he7NM+wLnUoC3YADOF0RsBs7WgOsCNpk3DgJdb9pn69uu3fbjPWM598XUxNd59jTHqg2oRQipP3Qp9Gdem7OTWExMTGcRgaZq/HB415/dniPlvsd6XpEfBfpfj6sKxe3XjM1QA5aoQHqOaSQkDYqM3RsA+O9twJ6h1Zn+GF6+gz8Rq1vdoCu725ZrXNB7Q2mMdHnUdODx34IhGHIg5gUHAnqTTB9kDFnDnL8fcCUIsX6RZwH9aUY/sD/7op/Hzo44QKJanMSmI+sZ8dTqTMXVJ+PQu/OKQuTsZeCxni+GB1VFT0Qd3wIIYQQ0hi48CGEEEJIY+DChxBCCCGNYVk0PqOy13nnLLt+qE3BNBWqLNqVTRuprZ0oS/x1Rr8ZNvQc0kN4Ifmz8ik3rPgPoWuj3rtVj6d38EoUnqlj+44ZE3XQ94nRSoQ0PdYxaj/wPWs9h05fIbJUyor2kn8vdR9PS9cuLos4Y0/s+ECpIQzD+3j9pLrCHwPlY2L5cXGM5+u557DPu5PDmEBWepGljt02uNdasZ0wbg9ea72v/qA4hQVqPHE8WXrLbGDPbWmn+FuytFCIr/ExYoUFpjJ7PLmY+leMS1Q5pZGL14dGDKkkGc1v4Tjgjg8hhBBCGgMXPoQQQghpDKVNXdZWeciUZW2bx9zX2yozlm2e6xxuUatdwlD740KUr5Spq3jLF93Z4UZuWSMjcyj0gHffzDB1GS6fwWfPi198ksS8q8j7VmZ0/76w0o1Y+JnPQy7dOms3mqAgHUF/aNboQZb02dmDznFHuWmj+3p/4LrJoylsbnZ43xizZJq69XhZ35WLcSh1gbfVr95BhlObMU7bXvvdNi30ik1Qed+90cEZt49bExuH9fTd9zEz55adnRuGF7BMmCLuu8T3imVxjAyMLPbWb4JlesfzsakWtCkmJp1C6LfF+izR1OX9rip39tAYt85bpq5Yk37VeXEAHYHm0OVoQxHc8SGEEEJIY+DChxBCCCGNgQsfQgghhDSGJI8TsBBCCCGErFm440MIIYSQxsCFDyGEEEIaAxc+hBBCCGkMXPgQQgghpDFw4UMIIYSQxsCFDyGEEEIaAxc+hBBCCGkMXPgQQgghpDFw4UMIIYSQxvD/A1Kg5AaKjKiAAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "End of video or cannot read frame.\n",
      "Processing complete.\n"
     ]
    }
   ],
   "source": [
    "while cap.isOpened():\n",
    "    ret, frame = cap.read()\n",
    "    if not ret:\n",
    "        print(\"End of video or cannot read frame.\")\n",
    "        break\n",
    "\n",
    "    try:\n",
    "        # Remove background\n",
    "        masked_frame, _ = remove_background(frame_idx, df, frame)\n",
    "\n",
    "        # Choice of the \"search region\"\n",
    "        if consistency_counter < CONSISTENCY_THRESHOLD and first_time:\n",
    "            # Search in the upper polygon\n",
    "            upper_polygon = compute_upper_polygon(get_points_for_frame(df, frame_idx))\n",
    "            upper_mask = np.zeros(frame.shape[:2], dtype=np.uint8)\n",
    "            cv2.fillPoly(upper_mask, [upper_polygon], 255)\n",
    "            search_region = cv2.bitwise_and(masked_frame, masked_frame, mask=upper_mask)\n",
    "            roi_offset = (0, 0)\n",
    "            preprocessed = preprocess_roi(search_region)\n",
    "            circles = detect_circle(preprocessed, frame_idx)\n",
    "        elif use_roi and search_roi:\n",
    "            # Detection in the ROI\n",
    "            x_min, y_min, x_max, y_max = search_roi\n",
    "            search_region = masked_frame[y_min:y_max, x_min:x_max]\n",
    "            roi_offset = (x_min, y_min)\n",
    "            preprocessed = preprocess_roi(search_region)\n",
    "            circles = detect_circle_roi(preprocessed, frame_idx, r_approx)\n",
    "        else:\n",
    "            # Fallback in the full masked frame\n",
    "            search_region = masked_frame\n",
    "            roi_offset = (0, 0)\n",
    "            preprocessed = preprocess_roi(search_region)\n",
    "            circles = detect_circle(preprocessed, frame_idx)\n",
    "\n",
    "        # Detect cicles in the search region\n",
    "        # preprocessed = preprocess_roi(search_region)\n",
    "        # circles = detect_circle(preprocessed, frame_idx, r_approx)\n",
    "        valid_circle = None\n",
    "\n",
    "        if circles is not None:\n",
    "            x, y, r = np.round(circles[0, 0]).astype(\"int\")\n",
    "            x_global, y_global, r_global = x + roi_offset[0], y + roi_offset[1], r\n",
    "            valid_circle = (x + roi_offset[0], y + roi_offset[1], r_global)\n",
    "\n",
    "        if valid_circle:\n",
    "            dx, dy, dr = (\n",
    "                np.abs(np.subtract(valid_circle, last_circle))\n",
    "                if last_circle\n",
    "                else (0, 0, 0)\n",
    "            )\n",
    "            if (\n",
    "                last_circle\n",
    "                and dx < POSITION_TOLERANCE\n",
    "                and dy < POSITION_TOLERANCE\n",
    "                and dr < RADIUS_TOLERANCE\n",
    "            ):\n",
    "                consistency_counter += 1\n",
    "            else:\n",
    "                consistency_counter = 1\n",
    "\n",
    "            last_circle = valid_circle\n",
    "            lost_counter = 0\n",
    "\n",
    "            # Draw circle\n",
    "            x_roi, y_roi = (\n",
    "                valid_circle[0] - roi_offset[0],\n",
    "                valid_circle[1] - roi_offset[1],\n",
    "            )\n",
    "            cv2.circle(search_region, (x_roi, y_roi), valid_circle[2], (0, 255, 0), 2)\n",
    "            cv2.circle(search_region, (x_roi, y_roi), 2, (0, 0, 255), 3)\n",
    "\n",
    "            if consistency_counter >= CONSISTENCY_THRESHOLD:\n",
    "                search_roi = update_roi(\n",
    "                    x_global, y_global, r_global, frame.shape, ROI_MARGIN, scale_factor\n",
    "                )\n",
    "                r_approx = r_global\n",
    "                first_time = False\n",
    "                use_roi = True\n",
    "        else:\n",
    "            lost_counter += 1\n",
    "            if lost_counter >= MAX_LOST_FRAMES:\n",
    "                use_roi = False\n",
    "                consistency_counter = 0\n",
    "                last_circle = None\n",
    "                search_roi = None\n",
    "                r_approx = None\n",
    "\n",
    "        # Display result\n",
    "        display_frame = cv2.cvtColor(search_region, cv2.COLOR_BGR2RGB)  # preprocessed\n",
    "        clear_output(wait=True)\n",
    "        plt.figure(figsize=(10, 6))\n",
    "        plt.imshow(display_frame)\n",
    "        plt.title(f\"Search Region - Frame {frame_idx}\")\n",
    "        plt.axis(\"off\")\n",
    "        display(plt.gcf())\n",
    "        plt.close()\n",
    "        time.sleep(1 / fps)\n",
    "\n",
    "    except ValueError as e:\n",
    "        print(f\"Skipping frame {frame_idx}: {e}\")\n",
    "\n",
    "    frame_idx += 1\n",
    "\n",
    "cap.release()\n",
    "print(\"Processing complete.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c26281d",
   "metadata": {},
   "source": [
    "IMPROVEMENT: Rescrict the radius of the ball when we are detecting it in full track (camera calibration)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcdff092",
   "metadata": {},
   "source": [
    "[This code is implemented in Detection_3.py]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
