From fbbfedaa58ce20f1e27aa0610f0a739b559338b4 Mon Sep 17 00:00:00 2001 From: Jesse Mostipak Date: Tue, 25 Jun 2024 17:36:50 -0500 Subject: [PATCH 1/8] initial commit --- ...te-your-first-python-package-scipy-2024.md | 29 ++++++++++++++++++ images/blog/2024/june/scipy-2024-workshop.png | Bin 0 -> 79928 bytes 2 files changed, 29 insertions(+) create mode 100644 _posts/2024-06-25-create-your-first-python-package-scipy-2024.md create mode 100644 images/blog/2024/june/scipy-2024-workshop.png diff --git a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md new file mode 100644 index 00000000..2b8a8a50 --- /dev/null +++ b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md @@ -0,0 +1,29 @@ +--- +layout: single +title: "pyOpenSci Workshop: Create Your First Python Package" +excerpt: "pyOpenSci will be running our `Create Your First Python Package: Make Your Python Code Easier to Share and Use +` workshop at SciPy 2024. Read on to learn more!" +author: "Jesse Mostipak" +permalink: /blog/pyos-workshop-scipy-2024.html +header: + overlay_image: images/blog/2024/june/scipy-2024-workshop.png + overlay_filter: rgba(20, 13, 36, 0.8) +categories: + - blog-post + - community +classes: wide +toc: true +comments: true +--- +## See you at SciPy! +Event title +Event location (Conference link, room number, remote options) +Event date +Event time and time zone(s) + + + +## Connect with pyOpenSci + +Stay up-to-date with all things pyOpenSci by following us on [LinkedIn](https://linkedin.com/company/pyopensci +) and [Fosstodon](https://fosstodon.org/@pyOpenSci), and connect with the broader pyOpenSci community on our [Discourse forum](https://pyopensci.discourse.group/). If you’re interested in our weekly newsletter where we share news, blog posts, and monthly updates, [subscribe on LinkedIn](https://www.bit.ly/pyOSNewsletter). diff --git a/images/blog/2024/june/scipy-2024-workshop.png b/images/blog/2024/june/scipy-2024-workshop.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d3c32fe1339f5f32e3a2e389dd5984a0a0155c GIT binary patch literal 79928 zcmb^Yby$>L+cu03A*nDl(xG%qH%KFmNJ=--4FbXdL#rU&ji7*lbf=PnbPph%()lf} z=Xvk}ySgx~lvmEHW$z1oB8xK}Hh-L6d|) zkX~b;fh+S~V;$gsn9d4%ZV(7g*Zn`FPpmlP5Xb`}TWwu;U6mKY=1y-oOf8(uEIGX2 zID@+(5K(Vo@bZnNyD5$L8wW=>VQ(?Uf9?E-3c;q{Ee$<>;ZTS!QVlZ%Iwhld^9!S3ec=x*xG?&wAjp7igJlCg9% zceQnPw{>!)xqq~&nUjaR7$f7q?)tAGS(yLp&p3OyI{foTEX+AA9W38iI=Z`Ya&vJ1 z+bAu}h23r49W4K2;8G6m|8d2^_I@V94yKOQVvOGG7M50~9uDq|;?6#5S~OmkW^T6b zmNe`%W)4o)G&Yu|7M8AV;H{gvt+Nk14;K$FyO)!zy_=1bvnc2N@EvUb$MgTW^6!6= z^Z&=d{<-ac#Nq#8h@{-zU2V<&6(&bF4%2_Gc-+U911vkIsl|Puxc)6r|Me|lDGRs% zG4T7DXj!`a#}yE&`wyH=UEM6TeVi@D7&R^3oIG63E&peJ{PzQ&yIPvMTUvvAeexQs;xEV=zL_oO9LK6kgo%{XCgXElL zL5ldq%TTJT{2H}sDS*i3#K40jss9_CUFn@P=SUQ9V&T)~Ck3`?i`4UU3h`DSQ~a$M zhPNq(4)dSIdzDCv42uruk$Ma^b3mox1G0AG=U2GH=N>Ve1ex+G9w=%N`GeU4bYgGW zwn<^o6pTS%U zpm>kNOea%6cz(gOrAK_=?||LPQEuzzdX!}&|Fym~p7UHMEep8dm~eUWWXQDkQ$eN}&>W2t#OL zsM1<_D2o9e6a+;N|88FYDb!&JFl69AC7Zy*z$<9s4swNKzdbg(`=XANF=*5(Y)9yv z=y@Zs{7O3*=jDSkEof!c%Ngf`(2zcF8WjEbiBh++Zk>d+q;^dcJV8oY7&NDZkHsQZ zMP}msN%Z3^SpIL_i4RZm3LB96|Fp&oR7PlDFG)>rmbR9|BPX~N5PEKIrIWqzN>IcQ(y#}GE~CIE&(1v=M8<$Tc@&d}3?I-yfj8nqFM?!73FYUhVTL(Q53^IYf~D8y4{5Dv<~F3aO&_E`?XZfE#KB&&3z=*U zZ~aqU^Ou|{h!^cq0@>4f8{CS|H!q84j2}SM?Gi>(Jc?Prnx{uXr7@_ZT{O-Ij~~9c zR1qGPPu1)F&}8{{Q7(S)-EN>k>;cA}gmOIV_#|J>uRnELCro(6lKO%kL54R%in5w^ zY`2GN+!NgJpkjzL1}2M0?OrE}a*?xeQGE%KpC=_A(}&}(?qBg*Fn28mq%DfQ3~a2I zXFl4fNDYzHZy1-xsGzUNM~<|x?{ZM{xozI_&_C#TL7$Lne5wJW$u!K_>TaHi8aB3< zk3gq|^|h^*&^uqv>(%XD5>9AXn2&#>6x30F_ogvvG=MNOA!Ey@tWXt3U!kAM>HF3} z3s;u1M1f3c|vb!`Mig zRvVG8lJM!!7Vfzr`*PG7k^HLUnFMp`p5SOIiNa^w?<;9g3MmL${B}i#uxlTcplxWK zj1+Ax7rSMDt;0z~#%AARfI;aDPzHVHJ_z8{E`ECYle|y!``StQ;aX9s_hyU`sjz6K z2gNiK>qUL zOxY1MpNfC+Hz)b$cpo5u;{CDVunE+s*ATbI_`LeP!Uh@_V^#r7v<8=RMOQ z(ZLQog|Ot422@H2;sy5zEZp_dKcf2Blrjh^jr?Z#EB*Ot>B?)$tK$`F1>eM{S?&#_ zGIDa2_t7s7^J)E?CxAr+O>I}>mQ}!d`Kpoup-LkCtbw@2>rV60HVcOA?L_FvhnD@L z4UXXISH50N=B;3wL1UXY!E!nYWCgFf;~a&na3bm>UQ?zu^IUyK^seov)jTQfwOoXO zi6p?nm|gZ!2o7tXmmZ9gyA_|)zBhkB0E#L~iB?19omz_k7@tNNA^w@15-&Q21nHUEN$xeHkaxy$L}uVEl8;O zhaV%fbd%B0P{i=06a;7^iD)q;)4T?4ktXL4m%jk$w)%`cNX@)-R4J4{vmhDr+_AM8@iYR?sw>0dMSi|$1H$As4WE(?9QX5b# z{I!EW??hQzjK&I@@rf^ZBNsy+9ok>Gl)@<91*mLjae9v=Ra&+pV{&r>k(#phQ+&c}x_|R!QkG)iH zp^)+cIYuf3R6Q~SJs3H|q)}Gzr{RTng7I-xyb)?T?28egSf(xy>ESVPR+RGJ=h!9V zennM7Ix11}>wnNrBP(3<&9#&>j7p10V$kOD+s&Cc-1%R;?2a>z`u(}mam?^V8lSM_ zkKkUu$^42~NqBMHOpvN=T-_rk%is#^h3zjA*uHPYL8eFzji(kIYL_wh!pffNi4&QC z%*yHw#{(-KTfE_1HlG|mxnLyO9S8B-9xp#wV|<`n6~G^6t+di!d)dG+f#;8KypvB* zh(a?ga^MwE^0Ls07DrA!PzOXMd7n6VUqIrN&GM3b(65QJsTRJhu!8v6`Q^c&&vHHwpy=x+Oxuui|u<8v2Nu;x6(7C^Wq zJl2LY!k|KpYj@Ed#%JOYX-;SRi`X6WNm;~Ze|!Ar_^d?>2NQ-mVUJGO%jnO$jL_jN z#uh>G$3qK<8)WyuAv^*Ck9U2hQ zXAmTaS!!4q84u&1LGixPnf&Hv?7shi_7)R&GB>dGU70zQPHC4oJEZk$6ar)Ze2|m3 z(E7nRW3a>j_3p0fwc%Af%_On(_$`ZW)R*+3N@4?_?HQXgyVaUx#G?$oUW4UeK+I4& zPV*i{(@6ofrLeT{s#yF4GR~<=vvwWQOZ&s027h&Xm-EM$WlB4T8Qn<*wYCDBjG{4; zvafU?A3V_&M2RFVqVAuf(eP%1v~?&eK_t59NjodEE$Tfqr{0i1aB7qkW;2o{s%-H7 zT}u~M`pBkyNoXKYm+jNW&JOes0$J#K#*|lw&)1`DY=(euK*ZE=i5 zDFz>i5>2ao!%GljQlL!t2kZRU7QCHk%^o7iuL#(v0uPMR@9Oc$Ylp)5mGp5Rr?Z!a za_H-)Ae~)FKwLPa)*B#{@1G;V{Wl7G7K{Ia+po7R z>axh<)2$lLWLIl!4>*Xiw5CcvbI974t|NkUg?3dbybmE*wS*m}&A!!=AXoeww+za$ zh(SU-Hp-Bdk{xz;8ZWg)p(hhbockNMoFy^wDOr>c$eB4J0Ju1kg`j~Tyw6M;+V&%m zR;cj3-~`m(J|)p28n$b28_~3A6vsUF)snK8k!WolkBD+e7|puCkvJPAD5sS_NU>>b zrxSy%gi|U`VC;Fet1KlAOhFPrErY6Jt67;AXmWs%ZLc+^v`&7}9d!OKLcO%$ z?9o%&GIxG2B5vtthUx|F+m29c=A|jdy`i}N`kA0aPTxCGqc=wMRWqoU>m|+e5s_6z zuzGLE%iZ$(ir5%vP!?Ev^A9x+O@h++keudi>!4-iLizJ=zmRd1Q_QD@n2oI%C?%t%H=&^{s3>jzjG+W(}(!DL3)$Kjh8=n@I zu^TTlch>on1IgWIY;kdp;ivWtI_Kh7esTHO14E1T*OtkZ81FJQsBXM^^hDM64$FG6 z00&J+Vbv_b@S?19NRe7Pwlj|l>v`?5Tps+LW=RKt?t8WT#E5ODVYB=Na>8@N4f2)c zsXT;{??PHsD3&1`s`P-QaWgh(rXp!6Pb9-@N|j~$ViS*!2yFIkNcJ8fN5^qQ>}jZ& znU_~}YMLDSktnR)DrMq(a9fd?Dy;D%Xv8=vfsFo}i%$zv_;oq>m&*lf*T$j*v=sg8 zPN5tuhOWxPfxFUgv9~eOYm6M^*HZpEN_-uUD9<*xU%I`TqdUZbLP%{!{pKd6^CJK@ zz_s&rVg$T6wrb*Oh1hYN_6%XNXHCp$bba-9)YdKg83d)%ES;QRJ0UIFGgEZ%uWlvGYt>5MqA z5BE_;EtfaGNu6M8xtIgUYvo2VA2hp1(J3r9GF!bI=yEQJnfaCvHzfXM`=`a13A5+P zGyOhQbcoHc2GX-YNV^a+HgsK(2O+@%#wR^y74t`wnoqN|=ThY_46`e!^+EKo=i6Sb zk4xOVeDQ#|FkDLWkL7=Gh~s+7ibM+T4?F8p3Z8dJX~d)>?29l#8i#PN#2@s<*H*;h z9iQIaJo(;q%lAiAP?1Y9!HtIHL4<$`mq(b9q~{mIjfAn#VHE(su# zWMGAZ6uV9`J(@Nub?a-dH`B$~ORJYdE@}G&1=%=oqwg1SK!8UUt=4-=gY82YxPbY`fau z>6|}PTk_vy9o`|P`QRTK7G?@%7iWaQ6FPqdn~}YJioJHRcHfwr7vfc>RNi;zMO&uq z-#cu*a{sHL-0|q}yafF)xGt38=5WRRZWOdL*P_Q$gYakFAa1|)DOK6-=5=7e?{Br` z*cNOOGSG=is0IY>tmFCf=AUsoHMQMbaSKJaMRLRcZcANvHbHVRab=~=By2jKBe}mM zB`+H+E-fH-!%uITzgmt>CmwjSa87iuIP-HB?lPP1hQ##4ynum}4nr;`yT8ifkc3ej(|Js&!H8xh?t{qvz&x}XiYs1vh5e|ozTtPazR24RpkC>PwS^|gvv=<)YAGf{#5J`dwWeXzr<87g8s zORFqvxRe}Fbv706Isecz=(j z^H5%k{*2|S9Jq#}Pw>JE<Wu&3wDeGO~FPo164#xw*jB4iR+6qc! zfbwX&Ld5Zc=#VAJM>K|oRZMQYcc7`Ma}w5JcbRS=f9o(uIXzK;Y=sR?EHD-wf@;+iQFC9dOu3V4DqY2X70cNiS< z^zd~Rbza#HI|--C#Rs}(3{a?n!6cGAJr6smjhhHCBlfbm0yZksGz^akh!-0l-@|c& zY3BNcY%h#n*a|8aO9k`6UBrN#->N^xp=Of0wU!4~-r9*9&6D@{)C8=?T7k>vc6mHm z2Y#o4-aj!H_wC=uF$4#Z&;1Pm9Df|S5$kJ?VlX||1`sIi3pGOnG`- zsvX3GiJ|D6b5emk^s&tv8F%FNd!n>Yg)hNKb|cR}NR$42zu(FXlkNkDqOMzaa3wi4p#-U$+}g zkC>2$N7;GUIm|Zy-bSE9WMsq5cT0ULGMze7i9~LE??8todVM}P)x6JqeX)B1EU$&~ zZ9IING=V=?bFK>J*$Ph5(g_NRLnZ)7Mp3*#yTh!#K*`8QnL(+24fMS96NeY4&o72lManMe9#-o)q+ai=~HGS+3);R^CuU)Lln!P(GXOCe)3XoL$UWJ>Eh3wN;EQ z(^qfIbYh z3i?cth;LOBb&~)o+gOC7OUJbBi5Tb=Xt)LNF15uHQWui62>|iPP;}Mx(~zc%yWo&d z?DYU6lWTinTelZ)VEUVWmtq-2(|8glmv-ecZ)Q~Y#{QrgCBNW;E>3YuJrvEsk{=Vg z(3(5kd~5K80r%kIS~l(mO@dg*q;qDTG%bF>fOX1avS_JcTkBxBJZ@#0Q9?R|de;z! z+L37_KQcEJNmN>NHuFdCuNKO^SKxO@4;UNxv~|0GETy)RVp_5zpm`s3*#r4W%K>|GT?7ek8KGPLyaJE|INzX?2p-#e z=&cGS3iDQrHBajLI=4+x_%S{4PKp1Xu7VABM| zw0&$3m{4a4>cc5F{v~qML%ZIS6JWeP{pv5*->{?u0IL)F}XuVXcrJD7(tTU&VlQ>$fhIuikLnIf(<1^mbdPds5V0 zFIMPxHWWENRta3-rjxB#P3tt*8Z0kKQ&WEcbj(M8Ywq0L0k$^xAJ~cv1v1bwX&cFs zJBhsdFK3JNS&ZO0LTZY|mY5TCfYJ)JNjf(~k0z`@0X#Id^YI!=B%EwZpNjK%sQOb` zltj`@rVc`R5Qq-{9UAuIYFLvC@dYyK6hz#A$D5I4-@QS9usS1h--%y)^wI*OI5uh9 zb4=F$V9vg^JHd7mQU9sYxjk-zLmD}!5sI&{%|CdedtGM;gluTPtIKQ|_f&#^grX!sKAmo*RB?m(ce*C8nJEE>&0xtP%8s zot?Wni2`IT(38+lTs)X$u?{yR>=^iN>Jl&Yksz4(tU(DGM@h{9b-^+^fdteKN{ls7os4hMEl}|r-Q8hHs?%5bf@3~%M zMa2yT$!F8G2zh}5xrpN?_giV;0MWu;dDN%?_=<6RdE)K4CSOPIM8Tj&*)ANrG?bVj z58^}GTzxu_kmSt~BopQCq*~z>G=c-YST2C%#*CVr&K>$2Zef+aZU7>NsbX{Zn$u&C z*c{$v?8(;gQDTl|$`4A%x91t)Z9h}?t2uVqj2-0Ftb}pwN!q#*8TZ7^C2$ift!^B4 z7S0G6)|Bq7(samU+9Nu3dud?aP&11RNx?0OB(*CQU$cRPL#G6cjRE2R+9Jr|w$bec z!KdTy#bVKw#~@Q<^Ch`K+c=oon$?rXgg+~gQ2u&_vZ1fOuju~5JLseH%J9M}Ls~}f z69?EY47O=72iN|GrdB_DN$D!D)y68f?mGjrM}G7+Y>djGKE@-Y5i&tcp|ZX*7PtGCn(KzzEJ zzlH!8eVVn3`!FSfwAEF#r<@`#ZDJ7?G5i9?+}kBg1*Q;jK3UrhRw49N)?&yQ*83V% z0*g=m_-;h~QX~dixm|p=EBcCDrt$813TpA_c`FBzJ9aa3U(sR4Bi?bc>{ zTwOi#e|-n{=r9&1Px$&lU*tcdcGNb?EWRsiYP-}X#YK8ORrUe{Ga0AUNj4g63bZ!J z!$ujAG5SBAy(aJiUZ(~7kB;NJ%z({Tr#~H@{9%av2IpdP(k-tC)-y0Zh%Ey^9Uy*< z&PC!biuDPHIT+d4v}?sV%3mrx1D#WZM|u#8$Qvo?+-lJ3XZ? z=_{m5P-Hx>If5Q4Mi4deF@fx^9UkfkvzB;1+wCc}hzpU^yiFGZrgTzUWy$3e23F5a^KlSd!!ctoXFbDQxuR?o9PRe>#DjQCz-Q}Y`G zZw^_IMg&uRaV{9mIdYW z#7tjzk(rs9Lj?I*Wh}mW&E4atpSX1ODQTM7CDDVJ@HjjqoGLFo0`dmiweUT)bB;&i z=FW{E+>E|w&*NK(?{0~Cr+20<}*@@GmKl4}anr{Q?Il)D)~A7N!?}PVWXCUH7HXj0ePr;VI zVA-u%x%?Mh!{fS=XNimhZ80sp5?S67+>r!-iDO7ad&cL8NOmVSN(0HR`o4%-(3dSV zqvslluq@!y2@E-8?^$4%3!(hJb`7x*k#P8qMOcH+FJ#|htyXaOrR2QbQdIjm-$rqV z$7QBoB8Qxqgh3K)k4iWF__L3@(uahy&D$hrWrrkga854Qd)6zKclAwG-o1zIS#S-d zUQxTADz=EE@VRpNIT9~1w;1h&m;vqhB(}s`IJ|!aSz-1&Vo=r(G2NKGm))_&c^XMv zWnFHT)&Is1PA&?K~VUz-=3d^cGbzFfn2?L6YX~f z>QEYaAm6IM-evK^@2Qh^5A8%<*XT`!Uz9<{b^0TMdvnz!nyt1sg8Mz{#f0$aI6@}+ z$?2mv>E#;XSXU=cVNe9+LPkw{0ppTl|AMa%djqORTiU)vmoO27Yn3u|q6&MPSCCow z6;k-kOw?t5BV_(BPHd#BkJmfF5(vUWlq0Cxj(zVubaH_z>SU4X*qecpr1s&?(D4rs z5UH+`=P6xlr3Z9!IekVgEtF6yszKpL((rH&Z2@9wy8x$a%SAVot+D!j47{j8oplb$F~&3W;PfO4pUQ zA*93uenq%ol$VP)-N>4FW8GNn(ksdXjW3#KwtFGn^sC~-Tiv3i4;{g-6U@BIIW|!n z;?-v%P`b>&>*Vj>{^8YhM_($wxeBMCmDiqD-VM&!jUCY)PRvj+%?fiYz){87UoX&s z(E-jhddZKTnN>}pDDSFUM5kO7KWsMt6D9cw;Vg63I7D1#)RFu$dT;qC)pcYPjP&EY zkOOnc(Rnl$Zm&(Hj;UAtfvHxT->5Alz6eMv=}hE6$d#*7e_AS)yZIq2OG9Lj7rBOqomtij2H^ z680WSr>1I6$#cRinBj|B;}L6RY(7}qQ8(5X=nziuCm}JbkRYltuROmm)v5co{>ory zuOh`E*#8ai=Db_?6YnAp^Agns;8Ef?&g39l4iA&mzNvAT zNfcnDIKR@_@HWvVjjU&dTB6G;{0)6 z8mVhC3Y*4tA5!wh^qts;EdER?_4mVXTlsgX>&uY#3<~4GA_QnNJ%WwSH zZm(|3b9)Ij^9) zqZ9fggbO;npsU9rc4cKOyj@c>bXS5gipp>FnOE*&8&z&Em~E@0s#!*Gw&>%u+TGqK zJF_W0=KPuVi?1KO=~F2i1FE>PNfafPYPP%n{8v|Qt@8}$FABHF$Gu6EURRe4EHPLg z4nL4y|1o(O;KoI_LN7*TZaHNZlvj44VKS*%$oX79xVok2I(}>qChPQ0)+y)yED&^I zTsZyQ><}k<=Z-@>^X!?XhfkSS!$3r*^}%$<;=z&;Hn-_-{GIs^VO~kmB-Q6g5bD;d z2d7)Y0|uh6M+99zm~-XHtN9Q~x<33GIJwbXq1$p*JrV=u1rUNRjK+8iYQ=VW$*hb{-AOGufW}eKPyh4JL#|ZTp{*HUI{|k zcY4G9nkRkd3Nk(NuTQO0nI3^ym`<5FH#Tdb!VyLyY!Zx%YULTF&p=IC#Og zT(q%$iWcIJjpn!MF;l7M#E!=vZybJqr;a}WFjoA{C9va_f>DD_&Z$RWIteX|w|BGb zxvHx00LRY7QU?H}oY3&>h*3%M($K;rw4Xt&S-x%wLMA_|vzZFuNulfaK|;`jI}A_w zKoY6jY6B3cC(0{nBX}l;X16=;q$Bu~V&uz6d#=}RxS1N0HdgU-&f$U=!&VOLAc+v4 zrL}}wZWgKhuUf@6h$k>R_ZuJo;+`L2ZD4hJfaGTS^hJF^Uw_S#VZdY8ZvzTrYXVn) zGnLjte4=_+GJn1GiFnJ-Uy6eLdJ%3)e`WGp@OJ+VQR+|2TD7hOYbm2I1Y(X`1HweA zhI&Cb3RNgw9b=A}_>W1TcAxF_iX>6nl#y25U8$)2TrsHST?#cXOpcC44o^lia!Dj1 zCLIYmQ@3tdJX+W?aVl`AxLyU3SGR1VA&s;Akw%`0b#4C7KW%kWxZF;M=k}h#`4rC( z+XW&Y{CVZOb_~ZFUfRRLUAE0=VebN(2w_Fp51d2t}RU+bGKGwg?lfCyD?=cGlAoN7JFnsfwJeF&~uX?OM zjl7>7a0Yxl`TWO~WR7uqf~1y7Boh63(e)mOe%wB<)3&L_sD88Ec`v+@iYs5WXHT~4 zyrlJYuy5f~3wL1-;Khu>4iW0!@pNgk_3EhThODU4Bj+M7k!+!Z<8(Z4Q%tg~30l=9 zj?*T}yE7Qx-Jsx2NkEC4A8cZ72CvJ4SRNEKm65H555w_U9UUb6D;&NtRYFWajqNOc zinUx+3DFPw8U*0i9FdUIl*L+|?(j_5&Oay7Bxgzg1xIY#M>BK<=D57lpX@I;iVxRz zMJu)Y`~xv0J&vhf>%BYc?z1doM09!59F&q8e!vQ6J@IH+$$x@tZ#t;j*w zRbOM;ww4xOFTJQ+DMdlGVJqzW2I=U;_ofs3axQFh=2Ubp{F6PtXfZ;w>QSqcqAC8} z#q?RO+fq$d1HFvueFaUYgf?ZoGI|+xQSOxRvQjG2_jsdQ_<=N>go#-we1-AU+vpI* zX2;crthDkaW>m_)$d4UfdCj6Ge}#TKK{g9i(CEmTo3Ju(hdH*7=nx&Dh7><{e2u zPeg*31GW^A32IH zz=+pFdcrx`{b0k+wqMhAbMkV!;=mCxFP^sW7#L*~lMY`|)nJ6E)()=l+mD`OO$TS6R?nLN3@Pho3d*Kr}wj zV5LX+owEfI62n`K-{bnoO(sqe_$+&1EPWqT^maUD5|3N$8a58a)Cx1}E^0hzJD*Kn zJt)Ve>M?hTO6g*dVVdPTX^zl!zQu)`J?YrAA$%v4z(CI1yX|APjvelVQei@kb*R}%`E1Lgd{{6aQ zgPn>9{pYcRNU9NS*Fr3y2XFvD8l&Fvg`W?q)qt7X-PWWEBRFI5xNMPIxq|dhhmu7) zkLkz=M!OjXvw<|arR5PnN-ftYCcIa|3#aM_ z-L_tIZ;Z&!wkcFMbT&}?;DOR?cCU&FfyimfQU-LP5IUn4L6r8oEjb*Wr+>LwAVBi$ zKsEVt)LClf`l!=o&MiwcDGMb=L~`{zgfghVQR@>jd-ItL;L7s#>0OUvrt;;J7diF% zZFEPSen=L>`$aw(kJoV|0*USw34V)EUm3Oq0Oeeuf&ZDrQ^7isZ9)uM9(8?vxOuNv zUUplRMko+o7(4qjxanA*I@Ts5e2>_dX5XlY!2VqW*lT|mbJfMdP`2YbA_*zp`O@VWI zBd^!6B_zm{L83Oy2&1bOQOWxDVE&%;J6#F~jHPQx3Y-w%F~eHT@Rk19PK`fx2y@kN z0?SLD{HOV*XX*1mPAa-){TQzkL6koAj52!f2HIk1V(wL_+2BM9#_q2OJsgk&Y=BwH zTgl_T=5*Zp*V+!!J|v%(A0d?^msA0-;zx|_7O#0pZ!pkA{A-z&G;fx46BA&Nsq#L9()G^o z9{z7_&o|O4526^8|EO;}n+-*elk)N+9}+l{@ai~va^F+Tnyjh31LlwSx37?%7`~>Y z>2a7mldq0n!hyEPn;;#LGk@~r$@0LGp$T>mnzG-j*!1(vAW6vMhc+o?gy8mUKvL%mn%%HeYNu->6q} zt0V}wij=9?ihGDZKV9mQ8i=BXRBX&=X}obWX&+S#?wvWGr#%PZ0o^NV+|z`zXzAjc zgoFL5Ob?dyRg3xsq|rhZd!%PBaWwQ57TS;!rgEtq#ek^U2z%7~z6HQysPK$s>X4o2 zQI|>Cg&lPj#l5d`t@S*)n-SKR1ayMG|GBZdGRB8me=YuxAJ1}nUUy$j??u1+IJUv$ zq>-T6b(L~~z8N6^;A3GWB}s1S3of-)2HNRuX5<%%^tRxFc+}P$V@tQC+N_UUc81Z} zF0jN;8cdB~XT26r_lvne|J@4AE7n@Peh5F$Iot z#3S-nkuJ7yk_FNj)ps3irB7hq<*FHt-#{ZtM_c28v!Tk+VKV?_3uDjnBMCAj4)-H) zi>#lXXV?R-NP1$=J+Ww>US4~P3iuIj^Q!CUhXTpd^*kOeV)R3$?V#yz;q*Fzme!?8 zm?n@zKp$>U4LKS|iBO#Ssy=|}d_irb+~%kC3|e(1#qJ@CX+3fbzKt?CxuBY|7d7bF zEKxQ34bO5G(Fv?f(!*i-g!_lXKS9r58ZLU_HBxauN<3Lv9|hq`5}neDmBO+M9aVve zizZC9Iz^+TpR;1l1Q>CCHuj9mNXRm#C-xD zm~v`^B!8KzMPesqCmpxDx0BT&ChbwK%^30StXo#M8pa_F7JzXn66-S6k+Ms)O?!g**>|zM}8W-q#($g?#5#my$ z0gLV%-_Y3-y(A<3PMU2{vcgRd1}WnYT&uFF<6sNoz;%n1!_Dy7dm*~ip9j#lsiN34a$g@nBVyWkNU+9kkRW01j`Q4XtH9?dY)JGVlaUO*i@NtH*FI88 zhui*2APLVatHzQjGp)sznN9c7`)y)q&nZXv|aOv3^}(m*=EK8d|?u*I|$Y}pYkaR_r|6kDYsq7hZ&4AM2AxQkmF^l()0(EX|iGFu-h;tTiywW0wQWjWJ~u%b=rglfbE{u+TSA z;%(2Z<@%Wb)YWnvuo~1_{m=w(H->~iMG+6q28V_H)je2@$n7>fdv(8Eav4dig@NNI z2IP9K$KU~TFU=VabQz1r@GP(5eVqW%c`_!sguqT{-n z27V6pRmA5)uW#_vLYh<50^K(GAJAfC$Gi!6Tr6D>#IJ)537v6 zPc2mjsdY!p;FhGU&m%zB-%+~QMv&bh#ibr}FO$MsxaU!$mP^K%f&E8=Ot5P__xL#; z{}&-PojNPqMq4i77Kw>~X6o^mJDFwaf*wrO^Q+@S@=e2Feia*~MXBroyoWDYxvw%@ zl51_6;3;?zb(Yzxd;I!X_~Df%TR@-DasEarvBWJik2pSw5yB?x(7Wt`nQ5rEE3?)N66eT(DHE$~2|R-tqorPw}zI1l;}Y9^R7A^cU+_`&H4 zj432!NYTe3EZ-JJO|2vKSIYZI%^Aga2=O~_5f;|Em$Dc9yPxoizkcpMGu}5(?H#D? z<%&`J>O@e4(+zfni~?@J%4p)r$h?_h(k%jKxD^4(Dk=u%HZ{RKSY8*|?huj8=R>HLb$C++*%5AmV+TFb!r>PeLo25gERLdj>ifUjb$v8k5jZbQ+eKcYEq?C5>wera-MoJ&t;cgmvbwH+urR8a+oPg;a#p;xoVO-+ ziv{7iWeGyH7vUL#rBw+Pq?Zc?-Zp`O4jVGfVX#TgP|{rfMh5hX2VZbI>D8h9821NG zdCCK(!O!R(b{(AzA0|Jtjr~oWizj`aAHr&fsXoPK%w#nv}^^;opC19*iRS4tlvuD79R1v!_)sw%Mi(q*W2-rA#STCYf zJtbZIP3V2rtgZq^;xtB?p@6XDkTTfOF)a_T>EN)5{uxPTv0WdBMetmwkoPa$wV7+u zn|5*uu8i`+-LLKND<{*12Rt@5u+jXhVOKW1FIN(8wNckh$vE{do z@v<9Hg{?gJpvjr=uZgpzdS>-2#)6It7`)&D=HD^QJs$Wam`4>2!d_eH_i?j{#!O`wNh59Rh)I ztqs=h#u_WwIkwlIW`_S>5t)6P-BvgI?%J}~;j>978Hoj>3>;tW3kYFysdFy!3-8k+ z*Ll}^=S#g8=nd(hpNb~Mh}sASw)p#lK_pS}H>B6s)7RO4eh%g&3ZG*g!``z#2t79+ z=tSW*Q5OV4u=CXynNNf7fUE?&7_m2vqk?a%A~yzy;|W1aiuMr8T6}28fR9%l2?ll2 zdi5&m_iy^*ua%XmYYofpf;s99i+~zH_)m%7o)DrfK5af!y$g7Xv{o>#TYJM-eS&v3 zG4pxYv(wRO=k~z1sLg1h0&-I>`&){ZXZFseu5RidEhqYfBd`SP6 z6-iCU+Rx^8rQaw!CDaG92*Y+dJWGt@N7~hWrxxPJbI@)bk2lIL`FpBc_7lkdL&W}C z%T=CYDhIXX3i$EN$89Sl86^?Pt}O^skU4slOw<|{S)j*_i9Y1V3-&gk=)PY|zjJ@| zsBKE#Nwz}(9mvvdwz%1_<9s8URi6GyiSP(50}cnk!pS#7f&&J;3k7ba4mg+8O)q{= zl>*NkV_6EoTtj?Bae29A#!rvly0MMZ8n7o8mvWy~uu`w27j1pqwH2x>SU?=!cl8Wv zjRciv$M|BmM^FDRp1v}w3NG6A(B0iBiiDKXohl(A-Ho)gbazX4cQ?`?9n#%MN_W4_ zckg}tU>trh#;&#ITyw?o)Vy+~#}8_J%UtZ2mwPIlr91E7)yOGQw9Z574F}!+BXd$|PtF?x|Lkdy+9xShTH@Tct!dwh9Kf~cb<{H?S z(`w5pl~cAZ2dzw0e!lWM>6X{ z%P&GV7jwPF=;_545($KW^|;;47#pAZHs5Wo4>;+bFVJKw^FQy^Q}K_pzYS7zQ}MS) z=>QI;)2>ER4~PS_ zHO#VYuX{Uh=V6sjn$EPSk*t-PcVt(j>tjEM{^n)Af9&Ax%KCQPO-mq<)|LyIC<;y1 zqg!gyfY|cnoqPREycRh)Ag**>G#lU0`s||i{!^%#*y-g4Xl?tiQpU+1*Ju&`^WpO?_?s|#u@;V;QbR9S)e!no1Y+4g%fAyV=}9a2cY|4fQvPqcLezSvPTjd#2ggB;fzZrBQbMy=e{2pHJoB{^PV^H7b~wL8bnd@ofjr zb722iK}M`T<{@#o(yEebc$LUzdH4`n*c0OgQMP7I)PBk!CDn_6_aeZ!n6>(P>}--n zwrq!TZH=(`r^%(z+W5`QQzsOXjh*{rUc{4V?&>4d11Bg>mp+&_N))p@WnFN$e#eN} zH#|maL|$#k?Q?W{Ep8q5RGO0M8vmM>GTH%_no|CSE*>}~jF+_I#qK-!21q1w<-8ju z_w*t8n?uche@1|5a0oP#`^r!qLw_YAdLa zoG)NTEl#N7A9xp3>p;l3i&qEQ2)di!uSc*u>tx^@12`_#Ix z@y+3J-p&5KEis;;_Vj2k_KsC)MYWTMUw-uwsEBtR|(J^nj=MApw77P~e zhNL4yOJpY|b~z12a={NQ6jbCMB5(9i#F&J!sqvo9|J1wBv9XrjlDG-muv(yrH)}sCZflR_r>_LJf{Gb)(XzZz6U%SF161YwwLV<{zm+D<-E1$bP6#X42F%G zCjmn)$HnhxQ>8vd=#hD2W_w3rS{n}elTb^&AYe9zhXAX_PmJ@g#co_9d?5kby{hf* z*fpfT+MMXm)t);KiD=hXN?`tY6Z~c=3IfZA5i7#&qde*1TIUsltYsW{56gwRY>1C( z6ywO_f%mxi))8i0$I<)WVplmzPk-YF0n){|ffac8_f^+FVcuE4AJ$|ctRV=ti&AsQ zi`vom@3yT&$fj6vP^@MDb`kd}FINpTc8cliI3jFBk{I zYsIq2%fp9OOlpgp6~rQ@0zpET(!C033N|Bqv4V6Anzc>xua{_iN&A#;8b-jFxPI6| zHD8-`FOo+L1sL4yj<%G&b6D@}auW1Mc-?Kg@$`vTm|7%;)oB7M`My(1TKZ+iMAX|i zxN1RRKh!V%Usg_)JLR|ME_NTLyE=2=d?WYf!xJBoj0T5pjBwsyU;SmmkeijoH!s&nP@ph#L=mJSq{!Q9!0NT_y<1#rQ@*(I&+(tXvIr^%&qVNf4LUAl z1jEyhPXT9wP$S{z$Sr;Zam5|Y2KyY4f0j?a2??y~BANSM2> zt^Nt0ZDK3$*+N}TA1;FF5<#8terVLqOd@WWhBH|X6@h$@2@r8O|(zCF!c0{@s zR0E$>c%tOCX-|A;!C2*X*f;#$50-A@Iu>K-vF^X;bhZyJLswmg2M&{YTV?An{`V*` z&b^{}>1(+#*8q2o3Y4~roo>X=Yg&uoYH%$(p6-4@Up|YiTE6spz0*OMoAa(p&A=e#t23Or7M!`vHw zaWNiGeV;$UEhZG&b9aS)?z>vSzmU2SYUk>&*@LU!m#77YKi3!|!=Pm8>%?k3Zv)PH z{fW$R=QuKH&bOiN1rDG0npi%(U$cxHEL~!WA86Bentd;IU{I+LV>rCMgZcEk*Pn`$ zGY~X0^gk;W{p0|(g8wb^JU&ur=cr7z@6Bw2og6j)dlC{ySqaeqxa8G{r4pMC#{}}S zL^Q)4^)-fbK}bh`(8xKxrI_s>sIK2wyUjt7Mx2mGnN>z^raA3vD|n=O0xS%90wEt5 zY@5AOgxJJ&`TZ&s3f5bC6=ffJ}HYH6WPa(C z+0atbV#G7tDod9=c_p5A$kiBF1YqTmwH=D50FlxB_h#z}6x1Kyl5v*bu+F#Z85n58 zTa9S4sNz~{x(O^sIKayDoDaF*{17v@ALH4v^QlM0{-E^sRaaMfWrVO)UBXXXm?n|l z|20CxM2%$q&GLblC3jgz+8)Nd3vipmV&BHlPySm_myoIO^+8ut2R;+wrYHXPUz$^{ zB4m97u{4aM{+u&rV;)_|Gj_OtJCqpJn9&DJ_d@sAEha`0 zkBe3;^Au|ygg*i?lJ%ZKuu{v5%7Cl-Guj*DfGV%PZlhU79i$K)*c6NYXIy1k>c$1O$jw!T!9v3As>EPlSN$8 zWDwAwE{(=gud}4prGC2k(fjlE-?EcAi&S=6V!wUbY`=7@U6hzBQq{&=FUUJ>pLRQ@ zsD?{9iq^ix1+gVD9pK^x#~Rs5g4!%bB&9+;177}`Z@>1s)?4ZMS##NQ)%&|LQb3nX z_$MHET(V1%-M_5jU72&i>cJ;{`&F3}+erPWs7hQCl8}oqTF~E86rY{#`$bc;=l>49 z^!Aj!*3!C@M}mm{BO9X=7d*}+&zy@r{v@MIlmFbq$nQ@TdM+FUvxBY?@;LzB~oNve~sivMR=X-B?#XzOB*evf`K`ez{7mhH= z3wHGRugdJkbWT(>U0)LpM&dug{n&Dz3i%3eD$;oLO-i%|VvWSLM|2t0K1_a!>o<+5 z*MPcMf3$ZaB%Tgf{$f6COB}*2E2_siMZ6uq|`B;tB8q^lgpFO-N*gsXW6A2@T>2KVe4^V~c`y}u8!r1{he zN=K+s+K$R|9)@(xPc_&yefC&9ivGZ6{w-{E86LX~1&F4nh2q>Fv&=tt+b%eHb68jm z-?BI`U+z~>ShHewc(gFplcs9xH3T;0(UZobcK^NC(c2jIfG(KSK|+c~bldliiNSu^ zkOnKqP3nKJVYzzzL`s+M0AOSDXoQk<&JiZfLPK}DS5CFBvy-g++epjdii&4?$_-xx zBR?Vj=jx9;XS&n4hV?E3v4iQ zhu;|o+?YLc%-CXL#e~rat|}cYkh?FQq)Kpkdl>C_LMGmL6)N3IecZ@r;FC-WY*`YK zotaRwP=b$jufxMhLO1Edu}Q4dITVo+(WJwd6QmB_Y(spW`jKrl-y$$$mG%-6uJ?~| z+CElOtTw%^TOV4ry<1@GynfVQ$9!<J#kWs4V$Q+ zwen%gT5!Xaq#M@Nj8#&mZFGmnLul7NfGIbz2`O<&Cx^rN=8I#kQP<5s%qqFGA?Jjo zd2A#r0#>`a%VfR18>u^DLAbwv`&UK$C(lwN@!!?|F7@|S>w620Siif}_>()m>?@3c;#y3fmmkO~)rsK_2 z1?I&x5+Y=j6=&yR0U0J7sQXhrnOGlor^?{e>#h7|l*8o}G<|aYb`XDHV?+jG+5F0K z=|ddXA+E#aur>-n<9%%qG5Ljb!3Br2yprAz%&Ay=DC+Z}I4}gnJn0<4;JN-Fkqs0$ zHL&5>d*0jD6B7va%Ipm&5?iTx{`rYaiES*nf^WH~Vd`%EDF!vrvH5%ICwKD(={HQh zO1;1w{spKRw4NWU*XbZ@b8klu-ZR3s2i&O%fG3|OFe@1tIj~9S_M~`QM z7IF#Qcolo1 zE-P^Av4psm9ACdAMy}~v!@@Vy2nvGff+Do9UcCY=^1oG&AIw)U31k=m2qbDFA6MOR zLkBS@=E%4vf>R?k9h+8;YmchxgoM#=49Lx@hQcmn-4R}@G~k)phU#r9GG*@FdTk5O zv>t?c^%>b$5_wjk(RP}`=kT)lD~X`66kupgRZ)Irlu@Nsocz*@ zL>fD%$G?g=Db7VUOmqL@_stHkPv@8OO_;UJ&3j!PAreH3i$_59p2_=vxrn?uh>5@( zHzLak^P7`qOmRn*=&h@|RzdiWFVc$nnL1wJK~&W^*XhGgS}4So?+&a(TOcu*3BfIz zR*?}CwS>L?yC+H@2J?GAdOsvBeV}{ZR-}5qX~M#?)=ol8$41uvuW967z7D@Bqq5PM+DXw){<(PVJsH5o|$Hz;6l20xY!G^)>c`L%PIuB@(@}{fm z$nsy`dv~+3nav*%9*AN7P?i#+tAZ#lo{-f0o<%6v9KnNtn(`qyv+2e5L!KC%^z*i{ z6#NQe|DR$+qiN3IjC~~*lw4#oyeIa-v^U@!ULFM^#)K=BGli`Aovxg|nq zSQRo%+{XBGY4j8bsBnSY219Fp>%ptOpWGy%OE5Ym2mWR3cAn%TO`v(UN$pSIu=^2Lur6qJw|8p8|Cx%8p{j?K&K}AT0 z>TseUB8|Y&Fb_IpZ7y?>`{(rwk)yMpE9xSQ}w?!Uq`I{ql=D%BSPI{iHe0=z#6AJWSmfhdK zwKIhF-w_KGDmLJ^Eq;gwo-X3BHT)pq@efdC@wp-mfuDE*x8mFOZw|-zWXT=1+SBa1 zd26Swm2WHP-!fxS249K5+;UTM@`yBoGWm#8YBA)ODkvddlFynCCa(liW&#`dU;Jma zQI}wcM!hkIEa?q`8NHg%A-9d#?{k#qOAon9QcX4vd`H9&>j5I^p&;;e5NJ57IPbz^ zY1-%b_%Vj+mHhQaB%z^Ue#i1Ao&IL=lP^8h9W%Rc8{rEl@l!IKPaZE+X=gqltZ1@h z!o087maK_4o@>$J6P@Suw39zD5qF2*mApoP@O?)qJ4?pKA`k))A|=qy7`Wg`%}RPHU2{^HcZvlttM=L-EB z_F0CA7)%N+2C~#Tmu>ruc+^i?qS1%%8JkLYiv4!ndt6NicRzhOHn2%ZkmV{CqlPYX zDn*0xLqbDOH0hQS{#!jJebwPKF)*iIo?deiXq?l-YIYX3@^JpwI~^UFbO%xpZCs=B zr@frZM|b$vF+F0(4Fk5Q^yCqq09j}^eHRUle)K3)VlUZZ`c9yI{{b=BgY6IzjHD9( zu!f?_^M!Y$EAGn%fTGrD`x}FbudXMqAR+B*Q^ulwJ~SehwzCZz5YMzqy1I}9HXuT{1FP)`Ly!B;Bm6jqmOp9AGQER0A=FYVg{7vG9Kl6>&7mQhA8lQuy9DA>5?O1sCp;j`Lp}?wG+of6?d9+0Oc4}+rkVlU;i1EI&Vh3d&@N5}N~#hn+2bymnE(i7kU1q)$Jp6LeEg>|Y8$Hbg`)d_(W`nk^% zWI8|$5TTW#2|GWwG=a;sYJRg|0;Um7<)LG`X8~OtsF{hpdyu0Q)E|el;CB~b+l0$b zII*LVDy@t&ElE|>pTx;i$>b1uD#RGi&Xf=l?Ipid5+EbnlQ_!-sp8?|3&oZEU&LXL zU;cmzPyNH}^x$_pRlgtm%LUH(dso9sIpCr>xN7YGO6c+9`+mjaz;Y%Uab4Q+ z3UIssu1u`Jy)QreE!)54?`S}i))O4XuOUFwBP&qSwxViNb5q}OuxRE8jIQz+mU6$5 z3tE_cLa|jAx;X-vDkSI;IS1`k$ns+R@5XV3w3As{F&3O^dtL-gcCGSBbv@yaH%4QY z!|Gg#IrjT%O}32qvixC@0(IiC#+NS3CC8bLTn;x@dxD(S^y%kZNYODWq3^X^>pc$b z&YCwisC#+>DCxQ3%QWgFb0lQcB&q#yzQg@jXN@VcQu}T5bt%oyW{3BXzUyV-YXQqj z#{<|ITkRUlWh2@iqx}|HYhDKQiJ;5ujTp zG-A=Hm@Vu~iUlCcNe4rJs?1T+W*6EI@65@tML=eN2_E&p>sUo+&Ap?CWeL zewg&lz1~MDhtq08k>8Pnc(_|sv{M9a9@m))^k4{zn8_!j5C1EyWU~QnwYH|pkPN0H zlp9Hh=?3puEy>^@i>P$7rT4H`QIltgq6gZJ9YKiUx> zl@_Dc4M?ls!FLhRV2adICJe3ZIUumI?l*AaP)i{H-$81>cOrV0bS)9R;zN*SkIV+h zbM?T3P=~f+L{_8(G7&Fi<+XWI;tZBd=SLNcX;P1;7{b6zf-M3n#y20MTKSIrPwTJF zrQz5n?0Jm>G3jwEp|)e z&+FD3r6`>q9#BbxV0*fLa?XqEG&SGa{e;20(g9^aBmumKh2gv$bTUP z*=B(+wthXp4N}7WJQL>1qr3z2rBd!h9_SDtfScL7%U9j-2mwTcTl_rf6HS-y{QIo_ z1C;{h9XLE}3v_mSY`UTr#ju+2z zh0}y==Y62l@|L}n<1y47>objH5`tg_VfYc&CMsrD1ZepJqZC0Nbj`@pGecE-=9So6 zTKSi}6?bZ5HDUO$Ol`BEUYJh?>W&S0hf!{Av zX(FY;Z#Q(R7S`EiRoL;09R!r}C?i!b91HO_GR^_V{w9;?fKat&iv!5k`ru}=Rw->q zdQYw+egpcMT0TD{E65|Xr1|~;*!ISTK6%XUc5r|=sn&86e#cPrwUyb^GXm9}7#m1} zyr>7VIvUD9wqon?7A z`GUO}I?d)nYWYCO2aKiA&>qmc9qIZr^InVZaP&6WBYj*dEQbK+<0V}YxLHD?+1?dJ z^h8$cOy%q2+tasf3jSo@@20OeZ6<$b%+54fwJv7H2L*VUiC!@Vg0OFJI#04>qJ5Yt zkKa7dAB5n}_l@HuS7KAUt8y>&E{b5Ec&4ilr4koCh0hUOC27zpA%@k1O>)H?{|1pz zEZK{4BCp2&{Haq;CpbvMcspsiHN%eYwRh5vHXq_IyNsQcZv>SLgx^PRM5QrDQ5fntgfG*EcQ?#o!r7F)k@PoX} zatGJxav17;nAD4b6xNMQKv8SH3VX2pnsp@a?Q8er%{%`uqqC3FGRTzIR^lS+l%ApI z)e5$C9mtLMKR+(fARKi>Ix4)nHn8^bo zv_oE2`MsMk^-L#B;A#fixNuxqKsGjr-M%+`dvR>!CXv|cC+7`m()ls=$qm#FeB3gQ@!8K zyt})DZM?dt((n8u{?ZrQMJn%d=F)g*eb=l^ET-Lap*z40f}iC4^Lvio5qVY6>Gn%9 z26f;@3^gp=vdE7g*au38!g^FAnP9}p%khp8rCVhjtaPanl4+vzna-AAj4#ORmt57i zb1r-Ab+aJeSsI%gInR}uW5%uuHLQeDzc+5yW*>>2|)-6-Fnx< zXm=*zX2FA@hLxQ>RSa_6#v@_t?xS!p0rUO#kKv(_whw>!(`)WL9l|bHOinRNwLC^e8gHC&)o zMjv7NnjTqgxPINz9LJ`|_~J3IfTD}>$#@r%jh?~xS=h@wB?`sPK^KZ^Z zxH3^cA*N?c6IaAAZ+I`VVK(!FYRJIAfY_HmOg}JX65srsKzecPewg?*f^PiBYrEdR z2nFhSNsX`Z_}UobhXwqWQbkr~R1zjBo>Vd@->ICozpk>tW`4^kE~N`5OspWHMf5fJ ze%M^N{qwD2XdtG`Y*4`Y_}8m1#(st9bxfei>4bH8{qIg#K)yq9Yk6)X>StqDq`Pj% z`33ot6{pXCx?-{y?by_up|AmC)A|f~YxA46U!q$^VVf=4t9s9BQKD{WwO$B7g zX8%g#jxUe4gem#sXw}kj-)-YS$x`yyCAfsJQLY*1^$r+M!$hnp{ z%a8l%GX#=ES?iq*-bDAMz>3`D`Ydeej}JDPtEYd%bC6OhD(pjj2b z4kDXQ&fprnUhEv1RsqL|Pa@+_*)@}70F_!Ao0|B0fG4@QwiLFLsv$Zqt&;~Yn`&@y z=!=5L;p~4@y_6>z37_FTH_3Vak!0u$TBXM{YQtmIt4YlYKM=9s~s5 zfp+fbJz50wG{zeNmzyVq$e*@m0SA!WyseHt-*#d3Vro8)XwYiW{pz)`-dOz5r!p*i z9XDQarSTG#zs{t0oYi)_hJ@=Bb?yHddXetDb|SQttvr1y-Ep_%`)|67oo0XHrm$(t z`KsAaD(y!>Z`ssDIlbw6@Vka`Kl(>VTVbVNj>S(L8_wjH&YK7`F{rKgf!vRk-R8uo z;k3uC#?wAD&e4>^qMX6$A2j3L{Vfkh*KgTJRt`zA?tH-i=w2TuRGM9yZSCOE+Y92c zHz__9lV)XIN2Ppz{SC1lx#$t^KbYE2AymFE_4^!ZLN2DDPghTt8Ujxj;M4PSc4A(; ze{joFAj|)&!HNOm`i9xx1sy278cx;Ep9h3{41NfR2Q`lu0tadTSc>L0I^ur(F3IPC zn#=Q;YHqyhNz_tzvhGzpw+jlkTxq%l9cZ)Y&s4mQC*;k0ozHXGeWw*$`Tdbl+F?JC zYSrGm$%tlV&$g?tTPJJAp7UMcdT(AIpJ8s(;Lyro-RxH zG_{l_+BC;tcH7iKnE*{1Rc|4ed4FnJ6c~bnwjtGfdW2vkBE%Mg?vH#jdJ8=-S=1f? zTbb6G8i#cQ!D=U0Cw=pq-u**NxNk&{mK!e!J^El+w^Eqdv?$2Z#m?QF6|}VjB%hbW z3uId}OLF>n$g%^@PzpOFUf%mef7mm0zkjUoT>B=m#|j&{mZioyxg3_hP|ctR}{BZ?r%=#-w7Qp+b%kr zsKB&e{U9|I1ihR^`ip&YfBZ6%6LLlAF7j7z9G(kWnOJTPMt23LB=Qex*idYqdPGU* z9AMr}n(bISyj&lL$^0`~;s@5Q7CcebktPb|5y9+<*VIdz?pT+!NRz3D@)|k?gXU-F zA#0oKp!Y`yn~QfuL0#P^DvEb^sfhF2^n`I5x;(pm*MCLCe$UWSreFBtf8FSAKX|jX zI}v~pPE?v?{BYs(EBQ&8r#Btq_Y9fYG$@~&<`t3;J_aQhpYE@2d8)ncRPWg&NCY@~ zF}36*&|o`e2)6S|iaa*ZTKwZj?v}A8L~J=m{9!Jy15kq?AZX+K`hm-nQkr;L{*9Hq z9{tNzA1nWb*D0ZKhtVoseUFspTC4Dl4A4BAl!}GdGyo#U7gvz+*H>Ak zJ`MMbeAavGJ|R9mHN)-|F7wXq;q(PJzh&3f!a5zLo230$>V{}{u8iJ2H{jS(nwFaA zA1vC?aTMyP+N6j2j^%oo8*2Zew!Ju4bk#b*gNv@dWt;dXb`|5pVSr4_%4`M^Q$ zvHL^yE@91$ALf(k1ya=Pf;wlf_oS>%ay5p$T+CZ{tEN~C^gHe>v(USiohtoh!mzz| zs9&D#w6o=|UkT2H+K^p0^DirJ5-P@*M>UHYd79O2?5hGTtx+0zeo(Xf%KAd^FdmlO z^X=Fs4f^{-@D++RVF!ko{8p=kZmMMcDBCFs^z<)c&OPkq?0a9gusi6~0 z2?P2Ti^-XGZ8Zy)!|5gf1Yyv~`zK4$PI&Wl{okq3486_v9o+PxE=YW&_o4}VQf$J* z&pBD(3sC%No9N4%(C3nwf88(N62FbM&Qd^eWzqB?OC_NN_yaXVjnMYNYv}`Dngq=_ zW{;LK_X6X&vmFdTLpLmBzJ34{OBNv+gJ@nn2lY*x8w-c*Ug^$R|KT%Z`ra!k^a$pw7X%whZG{W&Q;!NO5FAb>>fWqS zORRBb`DSM4X;W0@V9;nuJapS!oDYbiwXCI$S+Sy^Z0K9DnpdxWQ?awhffh`(KmWrJ zqLAHEA+~mx;&VAWbIq$zcks=r6=QL5?C6=fjnXHLWsK6Wkpp>|_f^j18J&B{+-eH4 zv$4}Zm& zG{O}m&t=vAdz;F42#y_5){UMw6`z1TZ(1HU4Fv*KV4M#tn(7S$gHam1yseAN{Qp12 z>gw;Zvy1KLJP#2F`iG-PEaq0jdkdNiRqN2y-P$a{%Y&MAD3q_!?Og9*Ak{U7$CzDt z<^(S|v;QyW@WAZG+W9J zur4Em?fi4;3ZHDI1!OiOptIvk3$Nmhq1C+9Ue?a^-ck-8Xg5lwr>7TDnxdI8!^DeE zOY=VazV38~1-`>BxxNqsP(a)L8GYEEvcA2=&y|O3N^bmZ2(&*ID73*Si>)t8{ma|g zLmrWp?#tYum^f(iYFhJ!1Z6B%u!XL+e1$Qtii^uo@iX6P@)U??k_@#k|B0IbxRl70 z=Ex&&c~)sHDPYx=qvG}ghelA5I5lf$tq3tXN*74aW-EFe9IRsZvJdGJi7aIpR+`A& zY$n#EOzC(&2>86&pg-o z>1L%^j6W~0UC1|#j^%^$VVa^}c*2xKIQTLS35QD-dwb3ck_jw)wln)<#%nWGk z8`%3m#9L`Rz$*N~1WSZN)E0{qRLxcrsIo1hIO^1PZxLnKRnt)*=e<(>5U6!<`r%N? z)h=`OR7iUvz$h0<5N2!i(q^>nIrwfo#NJ1bIh+hGfde2aLRc#{CEx2jx9tfIN=8JqO-Xq`b>8+(!R+Yq!f3iPrOjI(jX=w3%toK6>( zL%aav8BVPvL9*Rz>3wgegmA8m>f2Xe@@*cuq?pWnfk%CAkDp8j)nbe?2N^KS%BNiV znwwINZwd+5gj3L=Hf5!yxa(NLV07Nw{6Z<@BBh&UBR|YD9q^wwR^O~suXMtWP27PK()J$({~gbz zb~1kxRx2KYjdY%VyIt{RG*=yKEkH5AWy|rjz{yE27?cbwHE#xSM6&H}1!RJO% zf={X!7rI-f%1I2M3kI@f_>tA%fqBIV6_sQXt=@e>KZ*TUPLf*?s;hTc?O^-d#kT|9 z`%bgnGx~c)X#FF_;{6LW4!d6Dbva{W;uuA2)dFE9DRrI{;RL^^LE=Qhu4-SRVI~r@ ztpk|*3W3hx1C;ezLqyd5H%|e#L*8VSch{$+#uA9*VuJ#Ub8SbYJ`_Fr<6}BGc`l+6 z)f?JBzA-Dm;~V5bt2HfaJ{LrPc1dZdQ;hNBkFz`K5e119B;wehluKvxIj%XO&(y2= zxSRF8yRF5Xs42u}KZ)dfC7&NVl5(I_%Z)J>n>ZY+$!3m|VZr$Vey`ixsMWvWA~iYj zo+dgq5y^pA)$`O|D(`ug^N;_pF?;)e6R9#H&*QBoBs27dOrSaZ1{3F;(8y@2A+Dc} zDI9$LQ02s*TJ-H-Xnkox@3~y9iTLD3I)P@>cx8%*p61XA;x)B`{$Dfr`E#!JbRP3} zO#3M|=X5R|EF{wQ|GEd%{V+#<7Weq>bhxt40cR^ATlqW6y4fZX?^=2EQds-w-Xt11 z4@y$-**~7}8M~pv|GeHKxx;cmmfVBVl#kkq=};p(&;7Ii@hmW3$7m)zVX@sbK+-k2 z@WT8B$uW5d;>P<{h<~}8bQG48r}vrYZae*Q0TY^7SbK(VVX8d)-h=Y-6MRW2lSqWN zTWc6mt$zY+FqUN{#}16NB@xN9(4XI6JV)rILCcF88Ra<>i?(VE1b)oB1?^124t|wu zEf)+o%UU7hID(=~hsnooD@)Z_AdJQ)?=#8DG9!a0I{PfCf`YOn(XrE|sr}*cf#uh` zu>F18HfAa@cG~uSh26Grp3t^Qttf6 zC(RyijO}IHt5F1g=J;u z;{3svR=_p?iOpi}@DUTJITIvmQl?;9}n-v4(O0|IM&0A^AuL&_RUa3pc0Fa_T%SM<0 zj3Vx<4aP!Gb?jEk>aQVT zsK#l~SWUTGCV)(c<*2H@4;Z^`GM#M;*1RT~p7sTX1)kp;J^MP>@E*dLqTQcdqURLz zfQbEGS5%RpyAbEpH?x;k*!N4mEK(#V-Mn*58l<~9hSfIEgq74KYV^)4^~@d8zUfW)A)n-jhuMIE@}LIyHOquz z&m?qRR>|9Jt*nwW+cE1yg@CXle*3vw@V@D{zBV+0x}J?$1Qbdkah(==nkON9 z*k?gMrD@>%SPfPnn%wt@01MWcMgjhQSrkGrS4mxCg3n-1MHTsIOGL+W)#)Ol%%Ga$!6x~kaH{oKzAuPG)8!TP(ue!=mxSE3}Q9zAYw58@o3sfkuUFr+I zX!S=dYTVWZp1JB(;XSfWpao`%?rbm7zRGk2wW5ETnxwxU>o2OGB>G`qViMD8l>G5) zv@Zo3U%pJ(TJv|VF*W)=z#^?Qv1dy=;NNoX><>11MqOwoI(9cy@UQdt(tq<5Us0$i z<5FK+d;x>(-#ln_w2Dx$g@hJ=S-$gdAP9sk6A)e6ppFG-3$hTvRIn{sG&Js4wfj08Wvgd#}` znn@ZTitD9BIL3e!gcymap9YVWRC_@X_37*R1ua#vY1+M5t?9@JYUDWI=*XJrbJhng zn}y(cp|h(G|D0H{MU)h6gh+EIFdDej`G!zl{WhAbG-tE7|9xM{4AiaqGX6fEa3_v0 zoj8=*zpN4Q88%K)wB`O88sVR`-NqK;SK*S?(yE)9t;RSIfBU!%jre7pb6juAas2Dp zZ^M_j?K0%7$%Er#B)ihmb5olD*G4!;F8Ge`?PMrU6^MJF>%O^%)$zWrmKCQ1n_LOS zHsXKam00H{qo}^W{>-Mc*d)n-3c{`JgFe|RMcP-{z2CoUQ`7Ge9dHB%^$04q%E0&) z76(VTzX*P*WwV}zXsG*ATpE#bg3ah1V;a5eBf=`#BOC%$Vs&s!F6xIn4HdkBg|9!_ zXy3&Z?y%(-Z0lo1G7ZLM6;!AT7KlP`VqWbwWwKHP(w@}UWBM*3f$0K5H&iN6TXnY) z>0EDgFIA>5D8BhFx3SwC8^bC$-ke|?crPMu?cjHU1Otfmx^IDUQoRb*9HU;U7#%F% zx=^a9yYYIqyMK&f!+xaO^KR(9fg$i)O)~)I@h0iBqg0sK# z#S~7|_^|Oew*nAckUpq;zxY~raQK~CfwxM9_RE-q?5?Ns{7ErW8@{XK7Ic)7-kX`M z1TVFLg2qBz+1P7pPK{Jc+q$~nRg0R+fmch|eA}^}Hw=xW*Uc~OC-46Xj2WeMk*H%c z5jMOxP77F&F9ceo#%${EcR(Fa3RSP#o54nq<)!*JZm0c}zCS(N7j_E+w3TZ01XKGV5OM#!mq@U%^1dOb z*F0|05~zyz4iY{kQnHBKAA+#MTtJ}&d_>9 zhC_5%JQ=U(2p8mmItIG0*Ex(RLPB@N9lsKDmIXe(Hrbq?B`;9c;TJ!Ndv}<3w9^%_@g}G--;BVdfahR%4xDX zPo+K%Zo4fj1|HkB(aF2}6Zw}a7K$;7&QAv`0Cd$a@BWG9Ny+Z3{#i*JWUyQ#o`U@5 z>{HMFwvDY#tV&SPy@gx3_Y;gMJmR>7?Kk)6gI@ozsDiZIOHV{WqmMfZQ8N85Hb-r)g@~!31UH$ zv`?@66<&rn{ybl8iaM>@r`EBz;CDlY((~n)&bkxdmu=VV?pT)9 zah&qWt0Aoih}XhhNZJ;V)s%JxvY){7JmF&Wav=8eK0*B9D;k73oJ?XczF*-IEVN>A95vTug2$!oZrPG8dIUZt!BxEb~S1?b``#Ub)>Ug zFZGi@KB3b^-oRX2OWM}uF4#Vraec2w;d;*EH5t$alAq*U{S{-u!8e|A1n-h!&{5IY zbf<4Rrc(v9ci81f_nl)pa2$cp7kwADM}&f=H46M9zzzr8<<3GGLH?>ZE+r+nfc2l_ zJFNBJuf?bY1p~pZP5m5>z}Jr@(&Xb%0=;f-e-CmXms~BI_i4VCJ_Iv6x54RAGVt{} zz&oGSwo4UVDsYL9J|W6000F){)!nbn zmskIoLM0PeHH8*JwQR|!NKtGS*9~o;*;L7j8^2e5P3bG>fzt=S$gfecHY7|Iw}MzT zJfM-+CW+XtzR=(Y-gi>@V*_kddIi-aQl!eQkgW~cPd})-(kK6V=ty^*2b`_;U^h&Y z*Fq~-eby#bCw(y4E;-a6eA|yuC+Q>rN#3#;(KBf71kvpbBmd}pa&m;MS0xa`Kb9Yy z0~Op!`U+o5tcD-SGpI{sfvDstoi8ii#1C=3W^7S^ICl&-I4+h6k5<+J1Qk8`t*hPn z<|x3{LL;-PKul=YbB+!)n?^?g+}M22h#!}~r$aCy)a30Q|AJjX^1nt_oY^SvFYrDy z)924E><9sIOBTRKbLUPGFV3cIUfhyIM}p7*goj-qDhxQH2+6t+%m%!8_d~(|lPf^>ICcQ;Z30@B^x(k0TJ(%m2((p}Qs{SLqTUC&zngRtN;*LCKc zz4tk@hftQMdLd(esy%;X4(I)_`jhKY2Nm`$c1DSx#(mA2hPGz-ZbQ~EZscHK^8e4B z{!rFaq&kzS6}QQ;g5ie1Y4+rD;-CR?`0t}uWT(klGB9X3+csG{{|-tg%FuIC>Hqoh z8D_$6D9Os=sl}=f%S}kM0Mrmbwpn5(FRuy=UjEm)eEcx#mu4Y$+Uu2Mf*= z(oMSeUv%5Iv=$}Z2Rg5m>nAD#J+ZHrZ|%y$tKM0IXEG+ma$+=NF{Y~dGhQ6pOG1~1 z`*!J3Lh`iYUu3un-IiSSJVS$0{g-0yqr#zRNtMJffJ1j}VzYkJsRr6c)$w$aB}z>W zj%FZQ1(98cANrO%+{2|lj(Ie!;o=_g;Hc7Ql%4UnzFMnk@jU8?)BiTA16-5jS{jeCl}Jz{Y&* z9Del@$4W{{3f&#w7jELAV`LO^6+;7V;Kk|;4w$u;g%7_MA5czcU0HdmdAdmf{+c8bzzR>k42K*ZV*36YuLiBv7EKL-Yv9kSy+LrozY{|*=w&GP60jZM7I3j$GFA7Kq%;aLXum$5LJom3%9 z$LqOX-Eeejd}K9;=ZepRQo})O=OK-DpWs-O=vtvm_L^>q7&s&S#BxSuklug|i^&Vb zTOUOt@)YH_SwCrem?|9yPofh70mH#(jDFO`K+Cb4Jrmn!Gg^0$nU`Cy@K#A)q~!Bf zqQtmas*Q^Dme3?5uC)q95>!E}Zerk8N&mwbXS~?&H=*E0lqUyp`$Pc}lC)6DpDwBu zPQ`CL@Rbc{_hs_`yaf+sB7f43WMF>i6}!09k4DRB0u6TG)f@F3*XZAS0|AZhFQl`U zv~p#{yt9>je|UmWr4>f|z~qp%z8AqeNk<9r(AliNz%iAlg~rJBZ{X@jshy3`sdAKO>2UbvvU;x3irV?jTOu9 z-%3_Ki5+CP|J?N++jsBKZ!?n^Z#qRa8F3rCUY=7s5&b6OXYjmh|EJM;AM%A4H@a%Q zFvHg3R1?{%KE^lmo!5GAA>^u+;%GN?$FnWtAuWN`!=N4NIy-?$0a~-i4teRmqiP?EQL;m$ ztu|&Sea=}HghuCkaKHHDoy|d8RRM>F@SqS+VOWbzU z_0$%ZDujuZK0ftC-??1d^K_{?Ezaf;$?hpoB*#qoZK+!X5KOJu>_;fbbKvzT^ zP2~EhxVp_rngwITkW$;#Z?rU=+CNw@6J;_P?J7q7cKR$FEuS>se8P9YR^_KBN6(Si zdulaixh=#l5_%xudFR_;YtYr*4ZAa}0WRcC5ZVqfY<0T~2PdEq@Hl%2Bh(+erGkF$ z&(@n+OfKS^zqAKrWS~OjF*Lz`yGd!N{TSa?sqg635p5DSGN_4-d&%jYq*Y&I=cl5llvNF5MTB&j{ zJ&%rW@XxUnyqdMf2iSGV%eoULQP8I5UgewBbyq!qEUf1EtU>3>8Sw`bf_p%jZ( zb?Rh*fqF8%58QKo)S38#L1*l&eLORrW$&;K!RMr<>rtN(+`Ca#7!!ZiaSRFeA+qvX zr2yYQw<2Akb!qQI`VX-A0}lftab@n0TA7Q!`oA}qG_ae3%MU7(Q)CRM!$~H#e@Mf` zDsa!0`r#wGuZ!#%ThH?o5VvqLs`+}j{4_Ewtb;?$8N!(>`>?{lv(wM=Kg`!x2*#55nV1*3 z$vTC71mG-mjnNmoFs`MQZrpt&FU!j3MIl?-lGuSNKDvnGf7DlZHo^6Uw)T+DQY7@w zTGtyEAdwx@W03Yz1f2w_A8dlyrzN=) z=j(?3iV{{VId3mk<`^P#*@6R+>2kG7F>s6AbT@Pcj1 z)ouD7>Xi{#R%Tr{_eYV|{$Y<;3dwP@bF@9rUW#0oaA9M-Z7%L-5~Pa)&8$6Jf4dE2 zs8<58o?soHqo41WLMfQ*+{azYEYM6=CFth#6UKH+DQ z-`d>IEw3#2-@Mu8AnHzgk{xJz&>Xi|fO|*mr}b}VD!Na%0!Kt8Il<*x#d98Z2I0uV zV}|!nxu%-}y5!^C>n!C;VfLkcD;;{>f(kBgyxPi_6nD*Q?1 z(>c!*``5-fMK6+2c*Q?3gK7yq@3B#7l1rhbnzwUWv)%6<|KoAJKy~6<4_~AaLQt9M z#+%-C8EE=NT5Xt*O2AS5agv8HIjid`t|j)O{>ni@iiF>bST=o)_|Zi-8}-YK-6PKm z-;a+@x0e3zUPl99X)CjB2AFJ?8-r{;(*sXFc(Wj8Ez(S^4o+2>51U?D-696xE<(RfySPcy%Zp@MKc&6D&G+Zi6{-zM(f(xbgg`|l z0OQ91HNyk1T!HcHG!?PurKw02R~(0feh~_`?YmMo^f>yyRAW;EnHv`q=i$NruLfI( zs~ekW5TRVoXE-kcc9<8psq~fTcxXYO9G_iE2(n!l^_jMQD)s1~=BnA{0lD)%gEwI} zPxKx?l27zs7u7&YFrs=KaUxK1>qH7F&P;i!;hzjjz5)u*&(c3~h#+ur&yi>t4}bi~ z3-wm5{}vf$c1E~D@Zs9ZuKs6SwZNj2ec#USjf`?Fk+QBig@jO z77mbbD^YtIOnxPx_qQnM{f|yy+goUbhlS^WQBe)OMH^SEMH0>yR-p3WmyADY5lWtvO4*Z<^*v+v~Yz zkL%|E73)%#1@(sr6l2QdKj>A=5MynbMu(P&UaZ%vuSuLEk0lmb&BFUx(uv{b>aiT_ zc`)iqk&)LdU!^@V+Un2%a>)7iZYDur!f3sTg=3k_Nx+30FaanKup_({gMiF1f&sx2ZyM8bz;1oDN*^@UAv2~LS1 zT|tSqQyG_mie8;w*~D<%T~Nm?6ZK%}t zNtRy5(3sxOFPmg2ks)MxS(h(NzV|uS9IgpFV0+H8j1p5s3epAN^8}5AKyn2h4wH1s z@5pss)SY|V43ek5sYo*%#qMC_h!$Q;RsUQV;Dyu({7MfmIb+%mCc|NZE(EfylC7`6 z*ACYBpta)8!GKJjq&bxEH_7o`<$iak$ zF!k21sDeo2M7zwpd2ZDm8!ti+2dS)Tw~JC!9o)&0O%IGr-w~t}+waFjCB|I{q+@fY z8=oDaFbuxFhTThy5=}IV>apEAir6G?DtvBg;_Y^Em4WcRN<{*XkISA5?p(p(k~k4f zB%I18D=cJVTxnoNJN6mlXGdS8QVaA#M673%mXL%ZH?1JyeXgf23N{nu^Gy>~T6`Q{ z&Pt!(cF}f>I9@mMs*WLcUuzl*wbv56vZ_jC+gDGC5PRieli*3<7cRwjluhvB8%+&l& zgoAGr=|e>}2I%6ALl|nxGYzGi(#viYcWJ#Kdi|PKx`6gsgXtk{gHfi}j9VPe0crJvwt&NW=3(8!<8)?rC zo0g2${QIGtEjB;K+;uzSEGzGeRUkLuZZTa=l4t+v$#w~wNKn;v{2KTC58lizXJqOk zTw^ry8z;s1$Gxp-go=MpwMWo9)gJ1 z6%(J2RLQ(+Wf~q-hO_373X=4O{pS$3Gxr*CJ=C5zYwyQ_pG7+(-eU+FV_8!bm?NNE zywRttbE`2K-o~*u!k*uvdLvox5PpzK8I=lfga{tjZKguv(@ zD!<)BKNJ$tKAoM&%efaAn!CCRvTZOoEDEt_ZG~BDphZ1#@PO*=85S?~RuJ&MQ?@z@ zDbdE;3Q2snCwF8i@LG$S)8c{+cAvi+uy_L(4gA0=k}JF6KGP{VHM{q(5igoO=g&DW zsRgpOiU(0T(y2>%*CL8TzXN=%KL}m&J`ldj6=G!_4>Wb)>pF#z?W`xo-8mp5IKsqw zg0V6d6JgX0cwJx9bl9HBKNk^JITZT8d_rcf#Ol)M_tkrA-B#@EcGU=mp2B=y3T`y= z$SPhR*NuO|p~uYCKrh3?3u&j_-0JPBsH;<-thV^2%uCHGg(AG6$*$kOCu(daZDcOh zIM_RnNIf}DhE4E5X?P2#0_~cj9(Sf6im2Y`vwJn$O zKCQFfObvLFq9@HD3TEmg{438md+a)A=9qk%O&7^{fgp1|WClPUiFlW4?`Pk}L)Z*R z`rW;%-TP@}nS%KX{5c`fm)*sOm#HtSm-tgqqW$$o^@8Mi)=R&4KJB8e{#i3O9;!M9 za5V#QDSPn|#p!+eZUMHB+*!Y2UhnVwWh|Wa6#_9{$y0*O{{W-Bg?-k)5wCYKq+oct>}jaw31V26a5_i5`idA-^s1hRhUKZ!$9{)9}1kRxCF4lU!t8LIP`Ld_0DjETa#Os zEYDO0Wecj1XQukGL8dI1+3E3tlE7OY!Kp7x`vPsI&4Wf%aYCHWN7&Xn{6{Qa$dWK_ z@m;o&_r2G=#%@h{>OzSkJ-zug1@U- z2V7(x>}rxyz@THi6Lejw25WzfTtM|sr|Tq^;6?d7A9S$9;$%q-T8>tQeq`_FLWoS8 z{6y3M-l7R5wjf+(-dsN162AJjB^*SNs>U_@aOqjnuXY2kl$JA2Qdw;2CXBG`FgF^0 z^;MyX0y43zPzhs;ob~diP~+ETZ~s z-#>oQpS?0i=Aq`i6k?;ZJI(`zURamOn?+C+K*1TitA-aO}wu~xfVM~vFo&cvYt*uBHu5A)uq)2uK{RyQ$i&`UDJ z8${Sb;1dk~;W7U4#DknX9{f8xI|&q)t=>epvy*cm9|e7?G>Zh3;5Sgr=yG4Uar{$r zU6Svh_xv(7SlkAkTNUO;RO-ckOI6Bbdm6|>=IK`ql~>WLDjhewd$VaICPYerE5V$O zw}MsX{+XO8co}L_RVJ!j9J0w0)DU+t@{Dn1HnQ99K+j1y&tF?DSVKA;5@f!Ri7&PL zEkS7wmg9lO*OtyEA1jt=ZzIL zqo&Lw14K(|B;seO`u}LD&XIQWT9E*2FVIgp%6o6y6GOAqv4k$}k*+(>87>i!CLgT~ z$R6tTg7yY+kNm@y^SJfw9AD+4j>&aF(+a3c%C)gNEREm&($zH`)AEi0&D^{>Ms&r& zjmpR%nze^cOiT;|MP<2lN8z}FZQg%JptZd1OSu_;;+juN$gjt?xMF7HAMduzoH4$T zI<26(sUNTtWiT?Eew&*LLC-b``39U&et@^RHIC@ORAi9-Oc{o}?!5I#o*al%H`Gj3Z2WfkSCo&wx2 zQ_w&H?5(Hvv}I#^=5(_DH-m30xuR&ZZRgl0_n~YqIc=`)(G_%Fj-+zq&P2pGFke#i z{-s0LWP4@TA)QRSRtPWP7v76Lt^A)tPJlIeg+&#NX%< z{4&Dy0A@s5OF5mQ492r_>11{yiG%fprmwhbhZA10n*iwsk56Akc`b^-@?Rk^)H26u5P;Nd}#Mr;@E*WN$mW8p8}(-8Z^ca%#(k!;H(}Y#o9CpWia@ z=|8H3HkFTgUosBV2LNt2RO_j|i$Jvhcgm}Iaf}|Vf-d*pBxhi`jg6-EVoh{6UC<_f z-V}{#&Y+4qz$=}9)-QAN3TP*KOz^kA+c$*s-mK})&m-Qx>^UjZH#dLW@yY@#&;It# zz8)QK)`5~FSn%Wh;edzHLF+dnYK)j{ehxBvk=DYcN2KoqPdm@RQZlhA{>E}S5*r+Q z5u;_=tqV+zKmhKy81~Fi)h~aI0*d4h<$XOX>>b_%WI&Bmb|s9>D$3`5htZxnJ7F0+ z-pElSdZ{iCER3KIY5nJ)m#FBy(dziz&oBa7Dn2R^mNMW{RG$>8@a0jYNmWQmsygCT ztli;)GDya%(#4}32GI8AeS~IUuwLKsuLuAtDZF!aF7<&aya}ck5+3=HHL_FPR}IMt zaOK{he*Q&!NJw&oMFc5=n|g6LDJX7uAE##Z^RaQT7!EcEmh-*X+rc&IGmNrtdJCG! zpvIn5FTYA;Xv{1~PuD;yiU;Ybx3?a`7aT1#v1_<~QxdsST_dx0q8w;M>R#aTkJRX$ zZQFsoI4NXVj1WnB$D1^wR8FPd9nqlKaD~-Q-0eH zCEe!|bO({|-)rJh@M1h}-=Vu+68+?Zm;6eP%sEF55G@{Sd4S;~a@GV6#yh>P8%mFn#Sf5mJUT;JTHVt{!^cZhI<;3({*Y;_1PO_~7W0ntAm!HD=k|pvRRivb8 zFei>_dQu_t@a~8VDuu0z?n%EE%#tt*27bjkU2g&ftK?~C@i!;X&IwUjIbi-Y`+D~b z5|!)KIu+CtC0@aQX<|tka9ZCfd=*ntwSH;O5ELo*LGkbyq~g$2jmX0Mh>s_ek?&0B ztOV{Te1sgUrJY%po~&$BqI2!vxE?x$x^7g}Knk~59r}FcWk7ST17SJYuT@(p2(hkj z_h;AVie#QBD&1<=Zp56W((c;$ze79&JI9*d2fbWFQ@t9FY~vcE1xun8AI!pv@qvYS zBPlN$bK)>?XbYVv#O;*VLjyS!|&Tt)*0>VZZY;K`-1xAAu+)t17Nm&kaNbisMzY=P@!(@CU1(x7Tabu&_rj^+t(M`KP1@@AbEvxA>8Cw-zWRn z8}6z_X3fB>v&$+i^&tQSM|0rqz^$01yB@;s>X__}I(>o^lH8XX&PiQUfHB5f1~@Hd zDp2anZwI>cG+2IZeU;5vN&OSmp~+_VI|PWlFZ18w*O>Nucu)$lE*Kdz>_guS29>nj z-4UjyRmc(rAR+Jw)4RdZoK=G;+3Z3Zx|xTC1!-EWQ*wSIKw0cdXwuUfSnsV^`(QkN`r7r|OD{4N%;GB&%GbV~ z#q*3E-j3Bz?k-TWZ{G?d<|x+%hWZuMu?$om80oPnWN+0y<$C8P?f82x7gC*N*GF z{&K*4%J{G&pyG`f^ko-C8~xbXEmADt|kQZGb|t=;aG@<4hB2lJ-n@xNySayzDvb$ejB)p%}nDSOf@&-PY~j<%XvO88q`HvqCy<@h@= z+WXJiM@gbk-_(fIp~BBVI23l*)82fRT2T838nj<$>pLrQ?@R{z5iRC>Nz!j3{Z?s6H&fK6+nqb#j#z4Jf8vJHfX*3J zu#vuU7q5Y;p~VLj7GTQ_&{}2SWY|l`ZY5QE3-ixnfN`Wf3rj}=J#c@rgKp8WEW}Ah z;q8EWq^Nftq~fwdI9B&i@${IasSr)kflJ$ z@cXD1!4kB)*{#%ivh_5yB!EFSxqryn(JSYwqOpsV%w-@oOq_b0b@wC7&6JX+Zp&2fgZOIvrk8uL zcBNLUGns;AuhFBs&n)`HQUf;tFF>=vq_f>gVYXoSDMn*>;iAW4yg8@PZc1ANE&FyR z-QvT(6CG&gZ=APDRA3M;F;X(A?=dgYOc8A=8+V~ zzd}&?@B!$uhNqfQg=|Os5pF@OK5Is4Mh{OXc%SOOw6*n7(`^t_qb$N&W*{+epo)i7 zAZr3sH83Y40ciS|JRf4ZI)~l<)&;n-Ox2R!cx=E{pLbd<7fLes7ua2sBi{s}naA!ZQ1K5H!~I_tc^AGw369 zH)qKkPYkM0%rG>EGf)E=Q42Z*{c;;NxsWHhh zJ2&5%rzP|!vG1lFmlswB>~tUp0d_F*$!_21&S8Y$@_kJr_xwF@MYc9JII?ndV&7c_ zclE-dBknux4^V_O$*hX1)1A|a25jObQyQ8(Rj zs(uin)601A6YDh-(Y&T1v5s!`1TSpygSza^?&8~rv6wXiNWJHyPDod4n*I4lDBtf- z|Na*hnT*o?!_8prMW-4agI2QEa)z7c{tw>Qad>HPWR(!g%hw#`)^;wtdTD|=rbF*K z4|}m939Dc_D!>d1NtEJB0m54gIiK(e4f}=Y9Zy*o7|_rf*o<1UP&isE=I)s&KOQ-s zeh_X2YKxm2nC^$+ch$*ydk@{cw!FWi&tPO2oO|Zq$5@V9pL*(MLE!Vqvo7Mothq*( zjaVmE*sPny$n)1dV%;?77p5F7f#*$hXI?OiC8+*lhZJE(+z$#})#E(Y3`kX%QR85{@tV3a8LRWEMhZ{XTe2 z(J;Vwgp{*P?>oj@B97mKo~`BrCq2ON=fcf?AEmO~A~6Hy&#_*xF_uvUOjd|BxFBk~ z>-tBD*B1w)ogzP~nmCrs_6)r#Q;-VcDeGFH0BA3#@&~UddgsIehrk{PEx}Q4 zf8oqIBT)a|=BW}L>rDDvdxdcMA31vfTAZvYM?B=p`DA5;igeH#?S!Npj1RUQ=&9H_ zxCDYo0$dfCLkhh0sfKrLW6z$LM85TrZ95}@|1l*_Mx&rGDRBBioUI6ASoY@Hl<$ep zK)IWDZ1#dM7r#)@w-uAD1mF9Z@w*i{qbVspik;ei>%9F zvIqLJDhE65B+vhOjrH~wH^duyyp3ZuHLwEx7O|dYLm@kB!rau%1dyOc?|Vp`a(uXH zdMb};&7{B1)!nc1cT7)f;U1G(Btz zb4xr#*!;c28Zw_(#((qPYD|&U&I3|F;Ki|45GdF3gp#~j6#|1g=UX4&N!QIjI=&rl zfFn0HGPb&~FKSiVE-=yp{V9T`g z`~P+MK3gqa9$b$929*K`*bv2N`QJ}eb5Sr-ns{0Bvq6IPaItzi0;u_A3j$Du6{CP7 zIAfW^lT)$UfSEz`_Hgk>;wgz{G(L$tCqayO$61wKeFT3dCX2 zL%&5s8?m*(y)+HBt0s$QnVNNHc%N7;&@$-h(+Ld!H2cjvIewxzm6@zu`N-u$k>FIO zOvqQjE>F}{jtxWn!OgX)vs3Y|Q0?==_0|DoKD{9rlQTZdhS#iJ)L?k<#1#2E4Z<3X z#F!Irl_Et2zWRKPdD(PLA&>5X3I&O2Y<5#;B8sL@e{20qHp``~^w;4u2PqjfxEhTt z;gk92TP#(hzu%)}22fZ04d$F^4cdv`9y0h|Mp^oqzjg@5|Gk@GGxe;ALU}kraAErY zT>sp3@c>Qv9x>d>WbuavfIkql~HFI}3(M!TnaL!j0j-JyK{d^5dyd0*;%1^UuTLQ`u)InNcG4 zR9t_Fz5Svi%j>*%Rnwrei>S>OTgj%#*`#zNd-w1CMOTc-HU=KaRItfJCEarps|6^n z?8)!Dk0oMKFaHRkP>|Cc-k2QSr>0vSy)u&cD|szA z%1E%d$3GHfzCrh)d2K9lB`i)hHnwc4so>~nJa_kpi8!Ps$xQhXq5!iCeRf+uQeGEsLRzL!);H$%lrd7SH+%aoC#T<7+JUu4Bw^ZA;$ z(D)$qI^&oppEjK6m5fG;c<~2HuCVsvGPO|mfUARhd+@S}#Z6DqpYEnHMo;bVvL$4n zm6bM|i5`t1C9yBPjEe&g-2Vj|Gp=z(&tV&0H2d7b|BHM@A5CNL`FQT2>1MF?9S0FC znMzPj4!zgdYcEVkh;g>^`FZURviQ?=M~9-8QgpcV!rCj7q_{Zu(6Ef6n)njgMU+&` zl1CtqM7@OAm<)?dHnddcsR@SNRp+TD9%ca!ze$s!wXyFi@x`Eu4`&nq?-~vM5}wW`TUS{H%)HNp6v4(pPfF(-o7vU;%O6} zb7y)W`9w-qUS9rpr&#$YW3g*Cjubu{+~O=j()a+&#oUbe)8-HE37h-K@;IzL8a%go z%$k_=4^IchgqhD@gJ*PTI(t>`TJW}<^(01exWM}m{+mNSF=_hZC-rTNwSO*;HarKb zu$a!j-Fvvh2VcaXgUYcswHSKBq5_hi|J~j`e(QD9!2x|j62Ii<&*%sU7mE7&-Gkh8 zJBfU>;jz=y76MCUE-?>IP25kf+CxU*w@s=PemIkeLD<=S2oh(w=~D1?PXr$X9J z!ic7#C9M$ZKyrUp?<$LHuuU$f55 ze?6Y`y^DdcMWwCMT`g9%B&C*|H$*3?#_Ja+FR=E5waCcDPW1z*)1S{9N89kz95}r{ zNUzZ&t|znGuvVI{CFVZx8%?E=V)x4VZAnSGGM)KL$$r~v>s5xb48>Y8a}w>SdnQAU z!-xt|CZbgF`MHg2a?;CmH-43+covux^ry707}}tW$j_8;U~|p}mzmo$lPvhSjwA7x zf{%IcajPs3mcHde3Cunkt+Z+UF5DI*ow!o?{`49?4sqZlPFN}QVCM$O#Aelsy2(^! zsXpXI7nb16yN!v=NIon9Ca>MyfziFFq+oXcGb2^O+1Xux zS@ob8^C$nlOP@YpMb0M-!I1b-f2wxbeCSmMPJ3gZyU=@n<^BoH)`3MpyYA}aB( zsEIoDY{6}9ysfSNhL)45j$B{m2q=P_e$`1^wU)uY484CbE^5h_V)SPdljfrnr3;P& z+dm$jleuiJVZMbw?2qZpPZJFp>jh3sQAx*v5f(wi>mROzU)1t?zADaZ+7hk0V4LPU zGOH4QmN9!!RL1(;)wBFLL`Vq>5#&vA9_S`D4TpFLc*2$V_{+h=q;PC9vty*m!VXr^ zNxR(a8x8Oki*uS_$fVtAdeEbynpV$UGlnP&$18`Z-5RQ`bjQyCbYTWN%4^8kCqDSg z+z`9(`dV(-Q{LnMwsk>@6%7z1RK|Ks`E_;t?yj)iwNWtp zc7LO*%USZsmGkuSrQt;`y%eJz6{cxOF68Z~G<46Dp1`M@E9&{kkV1A25+0WGFD>IyFLPmLZPIRPg zHJbP#xRZ)?tJ|VOX`F#dJ&Mwqw*XmI8xLAGqeAi==241Ref*r`(Xl*mg|b;u@4Ia; z&JF^dkN+Skl_^+$hWSoX#Gz@w9e9fu9?Y9O*3Jw0=`r3Ag>plGYC$%Gr~9eSo2D4w zndm1XP4Z1-U(%y+p&q7nBZtL(u6G((<2p|P$YAtjPGr&1J ze~ZPdr69&IsjYJ|vN}XSb@9QgQ$B4n)kO~z-{Yw+RjzzK#8<3u!7s6$HMl;fAdIE@ zOD&?WUW!u)cF90obP1D)y?-6sVU!gr8V*_jJnMtuL2J8pro^$uVJNe`8EIgkOV0zg zq`jfbCjl)C1WXn9{fX6!m%!Vz>ELNN(w<7o}BW%@! zWV78M>plJamhXPm=85cFuE>w8xgonXx;gjG$lP*qNu@MEVfBRt$y z3@kaWMEb884*qmZk!`uCq^xV_@|s2nypxHRtg2F6g5TDY-u-h|$abB$r4k|E5~yM550f+3$X1 ze*tw?AsGc&O}(q)poY|$%cLNl(t!4P`w-X22flK?ySVP;l@_J~|5rLy<^22#x_EAOpsccg%3y?xoQcv4`Qm$KH-}+b@E2fK5*%w;`f_&A&%n!^t)sCo_e&SYfJM0#TK>R;L<}*s z&zC?=Y1V@W9Wo@y(9^$~QT^XwYA;*joCQ+(%P-n%mhY{o`)F7|nR^JD`Y8R*;q%@gX+t7E7zuzUZ`*rq`Ik(Vs zPbBi_8L>%$Uw@nxlugMW)-QUhQe0qmks;K?VVPRTn&$vjEP+o@FTokJT2)^YQczGu zud0?^gk)Y(Ia!rpGzQ*-BcMA{(qTpiK{;6$e z&-)ap7SWF0JeV$4r5OkVO-vTHf_eVwC@XH}A5&T2`7~G#zQ^V%&@-vD& ztzsq4S`4O|a9ZY*h!=w~rJ?I6K_uDbABgwd@eqqiqb@$f&pa7Ly`gl@2Ks)v70_QVZMf6?stum2G>cVl+Oi_Mvrv`oFf7CxTYXVa8-+ zIg{py2jLrg_HDi)zP>BxH+~wd+Q+B&!R|#wJ>h-t75kNk>oSQ{Q$Tfz>f$53VyfH~ zKT`8WLfKtg`;&+${rBLtyrluT%x3ZJ1%JpGay>L@HfEB|SO^hfTh^+ljgE7A!|@;^ zP7D>nP#)Ub94^M=9lRn#tk0P!rLgH-BWO_{z1&ljl&w@k@LV{=&@NCx zq(VgK=xBSf8@}=Nu8ibRz4MWXmq40S(;D8TDr)tk77bv zRqa<~z&P`I6cN&ys=x;}v9U2NzG&wa@nzMASU)?qnp6RQk0B%?UtANtT6II*ZjN;-BL^TrmzzM3+Egeal6Iveh1&FlF^J4RPi9KK4U zSUEj286cxUI`8OQa9n})H#>kyS8p{SNy;^GQ5P*N@zHzAB3~P0yKkxQ&-ZxjiF+eY zNj^v@h}%m8|4OZo{>Oo8ht5@#wFRT>=tl?vJ%=)HLpP}lqtGZ(N!j^Zh2I7sOofzkn zJ7c(ugDZ&0b#v`!VRj`#4XPnEm>PREiuaR>o-`PiT?@tU^EmXfv$H?*5Oqz@PWhD% zdoXiQ^S+bGv}kEneW)Xl{&)G6{%fp*faLzA^76VG6m(JB{@3=bNubsY zaGD>Ep?}t1gLwZ2xB)cAj|?R|_fSDwvxf zCna}>s+L)aPO8^9g;a3`^z?gH!nEQd5|c+=?+s9L-oah zI(TPv&6000F0t?G_=Qp3Gu!pCq*YR!?Os^vYtgA8?i4vK(}Ig} zggI(nyC>*{%B|7)=t(L;7|xENp>KJfxyf=Fb3}FlQ0*_Ry(&N62XM*iqNNlV_1T;>igG=A3l;RpVf#C>o*O> zg?A%-p_+mYMPuV_J)Ic-yZtEDZudT>=6<2SFgJ?s#nzHGLw7MACFrZr!!=PP{u8mh zZiMUM}Y zDtIK8^pz6QCZ}e5t4kxuW-1wr|;jkK^{x5U%KVn$mX%7gNn=_gJTHKelruz)#^aQCXV7my~%F;6Qd(?CY5QgTv z!5q}bQX!LH5)!eu9$=`>K&-kIe>vU30My^l`%g`#w#?_)sBzg zkcVoo_QkuRl{R*;F-I2hjkjG%=jR*1+V4y8R6d$-9OQd&HSQu zg(#~PyuPa5FumBa^sZJu?el_lME?SQO=i$}Go8aDMtC4$`iqBd@wVhhFv}UD;}>#@ z8$M82a96Gr0Zs}0EyQRDP zF3cqt>%>-w-=n2PtOlPbGUCPWpDbt) zzq4*K$+k}dr9MsY$A6@L_~|e@iU*#@6Xf6q{ZtpE&Z$G>To z6up=sM%kNk17b6j*v4m0LfjSHqS$Fvuc634V&BVPF=Y^lBzS+%&D>^K$}mvHeE9@q zlXj2tF-&rhvhnAAVG?bL=v}D>!h4qvA^v!N3EU>ih{&Pw+2fOHJgS5sJ6Q)ho!9J$ z_5_n&WA4;}MAVG|H|FuXo~Oy@A;7!5@AOsKtulzrMY$@dgohjsu7RT-AI~}bJ;I!Cf($c4f89EJ0z9-Aidbh>bcAz@ zeUYcgb4L=Ix}#!OO%{Bq*fGWyH0Qh=L?xCR%g#j*5iDZt7-_wOmo~NC1O(l%1qv}U zeob)F*I(Y&)9Z0tLHBsqa_An_r877o%nih|`a}tE~J$Ha6+@hq} zb1?>0m`YZ?ux@O2-CAk)+`Siz3<&Rb4mc({G#hcvF> z>|4`r6Yi1~(V>@^V*yRAcOGeBq4ok%IyIHT>1h9ZZS5a7waY*!ZZYjeClrof1PS!Q zspgQHsD6n74hbYD6xDg7xj}iI&;x0CsMh4pW)anskBYi#VOtljcI!^C0FerTG*E9? zHrs@?Cnen+u@@`+UBE4`(P(@HA616|@SyOpnkmnsuNlAv{DJz7m7*G+q~;?**^1e2 z-2{5^#Lf|CDPdfP46Zh2UTq%KA3W0Eo&2=;tSfN9cX+XgNVqA22Z`Dug(jCKT<@cY zOK?<0l`94RkU>3EU?sTrjb&m78RN>2$!LL;2=*_v9S#oGXeYWZ(76V)K%)yHadC-D zH5eZKp+BX`&1X$&%-{QHz8K^Dz}h#u%UBesw$Zt2|8GtX=>AZ7wm(Z1&T~hA8>fc( zDtN6EuEBf1A^tx#!;X(1uQ;j3tQR34+xsce&gB>~wg7iefd=9=Ro6J8%6xBg)erdi^|hDXXj)_QX8vYZL~lV9s+5K|um($`2;7Q^>HOOSwV{M|eG zwlOii_lqA&ag3_b-Nqa4R%RR|qpmS&i@rhk;$WDdM#I^}3ponNIIs1ng}*Q8VdAHn zYvSw?N8A&Nb_g-N4U>)-#BU?adR|2kz-SvYGG$)ngpJ6gN(X5(fx)lbkX^Ia>HxWm zjkEQdh}PN|{XPi%Z1kC^{cQgR99GQ8K<_`fH-Eg#fLPA3$gQSOc6ag237X(tK6*iz}fn5Q`uz zxXg~0yif(p1p0Q}X|LYL*811{zytOUU=nSeD=WmqHXPlX)M(NnB4R+nj~eEK1 zcRBgScrbHy^%uLNrL>ZNvW!#nGss4TcSc5s>_qb4B~+Z?P4T*4X$bIpzO=p5wI-23 z($KfV12J7};bcBf)L=PC`E8!4eq=ub+6I-Ep;5KcG_{u__=xJv%ejMS;W^yf+m&UXRm+MY zktSUa(!|DX>*m0xEtAQ%k3D^c6XXgGh76GBykXh+2DzSwi_aRjS6{F}WZlWjdq^T3 zA!8teO&Tedm!TlH_*xcCav~jD#awq50CNmfGq5RvK@Bjrm}s?;G5TKio=84F{&UZBPtyd%)+|*nk*hh zy^%YFB!hHo{%0%_7#mLDj*N7*^_hJ-JY3Q@85$kt*Dj8oCbNdiDE~wol>j|(P{y0G z)_wP6|IVF!=J~^0Z@4BQt&lc{e1K$=dG6u7K5pWDq^J3M^iieTUqsu^xWj{5h{Tv* z{Q9XduUkLxR}J6X?<6tgD^4)j0vgS+ADCgG^DG4`6Q1EY1G}`R`)Cl6FS4pGg-nZp z6`Xkvc?aoYVXnwkp;f)+2Ot|k)YS-nY~{s>3grhzQp|zyPFXaZ{y%?6BC)*Y!n@vN zqIT5Mc3ya(@`lPqs_a5C=y^5ib1B8`e&h^CRyBnzi5vJSjb1|DCs9zwBY4lHQZg2z4hk zrNQjvqoI|CXU_O01zylvz@X0|T#sM(Lj?tc-P;N(Qv+}cte&l5Bju2#Lh`Fn=&`B= zIa8eQ;|Ura>D7y8iI*J3_Z&eVypr_auL>7P@3c=IpZKNUN!U3Ze&$8~guspfg}p?f zH?E>?{qb_uVFl;CZB6+e$m3=<+W4vu4r7 z0}GWPF)?ei)0uy8@OzLpaps*|f}1qpCJfMHvr?l|B{(yyiVJdJQ|$K_&m@R3iK2~-+v(PJ#2|(2% zm0vf&E^0y=z)a0HmN}|C@9@=2Swdzm#nJn5t+0g#?!Q>%MdHJ4sJ(#yO1`Y3$aV!R z8xEcEbmXuN68;>F=E7rZaYtH8;TS9;z^`_@hMk6DhYJlg^-l>uWIXFu+#gjb(dO|O zqlKinUlt>+?oaGx;h#u)NB>~p5c_io%3~V;p@-o1W=FXwd=djk9HkeyBoA-YD6SmT zy8DmhI^#pHK4rbm@%v#4NB4Ap4=_gF?7m!jK>@r@dfQJb!)pyf@u=@|c*)7Nl*F(Y z8j^%Qq$bJ>*X#p`#yunQv{77O{Ec%xN4IY~ez=i3-ue%!?y;3-4kJrJZ*Bjg;>FYP zz+tyIdC$7);{0rq=4P#89m2BnU!T%>a|EPo0e9g1CgXN{sc3|%5EW)O8I?n8p_cJaKG_+zAXz1YeRjR&L&wbzCuk`Ma-a{>F zGOTV^M)}`|2lQz9`U<`vfDTR`AAxmqe(#A1k%<#;IB{AxSG7R{DhJkQduRf`|MM-a zaFzae%a>DN0~VLxXH&Ri_^F2%`CP*vM~_Hof13fY;tg1Q;w9}^_ zKq!&X!V;BmGaL=OyR}&qyF5+!P=9^*qk*Nzmeyy*Ew!4XxB;wrZ42Y-li%a7vq;T4 zr5`v03dv{3gg5uC1C??%kCkQXo6jCPwE;E@gc z0_VFk%JS>w69E1nCLq6+i@{{f&pOrF+6I7P8Sr}WsQI-my?;DS38ceH9 zt!+$1u-}m@w0`z$tpGvOtHGJVg*3XW>c&$@OET{~by}7Aba^)9HQsQ&{9OHQwTrVA z=ub`67<=#ML=#CvU*2;~ItoIVefTAlmj;STdQ8W!Twa}OI`n7_l9*tYq{F<%eA$V> z9GY!lDTv94uAgkRBn|$BpcOc&Wd)sdi;mBW|M|!- zayLVy{kg!MkD^rii&h$Ka9{L&YzD*N!j_HYxO*i}RB15rM4pUS>G=*BNTC4f0&hv* z+?rTzCjYh^SXEz~tH7D+{XpG+4AgocwSC4h#oOGN#nX`Y2cpC#08+I^VSWhjA(aY& zLc?(DK!Zx{9genhBYD7Ca+BZYyTjTS>=jZeuo4hwc>JeuDy2!B9(WhIoT_AtGZ|t* zvSFRL-vQwZ`oEHdStw@iD5qCQwfSafHJ>aOLL=<_O5W=X0&)2IR!_s4Dzp`_b6{lO zGF=Brm3id+P}0>oz!cvSP+9Zk6j!8kw8K623Z4DBZ15fu^W)!)Sm!yr!!c3^QcJS& zULXnJ<{GF2rn zLXxo=8_lp0kb~3j4w285w>z?mii?C7qG~0y%o4WZ*TA)sdS*%)DaGOT`5YP_AS}cB zO6TXypI^(15`n|_5@m6Owc(=Ex0h?4++v4*AJq5(8}QIIKcGAt0HG^SRB`Yk$Ki0v zA#=X&3MrczruWY=bMCV zq-FHQP3!m6FgC^VePuqV#v@~6!U8(iFU%UCQb4k)*QgWPSsHWDj4(+UNRXG`Dp2~% zfs3dYN)PsF<8O7^?O8{^{Xw5-{;Y?tN>mW(QP1<7vDfvmU2Pq^A9EjO>mYAT#sxgHZN5_Hea;7_2_f{mn&pH@==-ZfyO1SUkV?^-Xou|q%_nhZ0q+BeRr?{?{kmKO3kzGx6=cRGS={p|DD_>X&rSup&1 zrX0hQ9TUhCQXzS9{qCczj(^`LaCIuGC}VVRiRX77#-9S8)yBb*oJNSj1`=G>#%sPB zLbsrw;QGM4g+V_;7X}}_;0qQ|t}MWg4Kfwq%wysaM$w)_&q9@ww?m@d?)|nZd;0nT zK=R_+8BlM4zR`kBs753X1d?D1t5l*E&915h5&&VSiNhzJTW_GN7nxXoC4#z{6GOeG zIMPZi!iaHeHLgZkCxbSQ_}HTsEZ@{mTjHtaw4@O^zVg^LATd!`3~_>N#OYxLwDY#& z9Ga+ko;pfm|Dj{!E!JP3K`ocWj6nbeBg{ikBWPN6gw!nT?y@c{DIw56LHvLS#HQ%Kjk3m6Cgb1h)=mY@gJk@jsJeo0VI$wOU>P`XI1 zU!?t|7^uEiFz!DpWpi-ILZaaC#<9moW;X)q3Wf5aQs{9d-a{}8=rPKYW$G3t@ZyR? zHT%X;I@O48O)?uZo~5=qJgyx5b&;O0`2?KBo^SeNu~v*&F<-@ReP62&e-{XHUeKS_ zwu&|mUKSr_`UUQt$Y4=-c0_}L=mn3a9R+G2Zas!+ysqW&Yiom+q1VQ2)meGG7&GyT zb$KKdy_~Kl__z4!44sCzBW@^9$ZIT>9!)F{UTvMKnet%+`utTmY?vZxq%zlP*ZSYU zs<3}K#}mz3Vgm#y$z<(IyId99E>7EpCx3pT#jz^l;qLb?p z+%NY}aFsqTNb|3iPAf;!uLkJME5HQGOJo@iF%DSJm925kl=5Qz49ghav!_5lud=dC z>+J!|@k)X(F0ptqWnCGB`ww8GdR1GzyG~E8oUpqHY*azM(hGm89z>RyWxqTvCoaoy zdjG@jU3hU>(QAzlxI64(LuP!1&E)H{KnhLdnlcPjYQfjCfL-BI^YZ|U51bXBRPJ_+G|Z`T3aoMmqu)ztX~7Yfn;+2clO8Q-c2E3b z0~%>KOF@V*q04Zmzy*VkR7Vfi|@^| zE8hSvAjO+TTa>o(ic*2}*%XCC7-6t)fe0eMS@`O6VXxS>q_<^ibLxi=_{+Rwn%SFm zL=cQ2NkvU>0DgR{yER+iY*7GXR_|M^v{*WeBS>RnLJle+IVPn`NN~tXMj-as{IVSJ z_S3m3R-^c8>VsP|$jPG}scp%3Mxng$^E0POOWVWyYy2nFeNj=JCAV_W{V}Fb?xzJ= zeHY|!4|-p!Z2DCiZ+4}4-zDe(a)>1G_?D{INf~*%7GTC`l$L^=nvABdN`A+~_tu`% zV)LJL##@_U!IorJ*Z-1qcE&lsr~zu6q8NKIv=ni~b>Ej;Yy9`ah`&L0ueRNx3YvYb z9PNTKWHFE+jm#R?I&E`m0_D!(Subo@N zA#gcb@Ip1L=IrW2d^jkQ2h!e4^ZQF6GXnVrnzCedrjGi|TNdhnYKg>8P=me~qjJ5O zy7>iMnAZ;-IuVEXx^lpZ(OEyYBX-`l)u}Gn)*s}i!v2`CHZYq5Wg6J>U>_7zRlnur z6y}L$(~La*{|3>nDk?iOu&0uc1~dWev`{%TWWy`M)viV-)vn(;Qj1u_{#hJKU>S)T zNn#;Ua8AJ^7SV`{8;B_gL1X8QDm-331VnI2;1{H)IF3~LT7E4L?FBm?7TqT~xrVBiLIU?{M>DTWa?dC8HN}zK-x9`j>SGQw+1P?Q;{<;tq zf0%SU+nl8??RAMCE@5FiX^_+7nE>KOb^XbYZfXf9BdfD7BD= z_Vm$q*x2lF-93zy^L+m+`JdxP4kkmEEB1QlS@N|i+UNT1ICb49{8C)v9i0blkz}

