From 0eea5c1424d6b89208a73617f112b594b9a6612b Mon Sep 17 00:00:00 2001 From: zhongxuanzhen Date: Fri, 27 Mar 2026 19:58:20 +0800 Subject: [PATCH] =?UTF-8?q?3.27=5F433=EF=BC=9A=E5=AE=9E=E9=AA=8C=E5=B9=B6?= =?UTF-8?q?=E9=AA=8C=E8=AF=81485=E5=8F=91=E9=80=81=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=80=8F=E4=BC=A0=E8=87=B3RF433=E6=A8=A1=E5=9D=97=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E5=9C=A8=E5=A4=96=E9=83=A8=E8=AE=BE=E5=A4=87=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E6=8E=A5=E6=94=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增协议识别器状态机,实现指令与透传数据的自动识别 --- Core/Inc/uart3_passthrough.h | 207 ++ Core/Inc/uart3_protocol_discriminator.h | 150 + Core/Inc/uart3_smart_router_config.h | 143 + Core/Src/cmd_router.c | 452 +++- Core/Src/io_monitor.c | 40 +- Core/Src/multi_uart_router.c | 406 ++- Core/Src/relay_control.c | 130 +- Core/Src/uart3_passthrough.c | 269 ++ Core/Src/uart3_protocol_discriminator.c | 252 ++ MDK-ARM/project.uvguix.xtell | 52 +- MDK-ARM/project.uvoptx | 66 +- MDK-ARM/project.uvprojx | 10 + MDK-ARM/project/cmd_parser.crf | Bin 24033 -> 24033 bytes MDK-ARM/project/cmd_parser.o | Bin 55452 -> 55452 bytes MDK-ARM/project/cmd_router.crf | Bin 547721 -> 551918 bytes MDK-ARM/project/cmd_router.d | 3 + MDK-ARM/project/cmd_router.o | Bin 622728 -> 628748 bytes MDK-ARM/project/debug_log.crf | Bin 13106 -> 13106 bytes MDK-ARM/project/debug_log.o | Bin 28996 -> 28996 bytes MDK-ARM/project/gpio.o | Bin 602256 -> 602256 bytes MDK-ARM/project/io_monitor.crf | Bin 545469 -> 545469 bytes MDK-ARM/project/io_monitor.o | Bin 617112 -> 617112 bytes MDK-ARM/project/main.crf | Bin 556074 -> 556074 bytes MDK-ARM/project/main.o | Bin 625740 -> 625740 bytes MDK-ARM/project/multi_uart_router.crf | Bin 546211 -> 546317 bytes MDK-ARM/project/multi_uart_router.o | Bin 629804 -> 629812 bytes MDK-ARM/project/project.axf | Bin 647280 -> 664632 bytes MDK-ARM/project/project.build_log.htm | 90 +- MDK-ARM/project/project.hex | 2410 +++++++++-------- MDK-ARM/project/project.htm | 1315 ++++----- MDK-ARM/project/project.lnp | 2 + MDK-ARM/project/project.map | 1440 +++++----- MDK-ARM/project/project_project.dep | 110 +- MDK-ARM/project/relay_control.crf | Bin 538917 -> 538956 bytes MDK-ARM/project/relay_control.o | Bin 602716 -> 602720 bytes MDK-ARM/project/rf433.o | Bin 631680 -> 631680 bytes MDK-ARM/project/rf433_hal.o | Bin 631404 -> 631404 bytes MDK-ARM/project/rf433_rx_app.o | Bin 618512 -> 618512 bytes MDK-ARM/project/rf433_tx_app.crf | Bin 550292 -> 550292 bytes MDK-ARM/project/rf433_tx_app.o | Bin 622552 -> 622552 bytes MDK-ARM/project/spi.o | Bin 600216 -> 600216 bytes MDK-ARM/project/stm32f1xx_hal.o | Bin 625748 -> 625748 bytes MDK-ARM/project/stm32f1xx_hal_cortex.o | Bin 617520 -> 617520 bytes MDK-ARM/project/stm32f1xx_hal_dma.o | Bin 613544 -> 613544 bytes MDK-ARM/project/stm32f1xx_hal_exti.o | Bin 605428 -> 605428 bytes MDK-ARM/project/stm32f1xx_hal_flash.o | Bin 613100 -> 613100 bytes MDK-ARM/project/stm32f1xx_hal_flash_ex.o | Bin 616272 -> 616272 bytes MDK-ARM/project/stm32f1xx_hal_gpio.o | Bin 604724 -> 604724 bytes MDK-ARM/project/stm32f1xx_hal_gpio_ex.o | Bin 594544 -> 594544 bytes MDK-ARM/project/stm32f1xx_hal_msp.o | Bin 595988 -> 595988 bytes MDK-ARM/project/stm32f1xx_hal_pwr.o | Bin 616008 -> 616008 bytes MDK-ARM/project/stm32f1xx_hal_rcc.o | Bin 617044 -> 617044 bytes MDK-ARM/project/stm32f1xx_hal_rcc_ex.o | Bin 596672 -> 596672 bytes MDK-ARM/project/stm32f1xx_hal_spi.o | Bin 681940 -> 681940 bytes MDK-ARM/project/stm32f1xx_hal_tim.o | Bin 589908 -> 589908 bytes MDK-ARM/project/stm32f1xx_hal_tim_ex.o | Bin 589988 -> 589988 bytes MDK-ARM/project/stm32f1xx_hal_uart.o | Bin 697884 -> 697884 bytes MDK-ARM/project/stm32f1xx_it.o | Bin 610836 -> 610836 bytes MDK-ARM/project/system_stm32f1xx.o | Bin 593480 -> 593480 bytes MDK-ARM/project/systick.o | Bin 598864 -> 598864 bytes MDK-ARM/project/uart2_print.crf | Bin 542342 -> 542342 bytes MDK-ARM/project/uart2_print.o | Bin 614776 -> 614776 bytes MDK-ARM/project/uart3_passthrough.crf | Bin 0 -> 546571 bytes MDK-ARM/project/uart3_passthrough.d | 38 + MDK-ARM/project/uart3_passthrough.o | Bin 0 -> 619248 bytes .../project/uart3_protocol_discriminator.crf | Bin 0 -> 10194 bytes .../project/uart3_protocol_discriminator.d | 8 + .../project/uart3_protocol_discriminator.o | Bin 0 -> 29764 bytes MDK-ARM/project/usart.crf | Bin 542469 -> 542469 bytes MDK-ARM/project/usart.o | Bin 607392 -> 607392 bytes docs/UART3智能数据路由与透传功能开发计划.md | 1078 ++++++++ 71 files changed, 6051 insertions(+), 2620 deletions(-) create mode 100644 Core/Inc/uart3_passthrough.h create mode 100644 Core/Inc/uart3_protocol_discriminator.h create mode 100644 Core/Inc/uart3_smart_router_config.h create mode 100644 Core/Src/uart3_passthrough.c create mode 100644 Core/Src/uart3_protocol_discriminator.c create mode 100644 MDK-ARM/project/uart3_passthrough.crf create mode 100644 MDK-ARM/project/uart3_passthrough.d create mode 100644 MDK-ARM/project/uart3_passthrough.o create mode 100644 MDK-ARM/project/uart3_protocol_discriminator.crf create mode 100644 MDK-ARM/project/uart3_protocol_discriminator.d create mode 100644 MDK-ARM/project/uart3_protocol_discriminator.o create mode 100644 docs/UART3智能数据路由与透传功能开发计划.md diff --git a/Core/Inc/uart3_passthrough.h b/Core/Inc/uart3_passthrough.h new file mode 100644 index 0000000..e40bf0d --- /dev/null +++ b/Core/Inc/uart3_passthrough.h @@ -0,0 +1,207 @@ +/** + ****************************************************************************** + * @file uart3_passthrough.h + * @brief UART3透传引擎模块头文件 + * @author Application Layer + * @version 1.0 + ****************************************************************************** + * @attention + * 设计依据:UART3智能数据路由与透传功能开发计划 第3.2节 + * + * 功能说明: + * 本模块实现透传数据缓冲与发送功能,将UART3接收的透传数据转发至UART1 + * + * 数据结构(严格按文档3.2.2节定义): + * - passthrough_node_t: 透传数据节点 + * - passthrough_queue_t: 透传队列 + * - passthrough_context_t: 透传引擎上下文 + * + * 配置参数(严格按附录D定义): + * - PASSTHROUGH_NODE_SIZE: 128字节 + * - PASSTHROUGH_MAX_NODES: 4个节点 + * - PASSTHROUGH_TOTAL_BUFFER: 512字节 + ****************************************************************************** + */ + +#ifndef __UART3_PASSTHROUGH_H +#define __UART3_PASSTHROUGH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/*============================================================================== + * 透传引擎配置参数 + * 设计依据:文档附录D配置参数 + *============================================================================*/ +/** + * @brief 每个透传节点大小 + */ +#ifndef PASSTHROUGH_NODE_SIZE +#define PASSTHROUGH_NODE_SIZE 128 +#endif + +/** + * @brief 最大节点数量 + */ +#ifndef PASSTHROUGH_MAX_NODES +#define PASSTHROUGH_MAX_NODES 4 +#endif + +/** + * @brief 发送缓冲区总大小 + */ +#ifndef PASSTHROUGH_TOTAL_BUFFER +#define PASSTHROUGH_TOTAL_BUFFER (PASSTHROUGH_NODE_SIZE * PASSTHROUGH_MAX_NODES) +#endif + +/*============================================================================== + * 透传数据节点结构体 + * 设计依据:文档第3.2.2节核心数据结构 + *============================================================================*/ +/** + * @brief 透传数据节点 + * @note 每个节点存储一段待发送的透传数据 + */ +typedef struct { + uint8_t data[PASSTHROUGH_NODE_SIZE]; /**< 数据缓冲区 */ + uint16_t length; /**< 有效数据长度 */ + uint16_t offset; /**< 已发送偏移 */ + bool valid; /**< 节点是否有效 */ +} passthrough_node_t; + +/*============================================================================== + * 透传队列结构体 + * 设计依据:文档第3.2.2节核心数据结构 + *============================================================================*/ +/** + * @brief 透传队列 + * @note 管理多个透传数据节点的FIFO队列 + */ +typedef struct { + passthrough_node_t nodes[PASSTHROUGH_MAX_NODES]; /**< 节点数组 */ + uint8_t write_index; /**< 写入位置 */ + uint8_t read_index; /**< 读取位置 */ + volatile uint16_t pending_count; /**< 待发送字节总数 */ +} passthrough_queue_t; + +/*============================================================================== + * 透传统计结构体 + * 设计依据:文档第3.2.1节模块接口设计 + *============================================================================*/ +/** + * @brief 透传统计信息 + * @note 记录透传引擎的运行状态 + */ +typedef struct { + uint32_t total_bytes_sent; /**< 累计发送字节数 */ + uint32_t total_packets; /**< 累计发送数据包数 */ + uint32_t overflow_count; /**< 缓冲区溢出次数 */ + uint32_t busy_count; /**< UART1忙等待次数 */ +} passthrough_stats_t; + +/*============================================================================== + * 透传引擎上下文结构体 + * 设计依据:文档第3.2.2节核心数据结构 + *============================================================================*/ +/** + * @brief 透传引擎上下文 + * @note 保存透传引擎全部状态信息 + */ +typedef struct { + passthrough_queue_t queue; /**< 透传队列 */ + passthrough_stats_t stats; /**< 透传统计 */ + bool initialized; /**< 初始化标志 */ +} passthrough_context_t; + +/*============================================================================== + * 全局变量声明 + * 设计依据:文档第3.2.2节 + *============================================================================*/ +extern passthrough_context_t g_passthrough_ctx; + +/*============================================================================== + * 函数接口声明 + * 设计依据:文档第3.2.1节模块接口设计 + *============================================================================*/ +/** + * @brief 透传引擎初始化 + * @note 初始化透传队列和统计信息 + * @param 无 + * @retval 无 + */ +void Passthrough_Init(void); + +/** + * @brief 压入单字节到透传缓冲区 + * @note 将单个字节添加到透传发送队列 + * @param byte: 待发送字节 + * @retval bool: true=成功,false=缓冲区满 + */ +bool Passthrough_PushByte(uint8_t byte); + +/** + * @brief 压入数据块到透传缓冲区 + * @note 将数据块添加到透传发送队列 + * @param data: 数据缓冲区指针 + * @param length: 数据长度 + * @retval uint16_t: 实际写入的字节数 + */ +uint16_t Passthrough_PushBuffer(const uint8_t *data, uint16_t length); + +/** + * @brief 透传引擎任务 + * @note 在主循环中周期性调用,每次尝试发送一个字节 + * @param 无 + * @retval 无 + */ +void Passthrough_Task(void); + +/** + * @brief UART1发送完成回调 + * @note 应在HAL_UART_TxCpltCallback中调用,触发下一次发送 + * @param 无 + * @retval 无 + */ +void Passthrough_OnTxComplete(void); + +/** + * @brief 检查UART1是否可发送 + * @note 检查UART1发送缓冲区是否有空间 + * @param 无 + * @retval bool: true=可发送,false=忙 + */ +bool Passthrough_CanSend(void); + +/** + * @brief 获取透传统计信息 + * @note 获取透传引擎的运行统计 + * @param stats: 统计结构指针 + * @retval 无 + */ +void Passthrough_GetStats(passthrough_stats_t *stats); + +/** + * @brief 重置统计信息 + * @note 清零所有统计计数器 + * @param 无 + * @retval 无 + */ +void Passthrough_ResetStats(void); + +/** + * @brief 获取待发送字节数 + * @note 获取队列中等待发送的字节总数 + * @param 无 + * @retval uint16_t: 待发送字节数 + */ +uint16_t Passthrough_GetPendingCount(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Core/Inc/uart3_protocol_discriminator.h b/Core/Inc/uart3_protocol_discriminator.h new file mode 100644 index 0000000..143785c --- /dev/null +++ b/Core/Inc/uart3_protocol_discriminator.h @@ -0,0 +1,150 @@ +/** + ****************************************************************************** + * @file uart3_protocol_discriminator.h + * @brief UART3协议识别器模块头文件 + * @author Application Layer + * @version 1.0 + ****************************************************************************** + * @attention + * 设计依据:UART3智能数据路由与透传功能开发计划 第3.1节 + * + * 功能说明: + * 本模块实现UART3协议识别器,用于判断接收数据是ASCII指令还是透传数据 + * + * 状态机: + * - INIT: 系统启动/复位状态,等待第一个字节 + * - SCAN: 扫描模式,等待指令起始符'$'或透传判定 + * - CMD_MODE: 指令解析模式,数据喂给CmdParser + * - EXEC: 指令执行模式 + * - PASSTHROUGH: 透传模式,数据转发至UART1 + * + * 识别策略: + * - 以'$'开头视为指令候选 + * - 超时(50ms)无'$'则判定为透传 + * - 帧间隔检测('\n'后重新判断) + ****************************************************************************** + */ + +#ifndef __UART3_PROTOCOL_DISCRIMINATOR_H +#define __UART3_PROTOCOL_DISCRIMINATOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/*============================================================================== + * 路由结果枚举定义 + * 设计依据:文档第3.1.2节伪代码 + *============================================================================*/ +/** + * @brief 路由结果枚举 + * @note 定义协议识别器的三种路由结果 + */ +typedef enum { + ROUTE_NONE = 0, /**< 暂时缓存,不路由 */ + ROUTE_CMD, /**< 路由至指令解析器 */ + ROUTE_PASSTHROUGH /**< 路由至透传引擎 */ +} route_result_t; + +/*============================================================================== + * 协议识别器状态枚举定义 + * 设计依据:文档第3.1.1节状态转换图 + *============================================================================*/ +/** + * @brief 协议识别器状态枚举 + * @note 定义状态机的所有状态 + */ +typedef enum { + STATE_INIT = 0, /**< 初始状态,系统启动/复位 */ + STATE_SCAN, /**< 扫描模式,等待指令起始符或透传判定 */ + STATE_CMD_MODE, /**< 指令解析模式 */ + STATE_EXEC, /**< 指令执行模式 */ + STATE_PASSTHROUGH /**< 透传模式 */ +} protocol_state_t; + +/*============================================================================== + * 协议识别器上下文结构体 + * 设计依据:文档第3.1.2节伪代码 + *============================================================================*/ +/** + * @brief UART3协议识别器上下文 + * @note 保存状态机全部状态信息 + */ +typedef struct { + protocol_state_t state; /**< 当前状态 */ + uint32_t last_byte_tick; /**< 上次收到字节的时间 */ + uint32_t scan_start_tick; /**< SCAN状态开始时间 */ + uint8_t scan_buffer[128]; /**< SCAN状态缓存 */ + uint16_t scan_length; /**< SCAN缓存长度 */ + bool pending_cmd; /**< CMD_MODE是否有待处理帧 */ + uint32_t passthrough_bytes; /**< 透传字节计数 */ +} uart3_protocol_context_t; + +/*============================================================================== + * 全局变量声明 + * 设计依据:文档第3.1.2节伪代码 + *============================================================================*/ +extern uart3_protocol_context_t g_uart3_proto_ctx; + +/*============================================================================== + * 函数接口声明 + * 设计依据:文档第3.1.3节接口定义 + *============================================================================*/ +/** + * @brief 协议识别器初始化 + * @note 初始化状态机和上下文 + * @param 无 + * @retval 无 + */ +void UART3_Protocol_Init(void); + +/** + * @brief 协议识别器字节输入 + * @note 由UART3中断调用,判断字节应该走指令路径还是透传路径 + * @param byte: 接收字节 + * @param current_tick: 当前系统时间(ms) + * @retval route_result_t: 路由结果 (ROUTE_CMD/ROUTE_PASSTHROUGH/ROUTE_NONE) + */ +route_result_t UART3_Protocol_FeedByte(uint8_t byte, uint32_t current_tick); + +/** + * @brief 协议识别器超时检查 + * @note 定时调用,检查SCAN状态是否超时 + * @param current_tick: 当前系统时间(ms) + * @retval bool: true=触发了透传,false=继续等待 + */ +bool UART3_Protocol_CheckTimeout(uint32_t current_tick); + +/** + * @brief 获取透传模式下的缓存数据 + * @note 在触发透传后调用,获取待发送的透传数据 + * @param buffer: 输出缓冲区指针 + * @param length: 数据长度指针(输出) + * @retval bool: true=有数据,false=无数据 + */ +bool UART3_Protocol_GetPassthroughData(uint8_t *buffer, uint16_t *length); + +/** + * @brief 获取当前协议识别状态 + * @note 用于调试和状态监控 + * @param 无 + * @retval uint8_t: 当前状态码 + */ +uint8_t UART3_Protocol_GetState(void); + +/** + * @brief 重置协议识别器状态 + * @note 将状态机恢复到INIT状态 + * @param 无 + * @retval 无 + */ +void UART3_Protocol_Reset(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Core/Inc/uart3_smart_router_config.h b/Core/Inc/uart3_smart_router_config.h new file mode 100644 index 0000000..0697ddb --- /dev/null +++ b/Core/Inc/uart3_smart_router_config.h @@ -0,0 +1,143 @@ +/** + ****************************************************************************** + * @file uart3_smart_router_config.h + * @brief UART3智能路由与透传功能配置文件 + * @author Application Layer + * @version 1.0 + ****************************************************************************** + * @attention + * 设计依据:UART3智能数据路由与透传功能开发计划 附录D + * + * 配置说明: + * 本文件定义所有可配置的参数,包括协议识别器、透传引擎和调试开关 + * + * 修改说明: + * 如需调整功能行为,只需修改本文件中的宏定义,无需改动业务代码 + ****************************************************************************** + */ + +#ifndef __UART3_SMART_ROUTER_CONFIG_H +#define __UART3_SMART_ROUTER_CONFIG_H + +/*============================================================================== + * 协议识别器配置参数 + * 设计依据:文档第3.1节 + *============================================================================*/ +/** + * @brief SCAN状态超时时间(ms) + * @note UART3@9600bps,1字节≈1.04ms,50ms≈48字节 + * 用于判断非指令数据何时转为透传 + */ +#ifndef SCAN_TIMEOUT_MS +#define SCAN_TIMEOUT_MS 50 +#endif + +/** + * @brief SCAN缓存大小(字节) + * @note 建议不小于最大指令长度 + */ +#ifndef SCAN_BUFFER_SIZE +#define SCAN_BUFFER_SIZE 128 +#endif + +/** + * @brief 指令帧完整接收超时(ms) + * @note 收到'$'后,等待完整帧(\r\n)的超时时间 + */ +#ifndef CMD_COMPLETE_TIMEOUT_MS +#define CMD_COMPLETE_TIMEOUT_MS 200 +#endif + +/*============================================================================== + * 透传引擎配置参数 + * 设计依据:文档第3.2节 + *============================================================================*/ +/** + * @brief 每个透传节点大小(字节) + * @note 单次透传数据块的最大长度 + */ +#ifndef PASSTHROUGH_NODE_SIZE +#define PASSTHROUGH_NODE_SIZE 128 +#endif + +/** + * @brief 最大节点数量 + * @note 透传缓冲区可存储的数据块数量 + */ +#ifndef PASSTHROUGH_MAX_NODES +#define PASSTHROUGH_MAX_NODES 4 +#endif + +/** + * @brief 发送缓冲区总大小(字节) + * @note = PASSTHROUGH_NODE_SIZE * PASSTHROUGH_MAX_NODES + */ +#ifndef PASSTHROUGH_TOTAL_BUFFER +#define PASSTHROUGH_TOTAL_BUFFER (PASSTHROUGH_NODE_SIZE * PASSTHROUGH_MAX_NODES) +#endif + +/*============================================================================== + * 功能开关配置 + * 设计依据:文档第3.3节 + *============================================================================*/ +/** + * @brief UART3智能路由模式使能开关 + * @note 1=启用智能路由(协议识别+透传),0=原有逻辑(所有数据给CmdParser) + * 可通过此开关快速切换新旧逻辑 + */ +#ifndef UART3_SMART_ROUTING_ENABLED +#define UART3_SMART_ROUTING_ENABLED 1 +#endif + +/** + * @brief 透传日志输出使能开关 + * @note 1=启用透传相关日志,0=禁用 + * 禁用后可减少日志输出,提升性能 + */ +#ifndef PASSTHROUGH_LOG_ENABLED +#define PASSTHROUGH_LOG_ENABLED 1 +#endif + +/*============================================================================== + * 调试配置参数 + * 设计依据:文档第3.1.2节、3.2.3节 + *============================================================================*/ +/** + * @brief 协议识别器调试开关 + * @note 1=启用调试日志,0=禁用 + * 启用后会输出状态转换和路由判定日志 + */ +#ifndef DEBUG_PROTOCOL_DISCRIMINATOR +#define DEBUG_PROTOCOL_DISCRIMINATOR 1 +#endif + +/** + * @brief 透传引擎调试开关 + * @note 1=启用调试日志,0=禁用 + * 启用后会输出发送进度和缓冲区状态日志 + */ +#ifndef DEBUG_PASSTHROUGH_ENGINE +#define DEBUG_PASSTHROUGH_ENGINE 1 +#endif + +/*============================================================================== + * 背压控制参数 + * 设计依据:文档第3.3.3节透传引擎发送接口 + *============================================================================*/ +/** + * @brief 缓冲区满警告阈值(字节) + * @note 当pending_count超过此值时记录警告日志 + */ +#ifndef PASSTHROUGH_WARNING_THRESHOLD +#define PASSTHROUGH_WARNING_THRESHOLD 200 +#endif + +/** + * @brief 每次任务调用的最大发送字节数 + * @note 限制每次调用发送的字节数,避免长时间占用CPU + */ +#ifndef PASSTHROUGH_MAX_SEND_PER_CALL +#define PASSTHROUGH_MAX_SEND_PER_CALL 16 +#endif + +#endif \ No newline at end of file diff --git a/Core/Src/cmd_router.c b/Core/Src/cmd_router.c index ecb27e2..ea6ba86 100644 --- a/Core/Src/cmd_router.c +++ b/Core/Src/cmd_router.c @@ -8,12 +8,12 @@ * @attention * 本模块实现指令路由与响应分发功能 * 设计依据:多通信接口统一指令处理系统开发计划 第3.2节 - * + * * 核心职责: * - 从各UART端口读取数据并喂入解析器 * - 根据指令来源端口路由响应 * - 管理响应路由表 - * + * * 工作流程: * 1. 中断中将接收字节写入对应端口的环形缓冲区 * 2. 主循环中CmdRouter_Task轮询各端口缓冲区 @@ -27,195 +27,541 @@ #include "cmd_parser.h" #include "uart2_print.h" #include "debug_log.h" +#include "uart3_protocol_discriminator.h" +#include "uart3_passthrough.h" +#include "uart3_smart_router_config.h" #include +/*============================================================================== + * 调试宏定义 + *============================================================================*/ +/* DEBUG_CMD_ROUTER: 调试日志开关,置1时启用路由过程日志输出 */ #define DEBUG_CMD_ROUTER 1 #if DEBUG_CMD_ROUTER +/* 路由模块日志宏,带模块前缀"[ROUTER]"方便过滤 */ #define ROUTER_LOG(fmt, ...) UART2_Print_Printf("[ROUTER] " fmt "\r\n", ##__VA_ARGS__) #else #define ROUTER_LOG(fmt, ...) #endif +/*============================================================================== + * 常量定义 + *============================================================================*/ +/** + * @brief 接收日志缓冲区大小 + * @note 用于暂存接收到的原始字节,便于调试跟踪 + * 当超时或帧完成后统一打印到调试串口 + */ #define RX_LOG_BUFFER_SIZE 128 +/*============================================================================== + * 数据结构定义 + *============================================================================*/ +/** + * @brief 端口解析器状态结构 + * @note 跟踪每个UART端口的解析状态和统计信息 + * + * 设计目的: + * 每个UART端口都可能接收到指令,需要独立跟踪其接收状态、 + * 最后接收时间、字节计数等,用于诊断和路由决策。 + * + * 字段说明: + * - source_port: 源端口ID编号 + * - last_feed_tick: 上次喂入数据的系统时间戳(毫秒) + * - rx_count: 累计接收字节数 + * - active: 端口是否处于活跃状态(接收到有效数据) + */ typedef struct { - uint8_t source_port; - uint32_t last_feed_tick; - uint32_t rx_count; - bool active; + uint8_t source_port; /**< 源端口ID编号 */ + uint32_t last_feed_tick; /**< 上次喂入数据的时间戳 */ + uint32_t rx_count; /**< 累计接收字节数 */ + bool active; /**< 端口活跃状态标志 */ } port_parser_state_t; +/*============================================================================== + * 全局变量定义 + *============================================================================*/ +/** + * @brief 各端口解析器状态表 + * @note 静态数组,为PORT_COUNT个端口各自维护解析状态 + */ static port_parser_state_t g_port_states[PORT_COUNT]; +/** + * @brief 响应处理器回调函数指针 + * @note 当设置此回调时,路由响应会调用此处理器而非直接发送 + * 可用于自定义响应处理逻辑(如添加时间戳、过滤等) + */ static cmd_response_handler_t g_response_handler = NULL; +/** + * @brief 已处理指令帧累计计数 + * @note 统计所有端口成功解析的指令帧总数 + */ static uint32_t g_processed_count = 0; + +/** + * @brief 已路由响应累计计数 + * @note 统计成功发送的响应消息总数 + */ static uint32_t g_routed_count = 0; +/** + * @brief 当前正在解析的端口ID + * @note 用于在多端口环境下跟踪当前处理哪个端口的数据 + */ static uint8_t g_current_parsing_port = PORT_UART2; +/** + * @brief 接收原始字节日志缓冲区 + * @note 三维数组:为每个端口维护一个独立的日志缓冲区 + * 便于调试时还原完整的接收字节序列 + */ static uint8_t g_rx_log_buffer[PORT_COUNT][RX_LOG_BUFFER_SIZE]; + +/** + * @brief 各端口日志缓冲区的当前写入长度 + */ static uint16_t g_rx_log_len[PORT_COUNT]; + +/** + * @brief 各端口日志缓冲区最后写入时间戳 + * @note 用于实现超时自动刷新机制 + */ static uint32_t g_rx_log_last_tick[PORT_COUNT]; + +/** + * @brief 接收日志超时阈值(毫秒) + * @note 如果超过此时间没有新字节,则自动刷新日志 + */ #define RX_LOG_TIMEOUT_MS 50 +/*============================================================================== + * 内部静态函数声明 + *============================================================================*/ +static void flush_rx_log(port_id_t port_id); +static void append_rx_log(port_id_t port_id, uint8_t byte); +static void cmd_parser_response_callback(uint8_t source_port, const char *response); + +/*============================================================================== + * 内部静态函数实现 + *============================================================================*/ +/** + * @brief 刷新指定端口的接收日志 + * @note 将暂存的接收字节格式化打印到调试串口,然后清空缓冲区 + * + * @param port_id: 待刷新的端口ID(输入) + * @return 无 + * + * 格式化规则: + * - 可打印ASCII字符(0x20-0x7E)直接输出 + * - '\r'显示为"\\r" + * - '\n'显示为"\\n" + * - 其他字符显示为"\\xXX"十六进制格式 + * + * 调用时机: + * - 接收到完整帧时 + * - 接收超时(RX_LOG_TIMEOUT_MS)时 + */ static void flush_rx_log(port_id_t port_id) { + /* 无日志数据时直接返回 */ if (g_rx_log_len[port_id] == 0) { return; } - + + /* 打印日志头部,包含端口名称 */ UART2_Print_Printf("[ROUTER] %s RX: \"", MultiUART_GetPortName(port_id)); - + + /*---------------------------------------------------------- + * 遍历日志缓冲区,格式化输出每个字节 + *----------------------------------------------------------*/ for (uint16_t i = 0; i < g_rx_log_len[port_id]; i++) { uint8_t c = g_rx_log_buffer[port_id][i]; + if (c >= 0x20 && c < 0x7F) { + /* 可打印ASCII字符:直接输出 */ UART2_Print_Send(&c, 1); } else if (c == '\r') { + /* 回车符:显示为转义序列 */ UART2_Print_Send((const uint8_t *)"\\r", 2); } else if (c == '\n') { + /* 换行符:显示为转义序列 */ UART2_Print_Send((const uint8_t *)"\\n", 2); } else { + /* 其他字符:显示为十六进制格式 */ char hex[4]; snprintf(hex, sizeof(hex), "\\x%02X", c); UART2_Print_Send((const uint8_t *)hex, 4); } } - + + /* 打印日志尾部并换行 */ UART2_Print_String("\"\r\n"); - + + /* 清空日志缓冲区 */ g_rx_log_len[port_id] = 0; } +/** + * @brief 添加字节到接收日志缓冲区 + * @note 暂存接收到的原始字节,支持调试回溯 + * + * @param port_id: 端口ID(输入) + * @param byte: 待添加的字节(输入) + * @return 无 + * + * 设计说明: + * 缓冲区大小有限(RX_LOG_BUFFER_SIZE),超出时丢弃最旧数据。 + * 同时记录最后写入时间戳,用于超时检测。 + */ static void append_rx_log(port_id_t port_id, uint8_t byte) { + /* 缓冲区未满时写入,否则丢弃(溢出处理) */ if (g_rx_log_len[port_id] < RX_LOG_BUFFER_SIZE) { g_rx_log_buffer[port_id][g_rx_log_len[port_id]++] = byte; } + /* 更新最后写入时间戳 */ g_rx_log_last_tick[port_id] = HAL_GetTick(); } +/** + * @brief 解析器响应回调函数 + * @note 作为CmdParser的响应回调,将响应路由到正确的源端口 + * + * @param source_port: 响应目标端口ID(输入) + * @param response: 待发送的响应字符串(输入) + * @return 无 + * + * 路由逻辑: + * 1. 如果设置了自定义响应处理器(g_response_handler),调用它 + * 2. 否则直接通过MultiUART_Send发送到源端口 + * 3. 每次成功路由增加routed_count计数 + * + * 调试日志: + * 使用LOG_INFO输出TX路由详情,便于问题诊断 + */ static void cmd_parser_response_callback(uint8_t source_port, const char *response) { if (g_response_handler != NULL) { + /* 使用自定义响应处理器 */ g_response_handler((port_id_t)source_port, response, strlen(response)); g_routed_count++; } else { + /* 直接发送到源端口 */ MultiUART_SendString((port_id_t)source_port, response); g_routed_count++; } - - LOG_INFO("ROUTER", "TX[%s]: %s", + + /* 输出TX路由调试日志 */ + LOG_INFO("ROUTER", "TX[%s]: %s", MultiUART_GetPortName((port_id_t)source_port), response); } +/*============================================================================== + * 公共函数实现 + *============================================================================*/ +/** + * @brief 指令路由模块初始化 + * @note 初始化所有端口状态、统计计数,并注册解析器回调 + * + * @param 无 + * @return 无 + * + * 初始化内容: + * 1. 重置所有端口的解析状态 + * 2. 清零所有日志缓冲区 + * 3. 重置统计计数器 + * 4. 设置默认解析端口为PORT_UART2 + * 5. 注册响应回调函数到解析器 + */ void CmdRouter_Init(void) { + /*---------------------------------------------------------- + * 初始化各端口解析器状态 + *----------------------------------------------------------*/ for (port_id_t i = 0; i < PORT_COUNT; i++) { g_port_states[i].source_port = i; g_port_states[i].last_feed_tick = 0; g_port_states[i].rx_count = 0; g_port_states[i].active = false; - + g_rx_log_len[i] = 0; g_rx_log_last_tick[i] = 0; } - + + /*---------------------------------------------------------- + * 初始化统计计数器和状态变量 + *----------------------------------------------------------*/ g_response_handler = NULL; g_processed_count = 0; g_routed_count = 0; g_current_parsing_port = PORT_UART2; - + + /*---------------------------------------------------------- + * 注册响应回调函数 + * 将cmd_parser的响应路由到正确的源端口 + *----------------------------------------------------------*/ CmdParser_SetResponseCallback(cmd_parser_response_callback); - + + /*---------------------------------------------------------- + * 初始化UART3智能路由模块 + *----------------------------------------------------------*/ + #if UART3_SMART_ROUTING_ENABLED + UART3_Protocol_Init(); + Passthrough_Init(); + ROUTER_LOG("UART3 Smart Router enabled"); + #endif + ROUTER_LOG("Init OK, %d ports registered", PORT_COUNT); } +/** + * @brief 指令路由主任务函数 + * @note 在主循环中周期性调用,处理所有端口的接收数据和路由 + * + * @param 无 + * @return 无 + * + * 工作流程: + * 1. UART1: 原有逻辑,所有数据喂给解析器 + * 2. UART3: 智能路由模式(协议识别+透传) + * 3. 处理日志缓冲区超时 + * 4. 调用解析器任务处理完整帧 + * + * UART3智能路由(当UART3_SMART_ROUTING_ENABLED=1时): + * 1. 读取UART3接收缓冲区字节 + * 2. 协议识别:判断是CMD还是透传 + * 3. CMD → CmdParser_FeedByte() + * 4. PASSTHROUGH → Passthrough_PushByte() + * 5. 检查SCAN超时,触发透传 + * 6. 执行透传引擎任务 + */ void CmdRouter_Task(void) { uint32_t current_tick = HAL_GetTick(); - + + /*---------------------------------------------------------- + * 第一阶段:UART1处理(保持原有逻辑) + *----------------------------------------------------------*/ + { + port_id_t port_id = PORT_UART1; + + uint16_t rx_count = MultiUART_GetRxCount(port_id); + + if (rx_count > 0) { + g_current_parsing_port = port_id; + CmdParser_SetSourcePort(port_id); + + uint8_t byte; + while (MultiUART_ReadByte(port_id, &byte) > 0) { + append_rx_log(port_id, byte); + CmdParser_FeedByte(byte, current_tick); + g_port_states[port_id].rx_count++; + } + + if (CmdParser_HasCompleteFrame(NULL)) { + flush_rx_log(port_id); + g_processed_count++; + g_port_states[port_id].active = true; + } + } + } + + /*---------------------------------------------------------- + * 第二阶段:UART3智能路由处理 + * 设计依据:文档第3.3.1节 修改CmdRouter_Task + *----------------------------------------------------------*/ + #if UART3_SMART_ROUTING_ENABLED + { + uint8_t byte; + + while (MultiUART_ReadByte(PORT_UART3, &byte) > 0) { + route_result_t route = UART3_Protocol_FeedByte(byte, current_tick); + switch (route) { + case ROUTE_CMD: + CmdParser_SetSourcePort(PORT_UART3); + CmdParser_FeedByte(byte, current_tick); + LOG_DEBUG("UART3", "CMD byte: 0x%02X", byte); + break; + + case ROUTE_PASSTHROUGH: + Passthrough_PushByte(byte); + LOG_DEBUG("UART3", "PTX byte: 0x%02X", byte); + break; + + case ROUTE_NONE: + break; + } + } + + if (UART3_Protocol_CheckTimeout(current_tick)) { + uint8_t buffer[128]; + uint16_t length; + if (UART3_Protocol_GetPassthroughData(buffer, &length)) { + Passthrough_PushBuffer(buffer, length); + LOG_INFO("UART3", "PASSTHROUGH: %d bytes queued", (int)length); + } + } + + Passthrough_Task(); + } + #else + { + port_id_t port_id = PORT_UART3; + + uint16_t rx_count = MultiUART_GetRxCount(port_id); + + if (rx_count > 0) { + g_current_parsing_port = port_id; + CmdParser_SetSourcePort(port_id); + + uint8_t byte; + while (MultiUART_ReadByte(port_id, &byte) > 0) { + append_rx_log(port_id, byte); + CmdParser_FeedByte(byte, current_tick); + g_port_states[port_id].rx_count++; + } + + if (CmdParser_HasCompleteFrame(NULL)) { + flush_rx_log(port_id); + g_processed_count++; + g_port_states[port_id].active = true; + } + } + } + #endif + + /*---------------------------------------------------------- + * 第三阶段:检查各端口日志缓冲区的超时状态 + *----------------------------------------------------------*/ for (port_id_t port_id = 0; port_id < PORT_COUNT; port_id++) { if (port_id == PORT_UART2) { continue; } - - if (g_rx_log_len[port_id] > 0 && + + if (g_rx_log_len[port_id] > 0 && (current_tick - g_rx_log_last_tick[port_id]) >= RX_LOG_TIMEOUT_MS) { flush_rx_log(port_id); } } - - for (port_id_t port_id = 0; port_id < PORT_COUNT; port_id++) { - if (port_id == PORT_UART2) { - continue; - } - - uint16_t rx_count = MultiUART_GetRxCount(port_id); - - if (rx_count == 0) { - continue; - } - - g_current_parsing_port = port_id; - CmdParser_SetSourcePort(port_id); - - uint8_t byte; - while (MultiUART_ReadByte(port_id, &byte) > 0) { - append_rx_log(port_id, byte); - CmdParser_FeedByte(byte, HAL_GetTick()); - g_port_states[port_id].rx_count++; - } - - if (CmdParser_HasCompleteFrame(NULL)) { - flush_rx_log(port_id); - g_processed_count++; - g_port_states[port_id].active = true; - } - } - + + /*---------------------------------------------------------- + * 第四阶段:调用解析器任务处理完整帧 + *----------------------------------------------------------*/ CmdParser_Task(); } +/** + * @brief 设置自定义响应处理器 + * @note 用于在响应发送前进行自定义处理(如添加时间戳、加密等) + * + * @param handler: 响应处理回调函数指针,NULL则使用默认行为(输入) + * @return 无 + * + * 回调函数原型: + * void handler(port_id_t port, const char *response, uint16_t len) + * + * 使用场景: + * - 需要在响应中添加时间戳 + * - 需要对响应数据进行编码/加密 + * - 需要过滤特定响应 + */ void CmdRouter_SetResponseHandler(cmd_response_handler_t handler) { g_response_handler = handler; ROUTER_LOG("Response handler %s", handler ? "set" : "cleared"); } +/** + * @brief 向指定端口发送响应 + * @note 封装MultiUART_Send,统一响应发送接口 + * + * @param port: 目标端口ID(输入) + * @param response: 待发送的响应字符串(输入) + * @param len: 响应长度(输入) + * @return 无 + * + * 参数检查: + * - port超出范围、response为NULL或len为0时直接返回 + * + * 统计更新: + * 每次成功发送增加g_routed_count计数 + */ void CmdRouter_SendResponse(port_id_t port, const char *response, uint16_t len) { + /* 参数合法性检查 */ if (port >= PORT_COUNT || response == NULL || len == 0) { return; } - + + /* 通过多UART模块发送数据 */ MultiUART_Send(port, (const uint8_t *)response, len); g_routed_count++; - - LOG_INFO("ROUTER", "SendResponse[%s]: %.*s", + + LOG_INFO("ROUTER", "SendResponse[%s]: %.*s", MultiUART_GetPortName(port), len, response); } +/** + * @brief 广播响应到所有端口 + * @note 将同一响应同时发送到所有UART端口 + * + * @param response: 待发送的响应字符串(输入) + * @param len: 响应长度(输入) + * @return 无 + * + * 使用场景: + * - 系统公告广播 + * - 状态变更通知所有监听者 + * + * 注意: + * UART2(调试端口)也会收到广播 + */ void CmdRouter_BroadcastResponse(const char *response, uint16_t len) { + /* 参数合法性检查 */ if (response == NULL || len == 0) { return; } - + + /* 遍历所有端口发送 */ for (port_id_t port = 0; port < PORT_COUNT; port++) { MultiUART_Send(port, (const uint8_t *)response, len); g_routed_count++; } - + LOG_INFO("ROUTER", "Broadcast: %.*s", len, response); } +/** + * @brief 获取已处理指令帧累计计数 + * @note 统计所有端口成功解析的指令帧总数 + * + * @param 无 + * @return uint32_t: 已处理帧累计次数 + * + * 用途: + * - 监控系统负载 + * - 评估解析器性能 + */ uint32_t CmdRouter_GetProcessedCount(void) { return g_processed_count; } +/** + * @brief 获取已路由响应累计计数 + * @note 统计成功发送的响应消息总数 + * + * @param 无 + * @return uint32_t: 已路由响应累计次数 + * + * 用途: + * - 监控系统通信量 + * - 检测是否有响应发送失败 + */ uint32_t CmdRouter_GetRoutedCount(void) { return g_routed_count; diff --git a/Core/Src/io_monitor.c b/Core/Src/io_monitor.c index c784b2d..a448939 100644 --- a/Core/Src/io_monitor.c +++ b/Core/Src/io_monitor.c @@ -107,6 +107,13 @@ static bool report_enabled = true; * @brief IO事件回调函数指针 * @note 设置后,IO状态变化将通过回调函数上报 * 为NULL时使用默认的UART2_Print_String输出 + * + * 回调函数原型: + * void callback(uint8_t channel, uint8_t state, const char *event_msg) + * + * 使用场景: + * - 需要将事件发送到其他端口时设置回调 + * - 传入NULL恢复默认UART2输出方式 */ static io_event_callback_t g_event_callback = NULL; @@ -129,17 +136,18 @@ static uint8_t calc_checksum(const char *data, uint8_t len); /** * @brief 发送DI状态变化事件 - * @note 构造并发送ASCII格式的状态变化消息至UART2 + * @note 构造并发送ASCII格式的状态变化消息 * 消息格式: $DI_EVENT,,*\r\n + * 如果设置了回调函数,则通过回调发送;否则发送到UART2 * * @param channel: 通道编号,从0开始计数(输入) * @param state: 通道状态,0=低电平,1=高电平(输入) * @return 无返回值 * - * 调用说明: - * - 此函数在状态变化被确认后调用,用于通知上位机或日志系统 - * - 内部会调用calc_checksum计算校验和 - * - 通过UART2_Print_String发送原始字符串 + * 事件路由说明: + * 1. 始终通过MultiUART_SendString发送到UART1(RF433)端口 + * 2. 如果设置了回调函数(g_event_callback),也通过回调发送 + * 3. UART2仅用于调试日志输出 */ static void send_di_event(uint8_t channel, uint8_t state); @@ -177,10 +185,10 @@ static uint8_t calc_checksum(const char *data, uint8_t len) * @param state: 通道状态,0=低电平,1=高电平(输入) * @return 无返回值 * - * 调用说明: - * - 此函数在状态变化被确认后调用,用于通知上位机或日志系统 - * - 内部会调用calc_checksum计算校验和 - * - 如果设置了回调函数,则通过回调发送;否则通过UART2_Print_String发送 + * 事件路由说明: + * 1. 始终通过MultiUART_SendString发送到UART1(RF433)端口 + * 2. 如果设置了回调函数(g_event_callback),也通过回调发送 + * 3. UART2仅用于调试日志输出 */ static void send_di_event(uint8_t channel, uint8_t state) { @@ -198,14 +206,20 @@ static void send_di_event(uint8_t channel, uint8_t state) /* 输出调试日志到UART2,记录状态变化 */ DEBUG_LOG("CH%d -> %s", channel + 1, state ? "HIGH" : "LOW"); - - /* 向UART1(RF433)发送状态变化事件 */ + + /*---------------------------------------------------------- + * 向UART1(RF433模块)发送状态变化事件 + * 这是IO事件的主要路由通道,用于无线上报到上位机 + *----------------------------------------------------------*/ MultiUART_SendString(PORT_UART1, msg); /* 输出完整消息到UART2,方便调试查看 */ DEBUG_LOG("RF433 TX: \"%s\"", msg); - - /* 如果设置了回调函数,也通过回调发送 */ + + /*---------------------------------------------------------- + * 如果设置了回调函数,也通过回调发送 + * 用于支持额外的自定义处理逻辑 + *----------------------------------------------------------*/ if (g_event_callback != NULL) { g_event_callback(channel, state, msg); } diff --git a/Core/Src/multi_uart_router.c b/Core/Src/multi_uart_router.c index 7e46013..a73422e 100644 --- a/Core/Src/multi_uart_router.c +++ b/Core/Src/multi_uart_router.c @@ -8,12 +8,17 @@ * @attention * 本模块实现多UART端口的统一管理 * 设计依据:多通信接口统一指令处理系统开发计划 第3.1、3.3、3.5节及附录A - * + * * 关键特性: * 1. 中断+环形缓冲区接收机制 * 2. 非阻塞发送机制 * 3. 端口上下文表管理 * 4. 响应路由表 + * + * 端口映射: + * - PORT_UART1: 连接RF433无线模块(用于无线数据收发) + * - PORT_UART2: 调试串口(用于日志和调试输出) + * - PORT_UART3: 预留扩展端口 ****************************************************************************** */ @@ -23,28 +28,60 @@ #include #include +/*============================================================================== + * 调试宏定义 + *============================================================================*/ +/* DEBUG_MULTI_UART: 多UART路由调试日志开关 */ #define DEBUG_MULTI_UART 1 #if DEBUG_MULTI_UART +/* 多UART模块日志宏,带前缀"[MUART]" */ #define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[MUART] " fmt "\r\n", ##__VA_ARGS__) #else #define DEBUG_LOG(fmt, ...) #endif +/*============================================================================== + * 全局变量定义 + *============================================================================*/ +/** + * @brief UART端口上下文表 + * @note 静态数组,为每个端口维护独立的上下文状态 + * 包括接收/发送环形缓冲区、UART句柄、统计计数等 + */ static uart_port_context_t g_port_ctx[PORT_COUNT]; +/** + * @brief UART端口与HAL句柄映射表 + * @note 通过端口ID索引,快速获取对应的HAL_UART_HandleTypeDef指针 + * 使用常量初始化,在编译时确定,无运行时开销 + */ static UART_HandleTypeDef *const g_port_uart_map[PORT_COUNT] = { - [PORT_UART1] = &huart1, - [PORT_UART2] = &huart2, - [PORT_UART3] = &huart3, + [PORT_UART1] = &huart1, /**< RF433无线模块 */ + [PORT_UART2] = &huart2, /**< 调试串口 */ + [PORT_UART3] = &huart3, /**< 预留扩展 */ }; +/** + * @brief UART端口名称映射表 + * @note 用于调试日志输出,快速获取端口的可读名称 + */ static const char *const g_port_name_map[PORT_COUNT] = { - [PORT_UART1] = "UART1", - [PORT_UART2] = "UART2", - [PORT_UART3] = "UART3", + [PORT_UART1] = "UART1", /**< RF433无线模块 */ + [PORT_UART2] = "UART2", /**< 调试串口 */ + [PORT_UART3] = "UART3", /**< 预留扩展 */ }; +/*============================================================================== + * 内部静态函数实现 + *============================================================================*/ +/** + * @brief 初始化接收环形缓冲区 + * @note 重置接收环缓冲区的所有状态指针和计数器 + * + * @param ring: 待初始化的接收环形缓冲区指针(输入/输出) + * @return 无 + */ static void rx_ring_init(uart_rx_ring_t *ring) { ring->head = 0; @@ -53,6 +90,13 @@ static void rx_ring_init(uart_rx_ring_t *ring) ring->overflow_count = 0; } +/** + * @brief 初始化发送环形缓冲区 + * @note 重置发送环形缓冲区的所有状态指针、计数器和发送标志 + * + * @param ring: 待初始化的发送环形缓冲区指针(输入/输出) + * @return 无 + */ static void tx_ring_init(uart_tx_ring_t *ring) { ring->head = 0; @@ -62,10 +106,26 @@ static void tx_ring_init(uart_tx_ring_t *ring) ring->overflow_count = 0; } +/** + * @brief 接收环形缓冲区写入(生产者) + * @note 将接收到的字节写入缓冲区,中断安全 + * + * @param ring: 接收环形缓冲区指针(输入/输出) + * @param byte: 待写入的字节(输入) + * @return bool: true=写入成功,false=缓冲区满导致丢弃 + * + * 线程安全: + * - 使用__disable_irq/__enable_irq保护临界区 + * - 确保检查count和写入buffer之间不被中断打断 + * + * 溢出处理: + * - 缓冲区满时丢弃数据,不阻塞 + * - 增加overflow_count计数供诊断使用 + */ static bool rx_ring_push(uart_rx_ring_t *ring, uint8_t byte) { bool success = true; - + __disable_irq(); if (ring->count >= UART_RX_BUFFER_SIZE) { ring->overflow_count++; @@ -76,14 +136,29 @@ static bool rx_ring_push(uart_rx_ring_t *ring, uint8_t byte) ring->count++; } __enable_irq(); - + return success; } +/** + * @brief 接收环形缓冲区读取(消费者) + * @note 从缓冲区读取一个字节,中断安全 + * + * @param ring: 接收环形缓冲区指针(输入) + * @param byte: 读取的字节输出指针(输出) + * @return uint16_t: 成功读取的字节数(0或1) + * + * 线程安全: + * - 使用__disable_irq/__enable_irq保护临界区 + * + * 设计说明: + * - 返回0表示缓冲区空,调用方应检查返回值 + * - 读取后自动更新tail指针,实现FIFO + */ static uint16_t rx_ring_pop(uart_rx_ring_t *ring, uint8_t *byte) { uint16_t result = 0; - + __disable_irq(); if (ring->count > 0) { *byte = ring->buffer[ring->tail]; @@ -92,14 +167,30 @@ static uint16_t rx_ring_pop(uart_rx_ring_t *ring, uint8_t *byte) result = 1; } __enable_irq(); - + return result; } +/** + * @brief 发送环形缓冲区写入(生产者) + * @note 将待发送数据写入缓冲区,中断安全 + * + * @param ring: 发送环形缓冲区指针(输入/输出) + * @param data: 待写入数据缓冲区指针(输入) + * @param len: 待写入数据字节数(输入) + * @return uint16_t: 成功写入的字节数 + * + * 线程安全: + * - 使用__disable_irq/__enable_irq保护临界区 + * + * 设计说明: + * - 可能只写入部分数据(缓冲区满时截断) + * - 返回written值,调用方据此判断是否发送完毕 + */ static uint16_t tx_ring_push(uart_tx_ring_t *ring, const uint8_t *data, uint16_t len) { uint16_t written = 0; - + __disable_irq(); for (uint16_t i = 0; i < len; i++) { if (ring->count >= UART_TX_BUFFER_SIZE) { @@ -112,19 +203,38 @@ static uint16_t tx_ring_push(uart_tx_ring_t *ring, const uint8_t *data, uint16_t written++; } __enable_irq(); - + return written; } +/** + * @brief 启动UART发送(Kickoff) + * @note 如果有数据待发送且UART空闲,启动首次发送 + * + * @param port_id: 端口ID(输入) + * @return 无 + * + * 发送触发条件: + * - 发送缓冲区有数据(count > 0) + * - UART当前处于空闲状态(is_sending == false) + * + * 中断安全: + * - 使用__disable_irq/__enable_irq保护临界区 + * + * 设计说明: + * - 首次发送启动后,后续发送由TxCpltCallback驱动 + * - 此函数仅负责"kickoff",不负责连续发送 + */ static void tx_kickoff(port_id_t port_id) { uart_port_context_t *ctx = &g_port_ctx[port_id]; uart_tx_ring_t *ring = &ctx->tx_ring; uint8_t byte; bool has_data = false; - + __disable_irq(); if (!ring->is_sending && ring->count > 0) { + /* 取出下一个待发送字节 */ byte = ring->buffer[ring->tail]; ring->tail = (ring->tail + 1) % UART_TX_BUFFER_SIZE; ring->count--; @@ -132,95 +242,197 @@ static void tx_kickoff(port_id_t port_id) has_data = true; } __enable_irq(); - + + /* 启动UART中断发送 */ if (has_data) { HAL_UART_Transmit_IT(ctx->huart, &byte, 1); } } +/*============================================================================== + * 公共函数实现 + *============================================================================*/ +/** + * @brief 多UART路由模块初始化 + * @note 在系统启动时调用,初始化所有端口的上下文和缓冲区 + * + * @param 无 + * @return 无 + * + * 初始化内容: + * 1. 遍历所有端口,初始化上下文 + * 2. 建立端口与HAL句柄的关联 + * 3. 初始化各端口的收发环形缓冲区 + * 4. 重置统计计数器 + * + * 调用时机: + * 应在HAL_UART_Init()之后、各外设使用前调用 + */ void MultiUART_Init(void) { for (port_id_t i = 0; i < PORT_COUNT; i++) { uart_port_context_t *ctx = &g_port_ctx[i]; - + + /* 建立端口与HAL句柄的关联 */ ctx->huart = g_port_uart_map[i]; ctx->name = g_port_name_map[i]; - + + /* 初始化收发环形缓冲区 */ rx_ring_init(&ctx->rx_ring); tx_ring_init(&ctx->tx_ring); - + + /* 重置统计计数器和临时变量 */ ctx->rx_tmp = 0; ctx->rx_count = 0; ctx->tx_count = 0; ctx->error_count = 0; ctx->initialized = true; } - + DEBUG_LOG("Init OK, %d ports configured", PORT_COUNT); } +/** + * @brief 向指定端口喂入接收字节 + * @note 通常在UART接收中断中调用,将接收到的字节放入缓冲区 + * + * @param port_id: 目标端口ID(输入) + * @param byte: 接收到的字节(输入) + * @return 无 + * + * 功能说明: + * 1. 参数合法性检查 + * 2. 端口初始化状态检查 + * 3. 将字节写入接收环形缓冲区 + * 4. 更新接收统计计数 + * + * 溢出处理: + * 缓冲区满时丢弃数据,增加error_count计数 + */ void MultiUART_FeedByte(port_id_t port_id, uint8_t byte) { + /* 参数合法性检查 */ if (port_id >= PORT_COUNT) { return; } - + uart_port_context_t *ctx = &g_port_ctx[port_id]; - + + /* 检查端口是否已初始化 */ if (!ctx->initialized) { return; } - + + /* 写入接收缓冲区,失败时增加错误计数 */ if (!rx_ring_push(&ctx->rx_ring, byte)) { ctx->error_count++; DEBUG_LOG("%s RX overflow", ctx->name); } - + ctx->rx_count++; } +/** + * @brief 多UART路由任务函数 + * @note 在主循环中周期性调用,处理发送队列 + * + * @param 无 + * @return 无 + * + * 功能说明: + * 轮询各端口的发送缓冲区,调用tx_kickoff启动待发的数据 + * 接收处理由中断完成(MultiUART_FeedByte),此函数仅处理发送 + * + * 端口跳过说明: + * - 跳过PORT_UART2(调试串口),由UART2_Print模块独立处理 + * + * 调用时机: + * 建议在主循环中周期性调用(如10ms定时) + */ void MultiUART_Task(void) { for (port_id_t i = 0; i < PORT_COUNT; i++) { uart_port_context_t *ctx = &g_port_ctx[i]; - + + /* 检查端口是否已初始化 */ if (!ctx->initialized) { continue; } - + + /* 跳过调试串口(UART2) */ if (i == PORT_UART2) { continue; } - + + /* 尝试启动发送 */ tx_kickoff(i); } } +/** + * @brief 向指定端口发送数据 + * @note 核心发送函数,将数据写入发送缓冲区并启动发送 + * + * @param port_id: 目标端口ID(输入) + * @param data: 待发送数据缓冲区指针(输入) + * @param len: 待发送数据字节数(输入) + * @return 无 + * + * 特殊处理: + * - PORT_UART2直接调用UART2_Print_Send,由调试模块处理 + * - 其他端口使用本模块的环形缓冲区机制 + * + * 发送流程: + * 1. 写入发送缓冲区 + * 2. 调用tx_kickoff启动首次发送(如需要) + * + * 中断安全: + * - tx_ring_push内部使用临界区保护 + */ void MultiUART_Send(port_id_t port_id, const uint8_t *data, uint16_t len) { + /* 参数合法性检查 */ if (port_id >= PORT_COUNT || data == NULL || len == 0) { return; } - + + /*---------------------------------------------------------- + * 调试串口(UART2)特殊处理 + * 调试打印不走环形缓冲区,直接发送 + *----------------------------------------------------------*/ if (port_id == PORT_UART2) { UART2_Print_Send(data, len); return; } - + uart_port_context_t *ctx = &g_port_ctx[port_id]; - + + /* 检查端口是否已初始化 */ if (!ctx->initialized) { return; } - + + /* 写入发送缓冲区并更新计数 */ uint16_t written = tx_ring_push(&ctx->tx_ring, data, len); - + if (written > 0) { ctx->tx_count += written; tx_kickoff(port_id); } } +/** + * @brief 向指定端口发送字符串 + * @note 封装MultiUART_Send,自动计算字符串长度 + * + * @param port_id: 目标端口ID(输入) + * @param str: 待发送的以'\0'结尾的字符串指针(输入) + * @return 无 + * + * 使用说明: + * str必须为有效指针且以'\0'结尾 + * strlen计算长度时不包括终止符 + */ void MultiUART_SendString(port_id_t port_id, const char *str) { if (str == NULL) { @@ -229,19 +441,36 @@ void MultiUART_SendString(port_id_t port_id, const char *str) MultiUART_Send(port_id, (const uint8_t *)str, strlen(str)); } +/** + * @brief 向指定端口发送格式化数据 + * @note 仿printf风格,支持可变参数格式化输出 + * + * @param port_id: 目标端口ID(输入) + * @param fmt: 格式化字符串(输入) + * @param ...: 可变参数列表(输入) + * @return 无 + * + * 实现说明: + * 1. 使用va_list/va_start/va_end处理可变参数 + * 2. vsnprintf将格式化参数写入临时缓冲区(128字节) + * 3. 调用MultiUART_Send发送 + * + * 缓冲区限制: + * 最大格式化输出为127字节(128-1留作终止符) + */ void MultiUART_SendFmt(port_id_t port_id, const char *fmt, ...) { if (fmt == NULL) { return; } - + char buffer[128]; va_list args; - + va_start(args, fmt); int len = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); - + if (len > 0) { if (len >= (int)sizeof(buffer)) { len = sizeof(buffer) - 1; @@ -250,25 +479,44 @@ void MultiUART_SendFmt(port_id_t port_id, const char *fmt, ...) } } +/** + * @brief UART发送完成回调函数 + * @note 应在UART TX完成中断中调用,驱动连续发送 + * + * @param port_id: 端口ID(输入) + * @return 无 + * + * 特殊处理: + * - PORT_UART2调用UART2_Print_TxCpltCallback处理 + * + * 发送驱动逻辑: + * 1. 清除is_sending标志 + * 2. 检查发送缓冲区是否还有数据 + * 3. 如有,取出下一字节并启动新发送 + * + * 中断安全: + * - 使用__disable_irq/__enable_irq保护临界区 + */ void MultiUART_TxCpltCallback(port_id_t port_id) { if (port_id >= PORT_COUNT) { return; } - + + /* 调试串口(UART2)特殊处理 */ if (port_id == PORT_UART2) { UART2_Print_TxCpltCallback(); return; } - + uart_port_context_t *ctx = &g_port_ctx[port_id]; uart_tx_ring_t *ring = &ctx->tx_ring; uint8_t byte; bool has_more = false; - + __disable_irq(); ring->is_sending = false; - + if (ring->count > 0) { byte = ring->buffer[ring->tail]; ring->tail = (ring->tail + 1) % UART_TX_BUFFER_SIZE; @@ -277,12 +525,22 @@ void MultiUART_TxCpltCallback(port_id_t port_id) has_more = true; } __enable_irq(); - + if (has_more) { HAL_UART_Transmit_IT(ctx->huart, &byte, 1); } } +/** + * @brief 获取端口名称 + * @note 返回指定端口的可读名称字符串 + * + * @param port_id: 端口ID(输入) + * @return const char*: 端口名称字符串指针 + * + * 错误处理: + * 端口ID无效时返回"UNKNOWN" + */ const char *MultiUART_GetPortName(port_id_t port_id) { if (port_id >= PORT_COUNT) { @@ -291,12 +549,26 @@ const char *MultiUART_GetPortName(port_id_t port_id) return g_port_name_map[port_id]; } +/** + * @brief 获取端口接收缓冲区中的字节数 + * @note 返回指定端口待读取的接收数据数量 + * + * @param port_id: 端口ID(输入) + * @return uint16_t: 待读取的字节数,无效端口返回0 + * + * 中断安全: + * - 使用临界区保护读取count + * + * 使用场景: + * - 轮询方式判断是否有数据可读 + * - 流量控制诊断 + */ uint16_t MultiUART_GetRxCount(port_id_t port_id) { if (port_id >= PORT_COUNT) { return 0; } - + uint16_t count; __disable_irq(); count = g_port_ctx[port_id].rx_ring.count; @@ -304,34 +576,60 @@ uint16_t MultiUART_GetRxCount(port_id_t port_id) return count; } +/** + * @brief 从端口读取一个字节 + * @note 从接收缓冲区读取一个字节(非阻塞) + * + * @param port_id: 端口ID(输入) + * @param byte: 读取的字节输出指针(输出) + * @return uint16_t: 成功读取的字节数(0或1) + * + * 中断安全: + * - 使用临界区保护 + * + * 使用场景: + * 在主循环中轮询各端口的接收缓冲区,读取数据喂入解析器 + */ uint16_t MultiUART_ReadByte(port_id_t port_id, uint8_t *byte) { if (port_id >= PORT_COUNT || byte == NULL) { return 0; } - + uart_rx_ring_t *ring = &g_port_ctx[port_id].rx_ring; - + __disable_irq(); if (ring->count == 0) { __enable_irq(); return 0; } - + *byte = ring->buffer[ring->tail]; ring->tail = (ring->tail + 1) % UART_RX_BUFFER_SIZE; ring->count--; __enable_irq(); - + return 1; } +/** + * @brief 获取端口发送缓冲区的可用空间 + * @note 返回指定端口还能写入的字节数 + * + * @param port_id: 端口ID(输入) + * @return uint16_t: 可用空间字节数,无效端口返回0 + * + * 计算公式:available = buffer_size - count + * + * 中断安全: + * - 使用临界区保护 + */ uint16_t MultiUART_GetTxAvailable(port_id_t port_id) { if (port_id >= PORT_COUNT) { return 0; } - + uint16_t available; __disable_irq(); available = UART_TX_BUFFER_SIZE - g_port_ctx[port_id].tx_ring.count; @@ -339,12 +637,26 @@ uint16_t MultiUART_GetTxAvailable(port_id_t port_id) return available; } +/** + * @brief 获取端口的溢出错误计数 + * @note 统计接收和发送缓冲区的溢出总次数 + * + * @param port_id: 端口ID(输入) + * @return uint32_t: 溢出错误累计次数,无效端口返回0 + * + * 计数组成: + * = rx_ring.overflow_count + tx_ring.overflow_count + * + * 使用场景: + * - 诊断缓冲区是否足够大 + * - 检测数据产生速度是否超出处理能力 + */ uint32_t MultiUART_GetOverflowCount(port_id_t port_id) { if (port_id >= PORT_COUNT) { return 0; } - - return g_port_ctx[port_id].rx_ring.overflow_count + + + return g_port_ctx[port_id].rx_ring.overflow_count + g_port_ctx[port_id].tx_ring.overflow_count; } diff --git a/Core/Src/relay_control.c b/Core/Src/relay_control.c index 431d042..d3bda9d 100644 --- a/Core/Src/relay_control.c +++ b/Core/Src/relay_control.c @@ -11,7 +11,7 @@ * 1. 最小切换间隔保护,防止频繁切换损坏继电器 * 2. 状态记录 * 3. 调试日志输出 - * + * * 修订历史: * v2.0 - 精简为单路继电器控制,移除冗余功能 ****************************************************************************** @@ -21,49 +21,163 @@ #include "uart2_print.h" #include "main.h" +/*============================================================================== + * 调试宏定义 + *============================================================================*/ +/* DEBUG_RELAY: 调试日志开关,置1时启用继电器控制过程日志输出 */ #define DEBUG_RELAY 1 #if DEBUG_RELAY +/* 调试日志宏,带模块前缀"[RELAY]"方便过滤日志 */ #define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[RELAY] " fmt "\r\n", ##__VA_ARGS__) #else #define DEBUG_LOG(fmt, ...) #endif +/*============================================================================== + * 全局变量定义 + *============================================================================*/ +/** + * @brief 继电器当前状态 + * @note 记录继电器的开关状态 + * + * 状态含义: + * - false: 继电器处于断开状态(OFF) + * - true: 继电器处于闭合状态(ON) + * + * 初始化说明: + * 初始化为false,表示系统上电后继电器默认断开 + */ static bool current_state = false; + +/** + * @brief 上一次切换操作的时间戳 + * @note 用于实现继电器最小切换间隔保护 + * + * 设计目的: + * 继电器是机械开关,频繁切换会缩短其使用寿命。 + * 通过记录上次切换时间,可以强制两次切换之间必须间隔 + * 最小时间(RELAY_MIN_INTERVAL),防止频繁操作。 + * + * 单位说明: + * 毫秒(ms),与HAL_GetTick()返回值单位一致 + */ static uint32_t last_toggle_tick = 0; +/*============================================================================== + * 公共函数实现 + *============================================================================*/ +/** + * @brief 继电器模块初始化 + * @note 在系统启动时调用,复位继电器到安全初始状态 + * + * @param 无 + * @return 无 + * + * 功能说明: + * 1. 硬件控制引脚设置为低电平,强制确保继电器断开 + * 2. 重置状态变量为false + * 3. 重置切换时间戳为0 + * + * 初始化安全: + * - 此函数应尽早调用,确保系统启动时继电器处于受控状态 + * - 继电器初始状态设为OFF是考虑到故障安全(fail-safe)设计 + */ void Relay_Init(void) { + /*---------------------------------------------------------- + * 硬件层面:将继电器控制引脚设置为低电平 + * RL_Control_GPIO_Port和RL_Control_Pin定义在main.h或引脚配置中 + *----------------------------------------------------------*/ HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin, GPIO_PIN_RESET); + + /*---------------------------------------------------------- + * 软件层面:初始化继电器状态为OFF + *----------------------------------------------------------*/ current_state = false; + + /*---------------------------------------------------------- + * 重置切换保护相关计时器 + *----------------------------------------------------------*/ last_toggle_tick = 0; - + DEBUG_LOG("Init OK, state=OFF"); } +/** + * @brief 设置继电器状态 + * @note 核心控制函数,实现继电器开关操作及保护逻辑 + * + * @param state: 目标状态,false=关闭(OFF),true=打开(ON)(输入) + * @return 无 + * + * 功能说明: + * 1. 切换间隔保护检查(防频繁操作) + * 2. 状态变更判断(避免重复操作) + * 3. 硬件GPIO操作 + * 4. 状态记录和统计更新 + * + * 算法说明 - 切换间隔保护: + * if (current_tick - last_toggle_tick < RELAY_MIN_INTERVAL) + * return; // 切换过于频繁,直接丢弃 + * + * 这个检查确保两次继电器操作之间至少间隔RELAY_MIN_INTERVAL毫秒, + * 防止程序错误或通信干扰导致继电器被频繁开关。 + * + * 注意/异常: + * - 切换间隔太短时静默忽略,防抖处理 + * - 状态与当前相同时静默忽略,不重复操作 + */ void Relay_SetState(bool state) { + /*---------------------------------------------------------- + * 获取当前时间,判断与上次操作的时间间隔 + *----------------------------------------------------------*/ uint32_t current_tick = HAL_GetTick(); - + + /*---------------------------------------------------------- + * 切换间隔保护检查 + *----------------------------------------------------------*/ if (current_tick - last_toggle_tick < RELAY_MIN_INTERVAL) { DEBUG_LOG("Toggle too fast, ignored"); return; } - + + /*---------------------------------------------------------- + * 状态变更判断:避免重复设置相同状态 + *----------------------------------------------------------*/ if (current_state == state) { DEBUG_LOG("State unchanged: %s", state ? "ON" : "OFF"); return; } - - HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin, + + /*---------------------------------------------------------- + * 硬件控制:设置GPIO引脚电平 + *----------------------------------------------------------*/ + HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET); - + + /*---------------------------------------------------------- + * 更新软状态和记录切换时间 + *----------------------------------------------------------*/ current_state = state; last_toggle_tick = current_tick; - + DEBUG_LOG("Relay -> %s", state ? "ON" : "OFF"); } +/** + * @brief 获取继电器当前状态 + * @note 返回继电器的开关状态 + * + * @param 无 + * @return bool: 继电器状态,false=关闭(OFF),true=打开(ON) + * + * 使用示例: + * if (Relay_GetState()) { + * // 继电器当前处于闭合状态 + * } + */ bool Relay_GetState(void) { return current_state; diff --git a/Core/Src/uart3_passthrough.c b/Core/Src/uart3_passthrough.c new file mode 100644 index 0000000..cb056f3 --- /dev/null +++ b/Core/Src/uart3_passthrough.c @@ -0,0 +1,269 @@ +/** + ****************************************************************************** + * @file uart3_passthrough.c + * @brief UART3透传引擎模块实现 + * @author Application Layer + * @version 1.0 + ****************************************************************************** + * @attention + * 设计依据:UART3智能数据路由与透传功能开发计划 第3.2节 + * + * 功能说明: + * 本模块实现透传数据缓冲与发送功能,将UART3接收的透传数据转发至UART1 + * + * 工作流程(严格按文档3.2.3节伪代码实现): + * 1. 检查是否有待发送数据 + * 2. 检查UART1是否可发送 + * 3. 获取当前处理节点 + * 4. 发送一个字节 + * 5. 更新队列状态和统计 + * + * 发送机制: + * - 单字节每次发送,由UART1 TX完成中断驱动连续发送 + * - 使用独立环形缓冲区,避免与指令解析争用 + ****************************************************************************** + */ + +#include "uart3_passthrough.h" +#include "uart3_smart_router_config.h" +#include "multi_uart_router.h" +#include "uart2_print.h" +#include + +/*============================================================================== + * 调试宏定义 + *============================================================================*/ +#if DEBUG_PASSTHROUGH_ENGINE +#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[PTX] " fmt "\r\n", ##__VA_ARGS__) +#else +#define DEBUG_LOG(fmt, ...) +#endif + +/*============================================================================== + * 全局变量定义 + * 设计依据:文档第3.2.2节 + *============================================================================*/ +/** + * @brief 透传引擎全局上下文 + * @note 保存透传引擎全部状态信息 + */ +passthrough_context_t g_passthrough_ctx; + +/*============================================================================== + * 公共函数实现 + * 设计依据:文档第3.2.1节模块接口设计 + *============================================================================*/ +/** + * @brief 透传引擎初始化 + * @note 初始化透传队列和统计信息 + */ +void Passthrough_Init(void) +{ + memset(&g_passthrough_ctx, 0, sizeof(g_passthrough_ctx)); + + for (uint8_t i = 0; i < PASSTHROUGH_MAX_NODES; i++) { + g_passthrough_ctx.queue.nodes[i].valid = false; + g_passthrough_ctx.queue.nodes[i].length = 0; + g_passthrough_ctx.queue.nodes[i].offset = 0; + } + + g_passthrough_ctx.queue.write_index = 0; + g_passthrough_ctx.queue.read_index = 0; + g_passthrough_ctx.queue.pending_count = 0; + + g_passthrough_ctx.stats.total_bytes_sent = 0; + g_passthrough_ctx.stats.total_packets = 0; + g_passthrough_ctx.stats.overflow_count = 0; + g_passthrough_ctx.stats.busy_count = 0; + + g_passthrough_ctx.initialized = true; + + DEBUG_LOG("Passthrough engine initialized, buffer size: %d bytes", PASSTHROUGH_TOTAL_BUFFER); +} + +/** + * @brief 压入单字节到透传缓冲区 + * @note 将单个字节添加到透传发送队列 + * @param byte: 待发送字节 + * @retval bool: true=成功,false=缓冲区满 + */ +bool Passthrough_PushByte(uint8_t byte) +{ + passthrough_context_t *ctx = &g_passthrough_ctx; + + if (!ctx->initialized) { + return false; + } + + uint8_t next_index = (ctx->queue.write_index + 1) % PASSTHROUGH_MAX_NODES; + + if (next_index == ctx->queue.read_index && ctx->queue.pending_count > 0) { + ctx->stats.overflow_count++; + DEBUG_LOG("Buffer full, overflow count: %d", ctx->stats.overflow_count); + return false; + } + + passthrough_node_t *node = &ctx->queue.nodes[ctx->queue.write_index]; + + if (!node->valid || node->length >= PASSTHROUGH_NODE_SIZE) { + if (node->valid) { + ctx->queue.write_index = next_index; + node = &ctx->queue.nodes[ctx->queue.write_index]; + } + node->length = 0; + node->offset = 0; + node->valid = true; + } + + node->data[node->length++] = byte; + ctx->queue.pending_count++; + + return true; +} + +/** + * @brief 压入数据块到透传缓冲区 + * @note 将数据块添加到透传发送队列 + * @param data: 数据缓冲区指针 + * @param length: 数据长度 + * @retval uint16_t: 实际写入的字节数 + */ +uint16_t Passthrough_PushBuffer(const uint8_t *data, uint16_t length) +{ + if (data == NULL || length == 0) { + return 0; + } + + passthrough_context_t *ctx = &g_passthrough_ctx; + uint16_t written = 0; + + for (uint16_t i = 0; i < length; i++) { + uint8_t next_index = (ctx->queue.write_index + 1) % PASSTHROUGH_MAX_NODES; + + if (next_index == ctx->queue.read_index && ctx->queue.pending_count > 0) { + ctx->stats.overflow_count++; + DEBUG_LOG("Buffer overflow at byte %d/%d", i, length); + break; + } + + passthrough_node_t *node = &ctx->queue.nodes[ctx->queue.write_index]; + + if (!node->valid || node->length >= PASSTHROUGH_NODE_SIZE) { + if (node->valid) { + ctx->queue.write_index = next_index; + node = &ctx->queue.nodes[ctx->queue.write_index]; + } + node->length = 0; + node->offset = 0; + node->valid = true; + } + + node->data[node->length++] = data[i]; + ctx->queue.pending_count++; + written++; + } + + if (written > 0) { + ctx->stats.total_packets++; + DEBUG_LOG("Pushed %d bytes to buffer, pending: %d", written, ctx->queue.pending_count); + } + + return written; +} + +/** + * @brief 透传引擎任务 + * @note 在主循环中周期性调用,每次尝试发送一个字节 + * 配合UART1 TX完成中断实现连续发送 + */ +void Passthrough_Task(void) +{ + passthrough_context_t *ctx = &g_passthrough_ctx; + + if (!ctx->initialized) { + return; + } + + if (ctx->queue.pending_count == 0) { + return; + } + + if (!Passthrough_CanSend()) { + ctx->stats.busy_count++; + return; + } + + passthrough_node_t *node = &ctx->queue.nodes[ctx->queue.read_index]; + + if (!node->valid || node->offset >= node->length) { + if (node->valid) { + node->valid = false; + } + ctx->queue.read_index = (ctx->queue.read_index + 1) % PASSTHROUGH_MAX_NODES; + return; + } + + uint8_t byte = node->data[node->offset++]; + MultiUART_Send(PORT_UART1, &byte, 1); + + ctx->queue.pending_count--; + ctx->stats.total_bytes_sent++; + + DEBUG_LOG("Sent byte 0x%02X, pending: %d", byte, ctx->queue.pending_count); +} + +/** + * @brief UART1发送完成回调 + * @note 应在HAL_UART_TxCpltCallback中调用,触发下一次发送 + */ +void Passthrough_OnTxComplete(void) +{ + Passthrough_Task(); +} + +/** + * @brief 检查UART1是否可发送 + * @note 检查UART1发送缓冲区是否有空间 + * @retval bool: true=可发送,false=忙 + */ +bool Passthrough_CanSend(void) +{ + return (MultiUART_GetTxAvailable(PORT_UART1) > 0) && + (g_passthrough_ctx.queue.pending_count > 0); +} + +/** + * @brief 获取透传统计信息 + * @note 获取透传引擎的运行统计 + * @param stats: 统计结构指针 + */ +void Passthrough_GetStats(passthrough_stats_t *stats) +{ + if (stats != NULL) { + memcpy(stats, &g_passthrough_ctx.stats, sizeof(passthrough_stats_t)); + } +} + +/** + * @brief 重置统计信息 + * @note 清零所有统计计数器 + */ +void Passthrough_ResetStats(void) +{ + passthrough_context_t *ctx = &g_passthrough_ctx; + ctx->stats.total_bytes_sent = 0; + ctx->stats.total_packets = 0; + ctx->stats.overflow_count = 0; + ctx->stats.busy_count = 0; + DEBUG_LOG("Stats reset"); +} + +/** + * @brief 获取待发送字节数 + * @note 获取队列中等待发送的字节总数 + * @retval uint16_t: 待发送字节数 + */ +uint16_t Passthrough_GetPendingCount(void) +{ + return g_passthrough_ctx.queue.pending_count; +} \ No newline at end of file diff --git a/Core/Src/uart3_protocol_discriminator.c b/Core/Src/uart3_protocol_discriminator.c new file mode 100644 index 0000000..1f0eb56 --- /dev/null +++ b/Core/Src/uart3_protocol_discriminator.c @@ -0,0 +1,252 @@ +/** + ****************************************************************************** + * @file uart3_protocol_discriminator.c + * @brief UART3协议识别器模块实现 + * @author Application Layer + * @version 1.0 + ****************************************************************************** + * @attention + * 设计依据:UART3智能数据路由与透传功能开发计划 第3.1节 + * + * 功能说明: + * 本模块实现UART3协议识别器状态机,根据接收字节判断数据类型并路由 + * + * 状态转换逻辑(严格按文档3.1.2节伪代码实现): + * - INIT → SCAN: 收到任何字节(非'$') + * - SCAN → CMD_MODE: 收到'$' + * - SCAN → PASSTHROUGH: 超时(50ms)且有数据 或 收到'\n' + * - CMD_MODE → EXEC: 收到'\n'且帧解析完成 + * - CMD_MODE → SCAN: 收到'\r' + * - EXEC → SCAN: 指令执行完成 + * - PASSTHROUGH → SCAN: 透传数据全部发送完成 + ****************************************************************************** + */ + +#include "uart3_protocol_discriminator.h" +#include "uart3_smart_router_config.h" +#include "uart2_print.h" +#include + +/*============================================================================== + * 调试宏定义 + *============================================================================*/ +#if DEBUG_PROTOCOL_DISCRIMINATOR +#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[PROTO] " fmt "\r\n", ##__VA_ARGS__) +#else +#define DEBUG_LOG(fmt, ...) +#endif + +/*============================================================================== + * 全局变量定义 + * 设计依据:文档第3.1.2节伪代码 + *============================================================================*/ +/** + * @brief 协议识别器全局上下文 + * @note 保存状态机全部状态信息 + */ +uart3_protocol_context_t g_uart3_proto_ctx; + +/*============================================================================== + * 内部函数实现 + *============================================================================*/ +/** + * @brief 检查SCAN状态是否超时 + * @note 内部使用,判断是否需要触发透传 + * @param current_tick: 当前系统时间(ms) + * @retval bool: true=超时,false=未超时 + */ +static bool check_scan_timeout(uint32_t current_tick) +{ + uart3_protocol_context_t *ctx = &g_uart3_proto_ctx; + + if (ctx->state == STATE_SCAN && ctx->scan_length > 0) { + if (current_tick - ctx->scan_start_tick >= SCAN_TIMEOUT_MS) { + return true; + } + } + return false; +} + +/*============================================================================== + * 公共函数实现 + * 设计依据:文档第3.1.2节伪代码 + *============================================================================*/ +/** + * @brief 协议识别器初始化 + * @note 初始化状态机和上下文 + */ +void UART3_Protocol_Init(void) +{ + memset(&g_uart3_proto_ctx, 0, sizeof(g_uart3_proto_ctx)); + g_uart3_proto_ctx.state = STATE_INIT; + DEBUG_LOG("Protocol discriminator initialized"); +} + +/** + * @brief 协议识别器字节输入 + * @note 由UART3中断调用,判断字节应该走指令路径还是透传路径 + * @param byte: 接收字节 + * @param current_tick: 当前系统时间(ms) + * @retval route_result_t: 路由结果 + */ +route_result_t UART3_Protocol_FeedByte(uint8_t byte, uint32_t current_tick) +{ + uart3_protocol_context_t *ctx = &g_uart3_proto_ctx; + + if (ctx->state != STATE_INIT && ctx->state != STATE_SCAN && + ctx->state != STATE_CMD_MODE && ctx->state != STATE_PASSTHROUGH) { + ctx->state = STATE_INIT; + ctx->scan_length = 0; + DEBUG_LOG("Protocol state invalid(0x%02X), reset to INIT", ctx->state); + } + + DEBUG_LOG("FeedByte state=%d, byte=0x%02X", (int)ctx->state, byte); + + switch (ctx->state) { + case STATE_INIT: + ctx->last_byte_tick = current_tick; + if (byte == '$') { + ctx->state = STATE_CMD_MODE; + ctx->scan_length = 0; + DEBUG_LOG("INIT → CMD_MODE (got '$')"); + return ROUTE_CMD; + } else { + ctx->state = STATE_SCAN; + ctx->scan_start_tick = current_tick; + ctx->scan_buffer[0] = byte; + ctx->scan_length = 1; + DEBUG_LOG("INIT → SCAN (byte: 0x%02X)", byte); + return ROUTE_NONE; + } + + case STATE_SCAN: + ctx->last_byte_tick = current_tick; + + if (byte == '$') { + if (ctx->scan_length > 0) { + ctx->state = STATE_PASSTHROUGH; + DEBUG_LOG("SCAN → PASSTHROUGH (got '$', %d bytes)", ctx->scan_length); + return ROUTE_PASSTHROUGH; + } else { + ctx->state = STATE_CMD_MODE; + DEBUG_LOG("SCAN → CMD_MODE (empty scan, got '$')"); + return ROUTE_CMD; + } + } else if (byte == '\n') { + ctx->state = STATE_PASSTHROUGH; + DEBUG_LOG("SCAN → PASSTHROUGH (got '\\n', %d bytes)", ctx->scan_length); + return ROUTE_PASSTHROUGH; + } else { + if (ctx->scan_length < sizeof(ctx->scan_buffer)) { + ctx->scan_buffer[ctx->scan_length++] = byte; + } + return ROUTE_NONE; + } + + case STATE_CMD_MODE: + ctx->last_byte_tick = current_tick; + if (byte == '\n') { + ctx->state = STATE_INIT; + ctx->scan_length = 0; + DEBUG_LOG("CMD_MODE → INIT (got \\n)"); + return ROUTE_CMD; + } else if (byte == '\r') { + return ROUTE_CMD; + } else { + DEBUG_LOG("CMD_MODE → CMD (byte: 0x%02X)", byte); + return ROUTE_CMD; + } + + case STATE_PASSTHROUGH: + DEBUG_LOG("PASSTHROUGH → PTX (byte: 0x%02X)", byte); + ctx->last_byte_tick = current_tick; + return ROUTE_PASSTHROUGH; + + default: + ctx->state = STATE_INIT; + DEBUG_LOG("Unknown state, reset to INIT"); + return ROUTE_NONE; + } +} + +/** + * @brief 协议识别器超时检查 + * @note 定时调用,检查SCAN状态和CMD_MODE状态是否超时 + * @param current_tick: 当前系统时间(ms) + * @retval bool: true=触发了透传,false=继续等待 + */ +bool UART3_Protocol_CheckTimeout(uint32_t current_tick) +{ + uart3_protocol_context_t *ctx = &g_uart3_proto_ctx; + + if (ctx->state == STATE_SCAN && ctx->scan_length > 0) { + if (current_tick - ctx->scan_start_tick >= SCAN_TIMEOUT_MS) { + ctx->state = STATE_PASSTHROUGH; + DEBUG_LOG("SCAN timeout → PASSTHROUGH (%d ms)", SCAN_TIMEOUT_MS); + return true; + } + } + + if (ctx->state == STATE_CMD_MODE) { + if (current_tick - ctx->last_byte_tick >= CMD_COMPLETE_TIMEOUT_MS) { + ctx->state = STATE_INIT; + ctx->scan_length = 0; + DEBUG_LOG("CMD_MODE timeout → INIT (%d ms)", CMD_COMPLETE_TIMEOUT_MS); + return true; + } + } + + return false; +} + +/** + * @brief 获取透传模式下的缓存数据 + * @note 在触发透传后调用,获取待发送的透传数据 + * @param buffer: 输出缓冲区指针 + * @param length: 数据长度指针(输出) + * @retval bool: true=有数据,false=无数据 + */ +bool UART3_Protocol_GetPassthroughData(uint8_t *buffer, uint16_t *length) +{ + uart3_protocol_context_t *ctx = &g_uart3_proto_ctx; + + if (ctx->state == STATE_PASSTHROUGH && ctx->scan_length > 0) { + if (buffer != NULL && length != NULL) { + memcpy(buffer, ctx->scan_buffer, ctx->scan_length); + *length = ctx->scan_length; + } + ctx->scan_length = 0; + ctx->state = STATE_INIT; + DEBUG_LOG("GetPassthroughData: %d bytes, back to INIT", *length); + return true; + } + return false; +} + +/** + * @brief 获取当前协议识别状态 + * @note 用于调试和状态监控 + * @param 无 + * @retval uint8_t: 当前状态码 + */ +uint8_t UART3_Protocol_GetState(void) +{ + return (uint8_t)g_uart3_proto_ctx.state; +} + +/** + * @brief 重置协议识别器状态 + * @note 将状态机恢复到INIT状态 + * @param 无 + * @retval 无 + */ +void UART3_Protocol_Reset(void) +{ + uart3_protocol_context_t *ctx = &g_uart3_proto_ctx; + ctx->state = STATE_INIT; + ctx->scan_length = 0; + ctx->last_byte_tick = 0; + ctx->scan_start_tick = 0; + ctx->pending_cmd = false; + DEBUG_LOG("Protocol discriminator reset"); +} \ No newline at end of file diff --git a/MDK-ARM/project.uvguix.xtell b/MDK-ARM/project.uvguix.xtell index 1f90a85..b5677f2 100644 --- a/MDK-ARM/project.uvguix.xtell +++ b/MDK-ARM/project.uvguix.xtell @@ -110,8 +110,8 @@ 0 - 1513 - 0100000004000000010000000100000001000000010000000000000002000000000000000100000001000000000000002800000028000000010000000D00000000000000010000003A433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C6D61696E2E6300000000066D61696E2E6300000000C5D4F200FFFFFFFF4A433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4472697665725F52463433335C496E635C72663433335F636F6E6669672E68000000000E72663433335F636F6E6669672E6800000000FFDC7800FFFFFFFF42433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C72663433335F72785F6170702E63000000000E72663433335F72785F6170702E6300000000BECEA100FFFFFFFF42433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C72663433335F74785F6170702E63000000000E72663433335F74785F6170702E6300000000F0A0A100FFFFFFFF3B433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C75736172742E63000000000775736172742E6300000000BCA8E100FFFFFFFF48433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4D444B2D41524D5C737461727475705F73746D33326631303378622E730000000015737461727475705F73746D33326631303378622E73000000009CC1B600FFFFFFFF5B433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C2E63000000000F73746D3332663178785F68616C2E6300000000F7B88600FFFFFFFF3A433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C6770696F2E6300000000066770696F2E6300000000D9ADC200FFFFFFFF60433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F6770696F2E63000000001473746D3332663178785F68616C5F6770696F2E6300000000A5C2D700FFFFFFFF47433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4472697665725F52463433335C496E635C72663433335F68616C2E68000000000B72663433335F68616C2E6800000000B3A6BE00FFFFFFFF41433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C75617274325F7072696E742E63000000000D75617274325F7072696E742E6300000000EAD6A300FFFFFFFF43433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4472697665725F52463433335C5372635C72663433332E63000000000772663433332E6300000000F6FA7D00FFFFFFFF60433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F756172742E63000000001473746D3332663178785F68616C5F756172742E6300000000B5E99D00FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000F400000066000000800700000C030000 + 1715 + 0100000004000000010000000100000001000000010000000000000002000000000000000100000001000000000000002800000028000000010000000F00000000000000010000003A433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C6D61696E2E6300000000066D61696E2E6300000000C5D4F200FFFFFFFF4A433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4472697665725F52463433335C496E635C72663433335F636F6E6669672E68000000000E72663433335F636F6E6669672E6800000000FFDC7800FFFFFFFF42433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C72663433335F72785F6170702E63000000000E72663433335F72785F6170702E6300000000BECEA100FFFFFFFF42433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C72663433335F74785F6170702E63000000000E72663433335F74785F6170702E6300000000F0A0A100FFFFFFFF3B433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C75736172742E63000000000775736172742E6300000000BCA8E100FFFFFFFF48433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4D444B2D41524D5C737461727475705F73746D33326631303378622E730000000015737461727475705F73746D33326631303378622E73000000009CC1B600FFFFFFFF5B433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C2E63000000000F73746D3332663178785F68616C2E6300000000F7B88600FFFFFFFF3A433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C6770696F2E6300000000066770696F2E6300000000D9ADC200FFFFFFFF60433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F6770696F2E63000000001473746D3332663178785F68616C5F6770696F2E6300000000A5C2D700FFFFFFFF47433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4472697665725F52463433335C496E635C72663433335F68616C2E68000000000B72663433335F68616C2E6800000000B3A6BE00FFFFFFFF41433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C75617274325F7072696E742E63000000000D75617274325F7072696E742E6300000000EAD6A300FFFFFFFF43433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C4472697665725F52463433335C5372635C72663433332E63000000000772663433332E6300000000F6FA7D00FFFFFFFF60433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F756172742E63000000001473746D3332663178785F68616C5F756172742E6300000000B5E99D00FFFFFFFF47433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C6D756C74695F756172745F726F757465722E6300000000136D756C74695F756172745F726F757465722E63000000005FC3CF00FFFFFFFF40433A5C776F726B66696C655C4533322D3433335C736F6674776172655C4533322D3433335442482D53435C436F72655C5372635C636D645F726F757465722E63000000000C636D645F726F757465722E6300000000C1838300FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000F40000006600000080070000ED020000 @@ -150,7 +150,7 @@ 0 16 - 0300000066000000ED000000DC020000 + 0300000066000000ED000000BD020000 16 @@ -170,7 +170,7 @@ 0 16 - 0300000066000000ED000000DC020000 + 0300000066000000ED000000BD020000 16 @@ -450,7 +450,7 @@ 0 16 - 0300000066000000ED000000DC020000 + 0300000066000000ED000000BD020000 16 @@ -470,7 +470,7 @@ 0 16 - 0300000066000000ED000000DC020000 + 0300000066000000ED000000BD020000 16 @@ -490,7 +490,7 @@ 0 16 - 000000000D03000080070000E6030000 + 00000000EE02000080070000E6030000 16 @@ -530,7 +530,7 @@ 0 16 - 03000000100300008D05000070030000 + 03000000F10200008D05000051030000 16 @@ -1170,7 +1170,7 @@ 0 16 - 000000000D0300009005000089030000 + 00000000EE020000900500006A030000 16 @@ -1190,7 +1190,7 @@ 0 16 - 03000000100300008D05000070030000 + 03000000F10200008D05000051030000 16 @@ -1250,7 +1250,7 @@ 0 16 - 03000000100300008D05000070030000 + 03000000F10200008D05000051030000 16 @@ -1270,7 +1270,7 @@ 0 16 - 03000000100300008D05000070030000 + 03000000F10200008D05000051030000 16 @@ -1799,7 +1799,7 @@ 3312 - 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFFF4000000DF00000090050000E3000000000000000100001004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E650020000000000000F200000009010000BA03000099010000F40000004F00000090050000DF0000000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF9C0400004F000000A004000029020000000000000200001004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000F200000009010000E2010000D4010000A00400004F000000900500002902000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFFF00000004F000000F4000000F5020000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C40000007394000001800010000001000000F200000009010000E2010000D4010000000000004F000000F0000000F50200000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF0000000015020000900500001902000000000000010000100400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB09000001800080000000000000F200000009010000E2010000D4010000000000001902000090050000BD02000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC802000019020000CC020000BD02000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF00000000F502000080070000F90200000100000001000010040000000100000002FDFFFF8E000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF0100007794000001800080000001000000F200000009010000BA0300009901000000000000F902000080070000E60300000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFFF4000000DF00000090050000E3000000000000000100001004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E650020000000000000F200000009010000BA03000099010000F40000004F00000090050000DF0000000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF9C0400004F000000A004000029020000000000000200001004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000F200000009010000E2010000D4010000A00400004F000000900500002902000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFFF00000004F000000F4000000D6020000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C40000007394000001800010000001000000F200000009010000E2010000D4010000000000004F000000F0000000D60200000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF0000000015020000900500001902000000000000010000100400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB09000001800080000000000000F200000009010000E2010000D4010000000000001902000090050000BD02000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC802000019020000CC020000BD02000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF00000000D602000080070000DA020000010000000100001004000000010000005FFDFFFFEB000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF0100007794000001800080000001000000F200000009010000BA0300009901000000000000DA02000080070000E60300000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 59392 @@ -1822,7 +1822,7 @@ Build 974 - 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000002001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050000000000770726F6A656374960000000000000001000770726F6A656374000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64FF7F0000 + 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050000000000770726F6A656374960000000000000001000770726F6A656374000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64FF7F0000 583 @@ -3606,9 +3606,9 @@ 0 ../Core/Src/main.c - 0 - 1 - 24 + 6 + 130 + 149 1 0 @@ -3721,6 +3721,24 @@ 0 + + ..\Core\Src\multi_uart_router.c + 40 + 245 + 277 + 1 + + 0 + + + ..\Core\Src\cmd_router.c + 48 + 255 + 284 + 1 + + 0 + diff --git a/MDK-ARM/project.uvoptx b/MDK-ARM/project.uvoptx index 1a57d77..7ec84b0 100644 --- a/MDK-ARM/project.uvoptx +++ b/MDK-ARM/project.uvoptx @@ -441,6 +441,30 @@ 0 0 + + 2 + 18 + 1 + 0 + 0 + 0 + ..\Core\Src\uart3_passthrough.c + uart3_passthrough.c + 0 + 0 + + + 2 + 19 + 1 + 0 + 0 + 0 + ..\Core\Src\uart3_protocol_discriminator.c + uart3_protocol_discriminator.c + 0 + 0 + @@ -451,7 +475,7 @@ 0 3 - 18 + 20 1 0 0 @@ -463,7 +487,7 @@ 3 - 19 + 21 1 0 0 @@ -475,7 +499,7 @@ 3 - 20 + 22 1 0 0 @@ -487,7 +511,7 @@ 3 - 21 + 23 1 0 0 @@ -499,7 +523,7 @@ 3 - 22 + 24 1 0 0 @@ -511,7 +535,7 @@ 3 - 23 + 25 1 0 0 @@ -523,7 +547,7 @@ 3 - 24 + 26 1 0 0 @@ -535,7 +559,7 @@ 3 - 25 + 27 1 0 0 @@ -547,7 +571,7 @@ 3 - 26 + 28 1 0 0 @@ -559,7 +583,7 @@ 3 - 27 + 29 1 0 0 @@ -571,7 +595,7 @@ 3 - 28 + 30 1 0 0 @@ -583,7 +607,7 @@ 3 - 29 + 31 1 0 0 @@ -595,7 +619,7 @@ 3 - 30 + 32 1 0 0 @@ -607,7 +631,7 @@ 3 - 31 + 33 1 0 0 @@ -619,7 +643,7 @@ 3 - 32 + 34 1 0 0 @@ -639,7 +663,7 @@ 0 4 - 33 + 35 1 0 0 @@ -659,7 +683,7 @@ 0 5 - 34 + 36 1 0 0 @@ -671,7 +695,7 @@ 5 - 35 + 37 1 0 0 @@ -683,7 +707,7 @@ 5 - 36 + 38 5 0 0 @@ -695,7 +719,7 @@ 5 - 37 + 39 5 0 0 @@ -707,7 +731,7 @@ 5 - 38 + 40 5 0 0 diff --git a/MDK-ARM/project.uvprojx b/MDK-ARM/project.uvprojx index 6dd1de9..4af2b1a 100644 --- a/MDK-ARM/project.uvprojx +++ b/MDK-ARM/project.uvprojx @@ -525,6 +525,16 @@ 1 ..\Core\Src\multi_uart_router.c + + uart3_passthrough.c + 1 + ..\Core\Src\uart3_passthrough.c + + + uart3_protocol_discriminator.c + 1 + ..\Core\Src\uart3_protocol_discriminator.c + diff --git a/MDK-ARM/project/cmd_parser.crf b/MDK-ARM/project/cmd_parser.crf index b9ad2556834e68a3b70fc3edcc0477a2d129b43e..53ab579e18a7fc807e49a43be74daacbbc04abaa 100644 GIT binary patch delta 95 zcmaF3oAKdp#tB;dyD!W<$Ho8zYj0XIFzHTy$fz+fF&iNq2oqMH%)}Up5ch(Kt4*H3 P_>c>3jNImGrnG1PW6~f? delta 95 zcmaF3oAKdp#tB;dAKuP5$Ho8zF*hw4m~c>3%-PM=Oli>olFA}W diff --git a/MDK-ARM/project/cmd_parser.o b/MDK-ARM/project/cmd_parser.o index 78d5f54ffe622eb4599c51242298510dc69129bb..d06261d5eb36393b943ce5e69a29ae4aef929993 100644 GIT binary patch delta 22 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 L`|S8{N|yZ}=5LUj delta 3384 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 diff --git a/MDK-ARM/project/debug_log.crf b/MDK-ARM/project/debug_log.crf index c3b6aa9130ffff6f6ce6cdc9e3461eae059c85dd..6a0a73369ef6dd91916e2a7cbd23e9424f3a3780 100644 GIT binary patch delta 58 xcmdm#wkd6bCfBYDGtaRx0D;D2K}PL~ak*T(VIqMbkx7h85o%^`UeDNU2mn$m6H5R9 delta 58 vcmdm#wkd6bCfA3zGtRLw0Kv7%f{fY|<8l!q3?Pw7j7t$B?wi*$HX8x}gm)B6 diff --git a/MDK-ARM/project/debug_log.o b/MDK-ARM/project/debug_log.o index 1df2d4894c1d9d6f1003700b9cca35bc7ad2d3e9..f33fd02de957332f8c84f9d7eb686a7e1f4418c1 100644 GIT binary patch delta 22 ecmX@|i1ElH#to;$*e$J0jjT*8HeVDgjsgI1K?uzN delta 22 ecmX@|i1ElH#to;$*v+hrOsxz|H(wMhjsgI0>jdz diff --git a/MDK-ARM/project/io_monitor.crf b/MDK-ARM/project/io_monitor.crf index d8f083eab79543bfd701f653ae0f3fd24e9c3aa4..5f8c73052efdf549dbca8b538e8bd4683a2fc1b9 100644 GIT binary patch delta 1468 zcmZ`(eQ1?c7(dTBcX#*R(6!BS=8~iKB#L1~l0qM|B7y=lFodA3{s<4)hh?i~`Cc1i z3?YJ%6!cfMMd~Fa@MTxUcHNwAyL#&HrOZYPhBlE3zkvS~h5ivP2y$hyKyu60Fx?pC+ zn-%l5$x>5z|I*~v#hLDT;?J;ylbcM?iNTa#tah2(E$>A30c1SnE7WVI+6I1=dY$Sm zZ^yulY;sKIPm9T7B7Xz(g3qWo=x)n7(900KNh>V(Bbf6wYB#O1)P&S#pa%w2 z)7ZbjzE3-{Gz_*y9Gu*GuzRI|0@x3tN_vbv;nV8FL{*l;Q)`p;w5%j&8x<4naZt{7 z0%oH9`nqIzeO=}Fg|r-C5-Ahm*p14)b(uLymrMULY^+UPUSA=1+YvT2q`pXI24t`Z z(-KZUmAW@kF#`XNu=<(QF^c^0aQNBO0Ui9`&RwYc2gi@tJ@`1ijvuu=N3tKi0;1sf zu?3>ZuTZBQHwdA5za~Bh3~9|}{O>n3?eA25j<;BD1=$PqW8jQ7Wgpb2e#ehnOw)V{ zY(eWQ_-tn!KVi8IWKkPFWaye-q6Qp48EfID952LqU-WmWvyQi0zDWr%iTOQc&LJ#x z&hg8ZJFrj=s~^>R4CJ8Wofb;d9F)L*YV=vKLyns*u9$cVIBxU4sa1-7aKaj9oN~<%=kIxxY>Q=%R@^qWS>gPjPqzA*A-R zT%%9`?2B7l)>^fHa@M2)zn+#6@ckfGx!(Pl5gQKkTGmt1dY{jTItM4B(yy z0TBlm19&6AC@@8dKTyD^<31!0;#(F8_g<^U9Ht5*l8R6U>m6Fs0@9iW_fPlu)#|c? z7fVC*A`nFgT7foAjo4${akrL^4dk29M!!@|I5f8fq{$6FCE>p4LBBywIz(2a7eQ3g z3lxA@NArS1X`1%=hQu?KwcUnD#j>nL+&*v-44+ZA2hTZ%NbO!c6e(nG$d_IvzHP|X|?Jf DJL|8R delta 1468 zcmZ`(ZHSar6u#%)cix?u&~aDMsa@r2oHoU=iJZt zIk%@cyQesNQ-ALF;f{e&$?xFuH({0%a{^st*bfhMG;_9`!&tJ}G+VdF# zG+=-LNX7X~xO-A_feOT8>iwf?8gG&?G4G3)m`?Gwi7ATNJz@5W_lbr%Ibnvy`%TQ- zra(b_>x}T>$=Qx^A{W2P;X)I&AvxVoRx8aE%PUZQ6>}Z(DfN`8wUM8ro~8!NOOP0r zMLv@8Lt_3A^Daiu^jXzHGc9ig(}>_1nq@ggFv-`cRn%zd36!<~+fklF#j~^k(XV7H z5u(+!5Yb!O*7;Dap{4>|1pAygIFGIPoO+%fKv0k+hqY}*-CBC2K&Mdmf;ik}YykE} zT3Vofu&v_YRPE8kJzBHJ|A?kL{B-q&Uoc`M^hYs@L&77Q-~}1iMS? zH}KgGIlkBO7|4<~yv5L)ewzBy@qJY-T$1B`jPtJbH>ir^C6+Hy045k;Q^u^qL|-|6 z((+%JXe(y#)VdAiVaF>hl%_c$;2{K^4LrYpfTGQbE>2ZIfI_uz7 zr6GC|h#~}6fH9)uSmT`I4lNxU$v2^9KSO=%(A*Y~CO7z$g!`gazd(KG5LuC40#Qjf zunVZ_Xk2gvu~6REtM45u?KM69o5g&~vG@;8+8VD2v0tgF3)Fdsr^@mu79P{I6x;dH z;f1k)yfj8sj4U;v_9rLZ4$%;AH1r;rpPh6%9wQRfEdz7G;jOXIkhC#14h2eSHRm6H CHK~~Z diff --git a/MDK-ARM/project/io_monitor.o b/MDK-ARM/project/io_monitor.o index 72d9960569383cb591db46561324f311480520fe..177ab06c375933cbfd7f1f1f85e360f89a30ab5f 100644 GIT binary patch delta 561 zcmYMuO=uHA6bJBmJK0SpO?S1I#CJ#bz>9(buUZcxVl9Xi^xzv4@bKq9?>8Szxj9g74s32{ z(PW7&57pqw@J!!~DPL%_(%`0-;vx*LHyAwzQ1>o&=79g!gnZU-d5^kufIaW=z7Bwj zSL?O`w!Ke15dbN7VqbZchvjM}DS!3u@GWl0%}h!L;uUb^M%;!~xnP}wx=fh|I=Nwt z7%?Mb#AtO;PMhc9k6bsez@Cg)2o+hi-oUoJnz&3)zfCM^RW4T&mtc#AKJR(*yB5ql zM~^rY$8Wmn+in^t8ii8=6rEyFg1(y$UGszE6Jv{`<4l5`_vf3TB@z^k3;ef{e}L=p?;Z zz+KwcABGs4ZpjBcSs)n_jGb%Ab$p=YB}w~M1V1X73oBVuKU>GKDUmZu9gJCk_Z^Xe zdAy;h9A(UIQv=^A`qIT%q)k7u{{+$D9>xM~vT;RGw)g)j8|y@RHqKZ9*NP&G-9?(; N(|pUHDvApue*u2zoC5#= delta 600 zcmY+MVZ*J>)3(jj641rfwQG(rbKJGnTd zh`5NLKbn`JLxUX}i;!~4;V38wX3*iFg9vUCYo+4Qp@Y9)Oo<)7JboYE@9|#68>n~# z^%W^}U=n6CYxv^mME``rUQ2nlBPE@uyMs*@Gzb^ivhfi;b~k>V&-@ghk;*cgi(kW4{^)mJB{n7hkbQd4wgw;6 zQjcmW(J`45TNv zZeo$<1ucdEtTr|1v!IP`fMA=p>F_yDRxg0BO<9@~lPTs8R`ryPPi oYw|x%Sp-+3S(U3@m5ULGnShuXh*^M`6^Pk@n0>n{7YAz*07>#F)Bpeg delta 132 zcmZ4WLvhs)#SPCmxIVm{agL1v1SWsrXhLvfCf9H(BDg;%FXvQ6a5W}hFv10szy2D%1b~ diff --git a/MDK-ARM/project/main.o b/MDK-ARM/project/main.o index 06cee4520488fc959314fdd5f783406829aba280..b8a89f078454b38e8efecd1b9beca1b73812f654 100644 GIT binary patch delta 76 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 diff --git a/MDK-ARM/project/multi_uart_router.o b/MDK-ARM/project/multi_uart_router.o index c65edaf09b413ae6db4224838e1f14bc265790c4..3112f787c34a65bbabeb89969da1084fb2195ee5 100644 GIT binary patch delta 5059 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 S*hT#a+P{CMi)YMl<9`9~6W;m& delta 5018 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 zan3?1@bscan_length); +..\Core\Src\uart3_protocol_discriminator.c(132): warning: #870-D: invalid multibyte character sequence + DEBUG_LOG("SCAN ? CMD_MODE (empty scan, got '$')"); +..\Core\Src\uart3_protocol_discriminator.c(137): warning: #870-D: invalid multibyte character sequence + DEBUG_LOG("SCAN ? PASSTHROUGH (got '\\n', %d bytes)", ctx->scan_length); +..\Core\Src\uart3_protocol_discriminator.c(151): warning: #870-D: invalid multibyte character sequence + DEBUG_LOG("CMD_MODE ? INIT (got \\n)"); +..\Core\Src\uart3_protocol_discriminator.c(156): warning: #870-D: invalid multibyte character sequence + DEBUG_LOG("CMD_MODE ? CMD (byte: 0x%02X)", byte); +..\Core\Src\uart3_protocol_discriminator.c(161): warning: #870-D: invalid multibyte character sequence + DEBUG_LOG("PASSTHROUGH ? PTX (byte: 0x%02X)", byte); +..\Core\Src\uart3_protocol_discriminator.c(185): warning: #870-D: invalid multibyte character sequence + DEBUG_LOG("SCAN timeout ? PASSTHROUGH (%d ms)", SCAN_TIMEOUT_MS); +..\Core\Src\uart3_protocol_discriminator.c(194): warning: #870-D: invalid multibyte character sequence + DEBUG_LOG("CMD_MODE timeout ? INIT (%d ms)", CMD_COMPLETE_TIMEOUT_MS); +..\Core\Src\uart3_protocol_discriminator.c(252): warning: #1-D: last line of file ends without a newline + } +..\Core\Src\uart3_protocol_discriminator.c(58): warning: #177-D: function "check_scan_timeout" was declared but never referenced + static bool check_scan_timeout(uint32_t current_tick) +..\Core\Src\uart3_protocol_discriminator.c: 14 warnings, 0 errors +compiling relay_control.c... compiling uart2_print.c... -compiling stm32f1xx_it.c... compiling stm32f1xx_hal_rcc_ex.c... -compiling stm32f1xx_hal_dma.c... compiling stm32f1xx_hal_gpio_ex.c... compiling stm32f1xx_hal.c... compiling stm32f1xx_hal_gpio.c... +compiling uart3_passthrough.c... +../Core/Inc/uart3_passthrough.h(207): warning: #1-D: last line of file ends without a newline + #endif +../Core/Inc/uart3_smart_router_config.h(143): warning: #1-D: last line of file ends without a newline + #endif +..\Core\Src\uart3_passthrough.c(269): warning: #1-D: last line of file ends without a newline + } +..\Core\Src\uart3_passthrough.c: 3 warnings, 0 errors compiling stm32f1xx_hal_rcc.c... compiling stm32f1xx_hal_spi.c... -compiling stm32f1xx_hal_cortex.c... -compiling stm32f1xx_hal_flash.c... -compiling stm32f1xx_hal_pwr.c... compiling stm32f1xx_hal_flash_ex.c... compiling stm32f1xx_hal_tim.c... -compiling stm32f1xx_hal_tim_ex.c... +compiling stm32f1xx_hal_cortex.c... +compiling stm32f1xx_hal_flash.c... compiling stm32f1xx_hal_exti.c... +compiling stm32f1xx_hal_pwr.c... +compiling stm32f1xx_hal_dma.c... compiling system_stm32f1xx.c... compiling rf433.c... ..\Driver_RF433\Src\rf433.c(209): warning: #188-D: enumerated type mixed with another type @@ -94,11 +135,12 @@ compiling rf433.c... static bool rf433_response_command_check(rf433_request_cmd_t cmd, uint8_t *buffer, uint8_t length) ..\Driver_RF433\Src\rf433.c: 4 warnings, 0 errors compiling rf433_hal.c... +compiling stm32f1xx_hal_tim_ex.c... compiling stm32f1xx_hal_uart.c... linking... -Program Size: Code=21148 RO-data=572 RW-data=192 ZI-data=5808 +Program Size: Code=23672 RO-data=572 RW-data=192 ZI-data=6520 FromELF: creating hex file... -"project\project.axf" - 0 Error(s), 14 Warning(s). +"project\project.axf" - 0 Error(s), 33 Warning(s).

