main.ipynb 144 KB
Newer Older
lucas_miranda's avatar
lucas_miranda committed
1
2
3
4
{
 "cells": [
  {
   "cell_type": "code",
5
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
6
   "metadata": {},
7
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
8
   "source": [
9
10
    "import os\n",
    "os.chdir(os.path.dirname(\"../\"))"
lucas_miranda's avatar
lucas_miranda committed
11
12
13
14
   ]
  },
  {
   "cell_type": "code",
15
   "execution_count": 2,
lucas_miranda's avatar
lucas_miranda committed
16
17
18
   "metadata": {},
   "outputs": [],
   "source": [
19
20
21
22
23
    "import deepof.data\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
24
    "import tqdm.notebook as tqdm\n",
25
26
    "\n",
    "from ipywidgets import interact"
lucas_miranda's avatar
lucas_miranda committed
27
28
29
30
   ]
  },
  {
   "cell_type": "code",
31
   "execution_count": 3,
lucas_miranda's avatar
lucas_miranda committed
32
33
34
35
36
37
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
38
39
      "CPU times: user 16 s, sys: 2.93 s, total: 18.9 s\n",
      "Wall time: 4.92 s\n"
lucas_miranda's avatar
lucas_miranda committed
40
41
42
43
44
     ]
    }
   ],
   "source": [
    "%%time\n",
45
46
47
    "deepof_main = deepof.data.project(path=os.path.join(\"..\",\"..\",\"Desktop\",\"deepof-data\"),  #Path where to find the required files\n",
    "                                  smooth_alpha=0.99,                                     #Alpha value for exponentially weighted smoothing\n",
    "                                  arena_dims=[380])"
lucas_miranda's avatar
lucas_miranda committed
48
49
50
51
52
53
54
55
56
57
58
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Run project"
   ]
  },
  {
   "cell_type": "code",
59
   "execution_count": 4,
lucas_miranda's avatar
lucas_miranda committed
60
61
62
63
64
65
66
67
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading trajectories...\n",
      "Smoothing trajectories...\n",
68
69
70
71
      "Computing distances...\n",
      "Computing angles...\n",
      "Done!\n",
      "deepof analysis of 109 videos\n",
72
73
      "CPU times: user 33.6 s, sys: 2.48 s, total: 36.1 s\n",
      "Wall time: 46.6 s\n"
74
     ]
