From 2aafc839d5e7bbdb297c3603566741a4eaa5ecfe Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 27 Jul 2019 02:32:39 +0200 Subject: [PATCH 01/17] Fix altitude in packed decoder to be signed (#403) See #403 --- src/TTN/packed_decoder.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index f1bf2c73..6db312a4 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -20,11 +20,11 @@ function Decoder(bytes, port) { } // combined wifi counter and gps data if (bytes.length === 15) { - return decode(bytes, [uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']); + return decode(bytes, [uint16, latLng, latLng, uint8, hdop, altitude], ['wifi', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']); } // combined wifi + ble counter and gps data if (bytes.length === 17) { - return decode(bytes, [uint16, uint16, latLng, latLng, uint8, hdop, uint16], ['wifi', 'ble', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']); + return decode(bytes, [uint16, uint16, latLng, latLng, uint8, hdop, altitude], ['wifi', 'ble', 'latitude', 'longitude', 'sats', 'hdop', 'altitude']); } } @@ -42,7 +42,7 @@ function Decoder(bytes, port) { if (port === 4) { // gps data - return decode(bytes, [latLng, latLng, uint8, hdop, uint16], ['latitude', 'longitude', 'sats', 'hdop', 'altitude']); + return decode(bytes, [latLng, latLng, uint8, hdop, altitude], ['latitude', 'longitude', 'sats', 'hdop', 'altitude']); } if (port === 5) { @@ -147,6 +147,18 @@ var hdop = function (bytes) { }; hdop.BYTES = 2; +var altitude = function (bytes) { + if (bytes.length !== altitude.BYTES) { + throw new Error('Altitude must have exactly 2 bytes'); + } + var alt = bytesToInt(bytes); + if (alt > 32767) { + alt -= 65536; + } + return alt; +}; +altitude.BYTES = 2; + var float = function (bytes) { if (bytes.length !== float.BYTES) { throw new Error('Float must have exactly 2 bytes'); @@ -253,6 +265,7 @@ if (typeof module === 'object' && typeof module.exports !== 'undefined') { pressure: pressure, latLng: latLng, hdop: hdop, + altitude: altitude, bitmap1: bitmap1, bitmap2: bitmap2, version: version, From 7ab96b67bcec15f00fdac9430535bdadd3c83b77 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 27 Jul 2019 11:59:24 +0200 Subject: [PATCH 02/17] display.cpp: reduced debug logging --- src/display.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index fff3b4a0..01b1a1ba 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -63,7 +63,7 @@ void init_display(const char *Productname, const char *Version) { // block i2c bus access if (!I2C_MUTEX_LOCK()) - ESP_LOGD(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); + ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); else { // show startup screen uint8_t buf[32]; @@ -143,7 +143,7 @@ void refreshTheDisplay(bool nextPage) { // block i2c bus access if (!I2C_MUTEX_LOCK()) - ESP_LOGD(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); + ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); else { // set display on/off according to current device configuration if (DisplayIsOn != cfg.screenon) { From a3f036c4d2a2c6b86e0c0ba072b66090c5f8e5cc Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 27 Jul 2019 11:59:56 +0200 Subject: [PATCH 03/17] Increased GPS altitude resolution --- src/TTN/packed_decoder.js | 7 ++----- src/TTN/plain_decoder.js | 4 ++-- src/gpsread.cpp | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index 6db312a4..5b7c1811 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -151,11 +151,8 @@ var altitude = function (bytes) { if (bytes.length !== altitude.BYTES) { throw new Error('Altitude must have exactly 2 bytes'); } - var alt = bytesToInt(bytes); - if (alt > 32767) { - alt -= 65536; - } - return alt; + var alt = bytesToInt(bytes) / 4 - 1000; + return +alt.toFixed(1); }; altitude.BYTES = 2; diff --git a/src/TTN/plain_decoder.js b/src/TTN/plain_decoder.js index 96655ee7..c6eba7b4 100644 --- a/src/TTN/plain_decoder.js +++ b/src/TTN/plain_decoder.js @@ -20,7 +20,7 @@ function Decoder(bytes, port) { decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.sats = bytes[i++]; decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); - decoded.altitude = (bytes[i++] << 8) | (bytes[i++]); + decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])) / 4 - 1000; } } @@ -41,7 +41,7 @@ function Decoder(bytes, port) { decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.sats = bytes[i++]; decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); - decoded.altitude = (bytes[i++] << 8) | (bytes[i++]); + decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])) / 4 - 1000; } if (port === 5) { diff --git a/src/gpsread.cpp b/src/gpsread.cpp index d99a7c46..33ba301a 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -71,7 +71,7 @@ void gps_storelocation(gpsStatus_t &gps_store) { gps_store.longitude = (int32_t)(gps.location.lng() * 1e6); gps_store.satellites = (uint8_t)gps.satellites.value(); gps_store.hdop = (uint16_t)gps.hdop.value(); - gps_store.altitude = (int16_t)gps.altitude.meters(); + gps_store.altitude = (int16_t)((gps.altitude.meters() + 1000) * 4); } // store current GPS timedate in struct From 8fdd83edf9e96772a14868356df4de41970b8f8f Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 27 Jul 2019 13:30:24 +0200 Subject: [PATCH 04/17] ota.h: code sanitization --- include/ota.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/ota.h b/include/ota.h index 3c6c8318..41ab5767 100644 --- a/include/ota.h +++ b/include/ota.h @@ -5,7 +5,6 @@ #include "globals.h" #include "battery.h" -//#include "update.h" #include #include #include From 1f9e93cf39342dadf358b1109335d172c562ed25 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 27 Jul 2019 13:35:12 +0200 Subject: [PATCH 05/17] Increased GPS altitude resolution, further fixes --- include/payload.h | 10 +++++----- src/TTN/packed_decoder.js | 5 ++--- src/gpsread.cpp | 2 +- src/payload.cpp | 16 +++++++--------- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/include/payload.h b/include/payload.h index e2356764..76e74296 100644 --- a/include/payload.h +++ b/include/payload.h @@ -18,8 +18,6 @@ #define LPP_BAROMETER_CHANNEL 30 #define LPP_AIR_CHANNEL 31 -#endif - // MyDevices CayenneLPP 2.0 types for Packed Sensor Payload, not using channels, // but different FPorts #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m @@ -32,6 +30,8 @@ #define LPP_HUMIDITY 104 // 1 byte, 0.5 % unsigned #define LPP_BAROMETER 115 // 2 bytes, hPa unsigned MSB +#endif + class PayloadConvert { public: @@ -54,13 +54,13 @@ public: void addSensor(uint8_t[]); void addTime(time_t value); -#if PAYLOAD_ENCODER == 1 // format plain +#if (PAYLOAD_ENCODER == 1) // format plain private: uint8_t *buffer; uint8_t cursor; -#elif PAYLOAD_ENCODER == 2 // format packed +#elif (PAYLOAD_ENCODER == 2) // format packed private: uint8_t *buffer; @@ -78,7 +78,7 @@ private: void writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h); -#elif (PAYLOAD_ENCODER == 3 || PAYLOAD_ENCODER == 4) // format cayenne lpp +#elif ((PAYLOAD_ENCODER == 3) || (PAYLOAD_ENCODER == 4)) // format cayenne lpp private: uint8_t *buffer; diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index 5b7c1811..2c5752f8 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -143,7 +143,7 @@ var hdop = function (bytes) { if (bytes.length !== hdop.BYTES) { throw new Error('hdop must have exactly 2 bytes'); } - return bytesToInt(bytes) / 100; + return +(bytesToInt(bytes) / 100).toFixed(1); }; hdop.BYTES = 2; @@ -151,8 +151,7 @@ var altitude = function (bytes) { if (bytes.length !== altitude.BYTES) { throw new Error('Altitude must have exactly 2 bytes'); } - var alt = bytesToInt(bytes) / 4 - 1000; - return +alt.toFixed(1); + return +(bytesToInt(bytes) / 4 - 1000).toFixed(1); }; altitude.BYTES = 2; diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 33ba301a..d99a7c46 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -71,7 +71,7 @@ void gps_storelocation(gpsStatus_t &gps_store) { gps_store.longitude = (int32_t)(gps.location.lng() * 1e6); gps_store.satellites = (uint8_t)gps.satellites.value(); gps_store.hdop = (uint16_t)gps.hdop.value(); - gps_store.altitude = (int16_t)((gps.altitude.meters() + 1000) * 4); + gps_store.altitude = (int16_t)gps.altitude.meters(); } // store current GPS timedate in struct diff --git a/src/payload.cpp b/src/payload.cpp index a53cf7a1..df879467 100644 --- a/src/payload.cpp +++ b/src/payload.cpp @@ -16,7 +16,7 @@ uint8_t *PayloadConvert::getBuffer(void) { return buffer; } /* ---------------- plain format without special encoding ---------- */ -#if PAYLOAD_ENCODER == 1 +#if (PAYLOAD_ENCODER == 1) void PayloadConvert::addByte(uint8_t value) { buffer[cursor++] = (value); } @@ -92,8 +92,8 @@ void PayloadConvert::addGPS(gpsStatus_t value) { buffer[cursor++] = value.satellites; buffer[cursor++] = highByte(value.hdop); buffer[cursor++] = lowByte(value.hdop); - buffer[cursor++] = highByte(value.altitude); - buffer[cursor++] = lowByte(value.altitude); + buffer[cursor++] = highByte((value.altitude + 1000) * 4); + buffer[cursor++] = lowByte((value.altitude + 1000) * 4); #endif } @@ -141,7 +141,7 @@ void PayloadConvert::addTime(time_t value) { // derived from // https://github.com/thesolarnomad/lora-serialization/blob/master/src/LoraEncoder.cpp -#elif PAYLOAD_ENCODER == 2 +#elif (PAYLOAD_ENCODER == 2) void PayloadConvert::addByte(uint8_t value) { writeUint8(value); } @@ -195,7 +195,7 @@ void PayloadConvert::addGPS(gpsStatus_t value) { writeLatLng(value.latitude, value.longitude); writeUint8(value.satellites); writeUint16(value.hdop); - writeUint16(value.altitude); + writeUint16((value.altitude + 1000) * 4); #endif } @@ -301,7 +301,7 @@ void PayloadConvert::writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, // FPort 1 PAYLOAD_ENCODER == 4 -> Packed Sensor Payload, not using channels -> // FPort 2 -#elif (PAYLOAD_ENCODER == 3 || PAYLOAD_ENCODER == 4) +#elif ((PAYLOAD_ENCODER == 3) || (PAYLOAD_ENCODER == 4)) void PayloadConvert::addByte(uint8_t value) { /* @@ -412,7 +412,7 @@ void PayloadConvert::addSensor(uint8_t buf[]) { memcpy(buffer, buf+1, length); cursor += length; // length of buffer */ -#endif +#endif // HAS_SENSORS } void PayloadConvert::addBME(bmeStatus_t value) { @@ -481,6 +481,4 @@ void PayloadConvert::addTime(time_t value) { #endif } -#else -#error No valid payload converter defined! #endif \ No newline at end of file From 9be1d36166eabdde60a16df23f3bff99d10e6cd0 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 27 Jul 2019 15:23:17 +0200 Subject: [PATCH 06/17] fixed TTN decoder for gps altitude --- src/TTN/packed_decoder.js | 8 +++++++- src/TTN/plain_decoder.js | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index 2c5752f8..66846cf7 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -151,7 +151,13 @@ var altitude = function (bytes) { if (bytes.length !== altitude.BYTES) { throw new Error('Altitude must have exactly 2 bytes'); } - return +(bytesToInt(bytes) / 4 - 1000).toFixed(1); + + var alt = bytesToInt(bytes); + if (alt > 32767) { + alt -= 65536; + } + + return +(alt / 4 - 1000).toFixed(1); }; altitude.BYTES = 2; diff --git a/src/TTN/plain_decoder.js b/src/TTN/plain_decoder.js index c6eba7b4..4158515a 100644 --- a/src/TTN/plain_decoder.js +++ b/src/TTN/plain_decoder.js @@ -41,7 +41,11 @@ function Decoder(bytes, port) { decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.sats = bytes[i++]; decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); - decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])) / 4 - 1000; + var alt = ((bytes[i++] << 8) | (bytes[i++])); + if (alt > 32767) { + alt -= 65536; + } + decoded.altitude = alt / 4 - 1000; } if (port === 5) { From 3058973f667f6304231b440a20700a4aadda0759 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 27 Jul 2019 15:29:08 +0200 Subject: [PATCH 07/17] payload.h: bugfix defines from paxcounter.conf --- include/payload.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/payload.h b/include/payload.h index 76e74296..1a74e762 100644 --- a/include/payload.h +++ b/include/payload.h @@ -1,6 +1,8 @@ #ifndef _PAYLOAD_H_ #define _PAYLOAD_H_ +#include "paxcounter.conf" + // MyDevices CayenneLPP 1.0 channels for Synamic sensor payload format // all payload goes out on LoRa FPort 1 #if (PAYLOAD_ENCODER == 3) From 88db2cca2bf2a2d435af7a5164cf93554e7cf7fd Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 28 Jul 2019 12:05:21 +0200 Subject: [PATCH 08/17] bugfix decoder.js for gps altidude --- src/TTN/packed_decoder.js | 6 ------ src/TTN/plain_decoder.js | 6 +----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index 66846cf7..4663b827 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -151,12 +151,6 @@ var altitude = function (bytes) { if (bytes.length !== altitude.BYTES) { throw new Error('Altitude must have exactly 2 bytes'); } - - var alt = bytesToInt(bytes); - if (alt > 32767) { - alt -= 65536; - } - return +(alt / 4 - 1000).toFixed(1); }; altitude.BYTES = 2; diff --git a/src/TTN/plain_decoder.js b/src/TTN/plain_decoder.js index 4158515a..c6eba7b4 100644 --- a/src/TTN/plain_decoder.js +++ b/src/TTN/plain_decoder.js @@ -41,11 +41,7 @@ function Decoder(bytes, port) { decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.sats = bytes[i++]; decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); - var alt = ((bytes[i++] << 8) | (bytes[i++])); - if (alt > 32767) { - alt -= 65536; - } - decoded.altitude = alt / 4 - 1000; + decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])) / 4 - 1000; } if (port === 5) { From 52f0bab1da1dafcd0e9a69bf221844119378c78f Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 28 Jul 2019 16:40:26 +0200 Subject: [PATCH 09/17] update readme.md --- README.md | 1 + img/Paxcounter-Clock.png | Bin 0 -> 89160 bytes 2 files changed, 1 insertion(+) create mode 100644 img/Paxcounter-Clock.png diff --git a/README.md b/README.md index e46e991c..a284d4fb 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Tutorial (in german language): https://www.heise.de/select/make/2019/1/155109923 + # Use case diff --git a/img/Paxcounter-Clock.png b/img/Paxcounter-Clock.png new file mode 100644 index 0000000000000000000000000000000000000000..68e760eea25accbecae5335fe69613adaaed08ea GIT binary patch literal 89160 zcmY(LbyQnX)34EDrGeraoMJ_b6P!R>+#QNTafjegv;>Dz9E!V3ad$87PH_)<)AzmK zch~(R$=YX~oNSpnd*+$nNw|^%7#oum69EAMTTWI=1pxs`5di@)7X20c2!u?t6#jwe ztOAxmC?6v~fHzPq#O1{i5UQY9kH)C*Him<&wlf04o1T9!#6*@iWblI|F49^qs`lnC z?#51L2=Z1YPWI057L}s8xs{2T-|+`W_(|0NPLgyoGj_4Ex1&ZIim(&;u0N@sXN>+Sf#L?rY6tegc#-OD=mQO7CaFk^pnF#I`;< zT15`$Wa(2SFK{Sq3 zNMnA;kNs)MQb;3XY!t-W^0Mf!QV^KbsrmH`5o2blXxjKV?5@3VT~}riHR=qDI5Dz& zgChZO{oUnpVn|2_#CGJ?VhqxIuc>lrwKRKyAp0Z}AK6@5s(3G_>+Abm`8J>vfq;;3 z%FM7a>e*u&SX5V+NbVNuq&f>iO6$r|Y9o_`X~pUcKr$aT_x1sN&jC8RU-nuaBa^2` z`BusK*7n-3Jnx^d+krKZpa5~^cg*N}Ha1qYE!~vOLcx>UH4C9E{QSguk6n=aE&{`> zpT6#Rb#+cYUlVl1icmxJ)(G_0P8-|!Veenw4#U3v+}e%z;!ZeyH8z)&cArN<7YY45 zNK{W0zso&RA=BPykhYgyP%aQ{EEl)`7j$?MuG zmcu8Lqm^WoXdKXK7=GXO=-GVGz^CkOJ(qY*MmIAFIypq2?MNN&#u4WzxXMqwODhAKVcdDk z2VClupIf8bmjt1FwDxby$;qi~9f0Ua<&LjTPKqzitjx-%Q=|*mkl};VLQfk2^syDK zs!|pkkm83!2*1R_0FWJ+kPDj2ciH)Sc=#6lLovf zQm$2cnDGb!w%x=4{cTqZiUqit(HUaieQ*UOeNy?$ox;9w6M8>$-|Oh7k5%?^L#w8` z@|n^w=Jy!lh2Z06*yUoXxnp~AJ$+7^fzKk{CA~h-DlStS7W4e^57Br9$tdFz!CvwC zM+QB6dwXahy9Oxtni?2ASg1H0s_grHo2+d0?NI+#;-Z1W41=vtoPq7smZpzkzSO1k zJR&fg*0t-}*lR17cku5b#7!z{5rsePP1Wa+Tz;S#Xj_gB_!fsHQ|}}4mmO{$L&1v; zbWoli&VdbHR+)Y2Wp6Iv7H@-g0T$zLx~;mTUJ8-<`$-ctqJcfT_tCB;e0%zE&b(%N zZ1KGgtgOIltxbU@|9jad@{(e~-fM~v`ZSrb_cItV@UK^mSj?A49n#9f;#Nf)^^>RR z$4quVWr1j6T=|&=0e~y+0qtm$#&XJ~ZC6{LMd3q;HRwNGD!ycjn?N*gC?nUufgx`S z;}DZ4A#6(qhnujjgJ^hZVa+XDa~AkAf60a+jSLkgOt><5L}@FQErSU)lMtC$*%ld? ztT`xG)~%&6^K%n%$mG3)AL|i7A2DFEeDRIWbs3|Tp*mXZl8pL8;$`{=ip{qAVW|>D ztYyXe)u_X6Sy4r|mccQL8AJM(71KTL2-Ak2N09LSZp#;9E72}{TY)sPqVac1P^+s> zTs0;3CcUxsJjdQnj9*Qi=kx-pd3r2kw-FFen5TI3fXm-ljN9+K-Jnt}Sjv%+vZL~u zMf;<6Wn-RJ+TR^XE)}3k@uj0Fh!q1Afe-2cj9p()XGj13{kzb0Fd-U})lyl=;c-1) zF@_HEy^qW^hfU;FjrAkOWqGeA;z8@;6 z9CrPobMs4Y`PBtAeT{ye>26IRC@LyBi_Gh;-S8>Xtk0QlC6Td|dFLVRY96XFG2N~s zulS-TH~!*mD=2bU{QaP10fy?q%0K! z7BSEH$&bZv8^-b9M!h(G*Uca^MKdvyNuZ`FSIy-wr1imN$WqGWQQDvh*rc zzxEWryO})JEYFgx@QAwMbBmRzLYoATeF?u)@pT zN$k}=yXJJ+nvVFhSd87%u9Ks$km2o_&r8Qyb(Kg ztu*d;jEwzUGPxn!TURv-e2Jj9(po@Q)ao&b>Z)8O{5~vw! zR*?1Rpsq_E(hh^~ja@+#nHx%-U|;bzttm91wWt}rX`H^gT4j52LtFb0e)~_1dyZ)j zJNz4apIhBcT4jR@O~X6iXru?^nSSscE4gFz-vcLOhm5S-glR?Uit(R>77@H=q)a%* zpFkW+TJ)QLBu3G$j6FeP12{ff2>`hl0>hTTw(C~=N$F$*x@b+v6Q<)z@uO*kzAebd zx!x}Y;YS_-+Hcb2IH93oK-fdc03pzMg@ntZNN?a+R-XMc`neD9YR#}b|D2!+(koNO z*2;4`^&qOuqL_=3bQL4VofY*%+hQncrVElKx>Yi|j*RGOuUN4zd0bE$T&n*AOB*zT z$_7l*^0fYHiT|@UN{Egl(V$PP#A}y>a17s;u7yItc_1aR;InqsU{<17$wffhpXFuN z)%}H9PdryQ*NDri{l9}Uf67Nt2m6aG(o$zbF|zu>%zaCyLCBzf!Xp<=WT`!m^s746 z-PlkldXiuZ+CCI;nx&Y@5qaUfLSxt=Dm%B<^1ay`ZJ_+J!CeId-NSGPbbjkDW?xJ* ztHzAOQv$1Gu7;#w{pdkM0G*|_tH;){IE!B>H#KmT0Ps4{fdeMIQa*parDT^ajc+7M z@O;VbB5&ZwJab)E1UrQJzluHFoldZ5EkbutvS3DLM0iC@bMo2qhH@%&7B-ObL(h$V z0)K!X#MM*IWxjKOH!NUW-Fgnvm2{J0-kEFQQpes2onAo|zwOjFQQD=C3bG9TWJ zqdE(P_f9-~grWvhvjZjU~ zK-F$$nD7s-VCd0Mya0y^XzGLACn;ZP4<0i)S-zW3W4O@J} z$I_Srv%+s5Aog^(T`O&$6ofeFWHeCb{tK6Jx1o$okdKd#GFhJ)2TxlMxNcNr^K>GQ z#Q{ldPgWzNPo+{OHeDbEZjNsyi|_I8xj|`YAk0Y2US0lm+N4Y_?#%<*l?T2knkCVZ z5LV!1>>3{wDyN&62RH0 z7BcYsh3*$pA<>oJadE|@yWf@m{gqiJVSk0;wX36u`f)yHAaM3$DCJY5InOUFl3CGe z7RCI4ZQ2FJ_bMxfU$^?8Sb_6NyGgZfBT@*0-%EwH12T_BI`sxzK&4atlbN4BenJ7- zHT=APct8b?%Kv#(+SOW8FE(FU@U{DA2+^ju7~cA}>38v@8cwoV>J&xRR{c!`ceuEG zK-QvMEM7F_!0hahp#p=`KTZn^hEJWj#SCmKsa5T4(;eIlp3Q z;_typfJ?En*uX?aHW`~2ogT>2SgAk4l}1J!Q%V&Q&57eyKW^as(FpZZWdvw*!Rw!o zmh9869tp=EF%O4&#zgyq7847r9&Fm=P+q+`9*QSGW`uit!s)!}(C0DM`xv*fL7CewBa#*acQYn*IxtqZh(DY{KEKc6e@7=O$K@CiaNwq>gOTno&K=Q#4l8FLAW%tM>X!3R3%XA2eksV?t`1jTC<;)=lS*%jZMQf z0jh*@AuAhsQwN_cpHs)DmJ^BM8nX1RpsM5K3#)9lFS50eYK~N2I|jI`8L-=eY-_Cg z0JJw&!-Inx!s6!?1l%;F$O}J$n$G05Xbt*5et?7!@a&~v^(cR@?jqL__9my`s0)s` zfT*SHWn=vE%x=*(&4!*Bh^qgoi}#}v10LJvy&M-8wAR^Xw_u*h+RsJ4(AZb9nLR;D zH43VI=kz#)fL?A^FVE0+MZ=a08=6gSvdPI;g$_OG`kq{L@=9Y*a*<-6&~O*DlD4+hNm+m#-AYH!zk#~~crPeO#%~s@GLoSuA=4F@o-VukJDA4D#>Vu`@-{7=YZMy7uf+y5w{gb2#ivs74^MU{= zVii7G@+&^R)dFeTqwK%(SL{QaQqY{ts7Py{mWu}p&x4Q|Shs8IbwZ)FV0o^HPbee= zjutRtJXxVgGn>YOj93Qir ziSPtXLG8!Bt#~X2Jyu_f*j}w1j`2_FD^In~ev$mQ1WA#nV%n(tTiWe5@6kd0MsFde zni*eAYJ=kb=Zd2R_G1^EA3O4Atmwo9u0Px5UDJ`>twwu&^Xsd^l4!3U_;OUWF(8oe z*EM`ipcjv+VnopUWTIdrv$BEnulp!sC)jO=i8t;8@nD$uOWPCNO)z5KgW@QbgJFeg zcO0M25)3(M9|zuKQu5m$2W+|%YUd%(zramIvc)E$ZFOx$hQhU_$DT!OWn4E^x9f>~ zt}Hl;RFvPSdU*&hOu;n|ZR_){7#-ZjhvKa`k|46WAM-`zvJ|Q=f=@#^fkl=kbnh~R zYp3#_PZZ$S#zGsX0NzXIFW=&0ZTOaJ8}}(Quu$dp0ZN6_t*a6lq5U_U`#A;*n~%d8fuoLc8rQU7GMb=4CyI=Xgf7=;;3M;O$|_ zOqDTm>@-QUkkj^F<3T4;L*&{WnMWN^gxyycal_ZnA%p}r8uo7h&y~wV(@B|j+4jDB zKWR2U?e-TL#T1c3r1Dbrt2nV$IzwwS)fQqXCz4WPQ@`$D_}ytDt+|o1G5Bs^@!a|& zyTqS<=aXmx{fMb%YTqTTCbe<24;^j3Qds)1zqk?WN1ZyANE}kNd~J9!{E|UX7x?JKc1U#oLnw z7EpDFrG0HsuNH|q|0d{zq{dfJCnRN%B;eH-eajg zY^LU`_WlVYKs@7GW6dKsMzUL7Q+XmAGX9QGMuj2rie`CS(%T%oIIgUa@A7YzE0TF_ zSMj}f!Yh`9?S@3WP=O+w!s(SJ?RZm`oJp_nqZ?1hVhDaJ5(5w11ShF1@@`js?7O(9 zJ|kaKdX-OOMX>K8rWDP5Ph z<$?CLNGNhc)>Rbj!}aSe+)jzLJOg>oM}^iBerR3e?wMeI2Z0HMe=YLoh|4VBuJ{hiWdlf{D8ztXP)3KTEJx)O4Tc(G_$>VlZNF%>W}k?Y#;LK>rk*Tn5= zuD+2C{F!4!%HC9JONwOAKL$dm7OjPjc^u^dv>Ws~LZius@5>L)QC3TypWXF6i;ZjT zCbTZ$c48BE^F)4R4rGb86;=EN7%4ob4M=1ZLet@o7T~dsmR&rc#4+pfnJQv5>xqzO zxQJDFAZ8M)Nd>T67@;^pqd)V5V-VLJW86CIwh>UtzE`#Pi;Ba>@L!#j=SIJs6Z}&_ zG)bW3G#`8*L!KwzP-|1K11p&o_Ovq`dq z;}C3k_dStQ*P_5<`130XbTyrEQNxMA`pR3DRf7sCk3r7^`sz!nEZc&eE-b4UsF!fS z?a9ut$q*i~+={l8#LZ=ufw7Fx;8zy7chP!h(8&xlx=>vki2=p!0N$k^c{3&4@&SAA zk{!-Wzai4+(ww~BK)x~oh`VdLf3$Ea3Qmjt=mSyF$f%r}taJKxSH@?=7_r(LS#+}} zO4JF^s6FGi8Vf{iF3~Z;fZb?wutQ%B4NGd8nDG3jn^MS;HCy=+U8Uza74$ksMkvXA zhTqa(D~&hJ!Y(fhP@#`j`yQ)l7B+-q;W#Lq?_UO}H`N~~os z2z*`=m}t=BSd?WrRSas62NEkxsS;hG_%g=}ufZD?l@|%SzR~!@?R`S#Bm9Lm7kMJg zDp-is-2tccaX2W6>CSHwGkkaj<_+;PUEVrwZBi~y?)HCB-c1-)_&u%d9CYtOMO@cwM z;bSo23gDZnY>;a;CWRh4W%_75p73v=U~Ya`S4Q~Rz^LblDqv$>Xum4l)ka4PO)wRs zx#4))0DMVAe{l68V#C~-2=$ohuMfYEv}<8|oL8Q?ED*)eagb*RUaXgiw>Dh($DYvy z@z@H5pW$N{m3r55SdW|YWBP?8GUDB{bo=tF_KEN6wqD@Nzj<>Vfse+a#a(^=Ay*E6 zt686bV4InRmh6^R(~3y|hMtvfyrc9AHZ(lg`$W0Z3u|;Vec6~5rON{vUYgwBs~Z+v zL^w4cVI@!AVQeLCd4PP+xk&kZ)A%F)UfliKrWC#XHBKUE;M=>SHa3!0xq-sW&O)>& zGxX!wQXTaEWon1Vu8ZH1TvS;gbS16vS*jCye_v@*2w{fGz$S!>uZ`(mw8-PXr)e65 zd#D5L?FIuH&PxojcStENfIbQ4uGy9P8y(;#ppLzi(=Z>{aDDFu`8RaGsB5`9jboEr7jM%+a9dSO!0%BhebS>jV6Vg zS-+&*$b=GUP73Wvdxq2v8RwD}gA|fe#EjLMHVGrxg-McTYY~4y5uoO*>M_tT*q5Hsg9|SQ6-PS-c({JB zquWj&tr0--(1dIGJ zttsR{%4IV27?W|zBh{SsJItIzX3SdGi>9A~w(GV>=-!7 zqH2)m6~5_SWqI61NhN;+mMWo|!0d3I43B3}xqd#(dluiS`nGUKT=ZOXFH7-8^kpyG zaABPZ>r#wDxYcPXanq7OYsHW{1%YeuR3U{wz`EEb=ORFw!rd2CcHeKS*8FIM*|LIotZ)nJV!*WeX5L3_;5J(}yDvPFU-o_7 zu&A_W$-`|S+RT4|r=2SE{qJpw=Ie?E6>r@ZdTd602%V6YjE~37bI~Udoc~n3uso*CM~(}nCn75<1@RyBkHxY0YpU%5Q7xRD25{SxU_Mu#H2X&)u7_;!9(kO z(S4W=e|e=1ZR zHb4`}`i1sCi<41$>h5TVy4u6Pe?8SK|M$y@XIC@MiO(yg&n^X|Fsc{H%Y%o-h z*M8;W_l7kE?1mMYM8D^n#{6VHjV|ltAiu9wi(J6{-pq)iqN41i{GztppkDE0oy z3*(SCC1^DloSx^Y6YM#v(Ladp6Qv0cdQB=$a!x=yLaGmI>Yynr)JL3fv<=17b~u)n zIP1JGEGf!O+9lqix^or?XZ~3DG|M;ejmic^7`3_Cva&^&98FNDmw8IosQrFVb6S0^ zo%!UwJGZ!0F}WkzLb|BC+}(~Cy^sGBKW_7sSTK1Jpb)Qs=3n2^V zTx~uO0#;sP?rf%VwY@$u%D}lo6tEr{MEUzgyfZZMs~q-V=nUKhl#u=0v4c!uALfF~ zqh422+NMG}Q4=mNhO_lzJLb9z(!H$t?Kkw@Lr&hsxE^A!U#yOpKnW_aO0xS^f7jEQ zPWb1|mH!si@ia5GGnEikOj?t_<)`WETs8384gkOQ*&Af7G@ZdUs9H#&W>LhrFiy&n zL#i!=ap2j8Q^C>Kr|sYO%<|7O1p~KzWZ5i|XJ6M8PN1T1(qr$onhuSAnLK$pUbQ_7 z!UM@3`wn-&%^PAHen{6 zXKgM-#8~U#7ZQ@yzFYY=iI8^bJ++nMt+B73?h} z@b^$cGh9zy-L%_K4$#?Zp}0Rc(JCg6h#f^n)J)pW#^&`#P?r39e~jibR_^(*6D_V~ zQ}oYP6fv5&_rW9@aI{?b7aTwCgn6&@xnh*fr(ny#IBX{95Eo}4DL?*b4d8>`qH0*> z+b-h!rhWK3Az1`Z)i+-eJUQ<47^! z{pje3@-H|?k$8KkPB+))vuSWj9XinwjIo&-TVK0BUm0*u`2MrU^?qPK+hzAQys_N5F-Ghk+Z8Hxf#2@?BzV7&kCY34$KH{}Ht%MWwh?O~rIF@CrW? zwxk_6$P|bdgo)7gX zmrqgve}D@7>a{+L<{?NS{vpHEKhHqA3y9fgBCcz}C_qLkMYV~UsDA3swU|Vh{@ICK6awQ8#()>|>2K9-7#(f=0zu&OY8W1ipyL$=z}0LtZlh z#fyR5A9)O130&C?-|tVr>&UJ8)+;klM;8BBU(YMg>s--C8E>xjnQ6z<&E6Tvf?3WH zBLUo?DSbKWSQM@EzChk?QE6mQay7!?rq6;OT&ObD;CE*GNg6_<(mP`ObVfkNB0d`0 zzg5Kw-2ZItqs4X?|Idx3|1VsysG{bJ8lJ@}T};sTwuP6m1dM1sepGqY5zp+g>VM3* zT_d`kg-*{rWK?qMy(05q}87jkjXW7GdqU15O)o5pC- z17bN*!`=gSa*pLut7a#rvY6+?jnFAR-zYl&d;Db2i0Q<%zRMN%hD}_vI773->V`@H>@xqp;aX_ zTrG;;++4la!5rCkVF}s zjc+}Oy||d|lgjCODOG@AIgm5Fj#tMRntIeX%Erzfa8MiqONR2D@0Zip;!@c6S!oVM zAq6N-9FXV#to~b$_jBa>1X;q*?>;^YZ*E5L{o`%BH0AGXGz!1CSXt421V5p@PJch# zm(>vrM73sPLcb8V@Aa*5m(&Qo=N4(Jdz@zx6CTltjO1)J7s2lUgCA?Y;uhUF=G{-2 z%*-uW{E$_bApMyl5WLET0MwWYAPod0g5bghK(F7Ejfdguw+27^&8<+dFF=&y8?i(h z{{H#wzOjMi%itg{C{)jf`MzINsw0cYqv*0^O*S4eE?98B!?o!Y!#=&}FNK`$q|$AC zW>`JMzLlUk2Qc%&d6t>FTl;f^!GlwGvs4cB2*DL6{}1+R9G-W!%gHb}$*ldJU_syx z)zk=`%18n}($Mw0_}8>g24XXm1folm@c$RNL7 zab>@D6s;Tbup8Xd|FSdK9ea3Rw|%Z-QxUV+ct!?Ue;{0^&Di)s0MC^EEiU3Jp-tn( zP*`VMa!@fG$-eciVIkb6Wk=zgPh%71o^b5KXbwnT#>?}i#TJje_g2;iljFYOoq=8> z%zRQPxD$!1&k?7HLb&^uNa!I{aZa`t7Nb6=3|8JbZUEO-toDbf*Gd5w&Li1n3wvzyFGVH*K0yH%{U~pLm#gE7Q_S#!?kQ(M_Rlc_meq0my`VM8*PLkj`ti^ zxw>}x@*9Ie!~9yaYQHgg=cY9J=*>EpUs>6&77x};>)7+ONMQVrkC~yqxKB^sl0im33O%@6T&nw>HmG+9N zds^y6~f zF>@hqO;oG}PJDdd&|RJUWJ2{w`}2w2K``wU-0h?=;EV_CcLt#tTSfio>hP-8@|=r1si zPmwM{Mi3MJQY_-_T3AeG0q0^p} zd{5T1%4)3zTuxtO^WTq2c zJ1!0gA0mApX7LWD_=_lQ?Y<}S&M`0N4|0lR{B{zB?bVps?m0$M%gPr@ ziJ?D@yjt2#=H`aS5cS8?v*~JKSX2@Q^W4;9&sxtepeU_@KONxf$@DThA&a3cPsQ@l^i`rGW6Mx6Uw-BeDw~9cGp(4T8~A+hDsc+ zMXeQ|K@ezKmuv@$gX_YyP2ZmJ9qqE}&^;#%ZezUo=_6W4x)b1b%@8M z!fE8zfq&u?LB2nLvvu-$fa^KoHkO=c0}uDEFNwr>@KhM1GJPP-yA&?JvQ5h(an7)4#r5}oL+7Cl6n5b^Tv!vpXO?0)*7NWb6*vS3)YdUGds6%l@?%7&E zBcr~s53n$P{$~9$?QEk@4ifcf6aI0cHg(!Ft@7}379l0pIqE+U3aB=+BESB{%h2gs!$qnq*t)x+$hdesC z_~?u1OlN@)lwm}axo9mSVs?DXN1mL8p7?PZo8_Jb(n_&5JJpRBNi<2_)O7VQ;Zt*I zvanv%UXhvMyJ>Z-@-AGaXD1bDto~wG_ zvu7M@92#VIUG*>LUCm49WqnLx0}y!N>R;2Gy31X0z8S|Bt0=vFMdq5=@HP#%}@6#9@z5Pqab}Lvk!leHEV}`Z!~mUaouQ@A<#4w z`Pz;{StP$y%cS?lm0;Q1e%}tV4!E`+CR%j_H&TdXY#!?(t!%YjraPp2xgcA551|qT zUlv{Fyea!l2eNu7z;qUI>2t)|*EH0V+$+1(;1Iioxmie8{_dST|ktrpXCf3)N zoAD?#F152C`wVRJpXo)(Lr+40c&)1?ZB;>*kFTY6koU~DN2@#WXih9Lyky{G?a&&K z8Y8CzYNQD4QxAg)W&XG3e)a#=+`Yg5Z_S;ogSHE<^%c*6BN%<vv_mn!LCfVIKK1u;$rr`ohf-5 z6K*;K=Z!Js7EX&pdvFS(oABjdr7q7N@>8fjq>bZESl9zUy^1_h%JO#;h0)piJ=h-V@?UApKI_`y&f&a6IBE6nX5prX z01BUa*?YFc=pNrR>#2ElV{@*BNuH^YGp{+F_triI0i^z0XeV$u3nJha$+&T*!e_G- zZ~YI08uns=r@a$-@EGb(pS^GVjqsyG%FQ>H3jABs${DX!Pa2@c@874bj3=J;_KbXJ z-Z7fD8=;XlnLI`S{O2RAz`|igZNe%>%#O8D-QNd)HysUV2JTrdsc=CfJvmQp-Y2wfOKV9x)QfPoPpdzYo8=Alj%Pz))4!j1bR^Nw^x-!2sqk9jS2YaQ2f<*Eey$ylmqC|V)K2M_|!49 zl`$}H{N<3kIc*x=2jQon3X!u-x3TGW7c!Dr?V;A77$K`D>c15u$ep2#os1l5j4R8F zBzOHz$}Ac~&kt9A(s_b9dBgisJ!PBS)`Br`3+vTFU=j9MW(4{S(gBIwzRq(T8H`t( zWlxo^O<*RXP|hxROc4XZ|CEGyg?yZ12Lg>fazq(6ina6%5qbXvzpz+kE{?DE<~H zyIu6L96j!R>n>tdDqT<>SioN*W@eU5q!DHDubXoB*j&-!O8-H3|BI}>ed{-ams`T( z2d&dwq{)Bt7O-v-%%XVknz-yCoiVx*YT#NMrUnjj!8H6gSyOVumN7e9@!vfrnHW8s4+qyl`yf_dUbO%{?gVxUzS?_O zdn-OwP~Mi@_T17h9TN<8P;9NzMUk7NY)1?VK*Xh^rdqtcp{0@ax-2g_NL(u4Uh~V+ zXJ3(fSn~Dp&W|jdH9GbZH6kx_-xGE_>&b3dappO`HH`@wUFX&;i?GzinkiUyu-gT@p(j-W4jBEs z6;R|fpPuD#>1>})dA&~3KjPB$B2hL_%N9SKc@{&qd~xYo&rjK|7Ae*U#HTVePqPni zGYG}w+6!pam<9g%wAk6?oZ`61<#HHIwqMKcAh94Hd$o9sm^9{?8nIe zLE=Z=2U?-h_pOh<1jmKeZ}cb8kbo$1=)pKRgH#yMB^1^?e+f^_D|V+O`q{i>?H<-KSeOo-#f7h&GX?fJ^)p4F@Z2zays%;~ zu84Ew-LJsOt^+}&yA}8&mh#`_@zHGwzpE=e^OA`rZ+CwLGR?xpy@xS|oIw{K6QPO< zWQJlj42fZD+NPA1=fZnC$-N9W&A=C8)r$!VXJbDfG?6EU=ZuTpE2$8C}TmiqGgbDt!d(dzh#$pUS(}aK;b%~tfs3=7A@KVz4thQ zSxn!gw+x7ur$OY|TqX;~a-Rw_D3mcN8giAB8PRP#Kfh5)q4aAsJ6jSHDv7+-o7 z8XY^%Jl{>@A01%pQ+Tge>G!qSGG;2KQYNBwI8vLm9dVLe|YW>nMV=5Umh9Hn{szjy|jwoFrMFlOfOBpF(EU)*wTh@rb4TgB=)a_Qjr} zRqad`gr-l4o>VX`$DW9=hGUfg(?7@SvR~(y+%&{BEs{NCB358rIkjpbaaRAcI05D-J9J!_8ob1Jn_V?rLlI!U#FJ+N`lbvFx@We zK4dTWKxXf1AW_(7D`~A2Yea&y_iJNb=LMW+p_=gDQt!ZI)JQw)_oh#EYgedSGQdpN z259@4QTp3e1=fG@9Ma67i<|uROEaUnrKPB-vw5unXOjJ|(uJ}5*7!xNprzHmbump# zH&fdaiV^Bzi2H58*Hq5zcP*HS(kkb>^`y-=h7}Y24+-OM5uWRr7jH(&l8*PZJnwM} z;FgEhfo6Gna!6T|$cRDRjVl2$UXBp!@!2;HjR;#R_CJDmUY$rA6o*z@q~KKu`D?uR zG_;b<{ie|CX_Nhr2`zhcBK%PfA^4vL@K?sc=1YVQ(ENPAmA7Bch9!>X>sL(w-emZ6 z>rC}8zM1%*SkRpWG>0p^Z{vFoEls~weoBx*;Z1$_m6bZGZ|7~xrTg)sG;)|28>XZ^ zi57x3NG3YgZ9UMj#_~S%{grtDK4#9EDL&F2l@HdNc-wCEO6q*_zZC3A{B65v7>Nzr zzxADO(HFk*1@ifPmU{e!i2IPk58+N={h5Q{BLikYha8sWBN3qf(X@d-!20e3*NIgq z3~pIuf&EDz?QI-U(hHpM{if>oo~C#1`xVuF{PIx$V81IdT02e$vi{0E0Nq%5O81I? zqHy>J{97vbR8mb%4Fw04zu961fZ3kz9%^ii{fyMi5VB^{dwY80KI=6zBp*FI6Uc-; z1gYdB6?I}CRLuwf6`wK~=Tn z=U#YjFgGtZOuy9<=oWljkmbV+N%C>d1?MD{57aZ($(Q33e1IRl`<6-USI;`{thC87 zSxM;QeCz9DBz$Q5L%I_am6Cow)(LcH5+CPXcwTHi_`2Qa4Hj%Xfsa0MuA6U^NiXKm zOAh{L3l}i;OhJusRLY0G-acjJX)tunVh}QC(tCTAnOv5S^di}Oq;)39P0Rja)wfXr z?1kv->l1(X%F2AG?dp@thgrrLx$>0tSLQ$>e588iNy3P&TI#)KIT+!HXT1k4J18Ue zJZ1SX2a>@D%E**XsQIumvV52eqv69WeFFd=OP4JjaX&W$KzAnbaquArn}!b~G&nfI zvcz|u)Xan<)xOM#xG}TN@{xXwh7Z#@E+$9z538?qNPT4aFaeUxhv;)-47u_oR%V+r zz+Yt&A94JySb3T;jrw<2rgY^=B9?txV&zFYFyTC-W)25u`7i@U!Uyu0kzaNHure}= zkC0ti8Ohd1y84fr4>R^(BLLlMyRteT2OT`}75`Kr7A>Yv ze}Y$R%mkx+Si(s$iL!rKeWjznKQs8ql$EDc>qGRz6e7IxlqvqIpZUmux3!JvW2{%6 zB=l_3)GJTXi~-jXsV-TzBr|3X2W7|%D8u={xm9>m_YW%rAH!X8&=PU9GSqfuWeB@s zeWa3)vFK+Rd`J~Cj%245TY`~6f`Qy02oQK;-HyYiG6l07cTl_#}6L<>o7C)JR0@%Q^P!ta8Q zhQ@~YD^Js>QvaT@U3mhuc4+^~H@`xk{rqQ5_l5CThJbsBR2MH@%#o_gvPKi;V+r$- z0W*h;;Dhbyz$FKU?aHdW4D}Cdu5@_39=i1MOX-TQUqMH&JX#z-bNOe;>-C0mSPQT# z(LeZTWrX|r7}`}T`l0COix!e6FOTw9ts)!SmDTz>=oNe{Wq*|ces}RfO8+n`A6mM^ zo~Ql$s;H*AM*Pj6aCF7Lky)G>jqXBaL?eloRY8`IR#vGu6sdx4aaBPC{W!;OO+8Ww z+DI~t7-i)>AZmFnRQ0Lr73KK?X4Xb#4sq!=f>^wb5b^j3(~aMuVs&8zf{FN)I`<-_v7zh~l6M)v&BvLjE>A&zh zk@B)_^mDeWSmQ_7f8uxOm`GdU@r7+^wHG2ckj@(cnM{WJC1w{7m|C*6zbizOFv(nWCR|ki&m~Z zo|gP$Y2(v#e`@|C!y1`?JCqsZtCI4F9jMfnYs8{f@@@U$*W2bPgs1@?E^GpJCduPoe ze_frzKOaSBiPLtN@3m`(_=ddYeNIBp;Aj7SalMH1=Cb|y=FAageDmg!hwY+&-@d5) z%61BmKb|~Xw%+TbT%MJBXU-ID@+c9?nL5~(KoLt4lWcT@~^VL@ca}Yj)zpnrNPdE>$M0}jT@WgfGDl4Uq zmtKPQlmk^jA*c#}zvurT49+MRUZlj3xT*yHmX2KoZ zejfV)*x6_RZ8?L3)ZCilFN}xmsOzn_LKjrvd-)s`cC!tE&x8S;aKG<;|9$E?U>@1n zmZRDg*Dr0@37?jelei6X9q4low&8B(2X>zRX1v zb>wp(iB#;2*0M*6UH7LdL!D_f$+!dcZ{xlg?%yS%RAyomh)>g*wsa~Sb0+JL;!Ra z9KS~RLD(;3g7%9Z&6AQt>Ju>hGwprM7?mgLb~~ zBF*~hH^`lrFAN9DlF`4N2SYfIJ-_`e`5PLj{h4Qkl1exL8F$Q)=$> zy;Qe#D+T(Lzbfv^%cEsC-9&!w6alq@&?$Kqna9y_aQla}_h0{^>iZv{yk*O%g9r9O zu1Bp((Qy&EbD&sq&{DFsx6)u<0kyvWfe3~s^WcKjk*SY8MECveHtNyL8~{-V^HRbN zV*JXZsJE$=_WkjXRKm`@@rfsBpr=RV!wL*$740v+DChv3+@Y8J;0H9wvxdfpAEqvz z-C!17#IvPVHtyy}A5~@`BDd0(sE0dPI|qiSN6fHb*c`O=w6%%Oi;maE1N$H!ot%IE zSHDco!`1YJ6gG6g|A}M zCJOMtIsV8MRJdpfb#lHzRfiPyvur%1CNXX0}Y&+3V<;WywwUbczX&pw;_J35Bi z0gapo{N^2Y81;Ve0WJH>U&uCdCby|LUko~OCK?a0bw^h_?YV0!4InUN{vadBSAgXJ z9nRnhz#uz`!4MA;2(Upr?8U`8a`5c%ydFChDRln)^CAys;Q3s~)D0V` zgU`4B;g8hw_+vswm`K1jf*~7MBV14DK4$adPdiP>sOI1Q7J1a=p_@hD{x;c{ED85_ zK|k~5;sMOh&KxsO4_2VK%sW?J8Mf1C5Gxlf8*hF-)jjY46>$JKllAZCKK${Y|4cn> z>r$rxXdHL)$3J*DeTq#5f^Ap7Cmr}kD-0oxb) zgq+1|5w-)^FeB(6px_J7Q{!8&)1KRI=RT*{6WYN0}m4VKpkG# z7za*ofAyH$uRxf*7Tgl4YA)8Omfve(a(B6_}+WT9kN&075c2YzsDN% z!+veblp#HFSwG5hfc)XFe@zR1@)H_h`F-%&&(eU}?=Xa)<$jJ})4^j60=QP5P`5nx zScE@TLtTbgj_?t4&pC&Bn8$9Ow8HNWqZ$6qVW%9YooZixmB*bADR=4=+Rx+10Qb>o z9HK4ohZU(`T$$C@D59k$s}JHqF&uHX9RRW!izg)W@je+54rsAl&H^8AqxXNfg$9`KSb9n|Y^Sg#lnnam@y}ewgJV0{nYg%6 zIWav3hap}bz7KCdS2^wX*F zjysf_IvD?%&r->ZX_Q-BKphRu)K=d>4(2Oms(mmfxNy%Kwt1-d6KSwQW3 z_R~%d2&aGUbF}Na>x2PHR9tWY)!%w+=uF{b16HZHjorWd9X0ce1N`RmETo--jT-Jm zdZ;+>JgWc4KSF0p+ePg3+c2>3Ic7R_JfHz+WA#J#l6T!n;ek}ENyxDI&%dYcmJaG~ zZlUehTqCY)+tFe+JL|r_UYa~_HceQ!iTWl^3fC=v6FPt!eT6gcJ+CTgubT>N2vppB^ zK;O%gfrI#WfNdM}A%SK<@*$5o9L(;%<5nIhzD+YY80_Let(N;hDcerdKmW-&hET?` zY7EJ0!sVZ%!@lul8kjjx)FtJhZU;ac5;70&Azu#jwfBL0==CeUF0M<3xCAM@Y_tYe?( zV4tXN1CTP3@^kOoNw59lTDILA`79E8b_lz5uwO4`9nRtbc;KLeM4jln1J6E7k8;2u z<)p10Q%6sH?c23h^(zw>O~J~d%#i3L7rm^eemtK z=}De!uKDmo>Z_=r$5`&+36usEms~>5f&$9pAPfGuR^u=9fHF1?IIzL`;EOJzU}yp( z=>pU=f*;r3?X>N-e^F~g6ZzaO+R2kLBY?j;oNcFn`t-1F)xctlqiPr3J7t!*4_yd; zcp@Xl7Xy6}b#7vr4Kg2c%A#&Z@&rhJI{$MQJ%7=s#3U`P!PD8zO~H3QeF=Sd&%L2b z=EuB~H__5t{z~0>In?s%8{|FgFrF<9z5Rhz9TyK?{Tw}aeEhMPb%7EH0)V4j^D`pbx7>m~~@6TSSDz=Y?7R@{)nla$vQqI1pdA-G?SX~{D(8WLxbx$V zXoG_wo4<$a<=H=61qZ*jZk7S+8RTnrC%02Z?r!eHJd^ep=ltc%my?YL2f)tv10lIW z7kJay-Ol>R;aPrn57qzozl!W*0d~f+!K9*_`xM$Mn#E2TeDG|(m#?Yi02*@;ltI?q z{xF-425HYMchFS8?LZ%DyM^wZ1N}7Mzz4+ie|9R3yLDz0ECU9PjcP#- z)b{=dVSAG8fCl)D@*`Lu<>SI_KpR00_!?h-UDzFLK1?*X~H2Y3xi~JcQ$GjdA|Fqx^SEC^ zR9NZbx`TG^&v}L9>g^`KCx`oMGuZ~X4z`Vc_8I8QgKX~uEv?k_+G|vL^wHu`VB;f? zC|eYmwlKIotmH|)o$RA@{jnNcM#>7l1dAL6+^30sJD~1^PW)!>TjZF3(j$R3a4u;D zWEq)PmY0zA0Jtv`AoHrr$Tk3Z1dvCbqdr+i(v5^`^13{iN9pEq4w@uzFTb&xFFL7{ zojJm0A9pmuijR#0CcfUq0g)F0G`T-7=Uy#+j|**Y3|_T58vZ$3}0#*>W) zvLFHjJG&>lhdRnDD38yv->VIKHMpE?2S+5y589DBN4^}Uxr?0x?&USrP**Y6)z(Oz z#p49;kdxGdtWzr^wa#Uda>LABT~6kcP~Stsxx6Opko>6I0i>*O53ApC|daIb)a z0>95g-5g-5=>TL~YDgN8z_(gfvb-!K%S#&ZTV9j$0^~I{a1C_>xF_2HWId?EJHQhz zrNeCsJ2`D^I|z>0XCj|yn|)Uw`!g@wcu&RT zux(ymYreGqLU4?gCB-?`0o!bf#+Fe+t&dhlC9wuS2w@*3LG+ODia z9s%iFC2jJ)O!8a}bsc(REojVZX<=VjEMy5e=J~tWwsNVLearJ4H1{_(r8ju8dA-3P z4-)Yn*C9YcRC(a-w^Q4TFH(RVzj$8Dv-S7RJ(mJJTBl6oXa_Q z=9s^9DQ)}mmqp++@A~VhMXpJc$v07 z-QPf^*srvA7wx$DkK~=dfO_72o2Hy`8Wr^Qo20LXLNqL}r4?A=0D+{nqu-s86G>3u8=I^6^mX%ly;K5)pKaYR&4cHI!grDIc zQe}(Kg`f57>gi>@vy52p$Q$M%L_5y0vgF_a61HdS;n{lM01fgCkbGQ!V1T+RtH@n8 zPCS~O_32Mh&cO%s?6FvsSNaxKR=6Fvmwze!1+6*yhGYbwEjJ#?@t}l#Pj)-5*u*4E z+9&9Av3>eEK$9|7LruH%Zs~GLi~3o&+ByaOkVS-!2e`k$FF>9?u>xx6K^H4gVikh>1-ZE-`xdMM477Jp z-T@25reg~FDbUhNj*>F+SM4PS`B0vLvX6GKf9MbSfba?f>j8ej)zrvxV*1%f z4fY4f&%u0<%Rq9@LAH6;p1QmnHV9hOdKzQ=&pVHC~wv* z>e;cAx*D3vTUHy6u@xDUgBNn23+X<@TyhoM+Ex5qLX zV7V#$fcB72#EO>>yeoRge~wP}iFURr)=QwNS=h`V+jHmc-IOzRilC`@>NKGb*sjzs z9IJ!%#KuAWq4rUyuw#q|axCO?_zrtxqgWw>y$*7}u(7Ye3O~kS`{d~~C~OCHGC$0# zq6LL^KhrMkllzj5`vmSO}LJgv7a{3$G(^S4|r~BBY#~r*@_CuGk&u0ElqE} zK_!b8Q-I@+rFpo`0=3wAe0%kcmq;q9LVfBF-(JoOaqx$ZjJcgrobhXbKzK0olE z|0EZb!$ynOAS-XUf%fzLDo*>kO!-MCkpm8&jj#OVlc_p%Pu%A;0egQ~Ac??*89N*U zCm$;n%il=ou09B~y^TDqU>B}AreO|jm)am2k2jyj1{PuZ0;s}?3c5rlY+p=9GkElc8LEPu$ z#&y9Pc zJlBtNTvyeJJU%vl4?AS!^>CfCZ7(|q(BW3bps{0?Hfjv8^>7$RR36GjU8_PqsgU>fW zZ#YUGMZ0VV2;=NbJ8a7{z=LRAy%?}s*(nFvY4~zHEH@{4L-LU2eZCw;Z`_uo9eRV# z-7G61U+9o|bh90yE&L9*AIht)6S`3BmXpgVhK&>ub5ZLZ>W`{sr+Dcg~H_(W7yc}eqe|tFq^tv5N9=;}QUX)kzdDs`gPeT6)GcbfAOcZ*D z?T7NAUi1}pc>w*u#=5|mf!F<;wr!*O_dcNg_diHAk3J?|1gd`ULE3lkz0}`WFL-uy zpyzL>7r~&Pb<@F0j+lP0 zs&62{CyMessZr})`bjVM1@PhEzz=>GdKuWiPXw1;`)i0`S0UR(S>;?2Gk^{@}wsMsn*N2#eucaF{PkDK;uc0C4$`e+de3K^8 z^0(in=V#0i8)DJ1sK5&B4-SO0q(F;oiYl?o(Ttcrt;ORsp+}rsAA%Jrp*sH;7d~ye|Ii(-a8uV8JuA+~bZFuM(qEwX@6#vu-zrM1^{2 z6tfb{mhjuf9Rjaex4rn1cMC?9-{Mww{`w z2Aw?1;yMMDJPYyjY`u@=l~Yl{x^AWBcm7AtvNExEDSzGp^qn| zS-h2l0l09{Lh9q72R2tUd$xE}X^?denZf4pYBxR^03L;XGQT$1Ij*s8vD$!12i_FJ zqwtPe4mb+)$unUBcOI-3v1T|gXa^jaMYC*Bk8G!t`9Xa}$FAahPHJcUIJnNdRjb73 z9k9w3fUeL!?3od+GepxMA4T0{QFH!)5rjuut zd>wBzI&*TV@s(GpnERC*D{CB}a0TSxGI=cPE|&EG`WDwILL&YjGD168^~*hGCFO7+ zchdMWcA5cY^@e%I=J0>~?KbkWlg&M56?L;e8h89^vga4jAkV&QIiQ7JF;Od9vxb@< zd4&Ajr0Lz2>m7ND>e;3;j_s5b` zP9Y!OuHyQ-S#Q{|+xWl(LvM{m$dl`0+jcU|cw-5loTxZ>DXpD5lOEf)lWHG-f@R2g zm>&2o(CjHJ7W-h((?y@pFQlA94(3T~2?Yz-XRr?2pZhP{Xbd~frqC((Ud?%_;JlLuQ{FyXV0KOPp^r9$zqB2Syaff~ zvjte~!zv+yWzmNrTR+-XR(}DEB?Si`Or7t&N2SLfPyOuQ+Ma$&*dkWxBwTFn$HGPm@PG z;g`@3{z2cC;|aHe?@tN;)YL>B?2}=a-1#^oO9K9#^Aq;+VZRykhBsuf;tDbDpmH zddguR&k-BdJ@%N;S6YGKi4UxAd(?#c>}-NZ@7x*mO`IssU4@0ggSKuB9`@K{!TG=a zZP4NI1l>hN!Bus2!R60A7d+&NCxVA^TK32z!3k%b6=Y?IH2%ypgUcR%Slm18$tQzL z?z&6Vhs1-Cp(NTbEe#&u(h^+v;)_96e7Fw1RCeyU;os$-{&aBSSH2QF;HN(gR$OvP zkOP2V$=PQ|977z)T_N$cFs9*ua#eXad5&{zZxtD@2cyuQmLwrSzr5_Zrez+ zCn>g}mmp*4zm)Z_cV8woy^DXgB{=@_&qdsimZH&wRHCZ0R7cm^YqKUzh&UffQp+rr zN!?EQXFem6JkLGll<@CFQaRhEx}IpMAMKsTRW zDq|gt|q@rx{zi-+BhCCf7I-{Y^iA~^ed-xJ5Oi!K_LN6+seUj@r<{1smeF8<|D zgA-Z4Grk(h>&yw`gdZ-BV&m%mW;7YG3w4^t_F;3nf^)v}o#5&R?hYRPkG}?wy!9`^ zxvU>`KD~PRA90*LdAPrVABh-mH20I4V8eEoONgdFm6?_J<9V~epj2y5|A^- zit#*Flo{+N74Sbyn~lfRcz#|l>FFa{8m6Z-B!@FMcT0e0C49m(=>rixzTYtEl1r%i zuYVP<_H$6hQMFTiLutyFzf4s(-6W#JDVJSFwYS|y?QgwB-5-8P9Xva%#;c+n%_E}k zeE)qB&G+osAyy*#YHDcmr$0@tSQ+9OP%JvsaOC9B^ee6)2S>$~cit(!(S)+vgne3= z84re5y70Si*DgUDXuz9T*t3D7h`e>`kO_5(yr?Tq-f-gR+Rro&@XWZMBj=6}KA;Ys zZS-v4E@;7{xFc4tqRKs$$`@j}jA#cmYiVM+1+aL z8|EB9ZO=YS13ZI5E86_(#Qz97w1CV++bjd*Q_Dl%S6{=jJNVeUd#_kE8VN+5Qh%61 zrwHM8Ksy7r+0S}~esXei=}exHZh!k-@s^EI;1M!(gnA$sDJLxyxrTIUkVmbo^?>#V z+uNvT=T6%H(Khih#ucoOXP$eJ>Y7`WJRzHeKk>|+D|`o5lhLQKiidrc-ud&DkFoN( z8lYjIqn$jHrclG9kCDHzF)A%#Fik<`(=~M}`Nay*b7bckuxu|H1RV<&hyJedhSa3AkuIf#V*s?tX+S&FjkC;Zjb%guhxD4 zzACbnlu|oZoJ&fm`y+){^p7LqulDVyewLlKeZ?+9HmRX28jRS58ezG9{4w=b@2BS1 z-=zANUZ%!ZUZb{m*xsdYj8ZQ?O7n|QKiB%JVSXfZJ=sb6Rrtg{9vAR7Df)6eKPP-R z=j-3INAM=bk7JpSy~F*kHfhHLy*x6h$BKSV@y3d9ex?gPL3jL$l7Lv_hhE};M7gxW z=*p9C(xl+A_4Pq_e!h~QBQG40u-fFUs0g}CN`go4*b#L4eBpaCFEcFe&;Q-;BBFVR z*Bd;xu`%eIJXxG0U%Z5T;gzSCUJ7~&3Zj<{wSyzh@mrm=_hY6+^2($tBiob-*W7M* zaKWMlL6_U5TPC6|PU^A|_w=r7uZ7N|)}fcwdDXu)`CL4M0w3T0mOkt`Il;0|eJbc+ zpM;}5H&?mNN6dh6Ut31p=elNHb(L5R*1NBlU}snXs`&ipgFJXgv==SmK2`~A><=A$ zK7YYHan#G3lH_oRK7^z0{aA_1lwNRQ(8<14&1+a6X|yXT*J%2Um-wFuyVClTF-aj> z)IKk&UsNYee%j_E z_+e^$s^!Bc5+`+Ri3f_dUNRzR<5f9fgKP7~umna*dQ5&K-!yoU9W zM!S-7jiz5CP}^0qeTX51{G2?>-*KVJFUOBL2h52aKcXR24#&6%<&`OJ8BJb8WkLYm z&%S)G1PgPY! zoe&5%DOQ|v3Qau!e6fTG3=RxX&26_){no7sZx~;>V+XmmZKJ2wt`*;$5(={zU^FoP z?c27C3pz`VQ)gCQS_RMPL|b&xsc_P*q566=4e0NLjv(E^E z<3--MkH;u&Z@opWue~NVg=1|=1Xg?xuMUb=x;b*hH7!JWKDNL8HnnkiqzC)_av#&kfdL76^HSQe#6SrSz}Hrx20{C^FT2q`G4XJ{VTk z2ax5%T*&fa9$>@xkK^zm`7|>?qolJ5pIWe}KEizP|5maq`_!whqNSlf{t2SvCXsUp zIG6Y2u!dtq8QkMRPb4Kv1aK{UKTZOceEZupos+x1mbU-)1{w(ctvIUz{2=0L04WO zRXzBS_+yZULXboQl_UuRwcta0Q#WoT$3QP_`|F?SgUi1n?pZN-0>rc4d2?v{N7mm9 zfen8jfAn!m_!z4Wm1;i53Yo$Ouwc;w`ry3}LTA=Q)~?J0coOV+GQx-1#}()Uj~_E) zFP+84LEHE4yEFLG#3__Jdk(pCbBXY`k>bGUKo((k$uPn}zxd1k^>4jNO*j96R?L|} zcmC!^>gwpQ?8+0qo3duz8hZSZ$El~=_;;?%1j)zRb!!D5_!4xo_!#S12>#r_+V#xG z!>o@4_u-id;Nyh#C(vULKW0fj+#WZbeg4_PuDUwAC^s)x@bRzP{zZMGc*`nX$RxY6 zIv?;T_&$>KS4Q|SqhAh>A1Cto@u>C3537xXw!;ou9Nf*;gwF>!-EO|3e6Bqf3=d~X zANT?sKMhb@QuZ{TQrRhZ0uFL~?6|6iZ>aWZ=phF+o70vVkwq&`) zk!tXyQ%?@&gg%tUhHbeN=Hrx;f;>261Ru%L2kJ;i;+b`D(<&9M)?4@Om1OH99V<=}RBgHCIOLI$B zA0|L1@FCx}8z~=* z&*iewqQyRPx$(7id0pXS#;h3`@wUYDS)BG$QMngL7N|Bc{De}ss{vrLDUH%)v;T$fCFUGd2j4-EO18Tpv03h;wl@#0O?_nJ{yhHq*F1v@i?r zYP+&BgkABB)CeDuwmBT>T9XjhJsDX&cGAJSiq6zTR^XkV;6P0x(+ z!)hyN8N2cX`9le6J+OWZ%~lQY5x z^rf{;HH`L~R6tK3@#r-pMq^h({!>Q2a+FMYWm5kb&B~KRI(--PnO%8GACek8jg=vx z9Wis5uFM>??cx-xOba7cnUvL^0-k~4h;u#YmrV`^2O}#B^T9K@Oqn_8=_3}B$+MWD zk8*`XZC6%CqI_s=Qw_Otq4b-vMKnHQ(Q8JG#;%0?^G7HDWOcK#=pV`G$MGQeNYV;g zy8O2EyVIs+#`podvee2GcD5%gfoWq&5!gr*fEh#O-pcSdAtLW1PzuuIscvz^IndV| zpgfBUVZ#1_pvc zZv+03*Q@2jsz`*7-kt#KVo)6Q(APUiIp{Zh9BcIU_KF#)`a_1G6aFR|y=KH{>`f)rYn-4wTmg)q6kA0Q0Sw}OUwX|-d(q6b6*I!rLK&PI*o+ga%r@8Z1az3s%luxujq9fB&T}d-$*ophA zpr;|!UQKm~50>MJ+)jO618v;Aj!Mhg>F^`ga5>I5>h_gmgq)ImjH!=kbgg54Ip2xv z`6%=j`-m@QM?2QCeor}VT}W@oP*qhOw-Y^owBs;7__|U0j2s2u29ELSsbhXOZ9b7o zN?|9*vmHU+L-&pHfqG6oV?9+=^w5mi$Iw3X3spVxKKjj!Im7R#>R4M-OQ)Q13avPD z1(lSP(DEaf)4T=qXz!j%I_=Dj3cXB^=*KCbC!Ty0J*xEq`^R;y{hi2qs@}hsrm%k; z@cU@}Nt@WN>sSto{HM=3n&qFEU5kDZ(r>Kt;CG_|epB5)guR9P@k-h^!hRgCy6y=4h18 zgpZI{NN(uw`1mUH0lA9nQI6ViBx1Y?9Z|oyuX9|tk?*6NJaW8)Sz zdGw=)g;PWG7dffAYLHy69KLR(T;vgS)p9wz-7btKOlRnbKkd-mR7Xn=%%hLC^^()+ z75Ve?yi``&MLTx%bCg>%M87P@^^1H3KAJqCZ&IwCW?S87NjO-Wj?x*tT z^?9kitz9^-j*brDpY~Vn=YH&?Qqhn7JnK#kJ%aDNkbG;0%Qw-Zo<6j8=iy^hLoLle z(8YWP__|NA>yY2t$^J+!|7i9baWq;!#4r3#9s8YV{2H~ZkscxU`~ojc6#ba(P4r_O zzD9BUPJciB#Ni;j&CcyLlFz5KZ?wGj7?!7`laH9J<9m85ogk9;_o%)FK>Z4x12!ED=TD)B&X9B zoH?71u91BO+UK(e&p5Lp=*tN|Pa9E+_l4M;97phyOQr;Ka~nI|x zHW|&ANCG_c6zy>L!H;mX{2B5O=g1JF1TRAsN}{SL+Ati z=-oF{0>9^;KR#&ZqxK&7fIf`yfqE{yFuL60-A{GmnP0?tGW2XD**KkZ-Z;^o-u*<9 zQM>YbZNfi#eMA0rwEQMg{?yaUV)8o{{Ug=-<$r>1mpi!m^o_xT4k;RT-%82j^#s?S zw4Uw7{QfFdf;|blvJf9UiLi^Agpq{(! zVYK`j!61(f`>XcRgh_UCds5?@^n75lQ*bayRh3mV7#P&OZ zf>7s10G2pL`=*T8tmSafg?`Is`C4|MKCfg*TQaKWOn{g#yxeON_D z;A7I1NrDe6Ai&N>4{EzI3-A`z{Dq0VMU`%S1V-VjB)@Q#2nLMuk>?Ium0l-b{TLhw{toFk6FNEk)bHX5Kj zWF_sqkO0VaYN?O#LhNIlcy!;Yr;k`5Qwi0D+4PXHPzKrnD1ddjiIwlBGi62 z6Tb6={ni=(ou_EC-LZl?QpF4?6_M&#=uh&YxALS1+{TL1f&+cz)?Hb`%AlPpN=COb zm?+}uBNh5d6~M>DDHBsZvraVv!G3CJe3=J{{?L{5L)d0`)!G=;{ljXI{9Mq8&c|@QeC&yM<%R1O`J3_vsa#gp^ls$CLoI2MSdkFo9uqcsJ=N0q{d6%dVI3?_5u=ZT{c#FN`-gv1ZuzQuv>rSY5auo zmf|D)h4DlPM%HvP7>>BBs|D>=kGL^&Fv^FW^OO|Dp1qH?I3ypKIY>T6Vju8hQ^t6| zmKJJ0tPI#mqN_Y+1imni6#^Ws4A@g9*p*rP2ZEup1neF33%|?!j1`hSW~%*eV9@$2 zPxywCmH4n<`ngN#yic7+UavQ;0Z}3Vog(6%5V_J}c4%!P%!g*hCLYqg=S+){@}ULF z4y~%C2XY3KP8yO0v)M@^zz6Bhx!@eSd9Z_~8CNme2+U$rwLiS4LKBM$?v2 zjHHb)A9cp~FbnLDJopGb^~6)u-`_uGM31%^C`Y|Qpf$*3z=$l+Z0xt+Vq+}$7z+qK zc*c;7nRT*P72Iw+tyob+9*;4)g%I6_2Pb zBN%BL$S20ZaTeS21S3LH2MeGbk-0jl`H2@;ATIch&9 zyv&S5O&nhq#~Ptg^8jP+~PT)X%NI@`OJ^JTMRl z`{c2Nlri3hU9cdR`c76=TIl-PXc|xrTgUWLxrg=w=LnkNNX+4Dq8z zPY?P>t2i2gnkJ*P0YmwXmsRIe{~k7dzzqm@<;oITv!+ZW{Km=(-&Hcj0LmlkJmQFv zN4O}06`gqt^;dLICnD5}aTOx)OSBC*F#LI$Baa+y6fWO>%NNI3@=@Bf(b~0Tbj&e| zJOv*db(L3?kBE;%f%-?Q8$Ado_Jz8+hQS)EU)vmzR+Fcfb0tja-!-0{A%qQvc!r8u7M7tKwilI@WTsr zZ6E!-yrP0UUI)#Y?@CA>(I9EnYfle)`~nHtJKIggxN%fcTEJsmsqhuhu~B|N>tTl# zvTuQ((3e##!2io~xw$#QhA}2Z^U2b$9d%SO9d}$Q9e;cok0s;D>val$6>Y@^*Pu_d zg(LnbeXPC=$hI&}p}pK(2irsJ)iGR$??9QdvV3uj#gBy2mYv(lBcJr#Qx66z1?9(YK@KIM+EPj-T z9BnULn8P!ToDg4dR)b<@t>pv7v@%kDD?I4QU!MC}f06gaPXQ<&Go2yb43&>e;g6{4C=6xV+zY7-Rv+=t{ zy*Bo56%%YR>wz9%S3N!bZ1=HgjRti7#oTsZU*csGMPKiLuxAW<;Puc$%Xv0E)SuO| zj0Mf`M=ZYlT$M+k@O*BSNJfK<3h8OT`dhz014(4JHJZiw^AXm)97cVZLgARgjLN{Xo z<Ds>VyY=K#UrvopJ>+uskkdZgz)=nzciYE3^yJe$bl=uWF`xsO(SPOZ^C{Qs=Fx1B3iErp zP7oRjZU$}i-{<@3iN~tw`#)I3MB*AzWBmaA;pX>+6A<wvL2=%ej+y5qK8boI}c@*ves-CZ`S ztqstPH+~S7TW+3?w|pq-gxnxAkJm%T9eOO}+=(t~rUsi9E}BKvEcN;^G@ zZFs$Q`qGzX@hlrFc{bX=zmIOeeLH>cdyCk)dFh>Zx;YPYtu|Sk=mg*Y{!T7qr<-p+ zlp31+v~)?3m?X~Yr20l5oqP84Vj%nVZY0S5WA&znngxZ|OYq9Voq>g%0!%{A|HFkz#={A~p_ zHFmL+=6j^*r>ctiy-sN-8qoKSI;w=0ES*Rbd2sT21Kh`yKv;pD8XFz-v!8t+^8Vq^ zNAP(UxgFgsqdd;)%>wW`%iLU+KQnGQ-R#`bn*ItW$ zI=mh9$!~sZAuGkj_Awq!r5@oR{eJ*W2hj-`UAIZ1nSAE~SBf^u=zz2R$oxvSrII zaRi{pQ_q-9)28H7X<3kJ_6O+qzaP>M=)L^%8LYh=TDhu-ni~hW@4d?Xcc@=%-aLcm z%`c$B!T{Tw@-=s9kI>bh{<4C~OYz5kyM_II^idBrH4**vr`y7GsDWAT#TQSeiIdBi z_kQ{r%O7&N@#Z60E?wku^pVG{*uzjeHu}F`F~8iWeO~a30olO;Z7!XE&RZe?y!qzC z*iQPn{vrKUh5BD_NLTnn)8G0264tk!7S3}~b#;pv5Y=*neI31OCB5<5^K|8R=8zNp ztHDpdz3x3-ovQ(PZQMAO7A-EOyqqAn*DG|Rj2F4wzdPtV-`>IO*y;M;9ZDT-lHMWx z34U4Gzr1!S1y~IIJ?-?vAMW5w4(4$=HMew=lly|gqn+A2h_3$0_6S*{HaGY4O((CV z6V`Nd|MinEk9~Je4}H9?Q}7%Qpcw&QWn~Xdo$BNM(ru`m1j=LJ-nXxpgP}qm=lt}+ z2c2S!iU#yUEM%Z8{0$yyzx7r#2SZ(AJXDW?YG5UL=1iYxYwp}a`tZZnP=KPJA5da| zJmK5H8+hEkyPJJrZ2IQS%VYoTVVe55o!IO?r8p`DSdtu|+?=O4kg?NqFP}sU7Uoi} ztDUb$TZUFT=$~)xq$@u6G7rRxWAS*M^rN30Mi-wyi*gFsU_H&Dyb=z&<^OfjcdvYn zgRZr70MA4*)A;y<9y;#Wd#SaxPca;~iwBq`^zPg5vcMz%1ceyPSrO-5Fo{;KolDCP zDx<>>+e&S1eYE9A%jnX}7gAAYDRzcKo8@Kjv~go8-Ft5fJ^%d4G>3(q z=k4bJrh}gRubocW_^>bzz~^(ZBV100te8X#7rCe;4~~s{Y?vn}J@=A>&OZG~`hS04 zP0Ls0vXgOeP}9qUgY%4+gBY-=UqIVo$4SJ=i(k5gNt5&$4Mt|c#{5h+e%uq%E#9{^#1#3=RP4fAUDrV zw=f+?uc%;W5uk!X_T<8yNI0po+Dl6o-A}D8N*M%mKl#Z)bioDl$yeZ@_uuZ|VCn%O zPsmNs41FBL`gm)&J}@9`*>W&#K4l&imIi4;8FbErFSoOFA!t+bW8nVkS7+0gzkC=E zMs9lh?RE}gAE96W`UpDftYYp^Zth?$oHNp1V1oq(Pjd&bahX$S(ljsYtDdhTpOZe` z<)NhqKEQztPXhjTGR>cj>j+fAw~Kc3{eup^pZV!$TXWHhBbU(^E-#`ZR~56o9CZ6X z_s}=K^isqi^OxJ!(z@fz+5H44KOg+qc_!#BKBDMn&mJEw zU3#C8TQp#0@bjOaM(3P+C@nk8$=nX9x50Yp2pdi#SRo=n;du zgY6`bRv!5mHEE=){HQ=Tq~I~3zgJ(~%+AfnP7eGi?QGxeqeBm7xrORP@O0gcE9v;- zC$cRKa=-wZ0JdkggZ_RSz5LRtbl_tA-7?ezeJgfSR`x8*PYFKI&wu}?V`=%J<7m!o z*4bPAv})CTJeybAfn2`yr5SX>h6CBQ^JpgrJ|~`VKi^mE6{{B4Uw$)=1KS1sVY#87AGmli?cMzm-SfbSbky=f+QEbBVF%x%t8+Er zN3OZ%a604MSv05^V0*lJ$DK%;|Y_;6RAJJFWbrM@0?1D=EBESv#)rP z1715%NKdANmwCBQqF(UGy(eI!i4~Cb&;&&E`cOar)P?!9e0dp_jStee5|oP`Pz(p? z!q_N}i9(hGt!URs9cp=j69b!V1=MZHGVyqoZ6(4Z@_{a+{79(zGFnd3WRx}u*;XQD z)%ld)_F&M@gP&dsgcFP!OMMHMD0`5c+?i;gl?RD#RsP6?2KxK^sA_lQA16im<%gq_ z^PoR~<@i2T89(Rk=h=iZvkTfeU_nO+w1~QRj8?Am4?N>7t0)tDY;djx9N(smlj+c< z9-d{ia63GM=h@h@gNrDK2jF0^nVm)CMtO-~&_+v_O{SY}I)Elj=pfr*1NHZzOds`i z4|PHSQR#t8eKdVa2g{|I>1-4EBtJYiq7FDGCeh&@U}xUWPO+5-iaw?($N`z1%F847 zJYgl^^wUad^7syRe9e3vgACWhgF7*84hPTHST0D)9ty~-kD8mfUH;GQ7-ZdaGA)=n zMmjX`TUcnP9A7ip9FRW(wjueWot73{6WIkY6P+^$&&*qRoK(taA@)Lm51l_A+zo0P7AxlVZcDr?aP5)Pr_%-0d_FXy~QWyFA zT4{jw7|Cy+urbubWKdyV8}<2Nn~*8^9i;9~$Ox;60q#r4%QO5S%SFt_hr`MGS+t~t z<=)En+$3ZNdi^NN^`MIs6ts~oAp5Iw-yXyaU*XqnM?3BOn{6aoJ3IrPKR;j4jK1IB zk4Z)!wKn&L^_QRD#(hKTS+Q$}o%^7wPOM5!n&_rNo;U#2PiGvcB`0>NH{?6q6su-Rxj(bO|1BUUkO3SB#*GUe*ciJ)pV2< zwXy$c=X0h}*rT6n>hYLWR51*0kCRrfok}^L4xu~Hi>(29x$M8Vzx(|iy6qI@wW#_B zVA9$e#|`bs)@-gZU|EUjcf9f}bJ%34WQMT=qr%Y(oe@ z2L~0OSX|uBdVqhCGT=Vfs-AeLz%s2ES5C8M=P=Lhl;dR`aT!UEv4rtaeM~gTa?q2} zI+QV4Nhqh6M=z<{lGlcOzkZVK$lu!gdP&k{G`~!;twhSnyd!N({?^{tOX_^eZ|;{^ zJ%Ceia&oB>mco_9=E{!6MYHDcOpb#EA5V01eLZaCcx;0_>T*h1?gGLwb$9SU#X*9E zi_0%s=wXM|#|}YxWP}0Ih7Bn^8^Q+B9Cjc$^X3xe=k#)0?7VzKUJLp0?7gwRQS716 z3xFIvAgowXLGyWbQe2GAgw5G@v22M)UAeivJRpG9P=N^8XvVB^y7=O$JVW$Tel8vt zDND>bJbO|@45V{>G-VRc0`q#AXUG#gVbwuNJ}!+sc&%G--lg1AhP_X}F`@>JfD zfhO`;mqkUrl%J=T{}8=-d2W$U0&<%*tANXJn>jsve<+ZU0iVzZ_`ow(4N!jm!U7Ji zxO|>`jN+nVjr>JBb4$6Me&)M}^D6Q!D#FH8KMzupUX)W3>cOT#)Pq!5*iE@iqmmD` z+PE$pai0g7e3mB<2+BQ_ce9=0r~tOw+|)!B|kps~L5 z^Od%Q+zOQY$O$<)9SHuUT-}@(aviEi4+t<8EgHvza)A3;pLk>^^&{)5D2J^m{FWAV zk;eraL22m4PKB&rltIv%BOWCU@<0b$L7w4&+^5ef;(pT4G%4 zxesE069!NP4$e5P!cC>zujQj3AU|)&4$8`g9`P!2gZ!2IL$L8R$g@v8+8jT=SLjv( z6Pl^hOKAGkLCS+4%2nEt06!Ba<}%Iw93Vm0iX9ZF?6HFB$O+l4(m4A?uSY}25S$!5 zAGB;76&Loi{)Zla=jU_c{_cv_PU%oP3cpUu^Rd10FWkqYW!ZnEJz~p&nhtEDE-z=_ z!2S_i50rKs5pqL6Z)$Adm@7czD_CxxZq@_ajH;e!z(jNLVh{7yD`-(@2MvlnVKR#r zQP=o#=7;SKep9PIq|zd`A8Z?O4sAIoE9(jMg(006bDxy7tAT#r(%i&>6WdX#;@1$A zDfAdgL*wJnxi(L{G?Fq%nDooCkO}-5j@o?cG!iGe z`P)d6`PE4;pI%bS-9gT`{&yVp_Vm!*|G6i$S4G)Tj$P;JTMbkoz%)KU{i{us=9 zdSK#CYG`)TbI(@ObN_7$KktRZmOI$}{s7fADzj76t4wpa+xg)Xog6S=ABcx`?P{aW zPCvcyLLGOme0u%uE}pdyQg0W^DCKJEF~i`WIOE;|$5vK8wDP1Klx$ok7{v0nhi5Q& zv;;>V6b=wvJ$h%p#T9L)#JeIMxiwjV1D)z z{qgr7ihWU-)!Q5%<|jb?!WSxZwzq=@W#y@~tW@wL0}&j$y9e39;J2NBdud-)fbO~n z`y~39Zl0YFV71Ce4NZ1>;kkYE@+&-3V`mW<2ynX!EkF}bBGoKH2II;UryLAA_`a9k ze7%_-d1OE9a8S@&RGKR`{V=>Q1-3eAs*~`n+~smoTU#Cn zP{j7)qM90>dA4*@Tf2jUI^|7^0oG4Xe=fcDdOL0X&kojCkP1riHl9)+?5MoFgq^Np zC$O8gu7L;{f*)n|%_-8yJDqgv-#(@V3oC?N&_`@`r+7TOWy?omF9-&XVwS6#Up=6_ zLJJzSGwrOOx7+Fdt=qXQc(l>v5WjA>gW9|DD2E5Z_de{SeS4bNzCHBD+xw`C?PTYk zI<}KM3fjE%&U+k&48NK(ZYSH3qCYLrPGKP)Z2_p$P4B$hMQ^=XE!x4Ppo49_ zun6rGuzy)def@sU^EjP<(Ye&kCiL&y?-T>LGO$BRc538)iTw+&yvmFI1NL6n z*uU85y6ZlqewO>R87^^O4Vy4z&}*mqdb~0|L^}rYygZrTMqS*#+U|wiiiY^vUFoDh z-TV>vAG~y<*kf}u=pg3BMIU|CK@D|{w0(Ck)1hw%>}km3gf1MM2Y>Z}iQqN|dKDT6 zIc?u&r@#H}LnD_mU z{`t?3Y2G{^)733jCE*h>=G1bX`7E~&J_yn+fBsO62UA&p3cu{PnBTlY7wy^u->kG< z+mI`CURh}qJ|ddV0nyJZc%sI^z7R0?<4V@w?|wJrTcQDddHM1}Ay>S#fb9hf7v_mQ zTYY^h1Bn5Qtp^=cAj+Z)d|y1k_V7ey_3H7g&t7`&xh9r{kJfKGksf{MQND(;HnJj= z!C1UxNj`n}VVBs;tk9`Uj1;X$0^<HG{ILx=Et~?-*3IuF7_3@ z`>t$9pE+3$Z+2pTp~Jy(#?$aQ`k!5p`SE5Ze!tE>eA%)B;cs7j5l?gCwged9S6^+VLk}$^=NCTz3KQE$Z@z|&heJko*=1Pj1w#%lm`}g? zO(m^3+RL+P7!RU){=tLyfB*XtU4LDrQYeJaewGKM0yxn@YHS^vJprH(vjG?@I%0Qs z0loiz3lDUC^z)xr(nXg{psLyy?u_gNS(pk2she$F4q#vsGl!<8rl>1VTs6-qz>iJL z(B!r8<8jR;e)n@U10iaGd*jORYOpdh#(xgGhw~OtYYX0t8!Ds(Bj{{+{yxa^%A>Xp z8~y56kcrX>4?9W;;IP4uRUxh+dPUt>;%sih;}C@pC<^RgmIXR-&Fd|o#>QTHnuDaC zUOx{a-NF#qwQ~zj4s6@$#vAs~L5Jf{SJ>G&P`9E>|DY>^N5nQWcqT3DwmFOF%{S}m z+G{!D3*m^BKA}4aMV1OZ00K#^+>{j?=0j)YX-Gz1P7dnr_t7tZSxJizh69dlr>ty9 zMgeXIj&Xo_;=3aC_4z`w9V&O&Q9jWL;3RCeJig**x#Ur0br)6c=%hhz1Mx2E&&%_Y z*Ih^-Z0id1yy6%y%T1{d@^5Wvq;cgOfe9Hg-&|15FZ5G{+ah@4pt{XVzy8fWy5bAi zh{*T39oWB}ZRQuh7^3xvm0spIwqphg3m^jojNqw|-u<9GLO+Ket?-MW#ld|Oc2!kl zbbq_)CZ`#ww3dM#(e(G!A+E=@t9=lWVDCZn7QR(AqOlCbl*d@N;^Jo z#|60}F!$0kPqV$$i3z_wu52v)>T0ocpLi9_F)a)$kpf=GTG z9I*Q67i`xD9_&!)V0%O##fsdZ4U@up+VgQU>$5=w0eV1RnK(}AD~i8R;PWW`f~T?^ zkU7|{_R^9=F!@m1eSiZ}C-;wibk4cuR9)XL`WIgE!9)u(Z{o=od^zL+yI1!=Kv`9W z-49Yp`9b?BiHtD)$q-&@$v7 zV*#-V##WSvo#Ew=n{S5B7kuFyLblNM^mTsY<~X$<>UqE!3Xx!J@?emYp*u4A~6fcDwT}`E2Zq-y**U5 zzn6SDM0TTX$}jyKmv_inA{S$P{h`9!M- zzH+&*{O8{_^zg&=w6D6I-h924+f+yXO4-7a06p|z6+QT1J?Cwp2Og|rI%=q~rH$Tw zr!9h?oO~Po=gwM@_rV8i>5)fjXxGj*p&+l%PP69tgxvB9xXuTdpGWFw*WOlo;rT{x z*GUTwoKKZ|D+M3nI@uROMh`qtM_aen(zDOja1hZe?&s|(6>tc6h8@>8+Q-o8(ex-$r7Si55d%2t_7zX=pq4WRzyN>0< zJl$VQyLY#X$G}y4{h@Z?G?jL?-UXdQMs2L0Cdw}g(Bmw7QTBma`uO8^AzQ%10mR$` zyi~axvg4q=I6zzPsbam?h*i<|-)rPxpoiXl8y_e{{XzQ29aZ%7lhssJ*~N4d%{jnF zl_7rdF~$QIFQkU%y>#3E+fR=^R!4i7-`AL5xw;B|gw8|!Jj^zX70C&cZS>y%+6jA9 zX3fgy&Rxl~JcU-!sct74uwgjAc#!U6y`t`|;N!VE+P`0U{4MyM=jA@-XKvX}iw2pF zee~!f)!cS7_lGX>|>-IJjk}WcW*n*X1m_Ehl5BSpvO%J zvYoZlt+&=wN$C;v%v1j(x7RQ3>jkqy7wj`1xUYfz;Q-fLE9?iWS@(e-_?L%kIPmD8 zS#y^Sg5gRtW+u13SyCkL86ui@9|B?R&WY)X7Kjy zu|Mdgzx=h5XZMX_B@jLw^eX*)0afkWOAfc6^~AoL1Hu=cgIr<<9pFv&8~C2bxNlWf zc8HZ8j2ZaY@JAnZ341DL{efSM4?A~u2zuwuSL|M~M`aA!v6JnM{TqTI=u+w&J_79> zz-5MfnSw2xe#ZTL(c%Tv&{Rpc--dSTg>TuueaN>&1ME+Zk9+s_iv7S?nQLns5I)8T zuzH0RCj=(4jF`;ENmzBm+u^%+cd~u-v(CJI8Radu&Q5#~lmqN` zg-*S^GRbiqZ|LETw&rH+2a8@t=C7*i74_q{@pb~#*l450%hu9suYAns=)9`Z}*$y1yD6buTTqFa?S!CfIWEbxsi4t^P!&~diY_%ynIh^*$R)ihPJ&bxkXEQ z@>1VB?u6X9`V;(eIy}^mAs105hK*`v&Hspge$>jyer|>&$DwFR@ySE^F%BNK{4jCU z%a1fvX6UGwPo1>w#48h-e+z%9S0hKo4|oIc z2%@N@D1r}^EmYMh+lDNWACCavc%w~3(vmhc!tL-(62H|z_IUJa>%?hZ-Vp8hJcAZO zA0>)Dv_N^Z$xbYEMYa(M*$z8H!WZVz4)WosE~|yC3Qc1JusSb0P^Mea8Sdken6@r8 zDUy$(LO08o!gQ#C{91mX7rf00dhw}(mX1!b0agvIT%!RS_R$aG0o6fXT7GdIri7!E zrMmxUfqYn=$0Hl;SHP^82QzV9-q*IH2JS;1g+-2G_NIo&$9+*tuk;bn5Bg`cb|kPu ziR}b$ypBGgWa2S7iUG8(plniH;t??>rN>UPw2jTH*m#A~m2uv|Peb$SKY z7wJE=K=Hyt7yC9RwRUvz%$Wb+==wYL13uN&@mo{^2!vt5e1R?6Keqo9=rtOs+e;04?T>PJVy&*SI~!8OHYhm@Q4z4T+`6pEp(d-q{iOauKI)GLw%8tvCRk2 z*3Y!Q@kWQK`hXUa&bQy{;NyVOKjbr-IDqXmG%3N;Xu1uG3VUqojBAg$-_+729_`=* zhkAAp_PYl8Fe}3ST8U@B_%-(xTW^D*VD&K=7fmE35EfFnCH2qR9{j zgPB8NQDM}TC#wJ}7KO!$@d3FQS(zA1h#6^UCD6(cc2!&?W^!z4%0(S09Xxs`cZykb z>Yacd9kSo3`%gT2ao;LV3jnD`R~ga?(211|yoFj6wku;$uf&WNM(aYpSZ1L1yAn!% z^Xozlqy5~>kmI1VE31x!5#zaq_(-UC%1)K)&JwHh0&wz(RNLFyQ?~LH4eo}l>wbt2tV&te z9?aa&jRp^pe^?(Gu<~RzK9V=Ji2_9sk;2fsmIxvuRTHc{jfNkw@{}q*n55ClS`T_v zLLUW%1sSpOR8S~q)`~t-A;V07A{X;OO^=?=qF+-m^84}1D1k;~|A;JO7U=P##*p7t z_(~M9>K`t*$b6CaBacAzGLhE+!3X+z2CO_46tP`pz{-==_^>0=LyAVQ85u!`P|xJl zok|VaZ=&2b1;olz`*1!+BlT498?R2Gj}RZDfm#OX&>Q&ZU_KPPPXhrKh18XDOrG5O zdhxN_AmQ6CYD60pO$nwIJan{o7+SH3lx1?DC$EvnQ2Je~_Ydi>tjq`WC;U|#?8^Ep zPgdi@e#vJpp>xhZhwxYN6+<#VKqn&AeEjwO1Xpa-dJ(_JKu@wwJ)6MFQ+|HpeCQ#0 zHU~O}(-Mn5%oqv^QnT`;@Rd46sRt3ou9O*&o(x6iX|R&=`D zbk=$2(1n+rEmjC{Je&QL%Z(4gCRZ;h2a`MGuSTX=BXWy%KUt7`D0N#*4=RNFc?$eh zGGJsZ7|l3nCRmjZduwZ}Dgrkz)V={7S6LyjZp1B}9af$?I)?Kh@2eqiE62!t$%Kjw z!@%mL)W=vOzT9HpS3_-AvGT=3oMuJ^6+0OT@y;UqqxSYTWi^v+3rD%)VLAT6PROpT zI>1Rp@?l*=jO^#u1bms`LudT360FLH{q8&OrU&nPkorSk^^AqF<|$fx!hs@EP11^u z9z@$I=U4et6M1=gmYz8PSgFa&SNPDw*vNDAfL-O~=Z5%5Odn(2KL9kbW z{jmi4#K3@`9=`t}+WMb|gj2=wq5B`C0l#0|w-nfn6uZh}Ia`c&4HQ09D^GkdlkFIV zGJeQ@ZcWH>(CXudRr%mCPx%n0;Z8jUoh4rVpcRp7S6A1VN2*EXoh!r26aH4+Sn`pI zX0STY)v4&i$`E$dspun?qLXR|CdC+;V@xO?(Zok`tvkrUP87T9vg81#wsr8)&3;!5 zcowk#X#G?fKf0L@?&l`uBc83uad521k7UEDe5BkX=^3xywL~Bz)tuZMOGn&HxR^z! zl8>>nLkw`ad5O*BMr#MDfHDJ8^uY>JE@lzEA7>FCY(}uFT%K8*ePD>!C#ByVDIf9b zm(a_nZc^UYyJiI8@q_)ARlB(y2c_S&>NsdsK4Ok^W@SP|s!UsVH)al)0U7KuDMBKh zHUi)S5qFaLNVPch>KFP5%^XGpb=~4OCwUwTD0bB&j6BB%QxJrV2*dkp_jC95PzBBMVE(06rA>ygp`UxYAnp;m;lr#ffvjk>$$oCfeT%wXj2CKuW!3S+ zs(i%#!uV*QXS{mX5{2xzeZ76c@RRM3l0l;}a3d`DRPhlFqL~yl)!UaDGg7IKM1&+n zIyUM{I`n8a3qSb6IQ&y@kHz2O4B3^{`v;)(5A01*>?9qKZL4iGF?(fwu)h*W7ZamI zs>i{xf>rsjUv%k3bk=!ik=N_BOvjdVf@TPMtmuYHldD%@DS{7Fo(et$y<=pHQXfVj z$QmQM5&>pF_}acAGi&sRvA|gB3ZL(Axm5Zt-Yp&UKuqKy&qnA5>Rf$EAvT&RtESTPcC}* zwb$ftm{DIZ`=&l+l><8I<#Sk9BK1flqs(aP99q#-R&1g{mX}8fZJA`>PXxUoog@>Z zp=V?WtvpGCvLMVf4vq#^<-`8ZfBciS-nCUYDXS1I2WXF5naPc2z)m$F(dc4jy7{Kt z?G_p1@geHrB#&bQ&=g5mG=AJ3H{TmG!cqdULg0a2;VeCNWpNRX8uAO{_uX?Z-Fe5o z;tS(<{_|eC@9ukPz~4^}u~EfZkam>`%2oW8)%j5Ob8{owxDXx(1s~R5d9oTGc6=lZ zNjvE2F_2C}Q@1T??Po^{I-?HQI+xSM1DcKCLH^71`~7}C;{H$u@l%z5tRR}zY1fF{ z{QZ8*7=Cm>AN@if$yR_78Dq-J2^mO1_VKmbihu(j+kyH!syDA+2L}#EMxf5VH5jm6dN?B zKGY)C6}Qz@kb%I;lVVraSB_cvNQ@-ucde@rIbKM=Yt`|?s(d6AJdK1UJ=+|uy~+W4 zz&{`aZQTKz>1O)DhZ09wl@A321ByPZ4c5nivJxotlOc#_S{64w3qabH)%yqfd5Dj6 z+RUiiw!S{X<6y||T6O%eDj$|y3zq}5!|4!$w(fup2V@g`C~;Kk`G8rb$~GMiMIU;w zNPl41$mw({f>I)=5y3kAW-&J4e(r!>S>G_ie2lT%O|IyyuaEFJ81lPT9S5z-N7Ud6 z49FA%}BoZkOOpJARy|CHee@$As!U^qE(4JJ>3EPQZ7V+tV=mY12@9=!3U~K z1|LRYj6Mauy~gqd0*XG2z-Yc?0qyzwjqrgPsiF^|pC~{*iF|v=ta1UO=~r!zM)^&Z zT#|)E+B0JJ#`)!b9>5Co*z;@5?v2?25auI^?#c*#Mqs?2^ynj*2#7AGyOfHI6-gHF-H7&PNNhrTiI<*i0LP z!pCuIjuUj^J2QH~b>v%r((xi+G`UFm9eez7arsRyAI1QBBz>{;2L9Y`53S#He29+{kH>tTPa-#~0WdJXU)>|oPsa^nrED3JUbu>-tmVkBR( zVMM=zUzS^ZeigeiDwnj_0n>+eL0>d}0noRO`4ILJOD+cZ1r)m)+mFZ!ehu1vm|x~6 ze*cKi2kaUC6!pad@+Hd-q<+zlP;V^#f_@`@7xk=OqsS!|63J&sE?%yW$JKcGjOYXR zP|xvekB{l^)0Gdvy=3zdFD@BvzVH{u)d@GDG47S5F@wagGRA<^%nkPTnM(U|*l| zRbzE~IN~~9$KQC;hOo1YtY@fQ)VG22Nq!}8KTJn22bFyPtaHy&DFsFp$*;OziOBY1 z^Q)}~*Sy?0H?Te;^{d=h%LRJdw0V=rHy|czk@qFQCqA|cKD5A$7H#&k{9Ifg+KsdW z1tMR7^Xbf#wdWFQdN9LAdG$&Ft}Fa{S#Juzs9!=|9zalhCfgMTn}LDh@&Nk#SuR}9 zrjs{{K?lHnykd`|pd-XDFVf{vti=O_Z?Zmq_j2@l)xF+o$^g)lfChbkFXW_5dAH=fzXm+5b1N_3S z&N%x_^5x`+YwCK`&|X*96O-Rj+I^T`U+jFS4<9cTd~ll*^1cMx+sJakQ9@5|xUXji z!C-v-c6S97dlLC2zr*#bu15m;IQ#r_M9`+Tdo4hp>>sg^NWPO!ImuYQ%|rRXpI(C8 zqK$(x0jNh!pPBL@rIQc6_(eCL%ARrEe%^)W5z+-0UqGjxc`6kZ7ty+n>%`#E*3u@9 z>o;wP=qxZuFe$F{QRYLrlF|}dzi~Yk6&2GdXKWDXn@?LWj1=E%L8IaF8#hvMNwFxW z9Cg~s@o_zyL_Mev^-B6$T3UqAhsqnP=Ttu8FF5ye?*bjjkNR3$TSa{*pQi9}%IOLp zs29hRPhBVSx3(zx)-j)GXQ-a_qWu#$oG9w+XjAx=kaTQ5eWR#9TwkbNltVk4x!uV2 z*9&@4K3tEgJ>C1EcFM}s^@QZY_dyr*5h*|AexzJ{VL6|C>c(Mm6XiB2e1z?Q&*k;P zqM|TAkSp>@JAi|fe29E}zqB0mD(&d;3;Psu5_YP{ADDYl1Z zbomX{qi4^!AECb}{G`P0nGevb_@CPA& zz^~S>!*T_`rKLPxDR!s!7i#^2kH~ryy9Yp@@Z*pRk5B6R>Lc=r{sBI8?kAj&>6h)s z%%`aje5~K3_)&Sx=8K(AE$3MI^x_xwQJW8oA_$@^xnVq=;K@%?pY^8#g2oVrT%37; z8Dun!R4@-rGg~4lYx;9u;R3y&5UR&^lO$EW?5@+y)jRirk&#s$Kn@-%6 zFOK>71;Jlme{FF5gp%Oe4Y}d++N5pA?Y4>QvL2bx?sYd_7q#7Z^|<(a!{(w0K2TqN zL19EbZ940M$-$d$xi*{+?W{j}s2-V6->-iAYr*g86LW^qal!_r{ydh;Z*KU_Fh16X z?#txicGhkv2o`ZYIBMGy{Br%n+SwRc5Av;9pUZR=2Y+?_@OBk`3b}rzd|qCD@b|Y| z&wNi2=S~-i`=Cc%uAqSVxbZiFZ}oMVPS}_yj;IgqjvHUhbmR=HN9IF2Ynk?M)+0BEm}UAwEC4v+Yb1>ne#>C_jtA`o1KEEpF1f+F4`pN z$koUt7M*(6)@~Ti_qvmY=+V1>{JI=&uPFG->wX=kPv(Q3QC@8aH!>e*a(~ymFVh+4 z!49sCkc%E2;1}(JU(gXtzee<@mA~HoMD0G79mssJQ>nM(PVhzTpV9n*mQHnjvFt$0 zFYL|j=HrRE;vD)xdFc1ozh(a%(ubby@IQjzoB#6L;Mo^O@~cgt592~Kza~>bVL|Zv zo30=8e7KK%(Z)fUvibB=BKfp&PWTJs>Vyayf3D?$tq+JJppB~Kxn4fyo{fAyr9SRh zV#)P^`yU|ueJa@o^2q$^b2V`8_9*rEavZoKuAv_MX&G$#ljUWKSC5B}IL8vN%m@1K zzxRIX=cC7?eAQUp9*(%)-^YC1`=H1NMAkFZF6w*mz6ZnnO5lE&4zFGO{jPuC{_ij! zsDlHei1yX>N<_97n_q1`xYpat^szo7^{d=h%LRJ7f9w4spLl~`b6)~{{_7wA5`1XE z0hwsi4f%0>XgAUh6om7+qwzZ&YI-;z7Udy730znB?Pa|w{DKY%b$I}P?+Sci)40<) zTpj>BZK3}M?t6gw8EyxXj(Gg40lGjRHciILr`L{_Up1oTlThn7nq2TkH~1C(BL=_u z`60idl8YK@JMinsMUPHdMtjZS(BpfE9=-dxChZ>dL65jLWN%7&K=`YWKah5>z7L?h zpX<4w^`@4KmJVSDY*%;w^WW6d-7T)E>rq2{UDl(O0j|fh16(s|_eSghKz;wdgZnx2 zVP`%hbB0?L12@3TlaDR zh9fecY)A_jFpTx-C!Q3863#~pw1wx8(b`N5LwtZvZ2Z*&t|Q+=_dOxN{@CPUK(EU$@^cKBg)Dce~D3AKWa!G<67=hrI zo#Z1AO8bk)M{IpaJ9v=oKnBrzNQ7T>%4GHrqcEah; z77}SMsd5o^#eO3V{2H_S1p2x7s4wRmz1t1LNV`Tbte&X#vOdK45jwRX#CXB<8yN?2 zU#3_{M?S0aVcg4^2$F$hek60Op^(h~F#Q7otN)o91&Mql)4WiBJTD#k;5IF82U+Mr zdCN|*D{DjfsIM~Mr44#wOt9bJtyC+kLyQ+pzm>;9z^Z&$GI){$w9^&2Vq-lp-Aq6J z9Ei2~P$2oRHlPnz$Pt@SA5528#+H}&Ck67){#ajM@VkN!6LgQ!_#3PHD=}U$`BonX zt;&bZZWnKD4TG8i{Pg*3bj7t96nO#d zHFbHtcAnvUpyc=yBg^1B3(JpOPA|XkvUo17M!b5Se56CSPC$=t+)Fw?Comn4F&%?0 zI^w7m^zw@eAF|A(RSvO*h*2Px|Ul!fgJAP9|z4MGZEIwp1nQ!Xa{#A7cDp?d6lXTD4lX zZQC}NZTn;`yOVjc@ALWo?!V4o*Lhsmn=d?JN-gmG+eOtQ8vGu)!D< zzm7~1yzt3BpuAA%RGG?TIq)SX_fH*_k+fe5GIrQ_Jid1~hf;R_6jQszT)>e_G7%H4Ai7oiSMiJq|RZ=_sjqH8i0A`1Zdb{v~B{9A$ZNsNLw1YU& z4Bk~4GEGu2@KWnMp}j$EtezT&ae%UGGOKN@g^i8fs*+ZATJ;%>2Ue70*2UGUbx}d5wOW>Iz%A$&zf84xlZlp*LNHO#?K#r@jhd$->;eXjafnndxZl)ha5RCkDbbi43P*m<<(IdF()sC{{Rk0O6Z zW*W_Iee|)vV(U>9C+G3Ak4cu$I4A@`Dt}7ILeRq7gtp=IlA9C8nDYYWzc=I(0-&0o z{NiCV0n~+|RPW~UsHWR}!gVAR2`fvB=Cd2X_y=uWHu=rLj#HKx%6-^V6)09%u=UqPI)deUVj;4M*d6*xDk_1fLFP(%oG^1(}hm zpvfP_O^;ur+wBJOqW-44uedZs9upFnoopDcG(3Mf6Hq>GDTj%GGSS+x#68_D2 z*pRS+jrhiAxUK!b=OyJGUDh_gQ%81z&N}_5#efRV&NBX2W&FW1hYZU$aEH=OjJ{lftjWjRxDw}F72bnk+!Ag_GDga{ zXW94j%EQx9ucP;5xk8WXG*L14W~Tul$=PkH?bij$tbJsq|E+=E2#V8pw33!^VF6kX zxrtR0e*MrLHo(qQ#dV0*W6iGshRifNJ?DqL#NXeW-H?1~nrXUgABDT87rAQaIFyBC zCafiXN@h#RqtJS0nbyz7^8~oo^$*}n5#_<+To6u@D0H_w66vs0(y1H(6`oZFnT#`y zIx>hA1jp%|iJ8+oAn=ODdyk@PeJZJ%OV__S1z&jolEzvWt6>P93=MlNr~TRxlgKcD zF%?VHNd%O@WMp67hxK3`t!{V7umJz^B~tVzp1*QoWo>7Tg(_b zQ;Y-G|1ESyc@;sIU;BO^1J50JdJFn}%@Q-?#<~sc+OAHw=cPIF1~H{tVzaX4x_NC9 z=U{`RT#1n;aCXIXGkzOhB974SQ-tr(;ndCkfY5!mB@W#wDGGC&HuN4#Sbn&abz?QYW6ED6w^K`Ec|gXq2YBk@NzJ)(~dCNNyX*K!mNig*CDR73aTcyMCGZ{lEWbK110p-MVRTyc0n8WsZ#S z9ZDZ&=Y3@U0QA=5K^9t}Ipqn~Cq}w_fG6zR4W*d%?Gtpf#UD-*)&mT4yXajo2L zdj*d-D|PmHi^k+07@*DtAJX+XeVEau@16Y*W+VVvRLS2)t@O-U+3;e6S7#LDH7n zN_JCtdUth4=tn9`Q3w^Mu_8%wFEPE`a6h_|;9ToV2B!+iS-Y`P0Fr|a7z&rKO;nWa zl_NxvR%>H3JOoUG%E+K910nWTsHJN@V+pmnn%N+FQ0uwaU`X2r|AIj&*(${fakpS? z^DcgCW;?bN(M;c#o)uAdAY{HcW;X@j^kW_k20itXA;q2=gJyOlX|?}{sQ|+_dM5m9 zsgIi3P$C*7HCISoUA-sXm!BVB<(}e#)2Vp*)zQAnVFc7vkIF^$gUD&P7bD5E9b`ot9(ebqq#M@OUk- zXEF8WpewMNIr91=Sv71UzZn?tsip&T$51^ElZ`a^l9EKZAM>S#KP?JlY&V8qfrZN5o*L-M=W?6ib+sPeI7U@DP?*&t&9u-xb}=jtT+KUBe5`uYzNFGPxRkc zzLvalEH=>S|I@Kif_5!*A+#+Qf+?~Q#7&5odYcR+OSLKDqI`-Exy^>=>-xse!o$0x~S)% z+X#w!PT%Pq^PB>^0yT6E2y${>osb`7Afj5WF=C2|Sh}{IQt| zWKg7*RkRObNq{{;uh^4OOqT529aF4@ImY!N{juBzCIAX(|MB0SUV&JGU} zHCB|_xdirPr^|%AT>~b&52N`;tkotFQMu@-6^n_5UV0q2oxQF(Sqy$@QG&lJ-5aPO?Jn;-Zf8lMCQiOvjgI-5Wvl0Agd$h z71z4x8taBCbmBxzNGE7!Gk-8msh1uHP%Da_6D&gZ&{CP0-&p`GzuZ^}0s8_6qqX*- z&?!)GMtAwLd+9g1S_kKGGOrnDazKOEpegpZgxoKH9j?`2XLNQ`vL*md`8m^f|wqKtyM%To1fB1nc$v32nl@pWbZ0tJue!SdVJ!WFMfqdrb=(Jbu<0J^%Z{uM|4icPO209?@UBZ`CTBfuc6(Mhnn$!>Z z4I_Bdr}DMdpHIoYuK{ie8?--Bkh9^H;)SC5d*!E3=h)t-p4o4>m@mOtaX=-JrhM`) zCZ#&p+H1^Y>a7{|h0E>4`^)}Gu6fjV2>$T;CHY0|@Dl63bgi9~s93iXI+8}-9Td+>cS@K{J^)D4o{WpJ^l|d0l%bI>J1Upc<+vT%oFOo1>Vt- zer5F*2%lyscjw{BwAg$RdYBfg7#Wc=Hy^`cFg<2Id^rXpFnw1&7N{*3!mE z!ramDs7UttyBvt|GD;zs->fvVAwg@6RM0R3zBQwIv$-WMu}-%DBK-4R3T>moPNFXd zu^RT7?VDU^zuf55uMBV=jGRPt#|ar+G6-H}EWSaL1KD!*%F^5#-y9zI5COvg@mZxg z6?)x=Ph;3RmKASif4#+{U{sT-g&vs+T){w6b#(t2;aUZqa2^f z1UBEONqZF@oS@8uY=?EU+rxtSyI{gh1HYc^xLz3)NCH%!Qj8=c*BSEg!K_l5UT`TT zkt$IXj>JY*@c|AgR{7?UIR7lwuT;>Z-+Uh4YhTx|%k=mf4qK=r?LK?pss0%X02td9F zypLb2s;C$dM8$BZg%tH?fJgCLqViW1Pyy-5)B*jSrJ5`___Sx3=HeC%1_7+mxQCo} z`D0K}XG~cx%r6zUFkp@E8g-7N;Qld>Ehzxi4CQhr&b^=gkV2@;^9zDnfh13*Es)ii zcvL{rek##DfP4DtKSn_4Pam+*RDkFP9xm=+;D38BG$@cq@k>as zHVwR43j=4S@nO9a9J_V7;Uils80C!YF%&mbvn~*0Ks854)#13z@usT%A?kbBZubMi zMVRt%K+@iTn#N2X65uylXm{yXX5VOJO89UX-xpyqI(kW%#0;Z|k^{9yo%c4sJCDw?w??Hbi@`*FJ_^#oivQ8G~&J~56w6#0H zD5mQv2KE6hB*G%|G89~MWA=S{(eoW*qoS=~FPD=2Vd7G_uZj}^3>cZuamarEGOF7m z#l9X$3^&|!rlZJj?H;lucS{PB)&a~&ZDNS|ps^=3WZF(iBh^hvMYSIdvfp_2^{i2E`uM;^%j%Z=B0k7jJslmaM= zHY>70BH+$W#h_@i+n;CxOCvlD)M@Mm^$vIhiMQ55%+`w=TOU6Qd;Ade_X{g0jpi1G zC4uWJ8}|PgfjHlwb>3u+dncf{jmV%_x!Pp#XrcbA%eTX7u2^2~znnp8DT%t$9l6Q+ zzp>c;AsZ1T1SFsh|1?P8LO~41jU@z7X^W5C#d-#!&RA!2?=Z8@+pAhs9JWVK5lp?Zw2qt$~Jz+i(I@EHC3%I)L;6F|L+1aRRJ$)|;ou|No@8p9(83OrRzhPp+=`$e za23sao>)j}ZSTwfBJ88-TDV55&16RI;Gi$6$9@QuF^t592!+EC9FR!aG^$cCInyob z$Ou7my=9*R6IFA_794$uX~o`0T`RkR8CXe@gDz;UhlBP3Er8jtd}QkMwM;#^{VboN z+80QJd?-cZ)9!pWV$Rn6-wB{e;_<-Z{&vKi#eDt+=DS)R?mjh8p~4d#fJcwSlw5)b zv;GS?geV*=t!){ZZ%3b{;Ui(^;fv7_5|WhJ?KXrdW!ax;^kMg9WLs?hGq_W<*B^W? z(km6<#t4pWk8MW6Ac;izuZr;5yjdA2XKnwU(2o5x>Tfw=SzTQ=2y|Q~^RTdhJbZuN zKzzP1&#t7VCa}Q0V;Z@Eg}JUbyFQTpEx*>Rvc4}XU2wp7+n z>cWb6JuRFH^eH z0bT<+Y$beASZ201vx!xXD_f%G>yrxYE*B+FPr*IB1*QOshPXOdh?QGk2*dUD>=G9N z(7K5qMer9U`xuBUy(h%}k+uq!u1YNNCy`w$>fyc9my13GRz!dK zYJ|v(JImS`8-qI}ni3&!5`UjditGkV>uQ$~(mwTUatTlbv>r{&m%i~|iHCtpZ!<&k zqm}H~#-`*He|>beo3nsG`4Q*zYzpVB!xZ1k0cYsL2Jvi1izCJJMqi=F)6s38z9LiC zVJNky?ih38MZkU2Y^edU>8Np5S&gkgqZNkyLT?m6_<6|^h27N_@AfQXwA-s!AZj7K z$H2WOxnPa`-`{PB!<>Zs#|KH?mUmK)(4Ia>~yL)Ie}oR%k0+q5ZF1F%bKdw)n;e6*t# zJw2ff=22C(K~9BsHrJEJN6$HU1pi<4K5sSlt#a;;*tUd-Rn$m-rJx<5qxpaU$^aa3 zZY`$MoOprMpZeVXMrvO`YhN@4dO<;5-DJ^bxgU$~+s9=?T-2$wKhF7OD%Yh7BPjPQ zx##!FRno%hB26@Pbc!QqjSiHNiDw(BrT7A6 zx~LiEApn`w)a2RCRjZ7~xl%p>uhHE6pPl)34njL5S_9=8+h`SaIg^d6gqP8DT()0M z4ZkCE_2qpQ9$Km3Jf1I0IAT;Z*`wI5YL{HTXtQ9{FO8vxfip8xPv@!k-SFwwbX-d& zFu-=<<@@PjCB;&^DxQh>H05(g&lSX*lbI>}Cu<>nr9m3cjn7}Ag_i`9nAGTM$L9_i z6?<7#`IBG=6$nte$=Lio`+R}P=w-&Wu)q}x`F2U#N7XYRp8ujQZqwl$i}!On?5_;r z=y!@LQI2~-W6G$YwMul=o> z&B-!{9w#4O`&J8ODUb8a>gF<_J=2admWrZZ)a9j^f>^*3zx+(J?e*U+5fq1tQTXX3 z{BQszZ!K)WC7&^gQAz#|UQZs3`)wLK=563Mns*W;Q&^HsKO}SZzamT{w^%^bhnDFsvSOHxG+tc8LQ~zw2+vcPLAmN zInfE!83^CLC4V_5b9vpJQ=0xL@)MQU#j!~2*#iC(+QPgREhVKNud_^{&x=z?DH7jn zx6oZ7$xl|(lRNXLF@aSHe#%OMviz70M+Xc#LG9ib>#A0zRU`7@V@z8ymz+x*v3L1@n5wGG|3Y( zC+!N-VTW~U+k%zZs0)hTaKK3VuKR-)iV7RPo+=4^a_4<`*j43mW++kW*U|c*5AM^W zpKd(cR7BEq^|J?fC0@fT=s9BIuDg|>ZJLu-d)ah|+!FJ0L(N+d?$;0ckaA1B`4_C% zugZ}Gi+5(}-UMpr3LNuGK`dSIEt?>Nk=^=$C=%SdKX3k`=|a`*K-FWj;cV8Y)troB zn5WlIT(_SeX)ezU;r+zZ%_$A`dufLsS&o{eZ>H9S2C7*ZOlmL0thc~OOFBGIO zRBPAxw2}uPl`03~?pylgIWm+0>5{^hc--hVcfu@&%94ul-(-pwrprjwhoJKI@Mkr{ zD-)xyk!HQ*Lju3Q4hi{6q%5rbC`vNEneiwZZzsrgSa4b|?fM%m89APpbH_EE^L_}r zV6r(AkqE)@R$)^PS>3e$38z z>14>!Oh(AwPq#+2A-ieH3OxO`>r_(@+=!>bL?4tUXQ7Ql{7596@y`Z}{~wR&1QHu0 zE|y^khT-7+fPb5@{q9V~v_BY=-F8dEaZ5N#mZ*$--PMRXotq`)LWE4KwJz}Owz`w3 zM6LYWO0x}v*PC0J5s)66PW|IWhl-qR3duIEyi9n|BwsbhM5>Z7z!NCP)a5$gIy(b< zD9p3c?gC59r!DOESoRwq+c8VC5r^2~mjpWa`Kg@ZrhU^#8bg3L4R3q`kG9f3hmL^# zQVlfTFg;VCQc9K=8((>=>aM&;hS)x6SdyTI_jEPPs?GiEgvFbNZB`~e9HW?*IPb~p zEQ*}*Edq$caI^j-lkWDUqpJ6>Zsr=w{ofmbSK4q~X=6)6#Bdcu4n$n>u>Igiq>9*EI7;ZtlqIH#gLoYYk=UKC7MOt>xtyNJsv*MEC zdJ7HK+l%VyaSgxU~ZL*)m%~odcU0y#EOTwiSN>BDie`A8=i!L$39L*^|UaF}Jfa5{fhvp(fbLISHWOK)rfC75O zn9VniTY*OH7k^ytoa3OiT3#m<`q!2Me-j0tl&Y>eir1&+SJ%w5Wfidiq;3W(JW9N$ zSA6|(>|LVAZ^*65a{a+w`-vJ_X@G9&~2Oi3? z%~-Ws|KiTXBZxH`u2GAIVa-W~$4-6vwBR^n445Ni%G&E#_<;@C>j&4Ht^HtL66bR% zoGE+Nv)I?Tyq>tfK1w7h731rC?F#zNdk+T| z0h9UJ0=OjfCupN|s0s0qL?Aj7X5FZ$PP6)4Y_F_DD^J)_EID3z{lP@>{f4(9gIsS3 zj{!6S)Y1Zh#L-d@FI%J)T(N+9%7c5(gSf<|Be4wHHNW5{GMc0Jr}Pz}!dao0cP}3a zmb$x>_s6xU&nYI|qg~z}Gmff#&d8`d<$9d+zI>YnyiI4Fw;16+v#t>`KSIo@Fv~OS z>$E`wzi9Abb4BG&!G_ZsK*^?{-Cxrh8frkN3F)}1>|!}W>K&?UQd!f#I04Y|o9eWx zZe3*{Z-Z6t=-hAwia@X`o|w+9g@+X zMQIZxBb8qaC?uJQB}U7zjTsJHRV2DbMU}|^;+1!?=FKOD^9qhWa&RP~f+63EjHzb! z%yu7@h#}H=+Es=@=AU=eMv=C)9Y^eZP!GR}rmIIZ;Hv6q&;^!nG1bmfcD8kll6NQ% zQ05ISpD`z-DE+iTF)mz~nV*yJ&L>JrS}K9X_Gkr8gCyK!B?Physj6a>|CZsvwo9Yb z^F54Csy|4}D*oZk)t`KvkFZyxGb@*c??xqFt1kE3s>TE9e5EYO_m)B};!0Qz@Unx7 z;EAer*dWeUOST;LyYIk*1>d;ehv2(*Ljb13PqzvuVR-ySJa!WtM9H@+7KyG~zMF2% zZ|fHwbP8RNIi2quxgUw44z$r4EKYPGlxOSocnDFBheGdp{rBs`2A|GWW}>4A%@(;f zYj*a~HFKJ5R)91d%Ko5TWSoXog zWkxT#n_?RZ*_?j(8nI$6`kTnDRKJ6B6Os+FA#!WO57_rAgRj9)tO}b;nu=j~WFE(| zG=z{DvU_d-%ZBV2WtRKjvdYg!1a*IPFXKkklg$6wULGoph_k%0BxiNme%f)dii$1tdE;w_XxH56&cL-QJE6xgBk z^BE!)L%iNM1)4O!8+N-NjwIY|&Y@ZPwHW==-zB5!LGo6tH>CQ>YP-ET2E%85NlDZP zc(@(GP_<8$YEtB%`so3 zLyc)|#AYw4jayXo4`^V3&}jX0(tFq$Jg;9-*yemfL%#Y2ukj1AY*%lRFp_Z7U z@*Si@21O);57_MrC`baMZulIJzs)WO{t{kiS2FkxA05Q&awd+@ntDhWsH{W_FA|ii zLv`FB8knLY(lt^qPv>+#n}#JpK?c~%Nkk4R53{eQljy=jU(8R)sh&O}KWwl<=v|~a z&JC{%GEB?Rp;FHf{fb%sJx%YYUd99+2%apc$rKA@+Iq-rJfHUy*9rGgOM(Xr+fIL! zjiMm_s1Xx9CH2;49DeyPnt4>Q{f;)D-#laSnUx&oi52892PuG;+d)|>AV*voMPvFMG?<+ZN+#8` zZ-{MjW~ApiHTAK#41Lw0zGfb;EkcTgB)pz3&vTr_k{q|a|1$Po8kY6N?vGP93}rED?OPF?0~ z)#ydq?b}l)kRTC(Zo}OozvBg-9Iz3$$g0Y7pY=^;)iLfMnxkV?5{BvW~8fIP!B zs=aJkIgJh*amVYoJ>M_oqOZohw4-0ji}EwoL`8s{rqm^2Iy-vBu|``Zq>5SteN)&k zzTFiJn8|9g6v2+zb*+SB94U4ThlM2u9|MwO?ONjjNZmVv6&k4B&gPq(VQu$^qGf5c z`6NmhqFs3NEc&QE(hN4J5GC#qhA{@*x=$clJ03Px@lNN`+^Y2?Xld}z(c!+04Uf&oC?%T{mn%8 zcenR1BFSo_RfcGek6_?X%zHFCvAMTpiId{8hta{Se7Ocj5hlfexiXESPE%yzFhFP^ zL{Bt~j?rps*zIhUdhWuzIlhZq1m4;rEO4Bf$3H*f2}=sxtMphO;J>airL!IJqIAb z__yZKSu>K-`hbCPBx&xTzf6q#ZaBrGzbHWaqmd5R?T2a!Q zihZegr3#{oc3U+g8GZ{d$tD(GZ~vw=MY5cqeVLpskyt5xiOh@lboU&#qnEB}r;hB` zuASHn-phzHD4@$SorcFDhALbpk1?0hs)*S_<7AX^^vbqIMbpj0%g zpjO}pv~RPdpN(KvyOjfS)G!Fd%TE5;wRplGpz9ki=zPB)4w|(uO4=ZlSBzP^NrvMm zc&%N(nDX!gjh(UE*%Q)@YwTh5h*9>+WHf!7Ybc{XY}))-IL0)IiPnI~@HKUN&9V z>Nz(h#pLnW7iy1O{u8C*igDn`Vz1Tgc<+r%Oj9RQ->NLN%7CxaCUDK!6?)ea^?5zP zxH+A@Vz;!-*W?a!6Q&%S_a!p5Y?z*#`ZoiP5ON6Qq+pzoj1d$Je!8i`k65zgwd<1+ z3+Xu7qh@1^%l5F&kIj={H?ibfX`Yf~n{-Widz(^XcZ~f>Bh#8`GM$T2dh@$p_qqEW zo3+>jTRxT4m7xK(2ur z=^G!Q@mnfpa@$L({trH~gn2HIboLOxdkGW+pNF&N<71NtWS;@2G#djJk?(I0(VJOl z62u21jt_ccV{>1E>1jU0s*Cq*5K=Ov5uCOrriTyvu-t-pUi~r$iOVbro;N4 zSw9A;?ZuasBoh}UZ}ZV}r(w>)5QXTcA?NvA(RDWquHGw?r>FJ{MzUHLorT z#iF%v41^zgT#J;te@n+yafN6u-bq$vsypl>3671u!kufubv@Rma=DDFv!m&WQ!#c{ zdhW+a7iW0jR}tiSIjJ9xN}IJ5%U3_dXuP1Ud#O^vmXf$+G87-k_Z*H0b47t9p96ur zFG8FSAsa8AN%YFhGCcmhY*R!#Z|;T2HWS6D2Vb6}ui{Myxoaa>e7VM$)e}lt$YSn; ze*7YSUeJ(mTs9V(o!R9Ekp>K>ii-tgC41RwGLUAJHo!t)cB>x+_cnEG)aG^ub&f6# zA|3X!XntqV6C*Fj2ren$>vse-T}leSX0@; zs`a+IBFyRVKaNPLaWTG0)TtH*MZT0M!X_|Pn9;Iwmo?twS?vlfx9r9smzy3qKInNE zft&$V8m7Li;Pt~TKbpHX`&R+W*-5^JZ<(KcRXkEZMUs1vv#F@>Y3Hx!dF9)(LA|Eu zeigJX8ex?i@GNV3H2X?^O6`92m=!%7W?180AEW1LP>nn+(6}mvA>`@1##JfyYhhk> zZcg#+^U+;IuP*uFSxJiC+Mr{DZ+$Lsl52B~HZlH8j?jN+H^w`kI%kaz!newEz5&U$ODtbeQOx9t4VxWZuMUDV zXqiBrs);_Uljqi+?28BGOy!SCPck!@WUgE(b1M0Q#u?CF_xCD_X&%qq)NEHzLV=su zt;MnOY2a}p6^q&uvU?}^vqJQl6`0?hsew(&ny1?>! zqb8x4;-?q}>9GV4XqHR#yN6z`^MLP$U~;zd~y7JZ<7UT%lCt! z_*8T#afVQIi2v4+jp-bHI~G63Gf<`Qr!l^-6S1DkW?Q5GhTESK;Au~_gZ{!&{B}#x1Td zBW}!CFpQZo4Hk=4soV#nj-Fe!S(m4H5rczd6+hc?o}-D4PRq((zK2GPfn*wlZh(Mi zc`heslT2mtcY-q=ZYA#mnSGaPOh* z7`pnawp8B@3MBt|+WjEm;4yl0?8(ZCb;h*@ZGC;ch?h-&93Pj%d31Ep+Hq8TJ}y)xrFWxIvf5;&Gp~DfyC}BNY%6u%8gc^ag<~qcc>5BjDYGc-uAHn2)aZ1y#&Cs`DiZCFpImQ>nGpyT@)dY z<-tnh-O#-1AChBxvxNvp_mg2Ak{SE@YM<$4ruFBVWLf#fC8oBTN&(8CQ+&N8{@^09 z?(Xei>-^2;#EFUf_SGPCFu3dBX4Zg6&)W^@E{VC^YfU`T!MKC$WmZ-@c}hP7vgT^! z!a_~s5Oe3X2r(QtI*k}?lGW8$c%gnO1>@3#>hC~J?VC^G&h^n zDo39^lcn`|Y3|mi<7~A`HA4(7E@xODi+8^m|JiQ4Y*lD%jOx(xyxfv|x~;bBW?Ogr zqv8F0-geTYEFl4Rq0>ucd+SW6DOQ7Y951_~G#p(9mCGy%g=)(S5krP7t~HHcZ&Wz8J+X!N5dawpSL3>Ra5Xph#ElMLC1^sL9f=kYT#2aQ5p{+e z4$VF^4{W)-se8Wkl)vE7@wxeG;c|~_(#6~iKCE_iD!0%fO>K}} z5C4^)pjJ-@CpqO$QVNBZUMd~OVH|OXVIyB7HV{_)a^IpT58ZuW@)nVR!T|qa!4PKI zIV&%}JbG3lbc7Wvz##_(Zt|*h%OBWmP&2jontR;ZYg?^t(+hQiXCsC>_<8R_gt)J< z*$VbeoL!*ZTuHnM$-!jS|8J6pqn-^L{enTAc9?yJA_eq|kag(YAnRnfKCN5ShUzf}};OTB0LFoGR( zo2z?!5u+IS`Sm*I+0{@3E_}NCy)y?irgJ_M+aqEMJhvTTl$&=Q>Na0M@t)r=hu9I8 z%v*2d62TwY==hP47*y)I>Ea7a)zsV1HF{|DvISOS@olkw}2M|dUY@k{|ya|DxEfYN`+DV1W!JpkzU(nm*R8UYRcSBisqoZ%yUy_wy*iQ!3UW>OJ36@C zE|Tr*v0|5akxrXXJx`j^uiH<_zwYuW#9{#?$!6kM6hcBE9(AX>(r_g_4M(aCBQ)L6 zevd<+E52!i9}JjCrUbVuS7m+iBEV~xKl#b%93NvXFc8izEI7`4xf|MF3e<@eLul+k z#Tu!}hJ0y&0m4?6*;e5DIj^AC0_xeb|429&Kbo!h)ELME2ER%|% z0*%QRzQM63G1*~!95N1E%W~F6{6w5CvZ%YBY~5K2z-?%n4p-y2S?bR?>hUI;&9hSK zZ54;sP3N9&xnFrxr7TCrL|>o(%$F!}7es5RhlKBJ+TJ0=3 zfIz%@G3GGQxP+N7&Rb+#gt#BL-SPdA_28wj)KWDUhtx$sloBcU;|^Ho=M-#R)~W!$z(iR1kiO)rlzKjpeo47 z>)Q=B4mEG$JJz;Q5*-YIhxAjqXgL$n9iuFf`YfpZJo0&mk}#V65E)w%;@NCD6>fw+ z5=jwZrL3)cMh>J*ZR|gQzji%!pWest*A4S*Ec{TA&Xt~HGXqQEM!$wv2|rQF^3EB> zoGtusTr$JH4fAw~6hjBczZ$ahwl~Liq_XBhG)L~{`f}CDe|HNz%gD&F@W|LmcPl-@ z`#I7QjZ#ygxMXJS(cvhIYZLQU-z>H65e_;~(S3y?s)|whIZr#E%xbRMRZ4JHnyZ6tsibmo{Xc<&DyTKSpjU($A1b-w32J(4QM=rJwxnk?o%sN(oDB>AaJXL5Y?@;A;hHS( z5-x8o8X9=VYUD*$_vd(6>$o3Ll6BA%?1EH?f&;rj3Ds{g-rYZLo>K&97+o_?6TN90 zoE)NxDXD?rFtD0FS+zHCPpveOS|2><#iB72qch+Y0;c@}rj@>&IhYqD?*_caYiuXx z`N5pcH2dhYV7!qYQ*yTw%0t@<@M@Ko&_h9G-^g}$c5*QpiN+0E@ zTHs|V&X%m-nm=CNfugPaW1hGHe!0>kCt}Yhk2Jwh2w*GelK18}s*3o81%5j>xZpZ> zexppA&8Dnjw+6qultgtlrZ?E@p{B~G%00=%2^#DbzZ`9LcCz(Z86dYxX^2EPLn zF!bS2sNOzpYVgTF+6`Pez&r`;)&8USF3_{u5E20@ow1|J(fgHoFIWUEg7jo~qH$&N z!{-VczV&dz@qdRPUg9ynd490RJM$ebt-Wl@`j4FU$v-LllTci+kuOLva13^Eki?mzgY!|CDiLmUG{lG!AJjn+_T$pvUt5@%Nc%|@Hpt0_uH#-$>IcybyiOJR zgH0>cGR73n1`hCX`e`Vc8t}{(_1ys|*tGQPT?&#CmXJD3BrA`YUvhEl^SvZThCj+7F5(903Q8V7Ywd4MY8ln0_4TE z&-iLRhHk;NOn)FIB%o7A?_waXuNr`=;22^HGknHEX8H%NAMSIR4LS`8T#{->aeLD3YhLWa{*zi5RCmni*l21C*88^G)74rSIb zp~nMXL0vV@RJtqro9J+e;4j-WHJ~`b!+z$Ij*Yuu524hJ-<7WN_u+cG9=r?{T-jD} zQdX7~7{Kf-nE_`j?0@&wYBdujRodo%&`ky->c}F@0?EKZ-QbtR1r^h438VwuX$)Ql z;+ zeMic{mU!S|01k=BrSYDymwaKrX*JVqJ{oWl_MA1vpU{RuC^<^*6}3xn2a9n z@t?Hqb}lhyh^97t1r%$Rer3XKKnso^pcr;uqGW0|5LV*Xvl`>MR!?lic&CeTc0$McSu;B6XoqU;B5j`#B>FAxRDn4zjG!*rdA6 zACIuzDbk$m8e!ikVN2}6B#D@YYsKJtXyX6EdOWvM<5IN9Q`hb|O@Y=6 zF4SZ^MCjMpBjBLOt3e8k*RSC9%`!c2FpvN!mREdQU*Eidc{UgqczlY?<(J3^mLcd$ z!`G7qr}+AXAnAm|%h&r5OCOb5VDVqc=)G4JFxww{O~}8>R6p(t^9Ngy$AiJ~ay3Ax zj{ap#pId=wA8G7!N#nXf?a^k;Fwd`VXlX*egVNgBY{hG@U5&F=z0)3Jq(epAK?_fIB zQi9NI{^J*6slYlz`~+c8GUNPHReR~5&921P6^rOEj7qEZ)C;%AgQyzKVc1&Rqdu1+ zT^cM_1kdhd0K%PGJ%7L^azsCoZ3-DfH7DKfT4Zb;il^mDO&F9)rF|}m`rm-=K1CJR zEw%Jlc#5Bu`v0OsPN&u3MHHWe;GowGF{<0YBHdu{07~^VU%K8UyNeirPz*Qy?5{^* ztz|=ezq(=A{|~yK)645goKWdH(6GJe{GKti0EK6%?3}N^aHGrM`)(oud@}#zrdV|T z&}mP;7JCxN@$8E^L*I1C*|jDzL1K_S>9T5Ks0AOfJDlSxPw_Cg7#xLu7@PC;gZn?| zcfR|iN-iqStifQ7TffO%H4*SFiZF197*Q~m81m8O))!G7J%jWAvGkqsZ2#ZeR25ab zsF^B7YqoZf*lJUI7j3OpjG%}Zt%^0;u>@8*p?tJgx|A{Ag`DC2; zIOn>qbDgiQPZ_g+rm`g;w5ooDGzNVLrPAMfR(J@1x~tfw0>RU3Q6?49_jRVbLdu}> z%hRWW5_nlv8RysAD*LyGb_yR?$2aE#cZt_> zO?o#JJK{W89zRcRmi>GG!`}qN zVl%!~={t@1=c$vOjj-kK&uK{R8|}yH01*sXS|C=;FgtrC+0)WL-BHxg zJ8RC<)3YUpe8MUlpDS0}T;EfyQ}tKOMH}zt*kay3Z(C#7KuZuX}@M8au^=*H@DQh)Jgok7GiS9gQRW$s zAyWZD7s5?zeG#xP*I(RZ4;y~!8aWgZX|qtXB=8{BhfZLRI)W!n7I9KBD`Wp|MadSt zq}_Vyhma80f4{~@>dQIrHKhqtuHt)FA^RY=3Bw^#aO;)e#MyT5c`W?$+wuI>B35NvAfFSpp-h0EogKc-*%U&=X?6X|?acRIW^C=a*{O_pWu45zxrx6oNGS5az0z^MWXY=a>Y1Z>se(m|X=6E>L z`M-DD^t5;lmE&}P`SMZrTMb*uI^s*#4|~FVNr(km$Bnb}uZyZn6e`QPRad&(;@cl? z{M9$^G#}@@_^;o7EXc8>0^|Eco% zVSn1}>B0Le*7t%dgMzM#mYQdP&z}oE@r#v`j$F;HuTS_M{@n-N#J-z$P)@V6!Gmx_@3ydCz0X+ z)rJZ$+!M2-YaIiNnU)PMylDV2Yy44{YATztlF#ImpJu_CxLmRX<0@*U5zLpSj#=1} z(9L63bD*vK{(VrDy%Yn#j><-ND;4t?zAO379r_6Rk)sv#`eb7#iRiv2MroCZu)PCn2s1O$AavMYGVx}!NAy!Z? zOe8a8!$JB25X~_b!opwKV~yX<4<4mc>G+RP^F&+)`z`Ak)yq%-`rCdC>{Gaby2v%n zLd65N8(;J5wg*6;wqEr{HPSziibh|34Bd(fH9F*W`xYBoKZ;)s8*V|}VausZ+3Q3< z=TWN<1z-6*#R~tLV-tTlq}sSt4lz@WV0JU!5igIASF+RZk^X5_G!U{_^rmd}`}gmf zv-q@lVq(Go%0Hwksq6KYM{L|cQb6~VLhGbEvlF&{C~5Xv{{74yurucX zyV%YoYq(w)_cO#p6-VtnMI|M8Uz(RMb^Bbmwzi<_Qubpkl`Zmk3rRheu+GOrs;hx$ zav)W@mSfW%D@V2>-g5+cme&SV-+-xxRaYInde(}?ikBGpb8|&4xi&V=p_y#|vBKY= zk!3P!dHMOHT^Z)*%>p0n`Gd+jVldL7JYQE-DKLa>`07ypN>@e!`DiKU+gw)d(qp5HBnC$OBmW?y1;#6Fly6LuM#avN8~{FWZc&NdKj| z$Ug4}yb#7Fibr&XF5EcDD{-a^S1^7O2g1f()wQ+Xzw3{XYwARX>2czZC(^2Wu-lpW zT6B&5MZ=}}r%nRDqC=I%0!t(-$0$iZw4GPq!tFkQIV1*(E2OC12~XU*GQNFvHR(U1 z;C4qCq!Pv4hwlD6GC;CUw-s?O!MIPsDl&?&iSOc(6n;m&PDAK+WZtAae#nEGkbKTq zndG%MDTepwAca@Jmbi{V`jxhTKw_u9v>;K;_-25`dA3BGhl|x$!?!y;2>t0%OV~$- z9%N|sQY4j#Ku4$Qe^=C_AgX|?N=F@vw;G`)cn4##y5EuUtfKpm{yS8+hQCpnRKP86 z!cf7)&Qx&;!xFpb9S1_l!;;0znf85u)HCfsUsw`T_1{oE0nLmKG;2cCix-b8?*j0O zvF~I9`l49Uyjwii>h`Vwdq19%B4b%~Z3{7#ZjVLuXYv3dJ;e;%-;m?oo7U$vPOr~6 z4WiRk(r4cudvXP-h9X*PhTQUHO6J<($>@HIr8CzEs+#tE20qxUrtrleP2lKP){P}j z?p69r!)kmg0-03~N61}OISS}VetYPbkyV{SzbS0e7s)Ij>QYk~2w#U)5pSb!^$hzs zR7tDv&^eNiFQe&CMpzc{&N3z1tXZv#ZF`L`0gbX%PYg|ge@SbOId~q$Sz~Or-6%DX z|Nbr6o%|ccVV`!+a z6X1VC4%D;ip3#Ui(M-fFu6y=~dK*;`=hV(L`u@pby*M3*q}|Fv*$jU07UV zA~K3tAQ<)s&c>U@6M?VmeuXj(W=GU3u{f7t%q3sWeV}Antak6{H`r-2wMe7totQEj zr2@#((vyz|EM6oC=nyY){*GXTaUrpXQ^lV51K7sQNvPOh#;Nrmi~K{+40KK8-r-BY8hf3Rijo3$S-&cT z<>8N$r`Jw4~F6S__AcVstWO)SmLF7nNCz`&DK%qpB+t z+et43VPQA966vEjT|9?i&N$P6C4as-o=8ip@AD*>`2HrUDezhs9ZwG)!5>!mJI$}% zC;mHp<}WO(y+gfppz>kc66Xx4><%6h$UbA6Md6#2iWHHQ-(j@qh5R&M?Dx2Xpvku_Ut_#NIaRx{Vmgk4^SR`je4Y>oV;T8RT|bp(bZ;By?tcU ziJ2Pi@5gNK43exN7X&VvS4v^6IOQJ3HDtrLrJe5(1F#Y-FQ5B$=A3OwsRQVIYtV3Z zGt$tU%{ZHAp`;scX@i}lb&_e4Sb`HT8sFjvZvFTnPsgp3CGtL_6GH~7aHD;(zq7_^ z)+P-mO~k0}w6(YKG`GRZVJ9c{g_U+Nhf#|7gJKZwNEN{}h>d(yTuV|RhDM0BAuv<` zf!|Wws;aQu%Q<#itBtcqrM01|0T$Ho`ZkQiWfYu{oQXg2)8+;yP!AL!+KlM(rs2b7 zp5c^EJx|%uOl*>iInL)5Cn%Rr)m9&HW+x0v2g{OOfl1nEsOPhzhYHiYTG=?1j*;gD zcp%=*f|vy6yLOv#Ifu=*gM~3{NcF1w5nyE4MY^5po}*z?I^!b_`^TSb-=(3+>HWO+ zXzY-yuoKrqo3pbp0zk&e-2i`9{vn=-)Iq|bd2CdJaqWsJZHkVzLNvwzAhuezo=3DWbl95pzfhU3hI04l0xPRx<%!U^rg@84&! zeM&3j-J=owSBC=pC0zySN>q5rmV8Ycv`aI zMl?_K6iiZc;PA{EEy4j7yah}c#=o>|g*8g&b_(7kA<*lx!xXv=s=OB?PSTP-LKbkz z->RapIJT>LTV<=_#n-6VA%`}+8Puti4sKHQ=Rt!pSB(l0kZj>>DgLtwS)aC@cn|iF zqUHMQ!B&%bR@JC9b<5!qLv|p&bVZm~rGH3?M*Ov5=V4HF&RP!fVJF|~&d_8UUVzz0 zLPm-&9{7wqhH9Fhu`l&(BQo{Rc0Pm5MJ z0?&+XVaSriKHhx+a_9+Wj+XgMRaW+N@x5Xim4DT2s+mbv{Q+1WsZr|adQcB5C*fJ0x@5jt(A#ls9dPx@h!!! z^+>f*_7@!_3xN-w0+!jq34Qw9sI(>zhZ`JL)MHX}l3<=3F*r@ft?9aeTvAQzi{+^i z3JH1uw)@SL2AGRr5^4FZw}^Bi5S1erZ4DC8L7$jraCKQG-`s&6-*-@WP!`C__qzPX zjzI|@M)HS4fv*F!dsz+}sf>8O#ax?jj;!mj8Q*_0&HhM#!Juvz9HEjgKE@nscPR= zQ(VSWRCkqkUm|fyW9|2wn=Z4G62k?RPWiN1BbiQYu}$8Yoau?A4*q9|@W_=9XB6P+ zF@&YD++9*UD^04(itqVKOkp1u5=_Mop$U9TNpT-0%Q z2;Mb)PdEDgU{WtzMOIcIJMQ2!^jJ#*MMMRX!&^wR0+w}TPVc5m-D(a|xpd-)@e{{| zj%8b-NHtLO##ZtoLrIUsHog)|Ax*&2 z(-6ST0A#LgO|6z)O@abalgc_t7&K`2-Ey~12u_C+qQ0S5(A@<1y^60%xiwR$>0p{^ zqAz#{V!?JVA6DfR6pTgNDDrm3;Jc}OpvM9dC?@-~&d~96_$7W&yp}|@a*-Y>#1V*; zaL6Lf&&#VqI1>bY~IKhQ+Yl%r{tDQ%bPB^@Fux zjxR2R33OflSk{J4uL;g9*XV%5$v{T%<`^gEJ7`Yk7V|8wWm8U3wz_&N0T{RK zf7P6_N2_$T7h}E9%@K|TySs8yU43PM0Ne}nuqDK!7s19{RjlQvHDBKkW+>OZAIzDq zu}6LRMz-zvDrB*Kf^P`sA{`@=b@&irW3@~jXd7# zw4mA!ITk4~_lKh9{T?&3h|`0BB98$o^UVSlh;1ot)Yk1e(QN_8=TJNl6Doy3fNsL> zW5^q6OG-*N&)aWh%Wq&}YinzxB@?9%V_($DqUGK0Q0o|(;1x=aYbEglD@8$#7s9Sc zZMLnBHX_&)$13_w$mfvzMyc^Y&uyiv^F8lD(P}qT8GOHH?EnX<)dw za1hXYOVcl4W`_|l8b<=_YJ?eZm&@sZuv`cDq0xPXMa|7Kj?a;8+$Pak!q@xW?YUsw z5!J4pj)9sQSs~yhlvFEIJpCROyQbpT2iZOz8>9LF1*m4Uzc__A~fPN}!P5-cte`DNJJC^Pf%?Km7&`|a^TSCJD@d^uXbqMCTM>3gpn z7QGK7D`Ys0W{6&C=-81Hu6{M8;rq`x#ylf}a9y#sJFhR+wi_d=+`jgV`M6H{Ul}Jk zVK4Djs@10>Vth~V>=u?WV?+BZ((MiDRqpR777c*^2~8xsY>LVQmd=}>REbBq(k780 zi!%;BecDg;57x-$hTN}VBoky#!{QeL zx?V-$>xiZ$MPvp~?qQ!_##@`L)|I(Jp>|wMNlD4S&>W)td-n}e#XnvY1(#N|eD5C^ zkYeLEG`4bkD&X()44hzobL0-s)dr@`o~+FXVch`i$Cj|=Ug&hpz~-FC@Y>ZsUO1LM z5tZY?aFoHr>+HK^LAVuhK=ouoQukFS$$?aO5WQm>Vq|IQ_nP4ShYt(VORcjmx7}64 zynAN5O~Q_C__OAcB>s)rc!g_~9dcZv@`~F898~nu9%)#cISKLeD>+UFpa&&(O-)T< z>B-5C0oeG&z3Z#b6Pr!z@Zhq<1M{889VJRT5NVTiCf%RmcO*)w=ewj2!h;=hOBP-r!4 z|6;jcL()>NA7UR&4ys+>ENb>(OxNh`?QO9p0}Z_k4k4YY5={3vlfsJ*l+vZW3zj** zqLdk}dP2=sKm>rP@FA<7twUZH{G{`i4KkPhyk`dbmS|dl5kG76x2sqlt%B_mr%7Jr z-fFS?_6o(ro^B-n;qa0i3@P4?qAqb{f);N;J?fMj&>rKw(a_P04wg?W|lAQ?luMXQGo7)u} zoJ06FXr7$B_Z~x0actpO;|p|APD@V6%ezIW<+d5e&T9~Cq_di=N_`o{mob)8HlphW zdYvb_?<$(J`dP@HwU&=Eb|2hi6YC$|MOV@o7>kpM+3iJUy?T8L>*zha^`KuB}h6 z(+J|^Tkm{-C?^qz(*XU$;AJ08l7LZF{zIE;(<0SjcH91)pE>)QI4wu6&v)CLy^gk6}lIVc(Qq- zstA(i{KBUHt`%8w-LVF!DijZOo!EGRbgdR{c~@x%3Z=TNi*&S^Xx>Ap$any;cL56f zDd|)#rY`tPM_MyoeBva5XWi~{yy)*n&>b^^sZU%Fb9L`*sMH;dWKgn8{y{!gBJcDv zIULQlBe@x;XahJHx%xpL?p1@E_h|T6V2?;1nVS^-iOpK8W1=}Q{(a|Sb42aW{PlX` zFE(jD>lxuIym2=Av(6(blgDJOgl0KlZM}&*fh+>ft?}GZDX;2%Q#BfAh?NF(GE98# zM^lcOv6PAW?7m$mnp&_BhT`0A#^jmHU`dF3i?CPrqHt6h=KFpQID6MY_4EKn*=KZ&-Uq3WReI09~u!`o#E!{Ou>n zS|>U#VTyiJeK@TFSM=(d>uh?fHdbZUwDJ6;rr?tMIkw_UyjZ|PaRIYNm8addzkSqv zqdpL2ujPp-ji`;=e~X0@1Z)yWefCJAG;%cxpD^|ECZ&7`TqMy(rZ~_WuC^9`&X4sp zW0-yo3pic)gM0IIs^X)x)sOd-{aofTy7#&*Aj?ak0(U6~$}IZ&ZVE`UJTO1=O_jRHPvvcZw`la4gtr%LzQ?pH-qxJkAnfH_kht2AMmVSI5+@ph$p_x zGTxe}{y=oZ^ZY1t{lF1v4vLB?S1^AV;M7RbW=y2=CJneg`BOt7^a!~UuQ)=rE;U2wh8e;@s);B)x z*X{~0#lC|Nm&h88g>HV7 zOYcu`%pE5zK5;uhc#g(E3m~c5V&)Hl3&1D))2R=E&#qr@<}LuFwgTIDmaN?6U#7QR zLrdmgm-ZpP)PO?l2dHr;I{EKf6ZEw7B8TO33OKPxO2}`LY(Ke7igvOp#&1zK2GwoB z%zR(CBsjoh3W2hBCoTBW+j5hmGJdK70jHOLgy02`%%SV%wiXZnP;n`R1cYQfCmKOI_fq&HP1mgWB+@S2|lVeM0XsVr15k1?W|C%L9J?m zIN-f2p5$Nt?p%5Jk6p!myGd_P*9Dfa*S}No7BFRY^k73t{#qqiAjmy*?X?2aB;|L8 zVw}?r>dqpKqkHH&MoQ54v7=scOh)(I&3N<_jHFh{Otv;nCcfb>ovwoA?c2uuE(M=% zjM)ec+wY@NrmSu^W#;5ic41{b@jPYrwxv9M_QKpm%9+xF;;&ZNOZpPv>)z52t-`e6 zC8EOP$_oeL37&EN&OgC{n~$|bu{IzlXRPziMIK!R4bt*#lMw0kho}|zDV8Loqk8_r ztsaS?*9LJ>^Nje0L$9Lalc+rX8aZ`=pYpiZioiG%zB2fzeDcQ$@%~5A@_b-xH8I1s zatjsW{z$Kji_Zw3v`5KQkau+7!^i=R;zazP@OYR=5&L78*Iu-dFlVl(^jv!SpMPfa zc0OsYa{V;^rTxFEW3?}KI+9Hy0WCT%rt1#>86$3-NAKhFS;#DgT^QEmdbU>AI;ySa zqb9mtt_N~d1LiI;xDm6-%#u_cx8DZd?3OyJlRS2@wR#c>_p9Y*gECLM=^}04Dd#TI zxE-f%{gK?J^m1y~$No|ts(m6j7U5(6AaTOnPYuXw+=~F-zOei4Ivc?xjkjCx(1g0K zBX;d$xwULVhe;^_ptP;&GI6Ie=abZ-f8Iz8Cm{rt9BW;x|yZp8V863 zfM(Yn=>W-E675=}_I&QGPo)xKTBhECd1#%hyEBV#+w0#=^Nyzc3&vl;>E73cMAMW& z_z~w8sVP;_j^+TNR;1S3fx6MSclw(V9z$7NsorKP_wbQO^7<{hZ>_SbXnCFyC>4uM z%068FSRqc!-|BmwgC~KGMO0fI%03u8WNHBZ&_s841l%GQw-#@2B&2Z}GBz*8#zl1% z?TDzJFKFZtWjLt4xx)sA%Uoj@z^E@|bQfk6c@v5n;o5LGsP**B9G7itO|cywwJWC$ zWR6Y`7)q0>-OYW62mCjHkChlSRackEDdH){O%`8y)$c!#_F1O4oCe)C9soo=w+$$b zy8*y`+=T{-&qXjp`uMoPB}z761$T?B3>fpjZARcH{@jkt2u;15ACEKGXnPQ_StV?A zN+bYh_gSSetMQ_s@)C>Cg={*1s5U)%X2@Ro@CTd3+~X~uUC15yMCzj{1p}Z$%5rR! zN_)MDz<9Zz#P&=%U%6FXN;7m%!Lk|3;TIXrroeGF0pi%1l0P9bg$$jIRQs4z5e{KpOW-xabMH32ZhGfIv52p_DG0QRo{^m<{yFa{VIQnjeN#y;= zNAEcm5&OS+H`iA+scx4KnosM^9T!ZGF9aI7HDW7}j`%PHa)TBR|KuV@1|{Y-slXWF zI;V+#H)8_3ft9OKwoO-73E-m>_t+BSuvy=&Rf=K#&Bk}n96Nm7&t<)9Y?s>HC|Smn zhg=U3?2lQ~pa!_A94Q-_c`rYYt1P@L^(jOBYp$6%RH{5ls?c>#?ux1qnfTru>fUIW4d*7F8mN7cQ8MTSePi;h9Y}8+bQ6Fw%X3j3j+Gd)nfj zP67{4`rYt>3$i8|>T@oz6VNvZeZK=4;%)tBBdqDzh9PTi409KbCrI1XS=ZeheeM8! zPpCON+=l`C*#Woc#b!~EaC}_666Yd&A6(y3B=*tcD%{+~0Lxa3^2U*b6W5_^;qj0x z0`9game_U4hJ*M^_bYDdyvcF%QL9;5Yv$CYjeNOM5+Uu{~2AR29 z18N(VG^#zGh3I0KlW_V87xVSLLnc&`ax+ZS>6N_KaivRv#}F`-5&$gI#68dY@NMgx zIy<}OEGb%*a)}2O4=@?YfL*FJUvz~xX%Sp7T7IJW53GvIjMX{yRA@3h&JB%X0XJ`s zOQ39ye^CKhRdW}{p?^_on!A010fcrEV|BnYIo!ix=RFRvyLwwlOG$sGtrYUa73ej@ssnkJ^c3NPRC$5d5~ok;no4J5pwI`5asxaIF5Du*cDBem!L=!o#nQ1ELF?CaGnjo+}0ms34D? zx6B0XrzaB0DpX+ifba)Ihtf%Kihn5|@Uy-RetrYDLkhnF>x$E(W1X{{MQuQ%Ej#Bxb87$ zP;0J~l+;iy?W=Iv(u<$naWC}KVE8ZAV6AbnTBz`ch~gc}dg(|8v$E&{{kt+kX|E~u znU*D9N+?BJb`iTX4s)27$kF)27PkXbZy}(+TOP2=!ujl}L`X@40Sa?8P+XArb*BC! z-cGwR$Ib5dD87fq%mMM(D9QYlHRLvBzpp*?EPgllfDx|a$+PqC?+zvG9aBOI4J0CK ze9oZcGW&Z1!d$!VX}=3>l_aIK-9#%_B_hWT8Fh4jW1zAL&V+-R;jmGlGVmC*!6;ouMZg8PagbMU8 zpKTdf8fiIiR2puY%x#K3gQ~Q?P|vO@{|;ilra{TK{Uo~cai%tV7<3!K9hLbilnSse zT-Kv~yMnish}AZHXISgCU{)eT-(SebB>#$Zo1Y~T?jedQo-^x%I_XTl1X~AOiJk7u zBGffB(&=7M@?Nd~f;e<-l0j=Ryn|RTZC&WxfY8>T!=v2ae9$&JDC_B2Z;KGFAlF6X z!@u4yJ{yqzyzrs+u&7MQq2=r%2~)U$ulJk}i6!i&7n-wwckt%Dmo7ALclSg6knB+p zoq>_r?|$Sv4Z++2!PbabO(8IEr2tCBZh;wHz0ftksGuAQ7z}exJmUOaocCGvG_w+$ zcH=q)*eofn%)!mUO3F&|qz_tRjbJ~6j|tMZoO>kqb{-W1FVqHU+*Or%{=o@AY3`jG zt!kQJf8adqcn~@?y&;@lXI<_&X~}yf#*mFiXqRO(4qC1#%PpE>)`wGd@Ml*FGWhD_BQi#HVPKWh<@e)ld${~ z?QCvmx~FEe>1)Q_eX*?>WsycD(|UB#n7A3fcxHjfxTLI+(coC^SOtxvC7@`)f zm&L96#hqhW;gm*u6SJl13JWl!8Ppw5{S_$Jw&@3Ux%zQ#+L=RpA4vPj;5f1U zCgdebq&TM}c)xLvGGm0G6)Kl&gfmUye_P{MA@SJaTHqm+3m_@aOu)uosK5>rRmuLW zH9qU@QkaRCms)E+;}b$xF($OhozMAG`5*N%#ziMA<)IuVq_o*Ej~`yk4Tk3J6fXp# zbinCw&w)yZQK|3?nnb_(kP`n6qKC=ei++jj9_~Jwk1uCS3`-@;Qz(BIi*@!RT4H)K zrDY*Fg0@SsRR^;J(RufW*UWo#VfY_S|1kFPW*9zFT(J4`FLEd>Q91mb3f|k`iz7>c zBcBds&<5p)`+ql+J5!%I*Ao}XtlfNz8V6*jq>BwrY1R>#CCiFfI;gFY5xtvhbUW#H zt{jOONYovzeo`+Zd)8wIoouPu45zR@R2Qj3JmS)dG^oy1c=6*`19|X=;6f{=w>4p% zyqho?apAS%?BY&ow(<15+-w=bKl)>*qJ85M6Z*Yg@<_$`rjbsrTv}V z;QS_c0epj{+8${mI^CU#Ro~V~>yNbp>S|7OjaiOpa0qm#_v=SP^Qz)}x-W&jPE0a- zxCZ662kF@4qQV_f1)~BD^9mb6z|3-s>@1?4uCO1Rn+@$(0+yd{LU1O;>K(^IAf15b zE1mzqbyG4)yFDh*)|yL#XobAo%*(?V9_61+?jfMbBxwl-I z_wf8#V}%i{xoe@uSm$b8Aa$>t+-&w){BBKyD9THbmEhED?%ZRt=}b z#QWIW+k4!`etg<}T`pk_UF!Mbcw9crTtg(>Pmq`eQ`TC-X660+{=wC0<<-qmoi zvb8p-3qv9pz%e}MXTjv}T8R~T1f&MxeJdKf#ghiVp3dh?SEgU9kJD8=Z8a)4oA%zF z8J(+?kRH45vlI>x06JMM$^2J`aRIiTZ4EWr#D(QvY zZZ0ySemGeK*#@}lG%7~*f=EY~>N5qW34mr|! zfZ4lKu0IzJ$KNhY`V9HV*CTjBC6hd&*I`Ezw>@~>`roAyN@FYkd|BDLcYa@HnuZ;- z-Tz2)igm*$#Ehp!##njsoqI%5JjC)hgF+wvd&tXew@^j)M^!fvC+mLl3Yg>?4IbhR z^ZPqMCUnm7#p`?IS4r2sTEfCn$LkO}Jo8}I?eEFdGKOhqkm39S?Fsb8jmZ%}57$vk zou9EpF=%8|p+4S9hFd4)Z|QQ`E`LbIX0ro}3*a#U@DE94+R7lAm}{h~8j_fB`*|C->t7uoy$ZDJYeboi+lM;g7IPr`A$=s zz-QztZXt?q@mh<2-(+3Tx_U02ii`>xty6R<);%j5K-1rnLr~itdf@*r=OC2U>?5=K zV~7}FIgei5POnxGGnB1Awkyp_*sG|W1+ctc2-tET#;lr5ADIC+wQdjlalW0gBBC5*kqOF=q3 zk zl3kVnlW})jFv)ke#mD2=5gXOw7U|l0dXJ0eDQY}f|CxY9By*f`7EXnCMwLotl+e`$ zUoRJieW1HYx>pV_Z)oSBXwWHvz-u=*_ejied3pIG<4pQk3l6e#-)9NpdBcxGu`BEw@eg9tkLv_`)nwR|Y@;1wy8WZH4CKcPwf z(N2FPzLfmOvPzucu)N2->)DmcOl|e^$2%ql>y{*I(*yjFg$eQT=RV_p1#90Z11Yj4 z+nrX6eu(;>ICx$35ZnWSZVBZBqrTSOjL0+VbjY?8%sq)}gpM7(_SUqw)PQH1xL$?T zci0rniA#>3oXu|HJcbL=JZzQF@QMy-v}zVq$z1WrnF`VrLOAy0(8QYd=fa&lqIcI3 zO!gywfEHB*_)Jpg!xEW4VS>>A`f7is_h_kGKwcb-=m~u zCNrskv>6v}pp$^Gp-cKj&k-ha4fp(4O4Q;h!_oy=0pN{tD{R_5 z@%YEdWa`~*?eaXw(a~UXw)mvbHT$Uw%M&E{`iIWdnIUA2rN6kjCB>+01Y|Qu2hQG} zqHXkcpYLOU;(`ouYw;UDo>mS2V!l%pP}@y%0H+@F$iVL=%otIGrx+d?C5B($!auej zC9v$-zR785-fbUs5Bt3F+XFFNH#`q&=xt-e{l1~A&RLcfb9HVru^ZMLuGPOkz40N{ zE>r&{G9#{3#@T3NZ=Xv*hA6YfKk9he%f=?#l2mx%d^Lll!lTB04^WQ%12^q^cgBQ# zFNrEf7pLcmG`y|wU#RfW&gekemxAor#a$LQp)rMJ5&R3GL88YR8#@Ie2YF%b_H9U6 zouz~H^Mz$umd3B$H$hF(%2;)OFdEs~v#S)6Isc^1Y4{$ltc?F^!x`j_Aq3G-hRPDe zQ1(AZIZDluf2G{U=Z7Oy3qI#;6%wAH3%2|4aah@6)k2$FtTR|{k)ae5Hjyd>B<-F$ z5Ncbs_0#^vdbPVUEwEXHZk_^I6kP@ZqpX0g#l^+^iTk+g^s`i#)^FF=bBE-9?^89e z%5qHSym1u`Y@J7R4&XpVKa1wo*9#C{N57n0L-zA#a>J{RsoBLcQzJj8*G}Xh1uaz} zaC9#D8ULXPWIt*vtYy?&@I&JWe2{JG&`MO+F>(_xB*Tf(+}_5g+wYe`qeK$MlzD6%2Wacv4WdLKRvKGWMGgskI(Z` zUVUxc>1Uo%HQ7nFK+I<_t5qoG*Wrc=iBG3vCmq`tG>&1{XM3s=5XmMo>9Zb77ZVlQ zG7$}(LvQEXY19yFh3+`lzqU5>@lh`&W-_*fY?8Pm{$&MyPV?L4vc^5?t#*%6YV}d) z3vx99f=qA7uIe8Qdq%kGoQ5uTVmO0b5qn(l5>!{HO!F<^9JRQQWod0bF+2k_-V!c! zhv4U~?-4!LlDzbMd@WZH4_$IL%^)~$H0zM{oLAdaIh?ljGa7EJLBl#0R%C$IGd zw@M2ZykQG;Y=$ZpW4_&u1d<%5Tzytbf2=kA^<{5MIgzGwZkFM}wO%5FD-@ilPa*)3 zX*zzwrr4v*JP%c}^edG{94e@m9{c5fZfq1v*Dw=fa~oz%qMYHm1ML_84$qZG^2w>5 zu(d*6C7nkll*bKbVG6*#mC+E9PKR#ag>b< z3LRA2f9zYOW=K-U^=b7RW#_Qbhe{+P8mfGY4Agpeevo8+qZ*(3P@avlPt)%E)_1wd zMEzge=wkI7EXD)XtXv&ov ze6nSCb4%HonRYI&$QvsB`pl67gmRZ5NyPp_#Zh*ghi~^QN!f?H1Bbq1?(*o=#5L|i zTL|4cQ7NX*P}C2%3FurpkX3H(@~5voQ{CpDPJ&RB&-~UKSGB^gzz0`qNtwycaj|2q zClowvG{*Cwn-No4k2)7%*iK~BrP){P0HSqHJG263T1R_I{N`{sQhx3ZT4YLVL^xj#HA{lIvJ8cP$(SroZ&H*PV>!Z{K{BztExTuKrRh z^F_Mxq;5yIDa7eZ4CV21r!5-Nu40jQ#26F-@P?1?E%({d6`#5N$Yu5^O^=N#S&*p< zmA;chM*yB2GSV(h)Ly8P`3bGkb$5E1xsnmHoleC`w04HXycNw?yMs|13>AI!h>c8P z;P}@@U{l^M7xVG*qvx!qo1_z=E0y0J2bucSH4ylP5qaYZB{$3AlZ4mZ-KY1r%p0LC zeQb^A90gbu%T;PuPHbCO8cQkE00AdaC86f~a)2bjh z6!F?F7ZYSR!gQtg=GylZx|l%mcpUfVOw#>=^q7OD7|!+__zA6xmoJ22V#`MyWn1cK z*Hu*4`8X<%?ro#61o;CB*|9k8g^71<&4EJ;t{fVY&&0U0RxlD_0lw`}Lta-KJ zBQen5{A`MSSiDOoR6z323mu+qhtnp7Y_hINpR;K70>}v@ev+w?Y1$7q z1s#caZJDU|>$qdkYDvY|V!m^M4z3Y~e{nLH=^t^U+}(~9=XcdMj+GU3FV%QnC~Brf z`JyH^a7!fELi@bqP?N<^w-n5W?SyfY&jnVYTwT40Rl8Aa_~sg;)w-e{eznkMuZLn^ zG48qDNS*YDR|*5dIJYiX3n}H;m0|(qXS#_T6bB=foq)?iAWFd z8=zH;I@~C&DL95DcB^YZFpn|Q@5l50I;=3T1KhUZySzfag)Pk3U}PSLC57<()xW?+ zuM!C{T;u|j$O-v$0_PfcE0+C&(`rv!;@2s~1XjEG#>8!veU(gqG$(TCn*CT&8*{5D z>r_?5>narb5Pt`f3xCT7kg#i4yP&koULkn-q^wUFdD%!GbR3+Gs;QchQUdUPP26}* z&Z9^`U#Nv?=&uDX1ubMc6 zzZT5vTzVl*n@2}|cLQLpSYOOLQ2azZbaROVkE^cIAX>3v0F^yq+eUtzzUhi6Kf6gwx zgQg)K@_GKj@XxjQcw2=#@h0-h@Dq-~-MWwpM9C`If!MWJ&6|PP!2o-%Z`zk~6%MmG z+w}Yos{fLQ3T-fj)t6>sHV`|k-2%RT+GsL{DmG1#v44M0jnGCfaMim+*{SQ{WY2?-7{{j z^d1mDJ1J6%=CC@)_56sfFxkW6+SJ3Icui5C^0z8z3DSS^Z1*aMQ805L_TX2`0xT|I z`=oeRx_cw^-?@S{Ds!j(pevNq0wRkyN5SUKR|X#)WpCFoq$@L8d%Z|+-Tct(aHI^2 zbd}wTTu*J4%>!tIU{Uq}cbg%cRLTwB3Ci-C*u%#v$?H<|%uS%X4(CI@-gIg2bfEwr z0(-z;!R+DWY|GEVV6gQOImWTGi+C5^@;puva-(vZ+Z+1c&-aKituF91_KQt-XmvT& zaKsMFw&VQyPFiZ+Qn%7me;J~DD0L+28O9wA#w;q5JbdgZ9{&75fz`#8F zm4f9$A_KD0#I5TbUL z8yE|A=2nWB*4K*FTsy@yH14THS0|Z zGl0)aw)Lp5dYXKQZaU~h_>5j>C-`}Odx&z8M%X@(mUwU!oM}SNSZGlSx>CO-x1 zMco8GdFl_Foc!;qVWAn)R;jd-IxJPAylLG%1>Gv}V_!7u){zIg=G#KLm-EieZpOs4 z`T6_i?y65#U8n1UN*j$*uI!op&S;I#Z}TlO&RkV{vNnTZ@)-XtC26Y@!Tw2y8GubQ z<+0##p&*3X)3AT`KZ3U=f6uoq-d>d}>(y=}ok!h~$W?CfoAbZ+*2c&E)~8m8+-{>+ zWMzk@fWC5XawDxf?IncuKJwLgnNHx|r}gxX4ysIY6wo~L8DTZoPp3ho1XkB&(2rLq zWG^ggjcg7L4t|Lx%#d_qFv$@&-|SEN!ICc4tldjGmuS~cEwQJfS{U~d(hl3FP;R5YpN}BQFlL$*{rTxHAw$}4v;9FFQj>i95hCL9!4QGc$Q* zj|=c#iP|AQg)J&c3;o{EDZ9@Lg__>F#o6~pC2IX>WO8TNNP36`phl2zD%~z@Fe~Yb z>+i}-v(=}Um51LhunpdD0I*bl5DA-*%r3tbdiAxWX@ep+i{vlVtca(UJj2}Du`J%* zNMC_Uws0_|-KM8}u@3!Tge)_Ftvt!trtMhjAK%EAZlXLp!yU1D2tAkwh607!(!Yh5C=WghwJZ4ivKP z(Ks!OTw9=Ix79O{nZ3}YR!T~p+(U?StCB!rQnQhsYR?a%^kN)fX%b-t4 z+79w~qp5`6mFEzR?ER^rSWx?~)jwHx6k`?t?5J_O`RH)@tA(wT$4CSWdwpL6qp=38 zcBC1bqQ8FM|K>$W*QKtI$h}5AVS$j6~Z2xjl+z&12^f zHJEdzpkpXR;^xEgPX)jUJodo@QczH|$xOPFbf=Ic{_Qt!?H{e|D{ZQ5SjXTaiPR4FE>*%8~nLH2ix?Oao3AOjxJc_gOedsTJXF#E8_;At&gx& zZ2)s-;B4)x9cBe5=xG?N8`vJH$1T2*o(cI>ATo;8HTDGf(R-*jZv#E}}pqY&gv+|;k$_fnRXU43etE@18NdQ?wjIi7v={QKL`hxw) zixp&NgUy;J!cSn^_u+bs4NC@1vkVN`Uo=ZvN{cycmU);6jJ%ttg)i$L3+WoRyj-}v z7i`5O)Vf&QW+r&WHP7l#5$;E-Bb6;qW!*0>FL~1L$5oxs>M2cyN#So^l1@VQd;=Uk2n z3p{5Cde~h4i+i5W=$Mq2B$fSuf|HWy^{Lhb5(_&4m z2k-xVnO~{hY*rDHTkwVc-vVM9tZ;1MDi&HQToSo<8M)2Z|6Q>^PdI8vvmcfKksp9L z&$qc(q1Ju=e4|etn%y}+$iDRM!+Ako?6T&AhJx^FRxp+KtJk#YfAGz;GW!N*zy$z1 zyA`+`7?XmXo**0-q!d;9Nr#u};;@4MJ^eyb))!ofKIMlXp8Bvg3rqnVVRhWOxuj%q z(zyfx*Wu|o5flhLANd=f zYb7!)=E;KLf-gVovy7k0=6#^AM}X`KrMuEBm{-gL+Z_AO#ZN4BsjOcJ4Y(>$WcD8B zy3#ImUNha1Oz(3(+IztnRhUK%d2kHaqIZ$9pC0wGAU*}Yk>_Dg*2aI_LS^J}#b`6C z(g@!sp=bFSuPy1IHKM8`WJ7|IC|%00BtquGsy(YzJ8oTc&JYFXQI-5LE)uwX>_Lo} zg>9hN-N!3>SRb^)sk1K%Xj;t(fO`zO;Z4p*-ui0;C` zyBK@CF{?Z3{IvoSUPpYDYzW_-)g9o4zmr;|J~VaKC0aO--y^Xvig@}*p61eZ@TbG5 zLeC|TU1YS)Vt`SOR=zr-Zo0$5r}IRA04?m;ggQrIUTkCXxx~?aaECJUP-~ufb590J z?26FCuRo;2SW6Y3=u-f65q43S^WE<5U`DZ13t3Oi0W^ee=7tJQAbt?BHTEFx*g}b8 z@M$nyk|tiM5KWB*^<>U#Pd#T-;E8D9nT)~PEY`eR;x@!`Z$c!!lrzOugrYo5j1Um7 z$27}9zv!2tm?jANHJmS=&9hXE3V9>W)9wfJ$3McK#1(1L_VFZ(mtDX2k71R~KXf8LCiD%GY*IgYQYy7Aeta$MD zzZqCaVFEVakIb7(Q$p8hDKD&tl*p%C) zK|LCmbp|$M8ohH8+aB3*!Tfg;=U7`-@R=m;&gb+MAz_7=q>%A%;kUZ_jXGo@)yu03~iZJm^|JsSx7;~Hn+ms(bjO?t<_D7i8h0DufGR|OQV}t-W zXuJ&+;9B*QE7iXM|$zR?n^fY#U5q{@EgiO|CLc{-(8Pk7un<_ViW=cHREQn z;-wvi2HghOCT_|Xf24D~nR|OHMKk@l_;4(VDAVOFTbI|bs9Iq=9KYH3nNm6M5*w@3 zp6WHPv&Xy>pM{WZ%$JA~3wGIdePt=+5lzt8>um-VFjf5%7Mi!}Bv%Tp(YZz`Hik-* zKHPVG5AO(ingg3=2HO(w$n==_>?K>+KDdf*cnb%%16@t+?)XZ~2L^t&drn3n3MgNKM)g=67Cj?QnXjH~D zkWSw1e*{32fVw1k3FLnd-#*Fgbn~WxZxy^Gw1@c)J&xOy^y=6-+8y!3!UvAf zr8@Wn@fXSCLo_pUqJW)7$hi(%)sOV$lY}~f5V_KWJEEAlwRa0Af&U!TYT0w+V2KS! z*dH{j5dlt-ulKcD^kpwg5)><_1_deUs9BOrQ-b_3=4G|MQJBw3GT-s4n!{4A)pSO= z_4}LBwoU?F=GmNY$~yEV-UDiqpjNSf2`Zww#ko8l>(j98JxkZANQp~k7m6q93%<8$?^ z$24GJDig?(H|VM=Uch8TZRM#??0X9I`RkPJmj0{2C3{RQltFo@4)aKsjL-`(l%q>_ zIbj{{-s_Wc2R*{a72|lTeEfsJyvEW(<}|<=u#Mnl*x7u)O<0yyF_iw%wYrxS63)hA zRn`D-KG2V;RUGXhVuQ{fWMMB~zFb7d@`Degke!-0KIzl=C|PZP*45V1I*}z~YiCH`#`stVqbKrdx(?&JI!?f?hk4tZGWvin<);;NGPfk3&a3{#Qh-*++~ zq?sjv&PWpTLj`+pOS^X8F+y$28!hNyv~@CNT^Lf-1X~rjtfUkkpz!lbzljY#FT_}^ zh$yBT|K{{>K8q1)^nqBG4Ex`)Gvy0jAGWxUo#Vt~h7$jE1TX`gmxUcfg@HC-PM`$i zaGH}|gpanFl*Hw1(B*f3;K~}<5nk#E3d=p=WN@(6aILs!v0#UINm|+k@wSxcZ{mD; z7u?%*YL#s}D1blA$kI}P<$^r3Xd>@3-ax$l<_p~)Z8=o!w#8}&KH^KjRsvgOM>jE- zMRiyH5rE;kZD%(C?F;|S@K&NireKc8tZ6&>lHwrQ){^@Ft#XQdHBXbA1O{RRbd=*An~^&#qP$6z)IcRFRgsiEP_&VzgrCK zKh)JTlWiKqF%u1La=x2G-&9CiNP-yG}>Jypn*2G#BYn{$gK} zO;=TDJ@1c&&AX5K3X6}_y+Dka|1(pXYuL2@Tmf)^iPV)>DJ!QT&66XuR%oi6yu5G6 zNV?s}xfMXbIn+bLSF4zvg1r$|tyviGe*Vp-<1@%6Uy6kkXE%oF^(=XJE2nz0^(@lN z|5-SF%-+vm6^k!NUOR_-m3dV(92wr-EU(!+b$2t_=0m#&oLTVJ44YiDWX1MfMB|_H zQ=gh^lGVZj;kPdfD!9!*I*j@L2yXXA>1xC4l%f#1=3kx-{T{)B$i$7hGur$EFa&%w zJ&XuJW3*4~>g|WyP0q**_4tmwQ}QP4@j}oK{G-HM)@JDgwqI}VByV(Dd$JldUZa&lXJ!`SnTokY@Y4?hIDkZO75oU&KBp- zt(A8vuDhisyMf5fdH4#u9d@QkRRg&x!aLx9y>RS=y@FVy|A&%l%+EgesW}I;)OAeE z6sd*KB%(4@O9-X?b1BOR_Dw=kavn@qe$tm9 z6;NOC-9*%=YbR!11T#!O3X@aVyZLx0Fb%e-(*&Kh+AdIot$W{x?{DeJO$#7x0;3`#b#U9Cx?uY=M&hJd8Mrz%-o(}ko|a_}FZ?B?L6%%U znE!rD+9qD2;uQvE+3VpaKBB`CaV@F_h^klLKYCBaM>A&q((_$gAAS7w`+9!`rdZ?b zrpXiXY>XX~H)TTTt%vVqi?EHA=>Lz6tiuUe3+am@>%?ct Date: Sun, 28 Jul 2019 16:42:49 +0200 Subject: [PATCH 10/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a284d4fb..997a51d0 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Tutorial (in german language): https://www.heise.de/select/make/2019/1/155109923 - + # Use case From 45b0bae9451b1d12fe6ea101d63fdc9c1df26c4c Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sun, 28 Jul 2019 17:12:46 +0200 Subject: [PATCH 11/17] Cleanup of packed payload encoder - Cleanup of write*int functions - Multiply pressure by 10 (decoder was already dividing by 10) - Fix undefined behavior on intToBytes function. --- include/payload.h | 3 ++- src/payload.cpp | 37 +++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/include/payload.h b/include/payload.h index 1a74e762..b41bb113 100644 --- a/include/payload.h +++ b/include/payload.h @@ -67,9 +67,10 @@ private: private: uint8_t *buffer; uint8_t cursor; - void intToBytes(uint8_t pos, int32_t i, uint8_t byteSize); + void uintToBytes(uint64_t i, uint8_t byteSize); void writeUptime(uint64_t unixtime); void writeLatLng(double latitude, double longitude); + void writeUint64(uint64_t i); void writeUint32(uint32_t i); void writeUint16(uint16_t i); void writeUint8(uint8_t i); diff --git a/src/payload.cpp b/src/payload.cpp index df879467..8afd0b3b 100644 --- a/src/payload.cpp +++ b/src/payload.cpp @@ -92,8 +92,8 @@ void PayloadConvert::addGPS(gpsStatus_t value) { buffer[cursor++] = value.satellites; buffer[cursor++] = highByte(value.hdop); buffer[cursor++] = lowByte(value.hdop); - buffer[cursor++] = highByte((value.altitude + 1000) * 4); - buffer[cursor++] = lowByte((value.altitude + 1000) * 4); + buffer[cursor++] = highByte(value.altitude); + buffer[cursor++] = lowByte(value.altitude); #endif } @@ -195,7 +195,7 @@ void PayloadConvert::addGPS(gpsStatus_t value) { writeLatLng(value.latitude, value.longitude); writeUint8(value.satellites); writeUint16(value.hdop); - writeUint16((value.altitude + 1000) * 4); + writeUint16(value.altitude); #endif } @@ -227,15 +227,19 @@ void PayloadConvert::addTime(time_t value) { writeUint32(time); } -void PayloadConvert::intToBytes(uint8_t pos, int32_t i, uint8_t byteSize) { +void PayloadConvert::uintToBytes(uint64_t value, uint8_t byteSize) { for (uint8_t x = 0; x < byteSize; x++) { - buffer[x + pos] = (byte)(i >> (x * 8)); + byte next = 0; + if (sizeof(value) > x) { + next = static_cast((value >> (x * 8)) & 0xFF); + } + buffer[cursor] = next; + ++cursor; } - cursor += byteSize; } void PayloadConvert::writeUptime(uint64_t uptime) { - intToBytes(cursor, uptime, 8); + writeUint64(uptime); } void PayloadConvert::writeVersion(char *version) { @@ -244,24 +248,25 @@ void PayloadConvert::writeVersion(char *version) { } void PayloadConvert::writeLatLng(double latitude, double longitude) { - intToBytes(cursor, latitude, 4); - intToBytes(cursor, longitude, 4); + // Tested to at least work with int32_t, which are processed correctly. + writeUint32(latitude); + writeUint32(longitude); } -void PayloadConvert::writeUint32(uint32_t i) { intToBytes(cursor, i, 4); } +void PayloadConvert::writeUint64(uint64_t i) { uintToBytes(i, 8); } -void PayloadConvert::writeUint16(uint16_t i) { intToBytes(cursor, i, 2); } +void PayloadConvert::writeUint32(uint32_t i) { uintToBytes(i, 4); } -void PayloadConvert::writeUint8(uint8_t i) { intToBytes(cursor, i, 1); } +void PayloadConvert::writeUint16(uint16_t i) { uintToBytes(i, 2); } + +void PayloadConvert::writeUint8(uint8_t i) { uintToBytes(i, 1); } void PayloadConvert::writeUFloat(float value) { - int16_t h = (int16_t)(value * 100); - intToBytes(cursor, h, 2); + writeUint16(value * 100); } void PayloadConvert::writePressure(float value) { - int16_t h = (int16_t)(value); - intToBytes(cursor, h, 2); + writeUint16(value * 10); } /** From 19ee712e517c5442b452e431355e9878fe84a34a Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sun, 28 Jul 2019 17:22:04 +0200 Subject: [PATCH 12/17] Remove increased altitude resolution from plain decoder --- src/TTN/plain_decoder.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TTN/plain_decoder.js b/src/TTN/plain_decoder.js index c6eba7b4..b7478b9c 100644 --- a/src/TTN/plain_decoder.js +++ b/src/TTN/plain_decoder.js @@ -20,7 +20,7 @@ function Decoder(bytes, port) { decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.sats = bytes[i++]; decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); - decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])) / 4 - 1000; + decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])); } } @@ -41,7 +41,7 @@ function Decoder(bytes, port) { decoded.longitude = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.sats = bytes[i++]; decoded.hdop = (bytes[i++] << 8) | (bytes[i++]); - decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])) / 4 - 1000; + decoded.altitude = ((bytes[i++] << 8) | (bytes[i++])); } if (port === 5) { From a061e75a9e00cb68ce4cf5f90a6916f862796dcd Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sun, 28 Jul 2019 17:25:24 +0200 Subject: [PATCH 13/17] Add signed int decode types to packed decoder RSSI is a negative value => signed int Altitude is signed hdop and ufloat values were ints divided by 100, so set resolution to 2 decimals. Removed some code duplication by calling uint/int decode functions --- src/TTN/packed_decoder.js | 106 ++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index 4663b827..b5379f28 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -37,7 +37,7 @@ function Decoder(bytes, port) { if (port === 3) { // device config data - return decode(bytes, [uint8, uint8, uint16, uint8, uint8, uint8, uint8, bitmap1, bitmap2, version], ['lorasf', 'txpower', 'rssilimit', 'sendcycle', 'wifichancycle', 'blescantime', 'rgblum', 'flags', 'payloadmask', 'version']); + return decode(bytes, [uint8, uint8, int16, uint8, uint8, uint8, uint8, bitmap1, bitmap2, version], ['lorasf', 'txpower', 'rssilimit', 'sendcycle', 'wifichancycle', 'blescantime', 'rgblum', 'flags', 'payloadmask', 'version']); } if (port === 4) { @@ -52,7 +52,7 @@ function Decoder(bytes, port) { if (port === 6) { // beacon proximity alarm - return decode(bytes, [uint8, uint8], ['rssi', 'beacon']); + return decode(bytes, [int8, uint8], ['rssi', 'beacon']); } if (port === 7) { @@ -123,37 +123,72 @@ var uint32 = function (bytes) { }; uint32.BYTES = 4; -var latLng = function (bytes) { - if (bytes.length !== latLng.BYTES) { - throw new Error('Lat/Long must have exactly 4 bytes'); - } - return bytesToInt(bytes) / 1e6; -}; -latLng.BYTES = 4; - -var uptime = function (bytes) { - if (bytes.length !== uptime.BYTES) { - throw new Error('Uptime must have exactly 8 bytes'); +var uint64 = function (bytes) { + if (bytes.length !== uint64.BYTES) { + throw new Error('uint64 must have exactly 8 bytes'); } return bytesToInt(bytes); }; -uptime.BYTES = 8; +uint64.BYTES = 8; + +var int8 = function (bytes) { + if (bytes.length !== int8.BYTES) { + throw new Error('int8 must have exactly 1 byte'); + } + var value = +(bytesToInt(bytes)); + if (value > 127) { + value -= 256; + } + return value; +}; +int8.BYTES = 1; + +var int16 = function (bytes) { + if (bytes.length !== int16.BYTES) { + throw new Error('int16 must have exactly 2 bytes'); + } + var value = +(bytesToInt(bytes)); + if (value > 32767) { + value -= 65536; + } + return value; +}; +int16.BYTES = 2; + +var int32 = function (bytes) { + if (bytes.length !== int32.BYTES) { + throw new Error('int32 must have exactly 4 bytes'); + } + var value = +(bytesToInt(bytes)); + if (value > 2147483647) { + value -= 4294967296; + } + return value; +}; +int32.BYTES = 4; + +var latLng = function (bytes) { + return +(int32(bytes) / 1e6).toFixed(6); +}; +latLng.BYTES = int32.BYTES; + +var uptime = function (bytes) { + return uint64(bytes); +}; +uptime.BYTES = uint64.BYTES; var hdop = function (bytes) { - if (bytes.length !== hdop.BYTES) { - throw new Error('hdop must have exactly 2 bytes'); - } - return +(bytesToInt(bytes) / 100).toFixed(1); + return +(uint16(bytes) / 100).toFixed(2); }; -hdop.BYTES = 2; +hdop.BYTES = uint16.BYTES; var altitude = function (bytes) { - if (bytes.length !== altitude.BYTES) { - throw new Error('Altitude must have exactly 2 bytes'); - } - return +(alt / 4 - 1000).toFixed(1); + // Option to increase altitude resolution (also on encoder side) + // return +(int16(bytes) / 4 - 1000).toFixed(1); + return +(int16(bytes)); }; -altitude.BYTES = 2; +altitude.BYTES = int16.BYTES; + var float = function (bytes) { if (bytes.length !== float.BYTES) { @@ -176,29 +211,19 @@ var float = function (bytes) { if (isNegative) { t = -t; } - return +(t / 100).toFixed(1); + return +(t / 100).toFixed(2); }; float.BYTES = 2; var ufloat = function (bytes) { - if (bytes.length !== ufloat.BYTES) { - throw new Error('Ufloat must have exactly 2 bytes'); - } - - var h = bytesToInt(bytes); - return +(h / 100).toFixed(1); + return +(uint16(bytes) / 100).toFixed(2); }; -ufloat.BYTES = 2; +ufloat.BYTES = uint16.BYTES; var pressure = function (bytes) { - if (bytes.length !== pressure.BYTES) { - throw new Error('Pressure must have exactly 2 bytes'); - } - - var h = bytesToInt(bytes); - return +(h / 10).toFixed(1); + return +(uint16(bytes) / 10).toFixed(1); }; -pressure.BYTES = 2; +pressure.BYTES = uint16.BYTES; var bitmap1 = function (byte) { if (byte.length !== bitmap1.BYTES) { @@ -255,6 +280,9 @@ if (typeof module === 'object' && typeof module.exports !== 'undefined') { uint8: uint8, uint16: uint16, uint32: uint32, + int8: int8, + int16: int16, + int32: int32, uptime: uptime, float: float, ufloat: ufloat, From ad2234271f97fec4c536b41d78821a97e949f207 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 28 Jul 2019 18:42:22 +0200 Subject: [PATCH 14/17] code sanitizations --- src/gpsread.cpp | 2 +- src/hal/generic.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index d99a7c46..e5b86738 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -104,7 +104,7 @@ time_t get_gpstime(gpsStatus_t value) { time_t t = timeIsValid(makeTime(value.timedate)); - // show NMEA data in verbose mode, useful for debugging GPS + // show NMEA data in debug mode, useful for debugging GPS ESP_LOGD( TAG, "GPS time: %d | GPS NMEA data: passed %d / failed: %d / with fix: %d", t, diff --git a/src/hal/generic.h b/src/hal/generic.h index 9d1d0b4e..1579221f 100644 --- a/src/hal/generic.h +++ b/src/hal/generic.h @@ -55,7 +55,7 @@ // GPS settings #define HAS_GPS 1 // use on board GPS -#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M +#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M RX, TX #define GPS_INT GPIO_NUM_13 // 30ns accurary timepulse, to be external wired on pcb: NEO 6M Pin#3 -> GPIO13 // Pins for I2C interface of OLED Display From 9ad6e62e84c7aed8e08af914167374a1c51b6115 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 28 Jul 2019 19:12:05 +0200 Subject: [PATCH 15/17] packed_decoder.js: bugfix pressure divisor --- src/TTN/packed_decoder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index b5379f28..0999c07d 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -57,7 +57,7 @@ function Decoder(bytes, port) { if (port === 7) { // BME680 sensor data - return decode(bytes, [float, uint16, ufloat, ufloat], ['temperature', 'pressure', 'humidity', 'air']); + return decode(bytes, [float, pressure, ufloat, ufloat], ['temperature', 'pressure', 'humidity', 'air']); } if (port === 8) { From e8521094b80e844e01302fa39a147d4b377851d3 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 28 Jul 2019 19:17:46 +0200 Subject: [PATCH 16/17] bmesensor.cpp: added comments with units --- src/bmesensor.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/bmesensor.cpp b/src/bmesensor.cpp index 28bcc34b..d9638d7f 100644 --- a/src/bmesensor.cpp +++ b/src/bmesensor.cpp @@ -146,15 +146,17 @@ void bme_loop(void *pvParameters) { // block i2c bus access if (I2C_MUTEX_LOCK()) { if (iaqSensor.run()) { // If new data is available - bme_status.raw_temperature = iaqSensor.rawTemperature; + bme_status.raw_temperature = + iaqSensor.rawTemperature; // Temperature in degree celsius bme_status.raw_humidity = iaqSensor.rawHumidity; bme_status.temperature = iaqSensor.temperature; - bme_status.humidity = iaqSensor.humidity; - bme_status.pressure = + bme_status.humidity = + iaqSensor.humidity; // Humidity in % relative humidity x1000 + bme_status.pressure = // Pressure in Pascal (iaqSensor.pressure / 100.0); // conversion Pa -> hPa bme_status.iaq = iaqSensor.iaqEstimate; bme_status.iaq_accuracy = iaqSensor.iaqAccuracy; - bme_status.gas = iaqSensor.gasResistance; + bme_status.gas = iaqSensor.gasResistance; // Gas resistance in Ohms updateState(); } I2C_MUTEX_UNLOCK(); From 49735685464ca2f75e9894c4a6c6643ec636ddfe Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 28 Jul 2019 23:51:24 +0200 Subject: [PATCH 17/17] GPS fixes & code sanitization --- include/gpsread.h | 6 +++--- src/display.cpp | 24 +++++++++------------ src/gpsread.cpp | 52 ++++++++++++++++++++++++---------------------- src/irqhandler.cpp | 2 +- src/main.cpp | 5 +++++ src/timekeeper.cpp | 17 +++------------ 6 files changed, 49 insertions(+), 57 deletions(-) diff --git a/include/gpsread.h b/include/gpsread.h index d1452b37..17336afd 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -18,10 +18,10 @@ extern gpsStatus_t extern TaskHandle_t GpsTask; int gps_init(void); -void IRAM_ATTR gps_storetime(gpsStatus_t &gps_store); -void gps_storelocation(gpsStatus_t &gps_store); +void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store); +void gps_storelocation(gpsStatus_t *gps_store); void gps_loop(void *pvParameters); -time_t get_gpstime(gpsStatus_t value); +time_t fetch_gpsTime(gpsStatus_t value); int gps_config(); #endif \ No newline at end of file diff --git a/src/display.cpp b/src/display.cpp index 01b1a1ba..d6cb3d3e 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -195,16 +195,13 @@ void draw_page(time_t t, uint8_t page) { // update GPS status (line 2) #if (HAS_GPS) - // have we ever got valid gps data? - if (gps.passedChecksum() > 0) { - u8x8.setCursor(9, 2); - if (!gps.location.isValid()) // if no fix then display Sats value inverse - { - u8x8.setInverseFont(1); - u8x8.printf("Sats:%.2d", gps.satellites.value()); - u8x8.setInverseFont(0); - } else - u8x8.printf("Sats:%.2d", gps.satellites.value()); + u8x8.setCursor(9, 2); + if (gps.location.age() < 1500) // if no fix then display Sats value inverse + u8x8.printf("Sats:%.2d", gps.satellites.value()); + else { + u8x8.setInverseFont(1); + u8x8.printf("Sats:%.2d", gps.satellites.value()); + u8x8.setInverseFont(0); } #endif @@ -252,12 +249,11 @@ void draw_page(time_t t, uint8_t page) { u8x8.setInverseFont(1); u8x8.printf("%c", timeState); u8x8.setInverseFont(0); - u8x8.printf(" %2d.%3s", day(t), printmonth[month(t)]); #else - u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t), - timeState, day(t), printmonth[month(t)]); + u8x8.printf("%02d:%02d:%02d%c", hour(t), minute(t), second(t), timeState); #endif // HAS_DCF77 || HAS_IF482 - + if (timeSource != _unsynced) + u8x8.printf(" %2d.%3s", day(t), printmonth[month(t)]); #else // update LoRa status display #if (HAS_LORA) u8x8.printf("%-16s", display_line6); diff --git a/src/gpsread.cpp b/src/gpsread.cpp index e5b86738..d746d127 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -66,53 +66,50 @@ int gps_config() { } // store current GPS location data in struct -void gps_storelocation(gpsStatus_t &gps_store) { - gps_store.latitude = (int32_t)(gps.location.lat() * 1e6); - gps_store.longitude = (int32_t)(gps.location.lng() * 1e6); - gps_store.satellites = (uint8_t)gps.satellites.value(); - gps_store.hdop = (uint16_t)gps.hdop.value(); - gps_store.altitude = (int16_t)gps.altitude.meters(); +void gps_storelocation(gpsStatus_t *gps_store) { + if (gps.location.isUpdated() && gps.location.isValid() && + (gps.time.age() < 1500)) { + gps_store->latitude = (int32_t)(gps.location.lat() * 1e6); + gps_store->longitude = (int32_t)(gps.location.lng() * 1e6); + gps_store->satellites = (uint8_t)gps.satellites.value(); + gps_store->hdop = (uint16_t)gps.hdop.value(); + gps_store->altitude = (int16_t)gps.altitude.meters(); + } } // store current GPS timedate in struct -void IRAM_ATTR gps_storetime(gpsStatus_t &gps_store) { +void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) { if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { // nmea telegram serial delay compensation; not sure if we need this? /* if (gps.time.age() > nmea_txDelay_ms) - gps_store.timedate.Second = gps.time.second() + 1; + gps_store->timedate.Second = gps.time.second() + 1; else - gps_store.timedate.Second = gps.time.second(); + gps_store->timedate.Second = gps.time.second(); */ - gps_store.timedate.Second = gps.time.second(); - gps_store.timedate.Minute = gps.time.minute(); - gps_store.timedate.Hour = gps.time.hour(); - gps_store.timedate.Day = gps.date.day(); - gps_store.timedate.Month = gps.date.month(); - gps_store.timedate.Year = + gps_store->timedate.Second = gps.time.second(); + gps_store->timedate.Minute = gps.time.minute(); + gps_store->timedate.Hour = gps.time.hour(); + gps_store->timedate.Day = gps.date.day(); + gps_store->timedate.Month = gps.date.month(); + gps_store->timedate.Year = CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h } else - gps_store.timedate = {0}; + gps_store->timedate = {0}; } // function to fetch current time from struct; note: this is costly -time_t get_gpstime(gpsStatus_t value) { +time_t fetch_gpsTime(gpsStatus_t value) { time_t t = timeIsValid(makeTime(value.timedate)); - - // show NMEA data in debug mode, useful for debugging GPS - ESP_LOGD( - TAG, - "GPS time: %d | GPS NMEA data: passed %d / failed: %d / with fix: %d", t, - gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); - + ESP_LOGD(TAG, "GPS time: %d", t); return t; -} // get_gpstime() +} // fetch_gpsTime() // GPS serial feed FreeRTos Task void gps_loop(void *pvParameters) { @@ -136,6 +133,11 @@ void gps_loop(void *pvParameters) { #endif } // if + // show NMEA data in verbose mode, useful for debugging GPS + ESP_LOGV(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", + gps.passedChecksum(), gps.failedChecksum(), + gps.sentencesWithFix()); + delay(2); // yield to CPU } // end of infinite loop diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index fabda2f2..86177a31 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -48,7 +48,7 @@ void irqHandler(void *pvParameters) { // gps refresh buffer? #if (HAS_GPS) if (InterruptStatus & GPS_IRQ) - gps_storelocation(gps_status); + gps_storelocation(&gps_status); #endif // are cyclic tasks due? diff --git a/src/main.cpp b/src/main.cpp index a147707f..f97ca72d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -438,6 +438,11 @@ void setup() { #warning you did not specify a time source, time will not be synched #endif + // initialize gps time +#if (HAS_GPS) + gps_storetime(&gps_status); +#endif + #if (defined HAS_IF482 || defined HAS_DCF77) ESP_LOGI(TAG, "Starting Clock Controller..."); clock_init(); diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 049e80aa..7cd1bbe0 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -18,10 +18,6 @@ const char timeSetSymbols[] = {'G', 'R', 'L', '?'}; HardwareSerial IF482(2); // use UART #2 (#1 may be in use for serial GPS) #endif -#if (HAS_GPS) -static gpsStatus_t gps_pps_status; -#endif - Ticker timesyncer; void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } @@ -32,7 +28,7 @@ time_t timeProvider(void) { #if (HAS_GPS) // fetch recent time from last NMEA record - t = get_gpstime(gps_pps_status); + t = fetch_gpsTime(gps_status); if (t) { #ifdef HAS_RTC set_rtctime(t, do_mutex); // calibrate RTC @@ -44,7 +40,7 @@ time_t timeProvider(void) { } #endif -// no GPS -> fallback to RTC time while trying lora sync +// no time from GPS -> fallback to RTC time while trying lora sync #ifdef HAS_RTC t = get_rtctime(); if (t) { @@ -123,11 +119,6 @@ void timepulse_start(void) { timerAlarmEnable(ppsIRQ); #endif -// initialize gps time -#if (HAS_GPS) - gps_storetime(gps_pps_status); -#endif - // start cyclic time sync timeSync(); // init systime by RTC or GPS or LORA timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); @@ -142,9 +133,7 @@ void IRAM_ATTR CLOCKIRQ(void) { // store recent gps time, and try to get gps time if time is not synced #if (HAS_GPS) - gps_storetime(gps_pps_status); - if (timeSource == _unsynced) - timeSync(); + gps_storetime(&gps_status); #endif // advance wall clock, if we have