From 973c359c3836f4a9487441ff9c936d6cfb2fd6cb Mon Sep 17 00:00:00 2001 From: zhang_hl123 <53029136@qq.com> Date: Sun, 10 Nov 2024 22:14:27 +0800 Subject: [PATCH] rost Signed-off-by: zhang_hl123 <53029136@qq.com> --- README.md | 346 ++----------- vendor/yibaina_3061M/demo/rost/HMI.c | 438 ++++++++++++++++ vendor/yibaina_3061M/demo/rost/HMI.h | 40 ++ vendor/yibaina_3061M/demo/rost/README.md | 45 ++ vendor/yibaina_3061M/demo/rost/control.c | 386 ++++++++++++++ vendor/yibaina_3061M/demo/rost/control.h | 30 ++ .../demo/rost/generatecode/feature.h | 119 +++++ .../demo/rost/generatecode/main.h | 108 ++++ .../demo/rost/generatecode/system_init.c | 486 ++++++++++++++++++ vendor/yibaina_3061M/demo/rost/main.c | 227 ++++++++ ...\345\223\201\346\217\220\344\272\244.docx" | Bin 0 -> 162 bytes ...\345\223\201\346\217\220\344\272\244.docx" | Bin 0 -> 69943 bytes 12 files changed, 1924 insertions(+), 301 deletions(-) create mode 100644 vendor/yibaina_3061M/demo/rost/HMI.c create mode 100644 vendor/yibaina_3061M/demo/rost/HMI.h create mode 100644 vendor/yibaina_3061M/demo/rost/README.md create mode 100644 vendor/yibaina_3061M/demo/rost/control.c create mode 100644 vendor/yibaina_3061M/demo/rost/control.h create mode 100644 vendor/yibaina_3061M/demo/rost/generatecode/feature.h create mode 100644 vendor/yibaina_3061M/demo/rost/generatecode/main.h create mode 100644 vendor/yibaina_3061M/demo/rost/generatecode/system_init.c create mode 100644 vendor/yibaina_3061M/demo/rost/main.c create mode 100644 "vendor/yibaina_3061M/demo/rost/~$\346\265\267\346\200\235MCU\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\344\275\234\345\223\201\346\217\220\344\272\244.docx" create mode 100644 "vendor/yibaina_3061M/demo/rost/\344\270\212\346\265\267\346\265\267\346\200\235MCU\345\274\200\345\217\221\350\200\205\344\275\223\351\252\214\344\275\234\345\223\201\346\217\220\344\272\244.docx" diff --git a/README.md b/README.md index ec080bb91..ea97a3bbe 100644 --- a/README.md +++ b/README.md @@ -1,301 +1,45 @@ -# open_mcu开发指南 - -## 介绍 - - open_mcu代码仓为支持3061M和3065M解决方案SDK。 - -## 支持的开发板 - -| 开发板名称 | 硬件资料 | 软件资料 | 购买链接 | 开发板介绍 | -| :--------: | ------------------------------------------------------------ | :----------- | :----------------------------------------------------------- | :------------ | -| 3061M | [开发板硬件原理图](https://gitee.com/HiSpark/open_mcu/tree/master/docs/hardware/3061M) | 参考示例教程 | [开发板购买链接](https://m.tb.cn/h.gMEbHlepTLs5DNB?tk=aKIe356U3bY) | 参考3061M介绍 | -| 3065H | [开发板硬件原理图](https://gitee.com/HiSpark/open_mcu/tree/master/docs/hardware/3065H) | 参考示例教程 | [开发板购买链接](https://m.tb.cn/h.gMEbHlepTLs5DNB?tk=aKIe356U3bY) | 参考3065H介绍 | - -## 目录介绍 - -| 目录 | 介绍 | -| ------ | ---------------------- | -| docs | 硬件原理图 | -| src | SDK源码目录 | -| tools | 开发工具及环境搭建指南 | -| vendor | 存放对应开发板案例 | - -## 硬件介绍 - -### 3061M介绍 - -3061M系列 生态板由 ECBMCU201MPC(核心板)和 ECBMOTORA(电机驱动板组成)。 - -ECBMCU201MPC是针对 3061M系列 MCU开发的生态核心板,用于 3061M初始评估和设计参考,内嵌一块 USB接口的调试板。 - -ECBMOTORA是电机驱动扩展板,支持一个 BLDC或 PMSM电机控制。该单板支持24V/12V DCIN输入。 - -核心板电机驱动扩展板的常用组装方式是电机驱动板通过两个40pin连接器扣接到核心板,如下图所示。 - -![image-20240715162059747](docs/pic/tools/image-20240715162059747.png) - -### 3061M硬件说明 - - 3061M通用生态板通过 ECBMCU201MPC核心板实现控制、 ECBMOTORA 扩展板实现接口扩展以及电源接口,同时提供USB TypeC线进行调试 / 供电、12V电源适配器和一个电机。 - -![image-20240715162244103](docs/pic/tools/image-20240715162244103.png) - -3061M通用生态板用户手册详细内容请查阅:Hi3061M系列 通用生态板用户手册 00B01 - -### 3065H介绍 - -3065H 通用生态板由 ECBMCU105H (核心板)和 ECBMOTORA (电机驱动板)组成。 - -ECBMCU105H是针对 3065H 芯片开发的生态核心板,用于 3065H 芯片初始评估和设计参考,内嵌一块 USB 接口的调试板。 - -ECBMOTORA是电机驱动扩展板,支持一个 BLDC 或 PMSM 电机控制。该单板支持24V/12V DCIN 输入。 - -核心板电机驱动扩展板的常用组装方式是电机驱动板通过两个40pin 连接器扣接到核心板,如下图所示。 - -image-20240530173305431 - -### 3065H硬件说明 - - 3065H通用生态板通过ECBMCU105H 核心板实现控制、 ECBMOTORA 扩展板实现接口扩展以及电源接口,同时提供USB TypeC线进行调试 / 供电、12V电源适配器和一个电机。 - -![image-20240527103127826](docs/pic/tools/image-20240527103127826.png) - -3065H通用生态板用户手册详细内容请查阅:Hi3065H通用生态板用户手册 V03 - -## 开发环境搭建 - -[参考tools目录README搭建环境](https://gitee.com/HiSpark/open_mcu/tree/master/tools) - -## Demo - -3061M/3065H提供了以下Demo供开发参考,sample存放路径:[application_sample](https://gitee.com/HiSpark/open_mcu/tree/master/src/application) - -**主目录结构说明** - -| 文件夹名 | 描述 | -| ----------------- | -------------- | -| board\_sample | 开发板示例。 | -| drivers_sample | 驱动程序示例。 | -| middleware_sample | 中间件示例。 | -| user | 用户相关。 | - -**表 1 board\_sample目录结构说明** - -| **文件夹名** | **描述** | -| ------------ | -------------------------- | -| dimming | 呼吸灯功能示例。 | -| key | 按键检查功能示例。 | -| led | 数码管功能示例。 | -| pulses | gpio发送pwm波功能示例。 | -| softserial | gpio实现串口通信功能示例。 | - -**表 2 acmp目录结构说明** - -| **文件夹名** | **描述** | -| ------------ | ---------------- | -| sample_acmp | 比较器使用示例。 | - -**表 3 adc目录结构说明** - -| **文件夹名** | **描述** | -| ------------------------------------- | ------------------- | -| sample_adc_associative_trigger_of_apt | APT触发ADC。 | -| sample_adc_continue_trigger | ADC连续采样。 | -| sample_adc_over_sample | ADC过采样。 | -| sample_adc_single_trigger | ADC单次采样。 | -| sample_adc_single_trigger_dma | ADC单次采样带DMA。 | -| sample_adc_single_trigger_it | ADC单次采样带中断。 | -| sample_adc_sync_sample | ADC同步采样。 | -| sample_adc_sync_sample_dma | ADC同步采样带DMA。 | -| sample_adc_sync_sample_it | ADC同步采样带中断。 | - -**表 4 apt目录结构说明** - -| **文件夹名** | **描述** | -| -------------------------- | ------------------------------------------------- | -| sample_apt_single_resistor | APT单电阻采样示例,仅在U相触发ADC采样信号。 | -| sample_apt_three_resistor | APT三电阻采样示例,在U、V和W相都触发ADC采样信号。 | - -**表 5 can目录结构说明** - -| **文件夹名** | **描述** | -| ----------------------- | ----------------------- | -| sample_can_send_receive | CAN发送和接收数据示例。 | - -**表 6 capm目录结构说明** - -| **文件夹名** | **描述** | -| ---------------- | -------------------------- | -| capm_hall_sample | CAPM读取霍尔传感器值示例。 | - -**表 7 cfd目录结构说明** - -| **文件夹名** | **描述** | -| ---------------------- | ------------------------------------- | -| sample_cfd_check_error | cfd注入错误前后监测目标时钟异常功能。 | - -**表 8 cmm目录结构说明** - -| **文件夹名** | **描述** | -| ---------------------- | ------------------------------------- | -| sample_cmm_check_error | cmm注入错误前后监测目标时钟异常功能。 | - -**表 9 crc目录结构说明** - -| **文件夹名** | **描述** | -| ---------------- | -------------------------------------------------------- | -| sample_crc_check | 测试CRC不同算法和输入有效位宽,生成并校验crc值。 | -| sample_crc_gen | 计算并生成CRC数值。 | -| sample_crc_load | 通过load初始值将xmodem算法改为ccit-false算法并校验结果。 | - -**表 10 dac目录结构说明** - -| **文件夹名** | **描述** | -| ------------ | ----------------------- | -| sample_dac | DAC电压输出到管脚示例。 | - -**表 11 dma目录结构说明** - -| **文件夹名** | **描述** | -| --------------------------------- | ------------------------- | -| sample_dma_list_transfer | DMA链式传输。 | -| sample_dma_list_transfer_continue | DMA链式传输实现连续功能。 | -| sample_dma_mem_to_mem | DMA内存到内存传输。 | -| sample_dma_mem_to_per | DMA内存到外设传输。 | -| sample_dma_per_to_mem | DMA外设到内存传输。 | -| sample_dma_per_to_per | DMA外设到外设传输。 | - -**表 12 flash目录结构说明** - -| **文件夹名** | **描述** | -| ---------------------- | ------------------- | -| sample_flash_blocking | 阻塞模式操作flash。 | -| sample_flash_interrupt | 中断方式操作flash。 | - -**表 13 gpio目录结构说明** - -| **文件夹名** | **描述** | -| --------------------- | ---------------------------- | -| sample_gpio_circle | GPIO环回测试电平和方向属性。 | -| sample_gpio_interrupt | 测试GPIO不同中断类型。 | -| sample_gpio_key | GPIO用作按键功能。 | -| sample_gpio_led | GPIO周期控制led亮灭功能。 | - -**表 14 gpt目录结构说明** - -| **文件夹名** | **描述** | -| -------------------- | ---------------- | -| sample_gpt_simplerun | gpt产生PWM波形。 | - -**表 15 i2c目录结构说明** - -| **文件夹名** | **描述** | -| --------------------------- | ------------------------------ | -| sample_i2c_blocking_stlm75 | 使用阻塞的方式读写温度传感器。 | -| sample_i2c_interrupt_stlm75 | 使用中断的方式读写温度传感器。 | -| sample_i2c_dma_stlm75 | 使用dma方式读写温度传感器。 | - -**表 16 iocmg目录结构说明** - -| **文件夹名** | **描述** | -| ------------- | ----------------------------------- | -| iolist_sample | iocmg初始化管脚列表的属性配置功能。 | - -**表 17 pga目录结构说明** - -| **文件夹名** | **描述** | -| ------------------------- | --------------------- | -| sample_pga | PGA内部电阻放大示例。 | -| sample_pga_extra_resistor | PGA外部电阻放大示例。 | - -**表 18 pmc目录结构说明** - -| **文件夹名** | **描述** | -| ----------------- | ------------------- | -| sample_pmc_pvd | PMC掉电检测示例。 | -| sample_pmc_wakeup | PMC定时器唤醒示例。 | - -**表 19 qdm目录结构说明** - -| **文件夹名** | **描述** | -| ------------- | ------------------------------- | -| sample_qdm_m | QDM使用M法读取电机转速的示例。 | -| sample_qdm_mt | QDM使用MT法读取电机转速的示例。 | - -**表 20 spi目录机构说明** - -| **文件夹名** | **描述** | -| ---------------------------- | --------------------------------- | -| sample_spi_blocking_kta7953 | 使用阻塞方式读写ADC。 | -| sample_spi_dma_kta7953 | 使用dma方式读写ADC。 | -| sample_spi_interrupt_kta7953 | 使用中断方式读写ADC。 | -| sample_spi_microwire_master | 演示如何使用microwire master。 | -| sample_spi_microwire_slave | 演示如何使用microwire slave。 | -| sample_spi_slave | 演示如何使用motorola spi slaver。 | - -**表 21 timer目录结构说明** - -| **文件夹名** | **描述** | -| ---------------------- | ------------------------------------- | -| sample_timer_interrupt | timer定时触发中断,执行用户串口打印。 | - -**表 22 tsensor目录结构说明** - -| **文件夹名** | **描述** | -| -------------- | ----------------------- | -| sample_tsensor | tsensor对器件结温采样。 | - -**表 23 uart目录结构说明** - -| **文件夹名** | **描述** | -| ---------------------------------------- | ------------------------------------------ | -| sample_uart_blocking_rx | UART阻塞接收。 | -| sample_uart_blocking_tx | UART阻塞发送。 | -| sample_uart_dma_rx | UART带DMA接收。 | -| sample_uart_dma_tx | UART带DMA发送。 | -| sample_uart_interrupt_tx_after_rx | UART中断接收数据之后,再中断发送此数据。 | -| sample_uart_interrupt_rx | UART中断接收。 | -| sample_uart_interrupt_tx | UART中断发送。 | -| sample_uart_dma_tx_dma_rx_simultaneously | UART全双工模式,DMA同时发送和接收。 | -| sample_uart_dma_tx_int_rx_simultaneously | UART全双工模式,DMA发送的同时,中断接收。 | -| sample_uart_int_tx_dma_rx_simultaneously | UART全双工模式,中断发送的同时,DMA接收。 | -| sample_uart_int_tx_int_rx_simultaneously | UART全双工模式,中断发送的同时,中断接收。 | -| sample_uart_dma_rx_cyclically_stored | UART使用DMA循环搬运数据到指定内存。 | -| sample_uart_single_wire_communication | UART单线通信示例。 | - -**表 24 wdg目录机构说明** - -| **文件夹名** | **描述** | -| ----------------- | ------------------------ | -| sample_wdg_reset | 测试wdg不喂狗复位功能。 | -| sample_iwdg_reset | 测试iwdg不喂狗复位功能。 | - -**表 25 middleware\_sample目录机构说明** - -| **文件夹名** | **描述** | -| -------------------------- | --------------------------------------- | -| mcs_65ldemo | 电机控制算法在AD101HDMA_VER.B板的示例。 | -| mcs_65demo | 电机控制算法在AD105HDMA_VER.B板的示例。 | -| pmsm_sensorless_1shunt_foc | 永磁同步电机单电阻采样无感FOC应用。 | -| pmsm_sensorless_2shunt_foc | 永磁同步电机双电阻采样无感FOC应用。 | - -## **问题与解答** - -如果你对项目中的代码或者文档存在疑问, 欢迎在Issues中提出你的问题(别忘了先在FAQ中看一看是否已经有答案了😎). 如果你自己解决了一个了不起的问题, 非常欢迎你把问题和解决方法发到Issues里, 如果你看到别人的问题而你正好有答案, 也欢迎你帮助解答其他人的问题, 所谓"授人玫瑰手有余香"嘛。 - -## **参与贡献** - -我们非常欢迎你能对这个项目提出代码上的改进或扩展, 方法是: - -1. Fork 本仓库 -2. 下载到本地, 修改, 提交 -3. 推送代码 -4. 在页面点击 Pull Request - -这样我们就能接到你的推送申请。 - -## **最后的话** - -Hispark Studio是一款年轻且处于快速发展的IDE。在使用过程中,你可能会碰到一些棘手的问题,但别担心,你可以尝试多种方法去解决,比如用搜索引擎寻找答案,或者向社区寻求帮助。记住,所有技术大神都是从解决这些问题中成长起来的。我们和其他开发者也会尽力提供帮助。 - -最后的最后, 欢迎来到Hispark Studio的世界探险! \ No newline at end of file +## 基于海思MCU智能蒸烤箱控制系统 + +## 一、前言 +本设计旨在通过上海海思3061M开发板以及无刷电机套件、PID温控等技术实现蒸烤箱的全自动控制等功能。侧重点在于体验海思MCU开发流程,包括开发环境搭建、程序仿真调试下载以及MCU外设配置和应用。 +## 二、设计内容 +单片机控制系统设计 +海思3601M开发套件作为控制核心,负责接收传感器信号、处理用户指令,并根据预设程序控制蒸烤箱的各个部件工作。 +传感器系统设计 +选用热电偶温度传感器,实时监测蒸烤箱内的温度,确保食物在合适的温度下烹饪。 +用户界面设计 +使用大彩3.5”串口屏作为机器用户界面,方便用户进行参数设置和状态查看。 +## 三、设计方法及步骤 +## 系统设计 +根据智能烤箱功能,设计整体系统架构,包括单片机控制系统、传感器系统、固态继电器、加热器、用户界面等,未做箱体。 + + +## 硬件设计 +1.MAX6675+热电偶温度传感器采集箱内温度 +2.PWM驱动固态继电器模块加热管加热 +3.3.5寸大彩串口屏显示模式、运行时间 +4. MOSFET控制蒸汽发生器产生蒸汽 + +## 软件设计 +蒸烤箱设置三种工作模式:蒸模式、烤模式、蒸烤模式 +蒸烤箱工作程序如下: +加热:程序启动后,电热器开始全功率加热,到达预设温度后由PID控制温度值,对食物加热。 +蒸汽:本设计采用蒸汽发生器产生蒸汽,由MOSFET控制蒸汽发生器工作。 +明确智能蒸烤箱设计功能后,围绕以上功能实现软件逻辑: +1、参考3061M套件提供SPI样例,实现MAX6675的温度采集 +Temp_PV_A=Get_max6675temp(); //获取温度 +2、通过PWM和PID算法精准控温 +温度调节PID:Temp_PID() +3、通过UART2通信实现串口屏通信。 +void Send2_Byte(uint8_t data1) +void Sent_Temp(uint16_t screen_id,uint16_t control_id,uint16_t num) +4.主控制程序采用轮询方式调用。 +void Main_Control(void) + +## 使用方法 +1、在主界面上选择烹饪模式:蒸汽、干烤、蒸烤; +2、选择烹饪温度; +3、选择烹饪时间; +4、按执行工作按钮,进入自动烹饪工作状态; +5、烹饪结束; +6、返回主界面。 diff --git a/vendor/yibaina_3061M/demo/rost/HMI.c b/vendor/yibaina_3061M/demo/rost/HMI.c new file mode 100644 index 000000000..2407958e9 --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/HMI.c @@ -0,0 +1,438 @@ +#include "HMI.h" +#include "stdio.h" +#include "stdint.h" +//#include "control.h" +#include "main.h" +#include "debug.h" +#include "clock.h" + +#define Power_PARA 100 //加热器功率参数 +#define Delay_sensor 100 //新版传感器延时时间 +#define SW_ON 1 +#define ON 1 +#define SW_OFF 0 +#define OFF 0 +//低温烹饪过程菜单定义 +//extern mymenu def_menu[20]; //设置为全局变量 +/*******************************************************************************/ + +extern uint16_t Slider_A; +extern uint8_t cmd_buffer[64],gucDecoderIndex; //指令缓冲区 +extern uint16_t Temp_text_id; + +extern uint8_t cmd_size; +extern _Bool RUN_ON,Timer_EN1,Pause_ON; + +/********************用户预约变量*******************************************/ +uint16_t Picture_ID; +extern uint8_t Screen_ID,Time_setvalue_H,Time_setvalue_M,Time_setvalue_S; + +extern uint16_t Temp_PV_A; + +extern uint8_t Power_on,Workmode; +extern uint32_t time_setvalue; + +uint16_t food_T; +uint16_t Temp_1,Temp_3; +extern uint16_t Temp_setvalue; +uint16_t Temp_6; +uint8_t current_pict_ID; + +/********************选锅状态*******************************************/ +//uint8_t mode_name[36]={"蒸汽干烤蒸烤回温△T预热保温除湿加湿"}; +uint8_t info[80]; + +void Send2_Byte(uint8_t data1) +{ + while (UART2->UART_FR.BIT.txff == 1) { + ; + } + UART2->UART_DR.BIT.data = (unsigned char)data1; +} + +void END_CMD(void) +{ + Send2_Byte(0xFF); + Send2_Byte(0xFC); + Send2_Byte(0xFF); + Send2_Byte(0xFF); +} + +/******获取HMI系统时间指令******************************/ +void Get_Sys_Date_CMD(void) + { + BEGIN_CMD(); + Send2_Byte(0x82); + END_CMD(); + } + + +/******系统复位******************************/ +void System_Reset(void) + { + BEGIN_CMD(); + Send2_Byte(0x07); + Send2_Byte(0x35); + Send2_Byte(0x5A); + Send2_Byte(0x53); + Send2_Byte(0xA5); + END_CMD(); + } + +/*! +* \brief 获取当前画面 +*/ +uint16_t GetScreen(void) +{ + uint16_t screen_id1; + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x01); + END_CMD(); + screen_id1=(cmd_buffer[3]<<8)+cmd_buffer[4]; + DBG_PRINTF("screen_id %x \r\n",screen_id1); + return screen_id1; +} + + /**********************显示隐藏控件************************** + * 入口参数: + * uint16_t screen_id:屏幕ID + * uint16_t control_id:控件ID + * uint8_t value:设置值,1-显示,0-隐藏 + * ********/ +void Desplay_Hide(uint16_t screen_id,uint16_t control_id,uint8_t value) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x03); + Send_16(screen_id); + Send_16(control_id); + Send2_Byte(value); + END_CMD(); +} + +/**********************禁用/使能控件************************** + * 入口参数: + * uint16_t screen_id:屏幕ID + * uint16_t control_id:控件ID + * uint8_t value:设置值,1-使能,0-禁止 + * ********/ +void Disable_enable(uint16_t screen_id,uint16_t control_id,uint8_t value) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x04); + Send_16(screen_id); + Send_16(control_id); + Send2_Byte(value); + END_CMD(); +} + + +/*********************文本发送***************************************/ +void Send_Text_A(uint16_t screen,uint16_t coutrol,char Text) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen); + Send_16(coutrol); + Send2_Byte(Text); + END_CMD(); +} + +/**********************读文本值***************************************/ +void Read_Text(uint16_t screen,uint16_t coutrol) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x11); + Send_16(screen); + Send_16(coutrol); + END_CMD(); +} + +/**********************汉字发送***************************************/ +void Send_Text_4(uint16_t screen,uint16_t coutrol,uint8_t Text_1,uint8_t Text_2,uint8_t Text_3,uint8_t Text_4) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen); + Send_16(coutrol); + Send2_Byte(Text_1); + Send2_Byte(Text_2); + Send2_Byte(Text_3); + Send2_Byte(Text_4); + END_CMD(); +} + +/******改变字体颜色*****************************/ +void Text_Color(uint16_t screen_id,uint16_t control_id,uint16_t value) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x19); + Send_16(screen_id); + Send_16(control_id); + Send_16(value); + END_CMD(); +} + +/******进度条控件*************/ +void Circle_proc(uint16_t screen_id,uint16_t control_id,uint16_t Start_Angle,uint16_t End_Angle) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen_id); + Send_16(control_id); + Send_16(Start_Angle); + Send_16(End_Angle); + END_CMD(); +} + +/***************发送5位整数************************************************ +* 函 数 名: Sent_Value() +* 函数功能: 获得按键输入 +* 输 入: screen_id 屏幕ID +* 输 入: control_id控件ID +* 输 入: num发送的数据 +* 输 出: 无 +**************************************************************************/ +void Sent_Value(uint16_t screen_id,uint16_t control_id,uint16_t num) +{ +// DBG_PRINTF("数值: %d \r\n",num); + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen_id); + Send_16(control_id); + if(num/1000) + { + Send2_Byte(num/1000+48); + Send2_Byte(num%1000/100+48); + Send2_Byte(num%100/10+48); + Send2_Byte(num%10+48); + } + else if(num/100) + { + Send2_Byte(num/100+48); + Send2_Byte(num%100/10+48); + Send2_Byte(num%10+48); + } + else if(num/10) + { + Send2_Byte(num/10+48); + Send2_Byte(num%10+48); + } + else Send2_Byte(num%10+48); + END_CMD(); +} + + +/**********************显示icon控件状态***********************************/ +void Desplay_Icon(uint16_t screen_id,uint16_t control_id,uint8_t value) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x23); + Send_16(screen_id); + Send_16(control_id); + Send2_Byte(value); + END_CMD(); +} + +/******切换画面*******************************************************/ +void Screen_Change(uint16_t screen_id) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x00); + Send_16(screen_id); + END_CMD(); +} + +/**********************设置按钮状态***********************************/ +void Key_State(uint16_t screen_id,uint16_t control_id,uint8_t value) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen_id); + Send_16(control_id); + Send2_Byte(value); + END_CMD(); +} + +/**********************读取按钮状态***********************************/ +void Read_Key_State(uint16_t screen_id,uint16_t control_id) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x11); + Send_16(screen_id); + Send_16(control_id); + END_CMD(); +} + +/**********************读取开关按钮值***********************************/ +int8_t Read_Key_value(uint16_t screen_id1,uint16_t control_id1) +{ + _Bool Key_value=0; + Read_Key_State(screen_id1,control_id1); +// Read_UART_DMA_AnyLenData(&g_uart2); + if (cmd_buffer[7]==0x10) Key_value=cmd_buffer[9]; + return Key_value; +} + +/**********************更新滑动条数值**********************************/ +void Slider_Set(uint16_t screen_id,uint16_t control_id,uint8_t value) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen_id); + Send_16(control_id); + Send2_Byte(0x00); + Send2_Byte(0x00); + Send2_Byte(0x00); + Send2_Byte(value); + END_CMD(); +} + +/******************发送时间数据,****************************************/ +void Sent_Time(uint16_t screen_id,uint16_t control_id,uint8_t num) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen_id); + Send_16(control_id); + Send2_Byte(num/10+0x30); + Send2_Byte(num%10+0x30); + END_CMD(); +} + +/******************发送字节数据,****************************************/ +void Sent_Char(uint16_t screen_id,uint16_t control_id,uint8_t num) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen_id); + Send_16(control_id); + if(num/100) + { + Send2_Byte(num/100+0x30); + Send2_Byte(num%100/10+0x30); + Send2_Byte(num%10+0x30); + } + else + { + if(num/10) + { + Send2_Byte(num/10+0x30); + Send2_Byte(num%10+0x30); + } + else Send2_Byte(num%10+0x30); + } + END_CMD(); +} + +/******************发送温度数据,1位小数**********************************/ +void Sent_Temp(uint16_t screen_id,uint16_t control_id,uint16_t num) +{ + BEGIN_CMD(); + Send2_Byte(0xB1); + Send2_Byte(0x10); + Send_16(screen_id); + Send_16(control_id); +// if(num>=0) +// { + if(num/1000) + { + Send2_Byte(num/1000+0x30); + Send2_Byte(num%1000/100+0x30); + Send2_Byte(num%100/10+0x30); + Send2_Byte(0x2E); + Send2_Byte(num%10+0x30); + } + else + { + if(num/100) + { + Send2_Byte(num/100+0x30); + Send2_Byte(num%100/10+0x30); + Send2_Byte(0x2E); + Send2_Byte(num%10+0x30); + } + else + { + Send2_Byte(num/10+0x30); + Send2_Byte(0x2E); + Send2_Byte(num%10+0x30); + } + } + END_CMD(); +} + + +/************************************************************************** +* 函 数 名: Get_Time_Set() +* 函数功能: 获取时间设定值 +* 输 入: 无 +* 输 出: uint16_t Tempe +***************************************************************************/ +uint16_t Get_Time_Set(uint16_t screen_ID,uint16_t coutrol_ID) +{ + static uint16_t Tempe1=0; + Read_Text(screen_ID,coutrol_ID); //读取时间分钟值 + BASE_FUNC_DelayMs(10); + if(cmd_size==14) Tempe1=(cmd_buffer[8]-0x30); + if(cmd_size==15) Tempe1=(cmd_buffer[8]-0x30)*10+(cmd_buffer[9]-0x30); + if(cmd_size==16) Tempe1=(cmd_buffer[8]-0x30)*100+(cmd_buffer[9]-0x30)*10+(cmd_buffer[10]-0x30); + DBG_PRINTF("time data11: %d \r\n",Tempe1); + return Tempe1; +} + +/******************获取画面4指令***********************************************/ +void Screen3_Instruct(void) +{ + switch(cmd_buffer[6]) + { + case 1: + Screen_Change(0); + return; + break; + default: + break; + } +} + + +/**********显示温度、时间变化数据*************** + * 函数名:Sand_Data() + * 功能:实时显示温度、时间值 + * 入口参数: 无 + * 出口参数:无 + * *********************************/ +void Sand_Data(uint16_t screen1,uint16_t control_id) +{ + Sent_Value(screen1,5,Slider_A); + Circle_proc(screen1,control_id,271,271+360*Slider_A/100); + Sent_Value(screen1,19,Time_setvalue_H); + Sent_Value(screen1,28,Time_setvalue_M); + Sent_Value(screen1,2,Time_setvalue_S); + Sent_Temp(screen1,25,Temp_PV_A); +} + +/***********读列表数据并执行统一运行界面程序*********/ +void Read_Run(void) +{ + Power_on=RUN_ON=ON; + Key_State(3,21,0); + Circle_proc(3,10,271,272); + Desplay_Hide(3,10,1); + Screen_Change(3); +} diff --git a/vendor/yibaina_3061M/demo/rost/HMI.h b/vendor/yibaina_3061M/demo/rost/HMI.h new file mode 100644 index 000000000..74ef67729 --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/HMI.h @@ -0,0 +1,40 @@ +#include "stdio.h" +#include "stdint.h" +#include "debug.h" +#include "clock.h" + +#define CMD_HEAD 0XEE +#define CMD_TAIL 0XFFFCFFFF +#define Send_16(P1) Send2_Byte((P1)>>8);Send2_Byte(P1) +#define Send_32(P1) Send_16((P1)>>16);Send_16((P1)&0xFFFF) +#define BEGIN_CMD() Send2_Byte(0XEE) //发送帧头 + +void END_CMD(void); +void Send2_Byte(uint8_t data1); +uint16_t Get_Temp_Set(uint16_t screen,uint16_t coutrol); +uint16_t Get_Time_Set(uint16_t screen_ID,uint16_t coutrol_ID); + +void Get_HMI_Instruct(void); +void System_Reset(void); //系统复位 +void Sent_Value(uint16_t screen_id,uint16_t control_id,uint16_t num); +void Sent_Temp(uint16_t screen_id,uint16_t control_id,uint16_t num); +void Read_Text(uint16_t screen,uint16_t coutrol); +void Send_Text_4(uint16_t screen,uint16_t coutrol,uint8_t Text_1,uint8_t Text_2,uint8_t Text_3,uint8_t Text_4); +void Desplay_Hide(uint16_t screen_id,uint16_t control_id,uint8_t value); //显示/隐藏控件 +void Disable_enable(uint16_t screen_id,uint16_t control_id,uint8_t value); //禁止控件使能 +void Text_Color(uint16_t screen_id,uint16_t control_id,uint16_t value); +void Desplay_Icon(uint16_t screen_id,uint16_t control_id,uint8_t value); +void Key_State(uint16_t screen_id,uint16_t control_id,uint8_t value); +int8_t Read_Key_value(uint16_t screen_id1,uint16_t control_id1); //读取按键值 +void Read_Key_State(uint16_t screen_id,uint16_t control_id); //读取按键状态 +void Get_Sys_Date_CMD(void); +void Send_Text_A(uint16_t screen,uint16_t coutrol,char Text); +void Sent_Time(uint16_t screen_id,uint16_t control_id,uint8_t num); +void Sent_Char(uint16_t screen_id,uint16_t control_id,uint8_t num); +void Screen_Change(uint16_t screen_id); +void Slider_Set(uint16_t screen_id,uint16_t control_id,uint8_t value); +void Circle_proc(uint16_t screen_id,uint16_t control_id,uint16_t Start_Angle,uint16_t End_Angle); +uint16_t GetScreen(void); +void Screen3_Instruct(void); //中心温度设置界面指令处理(screen3) +void Sand_Data(uint16_t screen1,uint16_t control_id); +void Read_Run(void); //读列表数据并执行统一运行 \ No newline at end of file diff --git a/vendor/yibaina_3061M/demo/rost/README.md b/vendor/yibaina_3061M/demo/rost/README.md new file mode 100644 index 000000000..ea97a3bbe --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/README.md @@ -0,0 +1,45 @@ +## 基于海思MCU智能蒸烤箱控制系统 + +## 一、前言 +本设计旨在通过上海海思3061M开发板以及无刷电机套件、PID温控等技术实现蒸烤箱的全自动控制等功能。侧重点在于体验海思MCU开发流程,包括开发环境搭建、程序仿真调试下载以及MCU外设配置和应用。 +## 二、设计内容 +单片机控制系统设计 +海思3601M开发套件作为控制核心,负责接收传感器信号、处理用户指令,并根据预设程序控制蒸烤箱的各个部件工作。 +传感器系统设计 +选用热电偶温度传感器,实时监测蒸烤箱内的温度,确保食物在合适的温度下烹饪。 +用户界面设计 +使用大彩3.5”串口屏作为机器用户界面,方便用户进行参数设置和状态查看。 +## 三、设计方法及步骤 +## 系统设计 +根据智能烤箱功能,设计整体系统架构,包括单片机控制系统、传感器系统、固态继电器、加热器、用户界面等,未做箱体。 + + +## 硬件设计 +1.MAX6675+热电偶温度传感器采集箱内温度 +2.PWM驱动固态继电器模块加热管加热 +3.3.5寸大彩串口屏显示模式、运行时间 +4. MOSFET控制蒸汽发生器产生蒸汽 + +## 软件设计 +蒸烤箱设置三种工作模式:蒸模式、烤模式、蒸烤模式 +蒸烤箱工作程序如下: +加热:程序启动后,电热器开始全功率加热,到达预设温度后由PID控制温度值,对食物加热。 +蒸汽:本设计采用蒸汽发生器产生蒸汽,由MOSFET控制蒸汽发生器工作。 +明确智能蒸烤箱设计功能后,围绕以上功能实现软件逻辑: +1、参考3061M套件提供SPI样例,实现MAX6675的温度采集 +Temp_PV_A=Get_max6675temp(); //获取温度 +2、通过PWM和PID算法精准控温 +温度调节PID:Temp_PID() +3、通过UART2通信实现串口屏通信。 +void Send2_Byte(uint8_t data1) +void Sent_Temp(uint16_t screen_id,uint16_t control_id,uint16_t num) +4.主控制程序采用轮询方式调用。 +void Main_Control(void) + +## 使用方法 +1、在主界面上选择烹饪模式:蒸汽、干烤、蒸烤; +2、选择烹饪温度; +3、选择烹饪时间; +4、按执行工作按钮,进入自动烹饪工作状态; +5、烹饪结束; +6、返回主界面。 diff --git a/vendor/yibaina_3061M/demo/rost/control.c b/vendor/yibaina_3061M/demo/rost/control.c new file mode 100644 index 000000000..b4b63476a --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/control.c @@ -0,0 +1,386 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. 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. + * 3. 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. + * @file sample_spi_interrupt_w25q32.c + * @author MCU Driver Team + * @brief Sample for SPI Module Interrupt. + * @details This sample is used to operate the HAL interface on the W25Q32 chip of the flash. + * Write data and read data to address 0 of W25Q32 + */ + +#include "main.h" +#include "spi.h" +#include "debug.h" +#include "stdio.h" +#include "stdint.h" +#include "string.h" +#include "control.h" +#include "math.h" + +extern _Bool Pause_ON,StopStatus,RUN_ON; +float Temp_Con_Water,mcu_T,Error_setvalue; //冷凝水温度,MCU温度 +float T_A_Error,Temp_probe_AV; //平均温度 +extern uint16_t food_T,Picture_ID,Temp_text_id,Temp_setvalue,Temp_PV_A; +/********************PID调节变量*******************************************/ +uint8_t Init_A,Power_PARA,Work_Step_A; +/********************用户预约变量*******************************************/ +extern uint8_t Time_setvalue_H,Time_setvalue_M,Time_setvalue_S,Workmode; +volatile uint8_t water_pump_time_on,water_pump_time_off; +extern uint32_t work_time,timerct; +volatile uint32_t timercnt3; +extern uint32_t time_setvalue; +_Bool Temp_flag; //温度到标志位 + +/********************PID调节变量*******************************************/ + +volatile uint16_t PWM_ticks,Slider_A; +volatile uint8_t Power_on,PID_ticks,PID_CAL_A,Timer_EN1; +uint16_t PWM_A,PWM_B,Power_value; +uint8_t PWM_out,Power_P,ON_A; //Power_value功率调节因子 + +/********************调温滑块变量*******************************************/ +uint8_t Control_mode,slider_id; //工作模式Workmode + +//蒸汽产生时间参数设置 +void vapor_para(uint8_t pump_time) +{ + water_pump_time_on=60; + water_pump_time_off=40; + if (pump_time==3) + { + water_pump_time_off=5; //蒸烤模式喷水时长5s + water_pump_time_on=50; //喷水时间间隔 +// DBG_PRINTF("pump_time water_pump_time_off2 %d %d \r\n",pump_time,water_pump_time_off); + } +} + +/******************加热器温度PID计算*************** + *函数名:Temp_PID() + *串口参数:PID_out:PID值 + *使用说明:计算温度调节PID值 + * *********************************/ + +uint16_t Temp_PID(uint16_t init_value,float error,float PID_I,float PID_P) +{ + float Integ=0; + float P,I; + float PID_out; + + P=(float)(error*PID_P); + if((error-Error_setvalue)) + Integ=Integ+error*PID_I; + else Integ=0; + I=(float)Integ; + PID_out=(uint16_t)(init_value+P+I); + if(PID_out>200) + PID_out=200; + if(PID_out<0) + PID_out=0; + return PID_out; +} + +/******************加热器温度PID控制**************************** +*函数名:Heater_Control() +* 入口参数:无 +* 串口参数:无 +*使用说明:加热器PID调节自动控制启停 +*************************************************/ +void Heater_Control() +{ + T_A_Error=(float)Temp_setvalue-Temp_PV_A/10; + Power_Conj(); + if(PID_CAL_A==1) //定时计算 + { + PWM_A=Temp_PID(Init_A,T_A_Error,0.02,0.8); + PID_CAL_A=0; + } + if(PWM_ticks=60) && (Power_P<=80)) Power_value=20; //实时温度介于设定值的70~90%之间,80%功率加热 + if (Power_P>80) Power_value=40; //实时温度大于设定值的90%,70%功率加热 +} + +/******************模式A参数设定***********************************************/ +void Mode_Parameter(uint8_t Mode_A) +{ + timerct=0; //时间计数清零 + Control_mode=0; //加热控制方式为定时 + Init_A=50; //PID调节初始参数 + Slider_A=0; //进度条比例初始值 + Desplay_Hide(3,9,0); + switch (Mode_A) { + case 0: + Power_on=0; + Pause_ON=OFF; //加热器模拟电源开关关闭 + Timer_EN1=0; + Control_mode=0; //加热控制方式为定时 + Temp_text_id=4; + Desplay_Hide(0,4,1); + Desplay_Hide(0,31,0); + Desplay_Hide(0,32,0); + HAL_TIMER_Stop(&g_timer1); //关闭TIM1 + HAL_TIMER_Stop(&g_timer0); //关闭TIM0 + Workmode=1; //工作模式:蒸汽 + Send_Text_4(3,4,0xD5,0xF4,0xC6,0xFB); + Screen_Change(0); + break; + case 1: //蒸煮模式 + // strcpy(info, p); + Common_para(10); //设置公共参数 + Control_mode=0; //加热控制方式为定时 + vapor_para(1); //喷水时间参数 + Work_Step_A=1; //工作流程1 + Send_Text_4(3,4,0xD5,0xF4,0xC6,0xFB); + break; + case 2: //干烤模式 + Common_para(10); //设置公共参数 + Control_mode=0; //加热控制方式为定时 + Work_Step_A=2; //工作流程2 + Send_Text_4(3,4,0xB8,0xC9,0xBF,0xBE); + HAL_TIMER_Stop(&g_timer1); //关闭TIM1 + break; + case 3: //蒸烤模式 + Common_para(10); //设置公共参数 + Control_mode=0; //加热控制方式为定时 + vapor_para(3); //喷水时间参数 + Work_Step_A=3; //工作流程3 + Send_Text_4(3,4,0xD5,0xF4,0xBF,0xBE); + break; + default: + break; + } +} + +/******************公共参数设置***************** + * 函数名;Common_para(uint8_t slider_no) + * 功能:公共参数设置 + * 入口参数:uint8_t slider_no,进度条选择 + * 串口参数:无 + * *********************************************/ +void Common_para(uint8_t slider_no) +{ + Power_on=ON; + Timer_EN1=ON; + Pause_ON=OFF; + timerct=0; + slider_id=slider_no; + Circle_proc(3,slider_no,271,272); + Desplay_Hide(3,10,1); + HAL_TIMER_Start(&g_timer1); + HAL_TIMER_Start(&g_timer0); + HAL_TIMER_Start(&g_timer2); + Screen_Change(3); +} + +/******************加热主控制A***********************************************/ +void Main_Control(void) +{ + switch(Work_Step_A) + { + case 0: + Screen_Change(0); + break; + case 1: //蒸模式 + Heater_Control(); + if ((time_setvalue-timerct)<=0) + { + DBG_PRINTF("时间到: \r\n"); + End_Control(); + break; + } + if ((fabs(T_A_Error)<=3) || ((Temp_PV_A/10)>(float)Temp_setvalue)) Heater_power(0); + else Heater_power(Power_value); + break; + case 2: //烤模式 + Heater_Control(); + if ((time_setvalue-timerct)<=0) + { + DBG_PRINTF("时间到: \r\n"); + End_Control(); + break; + } + if ((fabs(T_A_Error)<=3) || ((Temp_PV_A/10)>(float)Temp_setvalue)) Heater_power(0); + else Heater_power(Power_value); + break; + case 3: //蒸烤模式 + Heater_Control(); + if ((time_setvalue-timerct)<=0) + { + DBG_PRINTF("时间到: \r\n"); + End_Control(); + break; + } + if ((fabs(T_A_Error)<=3) || ((Temp_PV_A/10)>((float)Temp_setvalue))) Heater_power(0); + else Heater_power(Power_value); + break; + default: + break; + } +} + +/********************************** + * 函数名:End_Control + * 功能:烹饪流程结束时,系统参数恢复 + * 入口参数:无 + * 串口参数:无 +**********************************/ +void End_Control(void) +{ + Power_on=OFF; + RUN_ON=OFF; + Pause_ON=OFF; + Time_setvalue_H=0; + Time_setvalue_M=0; + Time_setvalue_S=0; + Water_P_con(OFF); + Heater_power(0); + Work_Step_A=0; + timerct=0; + timercnt3=0; + Workmode=0; + FanMotor_con(OFF); + HAL_TIMER_Stop(&g_timer1); + HAL_TIMER_Stop(&g_timer0); + HAL_TIMER_Stop(&g_timer2); + Desplay_Hide(3,slider_id,0); + Desplay_Hide(3,9,1); + DBG_PRINTF("Rost End \r\n"); + BASE_FUNC_DelayMs(1000); + Screen_Change(2); + return; +} + + +void TIMER1_InterruptProcess(void *handle) +{ + BASE_FUNC_UNUSED(handle); + { + if (Power_on) + { + timercnt3++;//计时自加1 + if((timercnt3%water_pump_time_on)==0)//12s + { + Heater_power(100); + BASE_FUNC_DelayMs(200); + } + if(timercnt3%(water_pump_time_on+water_pump_time_off)==0) + { + timercnt3=0; + } + } + if(timercnt3>65000) + { + timercnt3=0; + } + } + /* USER CODE END TIMER2_InterruptProcess */ +} + +void TIMER2_InterruptProcess(void *handle) +{ + BASE_FUNC_UNUSED(handle); +// if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否 + { + PWM_ticks++; + PID_ticks++; + if(PWM_ticks>=200) + PWM_ticks=0; + if (PWM_ticks>40) + { + PID_CAL_A=1; + PID_ticks=0; + } + + } +} +static unsigned char g_rxStr =0; +static unsigned char g_txStr =0xff; + + +//读温度 +/* +******************************************************************************** +** @name : Get_max6675temp +** @函数功能 : 获取MAX6675读取的热电偶的值 +** @函数说明 :K型热电偶读取函数 +** @输出参数 :成功返回TRUE 否者热电偶 +******************************************************************************** +*/ + +int Get_max6675temp(void) +{ + uint8_t flag; + uint16_t i,t,t1; + float temprature; + MAX6675_CSL(); + + HAL_SPI_WriteReadIT(&g_spi0, &g_rxStr,&g_txStr,1); + i= g_rxStr<<8; + HAL_SPI_WriteReadIT(&g_spi0,&g_rxStr,&g_txStr,1); + i = i|g_rxStr; + MAX6675_CSH(); + flag = i&0x04; + t = i>>3; + temprature =(float)1023.75*t/4096; + t1=(uint16_t)(temprature*100)/10; + if(i!=0) + { + if(flag==0) + { + DBG_PRINTF("temperature test:%d %f \r\n",t1,temprature); + } + } + else + { + DBG_PRINTF("The thermocouple is not connected\r\n"); + } + return t1; +} diff --git a/vendor/yibaina_3061M/demo/rost/control.h b/vendor/yibaina_3061M/demo/rost/control.h new file mode 100644 index 000000000..1a92a1373 --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/control.h @@ -0,0 +1,30 @@ +#ifndef _MAX6675_H +#define _MAX6675_H + +#include "stdio.h" +#include "stdint.h" +#include "main.h" +#include "debug.h" +#include "gpio.h" +#include "iocmg_ip.h" + +//#define MAX6675_CS_PORT GPIOA +#define MAX6675_CS_PIN GPIO_PIN_5 +#define MAX6675_CSL() HAL_SPI_SetChipConfigSelectEx(&g_spi0, HAL_SPI_CHIP_CONFIG_SOFR_UNSET) +#define MAX6675_CSH() HAL_SPI_SetChipConfigSelectEx(&g_spi0, HAL_SPI_CHIP_CONFIG_SOFR_SET) + +int Get_max6675temp(void); +uint16_t Temp_PID(uint16_t init_value,float error,float PID_I,float PID_P); + +void Heater_Control(void); +void Time_Control(void); + +void Main_Control(void); +void Mode_Parameter(uint8_t Mode_A); //模式参数设置值 +void vapor_para(uint8_t pump_time); //蒸汽产生时间参数设置 +void Heater_power(uint16_t n); +void Power_Conj(void); //加热功率PWM占空比因子调节函数 +void End_Control(void); //烹饪流程结束时系统参数重置 +void Common_para(uint8_t slider_no); //公共参数设置 + +#endif diff --git a/vendor/yibaina_3061M/demo/rost/generatecode/feature.h b/vendor/yibaina_3061M/demo/rost/generatecode/feature.h new file mode 100644 index 000000000..1e8331dc3 --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/generatecode/feature.h @@ -0,0 +1,119 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. 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. + * 3. 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. + * @file feature.h + * @author MCU Driver Team + * @brief This file contains macro configurations related to the project. This file is generated by the IDE tool. + */ + +#ifndef McuMagicTag_FEATURE_H +#define McuMagicTag_FEATURE_H + +/* Macro definitions --------------------------------------------------------- */ +#define CHIP_3061MNPICA MACRO_ENABLE + +#define MACRO_ENABLE 1 +#define MACRO_DISABLE 0 + +/* Macro switch */ +#define BASE_DEFINE_USE_ASSERT MACRO_ENABLE +#ifndef FLASH_CRC_CONFIG +#define FLASH_CRC_CONFIG +#endif /* #ifndef FLASH_CRC_CONFIG */ +#define BASE_MATH_SINCOS_MIDDLE_TABLE MACRO_ENABLE /**< This macro is used to control the table type when the + BASE_MATH_GetSinCos() queries the table. When the value of + this macro is MACRO_ENABLE, the error value obtained by the + BASE_MATH_GetSinCos() is relatively small, and the return + value of the function may be greater than or less than the + actual value. When the value of this macro is MACRO_DISABLE, + the error value obtained by the BASE_MATH_GetSinCos() is + relatively large. However, in the range [0°, 180°) and + [180°, 360°), the return value of the function is either + greater than or less than the actual value. */ + +#define MCS_PARAM_CHECK MACRO_ENABLE +#define APT_PARAM_CHECK MACRO_ENABLE +#define ADC_PARAM_CHECK MACRO_ENABLE +#define CAPM_PARAM_CHECK MACRO_ENABLE +#define CRG_PARAM_CHECK MACRO_ENABLE +#define I2C_PARAM_CHECK MACRO_ENABLE +#define UART_PARAM_CHECK MACRO_ENABLE +#define SPI_PARAM_CHECK MACRO_ENABLE +#define TIMER_PARAM_CHECK MACRO_ENABLE +#define IWDG_PARAM_CHECK MACRO_ENABLE +#define WWDG_PARAM_CHECK MACRO_ENABLE +#define GPIO_PARAM_CHECK MACRO_ENABLE +#define GPT_PARAM_CHECK MACRO_ENABLE +#define DMA_PARAM_CHECK MACRO_ENABLE +#define CRC_PARAM_CHECK MACRO_ENABLE +#define CFD_PARAM_CHECK MACRO_ENABLE +#define CMM_PARAM_CHECK MACRO_ENABLE +#define CAN_PARAM_CHECK MACRO_ENABLE +#define FLASH_PARAM_CHECK MACRO_ENABLE +#define PMC_PARAM_CHECK MACRO_ENABLE +#define ACMP_PARAM_CHECK MACRO_ENABLE +#define DAC_PARAM_CHECK MACRO_ENABLE +#define PGA_PARAM_CHECK MACRO_ENABLE +#define IOCMG_PARAM_CHECK MACRO_ENABLE +#define QDM_PARAM_CHECK MACRO_ENABLE + +/* Peripheral module macro switch--------------------------------------------- */ +#define BOARD_DIM_NUM 1 /**< Number of dimming handle arrays. */ + +#define BOARD_KEY_NUM 10 /**< Number of key handle arrays. */ +#define BOARD_KEY_PRESS_ON GPIO_HIGH_LEVEL /**< GPIO status corresponding to long press valid. */ +#define BOARD_KEY_PRESS_OFF GPIO_LOW_LEVEL /**< GPIO status corresponding to short press valid. */ + +#define BOARD_LED_SEG_NUM 4 /**< Number of segments. */ +#define BOARD_LED_SEGMENT_ON GPIO_HIGH_LEVEL /**< GPIO level status corresponding to valid segments. */ +#define BOARD_LED_SEGMENT_OFF GPIO_LOW_LEVEL /**< GPIO level status corresponding to invalid segments. */ + +#define BOARD_MKEY_SCHEME_NUMBER BOARD_MKEY_SCHEME_NUMBER_ONE /**< Define the scheme to be adopted. */ +#define BOARD_MKEY_OUT_NUM 4 /**< Number of GPIO pins used as output during scanning. */ +#define BOARD_MKEY_IN_NUM 4 /**< Number of GPIO pins used as input during scanning. */ +#define BOARD_MKEY_OUT_PIN_VALID GPIO_LOW_LEVEL /**< GPIO level status corresponding to the valid \ + status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_OUT_PIN_INVALID GPIO_HIGH_LEVEL /**< GPIO level status corresponding to the \ + invalid status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_VALID GPIO_LOW_LEVEL /**< Indicates the GPIO level corresponding to the \ + valid status of the input GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_INVALID GPIO_HIGH_LEVEL /**< Indicates the GPIO level corresponding to the \ + invalid status of the input GPIO in the key matrix. */ + +#define BOARD_PULSES_NUM 2 /**< Number of pulse handles. */ + +#define BASE_DEFINE_SLIPAVERAGE_NUM 2 /**< Sliding average array length. */ + +#define LISTNODE_MAX 20 + +#define BASE_DEFINE_DMA_QUICKSTART + +#define XTRAIL_FREQ 30000000U + +#define DBG_USE_NO_PRINTF 0U +#define DBG_USE_UART_PRINTF 1U + +#define DBG_PRINTF_USE DBG_USE_UART_PRINTF +#if (DBG_PRINTF_USE == DBG_USE_UART_PRINTF) +#define DBG_PRINTF_UART_PORT UART0 +#endif + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_FEATURE_H */ \ No newline at end of file diff --git a/vendor/yibaina_3061M/demo/rost/generatecode/main.h b/vendor/yibaina_3061M/demo/rost/generatecode/main.h new file mode 100644 index 000000000..8f0ddfc02 --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/generatecode/main.h @@ -0,0 +1,108 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. 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. + * 3. 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "spi.h" +#include "spi_ex.h" +#include "gpio.h" +#include "crg.h" +#include "dma.h" +#include "dma_ex.h" +#include "iocmg.h" +#include "gpt.h" +#include "gpt_ex.h" +#include "timer.h" +#include "timer_ex.h" +#include "stdio.h" +#include "stdint.h" +#include "debug.h" +#include "control.h" +#include "hmi.h" +#include "clock.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +#define ON 1 +#define OFF 0 +#define Water_P_con(n) HAL_GPIO_SetValue(&g_gpio4, GPIO_PIN_6, n) //纯净水电磁阀控制端口接在mosfet6,1--导通,0--截止继 //修改PWM占空比 +#define FanMotor_con(n) HAL_GPIO_SetValue(&g_gpio4, GPIO_PIN_5, n) //风机电机控制端口接在继电器3,1--风机开,0--风机关 + +extern UART_Handle g_uart0; +extern UART_Handle g_uart2; +extern SPI_Handle g_spi0; +extern DMA_Handle g_dmac; +extern GPIO_Handle g_gpio4; +extern GPT_Handle g_gptHandle; +extern TIMER_Handle g_timer0; +extern TIMER_Handle g_timer1; +extern TIMER_Handle g_timer2; +extern TIMER_Handle g_timer3; +//extern TIMER_Handle g_timer3; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); +void GPT2_Init(void); +void Cmd_buff_Clear(void); +//void TIMER3_Init(uint16_t arr); +void UART0WriteInterruptCallback(void *handle); +void UART0ReadInterruptCallback(void *handle); +void UART2WriteInterruptCallback(void *handle); +void UART2ReadInterruptCallback(void *handle); + +void UART2InterruptErrorCallback(void *handle); +void UART0InterruptErrorCallback(void *handle); + +void UART2_TXDMACallback(void *handle); +void UART2_RXDMACallback(void *handle); +void HAL_UART2_IrqHandler(void *handle); + +void SPI0TXCallback(void *handle); +void SPI0RXCallback(void *handle); +void SPI0TXRXCallback(void *handle); +void SPI0ErrorCallback(void *handle); +void SPI0CsCallback(void *handle); + +void TIMER2_InterruptProcess(void *handle); +void TIMER0_InterruptProcess(void *handle); +void TIMER1_InterruptProcess(void *handle); +void TIMER3_InterruptProcess(void *handle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/vendor/yibaina_3061M/demo/rost/generatecode/system_init.c b/vendor/yibaina_3061M/demo/rost/generatecode/system_init.c new file mode 100644 index 000000000..081f14b27 --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/generatecode/system_init.c @@ -0,0 +1,486 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. 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. + * 3. 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" +#include "stdint.h" +#include "stdio.h" + +#define UART0_BAND_RATE 115200 +#define UART2_BAND_RATE 115200 + +#define SPI0_FREQ_SCR 2 +#define SPI0_FREQ_CPSDVSR 50 +uint8_t g_rxStr[64]={0x0}; +volatile _Bool rxDMAFlag; + +//TIMER_Handle g_timer3; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.handleEx.clk1MDiv = (25 - 1); /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + + +static void GPIO_Init(void) +{ + HAL_CRG_IpEnableSet(GPIO4_BASE, IP_CLK_ENABLE); + g_gpio4.baseAddress = GPIO4; + + g_gpio4.pins = GPIO_PIN_5; //风机控制 + HAL_GPIO_Init(&g_gpio4); + HAL_GPIO_SetDirection(&g_gpio4, g_gpio4.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio4, g_gpio4.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio4, g_gpio4.pins, GPIO_INT_TYPE_NONE); + g_gpio4.pins = GPIO_PIN_6; //水泵控制 + HAL_GPIO_Init(&g_gpio4); + HAL_GPIO_SetDirection(&g_gpio4, g_gpio4.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio4, g_gpio4.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio4, g_gpio4.pins, GPIO_INT_TYPE_NONE); + return; +} + +__weak void SPI0TXCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN SPI0TXCallback */ + /* USER CODE END SPI0TXCallback */ +} + +__weak void SPI0RXCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN SPI0RXCallback */ + /* USER CODE END SPI0RXCallback */ +} + +__weak void SPI0TXRXCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN SPI0TXRXCallback */ + /* USER CODE END SPI0TXRXCallback */ +} + +__weak void SPI0ErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN SPI0ErrorCallback */ + /* USER CODE END SPI0ErrorCallback */ +} + +__weak void SPI0CsCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN SPI0CsCallback */ + /* USER CODE END SPI0CsCallback */ +} + +static void SPI0_Init(void) +{ + HAL_CRG_IpEnableSet(SPI0_BASE, IP_CLK_ENABLE); /* SPI0 clock enable. */ + g_spi0.baseAddress = SPI0; + + g_spi0.mode = HAL_SPI_MASTER; + g_spi0.csMode = SPI_CHIP_SELECT_MODE_CALLBACK; + g_spi0.xFerMode = HAL_XFER_MODE_INTERRUPTS; + g_spi0.clkPolarity = HAL_SPI_CLKPOL_0; + g_spi0.clkPhase = HAL_SPI_CLKPHA_1; + g_spi0.endian = HAL_SPI_BIG_ENDIAN; + g_spi0.frameFormat = HAL_SPI_MODE_MOTOROLA; + g_spi0.dataWidth = SPI_DATA_WIDTH_8BIT; + g_spi0.freqScr = SPI0_FREQ_SCR; + g_spi0.freqCpsdvsr = SPI0_FREQ_CPSDVSR; + g_spi0.waitEn = BASE_CFG_DISABLE; + g_spi0.waitVal = 127; /* 127 is microwire wait time */ + g_spi0.rxBuff = NULL; + g_spi0.txBuff = NULL; + g_spi0.transferSize = 0; + g_spi0.txCount = 0; + g_spi0.rxCount = 0; + g_spi0.state = HAL_SPI_STATE_RESET; + g_spi0.rxIntSize = SPI_RX_INTERRUPT_SIZE_1; + g_spi0.txIntSize = SPI_TX_INTERRUPT_SIZE_1; + g_spi0.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; + g_spi0.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; + HAL_SPI_Init(&g_spi0); + + HAL_SPI_RegisterCallback(&g_spi0, SPI_TX_COMPLETE_CB_ID, SPI0TXCallback); + HAL_SPI_RegisterCallback(&g_spi0, SPI_RX_COMPLETE_CB_ID, SPI0RXCallback); + HAL_SPI_RegisterCallback(&g_spi0, SPI_TX_RX_COMPLETE_CB_ID, SPI0TXRXCallback); + HAL_SPI_RegisterCallback(&g_spi0, SPI_ERROR_CB_ID, SPI0ErrorCallback); + HAL_SPI_RegisterCallback(&g_spi0, SPI_CS_CB_ID, SPI0CsCallback); + IRQ_Register(IRQ_SPI0, HAL_SPI_IrqHandler, &g_spi0); + IRQ_SetPriority(IRQ_SPI0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_SPI0); + HAL_SPI_ChipSelectChannelSet(&g_spi0, SPI_CHIP_SELECT_CHANNEL_0); +} + +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ +} + +__weak void UART0WriteInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ + /* USER CODE END UART0_WRITE_IT_FINISH */ +} + +__weak void UART0ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_READ_IT_FINISH */ + /* USER CODE END UART0_READ_IT_FINISH */ +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_INTERRUPT; + g_uart0.rxMode = UART_MODE_INTERRUPT; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); + HAL_UART_RegisterCallBack(&g_uart0, UART_TRNS_IT_ERROR, (UART_CallbackType)UART0InterruptErrorCallback); + HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_IT_FINISH, (UART_CallbackType)UART0WriteInterruptCallback); + HAL_UART_RegisterCallBack(&g_uart0, UART_READ_IT_FINISH, (UART_CallbackType)UART0ReadInterruptCallback); + IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart0); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_UART0); +} + +__weak void UART2InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART2_TRNS_IT_ERROR */ + /* USER CODE END UART2_TRNS_IT_ERROR */ +} + +__weak void UART2WriteInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART2_WRITE_IT_FINISH */ + /* USER CODE END UART2_WRITE_IT_FINISH */ +} + +__weak void UART2ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART2_READ_IT_FINISH */ + DBG_PRINTF("UART2_Irq \r\n"); + /* USER CODE END UART2_READ_IT_FINISH */ +} + +static void UART2_Init(void) +{ + HAL_CRG_IpEnableSet(UART2_BASE, IP_CLK_ENABLE); /* UART2 clock enable. */ + g_uart2.baseAddress = UART2; + + g_uart2.baudRate = UART2_BAND_RATE; +// g_uart2.baudRate = bound; + g_uart2.dataLength = UART_DATALENGTH_8BIT; + g_uart2.stopBits = UART_STOPBITS_ONE; + g_uart2.parity = UART_PARITY_NONE; + g_uart2.txMode = UART_MODE_BLOCKING; + g_uart2.rxMode = UART_MODE_INTERRUPT; + g_uart2.fifoMode = BASE_CFG_ENABLE; + g_uart2.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart2.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart2.hwFlowCtr = BASE_CFG_DISABLE; + g_uart2.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart2.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart2); + HAL_UART_RegisterCallBack(&g_uart2, UART_TRNS_IT_ERROR, (UART_CallbackType)UART2InterruptErrorCallback); + HAL_UART_RegisterCallBack(&g_uart2, UART_WRITE_IT_FINISH, (UART_CallbackType)UART2WriteInterruptCallback); + HAL_UART_RegisterCallBack(&g_uart2, UART_READ_IT_FINISH, (UART_CallbackType)UART2ReadInterruptCallback); + IRQ_Register(IRQ_UART2, HAL_UART_IrqHandler, &g_uart2); + IRQ_SetPriority(IRQ_UART2, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_UART2); +} + +void GPT2_Init(void) +{ + HAL_CRG_IpEnableSet(GPT2_BASE, IP_CLK_ENABLE); + + g_gptHandle.baseAddress = GPT2; + g_gptHandle.clockDiv = 10 - 1; /* 10 is the internal frequency division of GPT */ + g_gptHandle.period = 49999; /* 49999 is the number of GPT counting cycles. */ + g_gptHandle.refA0.refdot = 25000; /* 10000 is the value of PWM reference point A. */ + g_gptHandle.refA0.refAction = GPT_ACTION_OUTPUT_HIGH; /* GPT Action High */ + g_gptHandle.refB0.refdot = 25000; /* 20000 is the value of PWM reference point B. */ + g_gptHandle.refB0.refAction = GPT_ACTION_OUTPUT_LOW; /* GPT Action Low */ + g_gptHandle.bufLoad = BASE_CFG_ENABLE; + g_gptHandle.pwmKeep = BASE_CFG_ENABLE; + g_gptHandle.handleEx.periodIntEnable = BASE_CFG_DISABLE; + g_gptHandle.handleEx.outputFinIntEnable = BASE_CFG_DISABLE; + g_gptHandle.triggleAdcOutFinish = BASE_CFG_DISABLE; + g_gptHandle.triggleAdcPeriod = BASE_CFG_DISABLE; + + HAL_GPT_Init(&g_gptHandle); + +} + +__weak void TIMER0_InterruptProcess(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER0_InterruptProcess */ + /* USER CODE END TIMER0_InterruptProcess */ +} + +static void TIMER0_Init(void) +{ + HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); /* TIMER0 clock enable. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER0) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 1000000; + + g_timer0.baseAddress = TIMER0; + g_timer0.load = load - 1; /* Set timer value immediately */ + g_timer0.bgLoad = load - 1; /* Set timer value */ + g_timer0.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer0.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer0.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer0.interruptEn = BASE_CFG_ENABLE; + g_timer0.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer0.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer0); + IRQ_Register(IRQ_TIMER0, HAL_TIMER_IrqHandler, &g_timer0); + + HAL_TIMER_RegisterCallback(&g_timer0, TIMER_PERIOD_FIN, TIMER0_InterruptProcess); + IRQ_SetPriority(IRQ_TIMER0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER0); +} + +__weak void TIMER1_InterruptProcess(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER1_InterruptProcess */ + /* USER CODE END TIMER1_InterruptProcess */ +} + +static void TIMER1_Init(void) +{ + HAL_CRG_IpEnableSet(TIMER1_BASE, IP_CLK_ENABLE); /* TIMER1 clock enable. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER1) / (1u << (TIMERPRESCALER_DIV_256 * 4)) / 1000000u) * 1000000; + + g_timer1.baseAddress = TIMER1; + g_timer1.load = load - 1; /* Set timer value immediately */ + g_timer1.bgLoad = load - 1; /* Set timer value */ + g_timer1.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer1.prescaler = TIMERPRESCALER_DIV_256; /* Don't frequency division */ + g_timer1.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer1.interruptEn = BASE_CFG_ENABLE; + g_timer1.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer1.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer1); + IRQ_Register(IRQ_TIMER1, HAL_TIMER_IrqHandler, &g_timer1); + + HAL_TIMER_RegisterCallback(&g_timer1, TIMER_PERIOD_FIN, TIMER1_InterruptProcess); + IRQ_SetPriority(IRQ_TIMER1, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER1); +} + +__weak void TIMER2_InterruptProcess(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER2_InterruptProcess */ + /* USER CODE END TIMER2_InterruptProcess */ +} + +static void TIMER2_Init(void) +{ + HAL_CRG_IpEnableSet(TIMER2_BASE, IP_CLK_ENABLE); /* TIMER2 clock enable. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER2) / (1u << (TIMERPRESCALER_DIV_256 * 4)) / 1000000u) * 100000; + + g_timer2.baseAddress = TIMER2; + g_timer2.load = load - 1; /* Set timer value immediately */ + g_timer2.bgLoad = load - 1; /* Set timer value */ + g_timer2.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer2.prescaler = TIMERPRESCALER_DIV_256; /* Don't frequency division */ + g_timer2.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer2.interruptEn = BASE_CFG_ENABLE; + g_timer2.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer2.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer2); + IRQ_Register(IRQ_TIMER2, HAL_TIMER_IrqHandler, &g_timer2); + + HAL_TIMER_RegisterCallback(&g_timer2, TIMER_PERIOD_FIN, TIMER2_InterruptProcess); + IRQ_SetPriority(IRQ_TIMER2, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER2); +} +__weak void TIMER3_InterruptProcess(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER2_InterruptProcess */ + /* USER CODE END TIMER2_InterruptProcess */ +} + +static void TIMER3_Init(void) +{ + HAL_CRG_IpEnableSet(TIMER3_BASE, IP_CLK_ENABLE); /* TIMER2 clock enable. */ + unsigned int load = 0; + load = (HAL_CRG_GetIpFreq((void *)TIMER3) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 5000; + g_timer3.baseAddress = TIMER3; + g_timer3.load = load - 1; /* Set timer value immediately */ + g_timer3.bgLoad = load - 1; /* Set timer value */ + g_timer3.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer3.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer3.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer3.interruptEn = BASE_CFG_ENABLE; + g_timer3.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer3.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer3); + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_timer3); + + HAL_TIMER_RegisterCallback(&g_timer3, TIMER_PERIOD_FIN, TIMER3_InterruptProcess); + IRQ_SetPriority(IRQ_TIMER3, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER3); + HAL_TIMER_Start(&g_timer3); + HAL_TIMER_Init(&g_timer3); + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_timer3); + + HAL_TIMER_RegisterCallback(&g_timer3, TIMER_PERIOD_FIN, TIMER3_InterruptProcess); + IRQ_SetPriority(IRQ_TIMER3, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER3); +} + +static void IOConfig(void) +{ + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + /* Config PIN16 风机控制*/ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_GPIO4_5); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_GPIO4_5, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_GPIO4_5, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_GPIO4_5, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_GPIO4_5, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN17 水泵控制控制*/ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_GPIO4_6); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_GPIO4_6, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_GPIO4_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_GPIO4_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_GPIO4_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN6 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO5_2_AS_GPT2_PWM); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_2_AS_GPT2_PWM, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_2_AS_GPT2_PWM, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_2_AS_GPT2_PWM, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_2_AS_GPT2_PWM, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN39 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN40 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN15 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_GPIO4_5); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_GPIO4_5, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_GPIO4_5, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_GPIO4_5, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_GPIO4_5, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN11 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO1_5_AS_UART2_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_5_AS_UART2_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_5_AS_UART2_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_5_AS_UART2_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_5_AS_UART2_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN12 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO1_6_AS_UART2_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_6_AS_UART2_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_6_AS_UART2_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_6_AS_UART2_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_6_AS_UART2_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN3 AS_SPI0_CLK*/ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_7_AS_SPI0_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_7_AS_SPI0_CLK, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_7_AS_SPI0_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_7_AS_SPI0_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_7_AS_SPI0_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN4 AS SPI0_RXD*/ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_6_AS_SPI0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_6_AS_SPI0_RXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_6_AS_SPI0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_6_AS_SPI0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_6_AS_SPI0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN5 AS_SPI0_TXD*/ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_5_AS_SPI0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_5_AS_SPI0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_5_AS_SPI0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_5_AS_SPI0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_5_AS_SPI0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN1 AS_SPI0_CSN0*/ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_7_AS_SPI0_CSN0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_7_AS_SPI0_CSN0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_7_AS_SPI0_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_7_AS_SPI0_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_7_AS_SPI0_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); +// DMA_Init(); + UART0_Init(); + UART2_Init(); + SPI0_Init(); + GPIO_Init(); + GPT2_Init(); + TIMER0_Init(); + TIMER1_Init(); + TIMER2_Init(); + TIMER3_Init();//5000us + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/vendor/yibaina_3061M/demo/rost/main.c b/vendor/yibaina_3061M/demo/rost/main.c new file mode 100644 index 000000000..9b843426e --- /dev/null +++ b/vendor/yibaina_3061M/demo/rost/main.c @@ -0,0 +1,227 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. 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. + * 3. 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +#include "math.h" +#include "stdlib.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +UART_Handle g_uart2; +SPI_Handle g_spi0; +DMA_Handle g_dmac; +GPIO_Handle g_gpio4; +//GPIO_Handle g_gpio5; +GPT_Handle g_gptHandle; +TIMER_Handle g_timer0; +TIMER_Handle g_timer1; +TIMER_Handle g_timer2; +TIMER_Handle g_timer3; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ +#define Power_PARA 100 //加热器功率参数 +#define ON 1 //开关变量置1 +#define OFF 0 //开关变量置0 + +volatile uint8_t Usart3Timeout; +uint8_t gucDecoderState= 0; +volatile uint8_t cmd_buffer[64]; +volatile uint8_t gucDecoderIndex; +uint8_t U2RxBuffer[64]; +volatile uint8_t cmd_size,tt; +volatile uint32_t work_time,timerct,control_on; + +//uint8_t cmd_size,cmd_buffer[64]; //DMA接收串口数据缓冲区 +uint8_t Screen_ID,Time_setvalue_H,Time_setvalue_M,Time_setvalue_S,Temp_text_id,Workmode; +uint32_t time_setvalue; +uint16_t Temp_setvalue,Temp_PV_A; +extern uint8_t Power_on,Slider_A; + +/** + * @brief User-defined read completion interrupt callback function. + * @param UART_Handle UART handle. + * @retval None. + */ +void UART2ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + HAL_UART_ReadIT(&g_uart2, U2RxBuffer, 1); /* Start receiving again */ + cmd_buffer[gucDecoderIndex++]=U2RxBuffer[0]; + Usart3Timeout = 3; + return; +} + +void Cmd_buff_Clear(void) +{ + for (uint8_t i=0;iZl@9d2Sv_UJ48x6#xl<1^@tr0945Dr@kNn00$%hfC7L9)e^F`aWb)S(o=S` zGjY_R1zKDE$OQ)_&jEmbjsO4K|KJsj7%>9%rrVv&j%$EXY3xnl3&v-tib=Bx74WN0}agIFlCV6#i|b+m0$fHDS;3Er~CV zTG$j^X@Ort_4{y+kH;)d6>cE>JZXY4cAiHr^A&|TI_zn;enF#d-R~-ILA>2fE6}^n zS+|_EG-%QT2DcdRONd{rN(>%4JBJ7oBnTr}Y+e+l#N!+!9O3GPjzkZF4qA(G0o9&` z3X19weJ5~0;=3HaBlk(Ylm4c0rTyx`09c=Z6NDzyFCC;Xw)HyHB*aLL8sxjD(L*#aHP$qVX zYIg=v%lsT#YU_xdTh) zU4Efa_KTNrU&PgOFtKu^qy5+M{}c9qFiZc-t(V93{OY5J=f4bi518&ySn0vclch77 zTE$$3g4U9dMp<3@wfOPQy|e_Xb8H|sHZvPPb#YpbA_Fxf)LgLv+%6jr}f$n z1SAHv7cc-9>~`SO4<1b4M~NgTMgzh%(84CMA!DC@r~K_k*{2kK*e`;!_(?H2XGC0= zmu0WA_?Y6&l#|LZzwk?3%LA&EN2D_tuXO^;8`hMsCYgyQCc1Z{R;OS2B)*w3@)yND zHMSK!9Z5#4VL2@JRr~abdtO)3Kxhy(%paIgx>rwAZDh@l!>|J^KGsV@je5OpTbv9X zf!i*h14#sr>)QGAW?CaW2yfZ}&O4*v-#p#X<3iX3);&rc8X^Yc{n#C(5I>e`H&w}bsU z(x%(U>1k|F`H2JSP%&yyEzXiNO0%l5kZ_7{P*|!U7j%clpzedZ+qzY=DbQoZVilC1 zxl1v1*flNN+zBk0NQR5P1@WV9L@|$ledv zwlxl!9l>QKK{X**3Ze9kQOp=gPquhWY3ES`?)*M7RJyK*irF)d%u_;5kUx@qf;BD8HzT(IJ0xmcx0O@PQKj8hZuszGvP{J8W^4%me{0I<4nFU#A z6*nBhu&HxFF=&M`a-Hmplt)zragJ3^Q>3uA3h?^7V~I0n_)0gM zs4^4(*}L}>MnYWBS6z~`R!Cf&f}gX9Ay-iu&+I8?wtd1a_F@qS{64GDert z+P2#2DWlW9%#5OLiY4M{qQ)@@)@cp$#wIw{&T6%Uvmo^NWnsP+lIcMY?k8{OjIxkh zOreqGml>(QwDuiOL&QBhf?8x`Bc6Kf2#43Wp*9;qbdBM0@$uJcC3#aL5<2S_>FhFW zWN_C0LNTxQ4uvyzjE0FdS`I3~am`pGkk1k%W1>fLPZ)}vk0yL2i1R-?jQ;d<+2IQ( z7b)3^mG-(V%v}vk*!|=wft}uU3f#SK{X1|NZ^RQntl)oa%ttI*6tK_j9A>J7jZ7#Z z>>VqMZg`0`5gL!8Eyl*HG%u`D*|O&ZqaH;ff3hu?EG$7DDk#@=TWoRH$~8f@e@R@k z>XndY*EyG_trJ`SJB>p`lTb4k<{^WQsUkB2hs~s@qPC=uL{d8)>=1fv!*{?e2bn%b z)v$a}vRbD8F}}-2$d*Jk_kl}AG=4-;S$k3579OfW90v6C*`;!okf3V@8BJKpCU!Vm zw}ld1(qqG^!GZrUJ| zg;q|QIGyY!vT$W^uY4yQ z5sO3|A1%f@Ms<^7rK%^<$&lP$mupSS1^&uy?g$ykrBFulRyu=;56C-bj;t)jMrN%Ig{fV<^Y_ZeHmCSCVbi8uv;?$76>W6A@-ql9 z8SgL(Y72zD(FO%Av9RIbbqrm}!m#n=qOjako^oxXd2iz1dB4mI7G<_G>M#?s>REzx ze{j{hU=aByB-&8$>K;>5XW{A0ZC#80Y9WoBQ%uUqwMePNJ{}p+Z`^zhaRnemLoIY9 zPs4}Pi0qS?nE8p@E!&H?{czh`#mwMbvlvP=qNO4_7W1#cs!KSkU)SZ8JsfB65zztS zEOA3y(U#Snnj7#OWy0Zp6Y)q8DO7Z1x}}&O5HfK^lZh&>qnp~5Te%Z+?uk}4OI*i; zH;_{5IPr))_itn7Tc`lw>E_9z*R0{ zovI{|!V}~FkT7|a*HVYILWFEIMcp*l_sRAXjMIEZ07Lg=uROQS)fl+#M0Fym^WyU|ULA%8;n}&xokri)hrzJL}w@&1Q`~MX+)QS}Qq` z1%cd}*nV3hwu_g&BxTSmo6 z2PJj1-0ILALCS}u=e6(0dJnzIe}7HpY$d*|LkRi6^zm%w?8)?W0|J?drIJM5ET?wJ zE5jr2Y3mM5ZDR zD7O0JXmftOLaF->(T`1{3XM<5h-S3($@yhGYy8JOv7YGWwA?LPN*5AL9d+WBn?i@? z;#+il&xU-2t_jd(>hipjA%V;H-+`!``^*X9@sX@g9L+DHpS2)rT#D(|sl`f)KAf%% z8buoESa7tR;C!!PtLBPXcRAV#??Ugd%jPBs=UudvOgq?A18h~hDMBk9?Ib6-&Y-fy26Ltdgpo5348kd#FMRUx{}6(f zn3K~~R&;ED8c-Py*W=ATFcH|Dlq-}?y3QRUMlEy^r>PE_{Vh9=@n^MrOPb#97nNzQ1%5VGVnuvbau*{L;?R}O2K_*p*ARX7Su<+F-YC=xK%fcV#tmL=6@$~8}* z{I1!)BaYm#Kx=2!E!3LeqKCmGujlVbri$oc)4*mD`&Ih#n>B<7)$wj*uuISO)^+B} z$cK%@nPIkt?2%fZo=DGr?CVI9K+*To$1KTOgT~b!w<9yK&#p?!yeXR>cq+9Lizaq( zUhM(R@qBPDEwlVo49K&y=ggj#j43GK=~rF0#|K&B)mq5s!L~H)oaax2K^R!(EY&zO z>6xg<9=b(zDcv1EDnL{+ncD3CpONf(BLtC?kfcw_de# zGOQQjI?7Ra$YvOJIDg1v=~H72P;_V`2nEVU$+zW*1!`spS6bnDh!M&e&OoC^-PWE; zg&(rxvujsHt0U;K{}$=9qHXJfOTBjG{y~VHl`1W&9X6z-Pi)@T%B-(XJO~T(cVPRQ zDQ>8622Qrvv&xamB%Zj3t{9&gM+3(giIPYV_eo&O_BOn-sN?o;Wh`t=D%^fee6W`* zUmcE5hTw8EBr%5|**?VnxuUiWtnPdF)G`($hPDbHkrIh{<#YDTOl_QPZBCAPQ32#8aH%J~dssa6}s%+DrV%@57MDlKotAifEk`OjkoHQRRYpdom z#{!Sg5P-HeA!ygroa^h}RgQ%_xv)=IYr3!~Ld z&h_!VXAB9GbTJ`Xy|q$Gos-M{aIbsSZ>@6T*9exDyJ!3u3k-dK1J#LMQZp>rnvtK! z!?JQdlVG$UG6S@&*^dPstxW`nY|T*&Lsb53UQ%@`sKYqoVTXQ`$gQJD$@(s>q-Ac5 zCnFOB##G2x>jk;D*3h7EXNMO_ZGj@R%*iF%n9jZN4HvgMZ)@onKpSo4j?1B!mg`p( zg!^M0njT-=(7<0_tlWypv)>7GF{aC=aCY9^&!LXqJ5azK%_bY3Y#^VQPj6_(D?Tpv zOyQzZ#FPTgTNFYeDSl)Gx`msCMn|ZX%`{>zb*!ymsHNe~RM636A&l;?FbU%0)zNTj`Ui;PxHGPb+1vqjdyaZVAf-!u%qm zQ({{B(t(gP*CW`7U)ds1N92ov__rG9_1gK*lgd3)d+)xkF+9y7_)2nFA3*x-V70ui z+D22863w()Wa;|>vVC7(dGhV}Kb6W(dp83|sR!l43FmKPNJyd+P`qxp88$d(n(xI* z?kY8E#cF6OXd~^Ea%A?|=B(D=vf|DCMgknlBD9;RoufwRgfn@%FL=7bF*IVhS>gvZOr- z7!Uz-cgV^jw%J@XH`mKt7FF8SdpJ;^tSRB8Bk%>$j{~5r$jK7G`=|Cas}I(6aPV z+Gg*%uKg~=YEVWOAMkaBHd$5rSXSa#;jL(XHc%waFfm8fL|wZb)w-t@~P0& zqivKja&tJpjN&g~NJvO0nVkbNnT&y6NG)hSfI_0faN)i@EF$^v5Dy{6XZA)01vtzv z2TKR}I!qY&8_J3ywfh)CTak7-x)>K8?g-tNgl65JYb!?ski^UacZ9}ILP3d4=ek=z zo9!sknTeG%g@Zc(DJ{fAycX(${TIMBt*Gco=ti7OXF91m8uDPW&RP$SEyq`pelFdn zD$>SIxG^S)w6NA<*<+~uEqM}19>W`i<#s|y<)Ipe-Wa6o%P>y>$&;(kR)0g=HlVpm zck8s*vPOw>mNB0CCmu1d`^D0izw+W76}O%665k%$CT;}cW@H6el+$=@P8?NCeb)DiceGAm=< zwAw>*YPYZJpYG**o`m}=g8brlHpT=k?#Zwc4V~~$^F+S;R(;Dnmul_oc{{d|qOnXM zwi^HRdQH&ZwRHv#pkhoT)*4y(%(MQ)Pw&5_Ez|Epf~jRl9SCe`&7|K0$0X6EzIt4` zH35mtn4@n%*kpOvudu9)<|D@j4ol$Y7Sc+4HJJK>=KK!mwE`svz(NMiYo}pci-5p& z??8v=eL&lRXb;Z|df;C~p{L1Ihr<21EB{TD0g>nVcNx$ve8>X0*MC$@b3|w z0C-dOklc(r@%)ES&3+Sz0I*DgtpiQFTe&M+zvzBX0Jd+i_WG63yT+qVz}7wW6I1pK z0S@$cTmid(fO5la<$~GxPqJ=)nm5cBN_q*^9uW4a08iK&*uH7gkbtU|GAb!kpr)1< zj`D}~5%BCSgrj61bb97`8z*GvjFm6hqid3oc6N7-p6M@!UhqMgmzv1j+Faq#6@a)I zmN(h?yEF0SI{rjwPW9VV3ZJgCunmS%4OvNyrHrgQR7tidMlXsKt)81{Sn!VVsL)~r z26^YYGDI0UORDAQeId$xD9as?j0$4#%+bzVJY5&@%oegyx3tSk)Fa;STmUyNX%u#Z zx$(^2Pr;q~0e0Ro(g>^0iD$jwaJSq|f+4smzcB^PiO#X=u18xOKpId@H z4{qnyu)Fzs;_RZfKBw=c8^_;vISejMGbIY5wZN~_){Rve0sL)s$U zM4es8*k3_-Ha=?E%;?`lUc$$q*ZI52@glIbU9KE_)0G^-cpUXf@Kk5ivk`vt7g1DY zTHfxhH!P^*5KAPe+m?`TUPb$CS?<|qE+l1_vjmwc@w!pE>b42(?RjG3UzqP7in*WL z)FdbC6XPy%rSiDDh*GoB?5&Tc{QQQ*pK$x#WW-4_t`Sg)tDhByc$14lofJ>1Uf+Y3 zq7RZH>mS-4C07k#>V_Y$1PIZ$f&SK}__+sBN9C&kNgtN21M(9QgV%h$9leT$(27v?*c^WU=2ev_7;c z5g?XIB(Pnd6_kDyAWDw|GMABseG~vjbzBWvhvX}MU`B*2Cq|qW4RC~f%k*f1q6dfX zNdUKVpp`w7E{AcI0TJ~y$m!A6#iQXU@7@-RRAqNC!B*&`$j`2gB_s#}$k)kBTk~Hh zG+Msd#912E^rO+fEVv9%@aFtphzD~3ZP7Gs?wpBrqFYk~Bs@}19Bks01dcC^z5^pE zZ3{F%h`cN#kL>gW7+JRjr7SjwS{-?~qB0`1rzU_@1f%$%@!m$su@CQTDeR)XioNJn zH6(F`gsB_sDgzCl-4APtgNh6NA;)$L>Pcckj_1;ztJ(YX(LZyNs&(6bt1C{Wdeist z1eCo9P_z?_^_55{f}l9J?&D1p#iO;_Rg?HS{$y`psX$m5^x&J*ICU$xPvdbjjfWXW z;g5$+Q~j43Sn7}+o^0KwP{DTt=q3DOfh}4NnJOjfVPU7(Cv^cx4jOjb;~_pNw{!W9 zza?-%%B>Af*DX^IwId|0C+Io;+gQ9*Y=$s1ypkc6DsxG@$&3HIyXHdhIpEm%5~ z-(M5!3%>_LO^=QMZ!9B1y@x?eWAob<)|!g5O3F?J$TboyfIe+mij=*qJB!dagl7%0 z(l2}HLa-z}q#Pp%CMar71s#G4ybv}HEeLh*=ewo@$8F!dGFGSNOt9Xmo^W$yPROa> zA2xGip4a^TD6+qx6xQ%{L~5T`8){@l{-5q?UbTvE(Uqn0IjzxByIb;jpZV^K)viSo z+zX`DaBPJav`{V^N{bhXJCAu4lPSWUXpgk&p4RRX@73YXl3R9qUakbQ*h(ndHnB7hR= zwt1-VsXgoxffE>^`e+|S{(*MC3wU|Mm$50@e^Z;&`elh+6&cY2%KB`aUd|Lp-LI@T zyP~}LeLb!|l;+MMMj+6dV&y5bn?>eMMn)=rXH`_oNca&Km+}MV4u~WM4J1I;;^B5j zKQc@+vWWvSC@#>Yi}W{XL0=a?v63gQp7i1rK3&YOwUo)0m(Fs9+2UGHK$v}-9xQ)& zcmy|BvaD7Q!?`!D9|kLN$rd@q+U;9S^^SNIMa#ReaA?lT_zi^BS@n=ViH_LX9#sFDGdGg1Or2@(l1SmZmQMl%ITAXW<37p%%TN=AM78-R=~pe+sP_EWXl6 zg@L>3Z^18^AZq=(u$?nkPctZh4Jxg;)Mys7ob1B)arAR(n?X8<j%Y{g~#*|7#1JLy8czVBol>6|! z3VNz@y=8b&f0N>fM*t~=asV&JqO@YK97bd{;w@Z2>bBN`$B5e%0`^+Nfeng?t-8!b z>uhwW>tY&o_B86V$@4k3wFt0RQgUGtoB1owPOwLWD6$4q2KHl`Xz`Ho^`6-l7r(jyXa_p5S&0C&HCc)yX{WBl-@#R+i1{bH7TkfFEX9b3yupM7o|+#cXS?-{<+XG!7Pe$uCDg zg9XB>LSm*yoqsy8>0B;ItqtJzyfbjzcUXkz!{c>#bhkZuTeEmx>B~&H(($}q=99%+ z{qeEi#unYhx~qXyCG!{h5WB)QtHb@{Y(Jh(@AGL1a4Anu-HWIIn(B;zuf-B1EPDZV^M8yTK zXB}Qr!!d4t!&ww8)-d9C@9cdjy=@u$IY}=~Nt7Oc=mt9tm-OL>z1F{VKe8mq?^Brmz9l;E%wvzgiQ{mZ^%7S?~j#k)pRcdzxXxVXRxq zRT@Kvlk?o$q=5KF9^_;}1!>Y=g7{V#yM)Gb-$}4{y#y0MtV0}Ouhb$CoDq~7SJQ`!q$bTOMg9&G)nZ5&ELp=TF6(3ntQ=O`Q=};}U$`tiKBL;#t?CWE* zj4bh6FPAEQR|V=4d)Pb8Igp&Fk%!m*1tnS&iQ?|Hxz^(m&Sl(f4+87Wc6v4cuaO&@;E=P zN;pQ;2&y_~M(A51s@>np=wRNm8I=pHPMl-zs^9z?G^CEu5M+0P$itEfH$DSxMi6>( zBC!oKO$>^Khp8sz2Lp_-9K7Mi+tC4#1P2aig zr&HWVR;H&ax_}lXslt_cD|DJvKLWPP3laB^6)!2~Ri#Jz{wB2Ig-d#)Bi*Fz2#Mq0 zs31PtN}A~$X9;wZnyCc*`t6~@}Un)Ja=-ETyls@Kz+y~?n z-p9`&20u8*eo*>Q=(;{7lszQ>eW$K1o!tHTJ#l?7fj2tKTB#2`InhLMSx6umJ^CdA z)2IKlfH%I4*0}sntCCW73D4|`yLm?&;*XAcs(Rkd(S#bNP=)u@Z^rf>9H8rRW(;fa zs?q78fu=QZR;;gy9mC$Hj>~SW*_lRgOB#(anF7{aeQ_;yj5fO;Bt(f^WJHl%h;Qiy zdF-j$#EWU+J^VOeulUsJB?%JBj;P1c3dr}HW;o{P3d1R6~tY` zu2SrhGztxRHYTR`@%l$!_Nd*cS;qT)M-aTvc`3V(-yTdjmQHmwKM(W%2&3>i|14w} zFy|)JnoSXWWQnBU`w4oVIX4-+N2ter!6iPV!_kdtkxd0%9<$J#BxR`sRe)6qHY2ST zSTr@@2HDD;rOMx0R#JqoZ(jh6c)dWK6q`Vu6x9#lRwY^d9(@9on&dRY9xP*yQ1PCm zjL;~9A1Y@KECOzTCXE?MH#@N0!#8~GO>W#+{DqOXOV&tP>Z>5fG50xlh^Gz~na&X3 z6VTO%#OX8~^N}r~eyF~ra}O%;sq?IpuW2FS)5z3{O6*pkTfm>~s+KWp;`7B@ZpmZe z&4`x)WaU$g@u0X#$=w2}cFhA(L_rd41Q4!;*UVr^RQbNsv>Qhvp{qY$otAs}iM;WZ zhdEfU!V!UtkTk z=$e}(+GjI$$Oqs_-u24M(x2z*%8213{aIZzYx!u2)V-b8@&A+!Qn3soE+b$BF*3iaL;E@9C zGgHY6c1TL>B~aCOFudDGOd5#Pi-bY8TRpKF?Ao#%*p#?=_R|y8yxnb!hI#w%uAV*8 z!42JMd+Zhh+jit$NE>wYO`nr4;?+vZmHU;oHqR3^7Iqa8kb$&4%ClZdAYsB%sx@Wq z+G=jK@lCY5+2<9mYa%tE#U_gTP$$Tx=+1WgL>nsb5ODsS*x2}%-e~oKuvGdWW`b?V zL^Z3Q?l0zqZ;@i!d)ia9?0!XKY~C)`6VCiK^XW3G@KJlq)_G0Zd@PSDL|X;+CCb&P z3{dOYfyw}Cz1apN!i!QvT1i=62UtNKOV3i7_CU4eznNXZZ*(vvs~9#vs~woOaW83cno{T?%*3KFb$j0Cz2MA3sPP&qX)hazN-PMd=J5a ze_O*oblb@^bPJLbF|hsq)Sr63d^Ub3j1{Gonq{8skJ-^>1pHe8ro~#17^dE&=#8}D?uOvTK+tQ;AcUnOsdOr$-hCmU4(0sQ-tk0EPf^4ehApay)()A zJKEycQssqWj==R^X5{yfX9{83_W&)8kb@4XF5hs5{`@SvNaKf9jiFmfkOGy}=jydZ zlaGQh=CAh?pBjg3wZ>y;bTXbvbmW?m4;%N14M<}^fj17m=VTJ@dGzcxoV?QzK)`!7 zOeY!gmN1Jjp>jirW6Iaul5L-c9{DEeB|oY?E$Suxc&X%_U=zU?mv?UyRf>2XYJR#s zU=q22EJ>$*=u>e=P;qF@?tGoeV@CIDf$^;l4es;8mghF9_8v;H-{FyH@rCQ-I*Fw* z#BK_kA}hR+RyUe}kz?1TC1@<+k;BCyk|WPMzSq?uTz?FHc6H>hP}*$lqmvsC zKJA9P4R&}O!#aJ3-gK^Pog06ufqT*N&m0CZddW*>scr8dN(J(!XCNA6#YrRs+Ug;51!rx$=_$q98&%E0fc;z?t`V`kgTDleY8 z7!+Ofk?ND(kWIZ8wmw&TX;gUSw2wexYoQUifa(!`UF5Pn9`SQc)V9UtpE(~}5%oYe ziM~2~RM-d_X)FJ^_*LCS-(&aWa5n$r=HlOw=;OJAweUH5Mc{mEa4W9h}DXCJlw?cbz5HU6`oUB zVs)EYJV}7vR7N$Mv&CoXL0cH6%Sz7dH@OMCckj=E)3?zK*>s|XgK<&MOJ4p1Q z)~Rwy(>;`{ZQpxN`~|3`pS*sD+>v!N!5!)5YFfV!oHWB)m-vB{)re;cQ>dOX5I>>+ zuyteavE>5g0V``C13IxX{$g~q+~{4}0*nuYj(*>>gT>XN1HPiIL1QR*!M1eBF-0-C z1fT6DMCY;ok27M$nBkj(LPD_c@rW~{_?Y#3E_YVvW#y{UyMh35QN=!;BG3F(Dg;Jn z?6EB?Ce@}Ll>wR3TmF-#NA9WneOA^w4641PMwGx9CF`iL@F1yhUSbU29|PwWomRSoPvo@{r>lGK6@ShR8}upnkGZ=0)gYfO&DU6&G#`G zRUd)YqDRd@pMB_W*1lKQdV6(0eP`6|jAl28dr<7dh#-Kn;<5@ijeAcFB~RxswMF>b6L9YZ&1VL zwSJ{5Dkg+_n(vb)$^;2gQhewX%2nxqysWHGDCWB^fN^EuNB7Y$;|D;;5+G4eP|=>I zy8R(S1=^}&gN_MKrOQI0jp}09!*A?jP3KAhDp;b5;VwH(1!z zQJ-hvKxXtPHX3zW-bzF1`%bBOa@jAo4#;!za@G}#P9=QoqtZ&97>aD$X54d7Gow1a zt2d2>Z_|6;(Y!?Y7Gma6w2%AnK4YhJb(?vUc-Y56S9!ZUfY)SblS>9=0$8pBUZ!6m zf9K7*lJR*5bvub}PmZP~=82jhdA??Ff13MO2L*L=-W}y}Y|+Vd*}vQKizmJ5c(4Vd zjnpKfp_F+b7jmG2=0&4}PwGzG6Br9VE6VV_uJXCslo7v*2_=@BZ(41hUW@1JR4>}A zX-*|aj!jl@Hm~Ww#+2Jc8r4*r1arjatvwK06)=xQJA-FwqJxt1N(op`qJ{Xn+>SNF z!@HwDdk)$9JP<W4&bR4ng0O>&F}W@K@I;SDhb9y6u;=Ht-1a(JE>+sX6gI^k^=#1Ui3s<9#Zz=#&Y%J z_0nwRxbuY*D1@w8SM2#wy*0zVCqx$kPW(GEjNG$_R6u z5^wOZY{+vJm&}uZtMk^{{%vb@?+J$eeD#c;a!jNDeWGdBzMl;(W7D%=Xx0bHa1~0a{;3F?GF|n&9Uf*p`>?n|LK5{yp1i zoa8wgznfvn`(NSO!DCvXr_=5kVUl%!>>Y*YFyyiG0KcTr%hk_}rz{@MYu|NP&+SM% z+$+W*t_|Xx&|MMRPNT}EqFt;@C;d_*f7c?T1lRCghD+0s*aJBr8^<81+|LW)%b_TV z4Qu`aArIU5_LL#G!B@)ob{`B4bPy>Ns(v*TzVBnmi(#T4)S_#P zC~BemzN%5M_2DYH_V24P^^$7|_2|U_*55dBtf6SW)4I}bJEYg={fGl-p#(TDccMG2 z_8Nu-&BXR?7qdT{aMM+?d#@o$ZO~!B0FkaZK-=^y8!1mMD_Wz1iM*&^NidhWu1Vs} z0P}XdVz54GAXmGPh+u*1?+GnXT`rUjWLvJ->ZMiHLm9|Pi{A7z=dk#WT=>XGOyDbo z(T356m%o39`zAAJdn#%Bc5zc*$7~RiuL9pyv1_gT84U;}-fqY1bR#c|g-Rk^ z(^A_a!&=)aLvNdqt&egc#+)~kXKI!!c}niBcwZ%H`^ZLR)W`-m7Pc(|(1(7T=9-if z73i!>0yH}}b>1u2>A`9nYy;>Pe8t@~BdZ^}>a6QHw~t2Jeh^A^)>JYD1nbt)@5M=J z?v}*_|H_w1LhH`MeG5XF5MEyvkvggEAqNAoS_$R|{?cFXcI0DWx|$lkrCJ;f73MEL zMDp`&f(r5dM3Surq!Fa@I^r>TQJqzMWyw8T)@<7d*D5P8LLiY%fOaO*c8Jb8mtHB~ z!Byz2#e7|xI}%RRH-V~TJ-=kL-q)4n!>5%+mEb`xunkm{4Xn-EZxD1x?Rwp-28@%> z^G##d;kH$~8Ma-!<(EoBd|ufGmA56_lM*eID^$xudvdm`)e9ln@s=Q>cseasLHn414-!-7Hn71c) z;~4g8ZQ)Q-Viw*8zl;wx5q4_)G^non*^NW z+@O5@_MrR&@?l$M7j#_i^z6FyoSg5Ix-t)!u5^w7h}~{!D+4Dj#K}z!SNIdZJbPil z!jGqkWB*WZVrw7RAvR#D)!jyrG-J@C&Y?39m7LA@`^z|@efxp`+<@2uwKXKQcfEV5ji*xF{sY-d=j-me)`P9vGtRaX>x#VpI9aJ6GN z*u+kU^2d#sL-p+)1H99tGaOqV7K`?6c1}JDb23WvkMk(cOB{!6 zJX&49rZt5v1lZ?|*kCW`&PUSg;wEL!Z4qIq0Ztk5antPA<6EXMHhNJB?cibTdDVrDt@Hkl>W8G>Vtj(D`b%aEi zH8k<}x>*ve&D@<0hPTFAv5yhIl80F{YFUndxl{^$OuyB}QDj?imEN%EP@K^#d9u#1 z)N{`}BNUwz>ob?NHF8L&hKKwL|J7}CHh-u)lVEMRk;a^Ojy4xDD%I*agvxhn-!&hx zi>eo~LjQ~t;?Z0677Pzu~IxT;C4b=Hk4I!~83|BvvU z_m$jXA21*Za5Lds*m=>v|5;`ZKZ5m-`4V8jf@$n662yLcF3Eo_Pm?=e>}F#Uk(v>m z)jmZ$!kc~7g_r(Dla0Y>V*R$+<#xNubf}DK9%k-&z}^26@dPbzibp{U+FAX8 z%2#&~KHaElm_VarWwkpX%Bo;x#zkIV=S8u%tP3F-l-2kl=(9@HE7Z7sgPnHbb$@4} zd*xf9PF~GJdFOj>iUV>XpCi86H(u8>h<(Ymw_F)|Zdy0w(zI+CIlh$n;tqFUsb!yaPIZPCtugC)21LLX4E78K`xsb2&se%W# zUDr7ae$-!{%x_$l;R6tD8$tXDkUj zFQ{pa^bl^+1-Yr0A8*u!Rbw7h`u@?d3kVmk^)gEh2s+AY)Ur|J+lWEb5^n$B9-OIB zfnEJr{dTCdzF^q%C1}F#u%LxAg+FL#*~|29a>Y52-{$Mk#T#f&>70xUy2}I+9}1>2 z@leB3$8baBUJShz9p zd;TJYH)9#rItORyHZvCf;Qq@Am4Zl(s#IREm2l!QaM$_wVGPotz|iM{rG}tsYN`mT zrR8@M|DAmu!dOb6ogfPT?Jo0GLMTBI(r!Y81g9;Jym_w&1_SgdAW{uhuTB0ui)lI9S+pcwR)0p}wAj@3 z{y=zqzyAQ4``i%3S+aVl-hOuU$WIGqjR|gC2-6`*AJh)EW=agLp@k_v3R4AV=wv`QJOzCB)g^8JDDVFBqw6FBr+Ge5%^wps?U);T(ntn) z`4iHB$ML9Lsaqnx^AXiBL-o&fS`GpM^EQb+)Hygo&Z5cHL;BT= zCG*DO7Kil4EZc&52xKIgVY#houj7i1^LK6E!Mv{d1lwMzIy83FyBRmv)p5Q&`{;9s zA)dw(M&^yaEo-K29;?+0dHMU)a*(Zov~d&2mB1yzbgIVeb4@qecx@r>QVhhE9mCfj zHU#5|7k%1g-48L_+^61Jw&Mfta9-Ak&_TbsrWVvN^{M7wStw_J_LNJ1t@i-uCH_?> z!}hw-t7!9(i+VE-w3pd6>AP3jIi!Ms|Hfupx25e@m@DDn(@A-^oi%CEW}E78BE5?X zrPmQ3oeRV$x-It<_NlOuY`E>qr0oU^%Rdc@8-BIhfNX#!VqEC3HgyuSHcWt-hVq^= z*Q7d!rN9Pq85On*E{f8sHh9D8NClOfeH9uy+nEkd+${L?LY-3%sFW60>L)r^%*K_1 z!~BpE<)H9C2JtXqR~xhp_3!3F{XCZ_cm^SJFc%g}O`66gU%i(}rVw0Ca?bemu5@`f zDX&0hQsKgNzllRh)(x-l>7kFNRc_h^uheNWGe{7QX z<3RA~LPfu|R{I#Be?7*ePOU}{Q$H2V#;=QC^Q2eC-A~EOS>%i=mPf84mTkw--Wuc8 zH{bPvgKHBD8#No62GLLvGbrD)##ENLKtzvejL{xm$~*FSUwf`1T0pq|7aM08)m9hu z`vS$SKyfHgio3gead&rjf=gS96?cbX1&TWaDaGBL;4Z--1i9(+uKTY0;jVnz>&!WO zc22VXduGpXj_i6o!XJMpuenCV=;r4V5J;w~tkM7F+BagQM_br*oya))ISBxweR9*i z`vJi(ed=^+;M(v1)u1&fHOcLEWGg*a_H1HH;$>U|nr+CM;AV&6SaEeq0^O8d&8G6^ zrVXzl6Wo$bm z_8;7gW{v0C+{cP*4kYSC_R^Ps?WK>5s<>j+I@=qvLTVrmIsYamz0Gelm24lUbopO- zsyxe-H9j^tNbH9b#N!kc%MLlXmpROg!&LW&4(>B{2GP1MRW3e1ox;137x8plbqW+_ zsq0bmbS2tEPd0y-efCW-4mQQFApAM+`;yi7C9}m8(HZ58UxqYGQ+M%uuRLi(7o!4X z)~9>AD8=~Y;IriI;osh8lM|p29To&)Qcam5AivNr=GyMCp>rlW|8l~3sDrXre%uU1 z`cFbl{~o0cN{*^`Or{!D-TB^JrkDqvW7;(9JU)%lS)Jtbff;jcp#pnQAtd*aWuIR@ z?`5C6^#im5Kd3nsFM@+;p^q6~!-SYNoVj*#YY@oIUSB4Q^pIJdx$u30c9nqXmUeUv zS{;lrd30sKR35|y9?AqBJYhjw>fw#Zu);gc{=kRLO}S0)oXvsz3wmr*boZg zD$R*`xxWt$383vj;G<(1*pTvw_3GVzv+^0rvfP7WUuB)qIB}K4JzFoHWxY&^SsO@? zSx=TU6NWL$z-6;o=d0@}jXf4AEq()z zc=KFtQ>s6E#2k+Gab$gqb$3Xeo&v%XMnD8B^@);lyd)?nB6`hJxlxiFp70S6fm3?1n4q4Jw@y|y zmk0U`A#ut(+3vFsrADZxb`LF9iVqTNRxdc``oXnNEmp~nk#akO$xkRQxTbHlWaGA5 zq~mtP*aOp5ufQ^*h{EID6cDoQv{yr(iXzJPGgg2!*nRnB?`9YwfCkyY2PRFv>+s$I#s~?l7TGDH;$gs_d+ttF1 zs9GcuiJo@2YK#|6*aZ!Uc=WG0i!2)U-#$?q_n;4Xcz ze6c}*m#4jCLDlz$1nlXBTa$GmdO&D^l7Crq2u$6KW#6jWmD59Uz5MG9Qo4Yr1!e~J za3;G_OYJDXopk8U9vakpFHPFD!(oRvdAUkWcM*WO+Ry(oJ4AUw)Gg-mX`A4>BWy%| zyv)Kxpo1@P@JZa|(?&k&_&wKCz~T-Bxs4-|FY%uE4h|3UNksyWRcm&3Olfwuhk=*` z%<}J+;0SPqUfH$iPU>x)doF`IhyFo7%80>SYusJBIo{)u@Z-w|K>+WzHHz^R>w7yO z&X@W@>oufVYhkoQZ$q_-^Vs772deNYyqTpABEkjBKs~y*7r(27ML#X}6b3_-e=zKA zYPHWU*#Kx)w_U6cR|n4toH~TU&%9=j4KHKU$3{QNA8|^TS16Hx^28L9H`bHGCjq-F zz+BrFp}JixyiAiHS?oEuM`RXzQwVl#MRhIX z?)@pT(}@LQq6L=BNTQoZ-Be5jNODr#=Or}jp~Nd{@0iG4#ARFvewJe)*Rm5<=cHIf zJOYOIz^**1jOqTuWA`6iU1N5Lfo`O+WE461yv|;s?z0Gmy4g0tYHMGx+~GRfZJTsG zgZ_oyJp5JNHFx@F096W<-5k?(8!)md;#2J^8yV{EU|Q2MB2;Ha>vu~$68osOvps=G zJjBafhvpR7mDc7AA%4QNTTYN^M5WQ@4+7kX#!I$wExArSHgoTF^bj39LuAWY+g4c1 zpH&RfFfVq&fAty$r2Zyxu((_I;gZ#t_~Kv1Myl7ahG?Z@=Xv!w317bPdcz8zTf;{2 zxL5zmO@bG)n$1!fdC~|qwnCd8n-AxyEw%!BqD|1Q@y11f@W?u*Uer|R_`74$$9p`} z{M$W3_*{$wcbPy|-M)0WyS>rfHtSa3AczpN*d>&OtCp9OMDz2v&x&mwGe4Vx#57lq ziFsI?=KSj^A)zQ0wC@{J&?fG!8Pg!EE&diost$e<$x@2)HR+QP(r%=~9P@*7<}c)JdnNN8RT&yZMJfG{Bno4*Q-aP7|bfc+Xxh+mre+06PRh77o2t zk*B!UFURk>l5xz9#mDYC^9Bb=*HF+=V zpUAd#Gh!W`Z;)B(s5!y<3TTpQVzA(Ot@g3?5$Zsvb~9vD0O#*cg6#77QSTYh&l=w9 zYDis8V)s_|NShh+U@|yi+P<`vPF<-z&P(WeJBNU;Thh(|Z~afjK3s^_@l9ds7(DB5 zzQBryNO}mweCd0>!q@jLP&<((g4|WGKQ~)COSLZ#kuLHcp0l}#&5lAgoPP~9WIa1OT_T$Uu)T7M_$3zvXRl-gA2>0$Ko zqNInvs zbsFE7;D!=i2nXej`wHe%jo_HmX=9K}4*C#gNH}`0-l!=!CBRi!95GPgMx zN1stbdNPmwhL&e68+p%n#xCCT&k7Ht+I#qKjbwbeX#D2YgWY&r{Ao8dd1u;-(T#Cq z+G$r4+cxe%)HXm>*S5J(HN^W-LXYLcG?zTE~=Xd zkos@jVzevr%|m<#)))Y6$GaVi7q9rOE_C1o4rG95g6$qFeaKq9;1{e8iL;^3GtHrg z^rLce=c)d8?*X2W0-E44Fk5C%C<~@#`O>7vf$x3Q?GOkW!|mprJB(icRp(G7(wb1K zleQ8&SJkz0b|pTfnXdx%jc{J+-2I-$w>dkVH8PO~vr~@}eGy@SG`Ev^?{y5z_OnF= zM(iRv(4Q9g!9p4cuW}HJ=nBZuCtoHnGts5N0+L~^aD><)iLa;bOD5&Zcncut`KAB8vcf4p?--BS}=`qmxGJ-qzl zXJs+xe)q#MlU6V>eR`gbazmTl}a-;F3t(1*MDJnoed|(wF zbV3UZLLJ@awgbwK;rL`;FrTlxf1?-Q;X#V$Dldv%$GJp1KJso9@hztXk^vk7<2u4& z3&I3`#53W$r@ll(Isw98q-9?Cx9RrXdv%jDeLf4D0yM9D zTU_dt)u`1ukO>2kT=L@~y6>LbF% zy9C|aw9mHZv#yhG(E>JB@AJ9tyC!q}T-&b^k^Qf78wNj|Osq8I^f}*6>9vqwW5y@C zb_9L%%pUOX3eTwdDBI-_5T5KCCc>R2_60KF0QtB+`Y|Ww{mLL^x)A!Q^#t-+yif#{ zoWE#UO`)iqi}i4jX!_V~_N8AhKl=g1Xx)?Lcz=TFIH#%VnAXeG&PDgRgSEV2S_HWJ z1x@_KecgF~>x?OTUjNV}+gIt+OTl&}}zLJ4+oCOf7qP6(Qb+ z)cwxpmrE@NbmLvleV*{&HpB$fpuFnbz(WH*JKr;`uY~ufOgyj6RQEqb}Vi4=yg zFmz&19LOBW1z>&bAXx$tXM(h0FD*!?^K zs2mlrmWjiz3pr?x+nyB$3tTOIC-=KsYcsOJ4c-&uwA5I8k$$i-Xu-5t>dH2}FI}FlK_%g4;hein2bGl21IEMpg*mvj z$ys%Qj%df#8xOIGNwZBc^@H{6pmQ-_W%7gaMR?z55Bx^q8wX=;n>`)0{BL_x-kNy` z$laeyUa?iz+n%${+EOjmv` zPurgG(u(4xY*HxW7ru6A6R4My^8KvZ(Y49B7BS&vbT;-OgP)flqr(Y150pOx)1w5k zaM+@+?T;*X`hAz9`bN_Y3tq0gi5JJ^uWp6YUF8kwF8uG1w?uQZK0ySd1998PGii%u zf%NCU(?m&346;p2>%GZv!xlICrRFnj`fSv+o^#C0c+>|;r~K>*3K5zR#x^d zww`RRPS&ax4%U`l9IPQc&`Lmw6iOVTEErDUVC56gosa ziHL~zHkDd@_w$=nICVAkdU`&Of1JhEyF{)plm+6giK&*_SeKIT2!uBSK%%sk8An+9 zoAVChok6Re-e#za7^7CIs;XxfSmh`W(VB0%qvj9!&1HxM8wA#^RQn zE|jQt@Z5+=VKzM?;+`;$-FmK>*b&Y*)T@AI6Ol7iN8GUhGXZrCy%BK*?ko&TT&@5w z0dWm^4O{q)FpBV7VT>otLkust4{#q4+u_$k2Sc4Gkq;-{uhxVYxBJ3hDQq$n5KfUE zBHSQ)gawO-n7v6r7RJPQiv;&IjH*YCl7jxtceuY{I6YiF4LzPc@;!s{_iztJa1D{jPIQO)xNj3{#iDD^o)mRz5=X1it-NVk7GYa_~ zDt9Xi*Ys<9JAY|cbUS*(%Sw(_ZipHyk;YlJM#?w>%<`5t@@eZlt4Dc||Yb(QmyD~?%B z3t#lS@!oa&FU<#Dp{}+BZ72b9E*?|lb-MqQ+}j6pXkUy6BiD>3=*Vvt7 zd<0*!U9pQ<)?b??RjpS@IYyIzb!VC>{*4Epi;W=5i3`MV$$cZ**2jYLo0-oj55o?t z29vVwF()E<@h$v2+LRY5Cb6(>pYL)3DpA>osL4AFk5GfPbJX-vx$3mR-4GxDl)Bsj zR>pgixZX|uxb3U@Ny%U5+C;jyx1 zXXxD-wSA{db0H7K@;4_HN0$1pI?j=FiUu+E?sjLh$qZ-qjGCv>$JejVs%D}^x42b4 z+y_P0Itd4xamTS&MFJ5wg|-+>SM3R*+;))C_AA>8TLVpX(`o;Y{i;?YS-+c)Xby>Y6W&En7!j&GPdcTdyPc++{Kkz+IJVc#f#Hl?VV5NMOX$%RcQn|(X8`Zu1p z7eLanNn+%hwsr85e%r%FE4@lHg z#U^uOA;o!b<#`0bGHr(`C2{GoBFwqMC#M`;a9oNwC&G}gHG9;&=Mxj4p44{!(}`) z^?6)KaI+>@8;DNT1D23*G$eun&k$B zoLYXgEU^-MF8R37Lf;DpV;C!#R;l_UIK8vOcIaN=Cw5TD>`n2GSg1J!*JN-`ywHs^ z_+O(An|Y#%AZKd^d(a=Cb59`cQVAJwHK%rYTfr9|Mb#tt4Rhi_hT5LPA(@l?A(?}_pk^31`az>XZ;pD}-x-c;oTL1Gni+#@ z&K|mPp7=RGI7rzU3aVmaHQs%J37kGJo>BGCsp?#kvBL3|nO+X{V5j0rC14iDz ze&uG{jL#ap;vLlkIUJ3a>3cx5Mya3F%xd=}f>HMmKaTy8X>SgW?1hAjM}<#}zAfPT zVd$`ETIRLSw6C$xqHPB*A?hFsMjTyaH7|v z>N$2$CU|%4NCthFkCWdDrG~#i*$|uw#pzXzqw1YZ*bulmgH-JZY^D4~{s-~!sR+Oz zo{AI063sZGqkv5eH;{X!7tYC#m@9)%S|*}fKX+t)>jw6M+XY4FjC_QtjsC3c*PE7U zJpt6`8Q!xY9^qvnkg#FA=CW^wqtcP({MZQwVa@I7Ab@;=E5BX{6kOVT<(mxU%MKZo z$ms7rJHSMC{RQXBFE%GZG=P11-5$0$6S^4ddUQBYHag{d))T|M*|bAVhE@Ufs~TcO zau!B7YsT*;o}$<|-&A5@geBFTQiB^1~I$IR&88 zK#y|YGX1#8!?Vfb#@od0Mhp9<>^DW6dlWsf8tI9OI|wHd?vG^jpof$FRqyhSj8IbI z5i?bG+W2SN{^T94q0oD}+lh#_*z&im%;wB{A5?MMev^_Y4gos75t+dpSVo%gl0&dn zlnbJ)1$`&F@I6qA_!1}v=3W^V`sWXT?3?C{u$XI;mGDMYTC*TZW$_inh1quy)7P>D zFOCpaWr>w^83_7tf+{Ig9w^$42pnZ(o6|E(tmdy!>_&L?$SC%VlRu)9dtU%R!fg$a zyyCmT*p)q-m&^^*62`t{@AvVVz&R=>s6P6gtKW0iyPoGjHK`C?aIbWm^J&iS;tEc# zlSOyzYQi5(>WV(ZV48c?Ow6$^gixOiNFuD78V#(l^0t0mk81~&C!}vw@8x3VjT_Ix zAk(N&tFEF*({AV}H(6G^_yK0K=||yr@OC$j$&<+R&-Y$Yu%? zH6vHd!o#boy!+^vWsAGg23^q=z*aP^vJ^H;_B}u~#@;(-kwOJmaXYVi%l>|`y^;kE z;$X{+Kij^*Md)k_{18&?{`l-cnogVVdAfh>>Ayo84&L9FA~-2+$<2+7sn{*B|+HS@B-H~FM z4%^}uOmPOw)~VEjcPCu3SQJ^XAjktD84M@Ko;_A(gk|yuy02rjaLMMn@FJ>@czkX- z1)PpYx^r8-UGdfW5&FU8vLEYV~n@Xvk=xf{zAP7KBfiG*nL zkT&&z%EoJVI4Gg>i#z` z)k=-j+k38;m2sRyfiIOwScV7x<7R`K_|bC89_Brv6NIdmUn`y z)IU!JwP&_Y_uEnzV9*k|#*-kobQc2*AezLiEd9$fmJRbK;dqe>5z;IU^IxSL*5NKnCljO2n=#2qS_DMs2l+H6*RD~ zEyHXx2dAXqMLhgXgBzAyhOUB3gqtj?gVHfdwKLNLEB1EfG`P)CF_r}7+sOq9z*_-N!XUOZyeM`9+ zCT>_rALCy+vtz%4pnschz)ws&0a&ToJNX0fD?7Ljl*w#Vj_xBwOxf!#d_kX=U%b$Y zniYf3tQ}K?s-A5*9I(Bu#aN!{i`D9!k>W~H?aSs~+Bx@fJqe~>?8cmaWI28zxf~Z_ zYU!PUx;hpP*;Jf<9964o;B;>IS#`+#tJ$FvOTtOU+=^+2Ev1T{Tp94$5TPyGTIlZm z#%+sjoT#qGPo*vjTq(W-`IH1KF&eSMbG4su z9?dQ1!8Xf($Cp;`OV)`38g@}!{-4)zIUcHWT zgLDULC=TbE8g*j{tkP#putzu#&eOH^e~&oV1G{`i5wEm5&M++a(5O2Ss|!yTG7-~? z0?8Ig;}JGyF&YoLU-N7t0juGq#4X(Zqg%KcDv?w#Q_X8X5=((VX?i#Y|XK`18)O!rimz;=G>FqY%C=9!OR@~&UuJcO^*ZazC zD*&5&Qb)@}qL7TykqX{@dsV2i@D_+V#|@0v1yDt_LD^_GCHzI9PRvxQ8gy%TFTIrl z1&bF>Nzb3Wr)}WOei1olxW`(xzqf4$udh0ZwYMw;t zckL7i_0CM|m`)UJcuvV{W4z1cHYaDIPG{(!I>efJJzZ-#0Z}{{ODSqj^Gu_3C>tnF zZ{*|qC@<}R`q^q$EQp`CV}6hBC>)n{5N&}GVzyKNZH|ks_WINHkm1L-`Sie1uS+C2 zAxjQOU0&hKSREN>)VlCfJ$I!{tGuJP8O}gQH1^@UpN=ig-yE~g^cQuq^Ty@co0nt} z*eK8S7Hyl|tI5SPl`C7^S%2>!K6|FRS9hcD7~xr~>D#^hB8p!*jj2BBjj1m0^<5M- zi)SCT#@q1H?~gaK7mxN`nm2r!nOEc<>}Hhhizfs}vEgRJA?)Zz`StvK(70TGh_!Hk zB2ib(M~s99KYgxyJ2j#n9bBg|=NgiYs}pUAyYQx@ht^%Qm!R(blu!&q)W*kPqSvTa z<`*vG+_VAkJHo;ADD)k`qc=%tm}O;!CcVk)L)FJZih|2?B(M|$X#J8RI@bF4#kE~Q zmP=2^b`~oxD*}lt;Y!at1Q6?@S)$rL$?gHm+nOdg*TTvsdA&`Cy#wVplP*2koAohx zM*lb-W?y8)AW%a!!j~`4FLewQKzk%$p}mEN*8lnBHeidmTOyC`IZKruQ0#ap|Hn8ttQ>)n8U5AZj&hGivn&tS}b- z;>DuJ@G!cC!42YPy=h!a(v*m< zffHnq5dv(*Z92Vg#B0E8Kl06Uv6-XuONAD?<1hLzH96>%Zcik3rnL}6L{&1P{cK70 z^X=RHofI<6*D$+q6&6&xk*^EO*%1!Ojb!|Gq(0dtXn66c&u=IjNR`(FT{ zP`<^WKc9Wkr+l;jcoH{`j-UHxf9ZZ$-P7Il=G_cBJ9mPvtjoYa9&C^_0?6o+Ub^#)3a_|XhYpV5%dfUV+9WK0A=H9W_ z^?bP9v36rk^V>$933MFxhn`T+yhE3@7Nn%-Kl~5mVgC?vM$lig?gImPY9|bcFL*l) zV_;am;U*^M=D0UD0Y1j%HBv|HL5sxs(MR)wj=*3?I1n0w3Hp76MHUR?@gSYt*gA*( zMzT5rUqC;)x@XN;>ZuBqjM8h#mp)c2KfFCj(D*I)xnB+ZUT2L-Ko1hk=;n%F+pWMh zDexc^-bk@{rw|5y4;l)}EM?NX2Q`8xHX8x2t?by9kDb=Pp6`kklsQ-ULgt|!MK;9u zlCoY7dF~Ve!=$K?xwM1MF)8RNM}-p|lp@-NZm`m1_p%G#B(@`|GdU3pmPS&3hdm<& z-L?XE!470!r^|t4HG`4AFz|fir8ES`2x-bHhdAnA@n9glwFC@gGzmz=I)b4J6>ufrHH#;qA z_>E!VvkhunjJiXSLr2FKY@NIy_xU8X@$R{ zlaJ~Uy>HNppL<2(vKF)T5?dvAPF-mQbvo`ag2WOk%SDq-Yp=DApG+m2Q9B-kzxM{~ zJlkQQdu0VREZug7{Q4nM;r}W=G4#P%JHQLW0voOJhe-9ovy}Cz`aBfbL-x*BuSw45 zU4WXN^{KlEm;xqp6|e_$)er7eh}}k(hM+Ve$MPAczUdZm8F)qz5b4$`J&bSJaShSer%ii@f8q~B7*ypfbC-BXeavY<$O8Sm5Ua|VRKIj0j z*x@UA?DZ+G`=B@@|CrX-sAgrWpXT$SW+c2G!+P1who^m!>e((xAL$32N=4v!^?RQj z2EmhMo?2o2Gm??!os27y0PQAcTFr&+ux1%9vlamOmVG(p%x>+A6XWQK9Ty|p@?Jpc zp?++~iVa!W;m^egg-NyM%Q{DjMR@10b`oIi6D|j1e}eMIPDU1+VOlLVd}m2>E4(82 zs;*<*=?|{#C7oLHABriC@a?euI!9;J^Sfw<>y>{EGSqJ(Ezw6XY$Pi19xJ}!J4u^c zQAbmZ$fm^oY)ERhiHN?-8m@jOFAxv#wjL1@54%INy$LE**3%pt;HFIs|131AwI``v zJ>6uaeJZR;nm>w$7qmK4rs&p1FKb=MXu@(Qs5GI5ex&RnaV zV(gjWZW}RI!G36`ecl1@1)BPQ08gQpbyVQcYw&Id&ZS1-;GU7I;L)vav6MgKQCG#j zCPd^SSE-I>S+=2#_k$X_W>5{{A0+V|4F zU`g002RqO{SV`Dwf`FQNy#F}ueO*^L;fcOigD@H>DBIoDVwZewIv|n<}3%{xf6jMMV zHULHGIm^h^<@(Wu<@&*e6;ARD^Ge$z>q^%n%Sso8CK~^p|tzS3s#$~*9_~P-(^wgKEWFZT&Y!+VN6V3w`wlHG2V5;+_ zF5{oj_$;?)_OFN{mNsy&Dy3O4nRSMlG*>&p`rBl?I1b*u>2RuAVo^6CAfC_CFS@xI zwrc*R)Hg1TX}4G4$F4dhhA?jRHGF~D^r9ZV5RsIYI|3MinK=2)eleiwfb=1<}i%|ZtELTXz8H9CJlnf1l52(@y-+QR=gU{mE7Xp0z660 zyCLpP{CeJx=I~72LIphI&Pc$nNQuM07Ei#q9(RfSMH~*ndRJKgnfGR4aBSiD=xF;; zzfYdpCPU4C{Lz({@$BwJre6Y3Sg5#`G~4edof8~5AH_Kz4Lo(Y7&8UDpf-54vNRkY zo;gQ0_{x>6d13r%Bg4{GH}oT^3g@P`^pChxOjzq2?5Xw8#q_Z(Ck5Ftgi$*{Mhj(E+T~^|5P{8VUIJJTi3?>B*TG_!Z{(8r+X9 z3oxCgenMPM5-W0~FfD7|MurXIx1v)iO(k>ESW znpZ0=cPqJOqQ@i>-J}z@r?Bq5u#@&dFXr~0zo9=`Tjc7-jNzf}@NK-KRw?9*dS)~t zBKi|Bq6az?ei)vlc40$w@jb&f^4p*ND@Z$oFYHDBYIkx9R&=t< z!&D+%-ygQ1zLu^-eRmv}d4;w{3KRJk1~)eR+I*PELsrf+nD$GagGBDkv#OQW9cM+M zvKt(#WX%58qb8T4x5_yHcB^!`?aoOhl9Tc8IZMusgam(I3{rn5pKd_yo&HpVRRsT|am$hggWs`L1W@(+xHeuP%gXWkZw9|R zg`G`wt$7dUz zvy^4F|4A9Q<~c!A!=re%u{qzX3iT9kB*9H}a|M88_r^)G;4;=p@=>=DMxQDVsZP=^ zUc)S4($z#rV1_;O><_X}m~BwU(hPo$ahl6+{eKi|BDQ@NrBPRx;K_5GZ(HSSPTsoR zQ}H!!{i@cs&i^Ws_MJ)*qjS~Y3wXA5)T8zM@wV3p;U7w6NDM{K4Gk&NqOjV+`O4rB zpG=1C?DQUn?sz;qF0{(BfyIW*iiUIkbIV0h9mEy%=`WyeT6R-|GEy^ANk^4BWu14c zYDCKecE3NXJu|KpMH)i`Xu|Fe`z3>_z3-kak)I#g({~g}DOdZs0-_nkwD#b%Urvyg zSO{B9n^u!3eTvxYNsmZIT)16Q(~CS#zLCyTsEVd@7cc(pY9tuR$mi8a%Uf=6oeFA> z&XzWkSm# z93?L!{3TsY-Pjy^CO6&Pd>*&Cr>w#`97nI9A(k2YWK266a&GH4kQtKMclK3BEcRLU z)!gfi3dgpO(j;brv?XuKOB*!!)z-b#S4dRsH3DifSkG)(KWF!bB=deVO%%nd*?-~} z?uDS%(&Tti1!(W8y~cT+V|3G}!uhSy*i!=3j|X#8N#J8!EoWqWl-m156L}kyXUZ_z z>spF4og%e*uEH?NnH*`nEqTkyN9M4sUHiKtuWP@$o2+w%BDhyAgIbkzkRB$F-dZco zGHraMO2$X8S`I9vVZt@oY!i6OIs%2T;bqlghwC`CPQ{5J_=dYMOC63#7ltl}?K~;@ zB;`-=Ugg7QF9$r)==7OdB|~J_th%UlhYpT|ZJnsZLbH3s#ydx_Q@Xi$Ipl@2#7s7? z+uUK$6@loN4T2ZpZuJ&c(@im~5LDmrjdw33+XPqHVO1W+`){|@^y#kWm6IWEnmG9m z{_(0D&b!EOo|WkHkNCyLtq2#gq|IX)r1dfdhjW$UZeeTIx&0|F(@b=m z(E8ST9ZsQy-edSF2OgZFQ2Cd$@mZ7hS#XUIFyh62{@OnS!j_v6jw^&!Cj5TqZU z&gdoGtyXY(g}C=au^YQ|hzRLnwYgwz{iG>YTN2lh=~IJu28`AT)?@PBTKt?xf&10X z&d4NApyX{%eXCV74{NM*jAM1>s;#^7@7l)O)D09U1d$>6ak80AoaFozq!|X1;MeI)=3+BLTesNl9{->HF zIm+6X?<5yKiV#{%5^&H3h+~r_X+IMMy#(+KOia22@@cHtd=#cjoeVhZ5i;*_q|4=Q z(k{G|9`-dMELNn2XG@(t>8LX)ln}3p1N7A$uWrAvJO3rIc3fjCovd?NM*P-ZIe#aA z6ZBW$bO1CD8hZXOz}{?p?V1KOZFGAqW&7D{k3N%jU-?r4U`M9oaf~i)$X8##DJ;3> z-&mwpj{Nkxihr^&@h9FL*t(44UK#&VIOo}6A zNg#O*=4~(vNN0$>`0KKQif&@EVNwX{Rf(^0!Jy!UMj?!rfCUms#eq87{u{=bA}+ig zb$}+tOSdUlB>e|;li@|7_FJfwJo$5Pyn_A`Tk|5hZM?#Df(^^AvEu!`;OA|J2FXI+ zY{t2nd9ZC4!O8d}!pceY&ea1mYdjk&c${$5aa8Tn|N1^Ncpp2f)WWrxuk1aVb!k#7 zXY#_mh|*Ez!F=l+MfnRi)HJ?h#r^k_OI;q_jldQ`qjvlKR0nl?-of4OzYKp_YVuX# zlPA%$N(?8~!okR7VUwpMT2Z}5Aju+pu8rsC1KHeFjo|pYfbZ^~&ALY>Cq?2q0dn1cf!(5-Pm%kkP0p%rshG*6 zXMl(7b7Js415Q0fSFj#< zY}mlt0bIulKJkuS0|&j;Fz_CNK4cGeHc_GH@$XxANrlq#4Zm<*@%iN@C>o^r@BA^0 z^6x}G3Vbsh*ikDQVO2BgF?SSI|C&-#GjeHDNS+ePhmbU5-jxm`ar~6-DE^&(0uDKd zg=b(O7%X?KS_#SNa>sGdbcx6Gd?5+YYkwagU4h>s?J>ZToYfBrRoCcfRVt|RGBrxMv0JN} zL2&25y`}N4dMLXoe_ba8WY6K)Q4q2;#a1#{4+y-Gn3*8wEOb)%@d9GvaxquxXoYa( zzUi!gVyULz?`p;EBY%q#WlxX}Up&CS!_3jN?ZlC85ik2n62R;qaGG_P+cUN#Fzq@p z5qnN7MD?gp;Bu-s?Qac1?>*`3A_|f_wcBhvd|29=2EhBjci|n#hOkXUy~rEkb)xxd3loS)2$QVKHTK`&uyBy~ z&t<4sd{(O9e@pa!R*N}G0XN1nD-zw}=0=`?aNtu67=ebvz?de+%cnR*Hida1AuEz& z#yHdvs9ZrOtLQBgQLLLLBqQO#D63FzVMwWY{3$L;Fj}-cz7<37qw>3W`I@MRl6i}a zYwASLU^cAGI{StGL-{$ zYq*Xf6jtt`6g~cyZnk`xVX*p%pdn9X{WNnz?#wyI_>{O^@Ok{)UGzIYU}@HCRF8D) z+bW!LJl@YM!!ds#o&~~zJMrx^u;hQnG#|mAQedcS$TAeSwluEkH8VLmAv7WO?I%h& zD|Ly4`I0QkU%x10`VeK{e{Q3FX>D96h}=f2Z*4T-b$2#acP#m0IDdDy-DEdkDXT-( zm_%8Rn)8}NR@;~_8Q^*X0KY=^{Xk>8W59-|2`KE7!;+{N6w}7nCGAqhpg{W0`#St% zSFh-UWLvtDLe}{6F=l?se+HrqfQIsv4h6;aK&iI5mW+TM(ve%961yu>Q6bh_mVJ=b z-?YjYtGuuWB6;LPc|xxQrxW|VjUyJ}T{4awN3+kzq2x17RBP7*U)v7+=aq%d^(_t0 z?Jb4QhxytS;uscMYdBc=O6m78DWVGHC;~OABkEF4s!LqDmLuaAkWJ|cxk^#GwpK$Q zKF2;LC2CMd2eTjV3xz+Z-2DM$10Qy6PGNaG@?^KHEALxv_yQ+*uE__#t!oE!SE2Hm{IX(NS33OCM; z6MlKHc-%zC`M3Hz%zU!T+|#dYMqUfPafe?nm6Cco4wA&D(+9W`u(=T+dYaPAv-Tfl zYhIQyaL6Iqy*SSs#0AXyr__e|X`niPSeKb40F*PQ+j z09Qb$zd8X?&vW)wAACbZmrN-te8a~;e6@Y>(M7eU6sg|uJuvCp*8OP0HY4f2$uG7p z5AhA@gD=m--YmC^y7?9&zA=69MVX8-BWZ!jFSdLz;`8p}d)K+NLB5Ek$yh|A%`8kt zm<=>>GaH2HUDxNj*H9M_-GhJa^|`-t{nqn(!g%n0uFtIsyyNw0d5u^2mU~`%Q5hJ&xHKWY41972CZF3h%(U{^@XT6yC)T?MN&~JS{Lr>)yEnkQW>2wi7?Vb z)LVTV6Sd$|!tT&@byF75pN&ic5i#vHC%#O1ya^;RF3n`ycit$`#w zGwu3;I!C`QN1hugPi)395u0`Ez7$Zp%0?%5MGt-K#{bW_KDQtIzVE4$GE2&MZ`W7; z>iump2)okcvA6ASlh2waBU%Hgy;+jKd#{nqI{^PP_P2ZD=>y*W{N%s8zfFeT@FK^W z)`i!Rx8OzQk$AoD{q3IE#DKRyxBI^Kx5>~OhB1J;E|rfc2~pv1FeLN7f`85ab}FFW zfBHxEw^5MxW=B!b+R^TFLmt8&4`eeA@lQB*dFmOjK2!+vOUuQ)utR$_Z3E> zcnhG~5({IPVqr1k&zvjC^Ctz}z6zk(18Q%W#E2|IW=6qH2&3H~6vbp3K)Bve3KBS7 z^`Jm>*ZX^Mvjx<-(8^Vh(9`dGn?Hzbi1vH(WIsbu2I>v!69Bsb)t3aJ9APA9-4V!{ zWV$C-Z>x`F`8~M(UaUglGK5tq>eDi9`fXVK9(?{N4xxa;0kx=Y=Z@eRLoB>QPY^z1 zkm)}Y2U0&*gTDP+@Nej48B_sVtX7NPf0AA*A@y$NK^XNORI)A3fNX;p%T$B+t(WDn z9^6GZmBUJH`hCdST}Z7(%2AA3)V3oYpf(VjWgCbGNDavJ`_?%dtP;2*S+T+DwdwbP zgAGRE;Ew%*gWOVTAh$|2kXxz^$n<}k&YcA+G$z%5oX(v_RD-A*{GxMCdf5h2gY5UN za|P&ZA4C`xAf(9j`;fJRfReQW@QbWT_0$GZU4((2)PPLCZ=I_^J$i|7s6ag;)9(X^ z3P9oT68wUL6OsZacD8|&f!csf|F`K}1Y7_kpfCJS(>Xcnz$8fdp9>+?7VG$PRp_a5h)k^rrw?yNY8zJ9PNT%Pn&V|A$2#3)KgDH?qzb_m{ zci}+Z7fZH-{7FOPTk?@_X-KC3OdLuP-2#2@-7rs_@{$GTdNHL8hBu&OUaN0A=aSpY zZvq>TYubruEjkXZMa5tWil?JE2(3-YcioWBe7Q>*?|jex1ax#FDhn`=F`#Atn1thB zP;tXg+88WmNwo35aerC2PLS*GAV57cNv7-2I{KG7(b|}-1dur6XiN*iQZNt1X~#4V ztkRAt8XXJQt^s~eXi2)mp2aFAx4}U`h>eyW9ObfGXz8>lcbo1#3hn)sWQft@pxX=m(p{oO4eLu$|M1f=#edSXWAZRjfB8)jX7 z*4Ay*`T8^QB12zzeTC>6pl~5E>xmbccdx7bzl+y?@WJ5yLkq=3~_N;d*>lM%}mb+y8^K zPYHB~KXxyTC7{|P`}o_wVA5auLY_;*t~8n7oqpHx{|o>B1R7c!M1V!ezAgjv(VF*< z1|Gm55>@T>Yf{eoDo+Md_sH^On1-UFz20Ph3T_YFSaz3yuW|cH=s3)dM9cSRp2)vu-lxx39}!Z z1gV^`*`&U|EuTF0bFxZ9v#4!AT}cE)Qv>nxwOR+ZXuy^Pl}3ms2!R;%2MGiyE-nVu z)zyU7J3M>#Y(4nolTR#=zcHVfKOgw{`2iQg#RZs{m;k9nDg|n_y0yU_uB&Z0rAA_S zmxZy*%DVlJ-ox)HBQvQ}6Afxso!YeKWp-Pm4!cg>q^W*2>3JhQvQF(?r-mTd4c5F& zXwXb#&tf-dp1mFht6xQ_o;Pyp)HCXkfe%hHu2V~u?HMow<-imB&_qfbiqq@VjAM0b zojNts1lO%o>!CmW>eTvmYJ)m88}X-Cv<$t4$slZnSK)Is{YF5L*=fduRzl2*+oZu9 zY2lz#rAaErRhp&yID9ABY+jP&GA%NXaT8*b`5B03mN3mm037?T7O5)*U7bW<}P zEklS~39s1hL zuNUw+mX1RuzI+LBarV$X-&K`MqQw9_Yf#sF>amY}rTejAsXZ*U$4c#Kpwu?Taf7wL zd-}i`?hgf-fwl>IUD8HW!RNv_b$3^N7k{WArN2W1MfubBTJYM0!$G~?-I z2>Tt&5b9?L4Kjr63?XN5hLD>fy zJULrO@nED3in>NEtm+#)y>Zcye<6V+y7`^sn=-gBVACf_rQfj~glDMauY* zGQ(q$GC`zF7%4M~lo@}RC+nXfG>O2OWm5-~%a1+lU`?tl#mi_e-Ym=gwK!Zw6ugdGYi@c+jD zR+!5FNV~tmOf#NghER|p6s8Gf#cEVpTjbtrP)hjPq~DHoz9>oC`Ni$5BLOaVPajD+ z5r@s@Roy$ZDy#WqQr4cVqgmim*7sS;EKL?IXP|(6(&8XOk#qe}4xf9rke7XEQVyU0 zL!sdrbU^U3&`o%@(CBQTvG{&|4nMHJ%S}mSra+V-G|doZnq>$F2xYe#aTCd%E0WzM zN4}Xj%gf>#fGlSE{A+Oi$U7CTyWQ$;9C8D7H_nrZBt56oTlJiFdLJ7o(D4v5Mdw(e zbGj`Q&I>+|pd~sH{sj%SKSN1M$O|BV2w*(vafw0MjKVn>XYxpAfsPhnn#!ar*P~ZX@+-p{nAi*_Q=d&Sb{2l^8&54gHFqmJz~J?*D~6*bZSu{R z?9Qit`=R9F@XznL;@8S0-cHZxG4<;`%h)P*JKMlqEE-^n%*)KN zg}U2ZH~&+T&dz5C%D-YW&BKO;nN4DNkJ=yZLbr32ejMiOILGn0ufjUMY+&jHFe~#( zReV|gOtJM<$5O{?N6_M^D>0P}l^m1=Ng^dHC4hu(+N`eyOTzey{;}+MFl5cquvHFz zWgElOz0I1IEK2ZFFrtm42Sc{Fb4l^f3Sy_sDPcKb(T;6=;8ylflkUCSlhf)}CaF5(kZ{c6 zpH+Jm#}tK%52E)ja^Crw9RZ9MMNin|FM=)+xYxLiksi_=(OJ>r)6v(W??oS$d~LJ+ zxuP`=uuoPd8l^a=j7pj4Kg&NdQn!G2@UWeG{tuN~^rzYZaqI5l8v`37cDHkj9@Ol~ z0e_d?y)m_D+nSkKi+3m0@A6N`^S@M|Sz20sAg#QzjbB`>uEz*N!ludEYh$FLH0_%M zI_mTKKe&v(+0MOa}kIGFg+{%twVAxvxXv#o^ zyJCaQDhCS)@^KydDfoqfbZ$$W#4K>W%*^TE?S;7u(`u$+QBKJnu7IH zwk?+Eq`|zb37a0=>)a<8`HEBVVPa)|)xHS>8uqf0M`7K_JZWQ5vQ>a@7dU~ zm$H4=>?+DDI#)FI=H){VFY09ed@6clVM`IvEio+_S|Yu!TVItOc&(0s{Vh)KhnVn^ z^H{y+NH`oH#r{lcQzhE9$mU;T}X7dJcPUR&u1?b>p#3siLyjo{Ju;^$#cP#2mD$QON}q)j+vGD3FI_Ts zE*$?{2|n84@*_y7jFRVG3(OwYSq0>5FLFI{nIWBr)@mzoY3wC1U01pgEVvr5!o3Q7 z_|GVLo=5aB=wHhBkCLxXg%6|TsR=hKDs$%ScG0+wM^3-Z`YUn+C;xSxOGb~K;%A-r zN|RnFmiZ~NQ2xv%@tWXpIcJ@JK)sV}#VF}KiFBEG{D{G0jsNNYvwxt!wA19-o!AB! zSxmgft#cSxFDz)7G&9~s8o3QDGm%=18zmh)HY99Gn0;7fPWuL&6*fHd!LQWfn|%IB!ridqGub>@bX_ zc9SK zsid=nqqJ1ID#3W=Y{??!63IGAsw7u(T?y_hA4uAi-sWqoMQ%H)lnPLzxLDsWr6#33 zf6zIiYQv>**!n`+`U~b&EVo?+F9}i2i)LVY;WkkLpxMMV#h|QzYD#WOLDI`y5K$um z5idYQvvK9igNh3v;x>q=FuP6AA|`@}H6UVivDs}rf&jtS`acJ*gpFdjViB>Hm{*id zoFTxilKVsrVXy4R9>8{Dk7XwWv-c`LP=24HOwpv!vH(0^%C2UU>K>N0JWFaG6=WW1 z{?YysQ>~cU>&(G-$|uSKb78q^7&)oGGzWA?Bge(WVP&Y}z53_%>5d@Z@xovMueL!@ z(PHpe4M4~bo(;0`T9=-Ny!V=y^V=E$P19h&CJ2=#z+C^?Ytp-q8p9k|r*=fHJ@VZ9 zxwE}>We|Dt&l}S!S~hOM2-)~&_06w4*1cv+59@5dS)p0o{J~|(MS9VA-K3(iIRSPD zCEqb{R~I&_lk}g<*=22+@Rdef+i)uh`9wb3b7;8X9m!bpU}1-z`nUu-8|s(|+3R=* z?`~oG=FrMpJH;5zJl)~Mpcy4Y+Nfu~%1Mlx;Y2n_1la2+>OklY1lbGAF zd0X&Sb3I38d!lYdi*62$G2BpXRVRchjrb+Pi`iM=C(5Xl<}sI!H@UNgAz%REDTu#{KMUk3_%jK;Q#P#t z(j0_z42|#XvVb$5WV`H;vG4k%fV& z1c(6PU?`YNfGDsOSOBXc;0oM;$0@O!d!4#d?-YdcFD+D>+XpdJmxG(*M^-q~<|A9R zWCY97vZxRp^t5^4D6kvB3`df*sTgllX+|@wv=a$|W)kg0l7eQE{%fr|Y&vWLrjc6G zVVE?DX~nQ2oGFvO_<&>^1W;Q2>MX>91h&gh;YH9sNykvx&MAU?x8v-Zm-{MOws4iu zM#r>4a@GB+tD5cfk=1SJD~{uVHD=)ug9cSRv~GUMxAyE144VQb`vy+v5YO?C@!v4+ zYp`QHu(uvIuKE>QSUmo!`|XMA#)3y)O=IJDiC!vGYfriLu*vvqhUN4khcL)Fo!141tQ-|gBAst{ zOiy8a9{nPP0fD>M3=A*|HhMjk$CmIwag%iY;IohwEM9*B>IPfb@-V4TSAW&#LSdXu zti>vOo|uTp;MrWkCC(64CWUOj~cd%_ZK3D*;Hj!D~$o1~vD z|71RI`ki%{CpZ*s0XsaWs(tvUAd`^ewCx)nM z@`uow@Ho*#Wx*^VZbsDT|Wk|d687$6;3 z{nWw^o5376i{NqO%;Lg0oLKISFJa(8%dZZDK!$CDcFOjkANge6$@j;aZMU=+=*Sf(1f)zz$f=AHaoYrVf!GvAJ@$8{A5AZXEYT(>5JUGPPS$X z9?Ylb(_YQ*tfpJSSkpNC5Uq1y3`^k^cNHn4F6i%P*-6hAW2L2M&RvFgH*xB7?Rh?k z^v~Gyu%KKlA~zSMb9uAUI(V*1f2yy0-S4SoeI=^y?-eSfF7!!L{x)es_2nsXbMAwu2Nl;$l_xUY?^R~ie|_dL7`Oi3 zi#j!$7C)&|%Ruu?fYmlw?RpXWN(ar9tA8 z9tt`&-j9h-*qR3A!G(VZwV}X}4gz2ilntpP%`c};%|%^8bC+qI+N_S;ED)HZit5z# z$D03PrD3;~zVpUPV+;TsOc@wyrEz8ZOjtS-mba2Nn%s6HWRf>lI!h;|+e)9-T4@Po zrLQrf^i7^OYK`}$?EN79A1;l!Tcsx&$C z_F)d@67!D?5|O#p-A6+P#Yb0Icd*;w?nVZ82Qeo>K@dcdg6O0nyW6G*TJ!+Q)M+GW zisnWgMRW7HEHN+_;|ailMtr>1tzV2$Ga;XdJrzQNkeg2f5<*FQoJc@9gjWaxwj{2G zifzpVYz_x0$oLX3hr75C$oLY8fJP%ywh)BQON1_sP}FZB=$m%}oz0sGn3727DA=t} zQ(+PT71d;aMb)pL_NlbLva1rCfO&}eo zT?6qj={uMThz-b{I|?p?eq7Al&^$#+xTL#C?1gGp^FAOMAXF1s>dpz=&8rzP$StT^ zoemgtIFG?r0#hi|iC`On+i>brwi7rG6x#{?!~>v!2=2D_xYpWxlUuWpGWI(4jZ!OC zWitylX-3mknyBZE=U8>>4=7<77@%wqg`sc+i!$r^q+PF5TS4aY#!uTSTAW#=ahD1e z+ipahp3yG3rlX)XE*nZ2@kRIW@=|(vQGmPdYs_>97Ox9{{B?Xk4u@75fdK`ByhB&o z$>dFk@p>GtzQELI2ONa)c?LXuq%qBrH<zj~?@YkHGdZhEs! zBF$?2V&eDW63MlJ|M!~6VL%N021)0( zec%*5L>dj|gB4%RmwLrWV?oTivEgm2r3+)E%K+x|q}hLF{7g@;1%rY-F(2e2y&kq7 zYWXAvo-s zgGR+~_kh5OW92yr`ixa+Hs&+k^ulTzq)Xr;t46PB?y})3&5|)px*Y?PMZsm<^42EJ zIQsQueU)ZQMN0-O1`rAyRhq4nn1+mjXKY3=uzi->vg`&dQ_?*aTz4BV55I4)*D7WQ zo(iMjJp5>MaCVnNumcNb!5JME9TqIeJvNEi@Z(&kfM}@L52plG0B73{ONPt?uswP0 z*8VO#r-yk6;G|fZpGInyRBkDtxqq-DTdDYrH|IB=v> z9-9NwBa{H7b`GlH$=Q2?z`PA(;|58$jT27>!9T>TUM?8Eb=4CvcebYY=zxP0Et2UCh zYSlf`R?#vC*EV!$E!7EsAXhMNzd8y4a^pM6o2%S4vT*rvt5U~eg3k_&S97e=h)-!l-$0vR5=pN2kWJfpk zGZm;yPtUtpuqA8{e+Sc;I7m@Dx3hGN_v20w#>k=AT^O7a52wR>;G=LQ{0H2?+^G*< z{M$&UH!SiyhLMi_P31WpvR9|_kWTq&2xdM4;4iA{pw!6Fku}$RPEolt`019^#MLLh zXVI3&eHiS<&>0{FO8GkjaNhc|X{hTv%b<@K{uk1<=>K)q;uA{!g>>DQNOs4-H>6YF zV}?RZ23Lo4EZUaoa~NBhTmRKa-)XzktR1vr;s{wBX#JOt^>Cxn85XKaGMZKliLv;1UkJ!9LMixaU6%i zjV4AeanZK3%Wj+SiRDxSn%rn~3*gLZV$$434UYiP+=dR10F9h9{*>Jhr|gD<_NjTM zH|Oj4CgwM8+qiJu-`o~JgIlwX+qgPz^P<6x3oT&(#cj~yCKl83bzi(^y!%OON1EC` zn?{*|b;H!gs4E``a5}#@nJ?n--)8kTzzhj`O^iq z1<$`9WPkeps=!!`h+Ta1y}$#HWZUN+ultrSte>+fL{tJgTtORb%>FcXFUn6K5 z%7IK`@^xxoh0fE@9=*Pu2N{$wb~ITnvR^)3f5mdA1&$FAQ{`zOVK8@_J(n|{n&lYT zXFx##r|_M=PGT^SkZh}$H^@d5`q)6ibz7j9DO|QX_xexUvlp$#MnarI=vuwmf0fmbK@csgyYoKC2Zyx7x_Wm1NGf^$wfzqCVfzY(dH_f&YWG#W z72f#%o2=4ye||zUa34(*z}SBXV0QJNAZQFt00BAz(5`O=efx(2AhF}bh&z}50sw9I zfyAlJplUgo{Y_TQI=Y9ge=lD*B&VBnl{KY_^tnm)zSYvFH-r9gNFR22r9mk~WNC4s zR21jK7rh*y1A|V@hO{2s)hyxW2mt6a?(Fh$V$6=J0---o)rq@TM>q7W_gm@BSb84! z_qF{0-VO8L>gI-^7HDSz*umI?8Z}}e!J9OJD8{1^bwf^={ui)V| zcj+~-~MY)S7(=fXIIrTs&$ZgxU-AHf+xf6z2iE&UQyBa!B_ey=F^ZI0`7EnU1)74 zKrX%abY}M+@?|8_e&YBj&;xQp7=F+*c{3gGfYcS=y$?)1Jtqv+IX6lyV?3E|Ez$(x=pgT2~r0Fq7l)AVQ= zCZ18xKX=nPa6TLYfXBAP~8?*I~=s*9Qq^nVhDK!bS4}QS_(x(e!8foL~(qPA8leZ+D){HnPx%wQ3jdcOpH~4 zr9KZsKp@{}Df0X?1yM}E+6ore%OPV!UJ?ZL>p`G_bhg_IuUkt%# zz-t~R{!-!_@e|JADFYhR4vlSw3?!XgpJ3_jY;kNE8jC*v ztTRsnz6l)~bK3gnvdrJ{mipify&F6Ou)s^-qFdX<%ZE*UjWJ(Z6D-yMD?{;EaR7}2 zF9(V%ZIcDyCA8wLR+nbp^gKYOFTT$M)}z_F98>N~0w|SytK|TjqCefZi{3kL(mKC( zS%0y|eaq8vf+4$R$bE*y@U=?}i2E^69+c_V?wXjo_%2(Y*TkF5Xx5FW-lzY3-FMdF z2JekWFf`$H-)Y{2`<;E%mMbfaMWVa_sxo?qP^TA3hUblL^gdbi%6c zX4Gj_CmQsHn*!Y%)eJEb6Ra0_2~4SOqc^@*4^j5Lp|D71;xE>bks&X!SNl=3N3l_0 zc{E-WuTS+lwZumGLmQ)MhZHNJ-4Dl#t1t+oxIpckDQM!|;H_%pYa^j1-gOtq@C8q# zU1_+X)r_6+j;D=eIBdvfzT>gwM*TdeggG0S_WeAs1lqS$b6O2e$D2|UyKgFiU4H{r z3C1D!?%hlIvMpX?>h+`fnK`X{x9mm>lZd%%aEp))&5R_ofi4NxuUa&6{f~j0R!9tL zaqFOr;FBquPw~y4;$LP3xmo_{X6QvauYB)(BxutLW#mkd@{XCcBbd2SVi=+Z5nxrY z^PP=|B0GfTs|Zst7$+r$tx17#DT!L=sI`60v8jt43vDFEG1;5;E3$%of*5)d)7GTW zMSac@9nJ}R10(vJr;JKn2{zZ~=(j3*6yIfpxHm%_iCIkcXyu}>IXi+4*5!m~oj3my zJa~ME;cq$Nw4h55pUO{o?_3skF3sq-oF$1Tl-mNQG(*M`I3~MbcC~1EL6^&#cGt8} z&oj-CiG&}My&x_n+MvUEO=JEV()m^@_vA7g`ysOneA*Z`&SmSHK9r8i;13zlT#-_e z%%}8sY!o!fp|KejK_&4F_hTVPL&}1WGD6CjA!V#%A!RX#&hzy`%Jf6ZI445N3_{8b zL&}Uo%8cnPO!O^kN}loOTx>f0%q;u`z3AtG%--;J0iV>39v7Tlj|vFguM9$7FPAVf z^vACbonI|_=dxMxj425UgSUNfv2AoL}KRMUjy=jG=`8IwzzcrSSGcoR02cXnmJ zGiiw0!M6V+Xvp09>|6zh#eg#QpKTr7$+2p2F}Jpr)_(l8xLRYQ8%!R-&OD8{=Tvh* zgRK;|cys5qymA0>2T0vx-$@Oe#wk)?&BsvC0A@B$i5mGx6FRBE$}X;ELQ z1QYZ}_pf&726Ao8i?$4l?hnpZ!ktHvuXAvS>C$G$#6{p8TcT^|OV@ znTeO`?(Ds7a@~aq7VWgY7AG~^X+6*M1lwM?oG&K*3dVt^Lxxtfs;{@%j!B+X+YvaD zJ83yz*~({6IBWCJ<)KU9Hk(!PtKuJfUpQ?KFX!uRoG@9Ga_BBoXdRO@V-n9hVDe+% z8Izm??2+o$hPZ7tk!HTjsqvrCst-2IZgiLUfKQmq0xyfU`?EjnySV_kH3LuJGW5GC zyzKK+}dy9R+OdD3Yrc<=L}*Z29CIkF|| z>TFL_WvjlbV`YL9qMaj8e;)J4cA3C$se$0*I{v%EGC|^q%8h%&IG1Grcs!6zzQ<@d z$7Ej8V_ed^5ZsI5m+B60NEi#wcHy+`{G}d%ZFui5_{q&I`)&r!W)z4#3nII~mXYbq ztV%hQDqa9hEbc{y2~*<;o0Yk@A@G zlJc&yMG3l;43)XcPBl#xP+IPHm+2jGT>JBqEvlWWUyE-XK3tUM!Gs#K+|#zDWid~r zWwFw-*lAgMX<7PogOiqJkd|ebmSyCamSvolWis0X^6~6W2iW<@qOWNQL?*G9I8Iz9 zz&%1kXbGm;LOoGET|G|?GH{tXRb8kqRsW{GqkgLX@?L$V@wY4P2kuEzxC0|KlN#Rp z&D1Q^%(=1w?J8;LNPN3d<4DuO#eP2taZ$76Lci}LO-BpJsklm*lXm1ZGJsr0#*zRb zc9EIli)4-J3E5;w%?BKgIW>4Ys?WG3nSzkdx4?6%yO$FR!Fg~6R@K*}0YR|w(;mO_ zM;Wl_aicM{5X5M>$Y|uE5JiHJl}Hi-)~bI&P9j&3Z{-1OAs8Wa5Y7-T5Msi3;WKKF z5FB-^>9{7W7cS?fx%3M4JU_aDDMf)cVB!*L4d%M=Wr%nguy(stJqexVeyMsc+61ph z!M93^3urCcguX?;puj{d5W9*`$rg)Oi?@ht)m^`e@2jqhpIkT_c`lroY}tv5@>)d4 zd5hkPei-j?RslkPuzT8-7eXZtXH*+|(W2?b8NexEW`<}X_+ zi;>~70vWg?tB?uAk7b>*uQC|ltO9Ph?#x+(|A^<}O8guSbkU~^K10P=g;3$803nJf z#m4Q>`R$5*3SA^-JV-ZbW3pbhr9shLQ-Q$ zYEr|7uIt6G1X~JQrCTHOl*P(&XoWr^@T$;U3|3gr)wHA^`j#(lUQ#TMyw%fb6e2kfR!qGvx|tV1&6buUTYL}L{mmo zTQ|YF4-EFqQVP{x>JW95dZRj94SrReR@HZ&+_P>5BbS^8O=t6gp_boZ~ue7Fa;$sisu+s1&3(b)J+`;1StD zekP46gmR&Ls0AwEtKLlIPzNa$RZTsl+9>dm;=-e0OTJ0l40r+jthsCYp#*MBaEAW- zIFBT1L!d)!*$ROeLn2l$p41fRwK$ONIpO(K3+H0y=;{-26$^~M`3Kw#lQ4wv5nE&` z0{oGsNDP7_1xN`}f!spCW26)LiukLng>FJ$VS7GxyR&cDoKd2rD=Sow*3rIKwB>uH zy1j=Fi4rG%>d|Hj_Xi?t=T^p?EY7Hsd+?L0pAb;}7vRJYNX7iqQ%u1*!;AtW+c^wkd|fit^kuX_*J$ zy6BW*>w!=GjfyvlkQf6c7;{i4^-#`HE>W&i{-jhW!6D^&B19Bt{& zAHla|@-10>%TPAoQjc$`&$r~z4FkTVA>Y!7Z)wc8WScZpK!09L=V$r!Smv35ed1GM zU7f}Yaj#epv%-KQHWOQjNiaEP0T*G%u#`*KU91J`!Wc4h*(>QIbXb5se#!Qhf%t^v z#+9-pS<|e&vg0uqJi&F@pR(7o0hs|l2A_h9a1e~I!p&4?#QTyjpjYrw8qkV|qin^B zZTZif72Y{}(+&JcNL9}qZxir7F!yOD$Zw2S>{RXyd#Gqrd{l6iz)Y6<&`p^x3sa7a z-J+Z+1HUTIDz7V(RIil-N(0px6_}zDse)CjR6pR`Rr^$@RN$)Wf$D{-SEWZ-5st*9 zYe2qa9uYXYC-pLp7EQCiwJF2b6TI^}QIK_Ti$}1FZK`YPqUH~CLPAA< z#57p%2|#HSG!luL(myz#{=GHr1v>6XrCn+LJTx$2sYRL1xU!Uaf=8mE5qE8pPUK6H z%4}04EJ=yf>tN=lw}Vm5JD#TeGT%TX`g%L2;dhC%m609>iy+`&e?4w{(z6ZD*N#FU z#WqE>CEM*Gbm=gpOAuu?ai#$;yGr;MDHYRHf<$axLYzD3RP3pxvdUdW< z>VW9$vee_dG6fKHpnAmXcfM)Wlix*oABO~y=L23gUQ8(O2xc^1bV_?=%}e$WR>cj7 zI1I-2V*Xw9uP|#tX(cJ4!@j*3Bk!HDGH_b#ly+`on zwLRt8^pYj74b_v^>dR|6@>&DBVJNRPlGhr`YfW;!ia+vu>Fq4W_ttWAeVLq{e)98q zu5M!*KWn331bcjqPI@`6tE&r)WH?rj%WC%*6q2PMO!f?r41<9o%(hrF(ZG>XYZg+V zM^iT8Mni>gFZGzZOx>fvDpE@^;UaP(tgFLc4g(pS3hPSQe}nJ9PvQ5lB>A(gt!=7L zaOgwV&?nu|d(bh{ug{xkY#e6YCy5pZb1Eh=`27D+N;tJc_^He0j< zbp=Av$&!)LqQb}hsadIy8)G9pc5PuV{dP(_G|Lonv9LjIkn*=B zKKmI7$lOdMzSG}$+3#`&+rJ%heAODswB6DKL?H}+J)e^CGaT|BXkL(ACLaYVO-yYtW;hGz9>Ry zg$g3QmZq&qKbN{DbLOLjT;KXDzf`tn$lVFKlA=Ja7mw!@KQE{euiCdJ^XpGwz&b82 zJi<0JE6p`CJQ7V6Y)^_;EYJ2)9LilYe^FMd;Dz>tyCT!$PTNnrul~#i-Ips^rLH%< zbeGfYl5FCu+-tj&tgAx8!^KSjIf zV^zJIgnQGg)^yEvGyCPQUbsta4Ou}kw@rsyH%(lz;~Xa%lHW8f3@vlf?zuAk=Jdp@ z)bOb6;uWC~lpmi1cIZtrU+Uyh>y(xQLRY_EVPCrS{G0+#fsZnDH{cXVlrge@;ln_S zlE#N)i%%~;*+8we5Q(PjzbB>6FJaOgZkeOF8F{WtSZZ55I^lVf@Tm7G>0w5aYlv1Xnsx|A=-U}34S~Ip}M=YT5eCgDXGQ* zVI6nIw)+sA^%-ZHC>9WAoz)CZ!Rm6xit^0zRq3K+BA+-+Tp((%ghxSPQYHk|XJKgr z#J9?LAW{e4GmVhmNlV>O6I;}lR=k6LsZ0BnUh2gb>7R%#;=~pi#1T}4=0hS9^WB5qn{Y`Wt^t1>rWRpz4!)kJGHYjQLPH7X6L);!c0lJ`_xQmb+z zQ4$1^*O4SLgoq+el2^#R1ZX9DNH#Tsa-e2V3n+{N@l-mshdN4CQh!j*6iERH=EJt| zR9JWKUkrQ(1_f}OCQWk-ehhcQQxF&dx?6; zrGS?(#A!;>NY6xJmQaG85P~YVCSWGIa8_ET6y1cTaMM!vq2LsH z6@7rdKzmU=v6a|S3}%WKiX~#XI73_{J|?~-26x3R;w~`*Gsos))35*xEW={46l@oE z1iOgc#-3nbMo6zji9}}Evu$b$es^AFBwN;J9Vhw@Ik@oX!%FAXHzQCP2wHVBVwr3W znj+gJJ0iO%>$)v_B6}wrTK(?R*6$xG)dPZk8;ZXQ=1$pc)rHkA^1`*! z*5Itdz_rqQ!Tacj-dd^tT4^X}t<+$x)NrlTXswiOyjE&b?b2KLPP#OhQ{w$j$~_jk zHpH&Pe1n_$27s!9R4Y|Us%@%YR3}weR6woLC+^^E;yvy_%pevJ;3^qUh!qivqeLZ9 zsAwhtNkD48+EzVP?XO;{j!^?#U7#*eSEz5PAFDgnU)2ECSZmxgzM3%28qEn!t_G}E zC97&Q4Vre1BWXy!QGr3#B~=I+MV=*V6#L0I0;CajyZDj>%+h>2+L+gErVzXUO#9JVpmE%qixdYWtdG7y$scpdg@C(IZ{spx?w2w zG?IE6OFc~nt&6)>zVU3gVI{orAH^&2KX9hv zrWjIy4zaCbs={A!iHK3m!4@imwV-X{`iqN?&D|a*gswWv)`GJf{RT z$_8b-@{`g~HC825d8t5%DoRzR%2ut$x8Q`TP6b}7>z7KdXUp-D0Kj8F!6e^Puet zO`Ha7IzDKL1nU;7L(pB^bwd&~JvO!c|~C)C?_SgJp2!?7f4REx+(z4!g$S?m4>&(mvFb$7aUCA)X>Np>o!D!_W# z5PtAa7#0u^02vF*vFw1JlE$bjnR~o>U1}eu`_^?2Yn1>XMArHpN{V<-0!a%O>I_Ch5k-ZR!Q z>;kb8TAua}z{BrRf2YRd+Ys6aDNQq(kclQ9H{nr3CD|Na)?ibl;7|w4MyNI1GY!G| zm=tNL%89CR-MS%5yB_LNU^U3uJ;?bj$QkFao~)^fs;P;hsfng3cpAj{R-2lubqgRb zTDC%mj#hZ7Sw)vt!KVWcr6_t><8rp}HQxkKjZa1n*j#?Su7|N7#4|=zM19DNAb$_U zbFGTzu5B8U!iE9moN=p4yAo9?yLEH-fkl6&LQnVD!VVTy)h1_$b&mNqxH=}Fi@cXu zI}4vjbMA-Q=|g`pZV?OJ5JG17Xh->&JQ&~vmBrcx{~CY%Iy1;|4MI&(?LoGRz4oOs$uDRWD&@)h$K` zrsaaXg895Xy}Hjy8zNF`-Lbybed=9EY^88DzKN;xO9AENDv(nCE)`SKHg(bY`a)Mg znb%>-g4F#6$ZJ&u4t12nZgQ#$e-DQ8A8aZ{6&8kG0DTM-(TpfNsE;6e=5h#`$u-?U zoqfJ|)#^Jqn0V?onVM*GLF3wgmBDj-k1t6j<7(}HiAc+N4|2JcNa7#sWMRB+>ohu4 z3-F%aTF`-XPN`>Wqf{9eOkx;YG;P^UWz=$$P|ICVX;FTbg_jE`aIfbS#VsoK(o1*m zGArJvZPBKhyV{I*(q;&E{SzNU1hw#HY0(VM73gHx+3Zu5TGMQ0oP|6BWyFVb_tN)q z6Hue3I)0@W(~x#y)f~!#;z<*%?Vkr^;+H@qR4c$g!GVLA2;CEe$UH@G^pOCAVZ=ZA zS|{!R_uZU()WMW~A90H;gl!Vqh4LmudlH|y=+lX7bI<9Ky(gfV(n$T;NFA_grWS0b z7ByENIai;)gTCKbS!|{@`Ewm0W4Qhm{fvtKwnG-pHn2khhxjK#CEO)ECUiQ&CftQ_ zuMLwXOX@F2E2RxbFBz>gEmDeZ3Meg=rgJNXXysJfhOJ!t4Y6_jGl}(RO0PJh$eou# z&WNm7q+yd`3rMus97zi?cH!IH(j1<=2DELWbTXJ&K_NDEvjn`DPXwruWj2Z-jiIu= z!7D^s2+W7kSAJ3bWIb>_aDGL72qSq4OG*yfV}cA)lt%tU4q*sgLDH+vs1Ne+s86!V zh{J&_Ia?@8%q3=p8VeY-zRJK=C=bs2gaE-A@!p^cHClCNDmJGfk7#8j>7xcRB-rMj z4<-&D6w$QBhZC;u`{@Vg-&rbXz*iiP%tKZ`dR>Sa?Z=XF&pSC;-0epZa9 zrz@=dzXDdspTM2DphH%eSu=2n007{UzUAgGk4s4PEHib(7S-Ep#WQjpZ@> zWd7RfCh3c-4!eKE%cM(GcOb#o(IZ6jM_qm7}NO`uM?>KeAj8e3DN%}`6DO?Fzt&ATCrRzOa!n@fS4 z6EeTkRW`Z)w(eGV)|J$Q=5Xati~yQ1-H+9m^V=Kp>?k%RQB+`*e$*UFUX_z+g%MP1 zf%eUC1E{Tw37pn4U6hZ=WXw%QFq6nJdU*j|5uu^GNFgsmXEOdGAzz=uHm)P%>~{wwKKrF^M$wL17oB9g68Bya)|tQ1t=ffNzcPZNhS=aW#CmF`8{Q5<6;1-~$j z*4;3<@+&~oxN4<%jZ-pKldQU}Iy!}~OOq_@_hCAhsyIX3a`s0%ZM4Amg#v0lI;yJR zn;LeH@3^5Jc*5PDa*}Ue{scRX3ZDlvACzQng0 zb|s}${mCOryFNISb7e@gLAyATdm%{Mo)Wp%83pT4*p!yMC7;PioybV7B$Lt}NgzF^ z5oN`mXEjn{w0SN!>})mE)~wGaN?R6+t8`&Vb7636j3PMXXIzoKReLj;*q2tmbYSE> zve95L7Fai$R|m^zzPGv6Zaw{j>vNnvnE?P}*R2caGFgKvBfHgdLT*m9mMhu18hUN^ zacE>R`+F85E(BsJj8!~2ymA3ts4O4hQ4ldPB0VB#&s$&Pmi^Z87N^d(&NYCY-&4R- zY~v|~26&Q}MPPX<4%~j4Z@YnE><|_&S*35B3N!sA6!6ERB2qvHQh!Ih$jcykO`(`} zn4Pwm!U5|zm6`WIXW`93El02*^5gui&c3Gh&IC^|_g6^2^A&?;b^_Cx-&!54#U${j zSb)^JXzQQ+1Zy4ZO{ldBmP;zR&Nh0J#w3RunDak5n=q{$xkkT-ZHoOvmS@Z;6hx%& ze?keK&-T?6`BXmM$KpZVaGAo-Y_ZsQZZs>kkCA;MblzW0-1NUualX4Sp27__4_jtL zXX4C>)#vL-8)kmh1koUSu-Y6xQ7~B`&Clk$Ma1M4o!<5Ru6?G&P~~iMi}=cps)EmW z`CQmzy7npBYJOmDKEt+MAU;!`sx13H-ad7ng0X1O9S-fdMSq>;n)I)E=NRXlurze) zI0<&z@TQ_8qx+VI&Ue8Yyriq8yyPM>{&8jY2O4~}??IXsZhjlza6QRnAAtcD(=Njj zXRjHy-YWQ;EQGM1bY-X)3>e4)8{E(78&NmdFB%wZHGSX5p)YhjM(*huU+>UpU-vKw zh788B4%^TI&624jN@aufxiiH}Di~TSf?CQbV?*N-l7(f;X2P*Tl z{XzI?a3_XuU0<&W#=XUc%fIWL6b_%H0IuZPKn>pste**7{+5;pg){Wi(I`n$q0Xxh zrtYV(QWjT*o0aHq_0u^HD*Zt<@Y4yTEKUeNt{aJ|k2a0_FLLS;7xdc7hTb{MC>x$jv7<95 z*1g-8qYXu#Pd9&IDZHa^$BU``t*Y0n4_@w1nW!TO!y&X_pR=sbAyd6!>yKG4*KkrR z*teTMzv(`GAl-XF{BqR9yj?>+ftHK>C;fr_Gs*b2+$@*Vx6K}q{o+cqPJj`)@8uZg z5kM?-1$*E-dhinkY(sh&jVZ~Cc3|gKhaf+Oj2p)6opZITRSjjwkUiAzUWS6-z&;qb zKdZUpA=JFM(NhWqdTKaqfk>rrPvi-Mn;&1bYH&7w{|1?eiaj`|Ut)6$xh; z8#h>ibb_>u|IGKA3j|)snqt%zN_wZ7N{=Xr$jpe_o>QztqqH132kBr%z_`lrztHE< z(eK>Tyu7)8jP1n=zM@Itur85gu%J02e8`oiXduvD>%HVcSm|2(rA{+}@NB8#CE-o| zdX5@&w+H1sR2^zXh8=h7^Cl1QK<3#^$tD6$9!3UwK)4fDee5=uuD1tD#>v=$>i0_$ zAeS6YyelzoxCD6?SLNN%&*A0bDF9W|{HEtadr<~ZQ6(XQhJNs!tv9Su;T$6mM;j+ft@I&li@`%fggWWYy{WpmMQwXY`3Hn}FHB_-fKhbG_`k`r_wHarq%ys)!)bf7=3#;U-XB+?k^82y^jj0nP_3e-_T z%@eMLQFcT?!^(b~MhzQK_zndRsRP8PmU7P5A?T?ldUkUTIs!p*jQ6%A@+VO(3uT_D zl~YjHCIua;#GHWD(_cAzECQOTE0e4a&$UOUO)4c2XpQ$p`@v}!O`!WK5p&ctOUSsE zQ&5dij&lZ=;KDcQbGEn{tKyEIL7*AdjGh+3jHg3U{)KS-@gNm3OkWDO>&hga1|Yv= zFNJCWcuqeDBp?g?Av#|)Y<&=-!V0=cj;PcOrdGr-SAJQgcc#`j7_jImp_?OER*#Bg zup40>_?LQMD72cyDslyFJO~K&7m(`P!}tvqj|PH-ZlZ>7)y(ghYf*Q&a4py{Gx3B#zNi6PTiXP5+E?!+XF5cXk(}0nTyemT>4`i2+1IPTyp`26vJp7MvMAdP*VO^ z(f|j6*kiXM(QNi2N_OGKq`kZco|=PZVVU3~n2LjSFk=4EQy}KB$A-2@p3#|vN;qr> zmK8&7*oh$GCYOnVaq~mM83i$!vm=DV;wr_zr2GeIA7;|W9Dx#c44YK7fa7=6Skmy1 zNO}QOE;rhV{+x+3H^j+n3T5z=G~7 zdg-(&PdMf(Gr{a9Hh%*`yrI(weknTCs3MjJ?uyxW^br;GRsCX&! z5jd7qVmSO)%HYhpel?ZK2c}|02tw*;GJ##Ny?y8}YQcTPI@{P8q?UbWh~Mj?vA7|x zA&CrV8>DTkl6KJ5g~a%nqbGtVArtWI#Zw);Ab4@!gkfJ!;{KxDv4KWe@dR^p#0b?(}wT;8@uln`#dPm~DiyEn9rh`HG)E(ai+27Bfc*;j|zt6;fJF4Pp&0FpX(Z3FsAIT-f#jq3{I186pv)|CnEnD{j+m*CG`z%Y9lpNpWQXr$#4WJB3pm16K~ZvR%4M z{f@55aPHi|+wi47cqkWN#W&Kg7@WgrthVdG))Esn%Aa-MxfbCW5Qi&H*cb6o9a9To z1ah%T116te)Y2g3e3Lw9STwxKkF;S)b7JGQ>c~%*9Otv{xiV+0sGCsPY#O(WVDxEC z5Ckp1TZ@A#-anxn6j$Vl;or7f3)LFrdKqQ^YaKs!L5LAu5j?~?V2i_J?>m+$lx9;t zdJ!fQ#Ik5uoj);a&S>2`yrap2c^!9pV~T@|EGNC}R??&E$ub~Y{OxL$hTp{v3b$yu zls9o<&bUS1P$?daP)9z{bsC2Ss8uJXOv(y$MZjkYgMw~Q%6Z^7j|DixnF_=c*avgM z1Y++pk^t_I``Qe;2DcS(Rw2uBF2n^`<%XUcVuYY|4W`)d0nlk9MCJj^BO4p*al8Rk zub8Ewb|U>uWj0`iI*Gi{8o5-eOeIrrj2oasCSSl=3Ey3G{j(chSwlpkhv>H+1B=-G zXlY9+QFlH@LTjLu4C4#a&fdeU!|1w|H4_BootS4fWD8I{PI#FV$ndg+@=M8e8eAK) zPS@V!WIXEEYIFD68d@ASK$Du*yKyY>)-axs{cvGQO`lhTkhm+l#EU``5^u&`ZfMLH z7nXRx?%F&M*@c0G;Lg2?B*akb?I6>IpA#5%i8B5hO|L(N6m+}Q+dV-Niz9?750dLhl9q>IQBE3nM z2Q@+zp8k)~2Y`1yoMT%1OuI_fxP62<@-a${=jfZc?MQpZ=9$;va+61j9p~Zee;d{(-}q6Q}vNX z24po=jh&gT=7`aT-XKXRtQF`R%hK>RE+X7)R@mdnP#zcyi!s)A5HM30Scwg(ynt}C z8g5WMOOsS#Fz=HxYP*DtKo>R3xpktJ+<9`;236~N^9(WUhU}AuoWu;AP2)YI`k}&h z%$QGdRCNvjNuRl9VVy>uPkBQ7p9Sfn=Zt{?q0Ty0qZ}}eb&q#94Rt;KiP;u>wCAde zt1NGNY$#LsGwZJ!>pB4Ot}-S}01!||fcgTwN-2}U%Q+9h`1v@Sg&S7v%VmaQ*%nf@ zn>3wH!LhfkeuB1$I2#tsa(crIpWk@55WXF& zC?{8EG@e{rTZ`#bh)Sir(dO{S1*|3w3#XyJzJ6y%w@uUgU?eW`@62k0$#Rv(@%g#O z{t)cuYKOGB?S%8iN}cPi{-!-0p%5)O`N@yWUtt|=7Ix#=+1dA}%Xyk-BuZ-P#)bwe zI=W?=x3v?R9%?EoDl)R;r^|IvP|y@wt-qeHj6e==52qg=o=xhX`cTTs%Gcb+57=nE04OXde2$A^^n+=Ae^Nud}$yrz)2T{Iy zE3Y1;^_#ukpYVM?>^|QfWAJ$Lm!Kyxn#C6=8_i3tLg4X5z7{J~mMhf~Qd2|sIWAGQ zlqPIFg9G50-%LB5ueYL{&nMED*umt=6fsoWoi8Ud*lM)e(Ryb$+g;+q3Sfj1z0esn zT5SpUP*71(F)_nHxPpR%i7ds$#7fQtx&O2b$;rX) zB3?2NkO;MGTUyGq>mjSLgo5UtAP-Nnf_lM%Ux(u<=iUc=21BiO`;O3)sSGAlIEwt6 znB8FJ2op0k4-XHSuZzJoE!pKY63uTtjb`(VOiWHDI@=2bsk^GoroHJ>WuT89UJZ{Z zl$!m|C9wW#j*br<_(-fdw3XXbtcQqi=O>Y;wEUg&f_khz!hOk1L66>QYHEvk4R?2U z_1*kR@M|ooNy*99tM$SqhhA}ApHJ%-7Z)nYNxGyOakZC{dYw8=!xzUnKF+qbwQtzW zc6&nRyc`pFeBKxP`@d4g=jZ30x-+Y!Ppo9p7(qj1Ysl&J(dvlw-dFqFyDQB@R)e6? zYyDSHPZK>s4-XD>rR4b8CuT%y)SJXzDpL@M*!Gi}Q+1me_5P^;lhuIb*T*Y39L@|y zal%P}92}G6-F3&Z>&=c|d;2?8b{3Iw92K&2G3wI0lEefM5Rh~hXOV&=S(QeM_2F0& zj`0KLCrPyJO<43;o?wV9svHy#n&H;cOcs|*Y)pXI0%c;MpSoT%rQUK|zI*o;x$*gO zjZVGc=-yxiV*JR+NN6a;!{dycw4|hvx1}ZZo!rsMY{3awe$RY~45GRaBA-Qo+Cq8Y z=5fT?r+Y!F-nyf+^H0-Zd~;thWV2lHT|q%Z({6W$z4Q%%VE6gr z{(N|T9v)Jble_ij5xg7>4t@sM74ZnxK^)0ov(d+Jf>wAtEy+1aggVd#g5WWhm+%Nq zy_BHKU$%U$#^3vi2mi}-7C?I>MWhDX@Ur96@apZ?>I<@cET7eq%RjG6Z=hW0MCrY` z&EZ)34dm+Oc3%yL&~-(+Hoa6#PEKxgbabRwC&1soHrmY0%!FNF0>NVeqB)oszzTy^ zOi{%$0|WlHr^Xc;k+9J!Iy#!m`JxAe-U?=;-R1gbw?7p_UlV%*t$GzdNABayVz_Jr z6*7&EkqxJlAJ~=W`P|2H8j3}6u*}?GZQ}SOs2Ot{k#gn-6%lDbvZP}LHw6N3qzT?q z>A?^bQ3~c|SI!Jz6MHp6yUk@}dLImyE@Vc?tDm76xLj`twv-ehIzmz@(n%V7O~Y$} z1wr#cU17Zd(m@(`rllfEdCa;?c*YRzyWX$bDFOXg*FN8wBF;YrCgkPiZ?@#e8-KuE z2oCz@W>-)MQHq16=VG-XPDgO|T$H_dFb^~Yv;6ttbpHI1ho*UtN~JotJddYz42t31 z{qn1D`(KJ?QfHQgJlsBnfCWlu6;XEv!jMf5XCps`6VOUmpB^3-UZkm?-LZN8G|JF< z;A{K}3JlEsd*&(guFg=iY4| zgIV;`_|Dx=WSQh@LVxh-Y4Y#qD7wViv$&+m4+NQK^1Z2-@zeMBPHx!vaJ!Zjde^Yr zn$#|yOm%hrlYX?n%fdr#f4cU<^yozM;{ExVEO7@<9@mXNl8frGME{+^%IGF?BK7Jp(t#` zL7#_8(zErJYd$aE;2)?q(AQT!%g@av$YO*>r`>2Uky$i|04omeyO_xnCQfG>{8ue4wkYtATZT5xmo6hjW=qO}Ta5_28rcSG^ zUzfaggYje-GFd4G-0N(wkhiijT9&QgGR(XhAqILsxo^$`&jwen$qK;F5F)H;7(f{- zPC`_)=jQG4{1i)fz+kyri(S6R<~>%Hot_>6u(+FMd;!?O%55T<00&QPU=Q_-dDqp7TjW?7e^8b2&3ro!{&#*5O$Ui^WEzk?cdPug$_r zSVt8#IoD&qFMlO0CEY@r?caBceA5B^9N*u-0J0LmASeJ}01!X-gaF*V@ZU`!007Z2 z004+TDK0klhI9@_j*e#5CJwZ&R+fz_>(=Y+2wpn6-@P;UoXLixYzs7=3JHDI5#+00 z#l&kz!9<|(_50LM+b*Kv&GYQSYr;8_lWEu?+)NMc@G&G-m$k8h4Rz?6uiDTJndpI5 zLtCF(b9k;aWe8LVhcGdnz{y)7&)wfo)_n1*6tW34w!H_X6T@4|W#$W~Bc2fw#5Jx# zn7$UY;)Od3mYgI=@J@?UZfb3a0;g5{O`?tzCDc6F*8FPRUNh-YGv|#Mwmk7g5mK z8jjOqGREZ%${~C_QCrr@mqAbZ7Nn3QPi2oO9Uj$*{AqIKB8_qn1#sTpwR$;;-V0X3 zr1EAhm)Fcv%)qFA7+i<42}MbBMK2g8W!>g(okEo>pcS|zsN4JEBG_bH*7DK%Z=7=Y z5ML?(GEP}?ECmX;K4fK2e=UR?Q>u@9Oiwz%3C9Dvo~(AkAmqs0@R>^=DS8KENRq{H z0JZ^GDqpQ`Y7DiSI$r<~iVmPP#NOxPspQ&kHtXY$u6}ZwLX8ce{g{vYerslp39Di( z9>QLtbWrrTWvf0hy2uQwN1U*}D}pN>fxT)zRY_XHPhkv^Q4+(M^XbnMB*u%^UPD{N zw2=AH!OD;bZRRX(fns{2_z1gVy#;K|MzP|~G8^+54&^SKQ@IbN)}&&&ibgahMPvWm zC2{!k=%tZ?{zUo^6O3Rm-am7k4!Z4DfNDhI$fgl+^jS^JSx(W*#!@PxmeStXuy%4# z4LkF*DcOvwo`G(1YL0ZWMyI=q{^aJ=kO5oDoNbj23u+7)4kidNIdoilXO5K9-i15q z8LSOLC8Pdo@4SoXIKRqB<8$kt8?B~!*mXHdLQ?xdOU z)=RDE=Jg6hq`@biPx?DIu#XCmam}A|sy!1&WKwgE>XSvt)MqC=Hd;boO3C)&`CeO> z9a>0JZ13;A1$HB>5{=N5-)uzNw%Tn#rKizqv?F>4mH^R)`Y$^Oha>Uy)xG9nu12x4 zBpjzz4>j69ZV39J*k>K3)wMltALQqtarj}Uc5Z>GK~k?pU;qll%wc6x9F#Q2q__CdnS%&bp39IbF8lZJa!)J`3S=HUZ5{)t7f_V6SOEZ`iAOzSa)XXN)vrqsv%P zG8yz@L9vAxs8AKxXWEvMb=2=~&6 zJ~i;+u^RunULUMbvqV2s)mf6_*^-&Xpl#NFOA!rIQF*L%$2MuPT8uh>n(s1?A6S89 zd(?N0ZT1XnG`cvB;GHVh6WuqPuo-SeoV|Fk>`qRJac|UF_jWmW zXU@8Ub1#a{u|6~YQYG7oB8f1yt4ajEDNq6RR0GV|GkAhQVZVhB$!|H5IH95XINk-; zh}XTyyI4Hw9y-S$gNy19=#1X`_G#GG#DBQiZfaL2g7eGz6SX{iKMqLh1lK zct`9%pmT~}vyAj>i0e;ArFiF(+`xN}0Kcd1=bkB z6HYWVZV^r@8%OQlbOe4DC|vS_otNO-G_8~xpj{wV4O0NPvtbZ5`OCykr!TA@f63CS z)RsErg%b@u)5{JFBL^X9&gx!51wTAwcl`I$LASfWP$)64tCkpNHYT92tUUC2MEiBX zb`gl!T&5(7&sM6R@6HGp>{42903o3X$H@Qz(`#Z5r{S^FBN>ycbc4UH*fKYhgG_aB zRg3M5F*iv!nHwDrlIvUtDVy7XZ=dPnxCv>@79_w}@45`?NA^w_q}amvF&O;GO1$;k zB>Yx9Dq2Cq^2Px$_HA^Fi8YER>&@P%nt`g$fiW0-kLU;nbKZoMHUdt*spq8h7Wfk@ z2M$S28aGGrVzk31dD8kp*1d9IChhn!s~bZtCv#;NY0K!ZI2T^am}c@<%Y!Od(zH&z zk1<$nftxASf;La%8^6_Gp{9jqf0W(! zpfGnFfyvO)*X8<8Tiu>N6SA6;=3sJT0S`ssQB2s}C3Z;JvuTf-kkU;d6$NT5yiV+3 z0^8m_q|5%491sTz>8Hd}TN+d_$_isR2W-nJSri*f)qfGt4K|nXD_rWjPxkFg-<+n$ zio?dYecs*fwYa{6Jip-oBeJ-I!~7nC0|01@0RZ?%;@_huM>k8Oe~q0svLqZ1nh|}k z%f@_kCn-2a(o?iGlC{(?Dceym)teh{8G;BIuvCc|2sx-mj};GN1>rb||D?ckkbHqk zdrMsmd=mjcOvRe}8wSLZJ{hS9*7C8w1LpQFhv07u=RIeWQtaQ}>OS<^?#!+n14h)u zfL~WnIm3Z#r^m4q5XPL|?qnAS#PGenPV;tnB^y5zO7Q@O&YQ&faH|@w-mP9)pV65L z&B4FK59QlUC4?I8nb>z?#~m0qZQQyw5@Tl6#Tq@g@9*0B`Ynpw6-@ z+_gi(g2oM>`qRw&JFf>hk0{wx|#4y%3R(f3waGx1fc!GQ**mG!xUH%Xc7xo#l}S2Zi}`^*U{~V z)y4QG#WQjmd|{mr`E5**B95Mkx$z?JrA|}MVGH!f%ND4%i=UyyJhdzfZl~JE>%E5q z=+L=JYz~Xl*cWbniMdk9H@fqBjYzSg z!3EvO>uxvCBLZ)QK)!BwPDE`w3K2a9{e6duaQ8u>PmZCnx+TnNSHDivptL)Ck1JF^ zcsMX9=z`5|?xsp4(xCELNau2Gihh$nYu8QoCcRukr8XN>efT4-;=2}vKos#pF(f0I zom!r!Re&E?KMCNP-YJ5o^Dg>5WuN_imvPDsDB+yhRlpV1!@K`Y4R@lI9eP9WyEepN z_$%E&l$CinR>CxzP-zB7kTjPg`1c%AKKWW1nAxofEBs#mD{-)*dEN$43e@*G-}g?B`iV4pR-OCJW;yT0U4| zpc1HJ)~@z51z`yZj=rNFtUL(M#jir2)-ec4g-`o#q~i=R)14gc+9dhSR~770+w-!D zZFrDCy$%qPrp@9oXmw$yfm3Dz204FWEL~<|2Nxn#W+(V9X-Auw(4v5ckElYWIfI;j zCnzOa=Nq7?g><DCYS8>9J)UbzER^FvSG7;L5_KgfL}%t@E+faG3!S z+4rkIN}K7CR#c!Gxn9%NUa1XFgV*H3F8h9GtKFXAXX{t>(Icgh^q^XU>*97UYI?8eg0Y=w_H&qY#Zc}W~xBTSpmelfPUQ+Ht)`M9-v!jvn< zod#CxFKuJUX@jcFJA=b`X^L+~bz0Fe#VSR9NBpx0=)EoM`U@`sbV9v4?C#EuFbHTK z7p71Z6`QF}s;)$%V&+Kf9fxcqZu_AHD!=ZR%qj0vkzQmukm2X(si%S2yIB7$M(_Yh z={>(+@u|l3sT`PssMpI6-a}$Yt$A9+%-!H51<|1?#Og;0aNunuZ-W}M-|VTd6k9f; zeFuMID+>SG15wdn7gwyJFI;agb{=LYB<0B{r>XlWDrk{h!Y%ux%l1Cz5Ru!2@A41T z1SC}LyyaMe9-kS?2*wvrxI!+bAD=lwXP@6+>U@~t!Mic)1YNugtKuTu@!<#Lj!`)M;z(fhVt zk)|dlj6DG^aF?6nh1h z&R#GZPe$D466lFJXR)X2$6TUC>`99+y<_K%+yY#vSpbJC-RzJ_Mdl-IGNqV6o#M`+ zib$e2(pJ#aH0fJFT=87p6jnA&?_Obxh?GO?iZL@_D{ZVMN2fy@R+Dntd)OsCo_&1b z9_N-4@o4UY*}!L+L=E*6uKEsmZrP>7?Iut56bxpGiW=S*Lh(el8Kfkn5?FHCmysqU zY+qAA%zfnDeqfxe8OMD>4jJRNA}4=nCR|T}uN`|(%!&Y)zGtGfkLiD%OA)@**A!v} zRoG;x1%bybEJvc$fxMlf0-fvf_b^heOXDu}kU`C`Sa)tz@-$P$SV+O&OJtjgquzj1 z%BkaV6FGNVCE-Mx=eUF_yJlU5mfgvx^t>sReUReOoFm~1y_&K!ay2@u9h)iNq1!;j z@yd51RGKGF4rh@hjUwxv^e36jNF>*Tik)c3or*l>yehXt$_A8zwNoiZ%@=dljZ;@7 z7a5gkCTz{1_~#M{HB^Iyvhd$YP>3f&LCEx)`2ueLP=-(t%0J|oF95f9ou#MSBueB#)6$ zB)3T@jn)65|0&J?WU81CWLNP&-yxrZ_mM<=-s3WL_ip=@i;i6T$@+ z1%MpqBoGVA`QlhQ34bD+HI!2$G5YgN*2k`&GmLZwr&dzRpcI8ZJ5Zn0rlgpwA%e|W zmBil6fRvY`7=n6hnF%eV05IF*Fi9_ujPn$H(KF|onU9wb1p#xAL71&BDRU6XgVHQ+ z|G>!^GgDs0^F&~^H8Zm87qk9NG)ut@9&5pcChR=Sx%s;g3vz9BFbI_jaAao%;n>R(_=xtekT-m=fdKVyv$d3$gBxV&!Tu3=b8-#HI?u^3g?e z)S^A}#1M(SRxwpE1U7;c5W6e~v6*~zN-+&(2@-#!CJ-;B7aSFuq%31n$H(lnnZ+n$ zps^egn5{Zvl(l~2#HCx5=| zetD6|e=(AVe}DX6I{w8x;6_A#-p0>$!4HdHU2HWkoBBW4=!v;z)53oT;* zgE9V75|)3nHCdX=EoI&w;?=WvL;d3mZ?QwJRtfkCkXJ6zN8#U1`{z5ZzZcjN3z4$F ztP{T+wUM!z(bMo(1_MVbzTO8F{jbgg-Mz#Vpj6^)hj;6rH!gs z@eSoe(&G}razx+Dl=G#=_cHY7MX8$VG-mUE6?j^UQHC$>83yl1=6oEFQtrE>TiG#Ao7Qhhe7e`p17im}W*@G*e%G^LDU zZ=(qY^{ik3{mrp}_q&zh09lw?hX%A-lLE2S*GC3?WnG6z#rXAm8+ry0Fd@et1SO#7 zTLL8Vu~z4mK5uOa5AaJM(6?s0%LJ=Dn1BF=Zi)3pQ^Un!U$RT*kTgwGBOo~qCpUvR za9{cG(W_W>p?9S?Rn`FQNE^+kBig8O>#PRr2nx)F6H@4%0=A!xcsqk`vV9C;T;q@6 zqj3`WWy1$ap2(}vBx#iIW;x^Q^pWleA9lWt17jLiH2h!&gok>YLF`+FVyduIC*B#W zzu()ZiqFgLd3Si*v&;9(xX;&D%iC8)sztI11I=ej+w_~=H00lOcT46+3=4Cfsu#r6 zwbPaL#X01HA~IEp^WFDhQ!^6-&440do5>Gcovs3kDQD4m2EIZr%r-DM`s>vLs025B ziTl_I)7Ja!+4X2LStMHzyvKV#1=&m^FePJ_SRbR_u}DPvx`_vmj8MuUQ4MBH)cFX=fmPvoW= zhhK6rnxs4=pCX3UBt0ab;hNkeJuakT)R{MPqScvsQX@5(d2rBMyxA}+g%#pB!L3Aa z@o<|?II(bHH4<^7;3Hbut{6GUtto#_o7+@FpG4~30;`)&IActTV*!ERyXV{A&lx^m z--|8VUhiZV9l}n(T04Bs$|mMhyYx*}?jSp6uSHh8fQ1gRhA`h&B-g<$rMOACG{!ul+ zO*6HUnHIb)->yLeOU0#-8~k@x|DJSKo#w8})|+$If$v_pzyC7;U9dBSw(iG^15=8Q z2e%0W59(2(lXDkw!xnY<(TBN{T!x;>o*}$+|8<1SC(G*EF7t<>Pe%!U+S0tO&emxC zssTGU*ZdzE)-k%rBM#8x=|P>-KR>pD|6nk<1;j!F_<2$f3jl!hUw?V6ovieY?0-xK z|5yw;c0n` zflmHS!7{~@OA_l0oMQQwR|Hh)R1XM~NenK~D;2@N#i)-Xe>ss#@cZ;nojn8s9ccGl zDh_$05Jp*5utPsu@SroH>B4VKCuT`;#d*_cR>6ldjS}wKLW0=x^88-}OE?%w9DAD; z1SR=qCR_fA*J0$4*858v&{OC8f}3%;y7+HW*pSs}-7zO^Je>Lje7au-? zjNgxZi~=s_FpA|5qZ$EG*BKXj*qlD8DS=bpC#|%&L;Dvg0ui5?@K<)03^O-BvMy4@ z`ML)|8C0SlaVyAfKtgCshVthj6>)Zgus8P$BfPmhGp#e=$?FDX>q6e%C-<|GZqtH_ z`(WU+c5x~rMz4p0Z{L^fpDwQjNbLW9D-{zCH|WH^b{g>Htw~bES$C|Nn&C|7?ff_?; zPKc-+CIZHESIQK1U(pCY$ekmmaFgXeY__0%qgKc9yf7QVPWI+?h;3ui#@{AtiU z@&QOnM%(C4+C9%Rh*&}dtQNcH$w!!vf8h%#qOKEAR8{X<9wXlP>~Yj0!gKxbfMZ}d-dA;<>-B+mu-5&6ISh>X{g37|&_zLxrcFMO`-;mwDw z6`HKp)ZdF7YG2E?+RSCPVhirx0tyh@2y!{z=aG@#o_F;gW4eY|3l$(G#{nGy9)+Sk zAmz8I2=WQxHYht_rXnUT1qwJiy_A|j(F+Pj*CL-$_Pxas!|GG?Z(gGGuhY{QDZ}Il z`f-+$=U}c?&Za8YT!P&rhcICamuzoNQSH}t7IqSOQ2D1kUEdp`WwNAI!7m?FYd7=*g%IEJNv`UV55Dr)P__0DlFOg_R<% z6LkQeQuU8*`yaOzD35%iWKsDt`weB6;ypYjU}jb4oY(uqC5u2satKl%^fv|XO6;Wb zn2`R{?iIZsps6|NFJyM&eYT<(096eA@M&NFv5x-I>saUgsh@t}{|nQNZLA#?_4FJwVUN)^%@gL_W~*Ltl{g_{SdM@7ZwxcgQPvkkm_dsoIS zA6T5J*TvN4sbuK)*c0_*}3FjivguMl`PpkBba`AcgX z$(z-a`+|_T*-}pX%{IO=bxsN)0nWE*((h|EL_Lc@5^eg&iyEl{SS%HWBEs#4+v3CD z0$d@803WD8n@Kn7p;l^#p0ktqqp!0rMxT?4TbupFZp(Lb8gL)Gfgx2k_A_t{Vt}iO z2U!$DDBvJ2DcG$P>pRoBVzZ9_qU}`@z#ZlRV+rA$vWD%LuaUyRaC`aK-5qBm^GA8Y zs(%_tku<)3sZIr!095VMB{QulNEVr8kT5h-A`?Sb!ri@yEBrFe&YVh!&>;bx#V3Z{ zxgtLu{v5v6;loXE>>r#w+m>BenBAs=`cqIy)7_Atn~~4qnXkw{flR{!jBK#14t#^? zY)+AvEQx&ahWwvK z5aaXdvR*%MH~mxN5dJqJ>e<@8>VIWG7q^t{WhANPKembqDTaplb_MbATTYAj`? z<$4pmHMEKhG9(ywEWIz}Q_lGImekdUXYM)l_p`)K^TqE|ZyF|keE9H#KfHis zWYPuB7Q@!bh_DH~ZU81)OEv}uV5&v~(aylaGBvLxKBTfBwKx`(iUYh+4Un5Cwf#L% zn;$UMbE9bA32aTr7p3MD>+69?bd5eNdGD%$HqT*YV30x4coXOr@Qf2gH?U<WL@KZ|l9B>iz@(p_lj@(8m6}{)sF#$Phi(@7;wOZ0*{`5xAuokO*N(of z0HNI<7}MaGL0e^jZUXxJA;N@}pJ5Jw&nBX4M(>FsG|ypTgjkQ#FGJUl+A>AxW?(qO z%E*AxPDR&_-e^D=P{0AT9;FF^t{=4;K