[小北De编程手记] : Lesson 04 玩转 xUnit.Net 之 Fixture(下)

  上一篇文章《[小北De编程手记] : Lesson 03 玩转 xUnit.Net 之 Fixture(上)》向大家介绍了xUnit.Net 共享数据的方式、Test Case的构造函数 & IDisposable.Dispose、Class级别的Fixture : IClassFixture。这一篇,我们接着讲解后面的内容,回顾一下本文要讨论的内容:

  • xUnit.Net 共享数据的方式(上)
  • Test Case的构造函数 & IDisposable.Dispose(上)
  • Class级别的Fixture : IClassFixture(上)
  • Collection级别的Fixture : ICollectionFixture(下)
  • 依赖注入以及输出日志(下)

(四)Collection级别的Fixture : ICollectionFixture

  回想一下上一篇中我们虚拟的应用场景。其中,关于问题三:“在应用程序级别统一创建数据库连接,Test Case 使用的数据库连接是同一份(或是统一管理的)”。 针对这一需求的实现,我们可以使用xUnit.Net的ICollectionFixture来实现。Collection级别的Fixture为我们提供了可以在多个测试类之间数据共享的能力。包含在同一个Collection之下的所有测试用例共享一份上下文数据。下面我们就来动手实现一下虚拟场景问题三之中的那个功能吧。

  Step 01:定义CollectionFixture(Demo中的DatabaseFixture

  与ClassFixture类似,自定义的CollectionFixture类,需要完成其构造函数 & IDisposable.Dispose的定义。而CollectionFixture类的构造和Dispose方法最终会在所有被标记使用该Collection的Test Class对应的Case执行前后被调用。即所有标记使用该Collection的测试方法运行之前会执行CollectionFixture的构造函数。所有标记使用该Collection的测试方法全部运行完毕之后会执行CollectionFixture的IDisposable.Dispose函数。我们定义一个DatabaseFixture,代码如下:

     public class DatabaseFixture : IDisposable
{
public object DatabaseContext { get; set; } public static int ExecuteCount { get; set; } public DatabaseFixture()
{
ExecuteCount++;
//初始化数据连接
} public void Dispose()
{
//销毁数据连接
}
}

  代码中,省略了得创建和销毁数据库连接的Code。只是使用了一个object类型的属性来表示数据库上下文,并且创建了一个静态变量ExecuteCount用于标记构造函数的使用频率。

  Step 02:定义Collection。

  对于ClassFixture而言,因为是基于Class级别的数据共享。so... ... xUnit.Net提供了直接用类继承IClassFixture接口并结合构造函数注入的方式优雅的实现了数据共享的功能。而对于Collection(一组类)的数据共享又该如何实现呢?先看一下示例代码:

     /// <summary>
/// 定义Collection名称,标明使用的Fixture
/// </summary>
[CollectionDefinition("DatabaseCollection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
}

  可以看到,我们定义了一个没有任何内容的类DatabaseCollection,该类的主要功能是定义了一个名字为“DatabaseCollection”(此名称可以和类名不同)的Collection,并指明该Collection所对应了Fixture。需要说明的是ICollectionFixture和IClassFixture一样是一个泛型标记接口(即没有任何需要实现的方法,只是用来标记对应的Fixture的类型)。而定义Collection代码中使用了CollectionDefinition标签,其定义如下:

 namespace Xunit
{
// Summary:
// Used to declare a test collection container class. The container class gives
// developers a place to attach interfaces like Xunit.IClassFixture<TFixture>
// and Xunit.ICollectionFixture<TFixture> that will be applied to all tests
// classes that are members of the test collection.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class CollectionDefinitionAttribute : Attribute
{
// Summary:
// Initializes a new instance of the Xunit.CollectionDefinitionAttribute class.
//
// Parameters:
// name:
// The test collection name.
public CollectionDefinitionAttribute(string name);
}
}

  被CollectionDefinition标记的Class在运行时会被xUnit.Net框架实例化为一个对象,该对象将用于标记其他的Class(有兴趣的话可以去GitHub看看xUnit.Net的源代码)。这里需要一个CollectionName作为参数,该参数将会用标记那些需要使用这个CollectionFixture的类。

  Step 03:用Collection来标记需要使用Fixtrue的测试类。

  xUnit.Net提供了Collection类,它的作用是用来指明测试类需要使用哪个Collection的。所有被标记了Collection测试类中的测试方法在其运行之前会调用一次对应的CollectionFixture的构造函数,所有方法运行完毕之后会调用一次CollectionFixture的IDisposable.Dispose函数(如果定义了的话)。值得注意的是测试类中依旧是通过构造函数注入的方式获取DatabaseFixture实例对象的。那么,我们来看一下Demo:

     [Collection("DatabaseCollection")]
public class SharedContext_CollectionFixture_01
{
private DatabaseFixture _dbFixture;
private ITestOutputHelper _output;
public SharedContext_CollectionFixture_01(ITestOutputHelper output, DatabaseFixture dbFixture)
{
_dbFixture = dbFixture;
_output = output;
} [Fact(DisplayName = "SharedContext.CollectionFixture.Case01")]
public void TestCase01()
{
_output.WriteLine("Execute CollectionFixture case 01!");
_output.WriteLine("DatabaseFixture ExecuteCount is : {0}", DatabaseFixture.ExecuteCount);
}
} [Collection("DatabaseCollection")]
public class SharedContext_CollectionFixture_02
{
private DatabaseFixture _dbFixture;
private ITestOutputHelper _output;
public SharedContext_CollectionFixture_02(DatabaseFixture dbFixture, ITestOutputHelper output)
{
_dbFixture = dbFixture;
_output = output;
} [Fact(DisplayName = "SharedContext.CollectionFixture.Case02")]
public void TestCase01()
{
_output.WriteLine("Execute CollectionFixture case 02!");
_output.WriteLine("DatabaseFixture ExecuteCount is : {0}", DatabaseFixture.ExecuteCount);
}
}

  Dome中定义了两个测试类,每个测试类中有一个测试方法,并用Collection指明了需要使用的Collection的名称。运行结果如下:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+QAAAHRCAIAAABsF+RxAAAgAElEQVR4nOy973cU55XvO39BXt9XfV9MZtYkszJrcsA49thj7hzOseWVnEwmPvl1Jp5AnJV4JTjuuZnEgYlvsMFJfBkTomP7YCB4/KM5WB5hmlEAWxAJYYTcCIQwCAWw1EKNWqIR/avASSaX+6J+7ed59lNV3arqH9Xfz9ovuqurntpPlVr96a1dpT9aXCwjEAgEAoFAIBCIFow/anoGCAQCgUAgEAgEgg3IOgKBQCAQCAQC0aIhyPrJUxcRCERbB/MmX3cSgUDQaPpHLwKBQAQPWdabnhACgag7IOsIRJBo+lsVgUAgggdkHYGIT0DWEYgg0fS3KgKBQAQPyDoCEZ+ArCMQQaLpb1UEAoEIHpB1BCI+AVlHIIJE09+qCAQCETwg6whEfAKyjkAEiaa/VREIBCJ4QNYRiPgEZJ2L6b7bHz73fNjDPp+/GMWwiIZEgHdTem3igS2nonmr7n0scf/WU83+dRFSpNcmHtsrPKg9Tm29P5SjHdY4CIRH+Lx/I/nV0Xay/s5Tq54+2Pw0EIiaIyESxS58Zf3rk7dlJqfDEaDn8xfdQZtosdN9dhJ9vc6SGMi6O6+QTpkzIJlFbzHoGXTXLH7dcxcXj0006hDVEMrbJL3WfmOu3essaZisu3tPrE03/TdVjSk1UdbHt9xPfqXev/VUy8n6+Jb76z0mDU3S+bFvcDg/ZuSs7X0soS5UEhbO+9LmXvObzn7/7l2bkFmbboKsH3xqlcxT7yx5l+d3PkJHrNW8IeuIdg1H0Jso68SiPBxLFxPPFRwDVtWN6N3z+Yu3NWv6DlV3DrYd2q9OPFcw5xiNrNefZO3RW7xNj2dvcckGPPFcwdbo3qIt3NN9hfwd7h71PyG9xdvOmvrxb98u9k3WKetjV43gK3/rrezYVeNbb2V9FzohvkfSa11Hd+yqUbK+9zHyDaG8uPex+7eM1zhgHbLluUltKdUt60t3xJpGaLiS7n0skXjg/rWPrb0/Ufs5bWQ0S9bHtzhHZu9jCeenSHhrsD9RdSesbHhq6/33P3B/rV8ymS/bdISmVdbr8+PzOx9Z9dTB4MsDBmQd0a5Rk6w/88xPE4nEM8/81HchjSbJOlVk6pceu4hG1p/PX2Qkst1lnTu8S4zn8xfds8Nm63HQJp4rBD2eX1+CrNPwXf+fDsyOXTX+x57L5tP/sefy2FXjnw7M6tYX3iOntt7PFOcaI+v0e0LdEa6s15oSZF0fp7beH8L5jTqaJOunthJLZnPQvQdDk/VTWx64f8v43rU1jgZZDxCNk/Vt27bhcYc/DjdqrayvW7c+kUj84hfPm09/8YvnE4nEunXrPTZZgqy7XRaOXd1x7EPS6kDaMCQh5uustu1RL7QeS0OZsqi0r/hvGNBrp/tuf/jcMbttw+khIX07pBhvZ+JTOXbTu+PYh87Xkq9P3r49WRSSZGbB7og5/p6HVzcF6axpTm5vkfbSMErt8V3r+fzFQv65SU224ck6+ziIr/uauizrvJ6m1yYe2LLlMfLX7fLioqVfYsOMaQDpte5f5N0eElJSTQt/MzfX9Gp+pes7KiBkdf+WcWE1zd5PbXnAGWHv2kRi7WPKJiTqSUmVdZ8jcP+WrUIOgrcFnHiZL5QmHtvrO2W6O/dxwPPIHA1ynGna5gFZQndQg0InyvLclQkyS2o4fXsfo/0ne9cqB7mmyjrzxvT8kbPGeWDLKelnnv1JK/PvX/ktwIxA5uj7a0H66mL+KFp/malP1t9xGmQe2XneXHh25zdIZ4u7wqpHdp0VtmVk/ezObzj9MAefMpttzNXccexNaDJkL+5CsqG1azVbdR0EImiY5W0Jj2q3E4na22AcXw9i6ov1yzoto9p1VqH4Kr4kjcbbJDeObKvumq4aOprovyEXVi+1NDvb0d1G84nnJtWWDzET7yDpWUrqHgeSpH4Wokwrx9/n8GqmwJw1ZvA7jn3oJeveXUy0J8evcb9WWWer6cFbYkxf9zV1RdadNlnpE9f+oHU7oce3rFX/Rm920Ipecsp87FiF8H1g71pfWU+vpZ/otEmAzcp1F3bvtgm5u9PXJutJSX3AHwHRxkgOrjHXPHFXn7aM02Kt15T1su53HjVHQxqzzYKdnTJ3dYLMlGs4fae2POAl615/lFDOO//G9PyRW5T+wOXMl/1J07x/3Vn7/uoI8KbQ/UrZ+1ji/q11yPo7T636xs6z5mPbvM/uekQWeq/KutoEf/CpVY/sPL948Gnbns3V7DEPPm0/dpJ55ynyVYGsIG7IZiuv4xWtUN/F48Y/9g7J14OY+mK9Peumrwcx9cW6Zd29WJCWS81yLFWxWmVdV1k/qco6GTag5ZMqu+5vApaPSrbqzkgpQtfSviJosXSsAsk67UHXTcRT1tkpKGeNHVxfWb/j2Idkc+4gX6zQfOxtuctVG9gGY4bZp+7Rqq6V9cXyolMmtARC+nB1/66tVBMVAxARldFex1vW5eX0013NiiTA7t2aTiLhZZ+6XQdJSZT1IEdAysHRvronviiO4z1lr8q653n0OkrS7toolMPIz12doLKkptOnr6yf2vKA55Hkf3rlN6b3j5y4R/JYkyr7/nWPg64Nhozg/6Zw0pMmmF6beKB2WT/4tHTR6SM7z9vVa0eLy7W3wUgjSKs5T+1kXK2XVhA35LNdYisOAlGbQy8qt4IxCbKh88UgyFeC+mVdq4NmDdiuRtfRsx6VrPuGkxUn68/nLzpOXM/gYcu6V9eNpn2cn4Jy1tjBhYVuMl+fDHCrGfHCAG8db6SsO90vUv86G/o3kVNC4z5xT22935E2D8nz7S3hS3r69V09DSDr+rp4IFmvJyVF1gN11wSU9WATXxTH8Z5yQFn3uM2I9lWzJtpeys7Junbu6gTJkppOn7Cy8Fcgv9uzsOddeWP6yLrY1uIofnSy7v+m0P5gn9pSn6xrW0fMirUp3I2XdW6/fLaBZL0V6rt43NzH3rFu3fqApk4joKOb4XS/SP3rulhCG4zrjl+ftCT7OVmmtS4rlmPFPgrSKUHau5U2GNsR3XX8N+Q80nVNx3E5WSe2qh/cPSyuxXJfQkwlvePYh5o2GN9Z8Mdf3FAolotdN8JBU84aNzhNwBmHaaFhg9xJJuw2GCrrNa0v3fvF+1Ywsqyf2nq/0FcaSC9IV7RaBqPVO/cv8rTHXRxHqE06VUzh7+OM3LMf7ezercLhqS0P+LfB1JOS2gbjfQTSW7aMB22DCTpxaRzPKZM7PNZ2Hvm+iPSWLeOLp7ZuEa5hqO1zoanBN/moc5cnyEy53tPnrBmom8jr2wU5oZ4/cnJDvOe3dP37197WT9b1bwrucDE/2PW1wbime/Cppw8ulhfP7tppLdFUuN3gl5ttMGd3fkNog7GbZEhTu74NhmxIxueyRWUd0bwILuvSvV98bwWzuJQLTLlLFd2bsgsmrbn4Un+fdadV4+Jk0dFBMtTEc4XbfZPMfbv9NmQkjLSFsPdZd9pgzNqzNHg9sv71ydvU0c3VaJLcLJSvHOrxlzyYdrNYp4OdAnPW2JNLFtKrBQS8b5Hpt86SZH0pph7E16X3CPkDuq75W26Svn/tY3xFdlFzrRu9e/QWpVDn7j5tj6O/UE/Oys7f1R1h76TF1r2rtLCJGrWlpFxgyh4Bd6F4eWLwC0y508HKuu+UnTNe23mk93FXpuPeddunMNxqwd22nDuD6gS5Kdfwc6seQ7VdhPvao367YN+YXj9yW5T6vV3R16Tq8f4NJOv+l8AqF5gKs67rAtOzu5y2c+LBchu6dckpd4Ep4Rs7z5YPPrVKcfTzOx9Z9dRTThML7UEPcoGpd7aQdUTTIlFL90tkt25sqQj7ruQIhF80/fcAAoFABI+W/Q+m8GlEPCOgrNcXkHUEIkg0/fcAAoFABI1gbTBNCcg6AlFzQNYRiCDR9Ldqy4R8mV1bNVsjOiE6/UfU7DWCrCMQ8Yn2lHUEotHR9LcqAoFABI+WlXUEAlFzQNYRiCDR9LcqAoFABA/IOgIRn4CsIxAIBAIRt/D9pEcgEO0SkHUEAoFAIOIWvp/0CASiXYJ9C588dXH9+vXr1683DAMP8AAP8AAP8AAP2usBZB2BiE/oZN0AAAAAQHsCWUcg4hM6WV+3bl2zf9UAAAAAoB5aTtZPnrqIQCDqDsg6AAAAECdaUdZvAwBqx0PWm/17BgAAAAB1AlkHICagsg4AAADED8g6ADEBsg4AAADED8g6ADEBbTAAAABA/KhB1lfaQNYBiIKRkZHt27c//fTTL7744tDQ0B/+8IeaNkdlHQAAAIgfNct61OLecFkfeyX57KG5xu4TAIXXXnstKfL888/X5OuQdQAAACB+LEnW1aL70g2ek/WxV2x9eWUsRDtyBoesgyYzMjKSTCbXrVt36tSp69evnzt37sknn0wmk2+//XbwQdAGAwAAAMSPcGQ9ysr62Cuuo88dejZ0XYesg+azffv2ZDJ56tQpZ8nly5eTyeSzzz4bfBBU1gEAAID40fKV9blDz0br0pB10Hw2bNiQTCZv3LhBF5p/TQo+CGQdAAAAiB+t37NOK+vychPXtecOPSs3zMwdejb5ytjYK+560oZjrySfPXToFWkzABrJtm3bksnkxMSEs+Tq1avJZHLTpk3SmgcPHqR97QcPHnReQhsMAAAAED/qlPU6Yu/efVQy9u7dF0zWHbumHk3L4aaO3759e+7QK/Yy1/BNf3e2HXslKRXSx15J0nVRZQdNYM+ePclkcsOGDdPT07dv37569epPfvKTZDKZTqfVld966y3zTfTWW2/R5aisAwAAAPGjcbK+uFjes+cNUzL27HkjcGXdwiqam1btFsfl4rpSW3dU/ra1oWzjkvdD1kGjGRgYSHL85Cc/+fDDD9lN3nrrLcnUb0PWAQAAgDjS6DaYPXve8DB1D1m/ffu2WzBn+8znDj3rWLur6JB10NJQU9+2bdvmzZvN7pd0Oq0zdR1ogwEAAADiRztcYMq4ttDIPvbKK2O3BeueO/QsX1kXNhw75PSsQ9ZBM6AN6LT7vD5QWQcAAADiR+vfupF2thDt1lxLanXFvPIKX1kX1nJaaiDroAmEa+q3IesAAABAHGn5yjoAMUV3nWjdoA0GAAAAiB+tf+tGAGILe51o3aCyDgAAAMSPmmU9ou4XyDoASwSyDgAAAMSPGmS9MQFZB6A+0AbTAsymVn/s4VcvhD9wYWjTyuVPD4Y/cINx57GkQxXe4YjLgQUAxBjIOgAxIZrK+lh3V0IlmQ4+QjrJb5BOJhKJRKKre0xcRBe0OLOp1dYBsXWvYbLu7joRzQ5rozC0aWVCOhbaFZsn6zRN68A1WtYDH6kaRyNjuT8brfCjAQBYOpB1AGJCi8q6OYBe1qmdt5Wsz6ZWO4ZUGNr8w1cvGA2S9dnUaipns6lHa99lPY6q2aYwtGkl0cLC0KbP6wdegqyHcGxrnXXIp7OmIxUA90ewMLRppTUw+XGgP6IAgDamFWUdgUDUHex7KoRfFaZziyJNRN6RcbKsq3vMEXK5hm4QWXdfobJON7VGd3KgRXl7PffrgJpWFF8CCkObulSPa4Csh2Ngock60cTaxug4Wa/xSPkjZMemGtmPIwCgobScrCMQiLpDJ+shXGCqyLpcchfMObCsd3WnycBEqqXhk2lml4lEV1eXzzpuWmFX7Flpnk2t/tjD29+0ehOEIqrVrmAvm02t/tjD3ZtX20u43gWxa8Pcm5d/cb0xXEZkvYT7DYBuWBjatNKe3WxqdcJKVdjGSVGnv1zHBy/rbOMGXehMwFpF2G3QabPZ2ouUGX8++aiwS16NC0ObVi7/YfemlbojqezI+8TR46ROST5H5OsiNzwq6wDEBMg6AhGfaKCsC8/ttnSu5cW7Daare4wMxUq1O4Al4lTKieSTVaS0osKyJ6WV3OlHcJsUrC4ZqUBO1czxLmcVsc/GVkmtrAtm5j7hMxLcjt27vSPyIueDWgUV6sjuE0bWtZOX5klnrvlDg9+0xW8/y58eFCagzlj6QqGR9QRNizmSPkfKmE0lpUse1HWZkcWfBGUT+u0DANDeQNYRiPhEA9tghJp5wvZmWtcWele8ZN0dvFvTBqM1cWtcdx98WlFi+Z/oe+ZL8hOhLiqrp5C0UskVLJaVdWk5v777hLgdu3c3ZbHQH1TWmQtiJQ2lS3wmr85Qdzh8pu1RWScniT+DAUbUHkmvIyVv6XyF8PgbSyLxsYdfHdNX1qXmeABAmyPL+n8a/U8IBKJNo4GVderK7Kr22kFkXW51F4ricmU9gKxHWE3ncdyNNTpaRGfXZD1OVzjV2PrSZJ21yCCy7nXVaXBZ95m8uqx1ZV1fyw5wfa60ipmO3aTj/T3JTQ/NLwDEDsg6AhGfaGLPOhFz3TK+Z31MHk+u0JsElHU2hUh61mdTqxlT4oyONIQQMRPWFHpGrK4IoY2B+r5cNrVu/6HvB/GRdXbvzrpke8020s1prHuc1NQGo+6ezmb2zW7915uapu0t6+qM5V2qp1EcUXcevY4UmYDzemGoe7vaGMMdJOV01nPlMACgxYGsIxDxiQbfDYb2nKiy7pS37dW8ZV1qQ3eGSnbXUlln04rolpDc9ZO8IzotMB97uHszp/UGd42hsOyH3UzNVVqfS0jbmGOvLF8W6T6nZiq2fC9/elC8tQndM9f5k+Atm7l2UhRf5eDaY8nfGwJO20PW+RmTXfKnURlRmYrvkSITdc8y2Zd6OJmfEOZQKisDANoVyDoCEZ+IsLIOAAAAgGYAWUcg4hOQdQAAACBmQNYRiPhEhG0wAAAAAGgGsqw3Ox8AQP2gsg4AAADEDMg6APEBsg4AAADEDMg6APEBbTAAAABAzICsAxAfUFkHAAAAYgZkHYD4AFkHAAAAYgZkHYD4gDYYAAAAIGZA1gGID6isAwAAADEDsg5AfICsAwAAADEDsg5AfEAbDAAAABAzIOsAxAdU1gEAAICYAVkHID5A1uNByTBKzc4BAABAiwBZByA+oA2mjcjfyI/nxoenh499cOzE9IlzV89dL103X5q+eTN782Zz0wMAANAixEHWH3300UcffbTZWSyVeMwCNBdU1tuF07OnNw9tfmjPQ3ftuGvZtmV/tfOv/v7f/n7be9sm85PNTs0wDMMY2nTnfRuPXmt2GgAAAFpV1hd3bx38u/ScYZSOv/buR1++7L12PDS33lks7Np89B8Ozgde/8aRXcc++fq0YRgfpE/8n7+YuFT7LmtMzN0jiJoIZH2suyuhkkwHHyGd9NhAGL6re2xpo7UJI9mR1XtXL39p+bJty2is2L7inw7907mr59itJl//2sfdY/UPr12JMkXIOgAAtAy1yfr1zOkVjw98xArTp5fM4vTGDQOikYcs65GkHTb+sj5/ed2TziwGbP1tEVlf2LV5QBzNQ9ZvHNl17CPuGRn4yOMDH/l/xk6Ek0lHE0EbzJJl3RyA24Ad2mdk/Wjtwuz12TVvrZE0/bFfPfar3/zqySNP3rXjrqd+/dRCcUHdcPL1r33cVvTJ17/28UhlGrIOAAAtQ+2y/sNTv3Yef+/Ey0v+m+31zOn7Nh0Xh4pA1sNOO3SCyfqxn4w6j00Vrl/WPcgfP/WXNdnz9Puf+8Hx+5z0DCNQZZ3OKDA159ZJRNgGY1qyWPsmtu3oM1nW1T2WThIP5zdWtkympb05T9jR3IXqEnd0eYyu7jF3Rdf9lcHC/3Lw2unX/mrnX1FTv+eX9wxOD374Hx9+seeLy7Yt+9vdf9v/m351QyrrhjG06c4oi+uQdQAAaBnql3VjcXrjhqP/fHyJCZSOv3b879JZ286toaOT9ZDSDp/aZN0wPkif+OTr0y0i6x+kT3zy9UviyJD1JtBIWZfr4oL+BpB18yVBg919BJR1MQc1A1fF1Sp+V1eXtI68qfutITRZX1xc/Pb+b9/x0h1U1n/wzg/ylfz+C/uXb1u+bNuyu3fcvXVoa7FYlLYVZJ08cdtjHL0e2nSnNQdzHc9VXCl3l4nLAQAANJP6ZX3uVyMfsR4vUtWe+9XI//Ev5ybsldO/GjH7HHjnzp//+++deHmSjmZEKuvhpK1n//79SYX9+/f7blijrDsGTGV9Yddm2iSzsGvzgGvJ1uZcG4zbYHP0Hw7Of5A+oTTbGM74jHbbieWPn/rLH7y35wNn5dplffr9zz3uZqJOSslNmrJA3eeifYnwbjCyrAvP7UZyTm01ustV6l2B52VdHs0ycDq28BWAvE5XtR6bA7ob0E3HuruCtdDXyM2bNx/+t4eXbVt25/Y779l5z53b71z58sqDlw5Wflv5Qs8XHH3fPLRZ3ZbK+tCmOx0PX/f/mlLtvC5XxcWSvLWky17DflXorBnadCdkHQAAWoT6e9aJxeqt115N13zirGzkz//9407BO8Ke9VDS9kZyxIB2WJusT7//ucfNx66sf5DOuK/+4L09HwhFaFvNVVlnZFpTveZl3V3Zbc4x6pH1+cvrNtmub7+kNtZzk9JS37loXxpYWVcr2HKpWzBmjazXVlmXR0snZd+XstQMqGi5+/1AKa2Hy82bN1fvXb1s27J/2PsPb5x744l3nnjinSeulK68ce6Ne355j2nqy19a/ty7z6nbCheYCvItV8nN5+4q5paufIuXqpqbjYlGjzYYAABoGeqsrF/PnF7BuLVhKCVqz+aTxd1bHXuWHkdSWQ8pbX/efPNN0w7ffPPNgJvUeIGp47hCG0z++Km/FFZwXmXU2TFdcytqvbW0mtw4suuYvS19XLOsk+RJcd2stZNkhNyUV1XqOBftS8NlndVZR3u7usf0jSS6nnW54G0/1sl6LZV1f1mPoJousb5//YrtKx547YFsMXvh2oVj2WNzlblvpL/h3Bzmvl33/evov6obqgVyw/Jya6ko2LKhE4XnRpqErAMAQItSdxtM6fhr71pF8XqtV7xJy8BHHh/4iFXGjq4NJoS0A/Lmm2/WZIe19qzb2E48f3ndkwOkrcVa0zLy6fc/Zxmt9m4wZoeJ+VINsu42rkhfJOqSdc1O6dcJdTX1y4ZEreeifWlgG4xciSZirlsmi7DX3WCYHnMi6/bzID3rdDsvWVc2JS0zYZbY3558+693/fWd2+/8+Ymf//4Pv//dH3635/09//lf/7PTA/PlN798cuakuqFOsS2pnnz9ax833XxoR7fQGDP5eneP0z1z38aj1+SWl6TVPOOovTsWAACAprPEC0xdpbYMeHF644aBYNZbOv7au6RPnQ4Y9QWmtaftbGW364R+V5mlyrrbGGNqN7lvzKYT3/6Fo8tcG8wb70tdJcHbYD5In/iI26dO16mrDYZ20fyvsROG8cGBcXNwJyWhDUZ5tcNp8N1gqN2qsu4Yrr0aV7UWBFlwYnertLBraTTx7jPymExDjKGVdS7/8GX9eun6hl9vWLZt2Wd3f7b3fG/6Qvrr+77uXHJ63677dmR23CjfUDdkK+tuC8x9G7vXWdVwt83FrbnbK6kXkwoXrSpjAQAAaDZLkHXzYk1TWPPn/94ujW/dHaxE7Uqzi331Z5SyXl/arS/r5Obln/zluHQpKvFprrLuVMd/QFvGg1xgyui7fZnpEi8wpTep5Jd88vVp5tXOBv/BtC2YvT774yM//tSOT616ZdV/eeW/mP/EdNm2ZZ/a8annTzyfv5FvdoIAAABaiNb8D6a10dn/wdQX/APRDiLCNhgQKtfL1w9NHvrGvm/cs/OeZduWrdy1MnkgmclmihX5jo0AAAA6nDjIOvCCtMeA2IPKettx06bZiQAAAGhRIOsxxmyMqelfJoH2BrIOAAAAxAzIOgDxAW0wAAAAQMyArAMQH1BZBwAAAGIGZB2A+ABZBwAAAGIGZB2A+IA2GAAAACBmQNYBiA+orAMAAAAxA7IOQHyArAMAAAAxA7IOQHxAGwwAAAAQMyDrAMQHVNYBAACAmAFZByA+QNYBAACAmAFZByA+oA0GAAAAiBmQdQDiAyrrAAAAQMyArAMQHyDrAAAAQMyArAMQH9AGAwAAAMQMyDoA8SHWlfWx7q5EIpFMN3pbAAAAoJnUI+vvv/9+1Gk1AHx6gzblmZ9t073UArKeTiZcrPdXOhnGey0qWecy9h2rq3usnjyMsA4GAACAjqFmWX/iiSd+9rOf6V8XPvgSiaV8qNWA8lGcTvrtWtiEfH4qE6h1En4f5QuDT/31Xc8cMwwj++pXrfH/fE1q0npJ3PGfr0mdePWr1ssAGM/8bJsZ7KvNboOR3z3meyqkL8ZRyDr3dvd7t/v/cqknEwAAAICnNll/4oknEolEbbLeEGGvQ9Z1my95At67Xhh8qstU7+yr37QdPPvqVxOmv4trWlLvbgM6G8fUdb7e5Mq6+eZxfvjTyWRafEN1dY+JbzH7PWsuS6bt19w3kLskrXmbSmN0u9+W+W3lfNWdkTTp1/lEMm3+qiB7NhfYO3AHY7dmDgYAAADgQw2y/sQTT/zpn/5pMFl3PhTtDyd7Afms03wKJtPuWuTTjPtwdvGSdY0GOJtoPj+liUhJqC7Bf5TLZF/9qmLl5mK5ei6sqdkMdBKSqbO+3hKyLlqo8v4S3yTa78jJtGHI6+qWq2N0dY/ptnWxRZs6s/u+r0XWBfSqD1kHAABQO0Fl/dvf/vaf/dmfmZ8xtci687FKHZz5UKNLu7qkVXSf5Ia0Ey9ZVzauWda5v/DLH91+sq6pkauVdWlF1NY7HdbUVV9vdhuM8AZwfv51nR9kOa3Juw5NfnkY4hP9GPYKAbblvpC7O+d12xB+ucgju9PQbo02GAAAALURSNapqSdqlXV3iVDHcrrE6ac0/bQlawtjsh+7/rIua4CwCff5KU9E+bx1PpGlAplXGwxXIV8YfOqv5SYYZT2U1kEQWuACU0HY2feX9LWXiDZ1W8V4VWH2GsPzmZBITZV1IT13buozyIOYhY4AACAASURBVDoAAICQ8Jd1ydRrlnX544sif6ipOu+W15yPVO5v1/Iy+pzXgFplXfM3dTIne+8esq4UyBcGn/rrhHL5qNutrt8SAIaIZP348eMHDhw4RODXSyfZb7e6i7mVqjgv60Ljmvu28x5Du62Yr/DW1ZYLxO31lXXlz4jM1oFk/erVq4cAAACAQ4cOHTrkI+v/8i//kkgk/uRP/uTPbP74j/+4jp51tUDObsDLeuDKOv8BGqas8w7uGLurDEEq6+xlpQbbwI7KOghEFG0wBw8evHz58u9+97vfEvhVNfeCcr/pkgsxhS+9uncpc7k32yfOyLpmW7+ME9LXbmZ7dznfs+7ZhS8cDG3P+s2bN38LAAAA/Pa3v/3tb31k/Tcc+Xxe/8nu9eEnfa6phW+NrOscgGqx/pM5sKyLn59+Peu0S1azTFUD4uFM+dyEK6JrVwaAEkVl/dVXX/3d734XaFXxHc5cHy5cYGret8VT1smQ9iXi4gWm2jH023omLQi0bnuy3Pmd1Z2UB9DuPa2sCgAAAOgJ/T+YytLMNXQLLwWRdXFDcRl7XxZds7lG1rnPT+bTXb16Tp2OIX6Uy7gVcvcm6xbWctbLUVgHgYhC1lOp1G91pXTg9Sc3AAAAIARCl3XgTT3N52hYBwGJog0Gsu4FZB0AAEDEQNYbTq0tLVwLO+g0Ppia0wVdDZX1RgNZBwAAEDGQdQDaAMg6AAAA0JlA1gFoA5Yo60vZNWQdAAAAaCKQdQDaAFTWAQAAgM4Esg5AGwBZBwAAADoTyDoAbQDaYAAAAIDOBLIOQBuAyjoAAADQmUQi65Vq5UrhyvGp4wcuHNh/fv+vLvzq6OWjl+YvlSolc4XzN2+GsiMAOgTIOgAAANCZhC/rxUpxeHr4Z0d/9oU3vnD3zruXbVv2qe2f+mzqs08efvKd37wzX5xf+i4A6DTQBtMw0knyT5Trv4H6WHcX9z+Ml5QQAACATiRkWS9XywOXBta8tWb5S8uXbVtGY/lLy7/wxhfePPvmQnEh2GCTOx765Hd6P1hiSgy5t9fdtWrLyfAHbjDuPJZ0qMI7HHE5sC1IW1XWzX8UZNMioplOBsyoubLOHLtYyLpz+MlU3FPiLozFZAEAIFxClvVL85dWv7Va0vTPpD7z9ODTPx748YOvPfiFN74weHnQ6YchTO54yPrFbetew2Td3XUimh3WRu7tdXclpGOhXbF5sk7TtA5co2U98JGqcTRprMkdD3n+YCy88U0riT/54i/PLTELDW0n6+EUlUPaRTqZSJDV00kvH1yCrIdgmrUeu7aQ27HuLnJMrfmRs+AubI/5AABAYwlT1ivVyvbMdqmmfuf2OzcMbMhX8nsn9n769U8vf2n5xoGNM4UZcdPJHQ85hpR7+5kf935gNEjWJ3c8ROVscsea2ndZj6Nqtsm9ve4uIoa5t9d9RT/wEmQ9hGNb66xDPp01HakAuD+CubfX3WUNbPr7qmTSI/WFN75jK/rCG99MfOJH/UvIQktbtcG0mKwTFQy4OmQ9VIQ5sRMUjnnEPzoAANB2hCnr89fmv9TzJams/rn//bmDFw/OFGd+2P/DFdtXLNu27LO7P/veB+8JW+beXtelylADZJ1+SQhjvCVuQzSxtjE6TtZrPFL+CNnJqQZOfeGNb0ZUXG/zyvpYdxetnVpmRlo+3NWlhYKMWk9IR4u1ITuSuJE2U3lDXta5lg1hYZoM1dU9Jh4ErgcnnaRb2YsZl7XTcA+cdTy7pV1yx8oa0Vw1mfY5VvyxdLO3N3DXoXl7nAGyjDkfYmUdsg4AACJhynrhRuGuHXdJZfUfHfnRgrGw78K+B19/0Fn47uV3xU1ZaZ7c8dAnv/NyyupNEIqodyWEZZM7Hvrkd7qfeche4va1cFu5nQ5eEsb1xnAZkfUS7jcAumHu7XV32bMzOyq6n5G3cVLU6S/X8cHLOjd5YaEzAWsVYbdBp81may9SZvyV5Bphl7wa595ed9eqH3evu0t3JJUdeZ84epzUKcnniHxdZPqkAsk6W1lfeOObf/LF/9X77KpEwuyTcbpm7FVvnDBf9GqjaTtZdxH7G8a6u5gaqi1wVOrFV6QnsgorI2lGkNN0XnGfMLLuJk32TNyZ25WboVDZp20giQTZk/q1wz526qzJhKUvFBpZF9bxOFbMCTDSSXlf6hcKz1Gl1eXXxV1C1gEAQCFMWS9VSqaLf+XNr3z/ne9/oecLZlk9W8yuP7z+jpfucCT+xPQJeWPLnpRWckuSaJOC1SUjFcipmjne5awi9tnYKqmVMOHLg/uEz0hwO3bv9o7Ii5xuahVUqCO7TxhZ105emiedueYPDX7TFr/9rNpyUpiAOmPpC4VG1hM0LeZI+hwpY3JHUrrkQV2XGVn8SahL1m+ceHYV1wSz8MY3bQs3rdxaxzb7GyeeXeXfOxOHNhizQGuLGi2P22LqUVaWntA1uZF0I3hkSQrYkqyLAp1gytjMrqjU0xX55WIdXH8IrFRo/30QWedK/Nyx0pw5uWxuPhf25XMGNLIufpFQ1wUAAGCELOvV0spdK1dsX/Gtf//WdHF6/+T+jYMbF28u/vvkvz/w2gOOqd/7y3szMxl2BMv/RN8zX5KfCHVRWT2Fzw2lkitYLCth0nJ+ffcJcTt2727KYqE/qKzr3FGV9QCTV2eoOxw+0/aorJOTxJ/BACNqj6TXkZK3dL5CePyNJZH45Hd6x5ZWWb9x4tlVurI4bY2hYu48NhXep32m7SrrQWRdkd26Zd2zbVvzem2yHqi7pi1k3etYaRqYuD9n2OdT6VVSEV7W/MWBrAtZBwAAkZAr62v71i7btuy/pf7b8Mxw5beV2fJstpj958P/TMvqX+v92vmr5/XDOGbEGh0torNrsh6nK5xqLGxpss5aZBBZ97rqNLis+0xeXda6sq5viQ9wfa60ipmO3aTj/T2ptp51n8tKfWXdHSWhH6f9Zd3tN1daPwxjrDvpiKXbBd2dFpZovZEbSc5HbDV3HDxwGwxVYtU1093SpsHaYGqVdetF3TcV/liJI/ocK+UEiO3k5mPzzNC9BxhVvttLA65CBgCAmBCmrFer1SMXj9yx/Y67dty1/vD63//h9//x//3HwUsHV72yyjH1O166Y9fJXfKt1id3PMSYEmd08p06mDWFnhGrK4I2UQu+L91TxL4bjL4fxEfW2b0765LtNdtIN6ex7nFSUxuMuns6m8lUt/7rTU3T9pZ1dcbyLtXTKI6oO49eR4pMwHk993b3y2pjDHeQeMuXD4CEbxeLn6zfONH9v/qVNWXarg1G7IlQro2U+rO5izaVfpmu7u4kMcku0nDBjiSgXpQqLWXq0/wFpty1sFJHjnyBKXcda82yzl+kS3fJHyt5RL9jJZ0AMslu4fuHOITPqNpDJZ0V4WsRAAAAwzBCv896oVR4ZvCZZduW3f/q/Zvf3fxi5sVH0o8s3+bezPEfD/zjhfwFdUPu+kneEZ0WmE9+p/sZTusN7hpDYdmPu5maq7Q+l5C2McdeWb4s0n1OzVRs+V615aR4axO6Z67zJ8FbNnPtpCi+ysG1x5K/NwSctoes8zMmu+RPozKiMhXfI0Um6p5lsi/1cDI/IZ5/h5Bxb7JuIZu7f2XdGcKjFaatKusAAAAACI2QZd0wjLkbc88MPrNi+4o7XrrjjpfucG67fsdLdyQPJN+/+n7VqC59LwB0FJB1AAAAoDMJX9YNwyhWioOXBx//1eOr/nXVp3Z8auWuld/Y94297++dL86HMj4AnUZbtcG0Dbf/6I8QEUWzzy0AAMSHSGTd4SYh3JEB6ChQWZdouowiGhDN/ikDAICWIFpZBwCEQifIOnQwNuBUAgBAiEDWAWgD2r0NpuXlzO9m7WDp1HiMW/5nBgAAGkQ4sn7y1EUEAhFiSG+xtqisR+VSod+SW7xtIPeviyJFvLVlM78jsPeUjIylHWN660oVeDwAIMZA1hGIVgzpLdZqsh6qDPnJeBSyXos1hr3/Rvw/IP8pSv8qaqy7K7Scwv7mk04mEomuZHKJhw0GDwBoUyDrCEQrhvQWa4U2mMByo8ioj51C1sPHb4qR/vehaP5MEeVhg7gDAFqZ8GV99PSlM+9/cOHy9G9mL1+av3xp4dKl+csXr16+8MHU2fNTp8YunTx18Y3z2abLEALRyiG9xZpYWQ+jUk6XSP8LVP3Xoso/wzS3Vv9rJvd/RZn/pOmuRP4pqiyT9iLlf60mxfyEublPxrq7zP/wSf4Tp7a9hD8+6n8nZQeRFnL/B5U2t2hG8hRf5v+68v9u1XyUtgfv6h4zmJ0rx9jr/516fIloxHccAVg7AKBFCFnWR09fOn9h+tzMhdRYas3eNff+8t5l25bdvePuL/V86cWRF0enxyYuTp8+c7npJoRAtHhIb7GmyHq9msJYleNp6SSRdkHGnY2Tlqs5i8dcCTa3c/7pvTwWq8GO+zmvCj3rdl5yNumkPRQd1UPWha8HzjrMFwOxZ911dEu0XRFWBlH7tjUWLSxnRtKLr3t46RO9rCfoY3EuzNCasyQem1aRdQqUHQDQREKW9fMXsqezZ7538Ht3vHSH+Y9LnVj+0vJH9j3SP3lk4uK0WV/3i6MbH/yLr/7P4fBNaHD3t5bft+7fmi9kS4xf7/zu8ns39Jy6ePLA5gc/sab7nfrGGd3x6Ip71x/AgW2pkN5iTWmDcbykxrvBeFfWA5R5pVq49Lrs33Qs87nQiZ0QsMvnuso62Yhxck9ZFxRXQFJMjXWamxHbVgbx+hYkPREfBhmJGU/45qKtrPssZsaWz1IwmirrDpB1AEDjCVPWx8YvX7o69b2D35M0/W9e/pvVb63+2t6vrdy18pF9jxy/NPL+xLRiJ0c3Pmh9lNji2DBZd3edqF95w03Pzsd0cU00V9Z/vfO7y93P/7/46v8cbrisj+54dIWdwNL3645Gjob7s/GJh3ceYjcc2f/9e53j8NFP/+TXocxOeos1t7K+VFkXa+RKPV1pkpEKtNJ4tNmDq83beppM6wQveln37RcPIuvKIHXLupqOznwbIut0vsH1G7IOAOhUwpT1Sx/k3jz7plRTX/HSih+884PpG9PvXH7n83s+v/yl5VuPb33/sqQmRzc+6BjS6I7/+3vd71xskKwf2PwglbMDm/+7zsn04UpzfTlIQyXcWf9653c/q9foJch6CMe21ln3bfqM1nfrPIlEoAd3f+uzNZ4CJT3rq9Hg7m8ttw5O36av2EeJ/oiK8e62L3/0bzf9e0jzskN6i7VxG4zcj00eqqZLuiBcGRd6TJw1uLHGuruZxhjSD2L3z3jIupWNlJTaGaKbgrgOaevRHB8xAbHFRB6EzsacK3vApCny6dCvRYZ7Nxi+DUazm/pkXT1L4rFBGwwAAAiEKetXrl5d89Yaqaze9VrXm+ffXKgubBzc+Kntn1q2bdkXe7544jcZWbz+RnXNBsi63sBqidBknWhibfvtOFkf3fHoijDVXzwgbKra/N/d9uWPJ38ZWiZWSG+xJt4Npr4LTDVNIO5LyW7Rhu01yXWk3bSy3u1uqVxLSsZiLkNVr0LVy7r3lZ7StaNkt7JI6q+gZI+Pclkrf6UtO0HmgJHF8gWmQjr8xaB0qfgFRNmNR12fmbvU684enVaSdVxgCgBoEcKU9fy1+Xt+eY9QVt++4ntvfy9bzPZf7v/8ns+bC+/eeffQb4YUVVKl+ejGB//iqz97weoJcWXUbVew5enoxgf/4qtPrnvQXtK36TPWZwG3VSKRsLomvByX6405sPnBT6z56XNW+4e8L7tCL+99cPe3ltuzO7D5wYSVqr2N67te+sv1xvCyfmCzPTjRcbrQOaRWhkIbDJnOX5CiMnMimGztbyC/3vnd5XZfSt+mzyQ+8fnVX1hBhxXE10l+cPe3lt+39snvLtcdSWVH3ifO/VuN/APDnSPydZE7EdrvdcN7fnSPPbePf2ePssKZLV/56Kef2mG2ynz0M8+l3932ZWttS/HdEUiFXnqLtcJ91nF7OxBX8LMNAGhlwpT1UqVk9r18dvdn1+xb8+nXP/3g6w/2nOvJV/LPHH3mzu13OhJ/YvqE7DSWTSqt5Jaluar0653r1poSKRbIqcL+X7aTOdblNjmcIiqplXXBzNxtD2x2vg+cPLD5QTtb6nbs3u0dje54dNVX5eTd0Mq6UHF3i8qMrFPpdHZhfkMQ6ui0kOzKOj1KZIK6E0F71u9b92/CpCwdJ/lQQdfLuuvT/JH0k/W+Td90G5w+sab7HeaoMiOLPwnKJqM7Hl3hff3AyVNm87ras35my1dsCze72y1HP7PlK4mPf2fPyZH937/3z7+9Sx5Neou1gqxTgsgNXAe0FPihBQC0KWHKerFcvOeX99y5/c5v/fu33su9t/PUzifeeeJK6crhDw7/3Z6/c0z97p13j0yPsLpj+Z9lRfrOBLl4LKtngvKJNd3viF0f1GJZWZeW8+u7YxK3Y/fulnKFHuvAsi4vVzWULhF2r5SxvWRd6o3hlzujeVTW3e9aCf4MelTW7c21R9Jb1sVvEc5XCI+/sSQSn1jT/Za+si41x3vG0NaHP/qZ59KyrDsGf373D+6zq+/O4/O7f3CfemWq9BZrhX+K5EsdMgQ3AqGAnz0AQIwJU9bnrxXWvLVm+UvLH3rjoffn389X86fnTs9V5n469FNaVv9izxdPTp3WG4+jhqwj0iI6uyZ7bxONrOtat5cm62yzRBBZ97rqNLisK7rfvrKuv5xA8yoVa+lgml/w7t3Qw24rruymR/5+EiTqknVntUQi4ZbYpbdYq1XWa2XpLgW76jTwMwMAACaR3A3m3l/e++y7z/7+D7///R9+Pzg9+Le7/5bebX3r8a3vX/6NLMeu9nnKOmkIITdOEdb89c7vLicN3KvXH5DaGPo2fSZBO1jE3u7/bn8l4NtgfGSd3buzIcmT2qFw+5HP0F4g624wNbXBuGse3bjG6d5x7n7zwo/0X2/0bTA1y7q1GjliVNDJURrd8eiKBCPr2vNINJo0kZt3gyEzdY7kr3du+qnaGKOcIzc9N41AN7Ucfutty87f3fZl5taNfrI+sv9HT+1R1oybrAchCjmDvTUFnEoAAAiRSO6zvvyl5Z/73597ffz13one77/z/RXbVziybt9nfUoyHtq/wd5n3XEp59LATzy86R85rT9JLx8UvgPYyx7bxNRcpfXZm51rZN1ZWb4s0u10p18wXBG01hFvAkMPBdf5I3R1e15gKoqvOBcrSfkCU/bO5TXLet+mzySoi5OOf9K5ZDfqPLmOq6yz51G8CQw9R3R38lkm+yKz0P+E0CtrhX4Ztm2dXGDK3mTdv7I+tPVha3tSlZfeYm3RBtNImqKDiAZHs3/KAACgJYjqP5jeteOu//rKf+16reveX95b738wRSA6N6S3WCdU1htP02U0xtHscwsAAPEhZFkfPX3p/IXpczMXUmOpNXvXmKZ+9467v9TzpRdHXhydHpu4OH36zOWmmxAC0eIhvcUg6wAAAEBnErKsnzx1cfT0pTPvf3Dh8vRvZi9fmr98aeHSpfnLF69evvDB1NlzU6ipIxBBQnqLoQ0GAAAA6EzCl3UEArH0kN5iqKwDAAAAnQlkHYFoxZDeYpB1AAAAoDOBrCMQrRjSWwxtMAAAAEBnEo6sAwAiBZV1AAAAoDOBrAPQBkDWAQAAgM4Esg5AG4A2GAAAAKAziVDWr5erZ+bKR7Olk7nSXLEa4sgAdBqorAMAAACdSVSyvliujs2VB7PFozOlwWwRvg7AUoCsAwAAAJ1JJLK+WKmemSsPZotn85Vbt25NXa+avp4vVjXCXpgY6N03PBXK3muhMDHQm0qlUqmUu3d3WUpJibzGvh5xaoZhGEYu05fq6R/PR7Zn0IKgDQYAAADoTMKX9cWyZeqSrA9mi6OmrzPC3hxZz2X6LBMuTAz0mgJcmBg4YCXiLtTkWZgY6I1I2LnULH/fd/hwH2S900BlHQAAAOhMwpT1arXq1NRZWXd8vSILe1NkPZch0is80WalLIkocc/UuFRBzIGsAwAAAJ1JmLJeLJWoqbOybvr6wo2SuCnrvLlMn9Vu4ripu8gtO0ur0E4Ve8hcpq+nf/S09YJbp067zstk4FtZl5eoCQs77ukfzzurkFHczYKlBlnvQNAGAwAAAHQmoVbWDYNKuU7WB7PFefliU1aC09S/9w1PKZbKq7Og7eaTXKbPEWGnwUQcTRmLbQ1nlN4ehkuY7tjqYTE3drtc3EfkiXdqkPUOpImV9d27d0PWAQAAgGYRsqyfmC35yvrxK6VrJT9Zl67ktIzXrEHL14K65qrTWrarxKN8ncv08VeP6ivr2oR7FIM3RJun4m0tR2UdSDRR1nt6eorF4pJnAAAAAIB6CFnWs4vVEeLrJ3PlmUXjbL7iLBm+Urp0rSK7ek294LKhE4WvVdbJys4qTPNLkDz5hOuXdS41zXPQATSxDcYwjP7+/uPHj58AjWJsbKzZKQAAAGgVQr4bTLVqzBBfPzFbOr9QOZkrU1MvVtTtfBpacpnDw1OGkTs9Yi5wnHZklDSlWwLOt8Fw12u6j9z9sybs9Kp43A2GS9hf1vk2GD41kg1kvdNoYmUdAAAAAE0k/Fs3VqrGzGL1vdnSYLZ4Jl8pVW9dvFb1NHVDc/9y+WpS5t7jziqCi0uXa3rcXEXZXt9+48i6/j7rasL+ss5fEctPzX0Fst5pQNYBAACAziSSf4rk+LpTWfc0dQCAD81tgwEAAABAs4hE1g2xvg5TB2CJoLIOAAAAdCZRybphGOWqkS9WryxW54pVmDoASwGyDgAAAHQmEco6ACAs0AYDAAAAdCaQdQDaAFTWAQAAgM4Esg5AGwBZBwAAADoTyDoAbQDaYAAAAIDOBLIOQBuAyjoAAADQmUDWAWgDIOsAAABAZxKhrN+oVCcXKqO50rn5ykKpGuLIAHQaaIMBAAAAOpOoZL1YMc7PV47NlAazxaGZ0pm5MnwdgLpBZR0AAADoTCKRddPUh2ZKZ/KVYvXmxWvVo9nSmbnyNa2vFyYGevcNT4Wy91ooTAz0plKpVCrl7t1dllJSIq+xr0ecmpHL9Fm77ukfz0e2b9ByQNYBAACAziR8WS9VjfPzlaPZ0mC2eDZfuXXr1tT16mC2OJgtnpkrF3hfb46s5zJ9lgkXJgZ6Tf0tTAwcsBJxF2ryLEwM9EYk7FxqRi5zyE7HfR10BGiDAQAAADqTkGW9UjXOz1dMNVdlfTBbHJsrXy+rvt4UWc9l+lwXF55os1KWRJS4b2r8QhBbUFkHAAAAOpMwZb1YLJ4jps7KuunrCzdK4qas8zI9H+4it+wsrUI7Vewhc5m+nv7R09YL1qqFiYG0q7tMBr6VdXmJmrCw457+8byzCtvbEjg1VNY7Dcg6AAAA0JmEKetVw6BSrpP1wWxxvigV11kJTlP/3jc8pVSTeXUWtN18ksv0OSLsaK44mjJWLtOnNoYz3mwPwyVMd2x+ibA2dl1bsG77iU9qEbbfgBYFbTAAAABAZxKyrJu3f/GW9aGZknJnGN5HKT3943mrBi1fC+p6rTyMLb1sV4lH+TqX6eOvHtVX1rUJ9ygGb4g2T78RWMs9UitMDPTi6tLOA5V1AAAAoDMJWdYvXqtQXx+bq1yv3Jy85sr6sZnS+flKsSJtWksvuGzoROFrlXWysrMK0/wSJE8+4fplnUsNzS+dC2QdAAAA6EzCv8D00rXKu7avH5spncyVh2dL1NRvVIJcYCo4cy5zeHjKMHKnR8wFjtOOjJKmdEvA+TYY7npN95G7f93VnClGyYV2FC5hf1nn22D41Jp1f0vQAqANBgAAAOhMwr91o+nrx6+UBrPFM/lKqXrr4rWqY+qLjKkbmvuXy1eTMvced1YRXFy6XNPj5irK9vr2G0fW9fdZVxP2l3X+ilh2amRm7O5BjEFlHQAAAOhMIvmnSCXb10/mytOL1fF8xTJ15qaNAAB/IOsAAABAZxKJrBu2rw9fKQ1mi+/OlM7PV7jbqwMAAoE2GAAAAKAziUrWDcMoVozs9cqFhcoHBZg6AEsClXUAAACgM4lQ1gEAYQFZBwAAADoTyDoAbQDaYAAAAIDOBLIOQBuAyjoAAADQmUDWAWgDIOsAAABAZwJZB6ANQBsMAAAA0JlA1gFoA1BZBwAAADoT3LoRgDYAsg4AAAB0JvinSAC0AWiDAQAAADqTSGTdNPXjV0qjV8u5onFuvnJspnR+vrIIXwegLlBZBwAAADqT8GW9Ypv6YLZ4Nl+5devW1PXqYLZo+XqF9fXCxEDvvuGppe+9RgoTA72pVCqVSrl7d5ellJTIa+zrEadmGLlMH7PryA6fs7ue/vG8tFxaxFKYGOiN9CgxcDk7ywJk3Yyc/YGsAwAAAJ1JyLJumvq7M6XBbFGSdcfXbzC+3hxZz2X6LCsrTAz0mhpXmBg4YCXiLtTkGaHWcamR3NyXzcXpAOJcM2TPYjqp1L7Dh/t8tDeX6Uuleg4cPtTQE8vmnMscsnMVDpxCc3IOBNpgAAAAgM4kTFkvlkoXr1WO2aauyrrj69eLJXHTpsh6LkOEU3iizUpZElHivqmRZblMXySHTpiaPE8uJ99BosczZ8MwAiXerD/zeILKOgAAANCZhCnrlWqVmjor64PZ4tBMab4oFdd1XiX3LriLaJ1XWIV2qthD5jJ9Pf2jp60X3Do1KUgzGfhW1uUlasLCjnv6x/NcG4u7WeDUiHLSdXXz5ATWfHTW2ve+4SnnwLmVaTFJeiyEp8yB8jyxAo3L2T7W+4anlphzE4CsAwAAAJ1JmLJeNQwq5TpZH8wWA8g6dVD7VVm+eHUWtN18YrY3SN0R4mjKWGxbtoc3cwnTHVv9I3Ibi9CXYT/RpmbLqdiOLWyvzNNDfFMkCerJPf3jeWmqUcp6g3IW2pY6Z5CtiQAAIABJREFUTNablTYAAAAAlkjIsn5uvuIr62NzZeUyU7a9JEXp6R/PWzVo+VpQ0Rq5Zg22q8SjfJ3L9PFXj+or69qEexSDN0Sbp8poLa+h6C+sqpunvko9pW5IDlpAWfcgYGU9+pwLEwO9ga6Jjaeso7IOAAAAtCnhX2B6XvT1o9mSZOrcDddr6QWXDZ0ofK2yTlZ2VvEouXrlySdcv6xzqbEjS5X1UMXX/2uQH42XdS5n78tKa8+5CUDWAQAAgM4k/Fs3lqrG+fmK6ehn8pVS9dbFa1Zl/cxcuVAKeOtGwZlzmcPDU4aROz3i9GmbTjsySprSLcnj22C46zXdR4LXsWbMtGeId4PhEvaXdb4Nhk+twN6ohnNW8QnZBfmTga/40jWUoxJyz3qkObM51J5z5ezh1O4j5wyjOj2cTu0fmaGPIgdtMAAAAEBnEsk/RSpWjPPzlaGZ0um5ykL55oWFytFs6cxc+Rpv6obS9UK6koWrMd3VqMiJTdzq5ZoeN1dRtte33ziyruTpoCbsL+v8FbH81OiqQuGd253k+9ZWR0cCV6m5402nWoesczeuiT5n8hPhvlB7zm0t66isAwAAAG1KJLJu2L5u3hxmaKZ0Zq68oDV1sDQKEd1nPXTInwbahlbJGbIOAAAAdCZRybphGDcq1cmFymiudG6+AlOPlJbsslZoFe+thZbJGW0wAAAAQGcSoawDAMIClXUAAACgM4GsA9AGQNYBAACAzgSyDkAbgDYYAAAAoDOBrAPQBqCyDgAAAHQmkHUA2gDIOgAAANCZQNYBaAPQBgMAAAB0JhHKerlq5IvVK4vVuWK1WAlxYAA6DlTWAQAAgM4kKlmvVI2Zxep7s6XBbHH4SunStQp8HYC6gawDAAAAnUkksu6Y+shsafJa9dRcGb4OwFJAGwwAAADQmYQv67SmfjZfuXXr1tT1ql99vVn/grMwMdCbSqVSqZS7d3dZSkmJvMa+HnFqhpHL9DG7juzwObvr6R/PS8ulRSyFiYHeSI8SA5ezs8wna69z31xQWQcAAAA6k5BlvVo1ZharI7OlwWxRknVPX2+OrOcyfZaTFSYGek2NI/9f3l2oyTNCFeVSI7m5L5uL0wHEuWbInsV0Uql9hw/3+ch6LtOXSvUcOHyooSeWzTmXOWTnKhw4ZmOPc99cIOsAAABAZxKmrJfK5SwxdVXWHV9fLEnC3hRZz2WIcApPtFkpSyJK3Dc1siyX6Yvk0AlTk+fJ5eQ7SPR45mwYRssm7gvaYAAAAIDOJExZr1SqJ4ips7I+mC0ev1Kal6vrOq+SexfcRbTOK6xCO1XsIXOZvp7+0dPWC26dmhSkmQx8K+vyEjVhYcc9/eN5ro3F3SxwakQ56bq6eXICaz46a+173/CUc+DcyrSYJD0WwlOPMrS/8zYuZ/tY7xue8i2do7IOAAAAgJYgTFmvGgaVcp2sD2aL88WquCkrwWnq3/uGpxT54tVZ0HbzidmSIXVHiKMpY7Ft2R7ezCVMd2z1j8htLEJfhv1Em5otp2I7trC9Mk8P8U2RJKgn9/SP56WpRinrDcpZaFvytPGgLfmtB2QdAAAAiBkhy/qZubKvrI/mStfLfrIuXclpaZlZg5avBRWtkWvWYLtKPMrXuUwff4WhvrKuTbhHMXhDtHlqhdbyGor+wqq6eeqr1FPqhuSgBZR1DwJW1qPPuTAx0BtIwLXnvi1AGwwAAAAQM0K+wHSxUqW+fmymlMmVjl8pUVPPF6tVydVr6gWXDZ0ofK2yTlZ2VvEsuerz5BOuX9a51NiRpcp6qOLr/zXIj8bLOpez52WlUrbtWVG3QWUdAAAAiBnh37pxsez6+um5ykL55oWFiqepG74NLbnM4eEpw8idHnH6tE2nHRklTemW5PFtMNz1mu4jwetYM2baM8S7wXAJ+8s63wbDp8bfrIRzVvEJ2QUpG/uKL11DOSoh96xHmjObA5ez9zeQytnDqd1HzhlGdXo4ndo/MkMftQqQdQAAACBmRPJPkZz6+pl8pVS9dfFadTBbPGmaOr+F1ERCupKFqzHd1ajIiU3c6uWaHjdXUbbXt984sq7k6aAm7C/r/BWx/NToqkLhndud5PvWVkdHAlepueNNp1qHrHM3rok+Z/IT4b7A5Kw99+ZAbS3rzc4LAAAAAHUSiawbhrFYro7NlQezxaPZkmnqc/JFpSAkChHdZz10yJ8G2oY2yxmVdQAAACBmRCXrhmFcL1fPzJWPZksw9ajxbzZpBdrMew3DaL+cIesAAABAzIhQ1gEADQZtMAAAAEDMgKwDEB9QWQcAAABiBmQdgPgAWQcAAABiBmQdgPiANhgAAAAgZkDWAYgPqKwDAAAAMQOyDkB8gKwDAAAAMSNCWa9WjWLFWKxUixWjgjs3AhA9aIMBAAAAYkZUsl6tGvlidTRXGswWR2ZLM4tV+DoAUYPKOgAAABAzIpF1x9TfvVIavVo+MVt6D74OQPRA1gEAAICYEb6s05r62Xzl1q1bU9erg9mi6etl3teb9S84CxMDvalUKpVKuXt3l6WUlMhr7OsRp2YYuUwfs+vIDp+zu57+8by0XFqk4HUco4TL2Vnmk3Wzcg4NtMEAAAAAMSNkWa8arqlLsu7p682R9Vymz3KywsRAr6lx5P/Luws1eRYmBnojkjouNZKb+7K5OO0jznVB9iymk0rtO3y4z1d7PY5jZLA55zKH7N0LB65Fcg4TVNYBAACAmBGmrFcqFWrqqqw7vl6qVMRNmyLruQwRTuGJNitlSUSJ+6ZGluUyfZEcOmFq8jy5nIKNFCmeORuGETzxZv2tZ4lA1gEAAICYEaasl8qVk8TUWVk3fX2hGETWmd4FdxGt8wqr0E4Ve8hcpq+nf/S09YJbpyYFaSYD38q6vERNWNhxT/94nmtjcTcLnBpRTrqubp6cwJqPzlr73jc85Rw4tzItJkmPhfDUpwzt/XLjcraP9b7hqSXm3LqgDQYAAACIGWHKetUwqJTrZH0wW5wvSq0wrASnqX/vG55S5ItXZ0HbzSe5TB/1OVPXxNGUsdi2bA9v5hKmO7b6R+Q2FqEvw36iTc2WU7EdW9hemaeH+KZIEtSTe/rH89JU65Z1v/b2xuUstC0tKefWBZV1AAAAIGaELOsBK+vXSn6yLl3JaWmZWYOWrwUVrZFr1mC7SjzK17lMH3+Fob6yrk24RzF4Q7R5aoXW8hqK/sKqunnqq9RT6obkoAWUdS3a4yiu04icCxMDvYEEPEjOrQtkHQAAAIgZIV9gKvWsn5gtnV+ojObKUs+6cg/HWnrBZUMnCl+rrJOVnVU8S676PPmE65d1LjV2ZKmyHqr4+n8N0hO0kaQROXteVlpHzq0L2mAAAACAmBHt3WBO5srTi9XxfKX2u8EI3pTLHB6eMozc6RGnT9t02pFR0pRuSR7fBsNdr+k+EryONWOmPUO8GwyXsL+s820wfGr8zUo4ZxWfkF2QsrGv+NI1lKPi2wYT+ArU6HNmv0fVnnPl7OHU7iPnDKM6PZxO7R+ZoY9aBVTWAQAAgJgR7X3Wz+Qrpeqti9cC3WdduX+5fDUpXY2KnNjErV6u6XFzFWV7ffuNI+tKng5qwv6yzl8Ry0+NrioU3rndSb5vbXV0JHCVmjvedKqesq49jt63Z4kkZ/IT4b5Qe86QdQAAAAA0nmj/g+mxmdLJXHkY/8E0UgoR3Wc9dMifBtqGNssZbTAAAABAzIhE1g2xvj4CU48Yjw7/FqLNvNcwjPbLGZV1AAAAIGZEJeuGYVSrRrFiLFaqxYoBUwegAUDWAQAAgJgRoawDABoM2mAAAACAmAFZByA+oLIOAAAAxAzIOgDxAbIOAAAAxAzIOgDxAW0wAAAAQMyArAMQH1BZBwAAAGIGZB2A+ABZBwAAAGJGhLJ+vVw9M1c+mi2dzJXmirh3IwCRgzYYAAAAIGZEJeuL5erYXHkwWzw6UxrMFuHrADQAVNYBAACAmBGJrC9WqmfmyoPZ4tl85datW1PXq6av54tVjbA3619wFiYGelOpVCqVcvfuLkspKZHX2NcjTs0ml+lL9fSP5+m6keSSy/SZOdC9MQnoKEwM9EZ6lBi4nJ1lAbJuRs6hAVkHAAAAYkb4sr5YtkxdkvXBbHHU9HVG2Jsj67lMn2VlhYmBXlPjyP+Xdxdq8oxQ67jUaBLUOgsTA+kA4lwzZM9iOqnUvsOH+3y0N5fpS6V6Dhw+1NATy+acyxyyc3UXcjQn5zBBGwwAAAAQM8KU9Wq16tTUWVl3fL0iC3tTZD2XIcIpPNFmpSyJKHGP1AoTA+n+kWPuolymL5JDJ0xNnid3uHwHiR7PnA3DCJR4s/7MEwaorAMAAAAxI0xZL5ZK1NRZWTd9feFGSdxU51Vy74K7iNZ5hVVop4o9ZC7T19M/etp6wVpVLEgzGfhW1uUlasLCjnv6x/POKmQUdzP/1KzHRDnpurp5cgJrPjpr7Xvf8JRz4NzKtJgkPRbCU+ZAeZ5YgcblbB/rfcNTS8y5dYGsAwAAADEj1Mq6YVAp18n6YLY4L19sykpwmvr3vuEpRb54dRa03XxitjdI3RFKwVoci23LZjzOHoZLmO7Y6h8xN6YtGqQvw36iS81ZTlagfsrO00N8UyQJ6sk9/eN5aapRynqDchbaljpM1pudFwAAAADqJGRZPzFb8pX141dK10p+si5dyWlpmVmDlq8FFa2Ra9Zgu0o8Kuu5TB9/9ai+sq5NuEcxeEO0eeZKUT410dC5Irxunvoq9ZS6ITloAWXdg4CV9ehzLkwM9Aa6Jjaeso7KOgAAANCmhCzr2cXqCPH1k7nyzKJxNl9xlgxfKV26VpFdvaZecNnQicLXKutkZWcVj5KrV558wvXLupJaVv424DbWsP4ahvj6fw3yo/GyzuXsfVlp7Tm3LpB1AAAAIGaEfDeYatWYIb5+YrZ0fqFyMlempl6sqNv5NLTkMoeHpwwjd3rE6dM2nXZklDSlW5LHt8Fw12sK9Wm504TCt2eId4PhEvaXdb4Nhk9NTEgtsuvmSXZB/mTgK750DeWohNyzHmnObA6151w5ezi1+8g5w6hOD6dT+0dm6KNWAW0wAAAAQMwI/9aNlaoxs1h9b7Y0mC2eyVdK1VsXr1U9Td1Qul5IV7JwNaa7GhU58fbZ6uWaHjdXUbbXt984sq7k6aAm7C/r/BWx/NSEPXF3g9HMkxy2oyOBq9Tc8WYTCC6+OebGNdHnTH4i3Bdqz7mtZR2VdQAAAKBNieSfIjm+7lTWPU0dLI1CRPdZD52Cew/7tqHNcoasAwAAADEjElk3xPo6TD1q2qPLus281zCM9ssZbTAAAABAzIhK1g3DKFeNfLF6ZbE6V6zC1AFoAKisAwAAADEjQlkHADQYyDoAAAAQMyDrAMQHtMEAAAAAMQOyDkB8QGUdAAAAiBmQdQDiA2QdAAAAiBmQdQDiA9pgAAAAgJgBWQcgPqCyDgAAAMSMCGX9RqU6uVAZzZXOzVcWStUQRwYAsEDWAQAAgJgRlawXK8b5+cqxmdJgtjg0UzozV4avAxA1aIMBAAAAYkYksm6a+tBM6Uy+UqzevHitejRbOjNXvqb19Wb9C87CxEBvKpVKpVLu3t1lKSUl8hr7esSp2eQyfame/vE8XTeSXHKZPjMHujcmAR2FiYHeSI8SA5ezs8wna69z3xagsg4AAADEjPBlvVQ1zs9XjmZLg9ni2Xzl1q1bU9erg9niYLZ4Zq5c4H29ObKey/RZTlaYGOg1NY78f3l3oSbPCFWUS40mQa2zMDGQDiDONUP2LKaTSu07fLjPR9Zzmb5UqufA4UMNPbFszrnMITtXdyG/sce5bwsg6wAAAEDMCFnWK1Xj/HzFVHNV1gezxbG58vWy6utNkfVchgin8ESblbIkosQ9UitMDKT7R465i3KZvkgOnTA1eZ7c4fIdJHo8czYMo2UTDwu0wQAAAAAxI0xZLxaL54ips7Ju+vrCjZK4qc6r5N4FdxGt8wqr0E4Ve8hcpq+nf/S09YK1qliQZjLwrazLS9SEhR339I/nnVXIKO5m/qlZj4ly0nV18+QE1nx01tr3vuEp58C5lWkxSXoshKceZWh/521czvax3jc85Vs6j1tlff369evXrzcMAw/wAA/wAA/wAA/a60GYsl41DCrlOlkfzBbni1JxnZXgNPXvfcNTinzx6ixou/nEbMmQuiOUgrU4FtuWzbinPQyXMN2x1T9ibkxbNEhfhv1El5qznKxA/ZSdp4f4pkgS1JN7+sfz0lSjlPUG5Sy0LXnaeNCW/NZDJ+sIBAKBQCDaNEKWdfP2L96yPjRTUu4Mw7aXpCg9/eN5qwYtXwsqWiPXrMF2lXhU1nOZPv4KQ31lXZtwj2LwhmjzzJWifGqioXNFeN089VXqKXVDctACyroHASvr0edcmBjoDSTg2nPfFpyErCMQCAQCEa8IWdYvXqtQXx+bq1yv3Jy85sr6sZnS+flKsSJtWksvuGzoROFrlXWysrOKZ8lVnyefcP2yrqSWlb8NuI01rL+GIb7+X4P8aLysczl7XlYqZdueFXWbk5B1BAKBQCDiFeFfYHrpWuVd29ePzZRO5srDsyVq6jcqQS4wFbwplzk8PGUYudMjTp+26bQjo6Qp3ZI8vg2Gu15TqE/LnSYUvj1DvBsMl7C/rPNtMHxqYkJqkV03T7ILUjb2FV+6hnJUQu5ZjzRnNgcuZ+9vIJWzh1O7j5wzjOr0cDq1f2SGPmoVTkLWEQgEAoGIV4R/60bT149fKQ1mi2fylVL11sVrVcfUFxlTN5SuF9KVLFyN6a5GRU68fbZ6uabHzVWU7fXtN46sK3k6qAn7yzp/RSw/NWFP3N1gNPMkh+3oSOAqNXe82QSCy3qOuXFN9DmTnwj3Bc3Vw+y5NweCrCMQCAQCgWh8RPJPkUq2r5/MlacXq+P5imXqzE0bwZIpRHSf9dApuPcxbxvaLOeTkHUEAoFAIOIVkci6Yfv68JXSYLb47kzp/HyFu706CAf/ZpNWoM281zCM9sv5JGQdgUAgEIh4RVSybhhGsWJkr1cuLFQ+KMDUAWgEJyHrCESAUN8mCAQC0bIRoawDABoMayFNFyMEotWi6R+9CAQCETwg6wDEB9ZCmi5GCESrRdM/ehEIBCJ4QNYBiA+shTRdjBCIVoumf/QiEAhE8ICsAxAfWAtpuhghEK0WTf/oRSAQiOABWQcgPrAW0nQxQiBaLZr+0YtAIBDBA7IOQHxgLaTpYtTsOPjz5MZdR8Ie9khqQxTDIhoSTf/oRSAQiOCBWzcCEB9YC6GO0rs1KbP1YDgCdCS1wR20iRZ78Od2Ej/f6yyJgay78wrplDkDSrM4+PNkcsPLIz6b733BzuaFXs9d+A/VjGj6Ry8CgUAED/xTJADiA2shGovycCxdjOza4Biwqm7E+Y6kNiQ1a/oOVXcOth3ar47s2mDOMRpZrz/J2mPvC0l6PPe+sGQDHtm1wdbovS/Ywj2ya0MymXzh51v9DHvvC8kNqX6/8QMNpYm1ax8PvvLOna+vXfv4zp2v+y50oukfvQgEAhE8IpF109SPXymNXi3nisa5+cqxmdL5+coifB2AKGEthJOVcGWdKjL1S49dRCPrR1IbGIlsd1nnDu8S40hqg3t25Gx7fQx7ZNeGoMfTbyhtrF37OA3f9V98cdfatY+/8tqb5tNXXntz7drHX3xxl279pn/0IhAIRPAIX9YrtqkPZotn85Vbt25NXa8OZouWr1dYXy9MDPTua8K/dS9MDPSmUqlUKuXu3V2WUlIir7GvR5yaTS7Tl+rpH8/TdSPJJZfpM3Oge2MS4PA6jlHC5ews88vaSdpvdi0KayEa/5NM2u2ycOyq/+WNpNWBtGFIQszXWW1Fpl5oPZaGMmVRaV/x3zCg1x78eXLjrpfttg2nh4T07ZBivJ2JT+XYTa//5Y3O15Lercnk1heEJJlZsDtijr/n4dVNQTprmpO79wXaSyMptY9hH0lt2JDatVWTbXiyzj4O4uu+pg5ZRyAQ7RUhy7pp6u/OlAazRUnWHV+/wfh6c2Q9l+mzPLIwMdBr6llhYuCAlYi7UJNnYWKgNyIR5VKjSVCbLEwMpKNQS7JnMZ1Uat/hw33eOut9HCODzTmXOWTv3l3I4azYyJRDpV5Zp7Vnu84qFF/Fl6TReJvkxpFt1V3TNUunJO+/IRdWL7U0O9vR3UbzkV1b7ZyVPpBAf3Mg6VlK6h4HkqR+FqJMK8ff5/BqpsCcNWbw/pc31i/rtCfHr3G/Vllnq+nBW2JMX/c19ZOQdQQC0VYRpqwXS6WL1yrHbFNXZd3x9evFkrhpU2Q9lyHCKTzRZqUsiShxj9QKEwPp/pFj7qJcpi+SQydMTZ4nd7iCjRQpnjkbhhE48Wb9qWepsBbCyYoo6+7FgrRcapZjqYrVKuu6yvpFVdbJsAEtn1TZdX8TsHxUslV3RkoRupb2FUGLpWMVSNZpD7puIp6yzk5BOWvs4EEr69xB/vkWmo+9Mn+5asPaYMww+9Q9WtUh6wgEoh0jTFmvVKvU1FlZH8wWh2ZK80WpuK7zKrl3wV1E67zCKrRTxR4yl+nr6R89LXY4iAVpJgPfyrq8RE1Y2HFP/3jeWYWM4m7mn5r1mCgnXVc3T05gzUdnrX3vG56SO0DELwGS5ApPferQ3i83Lmf7WO8bnvJLql1dfQmyrtVBswZsV6Pr6FmPStZ9w8mKk/UjqQ2OE9czeNiy7tV1o+m556egnDV2cGFhjT3r4oUB3is3Utad7hepf52Npn/0IhAIRPAIU9arhkGlXCfrg9liAFmnDmq/KssXr86CtptPcpk+6nOmrikFa3Esti2bkTh7GC5humOrf8TcmLZokL4M+4kuNWc5WYH6KTtPD/FNkSSoJ/f0j+elqdYt637t7Y3LWWhb0uScc78I6BJuaVgL0fif3Cji6FrvVkuyd8kyrXXZ/pc3au8GQzolSHu30gZjF3rddfw35DzSLRg7jsvJOrFV/eDuYendamfIfQkxlbT/5Y2aNhjfWfDHX9xQKJaLXTfCQVPOGjc4TUCx+QAXmNIvCWG2wVBZr2l96d4v3reCgawjEIj2ipBl/dx8xVfWx+bKymWmbHtJitLTP563VEq+FlS0Rq5Zg+0q8ais5zJ9vK/pK+vahHsUgzdEm2euFOVTEw2dK8Lr5qmvUk+pG5KDFlDWtWiPo7hOI3IuTAz01nDVqHdve+tSr6zzlyq6N2UXTFpz8aX+PutOq8aGrS84gkuGGtm1Ifnzrcx9u/02ZCSMtIWw91l32mDM2rM0eD2y3rs1SR3dXI0myc1C+cqhHn/Jg2k3i3U62CkwZ409uWSh3KMfwLDVm9mHLOtLMfUgvt70j14EAoEIHuFfYHpe9PWj2ZJk6twN12vpBZcNnSh8rbJOVnZW8SwT6/PkE65f1pXUsvK3AbexhvXXMMTX/2uQnqDXaDYi5zrUu00bYQLLektF2HclRyD8oukfvQgEAhE8wr91Y6lqnJ+vmI5+Jl8pVW9dvGZV1s/MlQulgLduFFwvlzk8PGUYudMjTp+26bQjo6Qp3ZI8vg2Gu15TqE/LnSYUvj1DvBsMl7C/rPNtMHxqYkJqkV03T7ILUur2FV+6hnJUfNtgAl+BGn3O7BHkc/a6a0zl7OHU7iPnDKM6PZxO7R+ZoY9aBdZCmi5GfgFZRzQ6mv7Ri0AgEMEjkn+KVKwY5+crQzOl03OVhfLNCwuVo9nSmbnyNd7UDc39y+WrSZl7jzurCL4nXa7pcXMVZXt9+40j60qeDmrC/rLOXxHLT03YE3c3GM08yWE7OhK4Ss0dbzYB3ZW47HH0vj1LJDmTnwj3Bb7w766qHl7IemQBWUc0Opr+0YtAIBDBIxJZN2xfN28OMzRTOjNXXtCaOlgahYjusx46Bffe621Dm+XMWkjTxQiBaLVo+kcvAoFABI+oZN0wjBuV6uRCZTRXOjdfgalHSns0WLeZ9xqG0X45sxbSdDFCIFotmv7Ri0AgEMEjQlkHADQY1kKaLkYIBAKBQCDqDsg6APHhJGQdgUAgEIh4BWQdgPhwUiPrzc4LAAAAAHUCWQcgPkDWAQAAgJgBWQcgPkDWAQAAgJgBWQcgPkDWAQAAgJgRoayXq0a+WL2yWJ0rVouVEAcGAPBA1gEAAICYEZWsV6rGzGL1vdnSYLY4fKV06VoFvg5A1EDWAQAAgJgRiaw7pj4yW5q8Vj01V4avA9AAIOsAAABAzAhf1mlN/Wy+cuvWranrVb/6erP+BWdhYqA3lUqlUil37+6ylJISeY19PeLUbHKZvlRP/3ierhtJLrlMn5kD3RuTAIszA981Q4XL2VkWLJfCxEBvpCc3MiDrAAAAQMwIWdarVWNmsToyWxrMFiVZ9/T15sh6LtNnKVlhYqDX1Djy/+XdhZo8I3Q6LjWaBLXOwsRAOgodJnsW00ml9h0+3OejvbnMIXMF5jBGB5uzkwpd6IGp9pB1AAAAADSfMGW9VC5niamrsu74+mJJEvamyHouQ4RTeKLNSlkSUeIeqRUmBtL9I8fcRblMXySHTpiaPE/ucAUaKFo8czYMI0jiuUzfvqMjzflLz5KBrAMAAAAxI0xZr1SqJ4ips7I+mC0ev1Kal6vrOq+SexfcRbTOK6xCO1XsIXOZvp7+0dNiV4ZYkGYy8K2sy0vUhIUd9/SP551VyCjuZv6pWY+JctJ1dfPkBNZ8dNba977hKblrRfwSIEmu8NS7du7j6o3L2T7W+4an9Dmb22Sb1Ja1ZCDrAAAAQMwIU9arhkGlXCfrg9nifLEqbspKcJr6977hKUW+eHUWtN18ksv0UZ8zdU0pWItjsW3ZjHjaw3AJ0x1b/SPmxrRFg/Rl2E90qTnLyQrUT9l5eohviiRBPbmnfzwvTbUOWc+5Um3oaVzOQtsSm7OzfbOuoVj/BfKAAAAgAElEQVQykHUAAAAgZoQs62fmyr6yPporXS/7ybp0JaelZXIzMdO9zTZrsF0lHpX1XKaPd0x9ZV2bcI9i8IZo88yVonxqoqFzRXjdPPVV6il1Q3LQAsq6D9594g3KuTAx0OtzdSkZHbIOAAAAgNYg5AtMFytV6uvHZkqZXOn4lRI19XyxWpVcvaZecNnQicLXKutkZWcVz54OfZ58wvXLupJaVv424DbWsP4ahvj6fw0KhKf6NiLnGi4rFWk7YYesAwAAADEj/Fs3LpZdXz89V1ko37ywUPE0dcO3oSWXOTw8ZRi50yNOn7bptCOjpCndkjy+DYa7XlOoT8udJhS+PUO8GwyXsL+s820wfGpiQmqRXTdPsgvyJwNf8aVrKEfFtw0m8B1Yos+ZPYK199lXzh5O7T5yzjCq08Pp1P6RGfqoVYCsAwAAADEjkn+K5NTXz+Qrpeqti9eqg9niSdPU+S2kJhLSlSwUON3VqMgJ15cyl2t63FxF2V7ffuPIur7wqibsL+v8FbH81IQ9cXeD0cyTHDb3Nif+4sscbzYBjfiql9tKXSrMSJHkrJTM7T/CBJJ1J2fIOgAAAAAaTySybhjGYrk6NlcezBaPZkumqc/JF5WCkChEdJ/10Cm497BvG9osZ8g6AAAAEDOiknXDMK6Xq2fmykezJZh61LTH9ZBt5r2GYbRfzpB1AAAAIGZEKOsAgAYDWQcAAABiBmQdgPgAWQcAAABiBmQdgPgAWQcAAABiBmQdgPgAWQcAAABiBmQdgPgAWW82s6nVH3v41QvhD1wY2rRy+dOD4Q/cYNx5LOlQhXc44nJgAQAxBrIOQHyIQNbHursSKsl08BHSSX6DdDKRSCQSXd1j4iK6oMWZTa22Doitew2TdXfXiWh2WBuFoU0rE9Kx0K7YPFmnaVoHrtGyHvhI1TiaNNZsanVL/GAAAMIgQlmvVo1ixVisVIsVo4I7NwIQPa0o6+YAelmndt5Wsj6bWu0YUmFo8w9fvWA0SNZnU6upnM2mHq19l/U4qmabwtCmlUQMC0ObPq8feAmyHsKxrXXWIZ/Omo5UANwfwcLQppXWwKa/L08mI/pJBAA0nqhkvVo18sXqaK40mC2OzJZmFqvwdQCiJsI2GNO5RZEmIu/IOFnW1T3mCLlcQzeIrLuvUFmnm1qjOznQory9nvt1QE0rii8BhaFNXaoMNUDW6ZeEMMZb4jZEE2sbo+NkvcYj5Y+QnZxqZD+JAIDGE4msO6b+7pXS6NXyidnSe/B1AKKnkbIul9wFcw4s613daTIwkWpp+GSa2WUi0dXV5bOOm1bYFXtWmmdTqz/28PY3rd4EoYhqtSvYy2ZTqz/2cPfm1fYSt6+F2yqRSFjFdC8J43pjuIzIegn3GwDdsDC0aaU9O7OjonuzvI2Tok5/uY4PXta5yQsLnQlYqwi7DTptNlt7kTLjzycfFXbJq3FhaNPK5T/s3rRSdySVHXmfOHqc1CnJ54h8XWT6pCDrAMSF8GWd1tTP5iu3bt2aul4dzBZNXy/zvt6sf8FZmBjoTaVSqVTK3bu7LKWkRF5jX484NZtcpi/V0z+ep+tGkksu02fmQPfGJOBBYWKgN9IDJcPl7CzzydpdL+KzGxUNlHXhud2WzrW8eLfBdHWPkaFYqXYHsEScSjmRfLKKlFZUWPaktJJbkkSbFKwuGalATtXM8S5nFbHPxlZJrYQJXx7cJ3xGgtuxe7d3RF7kdFOroEId2X3CyLp28tI86cw1f2jwm7b47Wf504PCBNQZS18oNLKeoGkxR9LnSBmzqaR0yYO6LjOy+JMAWQcgxoQs61XDNXVJ1j19vTmynsv0WUZWmBjoNTWO/H95d6Emzwg9lEuNJkGtszAxkA4mzrVB9iymk0rtO3y4L5ism/rbsHPL5pzLHLJzdRfqtm5HRXdpoKwLNfOE7c20ri30rnjJujt4t6YNRmvi1rjuPvi0osTyP9H3zJfkJ0JdVFZPIWmlkitYLCth0nJ+/f+/vXP9keI68/D+Bf4TWvkWxRopihob7IZA1omU9hdbkeXIwjLYHq+sRLHcuWzwRfYkG3Z7vSSKVbnsAGNCbI8HSHBoLw4O43AbGobh0mBjYDYwHsyEGXObYabGENva/VCX855z3lOX7qq+FL9H/WGq+tQ57znViKfefqtabBC3Y0cXIcuJ/qiybnJHXdYjTF6foWk5QqYdkFknJ4k/gxF6NK5k0EqpR/qXEAHfseRyX3rk1Roy6wDcKiQp67Ozs9TUdVn3fX1mdlY+tCWWNDFChFPaMEal7Ukp8IDQLp/aXRkcHhK7Jka2p7J00tTUeXLLxTAxsn3b3uHmndvAmL2IzIGnddnTPJou62za2jf2olWLJutqqbuUFFcz6xFkPcVsOo9vRqzR0SQ625L1OFPi1GBhjck6a5FRZD3ortPosh4yeX1f+8q6uSQ+wv25ShMnHK9IJ/g6CTXrAGSYJGV95vrsYWLqrKw7vv7xdBRZZ2oXxC6a55Wa0EoVr8uJke1bBo8cc99wm8pmxkQQmllX9+gBSwNvGTwx6TchvZDai9DQ3L+JctK2pnlyAuv89Z479rYDY/7Cicy0HCRdC2mTWSjSaDz4eqZ5MXtrve3AmCFm/Ux0Gi2sWSdibtrH16zX1P7UDL1DRFlnQ0ilZv1C/6OMKXFGpz6pg2kp1Yy4VRG0iFryfeWZIt7TYMz1ICGyzo7utyXHG45RHk7jPuMkVhmMPjydzYU/WObLm1jTDpZ1fcbqkPpplHs0nceglSIT8N+/vM9apxfGcIvEW766AACAziZJWZ+zbSrlJlnfMz49Na2UwrASXKH+ve3AmCZfvDpL2u5sTIxspz7n6JqWsJb7YsuyGaX3uuECpgO79SPOwbREg9RleBum0Pz9pAH1U3aeAeLbT4Kgnrxl8MSkMtXYsu4fH/LlQ/NilsqWTBcYJKpOLIhp8tNgaM2JLut+ettrFizrShm631XJipNZZ8NK6ZGQ3P2TvCP6JTBfesRaw2m9zd1jKO17xmJyrkp7LiBjYY7XWL0tUmxTM5VLvhf82x750SZ0ZK7yJ8dbNnPvpCy+2uJ6fanXDRGnHSDr/IzJkPxp1HrUphK6UmSi4iyTsfTlZD4hgd9DAAA6nIRlPWJm/dJMmKwrd3K6WqYWQDPV22yxBltVEpBZnxjZztdZmzPrxoC3aAZP/1Z80t3PhyYbOpeEN83TnKUe0w8kixZR1hlI7+Gy3oyYL5/avTVOurxDy9fxC6YAAABAxkj4BlOlZv3ghZkPPp49MnFdqVnXnuEYpxZcNXSi8HFlnTT2mwSmXM1x8gHXL+taaOPq1YAorGH9NQnxDb8MMiA9VSX44SrNiLmOPDlkHQAAAADtQLpPgzk8cf3Dq3MnJmfjPw1GcuaJkXcPjNn2xLFhv07bcdrhI6Qo3ZU8vgyGu19Tyk+rlSYUvjxDfhoMF3C4rPNlMHxockB6kt00TzIE+cogVHxpC21VItWsi3fjZtYTjZkNgIv58vg4mZGq97Pvvdv/xl9P2vbchwcq/W8Nn6d/tQuQdQAAACBjpPuc9eOTszNzn/zvpUjPWdeSsOrdpLQZFTn5fkDuJkHjw1W0483lN76sm5PFesDhsi73yd12ar51U3sajGGeZNnEo1nCxZdZbzaA6LI+wTy4Jv2YtTS/9yVM0A2mdBjnb8g6AAAAAJpPur9gOnR+5vDE9QP4BdNUudwpDxy8LJ5h3zF0WMyQdQAAACBjpCLrtpxfH4app0xnFFh3mPfatt15MUPWAQAAgIyRlqzbtj03Z0/P2ldn56ZnbZg6AE0Asg4AAABkjBRlHQDQZCDrAAAAQMaArAOQHSDrAAAAQMaArAPQAfz7f/aaXrQZZB0AAADIGJB1ADqDUFO3IesAAABA5oCsA9AxBJu6DVkHAAAAMgdkHYBOIsDUbcg6AAAAkDlSlPUr1+eOX7y+d3zm8MTMxWk8uxGAZDCZug1Zzwoztj3T6hgAAAC0CWnJ+tXrc7WL1/eMT+89P7NnfBq+DkATgKx3EJPXJk9MnDjw4YGhc0MHPzx48u8nr8xccd76cH5+fH6+teEBAABoE1KR9auzc8cvXt8zPv3e5Ownn3wydmXO8fXJ6TmDsLfqJzgvn9q9tb+/v7+/X4wu9vVrIZH32PdTDs1jYmR7/5bBE5O0bSqxTIxsd2KgozEBBB6b9kqZxiUBiljCoibrHtq0DYGsdwrHLhxbs2/NA5seuGv9XfnefKGv8PAfH+491Htm8kyrQ7Nt27b3rV649Gd7L7U6DAAAAGnI+tXrrqkrsr5nfPqI4+uMsLdG1idGtrsWefnU7q2Om5Hflxc7DXFePrV7a0oayoVGg6AqefnU7koaXklGlsPp79/27rvbQ1y2NaeUjXli5B0vVrHTeHgrLhoTIwVZr1nFnE6pEr2HSingAKn7olVrrLcOYXh8+NE3H12wdkG+N09fd66780fv/Ojk30+yR515feXtYq1WvPZRmiFC1gEAoG1IUtbn5ub8nDor676vz6rC3hJJmhghwiltGKPS9qQUeEBol0/trgwOD4ldEyPbU1k6aWrqPLnl0g5P5RIikMCYbdsOCTytpWwe7SjrTgfcAWzXIT2be+sULly58NifHlM0/am3n3p79O0X/vrCXevv+umun348/bF+4JnXV97uKfqZ11fenqpMQ9YBAKBtSFLWp2dmqKmzsu74+sfXlLunTF6l1i6IXTTPKzWhlSpelxMj27cMHjnmvuE2lW2SiSA0s67u0QOWBt4yeGLSb0J6IfUioaG5fxPlpG1N8+QE1vnrPXfsbQfG/IUTmWk5SLoW0iazUNyseJoXsxfVtgNjfMwTI9u37R02Vx91ACmWwTiWLOe+iW37+kz2Fa1apUQ8nD9YO7JUUUbzN9jexE59j+hd7aNo1URD4f5aZ8lfHLx27LVCX4Ga+uJXFu/5cM+Nz258e8u38735+9+4f3B0UD+Qyrpt71u9MM3kOmQdAADaBjy6EYDs0ExZV/Pikv5GkHXnLUmDxRgRZV2OQY9AqLiexS8Wi0ob9VBx1ZCYrF+9evW7b333jrV3UFn/8c4fT85OvnX6rQW9C/K9+bvX3/3yvpenp6eVYyVZJxuiPMbX632rF7pzcNoENhFSLvbJ+wEAALQSyDoA2aGJsi5te4XknNoadJfL1AuB52Vd7c01cNq3dAlA3qdN3b+dDsUB9NCaVYxWQh+T+fn5R/74SL43v3DdwsV9ixeuW7jsd8t2/G3H7M3ZB7c86Ov7mn1r9GOprO9bvdD38Gf/y5Fq/301Ky6n5N09Ra+F965UWbNv9ULIOgAAtAmQdQCyQxNlXc9gq6luyZgNsh4vs672Vimpvq9EaehQ03JxfaCl1pNlfn7+0TcfzffmV7y5YvPJzat2rlq1c9VHMx9tPrl58SuLHVNfsHbBL/b/Qj9WusFUkm81S+5siybOkUK+5VtVncNqstGjDAYAANoGVdb1/+nxwguvTnk1XdZZnfW1t2jVzIUkppp1NeHt/W2S9TiZ9XBZTyGbrvDc4HN3rrvzm699c3x6/PSl00PjQxdnLz5RecJ/OMzSDUs3HtmoH6gnyG3Xy929smCrhk4UnuvpDGQdAADaFMg6Xnhl59XCmnUi5qZ9qggHPQ2GqTEnsu5tR6lZp8cFybp2KCmZSTLF/pczf/nqhq8uXLfwlwd/+ennn/7j839sen/TPRvv8WtgHvrDQ4fPH9YPNCm2K9VnXl95u+Pm+9ZbUmHMmdetLX71zNKf7b2klryU3OIZX+1FXwAAAFoOZB0vvLLzavLTYKjd6rLuG67XjMtaS4IsObE4qiINrfQmP31G7ZMpiLGNss7Fn7ysX5m58pNdP8n35u97476tH2ytnK48vu1x/5bTpRuWrh9Zf+36Nf1ANrMuSmCW/sx61s2GizIXkXP3Guk3k0o3rWp9AQAAaDWQdbzwys4Lv2DaEVy4cqHnrz2L1i/6+u+//o3ff8P5EdN8b37R+kW/PvjryWsd98u5AAAAUgQ3mAKQHSDrncKV61feOfPOE9ueWNy3ON+bX7ZhWenPpZHxkelZ9YmNAAAAbnEg6wBkB8h6xzHv0epAAAAAtCmQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBiQdQCyA2QdAAAAyBjxZf3iwOM5wheXbzxl21f2/8c/53K5r/TsSj9kfjA2rLbGnYZP2OJJ03amm8wsE+hLnYsbZ1M/FhGIu+R1968sJhk35bWArAMAAAAZI56sM07WBrLORNWgxjauryELolxaNFfW1dhaLutN+fTUs+Rx0JbA7VxfmjQvJCHrAAAAQMaIJevXXe8QjnNl/89XtVjWuWymF1ZjAzQiVa4a8gvieyN5++JAqVmyHhhbfTS2YikEZBgi5pLHHkC6dPU3vqVeVqY3U8g6AAAAkDFiyfq0YzyMkgmR1K1ITi36B/uHVAYeJ81JApQqjejki8vX/lGzVrMmSqOLVkzA7pumehotMK9nr4UfiRufKX8bamyhIduMrBvWTe7sKz07mEKQoL5ob367mt+J96ZB1knIXp/KJdZXVllaQMqVn7TJf2rIJNkPQvCSy2ectqHvaCeC+XR4m8Zrl9QvSyDrAAAAQMaoK7NutLIvFou6l2v1B5J2eYeQqgndnLgSBue9YPsxlz6YA+Zk3RQYGZ38GVwZHZKEDg2ZkfXI6xZB1gNqitx20pIpy2mWdamN/iftL4Ks00+NtmLa0gYvuTbjwKs2frSIlUVhV5aNA1kHAAAAMkbMG0wNWXIly2xOZF4U+VA1Ma0ajmiqdEdztIEpU/VNqkqBAatyZwpMtPxW6TtyGZD5IiJQ2CKErMt6xHWzr+y31iqXGNr0lOikLuTkuNTScLmgOKw3cKkkq6wSUARZZ76gIWdOXdvojkyOZyu7TKPxS2r4jiPNcp9My3rNKuZyuVKl2ccCAAAAraSORzfKYsZmVmWn4VPrWrqTy+kSE+LrQYIy66byDubWR7YMXjVWLTDlTaaAgokrMM0bOWTSMPK6mWLT+6I3JYholf6YKm3DOdauYZSw4su6JvrM4BGX3Jha54qBTKOFyboYIvtPg6mUyNq4dlwp5RIw5bRknYs4tK+iVasnDjupxQAAAHDLUP9z1qUcp1nW5VynnlnnRE42oR0Gq5fy85GsuE5ZNwUWVC4dcBERkOeNHjIx5cjrZopN76teWQ8sg1GWUrrTM66sG26I8IiTWqdflKiZedXXjaPVgspgmpJSd2m1rEvem/OcNKG0dhqyrgacy4V7eKUUoVHsSAAAAACemDeYfkf30RBZl7SFWllgEldCuTdR3mRzls7TYAw1JdzoUTLrQXbtllAbKzvY+Sh2X2IqV4wh69lwPbzkymC4cps6ZN3rnBScs4slbcuzMOl/iAeblzw4b69Owzia/Ab3pUMTTN1uuaw76ut7bKVUqsg6XLRqsiB70ursK1W894QLiz0VorkBfVgi8c0fq8arD0bCpN8N5EoVR7XJyM4ObwDRGXs0sxgAAABACPU8DUaClTVN1r3Gjqbxss6lsFUh13rR36VhMUlnOdtpSOaS4wzJazWtr4uxCEqXvIDajYghc9dAYevG7daup7jVZBTUji/r5DrAUBnvjcWeUYOsM42lcx+25MpdGMWiUrOuBGAajenfVCDErFNytIWsyxaq+ansu4x8k/1KW9N+vY+iVTMdK/BEmzqzkOw4si5hVn3IOgAAgPjEK4PRny4iVyOwNev+Qb60mmTdVt2GK0326zukI/lHd6hvaGl8g6wzqVg9MCXhr976KKX8mYysanGGeiBDyIY6fm36/NMH5a8jAvvSuqpP1tXVMSwe932JdLr5T4189qWPXfiS+3v9chZG1s3XlIaKnMCLhMzKuqyuvhqbKj/IfpqTFw7tdkeLaXjhJn14DSIcKwm11F/Rqhl021bKYOSexTSMR6MMBgAAQDzqr1kHALQbrZZ125aFnfVTJYtORJu6rWa8ujAH9RG4JQUSK7MuhSfmpm9B1gEAACQEZB2A7JCerN+Q4RtVSkJCiaBKfkoehqJlxXlZd02Y5LAj9GE8Vo43J+s6Tc5TDZeON2fWyYbx6EiyPj8/fwMAAAC4cePGjRuQdQCyQ0qyvn///kOHDlUJfDut8lyS1Zx0I2aUzDr3sBa2TpyRdcOxYRETDzfU0ZP9fM16YBW+tBjGmvWpqakqAAAAUK1Wq1XIOgDZIQ1Z37lz58WLFyM1lc2VyCh9yIvfyHluS6Csky69J8XIN5ga+zAfGxi0JNCm48l+P4NuaY+xMY6uP/EGAAAAMANZByA7pCHrr7766s2bN5OKMGtwT5QBAAAAEgSyDkB2SEPW+/v7IetGIOsAAABSBrIOQHaArDcbyDoAAICUgawDkB0g6wAAAEDGgKwDkB0g6wAAAEDGgKwDkB0g6wAAAEDGgKwDkB0g6wAAAEDGgKwDkB0g6wAAAEDGgKwDkB0g6wAAAEDGgKxHZbh/6MuvnI32Q46xmNps7b1v21TyHbcIf6HO7jj0hTXvn62zm/Fyz9Az+682Hk9jYaSHOO8JfrQg6wAAAEDGaAdZr5YL7m99L9841ooAGIb7h257evdtT+++zfO8psm6GPrpZGw1GY7W8m5Uu4PXobWyTlZv921PH+w7l3VZP3dq5Sp/vrsh641TKXmPTRd/1UHNKuZKlWQDAgAAcCvSclk/XC74jj468PxLu9ogxTzcP+Q7+tkdR1fvv2o3SdbHyz3i8sC2x8trjr47GbO/c6dWrjrYd67uGBiG+4cc8fU2DwZodP2yXk/kxtGj0cKvNdIYeqo9ZN35oSCPNhHNSiliRK2VdWbtMiHr/vIrU6mU5F2ZmCwAACRLq2X9bKW72NMOgk6Y2mxVdRltgqzTi4T6SVzWj9byT8foELLesqGP1tpH1pNJKic0RKWUy5HmlVKQDzYg6wmYZty16wi5rVlFsqbu/JzLklKpBFkHAIBgWi3rUmadImpjcktcm6+WC0t8sRcb1XJhSY/1fMFrODrQ3SWX1Yi+3ENGB7q7lpivEVhpHu4f+vIrH/RZe5UClbM7Dn3BKUJ4wc2CD/cPffmVE8/0eHtEAQl31NO7b3t6933bpoILP7jamPFyz9Azf37frYJQx/Iy9OroU5utvd7sxss9u91QSd2IPrRRf7naGFbWyXzFENLOd5XI6WpMbXaXnRzumL1/lLlayQ9juH/IO0fOIox8V5q4ZM8i+KO1/AtHX94wJC2gPChhvNwjLYheT+XBlME4g1a8Q4TKcx8hjanNVhWyziD8MGpzyHqiSHNSJ1jRZD3ljw4AAHQcLZd1X6WpsVepwfsbZlnPkUqa7i5Z/kcHRO5+dKC7a/nGsTBZ95VLKyV3VUnY/LlTz7zmqKGcIKdOudorZfEzxzRXfe7UylUhsi5dPIhjx8v+9YA9Xu7xoqX5aXZ0b6CzOw4tfUUNnh2dl3Up4y4CYGT9aC1P43/h6LuTjqnL1wZSZt1fjanN1l4/gLM7Dn3BmbJTq+2dhZWryKnxpd8fyB3dm6aIh07cLOvkkzDcP0T/llfGufghe7zJchhk3RtLmilzErnTseb9dpX1mlX0hVkUPpCSD9Fc2Sm5nLtBKlqkLK3Sk3yQMVL1QF7WxZikM7qzQroqWjV5EbganEqJHuXtZmTdC4NUjDjraSlDcmvl9ug0LVVC1opfSxG9d4BoQ+MOOANkn27nkHUAAAikDWTdtm0/He5otmTlQrGDMuuKjWsdCwIlXcK9dc91I8nMJAljkqmSXJIMuqP7suT50maSdWU/3170SXyOHd2Nn3wVUJ+sK/tpAluRdfmmTyaNTRZck3VVT9n9QTdrStU48jmNKuvcuWby5YyaO+1ZvTZm1kmo3g2y7EnkemsfWVd12pOymlUUKkxltmjVZKmX31E2VBXWejL0oIbpvyM2GFkXQZOR1WprZSgRoZTZFxuVknBdtThEWjt91mTCygWFQdalNgFrxZwAu1JSx9IvKAJ7VZpD1gEAICbtIuu2bQvtTlrWG3nIjC9SrKzTJDrbkq3bNsi6SYsbk3W2ajyOrJvSw7FkXZtX58q6uRDFlEd3BlXfiiProaX/3tDtI+uMcTkJWs/MaHrcE9OAtLKyQVtyPZl6CIiSJLAVWZcFmktjM0NRqacN+f1yHty8BG4otP4+iqxzKX5urQxnTk2bO9vSWCFnALIOAAD102pZP/ybglBpX7v5MhhSvDI60N2VY2RdKnAZHbA2KSUv1XJJ6YlhvNxDn3wSIOukQuPcqZWrmMw6rdCw7fHyf79/1pYrQGiVBenEbb/GuyTgy2BCZJ0d3T+QxBl8s+PUZmsvdU33aTCxymBI2Y9TOCTKPGz77I4Tb5yrowwmrqy7zZjCGG8NaTX/bYyss08K8udOipHs8b7NZy8eff9lZ/GZ8pWosm44iRJ+RVNnybomu3XLemDZtuF9k6z/3z/9E17RX1qtUsgJQM06AADEpdWyLtepCG/n9/p3ii7psZ7nMutKI1/RlQe5h9Ws02dXs3cu+gLn3/n3wtGXN3Bab9O7A6VrAK//Yy9LokwLLSQZ1XYaZN1vrN5gKird6QWGqJA23GCqBkwKuGmFhl7Jzd9gqoivdHMqjZzOjqzJC2z1dhRZ1++sFWXi7sTFeT+4ejObWZfOhTeQcsMAXW3RWLsWiizrho8Q21Uby7qoN9dKP2y7ZpX8LLCogrYq0h5az6Gli0lPLfdXvKK/OuIOWQAAaC2tl3UAQFK0j6zLNRHavZFKfTZ306ZSL9NMgwy8wZS7F1apyFFvMOXuY41dBsPfpEuHlBbPMvXIrro8HAkP0BwAAAuzSURBVH2bTNKSyvCbfVKifvoAACBzQNYByA7tIeuxgdjdmuC8AwBAFCDrQEJ9ckvjP9IEmkjbyjpUDDQCPj8AgFsZyDoA2aHlsg6RAq0Cnz0AQFaBrAOQHZop61Ai0EHg4woA6Fwg6wBkh1RlHZYDsgc+1QCA9geyDkB2SFbW28VgDM9tTxQ8QTB9OmeN2+WTDwAAtm1D1gHIEo3LehKOoj+6sTESl3X5Fze53xlNFXl9Wumv7DMlU6OxNaaPrmwyEHcAQGuBrAOQHeqW9QARafRHkcIlK0zG05D1ONaY9Pjt8U0B/Y0pZzOxmJK+8qmUcrlcsVRKf9kiAWsHADQZyDoA2aEOWQ91jgR+wTTETiHryRM2RfpbsU0fvD6asWyxgbIDAJoAZB2A7BBL1iNKRgKyLu1RfguUlqQYftjUOVr7aVO9L+5g2oj8KKoqk94u7bdWS3J80tzERs0qOr/w6UZC6kt0v+TXR/91UrYTZSf3O6i0uMXQU6D4klPCrpjYqJRyRavidV60ajYzuLbGQb+iGnAR0Zay7gNlBwCkB2QdgOwQXdaji0USsi48rVIi0i7JuH9wyXU1f3dNSLBznP+j92pfrAb77ue/K9Wse3Gp0VRKXle01wBZly4P/DbMhYFcsy4c3RVtIcJaJ3pJkcGipf1MT2bxFctLN8yynqN/y3NhujacJXltOlLWHSDrAIA0gKwDkB3iynqUPpPOrEdI8yq5cOV91b9pX862VImdk/DS56bMOjmIcfJAWZcUV0JRTIN1OocR29Y6CboKUjbkP6P0xPQnXbkYM+shu5m+1bMUjU6QdQf4OgAgWSDrAGSHiLIeSyaSrFmnCWjedCslLdms9keLPbjcvKenpYpJ8NKX9dB68SiyrnVSt6zr4ZjMtymyTucbXb8h6wCAW5XEZP3a9WtHzx/tr/X/5uBvfnXgVxuObNhzds+l6UvOu+fm5xMKGABgpB0z62o9NvlTN11SBSFkXKox8VtwfdUsiymMIfUgXv1MgKy70ShB6ZUhpinIbUhZj2F95ADkEhO1EzobZ67sgilT5MOhl0W2eBoMXwZjGKY+WdfPkrw2HVwG4wBZBwAkSzKyPnltcsORDY9sfWTZhmUL1i7I9+YLfYUHNj3w0r6XTk+eTjbi9qJaLizp2TXVSBejA91dyzeOJRURIYHg2gJ/Ho0tVXLL0b4L2z4164YiEPFWyZJt2GtJ7iO1aGbdEkdq95KSvpjbUPW7UM2yHnynp3LvKBlWFUnzHZTs+mi3tfJ32rITZBaM7FZvMJXC4W8GpXvlCxBtmIC8PjN3pdadXZ0Ol3XUrAMA0iABWb82e+23w7/92u++lu/NK69CX+G5wef+NvU307GVf/1GTqFhbx0d6O5KsLtgYmubiM47rmmyThcm5WWJRLVc8MIJXsPWyjoJ01u4Zst65JVqk6fBAHDLgafBAADSIwFZH/5wuNBXUDT91eOvnrt6btXOVYvWL9pwZMPV61eDuqhLwkwH0f2jA91dqWpVPG2TwqmWSxvH7CbJ+uhAdxcRvdGB7n+JPWRdgRoWqFou0CuGavnBgFWsX9aTWNuYZp706Yy1Um3ynHUAbhXwnHUAQBNoVNbn5ua+/+fvK6Z+7+v33vzs5rGLx5ZuWJrvza/YuuL0xcBimNRk3bar5UKaWeR4JscG0wRZT+aaJTlZr5YLcXL7t7Csx1ypNvkFUwCyDH7BFADQZBqV9UuXLi373TJq6neuu3PrB1vn/zH/4q4XnT2LX1k8NDoU1IsuOOKLf5KJLohSBFqboMiM1BnZ0AtQ5C7ZJqR0RLoAIIUR9WbW5XgrXp/cMGQGy1+yurvcPVGDC/JHrjaGi0hfcG30arngLcboQHdXzg1VX6Ug/eUqPlhZZycv7awoIdNho06bj9bbpc24VJKGNHwUq+XCkh7r+YI3RXYqoSvFUres+5hEBDoCblnwjwIA0FoalfX5+fl8b37huoX3vnbv/QP3F/oKD299eObGzPHJ40teWeIb/PD4cFAvik2ODnQXqVWppsUexO4XicnRgedfUmrE1S7ZSwZ/h9daKWUpxJF138v0UnIhwO57XpWM4qqSwkYMzijrUnOxYYhI6oYbnZ6sANU1K6iURxYbjKybJq/Yrhoy80VD6LSlqx9nn5iAPmP1goKX9VwueCXDVspE47JOCXYUaArIKvjkAwDaigRkvdBXKPQVXtz14q6xXd97+3uV05Wbn938wTs/8E190fpFI+dHgnqRbVK+Q9QzJMeZZKU3yrqSBHZR0/Vql86Rwo7kJDWTLDW6KJ8nVVpwDqxt0J5U9YwaXLSCIUN7saFeBamjk5ClRH9kWWduiJWvquiesMnrMzQtR8i0AzLr3IyjyXrwhyx0pYwkK+sOfhlMqMHAY0DHgU81AKD9SeAG08f+9Ngda+946s9PnZ8+f3zy+LVPrg1fGL67725f1h/Y9MDJv58M6kKXdYPmUp2OqqC2bcvJTNmAVEMnCs+pUgRZj4bfEWt0NInOt4wTnGGpGpN1dt6RZD3grtPosh42eX1f28p6wCfItFKG5unKukJEy4HugHYAH1cAQOeSgKxXPqjcsfaOezbes/XU1s8+/+zTzz998n+e9E19wdoFPx/6+dS1QJ/Vy2C0h6ZU+yyliiWOrCvFHG6uXulydMDaJKsoLcvw6mho5YtclxIKLe8JkXUysrjOkGcWKzjlmSKjztNgAupBQmSdHV0sJG/1tChJXjj3GSexymC04els3HMZuwwmrqzrMzatEjkDco+m8xiwUrUB/cPl0ExZZ4mrRHAjkBT47AEAskoCsj41PfXc4HMLeheseHNF7+HeNdU1NK3+6JuPHvvo2Jw9F9QFWy2uVAWImhB1j2LmvMT7HS7psZ6nNeC0S9JIuxFReu5hl9ZXRJj7J3lHJLG9ZBkuT+IFR8uD2CoMadJcplhecHV0WjJOLhrcAZb07JqSH23C3iNMg+QtW/88aN+K5PQbhNUvSmJM2yzr/IylVeJOI3uzhBxLhJXiabmsm6hbpGBUwAEfIQDALUsyv2A6fnn82Z3P3rX+LufnS/O9+QW9CxauW7hi64qQW0sBAMnRtrIeTOMeBi3rRHDeAQAgCsnIum3bl2cubz+1/Yc7fvjQloce3Pzgk289ufHIxgtXLiQYKwAgmA6V9VAStzo4XyLgvAAAQBNITNYd5gmJxAcAiE5WZT0WTTZIvBp5tfrDAgAAHUDCsg4AaCGQ9cZpub921qvVpwsAALIPZB2A7ABZBwAAADIGZB2A7ABZBwAAADIGZB2A7ABZBwAAADIGZB2A7ABZBwAAADIGZB2A7ABZBwAAADIGZB2A7ABZBwAAADIGZB2A7ABZBwAAADJGW8p6tVxY0rNrquXDjA50dy3fOJZ2HAAkBWQdAAAAyBgtl/XRge6unI8jz5mW9Wq5IOaLSwGQKGnI+htvvAFZBwAAAFpFW8i6qqytlPW0x0a2HqRIGrK+ZcuW6enppCIEAAAAQCwg682X9WIT5gZuTdKQddu2BwcHq9XqQdAsarVaq0MAAADQLrS9rIuqEbeVc0DF2+03FPU03i5SYSNGkKpQcrKX05KcJT27pkRs1XJhSc+mPuftJT27pvxuRM/6cNVyQSt0IeNzFwXy7JZvHPN7Na8IAB4pyToAAAAAWkVbyLpawy1kvVouuULq73MOWC5255ZvHGOcv1ou+Du8g0cHursk6Q3OrEuy7umyNL7QcW44TtalkfR3ae9kUBF5k751AJ0JZB0AAADIGG0h64FlMGrCWjnAKytxmonD5Ay6yFKTQ0PLYJTMuraX/M0NV8/UpX3KNwz+3bdIqgMDkHUAAAAgY7S1rI8OdHfR1DIn67JxC5PlTDxdWY+d8K5P1v1mfB0NuKWBrAMAAAAZo61lnRSKVMsFklmXytJdr7c2jZkOtkcHnn/Jy0pLFe2JybpxOGVuo7Ua/caALYMJlPVqnyXiR34dyEDWAQAAgIzx/2JBsVrFkEUBAAAAAElFTkSuQmCC" alt="" />

  可以看到,DatabaseFixture中的构造函数只是被执行了一次(IDisposable.Dispose也有相同的逻辑)。因此,实际的单元测试中,我们可以此处构建、管理数据库连接以节省资源的开销。

(五)依赖注入以及输出日志

  依赖注入是一个重要的OOP的法则,用来削减计算机程序的耦合问题。如今已成为许多不同领域软件框架的核心。关于依赖注入的概念,我想大家都不会陌生。这里我列出了几种依赖注入的主要方式:

  • 类型1 (基于接口): 可服务的对象需要实现一个专门的接口,该接口提供了一个对象,可以重用这个对象查找依赖(其它服务)。
  • 类型2 (基于setter): 通过JavaBean的属性(setter方法)为可服务对象指定服务。
  • 类型3 (基于构造函数): 通过构造函数的参数为可服务对象指定服务。

  这里谈到依赖注入,主要是想跟大家分享本人对xUnit.Net的设计理念的一点点理解。我在第一篇xUnit.Net系列文章《[小北De编程手记] : Lesson 01 玩转 xUnit.Net 之 概述》中曾提到过:xUnit.Net的一个改进就是在处理每个Test Case的初始化和清理方法时不再使用属性标签来标记,而是采用了构造函数和IDisposable.Dispose方法。这样做的一个直接好处就是使得依赖注入更容易的运用于xUnit.Net之中。前面例子中各个级别的Fixture,日志对象... ...都是通过依赖注入的方式简单,优雅的被我们所获取到。而对于日志对象,使用者也无需去关注它会输出到哪里(这个是由运行Case的工具<即Runner>决定),我们甚至不用关心它是如何被实例化。当使用不同的Runner运行Case时,Runner会针对xUnit.net的接口去实现一套属于自己的输出方式。下面我们来回顾一下输出接口以及它的使用方式:

 namespace Xunit.Abstractions
{
public interface ITestOutputHelper
{
void WriteLine(string message);
void WriteLine(string format, params object[] args);
}
}
  可以看到,ITestOutputHelper定义了两个输出方法,使用者可以通过下面的方式(构造函数注入)获取到运行时Runner提供的输出对象。而关于对象的实例化,管理等操作都是由运行Case的Runner(程序)来管理的。后面我会为大家讲解如何自定义Runner以及自定义Runner的意义所在,这里就不再赘述了。
     public class SharedContext_ClassFixture : IClassFixture<SingleBrowserFixture>
{
ITestOutputHelper _output;
public SharedContext_ClassFixture(ITestOutputHelper output , SingleBrowserFixture fixture)
{
_output = output;
}
#region Test case
[Fact(DisplayName = "SharedContext.ClassFixture.Case01")]
public void TestCase01()
{
_output.WriteLine("Log here");
}
#endregion Test case
}

  日志对象本身的使用很简单,单独拉出来讲是为了向大家展示xUnit.Net设计的工匠精神(更靠近设计者的意图)。很多框架级别的改变虽小(NUnit使用属性标签标记初始化方法,而xUnit.Net使用构造函数),但是用意颇深。so... ... 我们就慢慢体会吧~~~

这两篇文章主要和大家探讨了以下问题:

  • xUnit.Net 共享数据的方式
  • Test Case的构造函数 & IDisposable.Dispose
  • Class级别的Fixture : IClassFixture
  • Collection级别的Fixture : ICollectionFixture
  • 依赖注入以及输出日志

  关于的xUnit.Net Fixture的基本使用就先介绍到这里了,下一篇为大家讲解一下如何在Fixture的层面上扩展xUnit.Net的功能。到时候,让我们一起来看看xUnit.Net在可扩展性方面有何过人之处?

小北De系列文章:

  《[小北De编程手记] : Selenium For C# 教程

  《[小北De编程手记]:C# 进化史》(未完成)

  《[小北De编程手记]:玩转 xUnit.Net》(未完成)

Demo地址:https://github.com/DemoCnblogs/xUnit.Net

如果您认为这篇文章还不错或者有所收获,可以点击右下角的【推荐】按钮,因为你的支持是我继续写作,分享的最大动力!
作者:小北@North
来源:http://www.cnblogs.com/NorthAlan
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
上一篇:Fragment初学8——Fragment在Android开发中的应用2


下一篇:[小北De编程手记] : Lesson 05 玩转 xUnit.Net 之 从Assert谈UT框架实践