Software Packages used:

@@ -122,7 +164,7 @@ Package Vendor: Keil * Component: ARM::CMSIS:CORE@6.1.1 Include file: CMSIS/Core/Include/tz_context.h -Build Time Elapsed: 00:00:15 +Build Time Elapsed: 00:00:17 diff --git a/MDK-ARM/project/project.hex b/MDK-ARM/project/project.hex index e5e3f36..6a81db6 100644 --- a/MDK-ARM/project/project.hex +++ b/MDK-ARM/project/project.hex @@ -1,8 +1,8 @@ :020000040800F2 -:100000007017002005010008D92E0008C528000837 -:100010000D2C0008750D0008D13600080000000006 -:100020000000000000000000000000002530000873 -:10003000B113000800000000DD2E00082730000882 +:10000000381A00200501000811300008D129000825 +:10001000192D0008750D0008B1400008000000000F +:10002000000000000000000000000000593500083A +:10003000BD14000800000000113400085B35000802 :100040001F0100081F0100081F0100081F01000810 :100050001F0100081F0100081F0100081F01000800 :100060001F0100081F0100081F0100081F010008F0 @@ -12,14 +12,14 @@ :1000A0001F0100081F0100081F0100081F010008B0 :1000B0001F0100081F0100081F0100081F010008A0 :1000C0001F0100081F0100081F0100081F01000890 -:1000D0001F010008A1360008B1360008C13600082B +:1000D0001F0100088140000891400008A14000086D :1000E0001F0100081F0100081F010008DFF810D0E1 -:1000F00000F0C8FB00480047E1430008AFF3008070 -:10010000701700200648804706480047FEE7FEE7D4 +:1000F00000F0C8FB00480047C14D0008AFF3008086 +:10010000381A00200648804706480047FEE7FEE709 :10011000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE7B7 -:1001200099300008ED000008202A04DB203A21FA6B +:10012000CD350008ED000008202A04DB203A21FA32 :1001300002F00021704721FA02F3D040C2F1200200 -:100140009140084319467047004870477C540008A6 +:10014000914008431946704700487047585E0008C0 :1001500010B50446FFF7F8FF0068005D00F00100ED :1001600010BD40EA01039B0703D009E008C9121F34 :1001700008C0042AFAD203E011F8013B00F8013B61 @@ -54,7 +54,7 @@ :10034000220501D5087015E0220701D5088011E0CB :1003500008600FE02868011D29600068210502D5AA :1003600080F8008006E0210702D5A0F8008001E0B7 -:10037000C0F8008038467EE770B5064603F00AFAFA +:10037000C0F8008038467EE770B5064603F0FAFE06 :10038000046805460A220021304600F08BF82C60F4 :1003900070BD30B50B46014600202022012409E043 :1003A00021FA02F59D4205D303FA02F5491B04FA2E @@ -78,8 +78,8 @@ :1004C000C007F6D12B2D02D02D2D18D0641E4A4620 :1004D0003946204600F0A2FB27B13968A14201D17C :1004E000C7F8008071054FF002040BD54042002888 -:1004F00003DD03F04FF90460A007BDE8F08746F480 -:100500008066E4E70028F8DA03F044F904606FF04D +:1004F00003DD03F03FFE0460A007BDE8F08746F48B +:100500008066E4E70028F8DA03F034FE04606FF058 :100510000040F2E72DE9FE4F804681EA0300C00F5C :100520000C46009021F0004123F00045B8EB02009A :10053000A94105D24046214690461C460B4602463C @@ -137,7 +137,7 @@ :100870001C464FF00043524263EB0403994208BF09 :10088000904230BD064C074D06E0E06840F00103A1 :1008900094E8070098471034AC42F6D3FFF72AFCDF -:1008A000B8540008D8540008202A04DB203A00FA83 +:1008A000945E0008B45E0008202A04DB203A00FAB7 :1008B00002F1002070479140C2F1200320FA03F3B7 :1008C000194390407047202A06DBCB17203A41FAA3 :1008D00002F043EAE07306E041FA02F3D040C2F1CD @@ -201,7 +201,7 @@ :100C700001EB10461FFA80F8B6F5803F00D3B94665 :100C800014F8010B2946FFF7CBFB0028EBDABBF188 :100C9000000F05D00FB1641E00E05446CBF80040B1 -:100CA000B9F1000F06D002F075FD02210160C81EE7 +:100CA000B9F1000F06D003F065FA02210160C81EF9 :100CB000BDE8F09F48EA0640FAE710B5141E73F14C :100CC000000408DA401C41F1000192185B411A430C :100CD00001D120F0010010BD2DE9F04D92469B4658 @@ -217,48 +217,48 @@ :100D7000F04DA2E700BFFEE770B504460D46B5484A :100D80000078C8B1B3480078052815D0B148406D47 :100D9000281AB0F57A7F0FD3AE48806D401CAD495C -:100DA0008865ADA002F0A2F903F066FD242C02D103 +:100DA0008865ADA002F03CFC04F056FA242C02D178 :100DB0000120A849087070BDA6484565007806283E :100DC0000BD2DFE800F0030B57A4E2F9242C04D186 -:100DD00003F052FD01209F49087037E12C2C0CD103 +:100DD00004F042FA01209F49087037E12C2C0CD115 :100DE00000219C4890F84E20401C815402209949D3 :100DF0000870002081F84E003BE02A2C0ED1002123 :100E0000944890F84E20401C815404209149087069 :100E1000002081F84E0081F852002AE0204603F0BD -:100E2000B9FAF8B18B4890F84E00072812DA8948D1 +:100E2000A9FFF8B18B4890F84E00072812DA8948DC :100E300090F84E1090F84E00401C864A82F84E0002 :100E4000501C4454401E90F84F006040114681F8F9 -:100E50004F000EE07F48806D401C7E49886503F09E -:100E60000BFD06E07B48806D401C7A49886503F0E5 -:100E700003FDEBE02C2C0CD10021764890F84E209D +:100E50004F000EE07F48806D401C7E49886504F09D +:100E6000FBF906E07B48806D401C7A49886504F0F8 +:100E7000F3F9EBE02C2C0CD10021764890F84E20B1 :100E800009308154032073490870002081F84E0016 :100E90003CE02A2C0ED100216E4890F84E200930FB :100EA000815404206B490870002081F84E0081F8BD -:100EB00052002BE0204603F080FA00B3654890F81A +:100EB00052002BE0204603F070FF00B3654890F825 :100EC0004E001F2813DA634890F84E1090F84E0039 :100ED000401C604A82F84E0002F10900445409386F :100EE00090F84F006040114681F84F000EE05948DD -:100EF000806D401C5749886503F0BEFC06E05548EC -:100F0000806D401C5349886503F0B6FC9EE02A2C96 +:100EF000806D401C5749886504F0AEF906E05548FE +:100F0000806D401C5349886504F0A6F99EE02A2CA8 :100F10000ED100214F4890F84E20293081540420F2 :100F20004C490870002081F84E0081F852002BE0F7 -:100F3000204603F042FA00B3464890F84E001F28BE +:100F3000204603F032FF00B3464890F84E001F28C9 :100F400013DA444890F84E1090F84E00401C414A85 :100F500082F84E0002F129004454293890F84F00DD :100F60006040114681F84F000EE03A48806D401C09 -:100F70003849886503F080FC06E03648806D401CE7 -:100F80003449886503F078FC60E00A2C42D1314A8C -:100F900092F8511092F8500003F08BF92D4981F826 +:100F70003849886504F070F906E03648806D401CF9 +:100F80003449886504F068F960E00A2C42D1314A9E +:100F900092F8511092F8500003F07BFE2D4981F831 :100FA0004900084690F84F1080F84A1090F8490020 :100FB000FF2802D1012101E040E00021254880F80E :100FC0004D1090F84D0030B9224890F8491090F833 :100FD0004A0081420BD101211E4880F84C100520A7 :100FE0001C4908700846C06D401CC86525E01948BA :100FF000806D401C17498865084690F84A2090F893 -:1010000049101DA002F072F826A004F07DF803F04C -:1010100033FC12E00D2C10D00E4890F8520002283C +:1010000049101DA002F00CFB26A004F06BFD04F0BB +:1010100023F912E00D2C10D00E4890F8520002284F :101020000BDA0C4890F8521090F85200401C094A14 -:1010300082F8520002F15000445407E003F01CFC17 +:1010300082F8520002F15000445407E004F00CF929 :10104000242C02D101200349087000BF00BF00BF5B :10105000B1E60000340200205B434D445D2054693A :101060006D656F75742C2072657365742070617284 @@ -269,1105 +269,1263 @@ :1010B00005280CD1074890F84C0040B12CB14D22C6 :1010C0000449491C2046FFF74CF8012010BD0020C0 :1010D000FCE700003402002010B560210448FFF74F -:1010E00059F800200249087002A001F0FFFF10BD6E +:1010E00059F800200249087002A002F099FA10BDD8 :1010F000340200205B434D445D20496E6974204FEB :101100004B0D0A00014908607047000008000020EC :1011100001490870704700000C00002010B5074816 :101120000078052809D1054890F84C0028B10348FB -:10113000401C03F00FFA03F09FFB10BD34020020A7 -:1011400010B5002018E0164901EB001108700021CD -:10115000134A02EB00125160114A02EB0012916037 -:101160000F4A02EB001211730E4A22F810100E4AB9 -:1011700042F82010411CC8B20328E4DB00200B49D0 -:1011800008600B4908600B49086001200A49087093 -:101190000A48FFF7B7FF032109A001F0A7FF10BD20 -:1011A000A0030020720000205005002064000020F1 -:1011B000680000206C00002070000020D54000086E -:1011C0005B524F555445525D20496E6974204F4B18 -:1011D0002C20256420706F727473207265676973A8 -:1011E00074657265640D0A00F8B500F01BFB0646D5 -:1011F000002413E0012C00D10EE02C4830F814003C -:10120000002808DD2A4850F82400301A322802D37A -:10121000204602F099FF00BF601CC4B2032CE9DB3A -:1012200000243EE0012C00D139E0204601F036FDDB -:10123000054605B933E01F4804702046FFF768FFF4 -:1012400015E09DF80010204602F008FF00F0EAFAD1 -:10125000074639469DF80000FFF78EFD164800EB63 -:1012600004108068401C144901EB04118860694631 -:10127000204601F06BFD0028E3DC0020FFF714FF9F -:1012800060B1204602F060FF0C480068401C0B492A -:1012900008600120084901EB0411087300BF601CBD -:1012A000C4B2032CBEDBFFF739FFF8BD720000208B -:1012B0005005002070000020A003002068000020DE -:1012C00010B500200349087003F002F802A001F0F5 -:1012D00087FF10BD780000205B4C4F475D204465C0 -:1012E000627567206C6F672073797374656D206910 -:1012F0006E697469616C697A65640D0A00000000AA -:101300000FB470B5C2B005460E462248007885423B -:1013100003DA42B070BC5DF814FB304602F0F4FF13 -:1013200000B9F6E700240EB1304600E01AA01C4ACE -:10133000009052F82530C4F5807102AA101919A244 -:1013400002F0D8F90444FF2C0DDA49A80190C4F545 -:10135000807102AA1019019B489A02F0E5F9044431 -:101360000020019000BF002C0CDDFF2C0ADC0D22B8 -:101370002046641C02A90A54FF2C03DC0A222046E2 -:10138000641C0A54002C03DDA1B202A801F0CEFEB9 -:1013900000BFBEE7780000204D41494E000000002C -:1013A000885300085B25735D5B25735D200000009A -:1013B000704772B600BFFEE70146002291F8210097 -:1013C000022808D00420886300BF002081F8200094 -:1013D00000BF012070470868006820F00E000B680D -:1013E00018600868006820F001000B68186091F828 -:1013F000403001209840CB6B5860012081F82100DB -:1014000000BF002081F8200000BF1046E2E7000086 -:1014100070B50446002594F82100022803D004206A -:10142000A063012548E02068006820F00E002168D4 -:1014300008602068006820F00100216808601F49EA -:101440002068884201D1012026E01C49143120681F -:10145000884201D110201FE01849283120688842B5 -:1014600001D1801518E015493C312068884201D12E -:10147000801411E0114950312068884202D14FF4A4 -:10148000803009E00D4964312068884202D14FF470 -:10149000801001E04FF08070084908394860012051 -:1014A00084F8210000BF002084F8200000BF606B9A -:1014B00010B12046616B8847284670BD0800024085 -:1014C00070B5044600F0AEF906462546681C10B11A -:1014D00004480078054400BF00F0A4F9801BA8422E -:1014E000FAD370BD840000202DE9F847034600229E -:1014F00094466EE14FF0010808FA02F4D1F800803A -:1015000008EA0400A0427DD1DFF8DCA2D1F8048013 -:10151000A8EB0A09D0453AD014DCB8F1030F50D03B -:1015200009DCB8F1000F31D0B8F1010F1CD0B8F1CF -:10153000020F49D120E0B8F1110F18D0B8F1120F05 -:1015400042D11EE0B9F5881F25D006DCB9F5803FF1 -:1015500020D0B9F5801F37D11AE0B9F5001F18D097 -:10156000B9F5041F30D117E0D1F80CC02DE0D1F847 -:101570000C8008F1040C28E0D1F80C8008F1080C6C -:1015800023E0D1F80C8008F10C0C1EE000BF00BF76 -:1015900000BF00BF00BF00BFD1F80880B8F1000F46 -:1015A00002D14FF0040C0BE0D1F80880B8F1010F24 -:1015B00003D14FF0080C1C6102E04FF0080C5C6195 -:1015C00003E04FF0000C00E000BF00BFFF2801D88F -:1015D000984601E003F104084646FF2802D84FEA86 -:1015E000820803E0A2F108084FEA88084746D6F8C7 -:1015F00000804FF00F0909FA07F928EA09080CFAE8 -:1016000007F900E088E048EA0908C6F80080D1F848 -:10161000048008F08058B8F1805F7DD100BFDFF80A -:10162000CC81D8F8188048F00108DFF8C091C9F8DB -:101630001880C846D8F8188008F00108CDF8008056 -:1016400000BF00BF4FEAB9384FEA920958F8295055 -:101650004FEA82784FEA18794FF00F0808FA09F834 -:1016600025EA0805DFF88881434502D14FF00008DC -:1016700016E0DFF88081434502D14FF001080FE00A -:10168000DFF87481434502D14FF0020808E0DFF82B -:101690006C81434502D14FF0030801E04FF004088C -:1016A0004FEA82794FEA197908FA09F848EA0505FC -:1016B000DFF84C814FEA920948F82950D1F80480AC -:1016C00008F48018B8F5801F0AD1DFF83881D8F8FF -:1016D000008048EA0008DFF82C91C9F8008009E092 -:1016E000DFF82081D8F8008028EA0008DFF814919C -:1016F000C9F80080D1F8048008F40018B8F5001F7C -:1017000010D1DFF8008108F10408D8F8008048EA19 -:101710000008DFF8F09000E05AE009F10409C9F888 -:1017200000800DE0DFF8DC8008F10408D8F80080C4 -:1017300028EA0008DFF8CC9009F10409C9F8008014 -:10174000D1F8048008F40038B8F5003F0ED1DFF876 -:10175000B480A8F10408D8F8008048EA0008DFF84F -:10176000A490A9F10409C9F800800DE0DFF8948085 -:10177000A8F10408D8F8008028EA0008DFF884906F -:10178000A9F10409C9F80080D1F8048008F4803870 -:10179000B8F5803F0ED1DFF86C80A8F10808D8F8C2 -:1017A000008048EA0008DFF85C90A9F10809C9F850 -:1017B00000800DE0DFF84C80A8F10808D8F8008020 -:1017C00028EA0008DFF83C90A9F10809C9F8008070 -:1017D000521CD1F8008028FA02F8B8F1000F7FF40B -:1017E00089AEBDE8F887000000001110001002402B -:1017F00000080140000C01400010014000140140AD -:101800000800014008040140024693680B400BB1F8 -:10181000012000E0002070470AB1016101E00B04E3 -:101820000361704701480068704700007C00002099 -:101830000348006803490978084401490860704773 -:101840007C0000208400002010B50848006840F0AB -:10185000100006490860032000F0A8F80F2000F0EF -:1018600007F800F02BF8002010BD00000020024017 -:1018700070B504460E4800784FF47A71B1FBF0F071 -:101880000C490968B1FBF0F5284600F09DFC08B151 -:10189000012070BD102C07D200222146501E00F0FE -:1018A00047F80548046001E00120F2E70020F0E776 -:1018B00084000020880000208000002008B500BFC0 -:1018C0001148806940F001000F498861084680692D -:1018D00000F00100009000BF00BF00BF0846C069D3 -:1018E00040F08050C8610846C06900F08050009008 -:1018F00000BF00BF00BF0549486820F0E06040F02D -:101900000070486000BF08BD0010024000000140A8 -:1019100001460846002809DB00F01F0301229A4017 -:1019200043099B0003F1E023C3F8002100BF704787 -:101930002DE9F05F80460D461646002701F00EFFA8 -:10194000074639462A46334601F00700C0F1070A28 -:10195000BAF1040F02D94FF0040A01E0C0F1070AFE -:10196000D14600F1040ABAF1070F02D24FF0000A83 -:1019700001E0A0F1030AD4464FF0010A0AFA09FA7D -:10198000AAF1010A0AEA020A0AFA0CFA4FF0010B5C -:101990000BFA0CFBABF1010B0BEA030B4AEA0B044D -:1019A0002146404601F0E2FEBDE8F09F00BF00F096 -:1019B0000702064B19684FF6FF031940044B0B430F -:1019C00043EA0221014B196000BF70470CED00E0B3 -:1019D0000000FA0570B504460D460CB9012070BD33 -:1019E0005A48006800F00700A8420ED25748006825 -:1019F00020F007002843554908600846006800F0B9 -:101A00000700A84201D00120E9E7207800F0020099 -:101A100002281DD1207800F00400042805D14C488C -:101A2000406840F4E0604A494860207800F00800CF -:101A3000082805D14648406840F460504449486051 -:101A40004348406820F0F000A168084340494860DE -:101A5000207800F0010078B36068012806D13C4886 -:101A6000006800F4003090B90120B8E760680228EF -:101A700006D13748006800F0007040B90120AEE799 -:101A80003348006800F0020008B90120A7E7304899 -:101A9000406820F00300616808432D494860FFF763 -:101AA000C1FE064609E0FFF7BDFE801B41F288310A -:101AB000884202D9032092E707E02548406800F0F9 -:101AC0000C006168B0EB810FEDD12048006800F098 -:101AD0000700A8420ED91D48006820F007002843DF -:101AE0001A4908600846006800F00700A84201D0C3 -:101AF000012074E7207800F00400042807D114487E -:101B0000406820F4E060E1680843114948602078AB -:101B100000F00800082808D10D48406820F4605003 -:101B2000216940EAC1000A49486000F03FF80849CD -:101B30004968C1F30311074A515CC840064908606F -:101B400006480068FFF794FE002048E700200240A6 -:101B500000100240C25300088800002080000020CE -:101B600001480068704700008800002000B5FFF7BA -:101B7000F7FF04494968C1F30221034A515CC84098 -:101B800000BD000000100240D253000800B5FFF76E -:101B9000E7FF04494968C1F3C221034A515CC840C8 -:101BA00000BD000000100240D253000870B50021B3 -:101BB0000022002400230020134D696801F00C0569 -:101BC000F5B1042D02D0082D19D101E00F4819E01C -:101BD0000F4DC1F38346AB5D01F4803555B10A4D1D -:101BE0006D68C5F340450B4E725D084D5D43B5FB16 -:101BF000F2F402E0084D03FB05F4204602E000BFCA -:101C0000024800BF00BF70BD0010024000127A0001 -:101C1000B0530008C053000800093D00F8B5044661 -:101C20000CB90120F8BD207800F00100002878D020 -:101C3000F848406800F00C0004280CD0F5484068D3 -:101C400000F00C00082811D1F248406800F4803000 -:101C5000B0F5803F0AD1EF48006800F4003000285A -:101C60005FD0606800285CD10120DBE700BF6068BE -:101C7000B0F5803F06D1E748006840F48030E54980 -:101C8000086028E0606858B9E248006820F48030B5 -:101C9000E04908600846006820F4802008601AE0E7 -:101CA0006068B0F5A02F0BD1DA48006840F48020BE -:101CB000D84908600846006840F4803008600AE0AF -:101CC000D448006820F48030D24908600846006893 -:101CD00020F48020086000BF606888B1FFF7A2FD93 -:101CE000054606E0FFF79EFD401B642801D903204E -:101CF00098E7C848006800F400300028F2D010E0EF -:101D0000FFF790FD054606E0FFF78CFD401B6428B9 -:101D100001D9032086E7BF48006800F4003000289E -:101D2000F2D1207800F00200022857D1B94840686B -:101D300000F00C0050B1B748406800F00C000828D3 -:101D400018D1B448406800F4803098B9B1480068B0 -:101D500000F0020020B12069012801D0012061E7D4 -:101D6000AC48006820F0F800616940EAC100A94968 -:101D7000086033E02069E8B10120A7490860FFF757 -:101D800051FD054606E0FFF74DFD401B022801D935 -:101D9000032047E79F48006800F002000028F2D0C7 -:101DA0009C48006820F0F800616940EAC100994948 -:101DB000086013E0002098490860FFF733FD0546EE -:101DC00006E0FFF72FFD401B022801D9032029E779 -:101DD0009048006800F002000028F2D1207800F05E -:101DE000080008282DD1A069B8B101208B490860EE -:101DF000FFF718FD054606E0FFF714FD401B02281B -:101E000001D903200EE78348406A00F00200002851 -:101E1000F2D0012001F064F813E000207F4908604F -:101E2000FFF700FD054606E0FFF7FCFC401B02281B -:101E300001D90320F6E67748406A00F00200002846 -:101E4000F2D1207800F00400042873D100277148F3 -:101E5000C06900F0805070B900BF6E48C06940F0A2 -:101E600080506C49C8610846C06900F080500090FD -:101E700000BF00BF01276A48006800F48070B0B955 -:101E80006748006840F4807065490860FFF7CAFC45 -:101E9000054606E0FFF7C6FC401B642801D9032075 -:101EA000C0E65F48006800F480700028F2D000BFF0 -:101EB000E068012806D15748006A40F00100554902 -:101EC000086227E0E06858B95248006A20F0010033 -:101ED000504908620846006A20F00400086219E0D0 -:101EE000E06805280BD14B48006A40F004004949DE -:101EF00008620846006A40F0010008620AE04548AE -:101F0000006A20F00100434908620846006A20F098 -:101F10000400086200BFE068A0B1FFF783FC05463B -:101F200009E0FFF77FFC401B41F28831884202D96B -:101F3000032077E622E03748006A00F0020000281C -:101F4000EFD012E0FFF76EFC054608E0FFF76AFCF1 -:101F5000401B41F28831884201D9032062E62D48B6 -:101F6000006A00F002000028F0D1012F05D12948B5 -:101F7000C06920F080502749C86100BFE069C8B33C -:101F80002448406800F00C00082860D0E06902286E -:101F900048D1002020490866FFF744FC054606E0CA -:101FA000FFF740FC401B022801D903203AE61948FC -:101FB000006800F000700028F2D1206AB0F5803F80 -:101FC00007D11448406820F40030A1680843114943 -:101FD0004860D4E9080108430E49496821F47411A6 -:101FE00008430C49486001200B490866FFF71AFCBA -:101FF000054607E03DE0FFF715FC401B022801D92C -:1020000003200FE60348006800F000700028F2D0BB -:102010002FE00000001002400000424280044242D3 -:1020200000700040002014490866FFF7FBFB0546DE -:1020300006E0FFF7F7FB401B022801D90320F1E57A -:102040000E48006800F000700028F2D111E0E0694D -:10205000012800D1E6E50948466806F48031206A87 -:10206000814204D106F47011606A814201D00120DE -:10207000D8E50020D6E500000000424200100240F2 -:1020800010B504460CB9012010BD606A38B960680B -:10209000B0F5827F00D105E00021E16102E000217E -:1020A000216161610021A16294F8510028B90020EA -:1020B00084F85000204600F043F8022084F85100D4 -:1020C0002068006820F0400021680860A08800F4C3 -:1020D0008270218901F404410843A18901F400615F -:1020E0000843217C01F002010843217D01F0010138 -:1020F0000843218B01F400710843217F01F038016E -:1021000008432021095D01F080010843218D01F47D -:1021100000510843216808600421A06901EA1040C9 -:10212000216848602068C06920F400602168C861A7 -:1021300000206065012084F851000020A4E7000021 -:1021400010B586B0044600200290039004900590DC -:102150001A49206888422FD100BF1948C06940F44D -:1021600080401749C8610846C06900F4804001906A -:1021700000BF00BF00BF0846806940F008008861CA -:102180000846806900F00800019000BF00BF4FF4CE -:1021900020400290022003900320059002A90948E4 -:1021A000FFF7A2F94FF480400290002003900490C2 -:1021B00002A90448FFF798F906B010BD00380040A6 -:1021C00000100240000C014070B504462546681E10 -:1021D000B0F1807F01D301200FE0681E4FF0E021B5 -:1021E00048610F214FF0FF3001F0C0FA00204FF09E -:1021F000E021886107200861002070BD70477047AA -:102200002DE9F84F0446206805682068C6682068F4 -:1022100047694FF00009CA4605F00F09B9F1000FF0 -:102220000AD105F0200038B106F0200020B1204688 -:1022300001F0A0F8BDE8F88FB9F1000F7BD007F0EE -:10224000010018B906F49070002874D005F0010060 -:1022500030B106F4807018B1606C40F00100606429 -:1022600005F0040030B107F0010018B1606C40F0D7 -:102270000200606405F0020030B107F0010018B1FF -:10228000606C40F00400606405F0080048B106F09E -:10229000200010B907F0010018B1606C40F0080090 -:1022A0006064606C002845D005F0200028B106F07D -:1022B000200010B1204601F05DF820684069C0F3AD -:1022C000801A606C00F0080010B9BAF1000F2CD031 -:1022D000204601F009F82068406900F0400000B392 -:1022E00000BF00BF2168143151E8001F21F04000F9 -:1022F0002168143141E80002002AF3D100BFE06BED -:1023000050B17748E16B4863E06BFFF781F888B123 -:10231000E06B416B88470DE02046FFF770FF09E056 -:1023200009E02046FFF76BFF04E02046FFF767FF58 -:10233000002060647EE7206B012877D105F0100053 -:10234000002873D006F010000028FAD000BF00204B -:10235000009020680068009020684068009000BFEE -:1023600000BF2068406900F0400000285FD0E06BAB -:10237000006840681FFA80F8B8F1000F55D0A08DB2 -:10238000404552DDA4F82E80E06B8069202843D0C0 -:1023900000BF00BF21680C3151E8001F21F480709C -:1023A00021680C3141E80002002AF3D100BF00BFD0 -:1023B00000BF2168143151E8001F21F0010021689D -:1023C000143141E80002002AF3D100BF00BF00BF72 -:1023D0002168143151E8001F21F0400021681431B8 -:1023E00041E80002002AF3D100BF202084F8420017 -:1023F0000020206300BF00BF21680C3151E8001F9E -:1024000021F0100021680C3141E80002002AF3D1CC -:1024100000BFE06BFEF7D0FF02206063A08DE28D6D -:10242000801A81B22046FFF7E9FE03E742E0A08D63 -:10243000E18D401A1FFA80F8E08DD0B3B8F1000F9B -:1024400037D000BF00BF21680C3151E8001F21F4D4 -:10245000907021680C3141E80002002AF3D100BFDE -:1024600000BF00BF2168143151E8001F21F00100B6 -:102470002168143141E80002002AF3D100BF202076 -:1024800084F842000020206300BF00BF21680C31A7 -:1024900051E8001F21F0100021680C3141E80002D2 -:1024A000002AF3D100BF0220606341462046FFF7B7 -:1024B000A5FEBFE605F0800030B106F0800018B13F -:1024C000204601F073F8B5E605F0400030B106F0A3 -:1024D000400018B1204600F03DFFABE600BFA9E682 -:1024E000D532000810B504460CB9012010BDA06912 -:1024F00000B100E000BF94F8410028B9002084F842 -:102500004000204600F02AF8242084F8410020688A -:10251000C06820F400502168C860204600F0A8FF81 -:102520002068006920F490402168086120684069B3 -:1025300020F02A00216848612068C06840F40050FB -:102540002168C86000206064202084F8410084F87D -:1025500042000020606300BFC8E7000010B586B0ED -:102560000446002002900390049005905949206889 -:10257000884237D100BF5848806940F480405649AE -:1025800088610846806900F48040019000BF00BF68 -:1025900000BF0846806940F00400886108468069F1 -:1025A00000F00400019000BF00BF48150290022017 -:1025B00003900320059002A94848FEF795FF4FF4C9 -:1025C0008060029000200390049002A94348FEF727 -:1025D0008BFF002211462520FFF7AAF92520FFF7DF -:1025E00097F975E03E492068884236D100BF3A48E5 -:1025F000C06940F400303849C8610846C06900F439 -:102600000030019000BF00BF00BF0846806940F065 -:10261000040088610846806900F00400019000BF52 -:1026200000BF04200290022003900320059002A91D -:102630002A48FEF759FF08200290002003900490DA -:1026400002A92648FEF750FF002201212620FFF7AD -:102650006FF92620FFF75CF93AE0224920688842AA -:1026600036D100BF1C48C06940F480201A49C861B7 -:102670000846C06900F48020019000BF00BF00BF81 -:102680000846806940F0080088610846806900F0CB -:102690000800019000BF00BF0815029002200390BF -:1026A0000320059002A91048FEF71EFF4FF40060BA -:1026B000029000200390049002A90B48FEF714FF3B -:1026C000002202212720FFF733F92720FFF720F906 -:1026D00006B010BD00380140001002400008014063 -:1026E0000044004000480040000C014070B5044622 -:1026F0000D46164694F8420020280BD105B10EB9BC -:10270000012070BD0020206332462946204600F09B -:102710002DFFF6E70220F4E770B50446164920685D -:10272000884208D11548057802F0FAF929460020B8 -:1027300000F06EFA1FE01249206888420DD1FFF7C1 -:1027400071F8054629460F480078FEF715FB01226F -:102750000C490D48FFF7CAFF0DE00C49206888427C -:1027600009D10B480178022000F052FA01220849F1 -:102770000848FFF7BBFF70BD00380140AC000020E7 -:102780000044004004000020A40100200048004054 -:1027900005000020EC0100202DE9F84F04460E460C -:1027A000174699464FF0000A94F8410020284AD174 -:1027B00006B117B90120BDE8F88F00206064212020 -:1027C00084F84100FFF72EF88246A784E784A068CA -:1027D000B0F5805F04D1206910B90025B04602E051 -:1027E00035464FF000081BE053460022802120466A -:1027F000CDF8009000F00AFF08B10320DBE745B9EF -:10280000B8F80000C0F308002168486008F1020829 -:1028100003E02878216848606D1CE08C401EE0844D -:10282000E08C0028E0D15346002240212046CDF81C -:10283000009000F0EBFE08B10320BCE7202084F8F4 -:1028400041000020B7E70220B5E710B5034693F832 -:102850004100202813D101B10AB9012010BD19622D -:102860009A84DA8400205864212083F84100186893 -:10287000C06840F080001C68E0600020EEE70220A5 -:10288000ECE7000010B504460B492068884203D1EC -:10289000002000F0E5FA0DE008492068884202D1E6 -:1028A00000F0E2FC06E006492068884202D10220DE -:1028B00000F0D6FA10BD000000380140004400408E -:1028C0000048004000BFFEE70021002009E0074A61 -:1028D00002EB001292791AB1012282400A43D1B26E -:1028E000401C0428F3DB084670470000100000205D -:1028F0000146042901DB00207047024800EB01106B -:102900008079F9E71000002070B5002512E0114829 -:1029100000EB0514A1882068FEF776FF08B10120BE -:1029200000E00020A071A07920720120E071002059 -:10293000E0606D1C042DEADB0020074908600120DF -:1029400006490870FFF7C0FF0446214604A000F0C6 -:10295000CDFB70BD1000002050000020540000206E -:102960005B494F5D20496E6974204F4B2C20696E86 -:10297000697469616C207374617465733A2030788E -:10298000253032580D0A00002DE9F041FEF74AFFCC -:1029900007461C480068381A0A2801D2BDE8F081B1 -:1029A00018480760002628E0174800EB0614A188A5 -:1029B0002068FEF729FF08B1012000E0002005464D -:1029C000207AA84203D00020E071257214E0E0795B -:1029D000032803DAE079401CE0710DE0A079A842F9 -:1029E0000AD0A571E068401CE0600848007818B182 -:1029F000F0B2294602F022FB761C042ED4DB00BF85 -:102A0000CCE70000500000201000002054000020FF -:102A100000B585B00020019002900390049000BFA3 -:102A20003C48806940F010003A4988610846806956 -:102A300000F01000009000BF00BF00BF0846806992 -:102A400040F0200088610846806900F02000009076 -:102A500000BF00BF00BF0846806940F004008861E5 -:102A60000846806900F00400009000BF00BF00BF6E -:102A70000846806940F0080088610846806900F0D7 -:102A80000800009000BF00BF012280212248FEF70D -:102A9000C3FE012205212148FEF7BEFE002241F2BD -:102AA00008211E48FEF7B8FE00224FF401411A48E3 -:102AB000FEF7B2FE48F28010019001200290002043 -:102AC00003900220049001A91348FEF70DFD41F286 -:102AD0000D2001900120029000200390022004901C -:102AE00001A90E48FEF700FD02200190002002908F -:102AF0000120039001A90948FEF7F6FCF02001909F -:102B000000200290039001A90448FEF7EDFC05B0F7 -:102B100000BD00000010024000080140000C014010 -:102B200010B50E480E4908604FF4827048600021CD -:102B30000B488160C160016141614FF400718161A6 -:102B40000021C1610162416281620A21C162FFF715 -:102B500097FA08B1FEF72DFC10BD000000380040C8 -:102B60000401002010B50B480B4908604FF41650C3 -:102B70004860002108488160C16001610C21416109 -:102B800000218161C161FFF7ADFC08B1FEF711FCC6 -:102B900010BD0000003801405C01002010B50B485A -:102BA0000B4908604FF4E13048600021084881601B -:102BB000C16001610C21416100218161C161FFF7A8 -:102BC00091FC08B1FEF7F5FB10BD00000044004089 -:102BD000A401002010B50B480B4908604FF41650B3 -:102BE0004860002108488160C16001610C21416199 -:102BF00000218161C161FFF775FC08B1FEF7D9FBC7 -:102C000010BD000000480040EC01002000BFFEE7BE -:102C100070B505460E46032D00DB70BD6B20684382 -:102C20000E4901EB800494F8A80100B9F5E731469C -:102C300004F1080002F0C1F940B9D4F8A401401C25 -:102C4000C4F8A40106A0616800F050FAD4F89C0111 -:102C5000401CC4F89C0100BFDFE700006C060020A8 -:102C60005B4D554152545D202573205258206F769C -:102C70006572666C6F770D0A00000000014603293B -:102C800001DB03A07047044850F82100FAE7000078 -:102C9000554E4B4E4F574E00A45300080146032992 -:102CA00001DB0020704772B66B204843034B03EBF7 -:102CB0008000B0F88C2062B61046F3E76C06002066 -:102CC00070B5002520E06B206843134901EB8004B8 -:102CD000124850F825002060114850F82500606027 -:102CE00004F1080002F061F904F1900002F0E5FA45 -:102CF000002004F5CE7404F8020C20606060A0602F -:102D000001202073681CC5B2032DDCDB032105A064 -:102D100000F0ECF970BD00006C060020985300082C -:102D2000A45300085B4D554152545D20496E6974AF -:102D3000204F4B2C20256420706F72747320636FBA -:102D40006E666967757265640D0A000010B502460B -:102D50000B46032A00DA0BB9002010BD6B2050434C -:102D6000104C04EB800000F1080172B6B1F8840049 -:102D700010B962B60020F0E7B1F88200085C187064 -:102D800031F8824F601CC41700EB5464E411A0EBCF -:102D9000C4140C804888401E4880823962B60120E5 -:102DA000DBE700006C0600202DE9F04105460F46E8 -:102DB0009046032D03DA17B1B8F1000F01D1BDE839 -:102DC000F081012D04D14146384600F0AFF9F6E715 -:102DD0006B2068430C4901EB800494F8A80100B90A -:102DE000EDE74246394604F1900002F071FA0646DA -:102DF000002E07DDD4F8A0013044C4F8A001284615 -:102E000002F01EFA00BFDAE76C06002070B5054636 -:102E10000C4604B970BD2046FDF7C7F986B23246AC -:102E200021462846FFF7C0FF00BFF3E770B5002436 -:102E300011E06B206043094901EB800595F8A8017A -:102E400000B906E0012C00D103E0204602F0F8F9B9 -:102E500000BF601CC4B2032CEBDB70BD6C0600200D -:102E6000F8B50546032D00DBF8BD012D02D100F0B9 -:102E7000FBF9F9E76B206843164901EB800606F180 -:102E80009004002772B6002084F80601B4F804010B -:102E9000002816DDB4F80201205C009004F581746E -:102EA0002188481CC11700EB11610912A0EB012118 -:102EB00021806088401E608001202071A4F581740B -:102EC000012762B627B1012269463068FFF7BDFCD1 -:102ED00000BFC9E76C06002000BFFEE77047000096 -:102EE00008B508490968C9084FF47A72B1FBF2F1D4 -:102EF0004143009100BF00BF00994A1E0092002983 -:102F0000F9D108BD8800002010B500224FF400411F -:102F10000548FEF781FC0020044908700449086058 -:102F200004A000F0E3F810BD000801405C000020A0 -:102F3000600000205B52454C41595D20496E697428 -:102F4000204F4B2C2073746174653D4F46460D0A2B -:102F50000000000070B50446FEF764FC0546154805 -:102F60000068281A642803D213A000F0BFF870BDCF -:102F70001A480078A04208D10CB119A000E019A0AD -:102F8000014619A000F0B2F8F1E722464FF40041E3 -:102F90001D48FEF741FC11480470064805600CB15D -:102FA0000FA000E00FA0014618A000F09FF800BF9E -:102FB000DDE70000600000205B52454C41595D2078 -:102FC000546F67676C6520746F6F20666173742C33 -:102FD0002069676E6F7265640D0A00005C00002056 -:102FE0004F4E00004F4646005B52454C41595D2014 -:102FF000537461746520756E6368616E6765643AC9 -:103000002025730D0A000000000801405B52454C6A -:1030100041595D2052656C6179202D3E2025730D4C -:103020000A000000704710B502F0D8F8FEF700FC67 -:1030300010BD00B58FB0282105A8FDF7ABF814210D -:103040006846FDF7A7F801200590000406900020CF -:1030500007900120099002200C90C1030D914FF4BC -:10306000E0110E9105A8FEF7D9FD08B1FEF7A1F910 -:103070000F20009002200190002002904FF4806009 -:1030800003900020049002216846FEF7A3FC08B1DB -:10309000FEF78FF90FB000BD7047000010B500209B -:1030A0000849A1F80001A1F80201A1F8040181F882 -:1030B0000601A1F808014FF4807103A000F016F892 -:1030C00010BD0000940200205B55415254325D2037 -:1030D000496E6974204F4B2C2062756666657220BC -:1030E00073697A653A2025640D0A00000FB410B5A3 -:1030F000A2B0249818B922B010BC5DF814FB25A822 -:103100000190802102A8019B249A00F00DFB044647 -:1031100000200190002C06DB802C00DB7F24A1B274 -:1031200002A800F003F800BFE5E70000F8B5044688 -:103130000D4605B104B9F8BD0026002772B600207F -:1031400029E02549B1F80411FF2907DD2249B1F82A -:103150000811491C204AA2F808111EE0215C1E4AF1 -:10316000B2F800211C4B99541A46B2F80021511CA8 -:10317000CA1701EB12621212A1EB0222A3F800217E -:103180001946B1F80411491C1A46A2F80411711C21 -:103190008EB2411C88B2A842D3DB00BF002E08DDEE -:1031A0000D4890F8060120B901200B4981F806016D -:1031B000012762B66FB172B60748B0F8020106493E -:1031C000085C009062B6012269460448FFF73DFBA7 -:1031D00000BF00BFAFE7000094020020A401002060 -:1031E00070B5044604B970BD2046FCF7DEFF85B219 -:1031F00029462046FFF79AFF00BFF4E738B572B6BC -:10320000174890F8060118B91548B0F8040108B934 -:1032100062B638BD1248B0F802410146B1F8021159 -:10322000481CC11700EB11610912A0EB01210C4AE7 -:10323000A2F802111046B0F80401401E1146A1F890 -:103240000401012081F806010846005D009062B685 -:10325000012269460348FFF7F8FA00BFD9E70000EA -:1032600094020020A401002038B5002572B6002089 -:10327000164981F806010846B0F8040100281CDD53 -:103280000846B0F80241B1F80211481CC11700EB22 -:1032900011610912A0EB01210C4AA2F8021110469B -:1032A000B0F80401401E1146A1F80401012081F884 -:1032B00006010846005D0090012562B625B1012295 -:1032C00069460348FFF7C1FA38BD000094020020A8 -:1032D000A401002070B505466C6A0020E085E084FA -:1032E0002046FEF78CFF70BD00BF00BF02680C32A5 -:1032F00052E8002F22F4907102680C3242E8001369 -:10330000002BF3D100BF00BF00BF0268143252E8A7 -:10331000002F22F001010268143242E80013002B52 -:10332000F3D100BF016B01290ED100BF00BF0268BD -:103330000C3252E8002F22F0100102680C3242E8F1 -:103340000013002BF3D100BF202180F84210002190 -:103350000163704710B504462068C06820F0400043 -:103360002168C860202084F841002046FFF78AFACF -:10337000002010BDF8B5044694F84200222875D10B -:10338000A068B0F5805F0CD1206950B90025A66A0D -:1033900020684068C0F308003080A06A801CA062EA -:1033A00015E0A56A0026A068B0F5805F03D0A0688C -:1033B00028B9206918B920684068287004E020689E -:1033C000406800F07F002870A06A401CA062E08D79 -:1033D000401E80B2E085002846D12068C06820F0F9 -:1033E00020002168C8602068C06820F480702168CF -:1033F000C8602068406920F00100216848612020F1 -:1034000084F8420000206063206B012826D1002050 -:10341000206300BF00BF21680C3151E8001F21F07C -:10342000100021680C3141E80002002AF3D100BFEE -:103430002068006800F0100010280AD100BF0020AA -:10344000009020680068009020684068009000BFED -:1034500000BFA18D2046FEF7D1FE02E02046FFF717 -:103460005BF90020F8BD01E00020FBE70220F9E74E -:1034700070B504462168096921F44051E26811439E -:10348000226811612269A1681143626941EA02055B -:103490002168C96841F20C62914329432268D160D6 -:1034A0002168496921F44071A26911432268516180 -:1034B0002D4A2168914202D1FEF768FB01E0FEF738 -:1034C00055FB00EBC00101EB001162689200B1FBFB -:1034D000F2F100EBC00202EB001263689B00B2FB4A -:1034E000F3F26423B2FBF3F202EBC20303EB02122A -:1034F000A1EB8201322202EB01116422B1FBF2F155 -:1035000001F0F00100EBC00202EB001263689B00C7 -:10351000B2FBF3F26423B2FBF3F201EB021200EB15 -:10352000C00101EB001163689B00B1FBF3F100EBFC -:10353000C00303EB00136668B600B3FBF6F3642622 -:10354000B3FBF6F303EBC30606EB0313A1EB830116 -:10355000322303EB01116423B1FBF3F101F00F01FE -:1035600011442268916070BD0038014010B50346D7 -:1035700099629A85DA8500205864222083F84200F7 -:10358000186928B11868C06840F480701C68E06051 -:103590001868406940F001001C6860611868C068E4 -:1035A00040F020001C68E060002010BD014691F84A -:1035B0004100212828D18868B0F5805F0BD10869C7 -:1035C00048B90A6A1088C0F308000B685860086A96 -:1035D000801C086205E00B6A581C086218780B68AA -:1035E0005860C88C401E80B2C88458B90868C0684A -:1035F00020F080000B68D8600868C06840F0400088 -:103600000B68D860002070470220FCE72DE9F041EC -:1036100004460D4617469846069E34E0701C88B353 -:103620002EB1FEF7FFF8A0EB0800B0422BD900BF87 -:1036300000BF21680C3151E8001F21F4D0702168CF -:103640000C3141E80002002AF3D100BF00BF00BFE7 -:103650002168143151E8001F21F001002168143164 -:1036600041E80002002AF3D100BF202084F8410085 -:1036700084F8420000BF002084F8400000BF03200F -:10368000BDE8F081FFE7206800682840A84201D12A -:10369000012000E00020B842C0D00020F0E7000088 -:1036A00010B50248FEF7ACFD10BD00005C01002023 -:1036B00010B50248FEF7A4FD10BD0000A4010020D3 -:1036C00010B50248FEF79CFD10BD0000EC01002083 -:1036D00000BFFEE70FB4054B10B503A9044A0298DA -:1036E00000F02EF910BC5DF814FB00001D4200082C -:1036F000B80000200FB47CB50C0009AD01D0611EEC -:1037000000E00021CDE90001064B6A4629460898F1 -:1037100000F016F9002C02D0009A002111707CBC38 -:103720005DF814FB474000087CB50C001D461646AA -:10373000014601D0601E00E00020CDE90010064BDC -:103740006A462946304600F0FBF8002C02D0009A69 -:10375000002111707CBD000047400008024800684D -:10376000C0F30220704700000CED00E010B5002807 -:1037700004DB0A07130E054A135406E00A07140E69 -:10378000034A00F00F031B1FD45410BD00E400E0F7 -:1037900018ED00E000487047BC00002002E008C8B7 -:1037A000121F08C1002AFAD170477047002001E0BB -:1037B00001C1121F002AFBD1704700002DE9FF5FF5 -:1037C00082B00021DDE90430020DDDF840B0034392 -:1037D00018D044F61050A2F2FF324243151411984B -:1037E00001281FD0A5EB0B00401C5FEA000A4FF038 -:1037F00000064E4FDFF83891B046504615D5CAF155 -:10380000000413E0119801244AA3012801D16FEAB2 -:103810000B010298119AC0E90031C0E9024206B0DA -:10382000BDE8F09FCBF10000DFE704460021404AED -:10383000491842EB0450CDE9001012E0E00707D030 -:1038400032463B4640464946FCF70BFF80468946D8 -:1038500032463B4610461946FCF703FF06460F4624 -:103860006410002CEAD1DDE90401DDE90023BAF19E -:10387000000F06DAFCF7F5FE42464B46FCF7F1FE78 -:1038800005E0FCF760FF42464B46FCF75CFF044650 -:103890000E460022284BFCF7DDFF03D84FF0FF3027 -:1038A000014607E00022254B20463146FCF732FE58 -:1038B000FCF7B8FF102409E0002C0ADB0A220023E1 -:1038C000FCF77DFD039B30321A55641E50EA01025D -:1038D000F2D1641C039AC4F111031444119A012A11 -:1038E00003D0012208430DD10AE0084304D0002090 -:1038F0004FF0110B119072E7A3EB0B056D1E0DE05D -:103900005B4504DD4FF0000205F1010504E003DA38 -:103910004FF00002A5F10105002AECD002981199A0 -:10392000C0E90231C0E9004579E700000000144019 -:103930000000F03F300000000000F0430000E03FD6 -:103940002DE9FF4F95B09A46884606460025EEE1E0 -:10395000252877D100242746F94A0121039400E065 -:10396000044316F8013F203B01FA03F01042F7D15F -:1039700030782A2811D06FF02F033078A0F1300270 -:10398000092A16D8039A44F0020402EB820203EBE0 -:1039900042021044761C0390EFE758F8042B039280 -:1039A000002A03DA504244F40054039044F0020425 -:1039B000761C30782E2816D116F8010F44F0040436 -:1039C0002A280DD06FF02F023078A0F13003092B98 -:1039D00009D807EB870302EB4303C718761CF3E70C -:1039E00058F8047B761C30786C280FD006DC4C2805 -:1039F00017D068280DD06A2814D104E0742810D09C -:103A00007A280FD10DE044F400140AE044F4801445 -:103A100001E044F440147278824202D104F580142B -:103A2000761C761C307866280BD013DC582877D0AB -:103A300009DC002875D04528F6D04628F4D0472860 -:103A40001AD193E118E0632835D0642879D065282D -:103A500012D18BE1702873D008DC6728F1D0692877 -:103A60006FD06E280DD06F2806D1ACE073282CD013 -:103A7000752874D0782853D05246179990476D1CFA -:103A800054E1C4F30250022809D003280DD0D8F81D -:103A9000001004280DD00D6008F1040846E1D8F8A4 -:103AA0000010EA17C1E90052F6E7D8F800100D80BF -:103AB000F2E70D70F0E718F8041B8DF800100020F5 -:103AC0008DF80100EB46012003E058F804BB4FF0ED -:103AD000FF3061074FF0000102D40DE009F1010150 -:103AE0008946B9420FDA8145F8DB1BF80910002935 -:103AF000F4D108E009F1010189468142FADB1BF8A3 -:103B000009100029F6D103985346A0EB0907214676 -:103B10003846179A00F080FA284400EB090507E0C0 -:103B200044E008E10DE01BF8010B5246179990475D -:103B3000B9F10109F7D2534621463846179AF2E007 -:103B400039E00A21C4F302524FF0000B0091022A1F -:103B500006D058F8040BC117032A09D00AE023E065 -:103B600008F1070020F00702F2E80201904605E0A4 -:103B700000B2C117042A01D140B2C117002906DAE8 -:103B80000A460021404261EB02012D2202E022059B -:103B900004D52B228DF80420012203E0E20701D096 -:103BA0002022F7E7914657E00A2100E010214FF06C -:103BB000000B00910BE010214FF0000B44F00404C7 -:103BC0000827009103E008204FF0000B0090C4F399 -:103BD0000252022A05D058F8040B0021032A08D00B -:103BE00008E008F1070020F00702F2E80201904621 -:103BF00003E080B2042A00D1C0B24FF000092207CE -:103C00002AD53278702A07D0DDF800C08CF0100C6D -:103C10005CEA0B0C05D00EE040228DF80420012256 -:103C200008E050EA010306D030238DF804308DF807 -:103C3000052002229146009B83F0080353EA0B0300 -:103C40000AD150EA010201D1620705D530228DF870 -:103C500004204FF001097F1E3278582A04D039A27F -:103C60000C920CAA02920BE03BA2F9E75B46009A89 -:103C7000FCF7A5FB0C9B9B5C029A521E02921370F0 -:103C800050EA0102F2D1029804A9081A00F1200BAF -:103C9000600702D524F4803400E001275F4502DD8F -:103CA000A7EB0B0000E0002000EB0B010090039855 -:103CB0004944401A0390E00306D453462146179A1C -:103CC000039800F0A9F90544002706E001A8524630 -:103CD000C05D179990476D1C7F1C4F45F6DBE003D4 -:103CE0000CD553462146179A039800F095F90544E0 -:103CF00004E030205246179990476D1C0099481EE9 -:103D000000900029F5DC08E00298029952460078FC -:103D1000491C0291179990476D1CBBF10001ABF152 -:103D2000010BF1DC5BE100F065F90544761C3078AD -:103D300000287FF40DAE19B02846BDE8F08F0000D2 -:103D40000928010030313233343536373839616271 -:103D50006364656600000000303132333435363735 -:103D6000383941424344454600000000600700D412 -:103D7000062708F1070020F00700F0E8022380463C -:103D800003F0004C5FEA0C0001D097A009E0200589 -:103D900001D596A005E0E00701D095A001E0AFF2C3 -:103DA0004C001390307823F0004365280CD006DCDB -:103DB000452809D046281DD047287FD13BE06628FA -:103DC00018D067287AD136E00021112F01DB1120AD -:103DD00000E0781CCDE9000104A90CA8FFF7EEFC77 -:103DE000DDE90D010C9A4FF0000B07F1010910926B -:103DF00000914EE04FF000400097CDE9011004A97A -:103E00000CA8FFF7DBFCDDE90D020C9B0F994FF0CE -:103E1000000B91461093009211B9791C00EB010937 -:103E2000B7EB090003D4C0F1FF3B07F10109A9EB8F -:103E30000700019042E0012F00DA01270021112F35 -:103E400001DD112000E03846CDE9000104A90CA8ED -:103E5000FFF7B4FCDDE90D010C9A00914FF0000B67 -:103E6000B946109221070FD4009A4A4503DA9146C9 -:103E700001E0A9F10109B9F1010F05DD109AA9F1DD -:103E80000101515C3029F4D0B84202DA10F1040F7C -:103E900003DA0121CDE9011010E0002803DC83449E -:103EA000A9EB000102E0411C494500DD8946A0EB79 -:103EB0000B00401C01904FF000400290200705D4F9 -:103EC0000198484502DB4FF0FF30019000208DF84B -:103ED0004B0002980DF14B07B0F1004F25D00220A6 -:103EE0000C902B200D90029800280CDA4042029092 -:103EF0002D200D9007E00A210298FCF74AFA303194 -:103F0000029007F8011D0C99481E0C900029F2DC64 -:103F100002980028EFD1791E0D980870307800F0D3 -:103F2000200040F0450007F8020D11A8C01BC01D7D -:103F300002901398007800B1012000EB090101986C -:103F400001EBE071029801440398401A401E03906F -:103F5000E00306D453462146179A039800F05CF814 -:103F600005441398007818B15246179990476D1C74 -:103F7000E00323D553462146179A039800F04CF8E6 -:103F800005441BE0BBF1000F07DB0098584504DD3A -:103F90001098179910F80B0001E01799302052463D -:103FA000904701980BF1010B401E05F101050190AE -:103FB00004D12E205246179990476D1CB9F100018B -:103FC000A9F10109DEDC05E017F8010B524617994B -:103FD00090476D1C0299481E02900029F4DC53465C -:103FE0002146179A03989EE62D0000002B00000042 -:103FF000200000002DE9F041044600251E4617462A -:10400000880404D405E039462020B0476D1C641EA6 -:10401000F9D52846BDE8F0812DE9F0410446002598 -:104020001E469046C80301D5302700E020278804AB -:1040300004D505E041463846B0476D1C641EF9D5ED -:104040002846BDE8F0814A68002A06D00A68531C59 -:104050000B6010704868401E4860704770B5044699 -:104060000D460C4830F8140080280CDA094830F866 -:10407000141030F81400401C064A22F814000648B8 -:1040800000EBC4104554FDF7CDFB044941F8240072 -:1040900070BD000072000020D003002050050020F9 -:1040A00010B502460023002003E0145C6340441C6A -:1040B000E0B28842F9DB184610BD10B50246002375 -:1040C000002003E0145C6340441CE0B28842F9DB4A -:1040D000184610BDF8B505460C461448006878B17E -:1040E0002046FCF762F886B23246214628460F4B3E -:1040F0001B6898470E480068401C0D49086008E09E -:1041000021462846FEF782FE09480068401C0849FF -:1041100008602846FEF7B2FD0646334605A208A110 -:1041200001200094FDF7ECF8F8BD000064000020C9 -:104130006C00002054585B25735D3A202573000005 -:10414000524F5554455200007CB50446274830F87C -:10415000140000B97CBD2046FEF790FD05462946B7 -:1041600023A0FEF7C3FF002531E0264800EBC41072 -:10417000405D01909DF80400202808DB9DF80400B4 -:104180007F2804DA012101A8FEF7D0FF1DE09DF889 -:1041900004000D2804D102211BA0FEF7C7FF14E084 -:1041A0009DF804000A2804D1022118A0FEF7BEFFE2 -:1041B0000BE09DF8043016A204216846FFF79AFA36 -:1041C00004216846FEF7B2FF00BF681C85B20748AD -:1041D00030F81400A842C8DC0FA0FFF701F8002057 -:1041E000024921F8140000BFB4E70000720000206B -:1041F0005B524F555445525D2025732052583A204A -:1042000022000000D00300205C7200005C6E000001 -:104210005C78253032580000220D0A0013B50C4698 -:1042200001216846FEF782FF00981CBD10B50022F0 -:1042300008210248FDF7F0FA10BD0000000C014013 -:1042400010B5012208210248FDF7E6FA10BD000072 -:10425000000C014010B500224FF400710148FDF739 -:10426000DBFA10BD000C014010B5012251020248DA -:10427000FDF7D2FA10BD0000000C014001463029C4 -:1042800005DB392903DCA1F13000C0B270474129B8 -:1042900005DB462903DCA1F13700C0B2F6E761294E -:1042A00005DB662903DCA1F15700C0B2EEE7002070 -:1042B000ECE770B505460C462046FFF7DFFF0646E3 -:1042C0002846FFF7DBFF46EA0010C0B270BD0000D1 -:1042D0000B48007800B17047002009E0002100EB96 -:1042E0000012084B995400EB00121A441174401C40 -:1042F0001028F3DB01200249087000BFEBE7000043 -:10430000790000205C05002070B505460DB12878C5 -:1043100008B9012070BDFFF7DBFF002414E004EBB7 -:1043200004100B49085C70B104EB0411084A8818AA -:104330000F222946FBF74EFF28B904EB041004496D -:104340000844007CE6E7641C102CE8DB0120E1E770 -:104350005C050020014609B1087808B901207047C2 -:104360000020FCE710B504462046FFF7F3FF08B134 -:10437000002010BD09E0FBF7E7FE00682178405CF3 -:10438000202801D00020F4E7641C20780028F2D116 -:104390000120EEE710B50446FBF7D6FE0068005D8D -:1043A00000F0100028B9FBF7CFFE0068005D202860 -:1043B00001D1012010BD0020FCE710B50446FBF739 -:1043C000C3FE0068005D00F03E0038B12A2C05D025 -:1043D0000D2C03D00A2C01D0012010BD0020FCE7D9 -:1043E000FDF732FAFEF725FEFEF712FBFEF7BAFBE9 -:1043F000FEF796FBFEF7D2FBFEF7ECFBFEF74EFE58 -:10440000FEF782FAFCF768FEFEF77EFDFEF758FC29 -:10441000FCF796FEFCF754FF012220492048FEF7E6 -:1044200065F901221F492048FEF760F9002000F0DD -:10443000A9FB01221D491E48FEF758F9002000F093 -:1044400005FD4FF47A710A2000F026FD002000F0EF -:10445000C9FB00F017FC17A0FFF73CF921A0FFF7FC -:1044600039F9294800682949B0FBF1F4214628A010 -:10447000FFF730F92CA0FFF72DF90DE0FEF7BEFE97 -:10448000FEF782FAFCF74AFEFEF7D0FCFCF7ACFE22 -:1044900000F018FD00F006FCF0E70000040000202A -:1044A000A401002005000020EC010020AC00002049 -:1044B0005C0100200D0A3D3D3D3D3D3D3D3D3D3D06 -:1044C0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D1C -:1044D0003D3D3D3D3D3D3D3D3D3D3D3D3D3D0D0A6F -:1044E000000000004533322D3433335442482D53FD -:1044F00043204170706C69636174696F6E205374FE -:1045000061727465640D0A008800002040420F004B -:1045100053797374656D20436C6F636B3A20256427 -:10452000204D487A0D0A00003D3D3D3D3D3D3D3D5D -:104530003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DAB -:104540003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D9B -:104550000D0A000070B58CB0044694F84C0008B108 -:1045600060A200E061A294F8490094F8481004F1B8 -:104570002803CDE90102009104F1080221465CA064 -:10458000FEF7B4FD65A12046FBF716FE002835D1E5 -:1045900004F10800FFF7E6FE38B961A000F0B4FDB1 -:1045A00061A0FEF7A3FD0CB070BD04F10800FBF79D -:1045B000E3FE05460DB1012D18D10DB1012100E03A -:1045C00000210846FEF7C6FC2B4661A2202104A864 -:1045D000FFF790F804A800F0CDFD0DB15EA000E05B -:1045E0005EA001465EA0FEF781FD06E04CA000F053 -:1045F0008BFD29465FA0FEF779FD71E066A120469C -:10460000FBF7DAFD002858D104F10800FFF7A2FEFD -:1046100028B962A104F10800FBF7CEFDD0B9FEF77E -:1046200053F90546C5F3C000C5F38001C5F3400248 -:1046300005F00103CDE90021029059A2202104A830 -:10464000FFF758F804A800F095FD294657A0FEF79B -:104650004DFD45E004F10800FFF784FE002825D059 -:1046600004F10800FBF788FE0546012D16DB042D3A -:1046700014DC691EC8B2FEF73BF906462B4653A26E -:10468000202104A80096FFF735F804A800F072FD79 -:104690003246294650A0FEF729FD06E020A000F092 -:1046A00033FD294651A0FEF721FD19E01CA000F0C2 -:1046B0002BFD56A0FEF71AFD12E05EA12046FBF787 -:1046C0007BFD30B95BA000F055FD5CA0FEF70EFD50 -:1046D00006E061A000F018FD214660A0FEF706FD8F -:1046E00000BF60E728736B697029000000000000BC -:1046F0005B434D445D20434D443D25732050313D87 -:1047000025732050323D25732043533D25303258C8 -:104710002F253032582025730D0A0000524C00001E -:10472000504152414D0000005B434D445D20496EB5 -:1047300076616C696420524C20706172616D3A2020 -:104740006E6F74206E756D657269630D0A000000EE -:10475000524C2C25640000004F4E00004F4646008E -:104760005B434D445D2052656C6179202D3E2025D0 -:10477000730D0A005B434D445D20496E76616C69A0 -:104780006420524C20706172616D3A2073746174C0 -:10479000653D25640D0A000044490000300000001A -:1047A00044492C2564256425642564005B434D44FD -:1047B0005D20444920616C6C207374617465733AA8 -:1047C000203078253032580D0A00000044492C254D -:1047D000642C2564000000005B434D445D20444987 -:1047E0002564203D2025640D0A0000005B434D44F4 -:1047F0005D20496E76616C6964204449206368617C -:104800006E6E656C3A2025640D0A00005B434D44D2 -:104810005D20496E76616C69642044492070617244 -:10482000616D3A206E6F74206E756D657269630DEF -:104830000A0000004543484F000000005B434D4420 -:104840005D204543484F20726573706F6E7365201D -:1048500073656E740D0A0000434D44005B434D4484 -:104860005D20556E6B6E6F776E20636F6D6D616E40 -:10487000643A2025730D0A0010B50020064908701F -:1048800081F84E0081F84F0081F852004D21024816 -:10489000401CFBF77FFC10BD3402002000200349C0 -:1048A000086003490860034908607047A0000020C1 -:1048B000A4000020A8000020014611B96FF00200FA -:1048C00070470248006808800020F9E7A80000202F -:1048D00030B503460C460BB104B112B96FF00200BB -:1048E00030BD1448006818B900201080401EF7E75A -:1048F00000201080002115E00F48104D2D68405D0C -:1049000058540E480068401CC0F309000B4D286045 -:1049100008480068401E074D28601088401C108021 -:10492000481C81B2A14203DA024800680028E3D1A2 -:104930000020D5E7A8000020700F0020A400002070 -:1049400030B502460B4602B113B96FF0020030BD1C -:1049500000211AE00F480068B0F5806F02D34FF0D5 -:10496000FF30F4E7505C0C4C0C4D2D6860550B4843 -:104970000068401CC0F30900084C2060054800682E -:10498000401C044C2060481C81B29942E2DB0020AC -:10499000DDE70000A8000020700F0020A00000202C -:1049A0000748006850B106480068401E0449086086 -:1049B0000846006810B901200249087070470000DD -:1049C000B0000020B400002010B502210D48FCF713 -:1049D0001BFFA0B9FCF726FF044607E0FCF722FF07 -:1049E000001B642802D36FF0010010BD02210548AE -:1049F000FCF70AFF0028F1D00220FCF761FD00203F -:104A0000F3E70000000C01400548007810B94FF0B2 -:104A1000FF30704700200249087000BFF9E700002E -:104A20009C00002010B5FFF739FF10BD10B50446FB -:104A30002046FFF741FF10BD70B504460D461646EF -:104A4000324629462046FFF743FF70BD08480078EC -:104A500010B14FF0FF30704700200649086006494A -:104A60000860064908600120014908700020F2E74B -:104A70009C000020A0000020A4000020A80000202E -:104A800070B50546FFF7A0FF04460CB1204670BD87 -:104A900035B1012D0FD0022D18D0032D2CD120E0DF -:104AA000002280211C48FCF7B7FE002201211B4890 -:104AB000FCF7B2FE23E0012280211748FCF7ACFE90 -:104AC000002201211548FCF7A7FE18E000228021F2 -:104AD0001148FCF7A1FE012211461048FCF79CFE8C -:104AE0000DE0012280210C48FCF796FE01221146C0 -:104AF0000A48FCF791FE02E06FF00200C7E700BF32 -:104B00000520FCF7DDFCFFF75FFF04460CB12046F3 -:104B1000BDE70020BBE7000000080140000C014099 -:104B200008B5094800684068C0B200900121684695 -:104B3000FFF706FF0A2005490860012204490248E0 -:104B4000FDF7D4FD08BD00005C010020B00000208E -:104B5000AC00002070B504460D4604B115B96FF0E5 -:104B6000020070BD4FF6FF732A4621460448FDF748 -:104B700013FE064616B16FF00100F2E70020F0E7E1 -:104B80005C01002070B505461348007810B14FF065 -:104B9000FF3070BDFFF75AFF044614B14FF0FF30ED -:104BA000F7E735B90D480E490A68026009790171C5 -:104BB00004E00A482968016029790171074800F07A -:104BC000F1F804461CB1FFF71FFF2046E1E7012082 -:104BD000014908700020DCE78C0000208D000020D7 -:104BE000DA53000870B5054615B94FF0FF3070BDB7 -:104BF00028210F48FBF7CEFA00200D49087081F8F4 -:104C00002500084629680162297980F8241020309F -:104C100000F0C8F804460CB12046E8E7002000F098 -:104C2000EDF804460CB12046E1E70020DFE7000084 -:104C3000C00000202DE9F04104460D4616461F46EF -:104C400014B10DB106B11FB94FF0FF30BDE8F081CE -:104C50000A2D02DA4FF0FF30F8E72078542802D10D -:104C60006078582802D04FF0FF30EFE73B463246DD -:104C700002A1E01CFBF7BEFA0020E7E725642E2521 -:104C8000642E000010B500F05DF804460CB120461B -:104C900010BD01200249087081F825000020F7E7C7 -:104CA000C000002010B594B0254890F8250008B940 -:104CB00014B010BD2248007820B1012806D0022887 -:104CC00036D134E001201E49087035E00020039001 -:104CD00003A904A800F02CFB40B30020029001902F -:104CE000039881B201AB02AA04A8FFF7A3FF044610 -:104CF000DCB913484068401C11494860029888613B -:104D0000019848610846C0690199884202D20C495D -:104D10000198C86100F074F9012000F03DF93220DB -:104D2000FCF7CEFB002000F037F900BF04E003E001 -:104D300002200349087000BF00BF00BFB8E70000B1 -:104D4000C000002010B50C48007810B96FF00500C5 -:104D500010BD0A48007810B16FF00100F8E7FFF7C6 -:104D600061FE044614B14FF0FF30F1E70120034922 -:104D700008700020ECE700008C000020920000206A -:104D800010B50446C0200649087008462168C0F8DE -:104D90000110217941710621FFF7DCFE10BD0000F2 -:104DA000700B002070B5054615B96FF0030070BD9B -:104DB000FFF70AFE044614B16FF00200F7E7032084 -:104DC000FFF75EFE044614B16FF00200EFE72846DD -:104DD000FFF7D6FF6420FCF773FB0020FFF750FEBF -:104DE000044614B16FF00200E1E70348296801604E -:104DF000297901710020DAE78D00002070B50446A2 -:104E00002046FFF73DFE054615B16FF0020070BD6C -:104E10000020FCE770B505460E4605B116B96FF0E7 -:104E2000030070BD0848007810B96FF00500F8E77E -:104E300031462846FFF78EFE044614B16FF002009B -:104E4000EFE70020EDE700008C00002070B505467C -:104E500015B94FF0FF3070BD1C210E48FBF79AF9D1 -:104E600000200C4908704876084629684161297974 -:104E700001761430FFF796FF04460CB12046EAE7AE -:104E80000020FFF7BBFF04460CB12046E3E70020FB -:104E9000E1E70000E8000020024602B111B94FF03E -:104EA000FF307047064882600020054B5860184666 -:104EB000C160002018611870012058760020F0E7CA -:104EC000E800002070B588B03248407E08B908B0CC -:104ED00070BDFCF7A7FC04462E48007830B10128CD -:104EE00008D0022842D003284CD14AE001202949A9 -:104EF00008704BE02748406826498968884206D3F5 -:104F0000032024490870002000F0CEF93EE021483B -:104F10000069201A1F49C968884226D31D48406885 -:104F2000431C1C4820218268684600F065F905464C -:104F3000002D16DD29466846FFF76CFF06467EB950 -:104F400014484068401C1349486008460461012029 -:104F500000F0AAF93220FCF7B3FA002000F0A4F91F -:104F600000BF02200B49087000BF0FE0094800692C -:104F7000201A0849C968884202D3012005490870EF -:104F800004E003E003200349087000BF00BF00BF36 -:104F90009DE70000E800002010B5044614B1FFF7BB -:104FA0004FF901E0FFF742F910BD002120F8801F02 -:104FB00041808180C1808038704710B5024601234E -:104FC00072B6B2F88400802806DBB2F88600401C76 -:104FD000A2F88600002310E0B2F88000115432F8E5 -:104FE000804F601CC41700EB5464E411A0EBC414A0 -:104FF00014809088401C9080803A62B6184610BD9C -:105000000D48C069B8B10C48C0690B494968411ADC -:105010000948C160C06958B10748C0686421484365 -:105020000549C969B0FBF1F0C1B20348017402E05F -:105030000021014801747047C0000020F0B589B01C -:1050400004460D46631C19A2202101A80095FEF715 -:1050500051FB0646701EC1B20DF10500FFF72DF899 -:105060000746C6F1200101AA90193B4614A2FEF79B -:1050700041FB0DB114A000E015A00246611C15A073 -:10508000FEF734F801A90020FDF7C0FE01A916A023 -:10509000FEF72CF81B48006828B101AA29462046D3 -:1050A000184B1B68984709B0F0BD00002444495FC5 -:1050B0004556454E542C25642C25642A00000000DA -:1050C000253032580D0A00004849474800000000CA -:1050D0004C4F57005B494F5D2043482564202D3ECF -:1050E0002025730D0A0000005B494F5D205B494F8E -:1050F0005D2052463433332054583A2022257322FF -:105100000D0A00005800002070B588B005462B46F7 -:1051100011A220216846FEF7EDFA0446601EC1B2D6 -:105120000DF10100FEF7BCFF0646C4F120010DEBB6 -:10513000040033460BA2FEF7DDFA0C48006830B1DC -:1051400069460B480078094A1268904702E06846B1 -:10515000FEF746F808B070BD244552522C25732A3C -:1051600000000000253032580D0A00000800002021 -:105170000C00002070B590B005462B4611A24021CE -:105180006846FEF7B7FA0446601EC1B20DF1010091 -:10519000FEF786FF0646C4F140010DEB04003346DE -:1051A0000AA2FEF7A7FA0B48006830B169460A4820 -:1051B0000078084A1268904702E06846FEF710F847 -:1051C00010B070BD244F4B2C25732A002530325867 -:1051D0000D0A0000080000200C00002010B500F0AF -:1051E000CFF80448006820B102480068401E014919 -:1051F000086010BD000000202DE9F84305460E466A -:10520000174698460DB1102E02DA0020BDE8F8834B -:105210003B4607A231462846CDF80080FEF76AFAE1 -:105220000446002C01DDA0B2F0E70020EEE700000C -:1052300054582E2530336C752E2530336C752E0066 -:10524000F8B505466B206843164901EB800606F168 -:105250009004002772B694F80601D0B9B4F804019E -:10526000002816DDB4F80201205C009004F581747A -:105270002188481CC11700EB11610912A0EB012124 -:1052800021806088401E608001202071A4F5817417 -:10529000012762B627B1012269463068FDF7D5FAC9 -:1052A000F8BD00006C06002010B5044614B1FEF7EE -:1052B000DBFF01E0FEF7CEFF10BD002100F580709E -:1052C00001804180818081710181A0F580707047EB -:1052D00070B503460C46002572B6002021E0B3F8F5 -:1052E0000411FF2905DDB3F80811491CA3F80811C2 -:1052F00019E0215CB3F800619955B3F80061711CA5 -:10530000CE1701EB16663612A1EB0626A3F8006154 -:10531000B3F80411491CA3F80411691C8DB2411C97 -:1053200088B29042DBDB00BF62B6284670BD000049 -:10533000F8B506460D4606B10DB90020F8BD0F4878 -:10534000007808B90020F9E76846FFF76FFB0446CC -:105350000CB10020F2E7BDF8000008B90020EDE72D -:105360002A46FF213046FFF767FB04460CB10020B8 -:10537000E4E70020014908700120DFE7B4000020C5 -:1053800000B5FFF70DFB00BD9054000888540008DD -:1053900080540008985400085C010020A4010020FB -:1053A000EC010020A0540008A8540008B0540008E4 -:1053B00002030405060708090A0B0C0D0E0F101056 -:1053C00001020000000000000000010203040607C3 -:1053D0000809000000000102030400001A1704C1BC -:1053E000C1C141542B444556545950453D3F00419D -:1053F000542B4657434F44453D3F000040404040FA -:105400004040404040414141414140404040404097 -:105410004040404040404040404040400502020281 -:1054200002020202020202020202020220202020E4 -:1054300020202020202002020202020202909090EE -:1054400090909010101010101010101010101010DC -:105450001010101010101002020202020288888838 -:10546000888888080808080808080808080808083C -:10547000080808080808080202020240FC53000855 -:105480005741524E20000000494E464F2000000078 -:1054900044454255470000004552524F520000001B -:1054A0005541525431000000554152543200000021 -:1054B0005541525433000000D85400080000002029 -:1054C000C00000009C37000898550008C00000206C -:1054D000B0160000AC37000800000000000000001B -:1054E0000000000000000000000C0140100000005F -:1054F0000000000000000000000C0140200000003F -:105500000000000000000000000C0140400000000E -:105510000000000000000000000C014080000000BE -:10552000000000000000000000000000010000007A -:10553000000000000000000000000000000000006B -:10554000000000000000000001000000000000005A -:10555000000000000000000010000000010000003A -:105560000024F40000000000000000000000000023 -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:08559000000000000000000013 +:10113000401C03F0FFFE04F08FF810BD34020020C5 +:1011400010B5002018E01A4901EB001108700021C9 +:10115000174A02EB00125160154A02EB001291602F +:10116000134A02EB00121173124A22F81010124AAD +:1011700042F82010411CC8B20328E4DB00200F49CC +:1011800008600F4908600F49086001200E49087087 +:101190000E48FFF7B7FF02F067FD01F04DFF0CA00E +:1011A00002F03EFA032114A002F03AFA10BD00004A +:1011B000A0030020720000205005002064000020E1 +:1011C000680000206C00002070000020B54A000874 +:1011D0005B524F555445525D205541525433205374 +:1011E0006D61727420526F7574657220656E6162F4 +:1011F0006C65640D0A0000005B524F555445525D0A +:1012000020496E6974204F4B2C20256420706F722A +:10121000747320726567697374657265640D0A0082 +:1012200070B5A2B000F084FB05460024204601F012 +:10123000BBFD0646002E30DD4B4804702046FFF70C +:1012400067FF12E09DF88410204603F0F7FB294663 +:101250009DF88400FFF790FD444800EB041080687F +:10126000401C424901EB0411886021A9204601F08D +:1012700009FE0028E6DC0020FFF716FF60B12046DB +:1012800003F052FC3A480068401C394908600120CC +:10129000364901EB0411087300BF2AE029469DF886 +:1012A000840002F00BFB044604B3012C02D0022C94 +:1012B0001DD10FE00220FFF72BFF29469DF8840087 +:1012C000FFF75AFD9DF884302AA22FA1002000F0DC +:1012D0009DF80CE09DF8840001F0BAFF9DF8843081 +:1012E0002BA229A1002000F091F800E000BF00BF70 +:1012F00000BF21A9022001F0C5FD0028CEDC284650 +:1013000002F082FA88B1694601A802F06BFC58B17C +:10131000BDF8001001A801F0F3FEBDF8003021A2D5 +:1013200019A1012000F072F800BF02F003F80024B8 +:1013300013E0012C00D10EE0224830F81400002800 +:1013400008DD214850F82400281A322802D320460C +:1013500003F0EAFB00BF601CC4B2032CE9DBFFF71B +:10136000DDFE22B070BD000070000020A003002050 +:1013700068000020434D4420627974653A2030783B +:10138000253032580000000055415254330000000F +:1013900050545820627974653A203078253032589C +:1013A00000000000504153535448524F5547483AAB +:1013B0002025642062797465732071756575656494 +:1013C00000000000720000205005002010B5002031 +:1013D0000349087003F06CFC02A002F09BF910BDF9 +:1013E000780000205B4C4F475D20446562756720A4 +:1013F0006C6F672073797374656D20696E697469A9 +:10140000616C697A65640D0A000000000FB470B564 +:10141000C2B005460E4622480078854203DA42B043 +:1014200070BC5DF814FB304603F05EFC00B9F6E7D3 +:1014300000240EB1304600E01AA01C4A009052F879 +:101440002530C4F5807102AA101919A202F042FEDB +:101450000444FF2C0DDA49A80190C4F5807102AA5A +:101460001019019B489A02F04FFE0444002001909D +:1014700000BF002C0CDDFF2C0ADC0D222046641C72 +:1014800002A90A54FF2C03DC0A222046641C0A54D9 +:10149000002C03DDA1B202A802F0E2F800BFBEE713 +:1014A000780000204D41494E00000000645D0008B6 +:1014B0005B25735D5B25735D20000000704772B68D +:1014C00000BFFEE70146002291F82100022808D063 +:1014D0000420886300BF002081F8200000BF0120A5 +:1014E00070470868006820F00E000B6818600868F4 +:1014F000006820F001000B68186091F8403001206E +:101500009840CB6B5860012081F8210000BF00207B +:1015100081F8200000BF1046E2E7000070B50446E5 +:10152000002594F82100022803D00420A06301259F +:1015300048E02068006820F00E00216808602068FC +:10154000006820F00100216808601F492068884277 +:1015500001D1012026E01C4914312068884201D1C4 +:1015600010201FE0184928312068884201D18015D9 +:1015700018E015493C312068884201D1801411E0FF +:10158000114950312068884202D14FF4803009E07F +:101590000D4964312068884202D14FF4801001E087 +:1015A0004FF08070084908394860012084F8210014 +:1015B00000BF002084F8200000BF606B10B12046FF +:1015C000616B8847284670BD0800024070B504462C +:1015D00000F0AEF906462546681C10B104480078B4 +:1015E000054400BF00F0A4F9801BA842FAD370BDE7 +:1015F000840000202DE9F8470346002294466EE15E +:101600004FF0010808FA02F4D1F8008008EA04005B +:10161000A0427DD1DFF8DCA2D1F80480A8EB0A0952 +:10162000D0453AD014DCB8F1030F50D009DCB8F142 +:10163000000F31D0B8F1010F1CD0B8F1020F49D121 +:1016400020E0B8F1110F18D0B8F1120F42D11EE00E +:10165000B9F5881F25D006DCB9F5803F20D0B9F553 +:10166000801F37D11AE0B9F5001F18D0B9F5041F53 +:1016700030D117E0D1F80CC02DE0D1F80C8008F182 +:10168000040C28E0D1F80C8008F1080C23E0D1F814 +:101690000C8008F10C0C1EE000BF00BF00BF00BFB3 +:1016A00000BF00BFD1F80880B8F1000F02D14FF0A1 +:1016B000040C0BE0D1F80880B8F1010F03D14FF012 +:1016C000080C1C6102E04FF0080C5C6103E04FF075 +:1016D000000C00E000BF00BFFF2801D8984601E0E1 +:1016E00003F104084646FF2802D84FEA820803E0C7 +:1016F000A2F108084FEA88084746D6F800804FF064 +:101700000F0909FA07F928EA09080CFA07F900E0B5 +:1017100088E048EA0908C6F80080D1F8048008F09B +:101720008058B8F1805F7DD100BFDFF8CC81D8F858 +:10173000188048F00108DFF8C091C9F81880C84641 +:10174000D8F8188008F00108CDF8008000BF00BF6D +:101750004FEAB9384FEA920958F829504FEA82788F +:101760004FEA18794FF00F0808FA09F825EA08053A +:10177000DFF88881434502D14FF0000816E0DFF81A +:101780008081434502D14FF001080FE0DFF87481FA +:10179000434502D14FF0020808E0DFF86C81434571 +:1017A00002D14FF0030801E04FF004084FEA8279BC +:1017B0004FEA197908FA09F848EA0505DFF84C817B +:1017C0004FEA920948F82950D1F8048008F48018AB +:1017D000B8F5801F0AD1DFF83881D8F8008048EAD0 +:1017E0000008DFF82C91C9F8008009E0DFF82081BB +:1017F000D8F8008028EA0008DFF81491C9F80080C2 +:10180000D1F8048008F40018B8F5001F10D1DFF8F3 +:10181000008108F10408D8F8008048EA0008DFF8E1 +:10182000F09000E05AE009F10409C9F800800DE0E9 +:10183000DFF8DC8008F10408D8F8008028EA000806 +:10184000DFF8CC9009F10409C9F80080D1F80480D0 +:1018500008F40038B8F5003F0ED1DFF8B480A8F1E5 +:101860000408D8F8008048EA0008DFF8A490A9F13D +:101870000409C9F800800DE0DFF89480A8F104089D +:10188000D8F8008028EA0008DFF88490A9F104095C +:10189000C9F80080D1F8048008F48038B8F5803F9A +:1018A0000ED1DFF86C80A8F10808D8F8008048EA6B +:1018B0000008DFF85C90A9F10809C9F800800DE084 +:1018C000DFF84C80A8F10808D8F8008028EA000862 +:1018D000DFF83C90A9F10809C9F80080521CD1F842 +:1018E000008028FA02F8B8F1000F7FF489AEBDE855 +:1018F000F8870000000011100010024000080140AD +:10190000000C01400010014000140140080001409B +:1019100008040140024693680B400BB1012000E02F +:10192000002070470AB1016101E00B0403617047B8 +:1019300001480068704700007C00002003480068F0 +:101940000349097808440149086070477C00002079 +:101950008400002010B50848006840F010000649D7 +:101960000860032000F0A8F80F2000F007F800F04E +:101970002BF8002010BD00000020024070B5044686 +:101980000E4800784FF47A71B1FBF0F00C49096809 +:10199000B1FBF0F5284600F09DFC08B1012070BDB8 +:1019A000102C07D200222146501E00F047F80548AF +:1019B000046001E00120F2E70020F0E7840000204D +:1019C000880000208000002008B500BF1148806911 +:1019D00040F001000F4988610846806900F001006D +:1019E000009000BF00BF00BF0846C06940F08050B3 +:1019F000C8610846C06900F08050009000BF00BF79 +:101A000000BF0549486820F0E06040F00070486081 +:101A100000BF08BD0010024000000140014608461A +:101A2000002809DB00F01F0301229A4043099B00B4 +:101A300003F1E023C3F8002100BF70472DE9F05FF8 +:101A400080460D461646002702F078FB07463946C9 +:101A50002A46334601F00700C0F1070ABAF1040F25 +:101A600002D94FF0040A01E0C0F1070AD14600F1A3 +:101A7000040ABAF1070F02D24FF0000A01E0A0F108 +:101A8000030AD4464FF0010A0AFA09FAAAF1010A38 +:101A90000AEA020A0AFA0CFA4FF0010B0BFA0CFBE5 +:101AA000ABF1010B0BEA030B4AEA0B04214640465B +:101AB00002F04CFBBDE8F09F00BF00F00702064BB0 +:101AC00019684FF6FF031940044B0B4343EA022108 +:101AD000014B196000BF70470CED00E00000FA05F3 +:101AE00070B504460D460CB9012070BD5A48006817 +:101AF00000F00700A8420ED25748006820F0070007 +:101B00002843554908600846006800F00700A842CD +:101B100001D00120E9E7207800F0020002281DD161 +:101B2000207800F00400042805D14C48406840F4B7 +:101B3000E0604A494860207800F00800082805D194 +:101B40004648406840F46050444948604348406813 +:101B500020F0F000A168084340494860207800F078 +:101B6000010078B36068012806D13C48006800F4A1 +:101B7000003090B90120B8E76068022806D13748E4 +:101B8000006800F0007040B90120AEE733480068FB +:101B900000F0020008B90120A7E73048406820F0B3 +:101BA0000300616808432D494860FFF7C1FE0646FF +:101BB00009E0FFF7BDFE801B41F28831884202D95F +:101BC000032092E707E02548406800F00C006168B8 +:101BD000B0EB810FEDD12048006800F00700A8426B +:101BE0000ED91D48006820F0070028431A490860F4 +:101BF0000846006800F00700A84201D0012074E701 +:101C0000207800F00400042807D11448406820F42C +:101C1000E060E168084311494860207800F008005E +:101C2000082808D10D48406820F46050216940EA36 +:101C3000C1000A49486000F03FF808494968C1F30B +:101C40000311074A515CC84006490860064800680D +:101C5000FFF794FE002048E70020024000100240F9 +:101C60009E5D000888000020800000200148006878 +:101C7000704700008800002000B5FFF7F7FF044917 +:101C80004968C1F30221034A515CC84000BD00000D +:101C900000100240AE5D000800B5FFF7E7FF044901 +:101CA0004968C1F3C221034A515CC84000BD00002D +:101CB00000100240AE5D000870B500210022002433 +:101CC00000230020134D696801F00C05F5B1042DC7 +:101CD00002D0082D19D101E00F4819E00F4DC1F3D2 +:101CE0008346AB5D01F4803555B10A4D6D68C5F38F +:101CF00040450B4E725D084D5D43B5FBF2F402E0CA +:101D0000084D03FB05F4204602E000BF024800BF77 +:101D100000BF70BD0010024000127A008C5D000808 +:101D20009C5D000800093D00F8B504460CB901208F +:101D3000F8BD207800F00100002878D0F84840680D +:101D400000F00C0004280CD0F548406800F00C00AE +:101D5000082811D1F248406800F48030B0F5803F87 +:101D60000AD1EF48006800F4003000285FD06068B6 +:101D700000285CD10120DBE700BF6068B0F5803F40 +:101D800006D1E748006840F48030E549086028E063 +:101D9000606858B9E248006820F48030E049086083 +:101DA0000846006820F4802008601AE06068B0F5FA +:101DB000A02F0BD1DA48006840F48020D849086091 +:101DC0000846006840F4803008600AE0D4480068A3 +:101DD00020F48030D24908600846006820F4802052 +:101DE000086000BF606888B1FFF7A2FD054606E005 +:101DF000FFF79EFD401B642801D9032098E7C848DF +:101E0000006800F400300028F2D010E0FFF790FDE9 +:101E1000054606E0FFF78CFD401B642801D903202E +:101E200086E7BF48006800F400300028F2D120782F +:101E300000F00200022857D1B948406800F00C00B9 +:101E400050B1B748406800F00C00082818D1B448D9 +:101E5000406800F4803098B9B148006800F0020092 +:101E600020B12069012801D0012061E7AC48006859 +:101E700020F0F800616940EAC100A949086033E038 +:101E80002069E8B10120A7490860FFF751FD054628 +:101E900006E0FFF74DFD401B022801D9032047E76C +:101EA0009F48006800F002000028F2D09C480068BB +:101EB00020F0F800616940EAC1009949086013E028 +:101EC000002098490860FFF733FD054606E0FFF75C +:101ED0002FFD401B022801D9032029E79048006804 +:101EE00000F002000028F2D1207800F00800082855 +:101EF0002DD1A069B8B101208B490860FFF718FD0A +:101F0000054606E0FFF714FD401B022801D9032017 +:101F10000EE78348406A00F002000028F2D001205A +:101F200001F078FA13E000207F490860FFF700FD18 +:101F3000054606E0FFF7FCFC401B022801D9032000 +:101F4000F6E67748406A00F002000028F2D12078D7 +:101F500000F00400042873D100277148C06900F024 +:101F6000805070B900BF6E48C06940F080506C4925 +:101F7000C8610846C06900F08050009000BF00BFF3 +:101F800001276A48006800F48070B0B967480068AB +:101F900040F4807065490860FFF7CAFC054606E01A +:101FA000FFF7C6FC401B642801D90320C0E65F4848 +:101FB000006800F480700028F2D000BFE0680128BB +:101FC00006D15748006A40F001005549086227E0F1 +:101FD000E06858B95248006A20F001005049086290 +:101FE0000846006A20F00400086219E0E06805284D +:101FF0000BD14B48006A40F004004949086208468A +:10200000006A40F0010008620AE04548006A20F0DA +:102010000100434908620846006A20F00400086293 +:1020200000BFE068A0B1FFF783FC054609E0FFF7B9 +:102030007FFC401B41F28831884202D9032077E6B9 +:1020400022E03748006A00F002000028EFD012E0DA +:10205000FFF76EFC054608E0FFF76AFC401B41F203 +:102060008831884201D9032062E62D48006A00F0D9 +:1020700002000028F0D1012F05D12948C06920F0C5 +:1020800080502749C86100BFE069C8B32448406850 +:1020900000F00C00082860D0E069022848D1002038 +:1020A00020490866FFF744FC054606E0FFF740FCC0 +:1020B000401B022801D903203AE61948006800F0C5 +:1020C00000700028F2D1206AB0F5803F07D1144893 +:1020D000406820F40030A168084311494860D4E901 +:1020E000080108430E49496821F4741108430C495A +:1020F000486001200B490866FFF71AFC054607E017 +:102100003DE0FFF715FC401B022801D903200FE634 +:102110000348006800F000700028F2D02FE00000B3 +:102120000010024000004242800442420070004021 +:10213000002014490866FFF7FBFB054606E0FFF7A1 +:10214000F7FB401B022801D90320F1E50E48006887 +:1021500000F000700028F2D111E0E069012800D100 +:10216000E6E50948466806F48031206A814204D1D8 +:1021700006F47011606A814201D00120D8E5002088 +:10218000D6E50000000042420010024010B50446AF +:102190000CB9012010BD606A38B96068B0F5827F63 +:1021A00000D105E00021E16102E0002121616161CF +:1021B0000021A16294F8510028B9002084F8500051 +:1021C000204600F043F8022084F85100206800689F +:1021D00020F0400021680860A08800F48270218906 +:1021E00001F404410843A18901F400610843217C02 +:1021F00001F002010843217D01F001010843218B18 +:1022000001F400710843217F01F0380108432021C7 +:10221000095D01F080010843218D01F4005108435C +:10222000216808600421A06901EA10402168486023 +:102230002068C06920F400602168C86100206065E2 +:10224000012084F851000020A4E7000010B586B0FA +:102250000446002002900390049005901A492068DB +:1022600088422FD100BF1948C06940F48040174907 +:10227000C8610846C06900F48040019000BF00BFFB +:1022800000BF0846806940F0080088610846806900 +:1022900000F00800019000BF00BF4FF42040029002 +:1022A000022003900320059002A90948FFF7A2F934 +:1022B0004FF48040029000200390049002A904484B +:1022C000FFF798F906B010BD00380040001002403A +:1022D000000C014070B504462546681EB0F1807FB1 +:1022E00001D301200FE0681E4FF0E02148610F216B +:1022F0004FF0FF3001F02AFF00204FF0E02188610D +:1023000007200861002070BD704770472DE9F84F25 +:102310000446206805682068C668206847694FF051 +:102320000009CA4605F00F09B9F1000F0AD105F0FE +:10233000200038B106F0200020B1204601F00AFD4F +:10234000BDE8F88FB9F1000F7BD007F0010018B994 +:1023500006F49070002874D005F0010030B106F446 +:10236000807018B1606C40F00100606405F00400FA +:1023700030B107F0010018B1606C40F002006064F9 +:1023800005F0020030B107F0010018B1606C40F0B8 +:102390000400606405F0080048B106F0200010B9A0 +:1023A00007F0010018B1606C40F008006064606CD8 +:1023B000002845D005F0200028B106F0200010B11B +:1023C000204601F0C7FC20684069C0F3801A606CA9 +:1023D00000F0080010B9BAF1000F2CD0204601F02F +:1023E00073FC2068406900F0400000B300BF00BFEC +:1023F0002168143151E8001F21F040002168143198 +:1024000041E80002002AF3D100BFE06B50B17748E9 +:10241000E16B4863E06BFFF781F888B1E06B416BDB +:1024200088470DE02046FFF770FF09E009E02046ED +:10243000FFF76BFF04E02046FFF767FF00206064B2 +:102440007EE7206B012877D105F01000002873D0BB +:1024500006F010000028FAD000BF0020009020688D +:102460000068009020684068009000BF00BF2068AE +:10247000406900F0400000285FD0E06B00684068D1 +:102480001FFA80F8B8F1000F55D0A08D404552DDFD +:10249000A4F82E80E06B8069202843D000BF00BFE5 +:1024A00021680C3151E8001F21F4807021680C3143 +:1024B00041E80002002AF3D100BF00BF00BF21683D +:1024C000143151E8001F21F001002168143141E866 +:1024D0000002002AF3D100BF00BF00BF2168143101 +:1024E00051E8001F21F040002168143141E800024A +:1024F000002AF3D100BF202084F84200002020638E +:1025000000BF00BF21680C3151E8001F21F010000E +:1025100021680C3141E80002002AF3D100BFE06BD2 +:10252000FEF7D0FF02206063A08DE28D801A81B299 +:102530002046FFF7E9FE03E742E0A08DE18D401A57 +:102540001FFA80F8E08DD0B3B8F1000F37D000BF8C +:1025500000BF21680C3151E8001F21F49070216800 +:102560000C3141E80002002AF3D100BF00BF00BFD8 +:102570002168143151E8001F21F001002168143155 +:1025800041E80002002AF3D100BF202084F8420075 +:102590000020206300BF00BF21680C3151E8001FFC +:1025A00021F0100021680C3141E80002002AF3D12B +:1025B00000BF0220606341462046FFF7A5FEBFE64C +:1025C00005F0800030B106F0800018B1204601F01F +:1025D000DDFCB5E605F0400030B106F0400018B172 +:1025E000204601F0A7FBABE600BFA9E6B53C00081A +:1025F00010B504460CB9012010BDA06900B100E07F +:1026000000BF94F8410028B9002084F8400020461B +:1026100000F02AF8242084F841002068C06820F4E3 +:1026200000502168C860204601F012FC2068006953 +:1026300020F49040216808612068406920F02A0059 +:10264000216848612068C06840F400502168C86073 +:1026500000206064202084F8410084F842000020BB +:10266000606300BFC8E7000010B586B004460020D4 +:10267000029003900490059059492068884237D110 +:1026800000BF5848806940F4804056498861084638 +:10269000806900F48040019000BF00BF00BF084681 +:1026A000806940F0040088610846806900F00400F9 +:1026B000019000BF00BF4815029002200390032044 +:1026C000059002A94848FEF795FF4FF480600290FC +:1026D00000200390049002A94348FEF78BFF0022DC +:1026E00011462520FFF7AAF92520FFF797F975E095 +:1026F0003E492068884236D100BF3A48C06940F45C +:1027000000303849C8610846C06900F400300190C3 +:1027100000BF00BF00BF0846806940F00400886128 +:102720000846806900F00400019000BF00BF04204B +:102730000290022003900320059002A92A48FEF788 +:1027400059FF0820029000200390049002A9264817 +:10275000FEF750FF002201212620FFF76FF9262007 +:10276000FFF75CF93AE022492068884236D100BF81 +:102770001C48C06940F480201A49C8610846C069F5 +:1027800000F48020019000BF00BF00BF08468069B0 +:1027900040F0080088610846806900F00800019058 +:1027A00000BF00BF0815029002200390032005908F +:1027B00002A91048FEF71EFF4FF4006002900020AF +:1027C0000390049002A90B48FEF714FF0022022197 +:1027D0002720FFF733F92720FFF720F906B010BDB7 +:1027E0000038014000100240000801400044004051 +:1027F00000480040000C014070B504460D461646E6 +:1028000094F8420020280BD105B10EB9012070BD0B +:102810000020206332462946204601F097FBF6E768 +:102820000220F4E770B5044616492068884208D1B2 +:102830001548057802F064FE2946002000F06EFA83 +:102840001FE01249206888420DD1FFF771F8054654 +:1028500029460F480078FEF78FFA01220C490D48EF +:10286000FFF7CAFF0DE00C492068884209D10B48E8 +:102870000178022000F052FA012208490848FFF7C7 +:10288000BBFF70BD00380140AC0000200044004098 +:1028900004000020A40100200048004005000020A2 +:1028A000EC0100202DE9F84F04460E4617469946E4 +:1028B0004FF0000A94F8410020284AD106B117B918 +:1028C0000120BDE8F88F00206064212084F84100D9 +:1028D000FFF72EF88246A784E784A068B0F5805FF2 +:1028E00004D1206910B90025B04602E035464FF00A +:1028F00000081BE05346002280212046CDF80090BE +:1029000001F074FB08B10320DBE745B9B8F800001B +:10291000C0F308002168486008F1020803E0287845 +:10292000216848606D1CE08C401EE084E08C00282B +:10293000E0D15346002240212046CDF8009001F01E +:1029400055FB08B10320BCE7202084F8410000209B +:10295000B7E70220B5E710B5034693F841002028F9 +:1029600013D101B10AB9012010BD19629A84DA8429 +:1029700000205864212083F841001868C06840F0A6 +:1029800080001C68E0600020EEE70220ECE7000019 +:1029900010B504460B492068884203D1002000F09E +:1029A000FBFA0DE008492068884202D100F0F6FEEB +:1029B00006E006492068884202D1022000F0ECFAC5 +:1029C00010BD0000003801400044004000480040B5 +:1029D00000BFFEE70021002009E0074A02EB0012D9 +:1029E00092791AB1012282400A43D1B2401C0428D4 +:1029F000F3DB084670470000100000200146042960 +:102A000001DB00207047024800EB01108079F9E7F4 +:102A10001000002070B5002512E0114800EB0514ED +:102A2000A1882068FEF776FF08B1012000E00020B1 +:102A3000A071A07920720120E0710020E0606D1C7F +:102A4000042DEADB002007490860012006490870D0 +:102A5000FFF7C0FF0446214604A000F0E1FD70BD71 +:102A60001000002050000020540000205B494F5D02 +:102A700020496E6974204F4B2C20696E697469611E +:102A80006C207374617465733A2030782530325845 +:102A90000D0A00002DE9F041FEF74AFF07461C48E9 +:102AA0000068381A0A2801D2BDE8F081184807608A +:102AB000002628E0174800EB0614A1882068FEF7DE +:102AC00029FF08B1012000E000200546207AA84235 +:102AD00003D00020E071257214E0E079032803DAC6 +:102AE000E079401CE0710DE0A079A8420AD0A57100 +:102AF000E068401CE0600848007818B1F0B2294650 +:102B000002F08CFF761C042ED4DB00BFCCE7000063 +:102B100050000020100000205400002000B585B0B7 +:102B20000020019002900390049000BF3C4880690F +:102B300040F010003A4988610846806900F01000B2 +:102B4000009000BF00BF00BF0846806940F0200031 +:102B500088610846806900F02000009000BF00BF37 +:102B600000BF0846806940F004008861084680691B +:102B700000F00400009000BF00BF00BF084680695D +:102B800040F0080088610846806900F00800009065 +:102B900000BF00BF012280212248FEF7C3FE0122B0 +:102BA00005212148FEF7BEFE002241F208211E4801 +:102BB000FEF7B8FE00224FF401411A48FEF7B2FEBC +:102BC00048F2801001900120029000200390022022 +:102BD000049001A91348FEF70DFD41F20D2001906C +:102BE00001200290002003900220049001A90E48C9 +:102BF000FEF700FD022001900020029001200390CA +:102C000001A90948FEF7F6FCF0200190002002908F +:102C1000039001A90448FEF7EDFC05B000BD0000DB +:102C20000010024000080140000C014010B50E48A1 +:102C30000E4908604FF48270486000210B488160A3 +:102C4000C160016141614FF4007181610021C16186 +:102C50000162416281620A21C162FFF797FA08B1FD +:102C6000FEF72DFC10BD00000038004004010020DC +:102C700010B50B480B4908604FF41650486000210E +:102C800008488160C16001610C21416100218161BE +:102C9000C161FFF7ADFC08B1FEF711FC10BD0000EB +:102CA000003801405C01002010B50B480B4908605A +:102CB0004FF4E1304860002108488160C160016143 +:102CC0000C21416100218161C161FFF791FC08B1D4 +:102CD000FEF7F5FB10BD000000440040A4010020F9 +:102CE00010B50B480B4908604FF41650486000219E +:102CF00008488160C16001610C214161002181614E +:102D0000C161FFF775FC08B1FEF7D9FB10BD0000EB +:102D100000480040EC01002000BFFEE770B505460A +:102D20000E46032D00DB70BD6B2068430E4901EB9E +:102D3000800494F8A80100B9F5E7314604F10800D1 +:102D400002F02BFE40B9D4F8A401401CC4F8A40141 +:102D500006A0616800F064FCD4F89C01401CC4F833 +:102D60009C0100BFDFE700006C0600205B4D554171 +:102D700052545D202573205258206F766572666C20 +:102D80006F770D0A000000000146032901DB03A054 +:102D90007047044850F82100FAE70000554E4B4EAA +:102DA0004F574E00805D00080146032901DB0020DB +:102DB000704772B66B204843034B03EB8000B0F8BA +:102DC0008C2062B61046F3E76C060020014603290A +:102DD00001DB0020704772B66B204843054B03EBC4 +:102DE0008000B0F89401C0F5807082B262B61046DF +:102DF000F0E700006C06002070B5002520E06B2095 +:102E00006843134901EB8004124850F82500206004 +:102E1000114850F82500606004F1080002F0B5FD8B +:102E200004F1900002F037FF002004F5CE7404F89E +:102E3000020C20606060A06001202073681CC5B295 +:102E4000032DDCDB032105A000F0EAFB70BD0000D0 +:102E50006C060020745D0008805D00085B4D5541E4 +:102E600052545D20496E6974204F4B2C20256420FC +:102E7000706F72747320636F6E66696775726564D4 +:102E80000D0A000010B502460B46032A00DA0BB902 +:102E9000002010BD6B205043104C04EB800000F16B +:102EA000080172B6B1F8840010B962B60020F0E7EC +:102EB000B1F88200085C187031F8824F601CC417AA +:102EC00000EB5464E411A0EBC4140C804888401E4D +:102ED0004880823962B60120DBE700006C060020E2 +:102EE0002DE9F04105460F469046032D03DA17B150 +:102EF000B8F1000F01D1BDE8F081012D04D14146A8 +:102F0000384600F0ADFBF6E76B2068430C4901EB57 +:102F1000800494F8A80100B9EDE74246394604F16F +:102F2000900002F0C3FE0646002E07DDD4F8A00193 +:102F30003044C4F8A001284602F070FE00BFDAE772 +:102F40006C06002070B505460C4604B970BD2046DD +:102F5000FDF72BF986B2324621462846FFF7C0FF1F +:102F600000BFF3E770B5002411E06B20604309490E +:102F700001EB800595F8A80100B906E0012C00D10D +:102F800003E0204602F04AFE00BF601CC4B2032CDE +:102F9000EBDB70BD6C060020F8B50546032D00DBA9 +:102FA000F8BD012D02D100F0F9FBF9E76B20684371 +:102FB000164901EB800606F19004002772B6002046 +:102FC00084F80601B4F80401002816DDB4F8020103 +:102FD000205C009004F581742188481CC11700EB27 +:102FE00011610912A0EB012121806088401E6080E0 +:102FF00001202071A4F58174012762B627B1012256 +:1030000069463068FFF7A7FC00BFC9E76C060020DF +:1030100000BFFEE710B50020FFF7D8FE002806DD50 +:103020000448B0F81A02002801DD012010BD00207C +:10303000FCE70000700B002010B54FF40C711F4826 +:10304000FDF7A8F800201BE0002100EB400202EB96 +:1030500080121A4B03EB420282F8841000EB40020C +:1030600002EB801203EB4202A2F8801000EB400258 +:1030700002EB801203EB4202A2F88210411CC8B29C +:103080000428E1DB00200D4981F8180281F81902BB +:10309000A1F81A02C1F81C0200210848C0F8201249 +:1030A000C0F82412C0F828120120044981F82C022B +:1030B000410203A000F0B4FA10BD0000700B002024 +:1030C0005B5054585D20506173737468726F7567FC +:1030D0006820656E67696E6520696E697469616CE8 +:1030E000697A65642C206275666665722073697AF8 +:1030F000653A2025642062797465730D0A0000002A +:103100002DE9F04781460F46B9F1000F00D017B9FD +:103110000020BDE8F087374C0026B04656E094F812 +:103120001812481CC11700EB91718910A0EB8101A6 +:1031300001F0FF0A94F81902504510D1B4F81A02B0 +:1031400000280CDD4FF409700059401C4FF4097140 +:1031500008513A46414628A000F062FA38E094F857 +:10316000180200EB400101EB801004EB400595F8DC +:10317000840018B1B5F88000802813DB95F884002E +:1031800048B184F818A294F8180200EB400101EB52 +:10319000801004EB4005002025F8800F6880012096 +:1031A0002871803D19F8081035F8802F2888401CB8 +:1031B00025F88009A954B4F81A02401CA4F81A0290 +:1031C000701C86B208F101001FFA80F8B845A6DB32 +:1031D00000BF002E0CDD4FF408700059401C4FF466 +:1031E00008710851B4F81A2231460DA000F018FAFF +:1031F00030468EE7700B00205B5054585D204275BE +:1032000066666572206F766572666C6F7720617492 +:1032100020627974652025642F25640D0A00000062 +:103220005B5054585D205075736865642025642098 +:10323000627974657320746F206275666665722C9E +:103240002070656E64696E673A2025640D0A00007F +:103250002DE9F04107462C4C94F82C0210B90020BF +:10326000BDE8F08194F81812481CC11700EB917169 +:103270008910A0EB8101CEB294F81902B04211D1AD +:10328000B4F81A0200280DDD4FF409700059401CF3 +:103290004FF409710851084601591CA000F0C0F90B +:1032A0000020DDE794F8180200EB400101EB8010EC +:1032B00004EB400595F8840018B1B5F8800080282B +:1032C00013DB95F8840048B184F8186294F818026A +:1032D00000EB400101EB801004EB4005002025F8D5 +:1032E000800F688001202871803D35F8801F288874 +:1032F000401C25F880096F54B4F81A02401CA4F849 +:103300001A020120ACE70000700B00205B505458FB +:103310005D204275666665722066756C6C2C206F48 +:10332000766572666C6F7720636F756E743A2025D0 +:10333000640D0A0038B52B4C94F82C0200B938BD46 +:10334000B4F81A0200B9FAE7FFF764FE38B94FF48F +:103350000A700059401C4FF40A710851EFE794F8C5 +:10336000190200EB400101EB801004EB400595F8D9 +:10337000840028B1B5F88200B5F88010884211DBCE +:1033800095F8840010B1002085F8840094F8191293 +:10339000481CC11700EB91718910A0EB810184F8E2 +:1033A0001912CCE735F8821F2888401C25F88209BD +:1033B000685C0090012269460020FFF791FDB4F897 +:1033C0001A02401EA4F81A02D4F81C02401CC4F8C9 +:1033D0001C02B4F81A229DF8001003A000F020F996 +:1033E00000BFACE7700B00205B5054585D20536564 +:1033F0006E742062797465203078253032582C2024 +:1034000070656E64696E673A2025640D0A000000DD +:103410007047000008B508490968C9084FF47A7276 +:10342000B1FBF2F14143009100BF00BF00994A1E79 +:1034300000920029F9D108BD8800002010B50022B3 +:103440004FF400410548FEF76DFA0020044908706A +:103450000449086004A000F0E3F810BD0008014032 +:103460005C000020600000205B52454C41595D200B +:10347000496E6974204F4B2C2073746174653D4F05 +:1034800046460D0A0000000070B50446FEF750FAEB +:10349000054615480068281A642803D213A000F0D6 +:1034A000BFF870BD1A480078A04208D10CB119A02D +:1034B00000E019A0014619A000F0B2F8F1E7224699 +:1034C0004FF400411D48FEF72DFA114804700648DC +:1034D00005600CB10FA000E00FA0014618A000F09D +:1034E0009FF800BFDDE70000600000205B52454C04 +:1034F00041595D20546F67676C6520746F6F20665B +:103500006173742C2069676E6F7265640D0A000028 +:103510005C0000204F4E00004F4646005B52454C79 +:1035200041595D20537461746520756E6368616EE6 +:103530006765643A2025730D0A0000000008014009 +:103540005B52454C41595D2052656C6179202D3E9E +:103550002025730D0A000000704710B502F02CFB07 +:10356000FEF7ECF910BD00B58FB0282105A8FCF7D7 +:1035700011FE14216846FCF70DFE012005900004A1 +:103580000690002007900120099002200C90C103B2 +:103590000D914FF4E0110E9105A8FEF7C5FB08B19F +:1035A000FDF78DFF0F200090022001900020029077 +:1035B0004FF4806003900020049002216846FEF7DB +:1035C0008FFA08B1FDF77BFF0FB000BD7047000018 +:1035D00010B500200849A1F80001A1F80201A1F8E6 +:1035E000040181F80601A1F808014FF4807103A0DD +:1035F00000F016F810BD0000940200205B55415207 +:1036000054325D20496E6974204F4B2C20627566E0 +:103610006665722073697A653A2025640D0A000098 +:103620000FB410B5A2B0249818B922B010BC5DF840 +:1036300014FB25A80190802102A8019B249A00F088 +:1036400063FD044600200190002C06DB802C00DB8B +:103650007F24A1B202A800F003F800BFE5E7000054 +:10366000F8B504460D4605B104B9F8BD002600279B +:1036700072B6002029E02549B1F80411FF2907DDC1 +:103680002249B1F80811491C204AA2F808111EE08D +:10369000215C1E4AB2F800211C4B99541A46B2F81C +:1036A0000021511CCA1701EB12621212A1EB022277 +:1036B000A3F800211946B1F80411491C1A46A2F8D2 +:1036C0000411711C8EB2411C88B2A842D3DB00BF2A +:1036D000002E08DD0D4890F8060120B901200B49A5 +:1036E00081F80601012762B66FB172B60748B0F8DB +:1036F00002010649085C009062B60122694604484E +:10370000FFF729F900BF00BFAFE7000094020020D7 +:10371000A401002070B5044604B970BD2046FCF732 +:1037200044FD85B229462046FFF79AFF00BFF4E723 +:1037300038B572B6174890F8060118B91548B0F8B0 +:10374000040108B962B638BD1248B0F8024101461A +:10375000B1F80211481CC11700EB11610912A0EB6E +:1037600001210C4AA2F802111046B0F80401401ED3 +:103770001146A1F80401012081F806010846005D08 +:10378000009062B6012269460348FFF7E4F800BFE3 +:10379000D9E7000094020020A401002038B50025DC +:1037A00072B60020164981F806010846B0F80401F7 +:1037B00000281CDD0846B0F80241B1F80211481C8F +:1037C000C11700EB11610912A0EB01210C4AA2F80C +:1037D00002111046B0F80401401E1146A1F8040180 +:1037E000012081F806010846005D0090012562B6BF +:1037F00025B1012269460348FFF7ADF838BD000046 +:1038000094020020A401002070B50546134C2078D6 +:1038100001280FD1B4F88C0000280BDDA068281A0D +:10382000322807D30420207032210DA0FFF7F8FEC4 +:10383000012070BD207802280DD16068281AC828A0 +:1038400009D300202070A4F88C00C82110A0FFF735 +:10385000E7FE0120EDE70020EBE70000A00D0020CF +:103860005B50524F544F5D205343414E2074696D5D +:10387000656F757420E2869220504153535448522C +:103880004F55474820282564206D73290D0A0000F4 +:103890005B50524F544F5D20434D445F4D4F444564 +:1038A0002074696D656F757420E2869220494E49D7 +:1038B0005420282564206D73290D0A0070B5054633 +:1038C0000E46484C207880B1207801280DD0207811 +:1038D00002280AD02078042807D000202070A4F8FD +:1038E0008C00217840A0FFF79BFE21782A464CA04F +:1038F000FFF796FE207830B101281DD002284CD069 +:10390000042867D15FE06660242D09D10220207071 +:103910000020A4F88C004DA0FFF782FE012070BDAE +:1039200001202070A6602573A4F88C00294651A0C0 +:10393000FFF776FE0020F2E76660242D13D1B4F87D +:103940008C00002808DD04202070B4F88C1053A0EF +:10395000FFF766FE0220E2E7022020705CA0FFF77E +:103960005FFE0120DBE70A2D08D104202070B4F8A7 +:103970008C1064A0FFF754FE0220D0E7B4F88C004E +:10398000802808D234F88C1F2088401C24F88C0929 +:1039900004F10C0045540020C1E766600A2D08D1EF +:1039A00000202070A4F88C0063A0FFF739FE0120EE +:1039B000B5E70D2D01D10120B1E7294668A0FFF739 +:1039C0002FFE0120ABE7294670A0FFF729FE6660B5 +:1039D0000220A4E70020207078A0FFF721FE00203D +:1039E0009DE70000A00D00205B50524F544F5D201A +:1039F00050726F746F636F6C2073746174652069AB +:103A00006E76616C696428307825303258292C2014 +:103A1000726573657420746F20494E49540D0A0015 +:103A20005B50524F544F5D20466565644279746522 +:103A30002073746174653D25642C20627974653D42 +:103A40003078253032580D0A000000005B50524F8C +:103A5000544F5D20494E495420E2869220434D4404 +:103A60005F4D4F44452028676F7420272427290D78 +:103A70000A0000005B50524F544F5D20494E49549C +:103A800020E28692205343414E2028627974653AA1 +:103A900020307825303258290D0A00005B50524FF3 +:103AA000544F5D205343414E20E2869220504153B3 +:103AB000535448524F5547482028676F7420272495 +:103AC000272C202564206279746573290D0A000073 +:103AD0005B50524F544F5D205343414E20E286923B +:103AE00020434D445F4D4F44452028656D707479E7 +:103AF000207363616E2C20676F7420272427290DA3 +:103B00000A0000005B50524F544F5D205343414E1A +:103B100020E2869220504153535448524F55474813 +:103B20002028676F7420275C6E272C202564206274 +:103B300079746573290D0A005B50524F544F5D2014 +:103B4000434D445F4D4F444520E2869220494E4903 +:103B5000542028676F74205C6E290D0A0000000055 +:103B60005B50524F544F5D20434D445F4D4F444591 +:103B700020E2869220434D442028627974653A20E1 +:103B8000307825303258290D0A0000005B50524F22 +:103B9000544F5D20504153535448524F554748208D +:103BA000E28692205054582028627974653A203079 +:103BB0007825303258290D0A000000005B50524F22 +:103BC000544F5D20556E6B6E6F776E207374617409 +:103BD000652C20726573657420746F20494E4954BA +:103BE0000D0A000070B506460D46104C20780428DA +:103BF00019D1B4F88C00002815DD56B14DB1B4F8D8 +:103C00008C2004F10C013046FCF7ABFAB4F88C00C0 +:103C100028800020A4F88C002070298804A0FFF7D9 +:103C2000FFFC012070BD0020FCE70000A00D00207B +:103C30005B50524F544F5D204765745061737374ED +:103C400068726F756768446174613A202564206208 +:103C5000797465732C206261636B20746F20494E08 +:103C600049540D0A0000000010B594210448FCF7E7 +:103C700091FA00200249087002A0FFF7D1FC10BDA4 +:103C8000A00D00205B50524F544F5D2050726F7456 +:103C90006F636F6C206469736372696D696E6174C0 +:103CA0006F7220696E697469616C697A65640D0A66 +:103CB0000000000070B505466C6A0020E085E084D5 +:103CC0002046FEF722FB70BD00BF00BF02680C3229 +:103CD00052E8002F22F4907102680C3242E800137F +:103CE000002BF3D100BF00BF00BF0268143252E8BE +:103CF000002F22F001010268143242E80013002B69 +:103D0000F3D100BF016B01290ED100BF00BF0268D3 +:103D10000C3252E8002F22F0100102680C3242E807 +:103D20000013002BF3D100BF202180F842100021A6 +:103D30000163704710B504462068C06820F0400059 +:103D40002168C860202084F841002046FEF720FE4C +:103D5000002010BDF8B5044694F84200222875D121 +:103D6000A068B0F5805F0CD1206950B90025A66A23 +:103D700020684068C0F308003080A06A801CA06200 +:103D800015E0A56A0026A068B0F5805F03D0A068A2 +:103D900028B9206918B920684068287004E02068B4 +:103DA000406800F07F002870A06A401CA062E08D8F +:103DB000401E80B2E085002846D12068C06820F00F +:103DC00020002168C8602068C06820F480702168E5 +:103DD000C8602068406920F0010021684861202007 +:103DE00084F8420000206063206B012826D1002067 +:103DF000206300BF00BF21680C3151E8001F21F093 +:103E0000100021680C3141E80002002AF3D100BF04 +:103E10002068006800F0100010280AD100BF0020C0 +:103E2000009020680068009020684068009000BF03 +:103E300000BFA18D2046FEF767FA02E02046FEF79C +:103E4000F1FC0020F8BD01E00020FBE70220F9E7CB +:103E500070B504462168096921F44051E2681143B4 +:103E6000226811612269A1681143626941EA020571 +:103E70002168C96841F20C62914329432268D160EC +:103E80002168496921F44071A26911432268516196 +:103E90002D4A2168914202D1FDF7FEFE01E0FDF7B7 +:103EA000EBFE00EBC00101EB001162689200B1FB78 +:103EB000F2F100EBC00202EB001263689B00B2FB60 +:103EC000F3F26423B2FBF3F202EBC20303EB021240 +:103ED000A1EB8201322202EB01116422B1FBF2F16B +:103EE00001F0F00100EBC00202EB001263689B00DE +:103EF000B2FBF3F26423B2FBF3F201EB021200EB2C +:103F0000C00101EB001163689B00B1FBF3F100EB12 +:103F1000C00303EB00136668B600B3FBF6F3642638 +:103F2000B3FBF6F303EBC30606EB0313A1EB83012C +:103F3000322303EB01116423B1FBF3F101F00F0114 +:103F400011442268916070BD0038014010B50346ED +:103F500099629A85DA8500205864222083F842000D +:103F6000186928B11868C06840F480701C68E06067 +:103F70001868406940F001001C6860611868C068FA +:103F800040F020001C68E060002010BD014691F860 +:103F90004100212828D18868B0F5805F0BD10869DD +:103FA00048B90A6A1088C0F308000B685860086AAC +:103FB000801C086205E00B6A581C086218780B68C0 +:103FC0005860C88C401E80B2C88458B90868C06860 +:103FD00020F080000B68D8600868C06840F040009E +:103FE0000B68D860002070470220FCE72DE9F04103 +:103FF00004460D4617469846069E34E0701C88B36A +:104000002EB1FDF795FCA0EB0800B0422BD900BF04 +:1040100000BF21680C3151E8001F21F4D0702168E5 +:104020000C3141E80002002AF3D100BF00BF00BFFD +:104030002168143151E8001F21F00100216814317A +:1040400041E80002002AF3D100BF202084F841009B +:1040500084F8420000BF002084F8400000BF032025 +:10406000BDE8F081FFE7206800682840A84201D140 +:10407000012000E00020B842C0D00020F0E700009E +:1040800010B50248FEF742F910BD00005C010020A7 +:1040900010B50248FEF73AF910BD0000A401002057 +:1040A00010B50248FEF732F910BD0000EC01002007 +:1040B00000BFFEE70FB4054B10B503A9044A0298F0 +:1040C00000F02EF910BC5DF814FB0000FD4B000859 +:1040D000B80000200FB47CB50C0009AD01D0611E02 +:1040E00000E00021CDE90001064B6A462946089808 +:1040F00000F016F9002C02D0009A002111707CBC4F +:104100005DF814FB274A00087CB50C001D461646D6 +:10411000014601D0601E00E00020CDE90010064BF2 +:104120006A462946304600F0FBF8002C02D0009A7F +:10413000002111707CBD0000274A00080248006879 +:10414000C0F30220704700000CED00E010B500281D +:1041500004DB0A07130E054A135406E00A07140E7F +:10416000034A00F00F031B1FD45410BD00E400E00D +:1041700018ED00E000487047BC00002002E008C8CD +:10418000121F08C1002AFAD170477047002001E0D1 +:1041900001C1121F002AFBD1704700002DE9FF5F0B +:1041A00082B00021DDE90430020DDDF840B00343A8 +:1041B00018D044F61050A2F2FF3242431514119861 +:1041C00001281FD0A5EB0B00401C5FEA000A4FF04E +:1041D00000064E4FDFF83891B046504615D5CAF16B +:1041E000000413E0119801244AA3012801D16FEAC9 +:1041F0000B010298119AC0E90031C0E9024206B0F1 +:10420000BDE8F09FCBF10000DFE704460021404A03 +:10421000491842EB0450CDE9001012E0E00707D046 +:1042200032463B4640464946FCF71BFA80468946E3 +:1042300032463B4610461946FCF713FA06460F462F +:104240006410002CEAD1DDE90401DDE90023BAF1B4 +:10425000000F06DAFCF705FA42464B46FCF701FA76 +:1042600005E0FCF770FA42464B46FCF76CFA044650 +:104270000E460022284BFCF7EDFA03D84FF0FF3032 +:10428000014607E00022254B20463146FCF742F963 +:10429000FCF7C8FA102409E0002C0ADB0A220023EC +:1042A000FCF78DF8039B30321A55641E50EA010268 +:1042B000F2D1641C039AC4F111031444119A012A27 +:1042C00003D0012208430DD10AE0084304D00020A6 +:1042D0004FF0110B119072E7A3EB0B056D1E0DE073 +:1042E0005B4504DD4FF0000205F1010504E003DA4F +:1042F0004FF00002A5F10105002AECD002981199B7 +:10430000C0E90231C0E9004579E70000000014402F +:104310000000F03F300000000000F0430000E03FEC +:104320002DE9FF4F95B09A46884606460025EEE1F6 +:10433000252877D100242746F94A0121039400E07B +:10434000044316F8013F203B01FA03F01042F7D175 +:1043500030782A2811D06FF02F033078A0F1300286 +:10436000092A16D8039A44F0020402EB820203EBF6 +:1043700042021044761C0390EFE758F8042B039296 +:10438000002A03DA504244F40054039044F002043B +:10439000761C30782E2816D116F8010F44F004044C +:1043A0002A280DD06FF02F023078A0F13003092BAE +:1043B00009D807EB870302EB4303C718761CF3E722 +:1043C00058F8047B761C30786C280FD006DC4C281B +:1043D00017D068280DD06A2814D104E0742810D0B2 +:1043E0007A280FD10DE044F400140AE044F480145C +:1043F00001E044F440147278824202D104F5801442 +:10440000761C761C307866280BD013DC582877D0C1 +:1044100009DC002875D04528F6D04628F4D0472876 +:104420001AD193E118E0632835D0642879D0652843 +:1044300012D18BE1702873D008DC6728F1D069288D +:104440006FD06E280DD06F2806D1ACE073282CD029 +:10445000752874D0782853D05246179990476D1C10 +:1044600054E1C4F30250022809D003280DD0D8F833 +:10447000001004280DD00D6008F1040846E1D8F8BA +:104480000010EA17C1E90052F6E7D8F800100D80D5 +:10449000F2E70D70F0E718F8041B8DF8001000200B +:1044A0008DF80100EB46012003E058F804BB4FF003 +:1044B000FF3061074FF0000102D40DE009F1010166 +:1044C0008946B9420FDA8145F8DB1BF8091000294B +:1044D000F4D108E009F1010189468142FADB1BF8B9 +:1044E00009100029F6D103985346A0EB090721468D +:1044F0003846179A00F080FA284400EB090507E0D7 +:1045000044E008E10DE01BF8010B52461799904773 +:10451000B9F10109F7D2534621463846179AF2E01D +:1045200039E00A21C4F302524FF0000B0091022A35 +:1045300006D058F8040BC117032A09D00AE023E07B +:1045400008F1070020F00702F2E80201904605E0BA +:1045500000B2C117042A01D140B2C117002906DAFE +:104560000A460021404261EB02012D2202E02205B1 +:1045700004D52B228DF80420012203E0E20701D0AC +:104580002022F7E7914657E00A2100E010214FF082 +:10459000000B00910BE010214FF0000B44F00404DD +:1045A0000827009103E008204FF0000B0090C4F3AF +:1045B0000252022A05D058F8040B0021032A08D021 +:1045C00008E008F1070020F00702F2E80201904637 +:1045D00003E080B2042A00D1C0B24FF000092207E4 +:1045E0002AD53278702A07D0DDF800C08CF0100C84 +:1045F0005CEA0B0C05D00EE040228DF8042001226D +:1046000008E050EA010306D030238DF804308DF81D +:10461000052002229146009B83F0080353EA0B0316 +:104620000AD150EA010201D1620705D530228DF886 +:1046300004204FF001097F1E3278582A04D039A295 +:104640000C920CAA02920BE03BA2F9E75B46009A9F +:10465000FBF7B5FE0C9B9B5C029A521E02921370F4 +:1046600050EA0102F2D1029804A9081A00F1200BC5 +:10467000600702D524F4803400E001275F4502DDA5 +:10468000A7EB0B0000E0002000EB0B01009003986B +:104690004944401A0390E00306D453462146179A32 +:1046A000039800F0A9F90544002706E001A8524646 +:1046B000C05D179990476D1C7F1C4F45F6DBE003EA +:1046C0000CD553462146179A039800F095F90544F6 +:1046D00004E030205246179990476D1C0099481EFF +:1046E00000900029F5DC08E0029802995246007813 +:1046F000491C0291179990476D1CBBF10001ABF169 +:10470000010BF1DC5BE100F065F90544761C3078C3 +:1047100000287FF40DAE19B02846BDE8F08F0000E8 +:104720000928010030313233343536373839616287 +:10473000636465660000000030313233343536374B +:10474000383941424344454600000000600700D428 +:10475000062708F1070020F00700F0E80223804652 +:1047600003F0004C5FEA0C0001D097A009E020059F +:1047700001D596A005E0E00701D095A001E0AFF2D9 +:104780004C001390307823F0004365280CD006DCF1 +:10479000452809D046281DD047287FD13BE0662810 +:1047A00018D067287AD136E00021112F01DB1120C3 +:1047B00000E0781CCDE9000104A90CA8FFF7EEFC8D +:1047C000DDE90D010C9A4FF0000B07F10109109281 +:1047D00000914EE04FF000400097CDE9011004A990 +:1047E0000CA8FFF7DBFCDDE90D020C9B0F994FF0E5 +:1047F000000B91461093009211B9791C00EB01094E +:10480000B7EB090003D4C0F1FF3B07F10109A9EBA5 +:104810000700019042E0012F00DA01270021112F4B +:1048200001DD112000E03846CDE9000104A90CA803 +:10483000FFF7B4FCDDE90D010C9A00914FF0000B7D +:10484000B946109221070FD4009A4A4503DA9146DF +:1048500001E0A9F10109B9F1010F05DD109AA9F1F3 +:104860000101515C3029F4D0B84202DA10F1040F92 +:1048700003DA0121CDE9011010E0002803DC8344B4 +:10488000A9EB000102E0411C494500DD8946A0EB8F +:104890000B00401C01904FF000400290200705D40F +:1048A0000198484502DB4FF0FF30019000208DF861 +:1048B0004B0002980DF14B07B0F1004F25D00220BC +:1048C0000C902B200D90029800280CDA40420290A8 +:1048D0002D200D9007E00A210298FBF75AFD303198 +:1048E000029007F8011D0C99481E0C900029F2DC7B +:1048F00002980028EFD1791E0D980870307800F0EA +:10490000200040F0450007F8020D11A8C01BC01D93 +:1049100002901398007800B1012000EB0901019882 +:1049200001EBE071029801440398401A401E039085 +:10493000E00306D453462146179A039800F05CF82A +:1049400005441398007818B15246179990476D1C8A +:10495000E00323D553462146179A039800F04CF8FC +:1049600005441BE0BBF1000F07DB0098584504DD50 +:104970001098179910F80B0001E017993020524653 +:10498000904701980BF1010B401E05F101050190C4 +:1049900004D12E205246179990476D1CB9F10001A1 +:1049A000A9F10109DEDC05E017F8010B5246179961 +:1049B00090476D1C0299481E02900029F4DC534672 +:1049C0002146179A03989EE62D0000002B00000058 +:1049D000200000002DE9F041044600251E46174640 +:1049E000880404D405E039462020B0476D1C641EBD +:1049F000F9D52846BDE8F0812DE9F04104460025AF +:104A00001E469046C80301D5302700E020278804C1 +:104A100004D505E041463846B0476D1C641EF9D503 +:104A20002846BDE8F0814A68002A06D00A68531C6F +:104A30000B6010704868401E4860704770B50446AF +:104A40000D460C4830F8140080280CDA094830F87C +:104A5000141030F81400401C064A22F814000648CE +:104A600000EBC4104554FCF763FF044941F82400EF +:104A700070BD000072000020D0030020500500200F +:104A800010B502460023002003E0145C6340441C80 +:104A9000E0B28842F9DB184610BD10B5024600238B +:104AA000002003E0145C6340441CE0B28842F9DB60 +:104AB000184610BDF8B505460C461448006878B194 +:104AC0002046FBF772FB86B23246214628460F4B42 +:104AD0001B6898470E480068401C0D49086008E0B4 +:104AE00021462846FEF72EFA09480068401C08496E +:104AF00008602846FEF748F90646334605A208A195 +:104B000001200094FCF782FCF8BD00006400002046 +:104B10006C00002054585B25735D3A20257300001B +:104B2000524F5554455200007CB50446274830F892 +:104B3000140000B97CBD2046FEF726F9054629463B +:104B400023A0FEF76DFD002531E0264800EBC410E0 +:104B5000405D01909DF80400202808DB9DF80400CA +:104B60007F2804DA012101A8FEF77AFD1DE09DF8F7 +:104B700004000D2804D102211BA0FEF771FD14E0F2 +:104B80009DF804000A2804D1022118A0FEF768FD50 +:104B90000BE09DF8043016A204216846FFF79AFA4C +:104BA00004216846FEF75CFD00BF681C85B207481B +:104BB00030F81400A842C8DC0FA0FEF7ABFD0020BF +:104BC000024921F8140000BFB4E700007200002081 +:104BD0005B524F555445525D2025732052583A2060 +:104BE00022000000D00300205C7200005C6E000018 +:104BF0005C78253032580000220D0A0013B50C46AF +:104C000001216846FEF72CFD00981CBD10B500225E +:104C100008210248FCF786FE10BD0000000C014090 +:104C200010B5012208210248FCF77CFE10BD0000EF +:104C3000000C014010B500224FF400710148FCF750 +:104C400071FE10BD000C014010B501225102024856 +:104C5000FCF768FE10BD0000000C01400146302941 +:104C600005DB392903DCA1F13000C0B270474129CE +:104C700005DB462903DCA1F13700C0B2F6E7612964 +:104C800005DB662903DCA1F15700C0B2EEE7002086 +:104C9000ECE770B505460C462046FFF7DFFF0646F9 +:104CA0002846FFF7DBFF46EA0010C0B270BD0000E7 +:104CB0000B48007800B17047002009E0002100EBAC +:104CC0000012084B995400EB00121A441174401C56 +:104CD0001028F3DB01200249087000BFEBE7000059 +:104CE000790000205C05002070B505460DB12878DC +:104CF00008B9012070BDFFF7DBFF002414E004EBCE +:104D000004100B49085C70B104EB0411084A8818C0 +:104D10000F222946FBF75EFA28B904EB0410044978 +:104D20000844007CE6E7641C102CE8DB0120E1E786 +:104D30005C050020014609B1087808B901207047D8 +:104D40000020FCE710B504462046FFF7F3FF08B14A +:104D5000002010BD09E0FBF7F7F900682178405CFE +:104D6000202801D00020F4E7641C20780028F2D12C +:104D70000120EEE710B50446FBF7E6F90068005D98 +:104D800000F0100028B9FBF7DFF90068005D20286B +:104D900001D1012010BD0020FCE710B50446FBF74F +:104DA000D3F90068005D00F03E0038B12A2C05D030 +:104DB0000D2C03D00A2C01D0012010BD0020FCE7EF +:104DC000FCF7C8FDFEF7CFFBFDF7A8FEFDF750FF8F +:104DD000FDF72CFFFDF768FFFDF782FFFEF7F8FBFC +:104DE000FDF718FEFCF778F9FEF728FBFEF704F84C +:104DF000FCF7A6F9FCF7EAFA012220492048FDF762 +:104E0000FBFC01221F492048FDF7F6FC002000F0C2 +:104E1000A9FB01221D491E48FDF7EEFC002000F011 +:104E200005FD4FF47A710A2000F026FD002000F005 +:104E3000C9FB00F017FC17A0FFF73CF921A0FFF712 +:104E400039F9294800682949B0FBF1F4214628A026 +:104E5000FFF730F92CA0FFF72DF90DE0FEF768FC05 +:104E6000FDF718FEFCF75AF9FEF77CF8FCF7D8F9C5 +:104E700000F018FD00F006FCF0E700000400002040 +:104E8000A401002005000020EC010020AC0000205F +:104E90005C0100200D0A3D3D3D3D3D3D3D3D3D3D1C +:104EA0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D32 +:104EB0003D3D3D3D3D3D3D3D3D3D3D3D3D3D0D0A85 +:104EC000000000004533322D3433335442482D5313 +:104ED00043204170706C69636174696F6E20537414 +:104EE00061727465640D0A008800002040420F0062 +:104EF00053797374656D20436C6F636B3A2025643E +:104F0000204D487A0D0A00003D3D3D3D3D3D3D3D73 +:104F10003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DC1 +:104F20003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DB1 +:104F30000D0A000070B58CB0044694F84C0008B11E +:104F400060A200E061A294F8490094F8481004F1CE +:104F50002803CDE90102009104F1080221465CA07A +:104F6000FEF75EFB65A12046FBF726F9002835D148 +:104F700004F10800FFF7E6FE38B961A000F0B2FDC9 +:104F800061A0FEF74DFB0CB070BD04F10800FBF70B +:104F9000F3F905460DB1012D18D10DB1012100E045 +:104FA00000210846FEF770FA2B4661A2202104A8D2 +:104FB000FFF790F804A800F0CBFD0DB15EA000E073 +:104FC0005EA001465EA0FEF72BFB06E04CA000F0C1 +:104FD00089FD29465FA0FEF723FB71E066A120460C +:104FE000FBF7EAF8002858D104F10800FFF7A2FE09 +:104FF00028B962A104F10800FBF7DEF8D0B9FDF78B +:10500000E9FC0546C5F3C000C5F38001C5F34002C5 +:1050100005F00103CDE90021029059A2202104A846 +:10502000FFF758F804A800F093FD294657A0FEF7B3 +:10503000F7FA45E004F10800FFF784FE002825D0C8 +:1050400004F10800FBF798F90546012D16DB042D45 +:1050500014DC691EC8B2FDF7D1FC06462B4653A2EC +:10506000202104A80096FFF735F804A800F070FD91 +:105070003246294650A0FEF7D3FA06E020A000F001 +:1050800031FD294651A0FEF7CBFA19E01CA000F033 +:1050900029FD56A0FEF7C4FA12E05EA12046FBF7F8 +:1050A0008BF830B95BA000F053FD5CA0FEF7B8FAB6 +:1050B00006E061A000F016FD214660A0FEF7B0FA00 +:1050C00000BF60E728736B697029000000000000D2 +:1050D0005B434D445D20434D443D25732050313D9D +:1050E00025732050323D25732043533D25303258DF +:1050F0002F253032582025730D0A0000524C000035 +:10510000504152414D0000005B434D445D20496ECB +:1051100076616C696420524C20706172616D3A2036 +:105120006E6F74206E756D657269630D0A00000004 +:10513000524C2C25640000004F4E00004F464600A4 +:105140005B434D445D2052656C6179202D3E2025E6 +:10515000730D0A005B434D445D20496E76616C69B6 +:105160006420524C20706172616D3A2073746174D6 +:10517000653D25640D0A0000444900003000000030 +:1051800044492C2564256425642564005B434D4413 +:105190005D20444920616C6C207374617465733ABE +:1051A000203078253032580D0A00000044492C2563 +:1051B000642C2564000000005B434D445D2044499D +:1051C0002564203D2025640D0A0000005B434D440A +:1051D0005D20496E76616C69642044492063686192 +:1051E0006E6E656C3A2025640D0A00005B434D44E9 +:1051F0005D20496E76616C6964204449207061725B +:10520000616D3A206E6F74206E756D657269630D05 +:105210000A0000004543484F000000005B434D4436 +:105220005D204543484F20726573706F6E73652033 +:1052300073656E740D0A0000434D44005B434D449A +:105240005D20556E6B6E6F776E20636F6D6D616E56 +:10525000643A2025730D0A0010B500200649087035 +:1052600081F84E0081F84F0081F852004D2102482C +:10527000401CFAF78FFF10BD3402002000200349C4 +:10528000086003490860034908607047A0000020D7 +:10529000A4000020A8000020014611B96FF0020010 +:1052A00070470248006808800020F9E7A800002045 +:1052B00030B503460C460BB104B112B96FF00200D1 +:1052C00030BD1448006818B900201080401EF7E770 +:1052D00000201080002115E00F48104D2D68405D22 +:1052E00058540E480068401CC0F309000B4D28605C +:1052F00008480068401E074D28601088401C108038 +:10530000481C81B2A14203DA024800680028E3D1B8 +:105310000020D5E7A800002034120020A4000020BF +:1053200030B502460B4602B113B96FF0020030BD32 +:1053300000211AE00F480068B0F5806F02D34FF0EB +:10534000FF30F4E7505C0C4C0C4D2D6860550B4859 +:105350000068401CC0F30900084C20600548006844 +:10536000401C044C2060481C81B29942E2DB0020C2 +:10537000DDE70000A800002034120020A00000207B +:105380000748006850B106480068401E044908609C +:105390000846006810B901200249087070470000F3 +:1053A000B0000020B400002010B502210D48FCF729 +:1053B000B1FAA0B9FCF7BCFA044607E0FCF7B8FA6A +:1053C000001B642802D36FF0010010BD02210548C4 +:1053D000FCF7A0FA0028F1D00220FCF7F7F8002033 +:1053E000F3E70000000C01400548007810B94FF0C9 +:1053F000FF30704700200249087000BFF9E7000045 +:105400009C00002010B5FFF739FF10BD10B5044611 +:105410002046FFF741FF10BD70B504460D46164605 +:10542000324629462046FFF743FF70BD0848007802 +:1054300010B14FF0FF307047002006490860064960 +:105440000860064908600120014908700020F2E761 +:105450009C000020A0000020A4000020A800002044 +:1054600070B50546FFF7A0FF04460CB1204670BD9D +:1054700035B1012D0FD0022D18D0032D2CD120E0F5 +:10548000002280211C48FCF74DFA002201211B4814 +:10549000FCF748FA23E0012280211748FCF742FA82 +:1054A000002201211548FCF73DFA18E00022802176 +:1054B0001148FCF737FA012211461048FCF732FA7E +:1054C0000DE0012280210C48FCF72CFA0122114644 +:1054D0000A48FCF727FA02E06FF00200C7E700BFB6 +:1054E0000520FCF773F8FFF75FFF04460CB1204678 +:1054F000BDE70020BBE7000000080140000C0140B0 +:1055000008B5094800684068C0B2009001216846AB +:10551000FFF706FF0A2005490860012204490248F6 +:10552000FDF76AF908BD00005C010020B000002012 +:10553000AC00002070B504460D4604B115B96FF0FB +:10554000020070BD4FF6FF732A4621460448FDF75E +:10555000A9F9064616B16FF00100F2E70020F0E766 +:105560005C01002070B505461348007810B14FF07B +:10557000FF3070BDFFF75AFF044614B14FF0FF3003 +:10558000F7E735B90D480E490A68026009790171DB +:1055900004E00A482968016029790171074800F090 +:1055A000F1F804461CB1FFF71FFF2046E1E7012098 +:1055B000014908700020DCE78C0000208D000020ED +:1055C000B65D000870B5054615B94FF0FF3070BDE7 +:1055D00028210F48FAF7DEFD00200D49087081F8F8 +:1055E0002500084629680162297980F824102030B6 +:1055F00000F0C8F804460CB12046E8E7002000F0AF +:10560000EDF804460CB12046E1E70020DFE700009A +:10561000C00000202DE9F04104460D4616461F4605 +:1056200014B10DB106B11FB94FF0FF30BDE8F081E4 +:105630000A2D02DA4FF0FF30F8E72078542802D123 +:105640006078582802D04FF0FF30EFE73B463246F3 +:1056500002A1E01CFAF7CEFD0020E7E725642E2525 +:10566000642E000010B500F05DF804460CB1204631 +:1056700010BD01200249087081F825000020F7E7DD +:10568000C000002010B594B0254890F8250008B956 +:1056900014B010BD2248007820B1012806D002289D +:1056A00036D134E001201E49087035E00020039017 +:1056B00003A904A800F02AFB40B300200290019047 +:1056C000039881B201AB02AA04A8FFF7A3FF044626 +:1056D000DCB913484068401C114948600298886151 +:1056E000019848610846C0690199884202D20C4974 +:1056F0000198C86100F074F9012000F03DF93220F2 +:10570000FBF764FF002000F037F900BF04E003E07E +:1057100002200349087000BF00BF00BFB8E70000C7 +:10572000C000002010B50C48007810B96FF00500DB +:1057300010BD0A48007810B16FF00100F8E7FFF7DC +:1057400061FE044614B14FF0FF30F1E70120034938 +:1057500008700020ECE700008C0000209200002080 +:1057600010B50446C0200649087008462168C0F8F4 +:105770000110217941710621FFF7DCFE10BD000008 +:10578000340E002070B5054615B96FF0030070BDEA +:10579000FFF70AFE044614B16FF00200F7E703209A +:1057A000FFF75EFE044614B16FF00200EFE72846F3 +:1057B000FFF7D6FF6420FBF709FF0020FFF750FE3C +:1057C000044614B16FF00200E1E703482968016064 +:1057D000297901710020DAE78D00002070B50446B8 +:1057E0002046FFF73DFE054615B16FF0020070BD83 +:1057F0000020FCE770B505460E4605B116B96FF0FE +:10580000030070BD0848007810B96FF00500F8E794 +:1058100031462846FFF78EFE044614B16FF00200B1 +:10582000EFE70020EDE700008C00002070B5054692 +:1058300015B94FF0FF3070BD1C210E48FAF7AAFCD5 +:1058400000200C490870487608462968416129798A +:1058500001761430FFF796FF04460CB12046EAE7C4 +:105860000020FFF7BBFF04460CB12046E3E7002011 +:10587000E1E70000E8000020024602B111B94FF054 +:10588000FF307047064882600020054B586018467C +:10589000C160002018611870012058760020F0E7E0 +:1058A000E800002070B588B03248407E08B908B0E2 +:1058B00070BDFCF73DF804462E48007830B1012851 +:1058C00008D0022842D003284CD14AE001202949BF +:1058D00008704BE02748406826498968884206D30B +:1058E000032024490870002000F0CCF93EE0214854 +:1058F0000069201A1F49C968884226D31D4840689C +:10590000431C1C4820218268684600F063F9054664 +:10591000002D16DD29466846FFF76CFF06467EB966 +:1059200014484068401C134948600846046101203F +:1059300000F0A8F93220FBF749FE002000F0A2F9A0 +:1059400000BF02200B49087000BF0FE00948006942 +:10595000201A0849C968884202D301200549087005 +:1059600004E003E003200349087000BF00BF00BF4C +:105970009DE70000E800002010B5044614B1FFF7D1 +:105980004FF901E0FFF742F910BD002120F8801F18 +:1059900041808180C1808038704710B50246012364 +:1059A00072B6B2F88400802806DBB2F88600401C8C +:1059B000A2F88600002310E0B2F88000115432F8FB +:1059C000804F601CC41700EB5464E411A0EBC414B6 +:1059D00014809088401C9080803A62B6184610BDB2 +:1059E0000D48C069B8B10C48C0690B494968411AF3 +:1059F0000948C160C06958B10748C068642148437C +:105A00000549C969B0FBF1F0C1B20348017402E075 +:105A10000021014801747047C0000020F0B589B032 +:105A200004460D46631C19A2202101A80095FEF72B +:105A300051FB0646701EC1B20DF10500FFF72DF8AF +:105A40000746C6F1200101AA90193B4614A2FEF7B1 +:105A500041FB0DB114A000E015A00246611C15A089 +:105A6000FDF7DEFD01A90020FDF76CFA01A916A0E3 +:105A7000FDF7D6FD1A48006828B101AA294620463C +:105A8000174B1B68984709B0F0BD00002444495FDC +:105A90004556454E542C25642C25642A00000000F0 +:105AA000253032580D0A00004849474800000000E0 +:105AB0004C4F57005B494F5D2043482564202D3EE5 +:105AC0002025730D0A0000005B494F5D20524634CB +:105AD00033332054583A20222573220D0A00000047 +:105AE0005800002070B588B005462B4611A2202131 +:105AF0006846FEF7EFFA0446601EC1B20DF10100E0 +:105B0000FEF7BEFF0646C4F120010DEB040033464C +:105B10000BA2FEF7DFFA0C48006830B169460B486B +:105B20000078094A1268904702E06846FDF7F2FDE6 +:105B300008B070BD244552522C25732A0000000085 +:105B4000253032580D0A0000080000200C0000200B +:105B500070B590B005462B4611A240216846FEF76D +:105B6000B9FA0446601EC1B20DF10100FEF788FFCC +:105B70000646C4F140010DEB040033460AA2FEF7CD +:105B8000A9FA0B48006830B169460A480078084A0B +:105B90001268904702E06846FDF7BCFD10B070BD8A +:105BA000244F4B2C25732A00253032580D0A000053 +:105BB000080000200C00002010B500F0CFF80448C9 +:105BC000006820B102480068401E0149086010BD0D +:105BD000000000202DE9F84305460E46174698467A +:105BE0000DB1102E02DA0020BDE8F8833B4607A273 +:105BF00031462846CDF80080FEF76CFA0446002CAA +:105C000001DDA0B2F0E70020EEE7000054582E2599 +:105C100030336C752E2530336C752E00F8B5054683 +:105C20006B206843164901EB800606F190040027BB +:105C300072B694F80601D0B9B4F80401002816DD54 +:105C4000B4F80201205C009004F581742188481C9E +:105C5000C11700EB11610912A0EB012121806088BE +:105C6000401E608001202071A4F58174012762B676 +:105C700027B1012269463068FCF76DFEF8BD0000CF +:105C80006C06002010B5044614B1FEF7DDFF01E0FC +:105C9000FEF7D0FF10BD002100F58070018041802B +:105CA000818081710181A0F58070704770B50346D5 +:105CB0000C46002572B6002021E0B3F80411FF293C +:105CC00005DDB3F80811491CA3F8081119E0215C9F +:105CD000B3F800619955B3F80061711CCE1701EB60 +:105CE00016663612A1EB0626A3F80061B3F804117C +:105CF000491CA3F80411691C8DB2411C88B2904262 +:105D0000DBDB00BF62B6284670BD0000F8B5064672 +:105D10000D4606B10DB90020F8BD0F48007808B94E +:105D20000020F9E76846FFF771FB04460CB100203C +:105D3000F2E7BDF8000008B90020EDE72A46FF2190 +:105D40003046FFF769FB04460CB10020E4E7002071 +:105D5000014908700120DFE7B400002000B5FFF71B +:105D60000FFB00BD6C5E0008645E00085C5E00080E +:105D7000745E00085C010020A4010020EC010020FA +:105D80007C5E0008845E00088C5E00080203040547 +:105D9000060708090A0B0C0D0E0F10100102000077 +:105DA00000000000000001020304060708090000CB +:105DB00000000102030400001A1704C1C1C14154CC +:105DC0002B444556545950453D3F0041542B4657AE +:105DD000434F44453D3F000040404040404040402C +:105DE00040414141414140404040404040404040AE +:105DF0004040404040404040050202020202020290 +:105E00000202020202020202202020202020202082 +:105E100020200202020202020290909090909010C4 +:105E20001010101010101010101010101010101072 +:105E300010101002020202020288888888888808EE +:105E400008080808080808080808080808080808D2 +:105E50000808080202020240D85D00085741524E6D +:105E600020000000494E464F2000000044454255A6 +:105E7000470000004552524F520000005541525415 +:105E80003100000055415254320000005541525437 +:105E900033000000B45E000800000020C0000000D5 +:105EA0007C410008745F0008C000002078190000E1 +:105EB0008C4100080000000000000000000000000D +:105EC00000000000000C0140100000000000000075 +:105ED00000000000000C0140200000000000000055 +:105EE00000000000000C0140400000000000000025 +:105EF00000000000000C01408000000000000000D5 +:105F00000000000000000000010000000000000090 +:105F10000000000000000000000000000000000081 +:105F20000000000001000000000000000000000070 +:105F30000000000010000000010000000024F40038 +:105F40000000000000000000000000000000000051 +:105F50000000000000000000000000000000000041 +:105F60000000000000000000000000000000000031 +:045F7000000000002D :04000005080000ED02 :00000001FF diff --git a/MDK-ARM/project/project.htm b/MDK-ARM/project/project.htm index 1d34c2d..3bd5a0e 100644 --- a/MDK-ARM/project/project.htm +++ b/MDK-ARM/project/project.htm @@ -3,11 +3,11 @@ Static Call Graph - [project\project.axf]

