From 6d267bcfc54be3834677252ffa11aa77ca89a39e Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Mon, 24 Aug 2026 17:29:33 +0800 Subject: [PATCH] feat:tabbar --- src/manifest.json | 4 +- src/pages/integrated/notice/index.vue | 1 + src/pages/root/dashboard.vue | 2 + src/pages/root/web-view.vue | 49 +++++++++-- src/pages/third-app/happyMall.vue | 31 ++++++- .../crud/crud-layout/crud-layout.vue | 4 + src/sheep/stores/tabbar.ts | 77 +++++++++++++++--- src/static/tabbar/feedback-select.png | Bin 0 -> 5256 bytes src/static/tabbar/feedback.png | Bin 0 -> 5399 bytes src/static/tabbar/notice-select.png | Bin 0 -> 4855 bytes src/static/tabbar/notice.png | Bin 0 -> 5023 bytes 11 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 src/static/tabbar/feedback-select.png create mode 100644 src/static/tabbar/feedback.png create mode 100644 src/static/tabbar/notice-select.png create mode 100644 src/static/tabbar/notice.png diff --git a/src/manifest.json b/src/manifest.json index a4d92a2..7a7c3df 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,6 +1,6 @@ { "name": "", - "appid": "", + "appid": "wx11771c7bf2913cb2", "description": "", "versionName": "1.0.0", "versionCode": "100", @@ -50,7 +50,7 @@ "quickapp": {}, /* 小程序特有相关 */ "mp-weixin": { - "appid": "", + "appid": "wx11771c7bf2913cb2", "setting": { "urlCheck": false }, diff --git a/src/pages/integrated/notice/index.vue b/src/pages/integrated/notice/index.vue index e6b2753..5ed9ed3 100644 --- a/src/pages/integrated/notice/index.vue +++ b/src/pages/integrated/notice/index.vue @@ -1,5 +1,6 @@ + + diff --git a/src/pages/third-app/happyMall.vue b/src/pages/third-app/happyMall.vue index 5bf377d..1104de9 100644 --- a/src/pages/third-app/happyMall.vue +++ b/src/pages/third-app/happyMall.vue @@ -33,8 +33,18 @@ function normalizeMallUrl(rawUrl: string) { const [, origin, rawPathname = "/", search = "", hash = ""] = matched const queryItems = search.slice(1).split("&").filter(Boolean) - const queryKeys = queryItems.map((item) => decodeURIComponent(item.split("=")[0] || "")) - const hasToken = queryItems.some((item) => /^token=.+/i.test(item)) + const decodeQueryPart = (value: string) => { + try { + return decodeURIComponent(value) + } catch { + return value + } + } + const queryKeys = queryItems.map((item) => decodeQueryPart(item.split("=")[0] || "")) + const hasToken = queryItems.some((item) => { + const [key, ...valueParts] = item.split("=") + return decodeQueryPart(key || "").toLowerCase() === "token" && valueParts.join("=") + }) let pathname = rawPathname // 宁波银行正常登录页是 /h5/thirdApp;部分环境会错误返回带 token 的根路径。 @@ -51,7 +61,22 @@ function normalizeMallUrl(rawUrl: string) { if (pathname === "/" || !hasToken) { throw new Error("商城登录地址异常,请联系管理员") } - return `${origin}${pathname}${search}${hash}` + + // 宁波银行 H5 通过 platform 判断是否运行在微信小程序中。设置为 XR 后, + // H5 左上角返回按钮会调用 wx.miniProgram.navigateBack(),直接返回小程序上一页, + // 不会先消耗宁波银行 H5 自己的 history。覆盖旧值,避免后端返回其他平台参数。 + const queryWithoutPlatform = queryItems.filter((item) => { + const key = decodeQueryPart(item.split("=")[0] || "").toLowerCase() + return key !== "platform" + }) + queryWithoutPlatform.push("platform=XR") + const normalizedSearch = `?${queryWithoutPlatform.join("&")}` + console.log("[happyMall] 跳转平台:", { + platform: "XR", + queryKeys: queryWithoutPlatform.map((item) => decodeQueryPart(item.split("=")[0] || "")), + }) + + return `${origin}${pathname}${normalizedSearch}${hash}` } onLoad(async () => { diff --git a/src/sheep/components/crud/crud-layout/crud-layout.vue b/src/sheep/components/crud/crud-layout/crud-layout.vue index d756303..6538ba6 100644 --- a/src/sheep/components/crud/crud-layout/crud-layout.vue +++ b/src/sheep/components/crud/crud-layout/crud-layout.vue @@ -93,6 +93,10 @@ function initBackStyle() { function tabbarChange(index: number) { const target = tabbarStore.tabbarList[index] if (!target) return + if (target.pagePath === "/pages/root/dashboard") { + // 从业务导航返回工作台时,让首页根 Tabbar 同步选中“首页”。 + tabbarStore.setRootActiveIndex(0) + } jump(target.pagePath, {}, 3) } diff --git a/src/sheep/stores/tabbar.ts b/src/sheep/stores/tabbar.ts index dae372b..a6c2e87 100644 --- a/src/sheep/stores/tabbar.ts +++ b/src/sheep/stores/tabbar.ts @@ -118,16 +118,62 @@ const TABBAR_CONSTANT: Array = [ launchParam: ["integrated"], auth: ["user"], }, + { + pagePath: "/pages/integrated/notice/index", + text: "通知公告", + iconPath: "/static/tabbar/notice.png", + selectedIconPath: "/static/tabbar/notice-select.png", + launchParam: ["notice"], + auth: ["user"], + }, + { + pagePath: "/pages/integrated/feedback/index", + text: "意见反馈", + iconPath: "/static/tabbar/feedback.png", + selectedIconPath: "/static/tabbar/feedback-select.png", + launchParam: ["feedback"], + auth: ["user"], + }, { pagePath: "/pages/tabbar/my", text: "我的", iconPath: "/static/tabbar/my.png", selectedIconPath: "/static/tabbar/my-select.png", - launchParam: ["canteen", "selfMerchant", "onlineShop", "coopMerchant", "integrated", "prosperityShop", "prosperityShopMchList"], + launchParam: [ + "canteen", + "selfMerchant", + "onlineShop", + "coopMerchant", + "integrated", + "prosperityShop", + "prosperityShopMchList", + "notice", + "feedback", + ], auth: ["user", "merchant", "doorAdmin"], }, ] +const WORKBENCH_TABBAR_ITEM: TabbarItem = { + pagePath: "/pages/root/dashboard", + text: "工作台", + iconPath: "/static/tabbar/home.png", + selectedIconPath: "/static/tabbar/home-select.png", + launchParam: [], + auth: [], +} + +function getTabbarLaunchParam(url?: string) { + const launchParam = getLaunchParam(url) + if (launchParam) return launchParam + if (!url) return "" + + // 常用功能也可能直接配置 Tabbar 页面路径,需要由页面反推出所属业务场景。 + const pagePath = url.split("?")[0] + const tabbarItem = TABBAR_CONSTANT.find((item) => item.pagePath === pagePath) + return tabbarItem?.launchParam[0] || "" +} + const defaultRootTabbarList: Array = [ { pagePath: "/pages/root/dashboard", @@ -166,13 +212,17 @@ export const useTabbarStore = defineStore("tabbarStore", { }), getters: { isDashboardPage(state) { - return `/${state.currentRoute}` === "/pages/root/dashboard" || `/${state.currentRoute}` === "/pages/tabbar/my" + const currentRoute = state.currentRoute.startsWith("/") ? state.currentRoute : `/${state.currentRoute}` + return currentRoute === "/pages/root/dashboard" || currentRoute === "/pages/tabbar/my" }, isTabbar(state) { - return state.tabbarList.some((item) => item.pagePath === `/${state.currentRoute}`) + const currentRoute = state.currentRoute.startsWith("/") ? state.currentRoute : `/${state.currentRoute}` + // 工作台只作为业务 Tabbar 的返回入口,进入页面后仍展示首页自己的根 Tabbar。 + return currentRoute !== WORKBENCH_TABBAR_ITEM.pagePath && state.tabbarList.some((item) => item.pagePath === currentRoute) }, activeIndex(state) { - return state.tabbarList.findIndex((item) => item.pagePath === `/${state.currentRoute}`) + const currentRoute = state.currentRoute.startsWith("/") ? state.currentRoute : `/${state.currentRoute}` + return state.tabbarList.findIndex((item) => item.pagePath === currentRoute) }, pageTabbarList(state) { return state.tabbarList.map((item) => { @@ -196,22 +246,25 @@ export const useTabbarStore = defineStore("tabbarStore", { }, actions: { async componetTabbarList(launchParam?: string) { - let _launchParam = "" - if (launchParam) { - _launchParam = getLaunchParam(launchParam) - } else { - _launchParam = getLaunchParam() - } - if (this.launchParam === _launchParam) return + const _launchParam = getTabbarLaunchParam(launchParam) + const hasMyTabbar = this.tabbarList.some((item) => item.pagePath === "/pages/tabbar/my") + const hasWorkbenchTabbar = this.tabbarList.some((item) => item.pagePath === WORKBENCH_TABBAR_ITEM.pagePath) + // 热更新或旧状态中可能已有相同场景但尚未加入工作台,此时仍需重新组装。 + if (this.launchParam === _launchParam && (!hasMyTabbar || hasWorkbenchTabbar)) return const appInfo = await getAppInfo() if (!_launchParam || !appInfo) return const tabbarList: Array = [] - TABBAR_CONSTANT.forEach((item, index) => { + TABBAR_CONSTANT.forEach((item) => { const visible = item.launchParam.includes(_launchParam) if (visible) { tabbarList.push(item) } }) + const myTabbarIndex = tabbarList.findIndex((item) => item.pagePath === "/pages/tabbar/my") + if (myTabbarIndex !== -1) { + // 仅对带“我的”的业务导航生效,并保证“工作台”紧邻其左侧。 + tabbarList.splice(myTabbarIndex, 0, WORKBENCH_TABBAR_ITEM) + } this.tabbarList = tabbarList this.launchParam = _launchParam }, diff --git a/src/static/tabbar/feedback-select.png b/src/static/tabbar/feedback-select.png new file mode 100644 index 0000000000000000000000000000000000000000..087a44e60bd31b7b765c820b0e358b2e220dc3c2 GIT binary patch literal 5256 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 O0000W3VGgCO7pIY^+~ z&3zDXg6xC4TRjK@PLP8H%H7-t0Vl{lxVzPZAaG2A90Xi<^Y{ojL5?3oA3;R~oFEm! zb=Aj5zzK5v82Sh*BG5HKe*gacAbFk2zyJRG4^j~qS8arVVn+-gh?hPOvHbPx*9V{3 zhZvcvqNYoN2s}W2{rLDm9zH%kZshLn?im4SMD1Sz8YxA|`_doQud(ZnAOI!s0QCVNQ$+0_02%>o1U*Pfe{YkI0ECcyRR+c48yQlx6T2Sc z)fGVi2%u5`U2B6L1hNo7bg%XCLnuH7vIvUcJSs8-f4~04>9p ze}n*{n}907!*opBQkufL8{-BuERJ zJ=tK)lACqKp8gS!J?#hET@a)fFaQN#!t{&pXBUxTSa36D$u8Am31fU)I@W4`7X)cF z*e!M-%Gsx0Ok+d}7TsMDV@sTBx80o}J)9+CAfJ&aU@jT%SH#Bd#}4+|AD!)9l(3I% zk(L3J-RFKQN*WR(Mf2&DaC<|Dm$pOf(!A}X)$SE!D-2IhPj5ee{`?2|`|rQ+kN`YE z*s5=9d)azsYO=N8-tF;O_*9=x37h~2eMcaMTyhRluN{T;9`QtXLIRR07}=erVt?@#_36+A%Fe5 z96`d!$3#(rn*?2nwCj`$a^OQ4W62gwB*PR6tV9kIj7ogkqwi%262SfpzS%lONwv$A zE37xdxN^7he>{!4Bq_$&U7jET42WX2Mp2SAB?;ufW*AHER@LW4mEv;Ks2E;OkO?|g zL?K~G+=+Vguh_s=iDLC1ss>{((R0SWPLPGDk}RB2NuGr!tGm_rS?hw=)rOf3(2b4E z?myIbAjV!*BiHYi{hS~Xv>^$}15qN)qKDLXc)TOpDB~cN1Kk;2hc1wVu}Ln!&KLk$ z_@5JG0hsY_h@xc7zJH>=rX+zJO7Q2gk6S*=pJA=BrO#E{IzbX64@s1ikCLo2u9DJ( zBqij)cggT5NaCZJAqAL@NU|>pmy)EE9QZEDBKQWFPSw;2k`Yd-iIP2Q%B6l; zm866mvU#;BRYp|jyEsASaarBlk|d?%z}M9Qd4pL5oFKEXr0pc}I6J4czHOy`!z(&( z_kRE8^*NA1BBRC^@^hI;3RJB8jG3y!`owB<#!a10V1ur?2<5)mLV zNzlaRH_gU`Q1!@qJViRVTIH8uu5zaDt>`mE4j14d z4V@rau%&gXO%f+ZS{zDRH6=)iqetxvNwjb`UpS)^-ABdcD1JLZ8bnG9_w1*Dm)t|= z(lOs}hkz5r4$C!7Sr0ePDOL5zy5BOV%lE|*aDv3~F*~X={_xJ)QiZHL&{e9(`==q` z1WCimq!nuh5mkZC zd~=^2hITrWPLReSrs;6qNZ81kH&}NzO_fd31W}w zqQ>|4cZ+FK_UnEY9rFW=2sl9&p$P|UwoH$x0HxYkzfg%v^?3g@1e_pgI2E_DAjilF zuOcHbYJPNr)I|4FH`U|wqsfLUVxq{EtRmn9S%s*)fpPU196IVW>;C?J^F5$pz&ri# zekZ$^F>75tE(4qf+QTC?P7np6=D%q5C@|bZ^5nRW-@;_Iif9^X_Hbv8pP`QvBp^{? zyR~|d6v&z@DQ(tt?0kGR`Foj)IYBCBiq4dqt~T+k6%r!=$7oa0?dqzjB8+3skT45> z)MvHI%=Ne4=LE4v^iy9>_4w@i0|JmhNZ1z=hht&ik++N^{7p#4iD-=ceMF=Sa)7TB z1QaTWg1xzVjNKrC5RwSdS+}di8T(rDnK1^@7`q`x7?TquAYr&IsUB8txE>n>oFFzh z-e@VU9yiMT%dQAGL5$(|>R}A%&gz^XI|qRI_s%YSndk1jgcoVQ{`&Rn1K~TQN4^?f z=z|l)IM}*=|5vI?uH2-yt=$d+$e&lq0}|}C0s_bqs>+$j;smkCj)@ME9}-M<4`12O@!?Ac z|5L?FUNfb*3sI1>ki`j-67`HWkbpbj5JCwvJYS@3cYixj{#9E;XuOACuQ)+6l7CAV zh@xrN@R*3UN$Zm>`b*ljoC-k}k#V?$yll5*GXWyc+C0}*i&6r z-<=>a4Xr1sl30QkrkcFxuTjuMP+P;tVJ3+>1T;Oxc^o8WMfM}I4yJH48inf(g!keW7T4HxXZ z3_(PM2MND-cqK^`q~UiDy>9Ul2{+UVV*J%r<6nKO#QNE+FXN*RvQe~L8Y1N+j`$62qI9U(+VB${vRZP z=p~M#Beg$m15qrWn+EkCl_e&5&fFH7QOaq*9=AHHl-*c0kWJavW zlIuqpN9*nB2~v92Z5@!9J&!h zI%X1ky07Fr`XGu0{vokRqeZ(Ug77?1i^*6!gct%7W&t|C4sk&MhTt#_Fq1Zzr@%5QI7H zkx4@0DABV?uCYfGRmWct*)aPjpP!}k=8Y%piy0`HLdNu#9J>TT04R_|LF%f6 z-E+{Qez>8TT2*?UUJ+*}2q>IPT1>C3AnUn$Fh(Z`D4a~zsz)zpZTV?B&8rbcCrAxc zchtG{`KOw$iU7Mz^DM{Y1hGW316^8MM4!9D#TL_=BTe(bWJ#PLOUUfAzu4;9S-aKr zsuw>>0d<0uBG^&?l(Y8z{eAU$e^1lA((v4uD)9ctLV(M#wLR`-nrAW2OA&-K8)sQ< zo4hm*TZl!VQgrk(t?9*&6wKDzT!tVds^;HKUm8cEAlP0DMCtJq8@(*fTTJsx@eKVh zK@gIML=A&(y~Q?FtEOEgUG!(QA0Hptzeu$7TUd1Wv)b7BEW;>^HMm`kAWh^aRnFyINAFf*jf@IjZ9w!KWRTKKVq zLC*fu6C?+eT7A~0LAiF<&f2OjO{Q0C<7?$dE{=2koFH?kRNAKsVm`e{sUDSv^G&S? zP^ChCGt_X$=?T)}x_`rXWtplzt&vwLL~Y@RTrvH3dV+wKrXY`O_Y|F7UuqJ^NmQAOOtSTZuaS98}xt z&m&>uQyxXoT`Cy%8G8=`{yq4y)rZRv1Yne?!MxJO#-~&xqX-b4Ue&lL0FF~x z^JCBIJ@s|#_e&9ED>yy3Pnp)VIBVDTWA7L^LH3S7rv0OwwdH5E3YrPsrfyDp(m zxTmKBM1U@)d9@Etlp6G>6J|YoFFzhHr29r*4FVR(;C@{R*xeu&O<<* zAOVSkY*QA+O3dMJoogz#>F)<_fk3)ftJoHOJG4zQ=>$oF>6ncm3TJu#cn!ottVYty zG|y^0OM09jOUQJ(pM=kGjebZVOKAl_SIiHQv&j?0F&`|BIYBH?Y^0+!se_v&w-Wf~ z?+1osDch7vbl>3ZDJi~|wsC@#B6#rrkR?==l*CUR?$gs#lM4l@{^YiEg5)B%L%*6y z2T_m|vd}Izd{w7YOs^PY9zp2ovI_!A&gy4o*?2|*S;hlRsWL6@!Hj*X`Pm6l6WzwT zIddbHW&=^Q{uwSAYi)6ex2ITP-~_QkvXLHLUS0gzE@y5e{P7w~vPjnhWMSKAs9l)3 zBtdjG9A3dwds`#II)g7xu^3OV2~m(hmaxC}7MrzgwA6nof+&H8OPe|izP1qN@Ys|z zx$CUzGHZvVg(#{3!w<%4C73Wh&Eh;@)Ez;BW7b(-KDrQ1bjb}EQmFQXeNo)~s z_!+WvWKEND`?bP8*Usq)VwIG+08jc=Cu-?*)#7Q%$Sf@taxf_Iddtoo_N_~MvEo~&usoKdQgs>tfv zNj6Q0Kj*{V`%X^~0Pf`s#~B%aYKq7cy^@t``}4xaDmg@;DsPNT^|N-nOAtg=WObTQ z8)y=#whasYR1L}Sm$=sSF{T!zU-P5p@kwQ&n<=OC3&<=BoTgbilwB@o??Zn zk)p$TOf6%w#nxpA0w^RYL?O6Jg5gG4tt~bXB{Q!cT}){F$`R>a)Ts)vnIw=yI#;i< zsm+_D%9wI+sNLsM1PNd&X@^&kLKqwQ`Oj1jHjrSm*DYj{Bu%MA4F100WynFyE=dpu zeso#6a0@Z&P}Esbf9{Z5cQP;X#UYm~o8HYI$Q>kWt@f(y-$%NEDt!99(@(59(Z0zw3VG?K;2(u?1{`{4xXJwhA&gAhSB zbn~VW1e_odaQsk@2(iTv*6~UaALSup$V$ibYjqc->`BXOQASxq>7FL<}C=@9x)*T@fT8 z$r*(A!a@|}6FdNPxw|_X29Js_#6Y^c+}|ZZ#zcWEsw{x#^7M2@4EQNZX!0-TK;ZuX009608-{wH00006Nkli#i002ovPDHLkV1lSz B7byS$ literal 0 HcmV?d00001 diff --git a/src/static/tabbar/notice-select.png b/src/static/tabbar/notice-select.png new file mode 100644 index 0000000000000000000000000000000000000000..90f55d6a22913338cdc4c8d2a710ecefa99664f8 GIT binary patch literal 4855 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 literal 0 HcmV?d00001 diff --git a/src/static/tabbar/notice.png b/src/static/tabbar/notice.png new file mode 100644 index 0000000000000000000000000000000000000000..3f9ef6064b0329afff50913d16b27a54c2f6f370 GIT binary patch literal 5023 zcmX9?c|4Te`yS)LBil3fEe0b)gx;)KW{hn{)|91^>}8Y?GKk4CvLstbNtDXIhh%9m z$dcEZeW_&M8iahkzuzBc`CQkzuk$(QbC&zQV=T;!I8F$kfWcrKcw>F5tn408J3^31&w{+jQp2KOp>m;hIzy0QJ*(|yU@3{Br|~+%Zs<<#oy4$ zO_J6LV-$s_ob267K6D2K;SN9?(!panN@9K61t>!+0dPkJW39`RX=l7y-JY9ckCui@j<%=vuYL;N+f)^pAlW6| zf3{cq&1_CtwdLxUU;1m;KN7yh%LD!><20S_07;P5_~aC;6_x2sbK#ckf~VmBk1Em3 znKCe!>SlHq#9nT?_|nuhKH=gzA_B-uFl7<@b8S0oJ4&9i>|wvg7hv7!1=K#wg4NM@ zZBJCbEBsov)I>fe)0fHewC8(tIwyk^jR`V30bh{3#xv`bwga<+2>KLqph)&^+dI}- zV{BqpIPWL*Xf&vf;iV4KiNpIS8ndE?)q=YIuS$kTt;G=2T^Bo|->cYs2@2Tkwof?W z8kb}8mRng%rqiyXa~-IaF^p-_7!!n;!cnx0W$`qmVcg~oc06QEPRY(`KtxMX5Y9)) zhbWp5UG_7S$E!@|Dk*ale2&IJ`tu)de`-I`7+M&PmP)&JjR%NM{IL>aEuv3G?J_o2 z=6v;6s6$cCwr$h+qlwW?hUj=$=#$5jMo2;cz~JY~PLSId&GmB;5H;5c3PQ1}rZF!)!tow_oZKAY??&in zd?vh~PhY6OaiMNTAtl?kN2AV0r&@=!kX^Ar;sFqt18z!4^%Fj)!vH7C zlymr`&#bewuZ_>T$wgqLaT1QTG6GoF6V+ zg~VAd94dX60Gb0afqiXf1mOYzg==M!Q1Oa2!t%YrSPd90(?r}ePa<58H56Z$S7(CORUq=SRUYYylCrzGb0m( z>`B4<7g;?zh8R^x6>u-n@J>{HsOcv(mL_IURMX5Jt`1DjX1=bGGlXb2Mx`bghMdpC zJ0%sVQ}icdMrb`K+6nLS((pqQ^1sXn#017ur!1aU?25~U2`-LEg7 z#Ufdj$6r?7Qvu#1G4HBWVo^L)nq_N^DqaInb$x<5*6sY|B_#ykmnuCb5qUGqWxD;U zxL(l3{fP(JmcF2&(^IscCeLjOb&37tEN3X}?Ub|x%9fQefm!1b?!>ykOA9N&D(BzJH&Bu1LY0mLlJNFHCWrxPlL(PtzwW%Y6Pa*qnu3Xny^iZbD z+j}Q9(moIp%OpHMYig{v4>wZR5i>?2nVdNW{Z8U2FkA1|9zoa}1WyY|5c3PMZ$MMo z&0Px5qT3EX)aR6vVn7D=wtn{hP$VfVcsz{=6Rk>98Ccw6%Fvk_9W?}A2^=D^^C=7A zs&c`Zt1ai`JhPY+8QBMCc^lSAtSvtdU=z_Vtme~Ir-zendU%ehCamD%q8!LnziQRH zAVpAIEB;o7;KJL~-xs(TU%i)7!~(Vhu)7jIJ(pX&_D6}+WwX`aQ;mkjpmi-Atx zFA+ULs--BX372^D?)-|XOWQfXvmlPm-f!+9TtL~TT=$lJWL=lAFWc(}>(SY%208<7 zwn>Gp`;1s1D%EBS+{`-de8K$f+d*y9x?1@wlX|I)s_(lK_n%Y+HcA-36qbV@CV!#?!4;!(!`^nlGuPqSB|;*f1^@Y)P|JDm(Pqk%Y5AES6OTP|GCKPsX6if^ z$D*&Y_DAxu5;{8)=lrON6To^^%D`fJ{VZw8r&c21!aXl~mB(5tQfft)7nP4<$;s#Y z+vZQ_&_G#=)1_h`AE>aP#&2vildIb=Qj%u1B+Slq8^X_2=|lw`7JL>%F=sG05CtOyG~@8A-DO$8}%!;WKo!)%_hw zVX0{E#i1XbF)TdTZ`Nw21^*PfDN~@n93y&NHqSt;T}0sk$0}l4A@wZ}HtqKD@w4VB zJ9=O$>-X~PiEpi8hSFW-FCj%9Y~}kv&*9yiLRS+of}nsv|BB(?$k_;1PD*}aPhNb_ z=I=0d)$A1cYR`%i1Xr*3wor7F?ko&y?<{z`a}itac7Qg?(Bos}ox@ zc2)I?_lEk~e~bu(w_eh9C!Do1Yn|uq!CcTV z@y+-}hYV75y%4%${QmM+wadgKu`wZR(6&9fC&y^_9f@ViR>Q?aX{PUuVIpp3>VZ#Z zp;bjh8$tSt>~p$UJ6NvP!V&i%ssSgPzE+Vpse5$s*829{!f1&;Rd^cq8{ORZ8&kQZ zZ(W)N4YY!{wza?A*v9*^?_E=uGM;O`rl&plHP&^TW}Z!$ZWHXyk>NR~qzv>#G-->! zFbdJy@jF#gJfeAPufoZHXoaL>8Uy;=qvcz%D*m`}f z3@fM3GB?aiP4=yMM^gO3GjT#J;(D{#1v4{JS#Sj?#0XcZT&waevMJHpou}YLGH6 zm+_ua`_30+2Fy@hL;-^P3xrMW7#pl{S?Vdur z(qb0??9C$P+{F0_f`Zl`S)k(J$~jVSf)0H&75OkDLzG==#GE;j-SDn#G4jm^qh9lmZfntgGisExn?G{m#^rH~wN0Q$LiB1%TkR8hl~Z zNA1q*qi8vnwNH$=0XJhG$FXeP2V$R^yY9)D0IWkf#knVS5y&vjP%HlJfZq9|ZHvF7 zjM&P|VA@P`WwP$Xh<487HoI@54F|ehzsuCxX>13E&0XMpEEe_(a#8l;y1iA}h`F<^Yg;mrf4xf#U1|*V z7sJZWvPGy;l!$-vPcMHJ0K*eaQKM5+-(Z)17jK$c2P<;Vzw+|l^1taE4FdCVYH;&% z+a7)PGEbguoPJsWK3Ox38R;)FBMsW+Ra&`=J#I>7-(her(TSHWDeX3aZr{3OXNDU; z*P(|=SH14e#HHNBuJVkL_2;K+cyWDTUbO zd5#;Nqb@Q;+~>A5n>Yjta!8~_mD!O_Dt_Z50qT;x*8(Jc;1ZMo z%s-y-dDLEf&muI4&>^-^Nq~g$Nw)d)(UOXQ2sGugrdX|H^$wbsx8n*!KGe%)~b2lO31Kc3>4LBwW7c}pnt?!a#J7hiT#BG@R*a-s5m{C4-{<~ z&m+ty0dB?AmKbs;DrvyOwQ1oeTfr7b?y<)pKpHf_ux;HozZlD{Z#VzY+D1U^*~%9X zx)OcV)P{A}z*^kK-LVo%PPJ zOCXt3F#1W>GeNj42&qxc3E5U&1qdKgncG?8SilKFI#8aaSCcB=5g_&^+qfU&R0x#7 zWI>8Ks-&somyx~2Bkt!hXsZ{ti!@7H9sKAIVwIpdhHzgVoMQs)E;jf}Nyv*~?elTS zbXG8|xi&@u2B$LKZNAUugT}&OO0Y=ZWM3(aD8!|Zxwn0(zdPGS%@h*gEL1h*jyB9TI*@VlvqAV_|4)Ufyzw4OT!OyN()+x+=xSc< zYWu|ZhRZLxI!+gSJ;O8d(g4w9zH8ENioeH&u>tOOCYuIoQ5eTn&R0K#*)bkX=lfT7 z{+nk)R=;=`hH92r%{=)S2h%kki3q3}Ue6g)!780dLPuU1WfEjL!NwPw=y%0Tp?O#v zn`H?_Rwm>g3#~p5J8L-nY+WTn6G_Wtt=Wl3*90#APKcy1;e{S1-FjQ7+)h*{tIx%u zIb+I=jM&!|&ig#evDH^WmkX!;q=XKNgaVB#ogEuc%Z;}MA9UGnc4k& zxZemxI;xW{Bba%V^+8Ir8o!w-yMRpoDGDPNyP@1G=Z@@(gm`3aQ4!7h?9nkNk0c#| zz1YvcuT#j-InV`L%%Q1Mn@Cm+)?=1QlZET3kb$Ndeitk<7Eb&_{Up$0JSB@;*nRZ( zjLCvWUQ;c?35bDps7RC|+4Pzu0PzT{pM&;#`oA3p(XzOg&$gvaMnYROl;%8u4w%=Z z0aktGIx@Z|KQ(jOy3e74BRqCN`1GInFYP`*O;#4x^mo?qFvJ_9vi@dpCQRP@K=(Mi mc621wne*Ye!~EZ!VuYPG-FEZhZs0#gV0Z&F{bD^w^8Wzuf(V}g literal 0 HcmV?d00001