From 41ebda6cdb0607074e2e0d092a577fb7d043532a Mon Sep 17 00:00:00 2001 From: Mouhcine <mouhcine.maimouni@cefe.cnrs.fr> Date: Wed, 24 Apr 2024 13:54:43 +0200 Subject: [PATCH] Test --- Sample_test.txt | 0 src/Packages.py | 2 +- src/pages/1-samples_selection.py | 43 ++++++++++++++++++++++++++++--- src/pages/4-inputs.py | 9 +++++-- src/pages/new 4.txt | 0 src/plot_axe1_axe2.png | Bin 0 -> 15926 bytes 6 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 Sample_test.txt create mode 100644 src/pages/new 4.txt create mode 100644 src/plot_axe1_axe2.png diff --git a/Sample_test.txt b/Sample_test.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/Packages.py b/src/Packages.py index 5c1d198..8966a1b 100644 --- a/src/Packages.py +++ b/src/Packages.py @@ -26,7 +26,7 @@ from scipy.sparse.csgraph import minimum_spanning_tree from scipy.sparse import csgraph # Modelling -from juliacall import Main as jl +#from juliacall import Main as jl from pinard import utils from pinard import preprocessing as pp diff --git a/src/pages/1-samples_selection.py b/src/pages/1-samples_selection.py index c9085bd..7c24b46 100644 --- a/src/pages/1-samples_selection.py +++ b/src/pages/1-samples_selection.py @@ -181,14 +181,18 @@ if labels: meta['index'] = spectra.index[selected_samples_idx] selected_samples_metd.write(meta) - +############################################################################ ## Scores if not t.empty: with scores: + fig1, ((ax1, ax2),(ax3,ax4)) = plt.subplots(2,2) st.write('Scores plot') # scores plot with clustering if list(labels) and meta_data.empty: fig = px.scatter_3d(tcr, x=axis1, y=axis2, z = axis3, color = labels) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , hue = labels, ax = ax1) + + # scores plot with metadata elif len(list(labels)) == 0 and not meta_data.empty: @@ -196,9 +200,12 @@ if not t.empty: col = st.selectbox('Color by:', options= filter) if col == 0: fig = px.scatter_3d(tcr, x=axis1, y=axis2, z = axis3) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , ax = ax1) + else: fig = px.scatter_3d(tcr, x=axis1, y=axis2, z = axis3, color = list(map(str.lower,meta_data[col])) ) - + sns.scatterplot(data = tcr, x = axis1, y =axis2 , hue = list(map(str.lower,meta_data[col])), ax = ax1) + # color with scores and metadata elif len(list(labels)) > 0 and not meta_data.empty: if clus_method in cluster_methods[1:]: @@ -210,13 +217,19 @@ if not t.empty: col = st.selectbox('Color by:', options= filter) if col == "None": fig = px.scatter_3d(tcr, x=axis1, y=axis2, z = axis3) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , ax = ax1) elif col == clus_method: fig = px.scatter_3d(tcr, x=axis1, y=axis2, z = axis3, color = labels) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , ax = ax1) else: fig = px.scatter_3d(tcr, x=axis1, y=axis2, z = axis3, color = list(map(str.lower,meta_data[col]))) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , hue = list(map(str.lower,meta_data[col])), ax = ax1) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , hue = list(map(str.lower,meta_data[col])), ax = ax2) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , hue = list(map(str.lower,meta_data[col])), ax = ax3) else: fig = px.scatter_3d(tcr, x=axis1, y=axis2, z = axis3) + sns.scatterplot(data = tcr, x = axis1, y =axis2 , ax = ax1) fig.update_traces(marker=dict(size=4)) if selected_samples_idx: @@ -224,8 +237,10 @@ if not t.empty: fig.add_scatter3d(x = tt.loc[:,axis1], y = tt.loc[:,axis2], z = tt.loc[:,axis3], mode ='markers', marker = dict(size = 7, color = 'black'), name = 'selected samples') + + plt.savefig("./Report/Figures/test.png") st.plotly_chart(fig, use_container_width=True) - + import plotly.express as px if labels: @@ -254,7 +269,29 @@ if not t.empty: fig_axe2_axe3.update_traces(marker=dict(size=4)) fig_axe2_axe3.write_image("./Report/Figures/plot_axe2_axe3.png") + else : + + fig_axe1_axe2 = px.scatter(tcr, x=axis1, y=axis2, color=labels if list(labels) else None) + fig_axe1_axe2.update_layout(title='Axe1-Axe2') + fig_axe1_axe2.update_traces(marker=dict(size=4)) + fig_axe1_axe2.write_image("./Report/Figures/plot_axe1_axe2.png") + + + # Créer et exporter le graphique Axe1-Axe3 en PNG + fig_axe1_axe3 = px.scatter(tcr, x=axis1, y=axis3, color=labels if list(labels) else None) + fig_axe1_axe3.update_layout(title='Axe1-Axe3') + fig_axe1_axe3.update_traces(marker=dict(size=4)) + fig_axe1_axe3.write_image("./Report/Figures/plot_axe1_axe3.png") + + + # Créer et exporter le graphique Axe2-Axe3 en PNG + fig_axe2_axe3 = px.scatter(tcr, x=axis2, y=axis3, color=labels if list(labels) else None) + fig_axe2_axe3.update_layout(title='Axe2-Axe3') + fig_axe2_axe3.update_traces(marker=dict(size=4)) + fig_axe2_axe3.write_image("./Report/Figures/plot_axe2_axe3.png") + +################################################################# if not spectra.empty: if dim_red_method == dim_red_methods[1]: diff --git a/src/pages/4-inputs.py b/src/pages/4-inputs.py index 439c3bf..59fbb88 100644 --- a/src/pages/4-inputs.py +++ b/src/pages/4-inputs.py @@ -1,6 +1,11 @@ import streamlit as st - +from Packages import * +st.set_page_config(page_title="NIRS Utils", page_icon=":goat:", layout="wide",) +if 'interface' not in st.session_state: + st.session_state['interface'] = 'simple' +from Modules import * +from Class_Mod.DATA_HANDLING import * # HTML for the banner "CEFE - CNRS" # bandeau_html = """ # <div style="width: 100%; background-color: #4682B4; padding: 10px; margin-bottom: 10px;"> @@ -28,7 +33,7 @@ with st.container(): .stButton>button { display: block; margin: 0 auto; - width: 200px; + width: 200px; height: 50px; font-size: 16px; } diff --git a/src/pages/new 4.txt b/src/pages/new 4.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/plot_axe1_axe2.png b/src/plot_axe1_axe2.png new file mode 100644 index 0000000000000000000000000000000000000000..a52dfe7b11df2b892ef0bf0b54e86c47fd0714b9 GIT binary patch literal 15926 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�LC#<=~dxX2s@g6g1=G~Hoij(!i;fw|7y{Vhe?ucrKok-i<n#0$w+;f$Qfx*S? z4$Fbi)nO}Ftng4(RlT(-wR_X1O(6jR3!2&ax9vRkvSih|b$UB$KOPlNTqD82pkVY! zjlu5UkH@nti<d3)pTF+m;r8sCn^LX*|M|SN=I1A~>o;=DmM&k;zJ1G<Ee2sc3=9I2 zB+UcO|5!I`_UxzMe><BoFf>F6i!*+>u+TXxGt=@dPh3>gEKtuNyNyS3(bLn@U!OI< zf5lsW?-B=v1%}DTUYyq7pYyp6QSiOHbR5(Y<0}+ous;0wW5%m1E2T`crX1^&U43<R z_-g<8c2&=2rr(MQj)~Eke_s5~xA*tuk99FJFzj-}HLm-*{L7o0!8dQ-1dUl0_kl}A z`{hxL3=B%TdgmC_R8=+A)!m;yeR^=CgTjJOpNcAN=9T^JgEYZIB_$>AhN>|zID~X` z8#hb}q0aOV14GH~9h?oq>V8+Q$JeiI<rY8n`fJve6@gmX+T3*pDfjo)dU^c#&UwE6 z@9TI_yzPlwueaj?)6*wUG9Dl6m9nd;SR%*7z~B&Z13XxdS*E^Rl?+NuRbMW;KmA$- zDvQ<URXFY3xij~iea(*z@AiI=TN}4GikFuc)X|%!6S?T)<KyjH^BCqHHk5ErXILDH zxkMqMyCjm~-~QnHN?USn8a;jbH1p&nRV@vT3-9jko;qt*)vZ5|kN3Y`ZvS^>P;l_q z>-+zO*8cu>RXo0C;k~`p?fWYjUZ^l7m}_AhiaOZt+mP|$Zoc58C8?*UWuBd78nv%x zCuFMO>FMdK7cO*^HqQ$=KhIXx^Y8EP{OKnd3eKU-N2&broP;tTbwG3OPqBsD?^Sur z^}BDsSGD@mrAsDBM>uSMJZR3!%*^~;_d`sP;bI%Z4c;gwx9)rQ7GAp-Q<;@>@wW99 zp$BiLJE)XCi*EV$?(XXS|Guuz%FG0{9ZT=meh1A=|2i!H@4~acA9S4<7V$D}kPf+K zHmB^_dz2Lvu}T6Q8m6Y9=k0#4DJm*5DSYH|xBC6wsBJlsv$G*~e`hFbZtl%(-+%55 z^95V0&$>>Ml9I1(ZeA`VEZm%YxQ%!6_19NFK0ZEm%9N5@Qu|yv9JV~<Nig?#`}D=7 zN`_tT>HAz?bZM^(@b&FwYIG=gBme(LyOEJm6mLC)KrctbT?N?6jE&;6{pzGFAS*L2 zbS+w>Wc&S2an;A8;#-TK`<<O>{CrEkpq8E<-?{n5>3vdCQYPi^V*Wms{|}mx|MH-j z|JAkV{N5|h3=MpbRUhO{n2`|d`LF=ggv|*$(eCKidT7$2hcWyD9Za%+#T2*SUR(P5 z+RJm+@2{v%k6E;@_IK91J3D8Y=f{CkZHdHvmLk4$WvYeim^n(;N9>(d4=q&BF_f)_ zHUeveIT#o^v{(-0O`DN0IsF2^ax5DIgM)xP6C+I*K|Ru9(2Ly_^7r@m>4zT%#Kq0i z($+q2@qg>}xXTw7IzKJ209Ai$V|SbROa+z2e)!5_tNO>sdS{trPD(p7W1+wO-w<In zp9?LV!dr50Z!-wz11<J4OYZ3`5sX#T*Y}?uTQ+lE%_mRKAO(R5x8GiSyZ!#UpP!%4 zH>-biq%$ik>yq{RJ;E}(|9m=ansr4(H+tKe*zYgD|9)Du^U3F*PfDzIKWk*j*dAfa zmb^7jA+CVu*h$F)xY{0~qN0kQRaY)pu;A=Z1_p+Yi`<uRzu;=;lMV9r?gqD6FJHQ} zCHwliu<I3j?}a_D-h0pN{qmhVBhQ{ad+>JM{{J$o*ccc(dUjYaOXwk{-`sbpFfcUm zb$2t&Kpj)jwzb`R)%4}dm!RpoqeqW^`dM=@_y51Y&*N+wI$pmJW$}yLS+q3AY_^)u zj0<~NnH<DHW?*kWJpNeW^vwIxudlCf&(ZfR+a2q-+&G0<;I>s2Yh$q8|3Aflzt{iY zzHZN_QwE`246*8ZOyCK*mph-&yWFk6Z^c~e@~m@nEI}dq<>h5n&*0^Lp@oHo1^@2s zEDj9|TXwWtJp1~(*k6C&*RMZ2+x+#m+j-qrKyzsQ_WyQ(W{X~4UY`Bq!^5a;IWy1M z|F6-F-?!(isjjZ>EThyeG2N&ojm+$A8>1LrNELom6nOb0HFn>>U)j1bI|Aa?hc9;P z4T_A6{Ln1-``g=Kr$hTcznfv0{N<GP`iz53th=7it1kI?RQz?X`MnDrg33x?1sGax zuGHqJ`QCqcbF8Doq<8!O*DYPPEbCa0<gefN|JPmn{g63@VUh1076;E=Z@1mPWz)Pp z@o?MaV|71I$G@7s|4*uUIIBWb=`$`S`MMtq|NVJxzk1iMU3b3+M@6l2?G~Hsy^`U= z(nrr!6Bu6P_4fAedbw=&mpjGhHC0uY-hKUpL9!u3I6R$!ae*=@cx|h{z4(0IK0Glo zu|P+F!($R?vg+>c^6U!>9G9=%eEaRD+izoIY#B=AKux(Y_w@<}B`*SU@9qk{diCnT zx6keW?_9U@nN(<acyVq3gJH9A1B1@m6)QY0FY~?p;^N||vuCeX^`17TjI|NEj)JfK z@fQBBukY?gPXf7Rh7$uzLZ<BACI*Hh%(D%Tx$NqQcnZq`J2XrL7&lh&9Lu`vu;+mU zWL|UH;8+UO+0Ag{!i5Ez!OKp(ELm0l{@yIZ<hDK;%c5hZ;qkRwbIhVom{os!V-U)t zFiQu$__;mj_nqSNFHdQ&zrrdWvw&M~hr`dGKhx*%GhEcrV|p+}Gk8nw@3OV=`{Um4 z`P^ss;{o&8S*EYofM+&$?b`L=+X?0VmW5Fa7gKQegzj%hY*zD~wdDK#`gl=M(W2dV zf89J^w~U#cuVrTu!wVZoU>9#Je(uLBZx=Ja=2NFzznre8mbUigA0HooeL6i}%h-7H z)l!gmK#N#Zy{DD@+V>Y}t=95-{)TfeyOIs?ly#-G-rn7yhK}veCzEGcm1f;|#de`m zrn#_yZNs8PPJ64r^R?M~o;rU%+{vlQEcaH)v90?1|A0CzpqgD&T>SNmi;L6e+`n^2 zXa9ZqO^h9}$NS~OLqn&2`uw>$nUj+fq}A2cb$8wIi;LaAzTJLb%hGb^?o%ucde@aN zvCh$6e|`0pD_16Ll(VhUu(XVfTfhBm>11{Pu>Ey^r_7wW^1R(|pU=<EUVe9X_tvVf zugpLT^Rg~3a*YkMZa868@?t_%RMeDd)5MJCO`EnXc6Zs<*X3tsoBPk4Ia5*b)9+cc zXJ5T@M`q7i`F;i^-K_Hr=jPl0-@>0+Q=gsRoOgCj<YrJS9yDcgYKrEs)A9cnU5~Gi zt^W2Vv)C7@&%gY=yu+L77Yp0B6g~9<4GI=n$mE{WMp_{i%5>o6qHjD8V$1I?ot?k$ zXHPL3pUjFcU%p(vx26``DEP$%j?GbXlffftpjlX#?Ng?RsH&;00*$rp*|+cCn!k@X z9+$i9%x}A-{C;it^q8WPlF!8u)4#$@j4mNW%=$XV!e@Q0LiHPNOoo^7*@s#<C;8QJ zEZMUsX8YZ;=-IF3DxV1c{n%fBWmoBIr+f8x#Qs&V2;?sMruyI;Xr<+`Ug_mCjnh|c z+7twu@yXl$*6eP@<KBb*4DuEQ4$kd-ym70u&(E{1deF!o5*oVny#4=}{JmeNftG2l zUbpMjn);K>9r~`Wu2t`LKL7HlTR-dhxw*59)B9%4nq^Y^tHkrtm6gGvF)=c8{(m^k z{~FW>{`B<p)&2GLm3!kV_uktaS1rP@$n(lP#y1_HnVRi)%VvWnl~q+#UWo7i(faRs z{Xg{|pY!+s4clG*p0Dndxu&M)`+dLHfg0P(mZ|N$oA>vT`2Gt`tlXe--sQxRPT{X# zug7OUJk<KBYA>kUbL!NoCV8Hl+w<oO3H|%K{nKTC`?a7Zw*CLl_Re+wo}Qg`|9{_a z-(14*V#|#Ed<iOrvWg0ulD<mxT;0`JanMkLU7wMefnh;1%@&Zq6nx3VP~wN9uh1aj zz`&9efPHk8BaDrqgLMxJ&yg8e2S#027%@1kQD9&)T%ww=<;7cBqqTqDT)DAmd-)30 z3%7U}82pq#a+|h2++tjRKUL-G&%TwLwkg)QGBPCbfhMcjrEl}q&z;H6utAMULBKhv z+HzNk9K(TGpvmZyvJ=+uOn1(WeRFi#<oRspWGBd++r+?N*an)$MjykB;os0ajo4LK z3$g_m8YPU87B!!l4PDe+%3z&=rwHCrxENFfOB$!Wxa@C#wS`mIB=HbS?(J>5XQnbc zJipmv7^A;v@*kukb;;?*qaS<~VvBj6J$?Fe(`miSll|>9J-Jwzigw@K_4nIt)B1mZ zE<f|1V-e`<>s$4FZh2Gk^!U1+paMGe^t9Hsc?@%p8=f$4oHIH2=FRut-FFB@T<!n; z<x2nWFH=-ZWixvUOdpoNy7BtW{f*Fqw5z)txgcGgt)-<E5)vW;9{)7ISF!l)@65cs zu;Sw458KW^=UyrAP%$_AeFr<sf#M4{Dn8Zk$lGpxXez_CYd3CaOh0|~VJV?T=awxY z-D0{{xpVF@x?HpW|MR@x*S-n|1{?O7GiTn~U%wwTr!f0$l>Xk@`S3Y*-D<19IXB$X zuV1W9=?P3uUTkD+d^jNXxv02!`y5l7njaf}eSN*W_V>4=Xa3hDef;Tt_Mu?6>F*l5 z*piE`UVhu&i3)QxJXcUubQF)PNL+HdL(6ZuahjCFk`4Xm)+zsf5yKRMx$rdX`jX|# z%QN<=+<aSh^X<3G$71!u&)AB?jaOHR_`Z3=wb~~PI{KQLo|cxDTKf9@eXLB3Q>RZq z{rKaSUB@1O1TBI4`uh5IOL>Mxg6YJMhh4g}v)HukO@waTo`~!5^?SqC#jFH1UT>z) z?|pKZp@C14VUhQZw`EhOOxg0wNZb#!{6OW~MI1%WmmAyj<4>G+!LzI^<9qF~N5ze^ z4mZy_tSpxOE-Qu|Ja<;XufTw7dkW1L72G=4dG)!Y`>VQlJD-<4of-~WFM9#hX8QBz z&t|)G?=D=dtvz*Ws&?w;n<j~eTHfhy5S3l~^TWf#yS`qFo;q=&;_kca<o~{KPpt1N z+44-)ds@bc35r(l_k4a*w!8HC-11j9HYO*o3j6h-nLi{V0yLL)GiRG|UHErR&_L_b z>2X@S@2)%8%$|L;OZ0ABx{Krj;bXnh>6<ofI&)mUKIh-R@B3#TY-XSBIazIP;n^D- zlh2-+Y3v&t8(Z-CXHDX&9lzJc?7XC+syg%O>FKlI-rhcYrg8eLdwZ*A|N8YS?0Nl{ zi|%TMh8Jx<ols6Y-Y1)Ou!(h9`uTZjudl65TxU~bwW~j_;vwtf5-aC<#&PS-&xDry ztg+*_iu(TK<m9uLmU^FEKEE!j?A@KrynR2@9vAIAGd;dea;xe5py=rAU*FzluiNv< ztN1XldCT$}|JN@zH8(e(eQ~k-?2nI+&*r!PbK%OhYoN)O8LwWwTCw)$)9LYMWxMb0 z`Sa;CXo49u8=R7oGQ;})9^)L-^|8CJ-Kl=RH|^`It8SAj|9-uG-lG2fy}i%=d_HgP z>goz|{<BW?c?O-Goy*p&(XnB5XJ8bN-IjcuPx)lcr<3XjH}3!YHvd@K=9$dwd|P(r zy}7Y5?cJT7i7O0@ii(TRuHAl5YR}zEmy(Q(jeRpSGgp7E|GGMU=IizQ?NW5~_0Ru# zX1@RBH7n(ni+{gp6^}E}o38D1wX`>)R<2~ryZ6?Gk6K<{T|K?><5BV5tB+hRS@uj= z-EW3r^067u=hxo@O)0-&+_2cx{_mH|;7RizA0I!|`e-7%_UE<eeAE9Q<^KyBg@uHq ztlROZD{t*)-M5?#<@am1|NPirFJoj@_{b$VAmBppR97*5#>I!V!0Q3?d*y7cET+w$ zzrLk~CHK~rmp$3>bw5*=E?JUsqyseaa_!<`_uaeiY_O>Nvt!k&RiHT~8E+4dfV#SU zT3T9BvB80Xf=2O^xVX4(&5?g?wYgvA<%x;PpuxL4dE4`LJY>tgzt2|YX_*%&%75p7 zj&<*sySn{;-RdV#p1jjCc1h3P_y6DTsk3ISk~B_hS$sxd?#iEQx8Iv|{PD%L+wZN~ zvc;rV!qAD|?#F_tsHjETo*5<|Td``D)(@kP_x4tAEqfc)D{pV7V_NQJBGdlxn0e!Z z!+S_tvABEplf3d57ZkT{*}}5l_R*9rTTI^G+PeCxY25nlSAVA8YTvlV_%|rOfd>Bc zc0LjMSz~AW?MAYcaazx|{QK)byRKwX%RNBe3;zBcv=(ya%$dvo`fu4?vg{eZ{hxsP zf1l@v#>UFFars}LIqUnoyQ@JHvBArHKm&K7!NH5~|NFN6*SFjGp+P}HQ%(Kn*+jPU z$zJlW`y?!xT=M7$=h=C-(ckYB`)|K~J2F?cy>5T}{hH6c=d9oF;RwA}%hA9w%f5b} zT-}d{#^-MCEKXlu|9?&7=BEF)MNd3ZQ&L{s%3gnUo^7>B#)Sob|KpD6_a9g8KQ6q- zHtmcAue6!Zd7IBYaup96Il|iBS3z6vxi>Z_X4x;feB;K7*?GG>&)a^V6BHDr6zjK} zm5FibvSqJsrq2&eN?KG@R8;cd03&D@K_X|v+>MEc*+9dXRj*bqpE7;=@>#Q_Kx>Kl zZ9X)-+x>o@$Mp99{R|xocE8)@ZGOMzv*dFg8H<3IFJFSTi=6n;DXf0w!i5E(y%P81 z<KpJ2tX#HC?HM!LUW)tA>^%Mb-(UC>aeZd(ms;EEZy{x6+p@B<b}c?qEVlZ5bMepZ zm2Wm4|8l{ZAG}slb$ZODxv6b0GR{_idvo#m{Q7l=4jp<Bp&&4!<dbO6-QDHo)$*^- z)SWwVA^^0eX2uK&8ELbe8GGW^gH|*xS+Zos>Yt!SHf*Bl(n<RtvuDjR$-bro8a7qD zzgAZFmKEPzzx0@Se<$zY;n}y?f4-fRRmls<?Ms%ZRNBbN+SNpahK3&8`hM^Cc}$HC z23NKoUpYO|$jE5duZ1nKK|zy>ii$$w;^btwS(reTuVwSsSh;@nlzl2|<M;17`*Y(u z<KHiSM@2<#DSdryMeVsGuRbr>{ND_;kW8-P0prxEQ(O0_TgX^NeZH{Jd28wGu+Z>u z_U-fk|9KAGGN!xzwrr`X_a)Krn1!=u%}R)vx}^TkWBF4jPQ3W`;rh*4{c^TdQ75cL z6M7BrhQG1wXnSn%M(MAn$dP5B^>1(9<ZRBotoHd~yZo$f{e2csj11!IelC?XO6j<{ zC3CXju^F>wNfrP9`+fG=+2*rv-HQ7BY<B*vMrQU|tJm$)3gTaQ8dQJWcw4qP=_uFc z<l}tC+1GR~?=FA;Ak{l>*Go0y`hR~O{OPy*b>hp5i-&E#-AGP*es1ovB}<M7O>ca8 z!Y*n{#>B|&d2?@WPVZm2YLyYFIag>Q16pA>v5F&IboKe>zH5IkIP-&-*<9cM&-96r zZEtUHVD#tju8)Eb$gZutzpr*#`1-hK+ivF>?=F9D1{#s@^z}8Z|8ZD;(Y9xkCJ9|$ z9j^a*|Nr0n(?IpX|9|iQpIPA8d}e*!*VP-Y-nnrj!|v~w;Lk6Y&zJIi_VKv9`TV+H zD}O%f*6%Sqc4of){W~R>eGmRzuE+d&_x-=;-rU)FStoYal+y<o*8Y5M|36dBcUDT> zhh}++<(D&;`OlZT^dmbvyI1A&zu)hrll{y#u3oq6l#05#^zOTPZ2WRLb>Da2KYF#4 zq1O;x8;Qr3O!V~fGTOOw=d;KC_I&?xK=sb8Et!g+<7>Z$eqJp9_XMbVmjD0bc-q-n zritq;{#b45f4Adt--A0_wwM^#{i)cTdU_g1$X&yYzieK3-2MCOtMMei+g@H?i?%&` z-|fO+vh1;G{+%5cpFDjk333FVOa^Gqah9;UpG)r9`*pw9{`~vCKA(+ODn*8`y>R#4 zXWRGxUHkL;{(qv|s_xhS{~I=c{_<CI%yMT*T9>`a%y#RQN}V)m(wPH|%xAgv_XupO xQa+gGGi6>sD+7bW_6Oj_{X>1{@R|S2e<n;Wwl1r`#lXP8;OXk;vd$@?2>??&n_>U} literal 0 HcmV?d00001 -- GitLab