aboutsummaryrefslogtreecommitdiff
path: root/pegs.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2009-01-20 18:28:28 +0000
committerSimon Tatham <anakin@pobox.com>2009-01-20 18:28:28 +0000
commit47c3878dc78028ea8750402b7f1f1e6e59b41198 (patch)
tree8d42f33f3b2c430eb49b86ee6b257701373c41a3 /pegs.c
parentf46eceb714ac038e0721f2b16e19e089859bc051 (diff)
downloadpuzzles-47c3878dc78028ea8750402b7f1f1e6e59b41198.zip
puzzles-47c3878dc78028ea8750402b7f1f1e6e59b41198.tar.gz
puzzles-47c3878dc78028ea8750402b7f1f1e6e59b41198.tar.bz2
puzzles-47c3878dc78028ea8750402b7f1f1e6e59b41198.tar.xz
Keyboard control patch for Pegs, from James H.
[originally from svn r8419]
Diffstat (limited to 'pegs.c')
-rw-r--r--pegs.c104
1 files changed, 101 insertions, 3 deletions
diff --git a/pegs.c b/pegs.c
index 7ac0ac8..e6e0d27 100644
--- a/pegs.c
+++ b/pegs.c
@@ -16,11 +16,15 @@
#define GRID_PEG 1
#define GRID_OBST 2
+#define GRID_CURSOR 10
+#define GRID_JUMPING 20
+
enum {
COL_BACKGROUND,
COL_HIGHLIGHT,
COL_LOWLIGHT,
COL_PEG,
+ COL_CURSOR,
NCOLOURS
};
@@ -739,14 +743,30 @@ struct game_ui {
int dragging; /* boolean: is a drag in progress? */
int sx, sy; /* grid coords of drag start cell */
int dx, dy; /* pixel coords of current drag posn */
+ int cur_x, cur_y, cur_visible, cur_jumping;
};
static game_ui *new_ui(game_state *state)
{
game_ui *ui = snew(game_ui);
+ int x, y, v;
ui->sx = ui->sy = ui->dx = ui->dy = 0;
ui->dragging = FALSE;
+ ui->cur_visible = ui->cur_jumping = 0;
+
+ /* make sure we start the cursor somewhere on the grid. */
+ for (x = 0; x < state->w; x++) {
+ for (y = 0; y < state->h; y++) {
+ v = state->grid[y*state->w+x];
+ if (v == GRID_PEG || v == GRID_HOLE) {
+ ui->cur_x = x; ui->cur_y = y;
+ goto found;
+ }
+ }
+ }
+ assert(!"new_ui found nowhere for cursor");
+found:
return ui;
}
@@ -798,6 +818,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
int x, int y, int button)
{
int w = state->w, h = state->h;
+ char buf[80];
if (button == LEFT_BUTTON) {
int tx, ty;
@@ -824,6 +845,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
ui->sy = ty;
ui->dx = x;
ui->dy = y;
+ ui->cur_visible = ui->cur_jumping = 0;
return ""; /* ui modified */
}
} else if (button == LEFT_DRAG && ui->dragging) {
@@ -834,7 +856,6 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
ui->dy = y;
return ""; /* ui modified */
} else if (button == LEFT_RELEASE && ui->dragging) {
- char buf[80];
int tx, ty, dx, dy;
/*
@@ -864,7 +885,60 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
*/
sprintf(buf, "%d,%d-%d,%d", ui->sx, ui->sy, tx, ty);
return dupstr(buf);
+ } else if (IS_CURSOR_MOVE(button)) {
+ if (!ui->cur_jumping) {
+ /* Not jumping; move cursor as usual, making sure we don't
+ * leave the gameboard (which may be an irregular shape) */
+ int cx = ui->cur_x, cy = ui->cur_y;
+ move_cursor(button, &cx, &cy, w, h, 0);
+ ui->cur_visible = 1;
+ if (state->grid[cy*w+cx] == GRID_HOLE ||
+ state->grid[cy*w+cx] == GRID_PEG) {
+ ui->cur_x = cx;
+ ui->cur_y = cy;
+ }
+ return "";
+ } else {
+ int dx, dy, mx, my, jx, jy;
+
+ /* We're jumping; if the requested direction has a hole, and
+ * there's a peg in the way, */
+ assert(state->grid[ui->cur_y*w+ui->cur_x] == GRID_PEG);
+ dx = (button == CURSOR_RIGHT) ? 1 : (button == CURSOR_LEFT) ? -1 : 0;
+ dy = (button == CURSOR_DOWN) ? 1 : (button == CURSOR_UP) ? -1 : 0;
+
+ mx = ui->cur_x+dx; my = ui->cur_y+dy;
+ jx = mx+dx; jy = my+dy;
+
+ ui->cur_jumping = 0; /* reset, whatever. */
+ if (jx >= 0 && jy >= 0 && jx < w && jy < h &&
+ state->grid[my*w+mx] == GRID_PEG &&
+ state->grid[jy*w+jx] == GRID_HOLE) {
+ /* Move cursor to the jumped-to location (this felt more
+ * natural while playtesting) */
+ sprintf(buf, "%d,%d-%d,%d", ui->cur_x, ui->cur_y, jx, jy);
+ ui->cur_x = jx; ui->cur_y = jy;
+ return dupstr(buf);
+ }
+ return "";
+ }
+ } else if (IS_CURSOR_SELECT(button)) {
+ if (!ui->cur_visible) {
+ ui->cur_visible = 1;
+ return "";
+ }
+ if (ui->cur_jumping) {
+ ui->cur_jumping = 0;
+ return "";
+ }
+ if (state->grid[ui->cur_y*w+ui->cur_x] == GRID_PEG) {
+ /* cursor is on peg: next arrow-move wil jump. */
+ ui->cur_jumping = 1;
+ return "";
+ }
+ return NULL;
}
+
return NULL;
}
@@ -955,6 +1029,10 @@ static float *game_colours(frontend *fe, int *ncolours)
ret[COL_PEG * 3 + 1] = 0.0F;
ret[COL_PEG * 3 + 2] = 1.0F;
+ ret[COL_CURSOR * 3 + 0] = 0.5F;
+ ret[COL_CURSOR * 3 + 1] = 0.5F;
+ ret[COL_CURSOR * 3 + 2] = 1.0F;
+
*ncolours = NCOLOURS;
return ret;
}
@@ -993,16 +1071,30 @@ static void game_free_drawstate(drawing *dr, game_drawstate *ds)
static void draw_tile(drawing *dr, game_drawstate *ds,
int x, int y, int v, int bgcolour)
{
+ int cursor = 0, jumping = 0, bg;
+
if (bgcolour >= 0) {
draw_rect(dr, x, y, TILESIZE, TILESIZE, bgcolour);
}
+ if (v >= GRID_JUMPING) {
+ jumping = 1; v -= GRID_JUMPING;
+ }
+ if (v >= GRID_CURSOR) {
+ cursor = 1; v -= GRID_CURSOR;
+ }
if (v == GRID_HOLE) {
+ bg = cursor ? COL_HIGHLIGHT : COL_LOWLIGHT;
+ assert(!jumping); /* can't jump from a hole! */
draw_circle(dr, x+TILESIZE/2, y+TILESIZE/2, TILESIZE/4,
- COL_LOWLIGHT, COL_LOWLIGHT);
+ bg, bg);
} else if (v == GRID_PEG) {
+ bg = (cursor || jumping) ? COL_CURSOR : COL_PEG;
draw_circle(dr, x+TILESIZE/2, y+TILESIZE/2, TILESIZE/3,
- COL_PEG, COL_PEG);
+ bg, bg);
+ bg = (!cursor || jumping) ? COL_PEG : COL_CURSOR;
+ draw_circle(dr, x+TILESIZE/2, y+TILESIZE/2, TILESIZE/4,
+ bg, bg);
}
draw_update(dr, x, y, TILESIZE, TILESIZE);
@@ -1137,6 +1229,10 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
*/
if (ui->dragging && ui->sx == x && ui->sy == y && v == GRID_PEG)
v = GRID_HOLE;
+
+ if (ui->cur_visible && ui->cur_x == x && ui->cur_y == y)
+ v += ui->cur_jumping ? GRID_JUMPING : GRID_CURSOR;
+
if (v != GRID_OBST &&
(bgcolour != ds->bgcolour || /* always redraw when flashing */
v != ds->grid[y*w+x])) {
@@ -1226,3 +1322,5 @@ const struct game thegame = {
FALSE, game_timing_state,
0, /* flags */
};
+
+/* vim: set shiftwidth=4 tabstop=8: */
QaC-inT˫&`[:u8V !AWS_+_hfK }RX\Nih;QuxBůCBʤ$ +>HE68jd]Ag͕( a$O:7æO^xT4v5A{MXFF%?P25nET{GOr@4c ORƖ|+BѢH0r@bi;9LVikPiK\':a>'k14vk!/RGd ^H%as xC+Y\|Ƭ ]9L&n?u^STm2^"&#"8$JtU*֌`AF]0-4IM!:sSHQN9=MKm4&s2w1®y sVL+Q,44e܈Ro]z{*ssWg+!aI quLS7J5lx8k"l[q%ֈLVN~1h)\$nA;|UA A1mZ tLGuYqDޝ6A ’%j/eϢU)tlEBgj\QwxLcl!bP=?p]?:T V >k(.JCi+؆4iUNmV*'3 ˌ<(ZOMFv:8Xo\H'| 2`_槪ޚy].Airέ/4l`8lHKRJ k+Kj"er*TwTzsZPDARːė)U0-{ٹe(Ͽj^ȞvACVY2@& #ghcz.5nD\k A[Is-B\w*i,A ty ŧ(̾F-/PqFK? Od g-b[YhpJwǃ%'SuxGY\:‸|9%l;!,΁sy@ŮL'䚬nS0 $UWE.'c^lwb̺N%@ts_0Ӣ RLP{iO! gD(g\:m'Wc"yI+"~,c[WCuD Fr,N}A3P/KlSi Ӣ*BK-GYXն XF#i9Q5ߴ4Y9ITi dLD #$*'9Р9wFl r.y> mni(tOeo#T5KPAt޷U6t:E 5m -Nb@wJuOG2S# KXaEHIFmVۈLàp b4c+6N!'`xN%</$͖1*EOq :6D5Y3ྍ ڗܺ |X_]~!|gz D[I֓x6yiH;NʀcqUfz[:M2C1h70m1|:CSz򶜰Q-Y5+Jp^LFX7st5SPGv,<VFon <=%'7%ڟ?OĶ>(mZC|_tvS<҈"-N&14_B_bti.VZ"C +!N'OG%*/>Zz`Au"BerOILlh=Ƶs_c"ۚ| lIwiQQ%VOp|J@@Uj.Mq. ujA2C#;(̀wDeO0q%k(OIm}N ,3/r^8pJ2WcAM6;!\i5*\,i\ _<%3lv>r;?K$ ȉ)xJm2RZ+zWǐ|V^Kol)DC%Ak~y Π{ C5w@.X tY_?_ K LHI;}i@I,$e# "h'֚ saY  {酑u4VrG<[EX+$9[<&4aǛMRp{OZK5h{¼0Y4!|%~ώ>I;kIɾRv4?|P"p|Oc6)ndAզR{}칷T{1u{ebp,.L*f?H(,:.N Iq̠TV`<24$g:sJqShNNq{v8+_FTȕƭC$Vo[ͯzSɛ J+f?pHSgj)q$WF(Ata|G&ۏORu FTv "fhoȺ0Zn EiiPGf2u|! !? T'sgl}N]mt.vFUo+ޏ;AdC7LGEP/t\^ZS1pF޶7N&JVz1jy7NqDd4Ʌ:@*3}*+3*`_N4x֞w$b$EQ_u܄"l(HEÍ!3)$xs$j*E7?to\_Dw97XK3N'::s¹W)xӺŠϙ0@!7V}r"|R޼qI1Z͙K.Q `I5P²t>VqNЏ }j~^xs+le'ºl NBBX>uWnRIMvgջBlgj2t P;ved%ۑ2ٰŰKҟeK#%6J^l@+>`d2S\: D#A+o )NcW)mڸI,ly@<0ŚP̌ˊ+uY;?ztNgר>(Xժg\qڐ6}9րu_eYKj/p1HM"a 05=v =9L!t4B@ 98@k43SІdMc{D}ȝ@zc d wxaqcZE_u^s> gKSók:8re!9px7+^~qԼw@+ޯOoIR[{ݝq2;pv=6Nh6*hm2BI7ۇlG? A CU፟o:1s?eej um`%R sq'w@B^ZgI3^0κ6a31w-WMQB\ʟlTP{b^.{ R{~ƴXko?Dvu<7*&Oq <ė^wywBRkj D0V +Op0&=qsJ-z&5w7}3l|A7/ Ӕ%sS to91U^qXC"t-B^/ h4>iYK˥ uyj(8?iLUP re)cspGȏ[~w%-@%B?Ub7>1*~;زH0Rz5f{aR~}gZ7Ě|c7fj#1o_W `:=j[1RڑQ&Y$ZlB4[Ŋz6 qvgd&Đd8o=V펠 uΆGT_Hl?ݞƩF]^pZ7J#"5xb% h }:\!oä3 *2V촬%:$LEuSc@$ROԊDBL6b+!Jԕ4zՋ'L<"xƃǬ÷ă[$7X'f`h{2Ȑ a՞JF+u -:)X'D<[ܾj%") M ӜF_ X3vqRӘ放WxQL1$wCW Gނ fk47 rULǢd2[pƒG-/;q\ x6M96ƠX%wK@] !a`^pц潹3|ƼL +iл(ׁrwK i5p@nӣO% po喏B;W4 K-3<%M8t"w]K`uY{Dr'ZSWٖsf"#}@L^gU1 p/HpG5 0AH7@~^ތ@B u]tAgU.P W *,^m:КߺuGI5HY6 1Xр2qD01 62m>ad"rDVYVRJDokv@>̀w[K4>׊8,ʵҶ|ۋ; @&4^ ߸>OXDeȗPO85ɑCc(P0I,`#*ݗRvc1ȶ>SauC aQwWKsT WO126ʿ0L_ # |O[ X `$x1NMe.=M\͌Qy8ݔ G:PMts vGKQaW,wT5bө'e`'/3[@0H8|SoU7b|wbLUl A n#p N>H7_DWD@vs 8LoK0;H$\V{ya6.s~?|o|%wJ*WEYARYY.aΦTRƉ^@H^)X^P!MžE9Hko Йċ"[dWQ ȡr8cVhc.ϰޏosWa.G(7բoni퍾hk얭lȺ* O^Jk89 Jxou82GY/ mp{d:>&EV/bYoM"VNHcRnpUh8Z5iޢW ?,]Vf8(NGvnDp|߀P^Pg/ vcXlcs▽'&uq&gK6T~'4 T-9]DUow JE (+/ fH**0:11j$PH߰Cl4̓+ARG܊C'#/aÕYI{o92HK'VH FZ6 *E%f&i…ZZsuum_%5VsX,8ˎ>0餮w܄F@N89ʿUq)W'Uy8 T5JSO)ձצfG2)_&G')FhHAAagO/;s1c/J-i0L+GCNk'¥<S*/n 03>r+)ck'>Vt~l2vt~N4?䎺F" '`(I: *^`.QW=vKH0xx#M( mw49~:~{{I&c4Gs2w sϲCp$_obe9XSGȱ93ș)m`oUD|"۠T"[T%5*ba axS62X2|{y#4)x[q0Iq#).+*Հ3>! 2 \Jʋ*RZ-k("}kQj SS\J&q=ɫUvZk!E2kSgi=J -)>bl6Ѐr-rxשI L.1Wa8G* T$8r$<}y^^ӓ5 {udh? BɂTIED'e@.Ք&ڶPje.d|W?VbVg&G'h'#(,Uq^I:S$D^&l+,ڻhIMJw`Gu=zN78dP jP$$\[(ٜ@C^#V z!ceB$Up,ynDrjvnᢘt7cX(>#6ߣwA-"FLS_WB[WF@X]z6b_˫ɳLJ:޷!G!t n koh{j! y@i}?Xowͤ`5R%^S&,wwp"MEnK΢x֙,s:7u 0i8㻖ET{& 44gREOJ}׃y-FSbjm ɀ:)C5$eW>DCC~ &Ή,G5N8B(J.iZ@r 4TD 7 2j;{ps`,}5 l2)tBߤ^O[qe n^`Cɓ!DDVKw͐"=QRШu$a@pVHѯ/;N@'$pOqD3Wjq3vcco (7ۘ9b,N1wͿmEalQܡ! e[9U|5m}k,׸UdtH'x8--8yVArŞ&IT$MʼCM??+1Ii,a{N('Z?W0ƤqKu&unYNJ?~sAYJR9lA7֫X Q;p*:r/MN>Qc] ɾ vk1ʁ21|p@˓gzh! o^Emfj$+`u$Q;Km0&믯- q1raEl,b`"û@Kh! lc[Siex `Q5gþ|c~:51d&@>ɨ&~6!?#vc锔x4wGpA[J̓kkAV @t _ց,l9L3uX r$)U5wmLO`^(Ȳrtb_ -h]qKh>^|iCw;P:,32?L?)[$3'뻎\GEfW5gvG)w .XB(Afn2֑PiuNZ5MIVjI$cjYXOk5uܳyԎ!<ݧ1d]2)m fƫ#5Y[q[wW"$aƭLb6؁, H͟Jmd!:KhWK@جgs7B*yadn؝6,DMxz\#VH$rU9q-ζsq>Jx(m_L 1&TlR͙Rs 1)鿩 ӉdM:ZjkOŠR8TRH,GT\78Q@INZ9Q]&q*4B+W*uPL|2_n P+hzUBG=̜ěũ? <C5^n%CֵBsu ,cdQ+--~_<䵦V8[Ȩ]B^uԹ;&$V*CƖ+UR=fL] |cgH? 6YdZm(+3/1ѓ(d$5|6;eܟyv; -<|+c~.=?AܣÕ0g!!Z#ԉಜLӬ:':᧕%8#Vn ^q1 f~vxH䈙Hj1Uls=fg- B?,P}ۯ)¬EfgQdKNV!>@N*`4+N! 1.b5Blf:K}rf~]V*1kg?0g[oi]X5>r&;Oqs v, #neiD:|BqF}WXA)} [b;nh+}کbkWǬy0Y*}nwxM qe:~j>E=(ʁ/,|Gh3zE!m㶉H@+(n|o`,;tv f{'y!z }hmZ|%W~e- 58~wN Ȇ*]Tj/c̭7:2[ V&k7dKw(\--vJgXiEܞIP]F+/61CvdG)PMˆH3pxȩ@oI; o^O"zEL5绾*̕)exPZ7~F}(նl1#>:p>~5Y -y+:j 2=ETUW wC ңi'>;` i  4itdXN BV`(|2%?߼gľ)B'H~mL!f8`d"IzqeƮʼө‘Ӗf^؉ǚ5:S7G\į5tIXm9hCƒ . ?o…Q/75dlޝd͹KUFY,9yDi_,*<3#>kN.h4HV6sz_b`hc;w0-u xr]w2७|`F { 4~Bx:hzf:"on_^LI]$Ԅ㟋P2gVBƕ,xUD7"g1*#dBD]|~WΥzԝuK~N`ߙ{ exCƄEW*y/ȘHb-7u-]>'/KbߋM5pӫ̶xcj  &:dcO㱗L<೒TO3ڻ벭TmԂզ͓Af] wcLt.viiyŮf\D'҅5Ά|y)n|Tan@O~_4hU/Fທyj3ݖ5{FpRs?ٍitcE_dQ p@u:٤G"w@hYƢW^D`ߐj~TY?POks \Υ, ,MF%L+pcP/ ؠchq'hevQyT ΙFi=%Ҙ`NZ$ cRkn%`7dܯnܕH҄NtC"zNuw"Y;7#ecs̼!BwE@G7 K 8rfq֫e,6f]b0tK7LQ -I!@')s}=xƮ (?d^l3eiʼn@jȞ_p L\ιI0zធg~_:9)$Ȋ#2.!i_(fl9&{*Arx:D64$xw;LVgU-J_./쉼Ҿ; D×JE$7$OH+N.MV϶LAs% d$GLw;k:[zbFjS 4i[Ou".wDͩ3m &0 Rnג%k)1(隺Gxܬf,NP3bm+'m&c[*]ǩ##xw¦#d ) Hk촷n}&+pOԽzg\ͫۜ/ RE]ֿvw~?@hXrŅy脪yvxFꑒFD?bC ɢH)HcZȖB  1!Z\#L99F~k p!y0NI@3>+6*N}xeUb4NGtތ3 X6hJeơ5swէFvF~WrI\2E" R#Mkw2B/$[doA;Nf\2^px U`<~ m|#M켒l,{/9@qk+" 7}VN>wQ.N>0,kFENJ3|_nJSx{LހN !؏}g- 8sF廓 p5ulMb{0TDd_ ;W!(:k_l7!/2w6Gco<ĪX,R1­4,DPobz~7C `2yIF jFq~$p?U~`eaN5§,UH@0#lP;r~ P)( v)Hh~,ZqBaN.ex:+'oKNϧ&* gx)s0xۡ.̷,xנnNYM˃\U9?VHe=ɠP8*"Ft=(hXG_y@޻ tk0H o#WEݘy[TSc`GC_Q?r7 Jvam>4oQv.^%>ѝWB ml_BkP*1,jStw8b#hLwKK&Aeא+ԃ T߫ʮ!i=Q@:yU5*|@ wzQiCTɪSI(]!V[0&\>@ x B{X$c[n>E5 YG: Y#|lc4f .+ "6&8^N6y/ \w}t*_L1kخUcOq8]9+ H_37tnIAi+cc.Zya<&1<**dZ9:B=2LP$`щU$jް[M@\8MQ2㨿H\n]z\35  " uEaJ44b̂HAA?Uf 2fB~dQwC? :btIP>THy9~zKuXs.f}R2biޱs:Gk^m+,nq#Hw~(2崼37"E[X6/lfIRu*))|%ݺ ^^մw YOjJrDR{rg"*j|$3]*esdKF+vN퉄qqΓHWY,brFuHJO:qi,F& -7$ja h ÍaoF-= ?Y#`|@iZ):\W-^B+jA0|wb+;x. >/:M֭gެK9W69I +PIc'P4X-o(r M{ ^QQ c@-iqCMiXXM\>kj}9IG?g!Pܰ%:gR5Yc1 EgL)JyZ1Q&پcragy GO\<شGlkC"SSuV"eq:Nv?žk_&YJ909t<\}HAid 8@ uI`%h菓Ox;!_\Up z:R|/{ _{-WqT%cNMJlijrй!ޛ+ss75<%]PәKE(Ybpثjg&ɑ3'bÈ{ Nk]_wPO<u;57Ѽ"A Ǫi"4nR[@[v? ] 6 kGr+rԐ^}$sMrHLxoܩp"Ih{e/ѼE ^M"DMOhL4cߣytߧyxuo15uBMPkv7 мn^@1j}<^F s?Ďa!vwI$DأbkRy؆ sp&dn\HEFOjd+6T8TΤE:P?AQ\a%">ț6Fcp%XR7өY 3g)\L}qSJ FuP7([gvh/"{,&2zyLԾ3Y: @ W919Els@%Uyv$SGt"u~qn yf=T4rm.[h1hg&\Fg..a~ ɎUӄf Y:#BU%YG>=JC4CbZ/(auX'yv/GeZsЁ|UXOv^B!\:=+^/IRahGaS\lɁkBNZjU۬-l0)FSoXFV,oG.ǏX5,5lIrMch[6cȢ#E}^p KQ%j=$'qS/o$dWD80c0yt2 WÕ^bO2e}T~T-E iƃJ-46zЀ/#UŰK6mlhxJOh<X>E';@2w~~ t&$D.+mP|50).6ijO\ˉ=q9XcX o}IcB7Z ߞ):3xib/3&@BMT{qF>gлyO'{JgOgXI8}@g Sjr-RSVadҐ՚C趄%mITzrH5q%ZXҢ ,kW)Սi4iֺWR?kQ*UdiU::éP|5(P@Ob r֕o1 WY*D;p(P{&ٍ>1fdVG1h@Bn&VjP<8W^}De)}Њo^6KyvALwni%}"Ҭsb4c, Rxag =I';r 07?vw6Eq6&ӆ#/~Ֆ@WЭ}rzt!o?+ydVJ/g@%H?GZ($EqI#(gv:\a 'M>aq[cβ9aT]Z*JG}3*{/HMVCQQZV;]UùFL5].H}ARw{{1- t Ԫk3Xu?°EV{5rku&"Xwet1SB6 tLL0pMhlrñDUFNPoUQ*,r&UmΩHQ>HzZ|r*q-"wEeAe_m,xF{#5 :#%î%?Ά_yڃ5w@P9'z;բHt 5|фqÜx OͳAnHߐ#] Ösf7hT󃥼::YeLUiW}DdsoQ*g{(GOӸP uBy2͖"m`֢jEt!=@;|߃y>9Z>ng=˨y0nctø=D") Ԍw.!VŌ|ƺK.2N%.CH*k2SIǐl"ͤNqKzɋ8ǵe6'nB԰o?!gY253 o>T27*#035|;Qx}f;V|vCFuPMJs):JYqނPmL\GX\${In:E|[We䇥I`6EǺo RQ}HI1!B0a41ʑqԆM) "L6S՟dv1vs--碱F& Ƙi)}d!ܹx%b^ Sm@Z؎ZbPfV'QȂ4& #ҏ~h"c~Vjɩi>&fK؇yccALbu46jP GBVX޲VM_5 ȡV?!4F.A]# ֑5%Q:ipYaA0"RNySz"Wy$~%Ps8Mz˟kȀZ0OǕ**e&?lj1ڽQ gh֓Vȩߦ.@maJT5wC֋HL/[8r&PJ4|XQD))`*MWY҂W3:h5%V<9`XL>xVE 4AhyžyL% MO@CxIof6ұB¹%%u19AŒA|,y (z<bDW{ (pYI!gr8r>yk~$_||k"KbΧS>V~.E2$!ؠ=7G.qߤY4:Db Pc$7`+!53vW6J0lA P$2LVvW$)NH|X1=O ETr|}F t5hlB͕ `qC'w10qc0 ( g*? Mt"˟$e7DkXNhq21T"F&:IT 6[lUs-Fɀ֊$eXmҗJWe/>L;s$9k<< dTW*zON,bd7XD-i_a"D!BChoSW~ި#D J[̍m> i2}ᶥ$G=r=_:d7+g5WWL#,>i~Y]2P3Rb]Bj+Ce4 Y2u3{r×',h?WW0Aw6җa4fNG%/l̒&o;Z^\߄rvA|p" /dLmeÈ Ko@hZ^-fq[4Su/L^ɒL08/))MbT6xjNPk9ϖLa\$ F95U3RSOZfMtB^sF# a}m̳=9,8l]k?{ 훵BƼ9,af9y'M `HDa1a'-qJQ*#abt&D/x SL6qnC:e͠~$9`0Ȯ§$@o3M9w\(chKE7^PJhvN|•+:ѹplE*WcQwQF#xݓ!{]@OˬmzpZ $6=j8*Ɔ{-]\JNS=.v}^6q^Z[i ʜ8’z% ma_hawlL4lPԷ Um>DD`ިs~@p3q/Vz޲4t~YI0{O[~[Bƚ '0Fc\O*MQUDfpp{c>̉-)M#c̭$)ڡ̺'<8VA3GIkQT._ IG4fq_H+0l/zjDz3)?}<{LQQ6U/}%+S|Aˑ.iyA%lTwk%{M2~N 1wֺ&/>Cʦ#z dĀ:M*D } w ɺ4X;8Yrm_Nm69mϮᡒ4)a)D7BC#pebMt%Pk>!>t%5F|pLKEip*oL%ΊcZ/HyP-[5+wQg鈵,O]g5ʼ/^8VS*ʍEO  ͝Nk̯_J̉ՑU0V{΀ Nf_zfHXP\Im6T>K^$Xbڤ*%K#J<<,YiTB<]v:˧'^A88 ~/8{3lw41gOVk4lfJܗ2 i|x$.$@Twp[;X՗۷$ ߖ@j=$ Oe7X]k6@L8 4y#|]0E!޹^7Pw}d MLD۲޴{dɛѫgTП=F$&كo-H͛{$AHrl~r@;6˵Co30ƬU g=2x{ yL7珬GunYb;it9c챱:ptꭱ:rYpG[CٓȲGJ;Bd\Œ"HR| $uWB6jB~e6Dl5 r&TGXK=XcC! ./b!G.Dt% )XoO_=yy7sԮ;xVmnbw`9}=CȚE+x!H/7G]6 Lpz? 7fg@c{&:-bIGX&? @ײ^M>wB%/G*6*Kwgζ7-v>ʷtrgG٤GQbl,_.}'a߮mᥕ|?vbvvY(O?u_Jd5eW{V0U,C\~]m?S-pE/:#;Ƒ5Z7(z~F ѕNCH;U(03G!+^OSh1zNfH?J MvHw.VbI~_1їulQ/(I,c[9(ˡ$DK  ҜkK\@|g}}!/d\z&6gDQ|m]޿[ |fQԘG>Sy3ʬU5>j)Ebct$4DC"Ĝ?, D.kBps t 2%3W.e_̵]Y\\"96q ).oUH7BԦd?ੌDU) UĠ#}~P&ߠWRg!4H,@^:qQV{ =h jOS-N>$.=܁A 3Ru),Lu؟XyS?7_v^X?j`a@$@*)3 Tol|[KKШYjy^/m69>h?إ:[}oXƂeC'rMn8ӓ,p87ɬ9]S- op:/!9D>]QE`Nvz (܏l>RKsV{:$yET|{`;eSԒ^D)([-Sfv[4Xt[үG`d %©[SI֞fH/g_`!uQL_ o|r4tdYLBstu|=*7Uq C+`"4L<^֮FdT#HmLa8^Y^MSag^ⱉ1Hm|eH= іII>䗇"ʹ$5nIBn!F yi;C_MV[b1/]D,97Fgٷ+eDKv؛3hq}:q~*:a+ LOwi {jq&z[Y*Qݼ3愇V+YK؄ko/C<|k.`eu7.lkhїDs:H }BO8½(UL{ZsNAFkXm9`G6UeۻZAUM@|eohl%5d ZlmTM,RXK-H%} z\.B عtS3Ok<0i= 2Hecc+kOD5aBXcUBwvXu6]H(x$*cJv.@3 FkKgPsа-N9wtSeRŃAS%C U4rjO0'b=&Yg<^+)ʒ"F=CW1"LE̴]k<!*Jڸ4~W'M\)X[VR&gkqobY!Ѳ'ZSN+|V„g(ixO_-ԿyY:_w,OךEUFyT&6$J~SM%Z!2rcZYxtbeSAfVj J%>tJqz.Ql?zMӎrɅfԎ")eR苮Śu%^^6 ,7Ä @EGff:Rj_yR;}l _,孠H;#dhc$YU,զKCDx`%%YJ֒Gf%wqFDo:OĘRELs?bpG_7߿/ϧ}^po~h8%e#- D٬n<*s*vm!~,@d ?Z \sy@qZxNH"7KYSn\8KŰH6%$ğ{W2B|4*3[' T09 7&ѻCn`z696s C!j9 YGI e;LXGǧa~F}!DMU?DO}A}xGp'asVF^"GJ ,K:x9e]Ȓj+IB$ X2ޔ~UX N a*=fz[lro?=58cFӽF1b kmgJGjr_b”^gZV f&tM=2G1 凙n z^pW:L JiuH=<.In \2+f?W ܫ%#? OJmBb 7S 4(?x_IoVX`X3D˨LAIp{j*yelRC# 49a@ Kz{|X 1FsÓߛ߱YfjlPsŔ^/,ӇؖYdE`itRG98tM#@AWW4"/XޑOTU}̩k=ھ3rϫaERhSLjEh៓b8SsA"5^ҰwW]l^Tہy4<լ E 0[? s#+@;X)f()F߰`lD J:Jc#)xTiT xl%8҂T$X۝eURKM $@3,ʎSyt* ᖿSZHG* +JH]vP1 [Hzfn|}+z8f"$@3t}!.'6`=~b6Db<)2xR՟ͮ/^ .wSnB@&qS5J>B2pɛ:p񤁺^Ag0B푐:x64 QEQt-I: ݺNmL.!\|JGC}^1})dӾ/w !)w"rqkl c='xJ.Nb ,rZv< ިJSE/t0nBq>?TyрMΌg.>D>7q?L}Jc}qƬå P_dRY:N%_P wpBJHG?$7b$[_){%SzT{$T)5 ? 1 g'&Tz蔍̬>ĕzy@d_"eȞGP% Z8 [nn$124AOb [r3hQ^I#Jz1f{/~ J]%58|F·;De8saHo(#uđ ]^8ni2փ P:xuAcHhz; t]RɾOD 2qTj\ֱX7)y Vn z=t^&==Ds D*fRTC.UK7NC3]c;T}nʡrsx R|\`f(VšwÈWxLJl/ 1:&XxSl(nanVAJ*\R*>6˓`\'ZTnAj_?ȨQe >!X/oi1%8RdQ׼$5E \2n]'f|*)aTiMm5׺-'HgZ0}*3tQa:%⎩~$1cy缱 S{hhx'u؜,m]׮DCGr=ZU{2v #gX\&oe =e&@'OXKQ +J6UǔE- @O+/k0EV٭T WUhrrnq?*cLA~}FXzyr^9+G!>ico 27ν; Hѧ 몷*qDT8eD+7Rg:?k(8F| 0uMl*)ve7t qWGVv@;Zv ]m!+mž)EV/i2sDl}~DPlhe;37Q%Y7i\T1-<Jf4uV &+6k'iaQY;gcJxr3BZPʙ7R.>5q:+0uaZ̴R_&+3I5ڛ#Bw8KznXpβm1XV[wT1gT}bHjHlL~B RӞ:kjWX(]]d1y;T|s-8F%n8kls!oA!0QIS6jy{ dvtqX~7Z&³&wjqP¶/[<^ _M>v33"79FfDq!}GؕRp G$'(gc<&cU`FDHyPU]{6*{2ZH 9XʄkW'D~gBPﳹ)k@ij99WHL6'BܧFaqO|h3(_ omJ.zþ'[c@ X4p€[Lᰡy IG'0(oݏ#X ȃj yNC2ײ7f;~UF]cszc gi]y/ʏ%bwN6ѭi$0FSKXhXRٟ~( \1RGڎ?mu;%FhQ^%džKj79ĪSۦqLihp &^1D ,u-?nl88 UMBh<29}]TVM:,XMKZ~˟x* 1G-Xb42=g>zӍSw `hb(&|(+gxZ&K2j@HziwR潤Fz]J5ߋ8f\\T~"H3dɸS(]H?TRi7|g.n,.CIRU|VCYJZŧ  g.YXekU׮(EoEb_M_zԍɸ>`,rQY44nA:ә!b< j'oKF~R! quzɟ_IivF/Aگ3&KpgT[05&)i"?>K٪»ȪhJ ^O)P 28[lRBI'|)hRKC*S*/.L z*>ȶ5mG3^ur!~_o@U+7@!ph,8z>]XPVGcZ9v=˾iR_M g.Z ilzژOQbj1 Uw(4Rd39(s* \C)kcR%fhWrLv#ng&\VE,o{} Xa-R SJ+ 2R]y@Yl\?sVfbΨ!F? [ H[A?Ҍ.xR.?C086P~t-mRh73ķP|6ZEmF6 .󏋂,)=5ϽA@$YE׬#3{|h6|14V(rx:<τM-O1!5?\ B  o]I4ȀBf7S$ڢ|upsX- YcM#z(V.moSi"lњқ>]ĸTeInlrȚ,#.cp67ku"ebrj }IG[Q>?T"y~Y*q!uD u+1cDms5NsTGכEO.'$wtmJ}Qɿ9%ڌK !PZ,n+5xʇ3}E]Eu crf,|BzF]Y&tk*_Cr8c%aVpEŽ?HWaؕ>Le_G,P%tx?@??Qdt٥7NXS]{ 릎N&R6>s5[r:6,Ƞ#bHpF"Q.NLЗ`R,e\MZ_ +lЬY=ᴞq5X_T+  ӖvH}ː,KI&S" rV7yڴ*|Y{͠H0i}LP$Ch&]& ꔺ@US{q,Utxִ UWQg27 TP>7GPQH%7ɢ} Ξ1 <)AyAӻͫ\Ixq7;b1Se1Pw„lzElL55pJhqU1M0736V+$tK_}y7 |CpXi nn)Dg36ÅX=alK 6j~VgD$4C#ze#:}]b $,St 48t,kgz-'wLx4Y`_F׺;"?䧖ގ{-WEzw*NJtŎgLw PcHWwaS%WFT WqI rPKC86/zmIm!-+|aUy3%~[+$_ױ2%߼oV߾/hѲ׫i#ge/n=Sp < Fnr8„7"Lj~ۜV &٘$ +\v2YQG6*%`V0b 擸,D˪Bvp:?{cGHD v="%Dg>xw]TCmoI]l=*y!]MHHV̭bTTD Ys[]@أY!ڬ"Mk_dڳ_&4trjzX,n1oйIz"om/]VW2WdA3>wkϛs6Ѻ*)Mto:+ PЍ0Uzd&=K|9Ɔʭ6 Co[]AHϞUֽ`w,rYѪĿ -Z0Q*γW\]!a?g @qlJʛ~ dNF'PFEc&L X? J(lw,=4ј*btx_© ˖/{FMuԩ=W KPjnD8dNd_i)p+o I,F:rĝ.5.#˙>3Jh._·HS~Q6c+ؾK4Y=ra+Rؼe!?:xEb1&, P'NF1/ sU#xIlPmt|H)26@ 0?q73Iޑ5s6>i?pCR.Pwsd: 3xBbWw fKI'JQ혂6cԾIdf9a *V&/ʡ-q%p yу/cpZ̀[Y8(zٗصH ٧m⼕d|WgSDdfr6ڛ;NM`: Z;"ܘ1X$13굍0%s0^=5f0UEv7O.""u@tg7:G0&USMn5ȩ )Kz<#Mi4'^{0Ⲟ=ݰ#`2*X@|(f~5p3*rVRM^Gh}}] .A_s5k?7ؓ@) |>]9ߟ}`l ` oE] @%)KiHCQ#X}C*; 7ˍ"5$ 8q륎qp7­6IeƳVW"cHk,,ΛQ@M#+DTd3q!Trwoe׻]U<瘕)eIY5gA6/## ً֞!ϺX#TݶV&pSj̡VP_nl|JM+?UεĶud=`bUæ:h1jT]4f|>C rt59J+E"]ꋾ_h1v8fYi*ղrli