From b405b826398715d5d2c3bd82a2d1ba9789f667cb Mon Sep 17 00:00:00 2001 From: dianjixz <18637716021@163.com> Date: Mon, 10 Mar 2025 10:54:30 +0800 Subject: [PATCH] [update] README camera --- .vscode/launch.json | 26 + README_zh.md | 159 +- doc/assets/StackFlow_unit.dot | 36 + doc/assets/network.png | Bin 0 -> 118173 bytes doc/projects_llm_framework_doc/llm_sys_en.md | 69 + doc/projects_llm_framework_doc/llm_sys_zh.md | 69 + ext_components/ax_msp/Kconfig | 24 +- ext_components/ax_msp/SConstruct | 13 +- projects/llm_framework/config_defaults.mk | 1 + projects/llm_framework/main_camera/SConstruct | 10 + .../main_camera/src/axera_camera.c | 1373 +++++++++++++++++ .../main_camera/src/axera_camera.h | 35 + .../llm_framework/main_camera/src/camera.h | 4 +- .../llm_framework/main_camera/src/main.cpp | 21 +- .../src/{camera.c => v4l2_camera.c} | 0 15 files changed, 1748 insertions(+), 92 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 doc/assets/StackFlow_unit.dot create mode 100644 doc/assets/network.png create mode 100644 projects/llm_framework/main_camera/src/axera_camera.c create mode 100644 projects/llm_framework/main_camera/src/axera_camera.h rename projects/llm_framework/main_camera/src/{camera.c => v4l2_camera.c} (100%) diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e1b8c1b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + "name": "gdb 启动", + "type": "cppdbg", + "request": "launch", + "program": "/home/nihao/w2T/axera/StackFlow/projects/test_kit_demo3/dist/test_kit_demo3", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "miDebuggerPath": "/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb", + "miDebuggerServerAddress": "localhost:1234", + "environment": [], + "externalConsole": true, + "MIMode": "gdb", + "setupCommands":[{ + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }] + + ] +} \ No newline at end of file diff --git a/README_zh.md b/README_zh.md index c7cd7ef..2b62fa2 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,100 +1,93 @@ -# Module-LLM +# StackFlow -
+

basic

-## 描述 -**Module LLM**是一款集成化的离线大语言模型 (LLM) 推理模块,专为需要高效,智能交互的终端设备设计,无论是在智能家居,语音助手,还是在工业控制中,Module LLM 都能为您带来流畅,自然的 AI 体验,无需依赖云端,确保隐私安全与稳定性。集成 **StackFlow** 框架,配合 **Arduino/UiFlow** 库,几行代码就可轻松实现端侧智能。
-搭载爱芯 **AX630C** SoC 先进处理器,集成 3.2 TOPs 高能效 NPU,原生支持 Transformer 模型,轻松应对复杂 AI 任务。配备 **4GB LPDDR4** 内存(其中1GB供用户使用,3GB专用于硬件加速)和**32GB eMMC**存储,支持多模型并行加载与串联推理,确保多任务处理流畅无阻。运行功耗仅约 1.5W,远低于同类产品,节能高效,适合长时间运行。
-集成麦克风,扬声器,TF存储卡,**USB OTG** 及 RGB状态灯,满足多样化应用需求,轻松实现语音交互与数据传输。灵活扩展:板载 SD 卡槽支持固件冷/热升级,**UART** 通信接口简化连接与调试,确保模块功能持续优化与扩展。USB 口支持主从自动切换,既可以做调试口,也可以外接更多 USB 设备如摄像头。搭配 LLM 调试套件,用于扩展百兆以太网口,及内核串口,作为 SBC 使用。
-多模型兼容,出厂预装 **Qwen2.5-0.5B** 大语言模型,内置**KWS**(唤醒词),**ASR**(语音识别),**LLM**(大语言模型)及**TTS**(文本转语音)功能,且支持分开调用或 **pipeline** 自动流转,方便开发。后续将支持Qwen2.5-1.5B、Llama3.2-1B及InternVL2-1B等多种端侧LLM/VLM模型,支持热更新模型,紧跟社区潮流,适应不同复杂度的AI任务;视觉识别能力:支持CLIP、YoloWorld等Open world模型,未来将持续更新DepthAnything、SegmentAnything等先进模型,赋能智能识别与分析;
-即插即用,搭配**M5主机**,Module LLM 实现即插即用的AI交互体验。用户无需繁琐设置,即可将其集成到现有智能设备中,快速启用智能化功能,提升设备智能水平。该产品适用于离线语音助手,文本语音转换,智能家居控制,互动机器人等领域。 +

+ StackFlow 是一个简单、疾速、优雅的面向嵌入式开发者一站式 AI 服务基础设施项目,目的是让 Maker 和 Haker 们能够快速的在当前的嵌入式设备中获取到强大的 AI 加速能力。StackFlow 能够为各类人机交互设备注入智慧的灵魂。 +

+ +

+ +

