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 1m3MhW-0008TG-Bj for pgsql-hackers@arkaria.postgresql.org; Tue, 13 Jul 2021 18:00:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1m3MhU-0000Yz-Rm for pgsql-hackers@arkaria.postgresql.org; Tue, 13 Jul 2021 18:00:08 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m3MhU-0000Ym-75 for pgsql-hackers@lists.postgresql.org; Tue, 13 Jul 2021 18:00:08 +0000 Received: from mail-lj1-x22d.google.com ([2a00:1450:4864:20::22d]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1m3MhR-0004gd-B7 for pgsql-hackers@postgresql.org; Tue, 13 Jul 2021 18:00:07 +0000 Received: by mail-lj1-x22d.google.com with SMTP id h9so15958797ljm.5 for ; Tue, 13 Jul 2021 11:00:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language; bh=/nUSBFZD4dhxf+zLMH0scOIscvZHGAv/5vKMTWLM95M=; b=qXhcGIlX8pY5rV9akFY7PpT5kAFkAppDEz0Crog4h5Xb4y2YnF+H4kxxNb7I/E0ZqC bt5Ljsxx4pV5oyXBJqsY+mxZXOSHQmRmsedDlyqa3Aqi6kCD7KXanzwlIUvylvbauavr WGBtKYb+sD8IRXz9DCsHIODX14hYvxJtmwNoPsz8UytgjF5DedRmjVGRYR6mDRFUZvsU o2Ma4m6E9Qmf/nQlo+D3N8HtZeFdQx6XT+11dQQ6w2jjKddwLjjTs2gXmePUqrEgdQnO xQ0MXa0Q6hwFaetcpnwCG7vCM3R/yoftzIkT4JYiT+PGFvz8kfuSqZt2KAhjhb0N63i2 RqTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language; bh=/nUSBFZD4dhxf+zLMH0scOIscvZHGAv/5vKMTWLM95M=; b=a9lvvCRBSmRZNqWK8aC+/w7ATc8KfQv2cvLFUkIRl7tfqM9fkxPzM7o+NelBNdFG0w nU5jzR9IzhCj09J+FiCdFqNLvyOc/ZxDr9iIv6/PaT/odhrlDLoWgpM364yefbesDC6A PwU8RDEI/M0ItkPr1Amwwz0Uv8W/FsN0JvNnO7V6sEfsNkS0HhKM285UQQOZ0X7CkfE8 KVng5o17LBr+T3Ayo7ilFW2W298S6PY/Zm8UKAy7eg0liXZWa3R/hKO3Ak6ck6QY9ZDh bD+k2c2kI86VwYfAXDY07ziyYQPEAHOBKKlUXVG5ojqydjp1V1O4jVY2GSBiVBPCtw54 n/cg== X-Gm-Message-State: AOAM5328TL8Wvq78fXx5goMeYDhimmFKInKgR1TAuFOGLv1QpE1MW9fj atWDz0dvPGcqmzEj+QleGGY= X-Google-Smtp-Source: ABdhPJyW6Nirpy5g9dBeLgjV4K7MqggKtX+6dkiQ7qdRV0si9uuNYAjywwbEc7JBdLrGVj7LerElJA== X-Received: by 2002:a2e:5c2:: with SMTP id 185mr5327484ljf.186.1626199203456; Tue, 13 Jul 2021 11:00:03 -0700 (PDT) Received: from [1.0.0.7] ([178.155.6.217]) by smtp.gmail.com with ESMTPSA id a5sm1626835lfj.190.2021.07.13.11.00.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 13 Jul 2021 11:00:02 -0700 (PDT) Subject: Re: More time spending with "delete pending" To: Michael Paquier Cc: pgsql-hackers , Tom Lane , Justin Pryzby References: <20729794-e2bf-bd7a-f01b-d132f89fd0d7@gmail.com> <78fa6a17-8e71-7c99-62bd-8a11a47fe894@gmail.com> <2aa7ce7a-d73a-fa36-4fb5-3affe1860c58@gmail.com> From: Alexander Lakhin Message-ID: <62c17068-a608-800f-295e-9d2cca5decf7@gmail.com> Date: Tue, 13 Jul 2021 21:00:00 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------CF0D29502F9E9607BC75947E" Content-Language: en-US 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. --------------CF0D29502F9E9607BC75947E Content-Type: multipart/alternative; boundary="------------423577E4CF318AEEEE154EAD" --------------423577E4CF318AEEEE154EAD Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit Hello Michael, 12.07.2021 08:52, Michael Paquier wrote: > On Mon, Jul 12, 2021 at 02:09:41PM +0900, Michael Paquier wrote: >> And fairywren, that uses MinGW, is unhappy: >> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=fairywren&dt=2021-07-12%2004%3A47%3A13 >> Looking at it now. > I am not sure what to do here to cool down MinGW, so the patch has > been reverted for now: > - Plain stat() is not enough to do a proper detection of the files > pending for deletion on MSVC, so reverting only the part with > microsoft_native_stat() is not going to help. > - We are going to need an evaluation of the stat() implementation in > MinGW and check if is it possible to rely on it more. If yes, we > could get away with more tweaks based on __MINGW32__/__MINGW64__. I've managed to adapt open/win32stat for MinGW by preventing stat overriding at the implementation level. Thus, the code that calls stat() will use the overridden struct/function(s), but inside of open/win32_stat we could access original stat and reference to __pgstat64 where we want to use our. Tested on MSVC, MinGW64 and MinGW32 — the fixed code compiles everywhere. But when using perl from msys (not ActivePerl) while testing I've got the same test failure due to another error condition: In this case CreateFile() fails with ERROR_SHARING_VIOLATION (not ERROR_ACCESS_DENIED) and it leads to the same "Permission denied" error. This condition is handled in the pgwin32_open() but not in _pgstat64() yet. I think I should develop another test for MSVC environment that will demonstrate a such failure too. But as it's not related to the DELETE_PENDING state, I wonder whether this should be fixed in a separate patch. Best regards, Alexander --------------423577E4CF318AEEEE154EAD Content-Type: multipart/related; boundary="------------84CE7663300E0D1A611766D4" --------------84CE7663300E0D1A611766D4 Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: 8bit
Hello Michael,
12.07.2021 08:52, Michael Paquier wrote:
On Mon, Jul 12, 2021 at 02:09:41PM +0900, Michael Paquier wrote:
And fairywren, that uses MinGW, is unhappy:
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=fairywren&dt=2021-07-12%2004%3A47%3A13
Looking at it now.
I am not sure what to do here to cool down MinGW, so the patch has
been reverted for now:
- Plain stat() is not enough to do a proper detection of the files
pending for deletion on MSVC, so reverting only the part with
microsoft_native_stat() is not going to help.
- We are going to need an evaluation of the stat() implementation in
MinGW and check if is it possible to rely on it more.  If yes, we
could get away with more tweaks based on __MINGW32__/__MINGW64__.
I've managed to adapt open/win32stat for MinGW by preventing stat overriding at the implementation level. Thus, the code that calls stat() will use the overridden struct/function(s), but inside of open/win32_stat we could access original stat and reference to __pgstat64 where we want to use our.
Tested on MSVC, MinGW64 and MinGW32 — the fixed code compiles everywhere.

But when using perl from msys (not ActivePerl) while testing I've got the same test failure due to another error condition:



In this case CreateFile() fails with ERROR_SHARING_VIOLATION (not ERROR_ACCESS_DENIED) and it leads to the same "Permission denied" error. This condition is handled in the pgwin32_open() but not in _pgstat64() yet.

I think I should develop another test for MSVC environment that will demonstrate a such failure too.
But as it's not related to the DELETE_PENDING state, I wonder whether this should be fixed in a separate patch.

Best regards,
Alexander
--------------84CE7663300E0D1A611766D4 Content-Type: image/png; name="ghffjapimnefdgac.png" Content-Transfer-Encoding: base64 Content-ID: Content-Disposition: inline; filename="ghffjapimnefdgac.png" iVBORw0KGgoAAAANSUhEUgAABwcAAACICAIAAACN7XMKAAAACXBIWXMAAA7EAAAOxAGVKw4b AAAgAElEQVR4nOy9fWxc15XgecoSSStfKypJJzZmDMmsogbssvwReQao6jZiCxFQpDpDZO3C zmZn2HE6VVnMGiy7h3AyKwyEgB5D0La2Cs5gmoXeIJwebwYVx+B0m/UAG7IbnrCQjZV4166w Q1bJYjvbSS/sUIodRxJl6e0f7+t+nHvfrVefJM8PglC879x7zzn3892691bMtm0gCIIgCIIg CIIgCIIgCILYNezttwJE7/jWU6cNJb8x9/jw8HBXlSEIgiAIgiAIgiAIgiCIfhGjvaK7hx/9 +DwavueWWyAGN2/afmX49CdHx8bGeqgaQRAEQRAEQRAEQRAEQfSOW/qtQFex8rG85f3RLKVj sVgsFkuXmpKYj/swCAoSEKX9J3KIRtgPD9SQhIyyUMdC9AAAgLvvuQf9lzxyJHnXkSN33+2H 3LhxQ+VTnGYpLbl1Z6MpI0056uqKg+9Jv74KqfLhqmRcMaH6s2WkLTI2kyBfQV6loWsmI90s pYU/g3bGWuD9aWgjwYAUmYuVj9g2I0fsMm796aNdnfCMqgGa9qUDWDo9USnaWIPEak1bTffO tzehTzPXRxveY3qvRseKNZT2amnvc2wfZmxgKi828irGEXw+EDY/QSbfNJoTBEEQBDGQ7NRV UWcWNllmAmYKyapt23Y1WZiRpqi5qu2wMhsHaJbm68WGbdt2o1if54St/KT7qAqTeQsN0Qh7 ysyXWaGyk30VJp2XfYMspFganT2G98RqP1ydeWrpK6ef/+rZH3zt25Wvl7+35+bWHvtD/9/x x5+N6vPdhFwisv9NSk1Pyolui6XqhyuL2hFLperr7tPmcqVmalyzlE5Usl7WVZhUv8mwGtr2 QsZzz1I5l0tWllnVakiz02BoIwEAIUWWmctWzkR5F40ckVGri8sBHbLLXMlAsm3PdID2rTDG NEpUlfpDK9rK3Tsy4Eqzjg7SF2cOegmq0Wnencbb+xxNsfL+2NAo1id1y5LoOKIcXJDRH82r BQUIgiAIgiD6wk5dFY3Prti2Xc2xYamJBABAZjpXW20w4c31uvvIo7FaS47HAQDi40leOLPg LJwCJCacNSc5RCMMANAszVSSuZQrYy2VU8W5DCMuxWqu11PZqTgAQGauWF+ysFganT1iAABw 22f23f7Zj9z+2Vtv/8y+239vXwxsG4Kz8x+97QO9ZwkArGRl/8sycqmZg5aqsqgdsll/ZbKx Cjm/zulpLleguOgrl1lgljvNaK7Xc9ML09yyaKpYTBaivBmG2EgAAOiLLD57EiKtLEeO2Bv6 aNcgeKZ3OsRnV8x6q0FwizktaCt378iAi806tjXG5b696H0t7We7YKaPEJ9d0Q3m6NDfynwA zasFBQiCIAiCIPrDTl0VlYhPZcFZpLGWyrlp52ttf0NVrZCIxWLeoV92mdRf0BKPxTWXK95b kTIEfWSdKSRPzk14T9broIjkx4qPJ2vuAlNzuVKrrzflWJjOIh9c3QKA0f1Db23+w9++8/bP 3/27tV9vgA3AXC37qTvf8T+n0/l8mj/2FJyESjv7ZVyZREHcichLBieqm6W0k5yQ1DbFKyOd /xkZZVmHZySt3asCGaa8lUlrqZ6dnlALsmkuV8B7h4lGc7mSnM5AYgK43aJTc5F2fYbZSACA osj8XovbrMTdJeI34VjeQs4EMxEDSbRDEA9QpktWaaZQqxUS8o0Q6VKTzVfqCsTbToS4gYHt 29VUKClrwpuj8Ey6ZJXSqOaSx5w+k91iJmw3C3VLB6zgURniKSYpYOZYXbJSjUJAjqovCzeR IKOJ6kYZKx9IKRwoO0bq3k0GXCwhvvRxzeXwkPJFcjEau0sllRvZyqmXVGkREkvRHEysw2Kx tyDlLc5d/CMnvnm3xs1bepqjgJX3hP1enbuHSUl8Kgtm5zTQob+l+QCal7kCBEEQBEEQfWLX rIpCfHYxW0nEYrH5icaCt11vIQMAjdWaexSoka0kFC9nnjAAODPYRCFZ1YUA/sjKT4IglYIl +cWQi5VZqCaddduZ1WRKE0tPLAYA8Nrfr9n7fjvy8WsjH7s68tGrNsCb9Z+9Wf/ZG2/WAeAT o5tBhFp9YpE99tQszfgnobIVZ57ryDSK/D5EUTKx4NxcYDkXGSxksKS2G5pCV8m0VmreYn0s FoslVk/623b88EQlu6jdy+OuTFpL9exUN1YWWQ39N19nUZT5IsIlPnvSfLuouY2EkqDXYjYr WWecu0QaRXBKw23mc+vpSaj6xyTd921ulxPSIbj3knghbOJL44vFVKrYWJmNM5JBX+HnK3YF goZMXyHtw2vbrvgsp6RGE9YchWcaRSjMg/OhstxE/MP4IWRPoV4Ztxm1b4UIboiDVC6mjlUn K9YozA9CLg2AWmF1mr1eQzYZiwUAYOVj8xMN2xYLkde2W8ilrxoHhfDlKV35YhiN3bIbFZVT IykO/Uax1M3BxDpEz8yC7dIo1udZdwmP3AQNuzXPut7nKJGZK/onTqC8ZPF7MHXEZ1cazty3 w99AI6M/mlfXFCAIgiAIgugQu2ZVtFlKz8Cibdv2IszwM7PgMHN8Kmu06SM+u2LbjYn5YGlL DkGFm6X5unuEOgB9MRQS9ObZK9NQ08QKIwYAQ/uu7731+tDI9aGRraGRLfdcvUfxodPBH96c Oz6VTZWXrOZypeZNhBOFWq2y3AhkOGTJprO0O+kuEGIC2w5NoatkWiu14N6uRjFVXrLk8LCX +PhUFlYb1lI58h5VUw1t71xdc7lSK0/iBZtZqJoeJDS3kTDC36yUmEiVJ2Ox9PKUe5jRacLN 5Qr4fRN7wQOzy0nuELwoXtcpJe7AJe7h5yt2BXwi7GalxIS0ZNAJu3wl9Zoos2a6QbY/lP3D KoPYEkGZ9q3gQQ1xkcvFzLGaZIUahfpByCUBkOLrkmyyhcWqFRKxyXLuJN+f9PDOR7n00SFV E44+QvtTo7FbcqOqcmokNahjKZuDiXWonvKe00AefWTUrfUtRwT3ogZrqV6sFutLFjRWjTdx Onc7KC7Vjwwy+qvy6o4CBEEQBEEQHWK3rIoyb9bSFjYJ9ibD4PYwSUpaQtUsqjqPLH/Kn/CO W8XHk+wMOSxB9xC2HMtMZwCAvbc666HXhke2hoav3bThruTvH7kreeSu5I2bN69cvYZHc48L +j9LZdvOq6YSXjLu6A4Q2CMJbEtM/B/IqMs6JJfZkzl00cBAvfr8fN25MwJAOqWLxghpH1qa y5WkX7DcTjMAcN4MZ86sen/yZ0/psHxUTIos2Ba3Ytu2fXI1YbjPHL8UDy+plhMHAKkraC2R jtrVmiZdvi7QSJn2rTDGNJ2Ibmmr7ZsMTLkq9nWUibZy924+4EbVXGNRi0Nny2N3f4kwMeB+ zydl9qiVbm0QcoTMdK6+XlqqZ6cy48n6urVeb7nWBZfqYyMvOvRHng9IF/grAwmCIAiCIPrN blkVFa7mZGeTzVLae8WzzhQgOxVnZoziOg0j7KYjh6iFM+4X5rbd8I9bZaa9U8XKBIMQ60yh lpvOgBxLo3NADABgeGRraGRraHhr79DW3qHrMbgZi7n7RW3bvnHjRiDvzV/dPNj9PIyWmLtl SfeMmLtXwDypgQQpdMn/iIxcauZkpiMvi0It6S+KBi2hsar4UXrhGrDgPjMTmssVCCof8kYV nz2ZLJe9rPmfUmpvdWE3Y1Zkmbls5UyplI6lS03ILDSKqfq67/z4VNY/mC3eWJeZy1bOLGMd AsidV2jiPHJXICQCQd+tqLRt22WoCfI2z6cgmyb4RwgBab3N3C2dtMIMsVyMHatBqFGygFx8 sv6yyWis1EQC4rOL8rqogbby8Goy4Kpt8UpfMQ5qxkfDoTPC2C2rZ2BICxg1h8h6erUH6SJU j8K7tb7liJKZThYK9eyUM5OYLDDDuhrOi9ZS2a2q6MiLDv0tzAfQvBQKEARBEARBDBL2Tqaa Y/YdBDdl5arCU/+RfyQomrAXohN2cFZFRc08ZTVZIPZIsbjNFgy/ef/Kh9e3fvXLX7L/Pnj/ vWtXr1z53Qfvvf/e5uav33333d9du762tmbbdiqVSona86r5ZgT2+Lazko1iivWkE1nlm+2B QZ3BLEQKkgdxqf8AclU5XIEs5oe4OuhSYfe45ND7znJV+Qa0VLGYE5J1tOaVaRRT/OUAQfyG SnkiDKTI+A7QDykWmWaN90Ry9azmAEDuEBpFIYQPcBLMVQX9nC5B1avIqQbPUykxbifsCp7o NWHMET3Dt1n2g9JjqZTXiSqsC3NLJ63wdEMN8f6UFDBzrC5ZeYiR4XNhS1btK02sRjEl5Rfa L+u6dz6S3Oh4D/OlrxxSRYvYUgsbOnHHqjJCqytTFfWSKi1C0lc2B6OJgaYRufECd0mPWMK6 NWCado9zVJgtTUjZP+QPnEP5moqNvPg4YjAf4KupkJdCAYIgCIIgiEEhZts2EB3GyqfX5wbv UPjl96+OjOw1kfzFxlvj4+PpdGlx8KwgCKIPOFczt98hWPnY0nTo/Zbd1YEYBKg0u0QvHdtO cx4E9L7qhnW9z5EgCIIgCILQsltO0PeWzMJAvultXXnvFxtvmfzbv39/v5UlzLHyMQHzI+/t xCUIQ5hqNin/4BzRFwaw7Q+CSp3SoWe2SBnJv//TvRzd5tw9Y3tfJXrfWfXSnwRBEARBEIQI 7RUlCIIgCIIgCIIgCIIgCGJ3QXtFCYIgCIIgCIIgCIIgCILYXRjdMknsDL711GlDyW/MPT48 PNxVZQiCIAiCIAiCIAiCIAiiX9AJ+l3Ej358Hg3fc8stEIObN22/Mnz6k6NjY2M9VI0gCIIg CIIgCIIgCIIgesfOPkFv5Zkr6pultHNrfbrUlMR83IdBkHTHvf/IfyKHaIT98EANhRArI+sj h6gNdLn7nnvQf8kjR5J3HTly991+yI0bN9AUlDRLaVWuOxRNNZDLKChYTV1x8D3pF6eQKh+u /AkGR0yo/mwZaYuMzSTIV5YPbOafMfFRtenHIzoOUmQuVj5i24wcscu4VbGPdnXCM6oGaNqX DmDp9ESlaGMNEqs1bU2GYC/YoG9rt/S7TO/V6FixhtJeLe19ju0jD8diLQ3+RMcRfD4QNj9B Jt807hMEQRAEMZDs1FVRZxY2WWYCZgrJqm3bdjVZmJGmqLmq7bAyGwdolubrxYZt23ajWJ/n hK38pPuoCpN5Cw3RCHvKzJdZobKTfRUmg8kzKyPrg4VoDQQAGN4Tq/1wdeappa+cfv6rZ3/w tW9Xvl7+3p6bW3vsD/1/xx9/tlVf70bkkpVLBCl9RVmrSDnRbbEm+uFS9eSjp1L1dfdpc7li /LPEzVI6Ucl6WVdhUvEmY+Vjk+A2nEa2kmDW8P34jWLdr/msOba9QL9D3jm0RZaZy1bORHkX jRyRUauLywEdsstcyUCybc90gPatMMY0SlSV+kMr2poMwfKso4P0xZmDXoJqdJp3p/H2PkdT FMMxBjqOKAcXZEBH82pBAYIgCIIgiL6wU1dF47Mrtm1Xc2xYaiIBAJCZztVWG0x4c73uPvJo rNaS43EAgPh4khfOLDgLpwCJCWfNSQ7RCAMANEszlWQu5cpYS+VUcS7Diwsysj6ohioDPWIA AHDbZ/bd/tmP3P7ZW2//zL7bf29fDGwbgrPzH73tA9ShBIdcsnKJyDJ4WZsh1URlYEA2m6ws O7WusQo5vz7paS5XoLjoK5dZwFcwnVUB70l8dqWaLDhvfs31eio7FffCaf2z++iLLD57EjSr 52oiR+wNfbRrEDzTOx3isytmvdUguMWcFrQ1GoKxWce2xrjctxe9r6X9bBctDMfo0G84H1Dn RfMBgiAIgiAGnp26KioRn8qCs0JkLZVz087X2v6GqlohwRwDZpdJ/QUt8Vhcc7nivRUpQ9BH 1plC8uTchPdkvQ5yJElG0AfREDFQ5IOrWwAwun/orc1/+Nt33v75u3+39usNsAGYq2U/dec7 /ud0Op9P88eegpNQaWe/jCuTKIg7EXlJK+87t5R2khOS2qZ4JYvVGUQGKWvTjKS1e1Ugw9R0 0qsT9ez0hFqQTXO5At47jF5MqO2JiVR5yQKnrSm2KxPdQVFkfq/FbVbirtrwm3AsbyFngpmI gSTaIYgHKNMlqzRTqNUKCflGiHSpyeYrdQXiZSBC3MDA9u1qKpSUNeHNUXgmXbJKaVRzyWNO n8luMRO2m4W6pQNW8KgM8RSTFDBzrC5ZqUYhIEfVl4WbSJDRRHULjpUPpBQOlB1jMgSbIJQ+ rrkcHlK+SC5GY3eppHIjWzn1kiotQmIpmoOJdVgs9hakvMW5i3/kxDfv1rh5S09zFLDynrDf q3P3MCkxH47Rod9wPqDJi+YDBEEQBEEMPLtmVRTis4vZSiIWi81PuBvcMgvOt9aN1Zp7FKiR rSQUL2eeMAA4M9hEIVnVhQD+yMpPgiCVgiV+hozIRDJQJBYDAHjt79fsfb8d+fi1kY9dHfno VRvgzfrP3qz/7I036wDwidHNIEKtPrHIHntqlmb8k1DZijPPdWQaRX4foiiZWHAO9lvOOf+F DJbUdkNT6CoZqay1eIv1sVgsllg96W/b8cMTleyidi9PYgIqy02wlurZKc3qaTSEBdn4eNL7 NLvScOoi94bHmkPXi/WCoNdiNitZZ5yrNhpFcDb3us18bj3tX4gQXPDA7XJCOgT32g4vhE18 aXyxmEoVGyuzcUYy6Cv8fMWuQNCQ6SukfXht2xWf5ZTUaMKao/BMowiFeXA+VJabiH8YP4Ts KdQr4y6wtG+FCG6Ig1Qupo5VJyvWKMwPQi4NgFphddo7kDtfaiImY7EAAKx8bH6iYdtiIfLa dgu59FXjoBC+PKUrXwyjsVt2o6JyaiTFod8olro5mFiH6JlZsF0axfo86y7hkZugYbfmWdf7 HCUyc0X/xAmUlyx+D6YOxXDcPsiAjubVNQUIgiAIgiA6xK5ZFW2W0jOwaNu2vQgz/MwsOMwc n8oabfqIz67YdmNiPljakUNQ4WZpvu4eoQ4QZsioTFsGBsQAYGjf9b23Xh8auT40sjU0suWe q/coPnQ6+MObc8ensqnyktVcrtS8iXCiUKtVlhuBDK+MJNmEzEI1WZh0FwgxgW2HptBVMuGL ACzBvV2NorsPUwgPe4mPT2VhtWEtlSPvUdUgHN5vrteZjGdXnHdI5pJb7hoyOkbXY/zNSomJ VHkyFksvT7mHGZ0m3FyugN/vsBc8MLuc5A7Bi+J1nVLiDlziHn6+YlfAJ8JuVkpMSEsGnbDL V1KviTJrphtk+0PZP6wyiC0RlGnfCh7UEBe5XMwcq0lWqFGoH4RcEgApvi7JJltYrFohEZss 507yfWYP73yUSx8dUjXh6CN06DQauyU3qiqnRlKDOpayOZhYh+op7zkN5NFHRt1a33JEcC9q sJbqxWqxvmRBY9V4Eyc2HLcPPqCjeXVHAYIgCIIgiA6xW1ZFmTfr4Ki5Cva2xuD2MElKWkLV LKo6jyx/yp/wjlvFx5PsDFklI+gjh5gbuPdWZz302vDI1tDwtZs23JX8/SN3JY/clbxx8+aV q9fwaO7GQP9nqWzbedVUwkvGvVWzwEGSwLbELXRtnQlk+LI2fzuIz57MoYsGBurV5+frwZUK oT+gEd4+PDHBgsZqTb65QXnJLdFJTIos2Ba3Ytu2fXI1YbhjF78UD7+6oeXEAUDqClpLpKN2 taZJl68LNFKmfSuMMU0nolu0l4GEYTIw5arY11Em2poMwZ3WXGNRi0Nny2N3f4kwMeB+zydl 9qiVbm0QcoTMdK6+XlqqZ6cy48n6urVeb7nWBcMxf+uDcx8EOvQbzgd0eYUFEgRBEARB9Jvd sioaH0962w7ECxGbpbR/dP1MAbJTcWbGKF7cyAi76cghauGM+4W5bTf841aZaf9HapQysj5S iMbAgBgAwPDI1tDI1tDw1t6hrb1D12NwMxZz94vatn3jxo1A3pu/uimy+3kY2zB3y5LuGTF3 r4B5UgMJUuhSiSAyYlm38kqTmY68LAq1ZLBa6VeUxqriR+mFa8CC+8wEsdmTyYJ/4USzlJ50 tzhz5Wktldta7CCMMCuyzFy2cqZUSsfSpSZkFhrFVH3df0ONT2X9g9nijXWZuWzlzDLWIQBf oZsmifPIXYGQCARdm6LStm2XoSbI2zyfgmya4B8hBKT1NnO3dNIKM8RyMXasBqFGyQJy8cn6 yyajsVITCYjPLsrrogbaGgzB4SClrxgHNeOj4dAZYeyW1TMwpAWMmkNkPb3ag3QRqkfh3Vrf ckTJTCcLhXp2yplJTBaS6PXxAorhmP+hRnddHx36DecDyrxoPkAQBEEQxDbA3slUc8y+g+Cm rFxVeOo/8o8ERRP2QnTCDs6Kp6gZu0mCl5H0MQoR+M37Vz68vvWrX/6S/ffB++9du3rlyu8+ eO/99zY3f/3uu+/+7tr1tbU127ZTqVRK1J43yFcx0NW3nZVsFFOsJ53IKt9sDwzqDGahoqwD EJf6DyBXlcMVyGJ+iKuDLhV2j0sOve9MKGQ+NeZWOs9O6bq0bVnqAwxSZHwH6IcUi0yzxnsi uXpWcwAgdwiNohDCBzgJ5qqCfk6XoOpV5FSD56mUGLcTdiEVGtWEMUf0DN9m2Q9Kj6VSXieq sC7MLZ20wtMNNcT7U1LAzLG6ZOUhRobPhS1Zta80sRrFlJRfaL9sPuDKjY73MF/6yiFVtIgt tbChE3esKiO0ujJVUS+p0iIkfWVzMJoYaBqRGy9wl/SIJaxbA6Zp9zhHhdnShJT9Q/7AOZSv qUyWTI7YOGIwH+CrqZCXQgGCIAiCIIhBIWbbNhAdxsqn1+cG71D45fevjozsNZH8xcZb4+Pj 6XRpcfCsIAiiDzg3F7ffIVj52NJ0xHtlO6UDMQhQaXaJXjq2neY8COh91Q3rep8jQRAEQRAE oWW3nKDvLZmFgXzT27ry3i823jL5t3///n4rS5hj5WMC5jcStBOXIAxhqtlklB+TI7rAALb9 QVCpUzr0zBYpI/n3f7qXo9ucu2ds76tE7zurXvqTIAiCIAiCEKG9ogRBEARBEARBEARBEARB 7C5oryhBEARBEARBEARBEARBELsLo1smiZ3Bt546bSj5jbnHh4eHu6oMQRAEQRAEQRAEQRAE QfQLOkG/i/jRj8+j4XtuuQVicPOm7VeGT39ydGxsrIeqEQRBEARBEARBEARBEETv2Nkn6K08 c0V9s5R2bq1Pl5qSmI/7MAiS7rj3H/lP5BCNsB8eqKEQYmUU+nAGIinz3H3PPei/5JEjybuO HLn7bj/kxo0baAoED+d/TcXQlKxIs5R2nvn1VUiDD1f+BIMjJlR/Nlc/I3VsMV9ZPrCQf8bE R9WmH4/oOEiRuVh5dUFriRyxy7hVsY92dcIzqgaobZgd1qHD9EQlU/+ExmpNW7kzNx+UzfTR hveY3qvRsWINpb1a2vsc20cejsVaGvyJjiP4fCBsfoJMvmncJwiCIAhiINmpq6LOLGyyzATM FJJV27btarIwI01Rc1XbYWU2DtAszdeLDdu27UaxPs8JW/lJ91EVJvMWGqIR9pSZL7NCZSf7 KkwGk2dWBtFHMhBJWWR4T6z2w9WZp5a+cvr5r579wde+Xfl6+Xt7bm7tsT/0/x1//FmdX/UM yBtdL5D8L5V1s5SeBKdaNYr1SfYNQVNGHCknQVusiX64VD356KlUfd192lyuGP8scbOUTlSy XtZVmFS8yVj5mGeh3chWEswavh+fNZ01x7YX6HfIO4e2yDJz2cqZKO+ikSMyanWxQ+iQXeZK BpJte6YDtG+FMaZRoqrUH1rRVh6CzQfljtAXZw56CarRad6dxtv7HE1RDMcY6DiiHFyQAR3N qwUFCIIgCIIg+sJOXRWNz67Ytl3NsWGpiQQAQGY6V1ttMOHN9br7yKOxWkuOxwEA4uNJXjiz 4CycAiQmnDUnOUQjDADQLM1UkrmUK2MtlVPFuQwvLsgg+mAGCrEkYgAAcNtn9t3+2Y/c/tlb b//Mvtt/b18MbBuCs/Mfve0DVXSCQfR/c72eyk7FAQAyc8X6kgXx2RVv5S8+lfWLP6SM1BmK NVEZGJDNJivLTraNVcgZ5tpcrkBx0a2IAJkFfAXTWRXwnsRnV6rJgvPmx/iC9QLRPfRFFp89 CZrVczWRI/aGPto1CJ7pnQ7x2ZUVv3bpBfvvFnNa0FYegk0H5e2McblvL3pfS/vZLloYjtGh 33A+oM6L5gMEQRAEQQw8O3VVVCI+lQVnhchaKuemna+1/Q1VtUKCOQbMLpN6y5nSsbjmcsV7 K1KGoI+sM4XkybkJ78l6HeRIkoykDwYfS+aDq1sAMLp/6K3Nf/jbd97++bt/t/brDbABmKtl P3XnO/7ndDqfT/PHnoKTUOJ5qXTJKs0UarVCQj4Ani41myUvtbwVPHI3VygvN+AlrbxfQqW0 o4GUVL+Ijydr7gpkc7lS48uIKf6wMlIir92rAhmmppNepa9np81ybS5XwHuH0YsJtT0xkSov WeC0NWQ/NtE9FEXm91rcZiWuubENEzkTzEQMJHveIQhxAwPbt6upUFLWhDdH4Zl0ySqlUc0l jyUKNeC3mAnbzcL7yfat4FEZ4ikmKWDmWF2yUo1CQI6qLwvXlSADgeb+El9K4UDZMdIQbDoo yx5mSx/XXA4PKV8kF11T9coyXSqp3MhWTr2kSouQWIrmYGIdFou9BSlvce7iHznxzbs1bsrR 0xwFrLwn7Pfqupt4AsyHY3ToN5wPaPKi+QBBEARBEAPPrlkVhfjsYraSiMVi8xPuBrfMgvOt dWO15h4FamQrCcXLmScMAM4MNlFIVnUhgD+y8pMgSKVgiZ8hIzIGhMeKxQAAXvv7NXvfb0c+ fm3kY1dHPnrVBniz/rM36z974806AHxidDOIUKtPLLLHnoJrCLwQ64wT0ChCYXq9RnAAACAA SURBVGl8sZhKFRsrs3FG0m4UU1xqc+sz/nGqbGWm1OQSYc+ZNUu8ZGLBuf7AchJfyIgC/Zx3 ZxaqSWdtfWY1yW3KbJZmCuBsB26xZL3F+lgsFkusnvS37fjhiUp2UbuXJzEBleUmWEv17JRm 9TQawoJsfDzpfZpdaTiNjXvDY82h68V6QdBrMZuVpObmN0z/ygfmMg9ul1N/OgSmmUv78Nq2 Kz7LKanRhDVH4ZlGEQrz4HyoLDcR/zB+CNlTqFfG7Sfbt0IEN8RBKhdTx6qTFWsU5gchlwZA rbA67R3InS81EZOxWAAAVj42P9GwbbEQeW27hVz6qiFMCF+e0pUvBtJUpViIGxWVUyPpN2dE B2UsdXMwsQ7RM7NguzSK9XnWXcIjN0HDbs2zrvc5SmTmiu4X9EtlKC9Z/B5MHYrhuH2QAR3N q2sKEARBEARBdIhdsyraLKVnYNG2bXsRZviZWXBwnT3prCM+u2LbjYn5YGlHDkGFm6X5untc PkCYIaMyBvaZxIoBwNC+63tvvT40cn1oZGtoZMs9V+9RfOh08Ic3545PZVPlJau5XHFX93xP JSZS5clYLL08xR2MYiTF1JrLlZo3m04UarXKclOdiCjprD1OumvMmEAf8d6FVqYhuMLTvZMr uK62lZIN7u1qFN19mEJ42Et8fCoLqw1rqazYxNwWwuH95nqdyXh2xXmHZG7x5a4ho2N0Pcbf rCQ1N79hBm2WucyD3eXUlw6B3ayUmJCWDDphl6+kYdckZh14Bth1Ctk/rDKILRGUad8KHtQQ F7lczByrSVaoUagfhFwSACm+LskmW1isWiERmyznTvJ9Zg/vfJRLX9a8obCowSRiMurJTVVO UHajqnJqJDWoYymbg4l1qJ7yntNAHn1k1K31LUcE96IGa6lerBbrSxY0Vo03cWLDcfvgAzqa V3cUIAiCIAiC6BC7ZVWUebMOztKrYG9rDG4Pk6SkJVTNoqrzyPKn/AnvuFV8PMnOkFUyYfo0 5Vgq6/be6qyHXhse2RoavnbThruSv3/kruSRu5I3bt68cvUaHg0/qe1Odk+uJlrZ/ef/tpWz rqdJRJD0lt4CL0sC/Se4FIFdEm2pjCTisydz6KJBaMSpbH1+vu7cGQEgndJFY4S0D09MqOyN 1VqQjYd0iy/RDUyKLNgW12KbxS/F60+HoFGvI3a1pkmXrws0UqZ9K4wxTSeiW7SXgYTBm4wn lKtie1JNtJWHYLNJQjuaayxqcdRzHWviokEgwpjO/Z5PyuxRK93aIOQImelcfb20VM9OZcaT 9XVrvd5yrQuGY/7WB+c+CHToN5wP6PIKCyQIgiAIgug3u2VVVLj2kZ1NNktp/+j6mQJkp+LM jFG8uJERdtORQ9TCGfcLc9tu+MetMtP+j9QoZdT6+PYhsWRiAADDI1tDI1tDw1t7h7b2Dl2P wc1YzN0vatv2jRs3Anlv/uoaFp/KAqdrvFlKx9KlJmQWGsVUfd2f7TKSkqbMpiDHQUIiTbWk d9DM3XCACPSNIH/rTMFZHbTyiUKyGpSEWRmpyExHXhaFWjJYrfRbQmNV8aP0wjVgwX1mgtjs yWTBv3CiWUpPuhthuaKwlsptLXYQRpgVWWYuWzlTMmmzwo11mbls5cxynzoECPpuRaVt2y5D TZC3eT4F2TTBP0IISOtt5m7ppBVmiOVi7FgNQo2SBeTik/WXTUZjpSYSEJ9dlNdFDbSVh+Dw QVlni1f6iiFMM7QZjnpyUw2NJatnYEgLGDWHyHp6tQfpIlSPwru1vuWIkplOFgr17JQza5ws JKUvIREUwzH/Q43uuj469BvOB5R50XyAIAiCIIhtgL2TqeaYfQfBTVm5qvDUf+QfCYom7IXo hB2cdTFRM3aTBC8j6YMYiKTM85v3r3x4fetXv/wl+++D99+7dvXKld998N77721u/vrdd9/9 3bXra2trtm2nUqmUoL2/98EL4QMcNXNVm98lkSo2cIO9+1zFVH27WMlGMcUWB5uj7ODegFcw QXVZP00ZBc9EoUYxBbmqPjKWjhziaqZLhS29HHrfmWgklxpju+cf6bq0vhTYDgYpMqR/qOYg V2SbG94wpW7FedSvDiF4nkqJcTthF1KhUU0Yc0TP8G2W/aD0WMqRCRwjWhfaT3bQCk831BDv T6yjNnCsLlmpRiHwubAlq/aVJlajmJLyU4zBSiU0xiODMudhvvRFzZUWsaUWNurhjlVlhFZX pirqJVVahKSvbA5GY7qmEbnxAndJj1jCujVgmnaPc1SYLU1I2T/kD5xD+ZrKZMnkiI0jBvMB vpoKeSkUIAiCIAiCGBRitm0D0WGsfHp9bkDOczNcfv/qyMheE8lfbLw1Pj6eTpcW27fCyseW pukaSYLY3jhXM/e3Q+iUDsQgQKXZJXrp2O0+vut91Q3rep8jQRAEQRAEoWW3nKDvLZmFgXzT 27ry3i823jL5t3///vaysvL+b5NORvjtKKIlGG+3/Avv7cQlCEOoQxhABrDtD4JKndKhZ7ZI Gcm//9O9HN3m3D1je18let9Z9dKfBEEQBEEQhAjtFSUIgiAIgiAIgiAIgiAIYndBe0UJgiAI giAIgiAIgiAIgthdGN0ySewMvvXUaUPJb8w9Pjw83FVlCIIgCIIgCIIgCIIgCKJf0An6XcSP fnweDd9zyy0Qg5s3bb8yfPqTo2NjYz1UjSAIgiAIgiAIgiAIgiB6x84+QW/lmSvqm6W0c2t9 utSUxHzch0GQdMe9/8h/IodohP3wQA2FECODaCiZg8gI3H3PPei/5JEjybuOHLn7bj/kxo0b GrciNEtpPM8di6Ya+EFIwWrqioPvSb+AhVT5cOVPMDhiQvVny0hbZGwmaL7h4a6xSDXnRDXR iVZAiszFykdsm5Ejdhm36vbRrk54RtUATfvSASydnqgUbaxBYrWmraZ759sbN+toRR9teI/p vRodK9ZQ2qulvc+xfZixgam8bC0N/kTHkWjzAWTyvZvHd8OZW5tZoDWNn4n1CPOZakdU64F7 O0gweHSnXLqdfu9z58vXNF0ulrEyHR/+WmqAfZ4DNEtp49YjdOztax763qqKZZ5vj/slB7YC OCn3pZR7NBC3UoUGj526KuoU/mSZCZgpJKu2bdvVZGFGqoy5qu2wMhsHaJbm68WGbdt2o1if 54St/KT7qAqTeQsN0Qh7ysyXWaGyk30VJoNmwskgGmLm8DISw3titR+uzjy19JXTz3/17A++ 9u3K18vf23Nza4/9of/v+OPPmvp4NyOXrFxnkNJXlLWKlBPdFmuiHy5VTz56KlVfd582lyvG P0vcLKUTlayXdRUmvQ40VB/btm17wfvNXmupnMslK8uuVGbBTTDnV1RHVBGdMEdZZAAAmbls 5UyUMSpyREatLg78HbLLXMlAsm3PdID2rTDGNEpUlfpDK9rK3TsySZBmHR2kX3PogS5BNTrN u9N4e5+jKVbeHxsaxfqk7nUFHUeM5gPuwI3m1YICO5zAY42JebP30k60QWEm1jsi2OsTwXA5 uw4uubILGW0ma+Vjk+DOgRvZSqLTnaxh+p0yJ1ruEWA6HPwVFycXKCO/+vcErgFq3N7VWZwh 1plKds7sJaw7HXvU99ZWsuhtv9TxHjhiy5XKq0u1qIUqNIjs1FXR+OyKs/7CkJpIAABkpnO1 1QYT3lyvu488Gqu15HgcACA+nuSFMwtef5yYcNquHKIRBgBolmYqyVzKlbGWyqmiU4MCcUFG 1lA2B5XhiQEAwG2f2Xf7Zz9y+2dvvf0z+27/vX0xsG2wbe/s/Edv+0CbBgEAWMnKdUaWwcva DKkmKgMDslm/H26sQs6vT3qayxUoLvrKZRbQlcqQrAGguV7PTS9M92MyvuvQF1l89iRoVs/V RI7YG/po1yB4pnc6xGdXzHqrQXCLOS1oK3fvyCQBm3Vsa4zLfXvR+1raz3bRXK+nslNxV48V 3deO6NBvNh/Q5NWCAruH+Oyi9ittRrDtNjgIMzFjezubXad6MCGdtpJ1vk/zWkF8dqWaLHTy O5PW0+9kP99t69og/J2lSxg3wP4PuM3SPJw0VKFbHXu099Zo9KZf6loP3FKFkcurK/WtlSo0 kOzUVVGJ+FQWnCppLZVz087X2v6XBLVCgtlhzy4w+gta4rG45nLFeytShqCPrDOF5Mm5Ce/J eh3kSLyMrCFmjiQj8cHVLQAY3T/01uY//O07b//83b9b+/UG2ADM1bKfuvMd/3M6nc+n+d3W wQbstLNfxpVJFMRvdHjJYP94s5T2N9v38YhHp/BKFqsziAxS1qYZYaveYUvhU14/bC3Vs9MT akE2zeUKeF1nq/oI6SSnM5CYAFoW7TqKIvN7LW6zEnf5ht+EY3kLORPMRAwk0Q5BPECZLlml mUKtVkjIN0K42y68fKWuQLweRIgbGNi+XU2FkrImvDkKz6RLVimNai55zOkz2W9rhW9uQ93S ASt4VIZ4immubdE5VpesVKMQkKPqy8JNJMhooroFx8oHUgoHyo6Runddh69BKH1cczk8pHyR XIzG7lJJ5Ua2cuolVVqExFI0BxPrsFjs9Sx5i3MX/8iJb96tcfOWnuYoYOU9Yb9X5+5hUhKf ygJyPArzKjb0G84HNHmZK7Cr8Ndo9P180AaVwyXSiFiQmZjBdSBhow82Fmg3Xant9fRso8dT ZYeOXC3PZLwo3IgmKOaeGEM6PcEz8ntiYiJVXrIid9oCpukLA7SpOSHl3m3rOEtlbf0pHyrv jtlY/xw2W5DnaaazF6EB+m4XqpOXlJvL6pm0YBqbOxNXdmN4Gan97O3yw1wkoejYhbmZmJS+ KwMA1XtrxMnDAPRL+ndh2S6pNionGy11RHJ5edGZ9L3oejd2qgoNJLtmVRTis4vZSiIWi81P uF9kZRacLzcaqzV3Q3UjW0koys8TBgCnziQKyaouBPBHVn4SBKkULPFdqySDaCiZY2BFLAYA 8Nrfr9n7fjvy8WsjH7s68tGrNsCb9Z+9Wf/ZG2/WAeATo5tBhFp9YpHdHd8szfgbsL3DCI5M o8h/nyNKJhaco/6Wc/J/IYMltd3QFLpKRiprLd4ydywWiyVWT/rf6vjhiUp2UfuljNsPW0v1 7JR+I7EJofowhrkDAbN+b5TsNus/B5yg12I2K1lnnMs3GkVwvsR3m/nceto/+BRc8MDtckI6 BPciDy+ETXxpfLGYShUbK7NxRjLoK/x8xa5A0JDpK6R9eG3bFZ/llNRowpqj8EyjCIV5cD5U lpuIfxg/hOwp1CvjLrC0b4UIboiDVC6mjlUnK9YozA9CLg2AWmF12jsHNF9qIiZjsQAArHxs fqIRHMDDte0WcumrxkEhfHlKV74YRmO37EZF5dRIikO/USx1czCxDtHTu57FyYt1l/DITdCw W/Os632OEpm5on/iBMpLFnBbP3TEZ1cazmSxw99AIwM3mlfXFNjeuF+vmPTzAJrhMmRMkWZi cr+NhYRoJSvJvSK1Yq+rZrs9Hpqd1+0r5gaGMxnHwIk5cYyQY8mdHuYZYT9BfDzJFXFLnTaG UfoNacgzMceg3LtnXdDhuKu6krZOFkI9LE/yr0tS/2w6WxAJn70AiA0QPLcvLGATJG9uXIaT mpTZqmjSgUhlhPs52OWHDmESWMcupYwkpezKPJD31siTh/73S9p3YcwuaV6tmWwoEkGLWDkQ O+k3iinITWcM3diZKjSI7JpV0WYpPQOLtm3bizDDz8yCw8zxqazRpo/47IpwIYUcggo3S/P1 onjhgtC1IjKyhrI5RlbEAGBo3/W9t14fGrk+NLI1NLLlnqv3KD50OvjDm3PHp7Kp8pLVXK7U vHEpUajVKsuNQIZDlmxCZqGaLEy6C4SYwLZDU+gqGbNh1IO5/aSYKi9ZcnjYS3x8KgurDWup HHmPamv6+DOS5nKl5kxGwosXiU50HH+zUmIiVZ6MxdLLU+6ZF6cJN5cr4Pc77AUPzC4nuUPw onidjpS4A5e4h5+v2BXwibCblRIT0pJBJ+zyldRrosya6QbZ/lD2D6sMYksEZdq3ggc1xEUu FzPHapIVahTqByGXBECKr0uyyRYWq1ZIxCbLOeFwTw/vfJRLHx1SNeHoI7RvNRq7JTeqKqdG UoM6lrI5mFiH6qnZLoc/MurW+pYjgrunxVqqF6vF+pIFjVXjTZzO3Q6KS/Ujgw/caF7dUWB7 01itJcfBuLtWDZeWfkyRZmJyjwpYSIhWrYwpens71eOh2QW7+bG5QYSZjOBaMZbU6aEI57ib 63XnQ4ROu530o5hj4JbuWRd0ONz0g9EW7RD939s4uZrgt8K5RyLMZwuCPmGzFwDTVyFxXsSY pkzZT771+R7qZ/Y6SP328wCpY5dTlpNSzvz9VKX31k5NHhC63S9pK4DeLn9eHXoawLQjUg/E zsrqQsZ4htmpKjRw7JZVUebNOnzzGnv9SHB7mCQlLT5qliOdR5Zf3RLeDuj4eJLtWlGZNs0R 2Hursx56bXhka2j42k0b7kr+/pG7kkfuSt64efPK1Wt4NPcLQH+AsW1n8FDCS8a90TFwkCSw LXELXVtnAhm+rM1LLT57MqcfHNXq1efn694lC/xZDFWM8AoVpk9zuZL0i5fbb0Z0A5M+INgW t+LOEA135uKX4uH3J7ScOABIXUFriXTUrtY06fJ1gUbKtG+FMabpRHRL2L3YWkwGplwV+zrK RFu5ezebJLSjucaiFofOlsfu/hJhYsD9jEDK7FEr3dog5AiZ6Vx9vbRUz05lxpP1dWu93nKt Cy7V5299cM6WokN/yxNMOa+wwN1JcAdHq911Kw1ZnomZel+vVetjisrebvR4XHYQMnJ1ciZj gDz3b6zWggm6oFXrnXZr6bdKmFu6bV1bOJ2eputmwWcLSlT+jN4Aw1IO6Mh8j70O0tBFDMqO XZ+Uql1L762mtNNRdKdfar8CRCiOUMTy8tdEHaItzrRXhQaG3bIqGh9Pekve4sUnzVLaP7p+ pgDZqTgzYxRvT2SE3XTkELVwxl2nt+2GvwM6M+1dRq2UkTWUzUGskIkBAAyPbA2NbA0Nb+0d 2to7dD0GN2Mxd7+obds3btwI5L1m4+bBfm/F5Ie5W5Z093i7X1GYJzWQIIUu1RlERizrVl5p MtORl0WhlgwGF7/qNFYVX+AIt48E95mZ69NcrkDQbCK/VxGmGBWZs1mpVErHnEMZjWJwxMwt dm/TnHBjXWYuWzmzjHUIwFfopkniPHJXICQCQWenqLRt22WoCTKb4VOQTRP8I4SAtN5m7pZO WmGGWC7GjtUg1ChZQC4+WX/ZZDRWaiLhXK4vvukYaCtPCdSTBCVI6SvGQc34aDh0Rhi7ZfUM DGkBo+YQWU+v9iBdhOpReLfWtxxRMtPJQqGenXJmEpOFpMk7I+dFa6nsVlX+l0fcdX106Deb D6jzUiiwy2mWZgrJk7NIw9R319q+Tm62yExsfVzsG+WeHMK0slSDUev2quzSmByam5+d95fo 0sgzGRY5VrhiABCfPZks+JecNUvpSe9wYOQXrmjpRzBHOQnpmXWtaCsq78vx/bPJbAGdp4XO XtAGuLQabp3oK8UsEVqaKGoRfzdcM7p5ppl27IqktBVAem/t0ORBNqLL/VJIBdDaxcyrtcVh 1hY05cWtiUZumK1XoQHF3slUc8yad3DlTq4qPPUf+Tv0owl7ITphB2fFU9SMXaDnZQw0VObl 85v3r3x4fetXv/wl+++D99+7dvXKld998N77721u/vrdd9/93bXra2trtm2nUqmUmCKfia9i oKtvOyvZKKZYTzqRQ/UdaCKWiKKsAxCX+g8gV5XDFchifoirgy4V9tudXJWPLuvDdympYjEn JO7Jei5gjEeib8PaMAAgRSa42gspFplmjfdEcvWs5gBA7hAaRSGED3ASzFUF/ZwuQdWryKkG z1MpMW4n7Aqe6DVhzBE9w7dZ9oPSY6mU14kqrAtzSyet8HRDDfH+lBQwc6wuWXmIkeFzYUtW 7StNrEYxJeUX2i/runc+ktzoeA/zpa8cUkWL2FILGzpxx6oyQqsrUxX1kiotQtJXNgejiYGm EbnxAndJj1jCujVgmnaPc1SYLU1I2T/kD5xD+ZrKZMnkiI0jivkAcHCTCz4vhQK7DN5jjCO0 3bXcBuUGgjQiXxKdiZl0ZiGjDzYWSC8wJvZG7PHMskNHLrR71M9k3HQ8lVQdmnJsUg+PbH7R Ou3o6UcxJ7zcO2wdU75yiEpbWYapFVj/HD5bwOZpqEWsN9AG6OeD+T/lvi7L/uNy17aOkDJC /CwWosJFYkGLHbu2wrhJhXZlqnKPOHnob7+kqACsH5BpvdgbKycbrXVEqvKSK1yYXR2rQiFT l74Qs23mB8iJzmDl0+tzg3co/PL7V0dG9ppI/mLjrfHx8XS6tDh4VhAE0Qecu4zb7xCsfGxp OuL9sZ3SgRgEqDS7RC8d205zHgT0vuqGdb3PkSB2Gm28ZA3muBNdKzNX9NfqwfR5O+AWDei7 fyfYwaZ1EPKShu3hnN1ygr63ZBYGsuC3rrz3i423TP7t37+/38oS5lj5mID5aZR24hKEIUw1 m5R/cI7oCwPY9gdBpU7p0DNbpIy6fr293Jy7Z2zvq0TvO6te+pMgdgAD+pLVD8gVg8MOLosd bFoHIS9p2B7Oob2iBEEQBEEQBEEQBEEQBEHsLvYeLfdbBaKHnM/B0XIL/xMEQRAEQRAEQRAE QRBELzmfC5dpHzpBv4v44junj5aN/v+zf/LDfitLEARBEARBEARBEARBEN2CVkV3EX/16Se/ fc959P//+Lmf/tWnn/wP9/7ECfnTn/9Bv5UlCIIgCIIgCIIgCIIgiG6xw1dFz+bghPf58P1w Pgfnc/D8/YjYee/fYwcAAE58wQv5gijsPzo7pgzRCPvhgRpjeF4aGd8W/98JdTo+/+2PP/xf /u+j6P//80/u+29//OG/fv1zTsgX3zmNJ0HwsBVMUzF0JStwAJ5/BA47H/gidpPlw+UqF6TD 5/vYI3DeSVnICIOtYGi+4eHgVkinQXHeyDFu0UQnWgEpMo+z6oLWEzlid/Gqbh/t6oBnVA1Q 2zA7rEOn6YVKxv4JjdWStnJnrure2UGhJX104T2m92p0rlhDaauW9j7H9mEG2WDU1kwG+IFb N/QzcxVO3k9tjIkoN0BhqDoAz+fghCI6nj6L4XwjNHGTvCJgOHNrMwsDz/QObel3i45MKTXl 3oNy7CBoJd9G6WuI0FT5slMp7HQdZ8eCD92lpebZ7xnCY48YTG8chHGnfc1D32pVsczz7XLv 8dgjQYLOK5vvTHE0jID54kAHqxBbe52U+11F22THroo+9gicz8ED/t8H4Ol74VQZjpZh416k A3IeHS3DM5sAB+DR/fDlMhwtw+J+XngMTnmP4Ji7FimGaIQ9ZR49FEidPQavnoOjZTgFzGKZ VmbtNVfbo2U4+hy8fRFeUKXD8Iff3Xs6/sYffndv/P+r/OF39/6T3/6ff/jdvS/80a/+8Lt7 azNX2f//6tNPmjqaZZs3hpYQK5hU1ofvh1PgltHifqaH4ktWxyU3QaeUD97n+dYPZwOx6G/v 954egAdHTU07fD88ezDIGo55yofqU4ajZXjigpvOiTvh1YvwoGf4Cy+5Aq/6ze0lXXTCHGWR AQDAwgbkIw23kSO6dLlD6Ixd5koyku16phO0b4UpxlEiqtQnWtBWnhJgkwRxUOggfXHmwJeg Eq3mXWm8vc/RmLMPwyvPeaP2sfB3WmHgBlAP/Qwzx6TAMTh/LJhaH/0pPMu7aOF1OMjMrg+P AbwOL6DRn4MHHw5ZODCdbxgkjtjSERg3XrzP7B24E20QKdAeEFb6UTD0hkF1bQu5HDvVVQrL Cm0m22IL6lb6nTIHI0JTDRRWxH3oEJwqwxMXgg9KOt48Nb7q6hzPkDF4cIPporW0Ou4YEfWt tqUsutd7vLgRDHnHD8Lbl+CQt554EOBlv6ZFXl6MMMT4RKo2/RlcusmOXRV95vvufCjgEjQA AODli3CIbUsH4KD3yGUU7rgMawAAcPEyL3wBjn7fe+RUaDlEIwwAAI8dg42LnswYPHAJFi4A ALzwEnzptRZkHE58Dl75SYiMw4+/euPJ5pH0h8vNz2Q/P/xff/6x//EL+5878de31WauphZv df7f9/8sphZvpb2ioQgV7PABeHvDLeuF1+GhMVh7LZiFs10hV7LmbMLGKCRMAhleuQzHnXxH AS7C22ZZHT8Ii+dcWwDgCXRaEJY1ABzaDy+/BBsHt+d79bZCX2RrrwFEGtojR+wNfbRrEDzT Ox024UvfD2qXhkFwizktaCtPCbBJAjLr2NYYl/v2ove1tJ/t4gAcvAQvbgIAwCZ8qRz+Thsy cKND/yVYvCyu/D52Hyw+x2THzIcd1i4AMLkcPwivXFBE34QvnYOZz7WhNo8uccyWjvPMObP3 7U60wb7MxEJLPwoRvGEwU20Htxw71VUK6bSXbKstqOvpd3xAaaepqiqGvyAgrwxgifSueQ7A cPzYffAdbG0BofVxx5Bob7UR6XTvsbYJd3gFfQjgOxveeuIo3HGRcVEnytp0iGmPnfeav7ff CvSKTXgF4PgBWNuEhw7Byy8BAJzNwctOWx2FZ3MAAG+/Dl96DQ4fgLcvu/Eal+HRAwAXGGGH A/DgKHxnk8lCDkEfjcHMZfjyZXgaAAAOHwC4LNV+Exkv5Uf3wzc34fCYWsbjn/4fe07H33iy OfWPLv3F34z+ye1Xii9B4YU/+lVq8baVYGF0pjZzNbX45L8DeP4R2AB4YBQA4JRj+wF4/mG4 A4KQw/fDs/e6rnvlINwxCs8+Al/+PqwxknAJvnwOnj7mpnbqOXjUe7T4HDyzySXCrecyiSw+ Bxc/B6f2B4lvnIMnLnECz6DO7wlrm3DHfXD4NVgDOH4QDgIAM78/fhA29Z4ahgAAIABJREFU fgoAYsm2ADpChw3bL74FT4/BM5tw4k545S148D6jjB4E+GaoJ0NnDAfgwcvwDMAhr90R3UNV ZH6v5WxWcpZKueZ2AZ73G2YZHvJ2ur16zhUOIh4IJKHHHYIU16d9ux47hispa8KZo/CMIzYz imguewwuuXG/6UyAnM++dVplnH6yfSs4VIZccJUESYGzJo5lylpOVqxRGFwulwAAjn8Bnj3E 5CuZjMYKUrskFiLnQEkBeUpwGJBJQjhC6YOkOSa5+ByAtnyRXLRN1cno+WPwymWYUbgxqJzn 4OkwSVVd0sTCm4Osp2JCJcQ68QU45Z3AePUcXLwvcFeCf9Rqt+Za1/scBZO9bVkvML362Rxc DJ32bMIrAE/fj39Tjvo2ZOBWDP0v/gSePgaHL3iam0wkmGl5IO/tnRGn05fg7UNwAhS9REvz jbDERVu6gfe+re+u3b5XO1wijUgwVvKM3G+LIWGjjzwYca9ImtJvsSPyZRzz/dYhm4DDLHIJ Fp2Q26nekyhOOR6Ap+UhEh3gtFMmPwo7dH6T739OleEFtHeViwCt5Afg0Wijg+RYw/QPHYti TkgF80CaqjzKoDgVQ5qAwSjcAe6CAAA8m/M01FTIaEOk70ameR73fPUqINMnf/abf4QpPsmE DTCdDaItV1n0Y/DgBjwjjX1461OMO8LMTUzqEjNvlzs6AFC91UadWqCVii2dDvceF+DVY5AA WBuDBy7DExfg0c8B+DPMA1y9elVbjuGohhjGuuiTTC8FbnCRnsotUei3jepSb9mxe0VlnjkH Dz4M53Nw0ft26wlvSfQOb9fxKweVW46fYFrO4fvh/MOwcU4XAopHZ4/BqZc4gbfBuwzCuy/D RMZNfAw2furWRZWMz998+cqTzSOf/vV/+H9H/+Qfbf3vv9xXuHPo6RN/fdvKzLW0t1f0n/7j 2WCv6ChcPAdHy/Dl1+HUFwCcfY58SN65l+A5gHvh4jl42+v9fcmjz3lf5nipHToW7Kt3jjCw ibDb7B/jJRsvwanL8PT9buLOq6yQVN+4AKcuw7M5OJ+DQ5e5J4fvhxlwt/HKJatj1E3wfA7O Pwzf8YdVP/xheOWcduJ+yd2L8dB+eNFwkteOPrngnpTDY7DxFgDAixthu+ux6ERH8HstdrOS 2Nz8hvkIwLngDL5zGIrb5dSnDiFo5udAoH27nuGV1GjCmoN75jmAewGcDwfhMOafwA+SLQJ6 ZU7wOkS2QkRhCGAefszYscpkpRqF+EHIZRRgFA69xZ1vkk1GYgGAt5B0VCrEZ/Ru6RBy6auG MCH8RW35ImBNVYyFuRGvnBrJ59SbNdSxNM3BxDo5ln9c2smLdZfwyEnQsFvzret9jiIXYNE5 bzQGDwA8NMZvxtHyzPfhlYPSVXr8aH6HF4wP3Kqhn2UTvqPat+VfPigd0PNzOTwGsMEnK6y9 bsKG2sYW5hsmiWts6RzOATKTfh5AN1zqxxTZM3K/jYSEaSUr+YRqcYEvfcOOSJZxRhC3PWJD TwBWXeU05XZqPjqL5eiNL6pJiOGUyfHkgjQYybFkpyFFoKrkkUYHBLP05bHVxBzTCiY1VSRx nlPat6dvPgdvOwsC3ocXDCpkxCFSap6+r57Apk9+XvBTnYELxrNB3LGKovc3iqIDnAwy7kgp I0mpOzoX7K028tQCqVRd7j2cbv/wAXj1LYBN2NgPh9lzEkxZ68vRBNUQgzqk5Ulm2LCLFIrU bxvWpV6ya/aKOl+nlGEN4LFH4LFzzOL3BTjqrU+/uAFPG1y8svYaHH0NHnsEzoK7ti2HoMIL B+Dg6/ACcGV/x374sqfY2TEjGT+L/L3wcjlExufzz+47HX/jSfjX//jDP/vF8J/GR55qXvtf X/ijX6UX2UP0JX+vKHhz7rUL8PbDcML5+veCF3IMDgNcvASncvDo6/ClMsABeNTzti8Z4KR2 AB4chTsehhkv+PgBPhEfTPKZl+ChHMxchKMXcIE+7kl84SW3ez3xBc8P/oWP34c1gMP3IyWr g5lJPPYIPDQGL1wQw0PYhFcAEs63Uq3Y0r4+xw/CA/fC+WOugLOLNjRZonv4m5XENus3TKbN PlGWIl7qU4dwAJ73d51cQuaXHbDLVzJMk0eBQ/TMAeYDb7XrH1YZzJYA436yfSs4UEM8kHIx cawmWaFGyRvB5OI7AA96d8UoTR7DYjknQi7CE/wYgWjbJeTSlzUf9STRcPQROurJTVVOUHaj qnJqJDWoYymbg4l1qJ6abRqKRybdWt9yxLh4GR4ahRN3wuI5ePBOgLekZUQ1z3wfngF3w+mL zmjLDrvOJikAUA3cqqGf54WX4KFH4LD8TnjBnbD5ufisXQA4Bodfg+MH4RVpLT4B3Bawg2oD W5hvmCWutKVzHBqFlwEeNeyuVcPlWMiYInrmAtI3ij35AXg+bPQ5hE7aUdjSN+yIMBl0YAV+ 6AHPV2J1vYR1LCBujTcdnXkOjcLLl+BBAJDnP5GnTCxYLNFpKKpKHmF0aCf9n0QxB38rxOCa Kpa40BWw29ZOPBdmIxhUSFl/wyESa54Iirxw9+o1V71u89khRe9tFHWSNdxSzY0757CU5aTU 7wVuOcpvtZ2aWnhqdLX3eHED8qNw/CBcvAAAcBHg+AE4NAovqyfekdc68CGmU5NMfe3VF4rf b0fYnt9ldsuqKPtF9Isb7gZsFWubcMed7ufEfnctXMZdQr2gCxEeHT8Id4zC+XvdwOcBvrQJ bwOjmJkMeCdGD3qX068pZFj+5n+6+vn/fOSOm//b23v/TWLffOPKybsO/NsTf/3va//qSmpx H3u76BffOQ3A/+CS4ri00+s5P9V3ymSAAQD5XAObCP9IlHTG3f3BUKc7ItEnDnl1hl0SBcBK 1vBQG8AzP4Xzd5od0uR5cQOevg9e/an3N3vaAoU91BZZnwPw4GU4+n33r8ceoUP03cWkyNZe A3gEDl9ouc26EYX3w551CGGJdNauljTBPdM5TPrJ9q0wx9DDEd0SeoeXFs7kA+47qixzSPrK 0ERbeUqwBkaThHY011jU2qjnOdbERYNAhDHd+WEH9zTxMaNHLXVrg5DjC2/Bowfgof2wcAEO 3QcnDsBGq0Oqf3xPJYAO3LyIfuhf2ICnnbsFzSYSrtiYdOB6E15x9sb6gcLNa6Fqa/I1Szyw pRswFxG02l230JBlzxj/Pol+9HlGPWkHCCl9w766I52VW11/glh0Nqdswi3AXyihGyI7OmUK R13JuYXXyKNDi+m3SkgF44nWVNlNvqF0ZfRso3m6GLjX/HVbw2P3wXc8PTVjH4437sjok5Jf /x3Et1pjWp1adKP3WNuEB+4EAFjYBHAWScfgoGpoa0N55RDTqUlm+7U3Ql3qPrvlBD17x+3x g9xs8vD9wZHz/L3wygXuZ84O7YeLl3BhJx05RCPs/BqDs6PYvdTjAmx4+9jNZfw0g8vpFTIs n//Pt56Ov/H2Lf/m8Ee/1bhy8sinvvnm5r9/4Y9+lfpP+/78vvOpxVtX/tXV1OKt57KX3N+g 964ZPjwGd1yGtU14BdyjCm7IAXg+5+6CXmQHGEZSZBNeuQQP+T+3l4MTQiIH1JLelmznHD0q 0C+Csh6DmVF4+QLAGDx7L5xi1h+RkjXnArx6KIqBaxcARpnfttuEjVE4fsC9PQflxQ3uhx3P 5rBrJbT6OLfcsgnupJ+oG0CMiszZrHS/UZs9m+NOpbm/odyXDgG8GgvKStuuXYaaYEM+l4Js muAfIQT429xZ68z7yU5YYYRULqaO1SDUKFlALj5Zf9lkNNYlaDg30Es/hxqurTwlUE8SlGCl jw9hmqHNcNSTm2poLFk9A0NawKw5RNbzojPnwboI1aPQbq1vOaJcgI174eAGrAG8fBlO3csM 62rYWajzm5yat2ijgVs79K+9BhuHXKuf+SnMPBxInn0Yr1QvbsCD9yH7XrnoB+D5Y7Co2BUV Yb5hkjhrS8d57Bhs/BRrmPruWtvXyc0W8cwBqW+Ue3II02pMORj54KVv2MD1MtoxXcSproo0 uXZq3gEyuOUIQcpc2UWeMinsVQ6UGMpKHmF0aCf9COaoZzsoQVM199UBeHAULl5QTMAEhVv1 j1mXjjTPO9XSPlLxKU1oZRqpQ/rpec3Y52A+7uBJaX0uv9V2Zmoh043e4wK8egge8Grm2iY8 cC9XDRAiKa8cYkLTNMsupPZqCwWYfju0LvWY3bJXFC7AqTu9G5Qvukfm3Xt2X4NTX4Dz3q8t OcfrvnOZEd5UCn/pAsAFKUQjjPHEOTifg1OMYkYyYzBz2dXNMJ1X/+W1B/7yyOn4G082/93p +BtPNp8+HX/jxF8f+fP7zn/9p0f//L7z6f909KVHLh2rjLp7RS/Bo06Cl+DL3wcAeOYcPP8w nD8WhHzzdXj2YZjxDDx0zL2dOpAEcV/0M9+Hszn30eJz8MImNNhEGG8LkocegZnLcPQCwAV4 KAfPA3xJSAp3Xi9YY8r61XPwAsCJOwEATjkOlH9IqnUuXnI387fGpnhQ4olzcP5hmAFYfA6f May9Bl9mrhv3b5JW6jMaCAPA26/Dxr3wCvOl99oFgIfhxGuKApKit+moXQheZNJV4muvAeTg lddhxm9ul4KvB9nm9uo5bje9E/GOfnUIXo1VnUxp1y7vTv0QTRhzBJfeoWiVsn/YEMeWhdfh Wc+rrHUm/WSnrDBiky/cTQBDx2r2v0g1CvGhkMslZJuGaDJIuvmxHCtycIi5Ql5woOryMmFK IIeEIpe+rPmjaPgmPDSqKF80J7mpKjLSqxduCLRw7smkOZhYp2tEjj6bsOG5S3zEEN6teVF6 nyPKxUvuzqwX3oJTzHUT7O8vCR/YmQkAnCrrllTy6MAtTSb1U5GF1+GBgwAAcAGOgjcpBVg8 Bwex33tcuwBwr3R8Xo7O/uYDO2e4CK8eamW+EZo4aktHGEXG6JDuWurukAaibrZogV4swyGh 35Z78rBB5MUD+KSd+9F5rPSNOqIwGc2YLuNU1yekNBtSO0U7QOT3WORydKbHwhB5CR5sdcrk FLffmXhlJ8ZSLGaFFIG3Jyva6NBO+i2bI082wn4Yx2+qsocF/Jcy502toZiAsRj6h4uCdemC CWjz9OchgtMQEzwDxTkkMxiZv25resuzx+A77BVJ2AAnv2uI4w5WaTVjpW4mIL3VRp5ahNre +d4D4OIlOOivJ16AV4+5p+lFNOWoStxkiIk6yTSqvUwhIoUi9duHtXVJ+NAbYp9bsHuU1W7i 7COwMJBXJZ7/k62jfzH8f/3x7/7Zdz9yPnfzaPmW1x69cv939v3wX175g7/cd+5/+M2x//Lf /c2/eO/z3/vE+Ry8fUl71NqQMTh/Jxw1/4khgiAGkNC7Fwxpp0PolA7EIECl2SV66djtPr7r fdUN63qfI0EQUYn+NjeYA1wbWhm5YjCt7iNMlz6wKwPts4NNa4euuqXHPu97EZ/Phcu0z67Z K9pbnlBse+kvX3zn9NG/ePKL75z+Z9998ovvnD5afvKL75y+/ztP/veX/+wP/vJP//k7p4/9 lye/+M7pz3/vyX/76f8K8M/byetsDh7wPi928K4cAoP1toP5RrB24hKEIdQhDCAD2PYHQaVO 6dAzW+SMun1vvdycu2ds76tE7zurXvqTIAhzBvNtri+QK8xBB5Ed7MAdbFo7dNUtPfb5Lili 2iu6u3jlX7z/4Pc+bvL/+Rwc7dWOZYIgCIIgCIIgCIIgCIJw6M1e0Zht06ooQRAEQRAEQRAE QRAEQRC7CDpBv4v41lOnDSW/Mff48PBwV5UhCIIgCIIgCIIgCIIgiH5Be0V3ET/68Xk0fM8t t0AMbt60/crw6U+Ojo2N9VA1giAIgiAIgiAIgiAIgugdt/Rbga5i5WN5y/ujWUrHYrFYLJYu NSUxH/dhEBQkIEr7T+QQjbAfHqihEPJlfM1ZnWQNNTo73H3PPei/5JEjybuOHLn7bj/kxo0b Or/KNEtpya07G001kEskKBBNXXHwPYmWuhSuSsYVE6o/W0b6ImNyQfN1wtmWo1OIM4rJVWGs 1Aj5KBq3aOy18jGszXEJsT5R5o7pPwCwjhE7kohKRo7YZVy399GuTnhGVXlMK9UAlk5PVIrW 6JBYrWlrPOBys45W9NGG95jeq9GxYg2lvVra+xzbRx7NxVoa/ImOI0igwfwEmXxrZiw7HdPJ UjRa8rDhHLL3qBuX471+qorOUVvqDcyn7p3oLrpb3wiCIHYiO3VV1Bl/JstMwEwhWbVt264m CzPSmJOr2g4rs3GAZmm+XmzYtm03ivV5TtjKT7qPqjCZt9AQjbCnzHyZFSo72VdhMhgNGZn4 7Irt0yimctMZScNmKT0JVVeiPokOf8N7YrUfrs48tfSV089/9ewPvvbtytfL39tzc2uP/aH/ 7/jjz7bs7F2IXLJynUFKX1HWKlJOdJtNlQuXqicfPZWqr7tPm8uVWivmJSrZhlSbWH1seyED mQXnYzXnt6CFTFjiNaT98YmvzMbByse8Cm03spUE4y2lW3T2WkvlXC5ZWXafh2iuyV2lf19p ltJ+idl2FSbZCXBmLls5E2U+HDkio1YXlwM6ZJe5koFk257pAO1bYYxplKgq9YdWtJW7d2SS IM06OkhfnDnoJahGp3l3Gm/vczRFMZpjoOOIcnCR5gOKvFpQYAcTabJkiIGHhfoZlF1jYj6W tzrX2J102C+8O5CstVTOVTvlsMi6sXPUqeUodsluN6dFbbtZ3wiCIHYmO3VV1FlIrHK/WJWa SAAAZKZztdUGE95cr7uPPBqrteR4HAAgPp7khTMLzsIpQGLCWYORQzTCAADN0kwlmUu5MtZS OVWcy/DiggyDdaaSncvIGsZnV7wxLz6VFfRwiQEAwG2f2Xf7Zz9y+2dvvf0z+27/vX0xsG2w be/s/Edv+0COSIjIJSvXGVkGL2szpJqoDAzIZv1lwMYq5LD6hNJcr6eyU452TMXqDKliMVkI e0V0lhy8fOOzK1VFHM4DGnub6/Xc9MJ0sCwaOXcj/XvNcgWKi359yizwE+D47EnQrJ6riRyx N/TRrkHwTO90iM+umPVWg+AWc1rQVu7ekUkCNuvY1hiX+/ai97W0n+2ihdG8iY0jaGAreXV1 OkFAmx6Ozy4W6/OlZqcau5BOR5KV39E6Qju6tWuX5/boKRAEQRAdZqeuikrEp7LgrIhYS+Xc tPO1tv9dXa2QYI5FsEOwv6AlHotrLle8tyJlCPrIOlNInpyb8J6s10GOxMsw6ZTm69mpOKph uB4fXN0CgNH9Q29t/sPfvvP2z9/9u7Vfb4ANwFwt+6k73/E/p9P5fJo/ehGcAUk7+2VcmURB 3InISwbHl5uldMz7apo/jLIt8ZytKxFGBilr04yweWHYZHHKWwa0lurZabk+KYhPZaGLGyKn 5sKmg3IVTkykykvYDgjOA0p7m8uV5HQGEhNgsCwalnu4/j2nAt5LEYffa3Gblbi7RPwmzN+I 4DV4JmIgiXYI4gHKdMkqzRRqtUJCviTB3Uvi5St1BeJtJ0LcwMD27WoqlJQ14c1ReCZdskpp VHPJY06fyW4AETaDhLqlA1bwqAzxFJMUMHOsLlmpRiEgR9WXhZtIkNFEdaOMlQ+kFA6UHSN1 79ohWI1Q+rjmcnhI+SK5GI3dpZLKjWzl1EuqtAiJpWgOJtZhsdjjonmLcxf/yIlv3q1x85ae 5ihg5T1hv1fn7mFSYj6aN5eRcQQNbCmvLk8nti9BkTplmc+HN1tXlu/SUA9rOhAB52sdtJNv edD3onCdv9BruYerkP7BT597ZOUThVqtkPAjiul4GipGYWVTjaAbr6RmsA7H/zatM0OAwc0t nK+kWcfOeCMjCIJog12zKgrx2cVsJRGLxeYn3F1gmQXnO9XGas0919DIVhKKgcUTBgBn+EgU klVdCOCPrPwkCFIpWOJnHYiMm9RyJXky5PvJZmmmAO6GRIFYDADgtb9fs/f9duTj10Y+dnXk o1dtgDfrP3uz/rM33qwDwCdGN4MItfrEInsop1ma8c/pZCvOLMyRaRT5fYiiZGLBubnAci4y WMhgSW03NIWukpHKWou3WB+LxWKJ1ZP+V9N+eKKSXdTWB3cZ0FqqZ6da+Ko9PrvScFoLN0Ni 9WnnjqL47El5u2WQeN4Cf2e3H2U8iUjybgGlve6iKPPdSAia3FX6DyJBr8VsVrLOOHeJNIrg GOE287l1/xIO5oIHbpcT0iG495J4IWziS+OLxVSq2FiZjTOSQV/h5yt2BYKGTF8h7cNr2674 LKekRhPWHIVnGkUozIPzobLcRPzD+CFkT6FeGbf2tW+FCG6Ig1Qupo5VJyvWKMwPQi4NgFph ddo7LurcHyOajMUCALDysfmJhm2Lhchr2y3k0leNg0L48pSufDGMxm7ZjYrKqZEUh36jWOrm YGIdoqd3XNTJi3WX8MhN0LBb86zrfY4Smbmif+IEyksWv0NQh2I0bx9kPoDm1TUFtjmZuaL3 bau1VM6dnJswarb8ywgAYB7WdCAyiYlUfd3rIRXDqOGg7wxME3NidnIsuX9g4B6tzzWKqVSx YS9k8HS8dxDFKKNpqq3pJsxRA6K9zrjfr3VoCJBrBQb+vhbZBIIgiB3FrlkVbZbSM7Bo27a9 CDP8zCw4zKw8ey4Qn10R7oWRQ1DhZmm+Lq1YCrMOVAYAnMnHtHbcc2+AUr7axQBgaN/1vbde Hxq5PjSyNTSy5Z6r9yg+dDr4w5tzx6eyqfKS1Vyu1Lx5QaJQq1WWG4EMr4ck2YTMQjVZmHQX CDGBbYem0FUy4YsALMwlREV2s2IQHvYSH5/KwmrDWiq3vEfVu8yWvYaXu0esrXNwmYWqeKIw SHwhAwDCzQDN9ToiybsFVPY2lyu18mQrdU2Tu0r/QcffrJSYSJUnY7H08pR71M5pws3lSvBt CnvBA7PLSe4QvChe1ykl7sAl7uHnK3YFfCLsZqXEhDSb74RdvpJ6TZRZM90g2x/K/mGVQWyJ oEz7VvCghrjI5WLmWE2yQo1C/SDkkgBI8XVJNtnCYtUKidhkOSd8r9jDOx/l0keHVE04+gjt hozGbsmNqsqpkdSgjqVsDibWoXrKe04DefSRUbfWtxwR3K1l1lK9WC3WlyxorBpv4sRG8/bB 5wNoXt1RYLsTnz2ZKy9ZzAG20Gar9B3vYU0HgtBYrSXHg43v2DAaYdBnQWJJ/QOL6hGejjS4 CKOMpqm2pJswR2VTiPI601itJceha0MAiup7lB3xRkYQBNEmu2VVlHmzDt8vxt5VGNweJklJ S6iaRVXnkeWPPAnvMER8PMnOOlAZ1wRmtRTVMGxJ1GXvrc566LXhka2h4Ws3bbgr+ftH7koe uSt54+bNK1ev4dHc3XP+z1LZtvOqqYSXjHtLS4GDJIFtiVvo2joTyPBlbT7v8KfPEdSrz8/X c/5qeqsXzEvX8HaIzFy2MnNmFX8ou6exWsvJ3wjIbpHsBWenqF/XuM1vbeSu1b/nmGyBDbbF rdi2bZ9cTRhu+MUvxcOvbmg5cQCQuoLWEumoXa1p0uXrAo2Uad8KY0zTieiWtm6OMxmYclXs 6ygTbeXu3WyS0I7mGotaHDpbHrv7S4SJAfdrMymzR610a4OQI2Smc/X10lI9O5UZT9bXrfV6 y7UuGM35Wx+c+yDQqbHx+Qp1XmGBu5jMdK68ZFlL2EYItNmGFnjgYeP2zl1DpO3kOzno9wxN U+0grfdagdu7PwR0yQSCIIidxW5ZFY2PJ71vv8RbA5ultH90/UwBslNxZsYoXtzICLvpyCFq 4Yz/Y/IN/zBEZto7jKuWcZ8yOwNkDa18opCs6seyGADA8MjW0MjW0PDW3qGtvUPXY3AzFnP3 i9q2fePGjUDem7+6hrH7eRjbMHfLku4pFXevgHlSAwlS6FKJIDJiWbcy73Cmz62rGp/KQo3Z Yuy3hMaq6kfpuQKxlsrduOfeOYZeLit0iM+eTBb82yyapfSkYv+05BbRXqflBBaYvOQZ5a7V v9fw94qx95WxZOaylTOlUjqWLjUhs9AoBufm3LvJvE1zwo11mbls5cwy1iEAX6GbJonzyF2B kAgEfbei0rZtl6EmyNs8n4JsmuAfIQSk9TZzt3TSCjPEcjF2rAahRskCcvHJ+ssmo7FSEwnn Ny7EdVEDbeUBVz1JUIKUvmIc1IyPhkNnhLFbVs/AkBYwag6R9fRqD9JFqB6Fd2t9yxElM50s FOrZKWcmMRl2cshBMZrzP9ToruvHsXEEDWwhr95MJ7YrmelceXKy7k3tI025EQ+3MMFulmYK wcVc8mARedBnkWO14KP209E01U7oFuV1xnN794YAncLSrGObv5ERBEF0BnsnU80xX38FN2Xl qsJT/5F/QiKasBeiE3Zw78kR4rPf1cky/FNBQ+EeMCE7h9+8f+XD61u/+uUv2X8fvP/etatX rvzug/fef29z89fvvvvu765dX1tbs207lUqlxOR4g3wVA119RVnJRjHFetKJrPLN9sCgzmAW Kso6AHGp/wByVTlcgSzmh7g66FJhqpOnqPQ1OxNfqp1mRjWKKcCNFZTg4xi6xQ2p5gRLvRiI 5mwiBrkH+g8AbPkwFVAol2oOcsUi06zxnkguzmoOAOQOoVEUQvgAJ8FcVdDP6RJUvYqcavA8 lRLjdsKu4IleE8Yc0TN8NWY/KD2WSnmdqMK6MLd00gpPN9QQ709JATPH6pKVhxgZPhe2ZNW+ 0sRqFFNSfqH9sq575yNpO0Op9JVDqmgRW2phQyfuWFVGaHVlqqJeUqVFSPrK5mA0MdA0Ijde 4C7pEUtYtwZM0+5xjgqzpQkp+4f8gXMoX1OZLIVBTZJGAhXzATQvhQK7E7F/CCYoJs0WS8HG PazuQPiyCwpU7uRRlfSDfjDvArHzZ2Op+ge0wxFC0HTUH5RNNYK2D/3UAAAgAElEQVRuvsdF xQyKCXW7HDfiEKAad5hwcRB0Emil4yUIgtjRxGyb+QFyojNY+fT63OAdQbj8/tWRkb0mkr/Y eGt8fDydLi0OnhUEQfQB52rm9jsEKx9bmo54LW2ndCAGASrNLtFLx7bTnAcBva+6YV3vcyQG F6a8B7A/HECVtg0D+hpIEARBqNgtJ+h7S2ZhIMfCrSvv/WLjLZN/+/fv77eyhDlWPiZgfv6l nbi9SZDYATC1QnUZAtFrBrCpDoJKndKhZ7ZIGaE/KtKlHN3m3D1je18let9Z9dKfxMBg5Wk4 3LkM6GsgQRAEoYL2ihIEQRAEQRAEQRAEQRAEsbugvaIEQRAEQRAEQRAEQRAEQewujG6ZJHYG 33rqtKHkN+YeHx4e7qoyBEEQBEEQBEEQBEEQBNEv6AT9LuJHPz6Phu+55RaIwc2btl8ZPv3J 0bGxsR6qRhAEQRAEQRAEQRAEQRC9Y2efoLfyzBX1zVLaubU+XWpKYj7uwyBIuuPef+Q/kUM0 wn54oIZCyJfxNWd10qihupf/7nvuQf8ljxxJ3nXkyN13+yE3btzQuBWhWUpLbt3ZmPgfKVhN XXHwPYmWuhSu/AkGR0yo/mwZaYuMzSTIV5BXaeiayUg3S2nhz6CdsRZ4fxraSDAgReZi5SO2 zcgRu4xbf/poVyc8o2qApn3pAJZOT1SKNtYgsVrTVtO98+1N6NPM9dGG95jeq9GxYg2lvVra +xzbhxkbmMqLjbyKcQSfD4TNT5DJN43mBEEQBEEMJDt1VdSZhU2WmYCZQrJq27ZdTRZmpClq rmo7rMzGAZql+XqxYdu23SjW5zlhKz/pPqrCZN5CQzTCnjLzZVao7GRfhclg8szIxGdXbJ9G MZWbzsgpa3T2GN4Tq/1wdeappa+cfv6rZ3/wtW9Xvl7+3p6bW3vsD/1/xx9/tlVf///tnc1v I8eVwF/HI8kTJ8EYycb2HOOmDgpnnHPzlsMCFC868SosFkvujcxBwB50WigHQ8CCDexFvOmw WIBAFryQ/Q+siMVmT3GbyagbhhMjTgCPB8lMxjOj8Uzvob/q41V1Nb81ej/oIHbXx3uvPl5V sap4EzGxP1L6irJW4cTRI7FUs+fKoo6DOY5/mbwNRwPjnyUO3Vpl0EyzHsO+eibDShhFZ+lv qXrDfqtVHYxY0SZIs9NgqCMBAAVFVj9qDk5nmYvOHJERa4nLAQvSy1zIPOTcllkA82thjGmU WUVaD2Wklbt3xOFKo44FshZjbnoJqtFJvpzGu/ocTfHamW8Iev6+blkS9SNK54J4fzSvEgIQ BEEQBEGshTd1VTReSBy32GfOXgUAoH7QmkwD5nl46SevUoLppLprAwDYu1U+cP0sXjgFqOzF a07yE01gAIDQPRxUW04Sxhv2nd5RnQ8uhGHwTgfNo3p46TvNhg0AUD/q+UNPK3OKBQAAH7x3 ++773737/tt337t998e3LYgiyM/Ov/PBUyQmISCXrGx/OQxe1magpaos6phmM1uZDKbQwuoT QjgaQO88E65+xix3mhFe+q2DswNuWdTp9ardWWaGBToSAAD6IrM7xzDTyvLMEVfDGvXaBMus Tga7c2HWW22CWcwpIa3cvSMOFxt1XGuMy/16sfpaus52wQwWwe5c6Jw56vrLjAfQvEoIQBAE QRAEsR7e1FVRCbvRhHiRxhv2Wwfx19rZhqpJt2JZVnrol10mzRa0xGNx4WiQzoqUT9BX3mm3 eny0l7659EGOxIdh0nFP/GbDBnu3OkmWnMLRYOJfhpjMIk+fXwHAu3e2Pnv0599+9YffPfz9 g68/hwiAuVr2Rz/5Kvu/Vmu3a/yxp/wkVC3eL5OEqXTFnYh8yPxEdejW4uSEpK4pacnq7M+E QcraNCNp7V71kKGRrkx6Q795INcnNKPRANI5zGyEo0H1oA6VPeB2izaOZtr1WaQjAQCKIst6 LW6zEneXSNaErbaHnAlmIuYh0Q5BPEBZcz33sDuZdCvyjRA1N2TzlboC8bYTIW6u4Px6hQoh ZUl4dRSWqbmeW0MllywW95nsFjNhu1mhWRagBY9KkVQwSQAzw+qSlWoUAnJUfSTcRIJ4E9WN Ml47D6UwoGwYqXs3cbhYQnzp45LLzwvKF8nFyHe7rsqMbOXUh1RJURBL0RxMtMNisbcgtT3O XPyrOL55t8aNW1aao4DXTgNnvTp3D5MSu9EEs3MaqOsvNR5A8zIXgCAIgiAIYk3cmFVRsDvn zUHFsqyTveAs3a53VgeAYDpJjgIFzUFFMTlLAwNAPIKtdKtj3RPAX3ntfRBCOTDkR8hImCSp 0aB63LEBoH42rsYruYfTqtkWQADLAgD49R8fRLf/tvP9Fzvfe77zzvMI4BP/00/8T3/ziQ8A P3j3UR5h4u+ds8eeQvcwOwnVHMTj3DhM0OOFEENWzuKbC7z4IoOzOpbUdUNT6KowUllrSRfr LcuyKtPjbNtO9rwyaJ5r9/IkK5Pe0G82lrGyyEqYzXzjRVHmi4gEu3Nsvl3UXEdCSd5rMZuV vNP4LpGgB3FpJM386LK2D+PsmGQy3+Z2OSEdQnIvSfqETXy4e95znF5w0bGZkHlfkeUrdgWC hExfIe3Dm1svu8MJqZGEVUdhmaAH3ROI/xmMQsQ+jB0K9hTqhUma0fxaiOCKxEjlYmpYdbJi jcLsIOQSAEy60wP2eg1ZZSwWAIDXtk72gigSC5GXdlnIpa/yg8LzUUNXvhhGvls2o6JyakKK rt8olro5mGiHyFk/ixKCnn/Cmkt4lSRo2K2l2q0+R4n6US87cQL9ocfvwdRhdy6CeOy74G+g Ee+P5rU0AQiCIAiCIBbEjVkVDd3aIZxHURSdwyE/MssPM9uNptGmD7tzEUXB3km+tCU/QQOH 7omfHKHOEUbIaBgAiCelB+mLdOR9cQDGF0aCBQBbt1/eevvl1s7LrZ2rrZ2r5Fx9Su/nH+cf 0jG33Wg6/aEXjgaTdCBc6U4mg1GQh+GQQ4bxQu5+skCIBbh2aApdFaZ4EYAlv7cr6Dn9oSc/ L5rE240mTANv2J95j6qphFF6ri4cDSb9fbxg62dj04OE5joSRmSblSp7Tn/fsmqjRnKYMW7C 4WgAWb/DXvDA7HKSO4Q0Stp1SonHcImnZPmKXQGfCLtZqbInLRksQq9MSL0kyqyZbpDtD2X7 sMIguswgzPxa8KCKJMjlYmZYTbJCjULtIORSAXD4uiSr7GGxJt2Ktd9vHfP9yQrvfJRLH3Wp mufoK7Q/NfLdkhlVlVMTUoM6lrI5mGiHyinvOc3Do6+MurW15YiQXNTgDf3euOcPPQimxps4 06vp0Uv1Zwbx/qq8liMAQRAEQRDEgrgpq6LMzFrawibB3mSY3x4mhZKWUDWLqvErLxvyV9Lj VvZulR0ho2ESFfDV0uRYtpnMAAC33o7XQ19s71xtbb94HcG96k/v36vev1d99fr1s+cv8GjJ ccHsZ6miKJ5qKuFD2rGkALmBpADXkqTQtfbPw/BlbT47sDvHLXTRwEA8/+TEb2Wr6YU/oFHc PrSEo0E1K1hupxkAxDPDw9Np+pE/e0qH5WfFpMjybXEXURRFx9OK4Q8C45fi4SVVOnEAkLqC coksVK9ykiz5ukAjYebXwhjTdGY0y1xt38QxtcbY11Em0srdu7nDnVVyjUYlXWdp371eZhgY cL/n45i9KtOtbUKOUD9o+Zfu0G826rtV/9K79EvXuvxSfczzoq5/5vGAdIG/8iFBEARBEMS6 uSmrosJFnOxoMnRr2dH10y40GzYzYhTXaZjASTryE3XgevZj8kF23Kp+kJ4qVodJ3uY7A/KU vdPupHVQB43MORYAwPbO1dbO1db21a2tq1tbLy14bVnJftEoil69epWHT8eviWLsfh5GN8zc csjkjFiyV8A8qY0EKXTJ/kgYsazLTGnqBzMvi8Ik32Kct4RgqthjLFwDlt9nZkI4GkBe+ZAZ ld05rvb7adb8TynNt7pwkzErsvpRc3DqujWr5oZQPwt6jn+ZGd9uNLOD2eKNdfWj5uB0hHUI wFfo0CRxHrkrEBKBvO9WVNq59TKUBJnN8ynIqgn2EZ6AtN5mbpZFamGGWC7GhtUg1Cg5gFx8 svyyymgsZ68CdudcXhc1kFZ2ryYOV61LWvoKP6jxj4aucwbfLYtnoEgJjJrDzHKmtQfpIlSv iru1teWIUj+odrt+sxGPJPaZk0MaOCt6w35SVVHPi7r+EuMBNC+FAARBEARBEJtE9CYzbjH7 DvKbslpj4W32KjsSNFvg9IkucEy84ilKxm6SkMPwb+VIkswif33y7NuXV3/68kv27+mTxy+e P3v2zdPHTx4/evT1w4cPv3nx8sGDB1EUOY7jiNLzCmUi5rJmgrIhg57DWjKOrLLN9cCgzmAa Kso6BzFp9gJaY/m5AjlY9iSRQZcKu8elhd531hrLN6A5vV5LSDaWmhcm6Dn85QB5/EAlPFEE UmRyrxGNW9Dq9ZhmjfdEcvUctwBA7hCCnvCEfxAn2BoL8sVdgqpXkVPN3zuOGHcReuVv9JIw 6oiW4dss+4/SYo6TdqIK7YrMskgtUtlQRdKPkgBmhtUlK7sYGT4XtmTVttLECnqOlF9hv6zr 3vlIcqPjLcyXvtKlihqxpVbkOnHDqjJCqytTFfUhVVIUpK9sDkYDA00jSuLl5pJesRR1a8A0 7RXnqFBbGpCyH+R/OIPyNRXzvLgfMRgP8NVUyEshAEEQBEEQxKZgRVEExILx2rXLo807FP6X J893dm6ZhPzi8892d3drNfd887QgCGINxFczz98heG1reFB4v+VyZSA2ASrNJbFKw87TnDcB va2Wod3qcyQIgiAIgiC03JQT9KulfraRM72rZ4+/+Pwzk787d+6sW1jCHK9tCZgfeZ8nLkEY wlSzfcWPyRGrZgPb/iaItCgZVqaLlJH8+z/LyzFpzstTdvVVYvWd1SrtSRAEQRAEQYjQXlGC IAiCIAiCIAiCIAiCIG4WtFeUIAiCIAiCIAiCIAiCIIibhdEtk8Sbwb/+8mPDkP9y9Ivt7e2l CkMQBEEQBEEQBEEQBEEQ64JO0N8g/ud//w99/tZ3vgMWvH4dZZXh73747ocffrhC0QiCIAiC IAiCIAiCIAhidbzZJ+i9NnNFfejW4lvra24oBctIXuaPpDvus1fZG/mJJnD2PBdDDGQuD6eg RuaYj372M/Svev9+9d79+x99lD159eqVwqQEC25/uWIIJcKVvkDo1uJ3WX0V0uCfK3+CIQ4m VH821ywjVVw5C0Qkry3IELo1q+0xibORUBU0WiBxgTUro0Do1oSPNTfEfrTCans6AVSJKwts U8BtBQDgtWcUfuaISyYpjjXqtQjLqCqVaWXbwNJZiUizNUYkFi9tiWQRNeWu3sRll5G2rJDL ZPViFOa4IZbZQHhnxw87eZMxIeM6intPNnyWAOo3FTJwI4osuJQ7Lqdc0GjRI/LEQxNWIm6k 1vYUIxPDEZcBah89H9rKXzQvMJpuzNi/aaZGccjF2daQhVgjQdWyVgoiMCeeZgogU7YXLVHx zBwfQRDEWnlTV0Vjh7DfZx4cdqvjKIqicbV7KHXkrXEUc9GxAUL3xO8FURRFQc8/4QJ77f3k 1Rj22x76RBM4Feakzwbqx9mPYT91MYXyiAqGbm0f4khBz99H/c/2W9bkv6eHvxz+w8f/9Y// 9qt/+vfBP/f/863XV29F32Z/f/+L/yhtbEavGzMzkSqYVNbKEuFKX4sTJxiJNTF7LlVPPrrj +JfpjGA0KPWzxHnWwd4JM5xhRYqis3r9qJdnEucDzK/2hm6tMmimUcawnyYlpoOIgMf12lZq 1ihoDipshZvILbt+lkRvZW0qzgy1rS7xjUZpZwCA+lFzcDrLgHTmiIxYSzThgvQyFzIPObdl FsD8WhhjGmVWkdbD4tqF7KANXPYiWYupN718iRTG2V107PiZN+y3WtXBKCtAr525kHTAovSe AiZ+UzWiUOeukNMAXB670czGKuFoAPnwKLz0oXVQF22Vq1sgvBFaH62NNk8r08xlcoqmGzP2 b+jUJpcLxmd1mNW2s343tgBrsGAtq6xI+TaIGQuaF5gTz2wKsISeXJr+1M+k+TFBEMSm8aau itqdi3gwx+DsVQAA6getyTRgnoeXfvIqJZhOqrs2AIC9W+UD189S11PZix2O/EQTGAAgdA8H 1ZaThPGGfSdZRkqCG8kjKmh3LtIRHDv447AAAOCD927fff+7d99/++57t+/++LYFUQRRlJ6d f+eDp3JEQkK0f3jpO82GDQBQP+r5Q09VInzpl8hQrInKhznNZjabCKbQmiFXALA757q1V7vR hHzKEo4GkJgh/dg7z4Zq9TPFrAoDjRsPUdM07M7FuNrN1iecXo/5VILEjNrENxu9ne3OMWhW z9XMHHE1rFGvTbDM6mSwOxdmc75NMIs5C6s/soM2cNnXHuNaQWwe4aXfOjg7yJcbmREMO3Yx Saqk38RGFMrcJTnnkMferU6SdIIpNI+zkUswnaSLokUUDIc0zDEWmgPNXCbGZLoxW/8mT21y vNNuVbJ4GdvO1vksxBpLYjaNZIE5FjIFmAVk+pNMjAiCIDaXN3VVVCJfvPGG/XgExGzpn3Qr zAkE1tGky5nS/v9wNEi9pfIJ+so77VaPj/bSN5c+yJGK5dGglOPp8ysAePfO1meP/vzbr/7w u4e/f/D15xABMFfL/ugnX2X/12rtdo0/OpKfGREPQ9dczz3sTibdinwAvOaGoZumxp6aSb6g VF5uwIfMj1Jlx5+kpNYFM+AOR4MJX0ZMifClXwJ09FMwJIJGOpvwhn7zYIZcAaBoNMguiyKL oszHUqBx5apd2XP6+UircTTTjCU2Y1Him4zCzlmvxe1u45ob2zCRs2JMxDzkyjsEIW6u4Px6 hQohZUl4dRSWqbmeW0MllyxW6U5AOkMqnOku6Cfn14JHpUgqmCSAmWF1yUo1CgE5wjgSjmYi jkBzf0kWCtsuqikyRUTZQZd02VLWcd3A9ZKfF5Q+kouuIaclXXNdlZHZqqsPqZKiIJaisRhq V1x8N55wNKge1KGyl/luu9EE5BSVUVJl/aY8olDlLss5jzzZjghv2K/u1htNmAZQPIwqEt4M 3EcL1VVsF2gvynpM+Wou/kIjviPq70tDaCiebszWv+FTm0TMdBImkNlW7o6yphv/72W+Uurn cV/Q9hZkDVShJF/BlaO9HCewUL5CB45WCU4jWWABfAqgcR8636rulnUH5LMGae9Wr8l4miCI m8qNWRUFu3PeHFQsyzrZS75Grp/FX2YF00lyDiJoDiqKrj0NDACxU6h0q2PdE8Bfee19EEI5 MORmKEbyKAndwy57hpnBsgAAfv3HB9Htv+18/8XO957vvPM8AvjE//QT/9PffOIDwA/efZRH mPh75+yRpvwagvSJdxo/CHrQHe6e9xynF1x0bCZkFPQcLrWjy8PsqFRzcOiGXCLsFDV0+ZCV s/j6Ay9O/KwuBljnhKd+Nq7Go5PDaZX7RpYpEaT0daTDHcuyrMr0OPsmOXteGTTPtV8vJ7MJ b+g3G8bDfiSVbDTIipTU13xZtMQqKJKOGcL0xd6tch87x4b7O1Hb6hO/fuS9FrO7TWpuWcPM zjwxJ964bXHr6RCYZi7ttJtbL7vDCamRhFVHYZmgB90TiP8ZjELEPowdCnYN6oVJ6vj8Wojg isRI5WJqWHWyYo3C7CDkEgBMutOD9HDeiRsiKmOxAAC8tnWyF+RnDaXtotoiy6ruUnbFynVD 5eCE56OGrvQxkIYsxUKMrKi6mpCMxSQZlLHUjaVQO9Piu1nkzi5d6IgXG7mvNO3ORRAPkUsv Hpf2m/L6Ep47Juc88iT5hpd+66AO9m7VvwyFYUvxyKTE1xxFyNVVaBds02Y9phQrgZunyDi9 gB9Czzvd0CNObTK1lcvQyaKr2MztznFrkg0yJ63jThJb9kFoF4GbZQHWkFqWHEDs5TiBD+FY cMeFVYLXqFBgZAqgcR+zdctKCwM/IV1gyyEIglgGN2ZVNHRrh3AeRVF0Dof8mC8/3aE8ey5g dy6ES3DkJ2jg0D3xpRVLcYZSXh5Wy8qgqZzxggUAW7df3nr75dbOy62dq62dq+RcfUrv5x/n H9IzTXaj6fSHHnNnZCpZ+oXrqMEduRJul2RTC0eDSTqUqHQnk8EoVCcihozXHveTNWYswBpJ L+G6OID8/h62RNDS18HcuNRjd1/kz4uO3NiNJkwDb9hXfWlvRH6IiL91Kz8hE68BldgaiqVj hLBNI7z0+ff1s7HRagVq26LErzPZ7japuWUNM2+z7Ik3ZlvcWjoEtlpV9qR1jUXolQlp2DWJ WeeWyf/htU7swwqD6DKDMPNrwYMqkiCXi5lhNckKNQq1g5BLBcDh65KssofFmnQr1n6/dcz3 mcJdqNoiA3XE+ZHrhqxXoNA3YBIx8YlyQ5YTlI2sqrqakBrUsZSNpVC7EsV3k8idXdz8w9Fg 0t+XrRgfglbcva+htN9kRhQ5cu4qOWeWJx4PhaMB7FUgXTHihSkemaDCzwTiQKV2wSJ5tNIz BOCH0DDXdKOQ4u+8RILppLoL2Mj/qJcNMnMDyd4Bi6thXmuILQsJoO4bU8cEeACjKlEosDwF 0LgPrcClxzDFE1KCIIjN4qasijIz6+KvndkjMuoRkOyENH40fuVl7qiSHlmwd6vsDAWNbiaP qQe69Xa8Hvpie+dqa/vF6wjuVX96/171/r3qq9evnz1/gUfDv9tNBrLH00qZHX/Z7eDxup4m ESFkOsDNzSQFWD/5ySG+REK59I3TtDvHrZkOn9iNpn9y4ufHlWb5rZWiA2Zxk/KkRdGSOzyQ NEPpodBEkBvB6kfNweHp1DynxLZGiW8oJnbON/GVbLP4trj1dAga8RaiVzlJlnyNppEw82th jGk6M5qlxClWGV5lPKHWGJufz3+7qOygDV22ASq9NPqW9ImJ2U0MuAlsoMe/boSjQTWzIrcb PEG6e1/HDH5TP6LIci+Us7w89m61PzydJgMVu9GE6ejSL+Xly523z5l9LDQHSEckDqGLo8zW v5lMbURy20rNXDXIRFB2EQuxRrEWm4U0BQBYTW9PS6IEQVw7bsqqqHDtI+vbQreWTvG80y40 Gzaz0V8cATGBk3TkJ+rA9eTL8CgKsiML9YP0yK+cYLE8OV670q2O9R7IAgDY3rna2rna2r66 tXV1a+ulBa8tK9kvGkXRq1ev8vDpcCCRzG40QZa15oZQPwt6jn+ZjaOZkCLspqBYVSGRUB0y PbuRbCZAAqyNPH/vtBuPwcUSsZHSN6d+MPOyKEyYi+2zlhBMzX6UPnQPu9Vjvax2owmDE3m8 KtwW5rVLrMqgce3OcbWbnRMK3do+svvW7hxX+30z7QAgs61R4puJmZ3rR83BqWvSZr02d4iy ftQcnI7W1CFA3ncrKu3cehlKgqwT8CnIqgn2EZ6ANOsyN8sitTBDLBdjw2oQapQcQC4+WX5Z ZTSWs1eJf9BDXBdlpNUWmUS6XVR20CYuW61pWjcUDk7j+Ax9otyQC2PJ4hkoUgKjxlIkZ7ni u6FkWyUBIPv6kTOnN+yXuWizpN9ERhRo7qic88pTP2j1+9m+OXu32u92ocQip8lwCAfx0YFU XU0Skiu5JrDYEfFDaMPpz2z9mzS1yTVQ/NRRYlu8mduNJnT3u9wgU+7nQdtFLMQaKlSunAtT 5M5KFS4qMJonNwUoM28y6ZZRsAnp9VxWJgjiJhG9yYxbzHdi+RUorbHwNnuVnYeYLXD6RBc4 Jl4XEyVLhTWQR1RQuOlLyC7mr0+effvy6k9ffsn+PX3y+MXzZ8++efr4yeNHj75++PDhNy9e PnjwIIoix3EcIbnsZq70Cf8glqI1jvg7vJxegCuc3ogjpprpxYYMeg5bHGyOKo2XDV7BBNFl +ThjCGTvxEBBz4HWWB8ZS0d+kkimToW/f601xp9zSQQ9h02QyZ2N1FLc76YSBYkbsZbFc5TF EUpKaVtN4qy4XBvcFDBb8VqnT3psc8MbpqziuAUA6+oQ8veOI8ZdhF75G70kjDqiZfg2y/6j tJgTh8kNI2pX2E8uUItUNlSR9CPWURsYVpesVKMQ+FzYklXbShMr6DlSfnwhqooMkTNpYrIh Cl02glQ3RL2U+rJlWuQTcbOrMkIrM1NR9SFVUhSkr2wsioLm61iJ4rsBiL3luCVYIfV+zIgF 8Rq67iJS+E0uC0BSZ1KQclfIKfti1Dsr5RGGBnwu6MhEJXx5dGMhedSX/J82beEVHgspKaYj 6mFDaKPpxoz9mzS1EYMpbYt1YmzRIT2hfv4kje/msEYuj1xDk8jSQEUpsFS+xVUC10hseJop gMp9zNUti/WAJXUqGzl0JgiCSLGiKAJiwXjt2uXR5h0c+MuT5zs7t0xCfvH5Z7u7u7Waez6/ Fl7bGh6UujqSIIiNI76aeb0dwqJkIDaBa1eab4YvW6XZN8piGyUMQdxgQrd2untBbfEGQd0v QRAbz005Qb9a6mcbOdO7evb4i88/M/m7c+fOfFl57exnPK/PMeRrC2Pt0r/qPk/cBbIhYhBL gjqEDWQDG91mi7TIqrsyTaWMKt0St4vMmWNisTUWK/U8BLFx2J1jMPwFJuJNwGvvw5iWRAmC 2GxoryhBEARBEARBEARBEARBEDcL2itKEARBEARBEARBEARBEMTNwuiWSeLN4F9/+bFhyH85 +sX29vZShSEIgiAIgiAIgiAIgiCIdUEn6G8Q//O//4c+f+s73wELXr+Ossrwdz9898MPP1yh aARBEARBEARBEARBEASxOt7sE/Rem7nUP3Rr8Z37NTeUgmUkL/NH0oXg2avsjfxEEzh7nosh BiohjzYdkY9+9jP0r3r/fvXe/fsffZQ9efXqlcKkCkK3JnjC14wAAAwYSURBVJn1zUZTDbJH SIEUlVFuyay+Cqnyz5X31cfBhOrPlpG2yNhM8nzl8LnO/DsmPiq2TnJiJpAiS/DaM7bNmSMu maQqrlGvRVhG1QBN+9INLJ2ViDSbr0FilZNW073z7Y0bdZSRR/t8xaxejIUVayHz1dLV5zg/ sjsWa2n+EfUj+HigaHyCDL7J7xMEQRAEsZG8qaui8Shsv888OOxWx1EUReNq91AaorbGUcxF xwYI3RO/F0RRFAU9/4QL7LX3k1fj5CcU5SeawKkwJ302UD/Ofgz76eDZTJ7idDi237Im/z09 /OXwHz7+r3/8t1/9078P/rn/n2+9vnor+jb7+/tf/EcZO99U5JKVywgp/eIy4nDi6JFY8tlz qXry0R3Hv0zehqOB8Q8Ph26tMmimWY9hXzGT8drWPiQVNWgOKplCXjuLH/T8rOaz6kQR/Rzl AtEWWf2oOTidZS46c0RGrCUuByxIL3Mh85BzW2YBzK+FMaZRZhVpPZSRVu7eEacsjToWyFqM ueklqEYn+XIa7+pzNEXhjjFQP6J0LohDR/MqIQBBEARBEMRaeFNXRe3ORRRF4xb7zNmrAADU D1qTacA8Dy/95FVKMJ1Ud20AAHu3ygeun8ULlQCVvXjNSX6iCQwAELqHg2rLScJ4w77TO6oz wU3lKUpHwgIAgA/eu333/e/eff/tu+/dvvvj2xZEEeRn59/54KkckRCRS1YuIzmMQRkpkWqi 8mFOs1kdjOJaF0yhldUVPeFoAL3zTLj6Gb6CGa8KpG/szsW42o1nfuGl7zQbdvqc1j+Xj77I 7M4xaFbP1cwccTWsUa9NsMzqZLA7F2a91SaYxZwS0srdO+KUsVHHtca43K8Xq6+l62wXJdwx 6voNxwPqvGg8QBAEQRDExvOmropK2I0mxCtE3rDfOoi/1s42VE26FeYYMLssmS1oicfiwtEg nRUpn6CvvNNu9fhoL31z6YMcqVges3R4nj6/AoB372x99ujPv/3qD797+PsHX38OEQBzteyP fvJV9n+t1m7X+GNP+UmoWrxfJglT6Yo7EfmQXjtTxq3FyQlJXVPSksXLSApTWEbqjKS1ctVD hsZBNa30fvNgTx2QTXM0gHQOow8m1PbKntMfehC3NWQ/NrE8FEWW9VrcZiXuLpGsCVttDzkT zETMQ6IdgniAsuZ67mF3MulW5Bsham7I5it1BeJtJ0LcXMH59QoVQsqS8OooLFNzPbeGSi5Z LO4z2S1mwnazQrMsQAselSKpYJIAZobVJSvVKATkqPpIuIkE8SaaW2eyUAoDyoaRunddh69B KH1ccvl5QfkiuRj5btdVmZGtnPqQKikKYimag4l2WCz21qG2x5mLfxXHN+/WuHHLSnMU8Npp 4KxX5+5PUmLujlHXbzge0ORF4wGCIAiCIDaeG7MqCnbnvDmoWJZ1spdscKufxd9aB9NJchQo aA4qislZGhgA4hFspVsd654A/spr74MQyoEhN0I2kscgHQnLAgD49R8fRLf/tvP9Fzvfe77z zvMI4BP/00/8T3/ziQ8AP3j3UR5h4u+ds8eeQvcwOwnVHMTj3DhM0OP3IYohK2fxzQVefJHB WR1L6rqhKXRVmMIy4kgXxy3LsirT42zbTva8Mmiea/fyVPZgMArBG/rNhmb1dDaEBVl7t5r+ 17kI4sbGzfBYdeh6sVWQ91rMZiXvNL5LJOhBvLk3aeZHl7XsQoT8ggdulxPSIST3kqRP2MSH u+c9x+kFFx2bCZn3FVm+YlcgSMj0FdI+vLn1sjuckBpJWHUUlgl60D2B+J/BKETsw9ihYE+h XphkgWV+LURwRWKkcjE1rDpZsUZhdhByCQAm3elBeiD3xA0RlbFYAABe2zrZC6JILERe2mUh l77KDwrPRw1d+WIY+W7ZjIrKqQkpun6jWOrmYKIdImf9LEoIev4Jay7hVZKgYbeWarf6HCXq R73sxAn0hx6/B1OHwh3PD+LQ0byWJgBBEARBEMSCuDGroqFbO4TzKIqiczjkR2b5YWa70TTa 9GF3LqIo2DvJl3bkJ2jg0D3xkyPUOeII2UAeo3QQLADYuv3y1tsvt3Zebu1cbe1cJefqU3o/ /zj/kI657UbT6Q+9cDSYpAPhSncyGYyCPAwvnxQyhPrZuNrdTxYIsQDXDk2hq8IYlBFDfm9X 0Ev2YQrPiybxdqMJ08Ab9mfeo6pBOLwfXvpMxp2LeA7J3OLLXUNGx+hWTLZZqbLn9PctqzZq JIcZ4yYcjgaQ9SnsBQ/MLie5Q0ijpF2VlHgMl3hKlq/YFfCJsJuVKnvSksEi9MqE1EuizJrp Btn+ULYPKwyiywzCzK8FD6pIglwuZobVJCvUKNQOQi4VAIevS7LKHhZr0q1Y+/3WMd9nrvDO R7n0UZeqeY6+Ql2nke+WzKiqnJqQGtSxlM3BRDtUTnnPaR4efWXUra0tR4TkogZv6PfGPX/o QTA13sSJueP5wR06mtdyBCAIgiAIglgQN2VVlJlZ52fpVbC3Nea3h0mhpCVLzaJq/MrLhvyV 9LiVvVtlR8hodEkemC2dmFtvx+uhL7Z3rra2X7yO4F71p/fvVe/fq756/frZ8xd4tGRjYPYz UFEUTzWV8CHtdNUsl0wKcC1JrK2tM3kYwzKSc+kct9BFAwPx/JMTP74zAkA6pYvGKGgfaTBB g2A6ybNJkW7xJZaBSZHl2+IuoiiKjqcVwx27+KV4+NUNpRMHAKkrKJfIQvUqJ8mSrws0EmZ+ LYwxTWdGs2gvAynCxDG1xtjXUSbSyt272SBhHsk1GpV0naV993qZYWDA/Z6PY/aqTLe2CTlC /aDlX7pDv9mo71b9S+/SL13rcnfM3/oQ3weBun7D8YAur6KHBEEQBEEQ6+amrIrau9V024F4 IWLo1tIpnnfahWbDZkaM4sWNTOAkHfmJOnA9+cI8ioLsuFX9IPuRGilBlTy2STqIFSwAgO2d q62dq63tq1tbV7e2Xlrw2rKS/aJRFL169SoPn45fkxTZ/TyMlJi55ZDJGbFkr4B5UhsJUuhS nUHCmJSRivrBzMuiMKnmq5VZSwimih+lF64By+8zE4J1jqvd7IKH0K3tJ9uXufL0hv25FjsI I8yKrH7UHJy6bs2quSHUz4Ke419mM1S70cwOZos31tWPmoPTEdYhgNx5FSbOI3cFQiKQ992K Sju3XoaSILN5PgVZNcE+whOQ1tvMzbJILcwQy8XYsBqEGiUHkItPll9WGY3l7FXA7pzL66IG 0spDAvUgQQlS+go/qPGPhq5zBt8ti2egSAmMmsPMcqa1B+kiVK+Ku7W15YhSP6h2u36zEY8k 9rtV6UtIBIU75n+oMVnXR12/4XhAmReNBwiCIAiCuAZEbzLjFrPvIL8pqzUW3mavsiNBswVO n+gCx8SrmaJkqbAG8hilI/DXJ8++fXn1py+/ZP+ePnn84vmzZ988ffzk8aNHXz98+PCbFy8f PHgQRZHjOI4oPS9aln0uR6Y7GzLoOawl48gq21wPTMoI0bCojDCTZi+gNZafK5CDZU8SGXSp sHtcWuh9Z0Ih86kxt9KlekrXpV3LUt9gkCLjO8DsSa/HNGu8B5Gr57gFAHKHEPSEJ/yDOMHW WJAv7hJUvYqcav7eccS4i9ALqdCoJIw6omX4Nsv+o7SY46SdqEK7IrMsUotUNlSR9KMkgJlh dcnKLkaGz4UtWbWtNLGCniPlV9gv67p3PpLc6HgL86WvdKmiRmypFblO3LCqjNDqylRFfUiV FAXpK5uD0cBA04iSeLm5pFcsRd0aME17xTkq1JYGpOwH+R/OoHxNZbJkcsT8iMF4gK+mQl4K AQiCIAiCIDYFK4oiIBaM165dHm3eofC/PHm+s3PLJOQXn3+2u7tbq7nnm6cFQRBrIL6aef4O wWtbw4MZ75VdlAzEJkCluSRWadh5mvMmoLfVMrRbfY4EQRAEQRCElptygn611M82cqZ39ezx F59/ZvJ3586ddQtLmOO1LQHzGwnmiUsQhjDVbF/+oThiLWxg298EkRYlw8p0kTKSf/9neTkm zXl5yq6+Sqy+s1qlPQmCIAiCIAgR2itKEARBEARBEARBEARBEMTNgvaKEgRBEARBEARBEARB EARxs/h/w5UmIVCYXE4AAAAASUVORK5CYII= --------------84CE7663300E0D1A611766D4-- --------------423577E4CF318AEEEE154EAD-- --------------CF0D29502F9E9607BC75947E Content-Type: text/x-patch; charset=UTF-8; name="win32-stat-deletion-v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="win32-stat-deletion-v2.patch" diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h index 05c5a53442..d72950880a 100644 --- a/src/include/port/win32_port.h +++ b/src/include/port/win32_port.h @@ -53,11 +53,13 @@ #undef near /* needed before sys/stat hacking below: */ +#if !defined(NO_STAT_OVERRIDE) #define fstat microsoft_native_fstat #define stat microsoft_native_stat #include #undef fstat #undef stat +#endif /* Must be here to avoid conflicting with prototype in windows.h */ #define mkdir(a,b) mkdir(a) @@ -253,7 +255,7 @@ typedef int pid_t; * The struct stat is 32 bit in MSVC, so we redefine it as a copy of * struct __stat64. This also fixes the struct size for MINGW builds. */ -struct stat /* This should match struct __stat64 */ +struct _pgstat64 /* This should match struct __stat64 */ { _dev_t st_dev; _ino_t st_ino; @@ -268,12 +270,14 @@ struct stat /* This should match struct __stat64 */ __time64_t st_ctime; }; -extern int _pgfstat64(int fileno, struct stat *buf); -extern int _pgstat64(const char *name, struct stat *buf); +extern int _pgfstat64(int fileno, struct _pgstat64 *buf); +extern int _pgstat64(const char *name, struct _pgstat64 *buf); +#if !defined(NO_STAT_OVERRIDE) #define fstat(fileno, sb) _pgfstat64(fileno, sb) -#define stat(path, sb) _pgstat64(path, sb) +#define stat _pgstat64 #define lstat(path, sb) _pgstat64(path, sb) +#endif /* These macros are not provided by older MinGW, nor by MSVC */ #ifndef S_IRUSR diff --git a/src/port/open.c b/src/port/open.c index 14c6debba9..09144351a4 100644 --- a/src/port/open.c +++ b/src/port/open.c @@ -13,6 +13,7 @@ #ifdef WIN32 +#define NO_STAT_OVERRIDE #ifndef FRONTEND #include "postgres.h" #else diff --git a/src/port/win32stat.c b/src/port/win32stat.c index 2ad8ee1359..1c9c01cc98 100644 --- a/src/port/win32stat.c +++ b/src/port/win32stat.c @@ -15,54 +15,10 @@ #ifdef WIN32 +#define NO_STAT_OVERRIDE #include "c.h" #include - -/* - * In order to support MinGW and MSVC2013 we use NtQueryInformationFile as an - * alternative for GetFileInformationByHandleEx. It is loaded from the ntdll - * library. - */ -#if _WIN32_WINNT < 0x0600 -#include - -#if !defined(__MINGW32__) && !defined(__MINGW64__) -/* MinGW includes this in , but it is missing in MSVC */ -typedef struct _FILE_STANDARD_INFORMATION -{ - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION; -#define FileStandardInformation 5 -#endif /* !defined(__MINGW32__) && - * !defined(__MINGW64__) */ - -typedef NTSTATUS (NTAPI * PFN_NTQUERYINFORMATIONFILE) - (IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID FileInformation, - IN ULONG Length, - IN FILE_INFORMATION_CLASS FileInformationClass); - -static PFN_NTQUERYINFORMATIONFILE _NtQueryInformationFile = NULL; - -static HMODULE ntdll = NULL; - -/* - * Load DLL file just once regardless of how many functions we load/call in it. - */ -static void -LoadNtdll(void) -{ - if (ntdll != NULL) - return; - ntdll = LoadLibraryEx("ntdll.dll", NULL, 0); -} - -#endif /* _WIN32_WINNT < 0x0600 */ +#include /* @@ -112,7 +68,7 @@ fileattr_to_unixmode(int attr) * Convert WIN32 file information (from a HANDLE) to a struct stat. */ static int -fileinfo_to_stat(HANDLE hFile, struct stat *buf) +fileinfo_to_stat(HANDLE hFile, struct _pgstat64 *buf) { BY_HANDLE_FILE_INFORMATION fiData; @@ -159,119 +115,83 @@ fileinfo_to_stat(HANDLE hFile, struct stat *buf) * This currently also implements lstat(), though perhaps that should change. */ int -_pgstat64(const char *name, struct stat *buf) +_pgstat64(const char *name, struct _pgstat64 *buf) { /* * We must use a handle so lstat() returns the information of the target - * file. To have a reliable test for ERROR_DELETE_PENDING, we use - * NtQueryInformationFile from Windows 2000 or - * GetFileInformationByHandleEx from Server 2008 / Vista. + * file. To have a reliable test for ERROR_DELETE_PENDING, this uses a + * method similar to open() with a loop using stat() and some waits when + * facing ERROR_ACCESS_DENIED. */ SECURITY_ATTRIBUTES sa; HANDLE hFile; int ret; -#if _WIN32_WINNT < 0x0600 - IO_STATUS_BLOCK ioStatus; - FILE_STANDARD_INFORMATION standardInfo; -#else - FILE_STANDARD_INFO standardInfo; -#endif + int loops = 0; if (name == NULL || buf == NULL) { errno = EINVAL; return -1; } - /* fast not-exists check */ if (GetFileAttributes(name) == INVALID_FILE_ATTRIBUTES) - { - _dosmaperr(GetLastError()); - return -1; - } - - /* get a file handle as lightweight as we can */ - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = TRUE; - sa.lpSecurityDescriptor = NULL; - hFile = CreateFile(name, - GENERIC_READ, - (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), - &sa, - OPEN_EXISTING, - (FILE_FLAG_NO_BUFFERING | FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OVERLAPPED), - NULL); - if (hFile == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } - - memset(&standardInfo, 0, sizeof(standardInfo)); - -#if _WIN32_WINNT < 0x0600 - if (_NtQueryInformationFile == NULL) - { - /* First time through: load ntdll.dll and find NtQueryInformationFile */ - LoadNtdll(); - if (ntdll == NULL) + if (err != ERROR_ACCESS_DENIED) { - DWORD err = GetLastError(); - - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } - - _NtQueryInformationFile = (PFN_NTQUERYINFORMATIONFILE) (pg_funcptr_t) - GetProcAddress(ntdll, "NtQueryInformationFile"); - if (_NtQueryInformationFile == NULL) - { - DWORD err = GetLastError(); - - CloseHandle(hFile); _dosmaperr(err); return -1; } } - if (!NT_SUCCESS(_NtQueryInformationFile(hFile, &ioStatus, &standardInfo, - sizeof(standardInfo), - FileStandardInformation))) - { - DWORD err = GetLastError(); - - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } -#else - if (!GetFileInformationByHandleEx(hFile, FileStandardInfo, &standardInfo, - sizeof(standardInfo))) + /* get a file handle as lightweight as we can */ + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + while ((hFile = CreateFile(name, + GENERIC_READ, + (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), + &sa, + OPEN_EXISTING, + (FILE_FLAG_NO_BUFFERING | FILE_FLAG_BACKUP_SEMANTICS | + FILE_FLAG_OVERLAPPED), + NULL)) == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } -#endif /* _WIN32_WINNT < 0x0600 */ - - if (standardInfo.DeletePending) - { /* - * File has been deleted, but is not gone from the filesystem yet. - * This can happen when some process with FILE_SHARE_DELETE has it - * open, and it will be fully removed once that handle is closed. - * Meanwhile, we can't open it, so indicate that the file just doesn't - * exist. + * ERROR_ACCESS_DENIED is returned if the file is deleted but not yet + * gone (Windows NT status code is STATUS_DELETE_PENDING). In that + * case we want to wait a bit and try again, giving up after 1 second + * (since this condition should never persist very long). However, + * there are other commonly-hit cases that return ERROR_ACCESS_DENIED, + * so care is needed. In particular that happens if we try to open a + * directory, or of course if there's an actual file-permissions + * problem. To distinguish these cases, try a stat(). In the + * delete-pending case, it will either also get STATUS_DELETE_PENDING, + * or it will see the file as gone and fail with ENOENT. In other + * cases it will usually succeed. The only somewhat-likely case where + * this coding will uselessly wait is if there's a permissions problem + * with a containing directory, which we hope will never happen in any + * performance-critical code paths. */ - CloseHandle(hFile); - errno = ENOENT; + if (err == ERROR_ACCESS_DENIED) + { + if (loops < 10) + { + struct stat st; + + if (stat(name, &st) != 0) + { + pg_usleep(100000); + loops++; + continue; + } + } + } + + _dosmaperr(err); return -1; } @@ -286,7 +206,7 @@ _pgstat64(const char *name, struct stat *buf) * Windows implementation of fstat(). */ int -_pgfstat64(int fileno, struct stat *buf) +_pgfstat64(int fileno, struct _pgstat64 *buf) { HANDLE hFile = (HANDLE) _get_osfhandle(fileno); --------------CF0D29502F9E9607BC75947E--