[PATCH] wmvcore/tests: add tests for WMReader methods

Jefferson Carpenter jeffersoncarpenter2 at gmail.com
Thu Jul 27 13:57:42 CDT 2017


Create a sample WMA file, which is saved into a temp directory at the
beginning of the wmvcore tests.

Added a IWMReaderCallback implementation for use in conformance tests.

Tested various playback-related WMReader methods.

Changes in version 2 of this patch: Declared loop variable at top of
function, and using C89-style comments.

Changes in version 3 of this patch (thanks Alistair):

Waiting for threads using Event + WaitForSingleObject instead of Sleep.

Verifying that callbacks are called using CHECK_CALLED macros.

No longer mallocing and freeing objects, as it was not necessary.

Removed getting output props, pending stub methods for the
IWMOutputProps interface so that IWMOutputProps_Release can be called on
the props.

Released IWMReader.

Passing a pvContext into the WMReader Start method - also checking that
that one is passed through to onStatus and onSample callbacks.

(For IWMReaderCallback implementation, kept common QueryInterface,
AddRef, and Release implementations separate from variable test
implementations of onStatus and onSample.)

Changes in version 4 of this patch:

Simplified TestWMReaderCallback.  Created globals instead of having a
void* in the TestWMReaderCallback struct.

Merged switch and if statements in onSample callback.

Checked that formatCount is equal to 37.

Thanks for bearing with me! :)

Changes in version 5:

Including wma file by using a resource instead of a header with a byte
array.

Fixed WMT_TYPE_DWORD typo, and removed the extra parameter from the
assertion failure message.  Also changed comment style.

