From 854e148a368dddbc074db37009d3dc2eef4ee6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 20 Mar 2023 16:33:35 -0300 Subject: [PATCH] eepp: Added UIAnchor (Anchor or a). UIRelativeLayout: Respect max width and height when using match_parent. ecode: New icon WIP. Fixed LSP TCP server connecting from the main thread (now connects async). --- bin/assets/icon/ecode.ico | Bin 0 -> 126772 bytes bin/assets/icon/ecode.png | Bin 0 -> 13444 bytes bin/assets/icon/ecode.rc | 1 + bin/assets/ui/breeze.css | 11 +++ docs/articles/cssspecification.md | 18 ++++- include/eepp/ui/css/propertydefinition.hpp | 1 + include/eepp/ui/uicodeeditor.hpp | 2 +- include/eepp/ui/uitextview.hpp | 23 ++++++ projects/haiku/ecode/build.app.sh | 4 +- projects/linux/ecode/build.app.sh | 4 +- projects/mingw32/ecode/build.app.sh | 2 +- src/eepp/ui/css/stylesheetspecification.cpp | 1 + src/eepp/ui/uirelativelayout.cpp | 26 +++++- src/eepp/ui/uiscenenode.cpp | 8 +- src/eepp/ui/uitextview.cpp | 76 +++++++++++++++++- src/eepp/ui/uiwidgetcreator.cpp | 4 +- src/tools/ecode/appconfig.cpp | 2 +- .../ecode/plugins/lsp/lspclientserver.cpp | 25 +++--- .../ecode/plugins/lsp/lspclientserver.hpp | 2 + src/tools/ecode/settingsmenu.cpp | 2 +- src/tools/uieditor/uieditor.cpp | 2 +- 21 files changed, 182 insertions(+), 32 deletions(-) create mode 100644 bin/assets/icon/ecode.ico create mode 100644 bin/assets/icon/ecode.png create mode 100644 bin/assets/icon/ecode.rc diff --git a/bin/assets/icon/ecode.ico b/bin/assets/icon/ecode.ico new file mode 100644 index 0000000000000000000000000000000000000000..9700d471fffbac943d7d8a17cafc9013d03fb609 GIT binary patch literal 126772 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%0A&nGopN`CQKjoYM++J@iN^eL_#orc5;ZF^-+2A6N z+@A*;e`YhKJ&Fe(7qMjH-Y379!fsO80%nmd(H&j5d|`tmZ9ODJs)pu;znB8TBMYn% z=?w3wF5&fG_ILWPz1P#IeVrw_|J#X%G+)%g!62im{kF)J)Hw&`{DVT*R5F9ZTqoe} zAsBqWB0R3O`2Jsh=*lm)bMUGBQF|K9K&r+`ZAnh`4$zZCHvBc57}pORLXA~U_U_PA z2{&~+JG+}8z&B;P_4bhS)W62iDo0#b-nm^~Y^=iA5k))ZeD?M=gPo&p$;iC+Aw_5h zE%SfV-HMZu^cC*@Q5ir(U%C72OWC@kanXx+$z}f`jrkU(P4bzjyKIfrdOsL|HuF;z zHzA~+cme_r4|AN1NQ$E}o9nd+UgiTqF?5_%G85W+wlr&bhpMj|QvwT>Pf1qDVaV6Tw6{ z+2j5R&iXy8wFZa2#PF$7DiL`htQ!3bPpdY()Bqhmxh*U)dvOgVH2vG6fbbVFAoP4) z#J<9kUKSKcowKab!<=Z0g;_!&r&(> zbV@$mp`!y*QggMaCouI*v9c``x3hx_xW7gPu$ik+$4t)O?@QG&X?N)Eh4r>>zD@vhs!vF>TjcS8Mz+8emu2?-;O zlZ|RO`wB2ip_;RH=r3M6xE4;qGQwP5^$#IEj`UQ|w`obp%?_fClqUi@40i|;k+VN< z=u(7)y?h3Pr~id;=)VWapgR4BtYx1Cl8wd!04vKwlj#>=v~rEf$PKIeYENWCh9gT} z8aX&z(ChhGlO5dId2xY&W`9RW=PSzzshvd1Xf4jO*&?GtdQNxAxKnUl$Vl7b0-~_N zShZBGk`2D?cKo3+RWB?9=y~7oFByc%vNg{xhRYNrTwM>~aQaqW{6&%@k-mGB9?_L@ zKsq{3UBwE0-MB2X61=UM8{`NBq&rVBtJ|@rl5c))-=auFZvKSgIE462B^^th>a>Qz zKsEZyRonR0z)Q}Y!neEU3;M`hg&6mgr_g6&am^vyo|~A4t7rF6C@54r@|WFR)R?+%KYRU$g|j1S`u8Y= zd|e4YP&l9qgPfxiQzu{R6@F6*a8^>-y@Pl6oPLt_QrNUR!kr-EMfx%qc1bTtLd_a4 zY$RSp${ayjAVW^%N{_aFnEB$fJ}7UroZi=96~fWV3LMJ)g9>Rn&GXh0y~*e{39;X^ zAeOzY?9d4u4?;bD{hMrui{8>gOrgFc%`vg6M&)ZW22RF&Ei2?r^gZL;l%Y+SY{3qn;yUF*!}{*^z^!MP^{WWddN7lQcjzG)B?cTa^&a8upqwBI4HSK+Cw>B z**b9YB(~RZ#w~&BJPJmMSrfEFG<5Hja1Q~hr!Rs8&1EaXqv8)~CMbhJ`!sX`@5E4l zUAZn7JRHA^`MHaV=3v&_WlDDftbGkV<8F7~h(L&=uE1`zL4)1gy@OZ;1bsdtYU}Ik zzG_Z$;GA)OKHUJef8;;9cE?y*;SkZ=dBsCT)Mt&)<>|-2*^00viwnd=;AHT$OH4;B z7c!=ZSTFb*VL?4!K8z9p7^HbZ1eCQn5_$f0#gwABg;S^qkIq_Du&5~ek&l6a5=+3R z{t8h`tLPMAC55LS**KdVH(i)W|Mht+x51$yC>n>%C|FkCkhE&xYLBgn;?8D^gTp1_ zGPHu?=xp$rM`AiJ3#)NyVevzuMRqkywwdl5Tu??vi1ZMqL{DqPmx!I|39iLOixORq zq6?MMx@r^qJ5)M8oXQlTn3%l!{h~p;e)RuYtQg4t`>pjt9P-WSHmDA1>O-OoAx~-* zD}N;GcAVTpxD^)0XVQUjRpHbLr19jlYDYeD^|RWtKcXK^pVHC<`G*bR{$aR|rI2AE zL*u0Xb#-Gk)Lpe;AD3{S#v#J)oTnmzri1cEq%he32?s@SYbRqNK!5<=5Rcj zD$kF#$UYodSvV%TY3}aqI1zz~zh&+`WA~DMnHR3fZWK^84CQ*BG5{OfsOt8-3Zx{I zmOY+g1g3?~aCbVBlp9s7g~CCzp6uS~0Rl;)or3o*?}KFA`rbujS~OaKyfO_7zrYd- z_UcPD_esr&lc5u9-9~Vgo$RlT!?rSguc5YDnzYw6@J!4&s6%)~?vhLI(#TR*DlI{z zW>7s^DqCB=&f+ej?Ciz$gj3gpMxz$>$(R<<%53deay)37gNOhn*!~Vt%f{nADhmf^ zyT$QpdX0j-6O){0aLCA)ul-XixZ7d3&ZL(NgBYNC7v&!mG&A1IX}O^h`u+Rl@z5Fa zY@OS=K`WZNT|_cw7oNGDUMLUN!r$6!a!x+oqc4@n_MLlvn~hHowuyu&lxaG!$msWT zy^Taq)U$2Gj>O_rjRAuaBqeBOM(Gn!cw1)1?ut@o%HquKUcO>*ef}({=F00%TY|TC zjXc><_2Wl%^)>XafRHo?rg0~ChdPJa(2n16Xcv(vM8fMMdXXCWCs4C0HDNV|&oG-` z5$<5kdsQR}m}D?B#D6_P@Sjp0<$NtJEv>0p$7*T)jG=dg*n-E+ebWpXQ7Lt+t^-AK zR9DxxTghzxxs>z>4ZZL|%>lijqM$_kL9%kw(_yiKjZ!o#a&f-qr6Y#US?w&SC1*)% z<{7@IHGiT`k><98WdUu!Jfzga`7JiL5P!2b^U11t^;@_mWdEB(rAwv-At}Sg5{ioS zQGDR$Q$7pE*A+*US`W3LjxZg(t}!>Y`keMLr|X$LIIx`F3&b*AHdeAD53 z_BWm~{|x+A|GdHEQU==59ruA@-qX*p@iEX(yJe+Dug-oTEgxJo#Jo0{!C0!EWZysn z3%jv;pZS+Pgs3uwL8WSfCeuq8-piIQ-$;N;Zw>!jI@TB+{xw9q@wcs5dGSxa)WT#f zb3D`U&io|y=?oQg|J|&meSNuP5+^5}mYnh?o@{bC*>GH;Uvu8M?GfdzGfVk_Sn|!& zYvj|^Df*Y{K|5DLTs4D`tq%!xSJuktCnB?Gz(7fc(t9JPyIoTEQ-O4QEV1<8dRDCe zxU}aAUC#}62spiDx5z_6id4vEEF4#WgJg^>aW36fepuud8yj+%b%6eN`1LMAf^rsf z#=qj4yd~hLT9HlWHEP#ayDUcL2pqiCWce79@w5Kqj(Ia`4u_!X4PaXr~J6R}! zOty_(mKdNL&>s9b5Cs`sS%u9|T6k_EcXxKb?Zwpmusmkr`c}TPqyF8LRSO)2kg;k? zJ$QO1F~R<=@t?RQM`OvU*(x)nDs4N1o!DAV*Q68;wN7nMAS4ky?>-#72D8Zl}4 zk>;aPkE)W3w@DY(`3OhykPsnc)A*E`$G+mLnDf?%9e*B;iCOMNIBcgWyOi)vZeh)$ z9b&2ZCYrR)O2RvL!h|mmUb=*n;^pHMY`?>7o#YeJaqB3aA>nWo-VJtOB+TH&e92#U z+10hX091Soq`UczQFscr|8JtfcEez`eK_fq@qD9s()(MsE61Ub^^vTkq;v)ee}7-!15N6O z_mbi3Q(>PnKl&vT-P|(yAtpz82kQn26n**9P{7!C64Gc|6@VN`bJL+iD{*Jdrh+f4Ql%E zc5YC3Jb#*iG;$7v9(4_mAj1#yIT z@|PHDclbA z)GreH5`BdrBFtgD?`SrDPx}k6FSSK^As{qpfrjhw7cS<3I#WzhXCkCZU!CJ_h4YVn z7h8o$)`D587)o^=OOvZB>;@)+CKLC*STESy}RhDIB!RC5KT-=0&7>&zS$ z?L4UIwqwf5+Dqfib8@KZ=6{*Kx~||6u651{(H`v5zrc5!y4PF8^(+ebXBcdccyKE; z4`^fM7Z@2jx+2}eHyXJJDf_N!*zvzLpv4C-!@&i9F+*fG!xT;DCc}=86TT?VR}B>M zsV6UQrO;<^)Uk9%Cnm0}W~nL9+S|-bP0f?-R=gwPu(o*m8!G8D?tla)<8KptM?%}` z3-2OL+XBb_V7JxV14+j%#v0R8Ov;w_0(~cS!qa?b8)ot`LnGZ$_7VZo7eDb^d`N&0i2i^$4q(EWvP_AN-5ALJ_6j#fAKwF0`}Oba;7zLWt5+=)i0 zA@&s|b(j5J|MG>oM8OSjt9Uc}O$%so{%)XMFLWK?a+BUWW=<8g5OjocVd}0`FM|Br z0w+Ps9uf~%s6!-y_o`QmX5n|jnqTl&%KcW7vS(%ZgIjrcuXpt`+6obsoPPo^=Jh{E z))h1muuH%sRJB~O5Q|JBpW6RokR&oax$dTJk7VpH`8CUi$J|HJ38_$xL+wJenAHHm z|Dkg~PlTk!m#xNE74yV2-K5=@eBc}6Cl0rz>3x8+y{WXcw)WafyR#(Q|3&hs#iJnz z!C(E|`p*;n?stYxvD0WnjX!q}Sa&iLyIWDr{tIJ^yACx%*Q=+Diygaj{cPTnXOT?cbqy`yq8Ff^Y(k+nC_>a0ikBS>zHKM_i;lbP_}*Y1UGZk)RMDu=MDcXj<% z(P3TpdcD3b3A%n{_^x(1TSD87Yp9-XE_{pU;}hmt<+OGQXTWeXZt-G@uZnH#qNJ7rhnnr?4p&U#?vxFY@`ECp zWU(t$aLB-R72q$!UJ65_{!)%dq}-Ri^wK6K4x-=R73suZ5C;mHw#zHObw*VFaM?;E z4q|%y)(fW$3ky;fSHX3m{$2q%Chg-wA8?PqQ{t2b8`2Ti(L*1BOh-vMl_$X}?wM zwh27wPXEB^mmPKSO;NUJO>zwO6HLC=TpFh5?w&u0geAkZxz_7WAEOvcbJlm1h5fT= z{8^Wk8TNVE0=AYytFJ>2&v%sA=q7&d%oePmiESJB| znS@ht$HE|(M_pb0R$cogxlr^tt7I*Nj@EM*u7^Dnro;` zF6)h3G1E`hdFqU>x&|cXSSy|4{JLjP`-j!en)XW52O3rREDWvL!GmTLvCH z<&0MWpuLZOLhHE>2<=mOS9gH{a6`_RfZ$he>*{ipEV9wb1tdok9k-JE+-oQs6O5LO zXZaG{2O=3rtVbAexRV`|VRakFFgdes9r%M%?Lvvbn3Ot6BYR|1KLy> zeO)IUqO6hTE@?amG$)pt)PN#Lbkvv3g;{1zHNj*X`%|s_N=o6Gi3n)c8z}MzxW($*nD=)o0$Jiz`-n%X z>3MJL@V?IEn!OAK(S2y{e7G7Jj?!fE&iqIqto`lUfYS1K#qip+rql+R<;U`b98n}(eE8l)X4+= z@Pnmm>RZ_Bq0c2g1oOqXhHPA-B`<{Em%fA~ zb%7*K3qR#h+zkBiv{+>WQboJAJI_VVH3g?Si+~m#Y?9ByMCT?1L|L!G>eGg8%XnR6 zX(FxXn3FDvybbg%ww!;`30 zcoiZ+nd%WnZzglQ7}@AuBfO~V^Zm>-^rP}xQb&!o2@J_fjJ9s?4G>6=_P^G`3$_m7 zjB!5yH=`l@!Syur%L0}9Y2~CTOJY)6miV<<)3bqvCc64;`&%9QSpJt`2A^MDjX$QQ z!M3CJ(`%F1-$}my3-1B}>&UD?mnGxl%l(57%;U2%0VWn0Y-~kes~a2Vxv2ZTxfh!Y zx=-Fq6<&*WBMg{l)EGdDKJ5RXM;eQcu^D4wHv9Sdf&NKHO-)AThbTlRYQ2o!=+P;n ziI#tp;lURlUjQ?dVBs_KzawjUS-hcygaj-9ySR#fFv>rFLWdpr!;iR*HWmIggtp_w z!a7_Qc#ZBcG}n)_s^?jV=-MRrrMKfdcho8gfiYJd=UaJSNP=}wz<;x6_y^x0E|TmY z7(DI2{=H`y_Wuqg?DK(S$sNtZ(DK)tAS6R0INj1lxR1gLwJWoU(b3cX48=DEYw>ay zD=q&8;*1yH79jQS(klB$U+cnKO8GhlFYP-s3#izqAs=LgqEfEL_M$RbLGuYT^F{t83zk5oJfM4RJE)2r^1RFn0Y+u9?wocl{ssbwCGe+fNv&cx7pXG9rXIh@h~BP~+n^QMljO zNcnE%-k<)o3__4V#Ys~2wUaCYb2yjH2&40cowP6{`FB^R|;rS3Ku^rYNYKU9g|GgmM+N`t!O23lftpSY<08b8`APLUkStD^T4H0 zfPM{pj9P~Y_6cGz*KmubvGL6nYXQtzKC^^s$ayYE{vDy}#^WfH?_78hXJgwLo_fHW z((*jPCqgqG!h`tJ;C`?-W~S2!&i*~@OFo>~&f?b2)@cCPs#A}#$$k^W4gR;jfyPCpM;Ros7nyJdv9K^L|bM?Zrl%drh38yvFm_79O3jTSFY!_?84q zSF1E*$IjmI@}Zp#!yuKtKQx(p?z8S`3AR1KljM7Ion2Vr%%`wP{V`3Oq9qwleC5wJRor zJx#Xa!XR@F)|q59W=aS0dqbG!zTD zav=7r?W6uzJ3_*ovxi{wi_P7&BrFiCtN5Az$8d2U#-lkMW)5N#hR?!Bffts=SP-*G za^2~pIz`#Yxg>mH`Of?r*}lG>OGb0kwIAqYbZ*Mj@OB>Hv`xYMdsK*s{d)NW*FI>n zk6x&QE@eB2>U5aQcwu4Q)-VHvp6(n3^N@y#y5KzoGe(rg zb`49L>Q&^+1|yOP3hbYPle3XJl=$H`H!njuOdhxP9DemUw>%016xeh_?Jy35m)VT0 zuqGNmmgQ>Rv*52|_x0Dd57RP3%~>9;`?W=E)MsmY*lZ!GQM0)%Zx>&n~Ejo{l7 zTDKSqzc$yzYx^|++34lN*w5FSqp>YDIc84b+Nz;7;H}Z(Wu^xwBsn$Q=Z?N2zfdM> z*VlY5V~-*uCggRE%x8{SCyb*gSfyB$@x^8QwXnN8Gcg(sz_eTv=< z_a@z$u~_xxTYW4L)7{iky&4s)5r6)DN)nLJNP$QlfEXCfixrXo%{yr&9%^LNG1pk&~HbxOD9JtyPaF(KJ zHmwtP{GCW%vci_s0E1s)x=Zl;2UYtli;A5cP8hwhFuoYDzWh3BQ*dE^<0?@>^a+p0 zie|0?v%dQ_$<@rphB{E@G&{ZP{tR`(UrkWl{7HY}o2@Pc=F-&*BDcLnLrBB;&Ir|o zR2F5WEl}3`y^=61J3a*q)6jhW-1iNre4iYf{cbH$c$i=-$MoTp#pQhFsup(4al0Ax z(+YC2!XuPIbM!8h^J3M-AahJY#d?ZjR*y(w_dQ=}YgbMQ52&1(U<*nu(Muo%arVB=)PC?zs!8m}$(vo# znVZoL!CrT*kKcE+2h5)y;&cCt0L*r9n?8sUf6)D!7e)Jf>Q#)@GHh%FrrMf+mG7T! zP`?X*T|rv+S&vb;dR@4PQw!oggd^)QtD+YM({jH%>S7Evkaq0Yy8;PVB=KC1j{6RA zKcbGhtTuF|;ixy)hKdsqK!TzqQ#U_!O}ll4aF6F9WI7_dNGJc-3L0S=Gfj76Wc_L# zKZz8_IWf*ok#u>%-Z|Z6Dm(0*22c0FZ?GEbQ2hd5#Fv~_=V+7~et{eb-;7ZeZtbpE zzCw~OHk=O{E8k)5Re=8Vx$q6RVri2?SDHvL+QWcB3^4FET{Va(Jrc`C5bkKcLtFJ3 z1G3-MsrYhq#30_)(D?n^_2ciM1?6eG#$aeO3D0Bg;s)&fyn*Jl%9_2035&%5axQNy?E<`xk<{;xkQ&W9C%%?ir z+E+qVE>EHt#$EO6;q{mPwR&07N))V9xt&oxmVF`QMKYwHi+Ci0b})#>Vj`RJ&n5VfWp#8^Rvb^-*pxm}jU8PzySVsR*J9zqOV0qc-W?KVcEL_1J84jAyfS^Gr z=%r``lG7H0FOLNQf6Fe%U)2z?YL&dj!GN!Psc6^SkF84+05Gk*JUz#McsUq+rt>Up z??n)!(lNd$hOKVZik^o6U%+pB@)Te8@_6D1LBZ-56icY;29*dDR}s<|_U*+R4sK2l z=vQpYFDr{cu(5$m3=VY~SSR{o()1^ndC%yq?w-RI(1` zHp{yAFXCBG0V`DhOuxQ`u>iq{*PF|fa|*ThDk!zi#DVl9tz`_@cp2Q^ELWoYr`t_q z*lTgxEwpaJrgTiJqnsk0Riz}uePcPNEnu0eih6v$pcg)YQdr#`RPX8Tt(xP>x*yCP zrmR@@Z~w!@ZcZRr?aY{zYe;W_8yFQkRaL8)SHW$TdV&!|ff5oDo+}Z;*Pcm28{6Mr zQPfXsCQV6~gH}2zJZNJ>wyRrfun~!(8+AlgV3+(Ra$GR*elg|nITH2{2UCfYjhy97 zA((0l)6>ti+T;8?dih25=J(-Yf~Nl6JM*9fE6JaQ69LEf104>k68mW|@|lgHP|vW| z1WhpL7nl2wxbU2#_yR32JN!<5ogMO)LT3_Vs($@;?ULG&b<0{hpInrAQ!pL zb>&re>Q`}ir_$gnZYUKN51vDyWPO-G;l$M*{r#=kq%1uxynJ?cq1l_>+|T>L>IXH8 zrk5vwUUG7c3?Hw;%)ZyOixV|oUnQj=DH@@KYzGv!43sP`wg+@aEQfyG>IcEHX*>gQ z$_2CTpEe{USW{m$Nhc)NeAQIhoe`xCttZ$WWX{@1hTm(%w&UssP|a3jfxX|TwBWp_ znHKcB%!3s)q+1F|%t`!!gMf#cGTg=fqmCtJKPjj0kbT?~I?dpD)3&q5!bZ@DV2;kA zz43AIseqZO1#VP50H1;kncR8#AiiAhK{2GhW%W2+I8S5hdk`2{}>`II2?qO<7h zHgw~PVBXV-nb%Fp~2GSE3fX`0XgF0gb&+*F2|07W#J9NQ;mb-Hzz0cYu-3QV=>u`|2&(rp3) z%F9cJk=$|L0x(H5voM3G4A;v9CZ2*!rKN8%sA-vgSqveYzg{FSu*rg(wuXrUOLk@| zyemq6bzh3UP~axRg~u?5M@IwF`q5Q7Vj&+JubPvlp`dGjyI%%R_+?E8GbF$2klv92 z42jVzGHUjBU?~%__CLQ%SUALWZ^|LLQt`^LT5vJQf5kUx_&Pc=GRYai!mTQbl*rM5 zYp>p?M9B3>wBN`lID57w7=cW3tfc`ub&##HQz{bg3>_O}GDh}>x>uPXBPDgL*EkEH zWE<9LBu^1Z_%$aa^l%TEme(k%1(0zdcj&hKmZPe&!8)BSv)ZjEL^$FH+KEX0v zuF)^7>U?-=eW4RVK2}&6JfiBS&}p@=W-meY&u5!K?vw=L7KtyBpmZt}rr$T`a&_MpJm}chhlOOH18nT6C%T7(gW) zAQYl4%UTPE{;cy0h5$+3{-@X-6}8ihQ^jMQ|^N##i_CLNrdxB}o@j*%XG zj^s`TNviwDC$_q@bdEN;^U=rYBxc%)|IYS6vlv^z{k-=&?{_d23E>6T%SX!j7oc8^9 zVIM~eG(e(Kn(Q(XNd%%HmluIP4Qbp)P*5%lxsjM}ERlg#|I9biA`gch(V~KYj2HdS z?e*%+VRme+uScCqxpKAxJVC%nf1@UUBM1=b<2-2W3JY6Lp4Fy4a{8g#r|-t`U&TIV zdMsVsc#g@%h?jU!K{XM;;NF*(bQ#Yq<=}@#$J|2@h3z-gT-s1D@MINe0zUcr62zqo zyOLr2s>w(NTMp&aesP1T=gEgScg2|nB+SqUclK|Tsi)d4-;*#}351{G1F3XOL9r?@ z1~>^3zrbTSbyKK<%gU21s|lPe2Opx$j{s~&e*Dk$c>lV%;#qQkeXg&8c@LrBNiiQ( zh;P(7(@C-ged+h_&P!CKtFcP86gS@#DF~pT?8t#_J*eKlvr~@vdYDH`l7x$QZPOA| zaoeex*Jw-zxG#{oJa0Z5HW?T?-e|5O=cyfYP46Cu`37Y+eJrt4yx9AX6HBSIBy+x9 zDtri=9kjd@n8T@r{>_F-A|;NW3A{9*NvVPBm;yE8xv{Aq@K8&+AnwABGv z0-W_lY=JC#ZhRQrzb)ScRL<%(kHfEYcDwAvZIUakuclX49+SPE6NwCCO19U!dF z?3GtiSNBLNK(=P}bxgnezQ|kdPES#dqm9)czQM__*wvjg^|L{++PdN|KjP0e5cAow z!a{5wA2lnTu@fE9{QED4RU6oyf0n_6h~(*C1BGOpVC86wCQazw)hnS;avOqTQB%YzK8I~0YvKP% zmca%jVo)K0+n{>O0UFHa;th$qNaA?;PJMTyNko7Xo&-j>{0BSAeIU~Ylqq*OOhHV> zG+3;K`J#6|>W>8G{W@7V{k0HN@sBF$#u63jbN1gPUX<3G2|Gv^n}8Ust_LAY(bOD6 zf4NWmTIq!28UIx$YjN-vSn&|+<1d%Ud@}^jME6j_0$Ww3LuQo<5k(9sT|R1sZq*%N zJuk(5I+OTBi`m}7-9lY(75@#OX7q^5?$_TU8U1}*RqN~Nsc8676r8{V4^FELwvkY% z39p?jFv1Y;*3@vSpXR5oQJLp;7;Ubr?h&>biF&^-A2@kdRn=|TP^rHlD@0ClBUaUp zSZjCl%fODAbNbX*eftgdaaK*tq_uhMR|Ibx~yu3!#@8A9Sy7%03&U2n| z-gDP^o+G>3Y0HfE^5f6p0r7!}@kyU~va)fBV(E*$<*LHUTMnlaKBd0!V!7GAPRD@U zc&^Pp4v9+nyv=XQxQU`z*XHgyw^xWwgWXx8i#)LUG2W?aW&$#rHu*0Z7(SV&i(7ybJ_WIf zFTDA#O}6E_ z+a8I-hv7E6P`!4h_;#7VRY8d@^>Y_2Z@-?DtpDm>wGsiz2Ek7s@F^&(ovuEZ&$Gb3 zWrtoR^)BNpp`wv@X(;IObY@&V*sRokqxbfbMy3mrT3JrnjiP z)`P2+=R8B5ZhisJbgjg6qK!xA3;Ib2NSf_wB=VpjfOnIoQc-u2gIV)qv>P!SHh$V* z^O?%)rcLep4R@3@?kF^WV4z&{`izu)hpOCHWcCa-hAd?cTIN^VcM_O)*w|3>+JR%r zT@$uB7CT?3(VU~rrNb<>dA6AAJe`lB%`NFIN4ITd4o#pV4&5ad@eF=mzIxZ~^4GGm zddOhr8@O!R<#%2ox-Hgk12|da5?p)faZ>UsJjlXc$(q;?9z?mcs|}w#CaujoK@$j*2>Qupczs7uwnMx6g%5LMn?(F1u$2z-1G9h#Slm+|1$ zX-=om02$Wh+%OWU&6c!nwA#7yNMLi7t83I1cd?bpA_DWaCMulJi*0J>YI#DTR_T5= z_m*kq({pWe?a3_|qB{0?XwyZqK6PU84}9kD;Gj~7$M@R!ioc<_Le2iD=(Tq-OY7&H zU8ca{bANT$u_H7v??m+UN{TeE`0VTjI++&^tXbQxXtv3MKJrm4Vz+7C{J;|t_4++7 zUxOY{Rn_WmdqHS+K3p@>!HBG#M^xy@=BE#oee(z~I@$P2_bk;;(%6%WDcv?WOSw|C zIe7hzvkwLHh#P(1%)J_Z&Boh1MNX*sZGwCblZEU-m>jIul6*9qL$Sw%mprb@I!pKr zi|g&n-#Tq~9=Ik*fAlB^M{#2NjjcR=mK!xERliEuH8(XxZ$> zemu(8xykB;HBRaaj7;}+R)k)1d8l-x;rv41`))1^Y0{d~va<^a1FtO2bs=^%KI#IU zF&BTylI;C2)bSH+Y2*#{T{MrAOYB|g-c=cKK=AoaCdK=mUa8_=I)e&iPFJ17a2ma? z$?o7<-ZW#|fz2YOGxel*8lVpr_131_8s??co89yms#Bg>A9Gx3hf)HWu*lNR2NE#r zZ>wZMyFx3=ip!@z7u^>7C}2f3ql%&;F6b+1T-<>Zu~uH^ukB--tFK*>d%f-9&YPzs z8;w(4UM|7ka#WY0-ojMNVdadsI`h`AT7Myo!ticEuIj$3{g@s}LZ+K$n|7|kBx&L+ zh27>j@$}nvne)_n3^bh^t~13Ec*do(dADr1=BgE61J7OujvPrNFXH9mn9~+lLsai8 zMz@lMOsFko`R9V@z<5_KBVG->&PKgc_jNgFAMtX#G~w~E7V2KP&0eQ&&a=p6Ddwox zW{MVTNk=36B77Gg4Cc+2hol%i{O#KW9#P;2%DaE*c;+*|2R~m%BO=1-xR5rtXPmAi zzkXs#N0pP61wX~Q>gM)aZ|2!9N|^gND(dZaA->LU%}=_O@4U?HcpZyTeZ9`Mtd@vj z*}^6IR&Cm<50dtMCcHZ5v%IMk!@i^DTJ&cfZDL6x00l?)hmxO_RLMgda8OI}}!3 zbco?u)3G6rOeE*LjhC^mB;J7-uSBy;wJrDf7tN@xmkhiF6XxRL6)u@>@bOg++3I`S z%}rNPLGaqSu%aSNNQeyYOhlz6InnO(9`BFvfm!~|w_5m2tQ%gL%D0BlebX!C;l9mT zc@*4vmRFJ-OezE2>K10d+7l=yk!9p}UrCXRJ^IixiQM{2RcG*@Y0!#wU80b7Tz_88 z`t7b7Y9S()BF{N5e77&OW;{X;Q#og`-L2j6;;TPJ(d}i=sd)+AJ=lD=NOrauSh;)P zmA>CW3-h=aeom4{eb4X((!qy|2w&1Pfea>GN-DG%M{Hx_v2b{@3t7WcasJ6NRRU#V zdR2ntqyzg53h~aKyLD^NNjyUcJQ6KS%w?d+U?|9_<{9CAIDtTkNGVHwlb>UUI3H`c z|D~g9p;^bQvtG9Oznl9AU-I=wyGq}?wjo|6Qk(bAEzl(rSRC2lgV}rdYE1>+x0ius zV&oU;Y77+>T4{D3KYyBJhpC^(!Ys{}e<^Jm=`xS zUnD2v37VJ2M#il;6fTR=orZEd_MFUzBJxaykAVh#@d*p@ibLr0EWrIhk3yq?!iz{vogntQH%6)o?5 z@ACNM1xl4=O6YikkGJsNA;E4f2(G24d_d}Il?kVbw~J9>0*RiCh%}K>kau=w4#llo zg%`KZT>r3&T4-(R^Xu1~sb-kGs7+7g+ALo!a!bB$q4c~wQ^fU^H(#2a?UHu6qXIXmUo#Rgxjz?;VZs!l z50nN-;pzGnn`Wm=#BcUYT)B3p!cA7W#WT6$_HK0XJFxEby|&^Tmp#6{JhD}oYUw`d zj6?4Dr{b984FhUF(z6C|(v+pw=T~Q13nyGjiP+_AtT)$nOPXzzCOPSOx*Zg<59;P! z&Jn5SFY%YA=9XXXEN26e8G;PiWnXej=*j!eqW&bKVtnBg(PPRByzHEM627cEQ(Ufl zG1rM-qqkY1qVgOKO_CwjMck~>Y@O|t6o%<~MvKO>p=(MybwYNf+$@P;y4ti$9u@Bk z<=@3`@KtK0Qn;MFe(7g9s<{oPcJINX)NT|$O^lzO9;$&9>tnJmEMtJe! zn@pS3n(Vg`5isQ{!v17q$V0q5iqpLN^B&#nDnIt%UOYu0&!ZPko2jg8;=aD#@a|e8 zQ=_&2I*%k`yq*BEfPHgyF3ExFHrn{fz5%v69d;Hn4J9)}db$m;?mBI_xT~>Tj z<0yU3ii&XW#?-PmZfj);m3{TN6Kcqf4t1;EI~=g=tmDl0^sRbg8~ObU4Eb%c{hPuu zhay~GGbSjC2vN>eUrP-%if;YRD^FxwE##Ht7VOxaBB)T$ z(z86S@IyAsXKke*Omeh(<>K7;XGxf}3zZ62`#NN#<1t1(s%$Q1o6TUX@X?yOTH*{H zeg454ud0(*79G8{Ep1nz*JcT^W#{uV_(vy^7Jbeu(GXm^Pl#)kg;R@x z9M_Hw9kq94dCE?^X-JwhWl{?06^m!#m!)*;C8h=m$%Pac;2+KS9L%%V<2?TAW7Jto z8f725J6w3PUarN|Apic{(+#b)2e>hu<<;39h0P5w4NPe7&7fo4$4|+6YN?gaT^B0K zrX=@|iQVkoExC?t-3E`y${On{lJkOug!d@Fi!c?vbnl?F;TgK;EK6k>MV78utq|LC z&2lBLfgDph2PWw*xk7Q`ho@qTqAhy#_M=pZJCk$R1xU%t--r^?c$o6^8ky;1Y_or?2}R+%L09{GRr?7l9Vwy*Ab)+x9*TSi7F zP?FN+$|DqKt0=~x3ZqcCRYBX`;`4XE+>+tuJ)aSkp7Yi{dR4}aWe1Ik>OPg^FBZ9) zXu46Q0J8lS#%M|riIz}jl6WuD*kKR;RluD1BO>V=L0 zf_kE5vo)$eONDo>HtIC672gwm+^yDQ$84dQE9Z!2&QsQ1aV0~bmacW#?Abad;&HDe zv_wpuobPmCXc;@p)~&--WVSKP>$==Z5yEqGGl9|Ur_UNMkuE>nDIROfSQ>jCF4}C_ zS*KcDcI-1&6+2HV+EV@U#It+x{teQBh5N%f?bjaK`XrV_@#)rQDFL(Sm=7I2dSZWV zf?)N&M))o?%i+#BkqDlJ_eFcU5>lEPcxJJNXf0GSUK7oKE70WQipLbQ-lDC1!n_Vp z=xJPd=gxw;F-2@&v{dG%VtnKkAXG=0R7O&fjw-S2m7YLlksM3_On2FN<3a1<&aSQm zQOUfZ%8ySd@lKQ2p60qL;%i7(^6Y**#eo%<7g24eU+s0y^{MCf^B2R{7oPNnX1->%5H)uI>UXQg=OS(oerThXWi$%7VHjs zqBbKh?8SjZO?r2Q=V#~~!}0|e7;r^r@U}i&_W1?Ft*$}5YX zSnszpeP&r%5PF>?(H5^#-|ViYm8)!=xx>3<=(D_tN!fdeOZcuAUu2&9_EJf7r;5i$ z-XP60(gxyBEfza7J!gG#?^$b;9b;*3L>HCPZXa9zxe__%o6MI7Z+_~?ErD+dQc!z0sW%75mJP*z%&xMvbi$e~*;vS0k$ zKYfsht(YB6&!>|*fdz^pO6db%O(&>f9n7Zc;S)vNG{+Ej19+H@^Gq`)<+W`)*9U45dcJN0vR?7$bM`bI*vY8Goi#HDSLoqJ0ceDv-- zc{;uGxtv)o+g&0hiF_>s?&vn|?HSh0$2*(Jk}NSKnKvLz!-vfW-4s6sbQAF3_2eg; zwIQ!eYN3a)buM?Vjr$>X!j!x6@f0i8x$f>;T;eTKcj%q(kj$07K@u-l6nbTk|SuC zT)LhIYMC*b9XBW5adNHK*{gf`lXE+pIIf*Ivs%*oo%w0^wRNv(`FSrE-{{klCgrh&45{EEjeZEO=8~L@@|V-X4N%ck?#)Pl93PLJ20;nQQl#id6TsC zz6WoW{WkuXSiSbkN{H(1%`{gp91`B-+JibKvvB?3}dyglq8I z6p4s39C}Qp*zV)s%?mSeb=5Qq)C%M~Sx~LCzZ*Wp&WjTX=SgP%)Ea1EVsgLn#Oc>1 z`}p_hyQs)vZp2G_SQYPCEg+!Dru#NLS5rru#hU(sm8pjAHHzo*-SD2Mbgq2B-8ORj zTOzGij-1tpHU)m_s@u(W<802xyaUdy{CavyC%N(i&PQRs8XVQWrs?3qACx4ucxGta zE)i9}yYq6I{ci1yX3V~LDrIkmx1(dmJdD13m8a<=Gd`)=qPl9@wA=|`c9Lt?ieuDc zl~{NBI3zm|+%7+R&MMPT&e7b^MBLTFX{~I2@KLKn*YmQxV+j%}@GLEjj*`_TfM7Sn zX4uLyZCuBv*yGCk#*iysi>d4e=1sVj_dQpnWE|2`1RXVR4+=b@FClHZ}uIy-gyNqUIn{*Rt8e$ zrTFN~*X=AB9P~SOuagSi;4<_6OxCl7Wu`~3KRlgUK**or_T`aLvdP6P&tbb<-GwhbK%6zN)pkOH-o}#$C4~0uDDQ$($#+;mIK{DAyxwA2|6fpRQ5S88f#Xf}LS7TCnkHOWokz6v`UgEZE@1~eBBAv!sxv*? zJ5x6VGcMj?BCJCps`GeWh%$^?4f|{~-m++uEcZ+NU~`|4=bLx?kUau?gLph^TK8URKTr z8y07{Ep`rrzPqN;lk1T|&O2JCGioG!^Q{PNT$O06#rHN#np+1Py+-D$TbqC74r!VF z`D@Pa_VDXheUmvRzI-<3$rG0g5BO*J9THh*nE6zW(>6nlnAxokpK_0v%4d&8QQCQ) z&jZ#Q$}PX_aDzyQ?ZuOm56t&%5GPZ)r!j|$>T>BBN4u74=N*+b#Jn5|9mjVP+^MW+ zJ^ElPwD2{C>p077jPprz!R~y5*?fX`WrSx|AKL4YJS#oRbL*0J8M2g5-hyl@atkiM z^Cl81y!N6iIoWfI_VS>VyV>>g-K6r$Al9OoKs|(Mh@qrAE9znv|4{Psw-m}KRy=qt z&*A*Q!?HcB%b@AbffE9fZ@W!PEIlsUopD@5o7Ayk#zPaD{T}JniiYj`PBJ^(_q~>s z26ucu%_+B$&v%v?ut*J&bKXXsSJM+Li9!4UsG|OP@r3n?gH(GC*s^Lth}V8S<*3- zWxkn$9Ehmdy`7%2rDR z-t*n@aUTUiw;casdO8faZ&yoiDNkxoR`D@!!H+c$fALMX^K&YlwCKU74;c7pt{(St ztPZu=b2(g>THT!>V!p>U6)M851_H~ytXmGQ{2)wkr>wB+Rc^N#eR~Ujz1(^}Wm>fW zeF8~`=e3^ff;>s#9LenS>2CP-%qo1M)P4W6fTQtcJL-USnORHNTJd0FIVq-uMAxNF zQ$cWxekAARE+uLf&od>+S$OlQdZK!TZ4Ya6^Bh%*qPWIVlSLJUrcVf}#WkzmuBv@> zr~TvO60*J8QZ0nUbV<%vyeP{O!}I-=@g(K9u__^Yax##6 zyrAU;$T2m-#S0I9aJzCUN zGBheYuhqR}tv>caiyE_OS9A2mWV>o&ilUA)6fLLs?pWfk8zx`_kzl?=p0$><__{1G zG_**kgx8|H>%_CQ_)1Im?NybMA*o1S&2ylVn664pOw2L(({W46<3x8QbCo`2Lo_D+ zw|4ujMDXyHA;?sx;6`5UewNDMX?OwFHo+=jMkJZit_xWHZWHp2b}IYx$ie zQhIGqc>Q60(mjp&sdPO>3HZF3);{O>yH{#9MH4BvXfbYA*P!v`d&8#(SF?rJo~6e`37g0J*%^h zFJ{-GU2DYW(iIlF-7PcHcp6k-As!uRQ;=5iJ;d0j@5-8}6o~)U4=wYt0rdXX>X|PP!ZP)!4 zuQ&oSii%EVU8hVn^$UFYQI0)N)6y|RAB{G>_$xe)zS%s-aTmM9UV}m|dfrtZ&esk^6oH&5ajxo<;MOvQU&ntXcIIjgm|Xk*Ja{Xg;Nn(lruf zq%q-3eV-aL_fsfe)*XokhzMH_5n<20`p9>o_THA!9%CR zR*VLZn4VIPxZJ0^HjaBLymM!{?Bk~qgWu39_1cg5@l+0?M z3D*0WWyr(?eOT2;3|1hJH;5<7KmDyXq1ZqIM^fUf1(U6r-pV6HUG4u<& zw3vyUAOdf%>1sQt{12*T;&_?eheX`)E#4fI_sB0Rv=hj^RlP{4$Ss3?E6wt>+gsq3 z;}-h110v=ka`^;@mhN3{?9p`9cS$M(galV3foRqoHr|z`f`aE1XPB=)+O*-a^3oYQ zgpPU!&JN*0-ZQZrY_oV3wb;sA;ankMp@Fx2%^p`Ph-S@w1anB?yE{B*^w-y>%ia{I z6|Q^y`US(m$Lq>I20fV-f;pf(8>0EFBzvLzp-m!vLpR|Ho2@~C*24RYKOEng482R5 zF0|>zxd*()Z*E2lv$viJSX59)Ox2-i(c8Utgv=m+h?o-A`3PN*SIz4#I9I*qTsWwE z7qBh8&PKVCL{MUtB<6hx`Q4T>ya*LJ=Mb>d%_t2yOi8WIJi3r|(Z;v7Zz$zGwz(s&h_sQ0M^Z#66RT63#X|u7sQqzD zT)UrcX_(<*dAEwznuYYE!K)d*D~z*y?xd{!9tl0Li;d_Txs3K(Mn>;dtCYzy8s|8u zsq7%xjs}2ir|^&rS)u5@K-zi^y#V+A*&njpx;3>GAd>lcvSpapwQqS8yA{nV1w3!m zT0B;}HeXGNbN>3hy+19?{MkV~Hy5|7Zmjw882^m3jj_O8iD<%gT7`Lg_?cLZA-;W= z#T`LGyEblW-W%0()?Q|bk|i|IILR{qvg;awE&SQq1%6UXVNnW6Qn57a$jveY~n z3F~E#Ry|rrc#Ni!*RBb#`ktnuBoRhz`xPtZb?dj!jpJo)$V zGloPEGFWdBC|PrVCZBAk0*Aetd_B_wZT7@tk=H+caHX%lx3~EVDQ3r4zq+S&_ef98 zOC)+OAg`lwEQo&jRV@K~a)kGrl-;==dWO}Dn2H$0>l><1zMmN%R<+{f({@htZP(t% z;L~VUH62VckQ21M2#R8*T9?^OL&@wZ9(6&lTs(f=N&C$t-diab&2->7_-H4(q`F77%+H3K>q$Iq`3VFn2W+=v= zQCyI-a86`&8tcIwyvbW1oL7un^2}}Kl5negPwmg8ujjX{RQF^wy8w5h;XKF-SWH4Z z-^Z!D#a`y+lC&2*tFBAUD1BOJzgmcyWzBY@!?UUt_eO(%r}B=OR9+&lRhHMTc^m$D zM^yRg$mZgg{Bm6u`+!?T2uaU#vj#3$hI!#@$+O>fI;5|tTEc&zW6wI#dO|8<#o(oN zvoFlw!OzBOchz#Hjr--e(Bs=AL`pB7T_$MG&rM1zf6+tH4X-ZPV)J>n>esUxS3}P{ zB*uTje@&rBp*tx}@&3!*I@WnhcHB9!=sq9xndx3a)9*$LIT6mD@( z`QHQ)l$eu0r(EEMq^yX+U(fD;SZI}snR@2w20ZS2Hz7zkEJq>&y+Yc)c{8QS3r(*x zZ@1OR9zDE@o=?^$lST%UaYj^u$a)cBd`I_XyYpYZ%(%h+&3?b%O5MtQ)`FCRC9jxf zMr@t;Tq4_>%qcCy;l^V|;FonDkbI5gt1Nw5h#?C95K2M2?yh^O>7CQUyuqedZ`~~o zE5M(1B4_)I+qxIJmtppleOODxp}v_$@gVKBxHYTvOoSG*NI1y8TsbRMf-__;ah6SK zW#qnUT^sIARm2x_s*gPLil>O?`Je=A)ijEwG~YjPe$9;dx9oM|;$FnNR4x@RXyE5P zD^$oZLv@K}#pxaM-(vXr)eg*H-R@~z&|0vF+V=5Io-K14g0(HVvUFP=Hl-3!&gncu z+a8s@T~Tu3^6iE9nRAIS?|AQcy*Z*ScU4t)DM&>3ydik&gPt8qwEGIGtMQ_?k|`)) zf?iABC03%APS+whpvJRj55|+{gBsxhQnFjOFmem$&v$ouOFH8NycIaG^^o`irF)A* zGcaYUMl0>`vcli1&A`m$A>$+P67egxw8dQau-GZZ?z-Ib+geX=@{nEl@XOy}>%6`t zLdc2)Lvqjn91Y11N_UY9&AntvOK9=bB(a>#f^2?y8Rp)s?fdp&p4>QbZMBk&t5_z! zZ-biYz5E8qdZ6_Dri1g{77$fV$LFRi>Ev=w2$&G#wZzdkWdeJM-}g9kR? z0o(%w0XhJaV{6>$plyZ#6aXs&l+Y)wf7|cWfbSE0Zh#6P8vyqHqmT>yr~zQT<$v2` zX~0(nkHYUM{v|*Z0QpN01AI#RJ;j5!E&sOhXu$6Y!2-Xh1nPh~0NDMnL<8{s0>CsL z9sEDm`3$-OeZ2v607kVtlt=z_pt1murhtY2k2b|c=FchwRG(D{Ujo_y$bS?aAlEB@ z6+&uUbn^dD#_t&+5$Hq)Q1c(P`EY$1mGy?73L)YDgN?Dt=&wq&%3p;j27vsZA`W!0 z2Ah8VtLMSi#2~jCpbLQfpQ97xe;%MhMDky?_dvM4IsmZyKj5GPU4PKof1w`)J|m$3 zcma@q7?Tcsg4AaG)$b1j)n+UJ!~>9j7?%zbP#yk_;{fzsR^UDNpWVl0_kq8cydbri zi~puR5Ue(n9e6GRApbBaIw%G`{uR##LC=mlt!91bbm5 z|BDJzljDPQG*=))x3>BMB+7I(RvOr7|HktPAd6F&Cjib$nc7#ZM zmOo8C-9N$pAsVwz0+2rwW&^XCL^YLCyhoZ~g-I z|I?7X z$8@>}e)m;rF1^3~KS{W3q8y;m+1t z=r`U-L6{nn_VF|lXC;7yzhwB0@=*ZoNyGE0w1223#cDt&0QnOTWyFEh7l!tk66bwW zMIurVs)EE@Z9>AJ|NIHEjFX2hs5d3^h{Cieh@h?5aq>CoI!=Bkf^@c4<81S;wtA!_ z+5m~QST_z{D51_Di`Y;t%HKYpFzf~8bpZTcrXM+=V4KTyaI$@MmOB#lX4y3JJLUR%`8(_%t~G}_Tx)ha0QtR`1N5<@ zB>L5;w(n|hKr%l`jYwytHvaOw_As#3WcLBkiOF>9B|rG#sJ3seOhRJKR{y`+zE5uB z$+UmC&RnK&?KvF)WO&Sl^OK7Rpf?a{ZYK}~-p7oz)#i91UtcX4RBs@S|D)rM2yLoK z`%Vmc)0|G-#hI@`&@p|ats>b5iPWL~XZxSO8_mfW10riZ#r~>W1Dpmx^pKye>hTyN(unKt?5BggvN-rug-8oB6X>!jlb#A z3y$qdO>_*1)R`9z0R2uq65eirOMVAd`!|)vAm3gwObc(*p^tI288s36f7O|{avW_= znmy_Zg0R{iedil%!ZkT<=|bNgBfdiUzXaUl?E_zRsnq}==hP$J^(a=`qZt_=PfZJ7 z)1iwAw)t#4_Kz}}j|c7MOt9^7+o-858ms-Q(%y}m?sUmBjqPTKX)PFYY`Sl{G%LU9 z(IC@-wD+P|ZI3<&#+fYpO?=TJF|S#XSYr;@FNQW~e^WbCuGcZgqyxLlPlxT%Hfysz zvD&{VOm)(1lK6HVQV{$Asmc0?wAN-LJzedC+U@D?MB3_dd-*B+qKqWj3QbzuQ>@$j zW4#7I-w*lT|Iy#T)FIAfIo$Ji4zfdEqO-LIi7{lE5I<4yypZcFgEWtGZeVLoCW7{b zSfeEq;$tdw8U=RyfuOP2Kk5}NS=39~4gfOMK!1p~Z zQ>14_obCUL-YxnSJu=nEa+knrrh;IFG4qpP&V#ho=V7He*%^%`5lFlV$C&w?B0al~ z!T$ME#M2;Ml}71eHA%8H|Ddv?@fT;b7-^|W#Y%5rMo(88f?jtj;!TjEP-Ubb@E%h1 zMF}a7GeXdDXDoBdTdLC#bj%rzziG(N!^Qs5`t!+SUd```(Vve@HR|*I2b!h-7@fO0 zR$gk-o%`!!J3z;Vf&e)r9#Jr*( zb`T<=`Ho4K*&e6+st&tH=M0yAeSyRpGLMNas+Y_U$B@?Q z^kL}^Jc;&|*w+ikO#e6Qe${AWK&(E)VE{7a09#<2-%}oIh&w-U57t(jHP94;j#2;L ztdA#gr#Fl);^29rJoYuv?HNRSXreOd?S$I-4K_G5s{IWZZp9ja{ihg7mTQKpuRmP~ z_kOtYlk0V{zuwRT^u1EnhvPWY8m-Md-z&eoGaTAxj@N}rYi~4uaLB(oy8Rbu#u_XD zo~IUR4%>#Ru0NgYeFT`Yj>kU09jnu%I4zBWN!!yg!_r?R;?QE$;63tdjdb_yt zH>8}#X!egYSYQc2rWzT}`v$6Q&~di=DV+F8c(WL6(Ke`VUjn_ih=+0ecgU6Ja~Yb! zel4hi>%i}5cN{b=Mzy~onMmF5fk95D-Qjq}n3`d8pJ4i=Hi;$KI?C~aQ(w#=9 z@%#1eKbrmH4Vl6L!0Xf^)p~uOseaiP1>MJqpF${yZA*ds%b_wA1+zg7IR|-SF4Y@>qSG zXcPq88f>-!sWf|`K{T@6NB1WgP`&pMy*7-do0{}@L#y?tOW}LrX!U<{{uTTu`u+zOesbK!2UZ(&T<>3H2zv?L+uJhQ& zfYzGy5$ob2;{?l$Zhs@@@B|}}YZ}m47(A>QI^q2P^At4VYC(GCmJkpCGg8T3A2BptO>CJtK{9iK+3_nY%9N4x(^db3CqfJ_$} z;d?u_Ez3z5C%%dTu|Ef3quqDDDBxy)8yWVSvEIwo=Xmy)8%|d>X~WMqL%%;IyD;LAe}T7K-}ys%oO%=oV}FLP1-}nmd8$dZ>oY0N`_85^B-xB(P#eu05V-jwd8^MHZ8;I4!!PX*l)s#w`3DG z1ieqgbwlR_z;mK%DEjw9H%Ovh~_)*VV~veIDFQNRBt8?&wk z0DsemTDS&d+t6`$EWDM5J{mRVH+sKc=y!Eky46V*!?M!VRyS<imyn6IKdnw`Wk>CeRnA5LxfwTfhjhUh=)pjftOh8$P5Go-Nyl%mqc? zD^w?$BN=uZvC^y0`82E@I~t3y)O;e0nMxFnK-XErz zEY1fY(}{ZU$-=gwc1ySB9T$ITaP7@<+=^t_tQ)<)=@JBOYq+f$=K7ALpF&^h;i~nX z%Xzj1lpMt*|HqAj5x2Nxg;D(g?qK%$!CE#_V*FhiKZjA zT@nJ{mauG@4niZ={Y^6AJpVhzluZ$UOgAcHM~?MZm*ob1VCiq+Gu4~}=6PbDKVIN< zX2fY)#$ znRAXyCnND&Gr~K<&Xx*jlVij-8{j^5xUH+TYQ%aY@$@rq3D6iT*l_m$N-nVH`RcuKlG*Rh;2)rt3df5v4V1TOC;DvZK6CgI+se zoSZegX}b<-gm29wZRq`AhSkau z+sJl=_l8)u8hD=k&Lhg_RAEW*K-=PS47@2!9e<RJ)ahDGys0Jz4C3eboB6@;!!f^0?T1U>TsjY7F$JM5dY~ zGpu?Yn$Zb!NotbcBB;Hx;eI#2xT!CC$s$4ywr7Igf{w%dR+t;y0k^rbP! z{uDa$*{nsXqP5^%eHk`$;(Wdp=Is=Jz6xzF8@1hmdMR)} zI`TKG4`O4YH<0!Ojwc-d8QP}EwB)P@Am6bJ_J1heu0V?YE+O@By&g+n=x8WFYE!I` z0{0{1k}b=6CDLA-fwhk{6$Xrp?!@%WS)XOeIpO&4=$HX~yqFj-)6-vaowp+;{#TGn zc($)eGDYgr>;U#iZL$SY`Ar@2t|7VaHc!|#b*a`^Z4WmDNWR;F3AZs0{ZGpJ554xc zSjLoPxx5pA{KH@!lm*LSw>{+4rP)r0&N`sKFpcMWkF8GD+vTPJKTx0)X1ybm76zLvuO`;y8#7}BEbOknAzHq#D z9;sgT+ZC?>$S<&hbN@#uhTr|jwuf;)#d3Od0yY}Sh7-xlw&t1#cCN{`;sV+JKT#eG zYYum{j(E*)E&GP#*sPik9o6Poas9USU(vn;c9%tM5AFPa0qj`^&kfk#?e}$v4wz$_ z=O{QWx58ib+fIxiE^yD;&QCHk^dJIxr-rfBlwl}*}ep6 z{1=fAcCU%if%zb~`H^-sV$l|)yUt9+Bm&m%->cS zk5mN7{z)<==G(5J#MLfSSq|*Z2*~?e?T_+Z?soxcNVP)h;km!m`_z=#y#U%C4L@|t zIF&XXYg-@#Yk}RGVgShV50j{a5}>tstoE3W@&)#*ISTBd57>kK|6ww8fa-EupYz7r zkAPp+Li@G30OTJgq=UQy`?Y_??|x_>0lPB-693tM-1bjEbvRV7e^a{9VJ&5$1FsJN z`G+y-0M*$ad7nSl{#R_zM^xm%s|P^-0Vf^2EVAeQqn_`_YV+aB7dh~qEOO*)1|a`1 ztPYw%M}NdS-Qnyv8Rx+69DtZ&=mY;SNC&Z?7tYDh@t;nk=-qnaV#jsQ0bKy-2mjYV zb@05zk&on0x7%d%2Xe12ezz_bfc&2#9&|9J^L8fNh7+Y%_HI2<$-DK}0W|>R{{*!l z=ZzA__5Znhyz%yj5~uZ4pp#dCw*PP+=m6RDOW&=h9-9>UHZTK>OPw}!0+9a* zIzSFHkZa+8-F}lLUzyVeM$nlCpzbg30}a5t7GP3+F(*sMe*>LTCw>aRB|sDa#)H2C zvB0Nv3Gn_m==g8pvCNsD2cQPX1|WYJ@_-+8z?fsL{Vn?cQ}`@gCy&AOHt>U6wA3cFf&S)xG}zzVj|TI8((7$7@MpSL zBBh_{UIvDye`fbGG=QC6h6b?H%h1sD0QPzr9Kc>LgG1AK1KR_Jho%Du=7Ru3(@F#L zL7<`Of!U})qofCk3jz;K4-yv?FxK=S^?-sVnjWN1Q1HL>AOnx8kBRDkX#KJFhoR+% z_P3$w(faQ%`9psXL(_o+^)<}zD{o-_Fu%`19S%mkq3J;iVn&cb0>gkdG(AY*M=;(E zY#)*Xf8fK8Ux7a>^p1CVKhwSA;Q$7E2j~F|GNbedFtiCx4`ApKnjXMVZ}KNYKgRR^ z278+upphTfgZ>7Yzt`_?;L-PVe*-^~eM4TaH0Ze>68s?7&+(?d@;?alCy`!`esF`H z?d5>^XFe*z59Yt01RZP|kUfDzcF?{M09wG{VHU!F*n}{c5cqO|;@|d915=>^pC=ds z-zRuHfb%|&@w5SMK94b90hxfJA3%@c9GZuxjh5}L^AwL@DtMgiHhiDp&jK6=ID#BC z0A!q~{Z0e_1WI$V`J8NeeoqNF0Y-jL@f!fh*gyc~M?@p!zX2?pY`!N-@3RUa2f*p` zQ-Yq)Dg?-25JGwq@stqSAan*y` zO@J-{GEu}?3nBHz5!gijalQvBjW?TcTLXASdEYdeoWtdZYEqB`@&L$05T-p3DUNzI zti8KBnvkjtS0o#L2l3XMk%*U!6KV?!pZRcp%=bv4FDP{Y$VBkXh#hGxjrqmqE!F8r zmiJX8LXUnz^vA%P&Tuxyb}me7HfPw2*_{AnyofPdg|rP>E4;I%3go_qglo+mH{Ega z(}~K2P2QpB!?or(1Ax!*A=-F3(%w)s$nJG{{z%m8rQ@bKUS0;&a~>+^aOnu`xtxF= z05TqYeK{X#t{A+2Wm%jF5}`A1T=d4n1C~0dOr!RJ2py_70N{6gKxG}cmBqgKg;pfc zo+cO#XY;;uUv=iqiqx6c2mt=Zj${X6cy0Z2jo{iGALOep&A4cdr+pmiGw6DbV+WptTC3BL`h0(+u_z4bZ2dJhe^+}wlI|ip zEY0EC!QtHbq4LM*&({VZ<3T~doqp+2+YUz~!E_m{8&}z14lWc(Ws((=WVvQg`B;Mm zNY;nrNK6m!w>W5XJg7?kxlU+p zrt7aX44Dx0-oI}{%j4QkVc^}qYQ6iKjQ2R#9ife{L*m!o&@pyk;A1_r&mILbdAnEUfe<{;f7RP<& zQ2FCuGZg`l@t`8spr60SqL5!`WH{~a&qoiE%$E0-DGE`9)X)3HzCz_dZy+CurX0O% zPWI)aePCezIF5^k%AfF>xd?!a2Svg1eXPN?t?U;XDVD4I^U;G`Pf5_hGPoAB3_3qB zQ5bN05S>zVEcmgZ^^#1M4$2=R-@nM8XtXd3fQ$!O??w7p>)of@Z~28zE8NfYZ5@rp zNb#44eaYT^UDk&|Hb&PNO)_Tdr;}>U2jzbDm7I?!`t!!Y^Dq5B@y()d0AxH!GF}Y# zKehexlt*dx(n$h(eJJp|+Mhq%LC(jcNVdy?L0P#Tr~2!oblU53`twV}pA5?DYX_G- z$oR|nm-L3^Ly|EI=zM&rNwx3i4Ygg08OJZQsuIom%M3hdsfa_8L5FDDZM9kbS-mn2 z;HRO$zdx@k!SomUW8nRl>tC`lt2O}m7$36V4}SisfIcuBt)jr&NLyWYuN*yH?MQw0 zM~Lhb_}xq^8Axx zx`ZIrY)LHu>@t3o1mEiup?BX6&o0FQvLn(=Ghc>O4;dS3(;WxZNw-)rXie%OSmS=2 ze1eQie|i2z?+4P%mc9cZ6Gc_r&-BPFn=dX~LlKm9C+O-NbjLm1b;j|Y8a zJDW<8Oxtz+4E-NCQ{!#`tO3n$6DCAc6>;E`pK#M((g51S} zMaY*QbQ0d~c+{dCNrCSDeuN zryqR)57xf3{hjOIRYyMV6B}u(j6=#lUmD|jbg(v??NF?;gSF%)JpT>V0jy6&0_#8d zjJA%|MDokL#F5fZ$A_$yHQsfmR{Nkl_x0h)*u&aKq_Fml_vEa5v=-J5`dwJ#13Z#W zhRj20z?vl_06SRw1J?Y&hB2*$F}Z7ppu7Q(L;0S}G^}}n2Wwp@0JpFjOE-ccU-gmB?`vde(%BY60Vo;Rtp4-vLenMtpBG5ckfZfF^_EPw}M5f1yFb~@$x*YTQCsaL&yXrbPvG|(B04YFMUxR9{q^+u&Hm~8yewfTo&fO zSPOmoyk0UGlA-%ROz%c8UHiQ6?UM}M_wn7gA1Ys;+DWaUwt+ST~4K zFazQhECmPyP6MQW06j*}K_1==tOTYZ1L6m;0`5Q@g3o|DK+gy<3D7*Wj6c+oL+efh z%NX$WCjjgR1Oj>hqs0iomXFp&X&e9_eZr}b1^n~30KNex*Z*IIFbbvpyJP@ga&quz zHwM4@ZUFeU{}upkViRaJ|kHMe&DH7=#!p?wmBKL2vVCN2)^6ZBlvcYsIULe$BYfnRgYczl~t zpWqma^+-Xu2KYHf_kZ6l0UxMw(5pdt8H*jjx0ND9V^$gf85_uvM8|zdePJlvH~gGa z*mq}8mF_x5dj0LE0Z%x;j{v_^<1d=vTRa9t>Muen)7}sIE{c9vug&#C@I;;Q>6E;9`TY7nEDT|FnAyKB!3CTY*77q3C?}yr2ijSN(;P=?B}5@-~tT z;1fv*{-99+@W;driMCt8H>37@7lCimWeMiJeB)YwjOC(G9DFo=6-DagYRP?&i;?!i`P&T-m7=?dw7PsmE z^dUyaF#dt4uUqQ7y+{uD{GtAPY4635XoH2rmL0DC2v zcuW1_M;EQnh!lda+Cblwz6z+nQAMI95^u`&OFdlMM|mB{Klo+Mh<-&^3jklP(NP}v zrk5Rb&Qt7bmO*u5U$Y_&1;Ksne&55mG&HUTDqE)8@j-QQY5RK_`Z|>7J{iEbYAK)x zM;|Nj;rc#rt3J=~7r(8Vbhw87*wAuW;0Kdn3VtCbF!v7p+%tVzi)0c7&5L^m-(-ob&kqS_gd!< zF)GUdaWBr`JMaxlmo|9m)^@~{bk-Wbfz^SPFfmCIha$XvStMS?+@`DUEnO$qga+ay z%z6jqGV}Z)E@K9WI*8BEu^n*oi4AUyjT=^;lDP>n9~X}PQVkJrC&yIlUVOi9m-s4K zx*JNY{t}NOi`+{jHpih3qN{cNB(CCi(0iV7oFa61gtsp7Ax6wc>g|2|NAB4dkH2P( z(^YTe)%Z8@b&Z>6SoNdyAclkZ1_Qym%0ta5!Wgqbt7AK$U3!6+E!QsyEwHl<1f< zYW^(00UUWZfPQ;?g51{fMe15Cc6zw8PIJEhC*)Z*k5?>`?^mHy!zCDbH43C z>6h~P5nlRjEhV$6;WVq826*}X&CEe#i*S-N7^_-zv^(}@UF-ITmcp;Tels}Mf!#}q zxA?$RT@80sE8oufPWjWO>I!o1)>xS9LMm*@58B8|Awi+l6+2 zU4;+61cx?bIgI`A4cX7l{eg43817{cP`4O8aB0V-ySWdciun(~qx1lHowo!Y8Pgnp zB1(9fcfyA(h8KAKCUP^8y`Wgenh2fkWWeuR3aWvcV2I2o?8cnvI(U$`!Pi?3+#m{g z&-o2Owmk-35SbILrxSVb@9qPI@Y0R|;q=M7b5rs9q^%Foci}29-N_iYst+8y+u_^I z0L#F4!K*RIy42CODB-#3R_XS?I*xH)7YdOdR*^yI(j~;EY4ROD(r2V}3rmS|jnI%N zWrz5PO1awQGU!S!m*zuF8z~Jslgs6oelYlxOSjZda=DVrHBt}jeWFUY$g>&8FZDKh znR+MhkGY@bew)X^IxgrzLX^vU8EnV1Fc%w*orQ3w|(m;s+C#CCi8X z8n*p(UZy(0DanGTQUot1Isx36DDOTf5}8i)fR~X4CuB<|ypRvyxI2~uKP{JJi^v{J z2RIc)fPCudQMdDH)&9{Ab!E_qKW#m-YRqj!cDnK5805i+h=P=Sgqq^nsxNR%UtYz( zJ3tQAaLoo)vw2R+ZQ}S6QTPhB=L5d|$?yPzfLzn|IKKzK!IeQBUmULav#Q=SGiBdY zGV~aXm3$oV%@@YyULKYAxuN12C4MbA-ohi%)xhCtj&YuW>dJuoKb&Wdx=3Tkz^3b-O_=EnvTi*FmLVn!SiL> zyo9!RdB|6zuONm-?mvD+UkYC${=IMN@%_j&`b<^g!;!JiZJm?gpKK^uKt8Tk?f>&sJVo2o zbnu$v*KPPhFTgi98s3B7*5e1>|C#pPHEf-&zjxwaX(*XT4%Fl56Hskczt!!Y@?8D@ z?8k=|?*p`1?={EAH`ZHEE;~C&ZaP^yYS!uYkMQ@1uU~v{W)8Efu^9Zo;h*R}+TV!X z`8>MX$&A%mbBnR8^AEp9Q99p-hg?pP-e&!~wvi7lp)a|Py6O$yLwnU4-PUpP_s0JJ{l&z- zi9Q_b|A${9cdUFs-oHJet_}pW++p(1b=7T9UHAke-A10m%i(|FLwHc<8M+)k!SNVU zP1|Pa?{>01TXL-H4|#+pVWSU?Wv6c`TcCQ+ZAr)-cx|{_b=Uq$HE*A-{Q#ju-_kmY zeyPve`N6BR@^S@`7 z*vjv~jvNH!EXf?9{p5-6^KxB`s*ZoIOeZ5KW0~W|m)L^yus=sL$sggbcue)ZL*Lt zS#n%17iI}~RWNRGFONSpMr z6T)-pOrB)}$#ECQ;Pxlg1*C7h44&_%z`GB`bMI?+Eam-Pht&{s=W3qq;@ghXm*+K0 z4>-{qg@bLP8D8=LIq++@J(7l(oxM?XVE&)YGe^Ya!PfD-Fa+PK8cwG?E1ZS5d3ya+ zJHBn?^t!vU;Wg&R^B}{gURU0Ce+>WdD{2rPQ@{U+`lPE-`HvRZa3}A{hl5uT&%=|P z)RNcx;>ka%5c!~k&zXoY*U{%B^MH+ZK5<|9quN&< zCTC>?j-I#lVas>U{6hbJ@*8r0o`U~1VCQ@7Is2v>4p*trUgjku{@DQcTkHH08Qj-q zaxVys^11DLEZGkikiN1_^1?NJ3b`aUa(#_}WPeLU+N4kNcFEtlPG)n>%m*t$fw8{O f_Wv81hK(0{s+%k8nok)>mS=u9+oi8;BisH5EzygE literal 0 HcmV?d00001 diff --git a/bin/assets/icon/ecode.png b/bin/assets/icon/ecode.png new file mode 100644 index 0000000000000000000000000000000000000000..f02eeb34f0de8ec0b390f819f93e9a2c66c20175 GIT binary patch literal 13444 zcmZ`=1ydYN6W%-QaCe6Qhr2^?4HjI2y9Ns`ha|WL4X#0hyE}vcL4#|6KyWA6ckd7Q zrfO@pW~XL*r=RJ5dUiTWLrnn_jSLL{08AxCSxo={!EZqT1Q}kvb1$=jSE#Ov1|9%_ zV*cL+N*!ozhBuOW%ISM*y|?l7Hg~rMyuH0S>|Go^EX`f5Io`Y5W}S$U0RRo4BrB!u zvwR%r9iXGLaMLi=#=l#7s|G>U@k1fh07oJsSxL%MQi?822^@A#R!%M+aET20vP1J3 z9<1zCP5DgY>#QR7At0Z@gB@MI1EM@kf!l!vxM1{sx=@FBlwdY6lF zwN?8ZPfx8hZzyrnAis^FCTH!8ij>m{D5?x}$;@^&jV@6SR+ZUjg{T<;L#V%ATQLeKL(SMOh@iGgz@4unw`jW6gXt6dLvKa#2* zm+1U=Vu6(78cst}PRUdy<{aeyHONn#k79njl0o_TS#nZM!VbrQI!^pt;4|McVyjF3 zVlVJ++ktFxCJo7GF&Gd+PE-w#%qn!A?x=ROMOS$h3j~0L!y4Mo!^noE3HCKZ+W?CU z?QhYHXzfWwR$(k`4q9jRO9G5|@_0J}ydNN(@mF-HIw_mzbkTXT0T*Xd zj9BsjRooZh7p}7Fz5A486cEOF)LG6*m3H>4UIijZaKh7{X+}mIc_6o8g)<V2ukt*lQKK6BHz6)S(BPiYLeZ<&7rpC@!#Tba2g#L2f>cI+!m*X^?&zLpmKN z)z4rsqUY3X+YE8Db-;JU^hxw_@BuP}P7`T?caFvvGLtG>f3-hj#+B43<8p(h91P=PS`)aJb^E zFlyavQK9$&Zf)P5GF?k|)dz=`tB`f0DA&o9;N@Yw{FyFNA&Ui`!=imF2l&Z4v7-G! zXHEupe2CI#Ai|I7g$o=my6s$dv9TC(==m;N-`gk>;s8dTbVX7ZP9%9)Vnq*!xzttS2|03fW*^d`}f{Q?F%UDwbcqyOIW|)2tIVdDU5< zr9g+lWhS+L0@}@BG@gkS0cL@B0*o=67mh^Vz6`Me)KY7qgnmh`?_o0|i^wBpD6bb} zE^BMjrEcxf^A9JjpX3thRqjb&nY|Tcd-!|uE(fk&@~5Z!N*gzD9(uH=%}PD3+Z7?w zx#aa@sz;!XdH@HuWEV|V4F%UZCygf(K)EtXLJ^LP=plkK32{~>`4^}$rk2NId!j`o zc^}G;yW8kME}4g*FU5hpBnkav8K8Jodbsfo!xC{bq%5OHOh?tZ1LQ~FU>s=fLjz?T zhz?9e*Dc`%pV4S@>I;8jdWBsjoq*kEImVn?w4GbA!In2_0Z_rdi|S5-?66=orFJA`j{kXJ-m<+@iTQ@4b@A{`^XhP*aXK*wwO!UXIsIHg-tfeUoKL@pGXF%*>+tLC`^=VKt-yav6*o^W0FpT5)W+=t#axwO zE83=pHw()H?x&9jgq2WNVo^HVfzK!ft^PiKLmQnX%`iQj-m|I6E~OBZC9Hu>hP$=e zDVFqF5*S8VtL1$qjZfdD+`&o+zXYLF0F3O}0ZYCTlEi%9ls53E88nNlU3E?h^iU2{n_6WgW$N19m8Yn(VYP~)-Y)1u`>}l_ zjSF0>cfZe`r2u)2P&xNkV0Cs17J-Z$))DF^1NuFmaW+=&byUO49b)`eI=C57!_4xe4RwT*r5ffA$;9J6Nm=wLUy;Zo~*>kZX zTMkJGLD(16%N~eURP*}^TYp_~Py#J*9qL3SF#i?MSg^32h-*i%BE8mAt7Zn z79Jj0#gUZjc!L%xi=5yun1J(+2Bw*e(AzsV>5;f$CLa{G#JoXyFk*R+ndGy{a*u>2 z1u)HE63*&AFfV}Zrdr+jVObg9eW~L4GLkZnu)CC>#Y1t-d{VHU`WqLu)=J)`!)QVs z!fQ7_8+B_@fKnz6M6z%?$FwJSr)_ZSD%;6r=s!Sa&(-eZ1||7RU;W#0?Lv)XlqxTz zT3?pnmALzzHXBU~n^|JrhH$zdZjNYAcuZRmo$Dx}d>5%wglN#Ka7y5k@KM;@p!H@7 zuzp`o^{auY9Q?_;SJK$pQ_Ew5{bvI`eP;C#izT$Ur%*~Hl`08M3B1jMt5Io1u%eKg zs!*6%;x|iWgZVz7L!FwTZ+`@(4CGUr2A|>Ur4x7vgX~5U{0L|gxaKcj&v`D@mj8&P zX6?Y)sgbtG56BD(2k^I_%y60Gg_waQ-j-Eo#kkk&y3_&gm!LcbSoF%eDgo*}9xSc= z^KIeSD>F+2rvK)Os8Fg^A z*epAdRo($iYP`s_Ol;WrrS=j@F-6xFhEv>hlVeDt*;>+T3)!4IN;Rh#3`RJ!W!bT3 zRm-j6MkkQa`B0F*6uOnqIG$&cIwimrUv7i^&4~AxSSaFqjV(Qy-4)wl@ zT-07bjR$0kuCPc+5qk%PBnSku-mVvviG>tQJbkr^$Xzu&ohO1p(cXa0RM=CHlE9Vm z&1UEEhK)uPm9#%_H{;He{tyG^Nb+a1ok89a}7>_gJ!B z+}OrB`4z(?65=#;?~&t!PvL!X(gb(-(DN-7_bh>+fiwvOz|(-aInCR`t{7|jd4|=Z z1kv6M7aBjuy63|sTfKiMjoxx}O9mG5U&(s}UHbtbrvu(cj0VZN@+$maa({4$Y1Z1;5r<-E5 zcbBb-c0Pp!ZA1E=@?WopQ*wZ4;!Y|_sXU7Z%7Ij~`nPQBZ)13!XDq>8p?p5B8j%)O z@~FNAu6yJmRO-NBl|PvzqR}3Po=l}d@6(E-#v1clY|qzVF62+FdnN|0h7%Hp(})_K zo7X_(m7C4q`svSa-#2d6QSx&w6;u8_58s@xOVYsI{D8K)JT%g&)2;E z;{D)!a3HMdG7TFw#9>vC2C=1>EPuy1@1Ck`i>oC8_XwAt@WS+WQ(A>l?acycU>C*a#M`cGq9srAt zzdEQ4Re$gH=Wbw23+S3`hE(-M$iUZYUp=`+qK6}%iz+6fy4Y#A5u9w)#6}Gg^Wt;8 znrW-)9hj`&9DABPV7Vb8wC8W}*vk}m#jk~T}{T;>}ZffBJ*X@t+s zz}(CF#rg(ydV9zI+~D8QmOY!!ZB_Jge=6fLZT5JB(K7@*zEZ$mh zSeo@R>Z5A$-5;x%;;G3$yKzspN47vxBtSLz5D7;2TKxWsBpn~1eH3f{dW(V1 z6M9}#ey(O;bF4%{dK~dGu9C=)_P+jYmBbn&Gl`E|X%S~wWX8TGc+?ozErA*IQvPcpD_? z&3-(0yE*>zYXn7d0yllb(G{Wafiz|qyts=8&Zn6@UP{WYpYUzJ!1j*6Xfcv?;`rOU zP>*#~a~wK^h1q~gkV>hm?WJGW)rk+_l_FEU__k~r86W| zs-PHDNgo8%e)xz|Nd}khrH>Q_(bk_l4zb&aJ!xT<2J1v~#;m+zmQr{7*Z+Rv2lJ46 zs(eIG0#onGuaQwaf}_UhMFw-VB8#hNeK;X>-TEPDk)sA=D`(4tw&xX?)cP|>B*Y}7 zbN$M4ba87=sz<77rcS?yqOaxhRuhTUR^!D4m&q4}HQnxj=X@;eTG=j_b*v>o7;$s{ z#-$~)IAFhqOJjh=#_!>vocDPMx$JBmvu@K`-$|53gqyd6Adf&mCZFKsUrSRbC9j8a zUB`EBN3$S5EtR8#gac%_=T<(;src+ znuF76dkR*H)P>S1U3$NMWKWim;1pln5~e6`cv0kJP~=7g=+Jhu<$>@-H?uozX-_e@ z6yFO@h2H&&>k!n--=dpc_>6iw-}NCm)D4(S7t#{;(#vmLd-k$WLXNW#c!fLYizrDO zYw7d$Lv3+{o1gS4?>VtQzxVlwO5Gvj5g@pmCM?mau6^%Z+m_p~6Bj zEKFW}*$#_sxI#^wO{;f>eFKR(4D?I;a*Ch%6VyS`}s zKpw*7(Fg+5c+zME_U3P$|NJn+yJE6v5NC*a-jAc)NB(p z$TQ0&d}tcMWs@#XHv}$_gQ>_U7~61nKNac*_&2YWs8d(%;*#gfx0)bjDbi|2*L$Hm z#KjxYtO?*gIK*aT+nJhizV59f!qZe#Q10M9m7A)*ro!!wQhM*m%of-wz`=q~_oS^q zr@kzgM^;1_ysn3S7-|>X!$o5U`J@a~3t37SUb;A-f(^X<7{bnKA9;GT0B=1S>augS$$u`eaU{4K1g z2^E0>2R2>72F8)nw2A>~D1WZ$L`)6YxJlo8c-fJ~uZX+wuADzZWMv$(R8H>v$Qjls z_WYV37rmQxV64>fHYY{%XpTjM2=)B4B#=WiU4jdEJ0jCIDr9+0y;4%TNbNG(pf0j_ zOvH6~!CJAvJ8Q9wtDjPs0I@QS*F3%~ne$WVsz>!eUA=a3D;i8mr))2js5MzIJ{UT4 z81tSyqx>YehX8zXW97juSIKD?54SsUf4I==C*{U*16;KV*OI*blW@xVJm?F*2~#r< zF4{NAFs4g|o3L*QrtX3@mU&yczG{Cd*51ftLe%`&ZIv+7x}K$e)beUKjWgGAh!*`WZi4k-kE)KRU5AYm6>Ct!H*V zMn1{ANzNNUG;99J1tpo)3Oy3+0UrO#ey+NVMAz7v!nZJfe$+~?IdWJPsfC9wBuxcuy?2%VN+gBcxKV1}V z!uMuqKZW7Rp}ER7KCM~Hp*e}HFgh+D6v@z09&RXrD5_88;bgT{@&UnaIcCPrH-2*> z%8dk%`B>i6%dOIC$<8Nq>+K8##_}_^B)nskI2 z&1Y;$PER8=$y)`z4P6qp{Yg`Y+&3la1z#)+lZwMt>od{*3uM)!m1((n;%wisMNohF zl@M^8qk{7j`@owx`GXL&zWYP|8w;b%&b^n3v5?KE#^aZwP{zm8Ttf(PbB{(;AbKtZ zRg^?*ynG%`j!fF<{#QeaLs6fi@YRTR4)RHsIV2ib&j2ET7KeubE$=f_8VQCQsYERk zL8dn=PlDMleXMQs=|5y0SYow3UM%=Lm*8l}Otv1t4>j^%p+*_2JVea@!6i_jy~734 zkSvnjy2ftlDYuG{>m5V4U3G^WRe#T>+jOWs|IY5}p(*p@k}hxZ+T5$1uCNbS#-pT^ ze-oe*4?Dzd^En!a%tX8SA2I+*xwvGGr^i^6zMDKj>Z)V+yV8{*xIh2wIr%*KY?#4O zY-ZF;ozD*UV>+s?nC3vu+QJ=DUZR_+Re*zQfCV1*5S?q+yz2 z_`M_u-&?sxbBjdamv2;rmK{KTfQNV`bf1~9XpyF$9e$*kJ?A;`o(T>>50>kvy#c z?9Jh#@0aUTwt~FXOx=d6`e@Wz2}q{t#)o;~#~mN~z0wF8cG-PT;pa;q`fjL$*B?;~ zGAeY2IdcN&&@YDSXrqps(7z!!Mk$ObiW2-+Ub%wkDTSTJ>pP5;?_V;#4OZs&&G4CX zHw>)3y(#_S%#yO^wA$^?p9niHMSEJXW;wE*qjKhY3MMNMc(3eqUdm2pzAI zzFKJ}p8-Et zQizQ~S`={-Ov+gT#OJkQ6)exp1dzpF*-?>CHEyA5hP1duwyZ3-efe;{*KPQCY!}8> z=;P*z!H0K3K1Wi0SK3Ob-15x4OTh$yYFUnPxHS5!I~LHrUv|S&Zp@Q{4ymSg{wC|D zG=8abS1v5h-yafM_!*b(r9<0elKVNaoEcd~HOUKfc&b2dj+=S9fq(n7Oazn}*cW2V zEcehiXF1nr318y{EP}TDoWxd^cX~MOj`}D5s_%Fs44j`ODuyrmKAdYepq}pkqVHI& z3K8GbPu|mS=pE!)LREj0dwFKQOMe3@nj-?M9I(_y(A%?#>qC9hx z`n-MkVhrbNp28{sV)0vhCzc`lW)a$op!(_O%gchd&x(+_#rf48TYbdn_mhp=S-kt~ zk!I`(k?2fxhPn9*c5=q)^W{tsY|N;^->>X%slTWSJYL(0&pzgTNKZtLKn1|gnufvv z^8`osw4Xyy_*yE^>L@8>vZi%>cG{AGm~Ml$ohF!>67><5>-=KeXlI}n!H5aMs7B;w;-!HVmU&wW`Fbs~m zh>pjH=``}QR1?)I)dmv_n^L`bZgb*n>FI{$eHox08S;zk^pCJRU;3eqDD<=cLEXQ? z3|~%i43jNL81dV*Ik*)=8-F&|McfeiA|PwZ1TRMbIn2!xlKt56GMsMOKrHd^TBX@u0@|y<&wIW1Uh)}O!Y$YGhLH=^l|0k=eV?k< zeY~_|WrpNJE}Nd$7mX(Pp3q7e8F=sj$?xLkwq7MdQ%XWXZ!o=bd!AZ~Fok|`JlS{^ zO2xe2FWy;b#7XB=&83GU0kL^4Dda78yr2O4d)}Q}BV}_!X05Ci256DZsmjl|J=}cC2wtjlwRSH*iGm}!QsJe~bHlt`Iht)pCV|2deHc9)O zj1>dx5X_Z}8AJY5>9kaAE3#75K%Dz^sIY$qRMPmlUG3AwlHLIJ?(v{}C9R-rXprwQ9v5*300@x& zI}2b4(!^q@$CYGIN4KmR1S6$FBs14+&9DGIOZK>L9vlc<{h~Egr>NJ-JqZEPJ<=welc2KAshzJ!?Po z{6&qToR_Yr8(of_vC*V&PQcFh3U!)RTsxufZBRxwLAYJ;ek-AF(smzv$)eQ=zilR_ z182j_LDJh56H1mWBv)F%8v~6F)=K~`}*erqHAFRdV(|O$d@cFiuh8~ z*bIQ*rsSj9f*k*yGo4(+*e9FMn0|yPUD07`Lw)&fs+I0=!<1;0`qF=R%ksoD;`gsb zd|etc>c+67LC{-={7|{_F3-+&?6I5Kz7Jg@$K&5=nNTR)ukc7;!^2VBgRfqh7cH4c zY>%ab-@r^5FvY>0dVH9on~J>xtAEAOsg)=r^X z(T`#`CZ*&;MCn99u}|l5BCs^5Qi{T1Y;ydlO$kzmXKo$=-{$j#Eu};E0cveD!TXcS z;m4XcKmU28S_>ReepPrm>%pwY@16Qx^-AkIqvoUMWDu*FVU1ZwSVX+VPNuGkk!d6z zr#L+vC~*hmYUT$aWL`BJAySgZGjBT}@V`%$d`T`GO%g!KuCP_f$M%44a1~m)2z{JV z6Yx`g*UO?&CH5|+{4cs2TooAc$Td-y5ZL1VZa2)?+Bq35Xk9``bAi4+w{VtjbBy{s z_e15Z(2B#2&yw0ZBiOGS?LM~J&LH7WH0~Wa@<3Be1OeDi7Z22!iF8y^FM*dsRy8n} zV%9R@|Na9LV{i~&&Av{-#F4@6?yau3#lKHl`d7}V$}2z25-~9`6EHdI_7MW)<>eDz zgy6q%wHee&Q1kPWi&-?Ijb8oUU_y2{x0eb-w^a@z99T46i&96M>_9vy5K($U-i68K zk21UTHHdycUk@Rh^EAwC|Ni`MOi=J?cZ>7rK635jA~ZrZW!sBk?7D-u+Kv|;QqNl} z$hS;AUNH<4(8vp3O9fI0{LqC?jLE1vrT|kJ#HQmpQ6Ku zJ$K3rn9>z^*E?OWKDNkF4u|121p1@rBg=upx<4y;2|n@ga3w*V zZ*vD9QxR>(!o~qo`U=HdqqxUOPPLl2D*kxac~N&c+JaLw^=#V-jU{r?LD2r{is$Fh zBJY8m+!{InE2d$;Ai_-4Zh4Nci8zHRLga``2-(T*Pu>^!^@x3iD=-lqq!gd<2*$bom`dyY>aW)m?y69 zAZ^@+Iq$P9KvzJHI@F+ye{m7klnlvNFQf9lN$8Cj>8yF5vn2m^&D@-9Z&*?~p*ucV zRkPbDdFR)nm<2J+p`_~<{fC@IBlctW@0UfExP?1?Y89!8ah#|5zo_^z*#~Y~V}be$ z+ZdWFR)*w<3Yn(l*TjWdTf1)OW@fITPdyy0!Oeeoz^$-r<&^7%8C?QpC^0hd-^&~4 zaGK3Xt&m2d{=N#$t=I2dWO0>n%o@1wKn%YH7 zOqDP~96}b(BK1M{(rLEbA+=W(mAPiA>MSRQthAE+=6SK5N~==wDgnRX?c8MTjO;*>4@r03VG>r1@oIpDag5_wo$25xQz@}+=&)X2VwD8PZQQ4a0rAkcXV%U( zRl;-zCqCBj`S#kerbW){4RMor65c4d3)vxp+;?a`)!g3b6)ixIW3!nMPi;#J-?vg< zS}rB-N#g(WjzEZv4+^o{evOnrsti9`0895)#)cr<`2_IrVs23_c4zfnrspZ1wXL9T z{_Cn~%E3lv!C#V_fJY5)FZS^<4dMMJoPT+ecFy0Av`0yFZk-|FM})#8io|@SDM4L& z<)_;t7hYD^sB)2N%k$BT0H*v1^5)-dMy2@(k`%~44NU`=R0SMK&HIz@7r)Q7K(Covq7fBf&+9scxJ6E?o7{DdzJ11N!ece{>nl04;7-d zS1`+8^uxnQ7RI_FkMm+i+ZcLv&tszQf$2_&KPkL9vS8V7FJgQh-=_}PK3Hyp&zGuR z>vcs;<=YVmHpM-*jNnQxEH{B^IJ7RZ>Y@l@y4j^m!hYF~43XE`n@GGOYjkSkeRp`T zb&)$4BcT=pdW=21%R)!A2*iP{zj0=bFmFV=E9fM=^>uhP)|H~_SXK_D zGJ6~V?9L*5yq$c%P0*v#6l^Ov8qD}$f*6_a+4(=LxONtxx0FOEVWENlV}i$|=4FSq zwWXvOK;KLJ+WmsMdr-+y#FRs|Ju~Pq_4!*jr{mBYiB!=?al_n!it=)w4;FZhV&jAw z7bi6{8M@<7CG~~?km%!;SHfmb0UA|R4z`SN5XCLjGuQWo4djlEE=sB#6UKH{VDb4% z`8p%F1qT0{8KgWtzVZPBu;F4i1-9^21e!zxa5dyo%e*Y?6#%?_CR<&C8(>`!e5k&9 zB!Z%6eh^|$>g=sI3urKHfBAdzFe<>aG>*`m-b~l89!ATP2#coANT!IToqiszbg*S; zCEWTqyFYRgAUZ|5aZCVz)nnp;f~VnSfJS(o9>j^&S*lj;;}-V?iCj6Y-zqPZ%prat zGYMF58IV$pM8ddy^ zF7IUXmyEl2qH*v8lK1aU%4dq*EJ4NfdcMzCx3|{S8XgqG!{k;E z>o_@R9uJ>(+D8Eb0q=tD82zT4_I2?#m{~+a!d;6c|>7i=Qv06M=-u zrnXtP3F~nA;s1+a$jew74kLFLbt(IqR$72(k+qwEC}ewlHV*op*Id(`Yfer1e!g4? zBLQ^~J_fg_I0kBnVFpq(i`UZV=dSvMp=pgKU`ai#pkb`51Y4l@IT}O!-M1$?W&7fi1s=pxa5%=R|$ik>33X>{DhF@ z?`UPeN=L{^W@S=tw_2&U07mj&mo9D$?RM^1QmY9}o;8IvaW^Z(87o3F)m z>~meagv&n!vhBGGic22)xwcf^2&xJE=ai4+#sIYTlFNhhSql5hT|)TRt+@ESj&4|t z52cCj`d2A4fG@_whBXxzm44l-f#qo=7vS5DTXW2z@PSFx!4trwYr<-`pQ<<1d#Qb6 z40~w>TX)2jMD0X_(ij8SAq0y?^YK$^3-kgSG2L51RJ?-x>RiwnYIGD?b9HOc3K0@i z#pOq-U|#E~A1OE7X=S8vI`lH%AH0M%K%v)4MEzj z=z(f`bA8jrUKgh2)7zTd?1vLg@2Bn+2ml=7)vTC*^b>$VnhE?q)eGQ1yEP&!9Ewac zsU+A1$0_`H^K~1iP;X}?neissFCL##OoDR&_4d&ptz{vD>~qJkqL3A+IIj9*u1s-n zDepwao!jd@>pa<@9NR|H9&vFBzlH6puYX|B$?@fT-4;=%EnRc~@XHx@WKpFshA5u^ zZ&aG5e2XQOJOrOVG!ik9#VKM=i;4$tI%v2dzHm55R|_H`t~G2!p~gZC@5j`--kjD9!wGHF5a)A&(*3(1^V4o__|fmUdCly< zZnTSve@@~*VMpMi%$eF2&8j$%;UPkax>AKE-&T4c-g0AJY#(z z{pv#~;W9JX@`V)i4wR)Jz814@PX$wKcKxj&pF!=Sgg)@2kqaXZD`g((`Du9et|~tl z_5Q-{H6GIQ_KC*!8bL_xR(TnrO~h$e+2MXj9G2#FJz&dOJoxEwhlQq z8dLUELwp-tv!1V=PcVL~w-xM_CY66gv}H}B`Lj*yGA&>?X)@|79soFzK3!>r|MXrW zbEk&8RZSVsKa_3W*+|DykW`@I6!6qn%ldAaW?$L->ua3=WH zffMEBZ&u(rf}H`mhW8mY@P1GHjmhP2WEIzsJGU;Q#W6Dl&Gi?T1iO%E^G~c-)}x^ z+kFNo$J4TTdrvHtG=mabeoUzb@Hj3x)rg>9-)X^E&Bx1_@`}Q{`_ibw9-1P%Gc#L` zeBWoc|6*KHS!?;NDt%4>=%yz38RIbb?W|Wkny3Q%N@fRm(xdNyH79nSRuV?(u~2*8 zH(er(yE@#k@dEGN^?u$u`WCH3BhX#Lhq29oU}{y00^ZUSqxP|tydkEGqpv5X-3h${ z$oXHz9Wtvdp@%melcRrk76ZTYoHu+2IYPAQ#yPV+ru3>?Y$ou`s5 zOsC27+U*5>U%oSXILI)9o)K|~D6A6W+EC9*+q?&2t8#*!Z%R-umo0l8&1e5G*=YVu zki`A5z!`?{2lyjCd&~YZLrgvSHw>mHZMeH$xV<=S8fL+xzX3wF7m}h;$?Oguaxo2* z%;RY04t%NCBI@!YK{CK1`e<1@b@;Ma*c_YN9BiG$DN!=j4)nOA%8Lo4;yt2E@)@mS z=xIapL3CZ-%YB3!&@JD<1*E&wHyT~1DpD6e6MVnl7MbZpkaAQ$uV{C&^Lo6n45bL@ zYIk*2t@2-|?Z3}P4OIXd8<3`4LC%2h&wu@xTJI-~jH{vFwW86_-u#aBVUb5#K?ARz zR5!DPQCJjjTofK|m7}C&Dt(o;`Af+x&`*(-ky;VP-``1JG1vBihH&r3#2_@*^-6)|4 zDrB#tPKBic-2ZLqjATMdK<{uju>3vIgz7OQB^WXDB)Lm`-1hni$upoFNW9*hVMbWh zt1b-!n6$l?K(#sExuG_$GF6>H7BbhaEfMV1Zw!{v4^W$yTDzfwmSr{{2OP7$1cmAl63=6E@*DM~3Di6jV898tHOkfjrw17cT7o z2|-@*)>PpjIrXfIM-0aA=(aDxiO8#K>;q`waoW2Sx zz{cE>3__RQ10t>Q+E~b>&Qc)(vBY10+f3w6ptZrXBM6Djxlmjlg|IwD7)B9YDHpq5 zqisS8tQtnARcm)o#=cM4A{mo{pna-7T*!2JW1vie3`ClDv!3a{**sx)luTIFW$vD|KQV9sZp*|}~RZrA>wJl>1m=u;~#!WKWhqyq= z`*j*ckR2M#3ScIdhkZ_0L6IB>QbG#}D3n1d(woXaHsPo+IPpL4R@`ri_nF zj*2k#F$`^s<`sq{0Hw{p+Lvb*!6`%mG?p=YJ%i*Db#atIo}n|0INi9Rix5KR(21Er zO=q~MTwHe$eQ|is&Hqig>4m^TLi+a4UO<0x3Y_F~m4@LNM1Yc mHighlightWordProcessing{ false }; TextRange mLinkPosition; String mLink; diff --git a/include/eepp/ui/uitextview.hpp b/include/eepp/ui/uitextview.hpp index a6fbb0de6..ebaab8f04 100644 --- a/include/eepp/ui/uitextview.hpp +++ b/include/eepp/ui/uitextview.hpp @@ -173,6 +173,29 @@ class EE_API UITextView : public UIWidget { void resetSelCache(); }; +class EE_API UIAnchor : public UITextView { + public: + static UIAnchor* New(); + + UIAnchor(); + + virtual bool applyProperty( const StyleSheetProperty& attribute ); + + virtual std::string getPropertyString( const PropertyDefinition* propertyDef, + const Uint32& propertyIndex = 0 ) const; + + virtual std::vector getPropertiesImplemented() const; + + void setHref( const std::string& href ); + + const std::string& getHref() const; + + protected: + std::string mHref; + + virtual Uint32 onKeyDown( const KeyEvent& event ); +}; + }} // namespace EE::UI #endif diff --git a/projects/haiku/ecode/build.app.sh b/projects/haiku/ecode/build.app.sh index 266b78bfa..50dff311a 100755 --- a/projects/haiku/ecode/build.app.sh +++ b/projects/haiku/ecode/build.app.sh @@ -10,7 +10,7 @@ cd "$DIRPATH" || exit rm -rf ./ecode.app mkdir -p ecode.app/assets mkdir -p ecode.app/lib -cp ../../../bin/assets/icon/ee.png ecode.app/ecode.png +cp ../../../bin/assets/icon/ecode.png ecode.app/ecode.png cp ../../../libs/haiku/libeepp.so ecode.app/lib/ cp ../../../bin/ecode ecode.app/ cp -L /boot/system/lib/libSDL2-2.0.so.0 ecode.app/lib/ @@ -29,7 +29,7 @@ cp -r ../../../bin/assets/fonts/NotoColorEmoji.ttf ecode.app/assets/fonts/ cp -r ../../../bin/assets/fonts/DroidSansFallbackFull.ttf ecode.app/assets/fonts/ cp -r ../../../bin/assets/plugins ecode.app/assets/ mkdir -p ecode.app/assets/icon/ -cp -r ../../../bin/assets/icon/ee.png ecode.app/assets/icon/ +cp -r ../../../bin/assets/icon/ecode.png ecode.app/assets/icon/ mkdir ecode.app/assets/ui cp ../../../bin/assets/ui/breeze.css ecode.app/assets/ui/ diff --git a/projects/linux/ecode/build.app.sh b/projects/linux/ecode/build.app.sh index 62729abd8..82a048e7e 100755 --- a/projects/linux/ecode/build.app.sh +++ b/projects/linux/ecode/build.app.sh @@ -28,7 +28,7 @@ mkdir -p ecode.app/libs chmod +x AppRun cp AppRun ecode.app/ cp ecode.desktop ecode.app/ -cp ../../../bin/assets/icon/ee.png ecode.app/ecode.png +cp ../../../bin/assets/icon/ecode.png ecode.app/ecode.png cp ../../../libs/linux/libeepp.so ecode.app/libs/ cp ../../../bin/ecode ecode.app/ecode.bin cp -L "$(whereis libSDL2-2.0.so.0 | awk '{print $NF}')" ecode.app/libs/ @@ -47,7 +47,7 @@ cp -r ../../../bin/assets/fonts/NotoColorEmoji.ttf ecode.app/assets/fonts/ cp -r ../../../bin/assets/fonts/DroidSansFallbackFull.ttf ecode.app/assets/fonts/ cp -r ../../../bin/assets/plugins ecode.app/assets/ mkdir -p ecode.app/assets/icon/ -cp -r ../../../bin/assets/icon/ee.png ecode.app/assets/icon/ +cp -r ../../../bin/assets/icon/ecode.png ecode.app/assets/icon/ mkdir ecode.app/assets/ui cp ../../../bin/assets/ui/breeze.css ecode.app/assets/ui/ cp ../../../bin/assets/ca-bundle.pem ecode.app/assets/ca-bundle.pem diff --git a/projects/mingw32/ecode/build.app.sh b/projects/mingw32/ecode/build.app.sh index a77c278cd..47ea51a91 100755 --- a/projects/mingw32/ecode/build.app.sh +++ b/projects/mingw32/ecode/build.app.sh @@ -54,7 +54,7 @@ cp -r ../../../bin/assets/plugins ecode/assets/ mkdir ecode/assets/ui cp ../../../bin/assets/ui/breeze.css ecode/assets/ui/ mkdir -p ecode/assets/icon -cp ../../../bin/assets/icon/ee.png ecode/assets/icon/ +cp ../../../bin/assets/icon/ecode.png ecode/assets/icon/ cp ../../../bin/assets/ca-bundle.pem ecode/assets/ca-bundle.pem VERSIONPATH=../../../src/tools/ecode/version.hpp diff --git a/src/eepp/ui/css/stylesheetspecification.cpp b/src/eepp/ui/css/stylesheetspecification.cpp index 51529f0f9..c36634804 100644 --- a/src/eepp/ui/css/stylesheetspecification.cpp +++ b/src/eepp/ui/css/stylesheetspecification.cpp @@ -390,6 +390,7 @@ void StyleSheetSpecification::registerDefaultProperties() { registerProperty( "text-as-fallback", "false" ).setType( PropertyType::Bool ); registerProperty( "select-on-click", "false" ).setType( PropertyType::Bool ); registerProperty( "gravity-owner", "false" ).setType( PropertyType::Bool ); + registerProperty( "href", "" ).setType( PropertyType::String ); // Shorthands registerShorthand( "margin", { "margin-top", "margin-right", "margin-bottom", "margin-left" }, diff --git a/src/eepp/ui/uirelativelayout.cpp b/src/eepp/ui/uirelativelayout.cpp index b93616b00..aec875098 100644 --- a/src/eepp/ui/uirelativelayout.cpp +++ b/src/eepp/ui/uirelativelayout.cpp @@ -43,8 +43,17 @@ void UIRelativeLayout::updateLayout() { if ( getParent()->isWidget() ) padding = static_cast( getParent() )->getPadding(); - setInternalWidth( getParent()->getSize().getWidth() - mLayoutMargin.Left - - mLayoutMargin.Right - padding.Left - padding.Right ); + Float width = getParent()->getSize().getWidth() - mLayoutMargin.Left - mLayoutMargin.Right - + padding.Left - padding.Right; + + if ( !mMaxWidthEq.empty() || !mMaxHeightEq.empty() ) { + Float maxWidth( getMaxSize().getWidth() - mLayoutMargin.Left - mLayoutMargin.Right - + padding.Left - padding.Right ); + if ( maxWidth > 0 && maxWidth < width ) + width = maxWidth; + } + + setInternalWidth( width ); } if ( getLayoutHeightPolicy() == SizePolicy::MatchParent ) { @@ -53,8 +62,17 @@ void UIRelativeLayout::updateLayout() { if ( getParent()->isWidget() ) padding = static_cast( getParent() )->getPadding(); - setInternalHeight( getParent()->getSize().getHeight() - mLayoutMargin.Top - - mLayoutMargin.Bottom - padding.Top - padding.Bottom ); + Float height = getParent()->getSize().getHeight() - mLayoutMargin.Top - + mLayoutMargin.Bottom - padding.Top - padding.Bottom; + + if ( !mMaxHeightEq.empty() || !mMaxHeightEq.empty() ) { + Float maxHeight( getMaxSize().getHeight() - mLayoutMargin.Left - mLayoutMargin.Right - + padding.Left - padding.Right ); + if ( maxHeight > 0 && maxHeight < height ) + height = maxHeight; + } + + setInternalHeight( height ); } Node* child = mChild; diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 03da7cd66..6d8208827 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -852,8 +852,12 @@ void UISceneNode::processStyleSheetAtRules( const StyleSheet& styleSheet ) { void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles ) { for ( auto& style : styles ) { - CSS::StyleSheetProperty familyProp( *style->getPropertyById( PropertyId::FontFamily ) ); - CSS::StyleSheetProperty srcProp( *style->getPropertyById( PropertyId::Src ) ); + auto family = style->getPropertyById( PropertyId::FontFamily ); + auto src = style->getPropertyById( PropertyId::Src ); + if ( src == nullptr || family == nullptr ) + return; + CSS::StyleSheetProperty familyProp( *family ); + CSS::StyleSheetProperty srcProp( *src ); if ( !familyProp.isEmpty() && !srcProp.isEmpty() ) { Font* fontSearch = FontManager::instance()->getByName( familyProp.getValue() ); diff --git a/src/eepp/ui/uitextview.cpp b/src/eepp/ui/uitextview.cpp index 4058dc9aa..1e8a6c183 100644 --- a/src/eepp/ui/uitextview.cpp +++ b/src/eepp/ui/uitextview.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace EE { namespace UI { @@ -173,8 +174,7 @@ UITextView* UITextView::setOutlineColor( const Color& outlineColor ) { } UITextView* UITextView::setFontStyle( const Uint32& fontStyle ) { - if ( mFontStyleConfig.Style != fontStyle ) { - mTextCache->setStyle( fontStyle ); + if ( mFontStyleConfig.Style != fontStyle ) { mTextCache->setStyle( fontStyle ); mFontStyleConfig.Style = fontStyle; recalculate(); onFontStyleChanged(); @@ -265,7 +265,9 @@ UITextView* UITextView::setFontShadowColor( const Color& color ) { mFontStyleConfig.Style &= ~Text::Shadow; Color newColor( color.r, color.g, color.b, color.a * mAlpha / 255.f ); mTextCache->setShadowColor( newColor ); + mTextCache->setStyle( mFontStyleConfig.Style ); onFontStyleChanged(); + recalculate(); invalidateDraw(); } @@ -819,4 +821,74 @@ void UITextView::setTextAlign( const Uint32& align ) { onAlignChange(); } +UIAnchor* UIAnchor::New() { + return eeNew( UIAnchor, () ); +} + +UIAnchor::UIAnchor() : UITextView( "anchor" ) { + addMouseClickListener( + [this]( const MouseEvent* ) { + if ( !mHref.empty() ) + Engine::instance()->openURI( mHref ); + }, + EE_BUTTON_LEFT ); +} + +bool UIAnchor::applyProperty( const StyleSheetProperty& attribute ) { + if ( !checkPropertyDefinition( attribute ) ) + return false; + + switch ( attribute.getPropertyDefinition()->getPropertyId() ) { + case PropertyId::Href: + setHref( attribute.asString() ); + break; + default: + UITextView::applyProperty( attribute ); + break; + } + + return true; +} + +void UIAnchor::setHref( const std::string& href ) { + if ( href != mHref ) { + mHref = href; + } +} + +const std::string& UIAnchor::getHref() const { + return mHref; +} + +Uint32 UIAnchor::onKeyDown( const KeyEvent& event ) { + if ( event.getKeyCode() == KEY_KP_ENTER || event.getKeyCode() == KEY_RETURN ) { + if ( !mHref.empty() ) { + Engine::instance()->openURI( mHref ); + return 1; + } + } + + return 0; +} + +std::string UIAnchor::getPropertyString( const PropertyDefinition* propertyDef, + const Uint32& propertyIndex ) const { + if ( NULL == propertyDef ) + return ""; + + switch ( propertyDef->getPropertyId() ) { + case PropertyId::Href: + return mHref; + default: + return UITextView::getPropertyString( propertyDef, propertyIndex ); + } +} + +std::vector UIAnchor::getPropertiesImplemented() const { + auto props = UITextView::getPropertiesImplemented(); + auto local = { PropertyId::Href }; + props.insert( props.end(), local.begin(), local.end() ); + return props; +} + }} // namespace EE::UI diff --git a/src/eepp/ui/uiwidgetcreator.cpp b/src/eepp/ui/uiwidgetcreator.cpp index 0cc14f0e9..7fd12fe2a 100644 --- a/src/eepp/ui/uiwidgetcreator.cpp +++ b/src/eepp/ui/uiwidgetcreator.cpp @@ -95,6 +95,7 @@ void UIWidgetCreator::createBaseWidgetList() { registeredWidget["menucheckbox"] = UIMenuCheckBox::New; registeredWidget["menuradiobutton"] = UIMenuRadioButton::New; registeredWidget["menuseparator"] = UIMenuSeparator::New; + registeredWidget["anchor"] = UIAnchor::New; registeredWidget["hbox"] = UILinearLayout::NewHorizontal; registeredWidget["vbox"] = UILinearLayout::NewVertical; @@ -109,7 +110,8 @@ void UIWidgetCreator::createBaseWidgetList() { registeredWidget["button"] = UIPushButton::New; registeredWidget["rlay"] = UIRelativeLayout::New; registeredWidget["tooltip"] = UITooltip::New; - + registeredWidget["tv"] = UITextView::New; + registeredWidget["a"] = UIAnchor::New; sBaseListCreated = true; } diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index 516544e2c..23857ecc6 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -70,7 +70,7 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath, windowState.size.setHeight( iniState.getValueI( "window", "height", defWinSize.getHeight() ) ); windowState.maximized = iniState.getValueB( "window", "maximized", false ); windowState.pixelDensity = iniState.getValueF( "window", "pixeldensity" ); - windowState.winIcon = ini.getValue( "window", "winicon", resPath + "icon/ee.png" ); + windowState.winIcon = ini.getValue( "window", "winicon", resPath + "icon/ecode.png" ); windowState.panelPartition = iniState.getValue( "window", "panel_partition", "15%" ); windowState.displayIndex = iniState.getValueI( "window", "display_index", 0 ); windowState.position.x = iniState.getValueI( "window", "x", -1 ); diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index 92adcee63..0adcd744f 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -1079,6 +1079,15 @@ bool LSPClientServer::socketConnect() { return false; } +void LSPClientServer::socketInitialize() { + getThreadPool()->run( [this]() { + bool ret = socketConnect(); + mUsingSocket = true; + if ( ret ) + initialize(); + } ); +} + bool LSPClientServer::start() { std::string cmd( mLSP.command ); if ( !mLSP.commandParameters.empty() ) { @@ -1101,20 +1110,16 @@ bool LSPClientServer::start() { } if ( ret && !mLSP.host.empty() ) { - ret = socketConnect(); - mUsingSocket = true; - if ( ret ) - initialize(); + socketInitialize(); + ret = true; } return ret; } else { - bool ret = socketConnect(); - mUsingSocket = true; - - if ( ret ) - initialize(); - return ret; + if ( !mLSP.host.empty() && mLSP.port != 0 ) { + socketInitialize(); + return true; + } } return false; } diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.hpp b/src/tools/ecode/plugins/lsp/lspclientserver.hpp index df597a94c..9acee3055 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.hpp @@ -273,6 +273,8 @@ class LSPClientServer { bool needsAsync(); bool socketConnect(); + + void socketInitialize(); }; } // namespace ecode diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index db5cf7437..2855d98ad 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -1601,7 +1601,7 @@ void SettingsMenu::createProjectTreeMenu( const FileInfo& file ) { } } - mProjectTreeMenu->add( i18n( "open_folder", "Open File" ), findIcon( "document-open" ) ) + mProjectTreeMenu->add( i18n( "open_file", "Open File" ), findIcon( "document-open" ) ) ->setId( "open_file" ); mProjectTreeMenu ->add( i18n( "open_containin_folder", "Open Containing Folder..." ), diff --git a/src/tools/uieditor/uieditor.cpp b/src/tools/uieditor/uieditor.cpp index 1bca4d5f8..9123ec579 100644 --- a/src/tools/uieditor/uieditor.cpp +++ b/src/tools/uieditor/uieditor.cpp @@ -1197,7 +1197,7 @@ void App::init( const Float& pixelDensityConf, const bool& useAppTheme, const st mWindow = Engine::instance()->createWindow( WindowSettings( 1280, 720, "eepp - UI Editor", WindowStyle::Default, WindowBackend::Default, 32, mResPath + "assets/icon/ee.png", pixelDensity ), - ContextSettings( true, GLv_default, true, 24, 1, 0, true ) ); + ContextSettings( false, GLv_default, true, 24, 1, 0, true ) ); if ( mWindow->isOpen() ) { PixelDensity::setPixelDensity( eemax( mWindow->getScale(), pixelDensity ) );