From 55f36d2f5f059b8522bb93eacba553008fb9dcb3 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Tue, 16 Oct 2018 10:27:42 -0700 Subject: [PATCH] Red light green light radio game (#1438) * added new game * added suggestion * updated summary * added tips * RSSI info --- docs/SUMMARY.md | 1 + docs/projects/radio-games.md | 15 +- docs/projects/red-light-green-light.md | 212 ++++++++++++++++++ .../mb/projects/red-light-green-light.png | Bin 0 -> 18117 bytes 4 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 docs/projects/red-light-green-light.md create mode 100644 docs/static/mb/projects/red-light-green-light.png diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 350682df..415e7b12 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -47,6 +47,7 @@ * [Light Level Meter](/projects/light-level-meter) * [Radio bridge](/projects/radio-bridge) * [Snap the dot](/projects/snap-the-dot) + * [Red light green light](/projects/red-light-green-light) ## #examples diff --git a/docs/projects/radio-games.md b/docs/projects/radio-games.md index 611058b5..c1126690 100644 --- a/docs/projects/radio-games.md +++ b/docs/projects/radio-games.md @@ -28,16 +28,16 @@ Here are some cool projects that you can build with your @boardname@! "url": "/projects/fireflies", "description": "Simulate fireflies with micro:bits, try it in the dark!", "imageUrl": "/static/mb/projects/fireflies.png" -}, { - "name": "Infection", - "url": "/projects/infection", - "description": "An epidemic has broken out, see who will survive.", - "imageUrl": "/static/mb/projects/infection.png" }, { "name": "Hot or Cold", "url": "/projects/hot-or-cold", "description": "Find the hidden player by seeing if your close or not.", "imageUrl": "/static/mb/projects/hot-or-cold.jpg" +}, { + "name": "Red Light Green Light", + "url": "/projects/red-light-green-light", + "description": "Play the classic game with your @boardname@.", + "imageUrl": "/static/mb/projects/red-light-green-light.png", }, { "name": "Voting Machine", "url": "/projects/voting-machine", @@ -48,5 +48,10 @@ Here are some cool projects that you can build with your @boardname@! "url": "/projects/rps-teams", "description": "The Rock-Paper-Scissors game with lots and lots of players.", "imageUrl": "/static/mb/projects/rpsteams.png" +}, { + "name": "Infection", + "url": "/projects/infection", + "description": "An epidemic has broken out, see who will survive.", + "imageUrl": "/static/mb/projects/infection.png" }] ``` diff --git a/docs/projects/red-light-green-light.md b/docs/projects/red-light-green-light.md new file mode 100644 index 00000000..8a1410a5 --- /dev/null +++ b/docs/projects/red-light-green-light.md @@ -0,0 +1,212 @@ +# Red Light Green Light + +This is a classic game where the game master is looking the opposite direction and saying commands to player. +When the game master says "red light" and turns around, all players should stop. If the game master stops a moving player, he has to go back to the start. +When the game master turns around and says "green light", all players move and try to touch the game master. + +In this remake, we will use @boardname@, the radio and the accelerometer to enforce those rules! + +## The game master + +Let's start with the code running on the game master @boardname@. Don't use this code for players! + +### States + +We define two states, ``GREENLIGHT`` and ``REDLIGHT`` and a ``state`` variable to store the current game state. +When the game master presses ``A``, the game goes into "green light" mode. When he presses ``B``, +the state goes in "red light" mode. + +```blocks +let REDLIGHT = 0 +let state = 0 +let GREENLIGHT = 0 +GREENLIGHT = 1 +REDLIGHT = 2 +``` + +### Communication + +The radio group is set to ``1``. We will set the same group in the player code. The game state is streamed in a forever loop so that players receive constantly. + +```blocks +let state = 0; +radio.setGroup(1) +basic.forever(function () { + radio.sendNumber(state) +}) +``` + +### Red light, green light + +Use the ``||radio:on button pressed`` block to run code when button ``A`` and ``B`` are pressed. +When ``A`` is pressed, the game goes into ``GREENLIGHT`` mode. When ``B`` is pressed, the game +goes into ``B`` mode. We also use ``||basic:show icon||`` to display the current state. + +```blocks +let REDLIGHT = 0 +let state = 0 +let GREENLIGHT = 0 +input.onButtonPressed(Button.A, function () { + state = GREENLIGHT + basic.showIcon(IconNames.Yes) +}) +input.onButtonPressed(Button.B, function () { + state = REDLIGHT + basic.showIcon(IconNames.No) +}) +GREENLIGHT = 1 +REDLIGHT = 2 +``` + +### Game master code + +All together the game master code looks like this: + +```blocks +let REDLIGHT = 0 +let state = 0 +let GREENLIGHT = 0 +input.onButtonPressed(Button.A, function () { + state = GREENLIGHT + basic.showIcon(IconNames.Yes) +}) +input.onButtonPressed(Button.B, function () { + state = REDLIGHT + basic.showIcon(IconNames.No) +}) +GREENLIGHT = 1 +REDLIGHT = 2 +radio.setGroup(1) +basic.forever(function () { + radio.sendNumber(state) +}) +``` + +### ~ hint + +Make sure to rename this program to ``game master`` or something so that you don't confuse it with the player program! + +### ~ + +### Improve the game + +* Use ``||music:ring tone||`` to play a sound while the game is in ``GREENLIGHT`` mode. +* Attach a servo and move the arm based on the game state + +## The players + +The code for players needs to listen for the game master state. + +### States + +First, we redefine the state constant, ``GREENLIGHT``, ``REDLIGHT`` and set the radio to ``1``. +We also add a ``state`` variable that will store the state of the game. + +```blocks +let RED = 0 +let state = 0 +let GREEN = 0 +GREEN = 1 +RED = 2 +radio.setGroup(1) +``` + +### Communication + +We use the ``radio:on received number`` block to store the game master state into the ``state`` variable. + +```blocks +let state = 0 +radio.onReceivedNumber(function (receivedNumber) { + state = receivedNumber +}) +``` + +### Display + +In a forever loop, we display different icons based on the game state. Use a ``||logic:if||`` and +``||basic:show icon||`` blocks to display the game state. + +```blocks +let REDLIGHT = 0 +let state = 0 +let GREENLIGHT = 0 +basic.forever(function () { + if (state == GREENLIGHT) { + basic.showIcon(IconNames.Yes) + } else if (state == REDLIGHT) { + basic.showIcon(IconNames.No) + } +}) +``` + +### Movement check + +If the ``state`` is equal to ``REDLIGHT``, we need to check that the player is not moving. +This is where the accelerometer comes into play. The accelerometer measures forces applied to the @boardname@. +If the player moves, it is likely that some small forces will be applied and the accelerometer will detect it. +At all times, gravity is applied to the @boardname@, so the acceleration strength at rest always near ``1000``mg. +If the acceleration strength is far from that value, say ``1100`` or ``900``, we can assume that the player is moving. To compute this we use this formula: + + moving = | acc strength - 1000 | > 1000 + +Now that we know the math, we can turn this into code. + +```block +let REDLIGHT = 0 +let state = 0 +let GREENLIGHT = 0 +let moving = false +if (state == REDLIGHT) { + moving = Math.abs(input.acceleration(Dimension.Strength) - 1000) > 100 + if (moving) { + game.gameOver() + } +} +``` + +### Player code + +All together: + +```blocks +let moving = false +let REDLIGHT = 0 +let state = 0 +let GREENLIGHT = 0 +radio.onReceivedNumber(function (receivedNumber) { + state = receivedNumber +}) +GREENLIGHT = 1 +REDLIGHT = 2 +radio.setGroup(1) +basic.forever(function () { + if (state == GREENLIGHT) { + basic.showIcon(IconNames.Yes) + } else if (state == REDLIGHT) { + basic.showIcon(IconNames.No) + } + if (state == REDLIGHT) { + moving = Math.abs(input.acceleration(Dimension.Strength) - 1000) > 100 + if (state == REDLIGHT && moving) { + game.gameOver() + } + } +}) +``` + +### ~ hint + +Make sure to rename this program to ``player`` or something so that you don't confuse it with the game master program! + +### ~ + + +### Tuning + +Does the movement check work? Try changing the ``100`` value to tune the detection sensivity. Try ``64``. + +### Improve the game + +* Use ``||music:ring tone||`` to play a tone while in green mode. +* Use the packet signal strength to detect that you've reached the game master. \ No newline at end of file diff --git a/docs/static/mb/projects/red-light-green-light.png b/docs/static/mb/projects/red-light-green-light.png new file mode 100644 index 0000000000000000000000000000000000000000..38953c4a233556fd0c8a50e820adf205ce941517 GIT binary patch literal 18117 zcmY&=Wl)?=(>3mH2?SeQLkRA=xVyU(+&zKC-Ccq^1QrVx+}(l)cbCO^_kOCrAKzB3 z*34YfJ$-feoIbOWDoWCrXe4MbFff?1GLmXAFt9Ap&%-E4&{wt1HBIOng0+~U7!1s> zc=Q)jMCf-^XBk~L7#OmU|DLeUA3eRGKYnxv>bR>rS-E?ex>~|Go7y_Me|EHVr{w(1 z{+ZpJDMua#MoL0fQcT0!=xiOil?9lIWCAbM|DCU(Fqom>kO>I~hl4IA0~dk1TGz$H zQjroV21F=^fKT^@B?>hrgBEprFKH{-f(F_Cx2s;Eqp5cD!JFxX(CnGzBZfRRG$(a_NJLd10t z5fN*|0M*cLi~oPO3}MsP6JvluP=NG{7j(FulrO}lfD&{zj4kXS6w~fkaqrbt@xOLe zaUJikfS3Cg0E;ns??upNBF7}kR+jy5`VRyI1TkS(DAD_%@~*2`oIFSe&Y}SaXh92o zYo7<(G*y$|b#*nYev%&`c>6Oqhyv1z&uRdx_TN2`juAhG4Lku@DH-#e+9RyB>`V zYvC~>2FSUp#!1^08HJbNJt+Ygyp3(io)|9;oER)51{tmbwxF8UqHGvK;l2Nhv#4iJ z2OCQ*6Rq2Jkf$pD`}Z>1%Lo$v^zQ{5cxKl`-f%n`*%BAD+T^E#G(MdXXjU?w)+rPfI*9z30=TRLx*QID+cZ-U%H)>uGp zo`>WqFx?AnPG>mtatFY(Z;vag0?(e1KmTu#{zU08=L3N$nrywnSQ0$F#m0OgUONV+ z;T-))cNxL=>JMJna{pG`+E+B|7?)F%&&hf%Mb61}R8;B{aIH@h{+h?*IFc#W5o{?i z4J!qv;pGRK{MHn%_MVi(n-bZvT@S%~IQU6i7=4i25s0#sGb02wmH+gx0=OFF@sx8? zg9?DlF8J^Jf0LiEodM}{C<>Md)%vNxkN3E3cS4?O9TT#{obS1>GVI%tq1Ml0(XT5& z)4b|<`%>+c*tYk)g~qw^KUEM)Lhqa;}`D>!_3Tjq}a?O*<8biaH1Eg!u|YeonnBCB{# zn}peBfB+e>ngs`Dn;}hV!2MC6F5HqKj_lD$qK)G$B{|+ir`zVdP(AYdZ+;Nr>QJ}z z9Gk~vls2IoR8n9BhnEbgmjMc-`(2?hGi)BUSmfOYGDafG^g+5;p_Ehd@tKT2O9Nk< z4c+t+{_DY-aNbSs`46c7a1e!FeEWJ#;;*nB^U6rEj5VIi1Z#7I-fY`CoBhAaoubEP zN17}UMbx0jiWR_MRYq{{Tlc@B#9hZsUV0+P`Tw~z zUO#CV))T{vEJxu*hr-OEpFwYr>ug6q;?O>v5jGV|@+r}(atPe`*q&96MrqTm3)18L zm4#qzMN$86&A^B*NbwQsN~l|pQ`lQXEg7=HMQHSIaRQ#cojlR`whH{r8a~>Ltf*IO zW$M&_=W8>3%Y+-;#$#>@OQp=`+I~X)i)I9ew`4g);Ozm&=)OS-^B?d2PdA#Vu8V*f z&S&Z1>h1R%{oJR&GG8jnO$b)z9^2i)^+vpq?bq#1ZN>Z+maP2rSBrfwBB%v<_Y(^u zC8Two=f7B>oYbz)G>6fC#`3h}^#iIax9`!}$PXXi(gTA>9%?dzxKC94b+8ly2CyH#Y;{>KJK*uZus1{+rBU~sja%|$L`t};VE z-oWLrg2$@4tX<@9mpI&;9dmk*1tH?RH{q?zG_@|h+rmHPoVY#5Rt@2DQG=@d}IJK-QUE>u<&twiQ4zG?ygQYPNmAN zdMD}~IT%wKIMkbO7*Hqrg_0nZeH<3SIM$O&4hFalvN%L9tjN~e$rQyE(W1%)lq2B(yMYnSaD)~^s2R+d2hiWp$>*r%7P z4C*Z1s46VRTSu+$u4S|W&{Fo)b8miozf4%=85{1T0diX01kW4JQQ=i0?5=wKI^RZH z|KyT>sJ{qvenZ}QSZOW_$iIJJ_$0kt4iJtG5-^X(ne;Ukd`ksXdwUEq@xH^m^t_s( zXuojB&A9E{$!8a~iRLWaAh7+GGnJwBmcrWs@wB=kn0?pCR$Bv*=evPL+RWv!Ld3PA zvDXlZI)Vbb)lWZPHu%@@TAlyZ9j}Z4U!~7XI^hiA4C$Nfz{x%zgsG(aj!N)z)ySMS zPz(+{+&-*JIAR%m!Q0Nxq?f@dF`ck^$3qTzJJlxpVC*{>Bf+9gF7$`MfI4Zr4mo++ zAV~ulwKRU_^%?k)XAQ*wi<2gMUrQ`E>wDIYrP@(a*01VNh%Ou2)^%Tzlot>ZhE^K- z06suPnh*8!)GDhyXTxHc>EOs)ndz#I13DXTnXNzEZS@zAex-p}Zg8he;g3eS`CIx+b!=f<~>yhPzK zDjzUHAKdlffMW-pEgZvE7&r}bEzgJF5oW}-&XCi8IFgl#0OG>+`@QmY|7hVUUGaM2 z;7Gsl33&P&=Im&{3&mx-36OMEM(Sl`QZ4vbawf`;o>_g;B-7qS!VMj}}OlYvzi~DQpVQ5w$P5hcp@s64Q z@H+STP23-QY+E40YL_#w2@u*`j50W!%SNO^-;q;~2r}Q4xOhi*6Go+|6(Df9Bi&?YLZT(qj#-c;UPQ|4Y&E z{=gXbR3~V@Oh(_IKQJ@p4;IK0yic+u{uw4<90~0U(JIC!xxRSL5!$iI8&T>$t?$_> zgvJi1R@wp~LyvFsDjQ^#Mi*lgf3HmcY7QMQV>g!Qj!=KHYjQ$4IBRplw#JzfXMAZle*6b;a6(A|oG797uJ9iSjMu+qNyXLB$6(dZgNWV$(&} zzhB+Z!}?OCJ;0@M$qvGEwOUQvT)EaOY+P14tw`O){#{jXBzqa&XWc->AfWXxCJSD+ z2q(Wpb8e(G7}0LB0HjDg?yU#=NoYcCLb-c1Bln1?tw-ay;(~ARupB25XfS-WL*3|* z)4$tjgtK{7#D9b}MuD>zNH%BeEPa&G>rc|G)HXoDXC2|>j|;D>m|b68iw9@T`|dXY z61Vbqc)NS2c?;4EydCFd4nmgemR-b6O9Dh`F4R&9J7+;w27 z=_rd8C9C6irVqzOxnSHW$BYB5L=FE9&O&s^Ar3)Jh26{WIH|gR?eNJy*@QgIzFv)$ z9Dm<8fbdoDPm@2|rT@&gVJ0vftKMjhH-q8Ci(qZp`}(WCF1V4*x6T??7q=J$ zr~ztp#rQg_+tNLjbf8T{Mo zpFg50pho^2fu#`HDM+0#s;@VJ-AYKWx#EpI~|mZAHvIX<-c2a0K3 zA@z{?gLLvWb|Ew(qTR!ald;7DZbZhKS-!4gx~F;^rPb=>(<-&CU5}mTE^|RCQCg2c znre0KLyM&k3S?KPA21O2OCwG?_nQ3KxD9wfv4tvUpH(-$1bE9~JZ_Lf&c zm2<)8lpDq9~@QfSHSA^{zp7JF7%SYzd7?bKz$vRfY=K| zxO%}adP}kpEX^NX+Yr@R7PK%aK(*=5+(?C!%DD0geu7>SL>YO-)sk?K^YYeDroBTz)k$5q@XIc}2%@2rHlGpsUTNX$MCX27X;9G14#n1rz5JrP zm>7O&y%ccIU-6lDQsn*RGUq^$9=hY^QN+_!!pU%R^r+GgZC~5_yanC=d;hh{cIf@k z{V?GCay1k_#@5|oV}gi?8(Lo)A%QK#xpo!jrI0kspk{9}KFqbKLoIm!D;~2h;LN`7 z?fJqO_b;Kgfhr0M{8XrJ;3VGxXm2b%d`?+J$iVlgB=uf@I*_0@3$OO~aittHiDo;A zlrQS(2BgdDum8_BJlLkS9! zytmsj?frY>_ot;}Awuv6=+rWUT4ZPN86^wvd|8?&RA-^qfZp>ak4YM{B@%s_qv}7c3+Ho_vwVSN`nM7M& z6~!K{^|WD(smw>N{i`YOqVZ+$2harfYIPJI6$!o#3C+GgzJ_Fy)UUlX{V;6*fAI2A ze{3?K+GFe0v#(iz_&jBc4mIY#o;siY8X}st1E85Iq9pINZ@xOVuAe!k=g>shE*W~& zL`dw$o98WG|B4T&redcXTR-<~sXwl)(gN`?{s4$o5cu0-`wUC;F6ujxVF_OTxoqiv zb(rD5U~Bysd#E~gGT;!rid4pM^6vZ8Yc2A; ze0h`qE|}wY-d3ZW@BE%eHoaV&}zFK?9N3`|x5DezYgO0KZSuHOE&PSGEKxJS@kpKR25RNSP57xA4L8}T}s>&6U(mEORG86>re%WJN zcQR-d)$$L=b8rI{3)!_vcuEs*NpPj05AbbI;VG?|#Cvv}2)zrCSx{&EdgUnC8Hw|rsY8UMnU8buJEtuGT zfBTq*uFJdFAa5yUf|g>+yZFk2?B80q!ekq$W(AF)wyxc#`+g(xt}Ya^&o1-I>f|F2 zi9&RM0)*^heIt8DvX%+WUyM!mF9R6+10n63WOtJzTPv){AY_S!=c5U|1)Y9d zkF(jG$zyK!AXAWfE?cHY*_7}V(=|*z3=uKeD8~EF7g?=&v4Sg<1Fw?_b#pyeY&8oV zqjG?<*di~N=bGp%!Qwj9qT733T{pRv`KcNq^B^9+4D;(MyJ@t~zYhy9$Bf?^j#KZT zcUA50MSs{MJEn|TwG4IiWexuG)}02~-=K@j)5fXV2)$|Q)O^iuYDSv>O%?Fn*#g)N z>Aa``mjyB+%ES<>r3dgr#yO@iE_|2TE6eA7Pij6u(ai(R8uR^V@Y-Co@yj;NR#bTa z)Qew`x7CZy0e7@~Sdc$b2i570GINUQImCINGa>|*6s=vH4wCt5eHvhlLd z<28k~)r-zn{TsRbP6B7ri!6{zw(JJ>%r?RLxP{^0+YZJ1Um;ghv6fJ=yWqU;Lkd=2 z>2Ll%n{W3m?b@t1_-LkgKeT9~BDm&HS}GxEn0p-gj|v{b4MjC;&?d&VNsms#De-}~ zMGG!&m?Zh)M;p(z7tu((vJEHS#1eL(@xmS`Gx6*g6$&U3S`6}=P0k~jGc>2R+S=o)+TTr02|{IQp%wYR%Nzet#UXrrVm6`arUj`H#;g zw5U$&CU31Q4$mz$j-5qNUM$8S!JHs5zXYR#CZ-u0ckre^OJP#pFaWvvTv#Udph2;+ z7K*xcu~*?{_|Ia|AvSE+EeAl>tM11~?QN)h`wnDI-rp|XnHtM|lp~h8aQemJ8hvvX z=M)oXuS$73E26T9z|e6?3Utq)(CTthe4ttH$=aWkmxa1O%_bftGV5(wvcp)KIQ0Eb zb81<^3Btj}KpST2R6yu|5{-bgt?IPK(NR$zp;qIn89d)%yq$?%1Y5;JfWcU5(yoe9 zg*=YXCikC@YP8sMD^AFw5iVOFCfxSEC^K|vRhCFLg%jS!jn|QVc8Ns1ItEh$#g$=H{Nd zH6WJq@kcB#KTJ6tNvaB2E3=9P3A?#J|0#g(Cdt1PsE7~#O$s~A+L$;f4y&kH$gE!L zQzzN{d$Z23T-cZ>*q0r^sgzZgf|sQUsJbu0(fUAgRnapBgjaOVO2_b0Eu9BhOS!f( z|K9U=ddqd*J|KCD4av!mLA`@!CLMnB-B(Z#EPT{)@At5&By=}_o_K@4+dGrTQH49J zp8qsI+P$X}$Qap11kcFex(?pOHTh`ml28=7%lYW{yt-)=i@DOML_8W8lb$rh1z`XY z_9&R4?KdBO%>*t;rhjwIl9#av%XOcX)r{3+>dRU#HQfMHY0xRuu2yVPF?XYqn2b{F zl8_)B!-&n@3MBmTx25%j-*y}2TVch5W&@CRY2^=jRR-Xi=9S8)ycHf9f%{XOH>pn! z1fFXyLs8R$je)Am!AC!FwEBGxaz8ZxHH+TumsUVJ)9$)X9hIEfQp4}ucj?EP)Y>>} z*%Yp*xGMSLQi=#+btrrk0x=ec*x-*ks=blpt2LB>kp}t#(If_Vk~Dr03HR{XH_SXgNI zT=cll)2&Mz%pEV`N!pGgUpAA1By}?L=B-z+u23n|c+vctJ|AT?O`7*OZcP`tY)x0- zW-nGxM}=wjd5ie#i7R?U^UQd|G9{v_*;{>}#R36j*C>{-7A6)xap}KERXJh~s5>$p z!6#}A@22MA<1P2FE;mK5Nx}bX5wyCxp=C>>(6_&dIsu%w*PHI8^I!uDB>vf#Or+p0 z2bVC)$p5@Ga1^cNHQ?x7dzBH$jO|yhg^h)EtNmd*a04{*&-0BwBJUaBmuKGPB2E)D z-2)T!8oT^~Mb?0C8?-mN$trH6H?yQVip*P4Aq0?g%#BicDYwB{L1tM@xK%TnDm;5$ z`*-pA_U5vfFJbprNNy-5wbBvkxTOP+GvkNkEUW%a>lMj0QIG>1lr($5oI z|4k8D6qPA_oyu)nZ2zu+Uh6Y0hHQzi5sN%E*-hgyPFYb0pzLF_+msReXs8;S&Hu#v zsoUw7i7bBFD~#Lf*e4CGr;X_*85}%$Or6((idXRye*dqyC*7GgFP~8y^a`$=t05Z_ ztaNajvTVHnN;Hb&C}_aB$^pmf>&z3vyz_3+!|28jy}Gtz)FP~9hL1*5Sc%t1>}QXH z_W8y)52gccUGa~@Y)p7Hd_M~&{>#yh$4jBayBAh0c>eI2mMtT~K9=~i(tVd*;N&21h0KxL$-d^wQkU7*QVyHq zm7Rx{R{9@;@Rc&MD8?EK#rEOYHUMxxA0L!U*&Peap zjN9u)4mu1a(Xt$SIW7?<0|SgW*j3bQ;%H7QzkT^MkB9XbT|F$xnjr4+bAP}+fpVo^~MuQAqwMc0~&*&PUS4{B|&Y5Zw4rU0VA5QD?4$FxzYO^+qRMw%Zu zb~S^dR!Pe!;)O?hSDPo;0tyQ*D96unLTTz1{GOx_c@E9XR_tF^J7=en1N@cUOwMdh!iBu?(`;0X zp_>YV`)5XL?RM#&jDTt02|0-86La?;Bt zA()jk>K8Gkr*F@%N$%5NQ=MzMS&7N&q?M)%TOFwA8y7jwav~As~=7R6d3chk$=5 ztbfWcKdjP{Jm&4B&vLf=hBt6jWak(1?@^{ig+?iQ0~#op-^&Yve>F}Qrnn5UurkCZ zYNwFkAlcZNqp)d~1j@;?i}5Zt;_pNoW2h=-$Z9Bx8C*TN^oLyzONX@*n15n2g@|+f z0P~uk(G)>6?Sh$TM{!xD{m4-F4)lUv@2p9sGp3RsBIsbxq$E|e(Ta0sL0Q`^S7hu5 zf*)2~l;j(5_QowqCcZ5&b8o%z-aiv=MGM|UD!~s%4(L0}Xe>LbjB5((=~2{V1tnZ0 zp<8Cb7RlmRkIw!G&!Z-<%F>*)n*%W<75+=P@9CzlObvzGWo<@rp&6&C$f0D@TcXQ$ zR~Th~B|<8Z9Gkzm%j{k#O%}`K@Ub=b% zsmA5N%}ngixAi>yhRYlqK5+Lb6&Eala+xdqYntM=_pseH^&cnIx8m9q&peW)J1;7B zkBSI)fF$G2sSbYvz2$;TC*^*kSS|^O+hds4Hfn?Orb!F#K&a--RvF#J9mG3lg{PrJ zDlhQ7OMj<-WaR8kxnfXQB?%OOTc{VaWs=xzQ#cHTo6+8nVxamus@QDgf|2C6JZ7Y& z2{TU<>(1M+zH1FA4EVlN^4TA{%c~A1lTngQKM-)3oqZd+u-l0D+kMWO&mTlCE&F7A z_GN|X>LsB(0DfP7t`^sNVD`sC^l`Q?;N>HKXz69=MF89K&mNzZ1dM9zTd%A|azD^z zN*Tx|IgD2iI#0Q6FA&!vic5+r$L|lMSbAH#f_ARN#zwaHRE>D%(iR zL`fNE=wiQeF$U7|rSaY@@xz&*$iFXje&+04z-OFXs|c<~MR;&qj?}n@`BOalu7ZT- zA=|&*PVVlaeBL}}U}v@c#E0z|9sYXpkIob6rX}o@Zdil=Wr0fk0RfBcw#O=>{M~OJ zDA3)1ui?eYl|G=vyR*9g0#)B}d1R9Wwqey4ZQ{9hV$+Bt{zeEmnl~YDbe(jrijF=E zmw5^WKQw#y>)%-4h$HLORBaX~%mpbzN5|QwBJfulk8*bv7>J%Oh!JN+3KuW^^uYzxp1>!djC-fo-b(Lp3lzb zHs$&WEHMI$G2aS*#Rkp+(z?ofv98EfM^YwsAQ+E=BFnX)(V0 z7E$0`2UM2ZKx{FBNwQ{hq()U~^vwz7y%sEq{l18kVV|O{N#yNsIwW7bd9l^2KB$*x ze$x$kXIk1ErL3L^`(=_^=pswZd-(@vArHsVt39*7>9`UQ=YA)-j*r}TT!}AgS3sq= zyxKW@b{*1h^U(o@Ls^75**(F0V^eK~-laALUd4)5v5?R4rQ1C%kSovthm#KB(0hA@ z2xg};(jc(F&oT}B>p+Z4O|FA*A!a;e?Sgo>KjX-nJBr`lmybeku@Jyg6~+3u`zqE+ zBQi;WJTjp$Si@F#nlA`ZM8J=X}&Ct&ys(6Rts5mvK|E^M(A-~>Tf=2?PVz2#`e3(;)172{N_WC z^VC1vmA#ZMRXd75YR~;R7j*cM^=L@fttDN77?w7^1tn}GWW?1gD3LjJu4YkYFA;0m zSm^m2Fk!~vzuvRrxWxj+bjWk&;VOBI;mb3$06=F^% z?1T<-m7dkwymXHsXcJDgPrh8P6oqk|l&_8776u5ufuo5LG9jc;|9;{&ewP5V>i#Ryq^xy^Tf|F$R`bNTgMgQ7bS?RYFriu0|X zsga7^7fP^|SBTN{v>Iqn&xo$9re~H}0kew$ALxj$o}&I9aN%c6nDilbx9?Eij1J?P zDnRRs)K$rSYFP5vkW6vXfWp`I6X#NMuUU^mv4ao!MhS#ElzMNo5vLQ1s2%35>(;CN zAhEEPh$r3s#!d?@N}CsEqV*vtcCu}|WfyxpDJb0KQ>6utG0*@z%+2$%smsIwGPa+C zVZc4}?3@?BURv-A7eJP?{{cLjx72qk;kd=-C8Iy=V*J$(u$a#$B)<$BqN7eDJ$}94 z40<13wsXGaV3PuNZ`{0Sc3Lp5&@p%Tu>8zaS~$%`p7z86Sx*>#w@FYtew^;`4Z-j& zE#YL}k(%d2Cc&Aj^vU~m**YZTNE?*m_0x*ovT*T$lh(sPMC=<%oG0r?>bjU4L7;cu z54vF2MVx@+XO?mBQkzs2>KIdkdQmtb^8&6k=}hOg0%_pGmS&iX-Lw)FQq+$g1;V7V zt?B*K4u!p`(5`TxV--8e&;A~xVd|Y?2XcA;4Q>2ys4qy}>LhSAq_!m}aFKUU(ew7D zob1sS-OV$vYBmp*zN*rN*+WVa{uHrzvaXuLLRD@AAQi7lKH0&^NL0l88Ct*N) z)G-)>PC3jdRZz2fi?(dfzqA6K=OHQ0o^Zlq`-BH9*=q44Fl>{v7C(d?%>{+O_; znx)=5y>23T9JkXEcK2O0G+ap>ZqY2O|22$Mbc#fQn>;Ho;zWdnP-!zCJyLcJpkSTO z{}m(c1ex{DsnC$=ui13@^QfV^CR&ylRK!ts#YY;JDa;?X=qoE3jOlP-B^I=qlsQh2 z07=8|!e<*E*uu$Ly0pKHAhF(Tt$t%QC6>`jnlC8Ax`5*Dn%hQ7=+u)7mkv6VtgMET z(%=-asGJ5Z#zHKN%#!mFA&jCsOy*j3Y_0tq2Ab|j4K!x|O5`**h2Q&A24p;d(ko6A4kai(MfsHvVQ4Zoqgqy*T!eahw7I{28H( zG-WwGM8(l(iQpXs2b*J*v@oFv@Jm2~C*P_KbcXJ)%^^uAX4h01^SiVWiXJcE|LP*z z@Jv8Cq-;AsF1z!I@B5dhWw2PxT~i)78I*9CEU5!$yfm92f{1wp4$MFfIY*Zl>4VdXeq9@CpnR>x_+Km7OY`FgCNFds zIgW}G(lS_3HEolDps)sHJ228^z_N*+#7R{s@13@D*S$)SDiZ5 zM#xO=n)CvUF?SwfY)oVpecJpeq;cq3>mt{Lzjp;CrO_pSr|bE(I$t1!jpf`gp1h?^ zsyX+M2}kUt(=osSfv*C|+Kd_3ymW3i<8)SGzUuyo1olS>73e$^n|tZnrs6-x8MW(+eNmLk zhEQV#__+W=)Ucb}H_(+(vib6Ynp|7T%F3W7WQI$37;d$k4CJaXAwpEUtx2W#45q9Ir>uZ*r29|=2xc{6O5=EZY1f#H}*$Y zEdS(rttU1p*|U<&@`0as4f8s%J3lgUbaLOxWn%v-5W7M1tzT70J6T%q$L4%Te&BWs z#}%tl&g^R*WJu)g>ez>?ZVNKYZ4ILfsFXRK89V{k7`aX0bw|QM88_8a58KZNL9nvtsib^7v{$h(cV_Jz;yhr8P|CqGXc?YpXU=q0q6}}oy zdF!8C(;w~B6Vb)ijgBE%)gv3m$fVOV<=cE$e=@gk7POLu*$|eG>e*?Y&YBe)bLqhR zE6|z*^X6s&k-8HbN&v4DlQ;vl9H0JI4lRK?hzt`$qmV06>VbFGToDH%;n5r{%}RyxJW~i z)|zAfYr718Sf!QN-peiet^ zo(OV}Us@t2kUdODH-~|M$vYwBmdtjSlePUZ8u=z?gykWDKa6{YMZdDZYSK|U@nyT` zl{QJ)KoeX^cDVHQv+J3@&EH`Ul6sY2EQ9Qgeu%%WtD^i%IbYgD{d*CUMU~=Zb9{Ti z050nyQ53=SL%Vtf`!R2Lr4-JCzf-6a$`dQ!vO;||OU7wH)V3*F3_-H8=x3;HvDcr} zwn^aVM>c`_;-WL|ao>2n(~G<>W&+brW;;bmh+;JKDY}7Pt>@5+xGB_~q&Ea0+-=TwFi<^1Ml?Zz?9^2^@#IZAsNe3XmC zKWiMfKT<2EkjSK0OtDc{W>B@6hTb#nh{*TLoG1s)&agw_CW?-h-OlrcqrOdKDv!2e z)xaWK8}`8X(>nu~ri%uY$JaNq!TI|f&4k-^QSUUI{BJ!p)9!40PG4bcV2VT~#G@BySHb=CkbO*CEYz2nLs ztgqMU3p)b!t!dI_l<1y_?2<|lJj_SOdywUCgoFB4scZGk&Vnd`ws`_b#r95q{-dY_RC7lQ+y%Y%3QG zko~^~Uf8?5v8>>Sdy8spiP<>QywO{)JYZ-%Q(5i|Ms{}QI3kov0mG-tI5!$KNGyU@ z{jF`9L%N}S16%;2mzMG;dcDqm;eN|iolqCX^8xDNQ~z7LTh~6{__idBngBXbXq5Qf zx9?KY?{kj7JX)?D@Q)00^)-aU0J1a>nOiAK3@KSQih6mDv^FE9Qa_KJe|^L-#ZLYs z=m4cWz{oJB27m7d*ODPVxt5S_A%&x|Pq-EuyjO{B8*z5cC3z7z1m6#r6&o-CrTS1} z6Y#zDOwLhAy~A@(Jv3Oj#E>K1aQHASZzg!^^l02XAsohtD!U0KwZQgVPUNcE44K%e zCqK1({GbzvSFzQnH``*vm?)@ah-S)-evmZOYUe@I7%7`~f)BT1kMiL|A+3fAjASWi zga5lY>$C`FS&r}HuKW@Guq62k6cR0AcUE$%jh6g6(y^qPkL{9A1i#N(Cc;VsG}!QB zx>ndTn3sh@FZmstx`h35DCRgMp)vKkCS#YhYz_g= zbg=}_$gNjHqnvr!MMDHHSb?kJ6Hw54QzRS5a6VJ?a~fqh9wWY=!S(fdaS^3Bu1ObQ z3QP9*Vd8~ zUa-VqLD<0|3(L#-LQ7_(Nb4~$WHD+KyAU%<(=R7da&9=Yplj6&Ba8R#^MQjNnHh2q z$7~eh%yco7QSvGWPoCOAdeZ3|#^&9FUa1fO8*NaVdGT=H(!Jgpef5t_7C}+SZA#CT z;X1{B;6*_fRneu62~z_;Mr~ZgfyJly+I24*Wrw-(=LE`YcH(UOy>J*b~!Clw+< zBIqjHFi&*)mJk#zRWNQ*D^n#!wqC3|-Eq5G2%Jk$D^AAmp7QZeV%$u!XP1>G7GU(& zc0E+vi6nB0_A!skA8S4MG;Z0vWG?0ra^AQ<>Td?EW2FYuNzRFW1!Gnv{gCM}$d6n> z>AUz3_WRX{62GBlWOj@=)ZPY}9AE#^|*5Shq=NAiE@0Zk2_#?Xz z)Kx}mdUa=0WTq;*@+vdNm4I0G?%zWLQ7D#~?!dulQ0{D39dJ50$(|3QT@`7O;N$q^ zRrJ?)t8n0ibW3m-*a)e+D$|7JT(X=c(Z7R)CkW+(UZ>%yhXr{ z%^Xa^IV>BP?Z&k#|0oelPvXY(bGguhl#1?Ab0bs1-_ihF8G6}aDvL)nA$Pbed4-qF z=9!Se2`)F#U~AHENX3v{v5!|CV)r*uP>xJ#i}8UUZ*vGEG>*0CwvH|4y;ocbOx|$u z*G0F4TPRTFsM|H4>99R6ieudwd6Xt~ktF;`e9$>J>3WU`0gV%_G=4&qkE`!sK@HS+ zbQ!KBf~VqQ@Lz0)X~6erx$ybGO66SC0eyhRxEtIg->$6pFAir znIncka3L|>602AtUx3c9{r_^~qaK#O&wk96e3TkAWXQ3eja*}OpYH;AB=H5QiLh(M zs2)^?y!=;8d?a~(Y>D9s_@{ovl$U${>E?_xpWr_coIL{hL?Wj${lR&9_#~FWS8j}U zh;#-1^vRqarOe6J15*s)W)A9Ov^B)f9*5p@@YDZ za#n~C%Tf+hBtG1^xjem$GxMs@U97+B19C(mTp;fi%1}Rn;?u6XLdwrX)LBc*3H48d(tC(Tk5@ABgOKsv09RTV+&J{3a$k|BI`2*85Lt5 z;s)&Sh;GAw_2>ruM-d~08MP{QkC8KK;v2>=#L$@qA?Ex9lisO;YfN(rUUZO@k9n7z zg^E+CxDF^8lvK8kgzo=RLyyRHZv;G`rP0|K5iJ$P@iY1FbL3Yr(XeEN3|4m6G%f1Y zC=;CxB+;|fXQ8&NGD>ZvV8ONJYWYKNBkAx`wlO;>k8%*%u2-!@py{K62LTJup+Qh{ z^Bj{6{qZk5RgIV_#7ewiv`2wq>vb184yzyyMipP5eo(iU*uT4D+`4MccDS zHVS;(RVi_~vU6Ni^Bi0=e|G&78mzXOR~-@U8bso z`B66-HMIWeyLleG#{Tb8>ld}>i|(LQbIX$CewpN?&YBwuCjkRt_@Eum30svA$+1js zIys_o>=?e%q7}`zx`BkjX-Pme?B#5yza=;6-n_j97e@KHKbFQ#PH8GN$I99{6d$(9 zDM3V>69rW3hV9C%%8mGHqYoie2VhVMlU^#$UcaMhW|l&a^1Tn{;1iumrpqU*A}A34 z4&34=WeBYpcz65G?3v0J_#d;wlF663BA5a=m+3S;n~{hId?ZSkq09cJw!m4bFKHnY zHC+v+-O_LvyI^L>U>-*^%`7;z(Oo&dzm-krF7N_}xyu>eUTS@0AsMoDD2#HyjheCr z$Pw{2kxkLlxTt?6rHCIlK`28dSCl%`PKjgfp8n>I(2qLG7V4gA?OZAE^zX}^-)U)~ zK}kk1A|eO7N3S>@m4%#o0@@ku)tAr=u_n41dpJd^+R(KOt=@Ki=0itWdDWuO>G|@r z)}1&_2;$FwE(4EXVXjbp$2QBoh^3UN?qP2z{8^K9%X{QjxLO{oa6$xbPHB*ja_Ety z^T?j}OlQ>Pgr1R3gtDB~~QDpKgJwSGdTA7#@ZcSWnxSvYj>zU7uxxMLH>Csy0E z7-3POB*R-Gw1TNqhN4$~y8jU~Kc zI1{$5d_HYd25#GNc|jHY6PVBXI`yEYs8$1FA;{ViI^dhC$V-jM*yl!ZvqkvQ6>lai;z=r%jrU8G{D`d6h{pO>l`jinnlqp`$& zk=ZfG1Ip%6Tx07TzAffU@GT*aK+>)uBWeA5s>lsLj1azk!Kt251Gty#6lg$F8vzUd@E$Pr#SVYO^=1Bx0S4lMk7-w@Pbm zDf68Kwk;VKVBe9&B9mhfaH1&7spD#Jfho2XWe#yfhtSq!-oAful8`p}_aB0aP{W#m zFwZ{Hh1pMbTir7c)y-}8^sNT;iQG)T2{V*s5?$-2Nivjlx)j2wfcw%m4f`k1^9swB zaa&(Jdf|!(dg#<5G;orr6xwr118!#)^6dLSXC?H9(UXATmRV&_D6b)E%}yMDAzA6? zVAM_>Q7-GF9WN1If^=A^Nyx`Hhdm~XdiJ6D}_hCTi7jz6%eC`Yz1M8Y9y z8pFO&3ALe^c=of~zVtEe2VK(bR}%Qa7{r{mF}wN%=>HX{dmGGU%d!SUXqvrLvQ^g! z)wW7QMsKZf75SwYzmPutUnlqe&-4PvaeNBLPNglEQ%Trk#xbi{F582h$C|}33@x^> zMDyK}#|kx0t=wvE2NNA>nAOS5CCqumStv&ya>?46hs$AE<&Yds?aVc2f5G{oKj8EG z=ZEL}HGwS1h_sUec-%e*R&Mosg6H|-qeH>;m^u^DB?T1Hl6Ha@e18(zZ}Av*3huPv z8|G78sW!G^Vz%>5U?QI!!?U5kuod;zwPHkf^lSi$1+qBcT*sWZzG^dFpbHm-eEj_PWY?a~+ZDwdgK*x<3l*m=6aPBR7a%-e>FT0{BoNpK^xQ;X8j2;HAo3P5G zQtQ6x`NV_a18}Wd_6_0_J#cSwGGB}t0dWEfiDe>M8);{Mca4kcO@e$5$WIaOPb`k$ z)~Q8N6JC?DlWn_PD$YPMsY!DKBS$3so+};gU2BIpN-j{y*^9{9Xmk^lDi8XR5%R2AZn`lUcq)Kt z@*X=pz}pXcM!d?he-h|=xb-~m zKZ2?(f+B5T0}Df3tq|4NuS3cd$4m-LjOA4p(ns{wOhc7Yeer*|w?w;yVVo!|Fh#G-bC*|AoA&#!@ zj>+^8Ki07{Af=#U+ue_}<;q4iMjLE2WN2sP%h9C!Ipx#L=?y8nWo2nW2V7DN zlEbazfyD{Op9lL4hNgR!UF4-2(?dMHc$Qedu<&QsCI-qHK!0v^B<11o*mXtZ=2p8| zkY`Qq;!9a+i5N2FwWeQLP@#`TK3Ch6ORFKO(hzo%WDU4j5^c1bg?U#R=G3CeGgG+T zmivL*Yrl;V@);*0@X&`AMF%ceRPL#XmoSGwSp}cR8rNdBRqE*4f0y) z9nh-1)2a}U9_E*b$=&V6!F0XVW;ot0LLe?5{GJ}kM&0aFqrHD?W2~%s{v|K7gj1Jj zpOwB4QNZyt^&V!z)uj54E==EJOr1xQ5eIWp+ QFV28KBw~