From 0f35ab55fe7160b1118bc74ae480e377dd8157bb Mon Sep 17 00:00:00 2001 From: justuser Date: Tue, 18 Jun 2024 13:36:29 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D0=B0,=20=D0=BF=D0=B5=D1=80=D0=B5=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=20=D0=BD=D0=B0=20Dash.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/favicon.ico | Bin 0 -> 105662 bytes assets/style.css | 67 ++++++++++++++++++++++++++++++ interface.py | 99 +++++++++++++++++++++++++++------------------ main.py | 29 +++++++------ requirements.txt | 2 +- 5 files changed, 144 insertions(+), 53 deletions(-) create mode 100644 assets/favicon.ico create mode 100644 assets/style.css diff --git a/assets/favicon.ico b/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2af6343ee8ed77f7dc699844fdc498abccacb778 GIT binary patch literal 105662 zcmeF41)NpY+K0DE$IQ?TBDNw*n1n@lhonkNcXxMphcpNxieh790CpiF?X|C7eZT*+ z_F2PbK2S^)_5R+w&&-^eVa|E>|IM{l5S*p|&6^kK|MLXPW}Ove3WDHbnLZViI4k_T z9tOcUeURk8Td2B(XGOzF=F{s}gyafa4C>!z{-W^59IjCU>N|;Kj*VkG?f0%YWKeO2ojIB9&Dojkm8qG(7=3rTcCz4K`)#j5l^asr)#Q$pc2}8H zCJpQNYjo_=+~);nvNbQ4D*yKJnfC6Unb}^RlF8ngo5em{ki`~uNf=h4Sn`yz;9vXY zuYp**Lig_nz3Zm2>NlmZRuxnKPde86mui_bG&qxO`n~CgzdJ9By*xRSy*4egy*@p& zy)i4Zy*)RpE$NEcn+>{WWM> zI#urxP19N5`f2RB37KrqqO3Odp7f5vc2!dElb+pls+yK1{+!@UwK*N*M!r2Ki@hZ6 zdqwQQ-|OPe@i$%9SvkMEw@SJ@WWm37YOg`H8&ljmyji+0de=*9D|^M;d-5&s&(C6S z&dp&18m2e#XI*Nfc}tph)v4&(1zFDx&P2Pna_Wn8Z%X?zh5Sv;WUs=Yw2$lVS@Ox# zvLC5cJk?dQ;9vXs*Wk*$=Vuw*Fzw6u-Eqy+8! zYkYgEr=@G@e@@$qTy%bLCfdYS@nb$*nAKjG6!Nzt#^39T0biM#(cYSy-L{R+`A(U_ z$+F9Wf9USBK|OZ@XM1k+B@@d*ydrm zo~~OmMQT~_ul@9E(BPJojV859{{wz^akqG}m(|`@O$-0KXHjN5vMQ%NJ|?>jZj?r` zV7hOlX}6t{UFRC9&y@xL z+R0yovPF_#G3u^#dj~g8Ya^Pab1@9s_wKyRwr8PqZ)p}gurjaB?wG;)-(_7W_19mYMi%^)?3xRcUGdVC ztcS>R;q0ZD|8+SCK3K-*_bts~6I;d2mIeRX$zKC8luG%;mI*D>Tkm>lY|GG$_L1`4 zx1@d4QTHwmweQs#xou!W;=**+v054{eq}Pdr);Vp`_xOjL;7~h$uzES{j|ZUTAey| zk`Ej>aOsK_D{RrCMb^7_?-fOg6v-+J{wg-|uDEG?7D@XiW^|l+{~PteFUkLYv?R9; zZ4y677W```e+^W>?>ABG^=ptub-p;~cd4i1cRyN`#Xeao{#NI+ReiHq@4BgNYMb;{ zw^T~Iy-+giUOSD6+pnc>g-@n&>YW6qYd2@>3mss)Q#WRb&hZiqiY*VI8v3c|6!Ql4WZ@>K_S#UaSO!N5JA0^Q~&mj6o z90-ThU*4RX^T)xB(^r!P|Jwh54N6>@Ec=kgXDD<1p9b#R>vOozK_M; zKIObe*W|T_M`pKvszpz3o!)v#^KO&&srFBe<~wOy*`Lxk)oOxYYPD+B$}@ld{O4xQ zoN436jdL7!>(=e%iWMtfAq!52-EwvEB0HvK{hZqJ3looNUsV6#??vS#yJlv!SEpzD zy7BEPOUQzM?fBO~G2c0=BhQ`KD!q&8rid%e4%vI+?gQB#{I1wLa9=k24^2L>J2GW|4U^Pq?^*U z4nL=DU2CQZeyxeQtL1;+9655NDKD|%!-t!6@XdPl>J^m*f0mWLHbt>lre*yis(omn z=Pv4lpBLL0VhZBf<8_@47yl z^4*Wc;Xc({K3$&O4z12__w~wT1EqbM^N>yOBMVU zn>~AWv1QAay$5^!`}eoOg9lsJu3g`0+_>>|vfz)lLix`-Yi7Inh15fzkL0|bJ;!0p zALD+)Q;L+b;9m=0gPSf-mRdRM!^CmJnuI;JoioB*!^M1JkDO!Q z(rk8kRUUg|ZeG`i8__JS&F&D#43^cnIR*7Ulcr5S6Nm-PKhmW2*S|h9>sQqEyykIzKE|ATET8N(@Y(Sh#a~Wa-ZSH>))iB! zr<5xA*TUDJRfW`p@S$VmO9!cz_wcYxwpXkX_xXGmzx(O39Cl>wh4#RZ>^4OG4(c;g z+s0Ylk|{Lggh}}Oba^ft(l~CKEcn;L*Fd$F zvSaQ^|1~TPQOq|_bA80q^f@q>bBM)#V(;L}JoeGj3vI@|@iwAqT9oc-_9o0S< zbL_=fgEy~*p2v@u_^*wYho+bH>6=3wS^inC7DQrn%kr8IJ7=~jzV)h_i%g5T4cHEUKyIq?zvu=*o5 zWXKTm;!oA1tNeTR>55)_{@HUoWmx{+{A~7|81vc(W6#Oo!kssG#Q*a7S2X|f?t)yZ z4Ww@-3;yYLS?=@BYg;Mxl43Wyv%Y=%x_A%+l zT2E`6-ol`73-!LPNtrBdJe#+;nrGE<7? zk$d1<(KmR*o*sMb`t11ddGPna!t9z;%d+>5Ym(=e1^*;Vk?icW(yJGEeU#sB)LhGU zv1r&ZY2WHT3F0lxImkC0d*r*zb7;0Sw;f(nz}{I@Kr;q$sxPNAbaTF9KjqD?_9x%H zQCy$*OZ2SRCFci!q}_ARJ$Fx@Jo#JlVQSRWs>R_qcieGDOIh$s?Xo=Qox7-8mbKK7 z(Yr9;2-$m}-`-`pZFS#F53A;v?4MNkyCTndmpm{iVc(`f8El4PJn~jzIQnET z_}D0|;ZRS5`4(4Wc0IQ2^1Zp-T>Zh-7uqK)F0ln&64Yl)r+Qy{TcSB=dLCVBriS4+ zq+^+Wsg~)U2>uM~(W6HP%`5yspLoKA3AS|UQkyep&UfOk-KjEoY3_5+ThuM{y7#1g z&y39w#(OcH^W4E0I`_or@ap)J{)HT7vQHF4&upKtOcwl8ELHNe&hAww?IKHoQaV}3;)FobPe$%*_ zXldBsU!!C7Z%GyWS*HG6SIy1*$jsIwk33>;zx_50ey?1l!>QyWiu>-^Jv--r$z@$$ zA+Eg7_1wYUldva)LHrH52p>N`F|!?9k&AeFqAd8QSf%SzRC;_=#_v}3j(0H|epmfj zH!naOr{1}G8sxkYzpH%r)8)CvUOwBuGQS;Kdzr22mqp(f)|(fKJ#uAco%QqnBMrOe z*XWq~eZik;stNX5xpJjF@x&9hbLUQbkTUAtL7cgqTljDd`cho(=6gvhGrQW5Gqzz4SI+es_lS zZ+XvnX{Y9*H5;fI)iu(vbAFAERnq<^f3~SN+?VcB#8Ep6LZ1(p2T$&S4(?}Nl6RcU8 zRK2+Wh}FnfsWIbsiT&nujJNj}=2Xs+RqSPU^Q5pxojKIL{I-8ZemlD13VUcoPJLfm z6U(mNe4qGZ9j0Q(AEjS4f31dfsG2f39VTBqkQgutgI23%jefEqYBybW-g(P=W!dz` ztZYulU@FQUYf&E+U!lQTMz=l{{_wl_V7~T_v{Q4Z-)ly3*Zk894`%gZeljgkY;!6g>}9Nd-vtDPghQn%J&rNx{W1E7?|o)`mM^N@ki3{IIFl{;`DdT2 zbsMXE&Ou+6oEN`K?yoA$F4|9z@<_de>&^$B{Mv4FS>2=*aH1nRz@|>GT z7M#g;+ttZyYu~y5tyIoIy#=2eS~?fMvH!#VR0yo$T;a-f^8X+!5)m+mZ2H!A+g8R^T;*iF68eS&5%<=RqgL3?GKSo7M!V;E7Q4| z74NH%0!F+~e^vS><$-?pVEuUxs@9^Lksz5e>^wrkf;@?yKEc}uHYy`EL5P~Mu>ENa7==d~5R62xG7 zS-cobu+55Zh;bg2!6ocD4yA=Khz>qGA+uYfzo=`%X03%j|77c-&xFrwZ@!_db0Ozo zE*|#i@lrQl)+2*vTXMR&f^fDVoauAwDAMg3j@_Kr!Ea zJ>q{D)b6&!OYU3${n&Bit#s)-tVYe6*0gC;YumQ1wQt|v)WrtX};aswQFZRd-ilQcbfThAK!J?U0;+fTehq8?W~h&-0v|9 z^?Ut{(l_QUIebXJ?^xGPPC_jB)?076HO88!arao`Ce5r?-9}cSQgy3RzNEFNd8LhL zk=yR;oyBp6e||*%8UCC<)|HRnn4Lqf?FFWN$H$zhdygliJ?DJIcpDV=Nw4BukBpda zy6Sb*nI9Y~A0WT$+4FNPzRvflYAyKP{i`mq&+ad1&rHlKf1B18b(Qw%=TUQ6rrvRj za>=Z7txPs*aA({6;8tVKnBM-hY17;~NP7L6`E(5OzNw}=Svr?+BCRW3x^(bYvGT=| z-`uZ5)vrg78LRz07TV)aJZ{tm>60v6xX@a+Zf%-xHQiU%sBsgkUALiCtWw*`l`C(x zDwniQjjpw69rGzpR9$dXoN6%fE;o5}M1p2cnHkS#&C8|iC=1R+D_=B4L(QW7xJGj< z%!HzQ#C+tw+V9$}d)dD%t9-At&(-;u>7&PSfeiN0zDw-j+RN?JH3f;4orW%U{Gojb zu71;^Tyh)NBHmgxsbC|=Otky&zuz8w@IiOgtci^oGsdq&a}28guY9uB!_uisl4{k- zbn(ype4P?0&bg;-%JQR|rPw;L{lz~F?%&Nuj2!KH#PmsE@SS(wF|9XtzWDCD@3!X6 zn}>SXxUqb5L#tM!o|UUuLvdm`Yf|$D8`8Xh)&^#FzWLd4ae968ss5bv$6j?(*Ovun zn&r)MZr0^J;&)M-qQ^_E8UE;3z~A$ev)kd7*~7Tc&$YN7hw6M0_V%y7)Q(E~cFw&> zGcxI%_Mv|;NWQ0l?@u$*V?u3WUK+-x^=5<-n`kpN6eSd;~zS7sHxZB zVnP^f(4fKV(z=_YdZ%0^I9;Z_xz4(`O6tnX4*e)ID3oWAL+|__9nMVXB!4&vi{MUMl`Bx5MiT+K0=pP@b%OL$l4y3Zj417Wla>$|ko-Z8X2y zy^(e3)Wg00v(z(q`st@#%npO=*ROZJOFdP`A^w>4Kf2_vOMjpG65p~HDRZIpDDWHPt&fjPXY+a#upT{o*{IRu+?sauotcI0+qXME{Qmpz zyL$}&$h)-O-Q8b4_ebmb8rs-Ib%FW~8e7#G^{sN{Dt2d$Qa?1Va>bU)H)pC_x=6YN zS@3tZ4C&5ECSSXWeMc5|4d= zJG${&%~@Sw^EyiV#2_5PAhmw2>#*)MQ`*Sp*>~PqzviYcU3;>=(fL^Kr|74`ATc4e z49z>y+jst$br_vGb#nC?@)GIZK+U5Be}+l#O3iAQe)*GQGJNy8_MT@i7G^@3O~%l` zaF#%S>&R@@{oXo?Z6~`Jg4~LDV%4fu_S|#N85;P(2Oqe5j9L@97HjRazQjG|Z{%Ks z&8RLmYTVT7)^BXJ>(sM4H7i@~%Ee!(UH1=W1rTu(O+W?QJC*~-4lQEyZhH%p}gZtJFu>h*1u&@zc;;`ae=+HeG{B- z(q1mEe%-Nlj)?^eU7NjC>o(ibHST|MUVQJ9Pd=F#3vS%F(Yv@DlIE6)G$0kkC#70)9UIVLJw~pP_ zwEhPb%9I*ktXSb2ueD%~Vn6qsM{nT@us2E9}Vq*Vvm2FO`m}&nE7a&$uhKEPiH-@+ozV|FL=HY;|Qp z=`!W7)xEwKUE}pkj*0%|hXV{q0W8B>Ss8OTb zJ+xuN27BqHmkj>)?%nI|F?i$NVvQ45zvhYi6COQ__-Ony9Fns%xU-?vu3gs}DtBqv zs3B{kR@`*cP34LeD|W6d_^Vmg_;ZrU0*tkeoNGcq$j5zfLeBfx=&ahKCAYW>`y0n} zk6H`;U3Bjld;8VrJ+iT|JvlCyv@e~j^-=G`=pXgdUPRrsuh5h>@gG*ZIeku9fZcra z&DHhVf5Yp|>&$%n0}njl7<}lVha7|WW8O2gf_W2I)Lt1!qsz-P8KxVv2ibYS!^6XF|NH zeFjd%ooCK5C@x>b&_P{UPsH~S556%o!B!2v(mJ+p<#MPfd+dA33_thPjvYG^b&$LZ zU8f#T&H{&M=71@-A z<%*^_!2XUp`|l;~^}U1MHk?rJqt81_+BZ-6?yfnxrG2?#wHDuB3u`UT@2bY^Vm{@& zu(yBBRd#e!QG0F9MXG;^U!7~@>n+R@(feSHrSeA8oN1$^v!<6^a>+T`Yi}B_FAVY? zP=|&&`dHMa;f^|*eDjymyJlYVYS*qE{1(%`HHFpRo+dwg_$_fqP76bxGp~E>L!bCL zeckaEyZTs=7|`#Zv14+)Jv;Rh>(ZvKYSANY=8Wl1`^cxzZ{k@D248*kRr~nkk8R(+ zeNOv{0l6QkLBS#SBm1;c2k<;n8--Ie5e~^&s88XSwP&1aiH%%6hnP{1zt{dsOVvxi z_UHQPf5g`_#hp`G%pGW`{Z;B|k16)oV-6IpBhGVkdAh;}XK)-|tvLev8>}CqzY&|G zKd#QKT$g-z|Js5s=Qy;Xusu2|yXLFX8~qb(m5j9wTB8nk%)accSv*BPnf5F_-g4#2 zm0tPY7G8H=f8rf<0tTrKk{3%Kj!5$wMs-iQWAJNC@m(R!(oPn42R(P*hkDLVc0GXXmkTy{lT6u03q_EY&k7Pja(?#1Z&gI3%|s&Uo#$*BpbNe)_3n zkXVGZp3D;ZS}6A<29sL<>GYB3cn-Z^hB?>c6N7rKoEGAzwWsSR(!g$o3KdEt3;qm~ z&#hX%Sc-$}DOz89TyVY`%rV=7-}U^#-s-+uU%EW6_GppzF+;C487)Ky(LL{L;T}>+3vY{!koj^Scvx`{S7x)5cW8t>``y| zY}0l2@{9}BJJDRUxLdD2z*=b^>lnyCi2ZbyBfYnKes0ZzW?_oxb^M6elGujWTd(hS zX6~8Y;8aX|(_E&%bL6&>8TOLTa*kgjS4sGCpXYP2&wG7yAIJDh{9IJ~^q9|M zXyA(zoPLqVQ)_}bVq6~cIqowU^uCyQkk?a~fj#`}l2|{&vj=~3 zI;2tz9ytfSDAp~pUWA^n^6LYY zu1j&TEciLo>~m?w*oXAm|5tuwqF$?PC(}6XlOOz)X+Ob>b#D!o-hG7D5#M>uI*z{x zZ+zWz1at0jEVlDGhW|QR=O1&0JO8=u;}YDOwFN`VOOM)!y@}GS$jvz zBE+}&W3PiSi19o)gHe3;>eZ{Ae)3#6#6J_Ks2-5$m&sSSZ;4~P7Sch!!?h z&8A9~%HyxR@`?mm@OznRE7dAqm*NmUx1P>&QP0S+M{n290xT7G)ad4ROs{$|v)%dS zcZv0m`P@%egmcWyw1oMF_q$=tcVOK$c4X7__WrV~qJScF4*MxH}7a>k4quD~*f;w8ycA*1?>s4a+ampJjh=&VM<)N;!vW zF30B@zPBdbTaE51=0o?^7P14Xw_ry%-)JvR&#$;o9J^Xe2FDfZ)mJm&MB zG5?(7Kh|^LOwaY~@$hp=EG;yF9JE(woa&zm@xu^PZlUxi4 zC(I;J(5a< z&(;2U)~jwB_0*2_|2=c;JAf_h9M)P6X}TEmv(SPPJ4M}1MA(VuX3p|&QGFIJ`aH>bdT8t*rOK1z8=)3 zncKoYlc&HSEW#mv8-EPHFi4!}`$K4}&rhOSIDFVp8_-|%)$ZMt+qJirVynW)b zZ_>UQ`&JaNgR8=RS|WF`^&8r^r?&2so(orr(}w=Mz_e^@|^{_9S5EfxbfNtSDq(-g-bq<&vegqABT*w z7Zq$ht$kWB`e}|=t;u5k;I--5Onc|*9HJaL2QZg?yfnA^MS1mF=5uyPvCKZLhuNoi zX77?5_V%mA7Y-bt+@z<|J$!J}rcIO+H&?FG$!X(VcQrHh?j~J! z*=6Zu!B3g?C}=Dn_IZO_!d!#>%zT`O=E2lXi`FZ|n_n{sgPfbZqGvkmTQ4Ou zU0>W?A;V>|;E%Avg$oDR>`ob5?3$VFd+!IGc8RHD3`Tq=%;{^MucyV@vlyIB$RNhh zv20rNlg;gU@u3)_AIbi$Fm_;NK0BoIOQ_TD(O&fLFUX-Y*|L4}!sIMRw07n#trdS- zug5yYH*>UpYtY(0X`5@UTfG6@?^-fy%ml|Bc`HU;g;)+BjMl*)>`{jy2jOEFBtFC! zqlIt?uNdEle)`^7KlZxUtXWglXYSGb7i+&l|12F`d+oK? z;E^MP2WW9eOXWS74lsCou4~l_5}8rIfgs>Vayrar@aSWS6!ZcaJ|pF!;g&uJEC;~ZU+Pt0AQ&*$Z=`)_y7%64?e)NJoPJ0aV%kB!Q-acTFs z`IB0u8?Kzct@5kdGuy}AqB>W>?zK{9Q9m<{`k3d)f~Z}8ZGntEd-dH7cMBFQbol~0 zg>JzR8V7IT`r%z}KLr@{I_MdU^&yYbLi{mWh(C_zCdX^x9M?;kJb9A(C(Jku)qHF} z^_sdW7iPBnE*BTVV8@Of9FMBcJfk(Tm&&xx>zG}b{oH0^kNuLhcXujxRw=bTG!H+E z-g(V){V>&qmvxV`?Gsh!)1EBsiS{YJ_W#wD@wrz?_s~4gUZ{Bo@4wCt-haIv+<24Y z@1^Palyk(nnK$;(!JgE*t*576X-j7Gu^~Mh|F3?TysL|sDDi0Js?|PIFZ@Wka^?1D zue@zK2epTED~s2!Uwe(7iJ-p5xsQ&@I*Waxo|ld>Bf4v57VXQLT{GO$sYQ9hxeDpn z-sKnCN6QM>hl}%kudn^*wVAp0JU2P_OV3Qm@!*=i85XHmIC^cr3>|du)|=ZQ{T+9g zOIb+wcaDXfI4zv#bSi6a_ju<_RGU)v=&-ebA zxDYLj`r~!$j*km{-J0JIgX83nN5~%!7|>t6rf$-`c5eQkH2|vhySYU26vc!)ixe$d zOcvzMocydybDejO&Z+vk4(uuBWB*Zf&$G8udgnFI_rg~8ijy{FasKtdssbTO1}3-dt!{%XK8I9^Mm2OiPDw{ssWC;(xy)tYirg& z@MD##)qX5nt{lBb?Q>Ay)t{)xQwLQqZM$@^=x@=&q;r;StE7p4Xw-!dvggrz3-kT> z)`I+B?wpf%-%Hc;zxLdeyjwR8&bEA6&&(4SchA&qRi8|aR1+<)o@7zYhUFXCENyzl z3&~``A7$DvI*)W`&w>T>UHv$kgZP{m-e8X$geyEo86;2f3`YGi43Zxo)50)6_HkiY zry(w+PD9N)^v5GdhV^RteVXfV4D$Za1I5TwYS*sye!(j)Dt2k^6gSr{k?K3G`7`DT z*ayw~T$f+OW>3~g@905nP!D#sat_v%?pc0OsC_QZBfpKsd8=b_o_c9voag;5+)3{? zgqnA7)6I5pQwclz&>i;PvO;ccAi0Km_=)!RoJ=}PI$=eT!i8qcR!wyIeJfbMYtlaV zcX5wVhw|%*G%xhAG^|ln$9~D<6UD||YsF>XIwD7d`+8@puJt-McBz@>qOr}>W?0fK zeF|A{x=lUU@$=@*bu~b8RcgujUs$5%g3m?w;LkJYbrApj;)^f3=i!fu8S%%S!%zpw zkGI%^n>Q&p*{C|rhQylniWSspmWX}oG_0?g=K3b|keOqkRtC+xo=S{H z4(t6d{Q13ASv!ouAq?`hD1%-LJ%>+d&HJ{;s1aeDFTz;`3tmipj>$sENC31)6-D-z6-zK}=j&7}B?=3H+dPTg8 z@2Q756MOXcb(Z7n4-Sq$zh;TF)oWHRWp_4gqWh_*tIrb~bB|N6r!GZ(9xX)Q=|ytC zDL#Kf8g==p>eMgs)qkbuR<2yJ{OnmXzFWS0nd5*uAg>QK7IF>vgFV*DVNnLr##de; zFMiq8tI1jL+s{55#)bS0UoYII{kVL+n%-Slr#a@2llJa-Phb#Vj1Iz`pRFc#>eju7 zHEni}Rn^`#{hM82_YcbIv~Hc^Jz_n4E`2bx@6i$3Cu8NMZtw3f){AMLi}PZ+t@O_2 zwd58qzC-Uyh`CZR=EU8Dx64Y~;VotD$iw9|ADvILMe)YDjr3Pv)l3OJ{VRk<@f$p$bMW{6`|mrW59}HAISF-YSfyuz7V>@Q zXEZMKIWj-@;fMc!t&rF=TBE@?vCfeBRybsF^Ko))dGdga@#Z?pV5 zM>mVscWa%6m<#tb)Kwq9yQqNMhbo*Mh~yZqmM6_qJ>`Ip@n9~IJL%nna97$6Z7Cxw zD=TM5wpOwI8*g>Y?V6EMwGHYUnQgbTOwzur_ST$iLuJ7wdE?XE)wJO=ebjTpzYJSg$fmdzpF_D8!lWpPx(hUgX()BXcze| zyulxHFszkh%`l(C55pkO!B@ZX%8taC5C**-MssB9G%y&gS5qs5dEdJu7xyy^Q3m}S z7uw)wS$l}f)@|Bbt!m}0cjF7}q2XCv?RSgY&oJIpbI@J{#C);ZN@7i=NSM!h?uhX= zp?TKsug4Yb&_fmM$fGswqm|d%uIcgi_MFUOEwip!LYph!tFy`8nw_PI zEWoZUQmkz6UcJ7?zcL$6uE+gIjQ|GWk=g)SNNtK)-?ow zSId?yTl#_h`@FPf%_g>nn>Tdux; zrdd(AbG1C5(|Ybg9~)|&m=kY@AF61FAFdqQBQ@;EBh~G_MHkpRb28{`)hyCGnXa7i z%UPEnF3R!M8?&>Plm*_}v~Jm*SON_vw}&-e2j4%3LwZK|X6`@!X4W7Qcd*WtI+S9< zzS6jJPo#6IDF%OMt6j5ti$&5vasu9ed;+ft_bL9ByaVRokJ)_e!w)}lF(F^`b(v#Y z_=;l?pX_ze`(xrl-@AkHV|BuCh9RjhhC${R&;`~+u+|AJ@eC3dx?H(a7pq&lsVTVmZb}>d2wy9a1gD$IKc`r+BJo3q4BW9oaiE_m<$i<> zYAV#8$v^x$;ZHu*lD7V31N`uVWB@h78iOQ^l>2!`k2t`V05MsU(EXxooj_b z;z8D!us#uAhBh$E8Zy|^x^(NQ8N#|YxaC#$@ybH>`6kWkp?&MfGpMVmcjnkDZimP% zTuv*^i^X=Z7wTP=khw?1oiy+8BQ@>tqqXel<9FJ=wS{fZ!UXL@6rStL{=05ZB7Mvm zmme(3`OJIsGN+LRQ7cudWG3YoPojezI&^e@1AiwmiO|*{CUdkt4*lbA$B0evmDHN4{SgPEfgyh%xhqWad168sBro>85}%vk zk6|#W7E-U~_4f>-1^8oT3W*8P0^$MUBIXHUkeV5};)xg}ZtB&$pY{T2WCL0jw)gHU zW?yVpEgAk`&&7M_UdfO>r+MTR=v}2y^ORp4mXGz!9eK32p?gOjYv`_@+@~`H-QJU| zNoQ@Q_Jh&-boM3MuetpX7Uo*4Jp;~?1xc+=?OInV-+SNd8hXfm&I|{CH#&$+F+h*w5uBe}}JU%9JtX;6eQ!T`+&1;*gb&L;iMN7yJZq-7!Bb{re>3 z5MK;~ta0E^L~~X59S`N6LPn$p4h8z zN1tq_=TJS(V}d_WWmX-YL$xRMhqMDMZdni-TWgl1%E5|Ie$0C z{Rorz9?hvQlXj*0Dg8Rta~l5Y&#POf)@?JUP5x%C-e+QA`efXP=n||D-@#b8XG}~7 zKl#MPgXkhLB7Pc9$y>Zn_IZh~(|9e6#)MIS%>D2EvDX1&q9}vx<-l4y`Ulj_V!2`> zgMIoAux9tPv0iN|*jua0+Lv2z31hxQpBu({F3v;qi18eIwPJc#KjiLl>E7dw?C4YX z*a7w6++G~9b7h!Ub>`*<3%FU!U9c4hcE{W@7+`qwvLW$o+|5fERSl=fgf1@mCmxP5iOfLeHSj zO?-arwa~|ezIT_jMuYw`%SEijzsJ|gh|gKWl9WMokbViXtv!47v34E1+K3)C?afu? z?8`^R96bz|XOxTi+$ekA*NQ!HcNBY~iPOF#Pc(M9j9Z6J|JctjxW~*fTq6E1`cB-H z`6>4N*9HyfJ9NbGVb-%pxPJ-zO89t(*IK@LzVs^oR5Yt$!-m0`Vuh~0D%->fV_%~O zF>l^{mx~dH@Y>)P=y612LC>DQ;)~Hi3{Jfk`n)8mKaS2ZP%HF4*>i{%!l17c`Wl7r z8!%JN+=ACZx1LVDx{$$M)_=f2>)Ne{jp$y@cCV~pUp-#Q@pt$kd@iw`*FCW(KYQe{ z24e3{ao1SZ)Y)fGw{$U~W6t%DeIL(XRpU`#PyY8)XznV5{8k|X1xl;MEvt~~J8Xt$xLwC?0IDiYZi`pMCpRdV$ z67j<@h()y!e~fl|9rU@0_sMYR^JH{3nj;e%`8ow!NM1s2Or4sUYVH;EgLoca41?$( z^+9qHd~tWZ$0NE`v^Q2&w6C93e(|vCdM?jUeyiN}h>P>Y-eY3#ak2L#x_6iS?%np; zGp$`++RaF7ULo9XNPRr^9df;7)`k?+dWU>3X>aKCvfxzg)>}%&4;s*a6YCL}!PU&| zZt2*azf{Y#Pe^d4*^t2l`cIn{=9`{DVliS9Vl}uS=k;|#`11^+g>dQpvCmClHky~9 zgkGR&qcmv5 zY0;tOxdQEtdB$0jM)mV9m_O%r-cuN)H-zuwy+@1ik+4I);TeR#D1%-Ly+8K#YR@70 ziLVDS?VVUXD^;wySu=pebt$Zl1{U=91`S;crx z|6+cZn9up$d!&2K?KAPm%!})zh_i4VQfxLF2Kn5EqVDU`pysDTht5Ry{NL2HNyD4e zk37U|27O85E@Ht49$=2+Vdccz#m{cXAXC&ZB!zoiH ze@D%i_cokSSgTlYv#Xm@LxCe=K{)docp?V*y4ONqry)m14?T;%X5;%PK1cESiJz$< zF7&wxH6pZ`IDtB~-#3$939KZgVbYX4TTII>4|+qJf?efvW5Fy~dB*~NY2 z9oyTueAxL~$6C182E7#K^Fs?C?_YK4$6_wupUPd#=PEA`&U70;er#`IEYIMQCE>g@ z43Zn5QRE|GZTeU&h!#fULH`)7ghOAaA&!hP=wb0jVU=W{-7V`UvNr?-{ONbLx zyLCN$a(Ec@^CZj{GrvIpu1`O7u#XMvUek81Yh?d@skMFfr2H@1_q6xD6{LOi@5CFk zf{s0A24np^^;P)X{#6%0DeXvoI`m`jvOK|=ZWYRvIk#WmKGP>nnyB}4gwq#vaJ|-Z zY}xW)Vvo+}BXD*i9pv+#!KhD8s)bP&eSGNqDC8$ewUD|H{+O7Myo7%n^%<{&+&3`D z3>39N>NNE4dMhXCt@+Sly&Bu=_qP^<_u6N%nv3(jnnw-SoqOhPaPz9+`jBuuCHs>Jo_W>25+z_{__+4K5!+i(rHt1AR-%pXbiA z8D-Je3i)0b_C6U7F|UWdj*UwV4uGI ztb4D1Hn3Mq+qtQ|efM$)`_J~)t`>M~9USYC;7ze$WF0W``s~3b{TX<=G)Qv~!9T?Y z^=^}E^4R{*jUG9~MvWY0GiJ_EPO`)?i2g)#V)V_k=2`R%`mcEgx%yfST1b9^KTpab zG2)4QGI~hen!1qp$Has_FQHCN4)14Y{5(H7GIeV-uxs}|Hb@MM+uuyHA$}Y5qU>C)v0`Ev{NUf6&|GMuz8v@ZK(2ve?yysn5Y6jF9Jg z&Z7Kz){=gW=kPh=LcZ5)AsnKKTru?UL_QfkBo`t!M2oo}s8usVLk*qyl^z#8V|35Y zv67!KXGbgugZ+Cnw^ui|w{IS===Rk;##(G0u-gLx{=$#7w(eW$&#k9RgLco(9{kg+ zQ;Uklr;qFP>F7}-ZOqtl&c~5^`dK3UAwJVH==p=MsCoVKU+3!ijQV8HBD&~nH%Wc6 z@9B{X!68~meoRbA&4|2&`iy6gp0S_bg25p}2CI)e(C+Qf)mk*EYTFl9wQsg*E_zdR z9kA9Yxi!Jea^0-2X(ndH#rvf{7o9E*I=C`-@K3aRTQ#jVbLR9fi0z55h_k4{k%#iW z;}2oP*JV6wQU36`e9YH8gVFk7)F;DW)VvnrlYPyG{xU|6;^RVU*2IJ`NM1s2OfA!| z@gx^vmKp|`$LrsJfVFDV(V91|V$UtEX5T)hHE>Srv_^?F!HH|q#iC+C@%N(iC*A4N zp!XN%4F0J$a^#46#*7*J{eXdk)cYFidSLAN2ZO|6FbE&$AS}Tdym{`p`p57Gd)WT{ z`9!sy>Nh5T6@k(5=-hN$1n)DJ}!hkSVUJbK88b|H%B>)YN3w_nW6D{ z2@JBfiGH15drO@LP3LnhrGqV+RJRwG)e(bbLhVajC#;#)4Mnu(GUwpasXu#`AZ82ZQ)RuY<7X`GYCXp!d)4 z=K1qiJ_nyX7cKP0_hV5G@ykAM=68|{c`YP2B1a-G@eC3-Fw>9k^*v+iG|Uwa8#dfp zwibg;Yud{z>f5)EmyN9zW={_72eY9t`!n8oI`!w7u^EDYnw2Y>ypZLdoG8xtmm4EposJcIa2Snd%_q>4Sfgl`WjSP={)1cK6j;@`DP4Z&zi>cGWAU@Oc^Vxxy>P<7lkt{W6;9 zwUF91F(LPa@7eKhjMfN!&zL$5^FN-!Huu!GUF+{sZANP~A1H2nS6=$Av?u%N)Sm}O zUmpBZtW4qL1v^$tvrA`}YH#hd?raVA+kRAM>^-J^kDnToVDr1@(|KR@)FT;VQ>RUL zISI877({nq5Ef3xpw~j5kHBG62ctgOKNt4=bND`(CPw6UV4g$R#~*tJA5-5B2L0@U zug}06xd?S?>NLcNBSwt0yPMx@?OHUjH#fDk@187cugtvgVQEjY)2Tmg8{ZcE6YP#_ zlV91fdYabI}sUP*Q2dTciNtA?I~NfbZ{nH@hg*Ern4h=3~i$GEMn~8 zZ`p5~eYc&7zr@G-9A{3jFY?qbmswxEPvgc<*7?^nUCoVnpBe}=%*0`EfPaJy?=yXU z1#ZwW{46Ya9rXNhMf2d!e~phn`|LAkd>t;MS_t1T?_)x0G{gkVFOaYM8X>t843dNR z^>tnc@z1SV-)l8$)_GXkljC&i&y6=+7o4ef^A*W2X;(G%%Q`#O`ZY+)`Q7eJTlU+2 zGI7uMW9-4)Q~H|QlUuPMx;Up#F&o^!tIqwJDnA@D$a~A26z@0rD03}n5*+#-hvyMq z(88n)!kp*N^XNZ^{(bSq7tYW_*yQ{9IZ-Y2{+QoSt(qDkvxI(j!81q>0)y14=@sLP zVX=Mt4xHb#Mf#KZbZO8vg$f2|qTO)W`4>y~UL4shWRJ7zIbVgdnH*HmTJW25t^+D!EiM{C6QlrBk!y#N?UKgVb zdS8s+_57iEKKApU`_F&=V_$vsm3{f;m(Cyae0(`t=s84Z`5pXD@)8*2-{NN%$V=!c zQm6K7o2U_b2FX#V)o2~tdTCI?>CmAZ*|P;_n(2Jni*zQ$3p(4*1}NW{(k8uhkMo(1 zoihM?;rTitlRPH(*rxsWUYe#ebk`PkXXE~7^L6&_^1?Q?&mGpkUmu$|d5Yf8>8{>J zFP8Zf^alS&-xhyNjsO$*NY5dxM0F6J&^rwF&^gSr$m7pH|J=U$<{M``hE4o9TIe~9 z`eS}K{{~;DCSM{Zgh6Im{XTHiXQ&m9)$B#TetoTr&JDY>ex3WILuvnPEy|K5b8seE z(TmS7Al-YOa~sKZC$&QNLiQ4Q6Kg!?>;eC|Cr9fXmQfk(jd=xhF6s4lc%x?1*N1Dy zKHq%3y}9%{o6x7S{8&H7AbBxx{>I4S(!8glQPW-@`h;m)zLbseNut+#2nbkeB$`3)YW!@7mEC-C1ve zv?%4DsYi|OtQ(vuR!r=*tDO4zF*?&_a3h@?swSE8n_s)3C*U(SCAD;}*aP9pu+!GHl zOGwSq=f+V6(Ld_b)M>bnw6~h|?$y<5R{1>zDcxVgjJBbN>Zj25Qmw7FWGU$D=*Fo=xlQM_~l8c~$|NGzn9E12|xa52I zey@f2WV8^@qYTn3@jB>xC4Q!#yaXL|Imtk+YZ8NPTHiBXnsn};p-cC+xjXo~Tak;- z&)=bH>gUEaPiI4$z+O7Bm(iW4;xul;v2$WM%b2s+IZN^BG4b-Z`Q04cVa;iV+#SD8 zEZqB%^%FN}j_!K<;-M1u%F?nnyk~<%27O(P7>gPq43dYUKb}Ff5GJAwMtyNKAHm0> zalQ`Ya}hM~haY}$9Ks`95)1s$rT-afuXIvXbT@V%U6yF+JNa7O#{ zG8pt{uk-OUW8?L4W_xex6;AWm*Y?D@5Z__#hK_BhW6&ft%8rMRMb#DQqu%hPh$C-S$4AJBfbZe1*X zmNkl6BgR>MZjBgmAbWkoU2KNk&CY56Wu15M#n#*Gg+*epXG7^nf7J)WvyYg&qwX7J zkbKlLhz`O8J`#jw4bWl%1{^Y z;d77aULtof200rW-P=7kzgvTN*u{Ei9c!>0Fa2FFjB=+<_628s7irh_mT)j>2XDT6SD;ftdhi0?)J;LkHiObDwm z=sD!)5oeN@@cZbMkQ>1u+DyJg%nE~kAGjeyhN>ph-}UYK_U$7b?Dn1XsretJQ93^} z_`6zx9Os?iwPu>Rv)aemBdW2y67#uU_h1m)K2B$6kI$s@zAuyJ!Blh|b{N|oTPMcX z#hY8B81DBSG6#2@;Rl1Uv-~u}$-bn|FD!3Ex;Joflw(ja75xR)X?O;S2fZ&QCrO$U z!%5T+!%&nz*orbpEa>^;3Xh&av=bf0&{Wt)XNf&wke;!h>5nqVzn55++_vZ82nwW=^d#qSB-Du7R^w-rt{12xt_TfV~^3i7pG*iJ*%#@ zBb&AU0iBbt4Sj0Vzs7uQ;<2>elprVa>e#DY-<1y#AKQlJLUY~t|&icOIvFBnu&z_I*qHD2Z@ts?z<8%(@ zWbV8To%Q0*dl7p&M>0J3MOU4JaCpld_SIt*#9$dQSl7*(j2$<@&BW8|@(f0OF$_jy zLEc-zwuk>?+zmv79khiR#b*^sz31YjXIfc_W>7ru~AL}jTj`NzM+#O^OaCi2G)-}2-d(oHC*)Q6s zep^L*X|WjWSCq*sN0FU?XvI`}(S?Gh<3>s2Ss z9G%PjJ!j-H%R-NBux9A*t&-Z!^zE7vviHjLoVIs$5j(tD3~^=y)CySj$ zAD-O@b1|)p=^eh+X`DOrz@K5tIai!1>Cctq${8?N$lzCxRk0TrSFjO1>#L`rH5g-< zJs#n-(C5WTeKGZEpNo(y{FEQ|J{Y#}!@f6iA_j>Oc@7MEEre%c!l(|iu7v)z_r=k5 z#?g3?Jr~#;SZj`7k!D@=d+3(-*9`v3R_x+r>6(>E)p=E~`1d)RbbjYJSK}L|dA^>t z(^#kKX>6i;ypIf%51y1!=hR>1&bl}PdoG`azX*3Ow}|Gma0h>3PJ!MfvWK5V*IyXFCd2fR4o}I%! zT5*m1Z3(xpL?U}m_k2#9ggcj4cz+R%>CFRa*p68Bh$Xs~tA7}sZad|tUvnRiL zqNeRwUd4uYuc5wb52u6F*r@fQgS@}^JKw8=LGlsLVAKys<3R6&;qTWl$oHd#J}-&t zpr0X()~Nm3I{G6pNIZxy=4?UDRBw`Y#r+ojQm!5R)vRK%6ql;5GE3)yf49DWf=!pN z9d(!HS>$Uw*GOYsYNm1i_POy1hR=Ox;YG?ZZd8sT9dotfu%^P9KVc3Vjqi^4v(eZt zF|SZQ5yp1jzlJeh$d~6YWbKg7UvvD4InKj!=FS2XgHP46S65WCq1{3TM~xmU9USdu zlIhhE@57*%8%b>XY1IPffkr2DB?1`eHFSdh{5#cLoeHH^c1Kqw3F6 zm!md<2Erd2=zAkx1HBK1Bd>vQ1%K3JlGdi9EaHnjgD@P`L4FSmk`H+X(LrKW=BSAq zU=aPLzK#wO4>D6N{TlIC)39Iq@2Pon%3CM5PXF-6sIP6B*7|F1Uh8!of7DuDo}6Gi zrFm~JyjZ-&H1D{a*5?*p^L%{Al{y~zY>Yk5@k@;Dd~V^j&ihw?jq-=D#n8Ko?(9jJ zJ1XW5i^oszFQHiAYI|#bUU$a*2lF!8?vToy1hUpUiHtr;BG0ALwJj zs0I?RMKv(WpU*?044y0=BwvO>*!3}?_r;z;bdY}sISD$*d?WMT#DeTOFR_l|eQT6C&sy{vo_TuYk*d-;oq+{& z8;aWp%dfIG=jOK8re(6%rp8O7GuZB#%86!YvX2&M#(!LH8{WCBTbs-JV)&!~PyfrG z8B0BmUa@D;$AQ#M$VFfU4Lp$#hATAC>)^>4L?bdn9oPh zLE=Gb)c9dtzn11y`=z?0`!F~iR_Xc_=eMYky4mdZaXay~3pyY3wY}@6HOtzS=Y1^x)f<}U+4DN*eXQpW zovWfV?4@%u^4xu5j+xar=7h|>Iwjs-otnXRsu#0+R%X)~x{3DY?9BG@Ld`!+$YDb} zm)BXp+9zn_Xg34JdrGcJeHx!fJ&yV`JzIQYltKKkj|061qJQv&{&^!7jQV1W{O4z9 zcrM?|&+&N)Kc8L+dAQd>{yofYp@S!45MK;~s&#&>zoqam(KG3P@MqiY*CfAL^HLih z7?eT#U&L!hKAjE6*D9aY{sgM2q_#O7;#?17=ZuWDdrn^4yC$sXp?P7B5z8$ccd!?Y z?_xC+e65S`i1B<4Ps}-=3wtmZjqQ>$7wR0mVTT-ZH`{y5u28<6ORQzI9g{=m=>Kt# z?4FrfJ~zDbI4OgB7OF2J28Va8Y(0Bx{#dmcYSYA5_&8se@oSo3(ATAXf7mk!Gf@UT zdtL*%;%~hUMi6v0Yxs;Z=wm|9Aivi$$jk!kNr)A=SA37e$AhdXVJ|}EC@)ISvY)D^ z>1PFhmX)|NS#I@fhp+4ve^j}x^R=u`Bd_fyUwd!m)HYJSck6KJ-E{fenc3`p`LsjY zt0YnLoYqBRyp8zTNQ~!dDA5?t*HO?tn2Ty%)X#d|;~e`+F`cWb-kNl7{mu67(#vhv z?3}9gWK;~Qn$MIBjz4-XJH^@SVh`>-d;XeK2j8BP**;mE!JeC()17PCyPwuWYR@hB zBOjqhLNAQE4D+kZ3wQ>7O^{d+KTQ4rgGuw?D1YeS$r$uH$n()puZ8?vVoh`q2BW$D>-HV^H;_71Fe1r=n}hUxGi{wC~Ef%4-|WxHtW)8wX}kzc$Xz>J4d} z&e#is{zdoNX>ED;P)l|xW_ok}g^H=jFT|Fssdzt24KJy$)pJ}eFRFLZ+`@AgW$zeo zF1J+-M?81b#dA6#G7>xlvhn_+5 zUzm&j=NaTVXrYe_i7{ai&GmUPHEL#9`L|KOWQLmfRa)nA66P)N!{j5reqVL0>b zIp*Ll>T7*I>+=dRmsm@Q=CeMw<4Qc|*%NbHD?8uHb^pd&?1THRmd@pt#)-K}aW3C> zoQW^ToY-^B#n^+p*To|G$763!|HK?VII4kf#yAWaOwd}-JT|tk_B$FqQTy@FcDV?9 zxX=UhIWhC|=pcP!a$1fp^pVUe_TC-C-TKG2%Gq0o(qTkJao|eVi=@0 zM2(31g1V(&-wuO*UIF%CP=5Iv=~{(9THAi^=Qq49WrGI>Yfm4|=+V1iO=OSSX{@b$ zEeuj`*{QsC=Zq||{Nm=&*Wzar`(|jK_p?6ED<#(aEDBoZ{VQ7M_0Gq4-p_{oac+GW z(^XZkt+ai#s;FBB!u;TiFgHm#kNm9T3at}s=$_X;_=7jDp0~uu-Uq{8#GL-c*n3MF z_?Glku@2KGf$UQT})g zUnld$)CpnJGYG>`2GL!9HwGWPe@frvyMsU4 zR68C)4H;icUQ5q*zG}-aP7Lc4yXWMyPu3Q5n&)O!66f8ceirV0EhSpNi*fh=a*8N( z>dQV{G4!vGRI!5(ma#pnwWfE$#rDdyY|=S;$Ha6QV~pWjL+%oNZ0utgLU}TVp?mMm&tmV+%Ph;H$GXmmv!^EH`DWR~yT6$>b&AcJJ@14JqCLc7XpxTv zqy6D%EC_?>Sd>ApfiQ^X!Cdq|KK453{V@!ZZ}WRRgWLzi1Na? zOKwke)tDCR@wq>zQ-9RgwfD+p>-r_EVGouT097u%7`O5+l1$4TS5kiEmI4IkO6m`-sWx$fR|H`?2aF11&uXBYbkGR1V{5ik`q zuXC?S+x%nr;$t+xIAM`RZph(B1>@aKE$n3Nr+*KBoS~Tk{L3XM2Mkd64{q+(I)d$K@3fKkMr# zzINy8#ooty_F`A^h^)~-EP2L~ULB9{=5c%98~Hbr$FnAyxkvgV%kM_0X%88s_F|01V-(;5l>rCDA;-=3_l~#m|a4%=uC0KVzJUH@M^P)7rW( z9vzwC6V1eKU(zjpo??xGsw>s+RX5GmihnbymvgQxI8~e6>y`rZrViXbcivo^qxg!t z@ABo#9D}^q=pYO-FZ2HU;U1VL(?QQ5`WMwe^pAMYGk7u`^zk4JlIKwOp%>%p)95kz z2z5)e8ei=90;W#~gZN|V)}#|@m;80`yV~99Z`e9K!!x{J_$T7{7bY+t&wATf|Kd1b zo3x&ySpu(jK9^0*C&Zj$x3F#;#&ky&&mC3ndf_g?vyXIct)?cD?#B|h%JyVXa zn1*={xx(VBvYpf%b&tF~JA=Kap6$EyG+Uz_0bQfUr*%!=X`jjin+9gsAuV5`xx*oY z8l`KdJgP*!QYkO&ST%JzS@3&U?>43L&7LykiFxzpxEO!s$`#VWrN`+YeL5I~1s@Ok zyx7+UiQhbf(H!JN{GEuwXih?I?dvk+;N&BIJ(Ksv#DnC;Oi?7MRAsUEZ^)X;l4U96#W6U#{v@QelFvz+- z<`T$xsX^1DBX=i0JAhL}(~Hz%pq{hFDDq~9Z7Q($H9geB+uiUxLQh#J^9*1?xOLX>s5I6$|?<$-dnVVcyPVWFDCx-y8=Z?A0h_5AoIQj@$r<#fC zbnFGWOSPJpq;D@wz`urdI?otB)N37AH24i-Ht|N^fjv34X`lO*J=55x2_^0Rg?)c) zQTv*wD&3rQ@2#b7vf`ym|4_W-9sjwx#H}CRa$D(jx873n7Flq*t$Ujq8K+GcwDi7Z z3zcVveUdqIW-I1jErv7b zYSgHqy)2u$dxN}~UNJem-}f!nD;^NlufBcz2EWF1hCznaeG*2zI62dIu(w0Cv*#7( zy*4v4AEmx+nA=8UJmR}p{VqEDnaEvP)#}6@`Kz?<6ZKxHnV_Y_k*;Qej7q#jd;F%9br_ zRjO3Bnl)=!ojSFxTD2NqSFTc{XUS5xpCb!Sr`4@mGVSPLy=E<2f}XGk=2ZD)`Xu4} zs`tfF2BR?{3=$I(55kYH4JKtUnvX=;^N&4){2ZT);DgaXeDGZ5OMY&U*;RC!oP@dz z`H0wiS$g+>?VSm96;+zYD}Y8CF_B$Sqr&twsNjOF2ogn+mVFS}f(B681yNDik|-bu z9U#GkorEkbX@h``sB8~Vac!5jZN+woON%HX$C;ti8o2%c-FmlDiD3pjb|Z6q=X|Nk z_v%&My7j-`es9%rGOw~dcr5>`KJRMPOzq$~^Sr?w{>6t{UjRSW)(TXJAxC2=n!|0e zNBqS37B-G2J-Z1V>&ve#8V$UBjA!?l;i7UpKoS&_fQ)@>2%K)+EB!1J$M zJBU7ZHLNaI0tS(Tl`)7th%Sa4)~ecqPcVocMy3)M1aG58jWRuZ_OvyD_(k~W$Us-K zMZHWEe}9*}>+EEnYG%A+CCxdjwsL%(dtT0Hu$O232jxha=Z#LpzhJ)Oej7(Y*OD)b z=FG71D$BZPzJfYB^y>j+o$Bd!7hEJgc~-fsi{>Ppj6;W_Tk)-le?Y7^#JWR;57tp# zL%gk-=KV6v&73<-?_0PhPT$3uH7WJXx<}43t0p!6CU1PgC$q-2KQeN}P?J4>ft`y+ zoS=8_K6b7(>mm;wI@DsYU%!5)PoF-!I(P1TsmME#l)G?7wRJ1!P0L-JY2$3!vaOIg z$Qk4f^#R1?h*7(m1&2X&rOO$+I5jvzr#ipn|H2^ngOHmpHv-Cr8_xytk~1DY^pp){s)SCG3N)FXZ?$!OQZgU)3q*+jLgHI4d=@6 zC!kJ}b=|COM=tE6;;YS{mNm6@-RrXJ{F*x7hjqBK_FPoAqVHMHN`6C7O9R$ecQQk3 zp2`n5MH9|6%oARd+R&_;eD40d$<2378_{C%q#>fNZ@lrw?jr9*Q(o3X6AE)O54+kyba6pJ zzQrK#Cm}9JuGY;`LL?zl{nR_oo;GcG^S(oFZF$M~A=lIvd5(Ja>Jy)m z`tWY-5^x7GPRXl7;E)^=a}9?L8y3jHq@<*8x_0e4R^**%%9=jx?v=T74`s_9WIgI! z#jC*}bpgm8*1B?Y>afxFC{`WL*`n4)=nG^Y*97b2 z=ZMQt&+TgW>1)}4$iM#<_F98K_3u$hc2m5b=cB?yDf1ZcZSgNYUDL|icwgbq+E^a` zh10df@tjX9>`C5zwHY1TUHI#4K3&_^yr+2G8`%xbD_RqcwOXvtie8mpu_L32**Le2 z*|qR;&86`37tc(qYm`?|y=uHs9!q$OH><|SAJ%)z4i!&||59~bFG}t$(VDw=rwoX1 z|6rf^#wp1SYlys~QIDRt#wuR5l|I>~_&t3E2B|YA$AI5Pe==U_Uoe=QoNVPFvQRpC zdb4KDVnyDGq(!raC9lrQIIwWxBH0nXPeR+VyWBb-Zhkwm5F9#vj7_)=iS(0~t zp8s9hbAMi}HC%EpKD_IRd(7&rVdlR6P0h5y%)_i}^2h02l@rb|#S>-AJrE~7TjxMp za)YtMx}JH#jKQ@}7kS4^0|yQqhfPeJ0Np`fQDct$;Q3)w5kJMYA+|bv_;8Cs$v^|i z4$NuSu3deRcOq%##H8-|OXqwte?IR^Twv`%WI6Z6{ScqQCPW{D3uhM+Ck$h-vK$Qi zBo2qpKSA~}W{JCiJ+{~a;2E6^&RGK;-^A5S)0f0xqVwj8B>SpW#^1s*@iFo-M(N!@ zpZYS7n$Qd6U%2%`L+e=}^McwGU*;j>kahSI)DVAAaIv)$U(HawPPqwU)9BbY7c{o< z5#NVyXxGSPUhkuKHhg~eq+1s6TtDaVgt1Ac=k<+E>TPvQ`mhG(kvq;a_YY`p?&{sj z^y<>)+ul8I-gI5NHqAud52EX?t1E0hPkhSxkLX_d3tOIbYI%m(F5pz-)r=fDQtu2J zWbuc+Et_!TU3cBpMC6@FdU#y_c2BLz-Ax^JcJ_Q5qb674<`-j&A)Ane_y^=ns9$jU z*u@CJATdH`4~AtSI++hx1ZSKN{eYha2EikK4ERF_qx)I=6}>_~k{2c)hh3w-d|%jW zIC}IL&yjLWO`c4xn@ilx=Iyf@nLWzc?$;W%`&qM5>%m)n>uQjZchDaJA{$v5grrxUU&6_Z6--Nu#aLRJ$l^oafgmwZxeYxgtVT{ zWzxZ)phxH@o)dE~z#w{qI6m@_?}_0nZWUl~z<>ex#b(HmA$dn9Bp2(}S-{S~FC||BHt>8;%jU>#f$en-9dAOE;Da0I@j8X=vbGB zC3g>|sUu-6aMp9lf8b2BNHJmNxfQ7{Ypr~T!qkiZG-lBC(?<>+m_K9c= zpEj#k%ElORr0}LcmK9u|D=>oUAk8ndB;oArM;vZO3}C2 zOvEtQQvVMA=v%hfRpc_saiVXKgTx8ths-?DzKFYi=F~fWDP6ohFE3yAplVqqyBRy& z8}b~#gt>LdE_59Xly{$L~AXrF#}Z-nl$jHT3@%k@D$VTl32|Js-=8EJ@fI3^UZ;E7nyx) zTj*UZtt9tY!wf&SosFp=@4k|(`>Xtk_w$;`mTP3!-J{+BIfp%m--<8G`(A!8%&~SA z>!wkQFCDLVoTc4M$Hp(6I;ifgBl}#^NaQId_fXNQ<)$!ynOUuz)A}`f@9DZ#W^M6G zGk5lH^^W<8R^Dsfn;=FE4i*1g(y?R51|sixN%d+I$*ZETct-RYz8e^%@9<05C$G+U z*BXp=Ei&nyJ+l3poJjkx^0nur^leeIeGw|)&X;D%q=Ik~&$)-!wZ&oleiU1Gjid%4zyzuML)A5f0= z3(a@jQ*?#-qw*84DE|D4Y&+)b5EBM-$hjAVIr3ht;ljKBSfiQsGqlcuDNd>T;qq~H za+OEvmy%TbT#*;1$&^X$g;=IIUVO?H;@II3+-kq^Zh zOpHUuBQfIMy?Y}Mw`%(oW5{zS>+uo5BDNYBwQU3Hc9w~+U3+qSh> z1FOjX4jnpJ{DD2>B6=4>W+MO4zYc%sdd`h)1NO^)@)^7CZFVqa(5F@zuG;&Y5ghe7G(cZ9vx$AdqPRsOe*{E@BbD{MaS2O%%OAOtRv zkNC=J#~kUs7^nMwird0vvmYqTUwQ~13*VUM4+fEE+#}C(k0R$%2HdK@1XEIJzz-3x&|bT@V+`WIOW{=hZY0IxZ@`DS)Tw#l8@PkGXY8Ctj2 zbENrc*J~d5ZoSLObh)agWLCUl&B`?_Xky-4biUQ2FU~HPb>t>^Z!>XUFvoi)7fZjA zd&Pzn=047Upw0@#=8{#Td7;QV7HZ%A`q-H>XB2_CP0u}Jp5M7$IM{5*EccI|jLM&2 zo&m8D>@i|<_yoe>$L-syY$t&$U*wc;mu)?ag0vU_1CE8sJ6)asZ&<^ zq+3@NEZGD0vNU$VB7F!B(TVt3j4d#NEW|#eAF!_y~Q?IAhDb5;p`tE?!7X z1wR>lxjJin4+u<>U*>y!U*doG*Zdxzd&|}xX07nIb>;o4M^;@)W*qN^9J^(P@K=fC zA2iXL7|*u9>@?G~aSfyOAj_0{IE0)d2f=z&iW6Gh3g%=#?v)=~JoApYp;{~LS0eAn zAnDVN!oW9R4t<9m%NXT<#w~FLaELypc7XUCYh)9T!Z$`Ij~FqctH?WEQof_NWZeIN zL1X~frwxi9Y?MAaN93Js^w=Z!HD0!G?&89NJiWg&%hp7ZlR%f?qtKV&(AgQ>GkyyA z0Y}bH29LySka1uQT?_F)e6WY_ONR=4Fq~%~`rHJKL|dK!>_d<+V2?M_({+KR3J}19*wB%ch>D;rANAFg3tYXfSbj~fp^<9$3F(U8(1I?N~`I`Lv+#T40)TIy;AvO#S;UNnd z_w+6Oj$TIh(Enf&o6f}$!6O9Tkaxs$!0OAdyl!^A^s@PLBwcg=wI1xowq|e9`HIQa z=bhk_k$bA0KPI}g$*HlUx}Dx!>$TJrdH+gk)27WC>Yr!882%dgV@xtO!61GdTZco9 z;m?1F|9dolS-QLC@#^oB;rMxTAFHeRbyI}50~r~a)~_W$hCIZkadAWJZTcQNg#HJM z=pdc}&jK9{u@8aKZQGwWJ9fTc-rbgNzS`DLYqEDTU#@FuKFVvvdmulP%)1D=x8<=0 zCk4sBZ6aOxHe(W9$bDj;fI-G5eggd=IwalOM|4uXSLZ~wck0wB*J{lEUj1ujAn_G) zjmSfAh;4&zK`*0+uzMKm;1OSiu@5ex4I8w5`dPE_nN8-c=N>itwf@9`O*boke5KjD z`aI2Xt#2gr9(8hWM|uPAWFh4oTC1Nv1B1kY8E5#$q4D^g>QqLFyr1d#`at%|DT;k2 z32!@*dteWpj64kEkniOGTm6h(jBEsxJQGVrnx|a!qheM1(aEHu8_RAjpPC4y+t6JmXXWp@|@u-~A8Hzdg zl};{}-1~z1NOB<9h-~>EnMnKwI}w>FnP6$zvRt!pX`xxae1iG3SnnlR*UapDqN(}o zipJ*sCH6hw5y`p>!}4yY?7x$ZG*<5s29Ge_z@PN*e<@xvO62`aKTaPgmQYO?Yat8{ z7v5HiJ{0!8b$A4e$VP|DxpOm=*HF#Pyb0#r<(HU!tF-2N!CB@nIm}J0e^_!aPjc>@ z%Cc^Iy8MrmkTgc85Sx=-@}G*c+#>RRrhi@^NC%&*x{J=j+e5@YKL^UWw0B0}lqriD#c>T8I~k@*=4v_F_7ZZqiF&Tax&F-ob=OaGV!Ct~9O! zFOlDt#iqIA)bn~o@L~d<#!F+G#%(csyQx zD)4-)g>Krb;f9L;nCuB_&}n>ZXZqJTH45G^FV^-92fB9Xaa6@ii^9b3C3|pe{(qLGXPRb@bN%6Yr>P+k%X2s2c@L=}5qk~)iV-0b zldHrZx%N~#Yl42Ep4BCyjnP@@-_)q6*3UezROhF`W&VKF&pfY;c8Pby!pVO)N3PRZ zxLJR!aN!uUi!%#L+qCr`lRtzb<)b^zjhYhwWE>cAyn}AwSp@h8lqPV9{pcdmt0hJ` S+C;nr`%hV_-T3=n>OTOtAH2i> literal 0 HcmV?d00001 diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 0000000..0505086 --- /dev/null +++ b/assets/style.css @@ -0,0 +1,67 @@ +.content { + /*display: flex;*/ + justify-content: center; + padding: 3rem; +} + +.main { + display: grid; + grid-template-areas: + "our_port search" + "servers sites" + "servers sites"; + grid-template-columns: 1fr 2fr; + grid-template-rows: auto auto; +} + +.our_port { + grid-area: our_port; + background: #53f453; + align-content: center; + border-radius: 0.4rem; + padding-left: 1rem; + padding-right: 1rem; + margin-right: 0.5rem; +} + +.servers { + grid-area: servers; +} + +.serv_elem { + background: #fff454; + align-content: center; + border-radius: 0.4rem; + padding-left: 1rem; + min-height: 2.2rem; + margin-top: 0.4rem; + margin-right: 0.5rem; +} + +.sites { + grid-area: sites; +} + +.sites_elem { + background: #abd4f9; + align-content: center; + border-radius: 0.4rem; + padding-left: 1rem; + min-height: 2.2rem; + margin-top: 0.4rem; +} + +.search { + grid-area: search; +} + + +/* Действия при разрешении телефона */ +@media (max-width: 900px) { + + .content { + display: flex; + padding: 0; + } + +} diff --git a/interface.py b/interface.py index 2a72f4d..9d38c3a 100644 --- a/interface.py +++ b/interface.py @@ -1,43 +1,62 @@ -import streamlit as st -import streamlit.components.v1 as components +from dash import Dash, dcc, html, Input, Output, callback +app = Dash(__name__, title='Jetwork', update_title=None) -from os import walk -from time import sleep from db import * +from os import walk -# Получаем порт со входа -from sys import argv -our_port = argv[1] - - -st.title('jetwork') - -ph = st.empty() - -while True: - # Боковая панель - with ph.container(): - # Столбцы для элементов - sidebar, space, main = st.columns([60, 10, 90]) - - - with sidebar: - st.success(f"Ваш порт: {our_port}") - - conf = read() - if 'ports' in conf: - ports = conf['ports'] - for i in ports: - st.warning(f"{i}") - - with main: - # Получаем все сайты - sites = next(walk('cached/'), (None, None, []))[1] - - for i in sites: - addr = f"http://127.0.0.1:8000/{i}" - st.info(f"[{i}]({addr})") - - sleep(3) - ph.empty() - st.rerun() +app.layout = html.Div([ html.Div([ + +html.Div([], id='our_port', className='our_port'), +html.Div([], id='servers', className='servers'), +html.Div([], id='sites', className='sites'), +#dcc.Input(className='search', type='search', list=[1,2,3]), +dcc.Dropdown(options=[], id='search', placeholder='Поиск...'), + +# TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO +dcc.Interval(id='interval-component', interval=1000*1000, n_intervals=0) + +], className='main')], className='content') + + + +# Обновление нашего порта (зачем?) +@callback(Output('our_port', 'children'), + Input('interval-component', 'n_intervals')) +def update_our_port(n): + return f"Ваш порт: {read()['our_port']}" + +# Обновление доступных узлов +@callback(Output('servers', 'children'), + Input('interval-component', 'n_intervals')) +def update_servers(n): + res = [] + for i in read()['ports']: + res.append(html.Div([i], className='serv_elem')) + return res + +# Обновление доступных сайтов +@callback(Output('sites', 'children'), + Input('interval-component', 'n_intervals'), + Input('search', 'value')) +def update_sites(n, s_val): + # Если есть элемент в поиске + if s_val: + return html.Div([s_val], className='sites_elem') + + res = [] + for i in next(walk('cached/'), (None, None, []))[1]: + res.append(html.Div([i], className='sites_elem')) + return res + +# Обновление доступных сайтов в поиске +@callback(Output('search', 'options'), + Input('interval-component', 'n_intervals')) +def update_search(n): + res = [] + for i in next(walk('cached/'), (None, None, []))[1]: + res.append(i) + return res + +#if __name__ == '__main__': +#app.run(debug=True, port = 9000) +app.run(debug=False, port = 9000) diff --git a/main.py b/main.py index 3d420cf..d98fd70 100644 --- a/main.py +++ b/main.py @@ -8,35 +8,41 @@ from network import * from updater import * from proxy import * from status import * +from db import * +# # Здесь общий запуск всех файлов и команд - - +# def main(): # Проверка обновлений from sys import argv if len(argv) == 1: - print("Проверка обновлений...") - system("git pull") - print("Перезагрузка скрипта...") - system("python main.py updated") + print('Проверка обновлений...') + system('git pull') + print('Перезагрузка скрипта...') + system('python main.py updated') exit() - print("\nУспешно перезагружено!") + print('\nУспешно перезагружено!') # Запуск прокси для сервисов # проксируем http сервер http_port = port_gen() - print(f"HTTP: {http_port}") + print(f'HTTP: {http_port}') rp_http = Thread(target = watch_http, args=(http_port,)) rp_http.start() # проксируем сервер обработки запросов serv_port = port_gen() - print(f"SERV: {serv_port}") + print(f'SERV: {serv_port}') rp_serv = Thread(target = watch_serv, args=(serv_port,)) rp_serv.start() + # Загружаем порт в конфиг + conf = read() + conf['our_port'] = serv_port + write(conf) + # Стартуем сервисы # http сервер http = Thread(target = server_http) @@ -49,11 +55,10 @@ def main(): updater = Thread(target = update_demon, args=(serv_port,)) updater.start() - # !!! ИДЁТ ПЕРЕРАБОТКА !!! # Стартуем интерфейс - system(f"python -m streamlit run --server.address=127.0.0.1 interface.py {serv_port}") + system('python interface.py') -if __name__ == "__main__": +if __name__ == '__main__': # Запускаем главный процесс, чтобы потом легко убить его p = Process(target=main) p.start() diff --git a/requirements.txt b/requirements.txt index 5cc3e49..c5f443e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ cryptography requests tqdm -streamlit +dash