From 398faf185113df730b2b19d91b4e38caf5ecca5e Mon Sep 17 00:00:00 2001 From: Fabio Ancona Date: Tue, 17 Jun 2025 09:49:04 +0200 Subject: [PATCH 01/24] Update LD2410 doc adding info of false positive Update LD2410 doc adding info of avoid false positive --- docs/source/Plugin/P159.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/Plugin/P159.rst b/docs/source/Plugin/P159.rst index 30fd97358..9469c3989 100644 --- a/docs/source/Plugin/P159.rst +++ b/docs/source/Plugin/P159.rst @@ -27,6 +27,8 @@ Description Detecting (human) presence can be achieved in several ways, like via IR detection sensors, or a light-beam that's interrupted by someone passing. But these sensors have quite some limitations, like limited sensitivity, no information about the distance, or weather a person is there but not moving. The limitations of these existing sensors are not applicable when using radar-based presence detection, and since some time, rather affordable radar human-presence detectors are available. These are available with 5 GHz, 10 GHz, 24 GHz and 60 GHz radar frequency transmitter/receiver chips. Because of the accuracy and range, achievable with 24 GHz sensors, these are quite popular, so support has been added to ESPEasy. +Some notes about "false positive" detections: based on our test and experience some false positive presence rilevations can happens. For example if the sensor is near to plant, the movement of leaves can be incorrectly translated as presence detection; also electric cables in front of the sensor can provide noise to the sensor. To avoid false positive presence detection try to leave the sensor as free from obstacles as possible. + Some examples of these sensors: From 7150f9641c0d4cb1e6c6797c635c66ee6a1b5ced Mon Sep 17 00:00:00 2001 From: Fabio Ancona Date: Tue, 17 Jun 2025 10:13:00 +0200 Subject: [PATCH 02/24] Update P159.rst Update wrong translation --- docs/source/Plugin/P159.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/Plugin/P159.rst b/docs/source/Plugin/P159.rst index 9469c3989..a79975208 100644 --- a/docs/source/Plugin/P159.rst +++ b/docs/source/Plugin/P159.rst @@ -27,7 +27,7 @@ Description Detecting (human) presence can be achieved in several ways, like via IR detection sensors, or a light-beam that's interrupted by someone passing. But these sensors have quite some limitations, like limited sensitivity, no information about the distance, or weather a person is there but not moving. The limitations of these existing sensors are not applicable when using radar-based presence detection, and since some time, rather affordable radar human-presence detectors are available. These are available with 5 GHz, 10 GHz, 24 GHz and 60 GHz radar frequency transmitter/receiver chips. Because of the accuracy and range, achievable with 24 GHz sensors, these are quite popular, so support has been added to ESPEasy. -Some notes about "false positive" detections: based on our test and experience some false positive presence rilevations can happens. For example if the sensor is near to plant, the movement of leaves can be incorrectly translated as presence detection; also electric cables in front of the sensor can provide noise to the sensor. To avoid false positive presence detection try to leave the sensor as free from obstacles as possible. +Some notes about "false positive" detections: based on our test and experience some false positive presence detections can happens. For example if the sensor is near to plant, the movement of leaves can be incorrectly translated as presence detection; also electric cables in front of the sensor can provide noise to the sensor. To avoid false positive presence detection try to leave the sensor as free from obstacles as possible. Some examples of these sensors: From ab8823a80d2d7b323dfcb20e646052a5e9e00ee8 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 5 Aug 2025 22:41:26 +0200 Subject: [PATCH 03/24] [P102] Add support for PZEM-017v1 --- lib/PZEM-004T-v30-master/PZEM004Tv30.cpp | 200 ++++++++++++++++++----- lib/PZEM-004T-v30-master/PZEM004Tv30.h | 35 +++- src/_P102_PZEM004Tv3.ino | 74 ++++++--- 3 files changed, 238 insertions(+), 71 deletions(-) diff --git a/lib/PZEM-004T-v30-master/PZEM004Tv30.cpp b/lib/PZEM-004T-v30-master/PZEM004Tv30.cpp index fd834487f..13c500f40 100644 --- a/lib/PZEM-004T-v30-master/PZEM004Tv30.cpp +++ b/lib/PZEM-004T-v30-master/PZEM004Tv30.cpp @@ -14,6 +14,10 @@ #define REG_PF 0x0008 #define REG_ALARM 0x0009 +#define REG_CURRENT 0x0001 +#define REG_HVALARM 0x0006 +#define REG_LVALARM 0x0007 + #define CMD_RHR 0x03 #define CMD_RIR 0X04 #define CMD_WSR 0x06 @@ -24,6 +28,9 @@ #define WREG_ALARM_THR 0x0001 #define WREG_ADDR 0x0002 +#define WREG_HV_ALARM_THR 0x0000 +#define WREG_LV_ALARM_THR 0x0001 + #define UPDATE_TIME 200 #define RESPONSE_SIZE 32 @@ -84,6 +91,23 @@ PZEM004Tv30::~PZEM004Tv30() // delete this->_serial; } + +void PZEM004Tv30::setModel(PZEM_model model) { + if (model == _model) { + return; + } + _model = model; + switch (_model) { + case PZEM_model::PZEM004Tv30: + _expectedResponse = PZEM004Tv30_EXPECTED_RESPONSE; + _requestRegisters = PZEM004Tv30_REQUEST_REGISTERS; + break; + case PZEM_model::PZEM017Tv1: + _expectedResponse = PZEM017v1_EXPECTED_RESPONSE; + _requestRegisters = PZEM017v1_REQUEST_REGISTERS; + break; + } +} /*! * PZEM004Tv30::voltage * * Get line voltage in Volts * * @return current L-N volage*/ @@ -222,28 +246,97 @@ uint8_t PZEM004Tv30::getAddress() * Set power alarm threshold in watts * * @param[in] watts Alamr theshold * * @return success*/ -bool PZEM004Tv30::setPowerAlarm(uint16_t watts) -{ - if (watts > 25000){ // Sanitych check - watts = 25000; - } +// bool PZEM004Tv30::setPowerAlarm(uint16_t watts) +// { +// if (watts > 25000){ // Sanitych check +// watts = 25000; +// } - // Write the watts threshold to the Alarm register - if(!sendCmd8(CMD_WSR, WREG_ALARM_THR, watts, true)) - return false; - return true; -} +// // Write the watts threshold to the Alarm register +// if(!sendCmd8(CMD_WSR, WREG_ALARM_THR, watts, true)) +// return false; +// return true; +// } /*! * PZEM004Tv30::getPowerAlarm * * Is the power alarm set * * * @return arlam triggerd*/ -bool PZEM004Tv30::getPowerAlarm() -{ - if(!updateValues()) // Update vales if necessary - return NAN; // Update did not work, return NAN +// bool PZEM004Tv30::getPowerAlarm() +// { +// if(!updateValues()) // Update vales if necessary +// return NAN; // Update did not work, return NAN + +// return _currentValues.alarms != 0x0000; +// } + + /*! + * PZEM004Tv30::setHighVoltAlarm + * Set HV alarm threshold in volts + * @param[in] volt Alarm theshold + * @return success */ +// bool PZEM004Tv30::setHighvoltAlarm(uint16_t volts) +// { +// if (volts < 500){ // Sanity check +// volts = 500; +// } + +// if (volts > 34999){ // Sanity check +// volts = 34999; +// } + +// // Write the volts threshold to the alarm register +// if(!sendCmd8(CMD_WSR, WREG_HV_ALARM_THR, volts, true)) +// return false; + +// return true; +// } + +/*! + * PZEM004Tv30::setLowVoltAlarm + * Set LV alarm threshold in volts + * @param[in] volt Alarm theshold + * @return success */ +// bool PZEM004Tv30::setLowvoltAlarm(uint16_t volts) +// { +// if (volts < 100){ // Sanity check +// volts = 100; +// } + +// if (volts > 34999){ // Sanity check +// volts = 34999; +// } + +// // Write the volts threshold to the alarm register +// if(!sendCmd8(CMD_WSR, WREG_LV_ALARM_THR, volts, true)) +// return false; + +// return true; +// } + +/*! + * PZEM004Tv30::isHighVoltAlarmOn GET + * Is the HV alarm set + * @return alarm triggerd*/ +// bool PZEM004Tv30::isHighvoltAlarmOn() +// { +// if(!updateValues()) // Update vales if necessary +// return NAN; // Update did not work, return NAN + +// return _currentValues.HVAlarms != 0x0000; +// } + +/*! + * PZEM004Tv30::isLowVoltAlarmOn GET + * Is the LV alarm set + * @return alarm triggerd*/ +// bool PZEM004Tv30::isLowvoltAlarmOn() +// { +// if(!updateValues()) // Update vales if necessary +// return NAN; // Update did not work, return NAN + +// return _currentValues.LVAlarms != 0x0000; +// } - return _currentValues.alarms != 0x0000; -} /*! * PZEM004Tv30::init * * initialization common to all consturctors * @@ -266,52 +359,75 @@ void PZEM004Tv30::init(uint8_t addr){ * @return success*/ bool PZEM004Tv30::updateValues() { - //static uint8_t buffer[] = {0x00, CMD_RIR, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00}; - static uint8_t response[25]; - // If we read before the update time limit, do not update if(_lastRead + UPDATE_TIME > millis()){ return true; } - // Read 10 registers starting at 0x00 (no check) - sendCmd8(CMD_RIR, 0x00, 0x0A, false); + // Read registers starting at 0x00 (no check) + sendCmd8(CMD_RIR, 0x00, _requestRegisters, false); - if(recieve(response, 25) != 25){ // Something went wrong + if(recieve(_response, _expectedResponse) != _expectedResponse){ // Something went wrong return false; } // Update the current values - _currentValues.voltage = ((uint32_t)response[3] << 8 | // Raw voltage in 0.1V - (uint32_t)response[4])/10.0; + switch(_model) { + case PZEM_model::PZEM004Tv30: + _currentValues.voltage = ((uint32_t)_response[3] << 8 | // Raw voltage in 0.1V + (uint32_t)_response[4]) / 10.0; - _currentValues.current = ((uint32_t)response[5] << 8 | // Raw current in 0.001A - (uint32_t)response[6] | - (uint32_t)response[7] << 24 | - (uint32_t)response[8] << 16) / 1000.0; + _currentValues.current = ((uint32_t)_response[5] << 8 | // Raw current in 0.001A + (uint32_t)_response[6] | + (uint32_t)_response[7] << 24 | + (uint32_t)_response[8] << 16) / 1000.0; - _currentValues.power = ((uint32_t)response[9] << 8 | // Raw power in 0.1W - (uint32_t)response[10] | - (uint32_t)response[11] << 24 | - (uint32_t)response[12] << 16) / 10.0; + _currentValues.power = ((uint32_t)_response[9] << 8 | // Raw power in 0.1W + (uint32_t)_response[10] | + (uint32_t)_response[11] << 24 | + (uint32_t)_response[12] << 16) / 10.0; - _currentValues.energy = ((uint32_t)response[13] << 8 | // Raw Energy in 1Wh - (uint32_t)response[14] | - (uint32_t)response[15] << 24 | - (uint32_t)response[16] << 16) / 1000.0; + _currentValues.energy = ((uint32_t)_response[13] << 8 | // Raw Energy in 1Wh + (uint32_t)_response[14] | + (uint32_t)_response[15] << 24 | + (uint32_t)_response[16] << 16) / 1000.0; - _currentValues.frequeny =((uint32_t)response[17] << 8 | // Raw Frequency in 0.1Hz - (uint32_t)response[18]) / 10.0; + _currentValues.frequeny =((uint32_t)_response[17] << 8 | // Raw Frequency in 0.1Hz + (uint32_t)_response[18]) / 10.0; - _currentValues.pf = ((uint32_t)response[19] << 8 | // Raw pf in 0.01 - (uint32_t)response[20])/100.0; + _currentValues.pf = ((uint32_t)_response[19] << 8 | // Raw pf in 0.01 + (uint32_t)_response[20]) / 100.0; - _currentValues.alarms = ((uint32_t)response[21] << 8 | // Raw alarm value - (uint32_t)response[22]); + _currentValues.alarms = ((uint32_t)_response[21] << 8 | // Raw alarm value + (uint32_t)_response[22]); + break; + case PZEM_model::PZEM017Tv1: + _currentValues.voltage = ((uint32_t)_response[3] << 8 | // Raw voltage in 0.01V + (uint32_t)_response[4]) / 100.0; + _currentValues.current = ((uint32_t)_response[5] << 8 | // Raw voltage in 0.01A + (uint32_t)_response[6]) / 100.0; + + _currentValues.power = ((uint32_t)_response[7] << 8 | // Raw power in 0.1W + (uint32_t)_response[8] | + (uint32_t)_response[9] << 24 | + (uint32_t)_response[10] << 16) / 10.0; + + _currentValues.energy = ((uint32_t)_response[11] << 8 | // Raw Energy in 1Wh + (uint32_t)_response[12] | + (uint32_t)_response[13] << 24 | + (uint32_t)_response[14] << 16) / 1000.0; + + _currentValues.HVAlarms = ((uint32_t)_response[15] << 8 | // Raw alarm value + (uint32_t)_response[16]); + + _currentValues.LVAlarms = ((uint32_t)_response[17] << 8 | // Raw alarm value + (uint32_t)_response[18]); + break; + } // Record current time as _lastRead _lastRead = millis(); diff --git a/lib/PZEM-004T-v30-master/PZEM004Tv30.h b/lib/PZEM-004T-v30-master/PZEM004Tv30.h index 6579b0418..c5a65e9c3 100644 --- a/lib/PZEM-004T-v30-master/PZEM004Tv30.h +++ b/lib/PZEM-004T-v30-master/PZEM004Tv30.h @@ -28,9 +28,20 @@ #include #endif +#define PZEM004Tv30_EXPECTED_RESPONSE 25 +#define PZEM004Tv30_REQUEST_REGISTERS 10 + +#define PZEM017v1_EXPECTED_RESPONSE 21 +#define PZEM017v1_REQUEST_REGISTERS 8 #define PZEM_DEFAULT_ADDR 0xF8 +#define PZEM_MAX_EXPECTED_RESPONSE 25 // PZEM004v30 needs this buffer size, adjust for models that need a bigger buffer + +enum class PZEM_model : uint8_t { + PZEM004Tv30 = 0, // Buffer size 25, request 10 registers + PZEM017Tv1 = 1, // Buffer size 21, request 8 registers +}; class PZEM004Tv30 { @@ -40,6 +51,7 @@ public: #endif ~PZEM004Tv30(); + void setModel(PZEM_model model); // Sets some communication buffer params float voltage(); float current(); @@ -52,8 +64,14 @@ public: bool setAddress(uint8_t addr); uint8_t getAddress(); - bool setPowerAlarm(uint16_t watts); - bool getPowerAlarm(); + // Unused methods: + // bool setPowerAlarm(uint16_t watts); + // bool getPowerAlarm(); + + // bool setHighvoltAlarm(uint16_t volts); //moja uprava + // bool setLowvoltAlarm(uint16_t volts); //moja uprava + // bool isHighvoltAlarmOn(); //upravil som + // bool isLowvoltAlarmOn(); //upravil som bool resetEnergy(); void init(uint8_t addr); // Init common to all constructors @@ -64,15 +82,22 @@ private: bool _isSoft; // Is serial interface software uint8_t _addr; // Device address + PZEM_model _model = PZEM_model::PZEM004Tv30; // Current default + + uint8_t _response[PZEM_MAX_EXPECTED_RESPONSE]; + uint8_t _expectedResponse = PZEM004Tv30_EXPECTED_RESPONSE; + uint8_t _requestRegisters = PZEM004Tv30_REQUEST_REGISTERS; struct { float voltage; float current; float power; float energy; - float frequeny; - float pf; - uint16_t alarms; + float frequeny; // PZEM004 + float pf; // PZEM004 + uint16_t alarms; // PZEM004 + uint16_t HVAlarms; //upravil som PZEM017 + uint16_t LVAlarms; //upravil sOM PZEM017 } _currentValues; // Measured values uint64_t _lastRead; // Last time values were updated diff --git a/src/_P102_PZEM004Tv3.ino b/src/_P102_PZEM004Tv3.ino index 545d5471e..a2fd17e5e 100644 --- a/src/_P102_PZEM004Tv3.ino +++ b/src/_P102_PZEM004Tv3.ino @@ -8,6 +8,8 @@ // /** Changelog: + * 2025-08-05 tonhuisman: Add support for PZEM-017v1 from a forum suggestion: + * https://www.letscontrolit.com/forum/viewtopic.php?p=74069#p74064 * 2025-01-17 tonhuisman: Implement support for MQTT AutoDiscovery (partially) * 2025-01-12 tonhuisman: Add support for MQTT AutoDiscovery (not supported yet for PZEM00x) */ @@ -21,7 +23,7 @@ # define PLUGIN_102 # define PLUGIN_ID_102 102 # define PLUGIN_102_DEBUG true // activate extra log info in the debug -# define PLUGIN_NAME_102 "Energy (AC) - PZEM-004Tv30-Multiple" +# define PLUGIN_NAME_102 "Energy (AC) - PZEM-004Tv30 / PZEM-017v1" # define P102_PZEM_mode PCONFIG(1) // 0=read value ; 1=reset energy; 2=programm address # define P102_PZEM_ADDR PCONFIG(2) @@ -32,6 +34,7 @@ # define P102_QUERY4 PCONFIG(6) # define P102_PZEM_FIRST PCONFIG(7) # define P102_PZEM_ATTEMPT PCONFIG_LONG(1) +# define P102_PZEM_TYPE PCONFIG_LONG(0) # define P102_PZEM_mode_DFLT 0 // Read value # define P102_QUERY1_DFLT 0 // Voltage (V) @@ -44,6 +47,10 @@ # define P102_PZEM_MAX_ATTEMPT 3 // Number of tentative before declaring NAN value +# define P102_PZEM004_VALUE_COUNT 6 +# define P102_PZEM017_VALUE_COUNT 4 + + PZEM004Tv30 * P102_PZEM_sensor = nullptr; boolean Plugin_102_init = false; @@ -56,7 +63,7 @@ const __FlashStringHelper* p102_getQueryString(uint8_t query); boolean Plugin_102(uint8_t function, struct EventStruct *event, String& string) { - boolean success = false; + bool success = false; switch (function) { @@ -126,6 +133,7 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even case PLUGIN_WEBFORM_SHOW_CONFIG: { string += serialHelper_getSerialTypeLabel(event); + string += strformat(F("
addr: 0x%02x"), P102_PZEM_ADDR); // Show modbus address success = true; break; } @@ -134,14 +142,17 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even { // To select the data in the 4 fields. const __FlashStringHelper *options[P102_NR_OUTPUT_OPTIONS]; + const uint8_t nrOptions = PZEM_model::PZEM004Tv30 == static_cast(P102_PZEM_TYPE) + ? P102_PZEM004_VALUE_COUNT + : P102_PZEM017_VALUE_COUNT; - for (uint8_t i = 0; i < P102_NR_OUTPUT_OPTIONS; ++i) { + for (uint8_t i = 0; i < nrOptions; ++i) { options[i] = p102_getQueryString(i); } for (uint8_t i = 0; i < P102_NR_OUTPUT_VALUES; ++i) { const uint8_t pconfigIndex = i + P102_QUERY1_CONFIG_POS; - sensorTypeHelper_loadOutputSelector(event, pconfigIndex, i, P102_NR_OUTPUT_OPTIONS, options); + sensorTypeHelper_loadOutputSelector(event, pconfigIndex, i, nrOptions, options); } success = true; @@ -149,7 +160,19 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even break; } - case PLUGIN_WEBFORM_LOAD: { + case PLUGIN_WEBFORM_LOAD: + { + { + const __FlashStringHelper*pzemModels[] = { + F("PZEM004Tv30"), + F("PZEM017v1"), + }; + constexpr int pzemCount = NR_ELEMENTS(pzemModels); + FormSelectorOptions selector(pzemCount, pzemModels); + selector.reloadonchange = true; + selector.addFormSelector(F("PZEM Model"), F("pztype"), P102_PZEM_TYPE); + } + if (P102_PZEM_sensor == nullptr) { P102_PZEM_FIRST = event->TaskIndex; // To detect if first PZEM or not } @@ -168,8 +191,8 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even if (P102_PZEM_mode == 2) { - addHtml(F("
When programming an address, only one PZEMv30 must be connected. " - "Otherwise, all connected PZEMv30s will get the same address, which would cause a conflict during reading.
")); + addHtml(F("
When programming an address, only one PZEM must be connected. " + "Otherwise, all connected PZEMs will get the same address, which would cause a conflict during reading.
")); { const __FlashStringHelper *options_confirm[] = { F("NO"), F("YES") }; constexpr size_t optionCount = NR_ELEMENTS(options_confirm); @@ -182,7 +205,7 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even else { addFormNumericBox(F("Address of PZEM"), F("PZEM_addr"), P102_PZEM_ADDR, 0, 247); - addHtml(F(" Address 0 allows to communicate with any single PZEMv30 whatever its address")); + addHtml(F(" Address 0 allows to communicate with any single PZEM whatever its address")); } if (P102_PZEM_ADDR_SET == 3) // If address programming done @@ -216,7 +239,8 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even break; } - case PLUGIN_WEBFORM_SAVE: { + case PLUGIN_WEBFORM_SAVE: + { serialHelper_webformSave(event); // Save output selector parameters. @@ -225,6 +249,7 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even const uint8_t choice = PCONFIG(pconfigIndex); sensorTypeHelper_saveOutputSelector(event, pconfigIndex, i, p102_getQueryString(choice)); } + P102_PZEM_TYPE = getFormItemInt(F("pztype")); P102_PZEM_mode = getFormItemInt(F("PZEM_mode")); P102_PZEM_ADDR = getFormItemInt(F("PZEM_addr")); P102_PZEM_ADDR_SET = getFormItemInt(F("PZEM_addr_set")); @@ -346,13 +371,18 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even // FIXME TD-er: Calling these functions is probably done within the 200 msec timeout used in the library. // If not, this should be cached in a task data struct. - string += LoRa_addFloat(P102_PZEM_sensor->voltage(), PackedData_int16_1e1); - string += LoRa_addFloat(P102_PZEM_sensor->current(), PackedData_int32_1e3); - string += LoRa_addFloat(P102_PZEM_sensor->power(), PackedData_int32_1e1); - string += LoRa_addFloat(P102_PZEM_sensor->energy(), PackedData_int32_1e1); - string += LoRa_addFloat(P102_PZEM_sensor->pf(), PackedData_uint16_1e2); - string += LoRa_addFloat(P102_PZEM_sensor->frequency() - 40, PackedData_uint8_1e1); - event->Par1 = 6; // valuecount + string += LoRa_addFloat(P102_PZEM_sensor->voltage(), PackedData_int16_1e1); + string += LoRa_addFloat(P102_PZEM_sensor->current(), PackedData_int32_1e3); + string += LoRa_addFloat(P102_PZEM_sensor->power(), PackedData_int32_1e1); + string += LoRa_addFloat(P102_PZEM_sensor->energy(), PackedData_int32_1e1); + + if (PZEM_model::PZEM004Tv30 == static_cast(P102_PZEM_TYPE)) { + string += LoRa_addFloat(P102_PZEM_sensor->pf(), PackedData_uint16_1e2); + string += LoRa_addFloat(P102_PZEM_sensor->frequency() - 40, PackedData_uint8_1e1); + event->Par1 = P102_PZEM004_VALUE_COUNT; // valuecount + } else { + event->Par1 = P102_PZEM017_VALUE_COUNT; // valuecount + } success = true; break; @@ -366,14 +396,10 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even { const String command = parseString(string, 1); - if ((equals(command, F("resetenergy"))) && (P102_PZEM_FIRST == event->TaskIndex)) - { - if ((event->Par1 >= 0) && (event->Par1 <= 247)) - { - P102_PZEM_sensor->init(event->Par1); - P102_PZEM_sensor->resetEnergy(); - success = true; - } + if (equals(command, F("resetenergy")) && (event->Par1 >= 0) && (event->Par1 <= 247)) { + P102_PZEM_sensor->init(event->Par1); + P102_PZEM_sensor->resetEnergy(); + success = true; } } From de5acb32656a2bd9681da6d4077d0862a3781d7e Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Wed, 6 Aug 2025 15:51:21 +0200 Subject: [PATCH 04/24] [P102] UI updates and corrections --- src/_P102_PZEM004Tv3.ino | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/_P102_PZEM004Tv3.ino b/src/_P102_PZEM004Tv3.ino index a2fd17e5e..22f431a69 100644 --- a/src/_P102_PZEM004Tv3.ino +++ b/src/_P102_PZEM004Tv3.ino @@ -3,11 +3,12 @@ #ifdef USES_P102 // ####################################################################################################### -// #################################### Plugin 102: PZEM004T v30 with modbus mgt########################## +// ######################## Plugin 102: PZEM004Tv30 / PZEM-017v1 with modbus mgt ######################## // ####################################################################################################### // /** Changelog: + * 2025-08-06 tonhuisman: Change plugin name to "Energy - PZEM-004T (AC) / PZEM-017 (DC)" * 2025-08-05 tonhuisman: Add support for PZEM-017v1 from a forum suggestion: * https://www.letscontrolit.com/forum/viewtopic.php?p=74069#p74064 * 2025-01-17 tonhuisman: Implement support for MQTT AutoDiscovery (partially) @@ -23,7 +24,7 @@ # define PLUGIN_102 # define PLUGIN_ID_102 102 # define PLUGIN_102_DEBUG true // activate extra log info in the debug -# define PLUGIN_NAME_102 "Energy (AC) - PZEM-004Tv30 / PZEM-017v1" +# define PLUGIN_NAME_102 "Energy - PZEM-004T (AC) / PZEM-017 (DC)" # define P102_PZEM_mode PCONFIG(1) // 0=read value ; 1=reset energy; 2=programm address # define P102_PZEM_ADDR PCONFIG(2) @@ -164,8 +165,8 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even { { const __FlashStringHelper*pzemModels[] = { - F("PZEM004Tv30"), - F("PZEM017v1"), + F("PZEM-004Tv30 (AC)"), + F("PZEM-017v1 (DC)"), }; constexpr int pzemCount = NR_ELEMENTS(pzemModels); FormSelectorOptions selector(pzemCount, pzemModels); @@ -183,7 +184,7 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even "don't use HW serial (or invert Tx and Rx to configure as SW serial).")); addFormSubHeader(F("PZEM actions")); { - const __FlashStringHelper *options_model[] = { F("Read_value"), F("Reset_Energy"), F("Program_adress") }; + const __FlashStringHelper *options_model[] = { F("Read value"), F("Reset Energy"), F("Program address") }; constexpr size_t optionCount = NR_ELEMENTS(options_model); const FormSelectorOptions selector(optionCount, options_model); selector.addFormSelector(F("PZEM Mode"), F("PZEM_mode"), P102_PZEM_mode); @@ -204,13 +205,13 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even } else { - addFormNumericBox(F("Address of PZEM"), F("PZEM_addr"), P102_PZEM_ADDR, 0, 247); - addHtml(F(" Address 0 allows to communicate with any single PZEM whatever its address")); + addFormNumericBox(F("Address of PZEM"), F("PZEM_addr"), P102_PZEM_ADDR, 0x00, 0xF7); + addHtml(F(" Address 0 allows to communicate with any single PZEM whatever its address")); } if (P102_PZEM_ADDR_SET == 3) // If address programming done { - addHtml(F("
Address programming done !
")); + addHtml(F("
Address programming done !
")); P102_PZEM_ADDR_SET = 0; // Reset programming confirmation } } @@ -218,23 +219,23 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even { addFormSubHeader(F("PZEM actions")); { - const __FlashStringHelper *options_model[] = { F("Read_value"), F("Reset_Energy") }; + const __FlashStringHelper *options_model[] = { F("Read value"), F("Reset Energy") }; constexpr size_t optionCount = NR_ELEMENTS(options_model); const FormSelectorOptions selector(optionCount, options_model); selector.addFormSelector(F("PZEM Mode"), F("PZEM_mode"), P102_PZEM_mode); } - addHtml(F(" Tx/Rx Pins config disabled: Configuration is available in the first PZEM plugin.
")); - addFormNumericBox(F("Address of PZEM"), F("PZEM_addr"), P102_PZEM_ADDR, 1, 247); + addHtml(F(" Tx/Rx Pins config ignored: Configuration is available in the first PZEM plugin.
")); + addFormNumericBox(F("Address of PZEM"), F("PZEM_addr"), P102_PZEM_ADDR, 0x01, 0xF7); } - addHtml(F("