|xVQ)=-E>11OsB5Q~wsW+MC@M-r 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Þ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 vmoD=Jtg#(39?TOoZR(E-I{lLwk0?Fucb42 Date: Tue, 25 Jun 2024 18:09:36 -0500 Subject: [PATCH 2/8] pre-formatting --- ...te-your-first-python-package-scipy-2024.md | 153 +++++++++++++++++- 1 file changed, 146 insertions(+), 7 deletions(-) diff --git a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md index 2b8a8a50..49478c01 100644 --- a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md +++ b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md @@ -15,15 +15,154 @@ classes: wide toc: true comments: true --- -## See you at SciPy! -Event title -Event location (Conference link, room number, remote options) -Event date -Event time and time zone(s) +## Create Your First Python Package: Make Your Python Code Easier to Share and Use +* **What:** A hands-on workshop, titled: [Create Your First Python Package: Make Your Python Code Easier to Share and Use](https://cfp.scipy.org/2024/talk/QT9GBY/) +* **Where:** [SciPy 2024](https://www.scipy2024.scipy.org/), Room 316 +* **When:** Tuesday, July 9th, 2024, from 13:30--17:30 Pacific +## Event overview + +Creating code that can be shared and reused is the gold-standard of open science. But the tools and skills to share your code can be tricky to learn. In this hands-on tutorial, you’ll learn how to turn your code into an installable Python module (a file containing Python code that defines functions, classes, and variables), that can be shared with others. We will provide pre-built code and module examples for each step of the tutorial to help make it more beginner-friendly, but you will need some basic Python skills to get the most out of this session. + +You will leave this tutorial understanding how to: +* Create code that can be installed into different environments +* Use [Hatch](https://hatch.pypa.io/latest/) as a workflow tool, making setup and installation of your code easier +* Use Hatch to publish your package to the test version of [PyPI](https://pypi.org/) + +## What you need to know +* Basic Python programming +* How to write functions in Python +* How to use a Python environment manager of your choosing + +## What you need installed +* Python +* An environment manager +* Hatch + +### Install Python using `conda` and the `conda-forge` channel +*These instructions were adapted from the [Install Python Using Conda & Conda-forge - Mambaforge post](https://datascienceskills.org/install-python-science-conda/) from Leah Wasser and Jenny Palomino, originally posted on [datascienceskills.org](http://datascienceskills.org).* + +#### For Mac users +*For homebrew users* +* Find directions for installing homebrew here. +* If you have homebrew installed, then the easiest way to install mambaforge is to use: `brew install mambaforge` + +*If you don’t have homebrew* +* Download a mamba installer and use bash to install mambaforge: + * Download the installer: [Mambaforge installer for Mac](https://github.com/conda-forge/miniforge#mambaforge). + * Note that if you have a newer mac with a m1 or m2 chip, then you will want to install the Apple Silicon version: OS X arm64 (Apple Silicon) Mambaforge-MacOSX-arm64. If you have an older mac use: OS X x86_64 Mambaforge-MacOSX-x86_64 +* In your Terminal window, cd to the location of the download file. Run: `bash Mambaforge3-latest-MacOSX-modify-filename-here.sh` +* Follow the prompts on the installer screens. +* If you are unsure about any setting, accept the defaults. You can change them later. +* To make sure that the changes take effect, close and then re-open your Terminal window. + +#### For Linux users +* Download the installer: [Mambaforge installer for Linux](https://github.com/conda-forge/miniforge#mambaforge). +In your Terminal window, run making sure to modify the file name to match the file that you downloaded: `bash Mambaforge3-latest-Linux-modify-file-name-here.sh` +* Follow the prompts on the installer screens. +* If you are unsure about any setting, accept the defaults. You can change them later. +* To make sure that the changes take effect, close and then re-open your Terminal window. + +#### For Windows users +Download the [Mambaforge installer for Windows](https://github.com/conda-forge/miniforge#mambaforge) and run the installer by double-clicking on the downloaded file. Then follow the steps below: +* Click “Run”. +* Click on “Next”. +* Click on “I agree”. +* Leave the selection on “Just me” and click on “Next”. +* Click on “Next”. +* **Select the first option for “Add Anaconda to my PATH environment variable”** and also **leave the selection on “Register Anaconda as my default Python 3.x”**. Click on “Install”. + * Note that even though the installation is for Mambaforge, the installer uses the word Anaconda in these options. + * You will also see a message in red text that selecting “Add Anaconda to my PATH environment variable” is not recommended; continue with this selection to make using conda easier in Git Bash. If you have questions or concerns, please contact your instructor. +* When the install is complete, Click on “Next”. +* Click on “Finish”. + +#### Test that the installation was successful (all systems) +* Search for and open the Terminal program (found in /Applications/Utilities). In this `Terminal` window, type `bash` and hit enter. If you do not get a message back, then `Bash` is available for use. +* Next, type `git` and hit enter. If you see a list of commands that you can execute, then `Git` has been installed correctly. +* Next, type `conda` and hit enter. Again, if you see a list of commands that you can execute, then Mambaforge `Python` has been installed correctly. +* Close the `Terminal` by typing `exit`. + +### Install Hatch +*These instructions were adapted from the [Introduction to Hatch](https://www.pyopensci.org/python-package-guide/tutorials/get-to-know-hatch.html) section of the [pyOpenSci Python Packaging Guide](https://www.pyopensci.org/python-package-guide/).* + +#### For Mac users +*These instructions are for installing Hatch using the GUI installer. If you’d prefer to use the Command line installer, please see the [Hatch documentation](https://hatch.pypa.io/latest/install/.#command-line-installer).* +1. In your browser, download the `.pkg` file: [hatch-universal.pkg](https://github.com/pypa/hatch/releases/latest/download/hatch-universal.pkg) +2. Run your downloaded file and follow the on-screen instructions. +3. Restart your terminal. +4. To verify that the shell can find and run the hatch command in your `PATH`, run `hatch --version` in your Terminal. + +#### For Linux users +*Note: if you prefer to use a tool other than pipx, please refer to the [Hatch documentation](https://hatch.pypa.io/latest/) for more information.* +* Install hatch from the command line using pipx: `pip install hatch` + +#### For Windows users +*These instructions are for installing Hatch using the GUI installer. If you’d prefer to use the Command line installer, please see the [Hatch documentation](https://hatch.pypa.io/latest/install/#command-line-installer_1).* +1. In your browser, download the `.msi` file: [hatch-x64.msi](https://github.com/pypa/hatch/releases/latest/download/hatch-x64.msi). +2. Run your downloaded file and follow the on-screen instructions. +3. Restart your terminal. +4. To verify that the shell can find and run the hatch command in your `PATH`, run `hatch --version` in your Terminal. + +### Configure Hatch (all systems) +Once you have installed Hatch, you will want to customize the configuration. Hatch stores your configuration information in a `config.toml` file. + +While you can update the `config.toml` file through the command line, it might be easier to look at it and update it in a text editor if you are using it for the first time. + +1. Open and edit your `config.toml` file by either: + * Running `hatch config explore` in your shell, which will open up a directory window that will allow you to double click on the file and open it in your favorite text editor. + * Alternatively, you can retrieve the location of the Hatch config file by running `hatch config find` in your shell. +2. Update your email and name + * Once the file is open, update the \[template\] table of the `config.toml` file with your name and email. This information will be used in any `pyproject.toml` metadata files that you create using Hatch. +3. Set tests to `false` +*While tests are important, setting the tests configuration in Hatch to true will create a more complex pyproject.toml file. You won’t need to use this feature in this beginner friendly tutorial series but we will introduce it in later tutorials.* + * Set tests to `false` in the `[template.plugins.default]` table. +4. Close the config file and `run hatch config show` +`hatch config show` will print out the contents of your config.toml file in your shell. Look at the values and ensure that your name and email are set, and also make sure that `tests=false`. + +## Helpful links +* Our [example Python package repo, `pyosPackage`](https://github.com/pyOpenSci/pyosPackage), that goes along with pyOpenSci tutorials. +* [Workshop information on the SciPy 2024 website](https://cfp.scipy.org/2024/talk/QT9GBY/). + +## Workshop agenda + +### Hour One: the structure of an installable module + +**Key Takeaways: After this hour you will have an understanding of:** +* the purpose of the __init__.py file, and +* how workflow tools such as Hatch can be useful when making code installable. + +**0-15 minutes:** Here we will get to know each other. I’ll also briefly introduce pyOpenSci and the work that we are doing in open science education and training space. + +**15-30 minutes:** Interactive discussion: Here, we’ll discuss why shareable code is important. And we’ll explore some best practices for making code easier to work with. I’ll also introduce Hatch as a workflow tool that streamlines tasks. + +**30-60 minutes, hands-on:** You will take an existing script and turn it into an installable module. You are welcome to use the provided scripts for this. If you are more comfortable with Python, then you can also bring your own script with you and work on it during the workshop. + + +### Hour Two: everything you need to know about the `pyproject.toml` file & project metadata. + +**0-15 minutes:** Interactive Discussion: Here you’ll learn about the pyproject.toml and how it’s used to document dependencies, and metadata for your project. + +**15-30 minutes:** Short Break. Stretch your legs, get a drink. + +**30-60 minutes, hands-on:** In the hands-on part of this hour, you will modify your pyproject.toml file with required dependencies needed to run your code. You will also learn how to install your code in interactive or development mode using both pip and Hatch. Interactive mode will allow you to dynamically update your code and test it locally without reinstalling it. Finally, you will take your shiny new Python module for a test drive in your favorite Python environment. + +### Hour Three: the power of metadata and instructions for you, your future self & your colleagues + +**0-15 minutes:** Interactive discussion: In this part of the tutorial we’ll discuss the power of documentation when sharing code and also for you when you have to update things in the future. ** + +**15-50 minutes, hands-on:** Here you will [create a README file](https://www.pyopensci.org/python-package-guide/tutorials/add-readme.html) that helps users of your module understand how to install it and how to get started using it. You will also add [docstrings](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html) to your code. See how docstrings are useful as “hints” when coding real time. Optional: if you are speedy, you can also delve into [typing](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html#adding-type-hints-to-your-docstrings) your code on your own. However, we won’t directly cover typing in this tutorial. + +**50-60 minutes:** Break + +### Hour Four: publishing and sharing your code + +**0-15 minutes:** Interactive discussion: Here we will discuss what it means to “[publish](https://www.pyopensci.org/python-package-guide/tutorials/publish-pypi.html)” code. We will also discuss other important elements such as license files and codes of conduct if you intend to turn your code into a published [package](https://www.pyopensci.org/python-package-guide/tutorials/intro.html). + +**15-45 minutes, hands-on:** Publishing to PyPI vs. installing from Github. Those who’d like to follow along interactively can do so here. However, if your brain is tired, sit back and learn how to build your module into a package distribution using Hatch. And then we will give you all of the tools needed to [publish to the test version of PyPI](https://www.pyopensci.org/python-package-guide/tutorials/publish-pypi.html). + +**45-60 minutes:** wrap up, questions. Feedback. ## Connect with pyOpenSci -Stay up-to-date with all things pyOpenSci by following us on [LinkedIn](https://linkedin.com/company/pyopensci -) and [Fosstodon](https://fosstodon.org/@pyOpenSci), and connect with the broader pyOpenSci community on our [Discourse forum](https://pyopensci.discourse.group/). If you’re interested in our weekly newsletter where we share news, blog posts, and monthly updates, [subscribe on LinkedIn](https://www.bit.ly/pyOSNewsletter). +Stay up-to-date with all things pyOpenSci by following us on [LinkedIn](https://linkedin.com/company/pyopensci) and [Fosstodon](https://fosstodon.org/@pyOpenSci), and connect with the broader pyOpenSci community on our [Discourse forum](https://pyopensci.discourse.group/). If you’re interested in our weekly newsletter where we share news, blog posts, and monthly updates, [subscribe on LinkedIn](https://www.bit.ly/pyOSNewsletter). From e8300412957f99a5e9139e0d257f7130be6521fa Mon Sep 17 00:00:00 2001 From: Jesse Mostipak Date: Tue, 25 Jun 2024 18:13:48 -0500 Subject: [PATCH 3/8] first draft completed --- ...reate-your-first-python-package-scipy-2024.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md index 49478c01..f54da6c1 100644 --- a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md +++ b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md @@ -51,7 +51,7 @@ You will leave this tutorial understanding how to: *If you don’t have homebrew* * Download a mamba installer and use bash to install mambaforge: * Download the installer: [Mambaforge installer for Mac](https://github.com/conda-forge/miniforge#mambaforge). - * Note that if you have a newer mac with a m1 or m2 chip, then you will want to install the Apple Silicon version: OS X arm64 (Apple Silicon) Mambaforge-MacOSX-arm64. If you have an older mac use: OS X x86_64 Mambaforge-MacOSX-x86_64 + * Note that if you have a newer mac with an M1 or M2 chip, then you will want to install the Apple Silicon version: OS X arm64 (Apple Silicon) Mambaforge-MacOSX-arm64. If you have an older mac use: OS X x86_64 Mambaforge-MacOSX-x86_64 * In your Terminal window, cd to the location of the download file. Run: `bash Mambaforge3-latest-MacOSX-modify-filename-here.sh` * Follow the prompts on the installer screens. * If you are unsure about any setting, accept the defaults. You can change them later. @@ -129,27 +129,27 @@ While you can update the `config.toml` file through the command line, it might b ### Hour One: the structure of an installable module **Key Takeaways: After this hour you will have an understanding of:** -* the purpose of the __init__.py file, and +* the purpose of the \_\_init\_\_.py file, and * how workflow tools such as Hatch can be useful when making code installable. **0-15 minutes:** Here we will get to know each other. I’ll also briefly introduce pyOpenSci and the work that we are doing in open science education and training space. -**15-30 minutes:** Interactive discussion: Here, we’ll discuss why shareable code is important. And we’ll explore some best practices for making code easier to work with. I’ll also introduce Hatch as a workflow tool that streamlines tasks. +**15-30 minutes, interactive discussion:** Here, we’ll discuss why shareable code is important. And we’ll explore some best practices for making code easier to work with. I’ll also introduce Hatch as a workflow tool that streamlines tasks. **30-60 minutes, hands-on:** You will take an existing script and turn it into an installable module. You are welcome to use the provided scripts for this. If you are more comfortable with Python, then you can also bring your own script with you and work on it during the workshop. ### Hour Two: everything you need to know about the `pyproject.toml` file & project metadata. -**0-15 minutes:** Interactive Discussion: Here you’ll learn about the pyproject.toml and how it’s used to document dependencies, and metadata for your project. +**0-15 minutes, interactive discussion:** Here you’ll learn about the pyproject.toml and how it’s used to document dependencies, and metadata for your project. -**15-30 minutes:** Short Break. Stretch your legs, get a drink. +**15-30 minutes:** A short break to stretch your legs and get a drink. **30-60 minutes, hands-on:** In the hands-on part of this hour, you will modify your pyproject.toml file with required dependencies needed to run your code. You will also learn how to install your code in interactive or development mode using both pip and Hatch. Interactive mode will allow you to dynamically update your code and test it locally without reinstalling it. Finally, you will take your shiny new Python module for a test drive in your favorite Python environment. ### Hour Three: the power of metadata and instructions for you, your future self & your colleagues -**0-15 minutes:** Interactive discussion: In this part of the tutorial we’ll discuss the power of documentation when sharing code and also for you when you have to update things in the future. ** +**0-15 minutes, interactive discussion:** In this part of the tutorial we’ll discuss the power of documentation when sharing code and also for you when you have to update things in the future. ** **15-50 minutes, hands-on:** Here you will [create a README file](https://www.pyopensci.org/python-package-guide/tutorials/add-readme.html) that helps users of your module understand how to install it and how to get started using it. You will also add [docstrings](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html) to your code. See how docstrings are useful as “hints” when coding real time. Optional: if you are speedy, you can also delve into [typing](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html#adding-type-hints-to-your-docstrings) your code on your own. However, we won’t directly cover typing in this tutorial. @@ -157,11 +157,11 @@ While you can update the `config.toml` file through the command line, it might b ### Hour Four: publishing and sharing your code -**0-15 minutes:** Interactive discussion: Here we will discuss what it means to “[publish](https://www.pyopensci.org/python-package-guide/tutorials/publish-pypi.html)” code. We will also discuss other important elements such as license files and codes of conduct if you intend to turn your code into a published [package](https://www.pyopensci.org/python-package-guide/tutorials/intro.html). +**0-15 minutes, interactive discussion:** Here we will discuss what it means to “[publish](https://www.pyopensci.org/python-package-guide/tutorials/publish-pypi.html)” code. We will also discuss other important elements such as license files and codes of conduct if you intend to turn your code into a published [package](https://www.pyopensci.org/python-package-guide/tutorials/intro.html). **15-45 minutes, hands-on:** Publishing to PyPI vs. installing from Github. Those who’d like to follow along interactively can do so here. However, if your brain is tired, sit back and learn how to build your module into a package distribution using Hatch. And then we will give you all of the tools needed to [publish to the test version of PyPI](https://www.pyopensci.org/python-package-guide/tutorials/publish-pypi.html). -**45-60 minutes:** wrap up, questions. Feedback. +**45-60 minutes:** wrap up, answer any questions, and provide feedback on the session. ## Connect with pyOpenSci From 20ce9cf63532ab37716ec649f0806df8a707a210 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:17:47 +0000 Subject: [PATCH 4/8] =?UTF-8?q?'[pre-commit.ci=20=F0=9F=A4=96]=20Apply=20c?= =?UTF-8?q?ode=20format=20tools=20to=20PR'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...25-create-your-first-python-package-scipy-2024.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md index f54da6c1..d809866f 100644 --- a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md +++ b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md @@ -18,8 +18,8 @@ comments: true ## Create Your First Python Package: Make Your Python Code Easier to Share and Use * **What:** A hands-on workshop, titled: [Create Your First Python Package: Make Your Python Code Easier to Share and Use](https://cfp.scipy.org/2024/talk/QT9GBY/) -* **Where:** [SciPy 2024](https://www.scipy2024.scipy.org/), Room 316 -* **When:** Tuesday, July 9th, 2024, from 13:30--17:30 Pacific +* **Where:** [SciPy 2024](https://www.scipy2024.scipy.org/), Room 316 +* **When:** Tuesday, July 9th, 2024, from 13:30--17:30 Pacific ## Event overview @@ -35,7 +35,7 @@ You will leave this tutorial understanding how to: * How to write functions in Python * How to use a Python environment manager of your choosing -## What you need installed +## What you need installed * Python * An environment manager * Hatch @@ -43,14 +43,14 @@ You will leave this tutorial understanding how to: ### Install Python using `conda` and the `conda-forge` channel *These instructions were adapted from the [Install Python Using Conda & Conda-forge - Mambaforge post](https://datascienceskills.org/install-python-science-conda/) from Leah Wasser and Jenny Palomino, originally posted on [datascienceskills.org](http://datascienceskills.org).* -#### For Mac users +#### For Mac users *For homebrew users* * Find directions for installing homebrew here. * If you have homebrew installed, then the easiest way to install mambaforge is to use: `brew install mambaforge` *If you don’t have homebrew* * Download a mamba installer and use bash to install mambaforge: - * Download the installer: [Mambaforge installer for Mac](https://github.com/conda-forge/miniforge#mambaforge). + * Download the installer: [Mambaforge installer for Mac](https://github.com/conda-forge/miniforge#mambaforge). * Note that if you have a newer mac with an M1 or M2 chip, then you will want to install the Apple Silicon version: OS X arm64 (Apple Silicon) Mambaforge-MacOSX-arm64. If you have an older mac use: OS X x86_64 Mambaforge-MacOSX-x86_64 * In your Terminal window, cd to the location of the download file. Run: `bash Mambaforge3-latest-MacOSX-modify-filename-here.sh` * Follow the prompts on the installer screens. @@ -110,7 +110,7 @@ Once you have installed Hatch, you will want to customize the configuration. Hat While you can update the `config.toml` file through the command line, it might be easier to look at it and update it in a text editor if you are using it for the first time. 1. Open and edit your `config.toml` file by either: - * Running `hatch config explore` in your shell, which will open up a directory window that will allow you to double click on the file and open it in your favorite text editor. + * Running `hatch config explore` in your shell, which will open up a directory window that will allow you to double click on the file and open it in your favorite text editor. * Alternatively, you can retrieve the location of the Hatch config file by running `hatch config find` in your shell. 2. Update your email and name * Once the file is open, update the \[template\] table of the `config.toml` file with your name and email. This information will be used in any `pyproject.toml` metadata files that you create using Hatch. From c75ba267508ed1be27e9aa95cb33ea1efeafce3c Mon Sep 17 00:00:00 2001 From: Jesse Mostipak Date: Sat, 29 Jun 2024 17:27:13 -0500 Subject: [PATCH 5/8] added in notes from @lwasser --- ...te-your-first-python-package-scipy-2024.md | 290 ++++++++++++------ .../june => headers}/scipy-2024-workshop.png | Bin 2 files changed, 198 insertions(+), 92 deletions(-) rename images/{blog/2024/june => headers}/scipy-2024-workshop.png (100%) diff --git a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md index d809866f..77f2d884 100644 --- a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md +++ b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md @@ -6,11 +6,12 @@ excerpt: "pyOpenSci will be running our `Create Your First Python Package: Make author: "Jesse Mostipak" permalink: /blog/pyos-workshop-scipy-2024.html header: - overlay_image: images/blog/2024/june/scipy-2024-workshop.png + overlay_image: images/headers/scipy-2024-workshop.png overlay_filter: rgba(20, 13, 36, 0.8) categories: - blog-post - community + - events classes: wide toc: true comments: true @@ -20,6 +21,8 @@ comments: true * **What:** A hands-on workshop, titled: [Create Your First Python Package: Make Your Python Code Easier to Share and Use](https://cfp.scipy.org/2024/talk/QT9GBY/) * **Where:** [SciPy 2024](https://www.scipy2024.scipy.org/), Room 316 * **When:** Tuesday, July 9th, 2024, from 13:30--17:30 Pacific +* **Workshop GitHub repository:** [https://github.com/pyOpenSci/code-to-module-workshop/](https://github.com/pyOpenSci/code-to-module-workshop/) +* **pyOpenSci demo package:** [https://github.com/pyOpenSci/pyosPackage](https://github.com/pyOpenSci/pyosPackage) ## Event overview @@ -40,128 +43,231 @@ You will leave this tutorial understanding how to: * An environment manager * Hatch -### Install Python using `conda` and the `conda-forge` channel -*These instructions were adapted from the [Install Python Using Conda & Conda-forge - Mambaforge post](https://datascienceskills.org/install-python-science-conda/) from Leah Wasser and Jenny Palomino, originally posted on [datascienceskills.org](http://datascienceskills.org).* - -#### For Mac users -*For homebrew users* -* Find directions for installing homebrew here. -* If you have homebrew installed, then the easiest way to install mambaforge is to use: `brew install mambaforge` - -*If you don’t have homebrew* -* Download a mamba installer and use bash to install mambaforge: - * Download the installer: [Mambaforge installer for Mac](https://github.com/conda-forge/miniforge#mambaforge). - * Note that if you have a newer mac with an M1 or M2 chip, then you will want to install the Apple Silicon version: OS X arm64 (Apple Silicon) Mambaforge-MacOSX-arm64. If you have an older mac use: OS X x86_64 Mambaforge-MacOSX-x86_64 -* In your Terminal window, cd to the location of the download file. Run: `bash Mambaforge3-latest-MacOSX-modify-filename-here.sh` -* Follow the prompts on the installer screens. -* If you are unsure about any setting, accept the defaults. You can change them later. -* To make sure that the changes take effect, close and then re-open your Terminal window. - -#### For Linux users -* Download the installer: [Mambaforge installer for Linux](https://github.com/conda-forge/miniforge#mambaforge). -In your Terminal window, run making sure to modify the file name to match the file that you downloaded: `bash Mambaforge3-latest-Linux-modify-file-name-here.sh` -* Follow the prompts on the installer screens. -* If you are unsure about any setting, accept the defaults. You can change them later. -* To make sure that the changes take effect, close and then re-open your Terminal window. - -#### For Windows users -Download the [Mambaforge installer for Windows](https://github.com/conda-forge/miniforge#mambaforge) and run the installer by double-clicking on the downloaded file. Then follow the steps below: -* Click “Run”. -* Click on “Next”. -* Click on “I agree”. -* Leave the selection on “Just me” and click on “Next”. -* Click on “Next”. -* **Select the first option for “Add Anaconda to my PATH environment variable”** and also **leave the selection on “Register Anaconda as my default Python 3.x”**. Click on “Install”. - * Note that even though the installation is for Mambaforge, the installer uses the word Anaconda in these options. - * You will also see a message in red text that selecting “Add Anaconda to my PATH environment variable” is not recommended; continue with this selection to make using conda easier in Git Bash. If you have questions or concerns, please contact your instructor. -* When the install is complete, Click on “Next”. -* Click on “Finish”. - -#### Test that the installation was successful (all systems) -* Search for and open the Terminal program (found in /Applications/Utilities). In this `Terminal` window, type `bash` and hit enter. If you do not get a message back, then `Bash` is available for use. -* Next, type `git` and hit enter. If you see a list of commands that you can execute, then `Git` has been installed correctly. -* Next, type `conda` and hit enter. Again, if you see a list of commands that you can execute, then Mambaforge `Python` has been installed correctly. -* Close the `Terminal` by typing `exit`. - -### Install Hatch -*These instructions were adapted from the [Introduction to Hatch](https://www.pyopensci.org/python-package-guide/tutorials/get-to-know-hatch.html) section of the [pyOpenSci Python Packaging Guide](https://www.pyopensci.org/python-package-guide/).* - -#### For Mac users -*These instructions are for installing Hatch using the GUI installer. If you’d prefer to use the Command line installer, please see the [Hatch documentation](https://hatch.pypa.io/latest/install/.#command-line-installer).* +## Workshop agenda + + + + + + + + + + + + + + + + + + + + +
Hour one: The structure of an installable module.
Key takeaways
    +
  • The purpose of the __init__.py file
  • +
  • How workflow tools such as Hatch can be useful when making code installable.
  • +