+## Table of Contents -## 产品特性 - -- 离线推理,3.2T@INT8精度算力 - -- 集成KWS(唤醒词),ASR(语音识别),LLM(大语言模型),TTS(文本生成语音) - -- 多模型并行 - -- 板载32GB eMMC存储和4GB LPDDR4内存 - -- 板载麦克风及扬声器 - -- 串口通信 - -- SD卡固件升级 - -- 支持ADB调试 - -- RGB提示灯 - -- 内置ubuntu系统 - -- 支持OTG功能 - -- 支持Arduino/UIFlow - - +* [特性](#特性) +* [Demo](#demo) +* [环境要求](#环境要求) +* [安装](#安装) +* [升级](#升级) +* [运行](#运行) +* [配置](#配置) +* [API接口](#api-接口) +* [贡献](#贡献) -## 应用 +## 特性 +![](doc/assets/network.png) +* 分布式通信架构。每个单元都能够单独工作或者和其他单元配合工作。 +* 多模型支持。包括但不限于语音识别、语音合成、图像识别、自然语言处理、LLM 大模型助手推理等。 +* 数据内部流转。可根据需求配置不同单元协同工作,避免复杂的数据处理流程。 +* 简单易用。通过标准 json 交换数据,快速实现 AI 服务。 +* 离线化运行。无需联网即可实现本地 AI 服务。 +* 多平台支持。包括但不限于 Module LLM、LLM630 Compute Kit 等。 +* 灵活配置。所有单元均可完全配置运行参数,在相同的数据流处理情况下,随意更换模型和修改模型运行参数。 +* 简单易用。开发者只需关注模型和硬件平台,无需关注底层通信和数据处理细节,即可快速实现 AI 服务。 +* 高效稳定。通过 ZMQ 信道传输,数据传输效率高,延迟低,稳定性强。 +* 开源免费。StackFlow 采用 MIT 许可证,开发者可以自由使用和修改。 +* 多语言支持。单元主体由 C++ 实现,性能极致优化,可扩展至多变成语言支持。(需要支持 ZMQ 编程) -- 离线语音助手 -- 文本语音转换 -- 智能家居控制 -- 互动机器人 +StackFlow 还在不断优化和迭代,在框架更加完善的同时,会持续增加更多功能,敬请期待。 -## 规格参数 - -| 规格 | 参数 | -| ------------ | --------------------------------------------------------------------------- | -| 处理器SoC | AX630C@Dual Cortex A53 1.2 GHz
MAX.12.8 TOPS @INT4,and 3.2 TOPS @INT8 | -| 内存 | 4GB LPDDR4(1GB系统内存 + 3GB 硬件加速专用内存) | -| 存储 | 32GB eMMC5.1 | -| 通信接口 | 串口通信 波特率默认 115200@8N1(可调) | -| 麦克风 | MSM421A | -| 音频驱动 | AW8737 | -| 扬声器 | 8Ω@1W,尺寸:2014 腔体喇叭 | -| 内置功能单元 | KWS(唤醒词),ASR(语音识别),LLM(大语言模型),TTS(文本生成语音) | -| RGB灯 | 3x RGB LED@2020 由LP5562驱动 (状态指示) | -| 功耗 | 空载:5V@0.5W,满载:5V@1.5W | -| 按键 | 用于升级固件进入下载模式 | -| 升级接口 | SD卡/Type C口 | -| 工作温度 | 0-40°C | -| 产品尺寸 | 54x54x13mm | -| 包装尺寸 | 133x95x16mm | -| 产品重量 | 17.4g | -| 包装重量 | 32.0g | - -## 相关链接 - -- [AX630C](https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/products/module/Module%20LLM/AX630C.pdf) - -## PinMap - -| Module LLM | RXD | TXD | -| ------------ | --- | --- | -| Core (Basic) | G16 | G17 | -| Core2 | G13 | G14 | -| CoreS3 | G18 | G17 | - ->LLM Module引脚切换| LLM Module预留了引脚切换焊盘, 一些出现引脚复用冲突的情况下, 可以通过切割PCB线路然后跳线连接至其他组引脚。 - -module size - -> 以`CoreS3`为例子,第一列(左绿色框)是串口通讯的TX引脚,用户根据需要四选一,(从上到下分别代表引脚G18 G7 G14 G10),默认是IO18引脚,如需要切换其他引脚,切断焊盘连接线(红线处)(建议使用刀片切割),然后连接下面三个引脚之间的一个即可;第二列(右绿色框)是RX引脚切换,如上所述,也是四选一操作。 +StackFlow 语音助手的主要工作模式: +开机后,KWS、ASR、LLM、TTS、AUDIO 被配置成协同工作状态。当 KWS 从 AUDIO 单元获取的音频中检测出关键词后,发出唤醒信号。此时,ASR 开始工作,识别 AUDIO 的音频数据,并将结果发布到自己的输出信道中。LLM 接收到 ASR 转换后的文本数据后,开始进行推理,并将结果发布到自己的输出信道中。TTS 接收到 LLM 的结果后,开始进行语音合成,合成完成后根据配置来播放合成好的音频数据。 -## 视频 -- Module LLM 产品介绍以及例子展示 [Module_LLM_Video.mp4](https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/products/module/Module%20LLM/Module_LLM_Video.mp4) +## Demo +- [StackFlow 连续语音识别]() +- [StackFlow LLM 大模型唤醒对话]() +- [StackFlow TTS 语音合成播放]() +- [StackFlow yolo 视觉检测]() +- [StackFlow VLM 图片描述]() -## AI Benchmark 对比 +## 环境要求 ## +当前 StackFlow 的 AI 单元是建立在 AXERA 加速平台之上的,主要的芯片平台为 ax630c、ax650n。系统要求为 ubuntu。 -compare +## 安装 ## +StackFlow 的程序和模型数据是分开的,程序安装完成后,需要单独下载模型数据,并配置到程序中。安装是先安装程序包,然后再安装模型包。 +裸机环境安装见[StackFlow 安装教程]() 。 + +## 升级 +升级时可单独升级 AI 单元,或者升级整个 StackFlow 框架。 +升级单个单元时可通过 SD 卡升级或者手动 `dpkg` 命令进行安装。 +## 运行 ## +相关 AI 服务会在开机时自动运行,也可以通过手动命令启动。 +sys 单元运行状态查询: +```bash +systemctl status llm-sys +``` +相关命令可参考 systemd 服务命令。 + +## 配置 ## +StackFlow 的配置分为两类,一类是单元工作参数配置,一类是模型工作参数配置。 +两类配置文件均采用 json 格式,配置文件位于多个目录下,目录如下: +``` +/opt/m5stack/data/models/ +/opt/m5stack/share/ +``` +## API 接口 ## +StackFlow 可通过 UART 和 TCP 端口进行访问。 +## 贡献 + +* 喜欢本项目请先打一颗星; +* 提 bug 请到 [issue 页面](https://github.com/m5stack/StackFlow/issues); +* 要贡献代码,欢迎 fork 之后再提 pull request; + +## Star 历史 + +[![Star History Chart](https://api.star-history.com/svg?repos=m5stack/StackFlow&type=Date)](https://star-history.com/#m5stack/StackFlow&Date) diff --git a/doc/assets/StackFlow_unit.dot b/doc/assets/StackFlow_unit.dot new file mode 100644 index 0000000..4ade435 --- /dev/null +++ b/doc/assets/StackFlow_unit.dot @@ -0,0 +1,36 @@ +digraph G { + SYS -> KWS [color="purple"]; + SYS -> ASR [color="purple"]; + SYS -> LLM [color="purple"]; + SYS -> TTS [color="purple"]; + SYS -> AUDIO [color="purple"]; + SYS -> CAMERA [color="purple"]; + SYS -> VAD [color="purple"]; + SYS -> VLM [color="purple"]; + SYS -> YOLO [color="purple"]; + SYS -> DEPTH [color="purple"]; + KWS -> SYS [color="green"]; + ASR -> SYS [color="green"]; + LLM -> SYS [color="green"]; + TTS -> SYS [color="green"]; + AUDIO -> SYS [color="green"]; + CAMERA -> SYS [color="green"]; + VAD -> SYS [color="green"]; + VLM -> SYS [color="green"]; + YOLO -> SYS [color="green"]; + DEPTH -> SYS [color="green"]; + AUDIO -> KWS [color="blue"]; + AUDIO -> ASR [color="blue"]; + AUDIO -> VAD [color="blue"]; + CAMERA -> YOLO [color="blue"]; + CAMERA -> DEPTH [color="blue"]; + CAMERA -> VLM [color="blue"]; + ASR -> VLM [color="blue"]; + VLM -> TTS [color="blue"]; + KWS -> ASR [color="blue"]; + KWS -> LLM [color="blue"]; + KWS -> AUDIO [color="blue"]; + ASR -> LLM [color="blue"]; + LLM -> TTS [color="blue"]; + TTS -> AUDIO [color="blue"]; +} \ No newline at end of file diff --git a/doc/assets/network.png b/doc/assets/network.png new file mode 100644 index 0000000000000000000000000000000000000000..248b9b68abb8d94da6cd40b8d9299707cd9a8629 GIT binary patch literal 118173 zcmeAS@N?(olHy`uVBq!ia0y~yU|zw%z$DGV#=yYvEMv1f0|NtFlDE4H!+#K5uy^@n z1_lKNPZ!6KiaBrYmRE$N{`&v%`<9eTzn3_#P+TZ&wXj*CqoGTwiS_rY*IKWxZ(9Ak zxLkMlu63oNvD{r9yaECNO-e2I6gdSvoT}c>oatlv{QL2fJe)IGm>L7-UEf)BHs#bz zV_~6Z#@|2R>GztJD(NV|0!1$(c3+XLWoc62fFcG3rd4oGfu{gtC|vChl?>}&3?Q8g zZAHb!gJWWRLPJH>CUed{>*njr%dl_Xz6=v78(Z6tU%wtrFi0?vu=>%#3bLpGV$6;= zPo6*DT>U+-PsZ}l#l`NHMNc>)BO|9wnUb(I>h>1>xqj{*9vp^-hDVMb6_l3tULUtt z!X!iB;lqdGFC@VZe9+}p@==tWHQ+aoH zB^pR{^zq~|aqz@M<(=<#y?$|NsdxKcHc+q>h~7{Ihf0Cxt&Pd-_v?P^W?x(L z@We#rAHRMX6+Q82SC-8p$}ZS>83wbmz3o(u^O7Zw*k zz9sYW4BKim=Qf_53jMku4}}{F2CzB`w0OHaIx^0$|7Y1PuCJ!6+k4|i#4`W+=dP>_ z_Vn>_S$?_nL}BFGFthx7XZ-E|9$6K-+M?`@#K(^x?-U-F1>q!(4WLNd!VfX7Z~DA> z=XSr}cY2X)_l4JA?-ZTZJu}~a{*fa``s_@m2L%QFc+{=`+3n_)7m&u&dw;`ZA=pG@|zc-Sh= z@Z&)<{|v)qH+K1{U@w`uu!55E4vVbp?3w2Ia+}l6CcV0{a>=q~Mep~1k28EI;;{H) z!Ts9r6Q@l(_T=Q`nU=+B<#!6%OG`^-Ycs&fAW}dy#8H6dVbkeTr;?8KNQ#Jve7KoD z->~%6l|H*A-AP|xT?IMD#np9V(ors}@^^PGwyS`mdAd=cBPcxe*2L~EGpzWKa3#xh zciG!rS%)+ae7zojeqHSD2`Zfjo7p#~pP$!frvl0|JC<}dXmK6Q^6+rGq-mCjvRluCcKNy; zYj%B(<4D^)Gjem<#^mFC+j4F?)zs9u%TEFaOV$yq6-^2pPQO>LS(9>Nf?`X1`{&Q+ z?c={bymBzd%((E8i)-G9KR@ob|8zAxUQkNvmfr6zx8K%$ILO{3 zVaQ}}Z(m|1D<~-FGuLWr`Tg4IYu4y6Y|Fpj=e0EJ)6@6w@2A9Thpovd`up{I{QYIe zE#eBv-3XjW%goT;i zynbe;@yWAiRZUE$tXZQIwm$Cevf~;2$;bOr@9n9y`S;_oMDMY(+v~yM`0j`dC~Yjf zyXX78YMZ}bE~liWB^gNEN}a#E>}}GC35s{h@7L-?ZCP>iE5H38gVWP=7jM~er7|)y zQgY+QjZ>yh-I#fKSz2P{w>LLcR8&5kF+M-%bMl<^hYmUIDtmis|Np=Fay1_g!fZPR zwe2q`{LaiaUw`+Irh}Ik7sJMl8}-)je>yFCR;-wa$dT;zd)W@i|NFqcCT#WRU8S$D zO`J9B)S*`H^RErhg-1k46hA-rbZ+@Q$C@x5P+W0AqY9Kx_~h;Gyu0df+~!(*-Or;> zza}5+DU7@svmt>|*}YFiRkhXpevNRzt`~N{UM$}8|KINyCA&V?^?d$%!I>Xq$-BF| zZ`a-jCl^a0a3zwls6|NbS>hy*Lv3%@yx(5<*zM5a!;%&S3A^RauLxYs!Oflg_t)2$ z^1G#fzTM9Em{fA?_sS5hf4}elUvxFA^5xR$C(fOF_H=rD+K~>y9!cY6v2u@VR8>?2 z1O*SS-~X@bpu9JzrqW|i0v9+JTsT!F0@_~udURSRtx(w9u+#I!#qAaQR|YQ^5)e2r zN!9z--x=F-ZXUX`v-sr6lZ*!v3=A?asVwuIeXK{)_`{bkIUo1=+kO>UzyF_AXJ@C3 zecc>pcD@}lO*MA?g?4$n-Oi4O9N%hQJ>*;=Ttv-Ie z9>2Zf{{DYo*Som8Z%#ce_V3Sg`|TF?-)iI@*Bm)|bmGK`7oYu>eX1e3E0a5aS? zfqRH|yV`y0wx6>MH_v%`=U6U_(20s;pT+V6Jro&KRaIHo+2c1nE-Ej7-e>(T;b@oW zlBbk#3Yezp!&(u9lUy302xa5P;g)G;;k@ZCRMMYg1wP-TYKc~=Y4#9{PND?^tkG`ru%-s+g&#If0dye^Av{I z=;+st;uu&8mA|t`kvkn3wz1>o@K3yXCq;8Lh+woJRE&uUSb}+eT!k<{Wc- z?t7}zduz|#HFMUl5Au7P_OxpDS--8T+M+^v(_XE-7?OBN!tiw3E1Oj-g0ChPu3qjI z-g@+Ki);R&C&9f(54T*s+jDU{SNCqo?t3j>VT!Ax@&grC`l;TIZ9MtGzhc+F%sn5H z7`bn~HTCrKdv;7Zf60m!C!T(Ne608J*6VSL7cF`;sjg?*lxfq1goKzHIE7EDY;NSO zIsaYexrLO;i4z{Y^HnSkX*SsZds}A%in0q6!If(Ud)a26+NnKDy)3t0(@4A=rJcMo z%x`UJLiUa|`@D`tshijEyUp$_^0jokujOMGDp9-I;8#fUrSNBlFVOnZecQ>fja=48*yKHZA=d{l& zbK-iAXPgXtsbRx5dB&4XUawX}?S9mqzgxZ^93d*;2$9-&?c@ya)H6?wzD`}vw0vpc zk1Zi)bHdDH!ZZ`t+i&f++V8chxqBt|ngcR%jh0)4l07Vs>4{!p3ki4~@7J4edDZUe zm5M3BF9Z7`vvbOHq9VK3ziGGs_ha=R&VZl7ee(ZG4y{l8d`w!t=EE^*ew#VZzrOf* zR9t`0g~j1*O<4i^?#!|cG5-J5K7CK`u~mydKWtQ~E0_Lj=BuKiKdUtG{Jg*2cipz% zDdJwg@0V8c@jg`zjgF=!rhUKPS;tkqR232u+VQy0TCe+fMvmy}AFrmRUU3PZa)uIVI8&VAv+z<6rE@SoXp#K8@l-iS0effnuQJkLJ0ZHQFVe12MLpZ@d}>jTcs z_D($`dMfqX<)X$YcCBW~;O9lJ7Iho8O%KY}Sgf|BWz~VCRe!uze$iWcW_3r=_MlTG zsu3Z+<&Qem8(D;0CVV!Tk?_3o_|rxfAqR#!jfGdZ*K>c`bmR3xGxtT$mbkdin%h-k zz133aSdwbZ?H;3YS$>zW?YXi6YnQlM=@~BnEh86df68E1xYGGn70;a8+j>Q{!!}fY zPAe)Z($Ld8cKC4fjT;epdp^3!RlhNue)<5Y2C?~a!TGG-_NcWPTbJ7{ww-_6LjLR5 zuRh%s9Sb)v+x&3b`5U%*yjr`ZcCY)IwZl0hR%PqEt5-5-mxr=(WZZ~py?*&TyTF4# z{1y~$+{3rvpUJj)m&zojA^@K!s>Y1fN#})-IUlzm}ys>9v#Gx29<@sh- zm+r>5+6A;$FW}<&dgX{nfOM#jYlPiY$D>nNp9DV(cA4ldcXXH1r>m7Afmc)H=T#&f zaF9r35%%FwY!Pf@WIo7Zy}p>mpWjCB(dxw;LQY;u@xJoJBSdy{aGlE{EAK-gDuMB; zhhNtJ3|;U!=%L(#L)tNCdsH1GwtUt5UaMBy{d?2B4f6^Po&Vn%^KjqKXVTBk%{_f` zvU+DvkIMWSyDhaRtY4L{2nk;_?dpxtb?rY^sq)^B5ARzUFmra!#o30xLW7=%d(O>Q zefGfX)nP3|=~XNE*B+9&R4~_Hb!(hx$ZPGDW$Tw*S}W7N>gV~W{(F)!()ofe0)9JA zzvhv+&~-4fNrB_gPEh&X;@zIZ9K6yccV5rNfI|@)f#C|tdXo*r=5fuR_G(%Ewl9rZ zUk+y3IEPlWtoX*}0sQ&XB}O%|H^vTT*V$CTwaH2pURhbttn&;PePb}3`+1g`fQ zrvL6KwH%QLA{PD{Y^@siKi*K!ebUnU4cm488 zS83BM5w_;W_xu0vJNZ;hXHAOg`_Fd!KT2DbL}W&Vem&TpwTf}W%qfa5zlv@uPH9*g zbnML@pP+T+HSv1dvU8-bR7*__kPhoq-8JXe2QMGNrxMND25g}L(gA*J{aHijJq>xS zy`n^Wc}(oJH#4rRi0ulfkXX!pvsaA11)!nBl_`;wYfUcXM6K`CTZ(_DBZM9ETno|Y*n#CXCV3a&YJc)=lMm)7Nuy=rHiDl6nt7gmb=d^%~ZrKjG` zClj2@4u>6Hso4MThp?~7+?RKf7{b@xvZL`D;4f599fNw)GZD=@)gZEEb~a<_YHTo znI0Z10v9`7%_^REtcf#CuzSW)9kZMp2bOqF1~o)GJ3GbSx$b1jxwWNpWAgD$g^%5i z^-5oV^!D4v{_hq2`agxL534B)JF-+hnfv+iX|tumCAFMA z-gazu*VGHy=H|7h6S!9%zP41z`+3oshf`-9I%O!SWxy5|^f=mYZ9ePNc}qifOb=Y7 zyJ$+#s}i!WH~ja@{fQ7|EztlFN>12f5aIh|avl6O$X6VmbXz!ST5sN^>1I zYsb!>^WJUy=~aeqBIf{lWdy+Zy7e zY??xSzs>ZwtCq@*zUgK8wBge)#w)@7T%vPdo-t@MY+$rGY`j)(wfek0XHMH3Qubv! zye0GUiF4=D?(eJheOAe}{6>x$8?Tg0M1;iaYiqMVmWk<{bC~X}cRJ!&dX1Z0*6Bsv0rur=HtGs>6pvt{s?fMA@Q!QroXdc{lQlNUO(Je>W!2Ye-me0;Tz2Z78 zfk$__*@~W94MtiuUMoK6ERBiwdi=J;kwx&*hE~%Y#TEfSi-j#hP8@=R>r#&z5eQ`XO@m>N(d;SORwjvYxk&T3h3~>O)t+W64#=w4E&9Ck7;6 zxmMI9oHEIiP4Zl@J3}dt{?*0Hy$@g8n)upDe37&na~ofc>$$l)num)|2fsaa;ZDfY z(;+d_U`Fz}tb^E5TZk9<&yXLbgYtsw4+jFh9TdAnLk~Wi+6kaCwe!b)2 z>ovYonSWaM#~e}4w{}n7^oxr#c;y{|gsBUE^(p>dCiJxCvBBz#t3PmrJ(OH^NY~}q zrL8i-E|$wa7-c!1TFIre?AZDquJb`$S6M{@T{u;rOunD;g+;^rV~cPfBlE%*tLNSA zg3n~Oz2C7<`B^u2lLCitM}ro}AJ}g&@6GTK*%%2;_!Kich(m>Ws2t9UmZ{= zz5OFwzJOcA>hHC$*KUv4QJ|Q8eO>CMC7#d!?264?wc^pUJ+p5vxYwZN)4C?>cl|+5 zl?}7+ia&T^HGyZ@rr^(K&o1=}&vaj4DmHi5xv276GG7!#e=TUUe8FaVE5rEM3ZpD5 z(V%RNrCJ+i1ie@C3OOng&@|0oUL{~Ah90nI5Pyeb*&2nFIZtS`|SFdE}qqYY(&l;t+Pc?YO zvGkY{=TtY&Z&v!E*Rp2ra!P%%uD;x~jYan$vkA-Bs{$8-n@=4*aYLr)#u2q`raA2v zExghTTZ9~0%HE_*_EnwAB5)wX&A2O&C*6Wm#iIT5ytSM@3Chxp5{D)19xzv3e7)v< z{qMKiH`o2Gs{8%c{MVP4mzN#i7bI&_F`+Q{nBcel2A9@(7uR`Q7JL8Mj{joK%Q>rC z&#IWO+%rq6^s||mcJXar)l+k#*r&S940|BD@J#Y|p5TX)tK4K04~oP(wJw}+YeJCM z-6;>EoH$!Wf-Y=$I{E&RRcqbf&+)oYku8&?+$qAlfW=YZmLE%qv=KD-d~sXXV;34Z&!u9zQa6g+G`b+O(&F|Zh5QWZkWV! zfZsm-M~~_@PlZxbkuP3>li#lByQOh6eYw)vzLe}2Go;tLtqxDr3X7|b40_hv)_)~Q zVu@l+i`aRC>!Ob)&q)!U{iFB(jU#GCCl2tM|GL<((6nN4U$V^N8A&xC5=|CMUf;l* zaG)}LUi?E*yXVDr515Y`Z9DtjT&fo|46|j6iCNwqkN5ZXo_}4TSKiJin{=p!^UKT2 z?WWn+Hk?hCE}rSlsd~=xYP$0LnvE^zBR5=MT*6%5axG~o)9W2)A{MYjtqfF7GMArf zyr-%~tN5`k@2Q$fZx_+fhpkgsH5Quo+dR)yY<)7xTd~!*?P&EQPm#bDK{t`W79lT_ zi!DO8o)r1tDzA+NjU&$BSkY9lb8^n94KeP?b61r-tqDE0(lS<#P4u6w$&ZqtRSW8D zul)Fa;eqT@x2H;nQzp7{lTD`VuYL_5C-&|TeURZ zQZ4sBnZ%!;p7ux>E|Ts4@M&Y}X)$o)o9|~&;q~4{uTA(5xo52`UHwQ=E=kk-e3t!0 zmrZk?@}zxWwR^O>eW};6h$SW!Mq-+xH)rLne3`1c{2E`_>jT;`FLmB!20Xs|q5SH{ zz3Z}Vm&UcGOmMXOd5$aR@nxB!SvnUNyT8wQQ&zQjd%>ZXPU3<|td2XPKxO1~?wjjE zUTO7dobCyc+iK3aC`WUQ!Oit+*#5us;`sVNCO zC68h=$xf9^k}lHo<8lvQ>v0uoz5PZcZ*$;|yKcVQTHMwjD(Jnm!DH#9l{SjOJI=P9 z)p&e8*7r$-tYD|t)R5;-tsYzrJZ`paVi7P)%Y|1zF5@x{f-o@$;dfqs^T zM+#yOo6Y+;{Y=%G^q}bI*D~*Z|NH%ZbHc$U(BSH;#r<}VJ});jSa@95XP#MS*WWBJ z{#zF-S9Zv(Uiw)?_O`m-bGz@=21z+vXRUHCxsQ>-a)OF$?Z^q1hlLjhg zBG>FL zTlf8|mnl_Q74P&pX(xSj_gfK_+Zxt6?n~PaRPa7LytSfjc1^mi{b%FbH`-c`n8qC58grU~Ex?I0JMwhZHDzVvDGPnl zt%PTKFma0ioSI=jN#)}qZv79RPU{=z-?O<_^;(ySiOK5M2E7>~K^*Hi(jG46{`qS4 z`ijzf(@W0J^E>O=dEsExu5(uwUUK?YrTugN?I{y^u0Q?!{`tFy4TQZ>f#{U z(wC+)NyGY1$zAW`LCSe`T7RlnaK2g`$dt)%+W1jw%RJqBue`&@0{hH37u~-3F2>tn zPJxhAZnI>~vA#9oR*_Acn#+nNt$Fef}zjZ!n7DUtM}_x_JY`5R~RYCa@N zU7m4NXWipn+IjEZy}G)(^2a}S&fw#p{`{_g&?cSt;)U}rg@4<==KnE$xBf-_rO!^^ z#VfL21g}UnWsT02`F+ai+xf69^R#x|U9tH0*}M>$t&?Y`C_gXfex3Jo!qW5h{Y$o) z-(1ef>?*?O^|h8+`bUfZjRS1YZ9aG?%{=Mz@67!5zwW>G?oDAWt~@O8NT%~v&dQSk zk6!t3X1`szJtePBD>cgP%gV$fy}Oq!4zgN0J-~^P)wfN=+G_dp$@f)`%(I)a z(z#FmrX7t@dn~(Bt!U4*6&tOXey`BHm8bq%UAuC2jz`$c4}wuvzSjgT!@A2;PV;v3 z70;QGn-q3{W@2MFCh@K^ezRO_ar@gT%QaqiSUu}v`x-b+g!9$vGs#z~=2X55uzL9> zXUp4U`L9C(yTeXeNCEa^$lkRMxPX=>&3Rl zGdnqjPe&XRnzmu`+!o<;Icdh-kv&NwQYPXbr|$UiCT-^5{Hv2c1=sA0jCp1>>*9`!PAB7c zEQwq-h0U*5d&4<}*~*sf0^7rCZTDKvlQjPM#Cr9*-t8rqX0H*gHeC~`%i+`x8kxD} z?7Pk7q@DFr-qSr(mTR5v$*>J&IkuYf)!LQ|2kxB;i2WM*^F67yYCyJ~fEUC{6ybX5PHwJ97?t zO-luham7_W73Gt$IB=v>xbn@$<1>s>xuV`K{rf9oZP>MSv8Qk6@AnM~68ii5`}3X8 z=Our8b8|(=Dd9hJ&hMPPd-mG$R~)PFzC8E#&bgXr$rd+TljEZ;{;g&8-s-d5)9TUt z()8O0Olx%O&sw+dS5QCcbxlhKc*MD)bn!gf zDm8;f=^c$PeZ;-5#VD@XS~Pi8wr^k2KC|dWX5mHa3fC5fPuumW^P-84?y_U%Zjni6 zl$ZRxzgx&_R%onjwAsybsij|D%)J_R{8N&x)Hc5oq5tljO$FOPmBqGAlBr(&x1_J_ z-4eX(e%s2Bl|5|Vt_c_gIDcT!b*we{QC7IO=k&`p5jW4~m2Eg2DQkO>lcDNDvtsYI zMxH&3+8gHSM>b8`YqsfH#K~VLyH-XVTRu5zt5jQQWERZ)Bpg6qA>JU8B8J zNGSToq3bng%WK>@Re6#GjAx$Yz2gx7i|K>){?CT;pPB6w4jxKTE4JQl+$>q~pwKYB zkMHV|EGw_m9pN@nF`q-HrPlp?D*o^5`ud4ernnUJC$Rn7-*{(Af$;b5JN_%lSDsFZ zOglf%w&v&4={m8yrc9b7q~<&8$Yg)JlS@1&$J|SodF-LK^W-KaKCO_9i%Cbl?0;=+ zU_G<#Uf0v<3PEC5gR2hs1;q0fmhZgymCZbacjn$tGv?muH7lC5M&$j*$In(PB`uk@ zg3~Mf!R6;GZ*Tmpz5kP1{-(at7Z(x_xAmNHV6$5NS6Nci>R?=B3a8J}UafUEg+gZv znMMkQN(z}R{uCDQeC?s_-BSD4W!3D?kZKLzdOGikkWl3lQ_i*O7LHYipRIVX`>|j7 zE_3d6wl6j96a-lwmMAUYIy6(FTczv!4b6K?OLBB=6WljxWp`V(y=>#VmgI3^!NvJ^ zrFUDsx^dhtz4S|Y-SSyke?BbcubngXVj_=n%LMK}JnMO;9-s1ak>u&MS5mxxd=I!> zxvEd^^4&SHrM^o~?b-kMe#8nZML~(>3xDh8mCU_Zv{b~8_kQe|B%_lm^D5GeXYV|- zRNaoixF2i$j8J#xtyUPLAF=HK9rWRCa-;=Dl3?pP9u=Vz>-ZaT~w%NwC zvr=`xUaEik^y$UL#q6J-pHKhy=jV|lN48Y`FS+#6H-9?gRzuS)6_u)s-GAR4mo4uq zzwPn+%Au2A!)%(aewndY`JG<*oxlEntJj{LdgA9%FTY8fcqTGn<<6%$GjTqt+em@BSUdEqmCoWQS4gOR4zV z0gY>ImX-9k2OnQZxV3-(Z)dPU8-{choM>ANp{->W&d zRbP&733uFK1sd1yz3F45TK!h!eXhj1-S_=!TYHYlHvP)rkXxaevLHzHE0_K6hh9fT zHn-~Lq!~xwI8^s7`LJ90uE`!sizR)PI=?J9&RSCzE|;zmo4EAZl9uu*vtD#Y?YjHI zEg(MCZ@G@+!)?KHgH5YMW0$>tQMQ=x@PcXW6Xc#Kct@Txnl{l>&GzNVwRcX*JTu9( z*xYWblO!1bNma_^&aqsZ1I#gpO~wEGjPIHgdfD}>OW#GKKToHvUbcWIHU6a6zGvBW z55-ebR8&G%cubpo@$FSm+=Q)&|mt1fc$N|kNoKCtu5#gb*+ zZrkmmY*-rJtG(=yYQ-D z(q)h0vZZCF&rRo5{JQvlRdj!}z&a(R1zh3gvptvD9QFH{XZy5%c<~*JJeodd+nJ1CENIMxfJhJQIC{$TZ+DTb8oE_a;!D|vd4Gjv~62_{6#}`k|nz%eT+`J z2%ptSGn{?Xx6Ljr@aXcIQ%YhJ-K3f&j{LoIKKD-9QC;rKVn=u9s@SIe>dCC zstDhR&g8oGl+FClu6b2*mQOy||2wW;ueO=R($g&{oCt<9%t&0I5ojZAdb!Z#CS z&l{M|U2gI|Maz4_@6}Vc`0I+~gjy{s+wJMze>3k#N!efHsS`YuI{kl6d8*^y+%|jX zOjex)k;Svl96znpy}hFQ|3`aguv+?ueD^Y57uUwx zz5d}3+cQ4>o5|O(f4{xfRId2=_&s~~a&mJge?E2gi_M+M>}9qNIXOBTH*PF>b!Fwr z8+n_FvM`kX37*N}D>me_>hs`TL2!xut6!JKLr3 zW_Kucu~$x5$n&(kF5PtX&C_u<9};XH&pcPM%xJ2{qFaBeIKuUUSNfE;&0QtDeAT+C z?r&#!NniW%E%f32V9wS5HcI{3y_)mIQb+kKzf2^##f(lq(QvmsW_Zctu|d11a<5bt zgX#{eLs^d>yz2kYT7R!eVGFllK&$rbvl_vh*8gSBWEK5$YJE<|jZ2=#nfZl0Q+Sdk z&StO~OW6M6{&Hqr%_iO=^GM5&bEnQx(Uvk7HN5`%MP2ddr>1MR8Xe!ib;7rut+R4E zJ6v=N%XbP}y1o8%)@shI_U#?6DH9x-IM3wY@RR4;HGS`&_Wv8EENu}u^!LvBWE(ZR zmCw(FUiLBiDO{hVo4qmFz4cYk;h5{2=XsjsTWtARsQh%Lkny$3?Gd$w6DCNUjxgIi zQ$6UveEyOB4}Sg7RGSiTWyQ_&|I(bZrH!YbUNb+qJEd9k^q$x<8{5h36%GDBmUxPW zw)4r?%s88K@9|zUeanz}NzXsDe@*$Da@5+(cRu@_mt~WqCvP>7p8PgolYgd4S_N2ZEy}U3gL)v?*&soo{OYg!IWve z;_SpZ-nlcpQV+FdzO37PE;aqquA0s%{Zp5@Z{oR|cSW!~{c~j{U)UO*bW8boT z7@0rMIL;&{;2tyiwwK46MBe<*X3{qfFtB~F=r5MuzVPtTD!K5PYN3}mMz#Gv{52++ zvs2S2ky$z>j8FRV!eqVTpFQVi#ir{_`B4|bs~q=v!R_Akyd7Wk{~a~9VV=~*dR*@D z;<)@Bd+x6PbE@LlV#mW4$3AlJ-?A${c%@L#)hN-))2p`Lia9+sYt>6felJZ|C#P;P zX12Jep>j_gg*=~F?>o#s-|VgUl>2k9_`kCJwpDbl_>ptP%Kzlb@6<%uyB&{tx5hMV zRiF0`_7xpc)mcBK7O$J8|D&nAqTS?@#BmF`=Y`7*d#he~s?7{tlfX&?20BT%?}yR>ay zY4)|XR~F7lvU{Zb?{vN9k_nkU$&B1HPF+b$yxcYQ{LeY{pZxs_nlgPJbIwc9N!C9S zykAE&XY0nV|9v7}r?maE=ilX%Z@VEpz|sC!phsf&XZ@=yI29U7F2#l|EB|}f=bDtZ z`QLYsi}s#B7UYqrz`QZZHTil`@Uyu(um5d4eS6>O-8Kh>&++Yk9eI9h%qzV^{A)i__PSMz%Fe@=_u!5UySBQM>WS>k|SnbF*rCCiLgN4RP%%)Pa~d8f~_ z6XIW&)Gn$ixcoOww)X!5`_)<@zS~^#CT(&F{wQZ1#V?w8cuL=aK;f-_-pxKz|ARj} z(pzVv%|YQa>H9t(-pOMWaa1d8^DN&SC#NI^<{k51&pcNmBGrT>LLsUa!tsld^uU z^Z&K#>LSZ6c3v*k3)T@Z5~Ub>EDqER5K&rDFE`AAPfT zti1X3TGY(e~$Qn zSrk6|+wB?2FMcole=T`!v)uL4%NJi9bv zS<1)46V)|G+$$cRmH)xq|G{Ij>eN%3>9(&U4@+I!*k^R=g_HO)!`_!Z={m`UkI!5! zaLjNDn-*3S60O~LL(_k2@Ki;`+m5eSDjE3sIxM~*bz$?Ab&mSmVD8A(x*2;zzRY;*c7CU> zxsle*^yd$Drxlss;&`)Gv93`%Hhss=Iq_Ks4|#=c>Tu0TVBY)UXtT|Uy?46BDHnkLLo@c$g)Yre9|N95d`6jz# z+WS0xl6bRY?!CWI|Jw3PovnHPSIfr*SM5Kl-+Ovj?Q;yfcu!jT54Gvr<37DtAK#B0?7C`ca%1D$bo-}Mm@l;I zox5Pwz^F1oL8_e-yryY~$<=U;)5;<_8z=r=9i)1deIR5aO_FnGef_$(e&kp**S;Tuby?IGVjZb$8FaRe?7mcWdGd1{|zT^ zKiQTzp^dTrlCa&Suj+zJr+kuo|B+EXz)RD3=E=o2r!w4j@7b$7dC!a4dt`X>n%W#-)=8FJEa7T&(zoqb)x)EK zeL|ion}2(mfvUOK{0kF5H%t__^0zuw)>tF?2+5cDO^1B^!Yz$zSo==SvKdpovQYn9|sRT6K2Z-D=|<%S=jy!!*4guzU|@$_}vSZQN`6 zV$ZpM_hTRbTw5)*O5zPV)#ceOZqfNw@dwhiIl_4a16sXX)`VOwGK)C*`>fl| zL~AWm2{z4Q4`sJ(&YsJ2HWn|}UOMHI_Wn&>p?^;FhXlHY@3Okj(b+dyeA?ow$-g>V zchz*R;Iw-5u1LAY<@EZ>%2jh~*Uvur_iCG>qw|0Jmz^FZwZCmXRWzGN98t3Q@WAff zV?{ZoSsBx}PoEfh%;?{tc#D&s&y45We@@?ZVQK8V_fwacg(sbM5?=Z{m!~4e|NZYf z(Qmr$ObQ8_c{Zm@GtIDD^0-Bt(G-(Q8-q^|>Rx`+sk-GTA!G z>rv-%htfW8hYVjJ2tn|ORr7T~s8T?CL zZ?<;k9VzRwchBqg<=jX!-W~f*+q>YCx;Fd0mCIl4n5$?0;>GtB`%dm!k^3-X)0Ev8 z-7>qT{xx5hbo9{llbpWKt$v5ZUDRYqqIA zu&qauTXoN&t1f-PPMJSEa%bC}%z0zb9(mF$Z1b$SZ;tSqA2XWv(kET&@(Z8mWp!qU zUcS;!?bF#d;ajBbx2n{C(RX6stqr^Xic96&-Z=kbT-=VeraU!H{zo#dA2jLKx%b3Z zY$J#LpNa|Wl}+j&j&48t_k99;|7Q#98wYEieP+_XFm>JYzcK4w)ay2E_^Y3`XYrMu zs>{s>ewe8RCm42DcC+=F^isl9YsF-<@aX_bWJ*+EBXm&4ju0pI;TUia33P z-zIST<@7isBksr(xA&ZFuQ_3R=dzvkvnwmw{{COL{87i;bHOD%5f$$oMW^^3vXowv zlD}nx)dTi0+b?W4_wpHAm2>G=*`439;99%3x5u00`I|3ZdYQe>Fa1~Ke;<~Gx_%KsC>Wf4HDvSjy}nM_RxeMSXc0UX&<0u(m2S~2 zQQ{Z7hxH+s64R=J!pK!AMfIU#UFUD79F9^KmRPS?1)hg(s+u1?RbLY%>&dgJS+38pn+NU-1oD0Gn8M>vs(85 z$=aR;83%=?8T41`#;u=bdL!gon&OY#d(S-Ql}KilzSz-h{X^pV-TGL~o9WM||15Rs zy>9f%eqL@BbG6#~k5cD9>HL2bualDa`>llPinMi`iaz8TUsYG#b+%~n|M_=r@3H#= zN`qY6ZvA+9MD3pZC-b1Te||Bi48)f0J#yy8N0zU)pWEfqrMPr#9r<@UL}RD`Xq zDvLOjH?8nN={ESNbkRD)a2M`MEiF=U8o# zGx&IU+ViGole}#{UJ1JW%4+r15cAbuHV2q%PA%7C*3#ge{B866eP415_b=DJla_q= zZfVK>o4twk`Fmg84txJeul`BD&DqO)POW~sD?gx4-nec{(F0xMV@#d%w(q|DUhw60haWH+-u|~ydIWGXU*Njf62z4Ns@cw*k&|ERY$R@qu6fQCg-xS`vIq)tlz^S{myEqheuDU&Pf$z z#jU&c=WLpN)?4mWK-s3vM}KErG@7>Y&msL>t8a67!|G};c-(KlBe`S4*JFOUUk&9y zEAW3Z@&9b3zy0+-S(VvF-@hM-{u+^$Qg!#C+kN{T|Nh#D&t9r)lUy}#ZQTCL_3tgx z{(f~$DrOh5i^*)dp1J8=&t>ZvUe<3%CKvW3TV3ASD9xd~CblnJASyUsF?iE`zn6B> zs=udx$XXk^YE7HtsR<7*9F%JMm3iAn>S$Z;Nr}QB7MV>yp|uNBISd zzSrh`*>m@A&ws|*U8&#pWIZ~D`LhJ3H_5ZnQEPVdUWPOEd_1m1fLmgY)(tc>mmF)V)Ghb&%fUoKI zV*C3ac>O<{{C^<-+*T&{^ZcHWxf6EOO)c-<{`3Evx#bnXPk*<+-{M<-Q#z}$DQC*k z6LP8glC10s8s32-t_}e#2j@3vXlO0!&=FjrFeUJtPIcYQ*-nj2sU@lNpZxqQsIjO= z#kQ5{`MIN|nX_!3*G`^XeD8VfvF8@YD`#)Nc|{q2swCp@nD|B+vD_my7p%+s&;oNKQ+5pir)*6;ZmY7bwO zEbm)&PWsgMPm6uZ?XS*q&`s5x|JkzohV$Yb(_j9$oc=;wE*XPt=~I5e>>&)>F}eo zYp&L4{Fu~#JM-WJorO2fl_hniem>jIDg5)Kzv-&L?x-tE)bu|zO$%J`amOOd6;hIi zXT9o~GOu&n#0{EpOWR5dF{X~C7BsdN__qn zy;yPMdjF)kax#XZ>@ssRQ{P`t`&0CC#kZCJW9Kf+j(MED@0sobh=~W*EQ*ur)M6w(JQvJ{rY>_oU?9bL9=hY ze82O=(J#w<<0>BZmRGIHS7@BF%p`QB7pqpl^j&#Nf8Kj^qD0%;ZN`d^p$w|lD|ZLX zIahM;i7%T$gJDnL)o=SZs&KNa-@n(h%H+X4(?{==I4-(;mYiSMqFl1IWcl$~3nQjK zd-|t}b$8^6&~vkuc;}qU>YK!G=l*^gS4>Zm$)btVxYm61@UVUU;FMnLY3nyJHk@bKj&G&+b&6rknH7>N=;|jOi7fyRIy? z`&!v3ZgP~V_c-fW$EyYMyIJ*)-Llwy<=9P8u0=%!#*JRH$xz97s zm2BJ4+9a}sS=MB^33tNwLmMT;y(W;A8t|IAa1 z3uiBRTxM3Aq4ac1^C|h?fy-vkcRzPb|IeZ7J?_3)pV;eHT#GHe&tmMJ9?^Mc*4ecg za}{h38<#9#KL1JQbi^^O+gUnQ#ur^KcZI!NAA3|Q>SEWVDNBr|YPwtU6;1HXdBl?* zGL!wlyuviTe>n^Poo{S$TT$)z@7((@3)l}!Jlmw==VlOBv>|;?>*f0Bld%_PXU%7u zu)fQxH#+a75PzD%^c_d4_Z&a|%u&Ley|}K|=}(sQG8e@slKNdH9~4cT{2RqP z#DV2Cr_yVd-Eum<@W7v2D_gc-53X#e{yO{iO~2AroBL~Rju$iJNX$BO?t$)>UrT<- zK5yd`-uL64;X92*6;s0v69TrzRlW`oUM_YcUH;K?J|IBigu}h(wSV6Hi?Pp9uj}pI zp=vhC-}1xhm5V)W<-1&7Xa=3%YBZ^S8Poa{)v`BHS{sfjA5Rll_il5sVVGj#=Um+% zF{yhsBQCEz9<^ZC^GnssE$7Y?l5ytwctqI8;Oa`hBWK-JwK5$Ude<~PTaa~U{uB%L z<(=xnQ6Faw5uurusa(h|wKWg^+RNeQV z^p;z=n(s24H1Ub@eD81J8@uj(QR`GWX4vS6o(z-{qQp~bI`h_8EHeElBpx}px}HM@V_IKZ~9us7z(B1PWJqR)XXN?PYU zoDb`ou!lb09}(R8Bh<`Kx8T}TwkKBux9prJG;!Y(t=Svz{#ThaLPpM6o1X3hQ)@YcA#Xj;+R-Qw0Vb8-^zvl#ze^&_A- zhvDGDa=jDh3;XzgH0=L5+e7JRTmHYxiC^O)HX5}k)|}qHWx1{J%oU}tYZ#t~-MC?N zqoqDiwsar2O1S0s`r}O>bnk!SoPS|L+nEHm%9E>qMI>7-5u9+oyULz**WY_ZQx+Tc zN}m7m<@vWB8UckpeuGBoZ z?veVvr?GX9)PG%Y554`}S;WHZ_NjfGX?yl8ymb8ElotL1PQisue$ z@&o4oit_RlJGAh?#+hQ@>XIGh7cKsDysl+?v2D|YvU`qi+|`7>YlOUbeZ2Vn&-;b% zZfy7{Z2wVneozCGPs*d(QltOAGKG7NWxq+5kN+t8{_{TT%hj(o%x=A#d`4zwn(Cgl z^Ik1xvRRe6>rCpd%X355B&jG%9$Dbi85VD!l3sY)WY!-^m&RA`mVTT6L`7Beq}8>+ z{;HSf<$qi})TyEU_L{v#s>}in*UH)3C66dZ(VQ-zeFV93AyH}d* zWyr}HEpl#spvCq}Z9i|l-F0=5?w2R4A3YA*`&IJXhOW?ZU)FaX?x%vnw(iW#*wJh; z=lZFZvs~iIqI&t^0z2pO#jKdt@BQ`W_d`81Ba$L(KW}We{qfk}H*48)=I~{krfpm@ zab^bJtIK^aR~2OKn<`wqX2}uD6QB2(t6EzIR~XM)HPwO1c*a2$wZdteLl$!FeQ|X4 zo>xJ&3y&Rs`p2qOR@rBUP%Bsd@4$7-tBZux7q59Ek*H>IrTdmJ(?8+D*yC3Bp2nUl zXlvwoB5YT<`rLc{e~Z*@HT??zJ@MCl^p9au-|d?>&bK^V)ck5Olg71Mo7rqvNBV~E zdep7Id4{WQ)=Ha8w{!m8ICAxG*)1LZvfY`NEslK@jlX;Gp!kCm@5T83n_i;;#j#dNi!M_~@w4GWowADiaxb5)7K(OWqVby7Qyd{!?y$vRb!r^D%K(2ueLX zY~1_h$@+J*^q%ewYRtd7_S(WeP#fz+K#$X*u;<7RNcM4_{#qJ zM+Xjag&E8|sguaL^Q3S2uFI3>&FUx-J6aNY<7aE9ad)mr?!x7-0_vN%cFA20^EtHb z{FymX2}^7I?dSbJ@xRaYzN?*-0BNtSR{ zMvXIv|)2nRLY76P!XvT4PvM^zKGEJMlKbql z{7L?DPnC(9J`cm|RQoJm1@_)fYnx(=+|KexL)KVDX!=ezovmDRf!Xr{}o zsXyNFaZ_{DeU_jl|K1i%khK<`ao~B4pCi{N+xwS$((-QFA5pZr*m*kUS$W-ZRo%N) z|1Y=woVB5H!9;Fp5v_f{?~7!ITb>Gxdu-}gG^wy>vH0FA@^AKAe3;zYJXzNzkGIhJ z>sPLD4Hv~l9gB2x-~YJ1cA0mq|E_Hrzb48{9y3^1cy_Jf4(~r&(y#BC1$`B+Kecb^ zyS8p#>D|Nn09E_bsyU-|3u{QW<=J(MKR z|0v15&7QbVE#}6D{#~K1C3~-4Xsap;FUXyvZaMSan!FTchSC+2t@a0x(GhCx@WzF=HnzzVug+Fun_uH0McfIZiY2RbC z@^bn0>CNhWt4b!_IUT2FG|~R&WCy0oX7d-m`M$4|yC>J&I(SX-T;ICXT|Wa~I@@ob z+f=Nblk@L}i$|dTtG^ZLQ{EZ0S57v+dEBneprw(gWcR^CAOH23-C zQ@b~EZIqY%c(ca!N0J8^+6<1Y?Y&rkZSAr38xwaav9wnOu9#-*x~V|cHcs!&UDb(4ilzzsniw9L z;36ctV!}MG$lk1|yYr4II~#IxZshuCUfO#0dP~mHJsP*1{5OXE;wfci+i{RLsUuOa zJK`YMB+q3+Q#({9`IRiPI2t;u^H^}hvjui5EpiI-ruIJGyjCSA?1bDq*Ok|6HE*6Y zKiq36V-ayGXy5bdu+6iAraa2Mw~XEP-)4&|Cz3d1<|n5<_b^sWjJqNs>oD*6o!y$9 zvSqcY&pzafohtdf^worhFGpuL9Wt*u{Jh3b@|3~Ul_85JMSsh^@xs5p?vXm1@r;Q* zSB@Nc-+Y(r_p#ZQU%Fd2EUSw9rFB3#_EE~D%Gujz9+tWH*mmEu*X`5(7L@Jm{rX-a zbGKSc&e1#fEwX*H85VW^JAYruOnc3noCj0)-u!U-&luYVes%Cmuu6uWm zWR6l^XYVuaCZjzLf6UEyIQnJ@IWS1y{E@N#{Qq+|e%zVAA??-GwKENkXI<<`N zYWilnYR|gZlOT5|GRj%mSfG9Ll?QK%q|>M0GElKN5qPP4k#4Q#t)Tf28QMg(rEeTy z5;K_pQ)QAz=&DN}pDFhkOif$#u?3V5q?Wlne8Izg{Qs6DU$J?atCp99$A1bx{o~yq z-n)-hTJ_z3i+jrs;Un$&G z?6Zh_;<_rZ*Hx$L$!yza*@w;rs`=?}`RF5Tdv!mDg2Mc&V!LyNzb;MRx@IYVt;E?E zJf=^*yUPmC*CYCH+Ef#rohxDxG zUrQ#G+&Q;UGwhtsrbn}Vk8fW8JLr|EeQ4gF!Xt)_oPUnxS3Eu&z31reJ*%%?vvHdf zm5}<|z}T^M?+R1B1B-V}zOtF`+BcH~Pcf-KLQ~`_MO);5G&=GuQWBkckf;BZUtd9s z*p>s_`v0EgYXuz4mG&22E*5d~+sv6Vs(V&^u2oP>e5bD@BI0(pX3G-Q{U4=wo}A0M zc(1vqx{OZNB(KGpjv}ib|8u)_|Bo-bRY47HR6cGNts_^A+Blxxz(N>hcW3 zp2BLIc?mleb!shp5B!NU`KNqhX-QD|jWcOdmnM9#{J-$*OGlNQup3raT2wtN9)4yx zbbFQc%bRDOG21CLFw{L1pFT^&wj=s((0RSBg8SVL&MJyNq-Nsue$y6rrOqP)hlQqX z=t-Sn5ZLK8tEKmtvb#({WxLZIA?ftwoEhu6cWPG%-#a(`QEp7ON|}Amjfk^Z&y1$K z>L|5}WCb)|ubdlR(JJ#KAX81M-*Q&-uN}py(+@Rzik({@d_wG*>&tcLeqHJ@vt_z* z+-~2~=zmZAKTVn*_vI0@-32{`e!*of>6hnp&lWlL^~>X*|NiM+efW2__id4D`;%36 zbcplTajI-+C|+1U^YoVm?588oxz`-=aI3nKS7$uCa^`eRM^3Sg9W_si>nHegUK2@t z9UxrjojaxS@i~#~a*N}ZanDQ3Hg;d^StkEi&a?K;wS{VWxq%gxz8qHkX0LW%>>Z*#?#)J;T5dLX=0l${AH{>@m0Aj$x1@wT9ALQ;j6N5tTRr> z#61mFGwi(gCG74#^&4jo?R&2y^XsV7LMyu~KeQD7-den6M%A;h7}q z^yxP@M7LhxuvNAC5wxT4xz+0J8xj&#wP&7=5!=AvnBg70>tZj5(g&x#*^S4N+n+74 z>$4EC*nHyD!uYj!EYg-I_{yK!_tbr2)jG}z_8k&QKW43uJZ?4bc_o`cLtn|2l67*% zLT1`IzYcWxPw0!f&oXI!SNh7@!qYiNzL^V2EnNO=2SW|h9QB(*(=PPpJy8-jo_Vr+ z&x?tFCC@BSx6Sm9US@dqZJL+A@bqn3IlnHn__1$2&OYJ4>-jK_`j6s!U${DQeNwLv zn%Je)f5mjoN~e&oAzJ(&7WYcBv0UHe8Jn# zzvi5udEBP2;K*CU)RtoHIa_z=*9khTync24|G!iGB~M2rbu3im4c-1;Gra8f%|9Cj zKZhwX0`1&rhG83@rSAT?^!v4948hp&fvCHwfZ$_wa>BB zY(XB0irh0#`dr)4)+DloJGP>GyPVfzyI!5+elCwUIvQF&IZ@K>a@Av^r0S%U$Lwr7 z%K`$AZi{_m6#vXSb)}BgMNi>OrPV1@wYHhc>G8Ryyswz-!|y+-w3a8yv#cWL^$VYF zAN_eMx7#F-CYIZ!i>|Iwk?-^?xfHw0d)AW5occLE!gF7wOyCh}udq9(F5CY0TlubS z+a1qbxBa~)NX50vQ{Qod-X&L_q=3pL?+R0Pxu#9?6Z4*w{y9?rHLGLa$&Jx@M}=Hm)}X2nF@kJilDWCkMsqF6opfoVkU6U zG^^w7{XMbhnqKvO)06S0!6_iUx6DHO{w4}$&$8Nob8%4!+vx;NomN+MtChN2Q&;)a zKKZWQ+kT2qx9OL}0*O}P;q{l&93*B7r=eqYeGdHUWh3s?_J zxS6h6X;9SL-urPYBm3{?ee<&=)rlhvVOzhef{#GY?g~>eLV76YyGBn z+nVF$UzRLC{_VIyoBxlNjXitQzj!lWI%j?3!@7w}9`mi@{rvo9xJ|d-+a&SzAEnH9 z91K}@sVhvY|4Oacb|2;N$o#CnuR2S=*4|6!&9*pkuzJ5of?H?GD<7UE8O7H(Ih1Ye z&I);Kaa{h_yS)|(XJ@lb^0Ua;>hgD)r<%`|WoBGl(Ko#qUM&|+Z~2n(%5>qc6%1Wl zgUpN5ElX}SH-OjCh-asDsY)k)^9 zVLA8pWz;pJX2~<@c6L8LaIL>E|KF5lTeyrboH&%Bxi3;OdR9Tsw5iRLb#JT<*tB@w zr`kUpXXbyD-^VL$Jo99RTk)*RC5wceC7dizfdbt9;L%<#X?uf5^S#~g$}^vgJau@B zbYt%P*%o%Uy}nLleEG8MbcCDuu7DYb&ZO$4YCN7;$5pr;EVdsy z_N-B@iK{B`d%MG?=>`9{zdvx$;@C&c`9afnok?J0)tte(xU@g|ZfW!%S)X~&@7jmU zT2!>9zi`!WGkmje{oGi^)~xxzf;UahK36N``9wwC@QBTqzGDp2R1!T`n-op?vgqIx zh5oGK_s1>I1-5FLEacogW9hm=QS|X3Bc1+l{*yeH>DSIYn^SdZ^2Z+a2@Y4^-0xrV zxa{2e(pPKaZss1p?e7j5wA8$G;P}$tyE%nt-#n8fChRK0sS?nWv}M=N72dIHRoovh zO!5{!r?ai_hdKAj<+37c9vn>0%x}5IDGy=_J92&=(J=N>^Ni{F`Yf1FQd9Y;_nsxQON19o*qY^w z?=G4C?veh#O#xz6cIVV(+I>^5XH53do~APUm-LaeFK?`SCtIx4EFP5}SnQ+l4 zYTfD5&^OsBl3PUXuW2z2wfHl;_3-}4kC&W(-m9DP?$PQ~=Qc94f1Yu?pslzoxMZpJ z{Ew2ZnzKGOX4@FO5xeoLbK>QTW?K9omeb)krF7~?W zB#A7RII@6ehWNc_xpmLW|2Fl zJhQ}TDkyv-f?HRJ2d}g`GCydpt#@RZ=HBmW-BQbiuEm`HEWhJk!)mLmm7UWi&R6sw zTh8WQw|ztLl$jl%7UkMH_3P(<^sN6mDFrQk=-Dw{N&&cJ$p_ns+zd z!rA1aP9mrDjRy03R~CusW_niN3T{!FX)npkJICs-`?6?@y$9M(oYgsSuWnW8E4w3# zbr0Cn47p{ksxCA$@+=T&4cWNqpQ-S^FC2E1uC2 zXS3LhCj9?sf9vwRz@ASY%Y&4&6FmwxtlK_u%V)k-g3ueUfLIVfS6R z`Ll9fy)QWzrOO!>+Qd3XdivSSbAo*vX5W3H*uU!ARVSH(jIP$bkIy`*KiGatn2Gbm z;<%{!vet_w&vLkdM(|UfDgV_u!g!tkW@miz<3CZY+3atBu)NR+xI251?w1y`E01UY zJ@|S5xzcMJ+K%e@U7w@l9T|18Yuc72YNlJic=Y-lpQbiv#`BPQ2JyuKi< z_xu}M++N%~z;^3mU%{cs15G^dcik`Y`~NI|)3dgrN>yrC1}ASx=dDWWTxzz}@`U5`SI@%tCMv90Fg^OX^tpm( zM&B2DpZy~}`(R|hRLF&HH{+}8-F;Oio(g$pIZt`k3!SyL6>k^J<$W);arVM<-x>8z zv+X=pw(WAKpGAQ|yXBPyZL7Z7s=nRR+&z0v?=-!5u%q=bTe?^@XsZ9pX1+tSURCbfzu$eY z=({#i?cy1SHQWT}!b(V`)s%0mMEdDaNZjta@7q66M zUKuG*<2{-dz#mG!kH(^s?4`MRRL z?(CeZE4rIpzbu;m(a0|N&FW6mtBSAh8=m;`LFK0Py(xP2OT|1Vsk~h>_eV#6&$Nq? ze*aFT6`a_4HSFf6&cJ73rCvAAte>oOyIuNe(i&eGy;YjBQ<`6vuC}`9If2E~J5%#= z>aIHzq-R=l_AZxd_kHq&Y4so3iAtBd)ldE^=P7!-q3U|%>>DYwd?p74dF?skZRM$c zQ~!79=Jg)~ZY;E1!9TNmqgiL(G_A{rC#RfNcQcF&eE+Q6Ca_=+Y%M_CIdA=!s`no0 zK3y_LXQJw=o7YZA$;``|mU(ni%I|{3THKo#Z`J{o>N4}Q1=}s26#tAVSv0xslK<2; ztNW+FFA|>XGf`7g{*Ca7n@_`L#u`R0ieBR7H79-kcfOm7OP5SZnf}HoIBk`U)7P6< z?kik8Ym?viM4-LJYX#5bM7{m#pA{CbdGlyq-21efIvhgkh41(bgMZw2*?gwP%yXUm zNtyP_mL387kJUC}MSRb<7PxUPPg}LzYS(wO_Y*jc9KS4@e(jRgX|sgF8!kfIZlxU8 zn0#ja>nls<1Y1TXu}i4t&Agf#d&;=TP3?3_rl#)E@S3C1dzLP{GUcLCRNv{3KJ!|S zUG6%pSCqFkblMibshLOT^krr3sj~Jf+vvT;WqJM~7q2CACK|80dHqDl7Bx@)?rioq zZ{%{-61$xa&aw;nedd0#%*MQ{K(`7_z2VJ9ka}agV2r|E9cr?5tm9*evOjqE!20a^i2}nJ1<99Nb=Wn!RR1 zVzs|e8TT8xTI;3Xm;UEIaQpt=DRHc=`9Incc^31P{+N4za}Bddc9%e??bNLKKbM~t z-+4OCEVw&L<^jV~&G(n8%jz=K3b#9bW<97U|C}rQgn!+&4Q*^DA2QZtDe*;oT*c@; z>4K4!#Cx7E&by_#xVEnBW#zto<6Fd%>bRRrH$1czzPB&n`*DY&>ERozg*G(u?m4xZ zMaV-WFl5oBRo||v{hZSLc%9Y$ywh_H?f&D zJBO8ePmWBT{Pd32`5=e?zK6tSgVN5neuK`)Gnc|{c}-yP>^ZU`slGW!!2aXpMxy}H z>VDxa*ObH6-~IOc+2u}u@oeQM_n#@2n{RA>|9Q)tX;DGme~!kxoqnOCDqn2R_cv`? zWa{LjvtCsmd0kt1f9;nz!HKoPXEtpJ?7DsYl-|wFQ+T{jMehC+s25q*dv4C_Kc1GF z2ZeN;Q!|#`IL~wDy6mP+-m^eX@;kSEMc)5OF_YLXIWVaPJUbzC^=-P?Gig4{%~!N$ z|B_DmR{YB-KYGZci6sA+KACrqF%M9&S=({fX_+rB{ zuGPCGJ*?g>xOhf^Yu}WQ@6EriX`VWlS0r=6@;BjPvtG{HIC<_70q5FR={Npm`dyxJ z%thc}ikf}t?zg}98yA->6FtnDF5FRHWOnS>t?fNOo?g0G5jMfyH!jVfIc$qk14B~B zLfg0Uv(HzYPB3(Y``egXS<7SizaQ%RJj30u=u(H< zJ3iCk52x21)?ePYH-7fX|BL*O&02i7HRg$ux~1eHfmgxv4Gx8Doi7Qh_3zyhKgt4{ z2Q!V-2yyTCTRPvx;9$uze}A8h>fXv_o%24~{^jVs@c1n| zXY?DHKQ}egr|)ogG;~T}T)*3G^`4Jva|)s^H1YpvxVA-Yf$^U3O$0QRv?G=4W>?itk-zl<_bP&0we}p1j(KkN|M>rp z;`M=(CbbB!JH%rW@?_DpN3%IWYd1b~8!vNN7^5Grwdd{nD623gPM&m&;2BQ2S)XO^ zf0Q}DGC4-sJJDAxtkgJR$AbkQ*C_O>xc}=ttDuvee&DwFyne5xJL`ofc_guFYdFv3 zxxN2fY1|{#q6y8VYfcw^Qk!|UcX656b`NKn1(y$Y$Fl^i+WcNtbMN_muTFO>GsRpo z`J+C4r;mTtrk+%u1cvwzN0YZI?Aa5XSn1BJySVve?7_{&mE6%QJbk}yp3fCh@UvF^ zS>(;1tuwFlr4_%fkbT)9YyElV`*#7xQ@7gofCk4(eKxoo*?xBxh`QLNER!hzn?unh z^!Ln@FI~;H@fZbdXyY&4#~<={^UOmczb;L8Gf6Vre6p?jd2pDb?!ALYBhtekv_!DB zGwnQ88N8&CeTglSkm9GXjNLgvU7%!an_`wV+Z^6ePSZk z2P|pizv|8=5aKacHjlOS{m*$1dDO*s{+PACQzc0Bwp1kl<Ux%Th3hPVCM_lJS)J-IOl$2v)Gmg0_`^r@^J+y95$0zKf>o7y}a=8 z4%zlcHGa=oOZRc7{O1?rnJ#lhM*4tp@7;bmy#&U+FMSOT`lMTxu2}r(h4Fmfzr8B+ zi!K=5`n+rYzc1;Mr!9^dZogMeCYQ1Gh=S%rq{|d|J%7Y!$7rJD5gA-J37PN z`qRXISDi%?M?<#$-w^2IbV#iAbGFF2^`QoFWdbobx}8dEG$Ky7D}Al`z`19Ca6vC< zSAlng6OW;UVNj>nmL;m|KWQ!1_&OnN@kf=Sy19q0DXO^$#{E$`@R(;#^~RpmFU!o$ za{ip?-?Dt~s&A$?Nz1Rfy0eNb26diXdxH&Cxy~+X%J>mIA?w`BvTeb=Sv-jx@}Csl zEf!fW_cv%`VLz>Wxger7t$yX>IZSV)^Pe4JlUA+Y>$bUuSD>YIP4H1mR*7Q<*EaV3 zJX8N_PH=UA5U$zxblWh!*$2A}4A znA6i6w7y#Iqi74O&H`oGyLIdBT-YC-Q7C9HIAnQLvt`ZJe(4GB?pOW)Sel(ab+xwa z>Ra(83c@oEod0u%uWUu0z46KLqqCoJH(#tgcxn3O9h)<5Z?a zgub=UsbMNb@i9G+XrGlvi)OFL5q^_GXUOO3*~xiT7eX(`CxHPMm$GWU2P& z8OKG}ZJ5v+vXE=?43|u=;JzZBG=q&t(stgT+qC_ zch9@}XZRKK6-_YPqBzOJ>e56Pq0r6iA4*2Cm^On-l-e1RM>RtJ-IzaV{f|{@OXm3) z9hNxO|Hnf&%dpdP)sn=llvo~4zG>w~3;3^G%m@=;ti0lxZn^!^v0Zj*=r|&rqmN2|B-6tmKMojQ*`&#?=ra} zeCtB{o~gC(cHi5WoUR?+sno@)^T6ggr*e;)$wF1#Ot0WCD}L|Iu(=s?<3Z0dEwzQe zPB3(B3;6yg@?25XMQ-D?x+m_s5?@|iP+BoB$x9^3-el9Z_KADWSAYKWN?=~CukG^^ z!){Ig$~437`9C^K*Ib@+SzQKHZlp8YFmPf&c)Crw)Y}a4fo2uNzk)$jg z8eK5|Ay4c}uku~?Q_pEK&1Ro9p_(O2hAZY?YWjVa&EC&~JeTsz|;^tr|9>LnSFe#`neQd&X}8A zA7T7dVDgM3hJA*eo->o|jX!c;3H<-u!K?gh^5NZXeP=_y8*?dj{5-QMO;1V(4;u=BKNGv zPnRY$ONUr57ZG_CG(9Bf=0UzcAH$Endwk@hW!N@8!;c5fn97>W5ptQx_I+PmPLgo` zC$;N4j%B!A?v8uK_f4=Mb^6>HC${jIx(l@|5?N|I_va-2yLJ0NZfaifYNbgxms))2 z_2UX0jw~OA?JxG`<;j0f+>pLzbM}|htD8B`tp7Lfb3ofCX8VE}heeicc=b&lJZhA@ zWag*6e^(e?_}|FeaObJ@zQy)`B~Li)d$d~T{=;zIp!1d%`;WQ(k!n4CThv7%Up3!J z`W0vIg~@x5{5^lvc#h(%j71$u+R+~m_qUlW5nWp`bNWg5eeEW~y~n3+KAoE*nW1EH zrMt?WbyXN&Y4^`F&voxDvN+nQTHrc|M7~JVyi; zzp^x)1e){SJmYJK)$(Jf`O5lC?%%fjd;Rn5U($xE|Gpn}>)}Z=_`1S9)2nzwvwur5 zSHUNJZANj(mHXEL`JXaY~&-LJSB1>p{U%?^Elb-#3zYQwZ&6oeTv*gXM{bz1I z{XfP3q_Z5GfkN;bd!ADz-xpuo!NBLgQQ-H+m*=bsMJwiipLxt=-_z(_mu02RO8FNvk1L#mY=qvMefUk=zXdk3RmA`r^Jd( z-mq)-#3>fmXP>dI-o;#zI^C({`|3Y?tR}VmS$^|~T32w4>F?P$Txwr^mc4&*`o2{+ z&vJyXk9+#+>gpxSmQ9*7ho|9S!hx*PW#6Bkd6}aqFCgIH;lWY)>4{?gy*)3!&bzvC z&D+c;f2yR5`hPE)-fw)=JlasdYwNY(J-zxjyYBv!Juc*3zRNx^@N%?1RA^iob_hme1k1*6QUFj{+OVyNp>ESG8 z)NbiN_l%gu?wRWELObFYPuLLo@D`)BU85CO$agi9Lz1z)C#v6{zuPgtlVH3`Ze@Kq?Rz(I(fsg-E*f*5t%f3vZuHA;iQcdrcG-*TXuW5xm0h2 z&i2odd-v=)G0*n5Y+2E>Go60RmEHSfT3T8JgoK**|DU|KGRK^IBeTz(=)}iICo`Z}liEVHl5yD*L0hx@(ce?DG%>2JJ1 z-P3TpXUSZF9V>mFs>TH!-{CgRU1r0-T;=KIS|)QB_nmvGD>8Y*3RkYj`(GZq=oNkA zgxjg0Fw@^^J|PR3QZ<}SF7oRxJ)2^*vHpKupN!?9latji|Bu~K(6~B${UVKdZx=i} zGjlQ%D_6jtibAhxI-Z?Esv41-RHkZ$D&^nXQ(o(TM@U-wm*jt8)vuq}+GRJ1eq9tX zd$;w{2YX)D9u%)Rd);KQgJSPQ@2NS!o|A4Jee>1Fjq+@-e@S>+<}NSw@mOZ!ljUyRS2X4C zoBB6WYJVpm*;{sPPpU$CX1pvlY)Zlm7VeOE?(#k_PU2jFo6)3)Jn0gLL$u z-G<-V#`DE~c5I!yd_&CkIlr!iU;U@R_R-kBxWidwVaKX%|4+^|PLJ4Krh9u^Zu0eY zu`)Il0cU(HXx<=<~@&1Pt6Z4KO-6}l>PwcFmRuPdUqYI${u*PDAB zous3%;B%Q9U(u8g%POL6U87&Tm*(wPon~G+*+oe5@CBj7PY`yQ1wqD`M$I13QLFX+aBqoBU2B*AP zlE=b0$Fw-uGm%44%TG8-kc?v#=5;wZtx)+c9s zYNE2cMd2fs!otFr|Mg;aG~9jnX3q1sZ|A;ad3JvO{69ZGFaKZv?afV2K0Y-Iiy3cj zZl0_gZPwJ>{PFwuwj)m>szG=5|%r0HZGoQXowDoVg$+ZN73Dc&z zWo2o3dV1d3QP_NXy8h%DGfqs^4)^fzP%tzU-2Ahw(_x-XrAE{i4cBflRUMt44<8D= zrtA6M+?0B9zWsmaA1Suaf8=Q2wlfY~H(frIZKb^BymKX07n<*Vc~-seIQQBhqsbR! zuI!#zcJJV`e&3jzO9LLt+H37w9(P3~K~?*un|aO0R5jz3zPVp}vTej<=I5rqUapo^ zFYWPh`qkXYb$>hNGH$LrYa4=VKH3Jz2?o&P_f`uZrL`z4I37eofJ?`ak>XWdYN@u3mGR_e(Dk`dBT{`nsx) z@vT?5UxCtL!81#9FQ14%+rG;APV^QRVPEN66WpSv>F>Q^cE;t8SL?Ry=Fol~rkWG& zXOhI!Ej`UPtpq2GQwL97=VfVs)$zlYqjtkDzbt1dAwP@L5pEoct8Ufb5oC|CPf<_Y z?DR)UI=t-m$8VP>uJ1Bm$Xm;iy-a<>fw!+SAIVvtzIDIs*gCQ9E>`IvuZhU5_iHKU1qB?(58PkQ=YeUoh?Hz$7e zhHcXuPci?|yzlxj(0<}zIhQeb)g zDC+9+*4NjcnyT$S(a z)y8`w_LsaAy1d*!{n8T8Ikwf)Hl?1vv^6{2s{EbL!$Xnb=MK%%`H^-#(QJ0))-2J$ zz(Adt9RjPbdcD537IgouprGK(_2!95EXqG-t$pwa)6hqq=L?opKK||YMr_6Z&DAfDfzO5Tj&S0R`eR@HTsA!Q=f98NEoF`+ zYVpOe>`3o?#I*hCiNZeCwwTzK&F2All&=b<0&e1E=k-r>#be(!tt`qU)en+H$6)SNSS`XTFj%fxVx zpVODg|D3q~=Pd4+2c~hsG4{JFpDej0e*HpCXY-?n`^0y81kZZZsUCfE*7Njvo0)?* z75tvi*>RUmsZ82)N3L6Zg!3ialLpDV!r1v#FMIW7XxXQzTi-n4c5P!Hi_nK-v(2_F z93qb@Hgd2(Ov?;AUd)j-(RbWqR3uYu436*UYL9cNAN1&%3Ln zqN4J*_{WFDcXxNUFJ7!%`udu$e8#tL-_Dh_e?6whT+i#Xq^3MNt3S~0PPy>x7as1v zE=|Ax!?*BnxJ-95mq78!Bk|3XJoe-+yZ61yCR$s%Xy=ThH7D9bmRos8EXq&|<*sc1 z!C@SIuk-lUO`>O?SuY5zIACh>immi)sb;R$>4TH3H#pvmJYH~UrB7;`Vb8{%vs*yT zfyc-D(~owEif9Bh@Z0@pU}R={@bu}@1zT@=*VNc}PuEMmwkC3pP35FpTeFSR&PZ@= z(Q}ahwZ~}lvi^=6xhdiMS?=9@JZ0&bE3z*fm^gFNtEc61NlkXiSus=WbiAF&S`Jr< z(-C$LC+pl^Xm-pc(f6^%o?Ev9US~gzKNaM;lq>YZ;eJ=0pcs4g3W+qe4c<0-scR~V z7cz%&{Z{C|wq)9Jn?{yJ?mrKn{B!25v)i`s9u;Y8Gkd49^}2odcc@S6Z|=p6%WUl1 zH_t6yldLSg^SG^6uw?zm<(UD&+t%MbcdS=>XTd`zGc&U*>tbiC`OdnqqcHi^)z#l` z{PO44Z@ZcE?9I*1Z*FdGx2^uRA^*PJyZih7A0BGWyts(<-@kuba&8*gy0_fAb0aa~ zynE*ri8S}CjHmeZ)+Ec$eR;;i&8V-i>-GLa5i(b_vx7LL=K3tWzBc2>=6@Sa`6E^5 zRj?T}Jk?3JI6U(J%bFAQFE8ra$UE=Zur-)T=|a|2=c-t@r5(zBQrrJ{_?Z?gI+DnB zQzRfneu4O2izABXip+w~z2BOBUBWz1#(TQn(wv){YQA0#FL`-M^?t91yj4lZ$;s-Q z3m?19>9Y!ax>ak9=B~CRk<*!%H}&q7SDhrJJhO;R{^Nx99S@J?|8bN5m2z|0V|z8> zji)_s>*~+nu#B&Cg@0|`ljAzKC(6deOgeQje{#lt1mBJ@g=XLCwuiKYsuId@VZv;q&L;Bbb!9PbHYm zwk&-m0%|inKGrK^QNS?Q&wa9*?}zW-mnR?Z^FKRfy@>eqB|;`@oclGaPL&1K?Ytl~ z?ZV`FKIvA?5=(ac(>}HO^#Z9!t<3Q%g~`(!&F!{6{@R}_>U*}nk-KD>arq8s2F5K* zmKHq{`y`UoBD+_(V{g*3uTku-?2Zb$qV=C!wp-3Cn00nJ|D)SJKP7)%p0mvAYUH`1 zdr$99e>Ho~oHJ82gJ+mz3cY*xuIBI8>m{$R@oKOBV;dnXBy{M-$;F(1{1yKF`{y&? zPL`j)e~y`VX^3Llp8M#RrRx_?;oG~^KSUMF zey!gUUUTFoQ?)_2&)(XW>wR{X=~dG^hlKC!ueZM&8M{4CwzIR-B=b_szrVj9zkk0z zYG3DslPBlQp6|4om2XPMia!r7l-C?LuQ^G2kk6MUFJ8}t4>~c&n7F;wY_ZpVUf{V8|OUTvTUo;In9RN?zSs8 z&eVR7t0?Tv?z%BiHlyT$?UBCK(mZ#p|2E}+)nDA-_OU13_H}V>?TzUR3re+To!k2S zml(7AzQBEYskvF3r)~Xna(+)j%cEaE1vd-ky*0MGYI!xoF`GBcEK`21p00C2)|w5Q z^KB+e=cZo1rOP8_(((HG`r>bIB0)C}bQjNZ-mz=frJcp;V)}7s-rn9GxuZalA$E7! z(v*{vYQEh}kJ(!l`tk2InY{M!=9efoanV$U-1y%qi6Esk3r{TlBYw^Q

