From 99bdee676a21b37b9b761d95b8ae5897a730408c Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 1 Dec 2020 13:26:53 +0300 Subject: [PATCH] cli: add tests for `db dump/restore` --- cli/dump_test.go | 64 +++++++++++++++++++++++++++++++++++++ cli/testdata/chain50x2.acc | Bin 0 -> 45771 bytes 2 files changed, 64 insertions(+) create mode 100644 cli/dump_test.go create mode 100644 cli/testdata/chain50x2.acc diff --git a/cli/dump_test.go b/cli/dump_test.go new file mode 100644 index 000000000..64191e129 --- /dev/null +++ b/cli/dump_test.go @@ -0,0 +1,64 @@ +package main + +import ( + "io/ioutil" + "os" + "path" + "testing" + + "github.com/nspcc-dev/neo-go/pkg/config" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" +) + +func TestDBRestore(t *testing.T) { + tmpDir := path.Join(os.TempDir(), "neogo.restoretest") + require.NoError(t, os.Mkdir(tmpDir, os.ModePerm)) + defer os.RemoveAll(tmpDir) + + chainPath := path.Join(tmpDir, "neogotestchain") + cfg, err := config.LoadFile("../config/protocol.unit_testnet.yml") + require.NoError(t, err, "could not load config") + cfg.ApplicationConfiguration.DBConfiguration.Type = "leveldb" + cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath = chainPath + + out, err := yaml.Marshal(cfg) + require.NoError(t, err) + + cfgPath := path.Join(tmpDir, "protocol.unit_testnet.yml") + require.NoError(t, ioutil.WriteFile(cfgPath, out, os.ModePerm)) + + // generated via `go run ./scripts/gendump/main.go --out ./cli/testdata/chain50x2.acc --blocks 50 --txs 2` + const inDump = "./testdata/chain50x2.acc" + e := newExecutor(t, false) + defer e.Close(t) + stateDump := path.Join(tmpDir, "neogo.teststate") + baseArgs := []string{"neo-go", "db", "restore", "--unittest", + "--config-path", tmpDir, "--in", inDump, "--dump", stateDump} + + // First 15 blocks. + e.Run(t, append(baseArgs, "--count", "15")...) + + // Invalid skips. + e.RunWithError(t, append(baseArgs, "--count", "10", "--skip", "14")...) + e.RunWithError(t, append(baseArgs, "--count", "10", "--skip", "16")...) + // Big count. + e.RunWithError(t, append(baseArgs, "--count", "1000", "--skip", "15")...) + + // Continue 15..25 + e.Run(t, append(baseArgs, "--count", "10", "--skip", "15")...) + + // Continue till end. + e.Run(t, append(baseArgs, "--skip", "25")...) + + // Dump and compare. + dumpPath := path.Join(tmpDir, "testdump.acc") + e.Run(t, "neo-go", "db", "dump", "--unittest", + "--config-path", tmpDir, "--out", dumpPath) + + d1, err := ioutil.ReadFile(inDump) + require.NoError(t, err) + d2, err := ioutil.ReadFile(dumpPath) + require.NoError(t, err) + require.Equal(t, d1, d2, "dumps differ") +} diff --git a/cli/testdata/chain50x2.acc b/cli/testdata/chain50x2.acc new file mode 100644 index 0000000000000000000000000000000000000000..6c10dabc4bbb20a3ea17a175d596cabfe737091e GIT binary patch literal 45771 zcmd44byyYQzqbnr2#ZB`cXvs{BBZ-hy1PqSKnVen?nXiok?w9Jq@|@hr4RhJ?(<&z z$a|LiFS#yU7t5Jh^O^5`Kl9AYGqczsARtQaf5G`lUs%#27N25dZ)@?fmQSJ-VJ{u% z=0!c*a;Nq)^Pm6udJA`74f4O1^a8D^&}%zR^VQkKkjL|gf!dcWagY#@s8A4uCG;=< zub&3lXZVBZHK8zIlvNCLd`51O$vQnxNmt!!j~p{%ii08AUudy#e>aqr#WM zu){5+85d%6W;Nbq5!-Pd8u7WvamY*~`4g$?r?>odXk5!??=S0Kv}ltK=B2d?BAaPT zUbhmu-LLP%D*thPyMQ2Dvz^@bEB59HWbE6Uy_r6Lp?1A*$|)bAFYZW6-PMZ=VHEO* z)k2R;-uK`g)bsb6@ds>?G5ws37-Mu6d0}Y<1l=H}L(E0635SmmlV1!sXK&R60#vQc4hSK_@X4J0ktF~haFU@#n$s4xl{s9xo!B6TNLE|0>rMeUlB+O`a&AP5AqyPu?>LG3o=)go$w z#RzmAi>J<9j~VWUN$IGex|85Y@SxHCB%h7wPawS)R+km7`rh!ivjMt)v++&zfij_)w#i}d}$h{3B6rzIQ*NN7WFc5^%BlpXmKxjb! z9~k(@C;sQJ5Pz}%yh7do3;D;QKxiXCK`foZ05M7cPIk;jcU`D(q>%ffM>7-~eM&%# zKh1>E0)%sMGPH9xGj#%DP{O45OL~kIx?T_{4b6|SjBDu63mf_9D04&JS3H6L_*?b1 zz&ljZ-e5R1ae9n^R}iJoa{*B->?>1^x$=`5?k2MxAgFl{;o4s^#5<2Um!ez zfQXd3!Fvkvzpr&enefD`?(tH)#p$#U4&G_Rz_(`qZ>^h#>#xSDpKv3shGpNLSMc`~ z!SFJ7H@&B_iLs)^ezm=f$7MDJ1IoUnKRxBn@DT6T%6(~WhWQdgM~QtDj@c0il3NDF zCFv2+LU@X)T^Ynb$2r_DBzULm%dxwp1&5X{QiN=4ScQRx&PpSmdWKu%483jBZPvw< zQ{6w2Kkd)s1O%~ura#L~_0pILw+mjAn#C%mv*3`=*>a9gNv`%VOP}6cK3lDbPFWz} zl%6D{BAPp=Ttk^Me*eax>~<7hMS z?LBM^KOj)^^4w-|#b5S}D^fYrrqFYbx=Zxk*SwyJ+w~0pE zTeyT+MNoaH!*7NE(?tKN4Tglc8HYryfb=G_Gqg1&<0TVwwRI4+x4UnFja|qX$PA4v z$#}iVEDW73?*Eg;!_?H&gw=$NmD|XKo%NX^mnkdjGcHq8E>1RfE>2SpE;eIhF2iT+ ztoO6pnz~rnn>ds4>iqY@^)2lzT`Uc4EWJ$cC$Kj&b2fD$<7HtWb1-ze|9BTur-#Y) z7|5JVU0j{)Ts$2fR!QC7(uB;1;lG#S;QFv;zvpKCpR@n>bk?Sx_tX7ah=`|)sj!oi zq38d(BsW7F*M~Lv|4#Ggb+~`m)Xmh+TzEeGG04Z8yg=Wjyj}p%9;5PsR2j>0!q`vQ$=`92r5Uzv8_0AX*yT zqpri&F^W8uHkGvZU4+&iRD-6#^O1T3iDhaI!IkJ_UG^2cwlbf}1HQ&nOi={kI59*I zpZn(j;pdyAEVa@>&gswxkbq%X8KCv8DEkAI71hm7GzjYAnWV zPXIwX^8E$P99l0g(|OeV(#)|DZ*}j=4IL)mGgMwTeWVi&4t6CGE`!q{*Q zLe-tKIcadle=o!;?U#7+PqrcdM>p?3M+Wc$|EVd&uh)l~K>oQ6;RON&QY%8IO)a>w z^?`sv;bF`*w;K956|@%MlY3o(7_9l-3=%K6l-GT+mI|=O!bu5t_x`hQf8f+J!FLH0 z3Z`4h7GRGke&HQpVd+r0<2EQSX`Zog_>BQqSyk@20Qq5;cboYXhJt^H4W?)q$~T0P zoGB{*?@nUia|-d$5dIGI`}O}G3}ymVh9QuA_ZkuiU@8w}>98xFy-)@(So0p?$@H5+ zy8Jjw->WFyuZt)F&=)X%hoTC6Z+g#*u#}UW2bX!&J+$~$+l|7_TB}i(uZ>nrnbs{& zNAe3q-N6s`TfqDmZz$#iTFg0z@d8f}kC0IJ3T8?1OJC&b_R>pB2sqj3AHJ@}8TyHY zK*YhcQY;q3+3w}Lki;P^T+Ptdu$CqBOTdRd!D9kO&%Nw~w2FHYRy8kNgWVDBGq#O8 zu$yM#x0%_djAS^=FX{OzcX1Rj@PU)RQ)TIhxOO{(nde;=foDVh$+{j25Tr0wDR55*wY@uY1$6hp4((C}S!5}GT_v|~?H;|XfNrFzbtHAFSiA$HhJnmZ>F zWItcejUNz%?DO(A9mK%%V-c z7uFw>vshy{rR3l0H*7sE{*F8dKBo}>>1_U0FhY?Dh5IALm;E#}fWe(;O~N-X1-ar$?B0Wsx%4m6{MNzDXG zLIw%pKOh&}dOuJ>{zc33TR@$YnbV75vG?Qrm3VN^)a_Mej7$mF*{HJCtRvsVpZLgq zre{nTZyh8hdwRW=t3$MYE7iH1d|jg)(DQ~};i^^kmw*rFO&$~Qx(h;8OhcLxN20Ed zcse}tX^ga3eSTp<_ibpTF{>liAOw^cMWgNVfn<=n-!yiQ@i)C3aV!m{!!H=|POHb+ zKv3)JI>4kJoRkhBC%^CyWwdkZRMs_Lozb5@217HIMqM@sDOWRE(xi|>pj5QD8&|=y zS(6(6nmBRwH(yVsbliX-pCxO-ZuWV8C{q<L5DQuqte(l!;Bi`&fSvN%>1pzFhh`kBr zi!!1X=~G@lAJ5j?Xul>Af^@oaVRxgDV6nCSLO|I25Wn|)zhD3F!D8zufod^J=fWT$ zpy<7&rv&DhUlR&=!KkFD>bpp=s_F6$9CzPprz!=}IG>+5P*sRh`oFAn%x+j43?ze1 zNm*g1dG-pLyJC}nGNM3)&?=435wgM9t^oXCzXfy{r+1S*y43`#sw5C1e}$Xv{L!QW z^v6a{xf#5ZBA3Zp-9?y);j&{Gl_#M>xci)qh626a`2lZ(K>gZy(X(3amw*r3=`jJH z9YWXlkmjl{N+~Dh?vg4`T4sq;y1^@Rx_eXpkUUK*a1^*B9_;BE2u;(t$*&-s7ReIL zG4uz$Cm8ls4p`*?Nxoo~a zX~&DyA75gas>_xG;V^aRs*~7C!(n*HW(o*eS2~BR!~NQXnz4JJ1+}6en*Y2_e5$e_y-vNU##ts_t{L~HF^{`EcJ(?4+fP?N_6 zw5UxZXqR%K>Z=Ug*1G}(hu-JBqTq810r%Izwi)$NX_85_ zKQaITX}cr)?lRB{q~72Kle^V`RC+R-M)!7ku2}YZVxrUWTpj+}_Cvq<&(4@&3dWFr za;8h0-s87Ypu7r1^=N8jG)>JrNOv?-6IenmRPclS7Vr&?ttZW^D95oPj+t$QpWCpP zp(79&wywR}=S5Wr#6nV5?~61-qT}6<<+DAoC{jo(-N&mbaiM;2tO-%_ULyj@}99jOjmT)CFonyD}l)R;tKjuY0-h^5kfEj-AlG)(U1Vyr@1uK0%1ep+l!i@L7e zLQS^vqO>Q4HrBGwYidH&joy|Iab9d1f}2pb7zm=IncPe3B`Q{nBW5@?EAjtPI+j9g zWV?$7<>Q3#O8bK;rC2N>%QiM)D=prNmD)S;Z}_s`fsBnOQwee0pZuc#bphf3!0AIx z9v3i~_a=)V^=em-0|+2x%3%7TID z^XOiOCkxxP-=BI2LJ8%vzNzFt4wLdI7>@n+7AqcgMezcbMKNCld`=+%e;q8Ug|#Q^ zhSvUh6%a7-oFv%A>WY<%8N6UqQ8ZY$9UR8cbROC8fvJ@)e`3ewpoYm1HIs7~^8j7~1?GrBXZk>5)Qz#GXkS2eb^RvzG zJExbD=&bTxg$-~f#vwmUIQB3P$=S-P@)|aiRPhITfuLuvpBx2(a&|MN=0M*T7K=sr zaQf9_mw0t{!fyk!gQ9C|vf=|57$ySEd@-fd7^tj9;ZKpemge!oI(KqI@sr$ z=Y`UG3v<}rKtO_a;N0iP*Bk*$-~|K4Pi3B+qHH4LHd}u9iE3<5X3$P@j4*^fc*$(Y zPv+{Zv-O2lcXkl4^UOu>y)~<@+Qu`n4wFl_iFWkUtUVz3!F~&vxr17Jf~~x2*3dU@ zj@{|F;r=r$0HNCiD=m?JWQ?6K%>1HZW-JFjTAuKNUTN`!90Mp@(f>$V&~K1M}WRJ{Dh zvmHX3^JW$~cL{VP<VO6ROiZ3hUlEV^T3|jnR6>5SMB-l; z5b+P3KGfuK0lnvnKk-$1jntt70pElIPh-}+3u{fmAMN~*Gbrgdi2w9 z^l9*1I=U-5<%WBlnsy@%0t_>JZmU|OfyDAJInN3eUTw*FdA|j`rNCdwSCa;xQwXHL z4o2P^(`l0;COdru1gxRSNMv0YTL$ES7wnyVVUpUQxOK-#&u9OPu*-<0u(-wRMxf^8 z*Y^`#Woeu}pP%2t@*ddDa=bTh-Gk{@L3zQ-q=%geDUP4+$L0opu-^hgCMPfvI}Gxh zzErE4?_u*Gf!7yDI&k!W>P*!i8Z*>&xzSA`ztxjU$_`!=xL(NpVb}&W&?}U328AHV zQq)GO^h>~pp2A}S2463f&9u`cvN+3Oo$9_RJj{cIB2ytIgq#~vXyA{1>u_$c1Cf-u#{2?UWo8T99Q@2d*c(#E5`&}^qZ+s8*qTc;te zQnif?pHjavM0%Y3BdQ!J^6g#=eb6lGwF0A#Zq__@2=N0e)USra?|)f#(aZwxs0wC%`8CbW+p3=;M7fkc$BkFLOWr$&{HgG2096)?orl7F# zv65`2FLwIJ@&>#PSNUnOJ`DpXZ?ZS_stZPI7JV_iAWpbJ^5>BsaF2Wda5AK{0LsLA63{^;(eT4LTN;WgbM~ ze8s@npo*UiOzJGxXC>-w?xSwSKFJ$g?{N)+m41{%fn+Nw3QVsGX%J~C=nSPIRT5T_ z)WPQz0`0GZwQJm-JBf5N8Fc~yRzt(FgHYu-X&B%I%grg=VKMK1!~Oob<$CS@K{@l3 z;&rrdjty_W)7uuD>h#JwwL<0qY=82VJf+NeV_xXWPopVNTyU!6@F&^2CEy49Eg%K= z&DvRj;(!cdXrhwQS9ymTs|^HIc@{=xKU>||49n$t0csI=)s5v2Cm4&=Ql6ywL%x&u zi};ydEgi41rsY+B3HZ=ee@wuvAG}LuQy7s9E0lVOb~4*#)Sg4RlnAyAlQ%;05jB{l zY1BRKTAZ&`l$a6)cR8JTvu!WzWN8U0_V_7f@FY5cpjTb9kXH4f1(YaZ|rvCW##3PHL7w0*CZTY6CH|`0C703FBal&YM>n0H7wVgMI z$=_n9TTjl~zQfU8B^eI;9JY|gr*sKD#lK5Yok1bQckC6ET9#EmpxPw# zNA>oZlN+|~zb+v9A2@xe$>Rc+@MPFRe#GY>x&{KcxEcF>)mQB6kHF)!1obO>Y8gkI z#F;B}-yB@auuP|WVQIi!leuhaSpM3_I1QrUiZgvKE~(96Ju&{yZvJ}Tqv*_o;a~`4 zRII`f@HvIR`0HR5G7~0RyaG%T2ta`6x7bDkY7b+Zjo#hb?Cds#Ssc&I#Rx_#ID4$MI`@@Pqvp zZ~_&{@@2MCcVP(SkKM@%mbrZMtBTjpKV6S!Qv`nbGNh(37eeUw?t{O>6YupHc}EFV zmdMoiyNc8zqB+Ud^R=qK1bjFKc}&2cv9&m_Uisn5=-J_aY_Aw&pygLmv1=w58BBra zx3dfDiS~`$1ga_PX~=8V9)r7G8K-`QWeo`*tvx2<`B5~pqtBZH69)t!XG%p9C2jN!34_P!6d~o8 zwI5WlpA;n12llHb$~ zSEQ{S!{PQMHmD76S;2>krC2}dDe!0bSrQu~;jAt6*iy3__l3T|r&e4IR}4DWwFE{p z@Pqvpu;OUN%dtyhM_vPJeoWlOx1ev!$*E&3@8iTXImzbS3Ra;7tJJyy9{GAAW*=?h z!h+@79U-F7?XEKCMN?GM3AJAWJ{&7QCZGiBYG>5o!91%!qX zW#sQSN*ngX{4B>l;rJgfk=h$W+HszZmKw~lUKH|nlb)m8*4>YUfhRIb7aA zdjwDjGl`fzyYYJT72%iMMY@HvIR`Rib1Cg9E>F{6FLYsqclkl`%Ua#9c6@`PEQ zQI0?;|0B>(G^S+`hP%hmhhrj4oZ4sahHCvfg19laT&nmSx~Vl27NUWmITiFUlE@x$ z`h#u$WogEDVml%M`4_9kny%TXZQZ7rej@|0NV0qAd_R{))$~Ax5q67OMLupbuV5;D zEAIAYfuJ`&P}f`2pKpJZLNCKwywc>pSRnul|M7GjT zPTFOOUl)QO?6-i+Ypq!gRUTBnjCYAgm~g%&H8Zgl-F$apyHuJVc_DL;&ODB}lTBDf zkkbPs;Iy69S#WLSM zL&6G)NeqGWFm`;Oe?>4bb?+MOAgvTW#oN&1{4= zlP!n;&5Rcs2nv6(OgOpsypK}R!-{KKWrFXSy6nru?|O$TuT!kC(0N72S6QxZXV6=& zw*AHfJw!!YRv9TPie5ZvPSi`i<$3q73yA**P9JLWxPZD?Fj6;V!MZm0oZ>4vY_%1X z22KZq$7uyhvMv90z8rwkb4!z{&am;r8?D?ChGqi)rP(jc{(GalI&mnq3kXjSvJgIf z>$eddzM3Ou^xF|;rJXOoq)!K*QwV~;4i?fumEyuPiTgwd2!O2iK14c_})B@j;`ii39sWiz4<49vzm zC;3!d1?hw~ZCwroy>_XWFQ%NNCSp=MiME>A>aj=LpQ&DFSI=^b@58$2Mxk`6yXgoJAWY)mWin#p9Fpx zMMRKSyn$VyyrWc2k@tRLaZFr@3HY2s5dC$qvUBW_uTxrLiuXg&%;>qpbxXXIF`k1L zY$sR~*+^5Fq`)YEZVA#{9N5-F_H#p~p^*>DsIbrcI}B38cf=)fC^Tt2NnWO?o8+?t z>j=XSSzL~dMI9+95a0*L32#S*C?W`MvZ_8Nvedxu2u**HBfil3CE&x^;>QFW3u3!M+>!@5+&P?w z3nXE7I0)lRH-}bkT2MfwjC@E2d~u{`%gDGL-mOM0Gs!PALt39FB6;g{^=&!i$JE&U zP&6NfT=99YaX&F4Nm;7}^OcFzUh~%1&t6Iz$e3%YXjkM`c00FbE#Sk_NmWCzHK!vl zAF;h!E56%EEwpG%gt)&4+4Y;nr5TstRhYGS9glhk!3X;)3-TyZiszPA^k^BR=$D=R z)385;NH+@wo`|an;Rxuu1SagR(9iE9pEf4*bNuT9690kIhnhStAeBFL@Nw#yyzo;X z;Pqe*vg`XLmG(@Q*AobHD{z;gn{pc~ zXWfWoB4$rOc`LZuTP#nbsD7vlTI1X#wSdnl1j%0qi)<$yM9$#SykZ3ce0)*e%v?iy zA}GKUFsoGHLR-yw{2R_T#Z~wep#&~DH66CriyjJlh2l_n$Et4J9o3$2bMq@Gfn(RX zuisDMju96E5|N8z!$Lx#y1@_jTfl>Qp&sg)tn?ywzh|z9-H>zCu~v6i?LZ zZK8U!6+-*vX%1sLYD4!<6e~qat3-XX+%N;3SXd?s&7!n_3HWdt{4oLB7MP}s{Z#Sf zTt+3f(=azEFVrcbv)u82K9P`Y*r7*t(Baf7%=7Vw)Inol{62u8U+uApl*SmojR>R} z)YjAnf(jkd;}q@q<+xjK!akp)1jA!&zF?$!(KR~6)X6|>jheOAB-C0Epg=&Ro8Vgx z5L$Cq4Ny!3@pNtxDBxbH72WRvj~x%b2)HDr5_(!xc67a*^gT*kNpzpT9hxv|T}dTi zOML24gRRTXS3sn>6 z+%W$3GdXy{@_XS)_}CW)bTc>`59BV7O8mnpTHoR(=ewk7M}=Nc`Z*MDVweS*_RsdH zQ3(PW??@AoE8$q<(p>i$=0K3F;0OCH;Ox%ue0tvc<`X(?tmBz7-3CcdRg0w*;j85D z8r?zOGrC9~Vgg}~?0jLsIY$D8NV`BZ+n2~`^n)uTcq{eip*p_=e7Icmn1H-g8S3X} zCzyoahPzCu2BGxuUkmYQfeC6if;=wQy}ZSzj5 zf1hhGl1$|wq-ekYOXLj#AZL6h`TdhyXxhIFlq8e73^_GQT;Ig>pNta(YhO%a@al_{=%yUl)-451c;K7OOrS7VCk1LzF=x`2rP_ zjn3V9(p@fNphG4DCnH&-qS|5~4~~D;5!)G>s55IH_?$ve{B^L`wq5ev9)hBPe$|@`O@d(Ef9vH7ez4yHVp)AeMLlZeslPt8!dE^W-_P6q(LxwS z&;%Db=j?CiDMS)2y^t|i+{>8$mD1_GI-ORc= zVWc}(kA8?uP6h&qq1S{+bzP&0DKAq8a54t}uT0+t)=uYbzHpOk~;cg$r9aS)ar zkf~Eb(NmTX9qUFi!#3T&IY5SvnRF6l3bVRlhHb+b+KhYt@!r9;~btNE{?EYKg??oR(qnQsU|h zv4~Xcfw^@XuRbUKHVkuP2313TsZgWdG8r&x@Lu85?~^3ta8YiSaZ=&*ynL&iNKe&2 z*-yfF&_6B5P885NiJE55L4{qu+h!5d&aqB$%kmb^cgVyi5K(`Tj92xq3rPJ3P9JLW zxPU{BN~-2S+JSW~gyd8hFaD zc}^{&lpZNqFN1RZHcILiVB@)oqXQ8S)t*Wf=8nadZnhRUeC`51rw}xM9gGN#AQ6XB zU9lq*2zc@m${7y*}kHghs^0W0Q`tP8JN zt;*&GzXYVkf5sm5-OX~SjE9A$%rNDgzADsJO!$i-KEDM#PdMwxD#xeYJnDa~%d;a< zJSE9OCT3_OG?k)>a*NxO=nn~3LIX(xy%8GD1hb#7x+>@+UzsP_f5x)kl7rg#;+KFA z7lI!XFlZz#B52)BRc{!8kHngCz6lLXu3N}}JD?G5M4MTnCQpuhk@K1n^n{$Gl_pi1 zqrnS8JSG8mD?_<~Osg<+2ncHaYfsQKwtB2{9&T7CJK~R{oure z=%H;0+HD}V5=`uSAP%=bCN668*(HOxt%i_tim(> zUjjZ1Sa?i8$DzeTzS$%tS+r`mDJjZg#c7E(*DEEiot-1dd>NM?!ql8t)7J6hoE}f` z@3xjc_}0?t+1T*8kfn_fw7?X(-#-NCReq;+(qy!b2*SmaFPYMBye4sSZ(=|14(MuT z;IN3|X$V^cnw+eX5iXDjl8Cyt4xT$_*BT_@jNL3|d>eZQ1iii5=I8#{5_DZW6$x~+ z7(mm&k^b;mTX9I`G|lOGUa_vvV8+xY$Vr(Xi%ZUwoXlfi$o5POd*rS}6#_uZr~a=C zNdE^;A8PWrfJoyLm*F@ULo&-ifUjVh+A?sCkiZ2zPSrRCaI(I~xM6(9B$cw9`LZOg zCi}T;LgY$;3a;kK^ST0>@%l7hLA`!>v400gh)bF>&}jLe25u1yj)4!^VNl*jUL#*Fkl(R(JO`>FXSK*!0;p zlHw{cL!s&zVUie=dncd|B_oz1)%7GYx~(o~R9Ctq9rgyG^}iU5ZCzKc;bGr)ik3o6 zaer{cx9MNzqlD2tP9vU3Yxupx@ruadz^(Gz^C3wW<7jsbB7b&QQKVy&4Bu%g-Rl^r zJ%e8YK8(b8OhCExC%1__WXzufvc_41EA0&+35D8Zj?spQqPW5e1XS~AP>ljX{Bx~zXF6Qb2D-Q^u-pF3))*_Eu_QuICM+B) z_6&}yJA;gbO5*6At)dtotOjDIKMi-HWF8yWQFI^N^XWn-xPLa|7vImA+*-)k0^;Lh zBdOdKxbxL%TDK+w>;)+M^i$d;*YP55n&UDw8)?26-7XE!rl=)A)D%%kEteQ)+9O*3 zx`2#-;Pjy;j|)gytXmC%AYKu2|453rQuAuK*vPf=+Td|oMZjJ+HEdhly{tERJ^{)L z^+vmFtQEqh|BL`(?AhHJDgAb0DagtC=X?rU4t_PUvG^xhF)t2r-xB-`qp_W&zYvh= zuY;LpxxuZp&3vHN00M>=raTnh9Wty*IFhNCSxyL zfv!0@k*gaaC99@A1ggwyW8!RHh|peMZKC{SFYX+;jcMm4;vz%A5B7Tx$ag1K-@N?! zyj3%+sg6eKxhI)t`~GC#=`7uqF5^Yq%gtO7{@OWV63KYmJ3nFRDrZLn$o#w-KXjA6 zPe%dh+=jmdd>AqGn1H4l+)N`i0)<9nMk0FV!|9EYvY>S2gKoSCMMc zg!&eCIouNi*sagzz9JQ6-+^SV-!<6n)G`1;<^fX2I#tBFVz3uEa^XllG^FFYIkY>h zsO)hnQHK-9a`CbPQbIWhbbO!DsM0B4Mso`b7P7*oJk2P=s}v3I0fI0=F#DLOH?bNq z#BAx;2gCwd)@ICe+HXwj8;|CT1E_!c*P0Sc(fCAm!j^d1uJ^P?iyqDxH+ zrw}ZE9V}IDfV*u$QmBp;2&i#{dUCZ9)Za)1o`CN>-dc&_ju;7%z?II69O}^zsEW-+ zBknXJ9p40h%6L6_wp=-=)}_LKV`JMHNF=Zxl`LFTG#@)6?pIlj`fLyUV7~>tZu$;2 z*Y4+Z=3L3AdsTH3bR7-QCy~Xub=Yd^)lTRvq;K4ms)NnL>Z-2P(>sjvTv0_PSnD@L zoQ4Wzz8+mS`X%7QP^iZQBsD$dfL}=x3jJJ=Li}p@l|=zj=2b7(5@cRw>pVp!ne73r z3CvlR!M9Gjb@BaS&p6*`OL#a?njC3=jmZhxMKAXr>6na{eWnmfYf9&Ceew zH#diXnw&2d*e4zg2Lr1t(3biIgewdFRl2f)nGFsvx7%(%W~=0&t%j5VLE3^^)@9hs zD`-#9K1=(_5aBsc|2)F~_(4biJh+!?@0%qN?uB|fZ%#-t$!W9zzxii;$8Gd4T_fbt47X_Et z25jJS3c>c*!Ir~z-fNNuQ|55rUx>$MPp!%%R8MpSPr%rZ+qOe7#456gu#=bW#pxbh{*K>M$q-+TtgN^nRZUs7g4_A8K9@#39RhBcymuoh?u)g~ zzQe!Dq-Ms_{zzo}OTdRAdyfg&8RAK{w|3&)>Y0~a{X8MDtDDKz1uLqN&Eu>?|27C4 zdS_+|W`0_h?WjK0JKr^0r{wOIJ}%?=P$1Xj%d4A^`=Qib{h;f91J7@sa$8rm%3ix% zhVHj_s#!?n{t2Wu4>tcDQ4oOP!~u$z5%>_n+fJ|mO5igpcyHjk6i4SzL&)EIk(_$xup6S zZ*onm-ZuSt`Ck{1{STZz)Z}pi6AZ3!(Uub@D}sQ4TV7+c&n==q>rg zEk=3Yjg^u2G~b>L?x3~V`qqx>&8U@j0|%>2h=78_%bG8rvyNy}${<)4le6(gj9v7u@6Mf}U z-pSCb)8rz$z)AZVy@|HPb(O!<%qtPiuB1@QNAGW#o!~@xgCFeo z9+1*gyM`U5%-=SgRO@4A@#2z0!*s0b)PBJW~0v< zU!8b-sMCr5oBIKu{dF)>fmapl5r?J30zd%aj_a8nJolR?z2F5qSR7t@cCl`!khVjn zc|rJ&5W8(SCpt*YA@!1%QQR1zy#anXE-H;0Ym4w_>3mvR8}&8IY%X(o)-r51awZM; z-wSwSHSkJKu3H2bdJ+~v#TuIq@`xz3ohWV$9eppmf!?Tm%}_Ie`==1(3Mbys6P}R} z_FCaHsqr0chLy56@_d=5zXW_3Gy9l;{2#-TA?T7DzAAIf$@|uH7Xs5km!h~f??>jy z)W_|iW^mKq?({YFFrMjs=RulCTFkL#!rGz&)*f(3<#4F-z4~7lkn0beKGfuK0qH(P&j_z>I=g${KN%afqN;|Ed9m0KJWg}G zioMjMhz-0XC_!l;QokNb-t63V77GgXfo;s`9QnGX0zylMyEm#+R|6wX?_LLOYd1v7 z6Mxy0CPRq-Or--prx4tK9gI}8;R{KOh$;#f5O8ElN~mJ=>8->mc){@GC_cEYQDoJA zop}bAiyTQ@s58CnNCB$1xEex<;`b=B&H5<_X#Ad(soqT7ztBALqJnV_O;(Zy-E;XE zUSbsdV88c(wXP0nIwO#`iUpkede-8L>VX~>L9X%+DnAkw)&z|-I|Rgb5~Ng`dPB01 z0+)+H`sQVCo-NVkyqe-%dRLFYYW7ROhrz&)37G0NDBcbC>}u`1RjeIi9rDk$3pV3? z#XX4x(zNTi329{B9rt8YM@?w-N)nF?=aj-j0~}4u*1F}!xXa^Wm-`3vmd_b^Z*9DI z|E<-8^eNQD58>*T7rD?u#mjjJD;y+)5Fiilb8R6E51VUUl)+)51c;Ko95P_|7t)+k8?I2)BrB69G%Ln75Pnqj2&1l<^oB^7>?Dk| zU-fgD$D8Osq|Wg;lxtm=SL>e2*>aix5|HG6J3S`g0kM`|aWvP>vXQC}S+t3erja`I zp)%8ky`Zg!V87CO+e+)eqAnNRm#CK(lu>zI^q`gC5Gq@O9NCF4D^1BXQz$AA%aqObSQF5;sMsm312 zuT24uQ?$y2@j<4E>Ir9T{F5(SiLjj8y3j3=FgRQJsi|LKAr<2{s%(m-y49t!grp9S zxxA;0%!s?qUpv3jo329A9{LLb`TsiD`#s=X+BhnUMLZA?9w*KD7Jzh969ir`X0Ee# z8Yn9nRD-~6+Msk9ePj9;!M%>yp2vH%2X8l7@*Q#pQmP3I-8?PQn@qeXu0m%kSJ~S= z-=@dih}Z$(!4LL(4=9BGh5lWdi#3~hLWVF(x*#Oaa#+oRvB#>}6>9?Y>Mq&QG%r-y zOyoLjEaNbXeeEmiUeX-)S<-CkStFrzcXA;-k!Z#(Z2>CRkpveliBbQAetfr|xQByCB_AY*a0#|!3iOM^UZGEK8g#zTtFkWD9jUGRUIsZ09SSlGKNqWX;iZjj zuu-^-^OoxEpiqqr@vD(Tz!A?3U-!BD*9H8~_agm|?}m7&$>Rd9pU@ea!W76MDgXg) z0eBEq*cXacU%}%v;0Tunou~@-h)Y2slCyK(NKi`~C&X-}a%gzhcR7@sf%ftoiP>@U zqmPpa495PP^Curo3sNH_crv71Y(Wzn?T&pmzKjcp1fobxxBY&avO3zrX4unw(=R%l_ zDeao^J(-T^^@|MKJ~sb)K}sR;gZ&op1Jwbw=aiTBdW`QE=kOhl0YaH(UdQ{f3mb)f>p}*U$nF;x?D|f?@Rtoeu+GqAx_z>|d;(g{r@!~=&kLVol zKN(FJzP}wwf4gUqU#t$(N*B-McDGgev`4Bqm!SfFp+wB}l*4CPp0y>WwsfTwFXHXm zm|V5OzSz;L=gyp7GQ-{3G2!BAK#={w3Q8vG>PU)nq=9W!ECV9Pct-Nf51lLjH=pB? z`(}=Nhz<+C-s0#vB{c-3YDOw8LtW;PZk!w+ho+c8riA|M0t)?s(}$WoE?~Ks zKG@ML_$xEswqnSP{yWmu)(ewsO5{~q{?2qOuM6-wg#i6^FiH6*V;Qu*-9K#ayP!p; z+WQT+H*j6x1+zaCxnuT)HsT(BNkKR*{t{CTnp~$XCh5UqEnHy1E3f!P>%q1dFUpz?55}WTQgX;FIoK(@Zolt#{?`fPX4T1 z=^#%~di@jdGw4hxcOs2x#SQ}tTEo(ZE)n`TEjGZ^D=9+vIp*hP?Eua)UPK*!NW6r@ z26I1k^|)8}U+JsxR1Ld_4b?rUs?_5w)hY4GJXB_TM&PBn%4t7YYQ5K0g{^OUJ?`n( zxdpwo3@t%1v37$-ND07ehux?-$37saiJ;t4TWDzP$w+YBQCF?f3Oo~vp}zExEBjVm z?GEE2Gj$To1iRgPL;1@S9XfVr{&W`ni5`8>sR6YcW12egzb>HgA2@xe$>RdHTYgL? zI{Nwy?+ysC>m!mt2q&X>?G7HN?u`CA>$c>YzCuN-z0BVb zC2A;+R(V3LN=r+3zc8ckCz)Bk`6nE6oyR`A``p)gf8|V2d;k^^m$GjE>BBTT(R~L2 zp?3zWR(k#Bjc%8g+V!>LG7SyfY_srzrI4hp%OHCx{~YJ^D1MlI_QHv9TK8Nk zLF~a^Mp&ql)oKa`k(=GhVMYLbdU%3eYb#nh85f$ow2gfD{0pZ8ANaxkJOOF$cY|KB2MWT#%nx)xKl&C06hlC$LQ>ioD`@uKb`z~G)`c=9DH*Zu8*M*Zs#hlc1yl8_d6G#zxPb)GkRW zxJ7WF_g@!K67QSLmUVmJ+05b5=Pe*OMf72 z0@T@>jW#ah7t3GcY|wJ{r|85m*BW3U>-*6BXcMDqMQLrsec*ll_qviT_`&`N7~J$s zZbI}LXE?E2)@Ma(FHUYzRF&C1FN=+8ZoZTXe_3+D=E{M4Y=}?i)IbE-Sz85Vs z`+U*_g%&e9R6am(bLlFo?R}>;ACD#z(SWHT5e|6K?T8F#=K!9!};Nby*(LTd7q4V8_lp8~1BTaB_b& z@yj+7{+t5D?+gaRqh0PD4RAca-m{9{9l%Bu8Hjb?gAeRiN~pf(hYEAfjyX>5l$X73 zrX$@$D1)1iK6F^D5tZ~0UZqJi3q{V)p?pVpN|{s4kV5>PX|fnU%;eXiw`V&y%FFC!L$?XD)CUHSqYZOt-B|yMq+JMDw@W}Le9(*~?Q<~#X zG}rVrcx&bRF2L^5%TdFHGvSuw%@nKLDG|S~4U(^tilTDanvM^}w8Py%%>xm8z(xM+ z5@yvwLQOq0_;U)7yfc`_w_OIYs$!H;U98y7V4M!JRIrzYob*Q-8H^d)idPX)6 z=*}y(yv8s*(*KqbG5k?**FK7?VSTCPpksu`tK2eb?l6ErpG*DAVutP33E{*D8Uo1} z{9u0s1jGU9Sc+n*41yUvB*z6R(!Mbnhe&$=vOO&R^!3|@UEYqkw-^!|Hba+mm+e4@ zlI>c}q)?z=zDa1DQ|Kj8n$>RsZx%vt6VQy$&NNux;%p6;gd1-T%JA}px))?|yyjQx zrgi8Umu5YRqx~?ZG_2Pp94Q+t5U_*qMM+zoOwHm_fzpee>kER&ZMQeIk~uK)c_};J z@1Lv@j`* zg47r?msJb$cb{-imi82ze^oTLBeG7b8B9H>4pLc|8lQiRE_Y@2h*nGpoY4U-FK2sp zg7}|h_X^&s0gb#qezetBMBB7_c6-EC_N(f$nQP0nvI zTsqpyGs>;hNhQ_8ADzP98Ijl^dtpVz<4@vfFqFibzHOId3t8XO=^cQ8o!2TEY4?-e zY;+@DN4{1juX_c5P65()1`|2Y1&F^XD(t#m^$%2`C+xJy{ECeNpMbP5iPc?VspwNK zKa9t55s3J`&<{D*YU1GMoq_5fvh#$n-`C9OF$snCuMl!L_y0_^4+ns{2NI{HD2gb> zaeUzi`y*f$as?_@3zr#8t|sOFXMDpR^yp>eBP^pct|6ZyF0_FnZ45yt-Z$cOCSzVkGl`QOv+dQ74iO~c2tV7l{^ z;`_w2*pg2sRKw_7sYrg4rl`i$E?JQG8lezUzZd&SXH=HYBDAObWI>Rn`e!K7E?T9T zvU@;f*pC<~B67z664DXR-^{Iz16_g5xhgRSOhf8N1Wni?P`P8Zm=~`L;(dSJ>l@x+ zUq$(R{Ux?gQa~x)HQ#ktpVWEd?XX9`LZxJq1^V^}mr~i7btf(y3#?{z>ZZpj(gH7n zIJklqWKx(kWTm*n1grN1$_f5;0cHM@)0>&xE?{|5ds=DLI~Ty0>%-XSYxR{0>a*u0 z@a5Fl@bgE^Bj|l+%E=8|L@-*TrS-ZM%{=>2wbO)5>vloT64u~>Q|O^Q=T&QEd`KUU zHL~u$$jfMrPA}JcJeXCb8 zeebEw9!RbJtmo{9w;Y!&bw!ExaWCsmABPeZG(+hjfI)}QlgFi!zlPpzk}2du8pS%M zP1J_?y3Za&@!!{WEWP?SM*}r_67zIiLJQ&X&p8(en+ji-Z41;L;EA9MM~mKf{v#k7 z%F7Axk9H1MqJhw^Y&-;G;j2{~+i^^0`*7k)ry%bv?t6LTI!`HDJNQ3m;(ua}+7?9( z9>H!c5DF8OSUGF6{w?6mM)qw2$`mt(e~bY|?s7KvnGgd?!ZcTWb z3rmhaZx!nmX+qqRnq9|i5?N!8p9fR)OF^H)f_Z=O);Un5Sxm19gZ)S44fJ*cU_Cz&>J`xuo;H*wJs6zS0I-W6n0^;CSi9Xe| z4ovRy)+{AMxY!Lie@XH2qKq$6t->Kn|Hwv8zC4xfj8dSVSE^WIXlZcmp&KO1-Jog< zNAyw|RS5o^0_5)u76MvE2U^1D5k^74`)B{TbLcYni}t_=mhh=3#yX`62IPNBr09## z!5#LN>Xo~8uQxU8_LW8fH6`}!%8wr!+!jpTa^D4(^v|1KvkLko{Fh?CwOCUsI|@J8 z9|86GL`WGts|a%h?YxYsdvSF%a#<_PGS9!@w6N4oa|NrN(TV+V+R%fYo|GuMFhm4Q z86}>w@X3Xy3h}pOOeWa;7VxGy;5Gr}AKtsSkno&{M)EyMLC+`qO+N%hYfN>+%kv<` z`flyw;SSw$d|tZ%7WJCbfvUpC@2rVUS4&J7TiHY3w6IOpgCN4W({wGrLNrVA9$|`* zX^;;wjJ{}T1>oo^0~u7}MkF~@tO=VH?6aAVEo$0T@HmW(=(~M06n>JdBH<#%qmhFk z>Ye!g9pghi__UGvhc7eZuA0`}br$;H_8KGN?Fnohmyd|Ck!1}v@SN%k)=OJ5)6Tuw zs%;^+7f^K=ICCVk_>@#Yc`3bT2?abDg*rX%2U`$8a7+qYQf6Z`L8s&QH{T z;?{;9r`8blA2^wn995ik6$jx+$@4{S`UdW*+MES;Y_b*2p22~Hqs+Ulx4h@obIl{m zc<_V$UqFUP6A%!B&hBokjI$s_Fs9J1COvSlQc($2xJOvN zioUEhc2N(K5%n^^v@`x9g!PK%kt<|7nKSU6Y2Plk^}S99-RnwwJ;@*9BDiOHOZQa=U=fi-{71*Q$DsqZw9hVx zl?P6VO0R5^Jz8%Nr?zxDODLTR8GkOq7_q zEl^mfil8pfFxuDT$(5*s5^55)GH%=@FI%JuQ4rGdF~^iq3~lHH_jRo<%?c~XF92OB zrzNz6P%P3ja}ztx&3%kBO{=t7=v4EQP;#@5f!i3>vkfE3G>`70Y_*zPg|7GZlL{Fl zE$xN>UDrBUq=yB6SBB1{AAD+@nl9ka(ANxW+6|xo#es*~b7i{hf3F)GDHl&l``pyO zPC+=E@*DU`S4eBhmwCYsA1KYgE}+U^a(Xk9+XXbf)$dilcsaHxs^5iQMs)ZI7zq#I@<13}3X%MuO{sL$92=VkvP71VH zg3n{Mr1RMVtRGP#Nz*XyAfW1Di7%DgHjf zHP>%$6Wlhmp1QENf08Chb_yR=wXzFDxAwSq*_N*$0IGe3+2G)@8 zOsE>)^^16xO2XjjB&BkldWgIOvK$T);~UjPg4r(ENnLCKqOi+URbkD{NWa*us(OpS&*SEnI{uPtD`a$ifE}@%|Ii zR>vM0m_X>XgqoMyTvIV-JyE?sjVQKDY6_MOhKY*3`0+Com6POHVm!5poVF=&-;PWA z5R0%pwup%hey~3RGCW`mTxgndJinl;5{4Kcg(R2bwyl{V1Jn0rRKfnI19U>l`MVo_AZ5iiq&4Yx}D)v6vBLw`H z_TQFjtirF~1Fls*Y*p4PoiKemep&NtsqEfqe7+~!z);!y zwi1l0q^YXoG|Ff@Q|VpgCH@T7f^~l2-e_914>#0| z(2(IgiZ(u{@5emJv(RfQeNH8jE4zh>>S>?aT+yKPl4*aceV{YT{&U<+#;P9^*tij6 zWYZg;w0xYbpp3YfNjmI{(0BNA3edPS*ld}|fztp%v40^5SXO$x-yJ7iCP4t7fE>A= zp*m9Gs`5J{Wi3;$S)03Ly}x%QeEno0hSq7swP--c`rnDR9irC-bl9!v)bC6H0Q0PM zdbJSz!nu`;4Gcfn9|6aZKYp=r8j3>DN&$ob=r`;g*F}olK4ywC;8s8%?k_En^+pv` zs5oFK7x4OplUqVh{Ze3MgRa|H#?3|=Gy{&m1-vN*x=p~RO}OI!OW{9u=x6lL^x*qJ28UKzIE763&g1>JVcXKz!{f6<_JI@rxmKK7Fu=GY^(lCcH!1TF!T%@Srzl*rAkCf;^#3JAr0 z3Vq7Km$D|oW3>!|u(_2c#7Ps3dwB`yBB^vKNr0g|B-vEp{P#~SRYkWZbzufeW74i# zXUq!(Co8FA&o39+0#(7z#+oBVwdzCZ zY^xDf%0^k$$p5s~k!1Y4CPEOLPpsQt9asN?lsf$u@TR=#HUaA+CF-}@1O)xO94Kod z@abTX_wMiUdr<|cK}_~r)vUJVp`@yPxgS#Hem2pLv~M=)tEe~e;cA^Zw9n?tOiN!s z0Y9OojG)&9+X_D}5s1JVLO~NATVaUbP&T9R*(-wjZ?61$8(|=A{$Mj_B;LaK`&VGP zPTbzu3VGC|jbiBiAQ0qj6U?Y*RLee%Duk+juyad)>oxe1(mb1X(T7_02g8dwQzOc$ zuT+?|f9V0#%RpA7L;k+{l(zL_$YZKOA=Ksnx`0}L$?45ZZWqwy$+?SUuvO8>#?Hn=M?b#&S1n12TQy^6-gPQKtL82*WJyqyp#eB z_`s^vi0SQMh-zSuoJ>b%bX->*(~r6Wz$%x-w>fL8qN8p*GF1SW!X$;e(Rj$JQe!O- z*%)zG{*NP42-?w;;VbyT{s?&4YFutuh4Ha%2f=!FHAcA`trt)acB4y3`;x<*2W6VA ztre88`al}xoZxCK-$iWbVAr0|MjDvKA}X%mGuN?4Ee_B+ zmM0_(&WnxtHBwwS@ijO{r7DYu+z#ty96dv2?Sq+oiLDwmZuQ}|SLJ9;!TAnRvbgHg zAP9l3faZGo#dgyr?fh~z+jufkRE9VCCf0~Gqv>-FKV+Bi5;L&sxw0aHCE5Ou5zU_s z8&H0)sm6!MGt>8rHuXS|2Xv#^7y%yXkKH$l)qS}f9HCBK`6^9QLhj?FG#?AzjrAA3 zC5RTP!1Ru`GCB)mKACqcuuUolipG7z#hK#e{MQB4{!318W^%iLks>zRMn*a4S&Sgy zqZ4Ova|Clu0i4zJh@59Xy<7WYCn=WFgX9ZqM_`Z>@^mUAL?l+DH4q=L?&QWInn}IUs!;ST+9$&oQfqaD5h?Tw{w~!LW#YwNFdiPKPT~CW zQ^WmH{nGCfO;;)(26*mJc=|`c_&QrAtf1y4?wyOSnkTXCk;Fu*0dG97?`>xl)G?dl zT8(r2@-9?35VOwQuQ>jsdDzn_I#enou>yh10r$K$(dD;*H|=q^2?+i9B!|;4w`djf zQzDA%s}eNM51Xc&p!n94P~(-!+<5E@VtR#=fpzv(b+?YUR}gL!$qta@2A7W ZFpDPCmXR}4%n`C382Dc8Zrq_0=6`Y)NgMzG literal 0 HcmV?d00001