From 068f672dc6cf0a5c56fea64c64de404787d5b61b Mon Sep 17 00:00:00 2001 From: Kostya Cholak Date: Sat, 20 Jul 2024 20:48:45 +0400 Subject: [PATCH] feat: Add resizable panes --- bun.lockb | Bin 151331 -> 152256 bytes package.json | 1 + src/App.tsx | 79 ++++++++++++++++++++--- src/ExplainableView.tsx | 37 +++-------- src/WhiteBoard.tsx | 24 +++++-- src/components/HistoryUI.tsx | 2 +- src/components/NoConnectionComponent.tsx | 2 +- src/components/ui/resizable.tsx | 43 ++++++++++++ 8 files changed, 143 insertions(+), 45 deletions(-) create mode 100644 src/components/ui/resizable.tsx diff --git a/bun.lockb b/bun.lockb index a26feae4b808ce6be9f436d1abcf8a4457f5b9ac..cc6e1a930e4959c99d3db63db00af6ac406a966f 100755 GIT binary patch delta 25307 zcmeHwd3a6N*ZnhJa#Y?t*J^;TB7)U))_=weV@L+=Y8JypWeskti9G=d+)XPUVEK=&$-za z&QW$OR;C6w?$>n^Tc0}IH(^f1oy>#n7D_9|pLOcnqyFt~L3sQd3X?@xSWw zuOX`mez{4Ks)LTJC`nXrZcbWiGV*qSuL^zyXthEldLZEr>foeR^vF@8F_4o1^HC91 zFdno4Xdzmw16lzM*8mj`lH?1TjC?Q9PN1HkW)$)VZ2_JPstf7{>ImusdIRMOsbDD* zq}at-lIns^0#BB&0VM;DpdsRS!Fn=eiHjz8ucq~6XiknjXQ(92fSmL)GjehvlbX0n z5~?f;fxHrEdQy5u>M$4$o<=M`X>_4Fgp(maT}9(SX=qY)nr+X?NE>UH7NS-^$Ugw3 zirxYxy_BS!jB)9bbPmHn4O#X4%+%reuvH2KPb1V{udf>@bs%1+sX2u~BhoUGrSljc zsyGH2M2Dc;RAED%zX6^sPR>pmYR{3RWQ;HAEdeD%%0MZv{sQGV}_38)@TWRCK$JW>9Qnt>RE#?BEgiB{;HQG||mW z%1sFxWzSE-cu+Swfs$Fr1GROu9+cKebW=^ffPdrQS6ITdwyFhdbO0#atSBcVJ>8xy zNz0H=qc#teIyEXIeQXj&c}p|RrqtY=py8?M_Ql|-HR!5?f(4VCpJ|ushiJ1i4duz& zzMwQ{6sJHVidMjn$ajWjWQYQ3(<>!S-jx(xmA}p2Boof z*ZC){v>~_#O7c^nRBs7r4XIEnT7`rg1hZ6uR5Tfs6th7|aUdv#;*NTLn4a&a^Uk1D zzM|fddl4G%-BGLOVh3%qE`z5LDg`AM+5qZSh=hZ#coK><5;s9TKo6oKIC0S|Q1Y7O z1T7?+x@bfC3wUbyDkynF>#kaZh`UK?NyF^n;Hf@;P#QsZP|`Eja(+@;T48EVu9RaR zJ(k?G4Jx9!3+tiXRNO%Q!T;J_o3o!fYwmZUr{*)eL8&L_ba`czcLg8bOZUchUMAS}(AFI?o0c)nA^=rd@Rst-oBGy%S#)ZZg$j;b4BPtVCu zA1aN+G7CpDnUEt?7JVGSzjX>OEF36Fhy_JSpyYvVbb5J!Hm{AqQ}yEpYrXq(NV5;o zB9066XeB&AIhq#3`cvR(&7Dco^s-Y&XD1DpBt3*ymZm0a3X_xhdrEL&lVRF4Vgzz? z?QnFx{C&vD&qn41;pUenC1sDuOv=u&Ux&O3=cJ>U`4BjO=tt;?_!Dh3itZk)I7pL-h%4Z~iR2&vGCR6gw&>D2rX=YGb#!%ehKvPGj=1Q)aTE0CeYm7ZR zUmE&C*W&SSHqdO3Qjj=@0CDhQTESXFAl(mXAsz6DClE(eq<>YUFjRcX+=+IY>L zS-6Fhou4AR4rnNf6YVuYvm+LiiXpbB{s>)F|J8|Wva8H-aQb@tij$AOz3~OF<~qe` z=(;)F%38{6-gm9z$S(1Xo>tb3Kg4wbkMgpzi#*@Uszg_iq-a#>z~kzgSuTI*Wi@Sv zEQZH=#jvM5-`mQf`9@rC@`t#-!lQhw>;}*GvC6d^`6eF=OX3e9TFRq*t+KNdFYvXn z_I#tSl@;@czEV2ftYD~9~Qq@hFSXRku z!Q;+kys0MEKxY!LWFF;jWrujazg5`|uj!3;EAnE$Nd6G=EFM+Ysw_qn=mNO|XBe$t z_{O?clNoWaHGk|GW6DRWCEw~B!*=ofdRFB(@HDm+c$|-!h46=vCAmpb9AqZWyv)i1 zaBbCgN_@@A6>#z3TzCoeU*ZqzTa}&FB?(agqemmqs0OtV>mS30@r?miWhwX;$d$<+ z(~sa<^H_{+Qv}hLMk$uUH#V>;??Xmo3EREQrfcBZ^4PjDrl#`NlviJH{UdT4e_x9^KRe7tU{LHNAzKKr5Om_AP(d)GF8U<|Gw!%*rnC{AO0UrXSzb%%a$_ zxOHC-!ia#2KrNVmjKSq+c_j_ZN;V(&% z$Z_N>CejH^446v1xQSVDLKt{SEdKeo`I>Jr*m5SXTed6 z>KrRguw9~&R@9+L0Y~#CsjF(ao>!5_!O|bWbwD0w0bGa1S~*yR7GBdij4u50COCv# z*hgdG*TmqcC*8qm0}9Tx2pm=#*31>8XnrcF^H@7j>y0|AtPhWhR%0cu-TB67tFox6 zHqUBAP;P;vIr(&~B_rFxO^lJ;@uS)L7fW~73kA02C9S9pG`RrYGmH^o}yn(Z^Dz$Sj|> z^0M|8(^t5MwB?W6$C!MuqS~pcB&0g1sijD1xi_E5!rK^nnR2Nlt{aJ1}?oV24YIg>R^lR3oz(gQ+Z%d0NNIZ8 zpUE6CS89E-tphJhu*mOp;L%+ya`TS7po_)yaz}U%pV%_S^{~jVcH?C|EJ`Wvxa8^xns8Ew z?#2y)xc1=arid_w8}fK?L)6y#_K>7>HMJKh&6dEPc(9|&CL`5KO+7|xfK~#x0k!+4 z)ktZ%caUnU=Efr|w5F8uI#O7(STb=TX5|bxOe}0;v1XGW)@P&|(h`w^*_y*CpMawU zsfJH>nQu(ADh(60FwHoElxZk9t^SorY4w+Qn&k_Ld{ZBb;)!KRLaaWl?@r(l_Q(Vu zvuP|i&G5rWwWHXk)ad)%44Q_3v+%9mTC%>ppr1uK172%_?mN!?=)QxlnT8^z4w`(d zA1~-{QT+PD$JB->(C2{DZeFauSzgtjM-Q;b-UE2S0E=l6qE9w$+e|eFA%;>)8HH32 z)o9!*<*x_vf`Jyf!C<~=phe+>B?*&7w+Y-degH=^tcG;C_7Gk$$f9Hn(V9aP!|iw3 z5MDOOV!8)mSK56jZIXGwlRAZnxfC2leRLR6-^s4+fweo{FmR-)-A_LR7pZDeEyux8IcVbUA2?j&)NdN5 zQQ)v)$55|BN*h3$sN3LZQE1V*{shSnm%zabgJVpMMygBRD@I92 zik6AGca=XM$qP~}%3TPlYX~gZiN%jHysJ1o(g_UpN89sk21j#)oe9S7p{}UzQ{?b8 zUY2T6=A;>(iYZdAfTKy)%&R%ta3uJl(nIIe4TI?&aMAp6Y>cuGDVhYe5&6kza%&|l zU9$s=bY!Fh7;SYgMv8Pb?>(b)7;ZRNLww~XW7R2A>^g_|guI2|Xb?5cGvG7_p-J=2 zG&%{+)DK()e~frD6)An`Lu)5E8c4V=`cg4Vt50(W3pm8LloH zeIuQ~Xm%CXGb=~Hbwd{13ggu%N0M;whw~THI?u&z^BGtA2hM*C*59+dOmGN*db!=; z5C(Lv?%3z^#(_hq)$>Zh(dyUQ^BMPiUOG6Nktc5)$D?yB%54bg{*73G9bI6aHre>@ zgT2o!aD$MiaeeZ&4ZX%K2S+2Iad*Ly!(leDmO=|O|Azaen3dt+!jV^*_Ozyt!G)@U z{A;9W$}mt^C|=_YzohBx366$T{f47V1J@gz*4EWOaM=^I;nwnYf-ASmX(CoJ%3 z-CC!KeA76K{O&|vHZHm_KvEydNe-Zm0R}YDX`oJVCs02`D*(-O3a3%^!$94Dc)$_p z3{ZWTe)aP_rSh02$prMl<7Tx2+%41(Q7VWzR^=FUwLt`1Nd^!NRUXktBj^wgD19H`zlWGj^z4tpX2!N|ewApXVuQ?F1MPdd;tp zYTOIZhbZOl)9HSlmV(mfMU*Dzh?=WWDt{E9dXEFdp8)7Xl;o!XlAoqYr4JJ7ho}>9 zUSm~Cir)c5F97tp08mAj07u|DK%eI+4b4vgmAk3aTcGqQr&{}}fV|=!Ko$QA(C0;z zD*O!~`T(F0Q7TtP3_e7uK2jn>=+!RiJJ3a^BzG*-1&+^AN;=^}RGm|uQh_SE+?g`* zAxiRUI{zX{hPmnaL`mNrlthI!^$env^w9YiQ7Y(-e5%k_*Zc2KDpCs~$}N?BGtpD4|AJZNRmZlDz4lJ)$5Ks6uy2a2fnzg6)weGjDab%Xv&^)>L< z47L1!QSg5#-&h0x!~hC6FQX^a87fDf@rvHF7g3t=NqRm}N>0XwKQuzuO z8mzOrK2b`Z!=(Xe1yVLBzggr_NIh`Ur9??v0VPpoUH)HD(yszNs>cPC_-dduq&4;O zFQSx%AN^?VO~3x3f?hiH)(bvQ={{dimlGxZ`Z`aPk_~j8DCIZQ`R6Ig8|m^!GTJB0 z1N8z;^$emkOU-q8h%W#Cp;RA6Iy@;IHg)@d6(pD5+G1tn2Coo`PJK13Wu1vNeaNCZ&(pSj$ciR7lJMAYfPw4)&rt#G2p{=S-*Un0M@-$X$;lvQ0b{*Uh{H*Dc)ZXd>InvvA$U_v5;q`yWeWJ9s{>CHxq! zJ9*>diTHV5F|J?oZ*bksLrx^JJ^T$^_wtLl?&DD>6WM+~4cAhB9oGXq?o=W>$UngK z5Wj=#Vczj{B0Iw8<9d`o#Pt~O{#7D7&X?kPg0rs^*-73P*He5ouBW;3O(Oe>Cw+t2 z{nnZ9{>H|>;jZ6ecF#ETG2hzQ8D0WzAGm-sHv9}N>kMZ1tTR6a?mO;(7PEWKnNL1z z!w)x)f%_U<_&FQ`2Qe?kB5p?}~4 zc*s5U?>_o>&&C?^i{P$-i@$GUjrp|u=-;pCAGkms_bdAM8~XRFjRo;L;2wbM^_vYp z`I`S5`u70+dtk#aPrE-r{~n@$;KDe2i2jwKe-CXeoUaDA0i1i8jhT5;8T$7K{R0=p zT_2%;zoUPTY%GSCfZGQy;CCB~}bivEF%=OIrMXGCH?W<0gwcfuFJU1QEO;+c(goH30hiuW1V`(SM%j)CtWGiR}w zL69Kskl+CcddU!U74u~XmQ;YiQ~`qSqI(4h`Zz$amIOTobAZ6f1cBWFf?i@Z2{w?x z-2_3RNHXD)QW1jPBvww6oZHdDy9(`DXtS4 zCE}`pq=^rRj23r5!~Q4{u$BZlg1JE8R1E^V z3j|}tY7%T9fqOLw#)+hA5Tv+5u$u(=!qpW5Pd8RojCEz5*mzMwf_-k#2ylbOM3LnN zL0)wTPLZHc_*aL0MIygCTgXnWuT_KXlBr`g*-+D3JTa^)N<6T7KJ#=C!#r3Y)^Yt- z4|bvgTeW_g59=yBpTKh~Jkl;Y2U?AE52(6ZYBMLfMbP?f9_%%lB>rPlbM18Zs%O@I z`cBWmvNO`s@P`A^M95s$qi`Z4-Acya86B{$Us;!pl}&^2a^9V4f0gptRk1pNRX4T9 zj{<56{~DT9bZfwzOwoA7?@U#VQmYaN8$!4^5nE9zzECx;s1anls={!R^%NHxu@)w0 z{Fp>7=%W@~AK8ReVW!@&SsenkTh995X-FY>&8$!>C)Cb~--A)(@hl7h2|v-ACVS-Q z?(4TTXYrk8)@I3-T1}*V2);KJ3g_`Gw(!YQ?L)FO{abc*V(>9|8mC&S1Wzq>9eU0@ zRDY0|uFL2d;zzn(hAuOKpQFn%bs0U>{8W<_N?E#)p3z#7rcbsmqsOH527wyO(Pgxs z{{f&+t}de&8t>|5$LKP85;{Ydjn!pUAgihyJx-P3(I-9oy$w*sdAcGdM*0Py54|hG zKlT01HcH@Apv$TuZM>KrugmBeH@!Wf_dOFp$#{BAXS}d2)b(hTAL);N@!Jfoks1*G z4p7C#y38HvCjfou#S?X)Ch(L5_!wV->45;ft|0^H#S{L~UwlZrb=hmW%nLFXq{*l* z^kxeG=+Atl%1BUS^k>N=^8pwV)Yu!kjD8xh7intjO$d2>2a%3_JyBlo=oc zpM(7Zm;v=#`T_lc0l;jieFV$_g1`p@&46ei2B23f@c_MGY7EdT7kW)&1?VNzPBc{y)CmX& zB7i8M0_t-Essl9`Ue(cyCO@Dqa1@1(0rVQq5uo3eYyq~4twqcu;wqBYfYZQNz&F5I zpcFU+>;ZNG8-SGn{RU=*B)p4RJ1+_m6cQ)|(2}PmPAj^b$S-DrQ3H@12n+%S14Do$ z;7wHV7BC*5-}uA>?SKwIM_`ILSBz1d3e{=AdjJQf0~BCR0<`ug026^g6o~|l0L(xw zfL`fj0b_u<;OR}ABPhMJY6U1jC7>o`?f|_43;<4|uHyjSN#Z3H1QfltLEr%;PrwVH zpP2j%+yU+a6u7PfKLR&^y})*0jveq0rX;*g55%35g=Hh zBz=IyhXB2ZqF;^BtGNaM{m8}(bUUawE@mG1=~;MHz(m$sfDnN03136uAg~Ic;Pfjfh4Gb0&jehcL$Z6ocJRN0 z?gIT1pomBj&;g*IxhMbyKL${6qnF(zCy>rQppp~CPkcH|r6^aokPP|&{L7#;{}}+e z6S)_8Ke-x>L}TbsG^~d73Qz^0#%qF7&&Y#61(pI7C=fB!UwTpWpeRE34~j63z-(YT z!12bYa1vt>4LC*oS`Y!;aL!e0^Q)psn(#Z8Ifl}TDfF|=dP?~s}&kb%7RphcjuKs%({0CWS31FQhu)S3bb$oB)Km{(XE7YdYg2cy_VL9hl;9Uui- zP-GM}MsbhA%t%z=16l_N1R4YW0NoKA0S$lvfXdVd>H#EgsG|uebsF^+s=cM&QIBcA zLOrB{K|nJg6rj)(21Ec+07ZE+j?&aK3Qw^>4A2sY2iofB4B7=q0Bit_bVq>XHa0*@ z&@lG`UIKapi9jEKD#=A}`-9S5j7EdJl00?@(t`nVnrMJlVlsGIndzXTnFxKGH7TU! zNIZJ0?ys{z3xG_(7~L^Q=K?gvDL@X=*#PNMM=4EVEFTyLbb<~Im<@C+XdYnblbqax z>cEsIs`o~k-U)!wI5kXhlZ+z8iGX1cRYY#^ypiO!MUdr9#RVVF6YHbjVV}u0sKUy~ zGyZT{W`mlG+bdX2Q8txT@}V}XAiKqyHwWi?+^vUfb8tv-3%a@cO=DhNra{343g==H z9PeKWi=gtsA>qNzrFnYIL2eUX^KtOliky(h;LzZZ=F5 zkdH4CMJw&1>f^VM`=exNa2TqTj)?iwSc2>+i`&y!o-!E)YeDgp$a;@?RX0uvy0+v^ zm(!;!X3ET8eDod*i(Q0B>;b(gs8|6V?-^5;`ua=5t1%6sAL4?xz4cfm!JI$#l@?gfj6W$xLW=O(id3>0jZ=*%Bq zef6(eoc^TvEq66Ny>u0!&PiWv_N(k) zF~~P+xrp>RSS!zthZ_CmtUgz}AAm-S;O4>MxXXz7bKs^iVl$C=Vch}JP5ew;e{pjW z^YSqcxoVzq5nO?%7G@tC_4xp5M5{wB9Oh#jk+t}ZdG(rf zSzyt-fJUt1+&q@R-V%ZHVT^I~)~lb{k2Hzux>2pDIsGZ^LNRzg7Uns@=R^IxxCnJN zL_7i)Zk(IdYsgPe%cds%ic%CkvHXn_v|@kRvAVQccnWeTm?LM2n79B98b@k1Y1ZNQ z2mNc%=$kRNFzlvS4F&dCxRkJ(4q>=Oi^~gOK||rS5M-N3SO`OIidhR$jd76H>yC}* zBrN>g2tZMibU+*-y?9Xzvw;9=UWCH^#i&JpXE!Dv8!5ziSNPGe|E%ksdUnn&wMVL1 z`n0~V%gyO7)k*j-MoUQ|W-(eCDKZwL`SD^a30n*6#~^sXOlCQ z?$au#pFC}Iss+?goGNG}&QSB&;y&7~Hy(Q4&@&GF>bw1xY4-V>jr6`^6mE!BJE1>L z4E%(7bv4faT9W@HBW#{eoP&DbCCiKxzaFQt&ob+_{T4Nli^H(6`dViml#Nf>*=PD< znfXFOH^w%?wiJ~ngQXkqu)e!?&T*M%l34;I?vNPAg7rG_Q~iRBYJE{@q&5z3L&F&w zA(igjXwt5RgUs?FsR7AJ5wrx}@B({UXhqwIBq+!}0b;@utnB##TDbUWSifH9TJC78 zwxJHyaqtrj3BFaco*YHv3Gw-{xWqfugE{ZzEB(^u<<2VRd78wJKPsIE1levEu4dxZIb* z=TkVhasFAQ>xs3j^ZrwYdasnSkAvR)(I%c#blU9hh6)dpQR$6Qrx~gGf>rX5 zgArl~X&C2@z1GoUTX=8EV@-qZJQdAi`bySBu5K1PRxyFJ>ag=H|&Y`;!7vOZiP1`TaHH?$$%nesWhCVvlt~{qgl&HNL zWsS4#UOK;h{_FROy~{P?aWC*fyH>~U!?UOCA6A|-C`zQEtgmrip39|UAx(cj@O!z2 zh!XRtcIQ^wruqE&?H?@*-5TYylpTm1T8?vknr}LBeQ3Y(oa|Pj<>#<$GBhZnJA1UfK4<0Fz2zFST8T_( zM67~_8#Gckwp`Mp;^-^o8YOzWXI>rNE@bAnCFMD%T8V8a>vK)7eObHIf!WrEv&%J} zh&!JnTDr%HDr;ay<2cQXv>^+go}RW5Hvppx);Q4$8WBCAL1tW?nR|D>_1Dei8g}HU zE5u=W%3#;%yz-p9IPngZ{f}O@Me^Ld;&OP1}{ z%SLoQxNiP?Ulf#Uoa`W~eZf5Ciyg%64Xj2T+RGTH@zt8vDShZXK2CnNNE|wfLD2R! z4*HAT?PDDO7qI)|o(+9Q;(nyXMYD8S%-_Jge2rrO zUD~ue;}Uz5ZXdJ@!dgRh!D}`1RGQgYblD0XF(P>_%d51rvv#Y~n)Q^m?$oH$0?iwT z=C!|+7T=^~J?+)haBP;&brw@MF;DiBh~0<~`bcaCkt-*NqIDQ(5@zp>1|c+T;;>&k63jxG#)Z)icuNAo7i%&Du^SO2bJ z&U#FOaoFK{&)sK_9)0qIZf8gfsdZOzd_AmCcfU1z;Kuc5L#nYAsEr~u9f?RMBHk6B zo%WvKPa90S4I+*khY@DH%;UfLq{*Rj+kO?JF>OA^VTr%ZcDeZ4hSImo6|{Mk!+MA< z8(^t%oZ}Y{YkxbnXb#@FVtBI!dkF({wyQg-hVQI}W_ew5z zPL&&Rp{J;dS@!*VGj;o(HDg$z`^Pi6?o}13dEHC&Zx(WRFX6VCh5G#UL5KPs2u`Da z2Qpk8J2CnK_S{AY_fOheZ0sdgZiWjT>LvD}Mm9q{+6?FXLAY;WVTLJq?10^KO$UTj zbra$trf*@s&vJE#{*#iIkuMt^du|z}Y(-n@7fo;R)%z^|*;mEC-mAB-ci+Zxn6Ghi z;g@}z|5oWg>)yqX_#8@3=rG4W91u%B-R<*>9gz_opwO8d2m#4812kx z<0z*M5LI?SF|@HZEZtsC+j4gGn&s*&s$QslX^b$AUu@>$lQgV{z{Xi0 z)ZdoCKe?wCRd;`H4-oI5@(AOI#~N>ad#TsK-PmNSE)FY@Z@6MY2YVGRA`Ld|KlLg9K z2Z>fYSsh=+Uke3(@})uDZ{4CDHiZEA*to%B!cJ86g0DdI{0bW(?JJP4eF$D$ps)Mi zo>0|8K9wiq)~7Zlok|}>!%{AOj=)&Y=ad;QJWNNawwu=pyn+y}(zGNS=>*B_j zaCO~@*nJVT8?4)Kkq)1VFb)O%=|S?j!PTAUYa2affY%wvgWjl8$E)%y0inA6$Qdv~ zY}t*+0VhX@+o*$G7Rny%Qa$iMn7-M4GC)}NU@VQZK_^*H`gA(FuRSWzBmTM+k-Y~S z;LuTG2Q(v$Q$a_?PM?x>;_O~%>JKCSJ|`LP%smstfPjwoHgZA!zpi5GZ4JM5jTCC=r6f5>&aZ)7O$J!RYpQS#Ie|GBb zAMa-L6!@<{TQl&IWtQ!AI3?e=fk__5A^=1rCtg4(8gJ$OQU9F z_VBtp*8vZ3BWUqSujhy^RMt4X^qU{2h*yJq+QIKN!OAy*uw+Kn?*8(u$f=+){8Zu_d5>e%qoP;UmISIL< z_5svBB3Iis9Oyms(D9S63@-ncqIFx0Jb-6iIeFrC? zmKk=7>f^K*hRqOK54|RcG73v zij86_quokMQtrs1nOTn1zS5t_@C2WcYjr{I1=SSFFR`$oz|&0pkAOAP$&SjEO;`AftCUN1^Paqhd^_v;7TM& zF~n7p0zvzLC(CDmk^yVc5b=9pJsC2|O_TotN}lw|%uLGcBS~4{NiRJuGYc|F@sK1` znd=UD3D8tWYFct%N%|dysK>G$gLBj_>S3wlPMAbt2ise$&DwE}^l)Ekd=dKdZR)Z{Aq z#0I5?*CSsw7_*zo?*XN9|9w5Rurl-to>bHN#i-~Q45RM#t)W%y!N)myHeL#j>>pNB zYbM>1H6UbAQg$Qs2l-b6l&1T-TG~3A4NB|89IVO5@l#Hf8ZW|PpfR``qS2U8ZNxIu zQd5&MBxx4%$(ccEslyzSBvr4i*^-=<8PYE~HOYfFHhH$27N(8CL}-&u382(9Lv(7! zWFZgwq@@i?PLiaN;Hhh5P_j`CN+HRaKZi?FMZU&l&-o%+lKhY}80%=-+#ChPI?UYyN{ey1F6TO*tLLZc@iP9`zB(wC56~TP10_DPl~&Kw zmf9Fet+gJy0y)i(6QE^skf@|9-i0FdgbR4G_-Z7k0q7=Bni^x;YVp>;oz|tLL8&1b zlqNxsSgk<>RY!`WZ&C;FR9^#7>cKEj(lZunwj(7aCpj}q%1jzOjOJiZG*Af&v2ofH zBLp-6yay9cTvBV~{zN!P%ah8%G>q+g1o z|M%d@AgsFzuU)|v_Obh9Ro@!b(g0XM$=@4jj;iaQl$x2H+D96QHH0pbCPR)m zn7b>I-*5@dncH2Gu+VcygVGG_sZ$A*#Fd2oiKpCsw=v81%xp(!kK@FhxUPV+w6Fro*tvXU^-_44k0HG2kT zhTzGTA~`bpr#mt-lbj$gh4$)W9TN=!rQtjPN^vK-e`;C=($t5X_tYTkL^IIjp>k= z1f2v*A$N>US7Nv+{-h)gLzCFFfT#QqG@6q;8wskQZ&Fe^;*gZ77aRzx%G3H}Wgy%o zWe&|shEoWAeM5$(OBPgD66Jz*njVsp)(4L-(B#3%SyFJCmYJR=U$yVylj_%k(d*wSwZMs2_sCoSrH8*W+r>|L*;r|AHrv=Z zo`CyKo^Q4(=30QTAZKuv9d}z9rJi*r{-*V=2eXXo2KLt^5ZuYY&n_MKxiWV4O>}xUo0d62a z=M!TZ3;%kmsk2D6P*Z{Et1gsMMj(X{kSmj2rUT$&RSgR~>`f_Il;o$qtx6#TP1NcO z1EQVK$DLHY;Yg`9nT{f*mN2!)3VK^DyUvv?H{FMzEeTj-o)BPTpYr?wo3a3lq6=y) z&I^4kOy=f58|%Om0&U8>nBK9-apD2!tnc`#K%1!of?gBuXO1y-MXCWm=NrS8@cbZ~ z@&kD4+G5;+dfd6WvQ24J1{*=hOgzABQO1F5rnTg2QTBmr4$e(&w+=T~u_=qoN)nbb zI*+=+8B?kO?-3Bgn(|Y~%>!Q-xiZ;fItZ=_?}5%MiHO<2D8*XxQ&nxsaLA}bVY}I4 z+7GT7?-3YdDv9ZBrIgZ|QqU-_dN+xitJ{?QkWo!CFZ8x3#XL36i5J4&w&1Aekq2(- z%REPbML7YEe8=#?PghJ)va=WusBTg0;HXY#wa!`Ks1HnPEtkMiIcIe``ttmmHl-`p zi&huLLz$s-sLR(P-!k*WT2{s1TQl9Hc6CpFs+Ns?&dtF#`LZ`p47Oql=Lg$N1AQc^ z5sekw!p$Kz`GpTp46!mR&kwP&cljyYw^3U8!&fs3uK8F@t+C?U@N-pT80V)#ZSrq^ z+`G1wrSgQ@Hug2ouWgg>SLCN_Ta{*5%KBUnL6?AwQr)Ib*!wcCu&PCov5Kkl(3R-e zX5iX@Q`ZPvz!So4tPIZ&w<%cxk`%3V2%P^ETnxApd~r>Saur-BwG<|Y5`!2(-K20w zutj+nTnljO;K)A(a_>N^;v1x?6yuA{7M98L>)4cyy3B<}UCFNeO8+Z6z|lxyC18Y| zs%V@xQjNehLLTN*h{d!7To-i~Jw%GSz=cLoiK?n`PJD54vn}xqEyow zMDrD+UBKuw1J35?oYwkQaMYeU#EOEw5w)VI9nlgT%^^u$Rg?9+;@knN4}xojJgh=+ z)oK{_&|FH=IcIfV9s!5=3iGHZp1%I7w;vX1-|m#~t8utKP7jWvzRNB_j8g%D{RV>Oxa6QyKM}3QYxeoVkVpW=;Cde_Hu?FO! zb@^NfH$e#NXp&%I`~t2kIEfe5wkXy}Bag;}_I+d-9$i>ot+CRm9Oj4FA}^2P-p#D0 zV;Gxm+^<=Tsb)P%N>Eedk@kPSpit8WuhT8XDfwNdM9f$6N3or;vEclxC)u%%v~ z+^;2{8*7zUw&bTl?5((Wd#foQLs_5CZxCY&Y>j80n#x0}E2Wf+NVP?8soMc1xQ!&W z1Lw>a2Utu~!8IT)`A{2vx`WkZw&Uf9TEQ};qWQVR22Lp4R~1=Nu&0`uhZI~uxl8SM zVn?f-8O!H(v?>L7#A|Dsp4$pHzh#r#w&#g&S>*-o`P{dx%9Zxo+(snC9Ie#B2=m0f z4USd_q7R<4v%&RNTg!@*q*OI^2`SB%79AxiQI#!1s*#%VdP|bJYbB6Uy*C{}O3N+P zN$o`RQg5W1ke;#xDJ(ten{bQrfHc4%Xf(8#>UX9Nph%U06pYd4o3a}m#ZNUVGKnX2 zwJA-ocq#faj^JY&3r?&5AW~ZWg^Ko^3&a|a%4B|-NS17x;xDPY{g9Bh&r7qrA$N$y^L^yhoAg= z5ANO5DmU)Q6MI^fwLK*XqXPSBgYp6#7C&{4k43K6i+lI7D)0BwnnNVQzT=x-d~PqR z$*s2}wWke*(i17_UUeU>tOZAwYL70-p%q17M4)N_uC7`;qPmg}E({#PD+N?=RF3h0 zn$a$AYh$GD{glSwXjY<&@p#YHIcykeTTJV~)#ZNJ&0Rq%jL*jor#wIPwoU2K#~5c= ztxN@nFiDQlh6Ehq4LOZCAJkXd+iFj;9B`zGCmFhWBRH*Xs^vB~DhEw$WLhL?oa(q~ zBDf}McNZX~bt2VJvY+O(7M*SV_~|68oZF9k_p{1d`|-qnR^=g7r~t+jjdboWsm}&% zBN8lfUVrZ0AL|Z6>N>Pl%c7VE7*>%tao}hGBsFg_ILra~R_GV)1P0SEG{)34SzYoN zulJB@1_gCXDj!Ye-pN+Qb)e=8;tIA`y}@Y{jQpGjj?6=kfcpU)tsm?-(0Anq8FK>z zEO!{h=MJisA@boQ=(mTM%@UQR)VX~dst(X%Sh1}sBOsR z!RpM89ZcC6U{fAa+S1;M6e()6_kqr#t1-Wt;5RcFs?Ez>okMU!-VSgyteWNnaN6Xc z0khyYwdNo=(@=0x+^-=XTS(DjMSajZ2ab9X9o9SAC0(mdn+XZv61iV8wkzq}JKd`E z8-l)vE_whZKLw}RwK&M4+yF;|hbe`=YMLQQc(!8|EQaRPOgu7Qa##L=YmkNY_cCuX zIK(x*+(mF$@;cXW=&N}%z#*pUc~`*E>et$f8un`5d*JX8(emW)hw;;yR;A={W8XvD zv=-oKpz(VKI~`>No-Z%COmLlEa{Iwi7igNU+1hMFyv2-a2d=J~7m$o!hTtN>l~jL# z>;e~|M)BW~q9H>^VUg4wY0OD=KLn1t6my%KC((4^(r?79Cf#5$2o9CRt1g5 z3Pv6_id8Lg(rBJI!YZ#C&F7A&pA#gh?|UUDP;AE~22|H+4V~5mrHg1WAVjBOprjuT zlmVIo&OjT0>Wc;FdX-Xn42)y~;7g8L0p@~w5v79N0IC?vU2PC?T9N^TQkCzk^9V0$ zMOc4xidl<_GeJ@KmJ z=)_7nRPq~u=zg6Z0Hy17lm_RhnyXPN_botOa2z1M0HBK~$xi?z{~n<06`CWtKyX$S zYm^kv0YuO1a-vkxMSy0}Re-KnDRs>afXdy}=`B#YUPozC{6>RJ75_n6xL!x8!utTx z2LN3}soX8O+ji|3)o+#B<5fnq2BURBe zh*E>qb%mOslvPXTLx{okDkV{bvtzt+ zXcTRblmu-9O2Ml;C|&;#DCXn;(2ytcGj)Uh_o>$Y|HTGW|J3>^l8k^OR4S)l#--R@^PSUpwmF9;#rjW7fQ1uA98AFo}T|#n)9lFbmr@duTq*L zOChJMk9E2Xlnhx8S^{*PF8@N8Zvdr+H|zWsP%>z{F5d}?f1%PY-06Cil4!T4Annof zi8}E$xs}36`v5p<{*X?O=vqWc{;kfdlt25xlRhU)1-Maf{h;R(rR0yeRRw*f%U`8b z+Y4Pzl$?@Ds8hzrOz~8wkx7@nN~vIR$f=Y9N_+`W>QZ-I|8Zy{?x$xEr2-Xoo+u^#b)G2Y2k88(l;nZBoG2MyMc1#Y%Zbuh*3{*-WPKUc(iQ$4 zN<~8Sazx31P@R93QjgWuhG5Uj2 zRx;gmO8NtJo+#<3>pW4)AENU`6z!8N6E}KFj0L4dG+w89pj7ZZoxTrhTtP?>Xtq=X zNUyq1|K%+;`Trm8snrJmPq)-L|M{L;TR*gwri&+Xbdv=Q7xc>Jy@Bduy-+S!8_t@$) zzXYDM6pdfEx29=Ba(Wd1y~qB0k4<}XEk^zS+hf=MH}}}$-J%BSqJvwVIE+)v;deq(1J@%O%o=Xu|_^4s9%^LqQ^ zdGvl)K7YTRE#%k1T?5zdfSoPo`3K_poCB`>8Mvjq^}%@F>Yyt(9kR1!Jnm3De+X_P zxaFK3j^`^5x$>mLcD9nQ1K0JiD=&Y<&Q^2Bk$CQM#Fg&@w}yKhjc03lGVY)8UAW^< znZAu@>-Z4dzu*UPU(W-M#j_1O8~2U80QXJ2#_@QznUBN$OMVLXEj+v+o_)pN!+k3+ z#C;pD_gy^O&ZpzPgI~w}Yu@-oJpCyk?z{Ls+;{WV-^a5(d@=5O`6Jx-@wk)m>>Iuk z_x+sx5YGkWkIb&z1c=%b23bqjJg4ZgR&ZjLId93b@3-+^nm1_JkLL%exByuG!f$KK&Z}y9WQR+2t1!Z*sj0zXo>MbvtAH-gP*5 z9S+{GGyFN%4LEoM4&Jmg6OX$I2f=Lw=giqHICv8d-m>G58P;L7rVU*RCQ3BTI$p}7Fuh+pC0 zJv;N{O=G3I872 zSuO5(2>%|!KX4)3;}QG=H}sL6)#kgv4R{3q9@|+sAMzOfJ%)ea>hORk@DJRCCw3Oe z3&4$d0{@=c@kd?bp2EMU@DE%)9{vpeft&Tr&SH2WxV&fZ@41~dyL+~4kZz-6};>8LEL6QtX zYq5?5U1bQ$7lXhq9K|4TDF(ql60{Q@P7r)af}u_jv=_TbFu)0dDkccx#1In%UM2`m zlHe^7P#l5-B$!Yfg3h9V1S5(=5a|p-ycp+gu6iS6A5OyK+sJTk|56o zg60YYJ;Zbcf@lST`y}Wk8kd0J8VQz_fWRT{LBQS?txJOR5sN`YtCGkzl|push${to zKe3WXf5BWq28aYA$zmOmfkG(_GDtXxq=+p<1`7{2RP<$OR5a8L6{U$?BpBcZK^1oh zhKM2V5O}#maFPU>BESQJ100l`pFK!On-5JZ-NV7M4p27>BkAh<$;Y!O}-f}hH; z(qeX5)`pD|g(S!;3ytRGpfN^FF9$(%ISB5TV}fniJf%F_BeNDF&WrUi&Gf*R8xd}1 zp5nL{>&~ig4l%P6#n{x%%#XE~UBAFPAiO-z-3IC|3WM1(5$w-gKQV9RFbmWh#ghg`xT7;I?^X4 zIdovA_IT|PD|%LAGfbU3;HBJV*foez6D0;}|65Pm*+rz*U|+B$BA_OlELZQgd2LM= zD$7Iqiu1wjw5e@>yv3z*Csfl)j7NK=VE^s(%?rZVCRS8&5ZgSu4y)9?lbu2S3zhS-K3pBf02C4~0zq-a+p}?*LTsFkP`U()R$mhU+r=!0{#0bQxbx+>tiE zN@nYNm}L@uUm*RFpkzF~Ff_haj?wkd%Q?~`WYA@NQ7MP?V}L3q>+p~MOOEsupeq*w za-ah6j0Cve(e>!t6n)Sj1IFtzFQmWLW$)@TGi0tvm!ZE)n4k;2Aykm2#wO}AAEaLZ z)Yv3lM)QC^j!2VrmXsn?vtj>BC_#K<{a@fT6%JU^p-W$Oc9NqX2qY zoCwf-qBqv`7P~3X3}_Ct09pd{VdN*^6mSMO2b>2k02hHm;1WasTo&tcnWy;%_?y5j z;5KjvxC{I$3XvW1Cz6kV$G{WdDeyVm_yU*-%mQWu`M_KeK8|@Ri;-Lkd@SO?ma(Bk zW1tBT4snDeMvh~FISr6*2v~u7$g2;;01beK0KIe$1+5K)0rYnp6+tTj{s4XE4T5Yx zXm2>~0O-|yTc904|3SJv&;f`8Is$J2^x>g1{e0+x#B3B6z#O0&`079nfIe450#?8V z(07#}pdk}}HV_8X0T}9|58EC<8Gt^om;qma{ubew)ElqlNfDqw zoA?UY3S0yVflI(;;Ah|p@C)!ga1!_tI1L;C4g-6EUBD*bQ(zUaS`zP%XWqhTJZold z0}I*$?SNRIJzC&fl0s2hm3{be*2EIIWDgd4U{XxZT;4bhhK#}Sya1FQ)>;veJICfBg z?TEx%KpP+%g()PB0@eU)fzN=?0s5jz;cY&!0GJMNU?z|bBj|BPAENw$6R4{!=yp&q z$lZVkNdF1k0KNg}Q*HzLSVb>CN&=;T(tsO4vG5V_1fbAHp=>`uFF;D7U@4#&5DkO? z^bq&~`GQYM`8y+G0+u|ff9f-K;e$U8-=r- z0LclYvm0=siGeF@DuuPcoH1bMfFBJ?JvkWY1#|~!L39JCCulxY21+Bn8dL$O?Fyje z7|r1oz;fUdU>QL1=3}53FduLRJ_0x}1Nac%u0Nc}9u@Nt;AR69om_yKV)6UTGlj%d zm<*f?P|%tOECm(=3joSr1S|xW0HjNKBwq;>0@V8#L1`gUkCOxR;f0){1=tx7;ghk4 zYBZUdOf&;Ji_Vi-jA<>BYs9R{EIwx^l3xSofm6T*;2iLi&YuN61JFu0bV!eSpNyap zpwXd8?gC1Aq(`H6AC!ieM(zPX^O6=8O@&JU%H*hjf<&R^XW%kGlkz%1D}=($RiG9? zI<%UcPywwXT1{jWt*kWo5Ut)WcTQlqp=9s(wv zrv_;e&|-K5JO*e%JO?Dbu}Mhg0kkNnJ~GCT5l`(Hy*EcVrZCSOnv%4BS^-@FvON-@ zFclAU0O9}&SymJe25k?-0u*K10WE+u}iX;P3ffgKnAjzA}X2SBr> zK0u4FH+VexI)2D%=Ddxx1E8&Y3aAXE18KkrAQhncNS+B~05rq{fFVd5y5uOODN+pw zh5~J%Lmg%Z%>o?;82Ti~^ysBlLSs%35*pr-fYCTLOren)r^ZOfFo-ImY4EC%6otk@ z)_W>$xcVO7+;JNFTo%5ZdHYZer7-#Gu7AH*w&!m_GV5sx4G*o0b6rFnXJ$503<7CC z3wkA?7gA>QL?0*5?a&L44vh#64>Jyaxb;(J=)_E)jg%7_85)LIh%%*7W^Ixv{cOs2 z0mz96twT9$#cj^o$$v7@U?v-(^u?pa4~iSa_LeSDj8966~Z5E71MQd3dBB&3)#A`1A876j7-VAXD#K$=F zWy!~V)4$m|qKwSK;WuoP4hgr}%p7SP6Z7sb?*6l!J>((<;~<&GRR`Q3GO`6m!YEo+ z^gvM`;{=)+Rc3EG*}8FjkwRlJeKxD(V;p6}?q@hpdf4bpkwUJxfEw6j@n|;d6|?{` zEcCSw8#&%$lz@J?m?coJdZrHaE!&+pZ}n}zUmXjz$GeEjg4JSuh1(ove%av*Mfe=n zTwYULxX)o;$elh1-KHsNTmU;QSUxk$mz{-gKC7u`2E80I3?0oM`Ntu-qH#nmwZ$;% zN7bZI(Q6L#{7a2J#Tbl-s5qAevjw8kJXS|B+|kBJEGo)^2K$Kh{};MKAKwb%Pt+)a z1q=2us{Q8)^OttjaWS)3%Ki%ts@l!}Vms5TDss~M-?Zf)r|Umd$3lcy@Gs4aqUMc0 ze%Tp&Fvn>rw|RIl#dLRRCwKOtShJA*=xdzT6K?ys%INVP-Wba|+Is!Hv{b=V`15;HR)(mf9T6IVZGsyfkf`+L;JqJpy&88IIdwzBLL(654me&X|o%G%jtCwQ^ zY!ert&bEt?k0G>)mLH?AafDLm-nU*np5}O<7Oq2PHx{2kFLIKX7A>8+Mszw_eAPbH zdetxEbfucLTRnZ)t=wabwoTvQ6J+trLTiOIvvy5s|^&w;dmYD+wf(usJKWX zGGF8`gDFSM7!{1wtAx)d&@)bJS}<{I(-qH3ex*RPT zM?T$%>ocmum^!jBXvE?70=W`*+KO@Kl) z6wsH(=}{}PpQqJXihsNvS<52^4cb&ORW=~KXJqQDZ$0|IW z8$*E}w0#ry>|Wru$Rx91NXkQE93j>D#I4FB)7%r(W>uF{pg{(Om$-McW{Yx8GV2OS zIY`zE$6;2^U!7pakyX!9*yrhi%}%3yU9HOk#Tqp2W1MZ3$mX4C@#jK3tFh)($8$v? z6!0W_LVCtoSbl+pK|7VeEzr|fZI-CL8XdH!sun;Bx~@9j`j3TIFxlv-ikV=XY86|1 z_Y(7=J>}G*st@R(v8(ai(z?O-HMZz&JgFv*K+(rIFzZ&|#Lnj$>}-ar>S3W^6tpUQ zJg^m{*w|rg%C@uX)_)2GeX041I-g=9E*1Sh#Y8mD&?<2~-p{t^gU8TA9H6N*P8|Cb z{u+m8J@QBz^t|rTd?>&fY?q{UBK&LSS*)&P7Jh56INqdLS2B*+s_;Cp`PZMFn5r5R zfl8zpF=!2p86y^=2Ie8|t;G*Ur?t$NRTlwkAyW52o}%MgR*prB{%cu)&p$r{tqrk- zgVF!EX;N!zCr=9#jXq;-<)6dF)X&g$#>rdlH?nb~8%C{AJ+4DtXBN9YW3@`uK$13P zBO}Cv&*(+H=|;^%mT>_VKuQ0E?AU#X34VC(UQQ<0K!OjK3> z3YJQvJD)Rh!X-BmvJP92fGE*w9jhsaMv1I-ELYBs5)am)>JOrX*B9W=Mv1v!VD(;) z65oEoyrPUFx;DPJ^;-$=Lsgs@`VJmTl5vPv+}t~N8Z9b#UX)|A2;cS0%hx#eYkd`` z9%0uelr7R2Z4n)y5oH_{Hu=M6^EL;0+$hp8juLy=GkjPp$xJM4b-qMRnt;ucxfJ6bz+$L1W@FC*_@-y)6dXyLyBwHrsE zxm_v<4}N<1X_1C;NLpUTN7c^dwRSDascsXgRMt2Q?0|Cz(c;?R-A)Wa3j2BdFtMqx zSaLgBkJs|`^H^S#)7K`pp{%cQz}Nzxu&+*B?~_=hF~uf+rP_@n$y_~~U0<+v*#067 zLfKqsl!Zo~)29P^dDI_Kq`~#FJmyx=z$tU{igK1W65UbOcZ;rZ z;6ZMs(I0o_MH)vNiD^{(MQD^k?NM!yY+5{H!^k2HeE;i>pxfm$udOTJ2I5)e!mS zoXK|alp02`@ZHJ0MCg~ScZqZOsZ38Q%^EM?*ZWNt+^~xyU&2P?9JeOzJGXB)h3_b` z(OKNviV0Dnt@cE{IdIfOrGC`HB894L#nf%Ez|vO4Zh;rZnQcSl-+kj- z_WAtlZeB%I__q@kze4lIQFnD_^clHp{-QB53yRfx!#E7@W{kseFd|k#S$e=&>P2;k z6)7ky6f_m|I0eYEsBWXvTmrj9^6Lmc(y!TcY`DC%NI z?clpZ6&{x_;dbw2k0mBZ1`o4MU{Lj-*pF8?b3AsZj z@y&J?;q%Y0Gt^%`m_qt*4y{k4UbD}^^Og3H#z}os7k|iLSJ+?<2+`;M?&iEK7dVW-X^9}C_+XkUr7=F+pn5&zRmx|h;;JrmfEl$2c-_xnC z9$LKqn|}JoH5{S;9u@<3vKB9Yg8uVfWWnZxJ6R@^2X+(I-I(~-{I%UgCHYd%xI1@f zUrBp)>@kd!_9~bX{9^saACy^iXe2gicw^N~e1NjPZ{BN8>LzwV<4xN<)UN#)m8W+T zrT4%LZlaFDa`I@Og zzq`>JWks#M2zAD(kA-<>vev~Oa?$O?tZLd_^xg|AjPoQjw{>2WrPyQ-tlq5WMCW z6Ycl$7}0()$+^A6SSZR5dW$*x*tc(*5om0YL))~QuFi@|owK%-ZYKI*wL{GNhV_%1 z_YqF}*<9u%7VgJuve#OtPA+$G8w$S05tXY0x-NM<;YH=58tW&C1_v;>#^IGWOZl5i zzEdRv8u|}_;r&GV0W5pt*vdIG8}0r6%dQmMBeD1}K_s#L0IO9wqQCar@eT6?j&1HQ zN*zQO6!aHW53;tt#;KK#-2wYr&N1Idm36fjG+hRYsibMp4+e>zhwuPBeUN$k8fR7R zEPZul%k_O}fa&!B!ob2o!u=47@HLLR9I@p-&e>^AQ;keLB{ z%3#%v#m{t_XGT-24xuUISj#SPhhrV?8|Vcj{RD%WB~@HJgx?dvX(IG6#@{%Jb5O&X zc|%T|B~5y{08RDxr&*@Zc9=D@u1{BA(&zs5;e`TtjMCeee||{XhG-ATwnM~oYRot) zb4)~NrQKzV1)?myH^5lvA-IIFA3@-(pCNLOpg;5@E^}L~da=@XT@yE5A4~V$4Dsy| zEE?lb%$4lva0G@^{7IU9d>Vb8p7pJW$l7>9TIc`v-adaHlMqMYbVv4F}N$9)ct zjVkp{W;<*;4asmT!ekcBE(nUvH`xYSy%Ni`iN)!M+oaNsOuH`yt!g6 zt{IAA$1%LC+mtO%AA?ypN{iCRSwCOnMA5Zpx84fK45k;AdeGDBmp>UURvkwP{c$22 z?dy?O?m9{Y7r?>SM#pfPu<4^jZ_;?PrFs{LPYYP=%Lep{jearwkb8C)W4}WO{I%bH z{to^v7(M$0^D6QAaeUXnm0lnMPp~E)S&rnC;W#(8Ww-CD-l?^&+7gj{f>pxbtL1|P z9>y0FdR1|z^Qe#GSNofP08ek?$9Z-x{i0mm^OyX@=@ZQA{Z67Le>Xbv2pduQ`Jw`? lmC3Q2BfiI9@rmzGvf7)?Kd_D=o6i@MOPMyuDDs5X{{`}$c#r@9 diff --git a/package.json b/package.json index 6bea5ce..a446ffb 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "react-dom": "^18.2.0", "react-highlight": "^0.15.0", "react-konva": "^18.2.10", + "react-resizable-panels": "^2.0.21", "sonner": "^1.5.0", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", diff --git a/src/App.tsx b/src/App.tsx index 96d3182..0094973 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,20 +3,21 @@ import "./App.css"; import { Input } from "@/components/ui/input"; import { Cable, Wifi, WifiOff } from "lucide-react"; import { useEffect, useState } from "react"; +import { toast } from "sonner"; import ExplainableView from "./ExplainableView"; import { ThemeProvider } from "./components/theme-provider"; import { Button } from "./components/ui/button"; -import { toast } from "sonner" import { useViewStore } from './storages/viewStorage'; import { useWebsocketURIStore } from './storages/websocketURIStore'; import api, { LATEST_VERSION } from "./api"; import NoConnectionComponent from "./components/NoConnectionComponent"; +import ServerIsOutdatedComponent from "./components/ServerIsOutdatedComponent"; import { dataclassDisplayConfig } from "./components/canvas/render"; +import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "./components/ui/resizable"; import { IS_MOCKED, MOCK_VIEWS } from "./mock"; import { Representation } from "./sources"; import { pushHistory } from "./structures/history"; -import ServerIsOutdatedComponent from "./components/ServerIsOutdatedComponent"; const didYouKnowMessages = [ @@ -224,11 +225,70 @@ export default function App() { ); }); + const rows = []; + for (let idx = 0; idx < view_components.length; idx += 2) { + rows.push( + + + + {view_components[idx]} + + {view_components[idx + 1] && ( + <> + + + {view_components[idx + 1]} + + + )} + + + ); + if (idx !== view_components.length - 1) { + rows.push( + + ); + } + // if (idx !== view_components.length - 1) { + // panels.push( + // + // ); + // } + } comp = ( -
- { view_components} -
- ); + <> + {/* { + + }} + onPauseClick={() => { + api.request("pause", true, (_: any) => { + }); + }} + onForwardClick={() => { + + }} + onSettings={() => {}} + /> */} + + {rows} + + + ) } if (isOutdated) { @@ -239,13 +299,12 @@ export default function App() { return ( -
+
-
- {/* */} - {comp} +
+ {comp}
diff --git a/src/ExplainableView.tsx b/src/ExplainableView.tsx index c17b6fa..424e124 100644 --- a/src/ExplainableView.tsx +++ b/src/ExplainableView.tsx @@ -1,8 +1,6 @@ -import { useState } from 'react'; -import WhiteBoard from './WhiteBoard'; -import { Input } from './components/ui/input'; -import { ViewType } from './storages/viewStorage'; import render from './components/canvas/render.tsx'; +import { ViewType } from './storages/viewStorage'; +import WhiteBoard from './WhiteBoard'; export type ViewSettings = { @@ -17,7 +15,7 @@ export type ExplainableViewProps = { function ExplainableView(props: ExplainableViewProps) { const view = props.view; - const [path, setPath] = useState(view.id); + // const [path, setPath] = useState(view.id); // useEffect(() => { // api.onConnected(() => { // clearHistory(); @@ -36,34 +34,17 @@ function ExplainableView(props: ExplainableViewProps) { const component = render(view.structure, view.representation || null, position, view.id, 0); return ( -
- {/* { - - }} - onPauseClick={() => { - api.request("pause", true, (paused: any) => { - }); - }} - onForwardClick={() => { - - }} - onSettings={() => {}} - /> */} - + {/* { if (e.key === "Enter") { setPath(e.target.value); } } - } name='view-path'/> -
- - {component} - -
+ } name='view-path'/> */} + + {component} +
) } diff --git a/src/WhiteBoard.tsx b/src/WhiteBoard.tsx index 2ef1ef8..0f7afdc 100644 --- a/src/WhiteBoard.tsx +++ b/src/WhiteBoard.tsx @@ -36,12 +36,26 @@ function WhiteBoard(props: WhiteBoardProps) { } | null>(null); useEffect(() => { - if (divRef.current?.offsetHeight && divRef.current?.offsetWidth) { - setDimensions({ - width: divRef.current.offsetWidth - 2, - height: divRef.current.offsetHeight - }); + const observer = new ResizeObserver(entries => { + for (let entry of entries) { + console.log('New width:', entry.contentRect.width); + console.log('New height:', entry.contentRect.height); + setDimensions({ + width: entry.contentRect.width - 2, + height: entry.contentRect.height + }); + } + }); + + if (divRef.current) { + observer.observe(divRef.current); } + + return () => { + if (divRef.current) { + observer.unobserve(divRef.current); + } + }; }, []); const dragStageStart = (evt: KonvaEventObject) => { diff --git a/src/components/HistoryUI.tsx b/src/components/HistoryUI.tsx index 17f342e..30627b8 100644 --- a/src/components/HistoryUI.tsx +++ b/src/components/HistoryUI.tsx @@ -23,7 +23,7 @@ type UIButtonProps = { function UIButton(props: UIButtonProps) { return (