From 9535c0a912943fb03a30b267f1c06b2280e7a78f Mon Sep 17 00:00:00 2001 From: liang <2303335747@qq.com> Date: Thu, 24 Nov 2022 15:18:50 +0800 Subject: [PATCH] first commit --- CMakeLists.txt | 12 +++ LICENSE | 29 +++++++ README.md | 21 +++++ example/main.cpp | 33 ++++++++ include/IOPort/IOPort.h | 41 ++++++++++ include/crc/crc_ccitt.h | 67 ++++++++++++++++ include/serialPort/SerialPort.h | 98 +++++++++++++++++++++++ include/serialPort/include/errorClass.h | 52 ++++++++++++ include/unitreeMotor/include/motor_msg.h | 90 +++++++++++++++++++++ include/unitreeMotor/unitreeMotor.h | 54 +++++++++++++ lib/libUnitreeMotorSDK_M80106_Arm64.so | Bin 0 -> 40936 bytes lib/libUnitreeMotorSDK_M80106_Linux64.so | Bin 0 -> 48536 bytes 12 files changed, 497 insertions(+) create mode 100755 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.md create mode 100644 example/main.cpp create mode 100755 include/IOPort/IOPort.h create mode 100644 include/crc/crc_ccitt.h create mode 100755 include/serialPort/SerialPort.h create mode 100755 include/serialPort/include/errorClass.h create mode 100755 include/unitreeMotor/include/motor_msg.h create mode 100755 include/unitreeMotor/unitreeMotor.h create mode 100755 lib/libUnitreeMotorSDK_M80106_Arm64.so create mode 100755 lib/libUnitreeMotorSDK_M80106_Linux64.so diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..c840b11 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.10.2) +project(UnitreeMotorSDK_M80106) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3") + +include_directories("include/") +link_directories( + lib/ +) + +#example +add_executable(motorctrl example/main.cpp) +target_link_libraries(motorctrl libUnitreeMotorSDK_M80106_Linux64.so) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6dfdada --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2016-2022 HangZhou YuShu TECHNOLOGY CO.,LTD. ("Unitree Robotics") +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5546500 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# README.md + +### Notice + +support motor: GO-M8010-6 motor + +not support motor: A1 motor、 B1 motor (Check A1B1 branch for support) + +### Build +```bash +mkdir build +cd build +cmake .. +make +``` + +### Run +Run examples with 'sudo',e.g. +```bash +sudo ./motorctrl +``` \ No newline at end of file diff --git a/example/main.cpp b/example/main.cpp new file mode 100644 index 0000000..1a28e85 --- /dev/null +++ b/example/main.cpp @@ -0,0 +1,33 @@ +#include "serialPort/SerialPort.h" +#include + +int main() { + + SerialPort serial("/dev/ttyUSB0"); + MotorCmd cmd; + MotorData data; + + while(true) { + cmd.motorType = MotorType::GO_M8010_6; + cmd.id = 0; + cmd.mode = 1; + cmd.K_P = 0.0; + cmd.K_W = 0.05; + cmd.Pos = 0.0; + cmd.W = 6.28*6.33; + cmd.T = 0.0; + serial.sendRecv(&cmd,&data); + + std::cout << std::endl; + std::cout << "motor.Pos: " << data.Pos << std::endl; + std::cout << "motor.Temp: " << data.Temp << std::endl; + std::cout << "motor.W: " << data.W << std::endl; + std::cout << "motor.T: " << data.T << std::endl; + std::cout << "motor.MError: " << data.MError << std::endl; + std::cout << std::endl; + + usleep(200); + + } + +} diff --git a/include/IOPort/IOPort.h b/include/IOPort/IOPort.h new file mode 100755 index 0000000..173b617 --- /dev/null +++ b/include/IOPort/IOPort.h @@ -0,0 +1,41 @@ +#ifndef __IOPORT_H +#define __IOPORT_H + +#include +#include +#include +#include "unitreeMotor/unitreeMotor.h" + +enum class BlockYN{ + YES, + NO +}; + +class IOPort{ +public: + IOPort(BlockYN blockYN, size_t recvLength, size_t timeOutUs){ + resetIO(blockYN, recvLength, timeOutUs); + } + virtual ~IOPort(){} + virtual size_t send(uint8_t *sendMsg, size_t sendLength) = 0; + virtual size_t recv(uint8_t *recvMsg, size_t recvLength) = 0; + virtual size_t recv(uint8_t *recvMsg) = 0; + virtual bool sendRecv(std::vector &sendVec, std::vector &recvVec) = 0; + void resetIO(BlockYN blockYN, size_t recvLength, size_t timeOutUs); +protected: + BlockYN _blockYN = BlockYN::NO; + size_t _recvLength; + timeval _timeout; + timeval _timeoutSaved; +}; + +inline void IOPort::resetIO(BlockYN blockYN, size_t recvLength, size_t timeOutUs){ + _blockYN = blockYN; + _recvLength = recvLength; + _timeout.tv_sec = timeOutUs / 1000000; + _timeout.tv_usec = timeOutUs % 1000000; + _timeoutSaved = _timeout; +} + + +#endif // z1_lib_IOPORT_H \ No newline at end of file diff --git a/include/crc/crc_ccitt.h b/include/crc/crc_ccitt.h new file mode 100644 index 0000000..2930e24 --- /dev/null +++ b/include/crc/crc_ccitt.h @@ -0,0 +1,67 @@ +#ifndef __CRC_CCITT_H +#define __CRC_CCITT_H + +/* + * This mysterious table is just the CRC of each possible byte. It can be + * computed using the standard bit-at-a-time methods. The polynomial can + * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12. + * Add the implicit x^16, and you have the standard CRC-CCITT. + * https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/lib/crc-ccitt.c + */ +uint16_t const crc_ccitt_table[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + + +static uint16_t crc_ccitt_byte(uint16_t crc, const uint8_t c) +{ + return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff]; +} + +/** + * crc_ccitt - recompute the CRC (CRC-CCITT variant) for the data + * buffer + * @crc: previous CRC value + * @buffer: data pointer + * @len: number of bytes in the buffer + */ +inline uint16_t crc_ccitt(uint16_t crc, uint8_t const *buffer, size_t len) +{ + while (len--) + crc = crc_ccitt_byte(crc, *buffer++); + return crc; +} + + +#endif diff --git a/include/serialPort/SerialPort.h b/include/serialPort/SerialPort.h new file mode 100755 index 0000000..7bfe5e9 --- /dev/null +++ b/include/serialPort/SerialPort.h @@ -0,0 +1,98 @@ +#ifndef __SERIALPORT_H +#define __SERIALPORT_H + +/* +High frequency serial communication, +Not that common, but useful for motor communication. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "serialPort/include/errorClass.h" +#include "unitreeMotor/unitreeMotor.h" +#include "IOPort/IOPort.h" + +enum class bytesize_t{ + fivebits, + sixbits, + sevenbits, + eightbits +}; + +enum class parity_t{ + parity_none, + parity_odd, + parity_even, + parity_mark, + parity_space +}; + +enum class stopbits_t{ + stopbits_one, + stopbits_two, + stopbits_one_point_five +}; + +enum class flowcontrol_t{ + flowcontrol_none, + flowcontrol_software, + flowcontrol_hardware +}; + +class SerialPort : public IOPort{ +public: + SerialPort(const std::string &portName, + size_t recvLength = 16, + uint32_t baudrate = 4000000, + size_t timeOutUs = 20000, + BlockYN blockYN = BlockYN::NO, + bytesize_t bytesize = bytesize_t::eightbits, + parity_t parity = parity_t::parity_none, + stopbits_t stopbits = stopbits_t::stopbits_one, + flowcontrol_t flowcontrol = flowcontrol_t::flowcontrol_none); + virtual ~SerialPort(); + void resetSerial(size_t recvLength = 16, + uint32_t baudrate = 4000000, + size_t timeOutUs = 20000, + BlockYN blockYN = BlockYN::NO, + bytesize_t bytesize = bytesize_t::eightbits, + parity_t parity = parity_t::parity_none, + stopbits_t stopbits = stopbits_t::stopbits_one, + flowcontrol_t flowcontrol = flowcontrol_t::flowcontrol_none); + size_t send(uint8_t *sendMsg, size_t sendLength); + size_t recv(uint8_t *recvMsg, size_t recvLength); + size_t recv(uint8_t *recvMsg); + bool sendRecv(uint8_t *sendMsg, uint8_t *recvMsg, size_t sendLength); + bool sendRecv(MotorCmd* sendMsg, MotorData* recvMsg); + bool sendRecv(std::vector &sendVec, std::vector &recvVec); + +private: + void _open(); + void _set(); + void _close(); + size_t _nonBlockRecv(uint8_t *recvMsg, size_t readLen); + std::string _portName; + uint32_t _baudrate; + bytesize_t _bytesize; + parity_t _parity; + stopbits_t _stopbits; + flowcontrol_t _flowcontrol; + bool _xonxoff; + bool _rtscts; + int _fd; + fd_set _rSet; + +}; + + + + +#endif // SERIALPORT_H \ No newline at end of file diff --git a/include/serialPort/include/errorClass.h b/include/serialPort/include/errorClass.h new file mode 100755 index 0000000..48313c3 --- /dev/null +++ b/include/serialPort/include/errorClass.h @@ -0,0 +1,52 @@ +#ifndef __ERRORCLASS_H +#define __ERRORCLASS_H + +#include +#include +#include +#include +#include + +#define THROW(exceptionClass, message) throw exceptionClass(__FILE__, \ +__LINE__, (message) ) + +class IOException : public std::exception +{ + // Disable copy constructors + IOException& operator=(const IOException&); + std::string file_; + int line_; + std::string e_what_; + int errno_; +public: + explicit IOException (std::string file, int line, int errnum) + : file_(file), line_(line), errno_(errnum) { + std::stringstream ss; +#if defined(_WIN32) && !defined(__MINGW32__) + char error_str [1024]; + strerror_s(error_str, 1024, errnum); +#else + char * error_str = strerror(errnum); +#endif + ss << "IO Exception (" << errno_ << "): " << error_str; + ss << ", file " << file_ << ", line " << line_ << "."; + e_what_ = ss.str(); + } + explicit IOException (std::string file, int line, const char * description) + : file_(file), line_(line), errno_(0) { + std::stringstream ss; + ss << "IO Exception: " << description; + ss << ", file " << file_ << ", line " << line_ << "."; + e_what_ = ss.str(); + } + virtual ~IOException() throw() {} + IOException (const IOException& other) : line_(other.line_), e_what_(other.e_what_), errno_(other.errno_) {} + + int getErrorNumber () const { return errno_; } + + virtual const char* what () const throw () { + return e_what_.c_str(); + } +}; + +#endif // ERRORCLASS_H \ No newline at end of file diff --git a/include/unitreeMotor/include/motor_msg.h b/include/unitreeMotor/include/motor_msg.h new file mode 100755 index 0000000..ba62da7 --- /dev/null +++ b/include/unitreeMotor/include/motor_msg.h @@ -0,0 +1,90 @@ +#ifndef __MOTOR_MSG_H +#define __MOTOR_MSG_H + +#include +#define CRC_SIZE 2 +#define CTRL_DAT_SIZE sizeof(ControlData_t) - CRC_SIZE +#define DATA_DAT_SIZE sizeof(MotorData_t) - CRC_SIZE + +#pragma pack(1) + +/** + * @brief 电机模式控制信息 + * + */ +typedef struct +{ + uint8_t id :4; // 电机ID: 0,1...,14 15表示向所有电机广播数据(此时无返回) + uint8_t status :3; // 工作模式: 0.锁定 1.FOC闭环 2.编码器校准 3.保留 + uint8_t none :1; // 保留位 +} RIS_Mode_t; // 控制模式 1Byte + +/** + * @brief 电机状态控制信息 + * + */ +typedef struct +{ + int16_t tor_des; // 期望关节输出扭矩 unit: N.m (q8) + int16_t spd_des; // 期望关节输出速度 unit: rad/s (q7) + int32_t pos_des; // 期望关节输出位置 unit: rad (q15) + uint16_t k_pos; // 期望关节刚度系数 unit: 0.0-1.0 (q15) + uint16_t k_spd; // 期望关节阻尼系数 unit: 0.0-1.0 (q15) + +} RIS_Comd_t; // 控制参数 12Byte + +/** + * @brief 电机状态反馈信息 + * + */ +typedef struct +{ + int16_t torque; // 实际关节输出扭矩 unit: N.m (q8) + int16_t speed; // 实际关节输出速度 unit: rad/s (q7) + int32_t pos; // 实际关节输出位置 unit: W (q15) + int8_t temp; // 电机温度: -128~127°C 90°C时触发温度保护 + uint8_t MError :3; // 电机错误标识: 0.正常 1.过热 2.过流 3.过压 4.编码器故障 5-7.保留 + uint16_t force :12; // 足端气压传感器数据 12bit (0-4095) + uint8_t none :1; // 保留位 +} RIS_Fbk_t; // 状态数据 11Byte + + +#pragma pack() + +#pragma pack(1) + +/** + * @brief 控制数据包格式 + * + */ +typedef struct +{ + uint8_t head[2]; // 包头 2Byte + RIS_Mode_t mode; // 电机控制模式 1Byte + RIS_Comd_t comd; // 电机期望数据 12Byte + uint16_t CRC16; // CRC 2Byte + +} ControlData_t; // 主机控制命令 17Byte + +/** + * @brief 电机反馈数据包格式 + * + */ +typedef struct +{ + uint8_t head[2]; // 包头 2Byte + RIS_Mode_t mode; // 电机控制模式 1Byte + RIS_Fbk_t fbk; // 电机反馈数据 11Byte + uint16_t CRC16; // CRC 2Byte + +} MotorData_t; // 电机返回数据 16Byte + +#pragma pack() + +#endif + + + + + + diff --git a/include/unitreeMotor/unitreeMotor.h b/include/unitreeMotor/unitreeMotor.h new file mode 100755 index 0000000..a81df0f --- /dev/null +++ b/include/unitreeMotor/unitreeMotor.h @@ -0,0 +1,54 @@ +#ifndef __UNITREEMOTOR_H +#define __UNITREEMOTOR_H + +#include "unitreeMotor/include/motor_msg.h" // 电机通信协议 +#include +#include + +enum class MotorType{ + GO_M8010_6 +}; + +struct MotorCmd{ + // 定义 发送格式化数据 + public: + MotorType motorType = MotorType::GO_M8010_6; + int hex_len = 17; + unsigned short id; //电机ID,0xBB代表全部电机 + unsigned short mode; //0:空闲, 5:开环转动, 10:闭环FOC控制 + float T; //期望关节的输出力矩(电机本身的力矩)(Nm) + float W; //期望关节速度(电机本身的速度)(rad/s) + float Pos; //期望关节位置(rad) + float K_P; //关节刚度系数 + float K_W; //关节速度系数 + void modify_data(MotorCmd* motor_s); + uint8_t* get_motor_send_data(); + + private: + ControlData_t motor_send_data; //电机控制数据结构体,详见motor_msg.h +}; + +struct MotorData{ + // 定义 接收数据 + public: + MotorType motorType = MotorType::GO_M8010_6; + int hex_len = 16; //接收的16进制命令数组长度, 78 + bool correct = false; //接收数据是否完整(true完整,false不完整) + unsigned char motor_id; //电机ID + unsigned char mode; //0:空闲, 5:开环转动, 10:闭环FOC控制 + int Temp; //温度 + int MError; //错误码 + float T; // 当前实际电机输出力矩 + float W; // 当前实际电机速度(高速) + float Pos; // 当前电机位置 + int footForce; + bool extract_data(MotorData* motor_r); + uint8_t* get_motor_recv_data(); + + private: + MotorData_t motor_recv_data; //电机接收数据结构体,详见motor_msg.h + +}; + + +#endif // UNITREEMOTOR_H \ No newline at end of file diff --git a/lib/libUnitreeMotorSDK_M80106_Arm64.so b/lib/libUnitreeMotorSDK_M80106_Arm64.so new file mode 100755 index 0000000000000000000000000000000000000000..576a40a1c467323df7d31ce4fc9714180588c828 GIT binary patch literal 40936 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℘N@B@W$#h&0~Pu< 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 literal 0 HcmV?d00001 diff --git a/lib/libUnitreeMotorSDK_M80106_Linux64.so b/lib/libUnitreeMotorSDK_M80106_Linux64.so new file mode 100755 index 0000000000000000000000000000000000000000..553fe129de62e03720e4d77d1ec425d7fb2e7477 GIT binary patch literal 48536 zcmeHw3w%>mw)g2HP+mP20c;1gNwq3V2%5lt$a8wkZ^!W!fUS zp;|9GI-`#Db=4VX#2H0I&?0Z2;A6yL)cQ_DrGf%Ju-|{}z0b+XX>v!s_xIi3{XRCN z`>eIsUVH7e*4}IHea=a4aJr`@CnZU0N|7#*2@fN2pHC(|EB&GScT^Vh|^{FsuX}@?@;HQ`9r&Rza`k z)CQ%Jj{_CIq`hKMuXrivW6Z6he`>C_cM()r2O z2b)J047_(#)!<;^sMh43fvOpFJIGEID76@o9?>k zud~m)?a2IRu9`iizRi7VZcD|mB{fUhx2!$+FPA=2c+0mR2iGKTicI+Y!D~+axME4W zyWIKZV9RGe?vFfuXV0bQTbrMVOjzD|-;Xo*rrAO#efHzMrQM6CEXjZf931ZXS{ss zXFm?Q=friUVF#*(sByEiVYp#&O3sHd;^D7>!H3479|L?m`WbM_c=#9l$Hz}e!2dq9 z8IR92;77%grym?O9=$t3zd94h`E&yMPvGeB^l)baeNIS#UpP2EpT!B}Z%H7}qy+eH z67*|P0{p`X^t^vie0}~s0sWQ)@_&Yb9#3!E63Bm10zQu=pnp37y(@wKuSkI3lYsxL z;2%%^feGw*Z-Q~LF9H7(pr3et`$B?#-I2g9js*RBCINj?0)KcaLAy5ie>^#R6ZDIM zQ#|@*3Fwa`&>O`Z3qHp5Ndo>u63Bn*fcSQN2aMy%IU#|4!9K1$?uBC4yW@>%7K1}zHAmpv4LY03jK(cS9SXXBW`t=}) z=MT3+UglTA?i9Butq^vpTg2fF!Y*F{B>9c@Jy+lu!T$-hT?Z#TO~|uV=*{Nk_}@bgN@pS`z2yu3`3x&b zR-u2RKinqx)D?5WzX|?c$U}Vgit(k&DJja58h@?Q5Gbz?D2k-GN@pn*-g@s6UqirK zUplL>+F$D}Eni&i!Xcg=A&dAxN2pT9O|Syg$!xs(d*wi0i>ue`e0UmwV6@YYs1i>qp+W%a&*SE}>Y z*Zb=kmA-b-cviLa;uxMFtEk2f2Rusxd0w?CK|DK#w#W_+4T1VWG!b)>jqw2}-TMwxHVYxpJ=8vy>@C zQ7S9E)d6ZnYVcNjJplD-crOH-2qZ*1_Bvj>(dOKp8>l1mvHD-wn+326Q`QSV=i8!O}4hP#+1 z3f%b@RChv{(u<+}Xp8WO1T7LVnwbQ5E3fvl(ZLYEpxyskWpyOzhkN08r(Oj=afCX3 ze5jRPtgoD_S3e&li7g^}LKwMYWdtb%|xe(mSi0T1wu!sqt{c;rId@zpNHbX}p8*Drww)CQmv5q~Kv8B2wgOI`5_$tU$% zfyL&|{3Z6UxuWLREUaG&ev6j}ybV}9DS_O&ax8h4D*?N$A>glDjKv17CsbDZmwEiP zfqH+nLg77D2K)cK40e0H7rN(bIOl(3=X8NQca}fkuP>~rD9&S7Mdg8V(uIb%+iUz4 zzRKlF1xlR7C2X}2EzN`bC^f_b4uuJUQL$hhmZXFfaw-X&ZHH^w3cQSDpY5UB8+dv11vKYNk{ zaES-&a)Rsxc{Kby=m7HwbB&UsnaZqOo82}^arh~f@nWJ6VqnG2e1;PCJsF#yHUQ`vJ-OeisFi$F+Ki^T{Qta6iVhYB`&|zzqj5`|1 z>|YA*QKYbcCU%vK`%uZa|3M!r>(9!Fp6Jr>=_d_9Db*(`%2T9)EKkM#I>PZ1I{ipx z5N!gnVFV3_lW;%pzw@8Oxcv=#Vf7rX_^jpFc@LI)fTNUzmN$!X+M3>W%WrWKGDtcq zaKn8*94(-C_)9!)W##>)Ap&kZ#fOuE6e&|2KqNs64~V+NzwYSm=;T1jD(K4@JV2Tt z;NT5oP~J}}5b*1dU5S$}lT<9=s~CN%v_QatG5?MobFy>=U`pzJL?Bt}6z39MVn40o zJErjRod$fD!0$HT%LE_kK3-4dqr&QbosJKz_>gW`66XO%e7E3FcyYwQ$iq5(F6Y4h zs^@J)Pv_4n|D!tk89MqjUAyAQjFo2S@P#^hiw?g;hi|%v19Tjw$7kv2_4mwH>FD)% zn~r{#j(@HWFYEBK4qv9j7whoqeK{(gufxyP(U+nrFJdF!A z)#>_Mp(2qt>+s@;h?REe@Zv~};qTDl>3*b|I(2yUjE>44*5TDNTf(o^;l+^_p{4aY z{HYAX|8(i_ztZ7%>hS03@Vj;R2|D~<9e$Dy->t*v>F{A4{(K$2M~9!P!ynb*FVx}F z#CW7}k*&jLc5;Ape31@s(c!6%nzB0i713h?(vq!{UlN|~6{{(?lV1^@W^6U(ck(O3 zW8%`1+{rHqFOHTOqF9I5<`k67*WoJ}CI3^V!{Z21OI12NCUh;;>F{ETXJt(~{1A;A zeyhVPI{YdfUO(+iEXtizu`gd(l&+q-O z@I5+wxek9+hd)h+m+s{N$#c36pQgi~p~GkB@Mr4qnL4~hhqvhPZXG^Lho7y(+jMx3 z4xg*TkJRDwb@)*_ysX2I*5QkF_F`-Pe4P$IO^0vN;m7Fk z%{u%!I{Ydf{#+ftLx&%$!{4F9kJI5hb$G81|F8~k)8W_Z@OB-3y$-M5!=mCY9X>}# zzf*^wsKf8p;V;$U_v-NC(KA-st;4%?^kE%-vJT&)!%xxSkLvIj=FjB6;bWm|Ha*+npM)hFCp~194Js7cTFl|f^Mn-Dz5C#v`U^?J9 z7)jD#+Grk(eD$N+U)o@z{~AmOWCtUAG?+G;=)VTj1{3|)VA@!s{~Ami%7c+xG?+G$ z=)VTj1`_?(VA?pM{~AmiL-b#RX+wzqYcL(ap#K_78$k45gK6V;FfvqwX~T#9YcOr} z(Enp<|1AuDUxP<7c#j6tMhyMeU^?hQ|25dk;CnTgHfZR-2Ga%%{nudHc%lCqOdBrr zUxR5wh5lEH_e*I?Qx!TuUd8zl5!gXusE{nudH5TXAXOb4~-zXsDm7y7Tkv>`(O zHJA>((0>i4jS>2@>hr4e&$*Jk9`*Ho&JF z;1LFRhygYk;A2pR^0KaK~UpBzo4Dcoc{GIhX=2C@jp7Ln(60v82W{$G;7?uFBY-A-8=I7$gUGxPza_!N{Qp7-8rH(57uq zO_t;kTCI@JCZ%4os{)p;?Mr^A@k3tjwf{X}jK^T7f``+H7Pz`$evD`kf1(T&5 zJm3m$4fmk5C>YuBMwIhApxyrfTLck*bUWGv&A-HS08`3=FvU-z-2Von4{qE4{&Tbv z2v>m#TDk+%Ff;%r;ftBTBbIRK>L?2y2=7Lpd5uZD#;RxyE3Yw;*SJ8`_yg6Lk2c)x z)z-3b?{}=BwNRRycjwB0m}vb>{#5!m`{UyN&PeFpS)o6l?}Ikt!# z^bvA}_K6=*Hs(h;*duTL@ZIqqEnwL`^;|4I!@oTOt+i}Ta|gQ@(41PCt=F$(p1a-O^fb*~j#5|fjd^nL z8*uy{9J3CY{nIlsFk|9HroGENCe`}GA^A_T=bF0kThL}`W}W>t3{_XKYdzdhl3(wh zF`#HmQ~UBHSFqc@D?Ar6v>fdXOl|8jx84nk&^2}L;0G9a;a{V^94fVDA|ecDQOVr) z4Do2$nngjtK`Lkk0y6@wWug5?vBs7|Ra0fq=+XE(;<2`xI^Wh0Zm$Y?O-pA(F^N21qt_(MHH_%=N_N%sW z!>wl4IDlnBcm+h;Ku(C_{_t9wBVng2KmorZ(9hK~S#Bm9xtwRWB+!4MZM+o(ogU8&V zWmrk&XUciI&29HVc=!f$jKAZWJBE1?9D_!L<8p_x1?`7M4?t6@U(CYRl*~MliG;No z^NWqbFM7?bYnWf$0F}&xN|rI7$U4YXk^$9(uEU@_2z`g|BL!W@#|Qbu^MGR-XY(2` z2UT$}*Fhh>;ho^)3ia2kW8NaDV+{(qI)WHvd_1E%*EhM;c600Ls!I)LE_KkwUFrb2 zR5x{sTo;TyjDPS|UFu|P)5#opXdXGaR5p61y3`X;jf*?XNsQt!5f3H`;ZpZU zDZT-kOiKEj6?#Ir)ZxG-Y)l2li1BnF{CN-8-5Xy;wH3Y{{39j8KaPagGiEXV+XE@9sBJ!HXRcXwk2W_daILU<1~owu!V3N60d zhup{3N5vL7?}f%oh{xE?RLj zyP^Rc`{iv5+-L7%HAK7-OtA-u@(etR!QHX|mPqAeb1^JII_&F{GTBPXt z1KVHa%AwP*LYpyRGYcJa2|e=Z=)LfxU-Ew63id9nZgZba#t5}{h5rVG1ADVN#7uMB zgHUX^1GFKCzOCiE)W$^{EWoje@xAagas_w+yj2c8nn@ENHelw~ATDVBYwRF%*cesp zJhkysn%L@T)QPz&;swz1*-2~#-SS#bD4E%PWTH{7+HYgs6Sz2 zm!)m&8Z!{Wb43Ub_n=GRYw(Ah9Nmcg1vNYR>f13-Rpg4#*P{opr%sQp)`x+!chMHe zLK9UUIFgcDKL9&4Zwa}rSy)Ysb%d&|^G6@}ptpC$uI4mJYT22(;)B*3NZQ(6_;i8T ziu|=o^Wqm;y1&EaUR-XeG*@pnj{&0<$E5d3J#U%t_r@R$v*Or%tQX9!PcqChT(3B` z65^O!8wj(KUK?F;Y$wC4z-U-;Y%FS-+werHw27vfX8_WFg6gHWt=>rkluG!&Xwk_lEE>)JjJn17&S zOI;`*Fcr{3f-Hb8a7lr|D~>g{FMv6&h3Yn$QOUk9Qjd9h#j)-s6M?@3+%~0S4Z_S6 zxr7xpx1Iq;DPXkXSm)@oKsF0T+%#Atvw=*VuT~th+}j`IIUqN$yo|Ywl#ve1Uzuy< z7ns4|Y+{h6F*ty!Tg(eB$7Y&ap91O9*)7Lv&23%avk4y|(Kbd|#CkgnEwuiVNZsh) zOoA?8ZAibx=HhhLKi-dUN=C(7aHpoQnELM9hS)^?bB-upwVL0OdWF|sfS`T2g!w;0MtPz*w>n?cy}Ek^m9 z43lbZ`y4Yu^GC;q;6eEO$Q(4Q`UPt+D?-N!v`!#CZC9cC)1Z{ZD0T$hd=!&Kn8BPp~NVR3y^il&6+*qwK5qCE_^k&nT2uZzQ%GPu7+?_%&E4bEe*S%b$g7>XA4 z>71Zr2xh+g$Vy!D_R+WImy#llKrne)c4m<3BNG@RAC95%dmGE2j!krLj?1%)!9%q2 zrx^@y6XlN(-275XB$M%KMFEUHK%);bdc*-iznsBITDcE!_@7}!v_&vNWIp{Vp+B?f zkBj~k;Sbj}tzfFLty<@{)&$bHt%CHO2`jdt~V*P)yyM38V zQEnbB?$}1#qKj}vR&21{!7e#?Nrt>(U(UL>e)I0Bh4PUP+`(nJ?oc-3RH?NLe-~P- zih^^}aOJiZ<8Os^zP$OfVTfU`%f9Dns;QLCwa){72{G*j*O)FWh5qd#c%{o+8wLue zx?LIOq0=+*$#RD(u@mj@4u;)H-GKqKXaPZ!t~*#^&2Y8+U|zNuf0G*B=(ST?RVcfI zJ?@|<9~-`c?Wqq2kP8y9y8o3=Pk=<99Wch!+dk=C#1g6#3jX88)Gt{ zee2(TMH)R4UIVGH$)qLQjL=3~50$oI5%Uf%nrVO5$hT)l!oiP7pF6@=eN2PMpJR0g zYch(0*FoEj3+3S6qM#RcI}qb3`rk9!9`qRZF73Q`dF%t6T zRGHgo!xothbU1>3bg1!??RVID$T4;v@+MS%D3qMn&)imyiH!~y=qrHa;Jf5fe?V2r ze~UE>x=c&ZYY63;nTm}GR#e!Qgk30X?J~FB!jwPyv)QEgamAxx1G@1pj(Sf(J@Zoy zI1>9b+#ed=K+6HxXFlk}xk3*qUOQKKKx_g(!sZha@hyzGwS=ya& zG^U2ga8zP(frMxlLg)_?218hL>n$Kt_kNL9>WJ!3G_+(^FJ`~}rkkpj!2LkLeRmoF zIkr?AGku7q*2W=&&!*? zOP0-#z3$HY%)Ihtkk4!{rJGp?a5Qq8IzLu zlgI4D!8BFhf&;tyKSIZ8MK}W%CyO{i!p?mcmW~_HU-JHMPABg_5dMbD8FhW_Jhfcx z+%1~R<5(*E>3iJxucGn&cWU_f%Al4K&|L_ zq4^=$g9%o5KR^ymx8anc86vau5(Kq(X5br=pm?#jmqRz$~iN0=Zs^LL}gXk+4h7W~@(Gk#5d_*HU#;n{3}f$uyZm>yWT!TAID@kr0k9w47A zw-?Um(qu7yrZJ#l;g6k9q%4SJKog?=ygu@vzEji>llnuZh>Pl9m&;QRtteAxgKP&Ac8LtMl(G-5n5chH;RZr^CNU^uX~ z1R2lW{)Dv?CdR3u+_E`8xF}0*c^Y;LM&*^)h}*$=1V)A2(@5~ zg|JNG&39wzU1c8Qw%Wp1y+dj`{f{#1(i&v;!}5++>ronmNR{RTUG9(vM;5SAXeQP~ zt=2T^f3TGaX78%R6}_EBC7H-w=tx;qFGrE zF0|&$!Mk{yA=CHM(RBM=R$8%{$E@b;TDmgLV_L0Uz)>$cDG!-;gOt#_32fNjXn7ygK(z}ZAMlld-d2j%F|D&&;Np3TT%5tc(GL_&8F&8@WKb)zyV zd=?@8g0|dwUFI7fB*lbQTlb>G{+gYRq+MfnhL^G)wOX5j#>{1t^Y)rsHxq5%wN|Vv z&jLf-nR|jYFNfyk)2P65FqbVMPe!R6+{kMOZ|x)N_WochigEU73O}@uI%it%q(R^x zi>SYmn~eDncT}DKbbyZhM)Q~RueBC~O&MoXPQ`G18yiTlKDk7=kSUNkuiKhWW17yY zxF_?0gMbws2v})jnz=P~E$YS}X7J-8G^87CYJ23v;Wck_gV7A8Z9vRz)uhA~TWP}6 zMZstYz<$Ks=4MvGEESo@wvuQEw>8;`KJ87KFw3UdUkm3m&vd3SPr?BJjDTCEv@Hpb z_y-MjOoRxcX%V^)F6LiMY&Lf9Y#%f2t=xibuLaJK+2P&;gbuzNeuIfGipc|l^K!SR zo}?KraxRu5h*#v3q$4@hgl*e_&@xNQD@ox>SR(S~4_K?fOE&U0n1>)b2nVIPf;<#M zEb`tloqSI))6*zfyBAyC>LU#vG>+jzzQKkPgr%c|ERZ4) zlkAz{QeFkocqWU+YN(AyWeay&+=d!ZF;Cjg~Zi~?GKs%uX+TozKiR$~z_rNM;r3EjB7HMNtp9Wsre#uA0@ zy?dxlKHKR+H=TC(4c#Ih(P?E{DYFa3?Q`{U`yv)9ThTHY=;C)Xb5djc{>&Xb9G>?Y z#c#}mthi1kOU-aA63k0#S}6dS|WzDhcd#_(?RS0BT76O7oso{UN7NlZq44F3zO zK{31(S85F3x?jZbt?Zqk$b2n^Z{06q_}2aZ!OuNO4<+WOW~V*(Bi+3W9^5f4btrUF z8NA+7+43!-?kO18=BEk~4P+E#Vpq4TrMtiRyq)G7X>Kr|XSyx} z*^P4;#bsRw&6k_j0CUiMsmRCn95QDVoW`mQ=T&B~D)fE9hs?Z6nW)0@BJV-vM4y?R|9sM*UcDZUiTiLg3-aN&u)3YxiVOP?tq^lK++|*^i-LjN_FIf9l_@-H;2=l_7@z%w~K;XoaS|}5s!iisTVoyn^~E8-7bP% zjv$Ban;pTu!S6x3OOU!8*rXF1@Fr4+BgkNf{iqJLH+ZNo-OP#G*Z zkB+pkPJWt>ohyU0)5t|QKu)r9AI2V8g*nOk{*0(#AiH4dr)S5h{51RF9R;)x=T`X~ z=p6<0J{OJ`_v!BYfoSs!FFBt5@dn%uTn{RB9yrf58vAhbjrXI9>OkiKLq2yV%f}v# z&|~FXUij!2u%Y?JkdD3=7@}u69Ih+!5^Dkd1O4MDU3T6fl>Z4=hfuyV5>m?{EXn0~ zh6z>zG;e1|!Ql75>n(6ReT)QNsKXEMGVhX~tJ&9kLu4i6(hNzY9R=`QSCM1=H$*>6 zqo?tSHL?ZIylUrhj#4~abpmc_&nq#nn}$P%L*{j}N5c;bxTBGuO-P*qoO1DNe!ZU;ko7$W@0j-$%@J@HNA>z zM1%RH@HE<%N6&k4K0O8xx^J*RaI85;51?>!AUy9yn(F!UdHUyl=Zo{{EbV+cJYyHl z%R9p3U!Yqukcu^+o+ndW$OJRvIrRfMIH&H?&Z*ahCxA%YFN8l?w?H1|TXfKmQ+0xm zr{fwpu7Tqk_}{F71Aw_x@??CEHokHg zUo73|30P_ytE(-w{(yyjld@38f=e88XS-%kkL65Xn>*IhSi6{hw7{|y-haPJI z+Ur~DweYX0W*mN2{bl&!1xvtJja)E0cP1+WGm9~c9 zU$U+F0lpdD8xVGtqE5+FZt+!2mBc8q_-ieNa|_2>=$oT0i|hSYq7h4lAHq>5=sWS3 zORhN@EqQEdPSK`$Gyc3~ClF@xq}ODzv_&#dxvM4{`Tw1XTAJx(W~zr zyZH0S9c97qpQ-<2KhMqe!}IUHXw>LG<=FZ?ebVd$JAPdF(wpyG@yLhkoBr*qJ8x`A zUwm8fX^#6Ro@0Id#N7U`_D=iqoqv|Ty#MLN4}bgnx=>o{irY?kXwAB@&p-J31@AxA zlb^QhJbc>L z+ul6q-uu_){^s#D)2@8=>QecgOBavZKcz1H+cR%I((jYI-x$8_Pmho4eEQ#QEjzB6 zeZ`ye7rH*2dd1kU&S)~zW(*sz=V|kW2hj?#soF{#D{Q)U(#8w8^T}I&|2s-~`P_55 z^B)S!*}WrA7I2-&r3;fzO*x-_EA&?&-2HTKZ$7TqZtCr=Lf(bE8F|O%-d?;DE)_hF zV`$u?_!9X`$VYAO?VXQX82OZA3tWf%2jpctdV9N2uM>GO>SbVsznXF^(dl_;+skMt z1@y1<_O3$SjC>>VF672pe+@p!DdF}SOG#JHm6Dn=l1?4mKdl38Sb?SO{Hpa_b}2n$T6*RT^PpvE&C-RZ zOg?9Vbre;k`bGHUZ|v>GPFPEX$Gb*SF7Ue{qne0@rv6U!QHUTBj_zmQ1swKSEK&P+ z;d95f-d^m(BxzcD#_D88dS*+?^mI#EdS+32MnQTSdlX_oV;RSdKS2YDO!Vsu0fI;6Z3XXL{CZlOx@>vfq`cj3zXGg@cm)2Gq1c4g;nLyJBWj;vI&MPZct+rv9#^ z{S8zZy8d?#$daT} zRo}CqjO@P=b;cu4os-IJ(UQDqV0zm0K@MT}jo`Z%G$(>aa+2NM%vNN_y(s$u<0+rY zV8@nZzgG4&$}G53jR$~)jhk3mF+lRUQk2o}>80+2<1*bsfkL+hnr@5Ib6fhm(tA=< zzDgaKo(p}$j?llRY*-3o7oQ${I`D)R-HJ-xk$@-czp`JH=gFqHJef|XfL{@8@&jz+ zK%V+H&a<6-K=>nMX@O6br3_AjdG!wI7(}|Iq|<-!EKUFEWi6(asjE}klW7do7&^QW z^9J%%1??c^JbPKNFzRR~a# z95#GT!Mr^IO{E@&0g;OEapTg8TLtZ;he9sLP05(5+G#9^u~kT8iw5Us1DTbe4$Vr= zK~fx9mXD6=qqwEtO4I7p_LQ5@mMY8hm{Z8_Qs3pW$RrEq@+_S7v)`CxeltV!8#X4R zHlChdmi%U13&U$@zPJOt7UGT!`+Yp{ia%c@zr=N`^=9Uvt>4FgdiR8hpAaJwN$&$OdT*9_<*!VnPnZsAqe7&jnvT?k;2F zhd>(Jr6?~$3}U|#h;iAHoMM9$q|t!LKzV@be-@qVX>MHw+&_V1zkdk%Rwv6e*RXjy zV;WOp?WE1A3M^a4xNS9WcOdqC8 zzc<~N^mV%QV1Lu9A<~NjO~=xuj|Z86`O{#+Y#dCOr_!NIs{eJe>9HZwLn)@4%u=h# zbh}x)-}GG4!)EEl{-*Uqr0)ls9yd$33^oC?Z!lp#A5572qJGAO6ljknnVw9R{*=sl zo;1wVAf1ovOHKDDN!6yilcYP6co8*Oev)Z>k~9tom+74(Nx?;PlIfmg>GmYk*Gbam zB)pQnHQDrHs)5$2D+V1IIORTm#27a9jh&HE>)5 z$2IW(y$00Z*;9X4PyHP|?RWG3muLt(QI_a83n{5E{br&brr$`UMDI{hdQre4;|Dds zL~OX}|rs%M000*}|Y{dC#Gk6Y-K0+up`AlUA+ zG#^KWlm_xlS}Fvgvp7m>dpIfLsgq}dt+ZY+rgI)j>KXM(9F*jd{6fX&pUz=b&NR`! zdXBBO_hT=Yzf5$jSHP+qJp#T-DCS!MtNj$s|38~G-yOeeHafsU$`^UD$jd}tC-P>I zcZj@Gaky}J= z6M4SKi$z{0@;Z?>i@ZbRog!Z=@-C6@7J0YGdqghX$J&M%&Z8>8ETCI^dPr+>VusXnXWc16lJLBS0w0TBHF43>ks`E=M-Xy8> zP%OTmq>krUe1A!u2V(JQk~*Kn;s2f)xC2ttBoVvviJ*P+X>9w$6x) zPnWuX9gp5Dsq?zNG=)xM>+~3Yoq}I(EnXTAKTK*`77u@dRDFFs{BZ4eZuO-p_$5R& zZp7kGl+@p+jm4iN#hY*N>%CIlJ$g!hogyK6b;iRZY8m{Ns8Xa;rHr_EHL68ZdSJ`;Ez^5R~xh`iI>U0LiVuCqWNGg&wFsly=}E zUVm}g4SM)bfYX5~OLU);_^azGBmZFr{(BSf|4{Jh5%P;xq>lyOBJ`}{j|#kT9hVNd zs9&mmLBetZVNz9`aS>0SSA(8@G1)lo+8Lj| ze*1fYSASPlUC*ooK3VEJ-s#?JGOe-<^UU*%Pv7zNqTsLUP1VC&4BvNreF6M1=#AdB zrlf|cB={rY=?M`^?A|o;kqpmJF@Gi}z|RMMB)m9ZtUK~WEg!>YNSzHFp{{eUVSLi1 zG6%=2<7kcGqs}wxdhbEthYFthY_H(6yNYAgbs{~-LH){bay+}Ijmr$ICx_`7h-(}0 zqd>p5lp_iS-kE^jn*e_e@bTn)Ap!k6z?0rGh2FA6y9XG3x>Q%p5$wJtF3-RMc9fve zXOn@C*RR?&H1BS=_JP4u@ii zPqE;WFZf&pd^|oC3Gly3fWMXDu|6r{j3EX~e@;N(odEw$0{kgZK|DDd7#?;k;q9^K zI&j&QfPOFV@$@hPZ&AhLKPdrT0iO7Dit(%ZRZ{}`%?a>tC&2drZ{b~v`Agq=8&6Ja z0(=wj@%-=)j2?b6m9uBh^5Jr`z#G@w|46|9d*DeA#`%9b8YR3jE-wT=o;+6rX^H76 z2ZF%I>+e$u==UU`{|I>e?~`m`PI7jLap4jaHNeMfHpAAexfEuNB49)MU5Y$LrtWaCu4sb~`-|uLSDx`b2}v<18u1A7|lsXYowW z+?gd4lx$x^eR;O6Ph0dPew?;qR|0k$y$*o40UB^Up|aY)3~#vv>iyM9KnOYA zJ*U9oR+NUu#fnQYysx2LRuXXMDvHnV!y6vxk=s7eQ}0nc9$z4!1j-jzdnF~7gLoBW zmLIQyuy;N@^?`;!BfcZuBURvajU~Q@fEOmJQ9RZDS}#nhRQQ!8)&9lh)k*~_H7Mnc zO_Il7Q&;T`cq_@D51*a;dVuyvD0kG}hECM-?5Uknl02iZX4k zW0q5K&Ms0E5Ko^yPjSiuDHqM9CL8<;e;Gq6x+J^aTbZpWOPZRLI=tfJuZ1@TmMcpk z8;K#Y79^$U(%Ft#u0qr{t0!B0jDQFf4bXMP&j|SG9fz$&EYkpTE9Z$B!JhCM5!`9dwljpR4ct$@1%q% ziG2yfAWe?&bfR<_DN8Rd3FPr{=ksHX^&NChgLIe8&Sl{SzthS~~+ zUg_xD^&%U`l>~CphJx0-7$Hmh@QsnJ$lj+CsWr9|UhrbCWc5)|sebh3>gN@zQeG3U zqkMLW?QZsXyR@v{7x4CJ;o=x+$(nkr=&Y@2t2mG8tq3}TjXh1}%D6>pQrTgQC^UgIcmDfa9MB*V|2P4n=oTzNx-Z%HlYtdblhM#0p5>Y3d& zM|&>_ruzlWIDHsa@Kp8nAWtQxPhUfw*IQxesj)fxFK;f!B&tLGw{!*ph`NKpW1pyb z7yN2*V`V(oighYxC_gFQSBn?&0t~Ao9W*Z;hvJd9+b`j)bWj(nnEzc8syPI`y&Hc4kRnqKA}& zMMN%w)G}WMqC4!!$5z1G zjkg_*eSyR1riY(pl34#$X9bPiew1s9&AD1JVPtHUQ=(3%U%34CMve?Qi^Hms0zS?ZZ;cidJnNr!1!b? z!d3%Dm$dVVQKy0&z91ye*Ex+YLQ)vkMMy0!*zGlby!^Uc?^mTRb)uv-8}*qF+r{M- zil@9GU@&;VgW0q^5a=@+N&-0^ymBn`sxB~$bH{khBMrWPHGRa4tU~+${Ut7`HfHvY zE-e1V5+;Y1jLu?cGR|ymS7P0pHKQ}E-Cj@c*z(Ekzp_Lp#<~$06$P(rCkPyTO~Tfb zKEEfRI<2-A1iwjaKjrN+YvOg}@;I?o*Re^oW^eGabyi7We2(g5a2Um3sqojND{BG> z5Ld@|Q1*Bm#w?3V#t{pFv_)Qy3tESx7@Rd$3qNtwhfp_5p_i1)Jzi%`4MeIjh}365 zM%Q4N3?}jSzg^m>gJw%$c?4dY;))JfLQe!5QK7QJTOFYJD%wXot-pVv4cU4&&Yr^% zq`}=jNxb}xP0o_W8f=I98W&>Bj2R0#%c{z;ALa7>i{UWQQ|&FUccP{7iVG`pd@y@> zV-zaFBAa&li0H3waQY17uF_dbbVrCC6YU2}`JQrK?J^&>2Y6Q<-9f#=LhN+dwp}+K zexfJPy2%6I4tSk&YvMUUsVkle4bsLg*D=}G`fJ(Fd#*S-FwO$n`GwH1wgm6HD}ild zOoJhy_nDvAPp6MBGGlqMsem?e*tTgR82Y9xsqxoRxUCP+c9 zRq7SKAi?MA2(ctw+*;t|iWJeU)^?urHOWEEkaW+y_0d6XU zW;|Hlvu&a{*kN4xu?gp)UK1Y@11y=yM&*7-KMc~y8w{>DtHXwa{^?4mNx5iM@vjwrq0T4eb>sQ-XpC4573UOaY zt!HeX?mOTXg(koH{EwPp_tWTj9=CS2`s#B+YOX$?2ojcrI4USD zz!g0!sLHQCPo(C%1*Iy#N~h*kD5qx+RakxQNX@%NeUhK#ROJ_Fi5|}(-fDgI`6M-0 zpLbN-SL>_&Um@xj2!`tOlWML$Z%Os(8Bt^X5OAauaa$|;ynzi!B=tE`4)wMFN)+hp ztItKLc{g=hmvF4llA7NFNMB!jekv!Hjzj$YR=QT}{~p)+`s#C5YOeoo1bscV{{4pf z>T^G8?wUZgqDif%VjjVTzJ2w%Ej7n&rT_zlMSYcy$|$L@ntux%$)vie`kcvLQU778 zq)Tc&71a-wNkwXX^|`m^c23bFI!xoAl3HK&quYSfx34}QS9dcbmpXW+{Z;F$xfzx9 z^`%Zhs#eq-i{sULYMyDVf1jxT?>txK6j)7u6+Q#?iI>`c_4%U=QD1FGr6*bS=~tqC zn;wa4wf?yVyjowM8@kA9