From 46b16c917e404befe471998f56ba0fe6dea66001 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 3 Apr 2012 16:06:36 -0700 Subject: [PATCH] support nodata for paletted images and allow user to set nodata on-the-fly - closes #1160 and #1161 - refs #688 and refs #730 and refs #50 and refs #1018 --- CHANGELOG.md | 4 + plugins/input/gdal/gdal_datasource.cpp | 9 +- plugins/input/gdal/gdal_datasource.hpp | 1 + plugins/input/gdal/gdal_featureset.cpp | 79 +++++++++++++++--- plugins/input/gdal/gdal_featureset.hpp | 5 +- tests/data/good_maps/tiff_colortable.xml | 16 ++++ tests/data/good_maps/vrt_colortable.xml | 15 ++++ tests/data/raster/dataraster.vrt | 45 ++++++++++ .../images/support/tif_colortable.png | Bin 0 -> 26726 bytes .../images/support/vrt_colortable.png | Bin 0 -> 7308 bytes tests/python_tests/raster_colormapped_test.py | 38 +++++++++ 11 files changed, 196 insertions(+), 16 deletions(-) create mode 100644 tests/data/good_maps/tiff_colortable.xml create mode 100644 tests/data/good_maps/vrt_colortable.xml create mode 100644 tests/data/raster/dataraster.vrt create mode 100644 tests/python_tests/images/support/tif_colortable.png create mode 100644 tests/python_tests/images/support/vrt_colortable.png create mode 100644 tests/python_tests/raster_colormapped_test.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e42b0dda..e84eb42f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ For a complete change history, see the SVN log. ## Mapnik 2.1.0 +- GDAL: allow setting nodata value on the fly (will override value if nodata is set in data) (#1161) + +- GDAL: respect nodata for paletted/colormapped images (#1160) + - PostGIS: the primary key, for tables containing one, is now auto-detected allowing for globally unique feature id values (#804) - Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentially radii) diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp index 1bdf85ce1..29303bd5e 100644 --- a/plugins/input/gdal/gdal_datasource.cpp +++ b/plugins/input/gdal/gdal_datasource.cpp @@ -78,7 +78,8 @@ inline GDALDataset* gdal_datasource::open_dataset() const gdal_datasource::gdal_datasource(parameters const& params, bool bind) : datasource(params), desc_(*params.get("type"), "utf-8"), - filter_factor_(*params_.get("filter_factor", 0.0)) + filter_factor_(*params_.get("filter_factor", 0.0)), + nodata_value_(params_.get("nodata")) { #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Initializing..." << std::endl; @@ -242,7 +243,8 @@ featureset_ptr gdal_datasource::features(query const& q) const nbands_, dx_, dy_, - filter_factor_)); + filter_factor_, + nodata_value_)); } featureset_ptr gdal_datasource::features_at_point(coord2d const& pt) const @@ -261,5 +263,6 @@ featureset_ptr gdal_datasource::features_at_point(coord2d const& pt) const nbands_, dx_, dy_, - filter_factor_)); + filter_factor_, + nodata_value_)); } diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp index 4aa841371..4b2d2ea9d 100644 --- a/plugins/input/gdal/gdal_datasource.hpp +++ b/plugins/input/gdal/gdal_datasource.hpp @@ -57,6 +57,7 @@ private: mutable int nbands_; mutable bool shared_dataset_; double filter_factor_; + boost::optional nodata_value_; inline GDALDataset* open_dataset() const; }; diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index 7546adf3f..14bf11ee5 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -53,7 +53,8 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset, int nbands, double dx, double dy, - double filter_factor) + double filter_factor, + boost::optional const& nodata) : dataset_(dataset), ctx_(boost::make_shared()), band_(band), @@ -65,6 +66,7 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset, dy_(dy), nbands_(nbands), filter_factor_(filter_factor), + nodata_value_(nodata), first_(true) { ctx_->push("value"); @@ -241,8 +243,17 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) float* imageData = (float*)image.getBytes(); GDALRasterBand * band = dataset_.GetRasterBand(band_); - int hasNoData; - double nodata = band->GetNoDataValue(&hasNoData); + int hasNoData(0); + double nodata(0); + if (nodata_value_) + { + hasNoData = 1; + nodata = *nodata_value_; + } + else + { + nodata = band->GetNoDataValue(&hasNoData); + } band->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); @@ -340,8 +351,21 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: processing rgb bands..." << std::endl; #endif - int hasNoData; - float nodata = red->GetNoDataValue(&hasNoData); + int hasNoData(0); + double nodata(0); + if (nodata_value_) + { + hasNoData = 1; + nodata = *nodata_value_; + } + else + { + nodata = red->GetNoDataValue(&hasNoData); + } + if (hasNoData) + { + feature->put("NODATA",nodata); + } GDALColorTable *color_table = red->GetColorTable(); if (! alpha && hasNoData && ! color_table) @@ -380,12 +404,25 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: processing gray band..." << std::endl; #endif - int hasNoData; - float nodata = grey->GetNoDataValue(&hasNoData); + int hasNoData(0); + double nodata(0); + if (nodata_value_) + { + hasNoData = 1; + nodata = *nodata_value_; + } + else + { + nodata = grey->GetNoDataValue(&hasNoData); + } GDALColorTable* color_table = grey->GetColorTable(); if (hasNoData && ! color_table) { + if (hasNoData) + { + feature->put("NODATA",nodata); + } #ifdef MAPNIK_DEBUG std::clog << "\tno data value for layer: " << nodata << std::endl; #endif @@ -422,23 +459,41 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Loading colour table..." << std::endl; #endif + unsigned nodata_value = static_cast(nodata); + if (hasNoData) + { + feature->put("NODATA",static_cast(nodata_value)); + } for (unsigned y = 0; y < image.height(); ++y) { unsigned int* row = image.getRow(y); for (unsigned x = 0; x < image.width(); ++x) { unsigned value = row[x] & 0xff; - const GDALColorEntry *ce = color_table->GetColorEntry(value); - if (ce ) + if (hasNoData && (value == nodata_value)) { - // TODO - big endian support - row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ; + // make no data fully alpha + row[x] = 0; + } + else + { + const GDALColorEntry *ce = color_table->GetColorEntry(value); + if (ce) + { + // TODO - big endian support + row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ; + } + else + { + // make lacking color entry fully alpha + // note - gdal_translate makes black + row[x] = 0; + } } } } } } - if (alpha) { #ifdef MAPNIK_DEBUG diff --git a/plugins/input/gdal/gdal_featureset.hpp b/plugins/input/gdal/gdal_featureset.hpp index d4a2e9db8..b812da815 100644 --- a/plugins/input/gdal/gdal_featureset.hpp +++ b/plugins/input/gdal/gdal_featureset.hpp @@ -29,6 +29,7 @@ // boost #include +#include class GDALDataset; class GDALRasterBand; @@ -47,7 +48,8 @@ public: int nbands, double dx, double dy, - double filter_factor); + double filter_factor, + boost::optional const& nodata); virtual ~gdal_featureset(); mapnik::feature_ptr next(); private: @@ -67,6 +69,7 @@ private: double dy_; int nbands_; double filter_factor_; + boost::optional nodata_value_; bool first_; }; diff --git a/tests/data/good_maps/tiff_colortable.xml b/tests/data/good_maps/tiff_colortable.xml new file mode 100644 index 000000000..c102ff363 --- /dev/null +++ b/tests/data/good_maps/tiff_colortable.xml @@ -0,0 +1,16 @@ + + + + + 2011_5km_vrt_nodata_style + + ../raster/dataraster.tif + 20 + gdal + + + \ No newline at end of file diff --git a/tests/data/good_maps/vrt_colortable.xml b/tests/data/good_maps/vrt_colortable.xml new file mode 100644 index 000000000..d20367c72 --- /dev/null +++ b/tests/data/good_maps/vrt_colortable.xml @@ -0,0 +1,15 @@ + + + + + 2011_5km_vrt_nodata_style + + ../raster/dataraster.vrt + gdal + + + \ No newline at end of file diff --git a/tests/data/raster/dataraster.vrt b/tests/data/raster/dataraster.vrt new file mode 100644 index 000000000..26f6b5cfe --- /dev/null +++ b/tests/data/raster/dataraster.vrt @@ -0,0 +1,45 @@ + + PROJCS["WGS 84 / UTM zone 30N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32630"]] + -1.4637000000000000e+04, 5.0000000000000000e+02, 0.0000000000000000e+00, 4.8596780000000000e+06, 0.0000000000000000e+00, -5.0000000000000000e+02 + + -9.99000000000000E+02 + 0 + Palette + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dataraster.tif + 1 + + + + -999 + + + diff --git a/tests/python_tests/images/support/tif_colortable.png b/tests/python_tests/images/support/tif_colortable.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0021b38d731fbd7d0b259d07341fff6893cd8b GIT binary patch literal 26726 zcmeEt`9GB1ANRRtVQd*?7e?A_g+WEkD4`N6yNYf*S-P!}=Ax9lTWC?1FhzEeC0m-Q z?%PsiPxk3nmSoG$n0b!x^DjI~Wg zs2_P7yN#zR&9`nmV+Xd$+4G)|j8agL8P*T!YH(JVvLw&pSI?a!3YmWnhI`S2vp>0$6r z?y^63`9xt`FJ-ff5+kRQzY%x`{^RR{dW2^A&v%oB&j$Wl9LFc`oW>&4HW{2L2FHD3 zw5@;E?_z$4`SAT}*Uxg;UO{;P*KEK7M zM~aTRXGWpQAePDG2kmC-7PR#)iDDeWCs35)L?*D)6ka`I3yD#@H#h9lyw7mnE)WgZtA*r-zl0ST`FT8J$r z(FfRBKz-r5|0{ZSmyW{o9CM*d8+ud_O~0eWbv^K=ZAo(VYrYK?C^^}VXV=*xnK@w&*utj_X9 zA`^+S2~wK=$8+e@Zuc=P1@y}&i8g_YD9FTjdH z2NJ6*mSoOz^++TaG`C5*Cc!chkDgAsa@@G1&gB>}=qYFQbTd_@g~1Q@E|BhNMR0d_9&h}ZC6~{aI(y*AdzaFXi0152@?RQ z2?WTj=Vx&Xj;t5Fc1O^gQ7waOMVBK4!y4Wcl1Tg*sl?ih(BtoZDiH|LIg1-k7jnY5 zQyRSoMib0=!v^3JU!+P*Hym%L+7DNCvTfh}&C9RpZs)aL_~XduJ{QK@jp0UPl+_uZ z3JcS*buPE2mCL!-U{%*L;<$OR^1kE8e_sR@lAOP=v!>XgY21@UbpdSQz3?TUlBQd( zz}e&eE}UTjhjX)WcNQq^TvY?Hr?BXLT-arj51kyb7>ZEE2%cjlX9TR0T|^gm^&aQJ zJa^#3of9(BIt>ilZ8kS~y>AaSyzOG|0d#x#WL)}8ff-d4SG1D<+1ctQwW406%Te2* zM13>8z>FL5jD^M%qlfoLobK+5W9$I#WMpxL?0!;cBpOxjD#6@L8gsh*XG#SvX|e=7 zu-|W2{9fcWixOfDT{M}F!#Fd&+LKA zoP8Ly@gK!H5(bba2=EQtWIq?gjYODKUK}fN1F8f`LsI`W6T$OjWA9ZF0P|a{Q4Eh3 zHG6#5;N*QX8KEu3j-+uihosj~bNI3a3@)*zby7JP16u!VS4Bgz=ps1H^y0>&Y71?j zH*KYogO7?4>6MX5YoRH>nm+DYWWt;wwWd)!@t>b>FVAT}l+6(vXvdl~gp$EKjbf<>k3zQpRDB&=I)&OdSRSnvWw z4Vo}$32G8K{)5CMTbBxeqeNm#Lpz{e4(P4H;7JLbZw>;$)!96fIKFTM~8?3GAc3A7XeF~R(#{K7OghBLjYt<3W~un;g^y9zx}xPtL=99#m|M zlE(K{2pQCRw~bKhEmnPu$_M-ilJXQR$U1vXfm&_bVbh zQ(+7wdxj27-2biLJ}_yUE8zj0lhzz%ePi-X;%-d|Hkx16a`A2%iy4K*uRAoQAUY&Skn-JzG{hG&vUFqN5Uh@WZGkk=#X-x3w z(I&lRqC^JRq|*L1^=X(ZUU}Y7ghY=Aj^2=u!uX4$g$Ny}e?bC(`laJ?F6&cH+;zPZ zf>(YlS>x-V}=}MVub>R#LPU>e4tD-!hGdN_) zU-8N%Zmv?uI(NoALL8VM=9!S}6D~-Wza)g@rcpfF#l{W>CuXSPHm~R+=+skxz{){( z0j5-^m=wsn1=ip2gX9>v4)XYd{kRqYT6H=^xI!Q|*)wJhi=i8?V~bu~?saLPg&Kn1 zs0=?&QVu1g>B7bYcd};ebNy1CAPCDrvSpE)d{8SI@MiC9NW%E-)EyEO&g!Uym!+lt z9%^P|3cbqaGLPxe-t?Z=cU$g`Uq3~pmXv#g!>vXt2&=;7=IhfmP-Vd8Y_3+{y}~R~ z$k+ykmC)F0rm`=3uD*<5QQu{Jf1|6SU5F0VQ~ z{Jjsy!N{3}K{9kv0*D)%#iOxjZKQqN_5$LZcQfr#i&OY7Rh(7aT?-ug)1^}PWZ`Hw zqg*amHdIGIJ)|?E6|L|BN?3IPa0q8fE`-t1wO?4NaD$lz=!Voope2r@Z@e~LHNr6; z46Nv-D+aIc1VBrPBRpz4;=)OBbG7({vr1uj;4<*QV*Dg+JPJRv>d`{`l~=3_{7x_l zaO60^Gz8j&zx+ktD`Z_SlDN_NgcL+0k{MfYt4 zRB}={HkszG()W;zh~>|D4jtzKGx2|(;J5oIZ4~dAwr%bJ?;BnBT4nSm*aj*@e0ad_ z<9|m3ULZy+{bTW9WseU>gpkJr{O>iZf?q@clpk}@jlXwqUc`cf1S>a;vh(H2Nn2Os zx#F408tZ^ZO8nme9IW5a#~$5qs2i!mV3b?U$ld(lYtnizVCwqYgZ8)nUzE`ufR*O| zRwG!Gu+!P9UAna%!poziL=Dpf10kT9@2+w>QRA+<`H2x@B6j0Jr^Xj${N$u~rC09Z!-VL{hM`qkXaNtP*mcE0TLu{PN!+W(bk-BBgB zJWZP~9}D5xspspJ-7qZ_(2Hx&2a|8Y1@B1@oFX)t$#`b^cdwEGDLwZ9m>c#vhC%bz zOj_7eB@E6@cSAr-ln8C?mgQ_xR|Ee=dnF#-MCZ+;F6>41sxA@c0F?)qy+YdsjPC9aMNkh;CI;mt995)!p4+3Z zu!A)pGoQhqT02|Xq^9wP&`48jHn1Q`WH=Fqj6NbQir!x=Gk zKjJ@zAk@4(aNzO08^XjQ_at_na zGFMiQ43Ce3ECT`HmnF~bX&HGa7JH2OOY|LIgTEUHaYYJH(w_%v{!{bvqF3y+EZ~*& z7dKkrZ7&1e-&JoiT3gGr=pp3_77fn56HXY#>A@f@%9GeB2grx84*=6=#znsNPj7m7 zxk4*jk>o7(Hs~|i*lgf?^Y6h)t_*nDI9L_Wq4vB}|b>8m7h7 zNx6$7MTi9tf^USFAz=tp&))z--xtUk0ucxrpOveJxoZP*=0&m^s!V%Rqkfsq2!WtdD4$^83O&IH^$65wbhP+APAJ)8JQN|KBy;sUxb+Xby$Gk0Yct{kx@)nPD2hh>4L*F=gIdq(j1UV%ge z{iw=}57fjkk-d>RpuMhUIvOpKn$_W&=_vzd*2Nt8lYtQm%>Hlp-UD7_up8yUCP^vH zq!vp5YkMI<9N1NYj647w4r*e7m_6!wxAvHd0-Yad5m<6EDLi?%6##ntX-dg$)E*rE zmu(S+9$0V^LN3^#ocL6l7|zIGJjLgae=AilhMom;#$up-%0(Nv@^@xnkX(TBAU%MZ zzzt_eWOIE0RWn#v)JVaZ2bhz&J4nv3DJaQ|0={*&d_1s=O#y9-)Cy6;w8QmpyAft?2;8ZUOryQC0OkF5jj(qZol`# zA-Cm}v;V0AyI@SJhR0o;%1{1=_{d;ui7TUEuG;^(ErnwEGWV^xg$pbQ+CR34WbGRoLWX> zxbByIX^b!LY_aHamES^Dnb0|Lbn4e+@a{9h?Y{sXldppwLsxV!@_`PY1M3+OV)fp! z5?mDpO`;fg>otcY;+zqXOgO|324BTb=YjwlLs)4~%jU8$cDu9Hn(F zi^Zn;xH~+5zKt~SnIGi6#J9&~lDSt?=7L*go%`DmAdItIV7T5ZbvNnS*Rt6r`8G+U z$sMD5ZKXPMNMPhA+iR(c2kGnvwq)iRUQ;PViJYi(H$5skrT=D&6$qWS0?aUd(@KT2 zfMpOW3_Q;x4-`BE%T9?AEmQFAB$5L!3lF9bzZiW!on08yFna)y_`r7DpmAG$Libg7 zRC9Dg_n$E#Bd#z}gLx(|KZDkqVdpj5+-iT#nyPI719-_Q4&Y`z+F) zuX&hoth27SHMOM*!~H?C($=Mjx z8-(?1p^fau`xHDnA93Wy!ENf(27sm8%l}~|`p%)qYd@Q4PrkJ!(;C`6j@?B3&pL}^ zc3(Y@yChi(Gn2P3HCl?8__8l42DRbY&ky>wAb!m7Leq^i@zKAu(9mmt{QJtW3y3G$ zcY%)klqw40&^qH~9oDQ)0#ulX>;Xn&CqgA@-q>jL*7IF@GCiKmktr(elki))vbicp{yJV?M$c`!B@ zSPxQ;&}KeA+X*i8vXF)$EU@9ND|mK)(e2J!;Ox~0lMrHmnW*nHGfd-8Mxq1-UA5Bm zla=<7W62Onw5}+6``o#CeT0;6IQBZJ?(aH8Qd8~as zVLot7UOVy=leRvYTUs$bVo7pCD$GzAnP@)NqgDV z`4iZ<02Ox1#HBb0=Qv43x`9`%f3f}LOJ*_4whS2LplbN zogWjomXJl`XLV8+IC5|=)q~R7vvQ!+1}Wk}WiS&bp6Of2Y?jC^nf$$3A;K+MGa)$_ z3C~?21}fuPs5h4nTR84vB_qIZ4+y>IrohAiUu{#^4rqQ=1)e3L+d&)=q6x@bIbK$O z`+C{n>DuXh8lYzFl0v8Ew*#vWXzug{6Qy_WR#za`$iGk`xnvRrS3CxUXJ`@HotXl7 zl}AxGTYQQDy3zksZGSp~&If)0OaY|-5vpCg0!}nQ$_iG(U3ZUBgZ{c)!Ad;6+10_F z&=?JUHX!4K08z{vKssY#6~+AN5}*3kebpW$j&0~6%rrb)abBK~=4kAs|Kq-^?*3;~ zJc)FKipQDuj{nkv{nOE$DeXo6uBuCc+Q8~P8u|ievwRoV;nmtthbnCMFscsP8^aCg z_5{27MVF-c60=R)RLGku;_PnId+fpl^vQcKZPq^Mi^#A|;)^xMwj6``2*KqxOpya< z4ru%ZHtUxM?LQ>ABV|B6n(AJ~d`KdBb1w97|8C(zwae}#R3%bHF)v5bojFg;wP?lt zjDEHns6O-lq4Y2x(vh?q0>}5qv-d)r-|vko6G{QIZXX)7O^uLv7hCS`>n33Xm;|Ul zgz4gpTAWU829DJD9lQY5tI`4;?&%7$9IZ|4zv-jH-lGX2@9!^d)*)yrju-62*_}R+ zHCBI)oT%{brpzfEJy<(UbXLQr$AH#lS2 z%426**)`X=e)5C#Wu6M3-kppW)>)h0pt=GJ4s`6I`lMImFd3T?wF>CRhv~mj)EzyS zbMF}X<)u9#7DL5h%IpCjVPdwvZAb`^?NM1GJ&MV{FiyHx7)|uuY5p`kbGvtWa~I#4Djj{)+6nd?#rC*AgqN^Kx*&jb-o1>G=4?HUL7Xg zlWYgH1E+ubnKBuYk(jB{&(?Q?yl7DDUrr^Fh17jG zJGTaU2nULMfn_R>Qij<2TT%-_(8|#8d%dP~!Z^qND?#MY_6iwwf>c}M9NAJU;Jqgwj z<~&|IsYnw7wHxf?-NRs_a1#*gD`&kIa%V5QA+;oy)q;G&@l>QQapl*vYi@te`HC5JJRT3as*9F>x z*)b!SflcF%cu-+XO+7F-9Pun%nMwY=;>V}DRV|9tueasNk7e3KVCl4`fweXs;OuKm zN`1ZZx(5r+?S-wX>8F8;d*|Mq-errWz7}WpAG~}EuhZ1mBl8i>S2aGXRCClwxS@QHO%%7KzS-bFccnB>C2r{iTUfmvAE)z8Jn|Yt!Uu za)&_ac8sR)Umz-&Ek~%%#U9nmv0ovyYby3Yp#&Q@odsA3;`Nc)?{(I}dlEs5)&hYg zf>;Jzwap=voG*dzdKZhsI!&RxX7 zf(kc z=?*9qMZJsfjom_^4f?bCu$TcY$>$IZqN+GkK<^Q3AMa4Y7l$R@1pFW+4)Egpb=UnC z+H%(O*Fsn7<#U#KsD`aZ62K}Ms!=4L<&bu-)+&{s+Or6z3@!j>4C5e z%)L%g`^!-*F8?ug;EHK9@VQAZT5Id(bv0Bdw{MGEbNV?GL9v8UiVl~CTWf2`&fCAX zzuUh>M(BL(2qDD%5`av@c3cZo)cx0K>vb2A`Ys@k(!pS{-p!;bD;{0R{iq~gd z%36lVYNh<3dIRTa4-SGj-v@CS8y9R5pnqeA`*bo8e9Px!-9;J$l?>rgUyzFwHO{Eh z;@D5%8IX8h79tIx#*$z0@R@2fFxJz#0j zwq1WS{^+Kd*TOE9hjd?^-D39PIXKNOj0k9AMlT*NS#xwGb&bx>gi^Lrb?4n=D^VV0 z#Q9F2?J;VI>!gN#iO97*^*Onbi~gP0bv&%P<2=P73er9+1ZLV=H&VjOGr(+d^o$kha?mLXQMM>X6(p8HMXh`NO>rEG!*92{+DMAJDS@eQB$xndbkvSkCtbN# z2&}Et3lFV3SH%**VG5&;M4qckv@G3++?-V1*+=f_WHRhBxQ2k`!-TJ1tM|_`Y=$|j4XXOutitcTQWIxg zqtFD3cFEw~0JTu4T`;m?6`B(2N+N5vs&1+_hahM-zk5{Pg$Ikx0CzR`Em-NGr2bD9!5^GZC$m@A#_&9wm4zIlzE^CAvp@;O98VvRF?<~Jeb)mS`H|=Y>4LWC1HRF z;jjqYb9S+C&s{1J%NfBV`%e6$^(G-9XH!4zU(R?*m&~lPQrL*~Rtj-k+P?iQr#RKTGYqR}q_tvbk^i4c-e3QH>ijkIS~>ti-qdS$gd69>1({-7q0If95ZbZwQzTcDZ;S zc2TdryAT+a4ZIy7rf-V{hInw{=ZuR&6&zGKIE6b&WL91dRro_3Xq{jBCFb7@$>=3y z^lCsC2o+~K@Hr#QWPI|bsyPOo*PjeFB!l5Ur~;Vh!1DecC|1`w#dJc~Q=w7ea|;Y= zPH2i>F9f7CPE||r7q$|x3{1y^&!yRWe9pz_)*nKqj?J z-tG%EsPUpVX;FKALMkMT1#-A&;h;XdgWmv@!F%XnT|c|k&eA-jjNMODNvviXJXI^9zzkroI9a*<7}SQw9snUH9g2a z(y#*uftnv^XC!i%AbF_fTMph`Q;bZcyQOCP zoUJvlnL4SPnWB&66}<>9Cpx=r4eJR}z}!46*uQR}J!5SM^@O*RW~6VkQ}$|`o)BFO z_Zgr%LQF%Z9r7}Y`NC5pEBH!=PbB+SjZY${#SNJm89G$|-%F+Gr{M^-U$Uw8vZdAj z?>FD-(h>QRg8M>%bzxy#_nI)SC6#*$wvC_)R)1uwT9w*FMS~)JCTZ(>Q?&&+RE(&8 z!(5%y3+tl%!B4ILY(S&MqT<-WVk|`#;%@Zic1a)HuEvS2P~MVlytx(D}ORA#Gyu4j7n4efm{y{An)Sc7B1P zplA~~b1cun2}%}2!oxZ78Ux~9kcdax0&C1u$@O{7K7l>fV-&}ohaeX8#quI9I!qUH zm%Y%YR8FKv3P0~HgM5b<(8W{l!LpD{vC3ZNxgHk+E81>Xr;<+g9smjJm3bFWMQ+Q) zu;!Hg!-V*C#j%o$!sX{NgZr)f^%K*!xBtXeFZ?(nu^9LyKGQf@oT^LvqDl2p+zTMG zfm1vsMXg1nv=AJ{ck zVqK7skfME~#i@WVR#mF|^Y~`p`Tgym#UvcQ7)fvXoItH1 zz?C@GxRsWC%2VPCOW%~ina%WlNnv>(ls`eA!1bY<<+F;Fa# z$fBlhW98sfNmQTqukcU6YJ z8|=ux1euhVm;QizuZ|nM64~yumGs>+NBVn+MBme2*tSfpY^67Fe!(uj@9}!#VA&)8 zq%{)*mu)$!L{<*|F!m7(-O#IYO~m4+j||Ha8r$yFJ=R)y0+^2Kd<%EP;h`k2l&X1Q z$jdfl(R#0fRL!9RW3JrRUK9gH#_WA@>wCNuFA3nXtqyyP?Ie26kxqV8HkFcl=}skw zn-9)+>DU5lD1%qu9HxV5Yf$MvVEE;5!E?>cHt4R?aBQIXaB^k1vScX3@Q0BPJgx~` z!e0m z@s)korHL&S=QSUCE|by_mf2tNoce$N*bV~5W-oqn@@0$lJ`R~FX7zthAy?6zpFUi1 z6)utnlj3#TMF%rC2qB$qUpmkEoqFEMp6%VrrO~Z?@Ba9?Mn%!mZNJn)2@fdLjT8q* zr*IQq$Zm0F+y3OV?>jHLzK8-E$|n-dz*>pe9^EFl#J=n~}ypCw{{iKzYzc zJgbg!D;`1#gL8#vzG}ul98cChUn)1Naow9L2a>gEgc`z!V7hSp z->o9>m&~{Np|9oX8?XhO^|5~Jn6=TgllxL+wdkAUd36;)|4;facdVy0NAt_oML4t2 zk;oO^lSJwh{$Ua`>JA?CyBj^7PnaDTS}{yG4;Rv$49Nk|MpzVWh3*7Q(aJ?%PN+<1 z?g$K!na&@FfG2eS0{C8MxC8!-&F51d7JI46ghc>_4u3$O?H!smOxQXc&Xvo~ojR|7 z#^K}8L!qXOthjmGghdsz5dq{eUmJ$H7zx!cUQD$$?3V|@TmpFZG)g=MyNPom z&PGF#GK*V~%EUWFbh&v;dRmg9=DWt(sb6(J%ACGPPR$W!Y-)3J);LKc_5z-EroUK*Hqd zUVBkslgt=T&4{Xx;NIzoom7SmbZ=-Xq*$P{0(|ki^>|*fRakB7SU2y}DwO~Y=A{FR zw#l@hzlWgLSZ+aUf#H(#>Vg|2ut zOE}0WXeNwz-G%p2iF?z(T3OlM16XR;M_UdCo_~JvTPtvdgi56taE{E#=#?!wQLCn& z&I4;o4-%J#?GQuygSRc*+4jGI`rb2AXGAR6TOM>gk~F|2c=T6z-F+Ee>dXs%O3rn1amrjP%Q zeZ^huvS8#(OKZ7}4MWPs`Va_nI;e?PH^&Z+wVi<;JLbLr5YT>kD+#@F*PyZWz=svT z%7_PRCJ5^`nm*Qcj}6<{)(1vWEF-{r838*kW%Q~%Dgqj&qx2)70fK&fYnMOFC1;#m z^8lnjKJS}U8e@Ez(9h>8gXCuZr#SFnZ3NI?a2u1rpgZ-P2&vvaako#JQ!=H(aBEpl z=)S!xQoHoVnx}YZQ`Kj6I6ppb-ZqV$yj*4FwWlw2^=pSI5i0NJOXJVz#{j-|CW-GJSM&UlyR`zJp_+dSXBhgzoJV?}a{TBItNYx*8u=R-8l$rjeImYORC>H`n zZ;sT%c`NAjUlDVcM^HgQPmQ$T0#LRM%(-_?EVUxg2q}s)zG_^80AB2N=(nS{!VFMM zy7<#Xuf~E5&C}J7Xbl$(pcjV-3m!S^Cu{)`&>7k&y_xU;o-R=9wd+HYDO!ar?d}m) zZnJVlnQnF6!wsVa#%|d=u3Ft+6-Croe@m_&WU#k?5rqDB^z;T6TvRi?^tIbVv_fMfMbu%Sxc)S}dDKP1} zDfL1DFV;-R7`Wx_d=tc7;x`&#pvs7>)?h;yEz2`VtYqq{0&-<=3 zIO~OZs<<#J_0%R7TpvjjG57C!VgoIYnF!jqNDF1~q#yKack@;8z2LOTyQEdDLsQye z>B~tXCTep}_vhV!2nw2%I4YVDBG2V00iW*{djB>}IAPJ04q7OUNB_9PSWj)qKauGg zy^h={{WE8wViHsscSB6n&g+KncZ&CyRkekLoJDnW#0C17lMt(~^yk z7>{5->zvc+bZQGe=P3j9LMVKHS8Ew=*Nc=}mDgd9P$%Ssjq+S#h<13P`w*)5gBSN1 zZk(WWhARikT{@eSGYq=NN#)Mhei}l+ZhtZZI#stA_Uq7yNbau?JM=pjkcwBFG}fQI z=1k92(Z~OC%s*lK8UX1>lTErTXYo^SWUD+H4L-BUQ)9OA>y;R0iWt(d#NCH5Rbk(V z+EnclV-Fc0O+8XIm8mo9^r}PHn46hDFa6W+@0FQ{+_3B1<_(;i8Dp1AY1zX}4Xm#( z*RN|un%4cRc-OnT7$)?V_IZI~XKRSK!3s0EKuLWX&>h|eUo8a2QGb1i@HkU^v?_b-P*txE3YIj6Gu@wWIUXB8mZeJkh zd<*z~$P@wDN4On}N+2L~J*y$(3{2#Vefj3!--f*9ayAaG&(zJ{*r=*&<%88^zCdSk zUkWV0Vb9khNTf780AE2s8~1!y4p9I25m+JAPr(eXeX`!$;HbKdH zaTK4`$CC*n_8*+QV2_W1*P1+}p^a;0Neg=?srO>TsuJ*w*bL0#4*Y7oKS01#tW&(% z4n5q+MxBZ4R})Q7{0~w1`mfxA6*a8*r>X^c(|&XohYqEneUMuR$vrQ9QpuZUKPbGw zh1VQ`Cw`vfW%T`(Qw1w6~PTfPC|IMUKw?-^|cH3y?Upo+pRqctZkSVC% zMsAQlx#^Qd%O^7oonI3zQ&;Y+WgeWYO^nOLFngV7zQ>r=@3S|;ws;axd)XmAS$`hj zK57NN;*m@OAoniEtwjK;!+K+D-zmTv!VzLq->7+Tw6MgJT$d__hmTfp^RFZK#%T4Q zg%AnJxRMj!{(R%Ut$7<426Ixe4k(r5fWBmn3xBg4%dZBJlPnHxvju4X{D8#FE4 znDnD%bWm)o|3yF*hKfa!x#cI$3`sAIC~`HHC_mSs=D9L;GT>T!E0n3`4%?5VYL9<3 zUvXVn@#EL>;nb0wZ$&kYW^J+BPjN{3!e&M{W$0UrCavEvkVqQ($E2=C7_g4i-Ww$M zKRL(M+O%-8z@j%_-iHUtxxUY#wz)%Y@H!9k00Dp^ENBy=y~*NwFEmbY?Q6I0!i)wQ zgX-2yna#l7FPD2yMquS~&3Kq(VcPqN5uahPem;;P9rf`F(;IvZR)e%hUk9b0djyYO z{UDxC9@m}V2ZvoRN&FF%wzQuQ?B5+AeGjS!J{);47jR9_DPht!WYB)p$#=0c;ujC3 z*yuvfp+9rfE;N+8d`9#vea) z=sI=B9p+f6RX3ry@x-Mz=%R&waClLL6`3grjQY>=Au3d72@n+h?w2UE1h)UYG9w3q zWSmX{H1LGbu+MUTg-8_*7kXaFt8e7lRzM$r)MUn9HrD(4Yr#WrXg{!`qKBUEmDS#C znleG?(ga;-?l)t$@B@|2+5Gk#sCRLT>-2{=Mo0%qE<3>W4 zG}#ks&+6LlJYVLy^3ct=BM$>+f}!8wu2_zL{hh|e`jSd%j50r87NA0v*e>+{Ob-YnbxF^X7@sFJuJp}vw;<7kJ>7KEY`muN~RL>@r5}9yU z>5e%eFWI0}lcW`bpl(oncO6NCmrX(9viFlQ?&KiXb1|!7IcUWrv6vsMvg(e#KIB}d z+7;Vy0K^6jt7z^hZ#ZIYIau^6G?0UOmjNL#{2!&2ZL)uI z<`XH?9XL0zg)O*FFjgVfsqx)PZU2~!-v})o0<6dpvCQM*7-i(YNq7^AD+ulMDF~=# zL(nj@lC->kVy2NEej?5(Z3QZ$FU1kp`R55wC$%E(>@lShs0VWEHbboLl zJfWdXD~kUhu}Ye2k0!$ACHK z+4Ip0^1#+&B4OXxp2Y5*T=b#IBX#(7MRQ`cOB}a0GS)yC<>694Iuj z7w{|21$o;vR)1vIti($PjvXe?emgRv*FyPS(?&(DDWpmh@?spkjKY+HrnbSxF$8*> z-hhC~^?2B`h#}z!IDxkBX=c|AB*9kAK}AJNm#TX&;K7#-*C(Rh z)AN$Lyg2JI3k7F9X!n9QMkWkEc_Hu=LPPGnpSdCMvzIrS`vRI?l>gwdzqy$F?SM;y zm6wU)Mz~6jQ+Dq~1XiA6444hSG4)DnL0*B50okMdcrd68ra#{r+7u7EE$7F1vNf$( z1*_Do<*K;+h%RQ|9>>0>EuWLS8STf0Z3xm96ORF}!EFOb zT6o&>0Oc}}l;bZI@%Vw=jnBEE|s$p|qjiL%auxUjTLMjQ;rp#3&X7g-Rh z;(P$>YzX_Lb=a)XFWQ5NXw=L@9)DYwsP5BL&NHh${L$spFN3f~r7?brf39!YT*lKYVA5GrM1mMdye}Fo` zOBoh>fL*4)+fOG40caO^VoZJvSeN)L@gTK!L(Q|qz`0KzQfl#MdnTNwa28UVu(vjQ z>befq&?6>fz`Q7&(WaBO+^h5cS>5-m5r|PjrkqOs?Z%L+F!^{u?asuPfc^>i4{1ZY zl_|qSgH?wEs{z(=oFhA$Bx$xhFkP)AgDdX7{c|&NF+BN*L?N8bIvEi4zrf4u_UKs$ zA!za(Wmt{AjDop?+p{$XvFTshJCb3|5OlrA^#XLMHC0p3`%%m*0htlGYtV(dxSpc_ z`Bi$SC{tfZ-H+gE$PBZk>WVRkhI|KA(3j#9GbN<``EW7vuiR-%(FUy9R|23wlTWVP zK?vy_zm&e*2AJ?uu-K6sY9BOSpT%x@1+}0w3QgrG`ckyIzjw&P&=La9!{^Ad2GdOi z@EQu13`#$?6pT%UCNp?IUz@UY|M;6O_GEZi?eUC5JBT%pz3L{-QRyvXYml<@({1!m zm=_ywyJWF-8-)*V)$K7jwKbm0zU!N`FUhvYPznAwKOyAY(&tqu78W8-u4fqTi>Vc< zz~b@b+b>$B&wTG;(8qZC5*Q2ut^9FBR0$n9jcJ+*G2Bu;_qR&UHRsIwjzZ%J9_iy} z%Ywv|&U{Ty>{?*jcTXa*nR>EO`*omdQ#rg4%s=Ofsh&g*2(%9!4F33WcW{;PIT&pd zuN+0Ff*qYLhapm+zh^`7sexS%h$j~u9lwQ>5jjG8{NM2$CD4A1c~u+6sQL=imz~w1 z3e<4dU4&4)4~lN-4GCRwd{AKM2+6nA=^Lf@l!p5aM8KIngv z+(NH>JbsC#emfT%b}^egc)?+)u!TLXMd;FR)6zUO6Ap#Tg!&%@(@4 zn^=mH&OIR_z(S3hV}N3qkynN`I}cp#Enb!isgl^5OQY8pV6MS|7hG|mDV4TZp0CCJ z^}C(`FPpIJh;%VQ_kNw%5dK^cN68ykpHPc+P;+ct3>2s8@tEo2R8wic_p_4# z5k#Ya(uty@0v4(w!~{n{!GZ-4kTTLi+JF=pNW_^@k!Ar6Dr5vi1VIG`1T;9lBPd|# zyddorhoaI98cLFV{@b&@yYJ$=`7X{{=f>p<+1WeKe)hlpN@f^nCqQeWobqwoH0S=-JKDl}hpe zyVUCkmT))`bl|d&nczJgd|#=f8Qn{&LZf4KjK6da;tSb>OuI_jJ$>wzmj*VZw1!pl z{3mf5pd_hIT_+C9o>QXJ6-W+QhS2+6RQ_wPgY%rz669ctX;Q+*@o+Wz9bo}@3t$l0 z+uTvNxi&V`evgzFq%nf~!|jP_R{gZ>T7nUZJXdEc6p@I306Wm5D?sb)SElMfqc?*> zYN&td*jrNVAD~@BLo-mIv_8;$EvRF4H8BL2Rfkf?j3gF%JbjCWQX}?T&l-sAu6a9- zo<~78EEfs$FJ#Itq^56?yAIP*8e+iy+~J}obkF$H1JlkbjP@o?#ylaE)xF}v*0bQ? z0OAwCAeNE*U7u!vjx&s2$7SBZMc$ad)sTdd`_%wu%#`>uEOKglad@fiJE!M(@fDkt zGb4;BRb0y<$MpxvpbW}3V66wHpoi;Tt2L}%jUl6tO(C2%2DT2qCwlfLhP7buO^#gM zxiHfx-cPgF(jN!~qJ3|+VZv4vWBpIhsp=#bFe~A`n(9$ABw@V?5c8=#7HbL{dbY-% zLV7g?aj&v^@wu~GeP6%qMi|X$>OL&f8J*QrtkNJkzOtp=Pj%1*RjPLrlSI05;5-Fu z8?jhL3Cm@Nna-fkB=2)^a4HJE9xUZL$UD56QGdwU47ovlqEz{yC}Q zr|+2xDDSi!qst=u_7YyVV{{xZov1_n>-m9tp1;66Wb7Ed&a1khT$k($*-b4}8CAXC zUD6P;3e~oww%Q$TKa4(Iwvn=r3)4_gqo=qnXqmEiE{q}o)vFi(l{{wJ-LFkJzLeV< zHRz$~-GJsWSCC#UdsfX@G4{X&S3}dqf2Wl^tkj$EBX$K9#gy1hmgS>uyE(^c`>Z%M zq2DX>6STT`*|tblw8swJK=EwW#}J)$V0-iM>e9CM*N_@~*K#=3-L3&rkSsY4#U*_* z0a`I+N^R8Q2qSyXT3O2xK?S$wi2W<^Qy?pRcCofT&zVdJbL;~qCr*U|$iY}Ee%8Fz z;H4hWJk~qjnwA&32a5*;p1wUfK2qS-Lv^GD^Cri|a#CHxsFEqW+91qv_^~S&O$vGS zgZ;QwDH!DRW*E*LSmo)v?x{TG?zTriYHhQhF+Wk$y|+!;)wZ(;rQeco*djNp3`J<2 z9;y7f((QSGw#)m0Lg_;)KMU8iJdvPmJp2+V=JIn$SkV*G2LH}j(e1d`pUX5PVIzV~ zPvm)^614?Tu`02O>K&W35h{!xg$MG$#WdN*CWg;E2Y2#V1L-(ul_b>%B}(9+fGle! z99V$s_g>$#3Kb_-1qyF)Y(djZ*(b=5Crw4P^mkj)a^YreIz`b}^vj>gNmsm|(4Q)F z|7oG;3cp|(NV15MZn+%leL9lhr($m{2vsJTaMC>=)|8&7!`$D$_22)AYi7mu9cyAL zn7WN<#^!LnnrPK$cv^&&+7cnx`6SaM(7D2AzoZ!kXKY66R0B>t$m%G0t0hzXXaVu31 z`k~&)XtDOOo2CM#X0TN{v>jT9i@TBOkDD}rSie~btSk<#K+^{f$JFg1Q$qU_H~cu% zJmk;Iomk$|A8loS1@56<9jJHsr{jz`yQSAg5qHIGJUygb=7x&l5H;a3F%TN7W z;}72GZCr7G{3?nHJkAqW5BwFhHk6FyvBTSN7}2DxJGva83U?v2f~ParW^Jw-tdWPW zba3G$LM;~{O;22HT6=0;Sv$6YW7TQ6CsjA7r3ho)viX)*$RJRT6+%(+pNxq2+GsjS z`*PGTM_mJIKr@y-JTY1H-4JZY?lRw_0ona6kE$6*uDJ(@0himn-~GPvG9;m zF^Q8rZ!^;Ou!HaOrBVvex5P?wX>w_!mcHD^whoAbb~#GPIt!kVpMlvBnCj=F&i-xQ zHMo()TGy$$sbu&-KU_Q1CUsuY+cO>u|GA)ZoHk@c^3viI>4Tdk|bWjJ{;?Wq{~ypF27$5e?$sgj7}LJ&bt@P55my2oGXsN82h6oP`d3@EoPzb+5&nuD(7BNf-0t%)^@M|TaV2>zr!N$Aid3EZAZU(Tu}Qh>8gNzLC<70QveyR>y2E zNTGELlh`32*cv!tPO%50XTb!Xl@4=^m}Flf;aP68 z$5v)xj<@&~>>AM--{zV(bAG_Y+h{}L?6Y!(ko$&U95xU@_!b$?K0}`0YSw;{SIwg4 z_xoYFJ8Sn;bN#l<@O@InEVZ33O0E=s>s=|Lp6^r()@1}Q~^k5E+yQ-;$BG0js2 zvtC25rqFZ~#(bdE(N#8G06R8Dh9~!rQA4%%+otTdEq=T;3R|;Y+qd61D$PLY(4y=A zM4*LbFf(=xjfb)I@Kp7p8udHyxErc?W8s)K`D<2!4DvRXEmKnn+|pyt23h4e#M5cS zah%V=IN_VpnlwbrRNpxx0-vehl3Iofz_lDR?_Le}36>TdUy9cd^w`ukf0}4YFIlWiu-w#?CXH};`%77$zzfX@9Vc_jXCOzxV7ZqH z+Dv_jk5lJ(vJfBLoG!2>78Y$erhe)ch#vUGVPvb?#Oqf%rj8*Sm;voM?TFPoFL0Fz zf=TQ8l`oP}Fn->aR<&zzGJ%??4*i8$YvlClED$9+fv^YeL+o$!rHbdICPCE?5g)nP~EnJeT(-R7|%Qd4!OUQUlh!@)H~r)@uvF=A6D?qK8lLR1zG&n zsQ5_ODwOvvVj}l%wmWJGq2xi9h$9sPw;%BccKc?iw5aH_5xekCk-}p3T@^xJ=#Fke zenjc=sNxx(Ph#nl?O}M2ex*CY>5k+Bl0sLiv02o*$M*_Ff*^r9-)8}g8J<|<16otH zsO}+ZvBtNfWc;i(?xM)?W1>be!w%o}<$`+&)DZV!)($xA5q5_?q}u{6I5-tIhpl}# zU|YXFMG7`&owzb3?O};M+ z27_CK0#aRmGQsm8#fqNhjn>tO)5s`jfLT3%7&MWD(_^>jZcSPu&$nW`Cs&Us)S*$q zCryDc)SIcQ}U1MnW+Tcxhb9zP#@%fN5}%6zu;T zc3rR9ci`H9PR{5ZSs22r1mNw>IjOdO&?91*m(s=q0*?bQLZBn*Z;cttm63_CTV8s9 zJ}y(@JY=E(91?q_@6Y|ljQR$KZwU91EH*HXDQMO@U*1q40hY-M>cv#=+~0j)8!r@~ zAvdW_3Lo;psKQr7o3(&QcN`!Eu68=2XH`sRF%b_sHd@^?k1lbUzH#|KY!iu&GoEA0 z-ZTO6M2(aaRI5NNsSlve@VCrpmu|lfa*adF@+T z7T}2`Q&P#4L>RNBbnu0E%~&+JygpqwoZZt`Z`@ld%h}H5%OXd0HdtuL0B^K*;sf%$ zFh4l@t9Fs!yhn$aaZBQ#GweS%EE4aE?w2T17*Kj_><&QyatmA%Nh8{J+#;Q90t;x@uk(tFef!jn+krs|S1{3De~}Yj;1RP|yMHwo`XQE`#FZ;kbbo5| zNRDZ_0l14voYC~5CHum7jDekRTOZ}mCscn(dpB1f;m1^EQV6o?iMt@3=puRBNOE93 zbDf)Mn|BN)?>nEk)WExW&?w<-tv0Q#*Y@()^4(0qL3WjfxDGb!V@Ogf!$&MEWIR)* z2Q$CHfYa>G9WBKO-|L1z2?o4x@g{>yd-$+yq;#{StWA3Ku@1$GP|Y=Z=MR-d%mG(z zr1V8ydlUcEhn)TAZRBPAmJR@^&O9`&eDvpfAGPPlhy3!z3=6z9LRV{1;(SIVL!%I< zHEM=ZYguu3sw%#L%U<`j+2L=yMarHge&Abv+w{}!_X(vHX<5?EjkA2oH`ms=iWIhG zF8d~vqE!mpQ^~adbA+E6CFzjd?ZAbea(3ifS0ibIwUvGn4xEi`Y(@EEuc6FY=X>lR zF~59r&=zkWR%PZ+?m~%l2UxBL_h*hZ`!2C`Mq4ymg1;O=Ck#JAkhM*7a*{$D6}0!f z--oHf&jr5=z|A3_-8Po9XjubJp_D?n_L(oKpL37Nwia@(-IIM1G+)tL>NmiDDK5H) z49<)Gbh8!NKr83NJ|eXFsFSD-D4eBjj|yd_!Jf<5;dAF7r2KMMjWkuu_Ze&35(O4U zninec=z()rXW~W{Dy~R_L9@e5lG4WrO0&&Jvoq?(HA@^PR34G3#j&wzOWOE?ycXk; z(qKOeGJ;K9k)|Rv({a2^CSrvHnbk2@ z*kkv*PXDWJBdPxt9k={&4~_o8AE}9baF|U1yxEtmhtZ9eZ{fy{n3v@yfWVjtkjGFu zu!E$!u)mgrktMO^bPB<&`;v+rrcAlJs2IsYG92#Os$`R68B0rcDs1zTy8JZw`M!s7 zfZ>)?!v>JA&lH_z$r zjlW`^5d5#LDGTFYx4GN(4_f^9Mb>{B&0$LqY62J1{_$N;n}eL|Qhu|S@4&9L!NIjZ z1ROtYMSv;8ms97SWr&B>6Po9q)zgC;Ow{q1=9Zv`i#4)V_8?Y?`E3Vvx=ZGB-${Q$ zPRsW$))rQdynKdOipO`pq9X6i83)3%Art5!^s#VQo}fG*%m_U?r3W`fB~Iw%FcYW9 zbWw)ft(tOtXZD+vUmkSLIHfF1)p$g)`E;s0l+>kHugly=oI7!peL|>$As(o`>|Q#c zd)TKI3i3@!O=lAVYTRFoEAH+JDcAY$3hX-U5bpthL&Dg(}+<}D?&usV^$t6j)YulcL@<=Uc#)5_kR#{Rq& z=V*t0_7(nYPOrCd;FZ}<8*OJrdl1kZ$t@TnLwm9Ktwb66^s;GBMRrDPwPf@yOKEo)quN0>qJ{m8(#%=-~v( zfYnk@EI=m}X1NW0n*OWMI=U)WS0i<^75b$x!For$2o%^|U0L0glRtX)S8WKC9{rDp zNF*A3b;<@UUu%Z#3I%PE?TgAES0=eF=*bdLk#v>D@k?0`z8ZzU^ea?s*S zWfSh`{XyU`VAnY}up)u*(PF1TV?3)4=RQ;21T>QEijRUmdF-tJBm<}`bk7BCxY0at z=@+8kH|4w)*>r!7YoE*5B$XddQ=SdqB>wz$2|UT&kmgFS$)KZ~>-11d_EZn)W*17< z{k(!yWzOFDakPp3>m{!F{GvE0O@~=f{5VM612>CWUKzC{xJ=o57zL|T0?hhzO%)>3ieEh37_9O^r02N5KUv*z2C9IO1`QS^%+Fc=x zUqpVg;A?O7-73U6T5i@CIoi6a(c#q2n7mA%rZn~XPB5vz3@!v08;liMDX|-r!)UB2 z#chemNrUxAoy*$oj*Y~R0j!75*z=)q$;AOB0OVWZ$bim(HfM1_!Uae9c*09!#e^(p zO!#yGg-pdRp@wYa@vlWa{Uo&nKYn5|2woeD4>+GZf}-oR)Hn^F!iy+*>e#ZSc?W~5 znajc4e>E&@3)5th76VGrq9Hd};e(1`P?G+H(v}+4pCbcTsz8`)=zxsd7{&-PD$$x9 zQnQegWk0Wmh)Hh%AqUUus4VYe)Qdi^b&b z=VoG|5>5QRkJ9No6a-Pn`J5wixB>0>RSc>$!;n8)jD=Eo6oaFIAzRtm% zEc~mqf0P2h6QKv40{urAywh1mFqHI^!WoDy##$C$M7Yy*-S@D=VK4+M53nQW_Isf8 z>OkY7d%SOiJy-yR2z5cVVmtcz4bX5_S_MbsgwFya8(#G%UVWgB#)ilGm`9=Lu+jmn ziiI^Jw0*B|NQxI zcH*A2B*5pxH%{b9;8Wl&6stuz0Nz4P{04ce`}5 zW4Qt9MjSE=N%8-3D0~!+G678m96+b`5_f=jsoVp;Ch^k$^ELcW{-6*E@e>_`-5m(+#uW@Bdj11Lgny&;P$gc!kTf<&Vmgx?Z{kqfxYf@1Z>s4|d#kIe>sD7+S69`I+qH9> z>U^#F0032*vx6G|7zkp3vJ!j=!dry^=P`0P2?i9YDqzAm+$qO5mER z4Iq=HZNohxCKhe@vvQ$yriVpu#MQLvU#{;P;DwBu{qaw zut>m?Cybx@`HdqM)vL(v_ov*Dtp~(|W!T=XI@u0>HvuG?NWjKT3xT&`mnyo_Obktv zH+&p8c+MsP;PkN$#8%I0BOvki7es^csL32SJ^u~pwEO_!an-#kn-t{3n=RiVTTPZ0 z#?{NSDLOGNMiso)1WBbKES(DW&+aVno!baL3r8XYVu5+`3S7;0f#R+|F*R@SKvMzC zTfZ4x$u;}K5(At*G=Qt7I{t(-p2~GRK)Dyy(NdMypV;@=PxU&|h-7M0yehgH*W2yr zGg5rw!J)rrBBn#5z|&4G5T?fAB_y}6X|HU$U)F&cdtZPA4S>YzoVz_IH%~@5Fn{{< zCksW&ME8$~e&)UWZ1PO32>0geL>b66Q+DHj3{P^56MwE*e@BTbIJYXPbx(2e^=#or zYQ%l4cceuV{WCYF!0OCon^#hshpKBdJ}0{o(LeFPC49IKOi45WHzp(h*{#!461pV3 zCU`%tMzD=mac{hx&0af6!5x)o0e`dov}Y~d*D(Lg%GodGKS!F@0mDl;TfRSV;LIBJ ztA%GH`m1bvBdQhkS6S)*2?y{Qh&azziJe@)0M73^I@{^k;km0E-T*5j|N7cfl8~Ha zb|BK=NW!PT3Oq4Vj174pZ3FaNbsWv6eRD9nNj!)et?xN&iuBLUNAn+I-hI{qW?Zwg zv`9kGEkwUibbIpTs2KBUZYi4o6)W9j1#VO5qNw!N$QpWO59WZ#KfQI2f#y```13NX z_bQ>|8d{jvi#KISzPfsVYvxHa`Kam3iau2kNQ%(af|&g@ldjC*V#U%x>j)x9|M1kd zC;4U=*QG1K92gF5Sr91`pQ!%{Hcl8`m+emfd+}f22fN!(^&QMosu8r!FmDL20$WB&glqEEu;i|uj zRm4q&!ttkU*6quamrv_Tm)3OmWaU2?^%87fa;AfL1<|KjcT@(EBK#wi&2R64qObD^ z*@li`{pVS}%C<}qFBgNiukV_wqgkc6b;7z; zwDlc209V||QR|KG(JF5r7(HwwGwWh)Zp$bVMf2HqlhW>~$$r@vP(JY}D##x+IC6}Q z3Xgjb8mbaxh1j`Q?l>3Ki`#zI-x_%{5qwZG`LeBGu5WJYK(r}&z*k)CW!wl-^RZsK zz^UdPBcfO9%Mci#D&DzZ_R{O%%oC1SXfL&_}~( zHfn)DoeG~^wr%>}dyOhi=N60|fCdpr?79Xk2|rY@zB8vqog9flxfT3$B5!4qVP-%q zGIm@+AlQe}XJ+0m2;y0I;L*8|Q$m?Rxp)b>p6j}pX7c5$nf8no*zjk~C-p=o{z^)1 zTEa}xU(<6lp(*#?fLP`kXSbrAs;GfM?|Y9L<=ARjR?3S-GjGMADGg9<>mo0son9sE z@cSDvxqMma>zsGsKqrnuit;Xlq2%(G^pj;Fb$&mKdh3cyk&LDu$K_bPO? zz{s%v&ykxq6CWO~P)j*?nZ=n}P+|?Fo;=gTVix&l4j#}VTet~hT$Rvk?7#JhSOQC_ zvle{TMp&k20|O@0I&4g^)bvo3kTlb|>iA?-4Odg#5fus^bbi`OVwvB;QKxXTf2A1E zeA}Pp@Fi7MGw#E|t86e2JF{b7e|vNYXJ;TluR>2ZNoyr6LU-`t8r^V zf~@H^$zdGXwf)zu6O)*OK?)8j7fL(I#IjOy@$SXipwxkrYFJp7EIwaT@tCtTrw%EZ zmiaSw<{4XplX1)iG`HeRE#U4%9ktMq*d%_N26v5wb$P*FwxsHKX=lOi)$73_ZDew$ zN_@aIddbnnSvcx%T(j#2>cTH9Q(>^#mjQoC!wq|VyAPj~uWp_^6ad{iuty-f-^0dM zSb>uX%ojS0-Zp7>C1js8`#74wS)gzCDXkdOss~Crx=@|_jOXWW>H*h{B5&L2Ezf2v z_+1ZI2G)Lz7eA1F*N?4kgvVJMxNobuR(7X);n*97%~g0O)?dRNhC>&WoR+CRxR2}-GO9%fTq$E**NJtSz>QL*hFTls zgl{(RF5-!P3|4D zbxUOX(FD%kqB)h-$AAtI;m&ZI7@4t1b1HA8l$%^#?jXuG!<|y?Ju_Zph%0P&I9*JWQiQb`m@ARuoyi@+X=i9eHU|au7 z-Xr(X1X=rQxzU|7iO8My@L+CW4ALCSt36WOPGHeOI&^`N6V-|+COz9WedRUNSCjwZMj&wNxdyWPfr^rdXd=5!p={D?<@mv4VV9Sg5S zeVt1WPhY%b<`?5Q&CMah2b?t)DjL%k?7o6D|HUKxWoW0{56RHST_D*PoHhKH3>TC3 zFL{axbmN%ITt2kyPC=UE{zZmp0@Va26nU)mcVK1u?;JMLe3wUH8#?|I49)AvQ8pTi zi-pEqA*?f|mFB4`Q4MYr90e+S(oZ@>;ZY?Aj=53c{wMW7SwnIjW*uA{w)Y6vYzNIm zmthI?mP)o{<}c(@u)X$Nvjene+I{9g4{~PaS6b*{dl7k#ut~dbogBI4N`78i3^IoD z2u}=k<2>=`yIgv6`je$Zu*8v5V{}4u2Oiy$OK(koLTJzgijJIeqZ6wSSc3WS%yZj6 z>@PV67B7`7&&rP|sRMWQg^FghJ^vpn?$yQSoaYg$3}5JBbJBSPPJX8x%H?6HZtr`Q z<+xvvu^ie;b*t{h%b^QYw}-uJhh7zq(+zxLqSx_Z-qhcE!sjEn7CkEKZQl z5J0sPb#@S|s0lJ1NQ={dTC1X2ORMJtBTc!mL+S4X>jAlA&IDx0jm7Y$nY5h&4opSh zvJT8oAeR_s`ahf4Cfh>2`$BHQ=JdS}Pk`AklsvfBSUGv5#|+HIiga=?a&uz0yH(`k zKS?>8jv z#r2LoN>iG)FF^T;$VW~j;xqTSgeoM*?ZqNInvkomoLOH-U#l2)GeS)h5a0=X)?Jt| zn`v!8wLV{Ydytzpn1KY@3zq%Wx3B6m-&4#8q57WByV7){Xt1Sw@*ODG7v?lG3(SQ4 zZtlkg-pYP@KUPV^mcTTYY%Hk$KpCM#kI!TRFXd$8aa#{^4<1#?RmY!lpQsndm`+=B zj5HXmRU0~U?-KJUGWq!U^=j=W>5dY9V}$_E$aO$K?;yokAqy|&PbKOy zZp?O9-Re|a^gi!E<4)=Pb4cn2Vft5#4PbsO`9S1Iv*WYc1leB;dhdf(d8BK4zSta; zSNnTL{9%DvGU`TZR&KTx1`R!u@MbLA`M%w$a^gKTG={UV*8{n}t;5vr_T#pQVxgo# zdm*Dd(QOI|I-=mIi%~*v`*rlcp7NPK)LoJBR2Xdz0^-S@PQz))ShKP@5X3+AVtP{c zAFkKVYPrJJR;p3u#?yB0m%HPumR}a3uhBRZaz2~8pttY(}`=_9D#EnzO74X_gqK#pX zq!FH3#p4MC+5UfJ;TmE;KG!E(VDO+S_jCfG`|InF(bbH{2^=I9UPkLqmYT(uvb<`B ztg+s2{94-mqepTX-w6vFVWCW2&c!v{wL5KZJN9e?IBV1XWLmg6a=d$!u~T?5QSQZ- zdDE?RaIxV>@kEevcCdsjdF1#0QUZj4u&ZYAD3M>K*L-5G$c1ihHQ=k=N>yU29F9; z3X#JP*#OIQ|*j^*yt`AqcB-8eSLCR6ipZg1nL38!G6!)aTBlRC( zfZ|=C`5XsNTAG@qs(|bxThG4&GmuMo^m8^5B;I)!{OHIkd1nAA(9r}IYjG%B672AF z(77EkCom42_~9vLpJI-)3M~N9{q`VD2>THSR&6ttHvJBQ+^-D6#G~e%d}`A%u&cwk zNgbPW4!b?#%y@B6F-s;dK&c0u zQVQvUl~YuMDtbvCXj%3tcvO{(i_d4C*V6>rx$28)48T78I*QJ+Vv}lxzJaE2WtBDtope=Gm zJzMIS(*55kdR8Vgwc&Vl(Jx+M#cWfth&=-vQ6jxv(;bxM*xnpot&7_isi)Z2p!cUp zZ}&h4*#z5*@-DczRWPdslu8~)ES7DN&HI{mtg`AL5#St12h!g?5ogOLzR`z00EHB& ze=xuoE(+nsT**Hp(L%I)WM*^4xa2jpr*y6%B?iKh^u15#ilyw7b6Nx$J7u1#B?xsO z$#+g1CiSO_ttslt$H9YGa*m;0+hu};Lej=)0u^pdTK>(cfQuceNr?F(c{jy_?^Le( zg$Or`E>1twR=FTx>jtHoI|-cp(Ba?sY}WB19959ul|C@#2WO>0-%&Z79{KdSszKM& zG?-aEA2aHI80KGgB%@=4CG=h<(AYsxc6xW&qt&MoYB+`== zQy`YC0rP-E8KIDZYZM|HwVB#Q7wJ z7>A6l6?&(&2AD6$dan?sLRT<1!Fn$fmZY`rG`EyPHU9xQjZF3#h=a?;6}2^ZbO~SW z0uM_YE@->NG7$z>L~DC{E7imoZPgc=r$_oRzp}d%fnSQ;U+fL1n#C_EBv6$Mh?)Ol zO1md~rF2&NI6$G@aE>GgH+9$%YYE{zMu6N497!$^Q!yL10q8H1yU_*O@G>kA9sxRw z8RoR2nZYPo0*uSxlm*zoM*Tc*EA3>}N4j{>SJrHW^*%C6jU`{r|KuU5V?9PRBy+mY zR8td?u{pl4n2Sqo_4nWidjJ|*06SK=WUDPKQ|T?K5*0dv{?LAZ&bVtJXO=$_O0`r% z^F69Ww`7qOv#c&P=M|%HxBkfAt@U+A8j}cX@vIvx8B6*)TL~Qd9XLPhrRhETO@#5ARDM$cCcP z2B=aYM*140W~}ICAA#N~Kkg_CqEBF?ngLLZd3t+5#9``wxUvlUQ1}$sJHcnGy&Q8E z!K%U7T)x7m za*~2A{BEm5&0{$DO#xP1sf*hMk&4;SF!Sfd!e^wdKI~@>Jwiia8&GeaUjiJYp-=If z<$i5Tlc_+5(Kq@z*_Q`ba6RKB=$!K{*d6I5xHG^y-0y=lYDI$Qopu*<)%^?4)~hfZ zi!oqSiwQC`7~b2B4oMq0!q?dA$HC3TjM(k&QNysddV~(Z6w;A2;8u@}u9N2+eg#Xh z?Y{Ets@G+$;*%y|Y%FZfJfzIKfb2RT_`2E=CxB_Np-|&WE=K4L_AX{iIdlF~Z-0f(5YJLgnC5eI+zfop%G#_@@kMjiSN~lw0%YT(ZVUWR#Ruy$cq zKilMjo9V>p`% zt298#vcdN9-6dY)`v1Uw!PSW4IpTw?#st}Sp5nu4$2s0$NPlp}eSrwu?gJFw+5)Dj ziMsSCXYDrA01wJQVZ!*A6!&4DXJfUW<(gCH5+a_gBsXRANjYnwUUTp&eMJPW!95_1 z2+qM@6A}wyZu@qS0dG@7;kWik0Lxb^W8s#LlfR%hWeT2R`t8aax zzs3R;%XwH>6!^UnhbbpkgKapfmlAdB09`S*8dT0=6B~hFLo6LR(DzbZ1J?5m&RBSa zVb~px0H7I%&9S$WhG78Qi{_le@Xv+B5@>yz03Zh%tQNK&fS?KZ9k}141myPY8{lmA zR`KbrU8m%&oII)a#1cTQUVU}uI|x9~IF6X$Q)RFl+dI-1c@N<03cJ%{k=}3W<||f4 zZOety`%XU(8+ePDtEz!lec>dBq6Cha44e3Nh@85RAhn^0aKtPFrg_0O0DLTgk`Dl| z05sPpu)s7CU@HYGGFv0y7Sz7-@6Z=v