Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mxoS2-0005rW-8A for pgsql-hackers@arkaria.postgresql.org; Thu, 16 Dec 2021 10:57:30 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mxoS1-0003kC-4c for pgsql-hackers@arkaria.postgresql.org; Thu, 16 Dec 2021 10:57:29 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mxoS0-0003k3-NE for pgsql-hackers@lists.postgresql.org; Thu, 16 Dec 2021 10:57:28 +0000 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1mxoRx-0001Vu-MG for pgsql-hackers@lists.postgresql.org; Thu, 16 Dec 2021 10:57:28 +0000 Received: by mail-wr1-x42c.google.com with SMTP id t26so7106051wrb.4 for ; Thu, 16 Dec 2021 02:57:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aiven.io; s=google; h=from:to:cc:subject:date:message-id:organization:in-reply-to :references:mime-version:content-transfer-encoding; bh=ewajvVd8X2EyVyPaRVI/dNMZRLyDvzF2AUVwjKgSZC0=; b=VwKvdrWa3F/3dWZlemo9tEX3KxINYZtfYPGCPe0SaacFfybBWreP5dXAgC/Zlwhgxa yAbrSQSEOXr8hGLbs1NYA51Y4liT61CJsH9+1Eb2u9s0jiKGaZiA6CnRWQ4JxhQ3eIAg NwdMEaeoI/NvPvgLcFcr47KE6QTWgl7vDirT4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:organization :in-reply-to:references:mime-version:content-transfer-encoding; bh=ewajvVd8X2EyVyPaRVI/dNMZRLyDvzF2AUVwjKgSZC0=; b=hRBuc5kRtIbGyW1mxvos7EYQSkX/KXpk73a/mjKW3Wwk+5t4YrPEn8bXxthYF2zP2Q 1fhzz0aGjb7+miIcK8J09Fen4zM5+AUxbkTQ2oyMezxpHgyQxqNXU9nL2upnjnErWVk2 2IWV/dMtD+V+2blx9rieZRzezCVrvAL/qGFQnxsRO2SNiSoD3rUeOm1mjsppc9ldnML0 bl66T0ggwD0cRnwNJZgM53Mxsyz9TYE18SWH+i6l5sdetp8YuNlxdnZ+d/xuA9BuQxf4 W5tZL1sGMBPJGyy1I+5gVAA68Hi/xpuQiqqMJw6OdpbBcp8vYE3YflGB8b8XlXV5D6Ms Ti0g== X-Gm-Message-State: AOAM531uklajYUbeGkTSyQ+83zxQjPvjCwT7GD6cxk3BpbfqiqCS7IzM oS4iY7o2JEFJE8p2PGFqb9QGtZaDHSTe5Q== X-Google-Smtp-Source: ABdhPJwlGmwRkHGEaj5Tx3OWZ7g/UQRushk4wvGO/qOEzZ2Viy5OdC/1cpvs8/i3hvpdkjsCTAJ7KA== X-Received: by 2002:adf:ee4a:: with SMTP id w10mr8682896wro.232.1639652243455; Thu, 16 Dec 2021 02:57:23 -0800 (PST) Received: from aivenronan.localnet (static-176-158-121-96.ftth.abo.bbox.fr. [176.158.121.96]) by smtp.gmail.com with ESMTPSA id j32sm4210370wms.40.2021.12.16.02.57.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Dec 2021 02:57:22 -0800 (PST) From: Ronan Dunklau To: David Rowley , pgsql-hackers@lists.postgresql.org, Tomas Vondra Cc: Andres Freund , Tomas Vondra Subject: Re: Use generation context to speed up tuplesorts Date: Thu, 16 Dec 2021 11:56:15 +0100 Message-ID: <2740198.88bMQJbFj6@aivenronan> Organization: aiven In-Reply-To: <567d1ea7-bfeb-bd97-1a7f-b13d2770258c@enterprisedb.com> References: <8046109.NyiUUSuA9g@aivenronan> <567d1ea7-bfeb-bd97-1a7f-b13d2770258c@enterprisedb.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart1851823.6tgchFWduM" Content-Transfer-Encoding: 7Bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --nextPart1851823.6tgchFWduM Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" Le mercredi 8 d=E9cembre 2021, 22:07:12 CET Tomas Vondra a =E9crit : > On 12/8/21 16:51, Ronan Dunklau wrote: > > Le jeudi 9 septembre 2021, 15:37:59 CET Tomas Vondra a =E9crit : > >> And now comes the funny part - if I run it in the same backend as the > >>=20 > >> "full" benchmark, I get roughly the same results: > >> block_size | chunk_size | mem_allocated | alloc_ms | free_ms > >> =20 > >> ------------+------------+---------------+----------+--------- > >> =20 > >> 32768 | 512 | 806256640 | 37159 | 76669 > >>=20 > >> but if I reconnect and run it in the new backend, I get this: > >> block_size | chunk_size | mem_allocated | alloc_ms | free_ms > >> =20 > >> ------------+------------+---------------+----------+--------- > >> =20 > >> 32768 | 512 | 806158336 | 233909 | 100785 > >> =20 > >> (1 row) > >>=20 > >> It does not matter if I wait a bit before running the query, if I run = it > >> repeatedly, etc. The machine is not doing anything else, the CPU is set > >> to use "performance" governor, etc. > >=20 > > I've reproduced the behaviour you mention. > > I also noticed asm_exc_page_fault showing up in the perf report in that > > case. > >=20 > > Running an strace on it shows that in one case, we have a lot of brk > > calls, > > while when we run in the same process as the previous tests, we don't. > >=20 > > My suspicion is that the previous workload makes glibc malloc change it= 's > > trim_threshold and possibly other dynamic options, which leads to > > constantly moving the brk pointer in one case and not the other. > >=20 > > Running your fifo test with absurd malloc options shows that indeed that > > might be the case (I needed to change several, because changing one > > disable the dynamic adjustment for every single one of them, and malloc > > would fall back to using mmap and freeing it on each iteration): > >=20 > > mallopt(M_TOP_PAD, 1024 * 1024 * 1024); > > mallopt(M_TRIM_THRESHOLD, 256 * 1024 * 1024); > > mallopt(M_MMAP_THRESHOLD, 4*1024*1024*sizeof(long)); > >=20 > > I get the following results for your self contained test. I ran the que= ry > > twice, in each case, seeing the importance of the first allocation and = the > > subsequent ones: > >=20 > > With default malloc options: > > block_size | chunk_size | mem_allocated | alloc_ms | free_ms > >=20 > > ------------+------------+---------------+----------+--------- > >=20 > > 32768 | 512 | 795836416 | 300156 | 207557 > > =20 > > block_size | chunk_size | mem_allocated | alloc_ms | free_ms > >=20 > > ------------+------------+---------------+----------+--------- > >=20 > > 32768 | 512 | 795836416 | 211942 | 77207 > >=20 > > With the oversized values above: > > block_size | chunk_size | mem_allocated | alloc_ms | free_ms > >=20 > > ------------+------------+---------------+----------+--------- > >=20 > > 32768 | 512 | 795836416 | 219000 | 36223 > > =20 > > block_size | chunk_size | mem_allocated | alloc_ms | free_ms > >=20 > > ------------+------------+---------------+----------+--------- > >=20 > > 32768 | 512 | 795836416 | 75761 | 78082 > >=20 > > (1 row) > >=20 > > I can't tell how representative your benchmark extension would be of re= al > > life allocation / free patterns, but there is probably something we can > > improve here. >=20 > Thanks for looking at this. I think those allocation / free patterns are > fairly extreme, and there probably are no workloads doing exactly this. > The idea is the actual workloads are likely some combination of these > extreme cases. >=20 > > I'll try to see if I can understand more precisely what is happening. >=20 > Thanks, that'd be helpful. Maybe we can learn something about tuning > malloc parameters to get significantly better performance. >=20 Apologies for the long email, maybe what I will state here is obvious for=20 others but I learnt a lot, so...=20 I think I understood what the problem was in your generation tests: dependi= ng=20 on the sequence of allocations we will raise a different maximum for=20 mmap_threshold and trim_threshold. When an mmap block is freed, malloc will= =20 raise it's threshold as it consider memory freed to be better served by=20 regular moving of the sbrk pointer, instead of using mmap to map memory. T= his=20 threshold is upped by multiplying it by two anytime we free a mmap'ed block. At the same time, the trim_threshold is raised to double the mmap_threshold= ,=20 considering that this amount of memory should not be released to the OS=20 because we have a good chance of reusing it.=20 This can be demonstrated using the attached systemtap script, along with a= =20 patch adding new traces to generation_context for this purpose: When running your query: select block_size, chunk_size, x.* from (values (512)) AS a(chunk_size), (values (32768)) AS b(block_size), lateral generation_bench_fifo(1000000, block_size, chunk_size, 2*chunk_size, 100, 10000, 5000) x; We obtain the following trace for thresholds adjustments: 2167837: New thresholds: mmap: 135168 bytes, trim: 270336 bytes 2167837: New thresholds: mmap: 266240 bytes, trim: 532480 bytes 2167837: New thresholds: mmap: 528384 bytes, trim: 1056768 bytes 2167837: New thresholds: mmap: 1052672 bytes, trim: 2105344 bytes 2167837: New thresholds: mmap: 16003072 bytes, trim: 32006144 bytes When running the full benchmark, we reach a higher threshold at some point: 2181301: New thresholds: mmap: 135168 bytes, trim: 270336 bytes 2181301: New thresholds: mmap: 266240 bytes, trim: 532480 bytes 2181301: New thresholds: mmap: 528384 bytes, trim: 1056768 bytes 2181301: New thresholds: mmap: 1052672 bytes, trim: 2105344 bytes 2181301: New thresholds: mmap: 16003072 bytes, trim: 32006144 bytes 2181301: New thresholds: mmap: 24002560 bytes, trim: 48005120 bytes This is because at some point in the full benchmark, we allocate a block=20 bigger than mmap threshold, which malloc serves by an mmap, then frees it=20 which means we now also raise the trim_threshold. The subsequent allocation= s=20 in the lone query end up between those thresholds, so are served by moving = the=20 sbrk pointer, then releasing the memory back to the OS, which turns out to = be=20 expensive too.=20 One thing that I observed is that that effect of constantly moving the sbrk= =20 pointer still happens, but not as much in a real tuplesort workload. I have= n't=20 tested the reordering buffer for now, which is the other part of the code u= sing=20 generation context. So, I decided to benchmark trying to control the malloc thresholds. This=20 result is on my local laptop, with an I7 processor, for the benchmark=20 initially proposed by David, with 4GB work_mem and default settings. I benchmarked master, the original patch with fixed block size, and the one= =20 adjusting the size. =46or each of them, I ran them using default malloc options (ie, adjusting = the=20 thresholds dynamically), and with setting MMAP_MMAP_THRESHOLD to 32MB (the= =20 maximum on my platform, 4 * 1024 * 1024 * sizeof(long)) and the correspondi= ng=20 MMAP_TRIM_THRESHOLD if malloc would have adjusted it by itself reaching thi= s=20 value (ie, 64MB). I did that by setting the corresponding env variables.=20 The results is in the attached spreadsheet. I will follow up with a benchmark of the test sorting a table with a width= =20 varying from 1 to 32 columns. As of now, my conclusion is that for glibc malloc, the block size we use=20 doesn't really matter, as long as we tell malloc to not release a certain=20 amount of memory back to the system once it's been allocated. Setting the=20 mmap_threshold to min(work_mem, DEFAULT_MMAP_THRESHOLD_MAX) and trim_thresh= old=20 to two times that would IMO take us to where a long-lived backend would lik= ely=20 end anyway: as soon as we alloc min(work_mem, 32MB), we won't give it back = to=20 the system, and save us a huge amount a syscalls in common cases. Doing tha= t=20 will not change the allocation profiles for other platforms, and should be = safe=20 for those. The only problem I see if we were to do that would be for allocations in=20 excess of work_mem, which would no longer trigger a threshold raise since o= nce=20 we're in "non-dynamic" mode, glibc's malloc would keep our manually-set=20 values. I guess this proposal could be refined to set it up dynamically=20 ourselves when pfreeing blocks, just like malloc does. What do you think of this analysis and idea ? =2D-=20 Ronan Dunklau --nextPart1851823.6tgchFWduM Content-Disposition: attachment; filename="add_tracing_to_generation_context.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="add_tracing_to_generation_context.patch" commit eb883bc52d6938d965870714e513ec00d18b05b0 Author: Ronan Dunklau Date: Fri Dec 10 15:51:54 2021 +0100 Add tracing to generation context diff --git a/src/backend/utils/mmgr/generation.c b/src/backend/utils/mmgr/generation.c index 2c98877953..b61a9c024d 100644 --- a/src/backend/utils/mmgr/generation.c +++ b/src/backend/utils/mmgr/generation.c @@ -41,6 +41,7 @@ #include "lib/ilist.h" #include "utils/memdebug.h" #include "utils/memutils.h" +#include "pg_trace.h" #define Generation_BLOCKHDRSZ MAXALIGN(sizeof(GenerationBlock)) @@ -278,7 +279,7 @@ GenerationContextCreate(MemoryContext parent, &GenerationMethods, parent, name); - + TRACE_POSTGRESQL_GENERATION_ALLOC_CREATE(); return (MemoryContext) set; } @@ -313,8 +314,9 @@ GenerationReset(MemoryContext context) #ifdef CLOBBER_FREED_MEMORY wipe_mem(block, block->blksize); #endif - + TRACE_POSTGRESQL_GENERATION_ALLOC_FREE(block->blksize); free(block); + } set->block = NULL; @@ -335,6 +337,7 @@ GenerationDelete(MemoryContext context) { /* Reset to release all the GenerationBlocks */ GenerationReset(context); + TRACE_POSTGRESQL_GENERATION_ALLOC_DESTROY(); /* And free the context header */ free(context); } @@ -458,6 +461,7 @@ GenerationAlloc(MemoryContext context, Size size) blksize <<= 1; block = (GenerationBlock *) malloc(blksize); + TRACE_POSTGRESQL_GENERATION_ALLOC_MALLOC(blksize); if (block == NULL) return NULL; @@ -596,6 +600,7 @@ GenerationFree(MemoryContext context, void *pointer) dlist_delete(&block->node); context->mem_allocated -= block->blksize; + TRACE_POSTGRESQL_GENERATION_ALLOC_FREE(block->blksize); free(block); } diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d index b0c50a3c7f..0531ff03c8 100644 --- a/src/backend/utils/probes.d +++ b/src/backend/utils/probes.d @@ -91,4 +91,10 @@ provider postgresql { probe wal__switch(); probe wal__buffer__write__dirty__start(); probe wal__buffer__write__dirty__done(); + + probe generation_alloc_malloc(Size); + probe generation_alloc_free(Size); + + probe generation_alloc_create(); + probe generation_alloc_destroy(); }; --nextPart1851823.6tgchFWduM Content-Disposition: attachment; filename="malloc_generation.stp" Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="UTF-8"; name="malloc_generation.stp" #! /usr/bin/env stap # http://developerblog.redhat.com/2015/01/06/malloc-systemtap-probes-an-example/ global sbrk, waits, arenalist, mmap_threshold = 131072, heaplist global trim_threshold = 0 global context_creation_sbrk = 0 global cnt_sbrk_more = 0 global cnt_sbrk_less = 0 global palloced_mem = 0 global pfreed_mem = 0 global sum_sbrk_more = 0 # sbrk accounting probe process("/lib*/libc.so.6").mark("memory_sbrk_more") { sbrk += $arg2 cnt_sbrk_more += 1 sum_sbrk_more += $arg2 if ($arg2 < 0) { printf("sbrk_more called with %ld", $arg2) } } probe process("/lib*/libc.so.6").mark("memory_sbrk_less") { sbrk -= $arg2 cnt_sbrk_less += 1 sum_sbrk_less += $arg2 } # threshold tracking probe process("/lib*/libc.so.6").mark("memory_mallopt_free_dyn_thresholds") { if ($arg1 != mmap_threshold || $arg2 != trim_threshold) { printf("%d: New thresholds: mmap: %ld bytes, trim: %ld bytes\n", tid(), $arg1, $arg2) } mmap_threshold = $arg1 trim_threshold = $arg2 } probe process("/home/ro/dev/postgresql-install/bin/postgres").mark("generation_alloc_malloc") { palloced_mem += $arg1 } probe process("/home/ro/dev/postgresql-install/bin/postgres").mark("generation_alloc_free") { pfreed_mem += $arg1 } probe process("/home/ro/dev/postgresql-install/bin/postgres").mark("generation_alloc_create") { palloced_mem = 0; pfreed_mem = 0; cnt_sbrk_more = 0; cnt_sbrk_less = 0; sum_sbrk_more = 0; context_creation_sbrk = sbrk; } probe process("/home/ro/dev/postgresql-install/bin/postgres").mark("generation_alloc_destroy") { printf("Palloced mem in generation: %ld\n", palloced_mem); printf("Pfreed mem in generation: %ld\n", pfreed_mem); printf("Sbrk moved: %ld\n", sbrk - context_creation_sbrk); printf("Sbrk calls: More: %d Less: %d\n", cnt_sbrk_more, cnt_sbrk_less); printf("Sbrk bytes more: %d\n", sum_sbrk_more); } # reporting probe begin { if (target() == 0) error ("please specify target process with -c / -x") } --nextPart1851823.6tgchFWduM Content-Disposition: attachment; filename="bench_results_5tests.ods" Content-Transfer-Encoding: base64 Content-Type: application/vnd.oasis.opendocument.spreadsheet; name="bench_results_5tests.ods" UEsDBBQAAAgAABVWkFOFbDmKLgAAAC4AAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi92bmQub2Fz aXMub3BlbmRvY3VtZW50LnNwcmVhZHNoZWV0UEsDBBQACAgIABVWkFMAAAAAAAAAAAAAAAARAAAA T2JqZWN0IDIvbWV0YS54bWyNUkFuwjAQvPcVkcs13hgQJVYSpB56QuqllXpDrr0Et4kdOQ7h+SWG UFqhqjevdmZnZtfZ6lBX0R5dq63JCaMJidBIq7Qpc/L68hQvyaq4y+x2qyVyZWVXo/FxjV5ER6pp eemUqnKy877hAH3f035GrSthmiQzKEEJL+K9xv6enBkDOSedM9yKVrfciBpb7iW3DZpRgn9jebB1 qpW8SDWdq4KQkoAVDqQWGGUwYg+VNp+3nLE0TSF0R6i19gIcXJzyjjHmcKpHtNwJ5/+ksAQC6DI/ NP8b+rztEPv8vjrRjBTjPYbtFFnYUYkGnfDWFWv97vA5AOCBTumcsslam+6weVsuNot5dAXYNM5+ oPRHy5PHTlcqZhn8mpfBDzW49ReKL1BLBwicOykjIgEAAEkCAABQSwMEFAAICAgAFVaQUwAAAAAA AAAAAAAAABMAAABPYmplY3QgMi9zdHlsZXMueG1snVXLktsgELznK1zKWUaykqqYsr23fEBq8wEs QjIVxKgAPfL3AWRpkUurpXK01d309MzA5WVsxKFnSnOQ1yQ/ZsmBSQoll/U1+f36M/2RvNy+XKCq OGW4BNo1TJpUm7+C6YMlS42p1oW5JndjWozQMAzHoTiCqtHrL+S+pYaNBiUz+k6UAYCFAC2Tk74n nbI8Qx40M8a7acSWfn4+n5H/OkM1Vby1XjolMRDNNZakYRobit0xs38corGvevqn4kyUD/pi66HB xpYp7uhEYFtA2uiUS8MUtDhgh3IlNFu+T1mWI4tIWW/V9IwWYHN6HK7qJewKOlkSYxu0aWSyGCiE BmpVlpvRWQsFqpHVJWnP2fB1sazI8Fl3HGbGG/Im2C4hOyMPWgaACPofhToaXimEhUIV23SoLO80 82TXvDEVy3Vx+dFfNVkVZbSAxa5tu6Dirfteh/zd4L+h6feqV7GHefBqNyCWOmqRVpBSaFrbzieZ UXD55+Ntdl+D6obd8gbF7f4ty+86E737z220h9Hdw9zULUm+D/DnQT6Nqtue+Hkhg72KQ7ru6+ga +/qDJvj7NVbGg1cVvAfVdkr4iEqKmGCOpVF+zJfrXrVmJ9XvSLEW3FX/mO3gKSqS2/zuTM8Nul3Q 9kN0+wdQSwcIqKnXKOgBAADIBgAAUEsDBBQACAgIABVWkFMAAAAAAAAAAAAAAAAUAAAAT2JqZWN0 IDIvY29udGVudC54bWztW21v47gR/t5fYfiAokVP75ZluUkOty/Jl0tx6G2BfqUlWmZXFgWKju3+ +g5JSaYd2WZi6+IW3QDZHXLI4Tzzwhnae/fTZpkPXjCrCC3uh57tDge4SGhKiux++I9vj9Zk+NPD H+7ofE4SPE1pslriglsJLTj8PYDVRTVNFohxSun9cMF5OXUcWuJCLbEpyxzf9VxHMg2bFVUV8JZ9 vV7b60Cyfvu7I+YsjjfcabgzlqZ5F7fvuoGTOSniyHoheP1Ds2Kz4MvOFV4cx46cbVjnlC0398MV K6a7Y08LtMTVFG9KzIjQGOVTSmGBRdO5RUB5RsvpboOpRK6WXZEjZ/Wcfz7/8luywEsEe1QcFQlu VrGSH4fPDR2GS7rDL01a5nLFcsmWJg7OsThs5Xi216Inga8VRBWpat14IvVtTDrVmHVtqpfMdC2w gmMsS8TJLMf6JilDa9NdBC94n75cOIPpcsGrrwW3TE4AO3ISlCetsnybY2N1BfOBqPVJUWtGwHEa 9iXmyFSW4N3zsZwU34/7t5jd+bepkE2VW3N6xIQnwxt0U3TLLSlTwXXM7TlMkJo7TJDueQuamRtR Muuri9VyhpmxbMg8r/1gbq44rPPbQAVP3Hk6y9p0O6erAiRBiu7KS2LZdG+HV2icNl7sSCY9WM8l c8HT8Of0HYeuTa7tsGd+ujyaQkUSxi8iy7UeTnCemmVwai2rw/QtVu/n7/R8/m6DGPHFkTicOM8w KX89/6LfNqbecXixVAkjpXEiVNx7iokNqyO6+Y6aHg5q/LSiIBg+NBUAWnEKOpPEkm5fPdypgKnj Ro0OVEiI090P/+YOD5gGNbUkhbRFButSkhEOZ/OGzsOd07Hnw53a9LWAZOEN64E5WpJ8K4ZErdEs yRgqF3DiEoyOGSe4Ggj/ha0Y/Q4bFLTAUqwm4ZQ4/7Q4SenC1J0qkLNKWhEuUeVshZt9GOUyUCxU ZCJ1ueI0akpcZ/pecwpuAQVYRf4NjF5Q8vYwzbAFroGKY5Miu+d4U0+/Qevgalo7bzLMAMqKegQO n1PIzT/MAvEzVNxzkucNbzvQsuKx+DEG1D0FaOfkDlD3bYCO3gUoKZJ8lWJrQdIUF1aC8xzCZo7y CtQ/4WnalFJVH+YMI27hZcm3zY45Ri/YylDZ8DCSLbjy0NRCG1ztrGmqcditcT0oq3j5T0vLHCfB SElV5mhr5WiG832VcpohKLcWS5IcwMOwSG0YUg7DiYKonpe1I9RO2JoBIN/bcXU/cbaF46EM0hXU p9acsIofbC3qLkvTQ4BNVyw5gBttSKUZyD0ZEcfd/wZ9evx/C/+PWzjq+/KLjW+/+ITWnXOt0vHb dJ68ub44aVJTsfG1g+mc877xYn592UIjGE5u8rL13P86MOfzke/imwTzSMF902CmgW9eV/+eYB5p J24YzDCKUy+5STCPdCk3DGaEofn2bhLMIx3KDYM5CRI0n98kmEeaH1ONK5qT9HrNsPGxj1T076p9 Ok6UyD+vT+QcfW+qJ2Y03baEPNPDnXIy+VueYk1S8TrnjZOlQm6BRRML9Z8YkK/k0wXD8/uhbTc0 35YCbSLM3FTzSY6qqtZ8OkOsGdedX7xCNSfghAsgQSA4SmiPgkY+wOfagTpP1xY+bCFblPIhhF6l 4gNrMMNFshj8KUclp+WPAxL9+c6pee4cTV4jPMcZLtKBTmiVN1DD5mSeb49DXzubb8ehwkqaol6M NyUq1FPgAuDrPrksbNVEmVNuIWivOhkhp6g3d/HOYDEo+iHi0pRhgfAfEZz0r0r1qtF9idh3NWH/ 7E3PsTyNmwOqPCPTi7VAlWohQciM8sUOAzsIPA0Cz/ajsKEb//Fs1/UOfSiyw5HgbN2OUpaSAnFs MZwBXI0I3w78YE/EKBodinBBRHwoYmyPYzHYQivayrYxXuLaKptGY4VxyQjgsbU23ZYK62FKqWpT lceLQGt0EVOpUKRKUI5b6QkMZZSJGL/AhP5ZE/6sMtRO5dPqb7vV33arP+6OUtcehbofQNQqe3Tt Ee3C9Nuvv50Ox4yRtHOTyUF2WaJ/UXZE8Qqz3SW6v03cbPOC8hWurPfY5NN5m3xqw0qGkRJjLuB8 3H7yjmbbBgUZ0CUlBW/feUoMPpmCuTTgFFgG0Ime8GLsPp/H7vNF2H0+j93nD8DOuwJ2X85j9+Ui 7L6cx+7LB2DnXwG7r+ex+3oRdl/PY/f1A7ALroDd43nsHi/C7vE8do8fgN3oCtg9ncfu6SLsngxq vJ6wW6M870Yu3NVg8xwKvW4uvW5pq2AoFWSxJH/XhZNakVMoryz13Ys9LmuBUYqZaJJWy6Lan1OD QtDbVnQONudRH7TXjNYOK6XR2c1q6YyuDyZg5EAs+EJTPL3aWs0djLTfRxA+Wxer0F6SIttVYc+o 4pjtCjHZZ2bQo0Ixl+IqebhKgQItarPfndOIuKoGg78MnsEHackv0MWoYOhTl0eywengAg2Mru3+ NbiGMYxu0T5VeYIQvOD8RjdZ3+e/iiWM7hVTTZxXSa4rG3fmQ5MMaQLMN1DCuwAPo0b8mpaFixPx 4d4MXMaeb48C7dlL0pdkcpNetne1PC/27Cjc6VUPXJLWTRrN/hXz45HtjzXF1MAl2d6kC+xfsSCK 7Imml6QvyfwmDVrvakWuZ4dafCn6kgvBpHf6Hdwwmtix7oWCvuR2MGlr3n87XC3j+9pr4xXxDKLA HmmfPii6H1njsWtDK9rKUnRPsqL9bKXofmRFfrgnS9H9yBpNIluDUJI9IRjHtqsjKOmTsnp0/6An 9/che2hKKrofWaHv2pH+QZ+ke5IVhrb2YYUke3ITd2S72vWp6J6c34M7TENQ0X0hOLJHsQ6hoD/K /XuKcT+e7BUJiu7JeFCARJosRfeVJcd2EOppUtA9yYphby0AFN1TugrHdqTFtaJ70msc7900gvwo 9+/LdKOxHev5RNL9yJpMQnui5RNF9yPLc+PAnmiK1QM9SfO8yB4HessrB3q6bwIoQ7QQUHSPOIYH MJ72xTPvQ+oZSB9qPzeov8rUfP/pgFTfemqow/+O//AfUEsHCHOIIQ/7CAAAzz8AAFBLAwQUAAAI AAAVVpBTAAAAAAAAAAAAAAAAGAAAAENvbmZpZ3VyYXRpb25zMi90b29sYmFyL1BLAwQUAAAIAAAV VpBTAAAAAAAAAAAAAAAAGAAAAENvbmZpZ3VyYXRpb25zMi9mbG9hdGVyL1BLAwQUAAAIAAAVVpBT AAAAAAAAAAAAAAAAGAAAAENvbmZpZ3VyYXRpb25zMi9tZW51YmFyL1BLAwQUAAAIAAAVVpBTAAAA AAAAAAAAAAAAGgAAAENvbmZpZ3VyYXRpb25zMi9wb3B1cG1lbnUvUEsDBBQAAAgAABVWkFMAAAAA AAAAAAAAAAAaAAAAQ29uZmlndXJhdGlvbnMyL3N0YXR1c2Jhci9QSwMEFAAACAAAFVaQUwAAAAAA AAAAAAAAABwAAABDb25maWd1cmF0aW9uczIvYWNjZWxlcmF0b3IvUEsDBBQAAAgAABVWkFMAAAAA AAAAAAAAAAAaAAAAQ29uZmlndXJhdGlvbnMyL3Rvb2xwYW5lbC9QSwMEFAAACAAAFVaQUwAAAAAA AAAAAAAAABwAAABDb25maWd1cmF0aW9uczIvcHJvZ3Jlc3NiYXIvUEsDBBQAAAgAABVWkFMAAAAA AAAAAAAAAAAfAAAAQ29uZmlndXJhdGlvbnMyL2ltYWdlcy9CaXRtYXBzL1BLAwQUAAgICAAVVpBT AAAAAAAAAAAAAAAADAAAAG1hbmlmZXN0LnJkZs2TzW6DMBCE7zyFZc7YQC8FBXIoyrlqn8A1hlgF L/KaEt6+jpNWUaSq6p/U465GM9+OtJvtYRzIi7KowVQ0YyklykhotekrOrsuuaXbOtrYtisfmh3x aoOlnyq6d24qOV+WhS03DGzPs6IoeJrzPE+8IsHVOHFIDMa0jggJHo1CafXkfBo5zuIJZldRdOug kHn3ID2L3TqpoLIKYbZSvYe2IJGBQI0JTMqEdIMcuk5LxTOW81E5waHt4sdgvdODojxg8CuOz9je iAym5V7gvbDuXIPffJVoeu5jenXTxfHfI5RgnDLuT+q7O3n/5/4uz/8Z4q+0dkRsQM6jZ/qQ57Ty H1VHr1BLBwi092jSBQEAAIMDAABQSwMEFAAICAgAFVaQUwAAAAAAAAAAAAAAAAgAAABtZXRhLnht bI1Ty27bMBC89ysEJleKIiXLFiEpQA89pWiBOkBvhkyuFbYy6ZJU5P599XSc1IfcxOHMzs4ulT+c j03wAtYpowtEwwgFoIWRStcFetp+wRv0UH7KzeGgBHBpRHsE7fERfBX0Uu14baVsCvTs/YkT0nVd 2MWhsTVhURSTmsjKV/hFQXeHZsUgLlBrNTeVU47r6giOe8HNCfRiwV+5fGxrOktxsTq1thmNpCDQ wCByhIaULNxzo/TvW53RLMvIeLtQjTEX4tDFlHeJkZDpfGGPp49GmGc3hpi/rwYeo3KZ7pC1zMfE wkLlewbupwclixjFlGGabqOMrxLOsjDO0ihL02ydkxuKXAr+XkopTzY8YeGKsTVLkmyVk4U2uYJU vl88lq0da5Xft/HXVfRjtvjv+q1K/BUNuDJ5x57hiVuDhl5sbPmo9ha+jcHJOmRhEtL7R6Xb8+7n Jt2lSXBF2J2s+QXC97u4/9yqRmI6m7zWm+pfHqjzfYvOKxGMuK/2DWBhWu0LxNAECmiaBUsW0OwH pwWmiMyVWwcWSzgoDXJiDjsv0B+rxLOHs0fl0tQ1tczJm+2SW39S+Q9QSwcID7dLvLcBAACHAwAA UEsDBBQACAgIABVWkFMAAAAAAAAAAAAAAAAKAAAAc3R5bGVzLnhtbO1bbY/buBH+3l9hKGjRApUl 2Zvs2s160fbu2gKXoEhy6McDLVEyEUoUSHq9e7++wzdZkiVZ67U31956gyTiPJwZ8pkZUjT3/d1D Tif3mAvCilsvmobeBBcxS0iR3Xo/ffnBv/HuVr97z9KUxHiZsHib40L6Qj5SLCbQuRDLkmMBjUhq HVteLBkSRCwLlGOxlPGSlbhwXZeHfZbarGmPhZjLW28jZbkMgt1uN93Np4xnwZdPgZL5Ej/IwKF5 uccqI8ZNjZ+F4duA45Jx6dBJXIHLLacalsQBplg5JoJoGlWa4w3icuxgNLg+CnGfje0LUD9meQkz saa4riThaDdWi8ICZfXuaqLGdlfYel/GWDwwsVdBjGhcDVbFwujhKnDL1G7Q1I4TibmD51iisbYU tm7qgZLia1dsRYvFItBSB03ZWCMPgvop66EQBjc4NvNcofXTWMM2JRsBM0/GB8w8aUQLWo8nUYPr vYttvsZ8tG0k0WEcpOMHDv1mVaJCJO4jnWdVjUrZtkhMfTHa8EOJOVEiRHW3ZUPDwWwMk7cINKie rIMdojBQGIfPeJLQrlgE1fMA6hLMkX9P8O6N60HZCcO0QVLT0AgYlve4EAWA8PG9qotVThBMXXxV o+s0ypifC58UkLesXNZ6143nSG56kvEm+ABC/deHH/cpyfOxIaKwjXocc1KOroYG3agcG5l3smUq h5J6EzshtcV07q3cypkyWDVTFGM/wTEVq/cmAarmiXlWbt16PxLIJs3p5DMqgABYJBw0J/Tx1vsD Kpn4SwtnGr1JQ7XC+xkugB4o6WJHhGggSiJj4OEecaLjORh27SOTbNipCjHGnUchcX4Wfybf4XtU oAz6HXetBj6bl0Ef07bdbJncaBKcoi21Gymn2TqrC4sfY0o9By8RRxlH5cYvIaUwlwR2X0YEaNDC Sj8hQqJCLSBQHt/G+X7q1PJ+2FE72hNwKTNiQX5R+sJS6jaKimyLMmjChW6IofpIDj7/9Nlrq/Uh 0VDRDJk9Qml2CKPfCJ0JJ/tl4yTWlhP8/eOhRbUKU/zQGxYt8xW804FKuiFtFyrRvz5q6js4HUO0 ZpTEFcv2uUEVRLKQnH1V/lAGa+yb+dW7t+jKm6jlBMoqpZXkerZI41QTswNVPivNlrxgvnq2XcQG JWznQ1gKLH0YRDidQ7R0CR+dMBgTiCrK0FYyUSIVhSTBzEARLTfIzWG5LWK51cGmvYL8Imo2q/kn BfbXHCPYqsHISVwxo3aCsMn1c5aA+hI4alBKigSrYq7eT7QS5Yd+j0kRFbiaZZcwYs9c16iGk2cr sA87bjVX2rilQPItOGUWWqbMSzWFv98nVH8Bh1qTjihGnOWoGKxF7eSdPSF5KZawaPtfMS/0zJnx HLrjchDBgs9Voep32WH7qqiT7/3vqxKzi1WJodLQZfW5pcHsl+22uVEa7KoWei3QxD7lpNAbqwz6 JSQjUoCL2lCHThfChwa+M/54rYJUW3mC/s7/xEidDwx0nlRpVR0W+E3Dfdmlw9JUs1B/2uE8u7Lh bNrMu2cB+z1E9807TLIN7PfWjCa98WQ01YXaTyt1Kmtyo9UBunVX9Pdor+T9+iuItrCPoSOUWlZ+ noU/R04tbAlKih79BmISncScY/1k5qKbJzDXMT2NWnDzLO76tO+zvlv/U9izkFP4mw3zN/tG/M3O yN/swvx1678kf19gPp9VEgcqLixU+CTd2qnaxsf2aPG+RvHXjKuDhGormcInjvdxiDJWIOqvqS+5 mpsCH8gkiCuZ0sp4og6Fwuk11MKJYJQkkzc3ofrpfzepheFcf3pfRs4RhuGFw7Bb/yXD8AfGZHGe cOlnxpI4hhkiEYVXnPMy45Rejpl+C6cX+EeYSXPIfEFqVOXGhy8BQ0lT0wklQPuIHUZnbQ9kRxJ1 hKde+XoQfU79dtPzs0RyKy61TvyDseQk3datU1aKONYrxZiCHobv3nXsK14L+lDEfMRbyWs6X4hW uwEYQ+ti8Urrk2n9G3rxTFWEjqQ0jjvfAF4pHaL0P0ifmp2F1ldqzkrN95wz/vIro2ZqTL6l+vMs UgfPup5J6ZGzrjMQ+rSzrr/GMfD0bQ4gX0kZJGXg/NEATjx+tJSfkoeWxxfKw99ecd0T33NwaYk/ 7dzyGcQ/4azplfhnET8fJH7+0sQn+jN+IJ+wGP427KXXk+bx06WPZupOnWHlOno698yVa8TZXPfK FbSu4thHNUs5kiT2neDo97Ozvu9nExwTyCEfkiDG4taDmlf75nZY+uTvddUVCB+yjW1lw70PZR55 HaDDawzNKxWU+3K9L5cbjJK2SduWMqbuCTTjXI1hY8MnnF6rK0i6GfEMJBSnqr3ZyC262bpmUqqr iWF1jyno98i68vJeSlZ2uNh0JzjgYAR3s/8j7upfBM2mV4v9F0G1wlOixPzCQTgNoxvXq+OFKlQ/ 1ezUEJBVGT6Ik4OR/voD6Vc6X8ejOugtplaQI1GpqC5X2UalqZEFrfsp9TzoKHHG/eYOZH/rS/9y Q2n/FRuMjY7V3d3d+6DdaFvK1tS04kGR222unYAp4eIY1EzuEff/rabIPqjZMOvBKnIO19oOxmAM tOJ8xBgscngMwQGTx8j9ZH8rZ4Db2UhuTTPHmbpNqEb0VLpNQ7D6o/mfJJLWoeb5Twcz2rDYaNIp 3vIiQdLNgL7XX98/wlZiUoH8e0S36pJTOIv8aOZH77xVGAb6TxhaLxRw9eeJczg/rlqBnOooWl5d L+dvoXJchdc319GNMrHUf6pBdyVCc3z/w9nhKA/qHfT1vdViUe9g2r59NgXdFTTo/qW81X8BUEsH CAqgiXpLCAAA1DcAAFBLAwQUAAgICAAVVpBTAAAAAAAAAAAAAAAACwAAAGNvbnRlbnQueG1s3Vvf c5w2EH7vX8HQmb50gAPud21nmjj2S9x2knSmrzoQd2oEYiSdz85f35UEHJzvDiU19kxenCB9u/tp tfq0EOfizUNOnXvMBWHFpRv6I9fBRcJSUqwv3b8/33hz983VTxcsy0iClylLtjkupJewQsKfDlgX YllyLOAJSe1ky4slQ4KIZYFyLJYyWbISF7Xt8qnNUsc144kQsbx0N1KWyyDY7Xb+LvYZXwefPwZq zpP4QQY1es3TlB5DR6NRHKyDFEnk3RO8+7m2eNjI/KhFuFgsAj1bQzPG84dqPbCAKgdmUfihxJyo 9SC6ZAwMPJZmHoG0cFYu9w7aa3sQ5ATXMPjn7sOnZINzBD6EREWCayte7vOx51FbTgKOS8ZljU6T BlxuOdWwNAkwxYqsCEI/bLKXbBCXthumwe3ViPu1rS1AoWTyEnZ7RXHbScrRztaLwkJdts1VMdia K2zbljGWnEnsOEgQTZrFykeKrZerwAehdmdD7TiBwqnhOZbINpbCdmqMkuLL6fpWs/v6tg3yIKiX sRNbCIs7uzbz3KD1k23g6sx1CiZO7QsmTjvVglb2m6jBbetim68wt44NyvO0DjL7hYNd1BxUqMR9 pfN1I8QZ2xap0dAjuqTMlh0PT7JxfvMWgQa1D+tZg3AUKEyNp+w7SFdb3vLQ2X6Wn5RQJcL4Xqlc U+EE09ROwZmXi0P5VtZd/U779bs5xEhuTpzDeXAHk/rH3Yf2bWNbHYcXi0g4Ka2F0KA7C1MOxYm1 RYGZdp0qf612IXav6t7AeBVBM5BBj+BlKMFeihMqri7McWiGHfOsmF66HwicLV0TzidUQCy4Mmpo TujjpfsLKpn47QBnBl2n41rhvTUuYHtB4MWOCNFBlEQmsDX3iBNd3cF5an8wyc6TahA2dB6FxPmz 8HGu8T0q0Brs+qm1wM/GMji109U42koGx4AknvbTlID+2VlTwsImWMVfKw9cOXSbF25t2R70Sjiq mEuChZOx5Ypj9MVbYahVcKhC1x4r+I6k6kRGfjSZJ7nm36Jzjlv0UtzGfjyKvo1b/FLcYj8afxu1 8UtRm/jTePot3PipcuNsd0AMRtqszJQa3GCy3oDmjvzxRO3ZecJbgT1WSpIj6rWtJd9ie94SHedd D+bQcmDulWiNPWNxjTO0pfJgUa0FmTYnJaKk6LHiU3lTTSn0217OUvBEuSdX9lTX/AnVNUflhiQN l+q5zUZ1D+CMsy/gomAFcNFDGaG0M6CaeQTZ9jaMk69MXeIeomQNt1KCC91Ld3H3KkKyR+UE3hxr bwxyov7iIVHiBLYl3ItwiTjSTA+KU3k+CGmdnL+e5KaJAtkxTc+p7LRS8Swcg5NiXU2sWPq4v+Xh vR2lYoOxvLowtaNayy3Vd7InsFQlU5fV3mdGitSjaIUptBkZogJSbzDqZHC8Bg/cg56MY6Gai2Oo HaFpgngq9sfGTOqfFdAk+FYlQ9TGekHe/gjVdmKDSrVQk1cO8ybFX6ERTDG8+o/cuiL3DnRhN7Xl taf0tsI9XMlSOPHhnUtJgxqsT/y8Pahi1H9/VFoyikJ4riix1b9QjSZYwSTJHj3I8baE5hnUJPM4 KtZY1Ff9xJFYSOF4zgoXySZH/IuZ8H+Plr2QqdMHeRv2enkb9nvp5/K2n8u7fi7v+rm86+fyrp/L dT+X634u1/1crvu5vO/n8r6fy/t+Lu/7udz0c7np53LTz+Wmn8ttP5fbfi63/Vxup/BOpT6yLDcc w9u+H/xpDnFUj8vHEqRCkLzUL9Z6TGzU9yGcr3BaD6FEbuGYX7qs+MBQ2lwLpRLwljpUUgGNxRof jfwRw82eVF//nolMw0GLJjx09bSlylVjd0SIdctfdR+mSfESTGlHUOvupav0qoE64lA1dQexwV/Q sGtsuyOnL5Eju9x3o9iv2XxNqqACbsASQ4bTS3f2vVk5EzXqjRoNEDUewOd318wZn+OXqMPm4wmi W+xV505yaJZcp/44d2QOHOlTf/UZShHq1jx0S1q5f/6Ad/pd4hVCOr86d4hSeFt60eA35AGnziuE fJ3l3kLxvnjA711rj3hN3KMq/5pHNfzfuc0oQ9LtzMBKw8gfx8dpGIOGhYEOQyMMF6E/m1jxqLAD EYkWYz+a2hEx2IGIxLOZP7fjoaHD0JiNQn9iVx8GOtS2zOA113JXFPRHl4NomDzHs9gfR1Z5NtBh aEynIz8cW9Ew0IFozKy1wEAHOoPRxJaGgQ5DYzyf+XZ7opEDbcli4Y8st0RDf3QhGEhw4whE1C7P BjpQexKN/JmdHhnoQDQmE39mx0IhByr90dgf2XUEBjqQDIRwzdttiYEOtSVjf2zXERjojy4EAwlu tJjbNoAGOlDVQXM5s6NhoEPdgVM/tntNMdCBaCzAt50UGOhAl8Rk6s/sdNFAB8rGdGHbmCjkjy4E Q9XceOovLHVfQ4ehMZ9P/Lmd7hvoQC+ko0Xsz+3SUWGH+nISzvypnTJW2IHakxjabTsxMNABN8by Q5KGvoQcHPvnISUDafsXFFq//9b5pYh60PzaRP10+D8nrv4DUEsHCOFQbeaABwAAejEAAFBLAwQU AAgICAAVVpBTAAAAAAAAAAAAAAAADAAAAHNldHRpbmdzLnhtbO1a3XeiOBR/37/C4+uejtR23OJp nYPWj05bawGx5S1A1IwhYZMgMn/9BtRu60jHoszZD30RQvK7N5f7TS6/LHxcmkPGESVX5dNPSrkE iUs9RCZX5aHZObkof2n8dknHY+TCukfd0IdEnHAohJzCS3I54XWXkjGSC0JG6hRwxOsE+JDXhVun ASTrZfXXs+spseXIAiMyuypPhQjqlUoURZ+is0+UTSqnqqpW0qfrqZTSl4kJ9pKzdHJVUc4ry/uX 2endroytdpkytrp+JZqzcmMth/X2G5ervSz/TpCAfiKb0mo4IXZVlizX5whGL1Irb1v3do2FOHIw 1BgEJg3K64ciDuRDRES5oVxWfgT5EPAdHItikEfIE9Nt0KcXSq26N3wPosl0K+uqcna6K/yJD4IT RDy4gN4mKRhtf0npGqkwLN6FYRjdeBtccsGkBpQbiT58jNMEdINPE0iB/IzRt0s+lwTkgpdOSo60 86kP2GwHbWyFjFM2oBwJaQxP2yRfy/dW3yI/b9UZNR90jzL0nRIBsBFgJO6pBzdfxpSyPfQdMoHc otA3uF9L6JD2+pr/AvA1V6A5TNF1QCYZ4snpDdb8HtiHrWH1LAezJ+5hffkatUmFoP4BgW1KfVOi HFSjE1AL4HATdWnkSl4ZgAlMPO276LWc4MaURl2GNp24QymGgJQbgoUwp3FI50sZ9Ey4EA8yyRhj Gt3BCXDjLFpjgHkGsS2D7weqrOjQZSCY7pKe7BAQLgoLCNWcPuMYEI4B4RgQjgHhfx8Qsh6nJcau dpwWHxnVzTKO7O3nXEYxdgB7p5w8z1kcHBX6b4VOCDRlWT0bMJjUpTkUbhcyNmQ05Z8f3noS/D4V RUEXY/IJaotiyraqS7V2Vq1+zllWv3mtBQilB7jkPPSJTqMeBB5kxRAxphAK6WkKQL/hD6HAiEAj 9h2KuQE34/tBiKQa35PZA04yCOkd2yRxnJnqtIeR3XCDgMCkOuACbirVIQgsgeWelq24wijokEvl yqwspCfN6e024bf3m/aEN0LHQ3PEM9k/EPh25vOqzhJeWyBuxDIVYZSg79la+u/Oc1ZN3+0TOBS7 t/WXAyEDiTZ9pL+vYbnvgcyWxFfqtABxIS5A1kGA4yGH7BoIUAB8KGgLYDfEQGQ6g/zwrSlgwJVK 2aJ+wCBPdP7gKVvbd6CncQSIzDZRIDoy8ywg2KRkkn1guCie0LvYe3jnFPxO6vovENYDSVW3sL0U mHz9J5Kj69WnUUNaYUHZyi1kJDW9QUhcEYIt7abDEPolid6vCqCFZ3l3iMyGgSd9enYP8ywnNAWe Li2CSuMugPM0nkLWlzdZjQlIIENuaTVzLzIDEEDWYdSXChVudvEOuJ2t8IDD2nkTEcDicsPXer9X FA87vhWD0f1k2PsaOETH7kT7R/6GitcxcdOwfj51pGn3Wvj4cn+jdeyh/J85cszwVaR3O8qzoS1a pCn3/lmxn25UvWqF9tPX4DluPro+Dr2uFbd8VT635HVHASM1HFjNuUv0+HmElZbfn7tdjN3vyiK5 drqLqdcdqrbf4W51eOuMOrFdxeHzSP/Te+orToJzrUR31xq/b0XRco0a210r8roT9f7b463b63P7 ycaOnCd5m9m+jj0ff7PNNY10fhWM+nhgarfDTrP9WFUTXs+9ti7pt2+H3Q6xrX4A/WHN7FpKsg+5 d0Nr9wem1WxaHbVtWc173ZqOzaHa1h8vNL1nRY7EMEfqzDZpzaza/rHaO1Z7r8ENMIfmNPQdAlAB ZUcCby3PTT2QFqa8CN0pri1XcC+xyLZc4W3WmAiwMNJgqsPx9tzgj3zYy5QjiacmlHXSgUrKrKNT ywKmlQ6tyvcPnaPa/Uu5zKHeSUjSHD7DjA/2WT/noa8dOM/IA/f7/pTZlan8cPyyknUwtfEXUEsH CGhJO2+iBQAA2ioAAFBLAwQUAAAIAAAVVpBTAfdqCd4KAADeCgAAGAAAAFRodW1ibmFpbHMvdGh1 bWJuYWlsLnBuZ4lQTkcNChoKAAAADUlIRFIAAAC9AAAA/wgDAAAAk5knZQAAAeZQTFRFJSUlKysr NDQ0PDw8fgAhcEklQkJCS0tLVFRUW1tbUU1qZEtgal92Y2NjbGxsc3Nze3t7AEWFI1+WKGKZPnCg Q3WlV50cWZsfWpwgXqAiYo4mY5EoZKEcY6MsZ6UzaKY0aqg2ep7AgBAyiRc1iho2hC1PhS5Qj0Bg plFmpltzzEMm/kIO/ksS70sg5VQx8Ewh+1Ml/1Yo/2E2/mY9rbkljr1nk8Btm8R4rsNX/oUe/r4d /YZX/4dY/Zlv8M8m/s4n/88o8dAn/tIg/dMt/9Ux/9k+/817g4ODi4uLk5OTm5ubg4CsoqKiq6ur s7Ozurq6iqfEiKjGm7bPnbfQnbjQp7vOqsqPrs6SsdGWtdObutaig8r/kc78lNH/ndT+tcncu8nW oNb/qtn+st3+xJGO+56E+6KC8q+d+6iR9rOh+ril/7yq8ca7/8a3/8y+/+eF8eed/+2l/+6sw8PD y8vL09PT0Nfd1Nnf29DU29bY2d7T29vbytjm19vg0d3p3dzhyuHzy+j/3OPo1ez+3ejx5dfT6NfS 6N3T/9rQ5OPU6OPT7uLe/+La/vTM//bT4+Pj5Obo6urm7Ozs4urx4vL/6vX+8u/u/+vl8fft//vr 8/Pz9vj08/n/+Pb1//31/v7+AAAA////HeDAOQAACLNJREFUeNrtnYuX20YVh7M22BpgZkQDmxRo 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 ZXN0LnhtbFBLBQYAAAAAFAAUACcFAAD9NAAAAAA= --nextPart1851823.6tgchFWduM--