Static Call Graph for image project\project.axf


-

#<CALLGRAPH># ARM Linker, 5060960: Last Updated: Fri Mar 27 16:25:16 2026 +

#<CALLGRAPH># ARM Linker, 5060960: Last Updated: Fri Mar 27 19:53:00 2026

-

Maximum Stack Usage = 360 bytes + Unknown(Cycles, Untraceable Function Pointers)

+

Maximum Stack Usage = 488 bytes + Unknown(Cycles, Untraceable Function Pointers)

Call chain for Maximum Stack Depth:

-cmd_parser_response_callback ⇒ DebugLog_Output ⇒ __2snprintf +main ⇒ CmdRouter_Task ⇒ DebugLog_Output ⇒ __2snprintf

Mutually Recursive functions @@ -90,7 +90,7 @@ Global Symbols

__main (Thumb, 0 bytes, Stack size unknown bytes, entry.o(.ARM.Collect$$$$00000000))
[Address Reference Count : 1]

  • startup_stm32f103xb.o(.text)
-

_main_stk (Thumb, 0 bytes, Stack size unknown bytes, entry2.o(.ARM.Collect$$$$00000001)) +

_main_stk (Thumb, 0 bytes, Stack size unknown bytes, entry2.o(.ARM.Collect$$$$00000001))

_main_scatterload (Thumb, 0 bytes, Stack size unknown bytes, entry5.o(.ARM.Collect$$$$00000004))

[Calls]