Reset energy can be done also by: http://*espeasyip*/control?cmd=resetenergy,*PZEM address*")); - if (P102_PZEM_ADDR_SET == 4) { addHtml(F("
Energy reset on current PZEM !
")); P102_PZEM_ADDR_SET = 0; // Reset programming confirmation } + addFormNote(F("Reset Energy can also be done by: http://*espeasyip*/control?cmd=resetenergy,*PZEM address*")); + success = true; break; } @@ -357,10 +358,14 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even # if FEATURE_PACKED_RAW_DATA case PLUGIN_GET_PACKED_RAW_DATA: { - // Matching JS code: + // Matching JS code for PZEM-004T: // return decode(bytes, [header, int16_1e1, int32_1e3, int32_1e1, int32_1e1, uint16_1e2, uint8_1e1], // ['header', 'voltage', 'current', 'power', 'energy', 'powerfactor', 'frequency']); // + // Matching JS code for PZEM-017: + // return decode(bytes, [header, int16_1e1, int32_1e3, int32_1e1, int32_1e1], + // ['header', 'voltage', 'current', 'power', 'energy']); + // // Resolutions: // Voltage: 0.1V => int16_1e1 (range 80-260V) // Current: 0.001A => int32_1e3 @@ -417,7 +422,7 @@ const __FlashStringHelper* p102_getQueryString(uint8_t query) { case 2: return F("Power_W"); case 3: return F("Energy_kWh"); case 4: return F("Power_Factor_cosphi"); - case 5: return F("Frequency Hz"); + case 5: return F("Frequency_Hz"); } return F(""); } From 98db7e78bf334e39913cf9447ef15a6012a83b1d Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Wed, 6 Aug 2025 15:51:40 +0200 Subject: [PATCH 05/24] [P102] Add documentation --- docs/source/Plugin/P102.rst | 217 +++++++++++++++++- .../Plugin/P102_DeviceConfiguration.png | Bin 0 -> 83858 bytes docs/source/Plugin/P102_ProgramAddress.png | Bin 0 -> 20505 bytes docs/source/Plugin/P102_ResetEnergyDone.png | Bin 0 -> 13403 bytes .../Plugin/P102_SecondConfiguration.png | Bin 0 -> 18325 bytes docs/source/Plugin/P102_commands.repl | 15 ++ docs/source/Plugin/_plugin_categories.repl | 4 +- .../Plugin/_plugin_substitutions_p10x.repl | 10 +- 8 files changed, 238 insertions(+), 8 deletions(-) create mode 100644 docs/source/Plugin/P102_DeviceConfiguration.png create mode 100644 docs/source/Plugin/P102_ProgramAddress.png create mode 100644 docs/source/Plugin/P102_ResetEnergyDone.png create mode 100644 docs/source/Plugin/P102_SecondConfiguration.png create mode 100644 docs/source/Plugin/P102_commands.repl diff --git a/docs/source/Plugin/P102.rst b/docs/source/Plugin/P102.rst index 12030e886..9d93c1dfb 100644 --- a/docs/source/Plugin/P102.rst +++ b/docs/source/Plugin/P102.rst @@ -24,7 +24,7 @@ Used libraries: |P102_usedlibraries| Description ----------- -PZEM-004T V3.0 or Version 3.0 is the upgraded version to replace the old PZEM004T V1.0. +PZEM-004T (AC) V3.0 or Version 3.0 is the upgraded version to replace the old PZEM004T V1.0. The old version has been sold out in most of the online store and is no longer being produced. Improvements over V1: @@ -99,18 +99,231 @@ Active Energy * Resolution: 1Wh * Measurement accuracy: 0.5% +Description +----------- + +PZEM-017 v1.0/v2.0 (DC) For measuring DC loads. When the voltage is below 7V, an independent (**not from PC USB port!**) USB powersupply should be used on the USB input connector. + +Specifications +-------------- + +Voltage +^^^^^^^ + +* Measuring range: 0.05 - 300V +* Resolution: 0.01V +* Measurement accuracy: 1% + +Current +^^^^^^^ + +* Measuring range: + + * 0.02 - 50/100/200/300A(Depending on shunt) + +* Resolution: 0.01A + +* Measurement accuracy: 1% + + +Active power +^^^^^^^^^^^^ + +* Measuring range: + + * 0.2 - 90kW(Depending on shunt) + +* Starting measure power: 0.2W +* Resolution: 0.1W +* Measurement accuracy: 1% + + +Active Energy +^^^^^^^^^^^^^ + +* Measuring range: 0 - 9999.99kWh +* Resolution: 1Wh +* Measurement accuracy: 1% + +Installation and configuration +------------------------------ + +When installing multiple PZEM devices on a single ESP unit, some specific order of configuration is required to be able to correctly configure a second, third, etc. PZEM. + +This is described below, in the :cyan:`Installing multiple PZEM units on a single ESP` paragraph. + +Configuration +------------- + +.. image:: P102_DeviceConfiguration.png + +Task Settings +^^^^^^^^^^^^^ + +* **Name**: Required by ESPEasy, must be unique among the list of available devices/tasks. + +* **Enabled**: The device can be disabled or enabled. When not enabled the device should not use any resources. + Sensor ^^^^^^ See: :ref:`SerialHelper_page` +Device Settings +^^^^^^^^^^^^^^^ + +* **PZEM Model**: Select the PZEM model that is to be handled by this task. (For changing the Address the model doesn't matter as they use the same command.) + +Available options: + +* *PZEM-004Tv30 (AC)*: The AC model, and default setting. +* *PZEM-017v1 (DC)*: The DC model. Also compatible with later v2/2.0 models. + +For reading the correct values from a PZEM-017, that Model *must* be selected as it uses a different data format to fetch the results. + +PZEM Actions +^^^^^^^^^^^^ + +* **PZEM Mode**: By default, the ``Read value`` option is selected. + +Available options: + +* *Read value*: Normal operating mode, for reading the configured values from the PZEM. +* *Reset Energy*: For resetting the counted total energy, this option can be selected. See below for a description. +* *Program address*: Only available on the *first* PZEM device, for changing the PZEM unit MODBUS address, as described below. + +| + +* **Address of PZEM**: Set to the address of the PZEM unit to be used. When only a single device is connected, can be set to 0, as a sort of 'universal' address. + +Available address range for the *first* PZEM device: 0 .. 247, on subsequent PZEM devices: 1 .. 247. + +Output Configuration +^^^^^^^^^^^^^^^^^^^^ + +For all 4 available Values slots for this task, a value to use can be selected here. The available options depend om the **PZEM Model** setting: + +* *Voltage_V* +* *Current_A* +* *Power_W* +* *Energy_kWh* +* *Power_Factor_cosphi*: for ``PZEM-004Tv30 (AC)`` only. +* *Frequency_Hz*: for ``PZEM-004Tv30 (AC)`` only. + .. include:: DataAcquisition.repl +* **Interval**: By default, Interval will be set to 60 sec for this plugin. It is the frequency used to read sensor values and send these to any Controllers configured for this device. + +Values +^^^^^^ + +The measured values are configured above, and get their names based on the selection made there. + +For a complete description of all available columns see the `Plugin - Values <_Plugin.html#values>`_ section. + +| + + .. Events .. ~~~~~~ .. .. include:: P102_events.repl +Resetting the Energy counter +---------------------------- + +For resetting the counted Energy value in the PZEM unit, there are 2 methods: + +1. Use the *Reset Energy* **PZEM Mode** setting. +2. Send the command ``resetenergy,`` to the ESP unit. This can be done via the Command entry on the Tools page, from Rules, or via a url command as shown in the configuration page. + +Use the *Reset Energy* **PZEM Mode** setting +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For resetting the incrementing Energy counter in the PZEM unit, this PZEM Mode option can be used. + +* Set **PZEM Mode** to ``Reset Energy``, and :cyan:`Submit` the page. + +The command will be executed immediately, and afterward the status will shown: + +.. image:: P102_ResetEnergyDone.png + +The blue message showing that the command was sent. The **PZEM Mode** is already reset to ``Read value``. + +Installing multiple PZEM units on a single ESP +---------------------------------------------- + +Configuring separate MODBUS addresses on each device +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To uniquely identify each PZEM unit on the bus, it has to be configured to use a unique address. The range of these addresses is 1 .. 247. + +* Add the, numerically, first PZEM task, f.e. in Devices slot 1. + +* Configure the serial port, and on ESP32 also the GPIO pins, to be used, enable the plugin, and connect a single PZEM to the RS485 converter. When using ``HW Serial0``, the Serial Console Settings, on the Tools/Advanced page, have to be disabled to avoid issues with his port. + +* Set **PZEM Mode** to ``Program address`` and :cyan:`Submit` the page. + +.. image:: P102_ProgramAddress.png + +Fill the desired address in the **Address of PZEM** field, change the **Confirm address programming ?** field to ``YES``, and again :cyan:`Submit` the page. + +When successful, a message :green:`Address programming done !` is displayed, and the **PZEM Mode** is set to the default ``Read value`` setting. + +* Disconnect the PZEM unit from the RS485 bus, connect the next PZEM unit, and repeat above steps, using a diferent **Address of PZEM** value, for all units to be connected. + +N.B.: The last set Address of PZEM will be kept in the configuration, but can be changed to the desired first PZEM unit. + +N.B.2: To correctly store the **PZEM Mode** setting, the configuration should be saved once more, using the :cyan:`Submit` button! + +Configuring a secondary PZEM unit +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first PZEM unit can be configured as shown above in the generic Configuration paragraph. Once thats completed, with the correct, unique, MODBUS Address set, both in all PZEM units to connect and the task configuration for the first PZEM task, that task should be Enabled, so the next task added can detect that it will be the second (or third, etc.) device on the MODBUS chain. + +After that task is running, a new PZEM task can be added, with a task number higher than the *first* PZEM task. + +.. warning:: This is crucial for the PZEM tasks to start correctly, and in the correct order, on reboot or power-up of the ESP! + +These secondary PZEM tasks do not use the Serial configuration, as they use the same connection as the *first* PZEM task. + +.. image:: P102_SecondConfiguration.png + +Sensor +^^^^^^ + +This selector should not be used, as it is ignored. + +Device Settings +^^^^^^^^^^^^^^^ + +* **PZEM Model**: Select the PZEM model that is to be handled by this task. (Changing the selection will save the new setting and reload the page.) + +For reading the correct values from a PZEM-017, that Model *must* be selected as it uses a different data format to fetch the results. + +PZEM Actions +^^^^^^^^^^^^ + +* **PZEM Mode**: By default, the ``Read value`` option is selected. + +Available options: + +* *Read value*: Normal operating mode, for reading the configured values from the PZEM. +* *Reset Energy*: For resetting the counted total energy, this option can be selected. See above for a description. + +* **Address of PZEM**: Set to the address of the PZEM unit to be used. + +Available address range: 1 .. 247. + +When using the same address as the *first* PZEM task, and the **PZEM Model** connected is a ``PZEM-004Tv30 (AC)``, the extra values ``Power_Factor_cosphi`` and ``Frequency_Hz`` can be made available in a task, for sending to a controller. + +| + +Commands +-------- + +.. include:: P102_commands.repl + Change log @@ -119,4 +332,6 @@ Change log .. versionchanged:: 2.0 ... + |added| 2025-08-06: Support for PZEM-017, updated documentation. + |added| 2020-04-25 diff --git a/docs/source/Plugin/P102_DeviceConfiguration.png b/docs/source/Plugin/P102_DeviceConfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..95b8c81d4a8352653b57ecab60a43cd9fd657275 GIT binary patch literal 83858 zcmeFZcUV)|+b)dLoB@?lnhkJNdWp0keN+$usiC)s5Q+ql-a$tJ0fC_egir>MAT5C) zgdU}cbO9+LK%_=$fY3vdZ^zO3y}$1|-?`rNz3=(wTxVZ;C7Z0Bz4ltqdYuGBOufTC|t1%LI`Q_mq zD_=IYQ|+w(#}E>yE&zYD_0zKS(}ejt`nWyxbMx|Kb9D9b@_?OWzXq1Nc3n#LnykVl z$xAZw%CfS`vPvh}Z+-dr(p{K~gJbX|3pYP$v|_s65tmwx-Lr>$QayYL%0?q|+( zproAR(>&k#CBHknc0!KBdfPT1>bbY1UQFBjJWQT!k=yH~hn2PrO{&w?$=ho5sdZo6 zcdT)_>m(t-dSzQN0UrZiuAPH%u})Ks|5r{4hozXq(o2`W9&g+aXeEu^xi1tw0F;7*y*OpU>@&%PY*HI?dN5Kz4A;(~IO;E)iE=&Ctyx<_=uhoHSBss0f89^-EIT;qc}tHV^!FI~ zkTeOV#YSKuEl62&f|SL4?|gS|h^0$z587`zLw4bQ>Fca&kFJWj5E#TDFcL9ZIGU!f zGx*Wu`qw9ztUzBwDiNiCFy~;>gds1(UBc z{qMvi;1fJ6;aQw3Tq7f3yf6tnx({KU2 zG*tqrEM#nxCfT@97D^m%QjPVz)x)iNFt3-}vGEFiKAY4mft&^Y`86tAD1GfTJOa3_ zEDVCOw6@jyc)~_rER&+A>s1qvkv%VMAxnx+vx%7u6cSo7vviiVN6W{J;jh_ys-;li z-Iz}7P2H~@0E+-qU4Q0kB#n6Y(C$ubK2{jAlRAY3fT|TNxEO`l@m+$ zSz(%GV#OK-KrtD7CqE8(SW`xCp8oq#GGNUNLLbUA#j7ac${U!Ah|B)fE5#EjT#gbSgQ|E$-GFg2L&ih)6^~P4oRRWJ z2Z~{T@tH^RoVhIsF*pz_iPXEbYPdZ z*3HK!x?zg8iQ2iX3sZ$iMYe~~ASNjMvg+aZg|^6}_n@mk4wW9rVQ3aRO%byh43DO> zK=5&>gHKFz&;~c?&1;o4HT=7?#~*be^hj2<6q@2}#5mCa*VyM-oRiCs9P(at(?-Xy z_0D-Lb~XnP+BzEvzVc{M3dYg1WpLLy@vRyy)FHI2S}@&%_&M0Qwm4@GyL4;OA9>eT zY1J8r|I0dHuWS9m?hR~?{~n`Sps{jS>*svT$uVB#`n7d;_VR@*{kd}oTiqD^Y=l|?8DDlN;lun?g?kE$ z+%ME|`#4bC%CWGXw^AA$vD%SQSagi75?#}cI*Orv#=j3J?n@+{@=|}~ z>{+-1{qfI;&xwLbWT=My#82aFPbh6%`C+X#C3}W5Ro3gJDP}#Wsj0*9bZJybn9AyU zqL`mg$6GjqUglJ=vn+7s%G4aR!Beg*UBAO|@#w7jcG&Zvaz%28-TYaeT=LLMrW%u2~*vQBZ?10(g-u4rn9f;uz?t97 zh5Y=)^YBfD8S=f9d>*hs3_JTU9bei97rNBmHA)9s_$PrHdR@iNQ) zcXl0A@IAM*^g^?3v7WwBFta4TMMyR|h29XkF)^7G1H&l|t&-_MLGGG_G$JZD|J3W#cbc*efLWLE0$53}mM6ljRl#W5snWZFkfyg(B3mQ$u zJ&*dpN9wB&^j_}IgM14nf*pm5JmvZ}bXgpd$osaL^MV@PKUW11WqSmh?Q;%9 zEW&#e6-Q)TKYEMEg%_!KgkYgb$%J?Pl|r!ASN`ri>{U+u>^i||GnQk(GX{3)h=8PHCUdvMX16vZTs^THJ*D}z&8*(@> zWvs@m^3tHb+kibGjrmE0eU{7lMV*?tA=P!=jq$ln@Ry|AV2I02z#TgFVM}Po>gc~i z-ycDom`~hgnJ?kpd6z!^WXLGQrx2xcHXhd64z+pg?#k7-7At*x;f@`LTV7pbh(VZ}mnGq_IykCq&n%h4uByQVU2 zQj}6;=0Qo>@roa?)m^E6`RrV?)D-;#QKWh;OAX{W%~3?Zc5UtHKzPLDehnY8050wk zNXV3PNhx@h=5^2qN|Z*Hno@sayLWyCq2Da=EIs^^on_cxePNFbx>1i)-@=mG!tZZ{ zkIP}j%91TgMRqa_vW1Fun!a`5|Gv*_Gk3tS z`kG384iE1Wi@%&QAfx?(54RP1Pz3MdEcC=!{8FgMa+evnFR1yCi2Tq$ay6_d0@^Y0 zd6VkP6~r?HGW;G?XpZx_O^08Rfy8OZOMkEyDHLuFB^#r{c6sl&ExMDufC$@`)#zjlfU1!-G1vIaPvb>3-hg_UDAlUZJV%Y zGbf}zb%+rvtbzIL1X6!2dD2}E@mceA1k{rfJ;h^qsV6;qBS2y0wO>6UbviqU&?n>E z2xVVL@~@iQ6vI&pcf`|7eV;_Njr$|J5|EL7^2Ons|D&2Qij z%$LAr{_Yu5 z>c!P=zAJTqg7^zO&WV=Z6|NMf2*2D|4eD;0#XZM7*}PqZGFvI_4W3wIp>^I=1!k(?6yL?nz3Y7QupBi z^A_oVJ_Bl+$rCCXY&ZasHW*KW8NYwY5^oTGIMHo4W76a^i_WW*t=QpsgfPP(8qMJ{ zxBdNx?IhwjH;0rE((V|!#^-3Vg1oTN6HFTxJViPjKiCjd4^tES^W7p4j-*t#*St=WXk7ST z2L#w2-C{8W7syqD2ls;39LcSDAyXg`ts(5u(i1nvTSpSl^md_OoC^orn;%%X;C2WZ z-*moZtqK>-oZS)p8M?cH5h*gs28HeyetF!{;U?OXu{pvqwri(ZIek?wvz-#{72c!L zdMhc114{oK+Gf$hC~nIOna^kw4Bj7Wjof&zyZ^s|HUZ*DZ%-G;p_-AUoCOI$~zP0_gNL3b`p{t*&_L!|+?WxDu z9(XTvn%FwQHhU=P|iF#=JW^0nkake*IDEJ>Ijl)54He}8D>&42q z%{s-|*bKlhF8H(M_@Fs1mD9;{>C2Wser=i$Ka;Hg4EqZk8>>YXY`7z*qOt}tuvBfq zJ7=$S!NBF6m6M3AEv!k!qLnZ_GEm$`kXQ=Y8N=iV>+b}4scAVC769n!FH5l9bcMms zxVGttqxX;L&6VK~Q|d#NBG|5rOCa=%2cji59rfK_zkcu5QykzS3tq=jWBd9K%UxJ=MJ28MpQ%nPlzp)GeRKqtv4QDn4$yO+0KT&_Yl ziqLdeWNzkUMir250_ZTL0E=YP>p{^UDy^Ce8RC_eSwzUrU!}iWbKj!gbW=BxBTZKJ zKX=xG6t6ZkA-Sy{p1Ifn7f0y$I|~{5D3~B%&|lT_P!O;J)rQ-&+U9eq1Pb`#y+D>d zKNm&vY8jW-74`V{DD_;&y+e}0x*N}NOXfgTKrF5s4^OUrXF7in9{v40=F`*)oz_n zr{23*0-2_3l-UA*(47yPL)(CBItG_Icnn4!!cyPU`B`HMn3qF@%9LdFWj8Qf<&evJ z%}ggo4C##PDT)l2R^*?gprnz`MFX>Oh4)9Lk-Q|q5vinq2Cm!^95pTF3-C$}S|%>p zwNI_f;144EdsX(rjUQ?tYvB*#@)yIi3?Z6QG9>eOgWa*fxWm4arm2`coLk<_Q&b3r9>3D0nGn{bsvJZ&$gur4s))|l0 z(FFg-x;{<6@;9JA*k4%2_ZP5!|9w&VlKZ1BD0*HM3AlW@Q)on{RM{NxVpuWcy<4^o zeqy$b0a8l!T&IqB-P1RX9F&$aQfv57p#{sL}aBjVbkIQUXhS<60!N*;*Gun!Sa z4+FlSRTO#e$z)Tooa$yf*UrfIo+Vt#bAK*dn)0WX7AyhIY}0{*?Ge`=b zlFs*MD^&-SE|C~$K~9#Z2Ef9HGECKa?MNosnE&_ZcoDa;&=Jy&QRV`=4 zq~lQU^TOxJZJaISlAvVPm9nfW6!?#BR9q|BN_6Wh6B~$1!e}*Om zm8Ai+zL?IM7l$5HB-0;%j&ZbiM05(ez_MdD2+OTsze_OX(dWa^Z|tv1K-rl)d(42X zAfCS)h^Fgj1mapp&6S9uw9TtASUfKL8fogGQp8_{0xqGT)lSZGCyiAPL3rExhm=qI zRyg>Bc+_aI`d-mS-rCficM!nB*sev*V3$60^aphdpRF|@aP#RSmdOu-RMD(Cd?W_g z#jW{nR3zn+*M1jq#t^@ROX)Nh%lZ;F@527TF8Pd4O|Um+xG**FBhu2oyL+txeiHV9 zX|?c)GA5qC7^=Pi_&>jcV6bCvchNz}nh*@qT(R`@VR<_YVs^fnW?_#Oq`mJ0J%x}C zHf!R6e2Mk=ndR__iHTEGjCVs55fqVCASRW;JKU>R*e~lsx=?2jS1wQCqnG-{Vrpm&t18nI!!djLXcN5%G_#F-;|^Z=9Vc8r< zpQhEChu@UL0!2%FYByc#Q!Kn?Qs2_Pm>7!%!QK~`tiYw=q7QGCluHFT!3d5k6b#=wA-H*-0ft((Nk>i{@$?o^IvnPe!IA^vzo6(8*JHY6&P><1l)=3id_zxfa!E z1Vol)UY#7`a)_3RLV0y>P{Y1%5kdYI)O;N?=*>I}0rLy992Of22$4H2$Hlsv-dNd# z`yz7KkK0j2<;Q%#nn>5`4KDNvRme~89q;T1$-Cmov677hVmK`bS z1aln)I&0~+;`n-&NByG^aARM>Lu`U7#WD=kwtL~@L;*N^F=Qs+Wp?wcn5H>@)y0pn z{fRi?Fz__Sprg$>nD}I>EbkEZ@rbP(9dH~?T}f9TAZ6_FX^b<-fb};m`Zm2b7i+A z2$?mHzW#tCf6_6&mpy;l!;gA^!Yy@Bb-hCMiZfxxrhRBn@dS}?9n?k)!iH6+ByzH5 zMWvq|X4<*Q*TTC=jL{r)xN5Ty+K%%d8RdO**F!>DeN=^_sx%S{omcDG$Ce-&fj9cz ziRsUEe-&X)Cx_?hG*k(DnA<8TofW@q^0X^4pawsL>V3VMh34bmmlWn|LcOr zRKOz>W^CqtqKvWwvb|x$AD|U0li&>c(3X`?WP$;ZI{bb31Ok&-n!@}0(w@))d$DJi z9MD-1s3F0teM^_h`_-_L3wvGx>BToa=`N66d_83UOVaFr=6h;ci{o$o<*Qu8I{gpo z(SPdn{{%SoGhjIIn?Tq^teu$nRtvy(B14}g-MCA@{i~b#cIP%nv4Xp`xYk_&IQ>4z znBLvk0#SCycJ7QeTK5K6I@CCv0a8i6z*F{27K+O3T(<>anP8Jffb?zVdP1NOfSH<; z3}UJ+W;>;$bDp>vur1-jd%(pS1ul#QkMerEq=CvIF*JPzKM1-X)|Skc2s61i+5=9%>%qiuckfyGsQ7#%AnZ{fxxVAJtI_S4V& z;RMsOIB}O#(RQk#%E7C;3h=+OOUO81nRE7%wd=QiU=T=LpUJeqX{#?VDGFOse@4^> zywHaZdccK{F}uMUstNDqR#D#zc8j&m>*5z%;N88L>hg%kU>p2YbB8h=;nkf4m0rB3 z99RhN=8>VciUyb0H%r?HCj_hZt;Q9DH+djtH~g=y!fj5NCAoMO_Dt4}HDbl56H%_E zi&f>STuQOQN1L5(9H6E@Phg^R)I!1M(5!Ub2<#vKVgc7Hgd6R^eX1c9eUxx2z?NA4 zB-LGb3!y*gSna?5oG2M-d|e^RMirkAdvm%$0tPwqg`D;Gsi#dyDV~3JQkBzjU1@csF2sN(5hd(UFEWmSn)d(mEc=I|o{zbsi;wY}JX^C-BqgHhdTH{_V zS{f&0h&kJBr-P_ZK{;9p6{wK#KXHi-J24Cv8ypb=wU)e%9e@Cx>}Gg zY5M`TWFzNx#WWNukp^nM@9IWK0|iW!p@cz5cH$VQe``fP zO`vP08nyGZEG%_>z$F4^YR6VYT_Kg?%7MsaGG?z(1V5t`mK(ZW|F)ncj%6DFX3hdS zR=SO5Wa==^+u1HkN+G+cuMEx{$7?pZM_m>rw6sDCAz*LY$z~up+1NNY_?ayr=&Lqx*AI_&g`;lC#IZuw|XE{>5~8FAWtvT$`wwpEuB) zubW>UDVtd;&P(Kk0zBI_);$31cnVSPnHV1x}H zv@768{u}ei|4I(}uWQGz;XJ3<4b^r`uLrK%UiV#m{_MS)zQ1IH-;zmPI4vNo?mM#qd~^AWl1W9zfCJaU+>{0}`DYCNeda=BCK-zW}KX#0gc z)@)?7&vZ1i%Ss95`8 zmje`Egaly|YkC|4d$%6+)itk1yOu?dNm&~-dq%-Vcqj4CmlMa=TDn$~ zD#z3Jh29*Vf`aXSaWU*1SXg?vt1CZ^sGjlL%El3X;Zp&q(oki1j`{`k)t(0eHnrvX zwv$Wxk%y}Yzl*1p0$AP!fJ{8P$>Zgg&*GEml{o&sLTT9Srg)~eV}~2@emOLxH@aw! z{H{+7A>{GP*adrAoL?hQOeJUEWUn8K0QIe>%+^L}$?#BKI`6C5QD`6XyMgE(%Ym%@ zb@`-MH!3H7DNK5Oo1-|4@G;$*4pfkxBDAl3I8uFJ4KUGPdT;|+jk?&5n-JyR#%Dzx zS~FGMA71yFf$9G5ZQrt-s$$AnTXSd9i3C9p3p8AJag2x3*686%yopZJ;{c zV$ke5;)aB+2gEB>6@z|q;3=ruLOQ6g^BfEif(>KWPL-+hY2R}tKA@LjbuAKwh<)9o zQpogld9!1$eK&$aR-&2+_tdUDaZ+G+PEp(bUt8r zmEctO_5QW@&dM;1yk)j6VH=x1Gb6P164;6bvd{h1k+YGX}A1-hT5v=SRxhQd@vNAL7+tt6Z07;ne6JRQ^`6 zD1*Z@=W>y>^pME|Qym%kH6yFxOzFS{NP!W!uP4o5aSj*?`NAu}EbiFL=J`Lj+C4IF z5E}R~M%InMO)tWUQ@x`Z=ciIA##t?JYp0J*T25QG_z1P8!x0QR=~%HrPAP=mcz(2b zqU1}CazzxWoOQ<8e(SloG`s9D3TnV_V{7%=0!o*6CS36>jOQrnZ9ufchT#)JKlY_~ zr&D5XovreqE>L(F%KWL882EW0n=rit1YupS4E;jSbe(Q4gDXd%YF?k1qpNmet!h`9)z*}p!wvN`PmAX~;CViiL%@blk z$cfh9ETr3Uktcci^iJp#x%H@L#9Ag$j;m5GYeC*JBc}|#q9n>~u3CV3_8gk*^z2SG z_JHAL-xJMSO3RJdd_>(d^vxzHu5ldM2Z4(Ip6)jJAAwTDde9k)wEIVdPG4QTzw2VA zq@HG?4GRDOSY$`X^*7_>YaoY)*!ZN!v-eAchHFXj#$DpPlf0r(_D0vr0Wa)X^=v1*Ef`AwAZcdT-}I zGD-2WrgK%|^xrCqkoAvG;UKvh<%KETrz z9NKf^`eWaF8~8sjO*8|tE%+BzlW+6g7ezyAq>BA()0+Uzf&7()GyW~-`*+s+hpy{3 zjTsq9!_ENTz1Nv*Q!8y&xpFZzxoq7@h_l+pT{F{jQv{0UJg<-1R$Z%01RAi zfbK&Vrg?8R&*&3g`^w}DbmTG?iuK%v&x{kXm{ibssE1VlzgQWQ?D_Vk-?@@MZPva&C;8MF1_|{yk)^zKb2%qjIQ!A!*4oo}&qA(xm;WIY z2OhaZ>g?_3c~TPRZzb(WifNv2rrfZuwXd;qt97akzqN8vjWMP`?6gQ48fj~dy^m!GFHw^s&3t#Bx1#SNBz6D7HQz=bm0a1c#dbmj*yHS;bWLp zpyHQsZs$iMCL{EBl>OeFlS_DZQHQnq?di)FW1Wv6#RelK47-yn_G=%%Jo4!@ef}wm zK^8N+@r)~vV>hY;p%uErW8s*tGz)I1`_tMX6wqZDN-n+E%U;-pgI~AQha>Hac-%Sa zrZt9TdUst4yY+w%70-I9`0k^ zBBJzBwy!u+_f?RmZ2n5)NS+r*PT#7>UL8r~n4tqkX-8j^T<*wF9i1@YGn5$MpwA;Y8P-rYCFr zgqvcDW3~>X{qC-`b7X*`$*KKeSwswR3MdH`Sdm)!6_$+EadP~Ms*ZK`%&_oyVG@vA zvkFE2KLFV8fV=;9AI_?U0hE?I2CJ+pl~PAj|8gL2b7BcRbu5etU`L;Su;9k_uwiEm zP>*kLmZhi?ab7V%Im}g&K$h-J9?0WlDLi5OEJzAyHb2z^fHP<|R%E&C_@oJd8-E+A zdZjFErZo)2zS%ZjKmz|0;0NydM?w7c>~@+(NBB15o=x_cb`~s;Dp|-MWBc%5+5W^z zY5v33DMH9D!R5)ftrzdP|JiEv?7h=}*ZXs#$Z1}I$q9CwDAoPipd+`f+T%zV@OHkc zuv?BZXW5H1(SzP4Jelzr+<3q!76@@>P@BhZe-i~7lWPEdbLu-->EzmFVX>@HsqEZf z(d^RVHK1~47l6@!AM;n8ObOi34tbDXtwB^wZfr5}rDUzQ{ZGwnZ+B`vqW%#U<|F#7 zVZ+q}>RbZK2npkYvU~$I?p!xPi8L9iM0}RFo&~+#;?hDlQtKCRtz@^y+UVXvFNz&J_&(zLi+md{H~to z1->YwV#^27Qs{MS$->Z%F*wsnw>c>C>yDgf7mbC*kldhrYzREk@46AR#?7lJ#`UAoZVi^S>I~dv2>n z_;QA5+gw0(UDncD=d3WL>QRJ#S%ir3(k`}D>W?Q>ybFM_!%57RlB4V2l%Qd!3as0v z+KqT0C;R74==EY{?7LFNY37UewBs0Dr+weI#*05awjX3 zhZAZ2s7b1Mi1fF4LiN4EmZaHxC({eoB4mb8p*GgGP8~n$sYZaP-swj*bxuHCea}^k z(RLkniSbQPc-)LCJN>>aJ8?q?bBXqV$lq`49#PoD?5n^w@O)y9@lF@n1*gZq8$@ zPNIzu4wN1z{%sM2o`wwz3)TCSr{+^o-?Z0yJ!7zkwNF%P!8g$?QRhFSb^Wil`M=uO z`xn@ySxgxC=nejG@^cs|M&m;6L5;;Mu*>V=T~@Ko7d8)D4nL%6Y~SBs(Krg7iDbOt z(*u0$aFBS;CD+*|KzcXQ04IhEzvAOvtmxqt$@eZ3 z(=%jyLWQta7M(P{tFqbB?Lk~sx`;Qp+|z@?M9f9(HwcD_g|*3Hp7)auV=Y=08S$WK zJd%fic!q*2hacWMs%v+Z1zEEv z1Pi;fQDG;=MlKiZ#)%RRWckBZ##QB`4MO9b}T!Jl=pN-OJ)zLr*UWr%jj53jF&?6|EQ zv9rHaSuJP!b4@1V3f%_=W_DD{%t;P4mx|cogeB56ynSfRcs!9l40^h}6enby8q(}T zgUbx$7f9hen>!1Z;yTjr2=@SG>=CO#Cz&l=jCUOaF`VJ^oNa5QlQYYVj8;Ako{)pg zC!H;fd)W_~#7PgAs52KxdnK%$d>3!Az@WA{n1?;KW6qd>^&$AlK>sqODp_LU^+p}4 zdS7oZAru|o#gYTPyK2+AQEz7!JeD;0s(mD_c2k0T$y}5H@hLKDTNM$Fs}GW~+kNJr zLQ_oA0QR%ZMDeA}j8s;;3<$SnWa#711+-8C_AgLqw)>x`(CiF7LE0K9io)EGnBm87 z=3l__prD1K5JPy*nJpfnV2!E;Eio?2nuG;0r&Bvv~U>&MC5`nTXEwk^; zsP^VTBVBh%{f_Ekz1RJfS8CukxR6scE0Ek)W|l``5|=1SnmYNzS55_-sLe zE+lIkZ`qJ~AU}n@A}!&J`(PHOYyA_}`<42?H$Fm|+m`(6*%oq)&!f1d& zHaB0}cH3p9uO=CbkrGAs0!zy>1cE+2KHRZE=#31RO%#;ykLEbL5w_QWTDOV4N%ls{ zfnQLMVYqY?vs+?@Nms-?g&ysIq63eP$SX5u0tatg+Gr7*95Xg~2Y2aIQW(jlRk4L! z^e;<@5l7D6e5GUk+^<-S`%DjeR&c|Dw&_#TC>==Cb8(G#+&X|MaOA^?CXxX|o$uh< zUfIB2m02I`aFNA5o?>Xq+p^mEmi~WK#uwiIQDuBChGZ-Ul1?z^k{CDkLp2yn8{-QD z(U{0R!H*gi2emHh5Keb0zR3%Gv_hgS0V7%pAo1}ZST+ju%*O(Z7_!|omAseEBTwDt zKsC&}juz6Qh6}rsWVD8!d8Z5wO z+byC^=ZnuXb|?o=HUdfhBDwr*Y@Mt$xZO?+Ibky&t(yw_u}{_bm>kHWw6(}j%ZQv_ zExhBy-fUfLM(csAOY{It-6+Ga;Fj+BX&a66795v`o; zI@5)rGJqpJtZgtEG=%{(9Lc!7UuM{HmT|}#DIP{w(cp=ob46Na=rUI=)CC#SH2YIt z`>}>G8g;-1^@wG;YHt$VXTOos#6JK~MUJdG)7j5JLBd6AuxI}BJ6zDUVeZStDnAb9 zm;|2@u|TzxuE;xQi}utCNk5pCPok{06MyvzO`YD_nv<0B_gP8105*hR{TG$Cv)+?# z);no*$98>%W#=GZ`d(<>31*v01iqgXu~*#cMJHO#eC!j62nDaU;*ajCO_PGgid#ts z4*y!u%K*J{n8qG&z?#dKFx}9yF=f(k+!&~5gUsAE7H;#CUbc8nS<&ntqV@bTkj0KU zNxSL$nNO$*DZF?3LbQi_cP%_4+k3dhT&xJ&8G`hLjT*x+*{~^%!{%T{aUdgNpTQX} ze6)%O{4pY_<;?WffQB7swEs!$6y6OJ8 zYu@;n8#CFJCZ@-cZ!jVI5~uF|Ty6j;l-GKko}&#B?&IP!$@Inog^tyMp|dGviL)kU zDtYUNh};+<+-|I2H4td^FwC8e8qyANW~GH$guv2n;rST5DxMwxgfmMVJcV{Gu>Pn- zw*<(G${c`O51B07_;2cOd%Z8YHQ|C{%9ni&Da&Wg_{)IAfWS%&SY#(aVy0(* zBPA77>D$AbGpwp+6l=Re0`uzbWuTBY{`4MD!Rnl?70|X|_Kt(*;MI5-tm4PVg{*+8 z==Yma&lTqm>`uQm>CCEtdO=$s{m+o;IccQNf)3=ol$6edj~lMUJ1dVU*prpw8cMr& zbn_R#U`6p)KB%mL>m78nm+<@kz+R6NhN_#I;X99PmVqrBFO_-CI$xH$Hu$fY|1GCl zH^bS@yk6Ud!BJ8n%5&w`;I;MWsnz|FIif>gV5p9c{7Bfla}&_uZsAdg-Hhp!iA6X_ zcSoz~^5s2Q024R(_wxY6%Ii@O@+bBz!rb7RJFo{L!)4`HL!&W$)9NEe=1(~ZjSoUj>Akq8(CxIpSM-wm_JkiJl> znVQ|OlpRCNP#m7@W-splPKO;gzuN}r_`r4JVPzTmI_HKJ8kI%r<6fPCN^!fW>la_u zMek-#9hyrii^ZN<=`B{#*T#wVq&s{6reI^=l;qPB*U7r;xKkTYKJv3dY~u^_unt4R z+Lv8Ryz0gW5FR`I{Az20e1Q5v$}7e2Me!0{Omu1byJhl5 zDvrPf=-xy0Gf<$!<9>ZU#lXFqc4aMt!inef#SHtOKtlqjdl;g>*R1D!rx;O=WO!iK zHvB?qE9UCzy`44@zgw4D7q8QTx`SP`a7&5d3=0!Ak+K$piJdr9{NBK#Ya)HEMSUEd zm-AW8&##mumor8`YF3zWca&XXOeJY6`Sb}YluT<&G}&d~JNc-6MSBs~M+c1GqoG)O zruQhXAZb}klU7|v8uOJ*GS*9aE7A1sC;UWy_iFG8Gonw3dj1s`6RmcN;=z{q1o(Z6 zK~Nez3u0C!MI_S*sv_W#V5tPr!fXQ)7F3cA3VOU>ioJ4!Ma zO-S#)n?ck-UXG|R8z7rf@~_B53VPfIcAVn_NzG!&5K64$(Zvzjl?-^KbM{U<%>#_z z5A09tOmz%?-hELIve}|5M?zfzAq(~lk5s}Rs<74N@$?9PdXX7 z+FPmuk8KHl&pjp?YnBWFP=+Pd%_2OK|4P>`=HUs!bd47N1@C!La&v8OmAwD^F-zR9 z51cD?GX*mAr|20+xdJj8Z0m+Vmcd=vjbe;M6F46=b4Dyh@+WB2y-VRr=(y6siI$3+5hN2BrSKegR+L~4!OUe%=O_9!px06nK?%!;RsP~U2^Cu05M;ub! z^YSJe26B-{p`zgfLKsZ1uW4+jO)v9Pusc}^YVO=TaX_}eP|edXt*D4$Kt6gm#W$9Wo-*`z(^x7)VvNz1mF<4&~dVqA=vHib!$`S{~mOH{$}M!|y6)I>GoU+5mMyzFueha;Y8><42i z^ORFOMAzGflo5uev)ICn-s4->54ht0%$2X9_N?M3oAg9vsRvIPz8`Zu(|~R;1 znBqHb4IPII>6!hF@_EV~{-6x~CsaLqXj_q%Cv!lc2LnNb(0nlo1a_Bnn+OtU7Z#k& z2vS;ba~WR13DLHbLZFM}F{Dd?`pD*QzOA{$4C*G)ILm>6KszlG)nzqwyzFmfl3h0x z{9nuk;xr%peIh(Foh03wj&VUQVoe8ylJJpB?w#hso z+KK^yB;K$&o^xn37VeXhsDURCys9vD-U^JoCw29~!Z zrW!h&N_)Jv-gH}cSju3?hvqC}=SiAJt>rva?55be>@ZRd=vab;0IUk`JLWko?K*jM!JkCc)?&}<#ZuEL(uEs zaG_X_oJYdPo~HEd?|d|@2BpxitK zS_RD14Jp2EYNdWq3vjY;+@!=@&2bAMP9M;T{e=@K;KvEr)&p7YujmZyfaL-UQjmd7 z3I7jkZyuLa-u90-PxqZOQ^w3>Sz%JsV&zt9qNOs8ZB}Sz<}SIXg1F=^Ff&bBnp#jLwX@#8}5;~Yb!TSCyl?e?cp5^{Fi`kz2oC#sLhEF3vQQK&~VGk zlU{L&*0Q-Xq_W6v_0QVYLT*;8)h_J#1i`P@%1Xw{^(qxST(u=7Z@LfY7V1_X9>=NX zPm5@`2o~iytj^+IDq@d%hY1%{mx4KB@~IcQZA5t^g}xdPo^>GWl~6g+IP?g>t^V<{k2KC(m5vm`-us2EX>?- z-1DM$pw!N99P(8p8dSb+XAg2q&A&0e>ev?fQ9IdlODN+-N85y|(9HD~N4=e}0qvZ; zU}(r906!AUu70tU=Y$#*(hs zqnUka2L9{cMINmy`(o9A}Xo-SZDTVnW9^G#g)MdK4p9nz z2W8D?$kt5pT{Pdcrw<04js#noh`TlKZ^t-Ke{vjnmZWeS4TpSUr)G&04BU7`@0Ryg zCLzwUJWglwuUuBJ*D>LHP-r0-ydQtK&%3OHxurPy)btR7k#^Ia6_g|hRRqk#VZ{bS@@WzmsTKHRV2rc$Xsg7ow!K3Gwpa zc7`=$=c*P4ke&9pd;0Ee$e#ruY~zC&muFv0IHB~^5>n%cT>=|gCPsnhM=vh9lDnu?R*tz_|yV{N$oGcIsd>+ES_A5uWU zlzv51#<}Gr{3J51CI z-*MAp((fyAd&YI;dds|u^Z<)(CIO^lLBRa4b1qoIWW9sPqOwtNX190JlOB4{pwi8v zb2?Zb)r3U$ zrq^OD-}5ePrCB?S4=WCVK@7i9dAfeOHxcQ^O+TWWK&U4gHG8nT+^o(=*!VdF-q|q>wHCg8P3D9wgUcK$t zbY>V|%F_IJ%IS@3B+PL~3+H&>-ZSGN09ysd?>Q}X+$`ax2Nc#eu8>VmOJwO!mGYlN zwL1O*MX2I2!1r6<$H^#>EhyJs&cM#luwuOst{zzHEZDWqjX3o@0)U5ldwMM;H z#?EH-`#9{XFAHf5_Lxsjjd_{Xt9jbjVV5{->$o={kEbZfd*VTB9~(en&z?u@Sw79xf4!^y zsOde7uYxrNZhnXX^(0Ev(OZ?8h`wY~;H)1#P8EyY7XUC=$!) zVg~o%T`_IJPORQ5BJG_coG*j%h#34G#o|PqAYvwAS7*l>9nG2y!WRug z@_&y?Z^H*bD4I=`tl<)ra2WNC>+o@-Rb|6)}u_q3~4H|?6t$G7WehcU5lVzlSGtt#>*#Zx8Av+rciM<#eX z4%W%dC2Hi@t%tA}3aDC-Q{1B;^kyRNZ3Ob9<@gGf$a~1O#AH*Um3|_|&)gUwk?d5f zpB?hl-?hUBP5oG^elX~*3q9;qEe!IN+UOp2wakwAk0jR#rH47y@nFRko>zHak;JLA z&`|BfF5SbEI%hk*B1V?0$(nxQr8ft-VGF-qT$jUHDxPvy73-#T^;ylMu*TS038YM& zXvlst{pRVAmO^S&xcTq~kZpk6JNuk*5zIiCnJMKsmu$7z8>Y6aAN{F`nke8D@e29A zu7n4yt$j0wx65H%>OdjK(kc*lA`TYXx3wo=3N_pK9#x0pD^JF~=`k~>L8GHb>N|r~ zT?-aW$>&N!kK-tOboSBtVHjpm-FYpNf}P2Kgw%zz6;<`9Tul2F^HqO;i7xm%ZFpE) zm3PaHS5rA4j2a}LmtOIv)Gs|?T)0&ov)=LrJhtWNtS59Y+oqd(EEE4DGSf2thZFimNYFpd! zP5m-)GxfOmYP`4S-qx0*xdt?+v)68wrftI#3Dv z1Q@FNV;N-{eZgdlbQx8lZ7;U8fJHm+p3yDcI&cGHtgArUuMgIRLo?#i!)JIG7d;A> zemmgD%nZ3dSZt!`LaEV`px{0@uBMJ`nMZ+GnX1E2*PPl6@h$8L3&w|d#n_+l!;JWi zo($X3Shh!j*~6m_XUyA0!;5Z61ZieHS?`vfLGmk$TVNr&?nyMIfsody`H_kSkZUU# zcupVHP`!MCMLE$JQ zvj^9fQT|hyS$Mi;dg+Su2B({*0I@jZDHEJq9Eq9C%252yNDa9JGw!8u+s{>Uow&KhZoJt?b{=krs^im!pRbY2%=*>wknMv_y3lWh1!gjA( z##x6wzFP`A8}x^qqH0NHdqnDzzE5Ry*)o{T&rYXE7K|Tw43&3>*)n5A8oAh1c7iy0 zp)XgK&ui*^f!%5#q%Fc_BYT(kMB~I=7s-)*DsT}(5gkpBFC8J3RBtPiYs;GQp7+j@ zlL4W|@zTlY^f-F_$osrH^>#n3B~UGcxfbm)OOP(SH90uB&=~Aa7{;7nhmq+I;b9Os z?_lE0drM3@B|2%6LWYOv1d8Qza$Q&mrrV|t1J3{EL#_YIZ=O}PoQ+uyoP_k`SWH6} zG?Z%a?}fn_Ht0+d^gtarcW_kySS!Y}ohUED{LoZL;HDKY!rIq7z|5~f73&t>>Sp={ zVV$`1y>vAHKGW$2&aGNIet!(j&ZyBe2f-AB3S?RGl$Cw*^799f7#=Q~*EzGNm5hl* z7{oL|ta9aU6uqL9GS)K5JMd6Ue;CH1R^D|f2pmihuQlkVBjJrr1GNZWS+}tEP{1Cl zQ_*_UlWvpk~Z=U{m4aPmIaB6Efz@2BZ#IIWwQe(zFJ?mC{0tU6GE zOld9eZW?Ooi}kN7`hEcY5fH;^-3!-u`{eLma`_)CNiV-8{%vk`o2Z+mKM znc$Z~=&x*>XlOb&O(`?zqK*IZa^|(|TvizGr=~*0KJ@z+wkPVqPfsHet$C3nVJ)fo zvQTy?QMDCH2=l8{kR(?DKd6~-Cz5KUM}~84nW<}haHw;2q|H?HwE5QsdP8$}|7e3i z+1*g3?<06QiROat-2-4WF3EqB>;ey$Izq}3Ny0?*GKisH-n%RIk6Q941l)rSqY(j= zvY7E<3@*T!I(@j0@KWwC@;0N^ZB6!}nTnWKS_9g*<=mNcdp+rhYod#h8a1mr*n3zT zHU2Q*%=D!_epq{l80S>+98dkUc)R;HX#l;B+xk-&`=xfIO^oCTDQWD5*E7`#mxNBQ zM%~x@9bv}A=hpThj0egiy{Y*W`cwbmzS%JK{W4ou0S}V!VB5XEuK3rYWh8DBd+gKl z4{9@QIV!n^K@sZNfeqtU#qPHNL3-4zk(n;+%+wRpmFbY3z+kemEpT0POq0ocaWtGWs)wN@?3g;NesE_I z9T~+Fx5e5c+{#E|_OPuRbrDyCqlDPhTg*M0TD}umEeZ%4Eki?Z{mliS#g$(4^U9ZH zj%Y>3IbrF+f|tUC)7<*uc%iB}%&$}pSQv+HJ^oaDPMD`lUO7eM1F_g<*l&A9wV-!g zO-ZoRLO??+*IEdfk%m-Uq)+GY!8QU~NNGeNW_j^#Vxw1z=U46cVd|}3^*jBvA1IEv z8eXujh&xzct^a&*K}a`K26T9t7A4>l=Rj9`Z2am$WSw8%{>t9G^1zjKQ32_{7hL(v zjb4bAQFKPQd$`RJ)nMAmxa?)3^?1iR3y{Pc413Zcz0Ch*@wM%G==wM{kLdNy`+m6j^Aft z%2jaxaPlEm%?Vg-bIlO04lFs(rS;EPOk+4`oiE~SYcICgWtnDxUNlh)q4vbr+Bbz; zQ1*tK^50!Uy;8W3nWzyHVQV@ z{y4ZVWUq00K?)X;B%d#BW(;M;rT+yG1r)Seah6@!XIkm9iENn91$3StJz-zej6-p` z)CdedfaHhqt8YXg4hO^;!TWMiF4K7bK-pIA5VMD_KY8$qk0n&ZIV<0C#a)?l0^s2HBZO@_c4=)T8?4ACx8+7^E zp^ew>)D}4sLletL)xuP4VU z4DhS$EXSiJcKOd`SI`H(Vcy;LU^>ynb87HK``>d#;+yvVd((th?;ei)&ACiy8j;Y^5czGck;}a zJ?xd-N67K`QoI3vj?e2)*t-`loD0b1T||x=GKsrHXomU5wFtItv)ZKIl8T0D+X*ky zLU6;PJkj6$Q~M`lPe+;*;p_(^=jpevGzPPi1^MVxa0bt2V;fzK)luEeraqy*+lSSw zKGYx6n)tjj09h?)Ya3Y36s!06NiE`Ve{;{vPTOw8`}SrVPvQ^9Wn`p3eNEr)u_+#y zXVfXTHW!X7VW_>f{nO>mLHlP75K116mX=_u-Wm{qJd8xRhn^`UY!p_fDrMV71L;3{ zqHF%98FN_rIdB=YP_YlU*J0oFvD%R&xX(IKXEu7_t?FqYJ7iGIDJmTJ1fA@Okb^&(Q=Mt znPt?WkX=;U0MdwoI+~Fey%DeFuXt%kd8Yqj2rnciJP!8oc^}F6y|J!=ZBl!Le$U1r z($)Z<9SoOy(h6{m`$C8HBu;ympC(tWJQqEQtohZ=I*uHP* zkIc|VopJ}b_M%vI@VS-4fr8Ao+#JkpP4tyB-NdN!;}>%h|7JBKOd>pxzG-Kwe31L6 zd8{Mm>Dr`oL)4|!(~Tr@b2hyF<%B0vKn?aFJpN$7``11pKga*-^IwW}-QV(mqCo$@ zHSYiO0{<&taUgaVfHS~hlpFkYPTQ)Jk4FC53gX?~zj`2IZT`2XW5b=WD;oD+l5YiXD7&G}CDPv-Ko*Z3bKQ-3-V1hJwQ8^J^ODbu z!yLvt0|+q9!F4wpXkw&)osY^Vj{GCyp)SAxQNH1}hbu03mISmUj-j&Qv3r&w6S*K@ z$YN!o))yH1@YkRIN_IImu;c3se!b^8U|MRz^{-Os4`$b#G~{<5uh3&zf;I#?NsV{0 zjTWA!Czj8&_06fSYNdJst)-Va^vH@gsg;8Secu9{`8rO&$VY>zOng~{y>(1my!7PM72qz7?-8-$>t9F$iiTZ3)c9RV;Gq zA?w*gaBtJm=g%Yd*>+;b_>9B05c=M%e6$0+cWT?TX}(ltg@vqzv6s|*ArsIQ4qvD? z?Df0Y{!s~GRJeK7x0gj+L}tt8?#P)Urm~23{L}hrDNdITSRf5)>o_QVWhw5E|5qV_ zH{uI>;0SmPJv{kpFgwOa_Uk#s{h6Z9i(lI2*5vatUV7B7o(P5`^q=DThh%9 z8VQwqf6DDUViuzuqG5+TZ$FJMn7k`9c>Sx7uT9QBtN6>okUH9y(L4mQdhMCW=MiNw z`|0c0FDLuIKj-3pnITRhSNXgw9X@300RK+ZmPC%Eqh!<`><_K!GlIZn89~=!X(z`i zOTLG*8{&<>n(e|IIC;Cxp5fp<^SOkQrc(v`);c{{VjH&g{4tRBacWOrZ_cqsRRQgB zTI0mn0r&#xgFfcgx-9(|Pvq$V;f}^X&IRrowcNR-0;fTGJ*%Q;U+g@-aRY~7_($eT z(mcOu!et36_su9uZQ5`;pRfHTYvCiZZM9b=mMn=xw6FF&jO%i;;C9eE;V^ ze`TG!uwQWc^!T~MZ)pC{N;=&yZ2aR_b*5r$p`XZ=p6)iId495ZVrd6IPISUNsDf;& z6#exb;|noMZ1_HW~}H??c<_ccEqB8^&JDXTvc)q_<(m zpMKIO4gn%R3&k`>(#xV8XI7YdZM(y=PZiQz7As+z$R*!^nz!#yeqD7t4e%4vjfcjX zMr=0zW^907FZT$bjWk8t$5m*Kan$|9E2Z^5PyaB_^FuCUbQj%xZuVB1=h&ux6R~`l zUx#h1^5%4RWes_KF2tHfRgK)mddB*?ip*=d@y9}6PH@}CcUj#j1ZtkRZOiuJ3I zt)A`2LOs6X%jHe@-`MeNz*l@#bn`2~eg$LzeLfj|g|FWLoc|7RyzH~Snw={#E0NkezXMU0*xI6p5la4#?o8Ok}$uEx0(+08CKrX`o2dL zEdR=8=0k*G0Gss4De`v%XLXq#x_fQfWOu-fZ2VDGIzu|H@tW><2LQsc|CxLJzwy5R zPoK84hQP35tZK4ouD8I14}z_1KY2<3h>I?E!YmuKgMneN(dPjPE%4BcL>2)CSmbn0 zCr(FKYm|b?Z)emC|5t+?qql0+hph(q4`&zAHu7sk@4dH$L`%EWE+Dk{F!k5(5#=Jm z4Ss88aFz1Qu1Jokn+mn?^xoJa=hd*NC+g{Ke z?`Su#P?SGiMY>QU;Nn33NXHexa#aEKe{T=8`)(yXyspmhE z@=3&%Pi>f%c!N$sy#G9fFK=Ml{Sk@$r$d z4zc=j0wGtU`|!L$I@nv8B^*w19heGcpS#>9aK!SL{4OT&gFSHdu$0BiLY4htS+GaP znjQvvYB2|1+2J-<)=#)Wa35OJO%xp-UcgUJ^`zHh;v%C?Hluk-97augy+s4a=liHa|l0wsE*!a=Xc)06vIpEAIrYAE+fstK@5@)t9Bub3Sra)+B zO2TpSjp&h;lBF%4s3k=8^5!u0 z3CAl#BVo8eu#=D!_h!}DKTW%d3%~!I-co!P!7Gi~T){E?G^0DXRrWcxWxEoRk-PLJ-e%f4GsG4J>+1|9X;s_bhm($8ulHG?!Xy?jVz&C8O_RCaszLF&fU|AaE8OM9{sk@V^Pg#`b` zB=v_VE~&7vNKzTV zysyu;ta~lB3WZS*ZZ*qx6=Ecwyl?F66y%ez+phh$OmIP0H-pX{LD;bIxf55@%VL}a zFS0(2F1=~Vo81vEC&pMvN##RvTs@!)O9%!RfC+SohKk~@ab*&N*&-%iBQ{N-pH8kr zTH0O{xrmH%Id$BwQJdZsUmEV)5rhd5ELi#dDW>yueQKjyQjxiN)I&G1SX5w+%!tiwJt4)8|&uPZ%v%babRB=TF61=MxsuV4nxOQpl`vfLd)cFH+FOIspC1#hXcHs6<2)cBtp^V#l_`B)B zQ7fRNk@#wt+UPp3Y|$^B+#3<-P*g4QiZ8n;D_d&Rf9BQTjjXo#Fdy6kvDMugMZ_|{ ztC02Mf$|F@!NmwqIyAXJ4Y;^+yi&ao}k(4lJjQB;6OICNzwK6Bp-%EIJhP6>A*iSyfHnzc8W@GVqVFd2Qi zV^gkkgaq`@8}W{jkZXyVtlL5UOOm!AOxLdqTK|G(n(v86b?F};)ZW1uufGZsRcwPz zF1^*s6g?9jG_(k*iy$P=Z|++@Jg4T`$S`<|##?#$nytDRqrOO<;)R2dUZPP9h*Ja? zk)^Z;ab*VUnUly%L%6uoW?@_^uQFs$3=U?tNk4nCQ2BF~>tTb!o}l(bR(@|+gEIkG z`O>QtHEXtb?__+p)yBK2SG>|GxbIFdH1#-sVwD?(w3hWCP1k>Ellzt z{mamjaB6*M2AX=aWxVi9YGcwH(rFSS$Uc%cpaNiBblDI;m=lC?cZ0nOXJ5<8((K}9 z@mF4OJBkb0o1m-bUpRV$5xp@6=`s|WTGzn%{q!AL*hgZep}MwePRG^z+yk<9%?V}~ z^$iDmsKXmOTHoZDHO|}-31aTVtGLZqRB4Cw1&Ewrzmw5I(_BRigJ=LEHp(+mW*iT> z=yFm(nKF?Pz~+=t=Gzqt)X3mexys3BPB+|~QAa2h<^Z+qEt%IaE#u>#mc|yIZB;Or zZ6@gfbA-v=0 zK0ZQ=Q*~m}*XzAZK^&5@?f8qyNgempa_v*C**8Hq5UB^51MLiX!6071cpT1Ek1+^{sP{#Dx^m zh#Fuqt91pavG>qumPNGi8`oovBL=X$Q;~>8lPr9rcq*wlSniw<4JL+d>*>b7Zk~T4 zK0!|I3icR;n&&_rJC}A0-)%}no@C?=;lFXc^Hsb+3Z|p}O(SEfd4M%eGXNVLAmw8|wi(s> zU3ou2u)TY-$?_H0>3TRZ2OUjE32PLYl955`aF%EI@|WJW3`>QN#|TahCSZ9J{m&L` zV-EwV$(3K0+$lh|HKzUycQrO~yijJsVeofN##5prMQP2*w(+JZKQOL^`0_b-`uWp1 zjqg|w1>vjNHcCM|!!rEmY>-RyvlrEA?A2$Gp*wiAL|B-5_L5|jXM|WhX$v3Li6rnm zmN`Mj?V6mh2_u+|h1?uuu~OD`GyIsZN;L=H)1u38TWwdKCbYhJiy-UAt;9UMCqdmr zD-iZBd^h&$xTKr4`_?+L+Z0{lN&`(pDuPvc#NllO(=U~=p$MWI-!IA`MuH26-6cF~ zDgvVL6c9BEwD-8yVKiRz+6nsN@SxKT$*Y0Mma((svX%;X->Xr=ckJ#&&*6IEOkyy0 zJ(1JMwNa^xm8kggaSGp>R}nBO{Dz*_F=Aj@Xf5ncYWud*P%{6}YuxT-j$$dO;mXm0 zBL4CZd&OuY;q`YDOF+isbAdTz(@auCPnZ|P_uT|`UpHzq10HZVz=Z=B007zD%4EDJtHQqfHcm6br6t3@{@lIFQo&Spe? z`{-Px_hofQCl`Ar@18y(xlx$Bd_=)R9+^@n&9B^GKDW8z9r12>gf%a9NfY1ekvpa} z;hqVUo=ao3%Qe0cgM>O^s3kr^{OE+PpLj!K7bAVtozMcMni_3rmm5#z;@o&f`S0xb zO^nxc*t#P~bQzkXRV^rG-6-?NnA_Q$;Y`3)>`n;f6l#@)*-oRB4v{}lBTS>_trS-c zJWA=jfy zLg4lqaMt|K*rn~I`@fhPehP}c+?R>}u(0|PDkEy8!LErm-h*s?H=DLbPQg>hp01k( z^CAg%p{xCv!$E*(Wh&`Z$AZ@2a1S#e{?nPz{S2A zwPGlC{WFu>9E!?_(b_kBOdE`vehXq}tnDUh7Uf;M4!8B7w^<4|g8gJ}3a0$5`sb(h zBCwMs&~rA~R*BlXY;EN1g9CNFNb}0S7B^B0p3n+nSHeZ({ZNM22+b5 z@B~+p;y=an=Mm7R1iUBC6Lo6Y+Hv@F@B9IU>VZHeV;nY4b{3`A76v;WWOvl1w=F&M zhkG@J5FV^*q^xM>5fPE;3-qT$%u~)l+)yoxo8?d(@r5+`@({>%4&Qayw)~{a{G&q% zq*~i?10}LG+Zm19qc-}Mki%)qV~TuIJGv(~sY!=jYofj5#}85C>d@7~Dm+>_n(~{+ zZ3FxZ=kvt2XPMxuCt0E#-269C|LX*_?kyMbL3ljl%2EUV&e(63H{Gr&dbF=B7T*!q z;{4qTBe#Hw{6p5NFYuT>v#3`wckDL;o(ZPs5BA;J=tN3!b1=Iw>)vd5yy9H)A*pP+ ztSmrOKcJrOg(s%1-bT_NO02|w?lZp66DG)_Me(?G6IUgVW@?;r|2VeL`U7d2E3cka ze|jEd>(CVG{*I$|3DJ?vLkwWNU;>Lt3ScmUg22-RXRfn%JU<_Ft?NETKpH-BHUTi) zF@MC4-Q#Um!eRAv7+2{|o=ds;5)1bP-Dk&7#04lh9s2Sm4b{xpkZehGsu(565o3&? zrPq$H105{=I8UlHY9S`9ZCpI|ndbq!RVnjS!xWKqLxu_Rc+pMXMwVz-mc@lF!g@JV9UVK?qe=>;L?3GuDEn5{ zRG?PT8y=7RqwFCNrG2{SV`}?NS-p989ZUMKRVAV64Gmr-P6R@B;!5d<+v!th(M4#s_558M9_mBS`x>o|XnE0AFd@xV4yxwvIJBMlwxk< zU#HoXZtXDb($0UM-lF>Q(OD_Xhpk5omQM5M2bE!hO3Z^9Av2%M`;fb7#H-Zbt%gsb*c4O_jbC57a{n95>>ID3j?oa zVs$(gKWJlnLRvCXGTJiu63vS>_SYR&Oie$LHHw9nkDT&ih=O|6L9o;6ycA?0XU5-| znl6*c^Xp`TZJB0cM+`Pd>)m>7hMLy)fzK;sL8EN}k7g>w)<$lAd2Dlb#=bs|)rSNi z-{V2E{O}2y&;^$@JH3GkS8LCIjE)?ewyC9Md<)O`_{TpUS-z9{DRl3UrX3ku+VyU; z1b6jCRf^|i($PdPF{?~RVmJlXsi(C;O9;fw)+?DwAf{U;R;@y)QkT0SyK01=iNUwc zw3q_cP>B7L=vTIg6}zPunIR7n^&`hQ@0l0EeHB+Y&*;)=hBgO;ZjuT@IRo` zNjtt(|1@pVcTI*9ko}t=>X=%DMt6~L3#vLmg1pIlf^ENlMXdJ*MIHOr4Z0K25@~~e zpC8eug;k(Hn-MSd1);4};Axf5<48w6gYKtY0t;5z4Sz4aIWOCN1Xt~(U6~br&is|f zo{X`phvjc*%S2va>{gh+Cha(*bcoha@X&pC(2jFG6Czd}G-)|xX|@HM(ER4gN*&VP zm3CJ4#LU0%H`ZzLcdldFqfsrYTyIM^G|*3 zUERd+bj1cSVguxkS-MiU&UGJpaF`ZJ8Jimn0u#aAP5d+JOPd{?#>6ySlwWISJIdbS z+e5~0z1G@_GzX*ri)mT)S~1jD^`{1}a9+^OQi%eJc|uk&vNd-oxP3(Lj3)J*@oHzk zM!hf1AsHcpKpI9(H|M}`)h-ZXgnAdR;==(YM3h%S_>1uDBWU7%4K0wMKwan-o%8rK26E{hw4yhS*7prz*|Mn0#SQI z^AjoH3^7s`d|p7M*J+ZN*tHV}Z`CqpS)c3z@WfPlkK6=f>zCv$otn>$-tr|Cz$up+ z$mVd!U1632>%EfRcH1<(8r{?r`J&4wsf%12$T^!Nbf-4ArE<+l`>$^c-;6#0f)*Fi2KgEW0puI9;t73i@CW)7oy#?B-2&(loJGc8c?M79+j)mUO84b+OSKDd> zP;Or1udZdaPNlVn+NZ+AMdUV}NEof$ejaw;$VkCiY3VcmxhU_EZy8aio+ec4J&iAY z2zTdp2Zm(3qx_w#wfpPx z@eo=kupHO32Y5E616-uvnIU==?+3N@5kPSYDoEh^t~hQSqApi}@(=1);1r}| zo*1m%;fFgVUBiJa4Z#ySwp7LZV(VRIGS;*Q6xMZNG8Y-Y!7rvSh9~R~`g|3+7|2zuN$#aCYhDG{Eg#DbB{= zm6J#Wm3k0wLN!^O9z19jkWeH0*}}Sgu83D6Q7@#G2SOI2PsvMc!l{njW@}^X`L^3) z*=#9T8GuaoKSAXOj9IQ#&mHCfghrvuFsYaP-fmARMGjh!;B#{{hl}$boe1wUU4FR# zzIgZ@%@hV%4-nwmGg0=ghLtYr(7r^wXyM8-+17XoC?tQl+YOo*KL}d>k_W{Ua2@8I zTjX!I8YfXVqdR=7V#W)o1L)aGFeybi63sWtltjy2_9^E75I+b>@)+B%eKUG{F||fN zC{-qBVz$)fqMwf5*|t^%pP)3bCejq3i(KvN(YJowo-4S!8pgcc_Y~oF3sVB|O#Zbb z!FVlZ=HM_$A7m`UFV>nzQ{;czdQD#%R78~qS_PbQ47~ultv?fYP#*-cA5y>uK63NZWN?dH@UMt@Q#D3Tu`gbwC81QYjk;H3=f4|=L8A(nowB;-k3f!$C8V`4>u z8mUou6&Z(2&fkKpu9IP0Y~5_d2QnDu;QCg15=(6t!=#2d@!U9!xiC>Sr=`558fO86H{2z}^)TcLhuvnCl#6fLavj^%H(q16fFF|!J-WsZG z*~b;^nl9nr49A=wX+F~WvFathvYaBQ%wju)2tq+G!RWSd95c>+RC%-!l0ywe`2{4U zL!@Y1!@?sX(r{Dzk8*wF4uP)Q{_U9d?QqG8U2$f_^c1ps!J(I0BL-G5sV|=#I>;Uqu*Ny%S-S`QD;&l10qrjHQk5%L?#{VfK6#I<#eOXj(mt4RAtGtCjQF zWVf2BT&f@kp!O*Z*mMys!oMdogqCVPCb_P!X$>pYvX(PY_35uxGDZ#WDo}VoFet+j zK#UiI_!4bq*k)UXeLcD(X%>HHVl}MQgjvbbF`-8hA(3uu!yUM=6vHl zATdqUT2k8O*+UBFA*u#Gnd#&&d9?B|Dyicvu2O=sY>!GtOFojDa3gzjtP*uE!%oa- z_wwkYCreHUSfhi*M7$C{sz-}Ka6XelaaqwW;%ZNB+6%I~WVCy+u6|^x zoT6C;i+-tQ&BVyXGwI;*;F`!4W7OPVDdC+L)9xi;?jR!SfqZ_+9>Mf{*?2JGLev`? zfCdWy8ia;HYdhzAejYm&3YnVEeA?D}3O(y93b1klwz_#Q9K_#@PaniTj`yR0`^9U_ zTE8o8?V*OFMq`~fR=Us}`JhCGBr^c6Blu#{sEKvke01HZRHKvb<0imv7BHjy4W7`MxKdz@j}b)On7X3PNOaiEl&tXq@)Q&& zJrSl{TDj<7x{K*ND$t*yM5u`|$^%U!<4yU_?Sr;;P8ZPo)(=U*)W{W1;gqBT;yiEH zPmHXhMo6}@z2{aok6?}O@;sZL6e*@Nd}infN?R^hULPavK&fn})!{yL$5e)w=9V$z z3}@`^++*~h#_C9>48>9;cNPbiHepoDjaU@H61X=U)}P#A=2 z&1YV#B~isSsW?Ei2(L78%+gHq08QWJyZ^C^6KCl)};$K#yIFB-p}IOnAWSi}oUenu)&99C36AUA64{_QJLVj82Y9O{kL{HZD*{ z!^r_dNqaO@CwM0=`KmDKrRdB1_(LQ_ss1CG?x# zESZg)e|TEL=9l1(r)?j_*;Mg)b6Ct7AboO`dn?7-3+dJT#l1Q2@MKpQ(1o_c_|LEb zbVK3t!j}&)qzM1%1f3AY&K2zv^I9evK+Dtt<3Nh0?TY{0J)V`qT@`!Fd}q^>@ty|r zp`}X<`dd=(!L|&e$#B_=ffC2qa;$LTbxMZSNp|>P^R=r8-)3$wrX< zcM=W+UR9{8#u#z1jiTyha~RaiyrQz}A0JctAjQcb-?)q*$>AcSou1!3Xmjn>+Mo4k ze&8T|t?{U*MO|om&ot!}TNpDQNQSiHJF@M@C%I(k4RxIZ!WXny_p#s_>g*`O@nv!d z&8TS#*){3=I&KAfC%{I-jI$Z zdZEA2>R6mWnHA2R@xxjRFO-j`wtSiTB~nqiAtU4tEq>wQc~M4do3SS2^z@-;Di7p; zEX}S*oO~5%0?RPpK5o+`moSpP46WS*Yyiww$aAg~^l*x|x{^+9YHOZ6NySI6zkX*O9mBzj(^_ zzWDd^h+Lu)+Q&A^V_uqPOX70y%Z6llc`wN#1TG&c*)=EfcyGg&J%u_;-S1g*QAOGg@{z4mokUdkF zy(u-FXWvBLTWi)#F1El!6$0e=C)A@_L_JUG!+Wi23_jO6J}E#Ru6?6II(r>?=_j2r<=hv$K=RDFZ*TP7L}lYZE~A^(mgUfy8f06B-z+^} z7Ip&-1Gw22NC`zFIMo$Z(%%g6*2e%TJ^S0l;Ez9B8tgiL?eTASHU?5Y#+BDmWA@pG z0V96SnUxs2$Bg&bA#Bm(mGTbNl|%t^Qd)q4Tf9l{4EDf`y-~XGsfz!0%l+Bkq&_EF zZ2ENVkF>VhR|PCT!~aFydxtfdb?d`UQDDvnfdJCRUN9h1rA3eyI!GrF zM+5`}M4FNS(t^}T?_?AMLMTFLAwYysgpgneB@jry9n^Wxd(L})*ZIzM&iA`M{*fn! zr|f6%wf4Q%eXn(Of^xCo;Z<3ecU9Fh>b52p=Q_kF9kszC_ufdN{G4%<#QtEh8S+Wa zx|!y}aul>wQkbKVAy3)&t?+h=EZ~aodlP3I#Ez(B7OIf>!mr8 zSLP#5f-wEw^ry`YG05c-)78wF%brg8F;^uab_9h8BRnQat2kNvgw%$h`?-EvC-5Si z7#u0*oAP0iZd*FkmnU1-_p|$tNtd6Vxbxe+_dv3+>vyB}w-?cV$wePa2^(^#vv%XM z*Rv%J?DFp_(NNBZP|sXvQ#{=R4@ybhu)8A9G8u(N*n}+v9E>b`nOF*~xbw zjMipVHyz!cmLpkS2{aGqgX?=|AxpvMC{OEfWh&F~MuFc3N^o4qb}hRr;Um<+=WQU?9ggh-JosvUocj|} z7;iFjX)=-cPi#hRgg-TuPgKms8GrlgKUnGD=KevN{KFEg*fGtTnosh_8>8;+!q#0a zBtEgyoRgP74x*?US$vv$w3`m=qs2(hkT*_SPps)xxY%M=P|dkc#BhYdzGf?p2EZs2 z&EpIQjA}L^E1|*y^}_u%7p*ibGOk=I+2W_p*%%BCMyyA?-Z{!5sM^mgu7wsdMWWSU znL`!Myq1+WFKVur!cA_$g&$dIH)*3~?7quSyTxbQd6Hnt7s>K9Ebg9WcPPZSqvUQX1*r291IeE~hZ}zU0K!5BAr{ zIvBd7jtx1vkW1eC7PtzlE%06KQ(;u{t{c?B`IWF&v(A3S;@w3<73OZTHhbO0!+fCb z67=2>!rWb1rDehqvLK+{iQFLp2||s2DLntBQq!oxp)6nb3!-O{)Y)6$^p8`$Ok0+O zs>GS}%-P~BxM-Xo(t!p@($2ga!`pMiwD!kKBY7N3J#TXX+5b6Yh+4=}*=GW{wJ-Hu zQk$ergadq=TPO5y_vKI5p9fFqC_NT_lu{9e&&K3fdNACKU7Un1eVg+rvNu9z91${e zw|+DWDu-KKxnmKvy_mVMc{b{;frVZzT4b~7wuRr}CVFA0xSzUS1}JdejpHt3NBNiE z{LIC1tT$_r8&t9KfUo3Qj7r#aSSB+juQV#5NlI|H=Aaw|zg7+(P)h!8W*!4vvA?21 z-J`d+j8up1Bp2r?+svdOdoQDFo~#9iPlc(ZO)OmLjJ|77=4#sAu&F~3j+fme>+pHX ztK0Lq3t9%5@T10ETeNGC9SU?m4AnlWH3iN~LK(0k7smm6v+2Bw0_3Foj&nYiuCgQ zw2KgAcocu7N8>T375QWGyMTJ{rtoe}6={f&Kz_L-#M2MxHUx3!4pG=gqM#)A!eT)ww`)hr{u=8XOrGB|#E0?1b$D>wh z0{y5tm9!{qKj3C(UK5%jAzj^OVcGR=%ujX1<|8#erSSE}tSt8Z_xriZbx!LOGM)xZ zNv@6uhvF-}+j4n9TA9)?{Cw2iIE;QUzWV^5d=4a4n1{DEt9rP_IkVsSKDU?E6%F|W zw^EH_SwK@7D=TDFMZJpO>Sqrn7VqrB)1#pVJ(!SCczdSg!QFoZPoU0UJ_DEC19g{z z&QdNFgrE^C)NvCUs2wEZd)eCMyN)on`^3i<5`12-i!|gr7zNO-C0@)s2a9`E z@e^-G+%EcaKvXf6mPP6XoBV?4g)f& zFM=I51ndeIi}{TGZTuvpUb@CC5Ea2RK}S*ajdf>3WHI1@yBY9#;EPiP1|T$l<$;6L z<0ux#J^D8f{1hNX_h}-z4S_YF`B~BiV1)k*qPS)dP=p8lWdch13iiUH*PVO$IZ7T2 z$<=Fc0S0>~-?q2YK>0co#vHUYO!$gWy5~%-mMb8ojX24<&XFNje(xoP+b>|*Jib6fGKX?M4Z=VRfXgno^Qyj$I z0J4zLdd4Pab#wv8lNVn!BEq7_nu5t-fQmREN&An{_(XA>+YM!&2d!cadxg;r{8q7i z;y${8m(d27lyK=UtXed!Q zELX3AEPwjiV#kdTgAY=YsmU2Z&piCdPZoI@o$)g{TR_t>*zljgonh_=1qs z!YNHgN#lUu0(y{m*QD^$2%Y^TE* zyZ5&(0s&Ve&`oho_AW$dhHTUvE#W^SFd)Hl#mBS`#kE{8xMNZ9PY$wv;}baA}q} zzOg}r@rF0SwMPXOc=cifahz6d?itjUl*b+z#?I^jYexhXUbLR$z6<|-pHDQ@lk1WS z-LOAMNk$2wO4j;IJAu!6-8PW07q#ma@!aBt-i^IEh*W6)@VP^Hw=&sy_2*oAt~PJ2 zoAc0s=a-THL20kd4Bvp=1zLqhl_wLpAN`0n1}xVc=gk$OsUTTH6Wv6VhTyT~^Z`Xq zl!ehJsT7sH-ISKapLTrX0yLb{EtSe}x0*i?U-`E~L{w4g{oJqdD4VYrUGt>))=u^i zYQp?VKl$?bYHIlG1nN5Qh@#1A-N_U27Y`0vwO`yQx$MwjdS zt|L!dUg}-io|pf=FHb>fxp~4nn7?N*m4|dTK}?XvCDK~UvA137;F;GlBi#o(0h;nK zaDZrmS6ncZ*g#Su%*a40DR=8gil3{h+@-v6XP@G)`X%Ei=xC;?VQ`F`!ZE1( zDLEn3G%j0^J5_JJ-Xf6D`gY(6xW6jYAyk2l{#iHX&Wcu*#1ep_i~S(H8EJ@Ix51`I z?PHgJ(nJA?1W~|s^=It?!%d6NKOEM4;M zZ8!TKY06x$lwH9ynRdJ7GK{U}{>fk~bc!|(3GTK%)9)MgzI00`84hOHF9j6Hxdy0G zZpNt%8IKs1td(!h?zm`~p<@(IR7kNC#rJovQP7LeD5q~k%av2i=5}AseCizo1ibkl zlCbxI0NRCERUIF`RtQNxvfFewOhGUnwI%C>;!k~~)%yT^HMx6B8}x-ABkr~Do4b1i z&cdX*kJBEUVLAthFHZey71ZA>nw@+Eas8jvtX543Qe!Zu>WjN-2w-72%Y!iL6ko6e z^!{D%^7Jz59J`{;j9bonQ8%m0o4{@8)oV3%^H zQebrwdg7%Vg^4Gr|cGeBosg3*p{@b~ZM0uk<@ z=SVbT{Ix3pc%JElarGP%>hY$>tjAw{kfqDqdMcFndgY~azmt51_Tl4()qSZ=rloM% zXLPa>xA^0`>Iq<4_;Ac~#1x@McxX`Qp(L2;8&;vpSf+9U_TRV^yH!x4*M_(he#`1r z?R>g+P2lsO&l__%2>SvalljM?VI@I)RnB!t=5yl;C3cfm3WUmBkpftk(BU$EUn zKDLY2_=@cg#b{fNIS`jTj>iIwu=_gat)5XsB&!u$LXT2kjh^Ujc$I*IDj`wQ@~m?| z02V5((OPNKk(~&pk-fWar$l>% zf}{NIt`EggP<-tj3_?eWb7S;r)=$cuKr@(W-THzs{xykxh3RDVG!^%=Ph-bS42&Yf zi=|$&4dTlQH>VVkM@o+TD}2XJ)?fD3XE$Q3>)7^u_3-jVru?AXF*|pMHvx4@#*fuOtPRi2`Bi)WJ{dfwt{`ii^asGF#GnG9bf zod2OuAey+m<(X@TlsLl{mNofNdX3qFs1kESr+o6BnK`hxN_B_y!}Mq=>O8r;`9kM5 z6tsM#>=&g4AQY>wvq@o7}Ajb~wCcqHjDReL5^#wY%S&WUf>HkoX(8g*H3VrMKvhM4{Z4`Q7^Wro(c{!YIs?11){n2Q?M_etFB!Vr&k6UIr@i6XJ^}`J3GT zsPLU|18a;DV-}0WN20;+UyPoo3IKFojBkGO9lx9eh`^a_)opn8PZqQR)RqVW;kacF z012c6Skur|8Wz_=5C%vENQ}{u0Jr#br)w5|Q3it}Iv0Ste<*_&$D1P)5_!Ty!t*7wqHrgEx_KbGUOeF~BgN z;=iJQlgatthH2nh{{;;A=EWMDd2f}Vfb-_#;Sl!t&i(P&RIb?)9|8l5!}Q_@E^|TP za4sc!ug&ev1S3n)S zbQa%Sc)wB`CQ{2|`zUwUP6O{`LSA|u6#s;?xlCnn`&YCO`&%0spr18oB4m~Ab8HpF zL>ID0k%O%0Yao)v_qZVF318od_060HNOAl(AD!Y^njoshX6P;Cui9Fp(pfH*;d7Q@ zPOvG38>>o($6bC^@p)y!TK~~)(7$&pxB?tu$sgW5n%88MQ$|@kO$6+}#yLUcR3=#p z!gSSlG3)j!&F>KoK0oU;6df{l+O0_ge=1&%KmUJKfXE3YwqQy0-TK5qMpVa`f2t75 zmk@KgC{tB%z(?}1Wx1nLvBKKX(a%?mtDqh`w2%OLV&=JiNUkO#Ubk9IEJgE>`*A%O zg&ddBR05G(Wil2#*8CNrllG_2c)Lj!PQ5Qa4jcLNJOa0~-abh7dQVnW`CCH#mmz0Z~7GDz< zBYa`-Oog=*t+z(YhhxKgjBx(X3UGiNB(K%RojK7y|B4e3ofxY?;4t zMd5~etocGlprttF!r$Igi@fmf>uwy1hBD={=jd6VgP_gc%+4GUA=EwsIuE3Fk_(64 zsZ85OLHh&Lrhfu&fP9H0a$ANZgj)9*1=kXi8Xl~6Htvuf(3W|*_YN(iPE(w6WBnn~ z&~}a}oVsr9S-0hQWQ9@oFjOJV*hDBJ5LE7|jJmP6EiN%7k`{X3`z#()`L-RPBfJS| zF(6rylM17)Ca!GHbqUI|uJ@g!wp)`Rj}fTZXdU1?Gs3a`mAjx{V5bzsC&EU5S-Gmg zL#gpa1qkbhu;3CK1iu)SXT6jNvtHAE=t3;a#Yv8K>(`@P-6-hn>p2yaFDW>fZoT^2 zV!EXRY2f4%RM;pWW>t*i7L0zbBA%9SGO8TY7N-RMi^%ENfn8s5WOz^0PeM_Kpn}KX zbTWvMva9;QTSVN`1q+fVOp2Pgv79}A$2#AvYg{J4=saBdf)PG_+0gY!iqN1ZyUub{ zf$nL(e)SUHSq*`V!LAE;#_bU@aOo?1iBItP%>tU8yRUkt7tWSdC;M*CyI5l6I0v$f zE}9akXh!# z8$(c?f_RTd=vzVS{GlHa!C;!Dxs^?HTKk**bRa%qYcs;n2zAvCRRmETxxV@M|^!h7``_{bmI` z*9%aP1L@Nx0(|XF{?Pxw)NgzQ_0Zk!$+azPyj1yYbNSlo3qKt^u5{r2T#C$3PaDc@ zg9hqJkMO^>jb1u&$~plG`A*SaE>81!&>?Hcc-InMA=ya$DeBt$2g;g~b}G<3m2 zpW5EPY`)aSm%T#T3g&)0oE}hLXdr$o@Ag=Bzun&j^<)qI5B;7TSvG6l8C~tBTrC~I zH1}lJ!dp2utl|k~^J1~^PS)~UozB%~)+OgCL9<~$Ogq#!U8SuADJU!KX(e(Sk21oh za~JTQ-|o@EeV;sPxZ!i}>a#(ptwEx!5dbbhNn21>u$$__+#JT#=r}wV#u+`q zB1+PmmYim+XGSl1uD7vOsHRi+>0H&WcFW7C#bOZ$Ed{20QH@nAEl5LwRy5#acf8$4 zY*%9st%bE{A>{p)x8YT+_S)sfuB5E_PsAkg(s_8fw8OKke1iASz1=VsuG!Cu=)vdb z#|=d>(9$QIWT;(FpF_Qy!Yzm$4YJQ*RLfKA8}Vje_ZvHdjVKdXtjq4K$z{^ur}fqy ze&692PjzDM&bAuWlATVAp<1Kg+TYsYic#~Q&$2Tp8(}KXuD3T`G3mGnSqNncv!3eR z_pgKJU$D?|S&suEMp9QtkzWfNcfg96*^)Act>1>(Qp);X|yPrl50*yUhR>mJQ?fiLo zcM7z5?Xbh5?rYUem*ZvDSEvTxs0Q!*r#_a!+0>D2iscQ)^b2WJ6%JYGJ<85sX0L=*2KashEaZrvRs^^N#6 zxp=nFrNGX-qmOsF76Ly*oDNG##i2I}ol!a4uib9nlOTA3gqt7G!{P3|I@jS?Gdoq3 z3^l-_>JG||z3GqDmWr8UX-OtO8?4m-`x&2sIdD|?5b3k4b(z%p9hX~P9iEL!?h%NJ z+m$p~=#KjS6eZIZ>`OoTp5x$^Ce+>S1Ti?@F(CkdLTyQDrY`^Mn1#eq)PUw>>% z|EGQ*apIfDyT5@Zo#5wCHrPgj!!!TkQ1vW;L#|^8R_FB6Qbhp0a&Vt6XFX_@p$vBX z(Fx#>9)wDvK0a>XaXFnN(jC@V(1J492fAsoKZb@9o45cvb*8ENr2=>H?m7_O{dGPO z>TzONJ#{!sD*1{|jvRUfdBXMFrs`>phaTY&#{lnKz{GRJvB`5iEUq2JdRx3 zxIH}Uvic`sXr;&KCRJ6E?@UyIqIZ_tR$vh&ytb-0+&i07JL1eE$mo<@HW|kI)IPV_ zNU7!~LI>30_@rwhz~pV&2*P(WmsOR7xp& zW!!_|80ta>4rkTEtyQDRuFXw)B+sNk?+?1G zSd{K*MDPNY4vU+c;Jx0hJ?@UEU+$f?Pz0@6K!f0yw;_9VQY~RGblM;E;Db$0?NJ!H zr}kRvrjwn4$>g40p=z)h^KQc3bCz#D#QAL^4!1fzr#nZ@3c?iTbueB5RfWHf1qdeP zLSY`RVj?98uS24k?z_>d0ttTVLR6{2@r^Qg*E)1pzKvGGrcCl5o=EAI{VQ*5)l6vW zv8&-*jW<2^6xbO!o2$ASBnw?X^2_dU{Ug6b=Y%{BBqhd{quh>l8*?`tEw0a=mR5W= zV@|aZN9juHOH)ZvxjO1yL#7)JXhl!!U#=v2DjgiFq)!oSN;-{W2#zWKlcTZ-4x7_NC;NXVzt9aMMdUxtCtAIawvU{;VvW zc;URz?i9~tIn+RNQQoMoU*&vZ>i`iRo#lGQ>$;tRB*K`wn>vPdNwvb^t1R_S%e`8h zT@6jNGpKDGh@^S2NBX=*KqG4KMq}S_?F862}pbaO^zOtyFj*<&9gyCkJdMTF5mB_H~JvN8@DN=+sOI96ijh6TKl@1az z{(LjoIPmQ3uZMmrt+>u}%M-qlOy5=r-?RHsk@w@4lb2+0v|I(lvMEb!#2fD@8wnYy zeKIHrEwiRxI$0t`AJU)V!(J}mBw!+!$#U-K1?IV*h>x+P4(i>J(RMnb+_>+Ah8|u!?GNsnuhFGP(!A+h6hBYiD2(g1_GL zqdGs`4tgZ(>I=%ngUxv3+UI5g>IrbNyY7SFv3CZ5%6Y675%(g-rMgcha{&8M;n5h7 z3~Kq?YTFL0qldA5mAKMA?yJ>IIE)hF(bsEMFp5ssTVUAyUKHf9 ziV%_2%3NL_4yqXS!kxY5ng)xN=p^TvXm&PNaz@8!?C^T@rl;5_r*~4TW=yZdMoYmV z_*h+rA3@VXJ7qD%ygCru_?MD`U2w@*^~z>ZUE4G=wxzqNe|>Lj_qovS)_#W|gcc=l zj%w~uFW??Wo|~p?!wLukvA?e!bD!}$-Rt|Ju(fMiQI-O#*i$~My5yzdriUvCw=G`? z6}qB|np08U^G~KXKdinFw!kYrAY{2bM7ecczq6ck`hKL?NWzq!-*;7m4UE?dKa<~J zbSgqcZwuOEXIJA9cm;Pab;@azsyK^WonbKtGni@wJ%bUtGdVw~K4;nULr8k34ou6k zKg8eXBt^?++-qcoeN1jFv@AF$$i8J}El_ix_75vVW0r8wKr;$ea4rKAm5P52}lTZ%Y9)LB#_3kn79A;q&On zC0>Z6_p@5^k*9_d3tWlNXJR+>LJY!M!d-4{Wz2X?Z1;uqK0?$gMN- zvo%r{1Ktyh9k(cyWF)V!z8&7Fl6Ot*_==q#P?piMd@!zgWdT(tW;qbl9V67GMy;ydV{&Hi z$6iU)$8a+GC05sIqRrf^Y=C0@!NLFbP}-~H>Hz^=ag#{m3%^Xz0~3d!-_ZE;82XU_ z?)%eP5oxK|H`lv8UPLE+WU^Ta$@#NN`0aln9jR^4-QdheTWT)n+eIA!_4?jfEkM2>E;LvDTp_2xG=hebgo-$hi>Y5Wmy~h`#so z;NVpYKhKQE&8;}|whGJ)GIny)-gaZdH)vn=T(b6vD40&gcfNb#>fv0$m5qODk|aDr$W$)WeD zR&`f53k(vcm(^DXi)~OUn|0kQZ!kkCSJ#(?QWV^=Cn*BXZfJ!_QocZ049FI%babuA>SJgaZgxu%pH(#9hn3t5Me9iyOswZlfx$@&i&sXVo) zgX?e_b=v!Nu?*pCZ5m-v7KvzqcZ_r^qJq6z>qdQ^RQNI|YZSkQebvEIO{d%jYqXci zuZA+N(45(;bw!T20wD^vI<&)-`_W8$z5#GquLz_4}je zbkk+39Qu9Li>(a0h5|RTS7YrPj?D)7t+GAFhCSagSK|b%V53%^oIMfwoz1rp*eG(A zf5xY(HAgGog`M~Yq1Fp!!4n$`8eN3$80c?;vDjfm$sn9#WxK-hJM+Fx?-_1u94aIU~L#*)&66-Jk+ku3Y?ixc*WH&;{du(U6towI-v1sR>ORg_ZU&xSSLA9y}De8;&Aot+PhE8H)kse zw~wn&1sPSvmTkH#mDDuunwlZZ^>q5nEChR!d>K328t|SK6En9CpBiQ0J+0hY*UzBk zklYZB+c)!sT9i{)ZP%{0uN@Ynf?ZKHvWniq=||sd&QuCZ5$R`lWL9$8 zWW_1H*fIeIoyxRzz3ppLrJrt_EVj~|@JKZyvVZAqWRGKT5^;XV(I-JI-s_$vj6;tJ zDh@}Jd|q_&n(BO-+V6f}8C~UXgZu!-+t$#$q%EP38B)`+f#qInReZM3fbqNMInN_b ztYdZ(y;C)K#PVIn_YDC-e8E9j-P%_`&~5$ z(cjnBk25Gtf73!a)<9t6V0a|$cQP(qxSr(e76rz6KrsbbbT&;DIU9!Htu}bt(tIp_ zdgqgvzlT_yQYN^I^ZpN9V{fPOy&(5J-P?zG+7>Oojm0fzG@F<~J;v&B&33L4GFReV zS8Y%cu8E=%aH+Gmo+!T36l1??v<Xx5(bo+A!Mt01$jSZ}ys71 zOb@Q4*QRyL5=kzfWcq?O@#Ciz!GPBiYM#+0vI868{ZriOR zr_3`9>Xyw%)9cg4B(=pjKBMyYRrD(9wa@0w)dyxvmd%RdR5#fOdg-5YwYT!tHyj(* zHj?dhAnsG=h8TmM4Sc&ELcCx6rlEDbIy8}>csm$ZRFoh}&NSkoVVbu$_Y4)qosO|2 zSiyL-J;J#4<3GvX09yjnz}^ob&r6PrWaRYeo@hVV@uuy~TxhMA7cS4+Du|hLqN_FV zC4DicJI;Ny3@x3R=BP`WSy)|ERJ&OFr1` zuV3|HqZ&y^r}$4$v^8ozUe7y-w|oAYB-TFFG3Z)z_-Bqmo!H)p7s@01LGc)cv00YiG3Wt%b<@3Oq3d<+#{!E#Fl2=4&2t%^n=vy! z1B+Kl+{EGI(fEe$qgQ=pBUU5Z&&C;sUymCsD9J$|)nc#?wh-M~M~kC zKK^5t>UAAGZzp0}RnsSe)+B)`#OjfjzdLcA{Mq)T`k5%Al%AV$+&(=IUtI~S5BS-x z=T`z3n?goIXsQ_l!%w1XU67<85pP<}PP*!`CH zMp!oq(u0OW=fX$Nq}^ea9mpFk$ynadtf{94SEdxBjO&Y<>7;!sW-S}RzOIOlmf&m+ z%!F5B!GfkiD-5ylKG|n5$YL?w>WRv{@a(#-R%=zX2!(1!^?4>waY74gG`&4NRdwA^ zdxi@9sH3SE75>hrG`I*7HyRo`^?o%&)$*=d`>C4JvV1bzMxhN>8I?U;-gX3!L$v(7NMB zRgGc$)y{jOH_s-sa0Y(og{z%;Y~M4!V!zj~F4*3wo4rYoo>~#XQeAjQyITU;`J08N zNapt*EsH4=O&|2~ECxE4A~?hC49|ByBYP`?o=eKJrb}&k*96H`;w78{o3v_LmMCwn zF0R$YPF-+8ukn_AW%J$?&%isF6`U7LXV6)YV&Z!oITiFrT}*Sxtz+4h%zf2sC7w#w z!=3?Dip;ob3@aWHn>gXn_EB~2suJ*kWLpR^cH#H7Ci4bl82sJT97UzfN9(z%MvGtL z&hH5z7zi~&yxzAY*3Ptb{QM@}O4e1YBSB!8tL%wpUb639X+{pRTO_1N5y8)~)Gx)Jo&Uc`91_UwrN(^~S~2F(SnA>NPW zP%VTC!-n_C!k@d7tZc4b+!>-Yva>zdQS+0p)dYA8Hw)I`Cpp(ggvr)dI6h?~*~{Kq zBcVUUhT3MN8_tJ%29mfIB)?PD_i4LgyVE!URT|1|L3bgYZTC))y71gah*?$rs5TsT z4|WV2H?G?3)op?E6v5X=^**!lT62Eebn8yn^3sIH3Z~^uX)G~%qJ|=Hl5?|4%YdY% z)D;+vUyVMoiI5=13XiXaR3{1jUhEs(N_DN*@gb`PSi0ATG%qCt7efTX*iDCp;fogV zv5*f74$VF_!7gcRtFu~K<;$WN(Jr6fds3vT>?!R|hU|?;s}sIW;k2NNjkc;bXmD4= zW`n4GO+%Yf3vJacFv7#r;smh-xAS`)5JUJJFQ{<*!FF3=oS0ha>&ds$yz`Nki;H_c zN`v?*`zNn6KM5O+U7vbeRc)p+(0pNllhj{JxXgIhtXfiW#0$ljx-S$(e;y}Oq4QknW z-UeUy_+=|*9gC@QjLPjf0N*X)2k0-`UjMlDap8TsC{UuBi3=RpFb(DxzuzVgyx`TW z&6wQi5TBCdzr#FRF>$fw*pofa;H?7Sd&0T@h-`yh$+fS6X`&r5yL@`3*u1mY+ATvl z?#d6N?z&xK+O^t&pY1Xv}sjmU*N*6OBF}O~-e2QC!=F!cxeSxEi(Cv0a=It-xGHG!2 z>3QE`m#FnJ_$Cg8B@1Eqb_*=TnvGuesV6O&B(=_MH?0H_;YkoZUTqNG&L0Cm(2 zb+H|zip8(U?W*xQW`X`XP;w|U@>@8{v}|&UP~-9*cN~JSl$98saZ{;|n7Z8%Dse4u z|BZO>=eIr-rKkzIjF;qkX;6DHh^8ZY5>jCh+OJJ+FVWSW->JwyTR;D7ik#a^}A7Q zp;`}#?i!aDXVO%gbj@z>#ZTnbWIH-*>XBW29Z80A&%z0(*>hH9FYY}4@(8EPU5-jN z9jGpR{YvmWRMKRJpM2%^Rws7=z;&mAA8p*JWR?*}?yy|oF zYc621EMM|gi_^)Tfmn5qfw*bAwzjr4YVh@*q-)iF!pCQou7IvxGL0=P?P?b@ZQpt| zwMZ7^-nrRzx|MLA=rUF_5|&BWUCr&vL9DgAzLttw7dC7vNGZw7e3RxRd+|%K^*sTD zk#R38dnvi!Hw7Ae{;cfX0c!UywC8wl%1OI`gWklULlT>#%Ao-=;ZiyU6_-F9{S7-h z0CgskulW@-Nb%BC z_vy=jp3ZhLJCdk4>z`VYbA*ys(frclPUEy}ZK&j)gERL+NELGSy#eGiX#<#{*>r8x zoexWRLy#Ufyj0wq{E(`i)IKHRp5lw9st?v>hO<&-Sr}RJ38{>U=%MJZZ`l&^ol48> zES$w=QnOB&iPQbb%pX8#`7%h?T^p(Q!v+AW#g7K>6gaNr-neXx<{P?sC@@45pbH8= zX%__&aShycS|`vzAC}-7;2;CYoBjX43l)3V@+l?_YtyJs{(uZSV@1&`%YbU^3`i)4 zB!Fe!wsY&jc$=%J^78WO#?>+B7ZR#oH;r3ySrP4fVT67iFN5(Ed?!mHeJ-1w&8m}zaH;&RIz&I{J@Wy;(#Se>fiU}AZoJq-_h3EC>Uis2V^FG(s|S~NZD~&$G-tR_J_*+)F`QfYc@PNxO9aT z)Kui481>w39c8CYn3lMyE^nef%4+Re_h}3a`K(-L_M4y%`n1CA`k2EJXPWOa`=hdF z9aA}bO?I_(`PZqyJHoL^o>d@xXoWlKz|1QAYH=)HyA+J53Ep_*)1!3wl;8za^yZtT zsKLHn(HBe}q~TUrtldp25iOtsfU@nK|?d_Obra5*kRjP*_NM%wX#YGt_ZJU#YcYC^+GgDV+Hg*QUS0tYcjx=u5vLiYM zmcE;7DlloAQ?9f-c1Sg!SrN7Ad~3a^nzT|HodlioDgyMGnh^tnXYki6TyDo$OZ@^< zX}XUQm$`1!^9xVjcB;81Cm&b!LX+E8AMHeaE{iH#a}zrrTc|~kchNj#N4zT{#4?v@ z3U6l?i=~^jRMMMn=}ItEWIVb1q*0ie{61klPfaWBFU#oei!!)DI9l-J1^Ppzk;ao7 zf7$`k$%9X&wb^ zGvVvYb{4aP%2ZwG5Y7H7cwPDq-?3aD&96@s){b#K^HgXbljeH) z=ckq%t=1Ei7q>pRv`6$K=#uE^CpZy%Qx8GHAws2F`t;2p^C}nIKqY@B-W?{Zhk;GO z^7ABUD6_Tq6*|Qh_Lx=+Q)sIa6LE=q?Jh*~RO||TaR^pU+8M1*YsYphQ)LIN)h}6$ ziF`E`AaS^UL0qTd@B-maw!cKId!MK6$?LbdE-m^mTG}xqk^5J@K| z*4fku)}TE>IBYfpokW1$RF73m(=~>;4%#6QCrhH!2>$h)^DCBi#HwGUt1rs#AbW;A zEH-WWoXQ$ErV6m?jhA zUvbF_xw$;uETH`)0pv*^H1fG88bFC0K#fr`_7k^UlJTL_$jpk%M6ji&=795j{1uqq zvvg5iI>>5LOr4N@oDUUPcR5E$7i`r zoYoHLYgi7`gD7nD6;BToTZa?`j3>ar%*pZP`{p=tyMr9gn`)F^h-~uBGh)tKYjm-9 zCj7VDT{~Mg+jHl>dh$=z-KkeSYY4qi-ed^E=B22;*Mm)sbM>M(5)$ldORuh?5-tzS ztoiSt!7KMfKT%ZCRy%xn+5ak7-Zz01;ww3INdj{9YIF1ZuS8(2kg z+(+G;c-dmg?r8{F4c_ifKSVYk7HXXZRD^<`u8So5lzQ?#zfFLNDFiB{onrJF3casw zVhGv%q=KSoN%1cN1n=VP72*C!2aIuha@z-Oa!b-aB)%Iz$D# zFkn(2(iNdb8=Sg}rY?)j`1p~OYJ-ij+Q|7LiWYONQY@I0kR2eoNSq<=A^Rs)J&O7r z>^HZi>m-%IIm@MLeoKOW+;`ZI%iAyMrzdXjSpkjLUKq;#S$4Y!HQ=i;dfFh&02YpK zb@tW0XMW1n9vB%n(LFPTFum;Uj8^5+5WhqyzOJMpWDo?K4^lV!^mrFoK%G__K;z*0 z5o>vb8HqtnaK+CS`N`1YA`8hTEt6UqN5h<=_85=qoBo#i4Mk#ma<2&zFl;}bhgMwU zvX`!~ocVoByuiVfGu*V2y!q1p=H@}&L}-#-w-wBV{3}^(z>YYBDqm>m-xyfMQ4k#A z33tdzGN^K}&EE~03^h-}23L0XMWv39ULd7iysl=DD4LXIE0cV#viHP36=TcrJ~Vui zaFCG8_Nz)SU_qoa=j@0}G)`+P7E4-FuFF`Tn#OKUs&_h2sZCb^w{4r)5k&&#Pi}Qo zoqd*XHR0TS0>e@Pu_NAt6Dtmg!QB0vH%wQ?VtlfE&V{1p3jSimfF9B(8@dg zv=GjqGOkw0uNz((!Rr+PtWFgakw~1b9JEqbrPF{!U{E7yMOOFw2eGRbY)6lxA7tKwyGT5MrHwX4X+MKuNySZWaks@vq(g-9@NN)s@X%fEx$o0jPG z3;9j(W;N~uI(RLilOD(OzQ33zrX&_JQ=a)?J#1QCJCZt{HHPGEPS4L51uQhKrh-0+ zDq>(y{RR%>mp9;>^iH7Ln#ifK(Mg+Z->CWZuJA(b=bn$IJ56=1AaqHX@yY8v+bNZ> zD}IwFPToLY;lDu(p+l8xl3VZa^U`8P@2sD3x9c>rODS0fsT6=(KnBufXc<5}+Qgd0F+uQSZ^j_09uuy~h?FunZi> zkH@f)s6DIQy!+wGg&)EjX5L;6y(fD2P5`NI3B*Wl7wIH1snoL=G5cFqwkK~K!*GJk zKNRhLy4jAgH@M~6O5AH8^{lFHHf(&rZ%0_bkXp=k0w!dnxi$KLTb7I2-llt;c>_pg z$Y=U=LiSrJLTjpC2xliVN%mzUEm!XMiO7yGz+s<2$(UXG*0B7#n7&(VZ>-M)J0k)n zsiZF`@mS|KF2Ld3+rve>V_e(4?5~oP{9P1d%Wa=KD#nF=FZ(2~W;gtTMXXIzPy+F} z31n|;X<$HA`Z?-a)X9(Dq>7_9PMmpja4UzOlXLWEnB*jz}|JJH)Lw2 zj1dTLCC6qI`n}+fiu_NH{~i&d-NBB}2?EHzjZarywOkBureHT?UicpZT*V3i|R_H|{o{;?5^gCtS3 z8U&M&@!n>Oaqh<^A5ebKcz2$lO0jC4{_c)967?H5oLWgo=?vARE=x+2YH+O#Ujd8P`cK%|qWw9&mZZP)~B4cCt55%9mO&%j+ZM_(-bQ0aMy_e@ck z*&s^WHpoZi)3usM+PPuve>UoN#C>R>ue-52_0X_S2u6K&D~?mUct%Y_NA!on=zi}A zhWrEU#P_AX@#n6Sl#~{RG&FSR?)Uq_y6qjDn(*y%_bW<6qmfOv&6V95N)py-H<4rW zs#?BX#Nj2Shxwkmnypsp)%Qd{)`1Pydkw6_#lnLN!`p8a%4O?zWgz=DN7L_S2p|WL zCv86uvz6nS%I8;vLYerB+6t>2-o*dI+1PGTnf>nlzWY7j zIp6u-^ZW4!NuKpQ>sjT#uXWw6$)r)C^+QlyIGCs|ir;ZK#(r{g6-#a)ECpUn(b*pA z@I;DJ#!ccfICIRq6+9*LQ=DD~Mf#aX5X7+A*0v|UGLY!e2@lZQ6PGZyEdcMpCoL-* z6TX2qqy}ikxnAFqf$%w$?Z&KSpXey4S|yb)jvsy(>1UTm+t-r6NQx?tL|0o#GX~@6 z$RpDs6|h4wH>16{LEiJ&I|SeZ*>nO0O@^DP4SDO)rkLpwIH-T5>^L=CPiK5jP@wj> zbaO<|>#Y;FfS}vaHEHYQX-+~_2&gpWF6BahZ7Tlx@*C};dktO66b8Fp8PP)t3oi}{ zMhMb!8l%P*POT#?h<@fCabXb+PGxi9m=Q{-4<)pzEJw~muTDQC7rxxL-|f`-4# zEhG^HLv*?|*L7l8TN+_4?J`Rr^ohB5d-;sF;QWrErE63*j@)G0sWd&?m`!|@%*;}!*#k#&#S8Vlo9DdD<9e<>Y*RN)zw z+tjq~By?1@s*mN4^=qH2y@a4c3(GR0b{7KjZKx`0=OFHm?>a}Niu>}flO1Z$v9ONg zSao8}v)$7T##9PhZ-2XmjXXh|Jmyjy-61}`jP;DB#K-9eQ<{HJ9yOeQ z$#T~sk;#VcAJdOx_P7e|T*t)mJE;h(~{dOc>=x}xRaVQ$Q4j$T`M9gxTE z`G(61!yll#6tijP*Lf*s_ZA&xD8(MiEskYOMi}O zt|iP`|D;`IxZh>>Z-)r$TA05;@3-D|;<%+};uG?&+3Cv^$X)nIdaNZ=n%07Z*}dEwno@4x_c*ylr+p>2n-t6+pUJznsb z<5yZIVwcCz%W5?8K2!SXFLL-VJjs@^rG0V7-*d3eJV%={o!k4>yoSod?>KM-Qc2^D zqz?hyt_fzzAX84ScE7MQz*RIf2;Rg4?po-|z3@^q?>w7lnv)fmy86eQ2yJlzakZX$ zG+^ta>hBMI%|xPjhmbyqvbG_Q3HQ{s{UFyo(9~3@9n?*Fxw_%v(A4nLdi;**Yk1T( znQw9P17g|=3LMMFbitfy#v<}k&+t%K-Rmn4nl+6^Pf^)jjUS#LEq#&qUcuzadd5)A zZ)1;iJ6m3p9=FG2PI-GyR&AdiOR~GEQ+czd;haP1q6?uWyUDjQL>!*z4|oa8`j}Hi zR%sg}Lj8)<79+5l7G|O}eL`3CK*+&__+Tc^J!j9EhYw7p5*hC(B}@DN4-RTwYU+@?R_VzPk2Vca_j@#LC&m zq&tI3;FSkhp%K#|R%$S4y_*WTusSGv=v9twdRxE;cFF7F?udH+QbSzB7$YF#UP#!- za>qD-m#VJ$j_O}FHLSRsH7Y87*Z%I6q-oYAol7>Y zN%4;<;boL!M05!CcsNc5UE8TU)EnlIeD}CQ;nmU?Yt8q` z!(9h1)Cg68`x%St2Lg#mhaMNFwanCA`>rzLH73T&fPWg5AP_<<1kITS!|g8Fv@5K)g^_i@2~hS6_cZgoY61)|pAncrgpj%Gg9fUd=wgFe?Wq zh1Y6FYWf}Fe?8Vb0D(xI1UQN2d|+a7MmadvqsZk(WWa%J1sq2Mf*88@%kCNTY5s(n+?9(ONg+1XtVv%|fJ?_27ewI_+YQ0ki_xwHHu zNh>b&iAaJA;~0JD^N&~^K3Pdr=cUoh3&UHD*on$RZK)5k7-;pXrhWSgPPcSI%+FxN z`>#F~U;S(xfcU17uhuj!zF7J8zR}|Q`n0mGi`9+|?}{vztIuFBOX+Wi8qNJcz*QZ% zU1cG~4Xweq#C{mM6+z(&>}HRI9Fqx>_Za-ZkcYsz5s1BmCD*~ZG}9H4;1hEEZFhxB zSVB(n3FDn78$XuCA+A^dW|t4cnH5P48x@A30%emCI)pWclp`f|=1j#wEU?JVo?xZ z-vs$aDsXi3kg{(j+w_&{k1@=99k;LMw26*R;H*4rbkX1Z@ZOe$ZxfTZys$bJ-sSZq zVD6-P2%_^=gdJNelj7Ke5aM&6ju`}&&c6@6I2s)E z+{d{!65>!Oi_lkXE#LFzbyIsm+iqIkF{NMOj_<{OHHOSr?)@Q7UXYb4XHRW#R3e;J zP#J38)1n1QbJxfFYT8g;s}5c0aFFsKtgxmZY`ZkEC--!F4g9borhV}mHu4K?l1y`d zmiJ5SI8^a&Mfjr*soJ%RHg5>CqZey}phQ<#Y~@Egc_&+>`jG~-I(a{Z=UrC2v!D@VYTgHjn#K^ z=g7rKz75u4Iv};f0S!wZHnU4Ax#u_5cKUn=lv8h~gD+``-*~O5r7x~~%;bO=7utb>x!Bj3tB}WC3Qyf3 zRP*Asdet=E8!bRN-F7VKD7d;maBQL}^17nhnAMyg~54?V!FUk1W%x2BlyKxz`=}g1P7G3c(1|s|Ql9 zKGbA$Y!H+y>J|;Y_ygCt^OGFEl3I-XWY&e^&(7f*NJu13?dhR`mV}bxwG~!d%*)Ti zdxm?Y3HG*oQ_8l1``0-nf{5_3?d+@>zkkrcBPk4hnGU6r^n>S#Spg13{=LE2YX2x!Uj$?1U7 zVHbyjWln2MId0%UkDr5xZvVOXlqK}L*cY_gbWY)z`U_?K^V?cq>w29)osM)jwjwTT zTqtSXwau>P+eu_{+2jG~pJubni!Veo^sf&g*O%*GNrc-ir>Kf3)88atrkcIj`$F~1 z2jSQ#AX4FKo@1$f9_)*UWJNE)BTYY)XB9T?J1{w_DdSOV9TOe8JDDb=LkUAUq!MW(5hl9tQy6DCZj~jhVXor+K;;%h>R1!@$NiBV( zleG_q4=R)}O-~-()=~4!&aHd6Cx*Ri`c|}@8QT8XJX<4!9Y4dnArt^U-ly1YvapQ z$}=A?)0B9Qqgg7VWgociH(2&Pk%@TA&zKF{+?M|;ufzYz@HkPwock)~02};A9g+0p z!+&Ova8NksDRLCpvL*Vm$h~XJn@!)9Eh5?V|I3en9OSHeGRPQzXklStmv>py3EL;3 zjvz5=SvYgSZbAn18brhX=k9wymj19T}|tkccCnKS>TEOq#Q)$Kpln`k5baQ&M``t(IXUv`3k_ ztcN75Cns>_$6Gqo=TSj@u+X7+Rw$zoO)9DSa{aN#?KRCq{zx+w%-CGr`czn#62=B` zYH{7f!7VM|@NsMG&V@=5Yr!5@a z;_W>a@wTJy8E)pIRs3H1Po5I!O5@Ss&obAc1pMwGqK0krdv(~$N5F3LNom0jdOtQV z>?iT|g8BP{cL=>pc!B>K;(UlDbU8Bv4!w#yGAwP}Ua*_;v7!jwqk?1Bgh#L<-9yrH z*NNW(iF3d7na=@}|9Vp-%%E7@Q+ZeIm$W2CQJ=KIVa^6z-=tQSx(>n7e)sRMj8E*?lW0|udY*lU0d z7If85HuoGXU>*`RlY~_JC<$nfS{#)zoRu$mIwFTTaz6f+wW!Zmp&haos+gZK zZe!gb03KEsroM)2BU?eqitURaS<#js3V}EYpc9+OARC4e`>-wMtIyqp9{4#} zMg3Wr*zEr(ja`Nz+O*?Qr9jmsYn7B_e!^J(*arPR=@+D#`1cOaH;h@8a= znwpFFCXU>OpBBZgcFYz!4lmkLCVD|n-(WTs(f=#==?Rc`2XWx{!Y(}jK zIYr!bgic13vu%(l(#kE;=dUSdW)#2#*KF%8Art%`=Zs5Osx=NE)o_s5Kk}>098HKA zy~0;=WJ=b*eG~O-8Q7ryO{e|qpyLg%S5~~QJt}!I@O$x^@3C=UNhj;3#hg`8%&7Ni ze>tVa=qTvAt=l5|;`SdG&0k6}vtwIJT;`v=clMRS)2GW4&92S9f`RF@zk|XfIgT zst&kg&D}L#T2ZtfRcQItO39UrvDCnQkpJ2N+oyJJ{a-HBC4S>^Tf@SyY0#5aage@@c>H~)8(^dQL^kNTKb8e_0hT&9g*sUF6tMNJQ5%FxrpHo|cMKNb$iiUm30 zlvmyQ^^M(;P#gnR*UYb!egoF-F1j#C_!HxPSq>BpqJ;W*rDa5aK~bu3n2bQOo5*zT z3dxD@&t>7)+sC`)*2mDHunBbC0fB}Amm3?fS((crG|BA95$)4CoC!I9r-(H*%^dWa zHU_=kA%?Ms3v_iE@r}GUZ1FNd3kcvB#!||JE`-yYdjO&VG7BXf%&^GerC+_ds)k-G zle*uR$;-AC%+Igo2+rZJJhIX3oe@=LLTFS=dt$pcN zq5KaG27cEKkPUq9A~|{yWDl=pKX$!_{e}0Tp(|o{RWV;%sfS+|&eDE595YcDOh0_p zz=sHN3fdasxiA~ug=fse zePC-E2DX>1x2LOMhEmjiNiqw3m_A0d?peHO3HAL@{V_5uK*fFfagO}-%@1zLLAKw2 zpHSTSsA5h#W6&c6A>Y3ak;guLFJAf?jop0WOpMxVHRaUc1wIiTkI>khKDam*B~{9rn0d~6VC8r|9I`nK z+Nm~Bv&U*FX3ewv4pmN8ijqwwD4RCtEn5>lM7O@C;MGs%xp@q(OAzlYK23 zf5p@reBW_s{6yvi+a!M>Ss(aZI7u*TyUa>@&q!n}w|KVyP`y}hg7cT4*De?9eXgGT zF_Amrj@FeM{z7}?H!en7`9H^sbfE<=)UV4q5h+%ZmQsA*#)ZZ)2Ry$f7;ai@ z>t@az*Y#AAi$&;tXAxM@VmM!v^Q^YQS)=KRImG0=^oKTTbaP64GMC>Nd#~cXYU*KZ zYw=7h9Jr?Wb5}}9-kiuTv7y9y9=glFtFCem(a6)b#qW?TRJ^w^;*R0ps22LNS{89u zu$plEq(iG;v>iQq7FIi{#%1qwdL|#gmeaxKi9s@A@2Wti$#j#1zYpD!v72HNmmN6S zXKv}m@asp)3Od#TNr!OINMYsy($dJBP#Ceki2XSJIZQdeccDCsPHE#wQjh7>T%bN% z*V~VS=A7rGfg$*=vl|2=y&a8u7LxPa9_kGWm*z*fUg4l{gm;*Ql9&KdDu@$ zftE)q)tlrbrN@`OGsa~@f`797HdXduV!UIc&)5k;D%U4XuM9O!@)iixgp0sM^|=pc z2abn^!gb})nFZgfV;#?pYBv6OX+X`#r9G;2gcPcu(j-ig+d^%Lb$is37dt{xA~3tN z$Nd;S1|7`asm#OsZPTw+`Q_;PfZP;gQilBCF}FSanIRKo#>98!EdijWDwJ@h)aS*` zWm}V)LeblR35}62ddPWLsgf~u%=LCluNeAT_OnYq4Pj5~sC)7Og&bC{_Vk1SJFdvd zFnafssk|oj30}(zTe-kmCe>PcJ40<3ZuK$TUyz%HfUbp)@rHzhacHN})p0ye8v_sV z=nsCnc&78q-LMuTY6Pi^RT$8Ivx1K%x`@;J2}V3x&*PPM_HmF=CM3IoQ=xcBjDXYg z7A4ncDc8}yuG)-pvo_${(J8v|n82pTAM}^Q)%C@^17u?!JebH+z{DLMHNIFL#i48$ zZu1Lzel2@p0g_VD(!Ts)At#(`8K6$|h`b-v45Dg`Pyyvh4l`F*D7eruBu_aAUFnIh zDB^b&z}aI|f~MP(HeV@7l6-VYV?h|s4BI0qP1KMZcgpmm6glm>LXHeR1q;blYe_%} zO==Kf2EKC2MC$qJ5!#D2zL!@Hc0v~ubHr1t^!jMh>v-43S>6?=)I-{{5#H9Xr`zjd zKLbS=r?6I0WX5VU;3)kp)>v#2vA2R-L+g6j^(-w${^6RlBHBmeRTs!+5+Ko*xbVVm zyF6_?%KHteC6>BQOmckL8R4Ug9z|!BI?24pM>A|1P8+XWz^_IydV2W7UzjQw)UYjG z8^4~fD|#JQUFIk*naMT58n|;2Y}|ge*B!&}_j=M?2-~=svE;nl3ct?Dr5?S+l*^ru zr_hULVb>SDHCXAZQ2|RRJljEmh^c(fKCnQ?v`mG!KbnTxr8wg}WVLsovL&VuzE1V2 z2S`i%WTKn3@a-AS7P-usc1gDn#;r{3wX=^2iSLV?6{CDKyAI3it7|V$JNr?TS0hCdW@BAmAjfbw38Tet=9t%_WoLahx0pqh1B{v@lM5WPORQry5OPDZ_J8 zF*)o+xN3poy(^^Yn)6&=UyuE?_`!e_ZnsfK!Q!@n=ht^#Li)X*Hi^@y=2vM<6f#%? zfpR6OW?Az%jb$ety_QQvOvj~8+X}RQx0@H$MWaWYk@l$eiDXCmJf#gNw3A20&&vW1DVsV`hy_+b&>n$7g*@Y!S%p9A+1^rqtBNk-rxC@4=AvdBQ- zt&yz_7(t?$n&SJuTyd&(k#m%HY9!M~0j?f<lifxS^~(rj%LuQnrxKZeFeOcwUQ)t?%Wy|zZn6LI#w=4HQ-7r?&?`OH=6*lU* zWcvPeWt6v(`wUSz)crgXwnXTbRJNIM(mkp^m6~9`StQ`fW^sTYwf=8?43Z)gfVv0T zB(yL}6h}b@r46LgjmCx6clq4*;cjvNw~*qe6O+c#dGSzdE8!5=5(q9uVfUjXAKY5 zK|O56&O%9uE#!qfLILwVPQUHZj_?F*zW&YhDd#TOG1K-dTuam57nzD`^`a+FXv}i= z{5FwQH8Oy@JCQxovbCXgVr7aDJ2?55>d|Od<8&_rtJQs}W73Xsa8TSKeLiZ(jh*J# zeZ2g8SUW3J4lhz0qnd`@<(?jQd&R%l>*C<`dpA5@v1ETfe%iCVh#&d) zNOeM6ds@^*SMzeYET|TR)EL`(JdYe8cEk9CB*w|WlQtRtk+*N$|5oQia{aTwT5LqN znm2gg!2ZE~LD4#>G&0kqq`;5VZM<@QGS#u-U z7!)IkE4f3d#eK3P-tRu{5tEo~$$irLD6pM>D{5l0Df)ej>BTO#oG#sS&*WO)xKNHI`j3T$!J6J)5OIK#nZIkxF5?~n7hrvt7*~gm=Z}- zk+=sJ50j7#GX|)9;kxKMJ~()F$Z6wEn+XN)i(<{VFiT?g?NW1f#_l^#Kh6DEUKG~* z_g%WhA@7X+czIfJ_6IzCOk7l#iw_31ir$ZPI3aw-m21fqyY#xUYC2%!S@*x?Pw&fT znSP(38Gi^AVyZ;14cd0~7zi7E{e^g6@6;&PB%&$A>kw;8%FNjqv-^o1U}Qh-L|^~q z%w->we&NwKlc6R?W%0RBG(S@6;kB)>qDe+kX=X^lX*(TvxxMM<%xmNnp(R#9f(u=d ziUcwLUx|@MhM}HxCk~I%Q@gE@833|K4piq;2lQxvQE4McV5ZvKR3s$nCSF08$`u8w z1)=sXyNvI{Jad)IYG`jCHQY1pHUI-CQ!Vze^9T9ycnOS6kq!{_O=-O1xlvn?x_SG` z{9rK|jGRMODteh9U0fw3)#M{|LyE#DwqASMp$J`zfrR&ZEd658^yBHvJ~8pOiV{yN z?)Ij^v@dchC39Xl7>ZuNPi`-km+50*<#RnBtb`1Z@C_EWQ?C8N1DT8Vx94Lnfr?1J zvHY>ku5XjXz-Z=7Q+fVY1n-d$V>Vlcl@uQ8C*nsngZmmFXJxtC7!H-_`mN5!@I-*S zFM+$S?09Fp@d8mN+ji&@$_5`kSg^2n;4D=3*uaYqDrr{#-fbmlKHRb+Mn_vX{G|fF zI~iHxXa7r#eDyetjlY&ERXSA@*Tuo!r^rhu1HlnTiZ+Dk7LLc8AVBT!ytE*&8|%X5 z%x%9!*1x%%^I)LE!hl~@`*C1%O+#Lf1h3Q87h=?Nw+x&B7DkE02*mNVAvNAlG$JXK zGeGhDEKXly<@h0wI4Im`b8`c`le%#3NNT1v?ZPtO!xNtCZ5E_-rk^9@j2UpCy zrVsu0)WM;APDMQS+L8O00xHxoK>oOzH_5FD^ZP!F!N?gI40LCs*zty=c7}O@8|%#V z3Ml-cWv=P3&Bp(%!PCw#ShJXql8^}b1EY+z`GFtS1K5prA=1d#u@qFNw zTt(E?G8y>JG&q}lqek(|Md7_5FZfpxEUyX`AF+gCn}28 zix*;QrmY%AJV2WXYpzIagEmp?OSz&{si8MOn?w2$13Uqj{@=8z7S$p}0!>(a4{LGS z&D;~-vq-IP`VqyVIU?t5`{R7&o?=f-#)D$9a&W;_g|Rr(MdzGw>4YGQMbQ*wHjWH< zS)3jRf8$ri=|-`gKuclynhQ{Ks|BDnCx%dYx9qzI2rw|Pl$4_Q$StM;QlNCqX)U91 zy;{o!4f>HlbL?Yquf3ZkUoV3i8}>qdG2k&FP9bGrbF*lY?a3Xzwm zTe?8CylGQ>MyL<>NvGBvY851}U0*3P={?#ru&MR^uw6ix>*xYqu3zqNp+5bSldGSn z#kGREYn5VcPt^xe16HdF9_0VcmX=Z9K(=JIb~bv1@9JBJ{C^kp8l zvnm*im(c%^&ooM%PJNIWSr9?`%eA|SQkb!EM$}yu(~I0Q{&4!g2Oq*ihI%h!JGB<6 zO;E7z%= z@Q>x>uBe@U4D0ow?`q#=#&@GcMfZOfYi7}Kq@VMi(}=d&-wrza0_eT;nIvv+{l{Q@ z_?e}!oj}yOP@+yQMov$1yZD$!d<>B08=@*H)~qZ?lSP~G&Tgb>3)g>;c; zQ(Rp9x@qH)abR$9*KL<0gQv|kO><7r+rBtk^CYUOvaIYK@D3N}Nq4T$G?eTDJgp@f zx~~QHiCzb&$aD*!Tq;7Z^moPIbgE%D&>&Bkw0wYGkoLE|&b?U>)_=&2$^q_Ab<0_;&UBs1nE(gz(9L+Nz5}i_1ktLAUgrpVh+&EN=>!M zD?arPEg4QG%lDogHAvf=Kp+nm+jfD$!=6bMOvS3%cmkkgN)MgiMCQ@4X5x|=*Ig_$ z#rT#B#Ff5nZy(2)E&l>_uXpZWGU{CWkl61IG-o-$wGM$5{Fkf5l>kyeMD`|xc{0fL z{=7BqY6UCw`vg7Tw?)e8A@>VvRGHp?z+7>ujO#BfG+F%Rp7oYG({0bYWKAweV}7j} zZ}^h-YNQG+3*TSYD4H7pFw%{|+_1NPE(WX2l9BD!BYP>Ih5kO_P8A`)2gdbTtFF&I zYmM35To9<4!!0k_pyybKs17YT-mOrc1M1N7ZONsUK4X5`!mX3b@Qhe_oHhh{{~NoM z1xiv-k4Pc_7!cGt$9xgC;BO5R^yp|&&=ZZ(3#tn29h!zSb-dMni^$z(zMF#L*~qF3 zGFt*M*@CxSoYR94s5 zbFaW==lmJ@j3cR{=At8&=$L|DKS^u8rvsoJ5H*f_h`o_tN^g9haCCF13C{h#*zSh~ zt@&WS{!^Lx(7C_FgRxe-5Lb?3q5_qr)4|PCus{R27@YC->c#^V49+Ve6|4Y#IAI0W zZ@E}opYuQemmKY9_XFWGz+Y5L!{@e&o~ zWi!Y9ZFdCa+-}e8!)1>TheY1tiBw`=S%K_0>{yUly<8Jo2*dG;FIUN?j%}id>@g8M z(+Mvx8qB_3lXJVKwy1^_E0un3Y&eMPIpUj{2S8XUwgeoJYch*sqsWei-Ky4d;G8j~ z0!W41UNJS{elIq_Q)b{n(Y-EjBtdw#QI>VfmRF*xa=^jo|M*9pSm%B&i;e-Vvp7+D zA_gc_9NT$hk;)cjB#IW3n=-|n5dnu z8K4MB%tq7Mj?|50Z6LPdLn=yZaYV$1^zpw;HXxQ~;mOZ0WEcHTPXuDVIG!08m*IF%Kf3QcL0f)h^`;GlYmEdjF1T^1hscRDWej1_4X57cATXf&POq zfPcNmh9gB_=6b=%KY$sBvjqTlUHb-<0kjusW6=c*7Yfa~*xCS6?%X`r#414bo6v>8 z)jPAnwx?1colwX!&=)pz4KnH$JcH0{m6QJ2A40O>S_lKx2BBu@(bOkkqkW(Oq4SXc zr3y$+uzDbewM4kJqIP6;`d-zWptA6lGt9d5a`}v6=MDVfP@{-*aDD6f@^+Qd*%FE# zBoY-;>+s9dSkdv=1;7OC%m6t4pPpz^OM#tCLu`^4vw;2x#|t&R=_s{)#+|o8fBQb+ z`^|p8b?&FivtU_u`nOOE`la@_4@5r4(hUPb?&`c*Xk;{o^)+(BVbvul@*5wLUMpKf zXKaf7cD{lXZ+aTAFTD6HmgX$$Z5P+meoJRc30(>znQLhHVUs4=9%E(z6@z7EPExO? zIB8qZ2sN1fkhhhb*Ru1Da7QPnatj}+JzCfJ6Pe|B&!#mE_ z#zk8~G=Mf^Nn#>8pz_I{xwrVN?E1U?9OuLOa|?n)1EnSCVHo zR}<%m+l=NC7s6H!wCJ7q{5~x59r9MXgY!Q<*i_klQxhIX_blR2L;<={LkA|6;6~|v zaiQ2d`rkkm83>fWek0_QuQj8zU}!|Vi$;54H6?4DpV(gYw?VE%y{bwSM_6cV?;jpY z={?bOcfbsHz89{YEm0Uht&ZK$$eZBr9~hCt{D!t&h@)aE;@|(5l*ni2{vl9LYBKyX zomc<{U{*K9`Bw`iM%h@&ZX-Z8y%N6ijVk}hoQzB0b=(g3lECzdPj`_}N+_*Q?&D7w zf39y=Zh~{a5}5UY#?+?*$kgz`{+59B2d#yT5o@p5D;;XK6b2l*Oi&Wxw7E%h#|=F? z^T64<65CNk#9!2A8Zy$Ht>_^k$_lF&sZ-{|U5b6Il7=xtl^8s8_>d>W8UuRm)&F2((w_1G_o z`IR$^MtC|R>xD&4LPRQ!_?`53=Y%n4^uIEH1(abP8>M%X__*mh`4{$-2m+4)2n+!b z_zLI8PcFQ%As#rW0QTur18cI+wzHvT)nDh~gZKXl0#cOTU7#N#oHb*u)wy=A751}@srC9zzdaxngWA&dlr(?tM|JG$KVP?2j^KjEVB~~q zsvCPOwGy&2=}&7Z%c-@ST&!}c$s;{}Ad{1W;&}S!7MXoLeV9dxTiefE++~XS=1P~r zUKrCbD7f4+d2QQUroVFX(6~f?gnTaeEwqnwO3~2QitGI1Aiipm7Cz~U)QSJ|@mM*6 zm|O~Q76UXddZAIeKdSCZ-M9~3{SR;hHqlW1rz+FN{<#9b;OB~gfDU&h06M&*i1k7c zE!MHIPh80QJ>+}&eLGAhNw*!Y9lmT>V7$@S1y!ioqPqxBiI}GUl%fVjJNu)a*BjuZ zYB!dC515qG|9t9v_-~J-#<6C=IN$?H&?m|c7?D%{SsTH$)apC`IDpOof*;hl*HVMy zI`_;U3F?TIR?7e$iic_6X#YXShdOvkb3vQTNG}oA5VZl1&;*LOd(Q%B^Ws8$1~60T z|2J)h07ZcD$MZu&PO^3ub}9loCCaf@x)u0O#{Q!*0sw{S4*V{o@qi-74Hkt~6eVIH zfo0?R;!Y3lPLD{87q{tFf=*tPer?XLlOK#@HdqV52>5oS*Kd+X>T3YPDRzs>S{4@E z!cd?w8*oXnHUQiU=vEOE^FM}%e#c=Ml?qUR0WXJG&eg2K`K>Q)s17;``z7jk{+ zFm9$8011a64EOuO&+EsJP$U472?5;H>bO5%3#2XdbZUwi1m%_sK*i@58%^OjZM*h@gu+bJ5scuQj$)b#Z5hgtYhXkobDc zq1j8}y|bbxXDf;bU}X zYI<9Qxgv2EPuzC?3qb#!XzA9sZURKhTd;5!N%tP?2uZ*eY#M{|-D3XH7!|gHK%&Y z8HbbCyDYde6>guciM@=Y)~IxF=js8XH0K6 zn7?2c$=4f-ALb)E-c4JAM~jH`uXMnzkcG!akGf8AAGq-HH@TFw1^wGBglq@>o?N1s z^NJgvHBmaUS|xnjcNc{}V%iFFLih84?zW2@4-E-Pt{&d7qX?Y)=cz%g4EeI2PyWyl z`6#=miNZeljL+{i@j)-mgyK}^oQ2Zd$q~M8bl+ksY$qvavPPTmdf}Kha%HSx%UJD# z%V%~-6ccHpGAObf{-IPO#MVzQp-xS2;HX35L=aNCV~%^BcjIM)y$<`b0&3*S`rkdd z*>$7DQ}pR0fjAKhzvQC-jv)ZM8KU6X@5{n_8RlY-3TTHK;3 z7YaK6SfRkmHMh>TET21ZzAF-h9t<|YKd?pwk#OO;w5X01)@n#QU3et$;eUy^Zj{fh zB}O()^}UWUTb#U@|E$da%jDA+aHSO1|#j zbplb?3k;TS%T3CBM}jUAz%Dx*ev%afkmEedRd-79$T^%jP(E z*boY={vzLI7Gu_sI6RF%J6wSHT)_$7CEtJZAb-|zoP$jk`WeY6#~uEM^$a+sU>@(~ zNU-<|vc5YbyIQ#C(@ax2ziExwka*XMse9FDubs)*U29v{`CVqd_6x(C2B8>2!JwlV z=AM5x>ihWET@6s+t3o@Os@LV!YL& z$`+xUT!W{0fU?rCe>8QDI-aCTkks5W0bk=qbcvwbu?^PCyJ`CR4b7}+S}AFeUb-qM z897$*;6FoWQWz6*fQL1PH=~JCcf^G~0I@l^r_vUe5b*o4E;8mw$avYeGUboox`C8@ z1)}rjro;*c>%ng@Fu=JR92KX@`o|hQN=WoyV}1r%?UwhDpv4VYLmeM@unRf&9<&l> z3v*Co_P4w?#Z0QT&-KZxT2E-lZU>)ov%Wo6fH%jE47l6gxGtSOB-9JkJ0+|1_s7OI zKAaIgFTWvadyQq|^ecOhPF|~oh)Y}mTw-cwph3+2$9>BYv<>#TDRn{L`xBT3YH0c2 zwHhy#8yl`{vhYR{m~QQSeEMpD^}s{<@`_cU9Rk^aD-6(CLsc~eRb6|XhTb@t;>^G! zPcMD$AfL;3PI$@vq#(6R5@UGGVgsN732*lKx_pMb3C}QcSjxg?w{TZxYm2A34a8G! zZ_)Sv%-$Q8&pnudQzfXw+$jP%3FWs{Mw1fBpBc_3b1H)!JK>DD4Hs@_lS z2}y(}ID=I#^%~6ksIM>@Lj{>M2QW` z2hb^FDH_D&PG6go>Y@pgA!t|jJmz9%a%zkpNgmul^Iq^bnf5p@gKkHe-vXT9O3Q#Am9(P z_%NXWkM`ozyGZWTY>y8yR7d4v>`tPy=_#*Pn}4#GKY+|{gHQEk=7sqlg{6Bru~Aouix zps=6a>UqxnxZPj6Di*h4ovjZ?#z=9=p+Cf!Z5`E4<)(b+-b43Q7#{0h12K5NsXHRe zJ<$QvQH)w447*QF0#o1c{LCmJlDSscculh9WymQ58wYybYx?Up6wPWELwfhVN&2+h zm@xDm-D8llXizF_s6JFXoI+eo^wI5Ry`Ob7)_SNj%9 zafa$PnIQRIm=Ad4YX!U2pvjOr)-egwq5F?#XlY^cS8{*+d+ax(wjZbVX}4~?yz0_> z=L?-9&Y*N~XDdE#c!Ruh7vadM;%Fm6IJ#GN!u`9zLmGODhFlu;r%cY!VokmfJ zd|E2Fzifc5Ii~7{W!;irf5R7pYabQ-4U}aZG(Zna69tavy#xFz?pk1+%jZU5P?k9x3pT~x=YW#UDx?(w zH&ya;q3^rTJgNc4%Kf466tIH`Vy(wPWl@g>UWP4B+r+ogKcxc&HwG;2_2jH2CQy@txpUAZ}pQ&xo1yB z?v&-q*uj9>YYU0K@-W(73MXUphWL@y=t+Y~BK{T;DXGY%kPyafFfp>6>8ODcvQYxha8^@3W zZcYJH-qouz-JjQXg9Y8#`Fy0RoqYC8vg65?y9Bw=`>)Jxz8#ssRwhcHp4vAWS|;lJ zurY7Hjq_jf%=}?v*o*X)p7?a1j#*my6pwNJ)PaCKV%STyq7ja{V(%?kMMzsdp!`5xgKx*KA( zA;u(!lc&{f94wfkQs{1H!prC2ym13J>7o^?m(vHUHw~yb#rbr~vW~mc#sUYFh(KV# zt6ex7GRH1Pv%MK~fi=sbME3t`?#iN?zP`29Ds2#P!U-_7s7wN;Sf)U*peP`qSY`-H z7{pAb5@JF^)D}?&gMdWK5NQRZGDv`57?Y}msHmZdhCm2W@|U4ukN^n;lKgXf*SdGz z$NO~e(|I~;uXXl0`}@xR_SvWU96@Vw_MJ0de)+$HUaL+st7A+h;9o9B=*M|($1_^j zcLGPvcz3k!z$3LyXb{N!ke9X1@)yPoL-CHQg$WAw9*M!bHDA-XHh;e$3EU_bT!K zi5m5PrGovh?YY)O=rx3`LRWxZ0Rm`WFYMBF6@;})7rrTRL&^D1= z!HLSx7?-Wq5-sVLlRVBc-b>_y{S}O;aenWmHsZ?*TQR!X)i*0`UtP`p(Z=!a)(Gea zQEt%Oa)}^*UwlRSi;_iWI2%*a268QYgDv~u+ZPe1TD;WuY}bw+v*@E%8@E;0syN1;{XBMTYQ_&?j5RP7OV zy4XhXLVT&UzWVK~T8YXWcO^;JlnFljpVB8wfF_ZtHlb zz}PHg-&lGnI{O(jk(du*s-BQ#$OP!I^HIz$%R@0hz`(U|m^ZQT?I08FMq_9Rz4Urz_N9=NT?XUSvMo9kRJ5gX< z6m&-k7nc1=(VI6-Z)|SHM#Wnw49z&P+n^XT%?&(L<(7;JVTMHlZyN%U)F#{Rqm-4J zF*vGo`_2f|#aye(M}jwclN=Wb^j8w+`NK8eKb-|)SKHb0+#o4GVqBd;+@Sgtz%ji# zX~O8~Df%NUkR&)e#Y+8J(Q2H)=<=#o6t*0Atje1d+AajKAn#JJD-RGWmnkn}cfz5F zz2k_7wD|!)|0yuIMu8>mr}TQh<>k?$pviD0JA1r)o5a)$mOQnuiAp9HCrZO^3>76s ztz7J!l!rBbzS8;AdFeAI-q*#COm0D$%Zn>!bpTqJiC~0O#;2}iTWD9Kv(SyD*}Vap zl)lhZ4#e;^ha`_?EEwMn-pRX3Gv+kACD-z=&T*@&F=xiY%afXHhm%^$6^61=4od26 z>AK=EJd$vR)%{GG`q(FYgzYe#Hfd&4IM?ALJ{Y&pCWh+FlU)A`Oi-9KY|HtUXI2U# z{N&L6BDC_t*Oxk#+bX5Mk)ud!TNG@Lta_h9h_ycewuf=+Ary}+bm9h{c@u`;@3y{s zyfu&$$Rp>bODq z@m*ikaP^L?w%HLh)%&+u@Mzqw$GLJ>ZNkf=*ANa4V)9Tg_{5G<7cJ@dEuTs|Ms_)l zTkW$Yapkh9S*eEUbCx{v*BwH&$!$&?^+QTzk{0?3bfQw6)_dt?O5G z`NP4~01a6~tf*<^KP(`i^mT6ARd1%1-iz_`IB*cCq?2K&)aGC_XQX^{b==jnxz^5A z`@4mz(OpDN(DMGOSq9+i|u&T;FYLQ)BLIvt;(G#JtJPOJ;1GgpB=le)Cl&_=D}*;CD0QbgBoyEXXrc^D#2`;^g% zH6TO$<|xI^Gs@A}v_}(#?qgWkfvhg+Qm5==hl4IyxTusJpG9T= z^C-?8lH%^R@E0YG%(&P{fY7yXnFL8nWdsFYDf8z!cOs61Z*9thGxNb-glAI8F5a=}t_ zHR552gL&tZZeQAoiTtQjfKMgA;Vg<@l-CNE|EX++Gw^|pXrcYWWS+$D4AwkrE<=8h zVvJTm(npyBp9HfTcPyr8be&~FdG8(1t9851u!i{wX-w< zL`Yk3)Chq$#}$8UZt8w8(|gkClAKE>G`BT90vKb=H-eqy@!aJ858y7RUQ>|~~{8E=( z@jVO%P{|f*x^JIcUPq-;`&15Bi|orLw$stUL}t+gF;=)WBu}sy9yEtbd8ECXw%Ueb zjLZj!Xy|=%%atxA8tqDNweDl$jX6JWQQ|=o5JfruE@Xj3A-a+p$yT>xrbJHGD%<)2>fWllaIx3O?XA2);09aU z^hz;BD91-nk|s4x^^C(O?WXAtb`JKfmZvRJ7-DZ2rc?m@OV2XA3S23nmn`(WL?M;{A$h3J=Iqwb|HV9=rdD8ajK=241WJK{}z=D^QNfj5^VB+8IgbRj>^T z&%O4HI|n@2T(si{P*zjr+S7(xHDW)vt_v%xH!JmMnmDoqm7GnB(vpcd4E1A;xs!vy zA_8UCovy-OJ|{gk#ZiyLZM)!GjpE1WTFv4c=jNKUa`_V3)PY88)&+%nLQh{==XPtI zHFWZ2|KI2JbJb^E{L&MO8(0@}Xs*mmt11OI3DL7Cmm|%g!Bce4+xFFbhrIGux=3af zhZPp0t)!W;HN|48^GQLCdHTfM7Vo3mDnh9KK)y=#`tzkVYc_=XAN%1)Y5>KEXVa=4 z+Jv>T%y2y>*kJ(GKu%GDpcI=O(Lqp!p4$^@4S-ic4`2F z>31uTwGOM~&aw2DM>A@Uz-!U8Gzs??7*|HPR|MCSp=YqtID}}&N)=7cJR?{fW!86v zq{ggB!c9pOW?jUDH>~%2(Xc z{TYY}dJ7>iha$`z+)UJm#wdok)jt!+WG4GGRXU7xIw#4M%=i%Q&Rkdh34nI;xNH9m z|9IUU{=q2f3tLHYgj+^8225&rGt+K@etdW5v7fSY?Am>g-@Vq@cp$63?wh|Px&|Au z)7BY7QX%Igmw|rgVk8Rs*X5Wi!CqMdfq(ZaJlVh~()xd%pP`g_&B%Pmmu-~i)}C{} z{1ImXZX{KqOM9n!CXO;Fi2Tr9$djsJQNH#cZ@C8R$_f`ZL>yZ1XQ*#Z`(-eA4QCre z*uni7uyyE3IhwvsUebeW=4v5wxwypi4h_t68=I>>uyD%|--HkmO`@Nq5&yiY8+0L| ztHz@ax0L&2c&GsE&<=WjKb5`mP;xT*xn^#zpe|n7w%Ux(mt-yP`skkA7bp?eu(Y8* zjQ7v`ty>l~SVlP0)5g(Q&SP|P;Kb!023-O`l)}YysS+^I?C*L{(?ysvrAl32>aj!) z_%9D_yv>5Q#OwfLqnWU(IpyMSWTFeE`pLB6*XBta%0BPTA@jY6X$`l!F685HUbf%V zIW-WtKX)x1{_Ofwz)qf_Y>J_w5xB*bYx{w(oDai?0Bl+KkWzA#(k#w%_$kY7X$VvL_FhAb_q@49L$Eh_*GKMF*n5(v@H@~a3jRC7w|nFMa`@8 zI)pXqD?xu3%pP$p-TM*8neHd+lC-gMdA*N5K}H^gjCOGI{w`G;7`}G{os~iXO-n2y zGri8Qh6#1(hSD2gwIKigO-0F2pn>NDCS2SGF3#B94g9!RLNeT(5*TqzTqpYOb`igK z&%TC;fP--($eE#{-o-+%z8h4vfsvrAXvTwe#jWbXjf__s^tOzKPg*5jsS4`N!#(0B z6UR4jtHW*JiQ3Lj#4QKl{VHRVtm|Qiw(ifW8{w|>V!8%?*MHw(L~X8l&>|h_xBLz% z&k3rJT>4tB$~p3>6QdkG)gFH&y?ZLfR%&wjk$8LNTa_BNu;;?GY)prbAvW3O-S74r z7)@W1&l1bQF`ga(RY=81sN5OD*?fXcJpNRP{Nh6z$l5t-)DA}+aYgqH44UAlBIjyR zNs1CdOyv{L$pTo_0_7FjRYW1x=q3%S!( z=-F)prn_h8jyZj=3~Xv@nfr;D{WHSAsj*fH+);L>M~@Dm7#ue<9+<2wZr zyE!eiLOpl~Phm2+ZH2qvOU`UUOet7#fb(h8x5Bu0rrYg5{AR|U`D#s(+ohjK3X=8f zjG@Tef?4VW9{O%mzx&v|?+h}#6`nv(BzQjEXwiY#c-8nFwB0fwHua)*diGcOyj{wk z<#f_5sWB5DaLe8ytc;#88o+XZF*0vxOj=D3Mj_6OdTva-J<5+f6`Sff%8&ZbVUQnd z>tgxi(z>C;<}V|@l)nG+uv6ByAx~V@*VEAUw-piY!k4VpfGL-6Vj7Fv1fg7_?ZJk$ zwS$+VQ!WtW*>K4DdhX5n!v*d+-UtY;s{N*SiecFOGE;;fo6;M7$?7szOEBo$U0gO zV(iNd#yX3gvCWJb|DpGNzu)(F&Tl#Ae}4b}bB>wknde@v`?{~?zV7RDdwI+FD(|7= zhd4Mmcnz;zG3DUkN@w3M9oWzQ%#T0T$^P2^@W$0E>~Ho()2l(SzYcm{v+(BN;QO)j z#~FWtPn7+mwU7RNpDRw@4qh&vJ}wXs4u{8H5U>;PAw__kqPm>2qVmNPvL}>OfXa$M zB@Ny~db_Vr+;nn&-~c^g?&9GH@#j6HZ+1&XSx-eyNmb*7+=;6Yh_k!XiQh%Lrd9em zI8JaFUeUc1U^}0Vi9TJqh9&{U?tkWdP;^Bo^KsGllB3+CkI%e@bEope9)^8Ax9w#7 z$%fPKe(1^K%(XMUYM)LPv}}m6D9I_w3ltKk?VR6ReF=%uO_ICsV&CDNA?{qCRm``y zNIK3>k6b<=_4{L8Kv()dkL5K7fPcMU7s(pY?>zXQ$9efMHq1YbHSA>odrTX@x5qwcXbHKdh(O8p>Q+sBbKPcoJ3M}SgXl#kEqGj zn9U#;ybenhk&r8d*2-eB8vC{y2|c9n*AZ_2>G>S_t1jx~AhlN)RiHq`IHO%OOeB5i z&08pJfAxRUzjjf;r#tg{z@+oRP1rh$CP}RSum#T9%oaBGTjLOT(G&8bYI)(7Q+Oq~enJuRn z$L-Ti7^n;}6+tp7i+goZE2H0@3k%oO50nS}UI^}gyTM;EzP@@La`NEp5d<%u2X2l9T(G|fxEnFeB z)x8EJ|K#)2{QJ^>Ene4vrU6df>5hafcT;y#e0HD{ZTM z76qp3ksAl_uDYnZ$A6eI*z%%lJZ3omAKd`zUi@!8I-q^?-@0;={125b zU7<#=^Wfk2ei4~R8#4@(I~6=1 zuv=7jU@-{W9hH@pRIJXn*7i!90u^O~JaU<=e~kE^UlR0-0Hd~VEl*xeNAFY`3p+vP z^2~dxmUg+pkRNtH%IEx{Q0dWt9n!v7v&l`98Nc8=&MU1wCH1uPBbmwAXfvPRt*Oi= znq8A%#4d0k%j{lK_BZQ&J8u#X>Pm;GoY}H3mRMqU+$%slzw`5#o4d{JOd#pRZw4ju z?38@QwuWS}E4#xU^V)4yOO?DjpJ-0)i!a6!wj5Wot##TVAk0QzA_3^qJf%za`gig3 z}=s643z4$MIT`j5Utb-OoBP=^lC=xPLaJ$g>!P50^n8Llbaa=!m(<|sMj-B zCwZXZ`H9h;N67`n^_ERk$?eT%8eyBY;itW&ZO!9?VBiU_f_{tSU)_#`8!M@M9gry0 zO`4F)6Bh1L^LnM0lc05c=_RK)FVHZ=vBW6+tiGrIUOnzqgSk6Fs&z}R56*}!6mSPe zw`D_KOb5#nfMqker&a|HK~$Km4GdwA$+-8eL+ZJ1H0|H2ATPw8edpHfFk`866CVzL zQx6qU3t9PiV5K)q%IUKkFVLm4af;x6A>4Qx9-TgtX(mt0w=M75h8HN`2gEwBC2wX^ zngg`aU)OJBRK8`8k3vEsGPai@bYvYC%dj9T0hUD3G(_jjzh*z?5HR`DOKIt($$huN z)(-)XVQveAD|Dn92XUpp%Dh*8p|XUC+5&%it5t-3<(I!=|Bma&&CDJC^_=6%F#RmE zFYVjKcAKlA?=B zf!o@8Bm4cY055CK+HKR#RmKGVP06)RnGqy6;30<-8BvTMeYg^4yp9NK!#qdhO3XSx zKBAhMAEMt6a-Dxn{KysiYui>DOdSX!vi6j``Qh*V+VPmfe{{f{r{Q}Fr7kfWCq&;Pf{n0^<| zUS7TXHw)klKh|`j-7ijlsi(&J526owAKS4z)@OG$Y7w&?%vu@`*Z9YfQTcVY*z1hl zG6(uHdq#{{L9)3;5R_gM#joCPMa)NqARY(FAmV42Xn`FCx9>5!wIzb$RhmpY*5=`b z9N6y=3=@E$wyP1}L>#${dS6^mcV)3P4E1-b^ODpz1dRL)fHMSvE zV6#2vo3%i_X|w3AXIfgyG&^;xEU#?<7tIG8DFl#tv(kcU7JvY)d@<(v%*lv}*@z8F zWi;lVj@XLD(ZH{oJ8WWKA=D{dUDQ2GdTR=eKC(B=*v-P}(m5{I%R_Yy1L18->-b9a zs(&VW%rv2yYt#UfaNu`6j-^9v(jCK;HT>JmhkjY#i+l);nCLJ5@hsoy z^UtL>UMoS$Dn#d<48j7h z{J2t0FOk1w_B__08{C<=b+2%=c58~q?jM&uwpM1+DFgTIFmU73QY8BXXrAMG%Ey^% zxkPHvYjwd;%B>NBFR_B$kKqM>&iRa;f6(!rQ$qV=(0@2$> z;WFZxMvK{K9s?d~s31Tp>Vkzjb;Jd}Q*{QK5e+?i0wosc^WpJ|9<{#9_YH_2&X-`k z`rHpW_}@q|cILZ}Luxxn>#c%Uh8hdA{2Aqyn)N7O*%@`?)(CI61^(-kP*uYER(TVl z99J2k@H}a12=?)bdiQoLX~;b&H)>A*>WcL_^FS#jL7$ZVkY9IiC@sa-hYfUA^EE3| z^@nKHDF+2bByLCJX55dwlC;EZ^b}4O%LyOLGR224jX$g3P9~t&&Ac^{ShPAM-%$OF(dB+qOy`Q2V z;2k9G)aU@Fo}L`D1)B9leL}CDYK^YD*Nc=m1(knyp^k$?`qj`od7**!hIH9Lo@Gm1 zdFfz-O!vrAhtQW7CbQn~BJPfR2wzf`3pgmFIh}DnXAJiFtLEuvtEpeZyKi*DB^+%d z4)p+|Yn41@M?g==uPxvPH(9%s>8@*!R87ZcIgqn_nm2lb6I{K)-*|5F;w2aX$z|H2 zdi3@`rnUDesPbLKeS&7Rp$A^kdmK(|Y#Rf%6m0a9R>NBNsrlm~FJYpHEU9h>J@hEas) z*jSTh!;%*!UG<-^l?(5l*l#HgvE)lvySclZe+KnrQ3&ryEUc>F>e5GS<<*|(E+s%) z0Hs&tF}T|F)`zB8dEcbH(C|B~3CTj|lthFQW;T9c<+XKN+Y(?k51B_7c3U?;*^i9b zwzQQi#*H3^KQGs=TkTJ)Qsj-={`rClOq7G>#H>8YTo0OrJ4VlR1@7NNOX`Pum$)3? zFr(5A*Ixr4pdivnI<7USis&sIx-uyn&MTQha+jE``J)^$QUM5F&Ct;Y4{X(~E^JEt zid&iXg@U@Z+Pp#W4)4!t(sLed$DWadoSFKpz5!kf48ZwR1_c6T!>YO66I>9t=1c2idN z1TG=KNQV?WEO@i-EHd)h^%c}UFBShk8I#UyiSHeL4(e!sig8OVuPrX;wX$>CplG-F zr?#7wo6IN!jFp=vNW*H++Ur(z1sP>Qu71$qPAy6qrL46gtw_9tkm}%$W{ywawnSHS zn+^dxRz)BsQHk~tce`MdbJD#da@gheF0AL&pi&-^w*~zxxTmtLqP;CU0G_&$NI@EA zl+ebc(@j=2VCBrX!W!~G(r5~yPPvzRRIJa*vJFhLq$Vke^k`eHc-3H?k1JS6h@(DQ zPeufou>2iJ?nsIUf%pA%9-3^K3UaLxm`tS|Y}!zQ0zuvNM)QS5JTu6lge;KoaYBzP zrlvTF?lSsdaM1RYTiF06EA5uA?dVToxfi~VSrfQ&w9_)2wGlGBIFy|24VyV?bHkwN zYC%Q_QA8v)PhL9a{n}$mGARVzH7LlOvC(`K74%q=t6YqkHrIw9YLCOcnLfA*o1@L% zcGyz=(#^x+`E4o{b1BKOdkTM@M>a0&Cam#?sPxqlVZjZf*&iQ7qedN3N4+me8(~3} z)+J_mk!wd01#`K<7CzT~;R(E@%3jFgDp1aUWg{Ab|kZh@v2b;)VSI48jtS)u3~)9YgI)|B-z3Hrrm{TaHt2NBeq$W zc~_A(*-s7aS5oE=@P6DD?9b{*cGn*LB0Gni)8>STKQ=AF*w1LW#b*4(+b_Iag?)5z z7pd%q(C+^nI9@j})+@Bsq#t*`;~L&nVv*JcO<30EpAuQVoy*h!X4C~nR-eVZ9$D6= zZR|@3y5NUyVfPT%rjZ&h|+dHqT9UviF!-j z+eXResFLdN zs~{aS1vkmn!bzpi-s#BnQRF&pE%X`MscEdoIP#P^;tL2l15)_`j768`MXWvPD7}3x z|MkENk?@JdOSddZcEVkX2{^c#9;RoX~fPH{!;a|~zG>gWSTihqUAESyImAFH*y)YDJ#?D-czhYh= zia#rekQl_1NibQ zv`IA68^iAi*W?iG5LwsKUP@lMsxwW#Q|cns_?MM{3CS5AT6B@!Pl?vKF7@HLhWsQlN4{3|WWf+3hQZ{L$i)oIQ`Y+b4(a zMG*!QQhY$Iw`-_@rZsU1@&a~KZvNlOHpm*CS)VU%1OfKfGQ5KfR>*@ti~DjWWlb)$ zvNcX(SL4#k$$@cCss+ztEiI!h$ff(*onjjS?|D*7!2(_rKT=zj*Nxn4i1iv5Oj@r6 zL?+`%X#exGtAfXhWg(}wKI|=svjcm>L49z+PTb5e(+otF0JwzmIQ@vd&W*YZuKuL3hd{YjOey|n> z(;SWShma~`_}hWlkZ5tH)Ee@{FhH~7#Rarzm?O|qZ;c5S_spnbny*Pf+8?)P&lJyl6&JZ=&PCaqm(^Bn!`!c7a!S5L#iZ(?AF-v(z($$y zv@{_v&uymiqu9|I^WyEJ6;I%En+H_!VqIDpV14++Vnpe?R6aXsgmdJg63jL|6VbOFz$x6($R z;$+c(Ky+Iy08+{tLfm6Rl~_6RvvZbKzDhk_wQhkN>w>C_Ajn%8m_YILqkK%HSNc}< ztw5d(TyelgPBpq3#l2eMyeP)dUR%C{L*9oC9}n*dwCkx4Fls9ril2OqOtTG)cH5Sn zeC#!cY{bOHN!!*OgbxngKRh%}d*s!WWR|#bcuKYTddF$FRaU{A|A8P7=)kds|fE;ysbuKkh)E{~3oY@`XBNKkk`|ny(U5v3zv05;Kc3 zoa@8BBx9$&&S0-ep05C$UKLTIq3V&YAac_}48a1M304k9Ag89w+N(3=%Cf#KiUJ&}Hp=ClL(?wkix*1rlg>&g0`j6#Ec4z#w}YJZ}dAiWor^PUgB)t%}%L-3SallHwPBP132>BXLB zGPv=nJ~T1H1_GN=8JMr(bcI(8CeFm7p$-aH8Gz4>&5UO1Dl7+H;9%K&`Mlo7-BDOl z>EYLlEub6n#>|UR^A~#+;#53HrCMvgmzZPYg~wdl<#4JkWg_647PTzwZH8%GGf3|g zsF$r{t|s$CJq*BEXV{B6U_#}S#OY=F&oXoH$N2PAGsVJnqLVxP%?N5bucR{{KlL*B zmQ^6AA9OIOD*tWp``;6m=lkuGk$l_fb8)vDQfmv2ny0~hO;sboSA;mv zxcDgc(CloS)E>VdA7Ce&Y2;?oN1Gmt~Y)xTTR zvU(MLp;)qy^%fAwa_=g4@QG@7LL>!=RXdzfjCUBgyIQecfO3q3K621B(s{HYoED^o zfKCg5Fi)CpI!8?hcLm?S=66lQ_TK#V+b0gNbVj$Kxo91&-5idgFn!K1dlPc!T!u|%!ryPI+OD|0g%w&Q^#d!m8YL}2HhQ%hB?JC! zh6nz#JOdV$F=HS$mbGJc*4P4_T2b2 zV7qaBs$R)^%N@z%aH9bJ2Lx_3EntM48j1qsY1wXHcm`KnE-N==*fvMtx5J3b?$o9{ z5O-kA150=;p$AtWzow7Lh1p^P*In&UZqSj72=^b=Y9pIW!f<5t)Z3D`J=7(o^puyLBZNE%@jk%e>34I35#~I6lp{@9TKGhWw==Lx zBY~Ys($Y5B*(X70%d|!h1a6=AUl7=yNVTi^VUPD#8i^?sT7?8e+cLiF4;e7oG!G^! ze^H;%IV|X)W80&a%pvjpU`Gji<7$ioEzLALAwO7U?EW6Eyc+*-kFiPH4Y>)*MTT_H za}JJ-w~DB`hC7FrCddQ%2h_isd4_q*?(Ws@?n?bHlUKEt6AlTP6%yiyUot}*-IV( zrh_)Qci#Agu+udbib)qL*&DpSu>ggf$O(*_e~}z_qrf%8(8Nt=(+q;<9BMm5+l5Ej zNQvx|2){U!&x{vU_&jM-^G8iSfa|Qz=CRg6cSA6?J2B8Kd1IOY^b2_EX zyg&-uKA#270u8JiFpgG9UJg_W7O$;7`phIz=f z=(frw(b3Qk$URkX85_ps@INw&se!2wppnz|`hptEOVQ~HlDI*k9$N}Cc8zonDrVwH zl;lpjcWw1vpkO(__O`53MMg;mA}`dhNeeF=h18Syy)`fNJ>HfhxPi%TYNg>~g3S(WBD z`_-yte#Nr~^&D|ZUsRfa7US)d{jvU$|IbrssKDga1}paNML#$n&UtXLAtg@o-uEn(Ep1G~cHN_Jp~1(vu9X|D zrXMeii?6tyX2fc3yN)_yO-;UF3*1)tH$oqUoXdWcDn&PBR^PsXR2H2iT#SkSW35o= zi$&`TL@`dw3UT}_;cOk2r-Ll~k!@hGohRN549uKrEU3Acpti6Fe?QU^2ciMgm@2f5 zDX=GAWsR|$Uba2K1^W1HGsZ#7uYWSm{apK2?@>V*X!;Cw0eH~^bRkc^t zG{1el3pQHkb_HmiCFewtu6QIy`2SQ$x~KWd-nf=XQyU+O8$EB>{T-f>P!Je^q@zWY zkyX9js87S28;=OT0QXIKho=z5W3;jpIB@Hm^#CSZP!~1WY*50-3zQ#u$C#61CDZ49 z@G8DdCw9153n*IM!;z*)8581rO_Ks_jfh>J?);({9|2-#{J9<&@TJHni%UU*JL`^$ zx&Z_@-@7zK*IHxw$GvikuE?ps@mxgCu#8s2PRnpy6gZc!`0yVtma=|sXJk2Cfm`to z|G=1oGZ?H-LpdACBxiK+ryUjsbZ5qy-HSF~xOSwHf^5OC^W{4v9r(>K0a#TPNNltF z>!8>khc}t(1f%IJ1s%m%sUAfQ-(T_HbC0YHt4DYkUB&~p7Tb$a^fA|CNeTw1Yu+npNk1%dOZ$kMVwZLLi zQ56ka5gfm3kDuJE4z^ehe-z5p=eYQ!68GMTbZ54|lqkD6g)b|=;KulXKx@U>dDt3{ zCtmYEypwEiaGSiYz|kP1QW#M;@kX5g6LCqTScp{PQb*tc?)#QiqJGZUg0;EPuUlpS zY)EMc_vWy1|A~v`%ZJvvI-hsDV23N>Cf~_hw&*BFS3b6qRU3ToM1-4h347runRxhe z#y4&YaT-Z0M(9L~NJ;zmVYNix+|_opAxuDLqv-{XaA;UqvO@_mSMxSAPUaL{6=Q;5 zc>UIO4D~SRGJX->54y*;0Cd?8Ig%q+>F@kURt6qpb0ivldHxCiGnJ_ zjNb|zxz>u$^n0#4FInhsiq9*R`>4HdIm4*iS%R(oQ@RI><&6~F)0>)pD(Rvwh7X=* zCeS}z4x*@pIb{diA`)vhx?*CtdK6V<}x&H5Zdq!-)eF2PqA~C=@`aB4Q(D@Nws6G2t7R#c>7runX!mLA{g^( z=|wwDjeYyToo>mQnS^GDniK*};@^gJUy}&oUScOs{p;)M(h)2giI!*=oU8+p-7?x!`}rB2jOh4nLsG#A@yeRqHw z9-954Hza{9JNlWn>`;ttpl+l8dON!J`Cx|3Nbu%)$HJm-8I1K|!O47Ev!Sm3^TE0VtMc5X8kPMQoCJKD8YKQF(3Dju3<3k|@6h z&qeV&vE^~d?xWs;^wMu)$Nt6+u_0)E;o^`v-CIq^_g7=fzgAa9m^cjmh-323ZZ}LBT2g;(@Yk1 zKy}(FXw7}YcMspg81U7@K&LgKR-WPd{A0N+axN(#_|V~f>F$?gAQ+*sgXMdGqWYrm z;l`dZnMc|9v`z{e{K;;$VcPT{kn$DpbxktpMl&A<~_P$e-@O#y6Ay$HsYqcloiQ zNeO&Rj|PLid!@y9hF}>k@X=jIxRhu(9X+*-A7^w{UTD5>0hKJzOgb0#Z12~!@6)m$ zCf9Uj3j{k`sE>zc2j)6Xknd2+x>@jm$DI_sLbx0f3kfcDK?Vn^Ac6^_3YbFFG^88O zB1)&SaTm&e<2Pn>Q5xdi7dbLR!=akPq^}8UZ_>q=On~I6!Bm`2Zm5bI;PH`(e>^$9~ zorLu0bm8%H2OoffPn_cqk%fAsduc+4{bXP8_t`ZWloY1QpC*hD;h#WWVH$4*-rZbT zaSzRVd}Bi{e=cx5;^YV430>5@e-5YbP8r`c#EHs!%(T*&$~OnZ+}r^|^Cy@#($J+)2! zH!>_$jR^b)NYitM`i>1SNE!DtBIE>u)gjGQkVo1XY!FEBb-S3hz1Po@%ZXjZ`1s>3 z;YR{_=`#hz302G(#Mb22B4RtJMuH8DdRC5M&O;ji3yYQb%WQx8BgR_IfTZWE!-z9$ zPqaYfsjYi)`_os;3NDfz>+>Uy1p5B(@LUpXw#<4{-29F^c4Ld!*kT_;I*o)R>1>Vj z-*`j$p8~TOT0-^@Myng` zncbIe9gwX!sQ7(!p4iIhyUHv zq%LZ6y(b>ZJjh|YhYg6$^8TAAPO{{8dyHZ6d}EF$*jQK~_upc_Kg@VG=G9TpJ?e6! z^>ED{ASf|p7o?3#{|z`QTvwW1Zmf56zLG$M)YF>8R@lJK zJF9)>cJ142yr~a;*HH3gN&4&wiJSgE!7-7!(~q-*&dPzU{-X^%M@It=*;VjhQvVG8 z%*Hv}nm&+cyMRgFT}Umv=#EF)y`rD~Ug7UN{NGs|{S`v||I>kUM=^#4L~M-sQ}LA$ z5@u^!;W76nw3`sVRnA~>SMcTlr`1}|CeJxz8IfbstRxmlOJ#dA}NybAj* z)$9ee78`NzQeVf;C>9kFQ#FkW{#bMwQ5@+QxEc?272ERi^;HRK|59T}xi?VRlK`o% z15lpD#=Xbhq~|$aEu9bS$XEKbPD6jEP}#=~Odv#TG23eP&3^d!sIw(Vz8JEI{N_-V z3MpF8IJ($2hdT*f@Gy3>6}Grwuu?003chrcOXp(xyJEL{w8FwQxpRe2vT5C$keIs1 zgtsjBp*O{iO9I}V(X!rVL3S$dNc&_qg5a8oTUVp~&lFR?!ZlT!`J#|-S?u*N2Zyu1 z4!K-bRgG#iSk9{eD`r2*PZYL4872pUBEgGbzaE1J)UMCi?xw9kil!Q)^uq>V)3a5K zedxlEWRKE<2Dr!$(({*l-t)jw5*SO;U+RCl2G#UPSC6eDHnFjY6eK$|;PAZX6J|_1Ns&uB z2tBh+?Dw#q46CS{2)e*?|GwjbT5x3>CN@Fz$C{mST-vj99zJT6{iTTuQtSQmA8C&E z*;d+vck3@J){-Up_!gw3-g(=trF_D|IP;TdD6GqO{gXi5b_{UTtSE23(5>C zCn=L?JxQQ{&VVK6f+{r4>oaamN2!&-xMK@?S9@Xq#x9XY_f$1_to20e=Z-O%hT@5Ly}fQq4wD+l`4_}RA(Hb zsj44RR`%SN?yMRELfG2nRDDOY;j6YOew~J_im!w(LmVw=PK`P11pQW)U%1$xD?#Ws zDLeFuCfGEbHgP(YXj^^t)1-Ydc(R(KAFyzt9&@kSrTQGV#1S7$yeUq^ogXafvNuhh z%~bZ5tHfCy@;k^=2KKhUd=GC;vf8|sV{4RCPLL(_=C>(B?I#xTGkQTcOpvhuIZ(vAC;(EZ(MfTVSEji{07s@R~*8ndwg%hAw& zZ70j)H=H!@5gxJB9B#qm_MPSnFSYf1VD-y+A@0(vAft7+s@E28t`<|u-sO+Zboo(+ zGm+o5k0BJ)v9EEEro~6wPoSovttYbR>O<*t1BQ3Yn|S;Uf6w)Yp?#nr?b}*Bd3?=$ z`fzRK?Eorj(rOYRqH`9Wb67e?MD)?HM24CiYR;d7BS0oaS9;`TQsaY~JRWdWW~x_z zq?3iMM)iGzm6hj$a|YG9r7t4oPEA+O+a66o*FW9?GAgxraS9wA{5O{REFOhp=F=DiUdbmJ-1&u{Hu{DAszF;aG>IS8f3)F$ylsK zrTh7htlHLLOxKN#+d*sIwU%5w@e9@?V0^4g11m5?wIe+zDGy##D)HE@b+H9z-*o+& z6@HOXY_uj(CaB50wG8f(zM;{r<5CAYeBH`#T4bHLPl2Pe)O#(+BaT;ih_xPO++DOa zq|7XLyg$FTC2rB$xB4x(;(}94^UyU34DV<~DWbNXor%{BaBwUd@;b3`SD`pkO}=*n zm(jHK5xm|sQx7LIs#l-cMHB9^nRReRSK2?@NqQZotM!ItwOz#XT!vurrhvyiLk&C^ zRruDn`m5bo`TSkHvSlimAn5F!oDC{?$i&2pz&4V252qdGO3yGU%`~=2A8DnL) zeg)B<*J<<14b+8)Dwa|J(6p*AX+itlXWzEBMLr*R^;WA4|NJfJK9wsq4d$&g;-I?Z zK$k+5MZYdDyt~0E{=MqFL!pQv{7`HvFV{#-GV2Km#2ynF}7XWCZ$*9+<4(IOG- zJ?3)udb0YDbH4YZT;u2ume&C{Z$x{QJQ1wAEoy2Jp=y&ENYRMbza=<3Y9MusYV_Lo zXwNw_{(E=Dtg^+kq92|jQK1N;1t1fMNpFXB`g=*LZ8%Yi5r4xawd|dB16y zjGyI7@6G!L5IXo+_Sv*|-%m@WSZP=}Sa>$v2a=G-n$6|OMKHhLZdeW1Wftigfz3=^ zt(Xl^`_m@IzX+de2t`+hDkHRiSYB0jsjb~RxuHIbQArT=I|MA84ZedmmTaXq)tdEd z>`OmQuJ!YNga8-EaUVBWk(I3ARp$R#x~JXyO#E6m&-uv@#P3flFd#N(bWsailS6@Q z*mDkojr4%cqDLU+{$hJL8p>|7LtcZ^Cg+6?)|`+xFJmwpFSRWTR*gQKixZr}!5t_~ zwl2*tz|FD&F4T!Cm>&F|J{@A!pod@0?Dk;Wr5&lc%AHPJp-Bey8-!gDsX%ac2q%ZL z0g&?YB(^ouvJQ%|VSD{w9->Y3OV_wFa5?xJ$Ue+kMc;ld%XhPb_wh5nlEN+C_Pj}t zkqJr5clDd@&V0{>unnKWV#B7kv0}4$r8l~$zt!9h=rsG~^}A^()(RtwJ*(M-1ISNa z$5-fewix*nh1YHj37vx00v@L}-^b@OJu?$CViH$Mapv8|i}TLT%Wie^jf0*A@f7_d>{pmn#_Q(&s1}d#> zh4%~S`%7696szH;J?~~sY zJLrK6)~q_NWxSx*h7oM}mvt?LzE{WJRkj@sT@Ff9vW9lNTI&&oD5FP8>lhC~=|aXz zmJ2nHT5CpijM4I5MLPa)F&a;9|$)$sc^bws;Ehj@%)o${oG)GBp+^#g>cd(!rBF zovt^acJ-aB-8K`C=xo=OZC=z}==?RoCKtVVeC~1v{j}Y?t2ho6k1mQ7C+d^Z<2~)Z znI3)#B7Z?`E@E{nxlg0*U#2gS+-qtdW@`Ezi+b;0w0+}X-cOX?Mbu5KEeQ%vH|ya z5ENL+bPN5#i5UET=dA>6(j@g8rp^ah!BMBGB+|5d46)Q`R1V&m9qyIF7l=jTa#O?LeKWQA1s!d{EEu+~?a6uue4vo9TI zwHy3x891<&@()$%Th(Kq#3e?P%o~+^&t@0S2fkVDKUY&E4+XM%f@ajQ_E(q?>N|%? z`nm^g_%Ki|u`zK&q`%r!(gO3vsYPX`0$N3UP5K`0?bGQ}cLxWVy}hb&Xj&r(`%P^F z>H!|9)AA4%oDxyR#<9;g+%nmaX}&$Lp_RElt6uKMGs;c@79eVA-ZG@o(HhvoT}Jwo zAquif3%Afc;Gm0Qec|E=L49K%x@*u_dXsrHFp0eY;NW1VRWJv(b_1E;N8$w7CRmys zIo-;JsmNgZp*+*WUBw3AfmL2%cBwCpyRp%ZU1F!+GoLY!k6++d*I#ur*-Z*u+C9v8 z#3vB+J1pnmP~XXwI=AiwcXq+FMy_j}^@l)w^?!wRle>p8VLQ=Y1i$3XH(c`t8;b<2 z&el?R^=?j_gM+;@zz)@d8S|C2R7ky&?w{rCLq{_OG{iOo`L8k#px`Za1aobm4X+OC z^U&F6w;%aDq=y|}=6i7O4lsmshj@+g*QlktHA^*mW9R<@{4bBw{?+F0=0Ql=By(#4%RW1}wcbq2KD%!elgd8xUrCMe zc=(#3>^80aJVvJj5?*+$E~r>di(e7}!++GIf5~@X@;JcK5HJRbHXjG{FPy~AbAFa= zqi%Wx=iyRn5d%qTeh!_O2Oj5E=Crtzp`P%(fszW`pvv;yvS01ZSceCP`;ge-W~?4U zUh;<)s&xOH1|X(!(2rh=@ZTB)s<~pnDPvQ#^*XcozkjKqB$w*iC_wtYKL4In2s-Lw zvMw+Qbxez%f}V9{a&wsMWuKz;cHo)XOs$^ePcRASRO7}(-NTtFmr`DWiadtLTml3! z#iCSH;bg-ycG7J5DHi(m1>z!h6g{+(pf?KF*&=v_1gT+oA|@p59`gb9`t?@ujgZCQ zRbNG}S2=Q@rXTuUXt4F(o3tc}!xP*OPtd?@ zkRfjA-X0c1ak$<%1C=*|;8?n|BeW|0`=}$#P)cFh9~uwCOS8BenAgyBeSG-1w_>T3 zacZnHfH&jR5n6+qmPC_YMl))Hl0gmoV>?BQfqO(0Kl&>Q!ZmkyyzxkLnHu7_q>lC} zZ<_G5_e_FY)13E{>)t28lGrR z>SUSANt1g&liuWl&Fi9`OFl)9oWXNC1?_FGQZwP{HZsRWrBn{C6bF17SlRm)Q?=1_ z$q+YucIf1F$rK>E-P^-%1SvYhy&NZEmSQ)r{@&!Ml{i$?sA})zuTu)%E~!02ealr& zgL@RKc$z|<>V;Zem?MoTN&6xt;Uh+ z1c>wVMz8Az$blBQTZGh_#`|awPsxd1UVHhl+t;iB*%wV4Bk5`E1*yOvELy;z!bdy^ zA0^wFuhHDAiVtU@W1Hrf5kxR!!RASl5_jx<|B~BS!0>cg)_QqUmD6k)PTd#D+uq|0 zHy}KkUs(12`Jm~^oYiD_#{(C?R%PziTkA7zXCV3Zs~TV}&5M$$=ykerb8LyePGn5o zcku1J)inT-&ll$`BW{`aBQK_TYju#+5Is<_$b|MrVTM5}2G>oI;wplsl20p*`}4~h z5~E_;RZ)l2^_~y*zuKyQ3oTSBGHCULX{ZuwnA*2C9%7h*$wVHeB+Lvh(Qi$p>D)pH z`ozSVnUp!GW}yc(R{OkS65{7piO zx3NN9w@K+Ay}<{Q+G~a``O#az2#;ctL&X`7%TCtNbz%VJMvyDh4R?2S+m%H z!(as3yzI<+hJ#s*MCtL3=5X5~*lgQz8~h4jo-X!|lCjMsUB(fAU3{rZ5@e3|7BbPe z39-@iHHSK9dp^U-^7mc~t9uk&%X%pl7pU#GL}uEultYwdrG}NXL99`YdqzUen#t z`uxRd+nNW)lOP?~P<8&a!sdK;X=}9`$YY#lKHKjlPN-)2tQ>6O9;H&Uuy>y@?VD#5 zW}D+*!HHv^=Dp?sn;;*s?GecWojSi{dIj?Q+(mA2n%Lvu+3YiBxx7wxeS8xiF>5SW zQNRpZVDc1_dNb&rE4t$I2SvlThgKwXHrlNa zGq%q0Yr6K}Y|>&#McH+h*mDdC%ol9Ys{Xz<>RZIANuSd(8(Qj2|1TgQ|3(kznA6U3 z$6%1xx}Flts}JT>5DXf!zNlu@5t<)b;af%KGJ8K_43BjD{>7uaH={(^CwsO8H&1Jy zKr2y$JPPhsV~582=^gIGm7sL5Lk55}UmY}HJs6X42i|qOxG~@tZhqS4=$run_2<(; zJ~4i=ZPwSb7b?dYUWcLUq>X-t^IM1SuXF&b(4RVPxc{e*YmH_DO~YC(txGt&opv-X z?dfR;6^b?pYNlzmHFcTk3@RFCl>`ZbxFwNobvU~vPTIN*k+h?>tVk#kh6LRbiwF%u zA}&qIR7C1taz=Is92{rCR(-apSd-}^rA_q^X@NhM-Y9U2{i9&19Q2YxG{Yq zWw-60kGob2dov`iNCzryfxF@KW2=8WSf)do-FR*F*08E+_Wn<_Yk8YO>FiaJ83?5BtGw3@9^w$ejAjZWWnsjughzI zow;iaP}z7ZORC^@vcFkT_m}!r7X2L-jA*`VYyZcEEbL$)s(=*k-|Lr9-@|cfmfe@l zst~xwO?=d+=>{U5axSTT`2MZMKL}sg?!$((jj4Oq+d4pe;L`5Fh&e#!`C95x|__T{j&n_!gZ zc1~LKOq`H+da48`%R=Pi9Zm4|W`P_7(_ZTddfZ+CK=)4!3|p6c?5id9{2R6*(dhzQ6wuwml#_0db$Ornn&*Vycw?TQWbX)M z;nV))VWrDg)bhu!OgAQcWeVm?QOA^{{LF#WM#b~kr(^i#`I4|16`G#@5162ufY7!^ z-UXD+6W_hkhQ4Df=RAmca1zM!Rb4fCT=GYc{Lbu8z zBy}iang&^QzjoY5j3^VmPk^@H>{Zn{1>--H)M0;VH31i^Ui#2D2yo0O=`VN0cjK9o zf~E6Tc_lvBUGxTO6vHH-g=LR=t=%5#e-PuH!qy=jvV>=5h#-s_wscaN47;_`>~Gut z>*e}liaJ5|`io&qRZe7A8&djQ!y>3=u^P(!PJlY$9t9v@-MyyrPOx36G3@^OioS89 z8i7jCLhga6J-w~b4=mHhq}I-Ba1XN_f#vX`JEHCk`+JYh#Z$*5@2rE^K2kSLVEj!f zFQ3fktU{+zasFAAE|SbT?L;e!NC~9oC2?DlSt_CbYD%#jy7!Dyy?L(dI}1q@Jgs(m zAY^Z{HQdKetP8c<7_9QZv1T8s)A0b(;q}49Le94ej+?$#dCRVNuB=Ws2CmrZ zl`lyz@v&$;u37e7KL_u%$B6kWMR)lpP-35sk9U-NquAhrFTwlAR5Qfy%(=DhY z+Yx6ZBn?c5Y&5%Dc)UF@x3FIqoy!kmE6O zWq&0>-HDadp)n|ADOs9q8Z`yJj;(?4jX-lO*nkr{X=knRD0~1vEB-DKrl4oMOl2jn zL-smJFEy4zWK>74vO~SL27M5gzfr>)cWAy51~4AS<8j>NVj}G|bBX=1rH(G~DxUxk z@i7eRzVIKaakuG$p)*Z{;Y~xZ#V9@~Yyd+R zk*A()7a^c*6+{r-J#>3XzbGsOI4DM#*&L4R>=p(``l-l*L^Gs8^qA}&nO)GPApOvG^mV*}4`^tHx- zV!iem(A+bY`K*%Q)=fr5UC&zeC>(Y_@^&{sxc==<&TVsf2;gIdeV38ddpzfr+xCLr zYrULWtXEk7dtm)N{=Yl=za9GD22*L90-`R>|38Ll$Y3oI4r|1}b-&@fpMCRM&{f8j H=m-A-P=^vE literal 0 HcmV?d00001 diff --git a/docs/source/Plugin/P102_ResetEnergyDone.png b/docs/source/Plugin/P102_ResetEnergyDone.png new file mode 100644 index 0000000000000000000000000000000000000000..c5d3f366e5c07379dde01d67a5549bd3b03d3b57 GIT binary patch literal 13403 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 J+wVsHopavv=aWmX+}!tk+su4t=KGns^YjkL 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 Date: Fri, 8 Aug 2025 10:15:05 +0200 Subject: [PATCH 06/24] [P102] Small typo in documentation --- docs/source/Plugin/P102_commands.repl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/Plugin/P102_commands.repl b/docs/source/Plugin/P102_commands.repl index f8d8a7f35..caac65d7e 100644 --- a/docs/source/Plugin/P102_commands.repl +++ b/docs/source/Plugin/P102_commands.repl @@ -4,7 +4,7 @@ " - | ``ResetEnergy,`` "," From 0c1cb690c452b4866b5677cea1ae09407656d89b Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 17 Aug 2025 13:28:13 +0200 Subject: [PATCH 07/24] [P021] Emphasize warning to prevent saving settings too often --- docs/source/Plugin/P021.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/Plugin/P021.rst b/docs/source/Plugin/P021.rst index 3578f33af..ab8884f95 100644 --- a/docs/source/Plugin/P021.rst +++ b/docs/source/Plugin/P021.rst @@ -136,6 +136,8 @@ Sensor * **Auto-save interval** Here a time in minutes can be set after which any changed 'Set Level' via the ``config,task,,SetLevel,`` command will be saved. This *requires* that the above setting **Save 'Set Level' after change via config command** is **disabled**! When used, a setting of ca. 30 minutes, or even longer when the Set Level is changed often, seems apropriate, unless the unit often reboots, but then that cause should be investigated and solved. The timer, when activated, should survive a warm reboot. +.. warning:: Saving settings too often will cause damage to the Flash memory of the unit! + * **Extended functionality**:sup:`1)` Enable new functionality. Changing this will reload the form showing/hiding the new options below. * **Long time span**:sup:`1)` Timer values are per default entered in [seconds], enabling this option timing settings are tuned to long intervals using [hours] or [seconds]. Changing this will reload the form showing rescaled values and new units. From 2d3996923eca1c0f1061facfa76a3fea46e8de61 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 17 Aug 2025 22:49:13 +0200 Subject: [PATCH 08/24] [P039] Update SPI and GPIO documentation --- docs/source/Plugin/P039.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/Plugin/P039.rst b/docs/source/Plugin/P039.rst index dbb625303..3fbcd1bac 100644 --- a/docs/source/Plugin/P039.rst +++ b/docs/source/Plugin/P039.rst @@ -54,7 +54,7 @@ Description This Plugin reads the data from Thermocouples and Resistor Temperature Detector sensors. You have to use an Adapter Board with a respective adapter/converter in order to read the values. Take a look at the usual sources to find such boards. -You can only use ESP8266 boards which expose the SPI Interface. This Plugin uses only the Hardware SPI Interface - no software SPI at the moment. +You can use any board which expose the SPI Interface. This Plugin uses only the selected SPI Interface. Nevertheless you need at least 3 Pins to use SPI. So using an very simple ESP-01 is unfortunately no option. **Basic Information on Thermocouples** @@ -68,7 +68,7 @@ Wiring Basic Information on SPI Bus you can find in `Wikipedia: SPI Bus `_ -You need an ESP8266 device with accessible SPI Pins. These Pins are: +You need an **ESP8266** device with accessible SPI Pins. These Pins are: ==== ============= ====== ======== ========================================================================= Name Description PIO NodeMCU Notes @@ -81,6 +81,8 @@ CS Chip Select GPIO15 D8 Hardware SPI (CS is configurable through .. note:: Write Access to device registers is required for MAX 31856 and MAX 31865 devices so far. +For **ESP32** you can use any VSPI, HSPI or User Defined configuration, as the GPIO multiplexer in ESP32 chips can handle any GPIO pin with Input and Output capability for SPI. + Supported Hardware ------------------ From f9c7ffc8f35ccd18c745abb51e9196232fa6afc8 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 23 Aug 2025 11:28:38 +0200 Subject: [PATCH 09/24] [P102] Don't check non-available values for NaN --- src/_P102_PZEM004Tv3.ino | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/_P102_PZEM004Tv3.ino b/src/_P102_PZEM004Tv3.ino index 22f431a69..627988306 100644 --- a/src/_P102_PZEM004Tv3.ino +++ b/src/_P102_PZEM004Tv3.ino @@ -331,12 +331,15 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even PZEM[4] = P102_PZEM_sensor->pf(); PZEM[5] = P102_PZEM_sensor->frequency(); - for (uint8_t i = 0; i < 6; i++) // Check each PZEM field + // Skip non-available values + const uint8_t toCheckMax = PZEM_model::PZEM004Tv30 == static_cast(P102_PZEM_TYPE) ? 6 : 4; + + for (uint8_t i = 0; i < toCheckMax; i++) // Check each PZEM field { - if (PZEM[i] != PZEM[i]) // Check if NAN + if (PZEM[i] != PZEM[i]) // Check if NAN { P102_PZEM_ATTEMPT == P102_PZEM_MAX_ATTEMPT ? P102_PZEM_ATTEMPT = 0 : P102_PZEM_ATTEMPT++; - break; // if one is Not A Number, break + break; // if one is Not A Number, break } P102_PZEM_ATTEMPT = 0; } @@ -376,13 +379,13 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even // FIXME TD-er: Calling these functions is probably done within the 200 msec timeout used in the library. // If not, this should be cached in a task data struct. - string += LoRa_addFloat(P102_PZEM_sensor->voltage(), PackedData_int16_1e1); - string += LoRa_addFloat(P102_PZEM_sensor->current(), PackedData_int32_1e3); - string += LoRa_addFloat(P102_PZEM_sensor->power(), PackedData_int32_1e1); - string += LoRa_addFloat(P102_PZEM_sensor->energy(), PackedData_int32_1e1); + string += LoRa_addFloat(P102_PZEM_sensor->voltage(), PackedData_int16_1e1); + string += LoRa_addFloat(P102_PZEM_sensor->current(), PackedData_int32_1e3); + string += LoRa_addFloat(P102_PZEM_sensor->power(), PackedData_int32_1e1); + string += LoRa_addFloat(P102_PZEM_sensor->energy(), PackedData_int32_1e1); if (PZEM_model::PZEM004Tv30 == static_cast(P102_PZEM_TYPE)) { - string += LoRa_addFloat(P102_PZEM_sensor->pf(), PackedData_uint16_1e2); + string += LoRa_addFloat(P102_PZEM_sensor->pf(), PackedData_uint16_1e2); string += LoRa_addFloat(P102_PZEM_sensor->frequency() - 40, PackedData_uint8_1e1); event->Par1 = P102_PZEM004_VALUE_COUNT; // valuecount } else { From 9ab134106d4d295a6911032675266ac8d118c365 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 23 Aug 2025 11:29:10 +0200 Subject: [PATCH 10/24] [P102] Correct documentation small typos --- docs/source/Plugin/P102_commands.repl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/Plugin/P102_commands.repl b/docs/source/Plugin/P102_commands.repl index caac65d7e..1ebe20567 100644 --- a/docs/source/Plugin/P102_commands.repl +++ b/docs/source/Plugin/P102_commands.repl @@ -10,6 +10,6 @@ | This command will reset the Energy counter for the PZEM unit (value is stored in the unit). The value retrieved on the next read should return the updated value. (Can be 0 if no energy is flowing, or the energy counted since the reset command was executed.) - | This command can be executed by any task is multiple PZEM tasks are configured, as they all share the same MODBUS Serial configuration of the *first* PZEM task. + | This command can be executed by any task if multiple PZEM tasks are configured, as they all share the single MODBUS Serial configuration of the *first* PZEM task. " From 339d8f88750b0021e351a87ba6bd467f73c4c075 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 11 Sep 2025 20:24:55 +0200 Subject: [PATCH 11/24] [P102] Use added setModel() method when needed --- src/_P102_PZEM004Tv3.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_P102_PZEM004Tv3.ino b/src/_P102_PZEM004Tv3.ino index 78daa90d3..58069b228 100644 --- a/src/_P102_PZEM004Tv3.ino +++ b/src/_P102_PZEM004Tv3.ino @@ -289,6 +289,7 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even if (P102_PZEM_sensor != nullptr) { P102_PZEM_sensor->init(P102_PZEM_ADDR); + P102_PZEM_sensor->setModel(static_cast(P102_PZEM_TYPE)); // Sequence for reseting PZEM energy if (P102_PZEM_mode == 1) @@ -323,6 +324,7 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even { // When new data is available, return true P102_PZEM_sensor->init(P102_PZEM_ADDR); + P102_PZEM_sensor->setModel(static_cast(P102_PZEM_TYPE)); float PZEM[6]; PZEM[0] = P102_PZEM_sensor->voltage(); From eb8e0e46c787f6b127d2e942985d1b8001acdbf2 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 13 Sep 2025 13:09:25 +0200 Subject: [PATCH 12/24] [P102] Use defined constants --- src/_P102_PZEM004Tv3.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_P102_PZEM004Tv3.ino b/src/_P102_PZEM004Tv3.ino index 58069b228..61d59afa5 100644 --- a/src/_P102_PZEM004Tv3.ino +++ b/src/_P102_PZEM004Tv3.ino @@ -335,7 +335,9 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even PZEM[5] = P102_PZEM_sensor->frequency(); // Skip non-available values - const uint8_t toCheckMax = PZEM_model::PZEM004Tv30 == static_cast(P102_PZEM_TYPE) ? 6 : 4; + const uint8_t toCheckMax = PZEM_model::PZEM004Tv30 == static_cast(P102_PZEM_TYPE) + ? P102_PZEM004_VALUE_COUNT + : P102_PZEM017_VALUE_COUNT; for (uint8_t i = 0; i < toCheckMax; i++) // Check each PZEM field { From 659e5e50fa0b99aa01e8e0d7c0f62ecf8c2028c1 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 14 Sep 2025 15:32:10 +0200 Subject: [PATCH 13/24] [P102] Add Submit instruction after use of 'Reset energy' mode --- src/_P102_PZEM004Tv3.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_P102_PZEM004Tv3.ino b/src/_P102_PZEM004Tv3.ino index 61d59afa5..38ef4e59f 100644 --- a/src/_P102_PZEM004Tv3.ino +++ b/src/_P102_PZEM004Tv3.ino @@ -8,6 +8,7 @@ // /** Changelog: + * 2025-09-14 tonhuisman: Add extra instruction to submit page once more after 'Reset energy' is used, to save 'Read energy' default Mode. * 2025-08-06 tonhuisman: Change plugin name to "Energy - PZEM-004T (AC) / PZEM-017 (DC)" * 2025-08-05 tonhuisman: Add support for PZEM-017v1 from a forum suggestion: * https://www.letscontrolit.com/forum/viewtopic.php?p=74069#p74064 @@ -232,6 +233,7 @@ boolean Plugin_102(uint8_t function, struct EventStruct *even if (P102_PZEM_ADDR_SET == 4) { addHtml(F("
Energy reset on current PZEM !
")); + addHtml(F("
Click Submit button once more to save 'Read value' PZEM Mode!
")); P102_PZEM_ADDR_SET = 0; // Reset programming confirmation } From 546e850959440a962f257575fa9c0334632ac9a4 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 14 Sep 2025 16:58:24 +0200 Subject: [PATCH 14/24] [P102] Update documentation --- docs/source/Plugin/P102.rst | 7 +++++++ docs/source/Plugin/P102_ResetEnergyDone.png | Bin 13403 -> 15793 bytes src/_P102_PZEM004Tv3.ino | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/source/Plugin/P102.rst b/docs/source/Plugin/P102.rst index 9d93c1dfb..580305b73 100644 --- a/docs/source/Plugin/P102.rst +++ b/docs/source/Plugin/P102.rst @@ -250,6 +250,13 @@ The command will be executed immediately, and afterward the status will shown: The blue message showing that the command was sent. The **PZEM Mode** is already reset to ``Read value``. +To store this change in settings, the :cyan:`Submit` button should be used once more (you can of course change more settings if desired, that's why no automatic save is done.) + +Send the ``resetenergy,`` command +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For an easy alternative to reset the Energy counter, you can use the ``resetenergy,`` command, f.e. from the ``Command`` field on the Tools page, to reset the counter for the specific modbus address (range 1..247, or 0 if only 1 device is on the bus). + Installing multiple PZEM units on a single ESP ---------------------------------------------- diff --git a/docs/source/Plugin/P102_ResetEnergyDone.png b/docs/source/Plugin/P102_ResetEnergyDone.png index c5d3f366e5c07379dde01d67a5549bd3b03d3b57..84183a0b2ad32d758be336ef57ebfb835bac553e 100644 GIT binary patch literal 15793 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 HECc=z*+GB~ literal 13403 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 J+
Energy reset on current PZEM ! ")); - addHtml(F("
Click Submit button once more to save 'Read value' PZEM Mode!
")); + addHtml(F("
Click Submit button once more to save 'Read value' PZEM Mode !
")); P102_PZEM_ADDR_SET = 0; // Reset programming confirmation } From 1f5cbc461dd529a0429e68ac727a5ad749cf1edd Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 15 Sep 2025 21:17:36 +0200 Subject: [PATCH 15/24] [Info] Emphasize the number of flash writes count since cold boot #3116 --- src/src/WebServer/SysInfoPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/WebServer/SysInfoPage.cpp b/src/src/WebServer/SysInfoPage.cpp index 0ffd9b76d..cd78abb4b 100644 --- a/src/src/WebServer/SysInfoPage.cpp +++ b/src/src/WebServer/SysInfoPage.cpp @@ -760,7 +760,7 @@ void handle_sysinfo_Storage() { addRowLabel(LabelType::FLASH_WRITE_COUNT); addHtml(strformat( - F("%d daily / %d boot"), + F("%d daily / %d cold boot"), RTC.flashDayCounter, static_cast(RTC.flashCounter))); From 314e1df8ee30d7482b6c1514cc6c0f6a58f70b85 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 19 Sep 2025 22:58:27 +0200 Subject: [PATCH 16/24] [P002] Fix docs layout issue --- docs/source/Plugin/P002.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/Plugin/P002.rst b/docs/source/Plugin/P002.rst index fe795c826..84c3f0c20 100644 --- a/docs/source/Plugin/P002.rst +++ b/docs/source/Plugin/P002.rst @@ -437,10 +437,12 @@ Change log .. versionchanged:: 2.0 ... - |improved| 2020-04-25 Added support for ESP32 ADC pins + Hall Effect Sensor. - |improved| 2022-07-11 Added ESP32 Factory calibration, multipoint processing, binning and charts. |improved| 2022-07-27 Improved resolution when using ESP32 Factory Calibration. + |improved| 2022-07-11 Added ESP32 Factory calibration, multipoint processing, binning and charts. + + |improved| 2020-04-25 Added support for ESP32 ADC pins + Hall Effect Sensor. + .. versionadded:: 1.0 ... From cdc29fb43fb60a8b2aed71e726609f8044282267 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 21 Sep 2025 14:33:15 +0200 Subject: [PATCH 17/24] [Devices] Limit displaying of (old) Wiki Help button to P056 and below --- src/src/WebServer/DevicesPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index 1253bc6a5..bfa6dbf0c 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -1075,7 +1075,7 @@ void handle_devices_TaskSettingsPage(taskIndex_t taskIndex, uint8_t page) addHtml(getPluginNameFromDeviceIndex(DeviceIndex)); const uint8_t pid = Settings.getPluginID_for_task(taskIndex).value; - if (pid <= 101) { // Up to P101 seem to be listed in the old Wiki, so lets keep pointing there too + if (pid <= 56) { // Up to P056 seem to be listed in the old Wiki (and a few incomplete pages), so lets keep pointing there too addHelpButton(concat(F("Plugin"), Settings.getPluginID_for_task(taskIndex).value)); } addRTDPluginButton(Settings.getPluginID_for_task(taskIndex)); From cf56ffe88872924ba3dcaedb9ec13883095b5a55 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 21 Sep 2025 17:08:13 +0200 Subject: [PATCH 18/24] [Devices] Limit displaying of (old) Wiki Help button to P079 and below --- src/src/WebServer/DevicesPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index bfa6dbf0c..4cf767eeb 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -1075,7 +1075,7 @@ void handle_devices_TaskSettingsPage(taskIndex_t taskIndex, uint8_t page) addHtml(getPluginNameFromDeviceIndex(DeviceIndex)); const uint8_t pid = Settings.getPluginID_for_task(taskIndex).value; - if (pid <= 56) { // Up to P056 seem to be listed in the old Wiki (and a few incomplete pages), so lets keep pointing there too + if (pid <= 79) { // Up to P079 seem to be listed in the old Wiki (and a few incomplete pages), so lets keep pointing there too addHelpButton(concat(F("Plugin"), Settings.getPluginID_for_task(taskIndex).value)); } addRTDPluginButton(Settings.getPluginID_for_task(taskIndex)); From cc09d4529a2300d4a92649f529d9d5c3606dff2f Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Wed, 1 Oct 2025 23:20:23 +0200 Subject: [PATCH 19/24] [Docs] Correct some layout inconsistencies --- docs/source/Notify/N001.rst | 4 ++-- docs/source/Notify/N002.rst | 4 ++-- docs/source/Notify/_notify_substitutions_n00x.repl | 4 ++-- docs/source/Plugin/_plugin_substitutions_p09x.repl | 4 ++-- docs/source/Plugin/_plugin_substitutions_p10x.repl | 2 +- docs/source/Plugin/_plugin_substitutions_p11x.repl | 2 +- docs/source/Plugin/_plugin_substitutions_p14x.repl | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/source/Notify/N001.rst b/docs/source/Notify/N001.rst index 1ad5d1688..e73cef858 100644 --- a/docs/source/Notify/N001.rst +++ b/docs/source/Notify/N001.rst @@ -2,8 +2,8 @@ .. _N001_page: -Notifications Email (SMTP) -=========================== +|N001_typename| +=============================== |N001_shortinfo| diff --git a/docs/source/Notify/N002.rst b/docs/source/Notify/N002.rst index 6797a5b84..4cbcb51a5 100644 --- a/docs/source/Notify/N002.rst +++ b/docs/source/Notify/N002.rst @@ -3,8 +3,8 @@ .. _N002_page: -Notifications Buzzer -===================== +|N002_typename| +======================== |N002_shortinfo| diff --git a/docs/source/Notify/_notify_substitutions_n00x.repl b/docs/source/Notify/_notify_substitutions_n00x.repl index 4a4a15f4b..b6c9702e1 100644 --- a/docs/source/Notify/_notify_substitutions_n00x.repl +++ b/docs/source/Notify/_notify_substitutions_n00x.repl @@ -1,5 +1,5 @@ .. |N001_type| replace:: :cyan:`Notifications` -.. |N001_name| replace:: :cyan:`Notifications Email (SMTP)` +.. |N001_name| replace:: :cyan:`Notifications - Email (SMTP)` .. |N001_typename| replace:: :cyan:`Notifications - Email (SMTP)` .. |N001_porttype| replace:: `.` .. |N001_status| replace:: :green:`NORMAL` :yellow:`CLIMATE` :yellow:`COLLECTION` :yellow:`SONOFF` :yellow:`SHELLY` @@ -11,7 +11,7 @@ .. |N001_page| replace:: N001 .. |N002_type| replace:: :cyan:`Notifications` -.. |N002_name| replace:: :cyan:`Notifications Buzzer` +.. |N002_name| replace:: :cyan:`Notifications - Buzzer` .. |N002_typename| replace:: :cyan:`Notifications - Buzzer` .. |N002_porttype| replace:: `.` .. |N002_status| replace:: :green:`NORMAL` :yellow:`CLIMATE` :yellow:`COLLECTION` :yellow:`SONOFF` :yellow:`SHELLY` diff --git a/docs/source/Plugin/_plugin_substitutions_p09x.repl b/docs/source/Plugin/_plugin_substitutions_p09x.repl index 0154a7f40..73ddd3dac 100644 --- a/docs/source/Plugin/_plugin_substitutions_p09x.repl +++ b/docs/source/Plugin/_plugin_substitutions_p09x.repl @@ -38,7 +38,7 @@ .. |P093_name| replace:: :cyan:`Mitsubishi Heat Pump` .. |P093_type| replace:: :cyan:`Energy (Heat)` .. |P093_typename| replace:: :cyan:`Energy (Heat) - Mitsubishi Heat Pump` -.. |P093_status| replace:: :yellow:`ENERGY` :yellow:`COLLECTION D` +.. |P093_status| replace:: :yellow:`COLLECTION D` :yellow:`ENERGY` .. |P093_github| replace:: P093_MitsubishiHP.ino .. _P093_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P093_MitsubishiHP.ino .. |P093_usedby| replace:: `.` @@ -63,7 +63,7 @@ .. |P095_type| replace:: :cyan:`Display` .. |P095_typename| replace:: :cyan:`Display - TFT ILI934x/ILI948x` .. |P095_porttype| replace:: `.` -.. |P095_status| replace:: :yellow:`DISPLAY` :yellow:`COLLECTION` :yellow:`(ESP32)` +.. |P095_status| replace:: :yellow:`COLLECTION` :yellow:`\(ESP32\)` :yellow:`DISPLAY` .. |P095_github| replace:: _P095_ILI9341.ino .. _P095_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P095_ILI9341.ino .. |P095_usedby| replace:: `.` diff --git a/docs/source/Plugin/_plugin_substitutions_p10x.repl b/docs/source/Plugin/_plugin_substitutions_p10x.repl index 6099d1014..c3cfbf7be 100644 --- a/docs/source/Plugin/_plugin_substitutions_p10x.repl +++ b/docs/source/Plugin/_plugin_substitutions_p10x.repl @@ -122,7 +122,7 @@ .. |P108_type| replace:: :cyan:`Energy (AC)` .. |P108_typename| replace:: :cyan:`Energy (AC) - DDS238-x` .. |P108_porttype| replace:: `.` -.. |P108_status| replace:: :yellow:`ENERGY` :yellow:`COLLECTION B` +.. |P108_status| replace:: :yellow:`COLLECTION B` :yellow:`ENERGY` .. |P108_github| replace:: P108_DDS238.ino .. _P108_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P108_DDS238.ino .. |P108_usedby| replace:: `.` diff --git a/docs/source/Plugin/_plugin_substitutions_p11x.repl b/docs/source/Plugin/_plugin_substitutions_p11x.repl index 12a1398a9..4ce29a9da 100644 --- a/docs/source/Plugin/_plugin_substitutions_p11x.repl +++ b/docs/source/Plugin/_plugin_substitutions_p11x.repl @@ -67,7 +67,7 @@ .. |P115_type| replace:: :cyan:`Energy` .. |P115_typename| replace:: :cyan:`Energy - MAX1704x` .. |P115_porttype| replace:: `.` -.. |P115_status| replace:: :yellow:`ENERGY` :yellow:`COLLECTION B` +.. |P115_status| replace:: :yellow:`COLLECTION B` :yellow:`ENERGY` .. |P115_github| replace:: _P115_MAX1704x_v2.ino .. _P115_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P115_MAX1704x_v2.ino .. |P115_usedby| replace:: `.` diff --git a/docs/source/Plugin/_plugin_substitutions_p14x.repl b/docs/source/Plugin/_plugin_substitutions_p14x.repl index 3996585e1..8ce70d11e 100644 --- a/docs/source/Plugin/_plugin_substitutions_p14x.repl +++ b/docs/source/Plugin/_plugin_substitutions_p14x.repl @@ -106,7 +106,7 @@ .. |P148_type| replace:: :cyan:`Display` .. |P148_typename| replace:: :cyan:`Display - POWR3xxD/THR3xxD` .. |P148_porttype| replace:: `.` -.. |P148_status| replace:: :yellow:`ENERGY` :yellow:`DISPLAY` +.. |P148_status| replace:: :yellow:`DISPLAY` :yellow:`ENERGY` .. |P148_github| replace:: P148_POWRxxD_THR3xxD.ino .. _P148_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P148_POWRxxD_THR3xxD.ino .. |P148_usedby| replace:: `.` From 7db54eb59baca2727034efe2850d5f7a65c11f1f Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Wed, 1 Oct 2025 23:25:08 +0200 Subject: [PATCH 20/24] [Docs] Update overview generator, include Notify and Network plugins --- docs/builds_overview.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/builds_overview.py b/docs/builds_overview.py index 204cb4a03..247e18566 100644 --- a/docs/builds_overview.py +++ b/docs/builds_overview.py @@ -5,13 +5,14 @@ ############################################################################################################# # This script parses all documentation substitution files to determine in what builds a plugin is available # Collection A..G, Display, Energy and Neopixel, IR and IRext get Normal plugins injected -# Collection plugins are also injected into Collection A..G +# Collection, Notify and Network plugins are also injected into Collection A..G # All plugins get injected into MAX build set # Some build sets have exceptions for plugins not available # The output generation order is determined by how they are ordered in list 'buildColors' # When adding or removing a build set, this script may need adjustments! # Changelog: +# 2025-10-01 tonhuisman: Include Notify and Network plugins, ignore not available files, parse NWxxx also # 2024-05-04 tonhuisman: Working and documented # 2024-04-28 tonhuisman: Initial script @@ -41,7 +42,7 @@ excludeBuilds = {'DEVELOPMENT', 'RETIRED'} excludePlugins = { 'CLIMATE': {'P007', 'P008', 'P009', 'P017', 'P022', 'P027', 'P030', 'P035', 'P040', 'P041', 'P042', 'P045'}, 'DISPLAY': {'P070'}, - 'MAX': {'P089'}, + # 'MAX': {''}, # 'NEOPIXEL': {''}, 'NORMAL': {'P016', 'P035'}, } @@ -101,6 +102,8 @@ def addToAllBuilds(plugin, pluginName, builds:dict): # Parse a single substitution file def parseSingleSubstitutionFile(fileName): filepath = os.path.relpath(os.path.join(basePath, fileName), '.') + if not os.path.isfile(filepath): + return # print(filepath) # For debugging pfile = open(filepath, "r") # Start empty @@ -113,7 +116,7 @@ def parseSingleSubstitutionFile(fileName): break # Parse into label, plugin ID, description and up to 4 separate builds (current max.), # append "(?:[^`]+`([^`]+)`)?" to regex for an extra build, if needed - m = re.search(r"[^|]\|([PCN](\d{3}))([^\|]+)\|[^`]+`([^`]+)`(?:[^`]+`([^`]+)`)?(?:[^`]+`([^`]+)`)?(?:[^`]+`([^`]+)`)?", line) + m = re.search(r"[^|]\|((?:NW|[PCN])(\d{3}))([^\|]+)\|[^`]+`([^`]+)`(?:[^`]+`([^`]+)`)?(?:[^`]+`([^`]+)`)?(?:[^`]+`([^`]+)`)?", line) if m: if m.group(3) == "_typename": # the typename substitution should be before _status... if plugin != "" and plugin != m.group(1): # Changed plugin ID, store current @@ -178,6 +181,10 @@ print('Parsing substitutions for build sets...') parseSubstitutionFiles('../Plugin/_plugin_substitutions.repl') # Parse all Controller substitutions parseSingleSubstitutionFile('../Controller/_controller_substitutions.repl') +# Parse all Notify substitutions +parseSingleSubstitutionFile('../Notify/_notify_substitutions_n00x.repl') +# Parse all Network substitutions +parseSingleSubstitutionFile('../Network/_network_substitutions.repl') # Generate output generateBuildOverview('../Plugin/_plugin_sets_overview.repl') From 32710e5367d7c9479a7431b2033a71a0761c4a44 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 3 Oct 2025 21:46:37 +0200 Subject: [PATCH 21/24] [Build] Fix compiler warning --- src/src/WebServer/DevicesPage.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index 7d4b4147d..746bcca45 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -828,7 +828,9 @@ void handle_devicess_ShowAllTasksTable(uint8_t page) html_TD(); if (validDeviceIndex(DeviceIndex)) { + #if FEATURE_STRING_VARIABLES const DeviceStruct& device = Device[DeviceIndex]; + #endif // #if FEATURE_STRING_VARIABLES String customValuesString; const bool customValues = PluginCall(PLUGIN_WEBFORM_SHOW_VALUES, &TempEvent, customValuesString); From b48600c42ae0b88f7d8d5220002c12b0d8863c1f Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Wed, 8 Oct 2025 23:35:09 +0200 Subject: [PATCH 22/24] [Docs] Add MQTT Device class documentation for plugins where available --- docs/source/Plugin/DeviceClass_binary.repl | 12 ++++++++++++ docs/source/Plugin/P001.rst | 5 ++++- docs/source/Plugin/P009.rst | 2 ++ docs/source/Plugin/P019.rst | 2 ++ docs/source/Plugin/P021.rst | 2 ++ docs/source/Plugin/_Plugin.rst | 2 +- 6 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 docs/source/Plugin/DeviceClass_binary.repl diff --git a/docs/source/Plugin/DeviceClass_binary.repl b/docs/source/Plugin/DeviceClass_binary.repl new file mode 100644 index 000000000..7e45b955b --- /dev/null +++ b/docs/source/Plugin/DeviceClass_binary.repl @@ -0,0 +1,12 @@ +MQTT Device class +^^^^^^^^^^^^^^^^^ + +(Only available if both MQTT Auto Discovery and Device Class features are included in the build.) + +* **MQTT Device class**: Select the Binary Device class that's to be used for this task device. Device classes marked with ``²`` are 'two-way' devices, meaning that the state will be updated when changed, either on the ESPEasy side, or on the MQTT (Home Assistant) side. + +The default value used is ``power``, also when not set (empty), and can be updated in Home Assistant by resending the MQTT Discovery. + +The available options are based on the Summer 2025 version of this `Home Assistant MQTT Binary sensor documentation page `_ + +The On/Off icon shown in Home Assistant (HA) can be changed for an alternative in the HA configuration, after Auto Discovery has created the device there. diff --git a/docs/source/Plugin/P001.rst b/docs/source/Plugin/P001.rst index d7f198f42..fdfe7c2bf 100644 --- a/docs/source/Plugin/P001.rst +++ b/docs/source/Plugin/P001.rst @@ -1,4 +1,4 @@ -.. include:: ../Plugin/_plugin_substitutions_p00x.repl +.. include:: ../Plugin/_plugin_substitutions_p00x.repl .. _P001_page: |P001_typename| @@ -25,6 +25,9 @@ Supported hardware |P001_usedby| + +.. include:: DeviceClass_binary.repl + Commands available ------------------ diff --git a/docs/source/Plugin/P009.rst b/docs/source/Plugin/P009.rst index ba17f11e9..17795e354 100644 --- a/docs/source/Plugin/P009.rst +++ b/docs/source/Plugin/P009.rst @@ -110,6 +110,8 @@ Advanced event management * **Use safe button (slower)**: This effectively adds an extra De-bounce delay and sends event value ``4`` when reached. +.. include:: DeviceClass_binary.repl + .. include:: DataAcquisition.repl * **Interval** By default, Interval will be set to 60 sec. It is the frequency used to read sensor values and send these to any Controllers configured for this device. diff --git a/docs/source/Plugin/P019.rst b/docs/source/Plugin/P019.rst index 678b229d6..11ee24a0e 100644 --- a/docs/source/Plugin/P019.rst +++ b/docs/source/Plugin/P019.rst @@ -112,6 +112,8 @@ Advanced event management * **Use safe button (slower)**: This effectively adds an extra De-bounce delay and sends event value ``4`` when reached. +.. include:: DeviceClass_binary.repl + .. include:: DataAcquisition.repl * **Interval** By default, Interval will be set to 60 sec. It is the frequency used to read sensor values and send these to any Controllers configured for this device. diff --git a/docs/source/Plugin/P021.rst b/docs/source/Plugin/P021.rst index ab8884f95..851c622e0 100644 --- a/docs/source/Plugin/P021.rst +++ b/docs/source/Plugin/P021.rst @@ -162,6 +162,8 @@ Sensor :sup:`1)` Configuration may not be available due to build size limitations. +.. include:: DeviceClass_binary.repl + .. include:: DataAcquisition.repl Values diff --git a/docs/source/Plugin/_Plugin.rst b/docs/source/Plugin/_Plugin.rst index bbe0800b3..8ed9069da 100644 --- a/docs/source/Plugin/_Plugin.rst +++ b/docs/source/Plugin/_Plugin.rst @@ -324,7 +324,7 @@ There are different released versions of ESP Easy: :red:`DEVELOPMENT` is used for plugins that are still being developed and are not considered stable at all. Currently there are no DEVELOPMENT builds available. -:yellow:`ENERGY` :yellow:`DISPLAY` :yellow:`IR` :yellow:`IRext` :yellow:`NEOPIXEL` :yellow:`CLIMATE` are specialized builds holding all Energy-, Display-, Infra Red- (extended), NeoPixel- and Climate- related plugins. +:yellow:`ENERGY` :yellow:`DISPLAY` (split into sets A..B) :yellow:`IR` :yellow:`IRext` :yellow:`NEOPIXEL` :yellow:`CLIMATE` are specialized builds holding all Energy-, Display-, Infra Red- (extended), NeoPixel- and Climate- related plugins. :yellow:`MAX` is the build that has all plugins that are available in the ESPEasy repository. Available for ESP32 16MB and ESP32 8MB Flash units (available for ESP32 Classic, ESP32-S3 and ESP32-C6). From b0c0be6e272a6d3e40203f4ac1077268589bb3a1 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 10 Oct 2025 20:43:13 +0200 Subject: [PATCH 23/24] [MQTT] Minor corrections --- src/src/Helpers/_CPlugin_Helper_mqtt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/src/Helpers/_CPlugin_Helper_mqtt.cpp b/src/src/Helpers/_CPlugin_Helper_mqtt.cpp index a4f327bc1..fecbbc861 100644 --- a/src/src/Helpers/_CPlugin_Helper_mqtt.cpp +++ b/src/src/Helpers/_CPlugin_Helper_mqtt.cpp @@ -420,7 +420,7 @@ const char mqtt_binary_deviceclass_names[] PROGMEM = String MQTT_binary_deviceClassName(int devClassIndex) { char tmp[17]{}; // length: battery_charging + \0 - String result(GetTextIndexed(tmp, sizeof(tmp), devClassIndex, mqtt_binary_deviceclass_names)); + const String result(GetTextIndexed(tmp, sizeof(tmp), devClassIndex, mqtt_binary_deviceclass_names)); return result; } @@ -429,7 +429,7 @@ int MQTT_binary_deviceClassIndex(const String& deviceClassName) { return GetCommandCode(deviceClassName.c_str(), mqtt_binary_deviceclass_names); } -// TwoWay devices are marked with ² in the selector, and disvocered as 'light' instead of 'binary_sensor' +// TwoWay devices are marked with ² in the selector, and discovered as 'light' instead of 'binary_sensor' bool MQTT_binary_deviceClassTwoWay(int devClassIndex) { switch (devClassIndex) { // Index into mqtt_binary_deviceclass_names case 1: // power From acdad31f0c19f4a0388d004f83e31f8329bb2fe4 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 12 Oct 2025 22:16:33 +0200 Subject: [PATCH 24/24] [Docs] ESP8266 is Feature Complete! --- docs/source/ESPEasy/ESPchips.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/source/ESPEasy/ESPchips.rst b/docs/source/ESPEasy/ESPchips.rst index f5cf06b70..708764698 100644 --- a/docs/source/ESPEasy/ESPchips.rst +++ b/docs/source/ESPEasy/ESPchips.rst @@ -1,6 +1,29 @@ Supported ESP Chips ******************* +ESP8266 is Feature Complete! +============================ + +(Since 2025-04-30) + +The core team has decided to declare the ESP8266 builds (that also support ESP8285) Feature Complete, for multiple reasons: + +* **Binary size**: Making (new or enhanced) plugins and growing feature set fit in the limited available binary space of an ESP8266 (1020kB) is getting harder and harder. Many hundreds of hours have been spent already to reduce size as much as possble, and there isn't much room for improvement anymore. +* **Limited RAM available**: The ESP8266 has only 80 kB of RAM available, and with the core of ESPEasy loaded, that leaves only between 15 and 25 kB of free memory for plugins to work with. This is a major cause for crashes when some complicated tasks are handling data of some size. +* **Chip development progress**: New features for ESP chips are being developed, but the ESP8266 platform, while still being manufactured, does not get technical improvements anymore. +* **Software support by Espressif**: New software development in the framework for supporting the ESP platform is only directed at the ESP32 line of MCUs. No new development for ESP8266 is being done. + +The consequences of this decision are that: + +* New plugins and features are **not** included in the regularly made available ESP8266 builds. +* To enable some of the new features (many are still useable) for ESP8266, a Custom build can be configured and built by the user, as documented in :ref:`PlatformIO_page`. +* A notable exception is support for TLS: That's *not* possible to enable on ESPEasy in ESP8266 builds as it doesn't fit in the limited available RAM memory. + +For new projects, it is strongly advised to select one of the many available ESP32 boards, or chips when designing a custom board. Some of the ESP32 variants are available with 16 MB Flash (ESP32 Classic, ESP32-C3, ESP32-C6 and ESP32-S3), and have 1 or more MAX builds available in ESPEasy, that include all plugins and features available, and also a larger selection of fonts for displays (TFT/LCD, OLed and 7-segment). + +Overview of supported chips +=========================== + ESPEasy does support a number of variants of the processors manufactured by Espressif. * **ESP8266** The original ESP processor, with external flash.