diff --git a/examples/board_olimex_avr_mt128/Makefile b/examples/board_olimex_avr_mt128/Makefile new file mode 100644 index 000000000..caa6eb8a6 --- /dev/null +++ b/examples/board_olimex_avr_mt128/Makefile @@ -0,0 +1,53 @@ +# +# Copyright 2008-2011 Michel Pollet +# +# This file is part of simavr. +# +# simavr is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# simavr is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with simavr. If not, see . + +target = mt128 +firmware_srcs = ${wildcard at*.c} + +simavr = ../../ + +IPATH = . +IPATH += ../parts +IPATH += ${simavr}/include +IPATH += ${simavr}/simavr/sim + +VPATH = . +VPATH += ../parts + +LDFLAGS += -lpthread + +include ../Makefile.opengl + +all: obj axf ${target} + +axf: ${firmware_srcs:.c=.axf} + +include ${simavr}/Makefile.common + +board = ${OBJ}/${target}.elf + +${board} : ${OBJ}/button.o +${board} : ${OBJ}/hd44780.o +${board} : ${OBJ}/hd44780_glut.o +${board} : ${OBJ}/${target}.o + +${target}: ${board} + @echo $@ done + +clean: clean-${OBJ} + rm -rf *.hex *.a *.axf *.vcd .*.swo .*.swp .*.swm .*.swn diff --git a/examples/board_olimex_avr_mt128/README b/examples/board_olimex_avr_mt128/README new file mode 100644 index 000000000..e4e5f4657 --- /dev/null +++ b/examples/board_olimex_avr_mt128/README @@ -0,0 +1,8 @@ +board_olimex_avr_mt128 + +(C) 2020 Akos Kiss + +Experimental Olimex AVR-MT128 development board simulation. +Based on works of and sample code from +- Michel Pollet and +- Luki . diff --git a/examples/board_olimex_avr_mt128/atmega128_display.c b/examples/board_olimex_avr_mt128/atmega128_display.c new file mode 100644 index 000000000..b84969731 --- /dev/null +++ b/examples/board_olimex_avr_mt128/atmega128_display.c @@ -0,0 +1,292 @@ +// NOTE: lines below added to allow compilation in simavr's build system +#undef F_CPU +#define F_CPU 16000000 +#include "avr_mcu_section.h" +AVR_MCU(F_CPU, "atmega128"); + +/* Sample program for Olimex AVR-MT-128 with ATMega-128 processor + * Button 1 (Up) - Turn ON the display + * Button 2 (Left) - Set Text1 on the upline + * Button 3 (Middle) - Hold to slide Text + * Button 4 (Right) - Set Text2 on the downline + * Button 5 (Down) - Turn OFF the display + * Compile with AVRStudio+WinAVR (gcc version 3.4.6) + */ + + #define Text1 "Conflux" + #define Text2 "Rampard" + + + +#include "avr/io.h" +#include "avr_lcd.h" // NOTE: changed header name to better fit in simavr's file naming conventions + +#define __AVR_ATMEGA128__ 1 + +unsigned char data, Line = 0; +char Text[16], Ch; +unsigned int Bl = 1, LCD_State = 0, i, j; + +void Delay(unsigned int b) +{ + volatile unsigned int a = b; // NOTE: volatile added to prevent the compiler to optimization the loop away + while (a) + { + a--; + } +} + +/*****************************L C D**************************/ + +void E_Pulse() +{ + PORTC = PORTC | 0b00000100; //set E to high + Delay(1400); //delay ~110ms + PORTC = PORTC & 0b11111011; //set E to low +} + +void LCD_Init() +{ + //LCD initialization + //step by step (from Gosho) - from DATASHEET + + PORTC = PORTC & 0b11111110; + + Delay(10000); + + + PORTC = 0b00110000; //set D4, D5 port to 1 + E_Pulse(); //high->low to E port (pulse) + Delay(1000); + + PORTC = 0b00110000; //set D4, D5 port to 1 + E_Pulse(); //high->low to E port (pulse) + Delay(1000); + + PORTC = 0b00110000; //set D4, D5 port to 1 + E_Pulse(); //high->low to E port (pulse) + Delay(1000); + + PORTC = 0b00100000; //set D4 to 0, D5 port to 1 + E_Pulse(); //high->low to E port (pulse) +} + +void LCDSendCommand(unsigned char a) +{ + data = 0b00001111 | a; //get high 4 bits + PORTC = (PORTC | 0b11110000) & data; //set D4-D7 + PORTC = PORTC & 0b11111110; //set RS port to 0 + E_Pulse(); //pulse to set D4-D7 bits + + data = a<<4; //get low 4 bits + PORTC = (PORTC & 0b00001111) | data; //set D4-D7 + PORTC = PORTC & 0b11111110; //set RS port to 0 -> display set to command mode + E_Pulse(); //pulse to set d4-d7 bits + +} + +void LCDSendChar(unsigned char a) +{ + data = 0b00001111 | a; //get high 4 bits + PORTC = (PORTC | 0b11110000) & data; //set D4-D7 + PORTC = PORTC | 0b00000001; //set RS port to 1 + E_Pulse(); //pulse to set D4-D7 bits + + data = a<<4; //get low 4 bits + PORTC = (PORTC & 0b00001111) | data; //clear D4-D7 + PORTC = PORTC | 0b00000001; //set RS port to 1 -> display set to command mode + E_Pulse(); //pulse to set d4-d7 bits +} + +void LCDSendTxt(char* a) +{ + int Temp; + for(Temp=0; Temp0; Temp--) LCDSendChar(C[Temp] + 48); +} + +void LCDSendInt_Old(int a) +{ + int h = 0; + int l = 0; + + l = a%10; + h = a/10; + + LCDSendChar(h+48); + LCDSendChar(l+48); +} + +void SmartUp(void) +{ + int Temp; + for(Temp=0; Temp<1; Temp++) LCDSendCommand(CUR_UP); +} + +void SmartDown(void) +{ + int Temp; + for(Temp=0; Temp<40; Temp++) LCDSendCommand(CUR_DOWN); +} + +void Light(short a) +{ + if(a == 1) + { + PORTC = PORTC | 0b00100000; + DDRC = PORTC | 0b00100000; + + //IO0SET_bit.P0_25 = 1; + //IO0DIR_bit.P0_25 = 1; + } + if(a == 0) + { + PORTC = PORTC & 0b11011111; + DDRC = DDRC & 0b11011111; + + //IO0SET_bit.P0_25 = 0; + //IO0DIR_bit.P0_25 = 0; + } + +} + +/*****************************L C D**************************/ + +void Port_Init() +{ + PORTA = 0b00011111; DDRA = 0b01000000; // NOTE: set A4-0 to initialize buttons to unpressed state + PORTB = 0b00000000; DDRB = 0b00000000; + PORTC = 0b00000000; DDRC = 0b11110111; + PORTD = 0b11000000; DDRD = 0b00001000; + PORTE = 0b00000000; DDRE = 0b00110000; + PORTF = 0b00000000; DDRF = 0b00000000; + PORTG = 0b00000000; DDRG = 0b00000000; +} + +int main() +{ + Port_Init(); + LCD_Init(); + // NOTE: added missing initialization steps + LCDSendCommand(0x28); // function set: 4 bits interface, 2 display lines, 5x8 font + LCDSendCommand(DISP_OFF); // display off, cursor off, blinking off + LCDSendCommand(CLR_DISP); // clear display + LCDSendCommand(0x06); // entry mode set: cursor increments, display does not shift + + LCDSendCommand(DISP_OFF); + while (1) + { + //Value of Bl prevents holding the buttons + //Bl = 0: One of the Buttons is pressed, release to press again + //LCD_State value is the state of LCD: 1 - LCD is ON; 0 - LCD is OFF + + //Up Button (Button 1) : Turn ON Display + if (!(PINA & 0b00000001) & Bl & !(LCD_State)) //check state of button 1 and value of Bl and LCD_State + { + LCDSendCommand(DISP_ON); //Turn ON Display + LCDSendCommand(CLR_DISP); //Clear Display + LCDSendTxt(" Welcome "); //Print welcome screen + Bl = 0; //Button is pressed + LCD_State = 1; //Display is ON (LCD_State = 1) + } + + //Left Button (Button 2) : Set Text1 + if (!(PINA & 0b00000010) & Bl & LCD_State) //check state of button 2 and value of Bl and LCD_State + { + LCDSendCommand(CLR_DISP); //Clear Display + LCDSendCommand(DD_RAM_ADDR); //set to Line 1 + for (i=0; i<16; i++) Text[i] = 0; //Clear Text + strcpy(Text, Text1); //set Text + for (i=0; i<16; i++) + if (Text[i] == 0) Text[i] = ' ';//fill the Text with space + //LCDSendTxt(Text); //Print the text + for (i=0; i<16; i++) LCDSendChar(Text[i]); + Bl = 0; //Button is pressed + Line = 1; //text must be print on up line + } + + //Middle Button (Button 3) : Slide the text + if (!(PINA & 0b00000100) & Bl & LCD_State) + { + while (!(PINA & 0b00000100) & (Line != 0)) + //check state of button 3 and value of Line (Line = 0 - no text selected) + { + //sliding the text + for(i=60000; i; i--); + Ch = Text[0]; + for (i=0; i<15; i++) Text[i] = Text[i+1]; + Text[15] = Ch; + + //print the text in the correct line + if (Line == 1) + LCDSendCommand(DD_RAM_ADDR); + else + LCDSendCommand(DD_RAM_ADDR2); + //LCDSendTxt(Text); + for (i=0; i<16; i++) LCDSendChar(Text[i]); + } + } + + //Right Button (Button 4) Set Text2 + if (!(PINA & 0b00001000) & Bl & LCD_State) //check state of button 4 and value of Bl and LCD_State + { + LCDSendCommand(CLR_DISP); //Clear Display + LCDSendCommand(DD_RAM_ADDR2); //set to Line 2 + for (i=0; i<16; i++) Text[i] = 0; //Clear Text + strcpy(Text, Text2); //set Text + for (i=0; i<16; i++) + if (Text[i] == 0) Text[i] = ' ';//fill the Text with space + //LCDSendTxt(Text); //Print the text + for (i=0; i<16; i++) LCDSendChar(Text[i]); + Bl = 0; //Button is pressed + Line = 2; //text must be print on down line + } + + //Down Button (Button 5) Turn OFF Display + if (!(PINA & 0b00010000) & Bl & LCD_State) //check state of button 5 and value of Bl and LCD_State + { + LCDSendCommand(CLR_DISP); //Clear Display + LCDSendTxt(" Turn OFF "); //Print Turn OFF message + for (i=30; i; i--) + for (j=30000; j; j--); //simple delay + Bl = 0; //Button is pressed + LCDSendCommand(DISP_OFF); //Display is OFF ==> LCD_State = 0, Line = 0 + LCD_State = 0; + Line = 0; + } + + //check state of all buttons + if ( + ((PINA & 0b00000001) + |(PINA & 0b00000010) + |(PINA & 0b00000100) + |(PINA & 0b00001000) + |(PINA & 0b00010000)) == 31) + Bl = 1; //if all buttons are released Bl gets value 1 + + + } + return 0; +} diff --git a/examples/board_olimex_avr_mt128/atmega128_minitris.c b/examples/board_olimex_avr_mt128/atmega128_minitris.c new file mode 100644 index 000000000..2255f3801 --- /dev/null +++ b/examples/board_olimex_avr_mt128/atmega128_minitris.c @@ -0,0 +1,489 @@ +/** + * MiniTris -- Mini Tetris game + * by Akos Kiss + */ + +#undef F_CPU +#define F_CPU 16000000 +#include "avr_mcu_section.h" +AVR_MCU(F_CPU, "atmega128"); + +#define __AVR_ATmega128__ 1 +#include + + +// GENERAL INIT - USED BY ALMOST EVERYTHING ---------------------------------- + +static void port_init() { + PORTA = 0b00011111; DDRA = 0b01000000; // buttons & led + PORTB = 0b00000000; DDRB = 0b00000000; + PORTC = 0b00000000; DDRC = 0b11110111; // lcd + PORTD = 0b11000000; DDRD = 0b00001000; + PORTE = 0b00100000; DDRE = 0b00110000; // buzzer + PORTF = 0b00000000; DDRF = 0b00000000; + PORTG = 0b00000000; DDRG = 0b00000000; +} + +// TIMER-BASED RANDOM NUMBER GENERATOR --------------------------------------- + +static void rnd_init() { + TCCR0 |= (1 << CS00); // Timer 0 no prescaling (@FCPU) + TCNT0 = 0; // init counter +} + +// generate a value between 0 and max +static int rnd_gen(int max) { + return TCNT0 % max; +} + +// SOUND GENERATOR ----------------------------------------------------------- + +typedef struct { + int freq; + int length; +} tune_t; + +static tune_t TUNE_START[] = { { 2000, 40 }, { 0, 0 } }; +static tune_t TUNE_LEVELUP[] = { { 3000, 20 }, { 0, 0 } }; +static tune_t TUNE_GAMEOVER[] = { { 1000, 200 }, { 1500, 200 }, { 2000, 400 }, { 0, 0 } }; + +static void play_note(int freq, int len) { + for (int l = 0; l < len; ++l) { + int i; + PORTE = (PORTE & 0b11011111) | 0b00010000; //set bit4 = 1; set bit5 = 0 + for (i=freq; i; i--); + PORTE = (PORTE | 0b00100000) & 0b11101111; //set bit4 = 0; set bit5 = 1 + for (i=freq; i; i--); + } +} + +static void play_tune(tune_t *tune) { + while (tune->freq != 0) { + play_note(tune->freq, tune->length); + ++tune; + } +} + +// BUTTON HANDLING ----------------------------------------------------------- + +#define BUTTON_NONE 0 +#define BUTTON_CENTER 1 +#define BUTTON_LEFT 2 +#define BUTTON_RIGHT 3 +#define BUTTON_UP 4 +static int button_accept = 1; + +static int button_pressed() { + // right + if (!(PINA & 0b00000001) & button_accept) { // check state of button 1 and value of button_accept + button_accept = 0; // button is pressed + return BUTTON_RIGHT; + } + + // up + if (!(PINA & 0b00000010) & button_accept) { // check state of button 2 and value of button_accept + button_accept = 0; // button is pressed + return BUTTON_UP; + } + + // center + if (!(PINA & 0b00000100) & button_accept) { // check state of button 3 and value of button_accept + button_accept = 0; // button is pressed + return BUTTON_CENTER; + } + + // left + if (!(PINA & 0b00010000) & button_accept) { // check state of button 5 and value of button_accept + button_accept = 0; // button is pressed + return BUTTON_LEFT; + } + + return BUTTON_NONE; +} + +static void button_unlock() { + //check state of all buttons + if ( + ((PINA & 0b00000001) + |(PINA & 0b00000010) + |(PINA & 0b00000100) + |(PINA & 0b00001000) + |(PINA & 0b00010000)) == 31) + button_accept = 1; //if all buttons are released button_accept gets value 1 +} + +// LCD HELPERS --------------------------------------------------------------- + +#define CLR_DISP 0x00000001 +#define DISP_ON 0x0000000C +#define DISP_OFF 0x00000008 +#define CUR_HOME 0x00000002 +#define CUR_OFF 0x0000000C +#define CUR_ON_UNDER 0x0000000E +#define CUR_ON_BLINK 0x0000000F +#define CUR_LEFT 0x00000010 +#define CUR_RIGHT 0x00000014 +#define CG_RAM_ADDR 0x00000040 +#define DD_RAM_ADDR 0x00000080 +#define DD_RAM_ADDR2 0x000000C0 + +//#define ENTRY_INC 0x00000007 //LCD increment +//#define ENTRY_DEC 0x00000005 //LCD decrement +//#define SH_LCD_LEFT 0x00000010 //LCD shift left +//#define SH_LCD_RIGHT 0x00000014 //LCD shift right +//#define MV_LCD_LEFT 0x00000018 //LCD move left +//#define MV_LCD_RIGHT 0x0000001C //LCD move right + +static void lcd_delay(unsigned int b) { + volatile unsigned int a = b; + while (a) + a--; +} + +static void lcd_pulse() { + PORTC = PORTC | 0b00000100; //set E to high + lcd_delay(1400); //delay ~110ms + PORTC = PORTC & 0b11111011; //set E to low +} + +static void lcd_send(int command, unsigned char a) { + unsigned char data; + + data = 0b00001111 | a; //get high 4 bits + PORTC = (PORTC | 0b11110000) & data; //set D4-D7 + if (command) + PORTC = PORTC & 0b11111110; //set RS port to 0 -> display set to command mode + else + PORTC = PORTC | 0b00000001; //set RS port to 1 -> display set to data mode + lcd_pulse(); //pulse to set D4-D7 bits + + data = a<<4; //get low 4 bits + PORTC = (PORTC & 0b00001111) | data; //set D4-D7 + if (command) + PORTC = PORTC & 0b11111110; //set RS port to 0 -> display set to command mode + else + PORTC = PORTC | 0b00000001; //set RS port to 1 -> display set to data mode + lcd_pulse(); //pulse to set d4-d7 bits +} + +static void lcd_send_command(unsigned char a) { + lcd_send(1, a); +} + +static void lcd_send_data(unsigned char a) { + lcd_send(0, a); +} + +static void lcd_init() { + //LCD initialization + //step by step (from Gosho) - from DATASHEET + + PORTC = PORTC & 0b11111110; + + lcd_delay(10000); + + PORTC = 0b00110000; //set D4, D5 port to 1 + lcd_pulse(); //high->low to E port (pulse) + lcd_delay(1000); + + PORTC = 0b00110000; //set D4, D5 port to 1 + lcd_pulse(); //high->low to E port (pulse) + lcd_delay(1000); + + PORTC = 0b00110000; //set D4, D5 port to 1 + lcd_pulse(); //high->low to E port (pulse) + lcd_delay(1000); + + PORTC = 0b00100000; //set D4 to 0, D5 port to 1 + lcd_pulse(); //high->low to E port (pulse) + + lcd_send_command(0x28); // function set: 4 bits interface, 2 display lines, 5x8 font + lcd_send_command(DISP_OFF); // display off, cursor off, blinking off + lcd_send_command(CLR_DISP); // clear display + lcd_send_command(0x06); // entry mode set: cursor increments, display does not shift + + lcd_send_command(DISP_ON); // Turn ON Display + lcd_send_command(CLR_DISP); // Clear Display +} + +static void lcd_send_text(char *str) { + while (*str) + lcd_send_data(*str++); +} + +static void lcd_send_line1(char *str) { + lcd_send_command(DD_RAM_ADDR); + lcd_send_text(str); +} + +static void lcd_send_line2(char *str) { + lcd_send_command(DD_RAM_ADDR2); + lcd_send_text(str); +} + +// SPEED LEVELS -------------------------------------------------------------- + +typedef struct { + int delay; + int rows; +} level_t; + +#define LEVEL_NUM 6 +static level_t LEVELS[] = { { 5, 5 }, { 4, 10 }, { 3, 15 }, { 2, 20 }, { 1, 30 }, { 0, 0 } }; +static int level_current = 0; +static int delay_cycle; + +static void row_removed() { + // do nothing if already at top speed + if (level_current == LEVEL_NUM-1) + return; + + // if enough rows removed, increase speed + if (--LEVELS[level_current].rows == 0) { + ++level_current; + play_tune(TUNE_LEVELUP); + } +} + +// PATTERNS AND PLAYFIELD ---------------------------------------------------- +/* Vertical axis: 0 is top row, increments downwards + * Horizontal axis: 0 is right column, increments leftwards */ + +#define PATTERN_NUM 4 +#define PATTERN_SIZE 2 +static unsigned char PATTERNS[PATTERN_NUM][PATTERN_SIZE] = { { 0b01, 0b00 }, { 0b01, 0b01 }, { 0b01, 0b11 }, { 0b11, 0b11 } }; + +static unsigned char current_pattern[PATTERN_SIZE]; +static int current_row; +static int current_col; + +// Actually, 1 row taller and 2 columns wider, which extras are filled with ones to help collision detection +#define PLAYFIELD_ROWS 16 +#define PLAYFIELD_COLS 4 +static unsigned char playfield[PLAYFIELD_ROWS + 1]; + +static void playfield_clear() { + for (int r = 0; r < PLAYFIELD_ROWS; ++r) + playfield[r] = 0b100001; + playfield[PLAYFIELD_ROWS] = 0b111111; +} + +static void merge_current_pattern_to_playfield() { + // merge current piece to playfield + for (int p = 0; p < PATTERN_SIZE; ++p) + playfield[current_row + p] |= current_pattern[p] << (current_col + 1); + // remove full lines and drop lines above + for (int r = 0; r < PLAYFIELD_ROWS; ++r) { + if (playfield[r] == 0b111111) { + for (int rr = r; rr > 0; --rr) + playfield[rr] = playfield[rr - 1]; + playfield[0] = 0b100001; + row_removed(); // let's see whether we should increase the speed + } + } +} + +static int collision(char *pattern, int row, int col) { + int result = 0; + for (int r = 0; r < PATTERN_SIZE; ++r) + result |= playfield[row + r] & (pattern[r] << (col + 1)); + return !!result; +} + +static void rotate_pattern(char *src_pattern, char *dst_pattern) { + // rotate the piece + dst_pattern[0] = (src_pattern[0] >> 1) | ((src_pattern[1] >> 1) << 1); + dst_pattern[1] = (src_pattern[0] & 0x01) | ((src_pattern[1] & 0x01) << 1); + // if the topmost row of the rotated piece is empty, shift the pattern upwards + if (dst_pattern[0] == 0) { + dst_pattern[0] = dst_pattern[1]; + dst_pattern[1] = 0; + } + // if the rightmost column of the rotated piece is empty, shift the pattern to the right + if (((dst_pattern[0] & 0b01) == 0) && ((dst_pattern[1] & 0b01) == 0)) { + dst_pattern[0] >>= 1; + dst_pattern[1] >>= 1; + } +} + +// GRAPHICS ------------------------------------------------------------------ + +#define CHAR_EMPTY_PATTERN 0 +#define CHAR_EMPTY_PLAYGROUND 1 +#define CHAR_PATTERN_EMPTY 2 +#define CHAR_PATTERN_PATTERN 3 +#define CHAR_PATTERN_PLAYGROUND 4 +#define CHAR_PLAYGROUND_EMPTY 5 +#define CHAR_PLAYGROUND_PATTERN 6 +#define CHAR_PLAYGROUND_PLAYGROUND 7 +#define CHAR_EMPTY_EMPTY ' ' +#define CHAR_ERROR 'X' + +#define CHARMAP_SIZE 8 +static unsigned char CHARMAP[CHARMAP_SIZE][8] = { + { 0b10101, 0b01010, 0b10101, 0b01010, 0, 0, 0, 0 }, // CHAR_EMPTY_PATTERN + { 0b11111, 0b11111, 0b11111, 0b11111, 0, 0, 0, 0 }, // CHAR_EMPTY_PLAYGROUND + { 0, 0, 0, 0, 0b10101, 0b01010, 0b10101, 0b01010 }, // CHAR_PATTERN_EMPTY + { 0b10101, 0b01010, 0b10101, 0b01010, 0b10101, 0b01010, 0b10101, 0b01010 }, // CHAR_PATTERN_PATTERN + { 0b11111, 0b11111, 0b11111, 0b11111, 0b10101, 0b01010, 0b10101, 0b01010 }, // CHAR_PATTERN_PLAYGROUND + { 0, 0, 0, 0, 0b11111, 0b11111, 0b11111, 0b11111 }, // CHAR_PLAYGROUND_EMPTY + { 0b10101, 0b01010, 0b10101, 0b01010, 0b11111, 0b11111, 0b11111, 0b11111 }, // CHAR_PLAYGROUND_PATTERN + { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 } // CHAR_PLAYGROUND_PLAYGROUND +}; + +static const unsigned char XLAT_PATTERN[] = { 0b0000, 0b0001, 0b0100, 0b0101 }; +static const unsigned char XLAT_PLAYGROUND[] = { 0b0000, 0b0010, 0b1000, 0b1010 }; +static const char XLAT_CHAR[] = { + CHAR_EMPTY_EMPTY, // 0b0000 + CHAR_EMPTY_PATTERN, // 0b0001 + CHAR_EMPTY_PLAYGROUND, // 0b0010 + CHAR_ERROR, // 0b0011 + CHAR_PATTERN_EMPTY, // 0b0100 + CHAR_PATTERN_PATTERN, // 0b0101 + CHAR_PATTERN_PLAYGROUND, // 0b0110 + CHAR_ERROR, // 0b0111 + CHAR_PLAYGROUND_EMPTY, // 0b1000 + CHAR_PLAYGROUND_PATTERN, // 0b1001 + CHAR_PLAYGROUND_PLAYGROUND, // 0b1010 + CHAR_ERROR, // 0b1011 + CHAR_ERROR, // 0b1100 + CHAR_ERROR, // 0b1101 + CHAR_ERROR, // 0b1110 + CHAR_ERROR // 0b1111 +}; + +static void chars_init() { + for (int c = 0; c < CHARMAP_SIZE; ++c) { + lcd_send_command(CG_RAM_ADDR + c*8); + for (int r = 0; r < 8; ++r) + lcd_send_data(CHARMAP[c][r]); + } +} + +static void screen_update() { + lcd_send_command(DD_RAM_ADDR); //set to Line 1 + + for (int r1 = 0; r1 < PLAYFIELD_ROWS; ++r1) { + unsigned char row = XLAT_PLAYGROUND[(playfield[r1] >> 1) & 0b11]; + for (int pr = 0; pr < PATTERN_SIZE; ++pr) + if (r1 == current_row + pr) + row |= XLAT_PATTERN[(current_pattern[pr] << current_col) & 0b11]; + lcd_send_data(XLAT_CHAR[row]); + } + + lcd_send_command(DD_RAM_ADDR2); //set to Line 2 + + for (int r2 = 0; r2 < PLAYFIELD_ROWS; ++r2) { + char row = XLAT_PLAYGROUND[(playfield[r2] >> 3) & 0b11]; + for (int pr = 0; pr < PATTERN_SIZE; ++pr) + if (r2 == current_row + pr) + row |= XLAT_PATTERN[((current_pattern[pr] << current_col) >> 2) & 0b11]; + lcd_send_data(XLAT_CHAR[row]); + } +} + +// THE GAME ================================================================== + +int main() { + port_init(); + lcd_init(); + chars_init(); + rnd_init(); + + // "Splash screen" + lcd_send_line1(" MiniTris"); + lcd_send_line2(" by Akiss"); + + // loop of the whole program, always restarts game + while (1) { + int new_pattern; + + while (button_pressed() != BUTTON_CENTER) // wait till start signal + button_unlock(); // keep on clearing button_accept + + playfield_clear(); // set up new playfield + delay_cycle = 0; // start the timer + new_pattern = 1; // start with new pattern + play_tune(TUNE_START); // play a start signal + + // loop of the game + while (1) { + // start one new piece at the top + if (new_pattern) { + new_pattern = 0; + + // select a new random pattern + int p = rnd_gen(PATTERN_NUM); + for (int i = 0; i < PATTERN_SIZE; ++i) + current_pattern[i] = PATTERNS[p][i]; + + // rotate it randomly + int r = rnd_gen(4); + for (int j = 0; j < r; ++j) { + char tmp_pattern[PATTERN_SIZE]; + rotate_pattern(current_pattern, tmp_pattern); + for (int k = 0; k < PATTERN_SIZE; ++k) + current_pattern[k] = tmp_pattern[k]; + } + + // place it randomly at the top of the playfield + current_row = 0; + current_col = rnd_gen(PLAYFIELD_COLS - PATTERN_SIZE + 1); + + // show the new piece on the screen + screen_update(); + } + + // game over, if the new piece does not fit in the top row + if ((current_row == 0) && collision(current_pattern, current_row, current_col)) + break; + + // if enough time passed, try to drop the current piece by one row + if (++delay_cycle > LEVELS[level_current].delay) { + delay_cycle = 0; + // will not succeed at the last line, or if playfield below has conflicting elements + if (collision(current_pattern, current_row + 1, current_col)) { + // merge the current piece to the playfield then, and start with a new piece + merge_current_pattern_to_playfield(); + new_pattern = 1; + continue; + } + // otherwise, drop the piece by one row + ++current_row; + } + + // if trying to move left or right, do so only if the piece does not leave or collide with the playfield + int button = button_pressed(); + int horizontal = 0; + if (button == BUTTON_LEFT) + horizontal = +1; + if (button == BUTTON_RIGHT) + horizontal = -1; + if ((horizontal != 0) && !collision(current_pattern, current_row, current_col + horizontal)) + current_col += horizontal; + + // if trying to rotate right, do only so if the piece does not collide with the playfield + if (button == BUTTON_UP) { + char tmp_pattern[PATTERN_SIZE]; + // rotate the current piece into a temp + rotate_pattern(current_pattern, tmp_pattern); + // check for collision, and make the rotation permanent if there is none + if (!collision(tmp_pattern, current_row, current_col)) + for (int i = 0; i < PATTERN_SIZE; ++i) + current_pattern[i] = tmp_pattern[i]; + } + + // once all movements are done, update the screen + screen_update(); + + // try to unlock the buttons (technicality but must be done) + button_unlock(); + } // end of game-loop + + // playing some funeral tunes and displaying a game over screen + play_tune(TUNE_GAMEOVER); + lcd_send_line1(" GAME OVER "); + lcd_send_line2("Click to restart"); + + } // end of program-loop, we never quit +} diff --git a/examples/board_olimex_avr_mt128/avr_lcd.h b/examples/board_olimex_avr_mt128/avr_lcd.h new file mode 100644 index 000000000..8131fca45 --- /dev/null +++ b/examples/board_olimex_avr_mt128/avr_lcd.h @@ -0,0 +1,41 @@ +//lcd.h +#include + +//#define DISP_ON 0x0000000C //LCD on +//#define DISP_OFF 0x00000008 //LCD off +//#define CLR_DISP 0x00000001 //LCD clear +//#define CUR_HOME 0x00000002 //LCD cursor home +//#define ENTRY_INC 0x00000007 //LCD increment +//#define ENTRY_DEC 0x00000005 //LCD decrement +//#define DD_RAM_ADDR 0x00000080 //LCD 1 row +//#define DD_RAM_ADDR2 0x000000C0 //LCD 2 row +//#define SH_LCD_LEFT 0x00000010 //LCD shift left +//#define SH_LCD_RIGHT 0x00000014 //LCD shift right +//#define MV_LCD_LEFT 0x00000018 //LCD move left +//#define MV_LCD_RIGHT 0x0000001C //LCD move right + +#define CLR_DISP 0x00000001 +#define DISP_ON 0x0000000C +#define DISP_OFF 0x00000008 +#define CUR_HOME 0x00000002 +#define CUR_OFF 0x0000000C +#define CUR_ON_UNDER 0x0000000E +#define CUR_ON_BLINK 0x0000000F +#define CUR_LEFT 0x00000010 +#define CUR_RIGHT 0x00000014 +#define CUR_UP 0x00000080 +#define CUR_DOWN 0x000000C0 +#define ENTER 0x000000C0 +#define DD_RAM_ADDR 0x00000080 +#define DD_RAM_ADDR2 0x000000C0 + + +void E_Pulse(); +void LCDInit(); +void LCDSendCommand(unsigned char a); +void LCDSendChar(unsigned char a); +void LCDSendTxt(char* a); +void SmartUp(void); +void SmartDown(void); +void Light(short a); +void LCDSendInt(long a); diff --git a/examples/board_olimex_avr_mt128/mt128.c b/examples/board_olimex_avr_mt128/mt128.c new file mode 100644 index 000000000..c3a661f01 --- /dev/null +++ b/examples/board_olimex_avr_mt128/mt128.c @@ -0,0 +1,386 @@ +/* + m128.c + + Copyright Luki + Copyright 2011 Michel Pollet + Copyright 2020 Akos Kiss + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see . + */ + +#include +#include +#include +#include + +#include "sim_avr.h" +#include "avr_ioport.h" +#include "sim_elf.h" +#include "sim_gdb.h" + +#if __APPLE__ +#include +#else +#include +#endif +#include + +#include "button.h" +#include "hd44780.h" +#include "hd44780_glut.h" + + +/* Command line argument globals */ + +static const char * arg0; +static struct { + int verbose; + int debug; + char *firmware; +} args = { + .verbose = 1, + .debug = 0, + .firmware = NULL, +}; + +/* Simulated component globals */ + +typedef struct { // UI key state + int count; // state change counter (~timestamp of last change) + uint8_t state; // key state (0: pressed, 1: released) +} key_state_t; + +static struct { + button_t button; // simulated button + char key; // ASCII code of associated UI key + volatile key_state_t ui_key_state; // current UI key state + key_state_t avr_key_state; // last UI key state change translated to AVR button press/release + const char * name; // symbolic name +} button[5] = { + { .key='8', .ui_key_state = { .count = 0, .state = 1 }, .avr_key_state = { .count = 0, .state = 1 }, .name = "B1" }, + { .key='4', .ui_key_state = { .count = 0, .state = 1 }, .avr_key_state = { .count = 0, .state = 1 }, .name = "B2" }, + { .key='5', .ui_key_state = { .count = 0, .state = 1 }, .avr_key_state = { .count = 0, .state = 1 }, .name = "B3" }, + { .key='6', .ui_key_state = { .count = 0, .state = 1 }, .avr_key_state = { .count = 0, .state = 1 }, .name = "B4" }, + { .key='2', .ui_key_state = { .count = 0, .state = 1 }, .avr_key_state = { .count = 0, .state = 1 }, .name = "B5" }, +}; +static hd44780_t hd44780; // simulated LCD controller +static avr_t * avr = NULL; // simulated AVR MCU + + +/* Command line processing */ + +/** + * Print single line of usage information. + * Expects arg0 to be already initialized. + */ +static void print_usage() +{ + printf("usage: %s [-h] [-v] [-g] [GLUT options...] FILE\n", arg0); // NOTE: keep in sync with getopt's optstring +} + +/** + * Print detailed help on usage and command line arguments. + * Expects arg0 to be already initialized. + */ +static void print_help() +{ + print_usage(); + printf( // NOTE: keep in sync with getopt's optstring + "\n" + "positional arguments:\n" + " FILE firmware to load\n" + "\n" + "optional arguments:\n" + " -h show this help message and exit\n" + " -v increase verbosity level (can be passed more than once)\n" + " -g listen for gdb connection on port 1234\n" + "\n" + "GLUT options:\n" + " windows system dependent\n" + ); +} + +/** + * Extract and process GLUT-specific command line arguments. + * It also initializes the GLUT library. + * Must be called before any other command line processing as it changes + * argc/argv. + */ +static void process_ui_args(int * pargc, char *argv[]) +{ + glutInit(pargc, argv); /* initialize GLUT system */ +} + +/** + * Process command line arguments. + * Initializes arg0 and args. + */ +static void process_args(int argc, char *argv[]) +{ + arg0 = argv[0]; + + int opt; + while ((opt = getopt(argc, argv, "hvg")) != -1) { + switch (opt) { + case 'h': + print_help(); + exit(EXIT_SUCCESS); + case 'v': + args.verbose++; + break; + case 'g': + args.debug++; + break; + default: + print_usage(); + exit(EXIT_FAILURE); + } + } + + if (optind != argc - 1) { + print_usage(); + exit(EXIT_FAILURE); + } + args.firmware = argv[optind]; +} + + +/* Setup of AVR (firmware, MCU, peripherals, connections) */ + +/** + * Initialize the MCU and load the firmware. + * Configure debug functionality (log level, debugger connection). + */ +static void setup_avr() +{ + elf_firmware_t f; + elf_read_firmware(args.firmware, &f); + printf("firmware %s f=%d mmcu=%s\n", args.firmware, (int) f.frequency, f.mmcu); + + avr = avr_make_mcu_by_name(f.mmcu); + if (!avr) { + fprintf(stderr, "%s: AVR '%s' not known\n", arg0, f.mmcu); + exit(EXIT_FAILURE); + } + + avr_init(avr); + avr_load_firmware(avr, &f); + + avr->log = args.verbose; + + avr->gdb_port = 1234; // even if not setup at startup, activate gdb if crashing + if (args.debug) { + avr->state = cpu_Stopped; + avr_gdb_init(avr); + } +} + +/** + * Initialize peripherals and connect them to the MCU. + */ +static void setup_board() +{ + for (int i = 0; i < 5; i++) { + // initialize our peripheral + button_init(avr, &button[i].button, button[i].name); + // "connect" the output irq of the button to the port pin of the AVR + avr_connect_irq(button[i].button.irq + IRQ_BUTTON_OUT, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('A'), i)); + } + + hd44780_init(avr, &hd44780, 16, 2); + /* Connect Data Lines to Port C, 4-7 */ + /* These are bidirectional too */ + for (int i = 0; i < 4; i++) { + avr_irq_t * iavr = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 4 + i); + avr_irq_t * ilcd = hd44780.irq + IRQ_HD44780_D4 + i; + // AVR -> LCD + avr_connect_irq(iavr, ilcd); + // LCD -> AVR + avr_connect_irq(ilcd, iavr); + } + avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 0), hd44780.irq + IRQ_HD44780_RS); + avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 1), hd44780.irq + IRQ_HD44780_RW); + avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 2), hd44780.irq + IRQ_HD44780_E); +} + + +/* Setup of UI */ + +/** + * Draw window contents. + */ +static void ui_display_cb(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); // Select modelview matrix + glPushMatrix(); + glLoadIdentity(); // Start with an identity matrix + glScalef(3, 3, 1); + + hd44780_gl_draw(&hd44780, 0x00aa00ff, 0x00cc00ff, 0x000000ff, 0x00000055); // fluo green + + glPopMatrix(); + glutSwapBuffers(); +} + +/** + * Trigger window redraw periodically. + */ +static void ui_display_timer_cb(int i) +{ + glutTimerFunc(1000 / 64, ui_display_timer_cb, 0); // restart timer + glutPostRedisplay(); +} + +/** + * Handle key presses in window. + */ +static void ui_key_press_cb(unsigned char key, int x, int y) +{ + if (key == 'q') { + exit(EXIT_SUCCESS); + } + + for (int i = 0; i < 5; i++) { + if (key == button[i].key) { + button[i].ui_key_state.count++; + button[i].ui_key_state.state = 0; + break; + } + } +} + +/** + * Handle key releases in window. + */ +static void ui_key_release_cb(unsigned char key, int x, int y) +{ + for (int i = 0; i < 5; i++) { + if (key == button[i].key) { + button[i].ui_key_state.count++; + button[i].ui_key_state.state = 1; + break; + } + } +} + +static void setup_ui() +{ + // NOTE: keep constants in sync with hd44780_glut.c and hd44780_cgrom.h + const int border = 3; // HD44780_GL_BORDER + const int charwidth = 5; // HD44780_CHAR_WIDTH + const int charheight = 8; // HD44780_CHAR_HEIGHT + + const int pixsize = 3; + const int w = ((2 * border - 1) + hd44780.w * (charwidth + 1)) * pixsize; + const int h = ((2 * border - 1) + hd44780.h * (charheight + 1)) * pixsize; + + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + glutInitWindowSize(w, h); + glutCreateWindow("Press 'q' to quit"); /* create window */ + + // Set up projection matrix + glMatrixMode(GL_PROJECTION); // Select projection matrix + glLoadIdentity(); // Start with an identity matrix + glOrtho(0, w, 0, h, 0, 10); + glScalef(1,-1,1); + glTranslatef(0, -1 * h, 0); + + glutDisplayFunc(ui_display_cb); /* set window's display callback */ + glutTimerFunc(1000 / 24, ui_display_timer_cb, 0); + + glutKeyboardFunc(ui_key_press_cb); /* set window's key press callback */ + glutKeyboardUpFunc(ui_key_release_cb); /* set window's key release callback */ + glutIgnoreKeyRepeat(1); + + glEnable(GL_TEXTURE_2D); + glShadeModel(GL_SMOOTH); + + glClearColor(0.8f, 0.8f, 0.8f, 1.0f); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + hd44780_gl_init(); +} + + +/* Threads (AVR & UI) */ + +/** + * Run AVR simulation: step MCU infinitely and translate UI key events to + * simulated button presses/releases. + */ +static void * run_avr_thread(void * ignore) +{ + while (1) { + avr_run(avr); + + for (int i = 0; i < 5; i++) { + if (button[i].avr_key_state.count != button[i].ui_key_state.count && button[i].avr_key_state.state != button[i].ui_key_state.state) { + button[i].avr_key_state = button[i].ui_key_state; + if (button[i].avr_key_state.state == 0) { + button_press(&button[i].button, 0); + printf("Button %s pressed\n", button[i].name); + } else { + button_release(&button[i].button); + printf("Button %s released\n", button[i].name); + } + } + } + } + + return NULL; +} + +/** + * Run AVR simulation in a thread. + */ +static void run_avr() +{ + pthread_t run; + pthread_create(&run, NULL, run_avr_thread, NULL); +} + +/** + * Run UI event loop. + * Does not return. + */ +static void run_ui() +{ + glutMainLoop(); +} + + +/* Entry point */ + +int main(int argc, char *argv[]) +{ + process_ui_args(&argc, argv); + process_args(argc, argv); + + setup_avr(); + setup_board(); + setup_ui(); + + printf("This is an Olimex AVR-MT128 development board simulation\n" + "Press 'q' to exit\n" + "Press '8', '4', '5', '6', or '2' for buttons B1..B5\n"); + + run_avr(); + run_ui(); +} diff --git a/examples/parts/hd44780.c b/examples/parts/hd44780.c index 7428be365..820521c46 100644 --- a/examples/parts/hd44780.c +++ b/examples/parts/hd44780.c @@ -144,7 +144,11 @@ hd44780_write_data( } else { hd44780_kick_cursor(b); } - hd44780_set_flag(b, HD44780_FLAG_DIRTY, 1); + if (b->cursor < 0x80) { + hd44780_set_flag(b, HD44780_FLAG_DIRTY, 1); + } else { + hd44780_set_flag(b, HD44780_FLAG_CRAM_DIRTY, 1); + } return delay; } diff --git a/examples/parts/hd44780_cgrom.h b/examples/parts/hd44780_cgrom.h new file mode 100644 index 000000000..0bc35206b --- /dev/null +++ b/examples/parts/hd44780_cgrom.h @@ -0,0 +1,1318 @@ +/* + hd44780_cgrom.c + + Copyright 2020 Akos Kiss + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see . + */ + +#define HD44780_CHAR_WIDTH 5 +#define HD44780_CHAR_HEIGHT 8 +#define HD44780_CHAR_NUM 256 + +// ROM Code A00 +static const uint8_t hd44780_cgrom[HD44780_CHAR_NUM][HD44780_CHAR_HEIGHT] = { + [0b00100000] = { // ' ' + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b00100001] = { // '!' + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + 0b00000, + 0b00100, + 0b00000, + }, + [0b00100010] = { // '"' + 0b01010, + 0b01010, + 0b01010, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b00100011] = { // '#' + 0b01010, + 0b01010, + 0b11111, + 0b01010, + 0b11111, + 0b01010, + 0b01010, + 0b00000, + }, + [0b00100100] = { // '$' + 0b00100, + 0b01111, + 0b10100, + 0b01110, + 0b00101, + 0b11110, + 0b00100, + 0b00000, + }, + [0b00100101] = { // '%' + 0b11000, + 0b11001, + 0b00010, + 0b00100, + 0b01000, + 0b10011, + 0b00011, + 0b00000, + }, + [0b00100110] = { // '&' + 0b01100, + 0b10010, + 0b10100, + 0b01000, + 0b10101, + 0b10010, + 0b01101, + 0b00000, + }, + [0b00100111] = { // '\'' + 0b01100, + 0b00100, + 0b01000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b00101000] = { // '(' + 0b00010, + 0b00100, + 0b01000, + 0b01000, + 0b01000, + 0b00100, + 0b00010, + 0b00000, + }, + [0b00101001] = { // ')' + 0b01000, + 0b00100, + 0b00010, + 0b00010, + 0b00010, + 0b00100, + 0b01000, + 0b00000, + }, + [0b00101010] = { // '*' + 0b00000, + 0b00100, + 0b10101, + 0b01110, + 0b10101, + 0b00100, + 0b00000, + 0b00000, + }, + [0b00101011] = { // '+' + 0b00000, + 0b00100, + 0b00100, + 0b11111, + 0b00100, + 0b00100, + 0b00000, + 0b00000, + }, + [0b00101100] = { // ',' + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01100, + 0b00100, + 0b01000, + 0b00000, + }, + [0b00101101] = { // '-' + 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b00101110] = { // '.' + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01100, + 0b01100, + 0b00000, + }, + [0b00101111] = { // '/' + 0b00000, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b00000, + 0b00000, + }, + + [0b00110000] = { // '0' + 0b01110, + 0b10001, + 0b10011, + 0b10101, + 0b11001, + 0b10001, + 0b01110, + 0b00000, + }, + [0b00110001] = { // '1' + 0b00100, + 0b01100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b01110, + 0b00000, + }, + [0b00110010] = { // '2' + 0b01110, + 0b10001, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b11111, + 0b00000, + }, + [0b00110011] = { // '3' + 0b11111, + 0b00010, + 0b00100, + 0b00010, + 0b00001, + 0b10001, + 0b01110, + 0b00000, + }, + [0b00110100] = { // '4' + 0b00010, + 0b00110, + 0b01010, + 0b10010, + 0b11111, + 0b00010, + 0b00010, + 0b00000, + }, + [0b00110101] = { // '5' + 0b11111, + 0b10000, + 0b11110, + 0b00001, + 0b00001, + 0b10001, + 0b01110, + 0b00000, + }, + [0b00110110] = { // '6' + 0b00110, + 0b01000, + 0b10000, + 0b11110, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + }, + [0b00110111] = { // '7' + 0b11111, + 0b10001, + 0b00001, + 0b00010, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + }, + [0b00111000] = { // '8' + 0b01110, + 0b10001, + 0b10001, + 0b01110, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + }, + [0b00111001] = { // '9' + 0b01110, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + 0b00010, + 0b01100, + 0b00000, + }, + [0b00111010] = { // ':' + 0b00000, + 0b01100, + 0b01100, + 0b00000, + 0b01100, + 0b01100, + 0b00000, + 0b00000, + }, + [0b00111011] = { // ';' + 0b00000, + 0b01100, + 0b01100, + 0b00000, + 0b01100, + 0b00100, + 0b01000, + 0b00000, + }, + [0b00111100] = { // '<' + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b01000, + 0b00100, + 0b00010, + 0b00000, + }, + [0b00111101] = { // '=' + 0b00000, + 0b00000, + 0b11111, + 0b00000, + 0b11111, + 0b00000, + 0b00000, + 0b00000, + }, + [0b00111110] = { // '>' + 0b10000, + 0b01000, + 0b00100, + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b00000, + }, + [0b00111111] = { // '?' + 0b01110, + 0b10001, + 0b00001, + 0b00010, + 0b00100, + 0b00000, + 0b00100, + 0b00000, + }, + + [0b01000000] = { // '@' + 0b01110, + 0b10001, + 0b00001, + 0b01101, + 0b10101, + 0b10101, + 0b01110, + 0b00000, + }, + [0b01000001] = { // 'A' + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b11111, + 0b10001, + 0b10001, + 0b00000, + }, + [0b01000010] = { // 'B' + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b00000, + }, + [0b01000011] = { // 'C' + 0b01110, + 0b10001, + 0b10000, + 0b10000, + 0b10000, + 0b10001, + 0b01110, + 0b00000, + }, + [0b01000100] = { // 'D' + 0b11100, + 0b10010, + 0b10001, + 0b10001, + 0b10001, + 0b10010, + 0b11100, + 0b00000, + }, + [0b01000101] = { // 'E' + 0b11111, + 0b10000, + 0b10000, + 0b11110, + 0b10000, + 0b10000, + 0b11111, + 0b00000, + }, + [0b01000110] = { // 'F' + 0b11111, + 0b10000, + 0b10000, + 0b11110, + 0b10000, + 0b10000, + 0b10000, + 0b00000, + }, + [0b01000111] = { // 'G' + 0b01110, + 0b10001, + 0b10000, + 0b10111, + 0b10001, + 0b10001, + 0b01111, + 0b00000, + }, + + [0b01001000] = { // 'H' + 0b10001, + 0b10001, + 0b10001, + 0b11111, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + }, + [0b01001001] = { // 'I' + 0b01110, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b01110, + 0b00000, + }, + [0b01001010] = { // 'J' + 0b00111, + 0b00010, + 0b00010, + 0b00010, + 0b00010, + 0b10010, + 0b01100, + 0b00000, + }, + [0b01001011] = { // 'K' + 0b10001, + 0b10010, + 0b10100, + 0b11000, + 0b10100, + 0b10010, + 0b10001, + 0b00000, + }, + [0b01001100] = { // 'L' + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b11111, + 0b00000, + }, + [0b01001101] = { // 'M' + 0b10001, + 0b11011, + 0b10101, + 0b10101, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + }, + [0b01001110] = { // 'N' + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b01001111] = { // 'O' + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + }, + + [0b01010000] = { // 'P' + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10000, + 0b10000, + 0b10000, + 0b00000, + }, + [0b01010001] = { // 'Q' + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b10101, + 0b10010, + 0b01101, + 0b00000, + }, + [0b01010010] = { // 'R' + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10100, + 0b10010, + 0b10001, + 0b00000, + }, + [0b01010011] = { // 'S' + 0b01111, + 0b10000, + 0b10000, + 0b01110, + 0b00001, + 0b00001, + 0b11110, + 0b00000, + }, + [0b01010100] = { // 'T' + 0b11111, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + }, + [0b01010101] = { // 'U' + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + }, + [0b01010110] = { // 'V' + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b00000, + }, + [0b01010111] = { // 'W' + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10101, + 0b10101, + 0b01010, + 0b00000, + }, + [0b01011000] = { // 'X' + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b01010, + 0b10001, + 0b10001, + 0b00000, + }, + [0b01011001] = { // 'Y' + 0b10001, + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + }, + [0b01011010] = { // 'Z' + 0b11111, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b11111, + 0b00000, + }, + [0b01011011] = { // '[' + 0b11100, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b11100, + 0b00000, + }, + [0b01011100] = { // Yen + 0b10001, + 0b01010, + 0b11111, + 0b00100, + 0b11111, + 0b00100, + 0b00100, + 0b00000, + }, + [0b01011101] = { // ']' + 0b01110, + 0b00010, + 0b00010, + 0b00010, + 0b00010, + 0b00010, + 0b01110, + 0b00000, + }, + [0b01011110] = { // '^' + 0b00100, + 0b01010, + 0b10001, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b01011111] = { // '_' + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00000, + }, + + [0b01100000] = { // '`' + 0b01000, + 0b00100, + 0b00010, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b01100001] = { // 'a' + 0b00000, + 0b00000, + 0b01110, + 0b00001, + 0b01111, + 0b10001, + 0b01111, + 0b00000, + }, + [0b01100010] = { // 'b' + 0b10000, + 0b10000, + 0b10110, + 0b11001, + 0b10001, + 0b10001, + 0b11110, + 0b00000, + }, + [0b01100011] = { // 'c' + 0b00000, + 0b00000, + 0b01110, + 0b10000, + 0b10000, + 0b10001, + 0b01110, + 0b00000, + }, + [0b01100100] = { // 'd' + 0b00001, + 0b00001, + 0b01101, + 0b10011, + 0b10001, + 0b10001, + 0b01111, + 0b00000, + }, + [0b01100101] = { // 'e' + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b11111, + 0b10000, + 0b01110, + 0b00000, + }, + [0b01100110] = { // 'f' + 0b00110, + 0b01001, + 0b01000, + 0b11100, + 0b01000, + 0b01000, + 0b01000, + 0b00000, + }, + [0b01100111] = { // 'g' + 0b00000, + 0b01111, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + 0b01110, + 0b00000, + }, + [0b01101000] = { // 'h' + 0b10000, + 0b10000, + 0b10110, + 0b11001, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + }, + [0b01101001] = { // 'i' + 0b00100, + 0b00000, + 0b01100, + 0b00100, + 0b00100, + 0b00100, + 0b01110, + 0b00000, + }, + [0b01101010] = { // 'j' + 0b00010, + 0b00000, + 0b00110, + 0b00010, + 0b00010, + 0b10010, + 0b01100, + 0b00000, + }, + [0b01101011] = { // 'k' + 0b10000, + 0b10000, + 0b10010, + 0b10100, + 0b11000, + 0b10100, + 0b10010, + 0b00000, + }, + [0b01101100] = { // 'l' + 0b01100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b01110, + 0b00000, + }, + [0b01101101] = { // 'm' + 0b00000, + 0b00000, + 0b11010, + 0b10101, + 0b10101, + 0b10001, + 0b10001, + 0b00000, + }, + [0b01101110] = { // 'n' + 0b00000, + 0b00000, + 0b10110, + 0b11001, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + }, + [0b01101111] = { // 'o' + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + }, + + [0b01110000] = { // 'p' + 0b00000, + 0b00000, + 0b11110, + 0b10001, + 0b11110, + 0b10000, + 0b10000, + 0b00000, + }, + [0b01110001] = { // 'q' + 0b00000, + 0b00000, + 0b01101, + 0b10011, + 0b01111, + 0b00001, + 0b00001, + 0b00000, + }, + [0b01110010] = { // 'r' + 0b00000, + 0b00000, + 0b10110, + 0b11001, + 0b10000, + 0b10000, + 0b10000, + 0b00000, + }, + [0b01110011] = { // 's' + 0b00000, + 0b00000, + 0b01110, + 0b10000, + 0b01110, + 0b00001, + 0b11110, + 0b00000, + }, + [0b01110100] = { // 't' + 0b01000, + 0b01000, + 0b11100, + 0b01000, + 0b01000, + 0b01001, + 0b00110, + 0b00000, + }, + [0b01110101] = { // 'u' + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10011, + 0b01101, + 0b00000, + }, + [0b01110110] = { // 'v' + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b00000, + }, + [0b01110111] = { // 'w' + 0b00000, + 0b00000, + 0b10001, + 0b10101, + 0b10101, + 0b10101, + 0b01010, + 0b00000, + }, + [0b01111000] = { // 'x' + 0b00000, + 0b00000, + 0b10001, + 0b01010, + 0b00100, + 0b01010, + 0b10001, + 0b00000, + }, + [0b01111001] = { // 'y' + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + 0b01110, + 0b00000, + }, + [0b01111010] = { // 'z' + 0b00000, + 0b00000, + 0b11111, + 0b00010, + 0b00100, + 0b01000, + 0b11111, + 0b00000, + }, + [0b01111011] = { // '{' + 0b00010, + 0b00100, + 0b00100, + 0b01000, + 0b00100, + 0b00100, + 0b00010, + 0b00000, + }, + [0b01111100] = { // '|' + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + }, + [0b01111101] = { // '}' + 0b01000, + 0b00100, + 0b00100, + 0b00010, + 0b00100, + 0b00100, + 0b01000, + 0b00000, + }, + [0b01111110] = { // right arrow + 0b00000, + 0b00100, + 0b00010, + 0b11111, + 0b00010, + 0b00100, + 0b00000, + 0b00000, + }, + [0b01111111] = { // left arrow + 0b00000, + 0b00100, + 0b01000, + 0b11111, + 0b01000, + 0b00100, + 0b00000, + 0b00000, + }, + + // TODO: [0b10100000...0b11011111] + + [0b11100000] = { // alpha + 0b00000, + 0b00000, + 0b01001, + 0b10101, + 0b10010, + 0b10010, + 0b01101, + 0b00000, + }, + [0b11100001] = { // a: + 0b01010, + 0b00000, + 0b01110, + 0b00001, + 0b01111, + 0b10001, + 0b01111, + 0b00000, + }, + [0b11100010] = { // beta (truncated from 5x10) + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b11110, + 0b10001, + 0b11110, + 0b10000, + }, + [0b11100011] = { // epsylon + 0b00000, + 0b00000, + 0b01110, + 0b10000, + 0b01100, + 0b10001, + 0b01110, + 0b00000, + }, + [0b11100100] = { // mu (truncated from 5x10) + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10011, + 0b11101, + 0b10000, + }, + [0b11100101] = { // sigma + 0b00000, + 0b00000, + 0b01111, + 0b10100, + 0b10010, + 0b10001, + 0b01110, + 0b00000, + }, + [0b11100110] = { // rho (truncated from 5x10) + 0b00000, + 0b00000, + 0b00110, + 0b01001, + 0b10001, + 0b10001, + 0b11110, + 0b10000, + }, + [0b11100111] = { // g (truncated from 5x10) + 0b00000, + 0b00000, + 0b01111, + 0b10001, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + }, + [0b11101000] = { // square root + 0b00000, + 0b00000, + 0b00111, + 0b00100, + 0b00100, + 0b10100, + 0b01000, + 0b00000, + }, + [0b11101001] = { // -1 + 0b00000, + 0b00010, + 0b11010, + 0b00010, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b11101010] = { // j (truncated from 5x10) + 0b00010, + 0b00000, + 0b00110, + 0b00010, + 0b00010, + 0b00010, + 0b00010, + 0b00010, + }, + [0b11101011] = { // + 0b00000, + 0b10100, + 0b01000, + 0b10100, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b11101100] = { // cent + 0b00000, + 0b00100, + 0b01110, + 0b10100, + 0b10101, + 0b01110, + 0b00100, + 0b00000, + }, + [0b11101101] = { // Pound + 0b01000, + 0b01000, + 0b11100, + 0b01000, + 0b11100, + 0b01000, + 0b01111, + 0b00000, + }, + [0b11101110] = { // n~ + 0b01110, + 0b00000, + 0b10110, + 0b11001, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + }, + [0b11101111] = { // o: + 0b01010, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + }, + + [0b11110000] = { // p (truncated from 5x10) + 0b00000, + 0b00000, + 0b10110, + 0b11001, + 0b10001, + 0b10001, + 0b11110, + 0b10000, + }, + [0b11110001] = { // q (truncated from 5x10) + 0b00000, + 0b00000, + 0b01101, + 0b10011, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + }, + [0b11110010] = { // theta + 0b00000, + 0b01110, + 0b10001, + 0b11111, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + }, + [0b11110011] = { // inf + 0b00000, + 0b00000, + 0b00000, + 0b01011, + 0b10101, + 0b11010, + 0b00000, + 0b00000, + }, + [0b11110100] = { // Omega + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b01010, + 0b11011, + 0b00000, + }, + [0b11110101] = { // U: + 0b01010, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10011, + 0b01101, + }, + [0b11110110] = { // Sigma + 0b11111, + 0b10000, + 0b01000, + 0b00100, + 0b01000, + 0b10000, + 0b11111, + 0b00000, + }, + [0b11110111] = { // pi + 0b00000, + 0b00000, + 0b11111, + 0b01010, + 0b01010, + 0b01010, + 0b10011, + 0b00000, + }, + [0b11111000] = { // x- + 0b11111, + 0b00000, + 0b10001, + 0b01010, + 0b00100, + 0b01010, + 0b10001, + 0b00000, + }, + [0b11111001] = { // y (truncated from 5x10) + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + }, + [0b11111010] = { // + 0b00000, + 0b00001, + 0b11110, + 0b00100, + 0b11111, + 0b00100, + 0b00100, + 0b00000, + }, + [0b11111011] = { // + 0b00000, + 0b00000, + 0b11111, + 0b01000, + 0b01111, + 0b01001, + 0b10001, + 0b00000, + }, + [0b11111100] = { // + 0b00000, + 0b00000, + 0b11111, + 0b10101, + 0b11111, + 0b10001, + 0b10001, + 0b00000, + }, + [0b11111101] = { // + 0b00000, + 0b00100, + 0b00000, + 0b11111, + 0b00000, + 0b00100, + 0b00000, + 0b00000, + }, + [0b11111110] = { // empty block + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + }, + [0b11111111] = { // full block (truncated from 5x10) + 0b11111, + 0b11111, + 0b11111, + 0b11111, + 0b11111, + 0b11111, + 0b11111, + 0b11111, + }, +}; diff --git a/examples/parts/hd44780_glut.c b/examples/parts/hd44780_glut.c index 77c28bcbd..3fc5d04cb 100644 --- a/examples/parts/hd44780_glut.c +++ b/examples/parts/hd44780_glut.c @@ -3,6 +3,7 @@ Copyright Luki Copyright 2011 Michel Pollet + Copyright 2020 Akos Kiss This file is part of simavr. @@ -28,28 +29,60 @@ #include #endif -#include "lcd_font.h" // generated with gimp +#include "hd44780_cgrom.h" -static GLuint font_texture; -static int charwidth = 5; -static int charheight = 7; +#define HD44780_GL_TEXTURE_WIDTH HD44780_CHAR_WIDTH +#define HD44780_GL_TEXTURE_HEIGHT (HD44780_CHAR_NUM * HD44780_CHAR_HEIGHT) +#define HD44780_GL_TEXTURE_BYTES_PER_PIXEL 4 // RGBA +#define HD44780_GL_TEXTURE_SIZE (HD44780_GL_TEXTURE_WIDTH * HD44780_GL_TEXTURE_HEIGHT * HD44780_GL_TEXTURE_BYTES_PER_PIXEL) +#define HD44780_GL_BORDER 3 + +static unsigned char cgrom_pixel_data[HD44780_GL_TEXTURE_SIZE]; +static unsigned char cgram_pixel_data[HD44780_GL_TEXTURE_SIZE] = {0}; // NOTE: much more than actually necessary but ensures texture size identical to cgrom + +static GLuint cgrom_texture; +static GLuint cgram_texture; void hd44780_gl_init() { - glGenTextures(1, &font_texture); - glBindTexture(GL_TEXTURE_2D, font_texture); + for (int c = 0; c < HD44780_CHAR_NUM; c++) { + for (int y = 0; y < HD44780_CHAR_HEIGHT; y++) { + uint8_t bits = hd44780_cgrom[c][y]; + uint8_t mask = 1 << (HD44780_CHAR_WIDTH - 1); + for (int x = 0; x < HD44780_CHAR_WIDTH; x++, mask >>= 1) { + int p = ((c * HD44780_CHAR_HEIGHT * HD44780_CHAR_WIDTH) + (y * HD44780_CHAR_WIDTH) + x) * HD44780_GL_TEXTURE_BYTES_PER_PIXEL; + cgrom_pixel_data[p + 0] = 0; + cgrom_pixel_data[p + 1] = 0; + cgrom_pixel_data[p + 2] = 0; + cgrom_pixel_data[p + 3] = bits & mask ? 0xff : 0; + } + } + } + + glGenTextures(1, &cgrom_texture); + glBindTexture(GL_TEXTURE_2D, cgrom_texture); + glTexImage2D(GL_TEXTURE_2D, 0, 4, + HD44780_GL_TEXTURE_WIDTH, + HD44780_GL_TEXTURE_HEIGHT, 0, GL_RGBA, + GL_UNSIGNED_BYTE, + cgrom_pixel_data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glGenTextures(1, &cgram_texture); + glBindTexture(GL_TEXTURE_2D, cgram_texture); glTexImage2D(GL_TEXTURE_2D, 0, 4, - lcd_font.width, - lcd_font.height, 0, GL_RGBA, + HD44780_GL_TEXTURE_WIDTH, + HD44780_GL_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, - lcd_font.pixel_data); + cgram_pixel_data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glMatrixMode(GL_TEXTURE); glLoadIdentity(); - glScalef(1.0f / (GLfloat) lcd_font.width, 1.0f / (GLfloat) lcd_font.height, 1.0f); + glScalef(1.0f / (GLfloat) HD44780_GL_TEXTURE_WIDTH, 1.0f / (GLfloat) HD44780_GL_TEXTURE_HEIGHT, 1.0f); glMatrixMode(GL_MODELVIEW); } @@ -64,17 +97,17 @@ glColor32U(uint32_t color) (float)((color) & 0xff) / 255.0f ); } -void +static void glputchar(char c, uint32_t character, uint32_t text, uint32_t shadow) { int index = c; - int left = index * charwidth; - int right = index * charwidth + charwidth; - int top = 0; - int bottom = 7; + int left = 0; + int right = HD44780_CHAR_WIDTH; + int top = index * HD44780_CHAR_HEIGHT; + int bottom = index * HD44780_CHAR_HEIGHT + HD44780_CHAR_HEIGHT; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -82,37 +115,36 @@ glputchar(char c, glDisable(GL_TEXTURE_2D); glColor32U(character); glBegin(GL_QUADS); - glVertex3i(5, 7, 0); - glVertex3i(0, 7, 0); - glVertex3i(0, 0, 0); - glVertex3i(5, 0, 0); + glVertex3i(HD44780_CHAR_WIDTH, HD44780_CHAR_HEIGHT, 0); + glVertex3i(0, HD44780_CHAR_HEIGHT, 0); + glVertex3i(0, 0, 0); + glVertex3i(HD44780_CHAR_WIDTH, 0, 0); glEnd(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, font_texture); + glBindTexture(GL_TEXTURE_2D, index < 16 ? cgram_texture : cgrom_texture); if (shadow) { glColor32U(shadow); glPushMatrix(); glTranslatef(.2f, .2f, 0); glBegin(GL_QUADS); - glTexCoord2i(right, top); glVertex3i(5, 0, 0); - glTexCoord2i(left, top); glVertex3i(0, 0, 0); - glTexCoord2i(left, bottom); glVertex3i(0, 7, 0); - glTexCoord2i(right, bottom); glVertex3i(5, 7, 0); + glTexCoord2i(right, top); glVertex3i(HD44780_CHAR_WIDTH, 0, 0); + glTexCoord2i(left, top); glVertex3i(0, 0, 0); + glTexCoord2i(left, bottom); glVertex3i(0, HD44780_CHAR_HEIGHT, 0); + glTexCoord2i(right, bottom); glVertex3i(HD44780_CHAR_WIDTH, HD44780_CHAR_HEIGHT, 0); glEnd(); glPopMatrix(); } glColor32U(text); glBegin(GL_QUADS); - glTexCoord2i(right, top); glVertex3i(5, 0, 0); - glTexCoord2i(left, top); glVertex3i(0, 0, 0); - glTexCoord2i(left, bottom); glVertex3i(0, 7, 0); - glTexCoord2i(right, bottom); glVertex3i(5, 7, 0); + glTexCoord2i(right, top); glVertex3i(HD44780_CHAR_WIDTH, 0, 0); + glTexCoord2i(left, top); glVertex3i(0, 0, 0); + glTexCoord2i(left, bottom); glVertex3i(0, HD44780_CHAR_HEIGHT, 0); + glTexCoord2i(right, bottom); glVertex3i(HD44780_CHAR_WIDTH, HD44780_CHAR_HEIGHT, 0); glEnd(); - } void @@ -125,30 +157,66 @@ hd44780_gl_draw( { int rows = b->w; int lines = b->h; - int border = 3; glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glColor32U(background); - glTranslatef(border, border, 0); + glTranslatef(HD44780_GL_BORDER, HD44780_GL_BORDER, 0); glBegin(GL_QUADS); - glVertex3f(rows * charwidth + (rows - 1) + border, -border, 0); - glVertex3f(-border, -border, 0); - glVertex3f(-border, lines * charheight + (lines - 1) + border, 0); - glVertex3f(rows * charwidth + (rows - 1) + border, lines * charheight - + (lines - 1) + border, 0); + glVertex3f(rows * HD44780_CHAR_WIDTH + (rows - 1) + HD44780_GL_BORDER, -HD44780_GL_BORDER, 0); + glVertex3f(-HD44780_GL_BORDER, -HD44780_GL_BORDER, 0); + glVertex3f(-HD44780_GL_BORDER, lines * HD44780_CHAR_HEIGHT + (lines - 1) + HD44780_GL_BORDER, 0); + glVertex3f(rows * HD44780_CHAR_WIDTH + (rows - 1) + HD44780_GL_BORDER, lines * HD44780_CHAR_HEIGHT + + (lines - 1) + HD44780_GL_BORDER, 0); glEnd(); + // Re-generate texture for cgram + if (hd44780_get_flag(b, HD44780_FLAG_CRAM_DIRTY)) { + for (int c = 0; c < 8; c++) { + for (int y = 0; y < HD44780_CHAR_HEIGHT; y++) { + uint8_t bits = b->vram[0x80 + c * 8 + y]; + uint8_t mask = 1 << (HD44780_CHAR_WIDTH - 1); + for (int x = 0; x < HD44780_CHAR_WIDTH; x++, mask >>= 1) { + int p1 = ((c * HD44780_CHAR_HEIGHT * HD44780_CHAR_WIDTH) + (y * HD44780_CHAR_WIDTH) + x) * HD44780_GL_TEXTURE_BYTES_PER_PIXEL; + cgram_pixel_data[p1 + 0] = 0; + cgram_pixel_data[p1 + 1] = 0; + cgram_pixel_data[p1 + 2] = 0; + cgram_pixel_data[p1 + 3] = bits & mask ? 0xff : 0; + + int p2 = (((c + 8) * HD44780_CHAR_HEIGHT * HD44780_CHAR_WIDTH) + (y * HD44780_CHAR_WIDTH) + x) * HD44780_GL_TEXTURE_BYTES_PER_PIXEL; + cgram_pixel_data[p2 + 0] = 0; + cgram_pixel_data[p2 + 1] = 0; + cgram_pixel_data[p2 + 2] = 0; + cgram_pixel_data[p2 + 3] = bits & mask ? 0xff : 0; + } + } + } + + // FIXME: unsure how much of this is actually necessary + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, cgram_texture); + glTexImage2D(GL_TEXTURE_2D, 0, 4, + HD44780_GL_TEXTURE_WIDTH, + HD44780_GL_TEXTURE_HEIGHT, 0, GL_RGBA, + GL_UNSIGNED_BYTE, + cgram_pixel_data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glDisable(GL_TEXTURE_2D); + + hd44780_set_flag(b, HD44780_FLAG_CRAM_DIRTY, 0); + } + glColor3f(1.0f, 1.0f, 1.0f); const uint8_t offset[] = { 0x00, 0x40, 0x00 + 20, 0x40 + 20 }; for (int v = 0 ; v < b->h; v++) { glPushMatrix(); for (int i = 0; i < b->w; i++) { glputchar(b->vram[offset[v] + i], character, text, shadow); - glTranslatef(6, 0, 0); + glTranslatef(HD44780_CHAR_WIDTH + 1, 0, 0); } glPopMatrix(); - glTranslatef(0, 8, 0); + glTranslatef(0, HD44780_CHAR_HEIGHT + 1, 0); } hd44780_set_flag(b, HD44780_FLAG_DIRTY, 0); } diff --git a/examples/parts/lcd_font.h b/examples/parts/lcd_font.h deleted file mode 100644 index 738483998..000000000 --- a/examples/parts/lcd_font.h +++ /dev/null @@ -1,1070 +0,0 @@ -/* GIMP RGBA C-Source image dump (font.c) */ - -static const struct { - unsigned int width; - unsigned int height; - unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ - char *comment; - unsigned char pixel_data[1280 * 7 * 4 + 1]; -} lcd_font = { - 1280, 7, 4, - "generated with gimp from font,tiff", - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0" - "\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0" - "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" - "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" - "\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" - "\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0" - "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377", -}; -