From 0c12bec57e13247af6a98f83ee8708d6f52b585c Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 5 Jan 2024 13:37:31 +0100 Subject: [PATCH 1/2] fixes in interactiveplots --- rowers/interactiveplots.py | 11 +++--- rowers/tasks.py | 46 ++++++++++++++++++-------- rowers/tests/testdata/testdata.tcx.gz | Bin 4000 -> 4001 bytes 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 7e6ab4ec..1264b7af 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -5909,10 +5909,13 @@ def interactive_flex_chart2(id, r, promember=0, x1 = rowdata['x1'] y1 = rowdata['y1'] - popt, pcov = optimize.curve_fit(func, x1, y1) - ytrend = func(x1, popt[0], popt[1]) - rowdata['ytrend'] = ytrend - + try: + popt, pcov = optimize.curve_fit(func, x1, y1) + ytrend = func(x1, popt[0], popt[1]) + rowdata['ytrend'] = ytrend + except TypeError: + rowdata['ytrend'] = y1 + # prepare data source = ColumnDataSource( rowdata diff --git a/rowers/tasks.py b/rowers/tasks.py index 28491f0b..f54550d6 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -426,7 +426,7 @@ def handle_workout_tp_upload(w, thetoken, tcxfilename, debug=False, **kwargs): w.tpid = -1 try: os.remove(tcxfilename) - except WindowsError: + except: pass w.save() @@ -748,32 +748,47 @@ def handle_strava_sync(stravatoken, try: res = act.wait(poll_interval=1.0, timeout=30) except stravalib.exc.ActivityUploadFailed: # pragma: no cover - dologging('strava_fail.log', 'Strava upload failed for Workout {id} ActivityUploadFailed'.format( - id=workoutid)) + dologging( + 'strava_fail.log', + 'Strava upload failed for Workout {id} ActivityUploadFailed'.format( + id=workoutid) + ) tb = traceback.format_exc() dologging('strava_fail.log', tb) failed = True except stravalib.exc.TimeoutExceeded: # pragma: no cover - dologging('strava_fail.log', 'Strava upload failed for Workout {id} TimeOutExceeded'.format( - id=workoutid)) + dologging( + 'strava_fail.log', + 'Strava upload failed for Workout {id} TimeOutExceeded'.format( + id=workoutid) + ) tb = traceback.format_exc() dologging('strava_fail.log', tb) failed = True except JSONDecodeError: # pragma: no cover - dologging('strava_fail.log', 'Strava upload failed for Workout {id} JSONDecodeError'.format( - id=workoutid)) + dologging( + 'strava_fail.log', + 'Strava upload failed for Workout {id} JSONDecodeError'.format( + id=workoutid) + ) tb = traceback.format_exc() dologging('strava_fail.log', tb) failed = True except stravalib.exc.ObjectNotFound: # pragma: no cover - dologging('strava_fail.log', 'Strava upload failed for Workout {id} ObjectNotFound'.format( - id=workoutid)) + dologging( + 'strava_fail.log', + 'Strava upload failed for Workout {id} ObjectNotFound'.format( + id=workoutid) + ) tb = traceback.format_exc() dologging('strava_fail.log', tb) failed = True except IndexError: # pragma: no cover - dologging('strava_fail.log', 'Strava upload failed for Workout {id} IndexError'.format( - id=workoutid)) + dologging( + 'strava_fail.log', + 'Strava upload failed for Workout {id} IndexError'.format( + id=workoutid) + ) tb = traceback.format_exc() dologging('strava_fail.log', tb) failed = True @@ -3846,10 +3861,13 @@ def fetch_strava_workout(stravatoken, oauth_data, stravaid, csvfilename, userid, if velo is None: # pragma: no cover velo = np.zeros(nr_rows) - dt = np.diff(t).mean() - wsize = round(5./dt) + try: + dt = np.diff(t).mean() + wsize = round(5./dt) - velo2 = ewmovingaverage(velo, wsize) + velo2 = ewmovingaverage(velo, wsize) + except ValueError: + velo2 = velo if coords is not None: try: diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index a4ae0ddb10b3027e58eba3133ce7da2a9d3ef33b..169642f1f07d1062c7a7d478de3c3c3fbeed4fe4 100644 GIT binary patch literal 4001 zcmV;S4_@#eiwFpo(T-&T|8!+@bYx+4VJ>uIcmVC4NpBoC7J%>m6@m`QVG#CP__!#t z0>{o^4A`C^F*3OgDpE)88L1_x%iF&nvfGhmTZQCFQv|C(9}IPMZCzhI^6fnQ?%ny> z-kassW_7WCxQ_<*_r5!NaQO17Tdh~?)5ptozr1?V_1$mXX1SMkUT+@mzv}zTgT>n~ST{1p(mV*XPfE-k#!{)q2x+>*HlQYO^}no%h+rao2Bu?VWC5Pk+=K zGVeAge}3TKyZ&)^c5$^@ZWeFw&-eem>yLN)FRw3!f9+C(fbM$e?l_ww1sk9+@t?+7s*F0Ma)+~H9YweEEJk7c_1pSphe{pI=g)$HG2reAWs z`RV%mW!GOWukG5~cGLgOBa`Qo+EYkx%BFv9*_xBBoSF6+0bZg80)y2ut z^KSjRJ4+Nl*?M#D?)bl--2HaT<;7~<-`t$PNbkU3co(<3eR||)uY?#o{F-bJxF>;| z6v%%;VMpS21fM)$xaIk7ceozCHeX!!<&VGq<(c5tG5qs0rgQ$Q>-!`&@o=&G>+@?a z(nUZ2dAHwUei3fNtEJ9hlC+CeP)9a64ea?rSHzuMMcfla1Q!(CDd|lGxre)Rr@G|b zN=4kAAx70GpN0r7$UV-6yR#K>k4fIGcn$YhQr;P6!`)ZJ-O_fPcM9${7%Ipe@4+3b z;vS$P?vl7Cq0(sc-nfZyuS?zoSH#_$;K6D1dFM)+aZK~!?(5+$V0=KUk#{dfCc?e4 zalRruPS`}SQNuk*N&9_H@*XPU?u-Khjb0a}s6Ia*c}J*7v6E<+b#7XOvgG+53jEfjmZ zHS;{#vgGZI$X67x;a~v3i-x>F$>_YjkKdk~RX0RF$**;&O2ZDdBl$Rkchw{KC}Ve-y+!JvuKGGS4Beoo{ovgfmf##S}YGoy(UA&+gI zznwhi+*<}DjVC9)C?&J5t!sY!QOJt{hM zIOpCvkEj{#1z|EW-|YEe^3hO$7*ynA)9t4pu@TDMQdCh|VQ9Mj^krVG2}!qC$-FI_ zbsbwR?I`5E5!OX)M9PwHKD-gg+XUO7x2mjbagF?4$=iy^lL=l|T_qkT6Q6G~KTKYX zB~(>cNhn)a*Lq-%Lp~TnRCP{}ShmK-H{E^=@(3m(vBrDr09)?u^kp8|NFdTgX&p|7 zJU36yAbFRwu2r279br-3eoo|T8ttP2#Gr}KJEo#l)V{^%#~`0`ZvzHR-&<#?XzuNt z$X8^~lQra!Rr9>iWO8r0)z1%-_XaJJYP5G$)SjOac}EqI&z%#9HT~_K=c4ocoXA(C z+b3;}BdS&{bAelwb_V3d0Enu~xr^MQw9_B$*&7jECqxg8{9Vacq}y9C>_z3t@n}nG zc=yV~YZ~4#dCuKWRo+{lEWy|^Fegu5jJFOou{xi0gMzU-!5P`}6~*UmFcuj#IXOPP zEp{U0YxCiSddLgrT3Xeb7G8?h&(BHbYtrz9jTb_V56?SS(r-VjdA=fhKFKdfQq|aa z?^;FW9m!V|rIl!a2~?wfaFfyPoA-8ryc_@;uk_*hSacQgS;@RqMBW+;qLTRlMc1O9 zmCU<}$a{l8pt0%#hRMi$BR@<&8kYup&1fGe6t(B)G}?!H$RinRF>11|1IH%wcO)Mx zA}D!!86pn>)pWB%dvJSnoMQuB2bNwjjt+9eCA1;EICiQnjPZgo}xkZ*o z75d;NBlVS`XIBsUWT)9cU{&a&FRJFvX~4&d&~uvW2~=}ELYNHt+6MfZq}~|@B-LDx zShn0|PUyKJ^f7DrQ783fS1oMl$3dSvp*mJ&W?`DKnub3E^pXdBRmc`msA#l)PHJ97 z#vKPk9)n85N7uZ0cQx)pJ?PWe4KDY`)1dc7`{3RyBNLi&H;CRE0Aiig2Rj+`*o?bD z^gf~2HPOh~Tt(4yLq7`oXrfiRbO>BgCEqW^3 zDs4_u4;7&gMub!iu#u8Q=o|WJyL5c+jA@;S%DAJXAjm}8=U`iweh|Gi>~-yP^1>LC z>73N;`eF3mP>`S-@I4eQtjDJ2je#DM04odbkOEGoBQCbI%t7>Q(CNBnA;qE#m(FUy zr;5-!1D13dxePp+HE!BmKa4(@D9Y*^MqAXS)8_h7&=Z8L43T{-+Bl7xT|Wx?Xegr9Y51XR_=cM|Zw&O7a{nxyH;-d%YTon* zd@BY-S$Jg;CKIo(Eg8F_psh_B8&Zra^h9m0pFVm46O{`Wqh%@@xobZBanQ4g4oQdJ z@?@4bYmVGu^xKw+UZv()vCXA3eMj!LWg>drT<>Hu30f^Ja{ztVwoC-wk~e6*G~;gS zc74b#6RilU9Jw~M>YKZw4;7&gxr3IjtA>qb!#CUp{4vlY8fI}SsTU}_Ts_Z7&4Y^2 z+ihzFm6|7o+bGSczTQ@Z-W#&Ypsg?z_2$_&;E#cxz#uWQ3cZENtZmr5dBf z*C&gh6Rs-t5q0Pt6*cZ!SB-Jdhb;A8H{g4ojMTRQe-J&R3BtN~y#!lS!*4;` zanM`i5K+}tL!xcoyy-h~*&EMfRY6+^ZZfGFP0brbpX@a2P?x3S(6s@7>bZFdJsY9y zq|u6Bo!HcG?jow1M;Ej8#lv;lwmj$9iPdLmWfm9ud&m9{NQXAr%RVXY6}IcRhJ z4A6@q(yDnLT1M{F3$H?MnTTnd4t>DMG*oG7-T?ZTTP6Zx)YIn*BrT1cj?63G7+?E z+IsINGuKlK+76=6Mb-?e@Qn|?+4VC(AB`mIPAB!zPsXmNrsfTyXEI`~E_@RpG`oHV z=p`3kfet+uMW2@nY6JcV=z{@9T|fMgllLcro|-pr2z_438ZhY4bDRwNwtoFEdNx5w z7r9F>N=XerccN(MM?mk4XB$;6o#3#fOJ`Q-r6Tk(uW1W9srOiP!1t{LV+`~{##s!i zES(UFR@&YReXF?}MlZSgCa5xULo8Zpd#?e%_0kzeAM%>Ey2xFGqKlo)O2e-uOGjY4 zk~N@LIdUV)WL!GX`sNLy->zh>TjwrP*`O`7xqcM%K3Cr;(X*e->XvP;A4H#5vSuWe zH!oUWwEBix-@H-K^L7z)m2np(w$&{s?#;{ST`s&*qIa>V)VD^dPUOk6!n$F0O98 zCXX&J&sN7>pMLuFi*bGKFHV-e`~LOn?Bx3A{*vCubm)zT^I^;L?my|0*;#P&^Ow7= z)@ieskNa&mTtC{+&VTqa-Sp8<%d=&-Stbto(}zcQj^Pk#HDjvj1Luh!`~JWeQ=S5MN@_$^)f=)wO04jq5x H#DD<+PI)z2 literal 4000 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 Date: Wed, 10 Jan 2024 19:11:21 +0100 Subject: [PATCH 2/2] bug i --- rowers/tasks.py | 4 +++- rowers/tests/testdata/testdata.tcx.gz | Bin 4001 -> 4001 bytes rowers/views/analysisviews.py | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/rowers/tasks.py b/rowers/tasks.py index f54550d6..25f2a03d 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -796,7 +796,9 @@ def handle_strava_sync(stravatoken, if 'LatLon' in tb: dologging('strava_fail.log', 'Trying temporary fix') failed = False - except (ActivityUploadFailed, stravalib.exc.RateLimitExceeded, JSONDecodeError): # pragma: no cover + except ( + ActivityUploadFailed, stravalib.exc.RateLimitExceeded, JSONDecodeError + ): # pragma: no cover dologging( 'strava_fail.log', 'Strava upload failed for Workout {id}'.format(id=workoutid)) tb = traceback.format_exc() diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index 169642f1f07d1062c7a7d478de3c3c3fbeed4fe4..8366df1ae38ee3ab50f7edee4f9cc15f121793b9 100644 GIT binary patch delta 3943 zcmV-t518U^~}#~0^|^yTLG)$+XCEN(x1 z@rL$yr#R@|{e`nUI__6*R{i@Q-u26MzQG$Oc(+-7a)!5TF0M`&1b~ZQpFjI~dy0pv z^``IE$A8Oo)Mj5_~8MhpOHU)-0*(y=gW(${@eY3_OF&#`@1jG z*H2H52+%zQc}VaQ`M}}ufFZ%8*ANKR| z_+ovsITH4Vi!Zi*JmAS{_Xa&*rXRaW_nGhIvyC73{sZ3;VmMq}fBLw?qaGB`T zboW1X{qpp1){(rgwakt#SEtk0Q_0#qCRqfv&ZQqJzB742%=7T(0rU!gP zm>=Wr?;8}aR;Q=w)|UONi<6`0-THNRmMDI*_2%B)@qa(L`|Xy?i`BZnxjBE4-hsdH zE^c@G^vKU%2{Cr~HQ63;PXae7kpF_hj>PQFz3^KQSz{36_jS4*A2Bxx6`ppI;C8rbuLu82Fi zinu3;2rekNQ_`CXau0XsPIbweI)McgHEPeP^9=Dl$f;a-=#2d;>_H^GC`==08% zG~<}&!`;`zUBLK&RwM6Tj7)@kW#fEBcAT(@V55e6kdpTMoa8-J#N8PO1RA|AN>P1& zKJt!Gkzyy&Fzej32xZChJ;+mCx==6SMZ$=ex`uP9=}!2p044S9i*(Rq6xzdbjr zZisx6U+YknhD8!f`tW8&z9Ju_d0x;YkyqLC3{W&;Go#VICYcv&(z6B9kVl-1Zr`G`!{nXuf{jjd{)XGRkzLLS>Ze>-{3xwi~R8c$AoQA%cATi5*dqkoVW0}MeW z^Fl=P8{&4Sz*+8t<)TS2W)~w9$SH@(kOSSQ_2lT31xJ4=p}F3VAY) zA*!0-Nm=r9s;G1okr!iySvAkQqP4WMA}O}WnkK}6_o-_=Eop!(Ik!2k*eis z(O$PQqbh2#6_ID-oi0jiV=S4IGbi%()Yx#&y>%W@GujKnWMsbC^MAwSqoDvXsL02r z+fP4YBb2+PsG_vO&~*Fh%e+_YO04Y>ka? zy8RgB5llp4jrZ08wtw8)>B~H_kwB!0(mI?Dd2XJZLGmtVU8_1FI>Ms5{hY|xG}=c4 zh(QydcT7dAsC|pik3l}?-UbYszPHX&(cIfPk*~;}Cu_(dtLAy3$>iR0tDhev?+scc z)oAais69U;@{TGZpF1ZIYx>(e&qe3?IgzhOw@=y{M^vp^=6?dWDD4c$ivbW-mva}n zMQNu$+Oszzx=x558u`1DuSmDIVAzYwljG5r)bQ?=hu1W`Ve*{2pQ^mKK3RgXWnfO8 zyclmCYGQRh=>`R3b%Hap=PQcO+h8m*YI1UXdRy#7$k*n>3-yo}%(b+tH7&dpt)HKh z%-5vh2^%kj8h;<2cdn%0epd5*MfQA>Uyh`zvGLxuipo2ZuP90@(Et;uM*H905o3d!}GD|D&(`0d8vrJH5NoA^8t#kMLjE-cNLNM27y3h)ddWbk@-e`n0z!Y z4fdMRK2RuX&(CSJ5A~2oGS*_$WL*c2P3G@NK2}6t41WaWXm5+IR5&Y7PDP_VdgDb@ z-BN-px;p8cytkg}Ay1HdW3k4Q6UwepDb&c1LY@tht_NlaMOQ7G6Zx9vc@h%@qb370 zL@b(_K{J}?eMRJhktFk)N{a~8WPa+gIyqo8mPwVF5s@4DsYh%Qd21;BQ<0~l>)7P_ z)0UYr0)Kg*^YB#t@FEvo$42aox}VlWKAPY#s${-!HkNIDZ^s~S$vDwfSH;5FSaVvJ zwxTF)l3!t^Ztq-Ct8Px@EAr&nU?>u3^6jJdMMrzr)}kJR{4V!aH_wMq)T)~k`HDO_ zk}NbPP?3+JXiko6^ZY2}oe7p$6QxCfvSHdep?|N)l_N1H+(S^ICur#J*#ESe@!sXm zw=U|&dj!U!Dfjn550#;piqK1Lm;$;1-_m5zW9xT4h&~uWLQb&70GJj}@WkG}jZT=6ZxM8T7Rc_%%trGYm+oxgN1>xy_u=b4BQ5*6^cF>dUTL z*wBxIK6gTOtjf&7G-EXle+K9!5BRE(Euv7-X#Jejyo!uF4u(7im4=V5dGqdS+=Y73 zr?DGc?vJNI?~C@qy;nviG~;d%y)^*DI)AATb~5O(8Fz!|eL}BmqLH(?ilXO+eiZc4 zM5}b^5V)eo9W`&>80eF-9#L0zgOnZrP3k9)UX1fv^i;N0+MJ{wDncKO2&o!iBPEN_ zH}unX>G<3k(>f8AaYso(kcqU)Pk!g)t`6IjPz8!|1)CAVD|adw(ce zSdUH38v{Ki0ag~=AqAXFM_g=anS^e8pYVO8BpEE24b@lZuWq;eLP*d|pLC;12qfY8wn9P8WEkSD#y)zbdYZ)T@ zShR5(HM@Qk^wCg6tJCm9+3*cFZ{8T_E#>}MI&U7w*wnn~5BOFLh_dj?B1|S;Ut2PE zML}DeG&ZCdRp^P@Tt9vE0wyXKE=J2#G;-H`_~W2w6CIKcz2(U)Z`K^S!++?vEfc*; z&9h>gOK19y+-=K5^t!p;$z&3=T3Y4+`mk-82)ZS2(0Xac-PG;+kXt5N5mY&HZD`du zcSRp6LLYJmEnQa)8_R}oxDEJYphq;!;#5*EP$PYSnDnp1tf ztq8q0WR*c%VJPa&vu(g11Aje%L1JVTdJB_T+pu}_hS6_}tVtEGPZmKdvYvs|yWCYH z>d-qXYTUK18snf3S?axR!1p{Esc!@RAbLguH=fC=g0>FaWKuPnnm33(*=g3HE=$LuYXkn&bMq2CN*{b~$5cy>v!F?=t$R zvgTqk+QXdcdj{dr|!~;xn&|~*R=KCPiC&C7PK8i zpNp&+RN)&Re6#CkfIb>Y)}2o3qo0gjPfg7mLeFHxT3z@iK!0d<{S44cF1!LAdMt`Q zFBQ}V{1MOx1B|+U_#r3nPXs+RZ{864yplCw(4prz8T4)a`eF2Jf{-q9mtK^T8h-9X z(a?{8-Wks}s$4q3VM&+Htk6qE=wn{f7IaeYvFL#BTM5P(=!J~47*tt0Ar!5&y%+jc zb2p4$a`jD6Wq;&`ShUjiUITvXr8A5^*7dxAkhF?pTj=**$Ye27ZtuD(&CXFr+ME!$i_h(51m%}6S5UbMbw^$oSY zd844`?IPwX<1R{Ut6NUoo0rkMTzI8K?_yD@Z;evNL4O}};g!y=j{#cqw26E368h~* z*2>6TjMzG3&j7tOX{J{#fIa_pnaIrh!!R}0d{KowG`qOIn{o&)Q#PQyz&6Z2Pp*$JP4ur0ctM-fs7HB`P0}JACxIe|2$n<28A7d3m-v z?)vo8uV0MobANHN^xgNbS7#^JKlhjPKBhx&Je&_(o_GIAm(0$Bo1eejZM9CDy?oqn zyW#rLes=!Dm+7XDep;R_yUj9j$e%tux*PX(_(-fif%s#p3PTx8}6FI$y2L@x}QfeYrV)wLI@Oi`x%h zyrKQwDGs`Kf8i{Tj{DV{Rsa5ncl~mmZ}7$m-fdQ&oZ&5-i>uQG0pQ}-=g)rLp5mL; zdee97<9}s3YO^}no%h+rao2Bu?VWC5Pk+=KGVeAge}3TKyZ&)^c5$^@ZWeFw&-eem z>yLN)FRw3!f9+C(fbM$e?l+90~iw#TQ#Y9`IzfdxM@Y(~sSx`^@+9*~X81|AFraF&r+gKYiTcQ4+Q8boq~E zy8EBHe);|7`S#W9-(RL*a=rQK`uk*W#JbdlYk zAFr^u<$n@4zJA`lTb;i?|3BS;xLa=EmP_3D`ssT6s`l@Xwr|BUk-gq>^Ff|0(*r&t z%#U&R_YI0ytJBkTYs>!C#mUk0ZvDDDOB6rZdUNmY_`jdr{dUXc#cJK(+?>Bi@4#Pp z7q`28dgN!Xgcv*gnrsiaCxM$3$bUg$N8)w_pMN}HxaIk7ceozCHeX!!<&VGq<(c5t zG5qs0rgQ$Q>-!`&@o=&G>+@?a(nUZ2dAHwUei3fNtEJ9hlC+CeP)9a64ea?rSHzuM zMcfla1Q!(CDd|lGxre)Rr@G|bN=4kAAx70GpN0r7$UV-6yR#K>k4fIGcn$YhQr;P6 z!++gZ#NE<%oOcTDHW(_%9q+*%tKuG@BJPs7C!x}4^WM0LaIZ_=16Rb|o8ZA|^m*q> znsH3?;qL3tC4pvMkd0&vT?p5J5Ja{uu;Q3NJ;yBPVycq;_i$C0*zi5rKmnX zA9+WpNU@V>n00PigtFxM9^|Pm@>IQypN zVnRXkG9&V_BJ#*^toV4Ou#$$T>YOM347eCBz9ipaCEjKUi7 zg?)E%M&zj?^3I^sIdRbWlJmTUHrkIuKA1>iHQ_n*p``!rUgXD$@-y<=*EHI*7bvVUPjtBKN*FPdTB$d5$c8L&$70VX5!waxPtMQLp? zKD~-6dp?5kO~ae|JTGXH$gAvm1}GY_nbBxplgx`X>DdBl$Rkchw{KC}Ve-y+!JvuK zGGS4Beoo{ovgfmf##S}YGoy(UA&+gIznwhi+*<}DjVC9)C?&J5t!sY!QGdvb0fwNG zd7+{an?`;d^4^3b@u(s1xXJt-$#XsA5sU-~swNqpi^{xjy8S5R*|0@X&GUhaYIwfM z{3zs|!HA-g`DlxJZ=1}ILw=ikt7?H}%T`q0i##?T-Vphmdn;C@+uO1gl{Pe)ABDU% zX{e7H-QJQbD)XUPb)%5?hJPYDjrZ2FE1GW~+Gsxpd4_FEERAk&tt+bAhZdh7g*+L@ z5LHd^q%8S4RaCl)$cwSUteWRt(OTMBk(Y|d2a~v~GB9n~ib{bd^J9>=Xp+Y1NY(PR zXs=tDQ5Ch=ipaC^P8X%MF_z59nG^YXYHT>?-a3z{8SMpOGBV%n`F~;Z(NKUGRODmR z?WZ5H5z5_CR8d-CXuAFMWnQcaNw-(Yye*q`9a}B!DCE5n)iWO8r0)z1%-_XaJJ zYP5G$)SjOac}EqI&z%#9HT~_K=c4ocoXA(C+b3;}BdS&{bAN$bly(N>#Q=z^%ejl( zqO{W=?b#a8y)^A*MCZ7>!YH90vxy)AYkH>zz$b2I|OgDyfu{msmN2&b!>9| zY0JzQfq%Tud3dURc#(^)V7Ujhsw}PMd&3rOaa}1Z)q~knz5ROKLhlV2Ygk?7E!2Zw0=%%UPZDCgj5Z%k&;E| z8~SOxbbRiNX`P75xTB;X$VA%bU|W`c5WO|*b?tNV!Wfh3oYd_4Vf5Zmkf0mzJ%1D} ztjDJ2je#DM04odbkOEGoBQCbI%t7>Q(CNBnA;qE#m(FUyr;5-!1D13dxePp+HE!Bm zKa4(@D9Y*^MqAXS)8_h7&=ZpHni%S zyP^*jp%1x(maeOYjb+0(+y?wH&?6dVaVn`7D7#!e&q&RKiqP9_YXy~>CxzQ6&8fcL zR)pRgvdW;XFckIX**4&hfq$OBAThEEy@koFZP>hd!|1m~)})HpCySsJS@@38m!;#-wE=(Xxp@ga8=>r^(SM+)>6Bo!HcG?j zow1M;Ej8#lv;lwmj$9iPdLmWfm9ud&m9{NQXAr%RVXY6}IcRhJ4A6@q(yDnLT1M{F z3$H?MnTTnd4t>DMG*oG7-T?ZTTP6Zx)Y>CXgdaaq})(NDfL{o1Or;ob`)~_>a7%w z+(A?GMnNA83kIFkiz}L{(bT+A&{Hz*NZDG!JJ%e!Q+Mga+%gfgYubA6Co|Vm3)&8% z&qdY@s_=~uzS;FNKp%}H>rN;2(ND&%r>5o&p=UB;tuA~MAb&Kweg^0z7hZu5Jr+fu zmkMeF{s`!U0Y+Uv{E(CPCxV`uH*W}iUdb9T=+JYV4EnZy{V;kqK}Z+5OD{@E4L^6H zXy`{k?~G>~RW6<2u%t_8R_LW7^f9k#3p%OySaiVmtpsBX^g_m245}=h5Q=VvM_{{>HK12HawE!Q zTsqMD<_)6Xu4JuS=Ppv&pe?kyeiZaRSKlbnv!BfBmTj&dM4wl(W+at2FIr!;`i5HH zyiw5eb`f)xaTg`F)h#FP&CBRrF1%8rcd@9{w??Vspns3K@JeUb#{jK)+Qhwi3H^2@ zYh~mvMr@t2XMo9xLTi{bbXi3+wI=2MCIdghmT(OuP&}`ye5w>FV9xT zU7vpX^^0+R?k`T3zWe_5>g?qD=l+u3$8_k8hx1{}^X@h@D0H3|HH+NFLqCU`