From b78cd74c1bda075cf0195cee79b668039c2e687f Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Thu, 15 Jan 2026 13:01:55 +0000 Subject: [PATCH] feat(shadertoy): add fullscreen support + ditch insets for max visual effect (#278) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(shadertoy): add fullscreen support Add fullscreen toggle button that appears when the host supports fullscreen display mode. Uses the same pattern as pdf-server: - Check availableDisplayModes in host context - Show/hide button based on capability - Toggle between inline and fullscreen via requestDisplayMode() - Update UI state on host context changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 * fix(shadertoy): button visibility after exiting fullscreen + Escape key - Only update button visibility when availableDisplayModes is present in context (partial updates don't include all fields) - Add Escape key handler to exit fullscreen mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- examples/shadertoy-server/mcp-app.html | 8 +++ examples/shadertoy-server/package.json | 2 + examples/shadertoy-server/screenshot.png | Bin 118093 -> 118454 bytes examples/shadertoy-server/src/mcp-app.css | 53 ++++++++++++++++++++ examples/shadertoy-server/src/mcp-app.ts | 58 +++++++++++++++++++--- 5 files changed, 115 insertions(+), 6 deletions(-) diff --git a/examples/shadertoy-server/mcp-app.html b/examples/shadertoy-server/mcp-app.html index d59774e..32c9d24 100644 --- a/examples/shadertoy-server/mcp-app.html +++ b/examples/shadertoy-server/mcp-app.html @@ -9,6 +9,14 @@
+
diff --git a/examples/shadertoy-server/package.json b/examples/shadertoy-server/package.json index c3f1866..62bdc1a 100644 --- a/examples/shadertoy-server/package.json +++ b/examples/shadertoy-server/package.json @@ -17,7 +17,9 @@ "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build && tsc -p tsconfig.server.json && bun build server.ts --outdir dist --target node && bun build main.ts --outfile dist/index.js --target node --external \"./server.js\" --banner \"#!/usr/bin/env node\"", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun --watch main.ts", + "serve:stdio": "bun main.ts --stdio", "start": "cross-env NODE_ENV=development npm run build && npm run serve", + "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", "prepublishOnly": "npm run build" }, diff --git a/examples/shadertoy-server/screenshot.png b/examples/shadertoy-server/screenshot.png index 3910d53af6a46a1ee3d3b89b6cd2759faa87bf9f..dee834a4500e53eb3fe2f45b3b94e9466dc744fc 100644 GIT binary patch delta 12848 zcmZvj2~>@H8}?PZqIqsNYqV8p7Lw9T({8ejX^nPU0XZWbAwX_kG^;zTdY#t7V<#)U(!pp67r4uIsw*I`c#?o)V2aFR=SCwX^Rj z=R|%4$3I1D!H&oo8AG|Jg2VprKi_gyQiCeqvz_%jn_}+&5$IKa@ywf-KZWXlJL9Ct zp2^baD{3()r7CW8K@ZcM>JNbgM_=fB%zQ`u|KB>R> z0vhst(@yb)S5xwRlF#@;3+4O7ukl6q$@fYBG@T+OZ#gy5l;I$6DbZ}I!`3wwD>5}; zhnPwYnQF7;O{e9U>a%@KC3{SD+2*F=b*3}e+f1eZuAR;nubrAEe}S>IR^pEQ1wo@) zu?qPMA`!JxZ{#lssMSt8A%8)5Wv%2>`3ph|YQ?Y0Ul83()k=St-#$e&n#Dd8&2Wh} zX17NR&WJW-mqd%KkDkr`Gg?47dM29}Exasx7W-ke(A;Pvc73$yPWkQ9U&f|L%YT}h zImYmk|0HpGz&G|->HRU`>n+PtzNtPRSQ*PJeLp6&zr`!%n@Z!rL&u*<&&Nc6x%X~s zxUsZhNpD0$)5->FY46@xR|yw$_0BC8&3yVlOw~I-bW6;^zgil@HzXaAxaE*)rzhd< z>YOVhyvyDP`R(hg?1CFt-v-NIBdbzHd7;u?hJbkgNV``R*SlWpQrp)xw|M_ZrT~-KJzb(rMnZA} zGbzN;Ro9dvkG8m$d1x$GrrXi|W~lqL4Tfif=7$}ykgqdQ+qO6_ZFg>_u=cDL9b>5t z(~bqJ96NL#o~*-)#0#85pR_mKaE`n=oON-n(Z!&>t_y19uhuLmUic_&-y^MV0ri%G zEUBTX8G{^Ge6Gbk)`@l2%H6wH-EdkZ_S%d(H(+?~V2sAxE%Nn?ucR-yq}IK#zg@^i z;i(6rx@#^Jdtb^kdb7&uswb-iuwgwpea;|urS$efs2e0ofLzvSz=KQb15Snqm& zOmNPaVe!LViS@gbyZ6RUJy@iY5oVqDB0Q-`<=de`6+bgQX+yzm6FYmApv4Mz?U&0) z8c~tA$} zCVEtOdA8)^#M|*FI}Y~Szp`KR(&1OWSpIaef-T-o-U_YWHl=c`6d#s`pUM%Z%lWs9 z1Pu#)yz!8hj+Vyfl`8se>a}0pD_(A^O66;-3imNRx)eGSHfAV=rv%tva8^4nS+4P< zNNBzY9@50oq<16nzuA9Uym{RIdH%P8MIvk0dMBDN9ZW1rgP0kz_USDwZd-1CTd;at z$YO6iqNQcINw0Hdd)@EejJ!K-RJAe_lK1a}eb%x<%$t!hEi-b!v#cM*FmrEoJ$hLlXA} zS9#+BExmIoq2iKK@Am#19{pmYR__L)yuWPGlKx;)>avSFW0z{Ld2E8$*mCdFL*lV1 z)d_e$m3zNX69S6{OY--(&6%()eg0v=uN$ZB7q*Kxv{dA;8It^CaJBdQF>U6*k1-?c zgH~#o-K{K}{HcyNrwE50n8r2{4YjwZtPu`%kq8#rI$g@MMfBxj!Tt}7mj|WyGX%wS z4mcK1W$F89TXr*!D80_oR1v(L?B1d7trY5HMTJVUM7QcFZxuZvx;tC?tB_$_0_(s{ z0Y!VZg2Pzcl6<`-1u=H(yp>)F8fJ=>CNB~2cUJUsx)4`hB(kwEzz)?m|66!mQn-S5 zh=skcg?Q<_75VxrgnLytby?-_2+x!nVS3MqaaN9zELFQwB)UhW7qnJr^w2LR6&Eic zd2_8qQ&(J4khL?zLaxX}HAGM~Et;7*O~9i?&%NzP+}U8&vmwrQsI~c*a}Ryx$aF0> zzBw3oZ0*crLA&jYYUCy z*sF_;m}CsFGK6E)XKaz9N(ASpn_H)C6FAi_ysG6)-0UH-bAv1FP-*j@UP`4Q#Nx|6!VK>w1BG8FN19Ul$vRh)vu)w%YFbkm!%((}Ezhar>L!PY6*W z-xfj?zkA$Brj%Wct6byMG#eW}G-bvG+8@YDR@i^W(XiNAwXs`AqgyvI zP$hfX@t?O7Dm#+i?tf+H`EqeoVf!sz#Lqh# zHLfU5ZQA5*KD|+~Z7P|#Ta9?!zb}3BhgsMEezW&SoYq)Q;G!Yr zAEOU9PiRmBUX8yE39lJE8dyChvU%)Y^_PhO>Hos9XHwd!rzF(%oi9TtC@$9Q<^fjj zzTc;-20V)WozfMlwVfv;I%9C(R&9Z(U9lf;iY^kg6_#DB<1=wYt}IJ+L+p~Y7}rb* z+jWixp`T}p|E{C<`}ZS4^RmS+@4KDY&~fO8t)iX1!s4LQsrjtbf=gcd-g0NWpOl!f z(ze5Q|5seuylb>IdV=}2IcEj$pNRUa=+ET9^uStEe+@YRTcbj94KWxa^KWQX( z@R{vjO>5pZ??0VWH>poWcb2@l6o2BL>1%px?0l$qoEa;nnzJ=a2YB`}Slg?@C!_d#z2ap>@IOKZX+L z{OdK;J)SR8@TfkleR-K|@&SR5x2MV%uKj#FA)FKR_wD5w%$7Z`?9@*tf4O~-ap}d_ zZE>w1Q+FvkPEB!r;lHGK@y6mY!&%+h3(a;Nl|7#IxWc$2HL~NKztl^|*)KmEN`KVR z`ncDBiZFZX!E1&Ig{-8(HAn5-jx63#&Fha8Fcu3R_TP5iZt3}ttVr(vFQbY}e-J?C;g1S}m*34T(ez9$Q8X z*|jT&zVC`Vv}WPW5Su37>fc_-$EMzI_@*8>ur&5n-@^%!=YtEXueVE2$S&Ib$$WoP z^&0eJJ|4Ct@f{YiE62c`E7dorc}_{WKn+jNblH!p102KZ~wWZ{|DY%{$tEJATg z6ELnxFdnH%Q=F3t6xRfbYZ8hJWCF!)km8y^agj_y@x4cY;tP@Dnn3aWnLzOx7od25 z5m5XuHcjz)nLzQwEh*K?^0V;n&P{Af#NnuaZN(;Po+TdJ-uMH7b3+q zf#QLgK=FJRpm=W)?=nL`U+nH!IAD6$dEN*^z)0+7R3-qp(S@fWETB(a8s-CGKaS9Z zJ?8?1?J5Goj`D%9$6b)HHb~e%`Clezz|P1dfbAPPH0=wkFbpb*y`5yXL)+oTH5S#EB-GTi(}HzoJl1u2s^k1rr%g{KEm}+Ebf}<# z!SV6zTNjfbf9|j}&Hk>QG-G!2ad+=INdqytrr-p+a>#3su<7OH2OWd zApW>_0k=K6%wumxpJ+C@tvc_vswwqNH{>w4^-?C+%S=E%$NgK!OFiF8S>LK`7mcLn za^ve00N(xyXq^-O7;;$r-F4IlKcp$P#p|#ZvAr+<9Q#*aha3Oy?jJVc zx*HA$YIK%8NDh%|o($h`g?svoalC#`Kx<~&HQN0;*K3+VsP9KmS1eFJYx z0gWTIZL2VQ&Ys0PT|oap&C@dwE8lnXHteFm!SLK=%#EwA_d{3w{X<2yL_VZ@*zfY@>PbyTKMA_txElGMg z206ch_|M^80G6@eXsqGbz^xKIAUDbdIu>q{jiUtf84I7K3Mhn+8j1~!~ z7P1>ui>BojE^ol7-#{#ATLrMCt%9~T;#b-#)F=`y+A5Uy6iI(;tI+xuGDV~7Ix()tg?zE;b2Mn9N57=Ew*mvrH4I`;2`*zXB4<_VA0llX-a z@C%;c7d*i)lz?A2iGINo{Xz+Os0%RlpF+RjiGHC3{emy}1**Rc4Fie&^GeV#_@ZGb z1HOY04-xE@QR0*06Uy}MyV(Rw< z{hC<<&-0`&r2boFkot!)^;26(>_6v=rlbr_Nw0Z{v-e$Ut3`>Ei_Okak}P~NS(MSq z;(uzl9=fXe$K}yhZ#?k4#Skq#Lx3M^cy7^V8{I9>Q__!`GcXsqi{b2el_VBc0 z$*r&D9u8A?u3H6ue!Qk#Z)ppacQRD$tikcHlwF!7B>hCAEs3VxeKhoO~$UTUQz6@Cv*!-*G#+4VR@F~K!SoI{rfcv9lEPc!3|oi7nBpVHkgyb+B9NsQvOI+e&Q=^K}g8`KkDOEB2|EXQ-B@ ztdN4|zwi*qakc}r>URrnyZQ>EMlv)&{*^t3ppTRsGnsEHg@wwlh zG*FMVGBn2aO#Y^LyvNhb#hw20G!ypCaW|(={s=kw4tVkl=#xM7Kb^vlxhcbEyPX2x zJ+CW^;n$x3xM-hx=d|JElt*hWPQ3ZK_u?_*AIgsA0d(URKq7MLQSv6J8;KVN9h?44Ch0>uG5=k;<2vwc z3%lzUoiGd9^jqYAo#$l9(rprLgN^CKjv~X?oeQ4_9l2-Q!Dsi zm)*?gemzvUVVRj;y%8yFcEF?D0sdsmUu{~(3qDJ?Q3{=J(K_w8z{@>L*HvrtSED&P$7>@$aJM!B%9KYJa-v?6F6AoP zn$t;joi5u4Db*o1DvCe#X> z&=c5%dSDZJmX{qzfAX1mkFn#7+{o*Rqd)l#yA#-Idhi6|=}(>;g0*JN2A)YgotzFn zv%+5U1aH4O{n4X4&qA@e4vNhaSZsP=v3YjARl14OzsToszjsXN$(xwoD$e|mo;%sp zzb1Fa1MkdP`p$^|ub$uTf2`&8TaDSWi;Xk#BDSrktajggvg$GYUf@)f>YViA4WIRC zUGwf~U0Eof{;sD>7584-eE;HMr^$ry6-Om*RYBzRCj-|ye@LAEByk!-;`E2a=?{ss z91>>*CQg4$oaJQT8URwiqXGu5_5Lt$eO@j|&s&{Yk^XS>>&qdAt@Nh{uJ_7e;2Mfj zUsnzT*X8~&aIM6FYXF>l^9qcu{=5KB5?jOj;9y_a$UEo>v9%IoYrrhtc~6L~W zPQSi~ulPg{IB%CjgQrYOUF>}8B^)==*w{Q2>%G;;*1&y{$s&=-P$v+&v zcYU^3#+>21vDY?J_fxqW=$q_JPg`8zSn}cJErO2E=?+~wJKrJZN^6#~+(6Qd6)@Ib z0pk`vo=ZN~_BGHJin!;wLoAR;RMeNLO-ZQhg7ZOQZ( zEw@bFD9O>uJ@h|+*wvrw)|NbJGVhjxyN6jPbIfK1(cVHV&I>3Y;W#G^ z$2m?o&MAa(&U!ZZs^3dtnzJ00&X~Le5d^cMG3QI6@>tOeiz~B65B@QdcwGrxm0cR@ zpi{Gnx~?(414;l{Mj8|zsZJCut~3`O&pr4!H-rzaswP}pDX7+IX^q02n*Ks~1vVjM z>%*b&Sa}}yR%ShkKlSL~GbI$$G^v5sWsgSz9e6Kt(?7NXYj z$q*^+9R*V)CluSl^-Ag9Ew0=pX8*rt&&2YU1+BH(qJ(KS3UuQM?G zc$(U68<>5+lk`*T9zgkM{$`w`|$2c0hN7iId;PM4Z_B*TYTT^3qh z7Ft~vT3r@eT^3qh7Ft~vT3r@cT_3DDe9-Copwsn1r|W}G7kk|FZsK%V=yX}=bXguP zY_ie7LaWO{tII;G%L1$0jaIiCt!_73-EOqH-Dq{YvF7MTr`w(5mak8>USOeKAKl!UFdI98izpsA8#BP!SPss{+{kRq9SLdx56&_N z`eL3Xkig=pW;Xak(ed^_TT!;IV zj`zt~gO_-n{(-?fTt&Q7%B#IDph!)#wH!^AP?Jn@O6qXS&Mwl`b#`&)x|t~r*_zqj zVz|4Tz1Gdq)eUoTK4*U>i%yh`r~2RaEbH2u--o> z1Oo?+ig5K!f7YiaB9h|tX0G?cRjy2{Cta-t4*Tb-_O^$O{!f_ z(7S$R=F{iH23{VkWT+48S71Sk!<3`Yq zxR9j`@heN7b!jZ@@~oP>f_D!YvegOf<}k0pPkI9hBe(0`T*& zczOo-Jqt>aJsSYuOIOw?KCM}e^hVj>5qP`7%BefDyBq3|97K1F%Caqr4~v1^`b1HV zVn`Z?ZPPQj{PB8QZ2X+DqvMtoS^n_+rnzXq<%b^ZevGT_Z`Yde#nlg-K;_VzAOEUJ zGryN!{79r1KkP}XW!6C!Kdd^);)i($ZNXJR`R8_!fs<(m+52EBkiCx}Z`k`VWx?JD z^9b4d$Tz0Q;ztzDSFKnuZ&LGv#Sckb{1Cy#kHp*g#akSQ?hZ?GX`4 zUbrEBMnW>|aeE}6cg&DJM9MqV&cpVIm%#BaD5~Z*GE*w$@+*0u8&xZ!1{;^YPJMjFem-b`iSJeB@;beP^Ar$N?E9@W*JDf z6KvaL93iE$(#!?HGHNqnowt~*nf>NU98$b1oDWA3nqOX5KlL8?^Ku+}qUpqfO*s}G z}E|r9VHOyX|L^rBPJ=uH;OHE0ZNFr|Xtq?3(n_Rra4n#3gC< zA6o>X1l($1Kcjlf)Xb?9kBxNp+v`<#OeoT;L)D8u%qW~*zRbeWMWSW=n|Q5^T6Dv& zwnY=l(bopGZRMsHEYs0*maB%#zBnpZU)J{D>y_a3W|Hfb;Pp!IdcJVI7`)y|yxu9i zo-esx3107rT>aV(fh_{md=De>^{-^7ON1&ak@q`PQR;=Pz@n8-Epw7X6;&Ds=l+QL zB>Kxy!SOZC@1(V7Rx1{&oTQ|Z|GzY8s3Zw(^narh?WG6c0U>|AbD{EKK8| z3Ra@8_JLcuhyV#7CUeW9QFG_Iky#UG!3A#3!luV**-LwlB=D4^;Hcjjb;TPbySN4P)gMgg=>- z>y%LWoueD^l4~P)Af9`3kZfpjZ))4<46H9oo)FIF>I^OWk@P&B-nmUqD0Sw`Xqd|M zjLd0S9NA*}O>J@@u*EW!IyB)LcfdI%i|NKatfO*R_aGY;2w~w&RxYz!Sw_EWFWAa_ zMK7K?YZj4BK4;vxEQN8m8p=-*!3ArxAH8om?Pz*=zF~R66*j%xF{{_AoZjPG?+5Fa zT$ptqXQTK~1Q=;MoXM{&@NboxU&%MRqOzUd?65#$IODcuI1IW~Ntu4bwTMK2W`qU( z>k0z$=>|b&XR%t9D8kTZ0jri=GUX0Q;nPj})=HBVbnH*JbSA&6P}>x)YZX+7y(%>q zso{*9mLv3tTSiJvgRaq=ql-xBx84*(|DwXZ5u4cqIwlcyu& J+~Tzf{|7T%t&RWy delta 11245 zcmYkCX;hPE7Jv;Xgnbc^9RZ~gP{S(X1_B}OtO3O;M8yb#!Q#GrC`7^ziegbK5S2in zf}&7YcBs{sB`j4@0c$C03lof+rM@%Up-&iK9e-sic?)icWX@|6>+7<-OV zZ+jnZ?Wu^^J?p6;ziLZovtaM9S7RRh|G$s-yrqQH?pvE8|Izrz)am*B9@~_FO4|%a zR@(MT+bmV7cxh#6x~()dsy$aV^{G=~gjD~Hl&MGP6sVuv!#hm2(FhB6ionaB(1jJ|14UQ&uH>|m@r_uP~FeN zl5M4TA>l65%gvtQGgY@cp-5Z9qvbCtH_X#SyiCn3Ex=`LfFCvT(In}qFCzuIoOi}Ki$J>^~Yq5=h$crnY= zPe;$EG9gtmacNPI$9aFHP5!eAUP%*DrFwpwf;@wR)THiF1vXKWf=qV!O?j<=Uy|X% zne40~HOiMvTB9UaEpJzfQH)A{GnA0Y*s*wXyk}3swZeIO3pRV)Y%@8~Hm87mM}|h@ zRQ2ZU1nLOi@W=*l4{HZiiGxi+rD5{uN$oc8<@Fnvs|ai_M7T#zbe?>fJ+A=2W1E6~ zqm{j;K;;DA=!9~Wf?cJmOmR)(mC)qZjF?)^*7|1&SHtbDM(p#LS26jz!u^Z|y=ey+ zFIyO+^4g|Fgl3p(8rFS|{l+V-ri^;xSr!vaH5t=R7*eDGUE9>;ulf8rtzydytXJ0;t22|riw$86IX{9N6VY z%UPYR|7-RF&fM(DKV;A2;5%|A`Du&%+&DgddQJQw)9HS?=lMa#oBRxZ;|H1R`{^9# z2N?zX>38vi%v}5?U*S{ulKdbGjW+EJzT9v{n=|KLo9WCpM^1U0aZH;l=VhC@S(^jr zOqq^+h8~Dx!gKYE3d}p0w zY@=Mr5ycJq#jj%acBZjL+oH@UYn9d$?2PIKVBzSd|&!Uxqu zI)&_ao5*vH+9~8zyw?{Adc)uT#Q18h@SoofO<6epG1YTICHG0l;%STd(?;!P9JQPq zFn*kV%=;IexoPoS>aP%`jovmJ-`J^LvNE~!&vC`MIch(AypwpNHTlCqeGgB)#Synt z3s|Y|g5fbgV0}Ay+;>ut_w?Jg64lb8{PkV_iZ1>?UA!+%ye9oUm-8!`Lw-TY zdU(o?i%{O4hs>+;RgNE%O?H>4U3=f9(buj>E%-PrdNh=H>)>lIN_`}Hs!{~|$hZqU z82Q!-7(px6pw&CmAY)D-n=%CT*&~WkFlcHY_-m6=Cw_*QngK$fOh|2ZwkPk0H zaeLWgT-M}X_BLA4l|R|_pDUBXDm5N_ynpCS?{7V^FY4C4_&a)$=98(K)Vm$Ho?Vkq~W(^!&pBFbNn%oA&W<)+yf}X3ukrq#RUhiNeHeW{`_sF`|G(mx z^8X4gRd@c6&lWRRoE@0@{i;!I3#Ha#Z9^T^W2+*QEKLp0T4}4uR{4vMXzV;|Dy*MW zy^3V$<6^^!+G!IPPWQH&#?d`{)XM0nwP@9h9MzHoOB1WO$zuyQd2lu^jy!v5s@)~a z>#HC^9~94TP21o4S0F>r+fwgM2{X0m}`G4SfY~uUao$xU18>dC{ec{@#?}WUi;!be9yWUI$bM}t%CII zECymd4_q|XGU2QeUt4K|c$JrfdV@oKagL#=-EgooG`(T>@{ui8$D%uKQW)DL$X7h3 zQZIzWY4^x>i?tM=1~b!{q95&?>a{h~LUhDQT{4z;gVOa7Qmr1?Y26s9`zu&oLF}V& zQP)aG*E%I+NsjuDIrXw!u1LP_yyu#8UVAS(PPKNlyc`0>s!wLxnzFX_Ww7~EpM_7~ zmQGMD(pKF^1yA(xzbhMH9XiVTEqF_==jzl&UVI_aDKt$2b;auS+f7Z%7DH zbYLbrG|CDMkMtY%cX89}1?i(v&i2g_^KEv!K&iTc^j>$b(f;n6D9vYl^Jn|6Oi-(2 zrrlg~_fg2NZgUA(@j@>rI&rqJbnLAfu~ z_;v~Lo}pp?Iq|+)V`I`OdnH=$_sX?CI@C%I879>k4z&BJHwe>51k*SX&ds}>DX8)D zQG3i+G&wJCQO}Cx8$|ANR{q98>+c0?5=5a%P3AM}0_+>MXYssx{HPJW*6^-AS^mA^E9+ zzSP8;Si?b}|fGUZ|Ho+l!$gVlU(4}0C3 z1IKwDM<=ehHhs#=zyomkHW98GuvDL4p&VFTi zI}FI(TW-Zl<;Uv#s^ogls9q{jzf*KN>^FagzW;Y1KmN(8{+Q@qirH1u7&}&AD4s4 zzUbDqZ*rvUcSTR)@%4GvuP8-VYCi9~pODd;bT2lhj<>a8XZ6nTuXg@$1*rY-ewLz} z*elkoS;w@=p*nML;>v;Cu;MtS&2c}M|6P-iR`axb)7rY=>hJsAW1n0I18Db@@2kmD z-aXW9J->PK{2kAYz8jph?%HeBi=#^0`t~Nj9jBgj`|hvbyg%-_-L3w42Wwsfvmd@s zqy8kY{+HT)pJ(LHYVus0M?^Y%84+olJP_$wv`F*vK%{38k&ewHB7J)q2-sQ_=~*Ds zs(D1DucJtRv%I8r!i1?4mMD3927P@eA+PToV|sPoF2*7T^@aL<|5-ffzHcUKg{fUjdP@5;nwmFhp8S##)ksHkgY zdEJ__hP}nE;nuDZmjl81`bx}tQ@&pLvf2Da)5796gA+6dvICRjCi=$REg5t>bj3@)n$-LupZT!a?BR}K^FId}=I*bVS)&tIo!NWj z_uYr`R^F_SzEKxe{HTAyLbumoe5c>1ZX3_ESoyJW_J?MR;!gu-|CK!e;%53q|Lw@u z=KuV;y(6BbIpD5G^v@LZZ!Xw;9E;XJcRh;u->z2TfAgLa|1(4X^8^2jV}bv<5t+YV z2>$n%AL!ps7U&`lm_sPbdKWb3>CiMg7x6{Yysu^FsYAB>Ja``j?FQ z=SB37s(4t4{?`Wnw@U#2H?Io(&kX#p4gBvL0r=ls^mtR$KTXuXWYj+|qJL(nf10R& z$*6x`sDFj1e{GUKePYUKpq5MPFh}Keq8{*_VTW`=0}yV`%WW0(edVcw7NITM2kveF%4AfIF_h zom0S_UThh+B6nN~cdpI=?mWl^?!+K>T#-AckUJ}oJJbaN9#;g{}cV#BzVa3?AdxKmXE+_^6Y?!+K>T#-AckUJ{~ceWyTT#-AckUJ|T0eFsC zJgcR?sNFGiBaJksk$nG??=q(~aoTg%kc!G$10xXue3v5fZW8FevQ8+jta*}of=E^t zkJ#y90hH9E0-T8m$cM?~!NXKvdElp6JSeJ}JTep!z?Ufz z9OoG2`ure(1UxSY=I96cToHg~l?%X6ZwjEON(5vol7UE0=h;3jO?r3HY#rUrobrv(74QUhSxlokLX zml_Zw_xxI(7664UHDH6YXD18%^(PjH{{t4#s)dE)CKklpFRa&#w~cu|W|7J!?(k5r z4_8m=0D%=#9iaXx9e^uw2h5vNI>2_s9n0_5zhFUa`@ou6yV$;dfCUEoiUsOF%mQA$ zXW_t!1-A2s^|E&5i_{LNZD}0`O=~?(Q#(Lm(>mf#*Dg7o+5x~y>!1ftl+W7K4%&CR zSYJ2ncvyRn1=X#O)z@%fer*E_9JZ6Spy8VvwLh_dSPxia_tjRFT%rKM25XcF!my)(2GO`LylCHLNBtWi}WI;(2MZ9;3+Gj zpce^sfmWmpTM-_%A~Mp7gtmm=#>i3NB=YoX!f0 zP767vg&ea&j#(kctdL_?$VpakF)O&36w2;FbHdRitf{R(f#jN0BR&X&ZxR@1O%nB}Kg&ea&j#(kctdP@L@xQqp{g+pZ ze4G~3@K_A+SPbxB((s^!p;me{J*@SJyJckqJ+grwen1Z<(u0ZgU;;h-kRB*+nSMwQ zKgf$rKZJ)L!UHDiOoRs$;lV_BFcBUU6Y0T3dN7e5OrVD!fHmC@>4Ex|?uYd7Lwfij zJ^Tngm^f5tB0QJ~4<^EciSS?|JeUBFHUbaoZWd0}Guuc{XP?!E^gw~jYD0RoAwAkO zUo?Kt1S`MA#IZUPdb&!cS&Pc)#u6qN+z-q%EtA$Zo@bIqJ)_NKZHvak^fs{a3>>Sc zw?R{v(dIIs03(nBe7Sne<>?`~|bDKLt9^q#els z94QSP$pBoyo;Z>LIMPgTBm;1yG;pL)bR>IpBm?>}SDw4d0!a!(Nt%h0WPp;ChLYri zl2k+-$p9TG4IRk`9jOQ%$$v+6gFnNP@ukDe{L*385QkYyhv8ZX!?h5GLiqn(PaLKJ z97ZdTM4@ILi9)Rqh(aMop%9}`NTN^^kM$eJM#g<2u#Fq$C{hFT#IhMFP7VT2fl zLJUJ8hM^F{P>4||#3&SE6w*_4db1M(QK(MaEA22EI7C(tfhg1nfhbfDfhg1nAyFu# zqmZH5Tj6tQ7FVH6jB(5LJUJ82}6w@2t)NA2t$n?-0t*17;5x5ktkHhL9#{Q)m5^8|} z3DrOX2{uB4jgVj?B-jWEHbR1pkYE!?Fgrn=R62nX%uZm03J#E&ow%v%1V%7B2_x8q z5mOpIun`h$gajKQaZGw8_Y2@Uy`WX4j8+vMQ58o!P?Zy)DrH1fcw{-&XAh}W8RlP)+ly^E?6iK=p$ zsLCl+m3ycvk*F${(NtFB)U*tyrd!eF=R}jK>1v#smci6?V>iIn={ZbIzuf_AvAZ}m zjU-v%@*Jn8`8!~0dJm_jkvKKIj8oIqI5jOJQ`1PCnqJ1K>1v#smfarTtoemDnSQBF z?`UmWK^JBlD9p#8FxxL>o)!Q&ezbxb{=s{v3{Vywou|XkBe?)iE*+~t$M68WV$#P_$luYz?Nns@~g@0L+ zEzAv)Y+?G7WIH{;a)%Vc^?($%Bi~42q_(t>GA zMX1&yT#txwrY9P1U& zD=&rCe4F%r;UcA^C>Q`GMX`=VxN(wbx2EVpe^L}INRn`>mlOqS`J^a%D7;hpEPU3p zh=WoX0mVsAgwHq;u}2CayF=O?KC?UGfE31h-$-#UFC{}^QPi9_;j`a}qF@9h8fIrc zVP%SjA!bFx&Obk~|5=1{JrOlb7V}aV3r9+0`(6Kh5-WuvP=wUH-{HF_Tci-Qo22Xd zT^>D&k&?k)(lBi1lZIg|oHYE^!Tvd)l7?r068-Pig8s|vO>jQqqO zPA0$O%&g4|s-x#dKS}#~6L0ozro}lgwT>~3GTx!l6Q?*Qb2I<*x(c|$Av==*l@fo(zYFy)-xD5X2 z9H);?Ea?!pgb=sH5O0MLFJgLA^~OaI<6?+$F~qnSW1NLCjuXx#7Kw2&#<&<`T#PX; z#uyi4jEhN(7YfA?;!+H8Tx5x)umKcFVQejeyOUW_A}PkW6l0vsIJbx~#>E)pVvKPy z9pia+){HmQf3IukfAg!eMKhW_r9quPPne({vV@-Aubn|2|KsQG57cRulx^7?-+x}; z@!6t!YD(CgP47PY_I|SX>(d=ukjd!;Lo=ab%>W8v!8!*JvLyBD1TqNA)pmRRRxLsNV5vHa^ua=Pj=%@&R4%dy%hY*5k1fvFN`O2|$%yS7 zfX9jm7}dhu0^s4ofXx%JgQJdYLY-x>*IAFy=>Yl4L*`V$Qs+D%#~yb&TL^LR5aS#G zXBuvF{(#(F0t=m$h#NBB2>t_UvlR9@AqbleP_E<1nlaesoF}Nk*+veM2G1|f-5xLg z!nR)18S6)9EDJIgWXlnPlkZ0|mIWCL4V-H$B&=TI1d7hs0?b%Ha4j~8%`2Xmu?6a_ z;^nPdv4NYzQr>PgWxGkP@}3;6cN(?{hgnJWN<_7sFf@(ul13em%alNzT@p(rN>N28 zJg@jG@9_Vn;JqN>h+v~1N%uq&nBE2FJ>ih1y8w>M1lYd0NKLLul=m9T)o!*cAJ7<1 z{$v>5hSfj-#n%w;Xw>1f?AR~w>b?l%EzB=-c7)E^QF=}>Xh%LvQwZ7F&$tB(u2Irb z4BCtSneb&IUHTCk_cx=23E=bqRFG5vd7qx24rJhO>? zI4!25M&nLJ<(F4@e`mS;QeYDOm&u^}k-3p0RCP!*V>@Gsg|#kMQUL7hnKIlj!rEJp|96e z&yBsGQmxy{i2d*H&4AyV2fwEWzqbp2?==2iApYJAQi~4m`uF$7$nOQh@5R%<_v4QY zA%ohH&olV>j#%Z?k6Ti8YJymt)XH0ArCPMcr(xB&QF}T6$&^NKds(kIu|~XE z-{SVboM{!X6ntF%srKx+8Wr|2aT+)3IDPV*Qdv<$YRthd%$<_V2WeA_cFoCYWq_bFbRc*B{BRc;r0G@7GfLqQ|&2tczaqE{>6r zgGJuIvogBa&B$NvLa%te?PTQkL$JAvKF!iOQ%3H2icSTS4KE%mMic*>pjb|>dBUY# zWWk$WWlUdwBv$gsT^7Y|k0RGRT_EliWJ8xRmq&K?m98De?=Er?wVG+)9X1=Cy!iYmEk6*i`0U( zm#@*wxs)&-y{@Nr#r-l&AM#k5uUOM|-_xzl_+N(ZK&o^@1Sjp*bHQFK_iD6mQZqiPN4knm#ZX^5Mut4(S_4ueV!JokA*P;%!}_8t0UC1XB^6om}nRfRv@O*`n#v84}IL>(M*UFY{ms$g5B zYiklrUrBoHkdS**X-p6)3CJoV(n|X{Nyxd1U=t;$PwNa`rr(z+x)&Yur;j8<;+=-+ zW792I5Hg63g%`BbH5Vv#x}ks)R;V(KmI*(dpfMv+fOv?eu+Qq-17qYD_N`TctR!Qtf&M@vw;7 z?eu-5rKzj?VTs$3K@Pd76W$+E|9RkaJ51#quch17q(*ayd&K=TL_655KaKk6