From c27b532aaa6da86ef125f3608a52129c689c5501 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 30 Dec 2025 15:47:15 +0000 Subject: [PATCH] fix(webcontainer): prevent double initialization and race conditions when booting WebContainer and loading editor workspace/file tree --- .playwright-mcp/workspace-working.png | Bin 0 -> 54026 bytes changelog.md | 8 +++ ts_web/00_commitinfo_data.ts | 2 +- .../dees-editor-filetree.ts | 8 +++ .../dees-editor-workspace.ts | 7 +++ .../environments/WebContainerEnvironment.ts | 47 +++++++++++++++--- 6 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 .playwright-mcp/workspace-working.png diff --git a/.playwright-mcp/workspace-working.png b/.playwright-mcp/workspace-working.png new file mode 100644 index 0000000000000000000000000000000000000000..6aab7232f4b7ed4054d413e72e3df11b7c2fdde3 GIT binary patch literal 54026 zcmeFZc~nzbmp6=MDOMrkqXnpll;uDv0xB{OsnW728I>u_Q4yI5a~Kl`)JG9eMj0a@ zAY)_-a{?kDQ=$wBA&@W#0Rjmjgb*@)H&l18e!qTK_xgIh?^@pX*9 zhEB}Av@%M+N332fDtv z4<9?0z1M*XtpKCO;zZMjQm(xE-u>8T8rzz{$Kd%!*v6RR^THuptS+jlNv}iS{?@G; zCWe_5E)TFO)p2A%g)ZS;N~-C~4{vu#F8&!Wbxd-8@YlZovf-0;Xw}=dw*^})R-_RK zVl{NBtE-FTk4B-OK|w*4emev;yi51LmHF{UGjnt4ox}9cKXFid*QWLL^;uS=kB<)+ zoVkCePrXFjynv z54Sx4pTET?3D{igP)=IA_T8E{8(FqTj~#o_YfZ#T?n+IE?b_f~#V5SPO-ugmSn50Y z|9P1IDu_>x(qH6Nnz&z0nZnS)#>?7AYMEtUDcPWG*0-2B&GEc^BHAN%^Q zL!vgGlwukxXU8!Mz2ZAg*Z;E9Y^50{n{YnL&{eQvN)GMxwSCXCt*6AJMWC(DIXYx( z6=q_i&DgSdu8-Wt%_Sq~3;KPpa=B$t<888{NbnJ=BE%W1ytj(~)`k~Pf8}FCm_q9+ z#2uk+g=of>eg4qN_*c2?*QiPH);37Y!_&c2{MXrk>^m9%A`02Ul}<(>X7F^RLGWdL z+5+&@A`}vNM>xkt%%9TktBdvB847OEfA^xX5?aMNuBy?;u$p+Z$66{=oHLvR4Qi*p2cL?#~-}Zl(582@dsc;LK_K)9+FC|;OY){LFY zFP1-ft8N7acF>)K^}ditikLAAQ{lwgd^*ktYOfLw`55Z+jK^z?a! zsVJu6eMaOo!zHkp-#JC`(PJjt3O5kphOIO~SCVC&&nPWD7LTnv?~RLVtk6)u0-NWfy} z2IQ*9BdLEq&9^9Qss6=DpSi#@#v83owe!i;-csOO_O=g8S?Ft(cl+nSy}c zmS-xFYhd*P!+R4py~9hLqxtBIb(deie*^1M#C!<(I(V=1HvV?)&+!LS()+&DsfLGb zT9A`015VyD# zG?1aZMTB5tIbUuv6mRO=^W=wy`I);$Di55*Dq49t9nOQ3k-F**A3 z$@u*I{8zb7PC+409+zcgRLO~_q{XxGE+T%3F7aRNIE=6>>~p<8Ijy`IeycMnz%oFc zeC%>)H4@YmU~6l=NMa3YmFXjdPm0H${}DnNf^7YDcSI}4nbO9L{GdKoI}<~VJv+IU z-kM>5I)%;Pbrw;1qiy%@1_fP=4+`@LD-6N)<27;sbD~WNo_OwYL6YhlHMNfXc=q(w zU!3YTP$2$8z-wfUmO%V1HCoxW3Fi+z&rTL}6(v)}W!d@4c>f>GnSzhf<%getYr|s1 zEPIH4M%ZqNgaHA|y}efANk^A3MhTWN(N{}6$%G6>Mu4oP@yYnXq%nk;ihu;u%4zvA z%Sr>zC${)}LPMT!3ffXGmOqm(7du}uaDKBAzLquEi{+4?K1EUuOP4yO3EHwx7#0I1 zRPJP~I8+uZB*>OYW8u`N=)rui6I=H9A*u^`ZL&OOVdF|MAZUw$7CuIFdtew5*;X(^ zJO+u5zOGFwZV8<(pMPgT$hZ(io2TTR@^yix9nXp?l=lkt(H$#f(n1HN6*i{|FD z7AA56vEjbHb3Fl7Gwo^_nO7>K@7YFl1|U(^Rq(~7k`1y(Nzk%1v^C&P#6ZteaCY`) zDMj>sX>~n=pjrK^EBni`qG25^kdR;oEPpXEd`GZE2M-pU5(|VQuEwQg<%f+wyE}m) zIs4~k>q;|>kjqBV_xnaSHchi}Z%m$jEHlp_dg@k3uQU_<_mRau=KBhQme;q-aYKHa z*vD&n?#;KO;${+(jq4Yb?-9M;G@~(R$ykc-P?l^f=_n5F889%c=x_90qp7t*?`S zyXoKpIh=j$nBkm#0+c^n#U54yBbW%2rnB}sjhK=PX=78{ymYn!0kvJqG-@(&tGjn& z$WJ+|E-%J;q=1`V>Hyl@s533kK(IFDN3w}k+ofXObc-En(oeym``XOt8RFKamYvUA|D}g08H-eB#Fng{e(mx{M}0&XbKMd~8;6 zcZ|AVCk>2$daD0`w;rnBm+m)bY3)y?W?OpFORUt@1_>9+`gE!TEr=IdSF=A3RX7;K zuGCMZnh~D{+3;WZ8>HFyxad|>hu^#)Qk-3y5W-En_pYv>1{nVozfOAq?0y*P$oU*v zwRF%ddW7U}kf&ZzhN{@Fxmhx@L=n2=JC41vYDb^aS28VWVoE_47-&apy3{dTQRLXviMEi1ACu`Y-zQEdezzw7@(Af=Xc(Eh#yNe zTpcrfBmEHu@n1+S*v246ieE`aeKm>ly3*-Z76oAxlms4XFVSg@<7}q7PlEw9RXT?B zUXf+>w`>ChlUJDPWlp!i5jn%I1AXLbJ zh-mN|aa3aI#5es4gto?#i(^58fQM(aiKAe2VC?K)ypQtfWlvR|>rTdhEaS)wIO_&l zbys9)R$2tW3$^0}{^c{zlLo5G&RGN)>0E2`oiT);`$aOI%#?&8=_{^>lC)#sEN{q* zFkfpwgDBp7L0Q42bhWn1cNb42_g>rg#6BU=t@*TQHapx>H2_>)UV&Pkn*5S>;E6rQ zl&t2ZMql=;O_WW{D_E;d`M6ahF0!+!i{urSJ$Ygap5#EVTb<>R`$%C>oqM*Htv0G> zUuKRGh)+wN_TUcwIM8qQV{)~!W`!GOy`-!x+#0%MfoVivAd|9iJp;Z9)Uc69k+xl% zc6Th}+-5{ii`uo#e3$)XxVrwL*MP}=loRM|H$1U+_q-CS((Phn$)K1fS(G9h z4LmPjF*1sUtIhl}r?ei?4X|2zUrEK!h?4osR7+|2TMglCPYLDK5N7y|bNx3^Tyw5audv0Qcc8zX>(i-n5^ngBi{{e9Iri;2DkS8AlN&k#erAZ-E|{3;xA*E| zfUEe^HN5WT{cEI7+={jghzs#O5V83*B?YIbls)Vj&e10Icvu$fFx?0uj4IVi45~|| zov&t|v{7>Hj%Q1-rH9vhXUsbK`jWO>0QA^n6s+;OtEzp-dhY%rpln2>3ganBF}TMiq@+(4uA>n+;e)z*G! z)aGa~KHYM5jxI-7N_f$bH5KvrrOna(%3tE*;($!@WW2wQ;pNMRECXC)|4vDN|NVC` znCM6hDeK!rGe8NAn~Bje=(=zO&869JiZrpY@Q_3qb!my&n6GOub3mQ^9v~d4Yv?Iu ztfx0VHl__1Y(0APNDy09sDD2)QZHvHB0OC7z=5Q2bqNa{dsf4s(n`mV|8!ZR7gB4u z@rnJCi{DOv|3z|^`s1pU#D@V5R>a-M9@Je4p8Zs#Aqf#~4+6>PFQY&ogfo&SULIA~ zlbruu+Wtw^;>|^Z_D*Zi4=-RaSaP_mtMB>q=X+Wtj7r^J@#)+NdH*;4{RamAL&L1+ zVbw%{V04Iw+fE-BH)p4&raatsXJ)Stvpn2(#&mJBetPHb&xgMA-nsbY8?=*vuDi1iz|kOp$tUP)GoX{LYb82@$#DV(kC>y;a6RpHN^ zLWL;;udtDBuiV*d9qY-ZYb}T)1hc`gsxz_EO97~ zHs`eyY6tlkSnmqkcaq#p_d*S1U+Y}l9oim)XkAuC_z$!*{Ea@9;!qV6(OVt2_nmYI z_naDyTr}c*I~jjavvPYt9K^wmVWCHje73vjA|9E3)qg#O92kQ~KZCE+s*7ag2irEU zh4wOC_+N^KNPS>xSQkfSoS&+#O5G=sUk5q(YyI?RU{xI^fvq%vwEodD51dvqLR!gU zEUo0OWezA*ud_`=~MvqgFA-c+vfVmo6oFC2f;4iimdju;oBttKao~1u!v^Ac8}w zK0SXceRR~B!)KEuj-=nbmnq4Yj@}F>=Fw`7AJGDwsGFM?BUTRJEr{hSr0gzj-ag>` zH%`%!_1^#%{}pljBlctb4-(gsKk2BrBhHuYkzV|nn(BwYbSYz39*EJV@bP-D?v6v%s{&w4 zUd>3uv%S=VlJ}-JtlD?)AevIRNB;p%)xpp#Dw}HG`bUeJW@|LQtsXtGtg=qqyh5V(8gh(X3+p$#_9<_w(VUzrjwapdSwXhSaM0)SYRf63%ki;nMXpu6mED z|DWrRso9rH7xrJ;oKAR_FY+bNY&Kr;`kH8K!s84VJzt#e6g^fVi?<##(2WtyvU!Mz z!<`KCnEezS;YG(Y1EF+dpU?AsbgV6WOKAwTaTdjQh+=|tuxq6kmwN7f#WC776LX`U z{NcasmU}|61t2W{oJTQh%8f<`%+0 zR64VU#z!Elk#3FxtNo?<{@e4q+ge`7GX0dsd5)h~lnI&Ysy!Cd4cUA_o5}Pe_ezMg3XCpU)n>&9>B4jDoKX8{Hm~1DPTm!Wi zt$usZw0La{DY#D}ZH6x@8wl?4ClZ&=h$DFrS7Q5SpR50$tjShYx8|mcUny9&bd{!2 zR^OA06Mbzda+cc_Vpj*_;M1H^G)UyZr?i(k{_+|UOn-LEnVo@E#5A!rhIBT3bSa5j;g)zj*HS?=c{aR?)SK{s+K}!o_<`J zeFSO1-;vW?ka$3Q8M#Dj4|j z{-mQ$fYtAJZ?COwZ)OtZJnK$gD*g6CPF2;uw@$qsWir-`;5v!QcLYvZ`N-Tgl^-~f zZtkA`SK8_7E$6ZN$EI*$mRqtI5ho9`gS6{`UPg!9Wj!+N;R@dSjCo~?ni{=viO)Zs zThMSeT57?6%E54!Pr>T1fKO{;jhGF7q(LR>IcIb+)!fYw=PU@8ROf4H?J; z?{j8S7_Mr&0x$pR>b^a!+UHq{*m^butMdgB^g;FXS*srle!Wx^+tglwQajy$_Q}mF z)giM%e2l-Ke7Kp|YYT!3xlk2Kjxu6iwKqBW*}tEgkPY>VFC2S-z#E4JJ6uKc1m(@Pu+atG zek6z0SNmd}y_T@!dME+7K69TGtteys@IIz{U-_BLMalA;6iyGp>R;b#?uTnEqHsC9a;TxdUeUC|xlN(myK6;8*7yI5#uuCkG zRj>Yj`CbHizd~4=RauhqKNVl9^dI*g&}^-_*jii_WePY90t9BgeYdu@h56gQF6B5> zwTeY)ve4k}{PpmJ9xp;kMEjNFSNE}Aso%lxY+#JKt9>%ZJDv5KrMje-kkeU5kQ zQ)?c_DKU-LGsV1hYxr3d!V8}O`U@Cy{fRHngS-1)>Ax|anARtnj8a3FHOBU^3O}vQ z%d$g(K>_13|wN201gVG&JUrW%(@e|Ady44NDvYUPshECWErU zYVog>ar=+As*zKNdOTRc1wjsdF&Qs4^WG@#eR|DkcwadzQ#y1Y4|J@*-ZMG^jS}0? zMVmy89sqe|_Z_?%Sw?SeZN2)74u?@jjBT!Do97i-8c$LWAIj|YIGHJPQYY9oczslV z<#xo+sYr{3Cl?Q0{ipruLs|a!FaFd9AMK!YuB6PKyI%9~sl{2PT2r}H$(4>_%F=7Ux~6ua`b(Rs#)MYBbo_R$wVJZ?+Q<>@n-IW4TCzDfK{{^VNIAGa=t6j z8>jpb)pwNTxUV2Ch>QHQB(B{+XmOSli-{^fT!3(wtYGWo zE61B6QR~^X%x4Gx47t|ZXx=-QTCI7``l(?3<5A*I?;7`S$R_Q72H2DgtL@vPAI8Rb zyp#J?PI#}LdlMCR=Z?`QuXI--^(;O=HIqc4>Yn4}?_mid|8lk86rrptTUK0!xE(oJ z>9s0<`MQ!bWIkwIQ*4mw9JpU@5t|wHIu0jNe|fU1k{`P=SlqnDEO>kE!`=usmr28NLEl z5(86wZ3wi~HcPJ)EyPI!YaDS#rCuUd7x<#SWv zVWtt$zlQ&;tG++t!~vl2VeY1R)*Q7pII1@AEG8lhD;U9GR?fk9lU(U|!?W<<*>s|p z4r-NRSkcB1=b99F-@6SXqB++{2W6H9XWHkMMdXbiNP`850h$4W2fXS~)yl40taAe( zt;-)8u_%v7z4%u+9kEM{D6u#Jd#UW_{l$dF)hXl4xvL0XX%skitJXID7WrTI0${fX zn}T;QEvS-hO>rFNPPF**H+emf#ShHC zJel0R{Y&c7gsxE->r8XkHDOkDC^~f~o}G@bBkvlz5h5%TiAH%&6)@&un$Hdr@c;%O z%R4&qpJe*LPJm~jB(}>Bibwxlq#PZ&`2UWkNnySJOU%u(bvtr&S!G%Oh}wmLgfl?6 zPHQ}`;d-j8`L*lWOvZ8G9^H9|eVK`KyB7g7x=988qAu)U4iC(G%VK`pNn|>l4*q>{ z@P~h?+Q0sv28rPQM;?D~;`qO#4*yIJmq2d0R@bjzcXD#Naigy(c#c9yJay{S?%lhU zm6e|zP(F6zL{jB%QV(noNi@{;?JR4n(y1<`@0($(v8E=le@AlE)~=6%A**z{A#u-l zQn?Qmjss*B-%m_Tz;aEHm2cm^1#G^pP2l>|9;r2*ojh9OkM#8PGiT1we9>)fZBBLf zfq(NVe%K{N`Ee(0*7!pe>KF)xLVbL0l#W1Il<+_1^fqNWh z?C{aBTeoic_$)ap?vZk>o&6iNq&e#3B=#l?n;X5q7LLeaR%!=;j`8MhK;bA!S%Si5 zW``LF3DPn0C#4Q5?{HhZFx~kW8W#k|fcEct@P3O409OypEx};0hld9sK8;Kzzz02m zX&Xy6PHFs}mzP({T#4f{EjAZ*N=Ws(|2v zjir$}))u8brnR-TxBgG5X}2K>#RmyCz~}-30)GF!bBi_SHIyAb8|&^)0TibvSp{$BrKDn-4Js(P%V$zOkV~ zLgK9~Kn{5l5(hl3_cN&PNCwS!(~=>^Yz>r1sh9sz^t>gr;n z9799deJGV&qo|OmC?2o;A5zmtb|l^nl*-CfO}s8=O|`<1zTX&AtA%0f$)qA?LvP*s3P{9CJA_c_1gMbe0qR=eRjCJT zpbidjbSWx9^N7)0!jHS8aJzRpzP|8M^GIxh=K1fX{+a!^7}!r0_d9^W$XL#|t`Y3} zgHk`+{EIj>GRe)MwCCI(d+yd8&IC#b>+EDwZfPujvP5Ma(UMSSi{y1)YV})`t@s#&q#?bl1ZnN+oITx zcHc{_8SL2Me{k2X|9txNsa34Tg$qWFsYs)lKABxoxh^|>%G^RA#Lw}zB^Kv?{Z$XF zrKq4_m37&3^of)dPF+({yJ$M7tRM2OzJ6noCgFa4{hta3VT(8a(Aq6EzDpvYlgleB zD+~taiUZ&@8g@zoitoXYIPKxECO{v{%Fea$c1i6Z{!PDm){*iIVOF_%HGoCFdv|ZL zDVTO|!s6@*kx2ad^(%z}w>ta1l%D*Kp!Za@x4YTwmvVjg->4V-*A<0-dxBLXiSwuL zzIy+@3exrg-BPP(G9Kqm9gszgPfVs7c25^(%f)TCJfa~s2a{|M=+owhoT8^@Tl#8t zYp$xj(YZs-hKLH(o7WDjAVU|kkjCT`ebDtbt6QtGNcUspwK`QLpbBn+sgI?i?Z!h6=$eDGtE@w1PmnfP2cG;eLDX53Y9wtGG`K}%ifn0w%{eFdIV zT0lYKu7}%La8?%?9{Mo-d#PN_9evSy@$8_Q2J+@{!^u=26}=*!$+TARGytCe^iB=c zUJbwR8N3J@-4ZZ$R=i`boi$#5;CPE8pl9Ha4o=6nZDU0Bce;{9Ey+}L)8+V^qCRZv zdI!@16lK%(!ZBn*Pz-=36&G;fD^WgOPc2o$#eZ2iZ$G!jY090vASSm`#KR-_1qDqM zh0R6^3)tU&x$CK&kg1Wc)!ugdg9p`Ii4f>(Qe$dxY4uuToPR{{zB@cGX0+HG1QD(j zJn~7Xc8j(TkLs+Mbq|c1OIrSl-1a{8YND^ZfPXX8<$}U?*Vm_~kxkXp)>wT#?gAG% zyKC12^Yoo{)GI~5URZpsCTk$jRV30MDIa)ow>cl3(Pf-Ym9l^?LqzO5t&6n2@nu1zAgF8-HOMOOU(3#YRg=bVgt4{rK(J16fz>=)m z0(g@d8Mqp17@Y!kL&UB6Y2C|4u(2oH>q@Z*YW6cMch1Y@DrZ;;w2A4rm}C1911A(q z5Nkcj?FHn|=kg71wMX(e;n&MD5sjOqsuB1UyYS%+qd}U0ts-k-!LsRsrP(M}4*`}A7kZ3TCzq379 zJ6Nr4jq*FT@8t1C%_fXah8`LcnbytEK_Xh3ORGYERy1hDgaLaP`aEkgsXcVrgtPdp ztQGiDpO;Sky{q0vKbh3rwX&=YCci%#bc>U&l{%$q%pUN{(K@*@PCU%tsGVr(A9`lp z)*rO-%=fP+`dX>VE=bqVu=EU9QvY_N5C|(Y{$7n5e<7mhNRXBBn|7C~0%!OOcuZjT z`XnAsgk-!_{0YJ(iRW78x@x6Ux@!*a3M-7P-&I`fxu-cPW3Js`Z+3oM?YZ2N>meH8 zi}OMiSCi27_#(td4)aBOUSNOCqi^v*Rl;6H+*)CkOV`j$dh+$VMaSPmu3i{HYlgQq zT^lN!+_(p9j-1=Iu_$M6b10?8V)?h;uXmdL&!&z5^*0J<$ANksGIy}h=zn*BdoN^n zfMpJ1q^)$m$9j}#W#unR^5^E$blbv=28QOh4WmN}R>l*XFHSsQtS>?5p2R-Ckr3E+ z2VNcAmFjoQWm~4YEqMN8qfm-8IbD#63>b&CflLEGsD}3wRqs>7&T@N-Zk;HHc`uMP zfRO6jPJD#>*})-3m?$HyD_G$$hX$Uw(h6{sgMU=l74sIKI9|vYn7{h<`N^UK`(|z; znrd5qVTIs-+gEdMb=c3(29JtqW+&c)?mPME$MdR+UfDzwamc`L`<~a{`~3p^g}ZX; zD>{_El5CkEd%`!+B-=oxVpiK!i#GnXGeGz}dnx^S$%4hc0`K+u{x4YV@Zprw$mKu0 zybzVqW>JMcKOeq&A^)#We?}e8L++ZM>Nej8gj2YmiOo=c!FXD+?qtyFM}6%P-vzhU z*rl||0^?`VG1;*CZzUJn?~vM-YhU=tfa=$^R3MJQ!<2=|_q(ss@-uDr)S+B3^(BS= zHmil#8$6puBG-Lc`JFe7qBaMYUlblr{kGSTynQ$oRbHW?R)JZcm}jd|H~%cO@a5;@ zW-F?(cYFe_J8^RTprXNkPwnff$)7n~ufv{Ne!geVbQO3!rb4uQY*vTmiMXU<_X&2( zblgTM?j2f}n~8@+2-|$*<+T$s#;ngpj%YByo;WDgl-AvosH98K4k|mRp&?p-AzylQ z4U{jKkGde;V{zxs%=EN3sz6#w!{F5J0RARd!OjY)PwQ8s-*w>VryQ>0#sDcV4N=YMNiTjvt&H?=XfjjAKWiOGBzX^@M9)ZcdK z{!&n-q|0D@#zY`K%O3btI+O#O&%Hr1HiWGP8l=ETl@$tYP|D!F?G6<})fD`+R>(Tu z0}vfY*;a=qR*pYFEW<;jeKS^}3n=&<|s(%(yI_=<_WCK1^c zQQh6$w3;Ind0?}{<`j2oWdHjXI*#pl;APhT4h(6S24aH$bVtI!#SfB|5jg%6XybpL z_#XlNclASr*kl;%(YLL(M7rNP(i5)zGV|)@#Y?Q;TxBY&&0rM~OQXZ3tArYusi9{T z8m7h_&1xuGHJA&ziUXGb{ZOaMsJrAXR`0L=o zLyz>O^FbeP&3wmVpOSV*vE)LOu~=Aj$Dk?*3zAIS=Xgmx4jfq*CGjL+6^Hjq(qJj6 zdmsO$f^Bi+Z{+ON54-=ihRb*UWt-C3{gRCLe~17g_#c@(_)ql2>}m8asUjc+@4l%i z(U{wx0iC+%O{{ji)-I`MJ~-(ia{xI1ACzN9*{@}o^$anafYn#k9R>1YDXFKZlmd6D zj-$T7mumG-m^x|(MaxBc;nj7rqE*W8Pb8G*u~B5|z&*yi&5thIX_g)wg} zC~0WL#=z(lZo?Zvf`yflHL>aQ3IeSW=U2@#Nru2|J6IsNKvUgln1z+4FQt?-BvvyyIdJ zPM_vKQST!b37-X?JAb~sqJrEM>@nRszWdni&l{VYqG@T+ubP_JnWsuUFQZftCo}ED z^Wj9d40qv7J6E*Uus&eI&+6$wN&C0>E#!@YgBXq`J}-KzvZb>SQxRPEDsIOA%?CWn<=MD4P4KB0^>ApgHeGsblNU zkm7YYP2mhe3=ahpd*ne7(WE)Tku{48bKt}mNq=!ObQjFy#cRW%Sl&>D;c$Haddg_~ z95-1+?*buw*yu#Oabq(G=1?p~Nc`}hwIY#7S|v6JK(3Ht0WIN$%(Vj(>tYA zjvqO)FZR@_?;jM{+1rPA$?6($Ms4Xt6lh-YT%Y9;h{^oAc$=yTiZrLEx%T1GY?eVG zVA^g3L#3?-RGczO%``Kk3avXkr8i3LY*K8_XRUYgz(Xdb_pkbxoeQtxpd{Z7ybOc3 zv3lg-YmX)R3EBFnXk*6VaDY!1BGn`y`o!0P>h&~ng`V@jRp24414CFQW$peL|4)3)dB`EOK z+hfS~aHfr!oXOVhtql^8onN~T7^{Rj6Cvhv_2aD0ahS2I&4iRtlSr#R1`t)2X7{j5 z;ziLl@9N*3=D=1cITg)YMTl^#sOJ!O3GH8NJO?tEu{1*}4+lg0lTy0rO20_$Poz*N z5W%dXX8XqQbf&hpwxWCFOhF8Qy*gC8lE~y38`Kz<-HkMI=4DyKH|Yrb+E!0aC^jkp zia4L_ywrgMXM(si$d)EV%q)ZUPK@Oko>$FHXXAGycL)IYaE$JRbzW=)3YS$@US96G z6u0NZO(9hwuV=pFRoVOZ;|+eq8zzy!9IJ@dp2@`lz4AwpqWYquQ*~n!kM;dHt3&KE z?Oys}*M1p4;JLc{LpM=7mA#Z5xcUFo;`>M6O--rWS8}fS4F4}KdUc}V|C);i#wYdL z|GgMudY`q6y34vFt_BlLYSaw5;jL+?a{6tI7`vZ4b&dEauX$~58@62QBT+C z9)x&U-G zl?QivjspGKS;w&HD6D9kjzW(!kYE~}+)Ok|T@z3sg1b1YtwY8-s0vfwnpyV}wfD$`p4TCAi z>F@wa`V$#QcQDH&Su)RhpQMi6{v(^sO$Na|0!f^@^8;%1>SmCecx{f_BIp$6!ym0m`zQUMR!(uRcAFUX0=?GqfVf`36J<>liI}|{d2{m zb+ZJgX4mSF&aNCv6fOj2Hb$Hb77jGx3`-X(n;S7k^rSN|*L)i@pA~y*bY!0?I*xv7 ztl4$y5x-Rt=#IsoG}(?!&NR z*Bjm8-ga@kLM2+D3;G*tle@Fmx8n|=Jg2^l4=AcWih{dyjLT?4V#jEDm)~-A zb1-GE&D1*}w%++&fQNUM(E$O?PGg#yEek5h$oU~%sz1D)_vL2zke0P}Bg&~xJs^fx zrfuv;@HbB%8+&X`Uy>XQlb(#DQ|GFj&|7>|eQ8>@3PLc?XaPz-C22PJe#3>ap>`2) zhr7|nQ{igH=}uHi8u(i?5QgFKa?kPB$BuSkNi4SVX-Tt8Ajw*R$>+46M#)Pb! zb^Jr3N76?DcI?!kRT>61JXH~A?F+g!#>Himw(c&f@|2@G3I_|L#=P>v2~OdSCWqOz zy>5cw1H5mUuML+gbTieR2%E33>$<-xajWzGJ=(XgR@Y-E@H`@k0KVe@4))v_u%>u7 zCe$=2j^>LJXqGvKFbC%-@oZ@hpo|_gT$SN-)x5&*p1FD-C8Gn($Lf|382PPKMwzPD zcy*`niG%IIU%jd!8?Vv5nMNGkDpF0ONw7Yk8DxJ|VhHvUW%-Jj6tDI7`(eVx;fi+e zYDP4~vt8EhZ6SSL6#ToemAAWN{Jx#vi@hMoMF)^4Y^K_h?cQD4d_>QfyrdaUJ6}bI}vwmgD$5TRkGc~ zSH#EhL}$b-TwS$VH5M`7pU#CqzXM7=Ql+0I_8BcyK{elJWjC8U1d^%fC6-}1(y4x$ zph}7Qj@hRaGgTV^eDg6i6<|H(n3)sP+m8l{ybMb&qHX$96YY6-qsb)tHVHjd<#z(J zFyBp_tnnY2>{devxuHps0DLy!UX9^o?YyLIt^wlwV@tT2<*T7(}Bj z@sqD(BKx!gOs(HiT>&d&EN=`7<*@L6HHkhZ75$3D%W;k!2>=#U=L`yXde@jZ;H!`8 zf&E!Pgaj<82RP^T9!}&SgzL&V)yVLX5fU>?GQ=Xhs2A=$O-UJPIwW=E&z_{J_xX*B zGu@#O5#g5+$qxI^kAT9so|an>U5l(^-0-V0d@j*E04s6#SwVZRNO_eI#jI=dV!ctx zR|F5f4gtc zn`?*T+N+c;tpnk3Pv*lhu*I9u5owKVV-pC0+T2jIRPz{?Cwzz(CTI5-K}uKq>_PB) z!{W5F)@>UlM`^kXY)`&HV}yTn2)mye;g#zl-Ym@lc9pl%-zz1YuYSXu@l&8_>j{Yw3MNoi>lrH^`tR z%hdj8TjorT*)lewv#sAvjp0n4aB>b^)d$Dbp=miv6yB$qvarcEC;{(^WqCoUQxqp7 zANZ7NpuXnn)<{3#!b#U5Am*$9Cl3qo4p7kw|9#57F<18k#~R=GZgjoJLpQ*9<5;)0 zt-_>!GY1rNplv#jrn55Ha+kH;XwYjH7q%eC!J8Y3xAo> zDOc%)fkSvJN5ND(Am5k{R<5t}m|8DF+Dl9H72hZ`&_z^=|1qK}x`)oxEWZOn6CyC|BYl~4THQ_9aV_QJ>FLOdi z277u0@xyU>hK2-_34uUH2y}o4TORd}^M=KEnfcr%LSgk9MvdiYJ#E={vDLqXS4O}0 zyk={5P8-w`J|IscT*-KsAxazmjas1PK7bPsZ`7y}+sCgowOxvVjMvVVt-3^%qzz~E zQYP0~p=y3+!^@&M6>xcbIBskNCis>ET`|}yOjQt(yik#R#YX=LAm{0BN(ju3y5)gs z3xh!YdM8YQ3R;7BtxF+ICDJN%Aek|V;dUrC_xPz9=DRkmKcS@A5TUvk_^UG-w$SZq zFB1cu;$h5Q{V>5vn z6-`_B^B}x0UrpWCP60opbg^8rkbCo%un?75qCB98 zf(B@ow-j!AG`ilL#4K|wTFLw#2P;i8OVgG3S9p7e{q>ETrD?5;bj86NF39bL?A6t7 zTTnRT5h{<`y43)7w(*5R8b!Mm@u=*2QI%U>cWU(;n-L;wwqiFBq&CyI3CZKEx4-CO z!l;xy<|O5<;6+xZ6{T*LEUkOqhv~@qtG9Dc+R#?m&`V5`mz>3+WSA?z(Wt$Gjk}SU z2tBTMt0l~Ju5CRjJqNv^tTzyjBSQttIezFyMeA$`_qhw+Isu|&G!RZag@|7JT9{@t z_E82D#rVfS`4Qcs5-&b3n2iYzbPEXfMYJw`&A8@4UzHQGI!#{;H*1-26N})xZ!Sty z2GAJn2E9SsMb`wqRkb<1-h;{~J7%EwfQz_G+Q7!F z3@UzTq00RS@GDP85?$jD-flYY_vSK!^@NDvJ|BV3mrmbudN z)mQoCY`zVjQdPw#H%64csNog4zx7`J7z#3KkLzwH!(^?vzUS{-G5xklNp5-P8n8k^ zExL;wmuoy<7%EK=@s(VhrS}@}8$nZo3MO=Fee+FP3&q#+uy5!&`JpBs0*#TaUv#B7 zJJxfVLdmtcHg=u1StaBKkjb`YyU7SbE!vnGIX~@G-(JC-`f|l{!AoT;0cEsKLjsv= ziL_2NC5uv4AB$5Tsc=SP);@l95oRRiga&j|O3_!ap^8s`0LO7PG3y;G$wPF6sG1|a zH?J2|{cy~X5UA_|>yGdA?yf7nVi!>jUtaCJ7HHHOGj_^wuOiluw*Ynyl?7+0M3+9q z2zSTv`N<;t-?MXbZaPGZ8d6*GDQk7zbflZxL?nF=`v9^bfA99D+y*0t7@R-dl*Fri zlz_YvYGys+0d3$GkCGa;YusXN4fIruf9F-F1Fo&0wGn!oKSFNgE}ZvENOJCJm1}-g z7(4%FRR0S((`JIo@f}Epnp^<@pJEEQvAwnh@fLcUIO0NN{EFlitlMpcMwI+s~z!#+B8fbc;tbZO$94 z^X5?R#pCjP_qK{=-WRJT+mJb1=7h2|)}KTs7<#THcQ-V%%J@};Yj_4#L~h(G-XIVj zvQm2$GBffKH#W${q=};7%>K-gj5-^HX!&qr!hKuIIj903XwASu8s2pcDR6^zid!`kN%|);W&> zTc9X^3+hMvf7pBPxTf-@e;g}o#a%=?sEDY5NE47|2c@Yuhal3s z^qx?Z-a7;mIzmW7D1nfW{0_MHK6mfk6`p7B@4s(ez9byZN#@MVXJ+0r^O-YVB7cJf z=y&+0%m?FX@)APrz98Akyw)>#>OHAG{L+mE+FKy#^nbLKn9(3N@8ij+lCIFz zvhg0+yd#^y*uvLR1t?j`B32i13d>fHhg>hM*MOpy7-l`o-DHAUi(RDMUMfUqoH88D(E_BCf0o$Gx4LV{W%brgRUOA>wTen zU4^Q*>P0Nx0*kZ2qKe${)e}PzUhWg~uY_DHCx^*MPGoM}kn27B<;<{v0P~i8*80A9 zE86Hlf3}xe=(lzlO03h_Rl)~W%t>Bi;{C?QR8Vctsax}nJ7Hy!cE-7ODUbc$3cQ?@ zr~8DjEhkc{;xn;)`7+#PVCh@TaaubM=e2Bd_3UCK-m6<_-jjgL)Z~ne#A9UFV}ckr zlPcHn4)^&swi&BgJVwWo&<=AMs)Sn7ptGn%Ti8ZdQ<(bs4g>^u3?1)LweBj} z#5}TyWl&Zz|5P@a{V`W+ZS44=Ze;hS$p|e%L;qnM7s{&##DQ-%Qo??Pgn-!Z2LA4q06WUWWR&hN(9j zf)$>~RN#&<=ti=akh?&zg7;5bZhr ztJXGadYa!S**oTB%gC%*4(C}w=SbeV`l4kQ!oro~K+?4G zjQ2Hp7LHm9@XzBT@EK}Fz|@jhP*>iD zHzfJvK~4Pd60ub3NJmCv>c{t&X4=eTDr{StOXwfnPX_E1^zQWh%yf`*il@B}yi@?B z=Q(xvg!p7;b2-{V&VsZr6FuB5N1cetG>z4NWDuN5a>d5hLxI5n(ht^4fn43wmL>hF zW9l7ZGS9~tY#=x+ud>dYzYgLCYEQUI~#4o{7C2IlM*^$C!fUtD#+#;>NYH)rTbOESF zq!}MM{`}XpQu__#fKefoo4;T7F()E~6ZPSlvMuO-9Ml8JU=`j;sVYKL%q_IwVr3JY zKng8604hW|)Q+;VWwz%EHVwck7K7_bie$^?8-iR?SBT3Dh03MrL`SrID#VnWp-^0O zwV%sV5uf1!QafU5;5@K$X!6l)Kd}g{yG9u+t*ol3DsXx-8xsQ{m2!z(6lCZnT!lU* zZ8Q_7ujSd(8Z;`MnB@f0!oZkm>27^v^}obfx8N;cYb8DMtD}xf7gx71!1vX#SA2_C zHN}-#MP2UK&C(_o4|~A$$+l>u2oVF73 z>l+0KPL2j<$()am*j$|z)XDKsyA6~n0y=g46cF%ilff{$I;$0d!;B1dtyGuKYQ?YL zbi~T*(jH$U-#Q{hd1^dAGz{PHPyrzF$4BK!xFeu=&+q=|7V2C`%cJ|&NN*PUn$MvHap|(u`j=6ix z3fZ6vlXJK79P5kdevr4dx&8fpSb*|!ujz50%{DbG%zgO{_caeIdsE2rD;1$)4m}D1 z4myC!?ELKrWh*qnqn8HRV{D?RdAvRM-O18VAhKj^comk9x^06E?vOma(gv!{)HO8v z@>k${8Pce>eyWoWPa7XUew+ntpGecPzc!sIM;c}Ih^Wk;=u0rTm(@9$L7I;}&{J|* zw{mhYMu>qi*%Z1!o;~V`|28eOzjAO+ZmMfT3Mj0zq!8taJ$u)NU+#OpmN1hdUonR& zA8xvnUYIm9Y_3keb~T%OUi{8m*_?@{=}?R2X8!w^E|aR0BTkm&;#m57W`9W~eNe#6 zo&XXbQw0a;>F~EOU_l|xR?1?DP+7SZ$kY+(rxYEdR+`$Nc)~-^I6$0RU(%jZ8nWUt zKn!CKmmlUV>wh*U#=T^=$+6|mJ&VUq!vrOtc1D!|9|!c9*XM2jq@%l44OIIQo2i@R zAcz*wxId?VWb5xKTlp62Kq<4!S0c9xqm6HY;`^1W)NYKN=X7sx@w_}Yb+!FPg27gb zui695VD|i(72Xfw2DZJdwaM%_Gq8SSYr`vxd8;U$Pr-|Rd0A3C=S7v$1;&CDCWh7R zxu+<`eP++ctgw_&kT4~*q;tl-e}>sjNQLQhd;|!lD9gkT*>rQYACo`S!89 zS}w+R>#KNzfQ#&|UKz`H1^ib17O+WMhv`JdkD5L2G69N7zgPXX(&ED>fs*;^_AbHW zUw)U?|7#ce|FLqpC5ivnhxLE!O?xQPdt^*m%x0uC!Jsy;EmAl!D{G-q*WJUT#A-;y ziJvXlNG1t^K)~VDUKl_47uH*iEH~>UEe(it8=;)b$IrO&q`%yDVD`0aJU*#Ld zkpDd4kJp^NlqmXX{7X&z=XZ>J;bCE`L?UjepaGqi*{cb($+y5$0Z zSL_+9ACttYPy9*OV6>>}3ne$$Q7skDb2}0C)x6P+t}QBgF}+`~*)Hh?CgB7v&h>V0fB2&~xUZ810A?-^Y?Svv5u zD%agF&m1mxgbK&zMqk=d*k9TJVJn8UOsA;CT;;et?Iz-b-GvBP+F5}v8p?y*7hNg; zS8f^}MFKh*olw3Dw(wj?+#|+QX9xc{o6Z`t3xNygi=3KXCM6i`OH|oeC&#kvXa3O( z@TX41B$Dk$#FBr=x83lji}lzi*1)^{$ufzrccUu7u)O~$pdKqhyRb!URafbZlIL(9 zhet3+f70q(SNj(J(bNTn0qB!C|1$&nLHH{x3{cI4h?Z%fLr?*iEK{%y%Za`;N%(84 zyRD|}i(3ZqkFl{?>1J_H>DI<)y3_nB5VZQ3f$8;as{f}o`FHaV*f?1a;=)jYX&ST0 zS(R8|>*?2b#>U1~RaGJ|ksU~m3hm1h9*9FqNAV*#MnYj>V)m3ghT{b`}-6kGc4 zzGSa%u@!6O$Slz2QDTdh>uq6WbtoGFwgSKR^OLX|w3`Cm6M^&n+~2$vy^<&>$s)pj z)rtk!1Kpdh?(2Sr=Q_}Um6O9oshH!0G`TMQ(N+J4Z8J5g|LiFz-)s4_5NN&oOOGo0 zX)BWd^HAd`576qE=#aUp{-I@htF;A#Q5!E4;X1p6p#x+yZhR7iTb8|Occ(Y>%;f2x zi}SVrt1XxIx9nS1Ky(ZA6wxc^t-Ht$oDuP1N!U_{{=03{az|X_wQkF@{#+hFDB<7v ze_N0LvQ>cf+1>BcazP(krswD9^DEBIH~oju{+$fN+eTu~O1<%eo2o zK8^3zjvn#X;Jb|O-{09v_Jzt?e5MlO`h4d$EcVt zzy<&4Wc^=8G>&&0zdOVy&h1Km{vuoeL^XXaaCuFtc~?r^cow_|Ad$LK$!Hn~kQko4 z#^idv4qE~=+iop!Ivw+JGHmbKwI352|8%=T8|(bZ%WF~F8rmMaE6#{)#Wbw*RR%c6 z9||hvxI1#iwq)*&=6{{|zmoaKqpN$Lx^B%<`1+2qrMVdZHfvjct^<}}(Dio5fcv&0 z;GY<6U*q=ZgFxt>9#NNtLCA=W+Q!=L9oN*_N5C)IJ-TW&xQOG<0J^8oJZV?t-N6_N z-+l@#iVI0uSypKgSJ-y&g+@p1Edbjz{slr~Yrr?CzSwc?Y9f^5d zAM$Cn+U&}@I^fapp}YF{GeC3izq+vRrs;6FTttgCuyrI&OTuu+d-^p708bwr%JiI_ zSH~Fof=g@%zdQrl+SOB4Im?p+&i%XD`wx8a+Ek!FkkQC8A!f8iCm#I9?kErk z3o7CH7oYneZKVTRw!LhAx6_*J0h}|?O1Jg;vm8=%mrz7YUteEbEr1B?qa6Dl?`U;J z+FX?ncKSQKidfNPKaYtTS( z;1vpPDk`!p87{h7+*`ljvitnzXLj;8HulGc4-`dz`9-HuT)X;A+!;|K<%ZYk4~J?7 z+OE_s6BKeyX1LZ{MWb|G9Yy00)Y`|wHmnaF|HTR==KF(Z!1RjnvGD9exaq?`LUI7( z^8dag58$C*&5vDrz}vCI2Rjudimf9)er%oAgoP$Gv(GFkhL9~I%hjQ0Gc9$GZ6W&pU!45U>%V$7n)x>^l05HGRuq*2Cs%rH zmF%uRT~3kuk*@%#DcN6QrD7+f^&>$4PfCF!+b^vv&+l5qFzC9$1}JFpuz#oTpI`a= zUA!Yj1@94iG$=FFyj(d$+Ql8VBK=wA;)RARub10%q^5f5zTCGrMxt$eJ6!;fP|90s zZ28ioZ14714bivGdkK7R6J?~?@l;5K<)xo7b(`q)kS#*%D@V63 zDBZ;c7e5Nu%`WqL98;9|yBw{j7$aSP*+&#~vwCfnzIxMN%Kvx%DvtUe{UodwU^`s~ z3`Qa$!ct!=RiuRcr@s7A9>LwLqMmY~{DJ3Alai`xo5lO-_g}S*uKVF|f$Y7KT}%J| zHHQN~7Cew?X8L{0D8SI1r$4rl0&ndO>@#a+-d5eD2~F7Ls8K+$v9EVhhJ&4v%=INp zE3Pu>rD3T`CV2ptQ_ucf;XnMBn5^AoKzHgh@O%SCK2-so{BzbQWvI=^u&_6E`nJZtHp zBlm=ht%dZ*TZIx|c#E)1!n6Sxfkd(&dFj2FcO5%Lj z6ld_vVE}OXqZb!hmSq4o>6i9k!b+5)8>%PQ1qAq>g9H>0XXmz z3o+vdhz{6p#_Pef{MH%?j7XovUzc~>oiYmnv&c5RyoW0bQK^pDx9$c;v2S-;17PLd z(4O-LGX~tk*6ZIEV*rUi4q##K5ccgg#-Hm1An_y{K+2JbZu5$cuO?MI^U6DDMdO9w z^8cQ(NDAp4#X0`A=5jmk-?Z;fWc`SD%g1eBaTZw&Jd#px_*duie{$j<4=INI7afQ0 zeXF&o5zdFE|KWlEoo~N;I3xv)>nX-kD3o)!-N>W0F(bNg<1^cu;^dL4WwdekMp*qZs|Nr4Z$QJh01 zq9*H}@U@bgPemH+-RDbqB~O2G>*4s3%m>0o-Iuz>=Sw5_f26zs1MqJic-ts!g_l`I zLUfVL&CSiV93mP$0^~1MUt0<}BWOqMEUjXMcDz67W=ZnkFVQZniaU zJNVAV3kh4UP||Wf$bOwPDDY1W{VSdS{d6OvsmhYE%0JqQKXLL8jDgyDtRa%vovg%1 zy~4*9;NV{VV8?s^MfAyh(VmM<+e;sq$f+{YTmWF_p?u?pAa1q!?nj4q!FM3wRjaxw z;Pf-4wf#}T1BAX6ef?ARe}ooCK5qLkAagG2-MFrsT~U_Sduu0j@H+E{`nvFUECUk+ zSIC>O3GIKvp+6p~#cmle{ATuv$kx9LgS1bW95el z?>ygf!@)i?uKXSEy3Ge3|2%#JlrtpKo&)e_?8xHf<>gt2t;_ z;co*WgYJ?gWdRKr72X}f?T3b3CPs7ty;r%5feUzdbAgvhE8rlS4EA*g{B6D(&Wvlq zm@VXX0cvmGHv$NKEFxdBRQcfEZm{U%rpWPSQb^UoB=)~&a9OT{4V2zx%b?{;AUkvP z>>W{&=i3kunEnbtyyZyyY?PHsS9mv(Evn!7ji60I6=`D`QS*dShySfV;1ggrpix zm}3gy$2g8FoDBxXqPDiS=H&^CwD0}7IX=57avt^i!yd7fcIoHTueZ=w>tEkY0I-pi zp4PR-_V)IcmKfI~tfnu19_I&}ure}yayxSToQjK!OMb)$_msOllRNpW-;o$V>i-Uj zi2)9`$>8RE6kC9Q!S$b;d+i5+vF9;=v<9^f`3|I{Lv7CNlCGBo?zzF@xP>=KEXd*p zG=rJUX;xF;pYtKFQ)DZ~G0NRDSO0gN#CC)eE~p#6pwTM5oqGV_d)uO`h^pTXL{x9B zzsk;`p}943&s_2&lMegRgl!_rfs7l=37fFDtR^vr((SML@aK&6Rzl=i zdj6>CZ@ap`8S8o=vWQp^KRqfL*rSdRtl9ITEoR1UyLkwR8b*E_$rrDw()-cl^z#VL zJQ*-r^78USnUMp#0(8sgwwN0Rn5L|(tSOr{sgB*zeCzIyR0Qtu2d}@a%3@lYnlnV* zY-F+ilPA&TyCU52gZ(9d&yGOu%?p99is)YtO!GS>cz<-4;7OGqNWZpC&(_@>`@6YJ z0ZF`Lg&MFB@89qC*o|u53=t*>AN`a!RvC|#Yk=Hdb(NXhRZ`_lQ{?)WtuPchy{E_V z?}l|B%qr9Xm6qBu2AyIZdVRt@z4XvC;Hd_Z9CAS34e(3A3&383gM&c-V}3yav*44h zl)&vBjA7!}HzvxJhtBLX`<^^O=dK5Q3NXq3tM1K&&c;T?CC!f^J7TR!xB9R9%zy-) zB)_yY`F{b=!lI(wP`Y*oJHoOw5n$6!JCJCV#tTXc?Z}_UfL+~Z8YgLQ*ezHo+qsjY z{s$KQR*WS`&|B%*?tVPw$G1z$lK3=3hSjZ4*6b zez{~xhG%mZ*y!v<)((JRF|h`qU>0n$n-Wcyzo`)rG9`H$CJFytl)}S#4#MBD|B>Y` zSUaP;<@Ma|p_@ftoE+XoWzQ}0zf_t5(ENO!bwy#J6V+FGnO4%3-mke2o^GCDVuN%z4=vWm{`o{LMd@Oe)|fuSQc3nXY1<=EcH*P?Z; zz}sB~55E)kSM`qC`^3F;tp=*!hNDONN86xXM!EZ+hm@pQjAkUHR9V*%jD!wccVChW z!(=EgSv)+{NZ_Ad7J3O7n=J2#x?{5LZFynzyd)=|l zAYd{U*0q00ZPeNF4Q*vS;T76@VMxxBl!_}Czw%`k?d`taJ8&H3Cr>ErcwE0mBYShO zhz)6>h$P*;#B|@Ufmn|z1tG%3K;xwfQlM^S8yaozI>-W+X;-j8EYFufqOX= zPHudMr#Mq@n-2Z$5#zQG!*8k7xvYm#BM>UzSkon)hip>AS5FwT_>kH|)eQ=A-0#4wbv69&FHA1p(PP9i-o9E;vkTty_}^S4NC1zKJP- zd0Wk5CUXy~xqPPoc2L)wQWx*6>bj~^&jOCfIywa>EIl1z3Dqdfm+8>nXDa`Yc0>&p zXLjAhX>1kN7{D#iEF~jj<W0m?Ll_W=*|nZY&d&!rg=X>m4p% zZZ2~0yWGB7DfLuP(7v@g_n<-mA>OO^18t&Df;zP7U7n9m&3;A5%2yll!c6CFJrks0 zPlacjiX~p#LblkEf|tFzf=n&Od&=gof)q=b@?H>)zvzJ_ z%fm(o>gg`~r`oOZ$rW2IYRS7VHJahVBq&4Pxrd3Hm7*c*H&8EIgoq7>)N1-8UYj6O zL@m4gEF^}~l0)m|vnkEN`yv+Jsd#8c%>vmi+*jq&O!Ee{C%#48{gXllMa_o+MT|DX zzo@U*cJ)CYYBQ82j1yDpa~5N13LdqNv36hs^Xhp^w)gCl7t394S%0#$tt;`Ub0IWG z4?(`Jk<^Xztu5M@m%pjb4zSLh&w1ID}-Mtk0)4BU?}qm-Cg=&vZ2J|lO_l`nTe*V(%N?i zy`5z&{MRajFdW4>0Nv$hjBB zrb8x@gN~lAVse!3j`)T4!||pYR{oHo=?Lu_5NBa7d_`pTIy!I7D~vhlIEVRMDXx1j zUrP@UETioh;QqO6z50BdrRdp+PC87OtB+U2ab~Pb5n2N|1~AJ8pYkU}ye;QjcZcRo zOD&;}mLi|ycpeW!}CmTnx$*kdr;wUGfh&qb7uD2u!soDH^?>IAX0es0H!H@}IMeU@4&gP60nvGVNGE5Nln%6Q~`h|@LlMb_GbE59+luv^A$*3^^=C)Vt% zh*^@zy3{t06A7PYcxPt>m#>4t#iIfAJjp%r zBj-mPW_ZZU4sBzdQ@IZWT0|z%cisI^j_s_0>}r}o$DDZP;RQu+%O2FsAxna)S8_~j zwRm49|NCVJtTvwN!zma%t*#o>MTILmf0E41esxIflniOkm<$_BN+3)X)I6ve2If-> zPX;+}E@^eimzi(ma^Flwj=XWDYSGZmcX|;vYqEI+&>5 zE;H_!<6S+Ko00QGT1m)pwrP6Yzvo@AJG+Dv^hY-|W1peAJ3;%ZkE(o~=J$U}uv?&>@ z#2^`1nTBs$Y`EOs0p-#BDDIh5R+5%sq@!7)@tqr5V0*#F-?TQdKZ5cHoKxH)37qn zmj%^yY)y=ul7k}}TFx5POPU)UW5UStSjEX1br0Fw_q8CT^ zWSTjzW=xmauBvUE21A8#HkZ?jqS>P9Ct!qXbs}aXo4%~5(=`+^x zlCJb7tCeTHUvDiU>G6gl^4ty0(128vaXfeK!~T~5o;Eh%4FRA+=u zMiseRA&k!kM+(D6URG*@FhecTJPGi@dB6lm2#2HRZ9Es!Z-gSsb6lM5wR+NRZ&va4 ziNAnX1z}mmNST;^t=#XUoH=X=<3{e%;_}K~cNZG!)d5pf4Ufo4Ld5Kl$#b`pGYR8~ zf(rZ+Bfyh|wRDGHR_Twv0^+i~?8X=MKE;YPtIinB2rjR3{@j#ek^YfIJFP5W49!Ng z-7QBuGv`mIF?MOC)wU$1!xVa+1H77PMe-Jxe)GN?RN&Cf4}q&)fxjZJleU#RD5@Z&QAVsb?4Ben5<$BtD!4Apo@Mmeh1Q5&0`#Yr`z zL1M?JbM#7VpvIGPQlwt34RwW0ub$Du&AAtm>SfPHGhS*jD9g$ozwP6rY!i&`sktMn zy{IQyRT;rY8@^}yO8*QPIi7+&##wisw&CctX}5uiOcxqYxG1!IQLQB(JNSJ)IXFD5 z!f;cTR)}H&-^|4gdO7vFDxH^)lif@%Qil&qHEejh_u4WPU4R2(w8eU zw>>~|E?;lkUb@&?5`OpKaTv88xA6SpDR*#3VBISMAyh1gT%JP%gw*!{op+q*>CrNn4eNhR#@9ZvO@q^mzY+J8m~L zBi_9szuHVZkDEJoTw?|qen`!rg8`{>ZiM~l9Tk~=r0ioGq)B0>U}1TsWGcU&!HGk~ zuP0_!=&rFHab7$AEuiVrFH^^haCoi&_8wGsUPiIlT3_Q-5Lj94YVRm_AUpqWT=U!u z#~LPGBsmJKa}lM6q@`(o{N^Mfh+Qt$k~`q8Pq~Nh#CfiHY|u%PU`H9u;xj0tU`tGg zoSlvVC@~=ir)_PYGn*z{&tiLH>*`#6xWndp&F1J(%hC}b-tw6^FUMi!bBwPUW@L^d_ic4DAvxdz2+c#@ab|YVJ)leHPkV`WM4jWom zRQOEV_w;o?DU%NsFjgw7L-EUz%MxDn-!TLYj z($lxDM&$ZOO?Djjf1NdH(&nqlDr!gMQI;qUJkAi4*(}s#<6(Wy#-DJxBCC;~YB8Y!%F$zb#FVzf@Fcc`z~8>Knu-kM9+#hKX#71}M}DTT-M;79R{6Xner1O0E{Yi_@A4a`Fuz=uRTk zq}%p_$BCmzNMURlu2I)%^FS7BB&bq~RF>Cy9ir<9LHf~a4rFIGdI(CAoF&`T945w5 zPmMJ0ys`Fug50=du{ZOQLtPE3%e-BSiNS1->gv?hx$r}V!CjHql7J}JeE;Jv z9A^4O2^Tt~r$=x67P)j^0=O+__Di+d^utfczSw!fk;D{Oo}n;G?6)iRVLdG;Lpu(l zLf#+o*rRID<|MS-#PII6Ktr*=TSt-WXfD@xK~PvkpT~`OuceKG<^h|mcC3ZDxh3lr zszy%^A+}_XE9moPZb<_!Eyur-5DFU~aMmR>g}LnwK%r?N;G~W@VFBL znU*C$-00c&kdgB{YkPU}$h_w@LT>DFL|->6d4*5T`PI-`_j7&tOiFX?BsuVCJ@BkP zmLMXh=d-cEAX*bW(xqtG^8EEj>q6<}(16)wQ=I@`bH>9kSli~IeNIED#sh`sa630BzR3`Mm;CBh8B=m# z17M==RIk7$OC8_(db}F1T$&I7D{GGV08?2TqloUa_d2>*z-MnkfAxl;!L4Rmy52U< z*dksXE^y_Y%z?g>zE1#4RL>$U^dJ_)>K$W-Ss4DD@D#zM4Vx9NpL~qkn9DfJc$lcm zn_R{PD)tOzHL z9Ux~f5xj|R{LR=0S55{ntP*uvaxeV?S@U(T04HmOMdMJc3qn_Wv~cN(sq$r2v*B6q zxMjqQVn^=Dp3PhB7N33E1jEG+d5{<#jxgUSXM?%V${+!xR-OtS0P0% zF5MKSo*I>o=^)O|+zrH`(cN9#Ep08b13L9!vUS}-^Xdid_6&K%EZlp&9!gsbAmiW( zMzuDOt`}&odB3C1TsRm7bp-VigQJiMzLdJz9Nq9S%&FF!g|yX@+Hmoc6zoUH6E+E| z3ESi*twTE3;2M?rgdEZ2!f&jUBt7uA7iq7yP-8TkslM^DW(oFlB=ZRagk3l4fZQTJqkQ>6A&W4#>F; z`v;oT={Nn=?9j)`#lEvBa+u>NLB`qhsGGqEy8&WsuNlH@AMh1~nQ0VFb%vH~_?&7S)u9SLIm+Q(H z6@JVal;i(RdEKlhuyfFCy}GOU7zp*4X`bN?k1$x-^ShZ6En^h|b*B;aC-EmZ@g8~U zi8gf+_^ZPF-2mPuf64PR{Q{er)07=XciCnyLO5gx^xO)e-i}Q^0if*ntfEez>=i)0 zmrI{tBGlB8k$c&38}j`+npq`o5FiJ!^d=nd7AW0bsbeV9%jB=YH0yrwU}80_5nQDrO+5ZJF`;QT zw$!aCJ=v&EA2RSYOPfaJ%spN&NJ~$ZA%)3V6cuJaDIw%)GQ6ofe~LZYtHvb<>~pP_ z^7W7%ZAE02^7Qgl%Ug4QmpGa+*Ve++_(ts?AB+<674Qa<7xoIbAYvB4s&IrBi5hS6 zBs@@}ZLC5zHC)Xu7`972E2ac;;*J0VtLpD~5I2#x7^xiGQoW0d2?gFV)LJk@)fFmD z0T?7rY>Nx!_I8?uG@#9eHoA${LIE_yfY(NDZU9==A?+FR%s%F=Pr%R$@Kq%;9vgTu zxkXF^jl<-C4SVu(&vD|3mRCO2nI2JiI{XyqWL`{GxLchw_riQ@8o5m{=uCLIId>0MIIE3As9 zTlv9w)nU_)OWBRw7Nae|BVp;DJ{vo1_8nN+bP)oDN+D4lInm@;I>{0#} z^=yU$R|a~ae=o#r?Lph2So9`r;lR^`MOPU=W+8*ZxAAUtk_ZSIx&}OXo!}}nbOb0c zonS$~KXGw>RQomJ23@F~Nn{xW{421TgGV`jPwU8Mpb1FGpml3oVG_Ms)3A|HjXvKi zHC~THICqIt_lUoJ`66(9Bzl4OZSu6vOQ4tp#8({8Hja+HwCe_Fn>#nMi3qLQU$U-5 z9b^#|5eZp%Q##Sg6gaoCzajo)hZ%~^``VmSw<4n8_7fPZo(Sqaa8IY99}UQ5egh-S z)H?chk0kj?h^;Kdd%!QKt*M+YNd{mG&``Tz2W16LZMBmz@;^iy-^ZL=*0IU7N0Bks z0QmFsp{)(CirllD4A3v9!S7^yUhNq>`umkz`}hP-mdP!T-6hk5^0ZDZ$IH{*|8bq; zxRMcF^~*6GBRFXmr58`KRT8;u5FNZQ4Sd>3XR`o`D_FgK6x z+*4kUJ#>#AG$5cG?buiEf>@E{)#xe!Ch*(RCZd7oSe51Ei9(DG>^p8TWX-M5j7ng! zY@$(bEa8MPgv`gyB590t3h9avrH2m`Ii7z%w_?&|dANrjT~?j?>cCiNSief9Onu}4 z83kQr<_oRjpqqQuvo(S50}G(?4;lr~>ti{x$AY}^3EpMNS9<(G7dJC~ZAgj3WL#O! zmwA4MQAhomC~zjO)VRrU4UK?!o|ko5D6>V;j^M39dZJ#0rQ{O%^{NJT7wph#XZ@0L zXxYq*lm>}YY@s?{$bCT)Vlq_MTXmBRBadL_{`NT)vk5->$BtFF$a;aW^ttP`P{_v! z6t#L^iAouY?MP=dgBuk$qfYxS_qg=CrNm{Rv$7Tl0)i3=kkBegx^(|-^6hQ_qC27O zFewXavaGDYwF^P9T{rkTJZ1uGs#eupDjgTmxE$~CR;JE3$;nZi2q`Dxdo$5~`$ZMU zx%W50{uiAN(y%ybjNInxY;3Nlaa)u`?}brUG-nsyGac71je(;|r(hm7_9D3?47s0! z93P*PNnWW!*!9!$+?Kj#9t?!8p~yWsQl2xB5psIv-)V61<(W*`7@H>x>uofO|G*O? zLwq#CmWBOV@WQt}ipD>5?#MS?JGxT4X^^Mq05+Arv4IW0Ib5?;3%O<>ZQ{@BQBcO? zGMB?`4xBF}gV)U>QXinVPbLPtn^PgV69sx!(k-A@Xvpo|gzZV$K1y zV{G8=xkG{S7hzqMfai=e;R{%iR!W+Vs^Oi?b_FI&E^Ez*ugN%cgf&Dnh(PO)l0>~` zyKCr9N&b&`c04Ix{74{x`Z`W5NFY-#`pR+4cQO$K|PKd!yEy^Zs^7?8wvoC4gUe<)pR zX9XVau{70WwEb*7I=V`b)y=n3zXdf+5?u4QANommQP7cK%%HcC*D`_dZeU?#cPBvv z(d?|A(gg6S%`SNZ&u`;k6=}8h0en+dZIJh>txYQztCaaEkP*sjI*Jb_MX4AZB4ew| zD{RC%Wb!MdMM%NirMLp`JS!Sc#Y;w9o>C6=gY!z!n6z-HkxLUFZKg#FB(_8jH6cuB zqp5uHu5jdjn~KbG@;h$I4CEdN<*!0H^2F+(f!C5kMMbuGvs$syH|zMS@=bdAYn1k= zn1yOSdG=R5-=wSNT0;=B-#sOhvZg87dDdA zX?GCN)DkkoJML={3n6OMHfBEq_x17Fpl|-d{rN%O1W_fToXo1xl>|yz2g^m{=mGu3 zI93^(`fU>Bs8b9ElDG}az~AGWi$(&&t7E!k+CYU#`dWT2a~}m~KvhFOCO zVcm_iAYV7Co7KFEH|ko3`Hqs6lgK1Km?WwFsOddTmnH?deAh8?Y??{27rJldYhnkt zUlc%v-EvyUq^I@(UmEoKIBX z_8Ql&O)_l(4YGpeVkqSvlH+QgGs3@56-fGAlBmG703xMGbgrp)gTq7h+ z>`ZNYZawTMuZ@v24lusVMxMS-UMEDsCUTkdjSt4a#W%=qGG7cTUGs$Nwcm(?sD4a* zY6gX+c;;h5Qv;)(4zs{b795s$SZ*5#GdRiq-AmeIh!7|5I;73a)aOZrA(taAbGaGM zGPrQI<-n^6rQ0lBBy+U~)ms=ROmC^;f?IYLlsXmsTj zA58vKp4^vwqPm1ZUaNa5nPln$@8s0UUuqZ96rxrY33$&<1P{1SpAOK_s7-ot=UI<^ zG&9x4cjwN8SY5wqn;%;E^@zY(CjG(GGD~8(TxQp^VjzxZ}5>NI#8(sP+whcmJ}-+yD2w71zNy>s@()Pq z-!9#&Uc(4Ev^Pn`<4J@)aB{v$iS(4D)pOzI27Ml)_iT)aw4OVbm$SH@L3hTnkN8R>o49LbnC zcJbuk3e07Q zcF}X<=2J@!Z|+`To4w4%QQpfPf6ZC!`+VUYrAzOveTQX3LrpnSR0&fs+IonK!kxnO zF7-zqlf`>Ojfd3*t<$BkU2K`kZmfoE&at8;#e5Cc8E&Qaqwkv9m5zxXYn1xHUa^rDvbz?TalM9VSzL zITUiuRF<5dcs5kR_x(NRj&(GrJNzdl!;w(`aTWqv#~@~iUtLW6I4-TcyM z-(4sq5m7pPP8zZvhkEGT6qqr;I38qmGeKEq_z9%3{-h1sS}!v{`jyZ7{47-cTA;x* z=jjT5<;x9uuUFoDv^ZRJ(_2D;wSefUeaX*70!|M0?fQtn+@glZnkdGqLhbaGr{%S5MofDjcft8mKRzB+Q=eAfK&e;!N8(X=s>nGu-aKt9i2+XM zCH?{HTyfT{fE@M~6IKakdfj<6>x9-R8?=62zgyb$?U-RF-ph4ttE#)NF5hPkiIJ~x#*8d~Oy)g%_*%LC`B1s4o=L6j{@^wl0savR3(|lFiwk8d z#=3tVd>El;K0!>1z9~qmsPoVGV&Tp>@6o3bbPtI^=c)IXzYp>3OUC)P0c{jL++x?F zC>g_?#x)!L-?N?W1MC1blvI*UKp*-vu-ReX_`FX3V>9!qvO$TOT=O?Xov`}_XDylV z%4a@fwBo>f&|fLWOAf2vhxCOJ9Jw#M^p8jj;``(6maH_r?l`Z`jF;b)Z(u-jP}6VS z$aJ#EFCn{~Wh)+{91MJWL1w=2xZ~Gl)e3|*ud$h29lAcqX>}$7g;GB0vI*~exQokc@8&5c4;-@2uHu66nL<)iuYd%L9y;|JJ0Eyw%Ax7~?n$en@f%X+ zKsemsTHbJ)puRFe;5xeU)(I}SQ_aYr;p|sHk188bLvh9zE(>*~9lNBH8+is+8z`sn z;ce-&OeM446c7t+P;h>z?Oyo429I*-dl9x7-DWH9VThoFhlk15SD6)V--r>{&eFTLeZ40ied3j4~i zwwk8@l(tyW;8LK$DN-P~6$nl#T8g_xet;O< z<;H&K0^T&?+AEIMPOTq7jg08CoF1me{pAysK4p4PgI^HJ7^HFRdx{i=8vQ ze=KuI8Y+0(wluUG^ku>%v%ALYY^T=o&eZgLE7+AAm(h)Ot5?M3{#jJ0-d?k-!SX57 z?Ur0NIy`^Ai*R_T!K??CgKpONpdTUjo9L|WqI9<8trh3IV*UtDOTQyZtT2}|;oG81 z@RO(io536)qX^PuF?~d9lD%rMM7xgxp^vw`2 zq8kPII$smQOsPb)k;i72Lm zVmc%=QyiBN=onm~YP=jxpSP-5Y1%e(Yk8#fjqYufjB(1ZK_he;9Bv%w4XRRi>wW~0 zg!EFlq}!RyZrA6Z)miZ!hr6l>IR84E@)$c#X-lTcYxQ!yMQl=s_vAFTA&agT2`N?3 z#5*#%q6);H`?SSWxIR;vNK%QpcIgYsjWC!cI8dkIfEn5_(yOHIAz{{%z5a0)_}9`w z(VWCKYqC{Bu}}7*uk=VL{3zqTy4Z&Ob%|7^{X|w}yUqhy8-P;pRCWGvx z;PRkNma~t3`9}6bIlP_nxVwMGP0#svmlW7ZxRPn0++Rm&#z}48gDi7fRo$|oD>#x# z;~DAYM!f`;l%r+&N}9bBuVquye@^w6?$6hKS5AAu1TvK`;kV9(FrXgHiW8gJw8eYd zi3z_<=ydq3ppB3f(bGffh~>OPFs%^g@19Yx6K3~u#pCIT2^9G^_gFH|+wv)Omaxy& z75C9GiYqdx3~dX*iA)2Zr5f*JHw4MYR$YH@G~P#*3aFzn*+hdaNP`N4S`)(N~U&Q-?cRP!-SfWL>+!XfSEi;h1t`I-=NoZ-h zo(t~Gsi1*Vgqd7N7JXco4FLtfV~DN=(2geQ^(df=UM9!)xQ7A>B&7Y})aC5tYMv_f zM!T%_d}yNWE4uHbX-tDRPxtlX=Wkvr-;DZl-H7(`%>3jqb^Ew4F0IL;LKfWz|0~nOnn-j)hO4$|Vt=Z>IQQVFA*i+AA>AW?-Sx0+Cg~nS zCfG!8ba~+=L;5_0;1qPmbgK3u0XrnDQTQ$RImZUhh-09@x!T!(J5LRkN&*BYUFuo!`DM00#8oQWGeo}}mPtrKT*byjeYg)ZGsJ0y zT%7C+gf4$a%seFD&%;9=_H=Kex3d!_v>V4Ea!aNfhYX=3aL`e&Dsu7cSc|IFU`tDbHbPu%E82tOjaZ-!fsA(}^o?9GP{V zsPIO<%sVPrl%R}Uu&KU4R*}4X*J-76w4};Hj6ygYRs*yH8RB|n<>ZK-KLxN$%5woK zoXmOPs`ZR(x1ixbcH*!NE43TuMryAX(`=&qgX?{-y3Bx zHix3FLNfRXem?v>!prDfzjb$3`*;9&T*1KGfd-$_-uiFiVZs0bST!|8;Ale78>n|5X+L zu1D;c|9u|SGM4=QU!*Wp^BLMx>i};$^(2Ss_!K62S8Bk~cX`BoO|B+~qANM-hG^=?u+H$NvcFJb9$I8+PAc^p82O8}LD1&0#Chc00G{H@DRubpxKlR;eDP0VW0Zxk)h;~j z1Da^Ny4zPrzHLUFm)cdS0t744cqhlSt~Qt>*lhJGNSt~U-j!W$R`$>S(n40HYH;dD z85r!zP89MRXh3epa-A*4(kv>bA2*}H(r{Hkn{R)ItkC5wvSWujrIAK5> zf;!{m=L&{_l6v<1ouK?O-91FlC((>GzwQ@mr7TL=t^=R<-L+f7-49ELA~sVg>QD)q z3!*gzlzjygXPwt?(cg#Lb)Ep`Ydk=cokk>EhRQ=>RzS)=itAGH*6 z%+PrPwBg?e_j<-2eVJG#bvzHL8lh%X%KVwmuaxAX99@(moQvGHh~Q!TWYVWu?XXK% z+#B!e!K%^W<=q^k>Fe20_HfA>np4nR1x{H;Gvum_{HpHOT_slw_j!Xm>vJngNRQ-L zY%na0Kl=Qk=dC-=Vo?(&gQCzC8d1IDRlr%6z^L_D1GCbQh8G|9SguHvk4uNAWyhc* zE>dC5naOipDmu-l+*tvaS+BK#JEOh;XY4u2Jh2h#t~&D)LSRrEkSZZx z#Z_Bau_6c&X95|`f?F1oR!W@Lq&d3i6$N2D*vj2m_Cg(=AD)vU0Qnis?)TIzrEC^L zu`G;h2fLe9F4c_6?GrQhbthgLsMqpvF&;n-qemfL5ev62O>}yBg+z!da@U1-9hg{M z%MaFT)0@KZ8@PloL8Fv%(n*K!ikWF= zPY?sC_ABPpV70oEL>$M7wNCYm z?tSOu<7?=wwEw4Vpe*}fW%D^BNTj;$V%^2znS zU%3M_IhsY%3)Hk{GaJn&rt9m0sKs8Mrcj8!_IR0l$AO4Q5a`j?J=e2_eIl5it#>8s>11jQ868Q z{&>=(#B2ZOxOe&+-N}E>W?D5K3$!6B z3ULH{PM|o*>Dk7DIn=b&n}=HG!b~pHS*@i;;p@@^S!6xJbbI^7USqaD zR?gv0b}gI0mpD`FzD`!mHmOKpDo-2J53y+8z?YzjPZF=@?U_9?NfQ{=)Ub^fxppWG zv?zS=xTBSZ=kl%Z*7|1PC^Go?yWBC0%eGW@TSxo5Y+~2EjuD`zzx&D0&8!7|$?vw! z%Qu5kL^^mr56FqTS3gbQ+r`D!>(L(gkX%KvYKHk9OM0$U{MDS(*Dftx!@BNar(?XB zSL{@_H%Dev8mcGCtbG3OH>2$fSYQ6G(e*IZnV5E8i;sBwvS3cPs6LIdKRqUttDdlO z&Hlb(faFEi*lSp?n&OkeL(kWL53_-*$(t2Tj-MR{=phjG)uLGE!8u}s+qQZNtxPqE znQ5C0T?LbBY^B=lwEc4i*7Dm|YRKRYH`;;e$Jg6pyFlQGSeUFF7at0M`L1t|W~lLl z_siI3S&^{bA&bkmZHp|WED`AicIiz&`fd9zG_myFV!TP2w3$uqm0-s)G^$;DMG=DI zKdR@LmbMCiY%rdVZ6Iuh%OrQk9qhmWhq~qvR9e`Al-Gkt&xnFW-gxj5o@7XSpw>c=LYu?%&%nt)H8u7V_xMQ!8hl9Wqmn95GV1U#{C8P zNc^ZHWj2w9a7;2MJakjy6TC*D+91M6A+B?atx0=!b*r5O;O>}tyQSk)i+{(O)dd+t zbbr5^vwIeRL*16AcbWu77&Ezyxdnni^sR>uqEsVkUD2_Lfgx!1HZ!FXG~}R_c`^()L(dBhIcG~lJbVfZ!AC{kgOhk+(YlC9`@sp1&Z$W`Hj;1>D9E& z(vZ#_Hg`>PSO2-ht#)Iq6r*KMp+0Z?BB!Bs=cm~&$VhYpPVHCJhu>m5JHvWku}N3X zj82O+L7p4^qjvbTdsX>4<5)}1L_QTf>9+sBoEEBTQ0s?gKwG!{dS@y+;B9z~{MFya>y#PeTYHY23Q`(#`3Wjhb4rK&w&) zR?sYI_~a26;P}->9mbl_4ERxuyutNYBB<**4SrZK`u+K(q&w}PyuvN&uNhQ{KX?{tay0hvVZU#P{aB;Zc>Vl^ z!p4QsV6}_pOjIN()(^B2PCZUK$)eWw=-vfRaQf63${GFahhUgG4~IZ^2r|W+#qkXj zg5Y?LoPN?m@yVx}y;SAii#+akW#eoz5VTyBUR~>bx0n=4!Jlv$ljHw`0EHhLNcv2+ zT*ckfaxL5f3wN`1*)x{(-J}EOfKkginTT!1(5nLR$AGzX!EAHyvl-Wq>aOA{;dB5P z%-X(vF0%IieRayDz zP-1=rf1MRaiCdY6+p5!cd+5XbRddW`v;gta28|>$X@y(EGd8G%g^=^@#H&N@@{YkI zOT^O-jg0Il+ziLswLNyatZ((@9R?L=S7c}o(12A3fiFEA`Y^<+gWFvFUw`T*&~M0x z(@rV^5)i#21iH766;Sasum70g&Kk{V_^ht$W|QqK2`!y&&`2=O*X-i8_-fGC}9x%l<=XGBE?U>{YRb9M`~1qIoD|I4Pir^T zI=LpSFEFWu$*1LAw6!N>BO}ut+z3rc!)g)}s4O3POu0k@(f^R~16X^k`N2WsX0X)f=cQzaJLnVg5BVAF#!gTM)h##h5I1ax7xnY06O|_vIgr4q ze@bqe(gKoUux|+=roNZI8q6MUy37Qa))Gq2jkdlhkx&|A!G@Y24u6p9fc^hOoJiq@oaXv0hTn z>bQJl+FGWO4}AVtftiCtPU}-F1a^_l*(P9u>vTtU^pfr$*=)$+DUsYh24bo{ck3*- zC|}9Qrbo}r7P!s~aek5Awisc%6(=r+YkxP+RR@6<$grL|&K0g~&v>*gR)QV$#ip3> zz)0`w8L_Z07RUO`sGk0k6Eo|lz0G&)VyJ5KL(UB?LX8YG-`4Kx5OsVmi8G(t3K_M<%J)eCdY>VPzBmX8ZR0x?wk4QRgc-x5YmQf?o^R8bpuyFr! zz3jBh_AUH1QO)~#+6#=12u`yjX{$x=tG)ih)Vrw^0rXv+mCKi#cz1{fh#WT;%fICY z*i8`(RBJLfJkB+UFxV$;3_t%XMBeYqtYStnk1XP|Q<^dn@TL+bbYDkqI4H;sKWlhc zDe7?WYzHz?@xhToc25PEdE9n8!_5FsedPz&^BK2#udEsnB1nk&L@Lt>m2nh?_XI#1 zXg66VlRf<2-Vho10_Bmto!3HzOT7o1N*?Sk-jAygKa=tGRf|t2!xG~cxWO2UJASaMDxwfZV8DFr1w-%jrtiOY=r zurFwUSiF0)P(evgOu#|kZ5%r4**Ovh+`qFbz~k5A;@^w^Pz9YTDoFBQ`ae8!ufp&E zG#(>z58F}N#V+dd5b2DzyX!z?Xbl(m_G8KjRU`r7(^-5`-|xQqYJYzHOhUv%i0%Cy zA5gadpYsD4+NQUIbFLmvyNkyqNC}@JX}$K_S$hOgGW-v*Q=bNeJV88+7eC0OQr&87 zG{$FJW0Ty)lBGt7hwFRNXTg~puWtl%8EstaSuOaLwx|54Lsy5HRxYOrn3vBTBXS!CGWP+Xwr zv&a33i;}>q%h-9&Oi6or%WHIxJkbD>^8ncKsz)Qvhco1n^{M#4VO6^bdVjORC;#R9 z;vc>=)RfpjLW_jEdLCOLH@{Sfdf`f#wuJ59x;=6j&<&+9Vr-eA^|Z@h(OfKAY%*AQ zRDjsUl2fTZ+Lxci7X=9kWttbhYgS_aKfWe7*7E4ALbG@@w{q9>trvq|iG00xpmJNc zg-8t03^V@y`I6G2_;}(L;E{1-)h~oWT9;G#ZQt-du`N@odCwk%Dbl4qV@}bQ}@Y0-=Feb~@Oyy`c z5b-$U&S*RPt$4Cje5}S*(8}%RW)Be+AAlVVCC%(RpQGVEbyh-~3?C_xqpK?d)GYmn z+NFLGP)8d}l>32RB5q_mkYO-upCxFMk-gZ6`t{DC#2pD?lnAAfgp;37>Vinc!BR1^ z3PH@p$>SRdxj;-n>m>E|`dH>;xdo5frVGj{74_gyI96o9nMU@KYpo|)HF+si9x3(t5zwy$j zedF*O1OtE{{+^vQq6_%%p#aK5e#?-Y!6+OQ%ox`TeE#c~t`{yOB6jZYu=fCO-p5Ai aVm{Cg#uTmH>f3t%WuzdZ0x6R+{`5cZ=`A1t literal 0 HcmV?d00001 diff --git a/changelog.md b/changelog.md index df768f3..d50c481 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2025-12-30 - 3.13.1 - fix(webcontainer) +prevent double initialization and race conditions when booting WebContainer and loading editor workspace/file tree + +- Add loadTreeStarted flag in dees-editor-filetree to avoid double-loading the file tree and reset it on refresh or on error to allow retries. +- Add initializationStarted flag in dees-editor-workspace to prevent duplicate workspace initialization and reset it on initialization failure to allow retry. +- Make WebContainerEnvironment use a shared singleton container and a bootPromise so only one WebContainer boot runs per page; instances wait for an ongoing boot instead of booting again. +- Reset bootPromise/sharedContainer on boot failure and clear them on teardown so subsequent attempts can retry cleanly. + ## 2025-12-30 - 3.13.0 - feat(editor/runtime) Replace bare editor with Monaco-based editor and add runtime + workspace/filetree integration diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 1678fd2..ac4f29d 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-catalog', - version: '3.13.0', + version: '3.13.1', description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' } diff --git a/ts_web/elements/00group-editor/dees-editor-filetree/dees-editor-filetree.ts b/ts_web/elements/00group-editor/dees-editor-filetree/dees-editor-filetree.ts index 9980685..714a8fa 100644 --- a/ts_web/elements/00group-editor/dees-editor-filetree/dees-editor-filetree.ts +++ b/ts_web/elements/00group-editor/dees-editor-filetree/dees-editor-filetree.ts @@ -55,6 +55,7 @@ export class DeesEditorFiletree extends DeesElement { accessor errorMessage: string = ''; private expandedPaths: Set = new Set(); + private loadTreeStarted: boolean = false; public static styles = [ themeDefaultStyles, @@ -484,6 +485,10 @@ export class DeesEditorFiletree extends DeesElement { private async loadTree() { if (!this.executionEnvironment) return; + // Prevent double loading on initial render + if (this.loadTreeStarted) return; + this.loadTreeStarted = true; + this.isLoading = true; this.errorMessage = ''; @@ -503,6 +508,8 @@ export class DeesEditorFiletree extends DeesElement { } catch (error) { this.errorMessage = `Failed to load files: ${error}`; console.error('Failed to load file tree:', error); + // Reset flag to allow retry + this.loadTreeStarted = false; } finally { this.isLoading = false; } @@ -521,6 +528,7 @@ export class DeesEditorFiletree extends DeesElement { public async refresh() { this.expandedPaths.clear(); + this.loadTreeStarted = false; // Reset to allow loading await this.loadTree(); } diff --git a/ts_web/elements/00group-editor/dees-editor-workspace/dees-editor-workspace.ts b/ts_web/elements/00group-editor/dees-editor-workspace/dees-editor-workspace.ts index 818a171..b7743a7 100644 --- a/ts_web/elements/00group-editor/dees-editor-workspace/dees-editor-workspace.ts +++ b/ts_web/elements/00group-editor/dees-editor-workspace/dees-editor-workspace.ts @@ -74,6 +74,7 @@ export class DeesEditorWorkspace extends DeesElement { accessor isInitializing: boolean = true; private editorElement: DeesEditorMonaco | null = null; + private initializationStarted: boolean = false; public static styles = [ themeDefaultStyles, @@ -442,6 +443,10 @@ export class DeesEditorWorkspace extends DeesElement { private async initializeWorkspace() { if (!this.executionEnvironment) return; + // Prevent double initialization + if (this.initializationStarted) return; + this.initializationStarted = true; + this.isInitializing = true; try { @@ -450,6 +455,8 @@ export class DeesEditorWorkspace extends DeesElement { } } catch (error) { console.error('Failed to initialize workspace:', error); + // Reset flag to allow retry + this.initializationStarted = false; } finally { this.isInitializing = false; } diff --git a/ts_web/elements/00group-runtime/environments/WebContainerEnvironment.ts b/ts_web/elements/00group-runtime/environments/WebContainerEnvironment.ts index f348321..c73e9c7 100644 --- a/ts_web/elements/00group-runtime/environments/WebContainerEnvironment.ts +++ b/ts_web/elements/00group-runtime/environments/WebContainerEnvironment.ts @@ -6,7 +6,10 @@ import type { IExecutionEnvironment, IFileEntry, IProcessHandle } from '../inter * Runs Node.js and shell commands in the browser using WebContainer API. */ export class WebContainerEnvironment implements IExecutionEnvironment { - private container: webcontainer.WebContainer | null = null; + // Static shared state - WebContainer only allows ONE boot per page + private static sharedContainer: webcontainer.WebContainer | null = null; + private static bootPromise: Promise | null = null; + private _ready: boolean = false; public readonly type = 'webcontainer' as const; @@ -15,11 +18,29 @@ export class WebContainerEnvironment implements IExecutionEnvironment { return this._ready; } + private get container(): webcontainer.WebContainer | null { + return WebContainerEnvironment.sharedContainer; + } + // ============ Lifecycle ============ public async init(): Promise { - if (this._ready && this.container) { - return; // Already initialized + // Already initialized (this instance) + if (this._ready && WebContainerEnvironment.sharedContainer) { + return; + } + + // If boot is in progress (by any instance), wait for it + if (WebContainerEnvironment.bootPromise) { + await WebContainerEnvironment.bootPromise; + this._ready = true; + return; + } + + // If already booted by another instance, just mark ready + if (WebContainerEnvironment.sharedContainer) { + this._ready = true; + return; } // Check if SharedArrayBuffer is available (required for WebContainer) @@ -32,14 +53,24 @@ export class WebContainerEnvironment implements IExecutionEnvironment { ); } - this.container = await webcontainer.WebContainer.boot(); - this._ready = true; + // Start boot process + WebContainerEnvironment.bootPromise = webcontainer.WebContainer.boot(); + + try { + WebContainerEnvironment.sharedContainer = await WebContainerEnvironment.bootPromise; + this._ready = true; + } catch (error) { + // Reset promise on failure so retry is possible + WebContainerEnvironment.bootPromise = null; + throw error; + } } public async destroy(): Promise { - if (this.container) { - this.container.teardown(); - this.container = null; + if (WebContainerEnvironment.sharedContainer) { + WebContainerEnvironment.sharedContainer.teardown(); + WebContainerEnvironment.sharedContainer = null; + WebContainerEnvironment.bootPromise = null; this._ready = false; } }