{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction\n", "In big and old legacy systems, tests are often a mess. Especially end-to-end-tests with UI testing frameworks like Selenium quickly become a PITA aka unmaintainable. They are running slow and you are confronted with plenty of tests that do partly the same.\n", "\n", "In this data analysis, I want to illustrate a way that can take us out of this misery. We want to spot test cases that are structural very similar and thus can be seen as duplicated. We'll calculate the similarity between tests based on their invocations of production code. We can achieve this treating our software data as observations of linear features. This opens up ways for us to leverage existing machine learning techniques like multidimensional scaling or clustering.\n", "\n", "As software data under analysis, we'll use the JUnit tests of a Java application for demonstrating the approach. \n", "\n", "_Note: The real use case originates from a software system with a massive amount of Selenium tests that uses the [Page Object pattern](https://martinfowler.com/bliki/PageObject.html). Each page object represents one HTML site of your web application. So, a page object exposes methods in the programming language you use enabling the interaction with a web site programmatically. In such a scenario, you can infer which tests are triggering the same set of UI components (like buttons). This is a good estimator for test cases that test the same use cases in the application. We can use the results of such an analysis to find repeating test scenarios as well as tests that just differ from a minor nuance of an otherwise similar use case (which could probably be tested with other means like integration or pure UI tests with a mocked backend)._" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Dataset\n", "\n", "I'm using a dataset that I've created in a previous blog post. It shows which test methods call which code in the main line (\"production\"). \n", "\n", "_Note: There are also other ways to get this structural information e. g. by mining the log file of a test execution (this would even add real runtime information as well). But for our demo purpose, the pure structural information between the test code and our production code is sufficient._\n", "\n", "First, we read in the data with Pandas." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
test_typetest_methodprod_typeprod_methodinvocations
0AddCommentTestvoid blankSiteContainsRightComment()AddCommentat.dropover.comment.boundary.GetCommentRespons...1
1AddCommentTestvoid blankSiteContainsRightCreationTime()AddCommentat.dropover.comment.boundary.GetCommentRespons...1
2AddCommentTestvoid blankSiteContainsRightUser()AddCommentat.dropover.comment.boundary.GetCommentRespons...1
3AddCommentTestvoid failsAtCommentNull()AddCommentat.dropover.comment.boundary.GetCommentRespons...1
4AddCommentTestvoid failsAtCreatorNull()AddCommentat.dropover.comment.boundary.GetCommentRespons...1
\n", "
" ], "text/plain": [ " test_type test_method prod_type \\\n", "0 AddCommentTest void blankSiteContainsRightComment() AddComment \n", "1 AddCommentTest void blankSiteContainsRightCreationTime() AddComment \n", "2 AddCommentTest void blankSiteContainsRightUser() AddComment \n", "3 AddCommentTest void failsAtCommentNull() AddComment \n", "4 AddCommentTest void failsAtCreatorNull() AddComment \n", "\n", " prod_method invocations \n", "0 at.dropover.comment.boundary.GetCommentRespons... 1 \n", "1 at.dropover.comment.boundary.GetCommentRespons... 1 \n", "2 at.dropover.comment.boundary.GetCommentRespons... 1 \n", "3 at.dropover.comment.boundary.GetCommentRespons... 1 \n", "4 at.dropover.comment.boundary.GetCommentRespons... 1 " ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "\n", "invocations = pd.read_csv(\"datasets/test_code_invocations.csv\", sep=\";\")\n", "invocations.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What we've got here are all names of our test types (`test_type`) and production types (`prod_type`) as well as the signatures of the test methods (`test_method`) and production methods (`prod_method`). We also have the amount of calls from the test methods to the production methods (`invocations`)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Analysis\n", "OK, let's do some actual work! We want to calculate the structural similarity of test cases to spot possible duplications of tests.\n", "\n", "What we have are all tests cases (aka test methods) and their calls to the production code base (= the production methods). We can transform this data to get a matrix representation that shows which test method triggers which production method by using Pandas' `pivot_table` function on our `invocations` `DataFrame`." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
prod_typeAddCommentAddScheduling
prod_methodat.dropover.comment.boundary.GetCommentResponseModel doSync(at.dropover.comment.boundary.AddCommentRequestModel)at.dropover.scheduling.boundary.AddSchedulingResponseModel doSync(at.dropover.scheduling.boundary.AddSchedulingRequestModel)
test_typetest_method
AddCommentTestvoid failsAtCreatorNull()10
void worksAtMinimalRequest()10
AddSchedulingDateTestvoid addDateToScheduling()00
void addTwoDatesToScheduling()00
\n", "
" ], "text/plain": [ "prod_type AddComment \\\n", "prod_method at.dropover.comment.boundary.GetCommentResponseModel doSync(at.dropover.comment.boundary.AddCommentRequestModel) \n", "test_type test_method \n", "AddCommentTest void failsAtCreatorNull() 1 \n", " void worksAtMinimalRequest() 1 \n", "AddSchedulingDateTest void addDateToScheduling() 0 \n", " void addTwoDatesToScheduling() 0 \n", "\n", "prod_type AddScheduling \n", "prod_method at.dropover.scheduling.boundary.AddSchedulingResponseModel doSync(at.dropover.scheduling.boundary.AddSchedulingRequestModel) \n", "test_type test_method \n", "AddCommentTest void failsAtCreatorNull() 0 \n", " void worksAtMinimalRequest() 0 \n", "AddSchedulingDateTest void addDateToScheduling() 0 \n", " void addTwoDatesToScheduling() 0 " ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "invocation_matrix = invocations.pivot_table(\n", " index=['test_type', 'test_method'],\n", " columns=['prod_type', 'prod_method'],\n", " values='invocations', \n", " fill_value=0\n", ")\n", "# show interesting parts of results\n", "invocation_matrix.iloc[4:8,4:6]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What we've got now is the information for each invocation (or non-invocation) of test methods to production methods. In mathematical words, we've got now a __n-dimensional vector for each test method__ where n is the number of tested production methods in our code base! That means we've just transformed our software data to a representation that we can now work on with standard Data Science tools :-D! That means all further problem solving techniques in this area can be reused by us. \n", "\n", "This is exactly what we do now in our further analysis. We reduced our problem to a distance calculation between vectors (we use distance instead of similarity because later used visualization techniques work with distances). For this, we can use the `cosine_distances` function of the machine learning library [http://scikit-learn.org](scikit-learn) to calculate a pair-wise distance matrix between the test methods." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.10557281, 0.2 ],\n", " [ 0.10557281, 0.2 ],\n", " [ 0.80388386, 0.8245884 ],\n", " [ 1. , 1. ]])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.metrics.pairwise import cosine_distances\n", "\n", "distance_matrix = cosine_distances(invocation_matrix)\n", "# show some interesting parts of results\n", "distance_matrix[81:85,60:62]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From this data, we create a `DataFrame` to get a better representation. You can find the complete `DataFrame` here as excel file as well." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
test_typeCommentGatewayTest
test_methodvoid readRoundtripWorksWithFullData()void readRoundtripWorksWithMandatoryData()
test_typetest_method
CommentsResourceTestvoid postCommentActuallyCreatesComment()0.1055730.200000
void postCommentActuallyCreatesCommentJSON()0.1055730.200000
void postTwiceCreatesTwoElements()0.8038840.824588
ConfigurationFileTestvoid keyWorks()1.0000001.000000
\n", "
" ], "text/plain": [ "test_type CommentGatewayTest \\\n", "test_method void readRoundtripWorksWithFullData() \n", "test_type test_method \n", "CommentsResourceTest void postCommentActuallyCreatesComment() 0.105573 \n", " void postCommentActuallyCreatesCommentJSON() 0.105573 \n", " void postTwiceCreatesTwoElements() 0.803884 \n", "ConfigurationFileTest void keyWorks() 1.000000 \n", "\n", "test_type \n", "test_method void readRoundtripWorksWithMandatoryData() \n", "test_type test_method \n", "CommentsResourceTest void postCommentActuallyCreatesComment() 0.200000 \n", " void postCommentActuallyCreatesCommentJSON() 0.200000 \n", " void postTwiceCreatesTwoElements() 0.824588 \n", "ConfigurationFileTest void keyWorks() 1.000000 " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "distance_df = pd.DataFrame(distance_matrix, index=invocation_matrix.index, columns=invocation_matrix.index)\n", "# show some interesting parts of results\n", "distance_df.iloc[81:85,60:62]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
test_typetest_methodprod_typeprod_methodinvocations
112CommentGatewayTestvoid readRoundtripWorksWithFullData()CommentGatewayjava.util.List read(java.lang.String)2
147CommentsResourceTestvoid postCommentActuallyCreatesComment()Commentjava.lang.String getContent()1
148CommentsResourceTestvoid postCommentActuallyCreatesComment()CommentGatewayjava.util.List read(java.lang.String)2
\n", "
" ], "text/plain": [ " test_type test_method \\\n", "112 CommentGatewayTest void readRoundtripWorksWithFullData() \n", "147 CommentsResourceTest void postCommentActuallyCreatesComment() \n", "148 CommentsResourceTest void postCommentActuallyCreatesComment() \n", "\n", " prod_type prod_method invocations \n", "112 CommentGateway java.util.List read(java.lang.String) 2 \n", "147 Comment java.lang.String getContent() 1 \n", "148 CommentGateway java.util.List read(java.lang.String) 2 " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "invocations[\n", " (invocations.test_method == \"void readRoundtripWorksWithFullData()\") |\n", " (invocations.test_method == \"void postCommentActuallyCreatesComment()\")]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
test_typetest_methodprod_typeprod_methodinvocations
112CommentGatewayTestvoid readRoundtripWorksWithFullData()CommentGatewayjava.util.List read(java.lang.String)2
151CommentsResourceTestvoid postTwiceCreatesTwoElements()Commentjava.lang.String getContent()5
152CommentsResourceTestvoid postTwiceCreatesTwoElements()CommentGatewayjava.util.List read(java.lang.String)1
\n", "
" ], "text/plain": [ " test_type test_method \\\n", "112 CommentGatewayTest void readRoundtripWorksWithFullData() \n", "151 CommentsResourceTest void postTwiceCreatesTwoElements() \n", "152 CommentsResourceTest void postTwiceCreatesTwoElements() \n", "\n", " prod_type prod_method invocations \n", "112 CommentGateway java.util.List read(java.lang.String) 2 \n", "151 Comment java.lang.String getContent() 5 \n", "152 CommentGateway java.util.List read(java.lang.String) 1 " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "invocations[\n", " (invocations.test_method == \"void readRoundtripWorksWithFullData()\") |\n", " (invocations.test_method == \"void postTwiceCreatesTwoElements()\")]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Visualization\n", "Our now 422x422 big distance matrix `distance_df` isn't a good way to spot similarities very well. Let's break down the result into two dimensions using multidimensional scaling (`MDS`) from scikit-learn and plot the results with the plotting library `matplotlib`.\n", "\n", "MDS tries to find a representation of our 422-dimensional data set into the two-dimensional space while retaining the distance information between all data points (=test methods). We use the `MDS` technique with our precomputed dissimilarity matrix `distance_df`." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-0.02495802, 0.10768622],\n", " [ 0.34902428, 0.58676902],\n", " [-0.0249776 , 0.10768132],\n", " [-0.26850959, 0.32472212],\n", " [-0.02497707, 0.10768145]])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn.manifold import MDS\n", "\n", "model = MDS(dissimilarity='precomputed', random_state=10)\n", "distance_df_2d = model.fit_transform(distance_df)\n", "distance_df_2d[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we plot the now two-dimensional matrix with `matplotlib`. We colorize all data points according to the name of the test types. We can achieve this by assigning each type a number within 0 and 1 (`relative_index`) and draw a color from a predefined color spectrum (`cm.hsv`) for each type. With this, each test class gets its own color. This enables us to quickly reason about test classes that belong together." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "from matplotlib import cm\n", "import matplotlib.pyplot as plt\n", "\n", "relative_index = distance_df.index.labels[0].values() / distance_df.index.labels[0].max()\n", "colors = [x for x in cm.hsv(relative_index)]\n", "plt.figure(figsize=(8,8))\n", "x = distance_df_2d[:,0]\n", "y = distance_df_2d[:,1]\n", "plt.scatter(x, y, c=colors)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now have the visual information about which test methods call similar production code! Let's discuss this plot:\n", "* Groups of data points (aka clusters) of the same color are the good ones (like the blue colored ones in the lower middle). They show that there is a high cohesion of test methods with test classes that test the corresponding production code.\n", "* Clusters with mixed colored data points (like in the upper middle) require further analysis. Here, different test classes test the similar production code\n", "\n", "Let's quickly find those spots programmatically by using another machine learning technique: density-based clustering! Here, we use `DBSCAN` to find data points that are close together. We plot this information into the plot above to visualize dense groups of data." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAe8AAAHVCAYAAADYaHMGAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3XtwW9d9L/rvIkESJEACEEhTMEiZFEMn9mEUK6TtRnHDXsceOpozySmnj6Ss1Rzn1h5lktNRHmd8JpWnI9VT3yYdnnOS1uM0VU+ky3vTpIdpndaO0kQVU+dBW7R8VSV2REOSDdGwREIbILHBF8h1/9gEDFIUCRIb2K/vZ4YDcGMTWAAB/PZa+7d+S0gpQURERNZRYXQDiIiIaGsYvImIiCyGwZuIiMhiGLyJiIgshsGbiIjIYhi8iYiILIbBm4iIyGIYvImIiCyGwZuIiMhiXEY34GYaGxtlW1ub0c0gIiIqm7GxsSkpZdNm+5k2eLe1teHMmTNGN4OIiKhshBBvFLIfh82JiIgshsGbiIjIYhi8iYiILIbBm4iIyGIYvImIiCyGwZuIiMhiGLyJiIgshsGbiIjIYhi8iYiILIbBm4iIyGIYvImIiCyGwZuIiMhidAneQoiHhBC/EkK8LoR4fJ3bdwkh/lUIcVYIcU4IsV+PxyUiInKiooO3EKISwF8C+AiAOwF8Qghx55rd/hjAt6WUewF8HMBfFfu4RERETqVHz/seAK9LKS9KKRcAfAvAx9bsIwE0rFz3AXhLh8clIiJyJD2CdxhANO/3Kyvb8v0JgN8XQlwB8ByAz653R0KIR4UQZ4QQZyYnJ3VoGhERkf24dLgPsc42ueb3TwD4X1LKvxBCfADACSFEl5RyedUfSfl1AF8HgJ6enrX3QeQ4169fx/j4OBKJBPx+Pzo7O7Fjxw6jm0VEBtOj530FQGve7y24cVj8UwC+DQBSyp8BcANo1OGxiWzr+vXrGB0dxfz8PILBIObn5zE6Oorr168b3TQiMpgewfslAJ1CiHYhRDW0hLRn1+zzJoAPA4AQ4g5owZvj4kQbGB8fh8fjgcfjgRAid318fNzophGRwYoO3lLKDIDPADgJ4FVoWeW/EEIcEUJ8dGW3zwP4QyHE/wfg/wXwSSklh8WJNpBIJFBXV7dqW11dHRKJhEEtIiKz0OOcN6SUz0FLRMvf9kTe9V8C+KAej0XkFH6/H+l0Gh6PJ7ctnU7D7/cb2CoiMgNWWCMyqc7OTqiqClVVIaXMXe/s7DS6aURkMF163kT0ju1miK/3d/feey/Gx8cRj8fh9/vR1dXFbHMigjDrqeeenh555swZo5tBtCXZDHGPx4O6ujqk02moqop77713w6C73b8rq0wGmJkBFEW77nIBgQBQX69dJ6KiCSHGpJQ9m+3HYXMiHW03Q9z0meXz88Dly8DkpBaovV7tcnJS2z4/b3QLiRyFh8tEOkokEggGg6u21dXVIR6Pl+TvyiKTAaJRwOWCoqq4dOECpqen0dDQgPb2dgQ8Hu32tjb2wInKhD1vom3IDnOfPHlyVeGUbIZ4vkIyxLf7d2UxMwMsL0NRVZw9exYLCwsIBAJYWFjA2bNnoagqsLwMqKrRLSVyDAZvoi3aqPLZdjPETZ1ZriiA241Lly6hrq4OdXV1EELkrl+6dAlwuwEzjBKU2c0O4ohKjcGbaIs2Oj+9Y8cO3HvvvaipqUE8HkdNTU1BSWfb/buyWElOm56eRm1t7aqbamtrMT09DVRWavtt574VBbh4EbhwQbvMJsSZHMvXkpF4gopoizY7P50NxFu13b8rOZcLyGTQ0NCA2dnZVVXfZmdn0dDQACwtbf189/y8dq58eVnrubvdWtCenNR68a2tQE2Nzk9GP/kHcQByl+Pj4+b8P5KtMHgTbZGelc8ssWpYIABMTqK9vR1nz54FoPW4Z2dnkU6n8e53vxuYmwMWF4Gvfx144QXtPHl9PXDffcD+/UBLy+r7tEES3FaTDC3xvybL4LA50RbpdX7aMsOu9fVARQUCHg/27t2L6upqKIqC6upq7N27Vwu0r70G/MmfAM89B9TVAbffrl0+9xxw6BDwyiur79MGSXBbSTK0zP+aLINFWoi2QY9eVPbLPL8Hr6pq7ny3qawd4q6s1IbK5+aAt94CvvY1oL4eL01M4OzYGGbTadTW1WFvdzfuDoeBVAoYHHynB37xIuBy4eVz57CwsLBqKD6dTqO6uhrv37NH66Hv3m3Qk97YVgrrWOp/TYZikRaiEsqen+7r69t2YpmlVg2rqdGGsJubtYCqqtplc7PW685k8NLEBF748Y+RWVyEx+tFZnERL/z4x3hpYkIbUj99+p0EtUuXgDfewPzrr8OTyWgHAiuKToIrk60kGVrqf02WYM6TSUQOYLlVw1wuwOfTfvL99KfAzp04+53voKa6Gu6VjPTs5StnzuDuj30M+Pa3gVtu0YLy3BxQVwdvQwMy166htrYWi01NkNXVxSXBlVmhSYaW+1+T6bHnTWQQU8/t3oqZGcDnw2w6jeo12eG1NTWoSqe1QHz9OuDzISElXv3Vr3D2H/4B6ZkZXEulkF5chOvaNaRnZpBOp9He3q4F+DUJYVZlm/81mQaDN5FBTD23eyvq64FkErV1dVjIq3EupIQrnUa12410IoHJxUX84PRp/NPzz2MSgCcQgCeRgMhkML+8jOlEAu7l5XeS4CoqgLyeqpXZ5n9NpmHuMSkimzPT3O5tJ+Hddx/w3HPY292NF378YwDQeuCzs0Amg/e8972YvngRqe5uzM7OorKyEhOxGGpvuw07FhcRzmRQkUrhjvZ2QEogndaG1tvbTT9svhVm+l+T9bHnTUTFTWXavx+oqsLd4TDu+9CH4KqqgppKweNy4f333IMWrxeVVVVYeN/7MDs7i/r6etTU1ODq1atYdrlQs7wMdWbmnQS1Cn4tEW3GPoe1RLRtRVULa2kBvvQl4MkncXddHe7+7d/W5ni/9RagKJhIJJD86EeBxkbUzcxgYX4eNS4XlicmgDvugDIzg7ekhHzlFQTSaTTNzMDn8wGxGHD33dryo0S0CoM3kc6sWEmr6CVJ77pLm8d9+jTwgx8AV69q2z/yEVxtaMBSZSW8CwvY2dyMSCSC5WQSfrcb8UQCb164gHc3NcFfXY2Zhgb8anIS7/Z64YtEgGQSuP9+oKFB3ydsA1Z8n5F+OD5FtnHkyBGEw2F4vV6Ew2EcOXKk7G2waiUtXZYkbWkBfv/3gePHge9+Fzh2DNi/H+333osUgLn5eXhrahAOh7VENq8XM1ev4o6GBngDAUxlMhgbH8cL//ZvGP7e9zABaMVhXnxRyzwvEyusFGbV9xnph8GbbOHIkSN46qmnMDc3h0AggLm5OTz11FNlD+AbrThmZiWZypRXVvWunh7g1lsxff06dtTW4v+47z586N57EcpkEMhkkH7jDfz7uXOQ6TSagkHMpFI4dfo03orHtWlm167p92Q3YERQ3M7BglXfZ6QfBm+yhWeeeQa1tbVoaGiAy+VCQ0MDamtr8cwzz5S1HVatpFWSqUwul7YyWCaDQFUV9nZ349d+67fQ9cEPwicl8PrrqF9aQsrvx6szM6jyeuGvqIB7ehrB+nrUezz491df1YbML13S78luoNxBcbsHC1Z9n5F+eM6bbCGZTCIQCKzaVldXB0VRytoOK1fSKslUpmxZVVXVlvnMZLRtu3cDra1wz8zgfCSCyOXLCAQCWALgkhIhlwuiqgpvpNNAVRUwPa1vu26i6HP/W7TdREErv89IH+x5ky34fL51z9n61pbyLDFW0lpHtqzq7t3aamONjcAttyCRyeDq1BR2BoPw+/1IzcwgmUigfscO1LpcmJuZgT8U0uqiu91laaou5/63YLs9aL7PiMGbbOGxxx7D7OwspqenkclkMD09jdnZWTz22GNlbQcraRVAUQCvF5fm5iCamtAoBHr27oXP50N9fT0yMzOYmZ1Fcm4O3XffrfW629vL0rRyB8XtHizwfUYcNidbeOKJJwBo574VRYHP58Mf/dEf5baXEytpbSKTAdxuJGdnEdizB5lXXkFwcRHvv+MOXLxyBW8kk3hPezs+9J734NZgUMs0v+WWsjQt+78bHx9HPB6H3+9HV1dXyYJiZ2cnRkdHAWDVsqJdXV0Ft5Wciet5E1F5rVnL2yslai9cAJaWoFZUoMrt1kqlJpPa9LN77jHlPG+95llzvjblK3Q9bwZvIiovRQEmJ6EsLuLs2bOoq6tDbWUlMm+/Dbz5Jt61axd8Ho9W+OVd7yrb+e6tyGaJezyeVT1mDl1TsQoN3hw2J6Lyqq8H4nEEPB7s3bsXly5dgjI9jYZwGO333acF7kxGy1IvcGGScvdeiyonWyLswTsLE9aIqLzWzP9+/549+I3eXrx/zx4Eqqq0wN3auqXAXe7CKmabZ82Ka87D4E1E5Zed/93crAVrVdUum5u17TU1Bd+VEdXGyj2lbDNbfQ2sUAKWNsZhcyorDu1RTnb+d5Fz8ctdWAUoLku8FLbyGuSfrw8Gg0in0xgdHeX5eothz5vKhkN7xWOP6Ubb7QUX81qabZ71Vl4D1kW3BwZvKht+aRSHBz/r205hFT1ey2wA7+vrM7zXupXXwGzn62l7GLypbPilURwe/KxvO71gu72WW3kNzHa+nraH57ypaIWex+ZiCsUx4tyuVWy12pgdX8tCXwOzna+n7WHPm4qyleFHLqZQHPaY9OPk19Js5+tpexi8qShbGX7kl0ZxePCjH6e/lmY6X0/bw2FzKspWhx+5mML2lXvRDDvja0lWx+BNReF57PLiwY9+7Phaso6CczB4U1GY/OIcDAzmfg1YfMVZdDnnLYR4SAjxKyHE60KIx2+yz+8IIX4phPiFEOL/0eNxyXg8j+0MnGNu/tfAbtPfaGNF97yFEJUA/hLAgwCuAHhJCPGslPKXeft0AvhvAD4opVSEELcU+7hkHnYcfqTVtrqKlpl7qNtlxpXE8tlx+hvdnB4973sAvC6lvCilXADwLQAfW7PPHwL4SymlAgBSyms6PC4RlclWCuyYvYe6XWYvMuTk6W9OpEfwDgOI5v1+ZWVbvtsB3C6E+IkQ4udCiIfWuyMhxKNCiDNCiDOTk5M6NI2I9MDa2eYPjqWY/sZa+ualR/AW62yTa353AegE8BsAPgHgG0KIG97xUsqvSyl7pJQ9TU1NOjSNiPTA2tmlnRseiURw7NgxPPnkkzh27BgikciW70Pv/BO7jqDYhR7B+wqA1rzfWwC8tc4+/yilXJRSXgLwK2jBnIgsgLWzS5ecGYlEMDQ0BFVV0draClVVMTQ0VFQA16P4il1HUOxCj6liLwHoFEK0A5gA8HEAv7dmn3+A1uP+X0KIRmjD6Bd1eGyyobGxMQwPD2NiYgLhcBj9/f3o7u42ulmOl5+YuFFCmp2nD26UnLndJL2RkREEAgEEAgEAyF2OjIygo6NDv8ZvERPgzK3onreUMgPgMwBOAngVwLellL8QQhwRQnx0ZbeTAOJCiF8C+FcAX5RS8h1ANxgbG8Pg4CBSqRTa2tqQSqUwODiIsbExo5t2U3oMeVrJZsOpTpw+WMwQcywWg8/nW7XN5/MhFouVqrkFsesIil0IKdeenjaHnp4eeebMGaObQWX2pS99CalUCo2NjbltU1NT8Hq9ePLJJw1s2fqyQ56BQAA+nw/JZBKKomBgYMDQXlMpZYNUflU9VVVzQdqJNntNNuqVHzt2DKqq5nrcAKAoCjweDx555JGyP5es/KIv+SModj8QM5oQYkxK2bPZflyYhExlYmJi1ZcYoA0jTkxMGNSijeUPeVZUVOSuj4yMGN003azNOI5Go+smpEWjUcdmJm+UpLdZr7y3txeKokBRFCwvL+eu9/b2GvFUcpw4gmIlDN5kKuFwGIqirNqmKArC4bWzD83BrEOeelkv8ESjUbz99tur9nv77bcRjUYdm5m80RDzZolfHR0dGBgYgMfjQTQahcfjMc3IDVcfMy/WNidT6e/vx+DgIACtx60oCuLxOA4cOGBwy9YXCoWQTCZXjRYkk0mEQiEDW6Wf9aqKdXZ2Ynx8HA0NDbnh1PHxcXR2dpq2+lipbZSk99JLL22a+NXR0WGKYF0oO1bQsxr2vMlUuru7cejQIXi9Xly+fBlerxeHDh0ybba5WYc89bLecPDOnTvR0tKyaji1paUFO3fuXLWfHeZ2F2qjIWa7JX5x/rc5MGGNqEiRSAQjIyOIxWIIhULo7e21VC9qI4UmpzGJ7ebslvjF/3VpFZqwxmFzoiJZbchzI2uHQxsbG3HhwgUAG8/ZtvPc7mJle+Xj4+OIx+Pw+/3o6uqyZOAGOP/bLBi8iQjA+utBX7hwAbfffjumpqY2DDzlClBWPddqp5X3sqcB8nveVj4NYFUM3jZn5yFd0tfNlrycmpoqqLJaqQPUegcXo6Ojlhp+turBRz6OspgDE9ZsTM+ayWR/my0oYnSiktVrbRv9+umF87/NgcHbxpxQQIT0s1lWtNHB0+qrlRn9+ulpx44d6OzshN/vRyKRwPj4uOUOQqyOwdvG7F5AhPS12ZKXRgdPq0+5MuL1K9V63HYZRbAyBm8byxYQyWenAiKkr82GQ40OnqVcT7scyv36lTLA2mkUwaqYsGZjvb29GBoawptvvonXXnsNV69eRU1NDT7/+c8b3TQyqY2SzoxOVLL6lKtyv343S0DUo+odp4sZj8Hbxjo6OrBnzx489dRTEEJg586dCAQC+Pu//3u0traatmoZmZMZgqeVp1yV+/UrZYDldDHjMXjb3EsvvYR77733hiU2h4eHGbxpy6wcPM1go9dP72lkpQywnZ2d+Jd/+RcoioLFxUVUVVUhEAjgwQcfLPq+qTA8521zVltik8iJSnF+utQ5AkKIDX+n0mLP2+ayS2zm97zNvMQmkRNt9/x0IUVzSjFMPz4+jp07d64q+KSqqmNWkTMD9rxtrr+/H/F4HFNTU1haWsqVuezv7ze6aUS0YjvTyArprZdqPW6jpw0Sg7ftWW2JTSIn2s40MiOna5Vj2lup5qjbBYfNHaC7u5vBmsjEtjONzMjpWqWe9maHOvalxp43EZHBtlMv3MiiOaWub84iMJtjz5uIyAS2Og3PLEVzSiF/VCGZTCIajWJ6ehrLy8uWXImtFNjzJiKyIDuv7pUdVUgmkzh//jwWFhZQU1ODmpoanv9ewZ63FWUywMwMoCjadZcLCASA+nrtOhE5gl2L5mRHFd544w243W4AwNzcHLq6uuByuTglDQze1jM/D0SjwPIy4HZrP5kMMDkJxONAaytQU2N0K4nIQcbGxjA8PIyJiQmEw2H09/cXlSSbPSi5cOECKioq0NDQgI6ODvh8PkgpWUMdHDa3lkxGC9wuF5TFRbx87hxOnz6Nl8+dg7K4qPW6o1FtPyKiMhgbG8Pg4CBSqRTa2tqQSqUwODiIsbGxou53x44d+LVf+zW8733vQ1dXV255Y9ZQ17DnbSUzM8DyMhRVxdmzZ1FXV4dAIIDZ2VmcPXsWe/fuRaCqClBVYM063maj95G6U+hd/5qoWMPDwwgGg7kqjtlLPdZPMDopz8wYvK1EUQC3G5cuXEBdXV2uwlH28tKlSwjs2aMNn5s4eI+NjeGP//iPMTU1hfn5efziF7/Ayy+/jD/90z9lAN8A575SPrMcyE1MTKCtrW3VtkAggMuXL2/5vtZ7TkavZGdWHDa3kpXktOnpadTW1q66qba2FtPT00BlpemHzb/2ta8hEomgsrISwWAQlZWViEQi+NrXvmZ000yNc18pqxQLmWxXdv2EfNtZP+FmzwlASUq8Wh2Dt5W4XEAmg4aGBszOzq66aXZ2Fg0NDcDS0jsZ55mM1lu/eBG4cEG7zGaoG+jMmTPw+/3weDyoqKiAx+OB3+/HmTNnDG2X2bGeNGWZ6UBOr/UTzPScrIDB20oCAWBuDu3t7Uin00in05BS5q63t7cDc3NAMKhlpV++rGWhu1yA16tdTk5q2+fnjX42tEVGVtQiczHTgZxe6yeY6TlZAc95W0lVFTAxgcDVq+hWVcSiUVx3u+HetQvv3rsXAY9H61XX1LyTla6quHThAqanp9HQ0ID29nZtv2gUaGszZF74PffcgxdeeAEVFRVwu92Ym5tDMpnEfffdV/a2WAmTdygreyCXXToUMPZATo/1E8z2nMyOPW+rmJ4Gfv5zIJUCKirga2rCe97zHuy75Ra8f24Ogfl5LXC3tgKzs6uy0hcWFhAIBLCwsICzZ89CUVVtnriqGvJUPv3pT6O9vR2ZTAbXr19HJpNBe3s7Pv3pTxvSHquwc0WtcrLDalWdnZ1QVRWqqkJKmbve2dlpdNO2zY7PqZSElNLoNqyrp6dH8hzoirk54IUXALcb0XgcL7/0EhKxGEJ1dei64w7c2tgIVFcDDzygDY9fvAi4XHj53DksLCysGopKp9Oorq7G+/fs0YL97t2GPCWzTxUzSyZvIazUVqPlZ+znj15Y8SDIjv93Oz6nrRJCjEkpezbdj8HbAi5dAi5cQHRuDs89/zwaGhrg9XqRSqUwPT2N/R/5CFrdbuCOO4Bdu7TkNK8Xp0+fRiAQgBAid1dSSiiKgt/o7dV63rffbuATMycrfcFbqa1mkM1mzh+aVVU1N4pBZLRCgzeHza3gzTeBhgaMjY2hoaEBDQ0NuZKBDSvb0dCgBXlg61nptIqVsl6t1FYzYFIU2QWDtxXMzQE1NZiamoLX6111k9frxdTUlJbMNjenbdxKVjrdwEpf8FZqqxkwY5/sgsHbCtxuYH4ejY2NSKVSq25KpVJaOcLFxXcWKclkgCtXELh6Fe9vakLtwgISU1Oorq7WSqh6PEBFBZA3dEjvsNIXvJXaagblTIqyQ2IcmRfHTa1g5Tx2d3c3nnv+eQBYdc77vg9+UMtG7+jQ5nAvL2tZ59euwS8E/M3NWs+8uRmQ8p2sdA6br6tcU7L0SM7h9LGtyWbsl7rcJkvZ6qOQz4hTk9yYsGYFa7LNx8bGMDU1hcbGRnR3d6M1GNSSz8JhwOvV5nZfuoQZRYGvuhptPh/81dWAEMCePVrdcwbuDZX6C0HPRDOnfnmZGRPjilfIZ8SOCZvMNreb6WngxRe1RLOGBq0nvbioba+sBDo7gfl5KIuLuRXHamtrMTs7i3Q6/c6KY83Npl60xCn45W5vJ0+eRDAYvGGmRzweR19fn4Ets45CPiN2/Bwx29xuGhqA++7TpoMtLGgrhy0saL/fd58W1N1uXLp0KbfimBAid/3SpUvaOXEuYm8KTDSzN+YiFK+Qz4iTP0ccO7USt1s7/71r1423ZTKA243p6WkEAoFVN9XW1mqr/lRWvpORToZiKUjr2crpCeYiFK+Qz4iTP0e69LyFEA8JIX4lhHhdCPH4Bvv9lhBCCiE2HRKgLeLcbkvRM+uZWc2lt9UlOFnKtniFfEacXFK16HPeQohKABcAPAjgCoCXAHxCSvnLNfvVA/hnANUAPiOl3PCENs95rzE3B8RiWsGWubl3euGhkHZdUYDJSZ7zthA9Es3smLBjRnY8t2oF28k2b2xsxNTUlGUTOMuWsCaE+ACAP5FS9q38/t8AQEr5Z2v2++8AfgjgCwC+wOC9BWuT1WpqtCU9s8lq99wD1NVp08SyK4ldunTjSmKZjGEriVFpODmolDPLnglo1mCHg9lyJqyFAUTzfr+ysi2/MXsBtEop/2mjOxJCPCqEOCOEODM5OalD02xgbk4L3G43onNz+Ifnn8c3vvEN/MPzzyOa7YG/+OI7c7czGQSqqvD+PXvwG729eP+ePVqPm3O7bcmpCTtbHcYuFhPQrMFJ5YL1+CYX62zLdeeFEBUABgF8crM7klJ+HcDXAa3nrUPbrC8WA5aWEI3Hc4uSNO/cCVVRMPKtb+GBri7slBK4fh24+25g506thx6Pa4Hf5dKGyj0eBm4b2mrCzqlTp3D8+PHcam4HDhzA/fffX67m6ib/SxpA7nJ8fLwkIw5MQNsao2oPJBIJBNeUfa6rq0PchrNs9Oh5XwHQmvd7C4C38n6vB9AF4LQQ4jKAXwPwLJPWCrTOoiRVCwtou34dty4s4LXXXwdaWoCpKW01sZ//XCvGsnu3tmLY7t0symJjW0nYOXXqFI4ePYpUKoW2tjakUikcPXoUp06dMqDlxSn3iIOVE9DKndBY7lGRfE4aIdEjeL8EoFMI0S6EqAbwcQDPZm+UUiallI1SyjYpZRuAnwP46GbnvGnFmkVJKhYW4I9GkamqQqq6GmPnzuG73/seXvi3f1s9jM4pYY6wlaBy/PhxBINBNDU1weVyoampCcFgEMePHzeg5cUx4ks6+1r39fVZLnCXM5AaOXTtpOzzooO3lDID4DMATgJ4FcC3pZS/EEIcEUJ8tNj7d7w1i5JUz8wAAJR0Gr/85S9RVVWFYCCAOSnx3PPPIxqPa8Pm164Z3HAql0KDysTExA01AAKBACYmJsrRTF056Uu6GEYEUiPzMKw8QrJVuszzllI+J6W8XUrZIaV8cmXbE1LKZ9fZ9zfY696CXbuA6Wl0d3djenoaS7EYFqqqcOniRUgpEW5pQXJiApcWFpBKpfDCCy+sXtubaEU4HNaK9eRRFAXhcPgmf2FeTvqSLoYRgdTooWsrjpBsB8ujmsi656ZCIaCyEq3BIPZ/5COoq6hAPJnE4uIi3vWud2FhehoZKYEdO1BdVYVf/PKXSKTTHDanGxw4cADxeByTk5PIZDKYnJxEPB7HgQMHjG7atjjlS7oYRgRSjoqUB4O3DvRICLnpual0WpvHPTeHVrcb933wg/jNj3wEPXv2QCYScFdUQAmHIauqkFlaQmNjI6LZOuZEee6//34cPnwYXq8Xb168iFuqqvDkpz6F+1tagIsXtUI/mYzRzSQdGRFIOSpSHlxVrEh6FQXYtNjG3Jx2HvsnPwEuXsRVIfC3P/gB3KEQ3CslUVVVxQf37YN3dhZ3Hziwfg10ovl5IBrV1n13u3OldTE3B1RUaPUAamqMbiXphEvGWkuhRVo4f6hIes033XR+YrYc6i23AC+8gGa3Gz1VVTitTTcJAAAgAElEQVR//jyuX78Ov9+PvXfdBV9VFaqrq7X9iNbKZLTAna3Ed+HCjZX4olFW4rORbE+Y7IWfziLpVRSg4GIbbrc2jP7ii+hpb0dtRQXc9fVwu1xYiseRnpvDbb/3exw2p/XNzADLy1BUNVcDPxAIYHZ2FmfPnn2nBr6qsgY+GYojBhvjOe8i6ZUQsqVzUytre/vvuQf/obMTtek0ZqamkLn9dtz+yU9iR1tbEc+IbE1RuO47mZ6RhV6sgj3vIulVNjE7tDU+Po54PA6/34+urq6bH2muDKP7d+2C/WoHUclw3XeygHKXv7UiBu8ibTnoFnBfRCWzZt33/DnAXPedzMJJNcq3i59QHawXdHm+hkwpEAAmJ9He3o7vf//7iEQiSKVS8Hq96OjowEMPPaT1upubN7ybSCSCkZERxGIxhEIh9Pb2oqOjo0xPguxuqwvuOBHPeZcAz9eQadXXAxUVSE5N4eLFi8hkMqirq0Mmk8HFixeRnJrSpovlfWmuFYlEMDQ0BFVV0draClVVMTQ0hEgkUsYnQnbGQi+bY8+7BHi+xnocM1LicgGtrXjxO99BayAAb2MjZEUFxPIyUlNTePGnP0Xb5z634bD5yMgIAoFA7px59nJkZIS9b9KFnqcj7YrBuwR4vsZa8gvtBINBpNNpjI6O2rcqVE0NXl9cRHtLC0Q6jYrFRcjKSlS1tOD1a9c2LdASi8XQ2tq6apvP50M0Gi1lq8lhmAO0MQ6bl4DRhflpa4xcwtAoO1taMLW4CPWWW5AKhaDecgumFhexs6Vl078NhUJIJpOrtiWTSYRCoVI1l4jWYPAuASeer9GjvrtRjFzC0Ci9vb1QFAWKomB5eTl3vbe3t6R/S0T6YPAuAacV5rd6gp4TR0o6OjowMDAAj8eDaDQKj8eDgYGBgs5ZF/O3VFpWPoimreHCJA6lZ4LWpouqmJxei8sQGYnvY3sodGES9rwdSO+estWHnZ02UkL25MTcDSdjtrkD6T2VzQ4FFZjZSlbHWS7OwuBdQmadO6z3h1yv+u5EtH12OIimwnHYvETMnMSld4IWh52JjOfEWS5Oxp53iZi5ylopespWHHY268gI0XawKpmzMHiXiJnPP/FD7sCqauQIeh9Ej42NYXh4GBMTEwiHw+jv70d3d7du90/bx2HzEjH73OHsh7yvr8+RAYuZuUQbGxsbw+DgIFKpFNra2pBKpTA4OIixsTGjm0Zgz7tkmMRlbmYeGbEzLiVqHcPDwwgGg2hsbASA3OXw8DB73ybAnneJMInL3Mw+MmJHXErUWiYmJnIrxmUFAgFMTEwY1CLKx553CVkxicspODJSflxK1FrC4TAURcn1uAFAURSEw2EDW0VZ7HmTI3FkpPxisRh8Pt+qbT6fD7FYzKAW0Ub6+/sRj8cxNTWFpaUlTE1NIR6Po7+/3+imEdjzJgfjyEh5ZZcSzR+K5VKi5p2y2N3djUOHDmF4eBiXL19GOBzGgQMHeL7bJBi8iagsent7MTQ0BEDrcSeTSSiKgv379xvcMuOYfcpid3c3g7VJcdicyABOXLqRS4neiFMWabvY8yYqM7P3tkqpo6PDtMHaiOFrTlmk7WLPm6jM2NsyH6PWIuCURdouBm+iMrP6+ud2ZNQBFRcToe1i8N6CEydOYN++fejo6MC+fftw4sQJo5tEFsTelvkYdUDFKYu0XTznXaATJ07g8OHD8Pl8aGlpQSKRwOHDhwEADz/8sMGtIythgRjzMXItbE5ZpO1gz7tATz/9NHw+HxobG+FyudDY2Aifz4enn37a6KaRxbC3ZT4cviarYc+7QFevXkVLS8uqbX6/H1euXDGoRWRl7G2ZC5fJJath8C5Qc3MzEonEqjq/iUQCzc3NBraKiPTCAyqyEg6bF+jgwYNIJpOYmppCJpPB1NQUkskkDh48aHTTDOXEYiNEREZj8C7Qww8/jKNHj8Lj8eDKlSvweDw4evSoo5PVjJobS0TkdEJKaXQb1tXT0yPPnDljdDNoA9nAnZ+hq6pqLgGLrM2sC2YQ2ZkQYkxK2bPZfux507ax2Ih9cVSFyNx0Cd5CiIeEEL8SQrwuhHh8nds/J4T4pRDinBDiR0KI2/R4XDIWi43Ylx1LuDI/g+yk6OAthKgE8JcAPgLgTgCfEELcuWa3swB6pJR7APw9gD8v9nHJeMXOjeWXqXnZbVSFIwlkN3r0vO8B8LqU8qKUcgHAtwB8LH8HKeW/SimzXbSfA2gBWV4xxUb4ZWpudhtVseNIAjmbHvO8wwCieb9fAbBRttKnADy/3g1CiEcBPAoAu3bt0qFpVGrbnRub/2UKIHc5Pj5u6WQ3uyR52a2EqxFLb0YiEYyMjCAWiyEUCqG3t9e0y6GS9ejR8xbrbFs3hV0I8fsAegB8eb3bpZRfl1L2SCl7mpqadGgamZXdhmUBe40m2K2Ea7lHEiKRCIaGhqCqKlpbW6GqKoaGhhCJREryeOQ8evS8rwBozfu9BcBba3cSQjwA4EsAeqWU8zo8LlmYkQtBlIrdRhPsVHGs3CMJIyMjCAQCCAQCAJC7HBkZYe+bdKFHz/slAJ1CiHYhRDWAjwN4Nn8HIcReAM8A+KiU8poOj2lrTkjksuNCEHYcTbCLco8kxGIx+Hy+Vdt8Ph9isVhJHo+cp+iet5QyI4T4DICTACoBHJNS/kIIcQTAGSnls9CGyb0AviOEAIA3pZQfLfax7SgbuD0eD4LBINLpNEZHRy09ZLkeOywEsfb8dkVFhe1GE+yknCMJoVAIyWQy1+MGgGQyiVAoVJbHJ/vTZWESKeVzAJ5bs+2JvOsP6PE4TmC3odeNWHlYdr2DLEVRIKVEKBSyRZIXbV9vby+GhoYAaD3uZDIJRVGwf/9+g1tGdsEKaybDoVdrWG/q0c6dOxEIBGyT5EXb19HRgYGBAXg8HkSjUXg8HgwMDPB8N+mGS4KajB0TuezozTffhKqqSKVSqK+vR2trKxoaGjA7O2vZ0QTSV0dHB4M1lQx73iZjx0Quu7l+/TquXLmCmZkZ+Hw+LCws4Pz583j77bd5kEVEZcHgbTJ2m19rR+Pj4+js7ISUEnNzc3C73RBC5LYTEZUah81NyMqJXE6QSCSwc+dO1NXVIRqNIplMor6+Hl6vlwdZRFQWDN5EW5TNS/D5fLm5vNl1zImIyoHD5kRbxLwEIjIagzfRFjEvgYiMxmFzG7DLSlZWwrwEIov46leBJ54A8mtl+P3AkSPAZz9rXLuKxJ63xdlpJSu9OaFGPBFt4JFHgP/yX94J3FVV2mUioW1/5BHj2lYkBm+LW6/Sl8fjwfj4uNFNMxQPaogc7qtfBf72bwEA09mfxcXcdQDa7V/9qjHtKxKDt8WxnOr6eFBD5HBPaMtrTN/k5tz2J58sR2t0x+BtcdlpS/lYTpUHNUSOV+hn/erV0rajRBi8LY7TltbHgxoiyp3jtiEGb4vjtKX18aCGiLC4aHQLSoZTxWyA05ZulH1NxsfHEY/H4ff70dXV5fiDmvWMjY1heHgYExMTCIfD6O/vR3d3t9HNIiqO31/Y0Hlzc+nbUgLseZNtZQN4X18fRyNuYmxsDIODg0ilUmhra0MqlcLg4CDGxsaMbhpRcY4cAQA03OTm3PYvfakcrdEdgzeRgw0PDyMYDKKxsRGVlZVobGxEMBjE8PCw0U0jKs5nPwv85/8MQAvUa38AaLdbtFALgzeRg01MTCAQCKzaFggEMDExYVCLiHR07BjwP//njUPjzc3a9mPHjGmXDnjOm8jBwuEwFEVBY2NjbpuiKAiHwwa2ikhHn/2sZXvXG2HPm8jB+vv7EY/HMTU1haWlJUxNTSEej6O/v9/ophHRBhi8iRysu7sbhw4dgtfrxeXLl+H1enHo0CFmmxOZHIfNt+r8eeBv/gYYGQHSaaCuDujtBT71KaCry+jWEW1Zd3c3gzWRxTB4b8X3vw98/vPA0hLQ1ATceiuQTALPPw/84AfAX/wF8NBDRreSiMqAS/GSkRi8C3X+vBa4PR68cu0aoj/5CZakRKUQaN21C3fdcot2e0sLe+Br8EuO7Ca7ap3H40EwGEQ6ncbo6CjrCVDZ8Jx3of7mb4ClJbxy7Rouv/EGllcC97KUuPzGG3jl2jWtR/7tbxvdUlPh0pxkR1y1jozG4F2okRGgqQnRN9+EAFBZWQlRUaFdAoi++aY2lP5P/1TY/WUygKIAFy8CFy5ol4qibbcRfsmRHXHVOjIag3eh0mnA58OSlKgQYtVNFUJgSUqgtlbbbzPz88Dly8DkJOByAV6vdjk5qW2fny/JUzACv+TIjrhqHRmNwbtQdXVAMpkbKs+XHULH7Ky230YyGSAaBVwuKIuLePncOZw+fRovnzsHZXFRC+LRqG164IV8yZ04cQL79u1DR0cH9u3bhxMnTpS7mURbwlXryGgM3oXq7QUmJ9G6axckgKWlJcjlZe0SQOuuXVrP+T/+x43vZ2YGWF6Goqo4e/YsFhYWEAgEsLCwgLNnz0JRVWB5GVDVcjwr3WTPbZ88eXLVOe3NvuROnDiBw4cPQ1VVtLS0QFVVHD58mAGcTI1L8ZLRhFzTizSLnp4eeebMGaOb8Y7z54Hf/d13ss3ffPPGbHNVBf7u7zbONr94EXC58PK5c1hYWFg1pJxOp1FdXY3379mj9bx37y7DEytefuZtXV0d0uk0VFXNfZltlG2+b98+qKq6qjzn1NQUPB4PfvrTnxr1lIiIDCGEGJNS9my2H6eKFaqrS5vH/fnP4y63G3d98IPaOe7ZWa3Hrara7ZtNE8tkALcb09PTNywIUVtbC0VRgMpKYG6uhE9GX/lJaQByl+Pj47kAfrP1xq9evYqWlpZV2/x+P65cuVLaRhMRWRiD91Y89JA2j/vb39ayyicntXPcv/M72k8h87tdLiCTQUNDA2ZnZ1f1vGdnZ9HQ0KBNOXNZ51+TSCQQDAZXbaurq0M8Ht/0b5ubm5FIJFb1vBOJBJrXrgJElsF5/USlx3PeW9XVpS3y/vLLwGuvaZdHjhRemCUQAObm0N7ejnQ6jXQ6DSll7np7e7vW614TDM2smMzbgwcPIplMYmpqCplMBlNTU0gmkzh48GCpmkslxHn9ROXB4F1u9fVARQUCHg/27t2L6upqKIqC6upq7N27FwGPB6ioAFaGnq2gmMzbhx9+GEePHoXH48GVK1fg8Xhw9OhRPPzww2VoOemN8/qJyoMJa0aYn9emgy0vA263do57aUnrcVdUAK2tQE2N0a3cEg6VEgCcPHkSwWAQIq8WgpQS8XgcfX19BraMyBqYsGZmNTVAW5uW5BaPa0Hb5QKam7Uet4XOd2dtlJRGzpE9heLJGzlKp9MQQmB0dLTkB3c8iCSn4LC5UVwuwOfTpoPdfrt26fNZMnATZa13CuXtt9+GoiglPw/O8+3kJAzeRKSb9YqXBAIBhEKhkp8H5/l2chJ288hxIpEIRkZGEIvFEAqF0Nvbi46ODqObZRtrT6GcPHly3fr2hUwl3IpipiwSWQ173uQokUgEQ0NDUFUVra2tUFUVQ0NDiEQiRjfNtsq1iAcXCyEnYc+bTKsUyUcjIyMIBAK56nbZy5GREfa+S6SzsxOjo6MAsKp8bldebQQ9/teFPA6RXbDnTaZUquSjWCwGn8+3apvP50MsFivqfunmNlvEQ6//NRcLISfRpecthHgIwP8AUAngG1LKp9bcXgPgOIBuAHEAvyulvKzHY5M9bVYvfbtCoRCSyeSquvLJZBKhUKi4BtOGNppKqOf/mlMWySmK7nkLISoB/CWAjwC4E8AnhBB3rtntUwAUKeW7AAwC+L+KfVyyt0QisW6SUyKRKOp+e3t7oSgKFEXB8vJy7npvb29R90vbV6r/NZGd6TFsfg+A16WUF6WUCwC+BeBja/b5GIBvrlz/ewAfFvklmIjWKFXyUUdHBwYGBuDxeBCNRuHxeDAwMMDz3QZiohnR1ukxbB4GEM37/QqAteNWuX2klBkhRBJAEMBU/k5CiEcBPAoAu3bt0qFpZFWlTD7q6OhgsDYRJpoRbZ0ePe/1etBrC6YXsg+klF+XUvZIKXuampp0aBpZFZOPnIP/a6Kt06PnfQVAa97vLQDeusk+V4QQLgA+AKxZSBti8pFz8H9NtDV69LxfAtAphGgXQlQD+DiAZ9fs8yyAP1i5/lsATkmzLmdGRERkckX3vFfOYX8GwEloU8WOSSl/IYQ4AuCMlPJZAH8D4IQQ4nVoPe6PF/u4RERETqXLPG8p5XMAnluz7Ym863MAfluPxyIyOy5LSUSlxgprRDrispREVA6ODd7ZL9mTJ0/yy5V0w2UpSS9f+cpX0NHRgUAggI6ODnzlK18xuklkIo4M3uwdUamwWhjp4Stf+QqOHj2K2dlZNDU1YXZ2FkePHmUApxxHBm/2jqhUWC2M9PD000/D4/HA7/fD5XLB7/fD4/Hg6aefNrppZBKODN7sHVGpdHZ2QlVVqKoKKWXuemdnp9FNIwu5fv06vF7vqm1er5ejg5TjyODN3hGVCquFkR527NiBVCq1alsqleL7iHIcGbzZO6JSygbwvr4+Bm7aloMHD0JVVSQSCWQyGSQSCaiqioMHDxrdNDIJXeZ5W032y3V8fBzxeBx+vx9dXV38kqWb4txtKqcvfOELALRz35OTk9ixYwc+97nP5bYTCbNWKe3p6ZFnzpwxuhlEudkJHo9n1apX7FWbHw+6yGqEEGNSyp7N9nPksDnRVnB2gjVxSijZGYM30SY4O8GaeNBFdsbgTbQJzk6wJh50kZ05JmGt0HNfkUgEIyMjiMViCIVC6O3tRUdHhwEtJrPo7OzE6OgoAKw6593V1WVwy2gj2YMuj8eT28aDLrILR/S8Cz33FYlEMDQ0BFVV0draClVVMTQ0hEgkYlDLyQw4d9uaOCVUH1wHwpwckW2eDdz5R+Cqqua+hLOOHTsGVVURCARy2xRFgcfjwSOPPLLhYzCrlch8+LksDmdalF+h2eaOGDZPJBIIBoOrttXV1SEej6/aFovF0Nraumqbz+dDNBrd8P7z3+DBYBDpdBqjo6N8gxMZLDtqQtuTn/QHIHc5Pj7O19VgjgjehZ77CoVCSCaTq3reyWQSoVBow/vnG5zIGtgT35pCOz5WNzY2huHhYUxMTCAcDqO/vx/d3d1GN2tDjjjnXei5r97eXiiKAkVRsLy8nLve29u74f0zq5XI/Djve+ucMNNibGwMg4ODSKVSaGtrQyqVwuDgIMbGxoxu2oYcEbwLTTjq6OjAwMAAPB4PotEoPB4PBgYGNs02d8IbnMjqOO9765yQ9Dc8PIxgMIjGxkZUVlaisbERwWAQw8PDRjdtQ44YNgcKP/fV0dGx5alhnEpEZH5OGQLWkxPWgZiYmEBbW9uqbYFAAJcvXzakPYVyTPAuJSe8wYmsjvO+t8fuSX/hcBiKoqCxsTG3TVEUhMNhA1u1OQZvndj9DU7GKGeCld2TuThCRuvp7+/H4OAgAK3HrSgK4vE4Dhw4YHDLNuaIc95EVlTOBCsnJHOx2A6tp7u7G4cOHYLX68Xly5fh9Xpx6NAh02ebO6JIix2Vu5d06tQpHD9+PDeV4sCBA7j//vtL9nhUeHGhcjyW3XvlRGbBIi02dv36dfzwhz/E9evXsbi4iKqqKrzxxht44IEHSvKFeurUKRw9ehTBYBBtbW1QFAVHjx4FAAbwEipngtXax4pGoxgbG0M0GsWLL74IKSWqq6vL8n4jos1x2NyCzpw5g8uXL6OyshJ+vx+VlZW4fPkySjVScfz4cQSDQTQ1NcHlcqGpqQnBYBDHjx8vyeORppxTEPMfKxqN4vvf/z6mp6dx22234dVXX8X3vve9XDJmqd9vRLQ5Bu8NmLUg/6uvvgq/34/a2loIIVBbWwu/349XX321JI83MTGxquocoCV2TExMlOTxSFPOObb5jzU2NoaamhpUV1cjFAphenoawWAQly9fLsv7jYg2x+B9E6VI4DHrwcBmslMp8llhKoXVlTPBKv+xotEo/H4/Ojo64PV6IYSA2+1mxUAiE2Hwvgm9qzHpeTBw5513IpFIYHZ2FlJKzM7OIpFI4M4779xW2zZz4MABxONxTE5OIpPJYHJy0hJTKewgG1T7+vpKnhmdfawPfehDaGxshNfrBQDceuutuH79Ourq6sryfiOizTF434Te9cr1PBjo7u7GbbfdhqWlJSQSCSwtLeG2224r2dSG+++/H4cPH141leLw4cNMVrOptTX+A4EAampq0NHRUZb3GxFtjlPFbkLvaTonT55EMBiEECK3TUqJeDyOvr6+Ld8fp+5QKUUiEYyMjCAWiyEUCuF973sfMpkM329EJcapYkXSuxqT3qUZWdGNSmk7Nf6JqHw4bH4TeicLOWF1HiIiuzNL4jGHzcvoZkPdHAInIjK/bOD2eDyrRmT1TCYtdNicwdtg5XgzEBFR8cpRsrjQ4M1hc4PpPSWNiIhKQ+9ZSMVg8DaYmd4MRER0c+UsWbwZBm+DmenNQEREN2emxGMGb4OZ6c1AREQ3Z6Y14TnP22DZN8P4+Hhu1aauri4mqxERrePEiRN4+umncfXqVTQ3N+PgwYN4+OGHy/b4ZqmxweBtAmZ5MxARmdmJEydw+PBh+Hw+tLS0IJFI4PDhwwBQ1gBuBpwqRlSAteVCe3t7WYGMqMz27dsHVVXR2NiY2zY1NQWPx4Of/vSnBrZMP2WZKiaE2CGE+BchxPjKZWCdfe4SQvxMCPELIcQ5IcTvFvOYROUWiUQwNDQEVVXR2toKVVUxNDSESCRidNOIHOXq1as3JPP6/X5cvXrVoBYZp9iEtccB/EhK2QngRyu/r5UGcEBK+R8APATgvwshmEpNljEyMoJAIIBAIICKiorc9ZGREaObRuQozc3NN0yjTSQSaG5uNqhFxik2eH8MwDdXrn8TwH9au4OU8oKUcnzl+lsArgFoKvJxicomFovB5/Ot2ubz+RCLxQxqEZEzHTx4EMlkElNTU8hkMpiamkIymcTBgweNblrZFZuw1iyljAGAlDImhLhlo52FEPcAqAaw7nijEOJRAI8CwK5du4psGpE+QqEQkskkAoF3zgolk0mEQiEDW0XkPNmktKeffhpXrlxBc3MzvvCFLzguWQ0oIGFNCPFDADvXuelLAL4ppfTn7atIKW84771yWwjAaQB/IKX8+WYNY8IamUX2nHcgEIDP50MymYSiKBgYGGDSGpFNGZWkqlvCmpTyASll1zo//wjg6kpQzgbnazdpTAOAfwbwx4UEbiIz6ejowMDAADweD6LRKDweDwM3kY1ZIUm12GHzZwH8AYCnVi7/ce0OQohqAN8FcFxK+Z0iH48IwM2XVy2Vjo4OBmsyDJcNLq/8JFUAucuRkRHTfA8Um7D2FIAHhRDjAB5c+R1CiB4hxDdW9vkdAB8C8EkhxCsrP3cV+biUxyyLw5dL9vnOz88jGAxifn7eEc+bnInv9/KzQpJqUcFbShmXUn5YStm5cnl9ZfsZKeX/uXL9/5ZSVkkp78r7eUWPxpMzP9hcRpWchO/38ssmqeYzW5IqFyaxOCd+sLmMKjkJ3+/l19vbC0VRoCgKlpeXc9d7e3uNbloOg7fFOfGDzWVUyUn4fi8/KySpcmESi8t+sD0eT26b3T/YnZ2dGB0dBaAdqKTTaaiqiq6uLoNbRrR1m01J4vvdGGZPUmXP2+KcuB64mdbUJdquSCSCP/uzP8Ojjz6KH/7wh6ipqVl3ShLf77QeripmA5xGQmQt2XnEr732GioqKiCEQDqdxr59+1BdXQ2Px4NHHnnE6GaSAQot0sJhcxvgeuBE1pKdR7y4uIgdO3agokIbBH3ttdfw67/+64hGowa3kMyOw+ZERGWWnUfs8/kwOzsL4J1EU7NNSSJzYvAmIiqz7DziO+64A6lUKperUlVVZbopSWRODN5FOHLkCMLhMLxeL8LhMI4cOWJ0k4jIArLziKurq/GBD3wAmUwGb731Ft773veabkoSmRPPeW/TkSNH8NRTT6G2thaBQADpdBpPPfUUAOCJJ54wuHVkFkwmpPVk5xGPjIxgenoaDzzwQNlWrSJ7YLb5NoXDYczNzaGhoSG3bXp6Gm63GxMTEwa2jMwiW7rW4/Gsmp/LaT43F4lE8M///M/42c9+hsnJSTQ1NWHfvn3Yv38/Axs5ArPNSyyZTOZWmsmqq6uDoigGtYjMJr90LYDc5fj4OGcHrCMSieCv//qv8cYbb2BiYgIulwvRaBQ/+9nPMDExgT/8wz9kACdd2GFEjOe8t8nn861bsnDtSjTkXE4sXVuMkZERLCwsYGZmBvX19dixYwd8Ph+SySQWFhYwMjJidBPJBuyymBOD9zY99thjmJ2dxfT0NDKZDKanpzE7O4vHHnvM6KaRSbAm9dbEYjFUVFQgnU6jpqYGAFBTU4O5uTlUVFSYajlGsi67LObE4L1NTzzxBB5//HG43W4oigK3243HH3+cyWqU48TStcUIhUJYXl5GXV0d5ufnAQDz8/Nwu91YXl7m3GfShV1GxBi8i/DEE09gYmICqVQKExMTDNy0CmtSb01vby+qq6tRX1+PmZkZXL9+HclkEj6fD9XV1Zz7TLqwy4gYs82JyDSYbU6lZvZZIIVmmzN4ExGRo2yWbW5kNjqnihEREa1jo8Wc8nvmwWAQ6XQao6OjpumZZzF4U04kEsE3v/lN/PjHP8bCwgLuuusufOpTn0J3d7fRTSMiKgur1GdgwhoB0AL3l7/8ZTz33HOoqqqCz+fD2NgYjhw5grGxMaObR0RUFlbJRmfwJgBagYyLFy8iGAzC5/PB4/GgsbERqVQKw8PDRjePiKgsrJKNzmFzAqAVyEin02hqasptq6mpwezsLGu1E5EtRCIRjIyMIBaLIRQKrbsYTGdnJ0ZHRwFgVTZ6V1eXEVkWw8cAACAASURBVE2+KQZvAqAVyMi+Uevr6wFoBTKEEAiHwwa3rjCFfDD1ZIf6yEROEYlEMDQ0hEAggNbWViSTSQwNDd2wBGs2mW18fBzxeBx+vx9dXV2m+2xz2JwAaAUydu/ejXg8jmQyCVVVMTU1Ba/Xi/7+fqObt6nsB1NVVbS2tkJVVQwNDSESiZTk8exSH5nIKUZGRhAIBBAIBFBRUZG7vl7N/GwA7+vrM12WeRaDNwHQ1hf+4he/iP3792NxcRHJZBLd3d144oknLJFtvpUPph7sUh+ZyClisdgNC0f5fD7L1sznsDnldHR04MiRI0Y3Y1tisRhaW1tXbfP5fIhGoyV5vEQigWAwuGpbXV0d4vF4SR6PiIoTCoVuWMo5mUxatmY+e95kC9kPZr5SfjCtkpFKRJre3l4oigJFUbC8vJy7btWa+QzeZAvl/mByxTBryuYqnDx5kjkKDtPR0YGBgQF4PB5Eo1F4PJ4bktWshLXNyTaYbU4bMfuCFEQAFyYhIlolOzsgW+4SAFRVzS3VSmQGhQZvDpsTkSNYpewlUSEYvInIEZhkSHbCqWJEJsVz6vqyStlLokKw501kQqzgpr9s1ayamhrE4/HcuW4eEJEVsedNZCLZ3vbPf/5z1NTU4Pbbb89VcAPMt6aw3ko92pAN4ERWx543kUnk97YrKipQUVGB8+fP54rP2D25iqMNRIVj8CYyifx66Q0NDRBCoLa2Nlfi1e7JVawXT1Q4DpuT4ZiYpcmvl97a2orz58/D7XZjeno6V8HNzslVrBdPVDj2vMlQHCp9R/5UJp/Ph66uLiwvL2N5edkRyVWcykVUOPa8yVD5Q6UAHJGYNTY2huHhYUxMTCAcDqO/vx/d3d03TGVyuVy47bbbbB+0sziVi6hw7HmToZxW9WpsbAyDg4NIpVJoa2tDKpXC4OAgxsbGHD+VyenP3xQyGUBRgIsXgQsXtEtF0baTqRTV8xZC7ADwdwDaAFwG8DtSSuUm+zYAeBXAd6WUnynmcck+skOl+fWm7TxUOjw8jGAwiMbGRgDIXQ4PD6O7u9vxU5mc/vwNNT8PRKPA8jLgdms/mQwwOQnE40BrK1BTY3QraUWxPe/HAfxIStkJ4Ecrv9/MUQAjRT6erZw6dQqf/OQn8eCDD+KTn/wkTp06ZXSTys5pS2tOTEwgEAis2hYIBDAxMWFQi4igBeloFHC5oCwu4uVz53D69Gm8fO4clMVFwOXSbt+oB/6jHwF9fUAwCHi92mVfn7addFds8P4YgG+uXP8mgP+03k5CiG4AzQB+UOTj2capU6dw9OjRVcOnR48edVwAd9pQaTgchqKsHpxSFAXhcNigFhEBmJkBlpehqCrOnj2LhYUFBAIBLCws4OzZs1BUVeuRq+r6f//MM8Bv/ibwk59ovfNbb9Uuf/ITbfszz5T3+ThAscG7WUoZA4CVy1vW7iCEqADwFwC+WORj2crx48cRDAbR1NQEl8uFpqYmBINBHD9+3OimlV02gPf19dk6cANAf38/4vE4pqamsLS0hKmpKcTjcfT39xvdNHIyRQHcbly6dAl1dXWoq6uDECJ3/dKlS9ow+nrT9n70I+CLXwTcblzMZPDvsRj+fXwc/x6L4WImo/3dF7/IHrjONg3eQogfCiHOr/PzsQIf49MAnpNSRgt4rEeFEGeEEGcmJycLvHtrcurwaXZq2MmTJx05Jay7uxuHDh2C1+vF5cuX4fV6cejQIXR3dxvdNHKyTAZwuTA9PY3a2tpVN9XW1mJ6ehqorFx/2PzP/xxYXsbF6Wmo8/OrblLn53Fxelrrtf/VX5XyGTjOpglrUsoHbnabEOKqECIkpYwJIUIArq2z2wcA/LoQ4tMAvACqhRApKeUN58ellF8H8HUA6OnpkYU+CSvKDp82NTXlttl9+DQbuD0eD4LBINLpNEZHR23f216ru7ubwZrMxeUCMhk0NDRgdnZ21QyQ2dlZNDQ0AEtL2n5rnTkDNDRAjcUAACLvJgktgGPHDuD06ZI+Bacpdtj8WQB/sHL9DwD849odpJQDUspdUso2AF8AcHy9wO00Bw4cQDwex+TkJDKZDCYnJxGPx3HgwAGjm1YyxZS/dHqPnaikAgFgbg7t7e1Ip9NIp9OQUuaut7e3A3NzWhLaWvPzWoLaRlwubT/STbHB+ykADwohxgE8uPI7hBA9QohvFNs4O7v//vtx+PDhVcOnhw8fxv3331+2NpQ7IG53TjersBGVWH09UFGBgMeDvXv3orq6GoqioLq6Gnv37kXA4wEqKoC8KZ05NTVAKrXx/WcynGamMyGlOUene3p65JkzZ4xuhm3lD2HnV7Mq5RB2NgDnz+lWVTWXYa733xFlOaV+flHPc+0878pKbah8bk4L3Deb593XB/zkJ7iYydxwzhsAPDU12O1yafv97/9d5DO0PyHEmJSyZ7P9WGHN4rbbezZiBaftzul2WhU20pdTRm6Kfp41NUBbG9DcrPWUVVW7bG7Wtt+s5/xf/ytQUYHdDQ3wrNnHU1OD3Q0NWvD/9KeLen60GoO3hRXzYTUiIG42p/tmByJcsIKK4ZSlRnV5ni4X4PMBu3cDt9+uXfp86yeqZX34w8CXvwzMzWG3y4X3hkJ4b2sr3hsKaT3uuTnt9g9/uPgnSTkM3hZWzIfVqIB4szndGx2IOK0KG+nLKSM3hj7Pxx4DvvtdbWh8fh64fl277OvTtj/2WOnb4DBcVczCiln/2GwrOG22uti9996L8fFxxONx+P1+dHV12fKcJenPKfXzDX+eH/4we9dlxOBtYcV8WLM9YLMExM0ORLhghbVEIhGMjIwgFoshFAqht7cXHR0dhrTFbAeqpeKU50kaZptbmBEZ46XCjPLSKXemdSQSwdDQEAKBAHw+H5LJJBRFwcDAgGEBnNnmZBWFZpszeFucXT6sdjoQMRMjXtdjx45BVdVV5X8VRYHH48EjjzxSkscksotCgzeHzS3OLsPJZhvGt4vNcglKIRaLobW1ddU2n8+HaHTT5Q2IimKXzkwhGLzJNOxyIGImxSQ1blcoFEIymVzV804mkwiFQiV7TCKnrZ3AqWJENmbElMDe3l4oigJFUbC8vJy73tvbW7LHJHLKfP4s9rxNyknDP1Q6RmQgd3R0YGBgACMjI4hGowiFQti/f79hyWrbwc+f9RgxymQkJqyZEJO3SE8MRFvDz5812WXGChPW/v/27jU2zus88Pj/mRnOnUMOLxJJkRIpWpLtUKoZyXKa1rG3ieMkCJpWaLpZOIgDtJuFDewHb73YAFnAi10EyKZohC26dpvNAs0WKjZooXXi3Qa+JVaC1FIihY4kW5YoiZQoipQocjjDuXEuPPvhnaEpiTKHnOFcnx9AzHDm5bzn8OXwmXN7Tg2rxCQjVb90LsH6bMb7Tz9Abb5GW+euwbsKNVr3TzlVU/IQVZ1K/f5rtIlUldJoK1Y0eFehQjKn6Sf59VuZPKSvr49wOMyRI0cqmjxEVZ9SpxnVnrTyaaReJp1tXoXW2oijUbY4LLVjx44RDAYJBoPYbLbl+8eOHat00VQVKfVGOI2yMYoqLw3eVWitrTMbbUlEqUxNTdHS0nLbYy0tLUxNTVWoRKoarfX+Wy/d0lZtBu02r1If1v2jY+Ibo8lDVKFK2f3aaBOpVHloy7sG6Sf5jdHkIaoSSt2SVwp0nXdN0nWoG6ezzZVS1UzXedexRlsSUUqDg4MarJVSNU+Dd40q95IIXZqmlFLVQ8e81Zp0aZpSSlUXbXnXmc0Y0y1Xkgkdj1ZKqcJoy7uO5DOIxWIx+vr6iMViHDlyhEuXLhX1uuVIMrFZZVdKqXqkwbuObFYGsXIsTdPsZ0opVTgN3nVkszKIlTpd5Go0+5lSShVOg3cdyWcQW6kUGcTKkWRis8qulFL1SIN3HdnMDGL5AP7kk09uSjIYzX6mlFKF0+BdRwYHB3nqqafw+XxMTEzg8/lqZrvLWi67UkqVmy4VqzO1nEGslsuulCqcJn0qnra8lVJKlY0mfSoNDd5KKaXKZmXSJxFZvj86OlrpotUUDd5KKaXKphxJnxqBBm+llFJlU46kT41AJ6wppVSdqeYJYbt27eLEiROA1eKOx+PEYjGGhoYqXLLaosFbKVV21Rxcal1+QpjP56O9vZ14PM6JEyc2JT/DRq5jPmfE6Ogos7OztLa2MjQ0pNd/ncQYU+kyrOrAgQPm5MmTlS5Gw9N/sqrUVgaXlS2vzQgujSg/kzu/+x9ALBZbzoxYKnodN4eInDLGHFjrOG15q9ucOnWKo0ePMjk5SVtbG/39/Tz00EOb/gleNY5ybTHbqObn52lvb7/tMa/Xy+zsbEnPo9exsnTCmlp26tQpDh8+TDQapb+/n8nJSV555RWuXr2qSzpUyehs481Vrglheh0rS4O3Wnb06FHa29vp6OjAbrfjcrlob2/nJz/5yfIx+uZUxdLZxpurHLsAgl7HStPgrZZNTk4SDAaXv3e73bjdbmZmZpYf0zenKla5gkujKscugKDXsdJ0zFst27ZtG6FQiI6ODgDa29t59913aW1txRijSzpUSehs482X/x2X0mqTV/U6Vk5Rs81FpA34AdAPjAN/bIwJrXLcduB7QB9ggM8ZY8Y/7LV1tnn55ce829vbCQaDhEIhrl+/zuc//3m6urp0trlSDUpnlpdPobPNiw3e3wbmjDHfEpGvA0FjzH9Y5bi3gG8aY14XET+wZIyJ33ncShq8K2PlbPNt27Zx6NAh9u/fX+liKaUqqFzLz1T5lop9AXg8d//7wFvAbcFbRB4EHMaY1wGMMdEiz6k20f79+zVYK9WAPiynQ7mWn6nCFTthbasxZgogd7tllWN2A/MiclRERkTkz0XEvtqLicjXROSkiJxcOUlKKaXU5llrm06dWV591gzeIvKGiJxd5esLBZ7DATwKPA88DOwEvrragcaY7xpjDhhjDnR2dhb48qpa5P8BvPrqq7o/r1I1ZK1tOnVmefVZM3gbYz5ljBla5euHwA0R6QbI3d5c5SWuASPGmMvGmAzwMvDRUlZCVd5an9yVUh/upZdeYu/evXR3d7N3715eeumlsp17rYQr5Vp+pgpX7Jj3j4CngW/lbn+4yjG/AoIi0mmMmQF+D9CZaHVGUyXWkUwGFhYgFLLuOxwQDEJzs3VfldxLL73ECy+8QHNzM11dXUQiEV544QUAnnnmmU0/f75bfOWEtDu7xTdj+ZnauGLHvL8FPCEio8ATue8RkQMi8j0AY0wWq8v8TRE5AwjwP4o8r6oymiqxTiwuwvg4zMxYgdrvt25nZqzHFxcrXcK69OKLL9Lc3ExbWxsOh4O2tjaam5t58cUXy3J+7RavPUV9jDbGzAKfXOXxk8Cfrvj+dWBfMedS1a2QT+6qymUyMDEBDgehWIyxCxeIRCIEAgEGBgYI+nzW8/392gIvsVu3btHV1XXbY4FAgOnp6U05nyZcqX2aHlWVhH5yrwMLC7C0RCgWY2RkhFQqRTAYJJVKMTIyQigWg6UliMUqXdK609HRQSQSue2xSCSynO2wlO41PwXgkUce4cknn9Tx7BqgH59VSRST8rLYPcM1sUyJhELgdjN24QJer3d5GCR/OzY2RnDfPpidBZ9Px8VL6Nlnn10e4w4EAkQiERYWFnj++edLfi6dn1If9F2mSmYjE1pWpl3cyJ7hK1O69vf3EwqFOHz4MM8995wG8PXKZMDtJhKJ3LZBDYDH4yEUCoHdDpGINf69tARut/WVyVjj4jduQGsrxOOQTH4wRu5yWcdpgF9VflLaiy++yPT0NB0dHTz//PObMllNE67UB30HqYoqthWwchtTYPn26NGjGrw/TH5G+cwMhMNWsA2FoLWVoM1GYmEBbyCwfHgikSAQCFjB+OZN2Lnz7nHxbdsIhsNw9Sr09Vmvl0pZL+B0wpYt1vlmZ63nXa4KVb46PfPMM1Uzs1xVPw3eqqKKbQVMTk7S399/22PBYJDx8fFVjy+2i74uLC5aE8+SSSuQ2mxWcG1qgmvX2OH3897FiyR6e3G3tJBIJIjH4+zZs8c6vqVleVzc6/USDAZJLCxw7s03eXDfPkgkuP7qq4RFoKkJAUw6jd/jofdjHyMYCOjEtwratWvX8hj3yk1GdLfA2qIT1lRFFZt2Mb+N6UqhUIht27bddawmkuGDGeXA/MQEZy9e5PW33+blH/+Y13/zG85PTCChEA8ODeGNRJi/dQun08nw8LA12zwahWCQsbGx5XFxEcEngtft5v2LFzl39ixL8/PYnE7Onz/P++fPY3M6yaZSnDl+XCe+VZgmXKkP+rFXbZpCWrnFtgIOHTrE4cOHAZa3MZ2dneUrX/nKXcfqRB0+mFF+6xbvnz1LuqmJmZs3EZuNeDyOu6uL2Llz7PT72btrF3R1WZPTkkkr8Hd2rjoubo9GsTU3896ZM+xta8Pt8XD55k0Czc3I0hKz4+Pc19mJY2aGa//8zwQfecQaH29pqeAvo3FpwpXapy1vtSkKbeUW2wrYv38/zz33HH6/n/Hxcfx+/z0nq2kiGZZnlF87fRq33U5qbIz2WIwtmQx+Y5iPRDD9/UxOTVnd6JOTVtDeutXq5vZ6IZMhEAiQSCSWX1ayWZLpNABum40lp9P6MGC3E4jHWZqbA4cDl9/PQiIB8/Oa9EWpImjLW22K9bRyi20FFLqNqU7UwQrEImTGx/G3t3N1cRFvczMYgz+dJjY1haevj9itW2CMFWQnJpbHumlqgmiUgYEBRkZGAPDYbGQmJ3HcvMlvGYP9/fdZGhig2W7HPjNDymYj09TE+JUrLMzPY+/rY35xkVa3W8e+N4nO7ah/2vJWm6IaW7maSCbn6lXcLS3MLiwQikQYHR1lcnqa+WQSt8uF/d13aUmnYWoKsllrMlsyaX0fDsP16wQdDoaHh3FnMiwdP443kWCgv5++oSFiDgdmaorB2VmSs7PMzM+TSCRYjETI+v20tbVx7p13CLlcOva9CXRuR2PQj7tqU2y0lbuZLYZiEsnUjaYmSCZp3r6dd155BbfHQzKZJBqNEpqZ4eCOHaQXF2nv7OT86CiT6TSRd9/F5/fT3d5Ob08Prdu3w8QEwbY2guk0HDzI5MwM7/z858wvLEBnJ102G4FYjD1uN+edTtKZDB6fj67778fv9ZKMxRibnibY3f1Bq16VhM7taAwavNWm2MhEtGITthSimifqlKWrM5eIJRSLMTg4yHwsBiIkk0ncTifpRILO7du5eeUK8S1buBGPg8NBPB7H5XSycPYs9weDBHt6YG4O0mmuh8Mc+/nPcQWDBINBYvE4F0MhnujpodPjIRUK4d69m2xbm9UVn81i7+1lLhazkr4kk6WtY4PTJCyNQbvN1abYyES0lS0GEVm+Pzo6WsaSV0bZujqNge3biS0sENi2jZ3btnHggQf4+PAwH+vuplOExPXreFMpQskkbrebQCCA2+1mPhzGGQhw7cwZa7exiQnYs4dfTk8jfX24e3pIdnTg7O7G19zM+1NTEAzit9uJNzVhbDYyra2kt24lns1aSV+yWR3vLrFil1+q2qDvGrVp1tvKbdQWw9zcHC+//DJzc3N0dnbS19dHS64bueRdnQ4H2O0477uPhUgEn8uFIxymaXqabDSKY9s2onNzeDo6yNy8ScDnI+V04nS5iEajuL1eolNT1pKz8XFwu0levkywt5elbBZjt5Ox27H19nJ5fJxH+/tp9/sZ9/nwer14PJ7bk74kk9ZMdlUymoSlMWjLW1WNRmwx5Fvcc3NzbNmyhVQqxdmzZwmHwx8+wS+TsZZ9Xb4MFy5Yt/lNQj5MMAjJJAP33ceCCJFAgGwgQGjnTibb24n4fFyfm2P0xg0yTU2kMhlc4TDpRAKv18tiOExrMgmXLlmBd3qaLocDrl3DOzuLLbdcLBqN0trTA9ksLS0tDA8P43Q6CYVCtyd9sdmsdeSqZDQJS2PQlreqGrXWYijFbmb5oYLOzk4WFxfxeDwATExMMDAwsPoHl3x605UbgySTcPGi1SLessVaj33nJiCZjPU1OUnQGD7a0cHViQkic3MsNTeTcrloy2ToHhxkdGKCaDJJk8OB3+EgnU7TPjCAjI/TNTBAeHqaaRFSZ87g9vu5cfEi9kwG99ISN1wuIrEYv/vZz1rBORAg2NRk7Uhmt1td5fmkL319NdFtXms711Xz3A5VGtryVlWjlloM+d3MotEo/f39RKNRDh8+zKlTp9b1OvkldX19fSQSCRKJBC6Xi5mZmdWXseXTmzochNJpfn36NMdee40zb7zB/M2bViAPh61jZ2Y+SISyuGjdD4WgtxdcLlpdLvb5fDwyOEizw0FHRwdup5Om/n523n8/7bmNSZw+H90+Hx3GMOh0IvE4548fZ3xigtnJSWKzswQ6O1lyOEhcuUKzCJ/77Gfpa28Hjwf277e6xjMZa1nYyqQvNbA5SamutVKlVP0feVVDqZUWQ6l2M8sPFbS0tDA0NMTExAQ3b95c/j3c9cEln940vzGI00lnJkMym+XE6dMEWlqwxeO4+vrYMTRkdU2PjVk/m5tlPjY2xkIoRKvTSX8iQYvDQWp8nKZ9+0i4XDjm5nB3dLDL6WRhYYH9Dz9szSy/fh38fs5MTnJlaQl/czPS3U3z5CTzxtC1Zw/7fud3rG7wfG/AwYPW5Dao2eVgunOdqkYavJXagPXuZnYvK4cKAoEAAwMDbNmy5d49Drn0pmMXLuD1evFlswiQEWFqeprIwgIP7tlDam6OkZERa2w5HgebjVA2u7wTWGtHB4lEgrPz83xk+3acO3aQSKdx5WaDSzJJOpPB63RareXFRXA6CXd08Itf/pIlIJHJ0GW30xqJ8MDYGLaTJ6GnB3buhD/7MxgetoL4veS3Jc2P1TscVbnfd6mutVKlpN3mSm3AenYz+zDrHirIBblIJILH48EejWKcTqZv3KC5uZlsNovY7XiamvB6vYyNjVmBNx6/aycwr9eLs6ODa5cv0zs4SHpmhng8jrHbidlszAeDdH3607BrFzz8MOFgkPNXr5JZWsLtcuG/cYMdr71GcHyclNfLfHc37NhhtdC/8x14//17VzzfjT8zYwVqv9+6XdnVXyVKda2VKiUN3kptwKFDh5idneXWrVtks1lu3brF7Owshw4dWvdr5QP4k08+ufYYv8Nx28Ygks2C3b48S9/r9UI6jSSTBObnSZ8/D9euwcICC6HQ8oS4PGdLC4mZGVrDYT7i8+GbmyMyMYHTbv9gRvjCAgSDXItG8YjQ29uLmZlh6Nw5Mk4nlxIJzly6xPunT/PDN97gbDZrBeNvftM6951WGbd/6623+PXp04TSaauOExNrz5wvk1Je65XyKw1effVVTV+q1k2Dt1IbsJ7dzEoqv9RrYICbN29y7sIFTv/610xPTzMzM0N3ezuu69eRpSUS6TTejg4rJer8PG2JBMn8ZDZAUimWJifxBoPWkq7WVvZ+5CM8ev/9fLS1leDSkhVAt2wBt5s5lwuP3U5/Tw+743Fs2SzT8Tg3ZmbIAn6PB5PJ8LN33uFXk5OQTsNbb91dhzvG7VOpFMFgkFQqxcjISNXt970Z11rzj6tiVc/AklI1ptDdzEqqudnKBZ5OY4xh0e3GEQ7T1tbG/OwsXLvGUmsr0+k0V69cYcuWLdibmujp66Ovv5/3Tp8mbrPh8XjITkwQT6Xo2LmTs5OTRNJpmiMR+np6aG1utgJ3b6/VDZ7J4OvpIbq4iG9xkZ5YjIX2dsLnz9Nkt9PsdmM3hozHg2QyjJw6xcNf/CK89hp8+cu31+GOcfv8Bjb527GxMWtZWRXlPC/1tdb846pYGrxVQ7p06RLHjh1jamqK7u5uHnvsMQYHBytdrLU5HNDXx/grr9ATCODq6aFpZgZECF+5Qnh6mnAgwPT162zv66OjpYXFhQXOXb7MA8PDPPjAA1yJRolMTRF0ONje28vVy5fxOp34BgeJpVL8OhRiuL+fYFOTNfYcDMLMDAP33cc7c3OYhQU6jMEXDGLLZHD7fCDCgsNB1OGgyW4nFo1aa81v3Li7Drn86pFIhGAweNtTHo/HGl+u85znjZpNUJWOdpurhnPp0iWOHDlCLBajr6+PWCzGkSNHuHTpUqWLVhiXixmvF3tPD4iQ9fuRdJq2QADf7t1s7enhgd276fT7kaUlHP392Pr7uTY+TqvXy2/19PDo0BBD+/YRnp7G63Ti6OtDHI7llvDY2Jg1U3x21mrt22wEfT4eOngQs2MHMZ8PAfD5iGWzxO125h0OlkRILS7i8XohHrd+9k53jNuvlEgkGiLneSNmE1SlpcFbNZxjx44RzO2AZbPZlu8fO3as0kUrWEt7O1G7nfS2bSzu2kVseJiFQAB/ayux2Vk8TufyJiDG6cQdCDDr8UBXF6RS1rizCCGbDduOHRinc/m1PR4PkUjEav3ml3D19UEmQ7CpiY8OD9N76BBb3W527t1LZGmJ6WyWDJBMJFhMpRjevx+mp+HTn7678CvG7ePxuDXD3Zjl+wMDA1ar+46WaT3RveVVsTR4q4YzNTW1vPFHXktLC1NTUxUq0frd9c9/cZGIw0Hvww/j3LOHSEsLJr/8CqtF2xwMWglUBgas5V89Pfi6u0mkUre99qqtX5fLyoiWz5R28CA4HOzbuZO9jz6KramJWDSKo6mJ3/3EJ3h42zZrotzjj99d+BUt+UbNeV5L2QRVdarffiml7qG7u5twOHzbeGs4HKa7u7uCpVqf/D//0dFRZmdnaW1tZffjjxPMZGBggJGREYB77+K1tGSNYxdybJ7DYU0ga2mxErEEg/DNb3LA7+fAF79ojXHH41aLOxqFb3zDmvB2p3xLfmKiqnOeb/b+6rWSTVBVJzHGVLoMqzpw4IA5efJkpYuh6lB+zDsYDNLS0kI4HCYUCvHUU0/VxqS1QcvEjwAACJxJREFUe8lkrAQnDsdyGtRIJLKcuS3o81nH5LOFFXrshwXRa9es5WCvvWZ1xTc3W13ljz++euC+s7yxmDWunu+eb2+3WtxVELhPnDiBL7eVaX6THG0dq80mIqeMMQfWPE6Dt2pENTvbfC137ji2skVrs1kt2vxmIOs5tsHk12D7VnTdx2Kx5e5tpTZLocFbu81VQxocHKyPYH2n/Nh0vkWbTFqt2K1b727RrufYBqNLuVS1a9x3p1L1auXYdCmPbSD5pVwrW966lEtVE51trpRSd9ClXKraafBWSqk76FIuVe2021wppVahS7lUNdOWt1JKKVVjNHgrpZRSNUaDt1JKKVVjNHgrpZRSNUaDt1JKKVVjNHgrpZRSNUaDt1JKKVVjigreItImIq+LyGjuNniP474tIu+KyDkR+UsRkWLOq5RSSjWyYlveXwfeNMbsAt7MfX8bEfk48DvAPmAIeBh4rMjzKqWUUg2r2OD9BeD7ufvfB/5glWMM4AacgAtoAm4UeV6llFKqYRUbvLcaY6YAcrdb7jzAGPM28FNgKvf1qjHmXJHnVUoppRrWmrnNReQNoGuVp75RyAlE5D7gAaA399DrIvIJY8zPVjn2a8DXALZv317IyyullFINZ83gbYz51L2eE5EbItJtjJkSkW7g5iqH/SFw3BgTzf3Mj4GPAXcFb2PMd4HvAhw4cMAUVgWllFKqsRTbbf4j4Onc/aeBH65yzFXgMRFxiEgT1mQ17TZXSimlNqjY4P0t4AkRGQWeyH2PiBwQke/ljvlH4BJwBvgN8BtjzCtFnlcppZRqWEXt522MmQU+ucrjJ4E/zd3PAv+mmPMopZRS6gOaYU0ppZSqMWJMdc4LE5EZ4EoJX7IDuFXC16u0eqpPPdUFtD7VTutT3Rq9PjuMMZ1rHVS1wbvUROSkMeZApctRKvVUn3qqC2h9qp3Wp7ppfQqj3eZKKaVUjdHgrZRSStWYRgre3610AUqsnupTT3UBrU+10/pUN61PARpmzFsppZSqF43U8lZKKaXqggZvpZRSqsbUbfAWkTYReV1ERnO3wXsc920ReVdEzonIX4qIlLushVhHfbaLyGu5+rwnIv3lLWlhCq1P7tiAiEyKyF+Vs4yFKqQuIvKQiLyd+1s7LSL/shJl/TAi8hkROS8iF0Xk66s87xKRH+SeP1Gtf1t5BdTn3+XeI6dF5E0R2VGJchZqrfqsOO6PRMSISFUvtyqkPiLyx7lr9K6I/H25y7geBfy9bReRn4rISO5v7nNFndAYU5dfwLeBr+fufx34r6sc83HgF4A99/U28Hily77R+uSeewt4InffD3grXfZi6pN7/r8Bfw/8VaXLvdG6ALuBXbn7PVh727dWuuwrymfH2oNgJ+DE2ofgwTuOeRb469z9LwE/qHS5i6zPv8i/P4Bnar0+ueOasXZsPA4cqHS5i7w+u4ARIJj7fkuly11kfb4LPJO7/yAwXsw567blDXwB+H7u/veBP1jlGAO4sX7ZLqAJuFGW0q3fmvURkQcBhzHmdQBjTNQYEy9fEdelkOuDiOwHtgKvlalcG7FmXYwxF4wxo7n717G2z10zi1IZHQQuGmMuG2NSwP/GqtdKK+v5j8Anq7WnigLqY4z56Yr3x3Ggt8xlXI9Crg/Af8H6MJksZ+E2oJD6/GvgvxtjQgDGmNW2nK4WhdTHAIHc/RbgejEnrOfgvdUYMwWQu91y5wHGmLeBn2K1gqaAV40x1bpd6Zr1wWrdzYvI0VzXzJ+LiL2spSzcmvURERvwF8C/L3PZ1quQa7NMRA5ifWC8VIayFWobMLHi+2u5x1Y9xhiTAcJAe1lKt36F1GelPwF+vKklKs6a9RGRYaDPGPN/y1mwDSrk+uwGdovIL0TkuIh8pmylW79C6vOfgC+LyDXgn4B/W8wJi9pVrNJE5A2ga5WnvlHgz98HPMAHn7hfF5FPGGN+VqIirkux9cG6no8Cw1j7qP8A+CrwP0tRvvUqQX2eBf7JGDNR6QZeCeqSf51u4O+Ap40xS6UoW4ms9gu+cx1pIcdUi4LLKiJfBg4Aj21qiYrzofXJfdA9jPV+rwWFXB8HVtf541j/o38uIkPGmPlNLttGFFKffwX8rTHmL0Tkt4G/y9VnQ/8Hajp4G2M+da/nROSGiHQbY6Zy/zBX63L5Q+C4MSaa+5kfAx/DGjMquxLU5xowYoy5nPuZl7HqU5HgXYL6/DbwqIg8izV+7xSRqDHmnpN1NksJ6oKIBID/B/xHY8zxTSrqRl0D+lZ838vd3Xr5Y66JiAOr62+uPMVbt0Lqg4h8CusD2GPGmMUylW0j1qpPMzAEvJX7oNsF/EhEft9YWzRXm0L/3o4bY9LAmIicxwrmvypPEdelkPr8CfAZsHp9RcSNtWnJhoYD6rnb/EfA07n7TwM/XOWYq8BjIuIQkSasT97V2m1eSH1+BQRFJD+W+nvAe2Uo20asWR9jzFPGmO3GmH7geeB/VSJwF2DNuoiIE/g/WHX4hzKWrVC/AnaJyECurF/CqtdKK+v5R8BPTG72TRVasz65bua/AX6/ysdTYY36GGPCxpgOY0x/7v1yHKte1Ri4obC/t5exJhUiIh1Y3eiXy1rKwhVSn6vAJwFE5AGs+VYzGz5jpWfpbdYX1ljcm8Bo7rYt9/gB4HvmgxmCf4MVsN8DvlPpchdTn9z3TwCngTPA3wLOSpe9mPqsOP6rVO9s80L+1r4MpIF3Vnw9VOmy31GPzwEXsMbiv5F77D9jBQFy/2z+AbgI/BLYWekyF1mfN7AmqOavx48qXeZi6nPHsW9RxbPNC7w+Anwn97/5DPClSpe5yPo8iLW66Te5v7dPF3M+TY+qlFJK1Zh67jZXSiml6pIGb6WUUqrGaPBWSimlaowGb6WUUqrGaPBWSimlaowGb6WUUqrGaPBWSimlasz/B0iWoSLE34GEAAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from sklearn.cluster import DBSCAN\n", "\n", "dbscan = DBSCAN(eps=0.08, min_samples=10)\n", "clustering_results = dbscan.fit(distance_df_2d)\n", "plt.figure(figsize=(8,8))\n", "cluster_members = clustering_results.components_\n", "\n", "# plot all data points\n", "plt.scatter(x, y, c='k', alpha=0.2)\n", "\n", "# plot cluster members\n", "plt.scatter(\n", " cluster_members[:,0],\n", " cluster_members[:,1],\n", " c='r', s=100, alpha=0.1)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
cluster
test_typetest_method
AddSchedulingTestvoid add2EmptySchedulingWidgetsToSite()0
void addEmptySchedulingWidgetToSite()0
void failsIfPositionIsNull()0
AddTodoTestvoid addedTodoIsPersisted()4
CommentGatewayTestvoid readFailsOnNullSite()1
\n", "
" ], "text/plain": [ " cluster\n", "test_type test_method \n", "AddSchedulingTest void add2EmptySchedulingWidgetsToSite() 0\n", " void addEmptySchedulingWidgetToSite() 0\n", " void failsIfPositionIsNull() 0\n", "AddTodoTest void addedTodoIsPersisted() 4\n", "CommentGatewayTest void readFailsOnNullSite() 1" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tests = pd.DataFrame(index=distance_df.index)\n", "tests['cluster'] = clustering_results.labels_\n", "cohesive_tests = tests[tests.cluster != -1]\n", "cohesive_tests.head()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nuniquecount
cluster
0710
1316
2119
3131
4717
5112
6632
\n", "
" ], "text/plain": [ " nunique count\n", "cluster \n", "0 7 10\n", "1 3 16\n", "2 1 19\n", "3 1 31\n", "4 7 17\n", "5 1 12\n", "6 6 32" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_measures = cohesive_tests.reset_index().groupby(\"cluster\").test_type.agg({\"nunique\", \"count\"})\n", "test_measures" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "cluster\n", "0 {AddSchedulingTest, GetSchedulingsTest, Delete...\n", "1 {CommentResourceTest, CommentGatewayTest, Comm...\n", "2 {CreateSiteTest}\n", "3 {CreateTimeDiffTest}\n", "4 {TodoResourceTest, GetTodoListTest, TodoGatewa...\n", "5 {GetSiteTest}\n", "6 {SchedulingDateResourceTest, SchedulingDatesRe...\n", "Name: test_type, dtype: object" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_list = cohesive_tests.reset_index().groupby(\"cluster\").test_type.apply(set)\n", "test_list" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nuniquecounttest_type
cluster
0710{AddSchedulingTest, GetSchedulingsTest, Delete...
1316{CommentResourceTest, CommentGatewayTest, Comm...
2119{CreateSiteTest}
3131{CreateTimeDiffTest}
4717{TodoResourceTest, GetTodoListTest, TodoGatewa...
5112{GetSiteTest}
6632{SchedulingDateResourceTest, SchedulingDatesRe...
\n", "
" ], "text/plain": [ " nunique count test_type\n", "cluster \n", "0 7 10 {AddSchedulingTest, GetSchedulingsTest, Delete...\n", "1 3 16 {CommentResourceTest, CommentGatewayTest, Comm...\n", "2 1 19 {CreateSiteTest}\n", "3 1 31 {CreateTimeDiffTest}\n", "4 7 17 {TodoResourceTest, GetTodoListTest, TodoGatewa...\n", "5 1 12 {GetSiteTest}\n", "6 6 32 {SchedulingDateResourceTest, SchedulingDatesRe..." ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_analysis_result = test_measures.join(test_list)\n", "test_analysis_result" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'AddSchedulingTest',\n", " 'DeleteTodoListTest',\n", " 'DeleteTodoTest',\n", " 'DownloadFileTest',\n", " 'GetSchedulingTest',\n", " 'GetSchedulingsTest',\n", " 'ReportAbuseTest'}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_analysis_result.iloc[0].test_type" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Conclusion\n", "What a trip! We've started from a data set that showed us the invocations of production methods by test methods. We also went our way deep through the three mathematical / machine learning techniques `cosine_distances`, `MDS` and `DBSCAN`. Finally, we've found out which different test class classes test the same production code. The result is a helpful starting point to reorganizing your tests.\n", "\n", "In general, we saw how we can transform software specific problems to questions that can be answered by using standard Data Science tooling." ] } ], "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.4" } }, "nbformat": 4, "nbformat_minor": 2 }