From eaf862cf572fdf7563097d229e3a0ae206553919 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 11 Jan 2026 10:32:45 +0000 Subject: [PATCH] Fix: Detect and penalize ghost courses as missing courses in SPA solver --- dist/static/js/solver.js | 64 ++++++++++-- server.log | 26 ----- verification/interaction_test.png | Bin 53621 -> 0 bytes verification/server.py | 43 -------- verification/spa_verified.png | Bin 35743 -> 0 bytes verification/verify_interaction.py | 98 ------------------ verification/verify_spa.py | 158 ----------------------------- 7 files changed, 58 insertions(+), 331 deletions(-) delete mode 100644 server.log delete mode 100644 verification/interaction_test.png delete mode 100644 verification/server.py delete mode 100644 verification/spa_verified.png delete mode 100644 verification/verify_interaction.py delete mode 100644 verification/verify_spa.py diff --git a/dist/static/js/solver.js b/dist/static/js/solver.js index 2ce51a3..8414558 100644 --- a/dist/static/js/solver.js +++ b/dist/static/js/solver.js @@ -269,10 +269,59 @@ class ScheduleSolver { // 0. Preprocess: Filter Empty Groups & Merge const mergedGroupsMap = new Map(); + // Collect names of all groups the user INTENDED to schedule (before filtering invalid candidates) + // This ensures that if a group is completely filtered out (e.g. all candidates are 'Ghost'/Invalid), + // it is still counted as a "Missing Course". + const allRequiredNames = new Set(); + groups.forEach(g => { + if (g.candidates && g.candidates.some(c => c.selected)) { + // Use the name of the first selected candidate, or the first candidate as fallback + const active = g.candidates.find(c => c.selected) || g.candidates[0]; + if (active && active.name) { + allRequiredNames.add(active.name); + } else { + allRequiredNames.add(`__ID_${g.id}__`); + } + } + }); + + // Helper to validate a candidate + const isValidCandidate = (c) => { + // Rule 1: Reject if location is "Free Time" + if ((c.location_text || "").includes("自由时间")) return false; + + // Rule 2: Check Time Parsing + // If time cannot be parsed (bitmap is empty or all zeros), treat as invalid immediately. + const bmps = ScheduleSolver.parseBitmap(c.schedule_bitmaps); + // Check if any week has a non-zero bitmap + let hasTime = false; + for (const b of bmps) { + if (b > 0n) { + hasTime = true; + break; + } + } + if (!hasTime) return false; + + return true; + }; + + // Filter out invalid candidates from the groups + // We create a shallow copy of groups to avoid mutating the input in a way that affects the UI permanently if not desired, + // but 'groups' passed here is usually a deep copy from app.js anyway. + // Let's iterate and filter candidates on the fly. + const cleanedGroups = groups.map(g => { + return { + ...g, + candidates: g.candidates.filter(c => c.selected && isValidCandidate(c)) + }; + }); + // Use filtered groups for logic - const nonEmptyGroups = groups.filter(g => g.candidates && g.candidates.some(c => c.selected)); + // A group is 'nonEmpty' only if it still has valid, selected candidates. + const nonEmptyGroups = cleanedGroups.filter(g => g.candidates && g.candidates.length > 0); - if (nonEmptyGroups.length === 0) { + if (nonEmptyGroups.length === 0 && allRequiredNames.size === 0) { return { schedules: [], total_found: 0 }; } @@ -385,9 +434,11 @@ class ScheduleSolver { // Missing Groups const presentNames = new Set(finalSchedule.map(c => c.name)); const missingNames = []; - for(const mg of metaGroups) { - if (!presentNames.has(mg.name)) { - missingNames.push(mg.name); + + // Compare against ALL required names, not just the ones that made it into metaGroups + for(const reqName of allRequiredNames) { + if (!presentNames.has(reqName)) { + missingNames.push(reqName); } } @@ -398,7 +449,8 @@ class ScheduleSolver { let score = evalResult.score; // Apply Missing Penalty - const penalty = missingCount * 10.0; + // Increased penalty to ensure schedules with missing courses are ranked lower + const penalty = missingCount * 500.0; score -= penalty; const entry = { diff --git a/server.log b/server.log deleted file mode 100644 index 6055d81..0000000 --- a/server.log +++ /dev/null @@ -1,26 +0,0 @@ -127.0.0.1 - - [11/Jan/2026 08:58:47] "GET / HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:58:48] "GET /static/vue.global.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:58:48] "GET /static/js/solver.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:58:48] "GET /static/html2canvas.min.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:58:48] "GET /static/js/app.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:59:07] "GET / HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:59:07] "GET /static/vue.global.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:59:07] "GET /static/html2canvas.min.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:59:07] "GET /static/js/app.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 08:59:07] "GET /static/js/solver.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:25] "GET / HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:25] "GET /static/vue.global.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:25] "GET /static/html2canvas.min.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:25] "GET /static/js/solver.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:25] "GET /static/js/app.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:26] "GET /search?name=&code=&campus=1&semester=2025-2026-2&match_mode=OR HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:26] "GET / HTTP/1.1" 304 - -127.0.0.1 - - [11/Jan/2026 09:14:27] "GET /search?name=&code=&campus=1&semester=2025-2026-2&match_mode=OR HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:43] "GET / HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:43] "GET /static/vue.global.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:43] "GET /static/html2canvas.min.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:43] "GET /static/js/solver.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:43] "GET /static/js/app.js HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:44] "GET /search?name=&code=&campus=1&semester=2025-2026-2&match_mode=OR HTTP/1.1" 200 - -127.0.0.1 - - [11/Jan/2026 09:14:44] "GET / HTTP/1.1" 304 - -127.0.0.1 - - [11/Jan/2026 09:14:44] "GET /search?name=&code=&campus=1&semester=2025-2026-2&match_mode=OR HTTP/1.1" 200 - diff --git a/verification/interaction_test.png b/verification/interaction_test.png deleted file mode 100644 index 1dc4ffb7398d8d553b3d0523c7a73e8be580317b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53621 zcmdSBcT|(l*Ds0{6%ZAWA`q1?q97n5(usAfdWQIIYoATp%WLR5+A2Lbbr_T`E!@kwbKVk+1L-~+>d?v{MrId{oSRA^+)nDa%b2AC=0W*B zmqAG+%Hl4{TuR?Ok9@vw-rMfNj4>zk0eY1!?aKT`-|3aO>wku2k#{&~Eraic*X6s$ z)wqv+vFB!9Bf0q;#|uGIbO5 zceb@B%1IKzMHW7c{vJ`w&f50WbhbNxI-mOTvX4*3aj%~E4!qv}*)3dI{qJnwnr56b z{Pd~-lZrGa)4kU&`UL++{A!Ur@lqO462P!`_wm>$*kEJ0FGqC^T#=bp%gb9OX1u8I z;wyUiXE2uF9MdyDo5isJWKHku{pIc@iBua(G{L3N=^%l1wAYM~+T|ezQSsTKwrApm z$uv9@mAE<7YA5O;BZpi{4iJoH+F?B>Bp1)Q4G8w*(K z0jw|rn-iijIJh5^I%4BUVXWYVz2r7@r-Izz6|d$H^3bm|-KbiVA;vO{4gr;ojGF;Z zMw}iaPt4HLYNhQqb4hnITOQHfXM$Il`wJwSFHJMvvk9!lK$6UWm9zi&M0k~aldOx6 z7se+6-(Td|zF+3{3I7TU+T29+uVLjiJgv{oP@Car|Lo(bV@G^hQmMqQLJViEh2{*8 zoLfg*l!p!^kO*ehRFypFg(eLicnrj5ns?++f_xuStc;}8N+ zr>&zSLIphPmI$GAF?R+QReS=k9hFR7yfgCLXeXhaNeqYTMCu5EC3vH?Mw=<}$-K-J z&Q`HUhAB4^xNIc@UT>zpIs^HLzmA=Fy1^`D0<_BNdP4sS+@tHDcauNHXUx3wwUx~` zinilJYqnz_03ZN{;Y!_tCh}?M4!Au*Txw|xD6`j2~}u))-y z7jx=ojX_u0{A!zBq=kWZy*A^zf!!vZ%MurPLs5SoI03Y@{K4LYrsG)Q6>6$_LcXX) zJIpi47GrScrAzJ`g=$*CYIW$AXI{Nk0P>4;bLWBOU~fZX+|1Twe#3Jy$l?|{{3##i z-@~mQg(^d>_LpZ+_yQ&H-qy|qO6Gx2FH~j$SGTYYe+{V%)G%wl>VQo3SJ0B|lPr=> zdZEg*9KSXJ zm62&{g-6ON*!PZukntyG24hzk>$VyVsjrH&aH()a3uumaF+qVj^TkS3 z2<(eL2#Chh*CBxC3)B^Kvf7s;V{#k)Ka|z)q!ZeMm@B_L{IH~3Zi_KqdwC#TF7@ZX z$G-0jS+;lXrLG_gqE4Sz|8@Y6J*4U9W6cx$-e0Pw$_=c~bBUPERpeK8x2mT|7ur?c z?FRTTH*kr-l)Bd_Vp>|7u!V3#3a9p$o1*c^$>y;hRKb4FJQ}M!(R}wK(tX|sM_tfT zp2!iLBpP+kC#IKKEo~6q6Dr}*L9I0-1GhE!C^Nd?egcA>j)Buu=e2MSeR>u5T)wbE+gLL=h~HxxADV=#Tb zBYXAhW+PFE#_2aPQesgmhm*!ah+;Ay4u$Xv^Sp@RX64wSCgNOjyum~eN;nJ8A95*Z zsU)Qs0YeG-?Dp(VZY1|HK@1Q2t`;P9-JSaKDhucLhUNgW!n9B^M(ye0T18ksr}RfR z(`GY9QN{mKPZpGU8j{&SI(ev_y5J#EfJwKE-nooqD`cFti?waFoiuJcf7aK2-Mvgs!Ii|DXzlf!kf@Zz}eyWbhYNwHxy`)6Y)S4ovKCh{=1&*EH8# zFlfI`nUm_+{tR?@Fy`r>zp}IrOB($P9vHr59V#+>>&JfKPy5t`fFg5t(i=yo3PJMSc6PJ<*TLbc)l5Z8x0jA=^uxFKC4(bOr}#@~jTioCSe98E zBVMpkTHQImi@B%td?i9q6*f-B$x|yL8=T2%jO>;8^3@kx=U1f#nl!=_YHvD+T$_V- ziEMuWPx+zGxv}vbXZzdD#b8wX=|43V=kxz%kmWytdVVdmd}QnE>q|&I{&#ed@SND1 zMQXG*5}fk?w0sOPa5zaK5ZvkasDI}ip|Zt4cK)sTTEf3j1fQSE1QZ*fPaBqa&puTI zF`t@hoeB#(^X~q6Vd0rpvzbr7hKT`x4s!Mrw@KB=ZEyOlIMe?W=R4<4C5jGO12`Ya zr=&1>_yV7lSr?{ZfphgfI_DFYf}O8O@Y(*mhYx~z)Bc43{!1ZV?Fh@J4?5^gNq+=F zQ0P2Pz_AR{qPLx27CF)sjMYV$~n+jK5z$y~E}5`pJ?In;OHf zJ69_~pu_|LuLb>zW>PrCaI`f|&_{WTe7ph%1OMvcw=Ck4lu-1XstWMX7?RTpj<%=b zv4!TawUTQd^_~_+xnJGPPK#SB!e7S`MM@2N!V8^kPr@L zv~r(Y#}B=-G=N&CF5@9|6U*@uCVm4I_(0Pq<;J>%ggV0CYiUZ#-6?gg6+*WUx#77k z0+%-uc^VCc5e%)LavrJ8DPsP!n+YDZk@uSLHSo#;b$5di184iLV?5KhiLr4~eFZ4pfwBt@6=4#>jfYX`Or0;S-T~Pk1BfL|`Q;&PPIBovz&H_%v__3s3Q-*Kg=H z)50Op=lrn;t60%Ta*0t;Shr#7pgIfAZ6n%{kx%373bOim$)Wg0zr3KbxtV>ne_l&R zyKYh;;*Qj;4NP)EJkk$EKyw=n`?6|ifV6*aT#L{TGt~n(GNT)`GKHc3{U2u30x-EU zuu|eZjowVOcbyrry@G-wf_USMg#0#3B;o)Z%hg`j4}w~)_PV-a zAJAOi>WpC1Br8JNqBwW5qhcN?AvC!B_WZ=5EE&zB9St_2= zb3(ISN2?h!IhTy06nWK`4)5>?3-ZY7BU1RdhG}?tj658s|0eQOR9NcQT#%hz!|bSkY@8@`&=m?wL7?`Ldh^9ZccUvrZz(A3(LIU#o`Yp6F$+m}iEt@=YRwEN{vAZsfs^;Mbq$K51MkHL8 z8xh2|VX-?+D-RL5tV~8b5+peN>e+M|b6=yH7-#8e*#WX>ytXhFi7$cHY#5D8fMCuS z+}PkGF0hjB6P}vNy|=YF42Er<5V4}^&IXvNeV8V zvL+(ngoi&P`!=d2X~GBSbmS(NE{4SI0#?IGB?|~R{|1lgQo^Z0|Jw$ zj6BTU`kO^~e#PPuSqQF8teH#kErF%4C(ya7oczA zN6nqP_r|ElphB$6YL$M@&}}FObmn4p{+B>?7~{U*88fZ3SHfmL=YGB{3V%K&th3^C zFc%3(Ev=?I(&u-@cn`$-MrJ&m8kWC=XNdxk#2rd-6Hs?xdJMq<9n!1cSjeOaOx*Qh zY!m?k>2B?uWX6{HD^=;S*Ifr_9iYP8i}JYzE<|A9`cxL8Y5Sn|-B^#*co-Q!1z8tz z-E#T9T(88WA(FCG2sy}aajDDW>yB4ArN24TR;SVH$CT(sP6ZB8NwI2T%h|>4a>lQL zbqshvYb5`OTUMW(s7~xmASFE-zL#vSlV1iC>eu#Y{V0Gx0c3=%pqaQBa)0ER`ekNV zb#Qn>%f(G-`JASFML(~wQuz*RPUFJ+;<~VawG6qzzHj$r z%w=@C7uLLnbePdeiRVH06Y$21?HYPmo)@6({~Dq}e}AH@-)qADDLUEoYx-Pw_p^%C zig+qlaPE}_&&q~!U!gKB0m|AxCI~5x-3Vt7-h?j4=Llc=$riK9)z3Wloe!#G z4U!=h=LsOtI$0y-ZK|~&pD|fX{wXXjzO>81X{2@}{fJtN6n7A51+?MKlX>i+fw_5X zs*mN{&XTDh#nC4fw&I`_L4_ADjPN{ysyE(Hr%W_L&I+CRrt0u)MOw^ssf^wbZMcup zO}Zob3)|3~G3HDCS)617>KhR6qXf73Yit%O4hef3~iT#+`OGq zOgNLQ=3rx)Tl0;33&KQkT4%_k)C6%O8&`a9Sa&Hr8Wp#?*7oQG9!7rbmR2V2{B-r4 z(mlLPy&{|E(Ha!RpaJ5Mja_|0#0EYy_PG?%!9|mzcDW8tTSLM9LT&pPb5l2#S`)A8eUtD&6#18-_!fpU8bB2D!^>F+0o0gaS_8fif5_7QDwY zSJZ3k=#Aq;gT$zrMa>82ixH~wWea%xayW`4RJi7pDvtu%Qz1a1;iUGeGMOu^Gpc%? zD%e8kb6jfC?pPU7@(R_YLa^?x)KilR;_MssfyL|7eAcy$GEcv*pH&x~JaaJ(4QN4h z!S9bf;YwZ_nm`Gs(^~$4#S)wjRZ!X%#31mXa$Lfmx|tZ|Qd4_QpXiKRvs$^PtgLh5 z&5BBamsw!vB;DH^ON$V1jYTHJY<7-@cr(@}j`pG`MdPm0mh*hRtyGtQ^&8z>Ywl_q%%kEWTyB)ly)kL!r{? zJvch0`debOVuqhb-?&wUBBh9xd}tnolLJHT z{WW)9n`yT!zNvRR0$%Z|(nS?^4~3jv=2lWV_n}QYtUR>&GduxDwTgP|ywR|^xdwe9 zr%ZQq(vzmWDNyjXphJtgfyRc8)zzn%wc`X!5SdbT4gFF)hG{fiv*QBr>l~1>TmPz=t+e7*E7ApY zoKi)r!rZW-=78|^pG0bNN5)4ZC`<+o-IxC{oH^Im z<%WgdF0QivO_$D2>zqpRNv}(h(@3zui za9mQ+RfW5EpRXnHXK@&PHHB3&)onik7i*xzkz(-75kHvpIcdq$}@@<(rtM{4iMe~80n!YdaeGM)tjN! z>wVA3zG5e%df$(JAEN~|HZ`fYri#hhnOS!4hWS(w(HpT=jqc+4Nhq&c*^2D3mxa-Z zYT#^$sdbucYh@>X``mzKQDIp@zWs}b_e%4(dWKB-1vjOiZV34tJK={(Rjs7mi-DWX zdqO|e^aU2@&ZmrD4N7ZfbOeB2Khw+{mWfVGp$dxmHqHhBzYcto2R+OPKsCDg0Qy=9UX zszUFtDZ-sSKd&V#j=F{hFhBt@@1j>mTw>_wwfy-WDKm;+$i0%J!JflBB`L`41s0YRa12fN=zL^`)Mx zsdSx(Vgs<(B}(V9E<4#J-sRDg(7G8f12AagE8+u`6tMquZ+Y(v&Y4`j7j5)1JR4zJXeuzNd@8sj$z+l2F#_Kqaw15DUpH&2t`$y z#sp+k(uRHh`p4ViwNBGBj9<6?d5uhj^6Ht$!K5X%$)yAb*GZRi)_S#1V_fcH#*QD^ zub$uJlpGPm`gv`!S|_2vHrkgq>mhpsLX(_el%&}nIYzOhgt^U&+%~BrBsMJJzpPs+ zTRMai$3ZAjY z-yVYWHL!V!7y%|rNQaDR0V&Z{%55!RaQ4aHGSv7n$7-7_c#gEPwce-RATRF{maL-g z(ZM;4mASQB)+tatwotA^ofh@=WV>kAhe<6W@ytft-0d5k9Tx6hTa=$#HtMKHf|=Y3 zQZ5)8N*j^3dBFZg%xg7^=hj>dUdN94Sbn8BT@P!)Qh*;n0dsjlnY zY?OPg<2Yv=Fr(?%18aJfiAf=M>M>XIyt#^u<<&!!=A;UpcoN#z7e%fv-mO4~IbNZj zC`vuPkn!Fdne4IYX}$SX4^uAgZd@j)I16+MQ{3%9BqN9+Urbn zxXPfvL2}Xj{=kC*@n2quR5Ph-KbEG0P(+DJ@S)$`r&;tl^EoZmzG=z?V+ik3yt$Nn z83@t$*yb!zd*eFuWMh?daG(yJ9D(HDvOYBC>K69C)s|XZeM3H|BDbxbHSbi0E0tW+ z$Z_sewsy~+3Yb_RQx+zL#|hS<9%9+6yoCXT^qG^t?42E5aTTCGlrmFp>noLl_oda7 z>YfNsz9e@ZeU!c2{XktG`pG$}LfOb8Tn9$;m1s(mXdbIV>j6|Z1|FiSs^h8g@eZ<2 zJ#=E`JazP@rk+G$?d~Rzj9SVAR1JA9$W!J_W_WTqD4O0zRoLE1$vV{)-t@-OMhE5_ znK!tp=O|uCMUjiDyR)HI#lgir0w*C~2FKji%VW|#3` z0`+c)tfEiKx>VJ>Zf=*YcYXz^y4PI0?7Y-Ns@eeVw@W`NIT)YHW&4<&{kyGAuO?6F zWW>nS7GHq)&abbUIL64~WfR>82!e@Pmp;;}2E!NwdD*o&X-@|1xs&2D-s~k$Lg+?6 z*AYLCe@)Bh){nMRe}b&(j=?$ZrAqBjr0@nG<0jDb^PYLer&*=DFT{c_$b)1tkUOTq%e6V14^(KY<)yW)sY`=asyT8PGp0G`SAq78Ro@`kuX{)_h)T1Ik;kM+6x*NH{WffI^Yoc$jvXb#i863nP3?qMDaar2DR*v{lR;V80!D@f zTz5L?!x(8s4yoQ*j%^IjVnx1rKI^k%6SD%xI;Al2qoXhJ=GDYR& zA@;?{e@>>ytA1)!&-o#pe054UvwgQ6F4wmIZ(jhVAe#F$Tli33U5cC5(QCbwU*(GP zHp4ss#m@%(DqC*Qm6Qp`n(@s($?3r8aq%b|Q>zT#GPUU7tV@b^XfpTva==5vA)p#zc;*iw7id4S2nesKEyMR&jE={~Ure6Pw!6r8_0&)G;KB-qf5?-H zPW{aW4*eku2sHi4@!GV^Og`l;JecvYkREpvZj3exw8-&0h*9v_^eW&h3T5X(0RmpqAow9GCgnzPX!4K3 zJp0q9IG%;od!RT(X9jM(BF&4G6L_X}e5}GVU$1U02}V?zC`x^oY{@mt^!M$moEqHm zuZs8`)nJvnHlb`cm~z4bA*5)j@O-f|n(^xN(2BN?1+`d0t#WdJLr%$gVv(Y)`9xK+E0%hDscpOWg=|E|8674&^}c20KC-2>W`S^s@|eZ2&btny29hSC?~ zkR76Mb}FW)ana;Fc<8$du&>BP=jVq+Hen70&&B7Y5Y$q1*ym7AwEvjff)nS)S2#vd zmo(zcIx`bR4FDdWbtVnzgLeo7aHVbB;=;W45AS zY?Is%u6`{W3@~%2Mt>2C6lV<1*Z$ZTdDZs*5Rz>HZG_~BC6fy!3B<`Rh(*0a>UZ|2 zGdn;Fv!zBLsw`<<-36~Uq;$1He6D23lr{BG<2dJ+R~^^({l{utq{R)``38kowFXG7 zde`&|E08PNEwC59Dv()Y1r6+Vm64`A7DsCitxLOH*=AxmreY%&?jA5$;`*@ZaU|TJ ze??3J5bCb-R8xlZ3&~8hdqFGU^#0VT30CD>iq9)3-hBNkYdiGP7SJ~Ya87`CjTs}8 zv)wXW7WJ-^TR#uzuhGa@$9o6Pa@A~)&L*IxAK zKNmJTJDPkgE`1_|*A5Uby6lnTQ69YrP`tn+2fn0dt7dMw7oAGSc$g{&4v!O*&4r8~ zg5aLT)oQjFT#7oX#S}q*S#bNJQE2X0)I{1HJ7r8lTICGm{{1uhMxx}py?$}iCKFgJ zttTTr0W2Nz`xW=&;O!)R&M=%oX)@k$A}a<_;yyY(0k2J%bxJMc9T2qc1ina}FQ z+1^9*bEs#a^;b{8VDDO)kVL6P_iVGuM4f}${d(89>s1!}%MUI3RLwc7H#g5t13^@; zQ-eBD;f&3m2L>~!oc`xdhHn%Ow<^d%oOF@HM{w^~B`{(8C#V+muS8~i5qrnAEpGFf+i)S1cG>ko(bT$N&i^h$O zjKmJCCNvA|4&C9at?C-xAL@jZANbK&3%FaBz07&4w{NLfUw6C-wY28+UoEyB#_SF^LjzP!)8h{9eXs}L%pc^?VxPbb*|%hH&4`(hvv%@R13qZzd@;Jlh1s60 z!w*vNP3S<*ycRF?9u@0W^JB(x>*U+CVcsq&?@*&!$_!$29-SCAO4hZ8?+)ZWJx}Qr z2`%P=UkTU)VQ;2V3DOpVoywIcUFcO&o2?M$PQjKJ8zA)}?-Io6_C<^`uEat7V3m%} zVRY)0Jld7U|Nf9TWKY5axeGxs$7O|;Sl4i3^k$D!RI*&oknHD1p-lDhe(*?uL#Egx zsP`@MV~cz4+7&yW<^r3*x$Nq51HUY?;@XXhAhU-UwqjaB;aV?}sME1m zKdmfvAtutz!Y2lEi&|=U?{O~jy8FR6&-#JgFgUg3jT=Y(p)W~b9{bF2s4y&St%lX> zgbs8yO`%on<7lRYxBVkkKXk4~7H<+Osein5r~U>E5}yLx2@&B)_~2_tNG)y%l;*F1 z`*qXO8}3ZFy&7QX_~qy>D&n^Ggh%G07KkV;i~uC|2Sh)iO|D?3m#DyK(Ad60>UBoO zTpK`5a(LRyZG$)J;F2or+0Hyv~Tvk z3q)3`8BVUqd=mmCF}Hs!jw~vATqrSbGc|TL3YKlxFrvDmW}$mo9cLQAc7_}0xV+jG zX=k~^YE4q9YHZ9>K1!CC1?)|Gr3JrK9K`O(FQ=e4UD8v(-OK|eyPvw{UPadC{2jtgP1g8AYES#fjF?66thkc zw0&vVJFE#O3>$Esb>HQzRkqqgV)qzPK8Iji6Y0^+CDR3Js-@Vb=P<1Hl9AMp(dcfZ z4>`nekJY3t!1sRcg2edXFy z$%;eIx61Q5UwC6s6?JTZwO?>*MUp9aj>iwdGg@#hyG^m;W6{1e%{|}HZDLFh?qa%D zwqSF4e6A=(5NG73LeqN%#i(w@E#MG|&+B_!x25$#s<*G)lj8O4 zwNvm{dJHJaz0s@s4Ie1n2cP`D8UJzT)(8doeg!(<=eZI z?X?On^&rcfwM-u&#cgMufgexGUNKr;ys*3JG}@n(%qQ+Y6D~~xi0gN>wQHR4o6OgR z8(X?uI$xOMbrPfcK`4O|4C6 z?G<(Yw9kCjy)uHzynEZVZw~<^y9TKm6ngt99B#JuYtsiSnRw@hl=$=Ego`{EF(DvC zav(7}TTl)*ipDGM1aXbFa53qfp-kuGO$>(7%HapxU*U!QW@N56lNpLu#^^5D$FlPM zE|}9Byu3@C`q(Ck-o2d8tZ=bv*zVp2zi*jA5M{iLPMfty78-HKCs3IfP zC{2Dc*1xo=?3;bnOFq%6lK+rA%(q+^9#e z@oEfDfw75`>OliT76;MHi$UcQR$MF1-^TnP8L)#5CZo)iHLQ%&rjhWHOhjcD!o)P# zgWu-9K_56y$fjmT(Z}IGPVI`|zkh4fw7d}D#CtCGn{S{`fBMiX53lrk#kG3fR`~TQ zSpXM9Q8Nml_)VJW89j#DH53!rTNZlJg;8hOs|ewY`u zLM=elDFl1kEtACiJwuzeTB zzeEnetBkU^IFQ5&&O#$D{nH2#t_;6OOWfo{o0*$W;z@5$ z%QC40=UR7UgVk*}2^UChU+cQ+)l^Xp6Ggk_lP_uMKrFg-D-VJRtS4+PwrK!>bo*Wl4zKzBU_ zaZIdj-%~zIO#Ji(mm@5@9m<~12(K4dqrN2S0(DBf&iWeK63^I40F`h=s2RB74&&E`|^UcFd@3HYf`iNqjlq2=qXrkbbTObgWwY8LnF=%$QQ#UIo5FBCoU z^F2%+_*ag=DoLS3`*E7`mAW3kX}|+JcWU`-H`5zd!iP=)&HBVV(`^xR5SwxsJsRX& zyP?=0;8&6?oOZAo{YBY{F)Al{@U>Apm4@-1Thnkqb1F>PG+ zRksM2^MUL%-Nh1BGMr4QW*h9^dIb_fhRXUQ2czzLDIY7vuAaUTfYn}8sbfgkRtC2vP0k1&P~9thL0PR0W56O}tmU*eKCd*guPk!lvJ~qqF~cO`TBsYg zAO2C5Ri5nxaK@Wq9cCo_jj6l!bo^pc38WW@E3;jhn&N7>BvFnyNH7OLfa+e@0EuU6 z7Ra5wa18nqalWTS1*|JjshV*55%k{J!z*tR!oJG%QxLx4so7a%l;D;x_Y`|>vAB^?Y`gc{N6 zO;;+SK>{Yx9l^>XEaXE=`qO0=P9YrsTQ`wYKV3QL+=l_6L2r+qWZ7-8vC^YSDF~y7 z*boCg+JZlAgO8|x0Kfc7az4Vscec?eUECqd=({H2=HArLp&=q+spsf1?X(q(OWTjw zqb#uDF+Vt;aQIOI8x)Eq}Y_A4c%q+C2A`_5)L~xX>DV z^#Aw7_Zr=)JRv&a9+~?{*rEm}X{rN_2EBai=j*%cpXMiWQWG-sCl>T&?v9}HtIbS_ zmD8RsI0>Snv+v;A_%02O`-Gdw)}`}gn7HW5GPq@0|b z!aM$ceqELeeUUY7mj)ot^rpipumm6F%zyo-!s7F@=*!>A|9+y*eBW zxQ}heNr3+bBY~uVdUWlanz@);I@8 z$I8jAG~M~TJGlh~Ts1)v%>*oi!Km4p{hN*x^vF2ql7PTs_$1FU7qqdpklD$Xexh%8 z|AsO1W>4Mn?)ri6CmEc1}{y$Vsg-M*O*JttO2wYlN5c$)>;`}IGZ>sp} z_SWg21Uu_3)4z>V5$r)V5-iv>{qIZZ^}$E~W^&c?@V|8d^R7;QelUrkOZ@BK9YaGy zacA1UXR`kt+LbK`%2_J0ge~@$|MS9Zb%Xh@&u9M6=ZgK8F8=>^#@c^^idViTUwZVf z+ggk{td&Jxoy!t(ksLlX6eS9B?!}ko>7fG_nnt>=x~O+}D2E3)3sl%`R9h<n`&qeHZDH4 zPH-yn3s8EftMUD=s8I>7Jg?7kEZJ$})|Cf9X^ly*#!7(-(#5Iav+TWYfBJemd8yg_ z`!Tt^@C2!0&qPM=czkPcISIgHZ$2@<)OE#Nt}4-c(Hg(`+Yr(0SXbO*=+HO$vh!{w zGuO~zS<*rcSYD8w;TV0RVb;d`<=d#gVlpL6{x8oC{7>-uKU6v`r5ry=69QkgsPymGzI~O5=I> zdK>~AZyXi5FfStHAjcmbFnP=?!k82Ngn2Rp4uif zx1yPOpOmvBjl(Z_t_@}#-ZxSxZ{EB)-}){gAtBJ`>eZ`{A_YW)uSD0^E6IE+Hmh@| z5UeT54~m-SI5m~)eD(G9_4Ga;z&|1oh(mTay|J_V49`3~G21#iNC&K02WfQbM#&OZ z{@uHGP|A?U;}~U#si_3>Ya_8=IY3pLk-~SmmEPKsV|RU(ma{q}-ctZUaI3dU_{`An zZF97xtgo+E*rLPc-n4u;ov9gpQNG8rtkY-oP-(Wdss`~G>biH^ruW;c1ejbfYiFCuf!iH%D4v8LLxx}dcVn_ zfq*4!*p-DxKG}z$lijq{b0x%@B_15KXnpsP*Uq00j>bVURcm56UMuRd+qyHY&9heS z9(M8j-(4ht25KVr4%1i%Qu#+!S3=hMIeP-$F4ZmHJ_NS%_hIiyRI%_rn@dqu*r-JY z*2;12ihl7S&S8Asb1jKuZ2*5PZk4hi5tA#ljf|D~MYR)XTsnvZf! zB#bht-p*m!`KJCetpVc9oVWawX2!ze8O|~#&(W?~uGOJ(OVQ?(+FGBjW6N$Qn`U`< z;otni->EU9C#aS<7Ys9Rbz%h+l6|m`;`~ZSUP@%lXUeDviOGHC)4ltUG4esCe8yjf zOs1EGGLmp(Mn=0|PxmqD?IsR^8HcG$w?6g54?^Th=p;0R+oJRaszbGM7GO+Q(UE`J zZ+DZ@S}_#Q9A9?i;U>=(u2`7uO%>WfWZ2n%Be-hch$^S0FcyFqGg-+wM1|T@iNNZf zHDIa|x0>CE?F@5k9Rq7%R?K&N>+(orP}UK^RD}t}oH9%1dIT>#;QMzOM?wmM={*_F z8G%cOwlgAF8TJ8gllF0BCShokmkY{j?{Ss~(ae|+FX=J43iIw*$3O!7=Q$jmJ1gjZ zTX_&6mpYrIYlrdaUfOHY^(n$KZl~ygI!AQ*M+bL@lEiHDdM}6kwIx_$TDn14jC0%c zu}!W(GTDML^R>(gVc_r!H*GC1Ll@w%7DL}Xj*i&f!szTS6jLKd9)+ojg%^dM{^upj z&+m%x?JNq~ChA2kZcBc}K5m6bqEBi8(-Odh8D(JVdgo6|!zm9W({4dMV{xGuV_Zo2 z#VJ6>QSyobU%E=*^bIjY;O(0?H`mirfJg^S@d^TNu^WDb;&HU*9)BunW5I#98gj30 zcPEL*uX!4T4?4o+HVULN80&`-i_D3(?R8L15lm(w^b8hMqk3LS0PWb*Id;t=keM8@ zEn8yyS|wFRi5AVDw2qt5YTnUetPElM`Bkqc7xXhITp%QXG4E1=gN1gTTzm9=t6CLPb*0Wfzs;rp%4P+Ci? z5Znc9XxN*oT$7vIiN(SPGBl2^_Pq=YYq2i#(%sk)v$z-U|IfdD0fBv$z@?gT+kESX zD%D#xs5{a)xQxbv#2p}fYmE+a31IdPNni6GYL2!ZVN9gp6M@Yn)VkQAaIW+>3aPDx zgvyuKy?S;$Sb0HsR?W^i*Zv$#UCD&%TVR+`mS1LaxJ?wK_<<_VFOa5B7?c?Q{!l_{ zU=w}@W6YsMBQcducVGvv(mw?}mN%X%_aiQAXlnL+zq-)vCkA#7jf_l{wT)t-zAOc5 zMDn22?`<*X5TtHn(lEAML<;$y9?@+xlqobY7x0fo28 z1q#*7=T$E4E{JamFP!y=KZi=TGR!*QG5Y`wWQIWdHM#;Rn>P2^$#2t@(}ypO~NBXdp<1!p`&X zR0WW6-@bjb6iYNEZH_Ojcb?fDxC{*wkRT!V+qg=?d71ktKs_$g>xaIkxRZn4*3;bP z=_;3%LS{2*Vki^ch;XvMzb^1 zPC%ywZ!MmGOZ%zG!@p)LSx|X)T5RjC#q~03M5ItF$4{2GzivOJtro5l;WK*_O2Lpo zBz$J4Os8fx-QiJyFpugU%>k_HIVWGTB}*FhsVM1)yd)Oxb-VT9p;$~^g`Ao_$+4f4 zyVDDRemvS<`p{DZZYEyVEl4M-I28 zN@h00)hKCfC&(5uvE$d3rL__XV9ue?#rq1nx+4}~wlg#wacux{V6(wXH#~l^|ICb< z*r2rY1Pd%oKnH#>#|7+7+ov+f@U+1zfGF5y5vz=~Xe7O|Wx$5%LY7zCZjERgn657A zgl(-Lr{UQXb=~xmA{bI>CsYwbzKbjAi`4DipF1`}gTS%+%SDXc=n}k3%6{8k4cWU! z;V-+}q+h^mAc=FE8Z!TwXf-Qr2m!5+Qg~Tz<+j*3O%Z4ESJB`fx}$d2W`IoW;hl`L z%cSgQrJWJUKt{S&g9Z8yX<={i+c!RwHm;wNeBVL(R)=>VWHu=t`1V25uj1xb;W-cz z&lhOFdklz0GFO^Q(5C^aJ8MAQKqq7c&9!E$m1{*?g*cJoiu&*sku2;BWmZeoUm{N~ ze{h-S#G+yJBPJ_CTLpep`ZmI4lGM79rZh#L|EY&k&4e!S%BqS|eEiG7Bg&I*IkW_F~O6`~1Pion_E2F_QJ z5xzw(Th=woMUVdQ$>qlD&h8#RKi{1{>S{331uTLuA(eH{=p+U%43%U) z-A_hbQ@HC|hP*of8G?3Pqfdik53ToAv16o_`&>Zl%bcj^#{*6?7a<2b$I2E_+>}lKB*w|Jor|kp#bMHMno1g#3e*Eu{kzdu{ z)5)obuYZxzlet>Q@&AQ=clyx~c7FMK*`^L!y5l$8K`HysD_8y-bMGD1)Z49#Vpjwe zl_r7;(h0ptRcX?D3%wg$G4|NX9&T_K>j@|7NuU$zL)J+s=cdBA3kPgY<&30+0y>z*qh~$kug8< zW@P~<`pexKPcoiNK#@ymv8EumQ1h2#F36Fvxebovc!Et}m>~c5P+u=oXM5Zvq}LK~ zlWS_mq2+IEl=2Pm1!-NNV3}iY{o+6Rpej?lzu#FMs^sLMU}2$NUd4R6uFmf8^gwe~ zPISXel-GYAO}K@&+Qz!00VJ*ct6Yb3)p_e<@3ct}UVBpvdB|AywxeOL)hHo*Vg-qoKZkJ&p^S7=(^=N@+sh53R2J?}H01C#Wf z>r0hsGPIjv9fPdeF$@uZ75Mjs|B-RHzSt%xE9o72tPb>?Kk?S`*%~2$D*sn4evQtP z-i3AQ!T7)QbpA;_Nbn+&qKtOcBu++24IGl8K}F%Uiyw>G(FRw6dU;N6U!QSWMzE`z zRLQiusnm5C-WiK_GSb)b@$o@_HnA2)phoc3l<+X+EN#tR743d5>Eev9O+9IW)c*ea zt=LeSOH%bAmZk?Tlfw?K;fsR{PUSeJa1Ro0bqKq~hWIP?sJCH!?wZp@PlxuJC#*Q3 z8p_4k1}dC7MTBqrC}moe%|?r2ZPuFUeGtB5@@WUl(lCd}GlUO8Y!c^A>REBd(l|xJNS}QYY3`ABYSZ3Yh4eU2dK`xCG9Y7uC`^`1x>SpER zn}-win;+@}jqA$9K@Hd>wG=4 zKfo!UHu^-s*{VPl@OadiE4#T(kLA$>Au!Ew(KIWwYniG^_z(1!MYW01$7xe(X}z}H zRYY%nD!WM8WMWd1gf?oG^0)A*Tt}slhHI_hz)iZPc!gv5_BrX(j}}@^%cGCvWTzV+ zrvnr$FwQ0#@6>c&$Hq`hY`8%D&l`_8gIA)fOc938^8!{rnuPaZH!Z$Sc{&Kd!sVBu z@J9M>maujgteoLSP4ENZdt$0-*b!Y?{$2t#C$!yb;K;k@pvnuMF zHup*nbLacN<1!;)0!Q-_JNOxqNoqk#?`P%UsPpk#2>GnR?L?Jga>NT_VAL6GfUyxS zIm%Un>6E;r}$H^vtNHhD;WspvWbSy zaOad%vZSF~mI^4ZK&N>NFCKEVD7n8hon zs;0+WT^}1{E{gw2rcSZ6Y?y?XxMzecEw|RcvmS=m8SpZwcu*4hxiAIU>vo4nJ^v{&IL&6nxjxz76}gKkQOjO_U+C%@ zJ?_SOA_3<8hVtn%{k-w>4VbZ_5o1@#(q4EJahoZz!g~dWC})#CZ;VhL^rb>htT8P8^wgoX`rF=$~fiGanC{QtR7f1&`7S*zV@@^ zcf+na%xMSKnWez?RV}zV0Vrl(c{YgeRcn~t&HgIYe(d+7Nrjj|}P-L2Zo%=>9 zKS(nLJLVBs%D#eNhk&Kvu2VKI3n_~Fau>2#^ZsPxdwHFE1(ue7I59$(Cun!{;J?8J9qu`k#?+q!DynyqEp zz*B73J?hd0H;kYiXFRw_*>v1s-tEAy&jT@j7uoSiO?JnqQ<8x4>3q7c~xhViN@-%R)H^u7c;eyrL11I_I z?c*tW?fC_H`_1Nkp;x|ik>jcL)evqpYpGhL%vK~h*h1;G+wV=ytw0wy@l`l^`t{KE zCzZdNGTWD{aU0LF=vHCi7@VYdX-$36P(Gk7>e2p3;`<~B=FKT<5y%?eXU-~I&Mxz} za%9)>Ykc*Ia6MOb_?_1)r*5E?YE5tC*;;F@Wny(<mD`&n&67n6jA;bYE)Z94oz&b7n-?(PrENd~G*OQtljf)5Q90KXad3z+@i z-MHiLpJ(z&E@V8~^Ne$NlL9F-xk(ug*!WkkUNI>CL;CFL<$rvzxcL2}JmOAg9z}k=KfA>C!{+BOUSZ*9ds=kpL&Uuad1M>0eJe(2l}WktoP zTViTd3M_Cq-1eG9wI>QQCnt}N zj;4z|g~NBo${ku?3)(b?^=CbaJRZfl>P;XG2c+v>cIZ5q?NsV_9lc_U&y<%9a zIgEa#i#Z`2~H?}c$JC?-TB2nqz=0wD80_MWm#*~as9;{_VW#x3R&|c-rAA=zP z>gh|k^XF$M=8vy*PUBCey#uHc>@|mR(0j-9-g6tLxKHqjy&y#OupA z5(+-%YB>Jh5a=Tp&1weXSq;i*; ze{w&ZtFB>h=qqSN!ib4`HdGm5H48S^lg1hU|r@utkA|T=KD%IF; z72ZlY&fq-HRG*(Vj~BkDluK8|a?0<4QvnZu>3LYznbzZLkNceJvbee>u0KbUnE&MW zQJus~3Yph+M=y>PU+(18(nx^SwM-3v+;Gdeyi?4#Vp2EeOxwU?mCi(c{8O8rLm<9+ zclVFa8{k(#2C=arM2y;srkt)Zbd;y@=cUgQ@iy)daQ+YZH^UAttBE$-+Z@0To7NJe zUqODS#XkDIcK(!~;J(t7?B|k#j3V6$D%e=(<&d(nObNs@cN_2w!^3eCj*lBL9#>Ae zc0XJA^J}5|3BTyh_hTf!DMRGgz$D+Vk2oYzpZ=b)8A+U8Glo70)SY+$`_U=fxLDgh zW$?Q`9Ksxl3i2RIhv3h$gq}TqbPJ;=zoUm%*g6|0XVQBtKK80?Mg(4Vg-rGCtOI$TUc|2(BY z>$lSp@1IEzJxBZ;N#aPVAgpmepN&J@qAt@=lTU!lEheY})N*AU<5|-?`l<1k(+M#_ zuxgbIhOv;aIkWfI1`^zIw0V2PO@=NpZ*EY7(pe`$pIBI=F(?9=xay#N%%q!fq5JP@ zgTLc+;6a1~y16l-43FK|6Tp0Q;qo&}OG`5|_s-K;WSp!mxBoOx_-_%FOsnAB$_lBk z?=J9W6xNRKFDcC@q?7#o{olmeCbAHKQ26ub&xVF4>xv@ce3Fj6)>5@*$t8aV#+-Ix zzB5l%R8%xIHNjv;xb<-pl_(8%;gpUrRxh<)P)kcotBR1uyVn08sd#zrRu{Cq4nHtD zdZK6gRXi4}1OA0rGCq!de-31;lgVV^){2UX*ESsh4}is8QSnQjZq^r2sR`evw|_uD zfS=#%$D-zEPQn7~#2SlJiMs#g7yrxP{ofMM3T~eHPI7Owu(Emv;Gc514}vx?8XNzV z_sa1eyzEXz)%$82xiyqEnOGKHjOzQcqBlsNo9$>|>sN*#+q;pfB}S|(@@%~i68s~D z=i3Vd%&mLz>}Cn-#{mT@5ITJOTbSV@PL%K{ss z1rDEbbMGtitU@A+)@nUn53*B;4vXd~9_Oru+=n;!W1FGagp?>raMG*j-PeqT#FDh> zTkg!K9`LdT4}VK|e}z+0koDe_#{e^)=y>iZNDiLw0 zoSah_jUYpzX0s^lh>vSd{R$C+fDKOj+4-Bf!gmkD3Ek($s_7j1L>=7CD+fPWY!eS4 z2fOF3iUHhn6n084*DHkWRho1t0oesi#4vPkIaulIZ$b9w+*9pOf?QJeY|H0H&bt9dN zKC&JXnMwSiCTlkw!_0&PrGAKGy)lhJF!`*SNDE+O>7nkX{0{8ev2hN$AaGiegPT=* zD114zYM?bu9-UDLr8E%Q64sL%Rv}SV5bIpk=^E;eO3UhqU@n~5Tk60O z*}Vz;8Hl)t-Ri#dh|5HZ)q2##$Adw*x}`}a?}!JfOo~vs-lyU*8d0yZ6GI-N7$_M%U_3f1ev}^7*DlG>MlV!l`g7>W=`+~*oY6~3eFza01_3N`f}=I=0w>HHQZf{|Jmlk>Lj zObA5(39>iM{wfwytZ!KG zXykIXyeD(suybPw4XpaJqptS@&)QaJT1u?)`rybjN4LrVWdBhs+uvS@Rhd)>^+wd2Jd zA_-_1-s#jhPprpAmQelz$f~Swtp36M z0V5+0k*qu{6VBDdVZd3`)Z&F!p|($$oEdoC(s;zhrgL(0(<{a-&6Uo$8PqG0=+ark zRQ;@K~xKU|k>~3?Bg}45N=swHf z(l{XaT-uz#z`?EL>OkLl+*-VN@E{Z62Ab#sBajZnE8W{{>*Y29!Ve^Lw7<_8&h7wK zMwqAQ`5F$vy9~J!-de9jpZ+kp4((m1;A3WmmObuY1`Ys7yPM!_5!XXI`gYHaurB&M zz8mT_uV#$Hq@Jm!HZ_z12aB+<~pBwwBZ^& zJB*^c?_|Md#JIOAm>8}$oP6Jo&Q*516}wxcWd!%&GmS2X;Yt}a(fn;j@t@~zO_^pz zuCm_4zt682F)i86HBw&o7Q&RKrHypEVlkm|@(E0slG+Vo>a$U6n&hyv@T*vpLT-`{ z-_VbP*OpraYHZrChVARd!Q=j-p~*28!)xM<@6QZ7;~RmuYEqG>U|~?xT>j`^T=wI8 za`iw&Og>~VVqB_ zVnLd_b;Ofx+dF!|t-)h8W2JV3F{z#iWt2?d3|@1^DtV^Pf5a^oYXFyz!@7&HVR= z-{-5TnB^HKY)sa%=MGMG&%a2OsirRo^Ir;3`Y}aKLNj)brIthVk?exp!3{YiM;I?* z3gecm>!?4tQ~$71C0kW1ri`f^Gyc&h=^nxQ(opttiCp416jV8Sh7J2~Jwm@2dOfbr zWo_UaB!yXGVm$Jy`?OzGFj9WwXC==)yZsl3h}x)qZ!^Weu>haI-#w@g6Jv5_X%#_E z1+$W>YOc$NVQVQ{kj;soU0u;1dsiW^eBCChg6*soqxkwvHCxd$AH)LEO!E!0K~~8t zqa~&-yY%y`3D|kl$U>NxMnC|nP=5*Vt)Pu@hWz+Fv_EuXxW%OIfh4BzTte)Rnu~!x zp?t=bWV>wW)LZhHI&m#%hH>^q>k>CjO!LZ2i=HJSIh2gwA6gN2xMi+unupDgG_Fgao7N0O zh>Izeb4rZZYr0*{R?{3mD5jB?aG$F7og~zz#-Fx}8?c;wFGNDP8UDCD;;!#LRto9u zi7uAlztGlYQW3KMEoNpY({Cf0{*oK3o7{{uPoE{VJMOjt#7E6=11RSSy~el3y<35xgh? zD;#OfdB-|o--!s#{*QSB+dgv9p1&_Pa6it1i%^Rn7_x7gC9o|(v_N1xKIR2U<>Mq-%kjlV62Nfu+RZ_@@;9c-ZaL7PW zxgw;(_K+fr$*5&K3W1C&W}3e`f9Bck-V2tK=2WM%H-ma4Kzw9gsO!mJawc2~Q_ zO{L^ct7H;$KC!=9<pLc^ zJSPcELuST%VxRU#7?~Irb@m4()`TEfm!LVdXuMkp$7k zUc*tKJX5xG9^y7y%Fa9e?E%aQVBc%`Fcf1>8H!@r*u&nwjcm_c$9X zojjsEw(!)FJ;P)8-6Bhju)5H*)|jJLQ)VB~`r~Wj?Nqg`?~}l2iwfIeb?$j7JhQ0NCO^f>3zRcptS?T$Qg`L*dljm^h zpM@)wFUDtf@t?<2rwTcE>CY1gL~;S0>v;X2G}?pBGyy)6b*a=y`7D`zg=#sRX)69z zZGdIn)3nsW^Z$6ii#$yV;c7;{H&}=3M{aie2V#m2vIRiiKA)pg8y~RkRf7Vf7^UiY zLUx<|jI-YF6Od#`Q8$pYQ@BYUOFAEmu~mxjdh~GLTYnV3XE!8o}y0wi(odS(WvN)}wbj%ytvKcAw!eR|roItW*LgdcsS|T1_^-z~d&+NAmkaUs zwf~B5k=A;`SW!f`KnY>6vBKw-4*^J`RR;G(p9Z`NSRWnb0ua;ns*a4Z9^EF-kTy?Ow>qYaP6%kWn1P zUn#P{1({iHa2p~@1r;1R&FkHs#B@5BgEb|SNW#=mFmCwEStJvcFe3@?i7Oh5Gh11{ zSUl9FqOEK1ZdnN;+2fG3_6|_!UV@uK9FR$mG9$W-vTc3rhVpkzmAPt{`~c^xn!e}r ztaOpnu@Xk^J`o6fjv&ow6F{{jE_TCI=D~qUB$cL$1onXs_{tl z<=7>0kcCwW*2W^|v%NTq%-rFf+C>Wd$G})*yrP6v_rJG-mF>u3;`HKiA@R0@^RB$~ zZbh`AG`FI~;oxL*e*YhMB_@eF!Do@0dEQQu^GTIv=IUXe_@*nI2@#;e4-@7q4ExSg z1)uz7T^?nd)rG_d%;tayEN1$JIt1#)!R?R6vE{~fy0vcIZ42`ztE{$dZ+8e6c2%oo z(}ik1Mw02#Q>{f72R+27;T0Hg5>DM*nb>Yq;-?C1;XqoY5-;0ANr-~Wcok$ner0a# zl7@!(spIz#I8gDN-}6yWo2;2Q0~#t?*y*Ub z6e9J&4!DrwJl!e3M_gk00-zD>)JqbFm>`F;-G*mC7>Qm)@~TeFg(WtU zg#CXReB>od`M8Y6Asj^M%vS$FLwRLB2?NZCx=)^QJyuE*2o!(-QdilJ0=eWnl&33^ z4BcBDW23Lzp)yC7+mH#;TWf1KRb{Hx@MB0hzEYLH#eB&Ib( zE08xEbTqE<@AzV`NjeJ`-+uM0^76_OK7H3<0*wab>E!ojf^_sU$-_?nqs8&Wh4j*8*W=qob0Ys#rmHQsE7N+jt>(5T8 z*!-<1Bdk%01o_r#nvYq&YPZT{S3Lk8)$E~0P|KPa)??&e@FU>TPVA-k9$~FhFfL#U_%6LsugMN^eBaeW zGok^~^LqK9ABvyCIH@B)8(6|nNg!oZ#nYvM3gT29N!#xvsZ$)S4J0qLR8vr^1=6Ih zh_2`qpIcF6x)G>@eO-l1NRThBb~f}ket3&HGh}c|?ws{sc%fC%KjDR+|Hcc07Oww| z7N-4;77n!t5Q_PSd`HNpf1!mF^gfU^QNDrf2~S5uC%tVN>GIwAlz4rWCZH#pE`H+{ zyoRR=q()~jhzPJ{>wCg@`%JfRAn?!4-4^912Z&XqZOatASGIEVQIh5a0}ug=G40J) zPJJ{xTB>0eC?X+Ns@6=HY3>y%x6D|OD#=J`2|E!8Itbd?RutrLK<(}3Gm`9pbP+UB zdRR6`W>~|VEp#L7LnI??X<`!wEJ|!sI^VliJXzGQNMj1S-_=*Rb`I=MmQB5ZaP!d% zE4|5p|22EffJRjcVaOuin08#oOrdZJ*jY_LIl{(thV3h?HCKXhFJzf;4{B9-uMdng zRzBM!(u%O&7QvT`yLXEDIu~E7FMZPGw?tiy^c4rC@M$qHORVy2^G-?shj5>#k%t{! z(e#n3)-LBpv6>;_PPDYKJHEbg6mWC@(hFGn(BS}*U;w?n^2Dvuq!=?$r0eU;;1k(t zyHOL$qsPqU+|5x~{|dx2^dpv17ly6Kof~f{krB_%+K2tR{oOEDD!O!z$^EC)ai;Kj zW>ov#Nq%wtb;}XvW+5j6o%ECN^vWO)oQ*vw?m0};|aSQ6$gm~SgS z`)jv+9C1`Nh6Dw&s(m!&PGBMZ2tmEyR<$ zmmy~iC8&!aNYl(d#ex8y7o=j2a*MMCL-<12D)d@WgRa!nz4pK+mE&-u>Gfm!#Z#FE zD{r`3#S(4=dA30^>u~yZK|G5tnxw`hu zeTAu{q2jJ;p^sa8mBXvgdj3v`oRbY#%Ra&79{f8lrzv1R_UO(% zJoVVfq%W-Jp-bsSP5Bo!udLm~AWUz=r7Z9CKlC4VD<4;I&r^tNUB)0s_8>0SGUIs1*VGN1kCaNa%SnEjmkQ!%cdi3)a-JwJg|Yom@X_r=Jg zRu|EQ2C&qA!}BdNV168sh=bDZK~{hWQd8O!Z+OdMb2Xe-qWGDUa)updk`EM)o0=F~=1KCqdc zAJb0Djm_V>fphPn-#v`(?V8{^=(6y(ji)WzMbHdBRUWyS94 z*$9Z(uT3D#(CKBi{?6^86>COz>5q}&#Smo$H?+BuNAc^#GUwre7&{FTXy0G*9+{a= zKMyPA5Cu5yK*6f(ybNO>^Ge61OS(L)6*V2WR!~lza5yx*(DMo~o2@?q>JPUO{Ik)_ z<6R(pTirk+qng2T6Ngehb3(aGrwg1O%%& zC+B=nO9#y3Td1}hx-)r#MGcW$v17*O<2F_2wNZoemE=6vc0aqm=AIpnce3CcJ$gE4 z3S&b^Ph&E3H@^~p`gd;1B~_m5rOtKKK6O?@nPU%YT&WesQ=DTLel>05FN`Uzkij zwHC!JQJdor4_h7{k{XXvsyrm>@0z;+tYPHpYcSRoviWr7iMfyUeq8s7D;PYe;CKu= zEx!4eT&TxY!Si9W9E*&sz77kgnj&P(9us?l;Nu_d2aYLxf&^a(9X0XT^B(I}t)m_Mr+i2V~N zbgWBKx;(0L*408wTXi_U2Jd|DpfzPmtz4Q#+w6U{Te)syP&n^UC)ITQ>owvrZv* zASpsKkeR*fVzBeU$L!1TXW73^wJ z_bppAZNkp%Gmc%r-f8g0Taj`qWQUSjC4Xe&EqO#NH^C_P!7T_R`HQRce+-M2(yjh) zuox2MzW=YVSmFOIu$cRbMV-Xcw$yITBmn_4RH12w)821iqeX&mL#fNl&&%e$F(_1# zNFKeLpEk?-vj2}}xaaYFixM?>{)!S&w9cVe5ZIeAUndJTIvPOHNx7ej`9B1}i2hGt z1zL&7)o$L(>@XA0y}7rHFjTJOhBr01YACMuz6dD+nd!ktlbBE@s`)T+77EYpb?EvG z#gFOVjYF2a|AoF8OF%9#At4)`A}erm;2vGxLa{}EKvnsm_X#=gwIT%zYXX2QxFt`% ziolu1cj~48!KW4(1G)pLHb_HtMAp^qdDo;EbU(UNm5$NN5TYE}*Y&P3{j`VI6X1rhWA%|*+e|(#W>6zst-DWc8QYOwu-W)l+05sNgu}!wAC0Z~0 zjV_Q@*Cc9*xFAnwv9m%f-)i0Xs5f4u9N#+6cb1oRmMy$f$9iq{{E%rhrt7`2_{a4y z!#v1L4PQyo&ix1Y2_r*A#SFdt{ybNXmu2r9P8$EN1oW8;kvu0AgK5k zU=?cTU`nPn5#wG82;80T-puIANd+-grieN%)m+Pr`_n%Hbu~db2_|(z{4WSIb8hYa zh4GyN9K+0JQ#aAM5!2h1o4W&g`Ko4(s%1`FIK*WM;@hT+(aI?`e46~IIzRHqXeP_V z##Ro4nhK>YKuR9XF0Y4lH^o9)ki&pkghvI5xf>4Dv5033fGitT>pcdMkaxxThI!=k z+fD)fyyZ3|g1`pc6%#Z|c%@`L0BDMIvy}e81jyL=%%a5v%rJ&DqB?0<(xFpUb&${IJ;#KcJ*H|tHG!uGgvJUf;E)#Ny7&Zv@Ucp9^+pV zul~gn>Yie`>l5kGi=>VyWbAepHr22BaHZ!MYI+_D4E;4ASFBEe7w>(=sZvM1=^w34 zWtrJ+)%eF1%Jhy@{IJiVeDNG`ADOFD$5v}%cy0N#=3gKc70>!fF#v@%1bnm+&*~t#@uM>26%$UvJfZVO3IP8{ z*mi^70Zr zgqV%t=+)FQTQ^5X9UjEvf((z@w(xh<#ykmVaX2-6L9G{oL=Z*H4vq&beqqAJwp_VZrz?cYTc3lr?d z;;5w{3t3gXb9j?KP>;(61%+Daa{l9f2Z#GxL{pf8-AkZUpt14Um(kbY=_I)E zp@r?w_tJlc-;_|bQ*A!7=R%a}XX=FIDa`3=qzG$r%pN&^Y9$8kS@^!wi;i>UA2yfr zIZW&t@Kv0=w-;r5N9b=X02f?h50q3YEHkZaY0U=*uA4EYlfPibg=a_FC|z3<0(0}) z^DIEx^r`5=lFO8on|sV!#>e)6Vj>mjt(D}kV)s+TL4~M0Y`0RBma>W5SRC(8<;@W0 zv5nC;!09y(X8fjg_4RDcY|Zj5bKZ=*1^kAcE_~-Tyu8Xa#?cw0R>{dJ_N)lqt)5Y7 zg|@IE;_$7@(d^Sm14F~;TVl={-xGJgxjrG&lGzv3>=6%Gn`7TYT#yhFo8%Mwev=P* zsC<+4Pf>#lyuHRoM!1TK4sl`YXCAAOKsByb)CUHMds@WK6w_pT3S{hqg~8N>CGIsF zX~DbS8#?zoJ<&3jNxc?j`vQ{BV%tMD<^qEe4QQxPztC0AheebI*bT&hF?VF!CN<^d z%kfyUkX;*B&`n|ag&^eCKI#Kun>V*3*~eb-lMH{-d(JOfeG{3-=RQ*?*8qJ(Ysq36 zT>EBkUGT@3$#0lzzqBF`w?0-Y`T0`{yfa(=V{Wd;r=EkDS9@sH_-nm>V=8bR;iRU8 z^4HF>VyrjscJWDxiWO$ZTk}1mx_I$*1KUB2hi{cy3@ts6J@vlruoAc>A@r$tpX0vN zhCzB!end2N{ID_j51*WIP|jD4Xsq&$tk~8rpu}O{)EDK}{PPlo7BYVP#w@-;>_)Uo!aNzf;_5!wtVE-JlupKPpbogH`19mMq8PFZ}D_N8QeYX2p_>X zp^8vib7>F!=Rb9QoMmnA6b<}+xZf-HM+0h+luAn(ey9soV!RCLHbRO*PU%C{!2t*l zEvPkESTh-U--^J;vo&YzZblAKdt#qH8eZ|ESi-HPfiPcyg-7nfl){Cm$omsTr1TE9}DL9k0%XWoU12%R{s59Z?>kUrb>Etjs^cS zc)2Uz&cEHBd-P$`LmrueLA-3*_%l(nF4_fN`+ZXmSMb-Jy^U{lV6eZ>Fq%|*2as~= zpzbW<)%QTXx+_u+bVfC1m$c+Z*7N*mp6k+=o+lkE36@m`y&LjCd6G&UFphk@HEVkm zzx;kp#6Q(;U!f`fWn^Z@Bh;CChlVEeyOXO-Kt+}}p8%bKMFA_tu}{J_rE;Z7%{}%y z@BEj@K8h!m3)<>mLbCGmXezagtRRb?lS9iutpNF`OjwpK#KOc*?N=MS_HFuJQ`LJb<>3Z+5r$`=s$4 zof((CtUhc-9}F7I4+6EM^UdKGxp+T%eu#F6_SLLeIiQ&6-^XuZa6viWqs-Nwm4w(% zeA)dn8e1eoxGzv%Cc`yyv-&r|n4drm2MhV6-bm53l>WZCThnlMZB+Y?yIH(uj&HxL z@rK)2&g_!2hi5%f==XsL*g`*eJ2DINlkc4cbar>r3m(Q_BH*6qe(kTFj)v*Etn8N| z=`V-1w=FWV>nMLbZr~D)49WDCK|SG)PmjvL;K!|DI{t-H*jPg~a92XCHu4!HX=wO@ z37y>&K&dOs&Jd0`^rbIsV69Pap8ePs{f_a@%|$K)y!hr0co6KBEeUMgH$pk>$zBG1 zd8$9+*OUEF=GA;U1Pw0O(7Et)m}?+mPZS^b@)E z%yCWvcYRsT5)>*fc+!J?es7MVIJH02iR|{|?`f?)Fh}0kubeOoEVnrB2!Q!DBCRY?1wi`fPxQef^6dfn$$dM{e89(~IR#k8}vvi?-S&LS~6arADIRY@$CVQ$ViQ2QcF%w z5Cy5`?5zWfA!CiF64&ko&bp#^E(rupS|eR3S>|f$70NT*-}kI;+4Pg%eSsD=#=qGt z@~O^DJ`(_|)?b}iOH&{7?gj!e1{q@M}4O8E2>mTTF$q7lWpIU$7apRl4$FNZ8 zQ>V@u?JETO8Jihl2EwYbr7nxt6Ac4<13;^-$dE`Jrb~KjK1)R(tZx9%S2KD7fyQU6 zfFJq5Kj4TaOv_C6mntgiDr%o_!EZ;Y<+Lv^J0~6FaB8DydrV=)e54bf>y!C27Y&z3 z&)HaU=5B8;MpkW1{j%3JF#055V3}83g5cghKoDdl_5J1rJ{)F$cgd_oRr0aHW-FSL z)M?ei&F2o9T{50!@GXdoii(aiS!6wWqO7buO>-2zlu|yOTF*I?9>bh#@dQK|nQedf zr)CjWP3!-597dpyrWURzloq@pZeN3Fe~<*Bn3<%Et_NF}lQy;HJDqW}Q%m_*tI|V; zmh#9skns%z(c>sekTp6CV6a8`$vp0QO{<9tuSEUKdo;ns&JsiWxZ&dzKPK|a6J?wH z8%Hpgj?vCb@dD;mI!3xan?s#%w`ehaJR+8Wi{90gKds4J!uU{Ey5GQ7m^KBlUGM!3 zIR@g~)$Ok#xOL|pl6c5B!SM-YVDy~z?&GAlk&Pf6(KK+fhOZ`_{{hHuuByX>2cbqx zg`7sULKq8Mgwz42So5?uxPS|kTM4zgGa0@|jHCap!dRV_V!K?l`jV{(-Z@qL@>+5)cF$MC8H{d;E=#Es^IfZwp zY5ZSRHj|vO_^+Tp!F!)-fx;4K9p7U@8tREGcZi;~b;cwV6}oToyUc@TR#Yf?w?D-! znfU_Q@1nj!eNhEr7!TbH_zbwO-nZcz98did(O0JU8yXrmuO*u$lWBref0a#ybq#Oc zGz6T+UieNQjtD0IA~QVWbxb&3&VmC#&%3zO>_U?+wK`h;NV{YkRLa1#$ndj(jQM$J zR`%-?S3ccQPwX^@R@|lC!W&j;yt15I#Zmsv`=6#u`vigFtk$+mWj9!o_B#Ndg2QX0 zbCA=*i*toTyWYJZm3<_GQm69{1itOkKX$0Uk72zmhd z2kyy;aN;i5bIi~6a3``O4Hd{cBCu!G<~QwGush0o#_ zNqwVVZ;h(bSwjXQqoTa)c6U$^ZN@9SJUsSi7-!}t1i3}KhPS{um`k&qfOV}-m%LA( zFs#x(8(tuQr;l@CBedq1>p?R0pvEH%9q4l#s#TmaeCGUQhCsj-tiBF@M}76Guj~s) z@4m%f*EiySaTI0=_to6$NTe6$P$a%8c}Vx{*`EtJvUdsPBfW9hY5olYVoc2F#xK{U zN{k9Gy-V=(QmaSJU(Nz+UJ>oZnoBT|=66no{p4p1&SL#|nuU_9n5($jz|I{**y#wa zWm~?I^oQiNI_WzJ;w8oWK+DPi-b{MsT|*s5$2=#*p8b5R2D9*RM;Fmjr0xoP$j;TlJJwf6ni*Ax!OSi@=GhMO0nJ`#zow>YAz4}IfZRb!7txsbJS{RdgV z*%wnT+Wvw{bf&GPtc1p2f9k9vww5{v&m5gOMogYF(J**!JyS9}CiC{o1#M(7-g`NX zzqQf1WxHVf&GC(+%k^PuRsz>=y&?F4(z8q7ufAtr*DcV+!m+kh`3(jjg}}qKADdjq z6M;fP&@=r^(Ei&F6ywjtS>klTd5?@o23MS2Nt%*wJVyD4M@OwsZ``^i6;NTvx2~md z!ir+ZSJt9H+HcG1@-L?-+Ld$VUuQVmpf>%zY{r)17PF}7am!CR*?1__yHTx4mrrnx z=UNdzWSg9)30VjU$p)|2e-PGx)qFp_(^7T1hSa&#? znA1TK@%*@#DI|oW&XkU82XWRc_4I?peBL!YTpDSaReSw`A=mkm_e;)3q6rMZ2pDf& z4{%sbvwa#2|Hd0GPxH*7ZY8t!Q!L#;SWlC5I$WKdrG9mfZElg7IS+V( zIio)4OzZps=2UlgH?u?Mp(MYvIVy{qsZl&#D7|b<`eBKxta6$l_YB<~w3(Haz?tu9 zH`Z56C|rumk!s{@EEXFQ5|Yf&4eZ#zLoBFH9l`rYJZog`rJXL#|1w10|M6p&n;W#W zZLpm8I!{{m-M;tVSipK!i}un8xkpq~JhkKD41n9*p%>6@SiFjiM1FIR>@`kzcXKw% zHz-RUef|AnwfhM`{rw4i9V&_yP2-j3)Q2gWDE|8LE$-X%=g$FO73Iv|IY*SM2Mj5X z4lOO?Fqth~z^Y;5+x_wnRIh*#)HkZOWw1qGtI?CpvGJ7UK{h1YKX>yM6BD^1jrSpE z$?5x=>NSDiCgtRUqhAB@e~rvT%PGtMr?hn;zQ@x*K}DpcRHREfhEO^Lq#LBW zh8P-DKARk#Wv0lQ*tg`JLvuT~ix~q>1 z4+c8_;o#tFG#}$EnSNJaoChYrLZ@{BH%F*9W?`vB9!UKQX7Aj-(=l42wOutU>$CvK zy8mbm>{$Mu`C-91QJRTWmB3r&g>?dUfGAOlafY!r^!Gq^W?&}dwH9;idYeROjJsNS zJfTfhPzW(wCzWwq8xT*hWahv}%K$Z7-J*h8W_@5B$VT;BVsCKIAa7~e#U@9>h4!}7 z2U`bA?viIb#Pc4UI<_p~4I|~0L<%;tHF67G0x(kd1YqIr9W$Gxm&%U3u~=qk+c+3C zW85SpBvd0Pkq=U9Gi?i}U}BnpFu0>Kva;q&*@R=VZQL=Z@E@1eg1>p5gK$&NIFCo3 zz`KoC*jEmMIGm~(Q-ELwEsO?q$vI3$xQ9Bb{{(d602&P(WL-&F%+)I!BOS7N*`3O2 zY72Ag)W+!L4}*|AaXq6*#&2aAdw+>RmCaW!kw*__+ldMgvn_w z?}G~P)|b;JlSu2OR&2D-#U`Es4sLIMmx7Q>wpGLZNeq>ATyaB}$`AvnEi}Z^7qO?5 zD(Ey|R;pJI0VFMf=pA#n@#7Kz^-3UMyGcIOADZ?KM$?vKY|>-eR>i$Xlx@2aUHSGF z(%b>#krN!b^fH}7vjou572!~JprC}m)D z@DYjMVDuraCDB?YjL~6awqYf#+S>YzOP$Uv7kWUh`)63!sUy}5$oPZmsjF3vD>9u- zmxPb^@B@?`fjAEq{OugMxg=lhww+P1-RblkK8Z%7V`k}K41CnPrGlUIQZraP;CEUJ z!we`+W#eiJsoDU!JwR}+#o*v09RL9$SWIQq1|wBaMJ0< zoQswBAt^c8l(3>Idkk$7UkIq}FDS#*7Z#RjVi4Bk##C%njuP$pIq*6FS~J^M55O|> z3$UX_I)_-~>N(81va2VAs&1zFVDfDE_v`b*`w>EST>ZY)r}4^A#!vbJf1{2aUseH8 z5;|ZGxIlvi9G#!=!i22&7!^w}!rs&N_E%oH8PD(2a|4lSK$(Q@jqIPjqvu+s+=R(L znwnyAXgiKP#@)1u-UDqPp39*)o^>S^_1M+;ROYPS%(r0!f=O47??B+=s1Ce{xHHc< zO`vm>08Xtx+QCWm$z9G38x7s$R(!}o6%bJ{&BMdfnXq~CAKeww{OB8=^V>ib>d)q^GocU{AlB+;^pD8GU7s~q9Hvc zj=8x+SND&gDB9JWN3ka~vBlWAsPm`FWLUvtbL{Q;drFx{j( za&PkeM=X=IGHry9PdHwdX{>Twh%JxK`{Lipv-ZFQW!aRgRg|n`9cBAirkflZ4#5YU zQb~f1eR)I(NiNU}gtt)lxEQ}po3*0-joZ$i%#4@#;ANiSMG0wGJ+38f;L*>on)k4a z5kz9;2s>;F9s0P;!W+EKh_xOd3k&1vREP$=YrU%lB{Eer1(55Z+ucED_`vRdU}2z| zaS50MRjp%J2s4oXudUySkHF6a1-$_7!MfDxb@=-xZs%8;Qr)kL?`G$li;4|n<2vKw zh_XfbY28BKnEJ?yOifh-7?tD1!`-t(ZETHaR6f6Cd+0PLPVI}DL4MqOey$g)z59Dx zUY8{9`O3I|cg4C$XSRvDpoR}Jr&UQSmV3Ua=;g7!mi|ViG#%ukA!dhylzJlfRs{Cd zkX3{2A@;c|xt-e1Z9(C(_L}~MY4+|CRRuO!M_A$!A+ACqd4Q?4gmExJtB>7n+BJbS zn#+Z>cSpOIZ7r@gka2jnn`EdTVx*HdhLWsXY}IrOl25ge1wE}TttdsolZAdDj4OG< zuv!dNtgZ1rF%Rqm)(>(fc_mtvW_Zxv7kXNn7`sj=c*@~)smXU^=d7I=2rcnj6)hqL z1I%$2q!u=0pwMc$%iX<=Zy%97rnid&BphSu+J1@M6wI=tQ}weCWRB?^FdEKg1Qt6E zg7j0vqYJ!n0FUjQf}R{=&fIz0P$(A1Yyfrl@v8NnM}4#pZireM;XaSvSN#oGW*CQE~Xg;hl_E zxy#{nC$26&fc(+f&9me+d5T=PDq~{URsGB!R`o06R|x==v6PBl7*2xM8u z+FYt!k#os(eKOG$P(*>IhJAL^lRcSjVR&MCDtftZ1($4RHyDvm0u$!vX7NrHF0m~y zTC{C$H$9ewS6CKnYQE9k8GHKM zOUkIM1E|&KFl(zpKT2lUU7!IE!O_|<^5>UNFqHnX_IwX)HS~>4zSQ$zEeZ$ypOiZe z?j4LnGSep$%$4d6CC7(Vd56ZVb~!3GJMB-4_v!DC1@2T}d=EB+%cHm&@J|QpmNWXB zeymlxeT?M1VU5J&@Y8xZ!d5HTj-r@AYJ zZ^)$d1ohyxregV@VM6MJr0?89+$xa?{SJJtW3QK4ic3P zwQAzWNhZeYxz0By#|T~4f6QSg?voob*d>%L_1ivT{%&xBw3gtvz& zrt{XVApEiUWqLEKqxci3;o^5M`Yo}!v!MauMJbH!$nDr{z6K}1=?XsnSa~yDc*j&Q zvqTMF>U2GXo}6f4J5dJ*N6VF_7+;&AwaMMR?W3aEF0FbkIIUImMw${ElAxtLZCx+g z_1HVyC|eWP=~@#6bU*ePZe!c#@mYbwK$N-+Vt zv>JE|t{S`?$uVR>%|_`6bS+|HyB(F}h&Or^7F#(c1%-C0L-qMZNVRyBc@{|1_L*8f z{Ipn2T^^2o#1c1(-I6rc6R$}cKQXuM=AG_WVE`QwFmmKqd6Zo~(6DadEI{c@rMB(t zM!mh>-5w_YMh?ZaI?$wDh_Z?ma8%qnK)B|I8R-wL#~b5giDvh#;~ex_0Q$V;oG+;s z4k_R5Dm0&yaW3qK-K8?Zjo2sp#FkpAn_R8N@Ods}(@_i_kb`J#s3Ef$X`8@_g=Eg{ zKf7`1(?R#6c5mHDr-^I9JXJM+x&n@zEXOIc^0wvRD6M~%xIFrmDcOkMW#4MYRgOAB z%ASBIt}D!y4H8r6^Cc-ob}B#dqb_L;>|1oDqqR3;WMfJ)CZvNYrYlyG?OfZlq7LO? z%E6M~RvBZ)g`fqz^KqN*Cv&rG{aEMBTU|CwXX7Cc zbY{W}&e1Jf8FEpFNw& zKC9$)gR=~6yX2*<(&N?h>b&v%QPWwj!h!rOPBJq-sJ?#Z3$KUIGsYpCQn;I#H$&z03i!NzNQRA0G2HK*(+sGD7JKA}U_oMf%R|YSW^HcU`pK(yEmZOYe;e8dJ zTbbs@Mt=p3Nf&w+_oSn=CCy&w>FLVlnhfl6Cdq%%wp+~SAJS4e z$?kO(`@+ozEojgEJk}hVgr+F0DYT`S3oeWGiJIAdFH=N+nz~XFmZqtFkDf)Vz*f~i zpfbmt2wJ15QxF8WkeT9D}4gI$ubxxQU9NUTA3G6OBEaV1tS;X5l9N5tmalv^)|+MXur&UEklOQ{Vb zhtNutKHsdOh;`_`M5F*Z(4qtOodXr?X5y84la#R7f~f5tG-i*m*Fh8?1%N^hXb{)NRe&a=q>k)Ej9VUZW^8$z35`;`RtX7xslxRMj;Z6@Zg8R_dV!TQbyO1 z)`q|Iow+|4PSF!vBdm%`+*4|x&0e$ywq$Awo0=~YwUQ`NNy#oP-?BMU@kU2%ORa|$ z*!J=e)sc#HF~^IB$Evn*9EoSPyLg|+E!D%?rv7MzBf^`c_6J-eU<2c}rgX{!sc-#r z#}{mnu5KGzN++?G6uW6AUBB!E!UQ7&&Gc2c-(Y`-#uO+ zYb3@_Ic7H%RFj1F$pzlj^7ZU0xO(~K=WUO-Hs~WG8_ra2tjU#Rvehm!a1A~BEdD?o zKc1{ZCmP9%&ACb7>dHwSlrXJ}Y@gl15?UR*(@)l=QD5;UT;AT6ATEA19^sm+WTw8* zgW2n2?qesyp^$C1T6A)0+0U!MmPAy+_pok*n`WAjISfYbbp-`fUZB!>zIBbo|nmwXjKC8mQyJf&eEI)WcdF(c9B<(94cs3iB8qK|4KZ zspN~>P#qi{A&mERZdQQX7OOMHlVLABnb!C0%xd2!YPoX~>vZ)RlMn&OMa-#x)m?+V zLjO@SVn67vDYRO1)3koHYGg(ZxmYJvc=HYO#@1|fNhE9Hl8zqcs8ULrWwbh?mJ__P z#GRK(Z!0t4IcMno-hpq@AfVk18Jn!jp4>H>lq_3O@wg~t$vsWP*&;F4bt{t^l4+`o zXmEIJY_3-;LjJ&=LTV2$N6&{!Cx6&vxCURA#m2&NSijv2XJM!tfu@B!z1Z^+5ExOc zC&-^tAr)wC|7Nc`+OAp|y97lSvqtHYTgYQZr8vH>Yc$ zilZ)p?vx9tL$v4SM_l2j5t~7Z{=)LC3i69ECu^Ba%T=k#YFI+Iwh>c^@x!Zl9dz?6 zJ+_3>QeT<~bc5VI{N){zJ3q*83CUUoe8l&IxoMXwTf9tnWV_lV0BS6H4GO%GejH@t z?Eg)GU!DskcWN9INw#|p!S7Rq-UxhM{OjngKV5EDp4ZiuS`Z)6t#?;L2I9jH6a*Pm zI|m6y(FtEwI)Ok6InStWdTr0PDCdb&#yAE$KEIB}{GM^lcRdCA3U4*lK!MH*%eifW z=x^swmJg?((=^xTdkJE*BF&n?ZFIP$rW;Bd`^QS)NRar9eH1Gk2h*+m8Ff`-0OE_$ zR|U1c(EQk+7vK3IYfbO3&qliSKkwo_oT8k6sOOqX{bD*X&zWlS`%%0d^NG#;t^Rps z#za=RDg78XUp^i@uh16%)PAy6Jy~gem_~;6XqsBPPiM~6g*JBhfdn5VDHE?WQ|*kE z<0p*d5iv#|K3M;`E-WHN6*p{iCT>QPmE1MR6OvcZOlNkQ-rH_S$9Vq4IjjiNtQ?x| zEJ4Jyn#T~Jtw#69vxIo!QCSx-gPWeX+{*9#p)H_7 z#M>i;*>Yo^U0+}B{9)u=H~E%+Nt#|5Jma*-0~p0;FqWZE9Ma*Dpt0pg=7Pl|y2&Z| zl|NE@j3iXa=iqS1L%X}#Q{TUNu0l6I%M~gTNoY|xk=H1n*r0!jecLw@fWf&4b`b%O zgYMZkpu_=t*=0@WSZeJOengGG{S&jZqr!VxAq0&3hi7TGPxfB^FdYKN5eP&Gs}gdm zbUfdtQx`co%5?sMr_5PZZMF7OEo@e_v~@8#@m}s1d4RWdSt16`OiDy=o9|NjLYx@7 zwVX3^EK|RJZZVqR76$XKXRfa1*&v`^QqnENjLsHz`*RVyPB)?zS?3qf_gYDntA_Ub zmPC$CTz+_)+$*OZwz3^>-yk4OXmc~JYg(9nBdC_y#!2PvWgKTuoHJ{ww5~@d!kPFu zQTimOfAZKbdC#C1FI8&r>L%VjeS1Tg!6LJI)$wJ-#>hloJR>7ja`;{#2>b!Re|%V1 zCKw{PP8niD$Y}fBt(H=+KstX^5*3gk?NwUZk0#|Y_y&z6#n79-tV;MDCYzH+y<<{^ z9`WMIR?m;>ZxL^wRIrIkP)=sXhR}B=nQKaA6hHD6-!wo~lO$FT^F-|Wa}FAZzdleF zJ|N??grJ6APzPzvjj=T2DRMPezRicaA@x{!6B}pO)ScQyC)0`Dkn&d{vft}hAmL}s z;l(CqYb01!dRpq^Vb=C)$aTB2aM#d$8ry^Sy-30yWdC^&bugaOa$MGS6VA{GAt?@53AzIJ;EzreLcY8`62uy{kWxkhrj}#o1_6=E zpz84RR*%pDl<4GZJ0`ZlUc7Jy)P!D`Es6lAt2APz_e?PPGUmMndiUs&pCU!4QTp2Z z?6ca#S7s_LYj5&<71w+j^%10tD?MC z?-yZgTPC4Gqt)*b@UC;l^^ulMep~I0IU^R9V)Q`!Ap4Jsld@4aGx}C~-HH_iBK}=m zmD;#ng*G#DmqiIZ#qRnZ?AzZnmi-wh?UDBCfstUby07!YOra?HT!JN)^G6U5#)QGUJprvZVJ_Lefj#l<-3tR%$Iucz zr$u<@z7dfd28Yle#>l$PITjSVDqPX zcD-uUOB6VGjIgHo3Cv(6XK<{eg4lWPSTw|G23=$kLe1w3Gl_Ewf-1K*=?KlVDD8Z> zdO<*-j}9BXFz`HoweJO{&hyY&&zvOiJ{uy@fLJyWb)YN@x= zO&RciEw_EmmS26`ZoRtc-iH!O^uYqYn6oOUrFJKO>@B}P!K$6vEmNU6ozW{`5Ag4> zYuo+~5LWaL*jJ>hM6g#*oT=x=4C7AOiR`w#sRc@)fj<&1=l6k2a<*t>dx3BF`M31m ztB+q6=&KT2{NwiAkbqac`W*Dm?{BsS`u*l_><04Vym3wBK%m}R|9poJ|KC1P!4!nq z>0-NX7!0cAE3DnY=C=ht6%J#&9%Ya|^L2+5U`gly<&XW_SM{$0Nid+ZnNL(`V6+Am zMT8c&<5~59g`3%$&3d`i+Xxln&TLu4Gwy8H_>yrg-X&Z`e=lZvh0O4mzAibFJigh2 zgU7LVt@&5pBGhCR7MY7iRv&TzQvp6yF@VA~R6=EvVVRU*GKW z%VOs0FmL%9!LD{0BZK|$fS&b;FR_LsHC<%E;aL0=y<+N1g>PbGKjO{@Picl#9|{*T z=48gS4j-)b&(C(7q$cVl9*$pXk^qzB5~oO>cpopsQ}Oo1$XPbll9+w0@_uw7b0nMVOF*7%3ES}rY$Yz#5 zySv&!R98I^k_NN#u*!MLo;l;NR`PK`$H-KOTPwerLr%$VllV?=qwe!RPm}V?O!KrE zh=@XQdRSQQ95(B8;-@BWjUCjQ%uRgqF4RR7ng%ChQT}JBVcfd2){io*TIEjL!e!9f{0 z%5>`bleM8wseoYB@S()J%ZKil&M|-E=tw9nZ8&H``-2i_J*j~`(}^kM`+B9Bf4v)9 z#({`cNo3bNW5(philmtnggQ!-xokMO!UarOrOwGZ`=p`xF?7(gVh;>ZI3JD@n=G47 zPT^IJ;M+i`Bs2(TdZx`>NEnQ&9@==!Gzak%q%343*g9D4)s|vrHOI~vQa`Dn2vcbL zxbaC%aM+{2AYPgB;KZImpmlFsc^9Xu?_&bD&URUC9PePHq6wx>B)m$m2w zX+p$~CvK5D-7F?7apy$RAD5zkYJ7I91wYy9` zRC{o{*JMYvW%6RO%VwIj0A(S>vEbhktfTlnZ66l|Go3JNdvF?H-?g-u$NDlEjQ1 zZMWo&{D}2SFjFv-mude%41KRBEbLd%0KtS5ui@sDcI+Dk2@Pi!{ ztlmy{L6R1;I)4$_9aT*r;<+0$ksbZ^yn~Jkp`W%7?tzyvE_Vl#_5$07gimpv=+aa{Ru7rO4we3Ntl*h zP1JnbDHvMUze;PUxhg}TbK?{C8-%)(506;B-`zdf*8KgAwAKQv?Q!-qp@YNgWWpiZ zkTi=}BF1_FbJx(EUbsJ*P#`klQFDNHe3^BuWZTk&&{2OWJNx@)o2=2gUyDDrS*SUq zk*vsUm68xsy_8Q*+xp`Jt0}r0&>mV@7G9@e@|6OHbCX|opGy|Kzcx<5<41s77NUR* zW&x#t&$QbrpW9{|%ySvwzWE?Arl(^Z<}}7g(Y|NaEg(3feNCw{MHLjLRZTDF4aniv zzYVH-%)kL!Fmfd<)c=N4RmkN{mA_a|8_-f4!lF(a*X$xCG&XY{O6L++idn!6{>fJ* zUQOy+D5tm|RE@+BE_v&T{`7HK!#zU!OY4n2Jgjdl*>dzFuSE*(BH<7zI`yRDHT~_M zGDSmHtkiEYEnCz%ZsiHS&vxzo60a5I1MdI=f|?|D{+U)8cuPFMd~$$3W>&F(%-m@u zE^Kt`ZJlweuv0@-L7zH(Imee`L$IioWEK}^;#ld)7U<1-+TqyjLsp{m!IBr;tD;r4 zN-+c(a@nM8bhnivRoNOg{S=JFRPT~)y~NFH$uD_o_qerhVp)nir*3S+ z4xQw&I)d&QV`_++tF%A-exhsFh|8R9vTk zY{3Yj#-bjMy00YFZN4+i(*r>lOLLTR35}Cg!kHvlVz)yp%k7f&;I1AnW+*k{on;e_ zX)m5Z;r=T;wLXPcRYpfJljq8x45uWSnzU43ZB_Z1`YIupr)!zpar4GvXA@zIz~hG{ zQj$6dntA2hL6v8Q7^PAkorM17SRrKJNtnooDG^U^Q#+`15nc@8)QST;{gw6w=sv!x zA6Cm^7+WjPoR(7~qQ0uQzE(##+illi9A947?uETfHJZM=R^``NPv{FHAE&D4Azf5^ z1?FVp_RI#yXbyfr$6ZNNU*Dj79448l70Y`%C{ilerpfF~j|Wfe8zvmhMKhA17Lfx~ z1Z(#{;aY#TS32sL?Uh1Qx$euVb6|~8s-LYF^G&Ac5ho#hOlvBF9(2?Ccc>b!1UtJw zUn?bxps}-2g&QS@A&?F{nHEA66A8NdX|;?2O+FEqt~c8OK4KHJ|O z_t=_y?s2l75fv;sWF29?Dx0Z~LLH_^va^O~+uGSF%8nGcB;9RZm~lVcNDtPvSF&kr zxi%A*JN*Cuz*Eh_nbCCXJEy;t5wvhL?5&ldm>m2-lt+g?*X)EM644v=^K|)-rpVO5 zM*F~%7`Y|cfCa?+F7>59N6JP&mVQx{_VkXLI`Ph#=-K%)&r)okJ}fY@@q#VyKj#?)>mSrK^^UpdJ_%T{?Hl~ibV1Y_v);b+dJK;*?fF`42d5x>i)nM z);qorjI5F|vd-KTUa2^kgw>mEK%T+StbP3(DKcz~Amhgc-~SBBnZ8y&V7(#E&T3%c zfA^CeF60wy%^+U%X18iJ?#8<_IbI@f9>`-C|6@3(X$xmv^u^5h{-sA{a7kAkb8QE95zq7!UN5IQ!WXOl^+RPbJ&n@Zq zZa--1XKpK9WMfn-Rkp1OS>mTYbZPctd_w%hc4~z@jMl74pOeapB|VZ!-6|vN5t!<8 z4{d9?+}C{Of^1Gx$HB=t+=#a4Xml!)nOSnQ>p=h{+<&$dUs%e%bR?f>U`({9GE&JF zmH>O`*otr6gX+i&W?CC#Ru^w!udjY0^7amQ>eCwZK^tpV-j_G}?PP#ttNxo@r`SNF zdeqzJ>@({Xao>8B&D;^s?OYMPc)ljjDLsm6&s4AQhF|Gi-$g^(BFOm8qvhOc%50V*<6$&|Qm=slhaAKZG)Db?M%KJ=7p!05C zqV80I>`K0*W4e~{Zcn$rN+<2$FnXa(-O`6cEB!<1afC=!6~Q8NH8K(GEWu1Pf!rRe zvZT^8P&Bo!n*)n7*1t^`bAnU(rljFSdO@DC9V)!+jqJ=u`U+ok(82Msz&ETRG~hwQAqQbaTBFTF{Kf~CV|Ic0Y_qs zJp=O)kDm5cvwhVUecy|x6J%oG*|elG-B0@Lo`t(*JZlY5u4{5yhg5akA~LT?0u#+X zrPBrP^^=v z$&Ihwgy}IQ>1CcKOA$~n4zS2Pv-x@cJ4=aR-C^vMP(CEq@oiH6invNBnT_2WAN$P< z7t)#x{1L&H?^O?z8+5FR2Ceh$i$~p$s_sV%9gwZE%Z_3@VpSn(-+-m~a)#`n+~vc{ z%*=h1{MjQo7FTmHMco(fqwp@$$2C_X^{>CS^2D^5zX%n5Njs!$x5-a{$qXMaw+Qx) z+ltFdnVV4eCFPQPvr|h8SN0gWgqf?)VqyKTTI^w1`56r#kIQn+blvw{1t-T9o~b)} zaZ@cR>^XM~)l+@qM_s?qOB)+(8;?n{a=n`FHs*!}n8C`Pj{wUKB44fk0a%{+MlvNC z``F*VG_5}+Gg1*k=f5IqZP5-ks>^naC?1Fii(p0Esvu%gUbW8CwSEzGH=f$LUd%h#zn~Ve&NzM$MAlI_wy-ll zCl7+ER3`vSj>WlXPh`-;7hm*N1?VCsaBYcPxz;lMZLH)Y!B%hvf)G(T@W~w>d%i~5 zssQJX_K>6zOYCEm@~#rDS+7Rj$5Iu7^_?xdw%?+&|9hO(>h$S{S4Fe}p+wc7<*+?* zPyDgb-*o8ad+aTl^m3ZwezorO+6caZAAxZksr;ocHfUqO?UC75(LTW;#@7TZc##RCM9cjzU)fWJzEc8Z6V?PEhfnC zNO{ugygc$_XoKENW3AQ7*(Wbq!JKYd|L3Kroz<=6Wgefs+iO6VxS%@=`?Bp?kh(QX ze+85Lo;d^LYDqxo@ElmJnX1WM6=-^C;%3=%Cfd&q+gsPFJ2>zvCkwK$rlKej5`flj zbmXSd66el-5Gi&3`rXa=()ql+_2FWN>M==?$oBM8MQp;~H~I3`6%^ z8_BNu?suT;!CjoyGzAA8V~2`kgaRF$s(Q+2F(mQ&M4*=zfXz2_tmJP?_Y5ERk<=vV zTlf}hO4(lc&jIi5Hg0+KZxlx+U%Nd)=-=uTpr(a0>uDe3HR$>@q~Yv@iCFq@!#u1H zQ-M;vI5R(V#dTj^*sOP2_H5YBU)mov{G#*^3$XXvABCl1ewXTq9L-L9%LkJG?W7xJ z9JYCV&Ocfgsu-M2)iXG-o^>)A_@<_w?+uHbZTN1V)Uj=zLHg?LYxjC~MRYDoMNTSf z*sAp_{~XuJP5UeZjo76Z`Wk#Xc0GPWeQih1;TJX=Y<9k`g}#l@3%EUYUDA?`Q{JcStiN*8oY!XbfJYoMHB-xBfsk z*J{pr^^X@vspxp^>V8m+r6gXQv!$&<#3%mYTneAT@(i4Z7qXr^^S2Lu&!#WpiF>A< z*K;q<+7hYIQ>DAJB1diZ;X-b)g{U;7hVPLUl&J^v+umpV>_FsL>Y&m01TJ!x25xN) z@lC5cgM~nw8)Pq3j?G&ae6pgy@E&=O+MjK)Vb(%Cu?k1dPj;y=X})_R-oy)*Yub+g@}Dt%RI`=84r#`8#;*@FV5+o;>bJt; z3zmW~`x;X)!@9#gumPE2g2%#-NUV3E*QzNX5_MvI)CJ~8vVGn7`BB70p;+tT#?OvK zzw1uspqDB2mZyD~WZvnM#Xh;sizDCjW!Fzjg}&~&o)K?}>n+a%l}^`f1*QwnR}6fF z=5d~-<6H-XjgP9|oo^f!Vi{bxZ=X|LguwQ!PfkJ>r@+lSCxFIrYQy%*bgsekabPEY z4M6;IOa3}rh&T8<=;Qkl5HkJbqUUJSXO8V+IpQKKeSI3b8De(I3EMq8fEQvc?Mbuj z>vyI$HS>H=OQ|kUl7SO>_Zu&9?3Dok`8DYld0C%LT&y1&)KklfYz$1F@Jvmg?Q4kG zbM=_|H(+Y@P6p*l8@gyPt05Ju) zIhyM6I4{gu@}QY6+{7H8C|(e+7G5kh%$D;{d3MkwBkJMS=vqq)C>F<$3ipdjuks8x8IW6B)-1CO>Pgn=%CH*fx zn%4cs2yKQQ+B%>VjVK>x1;Q|PY0yv3}0hRb^GBby9v zV78iYH_>&c%eiTkyGKC3Gd-Y({N>7V--nSroCW3Vk;o+F8ab`?g5=##bfUs>w7F7C zuCp*}vZ;^Bu$f`hEvTwknK}c1VrjEFQ5!jULSSDu{Vm?=zT~Fuuc;I^LG~GA7BHP! zh;_?@Vx?(SOS(4C^K=J4sLdv=l@LXp_OD5dv=(V#aZPRdAGgTTbwN89OsA?A|IsVt zudv~76B!-H9nd(kQ&;yKd!)DrZhA*cVuv7S1;-}pYH8fBZI`OQkhkH>-TU3vZ2avi zmn1i9I^MwN*m2M%PnAQ#>*W4qeohQ$Kwy38>rKGvu?!QQEbjlb%O{hCX|vLCq!Ugb zTnKYll|^cPv*GZ1N-pn@5VsuSxn(FcmZ6~$`p)Xk=-$wq*G7PV?JrZT?26`2533T@ zAk(;vQwUIn7k^jaa}J}eR=#?0!0kCvC%KTb?8jhtqeXb6@`ZWtR78b-_1F zgMKRnbKx&U;T5YfVdsPERVIe#A&hF4H9tlR>B_C)#^0qg1_`WWHyJ4m`PCxz=9uIh zeU?BC_Kpz7NQ@U{^=M2JeNpe9T#MoE1bwC2O5_uak@fQ{qKdCY}X5QlR4h zOBH3~+;RB%#Kja8IrUE-vH8eNQonj@V3n=z;G7q|c!93C8Wyj!)V{uzW?Po;^nM2d z4>&I|HMqF{uJ^XS_`2_q$+P$lHSwyc;V{+3dCBL+nigX#TT7=?kLlkQJv&K1UGFSro}q8rpo1!XjdN=2 z@n*!hj#w7m^ zxgn6_S_GLEi`*S1{e1H9MaBAG2yKJp(Cz|zX|ogVKb<+63VL-(wNnG_bNyri0Sl1K zDXQGl;Rxjzl{_78r(f*G75Hk8dF>E|!{c=m77%uKQ%KdopKJr`&GHH&s&kM@OFfDAr zmKFDhBFPQt!sL8}haRoME+ax#pwuwXX=x$*&5xz05KBWydWLksaksSavQTT|C^B&< zUZQv#gC<2Da5b>VVz;c9>uRVDf8#3cR_gglsMU`v;^+EOePF#ke>*>%Sy&}>;x(R@ zTIh?32Foj4tv})P`FuxKxMQ$xqc1bl4A%mj&E;=Y91Y6{G_*YR`PP4HDqBjk^sG|8 zF^62;rQ3~1eg*{c$kC4H2W_RCjFg%aNF+rg>8 z3=^(XgQA>fJ!RJFk%Zp%g_E%QN`ZddhRi7x_*rbrOazS;Le;cXkBQi7qHiAC97!jb zpKqs^F%g$_P#^NGbH-FX35TWO2fOFU!ZbC&oVuw6;L*ZV>Qh-M?nq zt61g09DKS-RiAH}RJ9kLnTFU?U^_^hP&2i@&tz&!k24k&nS{sClV;Yp(sc7B$`@@O z0usjTRdJeEBV*DuSlF5P4_N8U2BCYQETUCSk@q<;`g;0(b_nwVvqQG?t4Qi5+Fi0@~ zdYF>isyzP-uD0UlT@6-}GZmypA|}j6^I`fWYC0~@(iCWSdzyCgfRyKX|8d4IHZ6FM zk!xN5gjn%pI?l6ehz-NM%9qhWD;u1wuY; z?N1gqSz?R_b;tr17WPfyQi@VnBlJ}uFY0(HM~Lr!YC2c@9J-`k)j?QV<%OuqbM|Dq0aULY9*cd7 z(_(R*ZZ1&9v*K1-fsXKmQ*D3B#Q&bD&Ykfe1(r^q10Jv-#&O1M(o>SEh9`h}5`VO! zRNKi|jH^`KNP@0_1|zfm1Kn}~skZpX_`+?NggPz#1jghVQo2>hsWIN>=V|CWLgP7| z0Be2q3>0%l0;qL9JV{Dq~ceNs3X5^wp_A?>^r@=8z7=6*=45n5qFX<7M^;UaJP6 z&H<>f{3l~<4AH)0d35t7`D;SrOc|Q$q=&+Nw|%?!-_HS5g20I7`Zs#Bhzb4J?~S~3 zUdb+b%HSCf${>kn;}Z23tH7!fi=SG)+W|FWoWg>>+?wh72>g7wjQDF+Og34FFd6^r zAv3cbKnY}bOn@W4k6c7o1i;=kUm|M-3dKi}BJjxbFMrpp#Q?1jo^oZg4h4zKm)g?3 zM5wT+zStxiPoMDi2^VIDj~xYd%S!Xc=h_mfXay;DABe%CZYZjrOc}Z8DKxi|*X6to z-DM9x>stwX&>izn9pYzSz(ikM;EX$209SVB^2%<4iq-x~DN)70$}MCh6vUCD?>_uD D!yBt! diff --git a/verification/server.py b/verification/server.py deleted file mode 100644 index 426ce5b..0000000 --- a/verification/server.py +++ /dev/null @@ -1,43 +0,0 @@ -import http.server -import socketserver -import json -import urllib.parse -import os - -PORT = 8000 -DIRECTORY = "dist" - -class Handler(http.server.SimpleHTTPRequestHandler): - def __init__(self, *args, **kwargs): - super().__init__(*args, directory=DIRECTORY, **kwargs) - - def do_GET(self): - parsed = urllib.parse.urlparse(self.path) - path = parsed.path - - if path == "/search": - query = urllib.parse.parse_qs(parsed.query) - # Dummy response for search - data = [] - for i in range(20): - data.append({ - "name": f"Course {i}", - "code": f"CODE{i}", - "teacher": f"Teacher {i}", - "location_text": f"Loc {i}", - "sessions": [], - "alternatives": [] - }) - - self.send_response(200) - self.send_header("Content-type", "application/json") - self.end_headers() - self.wfile.write(json.dumps(data).encode()) - return - - return super().do_GET() - -if __name__ == "__main__": - with socketserver.TCPServer(("", PORT), Handler) as httpd: - print(f"Serving at port {PORT}") - httpd.serve_forever() diff --git a/verification/spa_verified.png b/verification/spa_verified.png deleted file mode 100644 index 581cabc3d5d6e8042c4ad35fad10d152b5f387bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35743 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%0A#YuBu3&boj?c5srkkyU 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 pmJSaOizOW{&H?6h1!w=_ { - const el = document.querySelectorAll('.result-item')[index]; - const touch = new Touch({ - identifier: 0, - target: el, - clientX: 100, - clientY: 100 - }); - const event = new TouchEvent('touchstart', { - touches: [touch], - targetTouches: [touch], - changedTouches: [touch], - bubbles: true, - cancelable: true - }); - el.dispatchEvent(event); - }""", 2) - - # Wait for 600ms (threshold is 500ms) - page.wait_for_timeout(600) - - # Check if class is applied. - # Note: 'drag-selecting' is applied conditionally in Vue template: - # :class="['result-item', (touchState.dragging && ...) ? 'drag-selecting' : '']" - # So if state changed, class should appear. - expect(items.nth(2)).to_have_class(re.compile(r"drag-selecting")) - print("Long press triggered class change") - - # Check that item 2 got selected/toggled - expect(items.nth(2).locator("input")).to_be_checked() - - # Verify Sticky Header - header = page.locator("header") - expect(header).to_have_css("position", "sticky") - expect(header).to_have_css("top", "0px") - print("Sticky header verified") - - # Take screenshot - page.screenshot(path="verification/interaction_test.png") - -if __name__ == "__main__": - with sync_playwright() as p: - # Launch with arguments if necessary, but plain launch usually works if we don't use page.touchscreen APIs directly - browser = p.chromium.launch() - # Create context with has_touch=True if we want to rely on browser capabilities, - # but here we dispatch events manually. - page = browser.new_page() - try: - test_interaction(page) - except Exception as e: - print(f"Test failed: {e}") - # Take screenshot on failure - try: - page.screenshot(path="verification/failure.png") - except: - pass - finally: - browser.close() diff --git a/verification/verify_spa.py b/verification/verify_spa.py deleted file mode 100644 index 6f44f6b..0000000 --- a/verification/verify_spa.py +++ /dev/null @@ -1,158 +0,0 @@ - -from playwright.sync_api import sync_playwright, expect -import json -import time - -def run(playwright): - browser = playwright.chromium.launch(headless=True) - page = browser.new_page() - - # Mock Search Results - mock_courses = [ - { - "name": "Course A", - "code": "1001", - "teacher": "Teacher A", - "location_text": "周一 1-2 (仙II-101)", - "schedule_bitmaps": ["0", "3", "3", "3"], # Week 1-3, Day 1 Node 1-2 (Bits 0,1) -> 3 - "sessions": [{"weeks": [1,2,3], "day": 0, "start": 1, "end": 2, "location": "仙II-101"}], - "credit": 2, - "hours": 32 - }, - { - "name": "Course B", - "code": "1002", - "teacher": "Teacher B", - "location_text": "周二 9-10 (仙II-102)", - "schedule_bitmaps": ["0", "786432", "786432", "786432"], # Week 1-3, Day 2 Node 9-10. Bits: 13+8=21, 13+9=22. 2^21 | 2^22. - "sessions": [{"weeks": [1,2,3], "day": 1, "start": 9, "end": 10, "location": "仙II-102"}], - "credit": 2, - "hours": 32 - } - ] - - # Bits calculation for Course B: - # Day 2 is index 1. - # Node 9 is index 8. 1*13 + 8 = 21. - # Node 10 is index 9. 1*13 + 9 = 22. - # 2^21 = 2097152 - # 2^22 = 4194304 - # Sum = 6291456 - # Wait, my mock above "786432" seems wrong calculation. - # Let's use JS to calculate in runtime or just rely on sessions if solver uses sessions. - # Solver uses sessions for stats, but uses bitmaps for conflict/ranking. - # I should provide correct bitmaps. - # 2^21 + 2^22 = 6291456. - - mock_courses[1]["schedule_bitmaps"] = ["0", "6291456", "6291456", "6291456"] - - - # Mock /search endpoint - page.route("**/search*", lambda route: route.fulfill( - status=200, - content_type="application/json", - body=json.dumps(mock_courses) - )) - - # 1. Load Page - page.goto("http://localhost:8000") - expect(page.locator("h1")).to_contain_text("南哪选课助手") - - # 2. Search - page.locator("input[placeholder*='课程名']").fill("Course") - page.get_by_text("搜索", exact=True).click() - - # Wait for results - expect(page.get_by_text("搜索结果 (2)")).to_be_visible() - - # 3. Create Group - # Select all - page.get_by_text("全选/反选").click() - page.get_by_text("将选中项存为一组").click() - expect(page.get_by_text("已添加新课程组")).to_be_visible() - - # 4. Switch to Planning - page.get_by_text("2. 规划 & 策略").click() - - # Check new "Skippable" checkbox existence - skippable_checkbox = page.locator(".group-header input[type='checkbox']") - expect(skippable_checkbox).to_be_visible() - - # Check new "Quality Sleep" preference - sleep_pref = page.get_by_text("优质睡眠 (9-13节)") - expect(sleep_pref).to_be_visible() - - # 5. Enable Skippable for Group 1 (Course A & B are in one group because we selected both and clicked create once) - # Wait, "createGroup" creates ONE group with all selected candidates. - # So Group 1 contains Course A and Course B as candidates for the SAME slot? - # No, typically user selects one course's candidates. - # But if I select Course A and Course B, they become candidates for Group 1. - # This means I can choose A OR B. - # Let's say I want both. I should have added them separately. - # But for this test, let's assume they are alternatives. - # Solver will pick ONE. - - # Let's delete this group and add them separately for better visual. - page.get_by_text("删除").click() - - # Go back to Search - page.get_by_text("1. 课程查询").click() - - # Select only Course A - page.get_by_text("全选/反选").click() # Unselect all - - # Find checkbox for Course A. - # result-item - rows = page.locator(".result-item") - rows.nth(0).locator("input[type='checkbox']").check() - page.get_by_text("将选中项存为一组").click() - - # Uncheck A, Check B - rows.nth(0).locator("input[type='checkbox']").uncheck() - rows.nth(1).locator("input[type='checkbox']").check() - page.get_by_text("将选中项存为一组").click() - - # Go to Planning - page.get_by_text("2. 规划 & 策略").click() - expect(page.get_by_text("我的课程组 (2)")).to_be_visible() - - # 6. Mark Course B (Group 2) as Skippable - # Group 2 is the second one. - # Locator for group items - groups = page.locator(".group-item") - group2_skippable = groups.nth(1).locator(".group-header input[type='checkbox']") - group2_skippable.check() - - # 7. Generate Schedule - page.get_by_text("生成课表方案").click() - - # 8. Check Results - # Should automatically switch to Results view - expect(page.get_by_text("推荐方案")).to_be_visible() - - # Check Stats for "Actual Weekly Hours" - # Course A: 2 credits, 32 hours (approx 2/week if 16 weeks, here 3 weeks -> ~10/week? mock data says 32 total) - # Course B: 2 credits, 32 hours. Skippable. - # Stats logic: actual = total - skippable. - # Total hours: 64. Actual: 32. - # Week span: 1-3. (3 weeks). - # Actual Avg Weekly: 32 / 3 = 10.7 - - stats_section = page.locator("#capture-area") - expect(stats_section).to_contain_text("实际每周学时") - - # Check Green Cell - # Course B is skippable. It is on Tue 9-10. - # Tue is column index 3 (Node, Mon, Tue...). - # Row 9-10. - # Let's just look for the class `.cell-active.skippable` - # Course B spans 2 periods, so we expect at least 1 visible, or strict mode fails if multiple. - skippable_cell = page.locator(".cell-active.skippable").first - expect(skippable_cell).to_be_visible() - expect(skippable_cell).to_contain_text("Course B") - - # Screenshot - page.screenshot(path="verification/spa_verified.png") - -with sync_playwright() as playwright: - run(playwright)