From f761ab55f9be8bf088ca873c016610d16bdb1010 Mon Sep 17 00:00:00 2001 From: Phil Kallos Date: Wed, 26 Feb 2014 01:11:16 +0000 Subject: [PATCH] Initial implementation of kinesis-s3-sink. --- .gitignore | 1 + LICENSE-2.0.txt | 202 +++++++++++++++++ README.md | 92 ++++++++ lib/hadoop-lzo-0.4.20-SNAPSHOT.jar | Bin 0 -> 193375 bytes project/BuildSettings.scala | 82 +++++++ project/Dependencies.scala | 69 ++++++ project/SnowplowS3SinkBuild.scala | 46 ++++ project/build.properties | 1 + project/plugins.sbt | 1 + src/main/resources/config.hocon.sample | 60 +++++ .../package.scala | 39 ++++ .../s3/CredentialsLookup.scala | 92 ++++++++ .../s3/LzoSerializer.scala | 103 +++++++++ .../s3/RawEventTransformer.scala | 44 ++++ .../s3/S3Emitter.scala | 207 ++++++++++++++++++ .../s3/S3Pipeline.scala | 43 ++++ .../s3/S3SinkExecutor.scala | 35 +++ .../s3/SinkApp.scala | 135 ++++++++++++ .../s3/sinks/ISink.scala | 26 +++ .../s3/sinks/KinesisSink.scala | 173 +++++++++++++++ .../LzoSerializerSpec.scala | 109 +++++++++ 21 files changed, 1560 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE-2.0.txt create mode 100644 README.md create mode 100644 lib/hadoop-lzo-0.4.20-SNAPSHOT.jar create mode 100644 project/BuildSettings.scala create mode 100644 project/Dependencies.scala create mode 100644 project/SnowplowS3SinkBuild.scala create mode 100644 project/build.properties create mode 100644 project/plugins.sbt create mode 100644 src/main/resources/config.hocon.sample create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/package.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/CredentialsLookup.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/LzoSerializer.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/RawEventTransformer.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Emitter.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Pipeline.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3SinkExecutor.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/SinkApp.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/ISink.scala create mode 100644 src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/KinesisSink.scala create mode 100644 src/test/scala/com.snowplowanalytics.snowplow.storage.kinesis.s3/LzoSerializerSpec.scala diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/LICENSE-2.0.txt b/LICENSE-2.0.txt new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8eebd03 --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +# Kinesis LZO S3 Sink + +## Introduction + +The Kinesis LZO S3 Sink consumes records from an [Amazon Kinesis][kinesis] stream, compresses them using [splittable LZO][hadoop-lzo], and writes them to S3. + +The records are treated as raw byte arrays. [Elephant Bird's][elephant-bird] `BinaryBlockWriter` class is used to serialize them as a [Protocol Buffers][protobufs] array (so it is clear where one record ends and the next begins) before compressing them. + +The compression process generates both compressed .lzo files and small .lzo.index files. Each index file contain the byte offsets of the LZO blocks in the corresponding compressed file, meaning that the blocks can be processed in parallel. + +## Prerequisites + +You must have `lzop` and `lzop-dev` installed. In Ubuntu, install them like this: + + $ sudo apt-get install lzop liblzo2-dev + +## Building + +Assuming you already have [SBT 0.13.0] [sbt] installed: + + $ git clone git://github.com/snowplow/snowplow.git + $ cd 4-storage/kinesis-lzo-s3-sink + $ sbt compile + +## Usage + +The Kinesis S3 LZO Sink has the following command-line interface: + +``` +snowplow-lzo-s3-sink: Version 0.1.0. Copyright (c) 2014, Snowplow Analytics +Ltd. + +Usage: snowplow-lzo-s3-sink [OPTIONS] + +OPTIONS +--config filename + Configuration file. +``` + +## Running + +Create your own config file: + + $ cp src/main/resources/config.hocon.sample my.conf + +Edit it and update the AWS credentials: + +```js +aws { + access-key: "default" + secret-key: "default" +} +``` + +Next, start the sink, making sure to specify your new config file: + + $ sbt "run --config my.conf" + +## Find out more + +| Technical Docs | Setup Guide | Roadmap & Contributing | +|-----------------------------|-----------------------|--------------------------------------| +| ![i1] [techdocs-image] | ![i2] [setup-image] | ![i3] [roadmap-image] | +| [Technical Docs] [techdocs] | [Setup Guide] [setup] | _coming soon_ | + +## Copyright and license + +Copyright 2014 Snowplow Analytics Ltd. + +Licensed under the [Apache License, Version 2.0] [license] (the "License"); +you may not use this software except in compliance with the License. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +[kinesis]: http://aws.amazon.com/kinesis/ +[snowplow]: http://snowplowanalytics.com +[hadoop-lzo]: https://github.com/twitter/hadoop-lzo +[protobufs]: https://github.com/google/protobuf/ +[s3]: http://aws.amazon.com/s3/ +[sbt]: http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.0/sbt-launch.jar + +[setup]: https://github.com/snowplow/snowplow/wiki/kinesis-lzo-s3-sink-setup +[techdocs]: https://github.com/snowplow/snowplow/wiki/kinesis-lzo-s3-sink + +[techdocs-image]: https://d3i6fms1cm1j0i.cloudfront.net/github/images/techdocs.png +[setup-image]: https://d3i6fms1cm1j0i.cloudfront.net/github/images/setup.png +[roadmap-image]: https://d3i6fms1cm1j0i.cloudfront.net/github/images/roadmap.png +[license]: http://www.apache.org/licenses/LICENSE-2.0 diff --git a/lib/hadoop-lzo-0.4.20-SNAPSHOT.jar b/lib/hadoop-lzo-0.4.20-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..137dd4d43a9566a14b8833896f3bfc9aa4ac6dd6 GIT binary patch literal 193375 zcma&O19W8Fx;311l8&8(klv;{L z5CZ(LNHqzS>L;;#dsd_(vXr8db2eo)3N|!SB9kJ(8+k(U;m;LGCMU_C`zGOMBHB>FwMo`-Z^xeB?~X;gw7ax{{@F7ipfrtt9{}i|o*CKM{8!)qCj#al2nQDnBP(mq zzd=I(18HtxY-eZxH$b$12mbkedq)!|Cks2i-9lwy{vZ|bjm@h`ytCpG@M z-TxDB@psP`_y1<{PhS1kI3WIm{^#Re9UFfJpn(hogz?ArFZ%zJ+zNk@Tw0UX$lAck zDOnBLUU>=Q>&xqgx3P1Lq&;rRl!Ba+T5@(t1hK%wnwWXavH>({-8fN49G|#OgP;69 z&b&IC)6k`a-nA*LL=&eOE}~Xl&&6B1S(a+4yt%MhvsuZevN^fqb9ze#B7U7>FURTY zch&>n%v*2cjNjcY`41-gLs1MxT4{k+OHbuQRT)v1O6A7&sS-67AJ*$WS>FiFgJI3b z3w~a^yEnSp*9&ZPdwqF*-9>K+GoON^{uXyHFQtO!MviSnJ5=$+pIUtE^hr{%hn$L^ zSWGD25R)oluf|&3ZKRYgz_MK?FtHA7Ea3taSyqtjB${+K*K{|~(Lhm3iMCC{ZOe5s z%rhsgEM?R;q6<#z!&}_N5-}kpQx;q3&MwPrbW!b2B>4dCi!H;$&+dvgOQ1@r&C6t( zSQ!bM3LDZgWA7wWcd9H_Xs=7weM9a-W?jwxNav|!>zJoB08q^R=;n!x#B8bkX4t!y zecsfcJ!N)zbZSJiW;169=ud%XFx}SISffq0+AG;(q)J<#htd|fml98IMGZa?w2aZ( zb~^|lo108+HJ$^*Jvq&vT9tH)J`W@(^FOwwDYM5|&Ax-StWjMY)9*g#_eHPaUN5OG zGkjdNE6=Q_EWQ`;|CZlbmKF-xUp8YB5=wV=I8gMLlUb5WvyZ7RkZ%?pTbMVaudM`) z>HBg%k#7kVHDHi#hJ1nQ}*L>I5f@lZSaidEdw!vOU{dLJ9zrxVtzw1WIfqNzH!{Y}B^A zI=0q}vCOi(nhGL0Td>5I1SyF;9>sxdO7hM3QAeg$b|J%N}u^TRjEFN38bdHqR`c z_YB=5ncV})XB^a%H4B>w*!m5VcZO+^%%$~%$gV#}5*be8W51k5j; z!?P6cP8L3|0BpWU@1)Q459?X)6Q;y-dK8fsheAzO8b@)7PO$5+1qXEM_jc(EO5oY2`)F4MubJjdZt?^hOL>*6C_@pC@* zr?H$ju<6@cd*MNs%-82>V)6IW$^+d4J_EeYq2x;~%`ZTxp+W>F%a6cW5(Kox#l-3b z8wq_#M2wnCE+jgSpi)`!3RWm{fg~#Nb3(V@rLJK)rGF_8v}L(oD<60#_q z5C@Or147$CbdPm3QVJ1~fOl}pfGTLkXQg(eHdBok5>@kO5{aIo__epcDE@^bGCZE7 z!H}zQd@_j5sb(s56P1isMa^ev;?XB*Vpyzs^rEM#ZknPuChQU7;=^r36jou5Zb`*L zrXr4tuFP2leQ>eKI@HR8)Zij=w(2SsXLcAVPtIsrWH+>5FD>^wf*JsZCX6~5dzedp zxd}akesVBI7y!2=TN!1)=gdAVE4IqX1DAuyqs>lelq#sYXBdO_u)cD8pEHu^$4e(k z11*jdDavD|2|}fqwQ~1OH=acM$;B~KqPYMJ(is7w$KQ3i!lW(Ay$+hn9$=yyD`k(Y zy6-x@?Jvt6M9Uq4f-AKpJioN!_Qa5qQ-A$7PJ=ItHgruwtnGyerubvXkO=nltEf|E(rf z?as#onr)P;O<{Wg{;+nHN~})q{xx4U0M7#Wa)r{qk`)KMDZNc5GkBxf$strVFxNb~ zO-pJQw;K7yV(Ya$rSEeclRMAmXP_orXw#It_(r%`)6Fi!l_z)2)d(`TkeubqKE;&* zcQsFpS<}g_Q{`&ch+t!6u@eE2h9LX^dulQXKNeNB0td|ls+iO*KB`8el|9jeks;Kl z=J;zS^+~Nbo>OteFRS^fsC4q7jfMaZCXIFV$_Ox-g&Z?nK>uo!Svp&yhpUAgLn-OQ z&4Ot9ny8=%zgG|ji^iGYy3eFz624=AD_KU_TsX&i_2j!^PW0Ql%%l&B?fVhUtAANb zDp{W~MfF_GQ8_(_QwbP}KX6>ew1l*>2(|gsIdk z#B|CGee)rcvX#>m(9%P(0{Kuw!uJZiZ!;a|71zeUi=J#xE;4t%`$GB}_;#9!3VNzN zjyon@&$eDx5Luu|^fvNu44d$=i z_F6btHT7q`XwzVfjXSRl! z$P}^nn8&4Jk&?ObRgSYs(e!o|&Ql~j>oi!{P!Y=6IHkli>ll-|8QC{z#eOKNt76(Z z2U9R49+{QDYQ_r;eaj8TAb)9VCDQY@e#JyWsl z9#P^-@RP9EuCQ;jM1s>phND2w(FyZ|JkaIeq^rak!)rl8Yq}6yV2#OC(%AXo_b_{? zF#$|Rm7&L+R!}GjlO@i~C3BfZCo4P@EwV3A?LJ4yt4(gAPD{#3QLI&xuSOZ>PC&Q; zqdJh@CMx?AH(ex&6XVwr%7^;#zApy=UYsR|kg|um^Z+(|Uxx!aw}FokT3u)cF_${Q zLXjxhF=sO6p;*)Mh`Ky6l9(1}o;=&p-}%AJwwC!}#39nSScO$muxAL+S*%l&P;?n@ z;>e`7LpyOqt3mKGI&`0SXm+8T*!cNA z&rB|EvoLWmyzZr0lqI$DD^IP%e1F9+2etTC@ZMc20fIG_*XUpilEHffJ=m<|OpiCH zEx%EI|nkrH{3q# z3@j+`m=129PdX^d0s$qCH4DIA&F}vb#Q&)X@FS>p@V)^7k^E7^O#e^>|4=Ib)DVAZ z)4ybTeD`Wu#UseexiLUiDO&O~t@fp&3Ix`TJ zfMW9eD?ZtwyrN1 zturG)mSsouk?qusZ3!gIwWlhuD=6(X(h>u(u-^xS3P0x|uY42XVYT3*cyA;z2J-0w ze#YnQ;Yti}CPXWUzl$C?H{-l>qjaypgn#0MOom)><{;ZL5>qYlgeVKSf(;}cxf`-! zItTqubJLDMp|)^xi~SX|U#KtGWti3q_e#K~bNw`_vlest)k3s+opK}f8+X8%>+l)+ zoNYQk*KoAi$vsI2u|@|owVrY*KS9K48nIu_Di$#$up6I0j^CIM z|9-b;0$#ji^ETlVd5J{5%N!AqN(Fm`E?i?V*79?;Bs|i|Lt!>j1fmn&KGD3?R>v*{^@}E zPrmU!-QU3d;oBGp5YS)lq`wsC|6jfd*}2#{TiBZYD+&KWLB$Q*1%3pc3vFp_p?nKi znM}nz{&S!dcN#%*#Js#PUKBt+FUMI3Cdu|F8m-SsV4P&U`!2{UBmxpX@XinRixz^s zE__^Wu0|%O>8!h+-*3-2KQ7uV`v%*QBG_xEz@Vwx%BDz=S&%Egxt@p+9)v2y5i_D7 zynsfq1<;GzLQSr$%YBsgppo10$b?ul#0$^kRaM(U9cEf;K}oj;%5Teo<6!XIa`|je zHmR)K*u5*{9Slr(Hy{swYm`Y2kwD+40kIp|QMEjs!x3eS z0Reb^>Krw@E!lT@nIIiz@XHp5|6tPi!M}$AaH4N)Su$^K!kiGC%qod|A`mU$EcS$Mn?LofM*lKdo;fub6MWL{(gcR0$n|M>|XqGo~PutbL2Sny?9W$P2W8XWV%8Oa~|& z5D>^8X9?@yGfvpT$=T7u(8bxr_|Ko6gsriOyNTm}GOSu1(i>&P}(swshWCW6_4{k40M?F$?haW(`yALKj9&4NUt9V0q8N)KRI- zRjZ@}bAVj|c@21fWf8f(h}dOAiKVlAox)Gqe*^NB>h3MV?XAY8TiSKIJp$@M`gyaw z`*QmW_`^Sh4`w%Zu^$ioR%Pf}E-8txdU)m5Ou!q*uV#-fz+5%scX7hAn&k=Gx7U)8 zUN}SKFVY{qu=_W+FXsnZ=XW-+zw@?t6k`2gb~^<=kiRqrddqJ7mTv9NKN~{))NX#u z$Eq=ZlzRHf-F?+!dgJ}B#;yH+$LB6X^I->6TloV2?KQukUBC$x7*SR-*i%_GQm!Ik zAB~0_xExNL9-k#b8h*6v$7E@E13o@9NP{@WD3G^~W#DTDHQZ=I-lBw$e9AbZ3?{P% z?GOGNSyCA@xlQrXsiwS!QoCOKMI$aEL?RPmu_^IIS>j7$PNY^b(W*o7q7mFPl*tQ@ zIk$?7ufCdX|LY!I0h<|%gDS*utRi%K9HfLYRtqxlDdBNf7&Gr&fSZh1T}j$o8Dis= zvN1ajhjm*a2a@fhU28&0XW%t?hFP~$U#Y>xlr_@Y)}21 zi|@=yj3#4#TWAXU8@n`zDW}canD|E*&YD$m`JwzUixJPs)wS^?_5&#RG{zm1BtSs# zU^BvXdod)7i?Id}`zWtk%2-IsX*pyBQnP0|@AU5fYYH23=?){NQMT^+uzGfQirAu9 zOWwc%;kJmwG(jNd#AZ^Xr69^+liM5lXn3I}9pAv-U6C8aWX;(}XWDuq#`(o1T4X9o zDwJwVF=toba$evu1ToqaDZOoP{X>&|!64xMtPe*H@NJVd(A5jW%e73qIAM+{G%Bez z7oB9BMI(PqQpR?{I5~tt6++WaionUdtajur}>$kB`sp-c{*_$Hh%DcHA)RzU-K$WO+3n+ z&yaz);U)#9hd+20%lC|^qcW$W`s@hpOkiqM8lj*<4`5Y8U$81AZPpwx zPoFl(E?+bVurj(iTO^T^#?emA7f4k$ogt-!#V~8@u#RcUuwKm5YN^llrx=z@;5e4j zYMErxx{YNz!x#zIIhRzrnnCD*C6pwBfOo?4As9BpdcX)mITH|Fr-@o~3!9Z}Ih(J# z3U)Y)mwH;S9NOx*j>-mDs!@yDZrj@B?$*Rvov@b&v$uv~Mxvi!%mWip;c(hDZDpi2kXU|OXr6E=YpH0Bh^~OaVK!{N%x_#@ z7oBpKOzm!v8YzvNEs{$0Y0yjbazSka0V~mMxN*cb((aRf0D^77{o=QrW&tA zK&DEXsfr`*rc`)$=BQfilzR{FUE@CM!sX&{oUGSY>37D6^VRuo(ycEftD9C^XH_&) zG;o%Lp<=ScX%#|2oS^`>au`M{c9f>SfFC`K zU%?Hz8`_%kZ3it;zvel7cH^dkuZE*0!3m7qxV)x@(hp^Aqz>YtRec@J0OSh?aT{9s z{ek;1+E_|4o@>B#jQq4j{z3?HM459;o2xJjKO)NjLXZ>aUV(h&CR{3vi+QJ{2i*%E z+z|Ch)I9>m4kBlH$wv3v*cwf~J^RNGQoDttD@XZ6x6^xB54Ew!==HI^QC!|CMBEyN z?`Evg;70-*F{z+SO$RFUe(!IbD=Fo!#nd7_!R6ULzNqI>Y8jCcEBlBGTUKyb>1`V< z#~EYJHAO6}$(&g?*4_u%Wt@~OPztg{kE5@ox-9qE%iOkq*$#FBFAX`aECje*-T3>vQpYGU%s>7-0wMZ=DYps7@>`Ij@9oOo{q zqeMV;b31=lUs;@(JTblx`B8{+aJLNJCZ)^iO7sD(Ru^E3MaT zZw4YSv-(6B6K?erm{RvDoXOI#!H!g0$>Qw?-1K&U3Nh#qnP$EwmxHDhuj#h(NUe3} zwaiCMNTn@!X*M@>Jm!(^9bjbws`cY34?#4!1YDMV3?{iQdc8j`YGWy1D%ZouRhf~D z5I3W=>T^gEmz?=!dsnn1B~26;EU;uUmrT~`s*5S&_wFwP`DU@nvSHgHH{Mi7Sdko7 zeHqoycR`X|kIZ?|Xy;mvVdRn2N8JT0-|dU4x1;s6HWrk-cez?zz*_%Tp!zB8<|rta zRPo?rr+RyV{bD7z5M*Q)2$Ak==L^(wDz)3fs_TtP>vNOK_TxBYZ64KGGoy(99LIp7 zDgu0YTY6+|?Ol+deRL{*deOxek5sOSQa^N3b_O@=XANuT*(Fd=9k5v@jPA~-@k*pJ$5lDk9Yg?CP&RDuC<7@| z;UjRrSzsS%&Ao6SewDtz;C*HPrpl%l!mKAUbT?5p+5bXV@p{BJZE+<6N*iDFjWzdS z4Ab~}K(awQ7^U|S8=4z*q)=+$DDjeNSX>Q6+(ya?bx8x1%Nw>Qh1!y{0<)rFmaZUh zr&?q3;+E}|tLgjI`ZE8~@_EO3$4@5pxx6KnRyWX0tN@KkJDbiZuvnFeMz)?O>KxL< z;Hg}&bn1>U_~ylB)A}@SZ`d#D6z##g%`(!+j&m|T|0TM-FUpkpHj`#p4eFC?fJRkU zzy_s#xw(ysZ?!86I9NbS3KfLP?rNhsg-AyU@!2|@9^&1V5+jzkT3roN>M6l)=`Gaq z{(<|N*Dr2(JQ18+EQCQ(&$jR$+uyGgF~Z9`!YA}&hvM%TSx>KagB(!;L?_MYBOaimZY z1~u;#XFTqpv5qK%t#_=Fj|z=;yEuo6B44e0+3sj3=qKKAWphTG1lyJ1HVVe+;?;oURdNl3oY^CnCTj~_Mh7cO4Vtk4=tOt9>b&B=H66gTih!lE(weZ$h@ zKLE|3%;}6U9j-o-m$KVvuI?GHR&h~r=`pJ-sjjK$9*{F`!nM2A6UAbppRJg0h_HB@ zTBd@4rZog6(!;t#DoChe#Zepc!^rg7fO?y)xi|Qxz1{=)p^=t|O3&)FU1J4B7KzIi{i|qyqAi z%y9H>yTJRhL|+z1{>>}S$ngx(_|G)$mSNgn^lUQchDfw&{|dI5D)Jljd&}FoPrD9U zjyIG_@(jQMk9yzNIN?{YXKwn?+`7@i;g%kPbJw>SLm|XeWD#vyRE4)3BXcKtj{pnk zOCg@;LjPU$XxrtVxBg=FlvGx_Y*Cr%gJR?uB+0(v>P}i!LT@{fp-}75?F})}J7ZmTqEje<(&A|C5338ng zxkPCAZ*LI10zfMI($5EGWuGWXj#f8E83FUApcjE`b@Z{xr964u)j*Gw%QSDmAuQa5 zduDnA6)Og>x!}5Poc5ybJQgUJ>v9ZbR`d?9z-ln93_k&s9 zv4iz&JP7&NCYH9&*FyD*XPRWh$;sphT<}=tWt>*>Bo75fw7X9RZqFlEN!=X$mXov9 zxX5PLCgUd6_x}E*Bh>@W~NLW3EI~7>HgDE&Z52W=xa)domE?R)TEr1yXb%$^Jdk4CuPpkEe~L4=YC6^^8EVt^2P$T#m%*1 zUD3}z*#T@B*t?%c%l^62qw!4w2R@C(lx68>G#oaum1YiFE4~`5i-q8vPfdqPcihcEaAMI-64+(M zFZ0+a{U?w0+^oxH#-OWM@Dp6dyQyT+LRa?*g-vbEzB%}AlvlW$GglatS0u;Ex=`wr zlWDZtlW*%uBPg+0M4nw7m?q-v>8vPq6+9ksb`WDtF#v> zWlB)%Ck{G!T2(JgpezNkIOeP}MDeT?L(FiQP`1@K;wGX2o|>^Smg0x9*&tE=_5{jT zKeD2=>t9nyFBNwsVXt#FIvu$q(UFEMFvb z_1EttLzxv8sv>cDNW$GSsHl`t-5rtcSkF|r`_nP-4y1wZDYGK8Xc`qLEl-}m0TT>I z!Z{-y19=sp@%72QeH*_C+-R(Sjk9;75P(<27nR>%it*hx-U0H|WhoV0Q+0Xs;K*pFMfrEr6D^p;j zr^WAHA5uPv0Il|vC!S>66G3(1#^E8dgeb!&Ye|OOo4MLfRdsU2jGK8L3F3b2htWp# z=_RP{e<2UcKZG=w#I8wr&WU1u(gsSC)p$Psq?*~X=3FYXQ6KryN#aK_&S83UXosd2 zPy}`M?Y9QG8L#-)k-t z(~=f#l^lp{6TV5+q1M(Jc(9Dq|5#a-)g_5ld}1HR!&kv3eOw@770w|jZTN8vX=HoP zCfo1T@xV>_Uh1uB{?-)6Tg?|a6s!AQqFn#uyEf?=6~D*1K%pP6=g71Simyb>#j%Bjp%A#gyU zZBFQzG4?0q=XV|0X_%HIL9{i?k`O~I&3k#$L=2pRi4oY4^ws!}c}3B6un?=`(|Z*ob<}vJ2QesG;zqi1njx8Y->L9D^or;6#~r9&I!P|SIYv|f z3bf%A$gtzo6c=gc&n3GM?J^wh43E@ner!s**bUpXEa3=?x$CgRaBAsXaa18-zR0S9 z$1Xask!&5zYKXLt6i-ub#CVr-9Bwh-IZ-`z$V{oz?9Y5jX2xA?Ui|9+#1rTd2R z7$sza9OxwUHR%qfYD#yh{Q91yCZoUO@r#6ck4q^!=F{f6xp5KeV<%;ORJ|sopF2`C za@l?Li%lLZ>W5yXn!FkeTZAY({(}B^X5`?hLICC+r#a zXkJs@my9ppH(fNgCu)HK%*mWmd5gwIZfoZkb<%!|Ef$)OUT$F$V2#LA@vNwiz^3v3NwqZw<|+ajz;Ge~PP+xq0kLl|vr>8(9`Fx!Q2$pM|l!{Ope<%De9 ziq}Hvrs0>dOo;AcmSj+aTJg>lzjC6CU32$pn0!2~a{E?Q{q@scjESFz3wy+K9(={c zr<8c%Upxq#`G8?*Qh;HeWl_Ta#9u8aA=WZFJRf3GW_yVwj#?zD|njnOlM^ikZh*I%m0A^AiE^Q5eU%qFsm^o~})nl`I@MnmB}VmLXaR)CQo;m&ro)hgTP ze!Qm9cj&*h?w7y7E>vfVVR*nTxdRrxBg!AzNyFq=n3s4AlF*WB4)h1lY1!zjS-ZA2ZMCd` zf6x2EMFt!M{t5e=bTxkFrD4u7XScgux1Vfsd7X^R*zEvU9klo>XyXRP1ZdWvw?&YE zh)`GlC^ixqp$y!MFeUdufgICU3HG++%0FOj+p<3w3~C{}#2uu4smFpLdg=NZ$%ZjL zbk20rUKqDg&2Bx!Revb!bZ}@q(Ft?bQ05d8UV(NST5TFVK_)v@npj?8kK?xzpL5?C zde*il0@KcO7DP}Bf6kbejKAA($)zv|>D>A!f&=Awp95jtOLJ+d6(qSv1Cw7sE8`I5 z>FQnyla4kYSx(>G)~ixp7NQjJYQ^_XgWkO4-gS4SeCaRC#0hWogCNpga1LuO&cDE!Pdi0`g$o|BS%QWqV zMI11wjSGM5**EUm3mMYR2lK;Htnimn8ZN4t`uj$Zd~$5iEe0t`tQI3VJj{jV-Ol$a z`vfk5ob7RP9{hLL^PI8y(dqu8Clrs^Gwnhit7N#os^l4QA7Zv(2hEX0c`S^sg2k0I ze7YTfBP0&|`Vs~q<8j4r6b)xs^EIb0aV5D0zd@^;>R!Rlh&;i*Z_j?Q=C^Rp0-rag zT`0~RXa`Ii`cuP38kbVI=6o@e=(Nk+qihqmFRB?=2}ONuPjhv|zYIPQ%rSGl)*K^R zL7^pfNu^0r7N`C|k{x&j`*)58Ra1J3{HY3Hh6e%?{C{%vFHQYd`GlP#@jp-hWUKs1 zPcd*dG4uFOfnA(@p{Bfo5$b1#o(2n32L>u2EW8Me91a>SYWV}0kRrkb!evoh6y4rA ztRufwW%2QzEnFIj6>12}k=Hpj%D=_n}-rDWH6vr!L&;GyyuQv_2k9+#Th4&E_l-w~w@7R4rKhQ&j zV3GyO_jENtNZJaDE2ExD7=xbD>QGlrUFKVdVAdN=u)#4F6y$Lxl*Dl>Ks3#c;?kg} zI?m8n%pl1_h+yiYrXT&m3+iCT}nUat7En+&mCZM^i-rb#;soOhST&iN7?WBbxR zKV)gACQcH>FU<`h9-qGJCoHz+P{HgiEbLPZG(oJ5jg8BIYM+TM)xZtUSsRv)YJja( z@rLK9O|_#|rHw(gqWbgI@fBfU%joWJO2*eO!a&=2f!5JHE#p}l##2-b=SY|ik?&i7 zecg9P7^oyN{sV5C-m8LTt25mz*=EX|Rhmt0)gseO8oDzwxYV<_+oWS_mT_tN%qHY~SbuzXjCt#)H9*o&&)}eik4l%oYWE6IS9$$hE(C zkf_rEj$;kwd=(KTc76~)D9ap&qPXGh40ePngB5!>UU zM2#p_>mu)&>d47u^}5Edkib0B#_BgLNqVMHp22ec0;5* zFvKRS-qFj@y6tSc=SY*1i!2FS>Pd{t(BaLH>4f@V>f@C>_f_uKo!ZA#XfKy}M=H;! zJKXQvgT&WTJh?rh&G#fcxq_Wo;281|{1Jo^*%H1V7yb<3R$QTf8a1J;J>|^$Rhol4a5r-IL>_lub4q1n+WA*`ulmqM$j~Hld zw7DDn-_xBUBZ_|9>3KWt?DAX(vaUC)fGfF$ZitWG-l{+V6CNYS+sfvZoV^)vlgQW> z?)3Wh@zG<+S)tqK=ah*z8_@m_lSRi_$5F>plS#+aBio6#qdJp*MhgzZ_7O%C4$Jfw z>_+U?O{?}9$KIo$BjAa^lu&ATE!=u;OOMI>wj;<1iHXFNQffJ^oO*66kLmlaBe01` zX_Wg1xKqb3p?EVwteIU6_BLTvnM1i4{|8KNwzxZ}^uSmJ)3Ih*%-`5Ktp{p9iMrcG zZkM}bCb4esL1%D~b@LwOUQL_z_z>XHnnATg(aV=|4u6%r3w1811?Z9VXwJ+z4dS8d6;3#(yC=SaJGaxK=}~=! zLg^4}Q{pZ@JaXT$-nr_OQw?zq;w?QqdEdG0XLm@dh4Ybq33T(*A>1J8 z)mFMRzka{7?UtuQ*&+WT&?&SUWD5^{Bs&Av?-ihCj>Kn-FIuFLH~ejC>Dc3Gwzl5)$k?Z~$u=(IjJAth{+$l)UjRQ2uJ3 zKmA5tyu4vug1lv21pUaafnd4-a{i`1jX{k7Q+|J5GW|?mw7kWvK$=}$jJ(M$x`Dp{ zTK>8|h(Ugzs9ADP=UEkYwN0n!^HOa&v8nIM z_(7bH`hfn^pQx5L#V<3gp5WX9C%3MgfOq@!ZRr(+KAFp(G@MM^#fUcq=k5%rC`PSH zfo%(62Bol&rQi}~Kt!^bURe@FSyJdOv_x0h18Gjk2h%i{F55%ACp_5q?hdO;QOG%% z(w>+O^9vzLIk;KRFuMU{(UCb4+z0JJCp@WV;@v*0I>Tr|dPSP2izRl4Lu!Z?w7=m0 zeUk3Mn+PxYQ~yc(r^Jo7bZHJ)9qRA< z{co2wfe}2EHTU~lZJI+~U2Wf2JSnxBEhEN~~@auXSi-d$x4fecig3Bfu0ra=4#}fETI7*yRIY zZ)r;IvfTs469GVOT)&*;XsGc61%LtouHvnU`Gx_2uY9eF5L5P+g~C<2^8hgEa)*o* zd&rF*L*EyX9XZMl5rn6vCJs>MDBd)u$PJ=nk?BzCiA|LhTc>nH2eD-?&Ug@|VzC^6>y>^s&PiuH zzYSVybnE<0 z%p=Gw3RO!|1x0PCq79m963mSri$Z48qu4?a^N50y|VNztB$`4QlV%T>CVK@P4 zn-8G{Ss1`uSz?Iz^+W-8v2VH_wx;SC%OCCBu^(nkY4z|9<0H9FpMitLG{4wUl^89u zggjm`SEWrjvl_S1GA{eY7xsMlW_$57kq!SLvS9%8(fP4p@+6W4W_eD0`~ws?@d3a5-Bip!eqpQEXztQ-s2Q-7p(<-a zTyafTL?V4TbpJWSbMsdkU$X4i?hrol(k1zP?x54cWXSWg)u0f*eUW~%1_?9VsEZcd zEJJtXBB?M1d=g1zXmIhz)4UMAF`n}l@sZi%Q+_>Q8i@vq*T#_E-CE4=_VpnGFcz;^ z=#gr7ZvHO8AMhwq5OHAs!uj%G!}H5YMxA|%D5;WSS+Aim{d^?+r|dwI0pAufE8?{E zMbtQ~AqiFcjFvbWm^eAdin53(5vuPsV-~-cST{5NEKnW;_=||`a?(&4oOa36J+yFJ z*m^kaPxNb8jO4&r3?^mFD-9LsiNC8XJ*!p{;qoLiCR7DqjWidgX*B??sZu~ii#2s1 zd4@cdhWo;xW0WR28%qMK`#chDE9)+$B{#V+Nz@f5Z*-78KIS=?EQ=4rkYQ3*&s@?U z*-%*!CC?f;|L!le<)Bn<-en#%kG6qfP=a=Asfhp|xi5chpG%Vsu@O$(>XbpUP?*pL zdlPVN)n0DT$R&DlUT-p?Iq51DtDzo6cYU!XN@<3^bZNcZq`=8_G60LgedtfY`}M@X z+s2TAlRMIhRL9JaQpY$CM3mj4?ygmNs`6PeIz`sx?4lCw&}}19WkIx6EOqILWTv$) ziD8i`ak@7tevQO_wc2909I0pB-gkFY#Q_>uWNf{C|F$@Kg;R(@72h1)Z#75)J*c3l zz*{(Zm?lzLtjh4aE}(W0`W4@`FBZ;OFfXzZvyG#-&QNy(jk*^U+v_Mask@)WS8eUt z5!H}xwNndTfcw}wyzYs;|LD}H5`Z!rOa6<~dSGa1ij0ejdEa4?yI)uN@@mf?#AND7 zL?*VD6@JBgi}$=C3eDLnw@B$pxoz`gdSD?l6v-mso%uWjzOR!s)H8RuB)JzG^>B7} z<(V+#!TgbC(qPWl+T!WW(R@8t6wW)+$^4op>{ykfK>mQghV7+?q(p0y8fq7#SuaSZ z2RWjnheYi0o}JSqmF-Oroxy{3NUbjZ&3wbt<) z-lzpDg8rO@8b&p>J1^6Imtv8dO_AE(YYx#5maZ6$DimA=I?Otx)?Jpl!8ge{!sR+W zD%LQ2g`V)2xk131TbONq@Pz^cv1{FqFyv8DM%SE{1LX!z*P4{aux!(=W7D3_Do}P1 zPO&UZDt?TcA&lCyirn}vf$<%E$sMsPQ7n%;uG(FnGb|qK%KlDUj_M9E zs4Xh)Wnr_I2$L-Wm3^VQga_A=6~)frooY;>@RgIbB|?H(sy>%;eI4_@hJ>akMSJ#$ ziMQZYP$+t^iikCJY{uO9)0Oeya=|23h!oNFnk*idNklks*MLM1YJCiD41MPF9>BAf ziL>=Ko>}rn=MmQ(BXWmd*njUMmPYe9XJ}1+{2SN-)N2ll#cP5FXuhh(KD;%lh%jp- zYpaFi@HSgR;v_Q_A~q)00Lv7{^un zhi&@f%(_E@WZ_D&8?#Xx8Y(w=AF@#gw4ztGG1q;CZ7ca|RJF_jCd5i)M($=F%5ni3 za10p^cxT3v)0>d(Wwc#0^&MP|#1W1L;~@BhO-$?{InBXJq(W@#L9oNh=g08ts`!=8G@A9h-@mW>HeCAJRQ_y=Ve)710E)j~_x&?}{vSS=KiTuxDmY)d&uLp@ zhtnapQl}|`86`F?BH{!hL-CNkYVZXUY1KfZKcfY=3+D%b&;U9-17 zfR%l4%9;Uq9isHy@y`pMwm&O7bVUbbTh&`4u-4H}8Ms3rDAr2ypQr%7;cCYg6}Z;& zHXOInJz2;Ok?EGPwL0Pkojy2#QoRzK8^vmI0d^+$DowB3#NPj5>>Zdi3!^OE%1Ya| zZQHhO+qP}H(zY|dv~AnASyMedF*my7#_b#DFYFVs_Fm6gFCP4hheKV?P8kvUE42p! zI_g^_IJ^`T{P98ATV_!H63<4D4s0#?-HcCCf9Wk9eZu>)5?*TV_RtuktP8_`6ZYdJu@=m3JAz*q%qBL z+t-Rj4HDO^fFh?CC?NB0OtR^qG>It-Y4|6MNV#ruD+$G^1U%gWaw4bPb(hi)V#&Zm zZJ`r^dVTn8GoCR^9z&936Qr10=3v^(sZxzK4e9aRRN18P&7=^I!bqEBF{wV)^(C5k zryAmH#@Pe1f~b#}l$<^+(DNw9 zsW1(W=+pC9k=VE~t_LUN7QrAd`W_`MWtW)xY~%!YfC%zY$ih`u@GcLF)?}@9wUUIh38|!b`Ub$ z5g`jhN)coqdjgeiH1o<{$~1X$jB~KMNUvHFY@YHGg(AhtI=sP@!4K0}AxJHWE*p!K zNR`sBFIbS{+XD$(%u=He>Z9E>A(KWWdz7H^)E*<1EZL|$lU~Gs%%+8FI|!xHnV9mp zzyChs5bvbN#ePgdXz$yCON}3OB_2IQ-nn1~w{oQ6mEW>w;GPGXl&v>#A(c%Ij!@K( z`((LCNJP?Og3DEo8X8v@ybZCheGVOdd`>0=`hE@BjfRVclk`hoeJTYGbME+`?EF}Om}8n7%(F{elF&8bsimR!i~vgKzc##pd1 zVJ{<&iH=(t_a@v>F{Unk7lnZ&RdHla_iV)K$XR2HB0V@z7=H>CP%H~IQtDUZI?B3F zeTav`IKB~F75n`A2F4y7J!Fko4qod{mo6Qm;su@)he@?(4AUYMJ7}U^UdX3dUt|Yc zmAOzO!Db~$o&?iyYsirnk%Mu=@*or)-H)Yq7(Lp?@rmcGGKUIYNv@^gibrvdr-RG(G0A{&|eTzHF*! z$#5Ep)@$mnZQD>aJvO0|->5f}H*1$9D0#z+4n*au5x2S(W}$1ti`RCa@k|!$1G+da zguHWW#Y5RiX1b~Q)s&N3a94!>2YQDRI}am<8C*5ztCgZe4ipSkIW!T7OC zvX*|8kzR-YJ|K-XV&!Qbl_mL30Ew+A+-dgFud_(ID|!=xxCjp6HPJ5sf3jycwI}?g z!WWTycUZ&`EBoM5>$JD;b>Hqvx@!K1uFLH{9-U~$xnuMbaWvi$HN>VlpvsDS$QJD^ z6K8wn1k&Q5eEpZjh>{d0 z(@GSZG{}w{lS+2vev181C3hk-ZM{uQp_SpPZ~;-0R^P$ixYFYuO>|a{Z_dQ2!%pA~ z%=SB`>UPo%Z#MZ^r%O)lO?B;L15t1{MNyTJB@Lu#<*~Y8YV^Zi+5@fw*I-$yHWAn0sxW1!we(4X1YGnnBMD3nIK5XwID^!D zwB?yF=!atHGbsm=aKPFqd&Gmx9fhH}4FVdMggud)R=^^TT=NX%!$m)Y3CA5|a-StR| z)_GdPKefg&)B662(YGuK>kc#yU2!*BF^--Yk*?qIEo-WrPzb_Lp0?i?q$b}DfoVp2lnc>j+@uJRRTSX+(N4#Uz4 z;n6aeyWr(U9H3_SoizvD6Uf3zwM;CRJ3S`3Ab*e7XYBS|R6#daVvW}L>bEc-T9 zRUGr?@}wgzv!f2qB}Q4TFo^xl_XEZ$M4@qtYk00QYVZ8248=D+Ykt<^e!e!V#j390 zKtFi&*cy)mpX5mC>uR{n@Kw{r&|-b#CS#q=ZjK?o$`!inNlfKV*k+ABab9a2g{cOV zH%-BpmVA(j6Xv+(hSNKG3qVJ8b~i!;Zd@U?+HRe+PURdxT~wC5``RVxb&uL zD%$fE?K-T!=HI{<6Dmxc&S?$sTNS>OI7|Mv<1}{3J$SSe;X`$RDSEjg%;~St#~dM= zk*}oXgn^-r-lt!8#_mQqd9298D@TWY$c9|{)VvB5KhGUq3&S%v^a=ufknDW73>$2M zi921R$}`94?pyLn1o}W4yfFn^pnkfkYDcMS(CChX^#ERd@bv@UJz?Lcwb_64!QMUU zx`(?N)Z+>A^?xuHWbHDZ*% z@Z6btbjx#p07RdjKJW}YHs5JS4&ade1xo8-Lu=nod5_LHPCku%Ly9&8;+!=Rv@tg7 z8AnMW?TNsuHV^!Qsv12W0)&)xEScc;Ok|Q3xw4FNG$l`w(iu>8r@Ty|f49Tvm*M&f zjk4d#iuq=j54B|k(dCfFjkZZH$I>ar-6E(5&fGNQF~j>R#@s4V)ur087ajT1s5yXA z7Y9*`ul;@$bEauBC*1_I7BAfr(@FrFM&ICbQb&*W9Yd8K(wo|Vp4P5c=~pFgbi#>& z67vTE1AyisQkCHSHm2zSt!lTqTK)QOH|b#;D+_vvU%!z56%I1~kGqM3h^g`a^^X6~ zj-qaYiEA< z=krAS7u+8Ga>lR@gsz9upg1cJst{^ktr*Cx#ao7lA5Vzk_<Ehi(VyA;M6gUvbB!z@JF zqs7cK#wrF;qq?9A5w9(#2hdHG1dUlo6N=2-C^?J@8#k_r>t@>%r}Jvm=_%8q;08!$ z&P-~VXEex}lCmPaZ;QHM0y4y{x*rYE4`A^HH7Nh7?Xn4s-cQSCtb?Sel&5}G{r8)AAwn+lTE5|Kh@ z+_<=ygIMt+H99->50=F8H^$78&RRBJ(iu#c&Rb(oP(7cY^ZAaa5ba&1%DJs`cM?xg$`$W*g@X>;0yCC?-!OF=5(n#BrO4^x$TW*zu&UINGVp7hLb^J@}X6Xnu&i|42j} z`A||&1#xT@S7`{FG=n@enl=q*!x3ZQpG!VF)Rn&@Th^JEEAaj^dXh5cMfZ!Mg4|ji zJ8^3lo<#CBCmhs{+M1PkZ8VEqrP7B**WaN*mA*A zE@O!b_;j7!BpT-Jwb|1)Yt86mBM#>8o2uCiPJ<^f9jelN7wQ}(fr~}z)5Yz#tthbe zmZ^$5gXaSK3KWEtyr-Pbl7mzg}zEwa~%F5LfA$oklp7QbGM*zS|Oc8s=a8-2I zz+4f3*by9dS>DkAw5m7YxTYTXJMd%M;0_t3Z;V02JVlbG zQH_3i(=N1syxP4X2|?)%(b-v{Mx(tnVgYdi$s5IV0{Q~izu9=%{?6>arW~)3xXl|&8BaxFyGkwrsXqc0)rLdtT3zXp8T>6 z;&Baej$`D0W zm!!ZZiJYF<1;6-APEs5^W&aPy8Z`#dnfyTaRLw|7)ruD<=0WcqL$0#HY+>T1ot(>s z&GpK8KITX*S*p~=;~acUdYX@TgFfGrMQV;VEijl2@`z&mw>iWk#qFQ#Pekpk_=nF@s?IUBNQO=eT!urii_y?oi&21!}jN z&DP-D4aox9sfDewn(NO}-X_J<(Qo-cV|~j>)IrJ1DX9z|A?kr-;OZ(N|J5j~&J*dG zH^d`vR7<|BGy0}nBG2XXSFnmGcO%qMNo7LT<{Vw$-YzW!FozIvC%4wY^_q)hL6`Lm z1TPri%m^InRSIB>@3g&%r!i8ujAuuGZr@cDHk`b?H`o@UG7ZHqm&wqtG7WK8 z2iv5h{@R%caW)MdOocq{-th{_R5?~i6)*HFWuht=Zb! z{igy+RnoOb`bShMQ`jW>71)YawX~`UY`6H{7mO6Q8c47k*z`|8XAb;Y?1Rw+Q~u2M zxfeyo{{s4-v0LeZ~LPddC9ef;6~11vnjzmMOsdR%#pn;}s7!Z!F+s|GxnTJdnBz(8|# z49)$Iy!c7~1zaUs&P*&&aPa9$twnQv9Df0xDpcSxgy2n?%2J0xlxdSn*jbfL!hR`D zDmA#%00H;zsJ=$&66{{ZlfcF&FD5Gvhr#w8cH@b=v($MzZ_SSo9Jn-bnP)l6zbLwl zpA`h>wRLr&Cr`~(zl2u0rpARpS_AROHs_0&ArG@2Qy1Ji`U#jvM6awoPCQMsfd{se z@Zr`j0jBFW#!0NM@D$o360wbm0Nma_XlXF-{# zbUmo?^CQ9xHF{@~${Bq#SGC+h%M2W+lC0dMoz)kcISR6ZUl&{ot0ETT;Y1QfP>>AT z1?NF{ElC)^$@2<4UX*ylD7qJK&SVrvin8Z^P2aoi+AOZW1} z;b9B!;tQK=Kq|uf{kOqXI?_`j{@3^$|F2z`;eQ;=|2I_(?SZ3;`eX0L*0nB|&1R`( zk<3I}BiU-%8roxFg?|p5W``%c5rS4M<3^rcke$iVwJDB*f+|`=L}8$f1w!?#h@#a9 zORLle4v#3B7!IW->O)QC=jZo~Je!$0Ww(HGU-a#CoBJPgoAVcN!}pwj2oK!;%RXi9 zZX7|)7`~2gc(BZ~Ju!Ut&H)*o{qar{j}Kjl)(&!CZ3}Gx%ZE?I+gsYAWfmOh?$i&@ z&inuv2quI9(>tg=_>}(6!5qOI)X^OQJowEB;q`8(!0`>K2d7V6NTHrQpe~F7+FN7B zu;*e2p(m`aY3TFq@#j}uJ(l?UAl0nkgWKmW)D98u^DhqaFmot#CxRdkc8^l^y!|T=ZqFNthghL!xqtA(tjbWuyI58b*$Lm)C!jj8aZ;vSC{iQU^#EaC*LUT6WV&Tf5b@+S)q4l?6JYyl*JP&hlQy zxV1~WY2(>1HsY{WOUvl`u7G@HZaP9(#;7bt5OWbGFshodG(mu^M)Rfe>_IFr;d6aq zJNNHDGPcWASpL-la>1#pkA=6J%vv)m(NZS!{yH1F7}<7X&`vc5j)>Q4faR0uo~JWW zr57{uIorBrUv@Ez7wp4C+0u#xlhT3m8p}#-w;(Yhqk`;h#VL#l&DKVHyOk9FoP>9q zCu>1nS(;43dI}^^8*34^hI4bXL^FG-7Udd+o?Mxk8f0Y!pnP4_g8SQ)k-4^%OGVoJ z{f1PjRJ_cf@{`}rqMr5Ez^6rK>1@($%%3%#UF=$01RXc~>R&n!m#v4lXrzt3!uKW= zbx`J#wy8~bThQ>2nMz^NcZ(N~aC#-0Cyj}P7SVMSeG9)B4mnROV3X1+Sgf_p(LL;u zxY8Z$rp|=-wjgoeoQnsyzr z81;0+=otLH^SY3r1AL+rt0vdvTxLrCV&8RPY+3h$ilMJ;u1v~ZK+am zRunibQbhw(R^PZv^+}XKhwjF4mCk2fHu2m-Y)2&FRWmOZ)9|bbtElywE3&r;57#Z0 z&S#S}r!W`N$WBfDe*y0E5ih9-FL7n<`54Jk3d&_EE1IH=<-=^z?wI_&GN3P+kx36x z12Md!6C0{!s|&Eq!{KrP**t?5(~7PlF`>=nr0HfC_AE`}#1{!ujH}W7!;W8a<8PpT zltrQ2FVq03V{-ji%5oeIlP|2g@i$m*M`o_yZ#6Ny`>#wteVh0r;wD!{iMfC3VS2x% z5dLKiz9MVBnqqqQTrtxLs1B8EAol8*enx;EfJnkqu`s)s_{Kf};Mf$2E9GH^W+^DD zV!v;Bpi*SwGp8x!Tysy$i;8o6vM3L4Va|sDOKG)L*ISV2F2bu|LPi>gV`CrP2f3=t zhD~Qd7Se&l~$qPNRGM90G#);o~@TlmBVegeEH61WT z^EXz_)!RH-8|Eq36}(5%vP(!B7rHE`4h=?JS~bd;AtQ}Ow0nih%db^vZ~lfxamrcm zX`RWRck5u0AIWDg$-twY=;f|`{mWU>w>IZ;VQc6yqcQPyY09{F_G=>0H$15J5(I3x zmoaP6<5uN(J2u5{VdDv}pJ8abvA&Xabfm<287V6N`8I1wr+Un38?ordn$6hSi0bfU zFoPa_I{52zyWA_Pp}&RYoJaU|R=-P#!e=^Yk8Gce@M4{2s`Vt-6OecPJ2oT2Qs=tA z&R)tnOPXWRlJ20^aCS-is$=-u&b7BJO z6HIYRm_Uaq!l2y=fpotk7$TH9oFPs!R}+f=R|OMz2eV9-0^DJ|;lOumqtCTbOc^6M zBzjU(G((`h3+`>Jn(iRk(ET0h&S*)&cw_9 z0u@u`5dl{GpDz$Hd(N<^MoLbZnu-0KMrX_ZQ9z#9W#c)I3LO3-18X=Y`~iSy$`|KQ zPJr+ylbrgssM(5tM0Liuoysxc)qMWvog7n_|4;{~)@aQ+V|tB?ed>Iw?pUsM%3QlO z1_3k=>|02PGOwWCD^KVG6e=a%ft6J&I_pXf5cI074T#e^c=kYLS6t-|ShXP;h-<+c z0Ula5D`F0~W*Y%W%}<2uX@L{wiaoY3{PG;VtLGO`$|zeFv;__q3P{Br=mJxerPhaI zwF$aKTv|9P>oxkQnjzf6+&S>m8E&P+ePBTSJ?F$dW4$(s`}l&98Bs2p?C@Du=F5*uw(?9)5qHP>08?a8{Zt*{n2c z*lxn`=GRxxpv?%7j0po=A3d&F`UhNm$;++DXq$adu}Dc!p(udE?v>++j$GVfXLrVtRWCfyIYRMoU0g?H=pk9$0%gTv zD#0Y$;&VK?VsDE@dGWFxxwB6+X&g@PhKPpB!g5U-Sn=_#2`Ed5$18%01OP%s0*3$` z;bA2}qcQ(f`BY(7lW=_oqmL^bQ0gpV<(W!-;J~z)Gt)HYw1o*H9b8V_ zfhV%95>H4)7)j-H>Uksv+BE!Lj@G0|U)hinH91^}W=j-PHNRubr6B&d=g6vI{S=1f6G(v3(30skT1B%EZ4?Usl-^F<2-PO!1D(<(~KI4s8?<9sJai%dD z0~c&73d5(a8RYGwUH6>vjNwmtD`723ydAc1pA1#yYWr_B1X5!?oIJh=&>~VBass8+ z5K6ez(>5a=>0BKHw!aoQgGr!8wBvad5fJzGklv;Ea4hKe@JimL`V4NDUDq3bp#QoFo|d@4`2MQ}x&3#Crv4uV_kZb_EK&d0 zF}eJ|DVcEw955tE1Pr-Bva3>sd-FdyoPA?t{UkvGlrY)r(|cy@Gja%XdQw$JHE5eu zFOAJ;wzkw1k|}8`t*y%|D?4Sj%X+OZ^<^bc-#b@i>w9D;uhgTPnXf;$pZdFh|L*WO zo+K*&N{gbzDr^_-&&7&z2*-g#FT!)LcnkRY{)59;yf;Y2S6G1IKKUANg%d~dmJufD zG)v;61NUm7K@cv#S03i=n2*C(v9H{&Z}-t0G;5JTcYJxT`Ti6TW&H5k9tD1U%Zq%6 zAUCG#>!jWr2E`cX1caRcBzZb1^riiMqbbq|JQMUJ;$mS$j^sv# z7+H!;4f4Ceg{nu`K(WUneLYj|RpdyiI4?N&%vEMpuB_eA$i@0HZiJc(OM4?*OB+P0 zuxpyvjKmVDaoaV5CNxV63rm~Jt=YYqwPh|LQe?c{Y+~Dl%$qiAmC`lMysdLZkA1;l z_{xsCgYMcTn+`FE`a0#h7D+>glW!8u9_enij60H#)2ggGZRbWeZPD;XN^4=vWlF}5 z30J%4lE~vhw{ghJ~<%yP@6v+rqW6oug?kt4M#^hWP zCvVG}t$~BftKwADL`P;^^T0lU?O~#<7UcxmI?hrIyS1WhgSlB(cfKcbI#aXS!qvD& zu8;K|6)0}o;LS-TR=PvppS&qk`s|RxH|w=7`a`X4Cj5KCXh4>?NdF>~UqK&Xn^RaZ zlBBd9k_NBT&;!Bf!MIwdK+1y6%9TrTg=+*H^%^)vlHH;lWQwYtH!G@%kWZ;_r3`KT zMJOMkWGc=iX;7O2BcpuiNl@rImKg*Rh&s6RT0&z~G$Ym&5-m4JCJ9Ec# z(m8L*tu`gg{Rz|Yr7lK|14r$lIJ$f1j{CQd-}MXnubGM~Amnd-U2K-!OG~{t0dCp7 zK3kjZHFg%89eXjK{Z7IX^Hi~MX6`4<#cVq!ah@AYqlofdW1PB!*r;X>Vn&0k+d6e) zS9taFFAaiau`p4Cvn`796%BpyDpvsT?a_=^DYa#X+UZ!gTNF1dv2nw^t67Yc*nmZC zv+;E33I+Ow^8XWaU z()AH%2#FD$0%LHui$V>H->V*9wXBWYG25laB3>Ec5!rELH~5LnD%dknA&)c=i$Qnw zpd(V48l09o+*1*%BW#@AOWF8Yx@HVZo2ZO}=v;ZKLn68|NXek3Fv@kVt9BEO+dX2J z7|KMeL1j6U7G%NU62YkK-pO`{daF{V027%i8jp+=HMARQ!KSiNsfJ-SbR>-L6vgeQ zKe(ObDUDlW$F@ARL5vR@rsA3GTt;#k9DH1a^&L(}UmW(phZc{>k@@(es>XSzha6qM z-Aeo20Cp3#JtjH-kdxUc=cA@C3}wHUHFxe8KW16DmYN}H_L6pm+{d_X(K7HhI zdA<#u@Ta^2g!yIlG5sKhDjO`A)^9ynO$w)!@Q5-+@s1=EvTKCQCxy|@)e0e(9t{A2c zIsTHAECmc5rxItV z;?bz4ub_obM1L~ar}>iydkd7T&f=mPR%Ay3`)2rSV30Q$NXupFBy^&gsXiGi+8Ri5 z9@BBeH~?i+f!k{3m@g{wa0bkY3Z6?Zi&_QRE(dR>-35l7nO^i;LX>?f5U1;>gQICF zEytIHH|#POsSsI-&_io&HPHAr=>7T`z`1bY1#jokpB7zwrUqx#OO)89gq5^%IdVEvv#i}z0Qt{pOdz_1h3Hn+;; z2w`7B>lZ&xjmRMl9EA#y?cWRyx1I`NR+n0#0M@E&n^+}gR8 z170zjW=2$X8Q3HE?@!u3PFl6um1I2Bi2wMY#$oWSpC!4kQbdw|MK{i?gPK=IIHa!79ZA?gi^tiLF2Ux?2e^Ve z(sOkZ7}ok)yz9Jz^K*r2&+(6v|1e^8E!{JH4Xnzz6cv2E)kpmg#mOqztfP#Q22&N! zS%+KSte4LdMvEB6>9X)oC}ZHE>(i~*hf_diHxTo=d<3P%Irz**q~dT)bwf!Mj>XIOK32sQFV6(-2*|D?_yHrbEu&?knnakJo#3Eu zpPsz2T{oE(VXznL_wL&-UCekyQbnD#Ptu7(_u9sy;ER)%%KC7qs3uNaU4x%*+I;`p zEv$Xw*|GnjvIK817|h}CAwQ>`J$diD19boM_rIywEKu1b*nb5io?yRzQT>0bSP@|h zQ)6pqSKI$IF=AD16ks;t_pXt|0z7SEs{v;}56-?mL&4m_M2Pb>i2t(eC7O1KIw5FP3 zf$98;6zMh->fxHw3eu<6OT7vu4da_qSLAdEGBL{10wJ)r`JEZ;^IHaC3ZFu}%CN#T zAc$Ev08g?PE# zf;6lg$Cgt+=k8-m!Q$MP8VmG<9v9h6N zgR9K715}yTVr!*On(CmlB0U}Rh|F?z6?+3`o2=)dN3Qep(%F}C=O{Z3`{2fkzwBzt z`q(`yYw_xJM$`LyD_^S&u=?)DtOoF-?NvxjC5JnQR`z(1b-W$gE*-Fhh%xrer zsm&3R@JYei?)+FkK7@hYbvfF(hj_Bs$@>zkt-<||=_HAzo}GnLQ+i`w>cK~Lx5)f; zDrP54kV}z=I+#bzuW3WR#ds1f<_eHOU#&Jn0**0k@k_Ti#u#uDPl+zYtaoG%;Lo^L zY7aS!(YvwxqgKNQ{C?wA|GajN4a6{nPoP`W5M**e+dhieg%<2Qf`he+Di$XwWIPYg zz=rXC>E=;99f25F2=u#LqzlIkF9|#fTW-=Df*yqX7_NxX200ET`ysDNC(yCwEgVdO zqfQ{j0iz5TQwkPmeETcxp}IDZm}Q8&&Wf|&L(J*|w)MBIULBHmuAs_yif7H*{b=ux z=KJU&xp=+e5X26Van2HObCe-x-@@s@uHOF0C!E14>xeURxt!qKHF(Ma?SkM~1v70O z9cE{BVYANv{ik9(bYjK&_wphK`Trj;#^Havg#Y=}%Kww1NIA~@%kS))JdWPhP*IIK_iyn{&k9*sO)#i0= zYs>YE#_G1Md)uq2;)j3FyBSk*$l&ge-}q&z<)Z@!4JogFqh4J_J9r zy;GpC-+%Q2Y&~ZC{Lfx}ZGRT~{6Y6d{V(^@H@>8@|IVNIx4ifM%GL+J!~R<7yZw6e z{Z;Z7Ecc_B%@4|e>kmgzJgtAX`r9X<*YY+X5dQm(A^_^EzfUj;5(ZHTs$EgXgw9Tw z2MCA$E?T{}=NDVVK6{$B$r?SWALX+&W*t#7v}qJbOD0x;bliN0 zJ7T4Cf3zGcbp=8Kx5;$|;DD9IRf)?6YKp z-g%3{FSE<)w-U80l}qZ*p9y+rU?%yCZ>OZV)5{5;UYa>%G_;9vruBp{q3UGi7S8E} zMb!W?)2*X)(GOnX>|sAnWqDrdY|_w1m8=%c(rG7KwemQ%j}lSVxyoSGjhyS3xk^7v zMm`@Xx_S zy(+$>vrFkA@C)O}ygUm)Sr6^}BFUYr>*xS4aL~AIdPrN?CAjju#`nXUfqq%)fs>$l zGdZ3dEE%ofqDPdd?UB|l_Kg(D$8*3>F)IUt?9in#H`4QDmUqoqT3~-q>9Ci=5a-!p zqvee8;m*HAi-WCBWudr>Dd6mS-%rUcCZAWzaS_|tkg9?;uhFZz*ctc~5I@=RE|Eh% zihMfE+*Ms$B1{<_m82$U$urO6#>bH%jV&$G>LTVo$JZk|@4?cdQ4iqqm1F5w{s33b zttdu4+2@?ulaPvnsroQgE6tW*Ynjm`zhfcq9BXT*#cJaM`()D|Z`q$_oJnaRCE8!> zbYQA9HeX1-h*j$B9JDO76))shC(&ZUI*lbuQ8#cq9xJZqAAybFcS*IQ&Qy~#cz=ml z&MzcLX$bi0QiB;W5)PV(Ol@(rtf~QaUyy2$by>XJVvHX6P>N*TqNBKw2_@FH@DT?J zb1KmUMGZgV3}?$NcA@=hORAx)lCOVAIO2?JCEn2QEv7ajMW?gCV%`RnW+qQ;V5>p( zGls88L`g6;ItZ#A8+$0o7Y#s`%F<+9h?d7A$J6C3je-27kGD%{6in&wgQI#6w25(AIn%z-l3m^4_#0;1` ztRUH*wuv3BF>$7u+QS`V2j)HZ$c{Qd9e&XDzey~#in*1aj-M;|kx9v8o)7%Xuk-ar z6aOn>YJTav{5OWyvK!CBAnZnkf5k~ah32kKkC$kzrSqJL>kYu>#6Ra4)*6k-IzAOE zbj5UEWsMCZo&rl$oeO-CYIcIS)sZ6>Xsbagm?{mU9!5u&UK1sflL6;U28N7yC93?w zcLL)qyNoHT9kdN9jvwn9+o^yOeVklICrTdQPhPE?thTRAR;MH=HEvRqN0*Mx5w@1q zF_(>fPYjve(z%IEf7m$8hKV$$jpDD!1ey##x#jcvvtR^t!Hr2FJqm7j30}kcQ1@G5 zWcYmqCE_{L5K|-`Z`e~7((rPr4pG(+IRh56thJ9d2ii4Mi*7yF(q*5LgOG!=X;0FA za=bNJPe?AA+n#dBh+=$E3{6NHoR~4&=6VqtoNaWemv94vA=Oa5+H@GwHX&78FQbW+ z%!f>*bWjgcWozrJb|T7aPIK-L>u8GKdoiJ;G8l>J*dI!5M`GtyjT1%gNMry;+60HQ zT+y_-72K`^6-v_pFr~NQP2$_rDf0xCLx9A{FKngvwsE(CbV}jI!4&!Nl2RY6+YF~n z9lHrsrxHT-Os5tdDaH{B=0kNS*d5kmt@jwp)$wNsSU={;kF^<%>%-&ypkW>UX~*>Wjn+XXHT)y^H2pcM;0bUA2r-lXTYYD zEG=e~oh;*v;P<%5P-`t^zPfu}?tZEv(uEv}@Jjo1sgIx?^O2kI%~*6G4MDb38P*3D ztMxg@66-PDb3oTI-bE>Aq72+i)#b5TR>8EERhCm7*EISuUzSUX1JC+52BRbQ4Z{%- zvi$+AGTu@wyyYVUHXzm=r0iIvtI`RFf<4q|o>t9f3@kw6gJ)re`55s%iIV$1Dl%PF z(Udc=e`;rNZce~AMHOZlwV}E;P(k0rTMIDvD|#S-PE~n7I}|r%$!0?R zh)ua?g87IMv~sj$awz_(8MVf-#5`al=p2s~rl6jY_bjUP+HyFT;%#(u1AZ_B%M-zY!##orw6We7oy?bB7rbW$TnG;+a1jLwYXtz=Lq}imPp04iLXpbY*r^pCM;Y7$)o%P zBT}+SMG`I@K{fFsEwcWptb@)@zp=3;)4N63D^<}gz7Se}%LM7ff@IK%G^om+O%)E4gwv#5JHo4$a0V}m^8*m`TYayLrup4e@3cYq-|ugcx~3)F2Dse)}yyXascjUfhW7{ zu#3W;$bJe&I9O@gTwC~p`#z>87hJJ5sO8yN1wK~IHPE;Scse*_&0}JuX$xOM3}0J( zvWqjnZBuFv)++Aj6hyB&`vvQ)1wP)IO%pBFf(+`iiq2qmjbKz^4NY!jlq2|%DBLAX zh`ZbTSECcr8^&-Jl-AW;<-Ll&LD3l+we1Yi=0H)@Ly14yek{jzgwMdfqPZx?Ksmlt z_PSU>C^Bgn@z+|!VLhzyFDQrVm4mC)b7Qce$u;+Vr?|Q?O#N}jT{<>geaiLsSqC58 znK!SW$7`ckd#4`u&0V2|yU5{tbIuQNk3am?wKWwrRU5DsnJ}w(?fJpsymi};%PA;; zJ%2c{X}&jh2VZumJmEe}&uc|PSV&phsOC%+W$vJZvMXi&Q8zq!P`SWBs}v(RDurmx z@xtyrk<8bL@7ZbJAzNY?fQnP^i$kYwMH$yenOPsIZczGxi|X4#12V!>6+=ELlGNi{K*P3` zlOwmg@~h~&UIS=5vnM^rL5{^W3Uel$0-P zw}L54I5aNxJT%9fucND)Zw-4*K2gsD(}DfX_Ow0LQKPASxeZldi|Q+f>{Z;J^*X7& z_l<31YsyMyPEFYi!07(uvMtb|pJ&$d%tODbCJXqj%r7`-fF^;C$mT7GGo zhGr+C+JzD4yxM99@THjix z-1axTR^qGLP*iQjR;Jthh62DZvR{qFy!b-gd+UUEFKV;9!<$u7r=_J_4N=M)ukhi_ zJ|j=a;q+hqF^8{wr_CM=LzyWLn})D@Eu0Buw8K@iy$pB60S|P_hm*(cx1>LO>b5}9=>?Z1)@b&7+hZoV!;NZK zHS`fnYoJeeG|aj`h{S|97AtbcpV?4oEzS{We=7Mxe5LosoK#(FhM?Z6w9|PZKxKf5 z@9Lk7OllGvWq} zy938<0_lDwU~mVq9b~u=oAcvcb*2>su;5L-X2P*HJ6_{e&v3}D1UvbVopphuFWgVg zG~i|dW{(-IA2L?Kc*9dkGN`4+fO99lDcenwtENy%4$j=svKH&f_-G7m;2B^`7+`}l z#+$W+uQmFPHphm#k}BL;k#AFFTH6}ClgIA4k}o!8D*5}Lm143>klG|z?NU?U04@h^ z>ml67PFtkx`*t1JuM-eA$=&VxegWV|ygU@W!-KU(KI5ukbqa;KwZ?Z8q#uo!ATV7g zhgG#^JSSSwqq@3l$5Drnt8P5!olyGj+c9Oj?t7T4!E4uEINlj{ubp~>kF~c(`Ioj= z?%yEvoqmz&y7&jE?!W3frSG%4Fn1l=_FP}F0Q-93_MP;7ZCkt^i@5{ZH zpN2lOV&h$kG9B{6hijnuB93r*eXDyVTU@Usr+U*Nj@V4;iajU2;?SPC@Nx&F7#8#jZ2(0i*jcL zV_osy8oMn~e+g?>{`N4pMmeiK*U%$={ZmMQuS&)uUN``~3|Eo+dWd7@Ik89boAImkE8*P2mQv04J24nqzszOgmU*?-J5QHzN&|Hq zmFX6GD3H>lt-R~su%^5wdhAv3lBb4&@@QYla(;@Au6R3#ta<}`|D$+4qC-5R`J*Z6 zCj7tAl>DdW_`eElH5y*}S|(`!d}KDWOxw0HTfLljQX6comRJ+kLanE5ZP+dwOpCEJYfhPPH{RGqwwBN_YV?&>SCJ?`agTBWjO4VZv z-_Mzdz9Rxzo**+U0B0&7JJ^qFAyx?fGs^GZjQSk+JuthjG3&phem^`wUT_)-ZrXjL zKP}=m$v(V!#IHQ2>R<>JJ#`%H#X|`_X&lV(Q3&r}Hu^FC)b-TsTlm|JEn5W8U|nA9 zA71TGz$U^EBdD3^lBDKrGu4)5E0m)SN*Y_B;Id*94Sl5?u05<^0s5)Gn z&3dmxQC}DPa>tb2-`SgcJMBK+`kFRFvhv?OnJ4{SVWgCDG8Z{=gfZ=E|n2 zJqM!Hn-#UVIgI+S7Wck>$0|7Rl<-ox5BFiQ%fDg}i%_I!D~H8<)f_!BNqiCN>}5vGBezel{!)JBBo%44lUHY%VlJ(55jE4 z=&FX?$->E7re(aWm@?2bF!5rJ(V?LzmP`^1z3aX+Vl?We>FyE|tShxui`&YXbkY*o zn0hPA%i5Jtl|>V^g2c(NlB1Q-CCT@>w3GD}7c@i*HL=1PHBBkUzro-VD3P@c)%9Z; z<7GvRdTXF;(qn4LJmN`Ku!0n3*0BEG!Bq`$k(qFBaAeD;Bx6gLg)UJhmQx7<50qX5 zU;T)ZO7l67PRVl`eaE%La#t5CXeI<3fM;o_9dCM}=A}T_keBu^V9iP(-6h3P?Mal5 zrCjv$g4HPQX%PvX1O#rQ$5w>BqLTtqb=XZ{3T?koHEafF8~qoKl=kF$vKW6K-X>Zj#y*U zmNY~$k+AH<>Z185j8C-_>j>)lKO;cNF9&&uZtIcbtSH^`E@R7#8c0bZT=BE#1S{d* zb&HyxMhkrs5gRE`*r-GzQ*eN#q{=77>+9(8Vnn)!Hc}GnrwX-|#|4q$skELSc7rv( z#tRiWCJsd^F|o89V*4*$Y4M`kHIlx~c@9_Cx||*>*h@ReBBB8`FRv@<2xZ|2^T6|I)HGAOHWeX$95_u6_{>ChM zFfLC$F{GnQ8{uKpLw`2>rNc|6ZOmJ5vfz*7F(OFBO$z%u>JAYJZ0RVT^%o+M3Y&8;?R(6>l>mL0EhdR%43s2GHi&XB@ef24sYp>==Q{RSFBJn zng)v!y{!w*>Cz{e#8$&yI4T;3Q-8#xQ5{OLGR4W{L^RSCIdReXpf`J;$kD>H3(1ma zjVoX&;TG&j2b||7lCvk!2cz7elY=J5Qf`G_dN&b<)`>uqJLf3+^7SHzP}zkI4BBNy zu545>7Lf}P;J((JUTJ@@?0mRl|6|@YLtFL|HCU)2dtNg3apVEXih?xH&8KN?qP|GZ z$VVkdGer#bV2CfAB2UfnOVMF@BgY7ET;UkGjFdQzgK{ttpNS$gikDSnGLVdTgmVgT zarnqjgsi|QU2#`mxjXo_*yHDZUg`;yp2w2=2|*@bGyA^SqjN5fExkx(?!=6cD{=CY zE4|`Uz~Cr?yhHw?h`Beb)$bEj zD4#GFj4_UCkdM6GkoZDbr#tdeO2coTB9rrvk>n_O$ekQ0As@C7kzqJVle!}j-E3yn z_Z~mAQT&%E0(FM{uQTQ5nBHUZz8oLCMUHuZ1b#;e9N}rg-*(gy=BkTB2Uau zSuluSR_Pb)bne&+OUv0JZe{&Nh2j(hA83H%9K|s0`=YO>>Uj<|qk!B-y8j>HXZl(U z{kRTyycxQqjoj2Ng;cGZWv{ix%qC|jr)Z5*P+ucUSlpp`C}CTnjRRn!t0=^Z$6dD+cH5|#fd~}z?BJO5@<*pv<5{;oakQ` zc!qG;bkNGmMv?}$VNcOA8EqdznXll;UykrtzGXezmg=O^JR2yV6*Q-K+#2;p8UFpw zYV93s(MN@I!}5XYiry2cx~{>ZaqVDMcLZv>yk7j?usKu9_Cu+>yhi(|a-d{YO(7VP z;H9O$x^_9vDG6)xWtdJN<03YWrIt8|GsLPDB(GhysAD!awzy-lc-kU$$5^oG$JUOV zlGtUMtfQvDxo-9(+m*6A>D(}WJf1R7yyyE43sgCHJpw5mBwT8Gilo#I8pS=z_zTks z&*=ci*t?3%`y`z@^scQCg>ab*K!jV2nT9QhlFnc8oL^hcK|m-6F>?669>c;!}CK-|T~`w!LNa_hUL3Ya|Q0;Ewzp0`k3}d!`&n zb6>!f+>(`DHtXtGaE;e6!GPI>1MqE2w_}r8(y-oo;gI79TBgWnX1|FkJNLlCHa!-8 zbcFsElM1JFcD`R_X(3P*tM3ACb}nE?2kIH=3jE@J(t-LG6`7uQSl$G{^@I!d@Q2!L!eJ}t@|a*XYcfmOdbEP&go9}jQ=nyrg_W|*Q>Z0|XFBuij(GQnN@3F!kbApq`0zY* zzrXnZ`;7Rg<_g?391svE-j753|9`sX$D{cFCR^A!{;x3rH7IxGHJ9%=Q&Bq>&qM)1 ze*xf#8D`?)daxiMGzl67p5J1PB|xq>Wf|la`Ydv}Au|<5?4_>RB^u*_I^42`VZ{UK zBbp2mJEIjjrdBBA#&?OuUQ1*$o6QkvxlVgaS$|-Iy~X#kyK=m4Isfra`RIAxY@7jA zm$ouB8!-95anSdeg=ix_Y7pk3JZ8tAg?whj^J6@E5Yj`w3HndyiQkO?=?-Fqe3r!1 zPYkAk0HAxRj;$O=_1+%hL;K+M>3Z?|+3y=e?Ib^F`RObHt>SO71beh&ulGJ1e?c?~D)bN?wbAY)9fsUQsl@!kF;Ciy%P9xA`pqXFx<8bq9LD>Ly#Sb&YR( z!Jl36dEoa1067gn2CN_5ai8%MeekDZ=)al+KjA$+u=_p$KU^RB?VhiVPB=2 zth>%?xa{_~;ZDUcNcT6FTvAxaL{$R4e-6i8nWC-4Q<9$Mh*qhBK#`-MOc^UvCL41` zaLVOOX-qYzb9%m8iK1yIvxPB}Y3P20>)me_(VD;V!=C?Q(X8_RH=3Ipd}x>HJ57tLP>J2?oTr8bt}}`0L`2;b;-~ z4W;$1i&ByOvs`K_D7HT-bH zE}G528@O`vr)vBeS$7zuz@GrSRj7E zX10QF>Q6Jf!e1ZL?$)kNEh9;|7|k%;a-}eh<=WlHLX=xlJpJ=4` z-RPZUa@tzWl4Z=WWq%jmD+1hoBT@Q5q7s#Hq?y+y<}Wq`M|Vv1K>z*cs<1RF+ahjR zK(fUsb1cWdWW!qHS;^r=;Mx?d7-w1AY2!z5pYdteV2|J!`bNOl{@F)s^)MPoX!8iNgr- z+>X*?_r~zJZijEUULic%uG*3OqJl#yu`FBxhU5=S86Suh^45&8u~IBQByIeTXh zc&^``x5!TDQ1Kpb;VP1?vWOA2 za`6PIIb!jC_R*SA_a%SPr#F~rDfWx8UAEwbzu<^4O4E+NisQ1$XAShLiY)`(25HY> zAfKBk7!+wDP7@y`#ktH8r7|(WNz$$d?6NJA4GxY5LCFSpSQqKMXj_%36^v#{T0<~ z+7FyaD&noQ;yJ7$(1pgXNU7uau7c|L$^(OkoGKh&h4Cc8z@bvRwI&ys z)9`^2@)1u@<%3*1wJYjul?*lavV;@09y5}Gv-d#PfLB-v%2!ep;zz{_BLy|&V#YH% zqhZt>p)@^SgNqe|9oyl?)NU@xl27Pqt0;H*^EN;2ns&+cn|4l1{ua{l6)i1%SEV~U zw?w?@yq0U?4quE8vlHvl^K#FqW>l5G&=pF2|E8TcC5saJq|cs+_tB?Ec`D-K?TltG zw^PMelxWj@R(3C<;mS_l>o(h&*>V^$$X4LFY58H5yY?(PYAe}JqG`?kl{5EFB_ydn z{qo={XDd5ikt{{1{?WK4#Ff}~6X)A2+*ICW6YRgj!yypkXIE8^aeonrY1 zPF0_d$h=>YW)OSZzopxeSk(aJsnw8JcM#nh$*;f5bZc@Szgq@tKGthP+aqJ=tkOH0 z^rPLz(idt|;~Uc|cQ`sn+O(CiLiY@g-md&vHeXcvks<|Mz~~)r7r^uhK&N&`S^=R}s@QlIW+qUUo zlr!s9RJm1CfWCJ0w-EN+6!=Q^c3X(>3xFu1>& zt@OkFWoz}3CFjK4lDKGllq_J`|&T*8`pUp;GT*=^FwMcSn7O-ucbZ-lD`dMQ0P* zCkj6OKNgcsTQmEz^xm!0wL{oHyWJw$Z2~w4WisAyHs!^%=J~GGg*Mi!uG_-g(6wZj z>4(N;Oua>7+uWClgTF-x{RS$T=4HV2<6*!%{^P=_kN7=Y!|6jM)5IMf_Y}ex*)h9< zFIM7zPr-5r<<3j4Q*>?A1%qlwCBGe(7@`$k2Cfsm_INRC3qmR6}=r|gXy*8rW!MQ|cPNrF*F34Cp| z=3&(nXP{Bj7La3{(;nE@(VL2L27ZDQpjpSk%}#y;*YdUKIl8cU=P-Ea0H5k$J&gbY zynsD7;hnf)EQQ`t^TnoDvw7#0jgn;F1&xZUSq@9R58M=&hnvsMxeFWHhB>B{ePn}4 zo4nuMj8M~@XG9x;k3CT1jN#W^$|#PtEy8(x4s=^0#332>0JJld*KapueVK+wE zNpN=lM?2qbpVSkQeyIz3@=0WkmcG;0W5H!ADpsp?e+f{ol{=*{x$q9Hx>#w-Q=6T4 z&)C}>*X8@{|HQUQL)f(&s|E49OIa?A7x(4*0Fdksm$oy@z}YeGI%cAs`{&NY&70ut z`n4#N&!5v77Um)daxn}u55WkEdn zIi1Ba?HSch#%YO%bLSPZ$kDs9oh(b$N^}X`ISlJ*@;d$zGi`x!Fyn^{i!8l%TtvDy z@;7CRyg^Fal6(G|%_WYaYVIq`=Sn4>yQ)819KLqQKjLHqxXrnOBVaDh<+fa*6_QrG zu}ul<*IbaC{^~3M+A!nC=+ik>K-d|e!57!_Ig89;i8nh$a+c5&m^$MM*tIcQXJzN8 zeSpqskL_a9$(I<#XaRI05-MJgOJUb zGiz-y)JDIFtx2K>^T?QUpzcP(7l{7~cqtI;v({%+!kbGn347F3*_Lq6G1O7}7uP@? zmBeVU*4uV3t;@gv;kc}|G9+I42}i_7|36Y0Kj+5(3h?}|Gh>hXn-`868n2NAz69P_ zv0uG3u4-R{TkQ{VT~nja8=;`>;PAC`Y`dES5JV5~cq=6E0VKM=H)7~H48Vma)J+0133S{= zN7ug2N7+9)LhL31sRX=$R-n(=XtOVlfV+3VBk#i-r^8z>##~ea!8o7*BQu&{0?-hR z@!5{RpYTu^oi_={2%a5-vE-|xC6hGmHU81vm)1(k8+K%?V$M~L6sjfzLG=Q(4SgN| zCakvyr%oB69`yhHw00)Ll9HB)H$>hXjnQ6Eb~>%jq_v>?jhO#S%9e+blQ(k{>5P0Y zJeU||0j4N!MCl2b+mjM4hswxhxUSsFlBDW1mDsrWEOkzS!-&Q*!(wQhOzN#$fg!57 zRd~n=Su^Z8+cr0CA3D^Ow0(?{s(`olthr+GGEh~#0!Bjy2nUOmy9(X;!4{!&1}%qg zmtYRFDgn)9f#DH}?-WL}p&X|}{G}2pLXY(km_>*P4{LOMxe_E5GL`d6bolK+o5B_~ zmDo~urrMl)KY3#yF8U6;aJh?s*8JB zcuvPLM!DDr(O((!Om1k%Wl%3vykolxYkXeog{L${0bdM>3>teiU8SCJx3HRLjiy|1 zrEHI|c4iF6=CP_lrKR*0^k>RV%K5|Vx)BH8UmUK!ZDTUZA!Zco<1Lv$EejzIX5Ki! z%B+=+psCA>tI@StnzF*uf@&##DJKKm*%O;l{>3V$+ldv<9ZuS>>Aey~%H!r3&Iz?) zR5?E46cij`24L9j^*r0tp7x!ykCXzs3Jjsafl=wI_Hcdj_f)Qb=5*#HsLhyn@tAiZEH3d88)BsjRXx|_- zu(|^mFuVPk*F~B%=LFK4ecDe|K|hc?E4*(!wE}ReSZfSyJ8E}`zO%tC?l4 z%io4+7}Z-`FQTzI`}MlnjnEM+N1>e*u3QEBPMd_bWO1OcFBnmax~ESNUUt+x2=M1h$5T5JmJv_`HB# zLNfbJt5iiOxz(w#SE}vMD$kikH`4WOhr@jwVuxKQOzEJ$5BeK<^cbp~;B&?RxScS0os^;E4 z!pGbewxSKdiX=x8m?XN_*XR(;A0zvnOU5W7gV0GsMRy6Hp}M7_+BVrxrn8q;zYqN= z380#)K|jnkX=tNSYB;Y^|GP=2#?56@^e-g9{KSW-8|sa%o4&{fr`I{m59ak#DcXgC zeW5i%D9gMr1_4qb>S1?99t&`ZIBob?=3AZ(zG^ulkL<$582nV^E2Q;bz^i3 z^ra^gFSJsWpXF*jti;LoC%fMaQ;EH0>jCp=K1gFKa#`gBu}!X3=*n3pH4@xdIx7RwmtwP=tq zJ~kEc8L-LY8GAU#Os?xp^0*NBT-54V$P`bE3&Lo#4~_^IeXo4fIdDM@wSTK73HF`+^>H1)~fk~>!$ajeoM`& zO(a|2+N+Q!Sbj}r`vW=Ie&af z>Q){eCLPWYOwS^qm6PyLi){ZRi~ReaUh2#(gW*#pU3~baN}L=ZG@E{<~{0P;30&^#L3%=j6I- zdZe*ytY#BiKMkGNBYjWw%_TUAS+$_2{{xN3q^q|7%WgVGTp=SuPE3u~%_-Vn!0CZq zn&&}p<8cmFSJ1Ke?0@9O|5JZPfd9WkHiiBtvS}rUt$@gjfsSGC17vwsRMS!p(^?z1 zsac{L6`whu8BWUhrLVevc-biRgWK;dBk)<;Y&JhQ`6(}Tz#tGFOjBX^CL+@1>OFn6vIQ0HJ{WUB!hzid ze2*JL}Eo6=C%%`@uFM~eI~n?;6{3+Dx?d~~T!Rj{`JUuSa5F-Xo9 z_v!vtOl=FH8f8rH2;yhqp9%kIDg_~0bjrb`<)%_iDh!s;vbLLq3@Sysi%`XdCrREF z?2yQTWzj<;nhA!liY4GKS>>W?G%P{K@}u8`mL}!hy}`DY1d|;gHT6~an8D#}TQ6pz zXdMMF#ufQl8!PfZ3u8J zE|4WO6SXq8ZwstVOWF%u5fms|_~ZzJeBTS(SHnDNfNp;E{xF-H-2cIBa&a?k^AF;P zozb~7g#HJ!>4wt$H01^Vf){JWA$JjbkZ?0$V|2_PJI4Bt^zhK!4M-3Gp}mGEdjlHt z3#D07g`MZme5;b0#R)1|w*3R}5VO%wC6>QE7!x0z?tqVY*@F2^;)mJ9AiX8yBY2Qr z4_|7P-TGlRxvqYg&F3FxldO2tAJM>IdfAww*@-|6@Sn`4G#jM-isAwU;+!QgcF<1S z%9KrD725QmOo3AiwChBk-c;Z3>o;CmHK1K;XFY+&0Q`Zo{D7BD`MfK3gIOo>3El%- zp9z@yruX#jVK{8_c&@whlgzR{>|XkBi2vTIk+054L--N9+Wv@LY5tF`n*Z8zlQ90* zraMJRPY&e|;y)X&zsK5BgoXQh%g{Fp9DmV<_)2>4CJ9c$nYJ=|yrI+Ol zi3R}s5cfh@W^$V5fdxF<*VEh6cD~F_A0KmbdO*ASHppl+m=D_lF&OZ=g{IAFZ0I&L zjO}7XwJyfxo)xJYr7S|s^6&i^6_8zvcagD*6$F%ih=*_SP*s$jZ#Xunk64Mrkkw zqPdQl>hK)tX`dX(tD-8?#_w~~U z`)p&h(vJ2lHr4jkgJDd^fWtZkmqT4JZL} z+Hv>uqjsUTDoM>O>nPbZEk3X(Rau3{Ofw2UYN9f6RSIMPXxi}?(bfpd?XM6vEkODP zQx3R85KYoR&mF~=|4EL)A#hD3)5P5H4NSwEX8xn!!&&*$UyWlA@r1a@?lE^oK<*)y zskqa*T}gS||M*>Rp$~S&f&l@2{m5B`|Bo-$|1M_z|Bkw^N!fB!5O z@(c6}ocl?QgH2!MYge5adgb2B-S9e{&dB(DS&QofG9Ou^TW`1?<>a{;Zbq5wMCx~< zIqNtH6iCYg@MK|t22Mu-L!_sHzNe>wy=SO_!ZYciV(RyjAR6kTVH)?+FbsQ(=%>F` z_7k330f%MO!9+9cAwn|mp@uW;A!C~K(lU&8li3Hq#R??9)%s6(%jsvo_4b24fdmvy zBY?#+@*{K1eyZyyzD4vyotDXZoA%>l6YQGg7jiSR=gH8}kT74^)8R~!n$BY1|1DdJ zuy&(rt&dk{n8%7VJN+y(T*{d4=Kq!p7G1L~e&Ym(2vUg=a6QX~Q+8igLM zibz3$tJ73p0h1LHG7~s>dikF#Gi1!=;2}`o>NkNk+B2RsO?m2`PupGowh zQ(0m&ORc>l8Qv7FX@_BxC1sYxv8Spxww4o&5AFiK+(jd5ek?Iqi`P<=)6JF75`1PS zcecj#D9QjypV3KWH6BksghMZU87}}=kK>^vAoe-t>JPG>NBpP@f?@h$Su}*s`Sb5_ zNB@$zlDw1OQ$SMTCh;cWCg~@LQwFI>sSHxVCdnqzCy-LfBgR-}8Ty=)j?pI^QzTPR z_ZwOr^UnE)71Eg)3yTdSKR)MWxe%5^PmnxkB9 z3q5%Ge)TdrF5TfkjO88zO>#|oPx+_*KVO@?lem-mQ~asH4AM-!sj!o>lk`)#sq)e? z?ppRdPo;V!&=eGZamJ_5*JW5#$ z<5|v7^>r@@j!IMeSJxc`$8G;C6pkuMHrexW7hwqJitJWOvee%J(I`1y?=5V*qVcu| zZVtQcDh0`!e$q;pjK;ch&6VX*w6hhM2b8`cfhB8>U4RW!WE4u1nO`ty}gx!CD=LT{@g`j->EmjwO>RXlRt=Db#LUDNj^t zgu#v}lPVKL8FyMW-Z9RT-glZOSH^7pb-CTDU)qf|H7*iRVMFLedDTAS0?XNz7;fxt&;c3K8+exSE>5+-qICmJSJ8tkX399x7c5WVeQfNik4T zEYB2Z&;$m%f}(?o0p)_qf*e6-L*YShMUT0y=O0J>|89TiQHOC?I>GXlOFAvS2+;i?#1M zAhV!XF-+EpH?&OKnISXlhy6C~I-%Uh7dh}W{W?_RC7^q*`h>T$hZ1?PujBW43YWUv zw@&-MJio~iCaL#QR$h%)=)1>Fac+~F!WtX!xUa*j)-U>D|5mP_^iQ0pJnb;?T=xUv zC#<}hV4{+F{XBhlm$HJ;SUyuU_!Rc|SIqGxJ#q{$_!27NwK%d&nWyFu3#?ht2?AKO zeYZ}GNK|+L@UBmT_zcFCWw;a%JKlr!a$l=GdlmP-ZE>(fNKwBa0}_w39ieTL?Xz0$7?@okVJjJalHuDW66!VohCauOD( z(Of>My#fSRoO*nTy%%9M(-uw?^cfeZFm*f%@g+1k&d#L^DD3KW2B6>u?9E#67kPC? z5!;Y*tD{_;F%1^uEMhNnVQ`+~EwFz~sZP+iPxLRC1r!?0{?<)Czx14A1F7L5{*@1g zHrL^=c8q@U-zzsyiIr6HNu4jqhLMkG{uxQInr7dUsm}D_{rg!H7PMbK@#qKkqiC@S zCgqrkyf;Fdt8yQZE|-qu$1M1j%2Y7L;v^fO+1fpOlZt{ur@mDX1aCkQLNWKc>E) z#Nz0?Ew=Litm6Nb9^HjO7Q7G}%uoPha|#nzUI&TQzuQgSES0 zk3YLskEu6b4=IEF?Z0-B5NaZ`r1GgSly`3i2M4@|oLzLF^C>c963*zzQau;~O91CL z;&lySI-cB&V-@tvE@D8hUI>UOYa-b|8Dr%0d*qMaZ_D5%eSY8c{v2yY89bNeZ5#=O zpYU{eb3m84pWYAzAS~1mn&ID|7xpR?7eS$zDg^5%PMReEGK@ug07!qY2x2mp#g9b< z=|@1xQ1J?GHhZUdb-g58c zz3@Nk9$su|T%_GbIpoAa&P;H{;rxxWRcsri%T@y+9tg^f2b>>F< zLw|FjU?;@qhtn7c6Dt=jqOY;3n@mnso;1T{q&TdX z?pXOkuL$+R3WLiJ>tXqowTstwUgN&ocTy{{sX84wZWt$JncSAb_V2R!(@Z)Zn~fDD z+@*7j-U`p+r;)~LtNG?ecg6GLA9Z?}*hs)%0%d#G=_{mA$3mgQqa0CGM;a;KNmort zICP+G$)k=PN3sMO$|}9*&rBwZ7@X$%X4;PV;^uEc+?R4{%}+K!C~>GhSg<p2$?q zYNB41L63DRDczh-?YD?jQyP(R%ntu6cS9Nw74H!4V4#GgjHKw05LsVH1kBL1w6Nbo z6EXU1Omz4&<9kB3tUP>xthFq5ZG$c)m6g&b{cW9!4rR_4Q53nfJa!OI8Eb*IidT-y z_Q4?ugr*YV&X$rD`CA+EfJA#(J!W5e5`C%VC$i+?rqmUyNz^mOZQMAZo&KW52UW8N zhn#9XoH23uZHd&3I#1vQ$drLrZj<>9or7Erem5lhP%ECd!`xE!&cIS6+XmgMQC`30<0^-qc}IrcfYL2@Q2>sV3cGw#y#7XI3mFDW`RZV6O^)BcGyTQK z6Z&zFDyKUdRElxR;9M(ANyiox4k#6LAXrVTGOX<#FT*;$L}ngCS1O`EP<$8uOa&49 z)2h^hA3Rk#n;y?R7?M^ZSd+zVpqA@+K!%&7KBpS*dXDJ+4&TEaEg6vUZ!3IK$lj29 zYYIN~L&w5FnU5(p`^`d9{iHA_nz)sbIb}79=Xm$&i`&tP zprHl!CKSef(BK0TyRII-SJFzii1kAz1_s$tF@P=W7lmi(Rm;G!Ga3$BIxza`1eic= z&MKY$QR2UbYB4FB13#euUV-C7yFhOHDU!5e0|C+h_d<(a~7Z#K73(e@#p0XuxAwH9{e0YMXGD6?Vvq+)76&0W((G9)-7eTnI{&#P zwOT+G;PvVKM{dpC7uO!tT=yFQ1?aTOLbrM-Krq-oFEs9~FXj6z1ST(jM{d%-4;Eqk zJ|7ms#9cg8&H~VkQS^ZI#z9gwXX)OK2nWcc{v`()L2mLZORw#_Ki~xXE`;EFJP^kVkQjI@MXgU8<4(o|@THyFbHCR@@Fhp}qrdlyKM;ZQ`+F$oE-{qH`YAG?WJGGz ziX}&J{@jp`RTqIB5j-KMR(^mC<~JVM1{Om{ylo3Uq-s`%CIwogs-;D;iVmw`BZV3X z)n4N2bQ4-id(~PE%eq``p)CIlU1SMqjl<~Ggd~$m*Z)j}6`JI5re$DBcH>$!(%2b@ z6s2rrlQu%!x`4|n;p@D;u1jzwxf$cS&BBF7)s){t7U&XF1-muwPg0BCTE5-VI=D?E zo+GNZZ7mTxvoA`#&@k9KGfUS+7V_sCTDFGXb z8?_NaSXEbfjW4E9(4Y!HE@GuCtGOWV#6a{n(8Y&>`g=%^{kc#}TWHswzYBY}P zaHNECE4IN_q#HHOWbQ8?M)d0_%EJhdAs0&F#c_lwx0m)=k$`d|EI%EP0Bgp|Q)5pq z9)Dz#a)1{ihs1FU6HjS2A;JjL4pgSPWBCHxAf8nW9eJaAC>D9kTIdWNW5{wgCU5=d zwX7N__!Sy7N>W1rjS~|?3eQo~ohWiv=pgfgc$s=*BRvMYW(-~eUE_Jcl^Gy3F;>QZx@^h2~E7=RdGCS;bQ!3ZCn(9u;fqCa| zR5sB~!_b^)6a%eU^Ev7J63%6;(Cw*W0T#^(_jTzMKD|~dMbg15bD^%-nDt>qZfcVN zUyZR7^F;?%wu^P5Ayq6`mMeyZ$|I_7AwrJ9;nfHB>lGx?sMx+Ew2(KmDrMOc3-L|d zr52Gf{(CvNx=VMse~S-xpJE4r|ENzy=GI)g1C+Yi=TyybyFM}MtlX8xw4!aMvH$p5 zNnTLNb+DYQs`OILJAl=H{O_5lSQN|l&Ie&rIXJOGkNW3kL57s72q>$~O zq3yS6a(YyK0$;?Dd~)6Pi-FZg`!9Xbs!mrwT2*SRp;;ylLXY-fb%Z`*GWwOSRDN33 z1moSj;C%a1;*y$uw6%#1-Ux18-m86t%p0fn(WFQiX#UfzHz(xYrG4B|oy4zks7gZp z6g04es|v&Ag4&nkm`U0*Hz7U%nnI%1mV6b)Mst%)^aX9ZYKQYeGllO`nO{cL$tf#+ z+{L$jFt~-w`fLsebzKwytW2r$Y={_{s!!;2Xl_EuNK(OI;mxUxN4HF5mZZ#N_7=E~ zRMN&|Sz21+U_qWC^pRd-1ee(9#{QMsOejx!wnoS#CRyx>;EpEkAbQ{Ijos#zeYtER zIbte5(P<~yf=jCLz`d%UHP=L4Jww-TS=rvphiik&%!n~Y|9>d^#^B7NZQG8G4mwUc zwr$(CZ9DnWamTi8+qP}nwqDLX^{VbU_r81U)voW?u3F#TyJoF5=Nw~>A!Z*l6f=C{ zwwRgo0mGultiJ$f0$G{4iLCmoFc%9?4q)5+9k!hfyYduEo6g^T33fioa zG|6mC=yW&`Co`5w-Ev6mz_#;0E=(KNy2f3Tu!ghdn`5Z)o+Kexwr9_1;?z&YAyD?F zp*ct>bHI@u{a^%Z5i+P)M3jGx&m;4tdc)wvTH9N6DT;H}nOlosyEE{x$#nLv;-YUS z?DLZ%nM9!W_h((ZqD=NfTm&K$C}AShLX~tJFSKD?a&HdbvhvAb#$q-#={p-g|C`}1 z>9Lubxq`{bn5JoJl63xFnxFr4h`zJb7Bhuf{o4+Of^PD`0O1yxblW2J$CEtDJs(W7 z$2QddL$(~aZFV(;Fwg?XN4206)({5Sz8W+uMRB*$GaYIiUBsS~(ybHx&;d$F9igWH|XZf^SQ{rt6pQEti>?$+$O5YJX9g;q&yd#LHl$`n8`flqdCE& zIY^k3F=0pp@?U!d^LiK`9`xRgev7&xt`0{YT7C%ATdsQ4mj@-u2c_|+=5@oRVb!DR z11CpZ4$UA?%ljS4pOU+nsck`SYxdN{YQar;Se$ZvG-$gV?J$@(Wyf1*J3Vl>bA(MoG%9?7s~IRw3|r`KAU&_1+W%T#am$|l4Fnhz)P=l_pGE>^iqyE6l+l}q;wr8 zpe9T>18bp_p7e}?h{prvyDKHKsj;|a9HHBB<`!rPTa4)Tmn(>4qgVciJdjP6>I2&K zUq4ZBozk_3d9M}&FPR<*>>E^Kd4cZ6b*RWjXt#{bkT)*c!i6QK>iMxVuc#WZjD84OUG;)q7T6s<7C_msFqe+m^l_Bj8w0UlNU>#mfu z$X4eidd%^X$c`GynQW`qb4~Z){44B+>X$KWEA+P^3T&)16?B?9Vx^wA8*iT}Eljr{ zY-1m66DhjI6oXo(VRlFN56=+%2MQOu$4bRAdytk(B}@CfR_wOD0e^K~P+^9#hB zp;enCj?1`DoT9Hg(DP*JT^H6B)ylcXFvf&W6&^@R6V|k!!7Bk_=n{Pp#?RB_@ebqb zuh-edM}{QYUw*)SD~}$I9T|ZHbf(yJYD5N_?L?nP zhkhy&k~6In$R)yX-Bs&)6{i*5c0La)RaFsQP2|zT1Mb;dJF!zp4R*gSN6Ia*V zetF-=I&E|)DDl!NJvEGt7+DTwJvSK&wc0{F#j8dC8Bi7CORUB|{*1379I>(w`OTXId;&zvW ziQ(=H+Ga5`4YYk}^!L7CEY$iL;l|W3LQxKh#v@z_^amZdl9tzp(L`Fg%QF5d+;NOM>Okorp;NM0nJhmSl_ zg_h3qHOUFA%#YJXl-@PETRT=&s<9Z^UZs-{kRiW|CYDY}?n6us5GiwoKe>0Mq$mI( z)*^g+?+<3c*peL3mkDgafn z0Bq5)Xd!G_UD41u3)8r40X!JmP~W&(M%}U1p!)T6ve#$$n#tJKLNhj7#G8s|I^}hj zarFw=dLg0hdN{xPk+=f~M`<2P7Y5#3}XqEZ>eYV`EGpcNvn~1LkvEd)N;S8b0NGdZM_2Df%k$x=oQMfyn6J$J7`dLX));F;|k>5j&5x)jSsh(LI&~7DkLQ8IfIxbFnv| zHf1s^iySZAx`g`lUtpQ3tJcu%mKVw7=hd+$qPn?bQnt*kyZPg0O?e_-X)%rcj)}+4 z9@HAzoI0Al*|loA^C%vTsc#vJMx|5gwnfN6g5DbIqih-Q+`B!4sa!PSP-b;)i>u$I*1ay?muvJj`sH#Tn-+cJ8?PyV3yytreL(r6&2q zRmjFJtLN2m;mN?pMSj!$;ZH>l>bAp%pYGLcG?~CwW26`w>m>}Ad7e;iCAz;RvP1Dv zNtM$LVB~JfL-k4AHa?3}kl^V_+P*B!P)(JlN1Y0H6Ze9Qyk}OS|CA*1tLD+*-4Mj4 zF(ElU|7`Tdor`%r*5CtH=OSw^&E9POmdzDxM=kgv6)Txta@Jv;EjUkw460Gn@mv05Kygf~}yuGz=1F;vhV>k|-Ue}dq zCocrrGdHlUr5liUxuK~3TSKO^XDA)z8$}%6K6M=4AzBnFvR&Z08%cd3*g|+1OVn{} zM-yib>wB2^x*fD6MX;E#bF6P0Dcz%b2A~Qo(KhNmni6}$7334AS(RE-=`7SFWkvFc zDv4DY<))3KaC>RhlV>;pW#U#y|GUl*-nA%>57JoH4W?&Hl*A6p|&k!%@ z8ShH)B&)^W5M!=JC+u&IsFwV`S+1V2{m&GKO1VaG$l@B}e13%zFh<^}?OQ7#RU zX*w(g7x5`Buk1;OjI>cI_BTNm7I(777F97P(Jy-eQX;krJW7Yp#HXw-7xa0#Wu;7m z(!J}cUOZ87k;ePjS+R=-5!5D&PF79uq-!S%1Ezrq`o-&&>}4ht!Picy`!QhW47U`r z%Wut4*MRVb);(9ItPNy13Z^?0_Vy&{=UaUmNDwg9C8>!XC5cTTcXYs_4KC2jorUq@ zO(Mm!M<1nk*-`(bgg%-Ig$^qB+1>8G$!x%yMdgODEn^1L! z>3woo=AzER!u7!a>{h^~zTtpfu`L4cgz`B7uG&A;GPCPyTM-IVew3ROxbljq01Wr? z&xy03+-Z<}ts!Kl>9)6oLz5lqSJV$9eQ3laAWeOJ5|Dq#nu5q zvW@CzA}<_C83FB+3SKbY;O$wv6LL@#SiPoYbLij*y*%1;tbonppao)oGRynm1%9dT zDkCqMbIcQEu6Ak;qFOG!RL&08vDb(*1S7(?wP**fY^R%i{9f;^CPws3R;(`IBqDjR z0fUDJ%-jo1T8Gb{kjb66lGvGB!=Bs4ZaKsNd3Sj{tPZ(p8~ntAbt6P^ut6>Ohpe{j zr>lG_niM%iF7!19LWLG^2M8m*B+5e)RlO>#6u%j zF+Vf#r!I}OT=ZFN`U%#F2$e-&t>Q<--17%oAmEUDBQz)O=I(+P$pdDnZoJp*^A_p-A_P&ckn>xkAX((bZY_S^N$loz9Y%{R`UiI zo#+c3pd2PaW~V0(-yFT$%=fNJCi8}u;`9|4Ha1PD(TVlnT<7v@@dQxH1TzPj=;g)( za>@(w(V;`7D`w<=EeiC=t^7X49BrY7k^BgQ=y9VpFNRD|-5n(aDTY&SPAjc;MR#-! z_{h0M+)5P~pT*ZoP^9BL#{qFd^M@^*9m)o;fk+5AVjxOBCIYcRj=v(VXIPew-U$B? z`zhibaQ_i-|D)%b&882TEr8S>U9cI1c2_2SKs%lBN~OIyIJs4|@J>Ho@sM)9I_bA= zAS2QxpmIvQ8G`KPuT-Om`kJ}0-y`hLPw~r9GFP|?ak)|TMCs5r=+zgB3dy<0v1@Sa z_<~$B_H4T(YE+F~BS~W-O^SqPw2x)3N+qpI@Aa0e$D52FDkz;lDU#(V9E@wi5e--8 z(I_^H47xN0yVAx~zCfv~ z*z(eslt9@1&H)aGW-7?ch|pz{k~+Vnt_RL4(-Qn}|p0mzQ%f;Wxe+7jBE zMmB;!|BYmGu@qu%`dud!e%luPPguc!*lzxlVk2VfV6E@;&or$;S>N)Tu(V(}kfIb%6}RgXE3mw#%+3ts zj)3No3Ix|ltRDaT{FFw0*tqTfPGNfU`zfha7 zAwE=)dOg0cu1mODdZckx!tQC#Whl%kUL?ZjTPH9v%&-QPldVWfdPv){6OVtYs_1PT5dapsKO9&Ub&7MpY zO@j4hbR(xd$J#(l-NfUq_TYw5yQoff=`5bGUk~2D78ZNY0(F$%F-!Fwv;Rg6`xkuc zzr^hSrI}~MX-CcSp#*IK<-;KHtEj4K51=L>xV8Z{&7@#gr0I@zns<7!80(RbB{-!y znftf)BhUu>VSN7Zj=B{R8-YL%M9WOEr{AT!9y$R&K5vk_3C~fZg**OYUt%_!Zu1E0 zM5I>(x~DJIXPHIU6K7eqFCls(sq`Ot#wtz2M(p$7#c)Qt4^G(=I_$VaJB*fX%jK8O z8TUD6f59GP?u9gcQy+Su@WROzF2uv4-ni`QdEpN0xxne-TQf=hCX<76vWInE8y|v+ z+z3%9Zgt0iF6w9EdZzbznnVnK^0VWdkkgCb|B^N35j>SB<>U-)#LXWB;Hz2q1YdlO99O+%Ae&7s!q$U0GN&GJiPebTMSMVr91a zP7Hmy31yE=YjqFJ9vJJ#!xPoBjZfU1+eOl5YP8pT0^Qc{Q3sfx|82Lt9HTBN{idLk zeoImPue;?xkyTX(^Y3oTKX=Oll@rG~5tOfrIJHQ5wsGak-vZ|0IJkl1O*U0bnjo6Q$CTo|K?ms1USFGFQxxt^%Y_@FIc-u7$Q=$y!Ggz`x;K;b#LMjvQbW05!*9lJ zLp$x?7J){9MLMOqLI8 zyfBhj7&qDpI4yZWqzsWrwRV3^C#9PgD9z=l)G0UjILy`PV7YYn7`Pz;hC+&rF9r5Y zoH0rE(C?H$>R+~2%fD|woq#+yoA`F>9VlZ{FDsq`8|Ma{gRRKR3o>>y1nwJI=-u#9 z&vxvkIR!p*2r9@bQ!aFV%H^=0l_4;-EOl3RhSOnX;q1Whhm|@SK9f}5w^`+>hG{iv z8z5i0c1nU3bCXnpaoW(U?RKM_M+mp&XRr#bRzB>*P|)*7cI%}{DCNlLa0PSNANDJ< zSeh)A>1%u*VV8F0@{bh<{=mpLS^XaD#L;y0`=05CmTL6xNVPhXJv3Q3vlvt&cfFgd zYdwsh+R&#YbQHu+AZ9AWM)@0IVM2(^5j(!6O*fi&x}fF9xyHiWdxQDmvx82^cH^h* z$jogw->4!^KP)mlyj>p-ATmDhQ)GDD75A+OdyI)H&W>7wtt(c%z@s|O6vdL5koP-P zDeXiwj& z0o4#FW1Tt8tpzG-N#P*qh|9wq5_MMFJeTW@#6Wh zK9fx$G=bA%B{4$snm#J{z5A;r8oLiwQcJQMSsq6q!UE3~UsctvfZOmK8Ke8&*Yif% zTSq6C&v{f!R0LZ1vQTC$5_)6kZC6uLO_NigR`Z!MS)}^Xx`a4^&&D{Kj$-92TPzUU z?=Gt186TbQD9n4rp3KParbE`9#U+>5tte5ciIUDrb~u?eDiS0H)AneAVmX~-KNtGw+Hry4YC+`@Y*{rq$z7ryZwWU+}0Pg$r z)4ZpQfQxm@6UyF*q(e|weIMzK@vIWpmpk7*iH ztr_P7np~)oNVV3;OOD+x18L9_rB|ALFeg|#TO984j=rVNK%Ii$n#8rWQC3oM-hKID z@?gV0=*1~klg3bKGj%m z^LU&scO>h{^BQ3Z;9r>IuKOdioy>WXiOa?cEz{Dc6Uc&*uOB(eQ`iJJAb0}!Ni7la z;hi8B9-4Pi!%+>!sciiA4Se^DR&mxM#g+{XC7;nS$T`Cu!fer+1D#z_^4 zrzI9jg2grl5P4gL5ip0$AYqE7@(>X-qXdkc8!?WUn51M-ODCub*Z+Agy_FM^_exx) zSV8$#aKFC0kyYS5eHyokl}?sM_E~;Qb^PYicy>Oew|zZNwOxTUqH}#qp)KGZhuMOATR2jUAUqUObluRh<+M?agxGPsDL#_Reuk?wny}&eULR zMIWleZOva(<7mcI47i_U#T~wAwEzBSa%S2Q#@Xs|6@GbQ^76p}{DCpp59R;_BpKb; zhU@$k)mXtLO(=sqR`pZO39(a6QyV0Z3p&dGM^ zX}&diAW-HFeHIKnm&#>eBI#i%G)M^`>3+>&Ow548o;pxiA9Z6NEiaO?-F&iUWuwYo zUtR2kR%2?PoTIkEp)qh$ESMmUcLExrXPi`r&I*NI-mMAyIcAccZ7JM>Y+`e(hq$b` zlD*^zLQnLQZnn|#EfUq@FNtVAHP{42sr+)2N}s@SZpR0u%>-MXxTqD$o7kp%AHBW< z)6DSRo(Ubze8#m1ss^Fa@uOO7W;pvvyRAerxeoK7T9Z;UhJh!?5VD*dVM`J!gMC)? z(rzbbog+TsNl=#gGkaWo5G&KWKp$;NJX8Bfaw}*G z6?IKSIpEKZ!^KdLfItZ#aKdOizmlsA?-T_Q1tzl{DLneJe+T%ZcwD~@ zTo=Q&<@;baVBIELR*HB@OctbTU;`XLI&oz$-=_&qvx5K|<2%-zYd7>IjLQCu2lozT zOKAnYHz@rv^b09LV9tOkr4xtMTXk~;k+m>OPW~?Wh;?khoQ2NckEsq?GgX^*yQn>F zb;By9a{RsBa+_lFXWCV)GWg+jrth~xcFZts852>qFYliB%7<@|CHSXb7v?h-57RVd zu@})C5H^b)!liMqx;0JFvBgWV-5mkuhZK8f))cr)DQxB9LIHbVhoz)-Ogg18abQN- zhzN9(7Ac&tM*~tA$|)KUJ5s9xH?eH6o2G7-QolxGan3GsUSuEtnsit+NgzE+RHa(j ziHnaq`WS-|gX1D4gOJwljR;OIhc~Y(3X7PwmdEWL`4nPoGiJvq841y_#%6=gdtMG|nQ?zk0;7yP9;mR2Ts>nd-J(kQI<*uJE& z9`Va+Hzf@~_TPFDtu zwyrEHqC5Q-S%6debf5e-$GG2yIY;gM>rcG!%c9rT8pk#-v8xrPilFl{wkL;1^3h$L zDssI{%{8QU!Pup>xGiljlY!HknA0_|wlveNdU~3hKG}#?z`o{s(QiqZ)?=)`Us419 z25nCQdEpvNPJyu-HO3+vb8l~2HSf=ZYGR8kt>N_4%?`r=+}MU@eRe)54O{6i>Z^1UlV?ld0@hxZ?e$_JT!;(?~VIjZTXs7GIGWj%JuCeJToMGj4`J zYx`?On6|scf6`3t#~^S*FlW^G?qD^B8!rf<@WsbCm*v6aTO7d!5>~&zLja0Jj5tt} z1e?S@RrW*v^Rhy>_1)zppKkd44|Rm_YdZuzZkZhsuD>Q+0V-Tl=eYXA(nyB!zBSvw zBj%F3!-ltsrFP(q?7^aTxj~;1Ul7M3!hR=o$Ir+QN(ScbJtOsm?_pl{AzrZVNe68M zg1S(v4ADtns7Ja!bPIWz>)*M&IfUUKcCjCL0#>7$n{rOOoC;+6RGGNScYeYZ2Fb%E z2E~JG_Mu}e$=(pVIZQouQH*_#+n;`87&P#@eqxQ zuGSA*PHkXZQvb~CgraH?*|`o!vmwUzw<(5_bOint0Z-2A5FOb7Ic%~vP!8u0EbG&( zd42$gES~tsUA4bE1!Su9~@Kq(-VI85Bk0< zxqlNA{+HwYKlri#6`53$ww>cc^gheCPi;ie;L(6CIAA;hA|#S2p^y{KCxH0|^m?of zZQ}x$Ev*;j><^FZ{wNYhv)S*8;t!@VL0cPv^#kFVn3$SwwyRG(4^7c-{a7E$fG(`Q z-1PvHDYR{F9+6v(uVK=J4YaV%%4x0;=%KqBQ{$4(OPuy>Um%|Hs{-EKIMOgV@~t!D zs2!@_fuOkM;8LQvA;>iQS?GKH{#2UcRIm~fH_sFw*<6Awmkq{hpb9Dx+~yZ7!01){ zD$&H9d7VutL#PfKraTp~w%5TL75-D+pi$YXKc{5L0a-*Hu_+Y$mqBte(u0uD4H@;V@=U__*_ zQ&@X)IMa9~D@O#ND64dqY$S8AN(s)&26zeii7^UMOKE`nGbRDsE6BAaS$pO7{M-$$ z7YpOr=UOYFP{R2)gI-Vpy`=LKv(K2Ryx*AI*hc?WQYFX9A_LcR*&)U+MhkUS&Z(fh ziE4`uZQLevlZa^!>2SzkAT`k#fbxp!kFi$*^};yO)R@dwHsCj@Ab;~%;vmw}9MoV1N3vY}gvcaC*2|GJnG`krC zErM1_HQZ<~F^)bvXgpaZHQbVISW33$a8%E$ZRpBaC-CO7W|N0i+J6nVrR-j(^zT;H zJHn42%>Nw@PAg>m&B`{^cQQ8mW@Z2PNo0ZQnSraD`;7i5TFO#mFo|i3WUx4>1A0W1XCg*d3MmXK zbsYC`b35nyo;XqdK1EBpdHwACK2dcmS~Is+oIADY8eBBv11yft5K|_uGDDc!+V}Kw zF4`_{$-X9Mr!fcC&b+<0=S*}j-6LDt;XPsZ_WT_POhECDD0I+)u{EW!MyINlTr=+l zs-t+Fo(7|f!{E4w4*rRo_*fbx%7p^CdpV0e*OOYtUbaB_ewwf@e*}3wN;^_kW18|` zwn_nANUIgs+mZUc)u?5YMH-}B=hcz5Jf^7NWZ9(Hl5zVvR?!WCm8oapwRGex!pO5{ zLFhewnZzTRxH`^@{ZZjL(z71KGWIxj<2Z7WDU{nt-eukr#DsU0MX0`z+jaIfw^gpB zqtT#x)07wSy5r%eRfG8~`{dgmrUVUe&-FvSl+Fxk-TTrP4ITQncxNRsigTODPDpBO zR2Swrs2yRYz)L%E*_2P%2!c7Ht~}pU;6}My>ln^o@nOBb%8O9ioD7}j6On0we6`u2 zKIJ>ca8+i{AwgLb$Aou@+R;oSg%i8*Z;w!E$}fR#K5p&xM~9OrIJ$@!xgDpB=7(ca zEk!X)=AJxqg9pWQ*eYyeHMT(WJ}Uf<7e$Pd!r;nzRPXBeI4XCP+Wkv>D)I7Wt6H! zdBg8O3uA8^T7ifv# z@Z06S8_RvOjMt1@Cch&AAiPN{f5vHc(8|R@y85e7E-Fb!?yLSD44?61Yw!LZf{SdqL+H4HIMZtK+ z0nl#x&{dD)0~+0fvGD%M`8 z!{5~Cxi%*!FcwvJ^aQGQOzeMBtdtKnuoB@RK-U<{=o}c_D3$UC;&?@^gJsIq6A*mF zUv>O6FX%~z9E6*d^N-0OLthzUJAKFQ=3m7Do~JVC|FJ2hs27hmha=ZTz;4)Ow0Hn9BX&tOd3y`qQNvt`ELx)jGT)H{c^IH&G# zHHl-ajYgXH4r2!e8_VKG+doA{^pJ6d5lGbYO^a7ho(`yBE-it=KnWl82!%O>Wp@DD zSAx&bAIfxN+e|HR5Cf}zUxr1mcrj-Sp7GDhk1EuXC3$AunL=w@%oZa;7fD7n9FAX+ z7gsd)I#_gWv2G+sDj5wK%s5Oh!2rZ9~UJhH>fC{LX-d+XG#DgC(5; zgh7K${U?GG21WDPhq2JzG~G~(DnxrF{>-Gl%CM>>YHYdiUt)@5Z5>>1%8*%irg?W! z$H~3*3kw@kG09<9BJj!_&nsrD61}4Xx#-Q(9R+@;ZF{bt@0-3=j=xIcXnU=ZVUdsg zW?oVL^|;$}PHNu%rhS!t)4rJg_v7yW!T$2}`fizgn&{TGr34_xT0^YPCjPpmkc28s zo(HCmAj(HbolR}bo!bzvHLj~0m$6Vpm6rqx%k~q4hHkX*uGc_`P2?*H&E3Y@`b*Y{ z_uP#(Kl{AF+2(E&`*6hD__4w5c-3pdI3hy7$d4SnX2j=94beUKJg$d&4hBmdbNrh1=k2lg`Pj z8WOM9d-w2zf`#2h=8e1t z8wJLBq7T34&Ai4-1d?#OZXhW|_MF)B0|RIy79Jm8p+A~NWP?vkeWH?I7R z89LftGTk0M>X5RRj&G{izyywoNRN5NTKI)X{g60OURk(Po}Zj%?zgK6cVo$RX-$!& zCUqO5MSg@@62=9?Zel{Di&3s6Tv1sKvx)Q3qgbIeW1P5JiJ3zYs`Z9BGfZH_7#VLh zQ;Y=L7>XNZ84KBUMfGlBHDL^c>XVZ#^Tos9B9ZH;Mn!VWy52I>P5Q|ew&7FA7hjdH$~em){>u!B6cG@LmW?6Gf^11l2GxfZL% z2xM-kPLUV#AN530iM=+z;v%&re@lK)bY|~{mD{66F>X`3_K(;1DNP^c3KddkNU>F> zB<%~1ErZJbe4r2^B{N82Xf1K%r7WLw%6GG9t^Gm7aujHgD4we&fy_R}7BnG5MomS_ zh+1T_TRO1;8?8nDD1fB78|nuZCuuWk54DZn*zxB$qc@uV{66tqqV5NHh+JtA=aK#I zI6}yeOd{)I+8^M^@l=-a6X%jvJ`|nf;Jw+EjE0Fgx~7=+b1HU2C^_Z%k z)++&eh6_qugd!s-Exx*HdJ_IFD#3n^&~!pQb6-9-N0MfK7n2gsHuW16V?_~Exlv=Y za82smF5_0Q(l(n)9iLu6BydUkEq-&Nf1CqjP7Dq#-Qb=t*$wx%8P-@lz|NVpd`(bg z&Hmv>0?JjgOAe>ox3ogeD|`W6!4D%&Y?lNp#|ddHr!dlh2X#L=;;aJ6cfQLOzzVrvH$?t98+W35eqTdk{sS zLTmPn{8_$3Yw$v;V6I5 z1X|#wd=tn6|CWo2g|U}5JxVI|!{ea11674VoX4+NUdn0a#Eu<1 z7FETyNeI`|^{zO^pu)O9dhJA6E}<$V1fPVWUE1l9&P<`oZG)lsB|kTf~I< zj-W_(^QK^5&^^+per>-{+h*HT_0ZCp&|i7FW<3>yc5DOH(3wDRYW-7Lo;^lTO_9Le zsHP>{OV~woO&nz|c81-GhKU9&ybwQ4dHOuEsOHOhp4_gP8uw1QM+@;MG)-lCvcGr_ z8;yJ2gz1&OR^hEF7@^MEreY(j3F6? z;ew8pHxbaZq~F{W>>yf0cptV(it0<~6umN*Ys#*etb-rAUk4HJo8Njq|aoZmdbz~!1bI$?9739T$53>FT3d-e`;Li zk@1B74X!oCPE>)G#gyy)p25@gg|63QsqA+*6UI@wv4ZQ+oa$2D!)%AgF$)fq_HwrE zfm{EXX`ADUliZW0DsW&9byX=4{iIo)`t%WB3v6kR3QPdK0tsb-vx?rJphbJ&S=@n! zRUK246>(Nvk@3rhz%;;=X30e1a^+WMN2aN1uMc#cvQ}QPTOVby>Wv7h$g%PGjb7P( zO!nSr2vyn|C)w7})~W_;v3D||z<|&=O3aKZ?ded8XU;2p_Yt?6wj$@BI{4Tv$~bfqxC1f^2#;2vk6x_c6A133OEB7el<+y9kOQ zi2n|Fkb`F`XqD~Os|=>=1_}w2n_LSb=s1Q-=l<({;h!uEcN9;3JS1TMvJOaR{WCgr zPXL~8TaF?~R;H0F%*3yRB`I;A`}Y_5iReVELM(CX{1hT%>Jcq@SbQR(hbdkufiVre z>JyxSeH(6Qyoj3xG(8%8_M~#Pq%u4#^|Z0FR{pj;)#UD@GGX(Ekk$`!ky{Q0456KD zT<-D>)|y9;kcteUxrhG4H9P7V59CeXwVE(u7sAVdiRCCwJ4jDE(57AT+#B`G%pacc zKM5FGqms*p_K;feCA@_W>80FVN2$={dqs$2@F$ePa)3Tr6#op0#f7Ymvnd6&CMWW&j0J1 zu__FAag>?W<;*-(qsBx_K&vWkN<;8@8f6dy;osccp;8UIy%4M}9tJ*b=hhrgpdf@N zSe@k76^!44#@s9m{zahrZufJ6K7@6cpft|+M(p%LswC+NZREOj5+WyE2+kYZxOHuR zOWY$V-{$>4iL|5I(ur(c0r#<)|MSK1h=~>2QkUS(IaA&Bxx~I~r;sRo7U>jvRi#_p{}n#rq!os&&OMSMyXQ4T zlDuw+%z(2bs3q+VXLkwu*_8EiX_>g&PIB!$`4(f5A9g3T>Rq9du9{*?a}X!}OrOQn zIcey5^X~8`gSx6#HM*$G?^7`zqlilBvbB2doKuIB=~8WP4*6-r%|l`6B5qSjEweNk z5Maq_a(NtINCXQ{VpN)BLOu{(FxQ29Z+lzc<=t%P@tG0q7ZuO_ewlDYbLm<08QkjX z?}?YJ<9wYy&|x#d_4??)#w*Q!drM00v$}}het4bG7r7*oH7m{@eYnpp^402gjH}e~ zvVp>ml%6%VcU)$Fe-&Z)l*9JUxErsC9^6GD!+vmI)dk@rnf}T;NPdKXIVj~?P_k_P z@n`y~Jl~n|#M150xsvqfWGBf7&D|Hl=uCnik}3O5eI4Oy4yAuKz`6IRb~&+z(Gdz(4(+Mr+cBMl=WpZ^_ivl~lK+ zSgo_PCMTCzVFkOSSdPNt6!SDbv=*$6vb1kv=fIgd#_rBU^-j%J!rNF& zg*jML)I0F|XZ5-O>22Rd~mw_@kd7-|4nhtl8K?+p(DIR^;k3F z4Ueb!Q-Se_(8Q@sehJEb>+m^S0i&({_@mrXTbtqBtDj48i}apf)Z@=$d=*<)`_#zW zBQ`uhmv>e|$+x6-GUh>m*_Un6H#5<4q?{&S5+vBpP-kH$4l3!A2KD7?f znxDs#bx>8;wwcl~ZZ5?iW#@^v*KC_ay4tIH{-ZN-EHOIFuc6~qv2;z} z)V?fO0EH1(bvKSyUT>Y9-Gfa_b;EMauD9N{@FFl z>|T7+m}bqF*E;+@aiUCGE^bZPydV)Y-0h0fqI`YM!E2x&@Mg{D*WmnJ;Ft?M>qN&% ze0{>fNzktt)5o`cj(@2(E_wOFXD^U(i^h6qdxj*MI(0o}YT}t!)n(-b+YVFUKF-S{ z1KDIv=twx&$2VHfJk*Lee8-Xf{>>gX+YliRljk%30Q( zvln?L#&Q;Cnti;d$%=fh#+pyU@X-OGKb{IA*`4s6@N=n9T`g4UHmn(pmWV6=ouZ@1irZlHgTU>uyFgvs<-YrD6 z_6jz!t}m>f!o;@Fl~Tu0=e0&r;O$GtdYU9Cgr$qd>{;f$>zZp{l13tTk(ruWfJU~P z8uYAktJj?myqg+Loa~9n5x9?^kISF$?L;md9SNc|eW*ErjmsQ*9&gJHj8)}5h8#n( zPDy0#^NJ;(Kx3l3=%9R=U?E#*)4B!=dZ3Ar=9n(972$tEGrhQv>}OpElBidJIG+k! z7l9|_R$*a^PKeZjCjGNM>0SVO95Amw%zM%07F|8+HPTHvKH@%K^9zFU6$`9)7 zW*+9Jg>y4;Ym)_l4IT?L>V(xMz(Aanx!=L`1W1O>TI26B)sx5Das^np8USShRM=Vl zj_lN?hm_JmTm?++>}V6fWOClbX8O9Qq&=|lmM*DLURmP*Q1um1QGH+AA_CIg9Yc3_ zcS?6ihk`Ui3P^W%cO!^&DK)gDbl1?`@Q(2NzP0{qvF^V6oZa_1GjrKD8Xpain!yw3 z+-W(loOVOLrbyBCrKgEHPYclCsy`@30B2;6rv4fi0qM42y z1^(7POBQI`^N@T=%el|C-E?^~(plx%hUYZ95r6FGDYWg!vaeeAS^E9t+KJW5N93Z! z1mVk1Li9U+fst!Zu{N5F>WW~M-KSWRs>yd&S=q8nE;Fc%ScY0Hm+z;k&t?=Z72*zmrv~nWxoE^i! ze6wWC$Z4Af7jH|xB{SDS#;noeQTOiDhAZ8)v_E<#Rm2q1_lRtEhab~^HgF%YYbsusB9E?FvZA9+-+XwrkTLZ8Mt(d$t}pamb%jklo}48w>y zoO@F@`H~H0OBbt1JUHjc*aA!Ny>`|7XC{y6QNM)7m{X3#&wtW?W?# zr$?P2LkK@MI-$Z-e6%*}+nV0TXmL*hdl?wcAWJ|h14bq=okLbGmSgu9s$-*Eewp}pO>hTWBX*IXsGfkM<_6Q3q5AAe(?!ozK z7f7*a`6)9ftK9ArEou$QEQ1|EhV~2>V-B&=^xw8~(Tj zL1xwOE#u2)b-}Vt&3Sdc=^leYiNQ5hcpR3Imk$zB?WI8*Kr{9Q&b$-zi)hs(8EJ-0RLM*Ub@;fE@;rN5I@{DCt@uIqeeZe9 z3NzRSNAM0UGY>4Wn(^5#Bdc!lcq#^!P~15XmLk#Z`($~{5;NH5M|kH(Xq`Ar!T9>; zseMyTcE*?$^)poxkvhsBk*pFkFxAia-9h`Nt~33$2n<=3yBfNG$JOx5?8?dzwNqxf zDmkqp*^9n6bns*5!PZwO3(6(SZISJ+LKXO4?RLi%EZ?%mt$Q{NWWxQSiS$@(#T$z5 zFSRbKgm-RinkrW=)l!|S8%)60tZ_`y+t9U*YW7p zmeuKgTev&NMukj-@v;4=CyQ6mk+KV`@+!AFQD>U?QFReU=dwZe{3H*`nD9p9;?l8; z%c`=_PJ48;p$n65XTb)ZA?ia#K|!khlv0QQzuTlMwBhNZE9T)(7d;ckq9{h+k6Gt@ zpuPDEDH%B5#AQ+KEWgYnTO%yjM?opWjN&UK0L;9`Iq=Zvf+ghBaj>}j`~{YerR@%v zKk^`z*t9ib8`(9;C%gCd}3zA1BV*ID17mz zq7sNv?vLC@C;8mU^D%?WvUMxFL|3kP+0WQxeeowd1ayW63<{t&+O@>Qw<{&KA2u1# zZ{_*z>^@U9mSjJ*D?k5ys4tKZtWel8C{8NcUGPazXZOoyo*96v8jzx~*_OK7}t3<8o`ZCf8c$KOgbk6=3neJIp@;+5$*=jb(NXR$d&Pa}L z7J@`II`*is-5Um=lfngzD9)AL+Rp^gNdbP1nrCF$WHq^@f!Dl>RP35hF-0!o$>8)@E)54uB3$g6n=OgG27j0>*T(ZHtk~inl z^fgzLI)2OjX8M8)kjp3#{FHw_=$fAI1S@wOYpVE-){4-au8jGKJU>2Mpa1_IzkA9R z$O8a8=|(mnJ6##%9_(v;5h(BPkW(HcQXb$UX0QZFY)Za+*H3y_t958Y5!~K4?Rw)H z9^~(|>{>9l^h!B6{h4jrU0|C3G)59J1M^s^M0!|1X`PcLeQ)HP^z0w;G%7W8jnC-! zzk2y2SDiR&`rm zX=l2hZiOvTi?{Ceh0>DmnFDLigsP30Z#(^Vt+5U_!w0O!V$Ob_ou!@g8Iax{w8o6V zZIZ~Pcz4i0WHxzUJ<=L)0RtB6Pwnyt^E7BWnN}-zh;Rn1&WhSe`G@atYfa%MlMRbI zS09Wy42vK9?&FR}T1CPhp8R+^P&W6iJCt|!DLQ6OT)B){w)Y#nla9rPQ`s#(S&sg) zs6vjL8IA)=0fT-A$Jk(Ro^(@7bdU2qTJqON9dpsl86(yDC_dh)m36kpfJ8V}tBm#O zSGwPq-j{Ani>zb!VL3?XaU)lKs|csvL%gY>5?@g9Nj;fO3rM(NAt-}~e`*O1&3DaL z1$W}T{ru+pqc)c)4f&n~8m{WvlQKByi~TCbopQQ@v3oAgx*c1`)3=)b(*|SoaNbF< zi%7UCbYQE$bLXmr0Nx3z#E7$oAlw4}-rHx|hS=f{yNDB)xM4pqTE1CE_(keTNs_rR zM16VoaOFU^A&+$P3qvsTq=oJ=$Ck1RX7ztme-~G9gBr*1C@~#I|4F6jn97_F5hlE* zw+@EN7Z&pH;d#LZRdeg2@bN|-Jd$V69|4|&y*1(tNe#5;6&AB96jaK5k{OeOLXf*cPv^CFsjAz9Xx;gUp8 z-?$SJm*Hcgd@HRB;Os(8v#uR51x2Cn6E`(4{%Au>wG|duOUa2R*+J$Oj3A2j-c)!SeodINAVfTi_4NOZ?)}m3EaUU@jpg5S^1ICet$x^ zG%g`(()0?uqveHlR$Y+cdLJFM)1Xj_-t8DeF$WcN8U_FU4Sdt14K#?R8y+_RQx;G1 z+s|}QA>J|(#~)M^?}Po4z78(Quk3{l)Wz_#>o{X$xqYyLNr~8m;iL*|ptz+6Qs~gc z^KCw_hFit9!EIGzfj)9R1zb|_;mm1;ZMxUaki~aOB@s%UfYmYy}9Z8y9Jc^=xVrQ zLMg*^PsDVOPF^kLL#1=38^}2diOgNhHt&>McY@d3!kR~DpZgTuuv%eUGgEY*OI~ai zPbwJW+i%rnB?SYW5wa;QxK(`CD2KC<0Jzn=dgtp#^99xhZZU zLfw_1w_Bwq|6*cFz598cS$?*-BU1Hz%Q?|rzE{londB4NfapLI;a&N>2sF8w;F4^hu&Xz$cpuvx3N-=*#&(?KxuZj(1HAZKurS|g zF0cr&)W$%f1AqOQmC%7#A)JvvI8`tF$Jx;Kz}%9j<2aEaNSE%CLC{w%TAe2%LZ)oULxlwm-o3OvWsb!bvKm% zd2@|b;jvdK$Hm-_lmofEr%8(|I3T@z2E9RyE4ynmJI{XFpWckI3-Z5(V~TPmE|dv+ z8eRpTxKiTsQ+)H1(j0JC2wS$;?64|_^_OF{C=SsP^?tMleJ<*c9?TjkXbm!4%c3L7 z>SL6)HMWcXbG4G~&2Zz1ks|rS9Mk=w{J8|Ud4!`{E5}fhq#OE)%^HX1Z*o9QNWW|4 zN2tpUxw55dzD?V}UcKqV_%Jlhs@kuy0q5ZxLS8CLrQu@{M0n=xyv_n}V z-LmlGYC|c#l(r#Jlpc6uvtiJ0$Z*Jpv3)2Zz> zIp`5%xd@Nw_kjkpL7Ss|-0ZrHA#A<|e~g0mQMEn26gvGBVSDN~_)(I0Dzb*n^Qp2! zdWw967OFw}kgVL0gG7w=Zwbn-!ea@3$R8P%vV<`HVtmlX6ae?JnIbkTm zO{CMs#W`3>vgkHa11^X>@K-=6G_M#^Hh8_T=;a3 zzjyMmqWOtA!n==acW-uTGK~HT-&p*rr6s#mEhjFpcW~_SmY43FeyroGu@5Lo6vxK2*WZ!kF&8pM2diNcVHyT%TQrI?* z;f1kxYLe2}#*FbIT0G@;NK6?`NT&UOJyLnx;c%H!pA1HG?Xog2$oBnAtqSMUN3%OZ zRpnnQA#5gamzUrMP(2jh@Qj>^y@Jb+zKgs@Q&sz+9m>DWQQRG9GtYAa5bEY7Eub;v zfc@|cz;nn;MEXpjY6IWr@aK4`!9sEmUYdheVnJ5JGT;<-sy@X{K$Q<(nhrc6;}u*Q z@Xid%vp&b|TWS6~Gw$t`H%x$tJC^QJf8)9a@qBsA$m_LwqR%9%&KQv)Y~sPz6=8ar zCO4wU)AnSxHUX+(+?#f&Xqp)&E+!X9vqt3Qbls_lw%@J*s&<%>D+N9UT#-x2@O@l( zFj9Kb+?U1yY=}jX)6y8z$tIOu2c$J4G`2DU-w9pQO1Ur_IJ$3Oz`B)&VpG-c%&__% z%s=y}wqhbx@&u|k;D*j8nCzxbPBz4Z&1aZsbQzT;3&uhs#e0)8G7*gKO4fbzK0CE) zgc?ki1fP>tUPS@^5a7sc%dNejtl<@KN_cVaeOT?!%faRgufjN$O#{{ma74ONo)jhs z^-1}T_1z>aSupf&%;7+EWOO_jJ!zZAl58fcDoZ-?h=)WvO`*X#bnt@ED)(^chh5m< zDIq={%k;cZVC^2~S#Gm|S8^#uCmS&iShB;k(?6vqkfDK6GU+ag3lDPdnjgw#&dLpz z**Z}bi)zGUUjZHr`ey`Hg)s4&%9&(z&3zuVwWWr6>HPGEzNFe~jzj7EnY*Zw+|fxA zGF#{*$b~4m#ALP+D|p|0n?4ALYh3;7afi}U^pXz;nuNv|IOEQUiG_DLN&+?A)=CMYHpf8F-=efv@OSS(&8u#Xa z`cOF2hnm3nYm4qZgDTWKAeXswrh|;0=?`9nn*C(Uw%Rj*pqjzMhNr`h*dVzFe27*BAVaW~=8y<}5MC%7+pZn4) zA_xSd)Gq#-&6h}imgNjK{UMy^N+|u9Vm&M^^qj9mQ_l292d-1FsEXQFCVx#vC}+l= z#+Ihxz4M*!A$GnSfWU*7_NFa4RpwEKU2+n7o;LrAih#vLv8^&oerj2=fDn8et|c?| zBx%Oe=JnwN97fdV-2y-B6iipvKc#`~JPr4u{E60ra3d1)6_O1JLLN_shj^+on8?_d z-o}&X|59rFSYtR$1ORyuo1KKF^7&J3(0QCtR>g8o#z)4T^w8+p2y?f>CLeW={iqKe zRAfJ?bvjv@Z?iH=p1f!bjQb>8v3KI8zcFwm^>(R|^0wq0@;vh_(Ol)= zVR)H6(G5G*WSzu?Z%j2OzP`#tRf`@0|2xg2o-W)(orql=64 zUgW{x1;YY+pRfr~&K%zJTj&MukdkOn{=I(uQ!y1FutHGy_f{E^Db<*>GmTX(+^C~$ zA>`}MUO#xq)vj>U9VP6Gw@SP*`4&shAoOaSasuyOvy83pVcu;+*_>F4GEanApr82{ z2h*5cYlT|EMvDLm3cJkds1R)np57(WiSOzyj)u%GIOO^b27?X}NkdwO6t3A<<7-zB z%37DTjaj&bL>~pBvs4O4zn~KTOi<3J8g6a=&R^?Xm)O|X=$t;)EZmWmBL+t!gX+1^ zEH}6k>ae3)7MSHsBycPa2dDmM>S{tGXLZXN!~S=atV|tuWt1_C=C786K$M!Vwzoiv zLKg1ELNhKuuh#w4!stp7QR_XgTSq* zbeAu*H>r(TE3&uur-y<7*DuRx{iAS&37NzUA;<^d_!8je)|oRoYCnrta`*YQT1hlz zTUDa`b)Rbd%zWYc{wdbnK_IM(6;VJB$9=R00fvlRx)K-^e!f9hHy4mC*g8wne}GZu zat=S7&4Qi7=Rdb{u?cztIS!M=%JVkxWzYF3^u~LHfBLDyl6}wRi1pDeSfl0Po#lSf zdNyWidogZE08g~p6?)mX^TLfZA8q>Wes%Nuyk#PMoF3J0bE;~4ZJ4P-hV;w6Z|iX{ zw?$769EX?bk~(<(=WvTCP`ab7t}>R1c&Pg!!caasHWqCYe?OIJwB5b493uywJ@&H! zp|Okv{F_7arX1g@huod8^;8Pa{OBGTjzT+=#gtieKDp9RMH>5IgcL0 zM^$qjd(KYEGDowrO3uQ*MM&m1AmJNMw*r4_M{))z_GZ~!@fZLa`n`7|GHu!Vt=KG{ zzxkcy%vL=c{&tV#YgiLV9lc1VaAGk}|Kar=WkwXS-fWM+#D1v$`;;}GCzE#uHST6(i##|ZQ ze*_+dZY<~s48BQLiA+)uNK>;)3qe^(j7GE~BeG1i%Iu0Fl+tW;EtCJuJ^Ev3~fS z2eb9Og&Woju1I3*$8{d_Q5RU(!`pN0E9!#W8F0Y*5)V1w~5A_fg=1U4u(TRDGoj>HLNkCM!Ii+m?mnDp%MAIlWG z@{je!-W>B9;454~yp{Pk%p$?8d~XQZ$&nBqmKY@$%950eQEOS8K&KOq&yd+uwnhNH zO*hFgvk|tX&w_z>YT%=SisfZSpPNPcC1Ii*>_R)`*VM{;W?YZrCW|z^~vU z3I#LNGnOd-0@@zL6zeUz2cbD+w;0M_6pZ{O0sA+g-{gDN(5{wOEzNlFV-xahHFIbr^9?_>+a+I+}hXj##x405S%D@q7 zKV+u|R`YY25Tz&NO-g6tYP9T+&0_hRFwH0|iF2DCb;5k{`(H!@m3;X(XLtDLJA3a; zwW~rVD3d41QzlIETrd-t8xn=T&@VaA9|mIh7S%OVmS3coxj>!(&Ip)3{s3l8QVU-1 zT2MpaOR5V_<$DVs8(&w?xJX9T3=kdYOY>`s6p(;G#f z)fHB@*dIK^MaO5$^6Jk-yBV0( zM0cIF7lzRfL1lg%7bDH?%ojNg7ly(pPxL2-KbWxp{lP; zcuYBq8bcRpZ_tH>;L^SCBJr&du%r_<%P?}tLwcaK!3@i}ZE6r9^FqI^VqKYz74DH` zZfKI)o+zWuNr|+QgI{+MUcn!0muc&RscLG+NeYBFh)EPtjVJVD^Vg!dKVlUd1wLkpprM{ z%cwE zbjLyM?%ddc%Z$N3fgbh27E;VfH}SQsBmMAfd@t`T&7v9O}D-=3^XTt6y;brpRc|kmLpa zM{qSxi-!1e?L{d)7j#S+Qb!KB5&iN$vOb&dmujc#8Q1XQn;qfVYSFEH--z^J1>&MvjVB;u;>$JP?n^s}v*1PmXfweEh!m!aB9kb}H@wEo*GW}UGQ-jp%!l#UxDo)8WA>5(z7Y?89P=reZDJo^U|XFaDMcEZ>r^SPa7H zL6k@c?DIxFQS`CbswjtSi%Sk~fX*xwq#+klvCST*8}PBWE-?giif&hH$@K}P=x@|# zo+y;bLy3N*+^}GSKu@TOS5aB3Xud-icNG2Rq&6^PI9h-8H`l%+vr|Vl=eJ%EkKMMN z9-yEv@3=c0V;CFORu8!E1#>bJ)r2S1np6BZbcbJ9dpH2>u1XPI4~P63wncBt5A( zsbTK+yrqBH2b|oqXJ)_G*!2C0nO*sN{Jad$OJa9Mi?J_TC9yVVHy+VC*V>m{+Xkc+ z(0Nt?K)53szw{WPlWX(470KlqfELdtq-cRUQx<gy z^5E7s%qbt_7iU9%w5q21B;**6O0)E7@t2axwawXl52^h8&69Acgkr-^>WyiM6cp9rVd~lcgTSAGX|J zR52}djob=W?XQ|Svlq3U$NvLnNisD zaGqHF&-TUEN5=&tN=>HFiYRfqCAAGJDv4EwOnMPXvPYG{Uc8W=J*y z#s2%tll-$rdYI&)zENAE-IrmMcW-jUQ~AZtk*LP}iW}1_!mORW++DB+>)Oq8%R200 z(4|DXFn=p)4?K^tmt;S|uvDl`tLmbB{9L7N4zFCJ$kQ&~IK3EEdGbMysOG>lNL${t z{cNYnXl^XN!9ej#_=S8Kq|%P15PEkGg6J1%wTK*k{KgS>s(w*P+Lnd zI|4-Y|E5Pm3Yr&r1b64`YZr|Eq+1ADOf_hJ*PDU zP<14DYy90@t1N$!H%ejv7G0eG*1lHS+1*G^h;`(!e2?+gAJ9+AX6ygA0V~uHv18H$ zX^VNs$y3FBC3vUoM*&}n%8zXIl2$OVqS9)4q*6=5c3W=0ZqIwd)1Tdp=4Y}{EpIV# z!?%uR427HQzfdk`#OB*_ys_=7+eG=pH$;?eWh&_(3I-7ZNeONngcYiRTOBEB2D<)Y6G=%pgFY(VaKR>wT0!LrLEVFq3A7b zFRE#lUxc|Xv7^NKmo6S>nrSKxq!3E946E_=uU<3Of-F^7lRVs%yjYkb$?x7wnvrym zB@PNDodL{wZUNt`y1R8mGbctLI6i+Am%0aPq>jmjV;-F$#TPPS&@yu+%i?9Xzel*n zg0?GVXri7$BZ+~X`G6#=`pYkziwY|Et&${FzMeMS4GgUD-)O*6aLvlvJ_+6#T(wM~ zUy)9(xUbkvub6L%=*g2&X?~0NtxBx>gMSScBCv#m@;FmvlH6Qk89r@5ASa)M91{q) z_aio}E${~kdz^dhC=z5`c87}N3?($cTzVNwHF0=AfGj)#9|$LD!%lhpH8tVi01geu z+2~G}t+M52Rt?l{<|mnDxu2BB5WP|3Fr5sDNDRhz^0YYjY${VTh?>g>8(aX#nKFIU z0uv~*?Hq^h2ZTkrvy}N~^KaTen{NL`LYF{pn_1=pXUdQX^P8`2lMo{$!Ou#YS@dgu z|Dyc{iPkx07xCXdC!kkyc@Ls|@?k)7SxoI;RwtTd<}%Bta3r&=D86L$*nv==l?C!s z%}^oz)K4HK8hhqd^DZIgGnB=_0Rg<)$TsLPNYv-yL2b_2V^M9+&5(`yYJIHx2~FsO zzsMV$f#5dh`Z4ikbU93*43*L*aU5ryJIWp7>yG4vaEh>-_+-gKZqU?`^ zr#_43L%|1@WUPoU>r(tO4Dtw$>S$5e%sN(yhg@lED9L}WG!wWz&K>7283#eZ4hg!Y z;%1hyt5_;qoI9(HlQ{Jm%2Tk57{sVt51lxKfE3|cQo`CexQJJcsLw{{_PVYhkQr5g z`vDnscIJ<5SKK6S(=sN6jDC^)g9RbNa&YmGN$9V?kYA9-1lgA8YkxzMUZ&d(kL?~1 z;Ao{VXN4SgLkKGBe=vx{{)59mh~c_O4VY{aZ_edF7}`5g2pm?Crvm?hhYUR=9v`@4 zNHGtAWeMV(a5_XJl&aqag4cIn^TCmAlc8h<5aJAkjdh2NHuFFa2=G%LKM1{2?SF+<>NJ8y!FFx`Ayk;9V{Ss;|O*Eq=`_1vb3WKkr^*Yi@tFnz{U{MXY+y z1qt1L5BbGu_U1$a+dy7>dB_BHRjQvMj?_P7+`H!OhM{{4a z;2hpy-$3fojVK}|4Dn@q|C#`k&#Uq3j#uM;#;?YgabHmLj{Rj?S(*AJAG(p(1RBy_ zjhi3-vP4xuXI?hSNH#p z5E$+yYn zj|M)z=J);SCE}9VH-dV35Imf|c|A}rZ(h{rIN!VkdqD8!#mp7*D~gW)qc>*jc9{Rl z_jf5a7lMbcj4$dOe26b<8kSHm@Icmm@v>9=I(;sS^I{!H`6{-m8PX09snF_3@Z&!k zIRyKH2P^Z}pmQu^?$#As~`C#}&_7YV0#)I?2zhIi5dwn5w-bQ)*5{y#d3#3u9VXV*oiT9Je zR>}eGH5cbs$`@Sn^axRR0YSZ}NjSf*gbSiqaZb3G*bHK!UkdsKseZNwQn*RU!)u7u zb4QdHYjUJWFViQY_vD=r2w5S&R)i4lwG#TUue86HG8N*iEwH2*6O#FV>*z7$74jg7 z*N|%`oiQM@bG+|fd_P#ee+}9Gl|pR;ZSo;bM0s-(N+Gc{LB3WXpD%&^!O7H+vexsx zVtz3W@g*jsA()rUh?`#yDvcfOi#1(VtQYH_2oPSxjtF1r@_)1i z9;!@1eo9RFOG2vc%ZK!0MNs&aKG@;C7Ub19((tR1RK6eBkOelJDH;z6ychTqiIpk| zcPpeCmH!E)Y`=QaKYu+0l&@ktCfUS5nm3G_q6j{46MGdQlFM`RFvn{7&lST7X^0qPY4hFkp(&Q7T*#s)PlO zy^+BX0!YdIO{MwBlS<_=d-v_`y!6TCyF!QN_U(9F2o)ST-`9|e$)Zh5^?)5%%+vm2 zj-_}sHjKDzTe%Nz7~yj1c3>n$s|YIrNFxgq!#Znccx2sH_hv--RO06^mH?Et^V*{G zCc4|G#J26>kt!b~(^B7f64(7am#<6iQS491(v8*3Dgd{wd_+b$f4aTtqzb|MiXru{ z)a=PE&2K0%NSeCH4yzzb#g!%`O+XYw)%6}N!C0Hk;B7-i~rDkf#1R&c6Q6j3cXIVO3l}y z(%>hUpzPcomDqkPu&&$~xB!$G{H_vZw&PXC0g?zgynx;n*fx~<*I7z9i&$TPSIAm{ z^cArAdHFmC7e)=$p2WNb#uSJTGB^I-V)65)4#rITXGI<{<{YcSF5m-PXCTsr0xGrp zZHJjOTd4hw=L%)#THXRNVsQPo#LI5WDNYAR8-GvtD>;5c{2>LSC?6*GgS$pQ(XHUD zjMA4myL$_0i^7Ejuy`yq8xM-aIP5s6!R;VB9(XJ9_l4^4eOkTfN z>ESQk_A$y!D=R@hrWex6@&#bW^g#MbZ-_7^@mnW6EMw%0@_FSaJ_UD&C;jVjNd{V7 z_x7{38qhEKysZ~W35QcLx$+I9xxembyD!%GRW@=ueCJuWUiMFTJX`RZ@?R?}PvdS2 zez-a%TqV2fpvKFI_GXpWGABWvSA{=&PNiu58>I1t6B8LWP|FxiF{~UXzo2aLQ;UAt z{cXMW#k%Mz*l}2xD(TCFt6;r@T<;=8ntMEBqc4*;oK?VpzDmGEy4i=> z&lXk^9eIVB>O~;W8!wPu7UOl!?$K0)S05mE{QJ~0x}MdX@)YF5%gpH+j(fRw>y=j0 z)POox-zwPqh7RL=jZfvY-Di{W1gmo@q#suq!K^puYR!@LuX^T8%6-L@dZvm&0k;;_ zY;=ieN3X=_&;#s%J8+;R<7|j*<(OP#GVz(@%nkL{N&QJAc4J_IX~*@kKX%7spg-*l z3j@E10HAFUCej)`zc)=|3NJA%z0yhPak{`>0o6hLUQKSez?fIb==!{UO3e)_L)dP z=I(S66b3<9;u9mwHErPGrd(F>jobF+j@;kv&sGhIE0D%%gW8UXw*czp&Ybt~!f1wC z^zThxH{V$P-hYj(=Qk*b3TCb*RxODR;SMFz;Dd079W@O6`?k*yBz4#8DX3p5pk?My z?|k2cTtF!kqkQgW%yvr<>J6;-_^II;u2An0>u`d_GPeF5m{4-F&Pbvb;}PyKv>ta7 zT;gGj&EFLaHJb63mrj-YzPn9D2#DU5eav?w9xAw1nMZSsp z(!N5v6%pJdnjj5)(Em5xNZxPLsXt0?NE~|gZ~mH6b^Sb1cDCmuZ9Be?duN!&dwlnLE2cIbv>jDJ=hyqQ?kwM`w2T6L zCP(pme_bmmN?~?}7Q%q=`HW~F1=-PKjWeSS>nuuw2!(f+x+ds>M}p|Ea|Y7H`s_d9 zoIKIbTtt-Tf}1GZkl5iyFZ7YV{T<*z-ojZ%qijjz4ncl{u}GsN{)S=nNwmg*$U|Q~ zSiNjqgWi9_Qh{!v%q6`{1G-3nvFL5dM04>3H*LEKUGu{`D7r`FCJD=_MdU}6|JTC` z$^B+LC1}_uHlyNHFs$a(jPzEG9~)0(o00JCqib@=~W%L_Yd!ke#P;oDF<1a>3FCN`AwoikT1l zkVD~H$R7OtP8Y>BK2Z)tpzsUweh>NTS}N_-%O-ogj?>CqkuS@viarV(z%i&tJK9Hv z?0654xPUhYYmNL5DERFqpuJ1f6M3 zydyD>PUPFHCdlPwZcMdr?8ZOAR{DoR+0~|g>>@agZGqQ;4)P6y!7+)#E5)dlMnmaJ z$A@sp2w^al{*a#0%<*|a4N{wx5!Pj&b_j#~6(!ZYa?+45|4PsG*b@VQxu{341TVF>b0@w>u|Ymc&KR}Dq2c(Ml9#?oh0Pz6 z%YSdYN&RFJRqbn=urSr z|JlMG)Z_H8SEB#Pw_oyR1}P2@Y1ub`jxm;xaQI#|W^>ds>lkt4!iS6DA{rWYYGQ1t z@m9>TCVzg6h#Q5QDjFXIk#FPc)diR|7fL@FMy^A+*#t%h~(<1F` z-f>P!zOh)HDH2@sVW#AI9Ovx%_A`S+`yBUMduqAJ;r`>ka$` zU`IbI(WX?e7G#4N@(il`4%gvgdBkoBWMwSa-G&-MJ1!-oZeY)EATJ??V~3iOY}ggi zi@p?Ko1xU`Ui{>nb$LSDuM=b1h*dA1j*Af!w8VaN@id`}(Yi&lkUQ#EZaig!C@nyQ z+iTAkHgwaw`;6_T;QU-#1$X$96|sM5x3V;-fc+`wEgoF;$_TwGQBq<8wne~hGtIa& z_*WRkg%A`E z+bldMiExsTBDyTTSr|j+la{AE6Nz@r{d{Q@x$7_3_7uF<5Lha=&ULOm&b@-&I-6Q> zc#QX1ESU0;ABz#8;jNhYlTuJc65$=}hB>XLWx>c)k=KPlikyceB{_sTZ7q-C610HRJkCP>R zf(3jD`)?#D(ry|rT7@HnWItZ&Xcet`ag$0VF%3z4H=CbBq|`YE6WdOpQpX8^3=y-9 zbL-{+rCE^ztU?M>GBc#fU?wsTh~s4j4o?DPz9|fdA4M=8;}P})jO)b59KSQeqeSk+ zb0*7n1)rTx0F3!$!WhL`HY;%ZJRA65HMNci;=)LwOVya$x5chCnjtQgw&;FO9YRu?wdMM^sP8=@DHaP%iC3WN1}5!2E`0C0X0rL&2=X^`$ni@^QCv% zrJxZjkS1HaTJj<`rEXt*i7Azc8EAnm-cIN2bL1uuBPi86<&DT1dh(_KmCNjiP*;3i zs-TRn8aAce`UkIUiMNHJB#h0YSyqFJ$<{jzEQ&wY=v+EXhtexB-=^vM5BqP+cfHfn z3B;Cy`Yhog>?inVP7hO%oTZ1@l_!ewoXZ$#xXfdu@wXMbr^@=ZFUtpN_|$jAi1o@H znemFw?-5epLG#=ycPLsGo2t8{58KctoP3L#Y4nZ%kZwW`V~NIRLq=7yZiO{JHo(pT z>l_VIOc-Wo-ANz*YChVF?3oSHpmL_Ozd2XhX6vI$y&y_ORNPhtd1F{GbEX{*XIkdt zt}5->P<(nSDm#*aG2E>RQJT&i!ff4G=M1LRKnCj;>Bo3Vm2L3nPL1yi+V;2 zT}R^gtbSK!g%Z((B9|kfFMe;>*)#tZQ_Vquoa*Cgpgu zapDbI1qKIl+27X5EnyJV9q}cWXxHWM?%5_TNND_Gk^8Ns?c}W@+I%r+a^8NfQ7>=p zQ#^jW(TIPr-^j=5To|=Gs~hC@Jo*C@Kej{}{E@|~@I+cGn_rOFP`%QaNB2wJ-F8v$(mFe@7CZ&4Z!q<4qi1@+E#A(;t6bNCc$ z`OYGmqmP_?*DCSOoe|DQB?~*g+B=J5vCf?tK1c5EqdrTJ7xwTLq>}%h@iY7Nyp@_8 zn)(LJtJ;kt&__xmuJ}bdG;H)e8;FlCVu@pp7;dvC+f?b3wGuXE(mdOUP+3X8G8o?| zp=HWTEd{6qPID`cgdYVy5l8bUQcg{m-+h*6_o?7bfzIk|aRNG9NKlEiaf{D>F|$+f z{cPcCW;R)ScNuldG@^N1LBCIMMo3TTTJihVwIUsy^h~BA44?Qglf3=V5?p>a1ODxDHRgI3L;v1)UR z(_heUf((WV@b5o@v{y2;^n+)`cONyQD$>(`GcmbFAp;vu3~ulG=!We+jaK}MC}4^M zxAci)+)K9b8%Wsb5vm=Q6A+4yr-oMAAvC7)oBynii~q5Q-&xsEEzDk7{gGnEmVp3F zucetlC09s?zB-|F2);`%hvkqnpqDPr*e6KNutE5h{$TdLBMdwlo}5d4q|#;%GTfk! zJZXT%5fM_XJ;GY)81)b7@SzqvkD9P7W7x@=_W;K`R(1R!V5+D{PGWuDjMu2BJ6h2_+B=B~m&0y+a)`|%HMG;jEB0WzA!U9!;T{v?jh!X?9s z9I&HLyXV@&cvdvKMtEI-E|zDzoZ|_riTw-5V=Lf8YpJ)?YI)a@s9i2u?OpmVK%{ow zT`!~N|0w&$;K-u3+ZYo~JaHzO*tTtUjG5TR#L2|A)3G_RZQGjIc1K^o@2y+6?$7T> z_wLi@?6aTM52{bqe%AU~Yriy9e_WT)pz-`ir>ku=6=#Ke{AmPsjX61^;ovQLq0p~l z&B1O?46#dmyXmg6mi9)d{sz;hqWAvAE$b66oOq@bLN~>HY95YEF0`T)skQVt|=$a zv}3fh7|n0WqjfEImtm>}{Vr13lN0Z}8TO#rd`1I0iYv@>#MpjgDoDSzbN}U^5mNSw z_PD9C$hj(0#f_Qti0fl$@>g4e(YOpivqE|;uAT879+G*(M_D%K= zy5~I;=gF5<*5q_BVq_D=EO2VjvGv8DJVYnQCmbG*xz3;VSM;HLex2Mn^~ZGdt7Gg}lJn?g|n`FXO$pG;Pj6^Aj}v#QO4QB4^b z>{G==9JL7Op|q-{>Xqd-26&WQ)moC5Y`UUwRC0agO`DqMT^87c677=OGOiqOfptc% zrasnMyhBTPF|(HzW%uy-COiqzT;jvpEp1TA_9{OL_&a#@gs3q1oaFMmSm=Iw4&OR> z8239RN(=^NYKB&XN(Gyto2oHr=UMmgGALMESlXhda%s#;r(oK;k-K^u-!+6FD9}~V znsr%7t&XE#(p!fOxJa_=4BW%%{K_ob!qzLS)WWRRvmBSysDxZuSjnH@FRH8z;H|3G zkz{EbWN(rjkhU+=BTA{CHTX>M{PKgczm>iEpA3)ggbY5u5n00$hqxqG1iHDKhdke8 zS(iia{jEd)t#nmgIR;Mt6sB(&Xo|y0BkcLuDUiV>UQ)ngobV|o9WOwMKr=McGNPue z)W$&ZvoCqFXLf?pyNBP)`v{e|RT$N!Q8%|b>jNZK!vX5(n24%c|={ZeObiyOlk8GcDI4Ipz` zFK7)Ji&-^zDHuCwng*G{+i}gN69KK%OUtxX)HF%#EYxupIJv4FH}OFbj>Y$?)kpoEbkl&YWig_v3WMp9T;8!%epWG_*k zs40-SEC+6$nN`O7y1V7rqWnY!&Rb|mhE99y(wl7;cv(vXxf`w zkWYQhokeOCyZnxdl%D~(Jh^B|R_)Ih**qXWd;GOo{V~s=(DjPdQ_)ntYN)xQQBtWAYcv_&&qHYcYdoZdt2iYna$Z!Q+jd zbVFL8dQt_R)3au!RiQ${FqQ;;CeszhV^3~eVOw=^$XK?0ti-o}hjrrVO--~LK|H=z z0D!f#a|vWPICk%W%QtT1J1TZXM&%%xe4fv$9YVn$-F zf+6IhY&rb^qjm7{_z#1EOQU5KP`+eFnT4D;wW-*H;sQTznA0E` zHhQUVyXkL4$R);b%MpRczWD49(TWHM@u37K#}1X&a?ksbUj+RuBEtSl|^<1x!rtc2r9vYyC?ztPt+DcaIO*LY^WLapbw=jWFt zq%7~MS{O*CrN$qcCb?IFpNUa$)FvA{!%3uON%8QL;P7tpzl%(P@Um~Lx}4K#uZHO~ zMuENF%c3Plt}saGtvtmtGN0ot#C)%Z!*-^f8V?j>_hZtg@9d7-QkvDA?SLThibK}t z_j>~PDjNJuYW^x__mkPyug%T^Dx-0 zIjxLrNjim+`!YX^n(?fULCw2aitiBm}AbtvSmVr>F7A|HaeL(_I@?bEM1 z8=K&H=;V`sooT6QV^<5SI0@DW3(TgsYy<;I$eSClz@#c z@YI3U6sJvXU#JZGO4K(CSdOsLy?=0W3txd7AquH5T5Ku^dg0!TYrldDo?e;wV_iv3 zUB(PGr~_m`c-5(ZhM}l!3?C_KbceR&0sl zyS2Pjh&85>(4})`A$40}UjWkiy*|!&<}_Yp^J~!FSapOo>0pHsEZ?+J!<)oHue@B& zU=oy5e`M|{tEcFpcWP%)QAg8V)VpO{lUNcF|3n$k6+S~f;E>WsVpxN29LWA$J6KxD zmDJ=|WFP(^OkXPTWI>LN_&+(35LB%Yqj@eoEaHJ!@qi^C@g=B1DjkLAc@4j0Hv6j~A zh>@|w@-;;3NJ+Fnht}uM1<^ah$*ek>dxojA&{j5rw_75Y6w{ zX_DCJSHV|gjuX*?R#{#sRnhqQ%_?1aJX7VnK=CB%#$=R5EV8V|#`W5!iIw4rC;mK2 zdnIeFDsihbol5k72TseSd!yf+5Aka1B7Nl>D zM4XGO1N^@I6&1Tb3f+^yAT$p%{5-{{rKQ~$B@}w(=CpQNrSbjYkR#GQC3I2IFYSUm zRiU<~I=@-i<(h0O%G0lZ|H#5|PGn%L6fs~GWDonTr$8#f@-$@$hcJEI&}kw%reP_IOVT+Ns z30&1V7_^Aw3#iYEke2`OqA;rS0W@*W4qG+REvz^-0EtHm~~>3A;2ekd|9S` z*>NYq0%%hwCNeB}r_&!;|G8~#yQY-UCk7;qS`$Vjcrulj4!nq;)e2Ka(l3#vH!K?m z0AlA0JWOu|LU+TXr;u1)a%;{`JcS`tUQX_d8NTD|->?P}RTDd&Y`V9#%YtcX{`dOG;Hn?dNEf z6nRM`oqfjRUtO1xhY6z=)%6>#RxfR|8FG|0QHCc4-U>-q^mIt3w|ok9hvS92Y)pqP zNejF=MbwE$+Lghq9$jqqS)Sh30M`I{U(-e7Sxw>xt)Gj=U8XLx-e?82&~o_i{*e;f z~ z`S;j;b}M0&Z-0Ga%sc%pa8QRj@#%K)Tup{3@-SJ3A8N>>s&G47Q*|_D*E@Z}fjYYd z1XTXU6(o;{X8a7v_amwC#*hZ4KC>& z!$v?KC3&T(R~k4m&OlZm5y$gqgZo7<0Nea6XrqHPIhPEwigb>KEoM1P3p{}Rks3` zZ*ca@l=S@Fv+wJ(+tZfx2?_9K;>YXymG`tjyVula=M$guLsa`OVp9}MapdP9W#7!6 z8E&4A;+tvoqbUp~@$B$2}; zs%$_17`zh1DlSk0z6|x9s`=M^d5|+`ELB2$X#LWQz^#?Xny*3grUiwtd|rULwTO6S z2c-@>IlC&Sr<qEG!t=gX5d6+*)JmT`o@zZ_XFe*!rXE03PP z=KONPFHG16J>=>dzpXo4G*M&z;*{SvZL;~3Z1d`#Dn&T`Yc4$Ue+@dKn@rK+arQ`Lqn$ zqqaoZF(&@$X_rWfMqJ8Uh+{Tfxuop0Q4i+taUV^CkP05e(HbCah?3Hc z^B6i79EAV(J_p~k9E>)^tco&~v=@d}6^EiVRWY@rQN=EB%~N**X~^}OHCZFFisq4n zwCZ1EC@Dlp+MTWX2IVX0mkMFP7)tW9{^uF4U<`E(iQQy!6>x6z8lqq}aMw!eRVZRDK=iwBwoH`(&R z)lG=gPukL#)K>&IN%r`PSewPBOK*x+dOQEP4}7v|zGZQR`Gq7}X5;ko8(-tcvi$ZYh!eB!iDSia zf?KsouK9E_ID3GeXPop~ctldtfQTudFfgqJ!Y7xU@B+JinBP3{*@_3bB5cY} zsPdX@0^_Z1?1I;L&QG7jhla!;sn%x^X<}3R&Gm|3ulSrF!jQ(D7^0iroftpOcYRpx zd4`e$@-i_Siuh|`W^4XqVgiT-h@Wr>X^8P-ZEq-#gpK*Yvw z8SNf&Rh(-91)N4d@aNdOOQUp_LWrw4J~nqPLPf;T?f9sxZ{W=uT5rtlsVAW;wW_d_ zFPMMSk|v@4X@ChiFf#MPCcm|(*-Gt6|ElGbKyFcs$P>wNw(jdXjN7mwFv6A6_USfB z8JXe2Ecs-lfZQHu3ZEY?+IMubB}~}xx-W=k74FFyQG}tEimKf;l*oj_Ywd^sU8^N? z3wab)H06MhyF@Se2cM3q7=-n2-KiZ-8IXf9-T9fZG+h6;jGu`mngG2J#Ry~K@X1IXdqCIcy$!1E$Rqz_B!h0mv zIEO@2Eu#-btCK`petZRv?jH zxq}Oc6u3&@j_M;i!+f*OZ=~N+=DALH5)ssj3Og zn?~ovetIweH~A!o5MnjHA6r7_?io#JtPA;Y2-kpn{>a-!b@L&osLa9n)PH?=>8 zyB_MmB{%IKMD?>=kxYzvhLyK`?PXrJoPMxK99$0855Cdzv2;kgZ5 zQM@j>AFZtgvMv*(0)+)u^(b50%=KB{h$KOM9F|Pwu1ycFo}>4mY-USo^+V4+wr7qa zotr@C&h+Z0xcHg1>a5hLu9obHU~Tq<9WL;RRTtgrNjWp#cfd|8@NLSarg9L&H_L%M z0pi0-ss|?`WDS}jUdeXTnioo_uJzc^hE-#GYx#(RuWoZTHZAc){d&74U_LCa`l~byup;w8={61oF7SajM;a; z25BbU@EBi}sr`P~KEwzg7x^T!a9Wx6y`e|HB` z>)jTY_;5<-_Kv!pPW+6kA%AIO8S5U|zv-OQNZ9V(&FS6uI~rUjwi&ieKK*U0CnS#h zjFi|9mahkpmJd)e?>q|sC$J7mt)AXDe=Q_h#r_p=(X@K(~Pi*99g0rx-RS_CY3 zVv@$W$U)~&MWwJKM4$m#Hl~YbSp+G9}zWV!oMG*1=rnxI&N@k9g^l-W>n0iEm$=FLxkz3WyKQkyvA^{Gp%aRq5R z5icF94ZM}lR}6NP&6nUeq)p{S2n(%?2n~yTb_DuX2MTVAqt4BI}}RN~vk|1L1n9*Z{C zP2q_jnrp zomlb{X_kxCbF?MRm#<)&45T619disH9&=)^EuOmPl6E-0xOZ!a`%!JHhucwv?6#b^ zX(hQWdQU4!LgvX+a7ErWd`$B7ox3|`kma4aV457%9`o3Xv^XQ!j5B-@xH%Un?jAi{ z9VV2f$+UE`P2Ci$Hl1g#Hef$xk0$Bj{NbJU{L;aNH9ProcLWJUnLU0E3?#N=%FKqp zNJYr$RA|S<%*#gH8e-c8J(U_RO1a#9JYer`vr$xkre|YbDy_VGL_JqbMVzf$8iB}X zUn<1tm|KA7qDkFIF0=xf(I=S8+mxHMurRSt9q_D4p!5R=3#1 z07p|Re0__lmfN=?ml5aB+S>c?X=Nu8$nH{ zn~cwx(qwmAo?wz18_nXP{_@}JQ`nEJeTvamgEU4J)x#f54`4=s!7jq(fLjNIlKdbK zUrHTCp;q~cSyNuv^p9sc;lfvECCbGkn$drIuNCdkA3e2OdJaU2oX)CQZtC5{j%|KG zH&w*I{PUbHaBaqYJ$Z?=yNi!vlKqA&zfeMHsJswbDL|d!s~vjBXJ?PZC#9>&Y_!rk za>s35=^Ikl<#*~vll1Lb=>KVV{zr*vSSH*@60D4F2lIcF(f>C}Og6t<)fALAn7?+u zYRV6OcaWC1lqix#$5mHH6e*fB&`kU-jT}R?s`&Huj4u(TB3M;I_KoFkYa%n1+@a}2 zayjHzR8j&;mlFa-uHOFFEN}85h7Db*Q-tafwE=m!42Bl|+y}tv&hzQvvfLPA7QlSb z13Gm<>;Aw_Gh1PD|L$Ieh-CszDh+|re&_HJ6`5xYrnT8}=cNaIo9%i^ZQPXM?K^9L zUqjcPuxD9?Dxue~S8O2Z&k(9VI0D~rC2xmw6lqPfHkJmvCySMVI8cuLkcfTn)nNk9 zZ7b5gAQFH6D+C(ND`MOlD+6vs)gc?*o|Q+pVp&*oPP$jGjuwBtdQz;NtzW5blX6Fb zCdW`(Oa59=VqKeGG|H161SH1y)>|lC>kF3#BPd-`G)g7H|5-}NFh|Q*Zv9+>O3Xnh5mm!5e2X4O`)zLyJ!#Ae?wH2U1VzIh=6EZ4Y(gkVMy}uZs<<4Gg=Ys?L7v zx0#%B3nf>@X!c+$hP~&KP>C@8d4^2=w<3JYs%#CcSJo;BSV8Y5pVYAXO`|B!C#iv> z|ASq3Xy1`%_@HtE*UC@boK^H@j-NcC8VX?wH)@m!UEjTz(!*_ zt3MQeBjL5Z3Ek@3rQUwL^M+ORlhT$mWm}dV1ROW1Wo?-EWE!GYfQ)JLNOtB0I(QU3 zC;@h&*J2OCtmK0yG~%q}Y=y^^*l`m3rKN0}KNMnHIuT`A zPCemSHCf8q+WwF+7#$tmH`Cm6wCq=T?rXjFZiHW&l$=~d`|Lnls`F(uMEt~`y^9QPzSb-m=z>b{nKSjd4VJyAlR;H376U2@lk{r% zaGsB^%s%t3>U7dU@~u0sqj|8euI846PkU=ie!!J!ktDvsobrbkoZ`tJEPpBu#fYf@ z^&jO3@!d)7uM+$6?4i#zZR)YMe*dlf?yi%&|IjlPYwSRJxcJG=@%I-5K0WfW{iw>x zw4qQ=2z1R}Ui`4cfldt`Nd6KY3mK1E}0dOY)%R+KN$ z|2$xJ$}2O%21)D-PS<=ALs8aMZXKkmiCw}*!|S>eoZ*9P*zWf;oS$u%G%TXLr&tXu zaXbIDvO0fo!>`fhn4#D-S$cr@>MmmT_(8@$50*p4A0%#y0v=d8RfAHk6P|j_hhjP& zZXhj^{O^5i>V*CZcGdm@rYX4{RmIA123~)^Zx{+GfO}M+3MUbThEokH{SZsgVSQg0 zQ1c6wr^cU!Yy&s$G#eB^yF46uz{^BPEm7;QeQ3ma?XsirX$Xnwj8h2;2&yvVKPH@# z9Zz5``_6k#5(4>uHkI>_EivKfe!A5?Gz2vHT6PvEMpnJb>vrqf2wa(r69hKl>(+Q+ z)9FKr=y|9(nImiE7P9idRuEfs9_rbQKH!S9kA0L)(N!%^L^vW-huFR+?N0@uyo^Gg z;~RVrhK$VFV>L+A@>6fQ1v5bJ2fcwv_NA-xzL<9OobPDqpjE>x8B(_CS^oTqGz+g= za}m~6g>{#8dfqDG&^8(1`?6T^oZkJ*%qhUQT3GK&xKD$*_u73lOhNV0 zK@v=rMACXj)zGtZJ%~0l@t1KF-p689)fY!31?Kw?74Lpv!V^e8LYZ@doT4vT-fWO*zZR651L_5*=+pU~_< zg71^TbVUtgyE9o09m?EVn6%Y|nrdo*0)WOu2vX6+!dm%)ysf+=wL12rrUrH@$o7vx z<42M~qfeXl3p$@MZKSnzs3k@6pd5Ispp~fuKvP$dq*rwg8K7RYQ?zv4R#*3PlDUep zusZoq(d{YH51nkb91>(p#nU2MSV|A$1!_=kZZ+7AXLDkr5%tct!^CIDjuqHmM`8Mv3uv< zB4+q`92!^vuE|BdS-}o*04&YE=f^;vtXPMmlJ-ZbPZtzTC-igE7Mj*P4$ie&ACjS& z43>$z&nqK?oWf7@WqS!skiw`ld-3#NoPGyy%n$HifH?yX2(^4cvNshkpOS{ZH~}x! zQy~Sz1O&gf_{ErSpaupsg8Edydfnj3Qazr2Jsm(Gisxub@4^t=?MTgaPW*R`b}vd; zytiY?&mS2okfFQ*HEgCk8+DmHq2VZQn{!XaDKRV%e3+&fOH^ns>LU(oR4j!mHi_1XA}g@zPF!GVT@^Pura?G4+%;{zY75RYq!M`C!huc z@ATh_Q&m|96-KQ5yKJ7LfE7QX?NlVo9DfKxo>Xii^&GNeMg8P{#<_IlfJgVtBy!dD zU#1W94LHl_lV`&q?R3FM#1!iJVHP0iJQXwW$9%W(8q<7qnj-p5__7Pk3C1y$iQG?w zIC7CF2uMUDSn4=ZMgJ3w-w)G0{n{AM_cahnax#$gkcYd^`9+jE>* zy49P}tS9}kAJG^Dg$UZz^*3dX?f_W0AqUdl7rBfmSPhWa%B7-Y;q0SDjy{M3FVnu5 zYG!_MCL6t#t|Lpxdd*MI!j;jGOt>Q-RsNxkEu$fofGe565x);bUsYv6ww=HJi<**g z);n?-BAr|Jj$w32JpAx=T|2FG(HnQNM?CmYHv(HBtKuaErAIvdP}d+LTy?V92$GVP zV_TM85w;2+vm(KoBzCapjcy4i&9w&M5oNHcUo6W09g%d+Scllvk$qrROq<{_Kv6Z} zYF5N?A=F#f@rNp?b|mYcm)@gTx_u^>Vsh8(1UJ1824SW`pcuRf^i5ZDHy-fBmVNnP&bfyj8P!+uov}7;ihYofJqmPvV1c;*$PxPhD7V3c6FvBXTkUMfS#_ zj@&Q9#xcg7*jJDWfJG&`@#pGIKqc^``i%449mpqE>4G5iLfp}Ndm&-ZV0n_^d*1Yq z&CJqbjw*@W7-9!DIT|0ooVmFn#uh8lmZ57VTzMQNZicAe$ye#0Wa+ z#Aujx47JOF2?zN=pvuk|_#yRtN8~+bnL$C7o6)}d^3OsFvh9@oZ{RV8>vH7!&WmBb zi4R3CjA-XWI|K!~?5rWgKGlNKCzSG+JV;NuV~vxbxqD>c)gaaf8Gk1P(-T*Js35pA zE(lsuc5y$b85hz1do+kiGIr7B#9Sc4!SN;}0299|7P=v9MynHQ=8Guiy{GUQ!odj| zgcYev@dtixbkNjXH+)05azHi$kq2AeDCn!OE`q|MImDXeF`*AlE>V!#aWnLqm_>0H z=8SW8k3n%4+&2cuz}P2?4O zMQ>A|hGhrN9C+g8Y6s!p(?KL-w&`rcm1fL5fZ+Xc(Az{}&;H1nh1)I7LsXGB$mBqk z2FwtFRD}r;H;cAWEHLxD9#SD}DP3|tFmoA#h!@&jf*;B6m3-L2fQT25AlJl>9pCYV zy$}V8>|q;XXS(m-{ZTR2^0=UQ#Vt~|>IoW1@{S&6{bMjZMVR0UJ$`t~7($N79b><9 z3L^#?EapHai63*kLks(g+8+-?7Jc=UyV?&0FA*b%rOcW44r&EEsI!I%5{vXc&zC$G zN)-Nq3Q~dUzP5{GhF&!1v>TF^>b`XgoiU^Wk!UUyN=F<_bFL>$hu}kgnCcpY8u?Nl zFoR~)ww#jK*@v*nbSs^qW0&IVJndGwckRXdudYI~{^4L3n5GI|2$v9R$Z$d^;?t zHED}N6=<+~2=`=#GZCXXn;_OiEh=wlb8Ul$2)3ctM5uo@oTFSw9m^X-<9CkpmXee@Yb(N|gyVnGxpUdt{{1E?g0QqleK@9fiHZ2mLe<8eXjh+CB1e9OfSN+Ixq1c%!kcqVk-qNF?t_*b!x zuJ-3dZyOkaYe-k_WWfV_ClwDD3YW(i2DNE{-I@?47M&}hp4+ivv zuLcIxHjMx+OLd>?2%T#qsvBhvaqtyXa)X!)ktc;>?*}$377rTipoYmbWDA@;s_0;_ zg9L0hkii+`wr46FiEzQ*1>f*z##yo*a>h5vjbIOw?lYol$R473C6=~qz6w8 zoT(YY0hc#lE(4e(Or=yh`!_dQgX(|Ds`V?J4f;uYnM9w>oDE`NHL6Tr7+Ki3b&0NA z2&eWDE~*dVj5Wqvz`$@}#Rb_m|Mz$=@~)Q~f%(O)uo~G?Q|p`GD8Ffvjt8Ni6UiC# zXF{L7MDBwyJZ}0nA~gdIdUraBa$ATtr*Sk#m&^D`)^7j7Vaa9(BXtxM?_1HlU{O2; z!Z2moBy6kvIq5BivGtmba*tY&v67>}S#c3&C8Q_?m`*F~TH202FS^~l;dSuZ30k1ya&mcoxi=TZXIrF>9vx?lEA6MoXL z$c)^ZyKm#UP~rcRp3EZ^}g%nK~{l_ zodeU6eQ6+{loEHUb7q3yKZ7Z^qCm|l#slv^ye%w?0y^;H;YwsL-0%eIQxb;+_5ZdHG}T5+K`R?ObQ%rxDR=7ol#mJjMPv zu7_2-f+%|uK^ak{9<=|9V=&f!*9wI_Z#g@0>%CMJougB}RA-$ZBJ`6UJ za?B-&-o}pE<=M2z+B~H0Y9WXYH76W&cU3FsQR%24c&OQn*;Q&&5jx&?#~|>vs>zGl zz3ge?=h7)$is7L)+$AkB75tFRJ%~oVwV^Q#xTPZ6HK&)WID~% z`2R$86Hx>V!GW>TN}Duk>DWv8!mv5uoe)GuG=yju4ylivP_{7Yz7$rn3$ zP7YOY`bNPZJeMrz?ZaG1I(nF3l5`I-YQl&YjuG_|T)fX9$0mXY ztGn}eQ5`gv|KoLKvb2E&^;MzBkY1K8XiibxDoCuLEQm!}c6WE=m4}w%X_5VnDp^M> z2@av?kTh~SP%OJ_VJlyqHfc_U1|~GFY@t8DL6}+rR(sqUBqj6sB6-sv#*r@R?^j!d)_?qR6yAMt!|)Tmh2PdK>OV$?`!;b52>$>S##4k!Tgcl z)MNecHjoI~`$ze2A-+wZ8a6bna*ERXs4|y0ng?{*=Dazo;yF#XqAFEOT-u#x^%Mv3 zq(`|TCS^W=PijS5ZTiV9IbQDj?RFLXA7PO7cbO$m;C#5d+V0){v5@h96 zEKAA;c7vdlJ&6S~Mz!xy7e2QZ%)j?DDG8srs`uG15Q<4Ao};Vdo6*+BI|wf?>3pd(jhc5!8Cc6zU2v( zoD^wLGCs7#-I#`BfTG?^( zv$Xa|sT)xk9aVP{j2`sSP*L0b5xKkhhVk8Wb9AaMO7FyuZ}K!d%SkvCUxJx{cJ~YR zkyH` z8>~$BNvYikxtae4QKqEkPvDO1bX5P$Hfq9c##y;wj+3T8B59iFY&>j;wwc`Xm-qdg zAWHc@lAXZ z^I+K7cady}--BNO!~qnZQS#J9rKLE`_yHye2?gpj+2~rbR1A1PO~0JE65l%xXpX97 zBa8=~0t`*%{HN%+V;@{X2X;$nI2{vo+hh_yhU$mbc;%dS>RC-}z6e1-nABH(xjA21 z5c}WvhcZb9!V>now5g0QSGw3yMGjdedN7JKt$kDR+7jynsDH*+UK*X*jW4L~@3KW|bk_7*E%o#=i!1~E;Nqt%2W(6H(gU6b z9(aX$>XP>}5$7B$r?6tL;^3`{%vP`zdd~yN_2FZ)r99`M)Zz}t+mt`pcg=G+h?T>Ngq}ql%1% z@3^=8pSZV#uSgzqaGx*y6n@{QAHXj;zwb(Wh9hj(_d+@5Q-&kX^CZ*8G3;5nfNYti zcy=tbp>C{>6v<}aJ0`IO@tY{0{NIPC-w4isWpcTddWiJ__vWguwcGD`VC$`Nv-A^f z`Zg~{|9(5KF{k_JEba9bbHfbuk$RLNJ7hitmbgd#n)rIeogo3_2{H@Q_NA7a9>8Nj z!k3s1c|lfVBQ>R87?`DtLEKF<`8|JO3eXzwn~!PN<>EM4QWL90?|E@!)nPv%5g#|k z`CStp{snc)MCeqF-8Ri4YOnm^hACU{A(Jgn7X=r11mi~RQ~sMf-VrJjl{FS?WTq-z zC_*irDmJvfb>tk}88D8{!{2u5^@R?p6>2!cDSYo+3~qOK)K8{FE@P)0Fr{QB+dB>j zg1~Onf$qKBh0d-@$hJPU=bEMs|7!uPAmDkg)#Ksk3!!c~F!c|n`vjhd%*M{G za^ZRkLwve)F{%{~S=T=*3NC+CJU>c5fr`wuy!5HDR%G;_-yZx}*&mNeOOfr#X!{>l zc|Q46@Q8_$yN}q>lZkjfsZ@BfD)L#o!b_u;aSuMO#7(_j)UzjS$!P75K9Wo6^Od&0 zVJG`LtAi>^VeZEzKZ~>vl!kw7<0J~Z$bYc4g{Kh`Po7=!){09|h6^%%E8tJ7Tt??I zpc&L#_2(>!*o1RMX+usm_&pS=gFjxy={0ktRy=7WAh5@@5)?OR;NeX}e@T|?V~w0i zr7-GVonU6X`9naTf?SW{s7031CArc)dBZf3{;zb?`i~`!>-K67Uzg+tLi1$$dTB+1 zqZF!TfK#?Y-3D3Np2x(&XF8-py9c4dce(+r-GxjNf+L*rZ5gLq;)0UMiWC>e#XrL^ zr((rG#=RHI-*wq`PtNDRxr8R=GFiP5%2q6a0@-dlsn$kE6UY9Md(y-*ZhdtA2p(VT zMz$)Q9w~|h(PEovIofSH#)$ju4_hZ`sp{6kJ7&Tw9m%YLBY!cqkHi@r$Z&b%BeO;Z z-BkIH8(+-4$3o?|B1ie9LoiQ3y&8CE$R4tegNp>wDeVgl;?z)rEPeSvBOEd2O*qJs z=yvV+`9Z2OM81A&w?7pBYcgkB3E=K94b4@jfj!zJuz})GvMaf4iSXB1N-7i)BxPC3N2o5qp)bS7x;M-yHzJ3fDNXQ7M2QsN2U=98LU-4}r=E``qFN z`^v5FPUT3Pwo9&@QNM5PHQ0AqOD2&Un7YaWA=KssoTLZ%!@*}KKzZ2|$$3On!a!Zmqc-14pgRXZQyu7=C!bWJ^(&{j2=7B6@D+l7?R zsqGhibQSecYukt~KKLpNdLLxI@+zY?i5bNS8bZZszF7pL6$v?OSecA239_ghW$Cn* z3@!=U7LGq^WDTs<)Q_jaB$D42ibpzCt(OwLo($Rj>cT28Oi4Wgc|*C{g34yGso$W1 zVtA^p$P5Csl_O>MX7lO+vXYh4`%50!-&0wAor6?I!}2UQX4LLm=@R59$Xln5TE|YD zeSf6N8XR2S{{ls+ZSz>D0d8ABU8;2IGSM1LPTaH&E5@|t`>Kf<jMeAoQgHeMe-RS|xnkG2w21VU$atz9&{gfOs#*Zvi&07g3C24lp zrTY?;*o&kkoK^X>TmnW~6sh8(e}9zI6g!B~NxK*pHmcu}utdSx;6d%c<2WQ()RgC@lYqkQMw1Vz~<_<&}3V@5ib~9VYXbG^qrr zCXAUgETvdW|Mr6bWTl`N{vtltqg% zQ5y}FKYf$Z>c|=jsWY&st)62eUjp3zN^JYLQ<{?XX8y(I7mad}m&6zK;%q0h2?2U$ zW#iiSbd_%H4J+AunBDL>Ch&!(_{D)uO@+eV z+6YzqQ*PBk0n#3{t)f2l6+l0Lx`&E2qN#W4V2kWk-n5xcBc<1Yt(R7ij)i8m zuA2g~%x09I1xxiDi4?!)XsW_AQ&`LbtbjM`3tEm$Yw}Y?5r48Ex_&z5Y;tSm$(Rc% zlX1f#QOtI+GS~bQRPwoWmsbN_EE9lqwNe>uk=6rNn0kjWMRKO-^kn;Y$N2J!`>-&3 z+H@1QF*5Aa7_)E*qI66PdDjK``U0HR7v{y?K-uZAXJ&FL*oZ3`j;=p>-NElemiJiTIr5%2Gwk;-`fP(PrUC6&Q=8F5hAmlle!#`K*F(a~1uZ zn{bsbD2_sI9Uwpk?%7~aS34Q$IOW|)pwH7hnTnsO*!PtacT7cRIkDN|5!2;|NFgmD`DCFyGxa}x!rA>G0#>F%BqqeHr6!i16H$N^)! z^Y{PXSNHvW!v@cnv(xA7Jm-9lTu;o~YQpoW3qd_dsylQBE;4Kpd2yucTYuqgQ3^*I zx|CMkQ7XLSIU}kffJ{^VG*@40uFELXQn$EckN371IMrA4U&I+X*K7|3@-8|*@Z{j@ zX}cm%oJ)LZXehe+#h1InzRx1^6s3POv@_w$yjzoUXTddZ(r21zuN+blm$_=$zwBCR zPHhx7-AL_Z*CX&1toW9~smfgl_9y7}&nHG|W*!ncTh>K*-o+*2U7tL8|Dvor%)lx` zQ)(ZaoVAj>=v4`)dUJmBf1l@Ym!SV%FAGJ&6P-PZ^mqe_Kju}=f9aG7>=|sg)?Oy% zY%!<)eNES9gl@vj`R5rEu-$)EE^sr?=?F7zCRIZ-rYI`9&{5Rgs6#Lg=Zhvo#IiF2kvKmajb3>r2x|yqr-9XR8h(W_FMWNOC?cDp} z7@eO5*S!^eT^jg$n)JTb+xjhiNlJ1~t((LZQBHt!SetjK`Xhf>W=cl?tRa+bNnyJZr<{RO9y2I!{kqGp=$v9FJ%*a z@*O*SfZiQ>QU?_;Gmf@6EJ(L#;|C7(qvLA9w(*xsGYRN$SiwoM^C1c&-xeZk9Be6e zv0ZS@(>P6R^0HY6);gRVs*>jPDu5ZcyKf>IGE@Y}bzE(UTk%T|vdUOA3MHf6D zR0Ce2zQ3&DBN22jn}~%5wMz!jH7TsiaL($VG)t48HJ%g)@%HBGca|wt0}osd3|E)e zkj$%xF6Z7|M!_usyPeysx93%WQ=Me;Xz_rllHhT3Utq}S&8jvQSYmMv=1G82&UT<< zo5-_B-YT=^d*#OsZ|rqabD@~Nz&RnYPdncT)@vwvvV`LRNx{qOFX92#-;#*i-BdhB zrv^2up6Cw%;GeLu59A2TdP6m0P<&!R_DA%p(q!I)+$VPnD9H*#-^}i{eNX!P+j{ZQ zR;a0kM=h5UlUV<|JjvqLdMc|HX%TwC8s6FA9Ys!?5RbKR>wpjk!*|jx#l-=b*5O|` z>$`V&T;q9!suP#mOm%fVT3hWcbzhx#7SylDs8y9Vcb0R>cT{VX<{HwN>gZBe^EEr% zn0EU1Hd~TX-%h~OkxAd&!d#EivXW*a$0Gbdl>eTa(`~w>m~*X{HW%)?LWc~bYgK*I z)+@Azsj0JygzxD>X&Hs7hSpj80!hjZ`BA1m<+ata#`+&TE9^0uo2FGRJuamIy21v$ z?on*f_onRWi~Fb=iM!N{P0B5wn21|-zM>Lyjd&PW-oBXnobqVsyUYx^bMNZ?z@|X9 zyCJ1d0{k*1C5>NG-iz^fbM+pX3|KYx2+^DkaXway(ycW}Gd4Bp2mm@~RPoAN8tYS% z--GQcHqm%1e%Awa-*@+_6*V?zqv}x8^)*HqJk9DVsH_jrs=CuZR$bm` z&|Q8H`l(2YJvpz$&@e?$ZoI1B-36$rGCwLHKy&cqOGjR7y&+3C1Rm7MTpO>sHKX zF!mCoUfS93)(jbC(a*VMi}$E?n^GJ4XLwLYAM<6_yga}nY1E_@Q7ZQQwbc?vqwW0k zX{40myljqM0Sk9(Gj=OzZ@GQzjZp5F@cw00Ys_dx$(t&6Z}TYjqX(Ft?B-*pFFGa? z9j#OaPIHEF(5>svkSdQNrKm7Q3m)L~Qn9~;Tv^_biR9GOo;!7>uOZCBfXysW@=NDV z`C6f*vs*-|pwlUH26}r`QR~ITc%oxkgzZ91uQ2$pJ#FR<_K%cM^|69_;#Q_owQN00 z{icMRcJ?s`No#toTWw7}^5l?=!zSxjU+;%IycVe9B~n#g@FlDF=CnOBchFYCauNnN zua`!Ig{Bz~nze7yOIsOy6aUuPpkg(y!izt3Y~+`)r;{Z?I2SR}m=?crz3I-imGref zQH^io*u5quq)=QiS?PxYk7(4W^axKREUFT$Bo_ILA#&AFp=E(d#@2jzm5-L&@d#$m zt4L8$EJg_${9y4=dX#GGq>eO4a5+fL(pNHLv&j)lI2 z>ZsaG0q3v0DmSMaJfAog?0j`O@}0pn=6tfy*I!ooOZ?BNyy{fKbwB4Q`cdufl$qI?Tk0H2edck> zgZJZ)T4Z>lUk>$t%uTgSkI*&x(sJAX}qGe`FlPjlfd+M%;w9Eb9 zrTJNAB^;gOF_n&Ew=?dO`>+JEKXxN?+x+fJwpn*9x>7=`r;w|W#HJHjCYl~<%nAEkY}BIv*1B&OnIygn-EZRW8m3&A}8pM%!FTC zR#lJf{rU>tvrKxvB1Z~=qRr7k^ZeqEq@VRo^FtRa#&;6|r3nHVF|^_Do)^-Z3Y)G$ zX15C?9c+$go2Hu-t0lXo&CPj`4Dp(6&m=1{Bs3>xaagprLak(3`KLg)>J{mz`{eTo z-!JRMHld?xdbRvYu||{NF}pNbO$&_5aaG}W^9kiR$?Up}Be-RQ;5D?|bEU8pPs|W8MJ84-51~i$zHmBlO%yzY& zP!?M#Z}rkqzrO5DQNc_y>$X5zc|YixM_@uc+enI)!7XN@>@%ypwl1SF_Jx5xRHpuY zwwY^YdQL$uUp3#%S2FL)nfhqms1ClJ4-`!5-pIo!u9&V=EhbfHHmP z#Qm=7(d!By^u3-F6SnZ^W-{|7d863w&QI3yEql|3hH2$<-)&@oLJ%f+b-e)m*N&zj zQ(wQl5BSm{;zTXoO4dwplIgY78{dpOM&81zMgqlSd|4IDehFmfm5&r+zn48f)mY;X zXZK=h+WS5HGrK%+j%{B)P{VP)-m$3P*2?lzmXlP8&Dd+tx3^z2cJ+FsX8$BD(9_cw zk#jb&T$HQ(!T2q2cogSMi`Xu726KF&L0>n7>^1^N5|vL)ix1 zbSz%yAHQqmCgmmL9nGh3R8*PSVR zH(0;ou4yUz3#-tK2KC>UX~~)@tv}hj^Q-RC(9o1Q0Ksbx9V!N~rkF7jq`Ff_(_E92 zbp3<8xwB@`m|s+^rM|B{>GmF0YZ*!R7H$^|qkY@Z)rOKL1>&~7_*O)t2CJic~ z#jM`3z#G?#4fXBQ7n*Up3#+uKwT~t*4@2H*ys1c;t)n*mYPIE-D%zY1YB8jG3VpLN z=7yI-Ks|B`mBF0cEC|vMBlmS$7n0|P;j){RueWm#d|`vhe22d!rD#naZ@^*hQRw5a zxRJQd*RL4m3(d}jVgbv%8|w?tDvoF0IW_YB?F(!2c}r=|T!qV+3<(s^oDXq-RKofG z{KTB$;)N>w8zjf85xnVHz za;&!3eVBv(Wteai)x_f%it*~~o9W69h74b0ohGVD1#6=*GYNiX8 z-cF^jA=S6>qnytuW6RjmU+WWjrh!Z0F(&5=k}tfH!s8CR0Ro>fGRH%nGHTXAIpUp* zycZLf2{`_|Y=o?i%+4pSlegKceMfR1x!P8Cio{l6?uWQ(9*D$Q?ArbM%fyE*Z>Dp32$zcE4IZphJXO}vD$K=pkDJcitPUkj`KbZZx z3GCSd`H}u1XbNt?^3bMV#d3Eo(Rz4CrIw9>Lo=Ba0!8{E34aWF}`)#Ge=EsL$D<$cB4{v*t1 z@+wSPQlm*A1wuLU4Gr@YM`M|bv1J2=Hn=61ADG?@*`J1)ituUBc)%Zc@&VRADwj=1 zi~CIoMaZx5>A>!ykI9XNMz|OPD?aCmL|TCdr(f9J`jDWuAu9r1aRur zt8Q;H`OyNuL`OrX50sVvK?*8*i*UA&vu$FoHbo>IM2oR@>h(ivVk?l>~oR!>XpdUI4Y?N3n4JzzTo`08TMr^JIBd;{fA3Hpc;dN=_ApR%sU0tk07 z8&ISwE&@tO2mn`{m-HcfutL#je;g|pm=OhG!#fbsQ2b2<8HwUH*aKH_wM+H+)Oqg9ou?}H<*13h{K1NfBfTc0|0Fde5ce=YH*S10Z#}n*$ zDugy0o&^C@$2CD=%D4)s5C^!W*Wf^;rkMkhs&d>!im&oo6Y^bSd=H{=eBAU#PpAvq z5{u^(#AOTOxb3YJCZ6{f=BOTm84g{Gv!4?W_P~RB&NW$_F8y2o>YkltpJ|t6YvsHF zdaX$LoqyhncTc?fKGt1)@W*9+H!t}o^(nG7wlF&Q3E^8aKVdx%8IYC*;$o%%1Pu1| zK9;|a=-mz&MD#w)XQzp9{G>BR|MauT`qM*)C@6s4>C<2q+o5AjXJ-AQL?e3|88Ky1 z{okW0&{_$dP0D7`uQWFA@Gn)=&+LTRbS>X`y5qb2UaHv+xwb*box zfPe2F52d|gq0JQp-9k?HNX>KjaT#M@!~%!ahTaH~!Q6iwc&-JTV0A}72eqr`MjUwj z5UTxKVuGb|R3%q7>DF6yRV zq4+yzVIgENo3+>s=BBBdw{`j+YhnU8S4UL~n0xKtIcY1qH4;;7a0YWfXpai!K?@w| zf%ol|Vous4SnYp6VA~Zm)A3NFc&QjMR&j24gN~o632}KKaVvTO;JzkjhMg9`J&etf zCj%i0JaZt`b$|B-aE^2kmijF-)KNynMDtcf`j@v?VVl!4d#91@TWC`(8|{@>am~e% z8lnR1%ZV}!RSHLfS1gP8`62Gs1N{*L?0!SB~@ zf=#3aho4`25DcO)KCVJ<^{+YF3+4{^nS10Ob8%$OIPl6b~2cPT=zL&8f!D6{YtD%!0ef?+KCDBq7giiV_NW@r9Ph=GN-;p14A#%J=x1eEqzi2-wPxLiz4 zBAyg6uM5%9=G4VG*>fjil!gd@ppe%J)$y26Q#JW;%x)oAo;BdgV=#V{A)x7TK$iGXVCE~9~7o?MX*4$ zlzj zAOVGc#+5nYKF-9~*x+6>%=?RUKR7?4K+I2(LikW*rJ?@9z{EXx9~Lw7*;5Q}Dhmni z!wL-&Y5)YPMNkj6Ylp3<&JP&9K9_{CJSnwCz!W!5?Q!1a1mSM6xL7tQNDCk5&}n+M zy4C~whCOfwgFj)ewnNUCP;xpLFlicmpwD+R_<2 z!k-(=j3Pk0mWblT+p9Cjuuf$l zBN4FdEP)+y_87DafPdK>+NB4DAy7GAO7IO4m}F-hE*9hF!V-{(iR2+a5C)TCV4~eo z>wgtc$YT8DAoh{0XY=vWdCQX-SrN;9w= z2%Y#EB;bG(-7(q)5cuP280l+H-Tv6%77hNqM)>FZK|W(#EiM^Q>e0k}zUkAA|Aev9 z1A!1&b?2W8m6}}L z^sfNVy-87!VtkMQDm?+_FG`$k^g@lm?oPPpI}}c5in@%rj>9vcmLX56rJ8B z;$jcS>pCw9g=zV2e~%}v;M?DZKKS{Sd@;|oP0vLgjw}%^h4{bHC(wjoZ3@F+}`OK#=_)@*13E&^t4QddA-CSL6V zYKA*vG4nqH0>d$`5HL4Nn*(C$fNK*+g1=$A#KCY|oPIcDcl9OX`nkrNDZ{19Ha6ghaYY;s*Qyp!9K7LNAul`RAb+iqB>BxUv3dqLi**7#~vZDTS!X zdnffCvlHBI12ww*5eS83UJzuU6M0}-d)(MecN4MxT}-GUK-&8Ow^0+137$5c?N+~m z2*S&K>@5`ND^`92tI9*}DbgLa3Dc%$Rl*Q*F=o#4lA>U_6LebDe&>Z{B{fRD)at}0 zMBv<8mRLW6zZE;yOp1^9(e3l|cFJ?pmN}=1~ z?$9YK1RTJMJteOZ0pG%q&_k{_%}YVyUoOxh2!hHxw=`?CnGVQ(0z2RW-tET%4Ul0_ zVV46oGoKRNwd_MuyS;CbZfFQXTn1P|w zgDi|=kDiX#yoHo@ABX@Whp#?hgeZYM*oYaBop#+3dJ^l}i@hv^`8W{|hqt&uJyrZv zgz-;vkQ4Se-x-*rFqmr$=1otKZZaZvJGv0FF|33Efe%19)Y*1}> z`7q4Y;J5(-sd!Zzj+xgd{2L*_O&d^9>}K5qs1>ntav_i}{QfxLT*N2j$FVsE$e&Q7 zv-s}sShH6I4n&EL9J6ERg@UU&qZ}NDuwX<~gj$18v%tUCi0^*oLu(#iQqzOJV0oZ~ zPY5FsRJN|%r+*o4hxCzyJXi!wV5Q1n#Kt<}(i!p%o7*UOk%DoBSxnR(?ci(Eps?aU z6gDB=StLPXmRI9~A2AA`Xgu4Q`@@3IZ>=5EMmVFDX>bW4U+{ym0@K z3>|S=LJShugO!?PY}yK=!r?PnGAXY<({>Y^G$pJbOWhY=_jeAqKqq{a{S+@oPhi9} z06@uKa!|JLtnG@+4O+3)LQ6p3`dhliw%l!WGJZ@0!nX~wU8{oUUeQe(ot=k%3plx) zgwaD7Fc;6{YH~@Y;xIdBRb@9h@OB|H0Wv>(?7Cj-c6}0)Yj_2p>@kA~gaD_FCMb=E z15V^t+ypjac12C4R{M@;L*ul?KrLmV*BsGovIp?KV{hl&m679Q=hfATh3*%-sM&+SUfRnoc)O=> zSwzb?W4bVecL+9;0iqs)$q95e!9d@R)n5^45EVu~%+{Up*g~ig2FhrUHk-yx4)ql7 z?woC3W#ZrZ=8O|#7CcQ~1D*iJF6y2&2s&K!7eRQ4pRiJ6<2RR(6Pek4k#i{~=yxhC zmpwG@q+u1;!Af8AM^1ixuT#TM_I~qj1+xFlu`|nQie!1e^wO4FG}M={-UcOSoFK<7H17=*uU5T z59kw6sV;TDIE zeRsHt0|nR@1VX_$@$^Tk3J2_dQ5Nvq=gAY;)xHUb&h{EG8;Y9>k{UsGHlg1pB^K%n zLQX@iv~iJ8NH~_Guj2IZhi@2grn)AV?1x*ag;iC}9Z}*2!8go9d!^`?qxD;Mkbvk5 zrG!OYR7=+O+1C>r=4m68|Ltj{(uG?lm^^j)8?maD%^zM&o#42NYr5f`vD-$ICrh-& z1lB3!@G+c|;4gdy_POfF-mZBf7o3ULEF#cO8_lrGl=7b z_bf;Jr^OSwDPR9R;ST(Z9ZymXt5DCx!DE;KJoep>gMMPkrxWwCiuIUf$>2}w$~xMQhnpWG z9Zp%FT(XLRK^QBMZr%NlBA0DD61%+|@>&me+7wDeEEP!DyjvS`M0)p6^w2pC{GHN5 z(^vs}Kd$7Qwo3C8I>(FHm&9S5F^WKflA?m=oR_T=KE>kwM+qcDghJwkq7&FNE=9#E z)$@jMyB_vtt*(0~@EHev%{uGbIx*tnj|BefD2!@Js?yr;G&zTc7^XkZv{AfyM>Zz9 z@4z-h7DJK=qDTT+2@@j;`Wrw6312iiOZH`SIkQp_;_xnNz=tPNUe2{@Hvct#BblQ; zVdJN0&)qj{2#L+We=UM161x^F;(AMR4EK@#$#SUR1xSRT^qW9R{9+Tb@>C9pVU)*R$VY$bl&!ZO4GxjPSHp=0A8Qtk~Y-b|fWS9;B zOc4j(EQuks2wrqEbr9GN;SW%rPrAiWE!0Sbfj3q^BmIm2btKb(nsuvnTW)urc?QA; zF~~+i)84&N!^`l0$)%h2e0-HdoZ?{5=;0CA-cfBDLWa3hD5Ux);o&(l5+g+g8^Z4Q z!N&K9@?0$O8#!@)T!9txtMe}VYVL-saljuJ9RNJ-{lJgqC>p$Gk@^~-=($MZ)b{G#7?&Q4d~X+tR?hmc3acmlr>1J$-aojv%uLrgi|gxK^64+Q<*IGpHV z;OXau-K>y=#WD`L4wJT>1H)oSPK+4pK>v*ObKQ|y)LDGpWguHs zbFddfPvFGZ&|QvXUU}8SKP^U=?539hAb{H_4+K&ZXM;GSII_ML1}F6Ffwvw#U$QLJ3u z-rvSO^^w7%-ASj^hXATco{sxfPUzMFgO@MlIeU9pf8+#$LK&bn_MI2_P%_l)nP`r$T+L}5 zu@;|(O;24l!=aU<&`Rj{kJDijFI$*NoE*-tKHi}iPBC#j|Bo*+W(luy<7m1YgWE7> zIn7ZT(0W+)|4lEtgIh{woHo$SI5ExEb@1{h7AYemV?@4Z7*XRfUc8!XyzCd(;o;*` zH^e{p$oHGD?t4)s6{T>$G(@q;tH8vxW@xfZ);5!QA>k==0`W#5YuUNV`s8sN6rosl zmt^q?$Myn9-H^rBtMsG;H34%}x?j@0_51@^{K+Tya@v)k#Np9Qone!}3u zK%vwj-r%iRR6$zR{IAfL6Y-i_YUwarIq5UfnirNBKr;WJM}R4161T|7{m*~)8*sHx zmOK1Zu^N#y#pBdlK3001ZYoW)#=SD&sxfjk#5Z{}6Ga;;mlX1%k*BJ^U)q9md)j zxo4R&19_>ao@P;PV*0}A6~;OZLiWAo!{SXene%EB>vM`*4DCsI7^6S-*^kbWY$cy+ znP0l>N|X#Stvm#tsncJ~**dp;%s&Xv_cX0J*YSDzS4xLU>-2N)%T4Z*XN8;dkjO;! zA&(Ho;K$vWPa&be7hXyZUa}9^n4Y(OPULtQTle`fzfbRD!@wPviHMHj)@$6V38Wi$ zO({6<%pv(ro5Y1{8=N=i+_VSUtTzPRLu5qImI-FZU-lxc*-*FV?ruEXsbNVxgfd$x zyuT8F^lJF5$ljI@W7d|1D@q6bFEaGxjA75cYts`hCAnEcBCvJ|xp8tn^eQjW3T_3> z3SoOlgQL*A3QQ{)=x+oJoH&}AS&A)68;_O$o>2>$vY z7t+3p>@9ktv5s6>zuoVW+Mh4uvhLB&b|kTVxOiFCWLSpP8__A{-K(kO6+BtK)#ZA{ z)8%^UGk-|L)5vThT@E+yqFodHS?{LmC>v&lkbV~)+x~hxP>a7?>)S?X0j}zf(=W3d zh&uu`WX+vE`g~OJ*#iShbOM8ovK}=dKrxZ-)&f!E9SWm!jNv5SvWd1>ut@r@il(r+ z5%s+^@{=>({tsd?YMOF4=)7%DhoTCW*6Z`E)mu$pCA%v3Hytq#MFjy`OgEjIpo~xX zs%bo5O&Iq*;P(=*9UKzSYOhcoHrsOs*Chx3dp|0)HfyqOV9DkAf{|^OALZ&=+AM9Z zYxbIwf2`*2Sh9i!qrRb$$qun+>#8egrIM{-bzj5w7;*cQV73_`yaN)JisKa(Z6xpa zuHYL7YfMe^zi86!bm#5G1U&Pp>9R$PP{8>AtLxY@3UP7KA~*PN)zOhXhd%5J!kh=b zOaAp%0vAh1vT_(RaCwZvY*1k+)RjZ7N6d zHlNZ{maM;a${vzfq$JpOsj>t5?x4D{uynw&_%zmP5~Rl3OX3pba3NhxZGUmAINAQf zU*poDopPFI-GH`c`|cFy)EeVB%wy_wR4j-FWo!A@?^Q(oR`mEF|p~@XF}g z236zak2P0Ps#|x}-b|&N-1FsSy?jz-)D!d{vE(E6q2ZTa;3t5XCl%~NJ1-A=Ue!>@?@#VwdMQV zF3qsMm0$S)rc~_rs#|rSPmlG`<7#y;xqE=!`@_MzMGA**k9}Li?GC3t+im5y$7zTu zONYm+XQ$EnDVhE(pEFkIwwJp7BVJ{KDW<)$FkO({GS@6jC|0&e-~OVohAl^M8n%A$ zh=|~L;~v<4)_{o6PF>H$U)*>}H+bBlzFg{0ci9bR{!hUv`A@<5)g>`28hR}EQYdK~ zDO|*7Ppo0{L&pdEOXWPhCA-@mvngvwTi9J+B7n1gD}hMjR7|*55P=-+e6HCM|hNp~f-h0SUiJT^feG~lg@G6kVc|4egyGFuI6P?3X8Dw9}|QNE$!uisn!fr-;gpdE2=U$s$QFRk^3rvD8 z$+0PZ(Q3zGMC9Y%P6YE`Iv%RAA8vBLyvaDTDq^``Fj5)r$jSYZ18|m4!S~*4yQi1F z_WVh?6t9z$``|w-=l*|IPCqkdXrD@8nsp}%4oYQC(Znb)=s1P#8!+aZ`xL1*R@Gq zMWHQ2>`A<8LHhAX$9h8wXOJ@Fn$C@Uqm%UOoRmSD1fo1M$=F`=kKJiG2ELyn?J6W8 z7Vc6_`psdsI*~RB zEla<|n9)UdQyz`TDn|B)%s$&95wY=ja-5t|CrK$=P;-+noAjz2N#RVEZ+Bq{!dL4R zAWwRUiJO8pzol%7Ot7)PxupJdE`ywCn*^ZP|Fd)?ugktDji|dhX`@&L)xOTmnPMFf z{LSf~rIW&f6%34~iVGpyKue6X@00HOiZfh0C-s$Nxt*d|T2V)#Bb)yRp-Z$)f*5jw zi2}@y!|&rhf5yo#?xQyho|V?r-685tS8-!Renw5q@1)OZ`(=tv$UP$0@{EHEKm=;6 zZ(jbnr?{x1olwOgK12V2=pDT+q@Pq#*j1E8d$Icu(q%Bdq zzXX?PtMvEgVAr@kee@$xxy=WZ`6gQ}(5E;X7cSQurJ3*Vq38 zcF6w+*omzfj`}C;pn%vt*XTdu(C&ap>KsZa3$fgO+ClI9=Ju%(VI-Pcmrz4uO;m7R zx%o7El9tHk$b{ovLMWa-+tMwx0Cg&<6%0UauKotLQhA6uUe8kAdS&MU3TgTDLYtAW z6{)S0=G;-oO2m-l;#7#RlY-NevjHb=^~U9lDb|Ccf}p{png(Z`<-lyFT4_G24C zK*qFjK9%KvB+n^>-JM@YN!uE>UnrbO@>__6&*{S@Zlb|;0BE^JEI}od39()>i{qWH z0Xa+xw4tpA#KM9Bx`^%32cx`cd4K>ulfn439o_-Xi_b0J`@AYyGPP^$71Ds(y*{|%6}^&~ zm}hXU=GOD;R8KOf2@l%2pDW|aTz=);ItqXBCl0$g;8axBMQN3)GcvdSm*Fi(3Vl4u zUo`(a$_QYe!kYNrt_0Gr7d|Uw;BN8KLx>4 zwjmNb);_tSzPYJM!727|1*uuu1Mg_1*@LAQJwde(R=+GtD&n9oI-2?Q-gyl9wDY`5 zrwYmHdV3Bf{^euXmUL{xZ4aIsBOX+og8G|poJSN}Ucbt%{U3Tql9TY*lqH^Ni=SFf zVL8V=hyg;qwx*-yx&$t2PbCgJD(HL!BJ&i$xw@(`|d@xoZLD2{Z6Xb z%WZxiAt#k!2J3mb^ag_=n3oWm_N(`|t}i*IAD3O@h#y$|JHYoqkGxteeEb&CPbs0; z`BnY%%RhOiAgRV*$f#z50zNYLK z6vgzHNRaj0N-6XD*{d@Aq=OYL$f#}SbH#LN@ceNrSg2xlsf9_us$=ElTxpUqsms+W z3TP&Vvka$>yQ+<4rXvqXXxHg^kAt*p*i?E6{t9Sx^7mHs}#(OQt#TpfkPWlo6xLmmz84(#=!L zNZs-X5u|;fcBGhE7+`9|08f{T*=?Va4*sSaqG`lHAtV>Wx?QdkR){^Ro`JtD5jMqz z8tssTGWC=GEbY4Sd0pIEE=@IdW(mWeQsbR4EeZ-h93wx(=z(R1&!h*P)XqN=jNUoj zU{y}UU*%?o-@kJsYOw114X=$S&u%GFeGb1iocQorxJ{CVU{Yp+#*L@a(DFt=#vXzAkN)uq1@R-cXhl z#X`<4dIg>c*>kmlt(`|Z+5WOBRym3mJ2C@X!TP1#A$#;!diNxLi41H_=nwumd=%{7 zXf(-EXji!K^(+x{#I!#2m2MCl%S?PFalm1&cJB3h{J$qJqe>+YE3)Y_M1!KVh6Ga3A`XV(oJB=_d>TVi5Au~o zRf^ktX_FuOD<9uiI5(_+Jh6ORQ1}+hFVRj>5sCYi7kMuD3MDCDDDNc^S4dxc|3HR&GwV6MoZXK5qt4NyLx+# zPf;dOBKi){#`Ak(o8Dgm<;Tt#??}K^DwW5VA6;tqJg7m-8u_qCY=!X(k0Z!qU>}PU zDy7K`cNOKn>Rdk0;vz6AGC#_{Z?P53lfrqcUL&6+X42WBv?Iz*%nUaw8F9glZ1`c@vB&x?C;k`b~C5k7+gi`u1qJmP|k@9Lyczm!)XU4PXoRi+vC{ zR;7n;<)Pr3hRaePAh{!c(@3Z$Cnm?yVH9FC*@QEp4;82TKB+8P^T0<_NOlFpejB|E zwEJf9c;i57<9osx<6%7U_r0pL!-MQY>*=!x=UsZM^q;iV&zs8xH&ZDUOFu45M#+n( z&@#(7GW_h_?U->JP{Uv@l*?Jlo&b?tg0?X-j?n<6H{BoX=CVZG;=J5nros;`zXuRF z%e=O-sXS%CAZ7Q$bvIifU=5&&~jJe2nlB+Y{+|$*|a$6SEtj2`@Jeo}!ow{4K2qK;5z;<)l*7=u=5zEhwu{midb$d12$WSp#0(TNt`ybj>-++F!7 zBJ?#eY$J6b{J|#=kj;W%j`atY0>%l}SqR)NU!&t;W`UXP&#mn?Z}av)$Ue`Sd)L*b zHoR7%mK&eNS7^*bgI5od7>aaypvb?yXN%KgyIsDsf%O@=Vxr>vl{&44dn2we4`p2) zLC2(%U$?Hfd=-qJ-o9uY`gL`qtMF99FXn`~3YKeEJ&H7X;!S!htH0ZT{eunVD9Svf zO*B2%bhvjr>%0ZloEvxG_FifG*cDf-!8x9^d3;fr{qb~a zHBadg{pjM|-#{(7b zveFQ(s@=tzz6U~nyf3vY1Ur~sv@w86lurF&l_5e4!!71QRuy*VX(JY0_*EIE5oFA% z`<{fkkNcu$r}v3X*$0&w={58t{!7ncrK#NBrB20^xpn~CQm1NLnu^(N zi=U>a!h!*}=X=F}3Yl=%c^ufl`rR+=$d%cAJEujIV{6S(~5lgEoH6s5!7szFlqpKA2N9#=kg6CkLO@>l3SP(es5uG8c96P8Yt`1I7K=BNvxsW<5pZ;#1OlXb{f;l zVgZf3jIHy?q&elG;E!V~IDT1|u)lfYv~YCMkd@99VXPw)-hGtfnuV`7JctFTDNS8| zeKEorH`8d|wb4A3b~HL=^=|to*Vt1kMi(o?X{|U^;{d{|;-I$Wf;{-YmtFs5KV1qTqcf4nm0eMR1M#^Q?&bi))%#UwcK5}pc1)^21wSA1!uaa^it$rX1i0hoThPl z*f----5)7z0XO1M*C0}>&Xv6)lIQbn+;!2A6!tv2zV9q|{Dq@K9<64jQeW{XHFOw^Xk>=vG=GHHsYXnNVBxAf^{N~{ygBtJ4mi@Y2V;TCy0 zM_<{xI~Xl8a&PI5*CIa>)>;w*c{@s|$o1+T6GjfuJL>#-bze;6OzQZN*lfM|TM5Te z+4+n}bGzmaM92<<_l!jGh_OVmVf3q(etsj{7>j9xR)o22Y}_hMPk8^$jmc%7!oIy7tBla0a)UDsx|ZW4BDzLy4eKBfnA7LlGnj zc=LF?5DhlcLGE+WIlk5wwx*C7GOPV4|1@iiCpckp@g%T30sb^TSvxshR|oCGE!|5x z?(>0Dt9FKTyk65F zUdn6~QODF;q=(-jC~<^6?VmCl^|sT4t%<0S!h%~}(#gITZB7am#W*jPub)K!0DlmOIj=g40r%W_{N1#$Tve#xDzt0&83 zmV-~WV6JyNo&V`zM*&LW74GJ-rWp?#x%n%jPW$K_h3=xh7iFeg&hx9Is@>hKp~3nF zf4JW9{8k;4SD|ITy!&(egU=2>`+(1U<8;T8fgi0b&iq(x-Tj@#ofz@1CAX!_90l6_ z@^qeD{|=srD7pb2$7qy;JB5iEV2kH~c(5cQW>#*@?vY^@yUD!w>rTCd1{BRlE+;;@ zP$~tzcFzK7mYsCsM#}1)p}7XNS4Z}KX`0DMk6!7V2GQ^x?BOS z`B1$T_Z0T&^88W0k@CV7<}{DxvGHb7iUUpGtYm2;srkEIY6Z_Y9P-j@L&(z=nXVWe z%s|y0D~vQ|?DZqg9MK8Xs)BxYOTWERlVbS?csc1h0vDTqhI}mzVtqO&85~tPEZvLf z8DnUxVVu`g)0_-0FCBQHZei)aXh$|J-egZjvq&bVBDC>@>{Bwox%+wmnbzz4uwwef z|3lSV2gUV!VdH2iP^86Oin}{3THLMZw#6Na+b)z+iWMmCEw1H*I}4?FaVzd_3(Eov z%kInfH}iXE-aqb4ZZbK^xye1rN%B0&o0YeEf-}-7S|v%uNA2jC{8j>Wd*pEt<6Z1_ z)A1=0|7yj*S_f$x_#zrd4M+Rv$dz7f_m(XV=u$px2*N=c2XQhhWS_xqCV zGNm=v2bWMpk^9>1DH#UagdkA3O(k91dsvTbvF$+wkKLB*jz z5d)1Lf2saWY;Up&7QZ6aE3Fl#55Dl%PL8@*##s}Qcg?6yiyA2V)$k!kM|)i7!0Ho> zK_u}^E$>L<`*))8t?9CcBYJwfA{t{Qh)(Qs`wJy)GQ5rdv_|^^b;JlM(hH5MLb+TU z)8+9tL=1IyE{eIvow&<3yE%BaHXk#{@tA(pPXFz?CE?}AgEY;2gaTWdx^BIm-oOp` z1zp6Y^j-f{9jIi<+vfP7nA%W9ok(qnAD6oOZ5;p5i*c6sHR#>XHkw*D0>px1>AHd1 z88vL$DENr2$@gw*W2Z%XC3cz^w;Fr*DXLX*hMfY}IO{eV+Vc3ORG(ETz5%)Gqp@jp zlhISToO&bE084K0=N2E$*wO<~(@YgJ9@^QTmDuui899Z2iSIm%f>Z7I_B%(qH<-kZ z(+kvCT|*b4u&g>eK;*p0GmM8>~2kiap1#$-o z8;c&a8a|~2&a~7nRM0$LOvv^*pNZ}1#8qDw7^L~$aaW7bpW2)4|Lzt}kIiOzi_lY( zj@gLiN66N*L(X^E0To;a&`h%t=`7E0@woM`-$mwr{8eW%u_dZQr*p7LYK(}k39E~q zGBToxsTFCnyud1bL0{mN9vS5^{^G!w#?kV5XMyFHwez)Um-^qpzO^4|ZYnw~lz%8c z^yxr}IA>6RxBy~^<9tq(SM~>O9d)tgzdrYMBR&dyZBxf$gg-g&o0^|aeRk-k`OEG3 z=^`fn5e_GRjd!S=GY<6an0d>bR1XL4XT znN$Y;bL|af7=JI36xCiPVJNr0#g}&iCI;KB&Pn7)k?D&0vL1e{0enOM{~1`Uh?Ipr zIm*zUMHP6pT0T&kYNN?NX?;J94*T>>xYPV=$O*&UtI01Ax@h^NsDA!(pRrf#*=Od) zc8pHO?p2i@GI+kaVxm-j(hES_NHNM05FKPH>H8p4!F*eE%L9Y`9+TimaQ5%`Avbz^ z|6t2{ui~?S<(_AFSz$p5U>4V&PUo?)$65ua;9y{b`O3jdN*KMas~`xTG(G%yz3|T8 zScqPigg-IPgKK6c&z7tvL6z3{L@=&IQqr_U634CoXzN{5i+Gyt%GBGseB~U!mp@Be z#Ux7?zwjPg@u(bW`@X?>V_&|o_{A!t%q+%gX3VX4{EJ4oM{vl~szQxMfF*HxE3e8~ zMnT8I7e55;`CLk6O4&QL@L{dj^C$wP_dSF6CLq%Q54JqB*Zg>OG5XcX@-@x9~IXP1c&E$8Oz0Mm8q4DGpuc&nC$6F_vg+m<<6*)3v;wrg^f?rtp0!t(xhLLOddOQr{HKpp>)XNLOW+Z(9R0+}aCUK0XW``@ z=I^Ez7JhKYvkrq7q;kexot9?CH*}p{mgPiWLKFrT4|Q+vC=s`Wu{IrlR2aQDG~Hui z&6nMwm4R96P`n6;I#M$!uwpdO`glAU>7&+@SeGO@wv$MOT`gc_OI7uC;)Q8?oa2Jy zmt&Q_{i*A+pT-6yW4+b>vy}xj*#~g7Ra7V#G1gFNHeL4J-}{Ue{e&q` z=V+9gk;hRksDCn)pZ{}jpu)vB_?4U%Nail`nV?DWhcs=?Tk?tu3-Strg$1|B{TvPB zrmlghKoHxi?OM9oG@aAL+ED>472x-{aa2#=g;^qk3Cx~jT4EmfP>{Cn^>zT+=U$0pxA zm(K28ryLj`c>n&3YP8&{;mDxWA6$PiyrNQ5QA8EqtNwzbH1w2Kd}<0%Z&a19@Y2gSQ<^v zoZ6eh`;HxT$-Cr?>i+S)dO1Ky2cIE3YU4Aq(mbCrCr*Pqo7eOt5rF4ES z!A}sIQJL!DNv&Zo^({~byMkXi(Vn8OOr`|vh1ub)~yiZ5=`3k1!MO_K_uxZsqb(|&o=QP@u z6_pJuD#cB*UDRlKRLytW_^7#V@;JWaTIDDkzy7V19fj=r%JsIyr3k4QXG;D$e?F(G zKqMRNBSky=AwwnJMZ|(|KwFCHKb>kT*08egI=dfkW(GAHB@oE%?f;x7mbGqve~3$H zQiU5X(7O}WQyGi_4FvPDFvY^(9otMeA7;r=pWB(a{Pa$kpQf#4;WD=RGJWE_gnO@@ ze_rr2E>4^L75w+BH$$yNR~1d>CE{~zT5W8k?p2g%6{Xt$B&=P67_tQ{(DjI9{33I8 zl?Aca=`CCn>;cZ2v0BYeIZG!|A}yAOVIBen;nca~-d$#dRb*uQtAFh_{^Pv;Q`-C{ zG$TH{uGG*yN2Mhr_Q={%@MS9IxTHzV+d5D2?vzR~2O*v}(Rtf7^`1n+KUb4qn9MK4 z{C-*6RL0%#$F-{>i;Ez~U;HC9j$4V)bdHY0Ak3k(qC-K_B)Xh1P(Z$1Lxy*ijc1nc z%Q~WC!>r>+`*%{e2=8L%X`c2MU-M_-7eW?;LV3?~SJyv|-uE9$-mq)MZpV%cH!!FI zYQ!v+JmiGuX?~dt*!0(T57LU1;S#k*lEqoRn~r!d+&4W`di*KG`0E$pl}ns;6-Vlw z$j|-%%^Tj*=%rfp)miYxwp6%&l}Tcj)?6WU%C%Qpbsp$Xp`ZSvI_C+p*ehb7|r#dS*6T#kB5M3gS9r zpH|-Iz43oaflSd&&c4|v3^tSq-~O7_?ivmg5w2$9s5OsLSBH^Q`@RuW%$5?=&{cU4Ofs0MFbX8D; zcMds&6{llUR$-**N=TQ%ylT2xOo?3De+%y{|0>ROs-}$pE8?U^rHD}Rq=72Z-~2Ug zo5{*(iaVK^65lsLvt23MW|J^z-NYLvw<~Bi(c}9x4(5$ zdU}nhq9PUT4EP?dbu;Q|9Nild$Gs1ffDybtfmEy>qs8O2hH}nv^mw4yaGC+*FXDRI z?;41j-t4jAr~0{13dYKN`dVsHI!E_aAe2;2L?c$C%9g$@@}9g-{2en-Gn8pY_0i** zdZqyfp;JayRgIq_Uu}4}+rH(Xx>QEja>`%R2>%FI0XUqZWKYqhFP^M*dq1t%c`g4) zZ??cLyEq)Ke5~an>@Mrty8o;c^44xaK{IZo?|PAaVkn?0P#CWZwKiDwPK}FMl)HFR zZb4K0FcR9CtX4l%>PPJg5|~-PitB%Y^QX_I`)w9(QJ*WRXiU?*Zf$n=ucs|CJr9E) zb)v!C54lOK(Yddjt1gL@B=DG!4*wNPHq?ns_Wai?l-<5$e9hn=?!yz)WchZYj-A-} zzonQ;Set$du3TBd=d46nrcyk8e$t~{>f;L{VYg3J_@+{f?ymP1g0%uX=GrswkH+9! zf(-e*EX3GapScgEW=qG&o$J-Tizo=vXVp^fwLB%H2MOcL_5PT4d91M#Gbc#f0Bp&z zhk6!FN%ElobfoFM-&(fK|J0$E{Ys&0Pm}+gMey8Pq7lc&x<;G4F?!ko{+qz~t@`W1 zdXRm}F?QbCq>j`Vk@4!f;KbJqzMhSOiBF@N@9C0>`1+|p(E^2T^B#-CnIo|4w^CzI z*QZnOpI?P<3=Ma^Z!`|XQZpYbm#BXV zH*+^$4f<+-bD|Wp%Mp+Pn_b=Qo;Kw*)$GoFdAYRBx%`TF&n)Km&$4BLdOG*2iV>R} zQC8D8W+&(}2O4yB8C4P$+l#GaSqOGGf1B(u6D^KsW7{@FR(T@mK5J_$+P+Oxp&nTLw@#eR+9f-Zze?p9AwPHY*{R!)w_?wP4olO9t>k;nw#3Er%^%J6O)pth~dK4>}Y z%#M2T&e~NjN@2aMm#PwofSkq-NF8PLUq;6=`6Bu9h!RSMLhgF)C(o$+6 zWUk4sBnjBae1UtYarDene!o@~MyPsfqcGC(Q58Qe|j zW{hwOD=?ic7;g1Vs|^?dZ`cgBIHsk8tzwXw9lKyg`6Tev01A04n|a;uM7zSBub+o< z9dAdbDu}g!OT#TdOKfjZE7n&)&3;jAsnPY*?-2Cs(2#8KcNG*#+b$&iYQz6Kvd~`> z(lGi@KqmIFaK?HNt$y=y^lD6Bzzz|Ztk*P~**tgyXPiL5ZoCAJ(39zdEdXyFbp5_H znxxJzg17;#{lZIqMg53M8S5GlBkuH|%lUAbt6K6nG56t&)8p9B%?dR?cth>Y2QglP zLpJDgU*u5RizavvLu$2AG?Fw{7n=7;D}`zCvpw?X!=T6YnAIn z8dU5@0-{pfr5oKrT2u}w-pq8AEaxXX&-W6j`)M=c%#>|({mvjT=eIBU#N^cQ`z7tI z){etqgOrO}@4BIFCvLfEyCa%Xs6bp-0-Z|81258D4OHJd z7;PR=Kt4130}6@@Guh%MfIPc~ws$oXT+|J36hSeo@|8#?pX;}!9S9Nt)VE}nNa||V z1Gy&^qDf5d0)NCTMnSm3l3AG!n(y942f~-(-kpV|P?k8PVzT54Ly*J~wf{CP#N!Rk<|@f8#=(``E3ZqP zXo#l*otxLtT3pvL32a3wv+>QAMO>KbRzEqY8=+G!zd;n&m2;s)^$6sZv)Vc%%Yz5% zdM^M|H){Yz-p$DBC&<`g5x6iOg-u{S#&i+5u+eu>1OCPe`~l4$y&E-^63+$w5y%Z; zLF$jVvbQ^XLZdov0tE02mW< zaQTe;>bU)@*b`CS+Tq+^=gnY~ z0aYYP>F5~-ihs$M3hE&?6^IRv*}cUCY917lU<0(uGeFN!t1g2mpUwCYg)TkEo*3XT zP8d(KHehqn7%>|O);|-Wg&U~zVx5;8+pzbl8w68g0o4PXF?u3z1hG)8d!aGfh(pt~FY!y5^H^B5ouowtvn=!KMA-pOuS z*k=;;w$5a}Jjb-vLv6j}<7^%SM!?h^TQK#@FB`~$zUpa$pCje3MDZekT8~1rcmY4| zzhQ!i5{Fnf3$ISxBk-O;#drmJJN3_k05h{MkTNrkukN%>P}LC|YG*;Op`x0T&o=X& z!DP^K7i++?FovUGf;(O@+ZN0xQ1gIQudfFBp_j^7_8f0r=kdnvsR7VVo1Gfqu)KV* z`eXTPs9A%R{w7(a%`*%pokwo6AObjAxc7p^7N_gevJZ!M%Y_*g>V-ET{eWn*ZYJzj z0-A0gGZ|5+au$Sf$49HafeHCEiY9};nE}(^F*$b)4Xq${=FZO|U>i%llO-T=94SbK z0~=I1N0Ji*@^!&{He%6WpJg+C7$AlTNngG-+T^W7RY$^dmpz}M#EzD5!f^KAV`dFaOmqF5dq4-dE6NL6Il?{S%lB}4!&ih1M~Pa*HVUud(=03e8= zkc9jvwi!OG0E12xIH_=U;%~S- zMe9vJ*%UJ(B>S;B|5NVvo+0AB&9{BCP}#3b{>B-S~nEhdsC z2agIHQg{y|*c40!w=+sT?5#u;>hBzaHg638VXuNPmu?+4+ndk=(2%RiLM)&v{E;>Y zczgiCm}Cv*;P@nW7Km4%`M68JDQN_uC6+5(4wQoi&-I8#FqJ=IKofWIXd~)40KUS| zdXovaNRpocOBhI{8L%MK+!-yr>0}fR#6V$=17#z<%28-xXiSA1uqfXpA4vw)cLw~- z&j)Lt{lmQ@RRCaziNd3FHhC+M!M$GPAb&>aZ3V*tCM5Ez7S~pL#|9+qfMS{W8HKwS_wgkjV2p+Ym5Xa!_=NXfq)AgH@k>CUj$(%4$(#2GC#IrZ@k$# zRN5>|EdXFc5|9T0oBnf50oVsgSYgCnobVN|NLa^~6jV=)afNdUA$;5_9|@CP#lr+g z-p^}n9+?!x_98;8@uAUk;7`5r6?rc=3k{_OF;O^((hbZD<+D&;=!LV~I$oGKzzGw{ zb>@YAUJ8OsKwB%3p^*?(q!6@p&Q?7VcB!&L9MF?;xS{xcv z`2metpm+n=@smw5kiEg2IEb8$fCX<(_afw=Y?~gMXueIR6bL__LiGOlb12cSe#ZZr z^sQb;exXu`R%Gh|jIGyvRt}B<)kcIcd4ntvZoLOa(t+3;+Mth2&|Cyex%VNZptu*$ zum|w6<(0or-6GzI%KfEg>{a4O0TfH97e;i}KICT;?UhW!ef~k@rQOMmTW=QO=F}Z-LV98Yi zPO!uqP)0WrS=xah$Sev2_26HV!!AV*+Y2saKTgAhyg}!OlL8^@ShD|Z{KMX}P})OK zU$5$g^q99TPolA}l2VZt{ik^sG1SCJtnCAAr_c%Pi4D^V-1SK0U@1YS>2~OtCq{73 zuX^0wgC~b666Wi(qDZn4(?qfx#RjI90tg1;Tw7~~OboY-J*9<5EWTv=?y=aIebJ8- z46^m4^zNw>#t2zwmLF3pD6H#TD3v==oRlna;vI&;f+joCoMaEBqn5(~!!X~F4J;>c zDEYPh_k!7&l|8^~#QL9cxO6Sxo~ZR?>tKk3>*^!DywXm^lL|@<^*Fnk)9-SyuWT&~ zGo!j<7P{w|Azw!usdv>=!gz=E%frk+AwPVF5bTZ}-fcfi-q5*f#Xi`%*8SlmyVr@k zyCf)I<$V-$ArjDBu0%2h!3iNI-M~DXSB4EMI0xFsFkvCY*$RbzZ#Nu{ux+?}wkd!N z{Ud3M33}$O02WuRm5p1Wc)5Xn;OBsTh71mJC$AnrEI| z1Rg7)2rQ8;pO7kSVBujVHW0<|ZP`xz{9BNWUMK#pAS=R32}Sk9hQ*8y{J!zx%A-;a zjD>KQ@eFyjTmBsk!rWc_j^t$qe@6BSBwr|pNe;XD$@MVZk;>>H2+njuzG3RK1?zva znLIO@_}05Lc|BZzvIQ%7{OSwYd&sy_ESL<{!$NUi(mYuM6#Wz=^}5ca4TZ#70_Vpg z9V@6Fx`&uI!bWeory4V_Pd|qtF2a)!9*RI%6B}zMLBH|^+1An4q0;R(AFX$_$%8FW zW<2QVUdfjvm`^_h@pT>hqa?SrS!`h_giZ>8ZXZyaY%~yTK?iV=0Ks9{*Q>fA3NcSY zg@z%@S03t12)sWJm>cSHPHEkF?r83(JA320Ji$C*oI8$f?MN?95dPtXDhw4)u$W{# zJduR$^Z>Xha-y1xKSN`t#Y~Ex6 z4HgKZ{b}to(S#!;*gf%g!M(Snf=qUToGXw4HBcg};20o!6wC`{4+HW-6aQRbKZXI9 zR}6sX=t2yq2lTAk+9=VH$q5l(xf#_|W zmgyqBdsU@KeFx#*;C(VJ;*!`0C!#cB660Ar9yuh9q z+CftpXk+6LU|?W8$Dr^Mdb4qX)i33Ofg!4hi6QV5>-pZ#CBQ*Y$Hmh>i2uEZy@VLQ zgqWba%ZL9xPTuZzULM{b9ejOVygUVby-vG>-;t}`16J2kHNU+7sPSBEoPs%0kr{tW zXcgZHOQ{{Vj`TY|{%1B0vR`mT99#>r^}`O{j^l=3zuFk%JE|*cw&4{1i)xG5b!!n+ zjMYK=;R^HmaKGE@i1XW9)cS1_gF{C_@o{BH)$vhP&bhuomYIT$v8fs;Y*ZC@ZX#8u zBMYI6T`V)8mGWJ6!$J%2^Td1`d`^Gf#iLbr_ohen-dt#5moj18&pMvWLVhG$er6bP{wIA<$NaR9skXq%G%0`oxk0gCA(b<3NacwOI6fZNDh)jz(q=g*(w4g0iYd`w68n~*1SK1MgYwWP?^ zgPowFrp`)#_wPIf?5&qpxP!KKn_A^B5=lu(iP>g{H691Yz2niiszFnV=Jff*L|qLD z@fa)1;|gW?2_5g~qNLt?Gdo{gQ$8aJ3I{QXXu34hbT~ZG)V`_oXJz{@79(Rr)6OdZ z*A=Iu1>-l;;x11MUk6x++LmL*;~&-%zpD<7HV0Q5-!`72Ce@rHa1)1-Me{4&%8JUG zYP2xBK9Tu=Ol6rgJt|2Ay{m(+RH2VHiRsQW0=Cw4DAbh-*O89!l)T}k*g787U=Mb+ z(2kdOkDWIlO5D?hOQ;wK8aSq9>J}IoW|?P6j%p<}8NKG>SIB82dpCnn8|}J3v`Tzn zQfNaNi5|Rm^s6>p#DBV_?(T;XO=r{LV~v}QjmT-(A35U<&TA$0kcfq}Iw?rkA{o zXG`bU0ATcg%3!{mxt%vNnL`hb48~ zkqARt{+TkBk?4uky%iXfFZ$1IXXQ5jOajD7hptFuYPw8Xx?`aOIz7BayGnq{5-%Dr zeci(zdU|>XTNfLL2lX2+<2{fOi9pw#z?RE{e|I`J&P+T`MUg1TWC+q|%sL>b^#=euQ9!=ScuHNd-#=yr=aJaC?G*Y<3G$3~USXB(FjKK#EhdxTo@VOs zs^9l3-`Y7qF=6J6jIn&|_e|fAR%;J1WV$|0eAzAg{E4FpPR>s=W z!-SvinJbiWcScsBb=G|CzmST;`cP2_FpSc-b=}ZCMdP1Eaaq|jo1TAv@3@x`ZBm%| zRoB6vUg`wuVxs7}LG=5mk&9t`-K^n1`@Y|ZQY#1rLwoyck$OK^W~mjLfku~tf8~Br z!}g&XkZjcgGU|aBo-y@S=Q8gcUHIE>rUZ_>Jy^V2Oc>IvOKrQM@q(KU-%(KoYdKO2T2C7zZs#41Wm zWRS2E*@o4m+K(iH%Dx_`q6MQ9#y(j zAis0a=DkJtD)|Ns5KHy9)XnF}oiNlr>~cQ(EAGEPbiC?#q$A?57dvm^bo5uqpJV9w zZ;M~gF{>X|z04zDKCv;UyxGA!bvDU(^VhKi=+(wU)k&0bZ$m3!Rr)%R)^*U5FRXQM*cxZL_c3_cDWiE%oSwT)tDHYdt&X+s0t9QL6Slc{+3tGSRy%C5%cX;eOm|$=|R|ruMA{=o!W1PSd>PvFPf;$H-DRR(aVx!1r{9=>m?X z3m;9-(_Qt;JUdoi;OtqE|6@mVEG2J4cUr0D?-qC9oX~Cm#(~OsAuP2>)<|Nwu!mmU&%1h z$~WSv@yyRjx9H%nEcS^1$_eIP$w*eS5FCpnTQ5mjm<~t?srdVSZiOv-mzIZF{cB5) z=FE}wp#<-2YMzUMd)d!vokHSm9a7yxC6&0{ZX?M`)sL7-FFr0FaA%x0YJLoJj3@Zp z0HFN)=*K(QJ39Y&W;7d^OzuJ1Nc`WiCGFovNpM<+OZ%v}cl!KcszbO7?}=tz1FGa_ zji9k4Ji&P3qNV}#UphR^+#(VuZ9b*r2-nYsLi+NzZ(~T``%+W5g|u^s%W>K4bn41P zDQHc>m5M)oxfL{!>gV!lZ)zMn-*csfx!U~b=Bmc%1yMbSw-i7Aq-jfkay>-HWG}Ur zuwiDj734TE=jb^FEwAi~Zn+Z5Y%w&|YJIeR(SAJhl12ELu_Rr^O7w$};@&&K${?(h z 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 N0TT$ZaUiK7{{zZz|1JOk literal 0 HcmV?d00001 diff --git a/project/BuildSettings.scala b/project/BuildSettings.scala new file mode 100644 index 0000000..ca226f6 --- /dev/null +++ b/project/BuildSettings.scala @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ + + // SBT +import sbt._ +import Keys._ + +object BuildSettings { + + // Basic settings for our app + lazy val basicSettings = Seq[Setting[_]]( + organization := "com.snowplowanalytics", + version := "0.1.0", + description := "Kinesis LZO sink for S3", + scalaVersion := "2.10.1", + scalacOptions := Seq("-deprecation", "-encoding", "utf8", + "-feature", "-target:jvm-1.7"), + scalacOptions in Test := Seq("-Yrangepos"), + resolvers ++= Dependencies.resolutionRepos + ) + + // Makes our SBT app settings available from within the app + lazy val scalifySettings = Seq(sourceGenerators in Compile <+= (sourceManaged in Compile, version, name, organization) map { (d, v, n, o) => + val file = d / "settings.scala" + IO.write(file, """package com.snowplowanalytics.snowplow.storage.kinesis.s3.generated + |object Settings { + | val organization = "%s" + | val version = "%s" + | val name = "%s" + |} + |""".stripMargin.format(o, v, n)) + Seq(file) + }) + + // sbt-assembly settings for building a fat jar + import sbtassembly.Plugin._ + import AssemblyKeys._ + lazy val sbtAssemblySettings = assemblySettings ++ Seq( + // Executable jarfile + assemblyOption in assembly ~= { _.copy(prependShellScript = Some(defaultShellScript)) }, + // Name it as an executable + jarName in assembly := { s"${name.value}-${version.value}" }, + + excludedJars in assembly <<= (fullClasspath in assembly) map { cp => + val excludes = Set( + "junit-4.8.2.jar", + "jsp-2.1-6.1.14.jar", + "jasper-compiler-5.5.12.jar", + "jsp-api-2.1-6.1.14.jar", + "servlet-api-2.5-6.1.14.jar", + "commons-beanutils-1.7.0.jar", + "hadoop-lzo-0.4.19.jar", + "stax-api-1.0.1.jar", + "commons-collections-3.2.1.jar" + ) + cp filter { jar => excludes(jar.data.getName) } + }, + + mergeStrategy in assembly := { + case PathList("javax", "servlet", xs @ _*) => MergeStrategy.first + case PathList("org", "objectweb", "asm", xs @ _*) => MergeStrategy.first + case PathList(ps @ _*) if ps.last endsWith ".html" => MergeStrategy.first + case "application.conf" => MergeStrategy.concat + case x => + val oldStrategy = (mergeStrategy in assembly).value + oldStrategy(x) + } + + ) + + lazy val buildSettings = basicSettings ++ scalifySettings ++ sbtAssemblySettings +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala new file mode 100644 index 0000000..5b2ccdb --- /dev/null +++ b/project/Dependencies.scala @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +import sbt._ + +object Dependencies { + + val resolutionRepos = Seq( + "Snowplow Analytics Maven releases repo" at "http://maven.snplow.com/releases/", + "Snowplow Analytics Maven snapshot repo" at "http://maven.snplow.com/snapshots/", + "Twitter maven repo" at "http://maven.twttr.com/", + // For Scalazon + "BintrayJCenter" at "http://jcenter.bintray.com" + ) + + object V { + // Java + val logging = "1.1.3" + val slf4j = "1.7.6" + val kinesisClient = "1.0.0" + val kinesisConnector = "1.1.1" + val hadoop = "1.2.1" + val elephantbird = "4.5" + // Thrift (test only) + val collectorPayload = "0.0.0" + // Scala + val argot = "1.0.1" + val config = "1.0.2" + val scalaUtil = "0.1.0" + val snowplowCommonEnrich = "0.9.0" + val scalazon = "0.5" + val json4s = "3.2.11" + val scalaz7 = "7.0.0" + // Scala (test only) + val specs2 = "2.2" + val scalazSpecs2 = "0.1.2" + // Scala (compile only) + val commonsLang3 = "3.1" + } + + object Libraries { + // Java + val slf4j = "org.slf4j" % "slf4j-simple" % V.slf4j + val kinesisClient = "com.amazonaws" % "amazon-kinesis-client" % V.kinesisClient + val kinesisConnector = "com.amazonaws" % "amazon-kinesis-connector" % V.kinesisConnector + val hadoop = "org.apache.hadoop" % "hadoop-core" % V.hadoop + val elephantbird = "com.twitter.elephantbird" % "elephant-bird-core" % V.elephantbird + // Thrift (test only) + val collectorPayload = "com.snowplowanalytics" % "collector-payload-1" % V.collectorPayload % "test" + // Scala + val argot = "org.clapper" %% "argot" % V.argot + val config = "com.typesafe" % "config" % V.config + val scalazon = "io.github.cloudify" %% "scalazon" % V.scalazon + val json4sJackson = "org.json4s" %% "json4s-jackson" % V.json4s + val scalaz7 = "org.scalaz" %% "scalaz-core" % V.scalaz7 + // Scala (test only) + val specs2 = "org.specs2" %% "specs2" % V.specs2 % "test" + val scalazSpecs2 = "org.typelevel" %% "scalaz-specs2" % V.scalazSpecs2 % "test" + } +} diff --git a/project/SnowplowS3SinkBuild.scala b/project/SnowplowS3SinkBuild.scala new file mode 100644 index 0000000..a66c885 --- /dev/null +++ b/project/SnowplowS3SinkBuild.scala @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013-2014 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +import sbt._ +import Keys._ + +object SnowplowKinesisEnrichBuild extends Build { + + import Dependencies._ + import BuildSettings._ + + // Configure prompt to show current project + override lazy val settings = super.settings :+ { + shellPrompt := { s => Project.extract(s).currentProject.id + " > " } + } + + // Define our project, with basic project information and library dependencies + lazy val project = Project("snowplow-lzo-s3-sink", file(".")) + .settings(buildSettings: _*) + .settings( + libraryDependencies ++= Seq( + Libraries.argot, + Libraries.config, + Libraries.scalaz7, + Libraries.specs2, + Libraries.scalazSpecs2, + Libraries.kinesisClient, + Libraries.kinesisConnector, + Libraries.slf4j, + Libraries.hadoop, + Libraries.elephantbird, + Libraries.scalazon, + Libraries.json4sJackson, + Libraries.collectorPayload + ) + ) +} diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..8ac605a --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.2 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..54c3252 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2") diff --git a/src/main/resources/config.hocon.sample b/src/main/resources/config.hocon.sample new file mode 100644 index 0000000..3bc087e --- /dev/null +++ b/src/main/resources/config.hocon.sample @@ -0,0 +1,60 @@ +# Default configuration for kinesis-elasticsearch-sink + +connector { + + # The following are used to authenticate for the Amazon Kinesis sink. + # + # If both are set to 'default', the default provider chain is used + # (see http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html) + # + # If both are set to 'iam', use AWS IAM Roles to provision credentials. + # + # If both are set to 'env', use environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY + aws { + access-key: "default" + secret-key: "default" + } + + kinesis { + in { + # Kinesis input stream name + stream-name: "" + + # LATEST: most recent data. + # TRIM_HORIZON: oldest available data. + # Note: This only affects the first run of this application + # on a stream. + initial-position: "TRIM_HORIZON" + } + + out { + # Stream for events for which the storage process fails + stream-name: "s3-raw-sink-errors" + + # Number of shards with which to create the stream if it doesn't already exist + shards: 1 + } + + region: "us-east-1" + + # `app-name` is used for a DynamoDB table to maintain stream state. + app-name: SnowplowElasticsearchSink-${connector.kinesis.in.stream-name} + } + + s3 { + endpoint: "http://s3.amazonaws.com" + bucket: "" # Put s3 Bucket here + } + + # Events are accumulated in a buffer before being sent to S3. + # The buffer is emptied whenever: + # - the combined size of the stored records exceeds byte-limit or + # - the number of stored records exceeds record-limit or + # - the time in milliseconds since it was last emptied exceeds time-limit + buffer { + byte-limit: 5242880 # 5MB + record-limit: 1000 # 1K records + time-limit: 60000 # 1 minute + } + +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/package.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/package.scala new file mode 100644 index 0000000..8eec5d0 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/package.scala @@ -0,0 +1,39 @@ + /* + * Copyright (c) 2015 Snowplow Analytics Ltd. + * All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache + * License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the Apache License Version 2.0 for the specific language + * governing permissions and limitations there under. + */ + +package com.snowplowanalytics.snowplow.storage.kinesis + +// Scalaz +import scalaz._ +import Scalaz._ + +package object s3 { + + /** + * Tuple containing: + * - the original Kinesis record, base 64 encoded + * - a validated SnowplowRawEvent created from it + */ + type ValidatedRecord = (String, Validation[List[String], Array[Byte]]) + + /** + * Currently the same as ValidatedRecord, but could change in the future + */ + type EmitterInput = (String, Validation[List[String], Array[Byte]]) +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/CredentialsLookup.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/CredentialsLookup.scala new file mode 100644 index 0000000..1279268 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/CredentialsLookup.scala @@ -0,0 +1,92 @@ + /* + * Copyright (c) 2014 Snowplow Analytics Ltd. + * All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache + * License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the Apache License Version 2.0 for the specific language + * governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3 + +// Amazon +import com.amazonaws.auth._ + +/** + * Gets AWS credentials based on configuration YAML + */ +// TODO: extract this functionality into a common library +object CredentialsLookup { + + /** + * Returns AWS credentials based on access key and secret key + * + * @param a Access key + * @param s Secret key + * @return An AWSCredentialsProvider + */ + def getCredentialsProvider(a: String, s: String): AWSCredentialsProvider = { + if (isDefault(a) && isDefault(s)) { + new DefaultAWSCredentialsProviderChain() + } else if (isDefault(a) || isDefault(s)) { + throw new RuntimeException( + "access-key and secret-key must both be set to 'default', or neither" + ) + } else if (isIam(a) && isIam(s)) { + new InstanceProfileCredentialsProvider() + } else if (isIam(a) || isIam(s)) { + throw new RuntimeException("access-key and secret-key must both be set to 'iam', or neither") + } else if (isEnv(a) && isEnv(s)) { + new EnvironmentVariableCredentialsProvider() + } else if (isEnv(a) || isEnv(s)) { + throw new RuntimeException("access-key and secret-key must both be set to 'env', or neither") + } else { + new BasicAWSCredentialsProvider( + new BasicAWSCredentials(a, s) + ) + } + } + + /** + * Is the access/secret key set to the special value "default" i.e. use + * the standard provider chain for credentials. + * + * @param key The key to check + * @return true if key is default, false otherwise + */ + private def isDefault(key: String): Boolean = (key == "default") + + /** + * Is the access/secret key set to the special value "iam" i.e. use + * the IAM role to get credentials. + * + * @param key The key to check + * @return true if key is iam, false otherwise + */ + private def isIam(key: String): Boolean = (key == "iam") + + /** + * Is the access/secret key set to the special value "env" i.e. get + * the credentials from environment variables + * + * @param key The key to check + * @return true if key is iam, false otherwise + */ + private def isEnv(key: String): Boolean = (key == "env") + + // Wrap BasicAWSCredential objects. + class BasicAWSCredentialsProvider(basic: BasicAWSCredentials) extends + AWSCredentialsProvider{ + @Override def getCredentials: AWSCredentials = basic + @Override def refresh = {} + } +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/LzoSerializer.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/LzoSerializer.scala new file mode 100644 index 0000000..d993d5e --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/LzoSerializer.scala @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3 + +import scala.collection.JavaConverters._ + +// Java libs +import java.io.{ + OutputStream, + DataOutputStream, + ByteArrayInputStream, + ByteArrayOutputStream, + IOException +} +import java.util.Calendar +import java.text.SimpleDateFormat + +// Java lzo +import org.apache.hadoop.conf.Configuration +import com.hadoop.compression.lzo.LzopCodec + +// Elephant bird +import com.twitter.elephantbird.mapreduce.io.RawBlockWriter + +// Scalaz +import scalaz._ +import Scalaz._ + +// Logging +import org.apache.commons.logging.LogFactory + +// AWS libs +import com.amazonaws.AmazonServiceException +import com.amazonaws.services.s3.AmazonS3Client +import com.amazonaws.services.s3.model.ObjectMetadata + +// AWS Kinesis connector libs +import com.amazonaws.services.kinesis.connectors.{ + UnmodifiableBuffer, + KinesisConnectorConfiguration +} +import com.amazonaws.services.kinesis.connectors.interfaces.IEmitter + +/** + * Object to handle LZO compression of raw events + */ +object LzoSerializer { + + val log = LogFactory.getLog(getClass) + + val lzoCodec = new LzopCodec() + val conf = new Configuration() + conf.set("io.compression.codecs", classOf[LzopCodec].getName) + lzoCodec.setConf(conf) + + /** + * Compress a list of Snowplow events + * + * @param records List of deserialized records + * @return Tuple4 containing: the output stream for the .lzo file + * the output stream for the .lzo.index file + * the compression codec + * the list of events + */ + def serialize(records: List[ EmitterInput ]): (ByteArrayOutputStream, ByteArrayOutputStream, LzopCodec, List[EmitterInput]) = { + + val indexOutputStream = new ByteArrayOutputStream() + val outputStream = new ByteArrayOutputStream() + + // This writes to the underlying outputstream and indexoutput stream + val lzoOutputStream = lzoCodec.createIndexedOutputStream(outputStream, new DataOutputStream(indexOutputStream)) + + val rawBlockWriter = new RawBlockWriter(lzoOutputStream) + + // Populate the output stream with records + val results = records.map({ record => try { + (record._1, record._2.map(r => { + rawBlockWriter.write(r) + r + })) + } catch { + case e: IOException => { + log.warn(e) + (record._1, List("Error writing raw event to output stream: [%s]".format(e.toString)).fail) + } + } + }) + + rawBlockWriter.close + + (outputStream, indexOutputStream, lzoCodec, results) + } +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/RawEventTransformer.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/RawEventTransformer.scala new file mode 100644 index 0000000..f9c45bd --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/RawEventTransformer.scala @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3 + +// AWS libs +import com.amazonaws.services.kinesis.model.Record + +// AWS Kinesis Connector libs +import com.amazonaws.services.kinesis.connectors.interfaces.ITransformer + +// Thrift libs +import org.apache.thrift.{TSerializer,TDeserializer} + +// Apache commons +import org.apache.commons.codec.binary.Base64 + +// Scalaz +import scalaz._ +import Scalaz._ + +/** + * Thrift serializer/deserializer class + */ +class RawEventTransformer extends ITransformer[ ValidatedRecord, EmitterInput ] { + lazy val serializer = new TSerializer() + lazy val deserializer = new TDeserializer() + + override def toClass(record: Record): ValidatedRecord = { + val recordByteArray = record.getData.array + (new String(Base64.encodeBase64(recordByteArray)), recordByteArray.success) + } + + override def fromClass(record: EmitterInput) = record +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Emitter.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Emitter.scala new file mode 100644 index 0000000..0315601 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Emitter.scala @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3 + +import scala.collection.JavaConverters._ + +// Java libs +import java.io.{ + OutputStream, + DataOutputStream, + ByteArrayInputStream, + ByteArrayOutputStream, + IOException +} +import java.util.Calendar +import java.text.SimpleDateFormat + +// Java lzo +import org.apache.hadoop.conf.Configuration +import com.hadoop.compression.lzo.LzopCodec + +// Elephant bird +import com.twitter.elephantbird.mapreduce.io.{ + ThriftBlockWriter +} + +// Logging +import org.apache.commons.logging.{Log,LogFactory} + +// AWS libs +import com.amazonaws.AmazonServiceException +import com.amazonaws.services.s3.AmazonS3Client +import com.amazonaws.services.s3.model.ObjectMetadata + +// AWS Kinesis connector libs +import com.amazonaws.services.kinesis.connectors.{ + UnmodifiableBuffer, + KinesisConnectorConfiguration +} +import com.amazonaws.services.kinesis.connectors.interfaces.IEmitter + +// Scala +import scala.collection.JavaConversions._ +import scala.annotation.tailrec + +// Scalaz +import scalaz._ +import Scalaz._ + +// json4s +import org.json4s._ +import org.json4s.jackson.JsonMethods._ +import org.json4s.JsonDSL._ + +// This project +import sinks._ + +/** + * Emitter for flushing Kinesis event data to S3. + * + * Once the buffer is full, the emit function is called. + */ +class S3Emitter(config: KinesisConnectorConfiguration, badSink: ISink) extends IEmitter[ EmitterInput ] { + + /** + * The amount of time to wait in between unsuccessful index requests (in milliseconds). + * 10 seconds = 10 * 1000 = 10000 + */ + private val BackoffPeriod = 10000 + + val bucket = config.S3_BUCKET + val log = LogFactory.getLog(classOf[S3Emitter]) + val client = new AmazonS3Client(config.AWS_CREDENTIALS_PROVIDER) + client.setEndpoint(config.S3_ENDPOINT) + + val lzoCodec = new LzopCodec() + val conf = new Configuration() + conf.set("io.compression.codecs", classOf[LzopCodec].getName) + lzoCodec.setConf(conf) + + val dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + + /** + * Determines the filename in S3, which is the corresponding + * Kinesis sequence range of records in the file. + */ + protected def getFileName(firstSeq: String, lastSeq: String, lzoCodec: LzopCodec): String = { + dateFormat.format(Calendar.getInstance().getTime()) + + "-" + firstSeq + "-" + lastSeq + lzoCodec.getDefaultExtension() + } + + /** + * Reads items from a buffer and saves them to s3. + * + * This method is expected to return a List of items that + * failed to be written out to S3, which will be sent to + * a Kinesis stream for bad events. + * + * @param buffer BasicMemoryBuffer containing EmitterInputs + * @return list of inputs which failed transformation + */ + override def emit(buffer: UnmodifiableBuffer[ EmitterInput ]): java.util.List[ EmitterInput ] = { + + log.info(s"Flushing buffer with ${buffer.getRecords.size} records.") + + val records = buffer.getRecords().asScala.toList + + val (outputStream, indexOutputStream, lzoCodec, results) = LzoSerializer.serialize(records) + + val filename = getFileName(buffer.getFirstSequenceNumber, buffer.getLastSequenceNumber, lzoCodec) + val indexFilename = filename + ".index" + + val obj = new ByteArrayInputStream(outputStream.toByteArray) + val indexObj = new ByteArrayInputStream(indexOutputStream.toByteArray) + + val objMeta = new ObjectMetadata() + val indexObjMeta = new ObjectMetadata() + + objMeta.setContentLength(outputStream.size) + indexObjMeta.setContentLength(indexOutputStream.size) + + val (successes, failures) = results.partition(_._2.isSuccess) + + log.info(s"Successfully serialized ${successes.size} records out of ${successes.size + failures.size}") + + /** + * Keep attempting to send the data to S3 until it succeeds + * + * @return list of inputs which failed to be sent to S3 + */ + @tailrec + def attemptEmit(): List[EmitterInput] = { + try { + client.putObject(bucket, filename, obj, objMeta) + client.putObject(bucket, indexFilename, indexObj, indexObjMeta) + log.info(s"Successfully emitted ${successes.size} records to S3 in s3://${bucket}/${filename} with index $indexFilename") + + // Return the failed records + failures + } catch { + // Retry on failure + case ase: AmazonServiceException => { + log.error("S3 could not process the request", ase) + sleep(BackoffPeriod) + attemptEmit() + } + case e: Throwable => { + log.error("S3Emitter threw an unexpected exception", e) + sleep(BackoffPeriod) + attemptEmit() + } + } + } + + if (successes.size > 0) { + attemptEmit() + } else { + failures + } + } + + /** + * Closes the client when the KinesisConnectorRecordProcessor is shut down + */ + override def shutdown() { + client.shutdown + } + + /** + * Sends records which fail deserialization or compression + * to Kinesis with an error message + * + * @param records List of failed records to send to Kinesis + */ + override def fail(records: java.util.List[ EmitterInput ]) { + records.asScala.foreach { record => + log.warn(s"Record failed: $record") + log.info("Sending failed record to Kinesis") + val output = compact(render(("line" -> record._1) ~ ("errors" -> record._2.swap.getOrElse(Nil)))) + badSink.store(output, Some("key"), false) + } + } + + /** + * Period between retrying sending events to S3 + * + * @param sleepTime Length of time between tries + */ + private def sleep(sleepTime: Long): Unit = { + try { + Thread.sleep(sleepTime) + } catch { + case e: InterruptedException => () + } + } + +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Pipeline.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Pipeline.scala new file mode 100644 index 0000000..27622c3 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3Pipeline.scala @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3 + +// AWS Kinesis Connector libs +import com.amazonaws.services.kinesis.connectors.interfaces.{ + IEmitter, + IBuffer, + ITransformer, + IFilter, + IKinesisConnectorPipeline +} +import com.amazonaws.services.kinesis.connectors.KinesisConnectorConfiguration +import com.amazonaws.services.kinesis.connectors.impl.{BasicMemoryBuffer,AllPassFilter} + +// This project +import sinks._ + +/** + * S3Pipeline class sets up the Emitter/Buffer/Transformer/Filter + */ +class S3Pipeline(badSink: ISink) extends IKinesisConnectorPipeline[ ValidatedRecord, EmitterInput ] { + + override def getEmitter(configuration: KinesisConnectorConfiguration) = new S3Emitter(configuration, badSink) + + override def getBuffer(configuration: KinesisConnectorConfiguration) = new BasicMemoryBuffer[ValidatedRecord](configuration) + + override def getTransformer(c: KinesisConnectorConfiguration) = new RawEventTransformer() + + override def getFilter(c: KinesisConnectorConfiguration) = new AllPassFilter[ValidatedRecord]() + +} + diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3SinkExecutor.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3SinkExecutor.scala new file mode 100644 index 0000000..e1ac887 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/S3SinkExecutor.scala @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3 + +// AWS Kinesis Connector libs +import com.amazonaws.services.kinesis.connectors.{ + KinesisConnectorConfiguration, + KinesisConnectorExecutorBase, + KinesisConnectorRecordProcessorFactory +} + +// This project +import sinks._ + +/** + * Boilerplate class for Kinessis Conenector + */ +class S3SinkExecutor(config: KinesisConnectorConfiguration, badSink: ISink) extends KinesisConnectorExecutorBase[ ValidatedRecord, EmitterInput ] { + super.initialize(config) + + override def getKinesisConnectorRecordProcessorFactory = { + new KinesisConnectorRecordProcessorFactory[ ValidatedRecord, EmitterInput ](new S3Pipeline(badSink), config) + } + +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/SinkApp.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/SinkApp.scala new file mode 100644 index 0000000..7d20a15 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/SinkApp.scala @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3 + +// Java +import java.io.File +import java.util.Properties + +// Argot +import org.clapper.argot._ + +// Config +import com.typesafe.config.{Config, ConfigFactory} + +// AWS libs +import com.amazonaws.auth.AWSCredentialsProvider + +// AWS Kinesis Connector libs +import com.amazonaws.services.kinesis.connectors.KinesisConnectorConfiguration + +// This project +import sinks._ + +/** + * The entrypoint class for the Kinesis-S3 Sink applciation. + */ +object SinkApp extends App { + + // Argument specifications + import ArgotConverters._ + + // General bumf for our app + val parser = new ArgotParser( + programName = "generated", + compactUsage = true, + preUsage = Some("%s: Version %s. Copyright (c) 2013, %s.".format( + generated.Settings.name, + generated.Settings.version, + generated.Settings.organization) + ) + ) + + // Optional config argument + val config = parser.option[Config](List("config"), + "filename", + "Configuration file.") { + (c, opt) => + + val file = new File(c) + if (file.exists) { + ConfigFactory.parseFile(file) + } else { + parser.usage("Configuration file \"%s\" does not exist".format(c)) + ConfigFactory.empty() + } + } + parser.parse(args) + + val conf = config.value.getOrElse(throw new RuntimeException("--config argument must be provided")) + + // TODO: make the conf file more like the Elasticsearch equivalent + val kinesisSinkRegion = conf.getConfig("connector").getConfig("kinesis").getString("region") + val kinesisSinkEndpoint = s"https://kinesis.${kinesisSinkRegion}.amazonaws.com" + val kinesisSink = conf.getConfig("connector").getConfig("kinesis").getConfig("out") + val kinesisSinkName = kinesisSink.getString("stream-name") + val kinesisSinkShards = kinesisSink.getInt("shards") + + val credentialConfig = conf.getConfig("connector").getConfig("aws") + + val credentials = CredentialsLookup.getCredentialsProvider(credentialConfig.getString("access-key"), credentialConfig.getString("secret-key")) + + val badSink = new KinesisSink(credentials, kinesisSinkEndpoint, kinesisSinkName, kinesisSinkShards) + + val executor = new S3SinkExecutor(convertConfig(conf, credentials), badSink) + executor.run() + + /** + * This function converts the config file into the format + * expected by the Kinesis connector interfaces. + * + * @param connector The configuration HOCON + * @return A KinesisConnectorConfiguration + */ + def convertConfig(conf: Config, credentials: AWSCredentialsProvider): KinesisConnectorConfiguration = { + val props = new Properties() + val connector = conf.resolve.getConfig("connector") + + val kinesis = connector.getConfig("kinesis") + val kinesisIn = kinesis.getConfig("in") + val kinesisRegion = kinesis.getString("region") + val kEndpoint = s"https://kinesis.${kinesisSinkRegion}.amazonaws.com" + val streamName = kinesisIn.getString("stream-name") + val initialPosition = kinesisIn.getString("initial-position") + val appName = kinesis.getString("app-name") + + val s3 = connector.getConfig("s3") + val s3Endpoint = s3.getString("endpoint") + val bucket = s3.getString("bucket") + + val buffer = connector.getConfig("buffer") + val byteLimit = buffer.getString("byte-limit") + val recordLimit = buffer.getString("record-limit") + val timeLimit = buffer.getString("time-limit") + + props.setProperty(KinesisConnectorConfiguration.PROP_KINESIS_INPUT_STREAM, streamName) + props.setProperty(KinesisConnectorConfiguration.PROP_KINESIS_ENDPOINT, kEndpoint) + props.setProperty(KinesisConnectorConfiguration.PROP_APP_NAME, appName) + props.setProperty(KinesisConnectorConfiguration.PROP_INITIAL_POSITION_IN_STREAM, initialPosition) + + props.setProperty(KinesisConnectorConfiguration.PROP_S3_ENDPOINT, s3Endpoint) + props.setProperty(KinesisConnectorConfiguration.PROP_S3_BUCKET, bucket) + + props.setProperty(KinesisConnectorConfiguration.PROP_BUFFER_BYTE_SIZE_LIMIT, byteLimit) + props.setProperty(KinesisConnectorConfiguration.PROP_BUFFER_RECORD_COUNT_LIMIT, recordLimit) + props.setProperty(KinesisConnectorConfiguration.PROP_BUFFER_MILLISECONDS_LIMIT, timeLimit) + + props.setProperty(KinesisConnectorConfiguration.PROP_CONNECTOR_DESTINATION, "s3") + + // The emit method retries sending to S3 indefinitely, so it only needs to be called once + props.setProperty(KinesisConnectorConfiguration.PROP_RETRY_LIMIT, "1") + + new KinesisConnectorConfiguration(props, credentials) + } + +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/ISink.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/ISink.scala new file mode 100644 index 0000000..50a77b1 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/ISink.scala @@ -0,0 +1,26 @@ + /* + * Copyright (c) 2014 Snowplow Analytics Ltd. + * All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache + * License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the Apache License Version 2.0 for the specific language + * governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow.storage.kinesis.s3.sinks + +/** + * Shared interface for all sinks + */ +trait ISink { + def store(output: String, key: Option[String], good: Boolean) +} diff --git a/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/KinesisSink.scala b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/KinesisSink.scala new file mode 100644 index 0000000..eb671c1 --- /dev/null +++ b/src/main/scala/com.snowplowanalytics.snowplow.storage.kinesis/s3/sinks/KinesisSink.scala @@ -0,0 +1,173 @@ + /* + * Copyright (c) 2014 Snowplow Analytics Ltd. + * All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache + * License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the Apache License Version 2.0 for the specific language + * governing permissions and limitations there under. + */ + +package com.snowplowanalytics.snowplow.storage.kinesis.s3.sinks + +// Java +import java.nio.ByteBuffer + +// Scala +import scala.util.Random + +// Amazon +import com.amazonaws.services.kinesis.model.ResourceNotFoundException +import com.amazonaws.auth.AWSCredentialsProvider +import com.amazonaws.services.kinesis.AmazonKinesisClient +import com.amazonaws.services.kinesis.AmazonKinesis +import com.amazonaws.regions._ + +// Scalazon (for Kinesis interaction) +import io.github.cloudify.scala.aws.kinesis.Client +import io.github.cloudify.scala.aws.kinesis.Client.ImplicitExecution._ +import io.github.cloudify.scala.aws.kinesis.Definitions.{ + Stream, + PutResult, + Record +} +import io.github.cloudify.scala.aws.kinesis.KinesisDsl._ + +// Concurrent libraries +import scala.concurrent.{Future,Await,TimeoutException} +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.duration._ +import scala.util.{Success, Failure} + +// Logging +import org.slf4j.LoggerFactory + +/** + * Kinesis Sink + * + * @param provider AWSCredentialsProvider + * @param endpoint Kinesis stream endpoint + * @param name Kinesis stream name + * @param shards Number of shards with which to initialize the stream + * @param config Configuration for the Kinesis stream + */ +class KinesisSink(provider: AWSCredentialsProvider, endpoint: String, name: String, shards: Int) + extends ISink { + + private lazy val log = LoggerFactory.getLogger(getClass()) + import log.{error, debug, info, trace} + + // Explicitly create a client so we can configure the end point + val client = new AmazonKinesisClient(provider) + client.setEndpoint(endpoint) + + // Create a Kinesis client for stream interactions. + private implicit val kinesis = Client.fromClient(client) + + // The output stream for enriched events. + // Lazy so that it doesn't get created unless we need to write to it. + private lazy val enrichedStream = createAndLoadStream() + + /** + * Checks if a stream exists. + * + * @param name Name of the stream to look for + * @param timeout How long to wait for a description of the stream + * @return Whether the stream both exists and is active + */ + // TODO move out into a kinesis helpers library + def streamExists(name: String, timeout: Int = 60): Boolean = { + + val exists: Boolean = try { + val streamDescribeFuture = for { + s <- Kinesis.stream(name).describe + } yield s + + val description = Await.result(streamDescribeFuture, Duration(timeout, SECONDS)) + description.isActive + + } catch { + case rnfe: ResourceNotFoundException => false + } + + if (exists) { + info(s"Stream $name exists and is active") + } else { + info(s"Stream $name doesn't exist or is not active") + } + + exists + } + + /** + * Creates a new stream if one doesn't exist + * + * @param How long to wait for the stream to be created + * @return The new stream + */ + // TODO move out into a kinesis helpers library + def createAndLoadStream(timeout: Int = 60): Stream = { + + if (streamExists(name)) { + Kinesis.stream(name) + } else { + info(s"Creating stream $name of size $shards") + val createStream = for { + s <- Kinesis.streams.create(name) + } yield s + + try { + val stream = Await.result(createStream, Duration(timeout, SECONDS)) + + info(s"Successfully created stream $name. Waiting until it's active") + Await.result(stream.waitActive.retrying(timeout), + Duration(timeout, SECONDS)) + + info(s"Stream $name active") + + stream + } catch { + case _: TimeoutException => + throw new RuntimeException("Error: Timed out") + } + } + } + + /** + * Write a record to the Kinesis stream + * + * @param output The string record to write + * @param key A hash of the key determines to which shard the + * record is assigned. Defaults to a random string. + * @param good Unused parameter which exists to extend ISink + */ + def store(output: String, key: Option[String], good: Boolean) { + val putData = for { + p <- enrichedStream.put( + ByteBuffer.wrap(output.getBytes), + key.getOrElse(Random.nextInt.toString) + ) + } yield p + + putData onComplete { + case Success(result) => { + info(s"Writing successful") + info(s" + ShardId: ${result.shardId}") + info(s" + SequenceNumber: ${result.sequenceNumber}") + } + case Failure(f) => { + error(s"Writing failed.") + error(s" + " + f.getMessage) + } + } + } +} diff --git a/src/test/scala/com.snowplowanalytics.snowplow.storage.kinesis.s3/LzoSerializerSpec.scala b/src/test/scala/com.snowplowanalytics.snowplow.storage.kinesis.s3/LzoSerializerSpec.scala new file mode 100644 index 0000000..e17f3ea --- /dev/null +++ b/src/test/scala/com.snowplowanalytics.snowplow.storage.kinesis.s3/LzoSerializerSpec.scala @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015 Snowplow Analytics Ltd. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package com.snowplowanalytics.snowplow +package storage.kinesis.s3 + +// Java +import java.util.Properties +import java.io.{ + File, + FileInputStream, + FileOutputStream, + BufferedInputStream +} + +// AWS libs +import com.amazonaws.auth.EnvironmentVariableCredentialsProvider + +// AWS Kinesis Connector libs +import com.amazonaws.services.kinesis.connectors.{ + KinesisConnectorConfiguration, + UnmodifiableBuffer +} +import com.amazonaws.services.kinesis.connectors.impl.BasicMemoryBuffer + +// Elephant Bird +import com.twitter.elephantbird.mapreduce.io.RawBlockReader + +// Apache Thrift +import org.apache.thrift.{ + TSerializer, + TDeserializer +} + +// Scalaz +import scalaz._ +import Scalaz._ + +// Scala +import scala.sys.process._ +import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ + +// Snowplow +import com.snowplowanalytics.snowplow.CollectorPayload.thrift.v1.CollectorPayload + +// This project +import sinks._ + +// Specs2 +import org.specs2.mutable.Specification +import org.specs2.scalaz.ValidationMatchers + +/** + * Tests serialization and LZO compression of CollectorPayloads + */ +class LzoSerializerSpec extends Specification with ValidationMatchers { + + "The LzoSerializer" should { + "correctly serialize and compress a list of CollectorPayloads" in { + + val serializer = new TSerializer + val deserializer = new TDeserializer + + val decompressedFilename = "/tmp/kinesis-s3-sink-test" + + val compressedFilename = decompressedFilename + ".lzo" + + def cleanup() = List(compressedFilename, decompressedFilename).foreach(new File(_).delete()) + + cleanup() + + val inputEvents = List( + ("raw1", new CollectorPayload("A", "B", "C", 1000, "a", "b").success), + ("raw2", new CollectorPayload("X", "Y", "Z", 2000, "x", "y").success)) + + val binaryInputs = inputEvents.map(e => (e._1, e._2.map(x => serializer.serialize(x)))) + + val lzoOutput = LzoSerializer.serialize(binaryInputs)._1 + + lzoOutput.writeTo(new FileOutputStream(compressedFilename)) + + s"lzop -d $compressedFilename" !! + + val input = new BufferedInputStream(new FileInputStream(decompressedFilename)) + val reader = new RawBlockReader(input) + + cleanup() + + inputEvents map {e => { + val rawResult = reader.readNext() + val target = new CollectorPayload + deserializer.deserialize(target, rawResult) + + target.success must_== e._2 + } + } + } + } +}