From ebbc0ae26cd1c6efac78bff3b53571a600a34eb9 Mon Sep 17 00:00:00 2001 From: jdg Date: Sun, 12 Sep 2021 20:34:18 +0200 Subject: [PATCH] First commit 25/05/2003 --- README.md | 9 + TETRIS.CPP | 1162 ++++++++++++++++++++++++++++++++++++++++++++++++++++ TETRIS.EXE | Bin 0 -> 47345 bytes TETRIS.PIF | Bin 0 -> 967 bytes 4 files changed, 1171 insertions(+) create mode 100644 README.md create mode 100644 TETRIS.CPP create mode 100644 TETRIS.EXE create mode 100644 TETRIS.PIF diff --git a/README.md b/README.md new file mode 100644 index 0000000..c2a351f --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +#C++ + + +*25/05/2003* + +ToDo: wwtcf? + + +![screenshot](/C++.png "Screenshot") diff --git a/TETRIS.CPP b/TETRIS.CPP new file mode 100644 index 0000000..5b67013 --- /dev/null +++ b/TETRIS.CPP @@ -0,0 +1,1162 @@ +/******** + Bases simples para recrear el juego TETRIS en modo texto y monoProceso +********/ + +#include +#include +#include +#include + +// Ya que el lenguaje carece de BOOLEANOS definimos unas macros +#define bool int +#define true 1 +#define false 0 + +// N£mero de piezas con las que jugamos +#define NUMERO_DE_PIEZAS 7 +#define ANCHO_TABLERO 15 +#define ALTO_TABLERO 23 + +typedef enum tipoPieza { PIEZA_CUADRADA=1, PIEZA_LINEA, PIEZA_Rizq, PIEZA_Rder, PIEZA_Lder, PIEZA_Lizq,PIEZA_T }; + + +// Definimos que es para nosotros una pieza +typedef struct { + tipoPieza tipo; // Tipo de pieza que estamos definiendo + int rotacion, proxRot; // Estado ¢ rotaci¢n actual de la pieza + int posX, posY, proxX; // Coordenadas de la pieza +} pieza; + +// Definimos una partida +typedef struct { + // Necesitamos un tablero para jugar + char tablero[ALTO_TABLERO][ANCHO_TABLERO]; + + pieza piezaActual; // e informaci¢n de la pieza en juego + + int lineas; // Estad¡sticas del n£mero de lineas conseguidas + int piezas; // Estad¡sticas del n£mero de piezas jugadas + int puntuacion; // Puntuaci¢n actual para esta partida +} partida; + +pieza obtenerPieza(void); +void AnimaticaTimeSlice(void); +void dibujaPieza( pieza P, int color ); +pieza obtenerPieza(void); +void procesaTecla( bool *salir, bool *pausa, bool *tocaMover ); +void dibujaPieza( pieza P, int color ); + void dibujaPiezaSOLIDA( pieza P, int color ); + void dibujaPiezaHUECA( pieza P, int color ); +int anchoPieza( pieza P ); +int altoPieza( pieza P ); +void muestraTablero(void); +bool piezaColisiona( char tablero[ALTO_TABLERO][ANCHO_TABLERO], pieza P ); +bool actualizaFicha(bool bajarFicha); +int colorPieza(pieza P); +void procesaColision(); +void fijaPieza(); +/*******************************************************************/ + +partida partidaActual; +bool pSolida=true; + +void eliminaLineaTablero( int Y ) +{ + int i,j; + for (i=0;i0;j--) + partidaActual.tablero[j][i] = partidaActual.tablero[j-1][i]; + + for (i=0;i 0 ) + partidaActual.piezaActual.proxX = partidaActual.piezaActual.posX-1; + break; + // Flecha derecha + case 77: + if ((partidaActual.piezaActual.posX+anchoPieza(partidaActual.piezaActual)) < ANCHO_TABLERO) + partidaActual.piezaActual.proxX = partidaActual.piezaActual.posX+1; + break; + // Flecha arriba + case 72: + partidaActual.piezaActual.proxRot = (partidaActual.piezaActual.rotacion+1)%4; + break; + // Flecha Abajo + case 80: + *tocaMover = true; + break; + } + } +} + +// Nuestras posibles piezas +void dibujaPieza( pieza P, int color ) +{ + if ( pSolida ) dibujaPiezaSOLIDA(P,color); + else dibujaPiezaHUECA(P,color); +} + +void dibujaPiezaSOLIDA( pieza P, int color ) +{ + int X, Y; + X = P.posX*2+2; // Coordenas iniciales para dibujar + Y = P.posY+1; // mas una correcci¢n visual (hay que encajar + // el tablero en la pantalla) + + textcolor(color); // Establecemos el color de la pieza + + switch( P.tipo ) + { + /******************* + ROTACION 0 ROTACION 1 ROTACION 2 ROTACION 3 + *********************/ + + // ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ + // ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ + case PIEZA_CUADRADA: + switch( P.rotacion ) + { + case 0: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + break; + case 1: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + break; + case 2: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + break; + case 3: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + break; + } + break; + // ÛÛ + // ÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ + // ÛÛ + case PIEZA_LINEA: + switch( P.rotacion ) + { + case 0: + gotoxy(X,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛ"); + break; + case 1: + gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ"); + break; + case 2: + gotoxy(X,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛ"); + break; + case 3: + gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ"); + break; + } + break; + // ÛÛ ÛÛ + // ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ + // ÛÛÛÛ ÛÛ ÛÛÛÛ ÛÛ + case PIEZA_Rizq: + switch( P.rotacion ) + { + case 0: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X+2,Y+1); cprintf("ÛÛÛÛ"); + break; + case 1: + gotoxy(X+2,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛ"); + break; + case 2: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X+2,Y+1); cprintf("ÛÛÛÛ"); + break; + case 3: + gotoxy(X+2,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛ"); + break; + } + break; + // ÛÛ ÛÛ + // ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ + // ÛÛÛÛ ÛÛ ÛÛÛÛ ÛÛ + case PIEZA_Rder: + switch( P.rotacion ) + { + case 0: + gotoxy(X+2,Y) ; cprintf("ÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + break; + case 1: + gotoxy(X,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + gotoxy(X+2,Y+2); cprintf("ÛÛ"); + break; + case 2: + gotoxy(X+2,Y); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + break; + case 3: + gotoxy(X,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + gotoxy(X+2,Y+2); cprintf("ÛÛ"); + break; + } + break; + // ÛÛ ÛÛÛÛ + // ÛÛ ÛÛÛÛÛÛ ÛÛ ÛÛ + // ÛÛÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ + case PIEZA_Lizq: + switch( P.rotacion ) + { + case 0: + gotoxy(X,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛÛÛ"); + break; + case 1: + gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛ"); + break; + case 2: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X+2,Y+1); cprintf("ÛÛ"); + gotoxy(X+2,Y+2); cprintf("ÛÛ"); + break; + case 3: + gotoxy(X+4,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛÛÛ"); + break; + } + break; + // ÛÛ ÛÛÛÛ + // ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ + // ÛÛÛÛ ÛÛÛÛÛÛ ÛÛ ÛÛ + case PIEZA_Lder: + switch( P.rotacion ) + { + case 0: + gotoxy(X+2,Y); cprintf("ÛÛ"); + gotoxy(X+2,Y+1); cprintf("ÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛÛÛ"); + break; + case 1: + gotoxy(X,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛÛÛ"); + break; + case 2: + gotoxy(X,Y); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛ"); + break; + case 3: + gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ"); + gotoxy(X+4,Y+1); cprintf("ÛÛ"); + break; + } + break; + // ÛÛ ÛÛ + // ÛÛ ÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛ + // ÛÛÛÛÛÛ ÛÛ ÛÛ ÛÛ + case PIEZA_T: + switch( P.rotacion ) + { + case 0: + gotoxy(X+2,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛÛÛ"); + break; + case 1: + gotoxy(X,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + gotoxy(X,Y+2); cprintf("ÛÛ"); + break; + case 2: + gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ"); + gotoxy(X+2,Y+1); cprintf("ÛÛ"); + break; + case 3: + gotoxy(X+2,Y); cprintf("ÛÛ"); + gotoxy(X,Y+1); cprintf("ÛÛÛÛ"); + gotoxy(X+2,Y+2); cprintf("ÛÛ"); + break; + } + break; + } + +} +/* Devuelve la anchura de una pieza segun su tipo y rotacion actual +*/ + +int anchoPieza( pieza P ) +{ + int anchuraPiezas[8][4]={ {0,0,0,0},{2,2,2,2}, {1,3,1,3}, {3,2,3,2}, + {3,2,3,2}, {2,3,2,3}, {2,3,2,3}, + {3,2,3,2} }; + + return anchuraPiezas[P.tipo][P.rotacion]; +} + +/* Devuelve la altura de una pieza segun su tipo y rotacion actual +*/ +int altoPieza( pieza P ) +{ + int alturaPiezas[8][4]={ {0,0,0,0}, {2,2,2,2}, {3,1,3,1}, {2,3,2,3}, + {2,3,2,3}, {3,2,3,2}, {3,2,3,2}, + {2,3,2,3} }; + + return alturaPiezas[P.tipo][P.rotacion]; +} + +void muestraTablero(void) +{ + int i; + + clrscr(); + + /* MARCO DEL TABLERO */ + textcolor( LIGHTGREEN ); + //123456789-123456789-123456789- + gotoxy(1,1); cprintf( "¿ ÃÄÄÄÄÄ>"); + textcolor( GREEN ); + cprintf(" T E T R I S "); + textcolor( LIGHTGREEN ); + cprintf("<ÄÄÄ--- - ú"); + for(i=0;i 0.5 ) ? true : false ; + + /****** BLOQUE DE ACTUALIZACION DE FICHA + Actualiza la posici¢n actual de la FICHA en el tablero e informa + de posibles colisiones (choque con otras piezas). + *******/ + if ( !pausa ) + { + // Si no estamos en pausa y la pieza ha cambiado + if ( tocaMover==true || (partidaActual.piezaActual.proxX!=partidaActual.piezaActual.posX || partidaActual.piezaActual.rotacion != partidaActual.piezaActual.proxRot ) ) + colision = actualizaFicha(tocaMover); + /**** SEGUNDA MITAD DEL CONTROL DE TIEMPO */ + if ( tocaMover == true ) + { + start = clock(); + tocaMover = false; + } + + /****** CONTROL DE COLISIONES + Fija la ficha en el tablero en caso de colision y procesa + posibles eliminaciones de linea/piezas. + *******/ + if ( colision ) + { + fijaPieza(); // Fijamos la pieza en el tablero + procesaColision(); // Procesamos la colision + partidaActual.piezaActual = obtenerPieza(); + colision = false; + tocaMover = true; + } + + // Demostracion de que nada se detiene + AnimaticaTimeSlice(); + } + } +} + +// Hacemos la ficha permanente en el tablero +void fijaPieza() +{ + int X,Y, rotacion; // posicion base + X = partidaActual.piezaActual.posX; + Y = partidaActual.piezaActual.posY; + rotacion = partidaActual.piezaActual.rotacion; + + switch ( partidaActual.piezaActual.tipo ) + { + case PIEZA_CUADRADA: + partidaActual.tablero[Y][X] =PIEZA_CUADRADA; + partidaActual.tablero[Y+1][X] =PIEZA_CUADRADA; + partidaActual.tablero[Y][X+1] =PIEZA_CUADRADA; + partidaActual.tablero[Y+1][X+1] =PIEZA_CUADRADA; + break; + case PIEZA_LINEA: + if ( rotacion == 0 || rotacion == 2 ) + { + partidaActual.tablero[Y][X] =PIEZA_LINEA; + partidaActual.tablero[Y+1][X]=PIEZA_LINEA; + partidaActual.tablero[Y+2][X]=PIEZA_LINEA; + } else { + partidaActual.tablero[Y][X] =PIEZA_LINEA; + partidaActual.tablero[Y][X+1]=PIEZA_LINEA; + partidaActual.tablero[Y][X+2]=PIEZA_LINEA; + } + break; + case PIEZA_Lizq: + switch( rotacion ) + { + case 0: // |_ + partidaActual.tablero[Y][X] = PIEZA_Lizq; + partidaActual.tablero[Y+1][X] = PIEZA_Lizq; + partidaActual.tablero[Y+2][X] = PIEZA_Lizq; + partidaActual.tablero[Y+2][X+1] = PIEZA_Lizq; + break; + case 1: // |ùùù + partidaActual.tablero[Y][X] = PIEZA_Lizq; + partidaActual.tablero[Y+1][X] = PIEZA_Lizq; + partidaActual.tablero[Y][X+1] = PIEZA_Lizq; + partidaActual.tablero[Y][X+2] = PIEZA_Lizq; + break; + case 2: // ù| + partidaActual.tablero[Y][X] = PIEZA_Lizq; + partidaActual.tablero[Y][X+1] = PIEZA_Lizq; + partidaActual.tablero[Y+1][X+1] = PIEZA_Lizq; + partidaActual.tablero[Y+2][X+1] = PIEZA_Lizq; + break; + case 3: // ___| + partidaActual.tablero[Y][X+2] = PIEZA_Lizq; + partidaActual.tablero[Y+1][X] = PIEZA_Lizq; + partidaActual.tablero[Y+1][X+1] = PIEZA_Lizq; + partidaActual.tablero[Y+1][X+2] = PIEZA_Lizq; + break; + } + break; + case PIEZA_Lder: + switch( rotacion ) + { + case 0: // Ü + // ÜÛ + partidaActual.tablero[Y][X+1] = PIEZA_Lder; + partidaActual.tablero[Y+1][X+1] = PIEZA_Lder; + partidaActual.tablero[Y+2][X] = PIEZA_Lder; + partidaActual.tablero[Y+2][X+1] = PIEZA_Lder; + break; + case 1: // ÛÜÜÜ + partidaActual.tablero[Y][X] = PIEZA_Lder; + partidaActual.tablero[Y+1][X] = PIEZA_Lder; + partidaActual.tablero[Y+1][X+1] = PIEZA_Lder; + partidaActual.tablero[Y+1][X+2] = PIEZA_Lder; + break; + case 2: // Ûß + // Û + partidaActual.tablero[Y][X] = PIEZA_Lder; + partidaActual.tablero[Y][X+1] = PIEZA_Lder; + partidaActual.tablero[Y+1][X] = PIEZA_Lder; + partidaActual.tablero[Y+2][X] = PIEZA_Lder; + break; + case 3: // ßßßÛ + partidaActual.tablero[Y][X] = PIEZA_Lder; + partidaActual.tablero[Y][X+1] = PIEZA_Lder; + partidaActual.tablero[Y][X+2] = PIEZA_Lder; + partidaActual.tablero[Y+1][X+2] = PIEZA_Lder; + break; + } + break; + case PIEZA_Rizq: + switch( rotacion ) + { + case 0: // ßÛÜ + case 2: + partidaActual.tablero[Y][X] = PIEZA_Rizq; + partidaActual.tablero[Y][X+1] = PIEZA_Rizq; + partidaActual.tablero[Y+1][X+1] = PIEZA_Rizq; + partidaActual.tablero[Y+1][X+2] = PIEZA_Rizq; + break; + case 1: // ÜÛ + case 3: // ß + partidaActual.tablero[Y][X+1] = PIEZA_Rizq; + partidaActual.tablero[Y+1][X+1] = PIEZA_Rizq; + partidaActual.tablero[Y+1][X] = PIEZA_Rizq; + partidaActual.tablero[Y+2][X] = PIEZA_Rizq; + break; + } + break; + case PIEZA_Rder: + switch( rotacion ) + { + case 0: // ÜÛß + case 2: + partidaActual.tablero[Y][X+1] = PIEZA_Rder; + partidaActual.tablero[Y][X+2] = PIEZA_Rder; + partidaActual.tablero[Y+1][X] = PIEZA_Rder; + partidaActual.tablero[Y+1][X+1] = PIEZA_Rder; + break; + case 1: // ÛÜ + case 3: // ß + partidaActual.tablero[Y][X] = PIEZA_Rder; + partidaActual.tablero[Y+1][X] = PIEZA_Rder; + partidaActual.tablero[Y+1][X+1] = PIEZA_Rder; + partidaActual.tablero[Y+2][X+1] = PIEZA_Rder; + break; + } + break; + case PIEZA_T: + switch( rotacion ) + { + case 0: // ÜÛÜ + partidaActual.tablero[Y][X+1] = PIEZA_T; + partidaActual.tablero[Y+1][X] = PIEZA_T; + partidaActual.tablero[Y+1][X+1] = PIEZA_T; + partidaActual.tablero[Y+1][X+2] = PIEZA_T; + break; + + case 1: // ÛÜ + // ß + partidaActual.tablero[Y][X] = PIEZA_T; + partidaActual.tablero[Y+1][X] = PIEZA_T; + partidaActual.tablero[Y+1][X+1] = PIEZA_T; + partidaActual.tablero[Y+2][X] = PIEZA_T; + break; + case 2: //ÜÜÜ + // ß + partidaActual.tablero[Y][X] = PIEZA_T; + partidaActual.tablero[Y][X+1] = PIEZA_T; + partidaActual.tablero[Y][X+2] = PIEZA_T; + partidaActual.tablero[Y+1][X+1] = PIEZA_T; + break; + case 3: // ÜÛ + // ß + partidaActual.tablero[Y][X+1] = PIEZA_T; + partidaActual.tablero[Y+1][X] = PIEZA_T; + partidaActual.tablero[Y+1][X+1] = PIEZA_T; + partidaActual.tablero[Y+2][X+1] = PIEZA_T; + break; + } + break; + } +} + +void procesaColision() +{ + int X,Y,A, i,j; + bool noHayLINEA[3]={true,true,true}; // 3 es el alto MAXIMO de una PIEZA + + // Miramos la pieza actual y vemos si consiguio una linea... + A = altoPieza( partidaActual.piezaActual ); + X = partidaActual.piezaActual.posX; + Y = partidaActual.piezaActual.posY; + + // Vemos si DE LAS POSIBLES LINEAS (alto de la ficha) DONDE ENCAJO + // alguna ha podido hacer linea. + for( i=0; i ANCHO_TABLERO) ); +*/ + // Comprobamos una posible colision con la base del tablero + if ( colision == false ) + colision = ((P.posY+altoPieza(P)) > ALTO_TABLERO ); + + // Comprobamos colisiones DENTRO DEL TABLERO + /***********/ + if ( colision == false && P.tipo==PIEZA_CUADRADA) + colision = tablero[P.posY+1][P.posX]!=0 || tablero[P.posY+1][P.posX+1]!=0 || + tablero[P.posY][P.posX]!=0 || tablero[P.posY][P.posX+1]!=0; + + if ( colision == false && P.tipo==PIEZA_LINEA ) + { + if ( P.rotacion == 0 || P.rotacion == 2 ) + colision = tablero[P.posY+0][P.posX]!=0 || + tablero[P.posY+1][P.posX]!=0 || + tablero[P.posY+2][P.posX]!=0 + ; + else + colision = (tablero[P.posY][P.posX]!=0 || + tablero[P.posY][P.posX+1]!=0 || + tablero[P.posY][P.posX+2]!=0 ); + } + + if ( colision == false && P.tipo==PIEZA_Lizq ) + { + switch( P.rotacion ) + { + case 0: // |_ + colision = tablero[P.posY+2][P.posX] != 0 || + tablero[P.posY+2][P.posX+1] != 0 || + tablero[P.posY+0][P.posX]!=0 || + tablero[P.posY+1][P.posX]!=0; + break; + case 1: // |ùùù + colision = tablero[P.posY+1][P.posX] != 0 || + tablero[P.posY][P.posX+1] != 0 || + tablero[P.posY][P.posX+2] != 0 || + tablero[P.posY][P.posX]!=0; + break; + case 2: // ù| + colision = tablero[P.posY][P.posX] != 0 || + tablero[P.posY+2][P.posX+1] != 0|| + tablero[P.posY+0][P.posX+1]!=0 || + tablero[P.posY+1][P.posX+1]!=0; + break; + case 3: // |___ + colision = tablero[P.posY+1][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY+1][P.posX+2] != 0 || + tablero[P.posY][P.posX]!=0; + break; + } + } + + if ( colision == false && P.tipo==PIEZA_Lder ) + { + switch( P.rotacion ) + { + case 0: // Ü + // ÜÛ + colision = tablero[P.posY+2][P.posX] != 0 || + tablero[P.posY+2][P.posX+1] != 0 || + tablero[P.posY+0][P.posX+1]!=0 || + tablero[P.posY+1][P.posX+1]!=0; + break; + case 1: // ÛÜÜÜ + colision = tablero[P.posY+1][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY+1][P.posX+2] != 0 || + tablero[P.posY][P.posX]!=0; + break; + case 2: // Ûß + // Û + colision = tablero[P.posY][P.posX+1] != 0 || + tablero[P.posY+2][P.posX] != 0 || + tablero[P.posY][P.posX]!=0 || + tablero[P.posY+1][P.posX]!=0; + break; + case 3: // ßßßÛ + colision = tablero[P.posY][P.posX] != 0 || + tablero[P.posY][P.posX+1] != 0 || + tablero[P.posY+1][P.posX+2] != 0 || + tablero[P.posY][P.posX+2]!=0; + break; + } + } + + if ( colision == false && P.tipo==PIEZA_Rizq ) + { + switch( P.rotacion ) + { + case 0: // ßÛÜ + case 2: + colision = tablero[P.posY][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY+1][P.posX+2] != 0 || + tablero[P.posY][P.posX+1]!=0; + break; + case 1: // ÜÛ + case 3: // ß + colision = tablero[P.posY+2][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY+1][P.posX]!=0 || + tablero[P.posY+1][P.posX+1]!=0; + break; + } + } + + if ( colision == false && P.tipo==PIEZA_Rder ) + { + switch( P.rotacion ) + { + case 0: // ÜÛß + case 2: + colision = tablero[P.posY+1][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY][P.posX+2] != 0 || + tablero[P.posY+0][P.posX+1]!=0; + break; + case 1: // ÛÜ + case 3: // ß + colision = tablero[P.posY+1][P.posX] != 0 || + tablero[P.posY+2][P.posX+1] != 0 || + tablero[P.posY+1][P.posX]!=0 || + tablero[P.posY+1][P.posX+1]!=0; + break; + } + } + + if ( colision == false && P.tipo==PIEZA_T ) + { + switch( P.rotacion ) + { + case 0: // ÜÛÜ + colision = tablero[P.posY+1][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY+1][P.posX+2] != 0 || + tablero[P.posY+0][P.posX+1]!=0; + break; + + case 1: // ÛÜ + // ß + colision = tablero[P.posY+2][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY+0][P.posX]!=0 || + tablero[P.posY+1][P.posX]!=0; + break; + case 2: //ÜÜÜ + // ß + colision = tablero[P.posY][P.posX] != 0 || + tablero[P.posY+1][P.posX+1] != 0 || + tablero[P.posY][P.posX+2] != 0 || + tablero[P.posY][P.posX+1]!=0; + break; + case 3: // ÜÛ + // ß + colision = tablero[P.posY+1][P.posX] != 0 || + tablero[P.posY+2][P.posX+1] != 0 || + tablero[P.posY][P.posX+1]!=0 || + tablero[P.posY+1][P.posX+1]!=0; + break; + } + } + + /************/ + + + + + return colision; +} + +/********** + Este proceso se encarga de actualizar la pieza en la pantalla, e informar + en caso de colision con otra pieza del tablero. +***********/ +bool actualizaFicha(bool bajarFicha) +{ + bool colision; + int alturaPieza, rot, x; + pieza nuevaPosicionPieza; + + // Primero borramos la pieza anterior sobre el tablero + // (esto se hace dibujandola del color de fondo). + dibujaPieza( partidaActual.piezaActual, 0 ); + + // Esta sera la nueva posicion de la pieza (en caso de no colision) + nuevaPosicionPieza = partidaActual.piezaActual; + // COLISION por la derecha FRUTO DE UNA ROTACION + rot = nuevaPosicionPieza.rotacion; + nuevaPosicionPieza.rotacion = nuevaPosicionPieza.proxRot; + colision = ( ((nuevaPosicionPieza.posX+anchoPieza(nuevaPosicionPieza)) > ANCHO_TABLERO) ); + if ( colision == true ) + { + nuevaPosicionPieza.proxRot = rot; + nuevaPosicionPieza.rotacion = rot; + } + + if ( bajarFicha == true ) + nuevaPosicionPieza.posY++; + + // Parece que intenta mover la pieza HORIZONTALMENTE + if ( nuevaPosicionPieza.posX != nuevaPosicionPieza.proxX ) + { + x = nuevaPosicionPieza.posX; + nuevaPosicionPieza.posX = nuevaPosicionPieza.proxX; + // Si el desplazamiento horizontal hace colisionar la pieza, se aborta este + if ( piezaColisiona( partidaActual.tablero, nuevaPosicionPieza) ) + nuevaPosicionPieza.posX = x; + } + + // Miramos si podemos bajar la pieza un punto hacia abajo. + colision = piezaColisiona( partidaActual.tablero, nuevaPosicionPieza ); + + // Si no hay colisi¢n, entonces actualizamos la posicion de la pieza + if ( colision==false ) + partidaActual.piezaActual = nuevaPosicionPieza; + + // Finalmente dibujamos la pieza + dibujaPieza( partidaActual.piezaActual, colorPieza(partidaActual.piezaActual) ); + + return colision; +} + +// Elegimos un color para cada tipo de pieza +int colorPieza(pieza P) +{ + return P.tipo+1; +} + +// Esta funcion dibuja una figura al azar en el rectangulo definido +void AnimaticaTimeSlice(void) +{ + static bool reiniciarTIMER = false; + static clock_t s; + static pieza p = obtenerPieza(); + + if ( reiniciarTIMER == true ) + { + reiniciarTIMER = false; + s=clock(); + } + + if ( (clock()-s)/CLK_TCK > 0.1 ) + { + dibujaPieza( p, 0 ); + p = obtenerPieza(); + p.posX = 16 + random(12); + p.posY = 2 + random(5); + dibujaPieza( p, random(15) ); + reiniciarTIMER = true; + } + + /* REPRESENTO EL ESTADO ACTUAL DEL TABLERO + /// HAY QUE SABER QUE HAY PARA VER SI TODO VA BIEN //// + 123456789012345 + 60 + Üß Û + */ + for (int i=0;iFwf5S_`ySlE+(U+vQG^ghIcIR;m;TMbhaug$D+|@f|M0~CUVzUQ zd`_kkat5C^eC(qM={JUuWPEPMXCgi`@OdAf2X0!Xdy1c6cnqJP;IkATJ3hJi+>6iO zj1vsS_&kTtUVQ#T)&D>E|3m_NCm7N^i6Xmed_#(u#u734Hd5KLrHrfgF zg-G+6%_XF=I=xzK7CZMS6`{7jot`<@aWDn|EM>aoCtj(3x zyY9_vNLk)=wyUyHJlkCbBGqcK^y;)qL1aI!G464htzU%Nx4LI^=?4~PyJnOTt}v@a z@0w9gk_+#sViteEl7^JRTX#JwCU@zP8ntWA2Mh%b&f4+{nS)C1!Gnon5`e+VN@f>n z80JY_MLe-?Vybq;RAr&fAN+z?>hw(dcWT`qy>9&YpGIjXQ8J3~c^aReG`y&$InB*!lsUgLayabY7Myh!A zVL2XtOsaJ1!^3#^DX9|Fhez@7IH@9I*M3^rviBEEL&``WNR0g?aS7NTnOwyqxm-)? zkbGE63P?UmlfEj#h=;{vna3SNEv`EiN36wrKQrOG%>6~YxKC_y`vm!P=3z&Y*n(`@ zWJPf3Ey{9MFV|X>Jp6p<+eIQI2CF1uER!E)3I&VzQAQ*1?SCLpuMw#B?aEU7#kVJ! z?43^1Dw9Q4I;T`|Bv;D6nGh~(k$B#o-XW)mc3vJVwmfk(jyvXE{hl$BT(i2yc(1v! z;#-?L99P-`Orh?D8Y593uM{lv(eil!Pfl0lG_gJ_SFH1&(6OLDWSYB{7mr6M))-&U zmF7;!PkzkGNc+-}mF-prmo}(`e9I%0q`ODf3pbewsTXchzpeNN^}*@YazC+IrBw%( zNY?bhr1XMX_?zU%lFX7oKoV5;#}KkoFU5|`&+^zVujD0uWWLANA=)}Tw$6H67f0%C zVfq!q@>?t@#r!(k<;2`QF+{rmR?#kqHeMzNeEV5KBsSAy3nS-)m-sYMpJ@v_3~nEL zsy(oqq$!UMsTY2Y6+7@(F#BsP4S_$B%}M605A%v>bN;XY<71WO6>mAY06*9c=wDHGbz_^PBG8f zGS)2LS(Rj7+d^4QzF8uAcWsQAm}2G*y1U}aC{h+h8n$@^nBX-gMw(?)Z9$C618vri z`RDQPHhiY3si%2D?k00c4#_18$xp~*&V9#KrTS+;?1W>T8bnw^$tS zo`EJi`rFsp__d9cqqR3lgNYp13wZt}Y5Nd&ZEVjN5p5=QV2G`vEhbCsREp!J%<=hR z0YBH>EfjNsZ*^*`r25}v+>7$K2FzyUcY(4*dz!~cgL+YH8gM=% zzZAGb7iIGejm_IAo1--pJ0tyje3Z>t4VceJ`!yh)A9g7?S#8o%M%qcivK{45Yp~^v zd=5`vX-_K{>7`z3)f(_|MtZIKMxEGa5=U zBTeWbF4n0tw?NBzo{@&ooWNg5ULf!8o{6>2kS zPa-4L_LPj!Y`sGj!^@2Pa!)n?)1rAZ@B$D$syi(f(e{do(zm@ zSKridK4qk(y+qe(zy?Oj?j>rMiZ$>-MjB7SftP9Hf2;w&Vx**A0`oNB*NprnP-bXP z#~G<}T%>Ig4##LY-!RfKEvFCn1}*Pwq@Q_g5mzRu5;(_5fA1k=mriKF@0h@&O5h-K zV=H5#9s0h8c$tx&?kOE%;|(n*$Vhp;Y}ln2HE2nQx?^$=Zs4YZy2f#yzy!MCjD`}-teNZTevI?*B{j- z3AYFj3lnwAbS~W%U8?SY&LJ$FYX}~_b2}umu_)V$t^2Q((i7`U&*Xwr2DA8lKj{lR?^eftz@ND zw?LEmIV%NkrOzhmY5H8oN@wXa6qccy{7|;PR@TExpV2(1EQ3o=tsH`!-~>D;Kem;X zcB)hctQ;+!rZ8wNDU{x4tn`|i11j{nft6OP&k4ZX6TuALjGPu$dNP7}mOg*YO3T#e z!N7beg4sZGPO{R>2N<$-<8|d?8Rx;9Os$|8&;;grI zFhrWuA$=Z(UImrS)(Iu(pF|p%ZmxC=N?d2_$i-JD{p!k<-syn8B6HIA+okpi=4xk$ zyS#%q)1})+EXZB4c!kv#TH&#^HQa&E@X_D9a2VYzSv3;obl4XhO6{Fwh$O5#N6Q+ER818 zQ;3h# z6HWJ}3#=%-2_;D2HTH%E9qDb5&!~%HH}*-N=#xHa)Lq}8-Xi`!Xech*qr__Zr?4}!t(biaRMbs zVE%QL9_X#qXXK-m*7iyJ`=lF4b#bZwtBD(us^zF7aMj*}=sWP-)7J>JrP zaer_B=i|4>(~l58S^Z3odm`?YIA7eOvA>P|S8Q8sLq8JR8TVxTO>y?vQ}NU;wdbj} zX7Xc+%pQSA$CIM=T+T3Q=~b+c9$OdeI9Q#VN8>vLn>t54?mvxU*vabksx5p|6tYk( z2yvQ$?Ski{*S1`e;n7puxGXM;n*rO?@kw@Oc~_avt#GA(b(dczjySpqJB)Nib#Q@y z6AE6OKpRC{C@WVwOdqlAn(;`tcB$@Se!3FagwF0^k5<41)=_hP6tK9u ztXyoA1E@lQ-`rGeAp$4WjmEPrv$(7D=*kJwmt*sud(ia%~(Uod{A} z+8$3$>A~eaTaDNXyocT82FAHew8dvVQ5^?+o@?d`VyVZ*dFS_l6%29S0_csHgKmTY z(b2aW2<|Ni-@qdAdn8Q6A>f;J-g9F~)O*|a>IHBxfasVTYK~SS&;9{Ix84Y&{C}TU z_ItekjsdR%cwGx~MQI0xQ{iILmW8}c8&pXrDE+_;<$L+)zO3&7DJj}P zH<0=t*bf{JL&3lxqCKQTVnc5atzfmi@%6x-X>gr1eptreZ{qc&K>xpu@$Vu3ubQY%H2n`wG`RMEpo#xm8UHWZ7#PX? za6kUP+nH``cyz6je-HB43I6}Ei~hqx_}_ZyI#%ew`0qUw_&O}ssVdv~p*h304>Knj zhdw@(ek?;?96~?t#6V*9;6D#OIdJx%&4buP)vnE3Nuqk$KjNi+0XVVO+1jX^A<0Z# z-8T&o%P*@33YP)bl!$fl($6odN<^pXkME;IxWkN7@RWCW$}hXidB({pwl2}unQ03- zuzGYt*@L!(!-*)ZyW*1{!#UPMC?)Z*q;Vt>?wg&eWlyBps)`av8B;l=+6DLiV&>kw6h&qG=k1UzMrpHl$J(CrEZoW@Kb8!?+!?5A?is@w z#@WAK7>?s->G^)DLA_<1S^9;RvQ_TgEUeb<#qlS+d2#tc;Vgb@{o`lDEW3E?ScE!B91G zHuU36u^!met2PZ<>7PvucB&$m8&K^JCVlCqpP8!ft#4gR$fWPLXYlGD$YAoHR zfj4sUp1`E*tDl(KLr||F{hpKdX=SP7ux+H;@Xeg`4h710g4tsl?9ZI^dN1Mu4fr-E zxqEAlv|+oJ_cvPo_x<9xQ2}^0l%1S3tCyxz1McFaANA6N|6c>Y&q+flSo4eDqXGZP zNn9_1i5k$yseWRM_Ed-dPgI4YdV8t06r<&Q2Kz_LiHupA*P5(K;B!tp|Dev{e`_E= z?4KS&IRDUqUvfX}7atRq^B*Q1gqwqygi2>7HK9=QQ8|UYe)@ zH8vmCz=L_!FTO~78pca;JtZTO%+zvH_+G#G%^GM7FP$0~l}3UFyor|@G+>{O4-Qv_ za2p@>i)W?$Jmu{af69ZS-Ws)k6r180xqD>u$l;^fl1GiCpQ7Z=$@G(uyiol#kI?=d z7{Mn$l6*RO&ZwV^OiO|PdL>y&Bq;{;bERLK^VMT|>G$RpaUWOXW9L`I{k>+z2gF6l zij6CR-E{rO3HJYoKUYQWgz7V`J4T(^bY|4z2KI~Gs&j_lj_1G97Yd8dQGy$2I7zd# zSGV|!WP4uKERwM$mguVS6HhkZ#b<0Wkxf~A#+!Pw_P~Vwl}D;3PTFH8AHSZ8Sd9^D zXS42lKI>F_m6HZ#M4qeIo(E6z`P8+-g;ceU4-};mF*KG+;WlDb5Hz!c(6E`2mZ>_& zFw3gxlkaf0TEs=Ht82RR>`d30$bH`M0Yr1u4OHqp7dW`lztSTz zp$@6=S9<3_Ko_I{x=aV?2@9ahbX60_?lF;1?41oMS*NHr#PKqh1(=Zov=2#z^JS&9iuD7nBLEly~QJvJI1- z>V#gBks`1py?Ueg?J^qpLOW6AwDe{W0TUm*o{D}-`($uKira@Sx`JBNC$N(CNgl6; zz_8>qv~%E)xqgLKi-}PO(%Bx&7@eUx|w)v zvCt^Ic7yBGaaWhkX%04*$6KobmW}4>3e{XUy1HgN`7Fg2s}v7FJONG`3c?E$*A*YM zL#xS^vX~9E<)+Z8Zl%IuSk)b_a14^iR$1?Hmxqai&C1$Vm1El$FfvuvoG56=UE2ad z;-VPbj&WO629|>XMOWj0s*#NB;!#WD<=xT^7K+xEZ&G42?@ zb*3}42O@q4F-@kebDbSK(zf0uBkm!V%L!%fEAD6AC+_E(cZ_e}I@ggn*OA~V7l^YT z>JoEItB*^cg;#fHmYbX$NXbuRY~Q*g&Ge1aNUzc1Fl{+_9$ zo!hrxRYs^RNZh#c`K#YIZnBAZ~T41a~pQu=d}e7p6K|7^SK*Iuo+)! z2UZBdX0E36t?2_uIaf6Rp*PkVhed2HV}s4pXC(kODBP^D)bFguX1(riH4~M zUbWWA%?l+PySQQE5smu}TlZ|oz`JL?#4VlHQXbsn$H=+94)^)|Ldw9|?-F(y;m*Kt5b%k-HHcYy( zJa8qP;pJ`K6OHG`#OcP5-)fTPIt&;O_;r4}#Pw~Qv;W$*klE?MQ z+?&O_Ygn!ZNF}UtM{?CCd~R~pdLdW3itRE+nskJYPwjBd#!vs}`7!}=3A{^aml+x+ z2}^ZwrDA#lECqgt6z$KC^kj6a|BU}k!=x8Z@P0}ASEOs0h`q?k%8&acJWP(|bx0T* z?nsM4-yDdf6Z@n`^-15_Cq1!GdPbl0oIdFVG~Hp-xg4l>#t9sx*06M%AqGuKQ?$u8 z<00KBEkrCqOnwLvQCP@4t0$Nh;UQgmb!0;F6TWE}MubAM#~$+Jgt5xRsgaYGI^h?D z*>!6}ifcw8I?1@o7TQ7F_V5tVPK`{fu!PODFOZGzbi zE{Ic>{(MMDd_<58ho!$Ca?>R$0oVp5afP5HK1M_5q}LDSqZI;e1$sM|g8r={M!(v|cM{|SGi|B(N1=Cwj|37^?ssI#^wUCTOkc1h3&Ke!;) ziHH4i(8m*pK0*xv4WAlFusv801ZI7Dqx{{H*oCgE@kQ}sbJK~YQyoWK`{J8qbJJ(8 zK>Ygj>ZVhl>0<@+fwGujQ_%1BF>XJRf5iEU_*FF|-W%A-H-5`r@k&h+chLLE*f{b7 z=zc3jKL_-yKtDU-sI{qYfhE?Hv9fN7-g;74n3pVu-1UaFO_jdNmRCdmK>J$>2ipJi z>d57EZ$>a5Z|*1^vDAwN26y+ElBKS0wh$J!)Fe;uWj_0>>wi`4V1uVm>s|?-;r6{6Jk1>{@Xhy1h^tmR z$$Pp<&gVY!evRI8pN`A)JK0QaisdDLQq0$u8=`U_iSbfnpv+-v*9$Ko+DDgawM;!V+gh?PvQ#(1o(^hJ}!BmUF%t3xcd>{(qZ+(pY3?%(v3 zfRJ5FIG--2t1LeglxtOl%?%1a69^mi5n>vrH|8!#t^ygU7S>M8reD%>7p_IhxuWG< zS~<*Hguh11m80BRT231=hMtg-P%d2(unAa{JEReC9mF6flq-e8`S~i2q*wCu5g@Pa z2JZ8b{J(Yg~PL`XZphV3xstqu2ig@iS#EoPbrR3icN~0YLL+C&oLSiru@RXk5(%B2lJQs zgb+=7%0ps#sJ2+JP&IPEw6Tu<5vmp6NqmAgPb!!PCwwuX@j0Nimb`G z0>eR35Y(b5GHZEf!Z+eUvDqb$a&?{cpQAD3Yzgh%bx$$zG~_XTZXoOs*fAP-bzNhN2AHd#g{DR6!Oqyt1)fq|*Lde)1oDJG3H+Eo6n(mzS8N@D2bA@< zjei}5N`~%cSKB(x)un#_3GpBnDW9tk|P|N;qwXFk=(cOLXIs%Cb>WB~gR9Tf1 zCJZ>e7|2)NH^`>&ibscMUK%IuRj+sHK>UIvo+~<$SLl_s=T&i>efX4gVL|AQQBaM zpatFQa`sxUuKof9GyN5;=nrfrAQoko$~aLE?k0Sb;n87d4Al1KtCcwWWr))$TC(1( z$mWb%`oOQPHrG3K$@-7i7$n=Z%$$y5PR!{DtnMw0M{H0W!W0to=EJP|VBrF6+M{jZ zTzI43CXB-f{SBl{vL4@tDuKFg`l-C2UITGJ<>)jwmiL#=geAy2e#;u2yS$BHi_j`ma@wR_Au))dFBWuG>1dVHp^PMWS9H5VKX>+{*cF&K zZBPS}T%l(iI#+11vp+f_Ywle4Q*CS+&BV=yoHj6mkr^WkJ4Q)QhG2D8bO4k^9OfP4 zrKKUSty{8(M0*?9yvh2hwZ-D)r;T$Mrj2s&)2vRtcke|lOE{M$mOt|B?W zdc^Wh&phO$k)czq=A-3C@iWw61WMq(5IP7$Nt3=gDt%cWk$qJzxz%=_vt6)wbU?x| z(`RQ}>UD^niw%jzt(7(d8oy(#w6~kid}q*Aem)nz-d){#clkMbkc>&qiM9*cHWx#- zkAH3asqt@)kH3Ay?MrU|$?cEc{@M7KZ-46c!rO~)Z@vAE30V^!ns73G#6GtG4&)V}gg@B18iexc|Km8!K z@=uC|P-d{mB<`DoN!iMEUZbY7lW%`Z&fMF=t*u^rG}Gtk-*x`r{=#m26?MPWed>}t zvJYT;x7gg9E&8@~pE?=Bwup7N#zb}qxtrPyxtrSYxs1;h1KqWy!hYVwHiI{#-LQ*& zpGb!ox)g8fFpT+y*Ur06y=1C+vje+m1o#qw(2GvFPF3_~cx}9jR+Hd^{3cBi39qUjLgnraJ7ip^y4>etx1cad>0pm143C`nUo z-#r<-Vt44J8H`*E_IDB77AgCgk`tC6RUaWjd6{Ah$%{92BNwYlntKLgB#xWB-~&Su zYa?bB9L8$6&4XdADl~SIYRb~nVL91r4||J4YTH|gH(4#S%lJOQq?Zm5#TJIJv|3|( zD%{*^U~C}>kitV{!+%J!4DRW~C^;dqE(a?r7Z|4Wspx3}#&(fN#~hh-Y7)ul#)o8F zngl^t{bo{R7w@@9V}R?rQ|$zK2=-RR#zR`T=%UyRmZ^FNk6S!3bXTX*Gsn?1stD~G z@Ls&6Cte@lx{LT0CC^7BZ{?AER|xitD-`F*Z-|$lp2lKM!nu}PMTRxRPaB3=Z&^*k zyO=$Cp&@>;d~{lt^YDA|y9PAGySn2YcU2AOKjCOYd=(k+-YEK`6}r_GyBhWpvxlIN zJRF2HvIBCZXB1QQVpKTe1v13J?#LRs%(p8}`h}7!4J7%y3>a~bD6VfR)>wjuHRv!p zVCZn_Gyv;fWsRlFFjeR@I0kM4gh-PWfYTLZ(;U}~P6Jn*K!37|V(5=Psy@Bht!8IA z_#H!Kvu4F@dVz$i-@K}3=pCb~NbBBn3RST)|MV`F2IW1E_=Ag|6lD5S*C7GI>Z_-+-Ru2S1@MF_{ z=FlICuz(_G@Nl8SY)Y<#GqfHbf?I(grq-EeQLA%WHWRW$urLBL_i+a+Ya(#H#S?2F zG8|p8(0Ms&KGCnOws1hBu2jk><3mxcAl6MT896@77M5TQg_qbdv{DdAWipRC1!7r? z1R6GHO65@>_@#{c(l*bTf_a;=w(0j>l?O8@e#Tl9U7N_0%BDBeGPJNyEl4TQT-rhQ zJb><hpIm^Y4rd*g}qAiWxj^0^D7 z`7~p3Zu(L0*D#0VrW0z$!dz)G%~&#BQ5-{X;}x>@ppr`5JteSeSlqxQa0_ho{Xoeu z+f#BfYIF`s6Ju@H6^B4+@r4V5%{VtsKZ@EurDYyetK;sL8z^P5C;tLNj!X_Bp&Wn{A+)UdIyT**H-IDJVm5G&2p1krF88Y6&4j?S|+B7W0u&> zbyn7km#nQ8PX@*$m6ec7M3Lo^=FW!6BGYoo>N3cjTI0z93F5LFNbTL)BWOO{dI zi!0Pz4Q@Es3ol`HNUw%sFBXmxV?jFkr5?~n7fbqSJE!!Z zqAusuT#I`744V;4+qjdLc6`SPA{~aDjZd%(xb0aQSE0kaDmLs@6siu|#YEiY7KxZ6 zV6~MtedmFz))wkvL3-d~;a9ztQ&*sL*Ts?=R3M`12s-xIaUU~G<9-ifV{!adgna~s z1ctC{#@*0TOmzZ&HqA83*kW+I8#}dK%h5|;W0jXp(pUJ&mFk&%IE3f|qh+hwYCl?< zq5I`bBI@wjJsZ&ns(e3KSP&Q>Fq^m@+l?ilHRQi$|f&P&iJug4^P!9to;+4vDgo3%cRDqq8uVw@7iAQB*ac>&y# zVd+U03YY%`V~asJvZUsf-P^p2coVw}|A3dt>%aBj8uZs` z^dZ&k)k#4wJ&S{>3YaGji@r*fN~iq4{N?aX*y6sGHwtd0)B|<9Ksi_ zC@oXKkwJRy3LVh31%gGq!)+5-HAa2}P{NU`Oq1aB^nMM^8|X%9?iGrRT^`6LR;<4t zee)++ziR8!uJqV7>hj0;X#Ybs?H{L>syj&aQ7(|yw8`<;L&9Nd6VW9s4?&`^PsDOT zv)=YYm4gv?5QnMbGOw20l6kyhY-U?Y$`m_aGCZ@GuNVx&G{LNt$C*3I&4@fB(U`Pe z52Ri2rga#0j*`vlb@Vv5&A{HBY3IvZBf?*GeiMoC4C`P#qq2<~QWnOAST=x0FkxFv z*k%gb3}Kt#DvzaM;UWwN(=Gy+NR0X|sNY~05Wuq{8B!>uy7gXsNC8Ac>RW)OrD1(> zv|LI^x>JEitxrLXdM^C1d?TB_{s!*3s6-V68e zq9I3!BZS2}1D4u~Sgdf~r%c|Q7;mwFV_s=+JDn0Sv}1SOi~X?D2ETcsx>yR>!&XR( z;dRcd6iP_CA}ATp5@}IziP)^)GRp`h%9vc)Vy;0i-272`HQbJHso*My=gzg+ERN#a z{zhLDa>=8IPZL)4W}9(K5!pP;xaDc$+r`0>`E8q61X@Iyje-ByR->K^CR&8A>i_mq+!x#aPM zw+2sgz5$0E=i~um7YYVXzP8#QJhlEc&X?ft!PEh>=)`@cJ;x}^aPq90j*%^~0^VKq z*^ZS4-dd+1y-xyv$JzkjclLlx8}AUX_u;Jz6oShqr8$;hHfuoiHS%Mzv%70xG6>Ex z%aptrX9>lkH)yWUd`QiF5I~bf%)=WQvSV=u6(i4)ZCXWwh0|w=t(IHv$h{FMcY(#5 z&BNC{Ef${T%sNK`Edm}0>%_Yr?q}lz%M_{*L|1xfY8hSnwFPvEUMa{!>A5HHIc%`l zI~GduXmhsP78Eqdri-N(g-b+(vX=@)@0?T8S{a4K*=c#gYE zyd=}>DmZlAm|kP85%-I&5%#hW2d(CytzsVT9EEX?NF`V{R_+I10OiVcr^(6K#C`W* zF*`301PIQH>!H}^qw6{pEUaVdk>EV|=dsqRW4VCFzN*VTsF!1l6c$Q3%Enu4hM{(> znY?AyqwMly%Nnh^7b8 zf(SxTFk}7@9W7komqbN{)2lg1&qoZ7!=0%*9J z!qi*g-zgr&=trySQOzbIv;mueCgg~S=7u-IG1K23rmMXwv?*Z-B{USLwCX`^RJY;n zd9~%LyVfyk2iP5p*^ZbdoH5|=V#X}vT3dLn&wL#2e`mk+Mrb_g7(F;{3R!BW(+tNs zi&qCn>*=W{oZpH^EUqcjo&TmMQtf{px%x9_W42hoRy*dWW7M9vwguIFf?Xyj#vcf^ zzg5Kisj@}WU?a1W@`EEXEUMlUA$qdv;7=R3-h)%cZAHx1I&(g`_#4_fHgyp z)G&?JT)MF;ap>EHSQRmQbTAYIHOEd>#A0kk0!E`!w!ot3>1?%#B{3EyJI0$>Y{rX; z)(nJ;G&0q>z#PUkqu6Y6nCMSG>^*ldkzL-0;~$J(E-;p%>%#~Wwp zVWf0(4{Kf$_=ysD0fQ1R^}$-wXDklwI~KKEyg=tPWT{ehj*YYhvw0XD|H)NzjJc5^ zd)WlE>2T1D&~l2+I85uIaX6Cch>cLda>WIL;Z4P6`1;h2NUp-E96h>!9A=f)H>x*S zEH^;iq(dIUgOh)poT7Dd)HRC!oJ7m0(=@$0u$9piqUOLG5WZRt40D0Onvjv&M=Vn+ zgrbLgq>UxQ*roPdbi(iwoSX^dYE}#Ns3}MrwhMpsrh#3LOGWMGTHydg}b2 z_*{4Lhxp9a_;i#7J`c;!P+IEno3HIaioR?VhFo+K^hkQJIupD#yNH~4Lm%WyuY*su z3%I~@VXXt+lSlMvkhVm=fL91XLYOoUz$Og$(Nw9z9U~TFg!F8-PP1EKD}+^Hr2_GJ zm`~rr*)|V%PUBXU^W}mQ{>FJm*fs;*GwubnAD}C-XV(k&0;)C&lWAb@LJgi5O0~H2 zs>&0?2@w_jAY>Ch25H%M`T1(0N7;5ueKs5`nz4>89a}VX?cS{#Y&j63Rs2A`@QCp0 zA{aJio5?v6uj09o@3EUac&4h-Tt%gKKg-J;uAbmQ4Ht>-_`PHi!lf`y9o@hU>D7^C z&z^_iD1#WBK=m!U04J}lu589y*#4)H-&-HktEt|>L$aojivCLQ;2dpf?4=_X#E74@ z{mptLd2M~=aZpSlGq z9lY<_eFh`Yh?ZsY3^}thY{<>a)f4_WU5^0$e0kx2-ZRCpaDXz`3MkV(hpE- z-fZsmIWT?C|(?$=pS425&ar;zk1qhQQ{d z2T85&87_DXMnrPvW2aOZ)$4LPbEOG9bORA?A7+-D2m5+64OYt2$_8>D7C2KV(5< zmVbPd!q;ST*Mm16_1FcE4W5I($m=y^{q@i%dvQD0L<#2|MMs>_{gWPgV0}Q5KAHDK ziqKH1(pgSDrbupTVdko*@Z&BJFiQ;B@la-RYLuXW$_*Cg2B^}aF{+7r28s;nZQQ9A zs4#s2H57nOfa$Gu!glImFyP#laoYtdnm(ofgl&+DhPfVG-cw_w5T&M$f^@Yt11b>r z$WJRaxt{`2v_(!*1I7kXs1tgq0lmPnv@1r)^COQ$9zj!d(2337)fjM4g7~4(6aWop zb2nyY+J(~3=`jFbSWokS0)+v*Y9V8ErX*MW5@#g7j(kjg>H$-y{sw}64@o}`<>yc5 z30^$-ONcszlPR^@hjp*N9YY*H$6b0lWc$LFXfU=fESthG4aPYJ(H|>)t)JR}j@1wA zSjWvO#Pk-ha?o+=dq#76@|@KDqiqBV$7;fh&eLt)~>QDU2_C9`m4F zFqITJf2Nkkc#SW|TM-1_X%t^tY;^C_%e?r~gGSf`t9> zOmGFy`EYk7y%Dee3$|N7#TKLzh|SzrlIR@j!ae@N1UV*iU!lQi#uHQ0b8y!a3AXBd zB|?he#mvO(HSvy28cp$&=D*kMz113l-5GN*pww4%zH6rV;E+d}lEJLv7_l`~gR69H?g@~JyMn#Fm zf|%ny(BWzji;YkSE#i+_Fz6UfM6gQ)M33akDapIC07YQ^Cp4;WWMN#cinQt_SbR7+ z#x;S?L#onC*N=~IK=uRHIbJFR>%8z{etr(M&JhKBI(iPd`V@&7GG_d=IS)Mavu9p- z`S*X_wZJYuAh^y{mm&U#s%j*<1U^w)lP8Nk9k@wobwuPk3ucwtpHSZYG#5&}(H`>-Vy6R=Re{<>Tf<+5We5p z=Ay4{8o}`iOWA~Ze8K}lQHj4Lia^6I9(5IWGgdxnDVsEpPXfXa3J5j^{fNOm*ijI^ zl2D&;JmHIk!yg%lslz$R+vfes8}NSN?e>1{J>j*5Rlc4I8FI=_P_b6iKoNO7+$9HB zg#8EoO@4nuS1XXJ#?U&f)p!N){*Ce{RZJENdvm&^{pQ7iFY!)B+LO}D*OnKyt|~Kt z`Vjf39bKsQp7hMMg2LuirGQs_Lh;@<%LjHFq=(1I|JWTbEge(ERLg%?jebNOQMWRB z2OTwkFREE)*uzw#D>G}#HfFYzZOzM9dw< zDJV{Sv&y8`ppH$&bRB4Je8zk~!tPb^Ah7z(Ae@kz6PgqDCmbx|{4Lp()#QjgUfs4B zvY>&vc~(XILJW4;;#`Qh&LLtk+hOBejyNtSCZRYsK~Zy<`>jWD6hN2X{RwUE!`R{I zb?L#u6{HssT)}d!30-cyV}YUy(T7-Ct|tdEiVhPkrva=7?BXSaDO3E;gcgKnM@jR& z0GivJ@TvO{aw&l^v@Q)@gV7qI2oxJ^iich+Sni9=udlibf27U&@si0Tj~3f$@6nm} zL3iOGS+|>)cBP`*y*XE3R>5Bw13%`_dw&45T9$SjgUd!sh^GtOe(jaxNsbCUq69gm2hdmvlH-+=eYBxT1~9P_(rM zS9C;s;R1coB%yZGc{~RTI$Q;vgrm}hxB!2xbZBOATVbLb{$-cFlUU2oCly>s%4tn1 zZYy08_!mxP#olVHs9dYYx<9GSeH@)YtFbmGed<0&)MvGt=A;%HJ*Ic=ps4!nm@Y;ZzFMr)xh z&}xaWueRl~wX=tJ(Wcd6?MiA++Mm=~RwVkhb_{Yqb(x9OTz(;;pfw?6kQx-Wpao;u1~6AIeO?nXJk6l@lA+PHnzMr(ailURT;iwM`E zq~Ikh8WwE!+B?x@MH8W8petQ1M7{-Wx+ZobORqwNm*jO~hI)>J&2SbrzUuN@ z=#0AARcgYUnxwgcbO#Y<#6Z2XOUpuecDq#FsmwFDg%}b;eG7EPho#SgavOH=x@4rk z)YZ?1rXZgLMHIwhOgF~aym%k$?=I5M#MamBKjQ8R7mZjrAN)0oZCCxrf*m=Tt;GXu zT&w?>=ofwRg{#;Co8`f_%+@02)%+!|1Usya+$AcNgqnmyA?txxwyFEjhHbbyfmfyz zHtTMNyK5$v5%}4)?Ohk$nXx6o2~%dUmKw?i%k#74>Gzj*`B#Jxo2_nrg-Op|$b3M6 zc5*gz9$(V0@I>ZPwnQjAlF1i-g>A6U-fPA^2J8&|95e6lDgEpfuG9bpxFfO`EJjC! zx4JA0srndkmhe&_Ld=PaT%$YFyuUeMFeLUI*01)j{%nK$Vm!iSw$Zef+_c)SC0_fO zsm35XU_ENBmj57LrA@YSIs>p2I@P~}4$~MTnh&3 z`J`ohi4oV9PP-hn@&Wquq5Ln3L7}d*A;;h3_vp`GyS}8cEL1!4H_vqY%F8F_2rdaPX+V1xnv3?;&qH=A-)}@6(t! zLUs9T5_+=w1BJ+6Y7Nt2E8LI-EuabGz1kwe9rgfgw|4kX`43r-vd0{0uCU@5> z9&CX^_a!duK%esHJhNHPeY|Ip;8|vPbIy_UhwizWClRh^;sJu9k@GQj?v^WXzvLH zqIhGN=>e1fQ|kfoh`5jH?RxoDu^ld9$Q}Wm5am~Eo-{R`b3DANOVK-Kz8AmhT$uAL zf(z&Yo$E}Tsof&Z<1FG*#^N2bgJ{zb3Yt2Zdw(IRWf4jFK8Pch)TM&Oyp+d>wU~!P zQ*?b6FTef$9H(wC#P)Kevc6UE;r$1{i73mLa}h-y<~_3wi+2!tL*>5ETlm}VjiC!@ zf-Zb#X@dX6!GOORD*#)?CSiQ|!y$ye|9El!v;e9rwYIi^Rk+3(ZVeT`( z{gOs_R@L>B7kcNy_eJxoBYmN~Tx=Pb zkKhXJ#Im<<>vA9F;XjAuS*t^U?yBAf4RG5IoUQrtgtdn&>)mPCI_S<2p`>5#zFR0Lr2AdT7q#f5vM*OgxOP-<)amHRZ_a1xJ9nkR-sLIl2j z_3W5!r>?&9;_MiDNgM%ry!C*3wCtGRI)%62zJk%yJkyW_4M;$#QJe4=cm)^BrHMq)%c2EU?;9FcZf>`Yc(#N@VHIh0$bO7pxl6&+~hxa zs#7(kO~*_vJ7ZE~IpVq+lQFQV*J1R{4|) z3W!%%y&->iHpw+36IWLTVgfB4Tt!^634;lTc@Fm3^L0Wd4SUr2XoAr=3p}jAU$4nz zdBN%+2HL7=U^NckS!E_AM!FiV=dl>#s~VejKT#?Y2I4V7x zNJp><+k}ukD22}=wRGlP_+eh_?L^=)hm>pD2KOh9-njvY-lMR7E=aW}3=o!h12P$sA#qnq1vFhuPI_a0u2$ zu|^(dZN!8D&>0_W4mQdru-!IjFL7C`1FsQmVy5AyrHr;k;4W-Qyvb*(->}}=hzqji z?XHt?r$^X7Qk15ers}3M;^(9Hr|%oxmVU@wXF6^=;=NYT+xydL?`Kx$h+f+qd(H7TK{+0mX7+5AN=}MTd$NMSmGEIk@9FN<>X*!fkc6uVM-u!AfoG)GRLKqqeg(dof|_U=iTf+ET-C3CgO!|Kb;ZhpJKL+Fm1B-% zmEDep->Wu!$nH_nz66Z{HV0Fiz6;{2!J)Svr84jT5kv6S8X0pPh_5He{plM)5WtG7 zg}kRg@Dv*YJIF_q$>>YzpZhP+f4IV2r+0_-PDF-zS(z1C=nLWdO9fNXnoK#kS0S#G z`lfSYSN7W>@dtd_(DW;>& zm|xX94P0a9;o`HhKz|F5yD#WVja>bjyY(Gk%W+)2=We~tRw1|+=t*I)NPpE|Aixn# z=Qq8=j&)tM;a!j{?pnb^3nxf1wb~Kh?+&+C^b)TBC#h5g4L>f$_ zG;tCBXFX0K4UWvIHj`tbwSXk$ut|14saPl)7(Ap-+oM;s84J(DL?*(Fou^kTZKh@N zdZvK%&td!9`ToViGTE)}p4&HUe`Wjn?XPWrN8LeJ2d&C9yc91=kopc2g7N^^Vw#4h zxf2tD*_&g?YnscCTAB2oI`(9$*`v*U{{FF5{kxU^Z{WBwsq~NP8sxoiNWX)mA5si? z$}qP+GfgX0mzB8j2{p-(nAz)hXi!4FntdpeWNxTojiUZlP)dLPty-IjqE?*Ym+a6j zL5d+4Ex%)iZK7HaAtOHjdcz;_rXvcE+c`Jb!!OtTJl%tXK4~<~eIv2zkH{Sv_DPe2Qv5Y(RZu#hAnMT9qgT-?dn(X~=PgqI zkb!k|LOT99HKQ!~p7mpJQbpna4A(t9Ttg>ImBeLQk|E6>Ox4-|fGI|8gNh$PJ$nsG z+lPNT^!$ZKmcB<7xZS_X4mrm6-yF%OKQ2n(_g#x zaqo#MN?9G0vN~3WamfI$Z(MUp729-z5GCB|bJxenN7NgZIvl6SKNSnYbJM(kWHH0T zt9zL!?w9mWNl>9~+F) zwO3a6^x0S`;+LQSX!bm5-4%DK;Y5WVUWpH`$f>jn_iO_v<#wY>=MApP8JsK4Q=J;S z1Cf$GI#7H6v>qc_6!NwYnLRZtXxQQy53|zoX z%!&|8{#kSmka;@}AYx1VdnNYFut<{3FCH1~|4(ki|3obE7g=Z5m8&|hly{kmr&IFK zwYSvZR;tVM`kZ%U!zzs&G-Q`vfi4-{>Q!YsL=1*o}Fg z3+lh^5h|QLeT)iq0Qay(9@FH3Tfl_uok+)ex|;VF-<D@fs86HMQshq(k_pqPX34+=-Dgwyan?Y=8Bi4=gCL64U<;1t9C@K z9q)R48E@~5SyvqHExo6GofFahdD6CT5uFsG$MjE}r6XyGdMcs?C5l0bSE)!ht0WWD z2m3ll45T~lEFwj5b0sWI_+CK_-s*B&Z*2qHl-ZC$o;3Yi`u({ib+?Jh7}MDXRx0g8 z-%TD?HFX$ngI=Zc1vBW_8D*C0tBdfnlgPqOXc0SkT$VadyWjhyX@0J|46_890Rriy zzh4UMB>-fVo25x@^|OT(5_lVifr+ehUZ%F!>ag_DrPX2g&rs?5^J8${8uAu|UERDR zlPw6jPV3hcg#2<*f8f0u!K2*%>KkgM(NmES_nc1pOBZhHt?Kd?gbvCFWqBIFjH5rM z^G`0V4pQ2*%=}0h$Rxy#aXqm>oh|7!+7!hgaT#FGLu@#w>~rv ztVT>j>1eC!+srDPObwH?op|g2oKn5ia!EYCli5vP{JCkqG`u_Cb(L|(&X-QKD)$-a zylOn1zvgEq+Gd{!M~q3TYhAo%mI>}p`P}ste9=EN(Wmpc$5s5xGWrLcfktfF);7A@)B-^ z=87Td_Dg8jx>DRQ%9DXG_c?6Ir$v-tG(`dI?MTV4X5o%9WAqh|@` zS-g1`Yv!HFP@9R2PH{0G8ySDgN(LGJ1@#p>anST zIQ>#n0&!(|W*O>cnP9bJR!Irnv_Zqaq2KfH5)U{~d1!%*+Q4spcr(dPem7#ShkNTA zrH*gkjY~bu)^vQkx0R$eHJ#&X)WChb%!c#Pmy)P9t;IXbIMziDR>N}HiEy!5hNcsZ z(pRRB<8KO{-LTFfNPksmJx== zC8P1y$KpbLNs_y}wIp#DxsB)JE8@LpsX{HbSsUe6`BC|)+v3aUk@YcpCVlYhaCK=L z`%Ppo!P!?Md6l-i11|av!49cFu{LT+d`r2C*o0r2oUPylrbC*cd&tVjm3OhE+t#7Bim-1msJ>DqVoYIkUJZ1IR(Ab|@p0aq%-uQJf zow2J^D^p)j{Y~m0Q~!|qm()L}_Q2!Jr{d3;Gvh{%9y;1J`oid&M~9I*HaZ>OOGhV- zd3W^9W8NPfI|d^%K?uCAD;d*KJIZ7R2)z zp0o+1ws=6!yTr2nwu#dWMe9G%SEqiR8hXX0R2Mz!QnE@0I0nMX?G~KzmhGP60c(%R zKecR^Im|F_Cx@*FkA{y*(~d3aOB`v06cCuy2COOv!s+ayg( z+sj&^B7!1xhhizUErLpoJdOc;1l?%+}5pv@79)Rh(G@2qWV9CT46E1u0;?9#MWQk0{yb*S?dlv zbWVHo_mnKL5ho+QW`CzQOWZ-n&OJvmo#n06PvJE21Y{Qf(@sy?KE&*Ed;z}e+O#+& zwQbG&_J1*XzlY6)h&-hE2Yq<&(51C?E2eA+2gM4Di|%Q59h04oCuZ#oFD$;N`OY)X z$c(&We)pS`A1GOeW-47~>kfTwZ0inHZ3&g-onPC;ORFXJ&eJJ{$abHdm~$>tc<4LJ zWZviYT}p{T)GzY69Vfsf?g(q5U`kAZc;DFPT!eGZ-aJdh;Aj=MVVb~e4}3+8=PLNJ zeIskeF~bkCrs-@YJ|o9UziBjsW|Xk-t?<_K3&q{g5&Ent@SJvA)93hLCLB>KTQ43R z?9(-U(~O$U+NC~p`q1f?pZqHe3Ys#%LLz~uXYIsnqQ=9FA8Ib*p0KI0IpFpFGHd4* zYVGFAww0W{y6sQ7Up)L~crd}eH!Xa1TcDqszW+hqMzs5X`r~GQ zb#uUv;x={tQQi#8&pDd@arp+1#lKD7=1ck{X-?9^NngPI0)M;VexLLU{yvfIK&MmX z#S0tEiAU>CD%Fiwpx=YRbX!vUmgd6C&9QuQIMm-ZGip%WGT-^LPe13He+_xDSwIRc z_u(!A?>Rr|qJ^TPAu0qD?)-jwJOt)f=`^@2LKK90w(bb=-GWZb;4K}g+Vd52q*rI{ zEueL*Kef-Xd6fl9ErX;D9Dy77kT7>|$B#lmXC42Gry!s0@xmz`# zYEEf>)hM)4+P`VN$^VF16WcvH#XMe?@+KcrjfzvKyves4je3%&C2Je4YIH;5Ig2OH zC?kIDGf~*KH2F~S`sDYM8!;+UQrUO}Co|YWwyVSPD_GG#1e_~XL z`Pcjd`tSB+zn2~!w9D*ea(6Xvli%869rXuMUEc_@+T+)sj<3He)(+jJ?9J$Wh@Q+< zxl7rL)y|56>QBz7 z|7C`H$Gj7XC(}-}Zddtuxc!l>K3#bID#jAG_O;h);<4@~&48D{(sN0S{SzlV_j=5h zj^iwpne67m_i9T`N2>%(@cF^D{z25%pJi@oV*^2hK#cW&bj-2eZ@nOGL1aP)ME2#r-c*7Y0xIt(D+?Tc*C*Ab{`HH zZ)iN(ka`5qWEvWGH#A<_$P>>U{GmO)sfXSW6Sp7y4u1!wD+do!+7jQoktKz!6?}?@ zW6dpM!_mfu#`E+VqtjY(swk(kwc+r`1YjTA+R*sN!KQ;vX*+xfJkfCM_m&>>P8>W} z|DBL_T4o`dMUM8JoN;SzTe>eSP|j3L4v0c`^#8NE3%ydUr6u1tXxc!zl1Eb2tmQU2 zCRM4WGu5uKsp0UU_8R$4*7%Efp(dOvu4br2{cpT=2Non0&!16Ki>jgV9CB{_0R=-N zBku*}tw^O6?R@bCZ@3TdgSjse*|z9>QD}o{5wM7t7HDs?+}=qIjawRyAll67*V_8m z8lXsrC;4Gis$^6D7H1sazj!}MTNPqQNB@MBU_aa;TY!$%$H8#*Zza=WCb z8d{d@YiUZu2~u~kF2W1Kv%>R2G!Nw(ez|ZM9T2h|UwmS2Q7u_?Piot%qkB&7Fkp4=P)?scKb^Z<~3F{fu)% zS{3!R!hn?d*4dX^a$1HyWgA9kGT!^d;T1}zhHj4^t%eAwI)-q4tY#CNJ~A$YYVKD504OvtW*n91xID8 zXI}0u)v6m(jw+g_viE*J)<8>F%dIVW^HMl#{XFpmj-IM5SgWYjt~L95%gHzOom-nK zC%UpbqjdYr>1vy1L-A7Gfb-`Ws)Dej{wnlfLu1!VftK@1!-o$)uouVP;2mH~4SuR# z#jut8z2!Kr6@SEeDLvQ=HDax}&8P74X{v4VRr2Guh9mt_Si|wu6t*%ITh#jR>t#;b z_YI;lm38Zvp7#CfROAbRZM5#a`_$Q@`JdIF!seWsYEMZ0Cx>UBFM78jrRecb)1pFH z(frSG+H=wNk?OrSc58!9l&Puz_<*jsAIel(Vl}3K>cw;tyjq9&JF(jej z6E%ia-v5V3^x%s4<2TXGzU$$^tb+0Vv4uayzAhh3H<+G)+^&}*klK+W>{5{_E)k(+j%SBL)))hWy$6v*bf~o`w*N=7Z9AEM z%wA&80TtQv?8SE07rbuWx?#}$!8ZKI`1TEKi=4z?T8*rL)w=4O_ClxE=N{u^h0Ix7 z<7Anv!ZWefRbwyqRJg}@YS=)CmBE#t`rewBj^6G6=6^Kot^a7`mZT>6_l7Nfp3J8H z*VxzFw{NC;G_tQZvkj+xINlFY%#3x~jb7R(Wn!DdaoIQIe7|HDOr@4Rs-n~E{zfa8l`!~tOW%Q=y z&!)R^CaadxR1dRBuxGJ)*pINsVL!^AgFTzQ2zw6O1UuVP>2z1IY?puL2u>)aQ|#T@ zkUE#Qyuvey4XqjzKyqhdf~oM-)Yv`cm}p#O?ix%ltk~x)n_w?@)>imfZiNSPPSsd@ zwZ~oM^UqFq*pq9pTfz<$yHI-uV;^TSHZ_~2TXI?9wgD{3msh{Ye7F7m5A#|5iQA`a z%gB0RV|ACc>vt@7r+=~LKwDn?)-*oX+&eSSTK!-e|^S=cDE~&$H9PL;Y_Q zV^4#Zg=0HzG;6@iBgwB+jhssgCB~R3Qeo6a zDI&P7Q`e4UWJjUs6dkR-(dfE%;9Yf{Az+NNaIVnt=#HI@odY5rw3d$19g>Y5ncV;S zj#af46`dF}nFLcLjd#vWqGSqH1dab9kZoPGP6ZHRifU(S+L1}G*6DOAwaKJ38N#$C zQ-mqpWD17+bGxy+0?QgQxG>`$R_&#^qo&MRRc^n-j(O~>`pd=fkg=2g#w{ccrYwYH5pWxOM9J? z5iF;;gym$HK&K>mZtn&1AJbn>L^1g|Qa{kIyPfQhdXwEL8@6rOJ%l&X&BA}pe_P=H zn-;iSq!(YuvTYXfnF-oL-^o{O7Z#2+f$jj_Sm>{+f7P(xRPQLB8B|Vb=Lc68MQ};M zSJ{38J@Nn`HGpuCg4T~>ih+ZxSUCYwkr_*XF7@{b(3YZ(5~F*T`2;BH0s)DGVA%{uj54#4WwHwdOh_UPMNmYtbT$ado1^eV zppHN^>&I3RFf+WKL5AiS)`zXbq+=!>j5It#SHuA@XdoyoxZS@Pfgmfpi%o~Bf*D7^ zvNRlOs)%QO*)j;4?Upatu)ddtwpesve{RngeeL;ZcwC@Pq0%|4D9VAhV9w0q| zG*AZuq?yr+0O_XmA#hs|;OJC#7jbBMOea7yqzrIeFUuj$9iV{(pm6L5eE|j&2k#kK zA%T8DfUP3?jyUO{GXye%AQM2*6;>8VMIbu}asYY~Cl_=(fdN4q}aq>VD2n-5> zy8#|2PCjS{fx)1!2o!*t2n+#@r)Dbz%_Bh5{ssa?pgjbNkwpuE6105?HSJKey_vu; zP(K3qf{Fa?*S8+F<^ki59L0d^8+JVx0m>c$BmIxL!1 zfN}{`g6JG(Rt0*5I@S{e)c{XW4^IRwA>aj_r>?F6{Z7CKI!%3E3reCsufqU*oxmi} z#{?z^!4!bg#F-id(=bRy8XymX@(DZyT18+wM)V~DGe9(U6!mb`0Bk1c?*twOeMn#y z=n@U9M?gJkSUn1QmB4I}hKAJ~&_e{~l83-!phX1cfz}b253ZCxPcd ztMXwj1#K7%s{!;4fn}h}1eSxk7QlJ|R5AqCiy(RDvH~Ej7}iQqLj8d>Q04Gua{tm$E5wsSrQv4!>tpnIe;1vM+K}_~405Var*Wlbw zU_F3?z&`-W2)qt3mcSbT69~KsP)Xn|fQbY)0MrurC%_~E8v&*ecpG3Efqwx!MBtqu z*c1fs0!*i%_W))PcpqRUfe!#4CGa7@90HpG<`dWg@Fan)OhU&1d<0H++(5H!0Ot$H0OJYl1Nb8ZU_ZbW0-pdRsQ?ZD zq!2g=(2>9)fY}5-1^Ai3X8`93d=4Ol0(=3GN#IL>ECOEvWD__HFoHlMfRDh}01py4 z0#Hxj8-OPW90hoqz%e|+{)oVFaMG}IW+woA1Wp1lc2>o{#b~(;gGh0T7+V0ogPV2@ z;0)SOf=As1hXY8>07?Qk1%=!cM8agQ3!h_V_G=q9>DMLk-OL!q5Bi$71<^+FbRz@%5c)LtH_zm|Z zHwU%1#*aw3m14C9v-k<%5^;V8_=CVjl@oMp4m6WJ!?W08p3Ro= zT=oGUz_#*%Y#$$lO=&*+oDXJ)`4ILEFJx`Jh((Ge*rN_(R&hA9i}$eJDNvy%{wwApj zPGNh*sqCQm5c^D=&Kkvf_Ki4`ofRKpKZuXA-^97>lK2?YN{=(Ww163rUkeQ`L zQ0ZFCZk3j>JER8IS6aq~OUs!#5kqaupx5`xSfGD8*jpQGCMc6$jYUici^U z#b<1z;!CzuafIzw9Aifm$Jq~x6O1cQvKZwl7N`84byA*TcPg7$p|XXQDSu=Wl^1a0 zO)HzNyvUX)FR{0jf3S_p%WR+W3OlK6W4|gfWUP=!J

