From caf65e31135a9283ef7fa667c6c8d9b807358f0c Mon Sep 17 00:00:00 2001 From: chenqi Date: Mon, 15 Dec 2025 14:24:45 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(router):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E9=85=8D=E7=BD=AE=E4=B8=8E=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构 constantRoutes 和 dynamicRoutes 中的路由结构,提升可读性 - 补充详细的路由配置项注释,便于后续维护 - 添加路由名称检查避免重复添加相同路由 - 更新数据库连接地址及 Redis 配置信息 - 完善 .gitignore 忽略文件列表,排除临时文件和日志 ``` --- .gitignore | 6 +- .../src/main/resources/application-dev.yml | 6 +- .../resources/router/modules/appointment.js | 96 ++++++++++++ openhis-ui-vue3/src/permission.js | 7 +- openhis-ui-vue3/src/router/index.js | 142 ++++++++++++------ 发版记录/2025-11-12/发版日志.docx | Bin 18650 -> 14445 bytes 6 files changed, 209 insertions(+), 48 deletions(-) create mode 100644 openhis-server-new/openhis-application/src/main/resources/router/modules/appointment.js diff --git a/.gitignore b/.gitignore index 92316bf4..a6163934 100644 --- a/.gitignore +++ b/.gitignore @@ -57,4 +57,8 @@ # 忽略设计书 PostgreSQL/openHis_DB设计书.xlsx -public.sql \ No newline at end of file +public.sql +发版记录/2025-11-12/~$发版日志.docx +发版记录/2025-11-12/~$S-管理系统-调价管理.docx +发版记录/2025-11-12/发版日志.docx +.gitignore diff --git a/openhis-server-new/openhis-application/src/main/resources/application-dev.yml b/openhis-server-new/openhis-application/src/main/resources/application-dev.yml index 500e9758..fe94317c 100644 --- a/openhis-server-new/openhis-application/src/main/resources/application-dev.yml +++ b/openhis-server-new/openhis-application/src/main/resources/application-dev.yml @@ -6,7 +6,7 @@ spring: druid: # 主库数据源 master: - url: jdbc:postgresql://47.116.196.11:15432/postgresql?currentSchema=hisdev&characterEncoding=UTF-8&client_encoding=UTF-8 + url: jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=hisdev&characterEncoding=UTF-8&client_encoding=UTF-8 username: postgresql password: Jchl1528 # 从库数据源 @@ -64,9 +64,9 @@ spring: # redis 配置 redis: # 地址 - host: 47.116.196.11 + host: 192.168.110.252 # 端口,默认为6379 - port: 26379 + port: 6379 # 数据库索引 database: 1 # 密码 diff --git a/openhis-server-new/openhis-application/src/main/resources/router/modules/appointment.js b/openhis-server-new/openhis-application/src/main/resources/router/modules/appointment.js new file mode 100644 index 00000000..6aeee38a --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/resources/router/modules/appointment.js @@ -0,0 +1,96 @@ +import Layout from '@/layout' +import router from './router' +import { ElMessage } from 'element-plus' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' +import { isHttp } from '@/utils/validate' +import { isRelogin } from '@/utils/request' +import useUserStore from '@/store/modules/user' +import useSettingsStore from '@/store/modules/settings' +import usePermissionStore from '@/store/modules/permission' + +NProgress.configure({ showSpinner: false }); + +const whiteList = ['/login', '/register']; + +router.beforeEach((to, from, next) => { + NProgress.start() + if (getToken()) { + to.meta.title && useSettingsStore().setTitle(to.meta.title) + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() + } else if (whiteList.indexOf(to.path) !== -1) { + next() + } else { + if (useUserStore().roles.length === 0) { + isRelogin.show = true + // 判断当前用户是否已拉取完user_info信息 + useUserStore().getInfo().then(() => { + isRelogin.show = false + usePermissionStore().generateRoutes().then(accessRoutes => { + // 根据roles权限生成可访问的路由表 + accessRoutes.forEach(route => { + if (!isHttp(route.path)) { + // 检查是否已经存在同名路由 + if (!router.hasRoute(route.name)) { + router.addRoute(route) // 动态添加可访问路由表 + } + } + }) + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + }) + }).catch(err => { + useUserStore().logOut().then(() => { + ElMessage.error(err) + next({ path: '/' }) + }) + }) + } else { + next() + } + } + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) + +const appointmentRouter = { + path: '/appointment', + component: Layout, + redirect: '/appointment/manage', + name: 'Appointment', + meta: { + title: '预约管理', + icon: 'calendar' + }, + children: [ + { + path: 'manage', + component: () => import('@/views/appointment/manage'), + name: 'AppointmentManage', // 修改名称,避免与父级重复 + meta: { title: '预约管理', icon: 'list' } + }, + { + path: 'setting', + component: () => import('@/views/appointment/setting'), + name: 'AppointmentSetting', + meta: { title: '预约设置', icon: 'setting' } + } + ] +} + +export default appointmentRouter \ No newline at end of file diff --git a/openhis-ui-vue3/src/permission.js b/openhis-ui-vue3/src/permission.js index 4d495ac9..7a28bd02 100644 --- a/openhis-ui-vue3/src/permission.js +++ b/openhis-ui-vue3/src/permission.js @@ -33,7 +33,10 @@ router.beforeEach((to, from, next) => { // 根据roles权限生成可访问的路由表 accessRoutes.forEach(route => { if (!isHttp(route.path)) { - router.addRoute(route) // 动态添加可访问路由表 + // 检查是否已经存在同名路由 + if (!router.hasRoute(route.name)) { + router.addRoute(route) // 动态添加可访问路由表 + } } }) next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 @@ -62,4 +65,4 @@ router.beforeEach((to, from, next) => { router.afterEach(() => { NProgress.done() -}) +}) \ No newline at end of file diff --git a/openhis-ui-vue3/src/router/index.js b/openhis-ui-vue3/src/router/index.js index 5dd60e08..094392ae 100644 --- a/openhis-ui-vue3/src/router/index.js +++ b/openhis-ui-vue3/src/router/index.js @@ -3,32 +3,69 @@ import { createWebHistory, createRouter } from 'vue-router' import Layout from '@/layout' /** - * Note: 路由配置项 + * Note: 路由配置项说明 * - * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 - * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 - * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 - * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 - * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 - * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 - * name:'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题 + * hidden: true // 当设置 true 时,该路由不会在侧边栏出现(如401、login等页面,或一些编辑页面/edit/1) + * alwaysShow: true // 当路由下的 children 声明的路由大于1个时,自动变为嵌套模式(如组件页面) + * // 只有一个时,会将子路由作为根路由显示在侧边栏(如引导页面) + * // 若想不管 children 个数都显示根路由,可设置 alwaysShow: true,忽略之前定义的规则 + * redirect: noRedirect // 当设置 noRedirect 时,该路由在面包屑导航中不可点击 + * name:'router-name' // 设定路由的名字,必须填写,否则使用时会出现问题 * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 * roles: ['admin', 'common'] // 访问路由的角色权限 * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 - * meta : { - noCache: true // 如果设置为true,则不会被 缓存(默认 false) - title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 - icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg - breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 - activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 + * meta: { + noCache: true // 如果设置为true,则不会被 缓存(默认 false) + title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 + icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg + breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 + activeMenu: '/system/user' // 当路由设置了该属性,则会高亮对应的侧边栏 } */ -// 公共路由 +// 公共路由 - 所有用户均可访问的路由 export const constantRoutes = [ - { path: '/appoinmentmanage', component: Layout, redirect: '/appoinmentmanage', name: 'AppoinmentManage', hidden: true, meta: { title: '预约管理', icon: 'component' }, children: [{ path: '', component: () => import('@/views/appoinmentmanage/index.vue'), name: 'AppoinmentManageIndex', meta: { title: '预约管理' } }, { path: 'doctorschedule/:deptId', component: () => import('@/views/appoinmentmanage/doctorschedule/index.vue'), name: 'DoctorSchedule', hidden: true, meta: { title: '医生排班' } }] }, - // 门诊医生站路由配置 - { path: '/doctorstation', component: Layout, redirect: '/doctorstation', name: 'DoctorStation', meta: { title: '门诊医生站', icon: 'doctorstation' }, children: [{ path: '', component: () => import('@/views/doctorstation/index.vue'), name: 'DoctorStationIndex', meta: { title: '门诊医生站', icon: 'doctorstation' } }] }, + // 预约管理路由 + { + path: '/appoinmentmanage', + component: Layout, + redirect: '/appoinmentmanage', + name: 'AppoinmentManageRoot', + hidden: true, + meta: { title: '预约管理', icon: 'component' }, + children: [ + { + path: '', + component: () => import('@/views/appoinmentmanage/index.vue'), + name: 'AppoinmentManage', + meta: { title: '预约管理' } + }, + { + path: 'doctorschedule/:deptId', + component: () => import('@/views/appoinmentmanage/doctorschedule/index.vue'), + name: 'DoctorSchedule', + hidden: true, + meta: { title: '医生排班' } + } + ] + }, + // 门诊医生站路由 + { + path: '/doctorstation', + component: Layout, + redirect: '/doctorstation', + name: 'DoctorStation', + meta: { title: '门诊医生站', icon: 'doctorstation' }, + children: [ + { + path: '', + component: () => import('@/views/doctorstation/index.vue'), + name: 'DoctorStationIndex', + meta: { title: '门诊医生站', icon: 'doctorstation' } + } + ] + }, + // 重定向路由 { path: '/redirect', component: Layout, @@ -40,21 +77,25 @@ export const constantRoutes = [ } ] }, + // 登录路由 { path: '/login', component: () => import('@/views/login'), hidden: true }, + // 注册路由 { path: '/register', component: () => import('@/views/register'), hidden: true }, + // 401权限不足路由 { path: '/401', component: () => import('@/views/error/401'), hidden: true }, + // 首页路由 { path: '', component: Layout, @@ -68,6 +109,7 @@ export const constantRoutes = [ } ] }, + // 个人中心路由 { path: '/user', component: Layout, @@ -82,7 +124,7 @@ export const constantRoutes = [ } ] }, - // 添加套餐管理相关路由到公共路由,确保始终可用 + // 套餐管理相关路由 - 添加到公共路由确保始终可用 { path: '/maintainSystem/Inspection/PackageManagement', component: Layout, @@ -98,8 +140,9 @@ export const constantRoutes = [ } ] -// 动态路由,基于用户权限动态去加载 +// 动态路由 - 基于用户权限动态加载的路由 export const dynamicRoutes = [ + // 基础管理路由 { path: '/basicmanage', component: Layout, @@ -115,7 +158,7 @@ export const dynamicRoutes = [ } ] }, - // 兼容系统业务管理路径 + // 兼容系统业务管理路径的发票管理路由 { path: '/system/ywgz', component: Layout, @@ -130,6 +173,7 @@ export const dynamicRoutes = [ } ] }, + // 维护系统路由 { path: '/maintainSystem', component: Layout, @@ -139,22 +183,23 @@ export const dynamicRoutes = [ children: [ { path: '', - redirect: 'chargeConfig' + redirect: 'chargeConfig', + name: 'MaintainSystemIndex' // 添加名称以解决警告 }, { - path: 'chargeConfig', + path: 'chargeConfig', // 收费配置路由 component: () => import('@/views/maintainSystem/chargeConfig/index.vue'), name: 'ChargeConfig', meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] } }, { - path: 'Inspection', + path: 'Inspection', // 检验管理路由 component: () => import('@/views/maintainSystem/Inspection/index.vue'), name: 'Inspection', meta: { title: '检验管理', icon: 'inspection' }, children: [ { - path: 'PackageManagement', + path: 'PackageManagement', // 套餐管理路由 component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'), name: 'PackageManagement', meta: { title: '套餐管理' } @@ -163,6 +208,7 @@ export const dynamicRoutes = [ } ] }, + // 系统管理路由 { path: '/system', component: Layout, @@ -171,61 +217,62 @@ export const dynamicRoutes = [ meta: { title: '系统管理', icon: 'system' }, children: [ { - path: 'user', + path: 'user', // 用户管理路由 component: () => import('@/views/system/user/index.vue'), name: 'User', meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] } }, { - path: 'role', + path: 'role', // 角色管理路由 component: () => import('@/views/system/role/index.vue'), name: 'Role', meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] } }, { - path: 'menu', + path: 'menu', // 菜单管理路由 component: () => import('@/views/system/menu/index.vue'), name: 'Menu', meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] } }, { - path: 'dept', + path: 'dept', // 部门管理路由 component: () => import('@/views/system/dept/index.vue'), name: 'Dept', meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] } }, { - path: 'post', + path: 'post', // 岗位管理路由 component: () => import('@/views/system/post/index.vue'), name: 'Post', meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] } }, { - path: 'dict', + path: 'dict', // 字典管理路由 component: () => import('@/views/system/dict/index.vue'), name: 'Dict', meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] } }, { - path: 'config', + path: 'config', // 参数配置路由 component: () => import('@/views/system/config/index.vue'), name: 'Config', meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] } }, { - path: 'notice', + path: 'notice', // 通知公告路由 component: () => import('@/views/system/notice/index.vue'), name: 'Notice', meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] } }, { - path: 'tenant', + path: 'tenant', // 租户管理路由 component: () => import('@/views/system/tenant/index.vue'), name: 'Tenant', meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] } } ] }, + // 租户用户设置路由 { path: '/system/tenant-user', component: Layout, @@ -240,6 +287,7 @@ export const dynamicRoutes = [ } ] }, + // 租户合同管理路由 { path: '/system/tenant-contract', component: Layout, @@ -254,6 +302,7 @@ export const dynamicRoutes = [ } ] }, + // 用户角色分配路由 { path: '/system/user-auth', component: Layout, @@ -268,6 +317,7 @@ export const dynamicRoutes = [ } ] }, + // 角色用户分配路由 { path: '/system/role-auth', component: Layout, @@ -282,6 +332,7 @@ export const dynamicRoutes = [ } ] }, + // 字典数据路由 { path: '/system/dict-data', component: Layout, @@ -296,6 +347,7 @@ export const dynamicRoutes = [ } ] }, + // 系统监控路由 { path: '/monitor', component: Layout, @@ -304,25 +356,26 @@ export const dynamicRoutes = [ meta: { title: '系统监控', icon: 'monitor' }, children: [ { - path: 'operlog', + path: 'operlog', // 操作日志路由 component: () => import('@/views/monitor/operlog/index.vue'), name: 'Operlog', meta: { title: '操作日志', icon: 'operlog', permissions: ['monitor:operlog:list'] } }, { - path: 'logininfor', + path: 'logininfor', // 登录日志路由 component: () => import('@/views/monitor/logininfor/index.vue'), name: 'Logininfor', meta: { title: '登录日志', icon: 'logininfor', permissions: ['monitor:logininfor:list'] } }, { - path: 'job', + path: 'job', // 定时任务路由 component: () => import('@/views/monitor/job/index.vue'), name: 'Job', meta: { title: '定时任务', icon: 'job', permissions: ['monitor:job:list'] } } ] }, + // 系统工具路由 { path: '/tool', component: Layout, @@ -331,13 +384,14 @@ export const dynamicRoutes = [ meta: { title: '系统工具', icon: 'tool' }, children: [ { - path: 'gen', + path: 'gen', // 代码生成路由 component: () => import('@/views/tool/gen/index.vue'), name: 'Gen', meta: { title: '代码生成', icon: 'gen', permissions: ['tool:gen:list'] } } ] }, + // 定时任务日志路由 { path: '/monitor/job-log', component: Layout, @@ -352,6 +406,7 @@ export const dynamicRoutes = [ } ] }, + // 代码生成编辑路由 { path: '/tool/gen-edit', component: Layout, @@ -371,17 +426,19 @@ export const dynamicRoutes = [ // 合并常量路由和动态路由,确保所有路由都能被访问 const allRoutes = [...constantRoutes, ...dynamicRoutes]; -// 添加404路由到所有路由的最后 +// 添加404路由到所有路由的最后,确保捕获所有未匹配的路由 allRoutes.push({ path: "/:pathMatch(.*)*", component: () => import('@/views/error/404'), hidden: true }); +// 创建Vue Router实例 const router = createRouter({ - history: createWebHistory(), - routes: allRoutes, + history: createWebHistory(), // 使用HTML5历史模式 + routes: allRoutes, // 使用合并后的所有路由 scrollBehavior(to, from, savedPosition) { + // 页面滚动行为:如果有保存的位置则恢复,否则滚动到顶部 if (savedPosition) { return savedPosition } else { @@ -390,4 +447,5 @@ const router = createRouter({ }, }); -export default router; +// 导出路由实例 +export default router; \ No newline at end of file diff --git a/发版记录/2025-11-12/发版日志.docx b/发版记录/2025-11-12/发版日志.docx index 4ad7e843345d20d4394de369afebcf18b10f6198..07966afcf1138556ea161acc5fc2931b308ad412 100644 GIT binary patch literal 14445 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
    nvjJ_tv{lNYsWJ zjanrxZLQbBn-{k5cu?mvb_4YE0b{M#Z?mbpIo~fX*@ifG-x%-|0X04z3n|j}x71PFe2_ zB6p%5fASp9PFo{oVQ0k;;M^}L=`qS*0=d9d`|ea1CLe&BQ~J$zS>#*ZZjD7?Vj{Xn|m^RE#MIFo5lWyXktjS5lA|$bBRqhS+bn2R7Ig?K$+z{BIS}s+RW%bfh^(%;kjcS zSD7ptaDOv!2q!{fxw0OUzB7QS4hLQa1jvus+@^bE9znkhkM-SKL<7cC z%foX5Gvw&U)wR+&kcFSHu^|>#?@dB75V}=GwoTiH3kJ)BtPTiNCLtMMvvdY^;XuXu z3a(Gl$S1{$_Qtv>fN@p>K~Q}hy@hb!5_ZI{1*+c%n-cuAsq*YD#H_i7$c!_T+ut>J z$~vifNq@5+oh5*+#Es{S*n`^C@|t!XkM?#-IJAxa_seT*<$QWjcq&CA}dgPePYA+)WpdL8lFuYKA(NtRV_rb`^gWdS~WrRPmH| z->{{flHin%RBYYvnmw_{L1V%|eGBf}Y&1drO6;t-qSQqc_xEk~_-?Wm-TkJDB1psF zD5_)4%bqfMp(vhldnGMqIK2;wp_cz}t!9Z!Aa%XJCnzRhu`!jheoJ*V$j0X zNc*e>nUkt&$d)B=3(N6F<@w`XxipX@xTc^Sw)z1{hpsl5vLVspt?=*cms z2R9SNi7XSIMktE%MPG3dk zH_c`x$eeo&;^C7N=?qE*b-0`}Co|(?qHaF2sgln9nKOI@UDi=> zJa+MapzhCNqDT@>T~fk#5Ctmo#2eBh5`=PrJY)o*pKUS;wI2i@*=}wq0}-)m zkw82IJj_amh?ZYA_y(M4VThz$CjRjS4K3r@E>`GnpFHw#L>FTseoMjQzGAZ z5N|6-4!8E)Fr2%BHg0Dp7SWuNu%gxR%lxGIF)I5Ip|Fg5Opmj{V(rn#7Xh(UxBgC9 zvJEZ;IazQ+2Awkg-(gpGU2oEkaAEWDL!Zz`^yq2##T8Jsx+6^cJlLN7f;Qwg#8F&Q z(O+Ctho6Pn<`Wk`wp(ElDQq@^!Q&)1xk7$F*wi97Uy`c(-Z|EiLX6xkyFo0VPc5A! zxpYo7x!)AusPxvJFx(tAPEL=e`bA3$i*{K>%PWRjhZb@9wRm`aaKLj1Y&E zlSE%d@j9Km7S}{MbL6-nuV;GDBHHxEJTGS^vwoAPRD>%Pq{GD!9Yi=JBFL+*gGIZI z$Vp{_>o|A=SdP24)fL+wv2SddF6L?7w<|QTj9)||v^%Dz#!H(5L&u9%5=Pf4p(BzE zQlbLJBmt(njQEYDrLjFwhzBOF=Jh4B)jL-YHcG!63+6TJ-iSsPwIopY0gF4pGmoDX z*7Bu{?!5UfY_yn=);Xb^~@*g~XhPUgF}V zb76+@I9W00Wk28^({_y&_f-9?tH{HY1{;DcAqx@>HNh{L1!V;(dSubUeu2hhI;GXD zH6ccC;N%lxOezlCRMvBKF@JqsgS-6mhL+otbAlM|c;2iGQ z0@NKuqtWlN*#h)Jvldyvc0>tV2+%2Hu@8^~M6Co4h63Yjk_5E6fyFL7_+ z`~Ms4t8D<}cxC{k>@;5>oJlSpc)iR*MbPE{AKbw}@BjDfg%tgsPbRY*JAeJHDt#9A z{+RrgsQJlkeefd}>>_tmX{Ba$E8J#$Sy9G)Z--|Q^MYqr6oHXV(6Xi6YIl?vz62^8 zH=Ai|M?cTm<2bGpl~0Qibi1!HNk__X8R@o&nCv!4GS*7XPxh#q{535p2NUZDv1aL* zoh;;4l#i`^8hyko%3YC#WePtk%YjKBoLe(FBWBQakL2?*-8zhbU8i}++N^Z`!i${G zG*T2;Zx(hgITgOLA$w4-iFg`zF15Q;KqJ#Cyo`sM?sfla?lkmT?s`cOL!aCQjRFTy zl3B>M0JD#6F$N!-Jj@?8q446&0^M>KSs54LQVPIm&Sm%sj08We3>> z!QBO9-bJdG;QFb(nK5n(a`t^EplUYakjhmuzx%56r*P)MqT|7XGLU*FOU#wFO?D`0 z4rUXj;3-5khRo&f2txR0Fv^(_o~~W-u4b`DMeWkWY}C^Y!zJ7P%7KeDba636>^$v& zgCGb>qt?(_3vpaqeoWa7X=){qoU=;qB07`m=(*g1zutl_4ajpzKlWYDEeDXY8Eoc}AJ34(4OZ&*& zT;`zrJltY53jKH9L775IN_9wn5wl?&z9-%%Daoe%#+KO*^FsBidAqzeti7%=hcO%P zF$ePz#bcVa1A!*DE_3XSRsqMnHjUH|ypu*oDnhKOYk_y~yzk42*2*ML9~*{p?dxU}dxBJ2X&wqV>!E|5l#%QU95X6W{x|@UF;wW;*obGI zGxj=#!W^@qS^mKi(rg*k({-ktZ%M~c#u;5Q+~(^)nCoGd>)VBfd!w>`t@KBABnGBL zS(xExkd|?lucI(m^cAHLg-L(xs8Zw|s&(~gGSjur?2LMI=ZfC?m2|B1cAE1Q6D(H^ zcqDj4?PqS0o+g4Ty-G}GsslEbMapWY`}1}X$!^W-+B0X^kY~4T&Wus}Gie;IQ|s6C zZ8SdU=6JmpYkPktSNVHgPjGvEZft$3WqXXKI@*WX@E6q_Md22ot|B(-6I*-}PoX(p zbAtK&_U4#EVm`LjJ-P)jmYrq#8rzk~&n_X`aA0k6U>$NGoxJ|>?0$U5Z|T`#{_sGv zxa1agg8kqaJd)bjiKFVt)%&70b+w*dMSA+_o=#$VHplf#`lB0Lz}u5b6$9syYQCS2#e1go{eCST%oB1+w0-c}`|el&-Sow65tw+`flV2A z7lejO^&Q-R5(SUbCeUfL8!zm|ZQiR(@tdzQP1o~jc9dP?BDUdnJFwz2@ZJo8hfAUy z*I|eMX@!12Hdn9hdC-|M(#}5inC4#V&9jaAn|WXIm0xhTdBj&1&w1U(WJQF{?-a#+9xviiY5aoK9tsC{k64#~^pJD%w(@(;OjsW4bh&VbQE zl>&Ke(mEyO!_Dhh0i-iV|7Rzek*3{rNDO|0SHcwx*IXIT_%;X05o_Lx0KS@RH_)xq&fCu#s#Oh&i z)Twb*+{1yaOVzXb>j+La3_1ujI?pOj)8h9oI(kB11~j;A#%n{2Zb>qgRz@Z84OHo{ zd(AF<;w{(C6|FTZ*=-o2o<+Fwj5o%)?HRYqTD3hLPf?2Tocec35``__b%~E8F3wU$ zO+}hP3Nf_&FEaDxVe%1KqV15C4CF40?>IhNb=aI`y_Khi(OyOPl-tf>8^_4Q5oo1H zcKt?zOA>;W@hVTo?p8TJ}#2IrNR=s#g0Nby`?!iIsh3w4Y`pl{*$s1JSja&e|rNltRfEtd{ z+$9SOF8a>$->2^mu35A%8^k($*h5K3^L51#=&%Br(lb0fE5V|PY_rgNkT8Zv0I^hQ zF0T$9mHJ+Q+hM(1iO2>G(~b)6J4eYJ+d(GQ;V9{JYk7X9!fLkVrmb95V%W?h-`P94SUofSYNSQ@SizXfk0|lU3c{)=-I75|(B(og6o@ z12r9?W~X|iqbjN>$>nk>@% zWS()apR2}hxj})St67b2d&VxMPu)nk_U;DKPdo((>l5IDKCR`iPkPd;Rv$!3q}E{j zF?3{{-4#7G$u&uH|JBCQ$8VZwM=a*^;htG6t z9>E?&P!|F3Mm!QHudCseV*)5Z?l38~F}*l6y(m{$7#Cm$!+e*wYdhZm9r61kPX;`3 z!?*-&SgG^AObiYI%kBW7&N2+#1)xxXRV)2&8a$6tdf%*7#!OV-EXvW7s3^Kh^=8*0bF{3`ErYB;|&e%kze+zE2nb1)a@8iwQmSR#3tcv#f;W%I%L>Fx6SW#goojwOfJ zBrx}dk^pBP1Mt{Q@1?U*n?1~==WDNV$#oT&k-IrOF^j&WSI#!{i3srHb8 z|5iv#cfi6^QKSwOB*`rb;S(r{Z{}dUDuM3i^~S-8JyUaD48+|o+eU%%U5Iy>qThDg z5P*9KKdLSr*c>d8&7EX}UaG;Fe`!;Fq$jp7NI*vf7e?0?KjPKIW;({KusDcp=wf%c zfqCC;(ar#J)ReQ`;}qQOA%ajxZGdevw#>4f#UeJHd-(?UVQ7jL*W2UO;TU0q!K>|! zr84Fh(97*i9$A#JSV_e4e%dM!cjnUvE?J~tV0Oz`r+OifCHXqZ2OBhtFzXPJvzCQBSkvvdVl z{3ZdOdatpJb;yg8cIBp(D+pG_?H0w#3Z*CkC+P}eeCxsDeYSzkd5sT`c@~}pje4z+ zumsbM#H%7rdh*Ep^0afUy#2C=oM9IfJ@Lh>&~k_lscL(RV)}o>wGLBhZ~3gWu9MIh zVU$cb*1o>2dRlZ`UAPA_9n4;XT7+rX?*(zB_OYTB1=e1oo1aMa%#brXoo_l)_-I?R z7r$L30b?lTy&;b%3f7ypH#KiUHy@RUnh~Z?%6}d@G4P4fo@YJ>{4QXDpe5kTqw^q7 zJ{!jcse1?dRA`Ur^-`{ZFL^)ln%e*Np9ph5wSOD9e(CJQm(IfdS!Z=^Z2ss-|4(JV z^!01YkQ@6$W!njFU}Y~W=9CmbEj4qMLV#&YeY2?D<5gH24KW2ivm}A>LonGcCf$Y@ z5&I7FnO8W1N-{N%>P%yeO$y~#7th{W+EdGKsYrAa=_YsCx%I|b-rk_I{O-`=22gS_GI(XlAfNIAI)THBO8Tc)8kH^9_M_G@G zH!xumSaxQ2T7%?KiyE|7>_{DHG71Jd6EuM4!fXTyXTXb9jD@GvE`OSy_4x<^7lXIU&sHjCX0;tzYF;H1tR_h1pp`l1_1ce zauI(8{&nX3zo3I(JUi#V&ZGY;{NFkM{{jO5h@<=i{y)qB_^YJ9(!KvBD-G=*lKzeS z{a5^7NwWXK7hwJa|7XhVU*Ugc7XAxfiSrNmUwMXq74cUV#=k@i5dTBOpE((Sh5t2) z`6oEVKjHtC()=s