TestWMReaderCallback_AddRef and Release now just return 2/1.  Got rid of
`ref' struct member.  In fact, got rid of struct entirely.

Fixed compiler warning on CreateEventW line.

Fixed all whitespace errors.

Delete test file.

Signed-off-by: Jefferson Carpenter <jeffersoncarpenter2 at gmail.com>
---
 dlls/wmvcore/tests/Makefile.in |   3 +
 dlls/wmvcore/tests/ahh.wma     | Bin 0 -> 35744 bytes
 dlls/wmvcore/tests/wmvcore.c   | 263 +++++++++++++++++++++++++++++++++++++++++
 dlls/wmvcore/tests/wmvcore.h   |  28 +++++
 dlls/wmvcore/tests/wmvcore.rc  |  24 ++++
 5 files changed, 318 insertions(+)
 create mode 100644 dlls/wmvcore/tests/ahh.wma
 create mode 100644 dlls/wmvcore/tests/wmvcore.h
 create mode 100644 dlls/wmvcore/tests/wmvcore.rc

diff --git a/dlls/wmvcore/tests/Makefile.in b/dlls/wmvcore/tests/Makefile.in
index 8054ddd0a2e..befb08ab383 100644
--- a/dlls/wmvcore/tests/Makefile.in
+++ b/dlls/wmvcore/tests/Makefile.in
@@ -3,3 +3,6 @@ IMPORTS   = ole32 wmvcore
 
 C_SRCS = \
 	wmvcore.c
+
+RC_SRCS = \
+	wmvcore.rc
diff --git a/dlls/wmvcore/tests/ahh.wma b/dlls/wmvcore/tests/ahh.wma
new file mode 100644
index 0000000000000000000000000000000000000000..4a844627583af3e0ff9086adce34e8124e9b5f27
GIT binary patch
literal 35744
zcmd432UJr{yZ4=hfC)vC5IPD8NoWB9X##2p0TY^`N>vC&s(^qZqJ|h^LeUU<Q at V5k
z=^)YtQAC=kfQYCF77*;^eo>$2K4(4WJnMbW`qsDBnXJ9n<l2+Wp6uT>`})t!jwY at l
z>Z0F0c-cchC4e>>{1yoKo%px*Kv3aqRnmcqd+>`(fNo(0dtd)Q2mi~yAn_k2`o5|8
z`h1|!Ki<~)egpl=t{p-D{$4rZKL>sp>09|<8(<R%XyUthMB`UI&;Hb- at uwI7K0Z;^
z{>%R2k6qxmolr71zU|pKJaY|DFnqY2>hq7%K!7sf5WpI+3t$E~2Ji-i0(<}gTe+hE
zdw?$>a_jZyUBvJ5asVrU7vKcI51<Rs2WV_<x?6iKfacZ<07%(3+tTu%YCistItZ5o
zK3lupgO~pR(2uy2)Tnp+ZeH at b2TyF+`u!Rg75-5SAh(r)Y;AvjPA?z`K&swq?>+$F
zB?tx({9WwNG2lzkOVC!9V0WLjLu(9PT(Z?FKJv$Zw#wvR?7uz*0!VJP^jB+qwpw`-
z5CKrwYPaw2_IhpQO#o59^PyXLCxF54+CTs=px(b+?FP>8L;q#>&+7*SG5`RmN9wNv
zi2x?>SKR=}%dN}z>q@=^ZSEff0Qi1v8MT`q2>M-A6(kB;anGkc5Y2THCxZ(R^c-6=
z1JS#WZv!dffsR6^pT7MtJbN!y84 at c(u%aZKGraX90gHr~oU;fx`?E+wXR^}GRt!9u
z#&a0U2O0%KUk~oP!+&CY0uk;HrIQN*&^Z#s%(1DdWi==$vZPzMlJ}UNns8xKL;wW<
z;sCrznSit3>FG`FCjmr2FF}RkDdB=yjw+C`q;M?kcy_4}8IYZ;B}IQb{UL5+>*N74
z0Dw9LlK}(-unC?3ojScOo6%T+CWdGII#>jNB*^e6m{Ju?E++RKhPMO|&e%?WapJ_;
zeBR>swH-_8>U=h+(bvm{()&_*3sWo8FP{3(AH at X~;-0ddeiD}Sf`z^(M1KO@#47o9
z^%NSlQ}7F6d47D^htC3+I$!gug&!j<N(q>2-`uK8lN%`0!OB(q(ZC_0yRT*UibS0l
zu4#-=04y&S0J(?jM17<?k6L!RhMyYU4Bklwj27jtQeM?y#~IwZpC3=H%GzWGEZASF
z%1^j@;e%x(V_V at D(^t96>fr`o$3rv*mO99=od%^4TZ5U+%|{*yR3 at vxP7jrsz#|8z
zpkHUYeRB(I5ejK_yX(G45iYh++A|uF=PXS+a21K?jFLG0`@f<y(EOvg$6?_Zo_x%M
zJp;@O^P4RO#`k=rZ_bkz-CyqMKNA*$VmHLIvs{Ga%pNP<cz1gKLkW+9`g9GSF_R)B
z*y1*F4#T6^S)N8vyo56zN4V^zxi2Ef6s+OkV;xkuNP=+le9Vfxn>x=;miC>@<c)+h
zzkmO}zqpxC6`OHSlA-gnL at 24CkoRynF?=Rg at jGp=9B6;XxsEKU8N5Ze&HoQ+%X_!d
zZ|)s_bN}JoKe^wpfw>S$bfPQACe@$iYo>U%SK!hXl-7|Gh#BN%qZorBB(qe=fvSUW
z`u at m@3uTt9tMAnRD`#$x{fSvhQP at Qn3<czw6<01ff at wN4o3^)+!tkWvz4`!BYmGN=
z?_h`xeowHI9}j@=UF6m&5iqQhDH8OAoe5EyoTu636u|G9Hu=aB1-MPkDL- at UdmXp=
z%EYVkFKc}kPUTP_5S)YUa4M(J;U<)#0xg|h1hW)Y7mHA~vImX at 6pRbb#C`^SCX~U<
zn?v<sz6lu?%l;#D7dv5)r<pB=0m&&T_clv at u6a`1c_u5F$J2~cK(g4{6a~tR7=IxT
zOJPFL1+*_2+4*g1L(UQSFR->N+GnD?;z|!sU6DupbuM%I?edqPJO%vKD|dye-poJP
zeXAyqar5XEK%7u%+rDk6z^UiM3464IUspbQywZBfpgt!y*nMyQyDq2nFNYAByR%b+
zv}9i8UOF*ya{28@=+t|89${QD#_G&7TLZg63HgaH^DSTHV>Dt$xe4e2<!3}mqrF_h
z`a$GjGr7Y7BsR+?ZEck2ZE5`4KCH2$Ec8`L>6?QhFJb=0P5SqRRO+AJAR>;+Hdre1
zoeJV;al8v1ddFF!M=MW>Syov+nLv8zP9YQ%=SeXU10c5koz66^x~48<RPH;99<^=y
zoV_i&YrV1k0slY`7Jg%|L1i at Kp5kGyvB!b8<FfB){VT6Y)LdHu9MfXxYy2qb-4Pj&
zkpzvC`731nxUEyB+5NDe1LNWLmuu8Dl#H#Fi>&t#UrJyqoAE4 at poRSQl0=3~@1j+j
zzH31F>w{91T`cacv`o0^GV^o7A at g=*A3~N$b{TMy9cpa at N)3kL^nS(+Zb0UIu<Noz
zO6zZvlMK9X$zEcr4!qy%J7wtLNq5(I0Svr&<oz{GurMJ~`uos<Y|nq^GC;n+xsU!A
z?&VDFg9{w{bhPd1%VkCT9SwU5+^S;>;;!|N_}hhi#(h5=v>CuAmtfMy-n8D-78I&K
zMk&Bp^r$>*aeIPLsid6;Yg4B&kyEmP5Ae}Fvk(RD2|h^g_+Wgy>X_Y?p_-c~0$fYt
zC<uQtzj(e%N~F0Ij>jy7oI^5J%P$P6?BXT*24j^`0ix5lVAk8|EniEzEC$L&IhCs8
zab(ii_aeXL^R_5~G{xk=YCHPvVFd&NorbKjw^aj=OT8{ozmMHM=U<j!vJD?eJKk-R
zg?6df-kb(R$f9W_<=xXeddjEW`#Ro<U at ktClm?m>2$OCL#mJI4-Xypp3BvUZsMj$i
ztbBW6<$c5ST6;Z!@19yq<fwkwJN@)??>58toe_C?`}OFjMAwMVF;m|gA4Jz)cb9tm
z{_TD0{LgnO?V~T>Y6Pm45?ikC)bn#ci8oL>IsRe7;EVTN>gKLsI6TN$)7kXV9yS2I
zQBP|-trG5TzPz(ul3^Z+4nH4*S<@^w8g;q|1z7LHC&%<OrF6+3GeH*C##b~;>>K#N
z$WvKjgp&QeeC&-x%R&!Ek0+w?tw;+2wdE8h9q(A3_Uf-Rodu#bvam#A!v<w#KFjd?
z?xFHb2>lBA0k;^Xk^L=SIU0{qM_ujZv5U>%W}_cS6P(Eu8#D2;-RFi5r&;fg{uyxo
z?!Nwn%|-0!bMN*TlfZ?|qSo_LkAG}b7*wS`TwE?%qe-F*6U#lG`E4E=ZM}#$A9EYH
zYAkK?LqC^;EH(C_Igh%)`!`YyoXnj~OfCkU3V}GQ44PXL<Gh9A5GZ?!ULBfv{tT?B
ztZrSD98BzHUfF5LO|>pD#@Rw{gLe&|>oovRj!P7MK}vt8+OYZ$U0EXpsV23FeF5G1
z`Teiw$CnoO!q;4N7-#7J4)XuT4g~+r{nbC*|3{pYB=ECxO2tikzYb90R6B#wLUgVn
zWX_1xg}rh;TTt1QcC`HoOp7I42q{_j)yPnz5eX>G%vE2}WHl2sV8<P7=~YwnmwUd-
z`8^yH>uU73cAz3a2x at aL!>*pp)&`oI7;Y~HYjW+Gd<dLMp>jG#Qz31CAq at g8gCgVe
zZI#jGV6Yu`hY1sA)rT#SVvKpyJk!Z37pOgz#4uK$0)@mAs;Gg28KG?oAbnwxSuR3Q
zDu+tX3CxW*7c2y1ac4A%N&ZS<t^<N?(H5Q{0=gPpif+KXb(mW1*VNGi!{Gvzbne5s
zg!-}%5r)Q1ve;^Mr|FxL4TBxjD(Q|Re24AF-_>R(t$frxjJo*aUH#<Z at sES;ca(1&
zFil)&h!FSa;UsOhEK`zCwTL0zvRJ)&GPczr-TRqqO>Qpx+N+T&YtW4dK8-fZ{x+?9
zC*R7IZ0z^Cd2IWS+3Ir9kuS at Ob%00FdpRYdwDL-Yq<0Jtxj2EM6Q|*s%D%Wr4*cNJ
z6mvG=lhwZIiL2 at L$q_k6-(`CC-tQzG)>sQ_j~Ht>oZThI%^;Zp7oxL<lfUfNhY{Xe
zJ;?WR_%a2ryXrbIG;4EQNeqiByKRWGF=S=2a!p at 5toALMntC0ItKF!VKP7$-G<`uu
z);W{`r;zK$X$scg*W<rp_pcxVwmN%?&ALuj*3>pWYn^uPP*_?2y!0-xSEKFp6 at zc$
zC at rt#=UpPzoP|;mi1)A>NYEQSs(Da=M>7r4`~1Z2V1?69bRHz25xotPDia$W#WALW
zwe$tM$F3g`3RC<MuNjxbd*%7*T^Lae1G_5#EOCw-5 at b4wdBQjUTGTuUU;xWYT%X(N
z1BO-Y{(aZ|-%$O3H~pgie_8sYKl--Lim|0XeyP$waoCeT`s1&E#$j at nM<5Hj<*{~j
z<rXOV+RI}qi;HopM$n<pqIXGVZCEiQH}O7-D at GdwZu~j@*KrC2d+p7L14;-Awj*%n
zmf)%NBCwlH$57_8KuvP{k^+d at f7=RK=$&B#b;a?y0XTMOp>oIxFAOize5K!nYXXo4
z(HIw|vM^@m_gOh0f2%1~tt7jXJwCMDerdti^(8^Uvz1vGDd}j~j#H-}BB#JPJTVZ3
zkx(~H7m!wf at +gKfFpYQ&;uvrmhAYP~hv!`Ase){~6VsYtsl5Q6Ac&kJXyzytNHzjq
zumxs)YL5CS<eTFO8$QxSkAuB%J5hWn<Fasw!{$}v81Dq%PZ{~Ui3=}Jqct9N=Iz#=
zQz^4adZcwl#<%wx|D)W;Lx4LIiATbtu9wjsqln`DgS0mtmx~X*d%^gTJu{v({W3g4
zu0?feGx)lc`@tb$r;!t-cRtGa-fnzr33 at vB=D6M0<tv>Z+Qd2}Rm9pHb59?T1Z<BV
z`x<T#suCl^4h at G7pV(G$et0n#o at hb1e7#?btbD^NZ*4!OBg9}|-Wv0YfD%(wiS;qZ
zdLy}UvuEi&`kAfCiz~9R6yk&+ry9n_@;Kgu;*@0G;7_#99 at u;I{xboQX87QPozg_>
z{s6X1L0W^fuRGe`+dF`BJT=&xX>yOBUy*`i^h6f!3+Ft=Xh9;*qF~NEPqAJi#uO7G
zmg0cTcyFm3OhjSW at ghxMRQh|RI!wA9N~}mY;$i`ZlbVNr3T at 0*_kCd)QrZ(wx?-La
z7e?{YYD(ceml&bwFu#h+yB at sM>9G^cVqHk9%RxvnRVp%*P!8JQ$CfZi+n(ZDMELGK
zwepqK!S@}HEU}&uwk?oXnGC*<LLeQ!AgMu#j}D}(b*LSnD75aajPLRPHro34{t5g&
z?(tiHfJJ`m?!UP=26qCC{Y%OiaHq?9ob8#F{-ydUEQ43B_rjWOq#^|?)?l97>{?zt
z0g3?{c4R)`i4hQBSXyC7fSPzE2qp|S3XYR{ej)JUU}o}>9NeM|W%gMV*hhKSG$Mh*
zRP`evpcM85pM@>U1cpYFRlHBo3w3Z=rdwgOXpiM$=DRBi%GNq1e40Rhw;d8YM$@}K
zvW+-c7y6BOYX&=hJW9#Dnv5B`_|zL3fJsw`gLdFC=~k9r=S_XsP#GmsxwuUq%#TdS
zse?qJX_gochod?NP15c*rI_URq(nY{st%}gKPmV&1pM at ZT|u^wj%w*gt(9XA!^!$p
zlT#at7OLu at FYAYkYt%dq>S{N!d9_MGy{iPt!+nU6CZioKoxU~mA9u~tCJu#AOCM$V
zT~od8L|Z)^D4R52(%lXbtmwFf9en!!_A~F&2PzSycOkQNi;3-*gX-tWD<i at hhvd9L
zCQd)<=8Es=TH9<2=7CR4>z#QxUHvKPp`oVN8 at Wb+7WRoXiGB4_{(Bu0mDU0N9liq-
zVc+)ZOW%`_*&l963&xAKG``twco{>43!J??a?=fNLE(3|-m6@#S*!6Oi6{$4%XUAa
zDO|7>l{c6yek)5kOMWtR%KKSD5$-mqre4 at Tjmdp%Pts#vNJ<^;idc3fMfJ<uz0~Ot
zD_37!NrXpUwWOe0y3 at Us|60m}oUW>wppkv>m?J{yp at BSy)LzRrOYjmU9tp*;^!DMd
zCnbPUP6O1-0>-`xWer-|F{+}wyQ>zJtuJXHnQNG*NWLSH0eV+R=j2^XL)i?0v0R at t
zZE0ne#a~~8H1)XLAvm5|{WBnERh9??wMn}#{DjYrA5^HZ)<Jq6J8=G8Atom<K)I3&
zNU(3nmj7-k9no+j9llf$9R|lME=up`0i)uyPZa*&9RaxQ at BUu<5BE3!+25;QTDu_D
zQi>HRnoq5Fen*!!@4n<Xu`ifPL6?EbnCA`LBOl8j^91ZdDe*_L3YGb%kU!7e9H;&e
zo&u3pDyaulq|f*#2c#ak)B%%v{K<gG7%csvY^KZrR;D+SIjJ{nK51)+s|W%$i}~+7
zRCgYWzS33QT?XZE_1%?9Bsyp{H$1pK&FE<+^4r}FC?R-G*76sjrF`l0wwM9)v>X;t
zO{6eBDFLmlz(6m+#@RC>cB+H)3XO7IJ1z&tB}7rPt-S6mOQl}a^RW;#fvpH&5I#td
zgf0MQg at p8aqH9a^43Hjr;dRe~!c}V*;tIo*!lm)ipPJiT-*0Sxb1EuZ{}fPNPh+R^
z3gFr?-y<jZUxe<kJSGCn$ZR@!#`>FW<z`L#M#3S$$m{E|g;DpLw`X<ao~1iFd7Yc<
zJI%e?UNo+e)q4BIyq|9QH!$g-9zUOtv$~Pui%pqBRn5abb?$}7o>e at mneLDg`Q6#4
z9S(R^p5sM%apge&^hD#=Nk(vz^k21 at xSdz{2_M+?hL_sFp{KS_=(q3h*IJj2hlOmk
zkxfQDUbfqwHa;b>e_zf;^r|As!P>DePsv3Qt1TVadw3mk`6I at r9}eYDu~o#fv)hIS
zZi&C=Hz8tz6NKnN$qJ26JTjXuFL_%Rao)+B37kDL-LD_d?{n4?#%QA;^jsy3lZZ at j
zrZ<dv{}^()xEJZrKIY)A at +>}8{DVQUnUt(-NOS7JJ-tIit282+qNkS`rgatOzVNlq
zZl4a?EJbK#o`i>`j##hj_4B-Jq0KW_V3ZA_v%+-iJ~f at smkJeyiLiy8AhLpz{DE|l
zKD^rZK!X;|d7)ctSCaM{HBTuIedjA(rPclW?)!gy1o&&@_)nbU^)KB2>hC4KBdl8$
z?jE^a!j#wVw`@6^?vp}++>2QNtdxqf9tZC^M;xQpjR=Z;yI+<X58k#oC%Pn^RsiWb
z5PaybyZHw5Yx!E$wmcfaT8!)o#F!@`yvS;=VL&Thu}q10_aME1`qK_lmB~mUm-1h~
zu8^@qLh~f`(kZR^q#~m0_A-a$+YoUm20#T at n?lHd9o#@m6Hi?)WoL;gekcY4r#ymU
z9F+ at 15QtuqSbPbRBUrr&W at VIg@dLoT1fnXb1YHQb>NzJ63C5!8vc&{IG7jS=ChVwe
z7)Dxw9e_=$Z&RfOR_^S#St at T|8*og1{-Iv`W`WGK_jpFk?DU()H<mxXt_*6%X0$g@
zULvNuA6SLDQLmkUtby=$UWk>fI$IpF+zi|n)7s!RX-$_o=4f5}E^qKf<Svw at n3#`j
zx0A!6g4*Jf-f at C6$JDpN at O01PN9vTUd~-P&emfxEWY0EdZ$f^Rpz9NCwbzQQD*qq}
z(Y=JPkE>kXc#PkxJdWweeH0$Kn7b~UwqT=|CrWDE{5B3oU%sjU1$5T$Be6Mfn`F=L
z4Z`y-Njqb?2l at 8~v)Zl>^TQ9qy?oDffdCWV!w~hZsApQA^?6V^ER54HcPPUy(}g60
zmX#WpA2Cx2AezI~jh*za$WXfa-}00%*QV+1^O7IEGQCe5Hpqz=QtxinS^3e4GzcR<
zi0G+J#E9UzxXaO)$10)5r-*S$#9(LCmfZ33XSO~T5<EWUtYU#3q$aox8;ix>L&%I+
zCpS0fUl!GJ+8Kkfzcb)r2JI at F-zm$G&_b0xUg&a!CSM(-X0cFS4N{*U2<ceVBxm|=
z*s4D*55$CsLhbPAMYsXcrA7$9HhJ6!;u87(z>?&bq|Q66V*pLz#=bmtodre1o_4;A
zM_=B(sUuE)ed84H80X$PhTi?7`oHywU)29EOMmponXQSBxGntw{dIP~<FM at i;+O4!
z?dZq(+zZFNg3;FY?rPSqi~jnu5$|8cf<w<<8UFEH?cBZf{jn2eWmeCvK>>xDAr%1u
z8jN__HiGG)<-Y2OF*|9IFU9y}0OYun!UflQ0U-(p4#L#UMe}$b407TSzZd`2)3abf
zYI;&ystU2mRsl^)|CTz}4I60-bk-20TR(aXzV at 1&)XGVgLTE2E0 at YzKUK}gOs+<DB
z)I%TB2x5nP3x at F^Va7BYR<017mT4zqi?A at MK!Ldqva}aSJ^^7<0tHVOYi7fRD={L$
z_d;IWaH+rXq4w=_>GnEPnL8FS4o>6YEv1igLyUskRNC^JM}PJl8GSKOcwW{v*6Pd(
zme(-kv~PH_iS_=z2LDIl_`8YUyu;NVxM66y>Da{hyc4FnJ}XLY+g|fd^QEE}bZ|1=
z_n)}Y2|f+aU%#W81Sh#kK6^|97~%(Rs6Gj6P5g$iC}3sV=CE%zS2dYhSD9$bM4{1J
zp%)7v$Bw@`kLf_1Vzo*+e9CoH$QEfZc}bH^UR6^Jk2z{<t4?Ce`#(t>EkS`>DOWm*
z&y24UF~t_Ryc>~m7~7m%?qCG+_BG+KUga^RAKEGA5iyzeBf$YWtP7b!UyzaM5VkEE
zJ7wa?zFJj<_bIUqsn>{4Quo!OHrkXS14Q(=6X^DO9vJO-PRLFUyuE#$;^Q)Gy3;J3
zTb{*?pB at 0r+UUoHZ>Vris1PMxWd}+7>N$<^J-+-d5LyqBqSx at bk;_s}qHvC@(IjP5
zOnqR+%Fg}$gno^tv;;ddm9lZnRW!Mf-&F=K9SBEz4leRvNs$_1)U1hWh=VXpok=g@
zoM?4TJt$n56MW0T)9{upx<uvk4YeL4+lyj&E1c;6J<R%VeepjVfxqV~e{<jUhx@<v
zhtSmzbziRtiI(e}^%<^kS3d#ag4;izUwK-JjZ^+Uo>G2r>1X|ueW_uUV{iV#7AV{_
z1R%a8hkm4LsF>ee8z5fjIwNH)7~ycF>M4E96U0aA1{Rd!_^?TE+?Xcaj<SF81d#3`
zCO}YdBAW<FdVwWio(g(E9{8Gsl|;six8zRqZ#+sHVM4X8g{GkC#pA=$Q at 4d9<fV{g
z3=+(vu3!~xkme=Lr1}Cqu_DsbjG-vH2pNFHlL-Yfg?KKnTU=nFM7M|ln?jKCG^?;o
zh(FF!Sl`@Fq*&?3%yn#nn%o0r&)$ysrOJcDV>KZs{oAbkZ&~!uWX66|ovC{soxb-m
zt?Q6Q=DQsev*O=^rGj67e;R+XXM#Uv>NTsX_{oFgRRbS|n6-IU4{$+m?o3u_jcPqR
zblE`CBDG0;cF)T4gzx+lbJ~s9r+e(JGQ at XD=g88J+p4a*X+^#Be at +G1fy3QxNbiWl
z0@}<y0KQY=xP9!@7>vhN(n8<R=r{2q*UVGfP(3AM4yMCOYonVpTsNdejmqoug7sHo
zVFLsee7M}YCxf5o2}c`_gfNSGtpe2+Uy4zBQbd`;rjFVdOZ)egX_UQZxU<g{@(a>F
zV9TgErsNPv{4`Z}2MWy(Sh!>#M_ at B)%R at xks0*yY3359`B;J6v)-Z6{r&xNGQddRM
z!bnte^r+%0R;EFk_(bUtNDx#Dach!VXqn^wOhxcja`S|WB*=DwMw3=V;dvH2&C;@R
zcfxE-FANEci}_oTy_G|@W~$<rc%Dp>m!#PM&(Bn*^2MU~mHvm2W;KQPaBn4_8fS%5
zYCnNJo#}F29$~_AB?ijH>_wQSi&iu8qzuB3-Cg270%Y-B23ilJRSk>y4_y6u4k-Jd
zY5srD|5?ZIoBP-Q!o8Z+&(Mb5pFDHYa3(bnI-`Z)mBm!IJGXzv at X9=20Yr*YRKL2z
z--Q6jxD{1>J!hioXuZEvAihXL;f^xb)S_g>mA_XvGTE=C<B=YKrB%0mXx0&WOb+pt
z&Lju4YQIEV0A}g^pz?kwczHjF?%`P{!=Y;qrE$Y|tnf+W^+zZ(IL)Pyo6lq9hO%}W
z`h#lWTtP+ at 5H{_Qic<xbsixw|C}Cj}mJNy at qfL8uL#IxM)stZBASIsboYG9u^kg4n
z_6OL?1OO1@(2)x5!3Go%fKh`6gvOSA=EMn$%Lsm;JZ#GE7YH!HW>{ye))uG;EzLj7
z`3@}fZ at n{oAwum0WrAxcd0a7Qgv2=Q-Z%An#?hs7#X-A=>k;8wTAA8qH74m^-f8Jo
z6Kao;j${e&zX=GQYmyRRlKktMTyP(&W+tSkv7rKP?{Nyd3%WwpQ%4H=gkcI&4<}Q#
zU8Az33?zs3haX+Eg5P+kpFi49FXyOgCicH6qM*Nc0I!Qom?zEOO~KsJdUax~<LZFM
zy3DHo{AEtr^O<9ZH&ZZg95$>T73|b$useG8dg-kr7`d-Y9U~2sm(fGoy!?Gb8d~*A
zGY#84rgK8 at k!9Yd$oVDJIUi*SO}6CHX6Sl`n5?r@*R3P>lJ~_^JH+qB>}$#q*v%xA
zt(77RD|st&;l{=#r7Ne#iYbkQES&9p6EfJ#p%8to-pPyUt-*Sa=+xy4&O)3o@{mC{
zKM<Hugan9+3OfrHrF_~E|4i}aYiBfQO(e-o<!M7+A#X6gH)$P-8^p~L>eEEZa9T;x
zGN2wJt((2f983+_w60IxE-#D1prSDEbC0!ZTmJPF!em)U*yHvFL(kZPj_|adU#w6C
z_b)x4)(%kK&h{yzXpKsCot<{>E7>J8GaUL*DEcoyPfdZ<9cKlk0znNy)f?e8$6zMQ
zzH8EZG~)=D{^2LUt-;lQ#5pqCe~mYN*#A%6tzBh&fL-H|r(0rk<vA$20uINFdFggH
zalt8gCNAlVJVME*;GJTcL#a+bkCwCF(qT)>h!vC|u}^N)EgCEx2$od6k$cyfxr3nq
z28i$@?NOu44LC|4xU6<K*{0D2F!{mNskaA!2hbCS*M_?36o at R=I!oG<-=Q=I5ocGs
z!;dFXUc^KNyjLlymdH?1^Lo$kYH at -!hy+3vxIAIFNqJfknRDLG!rHz;*b!X71*X+a
z(x7m`#^3_Fow&NUZwVP2wT at MR02ti!L<E>`TO9<P?#XgYM3YefR_dYPL`DIdjnPdK
zqmDoVt2>%x$Nc(2=hdZ;B<<075c~6Enetd;<I}KO2Xpq<5q#5;z=Gu<k8k(p3?P${
z_W_4quI_kX9*_~x5t?q(h-_66N;`B~=<DYxo!&mr*B)oS(TX42N>s`&Wtf#+yWZ*j
ze8Y&pN2uPE*W7Xa(c3OnWSfiLAr}$9BD7)r;5XGu$ms)kfM|@USh!NDmUL(8sqx*d
z9h8pVzVVQLuJGol;4Y`*a*xLs`cvfMDi&Xv?yoWs5?x|&Ah+E}NsT$os28GZ!{39=
z8D^DaVz|+LuaotMW0u9{`(1kbJ`*Y6nk2GwaE4y0)SOR!T6tp8Q<KidqLcBvie4Iw
zrQDoJ;p0A{G!ev!l!ns}rd!2BFyqn`)8!{<g=V$T_L$JrQRJ&D14EY%R^!>Nn%Ba&
zfpv1FzOp*Rl?Lt$(`2m6j5h;xvQ?G8(ThUji&Peg2;xrX at nr{6Du7$3O&!S75++JL
zwjxsc1)<((!3J;+EC-h1W<^Cl#~I9dpBl=w_SH=>h7|g)S?db!lz_<AsNTxc!52cU
z at Mc85&qpqOo`6WKT;6ZA%V6Qc`i-UGZYBArr>FT&(*<^0B!Vq7462^=N6_)y{)pG;
z!JewwVXDvv%9H;Z82zIDe_8sYKh(Dtp!`~YwRIEvhhI|u#V_T|AIy at iQDded%WOX?
z_syrGFnfTU0Izb|F5M&2NuPN<0mU&<c-45e&wsI at zVKlj8vKa9`-I*^MQ2CtKv at sM
zdP6!ALkuj*7=dC%ZzGLn*}irpm;ys{m{eAN=?jU#uTxeO2e2njwS|0W^RgE0w(vho
z?BzD|&;__cf9(B9GnmBmlR}6I<_;U8{n-pTVdb#v)j3D7dRb2F)J^3=?06az`-Oso
zf^qi3+A?lRA~=8gB*QMpo<cD)w16_L?KR7HJAix(5Hh`yr~-xany|r-XHKLjk at +;N
zkawi`)m6~4r^({SyYGN_P>i&=zzAAcVi-UDSn<pU-veMFEP-}(XV`<lweKFT at 155x
zCQQq2T<>rr*AK}GRef9Xcr!2`$Q^lea#qfT+W5_Lvuiyu|3nEf!K_L~Qq5EUZHssG
z8#ggt8?Qs}Xn4Ksi-Bhil|MF~egT=IUmjJ;-W70Lhl?BclZcNAT?>vePzKVZ-(!p8
z=!bSqqam{0r)Oc*Z=(U9ushsCmm8qT{rXj+`vUgeocSd3?4wJfPQu6o4;x?^hP7rR
zlL)`W!S+jtT!OyZ*NoG;6^3CxwGkgHa+bO++b8305(F#i>L1rH3fQ<l-<p3}>w4_G
z$z99oOe2ZY$bhSZwgOaJedO^E#^bArlMTjc3n3M+*AL1D<2ms4vQQESK`4vT_!{eK
zpaaOHZCEBU4rUW2$O@(l+)Qw8h!DdTX%oSqcK7cqx{T68=^WTL!0LF9uok&ObZilj
z7P`j8eNBC*{UjRGu0zd`4be#uler@`G?s9BkWo<-XH1Q$>mQPpkQ!?z4BF`!Ckp}{
z%ytGiMMjU#QSag^c6;emE#4H}41=l{#oqR!znA^5&i4NvhS>nOVE+gAasR^o?kCEw
zz~Hn32RE&o3)wCE0~bGgPCq##B~l|SZOKmWu|Q+Q1ROU$vj{3>^?g3+o)BSg%I at JL
zzZV}2U#cG|Pn-)0rS3JMKzUIBi|#Sr*-hA?j1oBmtS12NqD at UBlDF1K=-34kO*bgw
zG`s7|7Gj22ilb>c#&GPwapt8DI#L2+jio|@7G65`CMNtBAVXxF47>FW7{>K4vnuo?
zC at Yh_DdIjnFMdsX#W0Zt9XVzH&LLGuzsXF%7(lZCzh(k8Bd3%D#C<3}{pN75^G=p_
zCStAJ`60m|-y-XU@{(=4j|6b?lSwYQFVkbticV)EoMJrXom^^sZoict{{B37n4#ZX
zyF=U6wOFcPFnqV=@Ju^$(62j=)033_W!hWPC+&HChvbWuo1D|GRmk??$2!}r5=X6D
z7FjO21qNmA)7c)t#BWP4u`LHI@|#RP`dnr#jNWcNZ<JB%TjhBAz)k?b>$p(OM!jTo
z^5^Ol>2dR?0c>jhE7X<lQ#s)C&jvO3yKs<UDJ*7)B+~lQ-b4wH2@@N|G!!jc at iQm>
zVTIy15Sfzry?Oq~AxVp)$wCn8&UL64jExEQr*f(b*RehIFMt~H24AN39{7|ewsiQ!
zu4uW3L~k1<HxfJ82Mb{8UrZ{lg6WFu40FVBpLGuG8Ec`0#lFovbcovCz(&L+`CE%<
zY*eh5cS;!AwLdr%JsCN;aS^8UnJw#L;tu687nHsi8fyq)bZ#-{WmaDOunK8LTSAoM
zooBB1=*Bbk(^9>Ocy1;0%<|xHuk(QSPRmgFUf4K733J`#C4SZDnJ448WmcW~3(bUu
zC%i)79bKtcf{r$6G6vv~i_S`Gl<7(1XZP=1-Tu7(<o_qy|HCnWqJMK=_M7|7zvn;p
z!*6O}>rKj-MD_b*^$mC1TPEzTw3w>9PrfQ}XSFU*;<ElykZ9SSU{6)O9VRcO%m!Jw
z$WtU)6>Zcvht%ta>@3k3 at qVRqio#fsn2b)fKL&SXe at Tehn;ZP}x>6(-noz9_mOzR@
znFYgY0V?PD)i11HFd<+;LT=?(T$pVxr~(!Pqz~NHIOTlqjV*If*Mvg$Z}rdkYaD^G
zyFLb_xu(?FR;XY|l*GaFo+gkWNLmlz&g%<ycBabK(1L;{&W!_ZzPVzy0;U2<js~76
zZEkWyF<D%gPLf0WSQGkgY_J-P(4ubd0!gn--QLlF^<L)=RIT#QHy%45Iao0CXq_f$
z9=ymHLa+I#`2;od?H8s{MRXWl%g2;=8|hz{YrtlDsLD3A`erAa<j)Css>rnJh~J&N
zJCT!fG&(aVqWKMF_qrKrkMapfK)MF!=&?X&O=4kW((ys7Igvx2_3eE(xI?YG{m=`h
znTPb@?%=9ecar%vcsaa5;G6q|fTG60Yj*U$`S_U|`(s{pQtx*n{5&=vh<r}6R6)Ml
z*nV2Ur1XJ8o~Tf+jlPUW8YH0UlhJ6r)MV+q>Q~A5W{qa{XRAUz2Rza0wrc^s9$fZ_
zHnP*4Q7>f=5?i4KCBM37Fp%WQhCNMM#Epm4bDSP6^mZZ-N9jsh;a?HBSB}t%zcy~b
z3+quyrw}=8Y2nr!3Xy$#)jG|LNH!(=8icGTAa<u=+2Bm632Uzf9*Be#RA@#W*a0AJ
zUuxtQTC{2p<khDom!G<fK{O^HZprgqF_eh!q?uX^iVINlz|97R_}W^$-t9fN9x(NW
zr0T}+N#jki)-->H0v>aV at eJXghGkL0!TdjMMS_SqE{HuBg}W^x6z`Z7+8ErDkIg$*
zFDT)6?qE!bqE-=7X}g0%*e;Q>yM$l`C#i>u3KfONP7iJe*!S_g4=8=!*o`?T at r!;S
z>~HQT|8RfqpZa6>+_5M9Kl}?nD6E&Dvo!|Pd>^JZJQ0HNm1exZm(h*lrR|GsK0THl
zxwd_JDAs2=!T<J=YH19N$+y>EEAGlk*uDH+ at k%j{1WPY#om8MQN02S<Lsc<T=n8C6
zQ at CqdLP#rn1`>En2c&aElS%smN at bj{CiOxrP?J%3zCvMrmz$pXgkJ4l3}Os?Y_S)(
zHP4p}R~I*RQGj`ALL|pCG>fR++`3Adl87A==0`On0YDTL0$`Y+O`ww)biX1&vVTcI
zMt)Bm*kmlHBnbsCAY{7p1cmHUSqK~%LG4v?6eJ;nD_wCT9-o#?p8RMHZ1{dz<w at Um
z36{Hyx8 at VR%hk;jORx86yB&?rAA8|>M`x~B`=lamxvdhU6odD}hgBGP(~x+6kJ)4D
zMzrUHNIED(uyycuuJ3avcL;2zQB!J4dTybrc<*V_nf!R*<eL*43XR&Qv|nUri at b^7
zR-3dLDOG;?E1p%m`$j&)N_iLOA)fUze?w5SLbz4-o#DH2^WiQTVYM2$O#tp^+WW(c
zHF}GD^BgVtIfZD0@;u}7liJ+g%^Z^vD^nlEPchWi{8(kP#*}Xjn`Rns at ZHp`V&7!1
zqQ)VbxJ`g+XY;Q6in6lkW_&%q5!Kv(;eMiFpwcOE{8EY!34t?ixo<Y{46cG<5^@nj
zs>^qO>_u$^=EiP67EMK`lzh82Sf?`_<y&HUNmlrvx)KwC`@(vRUzL at 8YEjYH-;Y_K
zE$0wrF-&edE9+2xp9)2!u^tpH*sa0)I(VMv?T!%JDdr8wYNu~fw8GpMpApS=RjIVf
zA{J5gWsLHx!h7^Sx2lkFV>#AhJKBZ1XTGwiGmq$bKF%(?Dk0WzzP*vY!3^m4Xvd at x
z+wxU~v8JPBB!;+?ni%8Ry=z~@n6BSGU?1TYsYiWUK*atmef-}}75<|Be_8sYKi0SO
z$FKPh_^-43Jsu{qb!*ys{^Rd)U^Tu~X_443TM~f~r{-dzh60k!FmUG~Gfy>pv8yAF
zeQ9YYS#i599zP{pINI*|%NL1h3GlJm1gv~){>dNHrPvuRn2YHF!YIm~fj|Q?W2`6a
z{s3CaC%aFZqQXJ at 5#Zal=Wr!-VS!4J!ZdOzGJ);n1wV}n^QoBavpjUnuV6(cm!7)&
zv2>|4;C5;RRJaumNC>TFD$vcD*&G<uheUt?QjIiKD!T!I3ok&0C47)_`U4k?MM=Z<
z?4oXDFuz}U)YkZ;mMQ=`sgnvDP8Xkz&3=iO&F6OrH93=xCzhIz`hK60%W?4e#(yZ|
zn(?H_t!Z`r%Pp<%uGp#)g1^6Yq4CKKU<lVl?%7R==MJY%W at yraXaX}&_e!f;#5c@`
z-K?5Xj1_Ag06^6qCza1NNRPK19un+^336o|1nX$WA4^{L)0#aoaMWV%RI)p6a_8d@
zIl1Y}I&+#c?2N#_7<)pcZSBh)^Roctc9C0SZN?LcrAxb#YxdP$<F<isB`ulUE4trP
zux*}w{F8AAR17(v<}ZrY;SN3_3kDoKU2=tbi+;`ehjM!?IYT#2_5PkP!9ua>70J)@
zh1I^TOAhNvg{>)uMQP7PFf*yK<g78J6lTrQo7I*5S(C)e8k_1W2{RK1J746!jQ%Wv
z<DB!o6--mq6qAa^;<TP!DjsU-{BE2?W3ru at +|*!VJcOAee at M<mZyB$uS9kfWHw{)O
zr)=Gj#?0ydtn+9wwB~tPs+V2nMU=KyMnBIg(>ZI1Qub)4q(wMST18Y`I0zaa6QA%N
zyDl&2C%aQq>+aCSm204+>s@><H7V|V7e4B5TVJS!oRwuHv}{`}6#s at cHS<O(z*rFX
zvCA=09&)f7XHR%a-k>%-%T$xC+Ep8QUr;wn=8O3MEI<Py{^nlm5BGn^Vd at v}d4D_b
z@|fi&Q|W^P2C*nS^5T30KR7}DRL4yUNo(@2_Xl#oUng46?$>{jhRoJ9eO?IE!MQRa
zPE at i0g}O;P(~fl+f8V1OyUfC{**nY*cpesxgRxJDk+l at gBZ|+x!3v`xq#}s at b{FuJ
z&hix0g0E%QlOi|(mu*V5Q*}%=4DvFanPP}PdXAJ4IoS+gfZmToQE(Q-Uspg16qbna
z<5PAcF$=P}5V1CF0RjVqWatTDK+wE8v@<T1%A7KUF(?y4KzEwVj0lNq$?wV&(@bFv
z_xiIGhW+7Z?(A*k|A;?XFZ)Gga*r~x@<3FZ$LXjl^u75*=cm5DR8Nn3T~e!BtMM_&
z?O2Y@<XeYB9-2*=d2TE#li*kJrL`WQamVa=^|_ehhNGoueB*}zRrYnv5M3s!U^>46
zlP=Jo6_<4HOrURzYp_+afNl}kY;|xm^aew?`NflquB2F2W00-SfnaQ$nTEHlTu&!=
zHu{mIKucM^yF=Ym$9!JN-r|ehd_1V-O+mSJ;dz^F3MTwn%O_qQxVra4+|^<RK&*49
z|B3L*DTTwTTo*{5P4=YO<g)<T`*ybI4SXT`nS}ODja>NRSA(IjigYx&#xo`ae>Dw(
z)DfjYVu`1eUd9!EXv{ohj#}3h3 at Y*Blo!XY#Hw5-`R=}jEK;@d*lrCyiFY12b&4nl
zMzLLXK|x5EVbJ0MrXFsFEz^rIl?^H<@jJKci7#-Jx5rA-5SQ((NIEz!Pev9)bO}<q
z%7`W=j>l(wgZD4(k&Sit7V}jpY|5B-PL=v;SqoTNR_}*349O_rDbHbKj+w#W?j*_b
zU{f36TZ-Uhp^v*#VlToMWr)%kZ%4zbBrB<PI7}>g__Ot0GuMiS`L!vWtS-aRRL3_E
zs!Bg|)Jr}L4ffVmcF&+MHC$SoZ4if4Fl>YVLwNinx3y;QpZ)!jf8pL3_2uVXNF~sE
zj}-%#>Fv{>VI<)H<4c+6Rr9h&J=?Sz^mYQOAr?O-Sf;jXep<b+<N$itYWO9W+(XS0
z+S1#sNDtG83U)LSebPF at ex}`yE4Z|#K5-;lfC5pYvSGC&o|9)WrI6A*|4PQJQGt}M
zd8xC{^|FC@{y8;6bPwj3tBX245`ayuz`yEXK`T|g;#k=_ps+Xs&IKRD|I9j_)PI>J
zW75a<hcd_v&3;|tLsb?_GZMhM-G9eK+>YIc(Kcaa1O?vHm3h1<zGH_6US3uvu>G2A
z-k?T9 at iyp9n-{BwQ$Hg7UVA)IFtze-%xByMjLnJ0Id>fOjkz%wJ0~0Oz at PY>{?SoC
zqhaIJ{oQvy-urmxPM at bpayH0$%rnC|SQSgC2#n86T->8p^|Ogt4zxR(n=4D(<)J0w
zpZ(4%iHKQje~N#sMX#*W!AZGHO6jxM*rap^@bzO}JY7TXK%~iAsp)_S0F@%r;dSDc
z=8s3=7`Y9rd1YIxH;qZ(lRw(eLWqybi(WH6WHg2ufY*2B>fbnOc~Cj-J-kbnY1 at CL
z$16YHKms=FxHZ4Vhq+Wyxlr0(*fQC5>iz*FvD(8!&dm62+Bzf}tCi%p9BLH=MO7 at M
zT4iXpP$xemYxSS;(2rYqBJLd~3S~Fjq9bP}&~noYwIx{>*6s_|z}dmhQUyP>lqQ+v
zG<<Oq^ENt7Y;p}>k~NbW;ti6M{v7v#(5{ynOI%SVovc7zO%VcF*Nc>+ylJHMs~2IF
z!QQuER2MQaI6zq&RZZO3Q{MHIlW_fza8`qsqM1#haPT=a_=13+WYqO(Ak)Xwxwxl%
z+0wS|d at J<1%cm66W%jkZ!URycz^Ye8U49nM^Kd%-zhL}7HUN=-bARy<_kZh;{rgmJ
z?OHZ1kXj^C#jArc`#}7gc05f<sVobFiEYO-pL7=Kia8PmCst31182ea4?aIeuvYX(
zpNtf^`-7m)jXVa&M!Jw_uo)Bx+4Uiwa^CLw<;J|SS$PncZChHS3CYv3Mk)+p7;$@3
z;!Q08rHHR{L=*Y;YlRR3iXX<WZ2HXhqZCX}cQKyvEprDUz=9DHy640wor}p<%@*N+
z={QvsxP*SaVQWSYToIY0tE#IG-g^F4m=~u>rFoXvGJ$F!qOvB?8N(F0j&~Ja?!h)-
z8h~2Te%(=UBi*g14{x*#fk~-dtaN#sj$n)WS(S>V8!;EE77Pp at 3`$?oDtCyI%DVZ^
z_rUH6L%&RyklJfTva(Rd_$g at v-`rzo-vwWbU&Fm)S!Kj4g^exvsA5RLRWNLF0PO{Z
z1+mjZV*HyD*i&z0ut~{T$Ne37d-50C5A;?YEeI#|pGV++PIc-$bdYdS-#t5IC at 40@
zn3KqE09*A0_l)OG90>H+)9cJ-9uYQr2#BE7wF)4*MIITH1F$nYWyggstj&j``(2Om
zD>#im6?xj46K=Mu4I!%7iPi`LWiNh7>GWb#4xUzEPQqU80UZ=uGCyDh^jh>guIGj*
zyR2Q%yHnl`85OstZpEUeBKlUgvA$Y}k3Vz?OAsg`AxtUINdLH{Lak@@dX=Y2zUqV?
zjN!3!Lo13dn^`CwIem)<))wT1x at qJ(Ht!$G*^vf)ib|PYqt;Qm52%m&0vV6P!C$SM
z8o%@mte6h-(N?NNG*I4fSN8z at j0Cu)?7{=2ZCYY-Nzp*;Ds9DMx!r}+1nTZ5JSICf
z;x|LHv1}I<M=4KapBKU0uPAC-*%DTD&eNZ_B<D-?cgdHy at B!#eHCXITj>{~w>^V2E
z?f%$8)ouOiNP8jX)J?G$hmSkfkE`~^w*4Cg@{9WaW$BOpDA;-sF=<PGi2pjf-}<BT
zU+zaD^`Aws8V}b|dx)AZL^RJu4pA`m-<E{VA)4|<xl*^wTgJY|O}#cg_ at W}vf<ug+
zu!;wW89lsJfJXb=O>&=-P3)R?@Z|E<0pg%^#6y(cQxO(aut$U)U_>UAYWqyh)1?jw
zZyN#(05QF=3sjiMu3?kKUh_K*Rw8qSJ7?K+9Vw{*zK9d&2`eIt4&2^dPA-5u4v-wX
zG;V?d2tlEb>jJvjGunE5m4ZnMJgd4SO+hm#p*$6m);R3%&x6QLpdE1nS<{w23IS!2
zB{}i+5pKfC>CzRcC-jIl?mgiGptu`G7m~Ub_mxZDjk(ie(L!8(ZoSBNW3e7!{_$;G
z>&0-TvfvMTBKLi)_>=<OYXb}caixBWO(90-u}=O1b20(;HkKp43_hdlm^!v+AnVTD
zNXm^$?e_yO{QBo)0zaypvkHD^Q7I)Q+YmWaXXKdJq*Zz{LdYvcHX!t2hm%)<c(-{^
z#>4C&uvP-^>fIwZuDRc^o7oj}=Y32X$$n~7di?3ZXo-<=c>brhW032kr=&u!qB=PP
z^bM|gWGHEof*91BSlXNqF_Q^t9DgT~XaDs{Zwa|!KmaB6K8k6$O7<~jgJ)K1`M%C;
z-9O9P{B|EM011gIV~>RH5kxi5JaJyb^0~h>c%oA@;A@;P(6jy_G1~%{l?mnqM@<Q6
zDpN+C2e}zywGv8zTnPzh$5dOCttYL|Dv1BFj2Xn^^<fPt@}rs*6K&SN8n(&$dfk=m
zjJ=dp+PeWCD9|66l2CY`y72h6cLA#NCUf<i4*4Mv9qsK?jW7*J(^@Wx&6O at +Bi5G6
z?{~^k1h?=+VOfuhoPF27$V>7Z1_RMT7i)&h2DRd#_Hw!x!3Wq27S at v{IW~39OTI*-
z;5!tX`gUG5Zk;D^x2b34^~{*gLx%YO!~F^<@i+IYf4Ki!cWYOvd|xh3RxYb?ygCNk
zFE-}&c&_c-SEUW~dI}l|H+d#RBJT!^`=8T=ocmhz((5x1DAicy=W_OX)OhaKI}v+;
zv)S3RASS?))QwAzC+)Ke5b>RWZ954UGDcw1hs23Y$)OT4vUmWgtO%f!9uJ8sSV22W
z%S>!{)}gbWs_}UOot(ELM0AEA;2}~P7p{^(=Vb{*VUNP3RE4#15FkKW+&`PBql)G8
zno=;aQb1KqKiuYN8YyBYjmkQ0f*I-!!6Lz878a@|86mNX!47xy$ZW>e#9pJRE1}%C
zOdPiI^)3WxCK_?Hncoz-{qXvmVs=xc#I<)B#;Z+Fkh}43T0cZM4&T|BFOW!8czt)|
zje$!+WsZC4i&r;10;~_DAHQf7T%U3(wd39ENAvBSGS^SO=s&LZaWFgA%FS`UjqL4Z
zz1ECsdDQ}kHP|%y=+s+HuYBN(N(zg`x0*VplV<KL)x7gx>IMpH>~c6CZoT<Ep5#qT
zdwO5xw2RDn8xs<DVT8D%SN=Sx?E6)|m{a$S^>nZ*kqsR~4MG<M+H(WSBiP|?s at 2g`
zM=rijD_ObMr}CQgey~J8`J+k~d%H_{`m_d=?O}?Fhq-1eDum#s0B4SGJ_^uCB&(mH
zd7B0*hUg{{_4y>g9NN|c-=?Up#5~GVy_q!IF0W?We*H&)ex*tAh1O{}7WzCqTr^&e
zc;|3(ZJGx3hJHzJq5mTPk!TJ6nD^qhpPf3hJYMiU8<Q5FETYw{S9e?1IwD^Ii&&JW
z_7CzT4&(UMX!m!JGX_%^G1fxrT77YeZMSc~wOooi?fso-=#!kBAZ`cJFb;$p;M%g~
zCyuHWeGf~udVLnBRGxWZ<=Dfo0tlu|#%+FveEDfpgXle&<~gHIlTXh7;~;G713<~Y
zxtHD=65bkby7|v>VCA(q)Cb3U24 at ZK^7CL(sgYek%h)*$%#!gb%cWJp1no<A->dGL
z1mAoH*8OWG1!N~rZ9D=dMNkK_8oGitzfUi?w^DFv at Uu5JZ=S8w+6F<DfB|0<7}F+#
z-D1s-7?>TVAe%;q_7eNe#8^3(;!JWXE*!J9vgl6*%-*ow|B*2^Bn-E}g3nWV+eZLA
zgp^6XRF!FiDhH}e<_)EZxn!ZPn^>qe_Ar>35yC8kT2D|{Rw+;t=Jim=vmG3HX>iyH
zY4DIQ)mm4Tj2UOtkqenA5S8pG0_d4Yl?*~k0i0G=D2%Od<CNc|mQ7_(<z;Sv;f?p<
zS`(lG1)8W-PU_JJjr~T6K2M&g$*?}W<MfQ+`m&S5 at 1FNR+VF7xCn5CCeLdf^ejC#2
zt at G16C*h-S-dGcx(bA{pdU*OV*Gr$3bL3CkCJSceyWef-O+Npqu)T@*RDVQ>-Y}NT
z_es+FTY0}BUXXk%+UaLf%Y~G#b#>dYxhVLU(g8dj`YobXY0p)J5<<T*K~R=`G~CtJ
zkade*zIVyx<hIU{;jW`Gw(c5u7eN2QOjb(N5Ph9}@5Lu)HV1*@4(gX%h0*pBagvtb
zX%b`@j}nErm7bQl2UeyOt&pO{=^99wzP!^DmTDu1P at -oF`zmLQt<AJ+*6V4s=5fS$
zpRSJ9u1A$~y4F?RqV*oY_hPIav?5JSVS`M47WWF38q}o2{PrNO<ny%VzDQf*Xvyb}
z-mD~wqj(tkpt2bj?)navdghs_C7=5%Q at ABZva@%^!{6O~SS=4BW35oIYKfM4DGBQ!
zEV38%`ZX~2llJo`aL%_8V)FK9x)YqtMjh5O+8;f8sXc)erV&xkacGnb#v2~<Q`(90
zIZjZV at Io5}QIGa^u_p;A%kh#RNqZmiN>C2NU`VHs%tgO1)O$o<?-U83xq at Ke`&<2*
z|LLzwfKq>RPyWsQf2_aSu`dg&Z1I2E`|_wH+x1;UG*C=HR1_^hK%4<lvq1&Xz<Ca*
zazInl%+j*)Q$$45QZ#bTImdENP0J~#tW481tsKg<d7g*k_kH_(XaDx^>~r=yf9-YF
ze*SuS*UMVZy4Ur*?|t3Fb(6-gO$&5KZo!PgXSF>Z^+`3!G?(vrTPB?oy4T~a3t0YC
z5di3<Rbq7c)BP7SiDNWi+`8CVZYGhf<<wvu(%)!2N)9;~g2gsg%|!!nI1~~ZCtdL|
zb90tEGYgi>OmR^FSMpt)U{coIZ6E7i<ZKBap3zkmY`^g=0BpCi)4V6Mf++=;$RjEm
zJgUIMF)7SRDLiduO(-QdodqEE+C at up?T~mH!YhG50DK%6=q<4g29`B3<I=$okYUd7
zA`=R>G5QMk3jn%%@@e`|^?;q&O~?fY_eb9~)Z5Y+-LXzz at g2VHrgK<b-G_ziCSjNM
z<d<M`PG0xAe<NofV<Gp!^@Bd@)(L{hi16;7wK&A1SIz3+pefVL!&|=iNk|lgb<Tw~
zV#sn}p at 3<6JxZ{Jza#bLtwZl9`_jPh^VCVlFyr2Zax8C?P1#GERcxwL$WjqttX;uA
zbbYL=a<O0YJ`1T@$$mZ_f9K6M@)1Gt_%G at 2m#-B at cjAt0!bk)}CE_+wdDVDp{?C9P
znI=CNu!i}8g~Moczy^yx(KBDBLO=hG>lb8sj54v&+J!RZBD4V+&!IMQ`b{2u>Ts5x
zz6<Qvk1<w!nd^Yz6NR-RC7r;S)C at 2`@pQgCiUBK*Xr&FzK0^nF=Tj71<Ehfv-z at yC
zrzaE~(<*Wp;XdEPS<Vo4YP$ixm2$FHJ2yNC0>R?boxxf?F|u#1-wujrAR at EZVNfnl
z4Pvk+3bIEx_?+ykiYcn~Y=p>|k+?ZA@!b!#OZn{@48={>RJNdmX$>NLq-4Jj&erAa
z6UHStiyrJ+Hn0FE_MQ>Jpd&XCY`lmCM)_;2{DKNOaX4F)@$~=8i~XPc=Xccqo2 at _j
zhu4}Q#P9W2D!=dU5B_oR&+pM+e%RKfU$^R#f<4l9$ubUZ)H8~RkUOU&`ZE4%)Is5?
z#aQpp-`+R-yqhOkuVfr&>fuXX&Wy>PRP7#k9_$I<H}An0$vGV?Z}gtft<+=$oEsBZ
zEmVieAo at s{47U#g9;(l<O%5Ofqa&}BOZp>5ZhT2Fl1Oh$_{fD<Sf{?ENZ07yPN#$5
zjVSjtOJBbxC8V{GUFPOhtt3BUmyXCzNwsnT$l-^mSYA-d5C%0y7ePr(SXi=+3S!*>
zMUEGQIu*f&hA4VN3FUn0p|yHdbl0=XGY9i=H|7PS@%$j5-zbJ9q|~G&9Wb-9%1~}@
z)xRxwb#Ax)wDC6Bg&!I``92(G^!<Z5oQ6+n_C&CEARJzEse&XUVA3{ReDJuS{b)#4
z>Y>1{r`~tq>zZ__?QOl^vS-9_nR{%xoWLWA6UP!Xyo4>{)e;<d0$Z~5+oZ0w5F_wH
z%|eH6gRBzF?~f1)u4AKHqG3#xjEm(_{xG_H$kG_VWWy1f(zZ>BRQUq*?vF>aD}GTj
zL%M39I&A1scZGH)GCTgrE%iVK=XMW9ZptBjtibPGDZ9eKFiD_m&j?-8umeY&puHYA
z`F&wg2iE)~f0=Pouk7=P+(#FquGD>+ at v#1fU`te at pn;B>Lh<rnMQ57VFoST9c2?#_
zdD<{jnHDx93aG*b8ZMqTmU}%yDN(`cfwV<$PU51eQEJviT=6ZJ$OhAX{KHL at tP-(v
z#%Z3CRC-OncAkQLE#!T%Q3ga;Khb7~G>%Ns6y##dHbEky0|{lHCnCT_9D!=~ZJ2Ja
z14vVvjT-PmfhJJ%*b-~wVO1FKVySuzWwDrYdL1b>HS{GnSSB|#O>Lpu(m`IR at j<g|
zYwU at wu}UG1)1FSRBy&@8qL*_|@GZJt<ER*<XF;KKcI3iVwq;xDx4m1KdqIZx9x-6K
zN|u6=V%X!>zdxc9Ya(fX!~Mm7 at WagE&*I<%ml)9Xv>xiWRMF=l=_)zW&<x$EID4Gc
z)3rnP1)Hp1^<|A6fOBwjKP&YFDwEyAUrVlXYVr(Dmd7(>RQ+P89ug7wGN9Ne#AaMJ
z8Y8wl<B3 at RYrMNy$)?W^Z38Z*nPD}-AUvxE<6Ma-Gl7S|Q;>7rRP?&)lHe_gM|N0q
z?RhmAJCR#RJZO{vLQb+ocWSkbFv&daCawgLnOO=bjDvX8a3|Mv6;wqqD<`J(Xp8rU
zXc1kG2;0%y1gPJOHdKym)k;|i+Bp=+0@(UVQ1R}1AfX8TK!@FQG^yfK-qo`xP5V2G
zh3dLpO*I$mCxExlzj&NdlSllR*_s_niAHpJCfanEgj){{){REE9PG3nI+=TAO^J~B
z4sB9Z9%Cp`%@PdV-c^O6HC#Fa379`RtsTj&oDA>I5pKJf2koq!PL6Nv+yA4#vi!x=
zE7vO3dyNMj&hH3jD_0kV%&ZH`kaU(PI#pa`*Q^ehkb~9IMYZX+vySWHKIN~goin*R
z)Ya=)^cM3(n3N>m{pAqraG|WCfu~7FzgP!$YqbD^+{j*;_XAJZzwxIT52<@zFxx=1
zD1wIx_!*Ee(lbYRue}-87?(k`_=Y%oN4HP<w+-5wa4!XP_Z5HlQ)S3L&q&97bc&0M
z(`T32$WD6*V$S at ov{SNTfS~oP>i5#O{X+Z4`1*HAj&B~P;d3M$9ybtfW~JdZ`vsXR
z(`|wY(w7B!2t>D-I6lwgS8TlyB`XImr;!pu*yl4|Gr}!nV^yNSA;o3JpJ!nMV`6aN
z^=c{S$n*Q at +<BR<Va+-GzzErBv{`82RA6=X_D!Xj{9u5G)!WiZm(ie)77yO7MOZ;Y
z5{Ii#E at Wg316xPu)A_dzTAd$tcR$)Cmv0g9ZZjF4?G|76FOcrv`3L$h+)w<8``^a?
zrgy0H;@O_<Z!guEBXg-qAF|5Lv-J}&6wxlgX<4D+UI53`a<Ow#+&!`@C3ylDcQPs`
zj03YhNL~h3&lwmo8mmvOj$e@%4H(NUC4W`0a?9`tP$H-~RMfxQCii?^vS`2(LmsKX
zz|v1kmSidLecg)EH{t=obiPhy@?O2CJ=w0V`&A8`8OSyWIRJ#0DH`Eswq+={V0dGE
zCn?YL2`PM!gEasLL?e(+Y)D)$xRT|^?k$Gk at 8CPeRdX=f=^0MLcgXck!PpF76^n}B
zE3=j$cTepga)<oxicRujv9`&W?l5S#Kdz45+31NCRr)7#uEnIeZsw*!GAWW9&5jO!
zd_p!tzkG3Vz`sLEY=0x-<Bp{>dX|=$mA&0U+5XW}@X{2o?(5yqQ`uvx?cVQihyx8{
z<$?sSTF{NXLpnG66_GE!rUX?jBWIwnp|+Na078OIo^5Yl=*A$2V(UIXtLI_0xSI>P
z>vH*(7J2=x80|LR)voA)kq($+_=GZI_)t#U5Q-}k$t+}T(=Te&?NTV^S!h(PK1NcC
z53wsN7LLhpB4QH`KieGIIzao{Pn+Y7hnmT!fwf>8qU~W6lKEPBVeAI$!S at rnNh;mL
zUW}wqg-jE9HJL2^78$#T$5bOxJQ+ at 3=m+D6p9x}B`z-x;cE=vQ>wI;11f0(h43HYE
z>l+bUmmw!nLHBkE#nkOdM#-uBgqANsc$2YmiK3!Li~iZr)PQ+`ZPYHCji~<gy9m|g
z$@-dzw5^*wHt48WWQJP8ac8H~bmesYnItr(_#KHIL^GpQ)m4LM81tp{d~iT~qqT#z
z)jq{X%|~KwGF2U`UNaMSNq?rm5>?!#Q6z_kFh5fT*&Xqu(B(!ryq=0`nQxB*u*eIO
zE2 at q^5k+mF18rpJr^D?PMWA^mxc1W at byk1>j{o~>iQm;r|MYWyFZo#G-GAYJE8$o)
z77rS;{fTv*j3I=@OS8z&W5G0usbujRJ%~8v^qgh#gm!U-#Shq>vg`gcC37&jM;B){
zYdEc(hbO4-iMv<O^2LO at mxl0DZ5+1%)kRfghS+s$F!~U%({F^CV_8#vw`s`9gN!*`
zkzJge6sYK`9rC_3bSAjZV4Hf6Zh#0<J;oGBD<#K+F`^JwI)az%4=SIMbcV9T!?K7}
z4QteKcao*E8`}af4vVw5aFW2+D?yT_p(#U>FgA-#$GBM-frfQi)fTyN_2b$VmEkB2
zyPb3Z!k5MH0HOQCieN?UQR3C#^beT^T~eSxMRIg!NE$F+0(S&W?l~%|Tb_~C at o@3G
zAMw1sa>;PRg8L64Z#rUxgi%lT!ZzT;`ul7HzRcR~RmC(a#&yXF<c_HhOl6xMJfH_v
zEm%^JsEs^C*7A34<F48!w(1t<5I7NWG~?cwu`3?~wQEHL>x?S#!%8Aju*>jPx(8^;
zwN4uoc at TUmK88uPjluM_pKV5Oy<6$_)U>PgWE_B~eY8K4d2If2St0bZmhZSQ(<y*>
z3JM5);cL>|_S!PsZ2XaKtdj|5;+FSy_S>Vd4WT%sc7}z3BYY8 at QKJ($I+T3Oga;fy
zWjWV6Z0kTja1!bl+w-xJTx`q4L263i1l`hdHJ>Av6KGcXhnP;In?|F(Nlp_8t((&I
z!bEuD7YG#-<|jr?gf7HvZJE3+TUFjm&U1(x=of8B at 2%F~Qi1<=Dr;*@Yl+#1H^jT%
z^Xcwy(vqDHr#^1Jb|>GepCIpb+zQ8lLq5pWUZ4;g1%i`LfSd at 7Sa+wfXaGGltEHv`
zjg*XmX1_)ZUX^-!I4)JVhkyE_uI2K^*n3C=ZTM&^W0OF|xCX70K&b*x2DJd<$bqgw
zj|1p;*1tIabIU9tt~G1^^ygzk%W*~Hj43tUzlZ!E*T19w-)#NKKagv}SHJTQ_1|~*
z2mc`d!@1PicnbclW-kMAZrWe+GYEZr%hm1$#cpPE6sGm7Gz2CVfQd#6j=8Xmm>|YA
zaG)x)|8bv@`rh4s1J|COyPVTum`jK1I`y!ZO42=~s<`5_w=(5EO at MlIwX{I&y?3iX
z1dK|N9#6|r9R{)T!B5g<cSDIqc=o*xXOC+mH&1d<10{YBB%EN}YDoqF$gQ|A6lb~K
z!ovERvm2JeK#4Mr2^FP+dG(;D%iU8WtO*IZOc3B+Rkek3e|=w=His!aEQnBV$=u-#
zGFBiN`6o7!4~^-%*U3&B3||vXDLoiNz^s5pTlx^-<b5VSpN>tBz1<afKQ(B?=jD~w
zubW*y=vKv^I$L1Z<1cQ+E#A^Dj=m=~&eR^=T|4$5Z at m6Ovzt`h1&l$$x*|&abmEla
zvvf&#ng9?~=QH)gg}@dC1V*$;=Y2w at EGu?X4-Tj#_P&V at nA<6>vZK*7WP3OWlJ-_A
z+KwG6mv#|m0-IjT`MTJJE9}d<4$2tnDir~M7MgGR)4g18HlV-vs<hamwyn&<#<D(9
zC48Bf!#AsEe(Z;aT=7J+-`@+8t8FfS8r$It3=ed!Qc66*60%!<$|l1cC~=tu40dXG
zei!DjvM4<~b<9-Ru^=#L7qv%ILDf=4Lj at 98w<)=^Buk%Jcreart@~o2gn9Djn-7^8
z6<DlA5k7v|AM2vLZ>r=5gofOA4IO}3Wcz9Bw(xivm$GK$UYlMER95A9`mWl_#7Nb8
za*+!s7dLQ{;Tktx7WeSSoNXAP3v!BZ8Pzbw_)GC=mmbhQ<B8|6uyde$u<WNcYFn$W
z8oZUJq`-rE;)zMhVPEq&BZJ!^dYz9qk!=;eXRGh~HnFvA(@=vaE%wF+6^U+*XD!K+
z%}4i<>Tk3be?16N7?{4{I3$Sp?w9c|MujET`Vanw`<?%Qd-H at Znkh-)Ux5?vhdieq
zO<EAjPj0;&em=EtSLso*`C)r0`+l+Vulxizfe6lPc1Zx_QwhF6$_9SP<Gp$a(7q2;
zkOZg}L%WWV#5-Ap;h`j4)zYHjX4MX>g>sQUS&=?1$j-qr*29XhQnV8fS5;Xh<%$Tu
zvN&|Hw7U#lBJb`1uYV^BFb2Jypn$-}6$tEv0F~_IDk%Z^Nr01`WV4GU6wIRIC#4WM
zp)SEFdN?`3T>v1DD at c_URrlj0xb$2WJz4q{#}ZN_7lvL3Va({k at 6dqLldn6tEqO^g
zkElOK>cM;&2?jj|n_%bfVn_G=XzRI+<92b16jy3?a9~TV`Z762xjmu+skhT=3axWy
z>cfbHm^!EhZKI7MOy=Ub26_`xCFfVa$b?uo4-u+)Loac%l9UK1)TE+nTBY|bHR>vL
z+*W05m&}E1KlNRs)jo-XS-W6pLVT0I#~vq$yLW4m%-pO;sI}m!L81zL#!q`_vfHP3
z5;dtD>Q*ynORwLMzRBc~8b>65>gf5qH;k2_&h|e|;F|H+tZR`Dbe6vS=3 at -T1{yCQ
z;RQjZthdgQF!Kh|i30{#J+so_98lV at KL=loy_$@w+99>K at wh%s3_h)#AoG|=aPGp4
z>j~c0Q(7BFAOtDBEaafsU2^V|0A|FM4`!yIV#|>7vb(rwUC+acj+;C$zPGX(;L~hk
zQls9ONFH;?UO5kb3h}nbXODH9+vv at 1(9BtcZ$mp)>B at Hc+;D0r(|rOAWQ3lqs;HE$
z4U+6WWaoGh8h?dI%uXLh2Mn at eEq#?0=%b7SRD&tc7w#E0G~j5oRct_z-iNGry60=d
z11;g!e)zD?OFQ~S2dCqbzrs&D<EN-5%OTSzf4SlP4kQ+%PX%#9;E9<?oSy)2<3`0!
z%h6h_=b0O?wcjmW4XW+V-|GJ3Lid09CP{4k3- at V%;{LDv2eozH<kl%CzDv$_q)2Z2
ztKsV4;2<5p!BrwxFSC75k)HUWUMR_C#>gAcYo)_Ni-3&cl;f*4{dOPfJhf#@TeQpC
zsO4?d{GKFtGbQOFRC<j{9k~y4C*8V;2^L-le0FtSOWl=WNmfiFEj}UiH60)q%2O!<
zz}0H0D2QGTmT4KN`g(>62>}!iA>t>O at kk&LL0zVw<xp^0=@Q8R*)usfZarL&-A9DP
zI1}urLgm=`^%+JoL1j5&Fx7(6E^@_Ld1A`4CPmyF!lh)fO_QFXzMB87yXLZN2_TC=
zkSK0wZMR9i7_g8?iM}B#BgaU8jK9%mW9zoUw3vq`swhiwiXLr_zb#aqemL|ArXRka
zeDh8yp}MDS!)WVXg4146u)84RSW5@~*5q=e_Vx9TUC`}o(W}VD+2Ncm_g at h0F5Z9Z
zaBsFn&m(wHrilFF>@hCoRwV!uH0!@j+V_Cl`aN|Za at ZFMj-Rp|Skej0!`OlaVVmQD
z#4XTA=NX{*{>#^nSZ!NZS6T7SQ_Yujy4*moHT(VheNLc9$<Mf*SuEs3;r3CkROh&g
zqvv{s*rM~*9f2Dkvw!6-WCmS_nQ3-NnytwSBf{}-DMF_+1U|`y`&I&r^|RITD?Cus
z6{-HnA?wg%g at Pkq#~p<n1r8h!=T$<kh3-bFZT_VlB6v+nALhyeVQ<8FVW at ls_ZX<-
zT8aC1 at 548(@*Cj7;O3E|x0}ZURuX|Dj1_00o|4a|>pvbvG>TN8X at xeFW%qKnXI%Pd
z{a}yEnt;iJuh%orHIDc0)q(XB`!C0*U-EYthgB at LIH3^T6)-xG1ItbqmGLux8mMl5
zBE^kF=3A5aEwayJQO^gJcn9p-kAKd`Po|yL6+MYay}Z}VdvA0*X7J&xlL&yvOu89J
zfkyH8v)wuievE7XgoaCC{=)s`KXLz8oK;77$rh9JjLou9fRa~85(Y)tIPLgNI%axy
zEUI2kZm4Dj50zLi0b(kN5<rYvUd at p$(>@)GM(`QAy^pkGe3EsA?ToJ}mxYPi1o?EX
z$Y9I5{m?i}I1*9GOrsQ+Fxce)gedC at xJYrH_adD>cHQ!j at -ViE>h5YEDiudjkkev=
zB&36b=|DQZm9sV^!(IzOi6 at qkz@CpL>Cz=OXu;5)<(F1Q)^SjCW>_(|)iwah?L!*{
z-~ybo>`-HRTMFq_5Dbi`I?$?WB+aoo`y3W2wsa_UR at H4f_Hc{Lg2-u1qRK<H`_Yg|
z*zueYqY at RR%WHyOqLuanm}gL5PvAxy!7DZ1)o|bQ&SJP!!%Z$M_y=c#>6<Gv(%06N
zBCD@{@8o%>cF*=Yxt!3Kw{}pfV`L{^ZJbicfbI^*Hf?$EsX;n;pam3$dzRYb`SjWk
zOOO}rqPIGX6Apg5GWjF#jNW7H at X40_ZOd$Ft3_lQUHb9D(iW5V at 5NcKOY_&#Y0*9*
z8 at Ape7mqOZ%VIxF&!Q$wzz=+$0CFSQvXzb!I*)LI7NL(RvD1ySt5{}hc&aF{Y#zf=
zJvQ-_#jV&3_8vSx`Fc=7W&S-=SEyxSS0kwvgynQWaObD)f`~3=SFWkrQy>c>Y>x$c
zgW((fGMtKSV1UNS{9)E412)!M!eUZdzfNbdax6y{uZP$-U>dM7F=lV9tmGh#N_lXg
ztPFV|H_-9<rd>Ndw|fP|G)TF!0#$u%6HxuR_QrWK3ytf}39lnamiEQP#f13g92sdJ
z(H_)<DlKt0e3g<Kni+ouLiHj&U9dqge-kv~Sl{=R=uB=@Shr&}^#tfQ$uG6 at wIQAr
zlx}7?+*O@);x|_&qy#)1s~WnHMlGS9S{4Dy+tQAH2U#TQn450V&%VA`Ov8d1u+p=H
zAj4h|PM+;`V_TXWAE9z~gXSM(<agBno2 at _j$MoO$2ln^f{lP!p|HHYYCczD7_MSH0
zxZslX*gF^~2SMimGl(e&Nth5;r2jCD7H28Br6L2U4Tcs2Od?v+XJ*15ZhO(xGPkH&
zW_26TFEO#ELCpXN!f|l66 at b2l7+j@`4u^z>3KRS6GG$b7FgU|P5nIN#k^=Nw_*9-b
zI8}r1w;O?$<6(4abe3%+59+3irpijbW`Rkz(kY0PO1oksFr)-#)89?%Eq_yLWyH}=
z_ln~K8}Q8~=`3o3_Rx+1gP9fSR#i at xn___rCe0y(8U%z#*Eizu&nto~sX3W?fi_~U
zv0H-qwp!0s769aM6P^h(2+u#1)5HxkeR|tEVD;e*SHrGPrv~gDc&S0Ri-!I5x~zjA
zDz#b<y(-z3)~A38)6dS%i}N?t+GFefDoXn$G^TDz5E{1=8DDO++vWblcD+4bSJ*R#
zC8e_7sFu1uTG5>l+ifkt-G`bV&N@!#e4VGf#ZVW at iC3<MRl08pS1G9OyZjtByJQEm
zh|{bi4?41xt*;*Ww$<;=CD_BnmH9ZSiD%<0J5;Q+U0UJ~<X{RzSBLaNVOSUz85-&j
zu|m`B at l^BE-}a@({1VNd9#^zoz!kdTg&d^&z|hbv!#-xe?#@r8fodw;$BmmZ!?On7
z4qS6(D3PGHHF6g;D~!hD-<PIU<Xca{L=4Qn1se6NB&s(j(p2mC(voF(WKFGUwEqr8
z<XT;$GO!^aCQARpYX*Z9rTWC_GVFY+Zb&(mpJJWQ$?(V?5G`A0x^4J$5oo{8jFu~t
zHMsKDwl69+k2DM^YZy(7=_mQ`jKLzoYt<19j(Py*yzcSPG_3L1 at R|%TG@`Th-i0k`
z=yg0Ch{K8V42)glp=pV(*SnuhIWE_DRL{c|fM196zE5~*$61G<u({yvneiDz*E8`U
z)tLAI{}o-)b{$a<M5$MaB3;BjGTI{$PLf+T91;v1syhL~#;$P`3EW?}$E~%3{C(fk
zR!|W@<;C6~CFN?YYNfKqa)axQ(IA*TKm*5sL;!jlov(4eZ$}?;W74e4KR_XLsdUb4
z!tPyxaHXIO>7R9y?j#(#k;^7AW*2cXe1Za70s}sP&`o1Hlr{!)f~0x0Ox7lM2rGn5
zBTT`BVI??4I4siN!e832N7 at x*F_V*1?ds-M38*ph7w}x{Mt~9pIKC6fqS8;wC2NR_
zv2hB5rWB2e?6RyZ$z|mPYB5ze$>r*g79+0P9qCE7Gl`7D8sRMz5eX)tC(7f{lkfuv
zv57T3&Yn`)Ik{Kd`d98B0D}4TyqmA~_&m}X at 5D@R3)Wc?ZbL654IMtZG~D8JQICFR
zHt?vR^4c$rf|I3lm4jM)m%ZU!ZP}w9F&L7aetSpG9 at 7G&b8^Dnq%;Z5Fo^HYE%)DH
z5~u?_(^p3>M+B5C3!CF#UO1x^loS?n(mJ8@#%qC;r_9Tj9ohyBCJBb^T{$T)(zL(J
zAGGLt{;3?U`m`{HnEs{w!Rm)Jq`X0X#1M@?2#+e>4L^)wKg}KlF?D6v&DrAwDZ#S%
zRLAImJ&e$KdrAf0vNnWCnUFb8X5!A4-&?RZlffw?R5i(9CQb&cCGg{q<rY=+8;e2$
zmo~bfzKy3hr3s4!N#fZAt<(Uvl(jLDk4+a{-y5fWR~d2r)zP`vHcDnu`xwsx=+>?e
zt{qPqXmm-u2B!@Sj&DHQ?KxG9-LL)hDJh(=-Zq(#0V#&z&@xll%ux!IqlNH!LU!;*
z^>+}B2R5-)%w;P*xnObjpoc#ennm)~rxZAVS+!Yuim8D^e3Dt*xq{u4eEDU2!%9c2
zXTK!&yJ4CqQU27U93kI}+aOS@(cGeKorg2$nQEO9yEUS)`1}Zy-MZ#0W7L0A@%vxs
z#((=Eq45{)xBrRzzxc;i&^>_KF^iw+5~PY0nc)3|QVl0|;e8R=gDW#qmC<qW^SR7z
z0;B1o@)m&f{@z?x+RgBL{jzd#x3t2QuBDeSU`5-mc`4XyCCY3Mp8F}vb+HTeu8_ry
zCb~TIiqvBc0SJ(gVp+FhzubDdgpmY^MJ#se5up6q;3XiK?>;|p4iACg(e)5n{zBne
zQ->7UB3;CFH*%(CT_O5%(F<fOCesNhxn9i;WeFicwh`*Z!#w6LkX<;aAjb}$mCSQ)
zP0!U<;n_6<B?x4R_=7`wmBEsPjulHJRO+htDaYf!*L{bm4x=yGko8SQc;Rh at qh27}
z-G?q^83<eU<oOJbO-3HOepxv)Dfn0M{ujHBMqc?mJ$avs8h#$xbUzOYoqWC{Z^xzB
z5)IBwP~F at BS<?v=>ToTmDFo at 9;Ji&N9%-Du_tqjF4Grn=zj{dD(oR{9B9QxZaxKfF
za0;oKzn>H2GEY9m(0uuXn`a1hV+Fj?>y&QZFlkBx`f>C!4WH#Y<N9TWOr{G=+K9b^
z7{&HSc7Z7KQb^7au=i|A+R~OndA+pee9F<Av~dnYChFFK{N?n_G&Cd(se-<K!%iHl
zWYz#HQjoE7-ef$iB>fP6rG%-q3S at K(5PrKJ`Gz(WS4_{*q)E(?O-2X<s)!VIBv<Q|
z{Hx7(rMDJW3y2GSp7s at ms*#C$soV?is<j>Y{xL{Ob)JHqZe)V83wte4j12LaSb{xN
z;6P#@xRRVGq$;G7x39v}$b=zx|3kuJVMw3?$uhM;z|dM!2qdI(-_=ywzrpc|*bB(@
z8yY#+%|x?kPGC5rq8OGhQ#^H*KmkC8a$|>v)wC**&LGzZI6n4N3DvmXeCcNxo`3Y$
zAjr at 7YfC)HPmTQ3#9T9Z>)nMo8`-YM=BRDLCFIHLj>!gb7LNk+{Qeu_|GXiA{|ooO
z{R8gJGtbqn`;|M<n4UG>OnyC;Zu at P&M7-0jczkh4ziN$Ndew>FcC~GDxc9^ObFR~o
zHFs~%J+4DpL;cM at v>|n~`@S~dO1iA|hy5EdSuX35x%{v?8V*c%E_-_LATppBo2x+W
z)dmL1o#DAS@$toeY34O_5aD~62~@H at t-e~;-MP!Cf=DA2XqVclY2dszhlVF00RH&L
zuX7nv5>l|WqAR*Yd6lNU0)Pn!5^w=iDCaaRpTuVD_AkMt%RtM>2+ouWp{ON+eph$z
zd({qTL-gCW#0OKHDWfO=34jr@;TWYtukiXd<*?zd*ko;1s#E2gJDaX3S-0$|Kd3r-
z^PT${E**B6+)zEU$HBZYFu)+}b#Lh*qUk;T&AZ4Nb&MvsOw|}~swoP$#Xm53w9)Xy
z9_Pt-(PI6G(>2fgA-+LY>#XWr>!;^h*mvm7J1TEy&T9DAoy>#J^=(0=TByYrEFK6A
zZmqkwcQ8T#ITQS(T=lU0cuJ(B>9&+i^J5Opny?LtnoR?VVr&=Y$+jo^Ms`;lXV at _p
z6tGUT63KoO<y200d)X8gk@`&1?r>aEyt at OOLD{_+(2`0pJF0k~LG}8nIo9b8XEZ~h
ze|*<xws9V+o)iWfN25eh${X^QLi;hMAN0vj?h0Ag_mC|b3mA8B5FBVBp(+h55L?#^
zu+6>Jn_%@goi)DLy^J+$yI50Zd``jBN)o|h8h at S$IcygmPw6-l!sl<2#*d{peHL`2
zY<hbaHsYeDVi!+I>(nQZZBa1(K-|fx9Ib)P8k-1Hm at LwW4Li`bl>MI9&%l$kYg|V6
zzl1K9o^cKzRerrycCq(!bI<NYIcst!YI|x}4BjI&*J`9HNAqATa>Vebq~Ym#YIfX`
z#y9f>?|*{r|I_W?QU7nY{^TD?YXcC(Yxxht at 4Nehf0X{ixzu|pURo^GLgvcAzxi_#
zvS=rk7mq=(vr!c>Y)eJUUqdHG1vSy$Z3762Y;^Iv_wc3)IjKYD7 at K!GgApNEhVBoZ
z*X+mJgDmo}Cj0oeAF2^UT6#P?$QYv at U)|?q^?D|UKYEa^OS|pX8Vmwqcrg0CMp^cw
z;euy54^*=KbhFcE(wIs;VP0G}5=lD~uK=>(5in~-OmGPp>%^MwVv%~eA9iyVV%jd*
zPeGMx#V}>diPrP8D}vdoR3Hoiz}7hnUAbbBzBq?C*gKUM*HzZeTxysBwXg<(wjlAz
zN9bB9ySxNU#QhWZI##<5Ag}zekUajr51j{HAQ~QVKGM{JOdCFPPoe49zNxRtLgf~p
z+l2FW+~=1vRj<U1R}ep^vAYf!P$!h*)ic|Io{hYl+D1O^vEr|tfn}X~@>s0h#;kNV
zws0FQ6z~d617V#sg?2q&nbIq|#n6ne)XuPIziO`m at a@h-5IErSbX*Uj_C+ds^Zod8
z+vunjK+YV`*0zEEsEhfQR-RQ^Z0OwVIJ4dtennmZm9h)oyvS0FYDf($rrr4Rgd^T(
z>2q>2gHePe?KR#&)<xjRSnZFkl2?cE$Ym^Qh!y-Xy^!<3bvd7xe$4Ag2zR#zCQ^#T
zPD?%J?~FwdUEi0*vE>s`&0mJH7ejT=-Ck!*!^%KY9c8jKQdg73u%^#%`FB at BxX@#v
z{jfw)hMcnfR-(&on at BYW&46gzI#_1lydZ at +J+fgBBTzk@p+vrIwBpar$a?L$Y8eq7
z(c>G_#uV{IQBH&3!b;Y~+cTADyz{Cu{Mot&2qZ8EHIMK-TBKB!Y0YUu`r$(9YB||z
zo393)y3$jJjw3!4o2J6<zC}pt5|+bh+~cpW*Rz2ZxU3w`i1?!n^x=4MU+$Drm*`({
z%p{0^;ePxda8J!jx)ZhTnT3qP0LH^QcQ}-KrFzo)H$;FoF@@z9B)e`UKGZoBd#6Dx
zfi)1No32eC2zD<#-kWh$rj|S;w~=Gxk}zCY;-3QWBYeGgUx(?Y1=DO7XY<_S0D7N7
zV=Qo at K6=W=BBfz8C at UGEa$!jL;QfsP3xq>1hVCYvY2pi400;wCGc=hw5PT!Pxmy;D
zW2$62xwz!oTL{>O%@_%MIzXnJz*7bL at i@i!YI at EY#R7|<Zkqx77lvi at bc;9yu?qiG
z_2KK8>Qcqv>?-O-(*nyQD(AUnJZ7ALnU?78GGAj5 at Yv|Yy$2u4d(p?VWAz91cFnye
z={|gZD}8LN{38v+jI;UpkyeUQ(K(}+v+Y9#0H99)%p9#>OsLemdf<f65MH8OZ}&;N
zkp>tG%+LF9g17QK@=$Nd=95>SD`?H;0X8Q9e?B>Iua$Fsbjb%Gb?~AdTCWj at k*MSj
z<jv?hHOhyf4fO~fVe2mMHgA`J1sx6M5UMK!0_iW*cz`Vqg^owJMbVnSP2G6YAXOzL
z_i|Zvy=b9p+X7@$ZothA*<NG6LWOkCr!q)VDVH$RnKGjhsG1;~*phnq)+0A-*7wlH
z(Bh~Vzg at B#DQzxm{%NSA+)Kv*DH(Ts#iO=&@2{Q7D9LyO*9zzlDGT(sK8{b!za-o*
z8uqumJ<rmn6lEP|8u4>vm#wYoYuQ}}D+2qbtmzCO^VzVjJ<)i&WS=Rvf~IdGp8kv%
ze4R!3c!pca3L{!=2<alNz0$_`B;ZIy*^0)gTsCB1c)8!c)_$a={d#F#6Zh~~q+G*-
z3`%*0eV4P;u#jpCgo#+k=+<A2v$LB3gHFjR$A3Ll?oBjFJq>VP_`Y{b>Osd}vAMnS
zpNWI#<Gbl~p5Q02r#Oi58{1KBv04(Md6n-yoYy%h?-CuXo%GMVur=PT`4{eG)>_g3
zo_BBTYwh-NW`T&+IcrlOE~L(5x3y$=ns at JmH0T|S=xNaK$646*2=}&12oouRvROgm
z#r57{G5*=?;<qw&{06N{#4Ix=jS@}Qj&SPrlu at Tui<{Mr45|#$zk!E=*Z_R7RK+R?
z#X2F%A(EF_Yppp-(s6JnHw~s-I5QEA^Md$raX=}SznGti<0|oH{2G-=m^*f5E?RvY
z9=jrwU6z$JpXEvimNvM=eVMi>_5*5LV0d9!%_0T&qN+pyn9EEc2%sRm5)kKPWkD|i
z`U7N=+_mY#bh?N26Q(7t7qym?f3owCaj+NBHhA|Vsvc!Y{l;&tJjG7V=!4VpQVBUD
zTRhRNyCzN?(sjR73Apz{fAmHN()Afmx$p2&<n(yciGEMrkOR?1$T0Diz at x62y4P-a
zY8>BS?@XUM&3SCS*b%*ByB*?zos9Tnv9r~2-9%3KXoPJ;q<?$uN#_fP`gRtw5Qhg5
z2AW+VrB(b!NCnQtox)Nq**6iN7+nTd>c%!Y&Ar~xc-YlZeIp`P={;4}{oDY_A9aOM
zaS;1X*d`F999A-LL&*?7pRYOXSgK%&MqmPvc=Hj%P6q1i*rjXduPHm|tSk&UXAvJR
zVHooqXLvtytwZ at RYVfXN>sNB6;DNQRT?7U3K-FG>Z;~{rcqOYhyIyD|&wmFT$^vp2
zs!^&-!m$$CXJ>_cFM5FNM#|*vwXy?`--2FzBzd`xwNQ|Lr4SllM3Bd4HD*){@N)+}
zK(ibzdk-_w0CLrFhxOL9*6gu~?g?ha$rAU_TKemTD;s|ey)M-59^+%T2PU at HE#_+^
zB9b?)1)m#0$Ldq0j*52p{FEfKluK7{Y(1;o2jTsT+3f$52lhAqLHY~#rhnl6fAxRp
zsN-dvnr%1$z4NJ(EeD5w)QNlBJq}+S2JOy$sA@{fX2|I+SMjEvPS_t9{*b-i!;f at L
zx*$u>g(n}jG8Dcjiqoih?5l{nH&ix0ObiBKX+;ic^8y}@PFIG}>G^p60x+v-J?)73
zQuNR)_;z}b=Gw#-AKchDj)m|8287zvcYt+WNc8ee4kNA-WjwYYXY#l#w+>`ZyTaI5
zPBWvI6W+qUSMZ&(#-$Kh#S&T=kVsfoOOjueKez5#=&@%0o4TYsTVfi&yj7R_+Vl3>
zS7!?w7l0Odl2wJV at so}h1gw9Y_ISw7(o>5(wI8 at poLk{pL?HVV)!({uvmqdOZdo<5
z%dYTyt#fOn$1L~xieXL2jh2qjb+zv%f5;aYwC|MHI~RF;>DAZjs~4os++0wY at X>f_
zG+ydHP?>nov-8 at St7<uUH#+vu>2!KO8 at iBq!)V(?AwDt<(wHCWh#J6J5PK_P$`Z<c
z?4CMO$keV>=sQ|w at TTy?0oCd~D}jjari2^rV>=Vmo-DG>3rrScHWy)@3sSt*Eqj2T
zBYZDi2c&tr;NB}*_LQ2+lHGZ^irky3D`OpI$msLQP*d45;&==+zkw>1Bv at FR0RSzF
z0u2tlZnR~fL+nT*L}ce;M6z6BGEsC>W|LX at fKtEtshwX8d=K0?pHP^hsmAH_vR_TY
zH-B9uOqVRmdI?jk;B7VeuL2VDqoU{7PjIVOLLGtk&0aqkf9`AerTpgV6(&8T1ebvm
zf9Yv0WD>Ehcd3Ld-KhhqY1joETx+*Vo#?@_U7nV!YYM;8mJaJu+=G>c>{H&4Z7K}=
zSaQeJ_ut*3x+$nMj%B+S40;2i1+zXnef=*L;{SI{|0_ at Yj{1MIwZ=c-zDFSRKPFMd
zOKAPRy*~(u at 1Gwe^Z!{8Y<Pd-gQ=C&54C8qOqJHbkB=~;VrrF<?JwFP+(*XUCy|R`
z8I_W~ZL4Fuqgv{_ZyeCQ7V8(58zz8OO=C_+l=-Y*4Ac%%1SmtK<X3)-#euXH-K+}x
z34EIMOR~3<D4~Vd{qrV_6i<uCA)0r$1)m>dbYvJ;7;Wx^Ygj7~0b(~+^?D&hCW9(x
z|5A=aIU4~LJ++shxUs7cDwuq70L-GIn7<&fSD^FgMqwy2mY)n^5kR0`CplT9yA&oD
z0^#uyQ+%G~S_eEM#nx8;CG*gydPbdqM)JF#qP(WmpzTH?TFMf?xSH4`ywbJ|%Ft^X
zZ*?0E at EE<Wn7$Su_~C-SVf}9SeO;bh_vy)j%WC(^(7wJm=N}xCJ(K&zsZH@&>>UsK
zt5?(ebDBM#?=neCC)hsO*m~#vPLz+_Q<)Y0Lwk4JKWVZsaFwZjrS)4oAjH at D;M|+l
zP@?f!#Mz>w4~oIr2$GkJ6caL;aVu#0L17woyZ7!_g-pw60rSn{C-MYwaHYy7em)~f
zcp|joP@$%5NWAa_<E)K$Oy`AFt90ihvm2z`ps{5{Gs<}ZRmYN}#g67gIX*QkQ`}P-
zAe_$rQjz#37}xkrM-r9YV2Bsy^81Hxfg1aXt^=8lq+{WBcAoaB at p4GBH_iRXsKd9-
zh#ei{LC_*!t{i2(2J6@}-(!O=p|lQxNg*xQYG7b&;+16Pv6RJV-Bs&c-vx)vC{%~j
z`0)s0CgYWK9xLKaw4*6p)@UV-a>?+CT0}r6jg at -=Y`qg!&%TiLuG5}E6IeN&!G&!`
zYIGMH<dk|h5#1p`B|in-t=*WdcHd*mWt3h#F8+LX!!ze-lApGpQ<{W=kH5zo)}2mZ
zzEfe(7x?Y<5=I}3Onnq at Ofg5(Qqn8bGvrg^vJRvo?&%wKbe!Cwer9hrCu?38u4D1P
kJ*WR>hw?w$`HuzuV}buz;6E1lj|Ki?f&W<G|6>dM59FM&TL1t6

literal 0
HcmV?d00001

diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c
index 709954980ce..7b0ed4df983 100644
--- a/dlls/wmvcore/tests/wmvcore.c
+++ b/dlls/wmvcore/tests/wmvcore.c
@@ -21,9 +21,117 @@
 #include "wmsdkidl.h"
 
 #include "wine/test.h"
+#include "wmvcore.h" 
+
+#define DEFINE_EXPECT(func) \
+    static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+    expect_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+    do { \
+        ok(expect_ ##func, "unexpected call " #func "\n"); \
+        called_ ## func = TRUE; \
+    }while(0)
+
+#define CHECK_EXPECT(func) \
+    do { \
+        CHECK_EXPECT2(func); \
+        expect_ ## func = FALSE; \
+    }while(0)
+
+#define CHECK_CALLED(func) \
+    do { \
+        ok(called_ ## func, "expected " #func "\n"); \
+        expect_ ## func = called_ ## func = FALSE; \
+    }while(0)
+
+DEFINE_EXPECT(onStatus);
+DEFINE_EXPECT(onSample);
+
+static HANDLE onStatus_event;
+static int onStatus_call_count;
+static void *pvContextOpen;
+static void *pvContextStart;
 
 HRESULT WINAPI WMCreateWriterPriv(IWMWriter **writer);
 
+static HRESULT WINAPI TestWMReaderCallback_QueryInterface(IWMReaderCallback *iface, REFIID riid, void **ppvObject) {
+    if (ppvObject == NULL) {
+        return E_POINTER;
+    }
+
+    if (IsEqualGUID(riid, &IID_IUnknown)) {
+        *ppvObject = iface;
+    } else if (IsEqualGUID(riid, &IID_IWMStatusCallback)) {
+        *ppvObject = iface;
+    } else if (IsEqualGUID(riid, &IID_IWMReaderCallback)) {
+        *ppvObject = iface;
+    } else {
+        *ppvObject = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return S_OK;
+}
+
+static ULONG WINAPI TestWMReaderCallback_AddRef(IWMReaderCallback *iface) {
+    return 2;
+}
+
+static ULONG WINAPI TestWMReaderCallback_Release(IWMReaderCallback *iface) {
+    return 1;
+}
+
+static BOOL createTestFile(
+    int id,
+    int type,
+    WCHAR filename[MAX_PATH])
+{
+    WCHAR path[MAX_PATH];
+    static const WCHAR prefix[] = {0};
+    HRSRC res;
+    HGLOBAL data;
+    char *mem;
+    DWORD size, written;
+    HANDLE wmaFile;
+
+    res = FindResourceW(NULL, MAKEINTRESOURCEW(id), MAKEINTRESOURCEW(type));
+    if (!res)
+        return FALSE;
+
+    data = LoadResource(NULL, res);
+    if (!data)
+        return FALSE;
+
+    mem = LockResource(data);
+    if (!mem)
+        return FALSE;
+
+    size = SizeofResource(NULL, res);
+    if (size == 0)
+        return FALSE;
+
+    if (!GetTempPathW(MAX_PATH, path))
+        return FALSE;
+
+    if (!GetTempFileNameW(path, prefix, 0, filename))
+        return FALSE;
+
+    wmaFile = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+    if (wmaFile == INVALID_HANDLE_VALUE)
+        return FALSE;
+
+    if (!WriteFile(wmaFile, mem, size, &written, NULL))
+        return FALSE;
+
+    if (!CloseHandle(wmaFile))
+        return FALSE;
+
+    return written == size;
+}
+
 static void test_wmwriter_interfaces(void)
 {
     HRESULT hr;
@@ -220,19 +328,174 @@ static void test_WMCreateWriterPriv(void)
     IWMWriter_Release(writer2);
 }
 
+/* test_wmreader_play_wma */
+static WMT_STATUS onStatus_expected_statuses_test_wmreader_play_wma[] =
+{
+    WMT_OPENED,
+    WMT_STARTED,
+    WMT_END_OF_STREAMING,
+    WMT_EOF,
+    WMT_STOPPED,
+    WMT_CLOSED,
+};
+
+static HRESULT WINAPI TestWMReaderCallback_OnStatus_test_wmreader_play_wma(
+    IWMReaderCallback *iface,
+    WMT_STATUS status,
+    HRESULT hr,
+    WMT_ATTR_DATATYPE dwType,
+    BYTE *pValue,
+    void *pvContext)
+{
+    DWORD *dwordValue;
+
+    CHECK_EXPECT(onStatus);
+    ok(status == onStatus_expected_statuses_test_wmreader_play_wma[onStatus_call_count],
+       "onStatus called with unexpected status: %d\n", status);
+    switch (status) {
+    case WMT_OPENED:
+        ok(pvContext == pvContextOpen,
+           "onStatus was not passed pvContext: expected %p, actual %p\n", pvContextOpen, pvContext);
+        break;
+    case WMT_STARTED:
+        /* MSDN says dwType is a QWORD, but it is actually a DWORD */
+        ok(dwType == WMT_TYPE_DWORD, "onStatus pValue not WMT_TYPE_DWORD, but %d\n", dwType);
+        dwordValue = (DWORD*)pValue;
+        ok(*dwordValue == 0, "onStatus call for WMT_STARTED not passed correct starting timestamp: %u\n", *dwordValue);
+        SET_EXPECT(onSample);
+        ok(pvContext == pvContextStart,
+           "onStatus was not passed pvContext: expected %p, actual %p\n", pvContextStart, pvContext);
+        break;
+    default: /* the other 4 cases */
+        ok(pvContext == pvContextStart,
+           "onStatus was not passed pvContext: expected %p, actual %p\n", pvContextStart, pvContext);
+        break;
+    }
+    onStatus_call_count += 1;
+    SetEvent(onStatus_event);
+    return S_OK;
+}
+
+static HRESULT WINAPI TestWMReaderCallback_OnSample_test_wmreader_play_wma(
+    IWMReaderCallback *iface,
+    DWORD dwOutputNum,
+    QWORD cnsSampleTime,
+    QWORD cnsSampleDuration,
+    DWORD dwFlags,
+    INSSBuffer *pSample,
+    void *pvContext)
+{
+    CHECK_EXPECT2(onSample);
+    ok(pvContext == pvContextStart,
+       "onStatus was not passed pvContext: expected %p, actual %p\n", pvContextStart, pvContext);
+    return S_OK;
+}
+
+static const IWMReaderCallbackVtbl TestWMReaderCallbackVtbl_test_wmreader_play_wma = {
+    TestWMReaderCallback_QueryInterface,
+    TestWMReaderCallback_AddRef,
+    TestWMReaderCallback_Release,
+    TestWMReaderCallback_OnStatus_test_wmreader_play_wma,
+    TestWMReaderCallback_OnSample_test_wmreader_play_wma
+};
+
+static void test_wmreader_play_wma(WCHAR* filename)
+{
+    IWMReader *reader;
+    HRESULT hr;
+    IWMReaderCallback callback = {
+        &TestWMReaderCallbackVtbl_test_wmreader_play_wma
+    };
+    DWORD outputCount = 0;
+    DWORD formatCount = 0;
+    int readerContextOpen;
+    int readerContextStart;
+
+    /* initialize globals */
+    pvContextOpen = (void*)&readerContextOpen;
+    pvContextStart = (void*)&readerContextStart;
+    ok(NULL != (onStatus_event = CreateEventW(NULL, FALSE, FALSE, NULL)), "Could not create event\n");
+    onStatus_call_count = 0;
+
+    /* Create WMReader */
+    hr = WMCreateReader(NULL, 0, &reader);
+    ok(hr == S_OK, "Failed to create IWMReader: 0x%08x\n", hr);
+
+    /* Open file - without providing an IWMReaderCallback. */
+    hr = IWMReader_Open(reader, filename, NULL, pvContextOpen);
+    todo_wine ok(hr == E_INVALIDARG, "Failed to refuse to open file for playback when context not given: 0x%08x\n", hr);
+
+    /* Open file. */
+    SET_EXPECT(onStatus); /* WMT_OPENED */
+    hr = IWMReader_Open(reader, filename, &callback, pvContextOpen);
+    todo_wine ok(hr == S_OK, "Failed to open file for playback: 0x%08x\n", hr);
+    WaitForSingleObject(onStatus_event, 1000);
+    todo_wine CHECK_CALLED(onStatus);
+
+    /* Get output count.  Sample wma has output count of 1. */
+    hr = IWMReader_GetOutputCount(reader, &outputCount);
+    todo_wine ok(hr == S_OK, "Failed to get output count: 0x%08x\n", hr);
+    todo_wine ok(outputCount == 1, "Failed to get correct output count: %d\n", outputCount);
+
+    /* Get format count. */
+    hr = IWMReader_GetOutputFormatCount(reader, 0, &formatCount);
+    todo_wine ok(hr == S_OK, "Failed to get output format count: 0x%08x\n", hr);
+    todo_wine ok(formatCount == 37, "Failed to get correct format count: %d\n", formatCount);
+
+    /* Start playback. */
+    SET_EXPECT(onStatus); /* WMT_STARTED */
+    hr = IWMReader_Start(reader, 0, 0, 1.0f, pvContextStart);
+    todo_wine ok(hr == S_OK, "Failed to start playback: 0x%08x\n", hr);
+    WaitForSingleObject(onStatus_event, 1000);
+    todo_wine CHECK_CALLED(onStatus);
+
+    /* Check that onStatus and onSample are called as media is streamed. */
+    SET_EXPECT(onStatus); /* WMT_END_OF_STREAMING */
+    /* (audio file is about 2 seconds long, so this wait should be plenty of time) */
+    WaitForSingleObject(onStatus_event, 3000);
+    todo_wine CHECK_CALLED(onStatus);
+    SET_EXPECT(onStatus); /* WMT_EOF */
+    WaitForSingleObject(onStatus_event, 3000);
+    todo_wine CHECK_CALLED(onStatus);
+    todo_wine CHECK_CALLED(onSample);
+
+    /* Stop playback. */
+    SET_EXPECT(onStatus); /* WMT_STOPPED */
+    hr = IWMReader_Stop(reader);
+    todo_wine ok(hr == S_OK, "Failed to stop playback: 0x%08x\n", hr);
+    WaitForSingleObject(onStatus_event, 1000);
+    todo_wine CHECK_CALLED(onStatus);
+
+    /* Close file. */
+    SET_EXPECT(onStatus); /* WMT_CLOSED */
+    hr = IWMReader_Close(reader);
+    todo_wine ok(hr == S_OK, "Failed to close wma file: 0x%08x\n", hr);
+    WaitForSingleObject(onStatus_event, 1000);
+    todo_wine CHECK_CALLED(onStatus);
+
+    CloseHandle(onStatus_event);
+    IWMReader_Release(reader);
+}
+
 START_TEST(wmvcore)
 {
     HRESULT hr;
+    WCHAR filename[MAX_PATH];
 
     hr = CoInitialize(0);
     ok(hr == S_OK, "failed to init com\n");
     if(hr != S_OK)
         return;
 
+    ok(createTestFile(AHH_WMA, WMA_RES_TYPE, filename), "Could not create test file\n");
+
     test_wmreader_interfaces();
     test_wmwriter_interfaces();
     test_profile_manager_interfaces();
     test_WMCreateWriterPriv();
+    test_wmreader_play_wma(filename);
+
+    ok(DeleteFileW(filename), "Could not delete test file");
 
     CoUninitialize();
 }
diff --git a/dlls/wmvcore/tests/wmvcore.h b/dlls/wmvcore/tests/wmvcore.h
new file mode 100644
index 00000000000..7910110a24a
--- /dev/null
+++ b/dlls/wmvcore/tests/wmvcore.h
@@ -0,0 +1,28 @@
+/*
+ * Resource identifiers for wmvcore tests.
+ *
+ * Copyright 2017 Jefferson Carpenter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WMVCORE_TESTS_RC_INCLUDED
+#define WMVCORE_TESTS_RC_INCLUDED
+
+#define AHH_WMA 1
+
+#define WMA_RES_TYPE 256
+
+#endif /* WMVCORE_TESTS_RC_INCLUDED */
diff --git a/dlls/wmvcore/tests/wmvcore.rc b/dlls/wmvcore/tests/wmvcore.rc
new file mode 100644
index 00000000000..6d4e35dc988
--- /dev/null
+++ b/dlls/wmvcore/tests/wmvcore.rc
@@ -0,0 +1,24 @@
+/*
+ * Resource file for wmvcore tests.
+ *
+ * Copyright 2017 Jefferson Carpenter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wmvcore.h"
+
+/* @makedep: ahh.wma */
+AHH_WMA      WMA_RES_TYPE ahh.wma
-- 
2.11.0




More information about the wine-patches mailing list