lucas_miranda's avatar
lucas_miranda committed
75
76
77
78
    }
   ],
   "source": [
    "%%time\n",
79
80
    "deepof_main = deepof_main.run(verbose=True)\n",
    "print(deepof_main)"
lucas_miranda's avatar
lucas_miranda committed
81
82
83
   ]
  },
  {
84
   "cell_type": "markdown",
lucas_miranda's avatar
lucas_miranda committed
85
86
   "metadata": {},
   "source": [
87
    "# Check tagging quality"
lucas_miranda's avatar
lucas_miranda committed
88
89
90
   ]
  },
  {
91
92
   "cell_type": "code",
   "execution_count": 5,
lucas_miranda's avatar
lucas_miranda committed
93
   "metadata": {},
94
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
95
   "source": [
96
    "all_quality = pd.concat([tab for tab in deepof_main.get_quality().values()]).droplevel(\"scorer\", axis=1)"
lucas_miranda's avatar
lucas_miranda committed
97
98
99
100
   ]
  },
  {
   "cell_type": "code",
101
102
   "execution_count": 6,
   "metadata": {},
lucas_miranda's avatar
lucas_miranda committed
103
104
105
   "outputs": [
    {
     "data": {
106
      "image/png": "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\n",
lucas_miranda's avatar
lucas_miranda committed
107
      "text/plain": [
108
       "<Figure size 576x396 with 1 Axes>"
lucas_miranda's avatar
lucas_miranda committed
109
110
111
      ]
     },
     "metadata": {},
112
     "output_type": "display_data"
lucas_miranda's avatar
lucas_miranda committed
113
114
115
    }
   ],
   "source": [
116
117
118
    "all_quality.boxplot(rot=45)\n",
    "plt.ylim(0.99985, 1.00001)\n",
    "plt.show()"
lucas_miranda's avatar
lucas_miranda committed
119
120
121
122
   ]
  },
  {
   "cell_type": "code",
123
   "execution_count": 7,
lucas_miranda's avatar
lucas_miranda committed
124
   "metadata": {},
125
126
127
128
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
129
       "model_id": "442c10a74fcc439c8fa501b575586966",
130
131
132
133
134
135
136
137
138
139
140
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "interactive(children=(FloatSlider(value=0.5, description='quality_top', max=1.0, step=0.01), Output()), _dom_c…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
141
   "source": [
142
143
144
145
146
147
148
149
150
151
152
    "@interact(quality_top=(0., 1., 0.01))\n",
    "def low_quality_tags(quality_top):\n",
    "    pd.DataFrame(pd.melt(all_quality).groupby(\"bodyparts\").value.apply(\n",
    "        lambda y: sum(y<quality_top) / len(y) * 100)\n",
    "                ).sort_values(by=\"value\", ascending=False).plot.bar(rot=45)\n",
    "    \n",
    "    plt.xlabel(\"body part\")\n",
    "    plt.ylabel(\"Tags with quality under {} (%)\".format(quality_top))\n",
    "    plt.tight_layout()\n",
    "    plt.legend([])\n",
    "    plt.show()"
lucas_miranda's avatar
lucas_miranda committed
153
154
155
   ]
  },
  {
156
   "cell_type": "markdown",
lucas_miranda's avatar
lucas_miranda committed
157
158
   "metadata": {},
   "source": [
159
    "# Generate coords"
lucas_miranda's avatar
lucas_miranda committed
160
161
162
163
   ]
  },
  {
   "cell_type": "code",
164
165
166
167
168
169
170
171
172
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
173
174
      "CPU times: user 2.92 s, sys: 250 ms, total: 3.17 s\n",
      "Wall time: 3.19 s\n"
175
176
177
     ]
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
178
179
   "source": [
    "%%time\n",
180
    "deepof_coords = deepof_main.get_coords(center=\"Center\", polar=False, speed=0, align=\"Spine_1\")"
lucas_miranda's avatar
lucas_miranda committed
181
182
183
184
185
186
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
187
    "# Visualization"
lucas_miranda's avatar
lucas_miranda committed
188
189
190
191
   ]
  },
  {
   "cell_type": "code",
192
   "execution_count": 9,
lucas_miranda's avatar
lucas_miranda committed
193
   "metadata": {},
194
195
196
   "outputs": [
    {
     "data": {
197
      "image/png": "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\n",
198
      "text/plain": [
199
       "<Figure size 320x220 with 1 Axes>"
200
201
202
203
204
205
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
206
   "source": [
207
    "heat = deepof_coords.plot_heatmaps(['Nose'], i=0, dpi=40)"
lucas_miranda's avatar
lucas_miranda committed
208
209
210
   ]
  },
  {
211
212
   "cell_type": "code",
   "execution_count": 10,
lucas_miranda's avatar
lucas_miranda committed
213
   "metadata": {},
214
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
215
   "source": [
216
    "deepof_coords = deepof_main.get_coords(center=\"Center\", polar=False, speed=0, align=\"Spine_1\", align_inplace=True)"
lucas_miranda's avatar
lucas_miranda committed
217
218
219
220
   ]
  },
  {
   "cell_type": "code",
221
   "execution_count": 11,
lucas_miranda's avatar
lucas_miranda committed
222
   "metadata": {},
223
224
225
226
   "outputs": [
    {
     "data": {
      "text/plain": [
227
       "(-2.735058755246037, 45.89004523470992)"
228
229
      ]
     },
230
     "execution_count": 11,
231
     "metadata": {},
232
     "output_type": "execute_result"
233
234
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
235
   "source": [
236
    "tuple(deepof_coords[\"Test 10_s2\"][\"Nose\"].loc[0,:])"
lucas_miranda's avatar
lucas_miranda committed
237
238
239
240
   ]
  },
  {
   "cell_type": "code",
241
   "execution_count": 11,
lucas_miranda's avatar
lucas_miranda committed
242
   "metadata": {},
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "fd74db019c394c33b7c234d237564043",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(FloatProgress(value=0.0), HTML(value='')))"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
266
   "source": [
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
    "# Draft: function to produce a video with the animal in motion using cv2\n",
    "import cv2\n",
    "\n",
    "w=400\n",
    "h=400\n",
    "factor=2.5\n",
    "\n",
    "# Instantiate video\n",
    "writer = cv2.VideoWriter()\n",
    "writer.open(\"test_video.avi\", cv2.VideoWriter_fourcc(*\"MJPG\"), \n",
    "                         24, (int(w*factor), int(h*factor)), True)\n",
    "\n",
    "for frame in tqdm.tqdm(range(100)):\n",
    "    \n",
    "    image=np.zeros((h,w,3),np.uint8) + 30\n",
    "    for bpart in deepof_coords[\"Test 10_s2\"].columns.levels[0]:\n",
    "\n",
    "        try:\n",
    "            pos = (  (- int(deepof_coords[\"Test 10_s2\"][bpart].loc[frame, \"x\"]) + w//2),\n",
    "                     (- int(deepof_coords[\"Test 10_s2\"][bpart].loc[frame, \"y\"]) + h//2))\n",
    "\n",
    "            cv2.circle(image, pos, 2, (0,0,255), -1)\n",
    "        except KeyError:\n",
    "            continue\n",
    "\n",
    "    # draw skeleton\n",
    "    def draw_line(start, end):\n",
    "        for bpart in end:\n",
    "            cv2.line(image, tuple(- deepof_coords[\"Test 10_s2\"][start].loc[frame,:].astype(int) + w//2), \n",
    "                            tuple(- deepof_coords[\"Test 10_s2\"][bpart].loc[frame,:].astype(int) + h//2), (0,0,255), 1)\n",
    "\n",
    "    draw_line(\"Nose\",     [\"Left_ear\", \"Right_ear\"])\n",
    "    draw_line(\"Spine_1\",  [\"Left_ear\", \"Right_ear\", \"Left_fhip\", \"Right_fhip\"])\n",
    "    draw_line(\"Spine_2\",  [\"Spine_1\", \"Tail_base\", \"Left_bhip\", \"Right_bhip\"])\n",
    "    draw_line(\"Tail_1\",   [\"Tail_base\", \"Tail_2\"])\n",
    "    draw_line(\"Tail_tip\", [\"Tail_2\"])\n",
    "    \n",
    "    image = cv2.resize(image, (0,0), fx = factor, fy = factor)\n",
    "    writer.write(image)\n",
    "\n",
    "writer.release()\n",
    "cv2.destroyAllWindows()"
lucas_miranda's avatar
lucas_miranda committed
309
310
311
   ]
  },
  {
312
   "cell_type": "markdown",
lucas_miranda's avatar
lucas_miranda committed
313
314
   "metadata": {},
   "source": [
315
    "# Preprocessing"
lucas_miranda's avatar
lucas_miranda committed
316
317
318
319
   ]
  },
  {
   "cell_type": "code",
320
   "execution_count": 12,
lucas_miranda's avatar
lucas_miranda committed
321
   "metadata": {},
322
323
324
325
326
327
328
329
330
331
332
333
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train dataset shape:  (133517, 13, 26)\n",
      "Test dataset shape:  (30003, 13, 26)\n",
      "CPU times: user 35.9 s, sys: 1.05 s, total: 36.9 s\n",
      "Wall time: 37.3 s\n"
     ]
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
334
335
   "source": [
    "%%time\n",
336
337
338
339
    "deepof_train, deepof_test = deepof_coords.preprocess(window_size=13, window_step=10, conv_filter=None, sigma=55,\n",
    "                                        shift=0, scale='standard', align='all', shuffle=True, test_videos=20)\n",
    "print(\"Train dataset shape: \", deepof_train.shape)\n",
    "print(\"Test dataset shape: \", deepof_test.shape)"
lucas_miranda's avatar
lucas_miranda committed
340
341
342
343
   ]
  },
  {
   "cell_type": "code",
344
   "execution_count": 25,
lucas_miranda's avatar
lucas_miranda committed
345
   "metadata": {},
346
347
348
349
350
351
352
353
354
355
356
357
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfAAAAFaCAYAAADhKw9uAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAACdHElEQVR4nOydeZhT5dn/PznZJplk1szCsMOAIAqKKFhFZHFBpWqttlqxVLv31VZpoVVbbau2Ynl9f9paq7VVoa51b6FVBFFRNlFRFFmGdYZZMluSyXpy8vsjk0wyOclkZjKZGeb5XJcXJufknJPMSe7n3r63JhQKhRAIBAKBQDCokPr7AgQCgUAgEHQfYcAFAoFAIBiECAMuEAgEAsEgRBhwgUAgEAgGIcKACwQCgUAwCBEGXCAQCASCQYgw4AKBQCAQDEKEARcIBAKBYBAiDLhAIBAIBIMQYcAFAoFAIBiECAMuEAgEAsEgRBhwgUAgEAgGIcKACwQCgUAwCBEGXCAQCASCQYgw4AKBQCAQDEKEARcIBHF4/EEONbbh8Qf7+1IEAkEKdP19AQKBYGAgBxXuXvM5b3xWR02Lh4oCE+edWMZtF01GpxVrfYFgoKEJhUKh/r4IgUDQ//z6tV38fdPBhOe/ddYY7lg0JfsXJBAIUiKW1QKBAI8/yOu7alW3vb6rVoTTBYIBiDDgAoGAeqeX6hav6rbqFi/1TvVtAoGg/xAGXCAQYDXqSZbm1krh7QKBYGAhDLhAIMDpCxBU1LcFlfB2gUAwsBAGXCAQUGrNYXiBSXXbiEITpdacLF+RQCDoCmHABQIBJoOW804sVd22YHIpJoM2y1ckEAi6QhhwgSAJAZ+XltpjBHxDo4ArWT+p6DMVCAYmQshFIOiEEgyycdVj7Nu+GYe9gTxbCZUzZjFn8Q1I2uPTE/X4g7z5eb3qtjc/r+fnFwaFFy4QDDCybsCDwSC33347Bw4cQKvV8rvf/Y5Ro0Zl+zIEgqRsXPUYO9a+Gn3saKiPPp675Lv9dVl9Sr3TS02LR3XbsRYP9U4vo4tzs3xVAoEgFVkPoW/YsAGAZ555hptuuonf/e532b4EgSApAZ+Xfds3q27bt33zcRtOL7XmUJGkiG1YgShiEwgGIlk34AsWLOC3v/0tADU1NdhstmxfgkCQlLbmZhz2BtVtzkY7bc3NWb6i7BAuYitT3XbeiWUifC4QDED6JQeu0+lYvnw5b7zxBg888EB/XIJAoEpuYSF5thIcDYn5YGuxjdzCwn64quxw20WTAfjvrlpqW7yUF+RwwZTy6PMCgWBg0W9V6Pfeey///e9/+eUvf4nb7e6vyxAI4tAbc6icMUt1W+WMWeiNx38oWdPpX4FAMDDJugf+8ssvU1dXx/e+9z1MJhMajQbtcVrZKxiczFl8AxDOeTsb7ViLbdEq9OOZu9d8HjeNrLrFG30sppENHhSPB7mhAV1JCZJJva5BcHyQ9XGibrebX/ziF9jtdmRZ5jvf+Q4LFizI5iUIBGkR8Hlpa24mt7DwuPe8Pf4gC/53I9UqlegjCk28cfMckQcf4IRkmboVK3C+uR752DF0w4ZhnT+PsmXL0OhEx/DxiJgHLhAIONTYxpz73kq6fePPzhVtZAOc2nvuofnJVQnPF163mPJbb+2HKxL0NUKJTSAQiGlkgxzF48G57k3Vbc4316N41Hv8BYMbYcAFAoGYRjbIkRsakGtr1bfV1iI3qLdGCgY3woALBIL2aWTqef7hBTlCyGWAoyspQTdsmPq28nJ0JSVZviJBNhAGXCAQYDJoOX9Kueq286eUiwK2AY5kMmGdP091m3X+PFGNfpwiShMFAgHQIeTyxmd1HGvxMKzAxHknlgkhl0FC2bJlQDjnLdfWoisvj1ahC45PRBW6QCCIw+MPUu/0UmrNEZ73IET0gQ8dhAEXCAQCgWAQInLgAoFAIBAMQoQBFwgEAoFgECIMuEAgEAgEgxBhwAUCQRwef5BDjW14/MH+vhSBQJAC0UYmEAgAkIMKd6/5nDc+q6OmxUNFTBuZLpnOqkAg6DdEFbpAIADg16/tihsnGuFbZ40R40QFggGIWFYLBAI8/iBvfFanuu2Nz+pEOF0gGIAIAy4QCKh3eqlRmQUOcKzFQ73T2/uT+N3QVBX+N4t4ZA9HHEfwyGIil+D4QuTABQIBpdYcKgpMHG1ONHLDCky9G2YSlOH122D3Gmg9CvkjYNJFcP7doO27nyBZkVm5fSXrj6yn1lVLuaWceSPnsXTGUnSS+OkTDH6EBy4QCDAZtMyfXBr/pMaPRt/InEn5vZNUff022PIwtB4GlPC/Wx4OP9+HrNy+ktWfr6bGVYOCQo2rhtWfr2bl9pV9el6BIFsIAy4QCADQRP8viKH0Nczj7id3/B94w/FT7t16L7Iid/+gfnfY81bji7V9Fk73yB7WH1mvum39kfUinC44LhAGXCAQ4PEHWfd5PQCG0jUYizehNTSj0YTwKPa0PFfF48F/+DCKJ8Y4umrDYXM1Wo+Gt/cBdred2iTHrnPVYXfb++S8AkE2EQZcIOhHAv4grQ1uAv1c5R0tYtP40Vk/U90nmecakmVq77mH/ZcsYv+FC9l/ySJq77mHkCyDpTyc81Yjf0R4ex9QkFOASac+iavMUobNbOuT8woE2URUcggE/YASVNj0wj4OfNyAs8mHtcjI2GklnHVFJVIS0RSP7MHutmMz25Iap54SKWKrdjUi6VtU94l4riPzRsY/v2IFzU+uij6Wq6ujj8tvvTVcsLbl4cQDnrAQDOaMvYdYHvroIdrkNtVt80bOy/jnJxD0B8KACwT9wKYX9rFzfUdo2dnoiz6efdXEuH2zUU1tMmhZMLmUx99vRQkUoDU0J+yj5rkqHg/OdW+qHtP55npKb74Z6fy7w098sbajCv2EheEq9D4gVf47V5fLD0/5YZ+cVyDINsKACwRZJuAPcuDjBtVtBz62M+uy8ehjqr4j1dQRItXUAMvPWJ6x61JCIQgZkJ0noi3elLBdzXOVGxqQa9VzzXJtLXJDA4ZRo2DhvTD/jnDO21LeZ543pM5/e2UvLd4WrAZrn51/yOF3Z+XvKkhE5MAFgizjbvXhbPKpbnM1eXG3dmzLVjW1xx/kxR3VAPjrL8LXeBZBfyGhkIZQoJCvT7yGpTOWJrxOV1KCbtgw1WPqysvRlZR0PGEwQ9G4Pv+Rt5ltlCfJrYv8dwYJyrB2OfxpJjxwWvjftcvDzwuygjDgAkGWMecbsRYZVbdZinIw53ds6241tWoleBocbnLj8kUK6bT46xfhrrqZtv0/xbX/Zq4Y9m2UozUJx5VMJqzz56ke0zp/HpIp+7lmk87EvJHq1yTy3xmkn/r7BR2IELpAkGX0Bi1jp5XE5cAjjJ1miwufR7zJGldNwr6x3mRIlqlbsQLnm+uRjx1DN2wY1vnzKFu2DI0una+5ykyjkAGNr4DvfPoaoSUPsr++TvW4ZcuWAeGct1xbi668PLoP9G3xXTIi0YL1R9ZT56qjzFIWrRsQZICu+vvn3yHC6VlATCMTCPqBjip0O64mL5aiHMZOs6lWod+79d64HHiEaydfG82B195zT1wleITC6xaHK8G7oMnlZ/pdbyQ8/92dL3N51btpHVfxeJAbGtCVlCCZTANCyrQ/Fg9DgqaqcNgcJXGbRgs3bg+nSwR9ijDgAkE/EvAHcbf6MOcb4zzvWGINYWdvUifpUDwe9l98CXJNopeuGz6c8f96rctQ9qHGNubc91ZYPlXnJCRbMQbg4Tfvo9yTWJGeznHTWXgIBil+dzjn3Xo4cVvBaPjhZuGBZwERQhcI+hG9QUt+SeofOp2kY/kZy7lp+k2q3mTaleApMOk1GEtfQ2v9DEnfghIowFY9lhJPS4+O21Xx3U3TbzruPeJ0FmeDFoO5X/r7BfEIAy4QDBJMOlOCiAp0VILL1dWJ2zpXgidh5QcrMcS0jmkNzbSNaMJuMVDmSqyY7+q46RTfqb2X44GeiPQMSrLc3y9IRBhwgWCQE6kEV8uBp1MJ7pE9bKt/O+F5v17D1okaFu1IfE1Xx023+O54pDsiPYOFzvUNQHgUbBb7+wWJHEfLQYEgcwwUjfJ0KVu2jMLrFqMbPhy0WnTDh1N43eJoJXgyPLKHT+o/odFbr7p99QKZVybOQFtR0a3jDtVWrq5EegbL/RQhpc59hCz19wsSEUVsAkEMAzn8qeoF9WAfiC+MO+Y6hgYNikpFcdBfiFT9U7bcPA99a1OXx012DrXiu+OR1gY3q3+1WbUrT6OBb/xmVpc1DwOJ3nY3CPqW4/NbJBD0kIEY/uxOj7dkMnVZsAaJ8qwhNYsDyM4TCfq02GUNo9M4bixdFd8NBtJdEEWIiPQ4GxPrBjqL9Ax00tK57wehHkEHIoQuELQzUMOfkWlfcnU1KEp02lfdihU9Ol6qCvGQIhEKaQj6C/E1noW//iKGFZgoteYkPV7A56Wl9hgBn1d1e6T4bjAZ77RCxypERHrU6CzSM9BJp7tB0L9k1QMPBALceuutVFdX4/f7+cEPfsD8+fOzeQkCQVLS0SjPdvizL7ygVBXiaBTch76N4h0FIQMAeTk6jEE//sPxnqgSDLJx1WPs274Zh70BS7GNYdNOYv43v0eu0dKta+otmRRs8cgejt71G+RnXo4+lzAiNQVnXVEJoCrSM5jIRHeDoG/JqgF/9dVXKSgo4L777qO5uZnLL79cGHDBgGEghj8z0ePdmVQV4kqgMM54S0qQC996mn2v/JpgbW1c+H7j6r+xY+2r0de67A3sfXMD6w6vY/iXz81KrjuTam+RY72zfx0/XXOUMpV90lk0SVqJ2VdNZNZl4wd1H7hkMmGZM4eWp55K2NZfOveCeLJqwC+88EIuuOCC6GOtdvDd1ILjl+5olGeLvvCCIhXiaippsvPEqPEG+Panr3Fe1btEkgcRT1RWguyrPaB6/JLDCi98mPlxp2pkctRq5FhlzSFsDvV9urNoSkekZ6ASrbt4663wE5IEioKuogLrgvlddiEIskNWc+C5ublYLBZcLhc33XQTP/nJT7J5eoGgS866opKp80ZgLc5BowFrcQ5T543ocfjTI3s44jjS47GffTXta+mMpVw7+VoqLBVo0TIstwKD6xz89RdF9zHKfs48tkv19faNb+Owq+dAzV4dv30C8h7+J26vM25bJtvzMjlqNfZYzRaw56nvN1RCx5G6i2BEnlcJdyhYzp1D+a23pjkgR9DXZP2vcOzYMX70ox9xzTXXsGjRomyfXiBISabCn5kM7XY17asnqFWIf+VP22ikw+AW+RxJpVR1x2qxjj8VZ3NTwjaTX2Z4c5BR77mo/v09TLjzd33SnpdJtbfYY/n1GrZP1HDx9sTK/KEQOk5Vd+Ha+DaKx3PcfwaDhawacLvdzvXXX8+vfvUrzjzzzGyeWiDoFnHhT787LaWp2EKqB3Y8kLHQrkano/zWWym9+eZutTSlQ6RC3OMPcrixLW5bkzGPBlOB6jATY1kZlTNm8eEbiSMlyxxtaNvlJUJvb0XxeNj02pGMt+dlUu2t87FWzZcAhRl7w+F0w7AK8voodNzdVrW+pi/qLgR9Q1ZD6A8//DAOh4OHHnqIxYsXs3jxYrxe9daT45mu2m4EA4SgDGuXh6cuPXBa+N+1y8PPxyArMvduvZfLXrmMS166hC+//GVe2vuS6iG7G9qNJdLj3Rc/8oeb3LT544VcfDoD7w+borq/df48zv3GYqaXt4LeB6EQJl+AMQ0tTKppjO4XrKvDW1PXJ+15mVR763wsRdLwxHlaln5Hy4YVX6Hy3//KeOi4p61qfU2k7kJ12xBJIQwWsuqB33777dx+++3ZPOWAonPbTZ6thMoZs5iz+AYkUdA38Hj9tvhpS62HOx4vvDf6dOdCqtq2JC1aDNxBHt5A2GgYZT9FPgdNxjx8OgN/PSmc5rrUvR+poT4ufK9xHGZu4aeckavhw/UVFLQqUc87gq68HJ8hH2dTlep5e9uet3TGUgBVtbdMHesHM5Yi9UE1fSTPHKE7rWp9SW+19QXZQ0ipZpENjz8S13YTYfrCLzN3yXf74YoESUlz3rFH9nDZK5ephnHVqLBU8OL5T6Nvdg2YkCnAxwfs/PtHv+DMY7so8bTQYCrg/WFT+OtJi1AkLa9cfxqTc/zx1xzzGdXusNK8x5pw3MLrFlP80+U8/evNqu151uIcrr5jZq8r/DPdB97XynGZmOHel8Sp/3WquxAFbAMH8ZfIEgGfl33bN6tu27d9M2dffR16Y3K1K0GWcdWGRySq0Xo0vL1oXGpRlE5ISogbN+ZS89BVXUqi9jmd8vqGv/6Ry6vejW4u9zRHHz8y9TJy8swYysvjjxEzE7rslHDxm7PahNymRVdkxnrJV9vfW9+35yUbtdrfx0rGQM8z92XdhSBzCAOeJdqam5O23Tgb7bQ1N1NQrp53EmSZoAzv/TE8fUItPpU/Imz4SF1IlavLJc+YR31bPWWWMm7cmMv41z8nkuHsl5BpUA6nBnavic5wVsadj2bTh6pvddaxXTxx4kVYjHr147XPftZ8sZby045SOrsQuXwOust/h2Tp8MiPF3WyTDFYVM7S1dYX9A/CgGeJ3MJC8mwlOBoSxzZai23kFhb2w1UJVHn9Ntj+WPLtJyyMVqOnEkW5fMLl0TatIk0uNX+6ErXypKwOhlDJ68tv/51QrZruGJR4WijyOTjU2EZpriGxta7TTGjJUo5BpVL/eFEnyxQizyzIBMKAZwm9MYfKGbNUc+CVM2aJ8PlAwe8Oe6dqaLRw2reiXmeEVIVUOknHyLyR+A8fTh4yPXYM17Ej5I3r42lnSd6bzqSgs4DsSnxJg6mAZkMebZvtPP33L5L3cEdmQnfBYFYnyzR90d8vGFqIIrYsEluF7my0Yy22iSr0gUZTVbhlTGU2Nkhw0wdJDVWq4ifF42H/JYtUQ6Z1+fCHn4xg9vgFfasfnuK91e7Ip3lPbsLzL407m72VX2WGPzGEPnXeiH4bsXo8MdD6wAWDB+GBZxFJq2Xuku9y9tXX0dbcTG5hofC8BxqW8nCOW7X6fGQ0961GquKnVCHT7RM0HPLXcqiHQi9pk+K95Z9t4Un5TGYc+zxahb552BQen7KIJS71xeW+HfXMuGgMJotBdbsgPUSeWdBThAcuEHRm7fL4PHGEmd+P6//uLpHWHMe6N/Efq8GeFzbeq+ZLKJIGCLeZvXzpy303O1vlvQUUiY9Lv8rXD1+MVgnF9YEXBDXc4DQioUl8P4QImf1MnTmW2V+diC/k6/P2K4FA0IEw4AJBZyKV2l+sjVZqc8LCcO5b2/ug1eH6vXz7qStotCj49fGGUYuW1y5/re/amGLem9JylI3NJ7HPVYSjLUirlEtV7lg2FX2JkEYCjR+91sW3msrJV1KnePwn1vKf4U/0WvddIBCkjzDgAkEy0tRA7y6pxF8y6YEH/MHkFd9+Nxv+9id2bNiY8LoP805i6+QWdNbPkPQtnFn1NU6pTz27oNVo5/lpv0fWBqLPXTv52j4fJyoQDGXE8lggSEaaldXdJVXrWXc1vNVIZ/JXICSx79PPVV8/3vc5nxYcIKgNr+23jHsOjeRlXNM0LP5CNCrhdIuvEHMgD4e2Qwd9/ZH13DT9pkETThfFZILBhjDgAkE/kEkN785semFfl5O/UgkLWXwyZq8WZ264az2kUXh/7Mt8OGIdV3z8U6yBRM0Cl7EZt94R99xA1X3vTJxsaH8r5AkE3UDcnQJBP6A2jztTYfNUk79mXTYevUGbUliozSTjzkmcEObVu6gq/ohptXMTth0s/CQufA7dH+nZXwzUoSKC5GRDr34wkNVxogKBIJ5I61mmfoTcrT6cTYlDQ6Bj8hd0CAupccimRMPnANqgBmubjhE5FYw+P4f9o7bhMDaiECRo8eI78RibxyQKFGUiHdDXKB4PznVvqm5zvrkexdOz0a+CvqHz6N7LXrmMe7fei6z07wjW/kJ44IIhScoCr0GMOd+ItcioOvnLUpSDOd8YfTxn8Q0A7eNt7bRqc6kyj2HbsCYM1KJRYMbuAkbVmcn16NDk5XDaWSWcsfQa6p2NmAN5FBXnodGFCGw/yvoj62lurqVSKWb65Pn8JAPpgL6mv4eKDOT7cCDWBHQe3Vvjqok+HooFk6IKXTCkSKfAqzs42lqoPlbF8GHjyMstyPwF94B3ntujOvkrmXJawOelsd7OuX/ajhc9EMRQuoazavZz0hFjwv5q429Dskz173+H6803CdU1DJo8ciqFvL4c65np+zCTDNSagGx1bwwmBu43SyDoA9Ip8EoHf8DH//3vjfh2V5PjBq8ZjJOG85NbHsSgTzR62SQy4avqowZcTT4sRUbGnVKSdPKX3phDftkwJIMR/AqgRam9kJHHngESBdLVxt/WrViBc/VT0ceDJY/cX0NFMnUf9gUDtSYg1ejewVIwmWlEDlwwZOiqwCvgTyzcSsb//e+NaHfUYHZrkNBgdmvQ7qjh//73xkxdbmZI7PhSpd7pxe3v0Eg3B91Y1aab0DH+NkKqPHLriy/hbWyhtcEd/nz97rAmu9+d/nvoAR7ZwxHHETxy1znssmXLKLxuMbrhw0GrRTtsGHmXX0bJjTd26zjpksn7MNMM5JqAyOheNQZLwWSmER64YMiQToFXOpOyHG0t+HZXY1axjr7d1TjaWlTD6dmqnO3s3bma1L272OvRSfFrebfWjFNrIT+YaMQ7j79NlkdWNBJ7yi5g0y/fxRMyY81xM9a4hek5f6apcBi2CRdguuD3GVG3i16LIrNy+0rWH1mftiqcRqej/NZbKbnxRmrvvgf31i04XnmV2nfWsXUiPDLbR2nesIypy2XqPuwL+rsmIBV9rZ8wGBEGXDAkkBWZh/f+Cck4HrO3IGF75wKvVFQfqyIniQOZ4w5vz6ucHnfu7hqVnpJOG5lGF0q4nnHmM4DTgXAhlSzpqcody6mOTxKOEx1/265Up8vPR1dehlxzLG6/feMu5+jIedHhZ06PmZ2eubxUqvBm/iuU1/yLeS98wdKvvpSxz6E3RU4NDz6I4+WXo4/Ndhfn2qHNr+GJ8zJXLNWdQsNsoyspQTdsmHpNQHk5upKSfriqDvpSP2EwIkLogiHByu0rWb33SfYWfKi6few0W9pVwMOHjcObxEHymsPbE879+WpqXDUoKFGjsnL7StVjKB4P/sOHexSuTMe7U7ued+tfxlAaPyt8U9GX+DDvZFp1VtBoyLOVMuXci/jSV68ND0X500x44DSkv52LeXj8ZxeU9DTYpqpeh611GpJioEavZ7XnICu3/D7lewr4gx0h+BR4ZA/rj6xX3bb+yPqUYfBUoeMZe0MYAqG0jpMOeoOWsdPUDWF37sO+IFIToEZf1gSkS0Q/4eVLX+a1y1/j5UtfZvkZy4es5v7QfNeCIUXsD3ukX3lM88lYfIV4c5ycPmtS0gKvCLHtPnm5BRgnDYcdidWwxknDo+HzgD9IU6ODTXveoqw5RLOFuOElnaVGM1H925V3J+UqSY2czvoZ/oYLIBQeDxrSSLxbfDZbCmZya7kVya5l/06F+l+uZ6zGz1nWo0gaBVoPUz7yCM6dIwj5wkbWZ8jHl5Oo2AaJsqvrj2zgptOXJs5Q72aldm+KnFKFjosdUOiCusLMFUtF7rcDH9txNXmxFOUwdpqty/swG5QtWwaEc95ybS268vLofThQSDW6dyghDLjguCf2hz0iC7pt1L8xB/Lw6tu4+qIXk7buJDMiN/34AR74fzepVqFHXhOuAvdwse9blNXvJL/hJT6YqETHh3Y2BulW/6bKpUe8O7U2srHTbLTIzUmNnKRvQaNzEgoUxz1/ts+Ee6+GSCzc6TGzk0UAzM77GwBaQ4iCiSGa2yPuRn8rRm8zPlNiYVFn2dU6jx176xFGFsdXX6dTqR27sIoUOam1GXVV5JQqdNyYB82W9I6TLpJWYvZVE5l12fgB1wceqQkovfnmAdcHLohHGHDBcY/aD7usDeDQNlJhqUj5g5zKiCxb/ohqH3h8H7aEbLRRPXIeGuDi7S8ACk+cp40zBl1V/5befDOKUZ9WLv3Mi0agOJwcqvLiavbFeXe+kC+pkVMCBYRka9xzuhBMCKgblgPe05llXY1e4weg7MRjMPk7ODd9ALW1lHmrOKxiwGNlVw2BECe0+Ch67Ctw8sXRka1d5fLPWDSOra9VJSys5o2ax+ovUhc5qS2AUrWTbZ+giUZOMl0spTdo+61grSskk6nfCtYE6SEMuOC4pyfVqwGfl5Z6O1UfJho66CgIy8stiCtYS2V47LapjD/wKjP2Bnj63FDcudOp/r2/9umUBVqxIfjSY8coqxiJbvZ5jPrZ/2AwhwujTCT/LGTnidHweQSLosEaUu9Fcyk23MEi8nXh69YUjqD8h3dQGtQgNzQwocjG+2uORsPEsrGVTwt2sHnMq0hKiMVvKszYE6LEATVmH9Z3/0FZUEFzyX1d5vLffXYPuzd3fF6RhdWsuZfCZPUip66KCTuHjtsKTWybCE/N9lMRs69AMFAQBlwwJEi3elUJBtm46rF2edEG0FjR6sejM81Bo+kIsydr90lleLzGQnyGfGwOO0vKLuUHMefuqvo3UGhh/bbkBVrfnfpd7L9fgfzMy9HnQ0cPEXj6rzTpfXEheLXP4sS8M3np8+nxB9b4aTO6cLaVk68keuEWyY5Z29TxxAkLwWBGgqjnFhsmNli1PPDhLg4dKeb8V49xwQ49PkM+IakV2R2geY8VnlhD+fm/TpnLzy00cnRPc8LzAId2NnHL5T9VHRJz79Z7Uy6A1ELHU/RwiRiaIRigCClVwZCiq17sDY8/wo61iYM5tMZT0Zs7pnBZi3O4+o6ZCXnLgD/I07/erGp4cjx2Zm67C0N5CZX//ldCXrH2nntUQ7iF1y0m8D+LueSlS1BQErYDDNfZ+Pn/q6XMkbgtmSRo7GexcXcz318dqdAPS6nqrJ8h6Vs4s+oqTqn/UsJxTyzcwNycP0H+iLDxbg9/d4Xz4Ies/8k/acifhi+nEKO3mRL7TiqrXsJg9jP+tVeQKk5MKgl7wqxyvthSCyq/XBoNfOM3sxIWVkKGU3A8IjxwwZAiVfVqwOdl3/bNqtuCgf3oQmej0eiB5O0+qYrIbPadaJUAeQvmqxYFpar+9RJImruGcAjepmK8IbkAR+xnMSy/Y8FhKF2DsXhT9PGWcc+jkXzRyn2XsZmDhZ+wcdrnzJ2zHSzlYEg0mMkWSjte93O0fH70sc9kC/eLAxOrXkD2aDGQvFL7jEVjqdnb3K0+6sEgwzkQh4cIBjbCgAuyykCevtTW3BwOm6uhOCHUhtVW3mW7T4fhacDZ6CEn0Iqt/iMmebeQf93ipO04qap/TeiS5q4hXCVtz0PdA09DgGNkYbsB1vjRWT+L29a5ct+tdyBrA0hOiWZzIYUxxrurPHPAH+TgAfXRj3bbVE5oeQNdRXihkapSO1Wlvdp91ZsK9a7orcLeQB0eIhj4iLtDkBXU2rFGn1TM1LkjsRTlDAhjnltYSJ6tBEdDfcK2PFsJX7l1LnkleV1ea2fDk2NQ0LSejq7k1rQ8q2TVv51z1zaTjUZXU9Sobp/o5eLtiXHldAQ4GlxeADQ6J5K+RXWfSOV+BCWksLdpL2dUnBH1Hh84tIrVVc9E9+mcZ3a3+nC1JK8R0J13ZcK1qlVqd7ePui9kODOlsDdQh4cIBj4iBy7ICsnymQDW4oEzSjFZDlxthGZ/4ZE91Dsb2LO2lY+27iXHa8VlbOFQ4U4q973EjL1BbA4wDKsgb8H8tDy5d76oZ/Hft4HGj3nc/WgNzRgCIQpdJAjQRJA0Ehu+sg7/A49GvcfGPA2bKzt63SNE8sw6xZC0RsCs9fKN++ZHK+bToTsRnViD27mQsbtKXorHw5/W3cXjda8kfDbXTr42bblVxeNh/8WXINckRgb6cpyp4PhAeOCCPidVaxUMjFGKEUPwpa8tAcIjM52NdqzFNipnzGLO4hv65brUMOlMHH7Dy563GzBTAECer5iTa+fycSU8fe5LLCm7lB8tuD3tH/+DTe3i7iEDSutkrv/oHWbsCWFzhEPz2ydqEozyxIKJ+B94NM57LG6Bi7dDpNc9QmyeOVn4u3JOZVrGOzZXrDeZ0u6jjshwqlWop0sk3O1Yt465x45xsjXxs+mssJeKgTw8RDDwEQZc0Oekaq0KhQKElDY0Um60tzqb4XR1pbVzuW7FYjyOFnILC+PmXg8EUi2IKltOZfz5efxg1s1I3fAqh8UUfl23PsjFVR2BuTIH7aH5EE+cp0HSSEwsmMgTcx+h+v++qnq8GXtDPH1uKOqdxuaZeyIjqng8BI7V0rR6Fa6Nb/cqV6xWyJiuJx8b7tYS+9l0LFi6UxQ30IeHCAY2woAL+hy1nt5QSEH2bCQY2A+KA6Q8mjzjcTWdTGG5NcXRMks6cp3ZoDuh4FQLolxfAddO+FG3Q8JaKXxOo+znzGOfqe6zqKaMc2b/mgkVJ1GYU4j/8OG09MMhPs/cHRnRuAKvTkYuE7nirvTWY719IOXAk8iCpTtFcakU4AbC8BDBwEYYcEGfo9ZaJXs2EvTFTAZTHAR9H7L9lSeZs3BRVlppAv4gVR+pe7JVHzdkJRrQlQHpbNgDPi9+bxOWAglXc2JPuLWH4yhHFYXD0EU+ByWeFvVrravnFN1oDO1DSlJ5jy0FWhwWbUoFs3RkROtWrMC++hl8hnyMkh6tEkjYJyI125P7JekCTlGYUPViXGW4+fTTkY8dUz1OcStMqA6xd3j3i+JKbryRoMOJe+tW5Lq6ATk8RDAw6RcD/vHHH/OHP/yBVasSV52C/iXg89LW3Jzx0HFs2NRhd4Y9bxX2vvFvhj3wZ4wxP2J91UoT9mS9aEgs0HI2eqn6sJ5RU4oxWQwqr+4eyTzsZAYkGAgiB0JU72nC1ezHUqhHq3kfT8tuHI0NGHIKCCpjEhTiejqOss4RrkJvMubRYCqg3JOodNY5pJvKexx78dd44aolvVIwk11utn2soe702xMEX6RQx+IlWa44VXuX4vHgramj6kP1Bdyutz6n8O1nogsGuboaR3U1mtxcQm1tiS/QwO1PK/hsFioWyoSmy13et53bx7RlZeR9eRHlt96K1pq9KJRg8JJ1A/7oo4/y6quvYhKhoQFFZwnRPFtJtHhL0vbeC40Nm9bsOcg/f+tU3c8jafBqNWiz0Eoj5Sp4cloxewtUt6/7++doJCiusHDFsunoDN3/uqTysIPBUNJc9q534j295qOvx0Us/J5moBm9UQvac7AW924cZb4pLFDj0xl4f9gULq96N2EftZBu2bJlhOQgrvVvIjfY47xHNQPWnVTBpmc+53DhzOjjOMGX/S9En++8sEjV3qVViBpNR3MA1+m/BE1i50MwZMFnyMfstcc9r9Fo1ATg0LU/aba7aFm1Go1G0+V927l9LHjsGI6XXkZrtYr2MUFaZL1nZ9SoUTz44IPZPq2gCzaueowda18N90CHQjga6tmx9lU2rnoso+fRG7RUTBhOXpLiHJNfJicQjD52vrkexePJ6DVEaJGb2V/wseq2iFceUsB+1MULK3b06BwRD9vZ6INQh4f9zt8/xFXnSJrLjiUUCiSNWHhdezDnSYw+qTitNjzF48F/+HDCZ/rO3o6FxF9PWsRL487mmKkQGQ3HTIUcmfflhJBuxIN0bdyIXFePVFxE6MxTybvlxjjj7ZE9HGo+zIZnPuPpX29m9a828/SvN/POc3tQgurSsAF/kIP7varb7LapBCV99HHnhcXK7StZ/flqalw1KCjRXvSV21dGjaZcXY3R24zR26R2ivA2f6vq55d3+WXohlegaCCY5OPu6r7tavpcX93zguOLrBvwCy64AJ1QFxpQpJIQ3bd9MwGf+g9pT9Ebc6icMUt1W5mjDW2MNEEkPNoX2Mw2Dk7ZwsflG2g12lEIElL1r6CxxoXH5e/W8VNVi+97Zz811y/GJHX92YaUtnChnxqKE1dzE59urGbTC/uSH0OWqb3nHvZfsoj9Fy5k/yWLqL3nHkJyWBWtqa3jvSmSlkemXsYP5v+M7563nB/M/xnbL/5mgkcdawwJhVDqGwj+81888cN53Lv1Xryyl3u33stlr1zG7/7fY3z2Vm3CQibZNXcl+OIz5KMbPpzC6xaTd8uNHHEcwSN78Mge1h9RH/ryzv51ONatiz7WKgFK7DtV98117FTNt+vKyxn2q1/xyp3z+O3XJZJI03d536bTPiYQdIWwpIKUEqLORjutdbXoDMaM5sUjfdWRfuucgExZk4NJNY1x+/VlK41JZ2Lu6Lmsdq9m26h/M6bpZObvu05135ACjdUuRpxQlPbxu5pM5m1opdjwXjQsnAyNlAtSnroRl6zh7ZCyDa8rta8ya2Ke36czcEwXrqbuvD2VBzl5l4ulO1exvXY7u5t3owvqObf5JNV9k12zlKtgKtDhaU6UXTXrAkx67nH0w0u5f9dDrP/3V6Oh8tPLTueYS73QzF9XT7A23ihXVr0EQINtKh5TIc52nfeJrpc5ReUY1vnz8Onhjfq3sQ/X9Fi+tj/bx4Tm+vGDMOCClBKieoORF+/9Nc5Ge0bz4pJWy9wl3+Xsq6+jrbkZ11//inP1Uwn79XUrTWRO9HN7nuNI/m6CIR+S4kUj5UYHl0A4TVo83NKtY6u3z4X73k0+L0Z/a7ggy2KhefxsnE0+NFJ4sRCLRqNHqx8fX7XfjlY/PnqdyUacdhWuLb35Zj47pl6TEKHz9lQeZKSFbI9hT/hzCORh8RWo7tv5mmPz12ONsziZOQmvqTy3ktyJ41XHg77ieoVcXS5tcmKhmaGsFG15kGBNh4GXQgoT97+AtfFVfnNtEa3msM77ltEAGmbsDVHsgMY8GL7wMsqWLeOo+xi1rloUvYbtEzU9kq/tj/Yxobned/TXokj81QTRkLaahKjf68HvDefjInlxgjJzL79QdQpVT85dUD6M/J//gjpJqzqJqy/RSTquO/E6nvv8WabuM+BzPI5WcYOUFzcHvLjCklCN3lVBVmz7XOe+dyWo54vyPCbVNFL56WpG3/N1AnmlbH1hJ3s+cidep2kOEMIQ/AyP7I+7vgjJJnGlE66dN7mEFz5Un3QGMG9yvEeYyoNszAvLryrtKxG33oHL2EKerzjx/LneuGuO5K8Bjo15GQWFMc0nk+crIq/YHC3Uiw2VdyX5GsGUW4B1/im0rErUQ3efUYmhzInsDnvoiqThifO0PH1u+Ng5ZcN4/spfodHp4gajrJovAUrU0LcUaBl78dfSum9TTZ/rLukYEKG5nnn6e1HULwZ8xIgRPPfcc/1xakFn/G5w1TLna1cDHSFtS1Ex3jYXAZVimn0bX+HsQ79EX1gBky5Kew50KlJN4uop6bbE2cw25uwfzuiDWqDdeLb3pYcIUT7hEq5YNj26f+fK8tx8I2On2Zh91YSEIrJIVfjON56K86BlbYCDJQUATNXkoLXZCPjhS1ecwIGP3yMQin/vGo1EvnEq0997jb1jz6d2+IK4CAHA6JOKVBcU6YRrzyxKHVE5c1xp3ONUHuT2CWEjOqxFQ2Ougl8f4EDhTqbVzk3Y92DRJ8jSXPSYEvLXsVPQxugn8OQVj2E1h6MgdoedescxvvlmUEXy1YVW0hEkGHeu3c27WTVvOtdpFscbzblzufiUFubv/Q936128Yu2ItPj1GuoK4drxC6KtaLGDUTob+gtPu5rZs29L+VlGyMQ9n64BSScKI8Lp3ae/F0XCAx+qBGV4/TbYvQZajyLlj2DupIs4e8WDtDkcBPw+nlx2o+pLnT4tbbKOgtbDsOXh8JML783IZSWbxNUdutsSpwtqGFVnBhLz1UHD53x12e1xLWSde7fbWnx8urGa2v2tXPmLGXFGXNJKzLp0FJ9vPIxauVpdXi77xl3D+ys+jraZ5Vv92B2JP6Z5jZ9gCPqZvH8N+pARu20qXmMhhkAL1rEjOfhJI5++XZMgBpNOuNbZqNLbHIPTF6CoUwQi4ikeXfMSxkYXjXnwQSUQCrHykSA2ZxB7u1b46nmvAHTMFDc0U5O3l81lr2J3X8PIvJFJZ3bL2gAHlC9okZuxEjauNrON775j5NztHTnteFnTYMJxAN6seYsbl70cbzTfuhO2PIIJuBOwKgrrzSbq9HrKLBWqQjSdJ8OV5Q3n3DHn8aPTf5Dyc1SjN/d8ugZEaK5nnoGwKBIGfKjy+m0dxheg3RjrgYKF9xLweZPmxa06H7m6mIrsL9bC/Dt6HU5XoyfzwyMtcRGioX9QnSjW1tyMxqleYS61BWhrbqagfBgAHq+PD7fuQ0uiR28/6uKd5/Yw5+pJCcd3NqoXCXqMevY5rUju8OLB2ejDST551mYUTxCXXIBJ18IIWyPDNr4Yvqb2vO34A6/iM+RzeORcaowd4elIhbfL7+Lcr0/GpDN1Ga4tteaQa9DS5k80fLkGLaXWxPcb8SCLfnwjf1n/e/7r2sqC12q4YEdHEr/DqMo8cd7LbB+5lrMOfoXhrRM4wX4Go12T2ZfrZPiVSrdmdhsDcMYe1Y80QYc9llidcsOoUeEI1O410e064KbmVr7idIG1ghFXPo3J3FG4GCsOs/yM5fzPtBt5+/nd1H/kwdXs4/kN27M2Wa87BkRormeegbAoEgZ8KNLpRyuOdmOsN5qT5sUrrU3opZhKq9aj4KqFonEZu8SuJEaT0VVL3NlXX5cQTk9VxGcttpFbWBh9/OC7f8bkmpL0/Ac+tvOlK4Jh2dP2xYchNz/p8SVdfrSKPJaj/iBrT/szBtlIk9ZOqcHKz61KXMWzVglg9LdSb1Ov8P5o2z4eNPySOWPOYemMpV2Ga32yek9UsucjGHKt/M/CX3PZXb/F9dE/Vfc554CJpwM+Tju6kEkNHS2EZm8Bn71Vi07SMfuqiXEzu2Nz253lSeWGBsxNibUCkKjDHkuCTrmrNnz/AjKwsqiA9WYTtTod5bLMvO33sfTs3wKoisPMOnApVe+2RA+XTS397hgQobmeeQbCokgY8KFIzI9WAjHGuHOrl1Xvo9Jcz5yyqvjX5I8IF7RlkGQSo7IiU3mRNalEZ1ctcbHedIRURXyVM2ZFDb5H9vBW0xucox+JNaBiHYC2Fj+uJi+fvl0dt/gw5U9SNeAa7biEXDZArq+QoD9EXU74x6E66FOtePYZ8pEN6teS6yuktbmN1Z6wQVx+xvKk4drDTW5kJXzsHHyUalqoDxXgxYishDhQ62S4yZA0ElK3YgWuZ5LXtVhbfCyxXY7301NVt0fayZbOWIomqGB59DUq92gpa25FLjRG5UlDgQByQwOSxYKuvAy5JrFlLFJEp0aCTrmlPHz/th5mZVEBq/Pzoptq9DpWH/gX5BQAJFS8P/Pps5g+O1k1GqPWHpdK2rUndNeAZLJoTjAwFkXCgA9FYn60Eogxxp1bvXK3/S/6Dx5JfM0JCzMaPk8lgLJt826Wuu+hJL84mpuMnbzVHW86loTFisoccLvbTrXnKAeLPuHkunNUj2MtzmHnhiN8urEjDOxs9BEKTaesEjytu6PHH3fqGRzdPwVXU6JgiMvYjFsf32DcueK5MQ+2T3BgtAaQXIlGNfYYXc2o9gZktAT5hfQsZ7GfMboqGrDyunw677mW8N6fPsHnCKhGQjqHcoOSPjx8xN8aFUPRlZdz7Wm38NR/E1vhoKOdzFqUw7QXRnEk+BP2TinkcLv+ec7qp/Bs207Q6QwXa+UbkTTqamXbJ2gSwue5ulwun3B54lAVgxkmXYRn619Yb1b/bN48/KaqwI85kIfGpa6TH9sel0ratbtT42LprgHpi0LRoU5/L4qEAR+KtP9oxeXAI6gY40irFxf9DnRSOMzeejRs7E9YGK5CzyCpBFByvFZMAUtUHhPCnmXstabjTXcmYbGiUrkeydG+N/Ylyp1jKXEnznsefVIxhz61Jzyv0UgonM03fvc/+Ntao8d/57k9cZGGCAcLP0HWxhv2SMXzuoU2lIYmDGWlzB6/gKkHxvHphsS8cewxuppRrQ3CT91H0cuXsF6xYZXsjM3ZysSQBp/fgM8fPo5aiDgSylU0EvvGXU6DbWrC8BGt1UpusTmhLz5CpAXu3Wd3s881DNrtSpz++e4O/XO5OWy8q0oh10fMgkbDtitOpEJxUueqoyS3hJnlM1l+xnKshiQDQs6/G7vcRm3jxvbPQoPZq8WdEySoDVHXVqdqwMPtcc2q7XGxLX2xrXFA0nu3J/TEgGSiUFQQpr8XRcKAD1UiRrc7xlirC1ebz78jHGbPQB+4GmoCKBE6e6ZqnmU63nQyIouVgD9Ia4M7LmQc2z704tT/5cwDlzG2+WTM/nywBDj1jEpOOmc4n76dGNKEsFcW8BIXwo+0mVV93ICj0R1VAts8JnEBAlBhqeDpi5/B5XdFQ7HKaQqSRkp5jGQzqiO1BrverUHxT8LV/rxTKWOnexF61KvTY0PEkVDuZzmz4lTlOhvfpv9bydhpX1VdsIydFr62Ax8lLn4grH8+/sCrCfKmuT74xRKJXJ8m2gdeoTh5ptNnlBKtDtvC+xj2wqVU7PAwqs5MrkdHm0nmcJmb6tNMKFKI2rb4fLOsDdBQVkXe4UQDHpkKl0ratauoSDr0twERhOmvRZEw4EOV3hhjgzmjBWudUZsfHqGzZ6rmWabjTSejq+K52PahLeNe4YhpO+cWnceNZ/8AU46RgD/YpZcZS+yUtvvffpDnDz+Z4HnHMm/kPApzCinMKezWMeYFDZhUcu2daw06E0D9nogNEUsmE6a5C2jYq35PRIyv8831nHnTT4DwAsDV5MVS1DFFzdnkxeVMlE6FDv3zztPBih2Q69NQV9gRMq9z1eHyu5JGG9Qw6UzMOzgG7cGOSIbVo2fKwXwmFVUQmjs+zosGkJQQc49theYQ9Tnj8OYUYtYFqJw9LrowS9YaF7nOVFGR7iC86qGJMOBDnT42xj1BVmTeG/USdaOgpG4sFl8hbcZWqgo/TvBMI56lWrtZNPTfDZIVz0E4ZKyTdCw/Yzk3Tb9JtSAp1eIj1axuvUHLLfP+h9B2XzRXGjmuV/ZSZilT7UdWPcY/32S9Yy91Oh1lssw8t4elB94G621x/fqpag26IrfIGLcYsdzwI3y/3qq6b8T4amtrUZrs0cVG579XqsiL0deMIukISvo4L1ytYC1ZtCEVAZ+XgsMyaoKyhUdkrj35f4CYvm9LGTduzGX8G58BnzE2Ju9vG/51JG24B7s7rXEgdMoF3UMYcMGAY+X2laz+YjUMB125HnMgD7feoeqZzhs+j+0vHul2u5kaqQxa56pik86U1HOKeF9qXmYq1BYHQFqVy9Ef/vxcllcf5CZHLXatFlswiCky3a1Tv36qWoMIetwESGxz+zj3XWo/ejdaiJVbbMZanKNqfHN84dGcumEdldF6gzZBs11v0DL25GJ2vpVo7HzGfLaefmtcXl0KKaoFawmV5jFEFnpSrkKL3Bz9XFP16jsb7fhaHXF/myJNLjV/upJIvECrBKLRgdge7Ni0S2dirzNBUa28DOvZp1P289vQmPMSXisQgDDgggFG55yhrA3g0IYnlOXqcskz5lHfVh/1SGcduJSdG5J7zN0hlUFLNihEjdiQdndFaCC8OCg3ltBmD4f/YxcKnT20hB9+WyHWglbKTgkxMtQpHN2pXz+VxxshaKzig9AJTJFk9F4jrvb8+vaytZg+tIAssfxLP0sZebDZw6M502mtGb//RaocFbjyOoWD2+d/R/Lqkl5hBs+gzFCoCFqp00JZbgXzRqlHKSKpkaqPGnA2efHktLK/4GMOTtnC3NFzuenk/8GQU4Df05zwWn1OfrR7IbJw8x8+nHYP9g9P+SFOv5OttVvj7t3Y60xQVKs5RvNzr8Jnr1F+w6KMyBULjj/EHSEYUKTKGXplL6sWriJHl4PNbEOnGHj6FXXRllSjNZORyqAlGxSSCjUvsyuSycCeecW1HP3fPyO/8wahmiNRzeuQotCy+h/R18v1jTTX5wIK5dM7BYQ79eunMrp+guwyBHgzp5KQ5GHf5IcJenx4dC5mHFnIlTuXY/EV4P3cyYbDnzHnykkxkYcGnI0ecrzN2Bo+prLqJTS5uYQUhZAsJx3yoHg8ONZvJDCi62LD5oqTsY1fy7KrV3OjdRh2uS1llCI2NaJBg9lbwMm1c1BQWO1eDbKExTAePNsTXivpx0On+oF0erA7t4+V5pZyyfhLEiriUyqqHQhQuukvSJAxuWLB8UPfav0JBN0kkjNUo8xSxoi8EYzMG4lJZ0rLY+4OEYOmRqr8dYRI5XpARY40XSIysI6GegiFojKwf/2fu/hvzVTeHX49e8Zejr/mGPbVz3BszdsEpcTiNOdRE4rcSUq0U4tgpNZg/8httBrtBAnSarDzWdEO/jr+FdaZZUIa0OictISO4chpZMaRhUyrnUuerxgJbVRJbdML+6KRh6vvmMUFwz5m5tbfMnH/C0ghhVBbGy2r/0HdihVJ37tcW0tbkxtfjnqvfiwupRh3ixf0Jkzmoug9oUaq1MiY5pPRBfVs3r+dkHQ2WuOp4dnraMIT34yngnR2wr0U6cFWIxJpiLSP1bhqUFCobavllf2v8NBHD8W/71SKam1aZE9766ZfXXlOMHQRHrgga6RToJNuzhAy7zFD1/lrtQlnPZV97UwqGVif/yDGHCUaQm7JrySgNyf0W0vtIzxlt5Zj2/OpmOlEU6jeIhitNRgBumHxtQYSYNDK+OsXEZKtFBvLaHE3MrZ5asK1hUIB9m3fy2kLR2C2mtEG/YQ2rklo+YLUQx50O/9IrrYRo7cZnyl1EZpFsmMuNKelAJhqoWfxFWIO5HGYKsyFBjzMRRc6m5DSFp0Jby1Wv5dS9WB3p30slTcP0PiFmXLLUTQZlisWDH6EARf0Od2dmZsw6SlJBbbeoGXsSYXs3JjovaTjMauRLH+tBINsePwR1Qlnm17Yn7JyPV1amxpobahHdaK14gwbFW0BQFyOOK7fen9E7ESD46AZ7bRLKP/hfQktgqlqDSLorJ/hb7gAnWJgXsGFvNG8FouvILo9dsa5r8XBqmX/ZOLMMzlzznlJPUpfXR2Nn39GwZQp8a19fjd88V+sNicl9p1x/eRqjM3Zhn7ygrRaH9PRFSjNL2HsNBufvVWLRqOPfs6Q/F5K2oPtd2Ov+zDt9rFUimqgoWWfFY0pP2lkSjB0EQZc0Od0d2ZuV61aQHQc6lnH/gPmeRzwn4lLLsJSbIp6v72hc/462YQzJahQXXWy6jG6ysN3jkg8VrUKT04AqzcxJI5kVR16Eoua2Ilz225Kg5qEXFmqWoMIWp2DuR6JCT4DeS+fwkXG0QQkP0Yl/LeQPRvjZpy7mhrYsfZVQrLMyE4epQLsriimrigPz4o74xZAmlCIurt+jfNfPmR3LhN1/wQpREPRNHw5hYRCPmQd6BQjVsnOuPzPOetsI5x/V8rrj5COrsC8kfOYc9okdJIure6Bzn87w6hR4Xty7XLYvQabo5rykcOpUfnTq7WPlS1bRkgO0vLMU+EPqxPOaqPq31EwtBEGXNCn9GZmbqpWrcCaX9D2/pPk6vzMzvsbs0KrcQeLMM/8CvpFv4vfVyXs3R1STjjbtoUAY9GQaHSTVa6rRST0c+ayddTHDC/wYq1NPJZWP1516EksamIncl2d6lhDm9lGmbmUY+7kRvzMA1cyzdtRbGX1dYzVDIUCBAP7VV+3/6PtTJw7B+fqp6LP7a4o5mBJQeTFcSNeJ9fYwxXXkZ8jGSbufZFTxj6L4VQt3mIjtuv+heK3YNY2oTWdj9zahs4fQDKl9xMWq3jnbPTgznFQVfAxh6ds49rR17J0xlIkqevugZTRpDc6RvSagHkuR9xwlAhqbW4anY7iJd+k5emnQUW2VW71i5ndggSEARf0KZmemasEg2x8/C/s27gTh28GeTofldZG5pRVka+rhf3/Bv8vwWBOWtE9Z/ENSNr0w+upJpy5mu3klngIyonGNVkePjYioWgkPsuZRcP+CcytPgOXoRGDtBk/9aA4QbKi1Y9HZ5rT5XVG+q1jUZtKJSsyD+x4AIcvft+41wX1jGtSH1Pqkzx4qcWoOFS3Oxvt5P7i1+gkLc431+Orq6OuSL2Xed/W9ynfrTJUB/DXaxgp1SGd+D0oGdVuPB9OOxUTS+fUSLgP/HRs5p8nGNNU3QNJo0lBmXJL/IjepU0tAKy35FGnlSiLGWLSGVmReeDQKmblSxS3JBZBipndAjWEARf0KZmembtx1WPseH0NtHu8DjmHHc3DAZhbXhXX65ws7A0wd8l30z5nqglnSFbkgAmNSuI6mjv1u6NytUpQExeR2Dfu8mi+VwNYA6WQ/2WMoUBcIVWYEJZCIwY9NNX7E84X6beORa33uvNwjQiaUHhkxzBZZlpLPrmyeshepxh4Y8ozzN2mI9eXuBCyFtuw2EoovPVWSm+6kcbVP8WTRK7V0dhAW5NdRSoGZLcO+YRrMbQX31X//nfUPvccOYEg2lCoy1SMGrHG2UqSmaNJSBlNWr+e0rOOEjtcTAcsb2rhphYX9m+9im3Y9KSV8iu3r2R11TNQqXBxYiebmNktUEWkVAR9SjrtNumSMpTtLCKgSNFe55T7bt9MwOdN+7yRCWdqRELbkhY07d8mjQS2ERbOXDQmnBP900x44DT400zkf/4sGpEISnoabIlV3UD7MQviw+YaDZf8zyl87Y4vMXXeCKzFOWg04RGmU8+t4PQvmdENHw5aLbrhwym8bnHCVKpU1dGlsszFLhchYF2hG5chUdQEwoVfLbmNHBzmUt0eO/VNeucu8g4/j0lW1zg3yQq5RYnDQAB0wyrQffU+FDSs/+tDvPrR+2ycNIq3TxjJZxXF0VSx8831KB710aLdwu+Gpqqk7Vopo0n1Dci64XHPeTQajuh0kFfByLJTkxrv2L/JqvkS/56hoS4fZA3YC7VYr71GzOwWqCI8cEGfk6mZualC2U7ZSJtsoKC917mt9ljyfRvttDU3d0snfc7iG/B5ZHa9/a5qaFuJiXqGFLAfdfH+g6uZ7Y4Z2dp6GF3janT545CbPfgM+Wn1PEewFuWQV2JKofR2K8otqadSpRyuodPxb2sk5x3gQNFOptXOTdgvUvi1fVILQHR6V35JGRNmzOJLV32Dltpj5ObmoN+9Bo0PylpcHCxJfK9lLU7yhufgSFRPxbpgPpLJxIbHH+HDN9ZAe0uex6iP5tNPrGnsUSomjvaCSHav6ZjMN+miBPWz1NGkYehOnQYf/hUZWFlUwHqziVqdjnKtiXkfPZh0/nfs3yQyMvbpc0MUusBh0fLCVUu6TBEIhibirhD0OZkaeZgqlG01Bsk987por3PKfYttUWnMdJG0Wubf8D3qDp+Iw97UKbStzoHDFmYVG9BrOsLdki6EdYSP5mYw+lvT6nmO0LmdSS1XGzuVyiN7Eqr4Uw3XCAfkOgqoIoNjxjSfjMVXGJVRjTwfkmDbiS3sOKEVi1fPE1fcz+G1b/HkshvDNQdFhYwP6piVAye11AMa6vJy8Rh0mPwyZY42TvK6KR/5CdpWC85qE3KbFl1uEOtpEylbtixlJKUuL5cTjjVh7G1++PWO4jMAWg93PI5RP0vV7mWdPw/pkmVg0LHy0BpWx9zeNYon5fxvtb+JX6+hrhAqLOXdHswiGDoIAy7IGmojD9WmiCUjEsqOzWtHqJxzKfpFP4w+1uoMmPInqRrw2BBvd9AbtIw7tYKd61X6fFRwyQW4g0Xh4rp2ZODJs9qw5to4aVdb0p5ni/MIjBhLm0NOexhK9BydJDzLY4qnUgnloImvfg5pFN4f+zLbRv075UCZoDZEbpmNqjXr2PmfjkIuR2MTHzKc5gYzU/wNnFjTyAnHmvDqtdE8dv5JGrSGEOXTnZROdSF7JHQmBclmAsVPW3Nr0kiKx6DDq9dii0nFdOd+AsLh8t1r1Ld1Gv4CXUSTtDo8593J+pc+BPexhMMlm/+d6m9yetnpXb8HwYAh29PkhAEX9As9VS+bs/gGQqEQu95+F7+7BSQrOdaJaHPnogSV6Gs3vbCPFvt0tEZnuN2pPexdNu4U5izuWms7GZ2V2nILjfjaZAK+xMphi64Fs7Yp7rmVRQWszrfCXB+WmRL3PvYSEO7h9hoLw+Mo7TuZ7HmfMQ+9hNcvdXsYSucitRpXTZwHqCaUc87wc3hlzzo8IXvC8dREXjozr3wOBzeoVF8BdXkWTjjWjJYQeq2M1q+gKzJjXXAeZTwS3U/ShTBY2z/H9mLE3MKKpJEUkxKi/KqrKFu2rOdqeK7a8LnU6DT8BbqOJtnddmrddeqfQ4r5353/Jjm68ALz1f2vsq1uW3QBphaCT4YYTZo9uitWlSmEARf0C13N3U6GpNWiz52LxjAGgy5cpY1GzydvHUMjaZl91cSo9rVGI6E3x0tjKlgJBkHqvkhb+/kT88+bX96vPv97lAu9uyN87tFoWG/u+CF1mSW2Tgqy8IOXUDQSdttUfMZ87MUncbDkBCZYzBhVjE+qvvZ0JTwTxpYqBl7YXgPWt7v3eWgkrhr/FW4omssT9vdV94l4yrl+GU2OlrE/nIPhqvuQDFr405pwyLoz7cWIekPyqMukCy9hxLfDUZd3n9vTo/spoC+kzTiGXM9B9FJHZCUQMuA2n4TZUKLS4a8eTYLuz/+OECtedPfmu3ll/yvRbZ0XYEBcZ0NnNbr+MiZDme6KVWUK8dcUZJ3uzN1O9trOcpexr+2sfR27bzpjQdPxXGLzz2r66WOmFHD6zDEon34b6cAb0HoUe+FwOmu0rJovoTNcjt5wbvQ5n8nGPheYX9gXZ3zS6WtPWaTWyQOMFco51NhG09ELMJQG0Vk/Q9K3oATy0Wg9SNrkQ2GuMgzntq3/JND8AHmGGTh8iebO5JfJCYQ966BHQlpwK5KlvVhu0kXx+ecIMYNXIhGTfds342y0Yy22Rd83dO9+ioTYcyw63nv28fBn2TCcPF0xldZGZpce5H3XEg54z8BZZ8N6z07GnpK+rn13tPyTsa1um+rz64+s56ZpP8S0/q6UBXf9ZUyGKr0Rq+otwoALsk5v5m6n89qeDjnpqecS65W3NbpxPfYnPI+t48Bd7cc496uU/eBqbJZiRr7yNbx1x2i2hAuVpJABj3UqepW31Nn4pNPXHusBaoMazF4t7pwgQW2oCw9QArT46xfhb7gAjc4JmgB5ox8gt00XPUbHhxXiUpeL5Qc2AaCXoNJczw7f8IRjlzna0IbCr9WVD4svOIsMWPlibYdB6jR4RdJqmbvku5x99XWqkYd07glrUU5ciJ3g23hbO0L+ET2Bav8UWg2Los87m7qva5+ulr8asQswQyBciR65V+pcddhf/wUjP4gpoutUcNefxmSokmmxqu4gDPhxQLcLd/qZ3kwRS+e1qbSvUw056YnnElfpbTDh/fuDOFd3OsY/ng73lukM/HpNC0Z7EHsebJ+o4eWziuMGhMTianTjbnKTX27tsq/97KuvQ2/MCXuAw+fyxUv/jrZ3tZlkDpe5OeHyuUk9wEONbR0PQgbwF3JW0ztUHqog1ytFj7F9UgshKSz2cltjS9wPyOzSg1T7p9DgkVGUNjTkkufPYeKxA0C4712afQFBraFDgEKrC1d6z78jLiTskT3YHceiFfSKx0OooYG8khKkTmmDdO6J2JRNKBTA59yj+jk0eALo9YGEDoPuzJdPS8s/CTazjQpTGfNfPcqMPSFsDqL3ypuLyrHt26j+wvaCO7nB3m/GZKiSabGqbp27z44siKO3etxqZGqMZbbpqYHtzmu7Ggvame56LmqV3ueVnsOl69Tzz63PP4sSgEhcocwBF28PAc24ilvI8yWKmVikeszb7oFFv6PRnryv3dHQgLOxkaKKsPc74/MCdAfzo9utHj1TDuZzyi4LqOvRMLo4XgvtrKb3ONXxGaCNOwaEW8fmuz2YQvFV6++7ltBqWIRe36Ei59Po2RcYid8I9UUnQ20RoVv/y7TTxzH7qxM77lODGYrGhT/XrfdGP9cKUxk/etfCCbtakY/VqkZFurongLgQe0hpgyQysIrijpv6FiGd1EtnUmn5p3rNj961MH57x2cbuVcm5RkwlaYuuNOVDOs3YzJU6bK9sA8jHsKA9zGZ0uNWo6eFYAOB7hrYVK/NLTJSOtnE9EtHRPdJLnaiTnfDYGqV3v858jQLjwVV5Q2VQAhUBoXO2Ovn2XE7Oak+UTBlbM42NPvXce/7ubx1+B1m5oQNaQKSlZ1vNXPuNcPxtbSwf8t7qu+jauNrnFN6CP1Fv4sTKAFw+Traw3RKgHFtB1SPMe6YmRPKj7C0tSXu+UDIwAHvGQAJ9QkHR87EEDJ3fC6uHD7dUIOkkRLu086f6/xXjzJ+e4iIjluyqEjC/VRoZOwkA2ctGo6zc02ElAtSnqoRlySz6tS3ns6X7y6Kx8MJn7aiplt3wm4PypjhSO4jiRvbi/4kQ/8Zk6FMpsSquosw4H1MpvS4O9ObQrBM05PoQncNrNprZ3x5NA+++2f+1fQG1Z6jlP+rPKHdJtVgiljSDYMFfF4a7cd460Cip91sgQZr2GNKl2IH7Ct8haAUFkyx+grJ1dqZYNzKWdbHuU/KZ/WeZwEYXlLE5MPqk8oO72rl6F2/x77xTZyFBtTE2R0+LW3vP0mBTooTKAHwBjoqsM1BN9agukyqyavjy29JaKZo8Pvae7Z1IdzBIpyKen5dH1I3GlUfN3Tcp343npZDrD/UEQUxBELM2JM4mQsSoyLR+2nRaNz//h3mQ6+irzoAD4/AXHkJ1sJLokZco9Gj1Y+PG4UawZajx6Ei0NPT+fLdxVNdTWuTnRyNJlo3EEGuq0cedi6G/Spzw2OK/vrLmAxlMiVW1V2EAe9D0s1b9oTeFIJlikxEF9I1sGo8sPP/WF2dvN+5O3QVBsNgYMPjj0Tf68wcGFZWEM0JQ7jQaPtETXtoPB6NTiEkJ34mjXnQZFWoLQoLpoxxm3nSvgcrvnDbmaVjnOfucRqm1J2CEqhKkHN1Nnqo2/xvjL5GTLkj8RgTjZAG+KCxgrm71yJ1EiiJ7hNSmNb6MSE0qI21NPllfHty2Fc1jEBQg1yci63cQ+lkO1ZdC045nAoIxQxjQZP4MxMKBXA0tOCobaZ4132wew21zkbaSieiM+iRtQEKXWBLshhKls/Vv/Ur8j+NV1XTf/AQYwsmsLNpTPTckmEaoZCCTnsYv6cZU1ChrMnBiY4DHD7hv9QVnpbR+fJdEf0ubX0fx8QRUaW6STWN0ciFrrwc3eW/g3dyUxb99ZcxESRvL+wrhAHvQ1Jqd/dAjzuW3hSCZYq+ii6kQ7r9zt0hlefyVqf32jknHGHVfAlQmLknhM0RCsuCDvcQCkHLXiud2T5Bg18f9pZlbYBZyhGshP+mdq2W2hib32Z04C2chtU7O2FSWU4gPEpUGwpR5mjrmL0dQwiJj1qGI+2pZm4ngZIcfXvtQNN7nOLclfwzcrShCYX4tKQ4ThZ1VN10xpwziZ1v1yF7NraL5zjCoWrDaIw589FoJEIhJW77C3euotJwEJ1pPgd8M/lajQ2XsYUDhTvZMfwV7HlB1YiGaj5XRVXNo9Fg12qZrv9/hGav5pONL4QL2BQHBlMho8xGKnYcwtSuDAcw6oNXmXK1FesPb8laYWjcd0mjSdB7h/YQuMWqWvSnRraNiSD7dFnptHPnzmxcx3FJRI9bjZ7occcSKdxRIxvhvoDPy95t6sId3Z321RPS6XdWI+AP0trgJuBPVE6LeC7j//Ua49euYfy/XqP81luRg3LSSMqoOjPaYEe4OjKMYul3tZgvbWL8wgbKpzspP9VJ4UQnuiJT+7SwCvafP5k3vzwCLVoqciu41jSGpUoeaLRQMBrb9G9RnlsRPbasDXCgcKfqpDJb3UfRUaKTahoZ1dACinr4eV9bKQF9/L1XYjGmzH2jhBjV0MKkmkZ2VxRzsKQg7OW3G5svWpoIuN+hwLYjHJqO5JcVB3g/QfaEq6dlz8a47c62AB82D2dHoxWXUoaEljxfMdNq5zK9+lK2T1SZ00qSfG6MqpoM3FtUwGXDy7lkxDC+YvWz+eAfwq1j7ef2e5rZ11jLYVt+Qrja8/ZbWC2aHn+PPLKHI44jeOSup6R1pfdORUXiZLn2or9kxlswNOjSA7/vvvtoaWnh0ksv5dJLL6VEVDGmTUrt7h7qccfSm0Kw3qAEg6x77M84+yi6kA7dVbzqTsV+Z88lVSQl16PD7NXizI0vOyosGE7pnAuR9rwOrUfRFI2g/AcLKZ19O3JTM7qSEiaYTMyXPRx1HCXk81HuMSAVF0OwFSzlmAxm5m29N66oKzJI5CTXmejacqKiMWWPbY6O15SAsfZWDtvyUcPp09PW5qXAGvtcIGXuGw0Mc2qRtYawUVFh3/bNaHTqBs8X/BSPfgKGwD7V7cHAfnShs+MWJWObT2bDxR8wqSgnXIVeW5c6n2spD4eUWw+3S9bmRTfVSXrce2uxquiqRYaixBrxnrZcpdKhTyaDmur+8hq1lM2to+jUVrUaSMEQp0sDvmrVKqqrq3nllVe4/vrrqaio4PLLL2f+/Pno9amnMQm6VpHqDb0pBOsNG1c9xmcb1VuuoPfRhQhq07QidFa8ihW9UFO86k3FfqrJZuTl4M5J9ObnjZqH6YzlsCBe8lICDO15bVmReXDb/2F99EUmf+rC7wRfsYWKhZdRvnw5GlREQaxljL/IwnemzsfvDEb/5rUH58bl73MCQUx+WTUXbi0pTfj7lFpzKCguwnnMQr6KEddorHx06o/Qe47h8b2k+jm5WtXnhwPoZR9nmX7Lu8pEVC2R4kxo38rz2/jbuf+g7OrC9HS9DWaYdBGerX+Jk6wFMHu15HrUf+5ipV4jqIXoU92PEbrSoVcj5eQ8nQ9r4JDqdDSBIK0c+PDhw7nsssvQ6XQ888wzrFq1ivvvv5+f/vSnnHfeeWmfTFEU7rzzTr744gsMBgN33XUXo0eP7vHFDwa6UpHKBL0pBOsuqcJ9EXobXUjXi1k6YymaoIL10Rc58VMXxVEDKBOaLkf7hHtbsZ8qkjL9S+ehTDkjuepWJNSpwsrtK9H+aRXnxhS9me0uWlatRqPRUH7rrSlFQUwxH3Hn/L2xvJxRw0fxhT1xKpba38dk0DL/5JHsPTCWUx2fJLxGMk5AI+UQMI8AWb0Fy1ocjnqoRWasOh8nG5rYqfPhkFXuDcma0L5lLcqhqDjsRaedzz3/buxyG7WN8YIn7pwgbSZZtQ0vVuo1eu6YEH2692NadRlKKCF3nTJSZ23q0GhXmY4mGNp0acCff/55XnnlFRoaGrjssst46qmnKC8vp66ujssvv7xbBnzdunX4/X6effZZPvroI37/+9/z5z//uVdvYLCgN+b0aUg5W6QK9wFMOWd+r6ML6XoxOknHdRtCNL/X4TF2NoCQmYr9VJGU+Vptt1W3PLKHd/av46dJ2qQc696Ma5PqShRErfJ4vMFAbnuXQDrRn9sumszdytXsfUNHafM+rLILKabSHVK3YLWM1HF6+elJDZFZJ1NpbWRHc6LcqlY/PkH9rEe1HFodtoX3Uf7SpdTEjPQMakMcLnNHCw9jGTV8FEZnMGnLVbr3Y5d1GWt/xsh9G1U1zKP319Z3w38rnY9KaxNzyqo6DqIyHS3rpBiiIsg+XRrwbdu2ceONNzJz5sy458vKyrjjjju6dbIPPviA2bNnA3DKKafw6aefduv1gv4nVbgvz1bK/G//oFcCNR7Zw/rDSbyYw/HV5emqp2WiYr+rSEp3Vbfsbjv+urqkbVLBHuZgO3uq3Yn+6LQSd1w6Fc/CKdQ0thKqb+I/f96PplPeWGeaQ4gQbaEPMPo7ZFb3lNu5dt5ylKBM1Yfbw4bILFFpaWJO4SEoGM2c08+D+nHs+2BrdFEx/rSZ6Axf4uCnTbhagr2u5TDpTMwbPT9hoMj2SS1MKppM4RE5cUHj96uG6LvT7RCpy7A3V8dpmAOUSQZsO1ZDJM/eScM8en9dcSVtf5yXMB0NiIq19AtBGV6/LeUQlYwiFgpp0eUnv2LFiqTbLrjggm6dzOVyYbFYoo+1Wi2yLKMTI+4GDSnDfaf3vjDP7rZT25ZYmAZQ11YTN00rXfW03ki3diZTkZRiQwFX7DAS0gTU2q3RZkD2MlYjvzvXbDJoGT+siEBxPnnFdQkLH41GwlcwlU0j1+A2KjjMCqfuzWfBW/k8/Z+bybOVMO7UGZy68MtYi23oNUr0xziIkemtPmZ+9Tr8ba3hXLxGj7vVx+mXnoDfI2ekliPZQJFbvrmUUEBOXNAobRjkA6CYAVM03+0NepN61TWuGmrbahmbPxaAHPTcuDEXy+ZgnIb5qvkS8zzuBOlZICEsrrcWUnDK+V1OaMs6r98Wd01K4xHkdY+i88tIl67M3HmyvVAY5GT1E7FYLLS1dQxNUBRFGO9BSF8W5tl0uZQHoUbl97ssGN4eoTtDBPqrYj8Zjv99kHO2Jqn4BvIWzE9arNWV8l2mNPJTLXxGH9nJfa97wkZqfDEaJRKaDuFoqOej19cgaXVRPQAlf0zCNY052QY4OPiJPeE6e0tc7UDrEWzBIKaC0SDpwKjrWNAEvPDYAqj7DEJBZI2WlcPHsr6gmNq2OkpzSzHpTLTJbarneerzp7ht1m1AeBjO+Nc/j26LaphrTVw4Vn14impYPI0JbVklpr8+pEDdR1acR03Ibi26jWuw7syn7Be3ZmbWeKeFQudIhSCerFrP6dOns2HDBi666CI++ugjJk4c2HrdxyUZCE31ZWGeydvCPJeT1fmJoifzXE5M3hYwF4WvoxtDBNKt2Fc1jhkO54VD/+tUtwU1IYpO1FD2k/9JfF2ayncZ0chvf89nLQrnqyMLnxzJS/HB96isegkJsDk1mD25eFSyELFqg2rX9Mlb8QuvjGv5B2VMb9zJyFTe3GMLoDZctBcIGbjfMppnJAW5LZw/r21T974jvF39NrfIt2AMkDSdc8KnLUgjNaBT8cDVwuJJJrT1GzH99XUfWWne0/HdlF2Ep+1pdb2fNa4ixBNFFPCpklUDft5557Fp0ya+/vWvEwqFuOeee7J5+qFNH4Sm+qQwz1LO0qAVWh2sN5uo0+kok2XmuT1hkZNOP3bd1X1OVrGvahxPO4M5pVVIe9ZmNJwXCf0HJT0+Q35YQa1dhEUbAttYOxqvHcx5ca9LR/kunYp7WfInL7jrdJ9I+SOYPekiZt3+G1x2N3VLvk6o+nB0d69ei8eg/llE9AByi0qTXlOq6+x1S2RX3lybHeo+QwlJbHIuocp7BqY6G1e1K8FtHvMqIY2ifux2IqJBZS2h5OmcNi2yR8JgTWw3TBkWT9HBkFXa++uVxiM4j6pHhTIyazxmoZDAQCjgG4Bk1YBLksRvfvObbJ5SEKGLH7O+GHfaIwxmdJMuYvmWh7mpuRW7VhsOf4ZCMOOrCR5JbPW1t6YOnyEfS1leUkGRZKgax//8CwqrmVvebrAyFM6TimzsO3kxdTnj8eUUYvQ2U2LfSWXVSxjMfnRl5QkLlXR19buquL//7Qd5s3Vt8naoJPeJHsid8iNCx+J/YFP2m7frAbiavKoFhMnokZZ/5yhJOt5c3S4IBdnkvJ6d7kVAWAQnogQH8P7Yl1OeNiIapNOTPJ2TG0RnUlkInHJN/4XFu0N7f7287lFkt/r3KiOzxmOEeBLozwK+AYxIQA8FUvyYKbvXsrFmNPs+3J7xcac9pv1HzfTFWka2HoW8kWDKhz3/he1/S/CEFU8bm57/jKrPvTibvsBsDTBu+hjO+dqJaeV8UxpHZxFnl3aqCO5lOO/9NUc5XNjR1eEz2Tg6ch4AM7WPI530lYRjp6urn6riXs718vThJ5G1YW8/oR2qC6On+9KyBCOVSns90m++c8Pu5B+GCpZCI3pHPYqlDMlkSi3ikiyyNOPbXXtzZVMIYIqOQe3MmOaT2Tbq38jaALloaSMYJxjk12s6RIN0RNM5QY0Gr15LTru+unW4B6lz+Dx/JFy0cvAUZp1/Nzq/jG7jGmSV0o2MzBpvXygMuAK+AcwguXsEvSJFaGrjHi07mjp+tLM5kCQpnXOA7/0Rtj/WsT3iCYcU0Ehs2mjg4+Y50SEZvhYHH1TncfTTqVzz2591uRBJaRxlI22ygQJDjLZ7L8J5qULcTRVTKbrkG6peWUq1rhjlu1SFZweLPoka71ii7VBdhDClYKtqzcGkmkaMkydzTBNMKGoM+IMc+rRR/ZhJKNz/DocWrUJXXo42Lw/Z4SBYW4tu2LBoeiRaMJUsshQMdO3NGcy4C0/HWas+BtXiK8QcyMOhbeSy5mZOek9PwUEdBQ4NLXkhWk4s4IKrfxzdv2TpUrZXH+BwXTUeSYNJCTHKpGHhmHcTDz7p4qQGKbZ7IFsjgSMkXSxpdUiXrsS6Mz+c8+5ExmaND7QCvgGOMOBDgSShqYAisa+tVPUlvR13mhEM5vC1731DfftHTxPw+dhrfxDZvzFeXERxULf/XTY8XsD8G76f8jRdSVnm6vzxT/YinJcqxO3R2fB86Q4MKl6Z3pjDuNPO4KP//Cth27jTzoj7O6lV3JdMzuFR+RnV80byuCPTCGEmqzk4cdky5GBie5azyZ30/QKcMLOMmn2tuJq8mCQvRQffY1zVSxBSkGtqkGs6Wgrl6uro4qH81ltTRwz2rYMJ58P2v6qctMObM3/7Gaw/X4szUJSwmyz5KcjL5cutjVy3PkjLng6DW+AyYPpIT93v/sCIO24H4O2nnwgr37VHfTxaDV/4IVd7KXMLPurSIGWqe6AnhGSZuhUrwn/XY8fUF0tA2S9uBa2u72aND7ACvgGTWkyCMOBDgSShqTbZgMOnrmefjYEkyYj70rSl8Ar9Tlz+ctxSXng8pQr7tm3mnGuXpPzypS1lGaGLcF6qL31vRGW2T27hi92tjKozk+vRRQVU5MktzI/ZT63iXpb8lL1Smnr4i87UZQhTAwmKbwCBmhp0JSUJ90uq92stzmHONyYB4KpzJBTIJSNaMOXpouhp1vfCBiGFN6fPzWXs7KmqEQujYuKnvl8y5+hC9h8Ne+mKRmLfuMtpsE3Fl1NIzmEHE576jJmXjU2ehrHrOHvpRvSB5pQGKSPdAz2k+ve/w7n6qejjhMVSO1mbNd7PBXzpdnz0N8KADxVUQlO54y8gr7URhz11WDZbqH5pTp3BnLwRSA71H3ajrxW95xg+FW1ugLaWxrQWIqq97e1V6Oz9T1rhvHS+9D0VlfHIHtZXb6DmxBZ2nNCK2avFnRMkqA1RXb2Bm+QfJ1SUx1bc64kf/hJL3PCXNEOYksmEvqKiS68t3febG3ImFMglI1owVd5FxCBvRFre3BmLxvH5ezUEvImFZkf2BPHqxyC7w2NB9427PFqvAODVF/LJ27X4vC0paxSOHTrMsAknoDeoLyR7q9ffU2RF5v823cusfz1Lscr2ZNXlx/us8XQ6PgYCwoAPFVRCU3qDmcrGR/ps3Gl3Uf3SvL4GJp/KXFR+pA0WcsxtlDv2ss+cbMBGScqFSKy3nLS33X9n9DMLYMTd5MOcnzgrOt0vfU9EZWJ1toPaUNz40mgIvAsp16VTfwDeFtbXf0BdW33i4BVIGcLsnB+tW7EiLh+ezGtL5/2mEuXpTLRgytB1xABI6s1Fcs2yXyHgU28XczX78M2+BJ35GXxeEw22qar71ewNYC0uwamyGAZ4/re3kVdSmtSL645efyZz5Cu3r+SND57mwhaVFjcyVF0+yEi342MgIAz4UKPTj1lfqqp1h5RfGruOsy/4Lvr9/433CkMhpK1/4fTQUzR459FqSHxtrLxrrAHCYEjqLSd46wazqpJYbH6yO1/6noyB7e788wgBfxB3kxvztnvQ7/sXy1uPclP+COyVc7Cd/ztMxg5RjngD3XGfqOVHLXPOwfXWRtVzdvba0nm/EVEe++pnEnrjOxNXMJVu0VNMm5mizYn7W1oKDegNWgK+RCNmKcrBcvnt+N7agWOrA1+O+mKwrSXIuKkz2PVWYk4+pIQXB6m8uHRSK5nOkUd03pstYdnXMpUgVkaqywcZ6XZ8DASEAR/iZGPcaTp0+aU5/W4KLvh1vFcYlEGjYVjeGi56az3vt47hmDkXn04i15DDxPnnMWfxDaoG6ItJY+NGbXYVIusqP9nV9dfur6G8cnSc4erOGNjO889jUZt/Hvdj3+jBKk1lbI6Xs6yPY2o9zMgPVoEuFxbe2/H5rFuHfKwW3bByrAsWREPhap52y1OJlcjR7Um8tlTvVwkq7B33FfbOPQWPbMDoa6LMs5/Jvm0ojlaCdXXqBVMpIgYBn5e2xgZyP3gA/b6ONMimwM3srBoTPYSrqVORYgxjp9nQm4yUPfQK8t2/J+ewA68+0YhbinKYu+TbGE266GIYOox3LGpeXDqphnee25PRHHkkqqPoNWyfqOHi7YlKcRmrLh9EpNvxMRAQBlwA9P+407S+NIac+FBo+4+3Zv4dVCyp5XJtPp6GZnx6LdbyYdEfyNp77okzQL6aGg5btaAiPhL5cQWiCxo0+i7zk6muXyNZeeWBveQVH+uVx5RsQEdcCLyd+AWHhFMpi4qVzM77W/jp9n72uhX307y6Y2Eg1xwLf15KiNKltySVCEWSQMVA9cRr2/TCPna+VQPkgAZ8OTYO59iwnHsp4+fpKXCFsAwbmdyYxESW4moRGurJ03mptOqYU6YQbKnlQIP6MfQ5WoxmHW3NPiyFRkaPy+HMi0YA4eKtEXfczoSnPuOTtxMV18ZOs2E0GaKL4WN7v+D5396mep5kXlyqVEPGc+RBGdu7/4/yoEKNFlbNlwCFGXtDFDugpUDL2Iu/lrnq8kFEyqLWfkgtpkIYcMGAoFdfmvYfbwnIzS8mN2aT2sjRruQ/3/zrnzny+SfR0PrIKTNwNE5EQ6LRjc1PJrt+jXYcGvS99pjiBnSkmD2e8sfeezqzrKvRa/zQehTFfpDWl15S3bf15ZcpuOrKpBKhasYbuu+1pbrebZt3s9R9DyX5xcyzd1KNA1Wd+oRaBDknOoP8lEI3TkU93SD7gnzllmm0/P0x5HfeIPTyEQ48HV+Yd/blo9HIbRzY7cfV7FPN5+uNOQybcAJ5JaXd8uJSpRpSteO5mry4D+0jf/TI9FuuXr8N09ZHmVdUwOr8PBRJwxPnaXn63LBQzYWnXc3s2eoLkKFAuqnF/m4zEwZcMGDoaT4+1ZdIbeRoKvlPvdHIrrc7DL6joZ5db60hJ78epHMS9o9t/Zqz+AaUoMy+7Vtoa2lGI1nRaMehM82Je01vq4pTzR5XPB5a99Qk/7FXbLiDReTraiF/BP5mGSVmQmCsihguF4rXm7S4TFtRgfXcc3Ft3NirnuBUBVw5XiumgCVRNS6JAltgzq+S1iJ80Wij9IMajCc24zMlGnFLUQ7eJx8m8PQT0eeihXlKiPLTHEi71zC79Sizisfinv5lzBf/Ar0psfWvNwtStVRDyhy51o559dVQUJqeVn9M//zSphaA6NwBm6Rh3syv8ZOZy5O/fgjQVWpxoLSZCQMuGDB0Nx+fzpdIrbo5lfyn2mxuACWwH43hTDSaeKMfyU9GrqXqw+24mhox5xfh9YxEZ5qDRhPvufdI67sLYvP8vjo7OTN/hVdfkLCfRbJj1jaFH5ywEPThzzeg0fDZ8GIaLWa8Bh0mv0yZo43Ren3SiW95C+ZTfuutKJ6f9qon2JxvxFpoVDXiLmMzbn1HdVVUNe6NO1UV2Noc/qS1CG0aAx6fRIl9Z1wrWIQxUwrw/FVdNMi55gVKvVVRSVS9cz/5n94PuZ6kuviZLBDVG7SMPamQnRtVwveG99FrvOlr9cco7umA5U0tHXMHFDBddk147KogaWpxoLSZib+SoGdkeMRmLOnm49P5EnUeORqZADahtjVB/rPihJPY/e561XMFvK2cPNvKsf2otkJ1vhZ3axPQhKyR0Jvnxh2rK8GWnhBbaKYFbLU7VI3U2Jzt6AuHRSu1dR4vn40q54g1h2DMABiPUc/BkgI2b9rA2T/+MU6fF/nd90DF0+5tT7DeoGVswRfsbBqTsO1gYbz8a52rDnvrkfCIUBVyj64nr+gUHI2J8q0mv0xOIEhlVThlYLdNxZtTiLXYzNhTSjj9DCMH7koyUazZoz5RLIUufsYKRNujDWcd+w+Y53HAfyYuuQiLromxhvc5y/p42tcEqCozmkIhRsoyFIwWQ0O6YCC1mQkDLugefTCWtCd050tUtmwZSgg+2ClRZxqHz1iESednwuxxnPfl0bS1NLHzrWYOfWIHaXuSfnIb535jOmj0CfnJVNcSDOxHFzo7znOPFTBJ1dObbFvnfmy1PH/USJWfis9QGF5wnFTAWQt+BPl3RX/c3/nnUxwszCUZu97ZwL4Pt+FstJN3wkjGXraQc7/1PXQWS9LXdBu/m7N0/y9snLyn41RstBla2Ff0CZvHxIegyyxl2ILBpApseuchKrUWdpCYYy5ztKENhYAQE/e/wPgDr+IzFTH5uccxjx+D4vEknyhmltUniqWhi9/rAtF2vXeJcAHirNBq3MEizNqmcC1Dd69JDA3pFQOpzUwYcEH36GrGcpbozpdIo9Oxf8JXOXyk40ffE8wJVz1L4fD2rrfDxUZa/fh4TfV2YvOWnUPfqa4FxYk5L4DXpY/z2lP19AKq27506VgaVt6XoHxW+PWrE/L8UkgJG6nD/6Z89T/JnzwmcYGQYuERwe/14PeGVcgcjQ18/O4GtFYrc6+5NnMRGFctkuNw2DhZw8bpYZvC+4XxXow2qGGe9Ux0phQKbISYU/QpBMaxz1mEUzZizTVga/AwsaaTVx6S0Rbp0RYXAInRmlisY/WJE8Wg78dcqui96zX+cA2DRque8knnmsTQkB4zkNrMhAEXpE86M5aztHrvzpcoVZVz1Ufxz0cKzoKB/aA4w3n101PnLVNdC5KVMVNHc9qF4+M86WQ9vUHZT8Dr4IstzqjXHtnm3rqNUf9KVD4LyXJSz9FYWkzRxAoklYK5lAuPFOx7Zw1n2/+I3nUkMxGYmJBuxDgtbQGkAtZb8qjXSMzeX8GoOjMa5wc8/upSKm2nMid0GEmTeDhJA3PLqzi79CBtsoHc4nIa3VfQvDds8BVgd0UxdXm5eIx6tt1+SzQ3nWxYS9nUZgJb/xo+ns7foY/f1x5rqglxIXX1tLSuKYNDQzyyJ2VXxPHGQGozEwZckD5djJvs6YjNnqA35jDu1DP46PXE6Vydv0SpZSp9hAgQCrahkXLRaPTozXPRhc6GUBtfuXUuxcPbFwNJ8v6prkWrH8/R3U5mf80YFzbvvKAIhRRkz0Y+/Pd+FNkBUh5a/fi4IrijzTkMl/QJCmWujW9jmTOHlqeeojOpWrpSLjxS4HT5aWuqo8CgZCYCoxLSjRZXVV7JG0eHsXfvBiD8N3Q01LOjAZgcM+XLWgaOeJU6vaSEx8C6jlD2g6ujU7R24uOgLT+6X+faiYRhLQYDbz35KPuq5+BwBcjT+ai0+Zlz/iykvvZYU06IGxWeuLbvjZ570b0YGiIrMiu3r2T9kfXUumopt5RHdQl0x3kR3EBRsDy+P2VBZklj3GQ2UIIKbz/7GYd2VyAZp0HwIIrsIK+kRPVLlKwFJxRS0CjvEnDvUTGaeqy2cvJK8tLK+0+/+Bt8srE66rkjWaPH6lx1rragkD2J41CDvg8JhXzozfPRaPR4tXn4DPmYvfb419bWUrT4WjQ6bbfGPKbyJPQ5OaDREPB4ErapjljtbQQmSUhXN+dX1C27UfUlcVO+jHnwyNyk96amYDjFS29BuvIK7H+4C1qaE48XUzsRW5i34fFH2BEd46oJ95XX5kBDJXP7uu4jVb560kXhRVMfFpSmYuX2lXHKgAmtfscxA0XBUhhwQfok+TEJKBJtw+aTG5JQH06aOZRgkKd+tZK6qo/CxWZSHpJuLAbrqUz40iTOveakhNd0lqkMhQKElDZk7wco/o9jDu6IGlG9eW5Hsdna5V3m/S1FZopGXojD7iKkdHjz4W3xVeedFxShUCDpOFTF/xm+wBG0hkosuqkY/a1x24MaDXLFMCgs7PaYRyUYJBRS0JtMUUOtN+Yw4YwzmXf9D3jvudXpj1jtbQSmU0hX0eYjt7bhaqhPXevQ5qWgvP2cSQydMuFCNj61OqrMloxo7URRfsfwmpDU44rjjIl8dJWv7ofRmxEddTWirX5DJJzenwqWwoALukfMj4nScpSNzSexz1WEY88+8t75YZ+LGWx4/FHq9r3d8YTiQPF/TFAjcXhXBQF/UFUg5awrKgkpQT5Z/yw+5572SnN1OdNQsIop53wtXFCWZt6/Y5HgQ6MtiNut85jQhAWF0qZa+d5xQU6Cvg/R6tui4fNUedx0W7o2rnqMD/8TH/YP+Lw0HguiN+Yw55pvwsF32VdVh9OnxWoMUmltYo6tKvFgGYrAhCQDdQ8/Ey3UY9gwcofl0xZQmyfeqWAoiaHbWDuWHf9JXIioHm/b/0KMbnpbxYJuVxxnXOSji3x1t3LQGfLWY6fjdSbd6XiC3iMMuKB7xPyYbPzbn9jx+UYgPNqyr8UMwlXTW1S3BQP7cTY6kwqkSFqJoPcdvK3bY55VlwINKU5OmVcc1itvTT/v350xobH7OhtzkXR54TB+CuScFqzXXoNnw8Yu87jJiHiFBrM5qWdZV/URbz/7GecWrmIur3D2GCmxeKszGSrm6jw4hepqSkJe2lREdxIKhrQ6POfdif2MG7AFg5gKRoc96KU/TOvclTYZ/QePoMgaZI+ETj6CufFxcvkSbSRWyyWrOO4zkY9Onna3ctAZbv/s6XQ8QWYRBlzQIwIhiX2ffq66ra/EDNqam3E129U3Kk7MentSgZR0WqYixP0wdyPv350xobH7OhocbHnxUz5/d0PK63I22bH88m5K/udGNvz8JmhuSthn3/bNnH3FleG8cOws705eoaWwEFdT4uvDOzs58OFBzip/Az0xxWARDFYwFYSLxjLYfqTWzw4wqaYRKTcX+6jhOJs6FQy1e5Sy2cbKnX9OMGY3jLwmdaW9RiLPZqPy1Bmc0/wQtW9bcR41Ibu16MxBtIYgJebW9BYQZFfko1s56Ay3f3Z3Op6gbxAGXNAj+kPMILewkLxim/p5JStjzZ+jxwckeoLdaZmK+2HugehFumNClWCQd5/qMKp6kwlNiGjfdWciC4u25macKkVYAM6Getr+OI8C38E4L2vjqr/FeYVJjTeAZMXt1OM2tpHf6RcioEi0tQXJXbwKfW6+aig2rdyvSihXTbcewomOSVXVjLr/TwQsueHj6nTw+q1Rj3Jl+QhWx9iMqDELBClK1m5oK+Hy5XdQUFaOvq2G2iW/p3lPx3x02a1DduuY1BLuH6/Ly8XTLjM7LAizv3pNwjGz9b3oVg66j9o/uzMdT9A3CAMu6BH9IWagN+ZQefKJ7NiwMWFbmUniHNPD4LpetaDHYDYn9To1kkQoFIrLVcbRR6IXnUOtkUKyHJ0Rr5yY8zXlT0JvzEn92es85HoOgtTR4hWQFfZuSxK5UMWIJcfXoZkOKCHYWDeOfc5iHLKRvN8/QOXpZ4bzupF90sn9pgjlqunWR9CVl2MaPpzcSGFeTGGhR6NhvS4AKiWU62s38tPTLmXnfxIN2ITTz6Rk1JjwtXvzcdaoK9JJwIk1jZxwrCk66EUrSShNTdBJkS5b34tu5aD7qP0z3el4gr5DGHBBj+gvMYM53/w+fP4q++wGnLKRXF2QSquduWXvIKnoOMcalWRe57QFF3LaxZcn9xgzKHoRIVWo1a/okAyTUOQDcS1pwdCXwkV6qT57lQrxtl1v4rRXpH9xSgPatpfQF3S0im2sGxcdyQngsDck5HXTyv2mCOVKC+9NroQW28/udcCHHaFbu1ZLrU79p6zOVcfEyy5Cp9Gl7NmVW9uQ21QPEUUbCpHrD9d7JJt5nq3vRbdy0H3c/plqOp6gbxEGXNBj+kPMQDJZmXvhlzj7/UfSUsXqbFRiySsp7V51cAbbdVKFWhXFjSHnNDTSOXEtaW3N/miR3pyvXQ0froouZKw6X7hCvCyxQtzQdhSNNIJQkvndanjcRwgoEnpJIaBI7HMWq+4XyesqwSCfblCf5BXN/WqULkO5SZXQYvvZ/7Mc/K7oQ1swSLksU6NP9MDLLGWUWssY3UXPrq6kBF1FBXJ1okFUQ1Ugpz0tMOdrV0ffd199L7qVgxba58ctwoALeky/iRmcfzd6oCAa0h6tGtJO5eVaior5xj33Y87LV93e16QKtUqSOWq0Y1vSLIXGaJGe5GlgbuGnnJ1PwkImoMRXjftzu2e8AZyykTbZQIHBS5tswCGrFwdG8rrvv/hM0tx9NPdr8HQZytUUjUvdz+53Q9U7cS81hULMc3tYnZ9owGONWaqe3bAO+nxV7984aRJBpzP5gqJTWkDKH8HcSRdx9ooHaXM4+ux70a0c9EDQPu8nwZnjGWHABb0m62IGaYa0U3m5rqZGvC5nvxnwVKHWEpOeVk2iMRo7ydBR1d4eFtW3Ho5WiCfkqXU+Kq2NfGnhPPKONOGwJy4WNJKkatytFn1UbS1X5ydP58MhJxoha7ENg9nMkV07k75XS1FxOPeryU+/oj/ZiFJXLTgSc+RLm1oAWF9QQl1I7lFBVSrvPxQIJBfISZIW0AMFPZGXTdPQdSsH3QdpoLQZIBMMj0fEpycYvHQR0u5K6/vDta8y/4b0eoQzRWyFdkIKwixRqT/E7NJNvO8q4YD3dFyKDYtkZ2z+bs66MqY1SCUsmpCnlnPCj5sqqTxdUl0s2EaOoeFQYti98uwL0ZefAF+sRd96lEqbPywf2nm/GbPwu904G5MXyY06cWqHB9rbUG6SfK4OWN4W5Kbr12BXfD0qqNLodOQvuxn/t6+kzBXCMmxk1FhrdDr1BUUmK7x7aOi6lYPuB9W2gTLB8HhEGHDBcUt4yMgMPnpd/Qe26sPtnOPzZiXsn6pCO5qCyMtD/+QFUKvEjdY0a5vQz7oeTJ2qpGPCooHmGva5S1XPve+DrVy34sHw/3fKy86+ZgnvPPW4er5Wq416bHNMJfDs0x37FdkYMeVkvnTVN5C02qQLJYPJxNxvfU/1mtMK5Xb2RlPlc0/5BiZLKT0pp1IVRbGnMZgjkxXex6OhG0ATDI9HNKFQSG2irEBwXNBUfZS/3/J91W0aSeL6+/9CQfmwzOlWJ2HD44+oesDTF345Xp0rKIdbpPasAWddvIFL5oX53bQc+ITH7rgLVL7O6bzPdN+/z+1mw9//wuHPduJstIcXIqedQejge3y4O7HKP+H9xVxzylBuKm8UwtvUFgE9DMneu/Ve1YKwaydfm3owh98Nf5qpnhYoGA0/3JyegcrUcQYaTVXwwGmoqh5qtHDj9uxHBI4jhAcuOK6x2mzklZQm7cs15eWx4fFHMqdbrUK31Lm0OrhkJfh/m36u0mAmd8y0tPqPk9UrJK1j6GRo33tuNbve7lBLczTUs+M//+LUgmqmF8I+Z1FHVfyE4ckrr7sK5XbljfYwn6u2UOnVYI5MVXgPoFG9GWWATDA8XhmyBlzxeNKe2iQYvHTVl/vec//oG93qGHqkztWVgetkWDPef6ziAQcqL2TftkbV3fe7ilgyfgdnlx7sqIAvaICgD7Td9BzTDbt2I5+bKoXR68EcmajwPl4NnWhh61OGnAEPyTJ1K1ZEpx3phg2LVppqkohBCAY3yfrVv3TVtTzxsx+pvmbvtvczpludUXWuFKHljPblt3vA0Za05qO0vf8kDvvpqrvHtp1FddN76jn2gTeaSmRm1rWLezeYIxMV3sezoRsILWzHKUPOYnWediRXV0cfl996a39dlqAPSdav3lJ7DGcyz9jekDHd6ox6x10omWWkL9/vRvl8DRtr41vSxlmayDMGcPgSW9ysOl+07SxKTz3HDHuj6aQwMjKYo7cV3seroevPFrbjHPWByH3MG2+8wdKl2Re8TzbtCMK9n4pHXYhCcHwQyfNGjJrBbEYjqX8FNJKEwZy5H5k5i29g+sIvk1dSikaSyCspZfrCL3fPO+4qtOx3A4nvs9u4atm4R8eO5uHtvd8aHHIOH7VUYMSr+hI1Cdcee44Rb1SNHhwznRTG0hlLuXbytVRYKtCipcJSwbWTr83uYI6Iofvh5nBx1w83hx8fL73SkQWOMN4ZI+t3xl133cW7777L5MmTs33qpNOOAOTaWuSGBvVeT8Fxid/tTqpQFlIU/G53xoReMqJal6VCp4C+MGlLmjeUwykLzqfq4486wvSnncGc0irY+5/MeY4Z9EbTSWEMqMEc/dGrLRiUZN2AT58+nQULFvDss89m+9RdTjtSG04gOH4J/7CXqiqU5ZWU9mhyVFftWL1SrctSoVNbm1c1TA7g8us5bdGVnHPddxPfp//OzIVIMxh27U4KQwzmEAwm+syAP//88zzxxBNxz91zzz1cdNFFbNmypa9Om5Kw3nEa044EQwK9MYfK0zOTm05rlGZv6WGhk0f2dMurTLWwsbYvbFQXIn3hOWbomP0xeEcg6Gv6zIBfeeWVXHnllX11+B6T1rSjgYAQ/s8KmfphT2uUZiboRmhZVV1sZNfqYplc2PSWTAns9NvgHYGgD+kXJbYtW7bwzDPPcP/992f71FEGbB+4EP7vF3pjKAI+L48v/aFqjjWvpJQlKx/KvLGIXeCB6mKvx+pixEcUOi9sMhZRSPP8fRbREAgGOUPWIiSddtTfHI96yIOA3uSmeyTU0lsMZsgflXSx5wkFuqUu1nlB298ea9YiGgLBIKZf2shmzpzZr973gCXNNqHjhYDPS0vtMQI+9dakwUKkylmNbgu1dIfIYq/1MKB0LPZevy0tdTEICxvV3nMP+y9ZxP4LF7L/kkXU3nMPIVkGMtCS1gO66tse7PeLQJAphqwHPiAZZHrIPQ07H2/h0YzLmKZDF4s925zlaamLDURho5QRDXsDbfU1FIwcON+DjCJqXwTdQBjwgcQg0UPurQE+HsOjWa9y7mKxZ/K2dKku1pWwUenNN/dLfUjKvm2th9xnL4MpvZs+NuAQtS+CHiDujIHEINFD7o0B7tZkrkFEspxxwOfF0VCf+RxyGou9iIrY+iPrqXPVUWYpi1ahQ7t40bFEDz26rZ+EjVJGNKyN6F2Hjr+6EFH7IugBwoAPNAa4HnJvDXC/FHxlkUjOWAkGMzamNOAP4m71Yc43oje0vzaNxZ4OUqqL6Xb+EZ1JRnYn/gz0t7BRNKKxbTNOex1WnZdKaxNzyqo6doqdTJaMTIWk+zK0ne70NYGgE8KADzQGuPB/bw1wRidzDWAykSZQggqbXtjHgY8bcDb5sBYZGTuthLOuqETSSmkv9lTVxfxupKrXsY7w0LzHmnBu67nn9Gt7ZTSiceE5tD0wl1ydN1FrPVVdSKZC0tkIbQ+y2hfBwEEY8IHKANVD7q0B7peCryyTqTTBphf2sXN9xw+7s9EXfTz7qom9W+y1G42yU8JG0VltQm7TossNYh3uo+x7V6d3nD5GXzSKghJb9+tCMhWSzkZoe5DUvggGHv3SRiYYvEQMsBrpGuCMTOYawKQTpeiKgD/IgY/Vj3HgYzsBf7DjiZ5MeWo3GhoJyqc7Gb+wgfEX1zN+YQPl8wrQFAxP/1jdpFvtgwZzOKqgxsQL1d9zptoxs9XWmeHpa4Khg/DABd2mtxXX/S0S0tdkIk3gbvXhbPKpbnM1eXG3+sgv6cUPe6ccuqQLYbC2Lwr6yGj0vHshmVhkkufTDUl3ldfOZmh7gNe+CAYmwoALuk2mDHCvJnMNYDKRJjDnG7EWGXE2JhpxS1EO5nwj0Eut8CwbjR7VBfjd8MV/1Lft+S8s+HWi8e0qJG22wdrlXee1sxnaHuC1L4KBiTDggh5zvBrgTNDbKIXeoGXstJK4HHiEsdNsaLX0vso9i0ajx3UBPfGCu6rQ33B3ennt/mjrHKC1L4KByZA04B5/kHqnl1JrDiZD75W/tmzZwo9+9CNee+01hg0LG7Q//OEPjBs3jq985Su9Pr5g8JGJKMVZV1QC4Zy3q8mLpSiHsdNsnHVFJRtX/TVzYjhZMBo97l7oqRecLLow9zb481nqr1Fr2RKhbcEAZkgZcDmocPeaz3njszpqWjxUFJg478QybrtoMjpt7+r59Ho9v/jFL/j73/+ORqPJ0BULIHMjJfuD3kQpJK3E7KsmMuuy8XF94INRDKfHdQE99YKTRReaqrrn0YvQtmAAM6QM+N1rPufvmw5GHx9t9kQf37FoSq+OPWvWLBRF4R//+AfXXntt9Pm//e1v/Pvf/0an0zFjxgx+9rOf8cEHH3Dvvfei0+nIy8vjD3/4A0ajkTvuuINDhw6hKAo/+clPmDlzZq+uabBzvGmm9xS9QRtXsDYYxXB6VRfQGy+4c3Shpx69CG0LBiBDxoB7/EHe+KxOddsbn9Wx7IJJvQ6n33nnnVx55ZWcffbZALS1tbF27VqeeeYZdDodN954Ixs2bGDr1q2cd9553HDDDaxfvx6Hw8Fbb71FYWEh99xzD83NzVx77bX8+9//7tX1DHaOR830TDBYxXB6XBeQSS94kMgVCwTpMGQMeL3TS02LR3XbsRYP9U4vo4tze3WOwsJCbr31Vn7+858zffp0fD4f06ZNQ6/XAzBjxgz27t3L97//fR5++GG++c1vUlZWxtSpU9mzZw8ffPABO3fuBECWZZqbmykcoD/Gfc1gDBNni8EqhtPruoBMecEiry04ThgyQi6l1hwqCtSlIYcVmCi1ZuZHb968eYwdO5aXXnoJo9HIzp07kWWZUCjEtm3bGDt2LK+99hqXX345q1atYsKECTz33HOMGzeOiy++mFWrVvHoo49y4YUXkp+fn5FrGoxkQgzleGbAiuH43eE8cwqRk/6YMR5HxKP/4Wa4cXv434X3iqlfgkHHkLljTQYt551YFpcDj3DeiWUZqUaPcNttt7F582Zyc3NZuHAhV199NYqicNppp7FgwQJ27tzJz3/+c8xmM3q9nt/85jeUlZVx++23c+211+JyubjmmmuQpCGzvkpgsIaJs8WAE8MZjOMwRV5bMMjRhEKhZDJHxx2xVejHWjwMy2AVuiDzbHj8EdUw8fSFXx7SOfABydrl6nnlmd8X4zAFgj5iSBnwCJnuAxf0DbFV6J2LnoZSFfqAx++GP81Ur+wuGB0OUXcqDhvMrYGC/kPxeJAbGtCVlPTrtLyBwpA04ILBhfixH+A0VcEDpwFK4jaNNpxnbg9Vi9ZAQU8IyTJ1K1bgfHM98rFj6IYNwzp/HmXLlqHRDdAUTRYYuu9cMGgQkq0DnG70VovWQEFPqFuxguYnV0Ufy9XV0cflt97aX5fV74jEr0Ag6B1pjsPsqjUwrfGigiGH4vHgXPem6jbnm+tRPOrtwUMBYcAFg55uzZcW9A3n3x0uWCsYHQ6bF4wOP47prRatgYKeIDc0INfWqm+rrUVuUL+nhgIihC4YtIh86gAiDbU00Roo6Am6khJ0w4YhV1cnbisvR1dS0g9XNTAYmh54GmIT6bJlyxbOPPNMFi9ezOLFi/nKV77CTTfdhN/v5/PPP+ePf/xj0te++OKL/OEPf0h4ftu2bezevbvX13a8E8mnOhrqIRSK5lM3rnqsvy9t6BLprVaRJI0oyKkxkBXkBP2LZDJhnT9PdZt1/rwhXY0+tDzwPhKbmDVrFvfff3/08dKlS1m/fj0XXnghkydP7vbxXnjhBS666CImTZrU42s63hFSq4OT3s5JFwxNypYtA8I5b7m2Fl15ebQKfSgztAz467fFi020Hu54nCGxCb/fT319Pfn5+WzZsoVnnnmG+++/n+eff55//OMf5Ofno9frueiicNHPxx9/zPXXX09TUxNXX301U6ZM4Z133mHXrl1UVlZSUVERPfbKlSvZtm0boVCIJUuWsHDhQrZu3Rr18r1eL/feey96vZ4f/OAHFBQUcM455/Cd73wnI++tO/R169dgnMglGIAKcoJBgUano/zWWym9+WbRBx7D0DHgfnfY81bji7Xh3F0PJxFt3ryZxYsX09jYiCRJXHXVVZx55pls2bIFgKamJv7617/y8ssvYzAYuO6666Kv1el0PPbYY1RXV/Pd736XNWvWMHv2bC666KI4471x40aOHj3KM888g8/n46qrruKss85i79693HfffZSVlfHwww/zn//8h0WLFtHQ0MALL7yAwWDo0XvqKdnKS4t86uBGtAYKeoJkMmEYNaq/L2PAMHQMuKs2HDZXo/VoeHsPdZEjIfTm5mauv/56RowYEbf98OHDjB8/HlP7ivHUU0+NbjvxxBPRaDSUlJTg9Savot6zZw+7du1i8eLFQHhaWU1NDWVlZdx9992YzWbq6uqYPn06ACNGjMi68Ybs9fkO1olcAoFAkCmGjgHvhthETyksLOS+++7juuuu4+WXX44+P2rUKKqqqvB6vRgMBnbu3Mm4ceHFgkajSTiORqOhs0DeuHHjmDlzJr/97W9RFIWHHnqIESNGsGTJEtatW4fFYmH58uXR1/XHIJRs56VFPlUgEAxlho4Bj4hNqA1ciBGb6C2VlZUsXryYu+66i2984xsAFBUV8Z3vfIdrrrmGgoICfD4fOp0OWZZVjzFt2jT+8Ic/MGLECMaPHw+Ex5Ru3bqVa665BrfbzYIFC7BYLFx66aVcddVV5OXlYbPZqK9PDClni2znpUU+VSAQDGWGlhZ6pAr9i7UdVegnLOzzkYeyLPPoo4/ygx/8AIBvfOMb/OQnP+H000/vs3P2BwGfl8eX/lA1L51XUsqSlQ8JA5sGQvtdIBCkw9DxwCEtsYm+QKfT4fF4uPzyy9Hr9UydOpUZM2b0+XmzjchL9w4hTCMQCLrD0PLABX2OGAHac8T8c4FA0B2EARf0CSIM3D2ymn7wu7MagRIIBH1DVkPoTqeTn/3sZ7hcLgKBAD//+c/jWqoExw+iz7d7ZKUAsI+UCAUCQf+Q1W/t3//+d2bNmsWSJUuoqqpi6dKlvPTSS9m8BIFgQJIVYZosKBEKBILskdVm4SVLlvD1r38dgGAwiNFozObpBYIBS58P+uhKiTADg30EAkF26TMD/vzzz3PJJZfE/Xfw4EFycnJoaGjgZz/7GbfccktfnT4lHtnDEccRPHLvB8FnaxrZli1buPnmmxP2vfvuu6mpqen1+xD0P3MW38D0hV8mr6QUjSSRV1LK9IVfzowwTTpKhAKBYFDRZyH0K6+8kiuvvDLh+S+++IJbbrmFZcuWccYZZ/TV6VWRFZmV21ey/sh6al21lFvKmTdyHktnLEUnDc5pZLfddlu3jy8YmPSpME0WlAgFAkF2yWoOfN++ffz4xz/m//7v//plVObK7StZ/fnq6OMaV0308fIzlmfkHH05jezQoUN8+9vfpqmpiblz53LjjTeyePFi7rzzTtasWUNVVRWNjY04HA5uv/12ZsyYwc9//nMOHz6Mz+fjhhtuiJ5XMHDpkwLALCkRCgSC7JFVA75y5Ur8fj933303ABaLhT//+c9ZObdH9rD+yHrVbeuPrOem6Tdh0vVsPF02ppEB+Hw+HnroIYLBIOeeey433nhj3PacnByefPJJ9u7dy9KlS3nqqafYsmULL7zwAgCbNm3q0fsTdI8B20J3/t0EZIW2XW+S6zmMvrCiQ4lQIBAMOrJqwLNlrNWwu+3UJsnz1bnqsLvtjMwb2aNjZ2MaGcCECROiE8Z0usQ/3axZs6L72e12LBYLv/zlL/nlL3+Jy+Xiy1/+co/enyA9BrKSWvja/sa+7Y047MPJKzqJylGzmHP+9/r92gQCQc/I/siqfsJmtlGeJM9XZinDZrb1+hyRaWS333573FCR2GlkiqKwc+fO6LZ0p5El2zeWXbt2AeHRo2VlZdTX17Nr1y7+9Kc/8cgjj3DfffclHaAi6D2RUaqOhnoIhaKjVDeueqy/Ly3x2hqb2PH6mgFxbQKBoGcMGQNu0pmYN3Ke6rZ5I+f1OHzemdhpZBFip5F9+9vfjk4jS0ZkGtn+/fu7de7PP/+cb37zm9x+++389re/paSkhIaGBi677DK+9a1vcf3116c8r6DndDVKNeBLHV3pSwbytQkEgp4zpKRUY6vQ61x1lFnKMlKF3uV5szCN7MEHH8Rms3H11Vdn7JiC9GmpPcZjP/kuqEVOJInr7/9LvynTDeRrEwgEPWdIuWM6ScfyM5Zz0/SbsLvt2My2jHneKc87RKaRDWWyoqTWQwbytQkEgp4zpDxwgaAvGcjTxAbytQkEgp4xpDxwgaAviSimqY1S7W8G8rUJBIKeITxwgSDDDNg+cAb2tQkEgu4hDLhAIBAIBIOQIdNGJhAIBALB8cSQNOCKx4P/8GEUT2amkalNCVMjGAxyww03cPXVV9Pc3Mxrr73W6/MLBAKBYGgypAx4SJapvece9l+yiP0XLmT/JYuoveceQllSJ2toaKC5uZmnn36aPXv2sH69uja7QCAQCARdMaSq0OtWrKD5yVXRx3J1dfRx+a23ZvRcW7du5f7770er1TJy5Eh+85vf8Mtf/pKDBw/yq1/9iiNHjrB7926effZZvva1r6V8nc/n47bbbsPpdNLc3MyVV17JNddcw+LFiyksLMThcPDYY4+hFZrWAoFAMGQYMh644vHgXPem6jbnm+szEk6PEAqF+OUvf8kf//hHVq9eTVlZGS+99BJ33HEHlZWV/OY3v+H73/8+s2bNijPeyV536NAhLr74Yv72t7/x8MMP8/jjj0dfs2jRIh5//HFhvAUCgWCIMWQ8cLmhAblWfRqZXFuL3NCAYdSojJyrqamJ+vp6fvKTnwDg9Xo566yzevy6OXPm8MQTT/D6669jsVjiBpKMHTs2I9csEAgEgsHFkDHgupISdMOGIVdXJ24rL0dXUpKxcxUWFlJeXs5DDz2E1WrlzTffxGw2x+0jSRKKoqT1ur/97W+ccsopXHPNNWzevJmNGzdGX9PVhDKBQCAQHJ8MGQMumUxY58+Ly4FHsM6fh2TquSb6pk2b+MpXvhJ9vHLlSm677Ta++93vEgqFyM3NZcWKFXhiwvSjRo1iz549PP744yxZsiR8jZKk+jqNRsOdd97Ja6+9RkFBAVqtFr/f3+PrFfQxfje4asFSDgZz1/sLBAJBDxhSQi4hWaZuxQqcb65Hrq1FV16Odf48ypYtQyPGbAp6S1CG12+D3Wug9Sjkj4BJF8H5d4NW3F8CgSCzDCkDHkHxeJAbGtCVlPTK8xYI4li7HLY8nPj8zO/Dwnuzfz0CgeC4ZshUoccimUwYRo0SxluQOfzusOetxhdrw9sFAoEggwxJAy4QZBxXbThsrkbr0fB2waAk4A/S2uAm4A/296UIBHGIxJxAkAks5eGcd+vhxG35I8LbBYMKJaiw6YV9HPi4AWeTD2uRkbHTSjjrikokrfB9BP2PuAsFgkxgMIcL1tQ4YaGoRh+EbHphHzvXH8XZ6IMQOBt97Fx/lE0v7OvvSxMIAGHABYLMcf7d4YK1gtGg0Yb/nfn98POCQUXAH+TAxw2q2w58bBfhdMGAYEga8EzmtDI9jWzevHn4fL64595++22effbZXl+roI/R6sLV5j/cDDduD/+78F7RQjYIcbf6cDb5VLe5mry4W9W3CQTZZEj9svR3TisyjezFF19ky5YtrF+/nkWLFnX5unPOOafPr02QQQxmKBrX31ch6AXmfCPWImM4fN4JS1EO5nxjP1yVQBDPkDLgkZxWhEhOC2D2VRMzeq6eTiMDuPPOOzl6NHxdf/zjH3nzzTepqqri61//Oj/+8Y8pKSmhrq6Oc845h5tvvpnXX3+dRx99FJ1Ox/Dhw1mxYgWSNCSDKwJBRtAbtIydVhL3exFh7DQbeoMYHiTof4bMr3w2c1o9nUYW4YorrmDVqlUMHz6cTZs2xW2rrq7m97//Pf/85z/ZvHkzu3bt4l//+hdLlizh6aef5uyzz8blcmXsvQgEQ5Wzrqhk6rwRWItz0GjAWpzD1HkjOOuKyv6+NIEAGEIeeDo5rfySzFQK93QaWYSTTjoJAJvNhtfrjds2adIkCgoKAJg6dSoHDhzgF7/4BX/5y194+umnGTduHAsWLMjI+xAIhjKSVmL2VROZddl43K0+zPlG4XkLBhRDxgOP5LTUyHROK3aq2KpVq/j+97/PzJkz4/ZRm0YWIdWEsf379+PxeAgGg+zcuZPKykqeffZZbrzxRlavXg3AG2+8kbH3IhAMdfQGLfklZmG8BQOOIeOB92VOK1PTyNJ6H3o9P/7xj7Hb7Vx44YVMmjSJmpoavvWtb1FQUEBubi7nnntuj9+LQCAQCAYHQ2qYSUcVuh1XkxdLUQ5jp9kGjbLS0aNHueWWW3juuef6+1IEAoFA0M8MGQ8cRE5LIBAIBMcPQ8oDFwgEAoHgeGHgx40FAoFAIBAkIAy4QCAQCASDkKzmwN1uN0uXLqW1tRWTycR9991HUVFRNi9BIBAIBILjgqx64M899xxTpkzhqaee4uKLL+ahhx7K5ukFAoFAIDhuyKoHvmTJEoLBsGRpTU0NNpstm6ePEvB5aWtuJrewEL0xp1fH+v3vf8+uXbtoaGjA6/UycuRICgsLeeCBBxL2vfvuu/nWt77FCy+8gM1m4+qrr45ue/DBBxOeEwiGFH43uGrBUi7mpwsEadBnBvz555/niSeeiHvunnvuYerUqVx33XXs2bOHv//97311elWUYJCNqx5j3/bNOOwN5NlKqJwxizmLb0DS9qyd7Oc//zkAL774IlVVVfz0pz9Nuu9tt93Wo3MIBMc1QRlevw12r4HWo5A/AiZdFJ6jLkaxCgRJ6bNvx5VXXsmVV16puu3JJ59k//79fO9732PdunV9dQkJbFz1GDvWvhp97Giojz6eu+S7GTuPy+Xitttuw+l00tzczJVXXsk111zD4sWLufPOO5O+bt26daxduxav18vtt9/O1KlTWb16Na+//jqyLGO1WnnwwQeprq7mF7/4BTqdDq1Wy4oVKygrK2PlypVs27aNUCjEkiVLWLhwYcbek0DQZ7x+G2x5uONx6+GOxwvv7Z9rEggGAVnNgf/lL3/h5ZdfBsBsNqPtodfbEwI+L/u2b1bdtm/7ZgI+r+q2nnDo0CEuvvhi/va3v/Hwww/z+OOPp/W64cOH8+STT3L33Xdzxx13oCgKLS0tPP744zz11FPIsswnn3zCe++9x5QpU/j73//O97//fVpbW9m4cSNHjx7lmWee4cknn+Thhx/G4XBk7D0JBH2C3x32vNX4Ym14u0AgUCWr8akrrriC5cuX88ILLxAMBrnnnnuydu625mYcdvVxos5GO23NzRSUD8vIuWw2G0888QSvv/46FosFWZbTet3pp58OwIQJE2hoaECSJPR6Pbfccgtms5na2lpkWearX/0qjz76KN/+9rexWq3cfPPN7Nmzh127drF48WIAZFmmpub/t3d3IVHtexjHn9JtmrM7dvYEm4iCw6YNBSK6IW9Eo0ndhheZoY06SN0UhAkyiVISmhqENwljYiW9IJkE0gvnQqUXCCyKXoiw8KaU4WCdYFcaTeo6F+487ZdqbzP/60/fz91ysdY8a1Cfcf1/M4a1aNGiWbkm4It49Z+p2+Z/5pfhqf3//NfcZgIsMacF7vV6dfTo0bl8yGnxixdrkXeJXjwd+cO+b7/zKn7x4ll7rGPHjikpKUl+v1/9/f26cuXKXzru3r17ys3N1cOHD7V06VINDAyot7dXXV1dev36tfLy8uQ4jvr6+pSSkqKdO3fqwoULOnLkiHw+n9asWaO6ujpNTk4qFApp2bJls3ZNwBfh+X5qzfuXJ3/c949lU/sB/KmvZkLkmwWx+uGn1N+sgb/zw0+pnz2N/r61a9dq3759On/+vBISEhQVFaVIJPLJ44aHhxUIBBSJRFRbW6sVK1YoLi5OeXl5iomJ0ZIlSzQyMqKkpCQFg0E1Nzdr/vz5qqqq0qpVq3Tjxg35/X6NjY3J5/PJ4/HM2jUBX0TMwqmBtffXwN/58Wem0YGP+Ko+C/39KfSX/32mb7/zfvYUOoDP9G4K/eG//z+F/uPPTKEDn/BVFfg7s/k+cACzhPeBA3/LV1ngAADYjn9mAgCAhShwAAAsRIEDAGAhChwAAAtR4AAAWIgCBwDAQhQ4AAAWosABALAQBQ4AgIUocAAALESBAwBgIQocAAALUeAAAFiIAgcAwEIUOAAAFqLAAQCwEAUOAICFKHAAACxEgQMAYCHrCnxsbEw7duyQ3+/Xtm3b9Pz5c9ORXOXly5favn27iouLVVBQoNu3b5uO5Fo9PT2qqKgwHcM1JicnVVNTo4KCApWUlOjx48emI7nS3bt3VVJSYjqGK719+1bBYFB+v1/5+fnq6+szHcl1JiYmVFVVpcLCQhUVFenJkyczPpd1BX7mzBmtXr1aHR0d2rBhg0KhkOlIrtLe3q7U1FSdOnVKjY2Nqq2tNR3Jlfbv36+mpiZNTk6ajuIavb29ikQi6uzsVEVFhQ4cOGA6kuu0tbVpz549evPmjekornTu3DklJCSoo6NDbW1tqqurMx3JdS5duiRJOn36tMrKytTY2Djjc0XPVqi5UlpaqomJCUlSOByW1+s1nMhdSktLFRMTI2nqld6CBQsMJ3Kn5ORk+Xw+dXZ2mo7iGrdu3VJaWpokKSkpSffv3zecyH2WL1+u5uZm7d6923QUV8rOzlZWVtb0dlRUlME07uTz+ZSRkSHp8zvM1QXe1dWl48eP/+ZrDQ0NSkxMVCAQ0KNHj9Te3m4onXkfe36ePn2qYDCo6upqQ+nc4UPPUU5Ojq5fv24olTu9evVKHo9nejsqKkrj4+OKjnb1r4k5lZWVpeHhYdMxXCs+Pl7S1PdSWVmZysvLzQZyqejoaFVWVqqnp0eHDh2a+Ykciw0ODjrr1q0zHcN1BgYGnJycHOfy5cumo7haf3+/U15ebjqGazQ0NDgXL16c3k5LSzOYxr2GhoaczZs3m47hWuFw2Nm4caPT1dVlOorrjYyMOBkZGc7o6OiMjrduDby1tVXd3d2SpIULF3KL5ncGBwe1a9cuNTU1KT093XQcWCQ5OVlXr16VJN25c0crV640nAi2efbsmbZu3apgMKj8/HzTcVypu7tbra2tkqS4uDjNmzdvxj1m3b2xTZs2qbKyUmfPntXExIQaGhpMR3KVpqYmRSIR1dfXS5I8Ho9aWloMp4IN1q9fr2vXrqmwsFCO4/Czhb/t8OHDevHihUKh0PSAcVtbm2JjYw0nc4/MzExVVVWpqKhI4+Pjqq6unvGs0jzHcZxZzgcAAL4w626hAwAAChwAACtR4AAAWIgCBwDAQhQ4AAAWosABALAQBQ4AgIUocAAfdOLECRUXF8txHN28eVOZmZkaHR01HQuA+CAXAB/hOI4CgYCys7N18uRJ1dfXKyUlxXQsAKLAAXzC0NCQcnNztWXLFlVWVpqOA+BX3EIH8FHhcFjx8fF68OCBeL0PuAcFDuCDRkdHtXfvXrW0tCg2NlYdHR2mIwH4FQUO4IMOHjyo9PR0JSYmqqamRqFQSENDQ6ZjARBr4AAAWIm/wAEAsBAFDgCAhShwAAAsRIEDAGAhChwAAAtR4AAAWIgCBwDAQv8DErBkE675rUQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 576x396 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
358
359
360
   "source": [
    "n = 100\n",
    "\n",
361
362
363
364
365
366
    "plt.scatter(deepof_train[:n,10,0], deepof_train[:n,10,1], label='Nose')\n",
    "plt.scatter(deepof_train[:n,10,2], deepof_train[:n,10,3], label='Right ear')\n",
    "plt.scatter(deepof_train[:n,10,4], deepof_train[:n,10,5], label='Right hips')\n",
    "plt.scatter(deepof_train[:n,10,6], deepof_train[:n,10,7], label='Left ear')\n",
    "plt.scatter(deepof_train[:n,10,8], deepof_train[:n,10,9], label='Left hips')\n",
    "plt.scatter(deepof_train[:n,10,10], deepof_train[:n,10,11], label='Tail base')\n",
lucas_miranda's avatar
lucas_miranda committed
367
368
369
370
371
372
373
374
375
376
377
378
    "\n",
    "\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('y')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
379
    "# Build models and get learning rate (1-cycle policy)"
lucas_miranda's avatar
lucas_miranda committed
380
381
382
383
384
385
386
387
388
389
390
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Seq 2 seq Variational Auto Encoder"
   ]
  },
  {
   "cell_type": "code",
391
   "execution_count": 13,
lucas_miranda's avatar
lucas_miranda committed
392
393
394
395
396
397
398
399
400
401
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "import tensorflow.keras as k\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
402
   "execution_count": 14,
lucas_miranda's avatar
lucas_miranda committed
403
404
405
406
407
408
409
410
411
412
413
414
   "metadata": {},
   "outputs": [],
   "source": [
    "NAME = 'Baseline_AE_512_wu10_slide10_gauss_fullval'\n",
    "log_dir = os.path.abspath(\n",
    "    \"logs/fit/{}_{}\".format(NAME, datetime.now().strftime(\"%Y%m%d-%H%M%S\"))\n",
    ")\n",
    "tensorboard_callback = k.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)"
   ]
  },
  {
   "cell_type": "code",
415
   "execution_count": 15,
lucas_miranda's avatar
lucas_miranda committed
416
417
418
   "metadata": {},
   "outputs": [],
   "source": [
419
    "from deepof.models import SEQ_2_SEQ_AE, SEQ_2_SEQ_GMVAE"
lucas_miranda's avatar
lucas_miranda committed
420
421
422
423
   ]
  },
  {
   "cell_type": "code",
424
   "execution_count": 16,
lucas_miranda's avatar
lucas_miranda committed
425
426
427
   "metadata": {},
   "outputs": [],
   "source": [
428
    "encoder, decoder, ae = SEQ_2_SEQ_AE().build(deepof_train.shape)"
lucas_miranda's avatar
lucas_miranda committed
429
430
431
432
   ]
  },
  {
   "cell_type": "code",
433
   "execution_count": 17,
lucas_miranda's avatar
lucas_miranda committed
434
   "metadata": {},
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"SEQ_2_SEQ_AE\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "SEQ_2_SEQ_Encoder (Sequentia (None, 16)                1787600   \n",
      "_________________________________________________________________\n",
      "SEQ_2_SEQ_Decoder (Sequentia multiple                  2685354   \n",
      "=================================================================\n",
      "Total params: 4,430,762\n",
      "Trainable params: 4,426,410\n",
      "Non-trainable params: 4,352\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
455
456
457
458
459
460
   "source": [
    "ae.summary()"
   ]
  },
  {
   "cell_type": "code",
461
   "execution_count": 20,
lucas_miranda's avatar
lucas_miranda committed
462
   "metadata": {},
463
464
465
466
467
468
469
470
471
472
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 9.16 s, sys: 3.47 s, total: 12.6 s\n",
      "Wall time: 7.14 s\n"
     ]
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
473
474
475
476
477
   "source": [
    "%%time\n",
    "\n",
    "tf.keras.backend.clear_session()\n",
    "\n",
478
    "encoder, generator, grouper, gmvaep, kl_warmup_callback, mmd_warmup_callback = SEQ_2_SEQ_GMVAE(loss='ELBO',\n",
lucas_miranda's avatar
lucas_miranda committed
479
480
481
    "                                                                               number_of_components=30,\n",
    "                                                                               kl_warmup_epochs=10,\n",
    "                                                                               mmd_warmup_epochs=10,\n",
482
    "                                                                               predictor=False).build(deepof_train.shape)"
lucas_miranda's avatar
lucas_miranda committed
483
484
485
486
   ]
  },
  {
   "cell_type": "code",
487
   "execution_count": 23,
lucas_miranda's avatar
lucas_miranda committed
488
   "metadata": {},
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10/10 [==============================] - 10s 1s/step - loss: 2095948.7500 - mae: 2.7253 - -weight_entropy: -2.3878 - dead_neurons: 0.0000e+00 - kl_divergence: 71.3445 - kl_rate: 1.0000\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgcAAAFwCAYAAAAsbtjfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAABGiElEQVR4nO3deXRU5eHG8e9kh0xCCHsgERAigmwhgkoAQS1gpQgiSyzWUkSpxIKCID+EIkhdQGuhqFCtLSoQBBWLuJQAaTASCIQIEvadQHbITPaZ+/sDSU1lEzO5meT5nOM5zOXOzHMvCA/3fe97LYZhGIiIiIh8z8PsACIiIlK9qByIiIhIBSoHIiIiUoHKgYiIiFSgciAiIiIVqByIiIhIBSoHIm7i5MmTdO3a1ZTvfv311/n444+r/Hs3bdrE66+//pPfN2bMGHJycq77e5cvX86SJUuu+/0i7s7L7AAiUv394Q9/MOV7v/32W86dO/eT37dly5af9b2jRo36We8XcXcqByI1QElJCfPnz2fbtm04HA7at2/PjBkzsFqtbNy4kbfeeouSkhJycnK4//77mThxIlu3buWFF16gbt262O12nnnmGf76178SGhrKgQMHKCsrY/bs2XTr1o1p06bRtm1bfve739GxY0fGjRvHli1byMjIYOzYsURHR+NwOHj55ZeJi4sjICCATp06cejQIZYtW1Yh65o1a/jwww8pLCzEarXy1ltv8cc//pFjx46Rl5eHv78/8+fPJz8/nxUrVuBwOAgICGDSpEmsWrWK5cuX43Q6CQoK4rnnnuPGG2+s8PnPPvssAL/5zW9YsmQJDz30EK+//jodO3YEoF+/frz++uvUr1+fRx55hD59+rBr1y7Onz/PlClTuOeee1i4cCG5ubnMnDmTfv36MWTIEBITE0lPT2fw4MFMnDgRgCVLlvDhhx/i7+9PZGQkGzZsIC4uzvW/4CIupmEFkRpgyZIleHp6smbNGtauXUvjxo2ZP38+hmHwzjvv8OKLL7JmzRpWrlzJkiVLyi+5HzhwgAULFvDpp5/i4+NDamoqY8aM4eOPP2bo0KG89tprP/qukpIS6tevz4oVK/jLX/7Cn/70J4qLi1m1ahV79uzhX//6FytWrODEiROXzXvw4EGWLVvGsmXLiI+PJzAwkJUrV/LFF19wyy238P7779O5c2dGjhzJvffey6RJk0hKSuLjjz/m/fff5+OPP2bs2LFMmDDhR5/9pz/9CYB//OMfNGvW7Irn7cSJE0RFRfHhhx/y9NNPM2/evEvuV1BQwAcffMCKFSt45513OHHiBP/5z3/Ki86aNWuw2+1X/C4Rd6IrByI1wKZNm8jPz+frr78GoLS0lAYNGmCxWHjzzTfZtGkT//rXvzh06BCGYVBYWAhAs2bNaN68efnnhISEcPPNNwPQvn17Pvroo0t+31133QVAhw4dKCkpoaCggM2bNzN48GB8fX0BGDFixI+uGlx00003YbVaARgwYAChoaEsW7aMY8eOkZSUdMm5FZs2beLYsWOMHDmyfNv58+fJy8sjKCjop5yuct7e3vTp06f8ePPy8q54vE2aNKFBgwacO3eOzZs3M2DAAAIDAwF46KGH+Oabb64rh0h1o3IgUgM4nU6mT59e/hed3W6nuLiYgoIChgwZwt13301kZCQPPPAA//73v7n4SJW6detW+Bw/P7/yH1ssFi736JWLBcBisQBgGAZeXhX/OPHwuPyFyR9+7wcffEBsbCwPPfQQgwYNIigoiJMnT17yGAcPHsyUKVPKX2dkZFCvXr3Lfs9FPzyOkpKS8h97e3uX57x4LJdy8Xgv7nfxeH/4uZ6enlfNIeIuNKwgUgNERUXx/vvvU1JSgtPp5LnnnuPVV1/l2LFj2Gw2Jk6cSL9+/di6dWv5PpWtT58+rF27lpKSEsrKyi571eF/JSQkMGTIEB588EFatWpFXFwcDocDuPAXbllZWfkxrlu3joyMDODCHQW/+c1vLvmZP3xfcHAwu3fvBmDr1q1kZmb+rOO8qE+fPnz55Zfk5+cD8OGHH1bK54pUB7pyIOJGCgoKfnTJfcWKFfz+97/npZdeYsiQITgcDm6++WamTZtG3bp1ufPOOxk4cCA+Pj6Eh4fTpk0bjh07ho+PT6VmGzp0KEeOHOH++++nbt26tGjRgjp16lz1fWPGjGHmzJnlf7l26dKF/fv3A3DbbbcxefJk5syZw3PPPcejjz7KmDFjsFgsWK1WFi1adMl/8Q8YMIDRo0ezcOFCJk+ezB//+EdWrlxJhw4d6NChQ6Uc7+23387w4cMZMWIEfn5+tG3b9pqOV8QdWPTIZhGpDAkJCWRnZzN48GAA5s6di6+vb/kwQE3z7bffsnPnTh5++GEA/v73v7Nr1y7+/Oc/mxtMpBKoHIhIpTh79izTpk0jKysLp9NJu3bt+OMf/0hAQIDZ0VzCZrMxffp0Dh8+jMVioVmzZsyZM4cmTZqYHU3kZ1M5EBERkQo0IVFEREQqUDkQERGRClQOREREpAKVAxERYc2Ok7Scto6//eew2VGkGlA5EBERko5ceN7Gba0bmJxEqgOVAxERIelIDlZfL25uFmh2FKkGVA5ERGq5jPwiDmfZiWxZH0+Pyz9jQmoPlQMRkVru4pBC91bBJieR6kLlQESklrtYDnq00nwDuUDlQESklks6koOftwcdm1/98ddSO6gciIjUYnkFJaSdyScirD4+XvorQS7Q7wQRkVps29FcQPMNpCKVAxGRWmzr4WxA5UAqUjkQEanFko7m4O1pISKsvtlRpBpRORARqaVsxWXsPnWOzi2C8PP2NDuOVCMqByIitVTysVychoYU5Me8XPGhpaWlTJ8+nVOnTlFSUsL48eO54YYbeO655zAMg3bt2vHcc8/h6elJbGwsK1aswMvLi/Hjx9O3b1+KioqYMmUK2dnZ+Pv789JLLxEcHExKSgovvPACnp6eREVFMWHCBAAWLVrEpk2b8PLyYvr06XTq1MkVhyUiUqMkHdF8A7k0l5SDtWvXEhQUxCuvvEJubi5Dhgyhffv2PPXUU9x6661MmzaNuLg4unTpwrJly1i9ejXFxcVER0fTs2dPli9fTnh4ODExMaxbt47FixczY8YMZs2axcKFCwkNDWXcuHHs2bMHgKSkJFatWkV6ejoxMTGsXr3aFYclIlKjbD2cg4cFut2g+QZSkUvKwYABA+jfv3/5a09PTxYuXIinpyclJSVkZmbSoEEDUlNT6dq1Kz4+Pvj4+BAWFkZaWhrJycmMHTsWgN69e7N48WJsNhslJSWEhYUBEBUVRWJiIj4+PkRFRWGxWAgJCcHhcJCTk0NwsJqwiMjlFJU62HUyj1ua1yPAz9vsOFLNuGTOgb+/P1arFZvNxpNPPsnEiRPx9PTk1KlT3HfffeTm5tKqVStsNhsBAQEV3mez2Sps9/f3Jz8/H5vNhtVqrbDvlbaLiMjl7TyeR6nDoHtL/UNKfsxlExLT09N5+OGHGTx4MIMGDQKgefPmfPnll4waNYoXX3wRq9WK3W4vf4/dbicgIKDCdrvdTmBg4CX3vdz2HxYOERH5MT1sSa7EJeUgKyuLMWPGMGXKFIYNGwbA448/ztGjR4EL/7r38PCgU6dOJCcnU1xcTH5+PocOHSI8PJyIiAg2b94MQHx8PN26dcNqteLt7c3x48cxDIOEhAQiIyOJiIggISEBp9PJ6dOncTqdGlIQEbmKpKMXJiPeqisHcgkumXPw5ptvcv78eRYvXszixYsBmDhxItOmTcPb25s6deowd+5cGjVqxOjRo4mOjsYwDCZNmoSvry+jRo1i6tSpjBo1Cm9vbxYsWADA7NmzmTx5Mg6Hg6ioKDp37gxAZGQkI0aMwOl0MnPmTFcckohIjVFS5iT5WC43NQmgvr+P2XGkGrIYhmGYHUJERKpO8rFcHnjjax6+/QaeH3yL2XGkGtIiSCIitYzmG8jVqByIiNQy5Ysfab6BXIbKgYhILeJwGmw/mkurhv40DvQzO45UUyoHIiK1yN708+QXl9FDQwpyBSoHIiK1yFbNN5BroHIgIlKL6GFLci1UDkREagnDMEg6kkPzoDq0qF/X7DhSjakciIjUEgcybOQWlOqqgVyVyoGISC1xcb6BJiPK1agciIjUElr8SK6VyoGISC1wYb5BNg2tvrRq6G92HKnmVA5ERGqB4zkFnD1fTI9WwVgsFrPjSDWnciAiUgtsPawhBbl2KgciIrVA+WTE1ioHcnUqByIitUDS0Wzq1fEmvHGA2VHEDagciIjUcKfzCjmRU8itLYPx8NB8A7k6lQMRkRpu21GtbyA/jcqBiEgN940mI8pPpHIgIlLDJR3Jxt/Hkw4hgWZHETehciAiUoNl2Yo5lGmnW8tgvDz1R75cG/1OERGpwbbpeQpyHVQORERqsK16noJcB5UDEZEabOuRHHy9POjUop7ZUcSNqByIiNRQ5wpKSTtznq5hQfh6eZodR9yIyoGISA21/VgOhgHdWzUwO4q4GZUDEZEaKkmTEeU6qRyIiNRQ3xzJwcvDQtewILOjiJtRORARqYHsxWXsPnWOTi3qUdfHy+w44mZUDkREaqAdx3NxOA3NN5Dr4pI6WVpayvTp0zl16hQlJSWMHz+ekJAQ5syZg6enJz4+Prz00ks0bNiQ2NhYVqxYgZeXF+PHj6dv374UFRUxZcoUsrOz8ff356WXXiI4OJiUlBReeOEFPD09iYqKYsKECQAsWrSITZs24eXlxfTp0+nUqZMrDktExG1ovoH8HC4pB2vXriUoKIhXXnmF3NxchgwZQosWLXjuuee4+eabWbFiBUuXLmXs2LEsW7aM1atXU1xcTHR0ND179mT58uWEh4cTExPDunXrWLx4MTNmzGDWrFksXLiQ0NBQxo0bx549ewBISkpi1apVpKenExMTw+rVq11xWCIibmPrkRwsFujWsr7ZUcQNuaQcDBgwgP79+5e/9vT05NVXX6Vx48YAOBwOfH19SU1NpWvXrvj4+ODj40NYWBhpaWkkJyczduxYAHr37s3ixYux2WyUlJQQFhYGQFRUFImJifj4+BAVFYXFYiEkJASHw0FOTg7BwWrLIlI7FZU6SDmRR/tmgQT6eZsdR9yQS+Yc+Pv7Y7VasdlsPPnkk0ycOLG8GOzYsYP33nuPRx55BJvNRkBAQIX32Wy2Ctv9/f3Jz8/HZrNhtVor7Hul7SIitdWuE3mUlDnpofkGcp1cNoU1PT2dJ554gujoaAYNGgTAZ599xhtvvMGSJUsIDg7GarVit9vL32O32wkICKiw3W63ExgYeMl9AwMD8fb2vuRniIjUVkl6noL8TC65cpCVlcWYMWOYMmUKw4YNA+CTTz7hvffeY9myZYSGhgLQqVMnkpOTKS4uJj8/n0OHDhEeHk5ERASbN28GID4+nm7dumG1WvH29ub48eMYhkFCQgKRkZFERESQkJCA0+nk9OnTOJ1ODSmISK2WdPRCObhV8w3kOlkMwzAq+0Pnzp3L+vXrad26NXBhjsGBAwcICQkhMDAQgFtvvZUnn3yS2NhYVq5ciWEYPPbYY/Tv35/CwkKmTp1KZmYm3t7eLFiwgEaNGpGSksK8efNwOBxERUUxadIkABYuXEh8fDxOp5Nnn32WyMjIyj4kERG3UOpw0nn2lzQPqsNXT/UxO464KZeUAxERMcfO47kMWfw1D/UI44UhHc2OI25KiyCJiNQg5esbtNZkRLl+KgciIjVI+WTElpp7JddP5UBEpIZwOA2SjuZwQ4O6NK3nZ3YccWMqByIiNUTamfPkF5XpqoH8bCoHIiI1hNY3kMqiciAiUkNcLAe3aTKi/EwqByIiNYBhGCQdyaFZPT9a1K9jdhxxcyoHIiI1wKFMO9n2Erq3CsZisZgdR9ycyoGISA2w9Ug2oPkGUjlUDkREaoDyxY9UDqQSqByIiLg5wzDYejiHBv4+3NjIevU3iFyFyoGIiJs7mVvImfNFmm8glUblQETEzW3V+gZSyVQORETc3NbDmowolUvlQETEzSUdzSHQz4t2TQPNjiI1hMqBiIgbO3OuiGPZBdzaMhhPD803kMqhciAi4saSjmq+gVQ+lQMRETeWpMWPxAVUDkRE3NjWwznU9fHklub1zI4iNYjKgYiIm8q2FXMgw0a3G+rj7ak/zqXy6HeTiIib2nY0F4DuLTWkIJVL5UBExE0lafEjcRGVAxERN7X1SDY+nh50Dg0yO4rUMCoHIiJu6HxRKd+ln6dLaBB+3p5mx5EaRuVARMQNJR/NxTCgR2sNKUjlUzkQEXFDetiSuJLKgYiIG0o6ko2nh4WIsPpmR5EaSOVARMTNFJSUkXryHLc0r4e/r5fZcaQGckk5KC0tZcqUKURHRzNs2DA2bNhQ/nPz5s1j+fLl5a9jY2MZOnQow4cPZ+PGjQAUFRURExNDdHQ0jz76KDk5Fy6fpaSk8OCDDzJy5EgWLVpU/hmLFi1i2LBhjBw5ktTUVFcckohItbHzeB5lToMeGlIQF3FJOVi7di1BQUF88MEHLF26lDlz5pCTk8PYsWOJi4sr3y8zM5Nly5axYsUK3n77bV599VVKSkpYvnw54eHhfPDBB9x///0sXrwYgFmzZrFgwQKWL1/Orl272LNnD3v27CEpKYlVq1bx6quvMnv2bFcckohItXFxvoHKgbiKS65HDRgwgP79+5e/9vT0xG63ExMTQ3x8fPn21NRUunbtio+PDz4+PoSFhZGWlkZycjJjx44FoHfv3ixevBibzUZJSQlhYWEAREVFkZiYiI+PD1FRUVgsFkJCQnA4HOTk5BAcrP9pRKRmSjqSjcUCkTfozzlxDZdcOfD398dqtWKz2XjyySeZOHEioaGhdO7cucJ+NpuNgICACu+z2WwVtvv7+5Ofn4/NZsNqtVbY90rbRURqouIyBzuP59GuaSD16nqbHUdqKJdNSExPT+fhhx9m8ODBDBo06JL7WK1W7HZ7+Wu73U5AQECF7Xa7ncDAwEvue7ntPywcIiI1SerJcxSXOTWkIC7lknKQlZXFmDFjmDJlCsOGDbvsfp06dSI5OZni4mLy8/M5dOgQ4eHhREREsHnzZgDi4+Pp1q0bVqsVb29vjh8/jmEYJCQkEBkZSUREBAkJCTidTk6fPo3T6dSQgojUWHqeglQFl8w5ePPNNzl//jyLFy8un0y4dOlS/Pz8KuzXqFEjRo8eTXR0NIZhMGnSJHx9fRk1ahRTp05l1KhReHt7s2DBAgBmz57N5MmTcTgcREVFlQ9TREZGMmLECJxOJzNnznTFIYmIVAta/EiqgsUwDMPsECIicnVlDiedZ39J03p+bHj6TrPjSA2mRZBERNzEd+nnsZc46N6qgdlRpIZTORARcRNbD2t9A6kaKgciIm5C8w2kqqgciIi4AafTYNvRHEKD6xASVMfsOFLDqRyIiLiB/Rn5nCsspXtLzTcQ11M5EBFxA5pvIFVJ5UBExA1o8SOpSioHIiLVnGEYbD2SQ5NAX25oUNfsOFILqByIiFRzR7LsZNmK6d6qARaLxew4UguoHIiIVHMaUpCqpnIgIlLNXVzfQJMRpaqoHIiIVGOGYfD1oSyC/X1o08hqdhypJVQORESqsT2nz3P2fDF9whvh4aH5BlI1VA5ERKqxjWkZAPRt19jkJFKbqByIiFRjcfsy8PSw0KdtI7OjSC2iciAiUk1l24pJOZFHtxvqU6+ut9lxpBZRORARqaY27cvEMKCfhhSkiqkciIhUU3Hfzze4S+VAqpjKgYhINVTqcBK/P5MW9evQprFuYZSqpXIgIlINbT+aS35xGXe1a6wlk6XKqRyIiFRDcWlnAd3CKOZQORARqYbi0jKo4+3Jba0bmB1FaiGVAxGRauZYtp1DmXZ6tmmIn7en2XGkFlI5EBGpZi7epaBbGMUsKgciItVMXPmSyVoVUcyhciAiUo3Yi8vYejiH9s0CaVavjtlxpJZSORARqUYSDmZR4nBqSEFMpXIgIlKNXHwKY7+bVQ7EPCoHIiLVhGEYxKVlEOzvQ+cWQWbHkVrMyxUfWlpayvTp0zl16hQlJSWMHz+eNm3aMG3aNCwWC23btmXWrFl4eHgQGxvLihUr8PLyYvz48fTt25eioiKmTJlCdnY2/v7+vPTSSwQHB5OSksILL7yAp6cnUVFRTJgwAYBFixaxadMmvLy8mD59Op06dXLFYYmIuNSe0+fJyC9maNfmeHpoVUQxj0vKwdq1awkKCuKVV14hNzeXIUOG0K5dOyZOnEiPHj2YOXMmGzZsoEuXLixbtozVq1dTXFxMdHQ0PXv2ZPny5YSHhxMTE8O6detYvHgxM2bMYNasWSxcuJDQ0FDGjRvHnj17AEhKSmLVqlWkp6cTExPD6tWrXXFYIiIutWGvhhSkenBJORgwYAD9+/cvf+3p6cmePXvo3r07AL1792bLli14eHjQtWtXfHx88PHxISwsjLS0NJKTkxk7dmz5vosXL8Zms1FSUkJYWBgAUVFRJCYm4uPjQ1RUFBaLhZCQEBwOBzk5OQQHB7vi0EREXCZuXwaeHhZ6tdUtjGIul8w58Pf3x2q1YrPZePLJJ5k4cSKGYZQ/PMTf35/8/HxsNhsBAQEV3mez2Sps/+G+Vqu1wr5X2i4i4k4y84tJPZnHrS3rU6+Ot9lxpJZz2YTE9PR0Hn74YQYPHsygQYPw8PjvV9ntdgIDA7Fardjt9grbAwICKmy/0r5X+gwREXeyaV8GhqFVEaV6cEk5yMrKYsyYMUyZMoVhw4YB0L59e7Zu3QpAfHw8kZGRdOrUieTkZIqLi8nPz+fQoUOEh4cTERHB5s2by/ft1q0bVqsVb29vjh8/jmEYJCQkEBkZSUREBAkJCTidTk6fPo3T6dSQgoi4nY37tGSyVB8WwzCMyv7QuXPnsn79elq3bl2+7f/+7/+YO3cupaWltG7dmrlz5+Lp6UlsbCwrV67EMAwee+wx+vfvT2FhIVOnTiUzMxNvb28WLFhAo0aNSElJYd68eTgcDqKiopg0aRIACxcuJD4+HqfTybPPPktkZGRlH5KIiMuUlDnpNucr6vv7sHnKneVDsCJmcUk5EBGRa/f1wSyi/7aVR+5oyR9/1cHsOCJaBElExGx6CqNUNyoHIiImi0vLoK6PJz1aa76UVA8qByIiJjqaZedwlp2ebRri6+VpdhwRQOVARMRUF4cU7tKQglQjKgciIia6WA76qhxINaJyICJiEltxGVuPZNMhJJAmgX5mxxEpp3IgImKShANZlDoMDSlItaNyICJikri0s4CGFKT6UTkQETGB02mwcV8mDfx96NwiyOw4IhVccznIyLgwaWb79u28//77FBUVuSyUiEhNt/v0OTLzi7nzpsZ4eGi5ZKlerqkczJo1iz//+c8cPHiQp59+mj179jBjxgxXZxMRqbG0KqJUZ9dUDr799lteeOEF1q9fz7Bhw5g3bx5HjhxxdTYRkRprY1oGXh4WeoU3NDuKyI9cUzlwOBw4nU42bNhA7969KSwspLCw0NXZRERqpIz8InadPMetLYMJ9PM2O47Ij1xTObj//vuJioqiefPmdO7cmQceeIARI0a4OpuISI20aV8mAHfdrCEFqZ6u+ZHNTqcTD48LXSI3N5f69eu7NJiISE31+LJkPt9zhg1P9+HGRlaz44j8yDVdOdi4cSMLFizAbrczcOBABgwYwJo1a1ydTUSkxikpc5JwMIsbGtSldUN/s+OIXNI1lYNFixYxaNAgPvvsMzp16kRcXBzvvfeeq7OJiNQ4247mYCsuo1+7xlgsuoVRqqdrXuegXbt2bNq0iX79+uHv709paakrc4mI1Egb9uoWRqn+rqkcNGzYkDlz5vDtt9/Sq1cvXnzxRUJCQlydTUSkxtm4L4O6Pp50bxVsdhSRy7qmcrBgwQI6duzIe++9R926dQkNDWXBggWuziYiUqMczrRxJMtOr7YN8fXyNDuOyGV5XctO/v7+2O125s+fT1lZGT169KBu3bquziYiUqNoVURxF9dUDl5++WWOHTvGAw88gGEYrFmzhhMnTmgJZRGRn2DjvgvloO9NKgdSvV1TOdiyZQsff/xx+ToHd955J4MGDXJpMBGRmiS/qJSth3Po2LwejQP9zI4jckXXvHxyWVlZhdeenhovExG5VgkHsihzGvTVkIK4gWu6cjBo0CAefvhhfvnLXwKwbt067rvvPpcGExGpSS7ON7hL5UDcwDWVg8cff5z27duTmJiIYRg8/vjjbNq0ycXRRERqBqfTYOO+DBpafenYvJ7ZcUSu6pqfrfC/IiIi2LFjR2XnERGpcXadyGPwX7fwYLcWvPJgZ7PjiFzVNa+Q+L+us1OIiNQ6uoVR3M11l4NrWRN8165djB49GoA9e/YwbNgwoqOjmTNnDk6nE4DY2FiGDh3K8OHD2bhxIwBFRUXExMQQHR3No48+Sk5ODgApKSk8+OCDjBw5kkWLFpV/z6JFixg2bBgjR44kNTX1eg9JRMQl4tIy8Pa0ENW2odlRRK7JFeccjB49+pIlwDAMiouLr/jBS5cuZe3atdSpUweA5557jhkzZhAREcFrr73Gp59+yh133MGyZctYvXo1xcXFREdH07NnT5YvX054eDgxMTGsW7eOxYsXM2PGDGbNmsXChQsJDQ1l3Lhx7NmzB4CkpCRWrVpFeno6MTExrF69+nrPh4hIpco4X8S3p87Rs00DAvy8zY4jck2uWA5iYmKu+4PDwsJYuHAhzzzzDABnz54lIiICuDBfYcOGDVitVrp27YqPjw8+Pj6EhYWRlpZGcnIyY8eOBaB3794sXrwYm81GSUkJYWFhAERFRZGYmIiPjw9RUVFYLBZCQkJwOBzk5OQQHKx1y0XEfFr4SNzRFctB9+7dr/uD+/fvz8mTJ8tfh4aGkpSURPfu3dm4cSOFhYXYbDYCAgLK9/H398dms1XY7u/vT35+PjabDavVWmHfEydO4OvrS1BQUIXt+fn5KgciUi1ovoG4o+uec/BTzZs3j7feeotx48bRoEED6tevj9VqxW63l+9jt9sJCAiosN1utxMYGHjJfS+3/YeFQ0TELMVlDhIOZNGqoT+tG1mv/gaRaqLKysHmzZuZN28eS5YsIS8vj549e9KpUyeSk5MpLi4mPz+fQ4cOER4eTkREBJs3bwYgPj6ebt26YbVa8fb25vjx4xiGQUJCApGRkURERJCQkIDT6eT06dM4nU5dNRCRaiHpSA72EoeGFMTtXNMiSJXhhhtuYNy4cdSpU4cePXrQp08f4MKkx+joaAzDYNKkSfj6+jJq1CimTp3KqFGj8Pb2Ln889OzZs5k8eTIOh4OoqCg6d75wv3BkZCQjRozA6XQyc+bMqjokEZErKl8V8WaVA3Ev170IkoiIXJ5hGNw5fxPZthJ2PHcPPl5VdqFW5GfT71YRERc4nGXnWHYBUW0aqhiI29HvWBERF9h48S4FDSmIG1I5EBFxgQ17L5SDO29qZHISkZ9O5UBEpJKdLypl29EcOreoR+MAP7PjiPxkKgciIpUs4UAWZU6Dvlr4SNyUyoGISCW7OKSgVRHFXakciIhUIqfTYNO+DBoF+HJLSD2z44hcF5UDEZFKtOtkHtn2Evre1AgPj6s/2l6kOlI5EBGpRBv1oCWpAVQOREQqUdy+DLw9LUS11S2M4r5UDkREKsnZ80XsPnWeHq0aYPWtskfXiFQ6lQMRkUqiIQWpKVQOREQqyQaVA6khVA5ERCpBcZmDLQezaN3Qn5YN/c2OI/KzqByIiFSCrYdzKChx6KqB1AgqByIilSBOQwpSg6gciIj8TIZhEJeWQYCvF5Etg82OI/KzqRyIiPxMhzLtHM8poFd4Q3y89MequD/9LhYR+Zni0s4C0PcmDSlIzaByICLyM8WlZWCxwJ0qB1JDqByIiPwM5wpL2XY0l04tgmgU4Gt2HJFKoXIgIvIz/OdAJg6nwV26S0FqEJUDEZGfQbcwSk2kciAicp0cToNN+zJpHOBLh5BAs+OIVBqVAxGR67TrZB459hL6tWuMxWIxO45IpVE5EBG5ThefwthXQwpSw6gciIhcpw17M/Dx9CCqTUOzo4hUKpUDEZHrcOZcEd+ln6dH62D8fb3MjiNSqVxaDnbt2sXo0aMB2Lt3L8OHD2fUqFE8++yzOJ1OAGJjYxk6dCjDhw9n48aNABQVFRETE0N0dDSPPvooOTk5AKSkpPDggw8ycuRIFi1aVP49ixYtYtiwYYwcOZLU1FRXHpKICKC7FKRmc1k5WLp0KTNmzKC4uBi48Bf4E088wfLlyykpKWHTpk1kZmaybNkyVqxYwdtvv82rr75KSUkJy5cvJzw8nA8++ID777+fxYsXAzBr1iwWLFjA8uXL2bVrF3v27GHPnj0kJSWxatUqXn31VWbPnu2qQxIRKadyIDWZy8pBWFgYCxcuLH998803k5eXh2EY2O12vLy8SE1NpWvXrvj4+BAQEEBYWBhpaWkkJyfTq1cvAHr37k1iYiI2m42SkhLCwsKwWCxERUWRmJhIcnIyUVFRWCwWQkJCcDgc5VcaRERcoajUwZaDWdzYyJ8bGvibHUek0rmsHPTv3x8vr/+Ow7Vs2ZIXXniBgQMHkp2dTY8ePbDZbAQEBJTv4+/vj81mq7Dd39+f/Px8bDYbVqu1wr5X2i4i4irfHM6msNShqwZSY1XZhMQXXniB999/n88//5z777+fF198EavVit1uL9/HbrcTEBBQYbvdbicwMPCS+15u+w8Lh4hIZdtYPqTQxOQkIq5RZeWgXr165f/Cb9y4MefPn6dTp04kJydTXFxMfn4+hw4dIjw8nIiICDZv3gxAfHw83bp1w2q14u3tzfHjxzEMg4SEBCIjI4mIiCAhIQGn08np06dxOp0EBwdX1WGJSC1jGAYb0jII8PMismV9s+OIuESV3X8zd+5cJk2ahJeXF97e3syZM4dGjRoxevRooqOjMQyDSZMm4evry6hRo5g6dSqjRo3C29ubBQsWADB79mwmT56Mw+EgKiqKzp07AxAZGcmIESNwOp3MnDmzqg5JRGqhgxk2TuYW8stOzfD21N3gUjNZDMMwzA4hIuIu3tp8iD+tT2PBg515oFsLs+OIuIRqr4jIT7AhLQOLBe68qZHZUURcRuVAROQanSsoJflYLl1Cg2hg9TU7jojLqByIiFyj+AOZOJwG/W7SLYxSs6kciIhcozg9hVFqCZUDEZFr4HAabNqXQZNAXzqEBJodR8SlVA5ERK5ByolccgtK6deuMRaLxew4Ii6lciAicg3itCqi1CIqByIi1yAuLRMfLw96tmlgdhQRl1M5EBG5itN5hexNP89trRtQ16fKFpYVMY3KgYjIVWzcd2FI4S7dpSC1hCow8Kf1ewn086ZZPT9CgurQPKgOTQL98PFSdxIRiNt7cb6ByoHUDioHwFubD/9om8UCjay+5WXhYnEofx3kRwN/H81aFqnhikodbDmURdvGVkKD65odR6RKqBwAcU/34VhOAafzCknPK+J0XiGn8go5fa6QPafPkXIi75Lv8/XyIORHxcGPZvXqfP/aT+OTIm4u8XA2RaVOXTWQWkV/cwGtG1lp3ch6yZ9zOg2ybMWcyisk/dx/i0N6XhGnzxVyOq+QI1n2y352UF1vQur9oDj8T4loHOCLlx77KlJtXRxS0KqIUpuoHFyFh4eFxoF+NA70o+tl9ikqdXDmh8XhBz++WB6+Sz9/yfd6elhoGuhHyA+uODSv8OM6BNbx0vCFiAkMwyAuLYNAPy+63VDf7DgiVUbloBL4eXvSsqE/LRv6X/LnDcPgXGFphSsOp34whHE6r5DkY7k4jdxLvt/fx/NHVxwuDls0D6pD03p++Hp5uvIQRWqlAxk2TuUVcl+nZnjrCp/UIioHVcBisRBU14eguj50CKl3yX3KHE4y8ot/dPXhwn8XCsXBDNtlv6Oh1ZebmwXQv0NT+ndoSqMAPU5W5OfaoLsUpJayGIZhmB1Cro29uIz0c9+XhYvF4QdDGMeyC4ALd1p0bxnMvR2bMeCWpjQJ9DM5uYh7Gv5mItuO5ZA84x6C/X3MjiNSZVQOapDTeYV8vvsM63ens/1YLhd/ZSNvqM/A74tC86A65oYUcRN5BSVEzPmKLqFBrPl9T7PjiFQplYMa6uz5Ir7Yc4bPvk0n6UgOzu9/lbuEBjHwlqYMvKUZYQ10z7bI5XyScoo/rEhhSv+beKJvG7PjiFQplYNaIMtWzJd7zrJ+dzpfH8rG8X1TuKV5IANvacbAW5pe9lZOkdpq4oqdfJxyms+e7EX7kECz44hUKZWDWibXXsJX353ls93pbDmYRanjwi9/u6YB3NvxQlFo2yTA5JQi5nI4DbrN/Yo63p58Pa2fbiWWWkfloBY7V1DKv/deuKIQvz+LEocTgDaNrdx7S1MGdmxGu6YB+oNRap3tR3MY9mYi0T3CmDeko9lxRKqcyoEAkF9USlxaBp99m86mfZkUl10oCq0a+jPwlqbc27EZHUICVRSkVnj58zQWbzrE3x6O5O72TcyOI1LlVA7kR+zFZWzal8lnu9OJ25tBYakDgNDgOtx7SzMGdmxG5xb1VBSkxhrw53iOZNlJmfkL6vhogTGpfVQO5IoKSxxs3p/J+t3pbNibga24DICQen4M/H6OQkRYfTw8VBSkZjiVV0jPF+O486ZGvPvb7mbHETGFyoFcs6JSBwkHsvhsdzpffXeW/KILRaFJoC8DOlyYo3Bry2A8VRTEjS375hjPfbyb5wd34OHbW5odR8QUKgdyXUrKnGw5lMX6b9P58ruz5BWUAtDQ6kP/DhfmKPRoFawnTorbGfPuNuLSMvjPM30JDdZaIFI7qRzIz1bqcLL1cA6f7U7ni91nyLaXAFC/rje/aN+UgR2bcseNDfHxUlGQ6q2wxEGX57/khgZ1+XJSH7PjiJjGpeVg165dzJ8/n2XLljFp0iSysrIAOHXqFJ07d+a1114jNjaWFStW4OXlxfjx4+nbty9FRUVMmTKF7Oxs/P39eemllwgODiYlJYUXXngBT09PoqKimDBhAgCLFi1i06ZNeHl5MX36dDp16uSqQ5KrcDgNko7ksH53Out3nyEzvxiAQD8v7mnflHs7NiWqbUM9RVKqpbi0s4x5dzuP9WnNswNvNjuOiGlcVg6WLl3K2rVrqVOnDrGxseXbz507x8MPP8zSpUuxWCyMGTOG1atXU1xcTHR0NKtXr+b999/HZrMRExPDunXr2LlzJzNmzGDw4MEsXLiQ0NBQxo0bx8SJEwF46aWX+Mc//kF6ejoxMTGsXr3aFYckP5HTaZB8PJfPvk3n891nSD9XBECArxd33dyYgR2b0Se8EX7eKgpSPcz4+Fve++Y4sY/dTvdWwWbHETGNy67zhoWFsXDhwh9tX7hwIb/+9a9p3LgxqampdO3aFR8fHwICAggLCyMtLY3k5GR69eoFQO/evUlMTMRms1FSUkJYWBgWi4WoqCgSExNJTk4mKioKi8VCSEgIDoeDnJwcVx2W/AQeHhZubRnMrEEd2DK1H2t+fweP9mpFvbrefJxymseWJRMx5ysmfLCDz75Np6CkzOzIUosZhkHc3gzq1fEmIizI7DgipvJy1Qf379+fkydPVtiWnZ1NYmIizz77LAA2m42AgP8u1evv74/NZquw3d/fn/z8fGw2G1artcK+J06cwNfXl6CgoArb8/PzCQ5W669OPDwsRITVJyKsPtPvvZndp87z2e50Pvs2nX+lXvjPz9uDO8Mbc3/X5tx1c2O8NZlRqtC+s/mcPlfErzqHaCKt1HouKweX8vnnn3Pffffh6XnhMrLVasVut5f/vN1uJyAgoMJ2u91OYGDgJfcNDAzE29v7kp8h1ZfFYqFji3p0bFGPZ/rfxN70fNbvTmfdt+l8vucMn+85Q0OrD0MjWjA8MpQ2jfVQKHG9uLQMAPq1a2xyEhHzVWk9TkxMpHfv3uWvO3XqRHJyMsXFxeTn53Po0CHCw8OJiIhg8+bNAMTHx9OtWzesVive3t4cP34cwzBISEggMjKSiIgIEhIScDqdnD59GqfTqasGbsRisdA+JJCnf3ETG57qw/o/9OK3PVtS5jRYEn+Yu1/dzANvfM3KbcexF2vYQVwnbm8GHhboE97I7CgipqvSKwdHjhwhNDS0/HWjRo0YPXo00dHRGIbBpEmT8PX1ZdSoUUydOpVRo0bh7e3NggULAJg9ezaTJ0/G4XAQFRVF586dAYiMjGTEiBE4nU5mzpxZlYcklchisXBzs0BmDerAtIHt+Oq7s6zcdoKEg1kkH8tl9qffcV+nZoy4NZSIsPpavlkqTa69hB3Hc4kIq099fx+z44iYTuscSLV3MreAD5NPsmr7SU7lFQJwYyN/RtwaypCuLWgU4GtyQnF3n6Sc4g8rUpjS/yae6NvG7DgiplM5ELfhdBp8fSibldtP8MXuM5Q4nHh5WOjXrjEjbg2lT3gjTSST6/Lk8p2s3XWazyf2ol3TQLPjiJhO5UDcUl5BCR/vPMXK7SfZm34euPCMhwe+n8TYsqG/yQnFXZQ5nHSb+2/8fTzZMq2fhqtEUDkQN2cYBntOn2flthN8nHKq/GFQPVoFMzwylHs7NtMjd+WKko7kMPytRB7qEcYLQzqaHUekWlA5kBqjqNTB57vPsHLbCRIPZwMXVmMc1CWEEZGhdGpRT/8qlB95cX0ab24+xDuPRNKvXROz44hUCyoHUiMdzy5gVfIJVm0/yZnzF5Ztbtc0gOGRodzftTnBmpEu3+v/WjxHs+2kzPyFrjKJfE/lQGo0h9Mg/kAmsdtO8O+9Zyl1GPh4enBP+yYMvzWUqDYN8fTQ1YTa6mRuAVEvbaRfu8a888itZscRqTaqdJ0Dkarm6WGh702N6XtTY7JtxXy08xSx20+w7tsLKzKG1PNjWGQoD3ZrQWhwXbPjShXb+P2qiH21KqJIBbpyILWOYRiknMgjdvsJPt2Vjq24DIsFet7YkAcjW9C/Q1M9KbKW+O3fk9i4L5Mt0/rRPKiO2XFEqg2VA6nVCkrKWJeaTuz2E2w7mgtAvTre3N8lhOG3htIhpJ7JCcVVCkscdHn+S1o19Ofzib2v/gaRWkTlQOR7hzNtxG4/yeodJ8nMLwbgluaBjIgM5VddmlOvjrfJCaUybdh7lt/9Yzvj77yRqQPamR1HpFpRORD5H6UOJ5v2ZbJy2wk27svA4TTw9fJgwC1NGREZym2tG+ChSYxub/pH3/LB1uOsevx2bm2ph7WJ/JDKgcgVZJwvYs3OU8RuO8HhrAuPBg8LrsuD3VowLLIFzeppnNodGYbBHS/GUVjqYPv/3a1lt0X+h8qByDUwDIPtx3JZue0E61LTKSx14GGB3uGNGB4Zyt03N8HHS3/BuIu96ecZ+Pp/GNwlhNdHdjU7jki1o3Ig8hPlF5Xyr9R0Vm47QcqJPACC/X0Y0rU5I24NJbxJgLkB5ar+uvEgr3yxj9dHdmFwl+ZmxxGpdlQORH6G/Wfzid12gjU7T5FjLwGgS2gQv77tBh6IaK7lmqupB974mp3Hc9nx3D0E1dVqmSL/S+VApBKUlDnZsPcsK7efIH5/Jk4DHuzWgnlDO+Kt8exqJcdeQre5XxF5Q31WPX6H2XFEqiWtkChSCXy8PBjYsRkDOzbjZG4Bv39/B6uST3I2v5jFD0Vg9dX/atXF5v0ZGAZ6yJLIFeifNCKVrEX9uqwYdxv92jUmfn8mI95KJOP7hz+J+eLSMgHopyWTRS5L5UDEBer6eLFkdDdGdQ9lz+nzDFn8NQcz8s2OVeuVOZxs3pdB86A6hDexmh1HpNpSORBxES9PD+YN6cjkX4RzKq+QB95IJOlIjtmxarXkY7mcLyqjX7vGmiwqcgUqByIuZLFYmNCvLQse7Iy9uIxfv72VdanpZseqteL2XXgKo4YURK5M5UCkCjzQrQV//+2t+Hh68MQHO/jbfw6bHalWitubgZ+3B7ff2MDsKCLVmsqBSBXp1bYRsY/dTpNAX+au28vsT/fgcOpO4qpyIqeAAxk2et7YUI/kFrkKlQORKtQ+JJCPft+T8CZW/r7lKBM+2EFRqcPsWLVCXNqFIYW+GlIQuSqVA5EqFhJUh1WP38FtrYNZv/sMv/7bVnK/X11RXOdiOdB8A5GrUzkQMUG9Ot78Y0x3ftU5hO3Hcnngza85kVNgdqwaq6CkjMTD2bRrGkBIkJ6kKXI1KgciJvH18uTPI7rweJ8bOZxpZ8jir0k9mWd2rBppy8FsSsqc3HWzrhqIXAuVAxETeXhYmDawHc8P7kC2vZiRS75h4/eXv6XyaEhB5KdxaTnYtWsXo0ePBiA7O5vx48fz0EMPMXLkSI4fPw5AbGwsQ4cOZfjw4WzcuBGAoqIiYmJiiI6O5tFHHyUn58LCMSkpKTz44IOMHDmSRYsWlX/PokWLGDZsGCNHjiQ1NdWVhyTiEg/f3pI3f90Nh9Ng7D+3syLpuNmRagzDMNiYlkH9ut50Ca1vdhwRt+Cyp8EsXbqUtWvXUqfOhfG9V155hUGDBnHvvffyzTffcPjwYerUqcOyZctYvXo1xcXFREdH07NnT5YvX054eDgxMTGsW7eOxYsXM2PGDGbNmsXChQsJDQ1l3Lhx7NmzB4CkpCRWrVpFeno6MTExrF692lWHJeIy/Ts0Zfm42xj7j+1MW/Mtp/MKmXRPuFby+5m+Sz/PmfNFDOnaHE8PnUuRa+GyKwdhYWEsXLiw/PWOHTs4e/YsjzzyCJ9++indu3cnNTWVrl274uPjQ0BAAGFhYaSlpZGcnEyvXr0A6N27N4mJidhsNkpKSggLC8NisRAVFUViYiLJyclERUVhsVgICQnB4XCUX2kQcTcRYfVZPf4ObmhQl7/EHWTyqlRKHU6zY7m1jbqFUeQnc1k56N+/P15e/70wcerUKQIDA3n33Xdp1qwZS5cuxWazERAQUL6Pv78/NputwnZ/f3/y8/Ox2WxYrdYK+15pu4i7atXQn9Xj76BzaBCrd5xkzLvbyC8qNTuW29qQloGnh4U+bRuZHUXEbVTZhMSgoCD69esHQL9+/di9ezdWqxW73V6+j91uJyAgoMJ2u91OYGDgJfe93PYfFg4Rd9TQ6svyR3tw982N+c+BLIa/9Q1n9djnnyzbVkzKiTy63VCfenW9zY4j4jaqrBx069aNzZs3A7Bt2zbatGlDp06dSE5Opri4mPz8fA4dOkR4eDgRERHl+8bHx9OtWzesVive3t4cP34cwzBISEggMjKSiIgIEhIScDqdnD59GqfTSXBwcFUdlojL1PXx4s1fd+OhHmHsTT/PkL9uYf9ZXRW7VgfO5vPMh6kYhu5SEPmpLIZhuGxx95MnT/LUU08RGxvLqVOnmDFjBoWFhVitVhYsWEC9evWIjY1l5cqVGIbBY489Rv/+/SksLGTq1KlkZmbi7e3NggULaNSoESkpKcybNw+Hw0FUVBSTJk0CYOHChcTHx+N0Onn22WeJjIx01SGJVDnDMHhj8yFe/nwfgX5eLHk4ktta68FBl3M408brGw6wdtdpDAO6hAbxziO3EuzvY3Y0Ebfh0nIgIpXno50neebDVCxYmD+8M7/qHGJ2pGrleHYBf4k7wJodJ3Ea0L5ZIE/dE85dNzfWHR8iP5HKgYgb2XIwi8eXJZNfXMb0e9vxaK/Wtf4vvlN5hSyKO8Cq7ScpcxqEN7Ey6e5w+ndoioduXRS5LioHIm4m7cx5HnlnG2fOF/HIHS157r72tfL+/bPni/jrxoOsSDpBicNJ60b+TLw7nPs6NlMpEPmZVA5E3FD6uUIeeWcb+87m079DE14f2RU/b0+zY1WJzPxi3tx8iPe+OUZxmZOw4Lr84a62DO4SgpenVoQXqQwqByJu6nxRKY/9M5nEw9lEhAXxt9/U7El3OfYS3oo/xD+/PkZhqYPmQXWI6deGB7q1wFulQKRSqRyIuLGSMifPfLiLj1NO06qhP//4bXfCGtQ1O1alOldQyt8SDvNOwhHsJQ6aBvrxRL82jIgMxcdLpUDEFVQORNycYRi88sU+Fm86REOrD2//5lY6hwaZHetnyy8q5Z2Eo/wt4TD5RWU0tPry+ztvJLpHWK0ZQhExi8qBSA2x7JtjzPpkN75eniyK7spdNzcxO9J1sReX8Y/EoyyJP0xeQSn163rzeJ8bGX37DdT1cdmz4kTkB1QORGqQr747S8zyHZSUOZlz/y081OMGsyNds6JSB+99c4w3Nh0i215CoJ8X43q35pGerbD6qhSIVCWVA5EaJuVEHr97dxvZ9hKe6Hsjk39xU7VeC6G4zMHyrcf566ZDZOYXE+DrxZioVvyuVysC/fQ8BBEzqByI1EBHs+w88vckjmYXMLRrc158oFO1m7xXUuZkVfIJFsUdJP1cEXV9PHnkjpaM692aoLo1964LEXegciBSQ2Xbihn7z+3sPJ5HzzYNeOPX3arFv8TLHE7W7DzFXzYc4GRuIX7eHjx8e0se692aBlZfs+OJCCoHIjVaYYmDJ1fs5KvvztKuaQDv/rY7Tev5mZLF4TT4dNdpXt9wgCNZdnw8PYjuEcbv77yRxoHmZBKRS1M5EKnhHE6DP67dw7JvjtGsnh/v/rY7NzUNqLLvdzoNPtudzp//fYCDGTa8PS0MjwxlQr82NKtXp8pyiMi1UzkQqQUMw+Ct+MO8uD6NAD8v3hrdjTtubOjy7/zyu7O89tV+0s7k4+lhYVhECyb0a0NocM1aqEmkplE5EKlFPkk5xeRVuwCY/2BnBndpXunfYRgGm/Zl8upX+/n21Dk8LHB/l+Y8eVdbWjb0r/TvE5HKp3IgUst8fSiLx5Ylk19UxtQB7Xi8T+U89tkwDBIOZvHqV/vZeTwPgPs6NWPi3W1p07jqhjFE5OdTORCphfadyee3f0/i9LkiRt92A3/8VYef9djnbw5n8+qX+0k6mgNA/w5NmHRPOO2aBlZWZBGpQioHIrXUmXNFPPL3JNLO5HNP+yb8ZWRX6vj8tGcWJB/L4dWv9rPlYDYAd7VrzKR7wrmleT1XRBaRKqJyIFKL5ReVMv69HSQczKJLaBBv/ybymtYa2HUij1e/2s/m/ZkA9GrbkKfuCadrWH1XRxaRKqByIFLLlZQ5mbYmlTU7TtGyQV3e/W33y04c3HP6HK99dYB/7z0LwG2tg3n6Fzdxa8vgqowsIi6mciAiGIbBq1/tZ2HcQYL9fXj7N5EVrgLsP5vPa1/tZ/3uMwBE3lCfp34R7vLbIUXEHCoHIlLug63HmfHxt/h4ebBwVAStG/nz+r8P8GnqaQwDOreox1O/uInebRtW64c5icjPo3IA9HwxzuwIItVGUamDHHsJP/yDwdvTQoCfN35eHioFIjXElmn9LvtzKgciIiJSQfV6hquIiIiYTuVAREREKlA5EBERkQpUDkRERKQClQMRERGpQOVAREREKlA5EBERkQpUDkRERKQClQMRERGpQOVAREREKlA5EBERkQpUDq5g7969PPTQQ0ybNo1vvvnG7DhuLzs7m6FDh5odw63t3r2bp59+mqlTp5KVlWV2HLeWmJjIM888w5NPPklaWprZcdxeYmIi//d//2d2DLe0Y8cOpk6dytSpUzl//rzZcQCVgytKTU2lYcOGeHh40LZtW7PjuDXDMPjb3/5G8+bNzY7i1oqLi5k1axZ9+vQhJSXF7DhurbCwkJdeeonHH3+chIQEs+O4tWPHjvHdd99RXFxsdhS3FBsby/PPP8+wYcP47LPPzI4DgJfZAaqTd999l8TERAC6dOnCPffcw7333ktWVhZvv/02zzzzjMkJ3cf/nst69eoxaNAg3nnnHZOTuZf/PY/jx49nx44dvPPOO7z++usmp3MvlzqXBQUFLFu2jMmTJ5uczr1c6lz+7ne/03m8Tg6HA19fXxo1alRtrlLrkc1X8Omnn9K7d28cDgdvvfUWzz77rNmR3NaECRMIDg5m69atTJw4kYEDB5odyS2lpqbSrl077HY7S5YsYerUqWZHclu5ubnMnz+fCRMm0KxZM7Pj1AiTJ09m/vz5ZsdwOzNnzmTGjBns2rWLgwcPMmrUKLMj1Z5hhV27djF69GgAnE4nM2fOZMSIEYwePZpjx45d8j3Nmzdnzpw5vPLKK+Xvles7l4sWLeL555+nY8eOKgbfu57zaLfbmT59OnPnzqV///5VGbdau55z+ac//YmzZ8+yYMECPv/886qMW61dz7mUy7uW8zl8+HBmzpzJihUr+NWvfmVm3P8yaoElS5YY9913n/Hggw8ahmEYX3zxhTF16lTDMAxj586dxuOPP25mPLeic1k5dB4rj85l5dG5rFzufD5rxZWDsLAwFi5cWP46OTmZXr16ARfGy3bv3m1WNLejc1k5dB4rj85l5dG5rFzufD5rRTno378/Xl7/nXtps9mwWq3lrz09PSkrKzMjmtvRuawcOo+VR+ey8uhcVi53Pp+1ohz8L6vVit1uL3/tdDor/ALKtdO5rBw6j5VH57Ly6FxWLnc6n7WyHERERBAfHw9ASkoK4eHhJidyXzqXlUPnsfLoXFYencvK5U7ns3pWFhe755572LJlCyNHjsQwDObNm2d2JLelc1k5dB4rj85l5dG5rFzudD61zoGIiIhUUCuHFUREROTyVA5ERESkApUDERERqUDlQERERCpQORAREZEKVA5ERESkApUDERERqUDlQKQW27p1a5U+jvzs2bM8+uijVfZ9qampvPLKK1X2fSI1hcqBiFSZJk2asHTp0ir7voMHD5KdnV1l3ydSU9TK5ZNF5OqWLFnC+vXrcTgcREVFMWXKFCwWC6+99hqJiYmcO3eOxo0b89prr9GwYUNuu+02brnlFjIzM3nmmWd4++238fPz49ChQ9x0003Mnz+fjIwMHn74YeLi4pg2bRpWq5U9e/Zw9uxZnnjiCR544AHy8/N55plnOH78OKGhoZw5c4ZFixbRokWL8mxr1qzho48+Ii8vj759+3LfffcxZ84cCgoKyMnJYdy4cfzyl7/kL3/5CwUFBbzxxhuMGzeOl19+maSkJBwOB0OHDuWRRx4x7wSLVGO6ciAiPxIfH8/u3bv58MMP+fjjjzl79ixr167l2LFjHD58mBUrVvDFF1/QrFkz1q5dC0Bubi6PPvoon3zyCV5eXuzcuZOZM2eyfv16Tp8+TUJCwo++58yZM3zwwQe88cYbvPzyywD89a9/pVWrVqxbt44nnniC/fv3XzLj2bNn+eijj3jqqadYtWoVv//971m9ejX//Oc/efnllwkMDOTJJ5+kX79+jB8/ntjYWAA++ugjPvzwQzZs2MD27dtddAZF3JuuHIjIjyQmJpKamsrQoUMBKCoqIiQkhMGDBzN16lRWrVrFkSNHSElJISwsrPx9nTt3Lv9x27Ztadq0KQA33ngj586d+9H39OzZE4vFQnh4OHl5eQBs2bKF+fPnA9CxY8fLPrmuffv25Y+7nTZtGv/5z39466232L9/PwUFBZc8pr179/LNN98AUFBQwL59+4iMjPypp0ekxlM5EJEfcTgc/OY3v+G3v/0tAOfPn8fT05Pdu3fz9NNP88gjj9C/f388PDz44bPb/Pz8yn/s6+tb/mOLxcKlnvF2cR+LxVK+zdPT85L7/q8fftfEiRMJDAykb9++3HvvvfzrX/+65DFNmTKFX/ziFwDk5OTg7+9/1e8RqY00rCAiP3LbbbfxySefYLfbKSsr44knnuCLL75g27ZtdO/enVGjRtGyZUs2bdqEw+Go1O++/fbb+fTTTwHYt28fBw4cqFAeLmXLli08+eST3H333cTHxwMXyoCnpydlZWXlxxQbG0tpaSl2u53o6GhSUlIqNbtITaErByK13Pbt2+natWv560GDBvH888+TlpbG8OHDcTgc9OrViyFDhpCRkcGECRMYNGgQALfccgsnT56s1DxPPPEEzz77LIMGDSIsLIyGDRtWuEpwKTExMURHR+Pr60u7du1o3rw5J0+epFOnTixatIj58+fzhz/8gWPHjjFkyBDKysoYOnQoPXr0qNTsIjWFxbiW63ciIlXkk08+oUWLFnTr1o3Tp0/z61//mn//+994eOhCp0hV0ZUDEalWWrduzaxZs3A6nXh4ePD888+rGIhUMV05EBERkQpUx0VERKQClQMRERGpQOVAREREKlA5EBERkQpUDkRERKQClQMRERGp4P8B4l1twVlDsn0AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 576x396 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
lucas_miranda's avatar
lucas_miranda committed
508
509
   "source": [
    "batch_size = 512\n",
510
511
    "rates, losses = deepof.model_utils.find_learning_rate(gmvaep, deepof_train[:512*10], deepof_test[:512*10], epochs=1, batch_size=batch_size)\n",
    "deepof.model_utils.plot_lr_vs_loss(rates, losses)\n",
lucas_miranda's avatar
lucas_miranda committed
512
513
514
515
516
517
518
519
520
521
522
523
524
525
    "plt.title(\"Learning rate tuning\")\n",
    "plt.axis([min(rates), max(rates), min(losses), (losses[0] + min(losses)) / 1.4])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Encoding plots"
   ]
  },
  {
   "cell_type": "code",
526
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
527
528
529
530
531
532
533
534
535
536
537
538
   "metadata": {},
   "outputs": [],
   "source": [
    "import umap\n",
    "from sklearn.manifold import TSNE\n",
    "from sklearn.decomposition import PCA\n",
    "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n",
    "import plotly.express as px"
   ]
  },
  {
   "cell_type": "code",
539
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
540
541
542
543
544
545
546
547
548
549
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pttest\n",
    "samples = 15000\n",
    "montecarlo = 10"
   ]
  },
  {
   "cell_type": "code",
550
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
551
   "metadata": {},
552
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
   "source": [
    "weights = \"GMVAE_components=30_loss=ELBO_kl_warmup=30_mmd_warmup=30_20200804-225526_final_weights.h5\"\n",
    "\n",
    "gmvaep.load_weights(weights)\n",
    "\n",
    "if montecarlo:\n",
    "    clusts = np.stack([grouper(data[:samples]) for sample in (tqdm(range(montecarlo)))])\n",
    "    clusters = clusts.mean(axis=0)\n",
    "    clusters = np.argmax(clusters, axis=1)\n",
    "    \n",
    "else:\n",
    "    clusters = grouper(data[:samples], training=False)\n",
    "\n",
    "    \n",
    "    clusters = np.argmax(clusters, axis=1)"
   ]
  },
  {
   "cell_type": "code",
572
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
573
   "metadata": {},
574
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
   "source": [
    "def plot_encodings(data, samples, n, clusters, threshold):\n",
    "    \n",
    "    reducer  = PCA(n_components=n)\n",
    "    clusters = clusters[:, :samples]\n",
    "    filter   = np.max(np.mean(clusters, axis=0), axis=1) > threshold\n",
    "    encoder.predict(data[:samples][filter])\n",
    "    print(\"{}/{} samples used ({}%); confidence threshold={}\".format(sum(filter),\n",
    "                                                                     samples,\n",
    "                                                                     sum(filter)/samples*100,\n",
    "                                                                     threshold))\n",
    "    \n",
    "    clusters = np.argmax(np.mean(clusters, axis=0), axis=1)[filter]\n",
    "    rep = reducer.fit_transform(encoder.predict(data[:samples][filter]))\n",
    "\n",
    "    if n == 2:\n",
    "        df = pd.DataFrame({\"encoding-1\":rep[:,0],\"encoding-2\":rep[:,1],\"clusters\":[\"A\"+str(i) for i in clusters]})\n",
    "\n",
    "        enc = px.scatter(data_frame=df, x=\"encoding-1\", y=\"encoding-2\",\n",
    "                           color=\"clusters\", width=600, height=600,\n",
    "                           color_discrete_sequence=px.colors.qualitative.T10)\n",
    "\n",
    "\n",
    "    elif n == 3:\n",
    "        df3d = pd.DataFrame({\"encoding-1\":rep[:,0],\"encoding-2\":rep[:,1],\"encoding-3\":rep[:,2],\n",
    "                         \"clusters\":[\"A\"+str(i) for i in clusters]})\n",
    "\n",
    "        enc = px.scatter_3d(data_frame=df3d, x=\"encoding-1\", y=\"encoding-2\", z=\"encoding-3\",\n",
    "                           color=\"clusters\", width=600, height=600,\n",
    "                           color_discrete_sequence=px.colors.qualitative.T10)\n",
    "\n",
    "    return enc\n",
    "\n",
    "plot_encodings(data, 5000, 2, clusts, 0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confidence per cluster"
   ]
  },
  {
   "cell_type": "code",
620
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
621
   "metadata": {},
622
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
623
624
625
626
627
628
629
   "source": [
    "from collections import Counter\n",
    "Counter(clusters)"
   ]
  },
  {
   "cell_type": "code",
630
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
631
   "metadata": {},
632
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
   "source": [
    "# Confidence distribution per cluster\n",
    "for cl in range(5):\n",
    "    cl_select = np.argmax(np.mean(clusts, axis=0), axis=1) == cl\n",
    "    dt = np.mean(clusts[:,cl_select,cl], axis=0)\n",
    "    sns.kdeplot(dt, shade=True, label=cl)\n",
    "    \n",
    "plt.xlabel('MC Dropout confidence')\n",
    "plt.ylabel('Density')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
648
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
   "metadata": {},
   "outputs": [],
   "source": [
    "def animated_cluster_heatmap(data, clust, clusters, threshold=0.75, samples=False):\n",
    "    \n",
    "    if not samples:\n",
    "        samples = data.shape[0]\n",
    "    tpoints = data.shape[1]\n",
    "    bdparts = data.shape[2] // 2\n",
    "    \n",
    "    cls = clusters[:,:samples,:]\n",
    "    filt = np.max(np.mean(cls, axis=0), axis=1) > threshold\n",
    "    \n",
    "    cls = np.argmax(np.mean(cls, axis=0), axis=1)[filt]\n",
    "    clust_series = data[:samples][filt][cls==clust]\n",
    "        \n",
    "    rshape = clust_series.reshape(clust_series.shape[0]*clust_series.shape[1],\n",
    "                                  clust_series.shape[2])\n",
    "    \n",
    "    cluster_df = pd.DataFrame()\n",
    "    cluster_df['x'] = rshape[:,[0,2,4,6,8,10]].flatten(order='F')\n",
    "    cluster_df['y'] = rshape[:,[1,3,5,7,9,11]].flatten(order='F')\n",
    "    cluster_df['bpart'] = np.tile(np.repeat(np.arange(bdparts),\n",
    "                                            clust_series.shape[0]), tpoints)\n",
    "    cluster_df['frame'] = np.tile(np.repeat(np.arange(tpoints),\n",
    "                                            clust_series.shape[0]), bdparts)\n",
    "        \n",
    "    fig = px.density_contour(data_frame=cluster_df, x='x', y='y', animation_frame='frame',\n",
    "                     width=600, height=600, \n",
    "                     color='bpart',color_discrete_sequence=px.colors.qualitative.T10)\n",
    "\n",
    "    fig.update_traces(contours_coloring=\"fill\", \n",
    "                      contours_showlabels = True)\n",
    "    \n",
    "    fig.update_xaxes(range=[-3, 3])\n",
    "    fig.update_yaxes(range=[-3, 3])\n",
    "\n",
    "    return fig"
   ]
  },
  {
   "cell_type": "code",
691
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
   "metadata": {},
   "outputs": [],
   "source": [
    "# animated_cluster_heatmap(pttest, 4, clusts, samples=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Stability across runs"
   ]
  },
  {
   "cell_type": "code",
707
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
708
   "metadata": {},
709
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
   "source": [
    "weights = [i for i in os.listdir() if \"GMVAE\" in i and \".h5\" in i]\n",
    "mult_clusters = np.zeros([len(weights), samples])\n",
    "mean_conf = []\n",
    "\n",
    "for k,i in tqdm(enumerate(sorted(weights))):\n",
    "    print(i)\n",
    "    gmvaep.load_weights(i)\n",
    "\n",
    "    if montecarlo:\n",
    "        clusters = np.stack([grouper(data[:samples]) for sample in (tqdm(range(montecarlo)))])\n",
    "        clusters = clusters.mean(axis=0)\n",
    "        mean_conf.append(clusters.max(axis=1))\n",
    "        clusters = np.argmax(clusters, axis=1)\n",
    "        \n",
    "    \n",
    "    else:\n",
    "        clusters = grouper(data[:samples], training=False)\n",
    "        mean_conf.append(clusters.max(axis=1))\n",
    "        clusters = np.argmax(clusters, axis=1)\n",
    "        \n",
    "    mult_clusters[k] = clusters"
   ]
  },
  {
   "cell_type": "code",
736
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
737
   "metadata": {},
738
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
739
740
741
742
743
744
   "source": [
    "clusts.shape"
   ]
  },
  {
   "cell_type": "code",
745
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
746
747
748
749
750
751
752
753
754
755
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from itertools import combinations\n",
    "from sklearn.metrics import adjusted_rand_score"
   ]
  },
  {
   "cell_type": "code",
756
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
757
   "metadata": {},
758
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
759
760
761
762
763
764
   "source": [
    "mult_clusters"
   ]
  },
  {
   "cell_type": "code",
765
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
   "metadata": {},
   "outputs": [],
   "source": [
    "thr = 0.95\n",
    "ari_dist = []\n",
    "\n",
    "for i,k in enumerate(combinations(range(len(weights)),2)):\n",
    "    filt = ((mean_conf[k[0]] > thr) & (mean_conf[k[1]]>thr))\n",
    "    \n",
    "    ari = adjusted_rand_score(mult_clusters[k[0]][filt],\n",
    "                              mult_clusters[k[1]][filt])\n",
    "    \n",
    "    ari_dist.append(ari)"
   ]
  },
  {
   "cell_type": "code",
783
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
784
   "metadata": {},
785
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
786
787
788
789
790
791
   "source": [
    "ari_dist"
   ]
  },
  {
   "cell_type": "code",
792
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
793
   "metadata": {},
794
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
795
796
797
798
799
800
801
802
803
   "source": [
    "random_ari = []\n",
    "for i in tqdm(range(6)):\n",
    "    random_ari.append(adjusted_rand_score(np.random.uniform(0,6,50).astype(int),\n",
    "                                          np.random.uniform(0,6,50).astype(int)))"
   ]
  },
  {
   "cell_type": "code",
804
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
805
   "metadata": {},
806
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
   "source": [
    "sns.kdeplot(ari_dist, label=\"ARI gmvaep\", shade=True)\n",
    "sns.kdeplot(random_ari, label=\"ARI random\", shade=True)\n",
    "\n",
    "plt.xlabel(\"Normalised Adjusted Rand Index\")\n",
    "plt.ylabel(\"Density\")\n",
    "\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cluster differences across conditions"
   ]
  },
  {
   "cell_type": "code",
827
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
828
   "metadata": {},
829
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
830
831
832
833
834
835
836
837
838
839
840
841
842
843
   "source": [
    "%%time\n",
    "\n",
    "DLCS1_coords = DLC_social_1_coords.get_coords(center=\"B_Center\",polar=False, length='00:10:00', align='B_Nose')\n",
    "\n",
    "Treatment_coords = {}\n",
    "\n",
    "for cond in Treatment_dict.keys():\n",
    "    Treatment_coords[cond] = DLCS1_coords.filter(Treatment_dict[cond]).preprocess(window_size=13, \n",
    "                                                 window_step=10, filter=None, scale='standard', align='center')"
   ]
  },
  {
   "cell_type": "code",
844
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
845
   "metadata": {},
846
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
   "source": [
    "%%time\n",
    "\n",
    "montecarlo = 10\n",
    "\n",
    "Predictions_per_cond = {}\n",
    "Confidences_per_cond = {}\n",
    "\n",
    "for cond in Treatment_dict.keys():\n",
    "    \n",
    "    Predictions_per_cond[cond] = np.stack([grouper(Treatment_coords[cond]\n",
    "                         ) for sample in (tqdm(range(montecarlo)))])\n",
    "\n",
    "    Confidences_per_cond[cond] = np.mean(Predictions_per_cond[cond], axis=0)\n",
    "    Predictions_per_cond[cond] = np.argmax(Confidences_per_cond[cond], axis=1) \n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
867
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
868
869
870
   "metadata": {
    "scrolled": true
   },
871
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
872
873
874
875
876
877
878
879
880
   "source": [
    "Predictions_per_condition = {k:{cl:[] for cl in range(1,31)} for k in Treatment_dict.keys()}\n",
    "\n",
    "for k in Predictions_per_cond.values():\n",
    "    print(Counter(k))"
   ]
  },
  {
   "cell_type": "code",
881
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
   "metadata": {},
   "outputs": [],
   "source": [
    "for cond in Treatment_dict.keys():\n",
    "    start = 0\n",
    "    for i,j in enumerate(DLCS1_coords.filter(Treatment_dict[cond]).values()):\n",
    "        \n",
    "        update  = start + j.shape[0]//10\n",
    "        counter = Counter(Predictions_per_cond[cond][start:update])\n",
    "        start  += j.shape[0]//10\n",
    "        \n",
    "        for num in counter.keys():\n",
    "            Predictions_per_condition[cond][num+1].append(counter[num+1])"
   ]
  },
  {
   "cell_type": "code",
899
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
   "metadata": {},
   "outputs": [],
   "source": [
    "counts = []\n",
    "clusters = []\n",
    "conditions = []\n",
    "for cond,v in Predictions_per_condition.items():\n",
    "    for cluster,i in v.items():\n",
    "        counts+=i\n",
    "        clusters+=list(np.repeat(cluster, len(i)))\n",
    "        conditions+=list(np.repeat(cond, len(i)))\n",
    "        \n",
    "Prediction_per_cond_df = pd.DataFrame({'condition':conditions,\n",
    "                                       'cluster':clusters,\n",
    "                                       'count':counts})"
   ]
  },
  {
   "cell_type": "code",
919
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
920
   "metadata": {},
921
   "outputs": [],
lucas_miranda's avatar
lucas_miranda committed
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
   "source": [
    "px.box(data_frame=Prediction_per_cond_df, x='cluster', y='count', color='condition')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Others"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(5):\n",
    "    print(Counter(labels[str(i)]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "adjusted_rand_score(labels[0], labels[3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.distplot(ari_dist)\n",
    "plt.xlabel(\"Adjusted Rand Index\")\n",
    "plt.ylabel(\"Count\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import tensorflow_probability as tfp\n",
    "tfd = tfp.distributions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.stats import entropy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "entropy(np.array([0.5,0,0.5,0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tfd.Categorical(np.array([0.5,0.5,0.5,0.5])).entropy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pk = np.array([0.5,0,0.5,0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.log(pk)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.clip(np.log(pk), 0, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "-np.sum(pk*np.array([-0.69314718,        0, -0.69314718,        0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow.keras.backend as K\n",
    "entropy = K.sum(tf.multiply(pk, tf.where(~tf.math.is_inf(K.log(pk)), K.log(pk), 0)), axis=0)\n",
    "entropy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.distplot(np.max(clusts, axis=1))\n",
    "sns.distplot(clusts.reshape(clusts.shape[0] * clusts.shape[1]))\n",
    "plt.axvline(1/10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gauss_means = gmvaep.get_layer(name=\"dense_4\").get_weights()[0][:32]\n",
    "gauss_variances = tf.keras.activations.softplus(gmvaep.get_layer(name=\"dense_4\").get_weights()[0][32:]).numpy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gauss_means.shape == gauss_variances.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "k=10\n",
    "n=100\n",
    "samples = []\n",
    "for i in range(k):\n",
    "    samples.append(np.random.normal(gauss_means[:,i], gauss_variances[:,i], size=(100,32)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.stats import ttest_ind\n",
    "test_matrix = np.zeros([k,k])\n",
    "for i in range(k):\n",
    "    for j in range(k):\n",
    "        test_matrix[i][j] = np.mean(ttest_ind(samples[i], samples[j], equal_var=False)[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "threshold = 0.55\n",
    "np.sum(test_matrix > threshold)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Transition matrix\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Treatment_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Anomaly detection - the model was trained in the WT - NS mice alone\n",
    "gmvaep.load_weights(\"GMVAE_components=10_loss=ELBO_kl_warmup=20_mmd_warmup=5_20200721-043310_final_weights.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "WT_NS = table_dict({k:v for k,v in mtest2.items() if k in Treatment_dict['WT+NS']}, typ=\"coords\")\n",
    "WT_WS = table_dict({k:v for k,v in mtest2.items() if k in Treatment_dict['WT+CSDS']}, typ=\"coords\")\n",
    "MU_NS = table_dict({k:v for k,v in mtest2.items() if k in Treatment_dict['NatCre+NS']}, typ=\"coords\")\n",
    "MU_WS = table_dict({k:v for k,v in mtest2.items() if k in Treatment_dict['NatCre+CSDS']}, typ=\"coords\")\n",
    "\n",
    "preps = [WT_NS.preprocess(window_size=11, window_step=10, filter=\"gaussian\", sigma=55,shift=0, scale=\"standard\", align=True),\n",
    "         WT_WS.preprocess(window_size=11, window_step=10, filter=\"gaussian\", sigma=55,shift=0, scale=\"standard\", align=True),\n",
    "         MU_NS.preprocess(window_size=11, window_step=10, filter=\"gaussian\", sigma=55,shift=0, scale=\"standard\", align=True),\n",
    "         MU_WS.preprocess(window_size=11, window_step=10, filter=\"gaussian\", sigma=55,shift=0, scale=\"standard\", align=True)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "preds = [gmvaep.predict(i) for i in preps]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import mean_absolute_error\n",
    "reconst_error = {k:mean_absolute_error(preps[i].reshape(preps[i].shape[0]*preps[i].shape[1],12).T, \n",
    "                                       preds[i].reshape(preds[i].shape[0]*preds[i].shape[1],12).T,\n",
    "                                       multioutput='raw_values') for i,k in enumerate(Treatment_dict.keys())}\n",
    "\n",
    "reconst_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reconst_df = pd.concat([pd.DataFrame(np.concatenate([np.repeat(k, len(v)).reshape(len(v),1), v.reshape(len(v),1)],axis=1)) for k,v in reconst_error.items()])\n",
    "reconst_df = reconst_df.astype({0:str,1:float})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.boxplot(data=reconst_df, x=0, y=1, orient='vertical')\n",
    "plt.ylabel('Mean Absolute Error')\n",
    "plt.ylim(0,0.35)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
1215
   "execution_count": null,
lucas_miranda's avatar
lucas_miranda committed
1216
1217
1218
1219
1220
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check frame rates"
   ]
1221
1222
1223
1224
1225
1226
1227
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
lucas_miranda's avatar
lucas_miranda committed
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}