From 2a60391fb4edc1e75eb33e20f89a317c786ba656 Mon Sep 17 00:00:00 2001 From: Katie Broida Date: Tue, 22 Jan 2019 15:53:13 -0500 Subject: [PATCH] Make Scratch 3 project timer more compatible with Scratch 2 currentMSecs usage These compatibility changes: - Use runtime.currentMSecs for the Clock timer "now" value - Start executing hats before other threads change values - Update test and fixtures to work with earlier hat execution - Add test for hat execution block order --- src/engine/block-utility.js | 15 ++++++++++++--- src/engine/runtime.js | 9 ++++++++- src/engine/sequencer.js | 1 - src/io/clock.js | 2 +- test/fixtures/edge-triggered-hat.sb3 | Bin 42128 -> 42138 bytes .../fixtures/execute/hat-thread-execution.sb2 | Bin 0 -> 55053 bytes ...t-block.sb2 => timer-greater-than-hat.sb2} | Bin 4152 -> 4068 bytes .../hat-threads-run-every-frame.js | 12 ++++-------- test/unit/io_clock.js | 9 ++++++--- 9 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 test/fixtures/execute/hat-thread-execution.sb2 rename test/fixtures/{loudness-hat-block.sb2 => timer-greater-than-hat.sb2} (73%) diff --git a/src/engine/block-utility.js b/src/engine/block-utility.js index b163e4d5d..cfe18a227 100644 --- a/src/engine/block-utility.js +++ b/src/engine/block-utility.js @@ -205,9 +205,18 @@ class BlockUtility { * @return {Array.} List of threads started by this function. */ startHats (requestedHat, optMatchFields, optTarget) { - return ( - this.sequencer.runtime.startHats(requestedHat, optMatchFields, optTarget) - ); + // Store thread and sequencer to ensure we can return to the calling block's context. + // startHats may execute further blocks and dirty the BlockUtility's execution context + // and confuse the calling block when we return to it. + const callerThread = this.thread; + const callerSequencer = this.sequencer; + const result = this.sequencer.runtime.startHats(requestedHat, optMatchFields, optTarget); + + // Restore thread and sequencer to prior values before we return to the calling block. + this.thread = callerThread; + this.sequencer = callerSequencer; + + return result; } /** diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 89beb4ace..04ae1b9ff 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -7,6 +7,7 @@ const Blocks = require('./blocks'); const BlockType = require('../extension-support/block-type'); const Profiler = require('./profiler'); const Sequencer = require('./sequencer'); +const execute = require('./execute.js'); const ScratchBlocksConstants = require('./scratch-blocks-constants'); const TargetType = require('../extension-support/target-type'); const Thread = require('./thread'); @@ -316,7 +317,7 @@ class Runtime extends EventEmitter { // I/O related data. /** @type {Object.} */ this.ioDevices = { - clock: new Clock(), + clock: new Clock(this), cloud: new Cloud(this), keyboard: new Keyboard(this), mouse: new Mouse(this), @@ -1536,6 +1537,12 @@ class Runtime extends EventEmitter { // Start the thread with this top block. newThreads.push(instance._pushThread(topBlockId, target)); }, optTarget); + // For compatibility with Scratch 2, edge triggered hats need to be processed before + // threads are stepped. See ScratchRuntime.as for original implementation + newThreads.forEach(thread => { + execute(this.sequencer, thread); + thread.goToNextBlock(); + }); return newThreads; } diff --git a/src/engine/sequencer.js b/src/engine/sequencer.js index d5d71fd50..464cd7489 100644 --- a/src/engine/sequencer.js +++ b/src/engine/sequencer.js @@ -138,7 +138,6 @@ class Sequencer { activeThread.status === Thread.STATUS_DONE) { // Finished with this thread. stoppedThread = true; - this.runtime.updateCurrentMSecs(); } } // We successfully ticked once. Prevents running STATUS_YIELD_TICK diff --git a/src/io/clock.js b/src/io/clock.js index cbb9f2428..cb3d0dd14 100644 --- a/src/io/clock.js +++ b/src/io/clock.js @@ -2,7 +2,7 @@ const Timer = require('../util/timer'); class Clock { constructor (runtime) { - this._projectTimer = new Timer(); + this._projectTimer = new Timer({now: () => runtime.currentMSecs}); this._projectTimer.start(); this._pausedTime = null; this._paused = false; diff --git a/test/fixtures/edge-triggered-hat.sb3 b/test/fixtures/edge-triggered-hat.sb3 index 762ec1af45c97aeae9dd83de5b3bda4ea1a43df5..cd9464378bdf6570a43e7da2f1420fbf435a70fa 100644 GIT binary patch delta 1276 zcmbPml4;gSruqPHW)?061_lm>nTu@vGUSCWtz%|j@Zn%!-~oyj6y;~7CYR`C73b$I z4XqD;Y$otmOK$7j#+8PfbpLxTzii}VF~fU@+)3FjJkF_^b9Zdioxg;oC}v-^YP*A% z)nOmCG}>iS*Ar(?KIN!D)B zKA84BTkVz9th0Qxy))N1FZ^5$oi==FiYOC9DHG*9_>pugr&p~x>*{Vp30CLado z?uO+pi`e}vQ;qdpUrUFdtykW0HNNmpaCc|t^N`ERirHD`*Te>8tn$7nBQ-}sKR{pM z$I9>iS3U>t*;O=A=yRL>(Rpnq-j`a0ryX~lp!RM<8YdSyEpq&JX02RzAoqb~%(r}=&HXg1GIZ@7 zT}`nqLD5k;sVfiGFFLk9M67E)`*ZQ;?{j3%`u`J}Z>Rb0Uex}KnGeitbAaxst&!JP#s9VFy*yv+M@H#n&C1F3|Ndm>mRT>V>b>ildimV$)fbO9A8g-O znRb7#ir%fy7pJ~$T-4H4{`>jyzn9I^|27x? >?uzEAUZbPoIo#eOk6L>>|PaQq$ z%)2Fnoh@9VrK(@*d)qj` z?dUePWhv3VAEHj>zo?mHcln3lwpn#c7!055bglULp=aY6pXp2mei09tzde3bFVYmQ zxo6s^XpJN113BU)Vs&~dyOPgsQs9|n)66ot$F1)uD7Whr-^a*|x4a&DT?X^4IzA;vUVO)cfU9mEc;f zcCY9Sd``Nvg19rg({-BVrBWBYe=B9OwRh=)xQG~yFB{t5&M}tl*&tp~v3{z;LZ(#* zxHrsCwCDIcV+o^SVp>>P{akC2`KMPc`aQ9I?p(#x)Wxl{{ymyABYlm`rsG-zscmcKC&!J5b4-qgFQe@JbQWH|qNwMcq7K zrLHty)H?Iv_vII|zUrf9@A)5F*O@XgFc<)_3NU+H7;k>ZoXEri%KDpw*`{=ZS(9H+ zya*9GFo~H1!a6?dH9Id#2{C#9B3+2`4~wK2Z%pQ1Y^(rM;P~N2AxR|JAl?e zfj`^iL^d_;0B=Sn5e7t=({WCKaWYWJDIf+p3IU!^UccB_9%QJkTg{@Q>^_AVevmbWcT*A!2V9LS3zylO5D9X=DO)k;PD$dVa z8d{%!+f3lE7Snb{&SjQUT>froPvkaQ&iP6u_KnHSCWXZ(Ca;YW3Y}E;X4$`Y%Bj|c zdluwftk1dkv7+Yvk9S`>Or|*FRA_^Ces+f91;yM~YXy+&DpXYx*=jO_QrTSM>4tO)y{a zSa{FdztW|9SoGh;EIG2|(d`?P8@4@GdDgNtP;5z|$PdkjHq9p8o&rbD-^dQkUtF;u z`0=T0%UoTycB&pZ%+|3eHTJ;7o!8z}S$r_}c)x3VYH{?H;6Rh7`9@+Te4m_(>L;A7 z&d|tiw3-;{SIn2BkhwG~YhLf!K=qj2y_0mbRJ2mgpZVhOC7Z$Q)x|7}%qii%T}cn~ zJPa4N-nx*aTg-cJn$-TFNR3_ZWAA_Y_vlGQ(Xaj=KLQKO)BY|>Yr6f#z|_C=zd=)$ z#=(TCRW7>MvLaXKeSECpRX6L=BmAffaZQZVC zGi|?5+o5sf#kp?|)0_{^{`-3JyPva9zk9f#+S0<(#{TuZ_?z2a#>V`uy!ZC|#NKO* z-bscW-KBoDqv+#@5HaTa{zBqs*Y4=(tQUQxb~Gr$^WO9%E-&Y`^KR%~T)%Tq+-l#l zzmDHy|98%<-+uNT>o?I`;t#~{Uwn}{r^QjM%~0Tx`;pIzN|{mxQZuhDefzC=^BSRu zqf2(`W!7?@;<$P3z?7WD{AEl3v^`Tlsl8V|N&9s=mq6jULlb7%-%DGQ%jUyop?c;! zLv`Rcd#-m=UTc-J%Wp6RhuM7Q`S=;ek=*Ffux!GP;GJ5+L_t!twPbad-HhCRjmttl3Z|)LAty4d4`HBC;P^oJ4IU@FMYCk^CdH_?d>ax zD4l=IsF`~6Gv;C@7Et!y9LqMP8_b&gb>c;c(5Xqx91zyUS+Ci7QA&ZyCl~2Ll>b^J z#dvPA=wf3C*JrU5lPlZgY&NyYeT#V@V)GVDG2WfL6Q<+?kh^Iz_Yz|TkdeXb{|T;U gXJA+*&cL7oELad==d8*1XQ@qYSt7u;Y!OHp0DIXu=>Px# diff --git a/test/fixtures/execute/hat-thread-execution.sb2 b/test/fixtures/execute/hat-thread-execution.sb2 new file mode 100644 index 0000000000000000000000000000000000000000..6338f33a51120c126006405ae6ba925ec3e9632a GIT binary patch literal 55053 zcmeEv1z42p*7nfd-9y(fOa~<;pn%=j9VjX&>Q=Yiz3mnY5LA>hz#^nOBm|^;m|=?i z*E4M0x{v#u^L^j>;=0c7mf@NAoq6B&thm>`)|%N)@t2U4$6zqB7_so>lj_3uA6_nr z!7Nq6U=-o##?2vXS1b#|uMG{^kTARYR5eX?7jO5$x2@ft^p2&sRjO<6&B0bnehNGL zmL*|(Dmd|+&6)TG=9RxXMqRtlwe-05mVh(LS1d4GxN?ZQ_K@Uor^+<(tIll`e$%?W zPGZB+rUTly6<-T>P_N}pDbpLqi`iK_e$38Fdr*vx&CDIpG+5X0s@r+CiM!on%8aVF zOk2&%dv%<5Xr8;wIJNM%?4s9{(+|BG1)JOMH$OgMZ=e?Pc~EoR)NrDKpyBhLg$m~t zgN|EZ*IZA-<*q(2LpddW>(Gg2cMd}_La@>|ahL40a;ciR(X^23@lPpPl}~SWHfm=b z#2roWSbh77+A8Kw4mEy1?Br>FOyU&=aaBF#Ac zc7N{V66_>b{eitYKJ+aK9gUk7oEtE=nHo&dDf5uCrNn(Ss-y~nLltVLdo7BY{Ka^4 zmERiao+@u+JLyqfh0bGZBQsn!UEF3N8*#nxfcPo7oEog9T;CeinK z?ZlOuJKri|PYg?1pOC_H%qE7EZryTZ`(w=;IG-gucjV48KT$0ibUcSCT(y~9(5&g< zId>v<;%1)(w=y22O5;v%^j>NxC9rNSb*%biR;^8rc+PD#Z_3d%l`@QWZRCASP%N3f zVq`+E!SorQj7n>39}K^|v^-($q$w4oo-O+`#11?!&n9#FuOc(tnEJlCd?h%8(7zt_gckIN!^SLpl{9G^p z9_Pj!;?F)Yw)cORbC#GN0^2dI`+F$SA!hJN>W*GW)-o7y`1ixnel2t44fM_Jj_zlZKmao_xDgA2?yb&{D z{3P$ko{RVWh=_F`EbHIvVKC?iAtDhUx^R4g1e z!>-t{WNGjUhowuFty{G@WXlG)@P-xP@Pa>HvTc2^Q|QJe%T~CWZQQ&fbj9YaE8xcK zgExe_nyn5C+vw!z7#<#u4=3Y8Hm`Cd5eNiFkofnPIBg4FvtixOUPxpznU12fW^VFW ztjj9&h<=N97qDdeip`72qEn*78<&Kw#;#lw9PDal?&IM>C3>4-L&G+QtOK#k;hylv z3=7f+l1O+8jfA5!@dPq+nFBl{QXL3*3YF+U#ghpX2O>N&9q4#Eh2%iSQwd}%^KIVF z@Zf$$y6K}PotA?Gzy#{ErTmCs5Bf2Phc=$ zO=pmBL@J(0qv9BNGL?)YGVw$vWf=ueL}&11CJ`>iWHLl+8jeWB6W|b>Ad-G2#xeq) zK_r6s1QHeANGH-^O`}q9L^woeI#A$|vW$c$(}-|)3JFJm*Pz2BItjfCE$I}B7ny`7 zG2seSJcG=@k>D2{HphgW&~ZN~Y=@cSm>s|pKd9UX{Tb6RT%8Qspuk1w%Rrq>1{3Z} zBa%S`0-cJZpbdiJ33M80fx@7`F3^@iKqhF4MyBAXupts0V9>}o8fb;_)6Ek>?MPDu zG6OaPI|5@8L~4ZXf=a2dbGRXh0DFXM(#d3a9h3OOIuzc;1VxZRPCC4cN_Rkar2XuU zUNk%tHbA4oYZ*u|DiiIKEZWo`oBpOG7sqd2`*W@R?x@Hw$qYP+NXIc~csiA~jDRCJ zFu)k#NO+P1kq-MHB4rUt!C*E94HQa({Somb3LP}SAfY`m=->ksCh`F?D3J;4pKfCr z@^msdpU7d5Kf*1@cp`Fsa3~Vd0gf>VBv2oXL__K$lEG>WCh{2)mGu2O6s$%^K|`Q} zs00EL)JdjLf2KX~ax#Go=ZQ2TvIc{Kd=i4-yLBjv1PYjeOaK=`v4adrrhAb=4-5zn z2A)a7QHXdNjfrER@TA~=(A+oO|LC9_LN)*@eFFp%ndn0TKo~pV@H;GmHh;$mSb^%9 zpe6?SU!`O+iHWpKrhvAP&pHrkcp?S)=pRZ3Q-B7+!bm}1m*1%vxx-f-|2!uC2_64D zg#Tk2`a$O+Zw1dGlE~nIL;~G`2)+xJfkz_q>+Svsh97|A&shBrOhZNP1BeUm$e^Md zgBOzkb>Z#+svCY+)YP~;K-uhEr2L?)34@1~OwP6A?qD^n;C8w3Dz z1O-Hd><~!~OxO(I89*vL0gwkk2cHDDhm=d9!D%{?3fH6%{_OlH2~dd$mmrt`*#Mm2 zWdJtFzZq~r5(BOa_hT^8BNIFWf`EZyiU}?QqM=7BL9|_X1(S|kgpLA}2~k4A)0uw? zH!mt&0g@0MWj7Lzij)J-Alg90A2j$aTz<%_q(#I<|72?Y2j-$6I3wd20K`NRL=xH; zf?yJeO$MYILu|laNWWk_;!l$;ia@4lyCg_QcseMN3i;{V3S~inc}Tw`lq;EJ3aFO) zyMjoN%HiE85mBiK|4B@AE0i5k0%X8x8bVAu{m(7~N@Y5Wj0Yxx1jZo3W$B{SMJ18I z;8ehCNStIcq7if=1Gyih4>$qX1SuA96iGnpLIe#`;1|e&Qr!2?LLu6iU~TYc$V$K{fQ2A=nFzX=B1vJhM06eG zbKvhkJo%IFh;AJU8ln-XC@DhDgk6)UpmaJg6$IIIL}dt6xF#4B&Y+E;&3^yvYt;V; z!{#EI@HCC^5PwEtNdu)p9)cGkfc&#>i`X6+G)@IefQ*1lkQOQMPPj51 zxFWa{SREV{a1V9}rWXkcaYYn49v}gD8kPP{mES9v^sm7!07*Ke3kVt_urUw-Gznr+ z$OxrSbdiZP1Tr8IAPV^}{109W1QlKYK>`H>kTevKjPKV0B#1H4JRQg+Js6=01UbYr z0XQHs16&@81{7jcaAJsi$g83l1gZ>~gGBk0X+`0?4EUl*ofMSjL=YtcAp}u?z6d2? ze@p;m2q7v8bI36`kc5O%4RBz99TJGjfItN4k)0t{p&kMZAW|Ui$bc$zV2b4L*FTda z6yz6G85CqXvS{zjv8n))A>5G0K$n2C4DdGM_v-+trx;KLP*Erb!|f=*JR$lBlz<l!~~*cTaw{{QzL96cJwqj~?Unl(8#;CdS|kxCn!Y3NQkNfuq7P;7yP< zi8va_L1!Xxp+Ip5&*;EKQLQpYcA!*1&VpPKN;a^kNFH#}pZg+|5OgXkXh~2RfJ;!( zR>1WjNWs!%c!Kf}^+!WPDGFE*ln%1*ck6)f)%h3d|Bum0l-B4_W5B+tW2_DW4-f}7 zM@N+n6CS}4X+P(@fIc*&2=op}CZaNh3dPWO>#tbxqmTT@gk(TcfNTyCM5B-S3Pg$s zdFi6e!ax}j9r>9jfaQQ6f{;vbMD#vX2vH%Uf4BZu2nnVogNK3NK~XDmIXD0n6+oyc z`y;Fe$ND+X0zW4Lc>;ZcLqNy?1Auo!sq)?WUm+yWL68HP8}&%WGCv)l3Sb?)AK0C! zI3+Xw%%sP_4K#^7g9K?CSPFy}SRQ4PugiZ*!mll%-zz}qLakV~WTUH@sLA!MFkHVT zY{ll_HSi1CWWP6%0DKTe1Ni<$PX=HMc`F@&gaKZN5C9b(-`3yBhi?0O*XmEc_*K4b zL{~F1yqU>>E*`8QW@!uxbk9g|9B2TQ2FGCyNKT-TzFzw0esCi?6Ez$dkO=|F0s9ediSim5 zQY+8^qKHK!x(U}8<#{N-;PRrPh%{C-!{xo8-$Fus7@;SQhRQcG4w4iDr2Jmizknt4 zul36Bdm{kf0PF=m4{iwT2c>g{sD}iaMS%bZVTH;wCTxI!4naJif&*2GXf1ldPj`)8 z4S5(|4Dbq4x#YFks-4~6#%k}WC0z5D!)DxN%r@RO8-w7l>)gNk{gKu zY?vvsDhegYKfv7}AwZ=|L#-aDctn-PUl|n=I;cv-08!$miW~vja40K6^#z6^Fc3pT zlt*M#xIBphMiuq1XpmY^9YciX4jckELQDk;0t!$|)P)o^esDj?`p;MuPz8!R92tO> zfRZj!EGn2m^CDx8*-ca^Qblz)lL>v%-;Ie3i-_@8GyR!4k0H=^h8?r4s0a7EFVMXx zRMAPWLIQGKDzqDDP_{r;CefhG z1Evr46I>P89P%p^r8FjjNh%G}0AjAl58*5%0wA`?HYfujE(ql2ZyI(Y9>75FAp-3~ zT@X01>kno$`erPjLe(Jh^0>ZBW`xmV` zP$(UAjZ_ZoMbr-hWP#cZRj9zX5loAanE7*40<=OOA5?Q7D2QN8ilz1IOOS@8ybSw z#bD468uF0-&4)aUpL)sP4tf58qd;{-2ZsRaL5121T%RH8&%nSyR9uNDJu2tGV^A{# zs0s5gavAj1fgV9U2h|z44>P3gf=GnQOep#w?kKC$@0E|08c|g%X zon!qH#!t%(82O<|77Tv~XjX?81If2iS`-u_@=-{bnuWQH_UEz#_DO)2ILHZQI%olq4LKL;L5%h0iBtx7DH$bs5&R)G ziF8B(Uj-`=MU@wk38fCIc)@*XP(Y#+P=|we!&QNdk^mQxfPc1_sQCto0@)u?0jj7t zqC>wM0CVg?#Qedg&;%8gq9OyKQWI=R6*b&|4Wc~41W5fs3qL;lL*M@uHG?NZq%siW z{Mraa!zJX7&@hG)6rvVL4&!e(3erNO1Q`PLM^Md#s1s5oLDWB?feKOGjk?SPNS8o` zpr8i;g2vf*YZ!e&#REqe&>aU$q2=F>eSxh}Ma3=^sMlCc4p|1M&3Efi1a6{!IKT?z zYf*_rAd!(2q8=d?b_()Bw;axb7k{@71>^(hK?6q-kt4vg6!JR#&*Nv*6G3(Xb_EE^ zL^DtbBLEh}{=mvWcc{c~1n2t>9qnI(=M?DT00u%Uf<%Ux7O@`&P$FpULr0MT6Ax&R z!XAIh%#o@QMWRBl073wvFN8I88oz%Mig+w^OQ85gWLY$$CK5%CO&u%ifJ#DCz&r;9 z0&0YR|11<)1bvWzf~Wwj$Aaf?G&x2okvbs`z#pKa08TdsY$zZ>3N&4UJR=$sfwn;u z5CEJEI^l>&A`VUiorBS+sOOI=Dnw#XWD-PER`ltD@76!lNhshlw3DF02HYD^9qKM< zFi|PsG(@0%U}uphAfAK(7!&|PiV_T&i3ZVVtd6i2P1k55$AA(EE<^+R1tC0E=fh>d zEdV{x_5hhcLo z+JKuPU!_BpiIym8DQL2RCay@ibja&qHBo1W0Bv6Qq==|zrJO$oN`EMR6j8$H6 zqyP4i0ssVz6hH-3dNAt#i`pgs^CJb&Kf=ZTOCtsFACVWqNFjg%0O*Fe6bx?> zjvxktD)he`DFD9zF;e(hzF79%L;={$7?MKRK{Evn6kzD{R}%#^VEj5!_A|0z}HUfdaJCzYP@72c7;q1`4RxCW46np@9NwEd1Sp0;-Bc10B?U0XIjC0X~`q zQbLRVo2-9i@(*0kS%3d!Y&jvH)tZ0U3d?Ms)9cS^pWULh2NC@S%J3zco;RdJMWT z$giN391{mV10)(Kd@tPJ8ut5+$lo6*z&s5N6i@>HUmPgFM$te4QCA=+sGx=Rs7NN! zXCuBz_|0zr`hfxz9cZ9{YX33j0Koh|IZyzif(8n}RM9{II4T+_ppQU^e*GcaA1e3< z1BGq&8>3n99Xj-b1`1^SKlwen-Cw^)#}tEa2&WMaaYC+SN=`Ss<6rU!vuF1I|03Pr z`=a2#$Cu?`mt)_F`^)c({r@l0efQ1Mf5R`!{k<;={=F~KgMJVs67bUN5bI0?IV#Rts|F47h*;* zcf@4Hmy4egmzS6)F;!x+#0CkR#3Au0u??7UqX8pf!8B7`-AkL1I{HqV#&HN75(d_Q~&(vzI+2%@GeDeLP$-L?4V0J{4@{J?7xq(>a6v zkNK+yTSpqiu1S57lTgZ2l2`6hI;u!l*e$2b;vM%hsqI&~nk;qkB<1R^x-}3gt|NMY2|s??!J7aJUidL%rOt z30=Fp9J`Km-Ribvg|Y8&(*~x9o69{>S+1R+Z)Vt_|5WF&Mu9R;o+AB1TzquK;3mE; z=Wy>xC%ZkOUA42mtExx7PqsgtA3ul}-!HdM)m>+qp|7!uQL>()rn^eAT)0%U*tn51 z1JS&d?4TZlPL=lG+Mc!>cP{Pz+&hW0fOmLc5OYTktLCV?*yxdor*WSCb*-DK{t9cQ z_lvuXHV%&PO*p2#dY$}MvsQ;Tl@6z_TRpvf2e}o3-jU_9}F2vq4+^zFP zJyQuU`%a=@bnoDMUTNRD?$zy)&6-U?P2tVs+Aegevu^h96r3B`Cd*XM(H}K!u!u63 z!Y1lJ)KXWSBVPzvm^w(}jk132+S5AWOH7??J*#0-^Y-@k?iBV%Uh(i&xs#e9M#n8A ztPfkBHJxGTq$5xxD@IHAVlEHL@z%4}c0OpyX^^Ws{@JfyqKVLcxx15H%Rf9)AVW4x4KjqB}*aRy9N}7!xY|!inwScdTh``I7iKqlQ=O)j(~bbUkK|@>h;t zS6HE=V0yr2wcTB-k7ns6MuxV!3p7?KsEg4AGJT<)7h4+}7uR8`*_FMYazB?g8FkI) zd=xCl$SR%Iv$F8Px#Kw zqj_g6d!0a4jIUf|c+h4k!I?P6o@$w9I%s^XXX_HtpH=wJld2)k8ZCa&b8M!2< zl>cc-Lv8!7>>lA{i5se|M$>IK5x0?cIZ$onEVr8Cj1qMoDt{8Q=Q(!^nhooFtDcm7 zELvM=T5|l;(uVZ5OROb=Zt+v+^4Zz%8VD#9#rR7 zC0VhpbV6}mVQSH$GH$g^)4|@SLXPwnZ8HmNd?$QU&eFlf=8NSf^V_DrM)%Zt5_h>$ zZIs&Ja<$_00_ptU@_h=+OV3n2_~O((TX00?ly0Y0CQ*rgl@jP+ZM(v1z&zVb(YQhV zvG^m-{bqXgjneSKGx>LOUGjDoXqUBARW$bYyGtEWmZq{(c1C)*>|wN`wK zxyHV#t|MAKdm6$%?I;;nI6hyHW0AYRAiq5O^UXHJenp9s8YbqO3BHVQx;x>s9m)2o z%>tVbmR}6Qdx5OsW`T8)=<= zv5l?mknO0=B(tR&PNVxeC)VySJ5u;4zbCIaCoE@EUSLT?wM(lXS4?KT-cFmDWD;GU zY+*07inb25b9A_D8)EcO)|XRJ-%{pSw7#G&Up%iMJ3RYCUSg?D{pX&m7^0@FMY-b$ zwT2Sq&~6=UV{Nz90W@oMN9+8Ebca+Gv8Xu@TX3x4YFohLb0 z&&jrow3xP%w9HP-db};p{yuJ-{aI5>l_KHOmU|UN`3X4zxoNrMb9-{E@^Qt#RL|+y zI2^07!SW)}j((bIhqtqdwJEk+fwRK(STeL_#Ok^%s|^bsbEr9I^OW5 zHXRiVsXQ=W@A!~9N_mbyZ$q?QYyZ(+%Kn_y5&d4-8t#|IN2P1C)iP&%EYA5gzqQ~* zVP{EU&FbzDDPN;U_$%~H^d7=xn=&gi`@Q%bjud-C>?!3#0|D)ERkI6}v$kd`WZlS- z&bw7`s>HC`p#8+CrOrKDIjRXv!gO)tZPwYd@Z%h3<6fADYit_DbX(M>7w-5NmmZeU z^>I)3_S}&I%?fgpflx+0*6IcMD1%5V!f&(n#=RokAeQ2fT7TAgEpePB({QiEGh2|( zNI#QNlIfC-%_o$FHjHpI6!6%m_)hA0dL?O#LzaUa@jTJaG1=C|=$=A4{C`X4S1RUd zWGwqIDa|Nj@5l1oqLTS_BfY1krWg?IeFmr~R3vi2uTCI^xX2#ZLE=#h*tYMMj5iGm_Y zu)j6p)6D`>)~WRIAG+U7e&3cZS3s=Q?mHv9%1GK?oMb?eCOvYblalCp@I{vW4kwNK zYw1tH5Zm;8=4iMED# z+tOa6X*jjBtoC7XXwK41owV$?`tQ`!Rr14YcJ_>ua?*FOT~Ab}I#Cn|k%S^j1TCJd z?r_@pSNRXTz?R8XPYcgxcV+0Ob-$hP&N$PzNUvUpTc-FKJKe#G@{sz9C{IwMoM)_N zzNFyoaJu)!AFy70d0aurzn6*okephR!h2Ve9Z^APa~@`^<(Qpum`iz2y+=MtQDrDO zO{B>=`k9_oauMdXU8|`qvdL~v+xzxVN@A*S`pLq$y3_1uGDiA~t)@6eQu-)y)N9NV zmjtIP2aHgm1$C3BZtZ0(V zRW2W0x@o5!ct*EnFLTvf{60D6duJ%Wz5S};B|FtVYh^`v+m=C!ikY#MjfbNec`3P= zX6f?9Eza4K>}X-7A~tBzAz9N^==t%)Tc1~VlKHO~X=z1vjR8Ds`D6MEEu|fzh@VO7 zw3#k%+&7Lp!YH#-*YOlP)SFg+t;94do!^(#Z4m} zp`_3^xUKc3d!KUM=qP2NDwWQTZrWQ>kaPC!jKot*{>J_l z;Ur0uzINOp-_L$`J!qs;1}7wy*v3sVm1lFOyye8(#+Jpj#6L~bt(@00D7jfD$K1ib z-SHgh7~{IfRn7GCZ|XT4vrnyeOcB-pKf7i zKL_ti3UZq7lOEXZpW_~aJFaniB)#Xzm#yW3ERWapr_&!TfBfoYMy}tN{elOIS_Uo_ z(YD(h(n*_KyZu}y4NdsPg>QLO`PLx6i(X$)(vUtc=~T?EsF_ccQfb9k+ge8kR5u#> znJuuYvRy)Ajk5^Qot)@9gErT=TSkVzw&Uz)Zqd9C?eRw*sXo$)UzxG9M!$cD++&>? z#tLSqEc$JC)2KeY$##>rc=+MsG|EQDu}53@Rg3eyQrS<}J=*c4HDzhBUi(W-kb1SD zmT9cHxn(gf*=eg^a$v6S2z@^`Np7v+MQ3JxNa^ehspN*(Ut$;uwwW-)#a+v`oo z?l#|R5o0}zG{J-IZxG<(u>?oZdiCG z!rGZrY&eiI1rtIx6qaRy8y7X-8hbL7E>`v(lt@Va6 z##F4f#Sy%P8)Kr-|DoqPLb6`I^fAG>?y`E>;*hsb;-sP#VxPUVE&R1DeRQ3=ju8gC z#Z=uq%1(``>*qGcEz|y_cezjJ$m_2uT``Kzi_K}yBvCE@yPp7@}sEF%*EN!lH*C@@{ z*~Hwe$v)YI>TfnF#d{S=%pge0mcOfOZ~d9Vls6+!);NjlFM$0m68vVIjlt=WhNzr-Utt3ph`g4PoM)Jn$ zCN@^079uMp9&wdt|wY9l=)K+7UfsP^80B6)`y~-)c zUui1CFN-2+BuZ)y9RD=|~<*IV)V*%#_9MN(H%lOpH2NT z)q1>-;}+eE((?y9*oT^9ii%zxi@bJg@ZNzJ$II{b8z?&JVf1x%CTZ_6dgQ3%vv~U8 z6lV`3yH6T<5*mZz9G52Lg562%dpB+@c(5TQzD9gdRh?+)U{I-jT1(ehhqQdc+Zj!h z4cy`^FDb{3Dhupc!}XTAwF!my3T~xE@BBdj@@RCUW{{zuzPGl#_Eqdos>#I3(-uwS z)3vdA^2NiJyjfk5)dT5PaT0eIMKs5?=Pv9rlv%2S*T1iwq+Y2-w8Xfi1bR-n>wV0z zNXJ{MZ2;SUqispK|J!RZIt+}vh>1r{WYD`H|dAs_jS%J+{TD|d(ZrTA7 zbA?jew$6LiXVPPyw%oOQxZ!0b~vM_aCdPn|4b0y<-?pM*|JJHlXTQn2NY^mt1b3<(&t3ZrBA%*h}XC=yuUw-HK~2Z zr{ihAJgvEB7G;q-QuAaeSj|GmLT#V?EcxrYu~e<;&lY*l@^Cw8Vl36hv*Xa`^1d=`N=5P1cArLh_kKW)*a4g#uD&^h> z#Y)}Ph)R9)YyJ6Are?E_tBQ}boYX?C^OUyfa!d2)*1B)S?vrBkTl(Eumm0t1GmG*Njh+?^|M@KiKlD zDL<8ULy@J6(Tb2A99=8EOE;DwGtGRq*u;;Hks9pLO~OxnmAwKUhy+r?^M1)XBn8Q_Qzgv3X)xJpg2fLF^s%{UL zYk3%cR!^5qA8MAIhn?-|JNwnl)1Ex@B$?fOJ#I2rsmHRGk(L~@?QZ51|9odof$FH? ze4S*ue9R4TzK#?leroWnJ$|KlFZGMVXL%pF&b<+Ju^(^8$=qv?TA8NSenak8gIfJ} zN+&RmBQun?J5&VJ&h4JEpK(Mte^iz0%l*Jv(YChOKiTvCgL_ghw|#ymK{GHn)>Ru4 zb06rFh%im`zA)$f%rox#rk5rCxT^gt`h{J`s+!+9Ke`!l_-R%_I=4{+ht<+OFC#zH zF|=PTh14~9-MrDj>!ePNZNnp+UpVvn3|ih4L?@=-J9>ZHYl+6IvI!=xSR2(1!$G_Y zVvn%}-p}T-=9YUOw|Fe0%D>7f+fOUyg-L|QmmEszG{r;7tho4@I-qg>+rf41(JHwA2lG1tP ztT+40e0tz6$HgkXg2CR)J#RXgb%%0C69tjj*p2B$Z6@-!jNTeFt&D73_s&H+P&buXkk1ni^77U zJS&VtFo)UOpH8(Uu^N1{$NF=nA~=5RYS}0vYxd^VnG5>ePU`gW z_jfV-CJ6?(N1K~JRz;^@9liS~jngBpvBs=Y&q*?$qt$;%;WcGXQ07{{1xy#N`pf?C zjt_kY1`CI(d!`j(9?!Wr<7!v3O3QlHa;tS_j}&I`Z?Mlv)9~C`nQJ^3d5*Kx5%7QM z`lau|p#D&EM_xAdVfs0_tJ$w-b&<6qEl(R}O3&hn@!gd(Xzzl`R$mDE=q#meDa`0G z=7b9a`1sbqtZk8B&d<2s`Z~JfjE1>&64pwQK5&fhuH;L-9OS+>Y(ByHkovZM&rU;* z_z+7t-1jXL+371A4S&B-H;mlx|(>E`ikN9Fl% zYpN4>TyQ*=bqkxHDt^|AhMT3kdx+O<#oMZT+DC0o;ChRh0*CuD7g&7}I~lD#16AEmgf+%<{j=BHSVNyGV~>|n=k&0b3<-y;So$Tt zk9VIvcgiw)N0qtaG~4qwC)IBAzjV0`w3uKg?FiNkJ~fqS+ax}*$FH|}VBDw~C%o*} z*pgF;#|xrn*9NN=;5u!us6=oscPt#-Wga!{W(Y4>X>z0G8?pGF5LW8I#^LauoV>vY zBgb(kU7zf3nyF2~dt0^18~3SnKERCP9OmbTc?GZVH^s^fHgw=vwnH06YPuKair>Q> z8#sCQxl_kgeX8Rmi)k|a-dEj+rPh#g7oOg{Xl0G}Hp9t-3%V`YPJ_3EnQa{(P40Cb zUvSndv8X*zXC^M!950v7-o#odV?&Z$7`=JQ>eoJLhM$Fv9dbRt2(Ar;cU{ioJd8Yf zHX5xlnz-52WVo|aw+AZ}8=BL5ytq6z@XWcB zEm1913X1-=wKihv;sgDC4>1Z>anr7D2v`?6>4KHE*v_u0UG2Q}gI0ZJ73$CTo!34g zdv|5=e5rlb2kp=5n2qdW&m5LDO$tm6_E=vvZMuDh9z@m)XZp z-VDrnH=1V2ceFE(5Wn3wm%l-Ko>$(gEg|wj6%;oG-QIC+`&d^5!Q7TFci-FHHb0qu zQ7m-|XD2p>gtx-V?PAyW*2rF=QWslp`fXX;I4P|Fj%@3*?pi^rP`%S6Z+>Llsl?Ns z&o;Hr*K;G!!?~*3_V;v*A1<{%J!|{MinS;FlT0{5*EY}2P5g#I*}l>;)u%yc#g2PF z9H?$oTSn?4c4$}dUD{uAi;ZF?*>4ovv~VWZHXrk$ePM?NPkwkjx2pPP;_TmM9VXv6 zP+%i_&haTV$awbffp%uElKKuWsdchp&lfBplV#?14zwh&XAE)pq=wqprI+fV0p^>w zXk@Xy36o5@L|lGQzwqF?n;01 zQf(*Crd}|(GjO0ik|V8uHlRM_c3k4-Um&d!4sT z+Saj(ku*SnH| zWE&y9*(yc)R?n^ODRN~D_OhL~9~-N(Fb?P|UD!Z1N!OHszrJC#QmC&xcu&~?aU z0(_TXw^9P@MY}&{4ZdOlcgvG?v;ETb@A2weulC#=|U3U9Dg`hfQ85bfISYaF|h;Qxf>Ko7--PwC8-|Io!VTnVpBTs*srhkYo zPRdc=%Jyx=58SqvpUc}484?>*B)2-glS{b%A`TPU>aTSCXPM zd^iVN9|$RyF*9y#)LVOa0^W!q*x2UN<2aOpF=g`$Eh3K}|}l*H)z~p z_qB`@F0`zh>9P4xaL>f$M&tQOEw{QZ4r+?;?)wqWLP5{i#UbsW8Rs63L=G+^lDEFjO-u zn#ezE5j#sfbjrGAeo6W(xYjKm-6exOj6NGvv?_A`QRl-7(KXFjL288Y2kKN4q`B$`&5e7MSeJ1eq>q9{5EgwPM5RfAa%#SYt3r} zG)v`KZX1197mat(6ZWUJOz%k_RuKQdURrqjLD7+_BcYFjI;yduPHu!VD)(7uTOSVI zw(gucdA-{*9Z!;OCU0l^M%I<#I?QHPVZOpc;n9W1?4Ja6c4Nbx9EsD^I#@QXDFc31 zF*7h5JXhp;&e6^0y0tNTJBEzK*7sQ!%0)gtE_s6WbYdsobTji;#|C8!7NxayFv+@P z#-erciayXIU0uv>gD9Eedv0!{Pg{VX+29#$1`*t)+nuD(b`W8pRwti z(X_UEaftgZ-F(5suExF-!y2Q@dL0W-N7K)oJ=>IUq-P=4kX~z_rs&5y)lM5F+3{xV zS#x4xtlLbTr$XnRa?YWlq#>2=p8US(edjKpPfX%=Pcu16RkKf4eBbxDvk)V+don|9 z)q$X2T*x{BgV$I~c&mp`4ZLkToby|B_yxw*11XKHPNPf266g|} zS;fq8I^3aI?CZSMBh2BRF2{nr7>NtlE=nbB?eNuKLfl~cOzC=mMDJa(^OkKBlNNf< znd0VSvP3e0JEgx~@D4EUdfnp8=TU@;z^LN*pV@jcukEK!9$2(w zmXKMglQO)DeS%}cPwpG2o1e~(+;Hjf&4Bl;K68UR_KIc(@)fZ^(LOi**5k~=fh}ef;stY#47tCrpQ#{p%%3*6q;b|J zrx0E2FsC<_CFJ?>4!6z8_kBF&!oY9G;;uCYXp}lUvp=qJ4Kn+*(H!Gf-lGe&7n1xG zY%1k~d0u_bxEca!7QULC;&J=hxsp4#b0&=rTRtVGVq+xt^v&ISaG2Y&wp1 zT=VeYZdMTIsNe)|d#h&dr$;9)&@MG6c(k@@8xwap6lq)+u3+^KyI{M0Y8DMFSnX42 zxmZT8Kb(c-B?!uU7gZg6RdX}=w?+4;g;J6(c4x@B*dFm+tm=Ma)vb)nb9319RdZQSy)IQr_vh^t1g;yeBIE)dl1$EiIPxUy%9FEGF0=fBW+-mmU= zOv1z~**bkPd>g@*?yKdql8Ue0`fYyXrm{{MOM7WztwF%3G0RjaqjT3~$=p*5R!+>c zPf@BCnsU;3)xzDJq6Wi{wU5d#AHH7wDz0m?o}Xil4Oex};7tB(*-JJYzw|l1Q*)dG zj02?0`GXuO?z_IGw&NA+Q_>=4T#CLwHCK0dyyXS*kogwb7rary2bHI!{HZ&FJ_j@q zQ?+)DCa|ShcUZ}t^XvB%>`K0KH}mG%XFXMk(mO48I<%O`$U6_4iI3{VGyA5P%((CU z+_q9#bx@Zb$4c#4-W*iwoKpRu@W$F`$vnouS>sTgi&>4L|8UFjS=B(t{DA3mf+i2r zKk4rglVKn1F=K7)-q@sGV(^k1VRoZ2uD6;j?`7Xj3OCD<>k(RvnCeiSWM?1FftC)pD} zs8n(TJ7}HjdrP{?>+j^ujqAHPbSL@kvfg$2!NfiI7rIemYQkkwX6C28$Im@9Ynpqm zNjm12p6Q*2eF2>Oj>Q#+U(LQFd!;ev?x#lzL5_)Z8OwVzZ~H9->(#Pod9yYyiJN+p zctOdK?bI6E8QY)EUDeHLIXqLexPws-V3+MZ6 zH;o#xZeQBm+l}K2Sz--uGNweQTp7B%D|`H~nKgl#hrgqKXP}llB)b@QZ}P!Ki)Uz2 z#Z|9x$Zcs|%Xvn8#}1Ps$LH6tf4Wwfl+YTX?M1pxu+jA%cHrcXo-&E^em37~UXJ@Q z=UOM^DnAvwDSxLUHK*%?_BmXjO`7V#0U6#-nKWzLiLVzV%)ai@ zub)2pimlWiIW#;%;+&{XPi?x7xvutTaq+L>*;dm@3TB$pr5rQC6}4A1$=PQXKbmCc z@LXXXx3gzDPkpp>(4l>D-q|M_*J`hMzvyc_tsOyl;}D=ZPsn2J#^6lleGC^YpZn3R z)POL0pqJeHlD}_=!BMU)e_Q(C{8ihBy?J%R=gq~4n=FRqO9U$i4yZUdCi=gb73zPD zXr$RXbfFK^x1M{RbF<}EVOe5OMBA;?NoN~3sc720u{*0hA0sDRB6Sd3>Uw!{OaO&h zWb%vbF=1f8JGYIqqur(Q;`^T1(-G@q&g6CRbM*7qj<}~2zHC~RJ* zPrXB&HDo+wHXy}vs@<7+{P~9mi=u4biM4G|I%fXLqDyPC)K1KJ#cT^Zx8ngz{btdu zOf2N*34XZYFfyxC=?OGD3wv{VZmXZbtKp!mW^ ztkk9tJ>fKSKMK$B4BE_!HYMuZk-Paep{F53brXKr@u+?%X1IUNsGiYW_m#7hW?XVD zGg&K@!p&xH;0^FXdM?$>O0#}seS`X7B-5WKZDL0}YW-5_vQS&FS^ln_`2?4lgb4>6 zJv7gb9N|o7hxXI^a+_usJ$;dVpK|Aygp$u#1zX!A4(SG$C9d#YF%9~4&eqdTPo=t^ z$CgWv@*Fr{cvtv4d!=iA)7a6>8&(ffvm1p$rt^u_RyIl(1crik#rt^ufZen36BO{L z)s_tVaUbz^3rL)X#&dZo@m&y9nlFqR7c0%SskPg$$CQvBNRl{j^sCFXDb|yHT{fDn zlNSuc@tXN6Jm0R@RTgQRV@}=bh_cLU8@P%MByP6RQ7sxQ5H40YVfVyWV#eDESBdMj zo{e;H-f)g^z4{1Ef&x||?e3>Lqc3urQdBbRPT?%{mr9TZ+9VztjdQ7(96l++dAg~U z+<4*m{`&p~_N8`*PyT5OAHR**8*?n*axl@v(lNmLH#KPtV?LyNJ>_3I9no0e+6SGAUCkWCD#0^ z{GcF>t-)dSS#{j5j>w!Ax9aYODEdcQ|FA)~;|sfmTJd6whZ^OIElFOAQ@bbJAV1M@ z8-3BYfMvwK(c9j{DAiB(jB1MD$Fr+iq}8m~5|*2tRkRyv$8>3}C2RV7Ojh=gvHq-Z zna}Ed#=6tj*HKifo^vApX}6%siT)Sp$p+Tq z1?=s;o7mN?uvX9V?QaVnRo%NCPpXrF` zxSsQlTf=?bU07?8r569>!SYA->F_TTsh_sFY%@()S2j~TUa8DN$t}oV%V!^Xk)gZH z>wz%76;Fp%-sn&|_oeryV5h8W zFIPRPFu0c&(DkbJTw&mc;e@46dXk$<`nYE`PMaH;Zq!hcZ&VC6;1d>jmH4DF7g`?B zSS(#R@_t}L|LnG?PZhadZ@0yJJ#BhDr*iMW1#N*v5;k0;L}9r~w$TaFRWV_t1Is@A5wPpjH;J!7k9u4_2{ zoN>CUhV=Ro46n0&W%ZtdlbMWE)x;x-D>EaSPDqv+owUAV%F#ZezDK*yT!W(Fw#uo% zK^^O$epTwgKuYhtFTQ2lay>KNrvxRKCDF53yx(SlqK z(eF6C#?Dnci!tuo)Ht!iys$VgH7n^&VnSTfp&V8RPmyGK!2TEWxq1a!(+uQoN~r-Z zfsA?hE^LR&u3^`1&3gTE%VKunnq0d#gy$LYgIR`MIjVAYzvB0pZ`J;wHdD9Jn#16^ zd%7qPZkbG0)D+S>PJhlTpILIaSSB|iWkXy+{G}Xn?_W~fN{TC7=Hua^* zx+}Q7Ay#5_Jy~;t-V;rDfGIzqP$ZrXDM6N3+r~PS6t=&b7{^ zI=D_^OvT+Z>Q>+ksL3~Fu{3v=Bw!`~Rc5_`Y7Jb-Pi(qc}qyJ~UIaEE@K$zfb9 zQ^jpLJ;~NvpC{`)Ak}-gY3-+uLP5@OdR(g6tBAC1p9Z)-8U>PkB{GWz5MjXthlR7PM%@9-Ii*pVe~-E~* z-GCxe0s?}7ig3ES`#10V$NafJd+)XOTI*TQUV9C7q<4`CRuufmsq&m zQj5>3W^&_5$?M~y!+D|CqVA+T%h}xhzYJ6CFy1{_>kgWhD3|>7)mB!%DfwUF)Pldu zPyf#Fl=B+nbsbBhouQ4P!Wb+qGS8jcBW+!WXihV@(>2MsO=fB8T(hxaQAtwatAgZ; zo^AU*UwBXB-*;?|?i*$f`xdjlbAGpl*^4`kjjG{%gA+VV;~vS`h6zwOgNTEk6sr(Cqfh#-&v4_bd@AEMRw-w1ub@(W@qcVda&wk`PNS-3ao|0 ztLMtQ0`&00q-#l)G0P*iMf&50ccx|bNtY%LijcFu0$1z?RpHN}wVXD7m} z0jTSzS%w^l;wOhB4T*6^^o+`iADMa~J)!g0`2Jy|8I0gYlT$jV`E<>lFWD96J{1>6 z6eIN{?O^mmhczj#BTCK} ze*c(N*GV%Bt?n>7bxP`*#L$?&(VgNmIu)l~>!gi)6WX0o5_oSi$kJPu)S9ZQEBwWC z3;KPWU00-;hmxY_rG|B8b$lJOAUZXEb;|a%(WxKevGAFUn80e|Fll+yf?7v4^5xg3 zRRzT#*43KT+t7v4iJd2*rcQ*sh?6_$AyGT8T$eqOi40cbIaF)nu@C5 zpJR(cK8Am7Q!MGhU`Fj`MUd#T0kEks6m$94iTZK!4|dV>%}r+On%Iv9_Rk z!{_&f?xF?NZxt1kl9&S-gEMEPM#Y;ujE<2c&hI2iGR9z`YCOW9ZxYIXw&>~wbz5rQ zeC}3QSahQ5mwXmwdCdBZL7D$c702_V*T$UbnBM7d(twyzAqKqNf6V+vVfZob+xfcW znunh=3x5@U`a+QhptsTA(+_9fBlI{mrX?mT@kDa3#04E@iHh*bz(UIu<<6hWzul`n zT=i!Or{I4Dt1BnTwnKkKAIUhCH6_iIxIPAs5yvY#R>tchdy0L)AZit!@}p zH@*7q=dT5{g3@xD-Pp( zZB~`MgjTTk{qFME_PIecBEL&q_Qv#)DaYbZ#$1k*Cj?_-BRh+(F~z`Br(Guy&u!{n z57lIqo-S;Cf3m`o!dlSRm$TOiBkRY_TwsokQ8>Ej7~=i+)W0 z7V&jx#m0|t!J*>3hIT_|MoC9Wc0w*I^F^mc@tl~9nEVcPVcUg5Hi&iz%(0cK!M4ip zYwA+J94fx@?p5Ken)S-*$mF=1tc<+l*^knQBKVl}7;}f*h(^&z?gYGyT<9d~M5Nwk z(zn{`qLOd#LkfmfbZZ|N$d5RgF+Fd0&hGT;Bx&sa=q=HVsDuz3cMjtc9O;u;kEr{$ zZfbyP3O`E0(JO)8&UC|2 z@!{`++NAOUMNMyuK8&wx)qKRjgp1h)dB?J*bgoaR>tKs&i;528@Kf2BXl#(UC$%0^ z23tDTZL9e3;n>^5?_(;)x9#$M57l?so}1ZiNtgPL-splzRb(*iJ3oefhTcXQ8$9dU zX?WItw88jA{VBJ={%%CciKd_C3ru>_(r)W>4P7Hr&G9Qb{2kd4{!w_0bD24h_5m6d zSZBYiv^3XLPyY-Q?sywrw7Oa=J4jYX3`;M{abvFdi8eo`x|A|KfgOZato5J+3RzxUAv^($H{ zxWr#-T`hamsH#l*Bz?c_J*8xG!&jXb-4Sz<_+7)PEOT0FQm>f%k@v!fi5_syvP$S( zkxQh}t~=_2=A^2zC1VTA-<|w$rh0&6gYTfQbEo8N1JP{n-&8CiJUTJzT-Xi%eNG3e?PYHNZF$11fvXF7_&89&@Co=WxBWH=IA34FGH{Kw{YC- z-^>G;7})L#DsA64e~Bx(SGcGk_EV2qhBVB#Qt&PLeP*CrC~@-mu~#BKhmH`|aDQ>$ zv3<05sMcGm-}S5C*I{MTKiUc?ALmsnT6&o<+R>P}^uN0mXAkHSpZGk=6n00{jX#w8 znlppB3N0etv~gqu8(3eSm(2U%`>?(2Xnnn`&3{e!D%qYDlY2e0H05T@j_}DLw*&)t zC%8@Qa@t+!nYWAn*RR^z#0vb=^AE2}IMpYAD$Ht{EV^s@*_2!La{UWRk%0#4bg#Wai%!M68%r8ToBGZ z!J5Uo!aPV_4gKr2>t?lP*Qb4{_+0%7D4kHf;pZ0fI@;Kn!5PuHqjO%TrzYNy$P-=Q z{lyx~3^EinkdhkQW^Iw){ywP2S^n?mJD-(#xr8!c^E+@0`K z!t0zN%+8Fz@D<2E~O_32!hxAwO9rYD+jPI6`U%HP=iX2#Tx zvdE*t>#P@e0_{I64o)WBay`>Fw5B&Os|S_!{bc%NuZU_&*Lf(W$dE4m@jMO z68j}|8Fw@NJT(Ukp==~=^(I(8%m4c^{9At2$kNhJp`~p#$!%qh$*ghlQ09T|>h7GZ zs1z*vx@Z~u8m$gJLwQVA`!r6n;h99)vbcU&<>1d5CF1fo4PR6ZWOsH4rE7F8kG#?YbzDA$1A{{Egzwx1e`IIHDgEx){bNpT6SD)XnoTtZzP-7Di;_W?ai z^17ujPIwr8h?`9v2_FNh{h(*3>#-$VeWM+225KgjR(ukdp00f-iT2FmV2MpxtbBgY zoLp^ZQXD006bnF}0jqVRr#>iFW)v*(n=+zkE(|LNHfl(q=u_f)j7BF zxAzRsNlcB3y(4VKl7WH2iQb^I!FAcTPWx8E|9QM_V#TmhQF+=|&+h@YmsE9B-!8>@ zDZO9!zMONYlOr1AU8QUwIsGQrA;)D$f;pg+ws&dS`BhnV_VekojkSZt3mhO_8r_h= z%rEYj(U+fdDa9ET$u>f9B(}fYx!lpqVKQQ>9pb8%!mt08hm@9=b+4mJNX}UdM{Ggn z*?hke-DX~~X=1k|3ejZ$|t$!lB;7#ET zN!H{x_p=Y|-J6+tI&o3xENWtKr2Cb1l`>Fy2R#d9Y(%$V;TuyWNpzd21ruPd=T+OC+Vo447|+1rd))$7G*qqE#q{IPgq z<>Mbmj7`X@s7YPV^u9m%=io!VuBUH`En=@D9dVY~zL*bMN*z<|-HaX7$J$?gi>l~T z((CiSYDH_g6O&%wcS2Pu2FI-l%Nz^DqmcM9xLmVH*EV~njypQ<9YO{$+z zQSy0i+1%P?;(m@J^xbg}vj5ljz~GAm3Uez`zJ%YUp70qQd|R|R#adyPn~St76@gz! z-R_FWvQrfwzljt>yl*+*I$q5U@2?&Fz2CuZx+HgKJ_h;y&JY{R+{b#u_T1=D_mVIC zSyJ0rxwWFa>QHk~!zHZ~Kq;|#i~AiMNb1eYyqI`fGytjbop&C$lo_r zZt-7Df7jS6v%h?)t8Y7RDMVNib)7eKf7Gv_Ut@Puml1I^?iR4dbJlj*FvZZ_#4t=z zm&mKzlE0^Zt*ly7bLRVK`3vV$yuHJxF7_Voek=Rxa;a&~4!f9i@<*4^d_xzl|DoTb zd8+6y)%<$i(En>m_4eAIEyb!4UInvj?BtBxo)P`&eFo)_Q>!Aj;tPX4oWo25bi?$B ze!u#d0+Y&qZff}P)mHPSesODwP7!>;OHItrPU#adphxfa?1{nzC3f5_kR))wsWoUcaaLxeT=bjbh=)iTpgOZ+733?w8W5W5;k<;3L;pW1V`P znx;um$rO3=Uu`2=rZpU{BYg|`iK{xfIrNKB8EJdEll!jj&C7+;pblk>yCkvWk)ETz zsotj^uAHavNLREDZUVp6)ShbS^}AV@7A)j!Bwjll%5UqlvFF9?@{~hi=cq^h53B_m zMAcipUDc|vDkeykzt%T>{C29I->jCjneT$*1e63y*PT7a^or~LuIrtSYeebj6<-&N zNF!FABA%1HRD6{`Z6EyOVdL}qXW#A;>wDsqV-LgbChg4{o3GEmm1FHv6gP_73yO0; zHmp@8s$sK!n}jw}CX4@S4@&Z9c4Wc()m zX`iiaPDr zfNb~Wn^$X-wTCs8${gi(+2YoZP3(rP^#$Mm6CX7A{SHQKBsIA$^JShZSDh(M?bP8L za~^opWi}ks_S3-{Oob~!iTKB>#;Nsp>JPL`lB+GFKsUEGx+ZmHw~+3gbCSANCaFW@ z)YZWiwkF*H?MCf1)kI}~d1RZs`EkS3`c;j0etR_i+%n81q9n{opOd>VPoJ&qQW$rK z7mEDhdtxrrZPhhsD5{f6iL`esx%pB<^|zdsPtp~p{NPyT)`-87UT2QTyOmp)713EA zb)5AMDtDhZ#Tz2^6pd0jMe(S;!w*#>|J&AvreDicKkX)XBL9CejLwg`jn0e9Io~xe z2?{0S-O2HetHxD^k-Cejhf0yGzO`%fj)szY>Gu$^M0eeLi)IMX$L~(xo`dHu%AVY% zICeg79C5$VVmWMJ>A$Mwim8g7;<}%GnuHBA8q7Z;6%^}5U?As2)PR)hS&rPwoS9kP zPTL~4vAV*Q?wRJ*hUvO6)p5l^nf|w^C8qIA{eyY&~H_be&a`l*{DL+u#4(+;pa4k;2Z`-}vT+dDPm>@c4ed?;r zKeL-N7j&tPPYW5#NCBt1dRyKYVl@9K`zizy`>#*UagBo;m;6{NU1FT$|4fSw86IDi zwk%7TwWMqJPNO}S8K#E;M?CQI^qpDTDSUm98`=;v+obO$J1?6Y0XMij0!l=0^ zBfCz?`j!4FT*JL$D8pVqUa$TSZlET&>3=a@NIw*DD#%PdfIXg$CN$AX}`|=C}{P`ZW>_UHdn1D){}!FXQhUvX_Qv?=)l| zJ2k`-{$KbOQ8{lf>pU$Vg(=C|rQR*ueENf6$!BQg}L;4fFz3Dx1GMGK7EF>Ow0y_W@yhT<8Ox_F52D4GSSm6+VX-|}G)fU;?$anCoyq1uz zVQHbYf)ef{rjxoF*#R#HKLJ|+I{AWsvBzhxF#6SbvW)g)ZC9jyw1XURfDFIF8yw;f z{VSweaEFkFntB%*2hRn!0egv2YJZJ~=a^u6tez=VRYtSqAN#?eFZ+|IQ8D@IcP!d>XVR-oK@bjT# zgipCq42U`c83g;mYOptGA${_{aYx%;>*py$B<*c~h&w7{O`p8|kmamv!jWNn!up2v z5u|YX(ADT_N-mTOb^}|152TlVk9)aow85r)Ch6Ah5)V}lG+Dg@q%W(d@MfqZbc^T; ze?B_|UyK&Pr=Ue38Cnl^AyWbgo{qLmLz8lpB&+?qSfs>E1HEDxXIAnbhZsZj!XQu2 z+D$u(Y=>`v(cnZd02C6^=;is(cE<2V)mu7Q+$OoAJYo9jSq9^bUp$5AV#rQmGjAzt z0BtlfkdVbUU^dtect|}1J3Q?+k(Pz>G0y)W7n@rA7K&I#v;>J8B;oJc#yWbrQHl5uz1>fm|2;1_o2Q zfmg{d$xF#=NxcYf^Vu=cvQEET^;A|MWhl02r`UQ1`XV=&@A+`ZWzjgHkNbs@Lp?~D z0PZKRApb+YPU;uT@R?i#Z7$H_To5`r5&=WLM%sq%s}QMyaML7QXW7i>qbvr74PAtD^kzs{aYZ$}@&&0uE`g6vQU zGzLr}?eR+OU5z$Xi)_5~f*jMHwmlB8Q95f6|E@4nc!58fBcVUR=1|h18K4GCfTzK| zq21&P-&aQ;(+u@XSwE>;mZ9lpJ?|GHBbfo-IpKO?6Q9Yw%a}x+L-+tCI0$0E|G*ug ztK_c!9nNj0x9aP%&l0jMRQ<~w>)Q%@=??BqL9yU1KaQKld_z?s{b2=2feNAZaChiE z`MiItGu@n}A@aD%U|02@_mvs5=42^Fw>O)LrfZe2k<66rP<+;BJ76tE0*f!)Cfpdv8I zea7-qOOsC*4-`}7gLSY&AH0a3WAb??_|3c-T!=-&QA|Sl3Vj5}K$D>R;0$1Wkm)&K zy+q7aD9#tpk+HRRZC3&}kPggr-b22NSH^wIa^MfKI79;3z!A_2s0h3WxPpj>Y?JCL zI$D)Bu(PFM@YG23wY4iSnI9 zB7PuUqK>re_MU=v;)^&9yegiayOuqIKAT#OtcG_$|3cYN1gIxZ2tM|#w>KHmRcoa8 z#9gIaRgnqyWP?X&O7<6?gO|j6#a7X2v})vExIgriIP)GrLmm^H;$*q8Jv&&O8x-iOpRe?;wP~+$Q$@1?1ol>Gl5&dBi>PtOjDjZK{iOTR610( z!Q^o-0;~Q%{y)5DoMB83eiaKx=E6Q`5L6C~AvXptc|O{I8;vSJmL$oSf-1dn zmwPYpm`Y|(;PvFc<~ccS%qh476C(eEgV083JmI}Z2HAvNQcXN{yzI2(p>(7w$Mnj5 zA2>#x!G6peBRJ1*=FVk(#C2FYG6GJ7PeTvE6TlEsgZHuHgz1*LLH1jM$=0eeO&8o3 z0Xg*(dkp`iAV)ysU1EL5i?O{(8?1r1!B3!(U>j+&FWR}nyhZb`yiKZ=`Bc+PMecur zOxknyHU32bSMZp7fQ8c2sRm>yr4!{9d>nEBFG!<(gPk_>O6?g%x~x@}r`lwk?>ayp zMeWP(&Ce8^;Q!4%%vwbkQ=3r}g-4kP=Rv1{C8VXk@6G~Cnl4s(K~^X`rCe%AbpV*ghlW?=oq*c_(fXpZ*>i@zR;~y0F4vqm%2Jd+1Itq-HsvR;!vR~>|#hLluWzY|t%x&jm z!oGseJTq%KU54RE0Q!^gI*Y->Kn%(2v`y;+G2s z2nu+s*fsRw)D&baya@7xH6Rt#kVg0;Tzc~XO)vQ*$uvn<#cKTqM+S+FMX~C63Bvxu z(Sj-5HOw;FN;Hb{9Qp(50PO+W$)f}9?vK_FI<+D~I!N+Rrqy6pmfsAQ(Wi1Z3Wf@I z3(|OtS#R+kSRcwiP&;@8yap7J-vyR>>TEp29pxzL05L4>uaX&;xL*Pm>R5IRe~Vy= zU?0!QT0p;mi77WA7x)zXOdzD!!CT(D4vTT5I$gG0EEBU79rUvaoU<3zFxT*=3z`L6 z`Rh2x7&xsC*#jSi?BHau4j^ic{2J#S^C^v0Rw~XD7s$?PPuQjhULX^h-*{7nHNs9p zDld(-7oURtq|AqZK?kAN;CR3j7~~mb6YGi;n`kFcV}Chv}5EG#Dm-SNE%eH&3(N-D4yPpdq?nIST8ulYi0ew z+0;Lgf8fJ#8hjJtfwSkq_K0_mA{hWNVtjGp0)Be!5~))W3w;ZNaQK^3>1c@{r} zg&|J}G>{5!fZhY;f&K0umMCqJY`XYP3j%dg?5-cN?g>2OU5X@#{ao{f;VX4oRNYEQJ9D?XyiB<6KNnCLs>(_ z7!te-j3LXtkYltVRT(2mX{U=*6>fdd`H6g$>SRwAOcVVf`bV&bdxYsH@Yo2-4j6}x zP!;%|yv|?hJYvGs|4Pf+L&V=@-E=?f7lKCg5bFiMv#3mzC+xvn$U2VCz{XMH;akuQ zXf;?%*82Z*eKPmd=%wS^8{2M4UZ~Gn8hzU-8yKs2vBG3gZ{h!V#2qbOhh3z&pm~rR zd_s8QiNQQiz&e4zI&;J`+DA(!sfL&Z-a2Rw{Rj7h&?CAf$`)MX3}?J2x?7ASBE>kU zA2bhaB<=QXa!fH6D;p&%+e^hm6?+YXT_M0Q+9r-v0EfhfbP`_W9$@aJ<)Js=^Uz&r z9h3;=0#G2#6>HwFu9UX4v&75fYTW?GRMHu2DSNNryXYE`IiBWSW^KYn#Lh+$(V_$4 zAv3}8LA`sR^{jTG{Gs@JyHIvpV<7O@Hsl_27k`{6JH#Sv;x)0Z;T)_lCoi=Hyb#D zyv4W1G1FL~yer|i17fnmp|?6Ui>9E$L&sF!G(;3MZOLqz+IynydP7od-j2vU;` zews^Tnxvj7ozXs}eW>h>_N2Wi_#3^+y1*|HUKR%Ul>{Q2MC*x8f@x4I_=xDA`kD*} zZn!R(Q#2LQ+3hde{1UEayLFR41IcGT=B*U&6b=)l5wYSjtv9*?-T@8+M-pED1X=Iz z>po=ZrF|+ZZQtKUl4Picnjx

PH{Vtra+gLBS0|_OtNY=xz8E=mw&|J3tG0aPTZq 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 XSDsiF;LXYg(#HaXmx1(eJ`fK8i=jDdP z`rk1SsA-EA{K>f_SnBxnCr> zH^07l@>YF$`HXXU_RhU;4kSP4yLKXt<<^}O*CLtLubXtD-hc7T&e)8yaB!NaydZ&BYyfeC8eOJ+QejOo(pbe(awd(n|K zKF^f={;=^>3{n|ZwKP#fx#Lhnu^wpoWpE2Bh?=P1nku8cX#e!1}i_RQ25%oN^xl-eY&9~cW zwofOoYx^c0wbsn*@63u z_pdqnZ0R|T_yPeXJ;mr03DtlnjUI`NiE1u}M_E)J+4Pni^x$E_TH5d23I)Co-t``dG*(Sraw>YzgYhO6CkuRgrQ{W#J=Ui{>Nn-M1M*>C(4wEwzmvF^X;TKC}XT7~Jom$y~D zpBs?Ht=Z4;{`Agr&$2roKB(RM&KJEa)ZV~)YG0GfqwX8Gt^by6w3=P%b#GyL&(FE{ zzE7Ka(NswFD|0-{mkkASmCpm3CI&xPu$*c4o4BdU1s`^u_}4h=%!A$5{=5DEGr-a| z12}DOp2)<<$^uH|n-{b5Ls{E+0-1PGQvPHSeqDKx$cBqTkKY6H0SL1K^8x}~pPaxi zVh&PMpQPsR;XJ9bYE67U^@MdJ { @@ -24,8 +24,8 @@ const checkIsStackClickThread = (t, vm, stackClickThread) => { }; /** - * loudness-hat-block.sb2 contains a single stack - * when loudness > 10 + * timer-greater-than-hat.sb2 contains a single stack + * when timer > -1 * change color effect by 25 * The intention is to make sure that the hat block condition is evaluated * on each frame. @@ -111,7 +111,7 @@ test('edge activated hat thread not added twice', t => { */ test('edge activated hat should trigger for both sprites when sprite is duplicated', t => { - // Project that is similar to loudness-hat-block.sb2, but has code on the sprite so that + // Project that is similar to timer-greater-than-hat.sb2, but has code on the sprite so that // the sprite can be duplicated const projectWithSpriteUri = path.resolve(__dirname, '../fixtures/edge-triggered-hat.sb3'); const projectWithSprite = readFileToBuffer(projectWithSpriteUri); @@ -134,9 +134,6 @@ test('edge activated hat should trigger for both sprites when sprite is duplicat t.equal(vm.runtime.threads.length, 1); checkIsHatThread(t, vm, vm.runtime.threads[0]); t.assert(vm.runtime.threads[0].status === Thread.STATUS_RUNNING); - // Run execute on the thread to populate the runtime's - // _edgeActivatedHatValues object - execute(vm.runtime.sequencer, vm.runtime.threads[0]); let numTargetEdgeHats = vm.runtime.targets.reduce((val, target) => val + Object.keys(target._edgeActivatedHatValues).length, 0); t.equal(numTargetEdgeHats, 1); @@ -145,7 +142,6 @@ test('edge activated hat should trigger for both sprites when sprite is duplicat vm.runtime._step(); // Check that the runtime's _edgeActivatedHatValues object has two separate keys // after execute is run on each thread - vm.runtime.threads.forEach(thread => execute(vm.runtime.sequencer, thread)); numTargetEdgeHats = vm.runtime.targets.reduce((val, target) => val + Object.keys(target._edgeActivatedHatValues).length, 0); t.equal(numTargetEdgeHats, 2); diff --git a/test/unit/io_clock.js b/test/unit/io_clock.js index 1978911e6..03ee48fb6 100644 --- a/test/unit/io_clock.js +++ b/test/unit/io_clock.js @@ -23,12 +23,15 @@ test('cycle', t => { setTimeout(() => { c.resetProjectTimer(); setTimeout(() => { - t.ok(c.projectTimer() > 0); + // The timer shouldn't advance until all threads have been stepped + t.ok(c.projectTimer() === 0); c.pause(); - t.ok(c.projectTimer() > 0); + t.ok(c.projectTimer() === 0); c.resume(); - t.ok(c.projectTimer() > 0); + t.ok(c.projectTimer() === 0); t.end(); }, 100); }, 100); + rt._step(); + t.ok(c.projectTimer() > 0); });