From 7a6a55b53511c1c5fcbce0458f4a6fea6acc2c47 Mon Sep 17 00:00:00 2001 From: yinsx Date: Sat, 20 Dec 2025 15:26:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=20=E8=84=9A=E6=89=8B?= =?UTF-8?q?=E6=9E=B6UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 45 ++++++ lib/scaffold/config.js | 342 ++++++++++++++++++++++++----------------- lib/scaffold/index.js | 35 ++--- lib/scaffold/ui.js | 29 ++-- lib/utils/stepui.js | 54 ++++++- package.json | 2 +- xw_20251220142204.png | Bin 0 -> 35378 bytes 7 files changed, 313 insertions(+), 194 deletions(-) create mode 100644 Readme.md create mode 100644 xw_20251220142204.png diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..3dc7ddb --- /dev/null +++ b/Readme.md @@ -0,0 +1,45 @@ +# Zguiy Tool Box + +子归云工具箱 - 3D模型与纹理处理工具集 + +## 🚀 快速开始 + +### 安装 + +```bash +npm -g i @yinshuangxi/yinx-cli +``` + +### 使用 + +在控制台输入以下命令启动工具箱: + +```bash +yinx +``` + +启动后,你将看到一个交互式菜单,使用键盘方向键或数字键选择需要的工具,然后按照提示进行操作。 + +## ✨ 功能特性 + +- 🎨 **格式转换**: 支持多种3D模型格式之间的相互转换 +- 📦 **KTX2纹理压缩**: 将图片转换为KTX2格式,优化WebGL/Three.js应用性能 +- 🔧 **glTF扩展**: 为glTF模型添加KHR_texture_basisu扩展,支持高效纹理加载 +- 🗜️ **模型压缩**: 压缩glTF/GLB模型,减小文件体积 +- 🖼️ **图片批量处理**: 批量裁剪、缩放和转换图片文件 +- 📷 **Sprite图集**: 合并多个图片为Sprite图集 +- 📊 **LOD生成器**: 为3D模型生成多级细节 +- 🔊 **音频压缩**: 压缩音频文件,优化资源大小 +- 🛠️ **项目脚手架**: 快速创建项目模板,提高开发效率 + +## 📖 项目简介 + +Zguiy Tool Box 是一个功能强大的命令行工具集,专注于3D模型和纹理的处理、转换与优化。它提供了一系列实用工具,帮助开发者高效地处理游戏和3D应用开发中的资源文件。 + +## 📄 许可证 + +MIT License + +--- + +**你我皆牛马,生在人世间,终日奔波苦,一刻不得闲。** \ No newline at end of file diff --git a/lib/scaffold/config.js b/lib/scaffold/config.js index 83087fb..22e9d62 100644 --- a/lib/scaffold/config.js +++ b/lib/scaffold/config.js @@ -5,154 +5,212 @@ export const projectTypes = [ { name: "全栈", desc: "前后端一体化" }, ]; -// 三级菜单 - 具体框架 -export const frameworks = { +// 框架选项 +export const frameworkOptions = { 前端: [ - { name: "React", desc: "Vite + React", value: "react-vite" }, - { name: "Vue", desc: "Vite + Vue", value: "vue-vite" }, + { value: "vue", label: "Vue(Vite + Vue)" }, + { value: "react", label: "React(Vite + React)" }, ], 后端: [ - { name: "Bun", desc: "Bun运行时", value: "bun" }, - { name: "NestJS", desc: "企业级框架", value: "nestjs" }, - { name: "Express", desc: "Express Generator", value: "express" }, - { name: "Koa", desc: "Koa Generator", value: "koa" }, - { name: "Egg", desc: "阿里Egg.js", value: "egg" }, - { name: "Midway", desc: "阿里Midway", value: "midway" }, - { name: "Fastify", desc: "高性能框架", value: "fastify" }, - { name: "AdonisJS", desc: "全功能MVC", value: "adonisjs" }, + { value: "bun", label: "Bun(Bun运行时)" }, + { value: "node", label: "Node.js(Node运行时)" }, ], 全栈: [ - { name: "Next.js", desc: "React全栈框架", value: "nextjs" }, - { name: "Nuxt", desc: "Vue全栈框架", value: "nuxt" }, + { value: "nextjs", label: "Next.js(React全栈框架)" }, + { value: "nuxt", label: "Nuxt(Vue全栈框架)" }, ], }; -// 前端组件配置步骤 -export const frontendSteps = [ - { - name: "路由", - type: "select", - message: "选择路由方案", - options: [ - { value: "none", label: "不需要路由" }, - { value: "react-router", label: "React Router(React项目)" }, - { value: "vue-router", label: "Vue Router(Vue项目)" }, - ], - default: "none" - }, - { - name: "状态管理", - type: "select", - message: "选择状态管理方案", - options: [ - { value: "none", label: "不需要状态管理" }, - { value: "zustand", label: "Zustand(轻量级,React推荐)" }, - { value: "pinia", label: "Pinia(Vue官方推荐)" }, - { value: "redux", label: "Redux Toolkit(大型项目)" }, - { value: "mobx", label: "MobX(响应式状态管理)" }, - ], - default: "none" - }, - { - name: "HTTP请求", - type: "select", - message: "选择HTTP请求库", - options: [ - { value: "none", label: "不需要HTTP库" }, - { value: "axios", label: "Axios(功能全面,拦截器支持)" }, - { value: "ky", label: "Ky(轻量级,基于Fetch)" }, - { value: "ofetch", label: "ofetch(Nuxt团队出品)" }, - ], - default: "none" - }, - { - name: "UI组件库", - type: "select", - message: "选择UI组件库", - options: [ - { value: "none", label: "不需要UI库" }, - { value: "antd", label: "Ant Design(企业级,React)" }, - { value: "element-plus", label: "Element Plus(饿了么,Vue)" }, - { value: "arco", label: "Arco Design(字节跳动)" }, - { value: "naive-ui", label: "Naive UI(Vue3原生)" }, - { value: "shadcn", label: "shadcn/ui(可定制,React)" }, - ], - default: "none" - }, - { - name: "CSS方案", - type: "select", - message: "选择CSS方案", - options: [ - { value: "none", label: "原生CSS" }, - { value: "tailwind", label: "Tailwind CSS(原子化CSS)" }, - { value: "unocss", label: "UnoCSS(即时原子化)" }, - { value: "sass", label: "Sass/SCSS(预处理器)" }, - { value: "less", label: "Less(预处理器)" }, - { value: "styled", label: "Styled Components(CSS-in-JS)" }, - ], - default: "none" - }, - { - name: "工具库", - type: "multiselect", - message: "选择常用工具库", - options: [ - { value: "lodash", label: "Lodash(工具函数库)" }, - { value: "dayjs", label: "Day.js(日期处理)" }, - { value: "iconify", label: "Iconify(图标库)" }, - { value: "vueuse", label: "VueUse(Vue组合式工具)" }, - { value: "ahooks", label: "ahooks(React Hooks库)" }, - ], - default: [] - }, - { - name: "表单验证", - type: "select", - message: "选择表单验证方案", - options: [ - { value: "none", label: "不需要表单验证" }, - { value: "zod", label: "Zod(TypeScript优先)" }, - { value: "yup", label: "Yup(声明式验证)" }, - { value: "vee-validate", label: "VeeValidate(Vue专用)" }, - { value: "react-hook-form", label: "React Hook Form" }, - ], - default: "none" - }, - { - name: "国际化", - type: "select", - message: "选择国际化方案", - options: [ - { value: "none", label: "不需要国际化" }, - { value: "i18next", label: "i18next(通用方案)" }, - { value: "vue-i18n", label: "Vue I18n(Vue专用)" }, - ], - default: "none" - }, - { - name: "代码规范", - type: "multiselect", - message: "选择代码规范工具", - options: [ - { value: "eslint", label: "ESLint(代码检查)" }, - { value: "prettier", label: "Prettier(代码格式化)" }, - { value: "husky", label: "Husky(Git Hooks)" }, - { value: "lint-staged", label: "lint-staged(暂存区检查)" }, - { value: "commitlint", label: "Commitlint(提交信息规范)" }, - ], - default: [] - }, - { - name: "其他", - type: "multiselect", - message: "选择其他功能", - options: [ - { value: "mock", label: "Mock.js(模拟数据)" }, - { value: "pwa", label: "PWA支持" }, - { value: "storage", label: "持久化存储封装" }, - { value: "env", label: "环境变量配置" }, - ], - default: [] +const bunComponents = { + 框架: [ + { value: "normal", label: "原生" }, + { value: "elysia", label: "Elysia(官方亲儿子)" }, + { value: "hono", label: "Hono(轻量级)" }, + ] +}; + +const nodeComponents = { + 框架: [ + { value: "nestjs", label: "NestJS(企业级框架)" }, + { value: "express", label: "Express(Express Generator)" }, + { value: "koa", label: "Koa(Koa Generator)" }, + { value: "egg", label: "Egg(阿里Egg.js)" }, + { value: "midway", label: "Midway(阿里Midway)" }, + { value: "fastify", label: "Fastify(高性能框架)" }, + { value: "adonisjs", label: "AdonisJS(全功能MVC)" }, + ] +}; +//后端公共框架 +const backendCommonComponents = { + 数据库: [ + { value: "none", label: "不需要数据库" }, + { value: "mongoose", label: "MongoDB + Mongoose" }, + { value: "prisma", label: "Prisma(支持 MySQL / PostgreSQL / SQLite)" }, + { value: "typeorm", label: "TypeORM(支持 MySQL / PostgreSQL 等)" }, + ] +}; + + + +// 组件选项 - 按框架分类 +const reactComponents = { + 路由: [ + { value: "none", label: "不需要路由" }, + { value: "react-router", label: "React Router" }, + { value: "tanstack-router", label: "TanStack Router" }, + ], + 状态管理: [ + { value: "none", label: "不需要状态管理" }, + { value: "zustand", label: "Zustand(轻量级推荐)" }, + { value: "redux", label: "Redux Toolkit" }, + { value: "jotai", label: "Jotai(原子化)" }, + { value: "mobx", label: "MobX" }, + ], + UI组件库: [ + { value: "none", label: "不需要UI库" }, + { value: "antd", label: "Ant Design" }, + { value: "arco", label: "Arco Design" }, + { value: "shadcn", label: "shadcn/ui" }, + { value: "mui", label: "Material UI" }, + ], + 表单验证: [ + { value: "none", label: "不需要表单验证" }, + { value: "react-hook-form", label: "React Hook Form" }, + { value: "formik", label: "Formik" }, + { value: "zod", label: "Zod" }, + ], + 工具库: [ + { value: "ahooks", label: "ahooks(React Hooks库)" }, + { value: "lodash", label: "Lodash" }, + { value: "dayjs", label: "Day.js" }, + { value: "iconify", label: "Iconify图标" }, + ], + 国际化: [ + { value: "none", label: "不需要国际化" }, + { value: "i18next", label: "i18next" }, + ], +}; + +const vueComponents = { + 路由: [ + { value: "none", label: "不需要路由" }, + { value: "vue-router", label: "Vue Router" }, + ], + 状态管理: [ + { value: "none", label: "不需要状态管理" }, + { value: "pinia", label: "Pinia(官方推荐)" }, + ], + UI组件库: [ + { value: "none", label: "不需要UI库" }, + { value: "element-plus", label: "Element Plus" }, + { value: "naive-ui", label: "Naive UI" }, + { value: "arco-vue", label: "Arco Design Vue" }, + { value: "ant-design-vue", label: "Ant Design Vue" }, + ], + 表单验证: [ + { value: "none", label: "不需要表单验证" }, + { value: "vee-validate", label: "VeeValidate" }, + { value: "vuelidate", label: "Vuelidate" }, + { value: "zod", label: "Zod" }, + ], + 工具库: [ + { value: "vueuse", label: "VueUse(组合式工具)" }, + { value: "lodash", label: "Lodash" }, + { value: "dayjs", label: "Day.js" }, + { value: "iconify", label: "Iconify图标" }, + ], 国际化: [ + { value: "none", label: "不需要国际化" }, + { value: "vue-i18n", label: "Vue-i18n" }, + ], +}; + +// 通用组件(React和Vue共用) +const commonComponents = { + HTTP请求: [ + { value: "none", label: "不需要HTTP库" }, + { value: "axios", label: "Axios" }, + { value: "ky", label: "Ky(轻量级)" }, + { value: "ofetch", label: "ofetch" }, + ], + CSS方案: [ + { value: "none", label: "原生CSS" }, + { value: "tailwind", label: "Tailwind CSS" }, + { value: "unocss", label: "UnoCSS" }, + { value: "sass", label: "Sass/SCSS" }, + { value: "less", label: "Less" }, + ], + 代码规范: [ + { value: "eslint", label: "ESLint" }, + { value: "prettier", label: "Prettier" }, + { value: "husky", label: "Husky" }, + { value: "lint-staged", label: "lint-staged" }, + ], + 其他: [ + { value: "mock", label: "Mock.js" }, + { value: "pwa", label: "PWA支持" }, + { value: "storage", label: "持久化存储" }, + { value: "threejs", label: "3D集成(Three.js)" }, + { value: "babylonjs", label: "3D集成(Babylon.js)" }, + ], +}; + +// 根据框架获取组件配置 +export function getComponentsByFramework(framework) { + if (!framework || framework === "none") return {}; + + const isReact = ["react", "nextjs"].includes(framework); + const isVue = ["vue", "nuxt"].includes(framework); + const isBun = framework === "bun"; + const isNode = framework === "node"; + + if (isReact) { + return { ...reactComponents, ...commonComponents }; + } else if (isVue) { + return { ...vueComponents, ...commonComponents }; + } else if (isBun) { + return { ...bunComponents, ...backendCommonComponents }; + } else if (isNode) { + return { ...nodeComponents, ...backendCommonComponents }; } -]; + + return {}; +} + +// 获取默认框架 +function getDefaultFramework(projectType) { + const opts = frameworkOptions[projectType]; + return opts?.[0]?.value || "none"; +} + +// 生成前端/全栈项目的步骤配置 +export function generateSteps(projectType, selectedFramework) { + const defaultFramework = getDefaultFramework(projectType); + const framework = selectedFramework || defaultFramework; + + const steps = [ + { + name: "运行时", + type: "select", + message: "选择项目框架", + options: frameworkOptions[projectType] || [], + default: defaultFramework + } + ]; + + const components = getComponentsByFramework(framework); + const componentNames = Object.keys(components); + + componentNames.forEach(name => { + const isMulti = ["工具库", "代码规范", "其他"].includes(name); + const opts = components[name] || []; + steps.push({ + name, + type: isMulti ? "multiselect" : "select", + message: `选择${name}`, + options: opts, + default: isMulti ? [] : opts[0]?.value + }); + }); + + return steps; +} diff --git a/lib/scaffold/index.js b/lib/scaffold/index.js index 4bcb0ac..16e26ed 100644 --- a/lib/scaffold/index.js +++ b/lib/scaffold/index.js @@ -1,6 +1,6 @@ import color from "picocolors"; -import { projectTypes, frameworks } from "./config.js"; -import { gridSelect, createComponentUI, formatResults, waitKey, showPlaceholder } from "./ui.js"; +import { projectTypes } from "./config.js"; +import { gridSelect, createScaffoldUI, formatResults, waitKey } from "./ui.js"; export async function run() { while (true) { @@ -9,31 +9,16 @@ export async function run() { if (typeResult.action === "back") return "back"; const projectType = typeResult.item.name; - const frameworkList = frameworks[projectType]; - while (true) { - // 三级菜单 - 框架选择 - const frameworkResult = await gridSelect(frameworkList, `${projectType}项目 - 选择框架`); - if (frameworkResult.action === "back") break; + // 三级页面 - 框架+组件配置(合并) + const ui = createScaffoldUI(projectType); + const result = await ui.runInteractive(); - const framework = frameworkResult.item; - - if (projectType === "前端" || projectType === "全栈") { - // 组件配置 - const ui = createComponentUI(framework.name); - const result = await ui.runInteractive(); - - if (result) { - const summary = formatResults(result.results); - ui.showSummary(summary); - console.log(color.yellow("功能开发中,敬请期待...")); - await waitKey(); - } - } else { - // 后端暂无组件配置 - showPlaceholder(framework); - await waitKey(); - } + if (result) { + const summary = formatResults(result.steps, result.results); + ui.showSummary(summary); + console.log(color.yellow("功能开发中,敬请期待...")); + await waitKey(); } } } diff --git a/lib/scaffold/ui.js b/lib/scaffold/ui.js index 3c63809..65bdf27 100644 --- a/lib/scaffold/ui.js +++ b/lib/scaffold/ui.js @@ -1,7 +1,7 @@ import color from "picocolors"; import { initKeypress, onKey, stopKeypress } from "../keyboard.js"; import { createStepUI } from "../utils/stepui.js"; -import { frontendSteps } from "./config.js"; +import { frameworkOptions, generateSteps } from "./config.js"; function clearScreen() { process.stdout.write('\x1Bc'); @@ -103,24 +103,24 @@ export async function gridSelect(items, title) { }); } -// 创建组件配置UI -export function createComponentUI(frameworkName) { +// 创建框架+组件配置UI +export function createScaffoldUI(projectType) { return createStepUI({ - title: `${frameworkName} - 组件配置`, - getSteps: () => frontendSteps + title: `${projectType} - 项目配置`, + getSteps: () => generateSteps(projectType, null), + onStepChange: (framework) => generateSteps(projectType, framework) }); } // 解析配置结果 -export function formatResults(results) { - const stepNames = frontendSteps.map(s => s.name); +export function formatResults(steps, results) { const summary = []; results.forEach((val, i) => { if (Array.isArray(val) && val.length > 0) { - summary.push(`${stepNames[i]}: ${val.join(", ")}`); + summary.push(`${steps[i].name}: ${val.join(", ")}`); } else if (val && val !== "none") { - summary.push(`${stepNames[i]}: ${val}`); + summary.push(`${steps[i].name}: ${val}`); } }); @@ -139,14 +139,3 @@ export async function waitKey(message = "按任意键返回") { }); }); } - -// 显示占位信息 -export function showPlaceholder(framework) { - clearScreen(); - console.log(""); - console.log(color.bgGreen(color.black(" 配置完成 "))); - console.log(""); - console.log(color.cyan("框架: ") + framework.name); - console.log(""); - console.log(color.yellow("功能开发中,敬请期待...")); -} diff --git a/lib/utils/stepui.js b/lib/utils/stepui.js index a0779b5..61dade9 100644 --- a/lib/utils/stepui.js +++ b/lib/utils/stepui.js @@ -6,7 +6,7 @@ function clearScreen() { } export function createStepUI(options) { - const { title, getSteps } = options; + const { title, getSteps, onStepChange } = options; let steps = []; let results = []; @@ -19,16 +19,33 @@ export function createStepUI(options) { steps = typeof getSteps === "function" ? getSteps() : getSteps; results = steps.map(s => s.type === "multiselect" ? [...(s.default || [])] : s.default); completed = new Set(); + // 有默认值的步骤自动标记为已完成 + steps.forEach((s, i) => { + if (s.default && s.default !== "none" && (!Array.isArray(s.default) || s.default.length > 0)) { + completed.add(i); + } + }); currentStep = 0; currentOption = 0; resolved = false; } + function updateSteps(newSteps) { + steps = newSteps; + // 保留第一个步骤的结果,重置其他步骤为默认值 + const firstResult = results[0]; + results = steps.map((s, i) => { + if (i === 0) return firstResult; + return s.type === "multiselect" ? [...(s.default || [])] : s.default; + }); + if (currentStep >= steps.length) currentStep = steps.length - 1; + } + function renderNav() { const nav = steps.map((step, i) => { - if (completed.has(i)) return color.green("☑ " + step.name); + if (step.disabled) return color.dim("□ " + step.name); if (i === currentStep) return color.bgCyan(color.black(" " + step.name + " ")); - return color.dim("□ " + step.name); + return color.dim(step.name); }); return "← " + nav.join(" ") + " " + color.green("✓Submit") + " →"; } @@ -81,6 +98,20 @@ export function createStepUI(options) { console.log(renderOptions()); } + function findPrevStep(from) { + for (let i = from - 1; i >= 0; i--) { + if (!steps[i].disabled) return i; + } + return from; + } + + function findNextStep(from) { + for (let i = from + 1; i < steps.length; i++) { + if (!steps[i].disabled) return i; + } + return from; + } + function handleKey(key, resolve) { if (!key || resolved) return; @@ -89,11 +120,13 @@ export function createStepUI(options) { switch (key.name) { case "left": - if (currentStep > 0) { currentStep--; currentOption = 0; } + const prevStep = findPrevStep(currentStep); + if (prevStep !== currentStep) { currentStep = prevStep; currentOption = 0; } render(); break; case "right": - if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; } + const nextStep = findNextStep(currentStep); + if (nextStep !== currentStep) { currentStep = nextStep; currentOption = 0; } render(); break; case "up": @@ -120,6 +153,10 @@ export function createStepUI(options) { results[currentStep] = opt.value; } completed.add(currentStep); + if (onStepChange && currentStep === 0) { + const newSteps = onStepChange(results[0]); + if (newSteps) updateSteps(newSteps); + } render(); } break; @@ -127,7 +164,12 @@ export function createStepUI(options) { if (optCount && step.type === "select") { results[currentStep] = step.options[currentOption].value; completed.add(currentStep); - if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; } + if (onStepChange && currentStep === 0) { + const newSteps = onStepChange(results[0]); + if (newSteps) updateSteps(newSteps); + } + const next = findNextStep(currentStep); + if (next !== currentStep) { currentStep = next; currentOption = 0; } render(); } break; diff --git a/package.json b/package.json index 3253f8a..7589be9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@yinshuangxi/yinx-cli", - "version": "1.0.3", + "version": "1.0.4", "description": "子归云工具箱-你想要的都在这", "main": "dist/index.js", "type": "module", diff --git a/xw_20251220142204.png b/xw_20251220142204.png new file mode 100644 index 0000000000000000000000000000000000000000..5e0d91a3341f68031232f87a0481e3a2d4ec3873 GIT binary patch literal 35378 zcmeHw3s{u(*6$0bsH9}1R47ztRHjsBs0@s5Gj_R^?e0Q_GF~bxlL1kg5ttXRq@+}) zcx6m?V)^N0W&=7fctKQ@(acb}4EIqH<_66Dea~8J7zB6wIp=%!bIx;FD8deFef1~LpY==Hz8`VWTjIlwSpm;3jFpZu31`Vhmcx4r)Al(!^a zt;Ifjo_cTVStFm)w(;D>yd~2Y99~@cOV|H@@@h( zs>%v?l_oWcOpnTqk216K6IT`%M#^+4vdqea6B~8Q%f=`T?<+dqzkBy?qN(w9CQ5IP z%GNC$9-W|eEsuXIG=y6*oBvu|I@Ei>gI`bnOMm!>_xe}H+A`(V2M-^=^8+sl*QSk| zQ(+9by{M>p5o0}&ZGVOvvuQ-c+3%+3Abtw}!H#&2A1Jp-<)!MzUn&zC97TFZ zzII{S*@cFXrsmi*(c#o1%G#kJ1Iy2b2&Kh~pG-b;BQfawuEd!i>`a{b+l^uTV+#8Z ziVF(o1%+WD+qqEH)>1Uq;<%)B&WNuY8o#o&b#a?zr`ontb!xQA+md?cP5Fh>!JRMU z%43{oVj6cA-QH<6h4D+GZmo{`Jg_;gs432B&E_SrHtn6(nzmNPx?XM_kSkZFo>2PK zhRW(gd#?Wn{)zrv&NHs3OB2!_{ZV=}XI;#SvI{MOcRrXoA*g))#dSyPK7;=_TUQWj zRv0&Gts5Cyh{NHytJj;GL|ha7nd$lgtrWMQwq~jO7k75P5|dUR;B~#Gruo!bKj#g( z>rpu@=$zR+Mr#`LnOJ|0`P77|mE))Z8M@uHbj@14XtiqVtu7)s@C7 zILw+&cu|e_?*E5_T;>y2(fpRpuyL7qI;V^8!hPnO`|FGIssUB2}J5E#wrXC4wxOMCE@YJK>KDBr%XM@CzVZ13! zx;9qQx2AoD_M2GA+SpolbqH4%(i|W(1{Aa$K4HD9;XX?!Xd1?iPPe46;r^-DPg{>G z9FwAq0m83@T!XNA$D+e^>}I^M+6BVS1vU`VH|P``a3F;v=xj=5cS}w9Oegyb+~wP` zbCz9m|AXK6pfl`9azokQk5Akl5OZQ-<5gLr{Fz9RGk2ln-1g!dpadvo1Ga3cuH@DP zUdvjdMZ#Ra zhBd8>f(7S-w!mTDsHyoVHFamNKVmz1xcK;oM)2>Rce)N@9cRC^?}_jVLmWR)3xCx}M#H`e^0b4yx@3rEm!; zxs@l>juYm6Li@hio^yQk zwAsww_1?$NKKwN?-=)P-3^w-X#s?cek4{7>DSShHzI;&FTCy1a z69dwUgW4EFeqQyZCHjOe99-YDHg5YnIo665`@&a@`~y{O-U#rQufEHx3A{8;s5sTn)N9w@>1#p zS!1B|YIypaZhhw4V{|JCKPw~~D{AR)5fup(aW_qyqi%1u!b#3Y7(|RCX*9Q=Ib7lL1j#3FC|4$*nrIvrCT#GjnH!W5W^2wrv&HHGrw|vZ5}LsRNk+8!qdU0jk8z%oUs;4LD~wUK>}2@ zymB!CJ33(J5VaWtZYS+_j_g^&kPzp|5W`@-VKAe*o>lk=x)PVN;M3+O0C@2+Gqmk9 zoE;*5Jlcj>SyQY;268G}iN3W1_E#7{E^BOBNvz>@IH6raHrJ63vfzi}PR~QPbjhXh z6^2cE>n4WY4Qmu#;2)+X;6qJELL5h!G!WiV40sR1lYF0$j#(ik$qs}shO8C;8QKw8 zeTddLLVFT!P7f+rIwz&Nq^F-T=78#Ru04kT22Z1z>@SJ~H%i|=Q-7wWCK&t*_JX>i zd`4L28>O#RSPv*`nzw{ZY#5--Z5pSxDGNI7nTC1#_DAma30-bVWs^f<)QX=RUkIDE zchI#Vw}BfEhP`IJBNB}YU5MkjqRh`c5Tpu25cUvZGis;}J@8jvd4=2nrcGs@S!0gW zZU$GQ$dang;h*dFZH8s_C3!-1Mf-?AR@8E$$S;HTLi!EXBwcnVPqslR-Knhe=MDbS z1flb^@FD_`8P}(JMrI0SzxKE9@vpxsbX_fQw4JbB331ITG6t!?%1OVG(}b>HzV=PI z{jGSoh#kK6Fa2!~GUaliCfRXX=$sng^mhDOP#N@tb|P9eix98wzc7#|XCI4$AQ4;_ z*{Xx+O`u4B0C)-C@2U6VsRo4sT^T{+6aIA=JV@u&ST}07Wx@}fx3als_#ra|x86>g zscI_INSdO{t(?fYD5`NfyR%yIfWlhuUmqE-e?V`uSD13eiIMt_b>XISi?VMGD=jdz zYa6t8rmNeh|B)x6=33OvHnOnbJ-{b)jpsL$UUUU2=t(fD_UY=E{a0LG?RNPIE^oI9o5FbPg;glZU{b8P)!68sKyQYw%@@gNo{c zetQ3q74N9cVhrJpX*Ig^;Gm!&LLH3;;fwrl!DYGYhTMpuBsndlq^U)^)FryzDQ*uP zF$32L@Dx%^pGN8VuXje*7zSy-1YA}3snvjaK#O@6VUIB&D5O;?(}Oe`!X7}V+wd1@ z{n0z?SKO-9miv*r%7Dx0?9b3!(cdv@o6z62qNtDyOxhtMRi~H%AbblgG&Zsl4*g!- z5bIJtX^p*JUEQPuUq}ML^$AIhPDdhyeSYNRNCc0*K>N)ZDCn9-#OyH#@3wu`S=<2HM9aKn^&@mc@L#0vT;yfV@V7EDhmzfiqVW-I zE8Bh`yB-~3>6EDYkx{EC02`z=46=b|HH`wXz-F?r7~RH$vEB}+B)gR<`y6-gOtD|j zcD+mRq3c8mOuJhud%lMN%;^w5u%aL*bz*kIIrZ7B!s}VaVPfMjf$Me*Mdme0lan*nJS@1Jp3V1dvzLX`idx8j z*yC@1JbqhVRLA#(0pzh`T7~>fH@ZVW#1sb=UI{XS#%BtYr2cqjR@^1o0`P6*cbj*L z_qR;qMy6k?NE^hE4O5pKSx}n4^!7tN_T*Bmj&Ey>?lfYT3+4%lwOpi!^ z+ZSB&@(gFOzmqv};)Lp%vq_Dem0}(GPTJdD&kvor{O%(;W9QWONIvk(4mg8a+uBTc z_$t8q7s2lhD@Q-rjN9xHLUsj{YOgJ99(g=?e+4}0drMgr9e{{I&jvz`MVGH{BV#`AkpC zozRD$@!8RM1ulfMysxPE;OQPmHm4&bqgK6b@k^VNhTi}vqSRqsc$^X{O#%)KK9rp-uQq@S|F|L~Ej z{_&>i{5p^iO*@2y|LFY+UNP%mZaw)o1U8F>#_uLb?#O%HGVYEa@D{guID0$1?h~zvV|GajluRu?;%ZTotH8E9N*?%8 z%REK#?<3>4=cQNr8ZY}>hcRuAOJW^s;PuYf?0)T$L)b zwMY`eY~Qh`edai`J9~wL2=(*&f%6X9>jvjKOP#Hu zMGsq2Zz@$nOC=t$wh13gyT)@SX=wK;TB}=*SJgPWXbc}TD6p*&Wka$@?K+cFzY=dK zQGF=0(EC2s;NN(Q^Qkrl$jjCWZIE@&lwDRH?f5a4_CMRvFXYtvoK!#B!tbZ!S1yXT zxC*p0#Fp(n6a~_ZQOl&VfUZhB)op_?zzqY(T2clC2H%$ zHrFw6{S~=0>j7Ot!vK+en7|&uZsOX5h48}Dx*r`C>N8n)P#u;0xjgeJk}w;II2}xH zbY3xJmM!EX^OUfX#JZX5l9eycJ|38HdZBX=?!H#^t6cR}G;0bo39o5o_0vIY?8|=% z?i}cxP9lpp8rY25g&HSLGKR@Eq2x>F%~VyzCDu39tkUW5uNjhr9!3W3fson4&kf`n zL-P%x!jtN^S^F?%-E_-KZ8cL_(`(&N@U>UQq&*vKpQ0_t+hq@~&f^}9acs5d`gZTi zrv0?4FthH|?)E%!o$Yo^&AEL-Tc8)BPL~Q~vBu;oZlt{2oQxvud(#61_v`f*(CY}> z8{$$FAi-tYw&F;~=dmBb8;rjew&x`@7a%|^K;5JjWpme$&9QL7~d+9HaLyMsdik#E<7Ve^uA@^{i1kuN%+q!+uo1mG;fyOC&8Kugh}PkPMQ` z0vGCdg`|%I|i?E!MJNtyIuj+gfQI|=n zOJmZ;^21KAjj-YQa-(pq_aDX}IE)i`JE(YEq&*-!5%kxm_DosPL`&)|-}H!vw#X{S zBJCMGZxF)t2N4oBsT+d;h|~SJ&TVSS7D35~j2FJ6@|v=L|W;4-6!IE9PLfu2dbrEuJb`s83>2zRtz^Sewzo^?=!I-VnCwvC*S11 z$V)GCBonqWfqcC#A8nMQy8RXT*?Yj+X8BrV4`&E4*v+_g@7gPJYclGT+khda=Nd}H z7ZQzQNuvu!2yEFsj^{FWRSf9i!1WNOCp&s!2pyywyQQZB)z6~f?IFEXpGJl6eT**ky89RN-}8~)itj^fzfZxz zhYj8Pf6BS*?aZNp{g3^{|A!yRuXW2*7Afz2YI~5I^M~&BD*ju->QA(tQ=HLOlqmFT z?mvbO;jk_ID7Tu_&5YmHQez#7&=Hc+ZG&8B6Ev=wMZZ=iAs&--B$MNWju|Js6*c9| z>Jt0uulZ-1wyZgvc{{IX4V0WS?=Aea1X-R&cc!ecZ`g)_Fv~D>pyy6V2_oA)O5HAI z@)0n&GlQ!1=q-E}d3Pw2uMb!6Mia_6>{@dp&)4?qBkECJ2lP+Xk6ODa`Mszsjq=Hk z0JHY{qRn&r6$RatZ}WXl@l^ZVkJ(S1OYZ~R;Lk6pf89QA;e^!A=lS>UQ*Z=#?$BVl zF}yug+{hj^4P5nTBa}l;ukBUsHxyo$Rou$|JbJz4g`Y!%#u~KyU5BrXxt#l1?#|!` zn#QjcukBoF4yn7iecZ0d)UCa5h>Zk(#KQ7jb)%uKC`IxD)_2YFI)qfF3SDT#Jj4OU zfboFay+!QN>ADdOElaX#sCKIZ9MOLYlYID{XQr=8`PQ}G>+|TO8-|Vnfy@J;Q%W=Z zoXQ=to6cBiX-Zmj4J7J!Y8)y}LpFCSyH`wikc-`CQW$J<-nMJfvJI445murzZ+|n~ zTtz_SB7y66U~TA(Cm9-r&HI(Mm)pX3sdu-1sNLmuu-!h2aDA}1aqbmag`n(x=FFfk z1M};>t=^hn(^oN%s4rG29DTfAkZqUlfnzQD3T`a$rea%X=zi7L2lUUH#7_j5e0Wu{ z&HkGAT$y_H<;9vK-Vubz#v4$2H5t9g!uj-$S-KXU6>OQpCq!0 z6gVhO$oLNF?T_>C_X*pJIe})#A~c(U2SbHWZrmVU!UDkj)3!>tNf-kTCAnWHr+LD3 zKaz6r2b_&J!R*=i@FVn-76-H6H5sI6v&B zeh2;7rkn&a3W=|fGMiav`$A)VfRfYq3D%hB!d77}T!(o?FYDeg`;)nqn29ou5}8Ih zqi?t>Mc;wRV$g<@a=9b6NVRiWm7ZdS&pgh%(`C1{iRuVheX^J2 ze3&aJ_?9P-)3IMm`hKN+3`)nJu=CSCzOeIi(+*G)*xP=2`0QHIVrS8r7~M<4A$L+Y zm^PeJF4-<#-5IgJXrH05Hg07_<9p7f+j0|_I}rndFDApctO20Uk{25B#F|AdnBlZF z#&93Rf2py4p{d1MOz)V5i`{E_5^6hEKP-1WoB@R^ZC!y2$TEZYuP8n`9?tbgw4;y; zL;Od_Rt+ddzjLdw??b+5PMtMlniuF_^uuze(H}3Gq4ygKr_Hmz+B94n{ z7&jrQz7M7=FS1+77eepMClW*I&@|&tD8r+FiLr)c9wh?EL!s;d7tt6nLpsW9zv}(s z$8O5E2maHw{u9=_Bl26-*PjPwI#YAQ#;nO{Ub{X}C)DgDru~ z;-c+DYuPNcZNBeNE8tL}&TStl1M0~xOPa>g2xOe2Hsr`~<1iMLV3dcBjJfLUbc+f7 zWWi<1erPZ0+imWQNOvS%5QzyD?zc+_=a}rM5A{~`Y1;CtV4!Jzao^mluh)8Oa$f2C z2s5V7wz8S44)@hw@OwKxmT43|vUmgk*P@-HHevybab;VJ`o?zbiuwAq%+BD8vSF5<1}MBO5UaX>;t>_p7x|R}Ucl?)K1x zQyc+rYG40G`S8WZ`I`bI*Wms8m&(U}-_!79{6p_fbp#~e$i2M!TgPAPQl}^<*L=Ek z_HW8{VCh^S#~G5>ziqh8ooUogm5z#ks%hhzP08C6>VC4%^e$HZ#S!2Gmg3I)zlA?^ zeAv6m?{TZot97DQrL09MIX5-Oz_limC=l)12IV20}2&!V-R5zV5J@ekFXtY3*gTUQqY5DuTd z5VYR(M!n4D->j{_d*djqIc>mwNIT$G6S$tvGoevm@dIh4S$8}s0RcqceKSzJ(di9r zZX8`W0s}j5!_Q*JD>OD7|?#_pC>NI)sBy^7GM6x;VP<*U?6O$17s< zE2=ZoRedzARFykav0@AtNp;b~di!B#43Yt{qEfzV;_0_Fw~xiQ9Fx$84q}xI3!Sj0 z#B1#Ca9KlmGub`Ok3GJ_554y~dEFds#~kVU9LWG~T#v6C*prJ2e_v$8oduR)wabhz zS3v=NG&-GKSjlDXHL+)KZ>z&4KJnXtIv3;mEylQ4@?GqTQNR%yP<#T4?n~4WdevsK zr+uN)E)B{xeUoQEYKwCbY`X9vWJpT(V9|&OoCR~B>QA+lA9Ni^H^w@G00?glGWdg{ zZ!y&J^oBPS?QiUwkhF?EC~6oLUq4EM8;RfM7dX~HRho{F7CfGOS7#-ix(ogg@8`Dc zTjFnTL5qpy!;5cgw75wm9m$|L{3ZV}zNlnlc+ELK6D<^2H6!@1@wTzdmjiFA#adtf zowad?-l1wUUNtiT?p|!@CoVRdOIc?rF50IS9C+Zn8{t>3O$kEn-G%Y+6&SztT)Q(S5exHZ=mbilb`;!`vU&7Aoep^>z(!?Hv6-YN zP~sH`kv#&ZV+-I$yUxp<143u+szm{^0*h%xn+2=37>NZof~gWHfexl_Kp~LKQlS*% zr#*@h@ONA6&6_vtYil$3XX4`Gh7TWZ(AJ?p!AN>(fS~=ELS=%= z_!@Cii0}_YNAE<~n28|n8CnO)I(v{HNr~95t;1-KaL!}b`Th`s!`-UNTU3K}8o3Um zCYxnN`@WD%(~BCXo3OlHl~g)Hb%1CVz$x&?t_fr{cpX3Jr>v)Nes?pN#9Q^XFY zcy~(8dBQmPyd&=>N+joiN8#VzjYD+rsGBHBKGZ)RcKNm_W`&-g91L>nF~X6P-7K z(r`#?A2WFHVCMSGoAY7miHXJhM?jBcPX?(@1~J61>{c7bZ6$V1I7xh~Fv?cbrgWIbw$$~F92k;|66lJ~{Bodwfz-cn=(vNsP2q&t?yH(EMBuJy<=rZPz$%NF$9R+s> zm?a4(T3_Kt;_VCShh*0x4c10fqx^=!&}INe=Ye7}ImY^F^jhDW*RRhlm~EO245a6C zrgNhR&e43DJeH&Z=}=)E{|GBVE9*t73-pN<-^JGBExK(5iGc44gza3p$L@Ne4I;{K z^|Fd1v&R-_yHT7W7)M(Jj)(a4{3Er<=(p*YAUPOqQTKgG@R>mRlAa34EheVb{IJgX z?&H7aIWup=YFM~4x?9hJZ($yR%rC1<8tyeg=A7W`>&pNlqIkGSH4eArcl;hFy|^HF z>Y*(_X~}gqhML!e3cNDV;`W1UK!yPlh|qaLa}|6G4+BkK0d!L^?~cu>T2?WK7IV*L z9)0(DCf{5hVZ*2%#L`-UxQPebzZfrg$+e@qCnm2WMVPzeY2+f|v(dLRR?+551Xui`NimXx<^gUti*5#5J>~&}&oL%vI!PHMd;sxr z@fEX^2QffNKGAkOi|}Te@hk{Fu!SDV=sxs(ElHx2NGJ!dZD7xL0kUKdnKqBX@%y`U z2mo~9u!x8VqOhh^CHeA0aMP%h@w#R4nMAZfkSb`{6k*jP7SZXG2etB*@NioW9iZDT zqD#BPBQEGV7!8@iT_y8R;`Y&5O+pC6-Y`-+wAK6w6ayseCV`6#5m!W8ZTI^W?Y(yg zsDyS&ASCeisrGmiVdp%S=BL?X$tOZj7xBa3F~Dem`qpCK6Le_3#E-!4GsN_GB#dMJ zgxmx&(m*jo?oD8bNUVk3d802kGy}{8f+@1SAxZjko)=wH!Ow>0gBvp}BS*SDrw)+=+qz&GO)@Z%kXHfOBnR!~8C5G< z4*mRlK4=&*7q46yLV%}kM3R%2+morJ<)HmUpWFR)H0(WjQ2a^AR>e1e7{4w^3`N|E zv`ZC@1(EnlbVRK=gy)14Q|Jz{XQD~F2x$L%2}pp=n^ofW^lk5r&2h#RVuVC=_wVI) zDBMDu8$;2FB^6PML1};<7}-YX$JzvjcS-%30lDq}4D~YnGc&+e=o0}X7ofRH|0 zjfUr|tXVOd1)^UW7+?Q(qy)MHgYK9G?-=hEq5zBEK_Az#c=2K*unf1(PN`l->a>!KJ*f?bg{U9I&qXIyMB79LEXfCgX#AIS zOg1TY$WSnVF$B6&7@W9)8Y5-$<5o2U%2gt;zuYs!sn2HT1AZlNctBMY^m*o4L70*(aR98}rKRru2 z1h*Ou7Mh`srh?t*-IoAqmU!d|h|nNe*cj!E2DuYlPK#QIHkup@Fh>)lrl)Y%{4DY< zpaW4|N4+KIC}u`kLv4e!cvmFjcB8$z#0wGXGFcMx?I@P2M2m#SRE0u;2*8cR<^iV) z(H$%RnF<+!4>VuEH2v}msdh2Uy|ka?hzAB%^U-3qg3JOCW=_q@YhNf|n<4$JYVG(RHDcqN&BMC4>=Y97-8JVKUts zNGQq-{Ehmwx|9S3AB`;GJVDd5&gpJf7IOd$WrFZqUd5zCs5|b+OzO7(sI`&=Ix>() z>}l&u{SFNF_T?Z09s2^1&g`UQ0cLO56CSVXo)7CHGvl$JZl~@Y$}E70lLv1GZ|dDc z?^NkAA||)W%L*+~5e#Ka93Dri7Tdni&El^TY@p;5cOAvfBhv8?E6kG==xl=e?m5=4 z7(02C`T8OUxmd|3;J>UE%9!Ebp!=392iN1%WA*pUhC2Z4SBr*5x`&*tGwTDKF_ua2 zaB#u#GTvXr;JLErXM|UuQJdXVp%zAdJLXbK zvH}aV6x5O3K+gy5-?U@zK2MIdC#nR>Q{WX;w1yB~LQvlAws~SpH2I= zKH3SemX@kyfB&E1!p7#PULZ^+4WI1MEy^j(>vpWV(>u0_o&*+1lNEY7KFqE3xMP&Y z3&?PLi-dQO?{iz1>!nd!A?HH|MSTr(S$IOUdN>kqOh014fDRpYd2olo5s6=qy|Q!& zfP>8N;9%2aF!G_1w_mT)yE7$})(pSl&ZFpnY3%m;QJ)zJhS`)a!A1jIl!*cc#20M( zn~ZRSeb)PTCe)*muyr-7&=o=i;*6GJmXbc)WtzM(*7g}Q%nw}!<7D&)E~?Mcu7uTi zve>W(x;h;%o%!+Du@X!maHFzi?fbki(2&j|6RXkSnYmHk8HYxN&}vXk?H~+Pz|$qw zVE3(F?L%VZD8!y#f0PwiC76pzt z_%k^WI#QV7j%&MxirK=h#WncUVsIRdZ%Bx2EW5fo`4s=-B&Sl)of+Lt9&* z?aGfzkjjAm1E(Y{qkO1$#-hUo>!9~4o63xkE@C&9%m+w>D8z^+hJK7l1N>V+ZGuV+ z#uzvbisnv{bEwhKf+qu@lXIe`u;PUo0g%1PJ9ZWh5poJ2?0A~KG8ux~u(J?U`W6Ft z^dYyT&4QXe?~z-MTvTstjRy7Io+EvfgSdYK8WDsW@^9e;KY)F{AlJCFC=fq#E6Ho3 z+B0;Lym#mw=9_;|2NE|Pl$PmEW_IUQ+@1saMHkTudjAN$>bOIG8TjmszC4Jy0fO_O*L)W{yUgpl|xf80jzsHH2Pz|)04gxb1Q@0Ytu_nXU?n&JFVF<#& zI><8dZ_#R!BLK=#;V4=2#ft0XwJe?2dujL zycl;T7VJBkAxQ#SdKBd@Z{35sl>WB5w0t_HgS&kRNdjeE%v9}gXGSo?&JQD#kC`O& z^1aEM7TkV4rXDl5;2;N*BJo3UeZG`Ky$8^XXh}2#0#7>LbxpJzLw;-*ZM0E<%Z+y% zoJk(=^@Pw|Xg4%190GtCW%M$>j`|QA|Ty>xuttl%F2`)uB zwu-tl6XaI#TJ&+~9P9kq2_&!(8b2E&9f*luM6zs1?^t0T!)RD7gU7)j#$~h421+QY zOS?=L;aQ}m>a>djIP{zLk|%&#?L+CMUEm^vjo_y!$-%jI9ewsKstUifi3&4S9k6$oIl-c??H9**^bQo7nGhb?8@C=_!`O z_C7SUnEt@5X%-zKmb2(+R(hNoh(5UDH36CluzyQoX{M0F-qwtMbvRz0c> z*%a+v5|mk#V9{Clfng-bZ2GRliew| z9w}8HdYOMa`OndlCQb6L#q z`2@FBr>#k5VS*O_cfT8jb3<@M2U!A)Bmx^f`;y4Wuc0jav}N!akC7DuS>5N}-(eaR zvAUnTTp4CVZz}i}daICU!&pz#+MNJkKq&}%)Ym-jmN%9N7(A|_88FmBW)KvGcBWt9G?w9c;c)P+a{VqLobW>*jm)#%_apyu`L*L$1y`NO6$>ig?Wy;Fy5 z>HPyp?%MUy*q(>&R`>qFIsSa)z2o3z|Jhj%afSm2Ejh&X5GP!Z&Lpjl&rQL^KY@cHg$p*|+B6!XYfi>iDLPL-lSd-{<{L;m=@!U5){#lOq`rafov6HGNNSE_{W9DgOwqEcn4ga8&R2E%$j^W#57;Hy z9^RBBcT7?}Lw!{M7*JHMRlRsNJ9C>3-u{pnz-_) z+LEq%f$rCA{?fuf9sKd6{9-&ONYaBvCGGU!e8WnzjCc-LPxhsoy;d00gyQa8=r$zh z@>4dUm8jR&d%(_&0#mLkcXA}U;j8br(jj1_2>}ssrFgsHYI7jr9Q9nw z+--{+=@l#g6$Wfwt3dT<3?4}Z@<~_6#ym6?m9pB+R(YGpcwa}g!KX75%#-wfh(%F& zP{woFj@L=m5Z37EdXcl|bf|}K37k?rsRYjlg+f}TD;i8b32ss{i@5UGJIUX`!|IpO z4Oc*C#`f9;LbLLoSuD7uNPmQ`Lj3_)X0XMe6Xn}0Bq{Mr6$@WZ?e4cc-y@6bdq zBor96?onA-2$pp&WVd1)i!(J1=xHx9m~p%0lm2UH`a@#V)8bQkX&3SgIQ~*_S(#R* zB(6-|h?C^Z_fwS^jE*yI1pD-bBLD%7VI2mevU zrMGjV%c@nMTo7!21cnAit*60!_!cViabqwcMZH-#Rm%xe7+=B4Ei^b;9|$&YD+SK! zcky?=lWY!`1_Zb7@ipp+Vnl`3koGAdXObP&FfNe6-rh~V7+vE;QOdz5J8&8gu?unH zU2OrCQt50~2e&`Yjm9J#UCN8u(g*l=FighLYE~GUH;V2IGvqL@IjtXM{`7`_0Ci1u zey3^x4hEAED~b*{15oIF*{}r(=hL1U8GO>G5ZRCnBx2a}$qpDt zyn@RkMqm_>f49>YjM=P!ABH6)WOC+fN#Jtf1*)2s!eC5V+T?d|yL7bo-`EBATdc6c zb#ywRVlzR+cZf7DYPO^1vvk;<4RSRzxkEV8kpb#ef%_Ft!vVv=_RFBO$>^f`(Zuwn z6U5QC4DP|SS$>f&9m~do%Tz(eFVf&L1}{RxJ2f_7Iz2=}6E58xUMIsW%|$%7WHn9Z zoYsNK;ONLZv(kW9F+S`ZN~{U#QG&}0LLBch&`Biob2BQju}iv#z9ys5jXU8Y6V;eT zZ>FX%E%FVL!3JwBO*3j5XCM!rA+|A2GenXNq_TmF!ysK)2A8ETqenna)t#imA&i)| zV}Nj%U57*67-TWy7%z})^_d=;hF>IMVld|{g!#Zayd>*CW9(1Ct83Oc(t+6h67APT zWA}Wi1C7K934NrYy&RntgWux(NGdWjGt*!$V5EOLDnHGQB*vw>w7h&U1Aoh?8X}5D zlBi*w6QvzWCNx75i#w)Zy)n2-kD|d~djY1Ut=MxQd&h}mN|lhc2U>{=^lJiX z7CsRM7bjBg;R`kt!F~9L4~2| z&Ik)`w(P9z6)-UaxkvZ@Ocw-&X=wsXlhmK1nRb|ghDmViq1uk(XTr3rsx(#Q%Ll;J zcZPUp5k(CVCe#MJ0Mr-Y`WiOC8PL>8H~{@g7d~V_1~SaCK!=jzuGD+cxMI?@efvfd zP(a-QD(zWj5`HWrz!`YeA`K1E$O_XziLT^lLbb+>`*RA@bN}WNBXJ@kFarfbDDt%^ z)Vb_NBtPIdO$MuD#-XCG@Vzw2R4K_)qR^>MN2q)(_b?|`x+S&_dz&TBh7b)F;@hzI z2L^J>zMu-8`?wKR-6QZ}6r-?SMnz8)R3B$OnVv+riFb-a5ouzsxvHjqOwB4h9~?qj zrAL&Z9!CNmTB68=HHS1*5C3+848&uGGz=RC4SOd6-2*ke4>V!a4iy=PqMXw3b~r1E zAKIG;IIcvus?++n#7c)!Cu(*qIEzry1f-MdE8xE17 zbUC-LI?a5EA!Dm)h2gTQXYQ#QHYAaRpwCJ?1uN<^Hy)`LZqURFLZt%T8I}R9vyW!D zU4;=5%O9Z9{!EyzN`-OAt8`Q(tI>|q%w>|uJya&`gHP8_o8U5h|KC1DsgC*4DYIx@2f$U*Wd#9cM>mJ+a6x^I1Op4Ds*2RYKr|T-(CAH+2pR;5 zw^c=DJM3~s4R6GadQqbnI*L9tsFb{{Zbb;B!Y316mFVMkj6iLhpy&gPp|OPXEzpl) zKvPR&CHZ04*Tdx3tqYRKkjsn&Irj_&Ktui$0!fl8@NEj+*5qG4rt3t7sshnWgW}Cd z+}}VFcJlphp&=zhb`b0cIku|DyWeWfLDm8h3wsIHir}}nEbyFNL-ZZ-`VyQCd8D9V zKrvST%yi$Wq`|~0BGLuA6y#Rp$VIZi*z#>aLpNI`8Il23h2~ViNOqqLIP!`GVsSQ5 z3<M%)megz8nBY_8Z|f=9wil5NB&;? z!*EmV88mAq&%$8Z5dI9lqp++{l%74?kK8~Xav%Xh+;)d?Lm+7dI#~?N1b6lYcC-r6 zHd0x&#ILOBp$sgfHlb2lSB6-<$fTiPP=~8Q)-VHfCLHYv;|E|wBdIW83XDxb6es7D zE*1S}@+ki&Pk9uE)ibnen7j$NF1lEANmy5sj1JwviaD;wUdRz`->A%kQ$n|Z461nxRS*J0JZUYq_CL#-) zkOcr86;>Z2KOUpuAovM0cxF}N9ZwVC;c8xt8GiXk3lUFpQ`_o*grWj^l>oyPa>}vd zui)*9;5ND}B--S~$otjef8gSga*0Pk?kbQ;iAzmzfJ?zQLL07(YU9Z6tV-5IqOzfZ zBi0TvZK0*l3WLFyamVlwWt@)9C62zg za9e>c82L9Sr{>S21*_0r;A@;94wH1{yGK4LfwubB>DQn53ayYAh1SB-O(UqC2oKE$ zxRih|#%gyGI6A?O>!l_vr+JB(<8(ts%z+B>E1TJSE4!mO7^|J;+xr!M_oi+2HYFI` z@vr@dCC1quA#IpzQ(<+Ak6#$y5Sf2_MAXiM+%n37Vv3KF*1ht@9qN83vuKV$iBurG5p>pED2!xGP!wK zP0qa{EdCceXjR}9%=%;IoXHc}T5muJ#3ZIblN?t1ElN20gDfh$(G}{9Vs`qcPYnKe z`K77bpiYEE2!1f04^0TgYH4mI7a$ACxRhBm-2deh%}-#y5(}KkC#*2%(bTD4s9&$v zB*#^m>W8!6hkpb$IjiCY_~0(-M$25>koxyOeggY5X0w@mtW@2%mA2e+#F|8S>{RL3MIZLzwGnW_Xk<%%)GQAF5r4 z<=b32PQQ}OK9b)yL~z-dBMV>#%efpN&&ci`m6|FFgIXN9<*agdbm1hbchwKA*}xw9 z!!J1(=38Uc=U|xPSNE?RGWPhKbhSBhw!vkS#+N zqs@Zx6lH2iE0OeL+B-qjs=uyk8YS7YF(|~RxJ|@AM5V(%RFJCDqck&=8FtL!hslfA z=Sbg#3Isy~a%^vkitR;t=Dk=0dr93nuL^5jeoG{k+9T4k>4wQc;ZglEs@2>mtlXw1 zVim!k2JTkrJ(>P{iRD0Qz42s7{h?a*ch)8YAMm@d?j9-~v=tXs^MHjfEA z>9e@X`Uta}x97M^4h&T_WGMNbm7@mDR9)Qp59Lg6ECw``%kAF3TOxP+PLkAzBw`gA zi@{h4>Ydo(uk`1(w7IT{Kj4jOzv9jX@tctx0Q@-Yt~-5tY7t;^t~=S_{{=iNuYdXdx$dXXRanaM3wFb$a0a35^!m7bX@X#{c!c?t3$X0QE#cu~+95H(? z|2lil@25Y0gzsF)>|>$sBdkPV^`u~o*pa%NZ_dGlJKY7=jgC6P)fd~e&X+7FItK~A zfkn45^mE>-{m{HMr}kUDWur6Y-I|V9f4ejhYiF)u;pz#fWOR$i|NXZFO5g`P0R^02 zf;&F#jre@SEL->li?8quoK!%@IEA^0I0w^czBqD-oIp=J48NEGREKLU#TS>?Zw>TC zoqYppb~O!bCWP-W)eTBs5-f+fMF7`Nz=UHe!!{)7UcOof10elaQv;}c%EF|wET11; z=VHH0*!_Xts6Oq&0wdMgNYk;Rw-O=D%UvE{6mk|TrdUA|DE}vKgAou&2SJL2&j22Ua+(>om4T>ZaAocB9Zz_9WJv)>{4Tsjv z##zfN_n*#M8j;uA_;98BOyWfQwVJh#-L6BxW9`5U4$<^9n)yfO!dQg8?`thf&t|2( zsBRm=dZ8v;P;R1Bu`leNTfJLi6=-*S34ICujy10 zs)K!ax61I${?&eTT5F$mt$O8o>7J%mRs-1dl4da)0ruz9mE6{bu#U4A4@>)J1qGKt zRTA;jxv1&KM$u0ym;Q#UMbuo-8fmn^FFS)W8y4oh@g`OyUEpA9?nSg<&ba^Hi|;er z!+`H`W4wRej*1mw4BU;eU2pHt9iv~DNEu-CL?FNEO<^^qaM0a0DUR@Kv^tcjQjvWI z!Y{(GB;h+zq8gs}E!H7ke;CKOC7j+$cwkHJwNy&hNBq zF2%*Kf&2;z-%PgDon~!NTk0-B7&^<=e z39SIoveJ0dAh`XHmj}BZ!{KrhT%YPsEtPzAT)GO5Wu87sz477Cgw5k8b_^6>!qL#J z(dx(WOA~A+aS7V4u;;w;;%y@)tT?O1l>~n9?_NcUX#&H$Ak5Ye4!I9hzmF~oK6NA~ z&BxwQk-W50>wWnh$F3D?l^-?iFa623CuhE{Bz`A;{8jZ_c48g&NxB^GzffrrqVS6d2QqdNcKdqcl`33V3K~xrLc16 z@yuixm>U@yZ(MvJE|gs05yH+JXqkL)fZL1s&9)Tu3kr6-c{9bx54+FH60|P~vn-Ke zKJ9JZjpp?q)_hZ%-qr%Mm(=JiCm9v8uh7BloxkKtf#)N<2u1P_|CSk8K)xrJiar#B zmGckpQ>oDpLhNt{i{uD{&FFR^g%_O|BE5Agi#Ff4wn07C*88?$+-~@jk|9;;mg?TG z!H=;|{)fLj;SV19pZ-3E{~sP{dNLog(7hPG6m-7&p9P)&_i=<<9TV@DN8oXM@h6Yt z|2-bZ;L{s=qYfmF?c&$|VJy*pE~}hj$?V?KkPvI z6Ws3k5`Ug$H>^Ss@MlY4j}-i$y^uZG8GqWIKW)#Swx_2?{Qr%YeE(55|DOBt#{6*% Q{NL--X1;p(FLPJ@4`z*51^@s6 literal 0 HcmV?d00001