From aa2552629e1e83566901873797cb0086e30a04e4 Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Tue, 20 Jan 2015 11:45:56 -0300 Subject: [PATCH 1/9] Add integration test with network data --- test/connection.log | Bin 0 -> 77283 bytes test/peer.js | 55 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 test/connection.log diff --git a/test/connection.log b/test/connection.log new file mode 100644 index 0000000000000000000000000000000000000000..6455cccdcb7cd19e2e6700c5613f2f0dfb422d5a GIT binary patch literal 77283 zcmaHU2VBl?_kTl1_Pz;yj56YmD1-t>dT<5&c`<&~#zvrh_MU0;|ebSULh1!3{<9`{U zjTcU9t*D^*um7T;U>TGztNquy|Nnpg8Gp#-`K|V7{h38cRGK*V5XAe}JNQrP`e9Q` zZKrWFrc4i-q(4wPTslbGSX)Iw@%z6&J}zML-!8qs+<#d6-zSAd{O3Pv;NKQRTpXxa z`yH=YrEi<`PAE7u`|O@&8oNTI;tY)<#p|;s1REMyHoNzUYHZ@$Ytp|OCpEJQ)Xo_$ zS=L5rgZjv%F)k9v7|Go2cRL+vwt9-{v4ORX#{~vXtNZlenFHj zo+)JyE(xN`!#q-I+upI6AS#db%Ll;3j+JcsP-t0715PkJ& zX{c$l&4ReEkp8Z#S?5NAxbqk-4b)Un6~xhxX{mSoyHkRAq6__9_wtr~1uD7WUKLpXQjFu*uteGo_`vv;D zKH=@&U{u}cwvLBlRtcg}Yr1VkP}Vp>+@Um=TxYXS86kq$zaQOpRi!pg%DKL@G~_~> znIIO%(W5f^JoA|#-fc&>4K!?v`L@)frLN<4N(FKK4Z7#3^95T4af~_LR&DV;oWVdZ zx~C%UC{pa;IIp+%1>&@|?gAa>f2@h?v! zmz%#{Ef>VtX7&H}4|lrf(f4Grg80j#{@<-L;Bxu;tgI%2*k};lcI<&Mezm8Jmio16 zc2^Le<%N;+wa)N>hikx`6!$+>&0)}UL3?mge$dicojdsp;=_^jcXbr!-xkCR%nsV=hBp?(xiNIl zCqm-7!PYgPd$w%+0QPF7HLX{r3$*VGqR#`m=Rjo@nIHx?q=}tD+N)mNw;-K zPS+R2erM^nR{d`P$s8X`w+&qv{ZJ4;F@C|zs_}I}^q10YT^0M>z)C(1AonQ3E#bHz z+Dp=$sAxjz`K3|NSZ2(!VUH!SW@A>9JsWv_-z|u@D>jnSk)JYw7;Qh(tC6X2A9mx~ zAbLg)@jmd~>lk|#WN@Sl#%xIUtRszYFNh9bY3a0Ot1+W{J!q+Pe`$&9lR1n(GHWX< z5X2M)=Qy3{01G@&qu;8bCKyEFSuyK1)_FVKcAa(R5J9y3PD=xf1Aub% zb?VSpRn($2uoTtx|Mv8M{J+0eR64?5OAw>))&IMHrM_-^@m*miEj2$AVJ(P1nAq7X zw9O+}{;wlReRjOy6%2hoLHFFOw8u9=RA;QWo8^jTf>=6_ZhPCN5`OT;8#*p?Dy?WL zh9MkVf@ z*|Xp2&VqP|;msy@Fo4Y|VtiRhD|J}lSJ$_Y`fQgn75qkDW=0l+%tK)}7^#hZA9z@+ z&h(h$FW*=whzktpb(RF|D8h^wd{w#4eFNgq<=Nzz)w?_ZR#}%zqfK+2-l~ZByy;Qd z_-UC5qD^mlRH2srdZFjxw6r2&2k`T8CbAZn4}s>aVS2XA8UfU|meF=u-f65x9P{1k zw+nv5GMLi{D*a$voY2P;==rJ)2pl1ZW5a1_RqR9{M#mwvG&dw}7?=|?dNnNDUItd# z!0fNn$Vp!j9Wxlo%D)D&)voSz&(7AU%xvBf~ZqPuZHd9*XPmmDSxu9;XOa#4dV>D?bu{94?$GgKugsZOTf2> z_oU}r?z{o|yqeLvQU?`81d0rcD4lc-tKqhV#tdewT>=DgBx8~6cFP_hI*z5sJSDR` zJnT~@dNNfQW+RBF7#wRp^+_4dzD6dwl2u=fu}A4m>DB1u@f?xJr3>_^3Lne_zAElO zOQnyF;v6-%qpU$nq{8N4y?$o6~C zI&=EFsfoLsfhRR-sntA#2|(gAXsOwlXD)&mIf|A_My-NvuUNK@Tn*{-0f;fUf zBR z)Y{-KG%)SI^Qyat((_Gte%KG*s_|dx|BdKVlR;$9NnI`4f_3RVj+FX_KLe9re58*3$Wvj1?ZA&K{Mod=|NlV?! zze3vsJZS`F`(eT=;Hzhw$Q=x|@sY$o$Y&GgtMZISs~BV&V~L_E4cunf-SkD?z-NPmkFx z&%PxzCx@2Kx2b_Od(GrS&7uwh4fAMyGYg8*SnJMQNA;6QHn3@Fjwl`s~S}}Pmx9s_d>3%S=m1V099l*FU zRy4rkf`cID7}M))-qIaxKoY|u7QFKVn|GM;R-rCiuYkQ|ywxm+_5QF||3Lu%wBDh= z3=oNUPo+oIQGO`|RV9;YskHq)V8Wm#wAPJDi1rl3w&&@#=8DfN5%HPOZGHNl1o|pw zVhziLQ+tp*W)Ndlv-801e>%}U=c~s9U7s6BOHDU6$wU1{XIh%;V15!lg+b;vFZ#p@ z;;^)ZIn*zkhc;^-g(d&`dV6p&u4|-xo@r>4)xJLdG#LLg}&hWkohvlP*UJ;NafU5%N5-Dfai@~SsKfS`KP`@6n)JbdV{g3YAnc;2{x zwx#KGTUWgy@a(EPXsOb-epRSAV)V-U$l`5?Qvautv)1;=<%I2+Rbz26S($8dVgCJm!Y;D4Fy;k=A>>jZHqvq!SBu<6J=h9{9LX>TwC z`W(+7nS?UsiGui7QjwoB`8UPCT7OLXfah}r+J zn|GKRSBpXy?C-r<%y&b>69jR3IV}|xCf*Q4y{*dRsJx$9z^YhwqTA*M+%iE7%V0BW z>q+1z)i%;?bylqXDTpP8^zM7#J}?kW5mTQtX8Ogif;f@!`;wF@7mgY9RinUtqN=vIE?Ux`6 zz|yQ|4FiE$LQu*=K)M+ z%I(C2Ca4!>Dnks@OyKt&zR;tpnlT*yD3gh-H#PqW`9B6&(%Ah$9m`yeZRvJx3Frme{ftrddUk;&s&w{HetR-#?Y*!X&nh2}r&{ok>} zo(g(33|G&GxAJG=?htEpjB1@S-8S*hAX7n{5}81*hRr!m;ODS?bPOv!5R7rg+a4p^ zx`gY>1hJ=-{;rv!!zkd%ku;yR9I56>MHVZ*oS`U0$DYy64m}atUQ&w_vXe zYHJbd{#hug|NrX#t6c7$q~22yXNJ-%>Ak}qai|WX8vz@gBT>J>SO$ZBjT#8zq&;-c z1$U#~p)NO&KB1xeWs`9Cf!SZpNtLQ#^J3_p^?uIA?Dd#2JG6~xBZwhPt+-SA2%H7$ zlXQKoG@}Z7_4x(;UFS*4&%i-3e0zoKVtZ8RGy1G&GB00$%Qhxsa%glG(5C)H`nx`7 zXJhvVdC*el1G(@x{Wtu#wXf9xx!iNxljrc=UFcJ0^W#DU_#EaIiR8e-F5rFJ52>eR zfAz}lW>cKsbf)gwXPeI_RIoGkNQOObwMNCDF+Hl{5s6Y{9vPcsa$p&(_W~w&Z1Q^_ z#@yuty;i5sMH~V8I!#LxZl^%o8!_BSR*Sws^^0%PZLK@~2ETE{nU;Dk8;iD^SJ6^; z^_e-SX8A+gjWI()VcWw?n6`m&mwrW2Hc1;Z8t275=#+>wi`t1j^|LHVgNXZB@iuh>tcg*es-2)*rW% zm|9}Tcgmjd?2IKmTInMq(#)gR%KXtY9YMUxR4i0pUwTpyw==a{ODs=g_pO+i&c|jo z(Dk#V{p5Vj3)^G>^Dm)C<)pR;t8t6ThdLZJ1Ba}}#B>LudlaFjmx<{Lr>t&WTtcvkfUnS9tD0WeAhEO8h(`9Z}3;dd#*PtDreKrt~^noSf)_ zY6qsGEN;*qoL{p`bkAlH#%sYqexmocAmIK-tOmndwsx`FK&H4j0R(6RVmD`TAmx8#pfNoo$>>dx)*M1qfN5+GWgDcq6iSD^Y$=(WB ze#TzOHZ{16$g3m$U57@hXW`54($W!qjCu>=yic^$bB=Z~R)dK(ylu1(31SPzPHr>p zH5!>3C0aLRc9((c78TOn~U ziQQ*%UR4ek!6VHJp?5Ig*Bf~Du+OyA>{+3+Ahu^1S3}dTSjibL>9$3ijj)4(43ddB zV1_+XpHH{VU$tXe?Mb0AgLMCZfvBRnNn?hJ%R$|7lPfht_B;D;?}B23aP@Xd)&EA) z{g?{6*&AxBq;3xU+pZ3I*P?n!x_d)tojxrM2sC{FE4q%BrcRF@0-oPBnbgUO1k-I` zw-{zj`pp!hT5d_76pMZbfV~?g(%%iuId~COoeZxsYkzO_?8x9r8~y2s2!1kgisu!F z=7L!8mj3R@_X)#M6~yzyrlE!7xkWG#rU?`fZsVijcr zjb(DFO0%WvsG$2mpFx`@e}G0Z-_zf(I; z$i=Gy(@*~24Sf^mCwX9gHR`XdoWUDq;bp*tUU&ZXT&Eeer`zjk)jCw8G5kiw_WRFJ z>++Fq>yo;B5n>z$t7O^^{0VKJPPaXEvIuCT4U^XheV;HCzFQbY>V~)9RguqkS8k6@ zg>4^AThW~HwOKr+uJov^#~EM4>1O&`_QS)Q zoRPHscNJ6%GixO&&q9>ivhg&st+~lZaBgpO=kQ;(f`%vT75QEnc#&S!4O(%?0NPe&W-;TvggSvA@B=tnW`aaMrA*6jJxTc z$L>3i6S{FUE%kc6@g0~krVc9K_F_le5o6wjvAH`LF|7V%x@V<(iojQHOx{ZRMY9pG zN-w(Yqz6sUfDK^SEj`(v19*?3iwn6{cGa_=w07V7zP<&j+X=Zm*<1i4*P20J&NqJE zg#K02NY!+v$xLwdv*|IHPWM#;*B2B(j>_4h6rOITHLcHgS1SO=Dlxb{*CHGdeeW^! zcQq~)0jchJMoUv)eOwQIlEJ`f*Lvt{TK4dvSySWOi(mr;hQa74KLKABYqx`(uZn&3 zRd|g-^r*^q_wfVA$XI^UKF?t{eoXH{_8hq)C=E=n7LC5f9<}=lj)GZ@!X9Z@tHBJO z40xe{v+v2ogVt%fu+M(|XON@1=e-7)p<6ILU!~bU3c%RRp`|Cb--0C^u5g0v*`xhB z;G9$S@Wy}G0CW9=qh050#|ubNwBJ8DE%!cn2BtbIHK#ZD=h3e;$?s-g@q-l&V^D#t zeQ{H0>|A<4mM`b}WoMiK?MoZ_>lc%9^MFZ!q>*c23V6>zqROT$bMW zE#5|BPN@BO4Os6GW+lzi*WN=_rz(9G6c0B~|;lL_oarCH;E1!WrKV`Tt z@1WX~q8LlJwd`;B9rb3DXsOd{0s8F9*!GffzdXUnF`35zooB$Jw;Av3A9@np^;f0> zHaFiAxruZJnfusm)r5CuGE>q6`!3;5YfJj2no?bR_}|QWd|jQtsrCDrZPp;RvhPB# zhRTKnjQRF@T52^Te-PN|X|!~DV%2H*GKOdHjBAKUvsjC6>v}eBH*!D`8_BaDRkR1^ z_f-kq)~Dt{4(iRAdq7U>f}SAaWAau$ugAcbJ!Ya9S-W4*$#YWLnl10R=LpaUbN0P@ zPl!Ur{#IJs=Pk{{9=%jZBj@W-U5GK;G7)`f<`K--L5ptd92bLAcJUkiU6tnV!Mglp z>Qn<%AL9I~Ff}&*VJF)mufb&TOz#iv1>DZCA1O^%XCQ~$h_(#3%3u8iW?SziG`;dfOUWH*O-mRw+gc;c=XqsLi-$AZ(8L9XdBr z_`CtuIdw4oT^r@>S%`p``YW9+%2&XQF|3-GN9RsB-PLr@j*;E7k(Yc*S2+fBdgUmH zy^jCQMbx(p=Fc_*6DHjoPwHf^H_ug}lg#crPm@6FRxqr~xl3>K5ydcf9{cWFa|>sm zsSU6nwh(${$5bhoY_f{L&9x_VoDwo>^h@~eYxG+ArZh#{j?7zOGc5-ogRmorK4nIy zimPzC&(S^m%eBz+l{d6*%o=z9hah(TLErziJGlz0u}Xuk&RVfS1e36q@vt(vskJ%2PmE=_P!Nxk68eOmQF%t&2G9*>TCe8a*WU&fk--c;H?sEPESSxjb z$ZFdTD>+~uJ?0>l1*XtgW*6-HHh?7zX4q-Rw~e17;!~^7LZpr!YAuLOX4ZXegAr{- zt><4wKIJNdRf3MWOTa*u9Uy09Khbg=7>w~oq||C;TX5IY8Mde7*5p&TzrY|U>Ak2K zh%}jc24C&CKtxX;>*n^?9{r0^SLg#QYGXi;Imz}eSSI6K`lKj!*TZ}j2X7!}q>{KO z9;eKkUP-go--3V%d()$GJz%^6=hvK;%GNzA1!7F2Z*fj~uy`>l=NbQN*)j=hb&bgZ z`A^Gr!i}o)^mpeBsDeI^_oa8R@W4UvX1|%c00jyPN7Ff{-adg`n=6fi9Ma~) zr<5_-|8ugJA5g!+)O>o1$~a{ijD7YA>Ofc%h83u`2@ytwDU`OZPm+ z!zLT?0#h6BT5W|fOSqVBx6g5min+&Ekt!g1@>QZ&@}$@MiSW)0_Rf8^7d^W$)x!4X z%b?Fov;OWv9YZy6OL(OHS2t}zJj+yQNYc6kF}`HZf|B1WjOr4@=J{S<)VkOTBlMZED!$j#_aJA@paMHJ^GdwYeb<%L=NS+CA=YqX zI2q?72SR~{_x~ML-RbU?seS3Gdw=X*`_f+ZCGj=8?psciaY1+HGCrJeFpPlA(Su($t(DxATER&-m5 zYy40|)=XSxox6T8*jny(aEKy2jwfR$RqRZ$zZ02QLu15fv^8X^{v2C7fq$OsT6b^a zUYkD{<<@5P&!j!W^xExz46V~;ZjX9(`T<|I`e_$(kKAA01gkbsMz59i+{@6q*Gjal zGdXl>IjXXmxI0s&26#iSF`Y@**ql&+Ds(36VYhkePO$L|@14=)tOb~p@V?}X?zNpL z;JZw%n&X||*1*7hzmYit2lEM?p>@0Ip6zdSyNH@1MxSlIxg)Y(@Pb}RJ=4igfz4JO zB**M|(dq{{q9r*TV{b^7en@jTY9!K#1gGjmc#^?cA4S{F*s$jR~O zRKyD}X{qlQ-w;?)uI;9_h%_Tq=(g4FOR^B}kEZQaPJ6S*$nh~~)2aIP7WB+yrpDy` z+KfCMvxB}BweNi19!if&(y#^$Mm3X5Es3lGSCF%kM!9LHjDf!H^rmOzb}|ZQa0rtH zunw~C4b;bIj=iVXGT5hx38col8d`y!=3bmI+tm*7uTvC#C(guv=O5Gr-ltb1$}HtK zDis;)?O)y%tjkG;SMg|Qf|Fv$WO;O!j2`&^`9+C@mQ4h4YF~O(wrkc-6vSf-Xlbcq z5TZ7vFj~6keN-$?3c~|y6n0JLUq1BG=+hN8$CB>ZROKw}M$%ncsu498niE|~+jjrg zsnE%XOtv)tni^u9O$?sADlbGd@t(0G#O zMdgUfyLO;^?)%;IC^U!3;wippe*#qpOeLyI%v{*XV@zC@l4k_p9mnvZwpwj~`TH^% z{4+NLfeEkvr^c&p6>I;L%dI2Z0yCUo;$O>7itw-wj9|8rH7wuCyigK)}p8J5ZaKx0_KU5w2+H>4@{ zH^Q2})9NvD7clU2Cf;{ip?e+77?Y!q`PkYRuVZD;hYto<)y2bNIw5z@j@2lIUyFgL`G* z7#Tlk?!Myz>`eY!{^MErid1qY+A+bvCtgL zgjJ+p$Xyu;#>Q}U{Tz`0=4!-Sf>GUFx9MZ(wX*W>`wKS|xU+CAbS-)wk|kSv>5@}@ zOZTsA%hz@ZLno#f(mnfnMt?%B=`UL9x>5EO*n7Au@URj~itlKhV3s-Xjk-r|c~KW>@~viQ90anX%qdh0=C-EsEiwe6KIU*}u$G zqE7R>^Afhbnx0YI6XS2Vxu!#(h3e<_cX30I8I@0R8^l&^8B~zk*#u+O^@=6e**L%E z58@Q&EHrNR8J6%6W1n60Ymr;=8+t~$E6-w`$1{k+e!adDxO%3#()DW?u;@D`wo2Xg z7`wlK!B_cLdRE{)B*vGG$+zEuQ!#_i0OmgHSZk5K(=&2zun)RH{gi6w?W0riQ>wif zr{M5%)k36bU((5a`zBd%&H2psg?uw_j~{zt=!=A!^$4s6Fizow)=ro~cWrt)(%lD^ zgY-U5OOpmiAV`__o|fvpJgASL+nSbo&uwpt2Q>0%X_9dz!pxUVX;rt-nGX6Qh6&1a zX0+>t@P{dLayqwgBis!$scV;8#6!C>;3`g{(5=-BOm()_g{t>p%3qyE z*#bUYWD1H*E?ZxNsxt+yUd`L&!yF~iqp~dD(hZk1nS@tFO6^aL$e+*-G;c%{LZ{D6 zcx%~m_&MlRKU#Bq?{>R`u=+JUDtqnkn?NBl0lRT@SA@4c{phy2uMZAJ`FaH{RcW>y z2Im%|v652*;MT`8Ze7vNK?~0xO{05uGT*xb$pt2a30mw>gR+pRblcp85n;HVaGI8u z*v$g8e#sQZ+Z7p!2Znl*o?Ub;u{(atFm<mk-gYv{dn6_L)?RwOhk-JZ#7mKWpSH+XjI2i5}It>yrRf z8Ys|KWn{}0aR5l?=(c*rO8^*xPSMuPZ$w|LMxU_35veV6pk2G9G#0=H!X zSd$FRJnXLleSSyn>|cvFm_4#{d;SYgpfF`!aWzl%5U?{ICrl8qlIIw|V7Taj4oC)u zV05+`2i^F?Nt@_CL|XX>UB))mU84k4fN~tUk}66@(3}YjE#^CH$$lgy85_IDr1l|; z{8%TlXW8-CPAD_3_j7D=xyN~B*n|Cp>#S6xiFDii00m&A@ktr7y1!Xx>1zL!%N-7H z@oPQeF!|loPTdb92!*{;s^92e|1Otj=`O|@lxovwf1P#hC6T7gI#(FqgAbK3-Z`R7 z3-irp?3Koa$FS`$L+F!|valMSeccWZaz=g&Pxk~B(3u`{vU1pJv}KA${EIey2hF>Q z)^?pk5;I(foJWu9oU9s%qBVmUz57mUi*-(=+vI!Sd6nlrQ$v%tg+sgEeR01Oo z;3=>#bkAm=hW`PP%b>3dM^;Ec0yEcaed8v7L17P52IFhg4b;Z~CZQQ}NO>e4D!EFJ zYFd1nKCUM)g%HNakKvRhFqElR^DkMjR~zY`O5rOUp(zY*ay&)Nz!>pD5mNtmIGMPu1^RAU5nwYQtjO^Kezw0BEbI+hpO4;2u zYIv-GNoU(Ge(8^hkD(Eghh)L#Ol2balZO-)1+kpL8`6E7;TKvl5w54R9Zp#`vq!Tn zqHt1Fn9?1`-aD{I{e0*oyW^(|_dt6xCq<>^_i4niJ?Q;)a#eVYb!HN6-uY|bof|OL z%wfM)3zYmZX$#w48-XZVFr@e8)bPPb5LD8ma-Es?1o)YuYBg>;L30WiE9x@8S$Cv( zB#gaU<&87AN{g0CKYfY@3fkaCYP)lr;A)h>EuqKk+`736(DgA!TKpL?d&NIU&^nhV zm&+pKF5{t+jnLKCCUYG?&Hp0}8Op?ip7$r> zyU&;cIj^q+JK)I(#vhf=+m5sE-)%j)zaa|q5yNUQm@wkHJI+zhNp#U>Zo(2EilxQ$ zI@^cbKY|n5$(;OdN}m%_=oLf7`(EFO_{dj-?s;OX&gK|%D_WYoY|}!Nlf}?ilGC=C zr^0I-rdPw|;7EA7@*Q-~Znj}}fq}0Dk~8v%X#&4+U)h3`rm6~vCVcGao-MO|LV!D; z(o&scN?VZZzC=sIx>vvtI%&m_-<7H;!E5BH(`VmBtWpN2%2;62l0xX!baT3``LkA2 z5tVnLN2M_nzc(#@Wy&PHwTHb&IT@4SOHy8!0u;oI`Oxm#Yx1^Z=}~zf2?6GR$1oWA zF~x(xt1$6k_LYI!V2YSBa{og&G3JNNS{?OUU5GL^<|?#wVDmk&!0YI!TylP80=R-B z^py&oB}QOQQg^N)_t#!m5165nNiN)(ssP^X`cit2##m(OVV#@O#Yj~~_kw}U+tTZ7 z8rXk3wEY9!v)!IGw^2%(MoXvNT&e{G#hkK?uc}tCDoiBkS0DKfES$cScpamxPn!-blP3e9B-8iTrL{&{~s^8--#OxxOZ=*OUf{6X3e zP%y?Y3BjgoN|C~27%JmLHMD(yi!Qvh?|sAp4Aouw`dIlhefYr$q*>+oXMwza>{{n( zBX`qlW%IOXBofw%wA6G+ckm3?U1_Oyt0{;yKQhk(csCnx0EKzgbX&zsk+73t%o$u~ z-TOJ7G2s$zS|fvi+nGF0NJ83NjQIuqW94DVUTeT_Fo;4UCj|P;J&#k?f7(kRHzswM zWOXeP7O4e&QgWK7A$4fNWG=Fr4R~Z(95=ImqWt{yQ$6eNWEVzb4Ij6FK8G^-l#u=f z9}tN!aj4t5qd;z7n9N0LpQCnQwi#4!Ue<0Ryhb^_zY{-xf=-V72d=5pMLZj>Y6M)T z#^6c&z_reJT$IU(72dW~LfI{fohXJ`$^RUzcjwLYs7#-9M?~L?@xO5c0!;A}V+{Xn zuxkmd+1x2~&vQSv`40B-H!ZDfITTp*EaTaWrSB2rXfUYHea#Vg_NIsFo>i9DKD@J= z$%mFdeLezdWd;+vl^jgMwKZnGvc3AJfr6aqawFgCD`BsiFq&i6tob9L5$62nuPHwX z++HtlRd?}W$dxW(CaoUX;`|!Z^L0>+#yOhD6!us*oE3_wjhXLA6;(?_xGr?h=HK?Z zf)|}dOC2rZppz>Zjg1|5=^a>?6?8F!Z?^}HP*Sp&?m5K$*an>Q2Q(^(xUTvH*AsH+ zw*UU|+$T)LCv$wd3%n>}y>Gh@MO5CpfR4O;PnO=o6%xkQP5e`;4_2Isamx1{+a`#e zm`t4I$%#@FK?%#q^J|k4`U=e0b9%n%()Wnk(wL~t;b8M$xYEcxv98_fT6;W3!Q_C} z8)pLNoMr5D>JQI`h;SMHN~Pu}kc{&Pdd%)KPGKe0ZqfT|I_btKa0PeiV*b82;;~lC z8T3_hc{VIz>o{fyADw>&Pj{XkRZ?OgtXc09C{KU_yZDUaF;7GTf*SkS9 za&30>jM7pC*!FMR=%@V5U!)vGM9*Y+J&iMxQEaA2`_S+|7E##2d2~Kh@>(GPkDC6V z$DA9q_aW>?CtB)c)EU{d;|zzK{nWn-ku{Uml3An_f+u9IB)hNuRDrUtdTi~#ZQZ(? z3d>iA$@;oX!J`3L^r$q7OuWIHS&8IH@w7dQc(5N(kaGRa``5qA<*rX$SL51gJsbP? zFUjT3t<`6DwV&@re>d|;ZJc7xtfZ}MunlqqO!i^hY;O}hpixhAYUf+~lj0J?fnPTi z#luV5F__~@lEL+AB{50x-yP`YN|eq3#crDxTD!X8 z3MZ4LJ-zPkB3$BQyoOu3bP_HQb)>)RR{FtbNhn?C>rotbP&uGO4MTb!fGOiUNt+dGwy%Jt;i+`!i{ zY`lF{VhfaIGKf*yKdlw6eqW~7Dp0BPE|AQ6T5748xE_xKtI~GE{<{p-JAWAd%H&mJ zFzRF0(fR!uZcBjr9y4blb!{Vf$q{ne|5muJ!YO;tU=?d;;RmqQselIF7%SadhT26(o+kyl$i zOYeR~$hJ1{3k-tt>_5f@l>o}mcA|H|^Y~Tp49U}JsbotjRzu31 zg`oKTz;&mX8jSJTD)6Cqqv)P}KGdv+70sljDZK)K&HN*1>1qA%z&Se^X=bB+3&7+v zUefWUB6i^_!__-)4_Jfv*UFCE1=nepx+6==)K}@k*8xK&7hB( zJ#evfHSL|No;=6-Eo7L_+_zn@zw3bd>Y{PE{8In9;4Fuou47ZAzO>ezJD>oR=$+$E z&ez#IRtYyUvgsLl99PAdTN|Dr+on1_hZX&PmToIC-Z!`QhlA;JBn$4Vj5`<14pzSz z+6}ojJErG94q(P6U8SXQ4{ogh>f2OAR#_O7EE$f=l1zn$-oDv8z)>)oBaP?)ot(ks zo}`ofuOa*3Rkt5?J5~FqTt0S(F?fM)4C9)+|3_yqHr#!U$}`ni4aPfLXDJUvHvBWa z8Y;`TpN0?JN=x%MwZI>=t+1m?zEMtM~8f0j~dNX-vhhSasX8oC!l-=#Bhx{O;S9*uf zI>M?j>_?Jym^&(*HR;Rjp}!h~C;Y-NRJIqNA48O?PtVuA%EA^8vuvWJr4C=#VKv&% zCaucpPrc0GHJCdlj+S5d;=6C@p51RM0LOM<>PA9*dT8K2PB*%3YG0>t)FCssIlS&3 z##tz0B3z#jUnI!HG1->MnTKA0zhX4UczXK{$e4K0qbfO$;T3WHZ8T87H@m3XmgZe^RO1F)&a)KYUV=SRx&3jnFCCqmXuDSF>g)>uE zkh<@jKB|}Zi<7Nx;?Y`$C-iFG1qiBJy~h~;dIn^)XIsM`RlCyF!ZT_Lq~Og)&<{yDtSp1& z@8w93DmUQ(5ONN~*7`b2KB*gBWLP!R^<~yTeGTcJ-SYHc89Fik$g}Z2oc*N?uOjU- z;SQLSVA|%)RT#b;)|-i)Z6}CHkTQ{`vyajnRD&~-wd7~Bt*|*q=aQ&k?i2M8#5nb` zE%o=PBzPzM!ZF6G_}Wc@PuW>Sua(8A3RvJIE!s;O*_r`;wKb&M8mZL)AzwK{OLH~8 z&O?r#sSW6-^d6{QU|5&rK~up4zhn4G4I!%;q8R2Zq;CI)9rR?XE61o?qiut!^q7zJ z{R}jc$kd8UrmDOKDqwQBnOXMG_HZUjb(`G|QJWoOCsp(|K_`DsrblJ(mJHpn>qVoW zB*UA~x=#$dCEHvIKR9I?{k)a?k;*n;iQCbb-?6;mbgU#(4Q`TQybP9*Va80%Lz^Ox z<3P{IwBbQyOY@i~BmBNK4Mv8Dv4lEW{mfy_7~b3O*-6BbrE7dh-(5Z|7!go6Mkk$a zZiF?PzMmfR*g5go-`oK1F|5(kCBwauH(*jq|J{fJT^6h3?w99(a<;n3Ttx!^8ej$|tk5BR@2PFWZtu zk80)P$A9?eyEA?b!AVhKyt8jg>QC5MbGm2gq?x%m3!$~yhY?$@VK?^;`tJ&anXTvw z4T~3H%@LOkp-;-BhqW&QEWbm4SG|>p6MA7RElssD0J?5owvE(Di)@>FV3?WQv1Rcr z;PxlBbk92Dd@yG2LE|c)QtXkYtRwl|Y_*10a8ej+CMz~cN6z{M{oNKNH{oF)F_k~3 zrgmro@62FeZ{ub|u`gN;$x$huZ2Aj~TrmAzE5}cPxck6h27?{juOn}zLfgqs9)tcfSrc)>-w#xzms0u!9E8W)A7-ihng1n5ff&eHHHtJiM+-KI$HD&HZ(z9AHza~9=QliD4q9j zhFLBzm~)`rKWhsV6go4yA-nr+4@R|=o>AC}FXxdjWBjk#0qs@z0Wvd2b2`Knfs;|B zrLrOGaR!etZLMc5L{|D>{AO|otLBV_ci!=ZM&`k}4bQtVC9esYOg4yaT5!mZ=$Y*z!vPBoj!_$Y#EMW5iYr%Js>00GIpW0^N45TpK=R za;DMWwQJL75nct!r==;OPu_t2VBScv8~5QWVmihW&Oha%i+i}tYWRP) z?k|Yz_2?f>b2S}+c%fSp`Vq*`C9B^fPH8uVT&qd1_cTM+;~+hw;M~4CsLonVOZ~eg z!#mqD+=#cwEu4J~P1>rsDCdE3o!6=_IVu&CmzZyVCJQirN+$TY* z{6^NOjU`}vn45Y@%H!Y%w<^nG8zCuonJ!lf{n%nAoDR#XlYSIa0TuHNN8!fT^Rgt`CHmPpKtjKTy7C#CuKVG z!;w8?Y9Q04wf8jRThjM5b-cokBBCEbk1ATe6%oOz8d~aqFcMrrp*sEaXy`>5>R(iq z>F?T$v({j(?*4CeOl`JQKj+GFFs|R}@6IlYj>emNs>i!rY<+UtZW3{DPr(*ME7cN6#2(8Wc2>4 zx82%e#TI(Lwu|l?f-87NOQi?0Kf^Lu($dhE`H0!g7#|w)!pIG;%rRBUk;h`8&ykEY z&MIvpazM-}b9~#RC8`bm=*m6Ecy()7ekQ_AHP{Bmb?QS}b98>zcw+~d`-5&(SvFwC z>cvcTUb0r}rr8|1ikuhYamt-G9KcTn^`>`!j=j@MR4Xx2Ouo~~%Xm4BsVfNmQj?8J z@_2fWyh}bImefq7rE`b(eT%w2CS&4uXes=!!8*FFnMXEwq*x|8R#I_G#Lr1Eytkv; zedu%L9=aMlG=xJO_` z_iS;wttxJRGoIZ&wsAj1i;Ruc%eaW|nr)zaPPY99RR4|H1xdiUkFfl==(Zt$mOjN< zIQ&oKCYJ{-KIDtM(!bW_2KwOU+(8Y{Fd+<}8d!S&6lZ=-i#e40C!eeg`&S2Ho?d;4oMuLxyAY zeJ*VY7I7}!)>wV$X^eRQBdr+;%dh$9ue9#IRkLRemCk-^HypR!8LN`}LylOv8Dj}U zbLY3fO3wb|j?sOEh~PO>)4Q|zC~#kCQS^+?T$u!v`*t2J z1sjk3J-V2dnth$q1$xEgM2xy5J;A*;#+rFvJ%yg9#M0KxI{ak{#w^g5KX>$b*elOD z^r$3X`e8sG@QL z{K798-L~@9A1BllF$gM5STznzU;y2=Y|Bivz0UYhS*JZx_!I^eSZD5;kF4cKn!WUU ze`5=@j^S1G8@)XDZv<6)x^Ry%_PTDP(uj!qqx59BYxSWMa8d&H)&IM7XH+h?y%+(@ zKTGwmeTHow&}lm|A!F-ql)h$kGT>cpEne&~v5Hq(#BRN3ci>=uvr>_<^x$#N^8LyoWAEMJQ8Qow}k5qgqp= zMQXc2zXkKaxW1yl8@g));@_3bt%^XyZ8!_f8QboXy!jyBRCJ_!Hj~YSy~<>)nThKM zE3olQt(yOZn|Dxo%fy2YI}|eTF7b8xyQvGBw+2V?bu|B0$vnh#;mt- zV*wDwH`?ZSmiggyZ)a{p`}OXS48QQ69&^Ev10rrio1^OB*IVe{Px=2=Q<*SXJpG1$ zz`4bprh6{SSNedH!o+kV4&Gh^PghR+BeNZ&{K3fO&^_yD3Dt-tnX~V+Ya48iW;LyK zQ$G$n38wcTy^=)-GGT#bC+Y9znmn5Z49s}Cg2NYp3MMg_@U+hBc%bXywANkAo(7hw zCBvxu%D&X#&cz_QZS|VIet182D?R2h=6S$KffI6MCZ<5>#`S-gM=p1KGtw3Jju|dD zG=D&E+_z#lw^Z$4+i|m)iT88t8aKtA<;L`wT~c;|Z=Y2`kNH}e6}+SogC~{756(n| zB*O)TCAY_SBN@BlYd-+GVaM?N7Q2h}@nd{H=~2c0euTA(W}-z&+roXQ!C)d0C)u!1 z{Lk%ex_0;;c)}$5yQS{efmN0>_Xy5wT7&)YW6q%45oOrPqs&Q}C;2%S_fvxDABwW- z74ZO3xg9+!jj4Bn@ZBr4)UKh%F)%g^S1@*MF?`u~#xh8n=#EBZCWDbeFKmH_bzrhQ zGU~%yVMA~fz37vYq-UoJy<)hL>=mwWu!Bss;n@AX;Rkb0aLlL9qN1O7nJVQL zQ(x`GeRjq&q>TQPjeIv#Pq=<#Q!okrnVhv=a^@JsM-0C5zp-qJAnqNQF1t+Jr1tvU z0I1+0v(DakdVwX5WiY>u-O+)tS1sv1vcGjR9i#e2OUwHBp>D*P$scK&MV&?7xjDUq zQC3aE`h!p?lW*{PGuKE2a)AZJlib;%+AUVBD!a zST)_gbk7&nZe2wFh_Qt8UX|Oz0y9zh`jPH9gQmafp3Nfi;eVBxnxd=n)k%2aIgM_c zY7hm#a7lq)D_^m;vN|MV8i|loLKT2E!_4TOoy)a~@XIXBN}jqZ*x?K^TyAa717n^* z_gw1G2wrl6dK_8L@8DL6T{yyE6$59*5Fq5AG_Lb{HlP7cSzG$Mg9Zk{!=9EMAXme& z=jqjmo)~_^`Nrz~xFcpvzhz;v`v>?9Z6>>vdh=)nqH-om)tKH2Ouh}{t(=@U1J@-m z@j^v=?Lt%>?Wf-jD7n(T1MoA$eU%RV6NYNEyrtx7cs+>91mh*m8)f$Z_Ga*vON@mw5OQE7IV11PES#fd zQ|K}Kbi9-zhzd+(Jx#kAIGNdzbX)bVojc)_F||D!7nYR40%y|qaBW|)eEAe(TQ>~Qr$O|j!c8~t9x#x;UwJ-nEWA@#A&;(TnZnR}^w3>-p zwWZ~Md+w#M;$M{OyOFW-KVkh$&3AG?46UDX54o6VCYu)hY(x}nJBQ3Y+Kxw!9D~iK zmpJ33WHW5fh=Zq|BmQO1zU1eCJ>bll?1Ohu6WGa7;rmIwa-aAFIM(pd-_@vNpZ~>V zH&KGU>ZL_XlXNvRa8h(=sgv+&12{JZ$EIk6!nR-EPPa90+UN^TnJ+Ev_~;a3_D}|0 zJGmCU0s6u(9M#T5E}t#ARo=Uq|Lpp&WhF9qJ#;!wN95INIqhL>od&^cG-dWT=+$vV z)_oZc+0AnBL1bz!&>HKy+x{A=h7#!c+8wHW&AvO6;gz;shZy$1e@b<`zJfyUjuQ_5 z{-kKVa3{I-7Y9e}=^_PRWFURn@P*sC9}Xmsc(N zg-~LAy|#6-+6^&Ce}mv?D6_c+-`B&iKeM0#;WVu&gK=SM61`A!+iR{s+L|$vI~zH> zAW3(R-h#aFCV!CpWiAnz#SVw6@6)Cq%XPi|4GI~_%-2hPY#~Z4M$lt+FYkzB!UdAP zvUmxMBom~hI-SBUTwqcU<|8~0!B{a5h7@j|qXDPS5KyU6+l~M(GJ%zJ(lt1ga}2%g zH6?K};38urJx=NL0xV}}B5BWpD|m1(lv%6eE|`%=94(#VJGpgj8jhA)Dt&c&QL%xc}A0@4pX(9m28u0~jbG{W289R~eINJJ-S@b>P;Uq8^s06jk|w-G$|Fpl{;p2S zLpYQf3|*u2`3Fd(cC&YqdNt}me1Qgs|4?iD+F z7j&dkV6PNk(e}AqOWzFE>@nRocbdXYQ1Rh)^ZmCiQ;z*>%Qi|R%v#x8wLJjRj3Fn@ zU27lG+Yvy2SG%1G;NoEh;@VoA1Q8UQPzOX^CwKxC;Wt3)?Pvjmf_yqYSPdlOUjOgb zoo~5(wCzmzg`S?Yv|{QUH~t}X>C6kZcx>b<-FEf{t33P!)hSx46lR(Xf?~Nty&3!+ zmB-PC7eTk$)7RFFH3tK4Y`#XHBd-RtaTdJp)2SBsHEZwSa_D|qH#FKt3_?;;mG0Se z+%8Ck=k$#78a9E}J!CG^C47uXR`cDoo^ETPT6=y^u2@X2hSR1V2+AHYKE$A8oFw*bvL_DC3{x7?Kc!BnDKNfTSq3~iUG5~wr_reREcXv(~lXS!@WRX?55|N ze|16*d}u5!T`@z%S-8pgGW~`Hr3kDJ(QVcIN0CjDKN4O>n?$^?>07TpZsoptG-Znw{^{n1hl32lLcO~cNE#?Sjh z64$=J!jyq1bW=#JbH6il7!YzNdPbRJuOEj$YDnW)*K0jsMYCqnYh`i#d}9zYmb7%8 zwI@8gK4YI}ZyblHZOH)|sTL?KUxgUwHQlp`ykj5uBPP<6b$fIQ^dl1i8C)yDjP`rb zJ$sFxF#%E~dKYX}KjR!ZG6^8hz#w3xnXBlP461GnZBJ!R*;Ml#$MCb23_0nOY;pm5 z6-kfTd}`cD{Gh-YTH0@p5x9cR%(V!2>s@;Abei;hr*!-Y?>x_q?%Bb87$VK<^J(c= z-Ra|i`rgq}2Q9xEByjg6kop|bbc^NxUQ3kAO)oWYL5%5JJK8YD@_Sv*0LqQGroU^m zKRyVlw9WKYJL@S!X9KJJq1(F*{libffXn>pRK(~ibCW!-+$ZQWbO%tWanV`Bqmb-+0~&7fTW8++k#5}A~T zr_CN9IF-CcbO{C*8{%KW~lgFrs>4?I<8XXWy9pAAk4jVCc$=M+`Z7_k-OofAKo zy~4#MCpu1XXix!Ue(PgAxr6z){ECpm8$_?O=h{%rXb6M7r?ft_3%*Q|Y5T*a4W1%l z;@{A{&vA}ol<6Hbe=xTML_K5cOh#_Pj3SsFw3+yE0oc5+H2QMTn(_f97R)*FwrKYq z55F^InffPGqhU9g@<_WrR}jV6Gahz~#h^f3FJdkbtuTr$L!yl-K{ro)8jlp76}`@m zVt=5o=}a=ksqX3?}WQPSoYK*o7jxtxA&}%YbsfpCsFw51tKAr^KX( zLJLP^;c-z$uf~RdyNf3yn6$Eav!e}B(#dc^=55y%H<8+*OTV!^4$_2;G)L| zx^1pumK}=v7~X7DjV)FqvW9M()U5?p^72zUJ{q6j^$^H~1T34gU_b#;WzO ze~0Tf%$UbyT7r##x}JV$DE!?x=vCPTI?0~?u=eR-55|{ChN;2wXEJ9{N2~jMoU$+U zYK#v|0L#>fNl8yW@uC&Z{&Zi`wtJ@)CxEYGtaq=s!(oBFm@>u8vlg#Ws5Xoqm7P}b z79bfW-d9Z71g3WplV3=lA8`(m*XG;g2~{+lpo6C>7|-r=hFQAFCmUte>oa5#&5=NU{@0iGQ*7`}QHaJbfMqb~I?t&X{^&I0>D;PT z+aQ`?wC?2RxxoCZ8BQkdfjW@Pz^C+l$Ibf<|C@W3_H-HpjV$mq)-}3q@zi6}z}4r_ zQojfDV!#8}i|OjJX$>~?KRMd<54_|_ri8V`!4r{JvWXw5lg9Uo;X{WqMVqI$rS-*A zehlyJW9{%27h9OM^1i(Y(PGqBdPWrm-tCc3VN%1+DdsJJa+%oKM0ONtWZ=X^az@q9 z55wl%nL&Ryz3fW}o~YVR^P(55yG=yg&8$XH^lmSlBhGHY`~Xga+b62naRg`=Zrsad!^ zG-od}qp|5)x_HX(CEd2y&==6y=}b%)qPqyu;xy*6MrB+YxIPOePiL*(9c_m*k8B6k zY-)%7Wf%;Xl^WiVGFLe?a>mWZlRiwgG=Ir{zhHh z4bfTzmMN3LIVS=}m?GX}Y`ag_3?S7v431U#w%7^R5(m=XP5gG;2c_?fB^+Z@eia2L z%$17VWv1{81}o{F$NLu>f@OM3OWo5Z0rP)%rlqzg_isi{WHT*Ii5SxwZ0&BEfwU-n z3WoVp1#N+?%pL=Mxn7{7Zbrqn8;+rQb#*?fHm7g z&qyL&3l{OHJuP*()B~Qqgu(6eE}mM1XD*oBqN8OX?A1^vyA+z;!V%mE!>Z+upSK5( z*nFc$71CqXOZ@x|^JtGu(q}GmG27|3b9Z`!ztUhLzWJkvRKX86pm#9Ut>IWmnW8Tn z&1seRxe&%Xcla^r%$Mq~er~XEHU;oz`F_*A&s3<6GM967mbT>7G|lJ&2xF zKGQQY-@9c!M#ZeNQ*-$qVXfNiuOv3}Xfr|+j17b8J9fO92Zou^9LF9Hh9H`FLXX)| z$?uE8{&8MY0Lpr1bK{3&j({Agj;24?jn(G(BAN6i!Kw>0y?MbkcUzvE{)>PIN zu``pyJ?-YW77xNOKNi!=Mj3nL{g9rK>y_ZzbHv2XAw{v6uO(9#l-LuK1 zKO?{rGgq-r8yFSCvon^#+SvCka&62d+=FhRzYuADq|fjF>+8znsou6YGNigHGM0!2 zL&QlAIU@TSPOHhs71VpPyY z>soW0=Kyck@K3b%H=|1At?o(d4nQ^93iJh5uByAh7Br)Y3%dVZbXoL2hY;^hq07iq zr-cDuiD3?EQQsOL0>%|nQ)F(I2$kZE7POe zYJsI-E;j5i-${jRcmle1%a*ae0^$XX?UMwtHLl=2?tVIaS2LUjsuVSG7u$UGdQ}N58Y;hX6dQ7~3=#g+N zST}~jFg(ov5$fwk(CAw8^`{<)aHH*zqfxfY7ox@2>S#-WAB+IJ5rBy`jYK)_~y&ZE}`g*gVkPQ^C@+3u-_ zRoPJMvI*_4ig@N=@8-qC`_{K*b^~*Q!B-Jk^AKq&enI!jekjcnY#$RXb{h1A0bhrC zS`fGcz9p>!X@I@2ji8^_YU|qqw~4{P^^Ma7 zuyVZ7x>_y5fRWtU(Bn)UVv->z@(8W#wN3}TibEs%X;bpGGGJXWUUXk>0-)SDEwrwY zKram{_r6t! z6BwSsUZ>z3Fs?@EniKg7QFX`xO{3rJ-Fg7lMjz&&wEMr-Tm^mu!)#j$T(g2pFz%q= z+}^ey7*|O?^ueWjJe)AU+c0Q^jjb8{hBu~HL77`1Iu67z35*b4@a^nQ=w5Z$nX3Zo z!>~-<;dX9Nv4DxJ!%8E;_UADksoZxPE7S&Xq1ST>$8}&oCNPZa^L9l*o5mPBDlndd zk!;2E%6=?g7BVJD=0$^%CP6%D4z=a`d=$NiTWDa&oTTEQGMZr`a@`ISQp_Tt?0Z{HD8p(7Doy~=F zA`J8w>9r79LlG_=RQ|6h2tiIs(A_#Th;a`>M`c^$Py>7ujh!I!;*n)POP%~IRLtshfQ z#agE8Jzvi7A!Jr>Wh};RI%i~Qubn#Ne=m8Dmx*a?SABoL2+QtH$OV?svrnxc=nj~;a_b(6@`@WJjfu8;Pzxi3Vb zBi_kJXuC-gGKPYS_rk2Mgl876)%ioiI@Wn%R-<9XZHA!9dyR_mNI^n|e5|{wbtrkI zSFOj2m3EZ2?Smb`j!*7A?B6BvywYwvA0eaoYkW`3aN(}0-SZ|{B@&NZ2h#X7PdTp^ z9q3zsQp@HTArrWfZliW5#p9QotJFSC=C)I=4xTE?)8}nyV|!-6Aieu>;I@Fy<8vkF zSqWwH{1mSSgT&8HEDHJLMx)qto+k!xRH7XlJu1cMx%HkXWzP}$$tC4H-w0Cn{(;9o z1ygm(>x@)qGR_#ys9*m0?iqWi)j0hyO1WpOL}p3(XtE8zD!I70E8p$$1ZxmUn`IB} zgBiJ(vg%AhoDrQ5rF?<;s%%MlLFxSh*D5Y;3k6T!T^gCId~ROvcPROJe1(fbO}Pa7 z5K6gFra5*=nfv~WuT-Hci$hN;-;~C$`EuELA^)hl{7skI+z-9M@ka?|XE(RwFg#0t zV(@QWrDO=JtvecQad01mjU3e`qqg08sZHlITZ?KW{pg3fnmpKoTKytp_uinKyka7m zuxBWL*tHL(eCGl+cuCpPrL}_f!5jYIiJ)PxMtMVh*BNIEMx0b`7oH&ClA=&ul0Fr6I>9J7&7ss zU;9U8Q8pG9y=$ZN)x@gK-Yl!XZed--UM_J?we^|SFDx2i9^QSj@UbiQ$UHZR*V>@{q$%M@5^YIzud>@ajwa!zIHV%$jIV{)V zT6C+b>BfihDam~lLS`hI-k8s?x?jqmxpUT<;w1I?j+;S5hxP%6qm4uVa48}4;&Roo z%}eT!E)YyslJDe2-AVM_(C5<-TPeth4_ zs>Et0-^>9!&;!`sGqxu7)Xlt46yN3Zyc^KRhh|QMm|OuA!CF zIEZd1m1ed|@(piyoM4SEOFzh^#!N6e+tbW7^GT^N?uADrA!B*7#AcTKt(qpooBh&X zt*@-z-?muQAitw>-uc3SaylWCF2LY!@qH^Q_~#$ws_3Gj;`#Mo2IHBH{L&FB$1g6r z5;A==;#_0W91|P8rubCcQXM5zd`sO=6#k}vJ~(S@{ro5)^EK}NH~*(r(XwH&ZLS_I WWlwc_``e}+`nMmM6W^-(c-dc~QnfSy literal 0 HcmV?d00001 diff --git a/test/peer.js b/test/peer.js index ad07739..d965195 100644 --- a/test/peer.js +++ b/test/peer.js @@ -1,5 +1,6 @@ 'use strict'; +var _ = require('lodash'); var chai = require('chai'); var Net = require('net'); var Socks5Client = require('socks5-client'); @@ -7,6 +8,8 @@ var Socks5Client = require('socks5-client'); /* jshint unused: false */ var should = chai.should(); var expect = chai.expect; +var sinon = require('sinon'); +var fs = require('fs'); var bitcore = require('bitcore'); var P2P = require('../'); @@ -15,6 +18,58 @@ var Networks = bitcore.Networks; describe('Peer', function() { + describe('Integration test', function() { + it('parses this stream of data from a connection', function(callback) { + var peer = new P2P.Peer(''); + var stub = sinon.stub(); + var dataCallback; + var connectCallback; + var expected = { + version: 1, + verack: 1, + inv: 18, + addr: 4 + }; + var received = { + version: 0, + verack: 0, + inv: 0, + addr: 0 + }; + stub.on = function() { + if (arguments[0] === 'data') { + dataCallback = arguments[1]; + } + if (arguments[0] === 'connect') { + connectCallback = arguments[1]; + } + }; + stub.write = function() { + }; + stub.connect = function() { + connectCallback(); + }; + peer._getSocket = function() { + return stub; + }; + peer.on('connect', function() { + dataCallback(fs.readFileSync('./test/connection.log')); + }); + var check = function(message) { + received[message.command]++; + if (_.isEqual(received, expected)) { + callback(); + } + }; + peer.on('version', check); + peer.on('verack', check); + peer.on('addr', check); + peer.on('inv', check); + peer.connect(); + }); + }); + + it('should be able to create instance', function() { var peer = new Peer('localhost'); peer.host.should.equal('localhost'); From 4283cc364ad8e3b347ef944580f695ddf328e3d7 Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Tue, 20 Jan 2015 12:59:06 -0300 Subject: [PATCH 2/9] Bump package version to 0.8.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8382bf..3bcdcd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bitcore-p2p", - "version": "0.8.11", + "version": "0.8.12", "description": "Interface to the bitcoin P2P network for bitcore", "author": "BitPay ", "main": "index.js", From 4f9c174feb0e77dcbe755c37c4610a351cda429d Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Tue, 20 Jan 2015 13:01:29 -0300 Subject: [PATCH 3/9] Add @desc tag to avoid warning --- lib/messages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/messages.js b/lib/messages.js index 2e704bd..72f715b 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -552,7 +552,7 @@ function Block(block) { /** * @type {Block} - * The + * @desc The block received */ this.block = block; } From 43a6a111250c857f3b9dd3a971bfdc38a23e5e9a Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 20 Jan 2015 15:13:13 -0500 Subject: [PATCH 4/9] Added index.md to the docs --- docs/index.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 docs/index.md diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..b4a6aea --- /dev/null +++ b/docs/index.md @@ -0,0 +1,38 @@ +--- +title: Peer-to-Peer Networking +description: Peer-to-Peer Networking Capabilities for Bitcore +--- +# Peer-to-Peer + +## Description + +The `bitcore-p2p` module provides peer-to-peer networking capabilites for [Bitcore](https://github.com/bitpay/bitcore), and includes [Peer](peer.md) and [Pool](pool.md) classes. A [Message](messages.md) class is also exposed, in addition to [several types of messages](messages.md). Pool will maintain connection to several peers, Peers represents a node in the bitcoin network, and Message represents data sent to and from a Peer. For detailed technical information about the bitcoin protocol, please visit the [Protocol Specification](https://en.bitcoin.it/wiki/Protocol_specification) on the Bitcoin Wiki. + +## Installation + +Peer-to-peer is implemented as a seperate module. + +For node projects: +```bash +npm install bitcore-p2p --save +``` + +For client-side projects: +```bash +bower install bitcore-p2p --save +``` + +## Quick Start + +```javascript +var Peer = require('bitcore-p2p').Peer; +var peer = new Peer('5.9.85.34'); + +// handle events +peer.on('inv', function(message) { + // message.inventory[] +}); + +peer.connect(); + +``` \ No newline at end of file From 8c8d0e19796c8fd7584d3a3cb2fe29e446ede2e3 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 20 Jan 2015 16:04:34 -0500 Subject: [PATCH 5/9] Updated namespaces for module documentation. --- docs/peer.md | 20 ++++++++++---------- docs/pool.md | 5 ++--- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/peer.md b/docs/peer.md index ccd73a2..b931b7e 100644 --- a/docs/peer.md +++ b/docs/peer.md @@ -12,8 +12,7 @@ Represents a node from the p2p bitcoin network. The Peer class supports connecti The code to create a new peer looks like this: ```javascript -var bitcore = require('bitcore'); -var Peer = bitcore.transport.Peer; +var Peer = require('bitcore-p2p').Peer; // default port var livenetPeer = new Peer('5.9.85.34'); @@ -39,8 +38,7 @@ A peer instance is always in one of the following states: You can subscribe to the change of those states as follows: ```javascript -var bitcore = require('bitcore'); -var Peer = bitcore.transport.Peer; +var Peer = require('bitcore-p2p').Peer; var peer = new Peer('5.9.85.34'); @@ -61,8 +59,8 @@ peer.connect(); Once connected, a peer instance can send and receive messages. Every time a message arrives it's emitted as a new event. Let's see an example of this: ```javascript -var bitcore = require('bitcore'); -var peer = new bitcore.transport.Peer('5.9.85.34'); +var Peer = require('bitcore-p2p').Peer; +var peer = new Peer('5.9.85.34'); // handle events peer.on('inv', function(message) { @@ -82,16 +80,18 @@ peer.connect(); ## Sending messages -In order to send messages the Peer class offers the `sendMessage(message)` method, which receives an instance of a message. All supported messages can be found on the `bitcore.transport.Messages` module. For more information about messages refer to the [protocol specification](https://en.bitcoin.it/wiki/Protocol_specification). +In order to send messages the Peer class offers the `sendMessage(message)` method, which receives an instance of a message. All supported messages can be found in the `Messages` module. For more information about messages refer to the [protocol specification](https://en.bitcoin.it/wiki/Protocol_specification). An example for requesting other connected nodes to a peers looks like this: ```javascript -var bitcore = require('bitcore'); -var peer = new bitcore.transport.Peer('5.9.85.34'); +var p2p = require('bitcore-p2p') +var Peer = p2p.Peer; +var Messages = p2p.Messages; +var peer = new Peer('5.9.85.34'); peer.on('ready', function() { - var message = new bitcore.transport.Messages.GetAddresses(); + var message = new Messages.GetAddresses(); peer.sendMessage(message); }); diff --git a/docs/pool.md b/docs/pool.md index cbcb4df..610b046 100644 --- a/docs/pool.md +++ b/docs/pool.md @@ -9,9 +9,8 @@ The quickest way to get connected is to run the following: ```javascript -var bitcore = require('bitcore'); -var Pool = bitcore.transport.Pool; -var Networks = bitcore.Networks; +var Pool = require('bitcore-p2p').Pool; +var Networks = require('bitcore').Networks; var pool = new Pool(Networks.livenet); From fc4b23fc03d6ba819543e458de7674310ffd6b7b Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Wed, 21 Jan 2015 12:32:24 -0300 Subject: [PATCH 6/9] Update bitcore version to 0.9 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3bcdcd6..23f08b5 100644 --- a/package.json +++ b/package.json @@ -52,14 +52,14 @@ "url": "https://github.com/bitpay/bitcore-p2p.git" }, "dependencies": { - "bitcore": "^0.8.6", + "bitcore": "^0.9.0", "bufferput": "^0.1.2", "buffers": "^0.1.1", "karma-detect-browsers": "^0.1.3", "socks5-client": "^0.3.6" }, "devDependencies": { - "bitcore-build": "^0.4.2", + "bitcore-build": "^0.5.0", "brfs": "^1.2.0", "chai": "~1.10.0", "gulp": "^3.8.10", From 21bf8f34ff783a27f8ce62611da321f15b6fd197 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Wed, 21 Jan 2015 10:42:32 -0500 Subject: [PATCH 7/9] Fixed issue with block message test - See: https://github.com/bitpay/bitcore/pull/938 --- test/messages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/messages.js b/test/messages.js index 1bdf1d0..0935cf6 100644 --- a/test/messages.js +++ b/test/messages.js @@ -199,7 +199,7 @@ describe('Messages', function() { }); describe('Block', function() { - var blockHex = 'f9beb4d91d0100000100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; + var blockHex = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; var block = new bitcore.Block(new Buffer(blockHex, 'hex')); it('should be able to create instance', function() { From 0ee82a1f099c7834f0f22c38363a6788eb620df0 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Wed, 21 Jan 2015 14:20:26 -0500 Subject: [PATCH 8/9] Fixed a typo in the README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d32c492..3a276e8 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ See [the main bitcore repo](https://github.com/bitpay/bitcore) for more informat ## Getting Started ```sh -npm install bitcore-rpc +npm install bitcore-p2p ``` ```sh -bower install bitcore-rpc +bower install bitcore-p2p ``` In order to connect to the bitcore network, you'll need to know the IP address of at least one node of the network. You can do that by using the known DNS servers. Then, you can connect to it: From 662a12eed3c19fd794c2f30e0984d543e269b023 Mon Sep 17 00:00:00 2001 From: Yemel Jardi Date: Wed, 21 Jan 2015 16:35:08 -0300 Subject: [PATCH 9/9] Square style on coverage badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a276e8..cebb5d0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ P2P Networking capabilities for bitcore [![NPM Package](https://img.shields.io/npm/v/bitcore-p2p.svg?style=flat-square)](https://www.npmjs.org/package/bitcore-p2p) [![Build Status](https://img.shields.io/travis/bitpay/bitcore-p2p.svg?branch=master&style=flat-square)](https://travis-ci.org/bitpay/bitcore-p2p) -[![Coverage Status](https://img.shields.io/coveralls/bitpay/bitcore-p2p.svg)](https://coveralls.io/r/bitpay/bitcore-p2p?branch=master) +[![Coverage Status](https://img.shields.io/coveralls/bitpay/bitcore-p2p.svg?style=flat-square)](https://coveralls.io/r/bitpay/bitcore-p2p?branch=master) bitcore-p2p adds support for connecting to the bitcoin p2p network on node.