p>G^HDZx=h<-lV9X&G_b2dnV0TSj{Kl&W^$@d3R^U z*Z-XwwDijA>9cNo`uaX?m#=$pJAeOD&&g^!aeHPga_xS$C34kEBxoSsU-J^4f%D3-% zA2=1(?8k3a&3nyHDu+8`L*ccA#~fDfyw~`og0_B?vDh_T_BXSq!I1~om+-B%+S3_7 z`&CzZ#it8-mTh~KX7nl@oIELIVt9|tFRehIm8V|0drmQ#f&>i{8(>7C4H*SZ& zk5A8@uh*iJva_`>FZUPUd~;1#ZskN}_r8wl)2C0-2z2U`vz>MMnZ~)h!fugIB$dni zr8h4z_FdLF*}`*?M)})2b~zJV=NV2adH?kM@wb~|1)j{i6MSagn+NAEZb{y^^ZbIY ze|0zYIW{?$tynaFa!kxDrS3gRPfkU(#*6(sZ8B3$>f#Bd$R%BMbq8lCC7IdoK0DXC z{K?{eJE7?4=)&US$sZpd_bw?Z`6iL!7|6rcye49!Q%y|`%LKPxsgn;6w~Jo(-;+Jf z{xxo~UtSg~JTInkzLC=R);hZC(*{dT^`qW< zj>O(kb#W58zJ0=Xk6!cBySB@ndd64S#oyM^al~^@$h1>I%FFuB=*z2q*H1aCSRs|2 z(wpI`U4Qz%{*`~<-rf${TUDwVxTuANoqcsuaNP5Q&Fq&}g=!a;luUVhd;9Y(mR&^| zDT~(Rels|2wRP#XFO%XT&0omhv7Y|S=6GD~x!ZYcEnX`WJT^SpTU_;={o|&Uv2(J1 ztz9zpM~DBu8cFVXGgP`yA3L#@`IW^F<&>6)?yYa8?p^ibdAX3VaO$BJ&PPw4s4VrG zI?1y5nMY7ikl*Z7N5yY%ZYuXmn~U|jDaY+9dVnWDcoMKL|&&JM%sZ*LOc-r73HqOi$ps+M8dn~0ucYwn)z zy0T%>u>$LV^Cq2H%Y5p-`0L>L7kkn)oGlM>9{n0G`e|!()$aup*UlBbAb#<~w=DM< zZOz|8_VYe&SuFehv)%5SzJZ^f&obiHKmIaOvnAjBLdG&H&xy+nd#|oZd$!cxAYa?< zD*si@%bVu^WfA=1l)dE9q32A$dEa&RJ|ULj_wPjim1So8e%NiE+i_uUb-9v~(v3~2-LFi~e&UwuZHwHTc5y|Z@~y4e z$9tvCi*7B^DNHTZdUtlsMe&oj_Liw?zjP8m`hMj#KB+Cc&YWG~bno<&-~RW0T&r*eE+=CHOliUc3ogqe)XsK z6Z3Ta_+!V9x2t+j+mLh9Xqrx>)5fIrezh;dC9|`$+4$vrJUlqmCUfTJ=TFm*pI7O~ z`@`>2Gh3)pS@y+EGmg3lofK%(SodFR!he~NMqzvP;uot`w7zd%dXcAk&6_F3evdns z+rEuF>2+<>G)A5PpW9CN)HJXRK;| z{CqmAjaT|x#QgXBe)FC9G4tmZ|AK;oUH3Nsx_R^F$6v44e}27wzuk6|Tc7*FJ+;Et zoOpP+{pJ1r_O?}D5{~sq&b+p%@Y;j#&GS~j=8d_Z6>#B{iC18k<(Wji;?JRbU*sq+ z4?n2YX?Rj+_iuF%ho2HVH~IZMW3v6pv?~*&f_%E3o=lMx3pt{*X|w;HHF;kGf*w!x z7fTYFY%)kX-`)7pC)ad=MfY%DP~_yq+6eirc|#Rm#Ef~ z2N%0!tV%rAtXcEq`~CXx5cAy@rpA%e!uv&&y{?tCoe=ma;(t}>-I~l#0eyPbBP= z*ToLEXD4JrzkJqW=a&-^7Z$cYR}KlpZ?@Y z%Fg2FeL45{#onv=?90gFQUCAH?DhM8Y3)6Gb94IqUF+S?TRKE-&HC!Id(q;>M=xFs zWO#XR@9*HPMpbEchmIa~?US|scBf8LQ?uyLkHU|iKMOm6l7i3exGxn`(@ss%Ty!zx z$?g38XD6LIs4twlvwV%pz0l`7FGp8-dunQK6k6R?XQ%o<<)d$9#{gtS%ZXzDSEL{AJ269SKpXtUms^A;A?c}M3TFho!`zI$08EGV9I(U+o%aW~IrtJy}H~o9(z)8u>@4s%hUoHG{{Dj0t(P&F0_mGR{v+wMw48C*c z&XN1~<0nnNdUDq zqwwPEua6!+R6HPj?y}-91d&N>mlV!lJ-B&+9lxHG>H?>pIln^Zwm-lBY5R?iUZ07YN=ikA zkzFhy9TTTWl)C*+JHb;Z;@&wqy+6d=&8;hL{q&og)3x)Q-T2Qkv-5deT;!U1Zcb0S zxSZ{t_3``v-FSbzM^f3jjYrVk-CZ+c!vcxk{`<GWTKK zw|93}cQs213M!hJnN{YAneP4evUAPd>g^}Q94B-a1uCANm*T#@!qUQ~xbMs2S@Q*j z7H$Z=d3wcQrIKC zcSYgvwARg^ZXnfrX-%ZDX85`}M~wwWj+jr#l_XHd|rQieEjIagN|uuXMOc~{^?*d`=eK{w7SJ~Pfcq6WgiU$E zlbBAtySv-?&Of8$tHqkxc!k{E-7V|?)hsj3lQlS@v|fVq{yM+Ak1LJ**Bp7(>isS9 z1bb@Qqx@N%HRkiKv^%Y~m(`32yxC&NZsA}&D{%I$oMh>BJG55iE9NJAHP+5o3;aL%Pkt*S^qjU&Qv8Qq(s-pCd~?gs*fx9W-r`vwQfiq(e*I@O={4|K}5TJD+UQ*H>39 ztgTn?+rP8;d6L=emv?r4HokpzbvVDEdH#>ZT~-=*5C8@+wCcu!Ox!Zz1V+cef)gaZn4x=>;IJh zeR=uR_mpQ9Q`25uSsAh}W@g>rU#U@xcg*j*^mdKqCtssuDo?Lp{JvEG>&o*CYzb~Z zCx!l;X!CZ#v6fjkZ)q~F-P#uRzwp3G=bMLb9+r!`*yU!D#G8F#ad^mmr+d$D{7@0f zo4wNBx8JQbW!GUzKZ}Pf0u7>JM`DZwYcIL%EZ-b<>T%|rr#c5&E_Xk-p4-^ixFzpy z)Yo0b#_8u$9vo=Qxw)y;Eccep*4S<_U4|Rma-)B}e|LZX`BrZ64`08YE%-gtIDNzR z?e#i4gPYlSHNw_N+}@VEICOQ`o4dQkH(OTAX~&5tXQ!k=VpAEq4dLBZp^9H zX>V(4PB>rNJnwsDyy9u2W7`%?o5DWxcl5LcEY~80-DYfZOEq3!pLF`{{vMb4A;&-d zoTPvAbR6I3KTGs0Md$8qTUPwGliR#Fq?Km@tL6!>u%ZTLpM<7IzbYH2OcB}l|6etz zv9~qr>Za8BzrVd@e(?2r{P~dozrVlVT=@9d7suOnwZ9lL{qAhuuyt$djSYz%9Kvcg z|GxM2_opB0k?fJNGzvCLZT;|}An*RZ-p!khLsx}VCRL~PhiB&Gr?XD5Dt)!&`%J6SRW+YZs{3cWy}v*H&fUA0h3!Rjqe6C-zt=lG zO?Pq&OX;MQg7RJi|gw($XHI=`E|c>+L;MzzO$D6ulfEi zcH_2fVsrh}Cr+H`zolN}k+#yL88bBU^70m4&3bxgXYtEiHQ!k(@Av&)*RjNQdWB!d z`^$FR;(BK;JnM0)2@VdvJXz)DjTub8+Qp?lTy&YUj4}EvN zbZ;Y<*THbRn*XdPW-IQyxZLN>imR zag+9;Lx((keV_K4-wU`mp*~?t@$%Broh2_PY5nplE?wLB=xd3^v{Sbht28j&y4dF=5_Doy z&&JbE9r{aJf5tuE)g<=Jxls7gOFb?k;$E=u4za!=YC0 z%gcPFd)$;685z&NS$+Mrq)`e-+UA*^!s<*DX3RLTCG)a`Y1S3)+YjEq@9(hr_VM%Q z>b(75UteE7ea6O(8xP*TJ$sRBchS2$miOxIAD@`EMrOU#kKeyHSATz}lNs{wfY|X# zQhmMw%T=yN982moojh|*S6!XbdCL{w&(FMZQ@iod)wLOaW;ZV~^<%uYp-t{ffugINfUi7G zI>ovZzY3tUd>F4LIiQe7^DtEH4>+LFgdung>chIet$NS~OpDFxr zojp7H*Z0}8Jv#-J%A_^!DrP@_T)J-a{J*Q(zcby~wd|_nRG(j|KaV=TvQRoR;#H{Q!z7I2H})vP;qppjWKWQD-#>H5z95>L6LG#xzXwBnhdM!jM}Zmmso^O zRPS+@|MfxHeo&Sm02p z9dl|$@y&IKyjxeeMxL_Up6leqG{NlgaeEs2_z$1Y+uLt_tDIhP zdt2@tyILu0>)pqNy#Ex-zKXB^+uGmH&&S7ieyij1%NMs~22azEKQ}$TuJdF{($!U= zkv5xp3X6)A^z{5hb5%KSXE-D;J^87@lYvoWiGprrky>=-8?Gz?<0VJZ>;i-83IZ-V zJl$v3l4~@fAi8q7dvlxqk0w=}li!W&qhw9yB>G>9HFiIyW&iq71G9GINx?pYR?V*0 z&%=a-h2vk`Tcgq|Wy*BIAn@YnAAi5!@9geAeDI)Rty<9Hix<|#S~HxRXZzcwX2a^#54%PA|?FLtSwRh&HeGSd>#XUcYqI9z9(aCv(4vtZ>h$G!Fc z_MgiX1x;au-?6-VuFUE}t-oY{)WKVHwjv1{4QSw;Uv%L5uO z{WH6X6udJFM{R&-qs=Vg-^_sJS zeH!cLOBa@wK7Dt0_sw1B8JXD@Tz)yv`iDi$kAf{xy5f2<3W3dNfqxs=c}A=WsfM_DR>;culCLNi_3jf z?ihWJ@-978-Cx*aeWx;!{p&>L(%08?L*Jb2VB?kAQ29CS&D*y>zg+hJ`Sp6danAKc zuG}sy@pV6+c79#j*Vp&s=g-2|*L1~nqoyou)>3kDbzQnX`LB7u+vL4__inCmku3iG zE%&PP^3A6X8yJ`S&(QencWuroWtoRe;+s_Wh#y#&aBHuv<>Z+)wjUH4S>6@;du}db zS!)_nbAOum=^#TjEqmXDW?p8=6E@E#Iy61{wUhUI+O?2ZsfQ;TdLFqSP#0Fk;at(Z z{e>g{qZ5Ax#UhX1zWsaU_k^t)@%wC&kN2rsSo~NyGebXa&xtvf#TDQ0mamN1sKg*` zp0}jn;h`VDex==5o_~KI18BX`k|pWswPl5ci6Ia~e@#tIoL0Tl^K)}Q ze*2boeO+w-)Y#xp6;o9-G&;IOwHIAa-}}gIVOChhmMzcTYif3IP5dhVfpMwk-y^%{ zwf>*@+IHg)4rA*o)qo9)tj=W$IR1F-&u+D$fmQ7Jl|#XuH*!^Sx*My6zedh8J=GDq zCdu~o&))m9e-+*;_qz z42)Bj+iYF2bVBO+W7k5NXKnH5IP+nJSXSLk*R>Z8vuzf1`oH*(4&wm^wh3NZj4Abp zrp#IJEWAp_JM*T!is9wgbLO|P@qV6po>|Ud%ED7!&z){<%RPN{b+~1XMfGXXUOC%Y zg34|m9=6LHB^}|=i{0gtm8E5#e=p@=6RSz)rIzdQ^>bOd#g=>r&0@;ed^i|vx;ktv zXjZMWw>S0dEYtH_6VJ>rJaXiS%~i%TdL~l5_iMk)GAO(Cc&zVS_2r{hcd-W?0)zwVh|tG~aS`><^CNfmZJnF$M>+r8#ml`e7V6k2ro<&l#oJ!@)e zQXU=YTs3vpOzZM>78VvBMMaymesv{?MP7Zdkfnb96xEp`o)ZrRMW~%}Y2~RloEF+W z)muBr=&HGEkc)Oyr0#0bZCcMQY^(yqOe-|f7F+$QUAlhC^iN4)tIfjn9v^gF%o5Tw zRrvDNoo&}oMLABef9fClrC4}t_VsDgbfcf0*w-&-tMz{W|9v}l@9y5Zb*qJ?rRUvU zrK!KZyqq*?QrZ6KdZBhEgd$Nr4@7ZkJwr!er_&SYM)d>-c*5oZY_xGZT z+DetF^M2j?-c@XJ-D*Xf%jTRqb-yt48ja4tQ}#C&sd%08id?C>RVD6`==JRr_FMc& zU9@J6sP;+zE0rgu6quK65IMKOEbJ5W=0AZ}Zilw74$jv1ImF^vcA{_ktL-&Ei$Hd6 z*kBO)rb={W^!9ZnudZk=KU<-;onJa-VtUV={S&sTe~XILj`|rAGzYd8;G)-#7VVUq z-5Ym3bhi8&{cLW#P>@sIr1>ISG}1fwrcJWbrhF{Fj%YrqaYof48b_p1imEdso=%sg}jho@~(+D>9s}A3u$Wl?zmTFWd3$ z@N2c7i+ifRzI%Q`W}|5IPTlRH7tbGla?WZ+n(~{!8WVRI80YI1ImEl%EI4KHD8rGP zB~f^GfkL(M(a00gcPw*MzMKzv)pI#H+TrJgdkRgE6U7gSoGbXBabWE>E6zz}8<^Q; zGCU4Xe|3Fju)5b2jgNOO>5Ikn?5+MTBqDNTf}(TLttsh6slAO(p=&iF6tf>bV`RB7 zn5b?x8*weE_1F?tXK77D)@FKXw^#7=VB`+>#WoY&GbpGdng|IrC51t)y;rK zjeURTt0#E`)YZN(S@yU^c>agZN4Iu%y7fvKW?j)>Gg4~&db?RHc^qqX<=PjlC{;BCNqg7m~Eaae*WAj3syz3KL_rT;RtR(@Hke>T%Ed{^3yXMPg| zub&FLv17&L$SV8aE1l;~KeuSr<(CphDIA}lomDn52@$;=CweB$SlPXAN#WyTS5}AX zFF#wUwJb%^#^Ci<|M$i7&*q%l_Qd1=k#kocE%-P4RBdhtmzhwl)5F%u|DOiirE*8_ zIN=)lrC3(#!|#J~&NWfj%9j=%XskSwe6{}n)AVC~vfcCN%je$O^6<<|W6RvW))<$h zB&GLzKJ$gIi%C2?%d|_y{ZvO5bMDUigGbi>J$2o6>*2nCU!I%SDR;i{)|e`OqLlAd z=lsc>w{sSpl&R(l4YgA|(_V8Tkx$q|;i<;*9s64U9DR9HQ{}$!tDa!>?DsBeLT(cK zCl$IydCYb^n`JaBedGMUCJP*w{o<3cm;hR@v%5V1%(L+29eXbQ`SbaFOH0d#)A~EB zr)k#g7Ia?p;HqBs&Fb(COxkN+cpQIj9wu?SDQeRD^nWpD`}wjq?y}8p$D|Frmb zDEBSZ33at!KWVkhmDi1Ie&;+Ep0lt$`gcmb;{0PKVjDY_>MUh51uY2J@3ABG*_%5d z_at(<_s;$_{gkVo(ae)R2~0~*{&+S^ME6LHS@4>9R(!8~^NM=2XO;z&TFHKXe*XE5 zjmbWzzhBvI{c^rrv-GFAS}xzQ%WkR=Z^;Yp^jtIh1_rAOjOuel zHoZBzaqF1{X&y`OZ3E3GEp_P<)0O{h*d5`bvk}yezjJ@nvDLk%?QSX)rB>I}Jn;Y1 zB4<1Q^Ug=Nc5=GAyPM_QaA;=Z&A7M6^7FH^r$K?Cpzb&4!1e3XH*7HAld*8PyQ?(x ze)?7Z+?~ZYJid57UF_2pG-X{$s#dU|>7$O%8aqL4^K(ZU^(U>ka=Pu)-6{Gv_D!D4 zlWrkA(b=N=l8kf*jMjej+xx%%FI^39DvsVSjrP=?! zxNtFFsnOcNy;Y^ld}kkfadC0{s$;WSw`?-Xy|raw-QQoJg@Km2=ZrmjMf2X8r&WIY zq9o3#)M57}@WiI+hu1ZH4?l{Eic@-!_Gd z{@vrTt{@;-j-%SnXGzC)(XDQp^3HX=*(HmmWnUa9XwwD<$m@oQ($+jz{<-x}{q$IM zO_FH!&C@2!5|3V46O!rj%zt8d|R$mY8n5vMonXy+au39_0>|DCtyoyUL>e*M)*uBmy zU}_OwH^p-&(^|e$`_r9Y)CU=^{J{6D$JqA8!IEXkPII@e+bMXvNvcNuW^rn%)^+Bo z>zDs9%fCE%Ud@@~KkLe(mS6t(_xt_L)!*|#v#DFNuFkNpw^O^ky4Y^-DjCb7mS10A ze+ISN>;6=fy}i}CyZW2jjnzN)@g~mZRdLm}KmC&}|3Nc<{fG8Pw<@Q~ln0!3yYV?t ziJ>>`#^S&qvbud1w=PY)UeW8Se;Tul?CchI?QAczpnI7fimmH^bbYU! z|LaP9+U@FepB<|&p21;V}P~7Z;nqy}b=u^WbXoSzBB$=D_*${My>u z+j4F;ZQfk$H~UM>x;%pi|CW_bWApBjh&&`zby+%>&$bRUBHt@~X66@Bn~y9CJqAZ} zPU%j0pVh4Bw_{&ur90Q9G|oeu>D^#g&=FET>%uDiF>CtP zH+yH_a8a3PIce{A!LoHy0v??w=PZ8Ez}%`aMgRK3SKS!}^`~cbdtc>D)^@j?b$QN9 zpKw=u^Wf?=vQlf?9(0~+|F!GUDgHkPbkYi2l)GL(cZ-RMnPHgBw%mXIvD2r!#dM=C zY{?AXmUp+SBULs&?)jyq-ZeiSwuh_=>D>SS-)z(DYa7bn$K9)V+$*#B7-Zh>&66;E_WR5oeXl;N71zxqc5G3a`pf>6W`JL1aNR?3vrQ9Kbr!0qf*NT5 zJ@zC&yRu$0L^`88S@Y@nle6!n2u=RcwO-@kX4%O{Jd8a97tLy}n%KQ$!lBoD*3DSv zwm9)n3+I`+*3;+L{pwuiJ6lLlaN&%)xMK+hAD&K+|Mcy4{^d=n-eqrYG_GEq?Kk_Y zQ_Ssz1GgNVPacab4yb=#e(%ZI_`Et0I#a`Fs*O^&kyvV6sdQp?_9sAXOH=Zc4 zZJd2K=FudrUpqym)p<+zZ&vIe|uYe%S7Sr zzZnvlYDwEa1*)yvajCCNCu!oNTa^=KiUS_6n{8>M)p@Emr*iGiPhVA?IUaiNOObh; z;T3%JtL_v3K3@;F_z35#|6ZxM{pwn;;Uw5*@MLH1`}wBLY%!}>JYF#GnTb_N$dW~m zZvFlB_3?>`%6IlwPY3m!A~&b)y_A~K)YP;hb~k8|2dG=c!ore}KfhebYF)0ugNvuE zykBor?o^p@K*qc83y1afEgo~%sCa!kVtn6f1!xLv%C#cTr3TxkZ8;)aUiZ8_^h>ev zyR&OPW+a|{xPFp>nwItH<&KAa(u%r*&!lZzbgQzljaOPoLgK{9$?6|Je@=dIpix9W zZVn?eTfu_^jdRS-A2Qxi|KG0o`MITTy;3F_7aBS`IK=c~PW=4*{O5uX^!ZwdjbW>C!{-^HmJ+*Dq)Xpw|L0z+M0orqRQ$K&JumzVpW zv&zu-zEf)a{oITXS+loJZ*kQ*Bv*ZF@@D0S+gMF9wxnnVPO^S?=RsRj*i$8wfPJ%h z!>>yi9MP87TIuSYU$wczRU#mLZFb(WbK9$e9=8bFYuoP*pLvQWkwaPXq;8((y7}TO z!q!R^KRfgA)KqOAS*s~~tG|QFgjJ!dk6l?A%*oAtI#XDep|G%UP0Y?o+j4I|diLzt zhlht(hOQQKbaZ54XTQ8T{d~-9iw!a2(s}X*lM14LI(`@1vcTeKWRGgUd!NOM>5ly?|76Tns5zEyvdr-PhjZLt zD=W_SY@S{<{e`BVrqsRJf_!{@J~NG4A0O{e&d>M1yQ?(w_BP#v2M?}#XTE%A^>@9) z?flD2US7(%wWU+ld)kKL=YFTA>(9TuY_Cc9wPlO+S1pXVyJoM>pM&yW7O+=MIe+D! zQO24B$1Jm#rg;T+aeT^uQFXICSD^UTnVnK!7Rz6B**r5`|MB*H9c=U0zp?mU&2@44 z6#k>Khb6dzCM5C%$5`tJE^^^?>ytTov|HS=;)BAzefxZ77%=MV>+jjSSJJvnr~d!n z?WudS%!*!L(|vYkrt|8swHiT7IPUH)Kb~N)q2gmw-u-=N=U5i62v+~B`hFAlck{Iy z3ojPr?)~)LU3*Q%^m5(T0Vf&Rzy1ni7H1AxX&$)#)amar&o(uQ>ZEEO)m#T^WqbZ8 zV-8eQ%UWfyn192Jqb$N_&j0yysP@si*@d41-V50tmRuDSYWlZ6XsMUzw|93>Pt%Rw zQT<(SYxebLZ@1r1`~2+ePpvQC|NQ(6TGD-KsW+(7-1qlew3D;*%WG?+{bow*KvFcM2@M(#6jIL!SS;(a1OFv5feR1zmMTVgZF9royi_aB8y-6|DQf;8o|vFmnYH%i{+;EwT;7BhPuu)mFGca{3OC;@t(3@X z8%`(bhLqniOnSmsF0w_dJaFM|UVgn9JE~)3)%WPv-aK{fkF?fb9g~3arg<~G)%5g2 z|EX@5eVgIP&1NiN{4<@wVD*g~H!kd{EUx?eHGEzCem@Tn4p8ZQYO401`~UySzkBy? zihlgOe}8`q3kV!&Rm0{H_7dN*}nU~evdZk+D&zA=ce1)zK1LY#C(pMV_AG(=T|K9W#F;IpM_L z&uV{|WiQ^;-o5Tz&&)Iv?6mbz(XUE$e)qepsRMXS?OYAh*i)0HQ=i8o=ptKG z?-7-D^NQI#Cebx3>_dOv>QG;LRJKUMbTRp{vF0?Ce6; z$IZR8)cg6ZuM=+`eS3SmW$`nf<9)Kq78WxeJV?m9v!l^%@xq#)pG@-Z%sAF7eR+we z@SQtxZ}zIM-}r8=Mc40FD~$bq{!X_4RXFSNdY_vscr2#n^1YgRb)}5VJeTgLd^@g& z{W~=8TuGbJl*2N|*yX`ByU)o(x0ZdJQWfleH-GB>lShQSB~N`2lsBCBQU8v<+LbfE zo)vE4E?JVm`ZT??eADFZ72UhlqPJ*nuXKdQ{`6wA)Iy1Xl#^~z(21eVeunkRqB|$fK z-8sB8b)}5#e4ppeeqGl!*(DAMT-(@pI>v4G=hT~^yHPft9Xnwu}r-BA4eT%w88#;sdHi@HHAr&Ck4gLf9CYK5$5 zXm4jfckbu&YCm7!r^kAwV|Es`Zcaa6^zTpQxw+QIcNRad`0#*{;oZA;FVFp6{9jBX zK%rgtyqw>8uZM5;i0qOnbz8h4dh^V)TbAlx-`QvV?o`)v-c83HeY=FNZSPoI!Y-ZF zA6S?6Su4D<*<9jOz%iq+!dmX1(=YE|TJY++$i17dTlRH)(oaa1ILwn)Fm<)ak_X)1 zcW*s^qA!kfPx&p$Z1<;cqYf~!8PBMABzpav*2=(GK^!xK&$ia_5H+1y0V+J1aga)&Ku%uBfOu$GV(v^2wIv%hmJu zeib{~Rhs_ihnt1v!8bQQ+^g=IIU#$8a7s$_c9uWety5R}l{!lW^(6f{IiD+Px~Y?z zYVq$06V0S$jMoNEn#7Z;G5_<d9J-% zN4;itqpiH^rKFk8(}XAfoy~5uK<4QS|9Ul}z`(cR6OSA@a(vDf_xah^*CiS)ZLQk1 zYuBTP4;yz^OL|Q&JAU~xv$?r>m$<&)L?zct_LjaiH8$n%?kH+$b?q*HU-bK1u9A`x z2RFC(|2z9?r8nPXlW@4W2vq60YK5+HnW`1KB4njd=<2YuqQ@r%AGvR^c~_uJzHZS1 z7w6RVcSV9UyaLsXCiee~2z+bf^vz;LR@=8(1{Wu^sZ2Z~*q7k@Zsqh8#q!Bg+G{dp z+>geYh5YyV**H04k*05^o6)DGr)6W~rg~kte)5aO`g0j?B#v#Eb#>0uHCn&Cgrucs z+cn7w2|0Oqa3m($3Pf_oEDBi}v}5<~<@P_iMYY=|PZrkG)63Wz_2$i+3$MRQ^twHI z^oXJ2#|K4DPEHqhcVS6M*N_mE@^^P0-rAbIWZAN{oW-T3M{nP@zN@(|bhX&LdGi<~ zcpkjs`uP9rd+SoK;t+1pQ;qr_s(k%EO24LbZkuiN{z$8k7pvBWnP;~wn%ZPJl^JGisb2#i|4uD zyqfJ$({iC~vvO2xdeSoExes}s>!fRXN2VUtWtcE$&Y7#L!!OJ3)(+3xR8yJ$fJfj_zu|<=*vime$sfU%cp;JXx5POXR@8gN*L(?lQ8M*KKEFJi zdLzLlqT#SIXz7P9Uwr<9+6@mJL+$=?la9fS>pZKsoFK_n(~Yn zTlJ0zc`Gz_Wj|-^TPf#KpX#e+UM7{X@r+~PbCFA%zR5k7P;7~q6U?oDbY*<-g$T!~ z|AUwFy>L-`)WF;<@#RwO6gjhEue|^=i|uUA_8srCDV3;oJF#XPG9L9QyTjL$$e149DABsi&_m(n?c~ z;Wr8RdU#E&G`_%dF%#tT^(u^lf+^N;2XrGv#K3(qB>=_(y zZ#xGGv9N_L_nRv><80cydwXa9+gba&?AL$$B8A6~9)WY4rJ%TgA?b^4EDm7Jm<*co(*Q{MzSW>bi;b4=6mDQt1kDOKpEiEW3TNbd; zNklhlijr&BgJ;j$X3v&(?Gib7?c2-ev1_9;n>Uzd9hhI=w0`}n`1E;)Hg7dup1w4o ze2?7PLwYBo_Z&@No9xt;_4QS;=^`af!?ehEvf7TxLZKJ?r)6lWw5H7933k2j^iS3B zln$e4^3yx-Pp*35?$PqXRo^%@ZP_pRzh<6h`-PWp2>rjf(_|u}k%MWi>B?~bC9d7+ z+kgJ67W6+aemVQ9*OIDI!O1V5zKPfs;<8$_am)F||KDG9R`J_wAG=LppK+*I4?q3)v71~KExOaB>J7v^fezMv**lFnKoZO-k+^=EB+zix^%Su}BRQAlAf_kU%(xFwmv6Ps9F z`(%Ut${#og#>YSXV&t5&#-p82$!hM2C7zbq-g!#@mU)6)azw8A(XB)wHI7Z;-?Y}v zWw%(B71s3FUUl)srtjjfQm)9J3i$Fu@~}kc7u_fE=g#;ZJjQvdd~=}df9ZV-HC$i1 z@AvuY-(|K~f6=|CmD6{NsJ=h?YE2}wqoYCMq0P5r_i`=u-aq46zx|<^#sUH#ineXZ z18)8wB=V-Olbad zP~In5s&B<+vtv&GRGu~#WJYR*+HW~}%I{~f@st3ujU9zOr%NK-F2x3_W?oi)SJ?0L zWG(AtHDT}}4|1VfzdkJYs^V`H5fa)}GC@yvq8`VKP!|yqLDsKTe?xXGSQH^3-4P=w za+FDnLt`)ZrQITmjtVMECNgj?@x6Or{F*b%HpRvx4PVz*Y9C^ef{vUUL%hGpZ(pdpH?JQS5Me;uq7Zd z<;&eWZ}|eIrd`i&Z85tNSl#hSQj1&cm|>sXmlYR;{^wnJ_#%f{Zr`g^|MHBL)hHNQWl$z8rCz-&Gn?=DLR zR!JXj#?5JtmzNcMNVxgNYSI;5wKG4Pr1s`a*YHrEE4n7ZWU=TMAImPcWfFQfy;NTH``9;7C9eQzC`)& zi{svVT10Pav)_q1ztr2Pc-Azw{r~xTr8KkuKk@vTQ`E+=wIlCt!hJgqzP7Tr2_KW( ztDi(9RaGSHP&r|<;?J>5cki5)`&KaXbl2^&vJlPye|_V^y7e>5f@?0UC}{cr(Y~*E zj{nb)%Ex(HCT-qLKi>D6NWE>n=l+x71B?2P&iNJ1<`)uoFX+&WU-3xZL9SB5U`I$p zRD?$JiNM7vKXW{1_)M4+^NUBz;p!@bI-5P;=l#jalr(Ti^T}^Ls#JdU_Lhm;PN%=x zQmeAgC~)mmx%&mT^Y6ufU~ObEnsJb;YMIQuMky1k-^ME(mTG=pYkOpJ@oZm_lvTw- z{HYrDADG2LJe+q3qh`@iSG51Xgn`uCp3_7$|a>IB^>OMUXEQu9XnKbxF;Jf$HT zVwNQwU#c?hL{#4XCLqkb|1X=e`=R~+R9Cn9ym}LFY3o?Jh2>bL=e-3r4Y%gLi`ekN zdcStw?VEu%H73uwzwHnAxXW(KnZ0b!qx-3P#;uw*r#D|&JnzxByCFG!wTTX|Ils2A zoNPPyRLHBK>54oXPxo2IFZdp;?y&a&E5mfI0Q=yRh!>>*}z%6IVao`!`4b{nn(X-uqHmls~x1{$;Gbm~l|s zBRQPSv`eGpg;wh%eTSTUTe&(ZKmFi^f}#~I?jFj$x;qL!Z)5u5nwj}$ig>%dX+S~T z&9e<^CJz(ko`uF8by4kA6H&62-BmtaSLXJ%sedbjqxfVeO&+JuFS2G-#w{7$-ynU|k5#y_imTYHOo2=u5o@f1P;5SH2 zI(J;L7q%9FNjPNV`(=-kPKeE!k-y|)hJL7tpT#2!>J zX8G~?%;oz3&)miR{=dJ={ZG$NjWwvK@?z}x`8o0bzf1M+{{4QM-tD}6vg*EezLOW3 z&-DpC-J2cht<-6A?lD)@GMl)C-&j{veQ^;8%rshImCsxF*XBp|Myp0&*;f}PP18wP zsP!$j^VnkBk35$OUL-$doqX?!uaM^x>3xBB%2E|AC9O&)NiUpjKKR+^7kL*9=3co;J=;j(Xi9u z!9phi-U;1v7C+N^l=ObTzBtqW@AXTo|E~<*WWKD$aM|`J2iX_a{=Ov7{or2p!3yUf z&*hVEUNTHhcz$lv*TYtmj)bbM+PY=^o^rn87hd5~mjWEmPdRSwl0CgkKV)9y3fC)g zk37qoTDje?Xdae56(F`*f?02w&N2h5eBSbXPtKm4-xFi8>P>m<sGKIk_MKO)amxk9RsXa9uji%${QHJza0p(xpa%_q_VkC$tsMo_ha4ws-Wm zjq5LMwbzhZAU8MH;WcAh)@R zTiM%n-_IU)*80=d?(EU=CqMi^QcJP)*(0|C@6C3T(vEz&<&nqrN2041Ug+b|@>sa! z)FemN71x5?19Elib;Hy*NS+E7#W5@VL*vIj@DyUpqgRcEj`>ACL#_q`{+H6KIo?3>-?dx&Z0f?badOU?Z4o+UGJ zhAdfg@l*LHhvh+kUU)ISlFoNpN#*wLkY`KsOcPHDgM1yW(r41)$W^tB@1CL*Pg#dbBTs;KFq`Ot zZwdbAbj%Y&7hW>&(y+RCGWHqwf=09TKPT)vy`~~RT4y6qx<&ryvZWG}m#}>NxM_{K ziHKQF!v=$|{godU)GXWK1@^FSNV@II-MSH6Q{T&eKfM0Z)Sp^n3*`Q75jgMAoAt;z z{{vg;%G1d<%erdKMa5T3_MJBmdY|ZT^JnUPo0E#|H_tp{jXS{3D&-y;R;9}o@b>JN zRcB`!2UR3~O3^e5iSnDjEq+7NEfdK(`@V*~yl0=#5E3=VPBv`Kgzo9-^Cm75RCaT4 zY^?n^g}qbzzux=a4R1Fl96e?8%y7~~KkdE}U9XgY#hvRyBtsganr#eHxP$7$!BJfI zG`#3UASjBz`pFj7+TO5U8t{>~F}!kW@tnue`$Df3us-=wIMcGXdvfaDZCm$NpA$QMwq%#I&pvf>W_*uGT4d8F~_Xw7yL})**QJ{(lSO z$!aHA51yEq`g@KLW7gIzgH*1XKO1A_-07QVn|NKX;@!^rDOILYk_qW4Q~YXgOwNE!UrqUGcYv9LW&ek6t#7ft)7Do^ zo}Z`s&pP#YQF7-~LAk>8!2H7pn=kA%zOt5kb@*wcYoC(7=Vjd9_NQ;TiJ{@9*kzk~ z7Jcl!AQTh6I%?*6Ylp3khd1;5aLZWvS-+I2A=5{>P2%6t{h*RN>GN|N<-)(VAG$;8 zH1h3!o=H(V|53(~MKdp+mq%jGzCGVRB>s5FUhzA3=1d*k$jE}9n~Wy?_qW&eUVW@* z=ifg;_VyVUA3eJtzFx2Sj->IEGZyKpU(0`=u6}ONo>#J%kyqr4kL@03Q<1nW{wkVn z5;_qc%D#&0W144uubQ;wUXNw`&!T<-rx&jJsf!DfBX$ODn>|I`=>$*8Y_q53KBg;j7H2H7s-CdP^(VttO<&7% zAHBBDO!?lm_e0ZzD?-A(Zq*C7*5(#_8=Xk7`&>D5`o+bE81IB+1Z|(W^T+a5x5ZaD zPdqc4Uh}E4?|I0^^=xiE6%X#5vVDB~@Z9o46O8&M>q;3WulBgKHDjwm_Ov;L-w*R| zyIuLlP{PFHol^YHr2X+(1!YS+SC!w20~J)OBc2L9@^Gza&DtojLHk6P+qvm0a#Hsd z{TGjl_nvOir^l0b7~S4} z+H!gBtrKTf)?0Sp`~OuuX2*kDl2@`<>MYJsvVL*WE_30BrcJXwdox-XnU`CxT@jmp z>>b0`Bj#*h?gdm&u;RYQ|8s%^)7`zx^Ku^Dh+&>s{*p6yNsZ-dQElUyCq3MR+$=TJ zG+Nkro!+{ITmSf5zEh#%``!9esotko1{*z=5?XPjf6C7{-a3^&|D@d& z@%WHq`l=fx6f2u&T3DZ|er|L<^~l7o4=c6&*ERXvUf-&*=)&UlC5)@eSG1kj{bkO- z(79E68F>y!=Zgh%N?rGAY@gruOuwS|ku>v7^{Kon>IRJ!k0Ot1xxU?HwEsU}?XMG; z?k)8`c$-o8>+bT?KX09#HTD0-tBZ_!7IEgUbza=sV|yy^p6L?Bs4X&&XDlk4E4iB~ zq_{EU-QLHB{-JJ3PbM6edGFVJkG^g)#=(L*0ZmO+{V7bs>DSg@a2>m#w@-M3Qx_2+j5?o@2>fn zs=$0Vb>H=X@A30ku3s!nn6)W6UFt%E-Is^9S_xYcKuyuw-=`Q#PYOjYdd2bW%|ynz zi~H7#iPnnrw(oDd&}Ma%IV8TOQ~8|if@#x&?PnW2=X}K<{G998obwkK6iR-SG(UHA z<4(7xtgMyyT<2c;AbDnie(g&CTGzK?oV_!-ubeEhDsI@7Bl+fzX0uatfRn;YHz((Z zbITK+`TTgyfBP+ujE4NN#cl_WcAxs0uAd%0YsIyo^y2<+Sz(i1g#14(IW%u&cliu4 zlYkki@orkPUU*3^IQH$E!{W;mw)oA}dA0wCxb;m>t(B{8l$)AZWqgg#pJYDc#EsQ& z{{9w?OO(ES!;y9EZXMOt;inI5sjvU>ulo484P~W`OD3&&u{h(ICil{_l5gy}^9DwLbq}_S$@8*^;CAeB(Vo zgOw_2=cepkd){vKocwPIrjDP~j0?6Ja?~^-w)r$P0Gk@%` zx_SBP8nuZo<=?LK`l{%dEc$*KlxI&}lK*VTo8iEpv%*=IwJN_?i)*HW@d~C!)~Dq^ z-aMS0|KJGcZ?8=M`E9dIr+!|^u~zKgcY8~(w0AML-?p?Im}9vip)p3la@LjHw4Uj# z8*6j81A;vYEen@qf8@IykdfXH6=}Re;dIUA@|ka6J>DyNui|odoKEV>N84g&f-0EO z8;dHQ{ZfrfvOI0+r}-=^)Idyk(!rOD`%nGe9QM>~_U*zK0unr;=FL^QqJ<*971BF* z7uN0HG?lNsfL-14jd)vz1>ZyUo1>Prz4b}m=eBr`^{*qs7Y-cLRAp-p;RsP~ z<_Ze^(JKC6>GTJ4WIuY`-?!Byb8jrZK0A8D0_O=*@mlKz-EwsuSgZG>< z@3Y|2RFM_`S9GeucY0FYuBlho<1bj`!ed0|IEZNp1!!apU$UfC`=_w%Ra z{KviK{U18CzA=8;_bN4@yCsK5!+O&JxwNxQTTCJ!WovhKZt{tEDR(8i@-gp^vH>g3T=weO?0^rY(C|G+C=xJa#1^yj~7 z%YRQ=#Zy{+B10cv1+^dU-m3hgso%!G-U5_UU!AzIHb+RI&w@e7Gvvy;%}K!xzpf_< z&uf%Qs#TkXBimIzG-uE@{fnhcl=ed z`C~F8ge#!CYS;P)GR~I8#Y;6VeLjENTy9wg+bSv5eXc)#oDjM{RePz>!nGkQndEC# z%HP!gkG1@N%ITUSH|uj&!|yk)<$M*kFKp!2i@wJlbTYh?XO(F7Qqj*VEe}lo%&zlf znTEZ)afiaL%Xed+RWmc1Zn;u>VzT`*X%W%O)pL%2JkY%UhnL~(bEoE5Zd&sF|3Cg^ zmXWXDzTfY>+^_H3A;XXtfF_W_GU?I}1J6&DlC>-({b_?pIE}&`A=^T(a_>^jpz22Ui^W!8W1WZbI^$ zIgOc@Q##+D*1w(p{EVdJ4_0>V$Jf`sxE1>CbdNOq^fxPPWXyPeeVx2Cwe^%=pN6RC zYhRWlS)A+AZ}&WiJdWase1o-j|4w$T|9|RMyVOhG2vt=MW&%r}O}tqy3rI6rhPWxjGcChTZkoH}~5y%{}*T!LQ5yshOXn^EDrbM|#BND;+!b=^nF8g7|KU(-EzE zwc@8}eC$;bvi;?CyM5Kw({WceXJ6$EU^fzAX1lgIPW1P>u5wXc-uWM%yvSj0^FC#( zJ@0AcB+oR<)1sSS`qX@2wE5g~#irt|se5&?arE|6^UhpbEBm%Hx$tYCiCw5E%hfBB z);Z05A9+qI>vE)Kal^0cO2VPDUU1|l++O$lZNv$uTNnFwT?qwc+3uwQ1+UVTzqVH{ z3Vis*=8$07rpf6QZk3PCAH=#kKWy!q?>N_p_0QjjJDM`OYq1B^Eqy!|MCd z?R_3f+PQ3^3fs2NJHssY$#{zXXI}L=-?o%b|0(ADc=?_Sl?NxDpK@7vg|lqc<=HdO zgq&Hn`NO^HqTs?`CC9)0pMK=p+M*|2+qW;aE#!--6!G19?bE&$D(@J+ip}`Untpx8 zir)=ZkBnPIKsR=!t^oDab3pyZQ^Kn{%g?6jZC&9SzH3#||EN7qCK7s@`)@FRI4-Xn z)t(+8ESxHTA$xt}`t^UmO`4Q)AUw|I1H+wi`5w94_@5VVZ2WZa_m9Ux7AtK$qOuQZ zyEt#PJ}tK(ZQ{}XKPy&sl~z8KRr|ZW+<1ji|18FiS2|Z~CSPA!%*3B0u>Vu`QjtYk zoO{=|sU`2V{Mg&LC*)$<}9-kIXetqp!?7e82 zbyi(!Yi9PXIV|RSb=zT1^=6)@JXVIOTmk2E&5{i{l76oYzPEeM(XP$5HRQxQf$Oqf|##Ed%tr;JW-+w51B|LsA<5OXOjbwez zlXeqTqi2|Ue_QA`Gif*P+Ay!z^DPvYemmX#tHfuii9`KjHN5S)Niy04TMdKKfW}6JPX-{~N4sUUt=aWHh~U zihJnBdgXfyrFblv7WxTI)e2GU)+z0o-lXiFaF9vzMy1Av`>94J+p8rJheXC89S3kW^BYtM&uO7e}ZWm-So zgkx7Shcw){C%5Fi(dtXq^6oNcGvDcb)@57EZc=}6cCdGE%KVULjSF2*Kejm+Uh_2M z@rhGi0!1xnuBc=q{6~SG=?T zcZW)l=x_5!!M@EK92}Qf31+bf^63iCG+>-%GBI_N*Mvz*=?kWnH*jq_vOU>d!jOrl zY|T?OpN1V4slN)nl`5M#*Dh~c(U-bEtnQ)sxuR*yE4*0GpOT*|Ucr{}=G=m?Z$j}6 zFWyycsj947c~F6EV^8YTq{Of=P|JVGygp}nZFTm47X6cb%}z%wn{oD&3rD5?TvP74 zKY@Ky3d`#L$Fjx#``7pF$j;1rFVE4U!biLR06x(+1j28WU^r84V*Tv0yL`scTJZ!PnahPl3 zY1dNyE#zEU&?KG@hYnBO94Yqb(UTudnU_--^0en#on(Joe17HU4W`ezFKwHhtM%UY zT%px~v^^ZPyue zEz9DToi3zPrg=2p+jJG4RlR~xLZ%s<&&3@r-ANpqZ${TZj-E?^pTlFV- z%6%Kdq$k$H>7xrT4w}b!uWLHhbN!Kq>W=vOsaZ8%{OM>Fe%`vbWp;lA^x~&IPM@Ndx>|BI=c3(H|Hj!(o_S@N+4q9}PkojG?+tia zXMUUhgK6r%Gv?3a_*)u^XI}~Y{MOUIydjE7H~ynq>FSwZ=ANqgU;ENqW#XCieM;Z1 z9Ls4tE;o6xN7$MMM!k>;+e=sT?64{+*rL9!-MAkVmCg|l4h5!eTEWP|P|&K~b)z`V zYwMiTHX5z`NmZ+a7raZif4O8gbBKBBu>#M6yv?1roUaJF|C%{}=Mhym11Hhnst?7N zhUzxI>JW-w9oogfE6Mcswsy9)nzje2MO-gk7ilC){xq-p}X&4lu^FMUi}jyF`in# zf35SFW5BPzCOvFM&{~sA+oC^oUlI!O-uvlZ#-dCoVNg`>m=l%d@_M1-w&_-TFUEgT zt$pcTx@vXOew9CqO`j}XalLt#uUV@`IA59dzTbR(a;@g~L++JTo_E+Q8W>o_@#oCU z4V9bUmL2PBb?bfba{1C5?Yc1*Nr}gQFo|v5f9TS?oo}j_PuL=xw(9l-+quVW)J(k*U5cx=$=-(CiqU7>%ynn_fllH z736(B8+qlLb zr&PqZpjP(e>$86h4<9(D{^{q&tD<#T#WSCjruHu=eevPYY1sv06SrOVc@q1Ig@Ivp zgsc6poqsNrn?F6ja=!1CJ=YJb9h`o9qLio=@B%Lv){yz2PvYeQ%?FAqGxwp2j2(J1kdtcB)q4wqKuD`bhBfO74b-DP}{(jR`?am!apYQ0%2wG?Rd3OuT&kZu>es$v87nf#B zKH2wy>B)@+8t)}nI4=I1{`lCh?`dm~YIxjDOS>P5nw~L*ZoyD_j#c7T-zcF?`1$8fg@}w6pIC@2f8hzb)j?j%XI0+U63@@UG_O>^J*$ z=KMK%;@`?votKkNpOo*7I9u?uf`mUYD`I6Teb&1zw>9_`^pLI z9}jtp{@$*1%&Z5v4&b+Eq6q-({I-EV*T7G|O<4h^XCriDJf+eL_@5zl`85Nr5 zu>XfsU+>RX+CLBU^iOy4(+-<*?p*bI&xify_cV6%&uf&*6RqUZjyPN2zx>Dc@Xp6G z?VdQZ8BMU>vG|SO4u*S)pA0MBIvo;Q)UoP|);`xGUp_pz<94~U+i>X%XL+NOPZ-#z zn8!JO=)MrJbYb7!^`al1PiNC%`}qCqx`&@;ZVG?OlPt0G$)-tDwJM^Gw8IYk{eIea zfA-0f6TLnh?>l+#aM;>YcTJB*>=xTqHdS?1-ju~_7H9a)*|2x%GLHQoy1w&2GW9NV ziI(DJIdUWH=kxyk*3DcK_MP@gm?O4dqx6^m_Km&2uI$&E`{tN$ra+iSOy;6%4*a2M z^Zy-`mw9GzSYp|pk3m8q-rQ0rESLH%Q|Q}K#2H}!gMo`X@lQqR8|xyrEKeR84c3M8 zs{PWOxVire=4!m1bNNDmORt!e{ae?qLS_};HnhvWdEgqS zbNgT{$9#iI=8ffISt=9XF?`KWs(PV$LMX;!QBAi~@GK$cp514*ORQ1zh{#AOJgyz{ z<8sqg74t=17hY+EM*i=05%LV*wW-6EtE#%X<%fGg-kXRYpS*v*zj_ zt-SQ%$Kwl&SocI6lelOc(5&(9ieOPsU_h+w+4{@FWc279L@?0S9GiD$aY#_Riz>g3$}Aah6{Y{Q}$ zV{`4W0}l^>x~JJ9^VGC@+nG7bmY$UR>(+bftZe9wt=?(P)!)musEf{?kW;2-;}bi$UAjrrl^|J ztJfUsme=HO5!L37JWKc+O5yJ}R%i(k+Vfh^!*e44erdy*Pu5jtUdURymsdI=RZ{ECo~FFO zq$Lw~pNh5n=oo$I-?>b`&)oYz80k;{w?MDsTy*ojaA(J5e^vLX`J_x-Iw5_XZ%MiB zbF)>~+h56<7u(AHlj0Fy+cD`C7i-G#+hz0k(+t>n)}*fOm76yAdfeouLRSvP^ES%w ze@1U}m}~X)Sy$GYSnk5YfbHuR+phd^Crjk)Y5mh@Qxum>c(@{vOXhVR|Elt9i@#pD zb0u@})ze~n(S=`jZP}yoQF_;p<)W)4SDA&oD`d+5)>v{ucEK)9;X_QGt9_4r4Og$; zHS_G8$8(%dS9f!)TC4hdi4|j(ZdPGe@TwbZJ3D6BMsq2%vaBeRSU#gM>PRbh!S}l# z-q)W#aHXjG$@Vz?^siH=eS4d_^Fz1(w7PAx-#G4->}8Ac{j&4zvvch=9=urw9ga)O zueb&#iDiidGQ2aozrS|NB?U|9!{tvv(YN=gHmqyjH$yef^c)-OA=y zvx4&rEFP9DQSOec`E9O!;M3EB7Z=Wc4^T`=J@@YJ(?@Nu*2KO(H*cD{>*9=kKbW4K znRqDb^78-1^Je;NsQUUkQWO3cUX=zWOr% zT>|?=m!R3VKqG;Mp0_iXDR{3CTTplY`<7)}gF6njm|ZA*+2Sg?aiaB(X6_h;$v#he zmCN@pUNq%quMTIrl%cSYQmCq}O^QI3wvSrGt}QuDJeQX_CM^<)*Wx|Ox*}??$e!#E zE7CjX?>*uA%y|C)5Ar1|Haoub`4MvUhAp@0B##5K3&aF3#`U+)Z!4aCMbiB8yl?M} z?n`%MEMNY;zwSkiNygWs`2mr=O?ymkpZofI=lrKS`r@Ydr8h6XuEfG49k$KaE?q^N z``i2S@AIvij?1^Ra(BIVznYbJMq)?B#eK;vN3t?4PH~^*&1PI3D3I~EL$V+}fN@8` z6{o4ktU_Hf82Abr!gg%wSn0^icGUcqDQ&xZy&ZmCw#Y%NSp8 zU(CqMU~#VSXs*01*Zq3_{QbQ1RF6BAJ@#Q-6{cMs@$ZN8x$3=FnYa~-Ey=f_oARvKZ!0Z{w5yb?4i>f12|jwN5{r#xUL7E-`Ai>m(-5Bl7i^Jc3VX zUw3=W7&!N#IXu^}oo^rV%z-=g*L`tv34?y|f!`ILL!IuZX(5qbACwnaTnY54!= z_`k;{)z`S!C+N{lC=W3$7peHt#buVZ1kdht^J zO8I>cZ_REBS$l6=azzUY08xY#q+3%iGU!DRFkq`^g*0 zGvV{}D#lfe%$zDaKpi5b($$jA+Z5KVw_<#yBzAG`yB6VfU4J(%`g~0wB6zh|16RQO zUtQ?|i^#e4Ct z?S`l)wb7YT7n%f|Zk$Ownj6mYXYtlAv9J6S=Dhn=6yKY>IIZi2yM0)|DaUhW1-sv5 z2L3+M%zx_B8U6hs|1B4@Ih}ZLJoaAnznVWA-x%(lJFhuRJ9>)OthrHAS-f8syqf!K z_0oO!7H;dG!6>=l*Q4zD!FmUD^qMO06yw6%S0rMbR^ISxnGa|Y;MP{Zsrz2k ze2P4q)n?#Qc>9~ct$^iG4YwNDy4Y7dKJI+H@2T>i36qq>jm}9d5WBc-t&H0LFPDQB zytsAr%EiS6?_zGgvHdD?Wp((jotxz9jJjXNx_aL>_mXP&f@ux@GurIB|E{>?QXOh>GHcRF_UM=H_LDpwNgNmX z^rNiwsJ4m}$$wv&bU(~V`jy4Mt%0Jqc{3KgV9I~$_2aGijeW6( zlU0LEn6J)c4q=d&|M5il#dZER{^`Z|HFe_LxxR66a&C)j*q+9mR9ulS z@c!8T(;v1xeDQDHQC?2YgV(Q5*9u)FASKncPi5+k=nX|rzt;YAon5(bp+VW2H}BVL zJl)_u?ZihT-6)G&lTWq!sfX6s|BDDS*Nsv+I%(6Ul-s=@+m=qdsdL{tr9(zGU3(#K z=@sc$o`1f(*(~Pj?6-H%%hTJrbLWhIeotqeO`_x*$k0yeg` zni)Y2+Z?#<%w?B3Efm}?F>7nNm*PzJvtMEt`SD-k-gBUA+vav#P!0Fd<91%!UFAxi zdqN9N9Xsi40FwMHM z;K4p7y{$WsZ2moeY1P+PpgoE^cI;T)eWB~r&%a_}_vdGSH~pq4Z#4I%%H%Z*%GaGe zYOkyFe!BPn_`jm-PgtD_oOPka_RT`mwW3>NFK(EX@cQ%5IkCA;i(A{c{fe~=8#kw) zpEP4e#n<$(Ffnnxm;*(trJ@_&9q`n6X~NINwJ7WAD$sVq8#f}duC4KmiIFkQzP7}3 zvRaGS(hchtrg~dc1l&8VE4CtD{@?F-39Btne5Pv`9hbeZ-@fKU<6_&wKUn1qFF{dq2Lk z)LWuB!Ru=5no~2+otpD#!Z#%xd`fP1uGiSvLjYW$Vt%%!eHE|+nlUKlU zKiO5`>+^1JlsSDbIY! z^b_aKscCC>KY5Z8ROfT>!^Xzvljp0On~O8(>+8R|y4wBkudgfP_uKi-Hd~r{dfJtB zv4zK)f3}>gThQdwnBVfYY!SHE;r3q2N&3YH-s_V#9bHq=aI3@3Mc|;C*-qvw(G#Xm zKR(a4`o`95@pgTgg}e62`=0qLdE;fG(HiyjY!eC#3%6ul?OGMO8nn?Ebd736gv7yv z2U%EHV$OE3v9ZP7-EivU$%DVPI|cgr@$KBXGiFD@!&mb^KR;jm?vAC9u<*^@<@)L8 z<}BQ>L7?H))zzRarn5}5-9QJ#O6)3r;2_EnwSAgX_1|BGlYeEpK6nw>(Lep~<~*7H zFzwrutjb#Y?V5aNFZprp(b1r@;T#r)POq|hBqyId*vt;PB9@br6Lgc}j~^9AMn()5 zGE7?9+l3`1D@!MDFMfWmrL9d!M5N{XMxSG0(g$zbx(NsfH1zlL-@A7&++JGdkN+YC zdwcojgA5HvlOBG0dRjzGY|`Y(&Sk4}ei~cP?iSadG;yM1R+d)v_jjo`H>ECFx-@oe z73dnU5>Mf%Eg6n)Z*9G3_3_cmX_8k`zsD%9ThD$ren;*7NxD}S z@+nK6bWvLc8uNer+%J5E?TO}R{{#Qci8&SY?s?rLPqi+Mqi=7Y{tI;arp=o@Jv<&9 z=@dS4{J5~Z{P~ZMk9&G}9LO;f77}tgJxw?B>MGIlyQSiDt;^L;xW0aW=4aD;>DXuQ zD(hUzH-F@2u6u00>te6TrH%uA9^0EX{(Z`%H-F=W^ogHDBb_Brsp@TPGwr%v=KAUL z=bJkUm1mpfCjI{Q7Iba)=9{2>$)MApe5K46CZ1xx@}qD%|NkSrxl+5XuCnCSmS#ogMK3Nd?_Zr(mv?%0{-OW>*jKJxw{>UK z%^ejVx&Hr-x9JvtZBh1yPe)AFX$!+Y6)US**6(&a&Uz5OzpfUPPkNf-2v#T_FSIJAKp3gll8g|WEYbI3t zt(fMxH9>J^%A<~8&?MFIqsd}L=Oa6Jy3cKYdH#=&yOmXH0hhovC--NLr7e?YUF>m| z*>w8Yo0}8n=p0`#MLjc9;AKmcT|1v_(&J;jIrsL=TpPW;=;6f7)enC0HOu*`S%>$>=WfCCGi+i&czxBvb9 zJ?Mr}pV?--y>8B@r|G`DwpRM??(*f{)Ah{1?y%CXis!A0=LJpdiQToo!}#heXzkM# zA>}sEzL!nhoAXK@v&J3h5cCg`+x2G2k|j$%oYvpJA?YZWS^mAAiy2EIH>Z`nxiL{Z zzGfnytd)SQZ0+52E`1Ign^X3-ks+d&eoKk&Eq?wfV*5LTlP7QA+?FeS-hO}c#l`NI z7rAo(`uh5K10!?B)m5Q8f3Fhro_^@T!FLa?+&ppi?A~8z?rlmvef8|zU8S#$G6JOk z{CTIWkzqJlEmT!U=ghL?jFKtd1zZAxf{rdOEOV{P_r3ex+S&>_^@*9Cui(Q2N6`Jy zZ*FcjlyI<#jTj*E9dt{_}(e{v1_f#@}03a+xOU5PA|S= zu_E%^^pYqklbncs$94EtUp>_)YaOvMiPd|$o~oi^?I7Zee3 zVq5O*8ygat?f-re4qoP?Xl6F8U9PGlaIst9azEMQRypjQokcz8e!sWAC2Y(b7ro#69dw7;yIrr>ebVI=J33+8WtDw>r^S9gUwd?K zj(PMEu||g_T_NDe`E%=g*NvZ9`?R*z3-0IWz0jdDaYIu6{!T95;-D?h~9nIAj z;ckt4;o7LN;pON2eVQ%~4FZyqT-IS+udYo!UM|AUCnIp)?)MrFZf@a*j2jyk{&-*i zU;Ep;yV`5QO5e?2=TKC%X@+U`v=U%vvgXqW#6x;8r?mu+c&H# zWiS`*(tfV<==H3dN~x~RJJ&5*{i$tk$JXrYUGr?Kxq97{rOa|P?0&y7F8uh&)qQv9x*0xd z8;hQLUEE(^zwm07>)TsfkE+kFQTp`h&HlX8-MiljB^}{#uMYfaAl3WmxO~0H-(O#a ztMr^d=a|LY?Nf%dugYL=KG@CyrE?YJ)UieNdV#9_>Q+bjmJlZDe$}E`s zb;Ng zrRu9ID-Zwr`r5MYkA<+B&w{+z?>^5Tad2`zoainGy3tRqr&NDb%gn@jg#k!1T5H*>%O`6 zcNysV@%Q)k3Oa4bx~kPDXM1XfVe-1*H|uy_e69NR?d|DLPfvp!u(#^#uB!Kc|9n1g zD1Mf;FzC|dr3>yWsK@7ps1y|y%`i-6+nRkn?Zt(K5lK8Agl=rlm%qEa{Q2MS_m{i%O4uqe_*{ov&iQbbXIwdXvB&nPS+$cuG2a#)oZHMrE@Fxz@io$;fbBZN$Dp zQ!_~B<<{#83J#I;y_~aF{aLxqBgo5(%ir#&%EpZwLFf5QkFT4#Ws6DOub1joUtTQi zxRsZ>uFZeppaeK@aL=B?*ZbyL%+8)79OKX_GunSFHpE-@!Th7W=RJl$1Z+yqrNh(la+Jc>b?d zH^L`%lv(wJvxxU=&u`3d-)+RcV*Ng@hYvqIncTHISnJZiKE^9t0iQp8nqgCE1iBaC z@v+{TUoV%>u`F);`1rW>-Ut1g7hlbiw5c%IUH10T_WN~*Z{ME1E_Sz3#fJpHc{VQv z=I=SYMI`0c@<-f84!)|PjQv_-Qo1gsmnJWAYLIf~*}CGW*_3D*ORm*dPxVL|XWZJN zx!iw#+S^-OLC5=S%e`%N%XImYsI6I`i&o}X6gFAE-!r-T{od(`hubDjo%%H6dS22= zp%=HsYid9NsH(2s-YKjev^_62Y)!<$D=ULN{ru8yZOP;dU9z_0$B!Q$o=o;H`tl+$ zY<*ns(WHgJ%l&vH3>uP;_ub6he}my_LEwY6Nexwv+#w6QvcBC7k-1bhYvT-sRg0}2 zr%u~^M|IP32F0(X6|EU3ZY=%7v|cyYQ=ySNM&s)5$B!T0&QClg68Y#g$E8aS%bQn) zPTjsY=cduCtE-QHd3m|=@7L>~+_TuNw`e-kN(ayd5Zm)W$9SqKDmEVLmHvGH|G)3A z8a{nGw0sqt^R@$7&!38VF0ppl%X)QpRYBc+$>4Q=XTFkt>A*hy`~o#~^~)=R)#K`Z zrhpPy$d`*xalz~(ex(6Mn{qS`lhm1^@!o26V`71~$!T1#C2(6zPiKE-Vn zaQbjmJRa1^O*=pDtaSb!$C?_O^LD>={{1_3KECWTzf^Bq+}^5#!IOojr|Wf-#!Sl#yUX)IClk5L*B)6uzs~FSwp`1iCmuUx?_2vYJLO%t<*YI> zWkMrs=`*q2MuBs`aA+@iA5u5@t=_vN@!bZG@6>i|PdYtK7u55dGe_pz`}^l#uixLd zJpJjM*IE3a^QLZWO#brnayuv`ZNFb9tvKbrfTni0cyl}Zm)FlT{I%rL&(B+0{{CK% zq;Z?OeC?Fr<$fPQx6f5nS6koO>gB#ZZZD`A9bf;~)O)%f=xXLQk;%6u4o6S>v1+a( z@8NBV+w-)hQ{}?awCAo{u20@~I;VWvbGKCitx;FBLTA38XZzu_ z{)czF`(#b#O=Z7)?YU+dlSJYYvtnL zz_2!Y`?JsI?e(W8|86-s`Q|;N`x=WjBs{cvKDA)A(?i)+ic1>%w!A&XK2i3CgWgV= zrz;+9yP9@yPbKK=QNOuX8?&$LNtx%p$(SB9>%akrXXodi?~ydFc-(7V@nT`S!Au{% zuP=AMPdLDE{Do;qO5Kl#?6XWVor;Q#Zg09HEIr`vooS~#!`98&8nkz_72_+eunV*A zRXnoVedX%z7lu!{jQBP7AINsME-R>Zy~-)Pz?uE{dzR(Pw8R&zi{9RMZmxCk?y_7^ zwba14F7R7yAn0tr{eQnn3#<7&c)5K3v#H^6fwtU_r1j=k{(Sz{+D{}X>{jfvXdCeE z&ES9ku6DSw2tFxF-4|c`RTNYiJU-r^esPiOyCN4>N%OorSHCqbbZ)oO@$mI(%DtU% z!=PPepOaEc!lx%EZT@^X+#_Q-iJ6^m$L}q3dp2w^0OheqN4q08Brw`me|vJM_0raf zj)sh@6r&Z^teEC_R!y2)teoxY*<8`xRmnU;JO`5*! z&3|v*s9P7$EoHjW$}Mh`bwxwXZ_bG+n!$Ho?a{ihH9I_PZPd|QTeBtYYIZoEs@?ya z@6e$I;p>a+OInX4Z8XTaVF0?a8&p#CNE+XHy2tO#1V!f?`)aL086@}iHWf9sX|IaS zSy#9|VwL;%>W+qfkzj*>*7ZMn=BetXt2A(`tO+G7~*+E{PqVe(WjzVQ+_r51L)90uD`}1?v*P6LDl|sF4 z&b!OrcGdp9v$HtEWY+9|pi8@UefOPZ@^abtITnRX4E6Q@XUAR6+S=06a$!xR@x01s zlHcCnkAL&A`}Z4m`I>^uzd?f>9fHao-QA#i>cNAAsO@=YXXo$pEGyeK_kPevn@=Z{ z*F3;T3(}!zSCHJJRo~rQeK2x>)nr{pQmw^`f`E*>(N*_x*Ln+tyq!%X}|+H1OW{iG8xx zn`(X*P1A`yqQ{hjyQa&4G5s7w5Q-|ri{zsu)Ncy@O7^j{WIy=~j?Rjm%Wo>fxv#rOS8lgvp; z_j4z!`QF%DZQj_}_~q5r?lWi3+^+Yyb6_b;_YW(*=oqgJcYaJ#k`ZfXWh!)<695{O zXuPR#q@1_dPw#%4o}cpP$495-mpkkK|Gxj|#6;yq3l=!U?5POUiQgAvl7BBI zWNlPv&h2e$UG~3yxO{${P}JHmPzz#}Z1P#>ok`D^)a-t1BEWm(^`p|?va1%Xk)5W! z?ceWb#TVktI(V5HJ;Y9S-42^{=T1!FaoO??zqwYNlTR+0ad)D!JC_5foqBX%-Mc%M zf^u?tLc+r9fA3v;{oC7jl1Cq&_=qtaWFc)xf7Y!zUG3@ z9E-pgU#m9O{45H6v-&5Gs8h#+1qvI>-`~4kr)O;)trNM)C1iD&Z$(8#$Jf`_xfNS7 zuC19Fu_fbT>HPXvE0?nZvI~zssJTk!0-Plf4oxy?pud?ps^4 zyRWT{?!I&9&ZK+0o-gBBbycIhzf^1MQ^|?Go7P?V{(RY=lQ)u&&C%}&TKGRiA>wq@ zuZOdWswS47TvPPw{i!qslZ+QG>f1JbU3T3^t>SN~gq_SR)8H=~%mM=#Zr(`=`Fk^uyN152|6|Lo zu%Jm{HMfKoo1W&3>RGd@OilBrP1V(VJ8kCvb7OzaN>hrSCg$KBxHHXUqF*^=mIKF8`tN>i7Ho z=XVxAkJwvfTD7<8`;PMawc`2t`C;o~POgg$k3XJ%cGl4~k()WVxK{m|r+YrPI^O-? z`~Uy?7dp2aB_HFNz4TYzPt}%|2A%#bbMEdg4`2ESdg2*Z@vv2@f3Md9ssCAnv_|YyJSvllrbaomnkXQPmZm&?m8}8zU%Vcg{)bAethru z|FC=^8F1kyaW{F&0?!SGu{IfgG|NY|P zSZeq0+3b8a1wFmKJ$r2WWGoLI=@fqb<(_HwwH33Ltrk;MRNV9ZUUkivi|%jk z?%sau@w&bRVIgh-Ym3cJa;#dSH|KWtf&KeScYV)GmR_6b>t7Xhbf0d9`JK)$_jzW7 zTwBpB>7%#vNKxj$6i?1QAK7faNyL=T-Sv8=_fiK_^`@x6z=PiUdylM%-2CF+-rc+U zVw?5%{bG}QL-IHg|Y`M))+3Oap`c6zYDrEV0owz*`%?A(2mfs0{T-eOU zt7Kp>;qC41#jmbtcGvC|vzprny6EWb?d_YBkMmu9yZcu}Tr-zalNM{%*NWEH8PApm z+H$kF$gWa0_lnw6VR&|y>E>I_b22Y4GfX(Z@aWN_hz$vh3`>_TwfXsEvQE?%j^+DB zoo;=)Q#R$b$8^2e9lzi0Ufr_C^yU`MqM`@?ey`mZvN-+ZB-JI$mTju|n6&#>;yGIp z7uhdeqS~+a-n+keOYh3gTT?WHL3f4x|Mz|WYTISMI95&V+PTzW>J_)jg-(8RCN|Vv z6I^lo=DC8l#e2U=JYaL&9erfS%;NeLyAQs0Gq3rWYJGe4zV8RwC(PGBcG`kVQZk8c z_4@q3_jjkB7Aq<$S|jyx^^-%b+@O(gcDV|MhLyp~nVh!V>TYB{dgp%a?{8N#-+)f{ zWPB0We&^k(5ZB+BseO{v~V zzb?;LmRZ=LbTxPN!R`0!PRo|xY23Ygcj%jJ6Dd#z`BG)Oe$OYa<^J=Z^_t%U-38Ah zXY*rIa&Bdw^`+7$jqGv{K0G`eRy`r?2)OG=B19<|HY zDQIh-e)T$@yS~1jfrpLx=FOX1<>t?u$Jg=Y;H?!l&)!77?%MqO-R}PU{eP!Tnj{qZ zcGu6$fS!P=gP$T-M5bJ|*tBw`ut9+Tv%2J~&V^eg4lwXYSe!U`i+`J8W@aX6`2FMK zXr`Q_72P0{>T#=7FK+^)jM$5vZCdUrE;|C+w0CZ>JA-&v=f zpVvEivao#JkA+(M;!kfswfGn-F~l1o2~hvmf(S133-~ z9sT>@*8^9>?+9I;(VBJ0MQvu*j;k7+GAoV;EGn>ziWR)ySH>cALjKRfRk5ZPb$=|n z78N}1HIJ%Y`}6bj%j;sT7cE*;@$cvJk82h09+~!hn{tf%mnvIOuj9wZ$6*`!H`G{G zR5kTh{WQs1v}n zXzZaR9l;funVDvu!d;!6iiU<0Z|Cp-yXk#6*R|}@&sSd_d44Zr&CmN+GEBl`qvMVK zX+0<{Dq2+f`r1}G`5)oxtLDs^6V<=gM(x6#ccGc~E?y+!@y%a=QL?!2iIdj9U+xwG?jajvji zdu`hDZHr^wZ*9puJkvORP15a@CQ)sdw=1Vse=y|?3JQ90W8>n(R}!v$mx~JjrzhvD zCVcbe&73(+u&ELg;gF&gI;DpHiLx-H&S1E6Py7O(ubwPf9{!gDjuTA>Be7=IEq+Hbrt!J}k zR8>`X?AmqfcCXf}YW}q~{fn1qSPSLl_x_z_o-YTQ zsXf%fxwWr)#ggLZ=k|QL zyXv1^$Rg@8YkkjxYd!V#w#SMr>Lc#H4$pV-iZQvk>ekjN2M##&xFv^nE!ey9=+3p* zUt1PFYB?P1?l<2qSG2L}(~^z_UT+u4B_<}SsHgwW^ek?~pa70zuuiHF;G)6BV7ai5;9pB}~gR(f~Y+f%*f_dM$A?4-?d zcDzaF7SnN9ef3j+{hwxDX|sZdhgf^ul+(}8OTDC=z<|Nrf8 zWM(gVcgJ#D-rZBBW)jnWpEbWPAS9F&CbHA)&L5L0Cn8sv9khM0-YR73@zkx$OdVMY z8<;@>7`M0T;j?GQzP;@$j@|ln=Ua{I6X(p4S+scZ>nl5!?W_5vxh0o7`S_~5T_=l9 z>uz6gHEaE@@LNn<-z}W9`sDfZ>A%0d?U6Koc8gsje8QjoMX9a@_om(t>)m=PiuLKL zR8^s+doC>bW3J-w`FG_Vt#8d!6rQF&O9Sfr7enaQQ}Fp6=CUG1-!QlFxt zPpQWly5`TnpL$%zs>EaG_j}b-A3R6^l^=y=Wns6r<*vR{cwF|>JlpDZJGbrL{X4YG zRI2yU!-oq?USIRAe6#WR6z6unt3UTbDsNef0*A^6jqFnvEKoRl^JZk`#YL?`l9DU; ze7lwH6*uqeJL&r42?iRCjg6ar7-E!mH-&222Wu$K5k~7U)^e=Qx z&diV{yYAkedVA{aDYrwmXKOw_)*F1RS33Qwsomc%msg)lcUZY%#fopXUv0OqFFm{B z-RmD8AB(MBYNj2wCSaCn_A(I>kri3ncSHp4*(37wta+%ZcA&`9Z@2Tq^Y;BrTfJ`K zH`^_{)?Zy6e*MS33l}a}{oGyi^HcUMeVsjj{)JBeT|L_@cb(OA2Sf?4F%IEy+99ODq!Mvb3sX=$kHceWyV8Nedf0pgat)4tRB_xdHxu)d) z@clnmXh(17`uP3z`mRqKKW)4el(}+>_O;4{1ih0d4;{DvXK>%`{=V9&v-9^w8qU1( ze~ssw(}!BQMbp#MpI%uR9JWz@`;w5z>&HL!zTSLlvzPzU<)FZsv`;g5-vwHU>6+@|Buk-V4r*;afuga@_8RS}67&v8( z&Q)LY%Ca{%7BZabxBr)sAFiS`VfO6RENpCA{kGpCO55K|*W4%6uK0RFqnKk$uMOFrn{VT^rK0tv$2Nnr;eikC|8Fx)PBDxwsS@%#SZSOs^ zW$ys?IrO_>RJ0G8X+x0l%|92<$wFn#v+qUZQ60a4C0m@2B6<;p8 z&$KL7`}pzWD+{%aTB4$&KJ#oO_4V~Z^LDG(K7O{`(ao z_4oddUPYdbUAgWH4qK?7;ubmg&Mbd&y1{`zKMT&=798fCzR!Nr#GJ%#E5B7PX=*0< ze0h1(ZdShE`~AhGrQH929JfDl=1j;PxGpdE zcVB$*!@cVFEA#&E{hn}T#p(C+g-Snu{hIpu+1Wo|F8dc9@n(Mde1842gY5Dt_x4o! z%(2*bEE&|0VA-kO6C$GdBf@dPyoWp|Rg7mGTy?ul zXR4&mS1jsOo0)QYZV0Eh+nGOe)6UM?Soqkj#7Y)4r#9mv|D@A~QoU#9SWaHQ?^oB? z*VivEcIRKc?)fWiFCMRR(Q=NgDYNorH(ay1;-MrPw15dT9LU1PW>omd< zaiP~BC*5n zUcSvE(e--!No~!>>+$XG@~smloUSi3Hox2zR&)NlR#lc{WaNYA%lp<|TN@3Ul=t%X zetCVpd|_eXD~V|PQK;?* z!3~M4W>1T0{`mO#=CZd@py|^YhRIKu=dm5QoxlIA{r{i-@AiI=v-|(&vsLeliA~jK#h$fTSvW49YcNf7&d;rN{v!5&1U`LoX_Et$xuTMIE z&&0je-*4SkJ!xuD|IeoUP9ghw+wU^mVmb*QA02)1we+>AGALd*q%|)&7FQqDnVrp> zn|EpQj&1KU_f=LdDogv8^WppcZ-&A%4#<78IO7(b+sO6c>C>aza&LoX&dcxDnt#7j z%)fKz&R2R$D}}ojZ76u?q@<*D;q_P063n{4ziwV(2aQNXPFp_v*W>e+=T<%le0*H0 zbj975d=5GrSKSJo44OD7e(vYx<<-&Ak#K!o?6<9!5LUbSS&k$ZWb|B~+RDs5?R-(3H{ z4%GTNGt>C>S5Pfiw*1K+r;C!pc6+bz&!6{H$5RE;$Q68Pa&qS8KsK)6*J6JwKl@(D z%3e2D@~B2kVXE=$&`+0)uK0ZXYptiJ2dXte`Dm_n`6bW<)4G_>lPQrZzCq=S7B7}G zO5xa?em?Epot>cQpP>EuTyBGuUDP(gdualD#Xq5;v zJ73C=4-fbJ`E+{9^x4<_9hmI@{ZJMZ6kM`&>Bryi_g}x&b2P@tDB-42#ka_UqD`lS zCPi`Z@T8ocrd#vx=X0ItZ9VVq?%tet*Gk0oZdIA*UCXjJ5};l?XrZdGnva5+*|fy8 zC;Pn{wKiJcG-SKbP#*r3HA^J$#f6Lfx7`xnxb9B$+wn8Y^VhO(XV2c;{NdwqrLEgj zPrvFfK00+`Pst3E`)7P!pPMOdSp-^R(j#jSO~6keBrLehHcz+<4{KS^w<9$tn|=w%SFk=G!WLSH`L-%ClQc_s6r@`4!LSmV^ajJ{6y)AMY0uA|fa#SoYQ1Eg-kw^mTxAlLPC83=`0bndIYr51&7G zzrU|`=jU_QmZh(z?2RqXICc8;&p)5fb8>ShAMcZ``Tcf#&EK!rD=I4^bISg* zX8OUSN3%|QymFjvmJ6Cj-?(uj3p+cgcu-PSj@((a^v$g$60AfQ6($Pt%!`~Uy5D*e9MEN@?w*Je=>?(Zf+3$F2JUs+hTSi0~? zqD$=VYoIZZoZH)aL2U%*c0NHdv14y;ZniAk`}6Pjdr*c}QB(W$;V}Q=%aQw*PlpCkMR_oIKr)ff+_Lf3 zp1IQ+7^{S?hs=NW`_JcsyQKlw_X)~X6d0S|wmob9dVSiQYkdpiPF`5(44PuNc=2M% z%S)}Gac>EU6O;YzJWEQp0b4FK{+|U{dIpmyu6aGt_oFAQTg!WasT5- z4v8G$_Pkx3UPU_Hi@X}6?AHXg-ma{Irb z+uyz@*>`*9m$__Rm)74)khjse^=SWBu`A1uOK zdfJ&8jzvXA-D0{*R#vm-*;a#=a_#%^s9Vk0{%VHFrrO_S@Am(%yR|+4d=o2o#e+t6 zi_%vj-QxOc1_l?>_U-v5RZ)Gong3RfXD2J@j_mpW|FjoBKL>JIS6A1L$9>kIlKIt@ zm7t6(A}V_Gwr~596eCbE4!Y`o-Tr@7Ro~y8y|y;G^3zFm%hFdO(c5wok8}uzovfL} z6q*!Xl+?3;aecv8^OgHQTi5-#*vPl)c3H`-`;S~UUz3`2Ene1jt~r0z_qLCZU#EXI z%Uj%Iv~5$Us{U*LvTZM{a*keFWCbdg=2#Yk##*bty-7UKz*zI`X8M;G7n>(c5SUl_ zOcE5nUESSpU$5vjoaqCa*meI4th6pJpVifqk`Sj=}-G~DXq%7a%HhPiJ}J3GU!*2=wKF7@}fw?BUW zHcmdq!^Fh2wcNAW`Iolk zM$i5=WrD(@<@)<|vi+r{-o1Nwr~H0x&i#FRUnv$RB`Hl-^IcT>`dW{aX;&+^c+s01 z8`bV+D=8~CZ_U1LRQf99&)>h21_=zWudPkKvLf)!-QClL)%`yF`FvhjMkXiJ-sF_% ze=be?kPV+ZljJNV_!FC zu66mR*X#F#s@0;RqKvz{Oc%TNKihUYFZs!di92@gWc={?{D({4AAY|#NMJZKmwWrY zS2LL3g@4yjNXj#|x}RKkDo84G%W~WOpQ|Tpn;J~FE%wr|$xXTl-qk< z9CJT?`UI+ef4o|~zN4$lY5n!$%f9A@X=fzddL#~hy&j*RFaFv$EKF?wzhBz+e?Blr zZ_81%ww^s!BVP{ePZ%}LOud|R`{K}}ReMaI2x{`2i> zcYM7T4Z61T;lqd9%HB4JtPtA0>2G7V$>&Q38I7}FZDZz0Fx&i7{D08hGUo*!wsgMF z(@S|FRDO%^>SB!x`}e=N^ZRlCvzveT|39pp_gv;GmNFFDC6p?seA9Pow{k0k&uv(MbQ%u zQ0aGJp)+X5&7((2Ha0dpUM`z0VO64Ge!s@}?ygej)obk>)wQ_p)k)X=VBA$ITwL*f z=kbkZHPY@PLMFF5rPF4{r-ZpluG_Jxk@wEAT&=3>6_!79Evx^>9=f|x?nQ`JdR6cB zh;v1LMM1L7d>&QaLCEgfo#?*{_!F4)925HWo66C-{0ervzakFZ&&BPzrQapYW>x? zxC+!i+_&assKa+jy%yi_?cTjt!( z$HKxAv9`G^E>2EUQ*+6ZB@?DhIkGYNct>yV)ARQKmu%T05*{87sxCmWYLLLd%*J!z z@L{X!0B;E^ksh~+ohq498eL8`H8oRbtgbnGR#f@>o;`bBTv;hR*Sfp9yr94!_tq9g z1%-yPx3_M7X$+{Ww0wSU?&C8vjZ;!m3Vwab6cQF*z0YsHUGE|d3v19$q3c>3?}8G- zmluuMv2Ip3_%s7lzb*bTr}OJyF3GLOWcS;>YV+IoNPC%KZ_TH|qYM44W>5N*%(^>G z%=q7Pu`kkVm!|s*Hg0JN>^a0LZnh~ip%tHmrO9e*3z*x{Aumhc91tE?=&`Hfrmk%a?`s#`U+iyN4e6 z^yK8ZDN}YBW&~*c{P{DqjEjrQK&to2)2FfDrp})2T~=oH^5x6vz2`oD`lO_y(xMl; zOF&A>Dn)Y16_=WgHR`6dpc&2-*UbcX!vtwbACg z%HFQ}W$K!1me;~5eB|)OI-}_QCnwLE<>lnW)Y;joqM{P=*H%~e?WT7JbfdN`$i2O7 zOV(8`etv!%TiexfwzjqxGfXO~s={RNZ%RGAs(tU&?>P;R9wnVRb!tb&N2Q-Xe?EEo zbmIK^{&jVBJ9q9(NlS|}Yx7!s@xlA|{>%O5u3{;9df(aExv;2c)5ZK#IeZoYPE(hx zEPUv{u`utd>t8lcc8deNcP=bBs_AgSL;Vi();-3jJ%T1p^PR1;y^{a?2L=8~&V2W7 znC(@ymS$qg*|j8;6TH)R#*G^jj~qYT#%oabCs%@p&B(|IlvizS=YIK8Vq|Q*v*009 zWo6|YyV_YZW=MSc^vOV~H`KqF@zW=>1sa7qF&4dIx=|sn@ptdu1(imrr>BKJGE-1! z*s#F>wEyb%Hr?FY+m`yyHrtYYech_OD`GL_a|KrX|7TwFOS9&OqD}-uzb)JUU(;XA z$jpxUyXA>m#Jx4{eX~~D?-Q)r#3#j2%96#QXz|d+=A&=eg0_|x0U@D7Eu6xu_NALh zdHVZ<_A-EW9R~%SICt*Zp;qpcloZe{iGF^3PoF*w<(;7yx5uM$XU4wp$XO2_J!+ag zTl(y5^Yubo7cN}*<^BEn+j4J*#XfIpZq9th@lxU*=NPY=JkU}fd! zXQ57;KFJi9maY}rE+;3qCG#?yzrX*VKYucAZ_5pRa_#*2^@<%Aq$V#n^?Ulm~PyE=8|D8SIL`THzGYcR`gD|mJ$M7tt8_RpV$e>F2~ zqdBgY-*4@=Z+m&UHDGJ%VL#AJX5_TekF1&jXAiF5-lr@-b>R$$#fR1~+E%T5Y~^=> zq3e2Xhu`wWwZFe@$-h6(v6=1WZQ1sxhxs3V$^7wBy}DW{ljFy)UyokD_Wu6v?%TIs z&2D`&C*J7gR`02ZU0?U*O2@>-GOA4+S98r>w#5}JJF(*7x(ln_&&_DIes|~8+BJs` z#UvV^IJeE;T#ykla@KAsqOj5c4j7X z*t}JW6FvU5ff_Lrs}Fgsetq>nhumX{qawndOI~f0ma44$aF2=iJCD(%ufCFMQ;%`` zr5OdfOmyn9Vtei3=l57}#q)CqUtGMfm|Z6>XXoB8B@vt1eAF(yd~iKpcY9|3ox2ZL zE`RXE)3Ex(0Y(n~_KnF$@2~BgJ)i9;i|Wm3=bff9ZLO4Z4Ut5wnZ-tw3 z+FdiTIdfgVnCS8C`yc0Gnzu)gjj!eG?6sShtzN&wRxCa8+68~EE58gmOEZjy5k@f+4Pgrc*gN7yS$2 zJs2CIk!AKj>qO^4hUo24dDkyq$a4Ks^1trJ-sm%5WX<1A3J49kB9~Y9=v&03%u1H6 z4NP7dfrrA2n|=UDqvHDbTqwYAOX=3d>nvqW=B%)>|c9P1og6Or^NIY(AQ=ZK*48s$=vxrT*?hd;T6Dk!aJ@cBITO6Swl4=*TQ^o>!P zctZ{p(Td+&I>Q!5nP{;GXs=M1c0=vHf~KY9z8_3+b&^`kTYtE{`0#S&JnQ(kt}?uol^@hTuY`2d4rNWYw@ zY|nE4cE7nUr#??zw0GZ*pP9Pvo@#sl5@ZLcc++MZG7g5^E>jllInGI>qcK$E!V+7Zx(xd^qs*KL6}zhhFB2iY$wg zn|fivL%nxNrmGDX`b}A^R#fDYyL9^WtJ61evGX6AqM6ikYH|On^zy$|7RAqAeF<}I zl(oJRef;9fYrZc2!ose%-tVbg^!nMKpNk@ASnl|h5wg;eRWsmq_dVa{@EN;GSIm8> z!@6oo*t7HPn~WyDRhsDWrWu;}j%;3BdZ~K$vTWL+is<6GE%zR+_{Q?Izh z%$c$G&oOCU>u7hS%oiSwS{p5&vT~_La>>bF?O)&~e3ti41K-zNbCG9f8ap^Hs($k_ zsoGJu%DD5jmd4(MokcHw(tlm-*Z*-SDSGS00QWN@VqG2cwwtes({($r;^?`#0v#TedvU@x zamk*5xyyCtzHkxpTyV4$1Jm;1ztIR|2zdJe&7iF|G2zG z`OA{!ugavkc9$L8miyt^?CEZOF`mzN&%L<&(EQU^Iv4q+YDwR4FuS?x#_GN{jeuUa z88(ueHn|*+XqvA^(OvUfts}d2O(;ueZCFNs~xg^nH@0LW*#}D`a7v=wJ_tWJrd#6z6l7HZU z{OP%~PIFg#_egI} zVH$6?&bCltOH1DM&F|mbR66@@_xlC4)up-NeJfY4NZhjaB#Zt3HSc!uii(R@{7Cfh z5{m8Tmup!Ud-TRE`+qyWRp0qzIwdZ^U|RIHZTA0y7R+kQ&gRu^-n#1QLN?(ZM&_4G zRwwyisyK1Bb!V|_@)En+H*b4gltA@$@u$f?6*0?Q7k^r=KhdR2BWn{=>0!1T+xg?_ z_kK%WUw=Td*4Sd-olhEB#j}hjcIu?>Ji0AQ$$EF9Yru5f=2q^b+4uLox*fmaK~U{V zH|BHaoLc_wb-SJ-G`D8`n-90A6c!0xyqtXe!SDA+E#~d3)$d*V)A}7_RKS&)ty-+B zDpy3d-)iJzP?@}@%hvO8;ys%}+1jt6)zwN9JwSDf>XS3(GGT{0$NR7Zc}Kx$kMNI+5p7svCCrMOt+SbA^2V*n6SyUx#2Y?@XrBqx|-F3Y1$#PWO6B@v`$Bn56pQ z-|t0&^IeoS+C$Umhci(@xCG)~k?lph>nisWqr|ZgtX4@)%e7lyc6S_kny;3B!x$WDQ z>4G7iqHc>b=9m>M_$sI7r84OkXi{#O#OZ}EdQNI7r}Y)INM}@8f4mfQap{+X>_?aF zT4!N;z2L7%`oEYkx5~z+fmeR-oFBSo(UhR>+}Q563o0)Uu?n_wa|-hFuF4KceHwUWrO(m^CbLZ!lcK|u3>@O-B`^OG7INT7XF!~u(u_Pa zz9-9?X-Pgt_*?Dl*WJ2Q(l_x82_f6wWflu7W6 zlX0wl#CcJ&?6TU2&zt}LTDdam+w!%og~@6f9BKa-H-(l@{qW;)l83+{=nO;!`U{N~JFUm^t55^=eXdy}G*l9;+;tuWPp- zc`+$;^^pnX)e~lE9hvMBdxv?8#dFD-_VIuE;%i0s{bXCW+waO>HMMJb&Rijx?T;^cIlrhqcceD0QlwNT`Qy>)OLexMI5#yVy*u2! zXTiS@%r^h`ykM{_Tl4pihws#{%dZ{KbvS)=vy;Tu48=vum-}`0zTH>5=-uyg)~>SA zr91wAb>|BC{NdFq=l81uQ{}SQtr89$$@E+OVCE9VNt2b&J#Lq4dU*IPsOZ}%2Fj;i zj;lJw9ADMH=_~A6R}y-6o$}{Tr;`r65JKz0#p| zr$Bw6q+_W`W7Q7>pII!y%Q{T5t0zrTQeJWGfUSe`OIFs$_x*Uq#RY9`3z@F1X|(^} zl6UtAbJyPL^||h4pG@V~%I(?xI%K7DZo9@MyTg**xt>yL{`R`ZeD;2ww%2x|hssq& z)>TKAi9~rWI40iu1rLR+D zh0yFo9r4+F#NJ;0e?#`U1*j;#9$5LWa^gA5(p6PvhnHDCz7ynp=J>SU&P@MmH={}C zfB2}Lm&rfkoaY<7jkhr8w9#Lv09J}OsXUG-}Rd&ldmTUoMHrFuK&{rhMA=AN$E zzQ@O%*T*I0^j_3pUA6Rw+l!O-sf)ferSf0clJW6y|K=-;PfuME7!ad#sp|a>=QFE7 zF6#!lEU@HOOHz}V)^*Tgn4eF~XL4lu^mu63{4Krk`s(J@*~=Cl_YoJ`r?=eT>ZUZ6 z{!bd#HyoKbSN)ha`LPA>BoWqSzRgQi1XYV$mVe-^|2xaNeA{~YUcu|vq)N^e7%t8` zw8E%LN>=w$-E!aN3jrs(zA7J9VO<4kv0TV_P_yM};1vg^RF=&CTb#PMmqWeRcls%X80d;kZ`xgZcEL70D9L z)wedcsIK}kb?#dW!7I<_x99I~{rY-guzGd1az{VAy84R?2k*@@aWZ-EYWdS7x4&|? z?i4h4%sY1c@C?HZ^_%4bJ7@0syRGAi$E)^YZ(cds(iGV(d-y`Rt}HvAzrSc2`MNE~9G!B)QoiTi*u;9TCU}YHs$MsC+jMi~ z%3@Z_jnDE~wr0#cS2At$oFEL8Z_|cJKb( zk_xWLR#IWH`^6Dgdx(GewwZfAb$J|}XCHs&`_wD4_dR4I+jaUEun8yx*UT1hb^Y+5 zS&8@mzu(|oxsn^~y1-ebul)Z%Ij=VP-tRY?4N^KvqaU;XJbIxSnXiX+EHoF&ns$fZIU!j zc<7`UGQW!J(&f;iEfXJ0uT)n*RuSo*T0DViYo=kbnuy4O^jBM5CwQoYfoh<$8eZWU z_rl6Pm`;DcUtC!y=c1H-Ql9a-cV-hd9{-ckYX7e%S*ANOXQTZ$zmLA2jrIS8+jxZq zL)?|^;6G-m%JtGQqPhPrc$nNA0O$wu)P24 z_0PKl{bwsy@$HS}5@YF;dm8v{LwiJ$?x*AP1g{)&k}&6EVorP;b>Zck$L^&XT^To2 zSXX^5;J;Gzam`aE(G{q|7TM4X?M})T%Kf!xi8PC*CcJ@oy=KO{5H5b%jA&l_m19k%Y2chI*J2sk5 zI{oowYUSc34or+Gv+|Xne?0EG{P*|!+qbI=buQTlYI$?ECAEI4aV>3>^0#4#&DgX1 z^QWSUuc0&SVqGF~TvzK^S>1nnW}&(FN)4m@xf+b_SVh1zq{JtP3nI*EHUmG;PPDsJA*HYr|ap`DGg3-gaGn zpOIOwcWt1Kc4Mwdh^g162j3qy^D{iRTt6vX$UXU~*F?Mj_y1cR(=h0C39<*ZAzBt0 zE7`8Aj4q8ne@wVvecq2pt5?OkKbq{XpzOTl$E{iO&YK)gX_?`F=Dn9uZ{~}Oo0~+_ z_S&nv@402ww5vc-CyM3tw3}*cZ^b-%eDL(?f4)nkjPn>Dg+<;EG!B2%oxhdo>w6w~ zy;((X@9COde|$V%Dmr;QH>X*K zZ7=O~2?95AS{9Xj+!6hjBa4Z%)E%NM-;z&u>lh1NF zqAxW4-qGKxbHwB9%F3rt3;yltm=QK9)_zoMtP=w`Eo+=#YN|oz?QbIjiyVd`R8X%sAzwAVRz;UtBid? zWPXvaFL)^A++n{r5Nj^_qoh?tKp5-+lYGXyW3Zt0%AL5)3K6Y}Ol-t=AAbEk zOB`}rZ2oS^u-R6&cE$T?9xA-TpnP;tO18#v$q%!z#;SidH9r;#q{PL2`|P~9`JTSX z<1_kf=l)ccUU4!EdL47fuO!LhaO8kwe=YRKrpx$feP72CaA3o&rc9PrO=bEb)YX}H4+g9JYJ^5IFbi=f6vA$U!54PuQ zI$QU@^m^xuOfN2*Un?xcZ*3QE+G-@a&oDS}Nl0w-rTWzmUgxob=GKmjO`lkLp`rNn zuK63{Dkgfb+Zr?VMq~bd(Z?xve?#VI3w17e2pX?a<7iyn*@6+0K z?A)Bpe1C-n`{ymFx7hgqsZdXS_N&>`6H-neQ9Ac0C~$SJdgY|IInPsrfVXn3Q|GLVZ5|5J&I+l6p={>u-UDeYwiD9qEifhMh9h^T# zo(`&szI;omF{*R^{Em6^>~t6X@t*D!FhPUWqWD6Q9>bPplb;Izj z((}cZdYEoOWd1@zbmER)}S7RLTvTe>)yePxVllbPLpm74AB(xkz|fm&(Kz z!Q{m~3zjW8@O=K^ZvCd&v-j>5{8G12QZ_d4BET;YZ&E z`KVnya3W@!o~Y?Mw&ovy&&}anzn3k(UU%QF zQsevE)>_s?^vD%WX_x4gG_OC+x++TWigqC=_e@q#JSk+jO3miar5m%_dfd2~?-jeg z4yi7=a&~>4V2EabG`n$nS9@Rfb*If~-@dsiOwXNG~(ZG0UDSETo+oF|(hlMO zy3E4UJA(yYmPWQ`^)IS=bTUP4^MuwJE9|69iV zy^`7+tmgw{XJwtM-MgDDcJnUoE7P_tX<(YVXY!5a+TRZ*y1QteInoIUa!|{Eb@9hJ zH+WadI{GSg_LYQOUADKgOUQK6`#s8LGrt`RSR-J%yJh~nT_=w62rtX>^4)sw%1S=b z1T|w%rOvlG>%Yx-#j+|aJMz|N@%R|K_a5`Bn1bif7N-m3eO_Eq++Kw{Knl&IK1^YYkVuXATIDS?Z9xASC3#-14qlucvCu zK2BWcq7*1z8RfmkuW(sYnEo!qRj!h$OD5l2!Sd?a*`zNgqw{axp1gmd;L6g)VY?r{ zS?Cz;ob|TVB6;rX&-0#m);)0-@>ub0#>QlQ`7LpQiT^Sr1&l+orSGiMSR|a{>pM%P z^>F*q48iJiCvt-_TxR7Lw*CCMacxE`-`rT1EY-WaI(=)C7J2-hYtG-)eDubwJvO^{ zhNf4Y$#LucCS|hA`~KyOg_X9)XY73FW_VPqT74sHzrEfm>3#qACC02)74rNGDkMw0 zHoLIjzad?TiN+6 zqRJ`qEBEq=CfGdYRGV>BXWh3Mg35YlZMK$d@$uwb6IFWh-c$?A&UgL#dl-)QbqbpF zojcfkVfFOAdo!YTuxIS7IQNHRm6&c^#m&$KVL~!Gi62qA;v~;-o}1? zF(>iC@4V?te`S6BDs9MY)O0JL^0n^A4TV>=E*^|gnrPy;#9?a0+)1Cg)_s*&5GU?e z$hF|2OThkLUL1?V<2G(rzxw#u^3*TCp0(Kj377cPRUb5Wa@(1|rNS$$N^A}(>!e${ zio|}Naj;q6)karVcXJ|h%$^Ef`+r@BdZgJoIhDGeJWBd!waqE;!T0;E8Pjj@eP`em zKX3JHg=F!^ucGsRUkNGv8@XT3szl&y`m0+eYxc-2TDnYcR1Wj>7?463Vxjiqc|&g35RmEXCr_}YTM(X-~RbW%*tzq@;#&6&efg3pE5 zl%Acxdsm!L!nB@gjE2&mPFbn0728!J80)wHr`wWmW+IOsD{6b29GG~6Z#%>3pc+Sx zknHl0rqBU%$$y{a4f|Fmy9a)+{Zn!Fee6~*n}A<`%WwbSx{#e`Jgc(%jLhVP|9mIK z6tYgp+{fE;clXisk1v-Wy%P+|w1&kI%`QRZUd2;Z@y*D(I73RM_Lt@yTW{;jUCJ4a*J1YR@vcc)_0rcD|e8VlB} z;b}hTkeH~Ld%KP4uB5SAXYKEE7dNGP*VNQ}`1sK={&=ME%9R_kuP=S(G42ij*?iH5Bg)0`T+`_PMvi#ns{+fA3x zH#+!weK$|*!^4TU&2HOR6c$}K_)r_Z?QXf?6mQ>2JZ#L*&(Gig>?_Lx*KV;FU#o;_ zg%?^cNm+K`>hA2h>(zyBPoAQ3D&DQ9Vf+1U+s%bKkBFVn-gM;El(>Ko?^e}ymn47tn^clTkbC|{i^LwOvZV+7q_>6TjnoRTF8ARVA|>gjlc`LXO;VA`(_7u z1YS4P4!CLh`(E|Y7pt$wi_hQ5$ei%*j<@DCX|n?>gCE_|(iT?wdR#v7MZoKyVWqZ~ zlJ1EG>QO4~h1Z*fe;60rM@B}L8ebCHAz0=1)g?IW`|Hjl+fvfF5^t>(UK4xUKwbkp zJiUIG(CXk>i!Yq(S%K+5P?f=gggZ@%7g&85fyc8|(k?o?}@oq^Ym3uCKpd%WBfZi3dUJygWP}{C>Y* zT~o7j(grmxcV5YBiG$9+uJTA+?e273oV8~jgNT?|l7YmTUGsS4{``M)x4a_c>a_z8 z@B37-JH6QJ;hyQJ5Hm%|x3g6*=#A1gZKVZ^5*`=n&Sza8;m}p$=pw=*vV_A^KxCyS z!%EMLl}pb5{CA^mn$s!E;xx6_wexH=X1>|XoOnJm{q5c`^Ihfd`{vJ|Z+Cx&#-*d( ztJJscwq6spw6B&!@f15}Kmd}oRLxOL}F44<6MiF0$UZ|*Ese|>%Z^S$4{F}%&Vn56gp?sLC_ z4*~~H23@`0*&iN#Z;8XCzfW0LWTxk^T+_chOU!43bN)wNuZS7HZtM(x`$xjosy_bV z9)+#-^;fM{hp)dB3)=Up6S=8nYxea`rLV6kU7tL8|C4~%-&P)#GS?4iy|hOC{lk|p zJtHC{YJYu6JTXD>O4+ux`hJftseV;>@~5)&-{9 zm5U0_dOM~p)4@bC%^nT)j#X*mrA*!zTy^vLu_UjnCHq}oc-Wt z`c=vGGbDDrns;)gin{vdl9xfClLW7=jb0hOlGFd%zd2gxWtNuTw_Xvnv}@((-|u#F zA33@<`SP->YofRJ9XaB%tL*Km4nbuJqm&b-=Bv*=nw_6;LZI}qSjrhA-L4O%pHuQ` z@6K-fJ~glYYs|Ax7X7Nyx~?x*y>w-KhK&UUB9F1Z&lF7B-g6%?|kRm z)xNm9d;81Ro;5W#pq0*VZ*A4vJkMg$8XeI&|NiZM#jE!=rA4D$X=&GbgOFpDUlp9r z>+VyxV06e;KiBg2@Ag}Hzh13ACpkyXwrUFKFwymKw)3i9X)-Z0NA9UGWcPpjaA$|! z9s8P=m*$fhnAt)eU372XSn$wENJuDRd!B6Rt1Az0rq5rRc6OG{w;RbaRwXCiWKKJ= zEq9gt8kXhHKCI1BT+1`HMmu;WkCDgXhJEgSDoRXB%G`W@j;TS#MGx*(KivJkOK$as zuTQ?bybRjfV)NkuGvCH}A#0Z^b*1W2Mp5y@f4>ut^M!gwH3ci4Qs)e4U1+5L zM|c6-Yw-ng&n?7s{A3sS&15poI&heOw(aCeot>SDH#Q`iWL@bv+AVHe`6=bmqel^Y zt4y2Ocn@6;{;H-K^Uw+w;=SFZuInb)w?ilAGIpG!?V2sQ9$YJ`eWk2GIa-8MaZWSKibDaBCm%>I z$?uj-=L;x*7cy0MxqrBMQJ;>UUY}jrYX|~tb z4n90QVa^(@b#iuVxNe=9&Axs=U%&0LbMv?5^Iu)HvdPoZ^25XSSPtH~imy8vLL8Sk zHitahq7yp5RbbuGulFQdoKJdP`oMF=+`;x-;jPPY*A3sMK5{9o+mIi>IX!60{kq@1 zj?HWjA3r{PZEf_+D=R184Bph;(7<5#>xFU~pX{j>fr~S)uaiAJU4MD<@xC;F-T=m| z`F3gN7u9@Tou_IXsQi3V+wT0A*UZxMOoIjF<)`}Q-r4cs{OYeM2J_}^ooVzmcvV=f zKz{!3a~FB~_RX82Yb?yhAI5K1_sg?Sk3(@?!3UYXg0jeyQgK%40sX~yG`UsQMl#Pf zTlr?C@@(^bx$Sq$q(MuCjf^(kVObvj`qEPFi4!Mo$-6r%@9wUR2?v=rFF*3~@`n2T zDH3O%#e1(!U%C9$wzJ=Do`0P+$$9std3O%I-~a!>i;HVt-WHEBD2&o@kMTbuRCX+o8LaqHuT{3Ug=Q#SjCndQI=J0nr9|VUGrY-e()Tn zcA4d;7wE;T;Oe$0TH6!3InA)_O~k#5$GmF(^K!nG$TVHeN^&*8)8o6;w=hHwUStGxEC>)SGK#?$xvuNt;~DVb`Ud+W*@ zNlrzXi6AdWdP>z@{px*X{sWeV;M9Q4n;&kyp76vYbnkV+zn@O)+kCwe>@(LYG*68i zbRJ+)aWQBEg!$bP;s3v`?|)PE_f5`K@efYQl{LV04P>oj*vgv5Jgx7nXSA~6#8`-a}Say4c+wU*I7KKi^A4^@- z{pKWmcyRDe@p)U&e$zDn2gs(Ib(ojZ4e&e|?{cW35;1qwDc zHY)-bvw^mBKJK@Fc4K4m^*#6Q-t^^*H$%=x5^AFhVS z2X0JqomclO^X@U-zN@PjRu*SmIk9fKXzPddnVP|DSFf)65$D_gHRb#~+n@hp&9xr1 z+Z!4h-haI=Y|hu^3$`A~+6t;uK?i3X>ytgbE_S!q*IJRIXTBb}7q+J1c78bHEB*Zr z1siS}3prU>fjxTJ#OBWz?kc~6Lo3hC-}hZ^$+AP;`m<~&H?57?IqB-^@Xs%o&wrGC z;NdaL;%5vSil6&^dw)Ov#cR2W2aNM-K6$>|_d5@C5{{P_SM;_V&_RGUf4^Mbl3$-2 zz3|GFkh1spcpWM#EM_fRm?<@L=FB%YHZ~tP;Bc&0`gph1|AW7O{``1SeSXZp;?2`d zvmdP6{ie*akolkK+SGNAs{4vFUVLXbD)?gSygNmwbu(ribLO{YIpD3o*Tu)jXW#YE z6#^{DG2;5 zrJl7>dvl5Od%d@MZ|mOH-92V}>E`BHViGGdFE5*EJNeMotgBwqb~QT`lb=6(mSviK z?aHk!nTr{3{rLEpyC&AfrG+h{-{zA?<9vDRvNd8dGIQR4FMoe;En`$gMa91Jvi5Z` zo1@mw+P!;s*}p$OH`OY$O4w9vC_AmY{e@kgBcIF#lM7qo>$jeM>S8GKThV*=ZH2(o zx=$}{3yWU8aG`3}vAx%4Illjz^7`6ZsRdWp#YUe#dsg>@>Bo;BXKmlUz3kVQm)Uju zcf9UjCc1Z8#;j$&GYlM=w=goZWth!g`{jOs;+viGZg`h%TW0&QW!cW1nYX^YOgrz! z@i0Y6rCEz7`E;1PT-~qU$~lkyf)!rA-5we}A$`7SwHoW~9fiu(-`_pG|Nq~1#mE1@ zT=w6wdpGEKBSwSze>Fu#MW6QO-QQQsV3K)h$$>&Pez}-Opfh%7zq-15^5n^fpu#WMf-e#iS{f4sLo@)na&keZ79c zoV>fc3g5+?%zv`Ae%tR#=?%-*Xsm-)eDe>=^q60RGc zS0!z^5%JaF?FGe9p3DOb;1bbIXaU#Zl=vXVrnvNgV9%#Y;&YW8YM+Wu{aW=zaC3T) zf$!xXKcCMBZ3RmC!!542q3UavTdx#r!B4iLZ*Ok?jJv%xJA75>>SMb~U%$A$U4OP& z?x8g8T1Kgc$H)7NpPi9pVrI@v49K6)$jr8(?r&8rw_)u24~bXp%O5x#)>HI4xOx$5 z`Ta}cUPW6OuAcas^5n$Ch_zw+{(g%V5*A+n^Uk@s)}TwL*1hJ-n4a=ibKQmw1`K6y zZa9{em90Fk*<*W6c=6vq#wBl7$enU?bGp4P?Ysxa!!;@nqHQNVPoG}!%J^QUA9KLu zS-*HPCOEfWxwh%GMLB@CJP`T0S| z-#a-SGF|`m`}g#ln^Lc=i=DkS`+Cvux7&mFR+WM_11@sy_6nJyVr@O!w)&ev&5r^b z8=D_L9`|$d@Lc&?efsiZcm79@A6r&j*ikp_^fX5gj*_=oH&k6Te_q`%#j5#LyS&|x z9X<_NPpX1ehv|ZLm$|vIb&KildRAQg?99$R+hW$Ly!I~)UA-)7_R}X%rewJv@4b<1 zYj}xWenswH+v-Ehd<*XOWh=I52yzCrCKmnc)V@=C3bcNN;cDTV@_n7c3nPss?C!jo zDWbPtX<6XSqp!E$4P6&A6LjFtoH;Vj&d;C!{%c}lqKmt`arwKLLx&H0`ujhBy?%e% zj}H&8tPEa$qBwqa*xFrpuT-F?jb z{(-&Un|AL`oG!5RN&IE6S$tD#VjC~M_PiHW^wsSCmoFt^`f+EP`R!)B|Ed~W-*x!K znPs-ugq2g$4mtB5EIxnGTmRr9*8~U03Pl%7Wl*mAW-l4SKlj{%V}k9{c`X8qPFJ{f zbTovn4rx?b&HVqhmxqUfh6aZ|bI_jpe?QePUc7jx{C@5AKXs1gGs8cB`jqtK#6-|0 z7Cn9XNW<;pw{L0+3JpJg zR5%~AFJLHp-=^ryBN;bkV!UtmO5+s^n67-DbG^{*nPHJFBj{Mvl>rNxCQh6cBdy;2ufg|5zyi@x>sx!bupf&3n}Ha06_b{2ukj*G851^woS?e(3m-#%6Q;nwR8 z&%LMJELrm4`SWti&6yh`BtH0W?Wz6!O;AuU@QK8`ckfEx-<#{&E%xzIxBjHr zvrm6|dOE-2?JU#mPgld^FK$S5{`dR-e<4xPrKi7#%xGv}2nr77m8||(vm!G1E(6!` z#YQVqxdUQVo3ox&F=E7j+&Crfkl@jd%f`FFGV&6_tt-Q1kp+ujz1eSX!S{{Q99;!?5X+uL%dYyT8` z^6hp$`-4YEyN}Ll-oD*DfA3eZS<4IyA008OF?YRe(p&ueoS@L6dbj&&&8*xBS2T{F zJ2E}J&UEdPx!V>#o%Zf^tfqr$mhH}{IJT05O{_QhWYv(pq_cY4^>|J2z^Du9`4& zX5^a%>vx2$kMn(cYU;}vkIU!U<*GOuT)V|4&YQ=#LV9yc3rpFX8-Wk5KS_1Gy(KgF zO(l<%NrzePtqp~bk2&4GKILjFxA=)urxtll)!Nm+H&b|y#lsuVXPmbFKPxQ9azfp< zFH>t`RUsbD$j~@D+gx2yvGMo&{qsM3D9{R9Q*k!iYx6&m<4ZgzcXV_-m{Ua9=`DPJvR8gTbtOp5i%acBDpSbf zYm;9;{p!-&(V?;7duHUd`Kxc{n1M!Pwq}XiR((l0)+1^2<3TehjYaTSrDQ&-TGZam zzA#uFw6SDOV|e`3yRuFk%$e6MH`_-4UKO`!TH(R6zspNLc7N+`Yn!$}Rl;arflRwt zYF7MqpG&!Wwnat1b$#o4_t<6cuxZOovzBBocAIHCc@pSI&u@P|pMPz1ty5Ut*|V(Z?Ri&^^~eRCslb>QN*XYbyvV`X8RleK#d<*F8xa)?dzLzIW zHq}*dxNP?);QPYXz8uS0X6pkNm8FD+t=#u7`E9bU3-`s!uxA&GZ8gu#G)^}uFE3wP z_V!j(Uf#Q>_w`SMTDVCYBepD9ps+S{b=WOof18DGZ*4t&;l20eo@oCs8xk6q{rs63 z)y_Ao?8}Oqn+2VwFbn>iB_8qr&>YPv)N4hEZS|FfBk%3 z@W*0Jbow_RuVwZB|LH_*Xn1*f`Qx}_c4}L*uI@^lwkd9JRqMWG-qZC;G!Nc;@kmVQ z=BCsVru*|@YXQ7B9@pu7^CoASUM#5RUm{<9kmA_&7c3)MP8TREV*;u6xTF0pBW7DbsYV6T=KOn^X8?U z_u>eYdvgELZ~v)3Vw(Fpp5=Z#t8jP*H%EKo>5C=W6P7G2oVJ;7`%!aS*?U#o^D3C6 zObn{cR6idP_7@NrKW=`%Ciz>)oO6>@y*v8*pMN|qf4%n2dHeQ-&I^N7@3xCsaj(c# z{p#|P>55l~()5@h4^Ze&_`2jvPmI6U>mP-ojy30GA~vz4odxv{6YW{&IEL=O#lsh% z+WhKQ&dpz`0p|<*ayH58In=(l_3#RMn>xpLu2t!d=kuy7KA$z`KI7HVl$x6Q@!Rcu z(5*RH*VnCmeZ#tJ#l7YIw#!~`IHd4z>zXC=bYdH#1VbM@S2`vtwn;tG-|P5^uS>S< z`!AQblQk$P;kloL%?(fo{M76}jH|Yvs(89YI$A|@?xXMv!sk5CGnn>SFtp!#RQ*wD z&u=}O|285QRgW$_JHxP9*}d<>zu)g?+lnp+9kE&P<;BI*t~0)vWQ%Rd@NBCqYpV;>Wk=+pJfaRnO;Ma&qHHoL9rRs$5lcL0XJ~ngg$zM8ju^ z+s3{#{6jxpP4CW+Yk1`$d1d=OCUf&2-}j%L=lSyL>hS)Plhut&Uxj>ocQ^Z6iOjwE z_5V)J&fj-(ie_-eg3t5b6+gccwo859h0=&bh5u1um;9!#6JMpxwqnz~DLoTkdwQy> zILx>EF#rF7jH9KTVG>`)606zvly!tW}AEjm@0m=P`@lwhEq`XX{;2 zVIgZ>_T=aD`PXaz{Qt|pXK&&Wj=Sw*Y#-OJty&o8rSbE3s(@p}#$6!|T$|>JOuzWr z(=+GZnr&a??ALAkV)vdx)RDi2+u#F%9{VfACN`+MY8h%sw< zPd_$AQ$UD`FXZx~D>gPZ5!-SkXDur{Z~J}1q(@S&(O;&_nRDiD`TgFjS)jXSD=J<@ z%##Y${apV)_-1f@eQdiJ8`p}(_nf?gHBR!HGjTj%68|!9+R7B$ora6APkyxN=7Y25 z3*Gr&Tw-0c=!zh-Vv9j^BjYOnRBlN&wiTf(wHUK36HZ^s@6NaR$XERD%ZJ1n*5b>2 znf3KIr!NLw6~6EPzv@Mc7r(r_+q|>0GtK{GV$7b3iPrCSG%t4V-;{P%s;RlTbpNsI z@vC+BZQ6T%=Z}zW58fqfUbYMgKfR!7jk@c`<5fX2A3t8$zP?Jn`g?4|wlhD=nK>0> z+z(1#IVEOv&bvYDl-qkH&%UC6C6`n(Ze98MD`Z>7#ip~f&5Qs1D9qdcx2#XrI_=vO zpYkUs1VN|r`OUXG`|RxO%v)PlDqjEj!CAsiChMwEN=2dw_m8VvrtG@fvzl#%!fQ{* zH(Tf3IibJb;r6zI7XmrASkBudpE79?SQNm@zT#lm;d2X`SXMl3y_X&!tLV_%(=t_i zy@*GVsqZY4#M9GsGiJH{{`NLo$(wN6wOnO3h=cRhJFG_-Q%BkKzPw)EHHG8(@q^;NqiMHXLM zs<-jTBFR$5hXOe_6E13=uIMWcS+>cpdFmy9`-8`N4Qj0-WEO`_POPb|1znC5U-whB z`1!e|p{v8z#O}WKCQ~x+?X9g_vaWXN@B8q0YWP0Tp^HC${E#Ty`}K9=>#!L%H#c~5 zH2=K5X;M{?(F#}1_peWahWKBtUe6Qn&$T&`c}xEKb93L_P>il>73f=kfWdUbzNvFc zdc8j$%lW*wbGC0zPQ*Obllyo?fL%q z_tn0`IiFfh&EyL{rriJ&8v_SOErw9r{SYI|Mp%HZFZ_V2%SEqBWG`0%~#yGsn; zNgay#w{>ky*Y=6CBR{Rz)o09__i4wxmbSJ{_5bTYLs+}dE33QbzI=OE`rQua(3g9E zrtS83=1}xn^MGONJg;h1d1E~XR*N%<&d0?24nAtri~JE1bW))?;mpc1jtwO%t=4}& zCcVt}pvl!$p~){VE&cQB_4*}CmkLTrodVtHcx`R;*?CbjbMNi>S)_lcr-!HR@7M5Y zda)<+_g8L8<&N34WLwGiS4-;`>?%~wxyhuzcgg!5hxReOig0Yc60BOkUnieYYs&tw zDJLhXhOEu{&-LYazw`DygXFfXMAQ6vTQ&$eS@buZU(gou;lt($pSBw^W|^)M^ia6y z0xA)C#I$b|owhqyd5(F8*n(%at#WpIYUT^SxwTdM_4WMa{v%?`IJd2wJ* zn^K)~PudWKsxw~uXy4c-ub+HjMR+a6nvt6>} zh5QP?nTw8bb6-xkN#y%~Yw7#eC^_aUHnF?QQh$GYyC!Dmq#ZjfrpNogd3ihkYISIm zl8eiM#r?C4cokbTwlXn?G&JlAo768Aesa5Euc||7p_ul9!~Fqq4O!R3?(6SsxDg?` zWLmnQ;3`u`7nj;){`1fF$y#SzSs~bO^NAyLby(_;4-aep|NWklk}|{gYR#p~mm~L9 znL4-gEzP>R%I4pX$0nJVTIO1pZ_2%G2D*^eY5%r#|I)ndzf~T7`-E0ZOHF@de*ZxJ z{*_r54(+UDi}=8!6}x(7SBOfdN=}u|6hAE+n>lZ9Z=XK<>k*HcGhfxbwEe!qscz!L z3!9c|1`9fM7-^a~@UF=>&FR)(!4SIb$1aQ2tY^c%+3tI8!9HWMqpyE>XqbGxjFj1y z-%n+o{Q6e?xv^FI%F4x2i@v<&mbETRxwyy`bSWd~C^=zuKZAq=3{B0=FYoWSm#_b0 z$j&e4a`{a>kMCs@J{gMx?((%R`|JL4@bRhH*vz@S-2d~x-|s=gG-A3@E*Tja8;`%a zDO~n0q%kWUPzl z?T6bRUW?tc@%yi+89@$>MyRH<~qZi$l~n@${Rsy+RD-`{Pgid@~DO+Vk>aO>{H#Rf%7 zPKoXNCbj1SQv`SI8di1xc~3y6DZRb5HRr~L#wSlwv_e)mWMpW_T9+*;eSHlSU!WuZ z_4V~*pUs#!@!-S5?Upq^4C?=UWET_^d~;{#v9%J|X#E9v@rzVDX-r z=KS+&gkD{3X65#Z`)g=zJsWg%PVsX;B_*Yfjt&JiHMZGj+pcCU1zjt@Dztl5=<1-g zQKn8#P8=K@2hN}8?>_3($|cI+;p5|S*(4}97*svHxw-ks(W8R$^5;)ZR{#0?{r-(N zb9U_92^uA^DtlA$lWm*tY_lD^cfbDMUObgoI>fEyx}N9?zu9cLw?zKjnj(^MM?$WG z;ot9g=jEzzGOpj2obyw+-Fm-vr06V(qzs?ry65G$0#5MvGMqYJ6(p3I`Qb{iR`#zu z#jhGyEnj|fvyfAVQMXRXQr^6$Y*H~d=6ioV_e=kT?286o>D@Pd&3C=D+h;KUsPEQv z&DEdhn5S01zn#B2=i%q`xBp&RW>qaFSIM&Px8L1AXJ#-i_4KQ#s1T5nsye%E`i);d3R{%>t-V@)FB3GO>}22SHqTB` ztY&qT<^So1j9I!_fpcHE2&yu!>fRLLczI>l`n}vLbM1KL>(|^m#WHO%%l}=aA09M6 zc*ke|e@*@QaD9FKsBJl(-r{TST->}|%j?tM?^)I*yUQ-DpZ`m8*Uz*Y+xhMO1k{GC zO8J)4I`2<*^huv9C%mqG;L-Wlw^*TRLxN(b3Um7NT``rmnmx-_nx-6LxoThe*sWl~ z++$803ui0&O?E8sHb3|Ns^TFH7wcPst*=dAigg|3n#EVT?Ofrxcam3D1}{u<4V77G zGd{_|D z5cSP=-?wuMNuFj2VTY!!iCP+U?8uQ7VxjBzhLs$&Qfw(m zGv^5i?z?@$$7I=>>grp?Ey~k>$8cRw+89-Ga>1?NJg-jcJ2$f#B(>bt%k0|o%`h=> zRqdJh`h$PJ&$iXRp0sg=Pf3~CmzRsrb(`j|Gg{TY^z^jT8+J9<`)X@0%{VLOG9e|v zb>XDRS2uR=e&5E(eC1|vroU=SL8&X-3dP*J8zK}GjgC*~E?>ahkP;X><>=X;+kUvY zuAKDu^77TiGuFL&5xC=T*;kReTPCI7wt(g>pUzt5)7Zl^b?(2v-%zP)QrJF5~< zs>)cpW|E`mu3Ni8Wd$QPvxTi`(BIGUf0AgIm=nkHkd%g3p$DCgF3UUe)*x+mzUZn8 zQub!P< z_2S5vms&f@Ow-S=%1v7AzFIdqFi`bPIrBDbrNtXDQp+u(r$J4W0!|{&+8DF029)cBb==PM5&LSE=j@zpJeyZC ze#Y^;$Acct-uhZ~5{Cn;)(gX>PP*~ynwrh;8GJD+Q-7O$rtr-StNXt{oz{A=XX0z- ztFqSXSXOP^=ypErh2nyBq9z`eftz$zr34)1w|7___Ugyc|Nq$S|7n;qwg^1E&C48e zo`HMntlg5^&Tbc)x}!DvM{7I}*w*V#epNS_uIxEe<=XSQdeUs}_4~LEx2C0HqA3wm=a(9Rr0F-zJS|*XPE{!zM80f>`dqj&D{`o_N+i*Z%VGS?anyAdGM(sR^Wgx${a>}RsXaUue@nk! z*%heltd|%bzP-QlZ)v7{a(-cqj>B{a8`m7VqNbL9?XHgNL^@U6E$k#5>1#Mdj533(J)cN&ho6jQa zyPQfLp=*p%Y7+U%<+(E^Ob-0T@l{Ej_w2m7ABr(M7M$agEI4%YOxn4^a}z$c{@wX| zl^1`i=9DQelM-1crJZ4z%{#CD-h_v5lkQrH_Po2tyZ?{U+vGDvpO*Zx{PlhR!f5ly z>z}_|xoPXhjamV*o1b|tsCw4(@wzxG_lk7Yw_Db_yxrQw!89RvpPq(cU})g`3ye)o zA+`lKpJoRMXYr?U|R~RKMNh@b!e?*Ux*> zdab3e5HuHP61pBBr}*lkR=dS27%mEw&=o z4yB*B1?=s%RA44pUvYgDxs2Cd)EzP#?N;@>%iw`;C%>?=8SW44P$%W1|}OEL>{t$<5*$3Dtfu}oGw=&ippwh`2BtrN6^z#Y3F@76zBMNGF`FSd)4gz{(1wo z?kfK86Firt1je@fw!gV#lZdBLQuq5Mo&o#qdZd=V-q1Gbn_-{2wzsW9#ziOA6@5oe zd$X=GH2m;v_I0*ZA3vs@Kev_j+V)8`CfjeU|9(_lJM5B&aY5K2jhi=Ly{W&vY*oh1 zIhL#B99D-x><;f_3MrT8F0I~OoD#~Z#mC&gi@tA5*l2Z4?7scK z0Q1-Rds*MT+r^u$ktzRpMqFLwSA&=h4x!geUH0wM(&+6AYkYNSsaC*Ti@>enLch4z zym$L_@lkq!Zp4R!?o1)-TN0bC@(eR4-MUo$puwtNuSH-{j#tg>+Yj>m&;6Sh{U|Q~ z=vM~*4Sl6Y6n|fwGtYHytln#}cw6Qx;_)qIZ|5vF+_j~@FlM&-;oa|7eO~T6YliJ? z>Cc~o8?$_RUR|^**SoTIHPh8@@w4;hW^?8wsQ&agc~AcDhsg|AJC7VW@ZjKu)zeqa z+nX=%GoSC@Kd|3poI9DXyo$Z^k#l3g7whD0KkuEr`{Utpp=qF$uFqe8!cX_^^{fn) zi6uXK!Xp3vT766E_qW@9@f$!T{XE-CcE>Kxv1UKqzPeo|`PdBG*^_qK1^j)bT{4r&V$HErPRTf%c)&3-9s&4MhAW{2UI|Relhq=482spi1euQz=QQlYgpPrnU zzxhBzl&9T~0{!ns^MC&0*L!nrb<@-{-AhkzTRzE)&vKWj=PV1ss_$)bwk4A11g>xI zzqvR1)^Uqj?ec8q=0DyTZ%z-Y3TI!XzkkiGgeR#X!b`*aXR??TIByPI6ze9mz-rr@ zoF6}ux7yZS)4A$geO~Uxy}NH_a)KI>S3S42eXpEQbH(k>IhnoBnOEfQ+kN9`{GZel zKMvLH(T+T^BVw1jWMwVm*AolYMJzm*zwc+-%yy%mE&YWx#_6kiPVT7;SUKtDW=-q* z`mJyOzTY3ZaQS(=-ID^RI&3XrdL6lON8qB|eRV%3dTDN-#o@d*ZY|eB+y8rRnHGLf zu=%^?^A!UDCyw-xRSa8$ip{m|KRUK>eXr)UE4_JFmg*JH%m%wcE9%6afNcz0*Q5s& z7eAaDer4vuvbU#9rYJ6{?J2&onf+LQxV`uGyJ_EYzDyNgA!lEw8Zfmd>t%%Pf&J5_ zE)il|G0Cx1$GXhn`Z@u*b#gLt77I2l4_!6G)>yHnpmymx)>|bl>c_9A6>G-*Px1^~ zV{_(k&B^I8k0!l)%>Dc0x)jCBPk3I1#~*xnc$I7S;)&l3&nc?1w(+$_=Z7+`TD{9^ zu~p@!U5fcP0{+&hsm`>uelB?Bg4d^skG9X6$Z)k##%6_FTG^{5=l;68uDq+mD+RV! z!`@4F!L`@#8{HdPXQUnz@viDQzT=4Mv`tqgd~B_)2-T@=n00-}J{`s^H#VQy%g*td z#ihc-(?nb8^1Dk%S|F%759#%N~a=%t;TpTXU;Vdc|&8Y4+xHRj$wV z|Jm=?t^PGPY<=FhoHyF~0lmGgg^#byZ)I6!Ubge9kKuH?`ah};rk+u=tdcHnShy(c2a~PtMSJ6>;p7^?qT`C5n%^A6JHMnpC;4 z6K1pC%v3$UXxdixSM~o_bE)*o$G=i6QGS~| z=X@*ot2>$J=Vi@a-SFT+Hn`4dd{zICdHRx=1F4O?AuYjoy!Hhhy(4(!wmpzc(JWJqKe<5ad|Gqr=>?U=6|XeEZZJ?|yH^|j*M?iMr9dWi-`iCe zug>+-y>sJxu|`Io9Os2C{`Rg(N>= zU3PZX%CFmlmuu@LXI(R?E_32gr|Pxiv88a#UGA}zdCkv`mI^y1@dM+a0_}9YTa$(VVU>%PyEkvY0rjL_P)(mSBHw;Tj+fC z=KtE?SNb~Ic+bw8E8x_z=!MXNYx^%V@6QV3J7cKU{Y&TkBuBRRk5d&NbN|gW+aZ$v z_>rS@m_PSM?M*j67FoS^U$*hlHj#aK^L$>NT%>$OIyGSOqy^#nH@3dMb-(^+YH6`e zS`XiS4^5BX63@4m>-Wg4+{R${W5LbMg?5UHs~()$nEdMg{VOZOnXdNmY)((Nf5|Bo zR&Md#UGKK~vdz2dwYX=gZeA44bMlR~fF4kAbT& zm%<1WU+q}_39sM$H=2C+eVS20G(()IcX;Vm4gXIn_Mep7Eqkor?dsS6BKS3o%{@GQ za^1DErGF=|-mwX}kaaq6|5MSF#251pC>?+06@Kf|H2xn84xD#)aX8+Wu<^iw#;oeZ zDyuD-%-!O*_xm2Wx%tBh8v+A^8Uj7$;6sNI?f4jY-LSyS`v!n-~9xAx&_q*W8zhb)Jj&X-j*A?CM#g`5I z*UT$;pq;#F#be3yoPHa6Qrmj;zXa~xY(4!^&h>A{t}2+n_A1EQ=;X0m+CF7RAlugm zj#Fn|F}b>YQ>3wknU86dyv2r|`yQO4SM1!FWS%E(UYRv7GxOD+S%2=nTTxf3Osjv6+FL@C&lXW z#je|bV{XKry?tlpl{>uM(GMd_x@Wg)z0IGa>Y=jn1jE-0iXT1%{GU5_t=4)s_ti`i zlhs!C%(%FuwkLarMPRCL_}ZpdSI^GteZA8zV6KJWER(>-WnPRQVQT@hmT4bJ5#y-6 zI{VQZ_f-YK|F)hN{_3K_ogB4o=b||>5gQnywuMAjW?v0DZhLKg_;bHj0VfOnSpQ>N zD^3WT`)|E_okRbVQuWQ#Qr9Gm_FXuxd%kMnO|JdHn^UtxGOHgmn078v>Q<4pSip37 zb!xhE*t9I!fbHvUrDcaq6w8!A|FkM4P&VT2Jh_mZS8Yot%-8D{ZHg9^U2to|M6axgl2`Ws z3yL=8o-~)GY3haH ztI~BWtC-m=$`@39F21*;`guLW^2~sRg$J|e=X^Z-{*L7gBUjraGmKnwpWD{Sq@4}g zuiheXs8q5j`dUhhx?J6c@4}Bat!TG60&Z}FgY1}g{6zs>ai=`Zdq0CUY#eM$R&;nr zU%7et<>hYM=t+|jP6$k$DQoJr_4tY6Z);_aOt0f-yI#!^xU{W8H?6^`TSeBUVrf&pT(@iLp?yD?j`i!`jFGR8VO=_F z*`{n|w-x`VeKTD5eCP9!qxbUnPxa|pyec|8_0*!p3&ZtAS3H{=c=qhxkJp_aKEM2S z;m_u{A7PuH+;$9#042j!TrZT}SFsD-uVr7qhiT)+R~D{Iz0%J6f%?jl+cv&kws0Pc zS;6D)lE+MT&pss5SJ+c|#yF)WuuSZ=eR|;fQ;VutA~@DmKbGG;DJ@`a*w(4#H;tw~ z)#+Tnujy#_`Vf|L=h}Fs7x>G6Ej%v!;raYacE?2be3z^FV_5TZsn#YXndrS$;Y?TO z*@iB-wQB0Ey!yosrSD?C8XV#Y$Q8O(^nnX zUB3R;c1hW_eE}?@amxN2iY?s6Iu2WRIPMnT`?EUN?Bm2=>6X$LJKQT;PWq^|irhUe z{%b}3boPIyYqcgPIBuP;xyw#y!MO!hk2=lovDW=tzkeOel)StLueqhoS1mGE6_j3` zSEYOXtmoyBV_y#QhcZY@L~JT-eH^(rYOeP@L+7uLM9wLLN*{?`Wv%UULAT#4pr?G$8#dmGkv2yc@46Vgdm)2F3 z%XzAZ-b{M-!13$qcJ`1J44{V6^+_jA20r)Oyy--FnA!O^H-A>I<$5kG%6hnM<(n$c z?e*Np1NZOa3gMRx%AF@yv*Ce5={*~Z%AmjBw`8hX_pg)Y-co;3I=ZilA#7#j!~E?} zmwE&hZL(6kxM5+I=;Z09cXx%R2DS<~aWHf*6D`YL*U!yf^z+}kkVE&rE_K{-ym$YC zmNbLr>lMAuGK@EPU*U(_2Stw zEf2q$L7zUhCR#S*(gtfn7i-4czr4J0E3Aedl&bc}7 z@LlOYh2J%g{W~XgLaF-8au%E6oWknzgL($A`pk@9uh+l$cz+cu~f#X2t|z zS&r>~iElnuExA1@-(~{80M8tj?xRi~9voL!hc7RDeC)^1yXWrgOkNqTKR3Q^W6=6} z;hoQaem?)oC%Uli*V?cjZ_PP)bw8%IoIE$bT`%^)eR;Fop#5CeH|NhkHAOFe-7led z`8iEh3rvgEY(BOa7JGPjB%GgT>*DS%EG+C?QexuXC!=V7uwDG`bwg#lInI*i8Cz;( z%gf81oSZ=WnR=y67ZpA}2HKaJc6QdqU8UK3_Hx@XB`%pE@!}$L)RqSMI*mW2vzGP6 z)_iEJioLtbAaBm8IczL9^7lD$D9-7tWxDdESnB>akA)|h=WUT)|6lr5l320*cVS1C zw;IosV;6RNPuKhSdi{RTwLwCHf{q~}BA%X}J9h32T<$mbw0Q{cD^sPEO#ho1) zr(RwzPu%?V@L}btVQZrVrKG%;`^|lEb+!1_)#3U@=boQ;{`~CK^+lVO%gJR)Z@9WD z>P*eY*0}ntLvlgESDib4RNUAnoA)7EG3LO#y9K}BW@%?SzRwZszNPf%gmUU`zq~xX zi4!O0+}rc>)2{MAKMFyU`k7Z&TzuM}b#;~C7Tca#hl5u}?N@4SY@E(~noCqGVPnLJ zQ>T=4b$J_}JV}`}d9tU6hk~8myv^z7L01GPB_(xqb}E{gP3!65v9YnqxVVV*?d|Q) zuSMrCb?=wEvO0Wy&ixy_E^bcm?`4U1FFQC<`Blw_t479&Cxt4W%WkdR9&0^SSJp13 zOrJxsMMLa2%L)eeXDLEo%h;IfcobGF+~*!|YGQR+QoiQL%=x9V(NDysr9rFEf4*Ek z|Higl>6tTUnq*(=xo{!C$=Uhkg@w#(qqiSB{rc9Kw5p~y|EZhOFPP^x@yVK;o71Uk zWHhOxgF{JKxwETF$=G;u*xIOzplgT@ALiud-knx$aG>`4$|lR}^L4jIT;UBV+m@Am zVZA($#DcDh5RDzTdkX?0BVWCL_x=9WpHI|$&&->+q5ZsFu;ishQD-978r0XFKMF&>#g9Ka+8wziLr_pqu%)Ht!tV0?s;{p?*Q{A;`y{pa`uh0ux3*^A++T0MHS229 zhX)7m)c^mxCHM9;fBU^<-SgYqxjbxbLMAT#_ct_q=CiYBf7`j-eDZA7gXFhSrFJ`W zqc^9kyiv54mNE&rU7i1BUE0<|i(CyV3NEgoqKSw8MFrQU8+a?x!KFP zf--MyJy_q$mG%4G|9{J)N<&vIDVuHcb;_+Q-4+3-DNTQwLK<3PcmA=^n3^a5Gid$( zf2@<`o(6_(p4BX)vx#Yq#=h9yWgl;*&o|7!XR~L|9?%xOW;WhM{`2iBDqj3AU$Go? zgK^2rAkglTh0g667n20q`E-@k-M3b+2zF0p`Sm5x)~~kKcisjKW8dcEa?PyVAq~IQ z*Uz+7PSoF=w(^nn(Zr1_l5FqSve*88_P^%duI&j2nM`~ayZ6h1*5Lnsx0~PI{;&Lo zS8uPZ4AzO?Hz)PlF+-m(NQ&F+p*e$kPjl&)erGpO|neW=DZU{r_B>uOZ2CRhbrcc6Mq0 zzArK!xs-m(eR*lp_ama`w9UicR$0_U{M~fvsH`SHm8Zso4741^y`z_-#jyR2sm|oI`xk+>lkaO!ODZS^IH5a+TZxuq+ijb z-l5brduQbLkFj^Jt&N^(k|`9uJ?|-K8RDlWCre&kIr%1YYGl-`U5U2k?@T~95gVtU zTjJEpwdczvZ_w`a)LZ}5WDd8>AKHBW(De92GYr$tyUlp`CG%>S#{0)71UvfLZbXFY zXurRE?yxiK@|Q0kyyeZ`vvIPj_dF#nt*#G{d&Kkhehn+$FF7|gC1pd(NuhgnzjKq4 zlO+w4Sk~|RmDSif)yVkazu$>ZPc1tC`Pt2_-rFv5E4Ezd{mUHEFe5cGXZ{So`Komx znd|ct5)QjbBt~r9)T$eC!QA`xs&n&fPjl<<0WEWTac{46{+^F*r|&L^)wQ#mxBXsK zcjV@@i(4{-)6ULvbzk}H;g)A-gVXQdt7QN8H-B@wvP@u@*q^`Ow=%w&U%zZ)ZZy-$ zlNYwW_WAezf7|72N0ry!xf3I%7jxqE`u*olPF4qnov@nEj+lU#k6cT|?2R^kc=P$H zjm?$)d(Yb$m)&#XP&~z3%oNh_b@3$+>&(aNCX2&L*oqsJa zU~_u&nRL6~H{4BEy|mk>ed5H42Q$;>J^Xy$KK;&)!aYBq&1RW$nD5oBWg8O?GR>>| zmHF!G>f@VIPv=$Gd0Vu_*9E?9IM&nXZ)aF-c1ZHb@#CKlF!O`9f5z2*4L#N`-=ALD z<+C2N!}D05?CE~{dB=`F4-X3dTTmX(I-#hT`~IWX@A&HK9=zv2cyQHSpZ#^;=I$17 z;+UQi*T7YfkS8{A{qoEIqwAZZcfGXwrmA;w*0n7Qc~3_ydwpY_f}URAzrVkWpPUeU zc4p?`yXE(Dzd;rqv++u~536tP`)mH{+S(H<0w1=tR0v9NFfs~AtgzDx z+41SV)wT#xCl1ARX?YE+ZYI2)5K?5k@IP0*j@9**KWEN=>FGah^PK95ljc?S$=RNg zEx*&ad$)D=wKWSJo7q5%u~Sk~KD=1mzbWOUkeE)yfd!7uXXZ`Pa46aGD*E;+(VG8z z@91<(NAE7vWoGAF61_c7CuYY4g`54e{6j)SnAvz1RDFH*=f~szkd;A4-)M3wwrJEV z`JT0mSaYFrmwsn^@z2kbeeNEA?^o_-JWIWDQg_Ui+M4u|FE0XjmA&;!NKn}S@7HRU z<<~!c`v$uD8MLC3N7}5Xm0Nt4t!m-i7a2SLmStSw2wOYpLCBpOU835cVxF0uFXig0 zP@y?ui)w#=1Faf;@+9TZp+gG4n0-m)F*mp^}8zWz)buQUfYw{f)U*nW;=8#1 z|3A=qPN0>CQCqWS+N!pvZ@vk-!x?moWME(*Xnpn@&8gY-|JOEM?h*|xh*~-6rm;}p zyCa>#Tk`MEyKo@@v?KP;oiDWvuTCW;CB3+_(|E3RdD_!cQ-yADE4FM9FW&wmF0Jw0 z<=PWompW$6Tlo9K_agmf$urG15qaBx)&2YVd`6E zmsHkfWo7NV{_orEeDgV%x%KxHoV~v1<1y)_|Nb$o3Df@k{QPpSsal}pY*MAXr}VNc zU$n%;_wmDac{K}*8ArRtr)yf=-JI^f&vfMiult>yoj>EA_hidEEOzVt@oaYfkAJ`4 z&$O*Bn|WN=i9@l=w^-qL-HA*4R?S~A_r{F1zi)_d?T*S_yRB?}+4^_M*1Lk2`(-*h zI{v?ZZ|-r|*thjE^}N5O@;ZL6n{qW&@H?w`!F{b@?c$S0XE&K_zjWowp76_Jr;9Xw z^Rre?&DLuA-Lz=N-7P-F@d5?Rks&jF{{85?Ha?1rIX>auc{v-Cv}ZN;3VomF6`y;4 zqm5TO?Rw$&x3|-ob7ZZ{&RqM=yzScB=>KnPg@uH2?Ck8!4tzUfeE!bmAK$Z%_sN>6 ztE=Ds^Yimtt95r~3#;dB`}8z-+pDX&+geyQub#LERB@W6r>94UgiN`6?9Jun{k$7` zWh_7CzrViFnf>+>&&hdz>*H$QZN8baP0_jS#-Bfba+dqg-}d{4l9E#S2J7-O3;wOk z$qqlYy*%}}v}Vlil>1YUvuYf8UUROz=6HBb>h+DqyFDkX1uk%4Jk}?hU8ec{?B&ao zH>I8iZLawC=4SEr-+TZ6`#nW3)+#z{MfiHT+TY)vuHAl5$=233dYxi<*{3Cj#jl>H zpP3`3ms93CNjzqES?|Tg?w>!M)(>9pC%e1%_U`h0hG*yJ_kY!6Z#j1KsGywOxy|S8 zW-rZt+VUb@8Fd(Sy1%! z)EukQu8xk5-Er0?CQ}|A?M{Cgwe#uD^OrAAR&;JNNIxf2`c+hLqRhnCOsi(kZ&jOL zQCJpjWq)?t|BJ@&Kj|^DTxhqu@n&vA@j_N^u?J6{94S6;n_i|l^V;t6e6MLbC%Z(o ze|$VH|G((>mdwi;mzVL1YKNWKCUt76w)=9wxic(_)3(Jr=k1pCtF0CFd;0I}9Lvee z=hw{=QuVq~`zCI06{A7hPa07WacThHc*4=Qr1CWAbsnb#Z%Vy}e$PvfN+#;g#FBIhMP2 z&4``&MD_Xk`RZzFZRh4%r=R{|TlM9@$&;O_r>7PE{PfiR?zZgfdXFAG%DBI8Z|u6M z(er-W*xF{^-DUdv+S=3KvO7CEo}6mn`f#HA-IT0Hr>2Dm?I^ps&v@?Em1iZ68O(Wj zL?HS4#^T96Jv?Ul_k1EEX53tw5_x}LEhh&@0%#kyF+u7ItDw$=P4LWsW%3ITx zwzi_j$9T8p-32)|#QgBe)!J*KmltS#*Ecc}GB-DOa&p>~`X^|qm!OoCS5%Z#x0vp) z%elqR&n*RA@VaZ)t+!P>AMWH|ka~I==sNT%Q>Mu5oY&D|u`WhBV57s|lk;xmq@1q1 zVqQ7f&18{wtf$Jwea+8>Hg4RgqN@7w#p3>1v0l?EtExbETdxUwy*5o&Q&V%#|9`)G zWGs!`vp6_77GzvpBx6~m;=b;A#<@9$hgP<;=iFpE+BGwF;uBX;i7l!fcI5VL>)Y!J zi#gxRPye}W*)q^3>zlRKu6Y&jn15W~|L^G6*ViozAG!3!2D`Y(1i#~5(crGg-E05h z$(d&*eCM{luM1J1^J9|!&QqbkE?r-j{9LTCu&_aJ&8Oz+aaEm%TDdo8TvY0lu{?BU zrt!+??RuaSZ;IBmH8e1sn{Piq`FgR4d%x3Sw+HX|CQf|tKEKR$QuxuMM^k?n$1V4p zs}Zn(0W=6?QNYlUzyI$vuc=z8r=^>AKHRzf#{2gYFMs;GxNM4E$G3uku{4H5>e0b@ zotbm)r`}h#W8z5AD~>#q^vv-5y5#3l!BrXhaB@<+UtwJ-g21)27wo>(hQ0&uedIzq_lH zIpN$K%k6b%*QJ&0e7N)c@#E|c=j)Y}CcQ1Hbzn`l&$>BnT~3{4>y#VT^KGX`uFW|5 zde1oqwh!FREBx-9G3p@Ms7hfMgeyq8Q zCDq)}@WKwmDcbDPW*N^yHm&oRsATzRPI>Xn_tWF+PEJ&Izp=Ae-QV_W$hKI0bDQss zRsVzqC+197XVMbO_^?j>9jk86oB2-1N`Ld&PwccgbJ*tOWR=M|_YeA(d~Q9mv-r8s z>Vrp*w#L`({Qls-|M%~oKPP{9aPY^^pHF}AG@VUTHZu#;zwjpIwpqqC9=S@EYik(o z?Kf*r`m-QnW0K{kIpMp@a#w||^@@p+IdAis2Q<=xamU4GV{*;k)3k$v#xK9Elkz)?o^#7UU6_;^6ZrX3!SFu$Ip|sE}IeC z727LkJL~jx{ows|e`WT*`~UB|y^yf*%E--WeR1ZX^*T}8&C>k$|Cg(ax7C=G>geb= z$D*)lvbulT@2z?BI(Jon&)Yq>_E-6ts&~wwfg0B?k%c}pjV$YO1qBOrD%BP+*#z9{ z{59Fua?1lN_h~oErM8+Z{n@oX;!M&qZALQCM^tH?8cxIv4Nrc=%M5C^*PtqTPi6vDYAU-E z`wD#$n51udFiYJi%`paTF7lgeRruk7BNH?8Sv~dhn{MWWtdE;3Wt#QjsCfL0SigB& z3lzV+;XH58e|dRx+-t8gP{+BWw>S0ox3_82C+W*rm-T3cuG)}rkZD)R%cL?(C8bIG zU7w$9$l849Se@pPx1P)28p+q3zVSYEov8NP%=7(!Ja`O$Oy0hGTg2Khxw;>TPEJlU z43pb#K7A7T`r6vXp{v7=9654l7VpI0#>s3v5)97mhwA?&mzhqQ|Mu3_?p>v?Hd0pEGsW9@ia(c>5=75J~kt^*P`iIuXOU(sGFNoyQeKpJGg%TKd-G>S7#Wdaxt^< z80?l26g>I=Q=S9sj;dp)UiF1*MqO@In_rc<@p1M9iKGk<=U*55zgL{EW1g*GYdd#W z>FY;t-=1COJ9|UK8}Vnd2Y zls4ay+Yn%KVrFgdbz1<{_fps`SiGa{gUeM?|9_xVyf4_3wC4s@}B?lvV-FB2fFoV#ZI)C)X)HGBtJgh zzub4WnTU4SnKzR@&EXVQ+mLZl3A8KLYl=o9C`mk$IQQ(OUZB*edBQZpeVm-V(*ou>tc_e%Y480yPR`7-_zai_bqmA=S!PD`So1u^1fZAuY(pk zv0hsn-9CGEZT+@So2Q6WywdFGXmIWB>D#Mh`Sw_^H0ZwXW_ErdQBl{ImzJK@(>(v< z(`o&e7Za>xa~%c*`dRSO@%A?r|HN0P1lPB)gLoVGADsjXh(AA zIrF*7Sv=ns)UcbIef59%=pfJT-q$U{@t;&#H5}5dCcDkLd(7Vbs0wT?fZ5^W^7THi zudU6zx=M6)_I_F>4GsS_Bq z!+r$r`=h59Q!$B+SL(y-_4{YVhOIM8KPO{V{?6z9y}dub@Bg0*j-iH6z79v3zN%LS zE!kx}@%+*WHP^DXFZ}x#&Lsj+?cG+>bCYnRen!T!*5pm ze`!t8<#u%Z@UT5#m&uvA+=Yc3>TJKfdg|@s!jhPn2s*q92&LF+h!h?nfJW% znPGo=<+VEI*(ydxla|k~laiO02c5aKI&AG3Ja#!p> zX})y1QIoGHb0XpMY0VpNeyIH{wmB})_QB@-=83)Eq;II4oo$}}|KDFw0d#F`^yRhD z=6>_-a?2tuAKluT4Qds+%T=~KKHk4M^Rk*-zuek_DtWs<0#)By>i#C&vuO=JDJLnp zAy>Lbg7M(NfQ3vvayfU*a;4^2u~vUOQ2#Ia%#;6@;~(19{t^%tc0Sm|x-x#h-QQnd zmF?{8e(#?UlX87s?3IqNEZzC0tgZNucbAlAon`ot?li{df$F-0}V7v8l`Y_c6Rbe7&I(&ZVy`GF>ww59B)^5_s`#M=Wnk1 zn&sr=^yA57{}oYNSKUnQ?C7{NrM_?G&e_2e&2Rij;_ClazWms0xiV?udbdWYPnf9*i&5YXK z?Lk37KfYY{pJ`KRq^YTC^Zicom-qMQvw!wnuD|-~DNybD<>lqb-DSF^udk(^nPJGc zbE&h7OVQpx@&Sx}dbT>g{^Sf{7-ib)cbYSKR?C8xo!Y;qNH+S2VDI%cb zVBO_wk9>T5JoDxzRsDTGlt7bTckkBSKRjnc`gyr$=jNWS|NlEa$4vUX-EW=4ZM=(P zb{3^gpZ5I7@x#gel8#9?jW{?BcPpJdJ!x_;TlDHMN%{2iQgh3rw-}^(MsH<`zdvV< z`plWe=|;7`O8R82-7YWlt$f%jo^gMl?Y(>VEWO#Y+kf+uAj?djAdhcK7)vVO7 zuddeo`FPyL#pS~RX8sE+gVjNUe3zH`7UxFX-Cu9-JzekV>h=2`otUT`vNEXk-{0St zcbDh?`Sa(Dp1!|T#f6Bt%#9MpF;Su#GYh}0`1pBqmT1n+q&NC&zP<)J&v8TAS*bgB?`GcKrW?DfWMS&*X+NH&WbN~J@0SCebDg z9IL*)@!Vhc_tQ}?2|>Y=-(}PnFdgyne7s!pdWOx}?xNh7w`TA9|9EgHZdoMC9nlc{ z&uZ`UX~ya2K=T9pe!bEzdwZ*O`gCzcMa7oZ){A>8i$M*uIdkXwuFn1Z>}*SWyRe+x zxt+z&LG4bEQ?jqGyRs_u^pstny1%~e)!WN&%W}Uq{Y+8ko$f6riw_36u;|3|?f=8n z%H{a^*|AG^`D7PF7;av@XZMdE6`-NKX*!XI!0jF#P>zPoiE?sr9Xfsb^p;;q$;mhO z)mjS*3a*LYKkt6s@7^X>?n^6!)jE@Y@Oj-x-)h{nBIA=QR z%!frK#lQb9-aD~(%QDm27l%uh-Ojyp=hc&wleZsANJ&u<*N;1L`}XVw3ly@hu5#U) zb(MpMXGzi1QzBX+C-ScQdV4=UF;N+`bby(iPe4}Ix1_}6`MJ4=uU?({>+9>wi(I** zwq!U41Wd5{bnD=n$Pb@RfB5nE*v?7wzP&bA`+4Q(=M8yt4ZU~e$*QRR+j%h1gX783 zGgBr^a7al}5fl`3ad9d5^P?~(CZ^)W!gkOGbPbJ;0|y+mLRY!WG)jH*t1Z^ci_5)F z<{`)t76lD^tG{n5e;?;J->!G_X5)hg54N*&5h0e@0ZJKH%Q3Jf{ydtS@u?np_N;F zSu0o10QO`S_Nlot?$P&Mqt? zvt})~lG3Djiv$PO4F~(ogDkf_Vp~|emt#fp{s~sil6#JLpGh;TeUZGq@bj#m9v;vs zdF%K8I|bT7U-!oXx&-3ipGv*>eP^z&4&Pb$m@P9ibICHZ14o~x*VG0xfW{u;;^Kb% z{vEs~!tl@EznX!ISf*-+@B8|2<;p!d#b32-{%+a0<@@LJz4yESTs+z>AepIiH+Caa zQu4x@N)B#gr_6{Mf)C#IDvSH|otVl}YpPESdB z@bYD6dpoj?7vK z-tA|ZgDrNe&V2^*bn5;Izr^xC=KnjJB=*^&|90-3KWCB}*Y7v`X4$pVZ@$^I#Ci7l zZzQjLi{1IMpSRB}pKZ11t81opaZb()(|k8;iwFu%w9&g&w^FBn;|_<%nQ=LiGn`z` zi_ALvZBYgD?;7i4#`8|cEVI7LsXnL8WXtItN;h@2xU5Q>7P5HdRSUY0`X)90%5dqQ(jRdv2JiwDRgNxll4q zTvh7U^XN~E@&$dxTNcaCzUgDS>Sk)p#5bEN48OceHQDgfyrBp>ftdRI_z zLt5{~JG-+&D_&_Pzs&plYr(x_km0d1Wu5QkZyF{1{t(i)evjXY5`C}sTg!hZYOUO| zMD@7EF|lm{^FEbHn%iFzivJw3){S{d`Mt)2&ArP!xD@)7l@HI*jo*5TV`=sGrtRAe zy>IQa-IB|#>OCuVX-7wg1;_E&N59?0(lZQh3U>?VRB5(O=-;bxS?RUnRbl_I4NcEX zmP?+!aVG6lz%f42?i=n&N+s{}WLS-=&At@g*%!yBs>o=TXEN>Gx){#s`qIY_w6sa( zhi%E>%*#s)*Hltc>hoayS}vxZVQ^Ad-2aA+LhCX4%D`=**POE$xdc2_&Sv^0OKqNc zc8aU??;|zs{L;UDA3s*Kxf5|q`{(sW=3_c9Pfb16vvRWVm6goOZW7g=@>M6^aJjm; zxQGP&Kf_ddOv-rW?0CP04@LB~N;dg>#Ga0tb+O0b(2XN%UIB;rSi4is%`!c9(NI+D zz&zUkH{stu{k*ygdCsf~-B4vZ$1>Suf7VT*xZ0~fLVx$Ty11xp4|MqZUnih?i@KOP z_wBYN37e~eK7L%YzV!3)`5sD{Ucs|2_W0&3k~sP%V8e;Mn{W2mF3aDS$#Nxfv%~R| z&*a_vrG9&auQQR7y}N_aG)v<2j@w(C*?4>Y-cwRiQrbC{>DAnb1=phGc2pevmbmi9 znt+wX*POEgyEZlQnk?kh%{a(r7SN(prV;UEe(YYZz17mkTYctm9B!W-J254+YFDAj zg;k*&l34%zF&5EcIXnCCmQ1(Fiys|5yDrGZ#pTI8%?1B@rPfy`Y(CicaAick!_?)Q zf3_I0U+C3meB zUkq*KI>z&IOXjh-r10M+O5%cof+q{PR{U4U=wR2A6D#ZUQ8hj2wl)0DW}7rkuZgW#ws`pCQTF^M z*E;iTF&+s9e>=|kwQO;5Y2hm0AH52FEHPttZ29@Q#`hvJE*{D#xU$Ri$B!A{wB7Mn zbHTmEUUTmjeBZpGGC^zQ^IVg8&svMc)Pqk4O)EH*=_GvX(lpaG2c`3Wi|FvZeHB{q zukyz;>BX9t7C5GbtNefRB2c+!T@>qVb7|w{S64gV-*+tT(gFoj3n4+liGR)~ZN8b4 zCO&ccocmMHwe8asS@p{2a%9|&pJ{(ZA3O40nzAfpA=m22v&A%>9{pQ)hAA-Y&hcQi6P$GvuX#pH@Rr)Hfyx#URHW}CFoRhwFMWgbiTW_mGkmaPbpxwyzRV0quhKgHkk zS})&uc7!weX6bajV>6c|CLX(YDerDia$-_);>V;H7o8u5xVX5;Oil|he)%d>ThMm$ z$sLS|pZ8QQsJXWJUt!EG?`G(0zVZT$Tis^&MZn~w+PZ8>m%>1|0 z{GaKZ%{I?G{e-+U{44|=S(X;`gs;aI;pOjgztnu>SxG~d#>v?(lg(t%LUTrCR-(RUbC+sHS zsUqmeBDyl8-K*G~^~#x>8yM%+-HPDbRibJ0XTwcV%Vo^$JqA*OjI+%o=dTVve#8CN zKHHGBSy`2!3|iUxZ9&@9?&+;*oA+p5KGe#quk!hJx%noWGzP|;B;kKQE>Bq|^K65x z*3>^o(u}8lZflh^F0THjG3VKmDI&@}`+jLn(c|s6VG3UE^zqS#0!0;-1KV;9YIYo2 z+0oH);_n4RKD0VR>UNyJ;>Q)%rfk&?Vp4y^7709Tx!h)EvPkfC>|gBO8?dWr>BS2#j`6MtWS&=fEMnK~1&w`;pcQB* zwOB){H#(d(x2agLNH}nD(9Tb@r?vJfYQNBbI+NP_L_mk#Vs9ErNwD}8gV#dIsr zo|}72E;v0sxlPaF#+$BB>w9<}|E?{5`R?A{2XA?OXCK;<>87C@cnA`qpTu=PZryw; z_D;sm3+HM%wlM4jGTKfXPd8CY2oWdh+??9gn88 z&3iTeWL&fQvuvW9_^u6&yfuf-w=7vYSL>|o6_uCo9z9+duFt{WK2bUGOGd$^Xz#Mb zt%vs2ZlC_{-HpVO8@V?w+_-&vr7#N{q>Ae}93X!GP08P`ix17~;@NudeP80keO;$_ zx+B})7sthG4*H~hk~x2KWzc8M1@~?)^F1c#E-oIi<%ETO@Fq3On=k72WKI28_)Uj} zMdJAWE&2RwqZ-$*zZnXe-?Uhg@z(LITV9>mp?x3HzW)d@`{upymP7ff{m&-8{5YpD zO>DD+@t(m1h=zdGWT`b9;{AzWrBM zALiDVSZJc*!Q1EJ;^I=o%z7m!t+3H5zdGoHWBQ_dUaC*$^zIV2DLnNgWfd!TvZS{n zmtlwFoM$HT9~h^t*}^j|=INKrTp|rCG**P2ebe=+@ALD-yH?55O5R3!cp05jczfd_$5KVb z2dnmjGL+KJS>F~s+u*%FWy8Z(kqwTM{WssU(QM+7dtT_o@i2SeF>Zb9&{>;hYWcIO zc5R$f{-+}O+n34ypskCminjOg{CL=Y+q*nD>A>a7HRj1aXnvrX{GVG$){rPZZe58xwvJiuIP#bT48}LN@c4|o?8?-*w)gVKU#((;4Y=5~c?8k${QP+ZI?J+HVvV!sJ=kpJ@USHrPy4X8^s#aR~ zl;3|g9=!PM?6HdmrLU#V_9EJ$f`Zn84yLzX^1jTGozj#asXnXbRjdEWGx7zMUBO!x ziF&GRoORXa)Z(%=Ce@Zv4tr}PNo)pSGXRk}( z^yW}L(>FCu-kod3#EBO+t6Nwe+*5gB%gURgGvD7ZTKase`6c3 zs2`|cmuXE4C>ECf^XI7PqWhkUW2D1h{XZ@&zW&Tx@2!cC-`@W(eZt}1^V&HlWY>SH z{?btU``@3P@%62bjvl=J{oC`H*xuT9Rj(&GwKpF=pWo}|;of&(ispsw>u-ua-P6Ky zW5>lAsc#wG9%lP@+@`NiZ>i5N8U3E++DlTpF!8bPzG6ZZsap*)aOx2nh z8+y*N;6TOX#HU_2c3$RKz$-1aaEmj0#S2AnM?`R9j0>ab_FYxSz|-_4C%oovw_S0? z@^i5FM3+x2{vQnZH_v&xOy0TpQA?r8iTi(_?A#^gSoY$=oYklAB_%)H`MhWERAqOm zg?Cgx-|qh0@+9T4#Ej6@3171;irKovOw-(NZ#S>2eZaVRwTPgg;KUd&MpN_6OAr6+ zzx?Cl;_NAzFTMVH&fD=bE$`%e|35C#w;r`g-~Vhob!E=;toQx}21kzEv0W0SbL^wi z(^F3~BFi?XaDI8uUsw0x>GXj0^KOc!&R^`_d(2Hc+^NE1$#Umjsbib&etWB^apK2k zkbQzb*|}C!9^Co%SfI%|J25A_Pm3-bJ~vb9IZt|qyY;!kKG8J`%(lLbdAWDC8E;(u zT@K^_^Ct^mS(mHBc{Y1pOk?8Vgljq#-y&z&{XPFX>vQv$l8!E;G|%ug2H&oWfttJb z<90=_nE@$!J>-@&%nDx;yJ2H#0N3;KrNPB5?EGJg+I`M=sZMk;-?edK@0motyD!rI zC%t!!nR8L(WY*u;xq5nT4R7z;KYx9y>qEhd%g0|_v##D|SUn^D$kBthwz_G=Zs!vc z?qzc~Pxo|o>Pfu`F2f=hG|XE5=ibxu^G8g)%u1IYO!2?NeW%{*tU~j|o)n|WlE)0x zj4n>$+kbY}!D+h3CMwrIdBc-_UaDIBbJLZO$2+F<+clk=`|z^=!h*!jt4~R-zWQRz zo}#6KUdc%Z4l_%c7&yI5?suGN1nDp-{p?}NiYuuLw~CJQKAO~c?D8HBsX04U_s{<* z$t>Z(Ze`G4S@AISx!3=DcXodG^SOSWYiXI;w9a+0vllN-i3$<<@+R|)f#2*jo!4hq z>&3O4@JP0Q*(K^Wd3n*(p5ka{=Y^%&A3hrH_5wE=j*A3*UbUs$Y#YDl!#CGTR_%Rt zaPi+e8&eiJzcJhP(V{ihbY@ACh+v0D{%dh4WHZe1~z_vpRI<$lKsRm^9r?%e5EQ}fQQ zE9Jc0i@Uci^wM92R6Jzeti7vz<;o4Uy9K?b>o!kTU+5v2aq9}lQduj9MkZ)L@@ZK; zH<#=B8?hiuzWmnOFGs6nr)}SL>U{C~gR%FDc9fkwcFsKLe^IromXNE6=}OOJsm%?n zH{*Z5-&MYUFZVoNd$M)UZV2~{N zKG^@@wY3HRY;@vyY^yZpfNIr_ohHq*{O?#9e|?-SlK;S|`Q*F`);~Z0w(BwnTWtHp zw$-gF;A`dg{XG-?tePdy9IrVeam--W#R#LzT0iWTER{5_IC=6|NSoi|TRL4&65QAKE|1=F zBKCebC^1d64sbZzezdn=lbh{*Y#>2RJM({t2r}Ud`-mKghDp+cy8HiKOTg> zId{3?_D#QZtHx1F!9S~g7`l#z?}iv)b$94u&l!%#_7r{M1<-t1p*Z_kNYkPw=FOXuss zlV8vE+aH#cdu&+u*nHn3?L!>9m%ol$8wNU*6SQKZ?%&UJK3S_H3!U37s=w)Qa&nee zv~U-&Rj_sZIK4J5E^dlOU{jZ<_NNQZ{DKk^9#>a|f>wBJYq@?Uq~dpO@--8aD>wGf zls@;z$Fot^x+n5d{{Gg>%X@8?>PAa7ZgJ)Q@YxuWEhqW}JDh!gF2`irw|g)BZ$8R- zxG*m7iqzA>>&KT*bhH2UQ8oS(-+O~O59@dOyScFi1_pvgq32qcgC>@fl9clD@2?i9MV-n?)7%D~6pF5PA0ExNu2+$!-9(^&8>@b+yB zwr9^S-TnPz6R6$o@=1vG${(F)cTMVMRla@qP$c==*^_6Tc2BhvS@Gw4Zszq3ZR;ds zHGgJ63*ok?Ni=lMJmbD>q%-@-l9&1!L;zw6))UR77k(# z7ay#MwN{>BmX|Y!UmKK$C!N<^@GM-s{#-)n?$tNe{I7{u7yqF7)aCb8yB!sOOZTpT zOaS@JGU+52bZEWWJ|Mz{rPV}}Or&g|u>*MX& z_+&g5I<@BA)i)E1t7M&~*Q!3h#oxa5Q0x1@R>jW_9BAB-FCVh5=6(O>sNUmuV&DTg z&dv*i)j78K`)h&nfA4=4UIqr9Rh}-6ArtqwFq-bS+VzI5{a^Lmmj6qW_a>g1bn8-X zIqw?3a{;?rwSDbA{<{2p|IcUA_i8@-_Q_Z}?Jj#OVU)trD`k4Bas2^1(DC5y@^vTH zL~h=2GlxgcW`?43+o!kN@A1g-@Y^sLr#s!)`?a2_M>!_0;$TKd%Ekj%R(`mZUH^Z^ zla%E8*JqdRetu5Uc)f14)WR*H+8@52y>(p+9E8U;7d$K9R+4P?_0G4Fq{WvyZ%;nh zn<6ci-m~G?ar;{CD|M%v+pBhOPCqZl#w&H?+uPeOudS6%KGvgX!0-QBRZR^vfv4s> zt7Y=#$uT>PCObCk^hl>4JpFpUeEsEfb1y9IHvBzn9-p7zF`+xX(*LXOFLuwL@4YLP zJ0->8>#Ob4-?6c-JU9{5UOyqPvA{|y+A79khU1-gB}t2oEac~&`|2X?ckbAw;BMAF z)1Uf}pYL_sTlIB@RjJn2?CWN`b9Q(3_ou(PQFvy~&Z%v@+@RI8S|KYw^!I!Fw{r?7 z{Hb_cJ>_G2?Or{-f{#i&b{*Q5d+gHP)YA_xC?=mQ*qpZAIrCuC%^ycWjrxu!xm+vw z&a+MDPcNtoXKOzsY_a(-o4L`thaaOv^!I$znO0+UR9sltd41eoi?TNo@Av<=J8%F0 zPwe~ZKNcl#xvIbavz&1+WuwDlw+-q2g>6}1UtL(%E9jMd-7GB<)UE^|o z9U8UH$$W@AYJ8gM=Pn=rD4kDByl^HlN5F5s**oh*rYmb#gJ#v0l#1+4nzcY_9kk%#-{0S# z53PA^tG?w|!K6YAve@>a@GSKEd-RNy91_l$h-;eV?KX2X~+w3>C zd&8^0OZE1HOA3|XEk~|T1g-4ukuvS_xBGcy;bBb&(8L}8{R8**zRkRKrFpXYd;K}P zc1hi>0*8spXORHekdzb^=XSo-Pft#Md42u-o1&uD$H!M++E<$&6C)P1@ll&*rx;Rriz4*2zDv!TwYJPY!`Bpn53wYjYe$@e*7WVPsvH$ad`QE*I zGv$_7eSP)j{{H{--rLvxshFl0TXnx*(lkp%Qd08FJloknKR+*iaDXu=Ctc5L)QFaUJEgt;!`JKa#V;->a=rQx1S%3H&RJl)qEAgpsp)99xN+{S zEjq22XHV0KY&x5^`zz=gB&H2%XJ^^h?#sTuF0$&(=JR%^8yJ~iTv;j1&L^XwsoA+U zdVA1fH(pQ)RZvhcZT~d;Sq6zr=gyt$kup8C?lCy_PTbX8U^V08V9($WNi)Fniaa)`{a~1Ug@GA9}+<~@*VG!_4M@xr?F=6es--cv>J3tanjMQS&pKh@I1-LwSrH{&Q7jD$+c@njOVkRyLVq+?9M+;H~QGo zZt>2Z9?)*4m>mU;@9ys2oPU2`&dzoF_uCg17Tz@41}Y*u?ksC~r7&soWX2DlJ{j#4 z`dv_1xG-{anoiV~j)#ZaCr_Ms5VR@bX_TFvUCiDp)97PjAbTg?7737bd3dOmaYx0+ zMJK1;+5h(T_WQ4%RIB^WHe-EoX{qV&)FF#+$_E^@| zO~udsK;d_7ZM0?SE0My&!iuUYAqj~SkNfSYcs4sjsiCO`8r@H|f4>cISF#&=m}z z%s=1${+pmrEt}KNZ>srO6j$|9b+b1($O<{QR`4xxXk@ba`{lCFT&t;DwwP=_ee&zS zzwhfGzkh#T*xx3xOcQJ*pCjYdgFVvbeJw34YX0+b$~1T0^0)tcq({cS9v&0W+Dbt|LHC7f zo_!~d9&KH}|KF@FTTFJ9yj=8mMLp>99MH{{hV}nyT7yCUn<%ra;ne~rCZ>puNvxn- zFgG5T3-(|I-Fh5X|F;yh8@QcM_Kco8s8~MoP-B7B1}W354RwF3%HG~`-Cgz;l=g0_ z&ODU1*)Z`C3ux=3n(wS54-Ph;)$;`FQOx9D_2DqT{e^|j?04?ojog+a$#4H>!%fwv zGp0-tsrvrz?DqS0r?+HYesO>Qe(<`zjt&d0w~nGK;`Ulyym%2*9_%W8{Rwn&E64k2 z7kBsI)nU3y%F3Ml{NWbh9B4R`X%)k9v%j}xA=Ja`=?)Abz6YsC6 zc>cRKRXZHi{<*x|UtL$X_uk&>%j@IqDZub7|&dJGH^YiKSnja6_=UA0?sn4ru zy13ZgIz(6lvi&jEbL~dDzTv_u$3F#Vo9>7Zr5~8H647$@|b@=*cS5^jBR8|IVPV;?rb+vmyfB?VU z4~53Y#)^uHl%G{$tEYlW`xh4!L2JT8LPU0#y;U+Z6U)!fKXm92=q``k+uP2DZr%mT zOiD%mA^}J1Kt0z*ixz<*(YpNIlM4%-mn>iY_{kHOokdSILRX0#?G{&uu3&lny1Tud zJufe>qPn{H@2}EHlP7P4EMVyt*B6qO_Kt~>S?)jo*@=nDOO`HW4A_+7nRR`g@84fv zSB9^bJ9zNmj@`Rw|B)2{`EH_4fWy=`AXE6{?aqKUGK0F#3*h{?E8Q%_hb%xpET&0|SGntDnm{r-UW|!}5%H literal 0 HcmV?d00001 diff --git a/doc/projects_llm_framework_doc/llm_sys_en.md b/doc/projects_llm_framework_doc/llm_sys_en.md index 56232d4..2469fbe 100644 --- a/doc/projects_llm_framework_doc/llm_sys_en.md +++ b/doc/projects_llm_framework_doc/llm_sys_en.md @@ -6,13 +6,82 @@ internally handling port resource allocation and a simple in-memory database. ## External API - sys.ping: Test if communication with the LLM is possible. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "ping" +} +``` - sys.lsmode: Models that have existed in the system in the past. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "lsmode" +} +``` - sys.bashexec: Execute bash commands. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "bashexec", + "object": "sys.utf-8.stream", + "data" : { + "index": 0, + "delta": "ls", + "finish": true + } +} +``` - sys.hwinfo: Retrieve onboard CPU, memory, and temperature parameters of the LLM. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "hwinfo" +} +``` - sys.uartsetup: Set serial port parameters, effective for a single session. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "uartsetup", + "object": "sys.uartsetup", + "data" : { + "baud": 115200, + "data_bits": 8, + "stop_bits": 1, + "parity": 110 + } +} +``` - sys.reset: Reset the entire LLM framework application. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reset" +} +``` - sys.reboot: Restart the system. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reboot" +} +``` - sys.version: Get the version of the LLM framework program. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "version" +} +``` ## Internal API diff --git a/doc/projects_llm_framework_doc/llm_sys_zh.md b/doc/projects_llm_framework_doc/llm_sys_zh.md index e51de20..73c41c0 100644 --- a/doc/projects_llm_framework_doc/llm_sys_zh.md +++ b/doc/projects_llm_framework_doc/llm_sys_zh.md @@ -5,13 +5,82 @@ StackFlow 的基本服务单元,对外提供串口和 TCP 外部信道和一 ## 外部 API - sys.ping:测试是否能够和 LLM 进行通信。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "ping" +} +``` - sys.lsmode:过去系统中存在的模型。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "lsmode" +} +``` - sys.bashexec:执行 bash 命令。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "bashexec", + "object": "sys.utf-8.stream", + "data" : { + "index": 0, + "delta": "ls", + "finish": true + } +} +``` - sys.hwinfo:获取 LLM 板载 cpu、内存、温度参数。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "hwinfo" +} +``` - sys.uartsetup:设置串口参数,单次生效。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "uartsetup", + "object": "sys.uartsetup", + "data" : { + "baud": 115200, + "data_bits": 8, + "stop_bits": 1, + "parity": 110 + } +} +``` - sys.reset:复位整个 LLM 框架的应用程序。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reset" +} +``` - sys.reboot:重启系统。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reboot" +} +``` - sys.version:获取 LLM 框架程序版本。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "version" +} +``` ## 内部 API: diff --git a/ext_components/ax_msp/Kconfig b/ext_components/ax_msp/Kconfig index 88d6048..ba264e3 100644 --- a/ext_components/ax_msp/Kconfig +++ b/ext_components/ax_msp/Kconfig @@ -16,4 +16,26 @@ menuconfig AX_MSP_ENABLED bool "enable ax520 bsp" help build by AXERA! - endchoice \ No newline at end of file + endchoice + + choice + prompt "choice common version" + default MSP_V2_0_0_ENABLED + depends on AX_MSP_ENABLED + config MSP_V3_0_0_ENABLED + bool "enable v3.0.0 bsp" + help + build by m5stack! + config MSP_V2_0_0_ENABLED + bool "enable v2.0.0 bsp" + help + build by m5stack! + endchoice + + config SAMPLE_COMMON_ENABLED + bool "Enable sample common" + default n + depends on AX_MSP_ENABLED + help + enable sample common + diff --git a/ext_components/ax_msp/SConstruct b/ext_components/ax_msp/SConstruct index f8cdcae..a77c7d4 100644 --- a/ext_components/ax_msp/SConstruct +++ b/ext_components/ax_msp/SConstruct @@ -5,7 +5,10 @@ with open(env['PROJECT_TOOL_S']) as f: exec(f.read()) if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: - MSP_PATH = os.environ.get('EXT_MSP_PATH', check_wget_down("https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/linux/llm/m5stack_msp.tar.gz", 'm5stack_msp.tar.gz')) + MSP_PATH = '' + if 'CONFIG_MSP_V2_0_0_ENABLED' in os.environ: + MSP_PATH = os.environ.get('EXT_MSP_PATH', check_wget_down("https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/linux/llm/m5stack_msp.tar.gz", 'm5stack_msp.tar.gz')) + SRCS=[] INCLUDE=[] PRIVATE_INCLUDE=[] @@ -18,7 +21,8 @@ if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: LINK_SEARCH_PATH=[] env["MSP_PATH"] = MSP_PATH - INCLUDE += [os.path.join(MSP_PATH, 'out/arm64_glibc/include'), os.path.join(MSP_PATH, 'sample'), os.path.join(MSP_PATH, 'sample/common'), os.path.join(MSP_PATH, 'sample/rtsp')] + # , os.path.join(MSP_PATH, 'sample/common') + INCLUDE += [os.path.join(MSP_PATH, 'out/arm64_glibc/include'), os.path.join(MSP_PATH, 'sample'), os.path.join(MSP_PATH, 'sample/rtsp')] LINK_SEARCH_PATH += [os.path.join(MSP_PATH, 'out/arm64_glibc/lib')] REQUIREMENTS += ['dl', 'm', 'pthread'] third_party = ['drm','faac','fdk-aac','ffmpeg','libsamplerate','mp4','opencv','opus','tinyalsa'] @@ -31,6 +35,11 @@ if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/openssl/arm64/glibc/lib')) LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'app/lib')) + if 'CONFIG_SAMPLE_COMMON_ENABLED' in os.environ: + if 'CONFIG_MSP_V2_0_0_ENABLED' in os.environ: + INCLUDE.append(os.path.join(MSP_PATH,'sample/common')) + SRCS += AGlob(os.path.join(MSP_PATH,'sample/common/*.c*')) + env['COMPONENTS'].append({'target':os.path.basename(env['component_dir']), 'SRCS':SRCS, 'INCLUDE':INCLUDE, diff --git a/projects/llm_framework/config_defaults.mk b/projects/llm_framework/config_defaults.mk index a61fc04..5517ada 100644 --- a/projects/llm_framework/config_defaults.mk +++ b/projects/llm_framework/config_defaults.mk @@ -23,3 +23,4 @@ CONFIG_UTILITIES_BASE64_ENABLED=y CONFIG_SINGLE_HEADER_LIBS_ENABLED=y CONFIG_AX_SAMPLES_ENABLED=y CONFIG_SIMDJSON_COMPENENT_ENABLED=y +CONFIG_SAMPLE_COMMON_ENABLED=y diff --git a/projects/llm_framework/main_camera/SConstruct b/projects/llm_framework/main_camera/SConstruct index 8de268d..2f1758a 100644 --- a/projects/llm_framework/main_camera/SConstruct +++ b/projects/llm_framework/main_camera/SConstruct @@ -22,7 +22,17 @@ LDFLAGS+=['-Wl,-rpath=/opt/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib', '- # INCLUDE += [ADir('../include'), ADir('../include/cppzmq'), ADir('../include/libzmq')] LINK_SEARCH_PATH += [ADir('../static_lib')] + +# INCLUDE.append(ADir('ax_sample')) +# SRCS += Glob('ax_sample/*.c*') + REQUIREMENTS += ['ax_sys', 'ax_interpreter'] +REQUIREMENTS += ['ax_engine', 'ax_interpreter', 'ax_sys', 'ax_vo'] +REQUIREMENTS += ['ax_opal', 'ax_ae', 'ax_skel', 'ax_opal', 'ax_venc', 'ax_mipi', 'ax_ives', 'ax_ivps', 'ax_proton', 'ax_audio', 'mpr', 'tinyalsa'] +REQUIREMENTS += ['ax_audio_3a','samplerate', 'ax_fdk', 'fdk-aac', 'ax_awb', 'ax_af', 'ax_nt_stream', 'ax_nt_ctrl'] + + + INCLUDE += [ADir('../include/opencv4')] static_file = [] diff --git a/projects/llm_framework/main_camera/src/axera_camera.c b/projects/llm_framework/main_camera/src/axera_camera.c new file mode 100644 index 0000000..d929a21 --- /dev/null +++ b/projects/llm_framework/main_camera/src/axera_camera.c @@ -0,0 +1,1373 @@ +/* + * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +#include "camera.h" +#include "axera_camera.h" +#include +#include +#include +#include +#include "../../../../SDK/components/utilities/include/sample_log.h" +#include +#include +#include +#include +#include +#include + +#include "ax_global_type.h" +#include "common_isp.h" +#include "common_sys.h" +#include "common_cam.h" +#include "common_isp.h" +#include "common_nt.h" +#include "common_vin.h" +#include "ax_sys_api.h" +#include "ax_ivps_api.h" + +#ifndef ALIGN_UP +#define ALIGN_UP(x, a) ((((x) + ((a) - 1)) / a) * a) +#endif + +AX_MIPI_RX_ATTR_T gSc850slMipiAttr = { + .ePhyMode = AX_MIPI_PHY_TYPE_DPHY, + .eLaneNum = AX_MIPI_DATA_LANE_4, + .nDataRate = 80, + .nDataLaneMap[0] = 0, + .nDataLaneMap[1] = 1, + .nDataLaneMap[2] = 3, + .nDataLaneMap[3] = 4, + .nClkLane[0] = 2, + .nClkLane[1] = 5, +}; + +AX_SNS_ATTR_T gSc850slSnsAttr = { + .nWidth = 3840, + .nHeight = 2160, + .fFrameRate = 30, + .eSnsMode = AX_SNS_LINEAR_MODE, + .eRawType = AX_RT_RAW10, + .eBayerPattern = AX_BP_RGGB, + .bTestPatternEnable = AX_FALSE, + // .nSettingIndex = 12, +}; + +AX_SNS_CLK_ATTR_T gSc850slSnsClkAttr = { + .nSnsClkIdx = 0, + .eSnsClkRate = AX_SNS_CLK_24M, +}; + +AX_VIN_DEV_ATTR_T gSc850slDevAttr = { + .bImgDataEnable = AX_TRUE, + .bNonImgDataEnable = AX_FALSE, + .eDevMode = AX_VIN_DEV_ONLINE, + .eSnsIntfType = AX_SNS_INTF_TYPE_MIPI_RAW, + .tDevImgRgn[0] = {0, 0, 3840, 2160}, + .tDevImgRgn[1] = {0, 0, 3840, 2160}, + .tDevImgRgn[2] = {0, 0, 3840, 2160}, + .tDevImgRgn[3] = {0, 0, 3840, 2160}, + + /* When users transfer special data, they need to configure VC&DT for szImgVc/szImgDt/szInfoVc/szInfoDt */ + //.tMipiIntfAttr.szImgVc[0] = 0, + //.tMipiIntfAttr.szImgVc[1] = 1, + //.tMipiIntfAttr.szImgDt[0] = 43, + //.tMipiIntfAttr.szImgDt[1] = 43, + //.tMipiIntfAttr.szInfoVc[0] = 31, + //.tMipiIntfAttr.szInfoVc[1] = 31, + //.tMipiIntfAttr.szInfoDt[0] = 63, + //.tMipiIntfAttr.szInfoDt[1] = 63, + + .ePixelFmt = AX_FORMAT_BAYER_RAW_10BPP_PACKED, + .eBayerPattern = AX_BP_RGGB, + .eSnsMode = AX_SNS_LINEAR_MODE, + .eSnsOutputMode = AX_SNS_NORMAL, + .tCompressInfo = {AX_COMPRESS_MODE_NONE, 0}, + .tFrameRateCtrl= {AX_INVALID_FRMRATE, AX_INVALID_FRMRATE}, +}; + +AX_VIN_PIPE_ATTR_T gSc850slPipeAttr = { + .ePipeWorkMode = AX_VIN_PIPE_NORMAL_MODE1, + .tPipeImgRgn = {0, 0, 3840, 2160}, + .nWidthStride = 3840, + .eBayerPattern = AX_BP_RGGB, + .ePixelFmt = AX_FORMAT_BAYER_RAW_10BPP_PACKED, + .eSnsMode = AX_SNS_LINEAR_MODE, + .tCompressInfo = {AX_COMPRESS_MODE_LOSSY, 0}, + .tNrAttr = {{0, {AX_COMPRESS_MODE_LOSSLESS, 0}}, {0, {AX_COMPRESS_MODE_NONE, 0}}}, + .tFrameRateCtrl = {AX_INVALID_FRMRATE, AX_INVALID_FRMRATE}, +}; + +AX_VIN_CHN_ATTR_T gSc850slChn0Attr = { + .nWidth = 3840, + .nHeight = 2160, + .nWidthStride = 3840, + .eImgFormat = AX_FORMAT_YUV420_SEMIPLANAR, + .nDepth = 1, + .tCompressInfo = {AX_COMPRESS_MODE_LOSSY, 4}, + .tFrameRateCtrl = {AX_INVALID_FRMRATE, AX_INVALID_FRMRATE}, +}; + +typedef enum { + SAMPLE_VIN_NONE = -1, + SAMPLE_VIN_SINGLE_DUMMY = 0, + SAMPLE_VIN_SINGLE_OS04A10 = 1, + SAMPLE_VIN_DOUBLE_OS04A10 = 2, + SAMPLE_VIN_SINGLE_SC450AI = 3, + SAMPLE_VIN_DOUBLE_SC450AI = 4, + SAMPLE_VIN_DOUBLE_OS04A10_AND_BT656 = 5, + SAMPLE_VIN_SINGLE_S5KJN1SQ03 = 6, + SAMPLE_VIN_SINGLE_OS04A10_DCG_HDR = 7, + SAMPLE_VIN_SINGLE_OS04A10_DCG_VS_HDR = 8, + SYS_CASE_SINGLE_DVP = 20, + SYS_CASE_SINGLE_BT601 = 21, + SYS_CASE_SINGLE_BT656 = 22, + SYS_CASE_SINGLE_BT1120 = 23, + SYS_CASE_SINGLE_LVDS = 24, + SYS_CASE_SINGLE_OS04A10_ONLINE = 25, + SMARTSENS_SC850SL = 13, + SAMPLE_VIN_SINGLE_SC850SL = 26, + SAMPLE_VIN_BUTT +} SAMPLE_VIN_CASE_E; + +struct axera_camera_index_t +{ + char name[48]; + SAMPLE_VIN_CASE_E index; +}axera_camera_index[] = { + {"axera_single_dummy", SAMPLE_VIN_SINGLE_DUMMY}, + {"axera_single_os04a10", SAMPLE_VIN_SINGLE_OS04A10}, + {"axera_double_os04a10", SAMPLE_VIN_DOUBLE_OS04A10}, + {"axera_single_sc450ai", SAMPLE_VIN_SINGLE_SC450AI}, + {"axera_double_sc450ai", SAMPLE_VIN_DOUBLE_SC450AI}, + {"axera_double_os04a10_and_bt656", SAMPLE_VIN_DOUBLE_OS04A10_AND_BT656}, + {"axera_single_s5kjn1sq03", SAMPLE_VIN_SINGLE_S5KJN1SQ03}, + {"axera_single_os04a10_dcg_hdr", SAMPLE_VIN_SINGLE_OS04A10_DCG_HDR}, + {"axera_single_os04a10_dcg_vs_hdr", SAMPLE_VIN_SINGLE_OS04A10_DCG_VS_HDR}, + {"axera_single_dvp", SYS_CASE_SINGLE_DVP}, + {"axera_single_bt601", SYS_CASE_SINGLE_BT601}, + {"axera_single_bt656", SYS_CASE_SINGLE_BT656}, + {"axera_single_bt1120", SYS_CASE_SINGLE_BT1120}, + {"axera_single_lvds", SYS_CASE_SINGLE_LVDS}, + {"axera_single_os04a10_online", SYS_CASE_SINGLE_OS04A10_ONLINE}, + {"axera_single_sc850sl", SAMPLE_VIN_SINGLE_SC850SL} +}; + +typedef struct { + SAMPLE_VIN_CASE_E eSysCase; + COMMON_VIN_MODE_E eSysMode; + AX_SNS_HDR_MODE_E eHdrMode; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode; + AX_BOOL bAiispEnable; + AX_S32 nDumpFrameNum; +} SAMPLE_VIN_PARAM_T; + +/* comm pool */ +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleDummySdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_16BPP, 6}, /*vin raw16 use */ + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 4, AX_COMPRESS_MODE_LOSSY, 4}, /*vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleDVPSdr[] = { + {2560, 1440, 2560, AX_FORMAT_YUV420_SEMIPLANAR, 10}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleBTSdr[] = { + {720, 480, 720, AX_FORMAT_YUV422_INTERLEAVED_UYVY, 25 * 2}, /*vin yuv422 uyvy use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleLVDSSdr[] = { + {1600, 1200, 1600, AX_FORMAT_YUV420_SEMIPLANAR, 10}, /* vin nv21/nv21 use */ +}; + +/* private pool */ +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleDummySdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_16BPP, 10, AX_COMPRESS_MODE_LOSSY, 4}, +}; + +COMMON_SYS_POOL_CFG_T gtSysPrivatePoolSingleDVPSdr[] = { + {2560, 1440, 2560, AX_FORMAT_BAYER_RAW_10BPP, 25 * 2}, /*vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysPrivatePoolSingleBTSdr[] = { + {720, 480, 720, AX_FORMAT_YUV422_INTERLEAVED_UYVY, 25 * 2}, /*vin yuv422 uyvy use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysPrivatePoolSingleLVDSSdr[] = { + {1600, 1200, 1600, AX_FORMAT_BAYER_RAW_10BPP, 25 * 2}, /*vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 3, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 4}, /* vin nv21/nv21 use */ + {1920, 1080, 1920, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ + {720, 576, 720, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 12, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw16 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Bt656Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 6, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Bt656Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 5, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Bt656Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 7, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Bt656Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 13, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 5, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 14, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10SdrOnly[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_NONE, 0}, /* vin raw10 use */ + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleOs450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 3, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleOs450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +/*************************************/ +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleSc850SlSdr[] = { + {3840, 2160, 3840, AX_FORMAT_YUV420_SEMIPLANAR, 4, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 4}, /* vin nv21/nv21 use */ + {1920, 1080, 1920, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ + {720, 576, 720, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleSc850SlSdr[] = { + {3840, 2160, 3840, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; +/*************************************/ + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleSc450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleSc450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleSc450aiHdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleSc450aiHdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_NONE, 0}, /* vin raw10 use */ + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingles5kjn1sq03Sdr[] = { + {1920, 1080, 1920, AX_FORMAT_YUV420_SEMIPLANAR, 3, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingles5kjn1sq03Sdr[] = { + {1920, 1080, 1920, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +static AX_VOID __cal_dump_pool(COMMON_SYS_POOL_CFG_T pool[], AX_SNS_HDR_MODE_E eHdrMode, AX_S32 nFrameNum) +{ + if (NULL == pool) { + return; + } + if (nFrameNum > 0) { + switch (eHdrMode) { + case AX_SNS_LINEAR_MODE: + pool[0].nBlkCnt += nFrameNum; + break; + + case AX_SNS_HDR_2X_MODE: + pool[0].nBlkCnt += nFrameNum * 2; + break; + + case AX_SNS_HDR_3X_MODE: + pool[0].nBlkCnt += nFrameNum * 3; + break; + + case AX_SNS_HDR_4X_MODE: + pool[0].nBlkCnt += nFrameNum * 4; + break; + + default: + pool[0].nBlkCnt += nFrameNum; + break; + } + } +} + +static AX_VOID __set_pipe_hdr_mode(AX_U32 *pHdrSel, AX_SNS_HDR_MODE_E eHdrMode) +{ + if (NULL == pHdrSel) { + return; + } + + switch (eHdrMode) { + case AX_SNS_LINEAR_MODE: + *pHdrSel = 0x1; + break; + + case AX_SNS_HDR_2X_MODE: + *pHdrSel = 0x1 | 0x2; + break; + + case AX_SNS_HDR_3X_MODE: + *pHdrSel = 0x1 | 0x2 | 0x4; + break; + + case AX_SNS_HDR_4X_MODE: + *pHdrSel = 0x1 | 0x2 | 0x4 | 0x8; + break; + + default: + *pHdrSel = 0x1; + break; + } +} + +static AX_VOID __set_vin_attr(AX_CAMERA_T *pCam, SAMPLE_SNS_TYPE_E eSnsType, AX_SNS_HDR_MODE_E eHdrMode, + COMMON_VIN_MODE_E eSysMode, AX_BOOL bAiispEnable) +{ + pCam->eSnsType = eSnsType; + pCam->tSnsAttr.eSnsMode = eHdrMode; + pCam->tDevAttr.eSnsMode = eHdrMode; + pCam->eHdrMode = eHdrMode; + pCam->eSysMode = eSysMode; + pCam->tPipeAttr[pCam->nPipeId].eSnsMode = eHdrMode; + pCam->tPipeAttr[pCam->nPipeId].bAiIspEnable = bAiispEnable; + + if (eHdrMode > AX_SNS_LINEAR_MODE) { + pCam->tDevAttr.eSnsOutputMode = AX_SNS_DOL_HDR; + } + + if (COMMON_VIN_TPG == eSysMode) { + pCam->tDevAttr.eSnsIntfType = AX_SNS_INTF_TYPE_TPG; + } + + if (COMMON_VIN_LOADRAW == eSysMode) { + pCam->bEnableDev = AX_FALSE; + } else { + pCam->bEnableDev = AX_TRUE; + } + pCam->bChnEn[0] = AX_TRUE; + pCam->bRegisterSns = AX_TRUE; + + return; +} + + +AX_S32 CUSTOM_COMMON_VIN_GetSnsConfig(SAMPLE_SNS_TYPE_E eSnsType, + AX_MIPI_RX_ATTR_T *ptMipiAttr, AX_SNS_ATTR_T *ptSnsAttr, + AX_SNS_CLK_ATTR_T *ptSnsClkAttr, AX_VIN_DEV_ATTR_T *pDevAttr, + AX_VIN_PIPE_ATTR_T *pPipeAttr, AX_VIN_CHN_ATTR_T *pChnAttr) { + if(eSnsType == SMARTSENS_SC850SL) + { + memcpy(ptMipiAttr, &gSc850slMipiAttr, sizeof(AX_MIPI_RX_ATTR_T)); + memcpy(ptSnsAttr, &gSc850slSnsAttr, sizeof(AX_SNS_ATTR_T)); + memcpy(ptSnsClkAttr, &gSc850slSnsClkAttr, sizeof(AX_SNS_CLK_ATTR_T)); + memcpy(pDevAttr, &gSc850slDevAttr, sizeof(AX_VIN_DEV_ATTR_T)); + memcpy(pPipeAttr, &gSc850slPipeAttr, sizeof(AX_VIN_PIPE_ATTR_T)); + memcpy(&pChnAttr[0], &gSc850slChn0Attr, sizeof(AX_VIN_CHN_ATTR_T)); + } + return COMMON_VIN_GetSnsConfig(eSnsType, ptMipiAttr, ptSnsAttr, + ptSnsClkAttr, pDevAttr, pPipeAttr, pChnAttr); +} + + +static AX_U32 __sample_case_single_dummy(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_S32 i = 0; + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCam = &pCamList[0]; + pCommonArgs->nCamCnt = 1; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + pCam = &pCamList[i]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eLoadRawNode = eLoadRawNode; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (AX_S32 j = 0; j < AX_VIN_MAX_PIPE_NUM; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + + return 0; +} + +static AX_U32 __sample_case_single_dvp(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, SAMPLE_VIN_PARAM_T *pVinParam, + COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_DVP; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (AX_S32 j = 0; j < AX_VIN_MAX_PIPE_NUM; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + + return 0; +} + +static AX_U32 __sample_case_single_bt656(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 2; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 2; + pCam->nRxDev = 2; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_BT656; + pCam->tPipeAttr[pCam->nPipeId].ePipeWorkMode = AX_VIN_PIPE_ISP_BYPASS_MODE; + pCam->tPipeAttr[pCam->nPipeId].ePixelFmt = AX_FORMAT_YUV420_SEMIPLANAR; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + pCam->bRegisterSns = AX_FALSE; + + return 0; +} + +static AX_U32 __sample_case_single_bt1120(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 2; + pCam->nRxDev = 2; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_BT1120; + pCam->tPipeAttr[pCam->nPipeId].ePipeWorkMode = AX_VIN_PIPE_ISP_BYPASS_MODE; + pCam->tPipeAttr[pCam->nPipeId].ePixelFmt = AX_FORMAT_YUV420_SEMIPLANAR; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + pCam->bRegisterSns = AX_FALSE; + + return 0; +} + +static AX_U32 __sample_case_single_lvds(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_LVDS; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (AX_S32 j = 0; j < AX_VIN_MAX_PIPE_NUM; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + + return 0; +} + +static AX_U32 __sample_case_single_os04a10(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->eLoadRawNode = eLoadRawNode; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + return 0; +} + +static AX_U32 __sample_case_single_sc850sl(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->eLoadRawNode = eLoadRawNode; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc850sl_sdr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc850sl_hdr_2x.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + return 0; +} + +static AX_U32 __sample_case_double_os04a10(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0, i = 0; + pCommonArgs->nCamCnt = 2; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + pCam = &pCamList[i]; + pCam->nNumber = i; + pCam->nPipeId = i; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = i; + if (i == 0) { + pCam->nRxDev = 0; + pCam->nI2cAddr = 0x36; + } else { + pCam->nRxDev = 1; + pCam->nI2cAddr = 0x36; + } + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + if (eHdrMode == AX_SNS_LINEAR_MODE) + pCam->tSnsAttr.nSettingIndex = 33; + else + pCam->tSnsAttr.nSettingIndex = 34; + pCam->tMipiAttr.eLaneNum = AX_MIPI_DATA_LANE_2; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + if (pCam->nPipeId != 0 && eHdrMode == AX_SNS_HDR_2X_MODE) { + pCam->tPipeAttr[pCam->nPipeId].tCompressInfo.enCompressMode = AX_COMPRESS_MODE_NONE; + } + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + return 0; +} + +static AX_U32 __sample_case_single_sc450ai(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->eLoadRawNode = eLoadRawNode; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_sdr_dual3dnr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_hdr_2x_ainr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + return 0; +} + +static AX_U32 __sample_case_double_sc450ai(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0, i = 0; + pCommonArgs->nCamCnt = 2; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + pCam = &pCamList[i]; + pCam->nNumber = i; + pCam->nPipeId = i; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = i; + if (i == 0) { + pCam->nRxDev = 0; + pCam->nI2cAddr = 0x30; + } else { + pCam->nRxDev = 1; + pCam->nI2cAddr = 0x30; + } + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + if (eHdrMode == AX_SNS_LINEAR_MODE) + pCam->tSnsAttr.nSettingIndex = 33; + else + pCam->tSnsAttr.nSettingIndex = 35; + pCam->tMipiAttr.eLaneNum = AX_MIPI_DATA_LANE_2; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + if (pCam->nPipeId != 0 && eHdrMode == AX_SNS_HDR_2X_MODE) { + pCam->tPipeAttr[pCam->nPipeId].tCompressInfo.enCompressMode = AX_COMPRESS_MODE_NONE; + } + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_sdr_dual3dnr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_hdr_2x_ainr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + } + return 0; +} + +static AX_U32 __sample_case_double_os04a10_and_bt656(AX_CAMERA_T *pCamList, SAMPLE_VIN_PARAM_T *pVinParam, + COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + SAMPLE_SNS_TYPE_E eSnsType; + AX_S32 j = 0, i = 0; + pCommonArgs->nCamCnt = 3; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + if (i < 2) + eSnsType = OMNIVISION_OS04A10; + else { + eSnsType = SAMPLE_SNS_BT656; + eHdrMode = AX_SNS_LINEAR_MODE; + } + pCam = &pCamList[i]; + pCam->nNumber = i; + pCam->nPipeId = i; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = i; + pCam->nRxDev = i; + if (i == 0) { + pCam->nI2cAddr = 0x36; + } else if (i == 1) { + pCam->nI2cAddr = 0x36; + } + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + if (eHdrMode == AX_SNS_LINEAR_MODE) + pCam->tSnsAttr.nSettingIndex = 33; + else + pCam->tSnsAttr.nSettingIndex = 34; + pCam->tMipiAttr.eLaneNum = AX_MIPI_DATA_LANE_2; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + if (i == 2) { + pCam->eInputMode = AX_INPUT_MODE_BT656; + pCam->bRegisterSns = AX_FALSE; + } + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable && i < 2) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/os04a10_sdr_dual3dnr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/os04a10_hdr_2x_ainr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + } + return 0; +} + +static AX_U32 __sample_case_single_s5kjn1sq03(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->eLoadRawNode = eLoadRawNode; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + return 0; +} + + + + + +static AX_U32 __sample_case_config(AX_CAMERA_T *gCams, SAMPLE_VIN_PARAM_T *pVinParam, + COMMON_SYS_ARGS_T *pCommonArgs, COMMON_SYS_ARGS_T *pPrivArgs) +{ + AX_CAMERA_T *pCamList = gCams; + SAMPLE_SNS_TYPE_E eSnsType = OMNIVISION_OS04A10; + + COMM_ISP_PRT("eSysCase %d, eSysMode %d, eHdrMode %d, bAiispEnable %d\n", pVinParam->eSysCase, pVinParam->eSysMode, + pVinParam->eHdrMode, pVinParam->bAiispEnable); + + switch (pVinParam->eSysCase) { + case SYS_CASE_SINGLE_DVP: + eSnsType = SAMPLE_SNS_DVP; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleDVPSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleDVPSdr) / sizeof(gtSysCommPoolSingleDVPSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleDVPSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleDVPSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleDVPSdr) / sizeof(gtSysPrivatePoolSingleDVPSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleDVPSdr; + + /* cams config */ + __sample_case_single_dvp(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_BT601: + eSnsType = SAMPLE_SNS_BT601; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleBTSdr) / sizeof(gtSysCommPoolSingleBTSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleBTSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleBTSdr) / sizeof(gtSysPrivatePoolSingleBTSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleBTSdr; + + /* cams config */ + __sample_case_single_bt656(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_BT656: + eSnsType = SAMPLE_SNS_BT656; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleBTSdr) / sizeof(gtSysCommPoolSingleBTSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleBTSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleBTSdr) / sizeof(gtSysPrivatePoolSingleBTSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleBTSdr; + + /* cams config */ + __sample_case_single_bt656(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_BT1120: + eSnsType = SAMPLE_SNS_BT1120; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleBTSdr) / sizeof(gtSysCommPoolSingleBTSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleBTSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleBTSdr) / sizeof(gtSysPrivatePoolSingleBTSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleBTSdr; + + /* cams config */ + __sample_case_single_bt1120(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_LVDS: + eSnsType = SAMPLE_SNS_LVDS; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleLVDSSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleLVDSSdr) / sizeof(gtSysCommPoolSingleLVDSSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleLVDSSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleLVDSSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleLVDSSdr) / sizeof(gtSysPrivatePoolSingleLVDSSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleLVDSSdr; + + /* cams config */ + __sample_case_single_lvds(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_OS04A10: + eSnsType = OMNIVISION_OS04A10; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleOs04a10Sdr) / sizeof(gtSysCommPoolSingleOs04a10Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleOs04a10Sdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleOs04a10Sdr) / sizeof(gtPrivatePoolSingleOs04a10Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleOs04a10Sdr; + + /* cams config */ + __sample_case_single_os04a10(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_DOUBLE_OS04A10: + eSnsType = OMNIVISION_OS04A10; + /* comm pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Sdr) / sizeof(gtSysCommPoolDoubleOs04a10Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Sdr; + } else { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Hdr) / sizeof(gtSysCommPoolDoubleOs04a10Hdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Hdr; + } + + /* private pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Sdr) / sizeof(gtPrivatePoolDoubleOs04a10Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Sdr; + } else if (AX_SNS_LINEAR_ONLY_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10SdrOnly, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10SdrOnly) / sizeof(gtPrivatePoolDoubleOs04a10SdrOnly[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10SdrOnly; + } else { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Hdr) / sizeof(gtPrivatePoolDoubleOs04a10Hdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Hdr; + } + + /* cams config */ + __sample_case_double_os04a10(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_DOUBLE_SC450AI: + eSnsType = SMARTSENS_SC450AI; + /* comm pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtSysCommPoolDoubleSc450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleSc450aiSdr) / sizeof(gtSysCommPoolDoubleSc450aiSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleSc450aiSdr; + } else { + __cal_dump_pool(gtSysCommPoolDoubleSc450aiHdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleSc450aiHdr) / sizeof(gtSysCommPoolDoubleSc450aiHdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleSc450aiHdr; + } + + /* private pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleSc450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleSc450aiSdr) / sizeof(gtPrivatePoolDoubleSc450aiSdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleSc450aiSdr; + } else { + __cal_dump_pool(gtPrivatePoolDoubleSc450aiHdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleSc450aiHdr) / sizeof(gtPrivatePoolDoubleSc450aiHdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleSc450aiHdr; + } + + /* cams config */ + __sample_case_double_sc450ai(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_SC450AI: + eSnsType = SMARTSENS_SC450AI; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleOs450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleOs450aiSdr) / sizeof(gtSysCommPoolSingleOs450aiSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleOs450aiSdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingleOs450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleOs450aiSdr) / sizeof(gtPrivatePoolSingleOs450aiSdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleOs450aiSdr; + + /* cams config */ + __sample_case_single_sc450ai(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_SC850SL: + eSnsType = SMARTSENS_SC850SL; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleSc850SlSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleSc850SlSdr) / sizeof(gtSysCommPoolSingleSc850SlSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleSc850SlSdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingleSc850SlSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleSc850SlSdr) / sizeof(gtPrivatePoolSingleSc850SlSdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleSc850SlSdr; + + /* cams config */ + __sample_case_single_sc850sl(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_DOUBLE_OS04A10_AND_BT656: + /* comm pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Bt656Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Bt656Sdr) / sizeof(gtSysCommPoolDoubleOs04a10Bt656Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Bt656Sdr; + } else { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Bt656Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Bt656Hdr) / sizeof(gtSysCommPoolDoubleOs04a10Bt656Hdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Bt656Hdr; + } + + /* private pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Bt656Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Bt656Sdr) / sizeof(gtPrivatePoolDoubleOs04a10Bt656Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Bt656Sdr; + } else { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Bt656Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Bt656Hdr) / sizeof(gtPrivatePoolDoubleOs04a10Bt656Hdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Bt656Hdr; + } + + /* cams config */ + __sample_case_double_os04a10_and_bt656(pCamList, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_S5KJN1SQ03: + eSnsType = SAMSUNG_S5KJN1SQ03; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingles5kjn1sq03Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolSingles5kjn1sq03Sdr) / sizeof(gtSysCommPoolSingles5kjn1sq03Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingles5kjn1sq03Sdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingles5kjn1sq03Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolSingles5kjn1sq03Sdr) / sizeof(gtPrivatePoolSingles5kjn1sq03Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingles5kjn1sq03Sdr; + + /* cams config */ + __sample_case_single_s5kjn1sq03(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_DUMMY: + default: + eSnsType = SAMPLE_SNS_DUMMY; + /* pool config */ + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleDummySdr) / sizeof(gtSysCommPoolSingleDummySdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleDummySdr; + + /* private pool config */ + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleDummySdr) / sizeof(gtPrivatePoolSingleDummySdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleDummySdr; + + /* cams config */ + __sample_case_single_dummy(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + } + + return 0; +} + +typedef enum { + AX_SENSOR_NONT = 0b00000, + AX_SENSOR_NPU_ENABLE = 0b00001, + AX_SENSOR_CAM_ENABLE = 0b00010, + AX_SENSOR_CAM_POOL_ENABLE = 0b00100, + AX_SENSOR_CAM_OPEN = 0b01000, + AX_SENSOR_GET_FRAME_THREAD = 0b10000, +} AX_SENSOR_STATUS; + +struct axera_camera_t { + COMMON_SYS_ARGS_T tPrivArgs; + COMMON_SYS_ARGS_T tCommonArgs; + AX_CAMERA_T gCams; + SAMPLE_VIN_PARAM_T VinParam; + AX_IMG_INFO_T ax_img; + AX_VIDEO_FRAME_T out_img; + int Chn; +} axera_obj; + +static int camera_capture_callback_set(struct camera_t* camera, vcamera_frame_get pcallback) +{ + if (camera->state_ == CAMERA_SATTE_CAP) { + SLOGW("Set capture callback failed"); + return -1; + } + camera->pcallback_ = pcallback; + return 0; +} + +static void* camera_capture_thread(void* param) +{ + int Ret = -1; + camera_t* camera = (camera_t*)param; + struct v4l2_buffer EnQueueBuf; + struct v4l2_buffer DeQueueBuf; + + SLOGI("Start capture"); + + while (camera->state_ & AX_SENSOR_GET_FRAME_THREAD) { + AX_S32 axRet = AX_VIN_GetYuvFrame(axera_obj.gCams.nPipeId, axera_obj.Chn, &axera_obj.ax_img, 500); + if (axRet == 0) + { + // axera_obj.ax_img.tFrameInfo.stVFrame.u64VirAddr[0] = (AX_U64)AX_POOL_GetBlockVirAddr(axera_obj.ax_img.tFrameInfo.stVFrame.u32BlkId[0]); + // axera_obj.ax_img.tFrameInfo.stVFrame.u64PhyAddr[0] = AX_POOL_Handle2PhysAddr(axera_obj.ax_img.tFrameInfo.stVFrame.u32BlkId[0]); + // AX_S32 AX_IVPS_CropResizeTdp(const AX_VIDEO_FRAME_T *ptSrc, AX_VIDEO_FRAME_T *ptDst, + // const AX_IVPS_CROP_RESIZE_ATTR_T *ptAttr); + AX_IVPS_CROP_RESIZE_ATTR_T tAttr = {0}; + AX_IVPS_CropResizeTdp(&axera_obj.ax_img.tFrameInfo.stVFrame, &axera_obj.out_img, &tAttr); + AX_VIN_ReleaseYuvFrame(axera_obj.gCams.nPipeId, axera_obj.Chn, &axera_obj.ax_img); + camera->pcallback_((void*)axera_obj.out_img.u64VirAddr[0], axera_obj.out_img.u32Width, axera_obj.out_img.u32Height, + axera_obj.out_img.u32FrameSize, camera->ctx_); + } + else + { + // ALOGD("get ax img error! code:0x%x", axRet); + usleep(10 * 1000); + } + } + + SLOGI("Stop capture"); + + return NULL; +} + +static int camera_capture_start(struct camera_t* camera) +{ + SLOGI("Start capture thread"); + if (!camera->pcallback_) { + SLOGW("Capture callback not set, start faild"); + return -1; + } + if (!(camera->state_ & AX_SENSOR_CAM_OPEN)) { + SLOGW("Camera not open, start faild"); + return -1; + } + camera->state_ |= AX_SENSOR_GET_FRAME_THREAD; + pthread_create(&camera->capture_thread_id_, NULL, camera_capture_thread, camera); + + return 0; +} + +static int camera_capture_stop(struct camera_t* camera) +{ + SLOGI("Stop capture thread"); + camera->state_ &= ~((int)AX_SENSOR_GET_FRAME_THREAD); + pthread_join(camera->capture_thread_id_, NULL); + SLOGI("Capture thread stop"); + return 0; +} + +static void camera_set_ctx(struct camera_t* camera, void* ctx) +{ + camera->ctx_ = ctx; +} + +int axera_camera_open_from(camera_t* camera) +{ + int Ret = -1; + AX_S32 axRet; + if (camera == NULL) return -1; + /* Check whether the camera is already open or in an error state */ + SLOGI("Open camera %s...", camera->dev_name_); + if (camera->state_ & AX_SENSOR_CAM_OPEN) { + SLOGE("Error: camera was open or meet error, now state is: %d", camera->state_); + goto ErrorHandle; + } + axera_obj.VinParam.eSysCase = SAMPLE_VIN_BUTT; + for (int i = 0; i < sizeof(axera_camera_index) / sizeof(axera_camera_index[0]); i++) + { + if(strcmp(axera_camera_index[i].name, camera->dev_name_) == 0) + { + axera_obj.VinParam.eSysCase = axera_camera_index[i].index; + break; + } + } + if(axera_obj.VinParam.eSysCase == SAMPLE_VIN_BUTT) + { + SLOGE("Error: camera not support %s", camera->dev_name_); + return -10; + } + + axera_obj.VinParam.eSysMode = COMMON_VIN_SENSOR; + axera_obj.VinParam.eHdrMode = AX_SNS_LINEAR_MODE; + axera_obj.VinParam.bAiispEnable = AX_TRUE; + // axera_obj.gCams.tChnAttr + __sample_case_config(&axera_obj.gCams, &axera_obj.VinParam, &axera_obj.tCommonArgs, &axera_obj.tPrivArgs); + COMMON_SYS_Init(&axera_obj.tCommonArgs); + COMMON_NPU_Init(); + AX_IVPS_Init(); + axRet = COMMON_CAM_Init(); + if (axRet) { + COMM_ISP_PRT("COMMON_CAM_Init fail, ret:0x%x", axRet); + return -1; + } + camera->state_ |= AX_SENSOR_CAM_ENABLE; + axRet = COMMON_CAM_PrivPoolInit(&axera_obj.tPrivArgs); + if (axRet) { + COMM_ISP_PRT("COMMON_CAM_PrivPoolInit fail, ret:0x%x", axRet); + return -2; + } + camera->state_ |= AX_SENSOR_CAM_POOL_ENABLE; + /* Step5: Cam Open */ + axRet = COMMON_CAM_Open(&axera_obj.gCams, axera_obj.tCommonArgs.nCamCnt); + if (axRet) { + COMM_ISP_PRT("COMMON_CAM_Open fail, ret:0x%x", axRet); + return -3; + } + axera_obj.Chn = AX_VIN_CHN_ID_MAIN; + camera->state_ |= AX_SENSOR_CAM_OPEN; + + axera_obj.out_img.u32Width = camera->width_; + axera_obj.out_img.u32Height = camera->height_; + axera_obj.out_img.u32PicStride[0] = ALIGN_UP(camera->width_, 16); + axera_obj.out_img.enImgFormat = AX_FORMAT_YUV420_SEMIPLANAR; + axera_obj.out_img.u32FrameSize = camera->width_ * camera->height_ * 3 / 2; + AX_SYS_MemAlloc(&axera_obj.out_img.u64PhyAddr[0], (AX_VOID **)&axera_obj.out_img.u64VirAddr[0], ALIGN_UP(axera_obj.out_img.u32FrameSize, 0x100), 0x100, (AX_S8 *)"StackFlow_camera_output_buff"); + + camera->camera_capture_callback_set = camera_capture_callback_set; + camera->camera_capture_start = camera_capture_start; + camera->camera_capture_stop = camera_capture_stop; + camera->camera_set_ctx = camera_set_ctx; + camera->is_alloc_ = 0; + return 0; + +ErrorHandle: + SLOGE("Camera open meet error, now handle it"); + return -1; +} + +camera_t* axera_camera_open(const char* pdev_name, int width, int height, int fps) +{ + int Ret = -1; + camera_t* camera = (camera_t*)malloc(sizeof(camera_t)); + if (camera == NULL) return NULL; + memset(camera, 0, sizeof(camera_t)); + camera->buffer_cnt_ = CONFIG_CAPTURE_BUF_CNT; + + int CopyLen = strlen(pdev_name); + if (CopyLen > CONFIG_DEVNAME_LEN - 1) { + SLOGE("Error: device name length over limit: %d", CopyLen); + goto ErrorHandle; + } + memset(camera->dev_name_, 0, CONFIG_DEVNAME_LEN); + memcpy(camera->dev_name_, pdev_name, CopyLen); + + camera->width_ = width; + camera->height_ = height; + camera->capture_fps_ = fps; + + Ret = axera_camera_open_from(camera); + if (Ret) { + goto ErrorHandle; + } + camera->is_alloc_ = 1; + return camera; + +ErrorHandle: + SLOGE("Camera open meet error, now handle it"); + free(camera); + return NULL; +} + +int axera_camera_close(camera_t* camera) +{ + if (camera == NULL) return -1; + if (camera->state_ & AX_SENSOR_CAM_OPEN) { + COMMON_CAM_Close(&axera_obj.gCams, axera_obj.tCommonArgs.nCamCnt); + camera->state_ &= ~((int)AX_SENSOR_CAM_OPEN); + } + + if (camera->state_ & AX_SENSOR_CAM_ENABLE) { + COMMON_CAM_Deinit(); + camera->state_ &= ~((int)AX_SENSOR_CAM_ENABLE); + } + camera->state_ = AX_SENSOR_NONT; + AX_IVPS_Deinit(); + COMMON_SYS_DeInit(); + if (camera->is_alloc_) free(camera); + + SLOGI("camera closed"); + + return 0; +} \ No newline at end of file diff --git a/projects/llm_framework/main_camera/src/axera_camera.h b/projects/llm_framework/main_camera/src/axera_camera.h new file mode 100644 index 0000000..6035c8c --- /dev/null +++ b/projects/llm_framework/main_camera/src/axera_camera.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +#ifndef AXERA_CAMERA_H +#define AXERA_CAMERA_H + +#if __cplusplus +extern "C" { +#endif +/** + * Open the axera_camera + * @pdev_name Device node + * Return value: NULL for failure + */ +camera_t* axera_camera_open(const char* pdev_name, int width, int height, int fps); + +/** + * Open the axera_camera from config + * @pDevName Device node + * Return value: 0 for success, -1 for failure + */ +int axera_camera_open_from(camera_t* camera); + +/** + * Close the axera_camera + * Return value: 0 for success, -1 for failure + */ +int axera_camera_close(camera_t* camera); + +#if __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/projects/llm_framework/main_camera/src/camera.h b/projects/llm_framework/main_camera/src/camera.h index 71df980..8aab531 100644 --- a/projects/llm_framework/main_camera/src/camera.h +++ b/projects/llm_framework/main_camera/src/camera.h @@ -14,7 +14,7 @@ #if __cplusplus extern "C" { #endif -typedef void (*vcamera_frame_get)(uint8_t* pdata, uint32_t width, uint32_t height, uint32_t length, void* ctx); +typedef void (*vcamera_frame_get)(void* pdata, uint32_t width, uint32_t height, uint32_t length, void* ctx); typedef enum { CAMERA_STATE_CLOSE, CAMERA_SATTE_OPEN, CAMERA_SATTE_CAP, CAMERA_STATE_ERR } CAMERA_STATE_t; typedef struct { @@ -32,7 +32,7 @@ typedef struct camera_t { uint32_t height_; CAMERA_Buffer_t* pcamera_buffer_; vcamera_frame_get pcallback_; - CAMERA_STATE_t state_; /* 0 Not open, 1 Turn on the camera, 2 Start capturing, + int state_; /* 0 Not open, 1 Turn on the camera, 2 Start capturing, 3 Error */ pthread_t capture_thread_id_; void* ctx_; diff --git a/projects/llm_framework/main_camera/src/main.cpp b/projects/llm_framework/main_camera/src/main.cpp index 07545b3..ceefc15 100644 --- a/projects/llm_framework/main_camera/src/main.cpp +++ b/projects/llm_framework/main_camera/src/main.cpp @@ -13,6 +13,7 @@ #include #include "../../../../SDK/components/utilities/include/sample_log.h" #include "camera.h" +#include "axera_camera.h" #include #include @@ -25,6 +26,10 @@ static void __sigint(int iSigNo) typedef std::function task_callback_t; +typedef camera_t* (*hal_camera_open_fun)(const char* pdev_name, int width, int height, int fps); +typedef int (*hal_camera_close_fun)(camera_t* camera); + + #define CONFIG_AUTO_SET(obj, key) \ if (config_body.contains(#key)) \ mode_config_.key = config_body[#key]; \ @@ -34,7 +39,8 @@ typedef std::function task_callback_t; class llm_task { private: camera_t *cam; - + hal_camera_open_fun hal_camera_open; + hal_camera_close_fun hal_camera_close; public: std::string response_format_; task_callback_t out_callback_; @@ -49,7 +55,7 @@ public: int frame_height_; cv::Mat yuv_dist_; - static void on_cap_fream(uint8_t *pData, uint32_t width, uint32_t height, uint32_t Length, void *ctx) + static void on_cap_fream(void *pData, uint32_t width, uint32_t height, uint32_t Length, void *ctx) { llm_task *self = static_cast(ctx); int src_offsetX; @@ -127,6 +133,13 @@ public: } enstream_ = (response_format_.find("stream") != std::string::npos); yuv_dist_ = cv::Mat(frame_height_, frame_width_, CV_8UC2); + if(devname_.find("/dev/video") != std::string::npos){ + hal_camera_open = camera_open; + hal_camera_close = camera_close; + }else if(devname_.find("axera_") != std::string::npos){ + hal_camera_open = axera_camera_open; + hal_camera_close = axera_camera_close; + } return false; } @@ -136,7 +149,7 @@ public: return -1; } try { - cam = camera_open(devname_.c_str(), frame_width_, frame_height_, 30); + cam = hal_camera_open(devname_.c_str(), frame_width_, frame_height_, 30); if (cam == NULL) { printf("Camera open failed \n"); return -1; @@ -166,7 +179,7 @@ public: { if (cam) { cam->camera_capture_stop(cam); - camera_close(cam); + hal_camera_close(cam); cam = NULL; } } diff --git a/projects/llm_framework/main_camera/src/camera.c b/projects/llm_framework/main_camera/src/v4l2_camera.c similarity index 100% rename from projects/llm_framework/main_camera/src/camera.c rename to projects/llm_framework/main_camera/src/v4l2_camera.c