From 0cf1447a1fbd08b92a15db59f3f09b0d54da1b54 Mon Sep 17 00:00:00 2001 From: fujie Date: Mon, 23 Mar 2026 13:18:38 +0800 Subject: [PATCH] feat(infographic): bump v1.6.0 supporting 12-lang i18n & canvas high-contrast dark overrides --- README.md | 5 +- README_CN.md | 5 +- docs/plugins/actions/index.md | 2 +- docs/plugins/actions/index.zh.md | 2 +- docs/plugins/actions/infographic.md | 4 +- docs/plugins/actions/infographic.zh.md | 4 +- plugins/actions/infographic/README.md | 4 +- plugins/actions/infographic/README_CN.md | 4 +- plugins/actions/infographic/infographic.py | 704 ++++++- .../actions/infographic/infographic_cn.png | Bin 173326 -> 0 bytes plugins/actions/infographic/infographic_cn.py | 1782 ----------------- plugins/actions/infographic/v1.6.0.md | 14 + plugins/actions/infographic/v1.6.0_CN.md | 15 + 13 files changed, 718 insertions(+), 1827 deletions(-) delete mode 100644 plugins/actions/infographic/infographic_cn.png delete mode 100644 plugins/actions/infographic/infographic_cn.py create mode 100644 plugins/actions/infographic/v1.6.0.md create mode 100644 plugins/actions/infographic/v1.6.0_CN.md diff --git a/README.md b/README.md index b512473..3c82164 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,13 @@ A collection of enhancements, plugins, and prompts for [open-webui](https://gith | Rank | Plugin | Version | Downloads | Views | 📅 Updated | | :---: | :--- | :---: | :---: | :---: | :---: | | 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![p1_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_dl.json&style=flat) | ![p1_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | -| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![p2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_dl.json&style=flat) | ![p2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | +| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | ![v](https://img.shields.io/badge/v-1.6.0-blue?style=flat) | ![p2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_dl.json&style=flat) | ![p2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | | 🥉 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | ![v](https://img.shields.io/badge/v-1.2.8-blue?style=flat) | ![p3_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_dl.json&style=flat) | ![p3_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | -| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![p4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_dl.json&style=flat) | ![p4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | +| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | ![v](https://img.shields.io/badge/v-1.6.0-blue?style=flat) | ![p4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_dl.json&style=flat) | ![p4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | | 5️⃣ | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | ![v](https://img.shields.io/badge/v-0.4.4-blue?style=flat) | ![p5_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_dl.json&style=flat) | ![p5_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | | 6️⃣ | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![p6_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_dl.json&style=flat) | ![p6_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | + ### 📈 Total Downloads Trend ![Activity](https://gist.githubusercontent.com/Fu-Jie/db3d95687075a880af6f1fba76d679c6/raw/chart.svg) diff --git a/README_CN.md b/README_CN.md index 703f08f..a3ce581 100644 --- a/README_CN.md +++ b/README_CN.md @@ -21,12 +21,13 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词 | 排名 | 插件 | 版本 | 下载 | 浏览 | 📅 更新 | | :---: | :--- | :---: | :---: | :---: | :---: | | 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![p1_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_dl.json&style=flat) | ![p1_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | -| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![p2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_dl.json&style=flat) | ![p2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | +| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | ![v](https://img.shields.io/badge/v-1.6.0-blue?style=flat) | ![p2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_dl.json&style=flat) | ![p2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | | 🥉 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | ![v](https://img.shields.io/badge/v-1.2.8-blue?style=flat) | ![p3_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_dl.json&style=flat) | ![p3_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | -| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![p4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_dl.json&style=flat) | ![p4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | +| 4️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | ![v](https://img.shields.io/badge/v-1.6.0-blue?style=flat) | ![p4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_dl.json&style=flat) | ![p4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | | 5️⃣ | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | ![v](https://img.shields.io/badge/v-0.4.4-blue?style=flat) | ![p5_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_dl.json&style=flat) | ![p5_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | | 6️⃣ | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![p6_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_dl.json&style=flat) | ![p6_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--03--22-gray?style=flat) | + ### 📈 总下载量累计趋势 ![Activity](https://gist.githubusercontent.com/Fu-Jie/db3d95687075a880af6f1fba76d679c6/raw/chart.svg) diff --git a/docs/plugins/actions/index.md b/docs/plugins/actions/index.md index 48e5d38..3b75fbb 100644 --- a/docs/plugins/actions/index.md +++ b/docs/plugins/actions/index.md @@ -33,7 +33,7 @@ Actions are interactive plugins that: Transform text into professional infographics using AntV visualization engine with various templates. - **Version:** 1.5.0 + **Version:** 1.6.0 [:octicons-arrow-right-24: Documentation](smart-infographic.md) diff --git a/docs/plugins/actions/index.zh.md b/docs/plugins/actions/index.zh.md index 708f17b..a0b26fe 100644 --- a/docs/plugins/actions/index.zh.md +++ b/docs/plugins/actions/index.zh.md @@ -33,7 +33,7 @@ Actions 是交互式插件,能够: 使用 AntV 可视化引擎,将文本转成专业的信息图。 - **版本:** 1.4.9 + **版本:** 1.6.0 [:octicons-arrow-right-24: 查看文档](smart-infographic.md) diff --git a/docs/plugins/actions/infographic.md b/docs/plugins/actions/infographic.md index 987978c..1acaa25 100644 --- a/docs/plugins/actions/infographic.md +++ b/docs/plugins/actions/infographic.md @@ -1,6 +1,6 @@ # Smart Infographic -| By [Fu-Jie](https://github.com/Fu-Jie) · v1.5.0 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) | +| By [Fu-Jie](https://github.com/Fu-Jie) · v1.6.0 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) | | :--- | ---: | | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&label=%F0%9F%91%A5&style=flat) | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&label=%E2%AD%90&style=flat) | ![top](https://img.shields.io/badge/%F0%9F%8F%86-Top%20%3C1%25-10b981?style=flat) | ![contributions](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_contributions.json&label=%F0%9F%93%A6&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&label=%E2%AC%87%EF%B8%8F&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&label=%F0%9F%92%BE&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&label=%F0%9F%91%81%EF%B8%8F&style=flat) | @@ -8,7 +8,7 @@ An Open WebUI plugin powered by the AntV Infographic engine. It transforms long text into professional, beautiful infographics with a single click. -## 🔥 What's New in v1.5.0 +## 🔥 What's New in v1.6.0 - 🌐 **Smart Language Detection**: Automatically detects the accurate UI language from your browser. - 🗣️ **Context-Aware Generation**: Generated infographics now strictly follow the language of your input content (e.g., input Japanese -> output Japanese infographic). diff --git a/docs/plugins/actions/infographic.zh.md b/docs/plugins/actions/infographic.zh.md index c897029..de3df0b 100644 --- a/docs/plugins/actions/infographic.zh.md +++ b/docs/plugins/actions/infographic.zh.md @@ -1,6 +1,6 @@ # 智能信息图 -| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v1.5.0 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) | +| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v1.6.0 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) | | :--- | ---: | | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&label=%F0%9F%91%A5&style=flat) | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&label=%E2%AD%90&style=flat) | ![top](https://img.shields.io/badge/%F0%9F%8F%86-Top%20%3C1%25-10b981?style=flat) | ![contributions](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_contributions.json&label=%F0%9F%93%A6&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&label=%E2%AC%87%EF%B8%8F&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&label=%F0%9F%92%BE&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&label=%F0%9F%91%81%EF%B8%8F&style=flat) | @@ -8,7 +8,7 @@ 基于 AntV Infographic 引擎的 Open WebUI 插件,能够将长文本内容一键转换为专业、美观的信息图表。 -## 🔥 最新更新 v1.5.0 +## 🔥 最新更新 v1.6.0 - 🌐 **智能语言检测**:自动从浏览器准确识别当前界面语言设置。 - 🗣️ **上下文感知生成**:生成的信息图内容现在严格跟随用户输入内容的语言(例如:输入日语 -> 生成日语信息图)。 diff --git a/plugins/actions/infographic/README.md b/plugins/actions/infographic/README.md index 9742706..a711693 100644 --- a/plugins/actions/infographic/README.md +++ b/plugins/actions/infographic/README.md @@ -1,6 +1,6 @@ # Smart Infographic -| By [Fu-Jie](https://github.com/Fu-Jie) · v1.5.0 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) | +| By [Fu-Jie](https://github.com/Fu-Jie) · v1.6.0 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) | | :--- | ---: | | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&label=%F0%9F%91%A5&style=flat) | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&label=%E2%AD%90&style=flat) | ![top](https://img.shields.io/badge/%F0%9F%8F%86-Top%20%3C1%25-10b981?style=flat) | ![contributions](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_contributions.json&label=%F0%9F%93%A6&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&label=%E2%AC%87%EF%B8%8F&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&label=%F0%9F%92%BE&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&label=%F0%9F%91%81%EF%B8%8F&style=flat) | @@ -21,7 +21,7 @@ When the selection dialog opens, search for this plugin, check it, and continue. > [!IMPORTANT] > If the official OpenWebUI Community version is already installed, remove it first. After that, Batch Install Plugins can keep this plugin updated in future runs. -## 🔥 What's New in v1.5.0 +## 🔥 What's New in v1.6.0 - 🌐 **Smart Language Detection**: Automatically detects the accurate UI language from your browser. - 🗣️ **Context-Aware Generation**: Generated infographics now strictly follow the language of your input content (e.g., input Japanese -> output Japanese infographic). diff --git a/plugins/actions/infographic/README_CN.md b/plugins/actions/infographic/README_CN.md index e684764..02a054d 100644 --- a/plugins/actions/infographic/README_CN.md +++ b/plugins/actions/infographic/README_CN.md @@ -1,6 +1,6 @@ # 智能信息图 -| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v1.5.0 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) | +| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v1.6.0 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) | | :--- | ---: | | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&label=%F0%9F%91%A5&style=flat) | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&label=%E2%AD%90&style=flat) | ![top](https://img.shields.io/badge/%F0%9F%8F%86-Top%20%3C1%25-10b981?style=flat) | ![contributions](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_contributions.json&label=%F0%9F%93%A6&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&label=%E2%AC%87%EF%B8%8F&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&label=%F0%9F%92%BE&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&label=%F0%9F%91%81%EF%B8%8F&style=flat) | @@ -21,7 +21,7 @@ > [!IMPORTANT] > 如果你已经安装了 OpenWebUI 官方社区里的同名版本,请先删除旧版本,否则重新安装时可能报错。删除后,Batch Install Plugins 后续就可以继续负责更新这个插件。 -## 🔥 最新更新 v1.5.0 +## 🔥 最新更新 v1.6.0 - 🌐 **智能语言检测**:自动从浏览器准确识别当前界面语言设置。 - 🗣️ **上下文感知生成**:生成的信息图内容现在严格跟随用户输入内容的语言(例如:输入日语 -> 生成日语信息图)。 diff --git a/plugins/actions/infographic/infographic.py b/plugins/actions/infographic/infographic.py index f6c2fa7..8049de1 100644 --- a/plugins/actions/infographic/infographic.py +++ b/plugins/actions/infographic/infographic.py @@ -4,7 +4,7 @@ author: Fu-Jie author_url: https://github.com/Fu-Jie/openwebui-extensions funding_url: https://github.com/open-webui icon_url: data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPgogIDxsaW5lIHgxPSIxMiIgeTE9IjIwIiB4Mj0iMTIiIHkyPSIxMCIgLz4KICA8bGluZSB4MT0iMTgiIHkxPSIyMCIgeDI9IjE4IiB5Mj0iNCIgLz4KICA8bGluZSB4MT0iNiIgeTE9IjIwIiB4Mj0iNiIgeTI9IjE2IiAvPgo8L3N2Zz4= -version: 1.5.0 +version: 1.6.0 openwebui_id: ad6f0c7f-c571-4dea-821d-8e71697274cf description: AI-powered infographic generator based on AntV Infographic. Supports professional templates, auto-icon matching, and SVG/PNG downloads. """ @@ -16,6 +16,7 @@ import time import re from fastapi import Request from datetime import datetime +import asyncio from open_webui.utils.chat import generate_chat_completion from open_webui.models.users import Users @@ -25,6 +26,477 @@ logging.basicConfig( ) logger = logging.getLogger(__name__) +TRANSLATIONS = { + "en-US": { + "status_starting": "Smart Infographic is starting, generating infographic for you...", + "error_no_content": "Unable to retrieve valid user message content.", + "error_text_too_short": "Text content is too short ({len} characters), unable to perform effective analysis. Please provide at least {min_len} characters of text.", + "status_analyzing": "Smart Infographic: Analyzing text structure in depth...", + "status_drawing": "Smart Infographic: Drawing completed!", + "notification_success": "Mind map has been generated, {user_name}!", + "error_processing": "Smart Infographic processing failed: {error}", + "error_user_facing": "Sorry, Smart Infographic encountered an error during processing: {error}.\nPlease check the Open WebUI backend logs for more details.", + "status_failed": "Smart Infographic: Processing failed.", + "notification_failed": "Smart Infographic generation failed, {user_name}!", + "status_rendering_image": "Smart Infographic: Rendering image...", + "status_image_generated": "Smart Infographic: Image generated!", + "notification_image_success": "Mind map image has been generated, {user_name}!", + "ui_title": "🧠 Smart Infographic", + "ui_user": "User:", + "ui_time": "Time:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "Reset", + "ui_zoom_in": "+", + "ui_depth_select": "Expand Level", + "ui_depth_all": "Expand All", + "ui_depth_2": "Level 2", + "ui_depth_3": "Level 3", + "ui_fullscreen": "Fullscreen", + "ui_theme": "Theme", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ Unable to load infographic: Missing valid content.", + "html_error_load_failed": "⚠️ Resource loading failed, please try again later.", + "js_done": "Done", + "js_failed": "Failed", + "js_generating": "Generating...", + "js_filename": "infographic.png", + "js_upload_failed": "Upload failed: ", + "md_image_alt": "🧠 Infographic", + }, + "zh-CN": { + "status_starting": "信息图已启动,正在为您生成信息图...", + "error_no_content": "无法获取有效的用户消息内容。", + "error_text_too_short": "文本内容过短({len}字符),无法进行有效分析。请提供至少{min_len}字符的文本。", + "status_analyzing": "信息图:深入分析文本结构...", + "status_drawing": "信息图:绘制完成!", + "notification_success": "信息图已生成,{user_name}!", + "error_processing": "信息图处理失败:{error}", + "error_user_facing": "抱歉,信息图在处理时遇到错误:{error}。\n请检查Open WebUI后端日志获取更多详情。", + "status_failed": "信息图:处理失败。", + "notification_failed": "信息图生成失败,{user_name}!", + "status_rendering_image": "信息图:正在渲染图片...", + "status_image_generated": "信息图:图片已生成!", + "notification_image_success": "信息图图片已生成,{user_name}!", + "ui_title": "🧠 智能信息图", + "ui_user": "用户:", + "ui_time": "时间:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "缩小", + "ui_zoom_reset": "重置", + "ui_zoom_in": "放大", + "ui_depth_select": "展开层级", + "ui_depth_all": "全部展开", + "ui_depth_2": "展开 2 级", + "ui_depth_3": "展开 3 级", + "ui_fullscreen": "全屏", + "ui_theme": "主题", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ 无法加载信息图:缺少有效内容。", + "html_error_load_failed": "⚠️ 资源加载失败,请稍后重试。", + "js_done": "完成", + "js_failed": "失败", + "js_generating": "生成中...", + "js_filename": "信息图.png", + "js_upload_failed": "上传失败:", + "md_image_alt": "🧠 信息图", + }, + "zh-HK": { + "status_starting": "信息圖已啟動,正在為您生成信息圖...", + "error_no_content": "無法獲取有效的用戶消息內容。", + "error_text_too_short": "文本內容過短({len}字元),無法進行有效分析。請提供至少{min_len}字元的文本。", + "status_analyzing": "信息圖:深入分析文本結構...", + "status_drawing": "信息圖:繪製完成!", + "notification_success": "信息圖已生成,{user_name}!", + "error_processing": "信息圖處理失敗:{error}", + "error_user_facing": "抱歉,信息圖在處理時遇到錯誤:{error}。\n請檢查Open WebUI後端日誌獲取更多詳情。", + "status_failed": "信息圖:處理失敗。", + "notification_failed": "信息圖生成失敗,{user_name}!", + "status_rendering_image": "信息圖:正在渲染圖片...", + "status_image_generated": "信息圖:圖片已生成!", + "notification_image_success": "信息圖圖片已生成,{user_name}!", + "ui_title": "🧠 智能信息圖", + "ui_user": "用戶:", + "ui_time": "時間:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "縮小", + "ui_zoom_reset": "重置", + "ui_zoom_in": "放大", + "ui_depth_select": "展開層級", + "ui_depth_all": "全部展開", + "ui_depth_2": "展開 2 級", + "ui_depth_3": "展開 3 級", + "ui_fullscreen": "全屏", + "ui_theme": "主題", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ 無法加載信息圖:缺少有效內容。", + "html_error_load_failed": "⚠️ 資源加載失敗,請稍後重試。", + "js_done": "完成", + "js_failed": "失敗", + "js_generating": "生成中...", + "js_filename": "信息圖.png", + "js_upload_failed": "上傳失敗:", + "md_image_alt": "🧠 信息圖", + }, + "zh-TW": { + "status_starting": "信息圖已啟動,正在為您生成信息圖...", + "error_no_content": "無法獲取有效的用戶消息內容。", + "error_text_too_short": "文本內容過短({len}字元),無法進行有效分析。請提供至少{min_len}字元的文本。", + "status_analyzing": "信息圖:深入分析文本結構...", + "status_drawing": "信息圖:繪製完成!", + "notification_success": "信息圖已生成,{user_name}!", + "error_processing": "信息圖處理失敗:{error}", + "error_user_facing": "抱歉,信息圖在處理時遇到錯誤:{error}。\n請檢查Open WebUI後端日誌獲取更多詳情。", + "status_failed": "信息圖:處理失敗。", + "notification_failed": "信息圖生成失敗,{user_name}!", + "status_rendering_image": "信息圖:正在渲染圖片...", + "status_image_generated": "信息圖:圖片已生成!", + "notification_image_success": "信息圖圖片已生成,{user_name}!", + "ui_title": "🧠 智能信息圖", + "ui_user": "用戶:", + "ui_time": "時間:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "縮小", + "ui_zoom_reset": "重置", + "ui_zoom_in": "放大", + "ui_depth_select": "展開層級", + "ui_depth_all": "全部展開", + "ui_depth_2": "展開 2 級", + "ui_depth_3": "展開 3 級", + "ui_fullscreen": "全屏", + "ui_theme": "主題", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ 無法加載信息圖:缺少有效內容。", + "html_error_load_failed": "⚠️ 資源加載失敗,請稍後重試。", + "js_done": "完成", + "js_failed": "失敗", + "js_generating": "生成中...", + "js_filename": "信息圖.png", + "js_upload_failed": "上傳失敗:", + "md_image_alt": "🧠 信息圖", + }, + "ko-KR": { + "status_starting": "스마트 마인드맵이 시작되었습니다, 마인드맵을 생성 중입니다...", + "error_no_content": "유효한 사용자 메시지 내용을 가져올 수 없습니다.", + "error_text_too_short": "텍스트 내용이 너무 짧아({len}자), 효과적인 분석을 수행할 수 없습니다. 최소 {min_len}자 이상의 텍스트를 제공해 주세요.", + "status_analyzing": "스마트 마인드맵: 텍스트 구조 심층 분석 중...", + "status_drawing": "스마트 마인드맵: 그리기 완료!", + "notification_success": "마인드맵이 생성되었습니다, {user_name}님!", + "error_processing": "스마트 마인드맵 처리 실패: {error}", + "error_user_facing": "죄송합니다, 스마트 마인드맵 처리 중 오류가 발생했습니다: {error}.\n자세한 내용은 Open WebUI 백엔드 로그를 확인해 주세요.", + "status_failed": "스마트 마인드맵: 처리 실패.", + "notification_failed": "스마트 마인드맵 생성 실패, {user_name}님!", + "status_rendering_image": "스마트 마인드맵: 이미지 렌더링 중...", + "status_image_generated": "스마트 마인드맵: 이미지 생성됨!", + "notification_image_success": "마인드맵 이미지가 생성되었습니다, {user_name}님!", + "ui_title": "🧠 스마트 마인드맵", + "ui_user": "사용자:", + "ui_time": "시간:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "초기화", + "ui_zoom_in": "+", + "ui_depth_select": "레벨 확장", + "ui_depth_all": "모두 확장", + "ui_depth_2": "레벨 2", + "ui_depth_3": "레벨 3", + "ui_fullscreen": "전체 화면", + "ui_theme": "테마", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ 마인드맵을 로드할 수 없습니다: 유효한 내용이 없습니다.", + "html_error_load_failed": "⚠️ 리소스 로드 실패, 나중에 다시 시도해 주세요.", + "js_done": "완료", + "js_failed": "실패", + "js_generating": "생성 중...", + "js_filename": "infographic.png", + "js_upload_failed": "업로드 실패: ", + "md_image_alt": "🧠 마인드맵", + }, + "ja-JP": { + "status_starting": "スマートマインドマップが起動しました。マインドマップを生成しています...", + "error_no_content": "有効なユーザーメッセージの内容を取得できませんでした。", + "error_text_too_short": "テキストの内容が短すぎるため({len}文字)、効果的な分析を実行できません。少なくとも{min_len}文字のテキストを提供してください。", + "status_analyzing": "スマートマインドマップ:テキスト構造を詳細に分析中...", + "status_drawing": "スマートマインドマップ:描画完了!", + "notification_success": "マインドマップが生成されました、{user_name}さん!", + "error_processing": "スマートマインドマップ処理失敗:{error}", + "error_user_facing": "申し訳ありません、スマートマインドマップの処理中にエラーが発生しました:{error}。\n詳細については、Open WebUIバックエンドログを確認してください。", + "status_failed": "スマートマインドマップ:処理失敗。", + "notification_failed": "スマートマインドマップ生成失敗、{user_name}さん!", + "status_rendering_image": "スマートマインドマップ:画像レンダリング中...", + "status_image_generated": "スマートマインドマップ:画像生成完了!", + "notification_image_success": "マインドマップ画像が生成されました、{user_name}さん!", + "ui_title": "🧠 スマートマインドマップ", + "ui_user": "ユーザー:", + "ui_time": "時間:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "リセット", + "ui_zoom_in": "+", + "ui_depth_select": "レベル展開", + "ui_depth_all": "すべて展開", + "ui_depth_2": "レベル2", + "ui_depth_3": "レベル3", + "ui_fullscreen": "全画面", + "ui_theme": "テーマ", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ マインドマップを読み込めません:有効なコンテンツがありません。", + "html_error_load_failed": "⚠️ リソースの読み込みに失敗しました。後でもう一度お試しください。", + "js_done": "完了", + "js_failed": "失敗", + "js_generating": "生成中...", + "js_filename": "infographic.png", + "js_upload_failed": "アップロード失敗:", + "md_image_alt": "🧠 マインドマップ", + }, + "fr-FR": { + "status_starting": "Smart Infographic démarre, génération de la carte heuristique en cours...", + "error_no_content": "Impossible de récupérer le contenu valide du message utilisateur.", + "error_text_too_short": "Le contenu du texte est trop court ({len} caractères), impossible d'effectuer une analyse efficace. Veuillez fournir au moins {min_len} caractères de texte.", + "status_analyzing": "Smart Infographic : Analyse approfondie de la structure du texte...", + "status_drawing": "Smart Infographic : Dessin terminé !", + "notification_success": "La carte heuristique a été générée, {user_name} !", + "error_processing": "Échec du traitement de Smart Infographic : {error}", + "error_user_facing": "Désolé, Smart Infographic a rencontré une erreur lors du traitement : {error}.\nVeuillez vérifier les journaux backend d'Open WebUI pour plus de détails.", + "status_failed": "Smart Infographic : Échec du traitement.", + "notification_failed": "Échec de la génération de la carte heuristique, {user_name} !", + "status_rendering_image": "Smart Infographic : Rendu de l'image...", + "status_image_generated": "Smart Infographic : Image générée !", + "notification_image_success": "L'image de la carte heuristique a été générée, {user_name} !", + "ui_title": "🧠 Smart Infographic", + "ui_user": "Utilisateur :", + "ui_time": "Heure :", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "Rénitialiser", + "ui_zoom_in": "+", + "ui_depth_select": "Niveau d'expansion", + "ui_depth_all": "Tout développer", + "ui_depth_2": "Niveau 2", + "ui_depth_3": "Niveau 3", + "ui_fullscreen": "Plein écran", + "ui_theme": "Thème", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ Impossible de charger la carte heuristique : contenu valide manquant.", + "html_error_load_failed": "⚠️ Échec du chargement des ressources, veuillez réessayer plus tard.", + "js_done": "Terminé", + "js_failed": "Échec", + "js_generating": "Génération...", + "js_filename": "carte_heuristique.png", + "js_upload_failed": "Échec du téléchargement : ", + "md_image_alt": "🧠 Carte Heuristique", + }, + "de-DE": { + "status_starting": "Smart Infographic startet, Infographic wird für Sie erstellt...", + "error_no_content": "Gültiger Inhalt der Benutzernachricht konnte nicht abgerufen werden.", + "error_text_too_short": "Der Textinhalt ist zu kurz ({len} Zeichen), eine effektive Analyse ist nicht möglich. Bitte geben Sie mindestens {min_len} Zeichen Text an.", + "status_analyzing": "Smart Infographic: Detaillierte Analyse der Textstruktur...", + "status_drawing": "Smart Infographic: Zeichnen abgeschlossen!", + "notification_success": "Infographic wurde erstellt, {user_name}!", + "error_processing": "Smart Infographic Verarbeitung fehlgeschlagen: {error}", + "error_user_facing": "Entschuldigung, bei der Verarbeitung von Smart Infographic ist ein Fehler aufgetreten: {error}.\nBitte überprüfen Sie die Open WebUI Backend-Protokolle für weitere Details.", + "status_failed": "Smart Infographic: Verarbeitung fehlgeschlagen.", + "notification_failed": "Erstellung der Infographic fehlgeschlagen, {user_name}!", + "status_rendering_image": "Smart Infographic: Bild wird gerendert...", + "status_image_generated": "Smart Infographic: Bild erstellt!", + "notification_image_success": "Infographic-Bild wurde erstellt, {user_name}!", + "ui_title": "🧠 Smart Infographic", + "ui_user": "Benutzer:", + "ui_time": "Zeit:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "Zurücksetzen", + "ui_zoom_in": "+", + "ui_depth_select": "Ebene erweitern", + "ui_depth_all": "Alles erweitern", + "ui_depth_2": "Ebene 2", + "ui_depth_3": "Ebene 3", + "ui_fullscreen": "Vollbild", + "ui_theme": "Thema", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ Infographic kann nicht geladen werden: Gültiger Inhalt fehlt.", + "html_error_load_failed": "⚠️ Ressourcenladen fehlgeschlagen, bitte versuchen Sie es später erneut.", + "js_done": "Fertig", + "js_failed": "Fehlgeschlagen", + "js_generating": "Generiere...", + "js_filename": "infographic.png", + "js_upload_failed": "Upload fehlgeschlagen: ", + "md_image_alt": "🧠 Infographic", + }, + "es-ES": { + "status_starting": "Smart Infographic se está iniciando, generando mapa mental para usted...", + "error_no_content": "No se puede recuperar el contenido válido del mensaje del usuario.", + "error_text_too_short": "El contenido del texto es demasiado corto ({len} caracteres), no se puede realizar un análisis efectivo. Proporcione al menos {min_len} caracteres de texto.", + "status_analyzing": "Smart Infographic: Analizando la estructura del texto en profundidad...", + "status_drawing": "Smart Infographic: ¡Dibujo completado!", + "notification_success": "¡El mapa mental ha sido generado, {user_name}!", + "error_processing": "Falló el procesamiento de Smart Infographic: {error}", + "error_user_facing": "Lo sentimos, Smart Infographic encontró un error durante el procesamiento: {error}.\nConsulte los registros del backend de Open WebUI para más detalles.", + "status_failed": "Smart Infographic: Procesamiento fallido.", + "notification_failed": "¡La generación del mapa mental falló, {user_name}!", + "status_rendering_image": "Smart Infographic: Renderizando imagen...", + "status_image_generated": "Smart Infographic: ¡Imagen generada!", + "notification_image_success": "¡La imagen del mapa mental ha sido generada, {user_name}!", + "ui_title": "🧠 Smart Infographic", + "ui_user": "Usuario:", + "ui_time": "Hora:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "Restablecer", + "ui_zoom_in": "+", + "ui_depth_select": "Expandir Nivel", + "ui_depth_all": "Expandir Todo", + "ui_depth_2": "Nivel 2", + "ui_depth_3": "Nivel 3", + "ui_fullscreen": "Pantalla completa", + "ui_theme": "Tema", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ No se puede cargar el mapa mental: Falta contenido válido.", + "html_error_load_failed": "⚠️ Falló la carga de recursos, inténtelo de nuevo más tarde.", + "js_done": "Hecho", + "js_failed": "Fallido", + "js_generating": "Generando...", + "js_filename": "mapa_mental.png", + "js_upload_failed": "Carga fallida: ", + "md_image_alt": "🧠 Mapa Mental", + }, + "it-IT": { + "status_starting": "Smart Infographic si sta avviando, generazione mappa mentale in corso...", + "error_no_content": "Impossibile recuperare il contenuto valido del messaggio utente.", + "error_text_too_short": "Il testo è troppo breve ({len} caratteri), impossibile eseguire un'analisi efficace. Fornire almeno {min_len} caratteri di testo.", + "status_analyzing": "Smart Infographic: Analisi approfondita della struttura del testo...", + "status_drawing": "Smart Infographic: Disegno completato!", + "notification_success": "La mappa mentale è stata generata, {user_name}!", + "error_processing": "Elaborazione Smart Infographic fallita: {error}", + "error_user_facing": "Spiacenti, Smart Infographic ha riscontrato un errore durante l'elaborazione: {error}.\nControllare i log del backend di Open WebUI per ulteriori dettagli.", + "status_failed": "Smart Infographic: Elaborazione fallita.", + "notification_failed": "Generazione mappa mentale fallita, {user_name}!", + "status_rendering_image": "Smart Infographic: Rendering immagine...", + "status_image_generated": "Smart Infographic: Immagine generata!", + "notification_image_success": "L'immagine della mappa mentale è stata generata, {user_name}!", + "ui_title": "🧠 Smart Infographic", + "ui_user": "Utente:", + "ui_time": "Ora:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "Reimposta", + "ui_zoom_in": "+", + "ui_depth_select": "Espandi Livello", + "ui_depth_all": "Espandi Tutto", + "ui_depth_2": "Livello 2", + "ui_depth_3": "Livello 3", + "ui_fullscreen": "Schermo intero", + "ui_theme": "Tema", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ Impossibile caricare la mappa mentale: Contenuto valido mancante.", + "html_error_load_failed": "⚠️ Caricamento risorse fallito, riprovare più tardi.", + "js_done": "Fatto", + "js_failed": "Fallito", + "js_generating": "Generazione...", + "js_filename": "mappa_mentale.png", + "js_upload_failed": "Caricamento fallito: ", + "md_image_alt": "🧠 Mappa Mentale", + }, + "vi-VN": { + "status_starting": "Smart Infographic đang khởi động, đang tạo sơ đồ tư duy cho bạn...", + "error_no_content": "Không thể lấy nội dung tin nhắn người dùng hợp lệ.", + "error_text_too_short": "Nội dung văn bản quá ngắn ({len} ký tự), không thể thực hiện phân tích hiệu quả. Vui lòng cung cấp ít nhất {min_len} ký tự văn bản.", + "status_analyzing": "Smart Infographic: Phân tích sâu cấu trúc văn bản...", + "status_drawing": "Smart Infographic: Vẽ hoàn tất!", + "notification_success": "Sơ đồ tư duy đã được tạo, {user_name}!", + "error_processing": "Xử lý Smart Infographic thất bại: {error}", + "error_user_facing": "Xin lỗi, Smart Infographic đã gặp lỗi trong quá trình xử lý: {error}.\nVui lòng kiểm tra nhật ký backend Open WebUI để biết thêm chi tiết.", + "status_failed": "Smart Infographic: Xử lý thất bại.", + "notification_failed": "Tạo sơ đồ tư duy thất bại, {user_name}!", + "status_rendering_image": "Smart Infographic: Đang render hình ảnh...", + "status_image_generated": "Smart Infographic: Hình ảnh đã tạo!", + "notification_image_success": "Hình ảnh sơ đồ tư duy đã được tạo, {user_name}!", + "ui_title": "🧠 Smart Infographic", + "ui_user": "Người dùng:", + "ui_time": "Thời gian:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "Đặt lại", + "ui_zoom_in": "+", + "ui_depth_select": "Mở rộng Cấp độ", + "ui_depth_all": "Mở rộng Tất cả", + "ui_depth_2": "Cấp độ 2", + "ui_depth_3": "Cấp độ 3", + "ui_fullscreen": "Toàn màn hình", + "ui_theme": "Chủ đề", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ Không thể tải sơ đồ tư duy: Thiếu nội dung hợp lệ.", + "html_error_load_failed": "⚠️ Tải tài nguyên thất bại, vui lòng thử lại sau.", + "js_done": "Xong", + "js_failed": "Thất bại", + "js_generating": "Đang tạo...", + "js_filename": "sodo_tuduy.png", + "js_upload_failed": "Tải lên thất bại: ", + "md_image_alt": "🧠 Sơ đồ Tư duy", + }, + "id-ID": { + "status_starting": "Smart Infographic sedang dimulai, membuat peta pikiran untuk Anda...", + "error_no_content": "Tidak dapat mengambil konten pesan pengguna yang valid.", + "error_text_too_short": "Konten teks terlalu pendek ({len} karakter), tidak dapat melakukan analisis efektif. Harap berikan setidaknya {min_len} karakter teks.", + "status_analyzing": "Smart Infographic: Menganalisis struktur teks secara mendalam...", + "status_drawing": "Smart Infographic: Menggambar selesai!", + "notification_success": "Peta pikiran telah dibuat, {user_name}!", + "error_processing": "Pemrosesan Smart Infographic gagal: {error}", + "error_user_facing": "Maaf, Smart Infographic mengalami kesalahan saat memproses: {error}.\nSilakan periksa log backend Open WebUI untuk detail lebih lanjut.", + "status_failed": "Smart Infographic: Pemrosesan gagal.", + "notification_failed": "Pembuatan peta pikiran gagal, {user_name}!", + "status_rendering_image": "Smart Infographic: Merender gambar...", + "status_image_generated": "Smart Infographic: Gambar dibuat!", + "notification_image_success": "Gambar peta pikiran telah dibuat, {user_name}!", + "ui_title": "🧠 Smart Infographic", + "ui_user": "Pengguna:", + "ui_time": "Waktu:", + "ui_download_png": "PNG", + "ui_download_svg": "SVG", + "ui_download_md": "Markdown", + "ui_zoom_out": "-", + "ui_zoom_reset": "Atur Ulang", + "ui_zoom_in": "+", + "ui_depth_select": "Perluas Level", + "ui_depth_all": "Perluas Semua", + "ui_depth_2": "Level 2", + "ui_depth_3": "Level 3", + "ui_fullscreen": "Layar Penuh", + "ui_theme": "Tema", + "ui_footer": "Powered by Markmap", + "html_error_missing_content": "⚠️ Tidak dapat memuat peta pikiran: Konten valid hilang.", + "html_error_load_failed": "⚠️ Gagal memuat sumber daya, silakan coba lagi nanti.", + "js_done": "Selesai", + "js_failed": "Gagal", + "js_generating": "Membuat...", + "js_filename": "peta_pikiran.png", + "js_upload_failed": "Unggah gagal: ", + "md_image_alt": "🧠 Peta Pikiran", + }, +} + # ================================================================= # LLM Prompts # ================================================================= @@ -92,7 +564,7 @@ Choose the most appropriate template based on content structure. `chart-pie-plain-text`, `chart-pie-donut-plain-text`, `chart-wordcloud` *Other:* -`quadrant-quarter-simple-card`, `relation-circle-icon-badge` +`quadrant-quarter-simple-card`, `relation-circle-icon-badge`, `relation-dagre-flow-tb-simple-circle-node` **Text Capacity by Template Type:** - HIGH capacity (long descriptions OK): `list-column-*`, `compare-binary-*`, `sequence-timeline-*` @@ -110,6 +582,19 @@ Choose the most appropriate template based on content structure. - Format: filename without .svg, e.g., `coding`, `team-work` - Use `illus` field instead of `icon` +### 📊 Template to Data Field Mapping (CRITICAL) +For maximum rendering speed and stability, match the list identifier to the template kind structure. Do NOT just use `items` if a specific field exists: + +| Template Prefix | Data Field Identifier | Core Variables on Items | +| :--- | :--- | :--- | +| `list-*` | **`lists`** | `label`, `desc`, `icon` | +| `sequence-*` | **`sequences`** | `label`, `desc` | +| `compare-*` | **`compares`** | `label`, `value`, `children` | +| `chart-*` | **`values`** | `label`, `value` | +| `hierarchy-*` | **`root` + `children`** | 嵌套嵌套组合 | + +*Note: `items` can be used as a universal fallback adapter if template categorization is ambiguous.* + ### Data Structure Examples #### A. Standard List/Tree (Default) @@ -250,11 +735,23 @@ data ### Common Data Fields - `label`: Main title/label (Required) - `desc`: Description text -- `value`: Numeric value (for charts) +- `value`: Numeric value. **ONLY displayed on `chart-*` series templates**. For cards or lists, put data into `desc` instead. - `icon`: Icon name (e.g., `mdi/home`, `mdi/account`) or `ref:search:` - `children`: Nested items (for trees, SWOT, etc.) - `illus`: Illustration icon (specific to some templates like Quadrant) +### 📊 Data & Numeric Fields Standard +1. **Value Specification**: `value` MUST be a **pure number** (integer or float), without any symbols like `$`, `%`, or `¥`. +2. **Units Placement**: Put units or currency symbols into the `label` or `desc` instead. + - ❌ Wrong: `value $1.234` / `value 5.2%` + - ✅ Correct: `label USD ($)` -> `value 1.234` OR `label Rate` -> `desc 5.2%` + +### ⚠️ Strict Styling & Layout Rules +1. **Color Palette (`palette`)**: MUST use space-separated naked Hex values. Do NOT use quotes (`"`) or commas (`,`). + - ✅ Correct: `palette #4f46e5 #06b6d4 #10b981` + - ❌ Wrong: `palette "#4f46e5", "#06b6d4"` +2. **Binary Compare (`compare-binary-*`)**: The root of `compares` tree MUST contain **EXACTLY TWO** comparison objects. + ### Content Refinement Principles 1. **Brevity is King**: Infographics are visual. Keep text to a minimum. 2. **Title Limit**: Keep `label` (item titles) under 15 characters (approx. 10 Chinese characters). @@ -278,6 +775,7 @@ Please analyze the following text content and convert its core information into User Name: {user_name} Current Date/Time: {current_date_time_str} User Language: {user_language} +OpenWebUI Theme: {user_theme} --- **Text Content:** @@ -291,6 +789,8 @@ Please select the most appropriate infographic template based on text characteri - **Subtitle (`data.desc`):** **MUST** be ≤ **20 Chinese characters** (or ≤40 English characters). - **Card Title (`label`):** **MUST** be ≤ **6 Chinese characters** (or ≤12 English characters). Use 2-4 keywords only. - **Card Description (`desc`):** **MUST** be ≤ **12 Chinese characters** (or ≤24 English characters). Use short phrases. +- **Numeric Strictness:** `value` MUST be a pure number (no `$`, `%`, etc.). Append units to `label` or `desc` instead. +- **Dynamic Selection:** For multiple stats/currencies, use structures like `list-grid-*` or `list-row-*` for dense layouts. ⚠️ **CRITICAL**: If the original text is too long, you MUST rephrase and shorten it. Do NOT simply truncate with "...". Examples: @@ -365,10 +865,22 @@ CSS_TEMPLATE_INFOGRAPHIC = """ --ig-border-color: #e2e8f0; --ig-header-gradient: linear-gradient(135deg, #6366f1, #8b5cf6); } +.infographic-container-wrapper.dark { + --ig-primary-color: #818cf8; + --ig-secondary-color: #a78bfa; + --ig-tertiary-color: #34d399; + --ig-background-color: #0f172a; + --ig-card-bg-color: #1e293b; + --ig-text-color: #f8fafc; + --ig-muted-text-color: #94a3b8; + --ig-border-color: #334155; + --ig-header-gradient: linear-gradient(135deg, #4338ca, #6d28d9); +} .infographic-container-wrapper { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; line-height: 1.6; color: var(--ig-text-color); + background-color: var(--ig-background-color); height: 100%; display: flex; flex-direction: column; @@ -387,7 +899,7 @@ CSS_TEMPLATE_INFOGRAPHIC = """ .infographic-container-wrapper .user-context { font-size: 0.8em; color: var(--ig-muted-text-color); - background-color: #f1f5f9; + background-color: var(--ig-card-bg-color); padding: 8px 16px; display: flex; justify-content: space-around; @@ -402,7 +914,7 @@ CSS_TEMPLATE_INFOGRAPHIC = """ border-radius: 8px; padding: 16px; min-height: 600px; - background: #fff; + background: var(--ig-card-bg-color); overflow: visible; transition: height 0.3s ease; } @@ -414,6 +926,12 @@ CSS_TEMPLATE_INFOGRAPHIC = """ line-height: 1.3 !important; overflow: visible !important; } +.infographic-container-wrapper.dark .infographic-render-container svg text { + fill: var(--ig-text-color) !important; +} +.infographic-container-wrapper.dark .infographic-render-container svg foreignObject * { + color: var(--ig-text-color) !important; +} /* Main title styles */ .infographic-render-container svg foreignObject[data-element-type="title"] > * { font-size: 1.3em !important; @@ -640,6 +1158,7 @@ SCRIPT_TEMPLATE_INFOGRAPHIC = """ // Charts 'chart-column': 'chart-column-simple', 'quadrant': 'quadrant-quarter-simple-card', + 'relation-dagre': 'relation-dagre-flow-tb-simple-circle-node', // Legacy mappings for backward compatibility 'list-vertical': 'list-column-simple-vertical-arrow', @@ -701,6 +1220,24 @@ SCRIPT_TEMPLATE_INFOGRAPHIC = """ return; }} + // --- Auto Theme Loading --- + try {{ + const html = document.documentElement; + const body = document.body; + const htmlClass = html ? html.className : ''; + const bodyClass = body ? body.className : ''; + const htmlDataTheme = html ? html.getAttribute('data-theme') : ''; + + const wrapper = containerEl.closest('.infographic-container-wrapper'); + if (wrapper) {{ + if (htmlDataTheme === 'dark' || bodyClass.includes('dark') || htmlClass.includes('dark')) {{ + wrapper.classList.add('dark'); + }} + }} + }} catch (e) {{ + console.warn('[Infographic] Failed to apply theme class', e); + }} + try {{ const {{ Infographic }} = AntVInfographic; @@ -961,13 +1498,24 @@ class Action: def __init__(self): self.valves = self.Valves() + # Fallback mapping for variants not in TRANSLATIONS keys + self.fallback_map = { + "es-AR": "es-ES", + "es-MX": "es-ES", + "fr-CA": "fr-FR", + "en-CA": "en-US", + "en-GB": "en-US", + "en-AU": "en-US", + "de-AT": "de-DE", + } async def _get_user_context( self, __user__: Optional[Dict[str, Any]], __event_call__: Optional[Callable[[Any], Awaitable[None]]] = None, + __request__: Optional[Request] = None, ) -> Dict[str, str]: - """Safely extracts user context information.""" + """Extract basic user context with safe fallbacks.""" if isinstance(__user__, (list, tuple)): user_data = __user__[0] if __user__ else {} elif isinstance(__user__, dict): @@ -977,32 +1525,123 @@ class Action: user_id = user_data.get("id", "unknown_user") user_name = user_data.get("name", "User") + # Default from profile user_language = user_data.get("language", "en-US") + user_theme = "light" + # Level 1 Fallback: Accept-Language from __request__ headers + if ( + __request__ + and hasattr(__request__, "headers") + and "accept-language" in __request__.headers + ): + raw_lang = __request__.headers.get("accept-language", "") + if raw_lang: + user_language = raw_lang.split(",")[0].split(";")[0] + + # Priority: Document Lang > LocalStorage (Frontend) > Browser > Request Header > Profile if __event_call__: try: js_code = """ - return ( - localStorage.getItem('locale') || - localStorage.getItem('language') || - navigator.language || - 'en-US' - ); + try { + const html = document.documentElement; + const body = document.body; + const htmlClass = html ? html.className : ''; + const bodyClass = body ? body.className : ''; + const htmlDataTheme = html ? html.getAttribute('data-theme') : ''; + + let theme = 'light'; + + // 1. Check parent document's html/body class or data-theme + if (htmlDataTheme === 'dark' || bodyClass.includes('dark') || htmlClass.includes('dark')) { + theme = 'dark'; + } else if (htmlDataTheme === 'light' || bodyClass.includes('light') || htmlClass.includes('light')) { + theme = 'light'; + } else { + // 2. Check meta theme-color luma + const metas = document.querySelectorAll('meta[name="theme-color"]'); + let foundMeta = false; + if (metas.length > 0) { + const color = metas[metas.length - 1].content.trim(); + const m = color.match(/^#?([0-9a-f]{6})$/i); + if (m) { + const hex = m[1]; + const r = parseInt(hex.slice(0, 2), 16); + const g = parseInt(hex.slice(2, 4), 16); + const b = parseInt(hex.slice(4, 6), 16); + const luma = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255; + theme = luma < 0.5 ? 'dark' : 'light'; + foundMeta = true; + } + } + // 3. Check system preference + if (!foundMeta && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + theme = 'dark'; + } + } + + const lang = document.documentElement.lang || + localStorage.getItem('locale') || + localStorage.getItem('language') || + navigator.language || + 'en-US'; + + return JSON.stringify({ lang, theme }); + } catch (e) { + return JSON.stringify({ lang: 'en-US', theme: 'light' }); + } """ - frontend_lang = await __event_call__( - {"type": "execute", "data": {"code": js_code}} + # Use asyncio.wait_for to prevent hanging if frontend fails to callback + frontend_res_str = await asyncio.wait_for( + __event_call__({"type": "execute", "data": {"code": js_code}}), + timeout=2.0, ) - if frontend_lang and isinstance(frontend_lang, str): - user_language = frontend_lang + if frontend_res_str and isinstance(frontend_res_str, str): + try: + import json + frontend_res = json.loads(frontend_res_str) + user_language = frontend_res.get("lang", user_language) + user_theme = frontend_res.get("theme", user_theme) + except Exception: + user_language = frontend_res_str except Exception as e: - logger.warning(f"Failed to retrieve frontend language: {e}") + logger.warning(f"Failed to retrieve frontend language/theme: {e}") return { "user_id": user_id, "user_name": user_name, "user_language": user_language, + "user_theme": user_theme, } + def _resolve_language(self, lang: str) -> str: + """Resolve the best matching language code from the TRANSLATIONS dict.""" + target_lang = lang + if target_lang in TRANSLATIONS: + return target_lang + if hasattr(self, 'fallback_map') and target_lang in self.fallback_map: + target_lang = self.fallback_map[target_lang] + if target_lang in TRANSLATIONS: + return target_lang + if "-" in lang: + base_lang = lang.split("-")[0] + for supported_lang in TRANSLATIONS: + if supported_lang.startswith(base_lang + "-"): + return supported_lang + return "en-US" + + def _get_translation(self, lang: str, key: str, **kwargs) -> str: + """Get translated string for the given language and key.""" + target_lang = self._resolve_language(lang) + lang_dict = TRANSLATIONS.get(target_lang, TRANSLATIONS["en-US"]) + text = lang_dict.get(key, TRANSLATIONS["en-US"].get(key, key)) + if kwargs: + try: + text = text.format(**kwargs) + except Exception as e: + logger.warning(f"Translation formatting failed for {key}: {e}") + return text + def _get_chat_context( self, body: dict, __metadata__: Optional[dict] = None ) -> Dict[str, str]: @@ -1245,6 +1884,7 @@ class Action: 'sequence-horizontal': 'sequence-horizontal-zigzag-simple', 'relation-sankey': 'relation-sankey-simple', 'relation-circle': 'relation-circle-icon-badge', + 'relation-dagre': 'relation-dagre-flow-tb-simple-circle-node', 'compare-binary': 'compare-binary-horizontal-simple-vs', 'compare-swot': 'compare-swot', 'quadrant-quarter': 'quadrant-quarter-simple-card', @@ -1496,13 +2136,14 @@ class Action: __metadata__: Optional[dict] = None, __request__: Optional[Request] = None, ) -> Optional[dict]: - logger.info("Action: Infographic started (v1.4.0)") + logger.info("Action: Infographic started (v1.6.0)") # Get user information - user_ctx = await self._get_user_context(__user__, __event_call__) + user_ctx = await self._get_user_context(__user__, __event_call__, __request__) user_name = user_ctx["user_name"] user_id = user_ctx["user_id"] user_language = user_ctx["user_language"] + user_theme = user_ctx.get("user_theme", "light") # Get current time now = datetime.now() @@ -1562,11 +2203,11 @@ class Action: } await self._emit_notification( - __event_emitter__, "📊 Infographic started, generating...", "info" + __event_emitter__, self._get_translation(user_language, "status_starting"), "info" ) await self._emit_status( __event_emitter__, - "📊 Infographic: Starting generation...", + self._get_translation(user_language, "status_starting"), False, ) @@ -1576,13 +2217,14 @@ class Action: # Build prompt await self._emit_status( __event_emitter__, - "📊 Infographic: Calling AI model to analyze content...", + self._get_translation(user_language, "status_analyzing"), False, ) formatted_user_prompt = USER_PROMPT_GENERATE_INFOGRAPHIC.format( user_name=user_name, current_date_time_str=current_date_time_str, user_language=user_language, + user_theme=user_theme, long_text_content=long_text_content, ) @@ -1617,7 +2259,7 @@ class Action: await self._emit_status( __event_emitter__, - "📊 Infographic: AI analysis complete, parsing syntax...", + self._get_translation(user_language, "status_analyzing"), False, ) @@ -1631,7 +2273,7 @@ class Action: # Prepare content components await self._emit_status( __event_emitter__, - "📊 Infographic: Rendering chart...", + self._get_translation(user_language, "status_rendering_image"), False, ) content_html = ( @@ -1692,7 +2334,7 @@ class Action: await self._emit_status( __event_emitter__, - "📊 Infographic: Rendering image...", + self._get_translation(user_language, "status_rendering_image"), False, ) @@ -1712,11 +2354,11 @@ class Action: ) await self._emit_status( - __event_emitter__, "✅ Infographic: Image generated!", True + __event_emitter__, self._get_translation(user_language, "status_image_generated"), True ) await self._emit_notification( __event_emitter__, - f"📊 Infographic image generated, {user_name}!", + self._get_translation(user_language, "notification_image_success", user_name=user_name), "success", ) logger.info("Infographic generation completed in image mode") @@ -1727,11 +2369,11 @@ class Action: body["messages"][-1]["content"] = f"{original_content}\n\n{html_embed_tag}" await self._emit_status( - __event_emitter__, "✅ Infographic: Generation complete!", True + __event_emitter__, self._get_translation(user_language, "status_drawing"), True ) await self._emit_notification( __event_emitter__, - f"📊 Infographic generated, {user_name}!", + self._get_translation(user_language, "notification_success", user_name=user_name), "success", ) logger.info("Infographic generation completed") @@ -1745,11 +2387,11 @@ class Action: ] = f"{original_content}\n\n❌ **Error:** {user_facing_error}" await self._emit_status( - __event_emitter__, "❌ Infographic: Generation failed", True + __event_emitter__, self._get_translation(user_language, "status_failed"), True ) await self._emit_notification( __event_emitter__, - f"❌ Infographic generation failed, {user_name}!", + self._get_translation(user_language, "notification_failed", user_name=user_name), "error", ) diff --git a/plugins/actions/infographic/infographic_cn.png b/plugins/actions/infographic/infographic_cn.png deleted file mode 100644 index 65204d1b8bcd1eae11298be2501e729b06531772..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173326 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

*QDbg{MJLhrfW29P5B(8M786@lCA;{j%b8 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�pWLGofW||U;{o8S|IlgcnW@e!k>ZJi{__Iz-@?%;hx< z5+lnwkoZoc9(WQrs{-ElavCd^mh?}tS5^na0=(X*Fm!Cpuq3qv97!1r4x&?Fc6*Ag zPMnK}K;uE$#iW|LOxfKi-Ic$>Fp!+8jjUN+-pDCo~cwVBem`*)mUm5lru_J3jIVLtR37k5hNu~z_2IU-kD zbx?mbuIBVAy5DlH+W2w5%hA_cTT=5@oz+a={q9lwzO1* zMLrG&i5PVzW(|xMrkQVJuPo;spqz7_6Gv2>Ltm{xJEK66!7~~c>oKchM)}hxR0cuSU78X_QiMigy|0y6vo#FKoW54{B zJk`XZxVK6Y3!Q9Jqn=_+tI@_{fHA=^#3aC9*^oh=t(d|Mj5ZD9gvL~7q3Io9V*q$p z6dd(JK`Z2^6`DVOxoSK4_+kU610NS_Y$}$<ndc`U8X<>Pv5t=ol|6PrHc%)8IEo(y@xxR+jf8=0vb5LMs?YLu2 z2AVD`CZ-pU3Q$l4So}FBoI^K&BJQtME2EExesd`FGVY)o14 z;no|)qI(;xD%<=H9B7q@LeuFde;L}F6qzup5}<*6SNZc&Ll&_N($}LrvjT4gnchO- zvzAod(m5AGn6LsMhPu3UNAp3IC|os4f7o$15sAcL92a37ba)66>IJiU+9C-8J?Ssf z1&xhwjzb#Z21YduR`^?q?G7VAR1eShsW^Lh1gnC3D0r`~jKTktled9*??kOL<*(!@)8f5QXAKekZU6QA z5XyJly^(PcT&h0&%&9DJxPNZB0!M{IIz%A409>D~m?7fJi;f?GZn zWZX_O4w4y-E*TlWZp%m-0|)7bCUKgp)8IJ;oL!OZ!4{MmA~<5rYtREPG+YNnQ)Osy zVxsi-^Z}E6YKgQe__)PPdW15ez#}}NTIA<)Jr=GJDKIprVO_Z_itL2N2-wZW!g zGjotXnd%yeaP|UGKJrPBQ2|}EGMmD#7FJeh=-`M@4ItA6U5EEuk#vi4#-)Lm2UR|Z zYAtAB5E@QkiKrgQPYsNIJT}%=sh$SeutR)E9SRo;i+TJo|Bm=CHAj{MW&Gzwm4TOk zrRCiopa@*Z=U0&AL=X9Sq63Xk`X9kr8oRrN8~o!B6PGd`LgJ~G+9KJ+3`qHXSLYo- zovS{?FQ*2vu1$b7Z;eEo{YLLl_2%*dVYH|jSS#-LVaGK6*M(+yaC~CkL<~-S)l@Vg zMxu`c&jyb01n$||AHg(;OIr7>Oxf6@<0l4Nm#pen2{1Cg00GA=Kn8hJ2iPsvfQYqS zx(#7?0sb9~dv)k#On_J&i20X3e;;u?2LJR_krrl|212A&G?U!7Mhq)R*$2Yag^1aM zxznR?&=*Xse*?01hj*?IWfhohx`YHP^1>SkG_e=@qU?Ky-KdtDHnp*dcXw%Z5HmP{ zRmO=voiXBf`2fS0yU95P31aPrG<1I1w^KL3_W@WrZ zDazT0zK0rlzc&H&m6t!~azO@7*R)fb5r8KFQSeFpz(gJ6G}t_xa%axh?lDE6us%9}t8sy6*Y+mh z=VBZtdHj7yEG5M6DU4*cv{4Df59;a_RJq{m3pWk?4a5oWYmOX-(Qa!smZ31^TE2@x z>Tb!X%+1L2D99znb8y>1Hl;yTClr|U;rcxg>K^YIaiU-WN;@P5_W6I{aAjlnRpwUB z+06zAt1yn;3lAoXY|-C>+$mhs{VBH9sO7C^uN&O4BEDT{onH@54$LCEJY``kDNK25t4Smkz#l<)j!?P<@lo;z#%zf zmC$$+I3LgIEYH+Z&%>4Z6%xp=cs$h`RXIM;HVwGx-=Xxxyu9%hNaOd%4rZa(=){-j z`3JpS@pmr$$@g4(Jd9W8*Msj?Nj;k^kO-lyq5I2f6Rqg!5wCT zy?^Ca8e+`MrgnbMrpxUdhyoBoxg1OV^5p-dJJh}5ggg~)QrRT7U9Sqy%rPDq1FkBy4be8Vh}}oR0UvX35Z2c zdwI73YKw6MVL73&8ic=$j8Anezssi%DgIA2Ufy(ZeDGi6=mgS#!toFPfa9k;(HDBF z!dRA8G;QU9QBaQ*`c;zF8o9;xFuj|1w1lPM^l+;aDM}Si&1=xI1ONX7h^*k1k(IBe z4QEdrViZpV-F1}2EQNJ}Gg0P7O7?6=X1xuI5_D9JE$X$l^J@x?ZfOo=Pl4ReXFJU{ z&_lRMUBfZ}|4taL3X29l5VPF8-|GwMm&&S{gvO6@fE!xE@OqpSFu3NpCdAmR8<6Aq zjetY2xZaR2H-B7gO_m*ezq`?gO#r^zmec2r3&mBTtS!-3G%>-@8|VH_g!`aMD}b|Y zSPQ%9VtA8k_B2Zw7W{k+92PAUKC)!&ziYP9KSCxosHN(OVW>4}EfaWJ>hIbD*(@mI zT-?rEf5~umFJ8|@SRpv$$iKov95X+2C^*KsdQ6uV_HU8&uWCWdX?&1Lce-%+IXNAW zT7`dJuQDyeWPsC0#Hpy%kblXk_(x8CPpMFf7R?+}CgXBTE8ce<@^(c8$Gs}H1G)FW z+zphc8Gc&;oPg42^pA1Ip^~~(2lwwMOaCFq+mohD0ZyNP(3G@hruOUx8ZQAt=#jMy zZ#>iuj9!a`@wh8R;gq_Kg^1eKm5Ewl8!=SI!g{B=i2_X?g1%EDBuex=%VvyE{@gW< z3X0icgaJHdSjC_U@Q^0{dXzg5?oI}GwW@Ea=mfC!afERdi~L30bD}(qLwc#>c`V3I zyq%`MP}T7V`Ahf!ERPmD18Jjbd78SB zj79*&H~kI74M8AX3B;djrTk|=MXrn^I{5+Fzc77UdA<}BmF`(M#n21oTSxOr0N61a`wZ&N%W$(@|aT__o8{ZCkq23xqkg-qSkZW6Q#w~lR9kxet8KW$Cnx3 z`UPYfsA>D%rUrl9>-^8ds6+~U*$!?Wjbb0+5z6eVOZ_v)f&%{s$8~)i#O(iL?YyI! zT(^Bq0!R>rfFc$kp$Vdbx>R~XH6SXYxGXdUR8&NIKp>%M0%{1TU;&Y$VgmuGp(w=! zP?}2b1VT-yfsjD%8&^4d@3Z&0cbswmbvOXc$NSB9&foJ)spDH-1U(jXQUB-8xfIC0 ztV~U~k`=-C`LlDb=Zv`*q>E0XMU&5^oX!_^3#m;1`s?fbI&l1Vz6ABLM8?Cp^rjhU z6+^GkxRTPl%|C1Kw?}6qm|Ag<{PCbp`1!)Z-?cVgu~#2-STS}*^=9&?Kq~Esz<}Tv zT8s4$pHN})+`IDCSTJw#*pFOSK{62w&Ph?gp4LkwDGJzAaHq=SR9s8pwc`R=+a^O{^%_kwDT(c6hP}RxitJBi+;$@@%T;PNaIvH;M4_Ub zlufb!!VM~YN)=mLptMe1km@arWfj|WV`j>O*|QUVeNF`=Ov#O&Wa~-A)p!2b$-za| zdFSPMlYrhWZ__r^>)k-NQzVYOd3&dC>czG{3E01~G*uwlu8-o*4$Za%(erx zdsV@Op|x|aJjIn50;j40ZZf*0|T(rzrQ93 zP*)jnOLiXV>;<)^{be zZ!q-i%&AuFDt&r=Q{1f4q&F_q$Qk3U5?e9Qro(FAIifSi>6>2g1s4~P25DDO%1>%41ff6o7~v= z9>?=`AUiXSS2Ve0-h+tWvv=;l4HyLPLyJ&wjuS*4-BOUJ@=&nv2p81fhSeyc`OBR0M4R}fc@h14rue;3XER;cb$bA;; z8wjBB#Na&?WWZy|q}!eFMpy_ra1m>nRBxBQGvW7fzkMWW#c} zWWd(Sdli@wQg)!?A;T}!AO+v@q^~mjMt9j)jg}R^zWZIARSL(qK;is0ERzw3PNCX+ z>VIm$$Eq4HlP;4g1~)FpB7$#)4*ODT%9ZwIY=fko>v>~zhYjd*^C0&&F+RsYCmG(y z>Dch9eM3b^c<3sEBx`^!=L}zNmuO7!`SS9WlV1-2|Cat>1c(zu({Dnk>dv|~ip5+# zb}IIPo=L+H7svTd<)DYGZlhl**gLfxiz5qWBF)M0)WysAV>9!go+S?3K7@(y`#15V zY|}%}VSn?&-$mCjrL4#_l6FD5YX}uIm_aqfgbo!O=1RgXZn`gGe$)2FS(>U^0SZyj z{cr^r;K2T~bAtl*WnSUd({$h~FcyKxc;jiz-AIGm(O`ICerN;YS5WDPf5;N|1qfh= z6iTe4#h%$8MFZ98b-B$JHvvx2S|U*SXbE#r#y-`9x(^7NA2iac18!z0AbR8#%Ryk{ zpYLL-uvZ7<DmA*i(btUpmI?Lg*nvyZoy^~Og>CzgoaHkBvG zc`|=q$*z{$A2C2>>bkHDu2BgZbsBB74%WF55gMxC0@sQCqaf77Ks)4JUl4JsyRh=$ zq|*foJ9{>*MzbsD#>49)akEFQ-+GLF+S)}^8TJb$#274Q&u|VHRXkiy^$V@ak}dFM#RT>y^oX^8?^?{cZit)MCe|L5B;@V(8mV)9V~&+%%H(lQPhZf% zCG7Gm)Xg7iCd!Ldf*CE$)J%5IVfTC8Pv-iH>zr=paPn;oeGh*}?id{E{e+%N71q9{ zFZ|%p`=w?HNuBb^dhOrX_a;aLD@h9?e0Zk4(aF8ry5_dTl7ah>nDj6HK``svcM7hU zQZeE_-S>E*Lhni(5)8KiAaCn`ku$3vo3}nTMc%{1E*J>j%!V!<`&`sZVv?l#__l+* zOvjB@Q>R~moNSo!v(AXk;Is$u4+tU!IyycuKea&-aJeVQhxZfi0{Wr>jD(GNn~{f- zOry7>4ksgg9Cw1&yptZ3)dW!D9H_dM;ZWA)+sVfHAWq}{s_!!w(^g1|_rC?JZJ|AoCfd+oT}_blNu zak!>s2odq(xpVc3lp|#&VZ$UPrM{(D?bFj%16ebV`0;P_7U(zACx}M8Vz>-G9Zik$9e*dZcJ% zSNYA#KqIdd#_|%unk2$1W3*oO$0jDFq<`b7qe32pu6DZC<^*%CKeOhivXjm`_b(P~ zNi4%2#a^=VkL2t{ryaPFqPD6SH5ci=K1LAi4zUB{*^M&-n*Wvry09A=UmccLg$<<7 zegy4>t(C%V1aLC+uX;ttZUvF^s$MF9Ig+M?!U<+rtnJ*lZe4?~MpIeh|DNgqS9G9% z`j6u(3hKv7{Kg%=ctIUA-Ou%lF%g6HNpPcs){#}Sh9XBCE7Qkj$&QYlvFGq&y9-2q zGDkq-yZ@#ts8_v0zXF$59iUwPydtyK4CxyA6c394LT(l{BsAkYHrNz}QKO34B3$~Q zV0;VR%ap3vd88}^R4{3(sAXC$SCFaoY&f zkrlb`#Id#-L+3)rZ!G%U#Cwi{SZofa4dLR9cUR}utx(#(#ZJ2E^j1WM4y8^_-VQFz z(e9%>4xNa5?=h5RHfgWpEB+=R?9+lY3B-$iZW_+K^-@Zma-Nl&Hmy65xPJ%XAoqB) z8V1+II|aaBGmLe^aLuks?<)1!9L6)FntAmVdi))DW4|cLgUQ5-dRH^o$+$nU7pr0`#KbnjP$#EPIkEHC_i| z&8dr#0@g&Sr0VYeO|h`o6HBn0=KmCFOHvff)GVI-%S`R47;zHtrReSu_qEkP=Vopx zE*`HYAYuf)hB+96faqFX*<@eQE(%)40?Z_92o!k$|HzzB8G!1;mryr~UTC2z^85}R!Km}T9V(u!o2 zj40Ta?<)iP=!}WTXWC=2UZjcJ@LFBdYTM2AQXrn9VG2s^>Fm?~VHyDA7ECgcl^i7+ z`4bXKuWwU0|Fk%GXiPz@Choz#BwoAkC=8wJ6E!vbagFSO0EGURp}hq+hBs>m$h&e+ z$L75^WDauz6cc~&o?SdpQOQ`WT`-VRxcnAl^P#c3_}sK4wo)ua@NxFfMk@=Ce8r${2Ed7h~sGN_ScrzjtRU+gduRr6yM$xJBM>BT|{WqKxqc)sSWHEOd&co z?eM5d%x00Ai}pkjwa#m}xV>}TrG`1P_4+mM{TIVDNFOvR z2we+cbh5b*+#aNK4RT3RjpAvJh@6QxT@ngPIg|=>A1Vg~Kb2y$9{nd^CicGpGqUlj zd(%$nqP^Z{35!$VoO%u?W^GUj`!+`iR2-1d|tzF9#e zn$NzW?F%(Oe7vy*)cGc=L#svMSY{?i37T;ZqT1Yii&PYa;wCt?L{UG7euIiPZ#s=1 z{jlA{RFqu68q)9msWuFQbV#S^bfVsVSsucu?FDsD_jGg#-|0aJ>&A5DL&0#;wgJed z>O(dl$CvK>d{KkFNuQNr5LB$z6OUfobn?VMWd(1^r0L4o9#;gEi=K~L>#tDVD5Ybr z;As_kD_|Nx8{?N9D<^A@S9lar$|M3zEkT0ucVMPqHZ2Afs~R;8tI1Q5Mu$PjP!JU) z#K7Rc`bCI3u8BEuN~qXn9IC=Uj7XW*09?Q?pBKm+_r!oUmRZ=6WUPbJ=+d;f z3;(pvp3iK$gLkP2w8?^P8{UDR?M7{#TMGQG0Hbkjhq^HB&4V8F&; zFbR^W258Gmn&NkJA7P`SC?!z}NI~+10=mYawYlWz)Ia}e;eoI!@G(K4Ixvn3QK)z| zj7;|IU%lt(fIHmMQkEptQNV|FHHwoQOP5SC#ANj(y=EgV$&uHn9S3pAmhci%P+j5N zgv+z+^aYCEdLMd`s<9Kd71PdIWw3Ji3l()U!TejZg!XH_K4|WpJBk;B*$OV$StyP3 zM(BiT`17arXh&~z`JqgX9^cVUXbc--3J2OCTE%qM{?x{uyz;jV_TQtZ_exz4kD5_W zgGQt+;Kt5mY%p(9RF3E;bNc4kALeF*Zt0}f78`H6C#2Lu;BB)r%uy+o|M5}|5kI16 zFuRtLg1}dXs6^1GDV5W_RD+ajJlm^c#G`>>lOJ48wTZ0-X_%^=#0PLhfLuc7F9CrX z>Z&ekQfu$PiU$>w_qN_rFy=nspd>j4qK)y6jyFqCA&HhW!8ldd*fEd-t|h%Qkp6r5wzvrQ2Jv7QmpFOg(QWuKw`HvI>-avX}`!T6H6aTXieUas~??a zh{^5%u8CFYt#|sp92C!-?q`1r{WIPOb;j6;5t;0L>cFA`T21aOo^e|OFvEPG5_NQ* zbl-sdahna^9_GRJ-Xgap4(s?r-C|KtGt7mhxJ}3WnwsSpuyqy3s>Om(nQ+rvQcwDF z`9-?WylWg?dxL<8&}EVrguZAFp`+LgaHL#gDd9wJZ$Mto)Y|hzC=Q4nI0ODSiYK}T zvb62Oko)N0ORL1z^UW+ae6{7>J-65_A$5o0xXnAPn~E1-pjMTxf5*4dGtSbzyj$bi z3nLU?%Hi3#9;)D-)JNjLHALtm>l2*La#8rzvYk! zC8%51Z8^@?cfLawEIPkIql7>tff+i3$lJf61aX{k1{l1K{o8?x}lx=<@0(7RJ2_gc4%D5>T z)1CW&;Vx#cH_%;exc;MxLOVv6Cw0Pm3gO)4ecSWFS%(4=r;R-Ic;R-IiQZ+uf`~9>j^#XHR z_p3O3hoPDrP0J$ecxog}N|Oj5Frm6;Oqgv#@i=Ngbb6Dwg?-i}%E&<%~|^!^m$# zR-y99^-yzZ`FUQC18&=LQ^kEXvnGXvuJkpKLHP?aFwzt1X`YH^v&v54A|r=4A_{J* zsh~gmH|$lc|A!$Uh^*MTl1h`>nJ5BCJlm#~7x8}#85bdy!i`Vl1h&9bmPWUH{-OUS zXhko9!yZ*`A01MIoby4 z(pz%>kUY)$o}NrGQw)#e=12bv^<|#l^|NiR*be|#7c5L}7ZoFavomqk-~;jPBpUb` zTuu>|;Ft?;I-Ae#vK8jQ;-X%Wy8a-(;+)F=9B!|I;WjbtuFpMi$GDR#lpA}!)9Ss~ zqJ$XrOV7?EA-%6^nFNc0Nd2;1-f}RDx|f&GjdLV&?k!pLFi6wh8&pJGuuDRkrhbc4^ofds z!SxU4`A%3zbQX=>p>DBN-%(kWGDj)ymK)t~#{ar4#jrMOsefzwAnnnR1{x{?jWR^K zXh6+J-tHO^N*%PiC%uf0pbJTxuaQ0Nv9GGW3ywr{o%jjG=5OH~2o?hlsL!^FfJ(~0 zqx^cM6Y+R&&3eaq(7!nD{--};6B=g2|LQ^`TakcbFxHFg70F zaBoi7Q)`ODn`jUP=Q!w|HdXOv2c!mrj8DTL=~3x zSl^Pug+@1?%t*>&F)%I#(;91$NyxJXHsj4>HFBG}aX)W*=rkuTQVAvHWm?I%gu3Mqu!%BAKtE?n;`%y$9`Q!GD_D;! zn*uW@?zm%imeia%2E1fNPZ0{s2ejo^hWZfR;H(xlUp5Ax{{`DUuuxQ`K_N|YFVl-s zY}pynN-tG7z>xb1aiJLE*ek0wQp>*gMd4$cQfIt?^O91wZkQ*u1Kc<5vLxhiS)_{1 z%4RZ~r+m8;NuWZ6Ke!6bkZd;LUU25*J*8ArElE;o`lU($f}R;*RMy*eOaV^tkA$wk zywMs(V6A_g4>0AW=PW?zZP^VlI?xpDUPxsoX8dijD7SgF*)MFm>_f^Us*n|!IJx(# z85(=7lgqYioaFM2y!e9~kY0Fm;5LV}QFkRFrtf`y2HWxpplK*wQ4m}Er*6m3%OkP%(v9_@kQBx0CMw!SZ)Wm zA$qRr)zN=aSKQOuB94Twe^eC}dmO)C1Iw<9@N)aoh)*|hrle7uzYEEi2`~do?)*k9ZE{Lr-U&Q=MGFmn*UlzGpyb^%wfG?maRH3yizW`#=`Ae&&RP>5+k{Bt&8-cpoG z(AE6Ip@Hp2gqKnTy@@OO#;W4KS{v(R+~SfDo?Q-`DU{Xg5pvSE)l$e@d^n zP$7fG=r#VhOz5rc7NCOo|IpfCf!2m(B*C(9@TUyK-y%1FK z0JmYifa!kU$?3W|kH+u~rAVJBIsI1M0Ta>K15TqzQ@5j=^aH^mao^0X-sv%m?)w%~ z95&DX22Kc}8{ypN8ezv5vgZo4dNBfsP2LIRYMl_u zNmlZczs-29vd8P@@yQm8Te#X6>1sO(PM7S9DXx$2E2trkhE4P1wJhN~PkeTH$YS6# zWwTWE?n=-{CZ0v3NbKphlei&u!WA@k3a{53gFLGXjj}!--B1+H*Q*ZMxm5L>)9B=H zCj%;nq2M^>ZBu6lg_<#Ejl*C&G_^I)1iekOIOeeRvG%Vdv%zy=L4JcSmIi_)K4$sZ zr=p0ZB-_M|R-ga`)xAF8SEgpCnRlELqcFW3rDWtWxkradQbB$-K&5Qv7rrIv>k}9R z0^R2ZS5^gic17v07zaeUu5r^EIf390poOYdE~M;FobYP`$RE`Y1+_RmM>fsms>Kj& z2Zt}Cc5PFN(2jpdQ7B6*f{w#{6xgzmA~2Yy{3-Qw*EQNzsnWJ!QEcefmT0M!j2M*> z27~Q=cLBb&zmD>8-aispTaDxXw)!E_C5Qe)CnHBZwp7^danG~`PUO;r5_>`2(=~Br z)*+x-yYVst$5Rd%bCt`fPbqrj$bNdKLoGI?-m`m2yIZ)ji>~FZNeA+Byh`{wqgAJaCs zHl#^t_wi-e(pNg{l%eO+5fnax3Zc-{Ge|rof z_k3<8k^Y>ug-e54-v9M|wk1|y?ITR_0IL^$K@7Iyi+_gYad`PuJ387xFN-oGadky5 zE3Rz^Izab_=piuw&`wTe?iy{CQ8C7OIa5@$(Ltj@M*|E;ioK>8Y`XR_%|(onm?b!Y z<1zwvMLpPLe?s(r=KcdCOQU8{&nec*YwLhpLj^6NTl zK9qiE4!FTDFJj*9T<3sP8Z;vVEJ3Pc{Y!xF7aPonI)Nf2VJMPam>p|!^MRkgH1HN4 zdQ)HjRe+j4;Hr%CK9rOn5us^_0MY*+U+L>i-1vCB7v2wOsq|4UQDRxzClV7s!=x-8 zMX^Dez&$h$#AZV>wRXSRcE>yPfujxxNtxfGfE=o9kLVY=nJ#J_B%U=6ZNq@64XXv@ zT>Hyk{`Oz0lRvZDAZ-DCC6@IHh!bYP-5d%6YN26pX_+6|3g@j2TH7C@D`JuZ8n?BN zEmnk=Eu^B|ZUisI&Ie9J-Z(F3$o4E?G@10iNw6dzaDolw+BuE3e~~~?f(Bf>oO)4- z3_DnAkmlXv$1LK0RuMX0mFLA3Qp%iVkfqb$I>Ui@^F+aghM&sHNv5z5%7f4p0iVp< zrZc_iMXEP<_Y89fcd`8I>hK)(J@;#4%FuiF?6Qv?9Z_qMbirui2yo{2uQtWSNYLs1 ziz)nLV4cgA(rfpmWaBOmX5*KkDz#&6Mf@mv1h!}EDx;L`!ekgH%I)l(ui5hxEWQ|9 zr}X*CxGN0aHscLWq?z3AFZSgL`lgnqTa}HgZQv#3m%$wkaWq!2@NBj(hsfTzD z%KR)qXa*Q@j})0n6{EH2_yp7rkgOu6MY6_6pQHZK9D#Vg33*jQp21XYlK_@Sof z&_)O$_0_!S_<2!P3|3M>PePcxtefP0T1{Ld4~8(Get8%nz{5y9n8Wy6;o|w<6fXTD zpz0JEOYK%VyNGF;xu9pZmQqy|g#mVj$rk0>*qg%4*jk9o%5H0>9uDG&X9?yTd~%_RZ#_onc*>sNf?yG=iSxtBsh z=qc6FJ2qT8F0DSFdH{*mz=g|&`=p!&nR8)tEPlq4d{)ocRL~36gGP-YhD5cvz7cXd zC|t9&H(kwwzJzz0XZVWCw)+VL!#j6@AMM?JM^~PF&xLiiCq{Vvw;rNYE&nn}UTz~O z>u+5I0hN*o>u|0L=Ejdlz(#M{Scr*%S>4q4JN*a;Hb8`eDO|)?GB@Vmr0tap0jBb= zeHG##eH9JRPmvK3p@CI2=k6noKmr3q#-@Q$Zm+bUAZqyrmSL0@$^4bM7s(m;8-aB^ z|Br_F5INdrbK=kv2yrMaQlB?S9SzhtAt0AZG8w=L4}uqQ>R<&(XqdeC2Bm*-!XGyW z&#~=KkeV+9ql+q#n%DLM&KkK!%=ojszFPd15zP63>-HB;^C!0kbe4gu3?JbQ1xJG2 z5?Pd7h?+kX@HxA$F#w_asepz05*;hsyZh4PsZNXq`C>sRE0<^xRPMc)`|Op!{bJUK z$hU7NQ*PL2uSG6O%tpo_D(Y7d+4wG_N$l#7K2BuhLcw*a3>uo(x6ydX0348}ZZO9@ zDkmuudHK*7Ax5NaWp3}~*lXI?HyIyZO!v1FlExe-Zi0YCHyGxXfJayIbXx16Fjh;Y zeK&h$vVAr_0G~vy_^s@IH+8#lKUB$dC<2?6b4^>fGOM`%LkuPWJgriy&2d?AB@@Ast6e5P|@&Yl>BJlaqJb15UqjW^+Upk$? z@+#sV0n-acLjq`9!4z;K?lMYsJz!P_c6T&J&Nnqk{amT}1@)@_T95#2-zl;2UioOFUyd;f}I{x@fO1RX?Pz)aw(w*i?Ytcux1G7HLt-cdfBsiEAX zh%`9D)Hf>8GrYSYV{#Q#OId;k(&s2{DJW7TuJWW=4BdAOprlnXf_ZF6legSCbQ7?3 z3YJlwdj}$==GTr7+|HC($RpA)L{&q7nAA?WAEL6Dn;cZjFWi^=H||>#d(kFd(^ntr zyTVw^Ti7O{#svzc9@qkU2yqM#O9*)7M0la zmyVOIPeEJet`JB?z@IMB=%;a`dkhkk&@OnLEIcnm_X#LZI(f}I0@;P>E?0yfjIT4I0M8dkMyAAUDK?|>w{RtQ2n#S z8lk;|8xQZFu?5`P1i;pK3tqvQ6P;7QKM%n57O*Nq%2C54Tvgisz9PxtK-2o|d$eI7 zMN_JAG4r;N3D|3Qz}Yn70nf-e_fo1_rX4TvmGZ$l3>!RO)p$l1;D?dJ}7{0 zq?rm(Wwjm$_dX?q;`ZS5w-Q+|Kz7z7aH-K!4;>SNP|_w2fh}f|L#vjIF9HTX+KMWM znIU)qONW0nSbNYw+D8>*UOQwJ7^MJ0;l=)fJuCthk)V@3Waj4!`0HO=w7REnfe(Hp za8*t8qg*RSog;(-{0Hh;TJ}NgFX+TZ2zdRL9Qx!vM+fN z-c@>Cj@z)?Jj^nCO*7*4=mrF>&0FsFVxL4(1togzS-$x)TE0nII?V*N3H*zA2*^92 zZu7adBuRcE0xQ-hLOJt4F?VQTO=w}+yBRyH@5U?3$Qox(8!vXu-0bysBihtKOn-=m ziWxNIO5C*xY1aehudpV0S#)`oL9ZdF{(k9(`wvFgD@nSz7^8)^_b0EV7-H^c2tO%4-Pp~Bv5K-9=2yHGH)%DLEu=>w-qc+0db|bI|ZV8p_(gdkoti-t} z3ads>EIkiOoX%v-6FDX!ZJ_wzF0N%dk3wO6#NKS1Fm>4cJAVCFZ{fU zNlBdQe`Qvx!1Kc$+O;YvDmxnhN0v%_m1F0A+a~p4CobebaJ}OVw;KZ+X=980zS7Yd zstbI*&+0=m9& zRRz)2griJ7)Vw|}dF>|MeQ>Ts^6IsvTcwd}Z8v{JjZ{A8zV6xOe?IlVeEsD_6O5&c zBpD7d?c)=qP;v@NDdO_TQMS((euK@*va0=1@}<#~#B#icp)XH1APk$LBvx0<>swFZ zN=z-@$8>wD(or+$_0XvMn?E-8JD&HLjl_}YO3*0MZQl2bnB1WaSC4A87|f$}ymLHH zi_vUXS)Z(TgH4uCOPUR-3R>4uO7U)2xYkaEkHB6$b6O1MHm!Rdx>477EpRy9_~mf& zz912w{sXAtKZ7|F;8kp^7`C}oK#;E_DO&Wx|IHEw7qCR(4iMWWBLth!el1WC#DfJ2 zC#1>9Etr*ms0qcP@VaN%BtTZ-HCwx5J+Pk~f7m`IPehJ%1>Cq& z<|L~z9}4a~r)W*0cQW}Zq4E~JeGSqlOhI;c)e9gW3nq<;|1(7n)KtK*0QZiv00iN> zAdySjUAf+9${@xGQmq-06wtS=orA_}YlrQs1(z2iMZAY_*ZlpITy@;MZ^3{%TF(2s z4ZZ;fmapV|L$7QJ=E>Qt-RCB(9WklrMV2#uMi(Vhfr zVn7PK=OoVx4T!+H5o#hdHN=^n`pYwh+G`wYVr|;#v|FsR7k`L<;mdbZ?I}K2t>3+H z-Ki;4qeS{3k~XpIu8%$}k9?YfYxcbb?=T6jwY1p6Hxq@YX=jb_J^ISVM7WZOjaM9~ zJJtc^&)N;W>c#sxv;2?#M9J^p)LMttutoq_RfWj|(wPttq!FR|)H;#iZnM)xA8Seef9fOs zu$7(q8;BoSS__D`-+>%&P*@A>4>VW2pro1cyNAB1Dx{LKx?`(oP;H;A+O^v|!|sBh z-=ACJGD;|4w+$#c3MSb~Hzj|bsdYt|SaZCjuPCQe~`~@w-N`D+myB#_igF#pJmNM6mZ(gTv z%mh3pG9)P=dsmo;W9PSnp3WByPRHgT9C4zQIX*A6pkW(!6;Yv`g`RG}<|uFzI@UPt z>d3o+<}U5Fp+RX^uuli6_N+ls>5azB%i9j#I4MHZ4BM!WM)`etgH-TAXexU2W1L5q zBrJlLFqaOZ)Y<~J=s02>P9h3G?IBeSCYi&L+IfvmzWeprzUNfzgi;ysngP6|Lf~21 z<8CHj)D0&cHXV8rsgY1dc_IHWN%1Vyd}^;Gq@@Saa%)t)XT$O$b6e@X_ts&@m7)rb zHfc$1h{T*P8X5{`9pvwtVzl3qSUzU=vFIUIR_49uslo&sN8E$!41NPOW`|hNfHsg> z0};RF39cV@N0H8{JtnCcw!mzTS_X1SDgkNmZUPiZKR{XC{KpPE08jzrmgD(#uR%#9 zl;7O20`kBD4K73mXmHj4(%_l}L|z%@9cN00rX*ft5Wv9V4|r&FRwicJn+UD5RIv#8 z3Sgl@0slBrLPi$zS$6tp2Z-wI`m2YJcWnSdjXwf9|FynOO7J3<0Af)C02)OtZLa4^ zgDqXeSkOC4(^CdMH6dw0eEo$KU9rY(2JWM@O8(mq|I1j7`NrLv`Y6*MusB)2mK_CET~C=4 z@jsQXbn?9-UyXeQ>(KsTY}bvM^yQDXOJn^yI{7V2vJ~9>x{!aV{+_5LW$NkdS-zThtKP zn~N;uA-uvv*iT$1p}mJ5&TfXt_=GtGjBKSuW6fS0X)zRzM@|0l4PDa9ymMC9*z35cCa{lDv*%iVB7-E)AmsCGL4@t|2TJo}rEs=zO|7pQ|S~pRQ8dSA>GQGJL62a64 zr;IYNkK^E1lr1IEn*R$T$+#^s>0gK>n*WtC)|wsO_@=FQxAH3p>@%ZKB5PGB8F*s# z(I-@4C6#wgq67}wQ@{qMwXfvb-65fzB*mCL-pR;EiOssGC&gpEgZCA}L5{);CRHyB zC{AFlxH|#1 z%!2_p4AL}lihreP))T-MbA4yRkTCbt0%R~9Km>!6qm)a335YXjZK;$hKi|kO!G01! z-{=3)vLGzb=={jpWD&K_Dk6+`MwNlNCX)e{88T;0wZOVRYpKC1Z1@9S=m~HwlR!?1 z!^cLNJf(0B+aFPZprTAei|Dx<_aG{|*y)LDGN_(`(K5h$3oz!5Lw~#RrwDD=)@snE zmec|{yymIime_e>oD$OLW5z~02IOyk*%uxdpl8i3^~P)uN737E{TmhWpYDYo`w(cx z01tF>5K20=T!4KB_^ z*4xzbK_%_U5TRY~hWKcAeenK`GPSJ-25(Zbv(v>*%CdiIPrGXH6i&(|;I4P?>6y`9*WkZi(5b zzyRleRT0Yg@n$GkaFcGcC}$Rx0fQ?a@7CHgx;j|nB1Rlvn+_~4f<-5eNGpK|@E5HA zf6vjRcC|$a7M-{aq-70N^=S_;k*7R{=jt60M+t;rXB^5RVwVWS=di*tQq3F8c^Vfy zNoxRY(920(yUQ+QCQ0!M6{ABSu;yvQ{~OjJ?vZtd&Vo)5Cb2ErErI=uUL zfFpTtJQNTaS0i%(sE>iX4X*ef}GZ^J$cvc~1}#cBnswLO!$tQjax0pA2> zno6KC$lxvYcvKZAOujxU*3lYC=uklzS}TNm-$7`Ey$hau+Mdu;YX6lT>Oo~1O}gr= zJdrbI9v6i>iRi6J?sb|=03#CG`$_&vztLpvE1f+18=bDInWB<#B`YgadbHV!3ss?gOws$8+MhO&gS-yI^)VJd} zqZ03_ir_bhlq2_RtL8D61u?tcTXvFp*+$oUUAMeaMV zY^78o0xpgL(hsb_e^iyC?H85-i#;3Q4{?kiXYRZ45Bn4WbF^*%Y*YMShG&SyD6mc3 z0}xAy0%7ox+ZdHwZ!}(=1rcp<&wk2UHbZ4jD_N0svbh!Q9kJz4jmrEDf+GsQ_Jnxd zGxBQ{Gl$TBKZYlMu9aF>f@3`Gtv)!_NmcACNW9)vT%EPDoZZgiQM-QKgxujPGfxUb z2rJt7fSp`?L&;O4)gRj(g{(NJZoS@?1pVC6fss@wEWg6&DP_;7qK|*Ivb^G>wqsI7 zhJn1#!bj!I5Mng;H|^Y=4Fd^m;0o^1BcwFTHq$8u2e|1dbI0>bXbe&4iha~`cCi=! z_+W2^OZ*|ABbi?nH6&GGkolP@3_#6I{-^Y7X&q&da z1A^104!)&KJ&ukZ9StZtyKc=E_sBEr&TQW1y64Q~Q?~5K9HIquOSp(ki_Nx9YycT9 zL;3XbW%<{TynT5-Z{NJrXYiQ8Dw?yG-ZSVNrrxV^E`81lstWo{Z}NY5^79z;4@sU1 zZ>G9?tgTK`K^Cin@nXgA{sf9U#LTtEjTWO!7cmJ!V>K^&S8t2xRj3D6ugqjsFq3yF z8_4$EHj7DOV~57I-%R>eWKX`5ku!O!YAnNj)!?dt7}2!`b7wQsy4simQtXD{eI_ZC z-WjmnGMGU)uB-)uLPl;+Z2~tdSCJ99N41ftCg)zwmUKFAPgk2C?yiGCT%5MYl!0*- zqh*Q5Hf_tj#=tZHc;Tpne2Kq2;sP4Ds2mX^fk$J06r({t;Nb_2V$_K)P((g!{j_@3 zU=vxj9LTV^QB!T+(KDo=SI+hCdf^IJ|>R-~xKXB@NRMQ8EH)R0KVwV4gYt%CyIfa7bMC048lT`t`pok;*o!?2r>0g z|M;UW-0}vre5g*Qe^@mPZoj6jNZ0hL>Zvt_vXI&H&PUzM!*q|uz7qyzfd?iGY!E0y zFS9$#Jy@r?;|EUTXEC9sBRR}!l%CQL+KwBzBhnj~%Cfd@U43kkBk!)(9Wc5$utDKO zZO!}f+2iU~TONBxAc`-YS$I*f_O3NhV>-#r;6hjwe!G>=Aw#8XR`iA<{puN|`It{t zEL<7wxC!}gSG=(KeWcWDdaZH9=<0{4l?dSsU}EXxEGvPz&ufh7DDSfjD-1Ug`k9{WU#+QIV zno?CFSZk0mkq*XvgG!ovFZ~+47-bQe6{*IVIwMs=j%ySjxL!e$d$Gmag^=I+s<5YVQfD3hk*!bH{%Q}fsY&8 zRRSd8i`%Tz~yaA;p?tl)+}6Vl5DUm(*U;QRX?&gBJh@@4Kug5k(b z!+8GkliQn5rSn_*NT`MTHa9&UFo)lxY|=kpG+aW(v~jOU#nCuF>=L5Br?*08KlQlIs+T^u3y7O7Ivuh^ z=(*-RO*}37W&575L&mc%*TpRF&AHkY6zqR-@pHg|TNW>q+c#wpopj*aUaW#pDOk;5 zfLgc1MFH`mJRm4@_T!sxi$*dTaYJS{j$0Cd_xu#0Be3I7kBcUVmCvLaDz`uL3iTKi z+I#ZUyORPHPxRWO@$0^y?g#VJ0zfu_%PUL!s40hITD#Lqg49Lm$E` z#2xDDg^My@LnAHN>!X#$BBBtjG8zc?I*l%AcJVxK&}3`%HhUq??! z*Xa^U#p-+JECZcwFd>d^JBj4?e3-X_kEQgeAJXFVyjp1aq3y5JyI_oEtt|TE{ST!G zjn(&{2C&+b8<3aA#$weCS5`uybccsR#he6f@WmDH8W<}BY2_+R0omRNSETrbh4sQq zR8{pdDjo{cb67lAbvNolnZ%$9i;r7us0jKP9OMky&RDj*{`L*@JGyW)M7iZy;rJb1 z)~1u9+j~*nM!au1wFPt_q`2!HZx(+_oB1j-UVjox@t^b+#mRj?=Z;LBq4@nN-Az}n8bf+of( z*)_+=n`crj$>$h^tTn&YaxQc$u#2AG0P)))vj$dHU&Ore!^ATZ2*Tm#9v|t%*kr-p z(+5e2^>4v444-(1JoJsXDMNRKUJE#^M^meodZ-V*S9}{{n?(23a%{(zETt9C;4M!% zu|al4Ib(EnS{_mVrea-#)X9VbY>-Ba@K2|t)vcu1)N$+LHxdqrD-2BWVE~4Q4}EDM z2cAkS5_SVWjTaVtPgzpzhdLmhIg#RL-yoF5chD)i*omv{GcCKj$N&8?nM(=QbvTHU5C-$`Nr zVBT3YYSK8*mh}3AtJN$4M?S~vkL7a@AE0qdxE*eN+@_tjCbOLKV zgO*)Ogfo5;LdOkTACX8l)bLnkKgyv3+MA_t`8P=ZX-UwywZb#cNXAWGVukP7Mbd+jI&lyrtwe*Q1Oip-8t;k=SKdofA$u1IHP(uiW zA)#n}^l{Ob4GR!;Kv<+&O4)_(C`PA|q^Mg?oK*nr)Dz%TP<*YqyS@i`fEgRVID~xj z=>e+!$?5R3ajWoLRZLh^m!ll@T!lnUb2mp?M(G)NpWg&9y92U4tLyU&fW7I5L^%)w z)%4c^34n3`kRSI|xL`u8YN31a<;}H6LBKqE%gOu~1>Xc#@;5N>T2k?g*jS3tqf+%n zEPMG7s+jwILDi!Vs-8ho?2~bA3#eO+FnB^jX4;KRi=S z-r6JRnin=-U5sI@@v~GBv$PB=rI8WtCsi$<32iYj zcIsB&dhyB0CEwb!eW&*yiV=#NkRp+uHI2QBuf{dt7+6XLKeJ+L!g-azbd}>FODc{W zjmxmQD^j}w>3W%3zgl1T@EZMg<4RF5Jr#c!)!2>w@>}n$BUOCX>-1^SOKC$@bCKpD zNLfj8(u7$zGS3lldvvn`z_1Fc79h}!$`#u*opT<22O!FA*hG2heYIT|-c}#+jSAyU zCm~|KHZg3w?g>}RAa|sJ62x5Xh{sR4qXC)aL%eARL=4YT&+zaB71-(G+ULTTV9AI} z=k6$(wyK&K+cqBhDawu%o18alkfj4cX^8wF6@oTL(7 z_sYm1RTyG#NvZ(^W&F0HM&0kK242P#kT5HevakJbuAbJ)=EJx=9&mXJcw7gG8E?bADb}zIV3_T#}|n zwC^S(WOkm$?Lx_pIK7^f@ecn1cI`<@zpnF{eTz7i)<#u~-k=c}Iy}>*skPmzxf8N4 zS!i$VT~Vi4H;(<#{38bMOrOBW1eRmo6uF)+43>+xLiRD+^w1wARIQ`-`-Fj`-Ts&8 z<{WpBM~g$wZhrVQ{b#&)mY<1?-A12fSC!^%5++|F?6wG2hn?S>K~S~$*kyJf;n|11dBhhxx?|6B$jMHy zi~j$x_T6Dkr|Y&<2^K;?1sxy(f(j~#WuzvdXhN}oM3E}RhK=64NU@}#fDMrjK~PYN zAfSMRqKHVZQk33%DBd@^XYZMP_CELQd(VIKJTO7XFWmC z2k(DlD}*kpgQ@re$x(~!e)>FgkW7DBq(?pTEDNdK5-j?;Qs^ZjQL*Wp;-nJliKlJI zms9mOu*8JuLP+io7jyVj2wlwx>ef0Nl5M@RdeS!IGR~=*-1e>x=Z@%(Y8lR{)$Ojw z3?u~aatxa41gg!(ZFk*nHhH`Ahl8ox$alW{w&LaNF&ntvW-M9C5hF@zF;k9_Se%hm zUw^?q)~ty7sBFjRe0!6*-%??Rxm#C9;oN>Kq4RkKvT%lOfuo+S|uB+Iy0IOXG?c!tjrW6cnA^BpR!1ebzoicF#jD zei0qrApCP&cbg8LRLL19hF+1{ble)x#Qo?UGd`w}vUwdV?DxnSIF6iei0C+$G4evi zj8GDCobXPC8aGI4SgbIqDOK|GGYuy#=JZ>Va{bb_Un)VTsz|q?S6tOllQm5jMMA`$ zw}ljJ<*PXUUS@34zC*&V6K@f#VqO0s`_!sZ%J(VzCKb+}Qz5cO*A;cBwWErsZ$5PN z$E5BJ5KU#r;Cyc8baW@1-_~vr63eckUd%x5);*w2jEf!xACz>%;ZT%EcW0VKN=mos(lC{;?&=_qWo%7dBixd~78C`ZtUm6tNp$&Y z*oK!MhYvz|zDQ5oOY9{!AA zI>?cl`dzBOBQEZip8Z$P*K!I=(0`DRTQ9k{^^=qTh4Ufloz{=VQ&+#jqh@pAC55{B z=8_V@j*$QD%lPzC*I|H`WEHn(SGo z`E>B|RLnNDw?r>wo^n2>Tnv{QA?e++XUxokO9X=c4aP3r`8UT_t=xPRWD9c?9(YZ2 zTMpu;9^(!9Y5R^$ai?RoY*%>IIUT=<&x2ZIa%`-zZG7aYXIBHGeN;hx)LV7-&;Zra zlX294x!g%%B%^Swe5`$+#DF+P9$Hfj>r&9oJQ9Q;3Nzndi zw<^~r&YpaH#^ALn8$4PqIcC+GQC=p7ar{vIB#|HGWrQ6;x$6fJ_X_gpH%$0ik{?l&t?6{i2$Hb(uAiU+!4;&1-DtP^_ za0#m}hwB&iLK(b`l4T);4P&l^3j9!WJUaj8VV-D(KymTIUM;yio?BAtTufr~se8n* z8RI;kKGvT8TgrruH&810t*QjqBkn<+G;>ub`aybJ?&+yb?_EGF8T1p!S$mk53=?Wr zKns=-I zFQSJz_|vM^ulRs*2z&d1#9g~9{O$L8xrcwt`9%ro4b0q!oP?T9lkD+tT9&rRQ|Zj^ zw>S}v?p}4^BW0}pz@IW^IJlt1xg^snGFRE<_SoCcZKPE-KWdJjwmoKkXUE-5yi=Ec z=a&kjC7ac5C&>ROwea`U!yoz9ITpE8+-`0sj8Wn5kxzzU9I5uLvg2cJSBJS%wK*JV zl(7TjE0<$9=s`@6swK%v_8it;Af z=Hi96LDH^_W$k#|E_Oh?ArEPANq^K;&%ffp$ElmXLq;D~BzZ!Pi?mKo9(U{XD(49` z6FD2;bT;%v+zI7Xg&)Jxk%F&>Z~1I!ulQtHyr3$;Id%LVN2>Vs?70*Cf}eU7KXV#( zFC6b@`W}7c1k+Ar%NR9?&H1$LG($5~J{+#@MoE4VlX$5nsqWCNjKAG$(+3bqLS4P? z?PP5D{!E4f1#+`}pZ-rNpOm@q3pdK{AMwTld&GyB+c&C{bY=Fm<70AwVhyr)>;-5+ zptO&5;VVa&67CH{p}B}Y9G^6_jzlvTlvEbt>8r5Q4#jHSp63S5?!koeqmR+sG^{Gw zOpcCibI_r>AM_YX95v=UB2`i|$JuWITu&_8@FkXXCzBN*D66DdZzRe@LR^TbCP)Af zO$S~4MU$Bo?BJY)_xCm)3cmbGUs5xO!-Ls1d#}9z>afK!J<8>nO8=?+?a}jPIR2?i z>il&IK2q9|+lzlh74&;ABl9n@WaUozb&rj)3eW?%g^}|v$*Xnv(WB$ZZwJ2h7ktt8 zvIF?@qw?5L7+tj>?dqHOg2~9X{8NR)RYmQi%5vS3Uo4(X?7#SF%y&@syvvV~+@s^G zvre5|<}M#+0V{PJ%v`Hqh73$qJf?Mi;5n))m-S%hb3{L$XA#{`jsYnm+!Hz zgrZ^)pRZEs)A6m7R_&NZ5WQY1(TYeWUnv?_#%~2_U44XAr83^Oc=sFh*a6pHtWTgK}$x-GDeNry9pP1%4g7~am zk-G_Cm-NV|SPc{Js};%*w-W?DaypX0%*Gj~E_wZn^vE$MpRZ~L5Lyp#NYT;L$jIvf zh&(hP)Nz~qlPf}7xVtkc{nGu&*lFo-TL(n=){=NeRke05vqIAP0_Y?m~o}WPGI!jj~&A=*NwT=tbQBQ>7UzJ zu~^KAOr8l7)CpD_d;{N*i66lEjTpN%WV^XGb+}l%Rla=EQaCR1<6;cYqVoAgkJ%;J z6_!)XjB1BVZhNQCTyuKIor8XvUJa_xkDo9HkG2r{*r?xll%@C77C3e4$9^owPZy-& zf7}>rKQVrSd}h}mN`)ZCh3#K`n`17B*)5JyY|>sh`|XouO0>9NW0$kSigMa>dm*PA zXUuPM1T1M~tDnu>!X7pcJsFr&FMLZ56~Dwdy6SCZovx4Sc1Psj{xluGU4636GE8X(dgK9WmQK`P^dE62u8ubp>GcU z@6k8jK&9v*1eM+T7BZ)`#JE(?03Zrd}|nk9|304F;~3$$dni_7#AZ}dt(V_U}> z`^7Lfr!I^vAS&syLBs)QRU>q=zIzqy#5+07$046Iuhg6_Zr`rqxwfy}a`di*CtbVZ zZq15F$4mTjOu^2K*BMLodbvd zcX#wZFHZGZY{R!4b5V{z=Ki>4I{}MwJXcKmF@u9$^t_+i(wniHX&Iw6YTr7auKlo| zuVURDVV=<%Aq+TPB4X~$ToS{?yxxTy<(+?xY@a@H_eJd!YTfGVC7a1Zd40r7e4$ur zoCDC<-}Zi?W@jDU9J{?F21I%!YSc_+@Nb^)7|Y&0J!r}siL6f{HFu((Mc>8KY^yG< z_R;BGy)rA8R)eGb&SSK0>y?E|`S^9gPG5rL3=EDhITDClhpTS~4eZEM)|=*;_MK|o znRM=i;@834Wzy;(`^aHbYc>%Fgg{odv73_*ae-P+p#sK5Nn|}QP@i#n_Sy2rgz@nW z+xj^s#U&`*(5OP#bYBJPR4{DSkoxi2#J<%~6`a_4(peYLmyk|(3pDJYY?nl> zS9HS7TQm1>C+H$CcL5;f(pJNaxsq31zwtI$*hj~*)-m3$Pv3@1lBbk%mxcE80L+o2 z$K?#W+I!z#%4yZxzz^4lKjPxRvZxu_NgO?kt%L;@R>xp;8IfF@Ackqa1`cT=^opcN z5xx!^4}cs3*9ZwstL%^+kq2YT{%JOhY3Z?rl+;y2EWt#Xz_RUBJyw)lubpVeZjzr$dD0m?yH@?KjrR zTKD6~Jmtq=@o4A8&5P#n%&>}AK6Z*YK3keOz|6O4@{9FaG{v>9P=9jisE$4vI~Fr4h!KuPOKuX<^M5nm$IQn^+?3c< zed{AGb#7l2Re0lWep*v;554achmP-?p4XmscLcXyI4k$zdLdJTgqSqx+pHrWYCL-v zJt)lUGgSlCHFo+pxS>~(!twd6{hgQb^(CX9$3=vT%f&GE-cQvBj}@hd3$1z@c?{b8 zaG|Ty%h}|4M8H7hk9;`;ofb5EWTQEa9}~r@e)x44*irrfKK!f_t!o z-_s+o$a0M^qvT#o8!FK_8-Y(^PN*M`CWc(=z(veo{NRKE6lN=6UT;d&XuzrheSH-%vqCd z`CnpwJ|2zZ^QYTAM?iw^ze=++&;@3bV097-04W`az8si{G+>P z%x`H$FW+zW$C=l8OQ(L!AL@9%vb3(C%Wo{CKui|Xt1E3do;omdG0`kdhj0h0TY=3RQaN8J2AsTP~*RTT*I9~eWzn}#KIiMTPN zSj=8|w8{@YfzOisVMUjRFLn*fkL|pD#-r;IdRQ2}gM5imCVC#xF6rAK;`78ROci&0 z1>|M{99!U`_bs)FXD+wk_&3%``T6v?<+ok+Za2-yn+b_u2`Z=AIE^yBDlfUqOYSVW zxqCMYz;Jl|MB}5PDUXW4)!TFR2mQd~i{9?`dcfKI$l;ou4aSD)aeH5g*VR3>)4O=H z%FE(M^8gDyWV73)-I=QlyKl3*x_4X|zKal~@8bJxd_k1)PV^KJzvf{*q7|~sB-NjB z+qOT4cqJphi+ymY;BzK?{3qUK&%IxyOKbEg${i%8!6wUqhg7l>o0jW8Vw?>1FV&!6 z3RNOF_r#_5N~>AcOvYBX3=KEE#+3^of8x@LM~v@T-#w#7 z5IWSyY4Hue=c(J{KF!A3rnWA|RtW5}KvM*0=xm>^Q4l2S-Xk4|GHmOzT^kS^F2!K! z#ZhPXnd%%}pAd5NWCBahATAQRHo(h2n2wb-9O5K~KIZVQNtA;h z90qypFGnt58ni+)~_- zLco&E$nwD5U8sIICr~e3b9%LQP}|w2>Rc_9)a2$Mz8tSIA~e2TeeMj4N2>Wr&=5Jo zfg{&N{IIS^neZy!1_Ilcu7iGv8cQahHl$GNSPukfTT1}L>`+zn7D3D%%WYjmxp@Z- z&o{E?o}aH~@82heW;|RMO1(E6pUIt&I33@|liHFYv^n_0j%*hm=6)t~9W>Kk8CbSo zx;bS37&9PZN|XHVu6HxYhl)`=VW8GTJZ7%Vl6z45{FHXEot{rf=UWGiN=XsX^FqEg zMs?Zu!(`@MzS!XBz_0f`DLbIhES~&G>Tpma0DnT zdbtBXvStxBAZ8eF6={a$C4`R8(60EBMe>vg?g^~xFS*Aksp)^?H!LXSSE+Hs+^}(j zqxFA>+L)xXsg0Dmy6^?WC$iy{`m1Y|G?-{_4gz(v~at` zklCiCCZhn4_Ie3F! zg1Hhf8#^rB)YNc#J-cAOo@Lb4adNVtc600!dzc@mV{Wc>NGlCm@fS%9PNr%BFLGcr<6<< z)a+^;AeJV&z=n=a*eU=|@Ib@ab;ThC50<_THQfaLhK4+Ok##;RiTe5DjG1+DCUe}8)E9%9$uDA(2ee5(5mBvndj?mQ<@U7BN;Wmk5Z_Q|xg`zl zgHlrWP|zSC-4k@UY7v!jZHPnhC=9~D!;@~w?z*|Y<$^L+3fM0aT}29(O%RkcvT@5k z^5Fr212<&q?83RnsJ{yc4zu>aV>+&apV_#Xq~|myprqQG`w$VvPT4^gUbXjswM`qQ zW(W=o|E(M(GWCm!rIU&cs2&w{wRygzSAYf-=msRS56!vf)~>5+`fetko|7uOYwzy& zIVo#xbQ?{qb**b z2$2Qw`_p{A z%qmy~Ju-SQfEc`HOs9Re4cVq_8{NcYZ2+Gv3B+xmc(ds9@xc@R!muG`N|kV9nQPOD z?l4r!1F=w=rxHA*a0j^X4KMn+QnC9>O{To(2F{CP z_KBmpISn(0giiXLKI(Z-ToTt!ck>%b2O|w>9~{u9l<}LDa3w?Xpdu_#+c=22$k#-KP;+JV#|)^tkMg0FcoX zAzgYX?OFs`@8mN{EYh*9e$cvx1`P{H?M(yeq1gsH%zak)SV0ZjTGQh#nr2L!M8E^eR_SF5XHtw5p*!@H@k(H$fs_JUzB1)xqzX zhG$T}_Z{f$NNo57a<#9M71_#Mwj!VsfQ+>L4!-y0_U72#?gs;cMDU);=s!dNUKHxC zK}99i`u)E#yA_A{C{*Pd>bqIawYH4j_$LxAryv_;Cj;o~jSuf}^DL1;0m;_6vDE;A z3o4sc2)hc2rhTrdJXF^q!K=O6wKyI_%}r@-@~Pz z2$!{302mNMFCF#|YB=M1#Q#GE*UPt@d)pSR_yvvp_*(%OWKNgTFpa!iZcG&zvqdZE z7*lx9Le~Nb1!y2TP<83jtF|vs-l)84Fc;}_fAg*8=p^r5dF0HxQ zL+x_I{Wtq~`a-~Q*po@N+}{$*g3yBh*V#$%WntrDw*dxA za9-_yP|g__&d*@zRgDJBCb4e0T(4&jPAf7!9FqvzopyAHHv6O(EDkvhg`rKL^O$V( zBAX78D5-sXb9{qVGSFTtB|yuYws}|@-??b8O*2v$^FA%xW^cEOx^6M7 z=>g*@;~%Qv^k*Y!99xt@hQwQgOoon^(!!$@L~3eloo9^Mru!Z|q#M(vM$wu50QjB^ zYoRdLxyw#on`}ovtQ9rGq~aP+<=A`qFNe;!$hJg|!BHTf2t??5_ADRGU#*ODRyOrnQE4LH6qH3_OJOX~YP2Yd*pbP%7gVuL;-zCU6EW8bK z5OVf0>ICm+P2V4*89g_3j4zYBfu+vm9n4gKmvC2F$Ff+L8{**KJS0zx_Z*`hrXYI- z3{G4~Fwtu+S&YRd9X$~BqPTWLkFZ4R#{fBb&Fgt9p8do^SfM53lFAo9tH_3{THX!P zsp1SQtKt!X^QD3vQ@KMKUoy(eSJ6#&Q4}KUU54X3={4@vjs`*TFu>{D@>HYWBoDvQ z4uc%&XtZZBoW1sbdFmfLhvyJW&>DZF&c+gfe6&L&5c}omHg&bvb_rYcZ40E-zRn>` zc55||&rB4gS6SzHtgO+lXkPrh-O9R#y2`paMN+~aWl_s{;cTT@UmW8YlnsCUtEv9( zW3=PdSk2m#DzJKeUEz_NGSDL=mS>SsRb2$Z4;e_U(A#s?>QEcCp=wIkR%BS9%QT*()Niy`cr2hVGd0_sUPT4)8fxdP6{RVG6wQuYIL?17d{{bLeTZZ5;)apuIX0X+J*qg{f@AKx z+&nHAVhii@aK}f_>h*AsA%Sx*10;E-Z7ht&0&LiAkm*jL`ufeJnK1c#l<_kj?B(V` zd209<>2?cy?+<@kZ0e|L%{44qCD+=vqg_GyHL3Ux=2T*8dMcN6(BF}Nhj2fU^x$8i z{*Pj4d#?mj^I15Aif4ZU=`Mu^1pt^1VJnUTwDcW<^C|_~G_j|9gtiYbO`_^2d@TVt z_rIGA?xXqMSt1Vn1oD!NPckae%(>S7~;pt5MoeYwD^%Xn18h? zRQ&(i6wY}!OT2Q5Mmzg!e{VFN4{`C_5C18KwrCK!+*L7aaAKAhTOl7x6XWM{v^^kI zrXK;BaHFvqyz|7kSshCG81nA@7YU@YNtCW$Zw+;MpDAJhB~KK4_Kp7GA=*3pzc=1wLzsx_Z{D;(=3qpy#5m zEN~Pl)~kX8(YcY+>C9}N&6|IO2Qrt^tqJu;&xSI#t>Ux!I;*H%G;0z{{8;6 zx1vqN>|W{Su6&%~@PY2wsxOS+yXFxzIONn_&Kd)RX?ZR)YT%S%E-VQWrQm0pLAGM( zD(S#c{wC%&0l|Ib_bP`#A{?Dki>=(_1CPSzAn`Alz&}D zgxzMz?bhqSIQwb~$qQ&0YPlPcJyM-Lu^o~awY@*lIC$kewWb7U?-paJ{}RUA1B?#} zN&RjuhR(T`R`jfY;YEYZ`bp3tjF?7<&_q(^vTiKdZ0<(6tAt}KZm+1-l`28QcE#`6 z@OgY;IlTPVp&8$4(nR#zH~bne2hsxF>UQ4^g9hWv?xaQ4@4F7vAdiLTW40LHwXc-X zr|sAxqYre6jCQExVZdTPwY$7bVi>F0B_hgK zgJ;1Iesi8M6#6Dls*CS{-5xlY%R8*7>sWwUlyH5^W31hvE%gY?o^VLvsXDAjS!jlU zLpG6<8N@+%B2v(*_!-|U-1q|Na>$bO1-*>V;IA=Xb8wIYrJ_Z?v4xSF(v`^;C?ly0 z2yux--^5;STO!FFb}FVG`1WBC9>RL&^9l$pBI%$^FTIyIYA$hehLA0iTpZkMlfnWh z4;hH9i;CHHdMzlS=R-ok`2AndJi&FBv|5rf!4Y)P{Nc_%yI|-pDRuIi;W>QB&)#of zC8C=9s9>I|?h3>XFA}tQhUnsptDAvs>SxxZy$PzJr1}U-!jddVtmVUEKpFA4%o_f6 z*n@VV$l^FXQ@+sQ8QO3k>yn_jBr1Hn+V9YFe6Y#>hI<0>E63^5NxEa`?RIo9SLX1E z8fy7Q5@mvxaP$9n1!M~1|KZZn>TxV#8<04h4*aNGm1>jXTcxGXx#E|M$8*R}UQ>dPSwwBT8@B~Ei2cu(P zUm{=?Z5TQAIm%qH>44TpOHlrXrq5;lgzsNh@Bj1m=bmLk)rWU`3 z83LB_4gh7XN;pkxEHM!7-P-yJ0<9jRy%%uSWh5X#`dNYpD=s$?t9U_`YW!c7uytkq zR%y&K_>kg(tC89_vuao10N;o`=+t0KWvV}=3eJapSA!kTWuSdEYb}6APomGn(e58n9JO1pIfQ^~j zq%uyS^q#CNZY+p*yAXo8x*zO{kPco->j2`ph+#TCpW9XMEwM>i6~ZG)$epshizo;G zvS>6&Q@AGsQg^2IR%=&8W+07jg$YaYhJ?5TDoG%l1`Sy1K+ldGvbz{-tMjgWU)a-s?8zqwfABf1GUvKp3OzAT%FfilJvA(vR}W*pUZOL5&v11b={wLNm?=Zk`RCJx8qg zA?yF5?1{MtNB!^Hmg{y>12`TGE!(H%et_z3grH8w0{P7Cw9;p}4VEBw51x53Ms+BL zsDFc%L^^whPH}MF)xj6USMyS#hAPG{MKyS>Y_c1CeNqIWF{F7RblIywPLOHQ<}xBA zhzpBc0m0oO$hgdFPFfb%%qqINFEAr=`$0YwHMJf)Hk*b z(zu|;J!PSPf$>AH)gKqd$zzqXD&|302WVdXM+U6m)$B-ANxI_a?o2|;)+6^tr%Jc! z)pkAosEjwt-gNgxGoz$BBP~Bjf({zAjosb52E2Axz*A;r%P8VbXk0X~_x>p_H(FO0 z-!(>d<6m0Wfx&ghs*9)eNbL`8d+z4@VcG|SGPFy^szr{qVXc5L|GUQWm-KL*0If7_ z$QsLttWR+P5bJZnfFY?OGb$_;T6g4N#SMe}` zStKa&yFnn2PExeKr@LbV>A?L8*F)}aM^Ud#f*EOVzq&oIy46yY!qWS?DyoWSVf7%n z(b->3NJ&#aMu7IJ#x{#v`;B-xuh1n}kF0c~&~PT^71nWvORKq_Zs2vUl>7@^Z&9R4 z{DkYjw3VH_zu>xF>!N`x^bXcu@%S7>Y@bABbb$)N?AMF2SDfA{cJdgUVFtBafY#du zTZ+laz$f=>`$De5#i4|IVOh6mRb!K@VDG<>fgGJUe&U4DuoCEMi8)9|ZsvIw`0e_a zFKF27s}sS@r5h2MxWr({2lpXNTN-UEq4Wll?<<_c_0z&p7&VjJb8^*T-{1W1fP&#$ zMx|8+cXXt1Q>$cL+g2vu+@IGh6Q~a9V#h>Od=fxYSJH zJBPu>!^Iu(DkZBh==^W_Rl%m?dc^zfBI?p5ndHP30h7S3Dmd5fWkl-T`@`Hpq-=ID z@nhZqjgdh z5d8fiHZ+HX&Pl6ih}Y(8d=3$J!_pmgQrcBt>~5BgBKL=MJ{ilM^b4Y}J!9C{-Qn=_ zm}@D(*hq7g>Bqorm4KJMh`Jkb@>$x0lD%@K1>xgbcO~q7;FcJ$DV3AgTUwOc6U>w9 z>dmuc+C;P~+@@yaVbbt@NrJPkVlp;4W4&I@qU6$U7f*e4-zIGYLXakzCMdau88Q`m z#;asDGmN`TpPYG=4&?H7x&1nO^(_OYxrbZ-)?Dx8KX7rErqe4srhwp)AkqVq!rhJV z-n=_t2j0%4n9W~?`k(UCt~^H1lFj!I(jEQ%2mFPxBcGgZXhR~Fx@JGKVlXzXr2dqj ztSZ5%L_4Eb8F##cSDr@un)19Zt9}D4Z-Ju~#2yGDk|UyYlZkcWTqV+M?+fPE8+67& z>`&^Qb>Cc-;26ZmDA<_x#-ArsCnAhOTU{fL$~OO8H3=00lqf# z8Yt<^NAx11h8Xezxi*y!77-#4j7v6$pZBUt50EJNOwSlH;x=?>tbDxOJkL+{;2|2n zmuYw|sXi2q){2PizORA|-KOT;5NTL29K0AP02|QI{Vu z?GHJP9=@jG`Ls&!*$t|e%<6m$3RNKx67ss2d^6BgE+2*|aM8csYfXvG5DG#=s$;d7B5e7fHLW zj87d0vcFJi<$xGkt0Bq}wwk!Q8YDf+jw?Q6x2k3jnXS2F3+OvQKySn*W)!?9mYw24hE6p_Oa-&llUC5^9RZ|98g_TGs1 z-SR*Z61-nYE9w3L)pxo0z?>-AO~>M-#;8d($XW@F2vJaNQDDMo{Tz^(&b}HD(U^b2 z>Op_P>Sbc+n-l)rJgv6#K~#dqk4Yx_ zTEv?{ILD#Cc1B0IKV*1`CVTJ+H}=b^C98s~WKEgRjdvw5N@5W9%kz$T4)SvrGA~-lL?}Q1g1@lURCm zj*H(p6#IaAUGGC(uP7k+X;Jc3s9q3kS6}YVDFpIf88>%_gL5%cfhROPRd?!~Tz4k8 z!cZ7qzEI0iUT}CEQPxkIeG(g~|}*AZpMv{{7rfSmy?2t|NsKIX7>Q3v$9?j^FqocK*cw)WSA6xYGu< zKaEl+Oix<;)xxHcEdn|znMpc(SSY*P1p(MF{20^?^}kJi3;l)3sqQ?aW;6n&7o;tQ zv1o|;3-$hW`S@;dr!Uz+H>`}>dJR~!o+(cF1eE(foNKAu)$PJ)Q@;Nx@t%41(#QJ9 z-7LGcwc^~oKrAJoLWRtUb;TFa}vk!_pWc5KZJO@3Fgb7!z5; z4Ec$hyBI@zBRDEYo+FUwHM%Z!&w(%UaMI9SG`O1bhP7n$&6#WTmdzb;OvtH*_avj;v9MFU|D9DE zXQbtfZEc}ImW<(*Akj%7naBkI_5&;6VS<(W+@4`jJB_Fc(6TSGzh(5~6Y2|3JqG^4 z%tRl9ZnuX%3TIWD^o8v8}{PG+A6EH82>VVCMy*GT6rb{0)uUdZPK!t=n42&}wodDAg zGsMwLsRsFc++FQOCmgs>U|&S6{FGTfx3!;7F5~j&n@(C8!j~eb@$bRt=071y_Bh@4 z_h*QmHxu&g+k#T2o92Mi@bCTX19k~g>JTzL;Zj9kv~m`M_{_xMcn0d7(~Vhw64tHo zcixE)ak%=dfno;#u%Ih2Z#Q#hT`G~D2_9)(q&s<6*a(Y+Tonfg5>*B7*%YE|aaYP^ z3?%njGP`s$sP%Ix+zH7CUKF=dc(GyQ5V3{p&TRh{t3#hL>}3(Mqs)cD3r)P(wz`b~ z_wPEs3KgDE%UPK>hvDRh*2_WUFYf&{?icrt1XK8935!i4OkP8Kp83u7>u@StO}wn6CR2(sNeF=C(ry_p~h~?JqQZy1m~nX^ro6>=z&b*zhiBi7AeG zEw^Vo=neKk=c?YbUYqu&4C=Mii#x4`mGNp!VzD2?(%!qdS7_sC5fFZ;+*4-%4fS9fe<)*yX~tXAOKP{nI*C#{pxE;zVGs%-pPH#?v}ZU4u4 z1F-4vAm*G}A1`S!vR=7*H%~*(Z#V0BgVoPqmPv8(H1~gn=#NA|FpC4*tIfT#m_fa_ z&USD(DK~+*GFMQz&&^d0r7eq7mLR&1tr3N`FkLjekfl{hoP|`FX54n=AJ{7YER#4+MD}>OE zVv=@pw|n{ER9+toEBK({M=FHdU%-6?XuZyQ?X91AG+_vh29Z3%cXB|O5&@E5qosQD zaU0)t=i&7&|68;_PmICt;R$O)hawBrJG#m_v%nUivo?wce%?uEpW6t*eLm$X1gVvl z@H&29Hk+ApIUOW3>GN7g*kguKe~9eGVU+lE2O6U_MLx5h-w^KZxm&ApJ(fqFL=G;AZxo?wiVVK)&gy!jz^OZX;x z-!tZ>Py~z2BY@0I{m!8al#`>)C}<-yr)=&cHvfV3N#Ui^1Sy|wgp*)7MnDCUwwgpn zwKUrW^L7J3EdLoefu)l}PQ2%}CFbk~tRMFi>l3`+@(KxUnFV~6uK_Lvtnp(x#a~!I zk=+)(r62HQ;s!8A`a{~qkLC{mDm?x0tSTHt805)*fn807*1 z>)Uh+8awg}V|5Sn-@Vss!;bYx$G_#}4+>E4p38Cew>4Ck_)K^3 z`vA(2^#Q+O8;}SgCA?iIH646TE&`Q{0Stvh^KdThA)DwQhsLSlD&c+P)X`lrA!rk`!mJKC^0+tT>`*(cLBDN}WnuRA<6LBa$plP!~<;Y@b$ z_8%cZ#FoXIA^F&X_#7(uWtI^_QU}VIUw??2iGPX46b;8i*o}$?bn%sIlb%d8|0{(} znF?&msO69w^1sB*!;_d5SQ^iKGa&1=xrVE&=2nb{KZ)p&^KFPfU5EYJ`e z6>s1ScVmaKUOMtGlr{O-^gMN=xcA{`d*AhKJ|$Y$=0lMXewFiDo0JHfx4VB_b{Z#m>xe%A3mVpX?+3EtIv$IY@Q$g+^}1rGi!8P32<;(`ANsrYAv-w99eo`*ZOAOwp) z$?maRyB;DCFQu`QDSn}Qxcxv(lt;EcIqehLR(cu|+A@$Q-phPjH3o)^AE|W{rnhE= z!G%42AswBJ=bv77!NMQ&A9C`B|Av$Qc-9{7a6U6}aQX&-Pj!1H?i<_uLxzb_LsJtw zwjhe2t=N0}FE=Z5!npC2>%+}4>Q=6@MTD$3 ziel`|%72IHcYDJ~YM<`o;M+$M^tfI1@v|M!p&L1&m~3EZH%7JbqK133>@EyW3b1%;9IOeceE*aF!(o%fJ8+9UR5nv=Vz!C;HQme;5NJ8+Gc0%eo(Ayt#U+>d3 z2%;LuqrCFlKZ)({f&WO>h6)zPI!^&XpyK)O{F#b30xI5!E3wNmW!-dv-RG{So4Qkp z?n*vvHH~&_i(coXWF>08y};Gme|NSfQhK^}-UQMY`a|fctUjVNGsNLWitK((*C5zw(xdX> zPO=rjR_p!J(R5;fEq+*APWoI-5yKWUw1!B^QfVQ$JpE%Jy1j4ZHBfW zM>YOKT?4?L?sMad2I(F%d zU$*!11C5>%NsJ&)klQP8t8Z$TkB2nIc8Rs{gx zcX94j0&Pv5PgFZ0Vsr9ZeHiFxBd*+;1{&$z3hLyIi%nf1qtq?Ae{oN0W8}vpkmyxp zWqN}5FiH}DSm*2Z>66f9{I3!u?+XLGdC&`v3Fmcuq-Ww{=tB6p-nOiW45U}lnIDh2 zZFjCME35$kr=-3aB?nU7Jtv0dV(RM;*cQ#!91g9ctr zsBGk}YamY_Nk-NX3@j;J+y|K^>8>83+-2Lfoc)YTeAyTt)H&rp{r8WR0{T*1yqjST zNVWH==xr{Umuyl}lj3PGJ9*jb7g--7qYXX9e|O-sbu}v=U-z$u&h!`H4CQH%f_E1K z7Pawf8iAk*h$jWX&ORk!!%s+G5IRFr!tF8$9Mvd*-_VF^P)`Ea%pldui=Dq{ISu&& zfoUiV3Rb@wzgx^jfRzXCD9-zJ%iUMv)I?cg1IA zM+#gV|8e|;v2APEl><6)gUF_D21C!sIXoUfL{Dmp)bIL_hQPV=!qV~IF!$LB>UK5R zm)Hvb3K}_-cDq;0L;Hn#H>$YZ zUHvb>zM+2TO6KZjEF!}Ip3$US_ZcFCI!n*FcRr=V_bWebkbK74mKe>=(_rzHi+^ca zO!9Bmc7qcg@15M0ctTAqT|t@~X2x{#zF@7@XtiVlULTJ^fb^%u0uzEKQb6)uzu_l$ zk4P(gC5ihbwvmM`>%U>{U4gkTpHwvR(ufd|)-(UIVnt&6;=3UIFuyrUPJz71d@Bp@ zY^^PfA^#1{w~INxaSedjqnU$upDe|P*CNtheHd+`NzB$zV|A;I#$l6KdN;wdk6B`; zKzI5kw2gG{w$Qe}=l(hV3*)#};`&V%e}H-G42WyA_X%356rdTAMe_*OW$<*uSM#@i zz=EH|t+_X_$i){P86&rrLlIGIQUO?dtRk#yn~!FU^~jhEEo0zs7fOZC!`TLr-k&Sl zKK&2S0>3_@`R%w}@l(q|7D-tH=B*|W)Ngb4U+@sm!<}POf^b}OYH*cs+g3^fQ*vhl zAy;sl@dgNhxZU|M@Q0+UFeolzck^aC*S?vT0)jL#dqDV+3ml8x zxymKd&sc_97y5K4S<+?O)uzU%{{vcIqFeDJ>~+CoL`#^4g_}*vRv2-=E?4AU9|j9N zPq2%>`%z@F-8wPJW{V3xS>UC6V_phzQZGRfJ1wUW`_je^ZA$`&mn6xK@n*k+ALcYC zA3IP_2P{`MPo}x|lR8%t6BdXXb6y&!}4WMm%M1ue%!DORPti9=EYw*%ezU z)O%XC5F7)kdNGc^`;*`i3c;RgAB}|zXjLwV8ECf$5*x-R?8VrBY{uJqsFmlbgbhCz zH`!8mjGEG0>JV&nGGvmU3LoGgB15;@@gV6A&^dMB%Gd$%nM~iXA6ns(>AnwzF-v0{ zoSb`&0zPl7l!9xp^W>dLF%0F4)@Z*fF1W}7uY@aKiB-`fxoWfEAOg6P0Wqiv5LN*? z%?;-my``yA()V=E{bK<5C9FRJHaFO}p~*ZDOBec!{==*3?Wy3Zf5Y`F^ z7Po?xPWzE#;6~V?_A@~jH-^kpeZ`jm>OJgX&}HWx-2XZAf&0u64U4jtB_qh&*g7gw4mV|NI7;naQ3jx6u_Vq$AoUA3-)s^#db zzfEJa5}_S-Q*+j7MX#_pA+~J){%D&j-aF71Lns#z6vEutPbIRY{1L#yYWu&P&CH)J zmDK!$-Y{EQb|0HKt7 z)A6Ygz;KP9p9Zcevc=bBdzPsOu6?*KR50RIv%A3wW1~%x4ysfR#l)*0mD6gv;WBN4 z+^D*kPrz>cbU!HJ^bbVQIAq!RjpsJO16Qn62BEQ_?W-*#-I8Iu?|;nzLE22%v-~jw zq^o1T@YCj=Afxtd357x`I7fz6A?5*u_r|{?&7ate-?$!`jtg*A?1a-ombu*vV7y9aD)SF(daOttv zZlenv-3D5o>%(q`2~c@88!nXa^sNb(xs;Dn3opa!Vy!?@m14JZn^h+HMwIy}mw;2Y z2IQzz9@04wv40hrG($raqKDeE>e6M4(HRJswGUWG*S(K;ZD6P2xg#u9%QI-@##KQG z+b-i}jPOK=CI6+R*D|{ho2uuX z!1`i_R=NhtldN9o*k#;NBK#{gJ*ZMaO@F18Ex0d;=$HPs(EJ|0@8FsuyMxgnKz)JF!-+A0jG16zlwbHI zq2YCEsGE71^-eHS<)n=DkX+b$?njRtz4f7T(}_G{`5yxR zG;?(8AS&m{&w*npnZ*lRL-|b08qTauyge4@L8tLp;#Me)7oy9by_pOiU9=M9WPo0_gtQYlpXANT*7w&l>zEG_5FDw>u~(6?@| zoJ$rg+=vmSgoPV$M zWwMaQ1?mCtWcpRjdK|gLisaDfx;XnvC{{V=(g9Rl^~Xk4yuL^4;Z9`KR)`Ll>boHn zrMr#`mJG)4*cqML{`Uv>MRJ7AY?s-6{M%V;(|tG28s%(0apL5KhK-vaL|V5&uHsK3 zzn3A8n>6Tr@|?>CCVpoCeU0BxVo_#)_sbIf_d9wIr0y&QFjnEK7cFsu+VyY3%8w#{ zC0dn0qSf`3jsIR@U;QcYZwmXvM>dHbFn=$jX6W-QrdCeKHin;OI2U(?%U0hDWE7(i zkp}``lHvPALTyYFTo8ZL@faA4%Gi5?R4EU{`u%@$A*&;F%OR-}PnX_WIF3fN5Ye z`r8Oe|A)Qz3~O?0!bT|p0#ZVgASDDsSDGRqy+|(#A|RbmM3gEJq(kUEbfs7*Dky>? zz4xvHqDZfTKxh&ml=Falzwh4f_Pfq^exLo1g!MdGW!9{F?pZU#WAa}{|CyqA2H@d6 z!RAOfbJ-68;i{KH0!cOkjg%*z%hQ`X34rIaGvVu6!pVgw{dRPu<$V4>uIyw&_&o1sdrB)C}O%I>D^kaJjiLMtnjxY+uqO*V_;Ao(Tw|zW^Kx zFKa&#>UZaDe|t-v2*k^(CjwbDP9tVrfWS`pDVcA4^U&^;#jk5o*14|e$yAu@8Pt3K zB!aK%r4~?jA^byUGOL{$K;_Mi!%ohD8sHpw4!A=Be6!uS4_JTPjOV1~l-%bM!N3ai z{23+-+^Nx6>>%n;GoEkr_G>((bs@t=OuYV1GknGH*2%^CC*+uuJZhvf&vZ!A&mF5# zO`jlpEm;^d&{Gs5Dxo|ZrVczfT`4n$P@~$IzG>~adXgPvYTtNZPn1V)6WyUo4TO90 zpE|eDLP;63%Czi2PSBl`u-((xSbX(2W%-VChlbz;l3^>r4w{?>Fc)wm_(t#x0CAB6 zQV*m&|0j-rb|c@eiY2f85D34!u8ab%g5B7c#Zc2mKnXY85~&k&4_6$r&u@lKRshx9 z1VkRvMJ2)iyk7qph?D($ZY5>UG>T0iyg2OiRuXVq@5khB9I%pMK)I2o z07hpT;7mNZa4kS|Lih8^RenB61$jac1C*Q2&vZ`0PrX1&0ctnj z=PEJW@>2)U_eB7Z-~I4SmJ`TCnQ>1DuD^5y9BK@-MEb1<^_NL7e_XbIYWosXD|%1- zzkI&?{gb>^2D*tMfEV=u$_g7jBs@8oZUauRsH8tH?f^esmy0AP*9S^fRLQkciMgXX zQ_{G907-|mg8qlh-zcgpo;~^xlrMY_lt_yF5(#1L%YtDVONTArJtOu9vYT`!q_jMH z7qGH>jUh@F@LB>Xi0N##fU+xBK>vHuo}}se>Pa!T^Mp3ynYY{MfdzmUkm=%+F) zM7B!swfWdh9SA!m_!G^{RtT0i2twmbFOPd$1#c9wV|$z zLO2SB?#1DW@sdCSY?89-+G=8XbIp`q1HH~%1@vK}UO z7KqCI7!Nu1*Ldj$0Zs+Lae6N?MWh#S6)FGn!-TNmXjpS0xuf?t^)8;8u+t$>;R>Iefq_fDS_B46mHgrM{I)tkS>^zj>x}_MzqP{pWz%=tC=+zE@$&X_84GkF z`}FiSqbES-J30vabVMN3#yqg28-zf1yKN{PGd&yo8T8AKXmWKbgx0NUStWhM_XJj; zXu0x7HUQLLUJBkCk(9sYW*76B`-(k1yFnDhA@C|nW#1S}#}U2e+C|M}08}o~v8BZ4 z1K(8$SaTxOUXUyS0khP5v^z}Iihj+?zEaoPuHJ@JSYi*JZ~3DKM#PwX#_E&)K)6bJ=f-6x=>dk=&kr}LHOsR5N{u@V4Bu|`u7 zVd64=lGHZnu7+Q$It@bf{cUb?+M8}KUN4KatR_8G1$5Hv(Fd^`<|L#IzAC^qbM+7a zc==V}9R5oo15cDamv9oSX7wIzfIovIK84Nzz!t zb^>IOXd~2$QiK#r{GX4K0Z1zsdVoMh>X3nn4|b_s>)-p`WBzZ0zqD7dc|1%*4$(*C z-TuoP{?Z^w^i73mBS>AIsFzfXrSpG(>yMVfv(ls)1lB}oat{03zyGDF%7oxLouJ4q zt_qnWRL!1r?>D}Y@ zX3@ori+^3bUoXd>B|c3Bqa7r2(%avy@=3#;%cPo7ai@-k`#~b6l`dbEQ?`;En#|L)~){3%m5Da*fQ62KSURbZ*3q%miIiVis|2zx7s`8k;QAsO zdPXpT1E(u(r6%e+-skOUxj)*%dK}kr{Dld-RKMS+Cb`CvfR_v4ok4PzHbN!qe+?{w z91>u)uB99b-Q65%826uQ32Z>^t=r{3+J2CAFma~Zq5iw)ovOK6Bb_U0FuD$01jy2| zzCJd1UNi_d(tsLt?81%IV2^L%X5<5l9>4;APS%$AuHaidU20eB*TPM)7lb5s@G|># zunk$inZ*sA!`&J2{m)#J(v=(dcI5<5?{VC)Mo%4001}(C_-qotk+(P{=dhZ|G2@`qCuY3BM?-A7xJMmgJ z3N>u*zn*96S7XO3dT+7O+|RAsi7{U}Gl85Ov3z5T*QuCn`06o!N82ZRDbSnsV!R1I zsStkKbDU+;&Eme)e3n)WmP?!*;)8uKEvUzi`3S=o%VJXoh<%O)Wns=Z_^VPQ#yrOd>^>#bxwTTOmndTd0))*(rgSIfr;3%bW?H zeeMY#yN3fFmYbwC31fFt`ny&SMC^b~GvWI=B3Z&-Tml1hIqG7%N+NP?DS5Cgpj*fK z2dJ~p|LJa4j1X4$!R!kGMUPEixexx^1|#=3*>mvUP|tb!=Omw)*v96`F3#wAmC1RJ z9ayk zA8PmFSR-ej)kk_p__P_XE+obl{h@gCT=&oZ>UFW7dSpJY+y~U^Ejy9P1CCO!?VE6s z+><(J_Nu%DDWAAGw*vNO9}IK9CqD`F+{_#g^dB}ILiONc1?2-hhJP^R;Bv?sEMiT4 zw3XUh*^~VWtG<64_|m~ug2&5mUm%?iHF1`Oj?* ze8atYD7heaP&_X1r|ey-+#6rMy6CxsqiWX)$_hB@U~HNa+RO)A4mIEV6nNA#k@vn3 z48bh~b~D}aw%l{QN2|Qa4P8tX*3cT@w{&)s+fzblFlt0rF1GD<25h!1uN=j+efqJv zdwA$O(0^4PJ((Q=6~<~nzZ^n8IyE+oK| zh*a1c{JvNmd>pWCfDG3rb;;#cFOy1N7K2@p(XGF4z4Cg$`Bm%)>BcSmsH=PcTxuKY z>Vk1g-bxSj4zEjMsD8bm+CEMuv9&1|`4e_HR6bq-8#b`Ey%nylSIjI87juojNuHQ+ ze8{vSH80zdp&y%rT(15v&4mI!i}iBG<)UELX%!^-;&{ZRdaXviGWh;m?~_l(?=qfj=Xl7k<(=UZBot?zrP zMMSwurfd3lr}%hm$RQ(5++D&?G|+sgL(_rx9l0Av2@bQ5J&A1Bkj*zZnT7Yv+l}NN zjW@vd)X>^j;AF5hpZ?XS#p{5$uWoN7jCl7e@Stf zZ`LZg(VNjEeqw}N=7S4i1 zc|Tdks$_3numsP^YnOV|3@FxTy|0%W=%BgR-nhX+Y|5j6h({+Tv+R5#+L%2@4tb(C zCu``u-pnFWRn?s_m$@u zC~qafN6waI@H}j&RGoB4S1qYSNFradVyrPlF2(Wen&;eGFy4R8-O@q`8IMqRtk&!S zb&hq+>1T`G<6_mTQta?xw6Pi?he)_>JZz9P)Zx;g<)HIGt(3C(w7y=MJ(BIb#EBrB zdob;B)*T=mvBCy6OdI!SoF+tHj(Iy^C6${+5Xp0gpl|3k_Yx@_RuAK`$vOvfnf48C z#c2CK+QLcM$y8!D@Ly{_JDEP3;#=(isfRwAEVr=D!MRRA$3T&O>Rn{fHI>J*loeH# zZczkDpw5&^SD29yp?>rI7N>3|qdno=gGKlbDi2X|5HVlp5SW*%wO{o;@cLX#X%?}i z#avAAwq4TR)@JbehMME@)}5-(m6X!i`iL!D$4GREA)wR9A+&;)pOXn*v~jb%N#OYD zUYAIai_0)IEMWMt)^~TsU;pTBYzOy1hb&C}YSqS>5`O`#bSLtXOWd|dOGss7y?3m z_`6rF+$v?FK=Gp5t{)tt=kU@PmAns37|KL`anzd9t*M{M*!$C^bZ^Vd>yuNCcuLJ# zr6ddeBx2ZjRlqxL$x-RjIhUeR&jtoUS>QP~30Egz>&8mUMLSX+@&T7C;)C^Vo_R^r zb7%+MXz;0^o|#?pbJDuD5j=SXxWx?ajY_w@y6O}nTpJ=8(b2kYy$4AZZW8*;Z+S&u z0*ooHT3e{We4B5OD^EzpZxCmQy50vMD*=BS>BKXjdd>(?NsNK2Y9pn!^6^%Fhrl=P zz4PzF&zG`zR86;d>~Amn5h5@f?&Dv|UFmsp)z-W;yn24>OYCPv(@oqacNb2Wf43!f z^XJ&y!;wk%in=GMEGj%U@Ixzul?-=q^Xhq0S}f8#`FxEE%2zl&TiXG$RX9y+u&E=I^X89Met>jfxM@_~q# z`t9KZDr;EgS*`)o8D1G(_RuU-j9U331Gy9bld0~MdG9RKoR~!OO^I_?+!l@wr)zG# z48i!(BzFi#4U8^!9>%XZtlli~KQTpMClk6J_e$~PSgZP&PIK1VjX%Nl(e}ptQ%V3oka%I%H`8;M>wU(vacO3*~cbEJj(Op^X$uN4)rnX7!jt5`2WE=SR; zUq7T_c{bBq$WnFQ+o(5u^$EhWNW#J*0=5<#+!9SFLC7hw_IiDwE-8g26Uy0u0Fv{A zH0ErY?#oL#06XcCF0QoOm#?7je3YWbgDI)1VMBCY;{#lKPhHxh^%oa{*P?apqT_t! z+;}_1xs!wjZy@$KN}>=z1U_92bNcLjInf@RQL6w!Gv=?1;lBJDaOW+FH}=`RcqjXu zdaw9Cl6$9S?0fgDuuhSN?E5ifGgY16`!1 zvFxh_QW`eb>rFeoql}-v+1_vd#uF&0M5f`cWWkiwNb&QWE`QRNMyzQy*UWCBe=Aq0 zKVsVW0c-whRf9av*Gavsa|o$5s&e$vuv(}B_IYs*UT5)#$#8D$fL(uTz4Y}~!Mjvq z+chRxDWNn1T1>NSA%gvm4I+)et%0>C-3TYMX$Kpj^~tEwdE@vs?dg^EHqD(EK6l3) zvZ0HW?q)Qiq<6ZfW=J(BkZXsZBx-S)+~kStW@}U?{J@0UIWyAj)!nFnzrEi%#DM?g*%W8vxa$|=t#a6;>hCe zan3n8U{`8bfN0AlAcSqA?3CsFTD=@Gu zH_;9iH;=tqA5q25>XVys3tqUh;U*tYm_h#+EB8@1spuOoBHLxA=r2b=j*Y3-UCeH~ zckETm7ZQcWL?BBMTTPu6N%a<`F$@6d!To!XInmfh4^PmEi}d_c-8Wvfi_`K;A(e%6 zY+7_2?y`FWa%WM*cfb%I=gnNZDygKaV+7&@66Fa9m*S1r!RO1-^ytC)!3JJ_+yb8h);Wf3v-!v3yHCsP$!uj%Uz2^&oInG~~eKHP*{gZguLpg39iGF{#DB(uyF_gaKXgl*ewcIz8o3&6JTNWu4~ z?&Fh@Xd(|mf~t{p6?L7b9$m<}(gW7qbAQ^YfY9msZ&V&{;K;B%3ZPPk`yb86VjooM z?C&-+wAhi1w?<%WXGt`&-{z?lZj!t@>!7;QPR9`v&^?>7$dTb$*%%G$hdB_ zd|53A{iA}<0jb}Q3@2LV7QhLCK(+AnN+DW~%6f#*0>}Q^ZjW!RZ!$f-h=uR$RI&Q_ z_i95`(C|QAJ8UHxiaL5RM?9*w(I8}MB042WLzxpdr3i;^MlF#jwfuE8siP)tgs&I@<$AHXS73QZSn^Rc_7 zUzwm)t0^`xE@bC9&i|2)SLtyjw=0}Cwc|3*|J?$1;ME7jEY~q885FNgrGzogagg-9 zw}zZ?JFxh``Cq2Oc8BF|jDnm+f3SOimPVX0(cFT?did6w7XLRONc6Drd|W8FZhiD3 zVKYtJ?7V-_0P@(T3aB<&^2k(C*?D_C7Y|eSi-?HI;#x{t1PCLf-}12i;QXJhrd!7<9w&v8spI)Wah*^id5V-~W6!$tA00hhEd_xWO1n4m_db}`b+yrP z@OkoCrpz^fr#UUrb^%4j-iu`?)6?^6CT&FOLFvs$1W8{Mh9N#BVYhuWh-{;X^9+l- z12;BU^H%OI*RE}+-LN}j^daNn=yckR)JOgN+v9;UR#E4>oo-nn~lny3^SZSN+s zV!sUZw>+AmlZw_-MY|C9A46ENn}ErXi4{sPSTNV~xvL$-YTv8p6IUf{Icwh5m;wS9 zh;`%N+)zyH@aqH`J_zX$KAsn@BZXWk_~6TLB)FJ-XtPKcb@?@~fug~n(7bV`CVYfe zFEZtAT=qa+X3HfGjp#}x1H{CN6f(*9_A3*UrGW?eD?#fA4> zm2CKifzJ|^dj0*bbcH=SlPwbF#Tae{Pq@w0;z|qnz_UJCZ=Igj@_sAc}h6 z4bvE!^~0=CCo~-9lzd@P)d1%elut=kNrmAQj(XUAWz=8R%-@-BnBrElS>9pT;7s68 z2MqXI7247m`|=Wcx^wQ&%ssSqh-~`-bB}C~9iw?`+NS^`jL#rQ5@jqQ!FY*{bF(fE zz-q?ZlMy3t#$SEmoa`}Mp6@@Zp|m-_z(~7KI%qtmDI}Cc)ZFVYv$-qMrva*7yX^h2 zyw*bN_z11r;sLQVJ%3c&f&V(s?c-#VgWs$%{EiiSWEO@3Db_~^ zbb>l-wNK2HJ3ox+RK6aTLDTMOnF|AQDBQWLBxqbBop4}$JbB|FU4!llAcK>E^sfNr zj;!sC3w|h8S>=HhAmlXAHgkxqC&#-DI|QklZB&Norl9ZNB~Sjjd6Y1lcZ=!h;`vwG zr56x9bM_S2L-m~2*8tH;hD(mEioA@Juoj~tFc7k>xdCl)LP(@<=B_;?A=1m_N&Yse zg9vJ+*nai`ERQ1g}FA%cmt|qx9wbEcx*S1J~5P{E}XH+_QGBwdonr+ND z$pdArBa5+R)y;~?msj13P2sBX>8&Xr8aHpL+ce8Ajy1?vps{vF7A150?iN0|ZVhj{ zX33AeoMuw->mI&wzsUWPG=jaa0|5)Nq}#B-gN@OSn`16HlkjB zLWG>K%g$df;ZRm7n}qM$S+!HHwnmgk5;)}q0(GN1s+w*``dH-6A<*j*r`EqYB< zNIKCl|F%cRxwSQRb8`8iQ+QrzETJ>Pt!~{6lQ*D~-&N=3l-A@~w2+eHYfKJGFu_o{ z7i*Ev<>>Jfis3}NcB`Z4YtK5D)0yx_J-kr{2F|7zX;=aAGkj6y-BUK_#~oWYWe^Kv z8EK3B!zKl_4eI)>ht6D4WgiwfTb)q4w2!Mt&OTMOnUEbBS{C*IB-Da@{%1yfTt-?4 zW6}MKcEy##@-?RI3Zhcis#@-lCl3A0B$$RN^~j^mbF~(@Yhd=J#|)iFN_vj6+yigT zb?p%v&L|QY-o3IInyZc;GeuRi>q`UUwhfit=^>-S4*}ChhFY|}XUo0gs+{&@!1C4W znHjy$Qdc)8Grw%PF4p(^=g7okrDKDiF%ydd^^-`e9NlJTV!Y)Z7c51kT&v%%p^p0! zxYULVVj)SQ|J1DIe0hd;S(e!8Ms(4#%H5X=4`@M%n0* z`e^3i7urqLcnuw8ll_c2d=TCrl%UtHAXn&7LPEz;Ub?teafy)A-BT*}z`U^i`qAfR zbUZ89WS=`@oO?-3Eqmz(2FC~&(C>&=Cg~FPW<@M49z1jEn#`@WRL6+2vh10rVxQw@ zvWxccQ*vsv7wg3uu8+l$Lv({*>`%?JXdT409TH`=7`K2TrH?-y65N+RkaOR=_Hb<_ zM#ys26Lb8%^I(;~M6{k^L9UpDH+7NUQs@r7paDBEPWBwk%P)KHif~kLQAy3KWKF)Z z6jn{4INFKMszH%;)B=yfSk=$U_ygX{J2G~YRT8(g+I0%NC`bbV+VSQ4a5)oqS)Y5( zOXN@u8J$BHzvb!+bR1ea25ZKsmN^)4)ggkMM?-9nI{5f=Pv6$91g(C-qqCWx;bj9E z5?o&Q(g|p1^6d%ly}3lFFMSrM3Yr%dsXCu~Eo1Y#uiqW{y>E$2=P^P1%MuL+hoha7 z8QPwELxvK3KF+$T)!U+x!1dk+Rbc(X0Q{d?#0bG7jXk#uFRvSn>5p| z9d}>FRvoBW*7zfBi$~AQ?z+xql(1RWJYyx^gxM(8k8|JLq(>sKftay0I{^Wq z`&kegg9PdBl7XQ`p&5hB=r^Aiw}v|C*Mv&~msrL6ZrVV!_?FMJH4J<0Eyl^fqJE4z zb$eg}Szn3PRqTiYgzJJRDYYPJbY@&P+f6ONlj&|u*d{?xZy_#905W>cDEeiDwZ$K5 z`cFq?BL@1s*M-3w@SGS}q3C;{&*KT3JWZ(MU=~_(wW#y65r21^S>2&zxX6+!4LB+v zO)fv0e4*HVxYyqPJ69o;SPS|1M6zG`5CJ*BZ}f;&QXb_u4a_nt|Fa(i$f@tG3ZieX zS1F%_^i%^!S~kZ#3!SCY@4SGGP-DOtl2JZ!+DVdx8(96`wRq~yzV?d&1c&;$g!(zA zC3ajK?EPJLspbD9SpVOguzxy06S4OaFBspZtYhU_kiqj)uE@Jb_veS0n8d*cBv6 z#7g*=kMTQT5kmKOmVt7Q#)x6=QW zj+r`k!0Jq{@V)l$J8qvm{AfAmUxJ#=BK~(}ArJ7sTB~-i3)Imrjd;iAiG= ziGmft5HRGeEi>dT$!*f$L-JG|J_^vs*HaX{OL*fe}8U;2Q^~2waP4y_eZ`K=sc=Ex7rj+_7>R@ALmr#vDm-z zQ4QAj`L+4C%D~AP!VRbLl#11*+h+vEhrUm7m~;f4L|09|}{YoU+P^hU{h*Xici zB4g+3rGmTr+e=@`V19}6qjkPGNx9+4YZhBeg}MDgRdX2CX zdtTkF@8vb`R~vR`V(vDDkbKn=t{Zy)n(+^r4pmnmw1pV8iE5mvzs5#7$$$gYd%wNS zl~f~(rTv!zA|P}G`vX3FyF`7GdEntsbGNG1_un>myeIv=pB=W)$Y)LB53zxhmEQQ( zibY)gUZ0CSZo(I<@l<1fvtr_bAbzK!A$vo-JKZuMlVvvB4Coerwn1zO-wlq~-iP8v ztDfIKJSiy7fNg2_)cfN%ea&G0+t-i2n@;ZEJi3UzYY3ga%4D8W{(yJYp*JH5*Rkt+ z0n8q0Bf22vv2cHgdn^C2N4UYPYCHlKkkNo0GSGW9L>f#JyJA}5Y;H=NRxc9X z@_l7TFx;wiT_fP_8PO1L>%@weBfZy-_XYxUDlBVJZnNbh7QU+*?ULS9*;*RKV9{D&VrDH8rp>~nNdw;M^90Fkw9@+kW%JxM zpD|BxjJ43`n@G9OsS81`V^4%mp%SKdF^8W@m&;d~RK)2tN&!RQK6+K#6E zob2Z)-t_xgX2(m#qAWH_w?k()`p$9BKX%i`=V))yV>UHLB&IB+f>>3^-w*3M*|UBG zCY;Oi=g_P-;LE#T%ee7t-VKjN4*R|9lS`=$KNlHCNEz`@zfkr?OM@PM zFQQL~hh##xf{DpS>#L&)^t0$Klu)(BCU1F^&qsUOQQH|s@=$QxOK+h##i<`i0K6#l z_^Zk($Rtfr0CULib?FIEQO~j=R~!m+b7~eNrddhN90Sb3!3+Jh-mU4+_3X z)Y+XX__or*|L3roNaeyqr_F0&+a~+|U|KsOaJU01fy2Hv>?4bf_5=C)j^`b3;&W*w zqe(>hC`Zo-RX&CXjk&f^`54M=EV4~s4ROqm4ej~p98r|~!4#Q%C*EE@47!=#aKK&U-gd5h)Sx%D4l=9f;f79! z4CMH2c4?Z@(+al7Ld%>+UdK*8vmXKW@>j_5)BakYt@gSz{VUj?KSmZkk9Rxd<9+)B z9J#mAiFpM2j^wWpr^uR(?i#@oBxCp#?OTbE1FMn3yq)W}snNo5(B~3haOFDX_&Ndq z8IRkZ!p&N@$T^m@xO#*2KAQSmLcamzdg{riI0>avowv0#!u7j0EpLfws7E~ogE#~} zSfY3mx6rw>&Ck~^gGi_IDadN?&rrBUlq~tzA8!xp>5an1THZ#=Fu~C`4(}D#qH3y4NGz(o-Q6j0!K;2!8z1Vz!WL1euiG z^~$HK%af&0NTmLjQ1<7LL6u@B??*e5gh*Y=*0Sms1R;eaIbi5_F!OY(>r#ID9NPIEAa2IbjgyZRxQ6Q5`$iaD>^bJP;55kkr2Y^Tna4Y=87Y8H^S9>JO*Ub<+;oX zO%&BbeG$6(7Oqy~&9hI2jh4mf71q(}b<$QbkfGwK4fAgrJzR1!n>38b*oG8r6tZjy2@|@6?Kg{yXow4FbAqe zWmmH|OqQ+?M2iU}Xbof1S&#Ik4GFuZXl%fstEgxed5wGYaM`Hg<$V>=CmOUAD$<*e zYPb5OQ`62JMe5F-w46@`-Y|9NKNa}{Iy@J=4Mvwks0hWdkq2%>c`15u>e$B}& z-OOF1pQ0pV`^c%J?(_HfM83^;DlkWj_?awaj>eXJbAIXh{O&B%VRAS*mQ&{9OtUXv z_n@BqIOKkGAw@a8f)y=08~l8!(JVXs7K$QuK8t_CsiR}@m&F|H4A{c=mHRHAeiU&9 zRnsb{???8?g)_IigK40hD3%mP%F5kVSX16t$FqHFlYz&F7rxTof=t7$d)-+tOq>G% z#XaaKia2Fn)UiSYF7QD@N<$>T)O?*kE$j@_We{Ya{|uAnmIjA?3fm-p;gL(ukoVj& zhwW3opeZ=5hC*gw>45ZF<+JI!mba2Q6}y-rVo-tgwh<#Vnuv6QB8#12m6k}-jciuF zj`JY&L7T%ny)$s}A!YQm?`WFONUL;@%w356?U)W4EV4oWlbZ^Ddwd#>ZcL-NvkFRl zN25#h6nlvbj4xlA%dy9euG-~l{W7+$a6cya#4q~e^kbs}-FH<2ey!Lp-VsN+h#6Zh zasg61>GWf<(1+*(LkcXsmM8Y7jito+eFOG_5B;;xc7>FLUY^?@64WYwxMKpS9g^$w zY)qDZ8yb95%BG)52hP;15zH(CIKeh6wxzDjz^eJ#v(yNZTK$hf*k^1`=bi}qUA;de zMea6;M@U^byPt1?X1vM{X$^;DaFRPe5RRX;Gw z9iv-JPdHl}hv;9vB%qto0f&L@8Jgd|T#0#(gleY-@)vWRs?uyg6)mCDJb$TDEAsnX zK~wpSQCujXV%lTtch($fsSw%D>%kvmM89?!E|`QQZZs0p%&E#oU5ioM6yuTW>wwm+ zH=pT<;)K5GwO;y^e@|9vMtw{~L`u#Z0EfKh=t`Arz)9z)PY7a{nDp~_cEPF4rY+jd zXqmZLw5CmeAsd2JM1TqNQsL$d3Y{d)HS2fzC^XT-cfY;A0P~QLQuwrS@mOS3nV^ZD zQ_}>j4ZdSXq+VnBUKf;T@1IJ}F{Fd*1|aO_f+0zw$y@tu#C;k3%3J0MJ+Ryo;}7H7 zfr0F3-&NF}+3DT{RL%_hsr49~#PJ~xIEf`m*`E@qn!H6?PWt1<52QG+HfW-q(V~&y zAX+_Ys?E!Z8L2oo8*-8s2r;8e=nWAL+dM;ZY{HEdjV+T8XNlR}B1$jygktKsK#*Ac zB_>rAkIdd&a@;Zs-dgkMXP*WfeAbLc{=ij^y7f%J!tG&*0+?PPhm>AQI+{rR+?5mx zUicd1932t(?yS;{898f-C4ahoh!LB2(F7rlL7mNv%{Lzi?|geq&e2O_9e4N> zK(K~q6*}jW*1EQRGZ?gFup?N^;U9F^E!t}YZh@yC8r31+BM6AVMZZ^K>hWi!j#vW zHNGb&CJ*(@?*Axp=}n+l98CqZ1~Hfw+KYOJ_9mPbjJ*KLxY^NNfE8RIm^J}(jF@|y z=L~Yzt=n76TqOj#u*dprhKR&J9Z?2z7`9wo|HPjL#>1QVxEU27a+OL4(}!-tn6USB z3J=L84clWDuNHmkB}QNN#jW+>kSSosJ3Q3-3FTCP-kc+dvaO6%XnRWVX-%T{mzw&Z z2XJqPd5)I9w3HoapF2n-SmgZd;K6fca{+G~qtIOw2%I5OK zrx2MUm!?&k2DxHgHf5)p62paDv+ky1!W*YvV4`^<3AW>s*svWOLR*jde2u^y&|yHT zd+0;F=!pzgYElV8++ap?O;#&Q{_*t}&bpU1hOEOi<&~{6q>+3z`Xx`w7GLS+TW7rj zCC;#R%{Spc86ZDhnPv-n-X1_fh^|v*XKGc>C@_j`KsA_vZ>7pQvi;(`6fOb-TBADs z03|0nq*M6x?0Sz%kR%TiQiv*s!_5{Qw7w)Kzm=5*gZ6HCjFPTL5<+*}Zrt7%*PZ2y zW=HF!3@=XnC}{}z^Z+x9sFnScjD)CuN_M$LF5h=qLm-IZ2M3YLjNY>7z)c@Eh=j9d&KPWuk}qV3ANGf5nbbkCW1yInEhW~CH}Hsm63<#>0qM>zLB ztFr()QKbC5N+CGcjOF9&6_s=~nE!pVW=&9xz!TwGGG)nq9#D95;UW6l6nA1kbpv22 zzQ=PKGm^k!U2AF7FUMH-ZixxUs@q3Dhxk5T$?ua6DJjlfwETGx0(|7bsr6I02#1YTGcvldCyKd8_MmGqqB+WdWT|&F6s#6eI)ikpg@CCi& zn)f)B+zbjpiVYOUy-&$)g-P-hwmOqb>mrZ&FFN$gbnV7eH{i#yWdPjIy;Oh6ho?%2 z4;nUiIr2UDJeb(8EdGmP4h@}q!A$qT-d4xYzQPsg(U49YN=9^MJFYWK@raT_b-4~V zA^lqJY1g>-WcEG45-XwCkYZ+;;AFtOnxUmDtX+@Qo6<1uF5CfA(bBbCl%hQW}v;0F%<0 z>N_XW|8A;0wDOZSfg^VgV{Q|-CR#u=oexadD?h*2O0Re6v#{)P#+5T?&v!z2J~cl$ z01R>G2c<9@vscR-lvpSQ{(>w?q^PQM0%YTL?Pm8uD}13vL$a6{*(4a{-!=ltN3r8C zvH4ynux_9uGOV>Zup79I{Bs*6pU9WvX!@yqQBo0ts3;}mQWv)qfmMHZfRJk@Sw9yg z5+UhT9zC5E%@Rq#fR5eHxVAt24r4>q`ILYzk=)Q{`9-0wW@mTp%n+0A`KB}6;+4v~ zQ;3X9DG>p*N)X5BS*7pr29jx6QOjnBryLkp%Daqb+pfG&)2R;DCqxgr7{9$afuJQa zkRb_|8#Hi5$=hh8tP@!GgH;TLY8Cj_WA?1JFRJcnR!cPA}>DHzv7Tu@$$RoaA zgc3KLXCwDFX@HtOoMWOr(^PaP(6LT3N6NhBDS`f2py9;Dd!z53?BQC2PbH?&6~HIV z@t*D}zw~+-NW{J6_8dKy4QTn8|MlbZndA!=}8eAm=sltT_x;&k)RMyG&uI+>G zW*6_HaOfp^1$_kccpC;t0%a3X5~zuEn)DgHThP(yJlC`osXOAD-4T9gwZ}4QV{&EC zM=4}|y|D;HLn$KxArRT#FrE^e5JfR_Fid5CTFJwdAze-Hh2A6rPqRRG!BVlo;?ZH^U>#+|p7rIj@KmMpB}muOr1_H9ed{5IP5_FXC67}jRR2NMMQm_o_a=I&~Av_5?6 zReV9}=KAdr#;2@s=}1R3@${=!*_`WS@IvEgBCzL`Y%+56g+CB@z=^%ftAqc88{!Tk z)DenUKl*O}H0k_LfZ|$tE)^~^LmHw`K|(_X%59E zrc<}3eQxTp&M+?JXZpg10yxy9FibQNZ_7Z@%rawvl8$T6$_o7@Tk?QCGi|Bt@DG0) zU7`XDu&14Ae;rf5^!p#ULp3LesIybJls@HeU;m==2wP=;^RmWHzzN5^$L$sJYpj3s zobd%!lKp!47j*mMd8iN20j`Et-D`jQ`j<<91cLj`j}vj}0X*Vd`WNzldfEPq2>Q-~)d_l1Xbkd5y87hOq81Zj<94iCNTau*>FW=wab!tu!Mf(0SEB-d7;3Qsv>)X^? z0sYf?39P#t%^#Ed*M~$l0hUZPAS(MYuv)>>@b&q0OZ#sXF2Zc$7)O45|4(d@6hFkek`s~|6>ZqvP&Xh=6s-RKMHhu$O;~ZEn z-~E33N--|&f~i2cHP(N9yo(2p-a3YOGjM&wb9=7{9HMdPFA zE$eGPS{9MZ?0gI#0ATq3z-h_k07L+qy`VJTDIX| zY@o1pIC}v2N|RGh@IdXL1JHE9JkV?l){{TH^ys34t`{I$i{WE{)MWdr<&h94moj!R z%5PC3MK1Vt_ZLnqg_UZI1Ixdd=P)FgCPF8wI_bC7S75X;cFi(1cgqQ^$ip%l* zY*NM1hJzN5=`Efk0z0*hL1X}q`l0o~1V99T?UR_yvILlVp9wPG$A*frk1c9KA{FXP zovXM@9*ldAl#dzpa&^Bpuh}dWldENcuynr`>5s7xUf~|)3|SYi6WKxPkq)4QRRgMV zw1m_BBTyQD;al(cEMuNB4V2mSZ0@|kF|fnOzSa49^NZDbygaJES~oKRAibtAw~jVh zXu7dND3Z#!K_jQcE%Tk4X5MeA7a~1@V8+N%VG8RJwCiN_Azq2v8 z5BM1>^X5BbUk#Ehpq|MnLX1oR1`hQi`gmm zevnWOd9SU*4QO_1Z4z)Q8IC3^=&^MoHB)HuEK%|*Bl%G)4lH$aQxi@Z!Dw`nPst z3`#6Jx0m~V6Rbq7>N3{Bkw9n7 z3>~b+1A4Qsjan0RzVS!%8R5Hvz$jHXWQbp;Tw38|3>_usK!L4W2idXcGC@$97$LgU zI_07SrR#Dt*qX5PNimv$C>J8S8||7%!Lo5)MSKD_aS?0=cfVj!E7>scWu(|7*%Bq~ zCj42Voz~2tByJo3otI65oh6oAMs8QG^$h?qLYO9Cc1&0}YrzWh#CZnL)n?o0JfOnCwX=Uk`ea^|uM!Y~Lc{gm#4yctJf`5N97U!i zy?tVyDL@FCP4f2E2fwhgfFFp+%l%xWN5yV|7o$YdY$8F{Fz6SQOXAyLbQW!Z@^@Y6 z$e0t;>!4DtLwl(U8B9u)*g4I*>$f9#iSjcELip%y$eu8vSj^nJxbvAj92W@b{K#b$ zKRgDQ#8;SsZ~~>sGdZGeP4OEAxLrB-NHhUvp=-(?Z2nGbQsXxHK=ht6itMRUq;Xrx zHgUSm6If2Zl)~=#{PRHc~3xzc*9?F*#k6Fw5&)*NW|A_hn1gWS#WosOdW zxzVV2|Lt#OVwx~y+PGHabvFo73sHX#{2AMcy|#0Hlk*07u*USIEdp}o;%IN8r-WNm z2CHRfp4C8!LM2FY?F*SaZQ|P;miRA-227AEFO02ls&HRGJ6U~L`&Jgun1kJ?WPMC@L@|kZ-TLmWJ)sNswHdgf!8W`Uq&LfDP2;9GVLykp2Qz@NiOi46CQ)bI6Zk7bTa=+R2?NxGoH;61eu!Kbs=hz6iW z=CxWcp;O$l3SQT6_iNUfprm{@!#i;h>(*b`y>XtBO@^ge8gY0o7o9E}qt}b)4pO1( zu!mFghdN^(a|&2JW)g0u?p{ky$TNnJJ!GyLqd`jFQ&T4iAyVb}(R_|0QlR2wlSx)FPLi@~Hhl+Qhk<2F2zq2#HAD!}%Ca8^yc;u*?RNL5;=U(uh0#d zmR(y)YgB|ta0e+)!g(wsA}7z9F47F$z>$I`P?GP{6|~NQex|Jty&glRS@cPl01hL4 zN@pZ`3EH~SZByCF_QA55c1vql!H&%+yVAW5`lx(pY@#$@i zGmDo#+81fupjFt-la(bE-=FOcJa2c#Jha!sa+_$BH>BCaszQULRy0n$|r{6%> zhMrIoM8VkTwSD`YISP0$nr@o&Rr3u%QNPj+=BMBY#DAMS*VAS8jhrJ=&dr^=Sy>>6 zgW-d`lKL%9c`_T0AF-WA3tx$QZp4CVAhCfmvYZZDh#;x~3|M|<9N21G6eT$`MmhP| zIR<7Guu8HdDN_?%Mgc|U1Y?pL%ayO9RzxclI*zPrBv?!R{}mP=i8m~-}i_Z!di zyzk);x*>msT3Ysr`PdBdKDwFFYc5`Y3-JM=gU~`h{Hu=tr>-$ghnwn|@0eAYKA5># z*WB}LxpNQs(M-*(cgnK&Jyt_*Q&kpMo_q}^Q%UJMHmrx}u->cIXh{((l=Z38h#DRO zX&Pp}@1$olJBHrrQ`$D0B%#2OdtZPdK}l1^X7~GGL`_X~5N75^EPFT&Djf(`5y`QI zYPO-Uv`u84FbOv1^iF}XQ4;JXhP^?h-@mRNiID5K(8KS&Y3xVj`i%i~8-{3twWt~$ zhIl6tqLTCdwdyKOFS6)e@ilFFITtFk;!BB#4a+D{`;@8i3QI@LKPlB$4oT_Hs3JGS zt-Y};t!Dbwopa))QB^FTKx$#oiYtcjkQkfo@B=s?3+iyecaCyCOJ2J!R87fn8$xVY zZCadAVv`(WjjnUwyrv-D67IvY=vBWA@$1R~~&Xla#RkT~ach zEE3O~v>^ClZdTL)%g;AlPtBwo$>qw_VDlp~L)=D(j0u_JE`<(~rr2Zo&i1h} zDL2Ou8&hNGPLb2opIxxIhLGN;W#$-juyEtV%%&QU7z(_UVve{hQSj-s0psCxsRMLqwI5gWDM6x9Q8nb;Nu*~mfJhWmx zhzp&VJdm3`g$p}T%b6|)XBVPlvT4@M$6oBwdTuU`>tS8)4n8CgYFf|w$ItiTHl6%| z8gw;KTjF{rpv$-XLz4~jPQX;4vexH~cK!-tzIjg`itJf zIu~$c*&KL0tr(6v6ImYwdW4uP9Zkh_zhBWyU1W;noTqnD!1A+6f(ff5?sNE3?a5y8 z#Smzsr26v_K00r)HoW#Cn=IMBL%Qw+M$%z(=5*}f5pZr%d1_`F5p@O z@L8KKrJd>XxBr{>nw;_zlKt`iE}Fm?8(HWizb37|l@=glV4YCue$IfR_>7d= z&A7nA6W~+?{hf#?P}(Vv-SUC45Hi_8nSW{3rmsVqJSK2jRnf%dm#@gHDsvn4Ezg zpVRHGTlj0(d%m8Nvl1J#v6>NwY4{7AV2ex}K((kQY;FSCHPDmGu1rd;hg_l)q$@lB ze0rsX)_N_+d7FduI>0VGtgOk-5l<~tln2^+@rl)9o4P&tth5u^e(N7V&jSMV=%ozL z^%ByuSW|MmWZ{A&Zs7Y(&3Ao$9M2C_x)7+|t2c{3L*V5wrPfX&Qcek1Cm;G=M%3ps zN^UH0OFiH_4~f68L6>|F^lb=kd4>N4JUU;6XZkfCljL0J>QG20sr_K}98?LR(ArPD zAE1P*I}Y8}iXZt&@pK7vy&4^WWmV)>UqJsL7QzlB3+E$og6`_kUY+9^wbKstWN#q& z`g?&NE0kvNZNStXi+)y&RLngd!(GGP_5Bkc{`-hX8yvKkHQEMUK`@HD=2t(6%X&i4 z+77{)i7@btu~%z+0N;{~cxHm4^(wR#Q9xls-2X`U zB9!XjN}J}ncp>a#jp6)DKROT@MupzB!=)6M;c7R;NJHURdG2%9_fhYkS}^MU{J3i= zR#-TeockyRKiXC7PGh$R)~UQO>>L3AO)(GNzU--oc4Lv(?;WXoz3@Ao4&s_TyUws* z?;dp;8hBrG(|pir+Xt>vHX@^v0HOyLW1wm)AY)j@xDFui7aWbz*KkoM4&xh^skc- zVR9-`CRXaR*dY-Jw;vdk;B)s(f8n!i_a})Z#KuFELHvpz9YrG7CM$7n&o| zyPd<(uTBs0$xkkVK2QTOKHM5&v5+P1!w#9f<(+k1+{0?>bF^3KDhcqd$cRr(kV+8E zVEPH%Hu3JEuqbp>UhKVOK#}|XffS6I9Gr~5<$4HA6ip6LZXh!r)kfzl-4^WPo& zQouK9Y2ut9q@ELMv~Ok<-Y9R0v7H$Pi(*UmeY@agaRT`EUMXP6Cl)rE(6ZtuNK0X! zPZyS+Eb7iYE(yCn@a^{#GPM;(@Cjn+SKV+@ads8BS9iTBNnie`mYQn3ycV zHw~5rV%Yr%A*y65#LEx*$2->E_Xg1%;_S0IG@2A7+3oyMvsbP5>a5rN%t_z8JL;T% z4I!_@ybzUTB&GyG8|mzR-gAqSQe&~q&o)S}jkh-MS3j6!gid75Fz)&JqgYG;er*GcQ#zRvG=7M$C#(HK!?XyNa!$?*5#D3+c4YFQD3e`X;|bw#l3E~tF9M&v?csB838Fn1z4xb%FM9C;s$=yx zK<{sU*n4CEIjDB&7RjCA*LV_O zUoEB66Xrd447~5+k5ZrWr-oc8$}bQ2@VuC!R2WA{UEb~YMGoHEuj319&ra576t_CK z3vPtDgza&WiEl`Ip8;V}j{`ID#&(Z}RP~%1-!cEryQ4;?Q@*49naGju5icAw{r+eFi zA*eXlUq3AYo6tNp-Ywo@#;4XF`ki1 zw{;cPH+JxgK>Y8(F2gP^m!$49(-Iyox&Gx>enMPQU>!sr9T<3T1Tfto0gf9fuGi4% zU%>QiL*`Tiw1?gR;|}{}2Q_vA%H=`*w}!`ABYC<%lOrOIxQ!I5ngZe;xA_6U;`Nz| zS#>A3c%?Gak;pE!xMU^9mAsbB3^!&9_(a6;hk5?9)U?1=?ghf|U?jxxJ|@0?FXP5t(r>ggdL_5**S6-&6^2`LJ-OS0-=+)KDIMSS`#Dx`?{ zqh=bD65Bh63}zOm#|J~Db|cOXWcdh5e@>~^V)fU8;lBuiXpGTj*96Ijw_?+d*=qfn zy_zIyuH7xle($tfsa=*z-|Y4MBUXRUH=|u9@o2lFS^3@W{F$Ma!e0TAnh!i{kzJVL z6Jw<#$Xow?>XE>0Qa1iDX78o+8!+*yo+|V$tbVf8|K=o`bq4HZC$Fq_=9AaBY{Qg_ zu|ep`j6NF`yr>tvHNtyupdJ?+p%5{2&dNlsROM{Utt~g!Ybe;~O2k#JE}yA}z=O{o zznAYTgSnpiY`;%K#976InFGBaeogvOekcF_E2qO-J2K^J9)bGpD?`O%3fGx`SCU`T z>B}_44&2+l;(c}EnRun^Qs2sodvNiY_t*NBk+b6C!?oK4#n%@Yx*uK@iK*V$EnJz5 zCX}(s{m0=+QI53(Ymq~=MW0HgF!)aQ< ziY6g+A>3atjMHn=@J3uY&~CtGwe$-CN=GyK5M{R8;jr9ehTn2nL&a7-<$Gh!ojgF& zviSgX8_ndmRSUpzl!c}h`0wY?W9QIpS~Pag4E=r)`Cy{*OT}cL8a(vqtkaU9xRX&N z=HsBwwGSkFwfGVL>B>z{gEB~!Z#8Vatk}dWdR*4=Z*Lek+pr@uN*a|HYM-B@jYCClRI(n&R&DeDtgz_=5SznR`b7)PSfss4FkyT}gfvq( zUgibDGMIf$OUkbAXW18@HXh;11d1ccMg5f&Idc+mF?>mSb#)`G7aG(>?J3?S!~>!2 z^#Y}RmAj!9e!AE&a)O?u4J=6bzm>*X{}_(yGhuU3$3u)O3H;bO{9WLa5^0HmMHyEK zZNQdFy*Q7i+6-!j>04y=zfcS3l~z8OihjKAr=j@J=s(U~6h!)WjaS54{Wu)~$Qg0# z>F|}QMM#g=55&HhC|XRQ@G>>CZ`zE({k84wOobP!6_c*y{scH!cn)C*PUWljKF6`k zC}@TDlFRCGDMc`dTvoA>!iz$v^=oCcO+?QFjg>EP5rJ~qIQ`gj#=iX6Ec*d(NAaV9 zSHT?jkKxg?Ca2H%JZ-YZQMY~cKSEUvOu z%!S8XK#j6K;gAngHtx^|-4x2j&XaY1L5}{p_$NAO{heTR-|~&5lJ$qVbtrUH$xR+M zKU#31ajYmrZ&B&YkHXe=`uA`=$$8}t|?Ktht7 z2Al)wjb&xZ&>%N_&X<$q6fGhw_zeV7xk>{-#VZLU(2A18!xHi6P95z;?D-2Daw_fsNEo2B*KuqZsDi?f-nfPXK#-YuLJEyS)a2qfG+5uFOoQ-L(| zgtvLCclzJZv>WE;sRiyS{pfuetgn``pwvhCpnLl{O82vpSHVB77fA(NZ$J@6L{LpoTE->HDY4<$V!ZAWBvsEZJf^p*Hh=$xAY!lb3vkA)~@5yBf) z`x}j9+fy_AvO2oN-m>O`cEfRAXGaqSPc9IzOG`7qdj!WXe)#p#3p|IoiQ{>p12Kf$ zy}*VYT`Z_YvgIq0HY*Q5*?goDL68UMbU)DU2sC&n(rjB8CsV~fm-`62(iHcOD`_Xd#0{zb@(ynBY>olhKs3Sf!H=1`Ri`=g4ZoO&I683oPi|fpA)C*kPWG$+e z=R&H5lk61Jh#uqul>YTZ66WUgP6XeD*6EQ`h0H0PKhMb zvu7+vwGLNlJiC)Tg-4DQZ2jgMt2v8u94>W2q5kCYZpMm~(Wz^9Tq^!Ui~l&QHz0zJ zGC;l{C{8+eiq{6`oAIz<>N}nb*?eO{>+_Df)3F^+ad#(QH=XH}vPlTLt zN6V8_uN2PF#FLeQ?c??ja-8nb&#Km&gvl{{FU{{(?HUB_7r9@xQiijg&8fDJ|wMg*k!xgZ}rkQZmQ>yTt;)R<+y@2i6*q7d4EH$chKO6bjNO?+;d^S*6 zMc*pg6?oWK>n+jqQZT_YYIJ*RfTewXL7(z2mGtl`-`~AQAXbb+v7)<|5n8?{>R3~_ z8ChL&8520lxn{iDQeQ9W2x>dq5Wg5ua!N*<>G34@#*{iF$USHUlCSPwkr?)alZXP6Q!`50RF5nVMnp_f z%kk-If*cP`D%)G_GSwo`V6)~E`S{=QCV9Z7->G(-12~8B>G1h_0-8uIcR@qgo#hA;PtXJWKq;a`vUUp+!$Atby$TQ&SAZ5S|N9x2-f*#% z=I+SEsi2tSWF42971#U*(EV8g*>GWX`SI-M;g| zAlh#1%gq9RE;*n3CBRYIweYI`aGq`oUHPGJ@|DqjHoD47`@_`1?&?Uf&+!aX&WXTN z`P7F4>Oy1Row+^*^+9dSNMNj~E~M zIx40-#p7RuDi21loxW!h-<*M(v&EzJORER3!Kd`4a@y_D3YY7{CZILk-M{Zjj?rMJ zyoax2(k-D3zSa5o)G(dfqqK1zG*SjeSnlZN0h~6Ii=XZHepS|7ls0y7O49sv8_TAw z6AX*}+kfd+l-$KGWLm*~+3gm_leGb2+ zwfqh;a|ea)yuVU0QPvUEd1*t1_8NUUVpn1Iyu3ee!#>QY14uWMB8eKkKy!Bmc2^Ii z1_Y=2FqhE|;o=Q`%ltSJ*&fGZSbF0yt0!|xGlkxviof#o@Rti&!ZZXEEVMk01HCQ+ zOol(+$0ur;(H4UO?IfE>2KzJ&Tjsq1!ZXqBKGd8KsV|-ObPDGkfOeq#U}gC8`zO|L zHhu^BoQIY`xOs3d6==sQq~+*$6{zF|)^eurhg=DJvEVl9q%?kdvNzF#m@99UN-dH5 zV5Xjmo({bNFE09KoD_f>=Bh3> zC>pP|cZ)0}-+x>`*y5-VHEHYthIU%ww2e5_rqt5R&;=wGTEM}3A>&xrv>KF21L!m{ zAOs5uB^d%~+r>C)Sx=C~7kV9Uw$5B@QJ;X5Hd}qf_}iCW9v6VCS2=)2`}i-WA7vk3 zvBkPBA8QKw8yUpWd^BB%S7+o4BZEE6zIwm0rX+4xOLG9W;3UPvuf%Y0B=wRpb~Ythl)ap(px0ZhetWXNoA;pD zi4P)gd-{r)GtLVd-fjg#V$CoW3}KjoxELQF07FtuY|1aRT;0q6vYeMdqxhJrDJbXG zOTla7e)@_Yk#3WKPLIc;a79{i%f0fz7*PE(-IxHCC+DiaHymYYXv-pJ+P@cVi|J*@ ze1J3M75xBukv@WPUcM`o(htFa2hZQ1B7s8x=s9->fTTpP5fEppUm5&F)*&8Z-DBKL z1ZTEuk6}MJEDEk@J=P_Q0&R*&Low#;G#q7*m|MBvEdBglW7+r`cXpXG&(pW6yq@jt z>aPDEl_(U(>QIm*e)b1#Mj?5gA0L952u{}{zO8oc5ojl%sn8A`l+g&*!>SLM0(jje zw>~mv;w3N1SG?S59>AIPBAE>t7kHD92Fw`BT->sK}S%~m-k(1{d07(_* zWE5bKoJMHzY(~_M%AgAJWHY{IDsJ3o(vRSLiZd z8wHK>Gxn@?;-JDgkdTd;lxriArJYuOWvVb90~+DE9U6rZ-iOS-O?4geh_##CE2|o^ zcR6&h+&vdUGbHf$mRwgGbWILV@gKgE!;C0!UfGemG{T(%tdLRu|~3J^ft}PUPTQB)ixN zu&-pP23?#PT4rC#esS{KvZio9xC3sLblYtTnxN}=a<410=bm%tw=LYgdUCWi{+`Iq%x^iD`m(k=)cN#e?x<)`13R1POm^r`R~?jm zTLWgR>5_mAY~xrN4$8(}-JkFdbhMU(Y-d`kIZ;WaV z$ua#jL+h6jCha>&k&}WYYgnZS&$Ye{-ia4kle50TpggjB3#dtEg6Qqr8iV=zFQd!& zlrVHLu3Hk!;?-0b)}MsCA1}DF_&vT`Z45)i)Uj+eHG9-Wr?EcH+1J>;?;-Axyj2WP zxqh2TqXq^8m#t@ryyoUpHUH<|L0m-^2$HH^AShw9;wDIfFkLhJ(ogmYQaQro zZC*0Q@ec!g5%bMXg4qxCj>u;oKPf zWG1(E3A3P8n9a<`H>pQUakM32rgB@}Ki}Ia>Bh1G)>4jLvB>C`C;J-y6^=4D*TbH4 zr+GQC9BIDv;c-lM-p*L*i*GHWejRB=WGs?&5@}oOy&Le0%(9jH!d1Xb9j|`k{X5@a z)6xKjk-~2SYhcB-h|7A!FFR9i;B1W0`2=8jCuX(~Hng$nqE4FTA^-k*?b)d~Ch(A3 zKfeneJ4NY!VPc!KibcobQY6{1ykyLcSC?^=*$BhGNw7$%R0*kP4qu>a7ndu^hyD$CknP~n50A@@p&eGJs&ABvw5PEv`OiL+frtlHlO>FoA5Z^eF$wWxl?0H7q~cU$lX4 zlsK{ZR!MBsWZ5@pNTvxyjJeRBb&=xNHY`q~yM*K~?r&-|MYUf`nZ?SmkJA95tMu!9 zxp(UTp=@qPR@S#Y=MQ#5b93RXEukpO^=6{%j?J=7Z@eh`I}Ly4IY5P3I@D^MvRU+$ z42EDZZ!{A(zpBJYScSuv&M(i}gkzDCCO4SQ!-9u{mDX=DyA_{IkC8>$W0aaezNkre z+3W`LQ`O64a>~0v?S&5~OSw27X+=D(vH9g-{&g!M3b|Y#>_+~^&yO)kbedd6@-o^Z z+g+^fR{ynR_Df=nlyJchmsSz72>dqQh90zXl)(+zi2l+r9(m@U@8g4&bE}^JCTHs? zzkXVzb-9VI!5mTZd{uZU@IZjK%38UGNK@PhO-3vyt|FJ`ks|kFHzjqR!uSdh_pNUE z^34M{n=$D=>TGKvV5qO#M}q!VvF&>3N{L}-qqn!znPcg?slq^{&+fiS!C{9BY@On- zIYj4yxCshA$o$>mAgn271-VzF49E;^J~fe`l5a7)eKsR9Z+rG%U*fqX8TpXVM2uGK z#O0p)D^#zFRLXZd*JqBLC&W5N^6cU^1}_1O0+!e#Ec^F+%>GqlG4a-^ae<3P-y)r# zTxD6Q9^))3D`o0=x+0=2GMmG+UP|_lNu&I_q4^svox@NWjvpi~l*%yn9JO>=;3L-Y zgP)U}a?PF7u_r0+*2GgVH#$ zDxjzrusOO0eYF=yuN`BQ{mAW2oP#GGr^Ut=JyANb=P9_=Qx@Yhob7E?)YUyTHiy-E;e^ zQ1J6RLdFa>0^jVN{ZRgTDj{?zp%wAelgBHtg!V1`1F3wmxatz^O^dgJMFIbE)s$*r zEB&!Ys=?m#!=U2x{*Ex{O4}xy^5^!R|K*QIG<*TIw5X9R91Z4pxetLFRf0btwa!@V z_cT{f;gjLi!xT(I(|4=Lz$~>Axbu%0rJ@r~F&uT2SLMGj5Csw+IGn~$su9{CmLt$m zhoHiXiPWTa`abm|4LLKM<%CF$2QQ_Z zv)5(YDz?e2-cM{Nj%18fksAE9O`u4i07Zfd&Z;fgvr`1>{tRfS>d=rn*>Sqm{pvdB z(UPW5k{1{X###L~56c-s8p5u3w*jVSAgx}*oOcXUpUucHRzg+~edFCDPF-)Gz0k)$ zuPYTZoqj&*P4qd~u3t&wjC|l=ue-m9ss1xP1u_!pOTgm3JN-y0h6N?pfvF@dKy1#4 z_Cfg`L;Zd%drE4>&#`3pJ4u8_d-ddL@gIz#oiOM=aA=G{iT1@_tuAq|zi;LEh}7zA zAZ*^h?MyOZWTwoGsr#Xn=MBS}yL}eO-5iU58*Bq)!JcW|X>bBY8c&#w(*{KGTd+4! zrR|N=1?7J!p!;wL6pZvIVAKyn3hpH%KUC%JGUr5mui0K9%pMb4l*~Nl;UDKDF8Ia{ zAYbyOtFe?rKMQ|l^=Li_jv%FTYW*`T=KK)wsez*#Wb>KfJ&Y}i5{?Zpkdtu7#MP0q zg&siR#Bd6ntUCCN2vd~BV{JiwsnB>L#>1_80;V_$MHFp9KQDjQ>+H8<^Dx?rr4hRS z?3uD@Iaoa6y+aWX!tXIyBBH{ZmcY)3YR}f(I0LH?6andlVA5K$CLBdCWZyN-vVdn! z$b9|#+@hg;TzLfJNypgayWG@{v>CGor^*0hkM_B~kBj_$s1OeL)Yz1u)B2f!KX0SynCs3~IDZ z*$MLE^(xQt=zmHRe>XNk8-h@2vcgalnXb{{C>~j7ANmNb;p}HfIY-b z@6AEG&k-Tb+t4ik0%emL<;|ET=5%BA?teCL5Zb__3!>goEKrBDj$BfSfaCs}(XQ;m%>%a4AkY+g57ieO6{PoCHKWuNS;e*fWjo>Pnxnj;L z+#a19pq3wSka)^>AZ-R;7i{Cr;!lGHwDK)pvzucP^-q5gONg|$OK5qKVP4+lA9YAP z`{=fEeqk@r_bGcS{)AjP-ww=!{F*g={sNuB50a~Q+dCxq#63~4=!~=0@jpRS`WDzR z`}2r;6V+?W6&5tQfppG~x1D2Lv?D_WEz;@)NQG$tANH0V7}ULMm9fCbEi0$L)IyTv zjT2uvXz!8WOZKeO&0F3d=obM?p9MMCIQ@YN$Qrp2i)C<%w3wiya>a2+I`{n7zvdaO zs|l!Nk6q5uoO1l>8pLoC={U#jgCV^w>|GG3sar@agm zS8DT&lN0=r-K*;p9G>SoH*(-uIQ;XxAT$^$fD?Nuub-F0+h4lOSz?K=cf0Y;gxzcQBpzq3?b4+jo|X3r#y{UpRB>3O zba?9r`MC~>hHtGmJve=xQ1tN&!TVG1zf_QiN+476xw@(X?7yy;GEpsn`8O%o^@gOt z9=$+utqZY>_-uFx6DtGtO&@Aa>Fwxf?7H16yh-FAAnTx;|5 zTsiVT@cu9czji9w=Zbf!X?EX!Td}R|eQrNeW;<~0*&CxH;})Z`(jrDCoa@n^wwVTH z^e&ZJ3Dy%TT=)CLvQ*oQc*h+)0>VbqlsLh_L}C%JAK(DE-PgQK$0^%#O5(gk5j6;XR5(x0SA?m(JZfjwz% zZF82>Fz*vce!FOPrpn}h(#R&K!Nv4zNtCn}`&b8`48AI;NH~UzP1Wr7; zE~yYDvu`_(1WxA*G=BYv)bSKLoT8|7M5ftr_>>j>-dDaAzZ);xHe-X+J5KO@ogCGq?A3WIxsUEU?Hs4RT>)5E;dnW!D%HeG;l|6x{y67 zCD5t&U-$e<-VYQ3p=bIdLXf+93&{x&^Q*5z8FH^1&U5Az+S_y)Th3&}t&CihS3Q2? z^D`+=oWX`NpoFm$-1aa_k^ebg^h8dY|A8>E7>VNma8SU9_*2R0dr->|2QJMQys(3E z+$Vq{%l3R)dLB9ap2PMvC4*!O>}Tj6{UE*x`87T#&-BHL47koFncolS3Sum1=?!4P z;P1-m5wHe1m^RzB@Y2xh!wjoN*J8(blc zV@EhCGR=+)b~e3(5w7i8)Ud8Yo~_S|*!C+qaWTb%KH~+r#(tWxr~e_P`9feE_Yh0X zN36d)_?g;JYmBYH*uo&CwYH)5!hbRbEmhOZ<|yNaFycU`Z_xfFq9O0oGkCtBkWYag z1LBNuxYQML-B?2@S_+(TB$U-d%cr zSOQ?|TTg*NP4IAXT+@3icIEZN@x!OHZP6{BJpesF9tVOk)z+=4V5WyaobmD5>S#sr zs$kWmKT(l`*Du2%fbvh2u5He=76TQN73d|m$yx)Wl(*BQ04%ujd%&b8)#vn}ssOZ~ zU$c;uI_!%q0;03et0NaE-V%Ye`tqS<`#)&{7klqVQ|Jdil2KQaP5!7O0A7PLdn!Td_)#EHH4I>ZwEdIow2XIiLE^e*B42DyFT zR@s_r`t`;QvQ6x%?3D{<7C>Mbe!6k3zSF;S^CmSvLaIYP9898$yMO{!kG-JR z;m(@@u+ig-1!*{K5JjekIT%{X6@rmh*_zt}?Zdggbw#N5KwYv0wEiC)@jxk`FHVRd zr0)G=dBD8S*m~c?V;F73R*X@Wug!r*mn5q)R-JO3x*3s(xC)=Lz5_RtIS!HJ+aY6; zOb&K`25JX)>rO~z3nhVji0gnW@g`KNADITjcsmac33C z4$A4qq?@*o0QY7!B#ZnQ&PgbP$L!lnGpxfh%kg_3&Y!)ASM;Dg#>pb74Uq_mY=^*u zd-ewoC{b03wypb32DEm8Su}Jktu5j7#c&!H45w`3H6Y_L_PO+!_kRw!20H+}?;<(c zVtxGaDS=_}t%+ycVymC2ht7^VY}E@)3hu=k)o!M&I9QBhg|Lhz7|Tax`tpCMkcI}1 ztBP>wOie;u450|V=lA+fmIhhG&1uONuR@f0lZ!mbFqq5hLXwr{$WTSE9H#nK={vg# z+!#sKATurLPs+#=9f>*GaRQ^LACPNMxRT#_ZYIL)%SVu^UopH|+lJkLwV(}`OgzfX z&+XRt14t~_^UAsPlH06H-SyyPcB^D3#cR8KOybhJ5hrV)f6T7{WWnY1kW)KCXL)CD>Ou&P5)?`V{TPKf<2Em72m-ZY_?A@^?_Gs+4%~N9&+3MXiQtCbAaRBe zEI1tPXnI@=)YT+TY~tE*i+Wa;@c=&mGKJ$Xs|zBsI@%a3g>|x)i!N+t+!hXQw?*(c zU6q)OQ_4p@zFr!?n|%kBo6*QeO3dxXIlsyclT$3_YNb7XMkunNLoy&hjx z+2Nv8c=Pdoyu{rpgMO9}`z9iB$>%tVLWJ769@?^4^_{2-N{5 ziL0!bJs6v!tZBIl`-hqW)rQHee2^ zpBZxkALV+_ZUM@vAwvWEkyzJYH*$3C8C7%Cwy_WENQpz0(pBm{^W}5H z$hSh}J)6Qzj;Co3dOlE_5T;BS&vMs~u*s?~UaitZ7_I?Pb*X-F6~|H?&|X--*mweB zO{^CAnm?y{7kQ!TX4aTPSy~E;k=4?|HmB$g z{!&W-t2_b|WwdF$zg08hVwG51sLb12+UU!ax52pfIBLAGw-Bi#9+umoFdlsekT#eq zt`H%0_J`*8oBhk=LuisOP;$0S#>;K>?p$!f@aF_Z zrR0rs+DKqRyf2_ItO{@)&Y7VvuC_T|_UwdVqM#{A(JL_J&m2l-~az!8@g)@>1`nM`mQFtn* zMSr;A{36PYl_&X_B9#-l+1d)@ZZMREN#7vc#1ybm@T5MI-6!rrNOCdzmQWx7ahxIf zy|t4iCM~EH&%#uL`_6~9M(h1oGv4oLS~mqpOj102@6T%e0EZCencc{zO@*{%`Z`Nj>4&&2ZoB+JC`>K36U@me%GKBk*wJ@HBo zB{rMH#r--zTuxUeLgRHH;kZ&z8UcF*K;rC#&b91+?fE-snX)ERv7_=4E+9U6WrCUVw<2O`3+*fF?OJY4SzBYLIlSz!**8{?=r4xVTtOihCe zi+tP;mtmDELJ=%5BD0~LZ;H8IOtuNmOQnI%0E++I}t}!B3XpLCT897UIc)xxqy&my8GXJ zfg({4$LIduymTnj)a{}jDapL13`1T-Q>=Z1^_weX%3|1TB$|YBjO6}XK%6w+B8ek| z=7zc`NSMKpXr0M4uid+iVz2^|L$a(?M+yz$`qx2VdOtSCGnkC2JHKK+X$6cN>Uv*y zO6l2P>jq-*>FX zBPoalbLbwRjh^jK1=F6eexV{_A@*0N(r9ERQxY2J^O=8JAArBfDv|W^lz(xuZs`VK z7uOdq0=_Sd0c6h6hB{Dr`?pVztxGsLBDi-f4SQ8{x~jS%O3kkWs0?h&E8D(${$@F` zaMUgoo$Eo5ssP${I^>@KEj<8>2xIpi73a7ie%80P5?<|Dd_t`$EF!#1cqC@gepNs0 zlANkxep##J*tqAu@_@x&acqpA;>K&-c7NQePk7~prFU}`L!|vg-_2md zi81jT;AI;fuT?U?K8#(vLCm54aQN0pK23cPWC@P|O`1JVU$^u(8pwAH^A?%UARk9a zdD*#_n*J&kkF)ISHX5oexGScC9u!OnDKywvE8k2}ABr(znh!cVA|QS6OX^5mZe#!8 zdHl?;B@FCxpL9oge~60VqHJ3c{kBFHIdTtMJmOGlOaRy@YC@<@%J(!@WF3exmt0ccJx_KP(Wz54j`x)^Io66)n zz?>8TSkxB6`{~=?{ZHVAS0tajWxjU&_~3a0W%YLT9-ZsD*I7V^7Fuc9(m%aV!_W3U&U+)eM@k<>z;*H?dolde;H)2-!i zYYT&8Ydj;I+3lkK815<``PS1jkkuHsuld*bvFNeo$;hSHqt-$4N=jx8HN~`9bsK%r zuXBCjdrBosV1#|T7Ynx0o#yd0;xZ}L0xkzd~J7a>@^Y1(r=&z zWflWTmgbjQFuq(-3>Nj`+83@PK#RP-L`OMl50&2uhW0k1U5&wHR)CX~-5nZ?{u&2> zfjKFcYLL4R0hUi-S&xUHMZOv$_&h;{Ui{g1Ai`GB1OhN1%5mPc=4yKyZZOm`vGf_p z+!N$7Obqsl!Apy{#pdF4ub7-qwXFp-WeZ*Fy_a5NfEp^FYH$S7`Jt^j&a>_h_de$p zN`B~T318LB9R6&pUkWO^u!#aPNhI%}J>$0Wi{JCV0KhPegoH$+PmaTIu_GIjpP%f; z)_Rd#17=!pM6U!PZNO}SA>5-FJXCPQX-no=zs=&=YEX@!+rT+McL}eSR0%&^)Ce-* zCtnwKecZj;@re)&fj8xIMNvLeEfU)$N4Bu`T;mh8}z%z zOuPmOY$wqSCD5_KiQw$WV$k~71H@$$R43;I%))9}Eyb*T)n?1Fl{^N#-$LRn)rmEz zggZnugr-Celfh%mt^KekHRS}be;xVd)6c6k^AX0Gq%+>rp_~H5+tY!(;m zS&a}|vlijmr8-FgQ!Ed>XO1j86K)Pq^2nw2F@lyCzXsgm&VjPVEC zOWydmL=B4Yi5p~ToE;viU#_W)F-y+ICVtr?{Hk?0jn z!+66CdlsN@GCm`fj%VXFOb(h{T2lr2LfJ*wINqJI$3qn2!3c&kuklLfxmH+JGYnBn zg728&|I#Lziwu3kOzvx{Zg_At#Wph>z|BIBDW?~b@T5zDEGZ#SgdU<4HChd+yiBww&du^ZQOVc80wDn}vkZ79J@F zY~<0r(IxE5jO&?Po-}8F7vi@U9M5(j-9L^KyL)I@MRBY}a_Zk>vUgxBq;bBAe<6Gj-m}P+-V2Qe8d;T4DQ`DYw(F&H;c*vP1A~Z>t7RW zc3cqm0&iF#@fGEwDT44CHolkZ^qKOLs-CEK|BJ`m9k@6*Rowphu!!;Hg%I{)d- zhLyi-3OmKc8$D53v{|*^smKZL{8m$oQ|rECP;2Y@?f>xg7En>G?;9u#0}LetNGlB8 z0@6K%(h{PABB@eJ3eq{GAR{5Al%OE3(g@OsgdzgcB`7&`!~Hh?Jm>t^y7#WNmkV&u z>~DYZ=JP%;Q}6N6ZG{i+i})934nwnF^XKDDQyO2v=d`POtR(E%F7oo+49(0SSlC0_ zdb}p-*;G_vP}3lw2%!IIOR@V{f$a=N0R=(fQ9?3d=RdYNxCz7T! z2jNL)%vde);q?($r?gnrFt~%crN-POV4Rr;K9!++rC;r_0Q3{2s`nct8Q<@yzBiy z=1cA$0axjWeY(|4X2x`K5)^Xen84Pck>A3;Tg>N`&I`5 zMw8tW<(y0Mh(tK9;mZtdqxp~@KAa%cmz5z7$|q#^b@o`EHd`&y1s=5;l4;jnu3Co_?Hx;^XP|m;Sd`P%vG! z$zLDlWh9AK$5t;W`1d(&z3|f{pTNn>DK60H9I8l1vtHh)w4SK3A#{c1D9f$(?YQ#= zVoWXkcO< zTH<6|C7wb(qa>svY7DpX63iw)uJTcr8xob;-T2$fxQ^bcUlL!&a zo5_@*-Jo{FxJZAg$Wt{uHgm$6__O`=XylC!p{5OzHPjD5SiCu6&*Fs(**RPwDyS%w z(!@L(ytT4n zyF|A7wD6gWWe3yHf%6)~Qir`~lj!$dNW?|Y(7HSxug~}(|9eCr;?E_{79`;3IC)Zb zf;MRacoz3CN2 z3C$BW$WZmr>Fh!UZ5$PuNn5-xC#%3?U4)s*sc(E#~$_2Ap2 z*?quQ2svtb7yhop|E3~yk5Fjc#po&X54WOo6`jt(sL@O|!sXQe)8)t@Zf^8YXI1=b z_De{$CuDvBmQVQoslQhR6R@yrl9}Bv~=^YBrhMru`%}J=spqS^8GdzT0N} zQKUUWJSzl;T<1rL8#@w3+nODO3ATxmNUhyOb7rz5Exrsdb4D;sJ*VtS8a;FGBRlov zk$z8bI9{7)YE#X#3%8jfBJ{Sr$T2rMs!+*WOYFGf!QlR^r$EP?64spHs1|`tBcv zfD8)b5}BXQtwAbZ*^X3i)#^ji(a6V{rD-=;P?M9Ff_2t)Sf!`vchk{m^fQk)o9Yy>IlaaV}+ zMzbe|=ydL?z)H4o<$C;gCGYYCN_C_@qm$Z1+tK7ak@M<2e_Z)mCGJuVt;oGH}O7LAClA01h8egeMVas~hpn;!`^+Js1|>0YvyoR&SV8p;fn{!QxRf zCo)C-RRPdO2Qbo(3RXv1%;Wb`t%vQ$1j@GE`QemTb>$xK8mx}9b_Mk38LR-meW~3M zDnkWHLT5^jCRr>EDfg?9!BeJ@rUAp(9 zRok&EGTza)WvlwcXH{`$Vd~{dvzX1;dcol6+5zRoZXxhg($(0Thya;KE2c{L@UH}` zlyGbkfMJ@fP!gP1$74IZ+n1y1btyq7?NtvnW%?L!%Fk2%_mMRmf#Dr5>kDqOKJ=)0 zJvPSmBH;R3Gd;R5dTZk3XoBmu-f*KYeok$yD2a}_*U!XBqU5hH)oTIcZ4E$z%!dgB zPu3r~9~|KdNOInPGdz7C4PCGs>>n=h{%1FQv4!^`==RoqK#9|*BLlK=)};axR4l7f zPiV7gt%uOidXM5%q}r>J`hEKqtx*-2#;pnWcF5*bF~4A5|9oc%6_*E{LUc8dw0!g? zF#`Yjc6}*0=*%gXbiGuA!*zD?s=zccv-*=Wj=mrX_v&ELp@ahA#l}gbY`wEG)~J|< z=eoUQVnbUT!G-Di@~ps#%An9=%WF;FHvAEZ8JB5F!RbNzi2?`doRP$<|JebjPai|_ z<_@Y~7tOg2$Aa`HJK|aj(9Eb{=et5pEubk1%!QzFdh_?UM%rosO@GKKIR>!rE2*Zn z7m`XmvAZQlt0m?QEYE4$)X~-7lNJfH)Gk3gu2UIInM|I&&VLstl}BHzB-YR~wm)iD zxjq(rJJC2(0%+t_1)%4|W~k;c3Nq@Kafrmu9nS}-z&m^ZbVE_x`a<5z70Lhd|N9-f zsd;m8LG9rr^wDXp1UdJDu31<`T<}bqyrdF$jTRaKFEKs|>SyK~(SNiV7^D3YbbctM z`C)16D_XRD>%q%8NnILhNTyLkQc@+EN$X$Htd{A4NS-u^!X@xpatPkM^NGt)u3wx6 z`f^(kC`L0qaw@+F{g$TSNZJN3tJ(ghUUb!w7N38|!OIH)x9$4C z?sW$-FOBn#sjmc~b>F&z7Zh@WOIj>>>q5a$esJ}bFX1$gf44W$F5_I1U^*+c(!!Bc z>KqVA`g%ZW^nY`-D?U8~;c(wF)!=aQxqA}HjF#9pM@-*BpnZcEJYR6vOYfyTyD zgJQ8S&uvf(;jBtKXScJ>qoDzRNd~JVK38vl4f+k6g3hPFV@&S0v#_5iU;QpmaClB& z^Ig}8vdM+U8|kbm0q5=TPB$tecx5it{GihX6GbEpFUu9LS%*dWwKA+Zl%+8>EvHpG zv8nbrRv=5}=LJ6h;J;%^Z*@Q8u2;qWG4F*RDRVYA*vhhyB~?nV<0|5JzcMt?my?3E zX=4K`<+5!kaH@H_;GJ9aUsNs=^hRIJChxBDdpXeR=|W1R<9TedfARV#b*qr$1h1J( zOqt=k;sM2LQSSYU*Mi;iclbV6_w-e!9wZoji5OA55LTalqx+V16+z)P1x* zS26AT{*KX;0Gc_9ra{-)P2SKv=6T=zm_Ji)2d%DrDpvP3Y(wrUzBAXYmqjl-P00Yk}{nkz0Y@vP^n&C#Q&t_Y$>XNiBqKX<WB^~@iumnzDopWUCedfe zgPjc+qRD><+GzQ?``iB}PyRLKQzh{+)=xe}{e%m+CdQ zuU>+!jFaXgb*azYGf33}0`v;fvOb$#OGV z5exh{btCdT#i8~U?bFSG0UzLmznVLpEMYiOu#bt!vNu-Hy7fiK(X|1o>r2A#_xESa z-&|`&+n@l`@aNvU-BhX%YnS%8DT$9hBB$sAnjIm0Z=<{ic_%< zeK)v}%0RL_358}(92I03Ntb)Y;|((%6Ry-w^MAKMdyNNL<4>3EQlYGS7kg5<=dzoed&I+B!KsYJYNG+o(5PVZ`a)?c28pwpe z+#4MmTV_%8W$>-A>1C;W_}g&jt2%2nL_9LwcMmW)Iv(wBMK0uDeN9Te@avaz(uLdn zH+_73+-61_0w!()oj&zYC&40(S0J3@5{ZXmzn{b%w36IjA zX7>J~`AH3Hb&8k`(Gf_4nG;zN|AerWjiOL*jkz|@!(Er``4L|#!@|SO*GlI_+R~ir z868Y9)B>#jyOxEDitjkopKQ{&$;!#yHZ_2+acLfCvHW=7bSc02c2i}CQCv_u*XfM@ znO79d5^Qq7)|PpNWEY0W##|G_L12{man;Gmqf)%SfdRU@b{l9YFlwcPAHDk|Bz4C} zs{yM3tJ(l@!w|BtUiZbv%!3l51_9#-OP~uTU?Ld{sN1zF9!@2qU`p_zr^7n1D-@p+f+r&h9C!R_JA7oN=qh0CvYl^ej{h`uSS!KHqO82R9k;=1M23OTp z;vr%A_u7?$^c^X?{%bhs`heW|jGJmEQ1u69QFUc3ivkm0;FmxoJq^RnTesX`2sSPS z1qH(2yRZ(xei#+^T+z=PCkO(w3E}p^u->iEn1UN6b93q)SL(r_0Rndv0Gvs$W0>Zi z8sRB(lKPCHp7$GS&Kyno*yqsdFIBJa=jDFOtcFg=-)k3aq+jw8=oi$yiFi%xHwulX z1ck#%sGvC<`z+ibp9$zoUdve3;{`{Qd2P&njOR3k>bOy+oLYEgjZ4*@xubPnVmR5X z)E&~MkPq#HWb_v{N2&|iL|o+2udcjUI0m@h+SbSP^K;j_qxs5rziup* zE$&Xm`FQ-!^VuJ(udf*_zb!v4Tb%J|OmAiIcZ0F+t$(+gTIMix;CzTTeW^4wQ4VLY z&z?O)V@vHpfjPjQazIPydk%v0riIS{TeFN1IkCtw;fu3hdkn}drlT1|*{^ebeUm5+ zi#UzJ%MU~vi^Itb@K1>(;AD++_3Vl17bu2mlq9D7g zH|RBgvok<>;Z!mG@4SAw4@M+D^2Ff-g(|85?`^=zvAwCcb5#&-;#u7mm5P)|FWc>mtI`Ca*+9;&%b|#?md7JRFTS1>d zSFqvu8g^TSM*)BiB!Cx#cQjd|2E%D52r!4|xC8G`fM5|(Y_uQ@L6E}RyyKavMuGxO z|IBdpp+C-U++mAu6Yjncm_w!C7sZNse^_d9=iU^DV6^G#28);PL$@C%%fIpem36=( z26$x+zm>FmLa=HF=Xc!7mv%+)?|@8d<4(YCGwUcs%7c1-7Zj=;b=&~lFEu};VI6q} zFM~b0TmVmN5RXPy4M_KdQKRF$of4W3LPpHu&Z^vYEP0{t3LcD^r0R2D^^VKWFZy@C zN1$ndP1pxdE98>o##e%eA*l+UiJ#R&`t-I0;UucCYXH&-m@(-u2jeCuyn}bb1LVm3 zK$55zbQ*VNY`T%hZI(k3GW%S*2&U4{@#7*E|i83Q7`?CH?oZ^@UuEfY|aTA}*{1afGEPK78t9 zOB9rTyYW4&Sp#W!SYW$Bf-;!mu_Hvfx(`u^bjg?_qJQ%8(d|CiaXlw@)qX+_oGWZYwnOlcTMI}!KZV*x6J zOkM#ghqNn%Tw5`865ZZYa(y7Ae^<7yWm4GbPUW|+ede*GB`=pB4_oA03* z+PYao$ZfZ)J+Q4Am(Gqpt8I02rFYdS?H0$0y#&R-^MecmC4G2?y8GT0h=ia(5~2vY z*3KK|ei9!)6U36KomIJVC|cznx`Vt{2;^kF-@z!r)RPWCo@Z}!ZHq91hr8;1c{w4g z==M;VwcC_10!2p(J;ve*?5=L3#yP=U@qoynrsuI!iku<;-{#d4;WKdIMoypGW` z3Ma^%cI$2j;X24b&yO>UTB)I|oR5k_8$_NpT-c{%yx2m)B+lER9{eagM$?~0jY{B| zDyO|d03dbb3f#Q?D2;RT=kI(c`^$$SRI^{Rrn4t?oeTXG%Xr! zir-Sli4^np_C9CHUXRw-7(z2-?XsXeZ=5aQHUd9*ToUe8O+bydr0X7l4$_+=%JQ;Z zG?;>b6seMw1E7{h0k}o+V?k@%%NW*i)d_E56M31w&6wtbjqUHLG)g*fy9RIm9_l|4 z(f{qmOaKSLv-_y~JuWp3&kV^a&UGi(IE!LBoL0r)!tI)~n_M}BYe8DJAn73%f=rQn zv;x09JTfxY5=k=#(!o&*{JXv&$ftbZRPW_4N8Bs#zL22WReBL{BCFR^x5e_yc`P|Y zyG*gk8Y8OPW$_$}Knx6AheCrNwOe*JGbvfPA|yEP745_swV?LwhD%ebs+Als>@`RT z1its*w;3E6Gg%!e-uq+L|5@Q2;0bdQin{}ao)-YKG{|AO(IW9)lMs1}M@6Hr-UW_r zSCK6R{>^s<;Gd@I*Gu3Yrr zv@Sk>8nXGH3=HanymY1~Os8Qb{wt{bh$%f0?TNfl#oEIM1~125o%=g)tS52`jm55R z(j=UWLEmU&fd$#7=&GQrB_95t=BUjZ|@{vTv$ymuPyb7 zJ_=~}ee|G@tom4LE>=TUq5L1@1{eY_8nVp8p;O$C2-$>V)_er#YK zrk#-#8TGGRh(P~_B7o<$V>ltxHJ?O&^qo~;U?77bKR%~6NEpC6wodX(aP%80zn7!x z?PXYZp5>oB9eK^e)9~cJM?m|0wWN}uuiRS7u4Q9~X#kw||9k!nsSrMXyHjlC?18)0 zs@ZfuMjpM?EW(s?zEE$Ed0e(r^!jDdgshL;flt5?`bA~Q+%Q#N+7}0d=z&YmKD$Hnc(bQ>aFF)(QQ*vszt3VPVvk8vdkC@5V*MdUA zRGh!JDmMkLBM2kkrQf{2F=?(HB_zDFN8=dqyH+7=zd8FW;X!#1!!w5wuSKmwn}?=K ztB3xT*N-`_EB&8S5CMWY8uC}{zt6%~CK^`jk7Z@Yl~_|(Rvg>Sd&s`usw8ULF|YOL zexVeg==8yrD_!)O?dO`Bno*#7qplBpxqla!A}js*SF7)?f*eD6C1n@Q+Tfs>8;{;) zbGMt(CZ=qe{V)x~UP=e^`wFq!CD25y+z>k*?Mqc=*F{0@E4w#fmF99{lZ>}19jj~2 z{T5aVGnO1Lu*_8HwkgpMDjhst^xBr*9{rQM`70l#A$OTE{}L_9IcevQDUGqlfe2*~ zmVFH}7#N>joaNGwt?lg^keRKyR&bs0NKQ`9&2KNf)Me%}00~{J1ehr_1MV}FJ;+oJ z2|hj>ZEhAW(DsgYPR@51SGNTP`XR8sNWebs$CoTsVx#eZ-?>Rdo500!p7p)&@4J!& zk~C-UI~@UBU0=xr$OW9UrhStpwbQT#>jC}1$&$lEF~HQH-A?e6sCSXv0x@>w3E+=x zJNSc0b>+QorgnLt?UN4f1FAc(d0oJ1IWG&(07D{5r#?HUcz;M_2lT$KN>5Ms?+t1M z^^h|<<>qNs&{x@21B)*6#A44s}90IS->GFP4D4BIP;0<;O!aoGb z6Jl61KrS*d)SYdCBGt0PbpY1hI26mebF#Py>I_4Ufxd7rDk@q53FIUG88*S)pTM@#&?{tp}_P{wkkAo#esV9sp?uf3VQY@8WZ`EJ=nK&|Pm&Hv2?3Gg{vF;oh)% z0o4JNwoe3{d>8@Tr8t(wSFC^@y#tu%uGZuAesV)Qz$+v4yMI*IzOf`R(;}3M!_%bc zG`v8GC7uv0G{?Wwt?p9UtuXrTVr9=ASjSiVUR$|GnZl!Y^JcCyD$R$#hU@J=JSSsis#Xv3y8YUa`; zeG9d`WOfsqZTQ#obm+@5Oo@YwfqSzXc#Yqt6K|L?>ZjaDAlB&na3{SB6b&eLwbKim z1srYR!!&kfAg<3VnNg_(Ry1B~&M?FFvR5@*>FZj6%r_<<>fL+f|>YXqMa3JeUTeI&^mN2MRI{ z_Zj@R4t8Uts7J>#qT5Ot>fsGK^ssNP6}w{IHDlkt)jkh+Arfh{F(!W17hV33c@BO+ zfS`7^n87zVDG5sFc`04=Xsjat;f>Mn1viM>3d}{uZMqm3PGY|V;gxx=O=s?blQ1^> zDL%v-aK_ZtWy7&5&Z1qwfX7T@!`V%Nhy7I#4;+Rk)(>0?ex3uMB=kq0ko`|Q8F1Lg z9L;#wRm;(E1$5IQA9tX!kGu(kl3*Y%8raqItu5#B{gtaM1l7pXonR3PFLQIb27McY z31!Sm*`E`Z(8A9qvt3+c$+~C&Ls%D?Hz?+Lwi!2)MQodFl%1tf))ERtEpdKO;J!lL zuO2=yScK>5^!cO6dtc%>X6w!r(5Txn13CQ|^_=SeRlVfuz@tb|@^qFky<=Kl?4qbFG3 zRgjbwmZEHVu2QXfC_}T~BzxF7FCUIg$Jrzao1aOyh9MTS+2LPp00VrZ1Ap*S;lPhv zroRaaa0ermPOI&*T6k=|q(@$7?xzqG9$BT+Z?k;5Whn-#(I$leoQEu8ZFqRtRdw>V z)t=rEjjNY0U?&aYZA!6h@RGFBNWcs3fHjwTTKBHU=ib}n!RjISa`C2p$~h@A_&g{a zM;`esUdQvQa=Nxuw6RgiSp#~an=ILU`O@%UZu<=-_13l1?D1dI|$A=i|NlO2@^iZtZeI`ITf5whm$|!k0`lOxE--lSV21m6L&|3+Tlg zJw3yBX@v<$0gCk~f`HRu`PZ+GpDCzSc*$DWM}i=kTfw@~n}83U*xLCZBJ>){{{BdX zkY@l$3My-8R$ko;k1dxV)1YtCv$Ca_6%?VfG ze4B#-YLT2W3cge?fv%e``s^+cD1Wq4y=%M_Zt2wi&VR9sKE0{Da*odx7+9@g=W$*K z-{X4~bm^jXM$OOvPobTfkIF>7|2mv_Nw>?@INc5R+wr22bb-(`nBRQ&j}n zq8pr7sF~AB04&nIMqbRfmK277onaF-atPnGSZypAWfM`9Qqf5km^L)>!c8jUWUQWr zx|ZrKefUW_<+ko+%$AZL`ek?g;-=Ud5q>+INjsRS2Y;FjH5)c1p(OtxK$|OA#A$?i2q4I%Y_p!x{~iSobgE`xE^ByK$i0Q42ix-gh>A9Xz&21i|>}_@SiJK}Vqz!=e>l_?UxrMWVOn zI(Snlv&3K-k*LE(_uqQAYKNc6B)=x;MRStSW9S{F!G9U^WHI|I#RX9J1>GQMrAK={ zAgWzWq}pK`)gnc8B`Qo2Jx@O*;BR z#Vuzb-rlp>koiPNMbpY-lhub7b4O3CKvKtKf9}>`cdPZn75EgX4fR5r*u20GK|IK&f0NVpfmPA4qrG+tMQ5DUA172&4~pUww`6Ixpv%}7ks!?B{)ZEzL_)5ItZstaB1 z(bi1{NEy#F*+eV|-&l*F!5}YJWwUP;J3S)~BC^anpjnASOzCRGDDZf{Rb#US9NxoxL^N z{Gnjs3SRX)ORZ^zMSs_c+rS4(e~c0fs}A?MA**7?vShkctb43f-Fx%ZCKqmbjJFPhEIGf2O)!T}rOb|FDd)pt68t?cDc236Vc>98@ZVdx}ow z4zzUgk`inW;i7J3xRfv{yx~I1Ld(!HkimSd5Xn8o!+XgH7jM^hrUZX@G7Igho8DU_ z!mxzFqB?LgC8BX&bmPQxPc1CDXY)SVj)NXlC{vL$Z08~y(VXqG~ilb8uislkyDZexDlEN={&F(E*j(FqPGXH+$s|F)mviG@2RFw^P!Hz)yDH<~%gb!(DrK?r z7ZM9&w<8vvoVr-49@Chi&Pz4u$x8gcxOeJTsXltP5AD$0h2b?P73fltHnA}JUQw!( z6wKlcyAT|~_=TaJ0rx&jX`F(gRkEU-jK}IOi|5Pa-5_Pw%8QEQG;^YjOkKM+ik=d? zq2)gXG~vj(`zq8;(W_76HbtK95Hz+mSPig-NQCb2_lV)vMW>pF-M*2j5J$RLo>5Zc z+m4$@y-IPm(!59FC7KmI%IitU7L1B3omdh`T(vasG)1`#q;RF!fqFz+7HmDq#LZ*# zvgm`G9R!9;bV*i+a;p_p112SE#XI4lPPOS3;ZIc$OMfi~N8|RZPP*BXgd6S4y#B9< z`Jv;lziBoNvnO+XP`y5TnTg zmzPKA!qIb%WySnz-174BitBkL(}%qmSRcK3wC||2u*@gxxbuzpiGcga1s0Fq3+Kt| z`zk97-r1T<{MT&K&;!<^x5ok>@LI#F3(^ZMaq0`oxHwx342SRZE+I{UHrYo0ka!Qw`T2T1qjDj zBQ+MgpI%2q&JZ?zFOgD=eKex^-1mI0y=w5+VxK`~>lrA){x`gW3~B+=oAdIkGtjX0 z<>356fh}9G-yoS$EBTvJ;wQ=aX02cOJD1eRf1ekDZUy=;U)ogxp!7g8Bipey(ud$m z`8zOE|(q3xWe6F|5_2k%33S_t*0hSfx z-lFo$c5sTgEW_Q@_W`B=`RgPXkh#F#@v@oO;lXEd*8k2BKNQm;{N;V;CjxR|p;Y23 z!7Aw5WlJMaqWsj3RnDX90Z1r_d{hE$d?tMw&Vb0KZib?Q=PCf}HQGWB4+J9|0o*&d zeZY}JX{P=i%GNzVDuz+At|;#R;u!q?ot9x`Zvhm&1uG7gm_J&rKX5E&Z^MvnjDS82 z4V8n1CNy1yQ*(g$gMa^AdU&bD767|F1m5xTPP(55D7Bh2IYi3(?LRCAw1gLvU!SD= zvC=&|-XC^&A_M9Lo7e{QQ&vGMzzm-Uy;CO72^Rn!F2uv8H=V*PmRYI?D#NSpeGtI^ z$nc#4pDsgmz+5~j>b)L&@OyKGpEqslO=;O?fBz1+8&WX-XNUj!mqHaRW%K=9I_gUn zzrJKS0uTAAvq+DwEn27JCax2(0#U-AP68|;Y5k7CDu*+ULS(sw4dAWU}s)q8C#Tjk{j&>@ncdx#( zaVZpFzA{OeY1tnrplEx5w-(~mRMNr)rQVse>Nheb#%3MtUa3M#o?;Qp98wJ`9=gA)Xk9NcdtuvqIhJJ^!S>d5^OwO6$h~%m zB1#%*!h$34-K6(vDXGlyz=4W%u(SJgEj=7H+Yp{?6w3uDSB643>;g8JG&>j8%DRj1 z4rAYvvQc^n>&XiJA7x_;1Ie6Ji}*CJNbpuOhG+2MtHf~12KKYSsGgESoHJ^Y=EXRm z(E95nC=h@lS+}3ewMb|8e7u|3@QWUBZwmWbE1iP@A7~j@jJ|``&sFpe(O!{E;AR2RD#;7IaDIPE8!qtncLs6g01wN78lh zs5D(yc~saJ+Y9(b`d5vRJ;4#c;Wvk~utuPaFq{}Fp9hiVAn?Q-4JK#e+sf|R3<3Z6 z`2=tnWz={I=)5ssW*T~TK*XkKI$w9^*Lzsl$$N2jt(#Ps`E8GiT3}PvrfDBL*|W{I z%?G%FG>*$y?4na|-|~C!|K@NY`Uy@UnXLjc*mr95I@iS*P@bW~nSmFKXJJNhY`%D; zh~Pcm5WLR~Y|F6T4gsqvk7Jlx21a9Y6Y$CXvgnpuuT=*mAX6P#LvdQw$i5>z6|);6lAA}h*&th%Cm zF(%NmvQb3mCKVx73o8$W6r7y;+4zWJ@0h7%&+Uw(jFsUQrCH2Vhm6D3dbKyg)oG90 zt9;UIYI)i#tBY&57>g6aV)y^idEkdT01d?{ry8T*41dD~b>k?_135 zv`wcX5BBENIh1_HC`$yfr^VR~Jhn~3UJCw+a6)9Ad>0MD6n<Rl@ijSEsr0Z<*Mp#b$K*-IiN7k%`?I4vqNcuFm ziUOy^G&r)26|tOB%`J1|-PbJt8a3_<3ahK9Gfj-SB7ZnS^=V21@Cn0HOh3x)-h>Ls2 z8_F*KP%cFM=Fip|Qsp*3gWONSYub$lou4&zmn+V1r|*FBvBuUWo5^$Tej=YNo4Ew* z``5GdI4pL@neFz&OTOy5%IOHb>mU8EZwtVQaBSPKUJ}NMf8KM|0CTaRq0tPw< zRX}DI4>T+30UkM-0C%8>u=btKozS>U_CSoPg#})`FINm+)3AwDHjpwLIjQ?Xb} z)g|Kv8=Mj5x0wPFRpnfTYGb5R-YEGjJ%(urxgGN5+9FpGJ%U|>uZ5CE^=(*7zpPF7 zDR}B{==mQ@iUx@)WPh#=vmO*aY*kudGNtzH+X2z=vW$o|yTQ+?;RKqJ>QBxwMu&>B z)Za_o_6)OVfvQ4m!}SAQVqJQ6`ax*==bWV(x%M+blD3&`h5~s?j&zqL6NW=YVzO{c zw5zQ#14)+L^}|~h$QXq1nn1OjMptLmA!&d)~yL~c## z<N#@yf=!OX_JCe<$|h0=F1rPgDzwfBwU-pk#Zqmr zXsoAtbuj0o@+kL0n83dm4vI*4A%o=MND+}I&4cB01lv$tm}n2G7OypFb$a~t$s?i% zRYfhN6Y)v}tDqXn_d8{pvPR@SnH-zwGySs$gjC^8H{cWn^1Y;12)FEv&{ABAaG+Yz zk0w7Pou{KBev3S>XB)^%ucu34&R|$DVZMpZi~E&-_570jHbx`-G#?beu82{3g zz0Ng~)I^qZ)_PYZ5`)!B$5YV$*Gg4GfuM0j4+c{80O(d|hT^_1azzG%jAWzm{Pmvm z?}$MP)dlEEd*2Xo1?X=Y+Nj6QR6S!)?-r^|U5tLrkZsCl_sHbvzlUrZ00F3z5>8X@ z==0Pa?50Lq@HIkE7EEiYc8&ZYfFn<*79Tt9l75RiDlQ%iCIicMv`B-U;p`G#8A@R-_A3fd%j5Yn9% zR@4q@V{{P>?`wo%N8XcWu1=p8$8^2{rHpyaGXHI_{?T`vFo@(}!T6dXQqy&A=2*}`?$0LtKWTKPV0118p_qklY%DL< zfXL63g9GSAo96XM9+#M6-Vntr6TVhxFm&$;-@+LL)%VfYyv;QOCW{klcU63*k8j0p zywiB_=k#eohrv$T{w(wyTVB|A98n}S*>u(0TWP-LWUV;x`eY%R@5ZhC9v>yvv3Ol` z=&?GoW{5KXyyYayFWyCeZG)tiTiTHRA#^DD?Hsr#^#%C;drJ5>8=zCki9)fdh20loew&)sWAjYRf=%Q&w#D$I zD;^OyN&h7Ew61^=h!{QsBZ|{VN6eMX{>#dAFE9Ds-CQ95MV_!uo{TgszE#EdizwPga+s|(2#ng|GDk}`N^T(c#p3J>@}@tb28A^s`>w`P6iLHVlW{o9;|OSaykc3b zLFW+Zb+?vykUp#dG;l;2pdft&Fr*dQg1pf$sc{fG83XJ?+LeIsVe}yS9l$_!c>nIp z#ov(e-po4yPP^6Mz`#KE$tZ+#7^{6W27tL^Q0f%)wHO0g?(?JLpvi&8+?2A6TLWm) za9dkj`|Esu5JFrIOmeqB?7jb~usJn50PTsVSwa(l#_bvun4u8JhLfXJ0;-w8hU0Pv z2Zzruo`IpkSFciOHW9AP&MTdG;r0O39F~Po)wBQ#&c*;BFQk{sU^m?xG;tW!XZ71O z!0oO2@5t?d|3#lGwV~T*qGJU^qu<;JWl{_AwT6;;1OsAsId=9FCkrg7BAlV2?n0-}qp69WV|jT!@)a%0<8YhVns)LdAt_m=$?LC?LP zNn;>kA1q3xC35&XcB^Zp=LB#(>qv+-XCol}(HN4v7VyUvvlMkH;r5#yY`dJLow80dq7R@cbaHp0L}a_{)ku;REI z#R!#~+YUFs>79oK3kM=AsJX}wLEo7!64c4s^y8ppWeHJsfD~}|18vExWzs4;0g^VJ z#@?9BjTFQ-JkK-{6&4PkYhK;(l77x3Urd4mLCBhel9T-sdy1;E>E$e5c1MY$*RcikTv_53;!aQY6EK z15C6v{caYQKO#C3<>_At_`;I(W})NMfIX)qPyCd_9I9LW(mS{6<9`U4y4(O_KWd3- z8!wUuB#-9qhvvMU6{j4%JbxCCuEh%j3K-RM1oCQX`n_Q%D0rl z!#->`?5Fd_bL*0}Nn`eyqRQ!LDPoyyf z2T~tL&*ok4vgR)Kd<*!)1W(}oH{eW=4h|bJ6w>(D@L$Nln{KVX`{GjT6RY5krzGcB z76vZtESWi3@!EZmLIS%ssNd=W67Oae2~j|qRb{(HVZ2kb)TS4uwNfXx@*K*vY%$=9 zXLuq&qR%Ndk6_d?t{;uq<7CT_Pd~-;5c?s~f_wICY(XN-orwZBsC}A-s?2@YE;;si zmJZdJ%!IT0Cl?H`D7OVDojV4pThGSXf;n1t{G1`a@AKW4fhc~rTs82YjHHClWMe4H zBX56?DGn`$MuD6Smy2wij}g<>#ZtmZ6+Q$N$qns`QH?BHd$p_eBdZT%Kmb8xpQQDp z09+VJ#>$qp0O~~CrePCT8;-U|EXbP_Jay~Ow29!iH286AePoclZ|rym(`3x-b3v-p zxm%D;)VGcH19v*sHgQJ-ZO`=>Z+&k*W4_GKwY$Q(IQ;wSoF%?2TOgvJp2> z3WTGS(=FnM6gy!p%YXIAB+W1HxzXGJkGtEuymM5pznZsEP8xA>lA`w4g|YTwjo4Cg z$K=q7Gfrdzo`B$nH1aZlJ5zH?|Mb~Mg(cG?Sjc?!E;-{K|D;itM#*0>Acq7gTgc8DxFr+RmmN0M&6ouIQG)jOx9L2gDq zHFC%Ee0_Nf99i5gVcFPp6L}G!{8&d3%{HTwGZU!hoqIUr3rOnHxaMX!QVoHD@sG1b zU)8{CjBlN@WVyf{_#EK=b{O|`4==he^iPVZWfroaTw3`^P!fkBdRGfbfx^4iSRDTE zzylHJ$$_UUZ+-k`X)ayyAD9}ZnI+P66N_FYjBAU}Ni{=F(L@o4J9%1fPSidUURCA} z2)%vlF%Quv`64Atet?!E=U-)eHsk;z!XRD+8fAV4ZD&UTwCDU_{Y~@ww@RbZ@g+lB z<(}y{KSN3+_4Bvk6-1b5pgM?4bn#L|tuNzJeR-x-I*=Jt?pg+Hfq>7Y`WM4f!;bBr$>JngBO+0DaIC#|&`=iI zC>gXCQYs;?4WlbLqx9Q$7nKqY&nEmXuh>Ll;77oc^-!I>9osaJ}zZIKuHe@ zNvbgg3Owgv5C9*2f6C+e)z?>`Vli3A0_FRuN&)`Z(L@yljRTv!2C!-;WxyK9Qb1<^ z-;0*VdC_*OHTF5;;!6$>*Zv$!!8wVzT=Q0``3Xu+Ukv7@|1VN@e5nF#e}6y#lqUmm zFoIY6P=^B~g$T~lGE9L@fMG>QNT|_=VbNFb?tKByqs`_!NUOs^OdnR2!@R6Csq~|Y zbPNe~geXD+G(xy{1t8K;69~ds3Ug_wFV>37VDat6dHgshmI$T#JWCkjoEfNz!j}Nl zEKM{`Pi_lD^F#%VPz(~rw|uX1OM3#snjd4qDgMRzkAVt)FiQB?T>qTa#m(L5%~%TI zo+^*8wA}}EAEwthBg(O-fwjV_HR|KHkMw6m-X9$@F;GuQdR_&BB)6bIpz2uiT)HKU z2nKH=FkhQP+a^mnnOO|cT%4I7#38E_S<((~-TZ$KR;gYX2_jB?zo~a-j#fn9N_Y{!a3MmN zY9%@v(%X7h8ny4`QLBh#$ZrHxpzc=VzkmUOOAnDL=8(+KMAb~OE1mWv&0eE`*BS!@ z&4teAINKQG0Fc3eQhYgV%Fc`{e-+}bRq}Z~=k{1ysX|HRiSRtJGtsw57n8tzKp@H0 zNjyCY|L6*aS-sW#G@4M?&Ryar5TMG2qX8}E0zGx>59H3x-~Zw4#r&>BY?r=0BNB=q z)T!w?$Kmj_0XW~hJRxE8ga#b?^!oa6y_@G0%G7;^kW&RDhH;sx=eekthzU1pS4cDh zh^Kr2xyuK%+>#%itMVDn^fLHzZlU{8f)rc^u7q(#9O&23s@Iu^+%6l}?VxdwjG<+b z%Xot~EK1g!+x74>ZzFbtvSh9JSUu^nLZakXYQQVL$mXA@sUfEVR zE;dRUjtGTZrLEdOS$4j;({?=HGQwAIN$zcziW6$)-JNH?pXmT>AV2PC5PyZfC1OeW z$2Wh?UA!Qp)AHiP4YSK(U`Q7N~-=5(Cm;61^h_{@^RsBe~kxsLP5 zS(D7K#O~=kPkpm${}GEf14B{tb*Vp!s!w!UwId765j{>;E}p~Zhu*Z9k8R`pCKBoF zs8Uy@=ZU+-zOdzM{w+tZfI1NfA{=Hr&VMCq0dOx_!MIv=Ewt>vqVrx{^PQXB+Pch* zqe~^;%K=D|`bJQl@AJ(~`YUxj@?tYx1YGn9dsxA$iLZtKkyrgjFLraB?S=+{$Kkky z^2aagqc1|P*VcHR%Vd9U@w@8NA!GUOh_6L|EH29Lux>U_oVLBX?z!$7w?^o0mQHfi zjw98!kH0@Ln;&`P=$1_%u&?MmX?Yd*WN5O5EhyIXi=$wq(z(`DF+fA}iC$TKRk4_~ z{3Acgh`dquoCaHs%2yw+;(xbIrjuiJ;@#S+pJY?G)H@GdqhWCod0!%%`USR1g$$gT z5Auguo!le7(xbSozu9ah7OQ`{Ut?m(=nTCR$;NN8bf=V|@F$;a;@JZQz>x?oVA$rHM4|?{XC=4xM{qFF$}@t+l1(Z z=?*MjyZ}F+2%5-W${b$B{yX$jIfg5#nw_8!6pXzk6vuXnao1G|b3Y>k{M3*y_DvL> zH|^R=iN)M7Dm_CHkGKD{LJ z4AEvpr(s3Q@W?ADp!?L9OjWU`U-ns}Z{07TNC*i4dz5L(opAAFT4U|_R;`GgULZzj zbcp~W>GERJwQaJ#%Go(g7IQf*V4{@{aQk1|UU+u;;l$Y-oyT4uHgm#%nG`kN_q@I` zaY8-nU~kMqKtSM5CEIF3D9x&UL+FjAe4u(#zu1ZBXnc`?7AC(jI)A(|XX*SV6M3rQ zb>*%ViH6z^o?6&tKzVR$v!q@1DvDwZD)=N*`1E1re z&O4&+t~{WkR;c1^oNe&KDFdG*3_{b#*S8cnxMmJkdOdI#utvoGQcMhu0(^?v#>GPh z`TDWTT^ZvD?qB|0Qd+|H953^YZr^fTO_Xn(bMYqU*(?E)#jUmrw=*9BL^CrIRqXUX zh$c6gPOIVJS!g?w7B1!Sn~Y$SvoXP?SJ3 zz5?|5b0Gc4vg}LydvZI2GV?vJcjJcBmh=;})kAQsUo+rOCY$~31 zj5^)CNnemau#r3nS|owPb)cmKhOay44Ue|FHH>#7ERKesxQEn@taleGgbP@F8-4CJ zi<(~r^p{#c?a(#P=G2f#Fk|0;tLSk&5oBFA0*d3ax~Rj*W~OYQB>(iSXySC{dZF1* zK!CU04J+XJuM|d$;WlWysZ#;tc&($eLmFEukU}%UeD^$58+LV!v-m#qC6nEH10jyh z^g;=k*t^Oa3!uC1$0Yr#9*sP%(74@b9s&}z_#-~rwqu#Xjv?M+J6kf4jezz`MaMYo z_fev-V7t5}5J;%`5>SsHKh}gb$U(f-RntGAH0A*^JTv6a>%LxlV%zS~4?hduM~) zqc*Xj-W{uIjvl8T4R+jeX7OSG*d~%1(dSSk_7Rq*wkLjyIkm<~=)gV^&}&tR;h+;k zt>~IG5#kctw6&VOjKj5PyR{}X^8sG09>3;|d8>;|VORuxv<3h3IHEU~ypyBCwafFp zFR1%(X%P2TLlSIfPo@Y`|0Gi=_)@Y^^}(Rbi0nQphTUQU0S09Msd@>77NPA|c9}IE zrR9sze{vPH@yeq_%5|H9mz`3Bsh8RDnT65Ngt9@AYw|%Da95_&5Mc&81hB?KJf{2O zpmwJyFKyY+nGMld%Gz3KbaaMHCd6BmC(}KG=Qp{KhIwva3Y}JE)>u1rDmwJC-t$uv z>*FaxC!suT0y+G9)s2t{xv!CjjB0pWQZ`R5zI1HcZ+F8x80ZFIz&f=9&~O;6@$Axx zT(SZ9lUtmkJnou%Iy9A>S_(2e9@83V*B9bzFyw#(hK{qqOyu zpQ00V2VzoL_0MDk*NmC8?7_>+%OnOIw%B*uHie@0{K?m?Q(eYqsNjrb2u@~0XH0_P ziYLLHgKBhaa z(ue#bQhuGt6w^OdIT$Hq%Ei~F`XWQGlW`if2?9;(^%gfW3N?W={z|>hUilDMmd7 z#UtTDkw$=QnNhBeDJqlOXrXsiS>#zwl)|Lo0|PH^+nw@ZcNZKXl4=%3LoR;zm0C5_ zva1caglcaYN~MJNGIDgl$6&_y>{CbTcoOU#= zppYF{8*SiG>@xSLn$n3HPqdw`;!ZM8veLDi2d39T^&KA-hLoZuU{q>gA8Zsl?uCg>76zDVZaTNtW>0Vbmu4KAEw<)tsI0M!*ur`2^JyP$hq^{TKKkaL11LfqZR#J~5?; zfQBZG&tErB`uhYc5)bRd+la@)`R(rJD)oKy?p{q0V@16juFB}S+m9wtbM?+-QXzp7?svaW{&D3)>4(ZL7kjP|H^PDzz_C8t+aDuRl*{tJjvf7&F9+TrYEx zsTbZ`@c$r*RZ!o6<=u?-U=-F|wBUsm*#5G~p?<>ZrONUo+#^9Pi1MrzJZad8SkIch z6)XuWu+){DU)BU;9N%u0KNK)?C&%UrW+`YzI`7L~NFKB)SzZe2c&2m6sF(LMND0^= zz)>tsrA>x~7B&>|DHpg{MNf^I@*f@r4$VTW(PeD)d>e8aQz*FD_P*sJ+P%uxh#rx(F$ZYsWFOeMhW_@ zOUZO0Hgj%n#dIV(lf+tHwb73-lFGdtYKN)xTD62gqe>goXv;J@l_o|fHKH18Y6+t% zzxAg1*dD$hHe0WRD1OW!n37`Ib1HfQP6GpJCp{dU3 zpi-|9lLd@L%uKoDer$$YVDZMRtn+5K1Z$gYV!|D@VB;_Qrv^vrRf=@8S<)-+mLf}# z^Zq^qs2Ac<533L0sF{bX+0M4mxcuSXB_Y@7QaC+GH^1@9x|lx6@lbhZLJ!9(xFMCH za>Wv5wH3R)>%b-r}`NlgE^&IW>dE=Gh8z=ID;z^=g&Zl2}r$xdNVNIW5DnH{sjABD-hOg)+X< ztiFJh;Ufa#qT#!oOay%6(BaH?BL%*2Z;=*CYVb z!_^-yZMW06;P36_l_;LEwLq+kd1N|awJN3OSava!Pwg5!=^_=SE@KCtX7z2EhY^^t zFdfm^>YoWXNAJc^oys9KrP_k((2zLUhNokXo*^?LXX09fR98AU%?Z3cL z=||Hw2hZ24acij{bV&0q#r|xmB5SDcV~T|DaN#mxm7DzuXE40m{S=};sD!Qij!GO3 zd<&DeoH~9vy-vu;p5@ge@Q{Ou&SiPnZfbG>^iM?mfcI*kL6K?qDNnANd zk)bmuMtHgEE?i>9$nYP#-dR~u(VD3g4WEc{R+v#N$v31lOmd?hCpKMbW8onnKXB`F zFh7>u$kNDRSBnA0$7SLg8D%b$6YmU0lEWidqY)~5mF*ADNe-5o#g=@QoqnTY9YHq7 z$k}~n2PT&PASU!MYvF^7h2w^=EpqS1HEmVbh;f?T8ivjV)9SJRwnUR6V;6B!=x-yh zzdxnIhs)OKxFwp?8zh(d!MQE)p$RWxBFrCrR4Rh<^qa@0ih+x5ZU}jnk=@W|`X7SL zou^uIE*$1_HSQhY6E(YL2_v?$?TD`*R;ME>fvWw#RjU4P(=$!JC4zYn0Pq|T1*-73j^%Q+KIspzP?bM)!@ zL8l1TDm-uvP5z9hIrs?gb@xh{KPs3@6pzh9habj%?%%N9Nk^u=X_vLbC#ghm9sP=u={O)4|TdkVl0>x!Z{))&1vZAM+;NDQ#{md4EY8R71Qy_xwwo8tf|w-Az8} zs`X&XK-un|{7B9F{c(wsH`;(gNYb={HG%j;Y925NK3+3lWqbQA+ZNDWFM*1yg~yeJ zp!yk?@Hs;}YW(g-B;|)f$qNBZ7d~aCt8iA zv+wa^-ouuGb{>E>4&)=Rz9N6ntY$F^1@19?0C6wRQtMH7gnJmkgi9bfl%c&cM8UZ=5sa;A1K$Qro051VIdk*yeCB<@n7|KolN(1LOj=WW&?t62cyk0MP3+`Hkz7t~uM%1y}4# zt95{69oh?j#RHs5J;50P)W|nBTWEz0OB7`U$;ybi2c@9ys2sa;DFt&xB;yvml}tyK zldSxYcL&@f_+SBkR#I!zgI5HW#y3~kvInBS;!C$|M*DVu$|ndSi|&Ci+&1sOUW*5F zB@5|hE5H8O+_5_LTZaHjbwi4sMnIyj)dBb`lEgdt_}2LC@oS~q$AT7Z)kD|j9EAYm zHGTV)?hT+;z>!=81(6$oAsCn-X-!H+Y6e^+u?f2jR(XeXE4b0ptb-y@V1fujT_{r6 zos@NFruYT{JSKNa8S14FJ_hy{Z6qMY#BF(Qp)- z#qYw@NwWPLkmSdY;T70RvbaBGacYI!x~X(9i^&5|9|yUi&;4&(3jB|%-q??iPGAfd zV&GPCZ7HDPT}4Xo2w!7|0WV9cJ$;m3S@R%7WHb2M^pFNdWx!v`oaCw_Q9xzk0$@+e zUn1dD<<0a)O8V4!M}RVd1?fJPqZOhAKhXji6)Bjpx6cHQN=KI~JOSo-kNDJOfcNj1 z3ATf3pGcv%HMW`s><5gy+4^EL5OSFNGIp=UHaEZt5@5sq<`a;W%;+Stq33)l=$MEg zl~JXN*-(W32|Npv(=Z<9tdhs%h)L1>tuG#H^#W3jYz}LLI{cwtGlAGv%C#}YfP%9l z?LhYAEVdao*SFxAmQRTOu zg_b`T$%4v9XgNq?_WHeE(W!|6xy`lsk=Ev~aBfT_zAaHjQ0%6JLpw9Z4)GpWhI@{e z7eirP5=5*K%wRMz5g(gBR$dN3)DWZMFU0~@UDA9mFsc(KT}Bs3r>A#Kt;s?qeO%=}nMx7rGOSqECZKD9w~+g3djVFtT~8djgP$^&aWB0p;9j zhxS}0bq1kd)QCr~LY&LE2-xqNe&UYr<&$`9pqrU*^j+R>u{7f1)1fcTk6u0fw^x^d z)&|4F@{S9R{nN}*z1gOWnu@Q8l}n33KR53(2>G3oj@-(VztZtSd^yF< zF3EA#v#g#II3wzPhqr4wQDagTzn6=Gd-W9U*+QHuEp6b!JT^zBH2o4SLn-yJEK{~W zm(N351zg%PiYl)i{Eoke@*HbG-vllj zX?AHJgZ;h$9>q;|WfwN)Lzi%RCpDnQuSY!il%p#&btTWDMqWv-{x2T&cnP=3of5G7h+t zGUMTsuDxjzl*Due9zzZ`pNZRO4W`k%k0?J+0jOVFP83!!`959_u1ied#OZR=jFaUE zBo#6#G$5x;uJQRm%{T&i>a=Mj8+!slSOLz7scUA0C9FpRB8^@ohek{Ca)@A_K}Gzf zp)4Nw8PK#RGsv^s8WHJ4t*%G$%P$ryoio&v_6=({w0C)dE7=y>u>4j$GvUsm;OMTf zw#kOG_oEncC-2XEB2a&T5r)jf$u}WU*j}ncpmn3&mID(@C25|Iql>cx{mMU%!nZPXOIvtTs$>4O3 z&P*hQZgKBwwwPGT`sgO{A-K(r)%X`>w|_x-@~fA1Srg{m1;sHqQdhY66*!|HIzccY z#*yxts}-io9C4SFV8IHkY{5V={Lh*tp}C39&)YjQT%b?FYvOC+o^WNOrUh7OYK&iM zGdtyQl2spJx8A51#ZM#33mQXm3OBbY@v*2)E*|7A~`yO_$&*G^Ld56Rnfk9;= zlt&><4TH+Ds(ALos)`CK8eKsitAXa|ZDA!+=JE^VED-Z-ERPDoY2h+SDK?DV2F=3t z9o@66;@D;uSX|KB3VWAPG0zGWjwXd}XUj=BG7P*Yet^_8T$&l5oI}}K0yFA#I}3Ng zvyXo!>|nS?&zblwJOC>DRaf7Yxbk|%uAAFs>i7v#gM5|vUs09b%%FnFbkC_Y{jbPF z;3%lRIG*DZzqdtU%q#pfJ0J>sx2f~)b4mm5QpVMU=CMn%>HPNr1hZDy3h5^3obFP% z(~`7HN*Bharcf9}f@vMDW#IvEt(?I{r?zZj6v61aUKpW-Kr8$zE)&#JKq!&s$0}pH zZAGj=J3%(yQ5ddm-I;?+#hN2dLO7V9Si;GQ6#7TeZ+=paOLCMDFL_U$rUSGm`u#HC z7D^>S#mA1G>!`_M(7LQa3+B#0BTYoGsmrl%+P(wd0?d>kPQr~dTVe5L_j%nd!)CzT zHk|!a_?`QL?jlnN9fLs9gTA{3BWlr=jlePi*Fl+$3=(D3hiDdn@g2o74M7ca#`5ef z;5U+qQgUgv7dhiJ_)|oOg>VcWoF^cRz;}@xrI8H@iumCINk?a|aWOb|Y5gx#glY6q zcPI8CG2&(dCmdCDQ`J0Vl%RVnwpl@ETmOj^#R-5_E2AbEYt1p;hD=FOPJx`ooLY9C z9sJ{7)TMmC(t5HV1rhqke(~4)|2n^OXRHrUSwQHyLSfOzwBCWRp-%VMZiHKxLF?hw z5#_%0_3~K`ykH-mL>T&uHsI#iZ9=2Mk$#F-|Gz5Xj0t2QRcwBzy)NH2Cv^27;h4(I zICh0!?d{5~W^$m{cg|N9&a%$2hm1)M10t!ZRQHi|E)`gx(X2 zq&c!@>f6aHu9Ji3EAY>3qs?}&3d(>(sa}^fmhciz3!F|pu~>8sErBvy{s`Ch!W#z< z#1&fxZ%lI3hs4qBAU~ti&BW;FVA|@}AabSjiw@9+!S$Bzg|Ck^gw;v{cRzQACnhyY z^15_VH!rxFj`NR!z<`Gg&UE5R{gX4`+HHW+Z78rQw0s6*OuPBD8!*_G7MHl*MqRx+pu66mHtv^sXYJ z5myMY2f)fuMuS<9w{2kR!#K|0LqyLi;Z$!n!sjCO3f8YcU;HH#MV$6=xu|TuPp{k} z=x!_dOD|!rN>KO%fOgZs=OSo zvBb@YV8<-vK8wz`Kd5mM+#XQvU-GOZUy->0cvoK%FPQzE90F%maBpk;)o*@Yu?KLH z69Q>S1d^AvqR81p(rrHfohdKTWtM%@-$wKA$pT`YPoaM+!obG16?I?s{sM-JXb^EY z)rtmkkBJ;uq)%*Hij3w7vBai!oUO*xT|33CY51B4*mQM1co~{D{(^gz-KEMy0T492(CTr*1!qis?0b5Xr}{!9W8@^wcqCBu5ZU0p;s8%>v`T` zE}?W#5a|Y>{Q4~P72~RD^pkFKT#2Gqrg4j-LnXy`v;yNPN>O0vLC?IN^9> z2R#j!7mJOSne762S_Hg{kP^1S96fQR+f?_!Dz6zd^SZPxPlGU=skRvNOYJ!kZI5ow zg4`VcW{)G+#w!i@Hu??e!Avh1#9!K*v+5OM@V47qlPQ5C!kB1OpTZ{qyH`K?e>rqt z{+L~&QBptLG6^ z)cxHP3x9bP^Xq6~FJTpj zQyFstZ}llE6h@3g8o6mAd>ji~ijQkc3RZFdG&8M-IhEC62pTgN09|YtbTIgurE=*u z$1)Irivg^J6-Z9F&YJk)VN60$w2I?#E=P{b2k8 zQ8Syz3%6>O%&JdRlp4{EguVS9xNl)y-DLhoJ=e5=YJU$fBP*KBSD!?Ex@uT(pGBdWN?v@%#UQU}hIfPTtxu2}*6-*D8Cc$fm7}H1%~+oOsdJLnJs;cSH>oF| zQt*)7?Fb$L?uMKwj&3TDLY>$1oaG3F($bYq=WgwmCMYXIZj-d2Ldr$1(pr8_4x4zY zKX+UE9N~&5F=EeAU?|b!>b5KVc{#uG8g7#TYG+%fK$8OUAT;(eX25*EUfHfcdZ4-r zEI{%8o@$sRin;)8K`rGD*H7N&J#Rd4^UkSgQ${N-HHB=L$mKBrT)XL&M}FEwGCD=RQ_o{nj2u4~m0& zi_-C?RJHG@96!y~p7a$3kBUmuL(gTQ#QBt6Rw+YRpKT<2_MMQxEr=?Gb#;C`WYQJ3 z<&tPGg!N-8`v4`x7LkhJ=ktCg?WG>sY0qz?MI{LxH4-`B{yuDmbEK*o30W|wrafqq zTjM}Lp94}U$XAY2qqmyq?^bEQBQ7)*Wm(*Qp(8{WSb9b%c5^BlPn5_9Ef;wGP+l6D zc1&b$n{ildbaY5|ns$7o;<1xFcwY3!fa#SBpCT46EYvKY`;x`?CA|SjBZ72Y3MmBBh73?#VW%^ zX=FUj*7Hmhq3BtbZn!o9ESQ)ZwU(kDR#Oa&1Yh+{&VX~$*O&&GDMKy!BD5> z-g9#id5>C$!TlhEL3&h7H^$6G#XWa7cK9roBB-G2gUc3E@yc&5VU4rkgAn$xwP|>8Y)mCzQrGEeeEf$ zt?fI8tFtuw=Lar-JN8amiq7R;pw7q9n<`O<^Le*n2<2OU{lKR(D(5PeC}Q`A?cjN1 z8lXS@I=vgW4W5&0{r3RnovN?DE)jwCn8$wC*tAfK#G@F@a#DCnzBr7YJ(A`W_cVX7dov24z1~^|D4}QWQ47 ziqRoJH*47i-SRXo#*guf=FrFfjQW9wadI2mYHac&E>KK-rR7KpUNUip5(=ZslR#wP z^Vlfa5NW`OnH?=#P3qUu?z#&jX6_EwWGs_=^(#s`QZ&cByOg63fP8}$%Tg~hM+}H1 zWxHePf@107SzOmB={0PMDC{A%xlgL&(ZMvc7&R^SrdAjtTd4p0>MDD;QOE!k0SQ9# z^nrTLLUJ&458T|1_e;9_P~vL3bbGt!0`{>lbi)5zGhO$s1Gt5oHeU7H;ZGA>8F|BI z|GjN-S?98mM6Xdeo(D>ih}YKf+#!vLGb2dIj`E$Leod6`<3=S2m&lQU80tFyZXvJKeg!WB0LMe}18f-L2opD;@Cl#xGTUdA=hVVR`Kk4;iq!0ZjG~(W& zd{XG|ZM?S>{F?RMYbr{=kL(j1o$Qf@JkYnZh4#KiciKe_E_mhE_M??&b_zRn)#k0p z<(zpuD0h3u4L+y--p%e?qRh5fN3`|F@@sGF@T`Y67B|vR=}4{1-`%-Se$TDUV6fEr zE5*l6$Peh%5_GTHi)mg}49@DwXh6r)g-c~#OrA_r<={hC56m9WfZ74e(Rl`ZXsE#I z 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

w!j=Xwyt5#p@ZJ8@ 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 -- Key-value pairs are separated by spaces, **absolutely NO colons allowed** -- Use two spaces for indentation -- Object arrays use `-` with line breaks - -⚠️ **IMPORTANT WARNING: This is NOT YAML format!** -- ❌ Wrong: `children:` `items:` `data:` (with colons) -- ✅ Correct: `children` `items` `data` (without colons) - -### 模板库与选择指南 - -根据内容结构选择最合适的模板。 - -**模板选择指南 (官方):** -- 严格时序 (流程/步骤/趋势) → `sequence-*` 系列 - - 时间线 → `sequence-timeline-simple` - - 路线图 → `sequence-roadmap-vertical-simple` - - 折线步骤 → `sequence-horizontal-zigzag-underline-text` - - 蛇形步骤 → `sequence-snake-steps-compact-card` -- 列举要点 → `list-row-horizontal-icon-arrow` 或 `list-column-simple-vertical-arrow` -- 对比分析 (A vs B) → `compare-binary-horizontal-underline-text-vs` -- SWOT 分析 → `compare-swot` -- 层级结构 (树状图) → `hierarchy-tree-tech-style-capsule-item` -- 数据图表 → `chart-*` 系列 -- 象限分析 → `quadrant-quarter-simple-card` -- 网格列表 → `list-grid-candy-card-lite` -- 关系展示 → `relation-circle-icon-badge` - -**可用模板:** - -*Sequence (时序/流程):* -`sequence-timeline-simple`, `sequence-roadmap-vertical-simple`, `sequence-horizontal-zigzag-underline-text`, -`sequence-snake-steps-compact-card`, `sequence-zigzag-steps-underline-text`, `sequence-circular-simple` - -*List (列表):* -`list-grid-candy-card-lite`, `list-grid-badge-card`, `list-row-horizontal-icon-arrow`, -`list-column-simple-vertical-arrow`, `list-column-done-list` - -*Compare (对比):* -`compare-binary-horizontal-underline-text-vs`, `compare-swot` - -*Hierarchy (层级):* -`hierarchy-tree-tech-style-capsule-item`, `hierarchy-structure` - -*Chart (图表):* -`chart-column-simple`, `chart-bar-plain-text`, `chart-pie-plain-text`, `chart-wordcloud` - -*Other:* -`quadrant-quarter-simple-card`, `relation-circle-icon-badge` - -**按容量分类:** -- 高容量 (长描述): `list-column-*`, `compare-binary-*`, `sequence-timeline-*` -- 中容量: `list-row-*`, `sequence-roadmap-*` -- 低容量 (短文本): `list-grid-*`, `hierarchy-*` - -### 图标和插图资源 - -**图标 (Iconify):** -- 格式: `<集合>/<图标名>`, 如 `mdi/rocket-launch` -- 常用: `mdi/*`, `fa/*`, `bi/*` - -**插图 (unDraw):** -- 格式: 文件名 (不含 .svg), 如 `coding`, `team-work` -- 使用 `illus` 字段 - -### Infographic Syntax Guide - -#### 1. Structure -- **Entry**: `infographic ` -- **Blocks**: `data`, `theme`, `design` (optional) -- **Format**: Key-value pairs separated by spaces, 2-space indentation. -- **Arrays**: Object arrays use `-` (newline), simple arrays use inline values. - -#### 2. Data Block (`data`) -- `title`: Main title -- `desc`: Subtitle or description -- `items`: List of data items -- - `label`: Item title -- - `value`: Numerical value (required for Charts/Stats) -- - `desc`: Item description (optional) -- - `icon`: Icon name (e.g., `mdi/rocket-launch`) -- - `time`: Time label (Optional, for Roadmap/Sequence) -- - `children`: Nested items (ONLY for Tree/Mindmap/Sankey/SWOT) -- - `illus`: Illustration name (ONLY for Quadrant) - -#### 3. Theme Block (`theme`) -- `colorPrimary`: Main color (Hex) -- `colorBg`: Background color (Hex) -- `palette`: Color list (Space separated) -- `textColor`: Text color (Hex) -- `stylize`: Style effect configuration -- `type`: Style type (`rough`, `pattern`, `linear-gradient`, `radial-gradient`) - -#### 4. Stylize Examples -**Rough Style (Hand-drawn):** -```infographic -infographic list-row-simple-horizontal-arrow -theme - stylize rough -data - ... -``` - -**Gradient Style:** -```infographic -infographic chart-bar -theme - stylize linear-gradient -data - ... -``` - -### Examples - -#### Chart (Bar Chart) -infographic chart-bar -data - title Revenue Growth - desc Monthly revenue in 2024 - items - - label Jan - value 1200 - - label Feb - value 1500 - - label Mar - value 1800 - - -#### Comparison (Binary Comparison) -infographic compare-binary -data - title Advantages vs Disadvantages - desc Compare two aspects side by side - items - - label Advantages - children - - label Strong R&D - desc Leading technology and innovation capability - - label High customer loyalty - desc Repurchase rate over 60% - - label Disadvantages - children - - label Weak brand exposure - desc Insufficient marketing, low awareness - - label Narrow channel coverage - desc Limited online channels - -#### Comparison (SWOT) -infographic compare-swot -data - title Project SWOT - items - - label Strengths - children - - label Strong team - - label Innovative tech - - label Weaknesses - children - - label Limited budget - - label Opportunities - children - - label Emerging market - - label Threats - children - - label High competition - -#### Relationship (Sankey) -infographic relation-sankey -data - title Energy Flow - items - - label Solar - value 100 - children - - label Grid - value 60 - - label Battery - value 40 - - label Wind - value 80 - children - - label Grid - value 80 - -#### Quadrant (Importance vs Urgency) -infographic quadrant-quarter -data - title Task Management - items - - label Critical Bug - desc Fix immediately - illus mdi/bug - - label Feature Request - desc Plan for next sprint - illus mdi/star - -### Content Refinement Principles -1. **Brevity is King**: Infographics are visual. Keep text to a minimum. -2. **Title Limit**: Keep `label` (item titles) under 15 characters. -3. **Description Limit**: Keep `desc` (item descriptions) under 25 characters (approx. 2 lines). -4. **Impact**: Use strong verbs and nouns. Avoid filler words. - -### Output Rules -1. **Strict Syntax**: Follow the indentation and formatting rules exactly. -2. **No Explanations**: Output ONLY the syntax code block. -3. **Language**: Use the user's requested language for content. -""" - -import json - -USER_PROMPT_GENERATE_INFOGRAPHIC = """ -请分析以下文本内容,将其核心信息转换为 AntV Infographic 语法格式。 - ---- -**用户上下文信息:** -用户姓名: {user_name} -当前日期时间: {current_date_time_str} -用户语言: {user_language} ---- - -**文本内容:** -{long_text_content} - -请根据文本特点选择最合适的信息图模板,并输出规范的 infographic 语法。注意保持正确的缩进格式(两个空格)。 - -**视觉优化指南:** -- **要点化生成:** 信息图不是文章。请将内容转化为“关键词+短语”的形式,严禁生成长难句。 -- **标题限制:** 每个卡片的 `label`(标题)请控制在 **8个汉字**以内。 -- **描述限制:** 每个卡片的 `desc`(描述)请控制在 **15个汉字**以内,确保即使在小屏幕上也能完整显示。 -- **结构化思维:** 优先使用并列、递进或对比结构,使信息一目了然。 -""" - -# ================================================================= -# HTML 容器模板 -# ================================================================= - -HTML_WRAPPER_TEMPLATE = """ - - - - - - - - - -
- -
- - - -""" - -# ================================================================= -# CSS 样式模板 -# ================================================================= - -CSS_TEMPLATE_INFOGRAPHIC = """ -:root { - --ig-primary-color: #6366f1; - --ig-secondary-color: #8b5cf6; - --ig-tertiary-color: #10b981; - --ig-background-color: #f8fafc; - --ig-card-bg-color: #ffffff; - --ig-text-color: #1e293b; - --ig-muted-text-color: #64748b; - --ig-border-color: #e2e8f0; - --ig-header-gradient: linear-gradient(135deg, #6366f1, #8b5cf6); -} -.infographic-container-wrapper { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; - line-height: 1.6; - color: var(--ig-text-color); - height: 100%; - display: flex; - flex-direction: column; -} -.infographic-container-wrapper .header { - background: var(--ig-header-gradient); - color: white; - padding: 20px 24px; - text-align: center; -} -.infographic-container-wrapper .header h1 { - margin: 0; - font-size: 1.5em; - font-weight: 600; -} -.infographic-container-wrapper .user-context { - font-size: 0.8em; - color: var(--ig-muted-text-color); - background-color: #f1f5f9; - padding: 8px 16px; - display: flex; - justify-content: space-around; - flex-wrap: wrap; - border-bottom: 1px solid var(--ig-border-color); -} -.infographic-container-wrapper .content-area { - padding: 20px; - flex-grow: 1; -} -.infographic-container-wrapper .infographic-render-container { - border-radius: 8px; - padding: 16px; - min-height: 600px; - background: #fff; - overflow: visible; - transition: height 0.3s ease; -} -.infographic-render-container svg text { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif !important; -} -.infographic-render-container svg foreignObject { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif !important; - line-height: 1.3 !important; - overflow: visible !important; -} -/* 主标题样式 */ -.infographic-render-container svg foreignObject[data-element-type="title"] > * { - font-size: 1.3em !important; - font-weight: 800 !important; - line-height: 1.3 !important; - white-space: normal !important; - word-break: break-word !important; - display: -webkit-box !important; - -webkit-line-clamp: 2 !important; - -webkit-box-orient: vertical !important; - overflow: hidden !important; - text-overflow: ellipsis !important; - text-align: center !important; -} -/* 页面副标题样式 */ -.infographic-render-container svg foreignObject[data-element-type="desc"] > * { - font-size: 0.85em !important; - line-height: 1.3 !important; - white-space: nowrap !important; - overflow: hidden !important; - text-overflow: ellipsis !important; - text-align: center !important; - display: block !important; - color: var(--ig-muted-text-color) !important; -} -/* 卡片标题样式 */ -.infographic-render-container svg foreignObject[data-element-type="item-label"] > * { - font-size: 0.9em !important; - font-weight: 600 !important; - line-height: 1.3 !important; - white-space: normal !important; - word-break: break-word !important; - display: -webkit-box !important; - -webkit-line-clamp: 2 !important; - -webkit-box-orient: vertical !important; - overflow: hidden !important; - text-overflow: ellipsis !important; - padding-bottom: 2px !important; -} -/* 卡片描述文字 */ -.infographic-render-container svg foreignObject[data-element-type="item-desc"] > * { - font-size: 0.82em !important; - line-height: 1.3 !important; - white-space: normal !important; - display: -webkit-box !important; - -webkit-line-clamp: 2 !important; - -webkit-box-orient: vertical !important; - overflow: hidden !important; - text-overflow: ellipsis !important; -} -.infographic-container-wrapper .download-area { - text-align: center; - padding-top: 20px; - margin-top: 20px; - border-top: 1px solid var(--ig-border-color); -} -.infographic-container-wrapper .download-btn { - background-color: var(--ig-primary-color); - color: white; - border: none; - padding: 8px 16px; - border-radius: 6px; - font-size: 0.9em; - cursor: pointer; - transition: all 0.2s; - margin: 4px 6px; - display: inline-flex; - align-items: center; - gap: 6px; -} -.infographic-container-wrapper .download-btn.secondary { - background-color: var(--ig-secondary-color); -} -.infographic-container-wrapper .download-btn.tertiary { - background-color: var(--ig-tertiary-color); -} -.infographic-container-wrapper .download-btn:hover { - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(0,0,0,0.1); -} -.infographic-container-wrapper .footer { - text-align: center; - padding: 16px; - font-size: 0.8em; - color: var(--ig-muted-text-color); - background-color: #f8fafc; - border-top: 1px solid var(--ig-border-color); -} -.infographic-container-wrapper .error-message { - color: #dc2626; - background-color: #fef2f2; - border: 1px solid #fecaca; - padding: 16px; - border-radius: 8px; - text-align: center; -} -""" - -# ================================================================= -# HTML 内容模板 -# ================================================================= - -CONTENT_TEMPLATE_INFOGRAPHIC = """ -
- - -""" - -# ================================================================= -# JavaScript 渲染脚本 -# ================================================================= - -SCRIPT_TEMPLATE_INFOGRAPHIC = """ - - -""" - - -class Action: - class Valves(BaseModel): - SHOW_STATUS: bool = Field( - default=True, description="是否在聊天界面显示操作状态更新。" - ) - MODEL_ID: str = Field( - default="", - description="用于文本分析的内置LLM模型ID。如果为空,则使用当前对话的模型。", - ) - MIN_TEXT_LENGTH: int = Field( - default=100, - description="进行信息图分析所需的最小文本长度(字符数)。", - ) - CLEAR_PREVIOUS_HTML: bool = Field( - default=False, - description="是否强制清除旧的插件结果(如果为 True,则不合并,直接覆盖)。", - ) - MESSAGE_COUNT: int = Field( - default=1, - description="用于生成的最近消息数量。设置为1仅使用最后一条消息,更大值可包含更多上下文。", - ) - OUTPUT_MODE: str = Field( - default="image", - description="输出模式:'html' 为交互式HTML,'image' 将嵌入为Markdown图片(默认)。", - ) - SHOW_DEBUG_LOG: bool = Field( - default=False, - description="是否在浏览器控制台打印调试日志。", - ) - - def __init__(self): - self.valves = self.Valves() - self.weekday_map = { - "Monday": "星期一", - "Tuesday": "星期二", - "Wednesday": "星期三", - "Thursday": "星期四", - "Friday": "星期五", - "Saturday": "星期六", - "Sunday": "星期日", - } - - async def _get_user_context( - self, - __user__: Optional[Dict[str, Any]], - __event_call__: Optional[Callable[[Any], Awaitable[None]]] = None, - ) -> Dict[str, str]: - """安全提取用户上下文信息。""" - if isinstance(__user__, (list, tuple)): - user_data = __user__[0] if __user__ else {} - elif isinstance(__user__, dict): - user_data = __user__ - else: - user_data = {} - - user_id = user_data.get("id", "unknown_user") - user_name = user_data.get("name", "用户") - user_language = user_data.get("language", "zh-CN") - - if __event_call__: - try: - js_code = """ - return ( - localStorage.getItem('locale') || - localStorage.getItem('language') || - navigator.language || - 'zh-CN' - ); - """ - frontend_lang = await __event_call__( - {"type": "execute", "data": {"code": js_code}} - ) - if frontend_lang and isinstance(frontend_lang, str): - user_language = frontend_lang - except Exception as e: - pass - - return { - "user_id": user_id, - "user_name": user_name, - "user_language": user_language, - } - - def _get_chat_context( - self, body: dict, __metadata__: Optional[dict] = None - ) -> Dict[str, str]: - """ - 统一提取聊天上下文信息 (chat_id, message_id)。 - 优先从 body 中提取,其次从 metadata 中提取。 - """ - chat_id = "" - message_id = "" - - # 1. 尝试从 body 获取 - if isinstance(body, dict): - chat_id = body.get("chat_id", "") - message_id = body.get("id", "") # message_id 在 body 中通常是 id - - # 再次检查 body.metadata - if not chat_id or not message_id: - body_metadata = body.get("metadata", {}) - if isinstance(body_metadata, dict): - if not chat_id: - chat_id = body_metadata.get("chat_id", "") - if not message_id: - message_id = body_metadata.get("message_id", "") - - # 2. 尝试从 __metadata__ 获取 (作为补充) - if __metadata__ and isinstance(__metadata__, dict): - if not chat_id: - chat_id = __metadata__.get("chat_id", "") - if not message_id: - message_id = __metadata__.get("message_id", "") - - return { - "chat_id": str(chat_id).strip(), - "message_id": str(message_id).strip(), - } - - def _extract_infographic_syntax(self, llm_output: str) -> str: - """提取LLM输出中的infographic语法""" - # 1. 优先匹配 ```infographic - match = re.search(r"```infographic\s*(.*?)\s*```", llm_output, re.DOTALL) - if match: - return match.group(1).strip().replace("", "<\\/script>") - - # 2. 其次匹配 ```mermaid (有时 LLM 会混淆) - match = re.search(r"```mermaid\s*(.*?)\s*```", llm_output, re.DOTALL) - if match: - content = match.group(1).strip() - # 简单检查是否包含 infographic 关键字 - if "infographic" in content or "data" in content: - return content.replace("", "<\\/script>") - - # 3. 再次匹配通用 ``` (无语言标记) - match = re.search(r"```\s*(.*?)\s*```", llm_output, re.DOTALL) - if match: - content = match.group(1).strip() - # 简单的启发式检查 - if "infographic" in content or "data" in content: - return content.replace("", "<\\/script>") - - # 4. 兜底:如果看起来像直接输出了语法(以 infographic 或 list-grid 等开头) - cleaned_output = llm_output.strip() - first_line = cleaned_output.split("\n")[0].lower() - if ( - first_line.startswith("infographic") - or first_line.startswith("list-") - or first_line.startswith("tree-") - or first_line.startswith("mindmap") - ): - return cleaned_output.replace("", "<\\/script>") - - logger.warning("LLM输出未严格遵循预期格式,将整个输出作为语法处理。") - return cleaned_output.replace("", "<\\/script>") - - async def _emit_status(self, emitter, description: str, done: bool = False): - """发送状态更新事件""" - if self.valves.SHOW_STATUS and emitter: - await emitter( - {"type": "status", "data": {"description": description, "done": done}} - ) - - async def _emit_notification(self, emitter, content: str, ntype: str = "info"): - """发送通知事件 (info/success/warning/error)""" - if emitter: - await emitter( - {"type": "notification", "data": {"type": ntype, "content": content}} - ) - - async def _emit_debug_log(self, emitter, title: str, data: dict): - """在浏览器控制台打印结构化调试日志""" - if not self.valves.SHOW_DEBUG_LOG or not emitter: - return - - try: - js_code = f""" - (async function() {{ - console.group("🛠️ {title}"); - console.log({json.dumps(data, ensure_ascii=False)}); - console.groupEnd(); - }})(); - """ - - await emitter({"type": "execute", "data": {"code": js_code}}) - except Exception as e: - print(f"Error emitting debug log: {e}") - - def _remove_existing_html(self, content: str) -> str: - """移除内容中已有的插件生成 HTML 代码块""" - pattern = r"```html\s*[\s\S]*?```" - return re.sub(pattern, "", content).strip() - - def _extract_text_content(self, content) -> str: - """从消息内容中提取文本,支持多模态消息格式""" - if isinstance(content, str): - return content - elif isinstance(content, list): - # 多模态消息: [{"type": "text", "text": "..."}, {"type": "image_url", ...}] - text_parts = [] - for item in content: - if isinstance(item, dict) and item.get("type") == "text": - text_parts.append(item.get("text", "")) - elif isinstance(item, str): - text_parts.append(item) - return "\n".join(text_parts) - return str(content) if content else "" - - def _merge_html( - self, - existing_html_code: str, - new_content: str, - new_styles: str = "", - new_scripts: str = "", - user_language: str = "zh-CN", - ) -> str: - """将新内容合并到现有的 HTML 容器中,或者创建一个新的容器""" - if ( - "" in existing_html_code - and "" in existing_html_code - ): - base_html = existing_html_code - base_html = re.sub(r"^```html\s*", "", base_html) - base_html = re.sub(r"\s*```$", "", base_html) - else: - base_html = HTML_WRAPPER_TEMPLATE.replace("{user_language}", user_language) - - wrapped_content = f'
\n{new_content}\n
' - - if new_styles: - base_html = base_html.replace( - "/* STYLES_INSERTION_POINT */", - f"{new_styles}\n/* STYLES_INSERTION_POINT */", - ) - - base_html = base_html.replace( - "", - f"{wrapped_content}\n", - ) - - if new_scripts: - base_html = base_html.replace( - "", - f"{new_scripts}\n", - ) - - return base_html.strip() - - def _generate_image_js_code( - self, - unique_id: str, - chat_id: str, - message_id: str, - infographic_syntax: str, - ) -> str: - """生成前端 SVG 渲染和图片嵌入的 JavaScript 代码""" - - # 转义语法以便在 JS 中嵌入 - syntax_escaped = ( - infographic_syntax.replace("\\", "\\\\") - .replace("`", "\\`") - .replace("${", "\\${") - .replace("", "<\\/script>") - ) - - return f""" -(async function() {{ - const uniqueId = "{unique_id}"; - const chatId = "{chat_id}"; - const messageId = "{message_id}"; - const defaultWidth = 1100; - const defaultHeight = 500; - - // 自动检测聊天容器宽度以实现响应式尺寸 - let svgWidth = defaultWidth; - let svgHeight = defaultHeight; - const chatContainer = document.getElementById('chat-container'); - if (chatContainer) {{ - const containerWidth = chatContainer.clientWidth; - if (containerWidth > 100) {{ - // 使用容器宽度的 80%(右边留更多空间) - svgWidth = Math.floor(containerWidth * 0.8); - // 根据默认尺寸保持宽高比 - svgHeight = Math.floor(svgWidth * (defaultHeight / defaultWidth)); - console.log("[Infographic Image] 自动检测容器宽度:", containerWidth, "-> SVG:", svgWidth, "x", svgHeight); - }} - }} - - console.log("[Infographic Image] 开始渲染..."); - console.log("[Infographic Image] chatId:", chatId, "messageId:", messageId); - - try {{ - // 加载 AntV Infographic(如果未加载) - if (typeof AntVInfographic === 'undefined') {{ - console.log("[Infographic Image] 加载 AntV Infographic..."); - await new Promise((resolve, reject) => {{ - const script = document.createElement('script'); - script.src = 'https://registry.npmmirror.com/@antv/infographic/0.2.1/files/dist/infographic.min.js'; - script.onload = resolve; - script.onerror = reject; - document.head.appendChild(script); - }}); - }} - - const {{ Infographic }} = AntVInfographic; - - // 获取语法内容 - let syntaxContent = `{syntax_escaped}`; - console.log("[Infographic Image] 语法长度:", syntaxContent.length); - - // 清理语法:移除代码块标记 - const backtick = String.fromCharCode(96); - const prefix = backtick + backtick + backtick + 'infographic'; - const simplePrefix = backtick + backtick + backtick; - - if (syntaxContent.toLowerCase().startsWith(prefix)) {{ - syntaxContent = syntaxContent.substring(prefix.length).trim(); - }} else if (syntaxContent.startsWith(simplePrefix)) {{ - syntaxContent = syntaxContent.substring(simplePrefix.length).trim(); - }} - - if (syntaxContent.endsWith(simplePrefix)) {{ - syntaxContent = syntaxContent.substring(0, syntaxContent.length - simplePrefix.length).trim(); - }} - - // 修复语法:移除关键字后的冒号 - syntaxContent = syntaxContent.replace(/^(data|items|children|theme|config):/gm, '$1'); - syntaxContent = syntaxContent.replace(/(\\s)(children|items):/g, '$1$2'); - - // 确保 infographic 前缀 - if (!syntaxContent.trim().toLowerCase().startsWith('infographic')) {{ - const firstWord = syntaxContent.trim().split(/\\s+/)[0].toLowerCase(); - if (!['data', 'theme', 'design', 'items'].includes(firstWord)) {{ - syntaxContent = 'infographic ' + syntaxContent; - }} - }} - - // 模板映射 - const TEMPLATE_MAPPING = {{ - 'list-grid': 'list-grid-compact-card', - 'list-vertical': 'list-column-simple-vertical-arrow', - 'tree-vertical': 'hierarchy-tree-tech-style-capsule-item', - 'tree-horizontal': 'hierarchy-tree-lr-tech-style-capsule-item', - 'mindmap': 'hierarchy-mindmap-branch-gradient-capsule-item', - 'sequence-roadmap': 'sequence-roadmap-vertical-simple', - 'sequence-zigzag': 'sequence-horizontal-zigzag-simple', - 'sequence-horizontal': 'sequence-horizontal-zigzag-simple', - 'relation-sankey': 'relation-sankey-simple', - 'relation-circle': 'relation-circle-icon-badge', - 'compare-binary': 'compare-binary-horizontal-simple-vs', - 'compare-swot': 'compare-swot', - 'quadrant-quarter': 'quadrant-quarter-simple-card', - 'statistic-card': 'list-grid-compact-card', - 'chart-bar': 'chart-bar-plain-text', - 'chart-column': 'chart-column-simple', - 'chart-line': 'chart-line-plain-text', - 'chart-area': 'chart-area-simple', - 'chart-pie': 'chart-pie-plain-text', - 'chart-doughnut': 'chart-pie-donut-plain-text' - }}; - - for (const [key, value] of Object.entries(TEMPLATE_MAPPING)) {{ - const regex = new RegExp(`infographic\\\\s+${{key}}(?=\\\\s|$)`, 'i'); - if (regex.test(syntaxContent)) {{ - syntaxContent = syntaxContent.replace(regex, `infographic ${{value}}`); - break; - }} - }} - - // 创建离屏容器 - const container = document.createElement('div'); - container.id = 'infographic-offscreen-' + uniqueId; - container.style.cssText = 'position:absolute;left:-9999px;top:-9999px;width:' + svgWidth + 'px;height:' + svgHeight + 'px;background:#ffffff;'; - document.body.appendChild(container); - - // 创建信息图实例 - const instance = new Infographic({{ - container: '#' + container.id, - width: svgWidth, - height: svgHeight, - padding: 12, - }}); - - console.log("[Infographic Image] 渲染信息图..."); - instance.render(syntaxContent); - - // 等待渲染完成 - await new Promise(resolve => setTimeout(resolve, 2000)); - - // 获取 SVG 元素 - const svgEl = container.querySelector('svg'); - if (!svgEl) {{ - throw new Error('渲染后未找到 SVG 元素'); - }} - - // 获取实际尺寸 - const bbox = svgEl.getBoundingClientRect(); - const width = bbox.width || svgWidth; - const height = bbox.height || svgHeight; - - // 克隆并准备导出的 SVG - const clonedSvg = svgEl.cloneNode(true); - clonedSvg.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); - clonedSvg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); - clonedSvg.setAttribute('width', width); - clonedSvg.setAttribute('height', height); - - // 添加背景矩形 - const bgRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); - bgRect.setAttribute('width', '100%'); - bgRect.setAttribute('height', '100%'); - bgRect.setAttribute('fill', '#ffffff'); - clonedSvg.insertBefore(bgRect, clonedSvg.firstChild); - - // 序列化 SVG 为字符串 - const svgData = new XMLSerializer().serializeToString(clonedSvg); - - // 清理容器 - document.body.removeChild(container); - - // 使用 canvas 将 SVG 转换为 PNG 以提高兼容性 - console.log("[Infographic Image] 正在将 SVG 转换为 PNG..."); - const pngBlob = await new Promise((resolve, reject) => {{ - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - const scale = 2; // 更高分辨率以提高清晰度 - canvas.width = Math.round(width * scale); - canvas.height = Math.round(height * scale); - - // 填充白色背景 - ctx.fillStyle = '#ffffff'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.scale(scale, scale); - - const img = new Image(); - img.onload = () => {{ - ctx.drawImage(img, 0, 0, width, height); - canvas.toBlob((blob) => {{ - if (blob) {{ - resolve(blob); - }} else {{ - reject(new Error('Canvas toBlob 失败')); - }} - }}, 'image/png'); - }}; - img.onerror = (e) => reject(new Error('加载 SVG 图片失败: ' + e)); - img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgData))); - }}); - - const file = new File([pngBlob], `infographic-${{uniqueId}}.png`, {{ type: 'image/png' }}); - - // 上传文件到 OpenWebUI API - console.log("[Infographic Image] 上传 PNG 文件..."); - const token = localStorage.getItem("token"); - const formData = new FormData(); - formData.append('file', file); - - const uploadResponse = await fetch('/api/v1/files/', {{ - method: 'POST', - headers: {{ - 'Authorization': `Bearer ${{token}}` - }}, - body: formData - }}); - - if (!uploadResponse.ok) {{ - throw new Error(`上传失败: ${{uploadResponse.statusText}}`); - }} - - const fileData = await uploadResponse.json(); - const fileId = fileData.id; - const imageUrl = `/api/v1/files/${{fileId}}/content`; - - console.log("[Infographic Image] PNG 文件已上传, ID:", fileId); - - // 生成带文件 URL 的 markdown 图片 - const markdownImage = `![📊 信息图](${{imageUrl}})`; - - // 通过 API 更新消息 - if (chatId && messageId) {{ - - // 带重试逻辑的辅助函数 - const fetchWithRetry = async (url, options, retries = 3) => {{ - for (let i = 0; i < retries; i++) {{ - try {{ - const response = await fetch(url, options); - if (response.ok) return response; - if (i < retries - 1) {{ - console.log(`[Infographic Image] 重试 ${{i + 1}}/${{retries}} for ${{url}}`); - await new Promise(r => setTimeout(r, 1000 * (i + 1))); - }} - }} catch (e) {{ - if (i === retries - 1) throw e; - await new Promise(r => setTimeout(r, 1000 * (i + 1))); - }} - }} - return null; - }}; - - // 获取当前聊天数据 - const getResponse = await fetch(`/api/v1/chats/${{chatId}}`, {{ - method: "GET", - headers: {{ "Authorization": `Bearer ${{token}}` }} - }}); - - if (!getResponse.ok) {{ - throw new Error("获取聊天数据失败: " + getResponse.status); - }} - - const chatData = await getResponse.json(); - let updatedMessages = []; - let newContent = ""; - - if (chatData.chat && chatData.chat.messages) {{ - updatedMessages = chatData.chat.messages.map(m => {{ - if (m.id === messageId) {{ - const originalContent = m.content || ""; - // 移除已有的信息图图片 - const infographicPattern = /\\n*!\\[📊[^\\]]*\\]\\((?:data:image\\/[^)]+|(?:\\/api\\/v1\\/files\\/[^)]+))\\)/g; - let cleanedContent = originalContent.replace(infographicPattern, ""); - cleanedContent = cleanedContent.replace(/\\n{{3,}}/g, "\\n\\n").trim(); - // 追加新图片 - newContent = cleanedContent + "\\n\\n" + markdownImage; - - // 同时更新 history 对象 - if (chatData.chat.history && chatData.chat.history.messages) {{ - if (chatData.chat.history.messages[messageId]) {{ - chatData.chat.history.messages[messageId].content = newContent; - }} - }} - - return {{ ...m, content: newContent }}; - }} - return m; - }}); - }} - - if (!newContent) {{ - console.warn("[Infographic Image] 找不到要更新的消息"); - return; - }} - - // 尝试通过事件 API 更新前端显示 - try {{ - await fetch(`/api/v1/chats/${{chatId}}/messages/${{messageId}}/event`, {{ - method: "POST", - headers: {{ - "Content-Type": "application/json", - "Authorization": `Bearer ${{token}}` - }}, - body: JSON.stringify({{ - type: "chat:message", - data: {{ content: newContent }} - }}) - }}); - }} catch (eventErr) {{ - console.log("[Infographic Image] 事件 API 不可用,继续..."); - }} - - // 持久化到数据库 - const updatePayload = {{ - chat: {{ - ...chatData.chat, - messages: updatedMessages - }} - }}; - - const persistResponse = await fetchWithRetry(`/api/v1/chats/${{chatId}}`, {{ - method: "POST", - headers: {{ - "Content-Type": "application/json", - "Authorization": `Bearer ${{token}}` - }}, - body: JSON.stringify(updatePayload) - }}); - - if (persistResponse && persistResponse.ok) {{ - console.log("[Infographic Image] ✅ 消息持久化成功!"); - }} else {{ - console.error("[Infographic Image] ❌ 重试后消息持久化失败"); - }} - }} else {{ - console.warn("[Infographic Image] ⚠️ 缺少 chatId 或 messageId,无法持久化"); - }} - - }} catch (error) {{ - console.error("[Infographic Image] 错误:", error); - }} -}})(); -""" - - async def action( - self, - body: dict, - __user__: Optional[Dict[str, Any]] = None, - __event_emitter__: Optional[Any] = None, - __event_call__: Optional[Callable[[Any], Awaitable[None]]] = None, - __metadata__: Optional[dict] = None, - __request__: Optional[Request] = None, - ) -> Optional[dict]: - logger.info("Action: 信息图启动 (v1.4.0)") - - # 获取用户信息 - user_ctx = await self._get_user_context(__user__, __event_call__) - user_name = user_ctx["user_name"] - user_id = user_ctx["user_id"] - user_language = user_ctx["user_language"] - - # 获取当前时间 - now = datetime.now() - current_date_time_str = now.strftime("%Y年%m月%d日 %H:%M:%S") - current_weekday_en = now.strftime("%A") - current_weekday = self.weekday_map.get(current_weekday_en, current_weekday_en) - current_year = now.strftime("%Y") - - original_content = "" - try: - messages = body.get("messages", []) - if not messages: - raise ValueError("无法获取有效的用户消息内容。") - - # 根据 MESSAGE_COUNT 获取最近 N 条消息 - message_count = min(self.valves.MESSAGE_COUNT, len(messages)) - recent_messages = messages[-message_count:] - - # 聚合选中消息的内容,带标签 - aggregated_parts = [] - for i, msg in enumerate(recent_messages, 1): - text_content = self._extract_text_content(msg.get("content")) - if text_content: - role = msg.get("role", "unknown") - role_label = ( - "用户" - if role == "user" - else "助手" if role == "assistant" else role - ) - aggregated_parts.append(f"{text_content}") - - if not aggregated_parts: - raise ValueError("无法获取有效的用户消息内容。") - - original_content = "\n\n---\n\n".join(aggregated_parts) - - # 提取非HTML部分的文本 - parts = re.split(r"```html.*?```", original_content, flags=re.DOTALL) - long_text_content = "" - if parts: - for part in reversed(parts): - if part.strip(): - long_text_content = part.strip() - break - - if not long_text_content: - long_text_content = original_content.strip() - - # 检查文本长度 - if len(long_text_content) < self.valves.MIN_TEXT_LENGTH: - short_text_message = f"文本内容过短({len(long_text_content)}字符),无法进行有效分析。请提供至少{self.valves.MIN_TEXT_LENGTH}字符的文本。" - await self._emit_notification( - __event_emitter__, short_text_message, "warning" - ) - return { - "messages": [ - {"role": "assistant", "content": f"⚠️ {short_text_message}"} - ] - } - - await self._emit_notification( - __event_emitter__, "📊 信息图已启动,正在生成...", "info" - ) - await self._emit_status(__event_emitter__, "📊 信息图: 开始生成...", False) - - # 生成唯一ID - unique_id = f"id_{int(time.time() * 1000)}" - - # 构建提示词 - await self._emit_status( - __event_emitter__, "📊 信息图: 正在调用 AI 模型分析内容...", False - ) - formatted_user_prompt = USER_PROMPT_GENERATE_INFOGRAPHIC.format( - user_name=user_name, - current_date_time_str=current_date_time_str, - user_language=user_language, - long_text_content=long_text_content, - ) - - # 确定使用的模型 - target_model = self.valves.MODEL_ID - if not target_model: - target_model = body.get("model") - - llm_payload = { - "model": target_model, - "messages": [ - {"role": "system", "content": SYSTEM_PROMPT_INFOGRAPHIC_ASSISTANT}, - {"role": "user", "content": formatted_user_prompt}, - ], - "stream": False, - } - - user_obj = Users.get_user_by_id(user_id) - if not user_obj: - raise ValueError(f"无法获取用户对象,用户ID: {user_id}") - - llm_response = await generate_chat_completion( - __request__, llm_payload, user_obj - ) - - if ( - not llm_response - or "choices" not in llm_response - or not llm_response["choices"] - ): - raise ValueError("无效的 LLM 响应格式或为空。") - - await self._emit_status( - __event_emitter__, "📊 信息图: AI 分析完成,正在解析语法...", False - ) - - assistant_response_content = llm_response["choices"][0]["message"][ - "content" - ] - infographic_syntax = self._extract_infographic_syntax( - assistant_response_content - ) - - # 准备内容组件 - await self._emit_status( - __event_emitter__, "📊 信息图: 正在渲染图表...", False - ) - content_html = ( - CONTENT_TEMPLATE_INFOGRAPHIC.replace("{unique_id}", unique_id) - .replace("{user_name}", user_name) - .replace("{current_date_time_str}", current_date_time_str) - .replace("{current_year}", current_year) - .replace("{infographic_syntax}", infographic_syntax) - ) - - # 先替换占位符,然后将 {{ 转为 { 和 }} 转为 } - script_html = SCRIPT_TEMPLATE_INFOGRAPHIC.replace("{unique_id}", unique_id) - script_html = script_html.replace("{{", "{").replace("}}", "}") - - # 提取现有HTML(如果有) - existing_html_block = "" - match = re.search( - r"```html\s*([\s\S]*?)```", - original_content, - ) - if match: - existing_html_block = match.group(1) - - if self.valves.CLEAR_PREVIOUS_HTML: - original_content = self._remove_existing_html(original_content) - final_html = self._merge_html( - "", - content_html, - CSS_TEMPLATE_INFOGRAPHIC, - script_html, - user_language, - ) - else: - if existing_html_block: - original_content = self._remove_existing_html(original_content) - final_html = self._merge_html( - existing_html_block, - content_html, - CSS_TEMPLATE_INFOGRAPHIC, - script_html, - user_language, - ) - else: - final_html = self._merge_html( - "", - content_html, - CSS_TEMPLATE_INFOGRAPHIC, - script_html, - user_language, - ) - - # 检查输出模式 - if self.valves.OUTPUT_MODE == "image": - # 图片模式:使用 JavaScript 渲染并嵌入为 Markdown 图片 - chat_ctx = self._get_chat_context(body, __metadata__) - chat_id = chat_ctx["chat_id"] - message_id = chat_ctx["message_id"] - - await self._emit_status( - __event_emitter__, - "📊 信息图: 正在渲染图片...", - False, - ) - - if __event_call__: - js_code = self._generate_image_js_code( - unique_id=unique_id, - chat_id=chat_id, - message_id=message_id, - infographic_syntax=infographic_syntax, - ) - - await __event_call__( - { - "type": "execute", - "data": {"code": js_code}, - } - ) - - await self._emit_status( - __event_emitter__, "✅ 信息图: 图片生成完成!", True - ) - await self._emit_notification( - __event_emitter__, - f"📊 信息图图片已生成,{user_name}!", - "success", - ) - logger.info("信息图生成完成(图片模式)") - return body - - # HTML 模式(默认):嵌入为 HTML 块 - html_embed_tag = f"```html\n{final_html}\n```" - body["messages"][-1]["content"] = f"{original_content}\n\n{html_embed_tag}" - - await self._emit_status(__event_emitter__, "✅ 信息图: 生成完成!", True) - await self._emit_notification( - __event_emitter__, - f"📊 信息图已生成,{user_name}!", - "success", - ) - logger.info("信息图生成完成") - - except Exception as e: - error_message = f"信息图处理失败: {str(e)}" - logger.error(f"信息图错误: {error_message}", exc_info=True) - user_facing_error = f"抱歉,信息图在处理时遇到错误: {str(e)}。\n请检查Open WebUI后端日志获取更多详情。" - body["messages"][-1][ - "content" - ] = f"{original_content}\n\n❌ **错误:** {user_facing_error}" - - await self._emit_status(__event_emitter__, "❌ 信息图: 生成失败", True) - await self._emit_notification( - __event_emitter__, f"❌ 信息图生成失败, {user_name}!", "error" - ) - - return body diff --git a/plugins/actions/infographic/v1.6.0.md b/plugins/actions/infographic/v1.6.0.md new file mode 100644 index 0000000..94fd1ec --- /dev/null +++ b/plugins/actions/infographic/v1.6.0.md @@ -0,0 +1,14 @@ +# v1.6.0 Release Notes + +This release is a major upgrade introducing 12-language i18n support frameworks and full context dark/light mode sniffing backbones to prevent card inverse overlaps conflicts natively. + +## New Features +- **12-Language I18n Skeleton Framework**: Full structural fallback algorithms mapped onto global dictionary namespaces. +- **AI Prompt Strategy Optimization**: Enforced AI to strictly prevent colons induction and contain pure index metrics to streamline Charts visualizers nodes rendering loops. +- **Dagre Flow Layout View** (`relation-dagre`): visual pipeline supporting relationship visualizer pipelines trees. +- **Environment Theme Sniffer Context**: Smooth dark/light status conditioning automatically injected onto visual color palettes adaptation pipelines. + +## Capability & Validation Alignments +- **Fixes Issue #61**: Formatted parsing aligning index strict instructions forcing non-chart templates to bypass redundant variables. +- **Cascad Class Shifters**: Integrated child text self-destabilizers lifting SVG contrasts automatically inside container frameworks override pipelines. +- **Strict Data Nodes Layout mapping**: Enforced items index indexes limiting structural interpreting limits during adaptive operations. diff --git a/plugins/actions/infographic/v1.6.0_CN.md b/plugins/actions/infographic/v1.6.0_CN.md new file mode 100644 index 0000000..70e913b --- /dev/null +++ b/plugins/actions/infographic/v1.6.0_CN.md @@ -0,0 +1,15 @@ +# v1.6.0 版本发布说明 + +本版本是一次重磅升级,引入了完整的 12 语种标准 i18n(国际化)支持架构,并打通了全链路外壳多阶环境背景(Dark/Light 模式)降维检测,强效解决了由于浅色底卡片跟深色文字覆盖时的低对比度排斥问题。 + +## 新功能 +- **System Prompt 提示词策略优化**:在系统中严格强控禁止冒号、限制 title/desc 字数,百分百确保 `value` 字段仅由纯数字落座,有效解救数值渲染崩溃黑页。 +- **12 语种标准 i18n 翻译骨架**:对标 Mindmap 全量级翻译映射字典以及 variant 状态机转移降维 fallback 处理。 +- **Dagre 关系代数 flow 网络看板视图** (`relation-dagre`): 对应 PR #161 全链,支持有向节点、依赖连线关系的组件流向与骨骼动画渲染。 +- **外壳背景环境自动探测 (Theme Sniffing)**:智能嗅探外部明暗样式并在渲染板壳中追加 `.dark` 等级控制自适应穿透。 + +## 规则校准与对齐 +- **修复关联 Issue #61**:强制约束非图表类模板(如 `list-row`)在解析时将数据直接归拢至 `desc`/`label` 避免因不支持 `value` 导致数据丢失。 +- **内聚容器反转对比度**:添加子代文字 `color: currentcolor !important` 等联级状态,百分百确保渲染视图清可见。 +- **模板主索引映射表对撞规范**:明确对应 `list-*` $\rightarrow$ `lists`,强控解析抗崩。 +- **Palette 裸排严防崩键**:加强提示词,强制大模型在 theme 节中 palette 禁止掺入引号或逗号,避免样式崩坏。