diff options
Diffstat (limited to 'kscd/kscdmagic')
-rw-r--r-- | kscd/kscdmagic/Makefile.am | 40 | ||||
-rw-r--r-- | kscd/kscdmagic/README | 146 | ||||
-rw-r--r-- | kscd/kscdmagic/core.cpp | 410 | ||||
-rw-r--r-- | kscd/kscdmagic/logo.h | 50 | ||||
-rw-r--r-- | kscd/kscdmagic/magicconf.h | 23 | ||||
-rw-r--r-- | kscd/kscdmagic/main.cpp | 300 | ||||
-rw-r--r-- | kscd/kscdmagic/polygon.h | 106 | ||||
-rw-r--r-- | kscd/kscdmagic/sound.cpp | 252 | ||||
-rw-r--r-- | kscd/kscdmagic/symbol.h | 1028 | ||||
-rw-r--r-- | kscd/kscdmagic/syna.h | 180 | ||||
-rw-r--r-- | kscd/kscdmagic/version.h | 1 | ||||
-rw-r--r-- | kscd/kscdmagic/xlib.c | 781 | ||||
-rw-r--r-- | kscd/kscdmagic/xlib.h | 139 | ||||
-rw-r--r-- | kscd/kscdmagic/xlibwrap.cpp | 209 |
14 files changed, 3665 insertions, 0 deletions
diff --git a/kscd/kscdmagic/Makefile.am b/kscd/kscdmagic/Makefile.am new file mode 100644 index 00000000..c5cc3a21 --- /dev/null +++ b/kscd/kscdmagic/Makefile.am @@ -0,0 +1,40 @@ + +# this 10 paths are KDE specific. Use them: +# kde_htmldir Where your docs should go to. (contains lang subdirs) +# kde_appsdir Where your application file (.kdelnk) should go to. +# kde_icondir Where your icon should go to. +# kde_minidir Where your mini icon should go to. +# kde_datadir Where you install application data. (Use a subdir) +# kde_locale Where translation files should go to.(contains lang subdirs) +# kde_cgidir Where cgi-bin executables should go to. +# kde_confdir Where config files should go to. +# kde_mimedir Where mimetypes should go to. +# kde_toolbardir Where general toolbar icons should go to. +# kde_wallpaperdir Where general wallpapers should go to. + +# just set the variable +APPSDIR = $(kde_appsdir)/Multimedia + +# set the include path for X, qt and KDE +INCLUDES= $(all_includes) + +####### This part is very kscdmagic specific +# you can add here more. This one gets installed +bin_PROGRAMS = kscdmagic + +# Which sources should be compiled for kscdmagic +kscdmagic_SOURCES = core.cpp main.cpp sound.cpp xlibwrap.cpp xlib.c + +# the library search path. +kscdmagic_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +# the libraries to link against. Be aware of the order. First the libraries, +# that depend on the following ones. +kscdmagic_LDADD = -lm $(LIB_KDEUI) + +# this option you can leave out. Just, if you use "make dist", you need it +noinst_HEADERS = symbol.h syna.h xlib.h magicconf.h + +messages: +# $(XGETTEXT) -kTRANS $(kscdmagic_SOURCES) + diff --git a/kscd/kscdmagic/README b/kscd/kscdmagic/README new file mode 100644 index 00000000..64af4f6f --- /dev/null +++ b/kscd/kscdmagic/README @@ -0,0 +1,146 @@ + +kscdmagic is based on synaesthesia +by Paul Harrison <pfh@yoyo.cc.monash.edu.au>. + + -dirk <milliByte@gmx.net> + + + + +SYNAESTHESIA v2.0 + +Introduction +============ + +This is a program for representing sounds visually from a CD or line +input or piped from another program. It goes beyond the usual oscilliscope +style program by combining an FFT and stereo positioning information to +give a two dimensional display. Some of the shapes I have observed are: + * Drums: clouds of color, fairly high + * Clean guitar: several horizontal lines, low down + * Rough guitar: a cloud, low down + * Trumpet: Lots of horizontal lines everywhere + * Flute: A single horizontal line, low down + * Voice: A vertical line with some internal structure + * Synthesizer: All kinds of weird shapes! + +Synaesthesia can run in a window in X or full screen using SVGAlib. + +The display represents frequency as vertical position on screen, +left-right position as left-right position on screen. It can also +understand surround sound encoded music, and shows ambient noise +in orange. + +X-Windows support was added in version 1.3, as well as a major redesign +of the interface. You can use Synaesthesia as a fully functional +CD player, suitable for use while working. + +There is command line support for play lists and piping from another +program (such as an mp3 player). + +Usage +===== + +Synaesthesia should work on Linux and BSD systems. (Note: I don't +have access to a BSD system myself, I have to rely on patches -- if it +doesn't work, please tell me!) LinuxPPC users may have to use the pipe +mode rather than taking sound input from the CD player, as I believe +sound recording is not yet implemented. + +Compile Synaesthesia by typing + + make + +then install it by typing + + make install + +This will create three versions of Synaesthesia: + + synaesthesia - full screen SVGAlib version (Linux only) + xsynaesthesia - Version that runs as a window in X + sdlsynaesthesia - Version that uses the SDL graphics library + +If you want to use the SDL version, you need to get SDL from +http://www.devolution.com/~slouken/SDL. + +You will need to run Synaesthesia as root to run it full screen +with SVGAlib. Other varieties can be run by any user providing you +provide permissions on /dev/dsp, /dev/cdrom, and /dev/mixer. + +Synaesthesia creates a configuration file, named ~/.synaesthesia, +to store settings such as brightness, color, and window size, as +well as which devices to use to control sound input. + +BSD users will have to edit this file to set the CD-ROM device name +before using Synaesthesia in order to control the CD. + +Run Synaesthesia with no parameters for further information on how to +use it. + +Notes for code rippers +====================== + +This program contains code that you may wish to use in your own projects. +If you want to, please do. (For example, you might want to add some +snazzy visual effects to your favorite MP3 or CD player) + +The actual code to do the mapping from sound to visual display is +all in core.cpp, it should be fairly easy to disentangle from other +parts of the program. It does make reference to some globals defined +in syna.h, namely the #defines m (log2 of the sample size for each +frame) and brightness, data (which stores the sound input), outputBmp, +lastOutputBmp and lastLastOutputBmp (which hold the output), outWidth +and outHeight (size of the bitmaps), and fadeMode, brightnessTwiddler, +starSize and pointsAreDiamonds (various parameters affecting the display). + +The normal way to use it would be: + + Call coreInit() to set up some look-up tables + Call setStarSize(starSize) to set up some more look-up tables + Loop + Put data into the data array + Call fade() to apply the fade/wave/heat effect to the output + Call coreGo() to add the next fragment of sound input to the output + Display contents of outputBmp to screen + +There is a simple anti-aliased polygon drawing engine in the file +polygon.h. sound.cpp contains code for driving the CD. xlib.c and +xlibwrap.cpp contain code for setting up a window under X (originally +ripped from the Xaos fractal viewer program :-) ). + +Authors +======= + +This program is free. If you like it, or have any suggestions, please +send me (Paul Harrison) an email (pfh@yoyo.cc.monash.edu.au). + +Thanks to Asger Alstrup Nielsen for many great suggestions, and for +writing optimized 32 bit loops for fading and drawing to screen. + +Thanks to Roger Knobbe for porting Synaesthesia to FreeBSD. + +Thanks to Ben Gertzfield and Martin Mitchell for some small fixes to the +CD controlling code. + +Thanks to Simon Budig for an improvement to the X code. + +Changes +======= + +1.1 - Added surround sound decoding. +1.2 - Fixed a bug in the ioctl calls to /dev/dsp. +1.3 - Asger Alstrup Nielsen's optimizations added. + Added X-Windows support. + More options, redesigned interface. +1.4 - Bug fixes, including a great reduction in + "Sound: Recording overrun" warnings. + New command line options: play lists and piping. + Support for SDL. +2.0 - Bug fixes: Fixed problem in xlib.c that caused occasional segfaults, + several endianness problems fixed. + New effects: Wave, heat, diamond shaped points. + Piping sound now longer requires the twiddle factor. + Yet another interface redesign. + Partial support for LinuxPPC (pipe mode only) + diff --git a/kscd/kscdmagic/core.cpp b/kscd/kscdmagic/core.cpp new file mode 100644 index 00000000..49fce661 --- /dev/null +++ b/kscd/kscdmagic/core.cpp @@ -0,0 +1,410 @@ +/* Synaesthesia - program to display sound graphically + Copyright (C) 1997 Paul Francis Harrison + + This program 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 2 of the License, or (at your + option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author may be contacted at: + pfh@yoyo.cc.monash.edu.au + or + 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include "syna.h" + +double cosTable[n], negSinTable[n]; +int bitReverse[n]; +int scaleDown[256]; +int maxStarRadius; + +int bitReverser(int i) { + int sum=0,j; + for(j=0;j<m;j++) { + sum = (i&1)+sum*2; + i >>= 1; + } + return sum; +} + +void fft(double *x,double *y) { + int n2 = n, n1; + int twoToTheK; + for(twoToTheK=1;twoToTheK<n;twoToTheK*=2) { + n1 = n2; + n2 /= 2; + for(int j=0;j<n2;j++) { + double c = cosTable[j*twoToTheK&(n-1)], + s = negSinTable[j*twoToTheK&(n-1)]; + for(int i=j;i<n;i+=n1) { + int l = i+n2; + double xt = x[i] - x[l]; + x[i] = (x[i] + x[l]); + double yt = y[i] - y[l]; + y[i] = (y[i] + y[l]); + x[l] = xt*c - yt*s; + y[l] = xt*s + yt*c; + } + } + } +} + +void coreInit() { + int i; + + for(i=0;i<n;i++) { + negSinTable[i] = -sin(3.141592*2.0/n*i); + cosTable[i] = cos(3.141592*2.0/n*i); + bitReverse[i] = bitReverser(i); + } +} + +void setStarSize(double size) { + //int factor = (fadeMode == Flame ? 100 : + // (fadeMode == Wave ? 150 : 200)); + + double fadeModeFudge = (fadeMode == Wave ? 0.4 : + (fadeMode == Flame ? 0.6 : 0.78)); + + int factor; + if (size > 0.0) + factor = int(exp(log(fadeModeFudge) / (size*8.0))*255); + else + factor = 0; + + if (factor > 255) factor = 255; + + for(int i=0;i<256;i++) + scaleDown[i] = i*factor>>8; + + maxStarRadius = 1; + for(int i=255;i;i = scaleDown[i]) + maxStarRadius++; +} + +inline void addPixel(int x,int y,int br1,int br2) { + if (x < 0 || x >= outWidth || y < 0 || y >= outHeight) return; + + unsigned char *p = ucoutput+x*2+y*outWidth*2; + if (p[0] < 255-br1) p[0] += br1; else p[0] = 255; + if (p[1] < 255-br2) p[1] += br2; else p[1] = 255; + //p += lastOutput-output; + //if (p[0] < 255-br1) p[0] += br1; else p[0] = 255; + //if (p[1] < 255-br2) p[1] += br2; else p[1] = 255; +} + +inline void addPixelFast(unsigned char *p,int br1,int br2) { + if (p[0] < 255-br1) p[0] += br1; else p[0] = 255; + if (p[1] < 255-br2) p[1] += br2; else p[1] = 255; + //p += lastOutput-output; + //if (p[0] < 255-br1) p[0] += br1; else p[0] = 255; + //if (p[1] < 255-br2) p[1] += br2; else p[1] = 255; +} + +void fadeFade() { + register unsigned long *ptr = (unsigned long*)ucoutput; + int i = outWidth*outHeight*2/4; + do { + //Bytewize version was: *(ptr++) -= *ptr+(*ptr>>1)>>4; + if (*ptr) + //if (*ptr & 0xf0f0f0f0ul) + *(ptr++) -= ((*ptr & 0xf0f0f0f0ul) >> 4) + ((*ptr & 0xe0e0e0e0ul) >> 5); + //else { + // *(ptr++) = (*ptr * 14 >> 4) & 0x0f0f0f0ful; + //} + else + ptr++; + } while(--i > 0); +} + +inline unsigned char getPixel(int x,int y,int where) { + if (x < 0 || y < 0 || x >= outWidth || y >= outHeight) return 0; + return lastOutput[where]; +} + +inline void fadePixelWave(int x,int y,int where,int step) { + short j = + ( short(getPixel(x-1,y,where-2))+ + getPixel(x+1,y,where+2)+ + getPixel(x,y-1,where-step)+ + getPixel(x,y+1,where+step) + >> 2) + +lastOutput[where]; + if (!j) { ucoutput[where] = 0; return; } + j = j + -lastLastOutput[where] + -1; + if (j < 0) ucoutput[where] = 0; + else if (j & (255*256)) ucoutput[where] = 255; + else ucoutput[where] = j; +} + +void fadeWave() { + unsigned short *t = lastLastOutputBmp.data; + lastLastOutputBmp.data = lastOutputBmp.data; + lastOutputBmp.data = outputBmp.data; + outputBmp.data = t; + + int x,y,i,j,start,end; + int step = outWidth*2; + for(x=0,i=0,j=outWidth*(outHeight-1)*2;x<outWidth;x++,i+=2,j+=2) { + fadePixelWave(x,0,i,step); + fadePixelWave(x,0,i+1,step); + fadePixelWave(x,outHeight-1,j,step); + fadePixelWave(x,outHeight-1,j+1,step); + } + + for(y=1,i=outWidth*2,j=outWidth*4-2;y<outHeight;y++,i+=step,j+=step) { + fadePixelWave(0,y,i,step); + fadePixelWave(0,y,i+1,step); + fadePixelWave(outWidth-1,y,j,step); + fadePixelWave(outWidth-1,y,j+1,step); + } + + for(y=1, + start=outWidth*2+2, + end=outWidth*4-2; y<outHeight-1; y++,start+=step,end+=step) { + int i = start; + do { + short j = + ( short(lastOutput[i-2])+ + lastOutput[i+2]+ + lastOutput[i-step]+ + lastOutput[i+step] + >> 2) + +lastOutput[i]; + if (!j) { + ucoutput[i] = 0; + } else { + j = j + -lastLastOutput[i] + -1; + if (j < 0) ucoutput[i] = 0; + else if (j & (255*256)) ucoutput[i] = 255; + else ucoutput[i] = j; + } + } while(++i < end); + } +} + +inline void fadePixelHeat(int x,int y,int where,int step) { + short j = + ( short(getPixel(x-1,y,where-2))+ + getPixel(x+1,y,where+2)+ + getPixel(x,y-1,where-step)+ + getPixel(x,y+1,where+step) + >> 2) + +lastOutput[where]; + if (!j) { ucoutput[where] = 0; return; } + j = j + -lastLastOutput[where] + -1; + if (j < 0) ucoutput[where] = 0; + else if (j & (255*256)) ucoutput[where] = 255; + else ucoutput[where] = j; +} + +void fadeHeat() { + unsigned short *t = lastLastOutputBmp.data; + lastLastOutputBmp.data = lastOutputBmp.data; + lastOutputBmp.data = outputBmp.data; + outputBmp.data = t; + + int x,y,i,j,start,end; + int step = outWidth*2; + for(x=0,i=0,j=outWidth*(outHeight-1)*2;x<outWidth;x++,i+=2,j+=2) { + fadePixelHeat(x,0,i,step); + fadePixelHeat(x,0,i+1,step); + fadePixelHeat(x,outHeight-1,j,step); + fadePixelHeat(x,outHeight-1,j+1,step); + } + + for(y=1,i=outWidth*2,j=outWidth*4-2;y<outHeight;y++,i+=step,j+=step) { + fadePixelHeat(0,y,i,step); + fadePixelHeat(0,y,i+1,step); + fadePixelHeat(outWidth-1,y,j,step); + fadePixelHeat(outWidth-1,y,j+1,step); + } + + for(y=1, + start=outWidth*2+2, + end=outWidth*4-2; y<outHeight-1; y++,start+=step,end+=step) { + int i = start; + do { + short j = + ( short(lastOutput[i-2])+ + lastOutput[i+2]+ + +lastOutput[i-step] + +lastOutput[i+step] + >> 2) + +lastOutput[i]; + if (!j) { + ucoutput[i] = 0; + } else { + j = j + -lastLastOutput[i] + +(lastLastOutput[i] + -lastOutput[i]>>2) + -1; + if (j < 0) ucoutput[i] = 0; + else if (j & (255*256)) ucoutput[i] = 255; + else ucoutput[i] = j; + } + } while(++i < end); + } +} + +void fade() { + switch(fadeMode) { + case Stars : + fadeFade(); + break; + case Flame : + fadeHeat(); + break; + case Wave : + fadeWave(); + break; + default: + break; + } +} + +int coreGo() { + double x[n], y[n]; + double a[n], b[n]; + int clarity[n]; //Surround sound + int i,j,k; + + int brightFactor = int(brightness * brightnessTwiddler /(starSize+0.01)); + + if (-1 == getNextFragment()) + { + fprintf(stderr, "no frag\n" ); + return -1; + } + + for(i=0;i<n;i++) { + x[i] = data[i*2]; + y[i] = data[i*2+1]; + } + + fft(x,y); + + for(i=0 +1;i<n;i++) { + double x1 = x[bitReverse[i]], + y1 = y[bitReverse[i]], + x2 = x[bitReverse[n-i]], + y2 = y[bitReverse[n-i]], + aa,bb; + a[i] = sqrt(aa= (x1+x2)*(x1+x2) + (y1-y2)*(y1-y2) ); + b[i] = sqrt(bb= (x1-x2)*(x1-x2) + (y1+y2)*(y1+y2) ); + if (aa+bb != 0.0) + clarity[i] = (int)( + ( (x1+x2) * (x1-x2) + (y1+y2) * (y1-y2) )/(aa+bb) * 256 ); + else + clarity[i] = 0; + } + + // Asger Alstrupt's optimized 32 bit fade + // (alstrup@diku.dk) + /*register unsigned long *ptr = (unsigned long*)output; + i = outWidth*outHeight*2/4; + do { + //Bytewize version was: *(ptr++) -= *ptr+(*ptr>>1)>>4; + if (*ptr) + if (*ptr & 0xf0f0f0f0ul) + *(ptr++) -= ((*ptr & 0xf0f0f0f0ul) >> 4) + ((*ptr & 0xe0e0e0e0ul) >> 5); + else { + *(ptr++) = (*ptr * 14 >> 4) & 0x0f0f0f0ful; + //Should be 29/32 to be consistent. Who cares. This is totally + // hacked anyway. + //unsigned char *subptr = (unsigned char*)(ptr++); + //subptr[0] = (int)subptr[0] * 29 / 32; + //subptr[1] = (int)subptr[0] * 29 / 32; + //subptr[2] = (int)subptr[0] * 29 / 32; + //subptr[3] = (int)subptr[0] * 29 / 32; + } + else + ptr++; + } while(--i > 0); + */ + + int heightFactor = n/2 / outHeight + 1; + int actualHeight = n/2/heightFactor; + int heightAdd = outHeight + actualHeight >> 1; + + /* Correct for window size */ + double brightFactor2 = (brightFactor/65536.0/n)* + sqrt(actualHeight*outWidth/(320.0*200.0)); + + for(i=1;i<n/2;i++) { + //int h = (int)( b[i]*280 / (a[i]+b[i]+0.0001)+20 ); + if (a[i] > 0 || b[i] > 0) { + int h = (int)( b[i]*outWidth / (a[i]+b[i]) ); + int br1, br2, br = (int)( + (a[i]+b[i])*i*brightFactor2 ); + br1 = br*(clarity[i]+128)>>8; + br2 = br*(128-clarity[i])>>8; + if (br1 < 0) br1 = 0; else if (br1 > 255) br1 = 255; + if (br2 < 0) br2 = 0; else if (br2 > 255) br2 = 255; + //unsigned char *p = output+ h*2+(164-((i<<8)>>m))*(outWidth*2); + int px = h, + py = heightAdd - i / heightFactor; + + if (pointsAreDiamonds) { + addPixel(px,py,br1,br2); + br1=scaleDown[br1];br2=scaleDown[br2]; + + //TODO: Use addpixelfast + for(j=1;br1>0||br2>0;j++,br1=scaleDown[br1],br2=scaleDown[br2]) { + for(k=0;k<j;k++) { + addPixel(px-j+k,py-k,br1,br2); + addPixel(px+k,py-j+k,br1,br2); + addPixel(px+j-k,py+k,br1,br2); + addPixel(px-k,py+j-k,br1,br2); + } + } + } else { + if (px < maxStarRadius || py < maxStarRadius || + px > outWidth-maxStarRadius || py > outHeight-maxStarRadius) { + addPixel(px,py,br1,br2); + for(j=1;br1>0||br2>0;j++,br1=scaleDown[br1],br2=scaleDown[br2]) { + addPixel(px+j,py,br1,br2); + addPixel(px,py+j,br1,br2); + addPixel(px-j,py,br1,br2); + addPixel(px,py-j,br1,br2); + } + } else { + unsigned char *p = ucoutput+px*2+py*outWidth*2, *p1=p, *p2=p, *p3=p, *p4=p; + addPixelFast(p,br1,br2); + for(;br1>0||br2>0;br1=scaleDown[br1],br2=scaleDown[br2]) { + p1 += 2; + addPixelFast(p1,br1,br2); + p2 -= 2; + addPixelFast(p2,br1,br2); + p3 += outWidth*2; + addPixelFast(p3,br1,br2); + p4 -= outWidth*2; + addPixelFast(p4,br1,br2); + } + } + } + } + } + return 0; +} diff --git a/kscd/kscdmagic/logo.h b/kscd/kscdmagic/logo.h new file mode 100644 index 00000000..478f8c70 --- /dev/null +++ b/kscd/kscdmagic/logo.h @@ -0,0 +1,50 @@ +int logo[48][48] = { +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,17,0,0,0,17,17,0,0,17,0,0,0,17,0,17,17,17,0,0,0,17,0,0,0,17,17,0,0,17,17,17}, +{0,0,0,0,0,0,0,0,17,17,17,17,17,0,0,17,0,0,17,0,17,0,0,17,0,17,17,0,17,17,0,17,0,0,17,0,17,0,17,0,17,0,0,17,0,0,17,0}, +{0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,17,0,0,0,0,17,0,0,17,0,17,0,17,0,17,0,17,0,0,17,0,17,0,17,0,17,0,0,0,0,0,17,0}, +{0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,17,0,0,17,0,17,0,0,17,0,17,0,17,0,17,0,17,17,17,0,0,17,17,17,0,17,0,0,17,0,0,17,0}, +{0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,0,17,17,0,0,0,17,17,0,0,17,0,0,0,17,0,17,0,0,0,0,17,0,17,0,0,17,17,0,0,0,17,0}, +{0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,17,17,17,17,17,17,17,0,0,0,17,0,0,17,17,17,17,17,0,0,0,0,17,17,17,17,17,17,17,17,17,17,0,0,0,0,17,17,17,17,17,17,17,17,0,0}, +{0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,17,0,0,0,17,0,0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,0,0,0,0,0,0,17,0}, +{17,0,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17}, +{17,0,0,0,0,17,17,17,0,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,0,17,17,0,0,0,0,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,17,17,17,17,17,17,17,17,0,0,17,0,0,0,17,0,0,17,0,0,0,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,17,17,17,17,17,17,0,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,17,17,17,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,17,0,0,0,0,0,0,0}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,0,17,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,17,0,0,17,17,17,17,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,0,0,17,17,17,17,17,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,17}, +{17,0,0,0,17,0,0,0,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,17,17,17,17,17,17,17,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,17}, +{17,0,0,0,0,17,17,17,0,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,0,17,17,0,0,0,0,17}, +{17,0,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,0,17}, +{0,17,0,0,0,0,0,0,0,0,0,0,17,0,0,17,0,0,0,17,0,0,17,0,0,0,0,0,0,0,0,0,17,0,0,0,0,17,0,0,0,0,0,0,0,0,17,0}, +{0,0,17,17,17,17,17,17,17,17,17,17,17,0,0,17,17,17,17,17,0,0,17,17,17,17,17,17,17,17,17,17,0,0,0,0,0,0,17,17,17,17,17,17,17,17,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{17,17,17,0,0,17,0,0,17,17,17,0,17,0,17,17,17,0,0,17,0,0,17,0,0,0,0,0,0,17,0,0,17,0,0,17,0,17,17,17,0,0,17,0,0,17,17,0}, +{17,0,0,17,0,17,0,17,0,0,0,0,17,0,0,17,0,0,17,0,17,0,17,0,0,0,0,0,17,0,17,0,17,0,0,17,0,17,0,0,17,0,17,0,17,0,0,17}, +{17,0,0,17,0,17,0,17,0,17,17,0,17,0,0,17,0,0,17,0,17,0,17,0,0,0,0,0,17,0,17,0,17,0,0,17,0,17,0,0,17,0,17,0,17,0,0,17}, +{17,0,0,17,0,17,0,17,0,0,17,0,17,0,0,17,0,0,17,17,17,0,17,0,0,0,0,0,17,17,17,0,17,0,0,17,0,17,0,0,17,0,17,0,17,0,0,17}, +{17,17,17,0,0,17,0,0,17,17,17,0,17,0,0,17,0,0,17,0,17,0,17,17,17,0,0,0,17,0,17,0,0,17,17,0,0,17,17,17,0,0,17,0,0,17,17,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +}; diff --git a/kscd/kscdmagic/magicconf.h b/kscd/kscdmagic/magicconf.h new file mode 100644 index 00000000..86ed42de --- /dev/null +++ b/kscd/kscdmagic/magicconf.h @@ -0,0 +1,23 @@ + +#ifndef __MAGIC_CONF_H_ +#define __MAGIC_CONF_H_ + +/***************************************/ +/* For the incurably fiddle prone: */ + +/* log2 of sample size */ +#define m 8 + +/* overlap amount between samples. Set to 1 or 2 if you have a fast computer */ +#define overlap 0 + +/* Brightness */ +#define brightness 150 + +/* Sample frequency*/ +#define frequency 22050 + +#define MITSHM 1 /* use MIT X11 shared memory*/ + +/***************************************/ +#endif diff --git a/kscd/kscdmagic/main.cpp b/kscd/kscdmagic/main.cpp new file mode 100644 index 00000000..7196d3a2 --- /dev/null +++ b/kscd/kscdmagic/main.cpp @@ -0,0 +1,300 @@ +/* + + $Id$ + + kscdmagic 2.0 Dirk Försterling <milliByte@gmx.de> + + based on: + + kscdmagic 1.0 Bernd Johannes Wuebben <wuebben@kde.org> + + based on: + + Synaesthesia - program to display sound graphically + Copyright (C) 1997 Paul Francis Harrison + + This program 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 2 of the License, or (at your + option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author may be contacted at: + pfh@yoyo.cc.monash.edu.au + 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia + +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> + +#if defined(__linux__) || defined(__svr4__) || defined(__osf__) + +#include <signal.h> +#include <time.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <pwd.h> +#include <string.h> +#if defined(__linux__) +#include <getopt.h> +#endif + +#include <klocale.h> +#include <kglobal.h> +#include <kapplication.h> +#include <kaboutdata.h> +#include <dcopclient.h> +#include <kcmdlineargs.h> + +#include "logo.h" +#include "magicconf.h" +#include "syna.h" +#include "version.h" + +volatile short *data; + +int outWidth, outHeight; +double brightnessTwiddler; +SymbolID fadeMode = Stars; +double starSize = 0.125; +bool pointsAreDiamonds = true; + + +const int numRows = 4; +const int rowHeight = 50; +const int leftColWidth = 40; +const int rowMaxWidth = 310; +const int sliderBorder = 20; +const int sliderWidth = rowMaxWidth - leftColWidth - sliderBorder*2; +const int numberSpacing = 15; +const int uiWidth = 330; +const int uiHeight = 135; + + +static int isExpanded = 0; +static double bright = 1.0; + +Bitmap<unsigned short> outputBmp, lastOutputBmp, lastLastOutputBmp; +PolygonEngine<unsigned short,combiner,2> polygonEngine; + +void +allocOutput(int w,int h) +{ + outputBmp.size(w,h); + lastOutputBmp.size(w,h); + lastLastOutputBmp.size(w,h); + polygonEngine.size(w,h); + outWidth = w; + outHeight = h; +} // allocOutput() + +void +setBrightness(double bright) +{ + brightnessTwiddler = bright; +} // setBrightness() + + + +static void +cleanup( int sig ) +{ + (void) sig; + closeSound(); + exit(0); +} // cleanup() + + +// make sure the pid file is cleaned up when exiting unexpectedly. + +void +catchSignals() +{ + signal(SIGHUP, cleanup); /* Hangup */ + signal(SIGINT, cleanup); /* Interrupt */ + signal(SIGTERM, cleanup); /* Terminate */ + signal(SIGPIPE, cleanup); + signal(SIGQUIT, cleanup); +} // catchSignals() + +void +usage(char*) +{ + fprintf(stderr, "Valid command line options:\n"); + fprintf(stderr, " -b set brightness (1 - 10)\n"); + fprintf(stderr, " -w set width\n"); + fprintf(stderr, " -h set height\n"); + exit(1); +} // usage() + +void +error(const char *str, bool syscall) { + fprintf(stderr, PROGNAME ": Error %s\n",str); + if (syscall) + fprintf(stderr,"(reason for error: %s)\n",strerror(errno)); + exit(1); +} // error() + +void +warning(const char *str, bool syscall) { + fprintf(stderr, PROGNAME ": Possible error %s\n",str); + if (syscall) + fprintf(stderr,"(reason for error: %s)\n",strerror(errno)); +} // warning() + + + +int +processUserInput() +{ + + int mouseX, mouseY, mouseButtons; + char keyHit; + + inputUpdate(mouseX,mouseY,mouseButtons,keyHit); + + if( keyHit == 'q' ) + return -1; + + + if (sizeUpdate()) + { + isExpanded = 0; + } + + return 0; +} // processUserInput() + +int +main(int argc, char **argv) +{ + int windX=10; + int windY=30; + int windWidth=uiWidth; + int windHeight=uiHeight; + int c; + int xx, xy; + opterr = 0; + + /* + KAboutData aboutData( "kscdmagic", I18N_NOOP("kscdmagic"), + KSCDMAGICVERSION, I18N_NOOP("sound visualisation"), + KAboutData::License_GPL, + "(c) 2000, Dirk Försterling"); + aboutData.addAuthor("Paul Harrison",0, "pfh@yoyo.cc.monash.edu.au"); + aboutData.addAuthor("Dirk Försterling",0, "milliByte@gmx.net"); + + KCmdLineArgs::init( argc, argv, &aboutData ); + + KApplication magicApp; + */ + + + openSound(SourceCD, 44100, "/dev/dsp", NULL); + + catchSignals(); + + while ((c = getopt(argc, argv, "b:h:w:")) != -1){ + switch (c) + { + case '?': + fprintf(stderr, "%s: unknown option \"%s\"\n", + argv[0], argv[optind-1]); + usage(argv[0]); + exit(1); + case 'b': + bright = (double) atoi(optarg); + bright = bright/10; + break; + case 'w': + windWidth = atoi(optarg); + break; + case 'h': + windHeight = atoi(optarg); + break; + } + } + + if (bright > 1.0) + bright = 1.0; + else if (bright < 0.0) + bright = 0.0; + + if (windWidth < 1) + windWidth = uiWidth; + if (windHeight < 1) + windHeight = uiHeight; + + screenInit(windX,windY,windWidth,windHeight); + + allocOutput(outWidth,outHeight); + + coreInit(); + + + setStarSize(starSize); + setBrightness(bright); + + time_t timer = time(NULL); + + int frames = 0; + + for(;;) { + fade(); + if (-1 == coreGo()) + break; + + polygonEngine.clear(); + + for( xy = 0; xy < 48; xy++) + { + for( xx = 0; xx < 48; xx++) + { + if ( logo[xy][xx] != 0) + { + polygonEngine.add(32769, xx+10, xy+3); + } + } + } + polygonEngine.apply(outputBmp.data); + screenShow(); + + + + frames++; + if(processUserInput() == -1) + break; + } + + + timer = time(NULL) - timer; + delete ucoutput; + closeSound(); + + if (timer > 10) + fprintf(stderr,"Frames per second: %f\n", double(frames)/timer); + + return 0; +} // main() /* linux */ + +#else + +int main() +{ + fprintf(stderr,"KSCD Magic works currently only on Linux.\n"\ + "It should however be trivial to port it to other platforms ...\n"); +} // main() /* non-linux */ + +#endif + diff --git a/kscd/kscdmagic/polygon.h b/kscd/kscdmagic/polygon.h new file mode 100644 index 00000000..4337ab10 --- /dev/null +++ b/kscd/kscdmagic/polygon.h @@ -0,0 +1,106 @@ +#include <string.h> + +template<class Pixel,int extra=0> +struct Bitmap { + Pixel *data; + int width, height; + + Bitmap() : data(0) { }; + ~Bitmap() { delete[] data; }; + + void size(int w,int h) { + delete[] data; + width = w; + height = h; + data = new Pixel[w*h+extra]; + clear(); + } + + void clear() { + memset(data,0,sizeof(Pixel)*(width*height+extra)); + } +}; + +template<class Pixel, Pixel combine(Pixel a,Pixel b), int superSampleShift> +struct PolygonEngine : public Bitmap<Pixel,1> { +#define super (1<<superSampleShift) + void apply(Pixel *dest) { + /* Pixel sum=0; */ + int count = width*height; + Pixel *src = data; + /* + * I don't really want this. + * + while(count--) { + sum += *(src++); + if (sum) + *dest = combine(sum,*dest); + dest++; + } + */ + while(count--) + { + *dest = combine(*src, *dest); + src++; + dest++; + } + } + + void add(Pixel color,int x,int y) { + if (y < 0) return; + if (y >= height) return; + if (x < 0) x = 0; + if (x > width) x = width; + data[x+y*width] += color; + } + + /* Color is char[layers] */ + + // zwoosh, yknow, it goes... zwoosh an all these bars and lines and + // crap intersect. + Pixel colorTable[2][super+1]; + void pen(Pixel color) { + for(int i=0;i<super+1;i++) { + colorTable[0][i] = color*i; + colorTable[1][i] = -(color*i); + } + } + + void line(int x1,int y1,int x2,int y2) { + Pixel *colors; + if (y2 < y1) { + int temp; + temp = x2; x2 = x1; x1 = temp; + temp = y2; y2 = y1; y1 = temp; + colors = colorTable[1]; + } else { + if (y1 == y2) return; + + colors= colorTable[0]; + } + + int slope = (x1-x2 << 16)/(y1-y2); + int x = x1<<16, y = y1; + while(y < y2) { + add(colors[super-((x>>16)&(super-1))], + x>>(16+superSampleShift),y>>superSampleShift); + add(colors[(x>>16)&(super-1)], + 1+(x>>(16+superSampleShift)),y>>superSampleShift); + x += slope; + y++; + } + } + + void icon(double icon[][4],Pixel color,double x,double y, + double scaleX, double scaleY) { + pen(color); + x *= super; + y *= super; + scaleX *= super; + scaleY *= super; + for(int i=0;icon[i][1] != icon[i][3];i++) + line(int(icon[i][0]*scaleX+x),int(icon[i][1]*scaleY+y), + int(icon[i][2]*scaleX+x),int(icon[i][3]*scaleY+y)); + } +#undef super +}; diff --git a/kscd/kscdmagic/sound.cpp b/kscd/kscdmagic/sound.cpp new file mode 100644 index 00000000..0bcb8d8d --- /dev/null +++ b/kscd/kscdmagic/sound.cpp @@ -0,0 +1,252 @@ +/* Synaesthesia - program to display sound graphically + Copyright (C) 1997 Paul Francis Harrison + + This program 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 2 of the License, or (at your + option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author may be contacted at: + pfh@yoyo.cc.monash.edu.au + or + 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia +*/ + +#if defined(__linux__) || defined(__svr4__) + +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <sys/shm.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <unistd.h> +#include <signal.h> + +#if defined (__linux__) +#include <linux/soundcard.h> +#ifndef __GNUC__ +#define __GNUC__ 1 +#endif +#undef __STRICT_ANSI__ +#include <asm/types.h> +#include <linux/cdrom.h> +#endif + +#if defined (__svr4__) +#include <sys/soundcard.h> +#endif + + +// who knows when we'll need that... +#if defined (FreeBSD) +#include <sys/soundcard.h> +#include <sys/cdio.h> +#define CDROM_LEADOUT 0xAA +#define CD_FRAMES 75 /* frames per second */ +#define CDROM_DATA_TRACK 0x4 +#endif + +#include <time.h> + +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include "syna.h" +#include "magicconf.h" + + +/* Sound Recording ================================================= */ + +#ifdef LITTLEENDIAN +#define SOUNDFORMAT AFMT_S16_LE +#else +#define SOUNDFORMAT AFMT_S16_BE +#endif + +//If kernel starts running out of sound memory playing mp3s, this could +//be the problem. OTOH if it is too small, it will start ticking on slow +//computers +#define MAXWINDOWSIZE 32 + +static SoundSource source; +static int inFrequency, downFactor, windowSize, pipeIn, device; +static short *dataIn; +static char *mixer; + +void +openSound(SoundSource source, int inFrequency, const char *dspName, + char *mixerName) +{ + ::source = source; + ::inFrequency = inFrequency; + ::windowSize = 1; + mixer = mixerName; + downFactor = inFrequency / frequency; + if (downFactor <= 0) + downFactor = 1; + + int format, stereo, fragment, fqc; + +#ifdef __FreeBSD__ + attempt(device = open(dspName,O_WRONLY),"opening dsp device",true); + format = SOUNDFORMAT; + attempt(ioctl(device,SNDCTL_DSP_SETFMT,&format),"setting format",true); + if (format != SOUNDFORMAT) error("setting format (2)"); + close(device); +#endif + if (source == SourcePipe) + attempt(device = open(dspName,O_WRONLY),"opening dsp device",true); + else + attempt(device = open(dspName,O_RDONLY),"opening dsp device",true); + + //Probably not needed + //attemptNoDie(ioctl(device,SNDCTL_DSP_RESET,0),"reseting dsp"); + format = SOUNDFORMAT; + fqc = (source == SourcePipe ? inFrequency : frequency); + stereo = 1; + + //int logWindowSize = -1, tmp = windowSize*downFactor; + //while(tmp) { + // tmp /= 2; + // logWindowSize++; + //} + + if (source == SourcePipe) + //fragment = 0x00020000 + (m-overlap+1)+logWindowSize; + fragment = 0x00010000*(MAXWINDOWSIZE+1) + (m-overlap+1);//+logWindowSize; + //Soundcard should read in windowSize + // blocks of sound before blocking + else + //fragment = 0x00020000 + (m-overlap+1); //2 fragments of size 2*(2^(m-overlap+1)) bytes + + //Added extra fragments to allow recording overrun (9/7/98) + fragment = 0x00080000 + (m-overlap+1); //8 fragments of size 2*(2^(m-overlap+1)) bytes + + + + + //Was 0x00010000 + m; + + attemptNoDie(ioctl(device,SNDCTL_DSP_SETFRAGMENT,&fragment),"setting fragment",true); +#ifndef __FreeBSD__ + attempt(ioctl(device,SNDCTL_DSP_SETFMT,&format),"setting format",true); + if (format != SOUNDFORMAT) error("setting format (2)"); +#endif + attempt(ioctl(device,SNDCTL_DSP_STEREO,&stereo),"setting stereo",true); + attemptNoDie(ioctl(device,SNDCTL_DSP_SPEED,&fqc),"setting frequency",true); + + data = new short[n*2]; + + if (source == SourcePipe) { + dataIn = new short[n*2*downFactor*MAXWINDOWSIZE]; + memset(dataIn,0,n*4*downFactor*MAXWINDOWSIZE); + pipeIn = dup(0); + close(0); + } +} + +void closeSound() { + delete data; + if (source == SourcePipe) { + delete dataIn; + close(pipeIn); + } + close(device); +} + +int readWholeBlock(int pipe,char *dest,int length) { + while(length > 0) { + int result = read(pipe,dest,length); + if (result < 1) + return -1; + dest += result; + length -= result; + } + return 0; +} + +int getNextFragment(void) { + if (source == SourcePipe) { + static int lastTime = 0; + int nowTime; + timeval timeVal1, timeVal2; + + gettimeofday(&timeVal1,0); + write(device, (char*)dataIn, n*4*downFactor*windowSize); + gettimeofday(&timeVal2,0); + + nowTime = timeVal1.tv_usec + timeVal1.tv_sec * 1000000; + if (nowTime > lastTime) { + int optimumFrags = + int(double(nowTime-lastTime)*inFrequency/1000000.0/(n*downFactor)) + +1; + if (optimumFrags > MAXWINDOWSIZE) + optimumFrags = MAXWINDOWSIZE; + + windowSize = optimumFrags; + } + + lastTime = timeVal2.tv_usec + timeVal2.tv_sec * 1000000; + + if (readWholeBlock(pipeIn, ((char*)dataIn), n*4*downFactor*windowSize) == -1) + return -1; + + int i,j; + for(i=0,j=0;i<n;i++,j+=downFactor) + ((long*)data)[i] = ((long*)dataIn)[j]; + } else { + int i; + count_info info; + if (-1 == ioctl(device,SNDCTL_DSP_GETIPTR,&info)) + info.blocks = 1; + if (info.blocks > 8 || info.blocks < 1) /* Sanity check */ + info.blocks = 1; + + for(i=0;i<info.blocks;i++) { + if (recSize != n) + memmove((char*)data,(char*)data+recSize*4,(n-recSize)*4); + + attemptNoDie( + readWholeBlock(device,(char*)data+n*4-recSize*4, recSize*4), + "reading from soundcard", true); + } + } + return 0; +} + +#else + +// generic dummy implementation + +#include "syna.h" + +int getNextFragment(void) { + return 0; +} + +void openSound(SoundSource source, int inFrequency, const char *dspName, + char *mixerName) +{ +} + +void closeSound() +{ +} + +#endif // linux || svr4 + diff --git a/kscd/kscdmagic/symbol.h b/kscd/kscdmagic/symbol.h new file mode 100644 index 00000000..aad04f47 --- /dev/null +++ b/kscd/kscdmagic/symbol.h @@ -0,0 +1,1028 @@ +#ifndef __SYNAES_SYMBOL_H__ +#define __SYNAES_SYMBOL_H__ +#if defined(__linux__) || defined(__svr4__) + +#define SYMBOLSWIDTH 586 +#define SYMBOLSHEIGHT 50 +unsigned char Symbols[586*50] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,241,72,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,13,30,37,31,24,5,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,132,254,237,72,0,0,0,0,0,0,0,0,0,0,0,1,7,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,46,0,0,0,0,0,0,0,0,0,0,0,0,0,10,87, + 176,225,244,246,244,238,206,135,39,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254, + 254,236,73,0,0,0,0,0,0,0,0,0,0,3,154,138,58,9,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,36,211,80,0,0,0,0,0,0,0,0,0,0,0,2,77,204,252,254,254,254, + 254,254,254,254,254,239,145,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255,245, + 215,72,0,0,0,0,0,0,0,0,0,0,115,254,249,213,138,58,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,36,212,253,80,0,0,0,0,0,0,0,0,0,0,7,136,247,254,254,254,254, + 254,254,254,254,254,254,254,254,208,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254, + 255,225,66,210,72,0,0,0,0,0,0,0,0,0,40,244,254,254,254,249,214,137,57,8, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,37,212,254,254,80,0,0,0,0,0,0,0,0,0,4,150,253,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,227,50,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,132,254,255,225,10,55,217,71,0,0,0,0,0,0,0,0,4,194,254,255,255, + 255,255,254,250,214,137,57,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,211,254,254,254,80,0,0, + 0,0,0,0,0,0,0,100,250,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,203,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255,225,10,1,196,187,1, + 0,0,0,0,0,0,0,0,115,254,255,255,255,255,255,254,254,254,249,212,137,57, + 10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,36,211,254,254,254,254,80,0,0,0,0,0,0,0,0,29,230,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,255,255,254,130,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,41,244,255,255, + 255,255,255,255,255,255,254,254,254,249,212,137,58,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,212,254,254,254, + 254,254,80,0,0,0,0,0,0,0,0,134,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,255,255,255,232,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255, + 225,10,1,196,190,1,0,0,0,0,0,0,0,0,4,196,254,255,255,255,255,255,255,255, + 255,255,255,255,254,254,249,212,137,57,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,212,254,254,254,254,254,254,80,0,0, + 0,0,0,0,0,16,225,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,255,255,255,254,112,0,0,0,0,0,0,0,3,12,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16, + 0,0,0,0,0,0,7,9,0,0,0,0,0,0,0,0,0,0,0,0,111,155,155,111,0,0,0,16,148,155, + 155,58,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,132,254, + 255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,115,253,254,255,255,255,255,255, + 255,255,255,255,255,255,255,254,254,254,250,194,15,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,7,147,99,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,38,179, + 38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,211,254,254,254,254,254, + 254,254,80,0,0,0,0,0,0,0,62,251,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,255,255,255,254,182,1,0,0,0,0,0,0,18,171,19,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,1,162,44,0,0,0,0,0,37,159,11,0,0,0,0,0,0,0,0,0,0,1,182,254, + 254,182,1,0,0,27,243,254,254,96,0,0,0,0,0,0,0,0,0,0,0,23,136,1,0,0,0,0, + 0,68,92,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0, + 40,244,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254, + 232,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,151,253,245,99,1,0,0, + 6,50,106,155,166,174,166,162,115,52,11,0,0,0,38,213,254,213,39,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,210,254,254,254,254,254,254,254,254,80, + 0,0,0,0,0,0,0,108,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,255,255,255,254,223,9,0,0,0,0,0,0,18,239,185,19,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,197,219,45,0,0,0,0,38,246,166,11,0,0,0,0,0,0,0,0,0,1,182,254,254, + 182,1,0,0,27,243,254,254,96,0,0,0,0,0,0,0,0,0,0,23,192,196,1,0,0,0,0,68, + 233,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0, + 4,196,254,255,255,255,255,255,255,255,255,255,255,255,255,255,254,232,65, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,180,252,255,254,244,95,10,97, + 197,248,254,254,255,255,255,254,254,248,210,118,20,36,212,254,255,254,213, + 39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,211,254,254,254,254,254,254,254, + 254,254,80,0,0,0,0,0,0,0,117,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,255,255,255,255,228,11,0,0,0,0,0,0,18,240,254,185, + 19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,0,0,0,0,0,0,0,1,197,254,218,44,0,0,0,38,247,253,165,11,0,0,0,0,0,0, + 0,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0,0,0,0,0,0,0,0,0,23,192, + 254,196,1,0,0,0,67,234,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190, + 1,0,0,0,0,0,0,0,0,0,0,116,254,255,255,255,255,255,255,255,255,255,255,255, + 255,254,233,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,186,254,255, + 254,254,225,74,34,220,254,254,255,255,255,255,255,255,255,254,254,248,95, + 44,205,254,254,255,254,213,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,211,254, + 254,254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,122,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,228, + 11,0,0,0,0,0,0,18,240,254,254,186,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 17,187,197,197,197,197,197,195,46,0,0,0,0,0,0,0,142,197,197,197,197,197, + 197,107,0,0,0,0,0,0,0,81,196,197,197,197,197,197,197,197,197,197,197,197, + 197,197,197,197,197,197,197,197,197,194,37,0,0,0,0,0,0,1,197,254,254,219, + 44,0,0,38,247,254,253,165,11,0,0,0,0,0,0,0,1,182,254,254,182,1,0,0,27,243, + 254,254,96,0,0,0,0,0,0,0,0,22,192,254,254,196,1,0,0,66,235,254,254,111, + 0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,39,246, + 254,255,255,255,255,255,255,255,255,255,255,254,234,64,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,17,187,254,255,254,254,204,34,0,0,47,222,254,254, + 255,255,255,255,255,255,254,248,113,2,0,18,175,254,254,255,254,214,36,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,36,211,254,254,254,254,254,254,254,254,254,254, + 254,80,0,0,0,0,0,0,0,114,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,255,255,255,254,227,11,0,0,0,0,0,0,18,240,255,254,254, + 185,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60, + 0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,251,47,0,0,0,0,0,0,1,197,254,254,254,220,43,0,38,247,254,254,253,166, + 11,0,0,0,0,0,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0,0,0,0,0,0,0, + 22,193,254,254,254,196,1,0,67,234,254,255,254,111,0,0,0,0,0,0,0,132,254, + 255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,3,196,254,255,255,255,255,255, + 255,255,255,255,255,236,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29, + 211,254,255,254,204,30,0,0,0,0,47,221,254,255,255,255,255,255,254,243,112, + 2,0,0,0,14,175,253,255,254,231,54,0,0,0,0,0,0,1,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,5,5,1, + 0,0,0,0,0,0,0,0,0,0,0,5,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,210,254,255, + 254,254,254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,74,253,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,254, + 194,2,0,0,0,0,0,0,18,240,255,255,255,254,184,19,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,23,242,255,255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254, + 254,254,138,0,0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254, + 254,254,219,44,38,247,254,254,254,253,166,11,0,0,0,0,0,1,182,254,254,182, + 1,0,0,27,243,254,254,96,0,0,0,0,0,0,23,192,254,254,254,254,196,1,68,233, + 254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0, + 0,0,0,0,0,0,0,0,116,254,255,255,255,255,255,255,255,255,255,255,231,53, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,210,254,225,33,0,0,0,0,0, + 0,48,221,254,254,255,255,254,237,78,1,0,0,0,0,0,15,198,254,231,61,0,0,0, + 0,0,0,0,73,213,214,214,214,214,214,214,214,213,214,214,214,214,214,214, + 214,214,214,214,214,214,214,214,213,214,214,214,214,214,214,214,214,214, + 156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,8,145,213,214,213,133,5,0,0,0,0,0,0,0,0,0,88,211,213, + 214,181,24,0,0,0,0,3,11,11,11,11,11,11,11,40,210,254,255,255,254,254,254, + 254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,26,235,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,255,255,255,254,131,0,0,0,0, + 0,0,0,18,240,255,255,255,254,254,184,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, + 242,255,255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254, + 138,0,0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254, + 254,218,83,247,254,254,254,254,253,165,11,0,0,0,0,1,182,254,254,182,1,0, + 0,27,243,254,254,96,0,0,0,0,0,23,191,254,254,254,254,254,197,69,233,254, + 254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0, + 0,0,0,0,0,0,0,0,40,245,255,255,255,255,255,255,255,255,255,255,254,226, + 52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,205,79,0,0,0,0,0,0,0, + 0,47,222,254,254,254,238,76,0,0,0,0,0,0,0,0,45,212,62,0,0,0,0,0,0,0,0,87, + 253,185,168,168,168,168,168,171,243,249,175,168,204,254,255,254,220,168, + 170,239,243,171,168,220,254,195,168,168,168,168,168,169,236,185,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,11,11,11,5, + 0,0,0,0,0,0,0,0,0,0,7,11,11,11,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,11,11,11,11,4,0,0,0,0,0,0,0,0,0,0,8,11,11,11,8,0,0,0,0,0, + 0,0,0,0,0,4,11,11,11,11,1,0,0,0,0,0,0,0,0,0,1,11,11,11,11,4,0,0,0,0,0,0, + 0,0,0,0,8,11,11,11,7,0,0,0,0,0,0,0,0,0,0,5,11,11,11,10,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,151,252,254,254,254,251,136,2,0, + 0,0,0,0,0,0,88,242,254,224,246,254,194,22,0,0,0,64,228,229,229,229,229, + 229,229,239,254,254,254,254,254,254,254,254,254,254,254,254,254,254,80, + 0,0,0,0,0,0,0,1,163,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,255,255,255,244,45,0,0,0,0,0,0,0,18,240,255,255,255,255,254, + 254,185,18,0,0,0,0,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60, + 0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,237,253,254,254,254, + 254,254,253,165,11,0,0,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0,0, + 0,0,22,191,254,254,254,254,254,254,233,235,254,254,254,255,255,254,111, + 0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,4,196, + 255,255,255,255,255,255,255,255,255,255,255,254,225,52,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,4,0,0,0,0,0,0,0,0,0,48,222,254,239,77,0, + 0,0,0,0,0,0,0,0,1,24,0,0,0,0,0,0,0,0,0,87,251,50,0,0,0,0,0,10,223,251,67, + 0,53,246,255,253,99,0,31,241,222,9,0,153,253,80,0,0,0,0,0,2,200,185,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,224,229, + 229,229,179,18,0,0,0,0,0,0,0,0,37,203,229,229,229,214,55,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,98,226,229,229,229,170,14,0,0,0,0,0,0, + 0,0,45,208,229,229,229,209,47,0,0,0,0,0,0,0,0,13,167,229,229,229,227,101, + 1,0,0,0,0,0,0,0,1,109,227,229,229,229,161,11,0,0,0,0,0,0,0,0,52,213,229, + 229,229,205,39,0,0,0,0,0,0,0,0,16,177,229,229,229,225,90,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65,251,254,255,255,255,255,238,15, + 0,0,0,0,0,0,11,225,254,207,34,104,247,253,80,0,0,0,71,253,255,255,255,255, + 254,254,254,255,255,255,255,254,254,254,254,254,254,254,254,254,254,80, + 0,0,0,0,0,0,0,0,49,243,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,255,255,254,161,1,0,0,0,0,0,0,0,18,240,255,255,255,255,254, + 254,254,185,18,0,0,0,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60, + 0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,253,165,11,0,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0, + 0,0,22,192,254,254,254,254,254,254,254,254,254,254,254,254,255,255,254, + 111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0, + 0,116,253,254,255,255,255,254,235,219,254,255,255,255,254,226,53,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,21,21,21,21,21,21,21,21,21, + 21,21,21,21,21,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,114,2,0,0,0,0,0, + 0,0,0,0,47,207,76,0,0,0,0,0,0,0,0,0,0,80,130,0,0,0,0,0,0,0,0,0,87,251,50, + 0,0,0,0,0,9,223,254,161,0,5,193,254,235,28,0,116,254,222,9,0,153,254,79, + 0,0,0,0,0,1,200,185,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,88,242,254,254,255,255,254,185,18,0,0,0,0,0,0,37,214,254,254, + 255,255,254,228,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,98,246,254, + 254,255,255,254,175,14,0,0,0,0,0,0,44,220,254,254,255,255,254,222,47,0, + 0,0,0,0,0,13,172,254,254,255,255,254,246,101,1,0,0,0,0,0,1,109,248,254, + 254,255,255,253,165,11,0,0,0,0,0,0,53,226,254,254,255,255,254,216,39,0, + 0,0,0,0,0,17,182,254,254,255,255,254,243,91,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,69,253,254,255,255,255,255,239,16,0,0,0,0,0,0,12, + 230,212,32,0,1,113,253,81,0,0,0,71,253,254,255,255,255,254,255,255,255, + 255,254,255,254,254,254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,0, + 2,141,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 229,36,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255,255,254,254,184,19,0, + 0,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60,0,0,0,0,0,0,1,183, + 254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,251,47,0,0,0,0, + 0,0,1,197,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,253, + 165,11,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0,0,22,192,254,254,254, + 254,254,254,254,254,254,254,254,254,254,255,255,254,111,0,0,0,0,0,0,0,132, + 254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,41,244,254,255,255,254, + 233,66,37,212,254,255,255,255,254,226,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,108,240,241,241,241,241,241,241,241,241,241,241,241,241, + 241,224,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,199,249,115,2,0,0,0,0,0,0,0, + 29,99,119,113,55,4,0,0,0,0,0,0,0,80,240,230,22,0,0,0,0,0,0,0,0,87,251,50, + 0,0,0,0,0,9,223,255,228,18,0,97,253,165,1,4,196,254,222,9,0,153,254,79, + 0,0,0,0,0,1,200,185,1,0,0,0,0,0,0,0,0,0,0,0,0,0,8,53,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,6,176,254,255,255,255,255,254,242,110,18,0,0,0,0,0,106,250,255, + 255,255,255,254,252,154,44,0,0,0,0,10,51,0,0,0,0,0,0,0,3,56,2,0,0,0,1,64, + 193,254,255,255,255,255,254,237,57,0,0,0,0,0,39,143,251,255,255,255,255, + 254,251,123,0,0,0,0,0,0,54,236,254,255,255,255,254,254,196,66,1,0,0,0,2, + 69,202,254,255,255,255,255,254,234,98,11,0,0,0,0,43,151,252,255,255,255, + 255,254,251,137,35,0,0,0,0,17,108,241,254,255,255,255,254,254,187,61,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,253,255,255,255,255,255, + 239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,71,253,254,255,255, + 255,254,255,255,254,255,254,255,254,254,254,254,254,254,254,254,254,254, + 80,0,0,0,0,0,0,0,0,0,13,192,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,244,84,0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255,255, + 255,254,254,184,19,0,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60, + 0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,253,165,11,1,182,254,254,182,1,0,0,27,243,254,254,96, + 0,23,191,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255, + 254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0, + 0,0,0,4,196,254,255,254,233,66,0,0,37,211,254,255,255,255,254,225,34,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,219,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,254,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53, + 248,254,248,115,2,0,0,0,0,3,112,186,152,158,153,173,163,23,0,0,0,0,0,80, + 240,254,253,85,0,0,0,0,0,0,0,0,87,251,50,0,5,36,37,37,45,228,255,252,79, + 0,20,226,73,0,40,244,254,222,9,0,153,253,105,37,15,0,1,32,38,208,185,1, + 0,0,0,0,0,0,0,0,0,0,0,0,8,150,240,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,186, + 253,253,253,253,242,144,228,183,19,0,0,0,0,3,126,249,253,253,253,251,170, + 192,227,55,0,0,10,161,237,76,0,0,0,0,0,3,123,243,112,2,0,1,98,241,163,201, + 253,253,253,253,238,78,0,0,0,0,0,45,219,201,162,250,253,253,253,250,140, + 6,0,0,0,0,0,0,0,75,237,253,253,253,253,203,161,242,102,1,0,2,109,243,157, + 207,253,253,253,253,234,143,236,164,11,0,0,52,225,194,169,251,253,253,253, + 250,158,206,214,40,0,0,17,181,229,143,241,253,253,253,253,196,167,240,91, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,253,255,255,255,255,255, + 239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,71,253,254,255,255, + 255,254,254,255,254,255,254,254,254,254,254,254,254,254,254,254,254,254, + 80,0,0,0,0,0,0,0,0,0,0,24,188,253,254,254,254,254,254,254,254,254,254,254, + 254,254,237,97,1,0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255,255,255,254, + 254,254,184,18,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60,0,0, + 0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,253,164,12,182,254,254,182,1,0,0,27,243,254,254,96, + 22,191,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255, + 255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,116,254,254,233,66,0,0,0,0,37,212,254,255,254,253,161,9,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,109,253,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,234,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,109, + 254,254,254,248,115,2,0,0,0,113,161,193,249,253,252,224,149,171,14,0,0, + 0,80,239,254,255,254,154,0,0,0,0,0,0,0,0,87,251,50,0,38,240,247,247,247, + 253,255,254,165,1,0,115,12,0,121,254,255,222,9,0,153,254,249,247,102,0, + 8,214,247,253,185,1,0,0,0,0,0,0,0,0,0,0,0,2,145,252,254,241,58,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,17,67,68,68,68,93,228,254,254,171,2,0,0,0,0,3,59,68, + 68,68,73,190,254,254,226,27,3,156,253,254,237,48,0,0,0,0,115,250,254,247, + 86,0,87,245,254,251,135,67,68,68,68,46,0,0,0,0,0,34,219,254,254,192,67, + 68,68,68,62,6,0,0,0,0,0,0,0,0,0,45,68,68,68,68,149,251,254,245,74,0,99, + 247,254,250,126,67,68,68,68,105,237,254,253,146,0,41,225,254,254,182,66, + 68,68,68,78,205,254,254,211,15,7,179,254,254,229,78,68,68,68,68,158,252, + 254,243,63,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,69,253,254,254,254, + 254,254,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,71,253,254, + 255,255,255,254,255,255,255,255,255,255,254,254,254,254,254,254,254,254, + 254,254,80,0,0,0,0,0,0,0,0,0,0,0,11,133,239,254,254,254,254,254,254,254, + 254,254,252,200,55,0,0,0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255,255, + 255,255,255,254,254,185,17,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253, + 60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,253,165,193,254,254,182,1,0,0,27,243,254, + 254,118,191,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,41,244,234,65,0,0,0,0,0,0,36,213,254,253,161,10,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,219,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,254,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 159,254,255,255,254,248,115,2,0,31,186,194,254,255,255,254,254,238,162, + 105,0,0,80,239,254,255,255,255,201,3,0,0,0,0,0,0,0,87,251,50,0,16,102,116, + 246,254,255,255,255,236,26,0,10,0,7,208,254,255,222,9,0,153,255,255,254, + 106,0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,5,213,254,255,254,88,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,91,254,255,255,211,4,0,0,0,0,0,0,0, + 0,0,23,241,254,255,250,46,9,223,254,255,253,75,0,0,0,1,184,254,255,254, + 122,0,152,254,255,255,154,0,0,0,0,0,0,0,0,0,0,73,253,254,255,224,10,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,197,254,255,254,108,0,166,254,255,254, + 140,0,0,0,0,118,254,255,255,187,1,87,254,255,255,214,6,0,0,0,43,249,254, + 255,243,26,20,240,254,255,252,49,0,0,0,3,208,254,255,254,95,0,0,0,0,0,0, + 0,0,0,68,189,198,107,5,0,0,0,0,0,0,0,0,69,252,144,104,105,104,183,239,16, + 0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,71,253,254,255,255,255,254, + 255,255,255,255,255,255,254,254,254,254,254,254,254,254,254,254,80,0,0, + 0,0,0,0,0,0,0,0,0,0,0,37,147,225,249,254,254,253,252,242,193,87,8,0,0,0, + 0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255,255,255,255,255,255,254,254, + 184,18,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60,0,0,0,0,0,0,1,183, + 254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,251,47,0,0,0,0, + 0,0,1,197,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,252,254,254,182,1,0,0,27,243,254,254,242,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,254,111,0,0, + 0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,4,176, + 65,0,0,0,0,0,0,0,0,36,211,160,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,109,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,233,29,0,0,0,0,0,0,0,0,0,0,0,0,0,170,255,255,255,255,255,249,115, + 2,103,151,250,255,255,255,255,255,254,169,172,3,80,240,254,255,255,255, + 255,211,5,0,0,0,0,0,0,0,87,251,50,0,0,0,19,240,255,255,255,255,253,94,0, + 0,0,53,248,255,255,222,9,0,153,255,255,254,106,0,8,220,255,255,185,1,0, + 0,0,0,0,0,0,0,0,0,0,5,213,255,255,254,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,91,254,255,255,211,4,0,0,0,0,0,0,0,0,0,23,242,255,255,250,46,9, + 223,255,255,253,75,0,0,0,1,184,255,255,254,122,0,153,255,255,255,154,0, + 0,0,0,0,0,0,0,0,0,74,253,255,255,224,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,197,255,255,254,108,0,166,255,255,254,140,0,0,0,0,118,254,255,255, + 187,1,87,254,255,255,214,6,0,0,0,43,249,255,255,243,26,20,240,255,255,252, + 49,0,0,0,3,209,255,255,254,95,0,0,0,0,0,0,0,0,34,233,254,254,251,82,0,0, + 0,0,0,0,0,0,69,252,67,0,0,0,133,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55, + 252,81,0,0,0,71,253,254,255,255,254,254,254,255,254,255,254,254,254,254, + 254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,52, + 83,84,84,73,32,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255, + 255,255,255,255,255,254,254,254,156,2,0,0,0,0,0,0,23,242,255,255,255,255, + 255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0, + 104,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,182,1,0,0,27, + 243,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,26,10,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,218,254,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,254,135,0,0,0,0,0,0,0,0,0,0,0,0, + 1,178,255,255,255,255,255,255,249,112,123,158,254,255,255,255,255,255,254, + 187,177,81,240,254,255,255,255,255,255,211,5,0,0,0,0,0,0,0,87,251,50,0, + 0,0,19,240,255,255,255,255,254,161,0,0,0,116,254,255,255,222,9,0,153,255, + 255,254,106,0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,5,213,255,255,254, + 88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,91,254,255,255,211,4,0,0,0,0,0, + 0,0,0,0,23,242,255,255,250,46,9,223,255,255,253,75,0,0,0,1,184,255,255, + 254,122,0,153,255,255,255,154,0,0,0,0,0,0,0,0,0,0,74,253,255,255,224,10, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,197,255,255,254,108,0,166,255,255, + 254,140,0,0,0,0,118,254,255,255,187,1,87,254,255,255,214,6,0,0,0,43,249, + 255,255,243,26,20,240,255,255,252,49,0,0,0,3,209,255,255,254,95,0,0,0,0, + 0,0,0,0,72,253,255,254,254,136,0,0,0,0,0,0,0,0,69,252,121,73,73,73,168, + 239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,71,253,255,255,255, + 255,254,255,255,255,255,255,255,254,254,254,254,254,254,254,254,254,254, + 80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,18,240,255,255,255,255,255,255,255,255,255,255,255,254,218,43,0,0, + 0,0,0,0,0,23,242,255,255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254, + 254,254,254,138,0,0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,182,1,0,0,27,243,254,254,252,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,255,255,254,111,0,0,0,0,0,0,0,132, + 254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,108,251,253,253,253, + 253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,230,29, + 0,0,0,0,0,0,0,0,0,0,0,0,170,255,255,255,255,255,254,248,112,120,153,253, + 255,255,255,255,255,254,181,176,81,240,254,255,255,255,255,255,211,5,0, + 0,0,0,0,0,0,87,251,50,0,0,0,19,240,255,255,255,255,254,113,0,0,0,69,251, + 255,255,222,9,0,153,255,255,254,106,0,8,220,255,255,185,1,0,0,0,0,0,0,0, + 0,0,0,0,5,211,254,255,254,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,89,254, + 255,255,211,4,0,0,0,0,0,0,1,1,1,23,240,255,255,250,45,9,221,254,255,253, + 75,1,1,1,2,181,254,255,254,122,0,150,254,255,254,154,1,1,1,1,0,0,0,0,0, + 0,71,253,255,255,224,10,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,194,254,255, + 254,108,0,163,254,255,254,140,1,1,1,1,116,254,255,254,187,1,84,253,255, + 255,214,7,1,1,1,42,248,255,255,242,26,19,238,255,255,252,49,0,0,0,3,206, + 254,255,254,94,0,0,0,0,0,0,0,0,47,244,254,254,253,104,0,0,0,0,0,0,0,0,69, + 253,252,252,252,252,253,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0, + 0,0,71,253,254,255,255,255,254,255,255,255,255,255,255,254,254,254,254, + 254,254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,3,81,94,94,94,94,94, + 94,94,94,94,93,19,0,0,0,0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255,255, + 255,255,255,255,254,219,43,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253, + 60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,205,208,254,254,182,1,0,0,27,243,254, + 254,145,224,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,11,134,158,158,158,158,158,158,158,158,158,158,158,158, + 158,158,158,158,158,158,158,158,158,66,0,0,0,0,0,0,0,0,0,0,0,0,167,254, + 255,255,255,254,248,115,2,62,170,229,254,254,255,255,255,251,159,145,1, + 80,240,254,255,255,255,255,208,4,0,0,0,0,0,0,0,87,251,50,0,14,91,106,245, + 254,255,255,255,243,39,0,2,0,14,222,255,255,222,9,0,153,255,255,254,106, + 0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,0,90,243,254,214,32,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,54,184,190,190,190,155,195,254,250,124,1,0,0,0,0,17, + 161,190,190,190,176,157,250,254,187,14,1,101,246,254,210,142,190,190,190, + 188,140,235,254,229,52,0,46,222,254,240,136,187,190,190,190,127,4,0,0,0, + 0,14,174,254,252,162,169,190,190,190,167,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 75,239,254,224,43,0,54,227,254,236,135,187,190,190,190,148,208,254,247, + 100,0,17,184,254,251,156,173,190,190,190,169,168,253,253,167,7,2,123,250, + 254,190,15,0,0,0,0,85,242,254,218,35,0,0,0,0,0,0,0,0,1,115,233,237,163, + 14,0,0,0,0,0,0,0,0,69,252,114,63,63,63,164,239,16,0,0,0,0,0,0,12,230,146, + 0,0,0,55,252,81,0,0,0,71,253,254,255,255,255,254,255,255,254,255,254,255, + 254,254,254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,8,217, + 250,250,250,250,250,250,250,250,250,248,51,0,0,0,0,0,0,0,0,0,0,0,0,18,240, + 255,255,255,255,255,255,255,255,255,254,218,43,0,0,0,0,0,0,0,0,0,23,242, + 255,255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138, + 0,0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,204,31,182,254,254, + 182,1,0,0,27,243,254,254,96,49,223,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10, + 1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,245,252,250,250,250,250,250,250, + 250,250,250,250,250,250,250,250,250,250,250,250,250,254,127,0,0,0,0,0,0, + 0,0,0,0,0,0,121,254,255,255,254,248,115,2,0,5,170,149,242,254,254,254,252, + 181,184,44,0,0,80,239,254,254,255,254,166,0,0,0,0,0,0,0,0,87,251,50,0,38, + 243,250,250,250,254,254,254,187,4,0,82,6,0,144,254,254,222,9,0,153,255, + 255,254,106,0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,0,0,90,204,37,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,55,227,254,254,255,255,253,168,191,126,3,0,0, + 0,0,17,184,254,254,255,255,254,207,157,184,19,0,0,1,101,203,155,250,254, + 254,255,254,238,141,211,57,0,0,0,47,207,142,233,254,254,255,255,252,137, + 5,0,0,0,0,14,173,164,199,254,254,255,255,254,195,24,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,76,208,49,0,0,0,55,210,141,237,254,254,255,254,250,157,202,104, + 1,0,0,17,182,159,205,254,254,255,255,254,194,168,166,12,0,0,3,123,186,21, + 0,0,0,0,0,0,86,205,41,0,0,0,0,0,0,0,0,0,0,0,15,16,1,0,0,0,0,0,0,0,0,0,69, + 252,67,0,0,0,133,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,71, + 253,254,255,254,254,254,254,254,254,255,254,254,254,254,254,254,254,254, + 254,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,1,38,44,44,44,44,44,44,44,44, + 44,44,9,0,0,0,0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255,255,255,255, + 254,218,44,0,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60,0,0,0, + 0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,251, + 47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,204,30,1,182,254,254,182,1,0,0,27,243,254,254,96,0,49,223, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,254,111, + 0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31, + 245,137,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,62,243,127, + 0,0,0,0,0,0,0,0,0,0,0,0,65,251,254,254,248,115,2,0,0,0,27,177,159,174,192, + 185,159,183,80,0,0,0,0,80,239,254,254,254,99,0,0,0,0,0,0,0,0,87,251,50, + 0,6,43,44,44,52,229,254,253,98,0,11,209,53,0,56,249,254,222,9,0,153,255, + 255,254,106,0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,0,0,3,37,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,31,192,254,255,255,255,255,254,248,85,3,0,0,0,0,0, + 118,253,255,255,255,255,254,254,159,31,0,0,0,0,1,63,241,254,255,255,255, + 254,254,215,54,0,0,0,0,0,24,201,254,255,255,255,255,254,245,85,5,0,0,0, + 0,26,146,253,255,255,255,255,254,253,144,18,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 38,0,0,0,0,0,53,212,254,255,255,255,255,254,242,89,5,0,0,0,0,11,148,254, + 255,255,255,255,254,253,139,24,0,0,0,0,9,31,0,0,0,0,0,0,0,2,37,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,252,67,0,0,0,133,239,16,0,0, + 0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,71,253,254,255,255,255,254,255, + 255,255,255,255,255,254,254,254,254,254,254,254,254,254,254,80,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,240, + 255,255,255,255,255,255,255,254,218,44,0,0,0,0,0,0,0,0,0,0,0,23,242,255, + 255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0, + 0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254, + 254,254,254,254,254,254,254,254,254,254,254,204,30,0,1,182,254,254,182, + 1,0,0,27,243,254,254,96,0,0,49,223,254,254,254,254,254,254,254,254,254, + 254,254,254,254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196, + 190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,245,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,21,241,127,0,0,0,0,0,0,0,0,0,0,0,0,14,216,254,248,115,2,0,0,0,0,0, + 18,115,175,181,180,148,47,0,0,0,0,0,0,80,239,254,239,36,0,0,0,0,0,0,0,0, + 87,251,50,0,0,0,0,0,9,223,255,238,28,0,75,252,146,0,8,212,254,222,9,0,153, + 255,255,254,106,0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,0,2,111,220, + 52,0,0,0,0,0,0,0,0,0,0,0,0,54,220,151,217,254,254,254,254,250,127,3,0,0, + 0,0,0,0,11,165,253,254,254,254,254,194,168,201,29,0,0,0,0,1,102,245,254, + 254,254,254,230,143,225,75,0,0,0,0,0,47,221,254,254,254,254,248,153,210, + 137,5,0,0,23,191,177,186,254,254,254,254,254,188,175,194,24,0,0,0,0,0,0, + 0,0,0,0,0,1,96,223,66,0,0,0,72,224,144,228,254,254,254,254,246,149,215, + 126,3,0,0,0,0,19,184,254,254,254,254,253,181,181,185,20,0,0,6,144,203,32, + 0,0,0,0,0,2,106,221,57,0,0,0,0,0,0,0,0,0,0,2,34,41,5,0,0,0,0,0,0,0,0,0, + 69,252,67,0,0,0,133,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0, + 71,253,254,255,255,255,254,255,255,255,255,255,255,254,254,254,254,254, + 254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,4,118,137,137,137,137,137, + 137,137,137,137,135,28,0,0,0,0,0,0,0,0,0,0,0,0,18,240,255,255,255,255,255, + 255,254,219,43,0,0,0,0,0,0,0,0,0,0,0,0,23,242,255,255,255,255,255,253,60, + 0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0,0,0,0,0,104,254,254, + 254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,204,31,0,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0, + 0,0,50,224,254,254,254,254,254,254,254,254,254,254,254,254,255,255,254, + 111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,31,245,112,0,44,136,137,137,137,137,137,137,137,137,137,137,137,137,137, + 120,6,20,241,127,0,0,0,0,0,0,0,0,0,0,0,0,0,126,248,115,2,0,0,0,0,0,0,0, + 0,5,43,9,0,0,0,0,0,0,0,0,0,80,240,169,2,0,0,0,0,0,0,0,0,87,251,50,0,0,0, + 0,0,9,223,254,179,2,2,172,254,222,17,0,135,254,222,9,0,153,255,255,254, + 106,0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,1,109,247,254,225,41,0, + 0,0,0,0,0,0,0,0,0,51,226,254,247,138,115,116,116,116,90,3,0,0,0,0,0,0,0, + 0,11,105,116,116,116,116,167,252,254,202,18,0,0,0,0,1,78,116,116,116,116, + 134,241,254,237,64,0,0,0,0,0,43,116,116,116,116,118,214,254,251,129,0,20, + 191,254,253,172,111,116,116,116,116,174,253,254,193,14,0,0,0,0,0,0,0,0, + 0,0,93,244,254,233,54,0,69,236,254,242,127,116,116,116,116,120,219,254, + 250,117,0,0,0,0,0,19,110,116,116,116,116,181,254,254,184,10,4,143,252,254, + 205,20,0,0,0,0,104,246,254,228,45,0,0,0,0,0,0,0,0,3,136,242,246,185,20, + 0,0,0,0,0,0,0,0,69,252,168,137,137,137,198,239,16,0,0,0,0,0,0,12,230,146, + 0,0,0,55,252,81,0,0,0,66,236,237,237,237,237,237,237,247,254,255,254,254, + 254,254,254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,8,206, + 237,237,237,237,237,237,237,237,237,235,49,0,0,0,0,0,0,0,0,0,0,0,0,18,240, + 255,255,255,255,255,254,219,43,0,0,0,0,0,0,0,0,0,0,0,0,0,23,242,255,255, + 255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0,0,0, + 0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254,254, + 251,254,254,254,254,254,254,254,205,31,0,0,0,1,182,254,254,182,1,0,0,27, + 243,254,254,96,0,0,0,0,50,224,254,254,254,254,254,254,245,249,254,254,254, + 255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,29,228,104,2,170,254,254,254,254,253,252,251,249,251,252, + 254,254,254,254,250,76,19,224,118,0,0,0,0,0,0,0,0,0,0,0,0,0,22,76,2,0,0, + 0,0,0,0,0,0,0,78,233,114,2,0,0,0,0,0,0,0,0,0,57,43,0,0,0,0,0,0,0,0,0,87, + 251,50,0,0,0,0,0,9,223,253,89,0,36,240,254,252,80,0,48,247,222,9,0,153, + 254,255,254,106,0,8,220,255,255,185,1,0,0,0,0,0,0,0,0,0,0,0,5,212,254,255, + 254,88,0,0,0,0,0,0,0,0,0,0,138,254,255,254,167,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,23,241,254,255,250,46,0,0,0,0,0,0,0,0,0,1,183,254,255,254, + 122,0,0,0,0,0,0,0,0,0,0,104,254,255,255,200,1,73,253,254,255,224,10,0,0, + 0,32,245,254,255,247,36,0,0,0,0,0,0,0,0,0,1,196,254,255,254,108,0,165,254, + 255,254,140,0,0,0,0,117,254,255,254,187,1,0,0,0,0,0,0,0,0,0,42,249,254, + 255,243,26,19,239,254,255,252,49,0,0,0,3,207,254,255,254,94,0,0,0,0,0,0, + 0,0,53,248,255,254,254,112,0,0,0,0,0,0,0,0,69,253,241,237,237,237,246,239, + 16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,4,14,14,14,14,14,14,14, + 72,235,254,254,254,254,254,254,254,254,254,254,254,254,254,80,0,0,0,0,0, + 0,0,0,0,0,0,0,0,12,14,14,14,14,14,14,14,14,14,14,2,0,0,0,0,0,0,0,0,0,0, + 0,0,18,240,255,255,255,255,254,218,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,242, + 255,255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138, + 0,0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,254, + 240,119,248,254,254,254,254,254,204,30,0,0,0,0,1,182,254,254,182,1,0,0, + 27,243,254,254,96,0,0,0,0,0,50,223,254,254,254,254,254,198,112,247,254, + 254,255,255,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,1,14,6,54,246,255,253,219,141,82,49,48,42,49,55,102,172, + 241,254,254,194,7,14,7,0,0,0,0,0,0,0,0,0,0,0,0,0,59,43,0,0,0,0,0,0,0,0, + 0,79,240,254,249,114,2,0,0,0,0,0,0,0,0,23,78,1,0,0,0,0,0,0,0,0,87,253,177, + 158,158,158,158,158,161,242,251,170,158,189,254,254,254,206,158,162,242, + 242,161,158,216,254,255,254,198,158,161,241,255,255,185,1,0,0,0,0,0,0,0, + 0,0,0,0,5,213,255,255,254,88,0,0,0,0,0,0,0,0,0,0,139,254,255,255,167,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,242,255,255,250,46,0,0,0,0,0,0,0, + 0,0,1,184,255,255,254,122,0,0,0,0,0,0,0,0,0,0,105,254,255,255,201,1,74, + 253,255,255,224,10,0,0,0,33,246,255,255,247,36,0,0,0,0,0,0,0,0,0,1,197, + 255,255,254,108,0,166,255,255,254,140,0,0,0,0,118,254,255,255,187,1,0,0, + 0,0,0,0,0,0,0,43,249,255,255,243,26,20,240,255,255,252,49,0,0,0,3,209,255, + 255,254,95,0,0,0,0,0,0,0,0,72,253,255,254,254,136,0,0,0,0,0,0,0,0,69,252, + 78,14,14,14,140,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,0,0, + 0,0,0,0,0,0,0,70,235,254,255,254,254,254,254,254,254,254,254,254,254,80, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,18,240,255,255,255,254,218,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,242,255, + 255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138,0, + 0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,254,240, + 81,38,247,254,254,254,254,205,30,0,0,0,0,0,1,182,254,254,182,1,0,0,27,243, + 254,254,96,0,0,0,0,0,0,50,223,254,254,254,254,196,4,111,247,254,255,255, + 254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,2,171,254,254,177,18,0,0,0,0,0,0,0,0,1,59,238,255,251,76,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,64,232,199,14,0,0,0,0,0,0,0,78,239,254,255,255, + 248,113,2,0,0,0,0,0,0,4,163,244,96,1,0,0,0,0,0,0,0,75,221,221,221,221,221, + 221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, + 221,221,221,221,221,221,221,221,221,221,161,1,0,0,0,0,0,0,0,0,0,0,0,5,213, + 255,255,254,88,0,0,0,0,0,0,0,0,0,0,139,254,255,255,167,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,23,242,255,255,250,46,0,0,0,0,0,0,0,0,0,1,184,255, + 255,254,122,0,0,0,0,0,0,0,0,0,0,105,254,255,255,201,1,74,253,255,255,224, + 10,0,0,0,33,246,255,255,247,36,0,0,0,0,0,0,0,0,0,1,197,255,255,254,108, + 0,166,255,255,254,140,0,0,0,0,118,254,255,255,187,1,0,0,0,0,0,0,0,0,0,43, + 249,255,255,243,26,20,240,255,255,252,49,0,0,0,3,209,255,255,254,95,0,0, + 0,0,0,0,0,0,27,224,254,254,248,71,0,0,0,0,0,0,0,0,69,252,68,0,0,0,134,239, + 16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,0,0,0,0,0,0,0,0,0,0,70, + 235,254,254,254,254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0, + 0,0,5,155,179,179,179,179,179,179,179,179,179,177,36,0,0,0,0,0,0,0,0,0, + 0,0,0,18,240,255,255,254,219,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,242, + 255,255,255,255,255,253,60,0,0,0,0,0,0,1,183,254,254,254,254,254,254,138, + 0,0,0,0,0,0,0,104,254,254,254,254,254,254,254,254,254,254,254,254,254,254, + 254,254,254,254,254,254,254,251,47,0,0,0,0,0,0,1,197,254,254,254,241,81, + 0,38,247,254,254,254,204,31,0,0,0,0,0,0,1,182,254,254,182,1,0,0,27,243, + 254,254,96,0,0,0,0,0,0,0,50,224,254,254,254,196,1,2,111,248,254,255,254, + 111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,54,246,254,254,129,1,0,0,0,0,0,0,0,0,0,15,223,255,254,193,6,0,0,0, + 0,0,0,0,0,0,0,0,0,64,232,254,253,165,11,0,0,0,0,0,78,239,254,255,255,255, + 254,248,113,2,0,0,0,0,4,129,251,254,244,96,1,0,0,0,0,0,0,2,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,6,0,0,0,0,0,0,0,0, + 0,0,0,0,5,213,255,255,254,88,0,0,0,0,0,0,0,0,0,0,139,254,255,255,167,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,241,255,255,250,46,0,0,0,0,0,0,0, + 0,0,1,183,254,255,254,122,0,0,0,0,0,0,0,0,0,0,104,254,255,255,201,1,73, + 253,255,255,224,10,0,0,0,33,245,255,255,247,36,0,0,0,0,0,0,0,0,0,1,197, + 255,255,254,108,0,166,254,255,254,140,0,0,0,0,118,254,255,255,187,1,0,0, + 0,0,0,0,0,0,0,43,249,255,255,243,26,20,240,255,255,252,49,0,0,0,3,208,255, + 255,254,95,0,0,0,0,0,0,0,0,0,51,162,167,84,2,0,0,0,0,0,0,0,0,69,253,199, + 179,179,179,218,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,70,236,254,254,254,254,254,254,254,254,254,254,80,0,0, + 0,0,0,0,0,0,0,0,0,0,6,179,206,206,206,206,206,206,206,206,206,204,42,0, + 0,0,0,0,0,0,0,0,0,0,0,18,240,255,254,220,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,18,196,206,206,206,206,206,204,48,0,0,0,0,0,0,0,148,206,206,206,206, + 206,206,112,0,0,0,0,0,0,0,84,206,206,206,206,206,206,206,206,206,206,206, + 206,206,206,206,206,206,206,206,206,206,203,38,0,0,0,0,0,0,1,197,254,254, + 241,82,0,0,38,247,254,254,205,31,0,0,0,0,0,0,0,1,182,254,254,182,1,0,0, + 27,243,254,254,96,0,0,0,0,0,0,0,0,50,224,254,254,196,1,0,2,111,248,254, + 254,111,0,0,0,0,0,0,0,132,254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,2,170,254,255,255,242,137,48,10,1,1,1,1,3,19,76,187,253,255,255, + 250,75,0,0,0,0,0,0,0,0,0,0,0,39,231,254,254,254,253,164,11,0,0,0,78,238, + 254,255,255,255,255,255,254,248,113,2,0,0,4,129,250,255,255,254,244,72, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,127,251,254,234,49,0,0,0,0,0,0,0,0, + 0,0,63,236,254,250,143,136,142,142,141,91,1,0,0,0,0,0,0,0,0,6,113,142,142, + 142,131,178,253,254,215,23,0,0,0,0,0,0,0,0,0,0,98,246,254,243,75,0,0,0, + 0,0,34,138,142,142,141,126,224,254,253,145,0,26,206,254,254,182,123,142, + 142,142,130,185,254,254,207,17,0,0,0,0,0,0,0,0,0,0,109,249,254,240,64,0, + 84,242,254,247,130,139,142,142,141,128,229,254,252,132,0,0,0,0,0,0,0,0, + 0,0,13,185,254,254,198,12,5,161,253,254,220,114,141,142,142,137,152,250, + 254,237,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,253,255,255,255, + 255,255,239,16,0,0,0,0,0,0,12,230,146,0,0,0,55,252,81,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,70,236,254,254,254,254,254,254,254,254,254,80,0,0,0,0,0,0,0, + 0,0,0,0,0,0,2,3,3,3,3,3,3,3,3,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,18,240,254, + 219,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,3,3,3,3,2,0,0,0,0,0,0, + 0,0,2,3,3,3,3,3,2,1,0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,2,0,0,0,0,0,0,0,1,197,254,240,82,0,0,0,38,247,254,205,30,0,0,0,0, + 0,0,0,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0,0,0,0,0,0,0,0,0,50, + 224,254,196,1,0,0,1,111,248,254,111,0,0,0,0,0,0,0,132,254,255,225,10,1, + 196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,54,245,255,255,255,254,254,247,225, + 200,199,199,199,204,237,252,254,255,255,255,254,192,6,0,0,0,0,0,0,0,0,0, + 0,7,151,252,254,255,254,253,188,37,0,75,239,254,255,255,255,255,255,255, + 255,254,248,113,2,22,160,251,254,255,255,254,185,17,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,130,231,66,0,0,0,0,0,0,0,0,0,0,0,0,68,232,158,207,254, + 254,254,254,248,108,1,0,0,0,0,0,0,6,147,252,254,254,254,254,183,179,215, + 40,0,0,0,0,0,0,0,0,0,0,0,1,102,236,92,1,0,0,0,0,35,211,254,254,254,254, + 245,146,222,155,8,0,0,31,206,188,174,253,254,254,254,253,176,186,208,33, + 0,0,0,0,0,0,0,0,0,0,0,2,113,234,81,0,0,0,88,235,148,220,254,254,254,254, + 242,144,227,144,6,0,0,0,0,0,0,0,0,0,0,0,18,186,200,28,0,0,10,162,219,148, + 247,254,254,254,254,209,156,232,71,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,69,253,255,255,255,255,255,239,16,0,0,0,0,0,0,12,230,146,0,0, + 0,55,252,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,235,254,254,254,254,254, + 254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,6,6,6,6,6,6,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,18,240,218,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,197,240,82,0,0,0,0,38, + 247,205,30,0,0,0,0,0,0,0,0,0,1,182,254,254,182,1,0,0,27,243,254,254,96, + 0,0,0,0,0,0,0,0,0,0,50,224,196,1,0,0,0,2,111,247,111,0,0,0,0,0,0,0,132, + 254,255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,117,193,193,193,193, + 193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,189,44, + 0,0,0,0,0,0,0,0,0,0,0,7,151,252,254,255,255,254,223,38,128,235,254,254, + 255,255,255,255,255,254,254,241,169,19,178,254,254,255,255,254,190,18,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 43,190,254,255,255,255,255,254,246,72,0,0,0,0,0,0,114,252,255,255,255,255, + 254,253,155,30,0,0,0,0,0,0,0,0,0,0,0,0,0,1,37,0,0,0,0,0,10,196,254,255, + 255,255,255,254,243,93,8,0,0,0,0,25,142,253,255,255,255,255,254,253,145, + 26,0,0,0,0,0,0,0,0,0,0,0,0,0,2,37,0,0,0,0,0,51,209,254,255,255,255,255, + 254,240,85,6,0,0,0,0,0,0,0,0,0,0,0,0,0,17,23,0,0,0,0,10,99,245,255,255, + 255,255,254,254,193,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 69,253,255,255,255,255,255,239,16,0,0,0,0,0,0,12,230,147,0,0,0,55,252,81, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,71,235,254,254,254,254,254,254,254,80, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,205,216,216,216,215,147,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,18,204,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,183,82,0,0,0,0,0,38,198,31, + 0,0,0,0,0,0,0,0,0,0,1,182,254,254,182,1,0,0,27,243,254,254,96,0,0,0,0,0, + 0,0,0,0,0,0,50,167,1,0,0,0,0,2,112,104,0,0,0,0,0,0,0,132,254,255,225,10, + 1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,209,217,217,217,217,217,217,217, + 217,217,217,217,217,217,217,217,217,217,217,217,217,217,108,0,0,0,0,0,0, + 0,0,0,0,0,0,8,151,252,254,254,245,99,1,1,28,104,164,209,218,218,218,214, + 173,106,40,2,0,38,212,254,254,254,213,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,234,254,255,255,255,253, + 166,11,0,0,0,0,0,0,26,198,254,255,255,255,254,215,41,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,79,239,254,255,255,255,253,155,9,0,0,0,0,0,0, + 32,206,254,255,255,255,254,208,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,89,243,254,255,255,255,252,144,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,10,162,253,255,255,255,254,236,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,69,253,255,255,255,255,255,239,16,0,0,0,0,0,0,12, + 230,222,45,0,3,131,253,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,71,236,254, + 254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,86,165,166,166,147, + 20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0, + 0,0,15,27,0,0,0,0,0,0,0,0,0,0,0,0,119,166,166,118,0,0,0,17,158,166,165, + 62,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,2,17,0,0,0,0,0,0,0,132,254,255, + 225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,159,166,166,166,166,166, + 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,82,0,0, + 0,0,0,0,0,0,0,0,0,0,0,8,151,252,245,99,1,0,0,0,0,0,6,7,7,7,7,1,0,0,0,0, + 0,38,213,254,213,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,164,166,166,166,137,11,0,0,0,0,0,0,0,0,26, + 153,166,166,166,160,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 75,165,166,166,166,130,9,0,0,0,0,0,0,0,0,32,156,166,166,166,157,34,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,84,165,166,166,166,123,7,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,135,166,166,166,165,70,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,61,250,255,255,255,255, + 255,237,15,0,0,0,0,0,0,10,221,254,219,49,124,250,253,79,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,70,237,254,254,254,254,254,80,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255,225, + 10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,147,99,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,38,179,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,131,251, + 254,254,254,249,116,1,0,0,0,0,0,0,0,69,237,254,236,250,254,178,15,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,70,236,254,254,254,254,80,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254, + 255,225,10,1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,105,144, + 145,144,96,2,0,0,0,0,0,0,0,0,0,64,144,145,145,129,14,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,71,235,254,254,254,80,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255,225,10, + 1,196,190,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,72, + 236,254,253,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,132,254,255,225,10,12,209,141,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,71,237,254,80,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255, + 224,21,163,155,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,71,236,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255,233,173,155,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,71,63,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,254,255, + 252,155,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,132,254,253,155,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,253,156,9,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 132,160,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}; + +#endif // linux || svr4 +#endif // __SYNAES_SYMBOL_H__ diff --git a/kscd/kscdmagic/syna.h b/kscd/kscdmagic/syna.h new file mode 100644 index 00000000..40128532 --- /dev/null +++ b/kscd/kscdmagic/syna.h @@ -0,0 +1,180 @@ +/* + $Id$ + + Synaesthesia - program to display sound graphically + Copyright (C) 1997 Paul Francis Harrison + + This program 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 2 of the License, or (at your + option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author may be contacted at: + phar6@student.monash.edu.au + or + 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia +*/ + +#ifndef __SYNA_H__ +#define __SYNA_H__ + + +#if defined(__linux__) || defined(__svr4__) || defined(__osf__) + +void error(const char *str, bool syscall=false); //Display error and exit +void warning(const char *str, bool syscall=false); //Display error + +//void error(char *str,bool syscall=false); +inline void attempt(int x, const char *y, bool syscall=false) { if (x == -1) error(y,syscall); } + +//void warning(char *str,bool syscall=false); +inline void attemptNoDie(int x, const char *y, bool syscall=false) { if (x == -1) warning(y,syscall); } + +#include "polygon.h" +#include "magicconf.h" + +/***************************************/ + + +#define PROGNAME "kscdmagic" + + +#ifdef __FreeBSD__ + + +typedef unsigned short sampleType; + +#else + +typedef short sampleType; + +#ifndef __linux__ + +#warning This target has not been tested! + +#endif +#endif + +#ifdef __osf__ +#include <machine/endian.h> +#else +#include <endian.h> +#endif +#if BYTE_ORDER == BIG_ENDIAN +#define BIGENDIAN +#else +#define LITTLEENDIAN +#endif + + +#define n (1<<m) +#define recSize (1<<m-overlap) + +/* core */ +extern volatile sampleType *data; +//extern unsigned char *output, *lastOutput, *lastLastOutput; +extern Bitmap<unsigned short> outputBmp, lastOutputBmp, lastLastOutputBmp; +#define ucoutput ((unsigned char*)outputBmp.data) +#define lastOutput ((unsigned char*)lastOutputBmp.data) +#define lastLastOutput ((unsigned char*)lastLastOutputBmp.data) + +inline unsigned short combiner(unsigned short a,unsigned short b) { + //Not that i want to give the compiler a hint or anything... + unsigned char ah = a>>8, al = a&255, bh = b>>8, bl = b&255; + if (ah < 64) ah *= 4; else ah = 255; + if (al < 64) al *= 4; else al = 255; + if (bh > ah) ah = bh; + if (bl > al) al = bl; + return ah*256+al; +} + +extern PolygonEngine<unsigned short,combiner,2> polygonEngine; + +extern int outWidth, outHeight; + +void allocOutput(int w,int h); + +void coreInit(); +void setStarSize(double size); +int coreGo(); +void fade(); + +/* *wrap */ +void screenInit(int xHint,int yHint,int widthHint,int heightHint); +void screenSetPalette(unsigned char *palette); +void screenEnd(void); +void screenShow(void); +int sizeUpdate(void); + +void inputUpdate(int &mouseX,int &mouseY,int &mouseButtons,char &keyHit); + +/* ui */ +void interfaceInit(); +void interfaceSyncToState(); +void interfaceEnd(); +bool interfaceGo(); + +enum SymbolID { + Speaker, Bulb, + Play, Pause, Stop, SkipFwd, SkipBack, + Handle, Pointer, Open, NoCD, Exit, + Zero, One, Two, Three, Four, + Five, Six, Seven, Eight, Nine, + Slider, Selector, Plug, Loop, Box, Bar, + Flame, Wave, Stars, Star, Diamond, Size, FgColor, BgColor, + Save, Reset, TrackSelect, + NotASymbol +}; + +/* State information */ + +extern SymbolID state; +extern int track, frames; +extern double trackProgress; +extern char **playList; +extern int playListLength, playListPosition; +extern SymbolID fadeMode; +extern bool pointsAreDiamonds; +extern double brightnessTwiddler; +extern double starSize; +extern double fgRedSlider, fgGreenSlider, bgRedSlider, bgGreenSlider; + +extern double volume; + +void setStateToDefaults(); +void saveConfig(); + +void putString(char *string,int x,int y,int red,int blue); + +/* sound */ +enum SoundSource { SourceLine, SourceCD, SourcePipe }; + +void cdOpen(char *cdromName); +void cdClose(void); +void cdGetStatus(int &track, int &frames, SymbolID &state); +void cdPlay(int trackFrame, int endFrame=-1); +void cdStop(void); +void cdPause(void); +void cdResume(void); +void cdEject(void); +void cdCloseTray(void); +int cdGetTrackCount(void); +int cdGetTrackFrame(int track); +void openSound(SoundSource sound, int downFactor, const char *dspName, char *mixerName); +void closeSound(); +void setupMixer(double &loudness); +void setVolume(double loudness); +int getNextFragment(void); + + +#endif // linux || svr4 +#endif // __SYNA_H__ diff --git a/kscd/kscdmagic/version.h b/kscd/kscdmagic/version.h new file mode 100644 index 00000000..aa5df67c --- /dev/null +++ b/kscd/kscdmagic/version.h @@ -0,0 +1 @@ +#define KSCDMAGICVERSION "2.0" diff --git a/kscd/kscdmagic/xlib.c b/kscd/kscdmagic/xlib.c new file mode 100644 index 00000000..2fb15c19 --- /dev/null +++ b/kscd/kscdmagic/xlib.c @@ -0,0 +1,781 @@ +/* + * XaoS, a fast portable realtime fractal zoomer + * Copyright (C) 1996,1997 by + * + * Jan Hubicka (hubicka@paru.cas.cz) + * Thomas Marsh (tmarsh@austin.ibm.com) + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * Shamelessly ripped for use in xsynaesthesia + */ +/*#include "aconfig.h"*/ +#define X11_DRIVER +/*#define MITSHM*/ + +#ifdef X11_DRIVER +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/cursorfont.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef __FreeBSD__ +#include <malloc.h> +#else +#include <stdlib.h> +#endif +#include "xlib.h" +#ifdef AMIGA +#define XFlush(x) while(0) +#endif + +#undef PIXMAP + +#define chkalloc(n) if (!n) fprintf(stderr, "out of memory\n"), exit(-1) + +int xupdate_size(xdisplay * d) +{ + int tmp; + Window wtmp; + int width = d->width, height = d->height; + XGetGeometry(d->display, d->window, &wtmp, &tmp, &tmp, &d->width, &d->height, (unsigned int *) &tmp, (unsigned int *) &tmp); + if ((int)d->width != width || (int)d->height != height) + return 1; + return 0; +} + +void xflip_buffers(xdisplay * d) +{ + d->back = d->vbuffs[d->current]; + d->current ^= 1; + d->vbuff = d->vbuffs[d->current]; +} + +void draw_screen(xdisplay * d) +{ + switch (d->image[0]->bits_per_pixel) { + case 16:{ + unsigned short *de; + unsigned char *s; + unsigned char *e; + for (s = (unsigned char *) d->vbuffs[d->current], + e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height), + de = (unsigned short *) d->data[d->current]; s < e; s += 8, de += 8) + *de = d->pixels[*s], + *(de + 1) = d->pixels[*(s + 1)], + *(de + 2) = d->pixels[*(s + 2)], + *(de + 3) = d->pixels[*(s + 3)], + *(de + 4) = d->pixels[*(s + 4)], + *(de + 5) = d->pixels[*(s + 5)], + *(de + 6) = d->pixels[*(s + 6)], + *(de + 7) = d->pixels[*(s + 7)]; + s -= 8; + de -= 8; + for (; s < e; s++, de++) + *de = d->pixels[*s]; + break; + } + case 24:{ + unsigned char *de; + unsigned char *s; + unsigned char *e; + for (s = (unsigned char *) d->vbuffs[d->current], + e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height), + de = (unsigned char *) d->data[d->current]; s < e; s++, de+=3) + de[0] = d->pixels[*s], + de[1] = d->pixels[*s]>>8, + de[2] = d->pixels[*s]>>16; + + break; + } + case 32:{ + unsigned long *de; + unsigned char *s; + unsigned char *e; + for (s = (unsigned char *) d->vbuffs[d->current], + e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height), + de = (unsigned long *) d->data[d->current]; s < e; s += 8, de += 8) + *de = d->pixels[*s], + *(de + 1) = d->pixels[*(s + 1)], + *(de + 2) = d->pixels[*(s + 2)], + *(de + 3) = d->pixels[*(s + 3)], + *(de + 4) = d->pixels[*(s + 4)], + *(de + 5) = d->pixels[*(s + 5)], + *(de + 6) = d->pixels[*(s + 6)], + *(de + 7) = d->pixels[*(s + 7)]; + s -= 8; + de -= 8; + for (; s < e; s++, de++) + *de = d->pixels[*s]; + break; + } + } +#ifdef MITSHM + if (d->SharedMemFlag) { + XShmPutImage(d->display, d->window, d->gc, d->image[d->current], 0, 0, 0, + 0, d->width, d->height, True); + XFlush(d->display); + } else +#endif + { + XPutImage(d->display, d->window, d->gc, d->image[d->current], 0, 0, 0, 0, d->width, d->height); + XFlush(d->display); + } + d->screen_changed = 0; +} + +#ifdef MITSHM +int alloc_shm_image(xdisplay * new) +{ + register char *ptr; + int temp, size = 0, i; + ptr = DisplayString(new->display); + if (!ptr || (*ptr == ':') || !strncmp(ptr, "localhost:", 10) || + !strncmp(ptr, "unix:", 5) || !strncmp(ptr, "local:", 6)) { + new->SharedMemOption = XQueryExtension(new->display, "MIT-SHM", &temp, &temp, &temp); + } else { + new->SharedMemOption = False; + return 0; + } + new->SharedMemFlag = False; +#if 0 + new->SharedMemOption = True; + new->SharedMemFlag = False; +#endif + + if (new->SharedMemFlag) { + XShmDetach(new->display, &new->xshminfo[0]); + XShmDetach(new->display, &new->xshminfo[1]); + new->image[0]->data = (char *) NULL; + new->image[1]->data = (char *) NULL; + shmdt(new->xshminfo[0].shmaddr); + shmdt(new->xshminfo[1].shmaddr); + } + for (i = 0; i < 2; i++) { + if (new->SharedMemOption) { + int mul; + if (new->depth == 8) + mul = 1; + else if (new->depth <= 24) + mul = 2; + else + mul = 4; + new->SharedMemFlag = False; + new->image[i] = XShmCreateImage(new->display, new->visual, new->depth, ZPixmap, + NULL, &new->xshminfo[i], new->width, new->height * mul); + if (new->image[i]) { + temp = new->image[i]->bytes_per_line * new->image[i]->height; + new->linewidth = new->image[i]->bytes_per_line * 8 / new->image[i]->bits_per_pixel; + if (temp > size) + size = temp; + new->xshminfo[i].shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); + if (new->xshminfo[i].shmid != -1) { + new->xshminfo[i].shmaddr = (char *) shmat(new->xshminfo[i].shmid, 0, 0); + if (new->xshminfo[i].shmaddr != (char *) -1) { + new->image[i]->data = new->xshminfo[i].shmaddr; + new->data[i] = new->vbuffs[i] = (char *) new->image[i]->data; + new->xshminfo[i].readOnly = True; + + new->SharedMemFlag = XShmAttach(new->display, &new->xshminfo[i]); + XSync(new->display, False); + if (!new->SharedMemFlag) { + XDestroyImage(new->image[i]); + new->image[i] = (XImage *) NULL; + new->SharedMemFlag = 0; + return 0; + } + } + /* Always Destroy Shared Memory Ident */ + shmctl(new->xshminfo[i].shmid, IPC_RMID, 0); + } + if (!new->SharedMemFlag) { + XDestroyImage(new->image[i]); + new->image[i] = (XImage *) NULL; + new->SharedMemFlag = 0; + return 0; + } + } else { + new->SharedMemFlag = 0; + return 0; + } + } else { + new->SharedMemFlag = 0; + return 0; + } + } + new->current = 0; + xflip_buffers(new); + return 1; +} + +void free_shm_image(xdisplay * d) +{ + if (d->SharedMemFlag) { + XDestroyImage(d->image[0]); + XDestroyImage(d->image[1]); + XShmDetach(d->display, &d->xshminfo[0]); + XShmDetach(d->display, &d->xshminfo[1]); + shmdt(d->xshminfo[0].shmaddr); + shmdt(d->xshminfo[1].shmaddr); + } +} + +#endif + +int alloc_image(xdisplay * d) +{ + int i; +#ifdef MITSHM + if (!d->params->nomitshm && alloc_shm_image(d)) { + if (d->depth != 8) { + for (i = 0; i < 2; i++) + d->vbuffs[i] = malloc(d->linewidth * d->height); + } + return 1; + } +#endif + for (i = 0; i < 2; i++) { + d->image[i] = XCreateImage(d->display, d->visual, d->depth, ZPixmap, 0, + NULL, d->width, d->height, 8, 0); + if (d->image[i] == NULL) { + printf("Out of memory for image..exiting\n"); + exit(3); + } + /*Add a little extra memory to catch overruns when dumping image to buffer in draw_screen*/ + d->image[i]->data = malloc(d->image[i]->bytes_per_line * d->height + 32); + memset(d->image[i]->data,0,d->image[i]->bytes_per_line * d->height); + + if (d->image[i]->data == NULL) { + printf("Out of memory for image buffers..exiting\n"); + exit(3); + } + d->data[i] = d->vbuffs[i] = (char *) d->image[i]->data; + d->linewidth = d->image[i]->bytes_per_line * 8 / d->image[i]->bits_per_pixel; + } + if (d->depth != 8) { + for (i = 0; i < 2; i++) { + /* Add a little extra memory to catch overruns */ + /* when dumping image to buffer in draw_screen */ + d->vbuffs[i] = malloc(d->linewidth * d->height + 32); + memset(d->vbuffs[i],0,d->linewidth * d->height); + + if (d->vbuffs[i] == NULL) { + printf("Out of memory for image buffers2..exiting\n"); + exit(3); + } + } + } + xflip_buffers(d); + return 1; +} + +void free_image(xdisplay * d) +{ + if (d->depth != 8) + free(d->vbuffs[0]), free(d->vbuffs[1]); +#ifdef MITSHM + if (d->SharedMemFlag) { + free_shm_image(d); + return; + } +#endif + XDestroyImage(d->image[0]); + XDestroyImage(d->image[1]); +} +#define MAX(x,y) ((x)>(y)?(x):(y)) + + +xdisplay *xalloc_display(const char *s, int xHint, int yHint, int x, int y, xlibparam * params) +{ + xdisplay *xd; + Visual *defaultvisual; + XVisualInfo vis; + + + xd = (xdisplay *) calloc(sizeof(xdisplay), 1); + chkalloc(xd); + xd->display = XOpenDisplay((char *) NULL); + if (!xd->display) { + free((void *) xd); + return NULL; + } + xd->screen = DefaultScreen(xd->display); + xd->attributes = (XSetWindowAttributes *) + malloc(sizeof(XSetWindowAttributes)); + chkalloc(xd->attributes); + xd->attributes->background_pixel = BlackPixel(xd->display, + xd->screen); + xd->attributes->border_pixel = BlackPixel(xd->display, xd->screen); + xd->attributes->event_mask = ButtonPressMask | StructureNotifyMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | ExposureMask | KeyReleaseMask; + xd->attributes->override_redirect = False; + xd->attr_mask = CWBackPixel | CWBorderPixel | CWEventMask; + xd->classX = InputOutput; + xd->xcolor.n = 0; + xd->parent_window = RootWindow(xd->display, xd->screen); + defaultvisual = DefaultVisual(xd->display, xd->screen); + xd->params = params; + if (!params->usedefault) { + if (defaultvisual->class != PseudoColor || (!XMatchVisualInfo(xd->display, xd->screen, 8, PseudoColor, &vis) && vis.colormap_size > 128)) { + xd->fixedcolormap = 1; + if (!XMatchVisualInfo(xd->display, xd->screen, 15, TrueColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 16, TrueColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 32, TrueColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 24, TrueColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 8, PseudoColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 7, PseudoColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 8, TrueColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 8, StaticColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 8, StaticGray, &vis)) { + printf("Display does not support PseudoColor depth 7,8,StaticColor depth 8, StaticGray depth 8, Truecolor depth 8,15,16,24 nor 32!\n"); + return NULL; + } else + xd->truecolor = 1; + } else + xd->fixedcolormap = 0, xd->truecolor = 0; + } else + xd->truecolor = 1; + } else + xd->truecolor = 1; + } else + xd->truecolor = 1; + } else { + xd->truecolor = 0; + } + xd->depth = vis.depth; + xd->visual = vis.visual; + } else { /*usedefault */ + vis.depth = xd->depth = DefaultDepth(xd->display, xd->screen); + xd->visual = defaultvisual; + switch (defaultvisual->class) { + case PseudoColor: + if (xd->depth <= 8) { + xd->depth = 8; + xd->truecolor = 0; + xd->fixedcolormap = 0; + } else { + printf("Pseudocolor visual on unsuported depth\n"); + return NULL; + } + break; + case TrueColor: + case StaticColor: + case StaticGray: + xd->truecolor = 1; + xd->fixedcolormap = 1; + if (xd->depth <= 8) + xd->depth = 8; + else if (xd->depth <= 16) + xd->depth = 16; + else if (xd->depth <= 32) + xd->depth = 32; + else { + printf("Truecolor visual on unsuported depth\n"); + return NULL; + } + break; + default: + printf("Unusuported visual\n"); + break; + } + } + /*xd->visual->map_entries = 256; */ + xd->colormap = xd->defaultcolormap = DefaultColormap(xd->display, xd->screen); + + xd->window_name = s; + xd->height = y; + xd->width = x; + xd->border_width = 2; + xd->lastx = 0; + xd->lasty = 0; + xd->font_struct = (XFontStruct *) NULL; + + xd->window = XCreateWindow(xd->display, xd->parent_window, xHint, yHint, + xd->width, xd->height, xd->border_width, + vis.depth, xd->classX, xd->visual, + xd->attr_mask, xd->attributes); + if (!xd->fixedcolormap && params->privatecolormap) { + unsigned long pixels[256]; + int i; + xd->colormap = XCreateColormap(xd->display, xd->window, xd->visual, AllocNone); + XAllocColorCells(xd->display, xd->colormap, 1, 0, 0, pixels, MAX(xd->visual->map_entries, 256)); + for (i = 0; i < 16; i++) { + xd->xcolor.c[i].pixel = pixels[i]; + } + XQueryColors(xd->display, xd->defaultcolormap, xd->xcolor.c, 16); + XStoreColors(xd->display, xd->colormap, xd->xcolor.c, 16); + xd->privatecolormap = 1; + } + if (!xd->fixedcolormap) + XSetWindowColormap(xd->display, xd->window, xd->colormap); + xd->gc = XCreateGC(xd->display, xd->window, 0L, &(xd->xgcvalues)); + XSetBackground(xd->display, xd->gc, + BlackPixel(xd->display, xd->screen)); + XSetForeground(xd->display, xd->gc, + WhitePixel(xd->display, xd->screen)); + XStoreName(xd->display, xd->window, xd->window_name); + XMapWindow(xd->display, xd->window); +#if 1 + XSelectInput(xd->display, xd->window, + /* ExposureMask | */ + KeyPress | + /* KeyRelease | */ + /* ConfigureRequest | */ + /* FocusChangeMask | */ + StructureNotifyMask | + ButtonPressMask | ButtonReleaseMask); +#endif +#ifdef PIXAMP + xd->pixmap = XCreatePixmap(xd->display, xd->window, xd->width, + xd->height, xd->depth); +#endif + + { + XColor c; + Pixmap p = XCreatePixmap(xd->display, xd->window, 1,1,1); + memset(&c,0,sizeof(c)); + xd->cursor = XCreatePixmapCursor(xd->display, p,p, + &c,&c, 0,0); + /* We don't need no fancy cursor + XDefineCursor(xd->display,xd->window,xd->cursor); + */ + XFreePixmap(xd->display, p); + } + + return (xd); +} + +void xsetcolor(xdisplay * d, int col) +{ + switch (col) { + case 0: + XSetForeground(d->display, d->gc, + BlackPixel(d->display, d->screen)); + break; + case 1: + XSetForeground(d->display, d->gc, + WhitePixel(d->display, d->screen)); + break; + default: + if ((col - 2) > d->xcolor.n) { + fprintf(stderr, "color error\n"); + exit(3); + } + XSetForeground(d->display, d->gc, + d->xcolor.c[col - 2].pixel); + break; + } +} +void xrotate_palette(xdisplay * d, int direction, unsigned char co[3][256], int ncolors) +{ + int i, p; + + if (d->privatecolormap) { + for (i = 0; i < d->xcolor.n; i++) { + p = d->xcolor.c[i].pixel; + d->xcolor.c[i].red = (int) co[0][p] * 256; + d->xcolor.c[i].green = (int) co[1][p] * 256; + d->xcolor.c[i].blue = (int) co[2][p] * 256; + } + XStoreColors(d->display, d->colormap, d->xcolor.c, d->xcolor.n); + } + if (d->truecolor) { + unsigned long oldpixels[256]; + memcpy(oldpixels, d->pixels, sizeof(oldpixels)); + p = (ncolors - 1 + direction) % (ncolors - 1) + 1; + for (i = 1; i < ncolors; i++) { /*this is ugly..I know */ + d->pixels[i] = oldpixels[p]; + p++; + if (p >= ncolors) + p = 1; + } + draw_screen(d); + } +} +int xalloc_color(xdisplay * d, int r, int g, int b, int readwrite) +{ + d->xcolor.n++; + d->xcolor.c[d->xcolor.n - 1].flags = DoRed | DoGreen | DoBlue; + d->xcolor.c[d->xcolor.n - 1].red = r; + d->xcolor.c[d->xcolor.n - 1].green = g; + d->xcolor.c[d->xcolor.n - 1].blue = b; + d->xcolor.c[d->xcolor.n - 1].pixel = d->xcolor.n - 1; + if ((readwrite && !d->fixedcolormap) || d->privatecolormap) { + unsigned long cell; + if (d->privatecolormap) { + cell = d->xcolor.c[d->xcolor.n - 1].pixel += 16; + if (d->xcolor.c[d->xcolor.n - 1].pixel >= d->visual->map_entries) { + d->xcolor.n--; + return (-1); + } + } else { + if (!XAllocColorCells(d->display, d->colormap, 0, 0, 0, &cell, 1)) { + d->xcolor.n--; + if (d->xcolor.n <= 32) + printf("Colormap is too full! close some colorfull aplications or use -private\n"); + return (-1); + } + d->xcolor.c[d->xcolor.n - 1].pixel = cell; + } + XStoreColor(d->display, d->colormap, &(d->xcolor.c[d->xcolor.n - 1])); + return (cell); + } + if (!XAllocColor(d->display, d->colormap, &(d->xcolor.c[d->xcolor.n - 1]))) { + d->xcolor.n--; + if (d->xcolor.n <= 32) + printf("Colormap is too full! close some colorfull aplications or use -private\n"); + return (-1); + } + d->pixels[d->xcolor.n - 1] = d->xcolor.c[d->xcolor.n - 1].pixel; + return (d->depth != 8 ? d->xcolor.n - 1 : d->xcolor.c[d->xcolor.n - 1].pixel); +} + +void xfree_colors(xdisplay * d) +{ + unsigned long pixels[256]; + int i; + for (i = 0; i < d->xcolor.n; i++) + pixels[i] = d->xcolor.c[i].pixel; + if (!d->privatecolormap) + XFreeColors(d->display, d->colormap, pixels, d->xcolor.n, 0); + d->xcolor.n = 0; +} + +void xfree_display(xdisplay * d) +{ + XSync(d->display, 0); + if (d->font_struct != (XFontStruct *) NULL) { + XFreeFont(d->display, d->font_struct); + } + XUnmapWindow(d->display, d->window); +#ifdef PIXMAP + XFreePixmap(d->display, d->pixmap); +#endif + XDestroyWindow(d->display, d->window); + XFreeCursor(d->display, d->cursor); + XCloseDisplay(d->display); + free((void *) d->attributes); + free((void *) d); +} + +#ifdef PIXMAP +void xline(xdisplay * d, int x1, int y1, int x2, int y2) +{ + XDrawLine(d->display, d->pixmap, d->gc, x1, y1, x2, y2); + d->lastx = x2, d->lasty = y2; + d->screen_changed = 1; +} void xlineto(xdisplay * d, int x, int y) +{ + + XDrawLine(d->display, d->pixmap, d->gc, d->lastx, d->lasty, x, y); + d->lastx = x, d->lasty = y; + d->screen_changed = 1; +} void xrect(xdisplay * d, int x1, int y1, int x2, int y2) +{ + + XDrawRectangle(d->display, d->pixmap, d->gc, x1, y1, + (x2 - x1), (y2 - y1)); + d->lastx = x2, d->lasty = y2; + d->screen_changed = 1; +} void xfillrect(xdisplay * d, int x1, int y1, int x2, int y2) +{ + + XFillRectangle(d->display, d->pixmap, d->gc, x1, y1, + (x2 - x1), (y2 - y1)); + d->lastx = x2, d->lasty = y2; + d->screen_changed = 1; +} void xpoint(xdisplay * d, int x, int y) +{ + + XDrawPoint(d->display, d->pixmap, d->gc, x, y); + d->lastx = x, d->lasty = y; + d->screen_changed = 1; +} void xflush(xdisplay * d) +{ + + draw_screen(d); + XFlush(d->display); +} + +void xclear_screen(xdisplay * d) +{ + xfillrect(d, 0, 0, d->width, d->height); + d->screen_changed = 1; +} + +#endif +void xmoveto(xdisplay * d, int x, int y) +{ + d->lastx = x, d->lasty = y; +} int xsetfont(xdisplay * d, char *font_name) +{ + + if (d->font_struct != (XFontStruct *) NULL) { + XFreeFont(d->display, d->font_struct); + } + d->font_struct = XLoadQueryFont(d->display, font_name); + if (!d->font_struct) { + fprintf(stderr, "could not load font: %s\n", font_name); + exit(3); + } + return (d->font_struct->max_bounds.ascent + d->font_struct->max_bounds.descent); +} + +void xouttext(xdisplay * d, char *string) +{ + int sz; + + sz = strlen(string); + XDrawImageString(d->display, d->window, d->gc, d->lastx, d->lasty, + string, sz); +#if 0 + d->lastx += XTextWidth(d->font_struct, string, sz); + d->screen_changed = 1; +#endif +} void xresize(xdisplay * d, XEvent * ev) +{ + +#ifdef PIXMAP + XFreePixmap(d->display, d->pixmap); +#endif + d->width = ev->xconfigure.width; + d->height = ev->xconfigure.height; +#ifdef PIXMAP + d->pixmap = XCreatePixmap(d->display, d->window, d->width, + d->height, d->depth); +#endif +} + +#ifdef PIXMAP +void xarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2) +{ + XDrawArc(d->display, d->pixmap, d->gc, x, y, w, h, a1, a2); +} void xfillarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2) +{ + XFillArc(d->display, d->pixmap, d->gc, x, y, w, h, a1, a2); +} +#endif + +void xsize_set(xdisplay *d, int width, int height) +{ + XResizeWindow(d->display, d->window, width, height); +} + +int xmouse_x(xdisplay * d) +{ + + return d->mouse_x; +} + +int xmouse_y(xdisplay * d) +{ + return d->mouse_y; +} + +void xmouse_update(xdisplay * d) +{ + Window rootreturn, childreturn; + int rootx = 0, rooty = 0, buttons = 0; + + XEvent event; + + if (XCheckMaskEvent(d->display,ButtonPressMask | ButtonReleaseMask, &event)) { + if (event.type == ButtonPress) + d->mouse_buttons |= 1 << ((XButtonEvent*)(&event))->button; + else + d->mouse_buttons &= ~( 1 << ((XButtonEvent*)(&event))->button ); + } + + XQueryPointer(d->display, d->window, &rootreturn, &childreturn, + &rootx, &rooty, &(d->mouse_x), &(d->mouse_y), + &buttons); +} + +char xkeyboard_query(xdisplay * d) { + XEvent event; + + if (XCheckMaskEvent(d->display,KeyPressMask | KeyReleaseMask, &event)) { + char *str = + XKeysymToString(XLookupKeysym((XKeyPressedEvent*)(&event),0)); + + if ( ((XKeyPressedEvent*)(&event))->state & + (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) ) + return 0; + + if (str) { + char key; + + if (strlen(str) == 1) + key = str[0]; + else if (strcmp(str,"equal") == 0) + key = '='; + else if (strcmp(str,"minus") == 0) + key = '-'; + else if (strcmp(str,"bracketleft") == 0) + key = '['; + else if (strcmp(str,"bracketright") == 0) + key = ']'; + else if (strcmp(str,"comma") == 0) + key = ','; + else if (strcmp(str,"period") == 0) + key = '.'; + else if (strcmp(str,"slash") == 0) + key = '/'; + else return 0; + + if ( ((XKeyPressedEvent*)(&event))->state & ShiftMask ) + switch(key) { + case '=' : key = '+'; break; + case '[' : key = '{'; break; + case ']' : key = '}'; break; + case ',' : key = '<'; break; + case '/' : key = '?'; break; + default : + if (key >= 'a' && key <= 'z') + key = key+'A'-'a'; + break; + } + return key; + } + } + + return 0; +} + +int xsize_update(xdisplay *d,int *width,int *height) { + XEvent event; + + if (XCheckMaskEvent(d->display,StructureNotifyMask, &event)) { + if (event.type == ConfigureNotify) { + xupdate_size(d); + free_image(d); + alloc_image(d); + *width = d->linewidth; + *height = d->height; + return 1; + } + } + + return 0; +} + +unsigned int xmouse_buttons(xdisplay * d) +{ + return d->mouse_buttons; +} +#endif diff --git a/kscd/kscdmagic/xlib.h b/kscd/kscdmagic/xlib.h new file mode 100644 index 00000000..077a9052 --- /dev/null +++ b/kscd/kscdmagic/xlib.h @@ -0,0 +1,139 @@ +/* + * XaoS, a fast portable realtime fractal zoomer + * Copyright (C) 1996,1997 by + * + * Jan Hubicka (hubicka@paru.cas.cz) + * Thomas Marsh (tmarsh@austin.ibm.com) + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef XAOS_X11_H +#define XAOS_X11_H + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <X11/keysymdef.h> +/*#include "config.h"*/ +/*#define MITSHM*/ + +#ifdef MITSHM +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> +#endif /* MITSHM */ + +#ifdef n +#undef n +#endif + +typedef struct { + int n; + XColor c[256]; +} xcol_t; + +typedef struct { + int privatecolormap; + int usedefault; + int nomitshm; +} xlibparam; + +typedef struct { + Colormap colormap; + Colormap defaultcolormap; + int fixedcolormap; + int privatecolormap; + xlibparam *params; + Display *display; + Window parent_window; + Window window; + unsigned int width, height; + unsigned int border_width; + unsigned long background; + int depth; + unsigned int classX; + Visual *visual; + unsigned long valuemask; + XSetWindowAttributes *attributes; + unsigned long attr_mask; + XSizeHints sizehints; + int screen; + const char *window_name; + int status; + GC gc; + XGCValues xgcvalues; + xcol_t xcolor; + Pixmap pixmap; + XFontStruct *font_struct; + int screen_changed; + int lastx, lasty; + int mouse_x, mouse_y; + unsigned int mouse_buttons; + int current; + XImage *image[2]; +#ifdef MITSHM + XShmSegmentInfo xshminfo[2]; + int SharedMemOption; + int SharedMemFlag; +#endif /* MITSHM */ + unsigned long pixels[256]; + char *vbuffs[2]; + char *data[2]; + char *vbuff; + char *back; + int truecolor; + int linewidth; + + Cursor cursor; +} xdisplay; + +extern int alloc_shm_image(xdisplay * d); +extern void free_shm_image(xdisplay * d); +extern int alloc_image(xdisplay * d); +extern void free_image(xdisplay * d); +extern int xupdate_size(xdisplay * d); +extern void xflip_buffers(xdisplay * d); +extern xdisplay *xalloc_display(const char *n, int x, int y, int width,int height, xlibparam * p); +extern void xfree_display(xdisplay * d); +extern void xsetcolor(xdisplay * d, int col); +extern int xsetfont(xdisplay * d, char *font_name); +extern int xalloc_color(xdisplay * d, int r, int g, int b, int readwrite); +extern void xfree_colors(xdisplay * d); +extern void xline(xdisplay * d, int x1, int y1, int x2, int y2); +extern void xmoveto(xdisplay * d, int x, int y); +extern void xlineto(xdisplay * d, int x, int y); +extern void xrect(xdisplay * d, int x1, int y1, int x2, int y2); +extern void xfillrect(xdisplay * d, int x1, int y1, int x2, int y2); +extern void xarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2); +extern void xfillarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2); +extern void xpoint(xdisplay * d, int x, int y); +extern void xflush(xdisplay * d); +extern void xclear_screen(xdisplay * d); +extern void xrotate_palette(xdisplay * d, int direction, unsigned char c[3][256], int ncolors); +extern void draw_screen(xdisplay * d); +extern void xouttext(xdisplay * d, char *string); +extern void xresize(xdisplay * d, XEvent * ev); +extern void xsize_set(xdisplay *d, int width, int height); +extern int xsize_update(xdisplay *d,int *width,int *height); +extern int xmouse_x(xdisplay * d); +extern int xmouse_y(xdisplay * d); +extern void xmouse_update(xdisplay * d); +extern char xkeyboard_query(xdisplay * d); +extern unsigned int xmouse_buttons(xdisplay * d); + +#endif /* XAOS_X11_H */ diff --git a/kscd/kscdmagic/xlibwrap.cpp b/kscd/kscdmagic/xlibwrap.cpp new file mode 100644 index 00000000..b5241326 --- /dev/null +++ b/kscd/kscdmagic/xlibwrap.cpp @@ -0,0 +1,209 @@ +/* Synaesthesia - program to display sound graphically + Copyright (C) 1997 Paul Francis Harrison + + This program 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 2 of the License, or (at your + option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author may be contacted at: + pfh@yoyo.cc.monash.edu.au + or + 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia +*/ + +#if defined(__linux__) || defined (__svr4__) || defined(__osf__) + +#include <string.h> + +extern "C" { +#include "xlib.h" +} + +#include "magicconf.h" +#include "syna.h" + +static xlibparam xparams = { 0, 0, 0 }; +static xdisplay *d; + +static bool lowColor, paletteInstalled; +static unsigned char mapping[64]; + +int setPalette(int ,int r,int g,int b) { + return xalloc_color(d,r*257,g*257,b*257,0); +} + +void screenInit(int xHint,int yHint,int widthHint,int heightHint) +{ + + int i; + + d = xalloc_display("KSCD Magic",xHint,yHint,widthHint,heightHint,&xparams); + + if (d == 0) + error("setting up a window"); + + if (!alloc_image(d)) + error("allocating window buffer"); + outWidth = widthHint; + outHeight = heightHint; + + //XMoveWindow(d->display,d->window,xHint,yHint); + +#define BOUND(x) ((x) > 255 ? 255 : (x)) +#define PEAKIFY(x) BOUND((x) - (x)*(255-(x))/255/2) + + lowColor = (d->depth <= 8); + + /* Set up palette immediately. + * Original code has the following commented out. + */ + if (!lowColor) { + for(i=0;i<256;i++) + attempt(setPalette(i,PEAKIFY((i&15*16)), + PEAKIFY((i&15)*16+(i&15*16)/4), + PEAKIFY((i&15)*16)), + " in X: could not allocate sufficient palette entries"); + } else { + for(i=0;i<64;i++) + attempt(mapping[i] = setPalette(i,PEAKIFY((i&7*8)*4), + PEAKIFY((i&7)*32+(i&7*8)*2), + PEAKIFY((i&7)*32)), + " in X: could not allocate sufficient palette entries"); + } +} + +void screenSetPalette(unsigned char *palette) { + int i; + + if (paletteInstalled) + xfree_colors(d); + + if (!lowColor) { + for(i=0;i<256;i++) + attempt(setPalette(i,palette[i*3],palette[i*3+1],palette[i*3+2]), + " in X: could not allocate sufficient palette entries"); + } else { + const int array[8] = {0,2,5,7,9,11,13,15}; + for(i=0;i<64;i++) { + int p = (array[i&7]+array[i/8]*16) *3; + attempt(mapping[i] = setPalette(i,palette[p],palette[p+1],palette[p+2]), + " in X: could not allocate sufficient palette entries"); + } + } + + paletteInstalled = true; +} + +void screenEnd() { + if (paletteInstalled) + xfree_colors(d); + xfree_display(d); +} + +int sizeUpdate() +{ + int newWidth,newHeight; + + if (xsize_update(d,&newWidth,&newHeight)) + { + if (newWidth == outWidth && newHeight == outHeight) + return 0; + //delete[] output; + //outWidth = newWidth; + //outHeight = newHeight; + //output = new unsigned char [outWidth*outHeight*2]; + //memset(output,32,outWidth*outHeight*2); + allocOutput(newWidth,newHeight); + return 1; + } + return 0; +} + +void inputUpdate(int &mouseX,int &mouseY,int &mouseButtons,char &keyHit) { + xmouse_update(d); + mouseX = xmouse_x(d); + mouseY = xmouse_y(d); + mouseButtons = xmouse_buttons(d); + keyHit = xkeyboard_query(d); +} + +void screenShow(void) { + register unsigned long *ptr2 = (unsigned long*)ucoutput; + unsigned long *ptr1 = (unsigned long*)d->back; + int i = outWidth*outHeight/4; + if (lowColor) + do { + register unsigned int const r1 = *(ptr2++); + register unsigned int const r2 = *(ptr2++); + + //if (r1 || r2) { +#ifdef LITTLEENDIAN + register unsigned int const v = + mapping[((r1&0xe0ul)>>5)|((r1&0xe000ul)>>10)] + |mapping[((r1&0xe00000ul)>>21)|((r1&0xe0000000ul)>>26)]*256U; + *(ptr1++) = v | + mapping[((r2&0xe0ul)>>5)|((r2&0xe000ul)>>10)]*65536U + |mapping[((r2&0xe00000ul)>>21)|((r2&0xe0000000ul)>>26)]*16777216U; +#else + register unsigned int const v = + mapping[((r2&0xe0ul)>>5)|((r2&0xe000ul)>>10)] + |mapping[((r2&0xe00000ul)>>21)|((r2&0xe0000000ul)>>26)]*256U; + *(ptr1++) = v | + mapping[((r1&0xe0ul)>>5)|((r1&0xe000ul)>>10)]*65536U + |mapping[((r1&0xe00000ul)>>21)|((r1&0xe0000000ul)>>26)]*16777216U; +#endif + //} else ptr1++; + } while (--i); + else + do { + // Asger Alstrup Nielsen's (alstrup@diku.dk) + // optimized 32 bit screen loop + register unsigned int const r1 = *(ptr2++); + register unsigned int const r2 = *(ptr2++); + + //if (r1 || r2) { +#ifdef LITTLEENDIAN + register unsigned int const v = + ((r1 & 0x000000f0ul) >> 4) + | ((r1 & 0x0000f000ul) >> 8) + | ((r1 & 0x00f00000ul) >> 12) + | ((r1 & 0xf0000000ul) >> 16); + *(ptr1++) = v | + ((r2 & 0x000000f0ul) << 16 -4) + | ((r2 & 0x0000f000ul) << 16 -8) + | ((r2 & 0x00f00000ul) << 16 -12) + | ((r2 & 0xf0000000ul) << 16 -16); +#else + register unsigned int const v = + ((r2 & 0x000000f0ul) >> 4) + | ((r2 & 0x0000f000ul) >> 8) + | ((r2 & 0x00f00000ul) >> 12) + | ((r2 & 0xf0000000ul) >> 16); + *(ptr1++) = v | + ((r1 & 0x000000f0ul) << 16 -4) + | ((r1 & 0x0000f000ul) << 16 -8) + | ((r1 & 0x00f00000ul) << 16 -12) + | ((r1 & 0xf0000000ul) << 16 -16); +#endif + //} else ptr1++; + } while (--i); + + xflip_buffers(d); + draw_screen(d); + XFlush(d->display); +} + + + +#endif // linux || svr4 + |