Breakdown
0-15 minutes: Here we will get to know each other. I’ll also briefly introduce pyOpenSci and the work that we are doing in open science education and training space.
15-30 minutes, interactive discussion: Here, we’ll discuss why shareable code is important. And we’ll explore some best practices for making code easier to work with. I’ll also introduce Hatch as a workflow tool that streamlines tasks.
30-60 minutes, hands-on: You will take an existing script and turn it into an installable module. You are welcome to use the provided scripts for this. If you are more comfortable with Python, then you can also bring your own script with you and work on it during the workshop.
+
+ + + + + + + + + + + + + + + + + +
Hour two: Everything you need to know about the pyproject.toml file & project metadata.
Breakdown
0-15 minutes, interactive discussion: Here you’ll learn about the pyproject.toml and how it’s used to document dependencies, and metadata for your project.
15-30 minutes: A short break to stretch your legs and get a drink.
30-60 minutes, hands-on: In the hands-on part of this hour, you will modify your pyproject.toml file with required dependencies needed to run your code. You will also learn how to install your code in interactive or development mode using both pip and Hatch. Interactive mode will allow you to dynamically update your code and test it locally without reinstalling it. Finally, you will take your shiny new Python module for a test drive in your favorite Python environment.
+
+ + + + + + + + + + + + + + + + + +
Hour three: The power of metadata and instructions for you, your future self & your colleagues.
Breakdown
0-15 minutes, interactive discussion: In this part of the tutorial we’ll discuss the power of documentation when sharing code and also for you when you have to update things in the future.
15-50 minutes, hands-on: Here you will create a README file that helps users of your module understand how to install it and how to get started using it. You will also add docstrings to your code. See how docstrings are useful as “hints” when coding real time. Optional: if you are speedy, you can also delve into typing your code on your own. However, we won’t directly cover typing in this tutorial.
50-60 minutes: Break
+
+ + + + + + + + + + + + + + + + + +
Hour four: Publishing and sharing your code.
Breakdown
0-15 minutes, interactive discussion: Here we will discuss what it means to “publish” code. We will also discuss other important elements such as license files and codes of conduct if you intend to turn your code into a published package.
15-45 minutes, hands-on: Publishing to PyPI vs. installing from Github. Those who’d like to follow along interactively can do so here. However, if your brain is tired, sit back and learn how to build your module into a package distribution using Hatch. And then we will give you all of the tools needed to publish to the test version of PyPI.
45-60 minutes: Wrap up, answer any questions, and provide feedback on the session.
+ +## Hatch & Python + +If you already have a working version of Python on your computer, then you are in good shape!**If you don’t have Python installed on your computer, then Hatch will install Python for you when you install it following the instructions below.** + +## Install Hatch + +_These instructions were adapted from the [Introduction to hatch](https://www.pyopensci.org/python-package-guide/tutorials/get-to-know-hatch.html) section of the [pyOpenSci Python Packaging Guide](https://www.pyopensci.org/python-package-guide/)._ + +### For Mac users + +_These instructions are for installing Hatch using the GUI installer. If you’d prefer to use the Command line installer, please see the [Hatch documentation](https://hatch.pypa.io/latest/install/#command-line-installer)._ + 1. In your browser, download the `.pkg` file: [hatch-universal.pkg](https://github.com/pypa/hatch/releases/latest/download/hatch-universal.pkg) -2. Run your downloaded file and follow the on-screen instructions. -3. Restart your terminal. -4. To verify that the shell can find and run the hatch command in your `PATH`, run `hatch --version` in your Terminal. +2. Run the downloaded file and follow the on-screen instructions to install Hatch. +3. Restart your terminal if it is already open. +4. To verify that shell can find and run the `hatch` command, run: + 1. `hatch --version` (in your Terminal / shell). + +### For Linux users + +_For linux users, the easiest way to install Hatch is to use pipx which can be installed using apt install. Note: if you prefer to use a tool other than pipx, please refer to the [Hatch documentation](https://hatch.pypa.io/latest/) for more information_ -#### For Linux users -*Note: if you prefer to use a tool other than pipx, please refer to the [Hatch documentation](https://hatch.pypa.io/latest/) for more information.* -* Install hatch from the command line using pipx: `pip install hatch` +* Install hatch from the command line using [pipx](https://pipx.pypa.io/stable/): -#### For Windows users -*These instructions are for installing Hatch using the GUI installer. If you’d prefer to use the Command line installer, please see the [Hatch documentation](https://hatch.pypa.io/latest/install/#command-line-installer_1).* -1. In your browser, download the `.msi` file: [hatch-x64.msi](https://github.com/pypa/hatch/releases/latest/download/hatch-x64.msi). +```bash +# First install pipx using apt install +>> apt install pipx +# Then use pipx to install hatch +>> pipx install hatch +``` + +### For Windows users + +_These instructions are for installing Hatch using the GUI installer. If you’d prefer to use the Command line installer, please see the [Hatch documentation](https://hatch.pypa.io/latest/install/#command-line-installer_1)._ + +1. In your browser, download the `.msi` file: [hatch-x64.msi](https://github.com/pypa/hatch/releases/latest/download/hatch-x64.msi) 2. Run your downloaded file and follow the on-screen instructions. -3. Restart your terminal. -4. To verify that the shell can find and run the hatch command in your `PATH`, run `hatch --version` in your Terminal. +3. Restart your terminal if it was already open. +4. To verify that the shell can find and run the `hatch` command in your `PATH`, in your terminal run: + 1. `hatch --version` ### Configure Hatch (all systems) -Once you have installed Hatch, you will want to customize the configuration. Hatch stores your configuration information in a `config.toml` file. -While you can update the `config.toml` file through the command line, it might be easier to look at it and update it in a text editor if you are using it for the first time. +After installing Hatch, it’s useful to customize the Hatch configuration. The +configuration allows you to specify things like the default name and email to +use in your package’s metadata. If you don’t configure Hatch, you can always +edit files later! However your Hatch package outputs might look a bit different +than the ones in the workshop. (This is ok!) + +Hatch stores your configuration information in a `config.toml` file. + +While you can update the `config.toml` file through the command line, it might +be easier to look at it and update it in a text editor if you are using it for +the first time. 1. Open and edit your `config.toml` file by either: - * Running `hatch config explore` in your shell, which will open up a directory window that will allow you to double click on the file and open it in your favorite text editor. - * Alternatively, you can retrieve the location of the Hatch config file by running `hatch config find` in your shell. + 1. Running `hatch config explore` in your shell, which will open up a directory window that will allow you to double click on the file and open it in your favorite text editor. + 2. Alternatively, you can retrieve the location of the Hatch config file by running `hatch config find` in your shell. 2. Update your email and name - * Once the file is open, update the \[template\] table of the `config.toml` file with your name and email. This information will be used in any `pyproject.toml` metadata files that you create using Hatch. + 3. Once the file is open, update the [template] table of the `config.toml` file with your name and email. This information will be used in any `pyproject.toml` metadata files that you create using Hatch. 3. Set tests to `false` -*While tests are important, setting the tests configuration in Hatch to true will create a more complex pyproject.toml file. You won’t need to use this feature in this beginner friendly tutorial series but we will introduce it in later tutorials.* - * Set tests to `false` in the `[template.plugins.default]` table. -4. Close the config file and `run hatch config show` -`hatch config show` will print out the contents of your config.toml file in your shell. Look at the values and ensure that your name and email are set, and also make sure that `tests=false`. -## Helpful links -* Our [example Python package repo, `pyosPackage`](https://github.com/pyOpenSci/pyosPackage), that goes along with pyOpenSci tutorials. -* [Workshop information on the SciPy 2024 website](https://cfp.scipy.org/2024/talk/QT9GBY/). + _While tests are important, setting the tests configuration in Hatch to true will create a more complex pyproject.toml file. We won’t be creating tests in this workshop._ -## Workshop agenda + Set tests to `false` in the `[template.plugins.default]` table. + +Your config file should look something like this: -### Hour One: the structure of an installable module +```toml +mode = "local" +project = "" +shell = "" -**Key Takeaways: After this hour you will have an understanding of:** -* the purpose of the \_\_init\_\_.py file, and -* how workflow tools such as Hatch can be useful when making code installable. +[dirs] +project = [] +python = "isolated" +data = "/Users/leahawasser/Library/Application Support/hatch" +cache = "/Users/leahawasser/Library/Caches/hatch" -**0-15 minutes:** Here we will get to know each other. I’ll also briefly introduce pyOpenSci and the work that we are doing in open science education and training space. +[dirs.env] -**15-30 minutes, interactive discussion:** Here, we’ll discuss why shareable code is important. And we’ll explore some best practices for making code easier to work with. I’ll also introduce Hatch as a workflow tool that streamlines tasks. +[projects] -**30-60 minutes, hands-on:** You will take an existing script and turn it into an installable module. You are welcome to use the provided scripts for this. If you are more comfortable with Python, then you can also bring your own script with you and work on it during the workshop. +[publish.index] +repo = "main" +[template] +name = "Leah Wasser" +email = "leah@pyopensci.org" -### Hour Two: everything you need to know about the `pyproject.toml` file & project metadata. +[template.licenses] +headers = true +default = [ + "MIT", +] -**0-15 minutes, interactive discussion:** Here you’ll learn about the pyproject.toml and how it’s used to document dependencies, and metadata for your project. +[template.plugins.default] +tests = false +ci = false +src-layout = true -**15-30 minutes:** A short break to stretch your legs and get a drink. +[terminal.styles] +info = "bold" +success = "bold cyan" +error = "bold red" +warning = "bold yellow" +waiting = "bold magenta" +debug = "bold" +spinner = "simpleDotsScrolling" +``` -**30-60 minutes, hands-on:** In the hands-on part of this hour, you will modify your pyproject.toml file with required dependencies needed to run your code. You will also learn how to install your code in interactive or development mode using both pip and Hatch. Interactive mode will allow you to dynamically update your code and test it locally without reinstalling it. Finally, you will take your shiny new Python module for a test drive in your favorite Python environment. +Note: for future packages you may want to enable both CI and tests. This +configuration is to simplify things for our beginner-friendly tutorial. -### Hour Three: the power of metadata and instructions for you, your future self & your colleagues +4. Close the config file and run `hatch config show` -**0-15 minutes, interactive discussion:** In this part of the tutorial we’ll discuss the power of documentation when sharing code and also for you when you have to update things in the future. ** + `hatch config show` -**15-50 minutes, hands-on:** Here you will [create a README file](https://www.pyopensci.org/python-package-guide/tutorials/add-readme.html) that helps users of your module understand how to install it and how to get started using it. You will also add [docstrings](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html) to your code. See how docstrings are useful as “hints” when coding real time. Optional: if you are speedy, you can also delve into [typing](https://www.pyopensci.org/python-package-guide/documentation/write-user-documentation/document-your-code-api-docstrings.html#adding-type-hints-to-your-docstrings) your code on your own. However, we won’t directly cover typing in this tutorial. +This command prints out the contents of your config.toml file in your shell. +Look at the values and ensure that your name and email are set and also make +sure that `tests=false`. -**50-60 minutes:** Break +## Useful Commands -### Hour Four: publishing and sharing your code +### Conda environments -**0-15 minutes, interactive discussion:** Here we will discuss what it means to “[publish](https://www.pyopensci.org/python-package-guide/tutorials/publish-pypi.html)” code. We will also discuss other important elements such as license files and codes of conduct if you intend to turn your code into a published [package](https://www.pyopensci.org/python-package-guide/tutorials/intro.html). +* **Create environment:** `conda create -n env_name python=3.11` +* **Activate environment:** `conda activate env_name` +* **Leave environment:** `conda deactivate` -**15-45 minutes, hands-on:** Publishing to PyPI vs. installing from Github. Those who’d like to follow along interactively can do so here. However, if your brain is tired, sit back and learn how to build your module into a package distribution using Hatch. And then we will give you all of the tools needed to [publish to the test version of PyPI](https://www.pyopensci.org/python-package-guide/tutorials/publish-pypi.html). +### Venv environments -**45-60 minutes:** wrap up, answer any questions, and provide feedback on the session. +Create environment + +* `python -m venv env_name` +* Activate_windows: `env_name\Scripts\activate` +* Activate MAC / LINUX: `source env_name/bin/activate` +* Leave environment: `deactivate` + +## Helpful links +* Our [example Python package repo, `pyosPackage`](https://github.com/pyOpenSci/pyosPackage), that goes along with pyOpenSci tutorials. +* [Workshop information on the SciPy 2024 website](https://cfp.scipy.org/2024/talk/QT9GBY/). ## Connect with pyOpenSci diff --git a/images/blog/2024/june/scipy-2024-workshop.png b/images/headers/scipy-2024-workshop.png similarity index 100% rename from images/blog/2024/june/scipy-2024-workshop.png rename to images/headers/scipy-2024-workshop.png From 90abb25d3aeff13014d83e360470c187b70f9d28 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 22:30:40 +0000 Subject: [PATCH 6/8] =?UTF-8?q?'[pre-commit.ci=20=F0=9F=A4=96]=20Apply=20c?= =?UTF-8?q?ode=20format=20tools=20to=20PR'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2024-06-25-create-your-first-python-package-scipy-2024.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md index 77f2d884..a98f85a5 100644 --- a/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md +++ b/_posts/2024-06-25-create-your-first-python-package-scipy-2024.md @@ -148,7 +148,7 @@ _These instructions are for installing Hatch using the GUI installer. If you’d _For linux users, the easiest way to install Hatch is to use pipx which can be installed using apt install. Note: if you prefer to use a tool other than pipx, please refer to the [Hatch documentation](https://hatch.pypa.io/latest/) for more information_ -* Install hatch from the command line using [pipx](https://pipx.pypa.io/stable/): +* Install hatch from the command line using [pipx](https://pipx.pypa.io/stable/): ```bash # First install pipx using apt install From 050566feadf5d8e094e525044ee46cc7338fd919 Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Thu, 25 Jul 2024 16:24:16 -0600 Subject: [PATCH 7/8] feat(css): update styles to unstick search bar and align ol --- _sass/minimal-mistakes/_pyos-dropdown.scss | 4 ++-- _sass/minimal-mistakes/_pyos-main.scss | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_sass/minimal-mistakes/_pyos-dropdown.scss b/_sass/minimal-mistakes/_pyos-dropdown.scss index 278b71fe..9fb94a75 100644 --- a/_sass/minimal-mistakes/_pyos-dropdown.scss +++ b/_sass/minimal-mistakes/_pyos-dropdown.scss @@ -349,8 +349,8 @@ drop shadow /* Positioned by burger TODO: might be better within the drop down??*/ .search__toggle { - position: fixed; - right: 20%; + position: absolute; + right: -6%; font-size: 1.4em; top: 3%; } diff --git a/_sass/minimal-mistakes/_pyos-main.scss b/_sass/minimal-mistakes/_pyos-main.scss index a39f0174..72ae9f26 100644 --- a/_sass/minimal-mistakes/_pyos-main.scss +++ b/_sass/minimal-mistakes/_pyos-main.scss @@ -188,7 +188,7 @@ h2.clearall { max-width: 90%!important; } ol { - font-size: 1.3em; + font-size: 1em; } } From fc0e12f1ae40ad5eaafe0813e526624e60a890a8 Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Thu, 25 Jul 2024 16:26:17 -0600 Subject: [PATCH 8/8] fix(blog): add youtube video of talk --- _posts/2024-05-30-pyos-pyconus-2024-recap.md | 26 +++++++------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/_posts/2024-05-30-pyos-pyconus-2024-recap.md b/_posts/2024-05-30-pyos-pyconus-2024-recap.md index dbfc28cb..a9aa29d9 100644 --- a/_posts/2024-05-30-pyos-pyconus-2024-recap.md +++ b/_posts/2024-05-30-pyos-pyconus-2024-recap.md @@ -21,15 +21,14 @@ comments: true * fix captions * add stravalib note at the end of my talk section --> -

