From 0735f4173380cf6de5f62ba8bf6482ef2c8ac06c Mon Sep 17 00:00:00 2001 From: xuesinan <1404152492@qq.com> Date: Thu, 9 Sep 2021 20:10:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=99=BB=E5=BD=95=E3=80=81=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E3=80=81=E7=94=A8=E6=88=B7=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + src/pages.json | 29 ++++ src/pages/user/accountLogin.vue | 132 +++++++++++++++++ src/pages/user/agreement.vue | 30 ++++ src/pages/user/login.vue | 148 +++++++++++++++++++ src/pages/user/mixin.js | 253 ++++++++++++++++++++++++++++++++ src/pages/user/rigister.vue | 173 ++++++++++++++++++++++ src/static/weixinIcon.png | Bin 0 -> 8775 bytes 8 files changed, 766 insertions(+) create mode 100644 src/pages/user/accountLogin.vue create mode 100644 src/pages/user/agreement.vue create mode 100644 src/pages/user/login.vue create mode 100644 src/pages/user/mixin.js create mode 100644 src/pages/user/rigister.vue create mode 100644 src/static/weixinIcon.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fa1bf4..d87b813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -197,6 +197,7 @@ - | 角色栏文字颜色修改 | 215c6b3 - | 解决警告 | c932b09 - | 日历的更改 | 7353ac8 + - | 数据存储,避免重复调用接口 | d22308a - | 小红点api缓存修改 | e992343 - | 修改代码格式 | 14123d7 - | 修改定期任务骨架屏高度 | 909a734 diff --git a/src/pages.json b/src/pages.json index e260fc1..6ea58f6 100644 --- a/src/pages.json +++ b/src/pages.json @@ -17,6 +17,35 @@ "style": { "navigationBarTitleText": "项目详情页" } + }, + { + "path": "pages/user/login", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "手机号登录" + } + }, + { + "path": "pages/user/rigister", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "注册" + } + }, + { + "path": "pages/user/accountLogin", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "用户名登录" + } + }, + { + "path": "pages/user/agreement", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "用户协议", + "enablePullDownRefresh": false + } } ], "globalStyle": { diff --git a/src/pages/user/accountLogin.vue b/src/pages/user/accountLogin.vue new file mode 100644 index 0000000..4fbb66c --- /dev/null +++ b/src/pages/user/accountLogin.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/src/pages/user/agreement.vue b/src/pages/user/agreement.vue new file mode 100644 index 0000000..2383a8d --- /dev/null +++ b/src/pages/user/agreement.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/src/pages/user/login.vue b/src/pages/user/login.vue new file mode 100644 index 0000000..5e83d96 --- /dev/null +++ b/src/pages/user/login.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/src/pages/user/mixin.js b/src/pages/user/mixin.js new file mode 100644 index 0000000..707deef --- /dev/null +++ b/src/pages/user/mixin.js @@ -0,0 +1,253 @@ +import { mapState, mapActions } from 'vuex'; +// import { getImageCode } from 'api/user'; +// import clipboard from "../../common/script/dc-clipboard/clipboard.js" + +const mixin = { + data() { + return { + rules: { + phone: [ + { + required: true, + message: '请输入手机号', + trigger: ['change', 'blur'], + }, + { + validator: (rule, value) => { + // 调用uView自带的js验证规则,详见:https://www.uviewui.com/js/test.html + return this.$u.test.mobile(value); + }, + message: '手机号码不正确', + // 触发器可以同时用blur和change,二者之间用英文逗号隔开 + trigger: ['change', 'blur'], + }, + ], + verificationCodeValue: [ + { + required: true, + message: '请输入图形验证码', + trigger: ['change', 'blur'], + }, + { + type: 'number', + message: '图形验证码只能为数字', + trigger: ['change', 'blur'], + }, + ], + smsCode: [ + { + required: true, + message: '请输入验证码', + trigger: ['change', 'blur'], + }, + { + type: 'number', + message: '验证码只能为数字', + trigger: ['change', 'blur'], + }, + ], + account: [ + { + required: true, + message: '请输入用户名', + trigger: ['change', 'blur'], + }, + { + min: 2, + max: 20, + message: '用户名长度在2到20个字符', + trigger: ['change', 'blur'], + }, + { + pattern: /^[a-zA-Z0-9._-]{2,20}$/, + message: '请输入2-20位字母、数字、汉字或字符"_ - ."', + trigger: ['change', 'blur'], + }, + ], + password: [ + { + required: true, + message: '请输入密码', + trigger: ['change', 'blur'], + }, + { + min: 6, + max: 20, + message: '密码长度在6到20个字符', + trigger: ['change', 'blur'], + }, + { + // 正则不能含有两边的引号 + pattern: /^[a-zA-Z0-9._-]{6,20}$/, + message: '请输入6-20位字母、数字、汉字或字符"_ - ."', + trigger: ['change', 'blur'], + }, + ], + }, + errorType: ['message'], + labelPosition: 'left', + border: false, + + smsCode: '', // 短信验证码 + showInterval: false, + interval: 120, + codeTimer: null, + showPaste: false, + }; + }, + + computed: mapState('user', ['user']), + + onReady() { + this.$refs.uForm.setRules(this.rules); + }, + + methods: { + ...mapActions('user', ['sendCode']), + + // 获取图形验证码 + async getImageCode() { + // this.$util.showLoading(); + // try { + // const data = await getImageCode(); + // const { imageBase64, verificationCodeId } = data; + // this.imageBase64 = imageBase64 || ''; + // this.verificationCodeId = verificationCodeId || ''; + // uni.hideLoading(); + // } catch (error) { + // uni.hideLoading(); + // this.$t.ui.showToast(error); + // } + }, + + //有图片验证码的值 + hasvalue() { + if (this.model.smsCode || this.model.showPaste) return; + if (!this.verifyPhone(this.model.phone)) { + this.$t.ui.showToast('请输入正确的手机号'); + return; + } + if (!this.model.verificationCodeValue) { + this.$t.ui.showToast('请输入图形验证码'); + return; + } + this.getCode(); + }, + + // 获取验证码 + async getCode() { + // try { + // const { phone, verificationCodeValue } = this.model; + // const { verificationCodeId } = this; + // if (!verificationCodeId || !verificationCodeValue) { + // this.$t.ui.showToast('缺少图形验证码参数'); + // return; + // } + // const params = { + // phone, + // verificationCodeId, + // verificationCodeValue, + // }; + // const date = await this.sendCode(params); + // this.getCodeInterval(); + // this.showPaste = true; + // } catch (err) { + // throw err; + // } + }, + + // 获取验证码倒计时 + getCodeInterval() { + this.showInterval = true; + this.codeTimer = setInterval(() => { + if (this.interval === 0) { + clearInterval(this.codeTimer); + this.codeTimer = null; + this.showInterval = false; + this.interval = 120; + return; + } + this.interval = this.interval - 1; + }, 1000); + }, + + // 验证信息 + checkRules() { + const { smsCode, phone, user } = this; + if (!this.verifyPhone(phone)) { + this.$t.ui.showToast('请输入正确的手机号'); + return false; + } + if (!smsCode) { + this.$t.ui.showToast('验证码无效'); + return false; + } + + if (phone === user.phone) { + this.$t.ui.showToast('新手机号不能与旧手机号相同'); + return; + } + return true; + }, + + // 粘贴 + // setCode() { + // // 获取粘贴板内容 + // // 小程序平台 + // //#ifdef MP-WEIXIN + // var _this = this + // uni.getClipboardData({ + // success (res) { + // _this.smsCode = res.data; + // } + // }); + // //#endif + + // // 非小程序平台 + // //#ifndef MP-WEIXIN + // this.getClipboardContents() + // //#endif + // }, + + // 非小程序平台粘贴 + // async getClipboardContents() { + // try { + // const text = await navigator.clipboard.readText(); + // this.smsCode = text; + // } catch (err) { + // console.error('Failed to read clipboard contents: ', err); + // } + // }, + + /** + * 验证手机号格式 + * @param {string} phone 手机号 + */ + verifyPhone(phone) { + const phoneExg = /^1\d{10}$/; + return phoneExg.test(phone); + }, + + /** + * 验证账号/密码 格式 + * @param {string} account 账号 + */ + verifyLoginname(account) { + const accountExg = /^[a-zA-Z0-9._-]{2,20}$/; + return accountExg.test(account); + }, + + // 微信登录 + handleWxLogin() { + const origin = 'https://test.tall.wiki/pt-mui'; // 测试 + const appid = 'wxd1842e073e0e6d91'; + const state = 'wx_web'; + const href = 'https://open.weixin.qq.com/connect/qrconnect'; + // eslint-disable-next-line + window.location.href = + `${href}?appid=${appid}&redirect_uri=${origin}&response_type=code&scope=snsapi_login&state=${state}#wechat_redirect`; + }, + }, +}; + +export default mixin; diff --git a/src/pages/user/rigister.vue b/src/pages/user/rigister.vue new file mode 100644 index 0000000..2000b1b --- /dev/null +++ b/src/pages/user/rigister.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/static/weixinIcon.png b/src/static/weixinIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..33b679f55af78c2ce2126aa3202bd4fb5302aad4 GIT binary patch literal 8775 zcmV-NBDmd&P)d@Wk?mAWH zQTtS#vsSN8r}q9I-`-#CbN1Q){}a+H9t1Wa*T1`e&S++|zcyN%lhwH2^D=WZ;(nGt ztj!^CzchwH!$jV0VjA|ChBd9Wd(@-hOg6JSTgwg)&l%p0lTnGs@ZQ!!z3qO;-mgJl zpQSHgj}|a+7zpzB0s*`r?DM8vCdh;>! zP^x*S5wK8_0HDJF9N4C~u)Dni@K#A427bXA?Q!>X_g}+S(hKrZg7_TezP0*sH4Vp+ zMyG)B9smdU?5aw$S3&qWd;CPk!!sj`tIw!nn96pf1esxU%#vvn@p0tgI3_w7;J2zg zkgeNBza{2Ptl=4Edd9WgQtL9hzeh@t31e)OjUzS2QU;b1aCG+%{~I1M@EifFJ;G{{ z7ti;S@3Z-u5@bE*S)=+=Vv@vIl1>bOfHh3K+R0W|V*opQ8IztRh_%jIM9fQ>c`1PX zdU+De;`S6~360pujA zYi|%_4f;&OT&@u>XW+<0jgVr-67amow89ncie7l%($xf+w;uCcVJ>Il3m{+IrB|2; zY$c|Zrs1yG*~QN(T}hDsV*lGlNh}8-iE&7nvm%wX7XmK=Sea#G#c*NxwQj?wy9lxh zIcu(QC8$n}q`k;X`rMK)B3C&7DQ?2D?l~vcH3Z3(jb)yPD~WJy(q~$d?PtcbnuZ%I zd9f;=5BGbF8%06tgr%=5objbk)Dn}5jY{*@zs{;C!c26P#gs(e!akWaOD@72iWIO=iV=4iZ+7deg z4?4CuD|W3jC{%(V@>sf4HGTr%WL1Dk?dT{1n=D}0m7G@ytqDY>tiQ~Q8qrLF%oyGGwy*&_3e#-M>tdD z#UpWI6DvXVA^oU~M$g6RV5+OT5U6>4bak-$%ecIXjUc&V?m(v6%W*lD>giqth%*OO z3YAyl@Gu^N6tRy*hRi1Z&N!S(b#y%fzjjz0hXVd9YENS!h*dUz0LDk6b|#hILkJKa za`NJ%QF|OYL2_mDc4odXYDZG}y@vo1-BHQApN`V=NC{#Ujjw=kO_UC#vU?l>#tlwE zd@(8%A|puS$okz;8J@~b5!izO^T(q)Djx|!>cLJRdA=%*=Sb&q905& z878~iET)lwam8res_ z)fsS7ttkQkdvr;d*-}Cyh|F6B&6CHH)6_iaOzk8B0-iP)R^F{p2qH5cR!Iz{N!>a* zFH+s(2*~7gIvaywWN-|HAXeE}nWh6xC#X^g5bkpFLe_~1bOk0zBa!s#KvtxkQv@PF zK-RnunlL*ULB>iDY)rGPM=-jn$S@Gt?Ccb$1}VJ|h#*$U_yT|%!tf-Oks=Tg0@paU z_-ebd+a^dO8;M*!(&9DkqM!DQ1A$#0J6vUTWk=hbL>NNsM`~tuMttd%g+m`@r0QhI9Wi~jA9r<_Q%lxUifU4e! zAnhaqpUl9KfrX|5T0!8|EE@}3dBffkLArQb_hm3Pvc?-3v{B^6^R1xXZd>ay>yOCu zPGF`15T6Z3f4j2Me!dZCY1`K~K^hs@lFnxX zI0uYFJ8DdKD}T|_#X`TC<9!n(S2RD*#NX%&>|E8HRbw8&&iM6lBm5ncK9L%zLF)?2O;J~nD z_o_T*`m9@UzuCg+;YPdm0aq3spKT4ybS z=arKLjGu3XB>6L&t!Bx*h``_O7JoY8hov@=#jbbBT5Uer24)?=PkHU1gEe(flZyH78YV;tjs*6p)z z%@e-_Xy3ST?*e^099#1Yo+@ivf|w;^3js%mq&NaG{Fq}`7eyerYec5Si&`5>2A*?m zaZFQ!m}Rp-%reKW!k4zlv7N_)8rWCr+kccsk0TGKLc=@A3ZnY$6@zba?ds=) zj$N)~e3*e%)5>WhG_xIhBsny%Zo?5#*wI(i7kWhh*p6*I+GnrZtmz2y698u@3eXFN zC*Je>LA)NszFEmJE;wS6G$lvFj-b1AR@wXxm_Hc=uO90AsAG%wPxN;>g8WX|(rJvd zor3s&paC1J+5Rg42RD^d^9G#7qZ^vGYomehPC>LChm)=%Ee+1=jx8o_kxwE> zu9Q86p~-BCDqfo%TLgXy*2)eKGj4VZ;_@iKu*$|Ju+Nuz0g0NfBK}8^;GJ5rN1qt) zF@+$;6%5?yUtEkW8Gq#zMBvk_xl&6$u61k?$?c|9GT1kI0SS_>BEFFZ0asRRanrN} zG0VnkVw~w;TzoA(4M&8ryJVI0a{#*6m*qr%>*U?P^wqY-Mpj8*577JkbYq?VyF1|i zi=VbLwMkbIf9NscVK*<9PD>E0WNcUSa3XJT?CO9&7iVwPw@yFK^XO?mvY7cIw@|&^ zPuo`8m__3oMDVp6=jdV%27<-5yl<6i;1X*S`^{MT-wdTAI2WJo-i!H-!z0b zS2g`w2AvMzT@AVNKL2q~!_85XW89B9>+lxA#&?JzQ~QjsCNBVdvtw894$EID#~d;T zN#nI)%Irp2GD@>zS1*~of|T@9}GanR&7P4ANKDkMWq4OvmZyLT{GbD;N~X?`;%~!w6(+XH^T9M9 z;Q0XL&#b#-$@e}Q4>aOqNAgt}_5tLI#z&d(U^J=%NG1HclNZg;Oa)Mp#I9D+dI#X0 z4A6U_u?@x_CD9L+Z6?OYDh2U_IzgfRo;omIsU0*SLH5K&tJJ>_GC|^KPM)c z@qPMaXAA+tb})9ZhV2^j4rba8;vEcayXNs6FGKqgvwRUIv(@ZRz%!UojnXP)M5sM^)%+8)F8 zm}dy%eWdYw!Sp`0BTC!$vXzcMaBT6hIzh~m@hky*g&VdaEt0ko$7Doea~MKruMtuN z;c>9H(aDcK4uThk%BeD}_13|t)=mRyr-E6=NW47?J*vuNV2f*uW5-tzxr5cGoUuJf zkb0bm23d}6YL%(`;c53cgEObejB5P$d1Rk`YgYAq02hFIrux;0V~c$Vn~<}Hji!Y} zq5^+bxjjUX#!li502WWcWSEHWCdNG@cD3`Nvyb9Uxr})MgC$X>4-@XlM2SYJ(=Ym{ zQMva2MWZ61)E*&7qr`+H$D137?E>LjT%&v3!C=SS1CGG--B-ad=js<|M4#;D!;e`u z_9bhbbqG99o+?%E>T-hg{k(5K&l&wHfRB%ZPlSJ<8ecausD7EaxsT%yL`DCyif8yj znarAYDCtA`Q5lWe-~9;1lIev^4PJ>*RqUes)){Ad9wa&5Sy#>wM7XwM3pFD;XF(`e zHkL8)WiS@R4rGK1YaSm>&5m40sNaw1mmFKX!%xE`wK3P3AD|jP0)jSXH$O%hzP56D za;ss<9Ah5Wz6|0Ek~9{x*(&4HN%bSpjxPRSrquLF90+U3T7-6#%mBNl>R3d$gExMdQzzpl;EbfC&rKfg7;aW=};X^J9SD+KuEG$J#8J zA0*=Y!I+~G{;k?Vj1QAl(mxK+w6zgh6&OYPC{yo5Ved>b8<|C9Lh1T3YIOMqM5EZ~ z{Q$i!PMpKl#pjV(G%q3IruCx3Ros%aUpuxqyrmwBH8zHfBQ(N~K#hmkE+@x0{Eg?^ z2ljj^C^jz5%#pbe$SN9FgX+5}%3j2LVx>@()piqknPuZg#2AY$?-6p04^;gHs7DX( z`Ep3o2r|Bq2!bSeQcbEv%Xq*ki2oUMj>r&UvS_q2P;Y(KzP#gaFZyAhuac3L#KLjJ*EpM)H{5EJzC)oy8pXfJ!VP2g+QUCFKX9@ zR{M?JVk!QRzQ?Iq3N5zkcwFtRqVatY&KjG`lT%u@YJ*iWWSN8yPuDM~?1?g)WWKK- z0dLiI*}nf#ymd5V$kWFOdYQ=QslUxTJ{rX9oP1TL#!19AInNmV%&}cxX-21WE>||r zY8FRMz*!Yr1d0mvS)1}}jxD~>&LA}2k%XGcs2w}}_Nj04s{W#Ik~0$$diiy-6Yb`# z#~)U!hCF>+4~3O4oZLaT?W$eA^6G|=N7yPEX9Kve31%-iwiwSN)-t?S$#@9BvX(n` zpu^aULbXdCOoe5;$2eW}EGO2G{t0OGw+-X(b8PV!LB`iA8IoLuCNheSEdrHWv&zO* zV0>*>J%oyr7j4H5<%aa*S))YkNY;;xUJUKJGpf z3L(`Bi2~$$md1?tZ*|#>mz+ZI!|)yWAM#EWW>@} z9(PwdU}_c=nCLTZKD>Vd<6fsA&J9D4Su%b+ zU4jTHn}Aqq2TUm)a@)lBFbd0r4R5YwJjcLM zQm$O0tAo{FhNZ(S>$eiq=O)PuVda==pIO!~B&Ml#QSL@fyWUysycC8%X3t&M z#jkxfkF43Gmu!ryor3s!WXifguvIcD^7~muSEi=@Q8RH|3&=5(?H1f}3td8Qnk$>1 zW9D1O7LedC?m{)N;ZJ zfG>6vEk$e6)Pb0odQ{ou)$I%!XvyG`tUce6^yUqNO=QSh2n z{s0OW&}kRDPCNrxMdK9^4gm0Pjx7#p*Y;lNXO;E80Mk7x`a7wBjx^9xv;bkdTLz3ECYqRe|Mq96-%~MLS)d`|z5zltPb8NAvf^WMrTJ2|* zj9rb2PU#Bb13X#UK^|T4(KO~J(-iSkwG4Ed$o$5!MeKn&6K=86XAmC)XBGAHLA26G z(^#9#R0dk<^gk^k^mmReVvjknN`?%lt!F(?cd?p}n7W4+`MmKO^?PnZ%*V__smA}( z+^qz(h~RvZAFn6uVx{jvd;n&a^qUEEnUAKiHsK8YH}`b6p3r^LeY#aLUIFU6Fp0hx z^nTZNAC21yvuym381jIUAgq6ga@4b8>yKl5yUL&pC+Q)l1vT& zEl0fNin#-!)oy3tEyVmRGq!l3r&>+XGv!3WX2%xtrD1wagFtRw_9XVSO{#&z%on+Z z>Yk(ilL*qcRzJ?m(9^0J-J(7IAJ7?^RWhyz;fpiq*a2V*7@OdEPk34FcNs6Uvr?<< z!WsDe)IO4EOtqKC|KF?OD6v@lQ;YWZM02ZbTm!~eRC89V@$n;ztIte(izWZlDw(hC z$v&={^*-z&rYkB1_Z!Wc*1zq+-vrTEruEjZVGw@DjQ=F?PB8tfE`o5~9#Mp^J9#m7 z%avY}5K!~^gMRDS?xbYfd%aA{6^)0P@S((xXOnUX)=>5|XqsFx?8tp2{9mUk4o+G| z$f$8K*O`Az9?PTdN?pWwq*4%PPBdySf~dOm`9+dAb5NyFk-Kq|zp>U?hmcqMThGkx?*vFz7q6{jywp*H&Ao4@AWNabe z=w<>H{d_HJbh}2{79OpAf;B85#<3l>mH987LUlZmTt`jmv~pFCG%@g;Yl~y1;xp}m zKC5J03*h=rgV{Cu881;Sb6T$lP$_(RS5CF-99!%an=&myd?qpOn)w@tBLu#!VplJY zLzk*L)ZDomL(3z)Tja&_zE%*~C|5H6o`EH*f}KRWI&}m_1*}xgdqBXNiY-1k9ZoaG zOj!Q%w5ou8f^49Tj_sb7AcI3O)hHTgYJ}CH2#Z3Yn`XC!)#R12L@I{ zqpRFS?r&7IuT`5G70dn_z;Uhijk`UAFLdqdoq-5~^~mO`#(O?9TM^B38XNdT3nkh{`4~77PZ*leNRm}!1 zn3nK+=hkLV;*2J95-VLAZ=&bS^jWvyezO@GO>eR40>&~g{sO>Z%><^O2StE45aX&! zp_+(7m*d`ArFvE0g+aZKssC2T6$`NhBhB>rBZ%DcEt;Qa;--N}%@n4e`#^xO8;sj) z9zPgng(@GK+iqeN^-qH6J8cVyu_G~EUMaY~Y9#t5$h`HK=Tz&fNSbpt#=!*PArE*^ z;S%lK9+NzR*##kxUlxBp90k?dMLx`Ds*U_7(Mo zo_wy*w1r^qBjVdC`ReA`^eMiIyqaZWVJlxSEfJ)?ijG>M{o^JFz0=6?CQx|Oqu!F$+FwuN4%?Efs0QvK#Hc^sAif*26 ztJEqPvY@I`JD$vV*4-se#WKjkp}w!y2~t1AXe?vKL%y}74Z9ct-oT{Y?B?B{j611f z><1A(Qpt-|tqw$61Zh05-v{9ARu!i0yA=Uisj+v*NTK?RN#(HBaQA-47U#5MO4|f6 zipIM%!bTOdQ?vs_+9wL;vL=db(#+qlyRpi9z{7WUL2(*pBW@l&p!MxV4gkS^#&{s6h^i+;FZWo!fU*Zwa z7)wVA;^82U1SUxRR;z5R1mpZ5hNOK{1VTlCaF>%87X+0V3PI!>_9}@X0`|&G7u3MC ze~Lh>2r#fkXJfFHH|8_x2!$Z^RbDcat z{@XWi89G6*2{~)GSp;#YX zZe~FGd5S;?2)wR=3nO+_hW&sScV$cXX+fc>L(D3#w62yC}>afIK@BtZ~~g&@+vM*PTLC9Z-P zpZ4ud1U$x(?Z$Vsidbv}k%pN=<{)XjwpAn3_9+762(U+s-9c9#X^Q2Fl^|o!Bl>cH zz8i~osgf>3fIs2b)fI6%6+1!dBuP^T#W}{^p{tFQJz+TB5rWj8Ny^5DG)ACcmM{QF zWvGvUM>w-nsaHEj5IHRRkbYD~BN^nMUMT|8B2e@A=uRf^?kGVdBDrGjK&F~JxAo3+ zj-&`oK;YNJnL?#dd8L!6bete{=Zo0K(&}NmAL%3*scuCOAUx!F;sO-#U!Ar{4T3aK z$d%38nK{(+{GA3k)!!NdM07_b?mqron z6o&W85~S{&4Bs6#Z%t#|!x(B6Wzd~Yzk6xeVX|R*sy0Cyo;I?j+>)jg3UlZ?Doe0O zmxY;qBr0zbL6G`$$&fX`ns-Z@oGz-V5RY7$)Qvptvas@2MQwFr2qJ-~*GSZa4C77H zoJKt}qL5FxE9)6ohmr9x3iGCunJ9vcJJ3j&ePx-C!QeVz{tX)o`);b>bp@*6@PMNHCau=jqMc7^rs=-R$W7o#%)*5nrmDM zf~*U1K)g`)ytY@tSn2Gl-%hnuYFTCERE)Wr00064NklcBlN}-jxIycV4C&a)r5^i6v2#Ds1m}fD~@Gm6%qVhPxt;^gErx zp{oh92h=s_GYxaOM!cMXBRd6lH|Qncd5>v@E8G=Wf{||UX*M5vgCOGwtVhdOgq z9)RP!eQ-ne?`Z~q&(*6dFo4mJWh*PLw+J#}7_4>HB4S?3%u506r|bxI*03E!w3>-l zJByrkoi(L1+IyBDd*EJ=dDf`Dl$e$>u%t7?pq5qw)-dsECtF>O0qj)Ex_GTg2{Hk1 zqih^0Yil#Glz^k-9g5CsW8gUgR?C|AA}`Vuv5nzK2{OaHG|Ogzm`?y8e@^Ve=*HIp zYzFWY6FueTU71-Xy`~_L62#|}$d$6E0NN=Y;UwZZX_EHbvV#dvX^bZU?}>^%DoawN zR}%zMg0wkB%%7SIsOFtQjAIyB0FZpoa$uX{!tVA8z*`B}#)K`L(VlSs)ZG@gl3tLP z5+uw~UW2|qOJBeqEnp1`z&K2jhw21EUzn-@j4-fGk^qFQ22XR?{y*;;mZc+T){mE*YMf;0|2{~tbO5j7*UqP+kB002ovPDHLkV1l@1z3Bh| literal 0 HcmV?d00001