From 6ecd0b5bd543217155c75d9d74956cf67c7c7c46 Mon Sep 17 00:00:00 2001 From: meswork764 Date: Wed, 27 May 2026 18:36:20 +0800 Subject: [PATCH] docs: add development plan and technical design --- .gitignore | 1 + .../MacroinfManage_MES.code-workspace | 7 + .../今后开发计划_2026-05-27.md | 77 + ...开发计划与新增需求分析记录_2026-05-27.docx | Bin 0 -> 54727 bytes .../元利项目详细用户使用说明书.md | 3 +- .../技术开发详细方案_2026-05-27.docx | Bin 0 -> 138355 bytes .../技术开发详细方案_2026-05-27.md | 3441 +++++++++++++++++ analyze_mes_v20_views.js | 731 ++++ tools/create_dev_plan_docx.ps1 | 206 + 9 files changed, 4464 insertions(+), 2 deletions(-) create mode 100644 MES_Manage_View_V20/MacroinfManage_MES.code-workspace create mode 100644 MES_Manage_View_V20/今后开发计划_2026-05-27.md create mode 100644 MES_Manage_View_V20/今后开发计划与新增需求分析记录_2026-05-27.docx create mode 100644 MES_Manage_View_V20/技术开发详细方案_2026-05-27.docx create mode 100644 MES_Manage_View_V20/技术开发详细方案_2026-05-27.md create mode 100644 analyze_mes_v20_views.js create mode 100644 tools/create_dev_plan_docx.ps1 diff --git a/.gitignore b/.gitignore index 0ec9630..14e595e 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ selenium-debug.log **/.idea/ .vscode/ **/.vscode/ +~$*.docx *.suo *.ntvs* *.njsproj diff --git a/MES_Manage_View_V20/MacroinfManage_MES.code-workspace b/MES_Manage_View_V20/MacroinfManage_MES.code-workspace new file mode 100644 index 0000000..2a0ed79 --- /dev/null +++ b/MES_Manage_View_V20/MacroinfManage_MES.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { + "path": ".." + } + ] +} \ No newline at end of file diff --git a/MES_Manage_View_V20/今后开发计划_2026-05-27.md b/MES_Manage_View_V20/今后开发计划_2026-05-27.md new file mode 100644 index 0000000..8a5bdc5 --- /dev/null +++ b/MES_Manage_View_V20/今后开发计划_2026-05-27.md @@ -0,0 +1,77 @@ +# 今后开发计划与新增需求分析记录 + +生成日期:2026-05-27 +项目:MES_Manage_View_V20 + +## 一、排期口径 + +- 按“最终调整”数字从小到大排序。 +- 从 2026-05-28 开始排期。 +- 按工作日递推,跳过周六、周日。 +- 跳过端午节、中秋节、国庆节法定放假日期。 +- 调休日按工作日处理。 +- 暂按单开发线串行排期。 + +节假日口径: + +- 端午节:2026-06-19 至 2026-06-21。 +- 中秋节:2026-09-25 至 2026-09-27。 +- 国庆节:2026-10-01 至 2026-10-07。 +- 调休上班日:2026-09-20、2026-10-10。 + +## 二、开发计划排期 + +| 顺序 | 需求 | 预估 | 开始 | 结束 | 备注 | +|---:|---|---:|---|---|---| +| 1 | 及时开工报表 | 1天 | 5.28 | 5.29 | 增加正选/反选查询 | +| 2 | 机加件排产-表单 | 4天 | 5.29 | 6.04 | 日期筛选优化 + 历史工时查询;SAP新增字段不算MES开发 | +| 3 | 装配已排产需求 | 12天 | 6.04 | 6.23 | 大需求,建议分阶段交付 | +| 4 | 生产日报-送检(机加/装配) | 3天 | 6.23 | 6.26 | 建议统一报表,部门做筛选维度 | +| 5 | 及时齐套跟踪结果报表 | 5天 | 6.26 | 7.03 | 依赖SAP缺件明细实时接口 | +| 6 | 生产计划跟踪 | 3天 | 7.03 | 7.08 | 工序状态、颜色、标准工时、订单状态 | +| 7 | 外协任务检验 | 3天 | 7.08 | 7.13 | 增加指派对象、供应商、SAP采购收货单号 | +| 8 | 异常管控 | 5天 | 7.13 | 7.20 | 报工页面直接报异常,多审批人可见一人处理 | +| 9 | 机加班次产量表 | 3天 | 7.20 | 7.23 | 新增报表 | +| 10 | 发货通知列表 | 1天 | 7.23 | 7.24 | SAP数据已提供,可新增查询报表 | +| 11 | 质检任务早知道 | 1天 | 7.24 | 7.27 | 依赖“装配已排产需求”的装配完成时间 | +| 12 | 生产工艺 | 2天 | 7.27 | 7.29 | 无生产工艺时自动带出标准工艺 | +| 13 | 工时报表 + 备注类小改 | 2天 | 7.29 | 7.31 | 指派对象、机加领料备注、机加/装配退库备注、保存提示等合并处理 | +| 14 | 生产订单关闭 | 4天 | 7.31 | 8.06 | 批量更新SAP订单状态,风险较高 | +| 15 | 及时检验报表 | 4天 | 8.06 | 8.12 | 报工超过2天未检验 | +| 16 | 工序流转卡 | 1天 | 8.12 | 8.13 | 增加打印原料编码 | +| 17 | 一楼质检大屏幕 | 4天 | 8.13 | 8.19 | 及时率、关键工序 | +| 18 | 机加现场大屏幕 | 3天 | 8.19 | 8.24 | 缺勤、关键工序 | +| 19 | 装配现场大屏幕 | 4天 | 8.24 | 8.28 | 缺勤、及时送检 | +| 20 | 编程任务清单 | 4天 | 8.28 | 9.03 | 按装配类似逻辑做编程报工 | +| 21 | 设备档案管理 | 2天 | 9.03 | 9.07 | 需先确认字段归属 | +| 22 | 设备数据采集 | 8天 | 9.07 | 9.17 | 采集接口、落库、状态汇总 | +| 23 | 设备指标/OEE | 6天 | 9.17 | 9.24 | 依赖设备采集和标准工时口径 | +| 24 | 工时查询-设备采集联动 | 2天 | 9.24 | 9.29 | 程序工时字段对接采集数据 | +| 25 | 手续确认报表 | 3天 | 9.29 | 10.09 | 装配/电气齐套列表 + 手续确认 | +| 26 | 产品合格率(工位) | 3天 | 10.09 | 10.13 | 需确认良品/总产量口径 | +| 27 | 让步接收记录 | 2天 | 10.13 | 10.15 | 新增查询页面 | +| 28 | 设计任务报工模块 | 6天 | 10.15 | 10.23 | MES自建设计任务、设计工时 | +| 29 | 工时异常报表 | 2天 | 10.23 | 10.27 | 依赖标准工时和实际单件工时 | +| 30 | 正在加工状态 | 1天 | 10.27 | 10.28 | 机加正在进行中状态 | + +## 三、暂不直接排期 / 需等前置条件 + +| 需求 | 原因 | +|---|---| +| 及时拣配(机加)MES | 等SAP数据、条码规则、状态写回规则 | +| 及时拣配(装配)MES | 等SAP数据、条码规则、状态写回规则 | +| 及时送检报表 | 需确认发料齐套时间/SAP字段是否稳定;若SAP数据已到,可插入0.5天 | +| 工艺内容修改 | 已开工任务怎么处理未定 | +| 标牌打印操作 | 需求未确定 | +| 首检、巡检 | 需求内容为空,无法估时 | +| 外协采购订单收检结果 | 需求内容为空,无法估时 | +| 不合格品单据打印 | 需求内容为空,无法估时 | + +## 四、排期结论 + +按以上单线工作日计划,已明确可做事项预计到 2026-10-28 完成。 + +实际执行建议先做 5.28 到 6.23 的前三项,因为它们优先级最高,且“装配已排产需求”会影响后面的质检早知道、日计划、及时送检等需求。 + +## 五、新增需求分析与开发记录原文 + diff --git a/MES_Manage_View_V20/今后开发计划与新增需求分析记录_2026-05-27.docx b/MES_Manage_View_V20/今后开发计划与新增需求分析记录_2026-05-27.docx new file mode 100644 index 0000000000000000000000000000000000000000..10399e1d6293fc0eb97b4ac97c3cd04d96dd7db8 GIT binary patch literal 54727 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 X_H*Dw$Ll*jtf>IQ`1yVuIezzV#0e)> literal 0 HcmV?d00001 diff --git a/MES_Manage_View_V20/元利项目详细用户使用说明书.md b/MES_Manage_View_V20/元利项目详细用户使用说明书.md index eafa154..e293efd 100644 --- a/MES_Manage_View_V20/元利项目详细用户使用说明书.md +++ b/MES_Manage_View_V20/元利项目详细用户使用说明书.md @@ -1090,8 +1090,7 @@ 9. 看板:生产、装配、质检、机加、综合大屏。 10. 新增需求页面:手续确认、及时检验、装配已排产需求、齐套跟踪等。 -## 二十一、逐页详细操作说明(按 src/views 页面) - +## 二十一、逐页详细操作说明 本章按源码页面逐页编写。每个页面都从实际 `v-model`、表格列、按钮、弹窗、页签、存储过程和 SAP/WMS 调用中提取操作线索,转换成用户可执行的步骤。 通用阅读方法: diff --git a/MES_Manage_View_V20/技术开发详细方案_2026-05-27.docx b/MES_Manage_View_V20/技术开发详细方案_2026-05-27.docx new file mode 100644 index 0000000000000000000000000000000000000000..6eb6961f3b7e13f0dd9749fe2a1a3ad7597244e1 GIT binary patch literal 138355 zcma%hb980Twr*_O?$}AkPIheDwr$(C)3I%JY+D`MNk=cgbMGDFocrD%Z;i3`u3c-^ zsyV-J)!Gv!F9iw)1N6@kCc7{2&-ecv(BBPXJ0p2VJ9{Sv`EN0_?+&PciLtS^V{!rm z0bzgu0U`ann1Q`Ly}ONdjzYif03%wb+&aHTiqrc*=wD!iN-5tE69J zNbesF1%hr{m%LgHbXj!MI=DIcZsR9-KS%>fX6Kb937wi~R&LP%)37=b%jTnV;CPxh zBakhpF(KPD_6qT{^kOm3uCet=@XiAad`54`)yjE7TQjLf6awGZ-rYXuTJOeYq0oF* z8KL>k4}U``E3F?Ph(Wg>rnuc7$)4gTlvV77Ne@)qRY_^de7u-UIg^p@*`_L8(#$wX zRinR+C86k2;Sf`V7+ODHG5-^0sh3wurEi#xzhOrHcbJXr98LbgIVMp?c90P%RxP*BlpMK@EHsDJhN?u&VLY6od0M%2wPBWjKZ$zv_q|-v%z58A_sF*R+#mx9y%S z$JTX6AdsaP$rKrga9u zE-7@9!cS2eE0xgt0-D_+uxaA#w)jlc^H|Ra^a85}FubrmB&WJyWGQ>l2NgLH{KPqe z@++4m5UgQ&U`PY_*gz;hFFJGEPg?U7Pzr`i)%J{zwlHf^H^b}g^al227yLyD+`+@R zo6C#+3j8Goz`ZJ(d;-gQ%fv4T!vGJ2_{;Unl&n7&-h2Q6-fv-kyq8;Zf>MoSQv>(3 zgYL>oJAdxfMQ}(Zscr&zIUGH|t&3uk-_x6aF@Dr7*xY_Tz2Cmvy*^|f>=@=HxPgBm zWWY6$@j|sjqS<8SeHFfd{3iouJ||qM-wa%RGl2RZ47fNs+u8iXL35&lT^1u+$PUFN zKT$8LwNfHSpfYeK<)wd#fymfIaJ0pyL3CYGsPxD6kF$DQWAFCUZ? z2jlAfh9@8#0sXqn@xT>Cf|tbUDJI6`>2s1=<0+n5Ch(dvLjJZqt+hH;r_yNMLRErQ zt1W3-sX1QMcASUvj-BKN^!BTfr~X8fF)G*}yilrEu)-WoCxRAKlSgHE?n_yCk2{hW ziMsRUw3nHDSBoFS+t?+uT{nHtv(N*x0kIKw;`$`v-bt&*#sf^jt0Vo{leW15bK0>? zjAz;pCvN9tCWYmWK7#s}T>K4Qq9$4o7-GETnG_`(ROhybwhBI4e3H4=s%2Xwm5Ear z!~42JQ7;Zzsyxu7ZLkL)^g6D$-rX#9Q}RC}${aVdl5Un>-MWH0mx4m%sm_@&El=1OKMc&Cb#If4$Pwp!%9- zzDE>T0|6oakBF1AhqZ~*KP(UHOgL_gqHmQ^fB6qkYp5qvYBZ>nmQ|_!iTtA=c{kYs z%?cO-%Ip_T?wWx#&hZoH)2DvTQa1S{X=NY?7SA8<=~H1#g+@8n-W)j=HIjQ3^yYWy-PY;yIOeh-H`EKJPDOo|D7``?^n1%foH$_hf-yM* z638YH+aAg>TibVMmF#Yh7U?L$U=C$4qmB@PAWV8wAWO7+-H$0N3>giyK!R9XFz@R0 zI!R@;+&_}=))wlD0AWxl&oud)Z1gh=JeT%M*^F%C2E#0uiXqN8oA`h-fp|54-Z$2O+4fRfJemOvGb74SSsZuO2mU%hL~JI9g8r6sK($4fz97?xFJ{nMY>%iL`OyZ!P*X z?g>E0!Eni1%&*JKxZTPni5gUok-Tf8lyD2EvGz@FdwwC)zvJ9VED2#675wDv60h~| z!G840*(K9=>czT9n}XvY0%$b|rQp zuTBoakTVrOY|@*4!PELSoAUpmGQPA?um!5Q0{c$fQ zNAElabg4%zJ2bWeH5bpLPJ9s1Bp3&2SdjAx&?2;ibZD3?nJqlJ=*F0PX%2sCCDx1s z?EM|5g8W{VPhlJvhz^T{`#OH%&(%oXk!0aMud4}Npg^q@=RkdzW1K+tUgHQro4KRk zU1iVTT@w7?T~u&Dlk!9vcO2uwgUo1Qp(d2@@DuV_IH?7+thB-k=IWt|vvqLb1qRsT z1t-d!c?E0XjeA)|8HyTJ%%{e83BbBTK(TIS(qJ72q^JbF_PZEUerq~bKfS7jx3_oh z!Jc-sfIY`NOYQpbema@<`{edv32NE(UIvzvMr4nH zg=+k{!HXF;Foq6N=W-yB;dJyNzIyF5xhS$_;wmfLP59k0FOoa;=;PI=V3Xh<(7M;i zqBOu1q0SJ}2BR2SDqh4z;ejPdf5RZ{5}eBNpo5%Na39$QIY@!O&+M#++&T&us})Sn zlh!JA-kz;H;Pl!QxZdpi(9ZEs<+3r6Zd7z`)(-rx~p&!P6ln3arN zUz_5gqouuZd%PKxu_{U)rqF~dv{Qe@ZqNAB9?u!l&lBNq8<-s`;~s0$hKlt<8{j}I zVdV4%a8ehrh_Kfe%_t&FeO;Mxetg{Yw0Cv(IP&$M$h@OD6gb876<(GBiz#Uc(Bu`M zi<-A#Lm6U4E5RN77QYdDWmN$w)raS6h`nKFB#LYdXC4DM&=i7?RFkaxLGJek&&kIE zTadj-kOlaT&JBJ|oytz@$kib@SVVu7y*|v$8?_Mw76gf1I5>0L`3KET%6Y#({-C{- z75GzS(I%nfqSkr*>Hu-YWZHa8rB^JFH1!xwD=9+<)kC9(=wbZD7`LCiBq82+N=l~h zhHO^4kIoo9gI01AMt1W`5`AL52XJm#CE?Q2N6uldfOGnV!#T*9QV}rCSX3b};;{5I zw%sktjeBDK8r#x%$X)nR@^_n$9 zy#~VD@~5oif(OKXRF})qrr-y-wK^tZ%x<$}~!#ez4-jHZGk9D(3i={tE;_yXbOeVI$J^noU-ZDkB4 zf41SQal=U2GTq7lWOGOGEl#J4qM z4XAe1(15OTZE~AmKbybpB1z&|6p{Hy@hEnO?WhuWB@Jodf98my;?nuHvM~JHjQ<|} zTKDMv43eLwa4_%JSc>Y{0bJZxWKaEp12#`7i98JH9mnAlp%={V%}&rC!3Q zY*#rM+PC80_%AP(eq;I%0Y8UvBlLIPjxe4)^W41Mz$V4U_1BJubdsF3We{-nnP1`R(MOIn*H`)+SL$71G+yoU0^yK)wA_CUea!TJ z-R}5(+^_V0J+A0|mcsYhe6b^{d41aXF7#~hYyWv3_jlm5p!x8v(Bt$!io5j?ILHBV zFK6H=a~;8AKeX#8+ElB}bYnrUd;E&?tn@Xefe$ypEoc_jYDd_X_fMq@E@Pk5BanM^ zG=SRjotuutuIdVjkC9TV0(Yi2$b@COKH=eoe!yNxHZv~a$+=g7tSXinNL7PM;7%vs%iIj)>wb*@(QfYjE~cO#=2+T{+_SYYEIYIQtd!C}Vc9Vw zXOH4R0mM;iA$_ZW+a5AvxyHYFqfn10(%L?(V%_4)XhsOS{4fUHH3_NvxAh8Qwz4#i52k2h-;4N3RKqd~NexLS0Mi2inQwD#8Y67E5R6=eC z`IFp|EsN338_dsI=?%HtQ1nc5ep9l(Mq0~8^Jta*M0LkLs}0x9Wm9RByrIT&lLau9 zASFELOg%M43q|{4v#hCor9VeWiX@izIIP1Cr1caQ*&Kj1mR(&M*hLw_DFG4y6^H5M z!S*c6Vmm8Dsv5g-EzX8uI*x>wo{l-uhLgrNs*G*IQqHtj^}8ui0~tu;-F)t4Yeg`Y zN{ne(;^4r$6WFwYSl#j3&{9IvYdqnVt%Y{s)lGgfe2c}`eG0eDtZ`!{D|e=|`Zj|( z`N+b|sY=I5(Zec<+eObx83hT$!&Bgx_=`78-*P}BLZ*rm*rE9!bWx<~w9MK36HnT^ z#Eicv%Q-9~1gfC6b_IGVsdb;OeU6|IAArizr#VfTGb@ckj^GK?MuIpAuR)RctWtGw zh6p&HQcL4kpR!JRxZ&>=5eAeju3gC;)S@E zy7;q(bRAuVEsnF2jm^mx!|n(3uTHe3;uRS#{O#Sbp{;ff>XQn6aEWj-%jueEsK&byss>T33r zMfMEWGEQ7PJdi^^0vD3(m&gy#y%n&?{CBABj5VE^A*;k$D5S-(A?~-yw-3Jiy>oVg zA8`1{#8h${f*+Q20%Y*7>7@$XZR{6%Yf$mZ9Qa1RmF5vlMIhK)wtbGdww0MApaNgZ zH-|2XRH-+#H4=#7j671z$U@vu=~1e76+~!^0^$U12UJz9njcfZ7FY$SWCbp^#)3o1 zR;h=cutsH57D0(oLFtld4M)OUV&YlWOhE7rmJtL7(+LsBNYRNxO9C-3^G*5s$Cn?` zyE5bqEyuLYba%Y(JYIuu_bTS73Khzmw(Xi~E|c%z{mTK`wJYaOXC*wKeFjjunp)Z! zF`uH{N~6vKPv?afw$&O|FYaQW>w#0%vSka_hb`&_5XQZ17&o}hkH4QP!q|zT?C5uK zb1rS&wgz$Ihie&j-&Qow;R)>on2JvKKr|_uc4kV_;-Sr2srPV!c77e+aKcm+RMA%( z4k$HOEu*~0NAUr%#v1^XicPUIc9G6nqmmNx)oJ>&z_{%$)I zWC>*|y^6kMP2?EXlnQyzjpTjE!8Y~q<>BTUire)822%v@;`BMe<_RBGo`accJs1ML za+v1QRu?8t~(5OppAo)HUm@Qa;XQFW@FrcaOJ zw3W$T)nxs7mG(A4Xl{@?qchzJvwaY;lS#IL`oh1oKFUXqKq$hnX+{OzJMIm?Fpn6K zLnrg8jpEXo0`TRy3fqI&`AI zHh)Y_kFT=sbw_e#qs~?3aiUs@tQ*cPGqY1W`m{GM!|jH3i((coYGOgl&{t}*-!C^k z?eYF_;Wj%UAp4PT$hL8+lv|_YI9L8Rgyrwi8rBV4==13|#30XHPK(4lxYXer6*p$e z8~cPlQv?)k9|0Afa0dvjC(ry45oSz$iDU<8F#wA;mDYj5M(u@QV|g4=Dkqt$m$!A; z%7eYbJmoM}C5clu9a^;o@UcpZD;*|G&j-4Ri_Kzt^HPjOC>pO#$pqKXkvIY|gHBLC zb7ozEU>$rQW$mDbUS((zf~j%UfvuBr@v!k8vl5vR54lHd(@qp;MHU%)bHi@<(;!9= zA6qW+Pcbd2C?8OpV~NDdntBnPgl_gRMTP!*+JL5o%TdKvPL0Ue4Z+IxbvXI(MpwoF zC1!6K=FyHtFY!r|He;BSIuk!rmMr=_vqlw;BX&W2dOqt-OuQ#|B2>joee8{S#@ag+ z{qkkwOFbJQb%u!m7&fjvbSqqWxUY0{Br*PGV`kz4$E3^Xlhw76Y{^$;WTxB{ZUl}x>ya8EZ&Gpj)P-+7pq+3*%{;=py`USM526}zJ`|Tl> zVK=V^tSG75(%HViIp@D@W;C!%s~?xvfMeqG>j=u#ks1)2j4Q6;3?98N8%Q+hN0pO} zY9_1JNF7C1<(+mrbT>fJgv)W+#w_}FWmodPvfXAW=d-7?6~wnE;kEKRd7L^ZFti1eo0HR1r&Xq6xircve`Px6s;4FQx^%lH^^cLC3~feILvfhBIsgXd zig?D-hLbZ!SJ&#^4@fB8puJeq8HuVbz&0QM%XN&=!LP1<0tRXmg8NsA;$N=gch$(n z#>Ce7pMS554=*<~u@;8NPrs429b&|{D--WDI_A5as~FkiMocS%3%0gSULH>(U=yuQ za6^fZ`V~GexPYlQVr!!ycsBi@f~}Z78|$E_o=U2zn)e%ZLd})&Yx`ccJ~m>#dfneZ?19|*c;DJNAR`R;(8Bk z=1Nm@K3<|D6i+|d?A&{qn)kl&KK;IWKS%o0o}@4M>RRh-%MBuYlo;?gd%f;M-7=>> z7;M&Ao8NMNZ_kw%bQ^V2P?VByTOwTMu6A1NSGWFlWoN_BPTy=Cn~lizYxZ+AbThJq znTZm8?&jud4q#|?JG4Z7!+pD{Y9%Lsj%6zgB`4q6ZgO+JlY@Nf4PSbWV;gaeiHZBU zGqT>XpkZow9}1fErn?W;z4{~kb4)6l=u_^Pfn2RC-S=sTzJ4_B59w^!S@)7SW$a#iRv=RFPM*h5K0kPc`Qur=zk4cK0*gqQec zZvr!JugYF(${O<81&vqRbM-zt1Ao2d22_!Knq>~N1)(*3i@O7#RGybdUpsF`Kak2F zp+@bLr{fzx!{E9icnHY1eeq7tSIIm5mmuv0e-{j)l>hPxU;>eluUhKKQ+<%{2Hbc~0 ziCyTmKJts>FRrX2>yN-EmB0_7Q|${6n5G#F~Cp}vev674~iqGGaM5bs_crRwjQ zr_*iY?|m73-+xE%a(+5l`0{)ihMG1%o+x?~-LbuR-%>x=o!-Iz8$LjwZfe*OLC1?Y zA~~Pze!=sS)M*!DMon8QmSD?S@GyKa%Luv;JMncTAj}fFNxV-`tG4Q@aeVQ)Sc8wFJV{(q46UN0|U+Lr;SXkzDB!jsz2qSYjTO#BTeqsEa?% zC06|OKCh1hMJ!Qqrc1_C2)u($g(81{rHho}LdW4`WNvn!>YPND%hblkT^WrBF<(OE zuH<&7;(xvHmmxM!`*tz9q3Si6^-fQFOYVFOTz+NqRoz|L;()hM)H&T2B%yjCT$Eyz zyqpZ*tKAHRytOt`5Y8U^IvJmiW?Z$d&9G}?`VJhgJF0YVcfv*!1!;O3K(I)ID`;Roj(zCg0c{A3JC!PrsK{N0~X`?{9>>nKd|# zXsHpJ=HV%ljuAOzi$+vz-Oc_&OAY9&tu;$XMs zO>sPc|4>}bXuGA)#!G-9$6K4+dg``2mHpF@IOQ7>Wa;DC>SF5pI@l=In9=LPr))qn zF;}!02fn31WcK!^H1&Hs&47y?_f7Qq(pLUx*h|>{gm`kwgivP)vzmcl{qOtc{w3;K zO8c=ZT2zSUuPq`O|736GZ-DX1=3-x@} zh`S+KGuq}TYtbr(Exc`hcK1eyccIHU4gpAlxlUJ6cdGSH0eG$LYi(HB#zNUGbYq(S z6zyi7uDkosP9G+2@5+xqtNYbTYwavi_jy*N!bM8gUF?NShZ|fDjXsx6>lhspg+X49 zoh>Wdi>NydJ_FWW5~dpH>;RcdoY{^9yX6jqX1_VlbOF>$jcs8|rPG89p#_C$_2nUT?%)8hs`B z-MNx-F>*$Doq2%ILo@l{-BR-bdW$Kpf4V9SxW&l+WV`Cer2cbKQybsj^!R#1|j3I?|bl_r|*Bvml?^l8U-sb#?^cQI12N+1@QT=XJT0^k@*Oa)VU zPQQt@k&r2Bii7QX0;39Z0sTufrlB|!rA~M&#)ed_-G0_J=6KzBg(C^wo56ieJ8b`8 zXYiJ<%>%SB@r8!R=00=|bPBpu^5%f~sx{uqUrc^iOgW{uVJCJ(gU+OaalmKkBsOdinl=Aq0S zd(*x*7$m+Mwb+|=9~C2oHz;m7gIqBgk?Q40Zy%s2Z7yV%R6^hNX>?4G?+&~(O1fWN z4>o3-xgKXXX5HQ_aw{7h)lY66#LP)VV0c?u<0VY5%7I|~Ey^DM(u7OXWUPVXrUDBk zUlVq%C!+eQ;gkl~b%Z^HW!cZgh#(iDL4GfKU!Qc5f{tjLPA#4J@(Cw%DAX!fxM`LO zx87-o{A$k@?Dm|!bWW7DtHnh(Dhrk9o38FLPifbO<0vs>{q}e7BTgB z8trO}-OG}YBr(WYPQkt8)=RtRQIS>l3a3FPqkyW#&Dt=r#yi=KoU4TQ9l0-TB6F#DW zt34Bscq^4cHxXR_=Z9hZVl}O1Xi}SN6(()X(M_+dpGnp-*RB3(I;~`TMNdeZmH~<4 zlElxsM|E3Jg}pP7L-JI_1F2F%tAGmdiWQqO>kg|fnyrhCniZP%U7JlXRef~pqoW%r znBEFp{0=!Gk>y~kT2`md4vtp>p{d;Xe4%>q{Wt6GVX5c)#S`zhTQS(UT!H!JWSSOa znoC^n`H1tO;I;a~%L6WqD#E-7f>xh~jKRfu!IsOtXw9MNhafV0c)h=1GjT;o5*yi! zNB5VQB<}P1Oz@(gGgM>TwRPJAvocC?hfRw`eS@6}-YdpT4mOQXM}+7ECT9tRNVx~U zZhrCH@HKt)Epp@Tc*mCcn)&)(fn&6MJ%h%KJ%@D=ekuHTu+iuV5CK0p@ud=!{K@Uc zbzV~ZR*&+7tPZ|639eQEdczmzY~<>>lp&WCtn*%*=_2M2I^Vck;`N3j4(XTEUz-r^ z&;%^mlT{Tb?7`PY)l!35Y2ap|< zhQsO!KO6o`lS7BKBvPrBBTNF_$ymIZn!JMLk@uL8w=yico5hAWxmG&@Kz*bp-@OnPh;Og*o^3}&@Xu;VH#?62}l^}8)fh*gH?=q;oJu_JlG>$eHeCN)sUm9 z^I1(ZJ7boe3tB!^Q<$d;z=X5RR&()NG;8j0XlUKcLjxy&)>hAK=7)mJX=gp+2z-d} z>(!oUsdjRw@H?#F*op;Ck3vqe5P@oSrjF-wp!`>z1&$ESzTLepQ2lST1XMNL7!X7ERk*i(?Dxg+}>FHG3$@JJ^eg_)Q;PTR94R)=}d` zTXzSzN>k1THK9NI&-ZI;WuJT^D2cnSw4sDj;TP;m!c~;^gXtM{%|hkq;~nUcSh#g4 zpu@VroptWk`oXW|QHcCOJCu#WUd4La2}Jc+Tn>V^S%Z{pI$C_gCeqwc-iuIlQGQNs zMuf*MODz0F1Sr2bY1i+XsY))YhroUXAs{avGu8gWsMM^2pj92ZA!UCYCb_VkEoqQm zi@+~QpfiS@#pP~)%b6RCX`zo2sG=?s4>^mNxc|~V!*-#3m_F*MrkB4tb7=~z=h3E< zZx(=8&%fZ1+!wHJJlj;F@UxU5te{tdpaz*Q)(2w`Tlt|>W3)klEX1=Bq{cp{EALxy z6s(#?hly=#7{y={BKC}Cn9s^M ztVWAx=7Jv)O0gKJF%Z}k(qgKz?-*0)^jG?C*6m7G$z*ji?W1%JDi z2D3w2uwXnC#-EPZdDn1@&<>)rt)gOl7WV5Whh%b;5cAO~Y}u~c@1YjyH>^3i1pFA_ zVkkhbU*lpH1%MfW4S5CXXI9s^0#IvG2VF*LE&3MQV&p>WVekxBx_ONcR+o`SBMQ^2 zQ1?t14>7v zikPq*CC3J!+>lH)jam#b9J#cLr#!V{od&B;E&okH(wZctVr`-N;Fwwpo!G#9*brQM zM==EqIiEgwpGUC55v5Wp#VRW{%#bVMP+>>qQK$K;GZIW>+Bi$IoXg6ERNFv9 z|05LJ2RvHlJ3t<~*Y1e}Beo{yPRJU0Jkv);4Q*tdaXN5nsEf8Baj%CRIagSGLBYkiET zUIO~U(NHC|Tka}T64Z4ns#c`~hY~|Vtd6T(ryJ1g0%VgfmT0$ z3QYp?`My2HXA+4Okb5@PcSXhRlEcUp!VDTYvrSxwm;s|W=)#%pOsCW=4X<7rj*68^ zv)>xm)XN(T4I1sBg=yPFuUC$T?ks~Vu-)a8wL|~$SH+y}R#Cs<_!&ko3V8&|cu{$8%u_9R4ftCx~v0f9qz+3cTz*r4#T^g+Ri+6Sn%IT;`SwsGC0i)7B>m zM4lORhyKoHxldSGlacZ0cd(nuLUVM=Dtcw05PO@g%9uU^{}rxL`e8*AMPukZ4+XnvHX5O+P+$Q}9$Y84~NzE%R1#q@wbfO#dEwuR-v5(TyrZbfQV zjuxNV{7;<-k#KxkCTeHWSw)g*+eu@{VNO_ZHHc zKSFzG%+aIz`j|_RXIH!)8_P2q+i2n$cvfD+$0qNiSyaGTxv-}7O6?gwJUN_w9`wAv zv=ROmbB>1*O|jLQ@2)1bR5KHTR>rl^s|OkFVzGwRphlOUh*MzM4P_)Q>TYcW{SalM zj)$aJgu5Fly5VfV7*b(h)O*~XPP&;9UOipj!iZa-m!W~LH&e4L)(}d}^#Q65of_A- zCd6`K5p{g}FA|k_huu(s{S5kP1--m&b}-+%pOsc^O=Icjc)kur*btxL*Z!q)FjYCN zWO|!KqIeYxC7DKrQF&X9OGI*KcdA$2h`PMHk>RaVP6je#ayZkc7dRcAw@*QBcd#)5(%us%-YV z{&U^IXw4X6;2CaQLK^5E-Bfzq-)!DhWv!wSdqrgZLtSM{al%*sNZKDUe5Zx zlXefao{@k_*kA#obOY@m0#sLep>eYrq1j5D%>bbD=47(;;;-3SMuyC#UF@vxitkYe ziW<8QZ+S^o&v5QIT_`X&{ZZ1xgXwXrdY%twU(~|~D@w7U&hJ87!}vxD1Orn{tfIQO z$_cSVIM5`g{_5JAzh^l1H&Zu8G!9DrdMLBuZ(t|&iGAVm;dHtjA8d(npVoB5KUjngusv4m2#pPui$F-(k+o}lOJIr% zl9a(VOo#_aB9`oEX>LG^K&dpOROnPdQ>iy@7-6J>FR=E0f_(^%8=MFuAu|!|i0Mu^ zy6B7u92RnF6jydo7GQD@;qhWLmIKN$N`RwKaBdaYDPrTW3Ko?9_T)c|Izjz?j$)p@ z1_wy5+|fld%}gL^OaT(w&hCtVq?&zK{dx@PXR*2;s1dux* z_eD>G(>sV`n@3@WRMIE}${<{^mO1yhGC!3IPdluz$_b!jzo67HiW2`umuf{=oE5kq zJQ|!~L)~r!GY(oO>dD}DR7@lQV{vV?o&$N(iOB(CtufJaf;V`xb(ly_-OtYk`3|9W zol0?|64&DJPSY8zxP%_+rPN$F=i&8N*BoqimK-0H|BTiLvI;Qi&yiwlwE2}zGlM`MTg$8{-uacv|gs>K6Gq72k zsgVaT{Q#sDqZmsIEuctlh^ogN&p%*Bso5&iOSq6u+z%$Bf#)M~f?y@=o$ohwljy*~ zw;=}1%aAVXsB-JVD$~h>#`0@<;(=&LlFR=pwEeKJY!Jw(M;EK1ln=Rz;HyJ_Ulo8Y z(0^c>GelFxq+W2_UzIygyjnl?qn7Q(*MC4j7S?%B1$m#@e-BFu8Fz(42`R9bLJzKR zJa3gfC)O5|PClweiSGMpQUQlZu;hSnW~+p)$mJQuyAckS)a(yAGyAsA9%q_HAeGw- zl7ue@eS^_Jp^;8;$+>R~({kg-`)>Hh%_t@a4G(T2y_WF6muRb5b>4H4V47Jf zcm~^#77BLx27}ekfR8i^Dv!-G_xh96jUHRI_cm_RjI~pzUOC zWpr!tIff{D`_5Xn@^xnUe4s}=`EM}rbfx2S_AvIo!(MXVuT7eP%1OG= zJ65}#AS^4aYJpzWS%4a`Vj|Ylgr^FSms7MchbUS5IGXOw9X?%bUCfoi$PJ9fEz0fA zN#z=M8bFaDo4z@3o?5k@AotX}n7Q6jU*5L+aeLkMPwy+$^HPVMwv{5Ia3}L>KyLCQ zT?EsZ-M&|soZh>)4QRFZl%o>5@Funn;PIhWw+2!ch0}NPj8LOfnt3~La64!C0wdlY z-5$ebcuc&bwP{1gnG1k+>U)!)bp_Fuf z=S|akxVJuUkB8S_s}j|004VE%Ah+~5^J{BGYm+zWwQNXeLj#u#R{t)HIo zC_&*=vFbL&xJihYj2LH+jbeH723_|=S=_yh>}fvEOm8pFx5B%PCXI-T1p44)b<&ik zYZ6AK6iB8b^ju!8F0WugZ>9TLR@^+j|D9Ky%z2s;w&a1(9zx?p=R*Ol5zJL8X7PW) z+{n6)V`n7T-I}|d!gUn+*nE8BDzitlgJb17bGBy7b7)PSgJqD86`B>5%qTwa@bGSA>f`*`fJwVTB0&1* zC8~KsyL0l~H6!o0ITY;RS_}t$I`9uA%+K5+Vp@ti>lKDJ=pQ0a+%CYx4%|0zu7KqR z&55%P6BTDw#+*s!?80Q=)yx@=cuwdCL#muE{o+zk`$6S8`?&X6KIfj3eu+)c9_o)U zY%`LM&dL#2I0j0+R*XPRC}YG?CIfXcXTzd%<&^}9bymJ#jfPFO<|viLCK#TB&tQIxQv&Uq=({7q z1gg)?e=mCzt(7-R`qCsKUNX89CtzRvHE(J25yonHP*Fz1{#k`?a*rP<8>t5F1H8Ib zJ%#{ZOLXxL*e(usy-}4)nR_qO=VvEbe*_tCy!vZMd0}XNr^`+~>jU$T~Bz=xU^4LnQ zLQtEY&diz$u??jBv^jYuV3kYe1^DA~MnFf0JpQ;p*w@Z*s=M~#Or(^)>OF!0uyZ2( z-9}!2QmmAW-nI$sX7$#2nfRF6JqB_7-m7HlUPr3u9GTb|&8+K1Cqy(j`Akw<>e zO@7Xf&JzT6VwzIRtTV(jiiC10Q8nc9hS1%0*&b7%PSm zdHM~mJB5&kX`ndo9W}2S2dp&wLP%!&Kv>(BgowDPAJG}pEizK0>Kn@`9%5ZYB`4pt zUoq@+kenz0c)5mV#*bQkjD@QbJ{l!s43FyoFzSIDGvWcJ2IteVkk>rf;J zJ^GLE>_}pwsP;OJ>RBHi@nxvV!q=3g9P{ql|I|RHaNV6KVV|7=2|jOU#_el%906ur zC%vVD988^SxXt=Y%3PTKu_&gb$q4OZBukq4XT1Q+p+L{1Zm|VGVh;w+u(- zC;=EXd1Z97FNO}E96cv?rpEp!{JZ{^Uga%mj!y)23qaibqWgtN>4hmjJorlFI5>q2 zfiOb@1R-y*`!2NVP_<#MT3{-iz->_y|q()-tbhtXcH&{*W>U91< z?%NK_=)o01Yhm=ms>$)5>e#f8iR_Pc(oDm34Qz+h`}@Z6o~_3X2r|?mc5tU_zNt4T zjI^(I6kd78M{I6;R8iIgv^VIqaz3$+!w0m%US2ZN=S-d&>*sc2`Q3N)9M!$Eolr%4 z;-I0dEJbK!oBrI@6h;Y!AZj^F-Q+q=-(bwCY$vjg zz80mR37eY53~39XWBtj@m}GrKvYv=lakD=t*RX;4;|VuS{V!q>fVRtJmKFoK6`^2h z;Kn()U#^-+W7(F4NY0ed*iK?G-Fve|@$uC;f#19P^Wau>7Eg48;` zvGL~!Y(VN|giHJd74Ny3+-HOPA5#|x;*L1c?=5J-XEcZ9+Ek@tcyWfUn6+qd=et78 zUN*Oz3ZF7;POU!I8{;JVZ4TKlOrR6!3@P6IXUqoYL#}~1TJ=3bxzp%|XSpd5B3(kB zCLo#wBlFWBO&`|z*)e` z^;qZd1+Vd^Llylvi0O{;k-2=NTc2k)`>uO~80ep_%SjP#YIgZpSo{@n^+fntj^!4t zjVCah%9nfT?O5@+1}YMKL-7)Fu@^LaP2WVHtCP)N5gM59<$KW)Dqk!o_lGQpWw_Pw zsPkeLGY6P2tbrS`(I`1{IYO?1#qD-@e#H3&Eq`5}WuEJ{*yRi=kJH637yIeItJ=uM z8R-%y!+~At!kVIDL_Q&sy9hFF7)N&gw5HhK9<|MkZW$U6Uy6@co6G*<{=3an!Mf5` zU$c-q>TuQs&ipzdk7dq_)6+-UMfz$ZX75XUFO8_<)Qm}MEyE}HOi}Hqui#|@8CmYt zh){D+Ob$O2e5n3H&r2sCXM?j1AGaHhQ_TiTS|dx|{M1ZF{^KE}R9@a->t)_GZSEIA z7lk#PMp zIq+dIX>KXA16FG+M#&hp-{`W@D6O>WjX5*TGL!vPk7sP~36ooI?`L~DU~|K73~V^? z+i*{(8Cl1V>T4%F6~A`__-N=j^fmGFz>n1OfursP{^XK`#a+KY`&OgTEj4d!;G^+9 z+*S`rnZn$Pu(Rw5ZtE7*Sw)KCu-#Y0ddT9Ld!w>}VLm2zeDOgson+MqkIPEi7}nL6m@$F)G#T2?dIH62Yq zA`LWwes3Q#OQnG=#a-Io3diRi+Q1})vKhL7GUc{kHe5d$y?tsId%y<{%?gXK2V0wC zc_93lFbCdtv$`g=M-7 zT+>V0>{mE1_WMio7jb`SBfm*@#KDea!R)(rsS${yulR(YCmoEzyIcjlS#A95xi85wCd-fOD7sAm!%6OwZVsPF_PjM-)nyi;7l(9#q?7&_Yms2PE{&K8AoYcrt}2n`xM0HapV*>)Q$1a(nBP`jc&vByP+S zPZgdFzEXHE3$?XCagv$>CUGqXIohJa>0H*!y0*F$0RmbF+`3e6xByX0EFci({;15c zT(1<7NY?|4TmKdIb6JX*8HlO0w=n)zVUKkfe{tfhV&ci)3I2_m6ft*Aff75=lQ`!1 zD^=cIm6D=7!{?RfLVKNiOAmv@@t7%AnJR_~$+gT%WW}Azo1^|mKh|SFF$O);#=bqwtZmp`G-!ai)f#5mE&zLc;V3#803nVm*YeR zaiw7kn%oAPGSj@m5mdOmLRbVwz$zdsJOS^$Gnkrc?AKAkQledq)+jx0&-+|HbbgVJHXG(zx9lvYmGT&LD&$G8=F?hM$BsdlFF*@exFZ?GKu zWv&zRUtW0p1XIk}cx$Ex)NE_hwF5V{q~NKBj`z|N79Wx_jXcZ$#-GXKOEk8iwsBTSbf*NY7sE^}U}LRfD9K}@<`BvK&i368=f#)WH7|vjx6-AG|aGP!9?ALh=PsPjBb)eLm+|uLQ z#87nMleh2Prl7p{ZeqD?=I8d4NA3IHsWFNk!>Td>)k$~0v+m4CSc?kDl^Zmk@o)~o z#7->vQ0v}fmZd<{jfOYQ9Y>I1VeUHq1pX`wIH)}vpt$I^@`Z3;b`BwHwmsSP@7woo zfc@KdKBb`yI41YLRa@Bzg1`*oSmuivP6T{+q%MkYoO^pTNThaM8gYvAu%uS16?snN zm@Hx=)k|`V4%&R`-^UfS5Xxx`fLT<2K=fLIkb<@&2)8EMo?R0|s|lC3QGpT{wOv7ceh)(HJq{&9LvE3QHtj@0GTUA8Z(&$O5QbJ&6V)k5BE3ljrKH#^* zQL1$4iA!t*qjLo@h#kSb#iA+EF2dj_^s?K?js@{?V@n|(RGOp{%OpLH)pSG+U0(_=Itxr&JJGEGJW5i^3s3mt=* zhJ!ddzD-AuWU~*JN!mO5p1Rn>l!%EPtzra9Z>e%&V}W8ea-~n206wEfzEjl?DyOM+ z;$}B&y-ZVnbQQF=?fIU8z|+9EoEbJWXL9N4GFjD*Pd9)US~=WXzEzB+kic3dsET$n zZ4`X?964ohEY9*++Mdy7qdB&>(Yz@YTgJ^=Yfr;W!c&~(t>W_RlN@BTd8>?u8*nmbb1PC++Z6xq1&tddc~Okg zy8+L{u_4e^k4TNP;nbKZoGlsm8HOLZD5)xca#^U!K(z)f@nGc*ostS##-tW zO@w^8Z7|8yNtSWKvmW zQ3CMN$bj}Oa8t4F5Xhmta44@$WDKpk6ADL zhZ=CBObn{aU#o&%SH3t1t=}gcy{y6mO2Sxc2&_^(3zj|@jw=RrlFF^>LB+Ey5SAj~ zSn)8*31fPVm3%B){LJ~U;2N1O6kIrPx|lNVrAyJQMyHmZ+Uek|e70BeAX|mKBB75i z%gSlg@-yU>f9KBhZd3)L3;>?RMq1UPUWKT<+HskpN?xsP#Xc&-21gA|@l8MMlNt-- zltL@0>JXIg4ZBqslF%|um7-g2;-N^^t7>hpMbk>ZzXA^-#in~fRJAr@Et*!i)tscR zC)@S?Rh&By)rdMDRj;nu)jUT7v9vHu`nf67@sr{OqSXK(UG3M70P33*4{()4`$@kg|}>CsUXsI(u=(%zHr z(cqIe$(+0aXMp`7dZbW)!YU|P)j7($*;4e+@1M``loJoANsdB{=@YQTd6gpVDmc?R zdu#E@Jg2Qd6?%P8Vbz*Bhk}mm>#s6&A>;#m0$u@KS2VuK#_yczKi0@iZ*N~ z!cs_EEA5Ap!Efkc=vCKoo_BQp5D4RZj^ZFlYMnktE0XfAh5kq~oiK{=-@y2WOPQ=#MA3(JF*w6ZlEKxl zFp_#*5BU2P(%8g{sKGI~>XoI>X_qQWehLLO73e`VW)Nd|(7?`(waG10Q%n?hy^d|q z(GKM69|FPRIi*w@9sO?e5fy`Ac(lg1fBbn}9vg-@0$h&|rWhPe>K>cQ#@VQuuz}V& zu;WFa-O}g$=vHo@qGY15mO_XQP6!w)t=Kw6a%?|LBHG_ZjmCkTWX{>G4`-dxH$E^@*@*QY&(YU z#V{Qd7wH!4t_+Enn#f)6N69|6Eid*_Y+8|^a+7LMmN5wp+e^?fGcdl-eZ2yCox%wf zRpt2T(T=^rZBzG@*sQxs#wP(Ri)9Tmq}z3vZ+?QZ{AI0B)j&5xf+hgo%RUHY#r49^ ze`88?9R)A8ZNSqC2dA>i)w+tN3SwN(9RE#yqtrANT7Ep!;uBLUEUs1!;GpL_&{KIA zbO^8u&u0PkNfzd)60J1-zy(x>6zInxn1dHYRfF~F(Mlsi@S=KgVkdmDT<21%nv2n# zogI&_6R%YItBw4xUeJm+rdq5r2vG>`RCS&!yk1wQ?WD1{k1lpYv8Aup{fmv=ud-YP zb>FWe`AV;7VH!_>7V(OAhGIAt>FkgM81*9w)1yfnS!E7ZClxt)s~UhlSPz&+PzlER zS1HO3LZUhJg@P(Uhm(ux7}BULp}B*|Ud14iM~N*og0ToG3%M$gff2&U5b61A_O|#M zmI=E|oIuSMrX65Yle;&)JJvWjwJF#)v3GQQ;=mNzD*;wPVX`*8dSKt~CVDM@KQZ~I zO=J7^G~OF}_dr7>7HXy_2BA17lJl|+1C=|B~Xf=E5PAHFs?=o_u}zjj=KuQ9IPPCXQj%DBiz0gWCA zHC_~u=*o@uov(pf#rjXxIEr9GJ9v^mryl9@((Z}ziOJ0y>X9yt^S}|$_6*nD+S@fQ z9qB?)hQ?k)80lgXc*40{2_Jiw?3WEo&p(D^jlJkRrYR!n1DO&)O$od3@N3<<U4tZ;1UQNb{nQd?k*w(-W%lLR99mz+-M-ln}{!9{)~6dVXqpsKBOs zu^N#Kb`7Ose4iXVgi=e*1^L3Wusuf>7hjiV8uSA$-;sc?` zuvqjvXW-^=(U)0Uti<);sz+uL7gQkT^EAd^oNA0Wb~m-Xz%3lxKQ8t2dUT(-t{Iw1 zgbdEILTC`n7K~I_sfd7@<8E()tB$EAs2OUVI#Ip}^hs>jM6pFv z7ZAPuT5LOL5xkeC9w0xM0rCjDM5!qv;4t@;#Q@4Vwqsz3;$_D^0F!xz09ON4Y$r$e zj7_}w_Tv_Hgf6n>s6`6I99`mLqSq0K!4#)_8WiH z-b6TQ@zE^4U_jh|lpOqu7$ce#NkaOmZd6#^vSXK^(NPu!fTz*Fy{K$?|zLMr=ZxaKN_;8?D^QYQS}mqRRD7!&_2q%XW%N zwNW_J7qsV|dtUpe@#e4o>FwsP@QuRzyBHcw^>bBb3X|V#*`~0*k$Q0mtk8<xWyY=Ty6noz&6eB$lpiA^{0Jk3y8PIm{cS9v_Dx z&#VAu5}`MF@vq-5-2Yqa)I$vZ033R2`Va#qz)TVf@tMt?&+a|~v@l>Vw2`U(I~(sc zb{}Xq&`gA>J-G#uou;#-mOekT@aQaFB0F*eBe9k~|FfEPOox04Fk9kIepz9ShQqbaVQ5Wp)h?Sk-7yIz+Ai7 zr&1Ovv-K=ABA!7ipXTxN={Sn*d6pjl5LjyQp)V`JBn-x{oNL;5Zm@a*mZ9ekD!TFt zh9)~EY!ltW4lQb@gU-{GP8yP#1UiTTs>~|Ic)7U<-q%o3E?j2>LsluAmJ5Piy$DGU%*ZF0SR(N?bO!+& z6cKJHIGwU0BnmTMs6X1?7=P>K(LXil$9pFBHLBGhIf)ZRwC7Sn5Jqx4fM*xHV5V)^ zxpaK4FGeU9{VS7u8j~CXpMl@Y0&Bfd5n$n9!Wi~m@_Z6wT%jd;f$aJ0$sO5OVRjOR zn2m#yQ^|AO6m_@#HP5T{omxqlBq$fpPgbgF<-xFD17#>X{xO>>N0yx{R6TE2^YGj_ z2rUOKzZJ~@;mJlnPewy=3~(QoKk4J0bDXHY-q}FW29N_QhaNlcoIiQRJ1ZzuJ@L%M ziYphes(G-s;Q%*E9=36jVz!)cl_!^Jux`0oL6s}KD$pPz#|Wh{6M)3KwkfI&6xc0I zUq$=6+SO!Y5-0(*w^Uj!-E)Z}B<6~8!upsn<$!&mJg)#FQw@~t2{9+WZV|Jr^1AT* zF_{SfbP~;jGC?Omkx^0Q^Q}5}R&A>gWw+1>%@rum1myYk-1OcxE{wg+3zYJN!S7Ld zagb)AyCo-iAzMx){(Q?mTBsrZ!k+g=*-PN(b+OVjRIIdh^!K9y= zXStkXh59>Fw>Ti3@G+o2I#xM2w4?wJ1LH9B!Dm)hE+@%*TvBSDeujAZ*=AbKGf%Cy z&9)+7q7@TrCADn~flYE__hhi2MwOsVFuo>1V@KCvDIxOjS|#YjW?=A9Lz6kBte9{Y zt~zWICmBUJdB6wpn5F5D%lDIRYraZPd7Ej$V2Su%)M}+JZyRuV8?ZNlJ1#=JidHWj zn@F_>@t`K!X2w) zriT8VP6ZuWsq~)L{+C2~_eM)8$~~IrtA@79ahYv@qFe6ljv3M&aj5 zr(s~kFEUH3q&no0XqD5@gAk(@Dktm}Q_euniQ`b7a@H*j@9oT8XVy7t>K|e>73-o^ z(<>-&M9NQ&?V!6R1_UQ8g3q5o2dN&L$?kr{%JEpL7V}mY=Wimp487L6aI;E^!UobJ z@=$__B$!78bs+EKzZYMA`NchZG+low|DQ}__bLwEK|>Yc_`sZgVQoWP+c00Uef&>l zZ8Y~|&IB(I=~+AH&vnoZ6j@zI74wF!i-|4_uBr01*FiU`hmmpSSTLOKVrrR9v1UnS zq-`;6mJS!?g@vcPhs%mI)v}QA>QOZzXE7I=(u-EZe<_RMi=~$=eypH9iHXsfF6OUE z0@D^9y%dBjZ`9eFd_rj}FTm8wQhsWphLR%Ru;mafsPpoHlC?@ML$0EfYvnKpIE0>qrsiU1l3P=IM}YhHkNB3 zW9C&>4XP!kuIuV>%Bp6|%ePof8Zf=U0I<~H9*fG>jWUTS6!fZ??xu&CZkQ=QFe&X; zV6rC4?aj&GcgkCPKKW-&fgN0w^ynRUa}wU2Gsw5VENc`B%ijW(-CB%M+!#>4F%I5%K_j%} zdzF_$wXjODFh)58tWo*$MkqmsK^a+koQ73h#`1G5%0p2PSCj`ML8ug$!?P+6wgt2$ z#6bs2-%5GlJ6J9c#Vzhb9vtB7=_pGalx>iUbpC%uc@W=XZF%T`@|;cE7b4AF^+6WJf>8plX0_ zwN9R7wpjboUooXt8=(n=5sl$-paz>cQ_5wds8o#I#FiFMx&|;Goz*@c8E$flvXA#rq1@A&t zkAa2~Dg`XtA$(Limf8>O&O85FQB;g??fcJ+c3?GnY#HsTS6qmIVdNRZYaB_Mcf-yAX^By zFe|iHD78Wva7BS-gg`~+<8`>9*tJ8;*|j77J;gO<5Cp^%()%M>-bdA4QfDr#ffy>D|_uSvDOEPZ)V) z>rOg&513l_Z)ZUFC^p1Xm*B?IHZdINo3maf9d5357r30P0X1qlHfXd2#-e z)|XfCEnaqU<~9b11DKhjK<90FYRN9ca$*;cExspvY8R!2&xE>nrL*oKpscWGvn^G7 z5;oHfgGAU-Wb6QYhBsrlA#9{%>*8ae8)bKA&>MoCWT`vN(D0k|!%y$3J9+0Y3DU0;VhB(P42QQu@q_a@4=b9)@wPz<*$2JN_`zK=}xAu z7#}clR5;sB2*v1?HVPqKPXav>#JQ8cRcRSS4^w1^F|RY?Dl0byY8O2ByyaeW?Sgk3 zak>pt6-%YLKKk=6ZqXHQEOU^i;lw_@M2DtGW} z$7L40YB<|Gwj_M)>A7|~_>%A`;cYl<;m&$J74TLP5Z~cr$#OBN8*8Yds9kU=)0gn< z({8LGHYWIl%IzSME0GfZlwEM-1JR;J3O8wqcl-B5w$?*Th)Mx1()ABYi0l_J+D$Dl z!2HGh0kuM@UGM?B-~eB>bs&E%Gcalkf8BAk)|PzHT}CN?1Y8zo_jBua*Vx;r#j3oL zV_{qpPk-~3;Bo_el9rglt(l+CPF^ctl`1IqXJSapNr{fx$436XwLI1GG-!EBeH4KE ztU!(P?Z|RjqRgG^xl2WfvVf<7pq3DT>O-7>G?eO5(&GklabiW2)ny6rYJgwo5tUk& zYFQevEa|2Z1t#E}yT%p0n-~xfE2*d~PUw?yB8!6%aq*<}80F00F?2<-G#v~&0$_2G zG2lPrM(1SpaQKroU7XC2SfW7`&t-S(67*`==-f&}8T67lVgHMsIE#HAAfn2-7gckIm$4kp2?7?tp3PRC_geIkJz5hDuZ)*sAHd0 zBh<0aXDarYL_|;Z!fjX*vHN?13h8bbC0@PkWLpH2iSvuMmetzk9JI|D z2fB&CMbWV9RCQE#+HBL*F`7iEC+|1@=LRvlb2tP~&G6%G_^SgaQi)+~04+&UAsE<<}MBy&V&^iPo=)))N*>49xHnNBPl8y=-mH?q}CLl*l7XPY^pW65tu<>I#X@o?E5MM0_KwfcNT>wl6 zAozSF-eewP9cIPLYYISFj2N&!1`vp(1-zE+dI=g|it@Jow_7!oOfNiE94bTX&@cl} z+8m2+0vbGLnOJFQ^g5A!5S}*SdR2Zv^jZQegdS+0iq*=J6Il^GPa~wF9mXT-?_Z8< z&?#2YSfL3(Zs;h#7Zgab+%Sm%2$mo9KuGC@A5x_RfH6UY8uh_ZQp}QSG&NIUU)(4G zHdW<*{Z)>rm~1Liqi{%O?2**slb+NMNfApYh`l(DtM2=-DwdAz+n8)UKp-VL4sqKn z(JQZS+o8R(?NX9SqZ2%IrR)`H5EfRO;xl%%Q4tZ?;1DCY<^s8NA@nEn(wliBQp zcrwMnm>A*(ZYo*=!&wrjL)*kq(QC_TD}JCtn~gy|#O7#`gF3nGufM#J&uYy{L<`dkn*MxFV2`D(M5FD6 zHpW~l3P+~}aP|F*g6%stmJ+&2bMzsd9`>Hb?y2oBg%E65n)i;j*Yn$83FaB)j&Pa&5#*9?BA4 zE?Sjb)0SGvjz@eu7V|=mxB9!z8yX{HnIe5jY4V48p2qK)`XY>oNyZm+3^N9a_Z^?X)g4pJXQs zF;k%`U|WguWEuhHEQ@P(vNtrN!Z!wJw z)fl`gkb8L?i=gk)w+BE7fIyc!uuzF&i-bOEr~ywmm?~KH>@c?zW%! zbL+FuQTDTV^-$$)H(kdJQVy-lS6nPCSbf_qD|AqN$iN)LZ4W0V_cSJ_@_RY=Q2NU0 zaEGq1zwLs8_Vw2tDeCKw>+5$g*DoP(pIh@meofFIz}!@e8H|Dq^lO4To*zZN zFOz|;vHi?@>7wev&_dt0Ojaw@Q9Z>XzRIe{F@OsXcVa_+LFGzexZhqZpyZmm7ceiP zRyuWXf55?gj5xq3^H}tI*_?ufxw*=$Z<)kHb5|h_gi&w#)B~(m{mQiy4@fCdjq2Jn zxvai&2Xp1x#KKH>i&f2cb^pWZ?B*#{Ov6pBEC9BzTcKgI3zDzM{NC!^kC6fdu7m8d ztqsn`zaS&B4tw=?{rx$MBo?=S*Z42h@-a}h2i-4nf2TOLFYY%08sr9Is+cWUo%@Z@ zNdfs-mo?P7KQF)Q_^5-5^q6LBV@R{0srj^|K3mW&+$4r;2raSwwxAof=Y}x`Y~=34 zuJLZ};uoxLbVS0U;xq+>m*E%Tre%G~l`mTtr6gu*2ntNG<#|PN#Q-;;xwK9&*6QY| zs2d|N;>00>au{I=MwSZ!b@IxanL6ES91%cahpaG6 zL-gQR-JxK+!s3o+o5V`0zMpcFIePW2(B!BagV?|7P3E>?hjxG>sa&$y(5?Lf46@LV z1}T&@nH#zrchPAE^B!B1Xot!P0bbAzP|T%9zFHe_-k;p9ieTN{%VifT-N{Bmd?O@P z`_jqL;hQnJ>21iCQz@b8hY5H*r<7%KM zBI|C42y<^JM?h1djktg;!MNjr(w5^g$Ov2wlA-9wDNznH0;ob&FZ(rg_Ns^yuRxz` z8($4x+p%TG7Jwb(?a!dQd-uGsy3&7MTWtf%OnHTC)pAVB@!i3p6$})d!ZLLW(5fs4 zGYB#Ke-fO+iG2^*-N9Kb44k41j6;DGI7W`bL8H6GC$6Jv{;Akc6h%QMtN-+N^H-X# zK$GQ}p>A5tFCE13zVccOIjbsMy(X3l9)TYD7*t|b_D0n32wdNYBEqX})i*{FkH98j z3*T&#AQ&BlAOv5YIC2Rghv->PaS46};^Zy0ThUepP-?O7-Y9}#27)=MLry%adM zW5GEbltItJQlJ8DJanIQ3_{7^I|2chFft_fgli0CPH^$hpvs`m@*LY(@W8qhfV{M&2!G!%krw=ji zX`THTkl$+0a|25UQVp}1`7UMO9$vaU-TwAa>*U33=4$KHZ0ylk1X%59XoX2p3N4&T0XXi$;^7C`v3aC!+IK(5-&Y+0m0{MXkpYn<4)lhM zZR`+zg~$L^zb0L6;rQz(@%JHX6r$TP!$lKl!|M@eWR{{b;szc{;m(bMcE07f=0l z@h_*c+vk?9Jy^U11w>B@zqU9#jW}ED1&8{s@ zcI(r7NHS^LgI6`ykqT`G1VRm41zQo{FpH6X@$hhV|31E0dUP(kae-A_;ag77?CI9= zbKMW2Fd1y28f8Xc+j=NsY_-ncX`Mc_^uaACLX;zdj>Y+Vt&`U~WU6R=M2DFbAMWh=X3mKM=AA-8&VDFjZSNbSxc^ zY5AL|na^zHmI-xN$uHTLcrfB)6-(S7?G zd*a64(S3V1jqTghcyH+41G3?=y(TVkksyq$RrE&bt1BoB0O-291q)GfxFiD3rDG<= z!)?!8h7PD=nb=O`>yaFW%|NMs>^N0DacY1m9xEVvfrDBZa&owMw`(uvp#>(Ri?i1j z&m9#$s(w#c0YXf1#Qe+(%!c=rUKCeqpc53=v4 z703V*C9xgoBMEC6re$G(Gm~eoMY-~?;Qi`B6u6EneNnV^I-VO>j+CggmK~=~Xva)E zq+2N$OlAdTr{~meI4DH|AkxY&viQUN;`|kA0DnLKW_IKjE`d$#vrS81e#O4}qlSAc zJ9iqxr-WRZR?KK^D(#%ZDtT|R6Z@m~=F+hf>^a(u8?9PL1?mRWC zKDsD;lpQ^i%|1|}l46jOw6Y2*Ztvo~JJd?diwZkioqyB%{uta>{!#nMrEKn7AlJ30 zKhT!G{t$oC^=?2CTi88Zs!Df&+>0PURV|}ts_3boU?`mQ z21ho+v5nQRm&;5Qle=Mne~0&>z$~U0MQIA?hTK#^&tV>sqb11v3!z}i>Hga9SIqAo zJs2Ju7};&wHcYpBH;7>K^KSmEh4>KiB|UTDFe9KXIUm^J>1ozp;4(J;=Al zn%%Q{wmV)poBn2UY!CfX!0jcj&x=cij}0HtKRLe(9}@#1s+Auj=8-P~JqhvXJf{b( zN5^pL)a3E>x^uVg++BC)?$dzK)e|GaonFW)lmNH=UD4%Yf*yFIkc=oHvi0SS*4#PC z9Y-a#fK~J~b`sN!N#vV_=wAtu%uZ>2_8@yW^Y zSL?oY>pn5D<%CJb z%Y+%!aI?Q_-6_(4c<+YaA0n4k2 z+8y=iUp9DVT9sb4aTdb8B5Bl1*cfNWt}KUJixkF z5ZTtuO#8{*$|7r}L1G$-@TC4kmd@@#5vy=zcSUxsZ7365;=7nl&2?8TxV7L8Sa8u> zN~n;PUIHBf_Ha;<|OB*cQCZ_RSBoh+@+h=ix;Tw;4b*4!{6e>4qkLP+gxNJd4u1{f5tXd}fZRK9+V z5V$dkO^O$Nf7h?B`=M*1-ntOmTA06)mjbtD&MiE?1nJI>9sRF|m(bABrJq&|UOrKL zhw@!2mFvJKF*-f-M~ia(Z09P=k?2vf6Zu5MCtJJpXH_*0gdR+2N}}Qcft$*=Th5du z@CfRhg=PBV7!&FkWhDZ8qrU(}c&*zv*2*}Q@d8kYLOEtJD|GnTak*AhHn2_`6z z^*R-IT!M=Q)>Wkorg8wN3ele_^bJ;C4+yhP;15PxZJ?j%01L~n!;ZRoa%}MydQ~s9 zW`8Uvu1q{J+6cLmkU4_2c-G=MVDWU3OixX5fOfIvp`2soSF0TYjaC;sGK+1!Ro5eW zK+qH=1Y-NXOfmWsGui^--e)aalIsj3t? z=-n|BcVL&Monk^o4@`gGQfZl~7p5F9kzbk|2jtXIiZ<}WkE|DK6TV`NSa4qZt%4=! z^fpN#3rg03s5%g}?m(0UEE-^*359Sgn=z{ju$fwc3$TNtVaZzfnD@Qjj;HJb!?Rt?i4$FM`I|l0tz!sPQ$Q@?azW~M#jh8?8shr|6Q`kY}pWT5ZsPEeP zt{w1Q3+OO|BFPAxTxg>%?U|+wTUxT?TDI#V+FM+;D7l*$*wtDFXy*}PNr7%*_(CKT z<4ygAo7@n+d$k@T}O4 zW1$BJ2#3WNXLu_NdVz^HMfbXQYv~v;4-Wwg5!FcLFHk1VgoF<9I0jTL&b2rXSe%Jx z$ChUo8abQ8MbL<~+`$q-2DFK17=p3RAn};x+TW@KnP}e^3;p^NXW*ViR+@;$_4O}W zUtVKIH2h!&p^=qgOLN<#RBZ9`z+`3Ci72+e)Dj)yr@CWt!(x(E0`$Pil&d#6n*b!t zwyaR7tyxb{)3%dPN41Wq@B7RUnyCpughX%++p~1u%;Mb5@;5Ex2%8wd%LX83zH`Ei z!#X}v$4Ay3A2ERVj(SXiU3ouX0TZg6Z{-qd>LKw>acb^*EHad|*bzo!iW1sSN3dyP zVlLE&uu|S%=swESa>HzjCRlx`dc$ktacdG~wR=!no?rVrHZ0OGg3x`lZ!0JwVlSh{bhDt3l`S=%Tdt zh^O|VR+Qgz9aSc+E>hiri2(_<<+XowHvrB!$``{?`xkKQyQAZqH%yKFonhF1sg9BB z+d#W_1TTgKh8P%QImdRSRSZ58KXTok=2o^6`d_LpW(INK`C(6;M?V)UYOB!)A@)D}z()68=&CzQ)6{fEIV_PoC3Vzv-57!;lOGYmWeTqDo7OW`uh zfFUidI0Bai37pLh;R$Reg!xEAD<;rGwbdh<*7T4yov{p!-^=UONJ zjL9ere;1hkjF$ZWsYA(rsyti4NK;IJ^`&E_T)_2v$Y}~n{@N|{0|StBgs~+9GT+Jb z58|kcos1S)V^#0okibF_KX7y;DBrGSfymXs#^ngbzz$U#Uu|RhwvO?<`Flz^LH+sI(Gv_7N->p--ZkoEl}~;Ow#0m5wYDWrwqcs%8ym?B zsxndx(egz zQLOt;IylBd*HW>Wv-%DK)C@z$t-&2@Pupa5icA2%JCPj^Ob&`=>D9?WQZRABV*@6K zBac_+coMj&o$Ab>8U)98%kcWx8r?+2pf$Ly=@tT3rv(i~CTaj#ENDRc!qP-Vby-1Q zx*?{DqCI_ZeA9!Szo)T#Z13p!M&i9-sH<_>lx&+EgLV-6lwCj8`r+2{CJ|k)uuFy$ z#wj3Q2DVFdmKg1Sq_d`=w3q3sbk`xWhzSEvhblH@t2&2UDD=fVqrq`_cKi}tfEDC$ zJF0uJ{U+HF2Ro9D&nwuUsEM-TwEEbB=T$}!LkU~1Yck(rZPtZ@w?8+7wS&ZZY5(Zt z=$1X3Hz3T5QYfS9(GGLN{q=2Ie*1c&ZP^wlf6!k4!%k)MeP_{NRoF=byO@S?RZC$Q zv(_uQ6&s6mDIJ3ax(r)+zC{;#Rc$VV>ta%&E}tVvjMz%7>O&}C4=377O=^ReS&U^q17h|MoBjlmh$%sVMeL-ckCu zYxI*sl^+X7&_dq1^X+RK3jziT8#BZHibV$&&wr00h8PmN^!X7^eDMWyM<3KK%%9C} zU(62QVqG|k*Jj(Z*XjECfIjrDFHL`eAFa7Xs77p`dxS@WlJ@u4*g9%62~8_P%M!dP zNp!$5j07+&V(u;{tyr|FI6=k6BpnNxBgu0t;3fxgRMoboL*~??5RMZ$QOaQx*Vc$# zQ4F^3z}WcZAjBJ6cV;KAQkKYBac8lR6}ztmaoiE00^2O#t;=`5k{-A9Ac;86P6evf z6bSKj6U8sS>_A9_dFW}+!RKPKl9|~oQp$VaRXqY^Fh<%H zpD@yyAsJyhbYl`KE7v(4{X@szW1cVeL>nop6UCX%jzL_+6WC46->Ea;m?8`pRbh|n zgw4VpjImM}p{kAix{v3(Kwb1uRaAUq1eAG&Sl)ckIvl71|M+zA30)rO8Ni4^f@}b_ z+KIb?Z~7+SLL}#5Cd9zFh*ctaWuazA1F6^{UJ82iXm;tbg2CbFF{aj{SXDxdo!FS* zD|VAIUCtCH#{DhapJtD3=MRK50D_8hiWuTWHEOXignrBDJxRy=X4lVP#I@S~0Y^Rp zJ4=WBS{6w{IuM!O%pLB^N#n8T-(hs>&LZI~Z=e!+Hsd%6fJ!6VDxEgq1S!+`{JEX` z^$Ue#Kv>fDEuW7?Z)Kjn@Tg zb%9zRvMRbmIx6=OH!d)6b9jU$H(R%^WnW&9S#dpr)w7}w{B>XKE@)kzgKtBdr@lF| zbmR>ELTsnPCyNh10}2rR(d=VH!X*YCe{7kk0Kp;hLX&xRbuDLI9X8+wE5nSCh$42b zikYq+rrtUnMBsgAU!AHfDh8Y%H}VA!r%XZ?Z=a|x5{?!70Ow>R*CJ7i#Gpk2qa$Mi z_q`Ar;H7CS8B$p!T$99+6AF!AY^grD-z12S5*8M#xxeQA0dv0_TZWNZLMVBJ2ju#g z0c9m#;@PrkbJbZNGw-n!pL|iXe$Dy=W_`;B<{+k-3W|Tn=+vK3bX!0qq253?H^WADRTcxoqjlXx z=yzlbR_A__qTC|lm`XMG*W5o~?kBOEVs4)>0cC{c>XB@&&ia6y)G=?ic%87Mb#>Oq zgjqC5^G3v)^=sB2FzW+dJr1mpl@oGnWrX87UieI%19K*Ux^-jQwr$(CZQB#u&cx=# zwry)-TN6yI@11+j{p$XKuI{R?#`EmGmi75y&*WBJmj#-3YyYR+0AQa(R4z%B-9fgp zW$5}H*s;s(r{))x4KKfdFa1GZQi*vq zW3oDjK0Pf9zGz(qrB(2$!H7%Kj%8~mKG|UDK=FaH)a*>nBB}vEp^ysGn343DfKOT& zhIEFn(0$fOcHl6inyQ$f|Gg$p4E|H)^3BG8vu$Z`0HwzG7$(>u@j4~mA_{O^+ z9e}%(aJ7pI^jeR5YOWNn+JzB+a!>VzAo(u5S!AhK)m5XG-A3i-07o*@;-=-u{28Ld zbx((W>Ptj1Nv!y5%LNhD#{F30efIYV0vx!B+mgFJPm+|z_a#!vVGYH5MfKP1o-9D}FcZ~t9I#8RJ$l~=zNWqaPHwW>J2}3= zzC)dieqjZjV>P-qI96tTgbAx#^pHN2m&`u~%~YR@9o2%Zk!^g*F_b59Tp3fVwN0I6 zK%QE4rI4uSqXv}+VC-5K(1Sk=r8!QakZ1#Ia3}rLptvonE;8Jy7u|u^n6ja-x=d4N zHUa?t7VVuK2FB~Oby;y)iC7Q4$z=5w;YjNHy$nang=kl`cr70=8{Ii2ijXyM;lSdTbHA|8kJC(ro4-PUzyvEUrNZ~8 zsigz)i`((+6EU`cEu%15K^LeRGbt66&q(^~i=kA|fqDFVaUf9$g{(Go-;q@8APmFn zZa?|VdWM{SXOKn#+?YyC@d_UukL#zY9XpTo({fbGpF%5VqR*Sk8R0=wHVd|2b*};a zABur4Z35E7aDhb z)4PTx>^~S0flmiW7Ba~ZqAQZ6q#`0o`elS^Vgj>ytnrWrYA+PQa>iZh3iOUKbo^kK z+xi0?f%)b51v#b(5Q!Xro0V%JFzWo3qF)C%|vyD&JjuD~<0mT5u^g}BQ zyYefv08(%g27BuP2Q&?0L)FFPPtxa|0@?!Q>C!>IR@(w2G1N6NG^DxHaYbrxiaIBe zir#L+6u*|U1l05&a6A7%gwKoVQ^QT(Z>kxHxz0R-jIopaa8}2;9M6Jn(W|L?4jQYp z|Gw6s&wi!w`6$$}j=C(-K2eUcL!@L_EfI(c#vy(5v zN5QP}M0J;y^uy^(Um;Wy=r{dVVm2se;Tsr4ct@5*$AN?1F6fzjP_DS}0*^G&{9c1>t<+Rq`p*?GK+V!!G7?RUE@eW*h%lWAYp| z($y##jNP>Kq&f=i_Bvxfr%YI{o*C7^gvQls>uKk?GP+2Pnj(FOA{6fMEcvDh{aP(L z>mW_FDahL30|b|?*^~#*ou#R1xh32r?8ejpAqPi9bg^2XIw4Vgr^w^FU zI|rA&({^`$@<%(&eGGS_5X%8L=tVY5PVdv?)N3{I2AYIVo<;BeVPg3p|5rn+;r>1Y z5t~SEdX|RQ%PQG+;pZi-?pkv(3Je!_wX3YHO-3A<1b)F~mI#(e*a21uc=9A48=Xou zAE%71)P#c?`KIth+93s<@zQSzM?4%HZv)ijfs8g$XFYZ97yR}I}wr#FiXgk z{gji)#0-6>_U!}FrGh8!bVS7eta+~Asz>YkL5zYad1)p^R)n*hK4 z{zSUf8vwb1-OHEVS9&{`w!h91EO(SyXl(vfyq z+stxN&xhdRDv+dYZV$?fisYc>{@VaM`OMND_6jNDz^Nq35VIKWv$}G#P!gr*mrY>J z1}~DPA7Lc&Tl|E6>y3b$DexzfO))sdY6rN1USj|a^8NjXQVu`I{blV~FP|KIF?t26 z1Zg&nULYP`nG9+fa#zXIi@SIN)R4)FCZ)p>8P(r4p|FCkPT!NNw@L*lJPt;q!t|R; zImv#2h;8J7#>XftD6g|zBIyj8@~NPE7>_)=x;$;QDaobYO?3ma&NPjxTSB;VB5{<0 zu~p#%d#E1>z24~?E}MAl#vei^F#Ol*^jM&s60SSATlJcvd*NFD8D9l&VXgZ)0fb9M zP5HaPpdiUnP!#$fKCA6a?e=f{E}_O^fOU&*wvX!{ylx@)KiDo)L32t#ZG_avMcDZQ zS0V)HhlpC_YT~NDi$K@kR1TK)3?8PPEjcvJknJ?Gv-5O(zVMN(UfVhpHpVV#zqkk+ z29v~FYDy~N!(ox72v?`5@f|Z9l@IP_JHybXf`;6u&>e8l&=pEHmvdpzg_6AF z4x(6`31w#m6R}uOfeT!;9NUA2NU0z*Bgz7mMu5+tl{4+Jb94Mu2*O^A`H4_@Q3@g? z>tW|MN*m3y!KTUy1?Q2i3Fw!{FO>iD)UCrwALE8t1mXodpQAh)1wJqpHB0j24K)+H z*HuaVoQw;CzJ$J#K6k%(YluqLG1jBCsB4{_W*I3eYYr66Iuo{=+F5gnU6vYYeF%%d zWM;szeE`Paf-+_dcLcyNZp`lZpOPkZ7iG%kkKD2GlX&itf^_+Qu`*`oQRot4Sf9+p#H`l*AMkr3&Rk#s<#8FpP%%>z@?#%?k%rl^Fk ziA2-e^Fup1SWl-gy*+oZdN%yzUMbpXfi^w7kg{+{*CUktr+9WK^3M>4zlZ}14&N`V zdN5&aPIP-BNm|`D_kEV`U@)>;4l-`EXi`Qii8KLt#@&92Fr(5QpQ3A9Hh)1Mh!*rk zy|~_e%-`UD|H?2^F^urChC1|1Em6zlmXCzM3?c_ddm4DOA8Mo%pi)y?aKedWg9)pG z6HQO={pfUm8(ti1Qd4%zFC}q@7%j}8wo{LS@K^+rVlWZac|VC*znfce!*@otagrJ1 z)$LDk4-pe0AEvE_+fnL{dqrH)Y;kcU3*cgs*t{}mDV_$_^UNtnj4RmNI- zdb+>3KzEGnFK08?G~Ev`xVZepCE_y#Ykw=lO zI2==GK#O2bW#4{jS=uBEEu@X^n3zp3Y6t=a2`xRb+H5={JbjBf+k-LnyEL{z3{sY1y3QiO6QKB^XsQ67%jsJ-S-W1}!QH=fI-U zwB!oF&H)g-oj9o*jjb}jOMQn(5&Wro;!kQ77EMCWDClQ%VPkQOptQ)c`dZqH&tuqi6fkQvgua)f_sIV4cc z&9zusBCF5#ens=kBq@`ETtcTO9AUxnlV=PK(y5;_OTivSB=AB z6xAI`Y5~8Z&kEPOx~p5uFZtffHKXFN)O5^gh;gegJ_lbwyZck?+70>QHW#P^J*vG3 zc%8-Q=;Y5t{%BcY(`Ed&A55h*ViA-c-rCmKfSwtg^^8u21|J(CJ~ zFBw)G_I)84iIM)NvtY48J~cnVBT?HSw^aauVteM|+#N^z9$Q8~V z$_Zml&-gvJe?T=mKVpE$HJ);+c?3}_O_!7T!})fpDJxfM-++na1sVtW-GLKCcT$Y@4pvFC*ca!14!Q3p(kc z_zDJ(pIPTUTu{w_dwCiK%|B1e%Y6KcpGac;i=Wgsn(yYJ_tl^FEZocuMNRO>O;mgs zzgCBPN&=WA88`sXv{y*H-P(UR;-bA2y}8MXZF?zrZ*QA7KO=g-Iz!}Ee-jGYQc>ti z?&fm|Nt&?j?(Q08f30dY`Dkn_W4weJuIa&tIK`u%*myAn_wRX@J36^c=)oV5)SQ9K z!7o#(vBRu%DwpSt>cLO3>i6TJ9c+`6(#kM`(SRxbsD(I*m2^03Bw8d}c_kOaU}T=y z9+58nKC1dFH@KjWd#9YYQcd2Pw&pHdtu+)V!OHqL%!6*>*f{B=p`bq7hA)h&+2V&L zu~$2xk1)DA6l@xBr{Hm;TOCJ1N1uNb~Pnk%o&QH^;m9tYk`x@$n>zGRJmxK5&8UOe%q_e zV;u!~v$l+R;VyP6(N&pTl{gkR(EU;NPG5CrwA-4mXQ$si6pU7G{)KZFwmZ z(f_P{azS`F9GO}qFHOg;J*0b_O_nY)Xv1l~am4!)Fn&}W2T|8qv|yYPwT%xd{`1g%sUAw0nP>1(?PbS9K1@;>C|_5zlXx0ZhemzH zbR+V{oLFWh7Vw@lUz=mtmAH-!H>dA?Qkg2K_k<3?{Pi!2l9VX(_n`; z1+y$U9b2FB)(8kY#B*kuQqThQ6LZ8LN8Vm>z3P*dVbO4R9>CEuAh+to&EuQ>557k3 z(12~?P&u6TO>4$(`Ot;CmLE6D@{GH(Md?bB_#gcvEkJER;Q-e7w+q=X^~~MDE$Dt? z*k>5iuM0cJO#z}_n^sBZYd{;A>ir1bdQQjLCVi>jYR=%%ntQXjOCXY8cW;G#9z^5V zFa71r9Q?AffN$}0T7b!D}vkS!Y(j5}M@IL%|?f5#EUw$4`1P2B?b{>eTysrfEm z^ou?#c@b_Ofq(1V?qz_L*T}fzbk&WxP(TVLS=%s8yp1UdFw{#RYof7zdDAfIbB?@- z?c`2AIc3z0(M(j*67mW$c8)dF4$If&Zf~4ux6PP>La{ae&}Khfdt6pAkpU~PcobRe z*jwYVI7Um?%SXb(3JQJ=iXDH$DX$9x zHUtHWqUmpe6;TQ`ub=@g$4g*-6^j%_(}%ql2PQ1@eP!{4^RiaXLD438!Ni4?L7i$; zjxoH|d(AsWR|7nA`l5kZ2uv*!N=RZlOiP`P`KmQrAIU)0h>7l8cx?66E{lXOi^di8 z`W4ZS3nJmw)Da@_L2!mqjw%5;XI=omV}*r#9+Wc@^;dlCYWTS-vmEmr)rj7dh%+|| zi~0D5p5>Gy2!0T^oQ`}9N?6`3Ky`E6INXu8nl6PfltN_p#G^jpA2d!b+Ax+SM7P{M0hP$6ge5roH2c=SK=u>vt@ zI}g#u`N=X#K$wEAZ+rmVS8*^(Z?GE-`P$c0-DYH@oVztv7Y}@_pDTWkg}n~8OO39X z{K*;;O3NIj4tjO5(o8g6E}iGkF-!-xC+d`B2LT;9tjUf|??fPe*QoaQ!Lc_UW;rZj zMR8~GJjD_^WWa(U3g(Prk66!D@`v`UefT9z*5Ag*){8lPki65<@A{W%Q$9)%!*9}1k$GKl4b)wJ{=OdM-zZh?2ay69p*L_w?+1(xFT|3eCq z>+)_{ZV2-$0gMUA!x^o*kct* z?Uv2dxZ{IiRaX*3SOh2%4*1L!nco#mea1kIb8?{@jB*Fr0F&`?s(+>+G#-D8)>Eb- z%O`VR3R!$i3x^YCuWk71)cl9aqxE1HGZw^D~TVdkYpk~JCBCjndK^6rIJ^vfvv@Zl~v1cmF6A$`V?@yCGb zCoo27CSmPJQ`4yjGO3nuBx;q6qK4~ zfH^vIvz@hf@8=6?%PTz?Y6mq+!WFbsXbBe0M6@5xbix2oazy}Pdbb;+6aln5T=&6` zg8!YQ(;!9`gQe(cr!>BSHa|bbd%~@Mro>f@9(BdR58-^7wywg$BtV$No=WmTu}4Za zy(=6qkV#a*@l?28^G8ZzqW8f7hwn#ViH=SFffVVF5^NKA&xr$5AqL`tNh81xp$K$m zs6Yy2enx1(vuK1ffz(P#;Q{6d9xa^OEQJv6fBJ2>qgCzdZ2;S9JA$azIs$FCAu!o| zQ&3Km)^e(bE~r!plaiQ2v|M%3;X*I`T&ZOROWXbvg3IHup^;miMB;apj!i}|HT zXQ)~@BUOmVbn0uw^Lo68h#R9WfWP4#9iV3ADxDKbP3S2Q=?7@MMh&7{bLTl^-|Zd6 z@67jor<-M`!5SIM>^^K*$p7}3C$#s8Z&-1K0W%4vhEVdMt7ndkLx!Sje16aouxynj zWq4=cXo4v%mx<%sv`m^7R?Y&jwT${Qc+?9)9{3i#uF0IT>9I)~cZ!?878Y6(SFR zOcV@L_wTT}YQFz+o)(G^!IwrF!#&)K!(_V;rVt}EXHfXFpE3MAKg?ea8@Je|EEO$0 zK2Rg+AncX5Wbh+Smy*snJRiERO3W#_lS1NJ?YL~W`)TsB&SoDM-!VwB!&ex~HR?~a zL=Dr~J-G2=>EObqvssz{qwz*vHwI;0jre&T8dUutS2GG%Md4l|O;n!I3A61WOaLMfOq!N(w& z1MoWl2NTuhK`08Dq#>d99DOzb$LihqHw>$S$ixVR(m`|hU;TU`SL10T`%wj+3S);T#*GaD5RV~)s8 z0LcQz#{LywSXFYPRnx<2(_pt#Jq&N#Nm;5=5?x)QBS5t}VLp1lO~wqElo5zv0cc|K z0c{G5c&wmXk}SwFS{`SO0G*T@=a_0`$z_@f8d(MxiyZGq&Cq(K+nVtnC?G}UhUU0` zEL!C3a@+$vrDcrO;BplNrQv{GZ#2gu?}46G5K;}sUJA-vX98rCS!VNYhBcf}Gw|9! za+}inf5TV#x!3JU(0Mp}0_fpG&ypzwqh!rX19z&-7%Qg&+(Dvn*&*w2!DBu}3VzAp zW{d@LcMVM;L{(=$pQTatlqkb?2(VYgAf2PzPlU*BGt)V1T(4=goIDcy z$LsK(u>B2YRPTX&P}b2A#THZ>nX8E;sI#Uiok+7wfWjC9Ty|1J^vDE*rB67$L~-~) z+hMcdEs3(Zr4hduI<7{;p5`<+p8JZ`r404MNefRz&Jz()^}ktAq|q)RwCQWGQpafC_ylsBP~ zsadNGcz?oX#XXy;qxLLdY{K~sdC>BT|4$bv=FUex)((~KeZg;bey$m6i^S=|De=VTO34&o3wK*F}S)I6D(mCUKLa{__qhe@Kx4tyb&xNug>)M_h6t3`}48LTNGTW)lC^v8frnG`AT# zE06m(|4^hYhaX~jwLddXhB z#w{g6==oKr3rs=7llpoi-%1N0SnBb3So}j+j^FT2$IpB!2O-W6T$T3LWmy-b+svZ> zA5&NJ4A-76E}wpqasAw661SPyAybq_$K$a|$EtRt2^_Iq&B7ty7qf*DBYrmWtd6m0 zPf#i)5Hy*ex=miko6k z9$)xkTbU!xRV9KP`%l+!^$9S48xBtbPtVI~x)p}O2~yynGc!hW7CC| z{x+VHoFbb0&ojRU$5)lha9?qT`3YCa9(0lSd|QYG;cIelGxv0#A{gPB_yA_nB|Dd8_b63eR(^$lxbAX+27Y{3# zxB6hyd7&SZ8EV(sGLSe*=hSgM{SpvE!Ivfk@e|JE`yFI1=KrroqpCo*tyCr|ZsxJK z@B?EXJPv?|afX11W!)<)b9@Q?F&hh9frz-9jQxF#x48hs51fdkzAP{=(+LtJP?nx@ z&8utaXvVsGb;X6TEQ`0mVNDw5!uvFw`(mFNwpHvhJfI|8p(TaaO-anq_{%Ru3#igTUA;3%t8pEVcAr^s4 z+GGc20Rtu{BnQHJUrc*;crk{32EV;Cl>G+hHjm>vv*sVb)HZud6-1YWz` zSf_&Kc=FeCQlJKLxz5yX(X(Y|N=aGNN#-E1kviE;qAZ>UyEqY5i`zNobplMvBibuS@l(#VZkD)z8~D}+Qk zP`Yz`E!D`B;c^sHxQbr$V|^^6Y=w+dTQfuL6ydN|Bw85LE>=BHBrs{0jUR`i;8|{) z(JDeR$Y}2qpGnTb96w?Qxu6XkjAF^%=ZFue z8oBMk*Jf5ptwh6%Vde$b1ebUG>7s6WT3(l}S3fV}_+Z3=AP+#u@gMZG&K0tr^lWHFpuF77-@w8RV=(dsWie9|t zgY-_#G*o$0s-0-|9>A`?fxtKL)3_XS#Fqhj3};ntXn?AJ8gvMMK;^gdIPMO3PYs z8r0kTd{McX^=de%{=w*z*iQ7P9qU*t$nPjfOdYJB_7*-;_G@>0Xt&<>td!u1b(ZR> zqxZN$>SYzXP&7%{ZY70AMuAlEMpZi&1u_t3M`H*V_cWFD_wu+vDlypa42?*Y_Imip zdNF10;4(?s!VQp`?IE{f?L0>MUZ2E?TH{98h5Y?{_B$x8c0?LM^+HBzV#0drj%kD& zMs|L*Bn_q-4qAF))h6F2zrV}F-$I}`VrvH`a^~fJmsM>i*EL&CGFl?*z&?XlC&;!-oCk#pY8KojuFd7?MM4g>20~5S z9*gE6BMJfqF@o35SdtB#S6Wvp(5;RHD#+HbDKk)?;nT}HwLGI=cD=X>fhjhj6T?$~ zT1WpeAqE~Ko@7I&Yu9PTaw|6~i|=WC!jzS|96uLsX$w*&+}TP9+MQ&n`no~dm!_3K zgKV6!+8LMklylw{LoZ6=h7Oh(rMAi{3KZL^*XH@#RAQmAwQ$`ubp>vz0W~%Xse)Fc zkg={piik)k>Fzw&WQbJ!HKUi$sZ<1i9)fgx8JrRgHQ%KlisP@GAN5v*bYy#FXu1+B z;d(A@j-&OXg%6}Tefi&%)pxG=d>-X~1F_22lAtyin1Q=Mz*}ch$B#Zt$&E%9*IGmE z8|Y1rQrP^u1f#WnuMo1A5xmx6L zo#CI@8rbayGseW8!-)#x+vS(vGbqu=i87o9cpheFu5~Wo#7~AHs&Rr3FgUc6Hd>Hx ziT;x3A2&rqt#DhF-FtFbfv89iD(7!~2f&pp@nkzO-h@$>mNRzWsG+(yu1mJzk zeYHDbwFhG#v=!r;A1ew@f-}M*I|e~8CVB!Uvb7)u8mtynFjUmb{&5B{9*UL7#w7$Q zM!VJX4TchXNG*x0&&ZPp4UqOxICGRS6qm0>@$z!w5bvA5mt=&28K0q?uA4S-{ooA}qIwT;^dMQ+A&}L= zh*xF~X^Gi{pCIA!{FRPLMhuLZ5m6py7|?N2qVZb>bohcQi0MgWk_}A|mO&tM$)cv% zHKdMIrKnwnk6(enqP}5EawTdTo&o5zGxq-7Kl}lAttmN|WUK)b{d0vlnjKfB6OGwe z#aOSs7(a!!!!T2^?6p$T37AP??s#4xs3J%k&vM>dArBeCVmr@Uwv+ZVd0jaEItNhh zlzHPatum5m^I=yMC8j8U`GXHQyM?Pa%k@m`)ubH#Z=`ML zGu0EUBP)t757=D>KfeyY1IL&)MKjG4j5_(IhV*C;n(+ZN;emOhvKNY5F94mwhR;EZ`u5u?=EQMQ*YZBR z`2(X`xckf075?B+7W@u`qz7(zs$Sb3^b(y`_!6Y37`H%^T{GA{!eYCy;|5{o7jURK z5()@ii4vE7Fmss0q}@}{(QKi}?azfyCb6OC6qBR2*zxr`r@3@gX=`(hAgEAt$im|h z0#|Tb?HY6U?M9k#5aX0ijsoWUuE6Y4I5iBV#+sM}VDfBW{--6MdZA6qlMTUL?HnJK z*-`u`R6>)IaxOO1ePX(6fHo2+#d%-A(98Kt)J^m!qag*klX4QDL@IvUl|gRx9p$;k z@=Hnx@N5IfoI)Tiz0|}UXL+QrN9<^`LjE4Y=CnAM#W5URI-)FOV6SbI@+M!>V&@xB z`-q*r{qxJ&vfAs$@nB)L@$kFyC2dKs2!wCgnE?`Zpa?Ato* zo>l&uaC^IaJ)r-}vD5+2n54VEwh0Y8ER*#ZkG2m3u(!gcB1KwNwFsaAXSpR?0;b^F zNH^bi;{S`{mIV!>=N6LTQ-TreVb{F-($I`JPSW3WVTu*$Js4)>p@Fk@6`fW_a%_$0 zG57U*=x}|g3ies?)j6~fYWtj|03x6S9w$&D?9*L%K=pH z_B{MDd~^a|44H-cce8?L35ngmA`_y>bMy|%RhUOrEW?C;g6#}A{MDdTH5ULV$Lsa%L#=vFid?+$@ccH+sMQP zaGy~C0}Uc)WVm!s_s{IFUOP5UwKb+_8f(a2iFvo7p?Dp5lTj!iMee;{1D>WY=#QH* z4~n-Vi-rsg(=%y|dKWmLLujlw7voCwFpA=6^FHSnd0MdHZ;V-1y#BR0`n-!olR<@& z9>LhT;vG7CZk{V_V%Ue-t)_#i#sVJpbt_LBfq#Hdqng*8LU{uvmX7OH%FFom?){TCtg7Qi-3@aT zN&O*+?3W}{ZtqLAQI2SP%F2<@ijWmUq##o>tVs2F$2B*;CZbBd<1Ztpok)`FnH5Wr5xpb7XWX8p~Mn4CTM&8z2Y+sN8aHbf~?c z$kh(FLkM4DoIEzXp^Z-AO|p+ zPtP5HnNXj;`@@bJ^aDSeM6;yRXg>;3^M_izEr8r`jh{o zmog2s-AMSnsYI_&hLBzbV5t!Ek6Xr2w7=u)!a)4#{}ZIF(&~;*KU-A7`)=RT58OKt zA);cO&r0WiPjh|Yjvpa;iarmpUj>k0fO|K-zI5E1#-y&$xFA_(zU?SaxV0vhTA1LC z?o%S?Opf1sm;@1(R{cS3$KNjV?CUe}TN*1;XPT<)uGXONexoEuRUb7Qo_I2CVqOni z-PHc~a-(u}fQ1@kEG)ts$hcuf7Q=k}wwf!#qT&f2Hf&DnGQZc&{nZ$<2`EaSrUiYx z@uw3gq$%Y=)3WRSdw|@2_@F0xFsx;w$jSRCh&yKDP*45UX+zfUrm2t4s9KCFD55RA zlfAcx{N~>7!SJ_g>klRA#FlBKsV5M@L<9+Dy#q*%X>XR&Kn`*UARx`P(mwp3V`NJ#BX$*6efBDA5M??_k zQE?H=;+hHlU_qPKGD2c7xf*%X89u>EG@n4fkl!h@-_6R)i_H4{d%E_rYR@~wq)6xh zt<4j?GxjSII#>u^&EQDIklFHXLYLm53Hp`$4rs@f1mH&J4MR8ATk;a`^@# za5s3UDrc~)wGPcR#I`EBexBKzLWUqInl@R3M+qyWrur>VJIIq!7{=W;?NNOjcs;R7 zwo!Ns1ZUO=TArWty$oopta%1R__#o;V2?S7TV#;&(Q#p+bT)~q=Q%xZlbpCG{iHyd@0+JdM>I!zNj&eL-i$`;c&tur$$- zWweGBX3QHkmsm2rD@`X03~y_hfqN@s7cK`JEA%kbOTKzK!LN8t4lE%OLj0I;v$NWwA$_d ztDxiVV#JnVvVH!jq>m2&Ie2W$gD@HXG1;d2wn58i>*FC0mx@KS;U5-(dLYqosov8O z{{5Irzp3HF#Tk|{Y$XqmdNIN)zgf*5CaVyn#UoEZx=e%G#V+k>r62v?7~j%{e%1tP zlI=Y_J@nXw{UoEXHB#54D)^z8gJi4JOx{^ z#P;zXAZ;MqTv$jPX4&r;?Y3LvjfmKHuanbV7UuZ3{u0*f`hfg}7952MZVd)>t$W3- z?m$Q<*USGbb1|q{3@7>kGhw`+Ok-v(^2h~YpIX9{VnuztJKHCt5e{hb^YZc)8we$R2 zmE)xF_hl*QDnDnncOk-`yfx01<(<47uKEBNmWRHtw!xjOBxG@jxqOYpl!>SiRZ&NI zIf~-0-StSv=9&Ki2X1_;c#(xuZ}blM6s{0zTZ|_3l-hp?uF3X6i+~+Jj-9@GRDVEo zoXrT*C|!yThnG$)!d?Dqjh!$2ge<#{^EC*f7^X%s($!3R`>tu^qOcD4kgBwC6;B08 z*_IuWie9&q?9JRLQ~zmR&_TEL9p6DoS6oNc*ANz!ZcMj?9eBxMM_X+NUopvON6`@VK31AOeu3Y46hzPC2X;)DWfZZgd? z*_^g%PXV8XI$y;_nIGL8>sACATfg|*EKLj#xxpn?O(~b<2@-VroRro3%O`^L>kPC*ZJHaTSju>dAWF2)k^vw^#dm#I(9F7II3N6*D^TmFRjgI z)rV|6EMzZDW`a|0v!n)Q%02xe$##nLD_ve@|a7B(;629=XOkx|~v6U(L%o-9nW zBmW_Xgk@82oFY?F?k{n4(%Rcs{mB7^`GkwbN=t91!P`x9@TxGh06klqxf?O#QK6A9 z`pr*BP$A3(CV@8h*Wtw$LO}9fCkP?g>o%VL6+geM7Xj+z!|bJt(V#N{j7isECVGCG zEOO6yVrO}EzXJzPN?Si=p~>+;Mbk@gi4trwSz81>kBPm*XQ|6HE<`ok-^a+!xBB&K zs`wosK)h;10F7yK$S)q9(=UT++QI|(14<&b==u*E&WsIOW(G!_ zb-toBbw3p+32%DQj#E;c3W%JB*@;ZVxof7)E?<_uclGGsR`UX+;Zv<76XHmFkw5Kx zcT@RH_q?|ovrj#`vSSt*2!*?QRZmyjR|~&*Gvlpuzo7{$wkm4tE_?0kjVf>9T2XZM z%*lyzHzSSfZ_p=XYEn1>FwKS@W$lC)gQK-}88QX%+D;_#;wnAX(&)K8oDQ_K`sbWn zvUvAC)a0X5*&n3_wMU+Dj*h*8J7-2McOk<7-a|s*av9@c^YLN!ecM2SaboQYIKojH zrc@Z}KXsGpD=S4mCLD|dOqqXbk`ll@koEa>T^nWLYU0=zupQ(xi+oj?{8>Gty~FeN zH4NOD1m~1MaHMN0KbpxkW!Z%r-((GGuhCyj-a9}KyKfpJq7$sDU1M;{m`(CjYTF*A zc>DYT{Fvx8iZqAwAh5YL;ls|2bXD~_!u*J^64!CE#=nD=TSC)p3AUqadMGp+`$-l! zG{o)B`EGlMLT(}FJ7sDh+RNhzyFKz%8Ir-R=S{3c>@~^NLe(ah^v$r9OD@*vA{li( z4)`pt@6!CK9$ZPheW(4w*4O>g`v<3vF>AEXt-Yqt=i(n=ShaTKI$+f?xv2U{N*gG2 zCIgYe430~W?vmzoE#4{Wa=juOMbXlN-!OrDww}19aZs<2&Aj}@H*=sPe0)tfazio2 zoJc(B_1H?ySyLG$Ru7#so44!jMTNst;Qg=F3Mt4moC%17a05p~8)Ti0>{xuupY5ID zEl7>#SRIRLB-(Jn|7>y?1I#K2hJwH%jUCJFUVo*#%F=SRd-dDzUhPNlYi6Nsv)Bn_C;xnrdl#+{4&dt%;?wmxkyQsi6#~_ZQF0 zBF0W`{YDE2H`BI*#Oh4`#^%fbLu_4k9sQg6+VON{ciGg{Ou7FQwtAI-g5y)+{5bz; zH!MxI+~0?&KZFVrQN0qTF=WuI4rkx2@WK85rCJ_fl~O9I*hp%L!MH8zDRKD`a`h(f zo5%kq@O~uc@npsE&<5DCRSRVikQ`VQ=PF8M*-Dnzn_{4zg1sfWS|Y7s8v|nr;QYdJ zU7r~Lxy{*wYbw#3=UqqSU zZL(%mZ42s#L|90@{!)S*Sh{S73XUe-)Rh%Z&CM?R)6-gS+5gREm}waJ*-uRk*g9H$ zr*#*q7}))y${Ng=2||9_#OH-={^uu`n2J-ETCk^uCiP4u6C2?_s6ov2Qz;#4&S8T4 zP)|lcKd0KT-sts|r1b1#<>^?E7-^xA_BJU5k9zmInAV#WfW-1k*$ zo#$~-lrx(vyy!1rDY1o?7>_XYed%Qr|F2R!-rZjq{;zUXM zT2O#;Mjg)JS|jzZIlR-=RwWU7gw7s4Ya%7Pc1%mzpM{%y>fmz(9Bjr*S>;YW{VQE_ zU5zs6f0UITR0xh6d;dQi4yde2@`eJBZ^eA6xmZaoQz$Ktw*JO!gdmUgGP5CjeWa#& zqVq;nU=gz_6$UkyzcBb21n zN9tPu716OjiP>eMEdjQFsYO%~*L=+~=x$`I?V$Li6V2Ba?|FOss&OuS0EpGcN&hX^ z^Oll}-j)F*s#8Jie}Q!+wCh9=uJ$)ZRTCKnB(;ocmUhotv3>ph@Dr(aD;Wy%&n5rF zQikS?sTtcf^y}~q`m1atEHSfyYTFQOPyS_;IzOqrPqq~h&afg>K##`cm}h%Hh3d?? z%35*Gj+#j<67ix%wo@HeD&QQ{vZ~YvmG;j+D1!qxO9l~?Nx)F+7wcPaBB0uIL!Ug0 znM2UbmMY*IhlX3fHY;5gGLf+*ii9cGQVM?E6{;>L zGBj*pmI)Uyp}PE#eN~6A7IR<~#{^~crm4E}aRZ3Bq2*~Ml#Pz{YJ5|&)Ag0NDK|~egWb%rGsNc`l|HziMXYY7{oCfzb<<1{np0R-%p;fi2RsA5p;8} z6FCaRTP)H<$4tl4lf@YKJI>jfO=tWn=B#OVfe5f@jvumyqzzYOSm~4hgkG1_70wjO z*QttS+XzMw=6lHy9Q{?u?xy)(78Bk>Q6<0ipZwKg3k&rZ2cYKQw{Q!pNAfl0SEeN& z`B10P&)O*~3^G>2Czu*rL>>IvR-KSgH@n#yIyEbz6zz%HI9#` z>yuOAM`LA=+24L#bPA_)bTpTKk4r0(@EP2@)JO~WLL8E6ewu9(HF9q5o;F#(P?1cTv^tdr-|omk0a#F+~32 zJV6qjvUnV)R_MZBK+vA}eGspT!h<0BGHqw0U!zX8878j)fR-$(qaw{Rd@xXvK~gds z7U2v0$zv=@ziVX2_EmfTTv)_M3d4W&8R56TqeEOuQCY{U96IOgF^7tBpny&gkP*cF}y-a(|~w`Rq{s{L1~;qBW@ zf2nq>FFB7xDW4~yWb~E#0`=KU4TJZq^83-qC8{r|XcdEi+S^Cg`n|k=0S~v0@EUvo zRZ?rWsCM#(Ixlh>W!&%fgL}UqMNsvq2pNF35Qr-z{ z^r)^~)!;b!Q?JR*g8HZkNlW?Y^}7FHsr)u=fnLo?J>h^B-*u3+i%8cRRJ<&?4hIsF z0xytU_a<;WMn$N4N~FR>qJUUjNSi5=m5ho`1THeJC7*s;Gul8b9FcW7?XMnIvRhu! z8<~9(HwSzR@8}79E@*AN15`h3s#Y_F6h|xZ%E8u5%LJq)#{$o!73&|})bM*V0jd88 zZmG!jbvJS8D9bllF`RF%LfD;MCBm#MXMMoNq-WXqvv~J{m<2YNvYsf5&uOINB`nJ! zP4Zv%KEzQ9=svO>yf+{I z_cJBsZO8&woVFMwF!fg7a_2LV*Wbn&+OD*Sg*jN(1?6S#Jx8C;_x#|v0Ov+Gx+CC@ zCY07YOAI0$EZ~C(rp0sJyvOFpwYnduy-F$&O|&5c+iFA;7;mI8oL;aly%)Mz(won( zlnFZTuf6i^?yToIwuH1g619h)oypH;c^z`4LoDdDr4p{}=q=+MQv2u#WPtN@?wvB2 z>sC+S=4WSc7-jp{?|aBAyr3@DxIUKthms1os`TQsd7AY#a_nPT6qo(!I>i-d$ekH1 z1kpUI6^)I~2i2D~@pna=qIZvIc|Cq~0?Yfl-{tAT zCCmKoX@V4c`WEgC8vsOB6NL$#b*FgoSWdNRqZ~+F0_2H47-bnAb%eOJdg@{bQZaMH zfaakfH- zsW<%Qd7PYKX&XXv*QLOL4Z6eA?Co(^QHqazu2EF*GW0Bo_a`rk>8SG{>A45;jnpoz z63lC>30_w&YpfJkp=v?#p~$<3CdDraeN%LGx@z=VOKqeNsDWzV<5O?u#+p%Yi;V|1#^PmyAgJ>Rk#5dUvOqFP$|$K z3gWD$x2k6Ptrps!EjDr&O*!Ka^TJsYukG`dwaNuGR# zpLK-fUl#wuC<{Io;L6p0D{n2cs4>i2nG?~@l}^USpl&l*Y(Wnwnpg?UpR?zp=rLGY zp|;AJw?uS{LQ!Fof#Y@N-2+3f3H^mmjR`v3BHB#BKcH;AThCb4B3ma*w(hM9lzX|3n98K}j$%T7zAkGQM+8xx|d3XN&eQ5T8a z$s}L7ky-zlUDuM4=GOcTXlgT{uM0n?0VQ*ZJY9-wkd8b+jW+hQG4T5p972Cq{xoTv z6jG5*VWZPZKbkBtttiVRAb%XA8oV{ENtHt(R`l1zH1FqN#!XVR)gOoFtj=WUI?Hv= zr=Ra)4QpmfriT1@eI0tK!q3G1R)(Yh!*(nN6;9+w5I!4PebU%z^eiyiovSj7o`QN( z7YTgwb5A!aWYW!9OJ8yU+#c9JK;UBZ)*8qF0kWQJU9bKcrQGtN-Z8Fhpfe@{KT+Uh1AN( zjwq<&7EL=Mr5N+sL8%y6SzW+<5Zd3CP9-~hg)ftlDe!@Nv>`{j>b^Fay3Ls$6K0-t zV=xQDP*uV`hYU$Vo>ETBF|3SL$C5o2vy& zEs>VB18-R0qO=x(Vln^m7}N2(PwN^m{%0PR=O8jNXr`xjJgibJJ|6aQCuVu2^&ie& zN$4Oy2>>3I;Yoe8C}l}QWreQ7Ko^Ny*((Zwyx-ZFix=WJK6?*!kzb_8_b-m-92!h*Ar4E+!`QAsHWKXd;9T z-&1QL0X_)gl1fGdDeX^v0{uax{-e~&L(6|i!|!oJb5{4%UhclCcY)j*AqGD$ zXl6P#IU-R_hNb97GuMS1i;+WrJb}x^XA+XDMx*g~LxSBZ^yk)rRE-q%jzoOH zXhGGx085F}r5xttNFL_%v@*J7cAW=2!%LM$%4aNWhKA`eJ4H}3CSGWWSRiB9h9Rjw z7vx0Pq%fCyI0C8l4=?`OL%`9O>Py3)`%*Vt`@VPxEGDVWvYu-(>K)M3jC6U?+M1EK^G)TJ9$tqe?adZU`#S$+*bKjq!FgZ)FM(qDg#uT z-t)tWI7r+wsiB+J(esSqm11{vzC9YTPzNQt&0AkKCGZR$p&stu!jdp8X?&Qe^+%HR z81I(@cKKTF-&}i|X{kT=HL)G6v?T)C$48H(XQV+%gHzDSzbTQos7WBFf^So;?h}_M z0uPOg5opHayNy?-yQ?g6iaZQ){oT-C0kr!B@jcZmK8!EiL)Li-BE~rQgQ_J{K5Lfq zO93HJ$k?sb78ryh+M{a-U09n^r1d0`XYVRXq!g9(pxtb5G&q}}IgS=ZON<_6kKKz(Y?j8t}WALl2YMDV{8f>70m-VHQBM}d+mJ@Te& zR1osh| z^^Ic$9U1)FFwu8p(hYy0Q1X_e>s~L3kwp=#oC zJKivcdk>cR>Ixb(1fUGeTN{T|Dq=wX11IGR# zh`2bx#==np%_$8fqGuH{CzmxauZ@nojYacUA{e#eOo%ee=Fi6q)swts# z+FukcpTw1bTnUSx_D=vI?9T_qjwYps82)-`wfe(Wfg2nGlQF(Arp>-@{sn7CaVJ(P z!0VZJEP4DX>)xYrj7EgzQ3kMY7*cN~HN8&E+hb z-4t552Zy0+g|Q9SJsJc@mM1gEnh!LWLzr`K{W9M&+ORr;I%O)qrDNb~x*a1Np`*~U z;py{e$kuzCwtzs9Rm@lE%VtA8j?mvkLY+)b);nDt&EF!2XgC-^0{*n z4AOc=eR^r6-cgLOy2v9I-u3mtFU_!6K9-AQ9zj7{E1J zV$`Ce5V(&a&l}bXQIquHLN6_{fms@0X%(;l-+;tc)7M#-IJdOHw)qy1MS{W zi%+fta!lSM$#vc$yQTM;RMn$hc$(0!;>6(}q5lW!OILtylOQ!l(G^=nX?_r;1U5y4=l-f@I@5k#KdRZ^*W9Po{#zy`Wm{;_T-zq#%0;eD=x zo>55(a9UR%qKS`~r5;IL80_z#VAU7Gcid7k6LOXG%lobT-JMlp(5qF5*CXTX`q3-s zXr^pwiT?XeZ@v8w95&j_ANLOzB&{hBuPzD`RW2r;IxizTwHH?;*1Fz?|CCVSK%qEL zuEB+~eet5&AAaS)6M(VNz(ZNjm^IAdZEVPykO98*0^AR6S{+mjJQC8mCIVDM34ipX z>|o8-=B14V7YmVe93E=PVvjNb>5<+41T97zRO1Ls0KX?R8(kmxoOOP66NW$|{)P)k zt^b#*_g=Y5>c|S*K$f)%}{t{ zT&?5!CE!Z_tBeo1S#0~;`1EV*P0>dDf2;t_ANt1@CX3UD8`yulQs$cK-Zy@C02wi| zfb@%t%41hQfb_E!-ysYM$a%n%00unA@1N191?i9ufR3hN>|rImFi9Xpz}}qh;j<2O z-djTbm4)#g++ZgYjpRxsAq1{dohK$ z=BQI-&3OwQZevbymB5PhWk(=~4JaylUBxK3_l$W0w6jLMX%;Wyh;HK?Q&gCMtx-;s z)Fc#@%hrey!owG^xhYfH+QYcS!_&smbc~Kn!SRjGB~JChYI=F`HMI_}6^kNg>uEo{ zZT?b!Fh%S$ZBiij&tEJnzZl}8+o!RS%IP$ctDy+%69egM{5gOPRniJO1fXI3f`}`m z{M{@fK}WjCR2C|#)KMuR2)yLwyaHA$Oqv@24_F|5^rRVpDT5>X19*hIaS?qettMA> z^MsZ3-oemBRlAYfiKgkQ>s#11m-y0D91gkFaRs zqf{NqEaw~VW&kZdSE{`FC(j5dOdbz+-Y|%|(tsQ+ zIrwg$NxDe1Q{D7A6<4P(U#ch-k>~JbtE{tZYxen(m&cRm2GKcy--^8#Hi} zB)9pWqz+P_IOwTRevzPvfw8~2g;3UK+J3Tjj#yDke-{*|2sM;BW&;O(%D4`0vH^O->3lDx-seoPrJ8WDvj5r64HNp*M$DehLUTE&NSrAyQy4D}j1aibh3{x(kj; z=KWVGk4Eb~#O91$uEaR$#O%uf`r2ThLVE}w;;kuvq#Ml;8|n}kMPXkPV_IbmpA~5t zz$@bf2@6}+5l9-5NQ6@PN{x_w+0XkBwyUA~5N^d+Z+Ihidy+0&l-JqYfy|v-)KQh# z8yy~&qElQ3rU@6j5oxStpaw0e?U#hvSzBBqf8-r~TT+i1ggF9Ha(+4vd}9$rf`(>Z z%pziq6+#YU;-dU_ah@qdwK>QkFf6j39QU7hBu~4-HC1g;j0tY<1}r-tq(}EXQ6>-K z!S5(_1+`HLq)8&)MOJ}bw zoJzY8Elh6$xp>V%%|M#6J9H4VbKb{qKHN#(8%9L&R=WxpqZ8sI4iU4N_)R3z+BxO{ zSAYdda>lZS@nOurQw*DNuSgnRzvW-L>4niH(!i0^luLuU+9kIag{JLKkV3$jX+yQ) zYp^d@V(foWkcjx-YQq*{>8g9nNc%qm^NPf0gq+hlH16^i$(!WUn>Nq$0FXz`d9tY1 zwkTo%YKR5kK|k7IBj%l+7rgdUmK~;=l#Mvq7`kolWN)twVxNk1+2(W&n_q~2X*xk3 zA~A;yhv^A7ab0)>%zD2YXi(SlybY?oFFGy`sxH1-*6O(Q=1fOo>SxfKr=Ap1k^fK$ zbyiTM1j=(CUT8abu@{I|g63RifZ#Ja#<3<1^qmujXcfkHl#cy`CI0T)U5*qp^r$$} z(yj;vmv&BWFri@ni+Mvv9%8o5JJ$F4uxKM`qt}Sx?d0aF>tJGgygTWhYr*xzeb2~z zp?EQ!@!wiH>yQKl2U9>6X{~Z_MVGbS+8BBn_!culQ5#xE_{vRNIs`1I2e=P7Fb~r!sEGZ?Cd+)Cgs?OU3f#HKCfk5PSW)sR_f+l~azZpahV6cZ5w1zO z_MaZW`?DqmzyEtdb14C`RUGG9v)=>461`_&}ZqItz70vzq+Vn2Xn?21zi3;1vJ z+8O$wFdvF}NBkAC4ua+$^dzk@a?tYOwFU)&p@IBu)Cqkp$iD@OG)bLKARen*4b z<-~6fH&K6Me3+DIIWgrvFULb?k-e3BwNRK3ZX#4U5{<4zAsOPdQaS*dFpjYhJf)qm zQ=g!yO-L8w5oe#!DE*FsDxxJ^Z_Yr3-Vj8io%w7A)5T2d0qL{U~-Ghdxv4 zXE24XNejc>sl2#A=$tCA)zZidbbs-DEpht{2+PqfngT!Vl20iTq;aTiU0x&z4R$_Z z;AJs64im`kK41alfLxlOTt`Ms?l)+7`3ldB zCF4-H)`MA}G=Z9wYz-F(Iv%X#pnae|8Z8+Y7=5)P8 zOLa{w6%4NrNP#ALovACIFpI_lUQ>6O^^Am}N=fRb0zf7e{vfsOm9x{zh=eO~+a&Kw z@GDE@N6t`SU!A-h!Sf15$NmKI5ESUPgHH+n4`}5%FyhRtUuad~ zwJe?)4CL#7xsyGcynrM=PsRmxh9!93#j!dXF zvnYNU&x?+twi#R&#l>}eE0L7)%{hakw=gKh%{u8|c{z+R1~I^-5F0txhV1SPu03~x zMf>FXK-ff$@D(S@%q?!G>v&!V{~+d%o_9QRKILIE-(3nx3?Ko zK`v%VMdJLbl_LoXe(-sQ%Q6M1`Q%mJne?Bjd&{h7QhhD96gn;MtP?1(r4)Oiy3&ZOV^CwG~D$=^$=5XFDV#$w);`yfv>x+Q&(?5B2b2#-t#z5Xyv zi{qSL-TD~#s1e15GXis<+Fm<`Jw(SQ>yp86yckfoX{HG8bOkf?xs$5h;7D&;OMhn$M*gx|||3u0dF@h>a8X+)$)L}X^1we>BP?Ipc!8+pNy1OmsyB~4=qCF$R0O{sF z^!NoRuKjAqH@x}B9@&q-`ekb}YU?0S7d+}UrV}r6D(w*+vimq7?honE5)>$lckgXk z5)8BVxc`ZFxx8dyDtMr@PJCdQyrVkf4MxD%iG6bwrf~{-LB+uSgM=86SrqiJ_WAR4 z)y`Ma(s`?NB$ZX5YiwXEkUC=au2F7xMVk-if+9pF5TkXL`0jOG=adQNXe4o2l(opc zJMeX!aT`qY5bMi_C<`6ZVK-rGTFYYPWq}DidXXB;nVMNl4STNdGF}&@Wz%+31Ma;z zTove16mM_W9VjX_TuGJZ?bWigpsYc&+2jXxt@l{uJcU<~C_WLc9*~yjiw!)07wGo{ zqR~M4pq$#H`WTNpI(>GdxHCIg58Wd4CKBZ+t$ zJ6DogA~a)}HqTosKqY_wVK8yD%AnUAu~@Cr%&2OAsWTA*$*kbnlHtX%UzI|=(pIAC zJH?->9Z$cQapI-454l#FJ8ZkD`t?e$=G!rlZ1hj6XA8B^-eI0+pz+1ck6AZqs0;O4 z-9TIN55X(>=w?!siP<-GERiT`SOzs~kvjvp(T46<}`FhKT@$P(2@t)5^D^FxDT9!>le*@wx zI#Cj|(8irrf7Yl`L4^^W{HOj=CZgWhxyj&Lyk9n+tHMEQvz|8(qQ{6fHw_%mlUMFn zO{Tdwg0azHQdO|B14NJhqT+is?2q#q#NeqrZOTD)xVeO9J`d1jHf)eg87BrrwpZCU)R0^k4>{klDg?q9%@GpOc3yo$SeS#7I4PuAC&hA+gC zQK{9>J8h8Lst1@{D|kZQuTQf;A!{+WxBl?~q%kHV`KTD+)QWd2dE6muD>nc(TnN9p z`AYaoQlzQn@P~5$?nAXdu)2hRe3T zMD%-S<|+LkdJy5?;fSZhIA(s7;sxCyq!!IcyW_-&)mDAv(FC5*NLG(*m~jmh{J$;k zyj27Tjf0yb2XlkQNTEaah4GZrEn7R&aLHdmKWBH}L!7mN;bbcI_KJZiy@LD#-H5mjV%?HjEpyq$Q-_=f zME`a4+Dh_do)Q6K+sw5rf%W6Cp0VvM-|d@VGSU%1ez}Ly2)60MN|yXvDMdt`=4Fr& zyvs_+Zg4Yu-sIgi^RR4b7x(vQq88Z7BAo~YDN~S##l7DHv#eAI!QSNV{R-N>T^mj` z|IC1>cn2PZR|rcHGxa|m90Pu2fbE9UW9w|4bYY+cQGlYwmUgG##v<=oBZNPZ3x>;j zsr5XdDQav3N=rflt~w|x6*+l20i%+ppZDG5DzyxQklnVCN+W4qwb5SYr6c zD?=_}Bl&KijhBnRp+uT9xxNmpMxCC8Z)5})#OTrq^{3Mszw`5B^qXRljfPup^_BA( z6^Ea3#qp9ypA~hUjis0jT!*zEe$P?bfH2m`W0M*IsE4ENngu!YU{KE{c!rg!EYX#% zqz=Sc92}v{nwPDMn|=Q&63~RC^i;k|>lX%O7qw zqAqdU)keY4p9EeANb9rG7_81#yG-65MSI|KS1tyXQBO-j3U08`GQeLtcX& zR|PF(O-5H4n^kB3M6!S4>iF7pD67urepMUj`%Z?p^O5TEmg=7%Ib4$G=4-2VlE%wjrU`_ z?O-gOGvMgN052xkyhoo5J^{UX>YS^(z+6B(n;aRO-Aj>L{7DNam(7H&QC{ZOp4Hf*t+%*NWb#3-BZO`gT z9k}OIiV&;imMDMD@Cuf{2_L|KyTpTq|F4$)D zxbn0^;Z~0>)?3KLVgDU3?XN;pzht`b7q3+hN9k`;-UrU-gbY!J*q<}YoR5H`UZHXM zHOQMT8r{zpUmC5sxDPI4kzcSz3gjhmWQBkMkt`uX^==al`6n@1{jI1P@wX=%?Zp{q z=%a1JWS7R)-v{0W=(>YT3Ie~>*q_;l2*P4{CU^mm=L}lF>}Xx<6&(Y;$V{rl{3i4( z;Xjld;)x@a8G6~?QsxbCAI`!oP=B$${HXgFT0B8$rHNF z=?X4m+a}bTJPQ^CN4t1ztfzNSG49qj|0~Kc{8T9@IC_VRYp<%Z};I46%`f`celjd!0(!AR8 z?PncB>Ua)JS1@D($EFwY6@vpe+8%piu-Y7?*Z9U#m1+){7KT{>poX@Ac7k~KqYx9f zYAOFgTHFX>k)A4+WkL)-C2J^>(F$SQexqU_9ZswypgH;4+B|=U(?OG#DvK3tcoJR` zBj)+m-`NzHy72U{nW1?%$?Zn`vKQm~a+xLR7^z!`MHrcK60Xa&D`@PaVbS%sw}xn)gwM6t`tyUO_sXWT z$KWZL>ENKR(_({Rb9Mwt%>Xx-IkaESvp0w6T1)Y6egEMrQ5qy2(guZcpN;q;yrH$X zEhdqcxwQc~3;p5HjLsgc5}yN&HA-j!)f3@(iis+m$BLRRri~f9@>e46^l@Gq*Xgh2(!>ka&wNJ;UrVj9#|C)9rqvv&U z+SVeaT#`DTT7`Xg#GbY=qNGwEV#5;o6g1$JK!JV}mdN|S{f`_`-Tv2&w7)taI`SL{ zWS3SV(2BB&v)i#rofoXt@}&y*W92}dc_!9T|8cqcVYxaTSqI$sFz?(Y3u6*QWvrm(Zq@%Nc8KaMp9pu#}5FKun&{Vp}5B@OJ`jV_XH3HbW+d>t-W=05PWnY z8c5d39KLU4^bnxy(fDnH$3NHel|M#p7AzuL->m`ckOH;({Lx?$Em?sG5y42XEI*OZ z$6qk`_={qJB*!#w1AHXVq3h2MSakKS1-}CbvXP@N@-$Y9b`f(PFc=GND#;TCk3)-a zSNlm=$(I@RWxCot%K>K(Dkb>kYE=9-V~9` zYt4yG07MAl)TqY`!C^zdrLEyToe$FId1Nd5u_^fK^nB|dBo7wFh%mCSOL$bh+Y6?E@_wU^Lt=k2OFxq5(%K<+(J7G>qpMW zgE1bGza|)~aRnUS{Hb!5z1kPb6A-a>M@#9v8Q^~UNL0KP(g>A$n$ z@LjQl>)7DSyegOE->@0%xrT!oT}RwLm91;Sfc`zsL7HX^+|ds@0t$f(`)gM!y9I(ZKDuG@>^eXWip2fM;eI!&kNp$w^WW}H)&)CNqL7B)+@>5q zIJI9kdAiLl$#$*e)2v=gDHhksNXs9Hw4og{2f;+X_E@$IkT_zqI4qJee1SkQ{Ow6V z#LSDfU~DG2ahYr|IQmKH&!dsHL*J37?A+OP;w4xT0^>^_=`GJ-sZ-#_$?oo!vrV@F zA)@vM)b8Oe1#_-3FhC{?ON&u2hll`Kq(}qRw)hWs;j?yiU3%(j0PDj%b#_uhqDygw zQTn27SNU%slvWvfmrcinuI{M?A^WugQfN1-zb>MA+;cUQ0SwwLJ(A26(w{h!=NoQu z>xL|qd9B6&3a3rItW$HQat8npMYp*efINgv-`^>H+v-?r-|J0Rr|nr zVou{`S9`h7p1YY=-1`bV$z6~W4BvVcPFva%i&i1xD+>5%ljzE;;UMe{JQF^%r}(J4 zJ|R-Vnd(fti4t=MqcegEz+*6RJX<2en%*iu->nOEWhNEmT1Dm5DJBS;bLmtRv~K@| zZ>Q=Cd@CI5mZy$i6rYXdW>}$w7t-S1FiP)B!FY@drWD?fZ_7~O*~~Gu8g{3aKqXh5 z6N|x9+bjIiC5KR+(%qPS8uCFAZ`yVRKaoQAFDuqA(7b0ildCIqK?KIz?MI8p&MGMS zggdPJY?$HiPL$abA8=3s6Ne1 zUHW!??!<;#4+M^>KAFqUBjtw&6-6Y3G*Wh4gZ*WCNhNtWXKIJ)1h6WXhq3r>LH-KN z;>DPxDW!Yhl>4$t!S}^IS_&MHkhECjE?xXY%!GQsg>B(68OPJg_b2g|lVBBF;2f;p&FHxol1i#%>`Y2%L&Qeu><>bIjBz+n7KM;;O6_Q>^ zk(=B64X=d?N_m3iV^k`yeJMlr6AQ3F5>hjxYP(w1kirO9C8w1LPc~;Yj?56^SCD4U z(WLeCKf8<`U>1kvS}Gd6+!9m6I(zDO#Wk&#-$<&aZ>TZ`hQcC(Tl@o!f;yg^S1Co4 z$cK9baWm`EhE_lDB|dTwQtG7#QoK&zM=5zmiYarsUYpZWt!I84x*xV_)Ih@{lAZk+ z5x9I1>Hd%~$Jk-gQJ75;lgWdny<{^9%Yx|bwt<$UQSb$Jxe@>u5;%!{F(CfM^{4>_ z{?QHxA?yZvIlMt>ol!e?-3NGXYT|;t?}(Z|gg#m}6Yyt;HJuYX^<%4xX)X+&6VPvf ze)sKeGTqs36Ns)&xp-f2w8e8v%rMr?a(Dc$Bny_z5(DRE7T2*kr#>QuGA|YG z!hIm=6B7}@kxJl`<97?fdJ5!d@hyby3Jo8upRJvD(DnrYs9Id*6Tf^*H12 zyt?VTqDSZhV<~@1loIhnVPgzPWD2D; z|F>BH{dTClRi4246I%)#pDX&i{=yRtM}{Y1#-pCU8`~XkDs%1r*6eXdrZh$%pTKj4oxv+S5jM?+GY!X<_TE{4La&cLfF9g+*UJY99D-E}@GA$qHd{fPcD#rBni4(f9O zC%_8{86kgDojuekywv*$q9&+!IU&v-M^*LMiIZsFadCU;o_c$@m1`ikH}B6TABO+D z47a1hP!#uSDcjHj=dJCm#y!IP1+J0a$%nmXK7hb86u zi%3D%`9f*rZtykycbSd+nkAKd7QwO)AQ-y9XMF@sL zv7j|{16M~jqz@Ud_}|}vAU1%{h-r_@{{Zt9)xX=yfuUz>j8L9drpovTLlCNpgjN=t zqELLC=XrH5-dd*<5YPmh!7a~9@Z=+FX|{l~zHCl)q@{t3)j@QB!|Y#9;za8X?!XY% zW$QQmiKeb&QI+!sp}3>h-wmvWc}s}SUGqHvGMbkmrQ63>+f%250MVu%?bsM|1Pil|^m~HeU?VY*_V1zmZ(v z=BOg{c1CeaKCN`7j65{V1K7lgV|Bd{5oUPodmPTk$?_a04j7;#;aWU)C7m_Z@PW|N zK0&-UDEXU-Ob-5wiKy(O6Nxu0Fw_0R?s?gp)%?kpK9knpK_x*MMyc>ZjMeoxlcqg= zn~ovjALY-sl4BM2dVtI~=xakyy!SaGK`n`PP^jJ?ka+qteD~YDbc3h>CTa&U55y>% zd`uX3Wg&B)(!=viRav>t6rurnEf;#O{p0mP3Id@a8YlL{N%@omc{_k79`kcOB3(xE z0aeP^?S6?Yp!WSVSaQEi{+vl0tM7~FY5k#ttarQc437y+fQ%7)vhwrapvz%aC-h&f+}G`l$XBmSp2 zwxg_c(t(1sE^CxxqkNVVlMClfrba%gj~#g3J^->wlwDB)v~#^KHt{$Ul0KkR z8o|CU@cX0OqnlcX`87&DzNk(QBW=*sNY?aw?K{fMjz#`jj}QpRp1Um;;MvRd@pdfB z|4dU-m9zN`2T#`bIrK8CI4%2Q6pqtEVqP~VIJPGX37~M-5t#V`)l71foBui>%)CHh z+{dQYO=L+8yf4y5=-V`l+!%B!+@?3wby_ITN#oPQt-tQBY*V&{?w&$iwwl&#EbOQXT&tEXGmpQwhmRaIt8Ai zn9`x-u?G1ib^*tZx#;&Ba_~k(!1C_^``>X9ahAg8nflk{<3~95tC3>F)%!7+@gJ;2 zr0#cpVozrosEo_LGEp7U+zshfHnNev+}{%ska0|osGh9D@50Gb_3iTS&+@V@$3$u> zVL=zha7+`-_0_8(@ZYNToa&;3E_(Wpa%T<-lbNy?H*5E6zN8fth{*_61X$k9G_%oX zR*-1>ZMd?_g7MDHSZv4tYB~;p)j{j*d+!emuB{79Inj2X2tMb8BktxMe_IY$xVXOj zg$Ib$0z7U{fdQ>s!wM9{_?teZOmK&C%t~9MW+7-U+*hv@bV> zCOa>p0JPGR)3nc5^-CSTeFPX=wgtI0_tcPn0Qyrlxl^U!ep3dhSCfM0R&8i-h;a?p zyHt<>PU7=ZK>egz7JBYiJelA5#f$j5ivRU&NBNs34k; z5IgY~O!gRh04njUA>+35acGaSm%|X9#Nm$o_@Cw9o9s6T-70bYNyflpzfzruit(`W z!>hh2t+F}gGK=HhTK6(~mAFhXgEdKewe?kKyC$!)1Zc~J<~U%NNhVnD z{Kbo9^&(4=$xZ<%Eq+xz)#B=y6ohd2J}72w9on7M3nmm|0G-JEEVDIgraTw9i`M^u zr`xt97eIfKm)pT1w)QoJKzBPqyidr0n^+yMj6xTvx|+Tw7d=fyS(9fw%iPT9Ra za(=q#{K|{%>}3mJX}Sqm8lf|alrMNf`}e+WPAr2KofQ>MUf6B`e#;jFV-{KjwD_e? z8MrYD(CvP0%hya9e(AY+oGJRl*f#|u^k=6`zG)7K(E#N&%{PsJ5Ld>v+DNsq*l>i@ zk)!Ay`Jg#*LqMp$f4qBjxqJSBSuYu08Y9(cyVh(0bebSH1Ara7QQ}&4Po3-C`kWqx zY7Vgf2HyiHdGISWQA{wvy(AvB+p2jQ^sXK;Zz4>=L+4j%#^4lK#t^Ow7;r>Jw! z@P5XiiNU0#{3=9rE?*$5+duquC;!FI@h;#WLtK2he`K})f z!esVz+$%RNA}#o66eDNnqv5JGDs8=WK*N-d!4WmHda4aWne}KH>}4s}z9(BqsaJc=itZs@>ZQfRt@c9q(Sd483f&vWt#GKz9Z5 z@k4te&xtB2}(k07~FyVg{`86t8cQ z0$P*BG$03_KhiE@%r?-!Rxz3}|CD27ovL6{qcAlJ6BdWKbX+IIn64C^lQ{IRyxYBa zxBbTI#UTuk`l!T|gb)YAyH9}(+lOjr0Qp=yQLfLpvr$S<#Wk@War7{YTtr%44rDxw z3^Nb>c+6|Ntd?Ll;^?Dkvq}m|L|Qyxv(V0F8;8lV&MW(0*LdBpn%k-h@C2tyWK9bXOtD78pghJ_{VS!8^x^4-OpUp)^TIP~+rbB_PPOU!gTu z76|&49hBfU*+>!lK|ppPJzLGAF`o);Wz~6l6Bvs z1!GxIX5a?PJzL3S^BX# zwb?X4YZj<1@n1?2N00!f?h`uPbMLDOm*wW==x zdd_AEFn-!iaY1?~Z#3stn@d-kn>wVxQ5_T4K@KJ|trqa}9O?9kb|v1vIlj<6_N|$~ zMOhfS==0XSv6qK6hHt2ULadF;(Y<_^8tLf;nmZqwT!jqX7-gimoL!v3(Tnn7n62f- z_)f8-eDVGl3mXe3?ALM;4Cb*OYQst6xU4GWIlXhoP?y|TzSBFqg8u`Vnb|qJm|${a zUl?pS#nWv6zWuY$auz3+;X3gDJo`kzf1#k5PqY0)zN;ZG*}j?IFcz#oJo^NA=h%@E zAJ*{CU)eu5xBqqe8;<7B2WQ%{0J*e78YBAcuqZXi*(+)N0fE&Yey02w6`yO`D}j>)OG2= z#th@)mQBj$OJlpmR@wiM)mJ4J?KJ2Wh^J`qQ;D6B#Hx{j4-m~T^9c!CxSiy1((nMe zVD0yIAY$sOA^1aq7b6MB+)jp-hG|uKSzT2A5P66IJKz=qU}Bo?oTfV`o$jn-WZWVp z4BHwy*~&xUxn-S(%Bs6*+5XCXw0Md6*axTjr!JGoQBNcf+S>lg`s(pF3f}HjSPqT%?1RadW-x%F}4A^Kc z(Mq<^2l_VqF%O>HKHTU1uSgnWTMSS1!DqyJcQ9pWeLk78mn%l)>I zJbDHg`~l6uR6eHiF=6?L9oV46RiactB6K{2i(e7&6y4|ctE-n1==G>_1jPZ}?48|n z^UbM~lrwBrj-z|1d*+9YGq>|U#bqik6BZXI za?pzxDCR^?D3QM3R@3Xn#r2V>iyg_)n%hZ&*F5;9w{V3Z2tK~vocdCJ-m~r)ne?!Z zf+!ULRH~5t?YQKsP4+=HP$vTSNoX7SoQ4p3?J7n8U4ps^4GbU1^+Ieou5ca@5sRGeVb zP^+gIR?oSs1gO%ye_U4LW(jSufyCg4(N=VVJW2h?ai3sEI8aAxtNoP~dUL}*(=sVA zG2rS>+sSjcb`yGnHf62_WH%oS3H%&DFa=d7EFO?O{}K?pUdr<41?|`avfv%ML(oMhs}@mA!KW%2vXJ{QCKqI*t+0SC{~a z%bvi?@+E|;%)xmc*Q@wpiLs4{EYTx;4q+2#VrSUBbb^gaud2W@^bpUIj?O zVz2`Cj=Mlpu$w(^&FyC`+SB&;eSh8YiMX$WvXol6axs6yrAPg7oN%Ec$7t{`N7~=L z6m&|MYU5Ua8Z1n+8jqaScpSB&F!g|cDloUX9cZZ)QQM2g1T!Ic-0kmaQ2`&HTB5ew zBp)+8-M&e-S2A{L!rpa!xAc5+4W_a>mDNX0q*-lvMV*pJ)*uewVG3_`N&rDab#C~#7DsL zk{U!>vMc{5+l9kAL)(`;h1#;oaodGM*GF;Gp{R5!t5aEhWLZ@MMW@ct*{ilq(1hUn z>T2`e$L(&XK8u3;3iNAVMWIBG0BU`FJy3r(E1wO2+rE5Tx-pC#v~P++^i&|G0x@ZU z2^3n^W|poePW|zf1i5r4dznXvMF8}XXp&k_Nt+u zk70Z(d)~}ncpb8e{VDkTMlZWS37*~-N+SYRuMl7dvL<*KX&RS;H`~tdS0Gtdk z6QG`^%`a2z$GQE#**iB(*!}G`zW|9{m!9!c%Gzw7od-|?>x7o@$84|-WYtWm>~++a3xF-WJh-`Ih0 zseWUem0_7D3Q|&U>00;OWlGQV*4_gTF>lB|h_DoYM89tSd}jUL3Ao$%Z~8m!Pi~VH zFmOa!J!M6kqLh$>Hz+hts^=vDzj5Hj%H1~0HMYn~6@^J&Nd*WXDa^k^;Aub(gG`Vp zAh7IxvIfw57JnYS%qDPFZs4~M6%o=@Ote)g^`ihZIVjL+B0t9gr&_JT$q`nWK+_sX ztyvW2q;7(8ymk&PE{fF2w#;Y-udI}`v#8bo3k?qW@djs^Tf^${*ygdVz}zJph@pMS5_~)^xR7? zKj}W@{owo_|voc1jVGb|mB#iv4I#;bhM^*4!6MZ0OPe1J0=IUtK|Ip7Zh z7t-Wz5P2gb8#25^K>=a~Op$SqY7%EeP7%AyW8I(-d@`U{qW1Yo>_^lNxRXf3p5jw= z1_Ph2iLk{XNM7QYJkLq&t64k?JB1rH-Z=rKy!J70F}d%?_d|FrTr1A)eSK3i4iD>J zs+UR_n>4q+yU4hZKJ9=+j#1f-{GBIdGxStP*1bmW9~Noi`GM^PFeC+w z!ze1^TFdwpc@EGkJUX;l9_jBSQZR-CaPCNFH@ytK@Gykh-9b9OyS5CN05&MU_z4p9 z%tu>eV86}M*EBLpW9(*w@@`(ZQQ>Jf>4izza6lbrTkc~M|hf-4kYHmebsAp4NoO(I!1;tCE(vJj7^wh3Q z?aGAh3fhEy7c-kSfHBb_!Z8)U+}& zZ#&JLOfx5cN12m0PHU5~QztF+8rc&rXH%;=wVID?H6KUj#7k-ig%+u~y(KB}e{$?J zKvo0j2GZn3%O=MiJB0^QhF~a`ar_#Ewke_7G!yc8G9f`;r#U+B`1b90RWB1>3>e{}RuX|AEa=W(UcdV>_>NgC#=;Nif0xCN03X>O9XioH zegy2q!y(e{;zuM*)Hu|>9bsD9(jz|XRpC0NExxBF%otoW<@r-PP%FN2o8AB!F(rIjP}X#SGKuLWg1Ks#~ZAVtYd z<+PRK35T@Nw3Xwpsg(l|05BAe6e_jE`mF|m3Bh9?w2TtpiDS7%vSpLwwsQDMQq)03 zc6{n_PCd>Edz@f7OoK30TRFCtnkLc8;T5r;xivL155hD)Upa{;4z#2o2u!Acaf2bP zsZsmg9Gu=sOe?WnKd4`ILby*>Utx&5+$oKB<~$Jp8*`? z3RpDLrrxR0ObBvAO?Ue)7-)-1Nly!*0Z&@<;2n|>!DKQfbbLg#qcl46c}UYJmL!2-^@wWj5SAPgbABeIiby*2OD2G(_Q(# z+XmCICFg-TQ6~-s%=okkW192$`)|Ssf{5q%w#|8X0pqe2`Os+`HI1VlIgWZ9O&9>Z zDFNLiwdA#=6I$ty|3Aoi0P7K%nJC+|u`QcywOV46?0?9UR>7qr->dT|oHk)hz0$|x zm4fy=_CmGycdL8Y?(PlJiX*;mT1Sqf*6wz zA|P@+>ff3gxT%4AWCJ&Hz3bYqN)<4FBz$VWw0em_p}P!|Qfc?6_=|9)cJyyu?S3&& z0ipPfA;J{1ES*2N!Oz~@GrQ-x*PeX>Y!U_7Kq-AQ6_2TSOj1&m_VwBfgi}?y8+y}9($uSZJYJQT)!s<1&n$hWw+=wz^8`i4N~4Jr8<*# zhKmE&W9g9@F87%Zz~Z|%-|l!0FbaVK*SmU5Bs*^}G$%gn>;O_e`ypW|Y9xGgFJTrq zC7PUciA5Luhd#ipc$B8yXUnXai_x!*opUXE53M@5q) z#726E8C;_W?d4RyHie4BPU&VCJY(%F+BemsPwn2ldv4~Ba|Z9{c>$WNV{%k1o^W9H z)g8azJM)JFJAOI4|FySXo!h(rji2v%W6y7AUY~hmj{WervwL2DeeWB;eQD2u|Jt$l zjn`)W_{{I$nladtlg5!#M5N6vwuF~9S-mP51*j+?jtEEOfd4|~Cj&g_(m7mUvricn z6|kdgZ3kdbI#_x;;d<0h86`lps$A=H>z%#;uA1J;a_`ik&eQ+!+qr-0keDhz+A7or zhaFW(3{s16?yt$}IMO1)%&DgM5Jy>=<=bK1wdx3Opd)U-)7+dl*oWhLW#!bO8&kbf zevNETG1dtfOE3oGp}B2!1ff>6oz%w%AY=6YdSGyPQ8h*yKh`}Omt?xxOlR!*0 zAB~;dMSM<9<0If#@y+qEJ9Gnfs5fBgM}t#E6rH$^z3_<7NbGdtq7h+`z=rIteb7CB zLHq_A!>>Bs4^FJ#J7=(~7==hLD``^i;r2=Yt>N8dWtG>q;zYYN`_^%khX}T;pYfk` zR&ykX2~g+D37wi!I6ic%S$8$WOcPaxu zR3vwwVFcOYDzB|IN0-f>=7bpxQXOlbmZ1WZ`}8!s!#0EecJn-m^32)?*#iG9J0vY)Hu%n<1BDhQS)E;31jHJJKtP6_7fujedbHn74TmKTk(0@i z(x04_>Ykg&EPik8R`=*7$j0W!97>IW6o3e&D8g!+h(w#uX#bS*uC^Q?ES15Y+$>BT zs9;OUG$TL=;}Glx)_%Gn0f2{L&?rx}Y`cz|R%MN0ZRV!Tvj3XfxfypcVqX?=K*izM zD6ln)zFZ*W)s>g)qOTx{LPnfodz46Qn?+x7l7Xzawp9fKDu|b|{P~LWJhVn%yW|rw z3dNi#%PQBOoN=PBF`*#LFHlMX!;a-AX_q*B4$_c*XTCaTHz>ku={wjZ&5OO!I| z-CS!HzuDAFvO#=`S#+|4J1E&>pcouBy9r!_i5(s76UtLKj5blC=T#AM!M39HutVFb z$t_~&0LslRLH0edNQiqXIz4W3uUtfnbr9Gp^7bQAlBk<@*)RYC9bV-Wfo&?PeLJL? zn#DsK?_aRuAagyi45C?Ua^H!ecAskwEi@~4HU-Ykt8;;@2;92KNf&*sM{_k%EY989 zot!SWb?pq)5?UBCAOB_fH4Xih&`(mg$P5>6N&QDf1Siin%pO?jAz_o5k={kN$l&Ch zx`Lwz-bg!rwNr3InQiAu)j%52L`8Lpc-y{aW!4Z7$7Sm0f!1SlYvjulcN^8vS|SK+ zF@3-~;8y|oJ$RKsH1F_sPVSw)vhP=Of7&-Q;7=A*^!W3Cr%7Ok!QjmO>CKsE`B>C& zmFM1gZOdPH?T>qge=d_Ma~kEb*q!&y{Dw^=kM(a~**`b8|MhYI^?-7AtVjQ~!J<6B z=TH0JVh6eTA^$$;nS3u4u;B`(kLLme1@|3_5;wU8)5l4p%=2>6OI#qP^h``8{Iy-) zVrJjIpYNIF+Ul>Hko|GYw}qJ1Eb^EfHhu^#qhtRkF@3z!FSAhe3T?N^aWQ@32pwp7 zN_pI=tWIYUCOwM~xf)9$EoHW!`K%x!~PPx^`)CkLfm#HZnP7n$;j(d4kz^ zA$`;c)f!|zL@wMqLAG4Xt4{63)Lu;7UZ4Ro6df`Tw-=NHx0Z`AhEtVi%0!#oLuqd> zyb5z40Qu#THkFI1TufLlyb#TOaiU-|ZDTJed2B5gXwOfx%As7WkUm;UlvnSdwz}L~ zIYYU7doc+^WP8JuT5+agG8K~vi%C$_VKr#_G%z2$U0_VwJ~!}l{C~xTBe|dj?WF^) z8^~>YB;=}e{O#mw)Nv{|@cbwfQ*;miAj8hO^#|txu|I|a%N+2VQG38pfw3N+;mQyF zER@@19<%x?j+4Rp#aO*&Dj;_93eTl5SKDaTT6YN9s1<6&-IJG_h0B`VjqU^9w^s&% zc3uFiS#{~eRPP!b_rGE6a~DWl*Kg0u_j7lL&fh^IrWWj6!?|?|Ifc|aMo^+x?z#jy4_*cItxk>z-rH> zWy0OtoN#xa_5$2-YIE%_f6-lD#EXdEet4sMVrAp-;f=G0@WWqJ)#f{LsNDX+)6G#G z1kx56$lb~T@P_U!oWOI!sNP0CTC{_Qfg*X|G~jD+rXj|pic~+??B}6d_@$DP166wW z+!328_{jB9{e(lRxl=JPMne#p^E;*eYIE;?#}mv8KfhKBt@31!L~k9d=kJD0z#%oPo*XpA#Z#rrUkr z1>2f_=nmt4=)Lud$N4P-^w8RO3%vaNE|LwB3h|p}=|=z7mj-7V#ED-464>^|7>ru~ z`**vmr`B(;b-Dg9cpA8b;v_6>``rv1XQMO#^8-X$BaBc=;BhL|T*umKe`SR-fdt=Z zc2T0Virp&JJ|}kEIM0n+ZHD#$k3PFdC2ub+RZwiNOnUc-LN(2sowW3dz47PS25y?qCV zwXwhe9yX8c^*w*2kNHmqa_I)ZRc3mSM{mSi|EAK0)#`W{tR97FomGL>QH`83s^UuO zCYamV{qAb_-6ccKiio3Pg?^0&hgS)z;hJQ6mc1HKZuroaeAm`*pXk4HuY2~v`q~$e zi2jjP`A^MU@hJ2ww6aqeBA&#AzW3?7VliCkwI4{}h`bLGR{!wV;(@>p<@@?a{2oXW z*iUoxEZh*Yrw2GcICa|D|1e7Hpbp3l5j$%nD@M;9d92yd$3+%F#cBbD0tc{=kv&$6 zu~BmajHhAd#rDQ-nZFlu%|U?%u8{N*j7C3z7~=%h1m_Z^vF+!|>V=n{d+FsT-KX52 zc7FNdb3e~se7W;Ks+Wzdnp>9MB&R;aX+7f5eUL^`io0X^@g8Q?9%psS7j$=O*NeP`*0vB&Y_IHf&(90m89&I1m<2zocUFj`jnNKgoD}U zi448V7k)yM7)EooF1mW+N?5x|Y)^QZr>>)qjasO2_8N#y>+U{ z(1-I1Hw7u5t#)r$5VrFdMu!%pNsxw8lWE^H$?uj|AktJb&5f%xDg@Yt?uP>3Vrpa29 z2LuSeF~Fz3^=KjlPr`mJ7Il*}&(Pbc`HH@u#Ch#2{R$%A#JzSy*F1D0aNTKLbEj}z zB-NFuhz7#FXIS2xg39LP1%O4+2SFfWa5r5POF|b#Sj}6-ZW&j(Aa)ersrmBl?q}yH zf!^7@%{>tOS^XcrYc5@2#O6!a5wo#FSzASb)SUXVS^R{~$n12&3=&;nQd_fA59#6@ zHOVI|Rh4nzf_OA58P2Zd16l$X`dYi>&t(>}U>Y2GL0fplb_+YHkR{AZR6tOHu{)pk zjnN5hv0N4|xXT)d+-!2*$Tm@wp@W1wn#4gmxz9&i(nl+Xd-75b^|9^Dp*D%s{^dx6 zZ-sX=-A|MOa&UrCd9(EK#^I$$IwL1aa#pgQ*zFd3n!mf5`SWZ*bwXq=0_1Tfw;^sg znz1(osIV9?lD0L_ZEn#cu*VWmpx(F-XvPMYJgZzO!m+Yh)(V{*)vHS`3PB4 zfPqbXOP9OnE_4_?%@F_3WIHZeACq8$&TVh$TKC)KQ7_2`9WH>c9oG{K0Uq7o_8l}* zCe||7e!(Z;Z=?GtLc5x6sM@}#NA$OSzf21hb|!bRdDaGHSyrjA0m*VBCqY%&ww&F5 zGGrkh=}w19;-!Ko&)h1sZ>f9yU~lbO@5=kg(a_V z(bGC;A?(oOSsIY?erGOrzxxoARbpG<_aWvLi$-b>dK98r=)5_w%woF48r9LdUVuBvIEmQ@nhk%HXbGu5m4YzQa*t;2o*(6blcu(kXXx(vc?S1FKYi$e$q&>#+j#!1?F)W~ zb+>kpA4cPr$)yYHAn{yY{u%8Gh`ppLa`FDN%$fp%NNP}}htOm&+)c9zZ{URD_Cx*tCJjc}NByTdKpgnb>cjd;WQ)wk#KKj&(G@9Hwp?18v=sri2;-n()X63VuPZl0&PsrcYKI?s()SmiBt~VbXWU1Zp4$1c!o4YeP z@n=&~kGQAUL7CQ>psPQzsR0)iryBjO6Z?F0rP%DiVCYN!jyCfQh&@2vGHFks|KL=A zS%6arB8lg*ffWa2<-}l7O;tr z{}E#^K)-!Pr3>>wvfYVbF|{Oy7HR_6O+YW2;3x{A)wLz=wze3VRQ52j>G&9#nV2ln zCfk`_3^Egb3Shmew2sw{CR0#?4nh28t9%SoJ8@P9sUL^B97i0%)S@GYAN4FHRm5pM zIE>t(Sr!F6DM<*t7P;4-`@`STDvJ6(^PJD zA&m;|aNX$XwuA&x>Blv^$tRc#CZ5tgex!Sb)jX&)L@T$}8-sB zgQQ87s0M@FYhK>y{J{-=_U4}1J=WqTKqGXh?VXL2ByoT%^928AI#jvV1{08q z^5icGt~r=6Y-9~s7Hv)hOb{7}8u)I+aoEH6x)nO8Jxn@jCchle(vLCd$MQXfaNd5E zB5vKTWk=hquyYf>_m{K#Uwi9S2Gc7+`2PF;+5h_8{A-T$HUPMw5kd&l%M;6cNy@B~23w&&oXZ3N3W13-D^k zQ=JFIgdNc_G{ox1FGQ2@%Jovm_P_C)y|b^sIP>QISv&tA z082<#X11kmLovm)GTQAt{dY~A+AHKVEKrD-&Y?NPP``pw9NnN=4g<{cVRX%U5Wzyf z#%=^9j{9WkSCMG0-@ev7c&GF9Km2y?pE~_7764LBe;|G|o-o&8f(8mQ_*zZUdW{W4 zG%7Pd^nhtiqbi)rOI>d}Xopr+;SE&9?RT1+^CtVK@(ldH+I>LA%PbY1ironq1{wj- zrDC7~T7Py<{?Z&@HM`r9=fwbrw62gV&8UKDXX(cdbz$v#G$mpjeUd)<#d z*|>MAxqODwr5*X!8T(@B>5aU^w{~UzlS0`4)%nkj!wjJvzi6)CZ4R&E7u_Rw&<9Dj ztXVmZIQ)MZ+>AJJ3QVg~F8JYJACdc;TjO?c3BpOWo=4w_5eziVn0;NK0Y;d_w{4Kw zN#sbKZ9lTWFIM_)S?;^#yZ^9p=9a{j7GC;1;W*I~?CqB}A3gqe&_vPKz{lU2P*0 zi%>A&ZY@wabu%y|7-SeK`|-IgaGIoT1SOJu1V+PFF}T4n8DlDwgWJ{K3plA^D|B;$ zZp=Ch)xI&Bc!v6AxQrZ>#bWN+^MVjONVXcGeK({jgqBqS@8jkh2MHV9kX=~gcwjJdEK>xBit`gdS zSw_&nRV128%yoSGo@|GSP1<1H5E;G9q2{qkY*Geje}vlw+Rn(@y=^}_c~`nSX5#2% zz=pA(r8Atn4nhD28t3iwUR0b#AtEK~_F-Xte*MC8|MS;X=eZZk>OVTa{twn1g4T46 z4MK+Ub0iE%>l&OKfH^}qv=+{tzj&eZ+AI5?Y2C+@@;;1upxrc$OE0v&?S^?5Fh?TW z1hNB-+lA4TEUZOGi&oBB-L9b1{b8}WbQ53;7~nBDZ_iC#KLLoIW*>2k1a&RCz-O7e z4TdYh1N(LN~QY3zAxZvPW#CO`21Jo`kzfAQv?S7(MjOoK+y-|yM?>=Os}zVX|AGwd(D zx_{sP*=L`4$UmNrX*}Vu)0+F!n>f+e{-OlQdT%W#5|4p~`!0%qeW4Pvcb>GaM zS&icO&E9>`D`g6(0^SAw2)6Dd-WntT;*6|3S z4l(F;?%~B~F0R zp9nlaG7dZCWgjXjOl~MIpo(CS7l5s*^(l-R?eyq0kzbYslQI*{spH7&H-|py?CyOB zg!T&}Z@qr|)8^=MbL~ub<@?^+t?toFXuD}1oY`&GLmE|40F*(V9vRgbPFbfpCL#Hj zw7D|gfrqyhe<;q%3pRU5BV<=c@L&FNcM)B`=-~Xz-6NW#9NmRqf?KnU_28nwA`IQ_ zS{_>RK7oBRDY!rKpw6{D2X0c-c@$Eib#P=Q=db4ClNR$HSnxk8Cm@$ZJm!-^$GFGKB$ra7MV??3n$>@iSG-7n_x ze;Z#Pr*yxW<#0fY<|e*ku!f%o&!cq-^$Y9L!^9>y6c~PJ_9T>jftwA@EBOHgLJWh~ ztbU0p3^FLn42IO5NYADzCF=Vd{Qb8LzHEe6bM%5}tBqj+PV519miV#+r``MZ+x6S? zy(5ceUl#Flie_i+;1D`cF_lt>^7{|JES9H}CPM7aZuv{vFbqO;Y+U+cyE)?w_jqo8h?1@RiiF#5^99`;`@lS^ zPBsI)d=hL&>(%N)__n2^IP}mHsAs|spnmIGMrOg>0!I%MO@lZB*1f#4+>>*N9f! zMW;c%&qiOy4-!~9{S=uOL}4i?p$2z)>1~Ls*;V#4^nS*%c4imt{4O}&sYWnZ8+e7_ zKIhmP2I3f3kcC_@Xo)2T{1ObF!(a*Di%Ni4E2@%C(BL0?QJQ1aRDA^~)>RW56cLgG)0oA!fGUgXh7gYb6r`jNPF&Gg}37ZJArE zGh?&_U@Z+^BtqdKL@$T@^@(Bt!e#L99ng9?Xz0{^Bs4u|S-RbrPOBaZIyefO&SxJZ zJ8r6HH3I@d3bGx=SdlH<`1l9JsPdy={+ln~?tXR-o)C{(zv(SpVVeKYC(XiTj7`ca zj|6mh+`ESVz%bH{vl>v=j@GpfLYC~^jw7KZ(hWBw-I&?Rm9M(jE_Y8}?w;G8a>ELCkcJU3|S3HRsn|r(5)T8IA?iCO3vb#&65(Lm*oZK&~2}Z ztWE|)l3c@3R%Y;{ab!5GaN4D)r`o-=iH0aDfS~C6E|CEP-@|rnNv#^f>%i=wV~reY zgMFa2(nFl9wLcLIW8ziHl_I=WcLR?t;EW zf1iul?E=Ig!EhUVeTTT_f^gb`6~fhH!o9 zUHIl`=l!mK{YUwkCQozmc5bYqi0pp&({|BA`$ymIy?tlg7xm*Z1^Tc~n%yJ@_G(Ru zA#n&uU37204It?MoZ=b1U@AQ$UvC$}CJLqFj82l}_YwY$u~ z^Ql&|+yGhv6O8g})1z^bXAVG5+Vw=MXjq4KA)+2P(dW_QEC()=NPUSjY!B_W`ViX` z#z(DaP?QPCp0uAb1`i#hso=*Uw$WI`b-107{ZN0@7?+70F(fP2mIq1=l#5r^5#mlI z4`Cb{IZ+rOO{BaVNhn4%3?7cAc?S-T64cSZCr(9!C48X51D;E9d}#@aP7Rg_t0+xN zRpZcgFrJ%+e)b$(dYvpgU@5`nP@Fic7!jqGAojGCm?#Nzzs{BT)A9niHLHlLcSwM% z7@Qrtq(g=tDBo_nJ~X>*u!NU`mD3Rk;=v{6>_^1vW3mJg?lXKwc^3#=hQvSyO9Xxq zBbN8%CFmZJ=`vUXC`OK(IZD7j)V;>5cx7Big_^68t(x&dU|A|00IJGwwADx&ycZO@ zUm*aN7qXFZuXGAT$;!Eiqvb>423rX8z-5u7yah7B-FKJzR}LC1!Nv+P&8M#v0D%bE zDSAV#AK7ZMtfTnQub~VAZMDnKON<`4iZqc)ZJXVnQ}`69&JY836H?pkip#BQs=V`uVnA~iaZ24fGgqx zOBIh{a6T&D28SJ|$hd=+>M?!FqAp$znmx6`;Y~3qJ!VknNp^R{psD0`uE>sBEu(vO;CwK51w~u zucgc;RAY1*Aim&}a-)eEcuz5)3+x^H=ovdyA{R(?07uk%tiH!8cPixW|Aqf_JUj(X zsZfk-Yv?G|Pfd)zmJeL3B7tGi_!^;~fHAG4gowp0z+szB#UtAsl?d8xuk!X_MDigR zfe`@^sjQ;dw&2k=q}@?I!*gZlmA$`Zz(3EG)eA2@_tMKxx=*=3?fmk^=YF2O_;Tle zR4<#LpagzZc#f#bntuzkJqisy!~+U3OwQ)?8R~$^<~;Ob_=u`4zhnF66k9Re7V=_t z`$Bcj4U?2|-xEAE?s$kp-nIEf0V{fTW- zMwl8K_bQIkG68|tW7(DN(i=Gcn7Tpdwmr*-5g=0-L;g-9#RdqqPNrB z2`--B0GrGf}!68fBC zQz)e|oGR3Wf;5_-XFS}@h(~4N5W5JfGJvjIiqSR(MzmP-)WoKzVzVVQH>|$~;7fF4ycxdDO3xu<3xDzk%A}0tYx|7Y6(a=9}F&t{{mIG=! zMwh&8Iptwr>(Sh}(2xBX@VJw^)r)7*TC~OLi(5TJqWzcZr80Y|deQ_Q&Ov*9S=yHh zjC_G02~qtF2^88~?-}|65x7QbrZhCZ0NA5YUE2S3{#2=E)C*Ie{r4Ky zh&rn18J)_-R4yhg7j6c$x*XVBJf+3Gj-A_B3Mx-p%LNE~;sSHl@>Aq4W_!7CVnFQ_ zK+~FfPzs;S)PtIk2jyV$5|nB3jon5rs7_9xRo2oG6lq!&qCIGqWKdr4q0+&^Zym65 zm?tHgO0*+yn8EU@GTx?{qP6x3ZYbUi!~jMXE^Br-+72IrS0hgJ0DnNeOOsf%%8HlY z{cn3`{;&&JmVkgCl@Dc^oN*DL3#_(o0i*Nn-CS!vJH}9Cjh~0wdFgHk!KF;y3o_Jxiq+P#J!A6@%tx_X3D!Ai9b9^&Y*c=+tv!bUn&qFQ=S|PaOl^ z>$i`t-@VxRRrX7>A#dDpHk76e$jb|}B|*A*`U1h|Fv!*~7B&`6;1}IMD49i*K0YO@I!3Z}$dqV5xhX@c(3Y@2@9ma+DDbF4kZ*QWgt{W_sl8AuAi4*bF? z^_a3w;JKhs=igte7h1GpY(Kp2RAJ(JAiLGvam*OlpN~b& zYH0re&yNA7oNlmIlJsAn;HbgC0?u0!?+&M5?Or_G96luf+(6WWzy(+VR6TR5EH+{G zp)qsB33qh|?9~_nieg283Gs~#yqT%;k=`zt2=S{Vd_0~75Mj@+=Ki#AWLO8?7%eqXB}COoECc= zO=E~a3qVFmes~LCC0PcIL1RMjn48AXRse)SnUk<(ldX8DVw3EDX1QHbn*e~$9iwq9 zP0?WxYQCV5Q@q)&og;d1i{Uv!yAVW zZ=5{@oHvkIF|-`y!gz5cKh#RiUa2qI-l z6bf-M3a&A`OS``LfzUUT%UezNu<<|If0Kyc<{ zRHyPWm5&L_hYKLU3LIWr75@(0UGOuutMq}hriw;Xr$C-9lu{Bkj>*(cLz1rE+I!8) zr|l1Evm22Q(!*F}9Hw$Hm5T|>MNmf`06r8qt9SJn!*E{uvHiO0Wg@JBkcEPkEM#b@ z#Ck$92IhjCt@h=GG_e2CRY1J}%qodj>r!+P+MVM9`S;f3U~4WGIQSgAUqBTuU)5}I zw6qkLK?uS=EhvSLOre{q5agf$5@d)x?Mr-!8)vTdPF^=l9)>^_aRI`md-tHsI0IGt zyX&*FNQ@eSkR?bz$M(tp?GY)+#il$s9f%neMOY_p>DcD`+vmQsO@xO>!XHDCGXlUc z`7-AD>Gq8g|09vcbr^hrG47I|xUM@uBcH@p1V;S;r_B^P3)PbhC%ghHZ#k^5kC2;6TK@pHi0>S zs$dSP09Y(g=uQ&5XiKH1^V-a-dr|6p(oLQU%y;H^=>CXON<2;CN^i|7jJdP0c1z#Q zZA+u=m%RVOLUWj7K79CK%snyS?HpR$(j+`|PuEYc-#<3yo}8%m@eL;j*da=&CoeQ- zFK*s<)Pv1$l^^(E~UO6L`mDg4V6{^f7ClHUgZA`1KzoVQf+fxQjQq)A zSys1HN`T3_-O!Dk0HlWRaY0}_fDU?~ndTn$EO)|o3f3K-Z*3Q0k#dGSt9>p3nr&HU zIbU%q9aHI;uynX#RYYE<)DhK@G@W#OjIobH)+1?*I4=xisdEi8HWx1U&K(o;NqpIH zWCTGiNZzJ0GVR-BI``50HdPA}CUFsr6w)3lBb2MLmJwjqhB?@LWD6pfrXDICZAHr{ zu5u?0wPTwgfsZoeOZY?Wau#7nP?cUg(_Q&qv%ArXr5hD7xP!I1lPL1iG{k5T|B7Tj zshH5-B{8}_3b0v}3VN|wTEmhY8M7UggXEOF4NH1sXu2{E1zpl$7k2c5?ipommF3OS)~u!Qe`cnVPIx?CMr;&zf{D`J*%e5T!O=K5Sc0Qa+v^dfg;+DqO>L1o;>4q zz^UFnvC=w#FseXe2O|e{rZu1-;l*gaJd*+N&$}Nt3yaOA6G)7h_13s$>4KJ9PgEQN z?4(jV$9IEQdzav1E@s}Co0;8J?%(^yZ&{Os&hZ$1BgRk&^ms)L?f(6);;q?PthPz= z{HwV=b8j6mSuw!qF$m@qeX#rG=XcT7$5(G2yt9kU2a&#@S$B7b{haWO&V5Y)F7$^c zS2Rh$HHMHvb2*~Cio;AGiP;H>FT9!^JT`gI-2AY2Y1LpmLFM}qh+=iyK^zYpfI{g` z!#w=@+GXel{P+6pW5Si+om}MCr@i=>0DOP^5>w|xTX!GcJ$6f zNl~DwM{&^x?iJ%{>;HJ6fBS2LqryN!g$W)-`;(&RoxIUNV_dq@+*~qP$cezl;78gs z51kAwYq9$B{A2d7yxS~(VtBl1;1#eFbi7EyaIf-}eT3DG-%kf-p9r47FsT}T4#Kd% z3(&^D+ksikZRiGOjaU}K2v`$IPU1C9PEM1PkDQ!*9A!2q&f&SqA#6(pt9yPK_z)VC z^Z!Aa%`3ekEE6d_ZP{dN{2(^jR!E2fKn0~!EYwjeH656p(7pZ{=KQ!}wFA(n(H;FTP5wy)PF7Ga%Y%2)7VPfgg=ggvqeQ*UhO z)j^QCO4LUo7b)`Q$3N3#cl*^H^mwQXV~_yI)~=HJGFYrl4v>0}FrzrFGmiu@Q}Zwx z^WbHr9~G678G?D}e)@KE@En;3W*ZKEj)a-5D7dv-1-QU+ih~wLW~qI#c2TI&S1XpA znuMuIn6ODe11pH%617R_%thH#YQMC4V-R~~>6D3L3?NQy$scuCy6ozsZ%{}8`ybt$ zs~gre@&MY*yBm~F=5NO<-I{r~Z*xyW4BW!hY0{fv83eT-Dj7a%muya*KzdKD)62dh z+23tCy+%`?P6BR#&Xz%ob65rP$dZVaui$4VLihqKHD^=1LV$+e)-oL}jMd!!0Y(E(Xa$hP*88 z!ln`p%<8CeU8U1WlpW46u5N>az@-NSV;}|TfWW=?L389p_xM2o;S!~_!9rnz8C~Fb z$?wt{*pGfu*5Lqz{a7asPF>eoP?9)kYaT5X%k-HJOeO$>f#KUdcVT1s4gh?+N9Vie zuH*H3_f`zvDnOTIktW)?_#pL?$j!EyJ!;VxDJquD(ovM8yT`r&cJW{CE>f9b2f+^i zaM#*Q3a(K z3ld`J;>^!4_bwh>U;6@uFlsRYWJho1CeRNUNb`|9D5bNXNaM!+2OoDozD|b$`86w| z#(7bsfLf3*oc9bvn(j2KA28PG_m6i_PVCUSbQk+K4&q7cw*lMyMRWgMvnK%?HOq1p zb->4q9{C0@3cP5n*qr*ZIrIs1V`sPgxZQZs-5d8#HJ8uuUp7ncbwB!qwt^qLZSa}h z99Iw!wDM~PcsPMwzki&rjM&1$O;l!S12}!N2cW;VOnh)MYVR%=z!(T zZV)mkh3}!CL9@JHm3bId+enah9FsAc8=@=tfg5@`g@9V!p?|>k=n8bh#WAnkXzqPz zgs$LuUK*q6jvuD^X4(gbCxxyM$8HiQ!8RIJdrIva6CyxZ`NIKzkIlsX;w3^_=sf+j zxWhu}8Hj?HCSDpO6mU)A0O><+&h2`9zIm`kgB`hPorNeKPwbP*TG0xGA*#coasyHm zlQ^3(VJQMHMHi3tlxq83lDiZ)zm(O~H$ZUFFHqH!`$|&V4cA=H3@SK1`IrB3! zgbt{Eq*Gj5&x83{23u!6oe}!6bRHgv{#^Kw6o_bFt2IVKH{->_y(7oFM?Ppy+@P@7 zU^kKDBw$Txfe(XiLcq;Mc$T+3?Ida!mRVZ)6j-$g7ny^*e3ktIxu&J};6>x_*aS^Z z3|v}A4=5I;pcBFHsk{Yx!{+*({>^1L)x)5Pu$T}+(7*tGffNOR74ZuoH8md`{L9@7 z1}B1H*D}vMHIv4JwC2!4vvS8QOmLz4$}A=IC(aJ+OWpGix)*W#cNS#CTr<4&Tc$ z3z5g#yp5lu72c`njkTh$&)fLUGoAj@IphHlz<1BTv+>C(gR_qUw~j*eZE3>HAc~PN zR5O{~Bgg|Ck*R_<-nmD2kOlG!mpi+ApR6IYYc8zzmglLlde{2u@g6YJ`0jSI6Tb69 z_xO?imG}Ec{>(CEjEBl3s7HG*8hImr`$ls&LE)yb=xS0=Mp5KXHw(UjpH+ky9imea z8F60!;mU8?<~c=E`P)TP@qF}bb8%OAQP57qe@rEy7Bm$Asdy!r<+&N27DT57(MK+b zK8`leAP+ngyChT4(m_eKTw^9hRdi5deH@#_fNK&*F^Lj)3|lryX0v^hqI8SBs(2Ad zP}dk$ru5`gR;RN1$g--|vAj4ypQjiV7m z-l;<(^G&~LU%X8&kUvCswHUdb%EeSJCM*|G8RovyzmGY0UbSVo*+(xwy@7JBHZUHs zI;vEJrCTH0r3{->P)afI4*41OQh_`ldRjywWGWR?shF@-U^df3%aoGHp=J)M^V75_ zn+5pn99`@7JFGVw0cwhsj}bPxE9mHDo|9zL#yjXi4_my=Y`CDCE|Y2KGo6~D;CV39 z3YuFNT6svI`r04&u)n~r(JT9gSpxd)FJ}ccAxCOd^}7?6$o#34C1MJi!)P!%^}|cJ z&9-t8<%N@lm_%=r3t>38sI)KMCKs&!lAyhSFF!RLQ^PS~!x6Xu)Cg;}CvWM!{;ew; z^Pl!ETyDiHU>8dqNYD10ZyjK3gOm?aZLD~WuR=&&C%tZ-e- ziGmnrDikV|(sT-WLg99VNxEP}r>}g~y>_{K@^bg|53RU!+lCcrO|Bv~pD2miB;6rBLd5 zFdJBQ+P>1{2A2fF426U4Hmn4nO2 zfVwP7V7zn3i~&@N%=0Vz^8K@~&CDL)f3P3X|IfxkW!yLOo4IlS?JN7|=Jvln?!O+y zjALzk>OM`#eX89ccYSIR7djm}9J3uX2s36(QANJ%RBEKc0|*gQ&?6qUxF}Vy|Ivb3 zq+q{{3enxG=D)nObn~iGvdyBan$sHezdYD1z1^RGhnmn$x}87OfhU}cXGF3s(o+h_Ez9YA3Ffc#coeDACK-!OS}lvPzZ;>zsq-}(}heweYx z0J_N{4xkDEHlhD4PFbW?LcX|7pFU>&Y4`w~1Kp4AZ7i>X$id)_c;FuK0tDQeR(*8v zry-myepK4c=qEOOm!ZIa`|bMe`Hhc%0Br~Q<2Szfm;lSsvcG=s|xnq#K{)xqT)uq+$%M|LzzC-6UJLji#UEXycSZYTf^ z#H2qaLr%Vr+9`3?_pY5aUe^HwiIZnaDxAR=5Q4y9-R9(>X6erZ)pw`&^%=8Whq#?_ zs3zKhPe3jJmg^r`?H~TSIeN9Z{UxK`Cem{LbF&A;APtBMwO=U2k#i+24*U4w?ydVY zKxMXQfT%e^I!PAE2#elWYPfpD^=U30?tTXhg@c%<0aQBs#rFsM_r7gTEH@`FFc=5; zP8ScFJuh?I{1osh zbZO`gnJpIrss-d4%I=_rfZN~uZmqX=VaLY#&*)b+x-HBzaAgQ^AaNlXIto%>PzYQ_ z00)T;@ts=4wSrio-VQJz_7jf9B6_JfT$0&~I2B-FGZhVn>7#?6ijTT-yt{achJ!J| zhN)%jqqlaed-Rgw141VS$-0teV7lqxrv%KzR($Vc_68iMX)wfjkTf_=Zks(RVk3G% zq0Ga^{Pcu&y?MAhzsAP!IE|g*q6KCkt4eY6KpulnB0OrFwY&uQF|MK`0PBRKfEh$K z2kZ=_GH7npY=drAfT1=}Zla5!L);ixEp7GLY~i4)0WGH|I|-8#yicie)MF_5+6BuJ zD3Ua;2?#+$uMCx(7bF$(PP&<4vVI6rFqu#Ev&zYUoFkh@`69E?$upOm2c|wk9(w3H zR9>EL7}!EK-Uk@dM`rs9WAJOFDvjCZO<1~4mtlv^ZHUvd3=)KDnj-~T4{A3BIqr5E z-zRVM$fm~U{RWVwhjed_MpThk6u|D(y6zsJo4~K5e5Ro{iq`C5q1fzn{V+}4SWV?X z!EgdHq;Pcg)cIf^7mcobGa!vv$ztmHb zSWKs1`lvavBvQuwI7yWH%a@yl1+%3?+@R8R6mu({SwNHM z?rKovfC5obBgarMKsgEg7JjS{fQRwO81?m~_1g^p9BPIs1?cwW6&q|dOhNS zQXoM#I~AZQI8L1@ijVY)mD$4aWmTs5$P7zvz~g!!F#tKHWZDh)R^@K#z+u*CmoTjI zC=wj6cG@Li+NC*rcBoy*$8A8fbk~H`35LH!kgHXC4*ayrSG52S^%;#FY8%~?SKzK8 z(8iEFzO>mn_)by*t5DHYL)Ah!7XUCqcNRlBICG7m_?ayXSE-Dga#Y7`Z3{44&I{q9 zMqsFua#SpumDA+B$YZvgQ+q}3s}&>Ym93>Hv*qF>bD{vAq3$-pxegJZ$vd}~f6w=W zj6vmSo&ah!V5j8DHw0D!A+tdEsR_gEP2fc5HEf1$%&2mQvhcpxLLCm;|xn? z;Ifmx966i~?(C5}%ze4^DUv2o4gD*CP65=*JpbXl7{xPthM&4+fgoFX1`jg80SIvr zazQ`2a;Q0b-)!9=c7WcNYQZbe;2Q&)i^4EFEfG@Gd3vZN2uEh)@ZpWKhv11A^N~e) zR3Lw#&4@AK%i=(B(V;HrQQhS)y331XG!2iUa?7Yt>E@v*l%0c0^U5)ic0ho|E4sb4 z_WoIh9?kX!+Rmb^ zDkb=18iRwxupAW6+Tj-zY|6xPh7WN3#LJM%)=0PutXpV6MJnxeh@Zl!`^YzHo`AwU zAg5IclD{p~2$E~^=k4+sl)kpv8~PYW4}e=Le-ZX=A^41t@clKzWe~F@$UVx-ki>{f z0(|om7Xim)vp1|627t|#7wz3$ZH`@H-qXqV!8E%A>GWpt2KgOkTXm3?LpO4!J@F*3 z!D?!s-iOq6zdzQ${$aPRE<75l;G2URM2`j(7AS{hqRwWc#ylkUDbGZ^F-VfRMG&LJ zpf{5>SV1Cn*t^S}Sb9kR@ORCP_vle(iB~6avm__Xku4`u02sj)Gext!QoWN>XY03D z0pw)%c>~u4_Ml2Zib_2UB)Gk7(zj6xoL@j<$+r(ikrwK$z01Op3zz%XKR4T#R|F*( zR+QW;3lq;>=-~VoGQDp2_FCmmoe66u~o>s@GoXryLbXW4VHYGa@U2hBiwIx3YiOFwe%i zEEC63?jA`HCBd8H3(cu-Sf2ONR~^Us8UMcytV751e-@_rKeHPZx^?bVwJP|aY2sIV z2jf^mEVudr{}oSPi<}2X=A)txjMK&^rWtGpc#}b`d<~Av&TDI=`dAdb{QbuH&ly1f z(aRgBKQVh1uZ~d5QjZKejFRFaLC!rwmhlHX+s7<$x2a1xFqbaNu}Xmi5y1CkQH((MBgONPc|MV$*a5&jUfi-GDw9y|Cpnl}Yw za|OCsCACBnM@=tgXX%D%lBR)TO-1ROx6YWY;=ACUA0XJzlFu%)%j2rT?whUUrEXOF zYP%5ai249+)m*8zo3krIB!UMf)co3g9<#irhLyZXIH>pgoxPzXQR=*@EBl zho6ZK_ZEDYKm2Ui#oqGo2Yu=-3s86Ra5MDVUy|Z{W#0gQRe@;rVnk}(3@ASiL*$3> zV_IVHFGtWIk%RXtw4rg;qfW^T_wZMFATnak)I2|l$tNjG;Z>5zg~g4}-|c<) z2_g;3XCQU_m%C>f$KBgk1vMz8R@P1qyFB~XSzlHAUfLwcab2LpO>wZM_;6&R$20%3 zwHvwZUY?^NN+~jK?Zu@YBIE{pSHEk&!vlk*KEVMIsh?&_jDxB!CgG{5MpA{S6@t41 z43RsiwXyv%?V=KU43k3Ri^$q;I-K~%Z}-hG&-B&(`}WU1`^28N=JvDS9?(1SQ)9Dd zcF%LKJ^MuHmRT06J$1#FB^S zAVi1#j}E6I$TF0_TZT%CszjS5wNz_soE#?rON&1gZ{nlJmReImm#Nv=XeS;>Au!sD zhI38z(e-isfjUMddIHbQqwr1cEE-m*IglP}R`f*S7;Qt2cF-aSi#YLJMR~G8iz6p` z-&_}8W$`2N3ky<4jPE#rx=_lXXy#;+jR6scz5ec}-E-fXRm7qk=)C9`mh)XGXpuWwt8Hn5kP8O3xk}-%@EGF|*vew_-EU8i0TkaCmf^#7#l>G*!Xr7PDzq z-f>2Q24?#WF&X4UrIMjzBe^{3Moyc}Hj$tRU03a~z}#)~<=fpKFrRRgjlVz&0X(pN z|1A4Wr+?!eIE-iw!^~xO@go{UBHn1THwcQPD6&}F`{QH85p#bO{%K`!P?k|;kS+l= z?Vxp|``M}W+b0PUq!o2=R4yYYFX|kau^PE_g0c!#6dgTJJc`DAOXIJn5 z$45W4=KEn9*>RJ=x?&C`NX;Lty_t7zJk6$<(eccii>Wn|h-*zgZ|s5l6;r619mW`^ zc58usL;9la)3a7Z{*_kI41$d@s$RY~QqV@<-}RHI&MR5t>mP@y0%$%wZuc+u?RkT) z+UqlK%a~&;ID06&-@jns zYV0v@%)GYif4(&{`zI5ip%4twaZ8V`4{XE0S7*L3zXC0WXBvFS7_D6;G_h=ob_);y z$O1-!IEuq=2*BXS5){Mkj%W_Oy-I%%AVD@r6Bw@bK;o>OYC(?=n6lKV7HA4Y@Mdr3 zF>DL~(md?VIxx0ObO(}vX}0dMuM7n>Mb*kv)9%`1dW2{Ah?Not?K4vAEaOK${B`f$ zADHm+;R5n6@$+Wk$Mt(3;A_Bmpe@g4^Z@*=l@mnTb~U$1lagWW$h+WA9;8=HZd>4i zYX(Uoc@;YE?giMnd2|9}=gdm;rTf=`8OQ8TXZN5_8#fM(+Pepx+PgbUf%9~Z;THpx z1X@uQYeCN#c2Lt%BASBXMSRs=Gi=a~%DlkTgmyy4jqA(g=4!%r}!p=^luSYkmXN;%3UhK?9-hW4KGY&WO)I=-wP(1-Olk z*hF5IgPuuQ3k$8^zJw|Mp;{T#$BsiTo5gRKq+a^U=6ZP`NsCKWQ?o4(om(D12%xRw z%+on{0R;vYb@H|k?()(u3`GU^)k_@hXb4c_Ys`ar{QR`utv@OnSYoAe&fw;H{BS zV@|-@yIbE5HV)MgAeS)!4t|oD?19^7_L{&C24(@yQ6q0|5*C<903y*ojQtxFc{oA*;_MeGe&O54fW_k zL7V|@N^pM-jt5|JD=Py7VdMz78RP9xWP`qZbLvFzimq8|G)DkTt*}7OSH7yohvdT; zVIoOMU=5ngKZnUPIA=Ela5lnR`T58?4j~{7mWVO@9Qz}M6264-DLA1MC79ipcL8|- z=Bn`$97dvw;BbO*y7WieV`wnS~PpDIE3L$RMSSW z2dfiuLqf@45k6t*ODDSL-zE!+OVC>}JwPPzov6_Ioxq!Ras*QHQK-o{6ZIKJP7S;W zMaPSGSv! zfh(4@Kv|TaFUVEo&9Oo%7$k7XssnBP2cNKzNo7Q7Ruf}?fh!u|LG|yy2S?TH zLL$EooW2p}+JRq)Ma7fm@6v^2KjBUmM9}O3n61MUzMvzVB~PY%@ixe!0X*8Qeu>LL zHn;PS9kQHe>qbZ#d5E5L-jfr!KC%;ZGcDpORF4Msm*IEPke7kljo|_06=<c1g7Fn;@1S?(=M!Bob5wfx)L3RIly|?;+AZ3}YA%xjgfc#w}#c6hLyb_6SAQj7d zWbyRHJ18uWLZ{+Yvv{fd(Y5A-uR-w%PX<%z78JACm)mp{E1QtkN&2C}L zhF3nQ6m$v%+56b5RTx2>9M!{Y(#9_1!+|Q6cP~j1Hz7-3(=A~DbV$1me0V7T{yYXe zp!_-5p23i;?11y#qV%DJ70KRB1H`*K z>vt}&?MsUy<&C%OT{&U4_s|0|1d2TJ-Vye%-#@l_QU7vxvAKJ3{q~W++&$8H`X7Ef z_fH+Vwd@Z#U@QK>wIn=HEPmVn+@ecG=xqwTOHs~ znCsTVDIN_>r_N(sYu6eR6Co) zhwxHNb3he{22=Kr_DpQQL2*kKv7?!o{!lu}d;ic4yir}4E{N)K~8p_6QQ4la8 zK{3+aZeQMVJ)}B(M6fyqnU*QKtrRbGtXPaeixrMqJ15{Fm=Y2ZG{)1FB^PuUB#8@# zw)w#|Gt&otR5*Y-Q9dOZ#&NBppP{n@Zn=EL1b8?m*pA%kt{kPx7TY^-zmcWg#o02feN7pW1k949$|@~0^=X4M4C6tfCu4~T*U{Tr^5=cZ}1wso6R@AkjH z!T$U3*Ytj7Pl9Tz>KHIs(yLHg91N!5qCqn7)S>>B_YoaZL=W2pw~c-RL`UGSp$yNu zAJ4zD@yRK(2fJmM0N6?EdB#ov1Yi}QR6K_Zh?(c0rDsK5qVO*s!h?NDVd28T4p2pJ@VxuNoU z_C9GCl>jqV>v_~4Oo}OKV$K?ad{yr0l^2HR#~l5^$NZB z`~a~U>I$eX0H@Aqdm#pt9Zv=2999=hH-;H!VC@YswbZ#K*9U(}nJamXvHV#`K9Zl6 zQm~P=CA`|9MPFMbD{m&kAu@Y00Ogc(C8cuwo#yN8_U_1*~l?`)nkAe_c;dQWimgTDkeyWQ`kdjr8 zG~(zN;3Gw4SUy@aKUKRM6IT_`fG$w^66hAn!klj)w5cLVxymNht zHLl{nmu}#iFpkUXOLUgaojjuArKs#CA44H!i~2 zDny^8Ms2xhdqo*r36(?`&C^F_2a8T+^aaJr=b_g#ZY+YM7M4J8m5J@_1ERxSjD7J7~q zTR{Z}Z4VWRlT8m5x;v@_aFVi6h^7>t?zVAU;RhxRaYbH>Vl3f;oVh$`={+cX5sMDr zH~;|)yl&lBL&GA-L1>NHuY9tqO^JBHzrUBcf1 z=Mus<P+QuNml#ChHCJ5P^VhA&l_EGwd(a5E{ z$9@)rc}^s}EW#z$H?f7ow6mkbT0p*-C&X_P#Tpc_aIxM8sS*s)s`2hHbdsObJA0cA zKk;)*PDj}8iSRLsx^Vz3#8 z+RsQK<@XVp0U~|nO$KDcC|8CdI@G$Ui?;jG9l-RM-TxrUkcI@6kmiGf_|}UM8_Bz% z(P6L{ZG8T**|z~dHymj-*C7hhoZNTt!PiiVreBi-X10IU7UKsPFp{(bE+y1(R}_TU z%pYkYvlX2fQ*^O99MYV<*u8dX;GPTi;O?hyqrAe%oxb}JHF$21%$t~zl8-}w0_A(UGi+BXpq32TIWmt`%q{ z%|1H3QHDRGTpi3BGMT=+D(fek%zO+119y`uWLvGQAqpMO!}!c^;$+ zaZl~MIZS_~hy<0}HHPyQAT;*i7V6Fy)0bi8DZm#y$8x^nA_u61YKnzUJ#$gM6SylQ zSBmC-S$POFI!7M#uNzjj9e@YLBW<%oQQOp1yx>G~vH7PK*Aqor^yikY?)aPl=vrXK zeUE?Jm|=+ROGqG1z3@AUWG8>clO(KG@h5xtoi*1$#e7{gDB+)`)Zp@nAU z4$UFctzDyl(X{O{_6s1Vs3!|7D4_N5aa{tX z=URC!0|qgsZr-N<)CV$S zoT+1X)CEP~We3qs5+LaM>PZ4NlbS>c)yz=TfG|;^M_axMBl?0+EyzWJSs0Q*nmr(P zin0J-u2$tnsI|bckRNWJ4DGwoM3K#i6fqWx+Z876P zSH}j4CiIJ{0;970zGPWseI|%*EjlE8$MF)BWtDZgnxQWH?&^$Jy zWPXWSxyHBj^E}I4)ho33Exiz+O}GZ~-X9@@2U0df?E(jLmMP4+os_{F7;od;T^wTw z#R2A|q;|(~A7LBP7)Y*~BSh5+DA$QnG8xN#bjqp*hqMx%iAhX0@AX;l<{Alu*=I)= zQc*f8Ru0-CsI9mE;A4tiXVHhifU_8=c=kB&j9z3rGp042K^tvOnR8cqu19? zV3+|JRgg`yi6@#^2Wcw#l!sSg^UOYW5SCeh-Vfc!cCfJ=H5pm1$MOVFs0aLgsi?00 z_djCl9mxo|cDrAGeizMJlJmQZifEJ|!Cx`?Mkq}ujHgZBEI~+Fd5}3c7XdLYud1Gl zhzLK7-!?jOT&d1(xe9BtK_v80uS9R4Mt#FJqAVsTo@Rxy;ZESj{2B(^%{K1>R;9|+ zK0o>xwC(QNa{q_#5c7O+0^PKu->b8J`}E+?)YCVU6d;)ez9YuZ#XBg6)cJ>f7!545 zm#VBRpDeSNpXxmAJ=OV_>LvEGCx7}=!#D{!$S}**JBUVl(I11HtCTxNk^`-x^b;yu zBfWt`FncASW7bIhtHx#V6E;}9aM{KTI!Ne&$61S2>C|Yns$8W}XpEkb8qgtCsH`Ff zPzJUH(I?^&)n3@PUBCxNU0#W|X$j+=2>?klQ~_lP+qR1UNZvlc6eWL4&IB8r1*_kN zDt^IE5+%AtCQATyH39>&ybD+dR^~JApYT!##XMyRvTMdmplAo;bai@xUPRVk2CoyQ zrQ>3FNPZodTm}?~{>2Y(7%agw1lUis8ZZU}I)IFnh{iq!h;mFFMruKc#Q-C10jB-Q zKC~$uEG4FugE**VyF{`F7W*LaRD~kJ%hQ5J4cI_XM8k=iG8-ePK;9NZg}_eGSS0{_ z;uxa?mT?DA9lzaFgqU4$^1BV6kCE-7(5_>1VU0dTIV1c z`eSeHJ(h62y*Bc5v*!U-EJ&PK3Ev1xWXpG8K5wU*HauaOSh2W=t9#eNhM3S5F?LC9jh2W;=N40sUWTLJXUd7 znwy_>=dZx*qT2|)IOxP;gT0GC7^p~~Uja=-Mc-(y-(g)rfP+7=V%E;%0{JZ;#q{JL zPXu3Nun~-cCQ&wmOuKLutrVnX43>bd$FzhRh_kmizYHG??IV#EC% zg;-_z3V4i+*YeSG!p=yi_dVAOfqJC)q|{D8H4U?{*$>e7h;9o-H%Yn^tMK7VQhGdl zZziYswx|K9MLW7@@;$-w)Ce}zMl5JOf4RGQ%6ya(;^CH&ujp60$s>;%QE;1&Vngi+ zl}Y)YI^MlznjnkQ60Nw(H_(1-yeIO!2<3o)*F9>8ix0{<2dzEYkRi+>w?^Ng{N3z} zJ`8iHM#)}YMcC-07yI|_;iAG-?VY`aPGHz4a#;B(*;v-7D(YgyTURVL%qd3PB~!pq zp`;sUeihJTgI4rF2^yjGd*1+RY}CGirC_TO!joCf6u4y2W|uxi;v7TAW;Y(pmSCHU zl*`aP4FIZx)S}p2zuO!(>?#QpbpEr?t8w@+Jydx3fAU8gBU;SL%&S$95H9JwDMhq? zQ*jQL*EDEE85BeHDlG739SSWs(5JMV1(+x1ibF6)DY<;AMv1!$)KTI3F`#Md^?|$) zrvM3*4|Et!n!dS{WegKpE39x=YBvO}l;i-86-!1aB9?xnXgYdzW>pC8N>bit_ZGJn zbQY@ml)a`+b=(m`Y32K(UjSEGes%WMc%fY@fe2%V;%D{(fKN zw}>NMX8;V!CdZCmetHANvoGci?7zb*BeA|{;$c1&24lPEk!5U;e1(r{9IkRB5w(mG zhhA2DV5X67UZ2lrLrP3uCigvXL@5`J6t!|J0K22nV}RWmtQuD+TPCSucJ!-K6NTBT zo(D+Q2rjNhXJQ}~P%&y}j7^XXXDda*MNtt#t1n$gmoe-Yg*6-RT-`Wx6?&e2OCQnj z8kYrF2vux&5wV~{7+kY!7a$lEcrsua27_>%o<}H7gsyA$Fh5FiurX_s@)#0@>!unq z+K5f7Giqf%ETVE`6c|#zgc@S->)y5dW|t8NU>IIi8-wZEk#N$LG`N2bhU*JoooS$( zX1NfWm_Y5M4xG#H)to;}9sqqN8-_1r&ryL<(Hg~#I69J_RZ!?}fa@d2;*S83+LJ8=HK2plT$%YCu3w>au2zQV6b(LbRHf*Q06Mdz z_GJIkU1JPs&zwT3Q3{x4VJ`5^(PnVMw{ zTLJ6;ly1H-Yxmwq&WP$s)Vwqd5Dc~*C#3^8VkKl{!y>#O56TZ?=>|oN12%T$6EXwL zaI#JquY#`m2s2X3rN$~$g=zSk8n5N&7>Udr#mmK7l;+z(&Ms>?`0SYRk^yF|fMB65 zLik95y1~dDwkE~%Q0A=wg&}|Eky;_2t+imX3(*o3jSRnThJV(9S%|)G0NJYAk1%9; zA%Ye(su-f0S=0bEkY9Ef*U94oaijL}8!; z0J}x+>M_yaa(e-pStP3Ihj?=cy@Be%&|Oewm`c%oHsshMN9=8u>Abm}tra~56?E&) zcJnOaZh3bmoD$2j9*tN zNCvfqR17);D^7Lh?XfN+j0yq*Kv6XEMIoLfv*QSps7w+SR|95+KGqJhcQ!FajJ}={ zt@-lTVoBpG$7qLUyFy!pQxxiqJr)0LR`I;daX~Gm?1kf9(kg^^xx)tM60v{ntJLW` zsre7yMf2XrtPz^OE!AJ}TeW9_VW8uW%uWH#EOl7u31A%5q+CyB%%ZrRbhw$!B2UB^ zF%?%%zDdTjy4Yq33>?jsBn3Kbr8Ru>n1M5@{Ll=N^4wLqDFn^B)H6U^CcFju3)FmR z_ArN~_Oe(xg#Ixgv>?-ajiO(gEoL^0v@_th!7G7Zo5H|?GYc~%dKT0uL<^*=b{h<* zR?NO5K%vl>rNZ&c-_fRA7bfV5tJRJ+Ik07AucNH90JI7Qb}>e0CXj2Do55rSo#h&x%w(++5Z%Z)$~pmdq&f9vvj7Z)+sy01?ogmR^Mg1+ zPFiBqImIeO;Kx*+L2C`0>BS@O-E2MpIot)nI?@Ad#?RpKWDMXz=W!q<02)Y@K-#{5 z!xU(O0-k(WZf;sV!C*DZ)?zp%>fZ0qdpn}Oe-a1ueQ5Zt_7BNl$ zdBHK9`T(iWG}6~ufznaAj@ns2mQx?2qL+^FVLXDT1is?j2Roho>dc}0@kexLQ!bNL z60GsgU7*nb@KX_IGK-{LN#!=zK5pJN1lbN)XTAq_LF0QzU^=Q&L7r(77l6J?R(oQW z^T-`QvvpCe{^$lTQX6MfxRV{BK&ROwbR@cSRq&}{e6V#B25JsX-thSG?KDqgxY(HU zEadNMQ>cIwo4X@jA)=(K5Qd)G z07)Nwef4O>t)A%B9D8ns0t zgd3(gS*82@vQR_|SMeQeu6bO?ahR(IMsh?-34JUZpDc)Il;0h*EAOGP!zn;&rcq6C z4Zv3PWb#X7sVbV%%GPiMY(8Cb;p{wY4`PBdiN235D48_#kInf+RZ)f%j z?EEuF6*(*fwn)bLc>6Y;quE;MfOmk6s@xhnb++7~&c&kWiwDKt2lRWmvS!bSFr$qL zF(sgpFFq56h07Si=$|;!yZXRz(UeWijHD_#S`op6K*<9okR8a~CC0R~a9O@aX3y}0 z1my)4<$(@I-aamDcj*+^L(LYAb4+&uJz6JQC=FErVNe=tEPWs^4bVq}?1W_S#ra|VDPEf^k<{BRrp0({|N>8ZmrVjP#(lxdTQFHpu1Rnb!?5g&c!Hb(`G~ph___q=py#-@_!}P+%Jxe32t}SaRDU!2#SaHw5ITdQzNC6Com{z0q1w_Nd427&GAm)2(hk?-rs#e2y z4Rhd705?=~)nZ`N1S16w8-EWiBSC>ddig7Dy=sK&jg-{jYJp9D!JOR<=mZHH|Cb*! za(iWsM_K05G4t#RO=@60U-8;Rn&j_kQeygd|iG7jlw=gHf5*42Sh6sh#gTv2i z_Fd4U3Y1|rjWAqdjEo@Q(5q4;+}y zcq1)mk|v}K4(s)hGA>5`2pnb~9MGzc#r)PluS&%$KEybL7P3p}xK0(gk&5$!axk#r zn4Y?F5L>5@Dz9(!0;uGn5~6a=3=>7RNu4kYSsGnmVPLF-PNCTCvD_-RK*}Rjfh}Nu zhDQz!&D8eYPto9ScELfZh^)8T^Ub1QD*N&S=9+)gpqZ^3R%lnqN4N?HH-lNN+l=~f zXkE+}bz?@F8>%;Mi=Tt+KckXAdeKIkhYsM3zz?VsbSU}4i$ybsO_~X0g#>WNdSKA# z!aFEU+%OMbMuC!!M(cPXV3q-2te71^q5bK2PeW5GLMUxg*+~LKUus)T4-h;^=AE0z zFoan<25OEu(!Gk;Bm*Rg1jhMgh9AMR?#K_omNL;^I)Pu9U5_9G8e&>09x6!$a_pGq zkxvI$ci>7eTbFT#L`9}eO@S>d0Sc&Mq-|Uk-!D+vE0v=eIwr>tcW>RtRBZp|vN$5l zAl+RuESGtJLPR5vvNfC~hwV2RMDtQm54$6+z#LA(;0i~OQ$WKj*~IS2_rVrm@Q=a8 znU*M;$#-12FErw7;kSD}hCwSea-uti8@yXyyYt)&ohP4p=9!+Q0^cvCt>L zbbt?u$V;P7&;=d1p>Psy%m+Als9TfG)1G{vQONUH#=wGrKfWl?{;Jy##ykKRHe#Iz zfmxdc`C?&X;l#*3OpFLd#gm$0Y-kP!oX`oIVU|BncYbXhC|``^;{+tiX$H4XUI_R|n84Tp-ZlCaBRd68!k{aFu#Z`f<>?j3AC)l8UI}zzDDb9grv!f* zZVmeLnv=(xLq9erZqabbz;?ZDaG`t$J~F7CW^t~DP(9(MVX_PMk3THkTQ@=7hEr@%Ll!Kyax2`!HHW?Ux zcEgYy-TF64S(-iD1F#L?7L;TM@vgP43;GLcl7QZaPk|gNmlafR*fipU!{p}EZRwx< z5lj|lJ3*&*4mK?%zLAmF=&gv#W#kCV9uPy&^K``c3eCwXdBX!1P54~i$<~=Y06mo$ z5XlvT28Wq7Dsz>w`2g-kQ&H7y=`bq5Gp62p!sHrR8Ww_nPK6?R1`D;$8}{(}C>$05 zUXpJ;V?8=`Ts-OKVORkO8uWztIS^3!4_VcP|4r0e$mt(^r_a&;Z1$o^g296sncCuu z60oGew_W%au_HFoyLFwZT7JA3E{4~L-(r9C6SGGmii-16h1n1yz;Q7Lg-d{K@*yS~ zL_GKPa0F4%bMQYkd}ILJRXGZS$$&A1FC+LZe22`1*`mnEVu)D1@k8r}b+@WZJPA$EW~;kEPz0Khwv__#0#3-1 zsgiOQhr*3E&d$V`1fUkdkfprJR=sDi5c;W$q*f6Gw!XZfMrNMe3$Q4G}5rmMgUIKwLfbemttd>OP0jWI|nQY_zFE$Rp$HedceS=*g zi;6iEwOgK+Km&r=5;5j1K>DOu=k9mk8$2ACzExd}l%_d$ErE`byc;a!Vvqy?rVo)~ zgM|Qk7~G+&5UrLEgU30>wQZQLzTA zpq8GMm5SN5)uI?Igno9Q{*R=Cx7Y@gg&YUPaup??-m5wC)%v|pNZJe*0`>zy4^;1o zJ{+l5gC*Q5%K#Uv@09|2JWx?phk`s7$pbZ0b#YR7As)89swdI>#zq<)TqrIp@)kjg*UJ@P?w;)dCAB5#$%Rji#4NBeIMlr|+BPvOeO$3Jvez9;Q&b{4*0 zd7zC|B)0eMw`l33wXg~@fxYE<%FE+YjAph5g^z=>D~-Q5;t8{#NVyz#yS7+cv!emm zW{xRKC5mQSUOhhC^48pj+0q`Mq=EadoGd?$Bg3Uh1Ct-i-ifRirzB^;-Qo(GJvd}} zH^52CN&ydU&Ysv-~bs=iBI{7o!(rX=Ub7G-W$1zyF9;M%VN|sJA1vD1w};KG4|}OhiKL z3|($tshWx)1lcs zF93dkjE^h>Hxc~r(8mW&KOu@CAhBvln9sr|TS2NV?ndS~^M2(AnGMj1uO>A31&NwQ*;F{wz9%D}(Y zPmE-6tSS{KeJqa;<5X#tsGw1zjg8xBoOScwQCu3Sjg3Lf(Cw%6Gyc@`u$*dB;b?6w%38GXSa@TiO$?sl z(t8`rtBlf-Ul9YX=WHEW zXpIdUsIAp#3BZ%|K(v7wemL*~ATm&;nGep09&6J47Y4hAQQ{%!y*sbIe76>Lr{iP()h`=ns|%a@yl z1%pK+7sGNG;gJtjF3=Dx9XXzMNT)#bs0&Q_>FzsV%R?X3=kim58G-Nr;>R$it{%gkLR!dRiP%B2Qi{Zz#+7t{HwE%}MX#_K*-KYI z)3Sd11LM&||4JP+eJ$&q;3c02=@SHM~%O6Ert&_SU{O zb5j@&OF25T-I7tm0~i|BIm0qm0REF4;Jw>ldrZSO99NvdORim$b8l9a)hH_BI8Z*V z_R5joLCYb+Q}Q42Yxt-{)D34F;Vc3+v(pO!IPHS@L4HO4Wd_Kpu!*8H!2xgAZ(nA> zy&U!y$#b&!urJ0)ut?-aDJD;~;#&b9$`MFb7G5Ql4;hi^NB7`ik_j=8%s6pCxD3mo zQ6&Lrt+GmGi6?AA`pmu4H@l1P5#|Rqo*;HuUp-5Qh0j3=a9j?A<_MlQ&VNq(>Yluc zhE@E9je`%Gg#i)s={q7iy?(cU_!gnP^J%$x{MPJKVl=JExGaH_td0^fj6?ROpolmu-UV$Xi#I4;g|rI1n9lCrCuGRL%T-dii zH_sp>I4wC(jJ;2ckkp4 zU`kSzkW~yHoCh*IVYe9EjG#mVCz!5eeF7E{dU19+7~}Z;&hBD%X3yMAxo2(<&BAvG z1KaG~!aDF!)l(9_2$xE{kb77J47AThPKJe=7 z-Z$r-Iq<*t@tcZQVYi4kgUioi_mwe~0Ke)`bJh?k1(~22RdmGw(69uXzCL}2K8*Yr zTqHJgF}Pjw9|18REesp;Z=0Pckfs1Jt54}VNW}tIQb}6EQRjKIPla?ZeF5P#xE>(i zL`qvFA!WS)%WRGa%^$<8Hs-2ue6U3LZ@C|Wo$1Q`=F;Jf!-qG{9x{8o$algNy;t(* zq^A<{6RBIcGQ;dL9>adk!Pp1C9;Aj*58?hl{ha((vwZ+@p#TApa;<0|m`wm+h_nw5 zAa`mJKWA_J;B2${CHut>3$X0S%Hi1A<2g-c@8n^#$Acv^&oBcj9|P`g_sm5gm9S5+ z@+p@Y_91Y!V16ic0*Wf==?3UW$0@Ob)B%(grn!gAIc(17^LH`PPoL6kPhpvR7!}Z( zU=K*dRis`#hIhyz_-PjgS1wKy48yCn1ZJyF-|1`)0b}o^=;$rY_8u28;t&-epPeUH z^} zSsbn;keuv(_=VxKYk*z>Gg@oIDj+Ubz&Mv`IxN&9DoMCg^A`;+2awXCbw`+v9-QwU zKSAa0iKvr80Rih4um90tWb0OjWY2fI{c41+x@zslg$~B$@;7 zv0v~BdTLvOTSdDeD~iC2{r#2C@I$k6L`4pDbu}}@jMk+qq`s*e3mTPK&A0C~hu3gb z;8f$f(uS}Dcq~A?>fgI(_DFbK;ObDPa9BZr0;Q7|$QNen=G+a`zJ?bVC`v+pI8q|1 zAwpRNP>2oSR-6H&7=D88^0-lgtecvK0O$vKSuCtsI)}M5gZmRyiHp{G#Wu>W9{G7t z0S2D0>H(T42S)W>Lqo_iKu;uZNT6qO-_h{1q0=_ck+74bYGC0urFUdfG zcQ4+CD3U3n?#TJOT+@7yh*9ulnhq~`C_Mw1R7ro0ek(ye!kH$9q$2|!hJy^p4BGt2 zmHskVZN?xY0oY#^Bl1u#(7E~E+9EC5{p?-TW12exREP9I|M)x2S;Htd004e~#Eed? zqX0aX0F>hox6dEYko)|3L|q2g3E&Ve$|2eS3vf*MlTdLug@enT1LHyi((q0Ysfkxs z)#7P*vEu3bWF25fL^N>ZD_k677Xv`oW$6JZSCaYW#uBYA+=?GB0A!skJj?zqUuBB< z{xO8NOjy2Sp$Iuqq30jr0Gf=`?mMZF%fo4VXN7x z1t^vyU!`0)k%U?Lx_|3J|JE17PIpo&IHN&pzmX2h!H5KccKIBLq?6n_Oy4sdhHC+9 zzJC8fv+{X&@kdf_hOfZN6maTvU%_<}5QeH#p>mLQ<@J;swYSQvL*~gRe+2 zGBq_b-=4UXd9qeyXYJX#JS1Tqz26N)2%v?i)8fp=P$t^^LoiY-Ojye=HdJgX#0uq} z@TL^hpjir<$L#n(MSuXa_LZkVAg+rpcobJ008EKCrs%*!irSC z1GETtEJRxn@IfhZL7hNU%`y3qe!$E1?tUQR1msB|alE_4rU()Pa^FD5Oh(IAVqHB!ni47U*6wA zz1Z}r4cr(f!;7PzN~d-M^aFx*OR-sl6gF~YjM>WaX`oH0&{&|2=%cy>m#nXJX_5dL z78&8*hrlJ1zam9LbQrW@vrmL}*$O=*isHbBMsU2o3a<7Qkt@Va!<6aT8cO|*0HaECMsvk343_}zwD!z7_`{SBqm5TjvQ2gWOa z2T`akyR=Qpkg;OWL0-h=?Qmqo&8~fj77x!+gFck@n2wdc3XyFK1Hds|Y{UUA7ib|@ zy9`;uXz*d_9C2QB=#;M+o}<~9bn6<;cPgU~D>JCiU=auRZ2(3Lqm7S=vNsJO&@vqjNboCTg24l5BqwMI_03VPKc|_>g zXQNJTUPpkVXCqA!_{UKfSMCDYWhxbeI3%7(!w|*}s>S^)N-h)Nu^5bn57s^LInO|wM2K;SJ}xxCY6Ty&jR`P> zFtCI% zgj#t~3h_jAFDW*WX}1tvz{AElo4nVYf}43knhE4~8*9Wm_6SGAv;p4@oe0>zTKf2Mh~Ty7oChN+=7oYsoT5cBtc;$zL40X;rG-i`)jUNE3T)HXhA(|WGMF|*R zGUeg+iWmdAF2+BVSj2e-lbNP7nP^YSfMuv1z6mimh)F2L&k{1}naO16vL0Y$ucQk- za*r7YBkMBxlsII}zFZXM=+;wnu_9W4+rz_ecI(bxV2KkRj!^HM+3I{U4iyY#*SC*S zihx!}_L^2iF$H%7wN?0Ah=6P!1Ggsxc!b^t0;9(bRCQ>d+H)LCt`;h2D83K42yI(&rCkNf0ql>gCZ{6Vb9+j5$yBCLnrzvo8+Zn+%K$N^WcT1tDDcH9!Rz#uK$o1Bw#Aiwii7M}`LU!s)QftiTMC&iV090Kv`>-BF6WFNAThh7|;P4vc;NqCr z%#a~0X6O>sm^9F%q9;S`${5RWkHMh`LPJHLY;_yZvWj%-#{31?e6!O4Clr`()QQ~T zt)q`mAC0n*RI9`Xpz0mnZ+rC;!^g;h_NY5D-$`O`fB|je<@3ZkrybxvmVx&jpv+yj zAl6|}0^@P2p&0e@O`ikD2C*Hu1~fOs2?7>SDLx#|*OF=nfU7`q z=SgJxKcb(Q4FQn6&?tb7Oaeh7s>4J{O9;hB)Z{#xAU1S*(x9)&M391_%5hX$>+b;k z6QfhEVlT)bSrqm{@aCX3OmWJIabxSbn8{BNltrF{??&@!8KQnvk1#x2_yAF!VED{c zu7><+nRE5dy^Zr1JB&?7q~cC|h)G7PZ;BFrjZ37QEX^zu$c8jFLiYxmzB#_oWshN( zsag6F2BH7p6f#ew@`t}A-H+djZS%j`-2b|F@;Vs=9KP8(qn+IkeQ0gXIRksTNxo0c|%H0uqUm-T=K1Z31b90-$f(PF-t<^jebk;zJZp!8Q z?UVeAl7VG@9S7*N3Cw{b3vL$G$g$`X1QPt4F$>NuGDcSLYkCsh8u^Bqy_laPXv1`> ze1mw|Z&MkI%gKXL`2jZX1O!+w57erbh)v-&a?L|8M>>byQeJ%Nf6oY9hFZ^dkfg2v zwhuxM&Ba5K7V1~cZ`uc}pr?q@8>ToUkPCUwbmc^Tjd#!3^v!_n3IL6u-P61R*oxdF zP>IXOa!}w#)R@9nl+~b{iK!_{{V=ek4{ymg!0d`4ndCXKI&RI<91y^~ zvy&hCm%FInufh}j%iSXe&-4=%?=eNLKL@{nC#xhaY@8G)%DmW3l;Sv@48}!79*Oru z+vo!aT|jvNd}Garb7P=xMwQZmWuJWXknBm5P}%k{`6%FKcuxqui%sScAUNG0#pdJJE zQLYW~0st7nHYz^lFqD)ZXQ{D057?6_njJL?5aS@=byUldHX0kap9Na}mAXs!M>K3+ zwATyZz5qsapj=3JqUib}oR$rK)`a9qopxq7Ab+3Jaio zIc5MbNPPXYym@gb7PF-x2u;Aht|$^_0Jz1b6JZsc!F)9Z8e8?Y*-4?n7q!z!c^FIr z6^iI#G_Wc^z-(y`v&0!_jb&>CDH=%fKp|7bh$~?_E3?&cN?u+g?WMWm0fZb0c;#Bz zt75c20ZC3}gtAh_4nQ8V2>zI6i(s3oJQrF)GR0%5Vz){vFF@Z z6u^DNb1W?4jn3`348Xspc^Aj80B9kA-feU$v(qvN9Iw(s)gh?q-@0bzoQ4kk z3Wg@D*_e-(LAb=quCek}sbI@zolrQS zLjqU|F$)r%gW1Q#nN^G$Nw;%UNZ~$@V*lADOVF6(xRL5<4E^J+CvW2)#~Ir5(m?S& zSb~=mWm9{_*2+Azr44Y513#{Y^vcK20yjP+sy%puSus0)AS6I9s`M*E#YhbRLfcx* zwYdm*Qd}8%%S^r=q2iCYtbm=9SHws^)%uk}ziAHvXXFA>fbQO5!V1&m>OkTcIve}} zPO1(|Tb201i~-c2ayxlcbm@BV}QBpL`#E z6V(W!38xZA^-2V8H1EsXtzZlK$1c-EAjNZwpHTgjvWaF7brZC8Cz-Zg17CpkxX{h9 zF$lO`ve)}GnJ|MCMG(7a!AAyAV+Al&@8*7jw2PvEFkvKn*!YZCk=2yBT`>DI?2_6=7%%PmFBxF>&^%Dg)EW16w~x3Wu`C#^aq;B>Ud2kcLNn*!%WbLcmT@xD%sZBD1z#IrXdK0{9%3)pq$UC^gBBijA?icnkr>)& z5=; zSqOGV^vi2>e^k~$gHWe)fy-q~c?8Ucs4UelKtx0uDz3##-H)z`#u^UszQJ#%*|CHL z$jFnCqBIe{U_Mh?4i}Kt?XG>sYQCQW_|>V`v7%45;R?Ks*ta)^&(Gsn^?LS^A}~6=JMr&DHQ<@ zDGI6rTXg6LRfepqn$3jyWSD?dK-S%b8{#AJr{N=^7i{Cx(`FwDypkaFR#WaUsw@<| zbA*r`ZCV?F0g+&aL6KpEP^7@fGp9wZE>fCi4p8}Z7by? zBWBx`IE~!e{>tZOplfJ9a1zky${Xn&`D!?ZW?(M-EJxtvDL0CiAedN#B^;1pAUUg? z|JEyGvQXlC_>yYgN4nGoOSm~kc2l>IPek0*4{re6#$X9F0Ki_UiE_F>tij^L2PR8o zC8M)Yavh?xnFHS#EP*ME0vv#z_WmJ9o&vX6c}eTxT!v*?g6~dV#d#()Z>tZ26yw8s zelHh^{5o-z6By4gbOR?F8AN97z_J|`e%sn*1`j)cJuy>7p!%v~1U~X1FtFRxD7G}tp1II)6G}oyd#s?*T02?0=uTepTDY}^cJ#Zgj7hzP)ZUP3x zFgLBQK1NZB0DOd3(YjYL0x@)2gVa+B=j@>XFad@*9h5A(PlsWgI#;QQsc#NP!cZxB zBGlA8LAV2TSe|lYg?qHHqF%RMzSqvA03>EOdBc3X?23TZUF#v#^ zn~FX{9xZXaBhbVY!F9AZ#?Ylc%MVyULfO z0iQnuIdlE~Su*X0VuI#gBwrK{n2{XaM6>*#ZRYbs&{TuyK=nPj(iC|SUgR{}6b7Nt zyzFV~C2)+;<&!9HZy$t$$TGoTwPH0{w)WBqB(pZ(AM6#@Pz&JpOJM(%6J>1-G*kn>o_Qul!Z#& zCYutv@+J#~DMrcFZa=PQPkadUZVY)Ctbuj|K%?kcDSV8T!y+pe(B2I}&jNrM)X__; zFcf892L)cOtqK`=?nod$mivJ@YG=qD98hU_A ztu|l;204&SDn)n(e#oa|JM zew(FX#erVqDG7Plak1-5H~Y6P3%+&^IxGlb_|%@+-q8h|WQB^I%<{{e*M(L0KR5yC zMOHYY8#9PU%vMKJ35Z=1ZGkKXH%C^fP^0!5*7Hh)-zqtVRRP!!Fb?eids`!pUY@xz z`bK2?J(h-bOE0bibs_4462}T!pW`2yooN)aJ!OiRurQJE!X=U(n>Gg4NeP{#_3AxL zj3UWFD$qtBLwL82IbmE-n2zIzp{Gf^87OHd4Fk-cX^US`2qYHF%F5q~!DM{9OvQC6 zmc91;M-t8Ye4G1gR7e0Hl^3D(> zg0=us?OQkw!*ntdo%l05qVkqP}MB?cimm9e?G^*MsT-Q~>h_r5yw^F43u`7P(2+Ce{f?v3B< zpM8DL+}{0f?8Z0T{i{D6n45Y1=X>_PF*ozZo;O~d+41lDXaDQK9RC}e|C;?>dJEhJ zmc(BJVd58v!6qN*50 z=-83hl2-vr6}HCBIAgAZNE44S{T+y)*<&IQ>{N&V+8zUgI6QKoO|yy7qi2WDrk9gt zmc9m6P|bD_#x=?ZnBwE1(cm_$kA7pkp6jKKpQ*)9vA>&ZU>`S-G!P0^Y~WM=u#~2kZ>qsU$ZizqcU9g^ z?1dL%>4q>c`+Fx0mP4J}0jaAm?@JziwpLZD!Cs-}VR;?);u`K7OcU?Pr%QwIp$Ad;Q`Uo;0krPx3~sdM$cmj7z)dHqPl;7p*i}MIJ9F&*6*DppVVwC;KBlY ztE+7kcMCr)bG7Ljbd(#Pdr-9rUh#*L-;yA75~8eS95f zE^mmKzHo21nhnSe{cz|Wj4CF$KsaPNaA8e{a6%tcYY^(`-(0)H`3gB5+^d)j+O#|f|0+s*`#fs__K_iW=aPC=r z7~6#d51mOE6qU~a(IAM?2a8?$%3yy%j_OX{GGYiVlQ}NwUAvIX8-!%Mv__Z6U^hU7 zDXRi*ne{CzTGMm-=p2nui#Qh` zItC+S4$T>jc*88sa`aEiM?5A9^NuaWKFRgBGd1WTKRm*9D{)LZw%Qy26RdBsZ4x5V{ zf)Caqz~QBocB z$h$hLimHS2Bb7g7De2$4L%<6{`d}BrrUjTAG#Nws!R5mv5n*OlTNQOv3?{LTt$Et2 z2FFa~Tfu!LpL{+CBtt-ceCAs@c?EzG4>b?c^Za?{6O(ALxI8?6ggto}tK8gCZMr7- z+z@Qjq-0#BATNl5BQZsQ5b{dFeUXVcE|(R@G8xyWZgdyVv*Q8>MIH*`V6QeI%MMat z!fVP$y$aT^@VvqNXn5r7P9XS6AcE-hqhm=Z#7Vk?vx~gi(t`TzqwNiFwjvb{Kp=vI z*mVnxJqO*optjV-yEd$)=~!rW(%}>+ZXsYTS^E0lZ^B>h9XlpZ;Dz%jju)F2wm%ku z!v)-iBuq1~!FE?<(01~VFUOOA_@DpsFV!9g`2L`6Z0*!S90Oqjo(mzR-#pIaVng)L zp65?E^wyn!#M?z>&0~^n##N{`2|vg(gmN^QqAD{w%IQh-17-WNzj1T2fAci{=?SuV zo*Hi%MqFm`P=85#yXp=w5upXcZg_ zoIVxKCp$oO$5^b8WsAE*aDC}ui7f>cge&9v4)xSjxIUUuEZfs-@pR}|-U#`H?TQx$ z#HNHL(|G$PahtC%t*9DNx-+{I>haVWj9$s;eaQs+84%OE~e# zPPP`Qxm7@u#`>rw>lN_u_v{ zO~3SFH`y7qnX(Q2WQ_A zW6Zogy8Jtb-g4UG$HT~_rnYp={H=F)? z_R#BZG#>iUTkjk?aPXg+j?F*+*JeLQ#ReXay8Qd5U!Hn@=3Tm*?FaeVp}G87#RsRS z|1ib-K|Cw{x#y2nJ`McUM1^gBx%}_>ikJL;w5BB&;F;%>;kWrV{oU-L1GJl7$G`E+ zG)AY(c!-t=q0v9?04{9j$Dn?d`%3$^?QsN@2ONzvH#_m3>Ad*%)a=yn4?qqAP!jkt zD}Et9>0hJ(scYSC^?Cxn>svkFKG^KPy}c~=%zm+R_VeC;=MB=NLi_HYJ~%a7pdDX3 zG!5OHbW%wGLpxRe8md*6o(G(l?!kyi|dl1Z|C$3+OjlUo0ECX9?o05B27(JYxTqdS&Ql6C-} z1-b_Gfgxks2FEp94M?VuIAVTlhyCA<2Gn&Im`iNiay5r=%pM1-9+wjoqw0<6F8%Tz zS~SoDsd;W{@DZ^{cpQ0E(Zqk7Fb(6smWv6gVA7EKC`haMDd4iVb=%w?!qnklEOZ6M zo>7E&?-ua0*jGS7Ifp+n1Mtt&EsJ^Zm+MZz$N=`#(W4gXeW6)mxVEWNv|R5|>BC`; zp!AL}AR1LZY?*pMc06+(*)!FuhgLmE2dbX2uNp|YWPt^^lg4@ua?Ck@7WH6izjgo&2H z(Nu(T?Oct>$h7jOy2BEarfZ`2l?*!G2!IF*vNYE13gKLEEh0pYT@M~@lE8?>xOE5epmsX3UYEyS z3}d1q4^3s%cODIn-lKY+YhUJ>5dK2>fMqi8xe+S(Byf2v^R3M9vdja?AHAP?2AWNN zZnZ_x4f1#;T|u;IWf*s76oB9%LBgsX(__90;tP55kY10{hUH>18c=tOKvxIu7@htX zyyC-4SCR7_u05=KJs-sxXfRR2h;w`RN*p;r>jd8kGz(tmRTp^8Fi4zaE+1A(JN?7C zNd0~+-?vjru#4E5{x=&i>K$L_C6QgDj082}7NjN&QC(3jMe4dy;EnOrs44km!U`8Mk}w1Nhh};5{$r21)bSi&T>yP|98<5dRDIeCa{;Cxu;F!1 zRBry_onPe=afCBe@2+GKs_yRQn+JFjkY3RGC2AbnIiT zX7M~58KMafhR5LQ*XX3%dUUs1Aq!Lt(BE`EIiBRs&Baqe!=7G`*+=>$xxtrhnizx0P(#*4ku*{OOz5ZJ|34*qWp@mf&>mDmseK1A1n3~H`X!KxK51`d~nuq zC#VRlqb6wU!SUhgO+0oSn}93MD39XPmQ#AP z17Y67`9^={xhDXM>YsmtSUy-JtKBLpggrF+6_z1^oDMNeomakoH6&2=z_6#|nDb5X zji^PCmC6%=v5&??z2q7s0h8SCJgL;t)~tJU0hgJjW0;r>;t5{P8k!Y9d=XhV^9ggD{&=>F@Y3pil;HMT70Ep`^miZCr% z8JvFIdVCRJE5q|AQIyZiRBgthj;ei%{o~b z6UGH6Y8dGhj4Yd#FJZdqi?bq480a{=_k=r_6e+MO)g|GEMeNNAzXvI@N7S_H z?`45_rEW!lYru5{(75tQc5c)P6R~3Kzc|n)vQtK@TnOE!sMOFL2vA#ek8W_UONC1~ z9UpN5of|=3;?9|^Csp8nNXdb-d51G}^El07_1B_A_Ht{%Tw9&a}6jzZ)|P( za1fZ06_x~0Z;?SAUPW;gAD9H*Sl?gm?k_Y$#)c0*NM$Dx4k$W%6pb%U@|z3Y3s0)4 zHaoRKaPVl?MH?5}zr0lmoRC`*@2}%9s&-x9i(KjzR_BY(EZ!%>bBkyI!x=n+?kAi; zKGdsS9r%<^20KT+I(n_RUa=g*s#n zwOQTx0LIjC^>%+5=p-j3HL%!8Y^1}a7+^z8)Rn34NqA^A0m+kg6@ET!jMlf$gBbN6I@zN{4nYgmok!3=xMp405F-S{ ze8n@dma6)qpv4I7AOKJkASPE+e-HEFUuWc{r%26z1l z@%l6$!i!TUqNrVg!20O=3S1r3pBrJjr@jU|9`35b0R(d^OR-J19c@dc=(<{UT_h;nf8Y$xQ-!p7`WM<2F8(&`FO^p~o$M3j?1LECjS##l=8O z6e>$k+3+4jTuhR)e)yQP4f^Ayupe(sHu?~QK{A9MwcvIIGF104m_G>lY?4u@*rOvL zVWH`9+j4u0uk!1O=zsiSvj1oUF4a)pSe4rV>U``Hb$h{cG%PTMM*s^}#EyNY-Vfx1 zR(p;V>G$+6~+OVftrUB0IJG*nV|Pb?UaLT zyEHSb)M#eeE6_WL)v;n?O<8GLi2)Lygipg~pH?=S&+lI0P!sDiso1Jah{{g<5k2&? zPw01}3H{S6-IbHW8;kidfyfK1TVM~sVW~1VJAhB-Naow>b0c+EVegub-!aW%igPeS z!E8x&3#vAq9$@~x%+T>VSP^Y)enH{Okt5Py{}v#=bhIu#WRL|lYD4FjK>3uXAW?=U%7xgZq@ zv@ejNbXU$z>{Uk;U~jx>#Y@%ls2IFN&lCVGQ$50?)4od;CurYcJ0Lv=ONOU`$53rG zO;CAeW^wYy2fRA^QnY%M`YxAg$Ds*24)uBQc4457Jb6>sNpfRPASr1VX5&dbr`$ZL z=N;LRVHiL(QZFkFt!KHc5xbt{S(?Lu07Q;mft>_Ps_q&XrVVbLpwMtb;{%FfWEFFv zo)M1r4zmha{oVvNQ}6mC*>J=OtcPbSs2@~abX){Ti|jlg*rAGH%!MD(vGPz7OGc0v zpz3gZ4izTg0L?apMOiq3$PB?VrsXo~WQmX=iqf%K8M#EluR`4y8Suxhqf3kL1Yx1U z)1wT_0v1<%KKzPcZ#hT;GzK|)Y>O@N0rT77X--%(A4V9?+?kV$?%lKK@C9W`Kx zyad^7PY){M5u*`~uR>4%Cm*G{AFvI!Hcw(#@Vxl>RMXmEb9a!J(=;=&MCv!rOkQv= zff2^5%+eKF6URGWn3W}cY<8$oppM{q9VYQn=RtOYt(45M0%6-d%dFBf8i*msP^c(eH9XqBDNivHV$kVU;M{Xh_$Uo|dc1R3$W0>@o{~v!TdNF zHLTh_IN-%_T`%SaL8_~#&5JuB3T5WNLin|lAU3T=c%jtf>Qb^=K_NKL`QS+LBun?w$1jKwhZ zY(#&8Bb6$cakr9<2#8@2KH{kqO$cRdD8|tesM}RU!n)`30hT5z=RI|ug%_%41Nugt zPX*23f#2A$iZc!{sUlFqYOZFT^TR?4jyfpm+VhOw3tQx~(2;b=RNojHM)W`#jQ)t7?z1P_L@ z?EIEXa^X``>6&;{KwQ8Vs(aZH%F7a+GZLw1b-dovC*6~4ll}9X-N$FiM#bYqwE&TO zp)muavh9{XUYTqa<+;@!FHlyYY{!VX#BRjx%DYES0xXbXW}{B9DmK3n!!N=;YT8Qh zPSd6J&CUGrI2F62EspKWdl!Xo!+8{^-sinr?Y11F6M1MeE!s2q9KHW~>|y7QuCsGM zS(?D#)@1~?jwt3P!+K=SQz4#WDY5KSyCYOmCZ4S#9nI~bfa8e`D$B(HGC_s5*b9R- zoWQrSnrw2=veq!UOk`y`W~4ngS!!|g`|jP3S$k{~m_wzUI)O3r5Fef!5>zz2sF{;B zU3jn7Gl@SF8URiF=5f509*@8^!CTtk8!Oz*BrK*Xd(JXr3pvRw>0x!PVZ5Q4M9v7|Rs-ihWVRRgja zIx;wfW%l9Y{^rg8=IyP=Pf55go$uk{feQG^ajY|_v#U)4@H&x`qS~wQzz))m;c5a= z-%xWqJ_-*IwNcDHzBO(@XdEO2#RLKlj%H8D3tzcDxO0_P3wEF^+EA*rD;Zbd$prg~ zRUUO=j|{aS>^~{STaAhh7a^4(_6l_zh-*4gWOAWXJrgdN;J~J8GF3C-9LrB_2g_Qp zBdjPj)3G2=Zo=_^tPQ2vwsQ^@%r*l;fs}4xl*w>HoJG3y*D>3`1_Z=&N0WY4&UT(@ zq|)SRCc^Nr%5bLDHoyS55~a4z@yGF#AvEeJxWfl1O=1N}jb+yNlhTh_T!m4>Bg0f6 znZJ5*u=E|D9aPM`e411(w3Ij|MES%84#X2Zq^OYK#0CD8$1QpIYRbax#2^Dm3cWgn z1<}xsdSgY*)f=pH5}W9j^$`_NuQmALKDt}jxfTmV1s{AnBagev(c-zFLGkr6Y(8Ie zZ1J&`Qsa6Y)T^^(hGio$r$=4*_niL3t;k#t5?mKyBhhA zbz9X694~J@O;s*6MTQ#p18g7Zy&6+Qn@f0EV>sSor$Y z_LmWPnF|pwQax^Hb-NJ>^lLxX2V+ zbyJuk`r;;<%&Dg>LL7PHT(xy@QV*=r#ijv@^W#+VD%3NUI*50DgSJezBmlj_?adWz z72ijBo#_@fuK6f2jXk|P9OduqWw4Ddn~xBtMd{z;b>z+=w%F6MT^Rh4>z~Q*2%DbH z{aeTBloy?8WSc0J^mxk`SHbCtlXNKfP9bbmEAi+q&e3Xe!e7L~qQn^3ucS`i!=Ld%#bIq)Y(Y}QOD_4!QMMw$E(m`|WKuYE&xwy}b3&~) z;_IoVanLTHNiPG3f{RE*%qBU`L`xxpOuRF&L{iU#V`+1l%k?+}#sN4KUG^nb3l{c?dwo_YL1QV z0^FQD$3z)JwWYMc;t8J9!unVrJ$jDwQ}wZ;lz(R-2lcx=1y}v&th2ZwgYSe}oGU0V zWF;e<08*Pu@D%~8B#yy-(=8E15e3DFv_Jr~*X6JHtzkp|-4a27n}N+ejoHD1o-Ozo z$(({ueZUfkAc%H};!hE46>c%37?n^)*x(;a5ds$atHm#C@ynhWzidSMu$z<-pydY9 zfeO`B!W%GL+kh!raL|wtC{Sp>#3a$cg#t-m2?vx-Qgm+pI+Jt(P16Y?#a=0!D0Xr2zt<_Aya%T^Lx1Pw0HXpH20&k^(6k`P;U9f%QOZ!1d(Bu_-d`jXf?(z zYYZ<&PY95#RbjWvw`sA)fJ_=L2=3L3aLENFF+};z^OX8LS=6QSlhO`YpdbZnk9uXN zfz|+YhVS}1+)5K^N9@`Mt%zbF%`6bbd|W=4G9}|s8B6H$CTNvRt7LXr$yi1j zq&5gVbGv$Ok6pe^i$sMe z>8OEClmk(M1fkyA;=N$iUNIA(-yoROmL1taUL}f_Gh*E0!tmUWz4afqHm+@Lo-1Fy zGVOuF5nw|bv3M}8_Gq=oE^7}jHL|p0X_>6r2d)cdfDl-?s`lXY5GMei=WKj6WTc-o zSsVZ%p-f&&2HFj@iQ^aqtf<{~6D{C)uANz#W}M+VUb&zb>tA3}qd>ya^e<}=P8+jZ z2(>c&@YZnk7V?~I${?lL-MCRcTA5n0fb$WAvLCfoE3I1DWwip-(bNJaq^c3z@@-ly z6hP3%K^oh#b$96Kun@(URK4-ikRXaw}Cpb(%1l+BcIap zI!)Ao2TF`M)Qe*L7mV7*iH{Z^o!1(yBu_34e)tsLjVyl?-R~$yK`Pc z#0Y~da3l*2{>6bfgtawITGM2gO%uyY zT@OCAy0>c|wq|05K2j&@MI_qw`dV-KX8E=+R!_bUWM#BMsMl-a&e-6^b6nl=YN7x< zAR(h(N{b8mFIYz1`!W;L1Qn2GY;lz|w^#Oo-MK6(%>^_&MPJc{h$UQlNM+OjjJSzb z>v?)DpxMjEFH>UTC#^c!Wp!fPR-BqTPDbr&319*sdZ0IJNoW|+D8|&9 z4a!TPR6y3LGv+lhQ0x%U0+9}8)kq&?$W_HUP6Vz~+du&+LhJxjRn?a&VOM=U;YGl7 z_Cq$oT0PO~iQU!{pvN!+y+_%seV+OV7PwBR+a00@b~yi8|H^f4v@hTN#ny+5lHLndu4y$LU3e3=3 z{SumFc=(gLYQ*;eRUFwG2uTw)VgNNWLl{GyU=#7T9FS*tI=>pOQ#*EKXB{_lLM@oh zIT;{T7S`GTvXU6JzBocm4hk%C`HGgQ6oLcuQpxh!s+3lx?6OL6(g@`ry60imu5`6L z+cdFJRf(0o=Avc3eBT!vBsN$K0GOghYnzmwfyOz6=xQ3Ni3V_@EJc}zc7M1|Z9mTj zs{qzXGv9z-s4f+fx)PlB!3|=99AOdwc%Xb0%e04YIiOyV?q91tTJ5ph+5-jBK$6q; zbNy@sC<>6fOf<7bmUbVbo*Jt67M*4NZ#TPlSAbwpE(yi@#7#TE4DM(SP7{3s(2!0x z;=!5as*@&qz@efs*VSUs{tI?(Qw}gK2|6(~y)>4g;V=@@$?+;u{#O7$PO^bAoSz5o zcK)}mr@(+e$8=Bq+e-}0);Ri_m`;XGA`XUD0ksNfmlcqk0F6DhH7rZBL7c#kT|+M> z8x@*RWdtGCtlqAxbbKQ*QAwxGtx1!P<@?tNbecQMt3qc23sA{>X2R5A*SU7 ziD_%*hgrYmHAN5=?7ON9#3ip>TJm!-#WKUiNR24dio+V|kkCl1Om7xwBKuYZyn9nO zID!}IJB(nt@EzCJVo;nHW>``(&X|_vC#!PG{2n_rKuYfN!)R4Tt1@<3Wf&ch)FDWr z3cFeRAjJ+1iCs>;3Ri4`2XOHC8;~p1wmFa%bpjpRyGaPv4P#JO=%u$!;I+(8j}HxM)ju_jH0l^Q$yI^mM8VHS z>(o}UZeS#t>u4%=TVn`>I7U&ZZ)2eB7EDbt)Y{q@t;X18jbU{_4W8<49`&0%>@f1Z zsG|uIx#G8uGo*j-!I1_SXHaH_W9uz8P1J=Qfk)X0w7_f=F(=Xp*gRSYqSK_qACN09 zvQ4UfC8{A&EQSpC)}u$m`Arbo6I6&;MGlPC*B(}aHfLKlVYk|&)gHU7J>dPKbKSGl zoov;vVK9Ld3i@QNhD377tbNg2TkNl|^-nF7@BUF_Lyu`#;CGA?oocN~#fNP=PC7=% z+DPglI*Nw?E9aS^{%CB5@Pld!QHg_%rl%yJY|a&HOnAcQprryipM3@?6$Xh*ttW!l3} z6DK4VGciaD1oE7uS^2GTFM<>B7S66p{ z%`%HorlrcN*Fbjwcf(Bp@TXpq#o%wygsXl}DQGc~9WZTGL{%K}=T*rV2r}1lQ7E=VT#EU5 zo~BKj_%3dg`P7f9PPK^^Kr4>np?7)gI<@n$fP}NaQm)NMrTvt?iy%)`*+I+KuS}H? z^jybo=^@^0Rmm@-O0obwv>;w4OLvxSYO8k1s0rA=$Z@s!NpIUwkPL`vlll?P4^zNQv zN>qkGK+ll6l=W4J?>R2o`P=f2R)zc`D#T3vBz5)X^akkTS;uk4aJt5bpn=^E`(*3! z$-h2YDi?!dOT>tREKc<5ktVvt@&MNC=}Z@mbO4wK6W3Dt^5*v7LiGzu0or8vS)i49 zAdbq4cd&G)`^n)+5T-NmQd5rx)nT1Db=X#H!>MgJb(h1bK1#b#xaq1#YXf+TzzOY+ zrybCP^)HDl9MF8g@?5{$eSEgA>Tm-ybX`lkY7-~M@@*6SZ<^QENaFp_^;5*3)y1L< z)i&EaGxE$d(TqP8J&2JF%h#*SX)&l+)oGJ2t<%En+`AqB@G~<7fs$6(RlnNF0#B=# zIGS64kjG$sO%{6`yH4SdTWj4*tK~9KVs0ds7Xq_G711VPR3E{UG|)M*nu&TC;7WQ^ zA1+is=arzF{SbqEYl)(6vloeAx~PHqqRA9+2#Ox zvSm7nu0?A5^1jG)=p|#k;~7P{S?I$}EW>kkl+q?P2g_@&9ET#+9 zF8eTjXzo~Fbxy=+nU~WiKnpWGPvv%?7;UOT5cYA*R7PxC71FAZT~;AZ<{JT^4Ao=a zt__9i+9`4gk#?klTe^Gk7HA5v^?#1eq}T)jWFTnu^q$-%4YWoOMoFN1p9yx=`&hb@arCt`TZgy4(rGt2TIgVX$^$>%r}xTR3TX&_Da8DX6Qb+1#KLg$WE0 z5jNBR=Gndp_yCT&y#2>n@#{a$y+3_$#L!~P)SmpK_y#zDKl@+{Y`zQ@zkC{ez!Q@b z6s`e2(bCEO>-Fh_w2=E}re|hfdQPk)-oEpnFFohb z=SA&7|Jv;5yi3*P-#7j8)cZ5<5~C33lWF+Z4$bAyGEXVv3xc#rfA0BXm9#`9>FM`g z%&CV;e&5W$liT!nvxg4Q%h&O5JTr}(!6=q(2Yega$3Czb>0@4t(J$v_C*Cui7vG+m zo%;O&{5A?=pdhhd*B<)qq5sT>{@i|6@bA1qx=}EH?Vmn4HCrJ0uN|76e(AXctjw7| z+Ntu_V+TlT`<@*shuAC+vXA$-d^fj;*_;aw1QG(J6aJT&q~n2665R3I_D#tofm+eM z@Ok+pX|8+%>aq%)br&?99D!_QwUyOpmQ`KK95X?!rNkNEH#76^Z%)nr`=92fX6ev8 zgu_CZL2pgHiE6A@e>W3N?f-Wv)Y+lgcjn~Zak{@eMeoGnlh;W|P^{x$02@2!l}2t7 z;jnT^7zwRDPp}ICMat9AWndEK5dR3K!7v0Q%;4rn-No~Hfpd4^eD}g-{;+(^GU>C8 z7=5fV%Fs$*D}B2xeYQnlM~UX~jR_5xy)+XV!?zP84z4q& z0|Lu8VvhN@($q@RE=!YZqy4wzXkj9jCT_}a7->eIoY~QXDS7!wcjaS%k#RK|>fwj0 z_a<>9adm6&+@0>J8~t0~ch^7r>!S;U#k-P?X61DE$aUj|pXLB8JE5#j zWV%MitwXI$wKBEKGUYgt?RY-#FBzgk#1#|;-Gw9F^@m$e*BgMeW7pb7qJy-POgx&$ zwPkX7etGNRB7>0w9uzWE-+Xg?3rCLG9yoYrZ9?eKn_r~*hm!IBmr@|Y*lT~iT0e><#WQa zGoZhwT0PJ3#-{+phAZB^zlIle<-qnL2hO(=036AIJbE5%^uOGI5d~VE-uGv>9^Hin zRz66n1r?>H?W8T{e0xX;r?pwGru>iqX9ZZdkcOlj&d7qg_G$Oz3L4)A_ii(R0*Y@T zBK^%zdY5Y-7;vhQ&at&90tdx+S5W*g3tNmK#6^pemaR1fYv!4nc2Po}8L{3Gk5T}z z67@cRgeDDCI`vMjvt?DT=8J7A@aQIhF4H1m&n_Z#q!iUf*oNzcrYsw;QTt%qFH8*9 zu6K_dA-C%G7k_>98Q{XeJjpb+y-U}78>c9=y?L*9>>8p5=vJY?w+J*)UHaw*SEPfK za(MJ4eRAz&@AC%*tF@z80=+A7Xs4W0)?@E}(m@}N&M1LejNzrL!w+wD7Z-XLm$o)8 z$mLx53L*F2;whRn#=m+wpHXk|Q+&v8;WG~BKgTq2d=H+U-+J&BH{J}Mo})*8?aKd~ z|Dbzn8U2xiJ0Ia>?>;>;T-yZnQSbNyF240(2{j;F8^^Ii6>iQ7yfn5`r|9O4FtIaJ zmf}nGY`!qj6YRi~{fozYm!9&RF;;)`{NV0kd`PQ)0&|#$kIDrp{o5CY^Go^D=-zn* zN~ z(?jrUqI>EDdQI>~?VQKkt&I&T;~L#bZ~1h8<@V%Y{=@F^Yhs6-!}L*i-d|tkBeL48 zjTrPrp6eDpcgyaCw%^h2h?2C6=d0~0+week(9tvs2N(hDHDssqBp2o;3p(agDU@M}ut^4#tnwMa| z%il`wWARrcLW%^XiogOE!VZC+rp}!;MHlMt+q3;^8vsffp5E-Pd`j#2fWiP<4>r1I z?f}J~A2Vxj{B?N#+VIk4-Z8y%%jDqS{TADuA$YkUg^}UFC3moL5vMS%>!lBe=jkZw ztzPdwUB%sYmlwJ#-__D7MhX@sL#B-NBgYDyG#p`>7oMO(nd1P~s|Rs{niIqMQ^U1~ zK)ULG@UZ#;7$iPaoWyaG$GQlVwAF%?@h_>^8+l8j=BHV?-*3lq{=2OfG!2wF3-4B| z7PP=OSoE=rHin(w1{YY-#};*^;@fNtmy{g3wqphz3H{%OAKUQbGlw64iE2Iz*oldm zC^lV5H6NeWlWd$6SokChzi{QDmHClvs&s)RbJc8g>OfrobtVkZO%vr*KVK@TnkJ%U z@>iO$2VS&JpkiT_t?&;2``1}vFhrxN+*ES4B@(>b?ZXS~~#R)C2GvXG8(cXYAZg%7{bv zyH$9&?C0`e{mqZLd{S((qhA15}Nc zMnmBcY9q*V6OK58q|^AqLC?omXAQcu{`Z^Yxhl;TE+(MgYvijmkG zTp<7T;u244@Zsa`u?yV=DzU0P3%`?Ev8h!QOS&u(^ur2EqK461UJk|yQr7>=-r2?S z!OOI$75kQn>Q50v&@JM>)p7_Y@lDqZwar_Nc&}J+5tp?=+oM0B&yRMGE|7dJZ2$}I z3L#*LH`LAe*++PdfE1!pgF6cpdD+}VBy{V+ajMe;TV_HuYuU9G*e@0DM7SMKyT zZ}yg+s-qy3*gb-1>I0$`StkPf!QBsgXYbX$DJ#n2u%iRrP#|8|i@0k4_%|HKLdTD~Oo@Z`SSc_!@l3Qe>R;9@a4MWBXrnFJ31&)p#=!CH)4Gg1sq)B4%J&|L=Ns<8QlAV zZ-VPT>Q2gzt;h!IqpDS)+1Q+G=D<0f#Efi9Lv?{e23wqz(+`ISkH6`jlo?|>N{(IU z5&$;1*$OYejWR9eC6Q<2|HO^xTIz50)HgZ_;Jc;bl^P$%3A8yc6^9bam#SC{+yFqq zL99IXN*2)g2d46rtuvChtf&^V4o_zV57B`0Ke@dEq^+8H7+LN7#d4RMKxG;-bh zvtlm;mb$j1d05`mYFfYUwe2j4GH}nR(t-*!L`;>lmL3ql&9^p(3Mft^1;o&2qn)yPPTl>*=|!RM;uU#deu{v{L0 z%6+_M>vR^s5r*5>jkSU|CqNuHe4 z#rK}zZ{;FgJSE47?KqaS&Qingmag)BFK{d!pOxbwh{JF%U3c+X@6+2@<}r1}5fc7R z`7M=cDZ>IyrY9?PTP@Z43%l$uSeb*$Or1w$XQy@fzAX{OPU?b%K|9(}lsZYK5nr9* z@E|SR(2Y|b1*gd9Q0ik;o?12MuX{kKKL=@?&V0)e5F%u}cx$9}C`38Qwgejz{Rf+hoL3~b>4bUB!e5VvO?|pPDKfVBzpoBm9TNP z9$tYUBWlVjty!`N9c`JFgi4uIervk_1J$YOGS*_fb5Bqojk!=>TjZ{I7O;vq8pCh7 zu(=eqi*C&V>iNNt9XvdK~q=3-l1&V)j9rpT%z16Gu0tJUQZs5yU zKD_0w7gY&zB&Y6V;XK=3>gbB^-YsZ1X>qQ8*+<^&Fwym5Imqc0CGYHy@}$bgEK_{Q z(8gXMk@vYuO+TwFAcDDp&vBNK$$Ir88XoDrrJI0`WtCh$cJb!*gETfeu9gO%t`HP= zpqq!*d~*SN6>SOK+ow32iL(!d4D_Kmg4vv{JFXKYo`Zb5x+&yY^7vHu`YPuHxv_+g zFlrc}bSt%4@uuJgBrfWZ2j7N>X^ajh4$ckk+{1m;o?yquan#XvEykzh$ftMZ@e8z# z!{|Q}jbEZ0faZm>_vw-D$_>O<_)plQbq7ZwVUigV0Zu+{Hb;0D=BZZIXTXkRf#OYB zK4#f2MC(oD+OmD7J$~EccbAV}2dx~oDa&i*u7+Y^t%4jObPj-<#`H}2HZE3Zw$t&_ zG0wD+N1^I3GMPtt)sZhjWo328^9=B=yS^6q#3?#KN|Zqm7;UPza%$_z1&q2KX}EfM zr&^WTL}VfAPQ?i$@XI6`I0IW2>X^Awf+YZLCULSvIsmQd{MWi8n`vl7=@@npdj>+A z=cpag$%_P-SfqDaM!1OMDGuZf=TN}Gij&zS*maUCK{g8$f z2G8IQ6^fzlu$gkOf;h?yUuiNBm@#D1qo#FpgGZj^DK#*b%#Ilc=p0r}Nj8M?9@9eG zDL)N{tGCM)UYW6ECAMpH0$$-(1+^+@msJol&<@&}HUHz;X(1ga_L6u^R)l-YZWLGS zs^c_^t=hmxrwV^fCfSV^joy>wCNYS}wU0m`!uo{^D_F}Q7y(Y zh7&rrUgW|`hp&grv&+UG=B82IaeOBOTelACJ6046!#3a3BL8q(@Tg+Agb#(b(Z1p0psr{P-x;HR~s7&(S$5`YoJcw9UPc@aW~FfdosZXOeHQr$A5 z_5{?!3%D-~!c)k{RA(gh6!3rq21e~028yJa>isRG35zOP>t5ST5U(2d!Ndb&%L+G^ zKRH&t{pF+hkRIaT>EqtUo$?XOl#ri>o&lsBq2^m7s5OFi+X!+Ez;=zD-vT~H?fWX< zx5aA5^#TjYY|S`$nJj`1u%^c_o+QckPDCP1@VUF~8yMi3af_;LK9D@rFQ(0yHJR1@14PC}L5 zAp``ZgY=G+AiW5YqI9GqQUX#1gn*PNARr(eDGJi0UOW^Joc=)nHIsbmYNKQ3& zQ^FeffIo{0pK~q5l?*!@RIjp`2=Q|x<4jSZ85JdPL^3ZozJpiIrn6 z*SE?8ao2YgsiHB21}(FE1RR*CeEU?#y8&hDEz0Y~${8`Xo=I)!sW>R73+HN+mOjbYdoXuYf&HP>uZ}zNaBso3tusI4-NU$YQz%Q?-2;EoeUmG zq#}sM8V5^>)Ng!rOuE&wULGby(I*ywvZg+;#~&nGmRH=+^>(XLs4JZZC5!1Jo-ZB3 z7N96$_IRA6qWnzM})zY!InQ7 zAfi`+XMX-v5pRZ@$An z`-G2PUi2oy#lgsIK#-fvU{>hT2CK>{ALYvF>?*kQ@dzVsza-1pMCAh=FRl;!g8J_} z{iT3h=7U!?Nn_hAiSE$JmcwoWwnox}NrPTDc2#mSbM-t9OJEdb;uXR*o@;Zyv*;t& zUnZgn(GXXq$gL_ucMUB$wn0zK61bV(JVPKj?uE1z@17{fKP3-h?d;rdjDmj!c8r+3 z8*hMm*<4S3hBZG1>(OKpNJ0CUairXWq|qE^m;46K>H@vFi4 z^>-9AS|x~MMMK4vRn>TL8D{Xb zZIa>ZsudATJ4eA5QMBwT`sx!0DBAlB`EfH_52k5!KdH>#hUG^kh1PLOHgwazRw9Ci zMUt5F0Xjx=JS|QssOx+X^D!s*h7>E5LiDtM4KogHQ(hxBlU2wm#qD&Fk;_wA-Wg@4 zUpCWu$x5&#NnM7-=4JZi$vF@0_Q}Yo*x(y*&|=3w0U!V@y+}v#TZA5W*7Tr(I_5j= zluZ)%`q+htTZF6jQVB8du>WYIq+^R6&83war4#f@R}Pl!KzG*(hgG`2fpnl$uhi{W zx}sWZ|J=r|z);YCavzrYl0|W67*-)zUkVjwzH%-l`7*MRZwlx}aqfwo8o>rV+2g*< zAS6ipA~z*|Zv!VA}03YYsIb)%}af^L^WI*@BYCw4wxBa)ReGr>4W%QeKp zx8QF#JGfy*26m4KSfyT29)YUi>@i`a8?F8C)h=UmK&nh!`6*d4nD5Lzqfe^EYyd&o z!g2xt1@cZqpEz}JkG5XGX=TYIdw2$8l-1{yk-2>I4dtWVpuI%^PP-hc zG@T)P{Jv@Yo8Z4KDqK$_b)|+nVrZ#Ra>OH2mv$MN>FtzY*CH!u?3nz7Z%b^Ejf> zGwr2+{;dV#$RWudl^zRgP9)-k`K#v^k3-_ivFu06n7QsPhqj>`n+mtjvR+)*kF!w@ z3$;J>np>HFt(X;UbI%&w(%jp+Hhp%(obqehXpDRZs&KE_Sm?;MYG_zQ?}HAV+WtoLL|U>FDIzd+2F+YBZrjZuc*gd z%FurQ0ZJ+7RTM*GdBxssHq*+brA4PswSQjOzp2N$utYfD2TyfNNS@u57|x0{Ryfg9 zjE|#+fY3MtnF4NRZQRX5Y=-vvRljK(3;Ao+ERc;izGQ0sVcm6(nN>;~Ja?m$-6?+a zg}~sn8J2dKXO8AgTINR9wkkfi8Z6L&QNx5uy};zAazPBe7R(<*sS4mCs z`D%-ALxI6Yan0lT{@W3@yTtW}Ad|6|`=Rn$2*1a{bH^VMMW3SZt>%k?R%G>yNk@m7 z+$!(RMZ#Hx>XeM+g8=V6J+* zy4wiYxw?4hTUt5U^7}YDp>9pNObF7UGAq5IwXW9TP!LbC##^qa1XlG?TH6 zXrCan4abSa=`6pX*M2Dm#xqu#&JQ(%p^mBe*qn!)Ul!8#PS)oL`ydkfcR7^%TJk#Y z!D72uDCaYdcBEyIs4#vcU7RVw#NLv=AMNrRi}c>NtlSz?K_}O}eMj~hkuEbJ-K zNVxTNh1H7EO-fpsS3fv<6zO&o2m4OU`>`z9WK6-pWGsYWeDUlwWJ<%E9Cwc&3u zz`&!C#aYzf?O35$(3?w7qhY6iZ%m}mOjbL|Frn#_Hp_cq_9}*iyi)K?ai_$~JJKqL zw0$VtzPGL&*Lj3H5p`e^)EU}l#h~R_p+w`_**akCbUy|t80Xnoux~(owbkPFxH2? z*@PD>!qGC}vl+BlRwXzTjoBY@c1tT#cw3{poEWcR=e-7F;eRmdDPP-9f8<41+i-q( zw5du=P8R`%0?elqlv+1jawYpr=1BVfL;>9zB8OXg%TK~* zW{$pOW0}@J5?D7OIvp8_4zo+ky%}dN_X;QNI35oE2%5$*S{~n9JfcS9%@r({*H!~c`zPNMivW{C zfbWU*{p4qZi#b}j+dADB_&xc6SFSLfV}APt0st`i_tS^}!m~JTN&`!XEOZNJhNUM! zVv^^|pp&c8O1fG=5KHnD@zhz2R#kvsNMKEA32NJ2*#5o${muvXJwkl4;+?k%5)Fuh z>q**AwVU=fE!_yOh&%{U+|Hd<0*m)9ww)qz7lh;eAQfEva=a_a^Xc(MM+<_tS>iC? zX=4jFMStjuc<_|5%fM`=bAJdcB{px29_Q}85`}f`GN-ST*D8yLJ(%{JVwaKB?nPYh zlccS1-mrl0%Hb6T6S=3@dCK)}J=ai;#09@3LDC2%q)|-9txLcxeXsVNmT|6!d+E0D^99sm5+P6YbAp-$!gHb{%>E`V(Mq_1zmbn6xtRb3^ z?nxc&i7MDzP5v;Q=9weKL9Zhb--D>+b~++`z^l6Hy{tXcadR2u@ujtxVTIEMPju;PEBPky4;~Q86%oxzx1Lnm9n2P{|bHf{|r1x z&YP&l-F+7T817Mz`*svdle$y zZNUwZiMPVxQfXN$Y_g#SikNSdQHf+9GqZmNONJ^(%=+e%baBs(iYDA#)e*z-om`tz zXOuzYrKJ!FF~}$sFC~^Qvj>`|vXyd`cO0~a84ytCh#8ZoqC?+!ah-(0w$WZB@3mSX zBV@bGS>O|JsnJpUFq@u&_${P)f;F)bj;uCIwoTTY4;t7D8&$!w?_s;7ZRF~Od#3~Os z6mZFkT8$}34Ta6XG=U&0z^^CppOb=_7XT2zjA>74K>s#HKW^~v`EgNcei#|%U`GY| zr|$et`e)_2!2BS6{14`Pp8P+uOFx(}?FHF|VbTod?h3!CbHDS6i`LRgVImJRqJNx! z@Nxb(%n}a22*N+nn#U(xdKk0~22K8*=zdzu} z0sPU~@!x^}Q_}t%c9a=oaq%G#P;;H=57mU|fA;#n@9`)6&z0e?ju4ao9Kmnv#6R&M zbrwMujJ~vZe@@yV=}-FmwjLgLUF`4w()?Fi+{SOL?88h!mJ this.CreateData(type, procedureName, params, pageSize, pageCurrent) + -> this.ExecDatabase(data) + -> MESCommonBase.ashx + -> SQL Server 存储过程 +``` + +常用 type: + +| type | 用途 | 说明 | +|---|---|---| +| `11` | 查询 | 返回列表或分页数据 | +| `12` | 新增、修改、删除 | 返回执行结果 | +| `7` | JSON 批量 | 用于批量排产等 | +| `2001` | 导出 | 现有导出相关逻辑使用 | + +参数格式: + +```js +const param = [] +param.push(['订单号', this.query.订单号]) +param.push(['合同号', this.query.合同号]) +const data = this.CreateData('11', '存储过程名', param, this.pageSize, this.pageCurrent) +this.ExecDatabase(data).then(res => { ... }) +``` + +### 1.3 核心数据库对象 + +本轮开发必须优先复用以下核心表和视图。 + +#### 生产计划主表 + +表:`MES_接口_生产计划` + +关键字段: + +| 字段 | 类型 | 说明 | +|---|---|---| +| `订单编号` | int | 生产订单号,主键 | +| `合同号` | nvarchar(50) | 合同维度 | +| `订单状态` | nvarchar(50) | SAP/MES 订单状态 | +| `物料编号` | nvarchar(500) | 主物料编码 | +| `物料描述` | nvarchar(500) | 主物料名称 | +| `计划数量` | decimal(16,2) | 订单计划数量 | +| `计划开始` | datetime | 订单计划开始 | +| `计划完成` | datetime | 订单计划完成 | +| `同步时间` | datetime | SAP/MES 同步时间 | +| `任务状态` | int | 订单任务状态 | +| `齐套` | float | 齐套状态或齐套比例 | +| `预计齐套时间` | datetime | 现有预计齐套时间 | +| `齐套时间` | datetime | 现有齐套时间 | +| `发料状态` | nvarchar(50) | 发料状态 | +| `拣配状态` | nvarchar(50) | 拣配状态 | +| `发货状态` | nvarchar(50) | 发货状态 | +| `要求发货日期` | datetime | 发货要求日期 | +| `入库数量` | decimal(19,6) | 入库数量 | +| `确认状态` | nvarchar(50) | 现有确认状态 | + +#### 生产任务表 + +表:`MES_接口_生产计划_生产任务` + +关键字段: + +| 字段 | 类型 | 说明 | +|---|---|---| +| `AID` | bigint | TaskAID,任务主键 | +| `订单编号` | int | 生产订单号 | +| `订单行号` | int | SAP/MES 行号 | +| `订单拆分内码` | int | 拆分内码 | +| `物料编码` | nvarchar(500) | 任务物料编码 | +| `物料名称` | nvarchar(500) | 任务物料名称 | +| `工序名称` | nvarchar(50) | 工序 | +| `顺序编号` | int | 工序顺序 | +| `总工时` | decimal(16,2) | 任务总工时,现有字段 | +| `指派对象编号` | nvarchar(50) | 指派对象编号 | +| `指派对象` | nvarchar(50) | 设备/工位/外协/装配等 | +| `指派数量` | decimal(16,2) | 指派数量 | +| `计划开始时间` | datetime | 任务计划开始 | +| `计划完成时间` | datetime | 任务计划完成 | +| `派工时间` | datetime | 现有派工时间 | +| `任务状态` | int | 任务状态 | +| `开工时间` | datetime | 开工时间 | +| `完工时间` | datetime | 完工时间 | +| `完成数量` | int | 完成数 | +| `合格数量` | int | 合格数 | +| `不合格数量` | int | 不合格数 | +| `让步放行数量` | int | 让步放行数 | +| `报废数量` | int | 报废数 | +| `外协通知` | int | 外协通知状态 | +| `外协备注` | nvarchar(500) | 外协备注 | +| `外协分组` | nvarchar(50) | 外协分组 | + +#### 生产订单视图 + +视图:`View_生产订单_MES` + +说明:目前多数计划、排产、生产任务查询均基于该视图。新增报表优先从该视图读取生产订单和任务基础信息。 + +#### 生产操作记录 + +表:`YL_加工中心_操作记录表` + +用途: + +- 现场开工、暂停、报工、辅助开始/结束、异常等操作记录。 +- 及时检验起算时间。 +- 历史工时查询。 +- 班次产量表。 +- 当前对应人员和当前对应内容。 + +现有字段从视图和过程可见: + +| 字段 | 说明 | +|---|---| +| `TaskAID` | 关联生产任务 | +| `操作类别` | 开始加工、报工、辅助结束、异常等 | +| `操作人` | 人员 | +| `工位编号` / `工位名称` | 工位/设备 | +| `开始时间` / `结束时间` | 操作时间段 | +| `工时` | 秒或分钟,现有过程按 `工时 > 0` 汇总 | +| `操作数值` | 数量或工时数值 | +| `操作内容` | 工作内容 | +| `操作描述` / `异常说明` | 说明 | + +#### 质检记录 + +表:`YL_质量检验_质检记录` + +用途: + +- 及时检验报表。 +- 生产日报-送检。 +- 让步接收记录。 +- 外协任务检验字段补充。 +- 产品合格率。 + +关键字段: + +| 字段 | 说明 | +|---|---| +| `QT_AID` | 质检主键 | +| `TaskAID` | 关联生产任务 | +| `计划号` | 生产订单 | +| `零件编码` / `零件名称` | 物料 | +| `工序名称` | 工序 | +| `质检类型` / `检测类型编号` | 首检、巡检、序检、收检、终检等 | +| `检验数量` | 检验数 | +| `合格数` | 合格数 | +| `不合格数` | 不合格数 | +| `检测人` | 检验人 | +| `检测时间` | 检验时间 | +| `检测说明` | 说明 | + +#### 设备采集相关表 + +| 表 | 说明 | +|---|---| +| `CaChe_Var` | 设备变量当前缓存 | +| `历史_设备数据_定时` | 设备历史采集点位数据 | +| `历史_工位设备状态每分钟记录` | 工位状态每分钟快照 | +| `YL_设备管理_设备台账` | 设备台账 | +| `YL_设备管理_工时记录` | 设备循环时间采集记录 | + +## 2. 总体开发原则 + +### 2.1 页面开发原则 + +1. 保持现有 Element UI 风格:顶部筛选区、中间按钮区、下方表格、弹窗明细。 +2. 报表页面只做查询、导出、打印、钻取,不承担基础主数据维护。 +3. 待办类页面可以做状态确认,例如手续确认。 +4. 能扩展现有页面的,不新建孤立维护页面。 +5. 所有新增页面必须同步菜单、按钮权限、路由组件、操作日志。 +6. 所有新增表格都要支持分页,避免一次性查全量。 +7. 时间筛选全部统一为闭区间:开始日 `00:00:00` 到结束日 `23:59:59`。 +8. 导出字段必须与页面字段一致。 + +### 2.2 数据库开发原则 + +1. 优先复用现有表和视图。 +2. 新增字段优先加在业务主表或扩展表,不能只存在报表 SQL 中。 +3. 人工维护字段必须有维护人、维护时间、原值、新值或日志。 +4. SAP 来源字段必须有同步时间和同步状态。 +5. 设备采集数据必须先落原始数据,再做汇总,不直接覆盖业务结果。 +6. 报表公共口径优先做视图或公共存储过程,不允许每个报表各写一套算法。 +7. 看板类过程必须可传统计日期;实时看板默认 `GETDATE()`。 +8. 写操作过程必须返回 `result`、`message`,批量操作要返回每行结果。 + +### 2.3 命名规范 + +新增表建议命名: + +```text +业务域_模块_对象 +例:生产管理_装配已排产需求_维护字段 +例:生产管理_设计任务 +例:生产管理_编程任务 +``` + +新增存储过程建议命名: + +```text +业务域_页面_动作 +例:生产管理_装配已排产需求_查询 +例:生产管理_装配已排产需求_维护字段保存 +例:质量管理_及时检验报表_查询 +``` + +如复用原有 MES 前缀,也可以使用: + +```text +MES_AssemblyPlannedDemand_Query +MES_AssemblyPlannedDemand_SaveManualFields +``` + +本项目已有大量中文过程名,建议新增需求优先用中文业务名,便于现场维护。 + +## 3. 通用新增基础表 + +以下表建议作为多需求共用基础能力,避免每个需求重复建字段。 + +### 3.1 SAP 调用日志表 + +表名:`系统集成_SAP调用日志` + +用途: + +- 批量关闭 SAP 订单。 +- 外协采购收货单号追踪。 +- 发货通知、缺件明细、派工时间、合同交货期同步。 +- 后续 SAP 失败重试和对账。 + +建议 SQL: + +```sql +CREATE TABLE dbo.系统集成_SAP调用日志 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 业务类型 nvarchar(50) NOT NULL, + 业务主键 nvarchar(100) NULL, + 生产订单 int NULL, + TaskAID bigint NULL, + SAP对象类型 nvarchar(50) NULL, + SAP单据号 nvarchar(100) NULL, + 请求地址 nvarchar(500) NULL, + 请求方法 nvarchar(20) NULL, + 请求内容 nvarchar(max) NULL, + 返回内容 nvarchar(max) NULL, + 执行结果 nvarchar(20) NOT NULL, + 失败原因 nvarchar(max) NULL, + 请求人 nvarchar(50) NULL, + 请求时间 datetime NOT NULL DEFAULT GETDATE(), + 完成时间 datetime NULL, + 是否可重试 bit NOT NULL DEFAULT 0, + 重试次数 int NOT NULL DEFAULT 0 +); +``` + +索引: + +```sql +CREATE INDEX IX_系统集成_SAP调用日志_生产订单 ON dbo.系统集成_SAP调用日志(生产订单); +CREATE INDEX IX_系统集成_SAP调用日志_业务类型_时间 ON dbo.系统集成_SAP调用日志(业务类型, 请求时间); +``` + +### 3.2 业务字段维护日志表 + +表名:`系统管理_业务字段维护日志` + +用途: + +- 装配完成时间人工修改。 +- 钣金预达、钣金到达、泵预达、泵到达维护。 +- 预计总工时维护。 +- 预计可执行时间维护。 +- 手续确认等人工确认字段。 + +建议 SQL: + +```sql +CREATE TABLE dbo.系统管理_业务字段维护日志 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 业务模块 nvarchar(100) NOT NULL, + 业务表名 nvarchar(100) NULL, + 业务主键 nvarchar(100) NOT NULL, + 字段名 nvarchar(100) NOT NULL, + 原值 nvarchar(max) NULL, + 新值 nvarchar(max) NULL, + 维护说明 nvarchar(500) NULL, + 维护人 nvarchar(50) NOT NULL, + 维护时间 datetime NOT NULL DEFAULT GETDATE() +); +``` + +索引: + +```sql +CREATE INDEX IX_系统管理_业务字段维护日志_业务 ON dbo.系统管理_业务字段维护日志(业务模块, 业务主键); +``` + +### 3.3 统一异常关联表 + +现有已有异常管控页面和异常工时逻辑,但本轮要求所有报工页面选中任务直接报异常,且审批人多选。建议在不推翻现有异常管控的前提下增加关联表。 + +表名:`生产管理_异常管控_任务异常` + +```sql +CREATE TABLE dbo.生产管理_异常管控_任务异常 ( + 异常AID bigint IDENTITY(1,1) PRIMARY KEY, + 异常编号 nvarchar(50) NOT NULL, + 来源模块 nvarchar(50) NOT NULL, + 生产订单 int NULL, + TaskAID bigint NULL, + 工序名称 nvarchar(50) NULL, + 指派对象 nvarchar(50) NULL, + 异常类型 nvarchar(50) NULL, + 异常说明 nvarchar(1000) NULL, + 附件ID nvarchar(500) NULL, + 状态 nvarchar(20) NOT NULL DEFAULT N'待处理', + 发起人 nvarchar(50) NOT NULL, + 发起时间 datetime NOT NULL DEFAULT GETDATE(), + 实际处理人 nvarchar(50) NULL, + 处理时间 datetime NULL, + 处理意见 nvarchar(1000) NULL, + 是否关闭 bit NOT NULL DEFAULT 0 +); + +CREATE TABLE dbo.生产管理_异常管控_审批人 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 异常AID bigint NOT NULL, + 审批人编号 int NULL, + 审批人姓名 nvarchar(50) NOT NULL, + 是否已处理 bit NOT NULL DEFAULT 0, + 处理时间 datetime NULL +); +``` + +索引: + +```sql +CREATE INDEX IX_生产管理_异常管控_任务异常_TaskAID ON dbo.生产管理_异常管控_任务异常(TaskAID, 是否关闭); +CREATE INDEX IX_生产管理_异常管控_审批人_人员 ON dbo.生产管理_异常管控_审批人(审批人姓名, 是否已处理); +``` + +## 4. 需求 1:及时开工报表 + +### 4.1 现有页面 + +页面:`src/views/AnomalousManagement/PunctualWork/index.vue` + +现状: + +- 当前按指派对象过滤偏向反选逻辑。 +- 需求要求增加正选页面或正选模式。 +- 真实目标不是重做及时开工算法,只改筛选方式。 + +### 4.2 页面方案 + +在查询区新增: + +| 控件 | 类型 | 默认值 | 说明 | +|---|---|---|---| +| 指派对象 | `el-select multiple` | 全部 | 复用现有设备/工位下拉 | +| 查询模式 | `el-radio-group` 或 `el-select` | 排除 | 包含、排除 | + +页面展示: + +```text +指派对象:[多选] 查询模式:[包含/排除] [查询] [重置] [导出] +``` + +交互规则: + +- 查询模式=包含:只查选中指派对象。 +- 查询模式=排除:排除选中指派对象。 +- 未选择指派对象:不增加指派对象条件。 +- 默认保留原逻辑,避免影响现场使用习惯。 + +### 4.3 存储过程 + +建议扩展现有及时开工过程,增加参数: + +```sql +@指派对象 nvarchar(max) = N'', +@指派对象查询模式 nvarchar(10) = N'排除' +``` + +过滤逻辑: + +```sql +IF ISNULL(@指派对象, '') <> '' +BEGIN + IF @指派对象查询模式 = N'包含' + SET @where = @where + N' AND 指派对象 IN (SELECT value FROM STRING_SPLIT(@指派对象, '',''))' + ELSE + SET @where = @where + N' AND 指派对象 NOT IN (SELECT value FROM STRING_SPLIT(@指派对象, '',''))' +END +``` + +注意: + +- 现有很多过程使用字符串拼接动态 SQL,后续应尽量用 `sp_executesql` 参数化,降低注入风险。 +- 如果 `.ashx` 传参不支持 `nvarchar(max)`,可用 `nvarchar(4000)`。 + +### 4.4 不需要新增表 + +该需求只改页面和存储过程参数,不新增表。 + +## 5. 需求 2:机加件排产-表单 + +包含两件事: + +1. 已排产页面日期筛选优化。 +2. 新增历史工时查询,总工时列和明细弹窗。 + +### 5.1 现有页面 + +页面:`src/views/PlanManagement/SelfMakePlandone/index.vue` + +现有查询过程:`MES_OrderPlanned_Query` + +现有过程参数: + +```sql +@计划开始1 nvarchar(50)='', +@计划开始2 nvarchar(50)='', +@计划完成1 nvarchar(50)='', +@计划完成2 nvarchar(50)='' +``` + +### 5.2 页面日期筛选 + +改造前: + +- 计划开始时间为时间段。 +- 计划完成时间为时间段。 + +改造后: + +| 字段 | 控件 | 参数传递 | +|---|---|---| +| 计划开始日期 | `el-date-picker type="date"` | 传 `计划开始日期` | +| 计划完成日期 | `el-date-picker type="date"` | 传 `计划完成日期` | + +前端传参方式: + +```js +if (this.query.计划开始日期) { + param.push(['计划开始日期', this.query.计划开始日期]) +} +if (this.query.计划完成日期) { + param.push(['计划完成日期', this.query.计划完成日期]) +} +``` + +兼容方案: + +- 为减少影响,可以继续传旧参数: + - `计划开始1 = yyyy-MM-dd 00:00:00` + - `计划开始2 = yyyy-MM-dd 23:59:59` + - `计划完成1 = yyyy-MM-dd 00:00:00` + - `计划完成2 = yyyy-MM-dd 23:59:59` +- 存储过程也可新增单日期参数,旧参数保留。 + +### 5.3 存储过程改造 + +建议扩展 `MES_OrderPlanned_Query`: + +```sql +ALTER PROCEDURE dbo.MES_OrderPlanned_Query + @订单号 int = 0, + ... + @计划开始日期 nvarchar(50) = '', + @计划完成日期 nvarchar(50) = '', + @指派对象查询模式 nvarchar(10) = N'包含' +AS +BEGIN + ... + IF (@计划开始日期 <> '') + SET @selectStrWhere = @selectStrWhere + + ' AND [计划开始时间] >= ''' + @计划开始日期 + ' 00:00:00'' + AND [计划开始时间] < DATEADD(DAY, 1, ''' + @计划开始日期 + ''')' + + IF (@计划完成日期 <> '') + SET @selectStrWhere = @selectStrWhere + + ' AND [计划完成时间] >= ''' + @计划完成日期 + ' 00:00:00'' + AND [计划完成时间] < DATEADD(DAY, 1, ''' + @计划完成日期 + ''')' +END +``` + +更稳妥写法是把日期转成 `date` 类型后参数化。 + +### 5.4 总工时列 + +表格新增列: + +| 列名 | 字段 | 交互 | +|---|---|---| +| 总工时 | `历史总工时` | 蓝色可点击,点击打开明细 | + +总工时口径: + +- 数据来源:`YL_加工中心_操作记录表` +- 过滤:`TaskAID = 当前任务 TaskAID`,`工时 > 0` +- 默认包含:报工、辅助结束、加班等正向工时。 +- 默认排除:异常负工时、未结束记录。 +- 单位:建议统一显示小时,保留 2 位小数。 + +### 5.5 新增存储过程 + +#### 5.5.1 总工时汇总 + +过程名:`生产管理_机加已排产_历史工时汇总` + +参数: + +| 参数 | 类型 | 说明 | +|---|---|---| +| `@TaskAID` | bigint | 可选,单任务 | +| `@订单号` | int | 可选,订单 | +| `@开始日期` | date | 可选 | +| `@结束日期` | date | 可选 | + +返回字段: + +| 字段 | 说明 | +|---|---| +| `TaskAID` | 任务 | +| `订单编号` | 订单 | +| `工序名称` | 工序 | +| `总工时分钟` | 分钟 | +| `总工时小时` | 小时 | + +SQL 示例: + +```sql +CREATE PROCEDURE dbo.生产管理_机加已排产_历史工时汇总 + @TaskAID bigint = NULL, + @订单号 int = NULL, + @开始日期 date = NULL, + @结束日期 date = NULL +AS +BEGIN + SET NOCOUNT ON; + + SELECT + o.TaskAID, + MAX(t.订单编号) AS 订单编号, + MAX(o.工序名称) AS 工序名称, + SUM(ISNULL(o.工时, 0)) AS 总工时分钟, + CAST(SUM(ISNULL(o.工时, 0)) / 60.0 AS decimal(18,2)) AS 总工时小时 + FROM dbo.YL_加工中心_操作记录表 o + LEFT JOIN dbo.MES_接口_生产计划_生产任务 t ON o.TaskAID = t.AID + WHERE ISNULL(o.工时, 0) > 0 + AND (@TaskAID IS NULL OR o.TaskAID = @TaskAID) + AND (@订单号 IS NULL OR t.订单编号 = @订单号) + AND (@开始日期 IS NULL OR o.开始时间 >= @开始日期) + AND (@结束日期 IS NULL OR o.开始时间 < DATEADD(DAY, 1, @结束日期)) + GROUP BY o.TaskAID; +END +``` + +#### 5.5.2 历史工时明细 + +过程名:`生产管理_机加已排产_历史工时明细` + +参数: + +| 参数 | 类型 | 说明 | +|---|---|---| +| `@TaskAID` | bigint | 必填 | + +返回字段: + +| 字段 | 说明 | +|---|---| +| `设备名称` | 工位名称 | +| `日期` | 开始时间日期 | +| `生产订单` | 订单编号 | +| `物料编码` | 物料编码 | +| `物料名称` | 物料名称 | +| `工序名称` | 工序 | +| `操作人` | 操作人 | +| `开始时间` | 开始 | +| `结束时间` | 结束 | +| `工时分钟` | 分钟 | +| `工时小时` | 小时 | +| `设备日期小计小时` | 前端可展示分组合计 | + +SQL 示例: + +```sql +CREATE PROCEDURE dbo.生产管理_机加已排产_历史工时明细 + @TaskAID bigint +AS +BEGIN + SET NOCOUNT ON; + + SELECT + o.工位名称 AS 设备名称, + CONVERT(date, o.开始时间) AS 日期, + t.订单编号 AS 生产订单, + t.物料编码, + t.物料名称, + o.工序名称, + o.操作人, + o.开始时间, + o.结束时间, + ISNULL(o.工时, 0) AS 工时分钟, + CAST(ISNULL(o.工时, 0) / 60.0 AS decimal(18,2)) AS 工时小时, + CAST(SUM(ISNULL(o.工时, 0)) OVER (PARTITION BY o.工位名称, CONVERT(date, o.开始时间)) / 60.0 AS decimal(18,2)) AS 设备日期小计小时 + FROM dbo.YL_加工中心_操作记录表 o + LEFT JOIN dbo.MES_接口_生产计划_生产任务 t ON o.TaskAID = t.AID + WHERE o.TaskAID = @TaskAID + AND ISNULL(o.工时, 0) > 0 + ORDER BY o.工位名称, CONVERT(date, o.开始时间), o.开始时间; +END +``` + +### 5.6 前端弹窗 + +弹窗名:历史工时明细 + +结构: + +```text +设备:CNC-01 小计:12.50小时 + 日期:2026-05-28 小计:8.00小时 + 任务明细表 + 日期:2026-05-29 小计:4.50小时 + 任务明细表 +``` + +Element UI 实现建议: + +- 用 `el-dialog`。 +- 明细用 `el-table` 展示,按设备、日期排序。 +- 如需要折叠效果,使用前端 computed 分组。 +- 总工时列点击时调用 `生产管理_机加已排产_历史工时明细`。 + +### 5.7 不建议新增表 + +本需求只需要新增两个查询过程,不需要新增表。 + +## 6. 需求 3:装配已排产需求 + +### 6.1 定位 + +这是本轮最大的独立子项目,不是简单报表。 + +页面目标: + +- 基于装配已排产数据。 +- 整合 SAP 字段、MES 报工、工时、异常、齐套时间、装配完成时间、日计划。 +- 支持部分人工维护字段。 + +建议页面路径: + +```text +src/views/ProductionManagement/AssemblyPlannedDemand/index.vue +``` + +菜单建议: + +```text +生产管理 -> 装配管理 -> 装配已排产需求 +``` + +### 6.2 页面布局 + +页面结构: + +```text +查询区: +系统分类[全部/系统/非系统] 合同号 生产订单 物料编码/名称 +发料齐套时间[起止] 装配完成时间[起止] 状态[全部] +[查询] [重置] [导出] [日计划] [打印] + +主表: +生产订单 合同号 物料编码 物料名称 系统/非系统 派工时间 合同交货期 +发料齐套时间 装配完成时间 当前对应人员 当前对应内容 +生产订单累计工时 合同工时汇总 合同进度参考 预计总工时 预计剩余工时 +钣金预达 钣金到达 泵 生产异常 历史工序说明 操作 + +操作列: +[维护] [工时明细] [异常明细] [历史工序] [日计划] +``` + +### 6.3 字段口径 + +| 字段 | 来源 | 维护方式 | 说明 | +|---|---|---|---| +| 生产订单 | `MES_接口_生产计划.订单编号` | 只读 | 主键 | +| 合同号 | `MES_接口_生产计划.合同号` | 只读 | 合同维度 | +| 物料编码 | `MES_接口_生产计划.物料编号` | 只读 | 主物料 | +| 物料名称 | `MES_接口_生产计划.物料描述` | 只读 | 主物料名称 | +| 系统/非系统 | 规则计算 | 只读 | 高压冷却为系统,阀类非高压冷却为非系统 | +| 派工时间 | SAP 或任务表 `派工时间` | 只读 | 以 SAP 提供为准;现任务表已有派工时间 | +| 合同交货期 | SAP | 只读 | 需同步字段 | +| 发料齐套时间 | SAP/MES 齐套字段 | 可必要维护 | 优先使用 `齐套时间` 或后续 SAP 字段 | +| 装配完成时间 | 发料齐套时间 + 3 天 | 可维护 | 人工修改需记录日志 | +| 钣金预达 | 人工维护 | 可维护 | 过程字段 | +| 钣金到达 | 人工维护 | 可维护 | 过程字段 | +| 泵 | 人工维护 | 可维护 | 建议拆成泵预达/泵到达或说明 | +| 当前对应人员 | 操作记录 | 只读 | 开始未结束的人,多个合并 | +| 当前对应内容 | 操作记录/新增字段 | 只读/维护 | 装配开始时输入的工作内容 | +| 生产订单累计工时 | 工时汇总 | 只读 | 按生产订单分类汇总装配、质量、设计 | +| 历史工序说明 | 报工结束说明 | 只读 | 多条合并或明细弹窗 | +| 预计总工时 | 人工维护 | 可维护 | 订单级 | +| 合同工时汇总 | 工时汇总 | 只读 | 合同下所有订单 | +| 合同进度参考 | 计算 | 只读 | 累计工时 / 预计总工时 | +| 预计剩余工时 | 计算 | 只读 | 预计总工时 - 累计工时 | +| 生产异常 | 异常表 | 只读 | 未关闭异常数和明细 | + +### 6.4 建议新增字段 + +优先不要直接无限扩展主表。建议建订单扩展表。 + +表名:`生产管理_装配已排产需求_扩展` + +```sql +CREATE TABLE dbo.生产管理_装配已排产需求_扩展 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 订单编号 int NOT NULL, + 发料齐套时间 datetime NULL, + 发料齐套时间来源 nvarchar(50) NULL, + 装配完成时间 datetime NULL, + 装配完成时间是否人工修改 bit NOT NULL DEFAULT 0, + SAP派工时间 datetime NULL, + 合同交货期 datetime NULL, + 钣金预达 datetime NULL, + 钣金到达 datetime NULL, + 泵预达 datetime NULL, + 泵到达 datetime NULL, + 泵说明 nvarchar(500) NULL, + 预计总工时 decimal(18,2) NULL, + 备注 nvarchar(1000) NULL, + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); + +CREATE UNIQUE INDEX UX_生产管理_装配已排产需求_扩展_订单编号 +ON dbo.生产管理_装配已排产需求_扩展(订单编号); +``` + +### 6.5 当前对应内容 + +当前系统 `MES_人员工时记录_开始` 和装配中心已有人员工时逻辑。需求要求“装配开始时输入工作内容”。如果现有开始记录没有工作内容字段,应补字段到对应记录表。由于实际装配人员工时表名需从存储过程确认,建议先通过 `MES_人员工时记录_开始` 的落表对象确认。 + +建议新增字段: + +```sql +ALTER TABLE dbo.YL_加工中心_操作记录表 ADD 当前工作内容 nvarchar(1000) NULL; +``` + +如果装配人员工时独立表存在,应加在装配人员工时表,而不是操作记录表。 + +前端改造: + +- `AssemblyCenter` 开始装配弹窗增加 `工作内容`。 +- 调用 `MES_人员工时记录_开始` 时增加参数 `@工作内容`。 +- 未结束记录的人员和工作内容在装配已排产需求页展示。 + +### 6.6 工时汇总视图 + +建议新增统一工时视图,供装配已排产需求、合同工时、工时报表复用。 + +视图名:`View_统一工时明细` + +字段: + +| 字段 | 说明 | +|---|---| +| `来源模块` | 机加、装配、质量、设计、编程、设备 | +| `工时类型` | 装配、质量、设计等 | +| `生产订单` | 订单 | +| `合同号` | 合同 | +| `TaskAID` | 任务,可空 | +| `工序名称` | 工序 | +| `操作人` | 人员 | +| `开始时间` | 开始 | +| `结束时间` | 结束 | +| `工时分钟` | 分钟 | +| `工时小时` | 小时 | + +第一阶段可只接入: + +- 装配:`MES_人员工时记录_*` 对应表或 `YL_加工中心_操作记录表` +- 质量:质检中心人员工时记录或操作记录 +- 设计:设计任务报工表,等设计模块完成后接入 + +### 6.7 查询存储过程 + +过程名:`生产管理_装配已排产需求_查询` + +参数: + +| 参数 | 类型 | +|---|---| +| `@系统分类` | nvarchar(20),全部/系统/非系统 | +| `@合同号` | nvarchar(50) | +| `@订单编号` | int | +| `@物料` | nvarchar(100) | +| `@发料齐套开始` | date | +| `@发料齐套结束` | date | +| `@装配完成开始` | date | +| `@装配完成结束` | date | +| `@状态` | nvarchar(50) | + +核心 SQL 口径: + +```sql +SELECT + p.订单编号, + p.合同号, + p.物料编号, + p.物料描述, + CASE + WHEN p.物料描述 LIKE N'%高压冷却%' THEN N'系统' + ELSE N'非系统' + END AS 系统分类, + ISNULL(e.SAP派工时间, MAX(t.派工时间)) AS 派工时间, + e.合同交货期, + COALESCE(e.发料齐套时间, p.齐套时间, p.预计齐套时间) AS 发料齐套时间, + COALESCE(e.装配完成时间, DATEADD(DAY, 3, COALESCE(e.发料齐套时间, p.齐套时间, p.预计齐套时间))) AS 装配完成时间, + e.钣金预达, + e.钣金到达, + e.泵预达, + e.泵到达, + e.泵说明, + e.预计总工时, + wh.生产订单累计工时, + chw.合同工时汇总, + CASE WHEN ISNULL(e.预计总工时,0) = 0 THEN NULL + ELSE CAST(wh.生产订单累计工时 / e.预计总工时 AS decimal(18,4)) + END AS 合同进度参考, + ISNULL(e.预计总工时,0) - ISNULL(wh.生产订单累计工时,0) AS 预计剩余工时, + cur.当前对应人员, + cur.当前对应内容, + abn.未关闭异常数 +FROM dbo.MES_接口_生产计划 p +LEFT JOIN dbo.MES_接口_生产计划_生产任务 t ON p.订单编号 = t.订单编号 +LEFT JOIN dbo.生产管理_装配已排产需求_扩展 e ON p.订单编号 = e.订单编号 +LEFT JOIN (...) wh ON p.订单编号 = wh.生产订单 +LEFT JOIN (...) chw ON p.合同号 = chw.合同号 +LEFT JOIN (...) cur ON p.订单编号 = cur.生产订单 +LEFT JOIN (...) abn ON p.订单编号 = abn.生产订单 +WHERE p.自制件属性 LIKE N'%装配%' +GROUP BY ... +``` + +### 6.8 保存维护字段过程 + +过程名:`生产管理_装配已排产需求_维护字段保存` + +参数: + +- `@订单编号 int` +- `@发料齐套时间 datetime = NULL` +- `@装配完成时间 datetime = NULL` +- `@钣金预达 datetime = NULL` +- `@钣金到达 datetime = NULL` +- `@泵预达 datetime = NULL` +- `@泵到达 datetime = NULL` +- `@泵说明 nvarchar(500) = NULL` +- `@预计总工时 decimal(18,2) = NULL` +- `@备注 nvarchar(1000) = NULL` +- `@维护人 nvarchar(50)` + +逻辑: + +1. 如果扩展表不存在订单记录,插入。 +2. 如果存在,更新。 +3. 对每个字段写 `系统管理_业务字段维护日志`。 +4. 返回 `result=1`。 + +### 6.9 工时明细过程 + +过程名:`生产管理_装配已排产需求_工时明细` + +参数: + +- `@订单编号 int` +- `@合同号 nvarchar(50)` +- `@工时类型 nvarchar(50)`,全部/装配/质量/设计 + +返回: + +- 来源模块 +- 工时类型 +- 生产订单 +- 合同号 +- TaskAID +- 工序名称 +- 操作人 +- 开始时间 +- 结束时间 +- 工时小时 +- 工作内容 +- 结束说明 + +### 6.10 异常明细过程 + +过程名:`生产管理_装配已排产需求_异常明细` + +数据来源: + +- 优先:`生产管理_异常管控_任务异常` +- 兼容:现有异常管控表或 `YL_加工中心_操作记录表` 中 `操作类别='异常'` + +返回: + +- 异常编号 +- 异常类型 +- 异常说明 +- 发起人 +- 发起时间 +- 状态 +- 处理人 +- 处理时间 + +### 6.11 日计划 + +页面按钮:`日计划` + +规则: + +- 按装配完成时间分组。 +- 未完成、未入库、未关闭的任务进入计划。 +- 支持导出、打印。 + +过程名:`生产管理_装配已排产需求_日计划` + +参数: + +- `@计划日期 date` +- `@系统分类 nvarchar(20)` + +返回字段: + +- 计划日期 +- 生产订单 +- 合同号 +- 物料编码 +- 物料名称 +- 装配完成时间 +- 当前对应人员 +- 当前对应内容 +- 异常状态 +- 备注 + +打印: + +- 使用 `vue-print-nb`。 +- 打印区域为日计划表格。 +- 标题:`装配日计划 YYYY-MM-DD`。 + +## 7. 需求 4:生产日报-送检 + +### 7.1 页面定位 + +建议新增页面: + +```text +src/views/ReportManagement/InspectionDaily/index.vue +``` + +如果项目没有 `ReportManagement`,可放在: + +```text +src/views/ProductionManagement/InspectionDaily/index.vue +``` + +菜单建议: + +```text +报表中心 -> 生产日报 -> 生产日报-送检 +``` + +页面采用两个页签: + +- 机加送检日报 +- 装配送检日报 + +### 7.2 页面布局 + +```text +页签:[机加送检日报] [装配送检日报] + +查询区: +日期[单日/日期范围] 部门[全部] 生产订单 物料 工序 状态 +[查询] [重置] [导出] + +汇总区: +送检数量 已检数量 合格数量 不合格数量 未检数量 及时率 + +表格: +日期 部门 生产订单 物料编码 物料名称 工序名称 送检数量 +已检数量 合格数量 不合格数量 未检数量 送检时间 检验时间 状态 +``` + +### 7.3 需要确认的数据 + +| 数据 | 需要确认 | +|---|---| +| 送检记录来源 | 装配送检是否来自 `MES_ProductTask_SendInspection` 写入的记录,机加送检是否来自质检任务或操作记录 | +| 部门归属 | 按操作人部门、工位部门、任务部门还是物料/订单类型 | +| 送检数量 | 取操作记录 `操作数值`,还是质检记录 `检验数量` | +| 已检数量 | 质检记录合计 | +| 状态 | 未检、部分检验、已检、超期 | + +### 7.4 建议视图 + +视图名:`View_生产日报_送检明细` + +字段: + +| 字段 | 来源 | +|---|---| +| 日期 | 送检时间日期 | +| 送检类型 | 机加/装配 | +| 部门 | 人员部门或工位部门 | +| 生产订单 | 任务订单 | +| TaskAID | 任务 | +| 物料编码 | 任务物料 | +| 物料名称 | 任务物料 | +| 工序名称 | 任务工序 | +| 指派对象 | 任务指派对象 | +| 送检数量 | 送检记录 | +| 已检数量 | 质检记录 | +| 合格数量 | 质检记录 | +| 不合格数量 | 质检记录 | +| 未检数量 | 送检数量 - 已检数量 | +| 送检时间 | 送检记录时间 | +| 检验时间 | 最后检验时间 | +| 状态 | 计算 | + +### 7.5 存储过程 + +过程名:`生产日报_送检_查询` + +参数: + +| 参数 | 类型 | +|---|---| +| `@送检类型` | nvarchar(20),机加/装配 | +| `@开始日期` | date | +| `@结束日期` | date | +| `@部门` | nvarchar(50) | +| `@生产订单` | int | +| `@物料` | nvarchar(100) | +| `@状态` | nvarchar(20) | + +核心逻辑: + +```sql +SELECT + 日期, + 部门, + 生产订单, + 物料编码, + 物料名称, + 工序名称, + SUM(送检数量) AS 送检数量, + SUM(已检数量) AS 已检数量, + SUM(合格数量) AS 合格数量, + SUM(不合格数量) AS 不合格数量, + SUM(未检数量) AS 未检数量, + MIN(送检时间) AS 最早送检时间, + MAX(检验时间) AS 最后检验时间, + CASE + WHEN SUM(已检数量) = 0 THEN N'未检' + WHEN SUM(未检数量) > 0 THEN N'部分检验' + ELSE N'已检' + END AS 状态 +FROM dbo.View_生产日报_送检明细 +WHERE 日期 >= @开始日期 + AND 日期 < DATEADD(DAY, 1, @结束日期) + AND (@送检类型 = N'全部' OR 送检类型 = @送检类型) +GROUP BY 日期, 部门, 生产订单, 物料编码, 物料名称, 工序名称 +ORDER BY 日期, 部门, 生产订单; +``` + +### 7.6 是否新增表 + +第一阶段不新增表,使用视图 + 存储过程。 + +如果客户要求日报定版,需要新增快照表: + +```sql +CREATE TABLE dbo.生产日报_送检_日报快照 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 统计日期 date NOT NULL, + 送检类型 nvarchar(20) NOT NULL, + 部门 nvarchar(50) NULL, + 生产订单 int NULL, + TaskAID bigint NULL, + 物料编码 nvarchar(100) NULL, + 物料名称 nvarchar(500) NULL, + 工序名称 nvarchar(100) NULL, + 送检数量 decimal(18,2) NULL, + 已检数量 decimal(18,2) NULL, + 合格数量 decimal(18,2) NULL, + 不合格数量 decimal(18,2) NULL, + 未检数量 decimal(18,2) NULL, + 状态 nvarchar(20) NULL, + 生成时间 datetime NOT NULL DEFAULT GETDATE(), + 生成人 nvarchar(50) NULL +); +``` + +## 8. 需求 5:及时齐套跟踪结果报表 + +### 8.1 页面定位 + +新增页面: + +```text +src/views/ProductionManagement/KitTrackingResult/index.vue +``` + +菜单建议: + +```text +报表中心 -> 齐套报表 -> 及时齐套跟踪结果报表 +``` + +### 8.2 页面布局 + +```text +查询区: +主生产订单 合同号 物料 齐套状态 预计可执行时间 SAP同步时间 +[查询] [重置] [导出] + +主表: +主生产订单 合同号 物料编码 物料名称 计划数量 齐套状态 +缺件数 当前进度 预计可执行时间 SAP同步时间 操作 + +展开明细: +缺料生产订单 缺料物料编码 缺料物料名称 缺件数量 属性 +对应单据号 当前进度 全序展示 单条预计完成时间 预计可执行时间 操作 +``` + +### 8.3 数据来源 + +| 数据 | 来源 | 方式 | +|---|---|---| +| 主表订单 | `MES_接口_生产计划` / `View_生产订单_MES` | MES 查询 | +| 齐套状态 | `齐套`、`齐套时间`、`发料状态`、`拣配状态` | MES 字段 | +| 缺件明细 | SAP 实时接口 | 点击展开时查 | +| 主子订单关系 | SAP 或 MES 人工维护 | 建议落 MES 表 | +| 预计可执行时间 | 人工维护 | 报表内维护,写日志 | + +### 8.4 建议新增表 + +#### 8.4.1 主子订单关系表 + +表名:`生产管理_齐套跟踪_主子订单关系` + +```sql +CREATE TABLE dbo.生产管理_齐套跟踪_主子订单关系 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 主生产订单 int NOT NULL, + 缺料生产订单 int NOT NULL, + 缺料物料编码 nvarchar(100) NULL, + 缺料物料名称 nvarchar(500) NULL, + 关系来源 nvarchar(50) NOT NULL DEFAULT N'人工维护', + 是否有效 bit NOT NULL DEFAULT 1, + 创建人 nvarchar(50) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE(), + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL +); + +CREATE INDEX IX_生产管理_齐套跟踪_主子订单关系_主单 +ON dbo.生产管理_齐套跟踪_主子订单关系(主生产订单, 是否有效); +``` + +#### 8.4.2 缺件预计信息表 + +表名:`生产管理_齐套跟踪_缺件预计信息` + +```sql +CREATE TABLE dbo.生产管理_齐套跟踪_缺件预计信息 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 主生产订单 int NOT NULL, + 缺料生产订单 int NULL, + 缺料物料编码 nvarchar(100) NOT NULL, + 对应单据号 nvarchar(100) NULL, + 预计可执行时间 datetime NULL, + 预计可执行说明 nvarchar(500) NULL, + 维护人 nvarchar(50) NULL, + 维护时间 datetime NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_生产管理_齐套跟踪_缺件预计信息_主单 +ON dbo.生产管理_齐套跟踪_缺件预计信息(主生产订单); +``` + +#### 8.4.3 SAP 缺件缓存表 + +如果 SAP 实时查询压力大,新增缓存表: + +```sql +CREATE TABLE dbo.系统集成_SAP缺件明细缓存 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 主生产订单 int NOT NULL, + 查询时间 datetime NOT NULL DEFAULT GETDATE(), + 缺料生产订单 int NULL, + 物料编码 nvarchar(100) NULL, + 物料名称 nvarchar(500) NULL, + 缺件数量 decimal(18,2) NULL, + 属性 nvarchar(20) NULL, + 对应单据号 nvarchar(100) NULL, + 当前进度 nvarchar(500) NULL, + 全序展示 nvarchar(max) NULL, + 单条预计完成时间 datetime NULL, + 原始JSON nvarchar(max) NULL +); +``` + +### 8.5 存储过程 + +主表查询: + +```text +生产管理_齐套跟踪结果_主表查询 +``` + +参数: + +- `@主生产订单 int` +- `@合同号 nvarchar(50)` +- `@物料 nvarchar(100)` +- `@齐套状态 nvarchar(50)` +- `@预计开始 date` +- `@预计结束 date` + +展开明细: + +```text +生产管理_齐套跟踪结果_缺件明细查询 +``` + +说明: + +- 第一优先:点击展开时前端调用 SAP 接口,再把结果展示并可缓存。 +- 如果后端 `.ashx` 只能执行 SQL,SAP 查询需要前端现有 SAP/B1 接口或后端新增封装接口。 +- 如果不能实时查 SAP,先读取 `系统集成_SAP缺件明细缓存`。 + +预计可执行时间保存: + +```text +生产管理_齐套跟踪结果_预计时间保存 +``` + +参数: + +- 主生产订单 +- 缺料生产订单 +- 缺料物料编码 +- 对应单据号 +- 预计可执行时间 +- 预计可执行说明 +- 维护人 + +同时写 `系统管理_业务字段维护日志`。 + +## 9. 需求 6:生产计划跟踪 + +### 9.1 现有页面 + +页面: + +```text +src/views/ProductionManagement/ProductionPlanTrack/index.vue +``` + +现有调用: + +```text +生产管理_生产计划跟踪 +``` + +页面现状已经有外协状态处理、工序子表、颜色等基础逻辑。 + +### 9.2 页面改造 + +新增/调整: + +| 内容 | 实现 | +|---|---| +| 当前序显示完整工艺路线 | 主表列改为路线组件 | +| 工序文字按状态变色 | 前端根据状态 class | +| 进度文案 | `打磨中`、`打磨毕待淬火` | +| 标准工时 | 表格列 | +| 订单状态 | 表格列 | + +工艺路线显示: + +```text +打磨(张三) -> 淬火(外协) -> 精磨(李四) +``` + +颜色规则: + +| 状态 | 样式 | +|---|---| +| 正在加工 | 蓝色或绿色高亮 | +| 已完成 | 灰色 | +| 等待加工 | 默认 | +| 异常 | 红色 | + +### 9.3 后端返回字段 + +过程 `生产管理_生产计划跟踪` 需要返回每道工序: + +| 字段 | 说明 | +|---|---| +| 生产订单 | +| 合同号 | +| 订单状态 | +| 物料编码 | +| 物料名称 | +| TaskAID | +| 工序名称 | +| 顺序编号 | +| 指派对象 | +| 任务状态 | +| 加工状态 | +| 开工时间 | +| 完工时间 | +| 标准工时 | +| 外协结束时间 | + +### 9.4 SQL 逻辑 + +标准工时来源: + +- 优先 `车间生产管理工艺_零件生产工艺_工艺库.标准工时` +- 通过 `订单编号 + 工艺顺序/订单行号` 关联 + +订单状态来源: + +- `MES_接口_生产计划.订单状态` +- 如果 SAP 同步了单据状态,也可增加 `单据状态` + +过程示例逻辑: + +```sql +SELECT + p.订单编号, + p.合同号, + p.订单状态, + t.AID AS TaskAID, + t.工序名称, + t.顺序编号, + t.指派对象, + t.任务状态, + t.加工状态, + t.开工时间, + t.完工时间, + ISNULL(g.标准工时, 0) AS 标准工时 +FROM dbo.MES_接口_生产计划 p +JOIN dbo.MES_接口_生产计划_生产任务 t ON p.订单编号 = t.订单编号 +LEFT JOIN dbo.车间生产管理工艺_零件生产工艺_工艺库 g + ON t.订单编号 = g.订单编号 + AND t.订单行号 = g.工艺顺序 +WHERE ... +ORDER BY p.订单编号, t.顺序编号; +``` + +### 9.5 前端算法 + +将后端明细按订单分组: + +```js +const groups = {} +rows.forEach(row => { + if (!groups[row.订单编号]) groups[row.订单编号] = [] + groups[row.订单编号].push(row) +}) +``` + +每个工序状态: + +```js +function getStepStatus(step) { + if (step.任务状态 === 4 || step.完工时间) return 'done' + if (step.加工状态 === 2 || step.开工时间) return 'doing' + return 'waiting' +} +``` + +进度文案: + +```js +function getProgressText(steps) { + const doing = steps.find(x => getStepStatus(x) === 'doing') + if (doing) return `${doing.工序名称}中` + const lastDoneIndex = findLastDoneIndex(steps) + if (lastDoneIndex >= 0 && steps[lastDoneIndex + 1]) { + return `${steps[lastDoneIndex].工序名称}毕待${steps[lastDoneIndex + 1].工序名称}` + } + if (lastDoneIndex === steps.length - 1) return '已完成' + return '待开工' +} +``` + +## 10. 需求 7:外协任务检验 + +### 10.1 现有页面 + +相关页面: + +```text +src/views/QualityManagement/CheckTask/processReceive.vue +src/views/ProductionManagement/OutsourceMange/index.vue +src/views/ProductionManagement/OutsourceSheet/index.vue +``` + +现有视图: + +- `View_质量检验_质检记录_外协收检` +- `View_外协质检` +- `View_外协报表视图` + +### 10.2 需求字段 + +| 字段 | 来源 | +|---|---| +| 指派对象 | 任务表 `MES_接口_生产计划_生产任务.指派对象` | +| 供应商 | SAP 采购/外协单据,或外协任务维护 | +| SAP采购收货单号 | SAP 采购收货成功后返回 | + +### 10.3 建议新增字段 + +优先加在质检记录扩展表,避免直接改大表影响历史。 + +表名:`质量管理_外协收检_扩展` + +```sql +CREATE TABLE dbo.质量管理_外协收检_扩展 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + QT_AID bigint NOT NULL, + TaskAID bigint NULL, + 指派对象 nvarchar(50) NULL, + 供应商编码 nvarchar(100) NULL, + 供应商名称 nvarchar(200) NULL, + SAP采购收货单号 nvarchar(100) NULL, + SAP采购收货行号 nvarchar(50) NULL, + SAP同步状态 nvarchar(20) NULL, + SAP返回信息 nvarchar(max) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE(), + 最后维护时间 datetime NULL +); + +CREATE UNIQUE INDEX UX_质量管理_外协收检_扩展_QT +ON dbo.质量管理_外协收检_扩展(QT_AID); +``` + +如果客户明确要在质检主记录中查询导出,也可直接加字段到 `YL_质量检验_质检记录`: + +```sql +ALTER TABLE dbo.YL_质量检验_质检记录 ADD + 指派对象 nvarchar(50) NULL, + 供应商编码 nvarchar(100) NULL, + 供应商名称 nvarchar(200) NULL, + SAP采购收货单号 nvarchar(100) NULL; +``` + +推荐扩展表,查询视图再拼接。 + +### 10.4 页面改造 + +序检收检页面: + +- 收检表格增加:指派对象、供应商、SAP采购收货单号。 +- 收检详情弹窗增加只读展示。 +- 外协收检成功后,保存 SAP 返回的采购收货单号。 + +外协报表: + +- 增加供应商、SAP采购收货单号列。 +- 后续供应商合格率按供应商分组。 + +### 10.5 存储过程 + +新增或扩展: + +| 过程 | 说明 | +|---|---| +| `质量管理_外协收检_扩展保存` | 收检完成后保存供应商和 SAP 单号 | +| `质量管理_外协收检_查询` | 查询外协收检扩展字段 | +| `生产管理_外协任务报表_查询` | 扩展供应商、SAP采购收货单号、采购到货期说明 | + +## 11. 需求 8:异常管控 + +### 11.1 现有页面 + +异常页面: + +```text +src/views/ProductionManagement/AbnormalControl/index.vue +``` + +需要加入口的页面: + +- `ProductionManagement/MachiningCenter/index.vue` +- `ProductionManagement/AssemblyCenter/index.vue` +- `QualityManagement/QualityCenter/index.vue` +- `QualityManagement/CheckTask/processReceive.vue` +- 后续设计任务报工页面 +- 后续编程任务清单页面 + +### 11.2 页面交互 + +在任务操作区增加按钮: + +```text +[报异常] +``` + +点击前校验: + +- 必须选中任务。 +- 必须有 TaskAID 或生产订单。 +- 已关闭/已入库任务不允许新报异常,除非角色有权限。 + +异常弹窗字段: + +| 字段 | 控件 | +|---|---| +| 生产订单 | 只读 | +| TaskAID | 隐藏 | +| 工序名称 | 只读 | +| 指派对象 | 只读 | +| 异常类型 | 下拉 | +| 异常说明 | 多行文本 | +| 附件 | 上传 | +| 审批人 | 人员多选 | + +### 11.3 数据表 + +使用第 3.3 节建议表: + +- `生产管理_异常管控_任务异常` +- `生产管理_异常管控_审批人` + +### 11.4 存储过程 + +#### 11.4.1 异常提交 + +过程名:`生产管理_异常管控_任务异常提交` + +参数: + +- 来源模块 +- 生产订单 +- TaskAID +- 工序名称 +- 指派对象 +- 异常类型 +- 异常说明 +- 附件ID +- 审批人JSON +- 发起人 + +逻辑: + +1. 生成异常编号,例如 `YC202605280001`。 +2. 插入 `生产管理_异常管控_任务异常`。 +3. 解析审批人 JSON,插入 `生产管理_异常管控_审批人`。 +4. 返回异常编号。 + +#### 11.4.2 待办查询 + +过程名:`生产管理_异常管控_待办查询` + +参数: + +- `@审批人姓名` +- `@状态` + +逻辑: + +- 审批人被选中即可看到任务。 +- 任一审批人处理后,异常进入下一状态或关闭。 + +#### 11.4.3 异常处理 + +过程名:`生产管理_异常管控_任务异常处理` + +参数: + +- 异常AID +- 处理人 +- 处理意见 +- 处理结果 + +逻辑: + +1. 更新异常主表实际处理人、处理时间、状态。 +2. 当前审批人记录标记已处理。 +3. 同一异常其他审批人不再待办。 + +## 12. 需求 9:机加班次产量表 + +### 12.1 页面定位 + +新增页面: + +```text +src/views/ProductionManagement/MachiningShiftOutput/index.vue +``` + +菜单: + +```text +报表中心 -> 生产报表 -> 机加班次产量表 +``` + +### 12.2 页面布局 + +```text +查询区: +日期范围 班次 设备 操作人 生产订单 物料 +[查询] [重置] [导出] + +汇总卡: +总数量 总工时 设备数 班次数 + +分组表: +设备 -> 日期 -> 班次 -> 任务明细 +``` + +### 12.3 数据来源 + +| 数据 | 来源 | +|---|---| +| 报工数量 | `YL_加工中心_操作记录表.操作数值` | +| 工时 | `YL_加工中心_操作记录表.工时` | +| 设备 | `工位名称` 或任务 `指派对象` | +| 生产订单/物料 | `MES_接口_生产计划_生产任务` | +| 班次 | `班次表` + 时间匹配 | + +现有函数: + +```text +dbo.计算班次重叠秒数 +``` + +可用于跨天班次工时计算。 + +### 12.4 存储过程 + +过程名:`生产报表_机加班次产量表_查询` + +参数: + +- 开始日期 +- 结束日期 +- 班次 +- 设备 +- 操作人 +- 生产订单 +- 物料 + +返回: + +- 设备名称 +- 日期 +- 班次 +- 生产订单 +- 物料编码 +- 物料名称 +- 工序名称 +- 开始时间 +- 结束时间 +- 工时小时 +- 数量 +- 操作人 +- 设备日期班次小计数量 +- 设备日期班次小计工时 + +SQL 逻辑: + +1. 取 `操作类别='报工'` 且 `操作数值 > 0` 的记录。 +2. 按 `开始时间` 匹配班次。 +3. 关联任务表补订单、物料、工序。 +4. 按设备、日期、班次排序。 + +### 12.5 是否新增表 + +第一阶段不新增表。 + +如果班次规则不足,需要扩展 `班次表`: + +```sql +ALTER TABLE dbo.班次表 ADD + 是否跨天 bit NULL, + 是否启用 bit NULL, + 班次日期归属 nvarchar(20) NULL; -- 开始日/结束日 +``` + +## 13. 需求 10:发货通知列表 + +### 13.1 页面定位 + +新增页面: + +```text +src/views/ProductionManagement/ShippingNoticeList/index.vue +``` + +菜单: + +```text +报表中心 -> 交付报表 -> 发货通知列表 +``` + +### 13.2 数据来源 + +客户说明:SAP 已提供数据,大屏已显示。 + +需要先查新分析: + +1. 大屏当前发货通知读取哪个过程。 +2. `装配中心任务看板_发货状态查询` 是否已经包含发货通知字段。 +3. `MES_接口_生产计划` 中 `发货状态`、`要求发货日期` 是否够用。 +4. 是否有 SAP 发货通知同步落地表。 + +### 13.3 建议新增表 + +若当前没有发货通知落地表,建议建: + +```sql +CREATE TABLE dbo.系统集成_SAP发货通知 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 发货通知号 nvarchar(100) NOT NULL, + 合同号 nvarchar(50) NULL, + 客户编码 nvarchar(100) NULL, + 客户名称 nvarchar(200) NULL, + 生产订单 int NULL, + 物料编码 nvarchar(100) NULL, + 物料名称 nvarchar(500) NULL, + 数量 decimal(18,2) NULL, + 要求发货日期 datetime NULL, + 发货状态 nvarchar(50) NULL, + SAP同步时间 datetime NULL, + 原始JSON nvarchar(max) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_系统集成_SAP发货通知_合同号 ON dbo.系统集成_SAP发货通知(合同号); +CREATE INDEX IX_系统集成_SAP发货通知_生产订单 ON dbo.系统集成_SAP发货通知(生产订单); +``` + +如果已有大屏同步表,则不建新表,直接复用。 + +### 13.4 存储过程 + +过程名:`报表_发货通知列表_查询` + +参数: + +- 发货通知号 +- 合同号 +- 客户 +- 状态 +- 要求发货开始 +- 要求发货结束 + +返回: + +- 发货通知号 +- 合同号 +- 客户 +- 生产订单 +- 物料编码 +- 物料名称 +- 数量 +- 要求发货日期 +- 发货状态 +- SAP同步时间 + +## 14. 需求 11:质检任务早知道 + +### 14.1 依赖 + +强依赖: + +- `生产管理_装配已排产需求_查询` +- 装配完成时间字段可用 + +### 14.2 页面定位 + +新增页面: + +```text +src/views/QualityManagement/QualityTaskPreview/index.vue +``` + +菜单: + +```text +质量管理 -> 质量报表 -> 质检任务早知道 +``` + +### 14.3 查询规则 + +过滤: + +- 装配完成时间在查询范围内。 +- 排除已完成质检。 +- 排除订单关闭、取消、整单已入库。 +- 按装配完成时间分组。 + +### 14.4 存储过程 + +过程名:`质量管理_质检任务早知道_查询` + +参数: + +- 装配完成开始 +- 装配完成结束 +- 合同号 +- 生产订单 +- 物料 + +返回: + +- 预计质检日期 +- 生产订单 +- 合同号 +- 物料编码 +- 物料名称 +- 装配完成时间 +- 当前对应人员 +- 当前对应内容 +- 累计工时 +- 异常状态 +- 质检状态 + +SQL 逻辑: + +```sql +-- 基于装配已排产需求结果,再排除已检/关闭/取消/入库 +``` + +### 14.5 不新增表 + +本需求不新增表,只新增查询过程和页面。 + +## 15. 需求 12:生产工艺自动带出标准工艺 + +### 15.1 现有页面 + +相关页面: + +```text +src/views/ProcessManagement/ProcessProduct/index.vue +src/views/ProcessManagement/ProcessesDevelop/index.vue +``` + +### 15.2 页面交互 + +点击编辑生产工艺: + +1. 查询是否已有生产工艺。 +2. 如果有,正常打开。 +3. 如果没有,提示: + +```text +当前订单未找到生产工艺,是否按物料标准工艺带出草稿? +[带出标准工艺] [取消] +``` + +4. 带出后只在页面显示,不直接落库。 +5. 用户点击保存后,写入生产工艺。 + +### 15.3 存储过程 + +新增: + +| 过程 | 用途 | +|---|---| +| `工艺管理_生产工艺_是否存在` | 按订单号查询是否已有生产工艺 | +| `工艺管理_生产工艺_标准工艺草稿查询` | 按物料编码查标准工艺并映射成生产工艺字段 | + +保存仍复用现有生产工艺保存过程。 + +### 15.4 字段映射 + +需要查新分析: + +- 标准工艺表:`车间生产管理工艺_零件工序_工艺库` +- 生产工艺表:`车间生产管理工艺_零件生产工艺_工艺库` +- 两者字段差异。 + +至少映射: + +| 标准工艺 | 生产工艺 | +|---|---| +| 物料编号 | 物料编号 | +| 工序名称 | 工序名称 | +| 工艺顺序 | 工艺顺序 | +| 标准工时 | 标准工时 | +| 工序说明 | 工序说明 | +| 指派对象默认值 | 指派对象 | + +### 15.5 不建议新增表 + +该需求只改页面和过程,不新增表。 + +## 16. 需求 13:工时报表 + 备注类小改 + +### 16.1 工时报表新增指派对象 + +现有页面: + +```text +src/views/ProductionManagement/Timesheet/index.vue +``` + +现有过程: + +```text +工时统计_作业者工时_查询 +工时统计_作业者工时_查询_导出 +``` + +改造: + +- 查询区增加指派对象筛选。 +- 表格增加指派对象列。 +- 导出增加指派对象列。 + +SQL 来源: + +- `YL_加工中心_操作记录表.工位名称` +- 或关联任务表取 `MES_接口_生产计划_生产任务.指派对象` + +推荐使用任务表指派对象,工位名称作为实际操作工位,两者都可展示: + +| 字段 | 说明 | +|---|---| +| 指派对象 | 任务被派给谁 | +| 实际工位 | 操作记录发生在哪个工位 | + +### 16.2 机加领料备注 + +需求: + +- 生产领料(机加)增加备注字段。 + +需要先定位现有领料表。如果无独立表,可能通过 SAP 或操作记录保存。 + +建议: + +```sql +ALTER TABLE dbo.MES_接口_生产计划_生产任务 ADD 机加领料备注 nvarchar(500) NULL; +``` + +如领料已有专表,应加在领料单表。 + +过程: + +- `生产管理_机加领料_备注保存` +- `生产管理_机加领料_查询` 返回备注 + +### 16.3 机加退库备注、装配退库备注 + +建议如果退库已有业务表,在退库表增加: + +```sql +备注 nvarchar(500) NULL, +最后维护人 nvarchar(50) NULL, +最后维护时间 datetime NULL +``` + +如果没有退库表,先不要加到任务表,建议建退库单扩展表: + +```sql +CREATE TABLE dbo.生产管理_退库单_扩展 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 退库单号 nvarchar(100) NOT NULL, + 退库类型 nvarchar(20) NOT NULL, -- 机加/装配 + 生产订单 int NULL, + TaskAID bigint NULL, + 备注 nvarchar(500) NULL, + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL +); +``` + +### 16.4 外协任务报表采购到货期说明 + +现有页面: + +```text +src/views/ProductionManagement/OutsourceSheet/index.vue +src/views/ProductionManagement/OutsourceMange/index.vue +``` + +建议字段: + +```sql +ALTER TABLE dbo.MES_接口_生产计划_生产任务 ADD 采购到货期说明 nvarchar(500) NULL; +``` + +如果采购到货期说明来自 SAP,则不允许手工覆盖,改为扩展表: + +```sql +CREATE TABLE dbo.生产管理_外协任务_采购扩展 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + TaskAID bigint NOT NULL, + 采购到货期说明 nvarchar(500) NULL, + SAP采购订单号 nvarchar(100) NULL, + SAP采购收货单号 nvarchar(100) NULL, + 供应商编码 nvarchar(100) NULL, + 供应商名称 nvarchar(200) NULL, + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL +); +``` + +### 16.5 制定标准工艺保存提示 + +页面: + +```text +src/views/ProcessManagement/ProcessesDevelop/index.vue +``` + +改造: + +- 保存成功显示“标准工艺保存成功”。 +- 保存失败显示后端 message。 +- 如果字段缺失,提示具体字段。 + +不涉及数据库。 + +## 17. 需求 14:生产订单关闭批量更新 SAP 状态 + +### 17.1 现有页面 + +页面: + +```text +src/views/PlanManagement/PlannOrderClose/index.vue +``` + +### 17.2 页面改造 + +表格增加多选列: + +```html + +``` + +新增按钮: + +```text +[批量关闭 SAP 订单] +``` + +点击后: + +1. 校验已选择订单。 +2. 弹出二次确认: + +```text +即将批量关闭 N 个 SAP 生产订单。该操作会写入 SAP,可能部分成功部分失败,是否继续? +``` + +3. 调用批量关闭逻辑。 +4. 展示结果弹窗。 + +结果弹窗字段: + +- 生产订单 +- SAP 单据号 +- 执行结果 +- 失败原因 +- 是否可重试 + +### 17.3 后端建议 + +由于当前前端很多 SAP 操作是直接调用 SAP/B1 接口或通过现有工具实现,批量关闭建议封装为前端逐单执行 + MES 记录结果,或后端新增 API。若 `.ashx` 仅支持 SQL,不适合在 SQL 里直接调 SAP。 + +建议流程: + +```text +前端选中订单 + -> 查询订单 SAP DocEntry + -> 逐单 PATCH SAP ProductionOrders + -> 每单结果写入 系统集成_SAP调用日志 + -> 更新 MES 订单状态或 SAP关闭状态扩展字段 +``` + +### 17.4 建议新增字段 + +表:`MES_接口_生产计划` + +```sql +ALTER TABLE dbo.MES_接口_生产计划 ADD + SAP关闭状态 nvarchar(20) NULL, + SAP关闭时间 datetime NULL, + SAP关闭失败原因 nvarchar(1000) NULL, + SAP关闭操作人 nvarchar(50) NULL; +``` + +如果不想改主表,新增扩展表: + +```sql +CREATE TABLE dbo.生产管理_订单关闭_SAP状态 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 订单编号 int NOT NULL, + SAP单据号 nvarchar(100) NULL, + 关闭状态 nvarchar(20) NOT NULL, + 失败原因 nvarchar(1000) NULL, + 操作人 nvarchar(50) NULL, + 操作时间 datetime NOT NULL DEFAULT GETDATE(), + 是否可重试 bit NOT NULL DEFAULT 0 +); +``` + +### 17.5 存储过程 + +| 过程 | 用途 | +|---|---| +| `生产管理_订单关闭_SAP结果保存` | 保存每单关闭结果 | +| `生产管理_订单关闭_SAP结果查询` | 查询批量关闭结果 | +| `生产管理_订单关闭_可关闭校验` | 批量操作前校验订单是否可关 | + +## 18. 需求 15:及时检验报表 + +### 18.1 页面定位 + +新增页面: + +```text +src/views/QualityManagement/TimelyInspectionReport/index.vue +``` + +菜单: + +```text +质量管理 -> 质量报表 -> 及时检验报表 +``` + +### 18.2 查询口径 + +进入报表条件: + +1. `YL_加工中心_操作记录表` 中存在报工记录。 +2. `操作类别 = '报工'`。 +3. `操作数值 > 0`。 +4. `结束时间 < DATEADD(DAY, -2, GETDATE())`。 +5. 对应质检记录不存在,或检验数量不足。 + +### 18.3 页面字段 + +| 字段 | +|---| +| 生产订单 | +| TaskAID | +| 物料编码 | +| 物料名称 | +| 工序名称 | +| 指派对象 | +| 报工数量 | +| 已检数量 | +| 未检数量 | +| 报工结束时间 | +| 超期天数 | +| 操作人 | + +### 18.4 存储过程 + +过程名:`质量管理_及时检验报表_查询` + +参数: + +- 生产订单 +- 物料 +- 工序 +- 指派对象 +- 报工结束开始 +- 报工结束结束 +- 超期天数,默认 2 + +SQL 示例: + +```sql +CREATE PROCEDURE dbo.质量管理_及时检验报表_查询 + @生产订单 int = NULL, + @物料 nvarchar(100) = '', + @工序 nvarchar(100) = '', + @指派对象 nvarchar(100) = '', + @报工结束开始 date = NULL, + @报工结束结束 date = NULL, + @超期天数 int = 2 +AS +BEGIN + SET NOCOUNT ON; + + WITH rpt AS ( + SELECT + o.TaskAID, + SUM(ISNULL(o.操作数值,0)) AS 报工数量, + MAX(o.结束时间) AS 报工结束时间, + MAX(o.操作人) AS 操作人 + FROM dbo.YL_加工中心_操作记录表 o + WHERE o.操作类别 = N'报工' + AND ISNULL(o.操作数值,0) > 0 + AND o.结束时间 < DATEADD(DAY, -@超期天数, GETDATE()) + GROUP BY o.TaskAID + ), + qc AS ( + SELECT + TaskAID, + SUM(ISNULL(检验数量,0)) AS 已检数量 + FROM dbo.YL_质量检验_质检记录 + GROUP BY TaskAID + ) + SELECT + t.订单编号 AS 生产订单, + t.AID AS TaskAID, + t.物料编码, + t.物料名称, + t.工序名称, + t.指派对象, + rpt.报工数量, + ISNULL(qc.已检数量,0) AS 已检数量, + rpt.报工数量 - ISNULL(qc.已检数量,0) AS 未检数量, + rpt.报工结束时间, + DATEDIFF(DAY, rpt.报工结束时间, GETDATE()) AS 超期天数, + rpt.操作人 + FROM rpt + JOIN dbo.MES_接口_生产计划_生产任务 t ON rpt.TaskAID = t.AID + LEFT JOIN qc ON rpt.TaskAID = qc.TaskAID + WHERE rpt.报工数量 > ISNULL(qc.已检数量,0) + AND (@生产订单 IS NULL OR t.订单编号 = @生产订单) + AND (@物料 = '' OR t.物料编码 LIKE '%' + @物料 + '%' OR t.物料名称 LIKE '%' + @物料 + '%') + AND (@工序 = '' OR t.工序名称 = @工序) + AND (@指派对象 = '' OR t.指派对象 = @指派对象) + AND (@报工结束开始 IS NULL OR rpt.报工结束时间 >= @报工结束开始) + AND (@报工结束结束 IS NULL OR rpt.报工结束时间 < DATEADD(DAY, 1, @报工结束结束)) + ORDER BY 超期天数 DESC, rpt.报工结束时间; +END +``` + +### 18.5 不新增表 + +第一阶段不新增表。若要催办闭环,再新增催办记录表。 + +## 19. 需求 16:工序流转卡增加原料编码 + +### 19.1 需要查新分析 + +先定位工序流转卡打印页面和模板: + +- 搜索页面中 `流转卡`、`print`、`打印`。 +- 确认当前流转卡数据来源过程。 +- 确认原料编码来自 BOM、SAP 工艺路线,还是物料字段。 + +### 19.2 数据来源建议 + +优先顺序: + +1. `BOM数据` 中父件对应子件,取原料类子件编码。 +2. SAP BOM/物料清单同步表。 +3. 生产任务行文本备注或行物料字段。 + +### 19.3 存储过程 + +扩展流转卡查询过程,增加字段: + +| 字段 | 说明 | +|---|---| +| 原料编码 | BOM 子件编码 | +| 原料名称 | BOM 子件名称,可选 | +| 原料规格 | 可选 | + +SQL 示例: + +```sql +LEFT JOIN dbo.BOM数据 bom + ON bom.父件编码 = t.物料编码 +``` + +### 19.4 页面/打印 + +打印模板增加: + +```text +原料编码:XXXXXXXX +``` + +如果一个成品对应多个原料编码: + +- 用逗号合并。 +- 或打印明细区。 + +## 20. 需求 17-19:现场大屏 + +包括: + +- 一楼质检大屏幕 +- 机加现场大屏幕 +- 装配现场大屏幕 + +看板项目目录: + +| 大屏 | 项目目录 | +|---|---| +| 质检任务看板 | `质检任务看板` | +| 机加现场大屏 | `机加设备生产运营看板`、`机加设备生产运营看板二` | +| 装配现场大屏 | `装配任务看板` | + +### 20.1 通用大屏开发原则 + +1. 大屏只展示,不作为字段维护入口。 +2. 关键工序、缺勤、送检状态必须先有业务数据来源。 +3. 所有大屏过程必须支持 `@统计日期`,默认当天。 +4. 大屏刷新频率建议 30 秒以上,除设备状态外不建议 5 秒刷新复杂 SQL。 +5. 指标必须能下钻明细。 + +### 20.2 一楼质检大屏 + +#### 20.2.1 新增指标 + +| 指标 | 口径 | +|---|---| +| 质检及时率 | 及时检验任务数 / 应检任务数 | +| 超 2 天未检任务 | 最后生产完成时间超过 2 天且未检足 | +| 关键工序应检数 | 任务快照中 `是否关键工序=1` | +| 关键工序未检数 | 应检但未检足 | +| 关键工序已检数 | 已检足 | + +#### 20.2.2 需要新增字段 + +关键工序不要放在看板维护,应加在工艺和任务快照。 + +建议字段: + +```sql +ALTER TABLE dbo.车间生产管理工艺_零件工序_工艺库 ADD 是否关键工序 bit NULL DEFAULT 0; +ALTER TABLE dbo.车间生产管理工艺_零件生产工艺_工艺库 ADD 是否关键工序 bit NULL DEFAULT 0; +ALTER TABLE dbo.MES_接口_生产计划_生产任务 ADD 是否关键工序 bit NULL DEFAULT 0; +``` + +任务下发时把生产工艺中的 `是否关键工序` 快照到任务表。 + +#### 20.2.3 存储过程 + +扩展或新增: + +| 过程 | 用途 | +|---|---| +| `质量任务看板_未完成统计` | 增加超期天数、关键工序统计 | +| `质量任务看板_未完成明细查询` | 增加最后生产完成时间、是否关键工序 | +| `质量任务看板_及时率统计` | 新增及时率 | + +### 20.3 机加现场大屏 + +#### 20.3.1 新增指标 + +| 指标 | 口径 | +|---|---| +| 缺勤人员 | 应到人员 - 实到人员 | +| 关键工序任务汇总 | 已排产未完成且是否关键工序=1 | +| 关键工序任务明细 | 订单、物料、工序、设备、指派对象、计划开始、完成数 | + +#### 20.3.2 缺勤数据 + +不能从“没有报工”反推缺勤。 + +需要数据: + +| 数据 | 来源 | +|---|---| +| 应到人员 | 班次人员绑定表、排班表、岗位工位绑定 | +| 实到人员 | 考勤、上岗绑定、登录、报工记录 | + +建议新增排班表: + +```sql +CREATE TABLE dbo.人员排班表 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 排班日期 date NOT NULL, + 班次编号 int NULL, + 班次名称 nvarchar(50) NULL, + 人员编号 int NOT NULL, + 人员姓名 nvarchar(50) NOT NULL, + 岗位 nvarchar(50) NULL, + 工位号 nvarchar(50) NULL, + 是否应到 bit NOT NULL DEFAULT 1, + 创建人 nvarchar(50) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_人员排班表_日期班次 ON dbo.人员排班表(排班日期, 班次名称); +``` + +如果已有 `班次人员绑定表` 能满足,则不新建,只扩展字段。 + +#### 20.3.3 存储过程 + +| 过程 | 用途 | +|---|---| +| `机加现场大屏_缺勤人员查询` | 返回岗位、工位、姓名 | +| `机加现场大屏_关键工序统计` | 汇总关键工序任务 | +| `机加现场大屏_关键工序明细` | 明细下钻 | + +### 20.4 装配现场大屏 + +#### 20.4.1 新增指标 + +| 指标 | 口径 | +|---|---| +| 缺勤人员 | 同机加 | +| 及时送检任务 | 发料齐套后超过 2 天未送检 | +| 排序 | 加急优先,其次及时送检超期,再按计划开始或齐套时间 | + +#### 20.4.2 存储过程 + +| 过程 | 用途 | +|---|---| +| `装配现场大屏_缺勤人员查询` | 岗位、工位、姓名 | +| `装配现场大屏_及时送检任务查询` | 发料齐套后 2 天未送检 | +| `装配中心任务看板_装配任务查询` | 增加发料齐套时间、是否已送检、送检时间、超期天数 | + +#### 20.4.3 字段来源 + +| 字段 | 来源 | +|---|---| +| 发料齐套时间 | `MES_接口_生产计划.齐套时间` 或装配扩展表 | +| 是否已送检 | 送检记录/质检任务/质检记录 | +| 送检时间 | 送检记录 | +| 超期天数 | `DATEDIFF(DAY, 发料齐套时间, GETDATE())` | + +## 21. 需求 20:编程任务清单 / 编程报工 + +### 21.1 页面定位 + +新增页面: + +```text +src/views/ProductionManagement/ProgrammingTask/index.vue +``` + +菜单: + +```text +生产管理 -> 报工管理 -> 编程任务清单 +``` + +### 21.2 页面布局 + +```text +查询区: +设备 工位 程序员 状态 生产订单 物料 日期 +[查询] [重置] [新增编程任务] [导出] + +表格: +任务编号 生产订单 物料编码 物料名称 工序 设备/工位 程序号 +编程人员 状态 开始时间 结束时间 工时 操作 + +操作: +[开始编程] [结束编程] [编辑程序号] [工时记录] [报异常] +``` + +### 21.3 新增表 + +#### 21.3.1 编程任务表 + +```sql +CREATE TABLE dbo.生产管理_编程任务 ( + 编程任务ID bigint IDENTITY(1,1) PRIMARY KEY, + 编程任务编号 nvarchar(50) NOT NULL, + 生产订单 int NULL, + TaskAID bigint NULL, + 物料编码 nvarchar(100) NULL, + 物料名称 nvarchar(500) NULL, + 工序名称 nvarchar(100) NULL, + 设备编号 nvarchar(50) NULL, + 设备名称 nvarchar(100) NULL, + 工位编号 nvarchar(50) NULL, + 工位名称 nvarchar(100) NULL, + 程序号 nvarchar(100) NULL, + 任务来源 nvarchar(50) NULL, -- 人工创建/订单生成/设备任务派生 + 状态 nvarchar(20) NOT NULL DEFAULT N'未开始', + 任务说明 nvarchar(1000) NULL, + 创建人 nvarchar(50) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE(), + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL +); +``` + +#### 21.3.2 编程工时记录表 + +```sql +CREATE TABLE dbo.生产管理_编程任务_工时记录 ( + 记录ID bigint IDENTITY(1,1) PRIMARY KEY, + 编程任务ID bigint NOT NULL, + 操作类别 nvarchar(20) NOT NULL, -- 开始/结束 + 操作人编号 int NULL, + 操作人 nvarchar(50) NOT NULL, + 开始时间 datetime NULL, + 结束时间 datetime NULL, + 工时分钟 int NULL, + 工作内容 nvarchar(1000) NULL, + 结束说明 nvarchar(1000) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_生产管理_编程任务_工时记录_任务 +ON dbo.生产管理_编程任务_工时记录(编程任务ID); +``` + +### 21.4 存储过程 + +| 过程 | 用途 | +|---|---| +| `生产管理_编程任务_查询` | 列表查询 | +| `生产管理_编程任务_新增` | 新增任务 | +| `生产管理_编程任务_开始` | 开始编程 | +| `生产管理_编程任务_结束` | 结束编程并计算工时 | +| `生产管理_编程任务_工时明细` | 工时明细 | +| `生产管理_编程任务_程序号保存` | 维护程序号 | + +### 21.5 工时接入 + +`View_统一工时明细` 增加: + +```text +来源模块 = 编程 +工时类型 = 编程 +``` + +这样后续合同工时、工时报表可选择是否包含编程工时。 + +## 22. 需求 21-24:设备档案、设备数据采集、OEE、工时查询联动 + +### 22.1 设备档案管理 + +现有页面: + +```text +src/views/DeviceManagement/DeviceInformation/index.vue +``` + +现有表: + +```text +YL_设备管理_设备台账 +MES_资源主数据 +``` + +建议新增字段: + +```sql +ALTER TABLE dbo.YL_设备管理_设备台账 ADD + 是否主要设备 bit NULL DEFAULT 0, + 是否参与OEE bit NULL DEFAULT 0, + 设备标准工时 decimal(18,2) NULL, + 标准工时单位 nvarchar(20) NULL, + 采集设备编码 nvarchar(100) NULL, + 采集点位配置 nvarchar(max) NULL; +``` + +注意: + +- 设备标准工时不能替代工艺标准工时。 +- OEE 的标准单件工时优先来自工艺或设备+工序能力表。 + +建议新增设备工序能力表: + +```sql +CREATE TABLE dbo.设备管理_设备工序能力 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 设备编号 nvarchar(50) NOT NULL, + 设备名称 nvarchar(100) NULL, + 工序名称 nvarchar(100) NOT NULL, + 物料编码 nvarchar(100) NULL, + 标准单件工时 decimal(18,4) NULL, + 单位 nvarchar(20) NULL DEFAULT N'分钟', + 是否启用 bit NOT NULL DEFAULT 1, + 创建人 nvarchar(50) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE(), + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL +); +``` + +### 22.2 设备数据采集 + +现有表: + +- `CaChe_Var` +- `历史_设备数据_定时` +- `历史_工位设备状态每分钟记录` +- `YL_设备管理_工时记录` + +新增建议: + +#### 22.2.1 采集原始数据表 + +如果现有 `历史_设备数据_定时` 字段足够,可不新建。否则新增: + +```sql +CREATE TABLE dbo.设备采集_原始数据 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 采集时间 datetime NOT NULL, + 设备编号 nvarchar(50) NULL, + 设备名称 nvarchar(100) NULL, + 工位号 nvarchar(50) NULL, + 变量名称 nvarchar(100) NULL, + 变量值 nvarchar(200) NULL, + 原始值 nvarchar(200) NULL, + 单位 nvarchar(20) NULL, + TagID nvarchar(100) NULL, + DeviceCode nvarchar(100) NULL, + 在线状态 nvarchar(20) NULL, + 采集质量 nvarchar(20) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); +``` + +#### 22.2.2 设备状态汇总表 + +```sql +CREATE TABLE dbo.设备采集_设备状态分钟汇总 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 统计时间 datetime NOT NULL, + 统计日期 date NOT NULL, + 班次名称 nvarchar(50) NULL, + 设备编号 nvarchar(50) NULL, + 设备名称 nvarchar(100) NULL, + 工位号 nvarchar(50) NULL, + 状态代码 int NULL, + 状态名称 nvarchar(50) NULL, + 持续秒数 int NOT NULL DEFAULT 60, + 是否有效加工 bit NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); +``` + +#### 22.2.3 设备任务绑定表 + +设备采集必须绑定 MES 任务,否则无法算任务级程序工时。 + +```sql +CREATE TABLE dbo.设备采集_任务绑定 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 设备编号 nvarchar(50) NOT NULL, + 设备名称 nvarchar(100) NULL, + 工位号 nvarchar(50) NULL, + TaskAID bigint NOT NULL, + 生产订单 int NOT NULL, + 程序号 nvarchar(100) NULL, + 绑定开始时间 datetime NOT NULL, + 绑定结束时间 datetime NULL, + 绑定来源 nvarchar(50) NULL, -- 人工/条码/程序号/时间推断 + 绑定人 nvarchar(50) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); +``` + +### 22.3 OEE 指标 + +建议新增指标明细表: + +```sql +CREATE TABLE dbo.设备指标_班次明细 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 统计日期 date NOT NULL, + 班次名称 nvarchar(50) NULL, + 设备编号 nvarchar(50) NOT NULL, + 设备名称 nvarchar(100) NULL, + 工位号 nvarchar(50) NULL, + TaskAID bigint NULL, + 生产订单 int NULL, + 物料编码 nvarchar(100) NULL, + 物料名称 nvarchar(500) NULL, + 工序名称 nvarchar(100) NULL, + 计划产量 decimal(18,2) NULL, + 实际产量 decimal(18,2) NULL, + 良品数 decimal(18,2) NULL, + 不良品数 decimal(18,2) NULL, + 标准单件工时 decimal(18,4) NULL, + 实际单件工时 decimal(18,4) NULL, + 设备运行工时分钟 decimal(18,2) NULL, + 标准可用工时分钟 decimal(18,2) NULL, + 产能利用率 decimal(18,4) NULL, + 设备利用率 decimal(18,4) NULL, + 性能开动率 decimal(18,4) NULL, + 产品合格率 decimal(18,4) NULL, + OEE decimal(18,4) NULL, + 计算时间 datetime NOT NULL DEFAULT GETDATE(), + 计算说明 nvarchar(1000) NULL +); +``` + +计算过程: + +| 过程 | 用途 | +|---|---| +| `设备指标_班次明细_生成` | 按日期班次生成指标 | +| `设备指标_OEE_查询` | 页面/看板查询 | +| `设备指标_OEE_明细` | 下钻查看三项组成 | + +### 22.4 工时查询联动 + +现有页面: + +```text +src/views/ProductionManagement/Workhours/index.vue +src/views/ProductionManagement/Timesheet/index.vue +src/views/ProductionManagement/WorkHoursCheck/index.vue +``` + +新增字段: + +- 程序工时 +- 设备运行工时 +- 实际单件工时 +- 标准单件工时 +- 设备采集状态 +- 采集质量 + +建议过程: + +```text +工时查询_设备采集工时_查询 +``` + +按 TaskAID、设备、时间段关联 `设备采集_任务绑定` 和设备状态汇总。 + +## 23. 需求 25:手续确认报表 + +### 23.1 页面定位 + +新增页面: + +```text +src/views/ProductionManagement/FormalityConfirmReport/index.vue +``` + +菜单: + +```text +报表中心 -> 装配报表 -> 手续确认报表 +``` + +### 23.2 页面布局 + +```text +查询区: +生产订单 合同号 物料 指派对象 发料齐套日期 手续确认状态 +[查询] [重置] [导出] [批量确认完成] + +表格: +选择 生产订单 合同号 物料编码 物料名称 指派对象 发料齐套时间 +装配完成时间 当前状态 手续确认 确认人 确认时间 操作 + +操作: +[确认完成] [查看装配明细] [查看异常] +``` + +### 23.3 新增表 + +表名:`生产管理_手续确认` + +```sql +CREATE TABLE dbo.生产管理_手续确认 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 订单编号 int NOT NULL, + 确认状态 nvarchar(20) NOT NULL DEFAULT N'未完成', + 确认人 nvarchar(50) NULL, + 确认时间 datetime NULL, + 确认备注 nvarchar(500) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE(), + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL +); + +CREATE UNIQUE INDEX UX_生产管理_手续确认_订单编号 +ON dbo.生产管理_手续确认(订单编号); +``` + +### 23.4 消失条件 + +报表只显示待确认数据: + +```sql +WHERE ISNULL(fc.确认状态, N'未完成') <> N'已完成' + AND ISNULL(p.订单状态, '') NOT IN (N'取消', N'关闭') + AND ISNULL(p.单据状态, '') NOT IN (N'取消', N'关闭') + AND ISNULL(p.入库数量, 0) < ISNULL(p.计划数量, 0) +``` + +### 23.5 存储过程 + +| 过程 | 用途 | +|---|---| +| `生产管理_手续确认报表_查询` | 待确认列表 | +| `生产管理_手续确认报表_确认完成` | 单条确认 | +| `生产管理_手续确认报表_批量确认完成` | 批量确认 | + +确认过程同时写 `系统管理_业务字段维护日志`。 + +## 24. 需求 26:产品合格率(工位) + +### 24.1 页面定位 + +新增或扩展质量报表页面: + +```text +src/views/QualityManagement/StationPassRate/index.vue +``` + +### 24.2 口径 + +公式: + +```text +产品合格率 = 良品数 / 总产量 +``` + +需要先确认: + +- 总产量取报工完成数量还是质检检验数量。 +- 良品数取质检合格数还是报工合格数。 +- 统计维度按工位、设备、指派对象还是实际操作工位。 + +建议第一版: + +- 总产量:质检记录 `检验数量` +- 良品数:质检记录 `合格数` +- 工位:关联任务表 `指派对象`,同时展示质检记录来源工位。 + +### 24.3 存储过程 + +过程名:`质量管理_产品合格率_工位查询` + +参数: + +- 开始日期 +- 结束日期 +- 工位 +- 工序 +- 物料 + +返回: + +- 工位 +- 检验数量 +- 合格数量 +- 不合格数量 +- 合格率 +- 明细数 + +### 24.4 不新增表 + +第一阶段不新增表。如果要日快照,写入 `质量管理_工位合格率_日快照`。 + +## 25. 需求 27:让步接收记录 + +### 25.1 页面定位 + +新增页面: + +```text +src/views/QualityManagement/ConcessionRecord/index.vue +``` + +菜单: + +```text +质量管理 -> 质量报表 -> 让步接收记录 +``` + +### 25.2 数据来源 + +现有字段: + +- `MES_接口_生产计划_生产任务.让步放行数量` +- `YL_质量检验_不合格品处理.申请让步放行` +- `YL_质量检验_不合格品处理_处理节点.让步放行数量` + +需求说“新增让步记录查询页面”,建议从不合格品处理和质检记录综合查询。 + +### 25.3 存储过程 + +过程名:`质量管理_让步接收记录_查询` + +参数: + +- 生产订单 +- 物料 +- 检验人 +- 检验开始 +- 检验结束 +- 让步状态 + +返回: + +- 生产订单 +- TaskAID +- 物料编码 +- 物料名称 +- 工序名称 +- 检验数量 +- 不合格数量 +- 让步放行数量 +- 申请让步放行 +- 检验人 +- 检验时间 +- 处理意见 + +### 25.4 不新增表 + +页面只查询,不维护。 + +## 26. 需求 28:设计任务报工模块 / 报工-技术-MES + +### 26.1 页面定位 + +新增页面: + +```text +src/views/ProductionManagement/DesignTaskWork/index.vue +``` + +菜单: + +```text +生产管理 -> 报工管理 -> 设计任务报工 +``` + +### 26.2 页面布局 + +```text +查询区: +任务名称 设计人员 状态 日期 +[查询] [重置] [新增设计任务] [导出] + +表格: +任务编号 任务名称 设计人员 状态 计划开始 计划完成 +开始时间 结束时间 工时 工作内容 结束说明 创建人 操作 + +操作: +[开始报工] [结束报工] [工时记录] [编辑] [取消] +``` + +### 26.3 新增表 + +#### 26.3.1 设计任务表 + +```sql +CREATE TABLE dbo.生产管理_设计任务 ( + 设计任务ID bigint IDENTITY(1,1) PRIMARY KEY, + 设计任务编号 nvarchar(50) NOT NULL, + 任务名称 nvarchar(200) NOT NULL, + 设计人员编号 int NULL, + 设计人员 nvarchar(50) NULL, + 状态 nvarchar(20) NOT NULL DEFAULT N'未开始', + 计划开始时间 datetime NULL, + 计划完成时间 datetime NULL, + 任务说明 nvarchar(1000) NULL, + 创建人 nvarchar(50) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE(), + 最后维护人 nvarchar(50) NULL, + 最后维护时间 datetime NULL +); +``` + +#### 26.3.2 设计工时记录表 + +```sql +CREATE TABLE dbo.生产管理_设计任务_工时记录 ( + 记录ID bigint IDENTITY(1,1) PRIMARY KEY, + 设计任务ID bigint NOT NULL, + 操作人编号 int NULL, + 操作人 nvarchar(50) NOT NULL, + 开始时间 datetime NOT NULL, + 结束时间 datetime NULL, + 工时分钟 int NULL, + 工作内容 nvarchar(1000) NULL, + 结束说明 nvarchar(1000) NULL, + 创建时间 datetime NOT NULL DEFAULT GETDATE() +); +``` + +### 26.4 存储过程 + +| 过程 | 用途 | +|---|---| +| `生产管理_设计任务_查询` | 任务列表 | +| `生产管理_设计任务_新增` | 新建任务 | +| `生产管理_设计任务_编辑` | 编辑任务 | +| `生产管理_设计任务_取消` | 取消 | +| `生产管理_设计任务_开始` | 开始报工 | +| `生产管理_设计任务_结束` | 结束报工 | +| `生产管理_设计任务_工时明细` | 工时明细 | + +### 26.5 工时接入 + +`View_统一工时明细` 增加: + +```text +来源模块 = 设计 +工时类型 = 设计 +``` + +注意: + +- 设计任务当前不上传 SAP。 +- 设计任务不产生质量、装配、机加工时。 +- 后续装配已排产需求的合同工时汇总可选择纳入设计工时。 + +## 27. 需求 29:工时异常报表 + +### 27.1 页面定位 + +新增页面: + +```text +src/views/ProductionManagement/WorkTimeAbnormalReport/index.vue +``` + +### 27.2 异常口径 + +```text +实际单件工时 > 标准单件工时 +``` + +字段来源: + +| 字段 | 来源 | +|---|---| +| 实际单件工时 | 设备采集,或人工报工工时 / 完成数量 | +| 标准单件工时 | 生产工艺或设备工序能力表 | +| 设备/工位 | 任务指派对象、设备绑定 | +| 程序号 | 编程任务或设备采集 | + +### 27.3 建议新增表 + +如需要异常确认闭环: + +```sql +CREATE TABLE dbo.生产管理_工时异常确认 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 统计日期 date NULL, + TaskAID bigint NULL, + 生产订单 int NULL, + 设备编号 nvarchar(50) NULL, + 设备名称 nvarchar(100) NULL, + 标准单件工时 decimal(18,4) NULL, + 实际单件工时 decimal(18,4) NULL, + 超出时长 decimal(18,4) NULL, + 超出比例 decimal(18,4) NULL, + 异常原因 nvarchar(500) NULL, + 责任部门 nvarchar(100) NULL, + 处理说明 nvarchar(1000) NULL, + 确认状态 nvarchar(20) NOT NULL DEFAULT N'未确认', + 确认人 nvarchar(50) NULL, + 确认时间 datetime NULL +); +``` + +### 27.4 存储过程 + +| 过程 | 用途 | +|---|---| +| `生产管理_工时异常报表_查询` | 查询异常 | +| `生产管理_工时异常报表_明细` | 查看来源明细 | +| `生产管理_工时异常报表_确认` | 异常确认 | + +### 27.5 页面字段 + +- 设备/工位 +- 生产订单 +- 物料编码 +- 物料名称 +- 工序名称 +- 指派对象 +- 操作人 +- 程序号 +- 标准单件工时 +- 实际单件工时 +- 超出时长 +- 超出比例 +- 开始时间 +- 结束时间 +- 班次 +- 异常原因 +- 确认状态 + +## 28. 需求 30:正在加工状态 + +### 28.1 目标 + +“正在加工状态:机加正在进行中”。 + +### 28.2 数据来源 + +优先复用: + +- `MES_ProductCenter_DoingTask` +- `v_CurrentProductionStatus` +- `YL_加工中心_操作记录表` 中开始未结束记录 + +### 28.3 页面/看板展示 + +可以在以下页面增加状态: + +- 加工中心任务列表 +- 生产计划跟踪 +- 机加现场大屏 + +展示规则: + +| 条件 | 状态 | +|---|---| +| 有开始记录且未报工结束 | 正在加工 | +| 任务状态已完成 | 已完成 | +| 有暂停记录未恢复 | 暂停中 | +| 无开始记录 | 未开工 | + +### 28.4 存储过程 + +过程名:`生产管理_正在加工状态_查询` + +返回: + +- TaskAID +- 生产订单 +- 工序名称 +- 指派对象 +- 操作人 +- 开始时间 +- 当前持续分钟 +- 状态 + +## 29. 暂不排期项的技术前置 + +### 29.1 及时拣配(机加/装配) + +必须先确认: + +1. 条码代表物料、箱号、批次、生产订单还是拣配单。 +2. SAP 库存和 MES 拣配状态谁是主口径。 +3. 扫码后是否写回 `拣配状态`、`齐套`、`发料状态`。 +4. 机加和装配是否共用拣配表。 + +建议表: + +```sql +CREATE TABLE dbo.生产管理_条码拣配记录 ( + AID bigint IDENTITY(1,1) PRIMARY KEY, + 拣配类型 nvarchar(20) NOT NULL, -- 机加/装配 + 条码 nvarchar(200) NOT NULL, + 生产订单 int NULL, + TaskAID bigint NULL, + 物料编码 nvarchar(100) NULL, + 物料名称 nvarchar(500) NULL, + 批次号 nvarchar(100) NULL, + 数量 decimal(18,2) NULL, + 拣配状态 nvarchar(20) NULL, + SAP校验状态 nvarchar(20) NULL, + 异常说明 nvarchar(500) NULL, + 拣配人 nvarchar(50) NULL, + 拣配时间 datetime NOT NULL DEFAULT GETDATE() +); +``` + +### 29.2 标牌打印操作 + +需求未定,不建表不开发。需确认: + +- 打印对象:物料、订单、设备、工位、产品? +- 条码内容。 +- 模板样式。 +- 是否需要打印记录。 + +### 29.3 首检、巡检 + +现有质检中心已有首检、巡检相关逻辑。空需求暂不开发。若后续提出,应先确认是新增报表、页面优化还是流程改造。 + +## 30. 菜单和权限 + +所有新增页面都需要写入 `登录基础数据_二级菜单`,并按角色分配。 + +建议新增菜单: + +| 页面 | 菜单 | +|---|---| +| 装配已排产需求 | 生产管理/装配管理 | +| 生产日报-送检 | 报表中心/生产日报 | +| 及时齐套跟踪结果报表 | 报表中心/齐套报表 | +| 机加班次产量表 | 报表中心/生产报表 | +| 发货通知列表 | 报表中心/交付报表 | +| 质检任务早知道 | 质量管理/质量报表 | +| 及时检验报表 | 质量管理/质量报表 | +| 手续确认报表 | 报表中心/装配报表 | +| 让步接收记录 | 质量管理/质量报表 | +| 设计任务报工 | 生产管理/报工管理 | +| 编程任务清单 | 生产管理/报工管理 | +| 工时异常报表 | 报表中心/工时报表 | + +菜单字段要参考现有 `登录基础数据_二级菜单`: + +- `path` +- `componet` +- `name` +- `title` +- `icon` +- `账号代码` + +## 31. 开发实施顺序 + +### 31.1 第一阶段:高优先级低风险 + +1. 及时开工报表正选/反选。 +2. 机加已排产日期筛选。 +3. 机加已排产历史工时弹窗。 +4. 生产工艺自动带出标准工艺。 +5. 工时报表指派对象。 +6. 小字段:备注、提示、流转卡原料编码。 + +交付标准: + +- 页面可查询。 +- 数据字段正确。 +- 导出同步。 +- 不影响现有流程。 + +### 31.2 第二阶段:装配已排产专项 + +1. 建装配扩展表。 +2. 做主查询页面。 +3. 加系统/非系统筛选。 +4. 接派工时间、合同交货期、发料齐套时间。 +5. 做装配完成时间和人工维护。 +6. 做当前人员、当前内容、历史说明。 +7. 接工时汇总和明细。 +8. 接异常明细。 +9. 做日计划导出打印。 +10. 派生质检任务早知道。 + +交付标准: + +- 主表字段完整。 +- 人工维护有日志。 +- 工时可钻取。 +- 日计划可导出/打印。 + +### 31.3 第三阶段:质量和齐套报表 + +1. 及时检验报表。 +2. 生产日报-送检。 +3. 及时齐套跟踪结果报表。 +4. 让步接收记录。 +5. 外协任务检验字段补充。 +6. 产品合格率。 + +交付标准: + +- 每个报表有明确口径。 +- 可导出。 +- 可钻明细。 +- SAP 来源显示同步时间。 + +### 31.4 第四阶段:流程增强 + +1. 异常管控统一入口。 +2. 生产订单批量关闭 SAP。 +3. 手续确认报表。 +4. 编程任务报工。 +5. 设计任务报工。 + +交付标准: + +- 写操作有确认。 +- 批量结果逐条返回。 +- 异常审批人多选可见,一人处理。 +- 工时进入统一工时视图。 + +### 31.5 第五阶段:设备采集和大屏 + +1. 设备档案字段。 +2. 设备采集原始数据和任务绑定。 +3. OEE 指标明细。 +4. 工时异常报表。 +5. 质检、机加、装配现场大屏。 + +交付标准: + +- 设备采集有原始数据和汇总数据。 +- OEE 可下钻。 +- 大屏指标无占位数据。 +- 缺勤有排班/实到来源。 + +## 32. 测试清单 + +### 32.1 页面测试 + +每个页面至少测试: + +- 查询为空。 +- 单条件查询。 +- 多条件组合查询。 +- 日期边界。 +- 分页。 +- 导出。 +- 弹窗打开关闭。 +- 保存成功。 +- 保存失败。 +- 无权限访问。 + +### 32.2 数据测试 + +重点验证: + +- 工时汇总和明细一致。 +- 日期筛选包含当天 00:00:00 到 23:59:59。 +- 已关闭/已入库/已完成任务是否正确排除。 +- SAP 字段为空时页面不报错。 +- 多人员当前任务合并显示正确。 +- 班次跨天统计正确。 + +### 32.3 性能测试 + +重点过程: + +- 装配已排产需求主查询。 +- 及时齐套跟踪主表。 +- 机加班次产量表。 +- 及时检验报表。 +- 大屏过程。 + +要求: + +- 普通报表分页查询 3 秒内返回。 +- 大屏过程 2 秒内返回。 +- 导出可慢,但必须有 loading。 + +### 32.4 回归测试 + +必须回归: + +- 机加排产。 +- 装配排产。 +- 加工中心报工。 +- 装配中心报工。 +- 质检收检。 +- 外协收检。 +- 工时统计。 +- 生产计划跟踪。 +- 看板刷新。 + +## 33. 风险和处理 + +| 风险 | 处理 | +|---|---| +| SAP 字段未到 | 页面字段先预留,显示空;存储过程字段从扩展表读取 | +| 发料齐套时间口径不稳 | 标记来源字段:SAP/MES/人工 | +| 设计工时依赖设计任务模块 | 装配已排产先显示装配/质量,设计为 0,模块完成后接入 | +| 设备采集不稳定 | OEE 和工时异常先用人工工时降级口径,并标记数据来源 | +| 缺勤无排班来源 | 不做缺勤正式统计,只做排班来源确认或新增排班表 | +| 动态 SQL 注入风险 | 新增过程尽量参数化 | +| 历史数据为空 | 字段允许 NULL,页面显示 `--`,不强行补假数据 | + +## 34. 交付物 + +每个需求完成时至少交付: + +1. 前端页面或页面改造。 +2. SQL 增量脚本。 +3. 新增/修改存储过程。 +4. 菜单和权限配置说明。 +5. 测试数据和测试结果。 +6. 字段口径说明。 +7. 如涉及 SAP,提供 SAP 调用日志或同步状态。 + diff --git a/analyze_mes_v20_views.js b/analyze_mes_v20_views.js new file mode 100644 index 0000000..d189402 --- /dev/null +++ b/analyze_mes_v20_views.js @@ -0,0 +1,731 @@ +const fs = require('fs'); +const path = require('path'); + +const root = path.resolve('MES_Manage_View_V20'); +const viewsRoot = path.join(root, 'src', 'views'); +const outFile = path.join(root, 'MES_Manage_View_V20_src_views_逐页面详细分析.md'); + +function existingSqlFiles() { + return fs.readdirSync(root) + .filter(x => x.toLowerCase().endsWith('.sql')) + .map(x => path.join(root, x)); +} + +function readText(file) { + const buf = fs.readFileSync(file); + if (buf.length >= 2 && buf[0] === 0xff && buf[1] === 0xfe) return buf.slice(2).toString('utf16le'); + if (buf.length >= 2 && buf[0] === 0xfe && buf[1] === 0xff) { + const swapped = Buffer.alloc(buf.length - 2); + for (let i = 2; i + 1 < buf.length; i += 2) { + swapped[i - 2] = buf[i + 1]; + swapped[i - 1] = buf[i]; + } + return swapped.toString('utf16le'); + } + if (buf.length >= 3 && buf[0] === 0xef && buf[1] === 0xbb && buf[2] === 0xbf) return buf.slice(3).toString('utf8'); + return buf.toString('utf8'); +} + +function walk(dir, exts, result = []) { + if (!fs.existsSync(dir)) return result; + for (const item of fs.readdirSync(dir, { withFileTypes: true })) { + const p = path.join(dir, item.name); + if (item.isDirectory()) walk(p, exts, result); + else if (exts.includes(path.extname(item.name).toLowerCase())) result.push(p); + } + return result; +} + +function rel(file) { + return path.relative(root, file).replace(/\\/g, '/'); +} + +function lineOf(text, index) { + return text.slice(0, index).split(/\r?\n/).length; +} + +function uniq(arr) { + return [...new Set((arr || []).filter(Boolean))]; +} + +function clean(s) { + return (s || '') + .replace(/<[^>]*>/g, '') + .replace(/\{\{.*?\}\}/g, '') + .replace(/\s+/g, ' ') + .trim(); +} + +function escapeReg(s) { + return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +function isInComment(text, index) { + const lineStart = text.lastIndexOf('\n', index) + 1; + const beforeOnLine = text.slice(lineStart, index); + if (/^\s*\/\//.test(beforeOnLine)) return true; + const blockStart = text.lastIndexOf('/*', index); + const blockEnd = text.lastIndexOf('*/', index); + return blockStart > blockEnd; +} + +function moduleNameFromPath(relPath) { + const parts = relPath.split('/'); + if (parts[0] !== 'src' || parts[1] !== 'views') return '其他'; + if (parts.length <= 3) return parts[2] || '根页面'; + return `${parts[2]} / ${parts.slice(3, -1).join(' / ') || path.basename(relPath)}`; +} + +function extractLabels(text) { + const labels = []; + const patterns = [ + /]*>([\s\S]*?)<\/el-button>/g, + /\blabel="([^"]+)"/g, + /\bplaceholder="([^"]+)"/g, + /\btitle="([^"]+)"/g + ]; + for (const re of patterns) { + let m; + while ((m = re.exec(text))) { + const value = clean(m[1]); + if (value && !/[{};]/.test(value) && value.length <= 48) labels.push(value); + } + } + return uniq(labels).slice(0, 30); +} + +function extractFrontendFields(text) { + const vModels = []; + const tableColumns = []; + const pushedParams = []; + + let m; + const vmRe = /\bv-model(?:\.[\w-]+)?="([^"]+)"/g; + while ((m = vmRe.exec(text))) vModels.push(clean(m[1])); + + const colRe = /]*)>/g; + while ((m = colRe.exec(text))) { + const attrs = m[1]; + const label = /label="([^"]+)"/.exec(attrs)?.[1] || ''; + const prop = /prop="([^"]+)"/.exec(attrs)?.[1] || ''; + if (label || prop) tableColumns.push({ label: clean(label), prop: clean(prop) }); + } + + const paramRe = /\.(?:push|unshift)\s*\(\s*\[\s*['"]([^'"]+)['"]\s*,\s*([^\]\n]+)\]/g; + while ((m = paramRe.exec(text))) pushedParams.push({ name: clean(m[1]), expr: clean(m[2]) }); + + return { + vModels: uniq(vModels).slice(0, 80), + tableColumns: uniq(tableColumns.map(x => `${x.label}|${x.prop}`)) + .map(x => { + const [label, prop] = x.split('|'); + return { label, prop }; + }) + .slice(0, 120), + pushedParams: uniq(pushedParams.map(x => `${x.name}|${x.expr}`)) + .map(x => { + const [name, expr] = x.split('|'); + return { name, expr }; + }) + .slice(0, 120) + }; +} + +function extractMethods(text) { + const methods = []; + const methodBlock = /methods\s*:\s*\{([\s\S]*?)\n\s*\}/m.exec(text); + const src = methodBlock ? methodBlock[1] : text; + const re = /^\s*([A-Za-z_$\u4e00-\u9fa5][\w$\u4e00-\u9fa5]*)\s*\([^)]*\)\s*\{/gm; + let m; + while ((m = re.exec(src))) methods.push(m[1]); + return uniq(methods).slice(0, 30); +} + +function extractCreateData(text) { + const calls = []; + const re = /CreateData\s*\(\s*['"]([^'"]+)['"]\s*,\s*['"]([^'"]+)['"]/g; + let m; + while ((m = re.exec(text))) { + if (isInComment(text, m.index)) continue; + calls.push({ type: m[1], name: m[2], line: lineOf(text, m.index) }); + } + return calls; +} + +function extractSapCalls(text) { + const calls = []; + const re = /(getB1|postB1|patchB1|posttm)\s*\(\s*([`'"])([\s\S]*?)\2/g; + let m; + while ((m = re.exec(text))) { + if (isInComment(text, m.index)) continue; + const snippet = text.slice(m.index, m.index + 1200); + const keys = []; + const keyRe = /["']?([\u4e00-\u9fa5A-Za-z_][\u4e00-\u9fa5A-Za-z0-9_$]*)["']?\s*:/g; + let km; + while ((km = keyRe.exec(snippet)) && keys.length < 24) { + if (!['if', 'for', 'while', 'switch', 'catch', 'function'].includes(km[1])) keys.push(km[1]); + } + calls.push({ fn: m[1], url: clean(m[3]), line: lineOf(text, m.index), payloadKeys: uniq(keys) }); + } + return calls; +} + +function extractApiImports(text) { + const imports = []; + const re = /from\s+['"](@\/api\/[^'"]+)['"]/g; + let m; + while ((m = re.exec(text))) imports.push(m[1]); + return uniq(imports); +} + +function stripSqlComments(sql) { + return sql.replace(/\/\*[\s\S]*?\*\//g, ' ').replace(/--.*$/gm, ' '); +} + +function compactSqlLine(s) { + return clean(s) + .replace(/\s*,\s*/g, ', ') + .replace(/\s*=\s*/g, ' = ') + .replace(/\s+/g, ' ') + .slice(0, 240); +} + +function extractSqlLines(body, regex, limit) { + return uniq(stripSqlComments(body) + .split(/\r?\n/) + .map(x => x.trim()) + .filter(x => regex.test(x)) + .map(compactSqlLine)) + .slice(0, limit); +} + +function extractSelectColumns(body, limit = 10) { + const noComments = stripSqlComments(body); + const m = /\bSELECT\b([\s\S]{0,2500}?)\bFROM\b/i.exec(noComments); + if (!m) return []; + return uniq(m[1].split(/\r?\n/) + .map(x => compactSqlLine(x.replace(/^\s*,/, ''))) + .filter(x => x && !/^(TOP|DISTINCT)$/i.test(x))) + .slice(0, limit); +} + +function objectRegex(name) { + return new RegExp(`(?:\\[dbo\\]\\.\\[${escapeReg(name)}\\]|dbo\\.\\[${escapeReg(name)}\\]|\\[${escapeReg(name)}\\]|\\b${escapeReg(name)}\\b)`, 'i'); +} + +function extractParams(body) { + const header = body.split(/\bAS\b/i)[0] || body.slice(0, 1000); + const params = []; + const re = /@([\u4e00-\u9fa5A-Za-z0-9_]+)\s+([A-Za-z0-9_\[\]\(\),]+)/g; + let m; + while ((m = re.exec(header))) params.push(`@${m[1]} ${m[2]}`); + return uniq(params).slice(0, 24); +} + +function summarizeProc(name, body) { + const verbs = []; + if (/\bSELECT\b/i.test(body)) verbs.push('查询'); + if (/\bINSERT\s+INTO\b/i.test(body)) verbs.push('新增'); + if (/\bUPDATE\b/i.test(body)) verbs.push('更新'); + if (/\bDELETE\s+FROM\b/i.test(body)) verbs.push('删除'); + if (/\bOPENJSON\b|JSON_VALUE|JSON_QUERY/i.test(body)) verbs.push('解析 JSON 批量数据'); + if (/ROW_NUMBER|OFFSET|@PageSize|@PageCurrent/i.test(body)) verbs.push('分页'); + if (/SAP\.SBO_YL/i.test(body)) verbs.push('读取 SAP B1 数据库对象'); + if (/报工|工时/.test(name + body)) verbs.push('处理报工/工时'); + if (/质检|检验|不合格/.test(name + body)) verbs.push('处理质检数据'); + if (/排产|派工|计划/.test(name + body)) verbs.push('处理计划/派工'); + if (/外协/.test(name + body)) verbs.push('处理外协业务'); + return uniq(verbs).join('、') || '执行数据库业务逻辑'; +} + +function extractSqlModel() { + const sql = existingSqlFiles().map(f => `\n-- FILE: ${path.basename(f)}\n${readText(f)}`).join('\n'); + const objects = []; + const objectRe = /CREATE\s+(TABLE|VIEW)\s+(?:\[dbo\]\.)?\[([^\]]+)\]/gi; + let m; + while ((m = objectRe.exec(sql))) objects.push({ type: m[1].toUpperCase(), name: m[2] }); + + const markers = []; + const procRe = /(?:CREATE|ALTER)\s+(?:\s*PROCEDURE|\s*PROC)\s+(?:\[dbo\]\.)?\[([^\]]+)\]/gi; + while ((m = procRe.exec(sql))) markers.push({ index: m.index, name: m[1] }); + + const procByName = {}; + for (let i = 0; i < markers.length; i++) { + const start = markers[i].index; + const nextGo = sql.slice(start).search(/\r?\nGO\r?\n/i); + const nextProc = i + 1 < markers.length ? markers[i + 1].index : sql.length; + const end = nextGo >= 0 ? Math.min(start + nextGo, nextProc) : nextProc; + const body = sql.slice(start, end); + const deps = []; + for (const obj of objects) { + if (objectRegex(obj.name).test(body)) deps.push(`${obj.type}:${obj.name}`); + } + const sapRefs = uniq(body.match(/SAP\.SBO_YL\.dbo\.[A-Za-z0-9_]+/g) || []); + for (const s of sapRefs) deps.push(`SAP:${s}`); + const writes = []; + for (const obj of objects) { + const n = escapeReg(obj.name); + const hit = new RegExp(`\\b(INSERT\\s+INTO|UPDATE|DELETE\\s+FROM|MERGE\\s+INTO)\\s+(?:\\[dbo\\]\\.\\[${n}\\]|dbo\\.\\[${n}\\]|\\[${n}\\]|${n})`, 'i').test(body); + if (hit) writes.push(obj.name); + } + const noComments = stripSqlComments(body); + procByName[markers[i].name] = { + name: markers[i].name, + body, + params: extractParams(body), + deps: uniq(deps), + writes: uniq(writes), + sapRefs, + summary: summarizeProc(markers[i].name, body), + features: { + selectColumns: extractSelectColumns(body), + filters: extractSqlLines(body, /\b(WHERE|AND|OR)\b/i, 10), + updates: extractSqlLines(body, /\b(UPDATE|SET|INSERT\s+INTO|DELETE\s+FROM|MERGE\s+INTO)\b/i, 12), + statusLines: extractSqlLines(body, /状态|排产|派工|加工|任务|质检|关闭|完成|已报工|DocEntry|SAP/i, 18), + grouping: extractSqlLines(body, /\b(GROUP\s+BY|HAVING|ORDER\s+BY|ROW_NUMBER|OFFSET|FETCH\s+NEXT)\b/i, 8), + tempTables: uniq(noComments.match(/#[\u4e00-\u9fa5A-Za-z0-9_]+/g) || []).slice(0, 10), + hasJson: /\bOPENJSON\b|JSON_VALUE|JSON_QUERY/i.test(noComments), + hasTransaction: /\bBEGIN\s+TRAN|COMMIT\s+TRAN|ROLLBACK\s+TRAN/i.test(noComments), + hasTryCatch: /\bTRY\b|\bCATCH\b/i.test(noComments), + hasPagination: /@PageCurrent|@PageSize|ROW_NUMBER|OFFSET\s+.*FETCH/i.test(noComments), + hasSap: /SAP\.SBO_YL/i.test(noComments) + } + }; + } + return { objects, procByName }; +} + +function operationByType(type) { + return { + '1': '旧版查询', + '2': '旧版增删改', + '7': '旧版批量/JSON', + '11': '当前通用存储过程查询/执行', + '12': '当前通用存储过程写入/业务动作', + '2001': '导出/报表类过程' + }[type] || `自定义类型 ${type}`; +} + +function procPurpose(name) { + const rules = [ + [/查询|Get|Load|Query|Search|读取|查看/, '查询/读取数据'], + [/新增|增加|Add|Insert/, '新增业务数据'], + [/修改|编辑|Edit|Update|更新|保存|Save/, '更新/保存业务数据'], + [/删除|Delete/, '删除业务数据'], + [/Finish|确认|关闭|Close/, '确认/关闭/完成业务动作'], + [/派工|Planned|排产|计划/, '计划排产或派工'], + [/报工|工时|WorkTime|ProdReport/, '报工或工时处理'], + [/质检|检验|Check|Quality/, '质量检验处理'], + [/外协/, '外协业务处理'], + [/登录|人员|角色|菜单|权限/, '基础权限/人员数据处理'], + [/设备|工位|资源|Station|Resource/, '设备/工位/资源数据处理'] + ]; + for (const [re, purpose] of rules) if (re.test(name)) return purpose; + return '业务存储过程调用'; +} + +function businessDomainFromName(name) { + const rules = [ + [/登录|人员|角色|菜单|权限|部门|工位管理/, '系统基础资料/权限'], + [/设备|报警|CaChe|StationStatus|工位设备/, '设备与实时数据'], + [/排产|派工|OrderPlanned|计划/, '计划排产'], + [/ProductCenter|ProductTask|加工中心|装配中心|报工|收料|开工|退库|发料|工时/, '生产执行/工时'], + [/外协/, '外协协同'], + [/图纸|工艺|Process|Drawing|Procedure|产品结构|标准/, '工艺与图纸'], + [/质检|检验|质量|不合格|Check/, '质量检验'], + [/销售/, '销售/订单状态'], + [/班次/, '班次与人员排班'], + [/加急/, '加急任务'] + ]; + for (const [re, domain] of rules) if (re.test(name)) return domain; + return '通用业务'; +} + +function pageBusinessNarrative(page) { + const p = page.relPath; + const labels = page.labels.slice(0, 10); + const procNames = uniq(page.procs.map(x => x.name)).slice(0, 6); + const common = []; + if (labels.length) common.push(`页面可见的操作/字段包括 ${labels.map(x => `“${x}”`).join('、')},这些是判断页面业务范围的主要线索。`); + if (procNames.length) common.push(`后端主要围绕 ${procNames.map(x => `\`${x}\``).join('、')}${page.procs.length > 6 ? ' 等过程' : ''} 取数或提交业务动作。`); + const rules = [ + [/PunctualWork/, '该页面用于发现“计划应开工但现场未及时开工”的任务。用户按任务状态、工位、工序、异常原因等条件筛选,页面展示生产订单、销售订单、物料、工序、指派对象、分配数量、上序合格数、加工/收料状态和加急数量,服务于生产异常提醒和催办。'], + [/CraftMaintain/, '该页面维护产品结构树。用户可以新增、编辑、删除产品结构节点,查询现有产品结构,并为后续工艺、物料、BOM 或生产任务提供层级基础数据。'], + [/DeviceDataHistory/, '该页面查询设备历史采集数据。用户按工位/设备、参数名称、起止时间分页查询历史记录,用于追溯设备运行参数。'], + [/DeviceInformation/, '该页面维护设备台账和设备相关基础资料。用户可以查询设备信息,新增、修改、删除设备,维护维修记录、工时记录或点检配置。'], + [/DeviceRealData/, '该页面展示设备实时或近实时数据。用户按工位和数据类型查询当前采集值、统计值或状态,通常用于设备运行监控。'], + [/Devicedata/, '该页面面向设备采集数据管理,查询缓存变量和设备数据,支持按设备、参数、时间等维度查看实时或历史采集结果。'], + [/InstallMakePlanDo|InstallMakePlan/, '该页面处理装配件排产。用户查询待排产/已排产装配任务,选择工位和人员,修改计划开工/完成时间、优先级、说明,执行单条派工、二次派工、批量确认排产,并在确认时同步 SAP 生产订单状态或创建相关请求。'], + [/SelfMakePlandone|SelfMakePlando|SelfMakePlan/, '该页面处理自制件/机加件排产。用户查询生产订单工序任务,筛选订单、合同、物料、工序、计划时间、排产状态和指派对象,完成工位派工、人员二次派工、外协分组、计划说明维护和排产确认。'], + [/PlannOrderClose/, '该页面用于生产订单关闭。用户筛选 SAP 未关闭或 MES 待确认订单,执行 SAP 生产订单关闭,并调用 MES 过程记录或确认订单关闭状态。'], + [/PlanShell/, '该页面是计划外壳/计划跟踪类页面,按缺料、发货通知、完成状态等条件查询计划或装配相关任务,用于计划人员集中查看订单齐套、发货和关闭情况。'], + [/priorityinstall/, '该页面用于装配优先级调整。用户查询装配计划任务,修改计划开工/完成时间、派工对象或优先级,用于插单和重点订单排序。'], + [/PartDrawing/, '该页面维护零件图纸。用户按物料查询图纸、查看文件、验证名称、删除图纸并保留删除记录。'], + [/PartDrawlook/, '该页面偏只读查看零件图纸,通常给生产或质检人员按物料快速打开图纸。'], + [/ProcurementDrawlook/, '该页面提供采购场景的图纸查看。用户按采购物料查询图纸,查看或删除图纸记录,支持采购、外协、来料检验时查阅技术文件。'], + [/ProcessDrawing/, '该页面维护工艺图纸。用户按物料/工艺条件查询工艺图,验证名称,查看或删除工艺图纸。'], + [/ProcedureManagement/, '该页面维护工序/路线阶段主数据。新增或修改工序时会同步 SAP B1 的 RouteStages,保证 MES 工序与 SAP 工艺阶段一致。'], + [/ProcessesDevelop/, '该页面用于工艺开发和生产工艺路线维护。用户围绕物料、工序、顺序、工艺参数、图纸等信息维护标准或生产用工艺路线。'], + [/ProcessInquiry/, '该页面用于工艺路线查询。用户按物料、产品、工序等条件查看标准工艺或生产工艺,服务于排产、生产和质检核对。'], + [/ProcessProduct/, '该页面维护产品与工艺/图纸的关系,使产品、物料、工序、图纸等基础数据形成可查询的工艺资料。'], + [/ProductionOrder/, '该页面处理生产订单资料。用户查询 ERP/MES 生产订单,并通过过程把 SAP 生产订单同步成 MES 生产计划和工序任务。'], + [/MachiningCenter/, '该页面是机加生产执行主界面。操作员按工位查看可执行任务和进行中任务,完成收料、开始加工、暂停/恢复、报工、辅助工序、首检/巡检/序检、生产发料查询、退库、图纸查看等动作,并写入加工中心操作记录和报工记录。'], + [/AssemblyCenter/, '该页面是装配生产执行主界面。装配人员按工位查询装配任务,处理开工、结束/报工、送检、缺料查询、收检记录、图纸查看和退库等动作,并会读取 SAP 生产订单信息辅助判断。'], + [/AssembleTaskManage/, '该页面管理装配任务。用户查询装配生产任务、查看工时汇总,进行派工、任务说明维护和外协/生产通知。'], + [/ProductionTaskManage/, '该页面管理生产任务。用户按工位、订单、工序查询任务,查看工时汇总,执行派工、修改计划字段、维护任务说明和通知状态。'], + [/ProductionTasksSum/, '该页面做生产任务汇总。用户按订单、工序、工位、时间等维度查询生产任务和工时汇总,并可编辑计划说明或派工信息。'], + [/ProductionPlanTrack/, '该页面跟踪生产计划执行。用户查看计划任务的开工、完工、进度、延期或异常情况,用于计划员追踪订单。'], + [/AssemblePlanTrack/, '该页面跟踪装配计划执行,展示装配任务进度、计划完成情况和异常。'], + [/AssembleTasksSum/, '该页面汇总装配任务,按订单、工位、人员或状态统计装配执行情况。'], + [/AssembleStatus/, '该页面查看装配现场状态,重点展示进行中任务和当前工位状态。'], + [/DeviceStatus/, '该页面查看设备/工位生产状态,通常用于判断设备是否在加工、待机、报警或空闲。'], + [/OutsourceMange/, '该页面管理外协任务。用户查询可外协工序,按供应商/订单/工序分组,执行外协派工并同步 SAP 采购请求或相关单据,维护外协发料、收料、质检记录、打印次数和备注。'], + [/SaleOutsourceMange/, '该页面管理销售相关外协任务。业务与外协管理类似,但面向销售订单或销售外协场景,包含派工同步 SAP、外协发料、历史记录和质检记录查询。'], + [/OutsourceSheet/, '该页面输出外协报表。用户按订单、合同、产品、计划号、供应商、状态分页查询外协报表,也可导出,用于外协进度、发料、收料、质检、开票等跟踪。'], + [/PickingTask/, '该页面处理拣配任务。用户查询生产订单相关拣配/领料任务,并可能联动 SAP 生产订单或库存出入库状态。'], + [/PersonnelBinding/, '该页面维护工位与人员绑定关系。用于限制或提示哪些人员可在指定工位报工、开工或执行任务。'], + [/ShiftManagement/, '该页面维护班次和班次人员绑定。用户新增、修改、删除班次,给班次绑定人员,为工时计算和报工归属提供基础数据。'], + [/Timesheet/, '该页面统计工时。用户按项目、作业者、设备、任务等维度查询工时数据,并可导出报表。'], + [/WorkHoursCheck/, '该页面用于工时校验。质检/管理人员查询待校验报工记录,系统计算标准/实际工时,保存单条或批量校验结果;通过校验后可把工序资源或工时/出库类单据上传到 SAP。'], + [/WorkhoursEdit/, '该页面用于编辑已产生的工时/报工记录,修正异常工时或补录说明。'], + [/Workhours/, '该页面用于工时查询,按工序、人员、设备、时间等条件查看工序工时。'], + [/Urgent/, '该页面维护加急任务。用户查询加急订单明细,并更新完成、转至等字段,用于生产/质检优先级管理。'], + [/AbnormalControl/, '该页面管理生产异常。用户查询异常记录,推进异常处理、关闭或记录处理结果。'], + [/login/, '该页面是登录入口,负责账号密码登录、角色选择、Token/Cookie 写入、路由权限初始化和密码修改入口。'], + [/dashboard/, '该页面是系统首页或欢迎页,用于承载看板入口或基础统计展示。'], + [/404/, '该页面是 404 错误页,用于路由不存在时展示错误信息。'], + [/purchaseIncoming/, '该页面处理采购/来料检验。质检人员查询待检任务,查看图纸、字典和检验人员,录入合格数、不合格数、检测数据,调用过程更新来料检验结果。'], + [/processReceive/, '该页面处理序检收检。质检人员接收工序检验任务,查询加急和字典信息,读取 SAP 工序状态,新增序检收检记录。'], + [/processSpecial/, '该页面处理过程/特殊检验。用户按工序任务录入特殊检验结果和检测明细。'], + [/firstSpecial/, '该页面处理首检/特殊首件检验。用户按工序和工位选择任务,录入首检数据。'], + [/final/, '该页面处理终检任务。质检人员查询终检任务,录入终检结果,并预留 SAP 生产订单状态回写。'], + [/materialReturn/, '该页面处理原材料退库检验。用户查询退库检验任务,读取 SAP 生产订单辅助信息,录入并更新检验结果。'], + [/salesReturn/, '该页面处理销售退货检验。用户查询销售退货待检任务,录入检验结果并更新质检记录。'], + [/OtherInbound/, '该页面处理其他入库检验。用户查询其他入库待检任务,录入检验结果并更新质检记录。'], + [/QualityCenter/, '该页面是质量综合处理中心。用户集中查询质检任务、收检记录、终检/入库任务和质检明细,录入检测数据、不合格处理,并读取 SAP 生产订单信息辅助校验。'], + [/QualityDetails/, '该页面查询质检明细。用户按订单、物料、检验类型、时间等条件查询和导出检测明细。'], + [/QualityStandardQuery/, '该页面维护/查询检验标准。用户按物料、工序、检测项目维护理论值、上下限、量具和启用状态。'], + [/Unqualified/, '该页面处理不合格品。用户查询不合格记录,查看处置流程和节点,推进让步放行、返工、报废等处理。'], + [/saleorderstatus/, '该页面查询销售订单状态。用户按销售订单、合同、物料等条件查看销售订单在 SAP/MES 中的履约、生产、发货或关闭状态。'], + [/MenuManagement/, '该页面维护菜单和权限。管理员查询、增加、修改、删除菜单/角色权限配置,用于动态路由和按钮权限。'], + [/OperationLog/, '该页面查询操作日志或报工操作记录,用于审计用户操作和追踪异常。'], + [/OrgManagement/, '该页面维护组织/角色类基础数据,支持新增、修改、删除和查询。'], + [/PersonnelManagement/, '该页面维护人员账号。管理员维护人员、部门、角色、启用状态等登录和权限基础数据。'], + [/SystemRrolemaintenance/, '该页面维护系统角色。管理员查询、新增、修改、删除角色数据。'], + [/WorkstationManagement/, '该页面维护工位资源。管理员在 MES 侧新增、修改、删除工位,同时调用 SAP B1 Resources 新增或更新资源主数据。'], + [/layout|Sidebar|Navbar|TagsView|AppMain|ResizeHandler/, '该文件属于系统布局组件,负责菜单、导航、标签页、内容承载或窗口自适应,不承载具体业务流程。'], + [/login/, '该页面是登录入口,负责账号密码登录、角色选择、Token/Cookie 写入、路由权限初始化和密码修改入口。'], + [/dashboard/, '该页面是系统首页或欢迎页,用于承载看板入口或基础统计展示。'], + [/404/, '该页面是 404 错误页,用于路由不存在时展示错误信息。'] + ]; + const found = rules.find(([re]) => re.test(p)); + return [found ? found[1] : '该页面为业务页面,具体功能由表单字段、按钮和存储过程调用共同决定。', ...common].join('\n\n'); +} + +function pageFlow(page) { + const p = page.relPath; + const flows = [ + [/SelfMakePlandone|SelfMakePlando|SelfMakePlan/, + '自制/机加排产流程:\n\n```mermaid\nflowchart LR\n A[输入订单/合同/物料/工序/时间条件] --> B[调用 MES_OrderPlanned_Query 查询待排产任务]\n B --> C[选择任务行]\n C --> D{派工方式}\n D --> E[MES_OrderPlanned_SingleTaskPlanned 单任务派工]\n D --> F[计划排产_二次派工 绑定人员]\n D --> G[计划排产_外协分组]\n E --> H[MES_OrderPlanned_EditTaskPlanned/DescriptionEdit 修改计划字段]\n F --> H\n G --> H\n H --> I[MES_OrderPlanned_Finish 确认排产]\n I --> J[PATCH /ProductionOrders(...) 回写 SAP 生产订单状态]\n J --> K[页面刷新任务状态]\n```\n'], + [/InstallMakePlanDo|InstallMakePlan/, + '装配排产流程:\n\n```mermaid\nflowchart LR\n A[输入订单/合同/物料/工序/时间条件] --> B[MES_OrderPlanned_Queryzp 查询装配任务]\n B --> C[选择任务]\n C --> D[Prog_MES_LoadStations 选择工位]\n D --> E[系统管理_人员管理_所有有效人员查询 选择人员]\n E --> F[计划排产_派工 或 MES_OrderPlanned_SingleTaskPlanned]\n F --> G[计划排产_二次派工]\n G --> H[MES_OrderPlanned_Finish 确认排产]\n H --> I[PATCH /ProductionOrders(...) 或 POST SAP 请求]\n I --> J[刷新排产结果]\n```\n'], + [/MachiningCenter/, + '机加中心执行流程:\n\n```mermaid\nflowchart LR\n A[选择工位/人员/任务条件] --> B[MES_ProductCenter_GetTask 查询可执行任务]\n B --> C[选择任务]\n C --> D[收料 MES_ProductTask_MaterialRecieved]\n D --> E[开始加工 MES_ProductTask_WorkingStart]\n E --> F{生产过程}\n F --> G[暂停/恢复 MES_ProductTask_Rest]\n F --> H[首检/巡检/序检]\n F --> I[报工 MES_ProductTask_ProdReport]\n I --> J[写入操作记录/报工记录]\n J --> K[必要时读取 SAP ProductionOrders]\n K --> L[刷新任务和进行中状态]\n```\n'], + [/AssemblyCenter/, + '装配中心执行流程:\n\n```mermaid\nflowchart LR\n A[选择工位/人员] --> B[MES_ProductCenter_GetTask_zp 查询装配任务]\n B --> C[查看缺料/图纸/工序]\n C --> D[MES_人员工时记录_开始 或生产任务开始]\n D --> E[执行装配]\n E --> F[MES_ProductTask_SendInspection 送检/报工]\n F --> G[收检记录/质检数据]\n G --> H[读取 SAP ProductionOrders 辅助判断]\n H --> I[刷新装配任务]\n```\n'], + [/WorkHoursCheck/, + '工时校验流程:\n\n```mermaid\nflowchart LR\n A[选择人员/订单/工序/日期] --> B[工时校验_获取昨日之前操作记录列表]\n B --> C[选择待校验记录]\n C --> D[usp_ValidateWorkTime 或 usp_BatchValidateWorkTime 计算工时]\n D --> E{校验结果}\n E --> F[工时校验_保存校验记录]\n E --> G[工时校验_批量保存校验记录]\n F --> H[更新校验状态]\n G --> H\n H --> I[GET/PATCH /ProductionOrders 补工序资源]\n I --> J[POST /InventoryGenExits 上传 SAP]\n J --> K[标记已上传/失败留痕]\n```\n'], + [/purchaseIncoming|processReceive|processSpecial|firstSpecial|final|materialReturn|salesReturn|OtherInbound|QualityCenter/, + '质检业务流程:\n\n```mermaid\nflowchart LR\n A[选择检验类型/订单/物料/工序] --> B[查询待检任务]\n B --> C[查看图纸/字典/检验人员]\n C --> D[录入检测数量、合格数、不合格数和检测明细]\n D --> E{检验类型}\n E --> F[来料/入库/退货检验更新]\n E --> G[序检收检新增或更新]\n E --> H[终检/首检/特殊检验保存]\n F --> I[写入 YL_质量检验_质检记录及明细]\n G --> I\n H --> I\n I --> J[必要时查询/回写 SAP 生产订单或单据]\n```\n'], + [/OutsourceMange|SaleOutsourceMange|OutsourceSheet/, + '外协业务流程:\n\n```mermaid\nflowchart LR\n A[输入订单/合同/供应商/工序条件] --> B[查询外协任务或外协报表]\n B --> C[选择外协工序/供应商]\n C --> D[计划排产_派工 或外协分组]\n D --> E[POST SAP 采购/外协相关请求]\n E --> F[外协发料查询/保存]\n F --> G[外协收料/质检记录]\n G --> H[更新打印次数/备注/报表状态]\n```\n'] + ]; + const found = flows.find(([re]) => re.test(p)); + if (found) return found[1]; + if (!page.procs.length) return '该页面未发现后端存储过程调用,通常不形成完整业务流程。'; + const procChain = uniq(page.procs.map(x => x.name)).slice(0, 8).map(x => `\`${x}\``).join(' -> '); + return `通用流程:用户输入查询/维护条件 -> 调用 ${procChain} -> 后端读写 SQL Server -> 页面刷新表格或弹窗结果。`; +} + +function fieldMappingTable(page) { + const rows = [ + '| 类型 | 前端字段/显示列 | 存储过程参数或表达式 | SQL返回字段/数据库字段线索 |', + '|---|---|---|---|' + ]; + const mappings = []; + for (const p of page.fields.pushedParams || []) { + const relatedProc = page.procs.find(proc => proc.sqlInfo?.params?.some(x => x.includes(`@${p.name}`))); + const sqlField = relatedProc?.sqlInfo?.features?.selectColumns?.find(x => x.includes(p.name)) || ''; + mappings.push(['参数', p.expr, `@${p.name}`, sqlField]); + } + for (const c of page.fields.tableColumns || []) { + if (!c.label && !c.prop) continue; + const sqlField = page.procs + .flatMap(proc => proc.sqlInfo?.features?.selectColumns || []) + .find(x => (c.prop && x.includes(c.prop)) || (c.label && x.includes(c.label))) || ''; + mappings.push(['显示列', c.label || c.prop, '', sqlField || c.prop || c.label]); + } + for (const v of page.fields.vModels || []) { + const name = v.split('.').pop(); + const param = page.fields.pushedParams.find(x => x.expr.includes(v) || x.expr.includes(name)); + mappings.push(['输入字段', v, param ? `@${param.name}` : '', '']); + } + const uniqRows = uniq(mappings.map(x => x.join('|'))).slice(0, 40); + if (!uniqRows.length) return '未从页面模板中抽取到明确的 `v-model`、表格列或 `param.push` 字段映射。'; + for (const item of uniqRows) { + const [type, front, param, sql] = item.split('|'); + rows.push(`| ${type} | \`${front || '-'}\` | ${param ? `\`${param}\`` : '-'} | ${sql ? `\`${sql}\`` : '-'} |`); + } + return rows.join('\n'); +} + +function statusFlow(page) { + const lines = []; + for (const proc of page.procs) { + const info = proc.sqlInfo; + if (!info) continue; + const status = info.features.statusLines || []; + const useful = status.filter(x => /状态|排产|派工|加工|任务|质检|关闭|完成|已报工|DocEntry|SAP/i.test(x)); + if (useful.length) lines.push(`- \`${proc.name}\`:${useful.slice(0, 8).map(x => `\`${x}\``).join(';')}`); + } + if (!lines.length) return '未从当前 SQL 静态解析到明确的状态字段变更。'; + return lines.join('\n'); +} + +function sapInterfaceList(page) { + if (!page.sapCalls.length) return '页面无直接 SAP Service Layer 调用。'; + const lines = ['| 行号 | 方法 | 接口 | 调用时机/影响判断 | 提交字段线索 |', '|---:|---|---|---|---|']; + for (const c of page.sapCalls) { + const timing = c.url.includes('ProductionOrders') + ? '读取或更新 SAP 生产订单。失败会导致 MES 与 SAP 订单状态/工序资源不同步。' + : c.url.includes('InventoryGenExits') + ? '上传库存发出/工时相关单据。失败会导致 SAP 未生成对应业务单据。' + : c.url.includes('Resources') + ? '新增或更新 SAP 资源主数据。失败会导致 MES 工位与 SAP 资源不一致。' + : c.url.includes('RouteStages') + ? '新增或更新 SAP 工序阶段。失败会导致 MES 工序与 SAP RouteStages 不一致。' + : '调用外部接口,失败会影响对应外部系统同步。'; + lines.push(`| ${c.line} | \`${c.fn}\` | \`${c.url}\` | ${timing} | ${mdList(c.payloadKeys.slice(0, 12))} |`); + } + return lines.join('\n'); +} + +function dbCallChain(page) { + if (!page.procs.length) return '无数据库调用链。'; + const lines = []; + for (const proc of page.procs) { + const deps = proc.sqlInfo ? depsMd(proc.sqlInfo.deps) : '过程体未解析'; + const result = proc.purpose; + lines.push(`- \`${page.relPath}\` -> \`${proc.name}\` -> ${deps} -> ${result}`); + } + return lines.join('\n'); +} + +function mdList(items, empty = '无') { + if (!items || !items.length) return empty; + return items.map(x => `\`${x}\``).join('、'); +} + +function depsMd(deps) { + if (!deps || !deps.length) return '未在 SQL 中解析到明确依赖'; + const tables = deps.filter(x => x.startsWith('TABLE:')).map(x => x.slice(6)); + const views = deps.filter(x => x.startsWith('VIEW:')).map(x => x.slice(5)); + const sap = deps.filter(x => x.startsWith('SAP:')).map(x => x.slice(4)); + const parts = []; + if (tables.length) parts.push(`表:${mdList(tables)}`); + if (views.length) parts.push(`视图:${mdList(views)}`); + if (sap.length) parts.push(`SAP/链接库:${mdList(sap)}`); + return parts.join(';') || '未在 SQL 中解析到明确依赖'; +} + +function explainProc(proc) { + const info = proc.sqlInfo; + const lines = []; + lines.push(`\`${proc.name}\` 属于 ${businessDomainFromName(proc.name)},前端以 type=${proc.type}(${proc.op})调用,页面用途是 ${proc.purpose}。`); + if (!info) { + lines.push('当前工作区 SQL 中没有解析到该过程体,因此只能确认前端调用关系,不能准确说明内部读写表、过滤条件和状态变更。'); + return lines.join(' '); + } + const f = info.features; + lines.push(`数据库处理摘要:${info.summary}。`); + lines.push(`读取/关联对象:${depsMd(info.deps)}。`); + if (info.writes.length) lines.push(`写入或更新对象:${mdList(info.writes)}。`); + if (info.params.length) lines.push(`入参/分页参数:${mdList(info.params)}。`); + if (f.selectColumns.length) lines.push(`主要返回字段线索:${mdList(f.selectColumns)}。`); + if (f.filters.length) lines.push(`关键过滤/匹配条件:${f.filters.map(x => `\`${x}\``).join(';')}。`); + if (f.updates.length) lines.push(`关键写入/状态处理语句线索:${f.updates.map(x => `\`${x}\``).join(';')}。`); + if (f.grouping.length) lines.push(`排序/分组/分页线索:${f.grouping.map(x => `\`${x}\``).join(';')}。`); + const flags = []; + if (f.hasPagination) flags.push('分页'); + if (f.hasJson) flags.push('JSON 批量解析'); + if (f.hasTransaction) flags.push('事务控制'); + if (f.hasTryCatch) flags.push('异常捕获'); + if (f.hasSap) flags.push('读取 SAP 数据库对象'); + if (f.tempTables.length) flags.push(`临时表 ${mdList(f.tempTables)}`); + if (flags.length) lines.push(`实现特征:${flags.join('、')}。`); + return lines.join(' '); +} + +function procTable(procs) { + if (!procs.length) return '未发现 `CreateData(...)` 存储过程调用。'; + const rows = [ + '| 行号 | type | 存储过程 | 前端用途 | SQL摘要 | 依赖对象 |', + '|---:|---|---|---|---|---|' + ]; + for (const p of procs) { + const info = p.sqlInfo; + rows.push(`| ${p.line} | ${p.type}(${p.op}) | \`${p.name}\` | ${p.purpose} | ${info ? info.summary : '未找到过程体'} | ${info ? depsMd(info.deps) : '未知'} |`); + } + return rows.join('\n'); +} + +function sapTable(calls, procs) { + const procSap = []; + for (const p of procs) { + if (p.sqlInfo && p.sqlInfo.sapRefs.length) procSap.push(`${p.name}: ${p.sqlInfo.sapRefs.join(', ')}`); + } + if (!calls.length && !procSap.length) return '未发现页面直接调用 SAP B1 Service Layer;相关存储过程也未解析到 `SAP.SBO_YL` 链接库引用。'; + const lines = []; + if (calls.length) { + lines.push('页面直接 SAP/接口调用:'); + for (const c of calls) lines.push(`- 第 ${c.line} 行:\`${c.fn}("${c.url}")\``); + } + if (procSap.length) { + lines.push('存储过程内读取 SAP B1 数据库对象:'); + for (const s of procSap) lines.push(`- ${s}`); + } + return lines.join('\n'); +} + +function techFlags(page) { + const flags = ['Vue 2 Options API', 'Element UI']; + if (page.procs.length) flags.push('`CreateData` + `ExecDatabase` 调用后端过程'); + else flags.push('未发现页面级后端存储过程调用'); + if (page.sapCalls.length) flags.push('SAP B1 Service Layer(`src/api/b1s.js`)'); + if (page.imports.includes('@/api/tm') || page.sapCalls.some(x => x.fn === 'posttm')) flags.push('TM/OpenAPI 接口(`src/api/tm.js`)'); + if (page.hasEcharts) flags.push('ECharts'); + if (page.hasFullCalendar) flags.push('FullCalendar'); + if (page.hasMqtt) flags.push('MQTT'); + if (page.hasPdf) flags.push('PDF/图纸预览或导出'); + if (page.hasExcel) flags.push('Excel/报表导出'); + return flags; +} + +function moduleSummary(pages) { + const groups = {}; + for (const p of pages) { + const top = p.relPath.split('/')[2] || '其他'; + groups[top] ||= []; + groups[top].push(p); + } + const lines = ['| 模块 | 页面数 | 主要能力 |', '|---|---:|---|']; + for (const [mod, ps] of Object.entries(groups)) { + const allProcs = uniq(ps.flatMap(p => p.procs.map(x => x.name))); + const allSap = ps.reduce((n, p) => n + p.sapCalls.length, 0); + const ability = []; + if (allProcs.length) ability.push(`过程 ${allProcs.length} 个`); + if (allSap) ability.push(`直接 SAP 调用 ${allSap} 处`); + if (ps.some(p => p.hasEcharts)) ability.push('图表'); + if (ps.some(p => p.hasMqtt)) ability.push('设备实时通信'); + lines.push(`| ${mod} | ${ps.length} | ${ability.join('、') || '布局/静态页面'} |`); + } + return lines.join('\n'); +} + +const sqlModel = extractSqlModel(); +const pages = walk(viewsRoot, ['.vue', '.js']).sort().map(file => { + const text = readText(file); + const relPath = rel(file); + const procs = extractCreateData(text).map(p => ({ + ...p, + op: operationByType(p.type), + purpose: procPurpose(p.name), + sqlInfo: sqlModel.procByName[p.name] + })); + const page = { + file, + relPath, + module: moduleNameFromPath(relPath), + lines: text.split(/\r?\n/).length, + labels: extractLabels(text), + methods: extractMethods(text), + fields: extractFrontendFields(text), + procs, + sapCalls: extractSapCalls(text), + imports: extractApiImports(text), + hasMqtt: /mqtt|MQTT/.test(text), + hasEcharts: /echarts|ECharts|\$echarts/.test(text), + hasFullCalendar: /FullCalendar|@fullcalendar/.test(text), + hasPdf: /pdfjs|jspdf|html2canvas|pdf/i.test(text), + hasExcel: /xlsx|exportExcel|Excel|导出/.test(text) + }; + page.functionDesc = pageBusinessNarrative(page); + return page; +}); + +const now = new Date().toISOString().slice(0, 10); +let md = ''; +md += `# MES_Manage_View_V20 src/views 逐页面详细分析\n\n`; +md += `生成日期:${now}\n\n`; +md += `分析范围:\`MES_Manage_View_V20/src/views\` 下 ${pages.length} 个 .vue/.js 文件;辅助读取 \`src/api\`、\`config/index.js\`、\`static/config.js\` 和 SQL 脚本。\n\n`; +md += `## 重要说明\n\n`; +md += `- 页面功能不是只按文件名猜测,报告同时参考页面路径、按钮/字段文案、方法名、存储过程名和 SQL 过程体。\n`; +md += `- 存储过程处理说明来自 SQL 静态解析:读写对象、参数、返回字段、过滤条件、更新语句、分组分页、JSON、事务、SAP 链接库等。\n`; +md += `- 如果某个过程没有解析到过程体,报告会明确说明不能准确判断内部表/视图和处理逻辑。\n\n`; + +md += `## 技术路线总览\n\n`; +md += `- 前端:Vue 2.7、Vue Router、Vuex、Element UI,页面以 Options API 为主。\n`; +md += `- 数据访问:页面调用 \`this.CreateData(type, procedureName, params[, pageSize, pageCurrent])\` 组包,再调用 \`this.ExecDatabase(data)\` 访问后端。\n`; +md += `- 后端:统一接口接收 type/name/param,执行 SQL Server 存储过程,返回 \`response.data\` 和分页信息。\n`; +md += `- 数据库:\`YL_MESDB\`,核心对象包括生产计划/生产任务、加工中心操作记录、质检记录、设备数据、权限菜单等表和视图。\n`; +md += `- SAP:\`src/api/b1s.js\` 通过 \`window.dt_Config.baseURLB1\` 访问 B1 Service Layer;部分过程也跨库读取 \`SAP.SBO_YL.dbo.*\`。\n\n`; + +md += `## 模块汇总\n\n${moduleSummary(pages)}\n\n`; + +const allSapCalls = []; +for (const p of pages) { + for (const c of p.sapCalls) allSapCalls.push({ page: p.relPath, ...c }); +} +if (allSapCalls.length) { + md += `## SAP 交互总清单\n\n`; + md += `| 页面 | 行号 | 方法 | 接口 | 提交字段线索 |\n|---|---:|---|---|---|\n`; + for (const c of allSapCalls) { + md += `| \`${c.page}\` | ${c.line} | \`${c.fn}\` | \`${c.url}\` | ${mdList(c.payloadKeys.slice(0, 10))} |\n`; + } + md += `\n`; +} + +for (let i = 0; i < pages.length; i++) { + const p = pages[i]; + md += `## ${i + 1}. ${p.relPath}\n\n`; + md += `**页面位置**:\`${p.relPath}\` \n`; + md += `**所属模块**:${p.module} \n`; + md += `**源码行数**:${p.lines}\n\n`; + md += `### 页面功能\n\n${p.functionDesc}\n\n`; + md += `### 页面流程图\n\n${pageFlow(p)}\n\n`; + md += `### 用户操作与页面线索\n\n`; + md += `可见按钮/字段线索:${mdList(p.labels.slice(0, 18))}\n\n`; + md += `主要方法线索:${mdList(p.methods.slice(0, 18))}\n\n`; + md += `### 字段映射表\n\n${fieldMappingTable(p)}\n\n`; + md += `### 技术路线\n\n${techFlags(p).map(x => `- ${x}`).join('\n')}\n\n`; + md += `### 调用的存储过程总览\n\n${procTable(p.procs)}\n\n`; + md += `### 与 SAP 的交互\n\n${sapTable(p.sapCalls, p.procs)}\n\n`; + md += `### SAP 接口级说明\n\n${sapInterfaceList(p)}\n\n`; + md += `### 状态流转说明\n\n${statusFlow(p)}\n\n`; + md += `### 数据库调用链\n\n${dbCallChain(p)}\n\n`; + md += `### 存储过程处理逻辑明细\n\n`; + if (!p.procs.length) { + md += `无页面级存储过程调用。\n\n`; + } else { + for (const proc of p.procs) md += `- ${explainProc(proc)}\n`; + md += `\n`; + } +} + +md += `## SQL 对象总览\n\n`; +md += `脚本中解析到表/视图 ${sqlModel.objects.length} 个、存储过程 ${Object.keys(sqlModel.procByName).length} 个。\n\n`; +md += `### 表/视图清单\n\n`; +for (const obj of sqlModel.objects) md += `- ${obj.type === 'TABLE' ? '表' : '视图'}:\`${obj.name}\`\n`; + +fs.writeFileSync(outFile, md, 'utf8'); +console.log(outFile); diff --git a/tools/create_dev_plan_docx.ps1 b/tools/create_dev_plan_docx.ps1 new file mode 100644 index 0000000..e715de4 --- /dev/null +++ b/tools/create_dev_plan_docx.ps1 @@ -0,0 +1,206 @@ +param( + [Parameter(Mandatory = $true)] + [string]$PlanMarkdown, + + [Parameter(Mandatory = $true)] + [string]$SourceMarkdown, + + [Parameter(Mandatory = $true)] + [string]$OutputDocx +) + +$ErrorActionPreference = 'Stop' + +function Escape-XmlText { + param([AllowNull()][string]$Text) + if ($null -eq $Text) { return '' } + return [System.Security.SecurityElement]::Escape($Text) +} + +function Add-Paragraph { + param( + [System.Collections.Generic.List[string]]$Parts, + [string]$Text, + [string]$Style = $null + ) + $styleXml = '' + if ($Style) { + $styleXml = "" + } + $Parts.Add("$styleXml$(Escape-XmlText $Text)") +} + +function Add-Table { + param( + [System.Collections.Generic.List[string]]$Parts, + [string[]]$Headers, + [object[]]$Rows + ) + $tbl = New-Object System.Text.StringBuilder + [void]$tbl.Append('') + [void]$tbl.Append('') + [void]$tbl.Append('') + foreach ($h in $Headers) { + [void]$tbl.Append('') + [void]$tbl.Append((Escape-XmlText $h)) + [void]$tbl.Append('') + } + [void]$tbl.Append('') + foreach ($row in $Rows) { + [void]$tbl.Append('') + foreach ($cell in $row) { + [void]$tbl.Append('') + [void]$tbl.Append((Escape-XmlText ([string]$cell))) + [void]$tbl.Append('') + } + [void]$tbl.Append('') + } + [void]$tbl.Append('') + $Parts.Add($tbl.ToString()) +} + +function Flush-TableBuffer { + param( + [System.Collections.Generic.List[string]]$Parts, + [System.Collections.Generic.List[string]]$Buffer + ) + if ($Buffer.Count -lt 2) { + foreach ($line in $Buffer) { + Add-Paragraph -Parts $Parts -Text $line + } + $Buffer.Clear() + return + } + $header = $Buffer[0].Trim('|').Split('|') | ForEach-Object { $_.Trim() } + $rows = @() + for ($i = 2; $i -lt $Buffer.Count; $i++) { + $rows += ,($Buffer[$i].Trim('|').Split('|') | ForEach-Object { $_.Trim() }) + } + Add-Table -Parts $Parts -Headers $header -Rows $rows + $Buffer.Clear() +} + +function Add-MarkdownContent { + param( + [System.Collections.Generic.List[string]]$Parts, + [string]$MarkdownPath + ) + $lines = [System.IO.File]::ReadAllLines($MarkdownPath, [System.Text.Encoding]::UTF8) + $tableBuffer = New-Object System.Collections.Generic.List[string] + $inCode = $false + + foreach ($line in $lines) { + if ($line.TrimStart().StartsWith('```')) { + if ($tableBuffer.Count -gt 0) { Flush-TableBuffer -Parts $Parts -Buffer $tableBuffer } + $inCode = -not $inCode + Add-Paragraph -Parts $Parts -Text $line -Style 'Code' + continue + } + if ($inCode) { + Add-Paragraph -Parts $Parts -Text $line -Style 'Code' + continue + } + if ($line.TrimStart().StartsWith('|') -and $line.TrimEnd().EndsWith('|')) { + $tableBuffer.Add($line) + continue + } + if ($tableBuffer.Count -gt 0) { Flush-TableBuffer -Parts $Parts -Buffer $tableBuffer } + + if ($line.StartsWith('### ')) { + Add-Paragraph -Parts $Parts -Text $line.Substring(4) -Style 'Heading3' + } elseif ($line.StartsWith('## ')) { + Add-Paragraph -Parts $Parts -Text $line.Substring(3) -Style 'Heading2' + } elseif ($line.StartsWith('# ')) { + Add-Paragraph -Parts $Parts -Text $line.Substring(2) -Style 'Heading1' + } elseif ($line.Trim().StartsWith('- ')) { + Add-Paragraph -Parts $Parts -Text ('· ' + $line.Trim().Substring(2)) + } elseif ([string]::IsNullOrWhiteSpace($line)) { + Add-Paragraph -Parts $Parts -Text '' + } else { + Add-Paragraph -Parts $Parts -Text $line + } + } + if ($tableBuffer.Count -gt 0) { Flush-TableBuffer -Parts $Parts -Buffer $tableBuffer } +} + +if (-not (Test-Path -LiteralPath $PlanMarkdown)) { throw "Plan markdown not found: $PlanMarkdown" } +if (-not (Test-Path -LiteralPath $SourceMarkdown)) { throw "Source markdown not found: $SourceMarkdown" } + +$outputDir = Split-Path -Path $OutputDocx -Parent +if (-not (Test-Path -LiteralPath $outputDir)) { + New-Item -ItemType Directory -Path $outputDir | Out-Null +} + +$tempRoot = Join-Path $env:TEMP ("docx_" + [Guid]::NewGuid().ToString('N')) +$wordDir = Join-Path $tempRoot 'word' +$relsDir = Join-Path $tempRoot '_rels' +$wordRelsDir = Join-Path $wordDir '_rels' +New-Item -ItemType Directory -Path $wordDir, $relsDir, $wordRelsDir | Out-Null + +$parts = New-Object System.Collections.Generic.List[string] +Add-MarkdownContent -Parts $parts -MarkdownPath $PlanMarkdown +Add-MarkdownContent -Parts $parts -MarkdownPath $SourceMarkdown + +$documentXml = @" + + + + $($parts -join "`n") + + + + + + +"@ + +$stylesXml = @' + + + + + + + + + +'@ + +$contentTypesXml = @' + + + + + + + +'@ + +$relsXml = @' + + + + +'@ + +$docRelsXml = @' + + + + +'@ + +[System.IO.File]::WriteAllText((Join-Path $tempRoot '[Content_Types].xml'), $contentTypesXml, [System.Text.Encoding]::UTF8) +[System.IO.File]::WriteAllText((Join-Path $relsDir '.rels'), $relsXml, [System.Text.Encoding]::UTF8) +[System.IO.File]::WriteAllText((Join-Path $wordDir 'document.xml'), $documentXml, [System.Text.Encoding]::UTF8) +[System.IO.File]::WriteAllText((Join-Path $wordDir 'styles.xml'), $stylesXml, [System.Text.Encoding]::UTF8) +[System.IO.File]::WriteAllText((Join-Path $wordRelsDir 'document.xml.rels'), $docRelsXml, [System.Text.Encoding]::UTF8) + +if (Test-Path -LiteralPath $OutputDocx) { + Remove-Item -LiteralPath $OutputDocx -Force +} + +Add-Type -AssemblyName System.IO.Compression.FileSystem +[System.IO.Compression.ZipFile]::CreateFromDirectory($tempRoot, $OutputDocx) +Remove-Item -LiteralPath $tempRoot -Recurse -Force +Write-Output $OutputDocx