e>{e-R^+L&$->POt)M9iXQ4VH+-+?@x@!R-0m>`tAdP@ zSB+VA1%17KNLC*XL$uZ@2Vj|df;71`4O+5i)BJDsE0{i&UKTzjpuwG@;?P# z-X0!P5#$^9n6(}LUm)Zs7ZiL6k}D9bK(G$MCIs~e8WC(mup7Z11T6^2bqKi_IfCd( z1g8*mAm~DH1_1_;JYHGz&mo8)=m&5`4q(XlB=UtU+8&g{(BFf;yhzRFl?@z#Bdeq2 zyb-fcW3I8Pan}Xc#LkOrrjE>HHw-k-W)%z`8a^>};(X*hk6&+2 VUX>r CV9zX5G|1yWFN_tB<%}0!D4y7Ov3zRT3{yX_ch+7wcp4+xv5Ya}c*cc{ ziKQ3qQ~5LYx`D@Lt$BkRhPMoDIe%!hZKQ2-*^ISjVE1fxar}X*##dcfHQ76py%`=Q zr}TW)sB6SEwsXAYLJQ20Q#Y_L@qqkj-$>tN(@fR|cpmk!lc?&G7{@a&WKJHPv2TQD z(5J$t NJ;HTO(Vo5LCmLYm3EB~F9dTsEO)noHv}sLd4-nq8$q zZLT`ruSD%vGFL)q26JVc2DLdlP74`SV#uIUYgJ;cN(&}>1`|DxCa6af)FTP%kp$J9 zpt=)O{k~0!zD-JBlX*$}xu6Cq9eL*zno*^h%mr${g7|J4&G~T})Z*`yX)cS?pcdav zy|Ec)WjCQVSD>@5yqoFfiuim`o68~nGF0wBExtyY*-85S*$6da3yEsB!s# )CPQ#114T NKe`328*_6rxpiBDN8#O-+=jWYYcsY0?;ffi?+ScID_Pm8NZc{k4=(Y3lyi&V3)Y z6JCH8CUwu!dFR}F&$;*A^E>C<>pvG3S`a*se)^xj`9g&LP6YKaD9p;cz{C-YSSo;m z$c-q%(*Y_-yJ?Bn1$05ZTQBkYfFWpf8!1GiLx?q;L#&b0`-@bgx%Zq-=G{!p lHYG4|2epB3vZGheN>9Y%fs5iT-G?*O#+_kVz3%{s!jah(m6QMQ)m<+&UV; z#M0;GD =nw4SciUaX<5pQGefX@p&4gh3sVoyGD$n8o 8Nd!AecvLjEf z2Dvm(t^s*Np1dWt(N!jzTEf8~7ZOC1Pi9U)W+)iIe9((yo- P6n>XbLnwt*58iUtDS-T>!QQjzpwdZ0vJc^OC?2})d}?05U~M@uRQ4O7Fk zx=+U;k9E3eY=l11%11oW0cFW9ov4p+fj-fkU598^zJg~X#BNPZ&DSmPZfWW{32Tq^ z1f#KN@495c5CbdhTBS=)tc(?YaNU_`R`<_vSyo|M^1CU^v7__x1$CY&5|2DCX)0 zVwfb|p;Be;y8MNdK~IE`QM6<${ctd2t4-Q!r`u=vl&vwrG_F7w5)IM{M5|)bLpBq( zO&{ |WuFpqyOnsn;$h*hFzUA+pU&*cNK=NiOHCv771-0CuVLjQ+VI51$ zKS9m$$j{_!%e;!lXB!1MUa1Hp1~U?})xrO`VdN*@vgR4iW^w9i+O{>SAgXJnP)uKo zglrwzhH&|aQE;dltYMg9jl;${WoIeW1toXH_<=EIlHY^WAbL;Ng$5}X( |M`cH?tb#Kdvnt~+Y}|Pdhqeo{VP|R z+F&JQ{i5zPCt%_^OaKmx6?~!aASV76b+9VYNC3tQqPg`wA2%RC#TN|_&mqBO5_P^n zMEVxIiCCy0MEX86QKz^FnGu49JeZVSu>eeZ6vz%aRP^UHZh=vep92|1|0pSsS4>n) zzLP51ao)IOcTR6ya9ux?INp`$^(}7Sv9Rar8-FRkU45%M)$UIBg))87WM4GZH~2_L zIbzg#)3V-Zb}m_q#yiG3#yiJ4CmYh%T1C!SE0fmBw6%KCQTDGTTlqsold&ZU`>q-O zs`L6AX=~e(qx|2?25A2#LiY7f#jiCNp&Lc!=6c 57F#vkx(sjxprEoP^ z0sk7#MmZc4&3$}8;IOARCNg2nN}P KwfKa^tL%rHli%#kmcPE4X#+fSBfNQK}<;@35gy00TN^k==38{{WZu;zh6 zq?9Zzk3nJ~C{XaEmEwf#S>2yaP`N4m*(8-~Q$3uWcSEjE< jEx$?5#QmLfVgxyXy6|~gIZAKys&YV z_Xl~QUn*!rRhsC?_DhCNfi=h$_R{$7iQUt>&zQ?h%I-RETC~~6V`H(5ttM%!nJ!D& zTp8QGq;20-{^r?)ZC}dvR>tN|+T7{x-b{Be*&WPu<778Zbqgt5G-Hb;ZLyT?{RH#= z !9gk?csq!*O4Jk0RZ+h|*71<^o~vj>m8wrQyY~|- zZvt5x?YtE2FJ+j9B-3!!@yDubRW}{Ct8P^#-swuVcO@F#X{LLLv5Z^BEE&d`WSnWH zV$tUK{(27%I4{h5Xci*35w;D#LI_Eh_*Ed94v9p2pX89$-Oa>GE0AY*h`T%4-koUd zNi(NbIphnb;`{3j_`( Vs8PETZpI&IxNPfZu;_Lf?gu|2ku%^G07&}PF`iG8h zdpP`VWrL+(FrZy|6+r^DsD}#)_f$kX6vUFj+0%c;nlg~zc@nly^T@Zh2$WwdzrN+F zHO;hY0=Uz)Rb)J#kT=MAJfg+pk?-NaTRon$QEx!$DfD;*@?V22%EujJOE?e>hD1|4 z+|o|NX-7Kj8jlNb`8h3G+QOLQPlpb3vD}p|?;5n306;31Qp}Tcl*k-}JKG8P`xMuZ zUUJou{ss`Om M!{b3gGB+YvWA^&~g*9bX4NDCot zgtP;hm2oE>tK@?iITVniXyhT3^>b*kv~u+5VzKiA9XC&yC%0bOIkj_PTe`Smw0*H~ z aHo*bo0gCGnF&; zE0wdAiH44p>u{?02$(A>JKsCbkMWb{N&1p`$~?XGV&TH}bW!8zA @xrUgT~ 4LXM55fRr$yc<+;9SuGw@kR@O;Q_WI7TUrgjGh;@aKWjN?4^;XDC$~ zfm^mp`m|wlcHri$_S4!{>wZOp6)6o#Na%E# ICvf zzWfiF;b@rU0y2(BP|C*0RsI|1ReAW2u^U8kVvN)RS=Lb$^(CsjgPeDe<4aWa$asvR QHUkj)$NIlUgqMu`7x+fG0{{R3 literal 0 HcmV?d00001 diff --git a/woniubiji/module/__pycache__/credit.cpython-312.pyc b/woniu2/module/__pycache__/credit.cpython-312.pyc similarity index 61% rename from woniubiji/module/__pycache__/credit.cpython-312.pyc rename to woniu2/module/__pycache__/credit.cpython-312.pyc index 83cbf574103157196d755550bbe4f2d6091f9c1d..10ddd6f9a9bd043f22a26fe790b95ad136da34f3 100644 GIT binary patch delta 538 zcmdlXc20utG%qg~0}#Y1{!J6%*vQw*!X(c)c`l2)dvbnmZfahMg3+_hE1tIXq~;an z=j13DKcBh#>E5Y1`RSQ?3MS9GraoV>zqm9hH?z1nGe1v3!Sva*_UEe?yqwYcV*T!- z)Wnp{+^mX>W?!9vb~szbgche3702Y3R+h&2=cT$7WtOGJJX_fFa_*v-7jvdR@0|U7 z&6F4GHpG DT3DJ|RC$XtEi J7Dn~W%Q;yYc?DP{J~K1034UY( ovL^53GGjEJ{DDh?(R?x|w~VkJqeMqge?(`*R|X)nNCxOA06v1RQ~&?~ delta 280 zcmX>nu|tgSG%qg~0}y %Ttw+K5`OMu<_fAzX zdDb=c`HKAt3Z~DdwLf3I;N^_g7wdO#)@D^? ~hN0Yfo5~%VPXJS!FW^zty zX38zLqSWHjoRVUY36n!P?HH{lPvO)QiM%Knd08;JgY5>lV29leVetpT5|cT&wlFGh z-pj?x$ji+t`I(u4P4FWVkTv-{x0#ea(10Qt5FrI5esS33=BJeAq}ml3PnPGA5!Pgs R> @&sx?KVGpeGL zUQ%@!$b%mO%o+kXL4(;wH^dz_%!ZA{1BRjxdnlHd4ttmcX^_BWK!G)h{WNDzx1j@y zolA =@g~X5!&LJ6r;K#E(+1;D3V;4k;KZbq_wiMnBA{1b{}yYZn15H2qI;2Qe2mH zMU{bX(_~FkGHGCG>0H7#x2d}(Z1FTXkBlOegd(&=MHm{j-Vd~V;}SM6(W}e~tU+3& z?NM_reWz{JNF~<_Wy_XDpmEIRCDyU1@8W#|ySN|P#rLRP9^r?!Rjz(QaOxv{xTnQ8 zHqPz%Kj!-7PRVl_t<<)N2q1eK 4k$tI z);}Qnb4agY0HI`~m1T+`Q=HgL(YmXqM9DUX+wOC9OZ>GQN|IfgTGH2~05M1Bs8!mD zU9!D}1xj{2td$t0z8{6sXLTpXtraCk7o0iC7Pxj|^xs*nx>jndPceFTeO-rX=#xDS zLXFKajt42^L64aqe0aWdRtgzyPa(aI;6a3Yr(Al!Gecr?l;qC2R%%hA&=^#=Dc28N zMw{JFQj_Q+GlnK9kqet{8#>E0CQdg!b>v_I1Ch1V*iXi|L_D34Q?g`w6Iia5IMbWG z;FP;;FPPoE{{H&h?46(gdi^)Q_}g!<-2L$n@2xB<(omLwW#jt7`pug|qoN;^^O?+f zS;u6+^eI}*LAuGlm6fq!dM1>VF5}oa1CD9!f=T_t1h$~j6Y0z(CNVLYxFnhGL`GE= z-Sm9>VnV*4L(w%^$d|M(vL=&AY1UWR-$P(&QnE%S?<4KgBft$0MPGqL(xPhC$VN}4 z mTaMm+@5;tce->T;$=tpCyZ2VFum5T-I+;l;*=M6_M#`q-sB`cG7Yx&{q+t!c z{xO$&om4*1G(s?>{TawK`b6lR>$}!B|5{1dKjXgb>#Fz$ioStGPucgSD({~i$&Xa{ zfg(S!wEKgx0zXjVk5>3_kq;M6pRJsZ7EebDZ;TgC#s0*9?~@*4G*Wo^OnH2wGOiZK z)zWz80pu8Ug#IV#PSE%5Zi{p$X&CDb(=*3z^BuFt^T%hy`SARqGC#OUGoGVVO_VylO!-GCrPR_wT9eviEP-0AgN{>r09-{oRti?3k1B2kllokB4Xp6pcIpg7a2?v zeH+Lc@fg4t4?u7F?F4NFy{3_;z+8J7$TWK3MuA`h_^O<5)|2;CxV|FSxA@hyu>#ju z;=WnoLPak05%Wj>_k7{i?-q`}R_4ZTbKY5R-do{ QXGE_f|i5eAFG;F9s-?t(B_5{^}ba8U@Cgwr$bs!y1C zq1x5^aaRu>gcWx9m>|STo-4pSIUidOO|lQP G&|rvh&NQxo^z3>+j=Uj*`akDeX1occ;dc)cjRUJ~AT*r{Q0m&wIq>9{J# zVx~71vkN@%d@S}>HlC`Dw8vsPc~RM-eFwRRGpVeaHrqzhx_n;7rq{U^6u6tt>TnaC zH@%?@mX-7A6SA>=vs%6|xg&6;j>2C9CXW_O-Ycdrk&0`YD(m0RNO&JnlgzaMhQAEl zGP1B>rN4ELT7+Dv+UGznqiXlw>62Aq&(#2d*Zi|Lh8Bj_o-YfBrjJ+Kch8)e9m|hh zHLl`0 I`1`^-}R zQs8F)a)06A@sfC=)cKw1k*dFU2G1IKV?J 9E7b~ zYB#;eE!?MlZ1)xe+$P~RzhLRux(>L_fTeS@y)`@FnsoPR(Almb&IpTb_M?HF0Drz| zzdc-PTuIxZV^3xzIb}PL0BYN*pK)KeA@Bk|3 _Z*Vv%|H2k9s;Xx_Fu#8)r9;FiSlw<$i{g $dA8@ZC#{$z5X2J>-5&nw>i|dmfW!*AC6zN7F1;E%TM{t^N|SzAqtL^98bB+vzE( zF4nq}yX>xfhyQWt`<$nEDsfjYHHhA8WXXD!&>o kG2Fca+MBC{0H$OKIH~)zp-n9HLS}N~&XCO_69D z0$CgrqEwZK;!>NnBWoy?z>96xE{k25#7Qk4j}FE$iK|3uII6|fAWJb5bv~8UMls2U ztWscny%!+T8-7Tk98s-AB1Em+iaCs%TY$)v!#BfZAgM)8 fHutizAMVz& zW69Dn&Z(7h7PHcOQ!61cpPe%C3|D?ThCD#JcBgdtO&O9VLFYN$WqRQ*nug*VEb {-2+&*#3LSv;*-L vSu?E_`4)>_ z 4yw zVL7f!G%}cm_%bR2Z9pLmGTH)Qk)vNn+=wgGr=STTtmpyQ^#;rPiZ*DAjD1@oW6N1H zs`x$thz_AC7nljmzFH6tPq<3Fcgj8KUgHC+d|=`EmEJrbDDWrO_|vQW=?|1Yj{jji z|C0;(u2+lvz;<8LR#5mKDrM}$6{&~2^}kZe7M*5{7$uD27)1pH=pBl^x>7w%H~TF& zV+|{(f72Ex+fELE{6+}CjshU(e;m$_$fedNZ#?n)pTGCU%{L0idW!u&UF#QD`^7^4 z@O_REMwkib#}7zu)8YSz$xRP}UG0fX4*`Q7M(_;;dk|Ezmp%pL){JemWvtC RhuPaUM;`22U44sATRz|`TFq`)rV7kSW-F@*=`JcM zFcohrcGa>1y{yBWsmJ_QUf6iYK(TTXK$hGQ8gk7u&1=HJRpH=r_ixWGo_(J$JoD16 z-u%zxysG7eg9YKrnvhu)G6msvXmeg+;$*45=}!ILuZroh j>mXfkT8!861aZjOK2Y@dy=|Fz)a_QOjb&mKCZ4kzP^sh&c-#q=hZeX};?`*T{ zx!``Ck3^EugcOPBo=C);X92H{L|)UPaqGkviKzIKWRm7^?dnLywM0^{>P@QBC5h@) zD*mR)qVDNRQAxg(JS(Ml3qZ5_Ho|A %{M5kYz% *U!FfRcV=Zz z(SIy^w&ZP?XrDShd3^eOE;JLmaj5A1cDA!5?3?yuGR?NnzcBa03jbd1&Dx@HDtl(v zlUq-HbmYS$MIn?uv(6KjaF6Aj`!_hi))8B;{#>4;au2Zenn$|lbT(Pf0BpU^kabzS zdn{l^QX4)x7p&5q!{F!3=Gcwy(jAGYoHV1%`ASNZ;-))0;mnjg0N6kI@0rnhlJ)?J m|C$Q&*Exn^Zj+r$2(e*<*PzIZA!C^Hath6bOkuOv%n+75PXyC>BA7)kSdt%nxxQggX>U=2 z_3#go@h~zk_+w%$5Efg3F-xK(1)>okS>ZI4rY0&1fmqk_D1_+Ct%m_eiAZpHURGed z29}7%pt8|I1%lGzl@jCxcG7TzRpnmuM!Jf8o$Uz58;q(eaFZr|oT4vj9LpCNhb>r- z^$UzsxUb@k#@XO(3w3Q9=_>Nif426G#(_0#S8Y*PiY39Fg}h2nnsr;1ei`F!Fbl84 z-6fU@Md!&4Z7JR@z*`FV@*)BfYk_1d@Wlmu1@N{4z7lwQ0bd2YqkyjlzNCQP2E4O? zuSt}8Trzh`5~(B`<4~Q1yJqd9fv}$@e7$1g;eTPZ$3e(P;-QfLbVvl+EQsCycqry! zsSTQCJ{pPl;q~p(E|IcByyf`+$P2|N86-hPys`*lk5%6wGs)zyR4{+Z3;N^_aEKjb z+sSnn9R`n!kNCslb%V^Ejf*rP7j*|hF_HRCCuFWWK&6<+ARD?u5_Q5@vWbckY(c{L z-EQ|MhoFA0p|dR!I}?q}{o?9B?u={9@sMBYUHsYTLh7xB$%~6Or#kzikwCnzGaMD- zA+Zx@-rJXuOS%IQ0cP{%moiX(3J-SgYIy}rC4C)=Ve-IPHd=Y1GUwctb?%xtlX32v zc77-4Jd|}Fnsz>$G|f7;ByEqNEBXH(tw7>TJE3?ZX(<$7>2jp;=p;0<+f8vBa^>pH z`2;Z}A{GW}*WbO~p$5nL1{A|&i6 op1j0914)i=oWK1qlUKJ%((VDsQ>hnN))fxrUjQNH={ zJM(YcMB@j9`OELjr+&9^abiAsTkp`&=coR#TkX-H)yu6^jKyiB!L91fC8rjCdVcQK zoyB*r=zTm!>Vhd{lL~Fwq>e?mfG}^OTA){$$f1}Bdm=ak!oZeO%dlJ)KaF~Opa65& zb#v5a9kt_zYnCgPiSDd>f1yz_{2|pITJ!@|0 e%u$NqN)M%mUOSiJx37f}dKm>q{{-T3 zmL1dmQ_uvet3E;ZW0UL+?U;f^t2zM-zHyyoWdkWQ02%>(WQN4_lx96h2OVqY%O5sF z5(bYkJ_J21I> $k5zygRmd^X<8xjL)TS1G{kd z(%g^V(>u()cX9F7J9D>xxo|iA@Y4CY-(21Et%b>}(06$T4eGjpB51+TShae1#rU)g z7>ajPHuQ)wz`7D*WRtouiU$u&G#n0KAX3~DdXp8{x2Z}#RcFAZ0%e8pS=4EVLcx7e zak?l~l;f+jeD&KeU3>Y;%TpE8yBjim^)%m@ z`WS=EAS)OI G>WVX%OJ-5Ro|eV0|Oj4*WMJ4gGTVH z=GIS{BNRP}% iNIVqKAFzXB=^bACafd!Wt3Er&k(ZPeI@ z1>Rx_F{t={H5gijsE>+00SRUwaH?1<5Pc6-UV{QWlB;_3@P)(UUz>J4F@84d@+A5D zj sD_~nE+ly^jL0cyq# 1=*OxsiTk=P8sZ3Q@I`081QD`{Qp3h_J?gw6u-IIi$<(l&ZHrn}3aju)6v`+|5+ zR(*rI3k8gAuDuRI^S1$99{hROR*D&z$6VlRFp3r+z=W9$SW*FjK?MOiD7qDjeBP)U zz7(vi_Lc%Y5hW@OROt3!)p82e5euu+zvD{!w=d^Bm~|eUb~YwWf3-UA7u(Y QZ3XMZMZe`eZVpENwM+SB!^`jP&>Shvq^ ztw}b$(fnZR_GHuR&1=0(Y5LXFt4W7q+g8tZnfLk7P5XSZ#phGsP(T;^d}rhSkk(@J z`C|CkR9P+7H$_A7a6~qrh{VJmkt*4OY-*3uK%_?r461wHk0+z}Xp9RK4@%~bK_EB@ z&R=o&v>qD{V1a3>Z0&+4o)i}0=_gPOxO5v9ZY*|V@l7l+p``dsq(`tg2E}!v>`HM0 zYBWJ#hN+zNE4U-)$!uBG@C&oH^5l!@j#S489UZtZFcF)v?H@iq>!?UlOiRZq$4W0( zUaB15_ty5Q-7}8*;pR=-^wAP9UgAPx-1X)Ur;IbU1D`RbuBWczxfxp>XjsdVb?Jkt zgCiXyFOGIx=opjU{QiVEW8FV|Y}Q#dQi{*hvAWBRml~(|+m3e~GtMK!E$g h~$!`h~t;4l N2@Qu8-rn
articleid).order_by(cls.articleid.asc()).limit(1) + min_id_result = min_id_query.first() + if min_id_result is None: + return None # 如果没有找到任何大于给定articleid的文章,则返回None + + # 提取出最小的articleid + min_id = min_id_result.articleid + + # 然后使用这个最小的articleid来查询文章,并关联用户信息 + options = db.joinedload(cls.user) + min_article = cls.query.options(options).get(min_id) + + return min_article + #------------------------------------------------------- + + # 分页查询 + @classmethod + def find_limit_with_user(cls, offset, limit): + ''' + 自定义每一页的数量 + :param offset: 开始的位置 + :param limit: 结束的位置 + :return: 查询到的每一页的类 + ''' + # 加载options + options = db.joinedload(cls.user) + return cls.query.options(options).filter_by(drafted=0).order_by(Article.articleid.desc()).limit(limit).offset( + offset).all() + + # 统计当前文章的数量 + @classmethod + def get_total_count(cls): + return cls.query.count() + + # 根据文章类型获得文章 + @classmethod + def find_by_type(cls, type, offset, limit): + return cls.query.filter_by(type=type).order_by(Article.articleid.desc()).limit(limit).offset(offset).all() + + # 根据文章类型获取总数量 + @classmethod + def get_total_count_by_type(cls, type): + return cls.query.filter_by(type=type).count() + + # 根据文章标题进行模糊搜索 + @classmethod + def find_by_headline(cls, headline, offset, limit): + return cls.query.filter(Article.headline.like('%' + headline + '%')).limit(limit).offset(offset).all() + + # 统计模糊搜索的总数量 + @classmethod + def get_total_count_by_like_headline(cls, headline): + return cls.query.filter(Article.headline.like('%' + headline + '%')).count() + + # 最新文章 + @classmethod + def side_new(cls): + return cls.query.filter().order_by(Article.articleid.desc()).limit(9).all() + + # 特别推荐 + @classmethod + def side_recommend(cls): + return cls.query.filter(Article.recommended == 1).order_by(func.rand()).limit(9).all() # func.rand()随机抽取 + + # 最多阅读 + @classmethod + def side_most(cls): + return cls.query.filter().order_by(Article.readcount.desc()).limit(9).all() + + # 一次性返回三个数据 + @classmethod + def side_method(cls): + return cls.side_new(), cls.side_most(), cls.side_recommend() + + # 每阅读一次,阅读次数加一 + @classmethod + def update_readcount(cls, articleid): + # 使用SQLAlchemy的update方法直接在数据库层面更新,避免竞态条件 + cls.query.filter_by(articleid=articleid).update({cls.readcount: cls.readcount + 1}) + db.session.commit() + + + # 评论数量加一 + @classmethod + def replaycount_add(cls,articleid): + cls.query.filter_by(articleid=articleid).update({cls.replycount: cls.replycount + 1}) + db.session.commit() + + + # 后台管理部分 + # 查询article表中除草稿外的所有数据并返回结果集 + @classmethod + def find_all_except_draft(cls, start, count): + result = cls.query.filter(Article.drafted == 0).order_by( + Article.articleid.desc()).limit(count).offset(start).all() + return result + + @classmethod + def get_count_except_draft(cls): + count = cls.query.filter(Article.drafted == 0).count() + return count + + @classmethod + def find_by_type_except_draft(cls, start, count, type): + if type == 0: + result = cls.find_all_except_draft(start, count) + total = cls.get_count_except_draft() + else: + result = cls.query.filter(Article.drafted == 0, + Article.type == type).order_by(Article.articleid.desc())\ + .limit(count).offset(start).all() + total = cls.query.filter(Article.drafted == 0, + Article.type == type).count() + return result, total # 返回分页结果集和不分页的总数量 + + @classmethod + def find_by_headline_except_draft(cls, headline): + result = cls.query.filter(Article.headline.like('%' + headline + '%'))\ + .order_by(Article.articleid.desc()).all() + return result + + @classmethod + def switch_hidden(cls, articleid): + print("articleid=", articleid) + row = cls.query.filter_by(articleid=articleid).first() + if row.hidden == 1: + row.hidden = 0 + else: + row.hidden = 1 + db.session.commit() + print("hidden=", row.hidden) + return row.hidden # 将当前最新状态返回给控制层 + + @classmethod + def replaycount_add(cls, articleid): + cls.query.filter_by(articleid=articleid).update({cls.replycount: cls.replycount + 1}) + db.session.commit() + + @classmethod + def switch_recommended(cls, articleid): + row = cls.query.filter_by(articleid=articleid).first() + if row.recommended == 1: + cls.query.filter_by(articleid=articleid).update({cls.recommended: cls.recommended - 1}) + else: + cls.query.filter_by(articleid=articleid).update({cls.recommended: cls.recommended + 1}) + db.session.commit() + return row.recommended + + @classmethod + def switch_checked(cls, articleid): + print("数据库中articleid=",articleid) + row = cls.query.filter_by(articleid=articleid).first() + print("数据库中row.checked=",row.checked) + if row.checked == 1: + row.checked = 0 + else: + row.checked = 1 + db.session.commit() + return row.checked + + # 删除文章信息 + @classmethod + def do_deletesign(cls, articleid): + result = cls.query.filter_by(articleid=articleid).first() + if result: + db.session.delete(result) + db.session.commit() \ No newline at end of file diff --git a/woniu2/module/comment.py b/woniu2/module/comment.py new file mode 100644 index 0000000..55e1ca6 --- /dev/null +++ b/woniu2/module/comment.py @@ -0,0 +1,106 @@ +from datetime import datetime + +from flask import session + +from main import db +from module.thumb import Thumb + + +class Comment(db.Model): + __tablename__ = 'comment' + commentid = db.Column(db.Integer, primary_key=True) + userid = db.Column(db.String(64), db.ForeignKey('user.userid')) + articleid = db.Column(db.String(64), db.ForeignKey('article.articleid')) + content = db.Column(db.String(64), nullable = False) # 正文内容 + ipaddr = db.Column(db.String(64), nullable = False) # 地址 + replyid = db.Column(db.Integer, nullable=False) # 如果是普通评论,为0,如果是回复的评论,显示commentid + agreecount = db.Column(db.Integer, nullable=False) # 赞成该评论的数量 + opposecount = db.Column(db.Integer, nullable=False) # 反对该评论的数量 + hidden = db.Column(db.Integer, nullable=False) # 默认为0,不隐藏 + createtime = db.Column(db.DateTime, nullable=False) # 使用 DateTime 类型,并设置默认值为当前 UTC 时间 + updatetime = db.Column(db.DateTime, nullable=False) + + def is_upComment(self,articleid,commentid): + return Thumb().is_upComment(articleid,commentid) + + + # 关联 Users 表 + user = db.relationship('Users', backref=db.backref('comment_user', lazy=True)) + + + + # 新增评论 + @classmethod + def add_comment(cls,articleid,content,ipaddr): + userid = session.get('userid') + comment = Comment(userid=userid,articleid=articleid,content=content,ipaddr=ipaddr,replyid=0, + agreecount=0,opposecount=0,hidden=0,createtime=datetime.utcnow(),updatetime=datetime.utcnow()) + try: + db.session.add(comment) + db.session.commit() + return True + except Exception as e: + print("新增失败,文章id:", articleid, "错误:", e) + return False + + # 根据文章编号查询所有的评论(未分页) + @classmethod + def find_comment_by_articleid(cls,articleid): + cls.query.filter_by(hidden=0).order_by(Comment.commentid.desc()).all() + + + # 查询用户和评论信息 + @classmethod + def find_comment_with_user(cls,articleid): + options = db.joinedload(cls.user) + return cls.query.options(options).filter_by(articleid=articleid,hidden=0).order_by(Comment.createtime.desc()).all() + + # 评论的赞同数量加一 + @classmethod + def update_add_agreecount(cls, commentid): + cls.query.filter_by(commentid=commentid).update({cls.agreecount: cls.agreecount+1}) + db.session.commit() + return True + + # 评论的赞同数量减一 + @classmethod + def update_sub_agreecount(cls, commentid): + cls.query.filter_by(commentid=commentid).update({cls.agreecount: cls.agreecount - 1}) + db.session.commit() + + # 评论的反对数量加一 + @classmethod + def update_add_opposecount(cls, commentid): + cls.query.filter_by(commentid=commentid).update({cls.opposecount: cls.opposecount + 1}) + db.session.commit() + + # 评论的反对数量减一 + @classmethod + def update_sub_opposecount(cls, commentid): + cls.query.filter_by(commentid=commentid).update({cls.opposecount: cls.opposecount - 1}) + db.session.commit() + + + # 评论隐藏 + @classmethod + def update_hide_comment(cls, commentid): + cls.query.filter_by(commentid=commentid).update({cls.hide:1}) + db.session.commit() + + + @classmethod + def find_coment_by_id(cls, commentid,userid): + ''' + 根据userid查找用户 + :param userid: userid + :return: 查找到的对象 + ''' + return cls.query.filter(cls.userid == userid,cls.commentid == commentid).first() + + # 删除评论信息 + @classmethod + def do_delete_comment(cls, commentid): + result = cls.query.filter_by(commentid=commentid).first() + if result: + db.session.delete(result) + db.session.commit() \ No newline at end of file diff --git a/woniubiji/module/credit.py b/woniu2/module/credit.py similarity index 79% rename from woniubiji/module/credit.py rename to woniu2/module/credit.py index 3bbc5cb..7512515 100644 --- a/woniubiji/module/credit.py +++ b/woniu2/module/credit.py @@ -20,7 +20,7 @@ class Credit(db.Model): def insert_detail(cls,category,target,credit): ''' - :param category: 积分变化的原因 枚举变量 1评论 2注册 3登录 4投稿 5文章阅读 + :param category: 积分变化的原因 枚举变量 1评论comment 2注册enroll 3登录login 4投稿submission 5文章阅读read :param target:积分消耗的目标,文章id或者登录时候的用户0 :param credit:消耗的积分 :return: @@ -40,8 +40,13 @@ class Credit(db.Model): :param articleid: :return: ''' - result = cls.query.filter_by(userid = session.get('userid'),target=articleid).all() - if result is None: - return True - else: - return False \ No newline at end of file + result = cls.query.filter_by(userid = session.get('userid'),target=articleid).first() + i = 0 + while i < 10: + i += 1 + print("userid=",session.get('userid'),"articleid=",articleid) + # 如果看过,返回TRUE + if result is None: # 如果没有观看记录 + return False + else: # 如果有观看记录 + return True \ No newline at end of file diff --git a/woniu2/module/favorite.py b/woniu2/module/favorite.py new file mode 100644 index 0000000..2907134 --- /dev/null +++ b/woniu2/module/favorite.py @@ -0,0 +1,63 @@ +from datetime import datetime + +from flask import session + +from main import db + +class Favorite(db.Model): + __tablename__ = 'favorite' + favoriteid = db.Column(db.Integer, primary_key=True) + userid = db.Column(db.String(64), db.ForeignKey('user.userid')) + articleid = db.Column(db.String(64), db.ForeignKey('article.articleid')) + canceled = db.Column(db.Integer, nullable=False) + # canceled 默认是0,不取消收藏 + createtime = db.Column(db.DateTime, nullable=False) # 使用 DateTime 类型,并设置默认值为当前 UTC 时间 + updatetime = db.Column(db.DateTime, nullable=False) + + + # 插入收藏数据 + # 每次收藏之前,先看一下之前是否收藏过,没有才插入,有的话直接更改cancled + @classmethod + def insert_favorite(cls,articleid): + userid = session.get('userid') + if Favorite.is_favorite(articleid): # 如果收藏存在 + cls.query.filter_by(userid = userid, articleid = articleid).update({cls.canceled:0}) + else: + favorite = Favorite(userid = userid,articleid = articleid,canceled = 0,createtime=datetime.utcnow(),updatetime=datetime.utcnow()) + db.session.add(favorite) + try: + db.session.commit() + except Exception as e: + print("收藏失败,文章id:", articleid, "错误:", e) + return True + + # 取消收藏 + @classmethod + def cancel_favorite(cls,articleid): + # 默认是已经收藏过的文章 + userid = session.get('userid') + cls.query.filter_by(userid=userid, articleid=articleid).update({cls.canceled: 1}) + db.session.commit() + return True + + + # 判断是否收藏过 + @classmethod + def is_favorite(cls,articleid): + userid = session.get('userid') + result = cls.query.filter_by(articleid=articleid, userid=userid).first() + if result is None: # 如果结果不存在 + return False + else: + return True + + # 判断是否正在收藏 + @classmethod + def is_at_favorite(cls,articleid): + userid = session.get('userid') + result = cls.query.filter_by(articleid=articleid, userid=userid,canceled = 0).first() + if result is None: # 如果结果不存在 + return False + else: + return True + diff --git a/woniu2/module/thumb.py b/woniu2/module/thumb.py new file mode 100644 index 0000000..28f206e --- /dev/null +++ b/woniu2/module/thumb.py @@ -0,0 +1,71 @@ +from flask import session +from datetime import datetime +from main import db +class Thumb(db.Model): + __tablename__ = 'thumb' + thumbid = db.Column(db.Integer, primary_key=True, autoincrement=True) + userid = db.Column(db.Integer, db.ForeignKey('user.userid')) + articleid = db.Column(db.Integer, db.ForeignKey('article.articleid')) + commentid = db.Column(db.Integer, db.ForeignKey('comment.commentid')) + upcomment = db.Column(db.Integer, nullable=False) + downcomment = db.Column(db.Integer, nullable=False) + hide = db.Column(db.Integer, nullable=False) + createtime = db.Column(db.DateTime, default=datetime.utcnow) + updatetime = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) + + + # 插入点赞明细 + @classmethod + def insert_up_detail(cls,articleid,commentid): + thumb = Thumb(userid=session.get('userid'),articleid=articleid,commentid=commentid,upcomment=1,downcomment=0,hide=0,createtime=datetime.utcnow(),updatetime=datetime.utcnow()) + db.session.add(thumb) + db.session.commit() + + # 取消点赞明细 + @classmethod + def insert_sub_up_detail(cls, commentid): + userid = session.get('userid') + cls.query.filter_by(userid=userid,commentid=commentid).update({cls.upcomment: 0}) + db.session.commit() + + # 插入反对明细 + @classmethod + def insert_down_detail(cls, articleid, commentid): + thumb = Thumb(userid=session.get('userid'), articleid=articleid, commentid=commentid, upcomment=0, + downcomment=1, hide=0,createtime=datetime.utcnow(), updatetime=datetime.utcnow()) + db.session.add(thumb) + db.session.commit() + + # 取消反对明细 + @classmethod + def insert_sub_down_detail(cls, commentid): + userid = session.get('userid') + cls.query.filter_by(userid=userid, commentid=commentid).update({cls.downcomment: 0}) + db.session.commit() + + # 插入隐藏记录 + @classmethod + def insert_hide_detail(cls, articleid, commentid): + thumb = Thumb(userid=session.get('userid'), articleid=articleid, commentid=commentid, upcomment=0, + downcomment=1, hide=1,createtime=datetime.utcnow(), updatetime=datetime.utcnow()) + db.session.add(thumb) + db.session.commit() + + # 判断当前点赞状态 + @classmethod + def is_upComment(cls,articleid,commentid): + result = cls.query.filter_by(userid=session.get('userid'),articleid=articleid,commentid=commentid,upcomment=1).first() + if result is None: # 如果当前文章不属于点赞状态 + return False + else: + return True + + # 判断当前反对状态 + @classmethod + def is_downComment(cls, articleid, commentid): + result = cls.query.filter_by(userid=session.get('userid'), articleid=articleid, commentid=commentid, + downcomment=1).first() + if result is None: # 如果当前文章不属于反对状态 + return False + else: + return True \ No newline at end of file diff --git a/woniubiji/module/user.py b/woniu2/module/user.py similarity index 61% rename from woniubiji/module/user.py rename to woniu2/module/user.py index 8d3b7fc..b1cb7d3 100644 --- a/woniubiji/module/user.py +++ b/woniu2/module/user.py @@ -23,8 +23,26 @@ class Users(db.Model): # 查询用户名,可用于注册时判断用户名是否已注册,也可用于登录校验 @classmethod def find_by_username(cls, username): - result = cls.query.filter_by(username=username).all() + result = cls.query.filter_by(username=username).first() return result + # return cls.query.filter_by(username=username).first() is not None + @classmethod + def find_by_username_deledate(cls, username): + # result = cls.query.filter_by(username=username).all() + # return result + return cls.query.filter_by(username=username).first() is not None + # 如果查找不到返回空列表而不是None first()方法返回的才是None + ''' + users = User.find_by_username('some_username') + if users: + # 处理找到的用户 + for user in users: + print(user) + else: + # 没有找到用户 + print("没有找到用户") + ''' + # 查找用户 @classmethod @@ -39,10 +57,6 @@ class Users(db.Model): # 查找所有用户 @classmethod def find_all_users(cls): - ''' - - :return: 返回所有对象 - ''' return cls.query.all() # 减少用户表的剩余积分 @@ -66,3 +80,28 @@ class Users(db.Model): db.session.add(user) db.session.commit() return user + + # 删除用户信息 + @classmethod + def do_deletesign_user(cls, userid): + result = cls.query.filter_by(userid=userid).first() + if result: + db.session.delete(result) + db.session.commit() + + # 统计当前用户的数量 + @classmethod + def get_total_count_user(cls): + return cls.query.count() + + @classmethod + def switch_role(cls, userid): + # print("数据库中articleid=", articleid) + row = cls.query.filter_by(userid=userid).first() + # print("数据库中row.checked=", row.checked) + if row.role == 'admin': + row.role = 'user' + else: + row.role = 'admin' + db.session.commit() + return row.role \ No newline at end of file diff --git a/woniubiji/template/__init__.py b/woniu2/resource/__init__.py similarity index 100% rename from woniubiji/template/__init__.py rename to woniu2/resource/__init__.py diff --git a/woniu2/resource/avatar/1.png b/woniu2/resource/avatar/1.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7cf8a8c5d0019e610fbc7900611d4b33844513 GIT binary patch literal 42737 zcmV*`Kq 004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv00000008+zyMF)x010qNS#tmY3labT3lag+-G2N40Du5VL_t(|+U)+$_gg z*o%Lws=H_AUCw@VwC}4I2}?4vgg0!<0>`VoVq%s+Vjv+Q+$1EwB=;t{g#3V9NC;dA z1QG~dAYNl*@G8r;yhygSSe9+=%aL>>o%P*jrn{@^{!!ii&dfVY_jJ$l9_u-uKJRqb zUS0L{Q_m`R7DmEdU;cpq^r6QueCnyE&O3Je$Z6~A>${rG=3?9m>+7peTo}i(A4O3R zMNvJD uYL3P^?Z#2G3yS@8+`IZe|Yx6g9k5p h(HG7)R|910aOW%6e8HbuiQZTWgbk zb-&8=K24t%^!8)g?U#k#{`QV%-av?!>vzvqHn@+r74EObAxfh`Yn>v{udA9L`d)o~ z=bqiqoOkX;w_Wy}=Y8pwZ~K+6&w5<5g86>i6M&mP_Lud$?)v8S_uY5j3!Zx7vCCAj zx?8ux8-%pf>veozIjYWTw;4>7Ow{}$#Ch4Y^U{w_7zZJDmYK&fbwVD5D1^Wy$<_!* zK_*vdVtlWT5zuPJw8Qwzi#vBeea^WT-hS#C=il`Ye&shmGV3u;bv|d^foZ@OKlX=b z-*)RQZ@m9|_gs7U@S*dhjjmZ}1o*xWrj{)ZxA+a#S|kQ3CDxi`qD+?F39*{5BXJcJ z&b%XmDq*`(u)QFx?0J$P!fbp3Ap};C^0nQVt$W8o)I>^&P!g<1Yz=K~iDHPX{G72; z?>lhD1J8Nx nW>Xyc8G zbsygsctT@ML>$LpYDg&) SQY%QGtN5q?kivLgP-{6zkhNbt4}(F z_&0y?JC}XsmM^^ZzWcv@U2AP+@4{kmwKOq)AW%wSV)uayl;@5T+Rua}DPuYnhG?w` zg5gKvSj_gw+zY)MI~`k5D2mYLm8u*U(QO+9DZ=5&TX?$N_p 9E8Cf2SV<%3cRjoS~g z(KH$jv^BI^Ere2do #qCATYmbV+& n( By&;HWgvz?scFkh=T2fXih|BoBLbn_>F>e!J(=PfKOJWt8mth+Q(7_~u#EVkjd zY;aqQ$5 x-g$xnRvA3t>ex368O+3S`T9O*9bXWg}#K!#XEehQ^8GU|g6^B}Ff zh;5WkUsV+BB!wr>BE=yf!c1jNN{P0HI0B?X`b%uIqEDWE?j>LUTW|caUwz4|-`<*a zcSjCq)*ToHx8L%Y^}qV)hyUSMzw*T!7i!)$`}gf2ZnbH(n$+ucFemTg%Y_X3AjCp~ z6x8ta2_J!HEwt%uKQAIX=_S_%z!MU!H5QFhZY>#O&{(AKX@;6m3%sE5u@_zU!|(qG z|MGX C@I^H* I8JT+a5lzVt!$XMgqwzxB}l-@b0wp2pRt9bt^g)M2bu7@d&m zC(&28N-6QMx{4@km))>~Y_0P`S*j|p#Jg$ Qo@$_DPpOzhSRac1C<@)Uz0 zAVy)0q#4CTk-hnaKlp>6_& MPlitt)bCqu-1yuG1QlqX*MI8t=8vu?Adqdt#ALupTGXbA77dEI8vA^g!pU! z tFlAn|ChxFJ5SP2pyu0 NC^n>ay9oS|5oxXTmHX-aGztIHTe*w(ad zkI$;Jv(Z)`R~8?-EUvFZ|}}m_#U)d8+cM+(FrN; z>@Tg9iElSAA=T%6!Hj@B2(6b2?7WKBUlg&8YJb#~r$1F*gZe$F%_`sBtf}Q$fDm5t z%Vhh}&8_X`lZwP&Kr%;4DLgL#RlndHx8HT@n_v6G=Y8qx-}(H^$202={Q2+w!cTqf zQ=fiUv)O#b?&Te{Ha75uBnSeewwdCqPP9XG(qog{%WWo88Hb{qZ2DxEK-vEGLKRe5 zk@|C#DAm8JDa2{}b2ORyS3;3z-l4idCL7jd3GRoHPC9*jrTMj>vFqt~{p8>MmFwU9 z55F_fP7i^ZBE(<)*T4AAZ{7Bhe`urlnq9kgA&n($wOFjxvDOl8v@+)kCj&y9KV%4_ zmcXp3p0da5$(PB`R~&~2d9owKwr)9UF<4}y4Xu!mz2 QP#+W+ah zU-xSdJ#f!;%L^x7)(C1y;n8kul=YAzKu4M&Sir`*Ya+EwcoW$RnAHeILlp|nlTRPd z8_u+#tQ)Z^DaihHRYw6 %fxpap zGo%@c&s}@nOF#6>|MpLQZ=#*=12f?v{_I;{`rnQpKX#gu_BD$O8Xd*7+aXH%G-?Y( zktU8}f}oB~j?CG-ri#d->(5+49{$v*Jkv{`Jq1{V2U&IfMcOIKs~pyT-ujEA_sctJ zFbO8?n33*&WcQ+PzKzx~f*_!=xX9|t2FeTYYYXQ+{K#Xx>9yCN`Gv23>z0WRq64Oi z5WoJpKi?G{d+>cCKC#y~>#tv`3tAg(1U{asBZVT2BeVf82#9ouRTd)+R+vp>m`vxq zA;Y|jd62MSymU7cB5@Vpjp#&<^n7EQ)KzqDiwb$Fs(;kG9#($TS}C(0W(^YOFk*8x ziFCzvAVVB!*mW5Y22c5bM{A=^qh3P_i;Xs@`R1a>AA5N5Z@ub;SAO}M4^Ax**3@S7 zYoGgo|GWSB*Z)kn*50wapa`35C=Y5ihm);!Djuy?3ngnTEG#-NH3MOO&dOz!peKFg zty+>=HH }peZl4QsbXZK&Fc5~#&5%%xhg*G8kd!1UX#_Gl@i;IgyMi6T6 z)Ai-u&-~&0zV_o2AI~% H?c z{>HIl&z?QBTN}i2$U?(;@RpwQM{1F1D=%1C+j!KRF4459eF3c>9?EmaajaZmf|W-@l`_s z&YDsj7i{9bPgny&BS|gK90eI$z x-;>&waIpcvpc;A ?%QuiH5t_UZ!`mrwEIskDGVg@yr@#ZGAE;cExskPn+OSkiZFBM0TW3 zq}NKJV@qr-OFMR*b$n&*@$0U< r1osCvnux@Q4p)pmNz7d?ho{eJqDEt_|Kz_=@u1<0<; z81OtFr4;S84H~|B%~MZ2dh!4Hi*NYVN%UqS6yh(u>$Sgr@Ue%UciMq{FSELhqYhIN zUL;DI2`-*z&1%L+goB<9;sH)WM{OGFF}>rT6>qWVn1_|mQ|GwrC(k>~`)pKy=Mz$4 zsqOl^DU6Xw>Cp}&>a_(7uw%#0vmSitA^CUS^`?bSf8mbXs_aeWv-Ge3(OduJJ$HZO z`rSL1UPjzTN_qm@BvHH)ixXkIvD%py6gdJFktlCIug;52-t=i5+w!zEDJgT+yu_k; z^70bX;Z>oQlQ-`?@fUlAFKSCrH>Y|P8@CqX#EFDoukp;&$G-l ^>uhXnWWEjB?KZo1?YjC4U--g}@B8n+ zadlPgRfZ5h@F&0e;;(<@Q$Mx5(0-lNC)ij$geM~x*VU-aONhkcL?a3WNSZW^3Wn5~ zHjFCFyU?eVUR9aA ^E|>Z#0rb=`!t&yE`#Tztvv6JJHCDTH!F}l zSAvb|(c^!-a^mpc-nFPOdJT!e_Y~F&q;WQl7UhO1G$}%K^D$c gQW!7>Pk|H`X$^rVIDYi##yfBPTl+rum2%D?N*|ej>tFrc&m1{& 2 zF+@>>*0VLMI~kzp@oZFGW&1M8`lkVt?&G}Gza8F58Bj{mY&JP?;J|ga-FDjz@BeSV zbw!!_O3l{C-}75ny!VfP=XX7i7cVU@&~9(wDTm3?2Jo_Daj$Ko%_zj_`{V0eB*Xm1 zjpCJUQh<{=`j%mwkDGtoGSjH5A57DhdC~!;#uGx?u_e*-9SJa9H?A*|{ d0JU?f>r+y?$}AK@^2(9TNo3a|OoY`?X|p Jt7DUA|L#}b{x3FG4_@qf8yK^O zHErra18V}JP-2abH3FxF9(7y>5D4QVj6eBlEhr! `l==(ma ztE=qZz5D9F`J2D_sd4HX>&U$1AOG#Bb>y{;x*_nK#Mo$o5DKGx>a|5;Z82zs(#}Pf zFv&4FQNyt{_j|(59f}GfMlF=Bb(KSudD`!H>?yOks-(7x)ISRfahl_sME(8N#IQ2G z&-w+O8ig>Y3DPR3g_25}Q#_IVO|Gtera%b5$Co}~7*ktN7}G{6jj=6E96$4#SHASZ zTfTAcXAAYG=m7rXzx~B`9y)aByuEw(X3}J9tqU42ME0!Rb`D^lg=!%0CdspL%JyTD z^-mHe-M8&l|2)5|yr8wF(P*%?wgx!8RizZZ?_YQS{r6w_q5tuF7Z#e6BAM^{+ +1wTKpbxmUxr1I(7e?@Nhl%=*iPdbHr_Jnldiw)hqS5>@yP-!D=WKy|JU*hSaKu8 z&wTLzz3^M#y6pyGV`_eY)dD3ZFC{Jm<4WC%)KO%i7R@`2^ilk Dy%$r_z z{p1n8 d zA2!x`1}zO*8Vnu=&uOpN8lF`sYfvI&DTr_Q=53$(@vnXQPxp?hFBgS)>h9nlh2hHE z6&h_KBm&=SI9p{odkS$BWmM#T(6hXGw R+6Y3FF(~Du zwMEL=d%G@s+{jzsI7f;+h;UwzU=f6}ohZdgek7`xt32tW?#q<#ttU_2^Yq@GRM|Km ziq;3~p^S$z5@ih@A&L!l?^N9Pz1v^$ xZvXnA`i4@7pZLq)z4+jx-@dl)$M{O21RZX? z4NA>^Vn>Al7{wEE&KX8ubon#fyw3}R`cX85LDjq}D;RnqMb}j{|Fo~d{TneqMdwpW z*>#Ote`VLtsQSkZk xd8KhCURaR%(MOimTkYP{!f~kEZhDxVA6f4>fKb`&q>x_6+dwn z>m&8Jom#N8+wH|a{@s7~vO)O=BE+wM;eCtWz5B~=X!s#DVeyPeywiAK6 Ip+nKX}aSiAGaPb|`>D#l-=T)%ooJsVa>p8AUlgT_f8)%K*; zhp^IJ*u*nVjFmAuY0gu1;s^wiKzc|MUVqz{J~L1+aUeqc{O3Rajwp&=p_F4Yc1B5? zHH^dG8kK+4aj0zjW%^ij)8xrhG<}?nHO*_>evEqGRm^pncU;9fAJtCYK8|W*9&kf1 zq^DbB3{pxOjRwy=^URqa`}6;&uV?LnLY33^w*Rd!+L!pkI_#@`tWg+z5DF{XAk0)f zUKd@&oqUddbtS(FEsAm4A69RX@_8w}LcB#WJbhGsdE1{fj7_ys-T2C`k0J=Lm$x@+ z{TDrz^ea28&Qb4WQlP9v+KyoNi4R4D#R!2mAY>h^LTH5}@S+P>R-Vyc{Q85R=&i3W zHv8b8{l^zHo6Q|5cI|buKPd)j6_Z-@3s?kc<>^zIBm1!ajC&j^n?9(`qV>-kWmpvj zTqLc`2_Ww}9ajIiNO4rzQT2=}Gf9XdCuNpW62~#d7;3c|_uY5j3-0^I`?rKH?Moq^ zcSijmZZr@6ZOH)jo zz~@D}JZ!S3{Y5I F+s!Wb3x2Z4No8C!bcIN39*llq6auBIahpfVQTi(C1A<9z-Yn}7z zIK=Z5acnvA#E~< 0cql)py=`XO~Xm77FpZ-@E&|AP6wV;LUhaioT?Ac_2mG ztnyjWK39Pxy3%dA^8FTD(f*bhOTRp$SUO$#2aILZSjX+pD7I54H8tqINcke^gW4+E zkA7_w9mgb~2N|N2;?CQ@c|Gu uSi<_lI=SNAp=jj45VP{+$i!Ny4+lqXM_ zyn>H$1QU777ZRjYm_DrBw1g_d`Z|u}xX2t75psM z_>9i |!Jju2Jph zo!>I!&y#;tTX~;Vy+6vX|1t=4TF|Q|nEsYhf(h$?_WS=fJ2rPA#77@}^s+{yLA%|i zSIRs|7`2FoJ)4IwWEm>4DB_(rDsdDtnKX<`p%z5~WvI=(6kpypCvk!rHD6`gDcVMr z(A!=oa+FeHjJf{ad+)tEP0ujiZJ+;uzk1@>DM}a&F`jiHMajIn$d1c&T-A2CZ2mIo z!xl*1BTEtFKF;xUP`+s&mGkx^4}~}CedR4bih9foMdl=L{dwQ#q{ E|n zG@%nI`pWRs6OTMEP0JACgAYD aIoN-! zgyK=|dq9YM{s7b8{rs+tx<*OdM)8#L@|?;-UY^vJ_O0x?1gg+AY);1Et<4*ZTqC{n zF=9Tqq?cSjdDroz>mSv2URKGVH8QCDwARz06N9ob)~xLNv;XpcUJo5=H-`@&J` 9*