From f00fd1b62c7f2928b92a08a9c258767480c7344b Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Sat, 4 Nov 2017 23:57:51 -0700 Subject: [PATCH] fix(formatting): drop PHP CodeSniffer (#504) At this point there are countless issues about the formatting done by CodeSniffer. It plain out doesn't work in many cases, overrides format options that are contributed by other extensions in VS Code and does not reuse any of our AST parsing. For that reason, I am starting to think there is no reason to keep it in here until we have proper pretty-printing support from https://github.com/Microsoft/tolerant-php-parser that actually reuses our ASTs and can work while editing. For people who want to use CodeSniffer to format their code, there could be a standalone CodeSniffer language server (like there is a TSLint language server and ESLint language server). As said, we don't reuse our state anyway. BREAKING CHANGE: removes formatting support closes #501 closes #474 closes #473 closes #468 closes #450 closes #445 closes #443 closes #423 closes #343 closes #296 closes #293 closes #499 closes #471 --- README.md | 3 - composer.json | 4 +- fixtures/format.php | 20 ---- fixtures/format_expected.php | 19 ---- images/formatDocument.gif | Bin 52182 -> 0 bytes src/Formatter.php | 107 ------------------- src/LanguageServer.php | 2 - src/PhpDocument.php | 13 --- src/Server/TextDocument.php | 14 --- tests/FormatterTest.php | 28 ----- tests/LanguageServerTest.php | 1 - tests/Server/TextDocument/FormattingTest.php | 50 --------- 12 files changed, 2 insertions(+), 259 deletions(-) delete mode 100644 fixtures/format.php delete mode 100644 fixtures/format_expected.php delete mode 100644 images/formatDocument.gif delete mode 100644 src/Formatter.php delete mode 100644 tests/FormatterTest.php delete mode 100644 tests/Server/TextDocument/FormattingTest.php diff --git a/README.md b/README.md index 90c66cb..8e7117c 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,6 @@ For Parameters, it will return the `@param` tag. The query is matched case-insensitively against the fully qualified name of the symbol. Non-Standard: An empty query will return _all_ symbols found in the workspace. -### [Document Formatting](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-formatting-request) -![Document Formatting demo](images/formatDocument.gif) - ### Error reporting through [Publish Diagnostics](https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#publishdiagnostics-notification) ![Error reporting demo](images/publishDiagnostics.png) diff --git a/composer.json b/composer.json index ceb357d..a21535b 100644 --- a/composer.json +++ b/composer.json @@ -30,12 +30,12 @@ "phpdocumentor/reflection-docblock": "^4.0.0", "sabre/event": "^5.0", "sabre/uri": "^2.0", - "squizlabs/php_codesniffer": "3.0.0RC3", "webmozart/glob": "^4.1", "webmozart/path-util": "^2.3" }, "require-dev": { - "phpunit/phpunit": "^6.3" + "phpunit/phpunit": "^6.3", + "squizlabs/php_codesniffer": "^3.1" }, "autoload": { "psr-4": { diff --git a/fixtures/format.php b/fixtures/format.php deleted file mode 100644 index bd35640..0000000 --- a/fixtures/format.php +++ /dev/null @@ -1,20 +0,0 @@ -@&W9+-{7-kJA9ZeZoTYkbbf)fD1 z&Wz)!BO=%lfw5wbFhGPVBhZS7Ks7FRU8J?HfVrlSfrfytI#N@M_txzjl6st?x}1Vq zTmp*Re8Rj)BrorOCFK8%e+CF3dBl+1ioBdU-0ZrXaD5K=Z4S5=CtQUSF3$y*<%Uc1 zz@>QMQhabJez>>*TvQM)EC3hcgA4J(g}C8DoNz&QxFDSEKLqE2!@1#bPB@$c{!g&5 zurM?I6W8~wEG%$1+kXho{&&E?RD>_|3t0XT;koKpeLr32?Qha;@v2xmCL z3(obNo!5h%&x!k{C9jl;fV`1_lCiLwshF0ToPmY1={*heyE=C*bS>_fSr}SeKU(Nn zSQy;BXL9Gk9dkFgANX}8t%$F%Gma8sS zY$?_3EWO=Ts@M6^pt;JVpx!jS#VozUG=0D5DAJZ@n(Jkd9NLik?>iibQ?jeV-0^z>fFQ2PKfj^4u(qb4x}~6^J+HjGsGz4ftGgt#yCk)b|lzj)NII5h9twEnvP`P8cG+`8w&uK&_$^JgZqXU8)+{*W4In3<}n7-@(J zix3h30053N5C{q=0tj9|2mDhe003xk*i(=KO%I$xHG%dF5ugV*ICt^SFUZ*;LI9=x1)?$Bk!RQC&P$=8&n!@oM z?Kk`n2WpBY3ygB`eGc03?@7o?kWpNpN@hRWbVjkI{~}3|L|Q8LA0p$?VfPynGj!|9 zzc%@HN^N@Olip9cOFh1sCF1_A6GJ0lHFWBbL?oYkDcOHK*sg{0ru{ZwU%ftxRTEEs zUz^LL=Iy}P<)t0>x+tVgfm0na;#&5UhmO-s>-TFdPkts&&_>zDO5Ym+YlAlu{k%!g zFTzfdK2L+qh+A}2KMhfqg|6cFao&))wlB|l^!&`U#DAUauMB?pGuF_@7f%!`>%=Fn zQtS>n>f(BKgnjF}KHlE>6m_ckmheaexrC+-a%9&w9^xTVy=sWa;DAACbsWQQ)Z@6I zQ15PzZ{{1z(IP#J(_x6E0`^yU@*|vb!c?VNY!bar#Z$QiauQmGSyz5dGS8=^Z^^|rLq;P zN%H3U2NV%MjMlEywlIqX#%J;f^kaR^tn*$3U51zE8Oswi=uq=Rh|kt$0X9)RPwhdt z%T`fgKJ$1X`P<^H5`0AuGk*zL1OIke{aW#MdGqns_Qy6Nft`vjde@!GKAw`Dsv)WE zo$4`7f!&&^JFdH*<{V3QYZraCck6H_EZvOZ{6=c^8~H3{_c*x^)EP;3uzSr%V)9|k zf>R|wTRSuRe|`pZ4sNl;OpWXPAN0 z&_OTvyGtt?YwUPPzhIqUnnMITsVx+)9<=?A{DVXD_5VuH`enY65CsoVKt=pk(heqO zcgPVlqRp=_YhLy(G*S8zWlh;~xIoi)((w+;*FYH*7|*T(^nCqLkHU7v4yEl#s33r} zqo@n+Vn{@UX@h`7I3_}F5Y>C-W*qSwfI34^d{~(T8BLfBwMsD;MkJTQ2biGFm65z{KN!pbJ&Ojv`aHTkx*t`peFlE(VfZISfe~{A_Il&nY z_v;VyZc@I~4r4pT67t0x0}YVf-$8azB)vmmAV!&XrhxfG1r_0%^nhjt1Et7Rb$2%d zv;H_m63Oic|2dpzrd19lIoDQ~J*ULfEOSw|wo!-p1}6}iL@Jw6C)qG#ZVz zYD3j|z+zz<%_>@9+Bb|i-)Rf&*}nXt#zKFl8876bLP;%>sXS8{dRW9s65y~#6FZ5% zlyq|&ZnB4it29Erf6+Kg^htnCh99d|*}eQ?p?zDDbGV+uv_f1@UgZo}-1f$Y7hf8( z0ic4C6^bPha*Vl3h$`rT``+^NBNf;`4epWT225{v9uw)*ihN5*X$?@8G)<7^TWk*+ zaLqppYLjt{EA#KV1fCzFq6DDa(e0NiG;NP-cc&{~5y}>Q5%C|12-73j)*GjsKMU2R zwUdwcLMe!=8Qv#%5K0v3iVadWB)FwYp)-f(SXO4VFd0Bt>EB+pi-HNi=k#-B(WY-W z8)V0*(s`ETv!yakCRQb+LOeT=`xV6Ujt40)e>;BWnc;M1(8pW9E&8}2)IR4Cg*p$5 zDK;9iAMiWe;wyGZpzzck_J6MYjvGQ}iM$h0`#Of)6k}^WV7m8YG`3J1|DLuu#Z+qM z?bD%BdjO3Xcs`LfCkMr8*Yrgy9Isp#xjRSGs$AIveOs6WLla_c4D-AkGqVCzxj`J^ zQ*d?CT<{HaF+z8`&4WyhHFLL+nwX5N5~GAg`#_%2u1t&43EzUy?zIt%lzG;b=W#J} z0K!_jm7%URyV|?Og#6q$(;;W*rzgksMrH?+jj=fkwROFUh{Jd#k9{f14rQBMM8hwW zl&pz1RI2S>13nAL?L-JUw0I{lcWa53=RmGO9caqUZSven9D*A+k?tZ1<#a3H9nI5H zPRofk3bSiYHTg){<;L=*i+G7$J@_*nxd&#Pw{D&9Cf##dKKwl6W$4Z3k8T8A_8NKI z>(xxK*8#9FIFJ!6Umr^erp2UFA&o=kmf)8nfG7riHWa^W8Ap+-JoWI#ZPV%T{*WWB zTma_fQAlL6W~HO}*ZZ%Hvf<|`-9J=^x9&8ZPglf!Dt)ZKeShJ6rhep8`HSIgtBdp5 zw(#dPBOP-#EDtP9j0jnx0(TsLMH!Jo2&*&ncOQ`J5l@uY);`J;p%V02z}=Z+!m2@xu?aaJ((K!iT2W z-bc?`A_C_$PUPouD%{&6TD)lLUotbtKkpRJAa%7sHRl=;1gQY{1I!VtxUCTtC{f_hR(o+Xeoljk0w=!tipL z<eo&>8b<=_6@_^G(-g5~Gvy-$M9r=eza+b0pZ0CjyyAd9S}O+hAtT z1j3UKNHltGc-MG@6|KvGa7btp1l z4~kP1m?4;2#)H-(_>WI8V;`e{s(pzR*HkC5j5!B$eXs=8OVHwb<@GgME>tK?xtO@NX8VXFiqDtvC~V+OOH zQ*4zCH`dlF+NY;ZjOmw;e0_pfB@sn~sP6F5D*ORO zlc_{cuJAlRqM!4Iwa7e3g~V`a!%WeZV3j*#i~`7KL_+)Ck441TZ3V#BTY(L0JDHoQ zh?WZsyT%PEIpT0;w?qp~mM2ZRr|uAD#TC=VJUMoBP}4I7+(HrY&_0)XDD}D^(XIN# zQ~*PDDHD;JYi{}Jo*of6BOWh5@!RYk%-obNPGLG4lyx`YQ*;XiJhp;qoKtd_u)8+} z!tNWRG+~ZmcU1WjgT+LoL}1qY0c@h2(@rp@_Gd`UA;-2v#SH!$x>X5Gi5nfJ)fXE1s zLWkNF+0-gNPM|~S3T%1f(S@2+s>S1AqHvB4cml*}_1U9VKLrp7BL{X8&U-WcP+lo#aX=+GXs~Sj>m)HL^V z41R$g+7OlVW|0l#XxTp(On%EznWGMMO{}04Y|Jg4Avwa4RukuyIT9avWZr4avz*Vf zI?uCV&bO1xcetPL=%4?5$xQ8$5s?ZB+9rh|n0y$OFLLPZ$7^cUMl@-WXOoprBAIgV zJDZ{kQEm2F#ZM7UU)P2 zwe?bgFbVY=8}fBT5rGIS8cR_YMKy<`h#MduL`C4n3Q@KtX~k3~ZGiOD7h8AymFUt; zY>REDsoscCjMY&&h~NY?X$jo&{BA50}N9^aYKaUTn;t|D*{AQ)bMlSU_~Qi074a#V&_ijX=>T)nNEmJ3Otj90BAj?P3c@ zs1@9Y_21^r?|WzX1+oqxkHS`i4~pl{3FC|?YTHSw{q63Kkq?Wc;^itns#hw-L$`U=Q(I|>41Z)5=0G`8^XjG98wGj@U zH_R;*rtXtZr#EZ^%qAbS4!msm8pZZKz9`nHE_)D`>*~L994d34Hm{2F+d-p_BrIO! z(cOyz5Jxh!68tBMVi#2bKUt zs7i%F3SMQB6+q<#wBt^61Fr&b?q&0@bl7he4Oc)Zkjj6J-z;bKbIvk9q2(tZAeC7> z`9~2F+!&eqaz`bEg3}H5-Ub5RCWB|U@4SQ=C{!B9K)4kscrFR8-UDxxc6VNM>01 z_08su@Q^b*ATsnI>1^-4PyuJw#D?w+S{1!3I8B-%rEmq1tk@K8@l&95VRKM&cY*t7 z%)S^b1xlgcQK8mBw;@E}^B_N|BBK7sSTRj0MLCXTym%NGOup?wL^KXr6B!{gwv%V6 zIq^Yi)MbV@H>PCsnH++&HHoE&)Jt>});$gJD(P@vc`#eVDRTweBCp99L{Ok2Evsq? zP(k>hI$@sTiATz8MKM+MaF$y?kOLgQkFVI-AHP9b0l#`1VKlyBQrMPF>DPzW^WybC6jQiD$2ivUIty%9YA)njDh0o~ojA!LKi!!0b z0ZR-ohi7Gem9!VXeoe*nMrBU^Stm`yTug>|T;N1J+ZSo^FT18+k{^nv?A}cODwa|9 z<@(fGoc<;B*1Ryyd_n9y_p{L-oM~ay;&=MzYaTAt1}@ZREHt((G=E)ay;^8vTkN>C zNH6YUT?FwjY$6dTWHgRYGNU#dgNWn(81nZi35}>mMRLHR(4PHVblTL>I7y!}K=9ct z$TRH?t<=2TVr>4R%g`ddXp`nK)u}OG_KmN(sZ?dyuM8aE(J@l6DDl<4_Wd@>Kl`~v z2PD1mq|VM?=Z3!n$4L%wq$O(=^ZrE=mQ>06Aa1G;l;bMKz2@Qi#d~Pig*5G(7f84f^Jy9SM69 zOuUsUKZ;7uirQ#zMOhJsAH|XO+5n8&$Ub|lLK9YX6=C{#+$}sI3QNhiSNvlinlSd! zQ@5XH{0CyO;VUW4BVnpU8_IecF*o=5{ty;|U6#1%8c8XZPm|w%-DU}O{@BG4VLH)E zY0jJMRi6Iq?NgcUcrQblT)KXJn0zfui5hofW;uy5xNnSd1i!PvXX@2PIkHE3>l?^( zf9I+Vr&GQ=GJ+dzBOR+C{jg8zfy3#G>`oix0QYvatiD!zkX_*@8`{*Z5kJ*3N%xjO zU+_DZPr&;)Qqjy>>z6V@K)}AL}_1I776Lk>$6XH60B-- zzri#f!c^7<*~V8q-zVP$5dSG2f_^S0`_L{$T6fpIf^4Uv+5^(s)CS@JPwrFl7>VU5 zifla;>@Xl^v{3=u@u~e_FF~sp{kkEs_f0+KlR)mL!MMefT*Q4&ZnTjKgEvc5{HMS( z^UGl8Z32je3S7rfg$8xR+rJJIhCSP-1Xd8*pvYQ1?6Suw8~1}v_E*4Ed(*dwn_*B2 z#gpf+PW*1d!ZVZAf=J~nzOR;@-oSw-@!HQ`k;=iq!)@Q+*ihCP!7%#=n2OD}?w`Kk z$R48DS47s70R3^UuoT7SjP#;#1hJ?HI0`Xp7gJYeG!i98GFri&-bOxzC8Q{!aE~Y7 z+K1l4y8`dVpO?HID*yQdY+U;|z1Gl@Vgv_B#gQ|8+km)>x|NHNnQlcP%shfriww-4 zWOGIW3dG}@<{(t1Rlj+u?~j@PIlyd}<2e9JxZXBhH20;i+2h_eZIm||nvrU``qd3i z6O~%h<)T+aK`G}ibeEO+`u#No`=bXcUx8GwSWw0*%5m^l=;e31*?h0+iI%5i3s%~A z#`x`4B`cSeb}ho8gQ9!R+fJKc$i;at;;{n8TnhX`(Y+Q%QYtUTnPjpLGw zXHl%--T>=p^>S!_5Iz{-kfusibIhS;KH-x6aIqvOQ)-ArlcV znq5oVG&?$&y?n?@%bOG@IYim~c0?umIg3g4yr(7(C2nsWILkVNIE?k7bfjgHB>pWf2DQDw%dC6w^9 z?0jxeqGr+z4Jn*RgK;qiU8WX^zA^HzFmdoQo-VcI0P?9(J_j0iv1?1@N6c{A!)`t3QFmBbfJNzYI{6nse5=d<1BsV=M|}yy>Qp8-rmDb86a4bDNVq z;FomA@-eGWPF^y5rPRj{d(pm8?YR(*-_)a+mM|kO2Bzj3gm$DlFyWh#To0c0`>iMV zuod1Ve;zfKpUr=cW`C$|z;jP$PbERm1DJ9gQO1R-mX?dCCy<5xFh3NnswF_Kx~} zN)CHQuFV=ds8xAQ8DEMbX0#Q35J9FskP23>sElh-25Ig%bvonum+IIZmRW}S4CY&J zQ0c^T(VL`nNsm$8sCx)v*;Q7dr!c1Qc|sx)DQg4NvLo?S&Jl;{sLNrExyv;A1x-?V zl=N^i@Z+%vC5$T5j7S%UzXnvD+YWgDM2+XLLI#cEM06-;YAK6SytSa@g&RXu$wDY@ zE>h5TJ7w@kc|ObP@1U1H0Z%uVdq*MAh;IOrg(Biu7Z8Yr&s0+t!X4vSV?c*!*N{E8 zK}d+dbGavjagXMrWTe&ZXX{N-DPYLU=yZ4FN z>f76WRnXMTW)mE@H_B-Y_)=OgZ|E>{P%xcoLn9%*aRJ^pBlYYg^wEzMe#jd7<4a6` zcRf~I$_?|mTmikZ)#UtrPbLVs@_|spNtLc~jQ!i2EXpt^`EA>=2g}H8KzfJ7sWB?r zXDWvs?Ci?QY?3(gjJ8)27C(=Z&VB$5RDLU>Bn> zIkRl~=|U|H7n8S*X8BUnMTTK6W_fbv#doHQ?{>S~`P67$?lWCt4R*EYmb+7xJYD*D z_Z{1+CuL67blKCeZL=IB5ezH_Ly99;mF2)wTE`>GUxD3hqPIXdkyz4~%>6VSSaq~i zw?;^qo5KwOQ$CS4;s}<0+A(ZMPpwnc2k;XorKo$6dP`)$vI1@ef%`MHGoOyQh19b} zh={n&KD`cn;{Lp8Av9s8+|@{V;HV+Y8L;Bttl{qUR-j;x`bPy($-2beIOU@7Y~yVA zo=ciMEJT#&!-IIuvnqM3!{irDN(hT5#QqD1wX-cVU-xKQE7C{qoV1*DKXnMjsN;af z7*}mV!eor$@!D(~v8KlocO~To&s;lY_`Zjn3Z*sXW(Px$NBBc~V*d*BPIe+sjD~_8 z^}D$)UQN#^^JY8xy1DL~;hr&%6zuWLvvWPtJ)UvTo9(kq>{y{41##G{G{<=iOHVV) z>$gKw4V+S(`hZU6Dfual3j2uJGtESME)q|`y{CIJd&<a0>`CjP#U(1E`3~uw#ifvXzKl6pJ4ZPQJR#%5wF&!Y*a6~f zOjU{|>;w?F5uBA)@fr_;zLM!_-7kGiTKDyLM|&ylkVkq0u{kuM-bBvEQ!0}7jh4)P zb=fHnav8?M!>6Q9Ts*!b-V~-AO|`QVCEhofM4yEue)}{ZK$h?DC;!N>mQc)XoX|9) zW3n(X@ci+!`aQ3@1+~~NIhc@C*Gc9C7gZL~SC#!f?sP#YE-}~x?d2ObB9r)WlZC~L z?78SWe0t14pQ6~LyzH4`c44Tr+UM6YL=Q|pQ|!ccez}QH6w5LJjrEazPHC&$P?#KR zl29XcIt~Bo+FXr@=n7@2E`0aVGu_V<+acc?EYm!B+B`0mCuv%t2^Pt4MfO(dm$i=DIOj~C8%0;k%&rL4hH}9B0@0@SUMjH?Omm^QId6V zhJ`V6Y%kCo^mVjzMK&wv%NDg6YZF<+f+tWw8H@0PP)yBagneX(W>VQ7PR^fRpYN{} zi6v0oSo+K!kAAdFdAm^B`;=anHqo1gSEEUZO{X!q4QOjeEC+~?mLUCJq8Kex@0LdG zpAOXnb?|m3sp$3wr2#Ka`ecWM%(6APjM*~IuTPo>vGQJZ#igR4FNgl z_B;vTC!VNUJO}yCA>Fxqy;f;9sl$`RdY?P=`gr%gK==A4_4?)Z`q%Wn?CK4e>J41& z4La(5g$MPaX#0Y>`$A$Wc*Ik_GiOhV^@YC|Reo9C=&ux!tIgypIh5TIHPy$^*%!Ik z_u8Q{j+Il=04Ay!NhS#8NAykpRKz+vWCbDo|w3Ks&l>Y?Kv5$GQLZQ$AEnav#bcz6mA;fIQUDWC#4$2i zugx1O_TIa~$!27_FT{5rtSHa8=|*mdB|ce|bgDpmXjkoe$L>jpMMq^lU43_$6gwH9 zN-|9`5nwpoR*Foyb(xKBVhtZcLoTLtCo2d8>kYnG=#4E9KbQ;VcOtgIXj(zgFGY|H zzr&OYBVOVn2v37KxI5_kdxjQEEU3^yZQNDJU>%EyX9?Y2P;%acgd3Ike8VZI@loAJ zSrs6OOfjOqF(vHrvdQ!GD0?yPRsr-gn{XW%v5(PBWCj(F3aR)(v^lHkT@l6B5)Hd& zyhn?Z(2NmMA@U)yG7{{NgcGWe`=bCRd}s(n`Fx7z_YiBN*q6Rh-9(^reS~9lk7Wu` z03ck>;`-XW9tc<9a9}vl_hAJHBI-=_*#}2Dp`W3`sma7iZdVZqDk|(W3GB-;SAAAL zPZLd#)^U;>2yKigjP~*%BJKk{tx!;l4`oaVDS1Y!ZbYq(;Lrs`eC;%6ADdp`9~I~$ zdb|OYVvPVWM|&e9?!*J%M?)_C%p*~EmB40GZGyrUp-QZ;5QwniByA~FnoBTi zw44t{g_u8V@^85t&I-9{Q+f!TOJKB^wi#^=Am8LvWqv+BZcjysvWN^ccJ(h{ub(@M zCypIM`$L9n!!Sa~{NRiBhe?w?V^q&EL?UkYY;K7$-HW&*(z@A69Su>Hew*-~Jf?Mw zTHr0!XQZL0X+gvWcA}4?WzjOfJ|ZBc*_bL&=n5^GmdW-A;#t0;4Zv~lFNqZ>w;HyTj z{zT0fb({RaVGT=l-(rFc?nPLH?=U0jE$iyG(zDfAF6OS|sPC{A!)fIBSWGO*8}_SR zV|=Uy133|uZ-^Y0_?v@aZ*GWB8*#7TLhC&|p*AD&w4hphbQY5sdCG(KW<>YeZv>2* zgW6<~bVi-D13^B4+ir>GKc0TDEKRsY1Y(Y)axeHKNiA1PMQ61XY%##ejN!#pNy>!I zG?hDfOxeQ13sS773eE7|vEyVd?8y(=H5bMvBkpPE8e0gk1wz-!=GXya7EGjYzQw|% z5Kpg(o;eerXwzWRtY8e(x{(y}=z*IT(G%!O?}dg_V!rqq&d0WOP`~T>ujr>038>a5gstBO@X?zI zTmjo~!U4KiXHH)+bp5;DS`hPy2Y#fIFFyQxp7I~_*wIO1ddb+&>W0OMA#X3snH}z&C}yz1oRZxv^&U^2 z5eE@LxZtoZxog7rj6US{6rDP3sn~xvcZIqqlk;hB7L{*(uXmY65n|U|GUm&9kOM2h zmAu$cilzwWZy`>7<8+UpL6|V#Q%fsYf}zdO=rnlhR_rIuNb7pA^+p&F1Ger9V@m;M zmxozncV2}MemHi<;zRJ(5dCT%R|99_UxBV~=Y<)QE6v$ZY!Iz)57%e$pta_-fO;^p z&*H%r+P6>Fo9M@k%?|hsoE;Zt)fXo1;hdE3Mz;}SEt9+y{^?#Hc;q}-#A9$1f#&*`><>Td^^dk5@JAr^>3_Whsij4p&JV49nU zdqI*nkzX5=!vi+Jq}#h}#*cuzMckGX%UIgjBPeIzP(q zVRx``UvDY>ikn}-AAaP1T*(IjHRl^+MBL~yn&qCpF@o*9v@oW(b{jR=r0zQq)Y{BE z4twZZDz+c?LGhi)oY!<;q28+_%ev(IkI6*=hcl?hTvNYo8JMi@l8f(yS?RZ&5s&S7 zeJCHtN+b6O5x;pp6Wb%7Jf1y%vVQD-a{QF|#Dn3)llR0+`sA6`i8tkmWIwTWpX2jC zTB&<0N_eTMlOILAWBPByPhMKOM8-7rAVWcv#fx;uf#0=0CYOFN^u2hQ`D& zOBOla8D6ImCt4GSKuH?_8G!KI#rLZHG$^J_*h2daSur);M#5|_edb5{loIh%mk)`+ z)_lk0kG*rIq1~IpFV~CA&3)dF`tdGEu{c?$6BS1@_y@$?lCl6CuFOV_^5t2d`^9+o zq?Cmzm}O_57gL^;pPak*zVL_aReV2|?040azWDU`qV~l_UBpHGyNiZ`i^jT(rrwKm zyBF6J8={g{-wX_iX_15lb2|ZrZ3xE;c;9|Jp82dbkr<-- z1RzpzU+?#Iz4sSq%Frk;RvJH2r^hEln4?uV{1hMPR?fQt6vr%W@?LF?_Le-o z4X_6!&0g-E;N$Y~zj`++Z@&E9>s0g6_T=54vw}b8b$>2;|6I=gxmy2&Kl$^A7{d-E zrWSPCM|7Z}3}S8@`y5>uYF?94rvuKO7-ng&os9#IJpZ$Rj8msW?tvu!yH#$Rhc|{& z#2!zSIzP*&6?2^toD;2xWRP+lsnI@jFl(`tekb;1>xgfv(4@em%w_sflBjTyIu$+# z(f^vqns&-*0z3@OnM6H&vVAPHSnstyQRaHW`A%FaNL#d175hfS+O)jI^;BfJD~dtf zo%J2*Ji8_JJ`9;R#KeaFBDc45CcZJ2t;LQ{JnOXxHXZSnHMOrcoTz#{S^nfgY7cEP zCjx_L2H&eP;moPY8NIW!IPgyV>E5N^F!B+tnP!=d8)d7%>FvlnuRjoMEcd>-`Ls3Q z&MaX=sVz>;#%dTzu*>CvSHxeQpRnu|2VrSlF6okO`00AsLrD1R5upNLA0l!vSTp$^ zjJfY#D3eP)M+93{9SsHwIRY`t^TC$F*ox~pqlFq%#)EGT$Z*9*=0y6D*t-z@(c{85R`|)P_Z8h+I2s}UI#Rfx}ogRiV`y;a>`5Tcrv2y3g z+=Sb5e0fgv11j%QT^cvTt-a3q3bWGIiwg77{P_*!4w4orxyyrrw{x@Q1j;_SCr#gZ zNPfqb;bTu!QCT}w-c8+amrjFFUVCX{F1M+&scti;OWWmXe(6=i?CeGnwOmg?FnyPok9FT0TytthvdS4Ru`XVNwS+x2{H zL4JZ*01Uteh!7hVyI#I#0REZA{qOj92L2Dr0OUS^5CTGo08rP^0$if7f#9}*H;LJ*9R>6*fUA03?#5Ks^i zQ9+?}OG_*C^ekW^>Y16j)3b~H{a+g!Th%qq9Uc9|#563dY-D8gj7+TmhkZr=KHUF( zG60DNkY1Nt#Xsdn#jMx2kLw60VORB*5w+6@V<3jb&v~E#KqkU~QW*qFJ07N+#`z}8d80$5(VAWg*e%Ul*|eaaSTHaREn-rr0|o;6Bq~f$lezrltQdrs$`HVW1OdSU zREA0c)Y_2vwk;I`Vk2rB7&dq|l7tzQVw3<3h0;?Hf&SJfmkL16Z z0f;pKd|jVL|8;#5g5u|lxU|CIgl1%X)SUf^2x*t8IpZIOXyTY?SG zcu|>huYeh{61K+Zn_lWE=nA&~!7b6S8%zzXmV!9RaNuWRm_hAsbC_TSvy ze-Hn62L6AafopD-m<*=;|CXEO250}@xLILZ2=@Pho4uWJ`&03BiAA-`*MYy>Y||l` zZf)t8YNyHKhl90c3w0hV18j0W|8TRvw!RM5ef<6zl{G`IS6{L8FK(7`8`l%hrJJeO zQ1xR_o8A7~P{Utt)^J*|v1W6!(6nSm*Zu?Qa=#Qa``9g_5%G zO-mpA!_6AH2Q>UzAItgRF5J@idwY)3babSp>Ex$#9X^!Zu(kOte|faTdNe5D{P>!i zy^9ZOy}CGkJUcr2`SYt${!MNi3PkUO3x@C%;zG#mXl+7an*VUKcbt~O7(&ZWg%`BQfK&5-YP-xDuyuys`3HnTT&SUY*`~HQ_He zt0%R&`o>6;??;l^9p@i!EgXw}BwPAy{&;8emzzy?UQ2b#FIr1;tKD2n_vqnUfA2lx zyq@8^Rq~ z%uW8w%@%JJm)36mJpwh47Z{caTY6bF(ll!GkW^Yi_oi@p0)v59^DagI+|0 z;9(#4JGaArWI^fSfMDIu;h;#b;IEUNJ8 zJbHyr7QJVmoP70NFFV113pm+5`HmtMKEx_Napb@%Dj@43exuZ|aA{Jc8BMcl-nuD*MUKieqy zh(F({`-#8U@4flw@@V$ypR3dLkALu&CqMuE0gzz<#M*5@=6w`I4+~`IYx@U7g~eb& zyxQ&1`}-k`Ls%l|zIF=#{ZIs1)^DJ42X)#$8mX5Bz1!D8-?$$p5|c&tSi6&Xem`7h zD2w7nUnl&0KO#YyEE^V~-Nng#fYH{=rheDg#UpnRX%v%9TcF*|fBzuLl$OIvyRf^- zqcZy087JckXOC!WUW}s~Df47~vSgL0kbA(&y=7!?)mUYmZ37qlb9V17pS;&Wi%RT1+L;i3D2XpG8z9NyT1mpH>ZeE@K+xHI>Q-*SRr2G2~{14w?$?}j|Is+zY6Nv-_ ze;ryFFa!|fC5QnC6BGg>hOh9$m-x{u{P-1q5|5w8&uJEf@_>C+4_7#2) zk3YcUf8p`xc>E>)KgZR7Uh&^rzTWy;*YA3P$DiTxr+;;V#~)wo>gxB^)zQ_}^(P%7|Oy4dMG-5EaGn*6!>b$fGdYx7^RvAKDze{LI_TWcFztLxj}*7xSt ze@(9c9$7o-Upwnvzv$Yy?A*9&U%&eNSFNj;O-mQ`U(Y|yUsTLqmdsq{&s<`sFVd$j zlE%(s2hSq<&QV>b-Yv(@bw{S9`--XSVo?j6{==-^eH?y6HzQ``6Tj(Yu38nWxfHMX zmw(4pE~ZpZXV;A9eHtyQA1$pPsBY-0ZD_4;XliI^{0}w!E9x5>YU}DhR@M|2f6U1% z&dJHk%gHOs&8^7GtjkYpE=ubtOYf`9m}~y9(wVi{m;G}%_t#kN*<}9dWcKM~*4aen z`FPsdX!6-`;@QyaO)pDC}`G#}Z>f>0&zAU-V*|%!)a*Y zdt?>+rNoBB{#%l57SqQHSjO;p`XGWIv4op3M%|{3P^Jl$ph1by_}`>;667-GN67K8 z^Kx-^;OGQgd^Doi- z4eGx^bsaF+{}Kfy1r!Pe5s_R^F(80|2`CAHECiq%1VB*&(Cur7P9^!LvqfDfq=oLk z>TEG?SND2I(TBx1KArs*^2$SguJS)RTfAA*4*6DprP5FHBit>T{HMjq9XyZ5jE7g*QAJE^<_t8il5c&%9bc zVe{n&o7AJq@6P$HhUzOikg?Y|s) zxT)^vcPxh=1)F=qhTxO+F=hQ6a#!3~j_wD8e;m3YjOLO|&QfXxtAl?k8GHZtvz?8} zYlm*V<-SYUpbOz$dU;yw->3k&!jg_Elr`}Fb!fzseG+c=z~4+-oi50w@i00Gi*Ybq zp}TT1_^(4xs)WRcbcH!u)9Ve76QLCz5&YBH0?FkPA1}Tfk{x&gWYHJx?jaTb$D#LB zI!0s!mr_J{{58bRB zOw*BbtDU1#p4uY1>`=y2btylLR54IlkEYKRuZhc!y}q(ytDL*@Ng2wUdNk1EmT#j9 zaJ%I@;rcOB8=%44Cye--yJ$9_M~Ho7U-qfG+eVk&RU1ag7mm4I99*L?*-MaBHosL; zs1iKPo=4$HDno!v`$mqncUGb$pQC16R;*tn z>a!;p3acz!H4C*bhv5<_WlTbeG$hWBxG*5uzU<*?2UPL^4i~>@MU{bwN#pB<3Oqxm zajSYb<+D=Hk5+(hNqA`7w5aqve)Oi&E&r0RZ7N?Jr!Kh@)bWD<3wjHx6oeE(O9=Ol z9hOzD{&E=z7K!f^5^lOPSW@PuR$E`1Dab6i5+wzaj7_bdaa>CGnZlx??06Uba^G$`o0xBQqi;9qLMVcv>!aq z(VXf6M!Dtmux?4~k{Fpv_&6ZoY{*+5pPK?Z1@je;QuM*u#u8`^8vxatqInx6mgbs9L@qiO9%ou|qX-)xtAYxK zF6`t<6T}aVflMv$1jKU8Hb`GC=}Q!i^>C@Y>5B{R$;0;Z(0?v6j?d12AM@Zn>*qVe zWAU8KVKhe6GFe0~M~ocR200L6NP^(1VH%9b9gIoQ*f*y^%A2Nd)#)lKuP&dyV|niI zC09ksBmO`V7Rv+IEB-7{JN=;cw3CpUkGV0N$iWA*DcLrlFV=HdD*DLMW;?!0C2B9F z!Z{U%@`bo`?`KL3@gkn*tL4klSxc819A;OeU5?tbL}42B3gJo?WFpVkajrK_=@qA1 zp$p0vk!Dv6p6Lc%n^CN~JD)qcslvvcKII*Ph_h$|EDTLJlW5KV1f+U^=i z{$Zapmzk!vI$5@gC5bu#4OCl$1HP}QOx6dxkur)lZQZMax(_+6$NgpMP!@lm5Ky?AL zkaX?}5dvx4_=#jTEZa17$o&y-(&yHMIz#!l4G+q;>HS&F1#8+RY1czpZoQe^!Z)V7 z*p)L&tOthYqA=zBmRKMtCFw{U$70K8fxq+ zi+U?)MdL@)%Xwogtkol1h((6FZtXb}Cb~)Ap2g~Y*d|XQxlGFcpzbZB+G@A8;e;T; z1En}2cyMSc^Nf3GM`Ur?^|Owzw6y0yUr%t>6xQ>9e16_I}^9&v(Z6 z=aV(Av2w3_t&uhI=gvLnyykUjy&4tj$N8G>veHhSYvQxnX4>EdH?=lp)kEPoqek8o|oJs{Ec_AHFm>Bsz!o34kR z$}eo2Zelfj@4d<*2L_W$*d*|36n;feWUV-*C<{!cyUKlicJ(Akf73O4$l0mn;j{T5 z?!%xDtj_@grq8+oM;rbP9I9wG=>!nkOp!}w-cA(TR+%j@bW=DSkM1SHRZKZh19Mhu^}P7x~S<0+SwsRVjs3gr*uZDK80)d-El%G+7Q;*LUmX;a{_z~ zDdvmoMg?rfBosbvut(@7g>n?}O-bY9Psfj^a5;N=BgprHabbabw&7;>1W~9L2#691 zEF2pV-g|-{W#Kds5iYriGJK^{(BR&DV7)AY{yKx8gagYhM1ueXUzz#OyYZeKncEq7 zRBu@uP=G2uL<=!7uUtu_PHYRO3~l@IpTYu-LTvDG=ybbz#)XV_ ze4;D$95>)Bd*1Oo8PM&v_@8R=`p5AHaM%xtgcG$VPQD2jkg$`s_1gOX87rgw^( zk%LBiO5#Gw{Uv*Cn$#$ir!xq=ax!I=M-J~6j%6PYwGvT1!MPqa*%F~8xdn8JbhaH&pB&Q?MpnN~K3O8>p zlTMK>BaYKNfhMqrhE{PNmmeJE*p_QxOK3PR$nhlm#4rCnEd zpLGduWs6p#tS&4J;l^~x1@%mA8`U%$3V+vH1?drXU?B?sG(3Ucxa6mOs^PMoamUN> z@M1H9TQ#gwMafbd$CO)f3-!!W$I%q$<{+XK5^`t`#?>r4;CN#6ceP9+{~&8^htE8@r2*fSPpwXl0_`qj!E*-gvY znK(5?Kmwi0+#3I!g>b2Q4*yw1?VRWR-*=>xFLEx`70dLhUY+Cc1kSzUa=vxr3F!M6&VmaM!YR-QMTd0EFqAExkpF!%(WbO$uF%)>#D4_fXX zH-N*hFVFoNw4~DJIcdks3n9rQE=hPX+KnBBq43$zLWR2WC!y`sLJRe}aDu|kiz2{o zzV$Y;IT|zHK?l8vSX~P@rHYt^NRPS`uX1oLqrA;3i+1PD-mVomOn6d>Eq7n4YS^fV#cBHIwUFT~X5h!5nmSj@5Eu z?Ji!AzG$?kW>;N%wUb*A_ExqR4Yn6uzRWc42=p#5r?V^R>@X_rsEvuQq3b-s>TK?8 zFAL~&v+L~GW$OCSNq^AU?F8$U?!wmX8oZa#l-(8H(KTYE`4NHFaanGOFPnU`W0M8* z?0jF_)sr-?La-$8qIuuho1oHHvT_YhyBSW4p?djTvSn$tE5B2yUH@tN&dZpkW|b$o z<>-bf@tRNEZx33zN)b}m5U^Ql>`EUX_q~enkd#Sf^-i|*xMS8NL5@x*zOWt-)TH27 z2i*aCLy?8V13)V|0!akGj@9NmPxA?Q^m5Ii_S#r+JGuwN7L79U(A#b5*w+!Pchk7k zX%$H47v+03q-Ho;SH$ExgI_GlOw z7LZT*q1mZQnD$-|kC*TxwHlcmI-_*#`8_`H`{{wraSdi(W>6*=Vz{%rMX?S0}K^H7AIglB>a$1P#E>MToTw ziwB%3$AHaD99wy^T5}PW4w_A2JV3>}wm(OQ-K(SfBgN2r78@*9W+gFQ8P*>P>I|jY z)Q#JU5pgZ1bcmGP{IRZJ_O}bM?8DjPI}PI>#}XE=#!?VipSHGLDST^)3mRr=|4?FbJoI(&Q57W$N1j*XeoM0}Y7Q_6l8ek@d zScjKn#T7s2R^jT?yxH}<1;c`s?1IhX1-qbye=1wlEQlq|X#_z8$ML68kf3_?91P(y zfa>}6dlbWBuR|i5D**_{O|BT zX0L>YWn{7%6@vE_(1(BFNCEvf6wyb@e?bL(^bh>GL>(!jjuieM1QK=hf8bxo*QIjTrOIDW?YdO!y3}}mdGF2T z{q9S>-b|=+FBd4^(r>O_eQup0betD*T_etOO&;0g0Yb_-EQ$+TM=}Q1?WQHDQ-6HHTJM1tg;xISzFfZmX zKmM>F>8LQ}s3`5IDE+87^XO&vQCZ$mWx-K((NW#Yqxy=YhU(+Sy5pwCob@lpn&H8oSx9f&)*UcN(ufAP( ze7kDATQ)z$gc<;B(I<@M#&AKYdwh5zXBTA)L~gcScSYw2d) zn}8?%Pd#4j5#7JDmQhJBwX*)w<4rCZPm}$VwM^NV%vS!R$Lnd;e5=Px981traa&i6 zy7@5L0()O;bgRdE&z-xc&Tg`Z?N41X{K?wr-+H|NSyu!RLjPG;{5M(4zv_xHP_4h~ ziW@|wElvVew{^wb_G7T5xBEMq>8#e2(pHi-=@jxCp*kTs&Yu-y;{t)JY%dvjcG!~Q^ zmHa@Yco?nq;-`Z3`xgw$UiYOvb3w&{`x$9kG9=_PA0jMbIaK{pa+@aPr-zRV1NO$f z?#u9w&1=b))x($k2^NkM;=ESjR7^6XEi7j7^{QF)+EN*+e!E6rCqxF+eG8AhJJQl7E=#-;V#QjdSTwY>8W@3pow4IQ(#t?+7D z`uqeK2}y_jo?2T;f)=G~c($W~BqF?;SUWF{DLjTGP4iZn%N7f$-b)^o-@D)G8Fpv= zMX#@+L+a~}C6WK-t*mQ~HV9IXb0(sH{Zjzr0oASLf z>6=YbzrSjl##cLgm~ND)f+OBzsZr(V5LJ-KZ{3>(PB z0{c(;lKULjeE7ll{dCVPz0iJy;%DTyhV~o|8k1rpEGIFUmAjLQ*LNOPq;0l-8L=fl zZOgKqqipRzcQTfCqMX|(!t)Lr2?R+3c-lmu(sMwWHO~7`<3!@XPYGUt-i5i1m!gB8 z!a{Bgf+%R;W7i0p0fOkorWJ6uAwrB28`#jTD%ByJE2U=z?ZAXoeRk`^ zOLOJ^HEe9U-jttF!KpT$Y|OIVJ6t zjQv&lb$u~Tu!MH7$l*xM$B;)IA4VI74P_Y=2uxc_!B z>=U6fP9tei?y6|5Yydj|{uiV8_79sY{qUAotf+XOnuaX}eU$R$=J)9p+t}~nk#S_v;qmb? zZ_2@sA3x5{&g27kc6WDWeO66s4rIJO%Xoc~^V`_l+uPjS+}hgeUD&)OBqM@;Ncevd z3ENH^{FOhv`}_2I{{2}B=IHhvZRn%b%irw%H|#yv;z4VOpzpH2UlpGJy12M-Yuyve zIlSdC6B1H4HMQMxnB!-!ew^OS51q8_-n{8LwY}Y2U``_6U43|WeE#b)7;|J)eR=-% z{P*Ey@a?UF%lWP&WZM-Ief#`xpWB&|i}PPsjrAu+x8sb{tjVjF%ZHP1S7qOB|M;=n z5V(WPID4~seRz2FrulelYcr{NTf6GO2mMVfbe%i%kSFzkv+$Td_ZQp94S(`4!IEqiG0hZ53&IVpCtCqv zfgsXiU1V6QBn;9@DKa!V-;mfWx&%rUvl|GgEKU;j6iZoeJULz(n4o)z^bR7)PDuj8 zp&yJ#icRM3xikM#)-Ow`LTD8NP~wRn_it1)3RQ^*AjsW*XoAF;*aZu1@RQl^+blEO z+lvCh$&1u7bp@DHxfJmX+uhTDbmJK|+LLwr^->bhL!Z&}-bF^><~;OxHU$hu%+Q9o zugoa7JmqIVCjVT<^x{*PV~gxzdOm zfoKsG%UHBTG#f}FISdedr$h`0ra^5dXMje4%pek_l`@dy1vVfLG!85(ASRQ7Fhnpr zvMCBcR<@8<&tMQ>hLu!BDqX)e9>9CJo>S3>s2&IfC$FtM0*kC zwNM%m3=4;O7$8iPRHYa?20$?NiP;P@MY1O8ApTl9VE~Ii0b(kE6DR?Q&_^Fx1|KMpaold2wnHK`JhODn>5qI~??P z*x1OJ1xXoXNoej7QJ9dDI+5Y~P~ZhoV!xmPg~4#5*l`nth!bURbzo>SwV{P39Hq_@ z6{v^hvCm$nN0j6ymlR}`6c&^em6jA&l)kJiFRiR7ud1miZ>%b9ug>eMNgA(@T4)Mc zX$#)ziQIpebUc%J{-O9{rSkG??d4|U)ppC(_gB|H+OB_fUhloRKJ2+Z8Mr!`xHwom z-TU-wdwpkpd;QDLkIM&(b4OFNCj)b5eV;FSx2^|%UJoDLjGW$#p5IJd+{|9wEMDAv zyt?^%eY0`(hr)DA82WWfA-cLgxw^i%yuP};zPY&i8@J=Di<|3P-qGKrqra#}x0nBw z==6V!*Ys~6{{3%f|C;>2xb=_w|Jwt%8-oAyt8SGLa+qCqO)6o+`REY~l6y{A1YiSS;?Ac&Z=!u-INx(i?8y_c9mdw4*Jl?{2|4+`Z|z-JEMGx> zA;fC97vi4^{;?{oRx?yb?(?aTx$-lg3eiMqO=daaT?6dZ(U(pFGxYG9ou$`Sl`i+p zBe0`_%c_!$%)?ZeWOAri*Lp$dUkf(nJ*s15ceE6qLin`Iy_H6`Wweh?Ll%v0?sVNz zPWzD>jXfY1$$945k1fa~Uptiudq-0!-_N?auh1M(t%FN3$BR@oBO@vSQ-;#3;c$(t z3Q_`m>NjFSK?h#iEM=d16dfIE?6g^o=M1J;O)xXLC==Ioa7>ZuTKEfh*;WfCCmA>E z_+wKEN{Yad;ckW}&a39Ki4Y^)$88llgA`l~eZy#L*pM!JnCl}9OB_?$XXXGI1iiuu znUXp3WHsWhDz#+r04JDDHyo?plpN0~0{lLbHkVV#!qhvZjOK12TM}-vw*?@Ee?9Yw zcGxk`ZE>q;;P|mZv}U1Qf`?3+8fCAf)k0ZeI5SI}*P`Lzo%*@2991{6>>c*SLc#t9 zlr55txS&QGAvM|cmPSJ3YRz7iCvk@Dx@>5Qp}c_F12O`c<5)@U%n_O*9)-8J#0^_# zvyx%^-&)JL6g63yl~tTvhRO|2;7yv_jAp=(?C(z>k-oU`<1q7iK(ANK_SD{pvto0B(GPowW8KXSPN5F{Nj4m(lV7ZCB%%9ojI(8trUUa_Uf-U6j3H~_o}kgYLY@Uf z#sg%IyXu8xGng{PK(*E@eSI3oOl)m;Cp+ncs3ON!?3(wjdA1l8#P#-Z{-+~Q>@(nSDYvYpu4?PWi;khKu zP51N4gX_DYGYq2*nj;F1K(&{c1h+99(5uL9SXQY{1(<=#?~?C|u9Mg4O!HBa(eCPL zkQu?k_#u|KzY~e2b?gTS#=BXi`sk#e!tlFnRguSPl=Y?c z(S(IPVJe4V#MWOU=_`4?W8g8)*y#RyS3P%QT~R#LqM%G0E7D+X92s9Gt|hg5F7G-` zZiKcP=`H4^~Qq)D)E2_2NQ@A;7UH()*b(avDlNMG&V0fq{^@0&OBQBeb8- zmqrn5uSvDbUO^(4r;p>*HbRJc1oJy)l4aao`8N*|VXcNq7(U2QqgUf6cOF^A?!!}{ zz|%CVETGSS@=`;jRPaM(B%V)jE_Uu_W{}Z_maBDGp2A_4L1L*UwP+fVH7>mS^ z`u&Q?rkpL!GPUN43GWUMrtg7eGMh$`kj2BivzxIpxzmx!=O?pZHML+wq6PK~+M@!n zRymStbShlxs1OoYuEe3C^PF4(Uu_Xc-Hi!hfGOZBm6xljYRn{M9hJbfDv)s)Y=(7< zV)}6f5>HHMaOF{{#CXMhpV8Sc@KNE|jYWi?SR@?Ku^~ zder?=XdX?TH9BAGe_X{biX<*@L^D{VfEm95b?^xmT04$wT*o=chaG`z;MF{&HkN@b z?fW+u$91w=SVm4L?Di8>xjLZQit62BL>d#pSs<65pX*#eBSk~pc(t8)%w!j0Aul+L z%aS<8Xd>&RSv|~{_sR%Y0JGYpMt$Q%>}>I&OukQQiv2vt4|q0I5U9k@y)Ubw_N?A;?3y$@|B0{J}!$GRG3 z9sr5~`oYGwqXq%SFv?q@LbxMYG{AWUIH6VUdT8=7Or?Ob4m{wVO@{?3!D_>m<>Md+ z1milt>cC#u1i2=naFdz4Z^rl{KN)`xEqVp54g3DI$#}ks(yQu}zFtmQhY(vvZxF`} z4wf?|fC#^D9}BCO=LN(PSuf^`w3bDB#YB_6YUy7LLO6Fr2ysNt`a#=Bc&iMk$ls_` z7(Bq^X!$Lx<|J>(tMMl3r3{9vu3f*aK+vu8UX2l4V(4lN#f{uY{Ss?ypJ!8h-o$OQ zGf^}(SECBIQry6G62}&e8Tb*ZY5!eJvR3=e6Py)bG{6Ey(TAhpgohRG?^y@|Vi34* zcplPA0DyFWV?g=tCiPdJ{Oq4cWpC+#_dym|HQ-~oT_K7%5{rsvuu1k(20+w>)hmA^ zT*Up_bTzPd@T6vlha3aco3jEeF}Nf#{IGH4KA&+7TjoG$M;m>7IJpZIjc%gHVU7$2 zO2c+=<^1(%zDnF?D4%tH`4R1v-rI#IhHCoN1$+cEUiyxE(33j00^6MZ=rV`{PceB6 zepE2L+Pc|xlkU8Yj7W!(x;U2p{{EFc#{cun1u>eusdbbU>JF|zFD|kt+Gy@;=kE#c z#^Ru#Uc!rS`iMOh=3+N5Kl}Cd$F&YH1YwZ3MuM}l?nT6q14u0WCk}qFtNP7C>Ydz= z{2ZbRVhXql*k^A{zqr6D1%L&3GT3_yn@h@pC%`+BOQVCESi8XW=q9V>a$Y8UexEhoanHJ}ptY0G(|48{5CPXBLUcX<^Qb&m<0sVEmu%ewf(fU=KC;+BV%<0v zg=gK;i$eu=?almhe$RV9?JtB~WsW?5mR#KVeWT?`otIX$5yaw%c6J*Nd>iBWP ziN{3>uo%PFP+-wHZ*mMFT*SrdEPPtH_n39dBp-uneP!OH;;MpY!!PmTWPpIaKiGuB zv)AVVWQwar_1VC@v7P~LC;-=500%98>&l{6bC)nd8P{S8-$pyk>?}-5AJ-6UWC9_u zsK?O-hdZ`~vnb;x*gnviGR~h0b2g0dR?{)r!>{#<2waRHdWl_ng#BD1GSo0K{Ol3d z-yDBRfaafIDCw5tUj&GNkWrD6Qr-drp`xImrl!6nQ~xoFWMO20GcgD-F^DrmrI?`d zFsM8uRGJaW3B7fSWMICnt^Eate;)ssU}a$7f1DzeHdvnr^v-cw=IQ)V|)f;%BO zeH6IDDyFk3BSe%DsjE8iDhx`j~RX-ms4_{puU;QVZ#*bai4W8L( zK66xj>MG;xA?oDA;~2zd5zJy3$^0;y=|L<^GY)ny0j7}x(@2Ni%VN^ZXHqL?)~jYQ ztYb54;jnJ!a%ksvY~yiy#rv#Tz`0TQX}yF?jhttNlHW`9z{2~%xevoKA4R4aN2i!4 zq*y1WIHx9hW@7wv;)C)Nf(jC!7o`W5<5n6kMM*~TuCduX7%!&Mm?v-y=NwU=O+CZk8iChhp%i#uAaQR zau~aEo4WL$IS-jXi+g{Tw0M@fc$&U+ma%l4xpbJdw4b&3Bj^2A&cfH+`7e3%pYmpx z@~7qs#@^+R4(1Q{<`2EiA9`Id)KxgtQ84(bV4%5hsHJ42_2o!w`Djb^SVP@JUE^eJ z>vUb$Ozq%8_1I$7#8TzVa>d+-^7#*C??03+ekfb|3(FtMmOqp(FPD5+D*UjNx4f9U zIGeOI8NE0bvN-zu{jmT00ngiDi1bgj?BBXq-p#b1i~MIW#M&1}ul2WkC6A5}`XBC< zk4DG-;a=&3^_P1khBM)hdnIR2=KWiafAk%$KV5jt^MAVVA`IR}Gwh1;+;-s=3rY6; z-G%pGt7UQx-v7~scUvucWjCvlCnF;C?OleG@x)lW$H;h|V$2(`|7{l@@x5ZRasPsy zg?g>G@migS-OjIu3kZ;e#L>1l79%9sD_C9Rq$mJ) z?nAYKytF+`42KG+RZJTAD&2sZfJONKhlWO>WDl z5$!zxQ9KKjCXqdBVGT_Oq$p~FY9%NEIhs{Mpp#YZ=UypZTH5TEg(>rgZh!JAS+1}{ z-8^ok&8YwvcIZ?$mZ~S$yxQnkuRRv!tge%NGx{wH2O_;&h1j4$HNNd_ewjSMPFPdb z>Ft1OdT*6|=hY|5<%c+0B(!|a&3X48ckH}*|FaXTf$&%8VJo-GYr(aEpRX?{Km2MD zM$g1k{l1{x>&Dp}b?JR6r1`yJH0p^H;>6*Th_pC^RIN{SGX! zaY7!F5y*CDr}{7qi|?&z)1Y`n&f$pkhmXPukl(RJQ^;L|=13*RT!R^n%Z29Wn)18` zbGn3&j=l8EYxEb4tp~i`>je>eyIae1crR(?#(8@<&3+JbbA0<)@1y%8gVRQz%j{P- zuL5E|h(GiE{rK)Zh7xiOqN;iHB=udlwaFpu`NaDm94|yH+iK!s4^uq7o-bS=rDQ}N zW76MqtLKj-?ZNw4Fd_GnB?V8)f}%v?D}^L90Q&w)QCQ&x><~wRVGHZNDhh0l;T{+H z5-a-bOes>x%H~K1uN+~O{FB`U~RO>6@9jA_hho6nBOtK5{Doc6Ing836A_3uwavBnHKqyOZgpv;%IibZ}UG z;YtV$Gev=~!WD^|lJ@Wl;Dv-0yi`JY)G{GjgI)~}%rv0F3X8-DFq1b$Vn|9tp!S;9 zIHHg!uc>0_?}CrO#qxNOh5JDc&0m3hZTS4_g^W*!@xCr@sYvMF_wtkZGPF}qDqIi( zJ>5gTBf)@N3j`U>&T?^CbyP((Ty1z*BKc}p0fsgpYdk=~VGc*P%vO=#RDCEm_6%AV z4oaJ^8sN%4MKZdhsFn=7ffwC`hNHT$mSGjx-g}}k20*}wJya}@x=U*%fw-;sUjR&eMv7O9O(+TslehnNI|r@Xh936TNA zkP3q&<;+o6A~>uNz@*>8VII*cQ~_F;Ac#QVeS>`gZmq;?(uM}FUaB(OFySW>8~`X< z;3}g2D9Cax^c)7l7Fm5mU&0cft+WVaEld!CcjK&J3K-`SdqGo0nXQXVM3;{wEdv#C zvmb_Ikpc+q>sMhSre;7lUm`8=I%SGIS|PI#*G33Ln|jvGQ=%ZL;L1#bx2P!CT8LUv zFDCA>7-VxUd`lv6w=x1#N&HF*Vc)EP<+p;vIXM#hba;hy2rwl575{;nW)h^p-Uz0| zG?sun2LrKLQ;>0BNUngGv=-hYZml(0FYwCi;D)P@bA>|1FTIbu$qA~d1ZITw->v=lL{L+k z*h8Wg8ecE*I|mX4^=ZSKM$z;2#H+noY`t4zE7gs%4$-@4>+#}Dz)Ld4+cOv@7gh2~ z2#ggeN7DSX6$&!nYFFH{qS;S%0kjy;fdELFm4e2c*P0NLmEQW{W`3b&Kf9ZQWtbe# zk9tz(Om(1tQ>pVh?E3C5Y z9SOB8^{F;R3#5DcX-5ELElBX8Rtzn2Wz>2#j&x!yD<2plQ$NHy_x{Y92XRWgcxUQ- zEl9dL@|<08@7-tHPFxDoyUNWsKj_zFGJ47Mes0S5XsI}#W~Np6VyB*JM^6Mv_Y?YI z%h^alh+UbJh}0s9-$aapoQsN#b42!M_Hpt-*TtKW*72l|JEhA(Wl6rOKO`V?xa$S< zduQvS7t_{Z555vNS`6xuqGBABTws#TgLD*0GN&XDBXWQIM74Ag-E&1i&US_R9V!-a z*Lx_(Az}?7BVXDk8Jb6@lv+q3F?Pi4I zLc2^#aP&j$B0LgHf1Q5IG;z{X1q24)r=TI2t~`|P1wTXysk;MeN3%^YK6}Z*5ZJ?b za|RZQ5aw!pd1&{A9(v;^m-q01{-`^GN@RNZ4#Cn`RVb7wW=RG}?vaXhWhZ>wA{gu} zxzG4cf_Hw2$U(c8I+#itt3h-8khrwK*KW|4|LA$O2!!6%as1AGdKAGl1zNk*4-X>I z$0UCw3~8<>wtdAXDh#%!l5XpMZ0I4J#G)!tgbpsI;a?OGjN}tm3lVMO6psv%jHKmj z3*nj$kvpSNfYT{T&>{>&P0*ovZlM}mWSWbi)cc{@_GG#eVI($TiXmYGg<&dvVM#h+ zW?K*o>TnK)aC^aUy9|hZMmSzWxU(VT*;#lkQ-nELgr|Lkd!$ej=2?X*{)Q{b<{nP6 z9v%uDX%7hw_sn3Rry%(yhW8r+qTK^;z>p{GQ7IXbOH350P56aMGC7e^k~)ldJ-{3| ziUC5hJ1G65JGkI1Bufn<-W`bp#KLI1kf{n)FGlAxMPoMr^IS<7l_F7FIDTa@{5^1? zRdC&1m`8Uc0V;NiI&MZHZq6`n!8dL(BW}4Z?&D(IXNkDK12QlG55PkS5C*7Xy}Xr0 z`Dgd6;J=LjwA2a@i-`1#OEyVM=S#{a$;!maNQa9^2g9XMtkOYjQobDGu5d9&PDuxT zSw~?Fdm$q`0Y`goFBk40ckXa^?le!X5^v55KaNU&_Hr+_;-?%1cI~jX&d3aBWaWXe2{5vXGO|iCGRs1l5m1;ilvNGN zddo1;g|Zt!xr`V&Oc~kD8QClu*=!lvoftXY7}b`p9=#w=gXdg^FL;c@xJ)D2&Enx^sqALCtfmDlCdDi!rL2#uSS_1b ztUFk2->^9Lvbqeic@MHa?_~+;W(^;J#|*)fdbl#%IP;n~3v0Oxt9c45`SMBy(hEhB z^MsOecoH+=@oDU_$?UNS+zC-)na>r9J=H55?^QW!);eo8x@k6hXtsE1z4Fm&_t)xr zuK6ZZqbEkaFHLPAM{TfJW2jtnxJqld<`(ycYt)A86o=~&Lv?b4b+Q9>GJW;3-Ociy z9f&w%RloMzZcDKluduE8lSIzH&;0_ zTRuEfHaK0y6(ye?9-EmQotYk)nRz!eJ25*uJ^T0ZZv!&I=a#mWMFZN>%p^o#xsVD6I!;Qp1&#s-laz=q+satyGlq zSS<)T|Nn#ziwrqoy`;Dj;Ssg>C4fJDx4t<>JokVq%)1VBXNO4hKg zUMcc%{f~|qQGbre)BEZZ!Hs>JaCIT64%r;L$w9EUGcE-pln2<0h&GzxTj?t;8O~8gHK) z``^qq(^5{Tl4Au|oMfefQ{&E$S1aM!5c3nxQteRX z&&zW!lZe^W{d;JozZa2-(2^N(r~}O)_sP-Lr84mS2!ik&3wCU>r zW%kW@GQHbCT}06b>{?b0=huT$#yXt&+FP_YOO5)yG!IjD?0_0BCE*#Ll}xAK$?wqf zY_!a$!EfEYO`iUdMfr*8ko#1aAVsVmbZ0K>k1UFT$HXkvn>j_~R_ZP`*UqghN1 zS$v8u?AR#GF;E5LV^kfXUGk39tvvPZbf`xMR~RT55+ zBx5;egv$nVo^n1TVsR!Brc01iAlF!5MiBUvGY`1Mn#1~e%UuD2b7)S`NHOAO1()w< zA*B!m%xK_%k(pb=qBU9v!fqSfTzl>&O9K4!Bw9rX*6(F#57Xf#6-_q2s_M;E5+||Hc!*L}K4>3{ zTj*q50;`Cuo|OZF*NCgIP*1rf(@kS*S5g;Q?UiuIi3;bF zB-v57*m0IB!6itj%kIdqL~95%70AfgBZ-;siH=#3Q^{^3it2F@_9^06=wNCrBSLvG zo5Xf$M75oM6{wt$AhMekc`?F+E*!^C*9oJ<4-QjL;k_e0z)AE%EhKb!CKpSwkB8Zj z6{*<^do;EE@T(sHO-{kICFP*N?3S--T&?q4ql$vO=RKO|VU28#JfaS$P{N>u}hegSbpwUE4<9 z#Mv=>8WVmoupZE;9kf<%H~AcT@5{yV>6^3hy630wzT8}#z6Frfqwq9Wu;|XZ!T0Nf zsm4}tr6riXBM0RN_g4s>JRzPE7$W2uvwXdUhQhb%BY!c2{YotQ;d%F>9^|Z1`q&Qe z#k(0auMm2VAqFLIN7q)!*61(WIE=T#q)qp}GVfv!s@!+i!c?!b*M*MUk8f1O79^#- zcRos35h6F7c#kK5hA9ps5cXDcLn!-v%>I7UP1gI{rt8l0ao5|X>&-(R7- zhCQZ@Q-o7w7yjWY;G(-V$&!YBv#0e(Kx{In>?15_78G2jK!qcPV3~DaI-zvfKNm;Wxszowqj_T8j|18!9vTJz{213$#(7U zyeI(SVjHzI$&Nooy8`Lf@>E;z2FGxHDI5hE<&+)AI-!*eCx31215LGlfnfeC{-v%h zq!wG`#RZ>!Q4Z5r7H;|l!dQ0fUgg~gKL@}=O(qM)Udiyuxl{X+tf|cgi>@&_qSu+B z2A>~GbX?aD41C2d89cAf&V3fN0-_hH50UF8bFrbaS?g&GmyxOmi91^_fdNmK5-dSAY1{V{g zu7vK7a%si#0zTQgo=PiT1H#*ec1a+(_9-DSsm=C2f58Okqns_@vNpNi#6+&MUIuZ> z$gcdG6ZB#cl*3nz!adQ2RNHN9YNA(^FX35`4c+v&wxDjp+TB;Gt3Nk~BVjkd_}FS% zg4e!y1-9}2lZh-WQ!i8r2X6pzJ&MqN50^K6xi@D*26!1wg7ZKG8dQj;_x0fFMo$ceO4viZTXB z$%8Ay@sYN*Fd*;-PcZoWQ81o`|94kHpW!fB4o?pV@eaUc;T6ayLZs+@pm9CnG2kh( zEfTv2_iZT<&%(>F%y9~V<-_5CRcK4A0(oyh;`9Wfhar3lhqStqGO7kg*@s~j;>D!n z6l_W7%?1W;O0m5nJl!LHyb#eV0qN3qz$F8pp-2zKA)Un}6&z8O%&r8B#PQ*%HFi>W z0I@m??qWA7fI8q3&y9Tn4SDbU%!2r5xeH<96Mq#_3JHjIebjGlS9T6d>@o+~uyp$n z;m@`w8sJcDG7K&!X<8cQ^`UA9?3urvV>Gq#t*^&ngtr}@_mx1x3U&NR8ACA4QwSL* z%Y-|-aucK?M10$dU0xKjXi2y{#Lm}#ry4{mstRczCVl@Txgt3E!)&s|zU%irujEqF zo3>yT$=i z4x)g&WcI>h`2zPR*9n%DWX%Bt{tk%lkUKBYJlfX$_E7{++688SqK2vIay{T&i~&|+ zT1@60HyD9<3wcueL*+siHav1y2Z)Lu#0#Iyhla<^8iIwBo@;bRuK;{WVSbm4APArG zrTU#)x8NQxL`c+~GhN9@2Z2#RNdZ9-h<1)tVwRy>7I$J6n>CANH$k~T7EX`k#5Tm| zhK4BvCWeO+3fIln>(AjXeDMC9MHhl!;hJemrcXx3Bp!lz>vu<40q7=}gRjHTV6C69 zc4yt;?vg`#92!ctD9)vAFn6APV(AmIyRziOf zN!{wsi?Fron0`DJ?L;(hXejX(nUS0zGSkRDB&bq2>y29zuyfm256cVfP<}GCVK)O zbc2nHbjOtNw*3K;A?hF31rak!dG$DkJNOO$fD;1EbAo$|Mg-fmbz;FB%{q(~1zIv# znip#?E4B5p_QA&e;DU1w2W8E{P|cJ?Ej)B#@ZGG>##$8_x(3EK1SJUA39vHR0%*!w zC%(s4vImGk5TxxH!m>q~owz4#Txc4Z7>cOPi#Wu!aUv0H*kt&JSyh)K8J!v}@MuC& z7-TqAZD2HCP!ZekB@2AIIzKoAVx03SnEyq8BjY~4WIavv3~p6-UPf=>i534dZ78o3 zA2h4N@`wTZE*^B|5hx5&aV{PS5NjZ4vlec?R2Zmmc!f0ut?EBMTaL(?rQpF+dbIh*hf$2<6_daJ;Nuj_YUZ~XgKvZ)J%-tbw| zwzg!=mb?Lk<%4t#o}_9=d@y7M4kS2bv3w`{y=w^6RI&%PplQk(6rk9tSvoidF))K5 z$)3tteVMK|;`&0^2W`+;vilVJIf{AkoWkt(-kXPnckbO0?JsoLDlC1cueRvDnxM6o$r zmobNW*!dl{+XI~Gp$_T6Lap;!j#Mt zHdy@<%(MmtVCXLGVWVNM0`{7tAjY+>_`A?KePc4`P{lil`#V6Jh9Plx9qzu#Yon>U zN=imDEpn~tgCpa)=7EYW?jr?5rVEB#)D37ziC~|#e20maJuVG5h^4$m8NbJ*G7Q}8 z--zvIB2g^-9cw&PAK2hdP3Afzy`of>YK*&TOd%_x-_d%hSM|9=9>XG;=)sE;fY7mt zZJd#AmB$-BHS_lpin06zdyw|L`)4(CfUkAiz5`}%XzP4dI5K15kgbo5B^dex8-UEax(tGc{ z7X_t+-XRFmL3*!BRYY1K6p^m<-V_l*K>Z0m+}C}tr@m{wf53Imnh$$s)_mCKtTlUP zpXWY~;g5;RT&R}=34^A#GB%K6oC#gYpa^U6`;>^Asq}I-nc6q0W;Q7zlwcH8 z)Cya)KQ^S495WNQm~6Hv+8jYATXdCMl2lGAYTGyR9TNUq0u)LJ1!wVJ+cdO0(5-E; zb(F*u%*e%A8m`3SLt`=GtZ1_%+YGbsbXD!!)n4D#x!Ki&?-?lU8QJWaMC|Q5vJURt zIpKQlHAeTU^cF4wi)n?_n!%h=knvK8OZpzg&|seyQTQf^Vb8oBmiBIFn-ocMGo%L% zu>pDO6miRdN&BHsZ1!CvV2NX2tZ0YtPM_=CJY;WOt}Jpu1XO1z&v`o>&;^5zr(on?&S`$oE2P43rDwmdXda zhkq&>dZHgu9%Ci6m1;$QO8m-BWd1^r)J{c;i{$IRKa&#CV+3TZb-$q*7S{Kfm+H$? zBy38L8jamwMS({A08?0kW_GY=GbDbU-V_DGweBxq2s#J8K0)3bo|tnK^Vy#z9iA#g1HEQXJAL)wdE@kBz16+vEo1jZ;39+S*hcGmY~ z%(ST}h9&lOI;?~V$+W z=>gM(4@Nhkq*xLMUDnMY2#X)Uz4-@e|BrisO9$JZH6I{#Etkv)m>UYRf~5{nyjpIi zW_<$@S#txIUf!O+RVykNPxSa5>x$>FVM04${|u zr(2iKJpw9QdPcbQy;t$Kdo$Fv{5SJGm?Hv=$9`|tC2A}Ae8_g?A}nrUBh4ujky_G931ZeA~Q6Bl1#+0JBxU-f4TD>h{1XfDOG+Dp&%WH&GDQe zG{tb;tc@IBFeEYRwlJpl)Z-}R;LB&)4NBZYJ)kemy`C<1gLivxGFJws_2g;TploVI zX5Sq~(pVKoYR@Wnvn{@?%Wt|;Qz>-$%-{6p!#>K<2C3-mp^UbU9A75}%epPvu{jyH z^mQ=5{9+o@WnQ4#uxNM3VO={uHATAX^ULuf#gFl(UzFZ{hAEF-NFs-n&kRr`Y&L&F z&i39XyeKNE{Jk@`a+fG}poSC9GddYvxwCsG{M#ZA7`0OUzw> zh#J#MYe2@`7K&wMMmGnTBfV2z=oY430uc?hFX0CXcdXt`#x+@4>6U#qiyowp80U9m z7q~M++8VQniEllR=X$BZnSnN_xZtyVS;>?1_z40iEk?MWY?OdxldE2_xf3QH4SxD#f^>WVt#Onx@DGCn3#sQ zi0tt!;IWazWgVurk;Iqt=CUu3MAPGq>6X&`!u8D)R!h}NW}~Y*Ej(M~C(XSw<`>Jk z7mgp5X>H^`vJCv7Drp`3(Yed|@kX4aP3S>Y*X;^;oTP2|)n1ovVbyC_ngZo3#t zH7WZz2A6L81h#l7ha}$WZike6Bi$PEKkY~3VoUqE3y_bK50h;MHD}X9`c&M&o_bSx z&`=#cypx~ua}5YmbE@0*vE+>lFFN*YnwO=BZP3RB7Z94joBRngq8|H$oSnV8c#$u~ zrcvdPB3!WQps-@%O-#w4#H__~hW7v|OLF}waY;aU_0x6hZT%b{LH={=Z zasYDm`nGvltori(&|6QX==dKfS2b3K-_Pt1{W>|@YqX5Y!tABl(cG}JranYhaD1Ru1~4IAJYNdK^_ zxV@vuZTV~N8V4lGRA&y~cIU)X_vNZn41ep9HhlP(|AM}c^8PvkS?zCq6=H%Uf`6m* zdr_@rEcG?6?&%9~e$`F=e#h0dW7Kb{b%KDhZoxx`r^k5a-+F-R$Wl&q+cR3wqs{JM z3_r^fJD#9(8XWN_1}-U!su9D9$|fGO?cPtc>9-$<9Cq~a3rv`X1<21RRfc|0ap+(n z?Ku=jMnj^a??vZfEhj68WHI!zE-?9!RwcF{r)uBIA5*rqJtUe}0b$4ev2U(Fc)FtT zLbuZrR^5)FuN{k&>O*jX!WnKzZ9H{2snVvV2s&CX;c69-7D&YNBl5@OUL>{bE1 zU#cvue9+zbbsPSl$hCSaJ0e$F&{QWMU)-7U@$8&v%UPJWxuep{-7of8Aycg$1gJ9Th2;a^iC z+M0-U8o2itqaM{s*6j-CD%dD|q1^6{-Edc8_=$16AA0|N|DiL+I;M2zG9l$j5hCyj z!gZ@MWYieW1^(!^PtYqtXhCv2o0e6pa2ATar@g~Mm847;>8|~(#G{14*hS@!H2x}$ zKk%lP=ew{BE|{k>BI;+gl3(VV*jD>H_5q`RJ?`{;wXR22{2rC-WuFHYWk=a3C+rVn z(&*E@Ufh3Q0v)0yR5}qO&L2_*hAvLCC=VsI|2a^OV8E}-b3OS1P}1BhsL!IH<6uqW zlPAl+!R9JEvWUoA(tb^x{p>z)=MZCQvr&gdqBx1eY;@p%c%8lqxh!dy_t&wRVc`rM60K_8vDW10z>e!gdrcA59ZyRSbNPkwFk1rsz) zwDWPklc~(*gz}uTJhl8y&ELiEjkogv6YEBBnruT(Y;hqORL2{HltSz!FdkQcEATdhz~0)zonaV}!rn(M&*Gc8 zbpFt@!~Rd7ODO|?bi)4fsr#Bwz}5v~6VJr`!=E4LwR(^@ybcC^xs!ywdy3RvJZiwS zHS)8_WHT5)^c3D^Qa`pfGJHY)TzbF@E5PvF^Wn{?JVgi$X{8cXX{`a>@k+ODH49|? zJTKS1_33-W^AN+PdLShsG2Hw)#)3QF^Sn_%E+}Z6ihci?IBO$=p%~{z94K;at1ULD zJ+QpY{R7cK&)}XzkH&gXW0dp#CqhA9x4!x;y|Q|s_W1R}Tc1ZaT`Ozf z;ve_!$@@O}xUzmV^0@Eft#8ED%En)kkbdHl=I$^jfpiZtOkdThm^GUIZorH~UR8^q zP{J0&2Q%EBwO@eJiPSZr+Np4JH(iTts@SOI0@~V}*R?7mOQlQ5#-1y7#(0t1x?2mkT`up4AKJS*>|u2}hVQ^)*DFJ9u2 z-*ay~;n^&oM#+!ZQU(|=^M!sHGUx2#GFF_$G z`#u&&{^=Ec@N2GX@}lfpFb`Ga)`Droc}+(6=a^fr;gc)DqB4XWWarX^X+#w12ar3A z=85U^r`jv}X3KK_lK5Pveas>X3qYVF|<;s`uV=MF$3R#iu>IP>q81G!voXI z?^sxrV7&tjf0US6WL;H&x3?23B?Do!#G0T#E10EzlsSrOGxH|S150pz-j@UDIRIof z^bc0xG2PwCo_Pejuyn9oPnRgkj@_WZ?pqo`r8dtuegDW@BIRUzRb+~!cfiWPVJSJZ z0{l-8`I77_M`;f2fqc$kWun1>p`Oe+TYoY`Hpkb(_14H~)OD=8)E-ce`T-cC^s7c|=D zPtQBU5g8|qup*5hS>;X@5Oh^7^9x!Ek|IH+9xay?07(iYqB8Ey(pyEDYJ)@(BtBT; zRI%QZ!Xf`joK>TGa^?P$&@ZnfLDZ8^!ctRQVhUb2lMn9r@9@Oot_9Rv3ZtBne9`A!rNAAvO575IpZm z!dp3t1>Fsn8uI5Fh^y>5ph4Fi%j7@Bhgnh3vGm3=4<=^!L~3ilog1woVz^^8Oqi_@ z57wwi)qZ>)ZLZflpHlQbOD<+}Bx@z+Mlq?kgArZwMfpHuv=OBam4Y4k#ZSp9DDuV2 zQ*p@i#a~qn@4$#6PSe8$6>ZTF!$V(U$bea zJT75%r0UKP$zX`Hrj{YGv1<&W zEm+c|Y|_zweADaonHQaL)8z2vlyOHM-<{43xA*^KPxcQlSnlbY6O1rhY1tKi{XSzVW4Mpx^eZJKwHL?3*``;RMitXV(CdX4x5k4IUVc&p~w*pY&Y zU;oTjI+YtQ_0s-cs7ZS>InZl`4i?w@A*=oPVcwS>j^H%3!ynU%Vbzo`nvNF_+=(a0 z9c+V2G9iy+0LJs#Q&@I}@AKhAE}SFtOc?k-gX_ng1deV@8q>YZ0swOHo$ zafK>t2 zqV-qu=@voPD{s>n_&&9<5u1fGTMooAkXR%@t!9ReSMkqR$EsGxJ60!ftCI_>@Ap=x zE>=GfTTjy&8$j1?W~&5E#nvb$!BkeXnVCKX@I_Z557OJ?yX=3AXyOu>N&#{p4c(8}Y^| z-NtwBjWh9$bJdL>Li|sRCoxqyu9f=q+I{^(jF%mY+z*Vi-)z{(Ew)-~{r)->!QFd< zTYM>RnP|Uq{jkeNf75=!_UL%2pknfpHDmC>IG~!b@LJD1$|^~A@nCYXKFf?y!OHyk z0F2(Crs>1wo*gyZytm3SyhF!V{J|ZHkKcz)->ez?zumI_I*^1mP36Z^vLS{ zFjg-O30k-{-I!8CHj9q!KL@P{tPkALUKAtSPT|*R+3NzQC%)t~h4*bo(kW*-FQbFZ z#81Xpa<)zy#}e1Hn^YZQZeQh{LdZT@28oZo;u-@fc2EWs|* zYI(BzI{@dUnqa4Rukp%jbGrShi1rUmi`&J{OG30G7-L7Z%QrI3wl%n&o>|A6wB5gH z_<~9^i?2$yLC%p2OGVC;0@a&Bi(@92+lfcp#x8rB)lRL2c8orzyf?e2MUHX9dkhM@ zS!r8O!zbH-E)F)ichvSCO-#~9IJ+6`r@S3iE}7)Nv3EqPv7GGC{@4kWa7u2sr8U_I zRiz}nnX!%lB2;7NsX+)dKg9tmuwz zXqu!*c#ft?q-Gp5fJP!3aR-lBb&7NHPoK2s6 zNzWaF`^v~KZ||Rc)$z59aysukxw@P+r}H)P_x&C3BiQF_pXqx&GX00-G|KTCfu!ya ziBlreQ)1UslEJAcStP|f4{3&%fMO|*m=)f(%1c& z)B_+dEIAprcs8b4as$lIzY9o8f=ADU4$g$H&hC+(BN@&`c+c-k2ELLH6z;S)e0wJL z!7w8DnEFv5yTlZ?V!CvOt#oIg!00(`3*@MkPT|}6BlmIngfk^w`ZDd4P`V&A=~VQ#OZWO@ z1)DYaD-3vZ&3V#oxndnSpE$F7dLZn*5ayn2dhTowJmBi?aI_~}$qO#y4Hxx+-wl9s z2g5l-;OrrAj@yP0oXZK$Wd-LkhI8K*)1u*Aif~S8IENS)d zjf0DgT>ybVvLi$}*`(Ov@(8#J8(aep*Mh@!;Bb95xG@{t6alwlXS3u)Sn;r%@^Kj7 z<6^V8WPW`nXE=$b;Mw-GWj5!U^4?*@s2*IzqZ~1q@%Flw8(}I=r!j+%@#pr6?M7iuWG7|Zv6%E}ZX~?9BaV*270G5vi z@&9XWW#w2F-+zE+sLPa7_{Nn4`KYv2v-x&|1wx=NSf79P`GrVySbtY>9dTh7Y7qA( zP5VFnNyb>=dm}~s9m~Dp8j<9yi@JhZk2~Wj1Pj0zu;*2*%?19y42N`hFBZC{`!yC5 z2cFCFuN)`p(G4bcYi)lIkHvq6+!_w^T3lo$npk=q^oex9U9>0@mo2ngARiCuOh1rW zK@d+^c;FBzQvYRi*g}y5xW>wQbFT^Ib(OyTgbcI%vBLYs5@$q^>)t>p0BcN7+1SEL z*l@F;Qczv)>$LVaoPn`|xvxTtCh)4y5qS|AYJh)r;kfxaLfMJu)}JJt{oYly8~adX zGtFe#eJ3%Cm|`M32IpzjL|llv8)TSDE0v8&rC{`am2q$N)D&i(NPvB)=)Q{_log<_ zy8UJpQJa_Z=DwVh_WkOQV*)t-*#DsA>6~sxpJ5D|Xc&RSM1B}jjG=xjDJ}6#i z58UG7p_PPkZy`=;3eV&Xb$OeaDt9a#1wt}}=?M5WRcC{#V`RHd5!eVTibYM;o0{s+ z5cv!UdXakhT2uf~mAtfrdZmoxC>*Bu{20x3X+A|C_{^k6*__o>`{lUHA!8{%d3aD( zeQ7qfDUICeD0~Trr6_;r)pl6zK=JVdS3boX#{$BpEc!>luk>i~1nQc+USi{YHjIc{ zduf8rpVlTk!Ep2 z3Py2_9rIzc&1pgjV_Q#e9I$vZO+*xc;OJn`tWlHrH7yHO(4r>dLQ374AB^laA>(}E z@9V86VViThp&O(0448G@OMrs>eHh*I1>81A`ReXj#fQu%w}!)EicH`XeLl(Oe39t8 zPJ@3T}OA*7G~zD04{{e9@eP`7ih7l>o752INiA#B<5Q97!1B-jA{G8^_%FlZ&Hu0A&}_1tz6*~Nexi?> z+15OV^HPb_RuXMFTG)((aF9|$7|$;pU%DRFsg{F`Ad8gj9X=D*T29GBRx$6UOo6QA zB3ZW6Gj6s|-H5Bf8ZQ9^Zc3@`Co>T&W;ni(!xUpsG$&jS$4j=YCY6Iu4`R^(xez3O zg$^6gPclFX&$6Qtr`9t=lVYE#9%OZwW`*%3A%G;cwNgXMCS_YzT6NS$)K0(#sW>(O zGTJ!g8D~Dr9x5+%{6WAWebrCI)0ZNwl@N9*3)!Skr#Mu2_xt;jTw~-u_T>J_mG=&B zn0JlhndqEt;tKiv_a)TJz-T}zV|gtxXKUy~1D*Tn>qPyMRs;?4o9WQp1pk5 zD9T1Z&qyLdqx%d2q)+O{59wsxInEdHXk+5^_BziGvq578f3BcjcH~cm@rV)TN9hjP zz!VlmKHQ`(Ma-@2PxP7)!&rSfMDY?~4|jQm zU^2r+KSrb`MBCAqYbZOK+D}uyh#n9P@e{}*NI}u=S{3Pyt_c?EEEE#}EPm%@e_}ua z;I{}He&&!)g4B1~L-0ZJS!{9;7j1t9M8<8v=U6X09Oc0J_b2g?QiIc3s%f3|@-9o}l2KC<0AJF?ZrWY0FBICNxm zV4hU3l30ZBKb>$!~f!#hDS=Fr%dFDU7 z{HlawGd|-U@)+|A=JGhpU49QLCT@H3AjRVMf^gLWGqq|(?hKa$VIb)S5l3HtKSNCkafYY>u~`mNbRnr z&>5jlh9kHo!ih}7;6zg`tMfSrMu^4^UD1m7aVSZLJ2rxV_4B`LO7E$5Gn zkcZjRYylh0_y9I~VBZp>efC$R`2=|{JN;vc3(xf5?s^{&cuT8@4hMT1)aVOtM}n!8 zt#>rKTwxI=`e1gcSVt+3_OO5ta$fdD!+^MO*c zG!fV<3G)6&_DNTo@K$mf7vNKI(3=>r1*4WFjy4K1bLq>csMM%1T2Rja$Mrw>7;! zbk0y7;3xmSLS8o5XeUdJLPR0QQ9;6)YAA?s4P|WS2NnM5R(nYJagzzH3KPaawVadJ zf$+{lrfomS7FhXYD1U3v*XeZuj5Mew}Ew36rvp~dd2ph`Mjd=y{5 zo@kwGBJU=Joj(|FM;Y3RQ9%kqc2Tl{&>t#R=R-j%{z<^hr(r)bIYe|Xj9^Lw@rWMS zIjs(F&og)?q>+e-XyAsTZ1fq?cS18dZL$0;27ik9%B<3Pa;c*%W$El&d6HUawnl#T ztvpG4DO=}P_N_e0;QzCfmnp|VI>*U8$0an!EkDPjC&z0k$LCj$A5(6CbZ(G&?xWD$ zko?>yJ-J~^xe>o|F-&>U(s{AwdGVoniTQb2=Fs@syoe(uqP7RX?(F+0NIQU>hyXZ< z0>8qLW3hsFkl^xA@?>m6x;s^)YUVRS=ZEeH<51hvjld^-nXeE-cgS4YGi82f8 z0U0$%R6^4frY|YVObyh?fCHtZf{4N}Qb=ik{5=3@PmmQXndbM03WVC3 zH4{}KpG%?SWvl}gQdk1TJC(pFf@Af{qZshSDaG}sRi>HDER3P%aW-EvkVOw%+8R!* z4|HgKQB77_Sj93q0AuLUpPErj3w<_-D2PZVf2vm!@ww(^ZoYIz=h6)o45{H`m#Q(yKP(u^T1;Dbq&LV7pJt2~J0hil6V z+Y333&q;vgT!#6+e9@RACvvBByb|E4g_`o?53lFX(R3zb~wN_;R|@gBS% z2QL?Asdcvaom^4xEd9G%Ma&UAhJ?R1rV_@skU0@cAy@~HaCcOBM=sVb>Hz@3GG8VR ztW&wi&N_~>np(&a>IWYSz&?-H^Lc9V5IHGd-pH~pxR}4>=6dPWvwK&a!Qh)8*wDl| zFxr`}OyQe@aI!x19g=+lL0QMairlU$F1=To05&K^`~r~qs<bY61wkZJR7WbaX z)NG3jW%)c)=C^ptxh3$DYo&Ra94(!oDEBzd_&^xN8-#WZB8oz3)<6JEih$D=Vt>M~ zb{2OQ?xvPmtkh*9&b3IMT3A>%rQYoXDs?J4h34f}6c%<74}_L*ZoTB^v%%K_1m3-PNQ6;+A z3L+8gwH|gvzmHG}N|FLz>+gU61^D-K&$Wuh@ppxb^Pt9*fi^8V?$BWu{w%H4VVyt2 zdMr2tIh>Id&Lj+HR)n+Y#c5VTTl)(Iwg?OKJc;g;r2|H+8hLC|NBG!BoLGPbuu=c8 z5gr0yJ|+@wKjKw10(?0l_?_^kKo9h&mduH9qyRI@8by*0C<@a?MD$YoS>cbB@ORlq z5+|vgH$mgecmsXl2m%ZxC%42C_Dz>I+G#Dfl4k+NTQLoU-wC=mOHmfonN~0{JF-MQ zvH}Fi899RTn~3ux@lOSX%ufW!jjAJnj*awENU}sgb5R)G#;LmOCP9ZD`L&4d{4qfZ zO5Fwm#-hrakq;Z3$Tg8b8~~h-n#k6Mb%l*OW65HtiBrNR9K)u%d-ZdyVEGU)q#u4J zjDa5oJ|hKWk!oz5;z+h|6}!Ozy}*7GpjpQl8^P#k<5*WCNF6&C0U&e@n@GfJv9;m} z+dhc*Ob}Atkffky2;}L;`^R;(G~Z#!X|M4V*WfBW^EJCbF8zs<)CmA~Onq}E5-?(00LkJxVB4JF8kK@POigGW?LE)kM5YOyCf=Hf zm?lg=eWCx5jt>bgYlUr{s)NH9D4;Xn#pn7(sBMK{_Dy4s(0Rg4VsGokL^)tC3gnCe z`N}hhBOsfN6%ETD`_=dzYZ^#~T4;J)f!Qg+^<=^&HZc0~$dXtcL-X3|}gD z3nl`|c&wPB7ummm5J*`wuUune2j*fx2S;lg4?n@#N8W_h@Bd$=yx|+7d(R_S$AZ&Bc_{d3GE zs&g!9>^`b6n{Aq@O}-LU-o96l#^nEyS4^xwVyca8uk761ehA&`K9C}PSx+IU#mP#h(lmKUgPdpMDdz-{$^WibqP zFlmH3gfMIX_XL5UVV_lJ#*52as|09b*CxA<#Z}Gt4 z#XU_M?LZytgFckH^M cduZ?EjCkxGstandards = self::findConfiguration($path); - - // Autoload class to set up a bunch of PHP_CodeSniffer-specific token type constants - spl_autoload_call(Tokens::class); - - $file = new DummyFile($content, new Ruleset($config), $config); - $file->process(); - $fixed = $file->fixer->fixFile(); - if (!$fixed && $file->getErrorCount() > 0) { - throw new Exception('Unable to format file'); - } - - $new = $file->fixer->getContents(); - if ($content === $new) { - return []; - } - return [new TextEdit(new Range(new Position(0, 0), self::calculateEndPosition($content)), $new)]; - } - - /** - * Calculate position of last character. - * - * @param string $content document as string - * - * @return \LanguageServer\Protocol\Position - */ - private static function calculateEndPosition(string $content): Position - { - $lines = explode("\n", $content); - return new Position(count($lines) - 1, strlen(end($lines))); - } - - /** - * Search for PHP_CodeSniffer configuration file at given directory or its parents. - * If no configuration found then PSR2 standard is loaded by default. - * - * @param string $path path to file or directory - * @return string[] - */ - private static function findConfiguration(string $path) - { - if (is_dir($path)) { - $currentDir = $path; - } else { - $currentDir = dirname($path); - } - do { - $default = $currentDir . DIRECTORY_SEPARATOR . 'phpcs.xml'; - if (is_file($default)) { - return [$default]; - } - - $default = $currentDir . DIRECTORY_SEPARATOR . 'phpcs.xml.dist'; - if (is_file($default)) { - return [$default]; - } - - $lastDir = $currentDir; - $currentDir = dirname($currentDir); - } while ($currentDir !== '.' && $currentDir !== $lastDir); - - $standard = Config::getConfigData('default_standard') ?? 'PSR2'; - return explode(',', $standard); - } -} diff --git a/src/LanguageServer.php b/src/LanguageServer.php index 118dd93..73560f4 100644 --- a/src/LanguageServer.php +++ b/src/LanguageServer.php @@ -265,8 +265,6 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher $serverCapabilities->documentSymbolProvider = true; // Support "Find all symbols in workspace" $serverCapabilities->workspaceSymbolProvider = true; - // Support "Format Code" - $serverCapabilities->documentFormattingProvider = true; // Support "Go to definition" $serverCapabilities->definitionProvider = true; // Support "Find all references" diff --git a/src/PhpDocument.php b/src/PhpDocument.php index ff3cf8b..0ac8421 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -166,19 +166,6 @@ class PhpDocument $this->sourceFileNode = $treeAnalyzer->getSourceFileNode(); } - /** - * Returns array of TextEdit changes to format this document. - * - * @return \LanguageServer\Protocol\TextEdit[] - */ - public function getFormattedText() - { - if (empty($this->getContent())) { - return []; - } - return Formatter::format($this->getContent(), $this->uri); - } - /** * Returns this document's text content. * diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index 2bcda2c..58e7074 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -159,20 +159,6 @@ class TextDocument $this->documentLoader->close($textDocument->uri); } - /** - * The document formatting request is sent from the server to the client to format a whole document. - * - * @param TextDocumentIdentifier $textDocument The document to format - * @param FormattingOptions $options The format options - * @return Promise - */ - public function formatting(TextDocumentIdentifier $textDocument, FormattingOptions $options) - { - return $this->documentLoader->getOrLoad($textDocument->uri)->then(function (PhpDocument $document) { - return $document->getFormattedText(); - }); - } - /** * The references request is sent from the client to the server to resolve project-wide references for the symbol * denoted by the given text document position. diff --git a/tests/FormatterTest.php b/tests/FormatterTest.php deleted file mode 100644 index a46f2ec..0000000 --- a/tests/FormatterTest.php +++ /dev/null @@ -1,28 +0,0 @@ -assertSame($output, $edits[0]->newText); - } - - public function testFormatNoChange() - { - $expected = file_get_contents(__DIR__ . '/../fixtures/format_expected.php'); - - $edits = Formatter::format($expected, 'file:///whatever'); - $this->assertSame([], $edits); - } -} diff --git a/tests/LanguageServerTest.php b/tests/LanguageServerTest.php index 5d03451..5d58172 100644 --- a/tests/LanguageServerTest.php +++ b/tests/LanguageServerTest.php @@ -34,7 +34,6 @@ class LanguageServerTest extends TestCase $serverCapabilities->textDocumentSync = TextDocumentSyncKind::FULL; $serverCapabilities->documentSymbolProvider = true; $serverCapabilities->workspaceSymbolProvider = true; - $serverCapabilities->documentFormattingProvider = true; $serverCapabilities->definitionProvider = true; $serverCapabilities->referencesProvider = true; $serverCapabilities->hoverProvider = true; diff --git a/tests/Server/TextDocument/FormattingTest.php b/tests/Server/TextDocument/FormattingTest.php deleted file mode 100644 index 1844891..0000000 --- a/tests/Server/TextDocument/FormattingTest.php +++ /dev/null @@ -1,50 +0,0 @@ -uri = $uri; - $textDocumentItem->languageId = 'php'; - $textDocumentItem->version = 1; - $textDocumentItem->text = file_get_contents($path); - $textDocument->didOpen($textDocumentItem); - - // how code should look after formatting - $expected = file_get_contents(__DIR__ . '/../../../fixtures/format_expected.php'); - // Request formatting - $result = $textDocument->formatting(new TextDocumentIdentifier($uri), new FormattingOptions())->wait(); - $this->assertEquals([new TextEdit(new Range(new Position(0, 0), new Position(20, 0)), $expected)], $result); - } -}