T2Pdx<+7OlY~KGQ-p%BX`qLM zQDM^sU)aM!UDzYS)Ues0xx!;%j|nTn<_oLBo)p%EJuR#YdscWo>^Wgu*dk$f*ka+c zuq8rc*z>}vum<5w*m6M;zCwrzUnyjTuNEr9UlJCFzbtGGUngu2UoY$qe_i+_{0-qy z_*=r~;Twd;@b`t2;U5T1;hTlF@SQ@aW|yGT>=!aM2Ze!}L&9jyXM$Vvh2YVADNNNI z6=rCT3$rvQgxQ*t!eg3mg=aLUgy%G8gr%Cdh2@&F!WzvF!aB{*!g|dw!ke1&!bZ)n z!Y0i{VZY{*(5U%cIIa0Z_(gMBxT?7-Fm0Ok@dBE|Dkdl6aCXh5t?0nfKOp;n}*byinJTkJP2|ak}n&g02Ujq)X$o zbhq<`y54-bt`A?QyMu4k-O0D=?&8~Y{rCZ0e||)l&d=yF_yt`S|4o;}FX{5QQa^|r z^mlWcKA(5i59Yn}g}k@^9-gf);)VKRK2l%8$LWXh@%rJsQa_SU(~shF^bhc7^bY=_ zel&koU&hz#$M8*h7vG^T=ZExT`BA-_AJ8p8I#6%t);pH77>Uc`T zB%T&AnfHsB!Usi6<-;N#;=?1R^Dz-Kcy&ZQe=uSupBwQApBM2cUlcK$uZoz%{}C~l zzZ)@+zaQ~9|1jbSelcPpzZ&r@4>vr=?S@4>#juojH7w)Z4KMJ1h8KCJVKtv?Si_ea z{?1n$*78>j>-ZanSNJBwt9-NJb-u^&20vhUi=Q-X;HM26x!U+P*Bk%EO~y^UkMUjJ z-}oNSGJe3v8Mp9B#*g?^KH_Y1Ur>g4 z#+)TyG!GC%V+Mil7RSaEi0+tsK*Pj6F~h~LW9}Ev#XJCVhHOaf4;M_^xG#xW)3ZxYx2r{LQjgR9W|l2J3#&X8lC$Y&{@m zS`Ui@t&L*7^=q-vdPFR>ek0ackBf_}r^Th#Ch82Unr(%JZYNwN=-EcQa_R(r9OV;?RJwBIj{u#c1` z+DA$A?GH$+?4zZZ?M~@m_A%1Oc9-LH2|?>E47% zQbocP$&)Zunwc<7T9hzdT9+_GdN1K&=}^KfsVU(R>1x6pDJpTEWKR45&v!QA(ayVU zO5$mG>xP>Rp3c6<^EKMYJ;VFT8x67!VApUKToL$lp2M1fX)|+}-%i1@i4k+LSrX)( zo>k0bEx@#=>P5c=6fh2P0Q&*^l~DN0#4PrcoFbkth+nbuz+vFOB7VkxlXsB#TubW7 zE&^-7-zjxtzX$jiqzJ6D64QZyNeahWOC`o*m9VbZr*RemToBfgaly~8178H+2>w*? zgJxA&qM(3GBp7SLY<^+j?ct}HQc$pH;N9UTVEfHFjadp4M0pFgUSpyrkj=%2If52@ zwmA5%M$8mUfohXQ! z45XnT4~>cd16x^m`zQG`d@*0f-{KqizxX@+1HP5-_@5A$z$sHhfoqF#&?V??Xi zOT0tO6$gm<;$X2z94R`)GVvvGjrfYVUVK~pP~0Z&6!(aqiQkAnh?hh`Qc5aGFPWt{ zDOu_&-74K7^_7N84#_D^l%`3WrJd4#>6r9`^s{t9x+Lio21T4AQIV|Zrs$~{su-oH zSFBd-RP0vlQ+%#CqA)7sl%14i%85#!a*}d}a<=j{oL0TXUDDza~>NP*b3}S2J4U)_62CG_y2IHOnj@8cBF4gYSp4TSn{-*1s>!Itdo1j~$+on6C`%QOA_lK@cr_}e>kJne~ zJ$j#hntr|hxc*!HclvYs3;L9Z;Suv9-jDb&;$p>|jsgvmzQP(YOkDFGS-Zs5w`oOf=w9|CJ^r`7<(@E1MlRh#jvQK2c$n?mZ$PtmA$VVcVL@tkf zF>+<(#>oAV-$q`Fyc*dS$)lp9xVYU{)VQdLQNE}Lqh>`dje09;SJcs{ zZ==48YL2=VWs2?`-7h*TIwyKS^vLL%=sD5LqE|+*j$RY}ZuEiZ)6suKw?zwP$sA@j znWN3|<`nZC=0bD1d78Q2{IGepdAWIm`D61j^C|Ob^BMDx=8NV(%seJE#un2vCNJiJ zn6emGj5}s}%%YfAW46ZZjQKcbPt2j1uVaqJoQ^pcBg96>c8kr79T1xrTM+Atofi9K z>`SrhVqcA2AGnWH9^Pyr?}R* zD{gX-B=kv0 zPbg3DB&@@CTTzMT#L`4pqA#&7aZ2K%M4G@I4qvUe)RR@`YlmKfWp%!C=LCQnm(NvI zSM6{BXACSJn3r2Z!4)oNRc$q)ajvonq}~7=RFHH5dtEg?kJmNT<@GR!v($rBvj-Fn z8CsZ*z`=uuWas3wbXSF&G%EAmRW4_Vv$O)jNfX^Hy~s7jU0OT-IP>E-V6&i2CP=4DZ$ z)QourSw$>8P}nS}?vc`$zXDXaAcv~p>~UMt)G~j;SZ-d9zg%U$TDd85-DTq-h1!&P zDm=l42uP=ARJozo;VyHQxGP=7749;ZoW~6nA2>88>xO!#d!Z@osdP{E3;KPOyu;xr zhjtnU17LY|EtE+BhGz|-_4!O5Scjl<}Od`kWb4_+buB^gShN0y51f8;g zw=BRI>++331m*znp}4HTk)NG6ES=>BT)z+8p+UAE1pElVppwO9*Y6{7zt`^|F+V`S z@ciO|=`7$N!0#_`6lP@0>G)m04Q}z!OiJDF`t1Toap6!(BsT~GeupD(NKR4FkRr56 z_K@NLbk{h2zA0ek4=ET>G9&|NsO(hKxLgyc!ovp-%})m?%o>dA1j%O&DZCFCObzt} zbNFp^g1@BzjyBfuV3Sd>>#l0&5!R#+lCMHz#sL%cO*UWV&+vQHj2 zepm{f!?9jZEoDVPC@qA>L0g*CqLDhZ7Xyg&8w1dhRXDVy0Ex;fM&*k5)PsinEGxatiW>ActWYG@X>>48IQ^@Q38*qibBgQvZeEm^9Aiby0qP z5OCpl`aGCNVdIJ`FR!SrK@DUFwFL^caJf8Q9OXV2u~BHu(9BWksw}HUBFG3(_5-2> zxL$qKd^b4boM>i8uD|CXRaaVzp2H;OPr>J{a8=3vDwzSzVjsqZdopv7?embTvBNjj zpMG9(HdMUOjg!1?x`Nx?$$>iL=4Dg!xw`l6<;bb>d8hbc@i?psWwq42@^p*v+pmY; z?r0B}14_KkYKB(LD9#x`YX}Bd_hGIwEHZvi&l^3r-RSAn?#b%z^o~VSIAnk}13=rk zy->MzIDqo2#`-~xD*%cy8G=<^LyMiK2IEs!&?Q{y94}{n6VHuH19P3%TZIe80X<%? zuY{&EG!MpQMIAcKG0x?zE_K!r^Cq6pgG{PrRc3} zK6kZ$sb|&9>%vB<3cu}9<{T`~Qq{5oehrpkFY`~Lg-}4D9Yd|xzv$O6>=mwiAmmr> zuAxD}(5uce()F(L40KM(&nw8ufIg1TzYAie&hbvKyt=b0Qv5IU)L{GLsgidSP~<>t z=ze%z{#}u`ByX@h%~#b{vOudadD(UNP>V_zoJrUzc;VJyK+D`}541u(lZ%j2wWnq{ zS@+4D;jAz(XGDf0YiLGxQATz~!0RufKd8t(bz*>B1a0=9#0~JeK#9LK1HAmrX;nbD6=>QVx*pHgewkH=`GC2@Lw{3fq|Xg_F}Qm*V8%3KiJa^0VW1{EM`(F1hYNN z*H^&=X#4;F(oAcB?xGC<`rFq%NYBN`hg#+Xg9#3d7#NXU4q~!0NHQ=poM3pt%*4RO z0F#t~>fm7DVF*br%FWD6%z+z%#_%ak&P+*EaL&&w&d*6jlLT{_fn)&Co(3iz#vZ10 cMlm2CnCPHj7Q-wCHD*R+XJRviY%xX#0Ku|J8vp