## TL;DR * pyOpenSci had a strong presence at [PyCon US](https://us.pycon.org/2024/) this year. I hope this continues for years to come! We held an open space, helped run the [Maintainers Summit](https://us.pycon.org/2024/events/maintainers-summit/) (lead by [Inessa Pawson](https://github.com/InessaPawson) for 5 years and counting), gave [a talk on Python packaging](https://us.pycon.org/2024/schedule/presentation/34/) and ran a 1 day sprint where over 16 people contributed to our efforts. * pyOpenSci’s theme this year for PyConUS was people first: people first when trying to make technical concepts easier to understand, people first when trying to write good tutorials or documentation and people first when you are trying to solve the world’s hardest problems. * Giving a talk on packaging at pyConUS triggered every ounce of the imposter in me. But in the end it was a rewarding experience. Having friends in the audience made a world of difference. It was calming to focus on people who I know support both me and this vibrant organization. Friends really should never let friends…package…or use Python…or do anything technical…alone. -
+ ## Another year, another incredible PyCon @@ -42,7 +41,6 @@ PyCon US, run by the [Python Software Foundation,](https://www.python.org/psf-landing/) is one of the biggest Python meetings in the world, with a record 2,700 registrations this year. {: .notice } - I also knew that I'd get to see a bunch of the friends who I met last year. I was returning to this inclusive community, filled with Pythonistas like me who care, who want to learn, and most importantly who want to help each other. @@ -73,7 +71,6 @@ projects and organizations and our sprints were awesome with many new contributi My takeaway: if you are considering going to PyCon but are worried about not knowing people YOU SHOULD STILL GO! You can feel the true spirit of open source (and open science) at PyCon US. No judgement. All "levels" of Pythonistas welcome. - ## My first main track PyCon US talk: Friends don't let friends package alone This year, I gave my first main track talk at PyCon, titled “Friends Don’t Let @@ -81,19 +78,23 @@ Friends Package Alone.” Getting a main track slot means presenting on a big stage to a huge room of people! It was real - headset mic, incredible tech support, and even an “escort” from the speaker room to the main stage. Wow! +You can check it out on youtube below: + +{% include video id="mJPoj9Ex9fk" provider="youtube" %} + Speaking of friends, it was my friends who got me through this talk. I saw them sitting in the front rows, smiling and supporting me. They both empowered me and gave me calm. As someone who often battles imposter syndrome, giving a talk on the "big" stage of a tech meeting was unforgettable. -
Image of a woman on a big stage wearing a red tank top talking. On the side is a slide that says pyOpenSci - Save the Date. Open science fall festival september 28-29 2024
Me talking on the stage! I was so nervous before but once I got up there, everything calmed in my mind. .
### A talk about making Python packaging more beginner friendly + My talk focused on how pyOpenSci helps beginners by breaking down complex packaging concepts into simple, digestible pieces. I leaned into decades of experience and study of teaching data science to various audiences, from big-ten university students @@ -110,22 +111,17 @@ fundamental concepts, and * avoid “Too Many Options and Opinions” (TMO) to keep things simple for beginners. - -
A cute image of a black flat coated retriever laying on the floor with a purple ice pack on it's head looking right at you.
Whether it's too many options or too many opinions, TMO will push beginner users away. Too many options create cognitive load that prevent users from having successful experiences.
- Giving a talk at PyConUS experience reinforced my belief in the power of community to tackle complex problems and support each other in our scientific journeys. - - - ## The PyCon US maintainers Summit This year, I had the honor of helping [Inessa Pawson](https://github.com/InessaPawson) and [Kara Sowles](https://github.com/karasowles) organize the @@ -160,7 +155,6 @@ quickly and a waitlist, the event was a success. Next year (if we are invited ba {% include video id="L-Ok_89QJOM" provider="youtube" %} - Also if you were wondering, yes that Monstera Deliciosa (plant) in the background is real! AND YES it is ginormous! ## Our second pyOpenSci sprint @@ -173,11 +167,9 @@ This year we had a tremendous turnout of over 20 people from several countries f
The pyConUS sprint sign-up board had lots of projects. Because the rooms are large, projects tend to share spaces. We ended up in the packaging room which was great as it allowed us to do some more difficult work around Python packages with C extensions!
- - If you haven’t been to a sprint before, it’s an experience that every open source enthusiast should have. Sprints are where a bunch of people come together to work on a project. If you are running sprints that support software development in a professional environment (i.e. at a company) this might mean a team of people working together on releasing a new software feature. But for the open source community, sprints can also mean volunteers coming to a space to help maintainers work on various parts of a project that they care about - like pyOpenSci! -pyOpenSci supports other people's software through it's [open community-lead peer review process ](https://www.pyopensci.org/about-peer-review/index.html) and it's online, free [packaging resources](https://www.pyopensci.org/python-package-guide/). But it also has it's own software too. We have tools that help us keep track of our review process and volunteer contributions so we can acknowledge everyone for their effort. +pyOpenSci supports other people's software through it's [open community-lead peer review process](https://www.pyopensci.org/about-peer-review/index.html) and it's online, free [packaging resources](https://www.pyopensci.org/python-package-guide/). But it also has it's own software too. We have tools that help us keep track of our review process and volunteer contributions so we can acknowledge everyone for their effort. Acknowledging contributions is so so so (did I mention SO?) important. And we value them so much. @@ -225,8 +217,8 @@ workflows that allow allowing scientists to focus on their research rather than tools. We plan to tackle some of these and other topics during our Fall festival on September 28-29, 2024 so save the date and come ready to learn and share! - ## Packaging summit + Last but not least, pyOpenSci had a strong presence at the PyConUS packaging summit this year. The summit was organization by [Pradyun Gedam](https://github.com/pradyunsg), [Jannis Leidel](https://github.com/jezdez), [CAM Gerlach](https://github.com/CAM-Gerlach), [Filipe Laínes](https://github.com/FFY00). As I have mentioned several times, packaging is one of the more thorny topics in our Python ecosystem. However, this year, things felt different compared to last. For one, there were a lot more people in the room, and people with different perspectives. For starters, last year I was 1 of 3? female-identifying people in the room - this year there were people from many backgrounds and identities in the room! Last year also felt more technical whereas this year was a perfect mix of discussing technical topics combined with a strong theme of considering user experience in both installing Python and creating packages. PLUS - documentation - yes PLEASE! @@ -237,7 +229,7 @@ I'm hopeful. From my perspective, the biggest challenges in our ecosystem revolve around: -* too much focus on tools and not enough focus on user experience and documentation, and +* too much focus on tools and not enough focus on user experience and documentation, and * too many options and opinions that prevent users from have early success. There is a path forward. And people who are working on tools in the ecosystem really do care -- a lot. So please thank them - thank the maintainers and people who work on the tools that you use - or might use in the future. It's all volunteer time.